vm: allow to emit any
based on its type
No functional changes, just moved a part of emit.Array to a separate exported method. It may be useful for contract-based witness invocation scripts construction and not only. Ref. https://github.com/nspcc-dev/neo-go/pull/3233#discussion_r1407786333. Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
This commit is contained in:
parent
2f9b4a2dbf
commit
b637048122
1 changed files with 71 additions and 65 deletions
|
@ -98,7 +98,21 @@ func bigInt(w *io.BinWriter, n *big.Int, trySmall bool) {
|
||||||
w.WriteBytes(padRight(1<<padSize, buf))
|
w.WriteBytes(padRight(1<<padSize, buf))
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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 everything that
|
||||||
|
// Any accepts.
|
||||||
|
func Array(w *io.BinWriter, es ...any) {
|
||||||
|
if len(es) == 0 {
|
||||||
|
Opcodes(w, opcode.NEWARRAY0)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
for i := len(es) - 1; i >= 0; i-- {
|
||||||
|
Any(w, es[i])
|
||||||
|
}
|
||||||
|
Int(w, int64(len(es)))
|
||||||
|
Opcodes(w, opcode.PACK)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Any emits element if supported. It accepts elements of the following types:
|
||||||
// - int8, int16, int32, int64, int
|
// - int8, int16, int32, int64, int
|
||||||
// - uint8, uint16, uint32, uint64, uint
|
// - uint8, uint16, uint32, uint64, uint
|
||||||
// - *big.Int
|
// - *big.Int
|
||||||
|
@ -108,73 +122,65 @@ func bigInt(w *io.BinWriter, n *big.Int, trySmall bool) {
|
||||||
// - stackitem.Convertible, stackitem.Item
|
// - stackitem.Convertible, stackitem.Item
|
||||||
// - nil
|
// - nil
|
||||||
// - []any
|
// - []any
|
||||||
func Array(w *io.BinWriter, es ...any) {
|
func Any(w *io.BinWriter, something any) {
|
||||||
if len(es) == 0 {
|
switch e := something.(type) {
|
||||||
Opcodes(w, opcode.NEWARRAY0)
|
case []any:
|
||||||
return
|
Array(w, e...)
|
||||||
}
|
case int64:
|
||||||
for i := len(es) - 1; i >= 0; i-- {
|
Int(w, e)
|
||||||
switch e := es[i].(type) {
|
case uint64:
|
||||||
case []any:
|
BigInt(w, new(big.Int).SetUint64(e))
|
||||||
Array(w, e...)
|
case int32:
|
||||||
case int64:
|
Int(w, int64(e))
|
||||||
Int(w, e)
|
case uint32:
|
||||||
case uint64:
|
Int(w, int64(e))
|
||||||
BigInt(w, new(big.Int).SetUint64(e))
|
case int16:
|
||||||
case int32:
|
Int(w, int64(e))
|
||||||
Int(w, int64(e))
|
case uint16:
|
||||||
case uint32:
|
Int(w, int64(e))
|
||||||
Int(w, int64(e))
|
case int8:
|
||||||
case int16:
|
Int(w, int64(e))
|
||||||
Int(w, int64(e))
|
case uint8:
|
||||||
case uint16:
|
Int(w, int64(e))
|
||||||
Int(w, int64(e))
|
case int:
|
||||||
case int8:
|
Int(w, int64(e))
|
||||||
Int(w, int64(e))
|
case uint:
|
||||||
case uint8:
|
BigInt(w, new(big.Int).SetUint64(uint64(e)))
|
||||||
Int(w, int64(e))
|
case *big.Int:
|
||||||
case int:
|
BigInt(w, e)
|
||||||
Int(w, int64(e))
|
case string:
|
||||||
case uint:
|
String(w, e)
|
||||||
BigInt(w, new(big.Int).SetUint64(uint64(e)))
|
case util.Uint160:
|
||||||
case *big.Int:
|
Bytes(w, e.BytesBE())
|
||||||
BigInt(w, e)
|
case util.Uint256:
|
||||||
case string:
|
Bytes(w, e.BytesBE())
|
||||||
String(w, e)
|
case *util.Uint160:
|
||||||
case util.Uint160:
|
if e == nil {
|
||||||
Bytes(w, e.BytesBE())
|
|
||||||
case util.Uint256:
|
|
||||||
Bytes(w, e.BytesBE())
|
|
||||||
case *util.Uint160:
|
|
||||||
if e == nil {
|
|
||||||
Opcodes(w, opcode.PUSHNULL)
|
|
||||||
} else {
|
|
||||||
Bytes(w, e.BytesBE())
|
|
||||||
}
|
|
||||||
case *util.Uint256:
|
|
||||||
if e == nil {
|
|
||||||
Opcodes(w, opcode.PUSHNULL)
|
|
||||||
} else {
|
|
||||||
Bytes(w, e.BytesBE())
|
|
||||||
}
|
|
||||||
case []byte:
|
|
||||||
Bytes(w, e)
|
|
||||||
case bool:
|
|
||||||
Bool(w, e)
|
|
||||||
case stackitem.Convertible:
|
|
||||||
Convertible(w, e)
|
|
||||||
case stackitem.Item:
|
|
||||||
StackItem(w, e)
|
|
||||||
default:
|
|
||||||
if es[i] != nil {
|
|
||||||
w.Err = fmt.Errorf("unsupported type: %T", e)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
Opcodes(w, opcode.PUSHNULL)
|
Opcodes(w, opcode.PUSHNULL)
|
||||||
|
} else {
|
||||||
|
Bytes(w, e.BytesBE())
|
||||||
}
|
}
|
||||||
|
case *util.Uint256:
|
||||||
|
if e == nil {
|
||||||
|
Opcodes(w, opcode.PUSHNULL)
|
||||||
|
} else {
|
||||||
|
Bytes(w, e.BytesBE())
|
||||||
|
}
|
||||||
|
case []byte:
|
||||||
|
Bytes(w, e)
|
||||||
|
case bool:
|
||||||
|
Bool(w, e)
|
||||||
|
case stackitem.Convertible:
|
||||||
|
Convertible(w, e)
|
||||||
|
case stackitem.Item:
|
||||||
|
StackItem(w, e)
|
||||||
|
default:
|
||||||
|
if something != nil {
|
||||||
|
w.Err = fmt.Errorf("unsupported type: %T", e)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
Opcodes(w, opcode.PUSHNULL)
|
||||||
}
|
}
|
||||||
Int(w, int64(len(es)))
|
|
||||||
Opcodes(w, opcode.PACK)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convertible converts provided stackitem.Convertible to the stackitem.Item and
|
// Convertible converts provided stackitem.Convertible to the stackitem.Item and
|
||||||
|
|
Loading…
Reference in a new issue