as2虚拟机的执行过程
大家一听感觉很神秘,很难懂。但大家请。放心,我说的是一个用as3程序写的虚拟机。代码并不算是很多。
其实了解虚拟机的底层执行过程,对于像我这种天天写as脚本的人来说太好了,知道了怎样去执行脚本的。对于自己怎样写出性能高效的代码很有用。在解决问题上更是多了一扇窗。
前不久,我就通过分析虚拟机的执行过程解决过一个看似很难理解的问题。
问题是这样的,as运行时报找不到A类。A类是需要通过加载外部类库才能得到。但他这时并没有去new A类,程序就直接报错了.
我通过分析,是虚拟机在执行他那个方法前,去寻找了A类。因为虚拟机在执行脚本函数前先去找到函数引用到的类。而恰恰他在那个函数里用到了A类的一个静态变量。虽然没有去new A类,但在函数用到了A类,虚拟机在执行脚本函数时,就会去找A类。
解决方案很简单,直接把引用A类的静态变量去掉换成等值的字符串就可以了。
如果知道虚拟机执行代码的过程,对于你解决问题多了一个分析的思路。那我们就开始吧。
我说的这个as2虚拟机源码来自于http://www.as3url.com/ 。这个网站很不错,有很多好东西。值的去深入了解一下。
虚拟机运行的是编译好的字节码。像Java虚拟机。他们都有自己的字节码格式。虚拟机只执行字节码。那我们写的代码该怎么办呢?不用担心,我们写的代码会被编译器编译成虚拟机能执行的字节码。
又谈到了编译器,感觉蛋疼了。编译器原理一大堆理论知识,我们这些虾米怎么才能搞得懂啊。淡定,一切都是浮云,我们只要静下心来就一切都可以搞定。
编译器编译出来的是字节码。而这个字节码其实就是一个堆载结构的数据。而堆载结构里面肯定包含我们声明的变量,和我们写的函数。
有一点点思路了吧。
我们先看一下代码,在一步一步深入下去。
var src:Array = [
"function putline(){ var a=[]; for(var i = 0;i < 50;i++) a.push('-'); trace(a.join('')); }",
"function fibo(n, a){",
" trace('called fibo('+n+', ['+a.join(',')+'])');",
" if (n == 0) {a.push(0); return;}",
" else if (n == 1) {fibo(n-1, a); a.push(1); return;}",
" fibo(n-1, a);",
" a.push(a[a.length-1] + a[a.length-2]);",
"}",
"function do_test(n){",
" putline();",
" var fibo_nums = [];",
" fibo(n, fibo_nums);",
" putline(); trace('result: '+fibo_nums.join(' '));",
" return 'OK';",
"}"
]//我们写的代码
var lx:Scanner = new Scanner(src.join("\n"));//语法规则解析
var psr:Parser = new Parser(lx);//代码解析器
var bc:Array = psr.parse();//解析代码,并生成代码的字节码,你也看到了吧返回的是一个数组,这个数组元素只包含了数字和字符串
var vm:VirtualMachine = new VirtualMachine();//这就是虚拟机类了
vm.setByteCode(bc);//装载字节码
vm.getGlobalObject().trace = puts;//为虚拟机的全局变量的熟悉赋值,在脚本中我们使用的系统函数
vm.execute();//执行代码
var rval:Object = vm.invokeScriptFunction("do_test", [10]);
puts("retval: " + rval);
今天就写到这吧

浙公网安备 33010602011771号