是我的疏忽,一直没事看haxe都忘了看这个神奇的东西
看看介绍:
hxASM enables you to program directly in Flash9 assembler and it will compile for your a SWF compatible with Flash Player 9 that can be either directly loaded from memory or saved into a file.
The library can dynamicaly generate a ByteArray representing a SWF file that contains the compiled assembler methods. The code can then be executed by using the flash.display.Loader.loadBytes method.
hxASM可以让你在Flash9平台汇编级别编程,它会帮你编译好一个与Flash9平台相兼容的SWF,之后你可以载入到内存或者保存为一个文件
这个库可以动态生成一个ByteArray来表征一个包含汇编程序的方法的SWF,你的汇编代码可以用flsah.display.Loader.loadBytes来载入和执行,太帅了
这个是hxasm的地址:http://haxe.org/hxasm
如果你还没有配置好你的haxe
那很简单的
http://haxe.org/download这里可以下载haxe所需要的,找好你平台对应的,上面那三个都是下载一个小东西帮你再联网下载安装需要的东东,如果不爽就自己下,其实也很简单的,点击下就ok了
不过还是用人家的啦,都不知道是不是改了环境变量--具体没细看这个
开发环境用Flash Develop,目前是3.0 beta4,需要.net framework 2.0,去FD官网http://www.flashdevelop.org/community下载吧,都有的
至于他说的haxeFD是不需要的,FD3自己带了
你可以完全按照http://haxe.org/hxasm来试试效果
不过我试了下,发现版本升迁有点点小问题(可能是我鹾,大家试试如果ok告诉下我)
运行刚才下载的hxinst-win.exe,会帮你配置haxe和neko,后者是环境,配置看这里http://nekovm.org/doc/begin,如果是用hxinst-win.exe就不用管他啦
"我的电脑"属性 -- 高级 -- 环境变量:
HAXEPATH C:\Program Files\Motion-Twin\haxe\
NEKO_INSTPATH C:\Program Files\Motion-Twin\neko
你配置的时候也是这样的,只要添加个环境变量就OK啦
好了,现在运行下cmd.exe
cd C:\Program Files\Motion-Twin\haxe
haxelib install hxasm
这样会去下载hxasm包,我下载到的是1.04版本,之后会生成一个xml就是包配置文件
不过很郁闷的是-lib hxasm加到编译参数那,我这边老是不行,可能是不使用haxeFD用的是FD的HaXeContext吧
不过HaXeContext的Additional Compiler Option加上-lib hxasm也不行
所以最后我把hxasm这个类包copy出来了,其实大家看install好的hxasm,下一级的1.04居然是1,04,这个没有深入去弄,FD论坛上逛了一圈木有什么发现
好了,新建一个空haxe项目,名字TestHxasm,地址自己分配一个
新建一个class,命名Test.hx
把下面代码贴上去(就是官网的)
import hxasm.Bytecode;
class Test {
static var loader : flash.display.Loader;
static function main() {
// create a new bytecode Context
var ctx = new hxasm.Context();
// 定义 Main类
ctx.beginClass("Main");
// 定义flash9的int类型
var tint = ctx.type("int");
// 创建成员函数 'test'
// 下面定义是表明test函数参数为空,返回值为tint就是flash9的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(666),
ORet,
]);
// we are done with all the bytecode writing
ctx.finalize();
// create an output and write the bytecode to it
var o = new hxasm.Output();
hxasm.Writer.write(o,ctx);
var swf = o.getBytes();
// load the SWF bytes
loader = new flash.display.Loader();
loader.contentLoaderInfo.addEventListener(flash.events.Event.COMPLETE,onLoaded);
loader.loadBytes(swf);
}
// the data has been succesfully loaded
public static function onLoaded(e) {
// get the Main class
var m = loader.contentLoaderInfo.applicationDomain.getDefinition("Main");
// 在这里,你可以trace下inst和m,可以发现是什么,这点跟as3都差不多create an instance of it
var inst : Dynamic = Type.createInstance(m,[]);
// call the 'test' method
trace(inst.test());
// this should display '666'
}
}
之后记得把hxasm包复制进来就好了,项目属性那定义一个swf生成和swf版本,之后在compiler那设置入口类为Test
F5测试下吧
来点更爽的,也就是官网上的斐波那契函数
试试这段
import hxasm.Bytecode;
class Test {
static var loader : flash.display.Loader;
static function main() {
var ctx = new hxasm.Context();
ctx.beginClass("Main");
var tint = ctx.type("int");
var m = ctx.beginMethod("fib",[tint],tint);
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
]);
ctx.finalize();
var o = new hxasm.Output();
hxasm.Writer.write(o,ctx);
var swf = o.getBytes();
loader = new flash.display.Loader();
loader.contentLoaderInfo.addEventListener(flash.events.Event.COMPLETE,onLoaded);
loader.loadBytes(swf);
}
public static function onLoaded(e) {
var m = loader.contentLoaderInfo.applicationDomain.getDefinition("Main");
var inst : Dynamic = Type.createInstance(m,[]);
trace(inst.fib(30));
}
}
记得inst.fib()参数不要太凶狠,不然堆栈溢出
其他版本的
import hxasm.Bytecode;
class Test {
static var loader : flash.display.Loader;
static function main() {
var ctx = new hxasm.Context();
ctx.beginClass("Main");
var tint = ctx.type("int");
var m = ctx.beginMethod("fib",[tint],tint);
m.maxStack = 3;
ctx.ops([
OReg(1),
OSmallInt(1),
]);
var j = ctx.jump(JGt); // prepare a jump
ctx.ops([
OInt(1),
ORet,
]);
j(); // patch the jump with current position
ctx.ops([
ODecrIReg(1),
OThis,
OReg(1),
OCallProperty(ctx.property("fib"),1),
ODecrIReg(1),
OThis,
OReg(1),
OCallProperty(ctx.property("fib"),1),
OOp(OpIAdd),
ORet,
]);
ctx.finalize();
var o = new hxasm.Output();
hxasm.Writer.write(o,ctx);
var swf = o.getBytes();
loader = new flash.display.Loader();
loader.contentLoaderInfo.addEventListener(flash.events.Event.COMPLETE,onLoaded);
loader.loadBytes(swf);
}
public static function onLoaded(e) {
var m = loader.contentLoaderInfo.applicationDomain.getDefinition("Main");
var inst : Dynamic = Type.createInstance(m,[]);
trace(inst.fib(30));
}
}
之后就一大堆的API
有兴趣的去优化吧,最后做成swf就好了,o(∩_∩)o...哈哈
好啦,翻译到此结束!
Good Luck & Have Fun