Wednesday, June 25, 2008

AbcExplorationLib: Starting an open source project

A couple of months ago I started working on a F# library to read and write ActionScript Byte Code (ABC) files based on the ActionScript Virtual Machine 2 (AVM2) Overview document. I though this was a great opportunity to learn more about both F# and ActionScript.

Although the library is still pretty incomplete, I'll continue the development as an open source project. The project is called AbcExplorationLib and is hosted in CodePlex .

Inspiration for this library comes from excellent bytecode manipulation libraries such as BCEL, ASM, Cecil or System.Reflection.Emit.

When completed this library could be used as part of a complied code analysis tool or as part of the back end of a experimental compiler.

An example of using this library to load a compiled script and print all the names of the opcodes is the following:


let loadedFile =
using(new BinaryReader(new FileStream("Hello.abc",FileMode.Open)))
(fun aInput -> AbcFile.ReadFrom(aInput))


let loadedScript =
AvmScript.Create(loadedFile.Scripts.[0],
loadedFile.Methods,
loadedFile.MethodBodies,
loadedFile.ConstantPool);

Array.iter
(fun (x:AbcFileInstruction) -> printf "%s\n" x.Name)
(loadedScript.InitMethod.Body.Value.BodyInfo.GetInstructions())



An example for generating a "Hello world" program:


let abcFileCreator = AbcFileCreator()
let cpCreator = abcFileCreator.ConstantPoolCreator

let instructions =
[| GetLocal0 ;
PushScope ;
FindPropertyStrict(cpCreator.GetMultiname([|""|],"print"));
PushString(cpCreator.AddString( "Hola!"));
CallProperty(cpCreator.GetMultiname([|""|],"print"),1) ;
CoerceA ;
SetLocal_1 ;
GetLocal1 ;
ReturnValue ;
Kill(1);
|];

let code = ConvertToByteArray(instructions)

let script =
AvmScript(
AvmMethod( "",
SQualifiedName("*"),
[||],
Some (
AvmMethodBody(
AbcMethodBodyInfo(
0, 2, 2, 1, 2,
code,
[||],[||]
)))));

abcFileCreator.AddScript(script.ToLowerIr(abcFileCreator))

let fileRep = abcFileCreator.CreateFile()

using (new BinaryWriter(new FileStream("Hello.abc",FileMode.Create))) (fun f -> fileRep.WriteTo(f))


As you can see this is the part that requires more work! :) .

Future posts will cover the progress of this library.