forked from TrueCloudLab/neoneo-go
compiler: slices must default to nil
This commit is contained in:
parent
eee8ac1655
commit
76925fe3e0
2 changed files with 51 additions and 8 deletions
|
@ -231,13 +231,6 @@ func (c *codegen) emitDefault(t types.Type) {
|
|||
default:
|
||||
emit.Opcode(c.prog.BinWriter, opcode.PUSHNULL)
|
||||
}
|
||||
case *types.Slice:
|
||||
if isCompoundSlice(t) {
|
||||
emit.Opcode(c.prog.BinWriter, opcode.NEWARRAY0)
|
||||
} else {
|
||||
emit.Int(c.prog.BinWriter, 0)
|
||||
emit.Opcode(c.prog.BinWriter, opcode.NEWBUFFER)
|
||||
}
|
||||
case *types.Struct:
|
||||
num := t.NumFields()
|
||||
emit.Int(c.prog.BinWriter, int64(num))
|
||||
|
@ -1183,9 +1176,22 @@ func (c *codegen) convertBuiltin(expr *ast.CallExpr) {
|
|||
case "append":
|
||||
arg := expr.Args[0]
|
||||
typ := c.typeInfo.Types[arg].Type
|
||||
emit.Opcode(c.prog.BinWriter, opcode.OVER)
|
||||
emit.Opcode(c.prog.BinWriter, opcode.ISNULL)
|
||||
emit.Instruction(c.prog.BinWriter, opcode.JMPIFNOT, []byte{2 + 4})
|
||||
if isByteSlice(typ) {
|
||||
emit.Opcode(c.prog.BinWriter, opcode.NIP)
|
||||
emit.Opcode(c.prog.BinWriter, opcode.PUSH0)
|
||||
emit.Opcode(c.prog.BinWriter, opcode.NEWBUFFER)
|
||||
emit.Opcode(c.prog.BinWriter, opcode.SWAP)
|
||||
// Jump target.
|
||||
emit.Opcode(c.prog.BinWriter, opcode.CAT)
|
||||
} else {
|
||||
emit.Opcode(c.prog.BinWriter, opcode.NIP)
|
||||
emit.Opcode(c.prog.BinWriter, opcode.NEWARRAY0)
|
||||
emit.Opcode(c.prog.BinWriter, opcode.SWAP)
|
||||
emit.Opcode(c.prog.BinWriter, opcode.NOP)
|
||||
// Jump target.
|
||||
emit.Opcode(c.prog.BinWriter, opcode.OVER)
|
||||
emit.Opcode(c.prog.BinWriter, opcode.SWAP)
|
||||
emit.Opcode(c.prog.BinWriter, opcode.APPEND)
|
||||
|
@ -1513,7 +1519,7 @@ func (c *codegen) writeJumps(b []byte) error {
|
|||
opcode.JMPEQ, opcode.JMPNE,
|
||||
opcode.JMPGT, opcode.JMPGE, opcode.JMPLE, opcode.JMPLT:
|
||||
// Noop, assumed to be correct already. If you're fixing #905,
|
||||
// make sure not to break "len" handling above.
|
||||
// make sure not to break "len" and "append" handling above.
|
||||
case opcode.JMPL, opcode.JMPIFL, opcode.JMPIFNOTL,
|
||||
opcode.JMPEQL, opcode.JMPNEL,
|
||||
opcode.JMPGTL, opcode.JMPGEL, opcode.JMPLEL, opcode.JMPLTL,
|
||||
|
|
|
@ -243,6 +243,43 @@ var sliceTestCases = []testCase{
|
|||
}`,
|
||||
big.NewInt(42),
|
||||
},
|
||||
{
|
||||
"defaults to nil for byte slice",
|
||||
`
|
||||
package foo
|
||||
func Main() int {
|
||||
var a []byte
|
||||
if a != nil { return 1}
|
||||
return 2
|
||||
}
|
||||
`,
|
||||
big.NewInt(2),
|
||||
},
|
||||
{
|
||||
"defaults to nil for int slice",
|
||||
`
|
||||
package foo
|
||||
func Main() int {
|
||||
var a []int
|
||||
if a != nil { return 1}
|
||||
return 2
|
||||
}
|
||||
`,
|
||||
big.NewInt(2),
|
||||
},
|
||||
{
|
||||
"defaults to nil for struct slice",
|
||||
`
|
||||
package foo
|
||||
type pair struct { a, b int }
|
||||
func Main() int {
|
||||
var a []pair
|
||||
if a != nil { return 1}
|
||||
return 2
|
||||
}
|
||||
`,
|
||||
big.NewInt(2),
|
||||
},
|
||||
}
|
||||
|
||||
func TestSliceOperations(t *testing.T) {
|
||||
|
|
Loading…
Reference in a new issue