vm: allow to call VM methods from outside

Abstract out (*VM).Call method and use in in CALL* opcodes.
This commit is contained in:
Evgenii Stratonikov 2020-07-24 11:56:35 +03:00
parent 6ecd1ae437
commit 13b9eda08d

View file

@ -1235,13 +1235,9 @@ func (v *VM) execute(ctx *Context, op opcode.Opcode, parameter []byte) (err erro
case opcode.CALL, opcode.CALLL: case opcode.CALL, opcode.CALLL:
v.checkInvocationStackSize() v.checkInvocationStackSize()
newCtx := ctx.Copy() // Note: jump offset must be calculated regarding to new context,
newCtx.local = nil // but it is cloned and thus has the same script and instruction pointer.
newCtx.arguments = nil v.Call(ctx, v.getJumpOffset(ctx, parameter))
v.istack.PushVal(newCtx)
offset := v.getJumpOffset(newCtx, parameter)
v.Jump(newCtx, offset)
case opcode.CALLA: case opcode.CALLA:
ptr := v.estack.Pop().Item().(*stackitem.Pointer) ptr := v.estack.Pop().Item().(*stackitem.Pointer)
@ -1249,11 +1245,7 @@ func (v *VM) execute(ctx *Context, op opcode.Opcode, parameter []byte) (err erro
panic("invalid script in pointer") panic("invalid script in pointer")
} }
newCtx := ctx.Copy() v.Call(ctx, ptr.Position())
newCtx.local = nil
newCtx.arguments = nil
v.istack.PushVal(newCtx)
v.Jump(newCtx, ptr.Position())
case opcode.SYSCALL: case opcode.SYSCALL:
interopID := GetInteropID(parameter) interopID := GetInteropID(parameter)
@ -1471,6 +1463,16 @@ func (v *VM) Jump(ctx *Context, offset int) {
ctx.nextip = offset ctx.nextip = offset
} }
// Call calls method by offset. It is similar to Jump but also
// pushes new context to the invocation state
func (v *VM) Call(ctx *Context, offset int) {
newCtx := ctx.Copy()
newCtx.local = nil
newCtx.arguments = nil
v.istack.PushVal(newCtx)
v.Jump(newCtx, offset)
}
// getJumpOffset returns instruction number in a current context // getJumpOffset returns instruction number in a current context
// to a which JMP should be performed. // to a which JMP should be performed.
// parameter should have length either 1 or 4 and // parameter should have length either 1 or 4 and