Skip to content

Commit

Permalink
[OpJumpFalse, OpAndJump, OpOrJump, OpJump], these four instructions h…
Browse files Browse the repository at this point in the history
…ave 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: 王录祥 <[email protected]>
  • Loading branch information
wlxwlxwlx and 王录祥 authored Dec 5, 2023
1 parent 92cbb9b commit 18424de
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 11 deletions.
6 changes: 6 additions & 0 deletions instructions.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,12 @@ func MakeInstruction(opcode parser.Opcode, operands ...int) []byte {
n := uint16(o)
instruction[offset] = byte(n >> 8)
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
}
Expand Down
10 changes: 6 additions & 4 deletions parser/opcodes.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,10 +106,10 @@ var OpcodeOperands = [...][]int{
OpNotEqual: {},
OpMinus: {},
OpLNot: {},
OpJumpFalsy: {2},
OpAndJump: {2},
OpOrJump: {2},
OpJump: {2},
OpJumpFalsy: {4},
OpAndJump: {4},
OpOrJump: {4},
OpJump: {4},
OpNull: {},
OpGetGlobal: {2},
OpSetGlobal: {2},
Expand Down Expand Up @@ -149,6 +149,8 @@ func ReadOperands(numOperands []int, ins []byte) (operands []int, offset int) {
operands = append(operands, int(ins[offset]))
case 2:
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
}
Expand Down
14 changes: 7 additions & 7 deletions vm.go
Original file line number Diff line number Diff line change
Expand Up @@ -218,30 +218,30 @@ func (v *VM) run() {
return
}
case parser.OpJumpFalsy:
v.ip += 2
v.ip += 4
v.sp--
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
}
case parser.OpAndJump:
v.ip += 2
v.ip += 4
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
} else {
v.sp--
}
case parser.OpOrJump:
v.ip += 2
v.ip += 4
if v.stack[v.sp-1].IsFalsy() {
v.sp--
} 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
}
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
case parser.OpSetGlobal:
v.ip += 2
Expand Down

0 comments on commit 18424de

Please sign in to comment.