lua的字节码在lopcodes.h里面
那么lua编译出来的字节码是个什么东西呢?简单的修改代码就能揭开字节码的面纱
lua的执行在lvm.c里面,luaV_execute有一大堆的case语句,那是对每种字节码都有对应的执行语句。在每个执行语句里面加上Trace(...)就可以了。
vmdispatch (GET_OPCODE(i)) {
vmcase(OP_MOVE,
Trace("vm--OP_MOVE");
setobjs2s(L, ra, RB(i));
)
vmcase(OP_LOADK,
TValue *rb = k + GETARG_Bx(i);
setobj2s(L, ra, rb);
Trace("vm--OP_LOADK");
)
数字运算
通过对比发现立即数,非变量式的运算做了优化,字节码少很多
lua语句 | print("begin-------------------") d = 3+3*12/12-(5%13)+math.abs(12) print("end-------------------") print(d) | a = 3 b = 5 c = 12 print("begin-------------------") d = a+a*12/c-(b%13)+math.abs(c) print("end-------------------") print(d) |
字节码 | begin------------------- vm--OP_CALL vm--OP_GETTABUP vm--OP_GETTABLE vm--OP_LOADK vm--OP_CALL vm--OP_ADD vm--OP_SETTABUP vm--OP_GETTABUP vm--OP_LOADK end------------------- | begin------------------- vm--OP_CALL vm--OP_GETTABUP vm--OP_GETTABUP vm--OP_MUL vm--OP_GETTABUP vm--OP_DIV vm--OP_ADD vm--OP_GETTABUP vm--OP_MOD vm--OP_SUB vm--OP_GETTABUP vm--OP_GETTABLE vm--OP_GETTABUP vm--OP_CALL vm--OP_ADD vm--OP_SETTABUP vm--OP_GETTABUP vm--OP_LOADK end------------------- |
可以看到基本字节码的数量跟c编译器变出的汇编语言数量差不多。这也解释了我在另一文章得到的脚本语言比c语言慢10倍。
lua语言 | function test_if(t) a = 3 if (t<2) then a = 4 else a = 5 end return a end print("begin-------------------") r = test_if(10) print("end-------------------") print(r) | function test_for(t) a = 3 for v = 1,t,1 do a = a*v end return a end print("begin-------------------") r = test_for(10) print("end-------------------") print(r) | function test_fuc(t) if t == 1 then return 1 else return t*test_fuc(t-1) end end print("begin-------------------") r = test_fuc(10) print("end-------------------") print(r) |
字节码 | begin------------------- vm--OP_CALL vm--OP_GETTABUP vm--OP_LOADK vm--newframe vm--OP_SETTABUP vm--OP_LT vm--OP_SETTABUP vm--OP_GETTABUP vm--newframe vm--OP_SETTABUP vm--OP_GETTABUP vm--OP_LOADK end------------------- | begin------------------- vm--OP_CALL vm--OP_GETTABUP vm--OP_LOADK vm--newframe vm--OP_SETTABUP vm--OP_LOADK vm--OP_MOVE vm--OP_LOADK vm--OP_FORPREP vm--OP_FORLOOP vm--OP_GETTABUP vm--OP_MUL vm--OP_SETTABUP vm--OP_FORLOOP vm--OP_GETTABUP vm--OP_MUL vm--OP_SETTABUP vm--OP_FORLOOP vm--OP_GETTABUP vm--OP_MUL vm--OP_SETTABUP vm--OP_FORLOOP vm--OP_GETTABUP vm--OP_MUL vm--OP_SETTABUP vm--OP_FORLOOP vm--OP_GETTABUP vm--OP_MUL vm--OP_SETTABUP vm--OP_FORLOOP vm--OP_GETTABUP vm--OP_MUL vm--OP_SETTABUP vm--OP_FORLOOP vm--OP_GETTABUP vm--OP_MUL vm--OP_SETTABUP vm--OP_FORLOOP vm--OP_GETTABUP vm--OP_MUL vm--OP_SETTABUP vm--OP_FORLOOP vm--OP_GETTABUP vm--OP_MUL vm--OP_SETTABUP vm--OP_FORLOOP vm--OP_GETTABUP vm--OP_MUL vm--OP_SETTABUP vm--OP_FORLOOP vm--OP_GETTABUP vm--newframe vm--OP_SETTABUP vm--OP_GETTABUP vm--OP_LOADK end------------------- | begin------------------- vm--OP_CALL vm--OP_GETTABUP vm--OP_LOADK vm--newframe vm--OP_EQ vm--OP_GETTABUP vm--OP_SUB vm--newframe vm--OP_EQ vm--OP_GETTABUP vm--OP_SUB vm--newframe vm--OP_EQ vm--OP_GETTABUP vm--OP_SUB vm--newframe vm--OP_EQ vm--OP_GETTABUP vm--OP_SUB vm--newframe vm--OP_EQ vm--OP_GETTABUP vm--OP_SUB vm--newframe vm--OP_EQ vm--OP_GETTABUP vm--OP_SUB vm--newframe vm--OP_EQ vm--OP_GETTABUP vm--OP_SUB vm--newframe vm--OP_EQ vm--OP_GETTABUP vm--OP_SUB vm--newframe vm--OP_EQ vm--OP_GETTABUP vm--OP_SUB vm--newframe vm--OP_EQ vm--OP_LOADK vm--newframe vm--OP_MUL vm--newframe vm--OP_MUL vm--newframe vm--OP_MUL vm--newframe vm--OP_MUL vm--newframe vm--OP_MUL vm--newframe vm--OP_MUL vm--newframe vm--OP_MUL vm--newframe vm--OP_MUL vm--newframe vm--OP_MUL vm--newframe vm--OP_SETTABUP vm--OP_GETTABUP vm--OP_LOADK end------------------- |
lua语句 | function test_if(t) a = 3 if (t<2) then a = 4 else a = 5 end return a end print("begin-------------------") r = test_if(10) print("end-------------------") print(r) | function test_for(t) a = 3 for v = 1,t,1 do a = a*v end return a end print("begin-------------------") r = test_for(10) print("end-------------------") print(r) | function test_fuc(t) if t == 1 then return 1 else return t*test_fuc(t-1) end end print("begin-------------------") r = test_fuc(10) print("end-------------------") print(r) |
字节码 | begin------------------- vm--OP_CALL vm--OP_GETTABUP vm--OP_LOADK vm--newframe vm--OP_SETTABUP vm--OP_LT vm--OP_SETTABUP vm--OP_GETTABUP vm--newframe vm--OP_SETTABUP vm--OP_GETTABUP vm--OP_LOADK end------------------- |