forked from TrueCloudLab/neoneo-go
compiler: emit Buffer for byte slices
All byte slices are mutable so buffer is a right stack item.
This commit is contained in:
parent
b4f1142149
commit
3a4ed7dfe8
3 changed files with 32 additions and 2 deletions
|
@ -716,6 +716,7 @@ func (c *codegen) Visit(node ast.Node) ast.Visitor {
|
|||
// For now we will assume that there are only byte slice conversions.
|
||||
// E.g. []byte("foobar") or []byte(scriptHash).
|
||||
ast.Walk(c, n.Args[0])
|
||||
c.emitConvert(vm.BufferT)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -1096,7 +1097,7 @@ func (c *codegen) convertBuiltin(expr *ast.CallExpr) {
|
|||
case "ToBool":
|
||||
typ = vm.BooleanT
|
||||
}
|
||||
emit.Instruction(c.prog.BinWriter, opcode.CONVERT, []byte{byte(typ)})
|
||||
c.emitConvert(typ)
|
||||
case "SHA256":
|
||||
emit.Syscall(c.prog.BinWriter, "Neo.Crypto.SHA256")
|
||||
case "AppCall":
|
||||
|
@ -1121,6 +1122,7 @@ func (c *codegen) convertBuiltin(expr *ast.CallExpr) {
|
|||
}
|
||||
bytes := uint160.BytesBE()
|
||||
emit.Bytes(c.prog.BinWriter, bytes)
|
||||
c.emitConvert(vm.BufferT)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1146,6 +1148,11 @@ func transformArgs(fun ast.Expr, args []ast.Expr) []ast.Expr {
|
|||
return args
|
||||
}
|
||||
|
||||
// emitConvert converts top stack item to the specified type.
|
||||
func (c *codegen) emitConvert(typ vm.StackItemType) {
|
||||
emit.Instruction(c.prog.BinWriter, opcode.CONVERT, []byte{byte(typ)})
|
||||
}
|
||||
|
||||
func (c *codegen) convertByteArray(lit *ast.CompositeLit) {
|
||||
buf := make([]byte, len(lit.Elts))
|
||||
for i := 0; i < len(lit.Elts); i++ {
|
||||
|
@ -1154,6 +1161,7 @@ func (c *codegen) convertByteArray(lit *ast.CompositeLit) {
|
|||
buf[i] = byte(val)
|
||||
}
|
||||
emit.Bytes(c.prog.BinWriter, buf)
|
||||
c.emitConvert(vm.BufferT)
|
||||
}
|
||||
|
||||
func (c *codegen) convertMap(lit *ast.CompositeLit) {
|
||||
|
|
|
@ -38,7 +38,8 @@ func TestConvert(t *testing.T) {
|
|||
{"bool", "12", true},
|
||||
{"bool", "0", false},
|
||||
{"bool", "[]byte{0, 1, 0}", true},
|
||||
{"bool", "[]byte{0}", false},
|
||||
{"bool", "[]byte{0}", true},
|
||||
{"bool", `""`, false},
|
||||
{"int64", "true", big.NewInt(1)},
|
||||
{"int64", "false", big.NewInt(0)},
|
||||
{"int64", "12", big.NewInt(12)},
|
||||
|
|
|
@ -180,6 +180,27 @@ var sliceTestCases = []testCase{
|
|||
vm.NewByteArrayItem([]byte("b")),
|
||||
},
|
||||
},
|
||||
{
|
||||
"byte-slice assignment",
|
||||
`package foo
|
||||
func Main() []byte {
|
||||
a := []byte{0, 1, 2}
|
||||
a[1] = 42
|
||||
return a
|
||||
}`,
|
||||
[]byte{0, 42, 2},
|
||||
},
|
||||
{
|
||||
"byte-slice assignment after string conversion",
|
||||
`package foo
|
||||
func Main() []byte {
|
||||
a := "abc"
|
||||
b := []byte(a)
|
||||
b[1] = 42
|
||||
return []byte(a)
|
||||
}`,
|
||||
[]byte{0x61, 0x62, 0x63},
|
||||
},
|
||||
}
|
||||
|
||||
func TestSliceOperations(t *testing.T) {
|
||||
|
|
Loading…
Reference in a new issue