def do_folding(src): (state, state_out) = analyzer.analyze_forward(src, merge, step, dict(), dict()) for i in range(len(src)): if state[i] is None: continue code = list(src[i]) if code[0] in BINARY_OPERATORS: if code[2][0] == 'symbol' and code[2][1] in state[i]: code[2] = ('constant', state[i][code[2][1]]) if code[3][0] == 'symbol' and code[3][1] in state[i]: code[3] = ('constant', state[i][code[3][1]]) elif code[0] in UNARY_OPERATORS: if code[2][0] == 'symbol' and code[2][1] in state[i]: code[2] = ('constant', state[i][code[2][1]]) elif code[0] == 'call': for j in range(len(code[3])): if code[3][j][0] == 'symbol' and code[3][j][1] in state[i]: code[3][j] = ('constant', state[i][code[3][j][1]]) elif code[0] in ['if', 'ifnot']: if code[1][0] == 'symbol' and code[1][1] in state[i]: code[1] = ('constant', state[i][code[1][1]]) elif code[0] not in ['jmp']: raise Exception('Unhandled op: ' + code[0]) src[i] = tuple(code) return src
def type_inference(funcs): src, func_new_line = expanded_form(funcs) states, states_out = analyzer.analyze_forward(src, merge, step, ({}, {}), ({}, {})) #for i in range(len(src)): # print(i, src[i], '\033[94m', states[i], '\033[0m') def add_type(v, state): symbols, nodes = state if v[0] == 'symbol': infered = set() if v[1] in symbols: for node_name in symbols[v[1]]: if node_name in SIMPLE_NODES: infered.add(node_name) elif 'list_values' in nodes[node_name]: infered.add('list') elif 'set_values' in nodes[node_name]: infered.add('set') elif 'dict_values' in nodes[node_name]: infered.add('dict') elif 'list_iterator_owners' in nodes[node_name]: infered.add('list_iterator') elif 'set_iterator_owners' in nodes[node_name]: infered.add('set_iterator') elif 'dict_iterator_owners' in nodes[node_name]: infered.add('dict_iterator') return ('symbol', v[1], infered) if v[0] == 'constant': return ('constant', v[1], {constant_type(v[1])}) raise Exception("Unknown value: " + str(v)) for func_name in funcs: for i in range(len(funcs[func_name]['code'])): code = list(funcs[func_name]['code'][i]) state = states[func_new_line[func_name][i]] if code[0] in UNARY_OPERATORS: #code[1] = add_type(code[1], states_out[i]) code[2] = add_type(code[2], state) elif code[0] in BINARY_OPERATORS: #code[1] = add_type(code[1], states_out[i]) code[2] = add_type(code[2], state) code[3] = add_type(code[3], state) elif code[0] == 'call': #if code[1] is not None: # code[1] = add_type(code[1], states_out[i]) code[3] = [add_type(x, state) for x in code[3]] elif code[0] in ['if', 'ifnot']: code[1] = add_type(code[1], state) elif code[0] != 'jmp': raise Exception('Unhandled op: ' + code[0]) funcs[func_name]['code'][i] = tuple(code) return funcs
def type_inference(funcs): src, func_new_line = expanded_form(funcs) states, states_out = analyzer.analyze_forward(src, merge, step, ({},{}), ({},{})) #for i in range(len(src)): # print(i, src[i], '\033[94m', states[i], '\033[0m') def add_type(v, state): symbols, nodes = state if v[0] == 'symbol': infered = set() if v[1] in symbols: for node_name in symbols[v[1]]: if node_name in SIMPLE_NODES: infered.add(node_name) elif 'list_values' in nodes[node_name]: infered.add('list') elif 'set_values' in nodes[node_name]: infered.add('set') elif 'dict_values' in nodes[node_name]: infered.add('dict') elif 'list_iterator_owners' in nodes[node_name]: infered.add('list_iterator') elif 'set_iterator_owners' in nodes[node_name]: infered.add('set_iterator') elif 'dict_iterator_owners' in nodes[node_name]: infered.add('dict_iterator') return ('symbol', v[1], infered) if v[0] == 'constant': return ('constant', v[1], {constant_type(v[1])}) raise Exception("Unknown value: " + str(v)) for func_name in funcs: for i in range(len(funcs[func_name]['code'])): code = list(funcs[func_name]['code'][i]) state = states[func_new_line[func_name][i]] if code[0] in UNARY_OPERATORS: #code[1] = add_type(code[1], states_out[i]) code[2] = add_type(code[2], state) elif code[0] in BINARY_OPERATORS: #code[1] = add_type(code[1], states_out[i]) code[2] = add_type(code[2], state) code[3] = add_type(code[3], state) elif code[0] == 'call': #if code[1] is not None: # code[1] = add_type(code[1], states_out[i]) code[3] = [add_type(x, state) for x in code[3]] elif code[0] in ['if', 'ifnot']: code[1] = add_type(code[1], state) elif code[0] != 'jmp': raise Exception('Unhandled op: ' + code[0]) funcs[func_name]['code'][i] = tuple(code) return funcs
def do_dead_code(src): def merge(states): return any(states) def step(old_state,code,line_num): return old_state (state, state_out) = analyzer.analyze_forward(src, merge, step, True, False) to_remove = [] for i in range(len(src)): if not state[i]: to_remove.append(i) continue code = src[i] if analyzer.must_take(code): src[i] = code = ('jmp', code[2]) if analyzer.must_not_take(code): to_remove.append(i) continue return remove_lines(src, to_remove)
def do_dead_code(src): def merge(states): return any(states) def step(old_state, code, line_num): return old_state (state, state_out) = analyzer.analyze_forward(src, merge, step, True, False) to_remove = [] for i in range(len(src)): if not state[i]: to_remove.append(i) continue code = src[i] if analyzer.must_take(code): src[i] = code = ('jmp', code[2]) if analyzer.must_not_take(code): to_remove.append(i) continue return remove_lines(src, to_remove)