diff --git a/go.sum b/go.sum index 375d84169..c2cbaae96 100644 --- a/go.sum +++ b/go.sum @@ -97,8 +97,8 @@ github.com/nspcc-dev/dbft v0.0.0-20191209120240-0d6b7568d9ae h1:T5V1QANlNMKun0EP github.com/nspcc-dev/dbft v0.0.0-20191209120240-0d6b7568d9ae/go.mod h1:3FjXOoHmA51EGfb5GS/HOv7VdmngNRTssSeQ729dvGY= github.com/nspcc-dev/dbft v0.0.0-20200117124306-478e5cfbf03a h1:ajvxgEe9qY4vvoSmrADqdDx7hReodKTnT2IXN++qZG8= github.com/nspcc-dev/dbft v0.0.0-20200117124306-478e5cfbf03a/go.mod h1:/YFK+XOxxg0Bfm6P92lY5eDSLYfp06XOdL8KAVgXjVk= -github.com/nspcc-dev/dbft v0.0.0-20200130105505-02c208d154bf h1:7QLeZnBQZ8eJeYksP7tnENG2ZEOZhHTJBC6LkFt4Ok8= -github.com/nspcc-dev/dbft v0.0.0-20200130105505-02c208d154bf/go.mod h1:O0qtn62prQSqizzoagHmuuKoz8QMkU3SzBoKdEvm3aQ= +github.com/nspcc-dev/dbft v0.0.0-20200203121303-549ecf2daaa1 h1:feHDSBix9oAVt5QzGABQczZo7dNWyeDKClLGwKvSJ/w= +github.com/nspcc-dev/dbft v0.0.0-20200203121303-549ecf2daaa1/go.mod h1:O0qtn62prQSqizzoagHmuuKoz8QMkU3SzBoKdEvm3aQ= github.com/nspcc-dev/neofs-crypto v0.2.0 h1:ftN+59WqxSWz/RCgXYOfhmltOOqU+udsNQSvN6wkFck= github.com/nspcc-dev/neofs-crypto v0.2.0/go.mod h1:F/96fUzPM3wR+UGsPi3faVNmFlA9KAEAUQR7dMxZmNA= github.com/nspcc-dev/neofs-crypto v0.2.3 h1:aca3X2aly92ENRbFK+kH6Hd+J9EQ4Eu6XMVoITSIKtc= diff --git a/pkg/compiler/codegen.go b/pkg/compiler/codegen.go index 1da9dcd78..8836cc342 100644 --- a/pkg/compiler/codegen.go +++ b/pkg/compiler/codegen.go @@ -540,17 +540,7 @@ func (c *codegen) Visit(node ast.Node) ast.Visitor { } // Do not swap for builtin functions. if !isBuiltin { - if numArgs == 2 { - emit.Opcode(c.prog.BinWriter, opcode.SWAP) - } else if numArgs == 3 { - emit.Int(c.prog.BinWriter, 2) - emit.Opcode(c.prog.BinWriter, opcode.XSWAP) - } else { - for i := 1; i < numArgs; i++ { - emit.Int(c.prog.BinWriter, int64(i)) - emit.Opcode(c.prog.BinWriter, opcode.ROLL) - } - } + c.emitReverse(numArgs) } // Check builtin first to avoid nil pointer on funcScope! @@ -680,6 +670,22 @@ func (c *codegen) Visit(node ast.Node) ast.Visitor { return c } +// emitReverse reverses top num items of the stack. +func (c *codegen) emitReverse(num int) { + switch num { + case 2: + emit.Opcode(c.prog.BinWriter, opcode.SWAP) + case 3: + emit.Int(c.prog.BinWriter, 2) + emit.Opcode(c.prog.BinWriter, opcode.XSWAP) + default: + for i := 1; i < num; i++ { + emit.Int(c.prog.BinWriter, int64(i)) + emit.Opcode(c.prog.BinWriter, opcode.ROLL) + } + } +} + func (c *codegen) getEqualityOpcode(expr ast.Expr) opcode.Opcode { t, ok := c.typeInfo.Types[expr].Type.Underlying().(*types.Basic) if ok && t.Info()&types.IsNumeric != 0 { @@ -780,6 +786,9 @@ func (c *codegen) convertBuiltin(expr *ast.CallExpr) { case "VerifySignature": emit.Opcode(c.prog.BinWriter, opcode.VERIFY) case "AppCall": + numArgs := len(expr.Args) - 1 + c.emitReverse(numArgs) + emit.Opcode(c.prog.BinWriter, opcode.APPCALL) buf := c.getByteArray(expr.Args[0]) if len(buf) != 20 { diff --git a/pkg/compiler/interop_test.go b/pkg/compiler/interop_test.go index 29831477f..2ebc71c29 100644 --- a/pkg/compiler/interop_test.go +++ b/pkg/compiler/interop_test.go @@ -2,7 +2,6 @@ package compiler_test import ( "fmt" - "math/big" "strings" "testing" @@ -55,10 +54,8 @@ func TestFromAddress(t *testing.T) { func TestAppCall(t *testing.T) { srcInner := ` package foo - func Main(args []interface{}) int { - a := args[0].(int) - b := args[1].(int) - return a + b + func Main(a []byte, b []byte) []byte { + return append(a, b...) } ` @@ -80,7 +77,7 @@ func TestAppCall(t *testing.T) { require.NoError(t, v.Run()) - assertResult(t, v, big.NewInt(42)) + assertResult(t, v, []byte{1, 2, 3, 4}) }) t.Run("missing script", func(t *testing.T) { @@ -106,11 +103,11 @@ func TestAppCall(t *testing.T) { package foo import "github.com/CityOfZion/neo-go/pkg/interop/engine" const scriptHash = ` + fmt.Sprintf("%#v", string(ih.BytesBE())) + ` - func Main() int { - x := 13 - y := 29 - result := engine.AppCall([]byte(scriptHash), []interface{}{x, y}) - return result.(int) + func Main() []byte { + x := []byte{1, 2} + y := []byte{3, 4} + result := engine.AppCall([]byte(scriptHash), x, y) + return result.([]byte) } ` @@ -119,7 +116,7 @@ func TestAppCall(t *testing.T) { require.NoError(t, v.Run()) - assertResult(t, v, big.NewInt(42)) + assertResult(t, v, []byte{1, 2, 3, 4}) }) } @@ -127,11 +124,11 @@ func getAppCallScript(h string) string { return ` package foo import "github.com/CityOfZion/neo-go/pkg/interop/engine" - func Main() int { - x := 13 - y := 29 - result := engine.AppCall(` + h + `, []interface{}{x, y}) - return result.(int) + func Main() []byte { + x := []byte{1, 2} + y := []byte{3, 4} + result := engine.AppCall(` + h + `, x, y) + return result.([]byte) } ` } diff --git a/pkg/interop/engine/engine.go b/pkg/interop/engine/engine.go index 3230d4a09..d094e3a43 100644 --- a/pkg/interop/engine/engine.go +++ b/pkg/interop/engine/engine.go @@ -29,6 +29,6 @@ func GetEntryScriptHash() []byte { } // AppCall executes script with specified hash using provided arguments. -func AppCall(scriptHash []byte, args []interface{}) interface{} { +func AppCall(scriptHash []byte, args ...interface{}) interface{} { return nil }