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.