Lua5.2種除了for循環之外,其他的各種循環都使用關係和邏輯指令,配合JMP指令來完成。
- local a = 0;
- while(a < 10) do
- a = a + 1;
- end
- 1 [1] LOADK 0 -1 ; 0
- 2 [2] LT 0 0 -2 ; - 10
- 3 [2] JMP 0 2 ; to 6
- 4 [3] ADD 0 0 -3 ; - 1
- 5 [3] JMP 0 -4 ; to 2
- 6 [4] RETURN 0 1
對於for循環,Lua5.2使用了兩套專門的指令,分別對應numeric for loop和generic for loop。
name | args | desc |
---|---|---|
OP_FORLOOP | A sBx | R(A)+=R(A+2); if R(A) <?= R(A+1) then { pc+=sBx; R(A+3)=R(A) } |
OP_FORPREP | A sBx | R(A)-=R(A+2); pc+=sBx |
- local a;
- for i = 1, 10 do
- a = i;
- end
- main <test.lua:0,0> (8 instructions at 0x80048eb0)
- 0+ params, 5 slots, 1 upvalue, 5 locals, 2 constants, 0 functions
- 1 [1] LOADNIL 0 0
- 2 [2] LOADK 1 -1 ; 1
- 3 [2] LOADK 2 -2 ; 10
- 4 [2] LOADK 3 -1 ; 1
- 5 [2] FORPREP 1 1 ; to 7
- 6 [3] MOVE 0 4
- 7 [2] FORLOOP 1 -2 ; to 6
- 8 [4] RETURN 0 1
- constants (2) for 0x80048eb0:
- 1 1
- 2 10
- locals (5) for 0x80048eb0:
- 0 a 2 9
- 1 (for index) 5 8
- 2 (for limit) 5 8
- 3 (for step) 5 8
- 4 i 6 7
- upvalues (1) for 0x80048eb0:
- 0 _ENV 1 0
上例中2~4行初始化循環使用的3個內部局部變量。第五行FORPREP用於準備這個循環,將for index減去一個for step,然後跳轉到第七行。第七行的FORLOOP將for index加上一個for step,然後與for limit進行比較。如果小於等於for limit,則將i設置成for index,然後跳回第六行。否則就退出循環。我們可以看到,i並不用於真正的循環計數,而只是在每次循環時被賦予真正的計數器for index的值而已,所以在循環中修改i不會影響循環計數。
name | args | desc |
---|---|---|
OP_TFORCALL | AC | R(A+3), ... ,R(A+2+C) := R(A)(R(A+1), R(A+2)); |
OP_TFORLOOP | A sBx | if R(A+1) ~= nil then { R(A)=R(A+1); pc += sBx } |
- for i,v in 1,2,3 do
- a = 1;
- end
- main <test.lua:0,0> (8 instructions at 0x80048eb0)
- 0+ params, 6 slots, 1 upvalue, 5 locals, 4 constants, 0 functions
- 1 [1] LOADK 0 -1 ; 1
- 2 [1] LOADK 1 -2 ; 2
- 3 [1] LOADK 2 -3 ; 3
- 4 [1] JMP 0 1 ; to 6
- 5 [2] SETTABUP 0 -4 -1 ; _ENV "a" 1
- 6 [1] TFORCALL 0 2
- 7 [1] TFORLOOP 2 -3 ; to 5
- 8 [3] RETURN 0 1
- constants (4) for 0x80048eb0:
- 1 1
- 2 2
- 3 3
- 4 "a"
- locals (5) for 0x80048eb0:
- 0 (for generator) 4 8
- 1 (for state) 4 8
- 2 (for control) 4 8
- 3 i 5 6
- 4 v 5 6
- upvalues (1) for 0x80048eb0:
- 0 _ENV 1 0
Generic for loop內部也使用了3個局部變量來控制循環,分別是"for generator”,“for state”和“for control”。for generator用來存放迭代使用的closure,每次迭代都會調用這個closure。for state和for control用於存放傳給for generator的兩個參數。Generic for loop還使用自定義的局部變量i,v,用來存儲for generator的返回值。
上例中1~3行使用in後面的表達式列表(1,2,3)初始化3個內部使用的局部變量。第四行JMP調轉到第六行。TFORCALL教用寄存器0(for generator)中的closure,傳入for state和for control,並將結果返回給自定義局部變量列表i和v。第七行調用TFORLOOP進行循環條件判斷,判斷i是否為空。如果不為空,將i的值賦給for control,然後跳轉到第五行,進行循環。
No comments:
Post a Comment