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:
|
default:
|
||||||
emit.Opcode(c.prog.BinWriter, opcode.PUSHNULL)
|
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:
|
case *types.Struct:
|
||||||
num := t.NumFields()
|
num := t.NumFields()
|
||||||
emit.Int(c.prog.BinWriter, int64(num))
|
emit.Int(c.prog.BinWriter, int64(num))
|
||||||
|
@ -1183,9 +1176,22 @@ func (c *codegen) convertBuiltin(expr *ast.CallExpr) {
|
||||||
case "append":
|
case "append":
|
||||||
arg := expr.Args[0]
|
arg := expr.Args[0]
|
||||||
typ := c.typeInfo.Types[arg].Type
|
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) {
|
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)
|
emit.Opcode(c.prog.BinWriter, opcode.CAT)
|
||||||
} else {
|
} 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.OVER)
|
||||||
emit.Opcode(c.prog.BinWriter, opcode.SWAP)
|
emit.Opcode(c.prog.BinWriter, opcode.SWAP)
|
||||||
emit.Opcode(c.prog.BinWriter, opcode.APPEND)
|
emit.Opcode(c.prog.BinWriter, opcode.APPEND)
|
||||||
|
@ -1513,7 +1519,7 @@ func (c *codegen) writeJumps(b []byte) error {
|
||||||
opcode.JMPEQ, opcode.JMPNE,
|
opcode.JMPEQ, opcode.JMPNE,
|
||||||
opcode.JMPGT, opcode.JMPGE, opcode.JMPLE, opcode.JMPLT:
|
opcode.JMPGT, opcode.JMPGE, opcode.JMPLE, opcode.JMPLT:
|
||||||
// Noop, assumed to be correct already. If you're fixing #905,
|
// 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,
|
case opcode.JMPL, opcode.JMPIFL, opcode.JMPIFNOTL,
|
||||||
opcode.JMPEQL, opcode.JMPNEL,
|
opcode.JMPEQL, opcode.JMPNEL,
|
||||||
opcode.JMPGTL, opcode.JMPGEL, opcode.JMPLEL, opcode.JMPLTL,
|
opcode.JMPGTL, opcode.JMPGEL, opcode.JMPLEL, opcode.JMPLTL,
|
||||||
|
|
|
@ -243,6 +243,43 @@ var sliceTestCases = []testCase{
|
||||||
}`,
|
}`,
|
||||||
big.NewInt(42),
|
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) {
|
func TestSliceOperations(t *testing.T) {
|
||||||
|
|
Loading…
Reference in a new issue