[OpJumpFalse, OpAndJump, OpOrJump, OpJump], these four instructions have been changed to use 4 bytes to avoid precision loss and panic when the number of instructions exceeds the maximum of 16 bits (65535) (#433)
Co-authored-by: 王录祥 <wanglx@smartsteps.com>
This commit is contained in:
parent
92cbb9bff0
commit
18424deb5a
3 changed files with 19 additions and 11 deletions
|
@ -28,6 +28,12 @@ func MakeInstruction(opcode parser.Opcode, operands ...int) []byte {
|
||||||
n := uint16(o)
|
n := uint16(o)
|
||||||
instruction[offset] = byte(n >> 8)
|
instruction[offset] = byte(n >> 8)
|
||||||
instruction[offset+1] = byte(n)
|
instruction[offset+1] = byte(n)
|
||||||
|
case 4:
|
||||||
|
n := uint32(o)
|
||||||
|
instruction[offset] = byte(n >> 24)
|
||||||
|
instruction[offset+1] = byte(n >> 16)
|
||||||
|
instruction[offset+2] = byte(n >> 8)
|
||||||
|
instruction[offset+3] = byte(n)
|
||||||
}
|
}
|
||||||
offset += width
|
offset += width
|
||||||
}
|
}
|
||||||
|
|
|
@ -106,10 +106,10 @@ var OpcodeOperands = [...][]int{
|
||||||
OpNotEqual: {},
|
OpNotEqual: {},
|
||||||
OpMinus: {},
|
OpMinus: {},
|
||||||
OpLNot: {},
|
OpLNot: {},
|
||||||
OpJumpFalsy: {2},
|
OpJumpFalsy: {4},
|
||||||
OpAndJump: {2},
|
OpAndJump: {4},
|
||||||
OpOrJump: {2},
|
OpOrJump: {4},
|
||||||
OpJump: {2},
|
OpJump: {4},
|
||||||
OpNull: {},
|
OpNull: {},
|
||||||
OpGetGlobal: {2},
|
OpGetGlobal: {2},
|
||||||
OpSetGlobal: {2},
|
OpSetGlobal: {2},
|
||||||
|
@ -149,6 +149,8 @@ func ReadOperands(numOperands []int, ins []byte) (operands []int, offset int) {
|
||||||
operands = append(operands, int(ins[offset]))
|
operands = append(operands, int(ins[offset]))
|
||||||
case 2:
|
case 2:
|
||||||
operands = append(operands, int(ins[offset+1])|int(ins[offset])<<8)
|
operands = append(operands, int(ins[offset+1])|int(ins[offset])<<8)
|
||||||
|
case 4:
|
||||||
|
operands = append(operands, int(ins[offset+3])|int(ins[offset+2])<<8|int(ins[offset+1])<<16|int(ins[offset])<<24)
|
||||||
}
|
}
|
||||||
offset += width
|
offset += width
|
||||||
}
|
}
|
||||||
|
|
14
vm.go
14
vm.go
|
@ -218,30 +218,30 @@ func (v *VM) run() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
case parser.OpJumpFalsy:
|
case parser.OpJumpFalsy:
|
||||||
v.ip += 2
|
v.ip += 4
|
||||||
v.sp--
|
v.sp--
|
||||||
if v.stack[v.sp].IsFalsy() {
|
if v.stack[v.sp].IsFalsy() {
|
||||||
pos := int(v.curInsts[v.ip]) | int(v.curInsts[v.ip-1])<<8
|
pos := int(v.curInsts[v.ip]) | int(v.curInsts[v.ip-1])<<8 | int(v.curInsts[v.ip-2])<<16 | int(v.curInsts[v.ip-3])<<24
|
||||||
v.ip = pos - 1
|
v.ip = pos - 1
|
||||||
}
|
}
|
||||||
case parser.OpAndJump:
|
case parser.OpAndJump:
|
||||||
v.ip += 2
|
v.ip += 4
|
||||||
if v.stack[v.sp-1].IsFalsy() {
|
if v.stack[v.sp-1].IsFalsy() {
|
||||||
pos := int(v.curInsts[v.ip]) | int(v.curInsts[v.ip-1])<<8
|
pos := int(v.curInsts[v.ip]) | int(v.curInsts[v.ip-1])<<8 | int(v.curInsts[v.ip-2])<<16 | int(v.curInsts[v.ip-3])<<24
|
||||||
v.ip = pos - 1
|
v.ip = pos - 1
|
||||||
} else {
|
} else {
|
||||||
v.sp--
|
v.sp--
|
||||||
}
|
}
|
||||||
case parser.OpOrJump:
|
case parser.OpOrJump:
|
||||||
v.ip += 2
|
v.ip += 4
|
||||||
if v.stack[v.sp-1].IsFalsy() {
|
if v.stack[v.sp-1].IsFalsy() {
|
||||||
v.sp--
|
v.sp--
|
||||||
} else {
|
} else {
|
||||||
pos := int(v.curInsts[v.ip]) | int(v.curInsts[v.ip-1])<<8
|
pos := int(v.curInsts[v.ip]) | int(v.curInsts[v.ip-1])<<8 | int(v.curInsts[v.ip-2])<<16 | int(v.curInsts[v.ip-3])<<24
|
||||||
v.ip = pos - 1
|
v.ip = pos - 1
|
||||||
}
|
}
|
||||||
case parser.OpJump:
|
case parser.OpJump:
|
||||||
pos := int(v.curInsts[v.ip+2]) | int(v.curInsts[v.ip+1])<<8
|
pos := int(v.curInsts[v.ip+4]) | int(v.curInsts[v.ip+3])<<8 | int(v.curInsts[v.ip+2])<<16 | int(v.curInsts[v.ip+1])<<24
|
||||||
v.ip = pos - 1
|
v.ip = pos - 1
|
||||||
case parser.OpSetGlobal:
|
case parser.OpSetGlobal:
|
||||||
v.ip += 2
|
v.ip += 2
|
||||||
|
|
Loading…
Reference in a new issue