vm: refactor LoadScript* internals a bit

Reduce code duplication, provide a single point where scripts are being loaded
into the VM (and new contexts are created).
This commit is contained in:
Roman Khimov 2021-11-19 22:17:05 +03:00
parent 83d0b2f465
commit cd3670a199

View file

@ -274,15 +274,7 @@ func (v *VM) LoadScript(b []byte) {
// LoadScriptWithFlags loads script and sets call flag to f. // LoadScriptWithFlags loads script and sets call flag to f.
func (v *VM) LoadScriptWithFlags(b []byte, f callflag.CallFlag) { func (v *VM) LoadScriptWithFlags(b []byte, f callflag.CallFlag) {
v.checkInvocationStackSize() v.loadScriptWithCallingHash(b, nil, v.GetCurrentScriptHash(), util.Uint160{}, f, -1, 0)
ctx := NewContextWithParams(b, -1, 0)
v.estack = newStack("evaluation", &v.refs)
ctx.estack = v.estack
initStack(&ctx.tryStack, "exception", nil)
ctx.callFlag = f
ctx.static = newSlot(&v.refs)
ctx.callingScriptHash = v.GetCurrentScriptHash()
v.istack.PushItem(ctx)
} }
// LoadScriptWithHash if similar to the LoadScriptWithFlags method, but it also loads // LoadScriptWithHash if similar to the LoadScriptWithFlags method, but it also loads
@ -292,8 +284,7 @@ func (v *VM) LoadScriptWithFlags(b []byte, f callflag.CallFlag) {
// accordingly). It's up to user of this function to make sure the script and hash match // accordingly). It's up to user of this function to make sure the script and hash match
// each other. // each other.
func (v *VM) LoadScriptWithHash(b []byte, hash util.Uint160, f callflag.CallFlag) { func (v *VM) LoadScriptWithHash(b []byte, hash util.Uint160, f callflag.CallFlag) {
shash := v.GetCurrentScriptHash() v.loadScriptWithCallingHash(b, nil, v.GetCurrentScriptHash(), hash, f, 1, 0)
v.loadScriptWithCallingHash(shash, b, hash, f, true)
} }
// LoadNEFMethod allows to create a context to execute a method from the NEF // LoadNEFMethod allows to create a context to execute a method from the NEF
@ -301,11 +292,11 @@ func (v *VM) LoadScriptWithHash(b []byte, hash util.Uint160, f callflag.CallFlag
// method and _initialize offsets. // method and _initialize offsets.
func (v *VM) LoadNEFMethod(exe *nef.File, caller util.Uint160, hash util.Uint160, f callflag.CallFlag, func (v *VM) LoadNEFMethod(exe *nef.File, caller util.Uint160, hash util.Uint160, f callflag.CallFlag,
hasReturn bool, methodOff int, initOff int) { hasReturn bool, methodOff int, initOff int) {
v.loadScriptWithCallingHash(caller, exe.Script, hash, f, hasReturn) var rvcount int
ctx := v.Context() if hasReturn {
ctx.NEF = exe rvcount = 1
// Move IP to the target method. }
ctx.Jump(methodOff) v.loadScriptWithCallingHash(exe.Script, exe, caller, hash, f, rvcount, methodOff)
if initOff >= 0 { if initOff >= 0 {
v.Call(initOff) v.Call(initOff)
} }
@ -313,17 +304,19 @@ func (v *VM) LoadNEFMethod(exe *nef.File, caller util.Uint160, hash util.Uint160
// loadScriptWithCallingHash is similar to LoadScriptWithHash but sets calling hash explicitly. // loadScriptWithCallingHash is similar to LoadScriptWithHash but sets calling hash explicitly.
// It should be used for calling from native contracts. // It should be used for calling from native contracts.
func (v *VM) loadScriptWithCallingHash(caller util.Uint160, b []byte, hash util.Uint160, func (v *VM) loadScriptWithCallingHash(b []byte, exe *nef.File, caller util.Uint160,
f callflag.CallFlag, hasReturn bool) { hash util.Uint160, f callflag.CallFlag, rvcount int, offset int) {
v.LoadScriptWithFlags(b, f) v.checkInvocationStackSize()
ctx := v.Context() ctx := NewContextWithParams(b, rvcount, offset)
v.estack = newStack("evaluation", &v.refs)
ctx.estack = v.estack
initStack(&ctx.tryStack, "exception", nil)
ctx.callFlag = f
ctx.static = newSlot(&v.refs)
ctx.scriptHash = hash ctx.scriptHash = hash
ctx.callingScriptHash = caller ctx.callingScriptHash = caller
if hasReturn { ctx.NEF = exe
ctx.retCount = 1 v.istack.PushItem(ctx)
} else {
ctx.retCount = 0
}
} }
// Context returns the current executed context. Nil if there is no context, // Context returns the current executed context. Nil if there is no context,