Using the Domain ActionScript class (as opposed to the C++ class of the same name) in Tamarin is actually really easy. This class isn’t available under Flash 9 for security reasons. It lets you load new ActionScript code at runtime, as our example will demonstrate. Dynamic code loading is pretty cool functionality – it could be used to implement a plugin system in an application, as the basis for a web server that executed files on demand, or as part of a programmer’s workbench written in AS.
Here’s how you load code dynamically and instantiate a type from it:
import avmplus.Domain; Domain.currentDomain.load("FileToLoad.abc"); var loadedClass:Class = Domain.currentDomain.getClass("TestClass"); var dynamicObject:Object = new loadedClass();
What’s going on here? First, we’re grabbing the currently active code domain (Domain.currentDomain). Then we tell it to execute FileToLoad.abc. This will load any class definitions from it, as well as execute any code in the root scope of the file. (So be careful for side effects.)
Second, we look up the Class for “TestClass” by name. Notice that ActionScript has a type for representing types – it’s called Class. Kind of mind-bending, eh? This leads us to step three, which is using the new operator to make a new instance of the Class instance we just got from the Domain.
At this point, dynamicObject contains an instance of TestClass as defined in our .ABC file. Of course, we don’t have the type available at compile-time so we have to declare it as an Object and run our code against dynamically. You can avoid most of the type-unsafety here by using interfaces and casting the dynamically created instance right away, ie:
import avmplus.Domain; Domain.currentDomain.load("FileToLoad.abc"); var loadedClass:Class = Domain.currentDomain.getClass("TestClass"); var dynamicObject:IPlugin = new loadedClass() as IPlugin;
That’s about it. Now you, too, can load code dynamically using Tamarin!
Some Further Notes
With a few minor C++ code modifications it’s possible to allow an idiom where you create a new Domain instance and pass it null for its parent domain. However, this results in a context for execution of the loaded code where the builtin classes aren’t defined yet! In the absence of things like Object and Function, it’s hard to write meaningful code. Ideally, it would be interesting to load a .ABC into a limited sandbox, but it appears that isn’t possible yet.
You can currently make a new Domain instance with the currentDomain as a parent – with some extension it would appear to be possible to use that for permission management, if you had a way to annotate the new child domain. For instance, you could add a flag that limited to only built-in classes, or to classes with domains signed by a certain authority, or many other things – something that the SpiderMonkey engine has explored in more detail.
One of the things I’m interested in is how to make plugin-related code loading reliable and relatively secure, at least to the point where a program can notify the user when they’re engaging in a potentially unsafe action (“This add-on is not endorsed by the mod authority, are you sure you want to run it?”). A “secure” variant of the ABC format would be required as well, so that signed code could be easily distributed. Hmm.