compiler: emit short jumps while short-circuiting

Unless there is some `ast.Walk` between current instruction and jump
target, we can calculate the offset precisely.
This commit is contained in:
Evgenii Stratonikov 2020-08-19 13:51:30 +03:00
parent 984aba3113
commit 2b73508561

View file

@ -691,25 +691,21 @@ func (c *codegen) Visit(node ast.Node) ast.Visitor {
case *ast.BinaryExpr: case *ast.BinaryExpr:
switch n.Op { switch n.Op {
case token.LAND: case token.LAND:
next := c.newLabel()
end := c.newLabel() end := c.newLabel()
ast.Walk(c, n.X) ast.Walk(c, n.X)
emit.Jmp(c.prog.BinWriter, opcode.JMPIFL, next) emit.Instruction(c.prog.BinWriter, opcode.JMPIF, []byte{2 + 1 + 5})
emit.Opcode(c.prog.BinWriter, opcode.PUSHF) emit.Opcode(c.prog.BinWriter, opcode.PUSHF)
emit.Jmp(c.prog.BinWriter, opcode.JMPL, end) emit.Jmp(c.prog.BinWriter, opcode.JMPL, end)
c.setLabel(next)
ast.Walk(c, n.Y) ast.Walk(c, n.Y)
c.setLabel(end) c.setLabel(end)
return nil return nil
case token.LOR: case token.LOR:
next := c.newLabel()
end := c.newLabel() end := c.newLabel()
ast.Walk(c, n.X) ast.Walk(c, n.X)
emit.Jmp(c.prog.BinWriter, opcode.JMPIFNOTL, next) emit.Instruction(c.prog.BinWriter, opcode.JMPIFNOT, []byte{2 + 1 + 5})
emit.Opcode(c.prog.BinWriter, opcode.PUSHT) emit.Opcode(c.prog.BinWriter, opcode.PUSHT)
emit.Jmp(c.prog.BinWriter, opcode.JMPL, end) emit.Jmp(c.prog.BinWriter, opcode.JMPL, end)
c.setLabel(next)
ast.Walk(c, n.Y) ast.Walk(c, n.Y)
c.setLabel(end) c.setLabel(end)
return nil return nil