vm: move Jump method to the Context
Because it's only relevant for execution context itself.
This commit is contained in:
parent
8c704a49b5
commit
a577d40de9
8 changed files with 22 additions and 23 deletions
|
@ -87,7 +87,7 @@ func invokeMethod(t *testing.T, method string, script []byte, v *vm.VM, di *comp
|
||||||
}
|
}
|
||||||
require.True(t, mainOffset >= 0)
|
require.True(t, mainOffset >= 0)
|
||||||
v.LoadScriptWithFlags(script, callflag.All)
|
v.LoadScriptWithFlags(script, callflag.All)
|
||||||
v.Jump(v.Context(), mainOffset)
|
v.Context().Jump(mainOffset)
|
||||||
if initOffset >= 0 {
|
if initOffset >= 0 {
|
||||||
v.Call(v.Context(), initOffset)
|
v.Call(v.Context(), initOffset)
|
||||||
}
|
}
|
||||||
|
|
|
@ -2188,7 +2188,7 @@ func (bc *Blockchain) InitVerificationVM(v *vm.VM, getContract func(util.Uint160
|
||||||
initMD := cs.Manifest.ABI.GetMethod(manifest.MethodInit, 0)
|
initMD := cs.Manifest.ABI.GetMethod(manifest.MethodInit, 0)
|
||||||
v.LoadScriptWithHash(cs.NEF.Script, hash, callflag.ReadOnly)
|
v.LoadScriptWithHash(cs.NEF.Script, hash, callflag.ReadOnly)
|
||||||
v.Context().NEF = &cs.NEF
|
v.Context().NEF = &cs.NEF
|
||||||
v.Jump(v.Context(), md.Offset)
|
v.Context().Jump(md.Offset)
|
||||||
|
|
||||||
if initMD != nil {
|
if initMD != nil {
|
||||||
v.Call(v.Context(), initMD.Offset)
|
v.Call(v.Context(), initMD.Offset)
|
||||||
|
|
|
@ -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-- {
|
for e, i := ic.VM.Estack(), len(args)-1; i >= 0; i-- {
|
||||||
e.PushItem(args[i])
|
e.PushItem(args[i])
|
||||||
}
|
}
|
||||||
// use Jump not Call here because context was loaded in LoadScript above.
|
// Move IP to the target method.
|
||||||
ic.VM.Jump(ic.VM.Context(), md.Offset)
|
ic.VM.Context().Jump(md.Offset)
|
||||||
|
|
||||||
md = cs.Manifest.ABI.GetMethod(manifest.MethodInit, 0)
|
md = cs.Manifest.ABI.GetMethod(manifest.MethodInit, 0)
|
||||||
if md != nil {
|
if md != nil {
|
||||||
|
|
|
@ -243,7 +243,7 @@ func TestNativeContract_InvokeInternal(t *testing.T) {
|
||||||
v.LoadScriptWithHash(tn.Metadata().NEF.Script, util.Uint160{1, 2, 3}, callflag.All)
|
v.LoadScriptWithHash(tn.Metadata().NEF.Script, util.Uint160{1, 2, 3}, callflag.All)
|
||||||
v.Estack().PushVal(14)
|
v.Estack().PushVal(14)
|
||||||
v.Estack().PushVal(28)
|
v.Estack().PushVal(28)
|
||||||
v.Jump(v.Context(), sumOffset)
|
v.Context().Jump(sumOffset)
|
||||||
|
|
||||||
// it's prohibited to call natives directly
|
// it's prohibited to call natives directly
|
||||||
require.Error(t, v.Run())
|
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.LoadScriptWithHash(tn.Metadata().NEF.Script, tn.Metadata().Hash, callflag.All)
|
||||||
v.Estack().PushVal(14)
|
v.Estack().PushVal(14)
|
||||||
v.Estack().PushVal(28)
|
v.Estack().PushVal(28)
|
||||||
v.Jump(v.Context(), sumOffset)
|
v.Context().Jump(sumOffset)
|
||||||
|
|
||||||
// it's prohibited to call natives before NativeUpdateHistory[0] height
|
// it's prohibited to call natives before NativeUpdateHistory[0] height
|
||||||
require.Error(t, v.Run())
|
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.LoadScriptWithHash(tn.Metadata().NEF.Script, tn.Metadata().Hash, callflag.All)
|
||||||
v.Estack().PushVal(14)
|
v.Estack().PushVal(14)
|
||||||
v.Estack().PushVal(28)
|
v.Estack().PushVal(28)
|
||||||
v.Jump(v.Context(), sumOffset)
|
v.Context().Jump(sumOffset)
|
||||||
require.NoError(t, v.Run())
|
require.NoError(t, v.Run())
|
||||||
|
|
||||||
value := v.Estack().Pop().BigInt()
|
value := v.Estack().Pop().BigInt()
|
||||||
|
|
|
@ -137,7 +137,7 @@ func (o *Oracle) testVerify(tx *transaction.Transaction) (int64, bool) {
|
||||||
v, finalize := o.Chain.GetTestVM(trigger.Verification, tx, nil)
|
v, finalize := o.Chain.GetTestVM(trigger.Verification, tx, nil)
|
||||||
v.GasLimit = o.Chain.GetPolicer().GetMaxVerificationGAS()
|
v.GasLimit = o.Chain.GetPolicer().GetMaxVerificationGAS()
|
||||||
v.LoadScriptWithHash(o.oracleScript, o.oracleHash, callflag.ReadOnly)
|
v.LoadScriptWithHash(o.oracleScript, o.oracleHash, callflag.ReadOnly)
|
||||||
v.Jump(v.Context(), o.verifyOffset)
|
v.Context().Jump(o.verifyOffset)
|
||||||
|
|
||||||
ok := isVerifyOk(v, finalize)
|
ok := isVerifyOk(v, finalize)
|
||||||
return v.GasConsumed(), ok
|
return v.GasConsumed(), ok
|
||||||
|
|
|
@ -458,7 +458,7 @@ func handleRun(c *ishell.Context) {
|
||||||
c.Err(fmt.Errorf("no program loaded"))
|
c.Err(fmt.Errorf("no program loaded"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
v.Jump(v.Context(), offset)
|
v.Context().Jump(offset)
|
||||||
if initMD := m.ABI.GetMethod(manifest.MethodInit, 0); initMD != nil {
|
if initMD := m.ABI.GetMethod(manifest.MethodInit, 0); initMD != nil {
|
||||||
v.Call(v.Context(), initMD.Offset)
|
v.Call(v.Context(), initMD.Offset)
|
||||||
}
|
}
|
||||||
|
|
|
@ -97,6 +97,11 @@ func (c *Context) NextIP() int {
|
||||||
return c.nextip
|
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.
|
// 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 parameter is not copied and shouldn't be written to. After its invocation
|
||||||
// the instruction pointer points to the instruction being returned.
|
// the instruction pointer points to the instruction being returned.
|
||||||
|
|
22
pkg/vm/vm.go
22
pkg/vm/vm.go
|
@ -1321,7 +1321,7 @@ func (v *VM) execute(ctx *Context, op opcode.Opcode, parameter []byte) (err erro
|
||||||
}
|
}
|
||||||
|
|
||||||
if cond {
|
if cond {
|
||||||
v.Jump(ctx, offset)
|
ctx.Jump(offset)
|
||||||
}
|
}
|
||||||
|
|
||||||
case opcode.CALL, opcode.CALLL:
|
case opcode.CALL, opcode.CALLL:
|
||||||
|
@ -1492,7 +1492,7 @@ func (v *VM) execute(ctx *Context, op opcode.Opcode, parameter []byte) (err erro
|
||||||
} else {
|
} else {
|
||||||
ctx.tryStack.Pop()
|
ctx.tryStack.Pop()
|
||||||
}
|
}
|
||||||
v.Jump(ctx, eOffset)
|
ctx.Jump(eOffset)
|
||||||
|
|
||||||
case opcode.ENDFINALLY:
|
case opcode.ENDFINALLY:
|
||||||
if v.uncaughtException != nil {
|
if v.uncaughtException != nil {
|
||||||
|
@ -1500,7 +1500,7 @@ func (v *VM) execute(ctx *Context, op opcode.Opcode, parameter []byte) (err erro
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
eCtx := ctx.tryStack.Pop().Value().(*exceptionHandlingContext)
|
eCtx := ctx.tryStack.Pop().Value().(*exceptionHandlingContext)
|
||||||
v.Jump(ctx, eCtx.EndOffset)
|
ctx.Jump(eCtx.EndOffset)
|
||||||
|
|
||||||
default:
|
default:
|
||||||
panic(fmt.Sprintf("unknown opcode %s", op.String()))
|
panic(fmt.Sprintf("unknown opcode %s", op.String()))
|
||||||
|
@ -1556,14 +1556,8 @@ func (v *VM) throw(item stackitem.Item) {
|
||||||
v.handleException()
|
v.handleException()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Jump performs jump to the offset.
|
// Call calls method by offset. It pushes new context to the invocation stack
|
||||||
func (v *VM) Jump(ctx *Context, offset int) {
|
// and increments invocation counter for the corresponding context script hash.
|
||||||
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.
|
|
||||||
func (v *VM) Call(ctx *Context, offset int) {
|
func (v *VM) Call(ctx *Context, offset int) {
|
||||||
v.call(ctx, offset)
|
v.call(ctx, offset)
|
||||||
v.Invocations[ctx.ScriptHash()]++
|
v.Invocations[ctx.ScriptHash()]++
|
||||||
|
@ -1581,7 +1575,7 @@ func (v *VM) call(ctx *Context, offset int) {
|
||||||
initStack(&newCtx.tryStack, "exception", nil)
|
initStack(&newCtx.tryStack, "exception", nil)
|
||||||
newCtx.NEF = ctx.NEF
|
newCtx.NEF = ctx.NEF
|
||||||
v.istack.PushItem(newCtx)
|
v.istack.PushItem(newCtx)
|
||||||
v.Jump(newCtx, offset)
|
newCtx.Jump(offset)
|
||||||
}
|
}
|
||||||
|
|
||||||
// getJumpOffset returns instruction number in a current context
|
// getJumpOffset returns instruction number in a current context
|
||||||
|
@ -1637,10 +1631,10 @@ func (v *VM) handleException() {
|
||||||
ectx.State = eCatch
|
ectx.State = eCatch
|
||||||
v.estack.PushItem(v.uncaughtException)
|
v.estack.PushItem(v.uncaughtException)
|
||||||
v.uncaughtException = nil
|
v.uncaughtException = nil
|
||||||
v.Jump(ictx, ectx.CatchOffset)
|
ictx.Jump(ectx.CatchOffset)
|
||||||
} else {
|
} else {
|
||||||
ectx.State = eFinally
|
ectx.State = eFinally
|
||||||
v.Jump(ictx, ectx.FinallyOffset)
|
ictx.Jump(ectx.FinallyOffset)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue