diff --git a/mypyc/irbuild/builder.py b/mypyc/irbuild/builder.py index 7561070b012f..a0837ba2bfc7 100644 --- a/mypyc/irbuild/builder.py +++ b/mypyc/irbuild/builder.py @@ -404,7 +404,7 @@ def add_to_non_ext_dict( ) -> None: # Add an attribute entry into the class dict of a non-extension class. key_unicode = self.load_str(key) - self.call_c(dict_set_item_op, [non_ext.dict, key_unicode, val], line) + self.primitive_op(dict_set_item_op, [non_ext.dict, key_unicode, val], line) def gen_import(self, id: str, line: int) -> None: self.imports[id] = None @@ -435,7 +435,7 @@ def get_module(self, module: str, line: int) -> Value: # Python 3.7 has a nice 'PyImport_GetModule' function that we can't use :( mod_dict = self.call_c(get_module_dict_op, [], line) # Get module object from modules dict. - return self.call_c(dict_get_item_op, [mod_dict, self.load_str(module)], line) + return self.primitive_op(dict_get_item_op, [mod_dict, self.load_str(module)], line) def get_module_attr(self, module: str, attr: str, line: int) -> Value: """Look up an attribute of a module without storing it in the local namespace. @@ -817,7 +817,7 @@ def process_iterator_tuple_assignment( self.activate_block(ok_block) for litem in reversed(post_star_vals): - ritem = self.call_c(list_pop_last, [iter_list], line) + ritem = self.primitive_op(list_pop_last, [iter_list], line) self.assign(litem, ritem, line) # Assign the starred value @@ -1302,7 +1302,7 @@ def load_global(self, expr: NameExpr) -> Value: def load_global_str(self, name: str, line: int) -> Value: _globals = self.load_globals_dict() reg = self.load_str(name) - return self.call_c(dict_get_item_op, [_globals, reg], line) + return self.primitive_op(dict_get_item_op, [_globals, reg], line) def load_globals_dict(self) -> Value: return self.add(LoadStatic(dict_rprimitive, "globals", self.module_name)) diff --git a/mypyc/irbuild/classdef.py b/mypyc/irbuild/classdef.py index 58be87c88a3f..6072efa2c593 100644 --- a/mypyc/irbuild/classdef.py +++ b/mypyc/irbuild/classdef.py @@ -256,7 +256,7 @@ def finalize(self, ir: ClassIR) -> None: ) # Add the non-extension class to the dict - self.builder.call_c( + self.builder.primitive_op( dict_set_item_op, [ self.builder.load_globals_dict(), @@ -466,7 +466,7 @@ def allocate_class(builder: IRBuilder, cdef: ClassDef) -> Value: builder.add(InitStatic(tp, cdef.name, builder.module_name, NAMESPACE_TYPE)) # Add it to the dict - builder.call_c( + builder.primitive_op( dict_set_item_op, [builder.load_globals_dict(), builder.load_str(cdef.name), tp], cdef.line ) @@ -493,7 +493,7 @@ def make_generic_base_class( else: arg = builder.new_tuple(args, line) - base = builder.call_c(py_get_item_op, [gent, arg], line) + base = builder.primitive_op(py_get_item_op, [gent, arg], line) return base @@ -661,7 +661,7 @@ def add_non_ext_class_attr_ann( typ = builder.add(LoadAddress(type_object_op.type, type_object_op.src, stmt.line)) key = builder.load_str(lvalue.name) - builder.call_c(dict_set_item_op, [non_ext.anns, key, typ], stmt.line) + builder.primitive_op(dict_set_item_op, [non_ext.anns, key, typ], stmt.line) def add_non_ext_class_attr( diff --git a/mypyc/irbuild/expression.py b/mypyc/irbuild/expression.py index a2a3203d12ca..44251fceceab 100644 --- a/mypyc/irbuild/expression.py +++ b/mypyc/irbuild/expression.py @@ -59,6 +59,7 @@ Integer, LoadAddress, LoadLiteral, + PrimitiveDescription, RaiseStandardError, Register, TupleGet, @@ -98,7 +99,7 @@ from mypyc.primitives.generic_ops import iter_op from mypyc.primitives.list_ops import list_append_op, list_extend_op, list_slice_op from mypyc.primitives.misc_ops import ellipsis_op, get_module_dict_op, new_slice_op, type_op -from mypyc.primitives.registry import CFunctionDescription, builtin_names +from mypyc.primitives.registry import builtin_names from mypyc.primitives.set_ops import set_add_op, set_in_op, set_update_op from mypyc.primitives.str_ops import str_slice_op from mypyc.primitives.tuple_ops import list_tuple_op, tuple_slice_op @@ -181,7 +182,7 @@ def transform_name_expr(builder: IRBuilder, expr: NameExpr) -> Value: # AST doesn't include a Var node for the module. We # instead load the module separately on each access. mod_dict = builder.call_c(get_module_dict_op, [], expr.line) - obj = builder.call_c( + obj = builder.primitive_op( dict_get_item_op, [mod_dict, builder.load_str(expr.node.fullname)], expr.line ) return obj @@ -977,8 +978,8 @@ def _visit_display( builder: IRBuilder, items: list[Expression], constructor_op: Callable[[list[Value], int], Value], - append_op: CFunctionDescription, - extend_op: CFunctionDescription, + append_op: PrimitiveDescription, + extend_op: PrimitiveDescription, line: int, is_list: bool, ) -> Value: @@ -999,7 +1000,7 @@ def _visit_display( if result is None: result = constructor_op(initial_items, line) - builder.call_c(extend_op if starred else append_op, [result, value], line) + builder.primitive_op(extend_op if starred else append_op, [result, value], line) if result is None: result = constructor_op(initial_items, line) @@ -1028,7 +1029,7 @@ def transform_dictionary_comprehension(builder: IRBuilder, o: DictionaryComprehe def gen_inner_stmts() -> None: k = builder.accept(o.key) v = builder.accept(o.value) - builder.call_c(dict_set_item_op, [builder.read(d), k, v], o.line) + builder.primitive_op(dict_set_item_op, [builder.read(d), k, v], o.line) comprehension_helper(builder, loop_params, gen_inner_stmts, o.line) return builder.read(d) diff --git a/mypyc/irbuild/for_helpers.py b/mypyc/irbuild/for_helpers.py index b37c39e70f11..9b34a094db60 100644 --- a/mypyc/irbuild/for_helpers.py +++ b/mypyc/irbuild/for_helpers.py @@ -251,7 +251,7 @@ def translate_list_comprehension(builder: IRBuilder, gen: GeneratorExpr) -> Valu def gen_inner_stmts() -> None: e = builder.accept(gen.left_expr) - builder.call_c(list_append_op, [builder.read(list_ops), e], gen.line) + builder.primitive_op(list_append_op, [builder.read(list_ops), e], gen.line) comprehension_helper(builder, loop_params, gen_inner_stmts, gen.line) return builder.read(list_ops) @@ -286,7 +286,7 @@ def translate_set_comprehension(builder: IRBuilder, gen: GeneratorExpr) -> Value def gen_inner_stmts() -> None: e = builder.accept(gen.left_expr) - builder.call_c(set_add_op, [builder.read(set_ops), e], gen.line) + builder.primitive_op(set_add_op, [builder.read(set_ops), e], gen.line) comprehension_helper(builder, loop_params, gen_inner_stmts, gen.line) return builder.read(set_ops) diff --git a/mypyc/irbuild/function.py b/mypyc/irbuild/function.py index 4d04c549d392..a84db5a08863 100644 --- a/mypyc/irbuild/function.py +++ b/mypyc/irbuild/function.py @@ -133,7 +133,7 @@ def transform_decorator(builder: IRBuilder, dec: Decorator) -> None: if decorated_func is not None: # Set the callable object representing the decorated function as a global. - builder.call_c( + builder.primitive_op( dict_set_item_op, [builder.load_globals_dict(), builder.load_str(dec.func.name), decorated_func], decorated_func.line, @@ -849,7 +849,7 @@ def generate_singledispatch_dispatch_function( dispatch_func_obj, "dispatch_cache", dict_rprimitive, line ) call_find_impl, use_cache, call_func = BasicBlock(), BasicBlock(), BasicBlock() - get_result = builder.call_c(dict_get_method_with_none, [dispatch_cache, arg_type], line) + get_result = builder.primitive_op(dict_get_method_with_none, [dispatch_cache, arg_type], line) is_not_none = builder.translate_is_op(get_result, builder.none_object(), "is not", line) impl_to_use = Register(object_rprimitive) builder.add_bool_branch(is_not_none, use_cache, call_find_impl) @@ -862,7 +862,7 @@ def generate_singledispatch_dispatch_function( find_impl = builder.load_module_attr_by_fullname("functools._find_impl", line) registry = load_singledispatch_registry(builder, dispatch_func_obj, line) uncached_impl = builder.py_call(find_impl, [arg_type, registry], line) - builder.call_c(dict_set_item_op, [dispatch_cache, arg_type, uncached_impl], line) + builder.primitive_op(dict_set_item_op, [dispatch_cache, arg_type, uncached_impl], line) builder.assign(impl_to_use, uncached_impl, line) builder.goto(call_func) @@ -1039,7 +1039,7 @@ def maybe_insert_into_registry_dict(builder: IRBuilder, fitem: FuncDef) -> None: registry = load_singledispatch_registry(builder, dispatch_func_obj, line) for typ in types: loaded_type = load_type(builder, typ, line) - builder.call_c(dict_set_item_op, [registry, loaded_type, to_insert], line) + builder.primitive_op(dict_set_item_op, [registry, loaded_type, to_insert], line) dispatch_cache = builder.builder.get_attr( dispatch_func_obj, "dispatch_cache", dict_rprimitive, line ) diff --git a/mypyc/irbuild/ll_builder.py b/mypyc/irbuild/ll_builder.py index a5a524b25af0..556d753b89f8 100644 --- a/mypyc/irbuild/ll_builder.py +++ b/mypyc/irbuild/ll_builder.py @@ -762,7 +762,7 @@ def _construct_varargs( if kind == ARG_STAR: if star_result is None: star_result = self.new_list_op(star_values, line) - self.call_c(list_extend_op, [star_result, value], line) + self.primitive_op(list_extend_op, [star_result, value], line) elif kind == ARG_STAR2: if star2_result is None: star2_result = self._create_dict(star2_keys, star2_values, line) @@ -1939,7 +1939,7 @@ def primitive_op( desc.priority, is_pure=desc.is_pure, ) - return self.call_c(c_desc, args, line, result_type) + return self.call_c(c_desc, args, line, result_type=result_type) # This primitive gets transformed in a lowering pass to # lower-level IR ops using a custom transform function. @@ -2005,7 +2005,7 @@ def matching_primitive_op( else: matching = desc if matching: - return self.primitive_op(matching, args, line=line) + return self.primitive_op(matching, args, line=line, result_type=result_type) return None def int_op(self, type: RType, lhs: Value, rhs: Value, op: int, line: int = -1) -> Value: @@ -2346,11 +2346,11 @@ def translate_special_method_call( Return None if no translation found; otherwise return the target register. """ - call_c_ops_candidates = method_call_ops.get(name, []) - call_c_op = self.matching_call_c( - call_c_ops_candidates, [base_reg] + args, line, result_type, can_borrow=can_borrow + primitive_ops_candidates = method_call_ops.get(name, []) + primitive_op = self.matching_primitive_op( + primitive_ops_candidates, [base_reg] + args, line, result_type, can_borrow=can_borrow ) - return call_c_op + return primitive_op def translate_eq_cmp(self, lreg: Value, rreg: Value, expr_op: str, line: int) -> Value | None: """Add a equality comparison operation. diff --git a/mypyc/primitives/registry.py b/mypyc/primitives/registry.py index 26faabc0c1e2..5e7ecb70f55d 100644 --- a/mypyc/primitives/registry.py +++ b/mypyc/primitives/registry.py @@ -70,8 +70,8 @@ class LoadAddressDescription(NamedTuple): src: str # name of the target to load -# CallC op for method call (such as 'str.join') -method_call_ops: dict[str, list[CFunctionDescription]] = {} +# Primitive ops for method call (such as 'str.join') +method_call_ops: dict[str, list[PrimitiveDescription]] = {} # Primitive ops for top level function call (such as 'builtins.list') function_ops: dict[str, list[PrimitiveDescription]] = {} @@ -99,7 +99,7 @@ def method_op( is_borrowed: bool = False, priority: int = 1, is_pure: bool = False, -) -> CFunctionDescription: +) -> PrimitiveDescription: """Define a c function call op that replaces a method call. This will be automatically generated by matching against the AST. @@ -129,7 +129,7 @@ def method_op( if extra_int_constants is None: extra_int_constants = [] ops = method_call_ops.setdefault(name, []) - desc = CFunctionDescription( + desc = PrimitiveDescription( name, arg_types, return_type, diff --git a/mypyc/test/test_cheader.py b/mypyc/test/test_cheader.py index 9c09f14e93dd..7ab055c735ad 100644 --- a/mypyc/test/test_cheader.py +++ b/mypyc/test/test_cheader.py @@ -9,7 +9,6 @@ from mypyc.ir.ops import PrimitiveDescription from mypyc.primitives import registry -from mypyc.primitives.registry import CFunctionDescription class TestHeaderInclusion(unittest.TestCase): @@ -26,14 +25,8 @@ def check_name(name: str) -> None: rf"\b{name}\b", header ), f'"{name}" is used in mypyc.primitives but not declared in CPy.h' - for old_values in [registry.method_call_ops.values()]: - for old_ops in old_values: - if isinstance(old_ops, CFunctionDescription): - old_ops = [old_ops] - for old_op in old_ops: - check_name(old_op.c_function_name) - for values in [ + registry.method_call_ops.values(), registry.binary_ops.values(), registry.unary_ops.values(), registry.function_ops.values(), diff --git a/mypyc/test/test_emitfunc.py b/mypyc/test/test_emitfunc.py index b97ad78d6970..90df131288f9 100644 --- a/mypyc/test/test_emitfunc.py +++ b/mypyc/test/test_emitfunc.py @@ -303,7 +303,7 @@ def test_dec_ref_tuple_nested(self) -> None: def test_list_get_item(self) -> None: self.assert_emit( CallC( - list_get_item_op.c_function_name, + str(list_get_item_op.c_function_name), [self.m, self.k], list_get_item_op.return_type, list_get_item_op.steals, @@ -317,7 +317,7 @@ def test_list_get_item(self) -> None: def test_list_set_item(self) -> None: self.assert_emit( CallC( - list_set_item_op.c_function_name, + str(list_set_item_op.c_function_name), [self.l, self.n, self.o], list_set_item_op.return_type, list_set_item_op.steals, @@ -353,7 +353,7 @@ def test_unbox_i64(self) -> None: def test_list_append(self) -> None: self.assert_emit( CallC( - list_append_op.c_function_name, + str(list_append_op.c_function_name), [self.l, self.o], list_append_op.return_type, list_append_op.steals, @@ -493,7 +493,7 @@ def test_set_attr_init_with_bitmap(self) -> None: def test_dict_get_item(self) -> None: self.assert_emit( CallC( - dict_get_item_op.c_function_name, + str(dict_get_item_op.c_function_name), [self.d, self.o2], dict_get_item_op.return_type, dict_get_item_op.steals, @@ -507,7 +507,7 @@ def test_dict_get_item(self) -> None: def test_dict_set_item(self) -> None: self.assert_emit( CallC( - dict_set_item_op.c_function_name, + str(dict_set_item_op.c_function_name), [self.d, self.o, self.o2], dict_set_item_op.return_type, dict_set_item_op.steals, @@ -521,7 +521,7 @@ def test_dict_set_item(self) -> None: def test_dict_update(self) -> None: self.assert_emit( CallC( - dict_update_op.c_function_name, + str(dict_update_op.c_function_name), [self.d, self.o], dict_update_op.return_type, dict_update_op.steals,