diff --git a/vyper/venom/ir_node_to_venom.py b/vyper/venom/ir_node_to_venom.py index 2c99cf5668..4fca95be90 100644 --- a/vyper/venom/ir_node_to_venom.py +++ b/vyper/venom/ir_node_to_venom.py @@ -107,14 +107,16 @@ NOOP_INSTRUCTIONS = frozenset(["pass", "cleanup_repeat", "var_list", "unique_symbol"]) SymbolTable = dict[str, Optional[IROperand]] -_global_symbols: SymbolTable = {} +_global_symbols: SymbolTable = None # type: ignore MAIN_ENTRY_LABEL_NAME = "__main_entry" +_external_functions: dict[int, SymbolTable] = None # type: ignore # convert IRnode directly to venom def ir_node_to_venom(ir: IRnode) -> IRContext: - global _global_symbols + global _global_symbols, _external_functions _global_symbols = {} + _external_functions = {} ctx = IRContext() fn = ctx.create_function(MAIN_ENTRY_LABEL_NAME) @@ -214,10 +216,6 @@ def _convert_ir_bb_list(fn, ir, symbols): return ret -current_func = None -var_list: list[str] = [] - - def pop_source_on_return(func): @functools.wraps(func) def pop_source(*args, **kwargs): @@ -232,7 +230,10 @@ def pop_source(*args, **kwargs): @pop_source_on_return def _convert_ir_bb(fn, ir, symbols): assert isinstance(ir, IRnode), ir - global _break_target, _continue_target, current_func, var_list, _global_symbols + # TODO: refactor these to not be globals + global _break_target, _continue_target, _global_symbols, _external_functions + + # keep a map from external functions to all possible entry points ctx = fn.ctx fn.push_source(ir) @@ -274,7 +275,6 @@ def _convert_ir_bb(fn, ir, symbols): return ret elif is_external: - _global_symbols = {} ret = _convert_ir_bb(fn, ir.args[0], symbols) _append_return_args(fn) else: @@ -382,6 +382,13 @@ def _convert_ir_bb(fn, ir, symbols): data = _convert_ir_bb(fn, c, symbols) ctx.append_data("db", [data]) # type: ignore elif ir.value == "label": + function_id_pattern = r"external (\d+)" + function_name = ir.args[0].value + m = re.match(function_id_pattern, function_name) + if m is not None: + function_id = m.group(1) + _global_symbols = _external_functions.setdefault(function_id, {}) + label = IRLabel(ir.args[0].value, True) bb = fn.get_basic_block() if not bb.is_terminated: