|
@@ -35,7 +35,7 @@ type VM struct {
|
|
|
|
|
|
|
|
func New(byteCode *compiler.ByteCode) *VM {
|
|
func New(byteCode *compiler.ByteCode) *VM {
|
|
|
mainFn := &object.CompileFunction{Instructions: byteCode.Instructions}
|
|
mainFn := &object.CompileFunction{Instructions: byteCode.Instructions}
|
|
|
- mainFrame := NewFrame(mainFn)
|
|
|
|
|
|
|
+ mainFrame := NewFrame(mainFn, 0)
|
|
|
|
|
|
|
|
frames := make([]*Frame, MaxFrames)
|
|
frames := make([]*Frame, MaxFrames)
|
|
|
frames[0] = mainFrame
|
|
frames[0] = mainFrame
|
|
@@ -189,26 +189,43 @@ func (vm *VM) Run() error {
|
|
|
if !ok {
|
|
if !ok {
|
|
|
return fmt.Errorf("calling non-function")
|
|
return fmt.Errorf("calling non-function")
|
|
|
}
|
|
}
|
|
|
- frame := NewFrame(fn)
|
|
|
|
|
|
|
+ frame := NewFrame(fn, vm.sp)
|
|
|
vm.pushFrame(frame)
|
|
vm.pushFrame(frame)
|
|
|
|
|
+ vm.sp = frame.basePointer + fn.NumLocals
|
|
|
case code.OpReturnValue:
|
|
case code.OpReturnValue:
|
|
|
returnValue := vm.pop()
|
|
returnValue := vm.pop()
|
|
|
|
|
|
|
|
- vm.popFrame()
|
|
|
|
|
- vm.pop()
|
|
|
|
|
|
|
+ frame := vm.popFrame()
|
|
|
|
|
+ vm.sp = frame.basePointer - 1
|
|
|
|
|
|
|
|
err := vm.push(returnValue)
|
|
err := vm.push(returnValue)
|
|
|
if err != nil {
|
|
if err != nil {
|
|
|
return err
|
|
return err
|
|
|
}
|
|
}
|
|
|
case code.OpReturn:
|
|
case code.OpReturn:
|
|
|
- vm.popFrame()
|
|
|
|
|
- vm.pop()
|
|
|
|
|
|
|
+ frame := vm.popFrame()
|
|
|
|
|
+ vm.sp = frame.basePointer - 1
|
|
|
|
|
|
|
|
err := vm.push(Null)
|
|
err := vm.push(Null)
|
|
|
if err != nil {
|
|
if err != nil {
|
|
|
return err
|
|
return err
|
|
|
}
|
|
}
|
|
|
|
|
+ case code.OpSetLocal:
|
|
|
|
|
+ localIndex := code.ReadUint8(ins[ip+1:])
|
|
|
|
|
+ vm.currentFrame().ip += 1
|
|
|
|
|
+
|
|
|
|
|
+ frame := vm.currentFrame()
|
|
|
|
|
+ vm.stack[frame.basePointer+int(localIndex)] = vm.pop()
|
|
|
|
|
+ case code.OpGetLocal:
|
|
|
|
|
+ localIndex := code.ReadUint8(ins[ip+1:])
|
|
|
|
|
+ vm.currentFrame().ip += 1
|
|
|
|
|
+
|
|
|
|
|
+ frame := vm.currentFrame()
|
|
|
|
|
+
|
|
|
|
|
+ err := vm.push(vm.stack[frame.basePointer+int(localIndex)])
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ return err
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|