mirror of
https://github.com/MontFerret/ferret.git
synced 2025-08-15 20:02:56 +02:00
Refactor iterator-related opcodes (OpIterSkip
, OpIterLimit
) to fix operand handling and label resolution in vm
, emitter
, and disassembler
. Update instruction formatting and improve disassembler output.
This commit is contained in:
@@ -41,7 +41,7 @@ func collectLabels(bytecode []vm.Instruction) map[int]string {
|
|||||||
|
|
||||||
for _, instr := range bytecode {
|
for _, instr := range bytecode {
|
||||||
switch instr.Opcode {
|
switch instr.Opcode {
|
||||||
case vm.OpJump, vm.OpJumpIfFalse, vm.OpJumpIfTrue:
|
case vm.OpJump, vm.OpJumpIfFalse, vm.OpJumpIfTrue, vm.OpIterNext, vm.OpIterSkip, vm.OpIterLimit:
|
||||||
target := int(instr.Operands[0])
|
target := int(instr.Operands[0])
|
||||||
if _, ok := labels[target]; !ok {
|
if _, ok := labels[target]; !ok {
|
||||||
labels[target] = fmt.Sprintf("@L%d", counter)
|
labels[target] = fmt.Sprintf("@L%d", counter)
|
||||||
@@ -77,9 +77,12 @@ func disasmLine(ip int, instr vm.Instruction, p *vm.Program, labels map[int]stri
|
|||||||
case vm.OpJump:
|
case vm.OpJump:
|
||||||
out = fmt.Sprintf("%d: %s %s", ip, opcode, labelOrAddr(int(ops[0]), labels))
|
out = fmt.Sprintf("%d: %s %s", ip, opcode, labelOrAddr(int(ops[0]), labels))
|
||||||
|
|
||||||
case vm.OpJumpIfTrue, vm.OpJumpIfFalse:
|
case vm.OpJumpIfTrue, vm.OpJumpIfFalse, vm.OpIterNext:
|
||||||
out = fmt.Sprintf("%d: %s %s %s", ip, opcode, labelOrAddr(int(ops[0]), labels), ops[1])
|
out = fmt.Sprintf("%d: %s %s %s", ip, opcode, labelOrAddr(int(ops[0]), labels), ops[1])
|
||||||
|
|
||||||
|
case vm.OpIterSkip, vm.OpIterLimit:
|
||||||
|
out = fmt.Sprintf("%d: %s %s %s %s", ip, opcode, labelOrAddr(int(ops[0]), labels), ops[1], ops[2])
|
||||||
|
|
||||||
case vm.OpReturn:
|
case vm.OpReturn:
|
||||||
out = fmt.Sprintf("%d: %s R%d", ip, opcode, ops[0])
|
out = fmt.Sprintf("%d: %s R%d", ip, opcode, ops[0])
|
||||||
|
|
||||||
|
@@ -25,15 +25,23 @@ func (e *Emitter) EmitIterValue(dst, iterator vm.Operand) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (e *Emitter) EmitIterSkip(state, count vm.Operand, label Label) {
|
func (e *Emitter) EmitIterSkip(state, count vm.Operand, label Label) {
|
||||||
e.EmitABx(vm.OpIterSkip, state, count, jumpPlaceholder)
|
e.instructions = append(e.instructions, vm.Instruction{
|
||||||
|
Opcode: vm.OpIterSkip,
|
||||||
|
Operands: [3]vm.Operand{jumpPlaceholder, state, count},
|
||||||
|
})
|
||||||
|
|
||||||
pos := len(e.instructions) - 1
|
pos := len(e.instructions) - 1
|
||||||
e.addLabelRef(pos, 2, label)
|
e.addLabelRef(pos, 0, label)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Emitter) EmitIterLimit(state, count vm.Operand, jump Label) {
|
func (e *Emitter) EmitIterLimit(state, count vm.Operand, label Label) {
|
||||||
e.EmitABx(vm.OpIterLimit, state, count, jumpPlaceholder)
|
e.instructions = append(e.instructions, vm.Instruction{
|
||||||
|
Opcode: vm.OpIterLimit,
|
||||||
|
Operands: [3]vm.Operand{jumpPlaceholder, state, count},
|
||||||
|
})
|
||||||
|
|
||||||
pos := len(e.instructions) - 1
|
pos := len(e.instructions) - 1
|
||||||
e.addLabelRef(pos, 2, jump)
|
e.addLabelRef(pos, 0, label)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ─── Value & Memory ──────────────────────────────────────────────────────
|
// ─── Value & Memory ──────────────────────────────────────────────────────
|
||||||
|
18
pkg/vm/vm.go
18
pkg/vm/vm.go
@@ -461,25 +461,23 @@ loop:
|
|||||||
iterator := reg[src1].(*internal.Iterator)
|
iterator := reg[src1].(*internal.Iterator)
|
||||||
reg[dst] = iterator.Key()
|
reg[dst] = iterator.Key()
|
||||||
case OpIterSkip:
|
case OpIterSkip:
|
||||||
state := runtime.ToIntSafe(ctx, reg[dst])
|
state := runtime.ToIntSafe(ctx, reg[src1])
|
||||||
threshold := runtime.ToIntSafe(ctx, reg[src1])
|
threshold := runtime.ToIntSafe(ctx, reg[src2])
|
||||||
jump := int(src2)
|
|
||||||
|
|
||||||
if state < threshold {
|
if state < threshold {
|
||||||
state++
|
state++
|
||||||
reg[dst] = state
|
reg[src1] = state
|
||||||
vm.pc = jump
|
vm.pc = int(dst)
|
||||||
}
|
}
|
||||||
case OpIterLimit:
|
case OpIterLimit:
|
||||||
state := runtime.ToIntSafe(ctx, reg[dst])
|
state := runtime.ToIntSafe(ctx, reg[src1])
|
||||||
threshold := runtime.ToIntSafe(ctx, reg[src1])
|
threshold := runtime.ToIntSafe(ctx, reg[src2])
|
||||||
jump := int(src2)
|
|
||||||
|
|
||||||
if state < threshold {
|
if state < threshold {
|
||||||
state++
|
state++
|
||||||
reg[dst] = state
|
reg[src1] = state
|
||||||
} else {
|
} else {
|
||||||
vm.pc = jump
|
vm.pc = int(dst)
|
||||||
}
|
}
|
||||||
case OpStream:
|
case OpStream:
|
||||||
observable, eventName, options, err := vm.castSubscribeArgs(reg[dst], reg[src1], reg[src2])
|
observable, eventName, options, err := vm.castSubscribeArgs(reg[dst], reg[src1], reg[src2])
|
||||||
|
Reference in New Issue
Block a user