vm: move Jump method to the Context

Because it's only relevant for execution context itself.
This commit is contained in:
Roman Khimov 2021-11-19 16:46:29 +03:00
parent 8c704a49b5
commit a577d40de9
8 changed files with 22 additions and 23 deletions

View file

@ -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)
}

View file

@ -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)

View file

@ -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 {

View file

@ -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()

View file

@ -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

View file

@ -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)
}

View file

@ -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.

View file

@ -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
}