diff --git a/pkg/vm/context.go b/pkg/vm/context.go index 6c086249f..cc16ac867 100644 --- a/pkg/vm/context.go +++ b/pkg/vm/context.go @@ -72,6 +72,13 @@ type Context struct { retCount int } +type contextAux struct { + Script string + IP int + NextIP int + Caller string +} + // ContextUnloadCallback is a callback method used on context unloading from istack. type ContextUnloadCallback func(ctx *Context, commit bool) error @@ -357,3 +364,14 @@ func (c *Context) HasTryBlock() bool { } return false } + +// MarshalJSON implements the JSON marshalling interface. +func (c *Context) MarshalJSON() ([]byte, error) { + var aux = contextAux{ + Script: c.ScriptHash().StringLE(), + IP: c.ip, + NextIP: c.nextip, + Caller: c.sc.callingScriptHash.StringLE(), + } + return json.Marshal(aux) +} diff --git a/pkg/vm/vm.go b/pkg/vm/vm.go index 3a348d530..7cc768d0f 100644 --- a/pkg/vm/vm.go +++ b/pkg/vm/vm.go @@ -335,18 +335,19 @@ func (v *VM) loadScriptWithCallingHash(b []byte, exe *nef.File, caller util.Uint hash util.Uint160, f callflag.CallFlag, rvcount int, offset int, onContextUnload ContextUnloadCallback) { v.checkInvocationStackSize() ctx := NewContextWithParams(b, rvcount, offset) + parent := v.Context() + if parent != nil { + ctx.sc.callingContext = parent.sc + parent.sc.estack = v.estack + } if rvcount != -1 || v.estack.Len() != 0 { v.estack = subStack(v.estack) } - parent := v.Context() ctx.sc.estack = v.estack initStack(&ctx.tryStack, "exception", nil) ctx.sc.callFlag = f ctx.sc.scriptHash = hash ctx.sc.callingScriptHash = caller - if parent != nil { - ctx.sc.callingContext = parent.sc - } ctx.sc.NEF = exe if v.invTree != nil { curTree := v.invTree @@ -381,7 +382,8 @@ func (v *VM) PopResult() interface{} { // DumpIStack returns json formatted representation of the invocation stack. func (v *VM) DumpIStack() string { - return dumpStack(&v.istack) + b, _ := json.MarshalIndent(v.istack.ToArray(), "", " ") + return string(b) } // DumpEStack returns json formatted representation of the execution stack.