From e754ca62dbe1826609a5a2623ec7d7df9dccac9b Mon Sep 17 00:00:00 2001 From: Evgeniy Stratonikov Date: Tue, 2 Mar 2021 14:34:23 +0300 Subject: [PATCH] compiler: do not emit CONVERT for syscall results When we encounter type assertion CONVERT is emitted. This isn't needed for SYSCALL (or opcode) results because value already has needed type. Problems can arise when result is converted to invalid type but `neogointernal` package shouldn't be used directly anyway. --- pkg/compiler/codegen.go | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/pkg/compiler/codegen.go b/pkg/compiler/codegen.go index 1baf52704..730256e9d 100644 --- a/pkg/compiler/codegen.go +++ b/pkg/compiler/codegen.go @@ -1226,6 +1226,10 @@ func (c *codegen) Visit(node ast.Node) ast.Visitor { // not the assertion type. case *ast.TypeAssertExpr: ast.Walk(c, n.X) + if c.isCallExprSyscall(n.X) { + return nil + } + goTyp := c.typeOf(n.Type) if canConvert(goTyp.String()) { typ := toNeoType(goTyp) @@ -1246,6 +1250,20 @@ func (c *codegen) packVarArgs(n *ast.CallExpr, typ *types.Signature) int { return varSize } +func (c *codegen) isCallExprSyscall(e ast.Expr) bool { + ce, ok := e.(*ast.CallExpr) + if !ok { + return false + } + sel, ok := ce.Fun.(*ast.SelectorExpr) + if !ok { + return false + } + name, _ := c.getFuncNameFromSelector(sel) + f, ok := c.funcs[name] + return ok && isSyscall(f) +} + // processDefers emits code for `defer` statements. // TRY-related opcodes handle exception as follows: // 1. CATCH block is executed only if exception has occurred.