Merge pull request #2800 from nspcc-dev/fix-vm-bugz

Fix VM bug and istack printing
This commit is contained in:
Roman Khimov 2022-11-16 13:24:07 +07:00 committed by GitHub
commit bd67fe5371
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 25 additions and 5 deletions

View file

@ -72,6 +72,13 @@ type Context struct {
retCount int retCount int
} }
type contextAux struct {
Script string
IP int
NextIP int
Caller string
}
// ContextUnloadCallback is a callback method used on context unloading from istack. // ContextUnloadCallback is a callback method used on context unloading from istack.
type ContextUnloadCallback func(ctx *Context, commit bool) error type ContextUnloadCallback func(ctx *Context, commit bool) error
@ -357,3 +364,14 @@ func (c *Context) HasTryBlock() bool {
} }
return false 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)
}

View file

@ -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) { hash util.Uint160, f callflag.CallFlag, rvcount int, offset int, onContextUnload ContextUnloadCallback) {
v.checkInvocationStackSize() v.checkInvocationStackSize()
ctx := NewContextWithParams(b, rvcount, offset) 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 { if rvcount != -1 || v.estack.Len() != 0 {
v.estack = subStack(v.estack) v.estack = subStack(v.estack)
} }
parent := v.Context()
ctx.sc.estack = v.estack ctx.sc.estack = v.estack
initStack(&ctx.tryStack, "exception", nil) initStack(&ctx.tryStack, "exception", nil)
ctx.sc.callFlag = f ctx.sc.callFlag = f
ctx.sc.scriptHash = hash ctx.sc.scriptHash = hash
ctx.sc.callingScriptHash = caller ctx.sc.callingScriptHash = caller
if parent != nil {
ctx.sc.callingContext = parent.sc
}
ctx.sc.NEF = exe ctx.sc.NEF = exe
if v.invTree != nil { if v.invTree != nil {
curTree := v.invTree curTree := v.invTree
@ -381,7 +382,8 @@ func (v *VM) PopResult() interface{} {
// DumpIStack returns json formatted representation of the invocation stack. // DumpIStack returns json formatted representation of the invocation stack.
func (v *VM) DumpIStack() string { 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. // DumpEStack returns json formatted representation of the execution stack.