Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 46cc7c0

Browse files
committed
Bring Tools/compiler almost up to date. Specifically:
- fix tab space issues (SF patch #101167 by Neil Schemenauer) - fix co_flags for classes to include CO_NEWLOCALS (SF patch #101145 by Neil) - fix for merger of UNPACK_LIST and UNPACK_TUPLE into UNPACK_SEQUENCE, (SF patch #101168 by, well, Neil :) - Adjust bytecode MAGIC to current bytecode. TODO: teach compile.py about list comprehensions.
1 parent 81f7eb6 commit 46cc7c0

6 files changed

Lines changed: 698 additions & 696 deletions

File tree

Lib/compiler/pyassem.py

Lines changed: 128 additions & 130 deletions
Original file line numberDiff line numberDiff line change
@@ -9,119 +9,119 @@
99

1010
class FlowGraph:
1111
def __init__(self):
12-
self.current = self.entry = Block()
13-
self.exit = Block("exit")
14-
self.blocks = misc.Set()
15-
self.blocks.add(self.entry)
16-
self.blocks.add(self.exit)
12+
self.current = self.entry = Block()
13+
self.exit = Block("exit")
14+
self.blocks = misc.Set()
15+
self.blocks.add(self.entry)
16+
self.blocks.add(self.exit)
1717

1818
def startBlock(self, block):
19-
self.current = block
19+
self.current = block
2020

2121
def nextBlock(self, block=None):
22-
if block is None:
23-
block = self.newBlock()
24-
# XXX think we need to specify when there is implicit transfer
25-
# from one block to the next
26-
#
27-
# I think this strategy works: each block has a child
28-
# designated as "next" which is returned as the last of the
29-
# children. because the nodes in a graph are emitted in
30-
# reverse post order, the "next" block will always be emitted
31-
# immediately after its parent.
32-
# Worry: maintaining this invariant could be tricky
33-
self.current.addNext(block)
34-
self.startBlock(block)
22+
if block is None:
23+
block = self.newBlock()
24+
# XXX think we need to specify when there is implicit transfer
25+
# from one block to the next
26+
#
27+
# I think this strategy works: each block has a child
28+
# designated as "next" which is returned as the last of the
29+
# children. because the nodes in a graph are emitted in
30+
# reverse post order, the "next" block will always be emitted
31+
# immediately after its parent.
32+
# Worry: maintaining this invariant could be tricky
33+
self.current.addNext(block)
34+
self.startBlock(block)
3535

3636
def newBlock(self):
37-
b = Block()
38-
self.blocks.add(b)
39-
return b
37+
b = Block()
38+
self.blocks.add(b)
39+
return b
4040

4141
def startExitBlock(self):
42-
self.startBlock(self.exit)
42+
self.startBlock(self.exit)
4343

4444
def emit(self, *inst):
45-
# XXX should jump instructions implicitly call nextBlock?
46-
if inst[0] == 'RETURN_VALUE':
47-
self.current.addOutEdge(self.exit)
48-
self.current.emit(inst)
45+
# XXX should jump instructions implicitly call nextBlock?
46+
if inst[0] == 'RETURN_VALUE':
47+
self.current.addOutEdge(self.exit)
48+
self.current.emit(inst)
4949

5050
def getBlocks(self):
51-
"""Return the blocks in reverse postorder
52-
53-
i.e. each node appears before all of its successors
54-
"""
55-
# XXX make sure every node that doesn't have an explicit next
56-
# is set so that next points to exit
57-
for b in self.blocks.elements():
58-
if b is self.exit:
59-
continue
60-
if not b.next:
61-
b.addNext(self.exit)
62-
order = dfs_postorder(self.entry, {})
63-
order.reverse()
64-
# hack alert
65-
if not self.exit in order:
66-
order.append(self.exit)
67-
return order
51+
"""Return the blocks in reverse postorder
52+
53+
i.e. each node appears before all of its successors
54+
"""
55+
# XXX make sure every node that doesn't have an explicit next
56+
# is set so that next points to exit
57+
for b in self.blocks.elements():
58+
if b is self.exit:
59+
continue
60+
if not b.next:
61+
b.addNext(self.exit)
62+
order = dfs_postorder(self.entry, {})
63+
order.reverse()
64+
# hack alert
65+
if not self.exit in order:
66+
order.append(self.exit)
67+
return order
6868

6969
def dfs_postorder(b, seen):
7070
"""Depth-first search of tree rooted at b, return in postorder"""
7171
order = []
7272
seen[b] = b
7373
for c in b.children():
74-
if seen.has_key(c):
75-
continue
76-
order = order + dfs_postorder(c, seen)
74+
if seen.has_key(c):
75+
continue
76+
order = order + dfs_postorder(c, seen)
7777
order.append(b)
7878
return order
7979

8080
class Block:
8181
_count = 0
8282

8383
def __init__(self, label=''):
84-
self.insts = []
85-
self.inEdges = misc.Set()
86-
self.outEdges = misc.Set()
87-
self.label = label
88-
self.bid = Block._count
89-
self.next = []
90-
Block._count = Block._count + 1
84+
self.insts = []
85+
self.inEdges = misc.Set()
86+
self.outEdges = misc.Set()
87+
self.label = label
88+
self.bid = Block._count
89+
self.next = []
90+
Block._count = Block._count + 1
9191

9292
def __repr__(self):
93-
if self.label:
94-
return "<block %s id=%d len=%d>" % (self.label, self.bid,
95-
len(self.insts))
96-
else:
97-
return "<block id=%d len=%d>" % (self.bid, len(self.insts))
93+
if self.label:
94+
return "<block %s id=%d len=%d>" % (self.label, self.bid,
95+
len(self.insts))
96+
else:
97+
return "<block id=%d len=%d>" % (self.bid, len(self.insts))
9898

9999
def __str__(self):
100-
insts = map(str, self.insts)
101-
return "<block %s %d:\n%s>" % (self.label, self.bid,
102-
string.join(insts, '\n'))
100+
insts = map(str, self.insts)
101+
return "<block %s %d:\n%s>" % (self.label, self.bid,
102+
string.join(insts, '\n'))
103103

104104
def emit(self, inst):
105-
op = inst[0]
106-
if op[:4] == 'JUMP':
107-
self.outEdges.add(inst[1])
108-
self.insts.append(inst)
105+
op = inst[0]
106+
if op[:4] == 'JUMP':
107+
self.outEdges.add(inst[1])
108+
self.insts.append(inst)
109109

110110
def getInstructions(self):
111-
return self.insts
111+
return self.insts
112112

113113
def addInEdge(self, block):
114-
self.inEdges.add(block)
114+
self.inEdges.add(block)
115115

116116
def addOutEdge(self, block):
117-
self.outEdges.add(block)
117+
self.outEdges.add(block)
118118

119119
def addNext(self, block):
120-
self.next.append(block)
121-
assert len(self.next) == 1, map(str, self.next)
120+
self.next.append(block)
121+
assert len(self.next) == 1, map(str, self.next)
122122

123123
def children(self):
124-
return self.outEdges.elements() + self.next
124+
return self.outEdges.elements() + self.next
125125

126126
# flags for code objects
127127
CO_OPTIMIZED = 0x0001
@@ -139,18 +139,18 @@ class PyFlowGraph(FlowGraph):
139139
super_init = FlowGraph.__init__
140140

141141
def __init__(self, name, filename, args=(), optimized=0):
142-
self.super_init()
143-
self.name = name
144-
self.filename = filename
145-
self.docstring = None
146-
self.args = args # XXX
147-
self.argcount = getArgCount(args)
148-
if optimized:
149-
self.flags = CO_OPTIMIZED | CO_NEWLOCALS
150-
else:
151-
self.flags = 0
152-
self.consts = []
153-
self.names = []
142+
self.super_init()
143+
self.name = name
144+
self.filename = filename
145+
self.docstring = None
146+
self.args = args # XXX
147+
self.argcount = getArgCount(args)
148+
if optimized:
149+
self.flags = CO_OPTIMIZED | CO_NEWLOCALS
150+
else:
151+
self.flags = 0
152+
self.consts = []
153+
self.names = []
154154
self.varnames = list(args) or []
155155
for i in range(len(self.varnames)):
156156
var = self.varnames[i]
@@ -163,13 +163,13 @@ def setDocstring(self, doc):
163163
self.consts.insert(0, doc)
164164

165165
def setFlag(self, flag):
166-
self.flags = self.flags | flag
167-
if flag == CO_VARARGS:
168-
self.argcount = self.argcount - 1
166+
self.flags = self.flags | flag
167+
if flag == CO_VARARGS:
168+
self.argcount = self.argcount - 1
169169

170170
def getCode(self):
171-
"""Get a Python code object"""
172-
if self.stage == RAW:
171+
"""Get a Python code object"""
172+
if self.stage == RAW:
173173
self.flattenGraph()
174174
if self.stage == FLAT:
175175
self.convertArgs()
@@ -198,38 +198,38 @@ def dump(self, io=None):
198198
sys.stdout = save
199199

200200
def flattenGraph(self):
201-
"""Arrange the blocks in order and resolve jumps"""
202-
assert self.stage == RAW
203-
self.insts = insts = []
204-
pc = 0
205-
begin = {}
206-
end = {}
207-
for b in self.getBlocks():
208-
begin[b] = pc
209-
for inst in b.getInstructions():
210-
insts.append(inst)
211-
if len(inst) == 1:
212-
pc = pc + 1
213-
else:
214-
# arg takes 2 bytes
215-
pc = pc + 3
216-
end[b] = pc
217-
pc = 0
218-
for i in range(len(insts)):
219-
inst = insts[i]
220-
if len(inst) == 1:
201+
"""Arrange the blocks in order and resolve jumps"""
202+
assert self.stage == RAW
203+
self.insts = insts = []
204+
pc = 0
205+
begin = {}
206+
end = {}
207+
for b in self.getBlocks():
208+
begin[b] = pc
209+
for inst in b.getInstructions():
210+
insts.append(inst)
211+
if len(inst) == 1:
212+
pc = pc + 1
213+
else:
214+
# arg takes 2 bytes
215+
pc = pc + 3
216+
end[b] = pc
217+
pc = 0
218+
for i in range(len(insts)):
219+
inst = insts[i]
220+
if len(inst) == 1:
221221
pc = pc + 1
222222
else:
223223
pc = pc + 3
224-
opname = inst[0]
225-
if self.hasjrel.has_elt(opname):
224+
opname = inst[0]
225+
if self.hasjrel.has_elt(opname):
226226
oparg = inst[1]
227227
offset = begin[oparg] - pc
228228
insts[i] = opname, offset
229229
elif self.hasjabs.has_elt(opname):
230230
insts[i] = opname, begin[inst[1]]
231-
self.stacksize = findDepth(self.insts)
232-
self.stage = FLAT
231+
self.stacksize = findDepth(self.insts)
232+
self.stage = FLAT
233233

234234
hasjrel = misc.Set()
235235
for i in dis.hasjrel:
@@ -292,7 +292,7 @@ def _convert_NAME(self, arg):
292292

293293
_cmp = list(dis.cmp_op)
294294
def _convert_COMPARE_OP(self, arg):
295-
return self._cmp.index(arg)
295+
return self._cmp.index(arg)
296296

297297
# similarly for other opcodes...
298298

@@ -314,12 +314,12 @@ def makeByteCode(self):
314314
if opname == "SET_LINENO":
315315
lnotab.nextLine(oparg)
316316
hi, lo = twobyte(oparg)
317-
try:
318-
lnotab.addCode(self.opnum[opname], lo, hi)
319-
except ValueError:
320-
print opname, oparg
321-
print self.opnum[opname], lo, hi
322-
raise
317+
try:
318+
lnotab.addCode(self.opnum[opname], lo, hi)
319+
except ValueError:
320+
print opname, oparg
321+
print self.opnum[opname], lo, hi
322+
raise
323323
self.stage = DONE
324324

325325
opnum = {}
@@ -354,10 +354,10 @@ def getConsts(self):
354354
elt = elt.getCode()
355355
l.append(elt)
356356
return tuple(l)
357-
357+
358358
def isJump(opname):
359359
if opname[:4] == 'JUMP':
360-
return 1
360+
return 1
361361

362362
class TupleArg:
363363
"""Helper for marking func defs with nested tuples in arglist"""
@@ -372,10 +372,10 @@ def getName(self):
372372
def getArgCount(args):
373373
argcount = len(args)
374374
if args:
375-
for arg in args:
376-
if isinstance(arg, TupleArg):
377-
numNames = len(misc.flatten(arg.names))
378-
argcount = argcount - numNames
375+
for arg in args:
376+
if isinstance(arg, TupleArg):
377+
numNames = len(misc.flatten(arg.names))
378+
argcount = argcount - numNames
379379
return argcount
380380

381381
def twobyte(val):
@@ -513,11 +513,9 @@ def findDepth(self, insts):
513513
]
514514

515515
# special cases:
516-
# UNPACK_TUPLE, UNPACK_LIST, BUILD_TUPLE,
516+
# UNPACK_SEQUENCE, BUILD_TUPLE,
517517
# BUILD_LIST, CALL_FUNCTION, MAKE_FUNCTION, BUILD_SLICE
518-
def UNPACK_TUPLE(self, count):
519-
return count
520-
def UNPACK_LIST(self, count):
518+
def UNPACK_SEQUENCE(self, count):
521519
return count
522520
def BUILD_TUPLE(self, count):
523521
return -count

0 commit comments

Comments
 (0)