vm: add ABORTMSG and ASSERTMSG opcodes

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
This commit is contained in:
Anna Shaleva 2023-07-20 11:25:00 +03:00
parent 2493400525
commit e7f77e052f
5 changed files with 22 additions and 1 deletions

View file

@ -70,6 +70,8 @@ var coefficients = [256]uint16{
opcode.CALLT: 1 << 15, opcode.CALLT: 1 << 15,
opcode.ABORT: 0, opcode.ABORT: 0,
opcode.ASSERT: 1 << 0, opcode.ASSERT: 1 << 0,
opcode.ABORTMSG: 0, // TODO
opcode.ASSERTMSG: 1 << 0, // TODO
opcode.THROW: 1 << 9, opcode.THROW: 1 << 9,
opcode.TRY: 1 << 2, opcode.TRY: 1 << 2,
opcode.TRYL: 1 << 2, opcode.TRYL: 1 << 2,

View file

@ -225,6 +225,10 @@ const (
ISNULL Opcode = 0xD8 ISNULL Opcode = 0xD8
ISTYPE Opcode = 0xD9 ISTYPE Opcode = 0xD9
CONVERT Opcode = 0xDB CONVERT Opcode = 0xDB
// Extensions.
ABORTMSG Opcode = 0xE0
ASSERTMSG Opcode = 0xE1
) )
var validCodes [256]bool var validCodes [256]bool

View file

@ -202,9 +202,11 @@ func _() {
_ = x[ISNULL-216] _ = x[ISNULL-216]
_ = x[ISTYPE-217] _ = x[ISTYPE-217]
_ = x[CONVERT-219] _ = x[CONVERT-219]
_ = x[ABORTMSG-224]
_ = x[ASSERTMSG-225]
} }
const _Opcode_name = "PUSHINT8PUSHINT16PUSHINT32PUSHINT64PUSHINT128PUSHINT256PUSHTPUSHFPUSHAPUSHNULLPUSHDATA1PUSHDATA2PUSHDATA4PUSHM1PUSH0PUSH1PUSH2PUSH3PUSH4PUSH5PUSH6PUSH7PUSH8PUSH9PUSH10PUSH11PUSH12PUSH13PUSH14PUSH15PUSH16NOPJMPJMP_LJMPIFJMPIF_LJMPIFNOTJMPIFNOT_LJMPEQJMPEQ_LJMPNEJMPNE_LJMPGTJMPGT_LJMPGEJMPGE_LJMPLTJMPLT_LJMPLEJMPLE_LCALLCALL_LCALLACALLTABORTASSERTTHROWTRYTRY_LENDTRYENDTRY_LENDFINALLYRETSYSCALLDEPTHDROPNIPXDROPCLEARDUPOVERPICKTUCKSWAPROTROLLREVERSE3REVERSE4REVERSENINITSSLOTINITSLOTLDSFLD0LDSFLD1LDSFLD2LDSFLD3LDSFLD4LDSFLD5LDSFLD6LDSFLDSTSFLD0STSFLD1STSFLD2STSFLD3STSFLD4STSFLD5STSFLD6STSFLDLDLOC0LDLOC1LDLOC2LDLOC3LDLOC4LDLOC5LDLOC6LDLOCSTLOC0STLOC1STLOC2STLOC3STLOC4STLOC5STLOC6STLOCLDARG0LDARG1LDARG2LDARG3LDARG4LDARG5LDARG6LDARGSTARG0STARG1STARG2STARG3STARG4STARG5STARG6STARGNEWBUFFERMEMCPYCATSUBSTRLEFTRIGHTINVERTANDORXOREQUALNOTEQUALSIGNABSNEGATEINCDECADDSUBMULDIVMODPOWSQRTMODMULMODPOWSHLSHRNOTBOOLANDBOOLORNZNUMEQUALNUMNOTEQUALLTLEGTGEMINMAXWITHINPACKMAPPACKSTRUCTPACKUNPACKNEWARRAY0NEWARRAYNEWARRAY_TNEWSTRUCT0NEWSTRUCTNEWMAPSIZEHASKEYKEYSVALUESPICKITEMAPPENDSETITEMREVERSEITEMSREMOVECLEARITEMSPOPITEMISNULLISTYPECONVERT" const _Opcode_name = "PUSHINT8PUSHINT16PUSHINT32PUSHINT64PUSHINT128PUSHINT256PUSHTPUSHFPUSHAPUSHNULLPUSHDATA1PUSHDATA2PUSHDATA4PUSHM1PUSH0PUSH1PUSH2PUSH3PUSH4PUSH5PUSH6PUSH7PUSH8PUSH9PUSH10PUSH11PUSH12PUSH13PUSH14PUSH15PUSH16NOPJMPJMP_LJMPIFJMPIF_LJMPIFNOTJMPIFNOT_LJMPEQJMPEQ_LJMPNEJMPNE_LJMPGTJMPGT_LJMPGEJMPGE_LJMPLTJMPLT_LJMPLEJMPLE_LCALLCALL_LCALLACALLTABORTASSERTTHROWTRYTRY_LENDTRYENDTRY_LENDFINALLYRETSYSCALLDEPTHDROPNIPXDROPCLEARDUPOVERPICKTUCKSWAPROTROLLREVERSE3REVERSE4REVERSENINITSSLOTINITSLOTLDSFLD0LDSFLD1LDSFLD2LDSFLD3LDSFLD4LDSFLD5LDSFLD6LDSFLDSTSFLD0STSFLD1STSFLD2STSFLD3STSFLD4STSFLD5STSFLD6STSFLDLDLOC0LDLOC1LDLOC2LDLOC3LDLOC4LDLOC5LDLOC6LDLOCSTLOC0STLOC1STLOC2STLOC3STLOC4STLOC5STLOC6STLOCLDARG0LDARG1LDARG2LDARG3LDARG4LDARG5LDARG6LDARGSTARG0STARG1STARG2STARG3STARG4STARG5STARG6STARGNEWBUFFERMEMCPYCATSUBSTRLEFTRIGHTINVERTANDORXOREQUALNOTEQUALSIGNABSNEGATEINCDECADDSUBMULDIVMODPOWSQRTMODMULMODPOWSHLSHRNOTBOOLANDBOOLORNZNUMEQUALNUMNOTEQUALLTLEGTGEMINMAXWITHINPACKMAPPACKSTRUCTPACKUNPACKNEWARRAY0NEWARRAYNEWARRAY_TNEWSTRUCT0NEWSTRUCTNEWMAPSIZEHASKEYKEYSVALUESPICKITEMAPPENDSETITEMREVERSEITEMSREMOVECLEARITEMSPOPITEMISNULLISTYPECONVERTABORTMSGASSERTMSG"
var _Opcode_map = map[Opcode]string{ var _Opcode_map = map[Opcode]string{
0: _Opcode_name[0:8], 0: _Opcode_name[0:8],
@ -401,6 +403,8 @@ var _Opcode_map = map[Opcode]string{
216: _Opcode_name[1112:1118], 216: _Opcode_name[1112:1118],
217: _Opcode_name[1118:1124], 217: _Opcode_name[1118:1124],
219: _Opcode_name[1124:1131], 219: _Opcode_name[1124:1131],
224: _Opcode_name[1131:1139],
225: _Opcode_name[1139:1148],
} }
func (i Opcode) String() string { func (i Opcode) String() string {

View file

@ -1587,11 +1587,21 @@ func (v *VM) execute(ctx *Context, op opcode.Opcode, parameter []byte) (err erro
case opcode.ABORT: case opcode.ABORT:
panic("ABORT") panic("ABORT")
case opcode.ABORTMSG:
msg := v.estack.Pop().Bytes()
panic(fmt.Sprintf("%s is executed. Reason: %s", op, string(msg)))
case opcode.ASSERT: case opcode.ASSERT:
if !v.estack.Pop().Bool() { if !v.estack.Pop().Bool() {
panic("ASSERT failed") panic("ASSERT failed")
} }
case opcode.ASSERTMSG:
msg := v.estack.Pop().Bytes()
if !v.estack.Pop().Bool() {
panic(fmt.Sprintf("%s is executed with false result. Reason: %s", op, msg))
}
case opcode.TRY, opcode.TRYL: case opcode.TRY, opcode.TRYL:
catchP, finallyP := getTryParams(op, parameter) catchP, finallyP := getTryParams(op, parameter)
if ctx.tryStack.Len() >= MaxTryNestingDepth { if ctx.tryStack.Len() >= MaxTryNestingDepth {

View file

@ -1097,6 +1097,7 @@ func TestTRY(t *testing.T) {
t.Run("Simple", getTRYTestFunc(1, push1, add5, nil)) t.Run("Simple", getTRYTestFunc(1, push1, add5, nil))
t.Run("Throw", getTRYTestFunc(18, throw, add5, nil)) t.Run("Throw", getTRYTestFunc(18, throw, add5, nil))
t.Run("Abort", getTRYTestFunc(nil, []byte{byte(opcode.ABORT)}, push1, nil)) t.Run("Abort", getTRYTestFunc(nil, []byte{byte(opcode.ABORT)}, push1, nil))
t.Run("AbortMSG", getTRYTestFunc(nil, []byte{byte(opcode.PUSH1), byte(opcode.ABORTMSG)}, push1, nil))
t.Run("ThrowInCatch", getTRYTestFunc(nil, throw, throw, nil)) t.Run("ThrowInCatch", getTRYTestFunc(nil, throw, throw, nil))
}) })
t.Run("WithFinally", func(t *testing.T) { t.Run("WithFinally", func(t *testing.T) {