Extra PC increment in JMP instruction
You must post issues only here. Questions, ideas must be posted in discussions.
- GopherLua is a Lua5.1 implementation. You should be familiar with Lua programming language. Have you read Lua 5.1 reference manual carefully?
- GopherLua is a Lua5.1 implementation. In Lua, to keep it simple, it is more important to remove functionalities rather than to add functionalities unlike other languages . If you are going to introduce some new cool functionalities into the GopherLua code base and the functionalities can be implemented by existing APIs, It should be implemented as a library.
Please answer the following before submitting your issue:
- What version of GopherLua are you using? : v1.1.1
- What version of Go are you using? : 1.22.2
- What operating system and processor architecture are you using? : Ubuntu 22.04 x86_64
- What did you do? :
function greaterThan(a, b)
return a > b
end
function lessThan(a, b)
return a < b
end
function betweenViaOperators(val, a, b)
local result = true
result = result and (val > a and val < b)
return result
end
function betweenViaFunctions(val, a, b)
local result = true
result = result and (greaterThan(val, a) and lessThan(val, b))
return result
end
print(betweenViaOperators(2, 3, 5))
print(betweenViaFunctions(2, 3, 5))- What did you expect to see? :
false
false- What did you see instead? :
false
trueIt seems to happen because of some optimizations or something like that. In case of comparison via functions we have following bytecode for the betweenViaFunctions function:
; function [3] definition (level 2)
; 0 upvalues, 3 params, 7 stacks
.local val ; 0
.local a ; 1
.local b ; 2
.local result ; 3
.const greaterThan ; 0
.const lessThan ; 1
[001] LOADBOOL | 3, 1, 0; R(3) := (Bool)1; if (0) pc++ (line:17)
[002] TEST | 3, 3, 0; if not (R(3) <=> 0) then pc++ (line:18)
[003] JMP | 0, 11; pc+=11 (line:18)
[004] GETGLOBAL | 4, 0; R(4) := Gbl[Kst(0)] (line:18)
[005] MOVEN | 5, 0, 1; R(5) := R(0); followed by 1 MOVE ops (line:18)
[006] MOVE | 6, 1, 0; R(6) := R(1) (line:18)
[007] CALL | 4, 3, 2; R(4) ... R(4+2-2) := R(4)(R(4+1) ... R(4+3-1)) (line:18)
[008] TEST | 4, 0, 0; if not (R(4) <=> 0) then pc++ (line:18)
[009] JMP | 0, 5; pc+=5 (line:18)
[010] GETGLOBAL | 4, 1; R(4) := Gbl[Kst(1)] (line:18)
[011] MOVEN | 5, 0, 1; R(5) := R(0); followed by 1 MOVE ops (line:18)
[012] MOVE | 6, 2, 0; R(6) := R(2) (line:18)
[013] CALL | 4, 3, 2; R(4) ... R(4+2-2) := R(4)(R(4+1) ... R(4+3-1)) (line:18)
[014] MOVE | 3, 4, 0; R(3) := R(4) (line:18)
[015] RETURN | 3, 2, 0; return R(3) ... R(3+2-2) (line:19)
[016] RETURN | 0, 1, 0; return R(0) ... R(0+1-2) (line:20)
; end of functionPlease pay attention for the 003 and 009 JMP instructions: they go to the 014 MOVE instruction, which is responisble for the result variable assignment. When JMP instructions are executed, the program counter points to the MOVE instruction, and then in the main loop (vm.go:30) the PC increments. After this operation the PC points to the 015 RETURN, that leads to the returning of wrong value.
For comparsion, there is the betweenViaOperators bytecode:
; function [2] definition (level 2)
; 0 upvalues, 3 params, 4 stacks
.local val ; 0
.local a ; 1
.local b ; 2
.local result ; 3
[001] LOADBOOL | 3, 1, 0; R(3) := (Bool)1; if (0) pc++ (line:11)
[002] TEST | 3, 3, 0; if not (R(3) <=> 0) then pc++ (line:12)
[003] JMP | 0, 6; pc+=6 (line:12)
[004] LT | 0, 1, 0; if ((RK(1) < RK(0)) ~= 0) then pc++ (line:12)
[005] JMP | 0, 2; pc+=2 (line:12)
[006] LT | 1, 0, 2; if ((RK(0) < RK(2)) ~= 1) then pc++ (line:12)
[007] JMP | 0, 1; pc+=1 (line:12)
[008] LOADBOOL | 3, 0, 1; R(3) := (Bool)0; if (1) pc++ (line:12)
[009] LOADBOOL | 3, 1, 0; R(3) := (Bool)1; if (0) pc++ (line:12)
[010] RETURN | 3, 2, 0; return R(3) ... R(3+2-2) (line:13)
[011] RETURN | 0, 1, 0; return R(0) ... R(0+1-2) (line:14)
; end of functionWe can see that JMP instructions will lead to the 009 LOADBOOL instruction (considering PC increment in the main loop), which is correct and leads to the true returning.
Source: yuin/gopher-lua