JMP 指令中的额外 PC 增量

作者: KSpaceer创建于 2024年5月13日更新于 2026年2月12日
  1. What version of GopherLua are you using? : v1.1.1
  2. What version of Go are you using? : 1.22.2
  3. What operating system and processor architecture are you using? : Ubuntu 22.04 x86_64
  4. What did you do? :
lua
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))
  1. What did you expect to see? :
false
false
  1. What did you see instead? :
false
true

It 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

内容来源: yuin/gopher-lua