2021-02-04 12:41:00 +00:00
|
|
|
package compiler_test
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"math/big"
|
|
|
|
"strings"
|
|
|
|
"testing"
|
|
|
|
|
|
|
|
"github.com/nspcc-dev/neo-go/pkg/compiler"
|
|
|
|
"github.com/nspcc-dev/neo-go/pkg/vm/opcode"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
)
|
|
|
|
|
2021-05-24 14:03:31 +00:00
|
|
|
func checkCallCount(t *testing.T, src string, expectedCall, expectedInitSlot, expectedLocalsMain int) {
|
2022-08-04 14:47:32 +00:00
|
|
|
checkInstrCount(t, src, -1, expectedCall, expectedInitSlot, expectedLocalsMain)
|
|
|
|
}
|
2021-05-24 14:03:31 +00:00
|
|
|
|
2022-08-04 14:47:32 +00:00
|
|
|
func checkInstrCount(t *testing.T, src string, expectedSSlotCount, expectedCall, expectedInitSlot, expectedLocalsMain int) {
|
|
|
|
v, sp, _ := vmAndCompileInterop(t, src)
|
2021-05-24 14:03:31 +00:00
|
|
|
mainStart := -1
|
|
|
|
for _, m := range sp.info.Methods {
|
|
|
|
if m.Name.Name == "main" {
|
|
|
|
mainStart = int(m.Range.Start)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
require.True(t, mainStart >= 0)
|
|
|
|
|
2021-02-04 12:41:00 +00:00
|
|
|
ctx := v.Context()
|
|
|
|
actualCall := 0
|
|
|
|
actualInitSlot := 0
|
|
|
|
|
2021-05-24 14:03:31 +00:00
|
|
|
for op, param, err := ctx.Next(); ; op, param, err = ctx.Next() {
|
2021-02-04 12:41:00 +00:00
|
|
|
require.NoError(t, err)
|
|
|
|
switch op {
|
2022-08-04 14:47:32 +00:00
|
|
|
case opcode.INITSSLOT:
|
|
|
|
if expectedSSlotCount == -1 {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
if expectedSSlotCount == 0 {
|
|
|
|
t.Fatalf("no INITSSLOT expected, found at %d with %d cells", ctx.IP(), param[0])
|
|
|
|
}
|
|
|
|
require.Equal(t, expectedSSlotCount, int(param[0]))
|
2021-02-04 12:41:00 +00:00
|
|
|
case opcode.CALL, opcode.CALLL:
|
|
|
|
actualCall++
|
|
|
|
case opcode.INITSLOT:
|
|
|
|
actualInitSlot++
|
2022-02-02 13:51:10 +00:00
|
|
|
if ctx.IP() == mainStart && expectedLocalsMain >= 0 {
|
2021-05-24 14:03:31 +00:00
|
|
|
require.Equal(t, expectedLocalsMain, int(param[0]))
|
|
|
|
}
|
*: fix linter exhaustive errors
```
pkg/smartcontract/rpcbinding/binding.go:523:2 exhaustive missing
cases in switch of type smartcontract.ParamType: smartcontract
.UnknownType
pkg/smartcontract/rpcbinding/binding.go:572:2 exhaustive missing
cases in switch of type smartcontract.ParamType: smartcontract
.UnknownType
pkg/smartcontract/rpcbinding/binding.go:862:2 exhaustive missing
cases in switch of type smartcontract.ParamType: smartcontract
.UnknownType, smartcontract.AnyType, smartcontract.BoolType,
smartcontract.IntegerType, smartcontract.ByteArrayType, smartcontract
.Hash160Type, smartcontract.Hash256Type, smartcontract.SignatureType,
smartcontract.InteropInterfaceType, smartcontract.VoidType
pkg/smartcontract/param_type.go:165:2 exhaustive missing
cases in switch of type smartcontract.ParamType: smartcontract
.UnknownType
pkg/smartcontract/manifest/permission.go:103:2 exhaustive missing
cases in switch of type manifest.PermissionType: manifest
.PermissionWildcard
pkg/services/notary/core_test.go:223:4 exhaustive missing
cases in switch of type notary.RequestType: notary.Contract
pkg/services/notary/core_test.go:292:4 exhaustive missing
cases in switch of type notary.RequestType: notary.Contract
pkg/services/oracle/jsonpath/jsonpath.go:62:3 exhaustive missing
cases in switch of type jsonpath.pathTokenType: jsonpath.pathInvalid,
jsonpath.pathRoot, jsonpath.pathRightBracket, jsonpath.pathAsterisk,
jsonpath.pathComma, jsonpath.pathColon, jsonpath.pathIdentifier,
jsonpath.pathString, jsonpath.pathNumber
pkg/services/rpcsrv/server.go:2740:3 exhaustive missing
cases in switch of type neorpc.EventID: neorpc.InvalidEventID, neorpc
.MissedEventID
pkg/services/rpcsrv/server.go:2804:2 exhaustive missing
cases in switch of type neorpc.EventID: neorpc.InvalidEventID, neorpc
.MissedEventID
pkg/services/rpcsrv/server.go:2864:2 exhaustive missing
cases in switch of type neorpc.EventID: neorpc.InvalidEventID, neorpc
.MissedEventID
pkg/vm/contract_checks.go:153:3 exhaustive missing
cases in switch of type opcode.Opcode: opcode.PUSHINT8, opcode
.PUSHINT16, opcode.PUSHINT32, opcode.PUSHINT64, opcode.PUSHINT128,
opcode.PUSHINT256, opcode.PUSHT, opcode.PUSHF, opcode.PUSHNULL, opcode
.PUSHDATA1, opcode.PUSHDATA2, opcode.PUSHDATA4, opcode.PUSHM1, opcode
.PUSH0, opcode.PUSH1, opcode.PUSH2, opcode.PUSH3, opcode.PUSH4, opcode
.PUSH5, opcode.PUSH6, opcode.PUSH7, opcode.PUSH8, opcode.PUSH9, opcode
.PUSH10, opcode.PUSH11, opcode.PUSH12, opcode.PUSH13, opcode.PUSH14,
opcode.PUSH15, opcode.PUSH16, opcode.NOP, opcode.CALLA, opcode.CALLT,
opcode.ABORT, opcode.ASSERT, opcode.THROW, opcode.ENDFINALLY, opcode
.RET, opcode.SYSCALL, opcode.DEPTH, opcode.DROP, opcode.NIP, opcode
.XDROP, opcode.CLEAR, opcode.DUP, opcode.OVER, opcode.PICK, opcode.TUCK,
opcode.SWAP, opcode.ROT, opcode.ROLL, opcode.REVERSE3, opcode.REVERSE4,
opcode.REVERSEN, opcode.INITSSLOT, opcode.INITSLOT, opcode.LDSFLD0,
opcode.LDSFLD1, opcode.LDSFLD2, opcode.LDSFLD3, opcode.LDSFLD4, opcode
.LDSFLD5, opcode.LDSFLD6, opcode.LDSFLD, opcode.STSFLD0, opcode
.STSFLD1, opcode.STSFLD2, opcode.STSFLD3, opcode.STSFLD4, opcode
.STSFLD5, opcode.STSFLD6, opcode.STSFLD, opcode.LDLOC0, opcode.LDLOC1,
opcode.LDLOC2, opcode.LDLOC3, opcode.LDLOC4, opcode.LDLOC5, opcode
.LDLOC6, opcode.LDLOC, opcode.STLOC0, opcode.STLOC1, opcode.STLOC2,
opcode.STLOC3, opcode.STLOC4, opcode.STLOC5, opcode.STLOC6, opcode
.STLOC, opcode.LDARG0, opcode.LDARG1, opcode.LDARG2, opcode.LDARG3,
opcode.LDARG4, opcode.LDARG5, opcode.LDARG6, opcode.LDARG, opcode
.STARG0, opcode.STARG1, opcode.STARG2, opcode.STARG3, opcode.STARG4,
opcode.STARG5, opcode.STARG6, opcode.STARG, opcode.NEWBUFFER, opcode
.MEMCPY, opcode.CAT, opcode.SUBSTR, opcode.LEFT, opcode.RIGHT, opcode
.INVERT, opcode.AND, opcode.OR, opcode.XOR, opcode.EQUAL, opcode
.NOTEQUAL, opcode.SIGN, opcode.ABS, opcode.NEGATE, opcode.INC, opcode
.DEC, opcode.ADD, opcode.SUB, opcode.MUL, opcode.DIV, opcode.MOD,
opcode.POW, opcode.SQRT, opcode.MODMUL, opcode.MODPOW, opcode.SHL,
opcode.SHR, opcode.NOT, opcode.BOOLAND, opcode.BOOLOR, opcode.NZ,
opcode.NUMEQUAL, opcode.NUMNOTEQUAL, opcode.LT, opcode.LE, opcode.GT,
opcode.GE, opcode.MIN, opcode.MAX, opcode.WITHIN, opcode.PACKMAP,
opcode.PACKSTRUCT, opcode.PACK, opcode.UNPACK, opcode.NEWARRAY0,
opcode.NEWARRAY, opcode.NEWSTRUCT0, opcode.NEWSTRUCT, opcode.NEWMAP,
opcode.SIZE, opcode.HASKEY, opcode.KEYS, opcode.VALUES, opcode
.PICKITEM, opcode.APPEND, opcode.SETITEM, opcode.REVERSEITEMS,
opcode.REMOVE, opcode.CLEARITEMS, opcode.POPITEM, opcode.ISNULL,
opcode.ABORTMSG, opcode.ASSERTMSG
pkg/vm/vm.go:912:3 exhaustive missing
cases in switch of type opcode.Opcode: opcode.PUSHINT8, opcode
.PUSHINT16, opcode.PUSHINT32, opcode.PUSHINT64, opcode.PUSHINT128,
opcode.PUSHINT256, opcode.PUSHT, opcode.PUSHF, opcode.PUSHA, opcode
.PUSHNULL, opcode.PUSHDATA1, opcode.PUSHDATA2, opcode.PUSHDATA4, opcode
.PUSHM1, opcode.PUSH0, opcode.PUSH1, opcode.PUSH2, opcode.PUSH3, opcode
.PUSH4, opcode.PUSH5, opcode.PUSH6, opcode.PUSH7, opcode.PUSH8, opcode
.PUSH9, opcode.PUSH10, opcode.PUSH11, opcode.PUSH12, opcode.PUSH13,
opcode.PUSH14, opcode.PUSH15, opcode.PUSH16, opcode.NOP, opcode.JMP,
opcode.JMPL, opcode.JMPIF, opcode.JMPIFL, opcode.JMPIFNOT, opcode
.JMPIFNOTL, opcode.JMPEQ, opcode.JMPEQL, opcode.JMPNE, opcode.JMPNEL,
opcode.JMPGT, opcode.JMPGTL, opcode.JMPGE, opcode.JMPGEL, opcode.JMPLT,
opcode.JMPLTL, opcode.JMPLE, opcode.JMPLEL, opcode.CALL, opcode.CALLL,
opcode.CALLA, opcode.CALLT, opcode.ABORT, opcode.ASSERT, opcode.THROW,
opcode.TRY, opcode.TRYL, opcode.ENDTRY, opcode.ENDTRYL, opcode
.ENDFINALLY, opcode.RET, opcode.SYSCALL, opcode.DEPTH, opcode.DROP,
opcode.NIP, opcode.XDROP, opcode.CLEAR, opcode.DUP, opcode.OVER, opcode
.PICK, opcode.TUCK, opcode.SWAP, opcode.ROT, opcode.ROLL, opcode
.REVERSE3, opcode.INITSSLOT, opcode.INITSLOT, opcode.LDSFLD0, opcode
.LDSFLD1, opcode.LDSFLD2, opcode.LDSFLD3, opcode.LDSFLD4, opcode
.LDSFLD5, opcode.LDSFLD6, opcode.LDSFLD, opcode.STSFLD0, opcode.STSFLD1,
opcode.STSFLD2, opcode.STSFLD3, opcode.STSFLD4, opcode.STSFLD5, opcode
.STSFLD6, opcode.STSFLD, opcode.LDLOC0, opcode.LDLOC1, opcode.LDLOC2,
opcode.LDLOC3, opcode.LDLOC4, opcode.LDLOC5, opcode.LDLOC6, opcode
.LDLOC, opcode.STLOC0, opcode.STLOC1, opcode.STLOC2, opcode.STLOC3,
opcode.STLOC4, opcode.STLOC5, opcode.STLOC6, opcode.STLOC, opcode
.LDARG0, opcode.LDARG1, opcode.LDARG2, opcode.LDARG3, opcode.LDARG4,
opcode.LDARG5, opcode.LDARG6, opcode.LDARG, opcode.STARG0, opcode
.STARG1, opcode.STARG2, opcode.STARG3, opcode.STARG4, opcode.STARG5,
opcode.STARG6, opcode.STARG, opcode.NEWBUFFER, opcode.MEMCPY, opcode
.CAT, opcode.SUBSTR, opcode.LEFT, opcode.RIGHT, opcode.INVERT, opcode
.AND, opcode.OR, opcode.XOR, opcode.EQUAL, opcode.NOTEQUAL, opcode
.SIGN, opcode.ABS, opcode.NEGATE, opcode.INC, opcode.DEC, opcode.ADD,
opcode.SUB, opcode.MUL, opcode.DIV, opcode.MOD, opcode.POW, opcode
.SQRT, opcode.MODMUL, opcode.MODPOW, opcode.SHL, opcode.SHR, opcode
.NOT, opcode.BOOLAND, opcode.BOOLOR, opcode.NZ, opcode.NUMEQUAL, opcode
.NUMNOTEQUAL, opcode.LT, opcode.LE, opcode.GT, opcode.GE, opcode.MIN,
opcode.MAX, opcode.WITHIN, opcode.PACKMAP, opcode.PACKSTRUCT, opcode
.PACK, opcode.UNPACK, opcode.NEWARRAY0, opcode.NEWARRAY, opcode
.NEWARRAYT, opcode.NEWSTRUCT0, opcode.NEWSTRUCT, opcode.NEWMAP, opcode
.SIZE, opcode.HASKEY, opcode.KEYS, opcode.VALUES, opcode.PICKITEM,
opcode.APPEND, opcode.SETITEM, opcode.REVERSEITEMS, opcode.REMOVE,
opcode.CLEARITEMS, opcode.POPITEM, opcode.ISNULL, opcode.ISTYPE, opcode
.CONVERT, opcode.ABORTMSG, opcode.ASSERTMSG
pkg/vm/vm.go:1116:4 exhaustive missing
cases in switch of type opcode.Opcode: opcode.PUSHINT8, opcode
.PUSHINT16, opcode.PUSHINT32, opcode.PUSHINT64, opcode.PUSHINT128,
opcode.PUSHINT256, opcode.PUSHT, opcode.PUSHF, opcode.PUSHA, opcode
.PUSHNULL, opcode.PUSHDATA1, opcode.PUSHDATA2, opcode.PUSHDATA4, opcode
.PUSHM1, opcode.PUSH0, opcode.PUSH1, opcode.PUSH2, opcode.PUSH3, opcode
.PUSH4, opcode.PUSH5, opcode.PUSH6, opcode.PUSH7, opcode.PUSH8, opcode
.PUSH9, opcode.PUSH10, opcode.PUSH11, opcode.PUSH12, opcode.PUSH13,
opcode.PUSH14, opcode.PUSH15, opcode.PUSH16, opcode.NOP, opcode.JMP,
opcode.JMPL, opcode.JMPIF, opcode.JMPIFL, opcode.JMPIFNOT, opcode
.JMPIFNOTL, opcode.JMPEQ, opcode.JMPEQL, opcode.JMPNE, opcode.JMPNEL,
opcode.JMPGT, opcode.JMPGTL, opcode.JMPGE, opcode.JMPGEL, opcode.JMPLT,
opcode.JMPLTL, opcode.JMPLE, opcode.JMPLEL, opcode.CALL, opcode.CALLL,
opcode.CALLA, opcode.CALLT, opcode.ABORT, opcode.ASSERT, opcode.THROW,
opcode.TRY, opcode.TRYL, opcode.ENDTRY, opcode.ENDTRYL, opcode
.ENDFINALLY, opcode.RET, opcode.SYSCALL, opcode.DEPTH, opcode.DROP,
opcode.NIP, opcode.XDROP, opcode.CLEAR, opcode.DUP, opcode.OVER, opcode
.PICK, opcode.TUCK, opcode.SWAP, opcode.ROT, opcode.ROLL, opcode
.REVERSE3, opcode.REVERSE4, opcode.REVERSEN, opcode.INITSSLOT, opcode
.INITSLOT, opcode.LDSFLD0, opcode.LDSFLD1, opcode.LDSFLD2, opcode
.LDSFLD3, opcode.LDSFLD4, opcode.LDSFLD5, opcode.LDSFLD6, opcode.LDSFLD,
opcode.STSFLD0, opcode.STSFLD1, opcode.STSFLD2, opcode.STSFLD3, opcode
.STSFLD4, opcode.STSFLD5, opcode.STSFLD6, opcode.STSFLD, opcode.LDLOC0,
opcode.LDLOC1, opcode.LDLOC2, opcode.LDLOC3, opcode.LDLOC4, opcode
.LDLOC5, opcode.LDLOC6, opcode.LDLOC, opcode.STLOC0, opcode.STLOC1,
opcode.STLOC2, opcode.STLOC3, opcode.STLOC4, opcode.STLOC5, opcode
.STLOC6, opcode.STLOC, opcode.LDARG0, opcode.LDARG1, opcode.LDARG2,
opcode.LDARG3, opcode.LDARG4, opcode.LDARG5, opcode.LDARG6, opcode
.LDARG, opcode.STARG0, opcode.STARG1, opcode.STARG2, opcode.STARG3,
opcode.STARG4, opcode.STARG5, opcode.STARG6, opcode.STARG, opcode
.NEWBUFFER, opcode.MEMCPY, opcode.CAT, opcode.SUBSTR, opcode.LEFT,
opcode.RIGHT, opcode.INVERT, opcode.AND, opcode.OR, opcode.XOR, opcode
.EQUAL, opcode.NOTEQUAL, opcode.SIGN, opcode.ABS, opcode.NEGATE,
opcode.INC, opcode.DEC, opcode.ADD, opcode.SUB, opcode.MUL, opcode
.DIV, opcode.MOD, opcode.POW, opcode.SQRT, opcode.MODMUL, opcode
.MODPOW, opcode.SHL, opcode.SHR, opcode.NOT, opcode.BOOLAND, opcode
.BOOLOR, opcode.NZ, opcode.NUMEQUAL, opcode.NUMNOTEQUAL, opcode.MIN,
opcode.MAX, opcode.WITHIN, opcode.PACKMAP, opcode.PACKSTRUCT, opcode
.PACK, opcode.UNPACK, opcode.NEWARRAY0, opcode.NEWARRAY, opcode
.NEWARRAYT, opcode.NEWSTRUCT0, opcode.NEWSTRUCT, opcode.NEWMAP, opcode
.SIZE, opcode.HASKEY, opcode.KEYS, opcode.VALUES, opcode.PICKITEM,
opcode.APPEND, opcode.SETITEM, opcode.REVERSEITEMS, opcode.REMOVE,
opcode.CLEARITEMS, opcode.POPITEM, opcode.ISNULL, opcode.ISTYPE,
opcode.CONVERT, opcode.ABORTMSG, opcode.ASSERTMSG
pkg/compiler/codegen.go:944:5 exhaustive missing
cases in switch of type smartcontract.ParamType: smartcontract
.UnknownType, smartcontract.AnyType, smartcontract.BoolType,
smartcontract.IntegerType, smartcontract.ByteArrayType, smartcontract
.StringType, smartcontract.PublicKeyType, smartcontract.SignatureType,
smartcontract.ArrayType, smartcontract.MapType, smartcontract
.InteropInterfaceType, smartcontract.VoidType
pkg/compiler/codegen.go:1221:3 exhaustive missing
cases in switch of type token.Token: token.ILLEGAL, token.EOF, token
.COMMENT, token.IDENT, token.INT, token.FLOAT, token.IMAG, token.CHAR,
token.STRING, token.ADD, token.SUB, token.MUL, token.QUO, token.REM,
token.AND, token.OR, token.XOR, token.SHL, token.SHR, token.AND_NOT,
token.ADD_ASSIGN, token.SUB_ASSIGN, token.MUL_ASSIGN, token.QUO_ASSIGN,
token.REM_ASSIGN, token.AND_ASSIGN, token.OR_ASSIGN, token.XOR_ASSIGN,
token.SHL_ASSIGN, token.SHR_ASSIGN, token.AND_NOT_ASSIGN, token.LAND,
token.LOR, token.ARROW, token.INC, token.DEC, token.EQL, token.LSS,
token.GTR, token.ASSIGN, token.NOT, token.NEQ, token.LEQ, token.GEQ,
token.DEFINE, token.ELLIPSIS, token.LPAREN, token.LBRACK, token.LBRACE,
token.COMMA, token.PERIOD, token.RPAREN, token.RBRACK, token.RBRACE,
token.SEMICOLON, token.COLON, token.CASE, token.CHAN, token.CONST, token
.DEFAULT, token.DEFER, token.ELSE, token.FALLTHROUGH, token.FOR, token
.FUNC, token.GO, token.GOTO, token.IF, token.IMPORT, token.INTERFACE,
token.MAP, token.PACKAGE, token.RANGE, token.RETURN, token.SELECT, token
.STRUCT, token.SWITCH, token.TYPE, token.VAR, token.TILDE
pkg/compiler/codegen.go:1709:2 exhaustive missing
cases in switch of type token.Token: token.ILLEGAL, token.EOF, token
.COMMENT, token.IDENT, token.INT, token.FLOAT, token.IMAG, token.CHAR,
token.STRING, token.ADD, token.SUB, token.MUL, token.QUO, token.REM,
token.AND, token.OR, token.XOR, token.SHL, token.SHR, token.AND_NOT,
token.ADD_ASSIGN, token.SUB_ASSIGN, token.MUL_ASSIGN, token.QUO_ASSIGN,
token.REM_ASSIGN, token.AND_ASSIGN, token.OR_ASSIGN, token.XOR_ASSIGN,
token.SHL_ASSIGN, token.SHR_ASSIGN, token.AND_NOT_ASSIGN, token.LAND,
token.LOR, token.ARROW, token.INC, token.DEC, token.ASSIGN, token.NOT,
token.DEFINE, token.ELLIPSIS, token.LPAREN, token.LBRACK, token.LBRACE,
token.COMMA, token.PERIOD, token.RPAREN, token.RBRACK, token.RBRACE,
token.SEMICOLON, token.COLON, token.BREAK, token.CASE, token.CHAN, token
.CONST, token.CONTINUE, token.DEFAULT, token.DEFER, token.ELSE, token
.FALLTHROUGH, token.FOR, token.FUNC, token.GO, token.GOTO, token.IF,
token.IMPORT, token.INTERFACE, token.MAP, token.PACKAGE, token.RANGE,
token.RETURN, token.SELECT, token.STRUCT, token.SWITCH, token.TYPE,
token.VAR, token.TILDE
pkg/compiler/codegen.go:2353:3 exhaustive missing
cases in switch of type opcode.Opcode: opcode.PUSHINT8, opcode
.PUSHINT16, opcode.PUSHINT32, opcode.PUSHINT64, opcode.PUSHINT128,
opcode.PUSHINT256, opcode.PUSHT, opcode.PUSHF, opcode.PUSHNULL, opcode
.PUSHDATA1, opcode.PUSHDATA2, opcode.PUSHDATA4, opcode.PUSHM1, opcode
.PUSH0, opcode.PUSH1, opcode.PUSH2, opcode.PUSH3, opcode.PUSH4, opcode
.PUSH5, opcode.PUSH6, opcode.PUSH7, opcode.PUSH8, opcode.PUSH9, opcode
.PUSH10, opcode.PUSH11, opcode.PUSH12, opcode.PUSH13, opcode.PUSH14,
opcode.PUSH15, opcode.PUSH16, opcode.NOP, opcode.CALLA, opcode.CALLT,
opcode.ABORT, opcode.ASSERT, opcode.THROW, opcode.TRY, opcode.ENDTRY,
opcode.ENDFINALLY, opcode.RET, opcode.SYSCALL, opcode.DEPTH, opcode
.DROP, opcode.NIP, opcode.XDROP, opcode.CLEAR, opcode.DUP, opcode.OVER,
opcode.PICK, opcode.TUCK, opcode.SWAP, opcode.ROT, opcode.ROLL, opcode
.REVERSE3, opcode.REVERSE4, opcode.REVERSEN, opcode.INITSSLOT, opcode
.LDSFLD0, opcode.LDSFLD1, opcode.LDSFLD2, opcode.LDSFLD3, opcode
.LDSFLD4, opcode.LDSFLD5, opcode.LDSFLD6, opcode.LDSFLD, opcode.STSFLD0,
opcode.STSFLD1, opcode.STSFLD2, opcode.STSFLD3, opcode.STSFLD4, opcode
.STSFLD5, opcode.STSFLD6, opcode.STSFLD, opcode.LDLOC0, opcode.LDLOC1,
opcode.LDLOC2, opcode.LDLOC3, opcode.LDLOC4, opcode.LDLOC5, opcode
.LDLOC6, opcode.LDLOC, opcode.STLOC0, opcode.STLOC1, opcode.STLOC2,
opcode.STLOC3, opcode.STLOC4, opcode.STLOC5, opcode.STLOC6, opcode
.STLOC, opcode.LDARG0, opcode.LDARG1, opcode.LDARG2, opcode.LDARG3,
opcode.LDARG4, opcode.LDARG5, opcode.LDARG6, opcode.LDARG, opcode
.STARG0, opcode.STARG1, opcode.STARG2, opcode.STARG3, opcode.STARG4,
opcode.STARG5, opcode.STARG6, opcode.STARG, opcode.NEWBUFFER, opcode
.MEMCPY, opcode.CAT, opcode.SUBSTR, opcode.LEFT, opcode.RIGHT, opcode
.INVERT, opcode.AND, opcode.OR, opcode.XOR, opcode.EQUAL, opcode
.NOTEQUAL, opcode.SIGN, opcode.ABS, opcode.NEGATE, opcode.INC, opcode
.DEC, opcode.ADD, opcode.SUB, opcode.MUL, opcode.DIV, opcode.MOD,
opcode.POW, opcode.SQRT, opcode.MODMUL, opcode.MODPOW, opcode.SHL,
opcode.SHR, opcode.NOT, opcode.BOOLAND, opcode.BOOLOR, opcode.NZ,
opcode.NUMEQUAL, opcode.NUMNOTEQUAL, opcode.LT, opcode.LE, opcode.GT,
opcode.GE, opcode.MIN, opcode.MAX, opcode.WITHIN, opcode.PACKMAP,
opcode.PACKSTRUCT, opcode.PACK, opcode.UNPACK, opcode.NEWARRAY0, opcode
.NEWARRAY, opcode.NEWARRAYT, opcode.NEWSTRUCT0, opcode.NEWSTRUCT,
opcode.NEWMAP, opcode.SIZE, opcode.HASKEY, opcode.KEYS, opcode.VALUES,
opcode.PICKITEM, opcode.APPEND, opcode.SETITEM, opcode.REVERSEITEMS,
opcode.REMOVE, opcode.CLEARITEMS, opcode.POPITEM, opcode.ISNULL, opcode
.ISTYPE, opcode.CONVERT, opcode.ABORTMSG, opcode.ASSERTMSG
pkg/compiler/codegen.go:2474:3 exhaustive missing
cases in switch of type opcode.Opcode: opcode.PUSHINT8, opcode
.PUSHINT16, opcode.PUSHINT32, opcode.PUSHINT64, opcode.PUSHINT128,
opcode.PUSHINT256, opcode.PUSHT, opcode.PUSHF, opcode.PUSHNULL, opcode
.PUSHDATA1, opcode.PUSHDATA2, opcode.PUSHDATA4, opcode.PUSHM1, opcode
.PUSH0, opcode.PUSH1, opcode.PUSH2, opcode.PUSH3, opcode.PUSH4, opcode
.PUSH5, opcode.PUSH6, opcode.PUSH7, opcode.PUSH8, opcode.PUSH9, opcode
.PUSH10, opcode.PUSH11, opcode.PUSH12, opcode.PUSH13, opcode.PUSH14,
opcode.PUSH15, opcode.PUSH16, opcode.NOP, opcode.CALLA, opcode.CALLT,
opcode.ABORT, opcode.ASSERT, opcode.THROW, opcode.ENDFINALLY, opcode
.RET, opcode.SYSCALL, opcode.DEPTH, opcode.DROP, opcode.NIP, opcode
.XDROP, opcode.CLEAR, opcode.DUP, opcode.OVER, opcode.PICK, opcode.TUCK,
opcode.SWAP, opcode.ROT, opcode.ROLL, opcode.REVERSE3, opcode.REVERSE4,
opcode.REVERSEN, opcode.INITSSLOT, opcode.INITSLOT, opcode.LDSFLD0,
opcode.LDSFLD1, opcode.LDSFLD2, opcode.LDSFLD3, opcode.LDSFLD4, opcode
.LDSFLD5, opcode.LDSFLD6, opcode.LDSFLD, opcode.STSFLD0, opcode
.STSFLD1, opcode.STSFLD2, opcode.STSFLD3, opcode.STSFLD4, opcode
.STSFLD5, opcode.STSFLD6, opcode.STSFLD, opcode.LDLOC0, opcode.LDLOC1,
opcode.LDLOC2, opcode.LDLOC3, opcode.LDLOC4, opcode.LDLOC5, opcode
.LDLOC6, opcode.LDLOC, opcode.STLOC0, opcode.STLOC1, opcode.STLOC2,
opcode.STLOC3, opcode.STLOC4, opcode.STLOC5, opcode.STLOC6, opcode
.STLOC, opcode.LDARG0, opcode.LDARG1, opcode.LDARG2, opcode.LDARG3,
opcode.LDARG4, opcode.LDARG5, opcode.LDARG6, opcode.LDARG, opcode
.STARG0, opcode.STARG1, opcode.STARG2, opcode.STARG3, opcode.STARG4,
opcode.STARG5, opcode.STARG6, opcode.STARG, opcode.NEWBUFFER, opcode
.MEMCPY, opcode.CAT, opcode.SUBSTR, opcode.LEFT, opcode.RIGHT, opcode
.INVERT, opcode.AND, opcode.OR, opcode.XOR, opcode.EQUAL, opcode
.NOTEQUAL, opcode.SIGN, opcode.ABS, opcode.NEGATE, opcode.INC, opcode
.DEC, opcode.ADD, opcode.SUB, opcode.MUL, opcode.DIV, opcode.MOD,
opcode.POW, opcode.SQRT, opcode.MODMUL, opcode.MODPOW, opcode.SHL,
opcode.SHR, opcode.NOT, opcode.BOOLAND, opcode.BOOLOR, opcode.NZ,
opcode.NUMEQUAL, opcode.NUMNOTEQUAL, opcode.LT, opcode.LE, opcode.GT,
opcode.GE, opcode.MIN, opcode.MAX, opcode.WITHIN, opcode.PACKMAP,
opcode.PACKSTRUCT, opcode.PACK, opcode.UNPACK, opcode.NEWARRAY0,
opcode.NEWARRAY, opcode.NEWARRAYT, opcode.NEWSTRUCT0, opcode
.NEWSTRUCT, opcode.NEWMAP, opcode.SIZE, opcode.HASKEY, opcode.KEYS,
opcode.VALUES, opcode.PICKITEM, opcode.APPEND, opcode.SETITEM,
opcode.REVERSEITEMS, opcode.REMOVE, opcode.CLEARITEMS, opcode
.POPITEM, opcode.ISNULL, opcode.ISTYPE, opcode.CONVERT, opcode
.ABORTMSG, opcode.ASSERTMSG
pkg/compiler/inline_test.go:34:3 exhaustive missing
cases in switch of type opcode.Opcode: opcode.PUSHINT8, opcode
.PUSHINT16, opcode.PUSHINT32, opcode.PUSHINT64, opcode.PUSHINT128,
opcode.PUSHINT256, opcode.PUSHT, opcode.PUSHF, opcode.PUSHA, opcode
.PUSHNULL, opcode.PUSHDATA1, opcode.PUSHDATA2, opcode.PUSHDATA4, opcode
.PUSHM1, opcode.PUSH0, opcode.PUSH1, opcode.PUSH2, opcode.PUSH3, opcode
.PUSH4, opcode.PUSH5, opcode.PUSH6, opcode.PUSH7, opcode.PUSH8, opcode
.PUSH9, opcode.PUSH10, opcode.PUSH11, opcode.PUSH12, opcode.PUSH13,
opcode.PUSH14, opcode.PUSH15, opcode.PUSH16, opcode.NOP, opcode.JMP,
opcode.JMPL, opcode.JMPIF, opcode.JMPIFL, opcode.JMPIFNOT, opcode
.JMPIFNOTL, opcode.JMPEQ, opcode.JMPEQL, opcode.JMPNE, opcode.JMPNEL,
opcode.JMPGT, opcode.JMPGTL, opcode.JMPGE, opcode.JMPGEL, opcode.JMPLT,
opcode.JMPLTL, opcode.JMPLE, opcode.JMPLEL, opcode.CALLA, opcode.CALLT,
opcode.ABORT, opcode.ASSERT, opcode.THROW, opcode.TRY, opcode.TRYL,
opcode.ENDTRY, opcode.ENDTRYL, opcode.ENDFINALLY, opcode.RET, opcode
.SYSCALL, opcode.DEPTH, opcode.DROP, opcode.NIP, opcode.XDROP, opcode
.CLEAR, opcode.DUP, opcode.OVER, opcode.PICK, opcode.TUCK, opcode.SWAP,
opcode.ROT, opcode.ROLL, opcode.REVERSE3, opcode.REVERSE4, opcode
.REVERSEN, opcode.LDSFLD0, opcode.LDSFLD1, opcode.LDSFLD2, opcode
.LDSFLD3, opcode.LDSFLD4, opcode.LDSFLD5, opcode.LDSFLD6, opcode.LDSFLD,
opcode.STSFLD0, opcode.STSFLD1, opcode.STSFLD2, opcode.STSFLD3, opcode
.STSFLD4, opcode.STSFLD5, opcode.STSFLD6, opcode.STSFLD, opcode.LDLOC0,
opcode.LDLOC1, opcode.LDLOC2, opcode.LDLOC3, opcode.LDLOC4, opcode
.LDLOC5, opcode.LDLOC6, opcode.LDLOC, opcode.STLOC0, opcode.STLOC1,
opcode.STLOC2, opcode.STLOC3, opcode.STLOC4, opcode.STLOC5, opcode
.STLOC6, opcode.STLOC, opcode.LDARG0, opcode.LDARG1, opcode.LDARG2,
opcode.LDARG3, opcode.LDARG4, opcode.LDARG5, opcode.LDARG6, opcode
.LDARG, opcode.STARG0, opcode.STARG1, opcode.STARG2, opcode.STARG3,
opcode.STARG4, opcode.STARG5, opcode.STARG6, opcode.STARG, opcode
.NEWBUFFER, opcode.MEMCPY, opcode.CAT, opcode.SUBSTR, opcode.LEFT,
opcode.RIGHT, opcode.INVERT, opcode.AND, opcode.OR, opcode.XOR, opcode
.EQUAL, opcode.NOTEQUAL, opcode.SIGN, opcode.ABS, opcode.NEGATE,
opcode.INC, opcode.DEC, opcode.ADD, opcode.SUB, opcode.MUL, opcode
.DIV, opcode.MOD, opcode.POW, opcode.SQRT, opcode.MODMUL, opcode
.MODPOW, opcode.SHL, opcode.SHR, opcode.NOT, opcode.BOOLAND, opcode
.BOOLOR, opcode.NZ, opcode.NUMEQUAL, opcode.NUMNOTEQUAL, opcode.LT,
opcode.LE, opcode.GT, opcode.GE, opcode.MIN, opcode.MAX, opcode
.WITHIN, opcode.PACKMAP, opcode.PACKSTRUCT, opcode.PACK, opcode
.UNPACK, opcode.NEWARRAY0, opcode.NEWARRAY, opcode.NEWARRAYT, opcode
.NEWSTRUCT0, opcode.NEWSTRUCT, opcode.NEWMAP, opcode.SIZE, opcode
.HASKEY, opcode.KEYS, opcode.VALUES, opcode.PICKITEM, opcode.APPEND,
opcode.SETITEM, opcode.REVERSEITEMS, opcode.REMOVE, opcode.CLEARITEMS,
opcode.POPITEM, opcode.ISNULL, opcode.ISTYPE, opcode.CONVERT, opcode
.ABORTMSG, opcode.ASSERTMSG
pkg/network/server.go:1395:3 exhaustive missing
cases in switch of type network.CommandType: network.CMDNotFound,
network.CMDReject, network.CMDFilterLoad, network.CMDFilterAdd, network
.CMDFilterClear, network.CMDMerkleBlock, network.CMDAlert
pkg/network/server_test.go:532:3 exhaustive missing
cases in switch of type network.CommandType: network.CMDVersion, network
.CMDVerack, network.CMDGetAddr, network.CMDAddr, network.CMDPing,
network.CMDPong, network.CMDGetHeaders, network.CMDHeaders, network
.CMDGetBlocks, network.CMDMempool, network.CMDInv, network.CMDGetData,
network.CMDGetBlockByIndex, network.CMDGetMPTData, network.CMDMPTData,
network.CMDReject, network.CMDFilterLoad, network.CMDFilterAdd, network
.CMDFilterClear, network.CMDMerkleBlock, network.CMDAlert
pkg/network/server_test.go:817:4 exhaustive missing
cases in switch of type network.CommandType: network.CMDVersion, network
.CMDVerack, network.CMDGetAddr, network.CMDAddr, network.CMDPing,
network.CMDPong, network.CMDGetHeaders, network.CMDHeaders, network
.CMDGetBlocks, network.CMDMempool, network.CMDInv, network.CMDGetData,
network.CMDGetBlockByIndex, network.CMDNotFound, network.CMDTX, network
.CMDBlock, network.CMDExtensible, network.CMDP2PNotaryRequest, network
.CMDGetMPTData, network.CMDReject, network.CMDFilterLoad, network
.CMDFilterAdd, network.CMDFilterClear, network.CMDMerkleBlock, network
.CMDAlert
pkg/core/native/designate.go:262:2 exhaustive missing
cases in switch of type noderoles.Role: noderoles.NeoFSAlphabet
pkg/neorpc/rpcevent/filter.go:36:2 exhaustive missing cases in switch
of type neorpc.EventID: neorpc.InvalidEventID, neorpc.MissedEventID
pkg/consensus/recovery_message.go:145:2 exhaustive missing
cases in switch of type dbft.MessageType: dbft.PreCommitType, dbft
.RecoveryRequestType, dbft.RecoveryMessageType
cli/cmdargs/parser.go:202:3 exhaustive missing cases in switch of type
transaction.WitnessScope: transaction.None, transaction.CalledByEntry,
transaction.Rules, transaction.Global
```
Signed-off-by: Ekaterina Pavlova <ekt@morphbits.io>
2024-09-26 08:30:54 +00:00
|
|
|
default:
|
2021-02-04 12:41:00 +00:00
|
|
|
}
|
|
|
|
if ctx.IP() == ctx.LenInstr() {
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
2022-08-04 14:47:32 +00:00
|
|
|
if expectedCall != -1 {
|
|
|
|
require.Equal(t, expectedCall, actualCall)
|
|
|
|
}
|
|
|
|
if expectedInitSlot != -1 {
|
|
|
|
require.Equal(t, expectedInitSlot, actualInitSlot)
|
|
|
|
}
|
2021-02-04 12:41:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestInline(t *testing.T) {
|
|
|
|
srcTmpl := `package foo
|
|
|
|
import "github.com/nspcc-dev/neo-go/pkg/compiler/testdata/inline"
|
2021-05-25 13:17:40 +00:00
|
|
|
import "github.com/nspcc-dev/neo-go/pkg/compiler/testdata/foo"
|
|
|
|
var _ = foo.Dummy
|
2021-05-24 14:10:20 +00:00
|
|
|
type pair struct { a, b int }
|
|
|
|
type triple struct {
|
|
|
|
a int
|
|
|
|
b pair
|
|
|
|
}
|
2021-02-08 14:25:42 +00:00
|
|
|
var Num = 1
|
2021-02-04 12:41:00 +00:00
|
|
|
func Main() int {
|
|
|
|
%s
|
2022-08-25 09:06:19 +00:00
|
|
|
}
|
|
|
|
// local alias
|
|
|
|
func sum(a, b int) int {
|
|
|
|
return 42
|
2021-02-04 12:41:00 +00:00
|
|
|
}`
|
|
|
|
t.Run("no return", func(t *testing.T) {
|
|
|
|
src := fmt.Sprintf(srcTmpl, `inline.NoArgsNoReturn()
|
|
|
|
return 1`)
|
2021-05-24 14:03:31 +00:00
|
|
|
checkCallCount(t, src, 0, 0, 0)
|
2021-02-04 12:41:00 +00:00
|
|
|
eval(t, src, big.NewInt(1))
|
|
|
|
})
|
|
|
|
t.Run("has return, dropped", func(t *testing.T) {
|
|
|
|
src := fmt.Sprintf(srcTmpl, `inline.NoArgsReturn1()
|
|
|
|
return 2`)
|
2021-05-24 14:03:31 +00:00
|
|
|
checkCallCount(t, src, 0, 0, 0)
|
2021-02-04 12:41:00 +00:00
|
|
|
eval(t, src, big.NewInt(2))
|
|
|
|
})
|
|
|
|
t.Run("drop twice", func(t *testing.T) {
|
|
|
|
src := fmt.Sprintf(srcTmpl, `inline.DropInsideInline()
|
|
|
|
return 42`)
|
2021-05-24 14:03:31 +00:00
|
|
|
checkCallCount(t, src, 0, 0, 0)
|
2021-02-04 12:41:00 +00:00
|
|
|
eval(t, src, big.NewInt(42))
|
|
|
|
})
|
|
|
|
t.Run("no args return 1", func(t *testing.T) {
|
|
|
|
src := fmt.Sprintf(srcTmpl, `return inline.NoArgsReturn1()`)
|
2021-05-24 14:03:31 +00:00
|
|
|
checkCallCount(t, src, 0, 0, 0)
|
2021-02-04 12:41:00 +00:00
|
|
|
eval(t, src, big.NewInt(1))
|
|
|
|
})
|
|
|
|
t.Run("sum", func(t *testing.T) {
|
|
|
|
src := fmt.Sprintf(srcTmpl, `return inline.Sum(1, 2)`)
|
2021-05-24 14:03:31 +00:00
|
|
|
checkCallCount(t, src, 0, 0, 0)
|
2021-02-04 12:41:00 +00:00
|
|
|
eval(t, src, big.NewInt(3))
|
|
|
|
})
|
|
|
|
t.Run("sum squared (nested inline)", func(t *testing.T) {
|
|
|
|
src := fmt.Sprintf(srcTmpl, `return inline.SumSquared(1, 2)`)
|
2021-05-24 14:03:31 +00:00
|
|
|
checkCallCount(t, src, 0, 0, 0)
|
2021-02-04 12:41:00 +00:00
|
|
|
eval(t, src, big.NewInt(9))
|
|
|
|
})
|
|
|
|
t.Run("inline function in inline function parameter", func(t *testing.T) {
|
|
|
|
src := fmt.Sprintf(srcTmpl, `return inline.Sum(inline.SumSquared(1, 2), inline.Sum(3, 4))`)
|
2021-05-24 14:03:31 +00:00
|
|
|
checkCallCount(t, src, 0, 1, 2)
|
2021-02-04 12:41:00 +00:00
|
|
|
eval(t, src, big.NewInt(9+3+4))
|
|
|
|
})
|
|
|
|
t.Run("global name clash", func(t *testing.T) {
|
|
|
|
src := fmt.Sprintf(srcTmpl, `return inline.GetSumSameName()`)
|
2021-05-24 14:03:31 +00:00
|
|
|
checkCallCount(t, src, 0, 0, 0)
|
2021-02-04 12:41:00 +00:00
|
|
|
eval(t, src, big.NewInt(42))
|
|
|
|
})
|
|
|
|
t.Run("local name clash", func(t *testing.T) {
|
|
|
|
src := fmt.Sprintf(srcTmpl, `return inline.Sum(inline.SumSquared(1, 2), sum(3, 4))`)
|
2021-05-24 14:03:31 +00:00
|
|
|
checkCallCount(t, src, 1, 2, 2)
|
2021-02-04 12:41:00 +00:00
|
|
|
eval(t, src, big.NewInt(51))
|
|
|
|
})
|
2021-02-08 10:51:25 +00:00
|
|
|
t.Run("var args, empty", func(t *testing.T) {
|
|
|
|
src := fmt.Sprintf(srcTmpl, `return inline.VarSum(11)`)
|
2021-05-24 14:03:31 +00:00
|
|
|
checkCallCount(t, src, 0, 1, 3)
|
2021-02-08 10:51:25 +00:00
|
|
|
eval(t, src, big.NewInt(11))
|
|
|
|
})
|
|
|
|
t.Run("var args, direct", func(t *testing.T) {
|
|
|
|
src := fmt.Sprintf(srcTmpl, `return inline.VarSum(11, 14, 17)`)
|
2021-05-24 14:03:31 +00:00
|
|
|
checkCallCount(t, src, 0, 1, 3)
|
2021-02-08 10:51:25 +00:00
|
|
|
eval(t, src, big.NewInt(42))
|
|
|
|
})
|
|
|
|
t.Run("var args, array", func(t *testing.T) {
|
|
|
|
src := fmt.Sprintf(srcTmpl, `arr := []int{14, 17}
|
|
|
|
return inline.VarSum(11, arr...)`)
|
2021-05-24 14:03:31 +00:00
|
|
|
checkCallCount(t, src, 0, 1, 3)
|
2021-02-08 10:51:25 +00:00
|
|
|
eval(t, src, big.NewInt(42))
|
|
|
|
})
|
2021-02-08 14:25:42 +00:00
|
|
|
t.Run("globals", func(t *testing.T) {
|
|
|
|
src := fmt.Sprintf(srcTmpl, `return inline.Concat(Num)`)
|
2021-05-24 14:03:31 +00:00
|
|
|
checkCallCount(t, src, 0, 0, 0)
|
2021-02-08 14:25:42 +00:00
|
|
|
eval(t, src, big.NewInt(221))
|
|
|
|
})
|
2021-05-19 07:34:44 +00:00
|
|
|
t.Run("locals, alias", func(t *testing.T) {
|
|
|
|
src := fmt.Sprintf(srcTmpl, `num := 1; return inline.Concat(num)`)
|
2021-05-24 14:03:31 +00:00
|
|
|
checkCallCount(t, src, 0, 1, 1)
|
2021-05-19 07:34:44 +00:00
|
|
|
eval(t, src, big.NewInt(221))
|
|
|
|
})
|
2021-05-24 14:10:20 +00:00
|
|
|
t.Run("selector, global", func(t *testing.T) {
|
|
|
|
src := fmt.Sprintf(srcTmpl, `return inline.Sum(inline.A, 2)`)
|
2021-05-25 13:02:28 +00:00
|
|
|
checkCallCount(t, src, 0, 0, 0)
|
2021-05-24 14:10:20 +00:00
|
|
|
eval(t, src, big.NewInt(3))
|
|
|
|
})
|
|
|
|
t.Run("selector, struct, simple", func(t *testing.T) {
|
|
|
|
src := fmt.Sprintf(srcTmpl, `x := pair{a: 1, b: 2}; return inline.Sum(x.b, 1)`)
|
2021-05-25 13:02:28 +00:00
|
|
|
checkCallCount(t, src, 0, 1, 1)
|
2021-05-24 14:10:20 +00:00
|
|
|
eval(t, src, big.NewInt(3))
|
|
|
|
})
|
|
|
|
t.Run("selector, struct, complex", func(t *testing.T) {
|
|
|
|
src := fmt.Sprintf(srcTmpl, `x := triple{a: 1, b: pair{a: 2, b: 3}}
|
|
|
|
return inline.Sum(x.b.a, 1)`)
|
2021-05-25 13:02:28 +00:00
|
|
|
checkCallCount(t, src, 0, 1, 1)
|
2021-05-24 14:10:20 +00:00
|
|
|
eval(t, src, big.NewInt(3))
|
|
|
|
})
|
|
|
|
t.Run("expression", func(t *testing.T) {
|
|
|
|
src := fmt.Sprintf(srcTmpl, `x, y := 1, 2
|
|
|
|
return inline.Sum(x+y, y*2)`)
|
2021-05-25 13:02:28 +00:00
|
|
|
checkCallCount(t, src, 0, 1, 2)
|
2021-05-24 14:10:20 +00:00
|
|
|
eval(t, src, big.NewInt(7))
|
|
|
|
})
|
2021-05-25 13:17:40 +00:00
|
|
|
t.Run("foreign package call", func(t *testing.T) {
|
|
|
|
src := fmt.Sprintf(srcTmpl, `return inline.Sum(foo.Bar(), foo.Dummy+1)`)
|
|
|
|
checkCallCount(t, src, 1, 1, 1)
|
|
|
|
eval(t, src, big.NewInt(3))
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestIssue1879(t *testing.T) {
|
|
|
|
src := `package foo
|
|
|
|
import "github.com/nspcc-dev/neo-go/pkg/interop/runtime"
|
|
|
|
func Main() int {
|
|
|
|
data := "main is called"
|
|
|
|
runtime.Log("log " + string(data))
|
|
|
|
return 42
|
|
|
|
}`
|
|
|
|
checkCallCount(t, src, 0, 1, 1)
|
2021-02-04 12:41:00 +00:00
|
|
|
}
|
|
|
|
|
2021-02-26 14:58:08 +00:00
|
|
|
func TestInlineInLoop(t *testing.T) {
|
|
|
|
t.Run("simple", func(t *testing.T) {
|
|
|
|
src := `package foo
|
2021-03-04 10:26:16 +00:00
|
|
|
import "github.com/nspcc-dev/neo-go/pkg/interop/storage"
|
2021-02-26 14:58:08 +00:00
|
|
|
import "github.com/nspcc-dev/neo-go/pkg/compiler/testdata/inline"
|
|
|
|
func Main() int {
|
|
|
|
sum := 0
|
|
|
|
values := []int{10, 11}
|
|
|
|
for _, v := range values {
|
2021-03-04 10:26:16 +00:00
|
|
|
_ = v // use 'v'
|
|
|
|
storage.GetContext() // push something on stack to check it's dropped
|
2021-02-26 14:58:08 +00:00
|
|
|
sum += inline.VarSum(1, 2, 3, 4)
|
|
|
|
}
|
|
|
|
return sum
|
|
|
|
}`
|
|
|
|
eval(t, src, big.NewInt(20))
|
|
|
|
})
|
2021-02-26 15:02:54 +00:00
|
|
|
t.Run("inlined argument", func(t *testing.T) {
|
|
|
|
src := `package foo
|
2021-03-04 10:26:16 +00:00
|
|
|
import "github.com/nspcc-dev/neo-go/pkg/interop/runtime"
|
|
|
|
import "github.com/nspcc-dev/neo-go/pkg/interop/storage"
|
2021-02-26 15:02:54 +00:00
|
|
|
import "github.com/nspcc-dev/neo-go/pkg/compiler/testdata/inline"
|
|
|
|
func Main() int {
|
|
|
|
sum := 0
|
|
|
|
values := []int{10, 11}
|
|
|
|
for _, v := range values {
|
2021-03-04 10:26:16 +00:00
|
|
|
_ = v // use 'v'
|
|
|
|
storage.GetContext() // push something on stack to check it's dropped
|
|
|
|
sum += inline.VarSum(1, 2, 3, runtime.GetTime()) // runtime.GetTime always returns 4 in these tests
|
2021-02-26 15:02:54 +00:00
|
|
|
}
|
|
|
|
return sum
|
|
|
|
}`
|
|
|
|
eval(t, src, big.NewInt(20))
|
|
|
|
})
|
2021-02-26 14:58:08 +00:00
|
|
|
t.Run("check clean stack on return", func(t *testing.T) {
|
|
|
|
src := `package foo
|
2021-03-04 10:26:16 +00:00
|
|
|
import "github.com/nspcc-dev/neo-go/pkg/interop/storage"
|
2021-02-26 14:58:08 +00:00
|
|
|
import "github.com/nspcc-dev/neo-go/pkg/compiler/testdata/inline"
|
|
|
|
func Main() int {
|
|
|
|
values := []int{10, 11, 12}
|
|
|
|
for _, v := range values {
|
2021-03-04 10:26:16 +00:00
|
|
|
storage.GetContext() // push something on stack to check it's dropped
|
2021-02-26 14:58:08 +00:00
|
|
|
if v == 11 {
|
|
|
|
return inline.VarSum(2, 20, 200)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return 0
|
|
|
|
}`
|
|
|
|
eval(t, src, big.NewInt(222))
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestInlineInSwitch(t *testing.T) {
|
|
|
|
src := `package foo
|
|
|
|
import "github.com/nspcc-dev/neo-go/pkg/compiler/testdata/inline"
|
|
|
|
func Main() int {
|
|
|
|
switch inline.VarSum(1, 2) {
|
|
|
|
case inline.VarSum(3, 1):
|
|
|
|
return 10
|
|
|
|
case inline.VarSum(4, -1):
|
|
|
|
return 11
|
|
|
|
default:
|
|
|
|
return 12
|
|
|
|
}
|
|
|
|
}`
|
|
|
|
eval(t, src, big.NewInt(11))
|
|
|
|
}
|
|
|
|
|
2021-02-25 12:12:16 +00:00
|
|
|
func TestInlineGlobalVariable(t *testing.T) {
|
|
|
|
t.Run("simple", func(t *testing.T) {
|
|
|
|
src := `package foo
|
|
|
|
import "github.com/nspcc-dev/neo-go/pkg/compiler/testdata/inline"
|
|
|
|
var a = inline.Sum(1, 2)
|
|
|
|
func Main() int {
|
|
|
|
return a
|
|
|
|
}`
|
|
|
|
eval(t, src, big.NewInt(3))
|
|
|
|
})
|
|
|
|
t.Run("complex", func(t *testing.T) {
|
|
|
|
src := `package foo
|
|
|
|
import "github.com/nspcc-dev/neo-go/pkg/compiler/testdata/inline"
|
|
|
|
var a = inline.Sum(3, 4)
|
|
|
|
var b = inline.SumSquared(1, 2)
|
|
|
|
var c = a + b
|
|
|
|
func init() {
|
|
|
|
c--
|
|
|
|
}
|
|
|
|
func Main() int {
|
|
|
|
return c
|
|
|
|
}`
|
|
|
|
eval(t, src, big.NewInt(15))
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2021-04-05 19:56:59 +00:00
|
|
|
func TestInlineVariadicInInlinedCall(t *testing.T) {
|
|
|
|
src := `package foo
|
|
|
|
import "github.com/nspcc-dev/neo-go/pkg/compiler/testdata/inline"
|
|
|
|
func Main() int {
|
|
|
|
return inline.SumSquared(inline.SumVar(3, 4) - 2, 3)
|
|
|
|
}`
|
|
|
|
eval(t, src, big.NewInt(64))
|
|
|
|
}
|
|
|
|
|
2021-02-04 12:41:00 +00:00
|
|
|
func TestInlineConversion(t *testing.T) {
|
|
|
|
src1 := `package foo
|
|
|
|
import "github.com/nspcc-dev/neo-go/pkg/compiler/testdata/inline"
|
|
|
|
var _ = inline.A
|
|
|
|
func Main() int {
|
|
|
|
a := 2
|
|
|
|
return inline.SumSquared(1, a)
|
|
|
|
}`
|
|
|
|
b1, err := compiler.Compile("foo.go", strings.NewReader(src1))
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
src2 := `package foo
|
|
|
|
import "github.com/nspcc-dev/neo-go/pkg/compiler/testdata/inline"
|
|
|
|
var _ = inline.A
|
|
|
|
func Main() int {
|
|
|
|
a := 2
|
|
|
|
{
|
2021-02-05 13:15:26 +00:00
|
|
|
return (1 + a) * (1 + a)
|
2021-02-04 12:41:00 +00:00
|
|
|
}
|
|
|
|
}`
|
|
|
|
b2, err := compiler.Compile("foo.go", strings.NewReader(src2))
|
|
|
|
require.NoError(t, err)
|
|
|
|
require.Equal(t, b2, b1)
|
|
|
|
}
|
2021-02-08 14:25:42 +00:00
|
|
|
|
|
|
|
func TestInlineConversionQualified(t *testing.T) {
|
|
|
|
src1 := `package foo
|
|
|
|
import "github.com/nspcc-dev/neo-go/pkg/compiler/testdata/inline"
|
|
|
|
var A = 1
|
|
|
|
func Main() int {
|
|
|
|
return inline.Concat(A)
|
|
|
|
}`
|
|
|
|
b1, err := compiler.Compile("foo.go", strings.NewReader(src1))
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
src2 := `package foo
|
|
|
|
import "github.com/nspcc-dev/neo-go/pkg/compiler/testdata/inline"
|
|
|
|
import "github.com/nspcc-dev/neo-go/pkg/compiler/testdata/inline/b"
|
|
|
|
var A = 1
|
|
|
|
func Main() int {
|
|
|
|
return A * 100 + b.A * 10 + inline.A
|
|
|
|
}`
|
|
|
|
b2, err := compiler.Compile("foo.go", strings.NewReader(src2))
|
|
|
|
require.NoError(t, err)
|
|
|
|
require.Equal(t, b2, b1)
|
|
|
|
}
|
2021-04-05 20:03:10 +00:00
|
|
|
|
|
|
|
func TestPackageVarsInInlinedCalls(t *testing.T) {
|
|
|
|
src := `package foo
|
|
|
|
import "github.com/nspcc-dev/neo-go/pkg/compiler/testdata/inline"
|
|
|
|
import "github.com/nspcc-dev/neo-go/pkg/compiler/testdata/inline/b"
|
|
|
|
func Main() int {
|
|
|
|
return inline.Sum(inline.A, b.A)
|
|
|
|
}`
|
|
|
|
eval(t, src, big.NewInt(13))
|
|
|
|
}
|
2022-07-06 14:56:53 +00:00
|
|
|
|
|
|
|
func TestInlinedMethod(t *testing.T) {
|
|
|
|
src := `package foo
|
|
|
|
import "github.com/nspcc-dev/neo-go/pkg/compiler/testdata/inline"
|
|
|
|
func Main() int {
|
|
|
|
// It's important for this variable to not be named 't'.
|
|
|
|
var z inline.T
|
|
|
|
i := z.Inc(42)
|
|
|
|
if i != 0 || z.N != 42 {
|
|
|
|
return 0
|
|
|
|
}
|
|
|
|
i = z.Inc(100500)
|
|
|
|
if i != 42 {
|
|
|
|
return 0
|
|
|
|
}
|
|
|
|
return z.N
|
|
|
|
}`
|
|
|
|
eval(t, src, big.NewInt(100542))
|
|
|
|
}
|
2022-07-06 14:52:57 +00:00
|
|
|
|
|
|
|
func TestInlinedMethodWithPointer(t *testing.T) {
|
|
|
|
src := `package foo
|
|
|
|
import "github.com/nspcc-dev/neo-go/pkg/compiler/testdata/inline"
|
|
|
|
func Main() int {
|
|
|
|
// It's important for this variable to not be named 't'.
|
|
|
|
var z = &inline.T{}
|
|
|
|
i := z.Inc(42)
|
|
|
|
if i != 0 || z.N != 42 {
|
|
|
|
return 0
|
|
|
|
}
|
|
|
|
i = z.Inc(100500)
|
|
|
|
if i != 42 {
|
|
|
|
return 0
|
|
|
|
}
|
|
|
|
return z.N
|
|
|
|
}`
|
|
|
|
eval(t, src, big.NewInt(100542))
|
|
|
|
}
|
2022-07-11 08:38:18 +00:00
|
|
|
|
|
|
|
func TestInlineConditionalReturn(t *testing.T) {
|
|
|
|
srcTmpl := `package foo
|
|
|
|
import "github.com/nspcc-dev/neo-go/pkg/compiler/testdata/inline/c"
|
|
|
|
func Main() int {
|
|
|
|
x := %d
|
|
|
|
if c.Is42(x) {
|
|
|
|
return 100
|
|
|
|
}
|
|
|
|
return 10
|
|
|
|
}`
|
|
|
|
t.Run("true", func(t *testing.T) {
|
|
|
|
eval(t, fmt.Sprintf(srcTmpl, 123), big.NewInt(10))
|
|
|
|
})
|
|
|
|
t.Run("false", func(t *testing.T) {
|
|
|
|
eval(t, fmt.Sprintf(srcTmpl, 42), big.NewInt(100))
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestInlineDoubleConditionalReturn(t *testing.T) {
|
|
|
|
srcTmpl := `package foo
|
|
|
|
import "github.com/nspcc-dev/neo-go/pkg/compiler/testdata/inline/c"
|
|
|
|
func Main() int {
|
|
|
|
return c.Transform(%d, %d)
|
|
|
|
}`
|
|
|
|
|
|
|
|
testCase := []struct {
|
|
|
|
name string
|
|
|
|
a, b, result int
|
|
|
|
}{
|
|
|
|
{"true, true, small", 42, 3, 6},
|
|
|
|
{"true, true, big", 42, 15, 15},
|
|
|
|
{"true, false", 42, 42, 42},
|
|
|
|
{"false, true", 3, 11, 6},
|
|
|
|
{"false, false", 3, 42, 6},
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, tc := range testCase {
|
|
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
|
|
eval(t, fmt.Sprintf(srcTmpl, tc.a, tc.b), big.NewInt(int64(tc.result)))
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
2022-09-27 11:35:13 +00:00
|
|
|
|
|
|
|
func TestInlineAppendStatement(t *testing.T) {
|
|
|
|
src := `package foo
|
|
|
|
import "github.com/nspcc-dev/neo-go/pkg/compiler/testdata/inline"
|
|
|
|
|
|
|
|
func Main() []byte {
|
|
|
|
val := []byte{4, 5, 6}
|
|
|
|
return inline.AppendInsideInline(val)
|
|
|
|
}`
|
|
|
|
eval(t, src, []byte{1, 2, 3, 4, 5, 6})
|
|
|
|
}
|
2022-09-27 12:36:06 +00:00
|
|
|
|
|
|
|
func TestInlineForeignType(t *testing.T) {
|
|
|
|
src := `package foo
|
|
|
|
import "github.com/nspcc-dev/neo-go/pkg/compiler/testdata/inline"
|
|
|
|
|
|
|
|
func Main() int {
|
|
|
|
return inline.ForeignTypeInsideInline()
|
|
|
|
}`
|
|
|
|
eval(t, src, big.NewInt(29))
|
|
|
|
}
|