(builder: IRBuilder, fitem: FuncDef)
| 1125 | |
| 1126 | |
| 1127 | def maybe_insert_into_registry_dict(builder: IRBuilder, fitem: FuncDef) -> None: |
| 1128 | line = fitem.line |
| 1129 | is_singledispatch_main_func = fitem in builder.singledispatch_impls |
| 1130 | # dict of singledispatch_func to list of register_types (fitem is the function to register) |
| 1131 | to_register: defaultdict[FuncDef, list[TypeInfo]] = defaultdict(list) |
| 1132 | for main_func, impls in builder.singledispatch_impls.items(): |
| 1133 | for dispatch_type, impl in impls: |
| 1134 | if fitem == impl: |
| 1135 | to_register[main_func].append(dispatch_type) |
| 1136 | |
| 1137 | if not to_register and not is_singledispatch_main_func: |
| 1138 | return |
| 1139 | |
| 1140 | if is_singledispatch_main_func: |
| 1141 | main_func_name = singledispatch_main_func_name(fitem.name) |
| 1142 | main_func_obj = load_func(builder, main_func_name, fitem.fullname, line) |
| 1143 | |
| 1144 | loaded_object_type = builder.load_module_attr_by_fullname("builtins.object", line) |
| 1145 | registry_dict = builder.builder.make_dict([(loaded_object_type, main_func_obj)], line) |
| 1146 | |
| 1147 | dispatch_func_obj = builder.load_global_str(fitem.name, line) |
| 1148 | builder.primitive_op( |
| 1149 | py_setattr_op, [dispatch_func_obj, builder.load_str("registry"), registry_dict], line |
| 1150 | ) |
| 1151 | |
| 1152 | for singledispatch_func, types in to_register.items(): |
| 1153 | # TODO: avoid recomputing the native IDs for all the functions every time we find a new |
| 1154 | # function |
| 1155 | native_ids = get_native_impl_ids(builder, singledispatch_func) |
| 1156 | if fitem not in native_ids: |
| 1157 | to_insert = load_func(builder, fitem.name, fitem.fullname, line) |
| 1158 | else: |
| 1159 | current_id = native_ids[fitem] |
| 1160 | load_literal = LoadLiteral(current_id, object_rprimitive) |
| 1161 | to_insert = builder.add(load_literal) |
| 1162 | # TODO: avoid reloading the registry here if we just created it |
| 1163 | dispatch_func_obj = load_func( |
| 1164 | builder, singledispatch_func.name, singledispatch_func.fullname, line |
| 1165 | ) |
| 1166 | registry = load_singledispatch_registry(builder, dispatch_func_obj, line) |
| 1167 | for typ in types: |
| 1168 | loaded_type = load_type(builder, typ, None, line) |
| 1169 | builder.call_c(exact_dict_set_item_op, [registry, loaded_type, to_insert], line) |
| 1170 | dispatch_cache = builder.builder.get_attr( |
| 1171 | dispatch_func_obj, "dispatch_cache", dict_rprimitive, line |
| 1172 | ) |
| 1173 | builder.gen_method_call(dispatch_cache, "clear", [], None, line) |
| 1174 | |
| 1175 | |
| 1176 | def get_native_impl_ids(builder: IRBuilder, singledispatch_func: FuncDef) -> dict[FuncDef, int]: |
no test coverage detected
searching dependent graphs…