vm: allow to emit uint and uint64 as a part of array

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
This commit is contained in:
Anna Shaleva 2023-05-17 12:27:45 +03:00
parent 15138b2004
commit fc6029d006
2 changed files with 24 additions and 5 deletions

View file

@ -100,7 +100,7 @@ func bigInt(w *io.BinWriter, n *big.Int, trySmall bool) {
// Array emits an array of elements to the given buffer. It accepts elements of the following types: // Array emits an array of elements to the given buffer. It accepts elements of the following types:
// - int8, int16, int32, int64, int // - int8, int16, int32, int64, int
// - uint8, uint16, uint32 // - uint8, uint16, uint32, uint64, uint
// - *big.Int // - *big.Int
// - string, []byte // - string, []byte
// - util.Uint160, *util.Uint160, util.Uint256, *util.Uint256 // - util.Uint160, *util.Uint160, util.Uint256, *util.Uint256
@ -119,6 +119,8 @@ func Array(w *io.BinWriter, es ...any) {
Array(w, e...) Array(w, e...)
case int64: case int64:
Int(w, e) Int(w, e)
case uint64:
BigInt(w, new(big.Int).SetUint64(e))
case int32: case int32:
Int(w, int64(e)) Int(w, int64(e))
case uint32: case uint32:
@ -133,6 +135,8 @@ func Array(w *io.BinWriter, es ...any) {
Int(w, int64(e)) Int(w, int64(e))
case int: case int:
Int(w, int64(e)) Int(w, int64(e))
case uint:
BigInt(w, new(big.Int).SetUint64(uint64(e)))
case *big.Int: case *big.Int:
BigInt(w, e) BigInt(w, e)
case string: case string:

View file

@ -225,6 +225,8 @@ func TestEmitArray(t *testing.T) {
veryBig := new(big.Int).SetUint64(math.MaxUint64) veryBig := new(big.Int).SetUint64(math.MaxUint64)
veryBig.Add(veryBig, big.NewInt(1)) veryBig.Add(veryBig, big.NewInt(1))
Array(buf.BinWriter, Array(buf.BinWriter,
uint64(math.MaxUint64),
uint(math.MaxUint32), // don't use MaxUint to keep test results the same throughout all platforms.
stackitem.NewMapWithValue([]stackitem.MapElement{ stackitem.NewMapWithValue([]stackitem.MapElement{
{ {
Key: stackitem.Make(1), Key: stackitem.Make(1),
@ -323,14 +325,27 @@ func TestEmitArray(t *testing.T) {
assert.EqualValues(t, opcode.PUSH1, res[192]) assert.EqualValues(t, opcode.PUSH1, res[192])
assert.EqualValues(t, opcode.PUSH2, res[193]) assert.EqualValues(t, opcode.PUSH2, res[193])
assert.EqualValues(t, opcode.PACKMAP, res[194]) assert.EqualValues(t, opcode.PACKMAP, res[194])
// uint (MaxUint32)
assert.EqualValues(t, opcode.PUSHINT64, res[195])
assert.EqualValues(t, []byte{
0xff, 0xff, 0xff, 0xff,
0, 0, 0, 0,
}, res[196:204])
// uint64 (MaxUint64)
assert.EqualValues(t, opcode.PUSHINT128, res[204])
assert.EqualValues(t, []byte{
0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff,
0, 0, 0, 0,
0, 0, 0, 0}, res[205:221])
// Values packing: // Values packing:
assert.EqualValues(t, opcode.PUSHINT8, res[195]) assert.EqualValues(t, opcode.PUSHINT8, res[221])
assert.EqualValues(t, byte(21), res[196]) assert.EqualValues(t, byte(23), res[222])
assert.EqualValues(t, opcode.PACK, res[197]) assert.EqualValues(t, opcode.PACK, res[223])
// Overall script length: // Overall script length:
assert.EqualValues(t, 198, len(res)) assert.EqualValues(t, 224, len(res))
}) })
t.Run("empty", func(t *testing.T) { t.Run("empty", func(t *testing.T) {