interop: add Abort() function to ABORT things

Related to #2227.
This commit is contained in:
Roman Khimov 2021-10-22 14:50:51 +03:00
parent e230040c2e
commit 36295357d8
5 changed files with 30 additions and 2 deletions

View file

@ -17,7 +17,7 @@ var (
goBuiltins = []string{"len", "append", "panic", "make", "copy", "recover", "delete"} goBuiltins = []string{"len", "append", "panic", "make", "copy", "recover", "delete"}
// Custom builtin utility functions. // Custom builtin utility functions.
customBuiltins = []string{ customBuiltins = []string{
"FromAddress", "Equals", "Remove", "Abort", "FromAddress", "Equals", "Remove",
"ToBool", "ToBytes", "ToString", "ToInteger", "ToBool", "ToBytes", "ToString", "ToInteger",
} }
) )

View file

@ -1724,6 +1724,8 @@ func (c *codegen) convertBuiltin(expr *ast.CallExpr) {
c.emitStoreByIndex(varGlobal, c.exceptionIndex) c.emitStoreByIndex(varGlobal, c.exceptionIndex)
case "delete": case "delete":
emit.Opcodes(c.prog.BinWriter, opcode.REMOVE) emit.Opcodes(c.prog.BinWriter, opcode.REMOVE)
case "Abort":
emit.Opcodes(c.prog.BinWriter, opcode.ABORT)
case "Remove": case "Remove":
if !isCompoundSlice(c.typeOf(expr.Args[0])) { if !isCompoundSlice(c.typeOf(expr.Args[0])) {
c.prog.Err = errors.New("`Remove` supports only non-byte slices") c.prog.Err = errors.New("`Remove` supports only non-byte slices")

View file

@ -116,6 +116,18 @@ func TestFromAddress(t *testing.T) {
}) })
} }
func TestAbort(t *testing.T) {
src := `package foo
import "github.com/nspcc-dev/neo-go/pkg/interop/util"
func Main() int {
util.Abort()
return 1
}`
v := vmAndCompile(t, src)
require.Error(t, v.Run())
require.True(t, v.HasFailed())
}
func spawnVM(t *testing.T, ic *interop.Context, src string) *vm.VM { func spawnVM(t *testing.T, ic *interop.Context, src string) *vm.VM {
b, di, err := compiler.CompileWithDebugInfo("foo.go", strings.NewReader(src)) b, di, err := compiler.CompileWithDebugInfo("foo.go", strings.NewReader(src))
require.NoError(t, err) require.NoError(t, err)

View file

@ -1,5 +1,10 @@
package neogointernal package neogointernal
// Opcode0 emits opcode without arguments.
func Opcode0(op string) interface{} {
return nil
}
// Opcode1 emits opcode with 1 argument. // Opcode1 emits opcode with 1 argument.
func Opcode1(op string, arg interface{}) interface{} { func Opcode1(op string, arg interface{}) interface{} {
return nil return nil

View file

@ -3,7 +3,16 @@ Package util contains some special useful functions that are provided by compile
*/ */
package util package util
import "github.com/nspcc-dev/neo-go/pkg/interop" import (
"github.com/nspcc-dev/neo-go/pkg/interop"
"github.com/nspcc-dev/neo-go/pkg/interop/neogointernal"
)
// Abort terminates current execution, unlike exception throwing with panic() it
// can't be recovered from.
func Abort() {
_ = neogointernal.Opcode0("ABORT")
}
// FromAddress is an utility function that converts a Neo address to its hash // FromAddress is an utility function that converts a Neo address to its hash
// (160 bit BE value in a 20 byte slice). It can only be used for strings known // (160 bit BE value in a 20 byte slice). It can only be used for strings known