compiler: do not load map key twice in for-range loop

This commit is contained in:
Evgenii Stratonikov 2020-06-19 17:41:06 +03:00
parent 1847c28b42
commit e54149d547

View file

@ -924,16 +924,24 @@ func (c *codegen) Visit(node ast.Node) ast.Visitor {
emit.Opcode(c.prog.BinWriter, opcode.OVER) emit.Opcode(c.prog.BinWriter, opcode.OVER)
emit.Jmp(c.prog.BinWriter, opcode.JMPLEL, end) emit.Jmp(c.prog.BinWriter, opcode.JMPLEL, end)
var keyLoaded bool
needValue := n.Value != nil && n.Value.(*ast.Ident).Name != "_"
if n.Key != nil && n.Key.(*ast.Ident).Name != "_" { if n.Key != nil && n.Key.(*ast.Ident).Name != "_" {
if isMap { if isMap {
c.rangeLoadKey() c.rangeLoadKey()
if needValue {
emit.Opcode(c.prog.BinWriter, opcode.DUP)
keyLoaded = true
}
} else { } else {
emit.Opcode(c.prog.BinWriter, opcode.DUP) emit.Opcode(c.prog.BinWriter, opcode.DUP)
} }
c.emitStoreVar(n.Key.(*ast.Ident).Name) c.emitStoreVar(n.Key.(*ast.Ident).Name)
} }
if n.Value != nil && n.Value.(*ast.Ident).Name != "_" { if needValue {
c.rangeLoadKey() if !isMap || !keyLoaded {
c.rangeLoadKey()
}
if isMap { if isMap {
// we have loaded only key from key array, now load value // we have loaded only key from key array, now load value
emit.Int(c.prog.BinWriter, 4) emit.Int(c.prog.BinWriter, 4)