diff --git a/pkg/compiler/codegen.go b/pkg/compiler/codegen.go index c7d888a42..f51de0942 100644 --- a/pkg/compiler/codegen.go +++ b/pkg/compiler/codegen.go @@ -1176,25 +1176,29 @@ 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) + c.emitReverse(len(expr.Args)) + emit.Opcode(c.prog.BinWriter, opcode.DUP) emit.Opcode(c.prog.BinWriter, opcode.ISNULL) - emit.Instruction(c.prog.BinWriter, opcode.JMPIFNOT, []byte{2 + 4}) + emit.Instruction(c.prog.BinWriter, opcode.JMPIFNOT, []byte{2 + 3}) if isByteSlice(typ) { - emit.Opcode(c.prog.BinWriter, opcode.NIP) + emit.Opcode(c.prog.BinWriter, opcode.DROP) 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.DROP) 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) + } + // Jump target. + for range expr.Args[1:] { + if isByteSlice(typ) { + emit.Opcode(c.prog.BinWriter, opcode.SWAP) + emit.Opcode(c.prog.BinWriter, opcode.CAT) + } else { + emit.Opcode(c.prog.BinWriter, opcode.DUP) + emit.Opcode(c.prog.BinWriter, opcode.ROT) + emit.Opcode(c.prog.BinWriter, opcode.APPEND) + } } case "panic": arg := expr.Args[0] diff --git a/pkg/compiler/slice_test.go b/pkg/compiler/slice_test.go index f386beddf..20223fb04 100644 --- a/pkg/compiler/slice_test.go +++ b/pkg/compiler/slice_test.go @@ -151,6 +151,33 @@ var sliceTestCases = []testCase{ }`, []byte{1, 2}, }, + { + "append multiple bytes to a slice", + `package foo + func Main() []byte { + var a []byte + a = append(a, 1, 2) + return a + }`, + []byte{1, 2}, + }, + { + "append multiple ints to a slice", + `package foo + func Main() []int { + var a []int + a = append(a, 1, 2, 3) + a = append(a, 4, 5) + return a + }`, + []stackitem.Item{ + stackitem.NewBigInteger(big.NewInt(1)), + stackitem.NewBigInteger(big.NewInt(2)), + stackitem.NewBigInteger(big.NewInt(3)), + stackitem.NewBigInteger(big.NewInt(4)), + stackitem.NewBigInteger(big.NewInt(5)), + }, + }, { "declare compound slice", `package foo