Skip to content

Commit bfceeac

Browse files
committed
2.7 can have two JUMP_BACKs at the end of a while loop
Fixes rocky#215
1 parent 47448e7 commit bfceeac

File tree

3 files changed

+35
-0
lines changed

3 files changed

+35
-0
lines changed
528 Bytes
Binary file not shown.
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# Bug in Python 2.7. Bug is bytecode for while loop having
2+
# two consecutive JUMP_BACKS at the end of 'elif' and 'while'
3+
# to the same place
4+
def PreprocessConditionalStatement(self, IfList, ReplacedLine):
5+
while self:
6+
if self.__Token:
7+
x = 1
8+
elif not IfList:
9+
if self <= 2:
10+
continue
11+
RegionSizeGuid = 3
12+
if not RegionSizeGuid:
13+
RegionLayoutLine = 5
14+
continue
15+
RegionLayoutLine = self.CurrentLineNumber
16+
return 1

uncompyle6/parsers/parse27.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,13 @@ def p_stmt27(self, args):
156156
157157
while1stmt ::= SETUP_LOOP returns bp_come_from
158158
while1stmt ::= SETUP_LOOP l_stmts_opt JUMP_BACK POP_BLOCK COME_FROM
159+
159160
whilestmt ::= SETUP_LOOP testexpr l_stmts_opt JUMP_BACK POP_BLOCK _come_froms
161+
162+
# Should this be JUMP_BACK+ ?
163+
# JUMP_BACK should all be to the same location
164+
whilestmt ::= SETUP_LOOP testexpr l_stmts_opt JUMP_BACK JUMP_BACK POP_BLOCK _come_froms
165+
160166
while1elsestmt ::= SETUP_LOOP l_stmts JUMP_BACK POP_BLOCK
161167
else_suitel COME_FROM
162168
whileelsestmt ::= SETUP_LOOP testexpr l_stmts_opt JUMP_BACK POP_BLOCK
@@ -211,14 +217,17 @@ def customize_grammar_rules(self, tokens, customize):
211217
self.check_reduce['list_if_not'] = 'AST'
212218
self.check_reduce['list_if'] = 'AST'
213219
self.check_reduce['conditional_true'] = 'AST'
220+
self.check_reduce['whilestmt'] = 'tokens'
214221
return
215222

216223
def reduce_is_invalid(self, rule, ast, tokens, first, last):
217224
invalid = super(Python27Parser,
218225
self).reduce_is_invalid(rule, ast,
219226
tokens, first, last)
227+
220228
if invalid:
221229
return invalid
230+
222231
if rule == ('and', ('expr', 'jmp_false', 'expr', '\\e_come_from_opt')):
223232
# Test that jmp_false jumps to the end of "and"
224233
# or that it jumps to the same place as the end of "and"
@@ -249,6 +258,16 @@ def reduce_is_invalid(self, rule, ast, tokens, first, last):
249258
jmp_target = jmp_true.offset + jmp_true.attr + 3
250259
return not (jmp_target == tokens[last].offset or
251260
tokens[last].pattr == jmp_true.pattr)
261+
262+
elif (rule[0] == 'whilestmt' and
263+
rule[1][0:-2] ==
264+
('SETUP_LOOP', 'testexpr', 'l_stmts_opt',
265+
'JUMP_BACK', 'JUMP_BACK')):
266+
# Make sure that the jump backs all go to the same place
267+
i = last-1
268+
while (tokens[i] != 'JUMP_BACK'):
269+
i -= 1
270+
return tokens[i].attr != tokens[i-1].attr
252271
# elif rule[0] == ('conditional_true'):
253272
# # FIXME: the below is a hack: we check expr for
254273
# # nodes that could have possibly been a been a Boolean.

0 commit comments

Comments
 (0)