diff --git a/pkg/compiler/vm_test.go b/pkg/compiler/vm_test.go index 694975b86..59cdae635 100644 --- a/pkg/compiler/vm_test.go +++ b/pkg/compiler/vm_test.go @@ -87,7 +87,7 @@ func invokeMethod(t *testing.T, method string, script []byte, v *vm.VM, di *comp } require.True(t, mainOffset >= 0) v.LoadScriptWithFlags(script, callflag.All) - v.Jump(v.Context(), mainOffset) + v.Context().Jump(mainOffset) if initOffset >= 0 { v.Call(v.Context(), initOffset) } diff --git a/pkg/core/blockchain.go b/pkg/core/blockchain.go index 1f92796d2..c32529dcd 100644 --- a/pkg/core/blockchain.go +++ b/pkg/core/blockchain.go @@ -2188,7 +2188,7 @@ func (bc *Blockchain) InitVerificationVM(v *vm.VM, getContract func(util.Uint160 initMD := cs.Manifest.ABI.GetMethod(manifest.MethodInit, 0) v.LoadScriptWithHash(cs.NEF.Script, hash, callflag.ReadOnly) v.Context().NEF = &cs.NEF - v.Jump(v.Context(), md.Offset) + v.Context().Jump(md.Offset) if initMD != nil { v.Call(v.Context(), initMD.Offset) diff --git a/pkg/core/interop/contract/call.go b/pkg/core/interop/contract/call.go index f6f2f13ed..f6933c1f9 100644 --- a/pkg/core/interop/contract/call.go +++ b/pkg/core/interop/contract/call.go @@ -118,8 +118,8 @@ func callExFromNative(ic *interop.Context, caller util.Uint160, cs *state.Contra for e, i := ic.VM.Estack(), len(args)-1; i >= 0; i-- { e.PushItem(args[i]) } - // use Jump not Call here because context was loaded in LoadScript above. - ic.VM.Jump(ic.VM.Context(), md.Offset) + // Move IP to the target method. + ic.VM.Context().Jump(md.Offset) md = cs.Manifest.ABI.GetMethod(manifest.MethodInit, 0) if md != nil { diff --git a/pkg/core/native_contract_test.go b/pkg/core/native_contract_test.go index aea370ef4..27b6e69d2 100644 --- a/pkg/core/native_contract_test.go +++ b/pkg/core/native_contract_test.go @@ -243,7 +243,7 @@ func TestNativeContract_InvokeInternal(t *testing.T) { v.LoadScriptWithHash(tn.Metadata().NEF.Script, util.Uint160{1, 2, 3}, callflag.All) v.Estack().PushVal(14) v.Estack().PushVal(28) - v.Jump(v.Context(), sumOffset) + v.Context().Jump(sumOffset) // it's prohibited to call natives directly require.Error(t, v.Run()) @@ -255,7 +255,7 @@ func TestNativeContract_InvokeInternal(t *testing.T) { v.LoadScriptWithHash(tn.Metadata().NEF.Script, tn.Metadata().Hash, callflag.All) v.Estack().PushVal(14) v.Estack().PushVal(28) - v.Jump(v.Context(), sumOffset) + v.Context().Jump(sumOffset) // it's prohibited to call natives before NativeUpdateHistory[0] height require.Error(t, v.Run()) @@ -269,7 +269,7 @@ func TestNativeContract_InvokeInternal(t *testing.T) { v.LoadScriptWithHash(tn.Metadata().NEF.Script, tn.Metadata().Hash, callflag.All) v.Estack().PushVal(14) v.Estack().PushVal(28) - v.Jump(v.Context(), sumOffset) + v.Context().Jump(sumOffset) require.NoError(t, v.Run()) value := v.Estack().Pop().BigInt() diff --git a/pkg/services/oracle/response.go b/pkg/services/oracle/response.go index 38a69550e..586bd5884 100644 --- a/pkg/services/oracle/response.go +++ b/pkg/services/oracle/response.go @@ -137,7 +137,7 @@ func (o *Oracle) testVerify(tx *transaction.Transaction) (int64, bool) { v, finalize := o.Chain.GetTestVM(trigger.Verification, tx, nil) v.GasLimit = o.Chain.GetPolicer().GetMaxVerificationGAS() v.LoadScriptWithHash(o.oracleScript, o.oracleHash, callflag.ReadOnly) - v.Jump(v.Context(), o.verifyOffset) + v.Context().Jump(o.verifyOffset) ok := isVerifyOk(v, finalize) return v.GasConsumed(), ok diff --git a/pkg/vm/cli/cli.go b/pkg/vm/cli/cli.go index 6069bba92..05db4d4ef 100644 --- a/pkg/vm/cli/cli.go +++ b/pkg/vm/cli/cli.go @@ -458,7 +458,7 @@ func handleRun(c *ishell.Context) { c.Err(fmt.Errorf("no program loaded")) return } - v.Jump(v.Context(), offset) + v.Context().Jump(offset) if initMD := m.ABI.GetMethod(manifest.MethodInit, 0); initMD != nil { v.Call(v.Context(), initMD.Offset) } diff --git a/pkg/vm/context.go b/pkg/vm/context.go index fc5388e02..40a23a592 100644 --- a/pkg/vm/context.go +++ b/pkg/vm/context.go @@ -97,6 +97,11 @@ func (c *Context) NextIP() int { return c.nextip } +// Jump unconditionally moves the next instruction pointer to specified location. +func (c *Context) Jump(pos int) { + c.nextip = pos +} + // Next returns the next instruction to execute with its parameter if any. // The parameter is not copied and shouldn't be written to. After its invocation // the instruction pointer points to the instruction being returned. diff --git a/pkg/vm/vm.go b/pkg/vm/vm.go index 63a06981b..4732f02b7 100644 --- a/pkg/vm/vm.go +++ b/pkg/vm/vm.go @@ -1321,7 +1321,7 @@ func (v *VM) execute(ctx *Context, op opcode.Opcode, parameter []byte) (err erro } if cond { - v.Jump(ctx, offset) + ctx.Jump(offset) } case opcode.CALL, opcode.CALLL: @@ -1492,7 +1492,7 @@ func (v *VM) execute(ctx *Context, op opcode.Opcode, parameter []byte) (err erro } else { ctx.tryStack.Pop() } - v.Jump(ctx, eOffset) + ctx.Jump(eOffset) case opcode.ENDFINALLY: if v.uncaughtException != nil { @@ -1500,7 +1500,7 @@ func (v *VM) execute(ctx *Context, op opcode.Opcode, parameter []byte) (err erro return } eCtx := ctx.tryStack.Pop().Value().(*exceptionHandlingContext) - v.Jump(ctx, eCtx.EndOffset) + ctx.Jump(eCtx.EndOffset) default: panic(fmt.Sprintf("unknown opcode %s", op.String())) @@ -1556,14 +1556,8 @@ func (v *VM) throw(item stackitem.Item) { v.handleException() } -// Jump performs jump to the offset. -func (v *VM) Jump(ctx *Context, offset int) { - ctx.nextip = offset -} - -// Call calls method by offset. It is similar to Jump but also -// pushes new context to the invocation stack and increments -// invocation counter for the corresponding context script hash. +// Call calls method by offset. It pushes new context to the invocation stack +// and increments invocation counter for the corresponding context script hash. func (v *VM) Call(ctx *Context, offset int) { v.call(ctx, offset) v.Invocations[ctx.ScriptHash()]++ @@ -1581,7 +1575,7 @@ func (v *VM) call(ctx *Context, offset int) { initStack(&newCtx.tryStack, "exception", nil) newCtx.NEF = ctx.NEF v.istack.PushItem(newCtx) - v.Jump(newCtx, offset) + newCtx.Jump(offset) } // getJumpOffset returns instruction number in a current context @@ -1637,10 +1631,10 @@ func (v *VM) handleException() { ectx.State = eCatch v.estack.PushItem(v.uncaughtException) v.uncaughtException = nil - v.Jump(ictx, ectx.CatchOffset) + ictx.Jump(ectx.CatchOffset) } else { ectx.State = eFinally - v.Jump(ictx, ectx.FinallyOffset) + ictx.Jump(ectx.FinallyOffset) } return }