MCPcopy Create free account
hub / github.com/rocky/python-uncompyle6 / while1stmt

Function while1stmt

uncompyle6/parsers/reducecheck/while1stmt.py:4–50  ·  view source on GitHub ↗
(self, lhs, n, rule, ast, tokens, first, last)

Source from the content-addressed store, hash-verified

2
3
4def while1stmt(self, lhs, n, rule, ast, tokens, first, last):
5
6 # If there is a fall through to the COME_FROM_LOOP, then this is
7 # not a while 1. So the instruction before should either be a
8 # JUMP_BACK or the instruction before should not be the target of a
9 # jump. (Well that last clause i not quite right; that target could be
10 # from dead code. Ugh. We need a more uniform control flow analysis.)
11 if last == n or tokens[last - 1] == "COME_FROM_LOOP":
12 cfl = last - 1
13 else:
14 cfl = last
15 assert tokens[cfl] == "COME_FROM_LOOP"
16
17 for loop_end in range(cfl - 1, first, -1):
18 if tokens[loop_end] != "POP_BLOCK":
19 break
20 if tokens[loop_end].kind not in ("JUMP_BACK", "RETURN_VALUE", "RAISE_VARARGS_1"):
21 if not tokens[loop_end].kind.startswith("COME_FROM"):
22 return True
23 # Check that the SETUP_LOOP jumps to the offset after the
24 # COME_FROM_LOOP
25 if 0 <= last and tokens[last] in ("COME_FROM_LOOP", "JUMP_BACK"):
26 # jump_back should be right before COME_FROM_LOOP?
27 last += 1
28 if last == n:
29 last -= 1
30 offset = tokens[last].off2int()
31 assert tokens[first] == "SETUP_LOOP"
32
33 # Scan for jumps out of the loop. Skip the initial "SETUP_LOOP" instruction.
34 # If there is a JUMP_BACK at the end, jumping to that is not breaking out
35 # of the loop. However after that, any "POP_BLOCK"s or "COME_FROM_LOOP"s
36 # are considered to break out of the loop.
37 if tokens[loop_end] == "JUMP_BACK":
38 loop_end += 1
39 loop_end_offset = tokens[loop_end].off2int(prefer_last=False)
40 for t in range(first + 1, loop_end):
41 token = tokens[t]
42 # token could be a pseudo-op like "LOAD_STR", which is not in
43 # token.opc. We will replace that with LOAD_CONST as an
44 # example of an instruction that is not in token.opc.JUMP_OPS
45 if token.opc.opmap.get(token.kind, "LOAD_CONST") in token.opc.JUMP_OPS:
46 if token.attr >= loop_end_offset:
47 return True
48
49 # SETUP_LOOP location must jump either to the last token or the token after the last one
50 return tokens[first].attr not in (offset, offset + 2)

Callers 1

reduce_is_invalidMethod · 0.90

Calls 2

off2intMethod · 0.80
getMethod · 0.45

Tested by

no test coverage detected