Merge pull request #651 from nspcc-dev/fix/appcall
compiler: refactor AppCall
This commit is contained in:
commit
f148798291
4 changed files with 37 additions and 31 deletions
4
go.sum
4
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=
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
`
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue