compiler: inline all expression with no side-effects, fix #1881

This has the drawback of traversing expression each time the argument is
used. However this is not the case in our syscall/native wrappers.
The old behaviour can be restored by explicit local assignment.
This commit is contained in:
Evgeniy Stratonikov 2021-05-25 16:02:28 +03:00
parent 3749f38720
commit 6b3afe9131
4 changed files with 58 additions and 30 deletions

View file

@ -247,8 +247,24 @@ func getBaseOpcode(t varType) (opcode.Opcode, opcode.Opcode) {
// emitLoadVar loads specified variable to the evaluation stack.
func (c *codegen) emitLoadVar(pkg string, name string) {
vi := c.getVarIndex(pkg, name)
if vi.tv.Value != nil {
c.emitLoadConst(vi.tv)
if vi.ctx != nil && c.typeAndValueOf(vi.ctx.expr).Value != nil {
c.emitLoadConst(c.typeAndValueOf(vi.ctx.expr))
return
} else if vi.ctx != nil {
var oldScope []map[string]varInfo
oldMap := c.importMap
c.importMap = vi.ctx.importMap
if c.scope != nil {
oldScope = c.scope.vars.locals
c.scope.vars.locals = vi.ctx.scope
}
ast.Walk(c, vi.ctx.expr)
if c.scope != nil {
c.scope.vars.locals = oldScope
}
c.importMap = oldMap
return
} else if vi.index == unspecifiedVarIndex {
emit.Opcodes(c.prog.BinWriter, opcode.PUSHNULL)