bookmark_borderC to ActionScript via Adobe Alchemy

Recently Adobe’s Alchemy was released to the public for testing. It claims to be a tool which can “compile C and C++ code that is targeted to run on the open source ActionScript Virtual Machine (AVM2)”.

In English, that means you can take C and C++ applications and run them in Flash 10.

Since I am always interested in the next big thing, I though i’d check it out by porting something interesting over. Previously I managed to rewrite a SCUMM interpreter from C to HaXe for Flash 9. So naturally, to form a good comparison I decided to compile this interpreter using Adobe’s Alchemy instead.

What went right

Well, I managed to get it ported, using a front-end written in AS3, and the back-end compiled to a swc via Alchemy. Above you can see a screen shot of the version written in C (the haXe version for comparison here). Compared to the haXe implementation, the C version is much more feature complete.

It should also be noted that it took me only 2 days to get the Adobe Alchemy version to work properly, vs several weeks to get the HaXe version barely functional.

What went wrong

While Adobe Alchemy is cool, it was a nightmare to work with. For starters, compiling in C++ was broken (as the new operator didn’t work), so I could only compile programs written in C. This obviously meant no ScummVM port, which would have been far more featureful.

It also meant that I had to put up with the full quirkiness of the horrible Alchemy API. For example, this grabs the current time:

static unsigned sdl_scvm_get_time(scvm_backend_sdl_t* be) {
  AS3_Val ns;
  AS3_Val func;
  AS3_Val ares;
  AS3_Val und = AS3_Undefined();
  AS3_Val params = AS3_Array("");
  int res;

  ns = AS3_String("flash.utils");
  func = AS3_NSGetS(ns, "getTimer");
  ares = AS3_Call(func, und, params);
  res = AS3_IntValue(ares);

  AS3_Release(ares);
  AS3_Release(ns);
  AS3_Release(func);
  AS3_Release(und);
  AS3_Release(params);

  return res;
}

Ok, maybe I am exaggerating a bit here, but it seems that almost every function requires an AS3Val_, which you need to release. And it gets really annoying when you have to keep remembering to explicitly release everything you use. Hasn’t anyone at Adobe heard of autorelease pools?

Another thing is I could not find a proper way of debugging the C code. I had to resort to printing out values and trying to decipher the cryptic error messages which don’t really help me figure out the real problem.

Error: Error #1502: A script has executed for longer than the default timeout period of 15 seconds.
        at ()[45593.achacks.as:3340]
        at ()[45593.achacks.as:3902]
        at ScummTest/initEngine()
        at ScummTest$/process_loadQueue()
        at ScummTest$/swfLoaded()
        at flash.events::EventDispatcher/dispatchEventFunction()
        at flash.events::EventDispatcher/dispatchEvent()
        at flash.net::URLLoader/onComplete()

It would also have helped if there was proper documentation. True, there were a few examples, and you can figure out a few things from looking at the headers, but source code is not documentation.

And finally, even if you ignore the failings of the API and documentation, you still have to contend with the slow performance. In my example, the SCUMM interpreter was notably slower than its natively compiled counterpart, especially when it printed all of its debugging statements to the trace log. And even when it wasn’t printing anything out, it still took a long time doing seemingly nothing.

To conclude

To be fair, Adobe Alchemy is still “pre-release” software, so I have no doubt it will improve over the coming months.

In addition Adobe specifically mention that “Alchemy is primarily intended to be used with C/C++ libraries that have few operating system dependencies” and “is not intended for general development of SWF applications using C/C++”.

So I don’t think I will be making a habit of porting C/C++ applications to Flash using Alchemy.

Ok, libraries perhaps. But applications?

I really think it is better to write as much as you can in ActionScript or HaXe. It isn’t like in .NET where you can access objects and classes in the runtime via a transparent interface. You have to explicitly use the AS3 interface in order to manipulate native ActionScript objects.

Still, I look forward to see what becomes of Alchemy.