Permalink
Browse files

pyassem: Split up the 2 passes of FlattenGraph, to clarify structure.

Now we can see the block_offsets variable in the top-level Compile().
We also noticed that 'end = {}' was unused!

Also:
- Misc style changes and reformatting.
  • Loading branch information...
Andy Chu
Andy Chu committed Mar 20, 2018
1 parent fed6d7e commit 11812e8ddcd507d191eec4070252074793f3e802
Showing with 31 additions and 23 deletions.
  1. +15 −11 opy/compiler2/pyassem.py
  2. +13 −9 opy/compiler2/skeleton.py
  3. +3 −3 opy/opy_main.py
View
@@ -80,34 +80,38 @@ def find_next():
def FlattenGraph(blocks):
insts = []
pc = 0
begin = {}
end = {}
offsets = {} # block -> bytecode offset
for b in blocks:
begin[b] = pc
offsets[b] = pc
for inst in b.getInstructions():
insts.append(inst)
if len(inst) == 1:
pc += 1
elif inst[0] != "SET_LINENO":
# arg takes 2 bytes
elif inst[0] != "SET_LINENO": # arg takes 2 bytes
pc += 3
end[b] = pc
return insts, offsets
def PatchJumps(insts, offsets):
pc = 0
for i, inst in enumerate(insts):
if len(inst) == 1:
pc += 1
elif inst[0] != "SET_LINENO":
pc += 3
opname = inst[0]
# Compute jump locations
if opname in HAS_JREL:
oparg = inst[1]
offset = begin[oparg] - pc
insts[i] = opname, offset
block_arg = inst[1]
insts[i] = (opname, offsets[block_arg] - pc)
elif opname in HAS_JABS:
insts[i] = opname, begin[inst[1]]
return insts
block_arg = inst[1]
insts[i] = (opname, offsets[block_arg])
gBlockCounter = 0
View
@@ -46,7 +46,7 @@ def py2st(unused_gr, raw_node):
def MakeCodeObject(frame, graph):
"""Order blocks, encode instructions, and create types.CodeType().
Called by RunCompiler below, and also recursively by ArgEncoder.
Called by Compile below, and also recursively by ArgEncoder.
"""
# Compute stack depth per basic block.
depths = {}
@@ -60,7 +60,8 @@ def MakeCodeObject(frame, graph):
# Order blocks so jump offsets can be encoded.
blocks = pyassem.OrderBlocks(graph.entry, graph.exit)
insts = pyassem.FlattenGraph(blocks)
insts, block_offsets = pyassem.FlattenGraph(blocks)
pyassem.PatchJumps(insts, block_offsets)
cellvars = pyassem.ReorderCellVars(frame)
consts = [frame.docstring]
@@ -91,11 +92,17 @@ def MakeCodeObject(frame, graph):
tuple(cellvars))
def RunCompiler(f, filename, gr, start_symbol, mode):
def Compile(f, filename, gr, start_symbol, mode):
"""Run the full compiler pipeline.
TODO: Expose this as a library?
Args:
f: file handle with input source code
filename: filename for debugging
gr: Grammar
start_symbol: name of the grammar start symbol
mode: 'exec', 'eval', or 'single', like Python's builtin compile()
"""
tokens = tokenize.generate_tokens(f.readline)
p = parse.Parser(gr, convert=py2st)
@@ -137,13 +144,10 @@ def RunCompiler(f, filename, gr, start_symbol, mode):
gen = pycodegen.TopLevelCodeGenerator(ctx, frame, graph)
else:
raise ValueError("compile() 3rd arg must be 'exec' or "
"'eval' or 'single'")
raise AssertionError('Invalid mode %r' % mode)
# NOTE: There is no Start() or FindLocals() at the top level.
gen.Dispatch(as_tree) # mutates graph
gen.Finish()
# NOTE: This method has a pretty long pipeline too.
co = MakeCodeObject(frame, graph)
return co
return MakeCodeObject(frame, graph)
View
@@ -218,7 +218,7 @@ def OpyCommandMain(argv):
out_path = argv[2]
with open(py_path) as f:
co = skeleton.RunCompiler(f, py_path, gr, 'file_input', 'exec')
co = skeleton.Compile(f, py_path, gr, 'file_input', 'exec')
log("Compiled to %d bytes of bytecode", len(co.co_code))
@@ -231,7 +231,7 @@ def OpyCommandMain(argv):
elif action == 'eval': # Like compile, but parses to a code object and prints it
py_expr = argv[1]
f = cStringIO.StringIO(py_expr)
co = skeleton.RunCompiler(f, '<eval input>', gr, 'eval_input', 'eval')
co = skeleton.Compile(f, '<eval input>', gr, 'eval_input', 'eval')
v = dis_tool.Visitor()
v.show_code(co)
@@ -245,7 +245,7 @@ def OpyCommandMain(argv):
f = cStringIO.StringIO(py_expr)
# TODO: change this to 'single input'? Why doesn't this work?
co = skeleton.RunCompiler(f, '<REPL input>', gr, 'eval_input', 'eval')
co = skeleton.Compile(f, '<REPL input>', gr, 'eval_input', 'eval')
v = dis_tool.Visitor()
v.show_code(co)

0 comments on commit 11812e8

Please sign in to comment.