codegen

Back to ABC Format Library

Code Generation

When compiling to SWF, you can execute this code using format.swf to wrap the bytecode, then loading this movie using the flash.display.Loader.loadBytes method.

First, create a new Haxe Project and include the format library. Then you can start writing in Flash9 assembler. Here's a small example :

import format.abc.Data;
import format.swf.Data;

class Test
{
    static var loader : flash.display.Loader;
    
    static function main() {
        var ctx = new format.abc.Context();
        // defines a class called Main
        ctx.beginClass("Main");
        // the type 'int' in Flash9
        var tint = ctx.type("int");
        // create a member method called 'test'
        // with 0 arguments and return type 'int'
        var m = ctx.beginMethod("test",[],tint);
        // the maximum size of the stack in this method
        m.maxStack = 1;
        // write bytecode into the current method
        ctx.ops([
            OInt(667),
            ORet,
        ]);
        // we are done with all the bytecode writing
        ctx.finalize();

        // compile ActionScript bytecode
        var abcOutput = new haxe.io.BytesOutput();
        new format.abc.Writer(abcOutput).write(ctx.getData());
        var abcBytes:haxe.io.Bytes = abcOutput.getBytes();
        
        // create a new SWF
        var swfOutput:haxe.io.BytesOutput = new haxe.io.BytesOutput();
        var swfFile:format.swf.SWF = {
            header: {
                version : 9,
                compressed : false,
                width : 400,
                height : 300,
                fps : cast(30, Float),
                nframes : 1
            },
            tags: [
                TSandBox(25),            // Flash9 Sandbox
                TActionScript3(abcBytes),    // ActionScript block
                TShowFrame            // Show frame
            ]
            
        }
        // write SWF
        var writer:format.swf.Writer = new format.swf.Writer(swfOutput);
        writer.write(swfFile);
        var swfBytes:haxe.io.Bytes = swfOutput.getBytes();

        // load locally
        loader = new flash.display.Loader();
        loader.contentLoaderInfo.addEventListener(flash.events.Event.COMPLETE, onLoaded);
        loader.loadBytes(swfBytes.getData());
    }
    
    // the data has been succesfully loaded
    public static function onLoaded(e) {
        // get the Main class
        var m = loader.contentLoaderInfo.applicationDomain.getDefinition("Main");
        // create an instance of it
        var inst : Dynamic = Type.createInstance(m,[]);
        // call the 'test' method
        trace(inst.test());
        // this should display '667'
    }
}

Another example that shows good performances is the Fibonnacci recursive calculus. It's defined in Haxe as the following method :

static function fib( n : Int ) : Int {
   if( n <= 1 ) return 1;
   return fib(n - 1) + fib(n - 2);
}

Here's the corresponding Flash9 bytecode :

// fib takes an integer argument and returns an integer
var m = ctx.beginMethod("fib",[tint],tint);
// we will have up to 3 values on the stack
m.maxStack = 3;
ctx.ops([
    OReg(1),      // register 1 = first argument
    OSmallInt(1), // the integer 1
    OJump(JGt,3), // jump 3 bytes if reg1 > 1
    OInt(1),
    ORet,         //   return 1
    ODecrIReg(1), // decrement register 1
    OThis,
    OReg(1),
        // call this.fib(reg1) with 1 argument
    OCallProperty(ctx.property("fib"),1), 
    ODecrIReg(1), // decrement register 1
    OThis,
    OReg(1),
        // call this.fib(reg1) with 1 argument
    OCallProperty(ctx.property("fib"),1),
    OOp(OpIAdd),  // add the two values
    ORet,         // returns
]);

When timed, fib(35) shows a +30% speedup in assembler versus the AS3/Haxe version.

version #19959, modified 2014-03-01 05:45:36 by hgupta