2020-07-28 10:17:38 +00:00
|
|
|
package callback
|
|
|
|
|
|
|
|
import (
|
|
|
|
"errors"
|
|
|
|
|
|
|
|
"github.com/nspcc-dev/neo-go/pkg/core/interop"
|
|
|
|
"github.com/nspcc-dev/neo-go/pkg/vm"
|
|
|
|
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
|
|
|
)
|
|
|
|
|
|
|
|
// SyscallCallback represents callback for a syscall.
|
|
|
|
type SyscallCallback struct {
|
|
|
|
desc *interop.Function
|
|
|
|
}
|
|
|
|
|
|
|
|
var _ Callback = (*SyscallCallback)(nil)
|
|
|
|
|
|
|
|
// ArgCount implements Callback interface.
|
|
|
|
func (p *SyscallCallback) ArgCount() int {
|
|
|
|
return p.desc.ParamCount
|
|
|
|
}
|
|
|
|
|
|
|
|
// LoadContext implements Callback interface.
|
|
|
|
func (p *SyscallCallback) LoadContext(v *vm.VM, args []stackitem.Item) {
|
|
|
|
for i := len(args) - 1; i >= 0; i-- {
|
|
|
|
v.Estack().PushVal(args[i])
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// CreateFromSyscall creates callback from syscall.
|
2020-08-07 11:37:49 +00:00
|
|
|
func CreateFromSyscall(ic *interop.Context) error {
|
|
|
|
id := uint32(ic.VM.Estack().Pop().BigInt().Int64())
|
2020-07-28 10:17:38 +00:00
|
|
|
f := ic.GetFunction(id)
|
|
|
|
if f == nil {
|
|
|
|
return errors.New("syscall not found")
|
|
|
|
}
|
2020-07-28 14:15:23 +00:00
|
|
|
if f.DisallowCallback {
|
|
|
|
return errors.New("syscall is not allowed to be used in a callback")
|
|
|
|
}
|
2020-08-07 11:37:49 +00:00
|
|
|
ic.VM.Estack().PushVal(stackitem.NewInterop(&SyscallCallback{f}))
|
2020-07-28 10:17:38 +00:00
|
|
|
return nil
|
|
|
|
}
|