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.
This commit is contained in:
Evgeniy Stratonikov 2021-03-02 14:34:23 +03:00
parent 5f4385d3fa
commit e754ca62db

View file

@ -1226,6 +1226,10 @@ func (c *codegen) Visit(node ast.Node) ast.Visitor {
// not the assertion type. // not the assertion type.
case *ast.TypeAssertExpr: case *ast.TypeAssertExpr:
ast.Walk(c, n.X) ast.Walk(c, n.X)
if c.isCallExprSyscall(n.X) {
return nil
}
goTyp := c.typeOf(n.Type) goTyp := c.typeOf(n.Type)
if canConvert(goTyp.String()) { if canConvert(goTyp.String()) {
typ := toNeoType(goTyp) typ := toNeoType(goTyp)
@ -1246,6 +1250,20 @@ func (c *codegen) packVarArgs(n *ast.CallExpr, typ *types.Signature) int {
return varSize 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. // processDefers emits code for `defer` statements.
// TRY-related opcodes handle exception as follows: // TRY-related opcodes handle exception as follows:
// 1. CATCH block is executed only if exception has occurred. // 1. CATCH block is executed only if exception has occurred.