Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
def get_inst(self, offset):
# Instructions can get moved as a result of EXTENDED_ARGS removal.
# So if "offset" is not in self.offset2inst_index, then
# we assume that it was an instruction moved back.
# We check that assumption though by looking at
# self.code's opcode.
if offset not in self.offset2inst_index:
offset -= instruction_size(self.opc.EXTENDED_ARG, self.opc)
assert self.code[offset] == self.opc.EXTENDED_ARG
return self.insts[self.offset2inst_index[offset]]
def op_range(self, start, end):
"""
Iterate through positions of opcodes, skipping
arguments.
"""
while start < end:
yield start
start += instruction_size(self.code[start], self.opc)
prelim = self.inst_matches(start, end, self.statement_opcodes)
# Initialize final container with statements with
# preliminary data
stmts = self.stmts = set(prelim)
# Same for opcode sequences
pass_stmts = set()
for sequence in self.statement_opcode_sequences:
for i in self.op_range(start, end - (len(sequence) + 1)):
match = True
for elem in sequence:
if elem != code[i]:
match = False
break
i += instruction_size(code[i], self.opc)
if match is True:
i = self.prev_op[i]
stmts.add(i)
pass_stmts.add(i)
# Initialize statement list with the full data we've gathered so far
if pass_stmts:
stmt_offset_list = list(stmts)
stmt_offset_list.sort()
else:
stmt_offset_list = prelim
# 'List-map' which contains offset of start of
# next statement, when op offset is passed as index
self.next_stmt = slist = []
last_stmt_offset = -1
if self.is_pypy and code[jump_prev] == self.opc.COMPARE_OP:
if self.opc.cmp_op[code[jump_prev + 1]] == "exception-match":
return
if self.version >= 3.5:
# Python 3.5 may remove as dead code a JUMP
# instruction after a RETURN_VALUE. So we check
# based on seeing SETUP_EXCEPT various places.
if self.version < 3.6 and code[rtarget] == self.opc.SETUP_EXCEPT:
return
# Check that next instruction after pops and jump is
# not from SETUP_EXCEPT
next_op = rtarget
if code[next_op] == self.opc.POP_BLOCK:
next_op += instruction_size(self.code[next_op], self.opc)
if code[next_op] == self.opc.JUMP_ABSOLUTE:
next_op += instruction_size(self.code[next_op], self.opc)
if next_op in targets:
for try_op in targets[next_op]:
come_from_op = code[try_op]
if (
self.version < 3.8
and come_from_op == self.opc.SETUP_EXCEPT
):
return
pass
pass
if self.version >= 3.4:
self.fixed_jumps[offset] = rtarget
if code[pre_rtarget] == self.opc.RETURN_VALUE:
# If we are at some sort of POP_JUMP_IF and the instruction before was
self.ignore_if.add(test_op_offset)
if test_target > (jump_back_offset+3):
jump_back_offset = test_target
self.not_continue.add(jump_back_offset)
self.loops.append(setup_target)
self.structs.append({'type': loop_type + '-loop',
'start': setup_target,
'end': jump_back_offset})
if jump_back_offset+3 != loop_end_offset:
self.structs.append({'type': loop_type + '-else',
'start': jump_back_offset+3,
'end': loop_end_offset})
elif op == self.opc.SETUP_EXCEPT:
start = offset + instruction_size(op, self.opc)
target = self.get_target(offset, op)
end_offset = self.restrict_to_parent(target, parent)
if target != end_offset:
self.fixed_jumps[offset] = end_offset
# print target, end, parent
# Add the try block
self.structs.append({'type': 'try',
'start': start-3,
'end': end_offset-4})
# Now isolate the except and else blocks
end_else = start_else = self.get_target(self.prev[end_offset])
end_finally_offset = end_offset
setup_except_nest = 0
while end_finally_offset < len(self.code):
prelim = self.inst_matches(start, end, self.statement_opcodes)
# Initialize final container with statements with
# preliminary data
stmts = self.stmts = set(prelim)
# Same for opcode sequences
pass_stmts = set()
for sequence in self.statement_opcode_sequences:
for i in self.op_range(start, end - (len(sequence) + 1)):
match = True
for elem in sequence:
if elem != code[i]:
match = False
break
i += instruction_size(code[i], self.opc)
if match is True:
i = self.prev_op[i]
stmts.add(i)
pass_stmts.add(i)
# Initialize statement list with the full data we've gathered so far
if pass_stmts:
stmt_offset_list = list(stmts)
stmt_offset_list.sort()
else:
stmt_offset_list = prelim
# 'List-map' which contains offset of start of
# next statement, when op offset is passed as index
self.next_stmt = slist = []
last_stmt_offset = -1
# except block return
jump_prev = prev_op[offset]
if self.is_pypy and code[jump_prev] == self.opc.COMPARE_OP:
if self.opc.cmp_op[code[jump_prev + 1]] == "exception-match":
return
if self.version >= 3.5:
# Python 3.5 may remove as dead code a JUMP
# instruction after a RETURN_VALUE. So we check
# based on seeing SETUP_EXCEPT various places.
if self.version < 3.6 and code[rtarget] == self.opc.SETUP_EXCEPT:
return
# Check that next instruction after pops and jump is
# not from SETUP_EXCEPT
next_op = rtarget
if code[next_op] == self.opc.POP_BLOCK:
next_op += instruction_size(self.code[next_op], self.opc)
if code[next_op] == self.opc.JUMP_ABSOLUTE:
next_op += instruction_size(self.code[next_op], self.opc)
if next_op in targets:
for try_op in targets[next_op]:
come_from_op = code[try_op]
if (
self.version < 3.8
and come_from_op == self.opc.SETUP_EXCEPT
):
return
pass
pass
if self.version >= 3.4:
self.fixed_jumps[offset] = rtarget