def scan_function_code(self): """Scan the function codes. Returns: list of constraint created while scanning the code. """ block_indexes = sorted( determine_branch_targets(self._ti_function.co_code)) # read-only next_instr = 0 co_code = self._ti_function.co_code print(repr(co_code)) print('Prescan branch indexes: %r' % block_indexes) if block_indexes and block_indexes[0] == 0: del block_indexes[0] self._switch_to_entry_branch() while True: last_instr = next_instr next_instr, opcode, oparg = opcode_decoder(co_code, next_instr) try: self.last_opcode_index = last_instr opcode_handler = FUNCTION_SCANNER_OPCODE_FUNCTIONS[opcode] except KeyError: self.warning("Skipped opcode %s @ %d" % (opname[opcode], last_instr)) action = ACTION_PROCESS_NEXT_OPCODE else: print("Processing @%d: opcode %s, %d" % (last_instr, opname[opcode], oparg)) self.next_instr_index = next_instr action = opcode_handler(self, oparg) assert action is not None if action == ACTION_PROCESS_NEXT_OPCODE: if next_instr in block_indexes: # Notes: some code similar to ACTION_BRANCH # We are falling through into a new block print('Switched via fall through to new branch @%d' % next_instr) block_indexes.remove(next_instr) self._switch_branch(next_instr, 'fall through') else: # next_instr has already been initialized, checks that last instruction # was a terminator if next_instr >= len(co_code): raise ValueError( 'Attempting to process instruction beyond end of code block.' ) elif action == ACTION_BRANCH: if block_indexes: next_instr = block_indexes.pop(0) # Set branch basic block as builder target print('Switched to new branch @%d' % next_instr) self._switch_branch(next_instr, 'some_branch') else: # Done, nothing to interpret break else: raise ValueError('Invalid action: %d' % action)
def scan_function_code( self ): """Scan the function codes. Returns: list of constraint created while scanning the code. """ block_indexes = sorted( determine_branch_targets( self._ti_function.co_code ) )# read-only next_instr = 0 co_code = self._ti_function.co_code print( repr(co_code) ) print( 'Prescan branch indexes: %r' % block_indexes ) if block_indexes and block_indexes[0] == 0: del block_indexes[0] self._switch_to_entry_branch() while True: last_instr = next_instr next_instr, opcode, oparg = opcode_decoder( co_code, next_instr ) try: self.last_opcode_index = last_instr opcode_handler = FUNCTION_SCANNER_OPCODE_FUNCTIONS[ opcode ] except KeyError: self.warning( "Skipped opcode %s @ %d" % (opname[opcode], last_instr) ) action = ACTION_PROCESS_NEXT_OPCODE else: print( "Processing @%d: opcode %s, %d" % (last_instr, opname[opcode], oparg) ) self.next_instr_index = next_instr action = opcode_handler( self, oparg ) assert action is not None if action == ACTION_PROCESS_NEXT_OPCODE: if next_instr in block_indexes: # Notes: some code similar to ACTION_BRANCH # We are falling through into a new block print( 'Switched via fall through to new branch @%d' % next_instr ) block_indexes.remove( next_instr ) self._switch_branch( next_instr, 'fall through' ) else: # next_instr has already been initialized, checks that last instruction # was a terminator if next_instr >= len(co_code): raise ValueError( 'Attempting to process instruction beyond end of code block.' ) elif action == ACTION_BRANCH: if block_indexes: next_instr = block_indexes.pop(0) # Set branch basic block as builder target print( 'Switched to new branch @%d' % next_instr ) self._switch_branch( next_instr, 'some_branch') else: # Done, nothing to interpret break else: raise ValueError( 'Invalid action: %d' % action )
def __init__( self, py_func, module_generator, annotator ): self.py_func = py_func self.module_generator = module_generator self.annotator = annotator self.annotation = self.annotator.get_function_annotation( self.py_func ) self.l_func, self.l_func_type = module_generator.add_function( py_func, self.annotation.r_func_type ) self.arg_count = self.l_func_type.arg_count self.is_constructor = self.annotation.r_func_type.is_constructor() self.blocks_by_target = {} # dict{opcode_index: basic_block} self.branch_indexes = determine_branch_targets( self.py_func.__code__.co_code ) # read-only self.global_var_values = {} # dict{global_index: l_value} self._next_id_by_prefix = {} self.value_stack = [] self.pending_break_jump_blocks = [] # List of blocks that need a final "break" jump # self.locals_ptr: dict{local_var_index: l_value} # This dictionary contains pointer to local variable memory # allocated via alloca(), and pointer directly to parameters # for parameters. self.builder, self.current_block, self.locals_ptr = \ self.make_entry_basic_block_builder()
def __init__(self, py_func, module_generator, annotator): self.py_func = py_func self.module_generator = module_generator self.annotator = annotator self.annotation = self.annotator.get_function_annotation(self.py_func) self.l_func, self.l_func_type = module_generator.add_function( py_func, self.annotation.r_func_type) self.arg_count = self.l_func_type.arg_count self.is_constructor = self.annotation.r_func_type.is_constructor() self.blocks_by_target = {} # dict{opcode_index: basic_block} self.branch_indexes = determine_branch_targets( self.py_func.__code__.co_code) # read-only self.global_var_values = {} # dict{global_index: l_value} self._next_id_by_prefix = {} self.value_stack = [] self.pending_break_jump_blocks = [ ] # List of blocks that need a final "break" jump # self.locals_ptr: dict{local_var_index: l_value} # This dictionary contains pointer to local variable memory # allocated via alloca(), and pointer directly to parameters # for parameters. self.builder, self.current_block, self.locals_ptr = \ self.make_entry_basic_block_builder()