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:
parent
984aba3113
commit
2b73508561
1 changed files with 2 additions and 6 deletions
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue