From 2cb974ae5a4a22bbc8484a877f2f930ae72af10d Mon Sep 17 00:00:00 2001 From: TermiNexus Date: Mon, 17 Aug 2026 08:10:55 +0800 Subject: [PATCH] =?UTF-8?q?refactor(handles):=20HandlesExprCall=20?= =?UTF-8?q?=E6=8B=86=206=20=E7=BB=84=EF=BC=88Base/Deref/Ctor/Call/Table/Ha?= =?UTF-8?q?ndle=EF=BC=8C2041=E2=86=92241=20=E8=A1=8C=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 直接移动+改调用方:~100 个委托函数按功能移至 6 个子模块,主文件 保留 _g_gen/set_global_gen/顶层常量/4 个类(AsmOperand、FuncEntry、 FuncDefaultsEntry、ExprCallHandle——CallGenLeafKit/HandlesTranslator 仍以 HandlesExprCall.类名 引用)。 - 子模块函数体内 _g_gen/常量/类裸引用 → HandlesExprCall.xxx 跨模块访问 - 28 个调用方 HandlesExprCall.func( → 子模块前缀并补 import - 全 App 语法/引用/import 验证通过 --- App/lib/StubGen/VpiReader.vp | 12 +- App/lib/core/Gen/CallGenCall.vp | 23 +- App/lib/core/Gen/CallGenCtor.vp | 24 +- App/lib/core/Gen/CallGenDispatch.vp | 78 +- App/lib/core/Gen/CallGenLib.vp | 3 +- App/lib/core/Gen/CallGenMixin.vp | 77 +- App/lib/core/Gen/CallGenVt.vp | 6 +- App/lib/core/Gen/ClassGenVTable.vp | 19 +- App/lib/core/Gen/ExprGenAttr.vp | 3 +- App/lib/core/Gen/ExprGenBase.vp | 3 +- App/lib/core/Gen/ExprGenCdef.vp | 3 +- App/lib/core/Gen/ExprGenCls.vp | 5 +- App/lib/core/Gen/ExprGenConst.vp | 11 +- App/lib/core/Gen/ExprGenMixin.vp | 3 +- App/lib/core/Gen/ExprGenName.vp | 18 +- App/lib/core/Gen/ExprGenOps.vp | 18 +- App/lib/core/Gen/FuncGenDef.vp | 43 +- App/lib/core/Gen/FuncGenMixin.vp | 10 +- App/lib/core/Gen/StmtGenMixin.vp | 6 +- App/lib/core/Gen/TranslatorGenMixin.vp | 3 +- App/lib/core/Gen/TypeGenResolve.vp | 3 +- App/lib/core/Handles/ExprCallBase.vp | 246 +++ App/lib/core/Handles/ExprCallCall.vp | 338 ++++ App/lib/core/Handles/ExprCallCtor.vp | 622 +++++++ App/lib/core/Handles/ExprCallDeref.vp | 291 +++ App/lib/core/Handles/ExprCallHandle.vp | 284 +++ App/lib/core/Handles/ExprCallTable.vp | 206 +++ App/lib/core/Handles/HandlesAnnAssign.vp | 6 +- App/lib/core/Handles/HandlesAssign.vp | 19 +- App/lib/core/Handles/HandlesExprCall.vp | 1998 +-------------------- App/lib/core/Handles/HandlesFor.vp | 9 +- App/lib/core/Handles/HandlesTranslator.vp | 6 +- App/lib/core/Phase1.vp | 3 +- App/lib/core/Phase2.vp | 3 +- 34 files changed, 2319 insertions(+), 2083 deletions(-) create mode 100644 App/lib/core/Handles/ExprCallBase.vp create mode 100644 App/lib/core/Handles/ExprCallCall.vp create mode 100644 App/lib/core/Handles/ExprCallCtor.vp create mode 100644 App/lib/core/Handles/ExprCallDeref.vp create mode 100644 App/lib/core/Handles/ExprCallHandle.vp create mode 100644 App/lib/core/Handles/ExprCallTable.vp diff --git a/App/lib/StubGen/VpiReader.vp b/App/lib/StubGen/VpiReader.vp index 19750f4..7eaae33 100644 --- a/App/lib/StubGen/VpiReader.vp +++ b/App/lib/StubGen/VpiReader.vp @@ -16,6 +16,8 @@ import lib.core.Handles.HandlesExprCall as HandlesExprCall import lib.core.Handles.HandlesFunctions as HandlesFunctions import lib.core.Handles.HandlesTranslator as HT import lib.core.StubMergerStore as StubMergerStore +import lib.core.Handles.ExprCallBase as ExprCallBase +import lib.core.Handles.ExprCallTable as ExprCallTable # ============================================================ @@ -1096,12 +1098,12 @@ def _inject_function_declare(pool: memhub.MemBuddy | t.CPtr, mangled_name = HandlesFunctions._mangle_name_with_sha1(src_sha1, fd.name) # 去重:如果函数已存在则跳过 - existing: llvmlite.Function | t.CPtr = HandlesExprCall.find_func_in_module(mod, mangled_name) + existing: llvmlite.Function | t.CPtr = ExprCallBase.find_func_in_module(mod, mangled_name) if existing is not None: return # 也检查裸名(非裸名模式时,CExport 函数可能已通过其他途径注册) if use_bare_name == 0: - existing_bare: llvmlite.Function | t.CPtr = HandlesExprCall.find_func_in_module(mod, fd.name) + existing_bare: llvmlite.Function | t.CPtr = ExprCallBase.find_func_in_module(mod, fd.name) if existing_bare is not None: return @@ -1173,7 +1175,7 @@ def _inject_function_declare(pool: memhub.MemBuddy | t.CPtr, # 注册到函数表(用裸名 fd.name,不是 mangled_name) if funcs_ptr is not None: cur_count: int = trans._func_count - if HandlesExprCall.add_func_to_table(funcs_ptr, cur_count, fd.name, func, max_funcs, + if ExprCallTable.add_func_to_table(funcs_ptr, cur_count, fd.name, func, max_funcs, None, 0, param_count) == 0: trans._func_count = cur_count + 1 @@ -1219,7 +1221,7 @@ def _inject_method_declare(pool: memhub.MemBuddy | t.CPtr, viperlib.snprintf(mangled_name, mangled_len, "%s.%s", src_sha1, lookup_name) # 去重:如果方法已存在则跳过 - existing: llvmlite.Function | t.CPtr = HandlesExprCall.find_func_in_module(mod, mangled_name) + existing: llvmlite.Function | t.CPtr = ExprCallBase.find_func_in_module(mod, mangled_name) if existing is not None: return @@ -1302,7 +1304,7 @@ def _inject_method_declare(pool: memhub.MemBuddy | t.CPtr, param_count_no_self: int = param_count if param_count_no_self > 0: param_count_no_self -= 1 - if HandlesExprCall.add_func_to_table(funcs_ptr, cur_count, lookup_name, func, max_funcs, + if ExprCallTable.add_func_to_table(funcs_ptr, cur_count, lookup_name, func, max_funcs, None, 0, param_count_no_self) == 0: trans._func_count = cur_count + 1 diff --git a/App/lib/core/Gen/CallGenCall.vp b/App/lib/core/Gen/CallGenCall.vp index acd328b..daa7567 100644 --- a/App/lib/core/Gen/CallGenCall.vp +++ b/App/lib/core/Gen/CallGenCall.vp @@ -27,6 +27,9 @@ import lib.core.CompilerFactory as CompilerFactory import lib.core.Gen.CallGenBase as CallGenBase +import lib.core.Handles.ExprCallCall as ExprCallCall +import lib.core.Handles.ExprCallHandle as ExprCallHandle +import lib.core.Handles.ExprCallTable as ExprCallTable # ============================================================ # CallGenCall - CallGenMixin 拆分(阶段 B):方法调用分派(含 super / 虚调用 / kwargs 名匹配) @@ -424,7 +427,7 @@ class CallGenCall(CallGenBase.CallGenBase): mdf_default_count: int = 0 mdf_param_count: int = 0 if trans is not None and trans._funcs is not None: - mdf_entry: FuncEntry | t.CPtr = HandlesExprCall.find_func_entry_in_table( + mdf_entry: FuncEntry | t.CPtr = ExprCallTable.find_func_entry_in_table( trans._funcs, trans._func_count, lookup_name) if mdf_entry is not None: mdf_defaults = mdf_entry.Defaults @@ -434,7 +437,7 @@ class CallGenCall(CallGenBase.CallGenBase): # 调用方函数表)Defaults 非 None 会短路跳过,但下方"用快照重建默认值" # 分支依赖 mdf_gd(唯一持有 stdlib 常量快照处)——缺它必 fatal_error # (ListTest list[int].__new__ 根因) - mdf_gd: FuncDefaultsEntry | t.CPtr = HandlesExprCall.find_func_defaults(lookup_name) + mdf_gd: FuncDefaultsEntry | t.CPtr = ExprCallTable.find_func_defaults(lookup_name) if mdf_defaults is None and mdf_gd is not None: mdf_defaults = mdf_gd.Defaults mdf_default_count = mdf_gd.DefaultCount @@ -455,7 +458,7 @@ class CallGenCall(CallGenBase.CallGenBase): # 直接回退读 AST 会 use-after-free——快照失败时 fail-fast 暴露,绝不读悬空 AST) mdf_val: llvmlite.Value | t.CPtr = None if mdf_gd is not None: - mdf_val = HandlesExprCall._build_const_from_snapshot( + mdf_val = ExprCallTable._build_const_from_snapshot( pool, mod, mdf_gd, mdf_di, trans, builder) if mdf_val is None: # 用 node(本函数报错行号节点,如构造实参/源码 Call)而非 cl—— @@ -1084,7 +1087,7 @@ class CallGenCall(CallGenBase.CallGenBase): mdf_default_count: int = 0 mdf_param_count: int = 0 if trans is not None and trans._funcs is not None: - mdf_entry: FuncEntry | t.CPtr = HandlesExprCall.find_func_entry_in_table( + mdf_entry: FuncEntry | t.CPtr = ExprCallTable.find_func_entry_in_table( trans._funcs, trans._func_count, lookup_name) if mdf_entry is not None: mdf_defaults = mdf_entry.Defaults @@ -1094,7 +1097,7 @@ class CallGenCall(CallGenBase.CallGenBase): # 调用方函数表)Defaults 非 None 会短路跳过,但下方"用快照重建默认值" # 分支依赖 mdf_gd(唯一持有 stdlib 常量快照处)——缺它必 fatal_error # (ListTest list[int].__new__ 根因) - mdf_gd: FuncDefaultsEntry | t.CPtr = HandlesExprCall.find_func_defaults(lookup_name) + mdf_gd: FuncDefaultsEntry | t.CPtr = ExprCallTable.find_func_defaults(lookup_name) if mdf_defaults is None and mdf_gd is not None: mdf_defaults = mdf_gd.Defaults mdf_default_count = mdf_gd.DefaultCount @@ -1115,7 +1118,7 @@ class CallGenCall(CallGenBase.CallGenBase): # 直接回退读 AST 会 use-after-free——快照失败时 fail-fast 暴露,绝不读悬空 AST) mdf_val: llvmlite.Value | t.CPtr = None if mdf_gd is not None: - mdf_val = HandlesExprCall._build_const_from_snapshot( + mdf_val = ExprCallTable._build_const_from_snapshot( pool, mod, mdf_gd, mdf_di, trans, builder) if mdf_val is None: HandlesType.fatal_error( @@ -1177,10 +1180,10 @@ class CallGenCall(CallGenBase.CallGenBase): # 跨模块调用:创建 declare 声明,避免 llc 报 undefined value self._ensure_method_declare(pool, mod, call_name, call_ret_ty, head, total_count) # 检查变长函数 + C ABI 提升(cargs 是实参 AST,self_offset=1 跳过 self) - is_variadic_3441: int = HandlesExprCall._check_and_promote_variadic_call( + is_variadic_3441: int = ExprCallCall._check_and_promote_variadic_call( pool, builder, mod, call_name, head, total_count, cargs, 1, trans) # try-except:方法含 raise(EH 输出参数)时追加输出实参 + 调用后检测 - return HandlesExprCall._emit_eh_guarded_call( + return ExprCallHandle._emit_eh_guarded_call( builder, pool, mod, trans, found_func, call_name, head, total_count, call_ret_ty, is_variadic_3441) # ============================================================ @@ -1243,7 +1246,7 @@ class CallGenCall(CallGenBase.CallGenBase): probe_sp: str = pool.alloc(160) if probe_sp is not None: viperlib.snprintf(probe_sp, 160, "%s.%s", anc_sp, method_name) - if HandlesExprCall.find_func_global(probe_sp) is not None: + if ExprCallTable.find_func_global(probe_sp) is not None: anc = anc_sp break mi_sp += 1 @@ -1417,7 +1420,7 @@ class CallGenCall(CallGenBase.CallGenBase): # 7. 跨模块:创建 declare;生成 call if found_func is None: self._ensure_method_declare(pool, mod, call_name, ret_ty_sp, head, arg_count_sp) - is_variadic_sp: int = HandlesExprCall._check_and_promote_variadic_call( + is_variadic_sp: int = ExprCallCall._check_and_promote_variadic_call( pool, builder, mod, call_name, head, arg_count_sp, cargs_sp, 1, trans) return llvmlite.build_call(builder, call_name, head, arg_count_sp, ret_ty_sp, is_variadic_sp) # ============================================================ diff --git a/App/lib/core/Gen/CallGenCtor.vp b/App/lib/core/Gen/CallGenCtor.vp index 45efca6..035e276 100644 --- a/App/lib/core/Gen/CallGenCtor.vp +++ b/App/lib/core/Gen/CallGenCtor.vp @@ -27,6 +27,8 @@ import lib.core.CompilerFactory as CompilerFactory import lib.core.Gen.CallGenBase as CallGenBase +import lib.core.Handles.ExprCallCtor as ExprCallCtor +import lib.core.Handles.ExprCallTable as ExprCallTable # ============================================================ # CallGenCtor - CallGenMixin 拆分(阶段 B):结构体构造 / 枚举构造 / 泛型构造 / 类型转换 @@ -178,7 +180,7 @@ class CallGenCtor(CallGenBase.CallGenBase): ctor_entry.HasInit = 1 else: # 方案2: 检查全局默认参数表(翻译时填充,不依赖 stub 注入) - init_defaults_entry: FuncDefaultsEntry | t.CPtr = HandlesExprCall.find_func_defaults(init_lookup_name) + init_defaults_entry: FuncDefaultsEntry | t.CPtr = ExprCallTable.find_func_defaults(init_lookup_name) if init_defaults_entry is not None: is_oop = 1 if ctor_entry is not None: @@ -211,7 +213,7 @@ class CallGenCtor(CallGenBase.CallGenBase): new_arg_vals[new_arg_count] = t.CSizeT(new_av) new_arg_count += 1 - new_ptr: llvmlite.Value | t.CPtr = HandlesExprCall._call_method_on_ptr( + new_ptr: llvmlite.Value | t.CPtr = ExprCallCtor._call_method_on_ptr( pool, builder, mod, class_name, "__new__", tmp, new_arg_vals, new_arg_count, trans, diag_node_ct) if new_ptr is not None: @@ -230,7 +232,7 @@ class CallGenCtor(CallGenBase.CallGenBase): storage_ptr = nw_bc # OOP 结构体:调用 __before_init__ 进行零值填充和默认值赋值 - HandlesExprCall._call_method_on_ptr(pool, builder, mod, class_name, + ExprCallCtor._call_method_on_ptr(pool, builder, mod, class_name, "__before_init__", storage_ptr, None, 0, trans, diag_node_ct) # 如果有 __init__,调用 __init__(ptr, args...) @@ -256,7 +258,7 @@ class CallGenCtor(CallGenBase.CallGenBase): arg_vals[real_arg_count] = t.CSizeT(av) real_arg_count += 1 - HandlesExprCall._call_method_on_ptr(pool, builder, mod, class_name, + ExprCallCtor._call_method_on_ptr(pool, builder, mod, class_name, "__init__", storage_ptr, arg_vals, real_arg_count, trans, diag_node_ct) elif has_new_flag == 0: # 无 __init__ 且无 __new__:逐字段 store 参数值 @@ -558,7 +560,7 @@ class CallGenCtor(CallGenBase.CallGenBase): kw_entry.HasInit = 1 else: # 方案2: 检查全局默认参数表(翻译时填充,不依赖 stub 注入) - kw_init_defaults: FuncDefaultsEntry | t.CPtr = HandlesExprCall.find_func_defaults(kw_init_lookup) + kw_init_defaults: FuncDefaultsEntry | t.CPtr = ExprCallTable.find_func_defaults(kw_init_lookup) if kw_init_defaults is not None: is_oop = 1 if kw_entry is not None: @@ -566,7 +568,7 @@ class CallGenCtor(CallGenBase.CallGenBase): kw_entry.HasInit = 1 if is_oop != 0: - HandlesExprCall._call_method_on_ptr(pool, builder, mod, class_name, + ExprCallCtor._call_method_on_ptr(pool, builder, mod, class_name, "__before_init__", tmp, None, 0, trans) else: # 普通结构体:store zeroinitializer + 应用默认值 @@ -620,7 +622,7 @@ class CallGenCtor(CallGenBase.CallGenBase): if new_arg_count < 32: new_arg_vals[new_arg_count] = t.CSizeT(nkw_av) new_arg_count += 1 - new_ptr: llvmlite.Value | t.CPtr = HandlesExprCall._call_method_on_ptr( + new_ptr: llvmlite.Value | t.CPtr = ExprCallCtor._call_method_on_ptr( pool, builder, mod, class_name, "__new__", tmp, new_arg_vals, new_arg_count, trans, diag_node_ct) if new_ptr is not None: @@ -667,7 +669,7 @@ class CallGenCtor(CallGenBase.CallGenBase): init_arg_count += 1 # 调用 __init__(storage_ptr, *args) - HandlesExprCall._call_method_on_ptr(pool, builder, mod, class_name, + ExprCallCtor._call_method_on_ptr(pool, builder, mod, class_name, "__init__", storage_ptr, init_arg_vals, init_arg_count, trans, diag_node_ct) # 返回指针 @@ -1021,7 +1023,7 @@ class CallGenCtor(CallGenBase.CallGenBase): if struct_entry is not None: has_new_flag = struct_entry.HasNew if has_new_flag != 0: - new_ptr: llvmlite.Value | t.CPtr = HandlesExprCall._call_method_on_ptr( + new_ptr: llvmlite.Value | t.CPtr = ExprCallCtor._call_method_on_ptr( pool, builder, mod, spec_name, "__new__", tmp, extra_args, can, trans) if new_ptr is not None: storage_ptr = new_ptr @@ -1039,11 +1041,11 @@ class CallGenCtor(CallGenBase.CallGenBase): storage_ptr = nw_bc # call __before_init__(storage_ptr)(TransPyV 自动生成,零值填充) - HandlesExprCall._call_method_on_ptr( + ExprCallCtor._call_method_on_ptr( pool, builder, mod, spec_name, "__before_init__", storage_ptr, None, 0, trans) # call __init__(storage_ptr, *args) - HandlesExprCall._call_method_on_ptr( + ExprCallCtor._call_method_on_ptr( pool, builder, mod, spec_name, "__init__", storage_ptr, extra_args, can, trans) return storage_ptr \ No newline at end of file diff --git a/App/lib/core/Gen/CallGenDispatch.vp b/App/lib/core/Gen/CallGenDispatch.vp index 0e7f46f..f38746c 100644 --- a/App/lib/core/Gen/CallGenDispatch.vp +++ b/App/lib/core/Gen/CallGenDispatch.vp @@ -27,6 +27,10 @@ import lib.core.CompilerFactory as CompilerFactory import lib.core.Gen.CallGenBase as CallGenBase +import lib.core.Handles.ExprCallCall as ExprCallCall +import lib.core.Handles.ExprCallCtor as ExprCallCtor +import lib.core.Handles.ExprCallDeref as ExprCallDeref +import lib.core.Handles.ExprCallHandle as ExprCallHandle # ============================================================ # CallGenDispatch - CallGenMixin 拆分(阶段 C):translate_call 检测段 @@ -61,7 +65,7 @@ class CallGenDispatch(CallGenBase.CallGenBase): if sup_cl.func is not None and sup_cl.func.kind() == ast.ASTKind.Name: sup_nm: ast.Name | t.CPtr = (ast.Name | t.CPtr)(sup_cl.func) if sup_nm.id is not None and string.strcmp(sup_nm.id, "super") == 0: - return HandlesExprCall._translate_super_call( + return ExprCallHandle._translate_super_call( pool, builder, mod, cl, func_name, trans) # ctraits 宏库编译期谓词:ctraits.isptr(x) 不生成运行时调用, @@ -103,21 +107,21 @@ class CallGenDispatch(CallGenBase.CallGenBase): mod_nm: ast.Name | t.CPtr = (ast.Name | t.CPtr)(at_node.value) if mod_nm.id is not None and string.strcmp(mod_nm.id, "c") == 0: if string.strcmp(func_name, "Deref") == 0: - return HandlesExprCall.translate_c_deref(pool, builder, mod, cl, trans) + return ExprCallDeref.translate_c_deref(pool, builder, mod, cl, trans) elif string.strcmp(func_name, "DerefAs") == 0: - return HandlesExprCall.translate_c_derefas(pool, builder, mod, cl, trans) + return ExprCallDeref.translate_c_derefas(pool, builder, mod, cl, trans) elif string.strcmp(func_name, "Addr") == 0: - return HandlesExprCall.translate_c_addr(pool, builder, mod, cl, trans) + return ExprCallDeref.translate_c_addr(pool, builder, mod, cl, trans) elif string.strcmp(func_name, "Set") == 0: # c.Set(a, b) = a = b(赋值语义,非指针解引用)。 # 若当普通函数调用会生成 @Set 引用导致链接失败(undefined reference to `Set')。 - return HandlesExprCall.translate_c_set(pool, builder, mod, cl, trans) + return ExprCallDeref.translate_c_set(pool, builder, mod, cl, trans) elif string.strcmp(func_name, "Load") == 0: - return HandlesExprCall.translate_c_load(pool, builder, mod, cl, trans) + return ExprCallDeref.translate_c_load(pool, builder, mod, cl, trans) elif string.strcmp(func_name, "Asm") == 0: - return HandlesExprCall.translate_c_asm(pool, builder, mod, cl, trans) + return ExprCallDeref.translate_c_asm(pool, builder, mod, cl, trans) elif string.strcmp(func_name, "LLVMIR") == 0: - return HandlesExprCall.translate_c_llvmir(pool, builder, mod, cl, trans) + return ExprCallDeref.translate_c_llvmir(pool, builder, mod, cl, trans) elif string.strcmp(func_name, "LInp") == 0 or string.strcmp(func_name, "LOut") == 0: # c.LInp/c.LOut 独立调用时返回 0(仅在 c.LLVMIR 的 f-string 内有意义) return llvmlite.ConstInt(pool, llvmlite.Int32(pool), 0, "0") @@ -168,16 +172,16 @@ class CallGenDispatch(CallGenBase.CallGenBase): # ============================================================ if func_name is not None and trans is not None: if string.strcmp(func_name, "va_arg") == 0: - return HandlesExprCall._translate_va_arg_sugar(pool, builder, mod, cl, cargs, can, + return ExprCallCall._translate_va_arg_sugar(pool, builder, mod, cl, cargs, can, funcs_ptr, func_count, trans) elif string.strcmp(func_name, "arg") == 0: - return HandlesExprCall._translate_arg_sugar(pool, builder, mod, cl, cargs, can, + return ExprCallCall._translate_arg_sugar(pool, builder, mod, cl, cargs, can, funcs_ptr, func_count, trans) elif string.strcmp(func_name, "va_start") == 0: - return HandlesExprCall._translate_va_start_sugar(pool, builder, mod, cargs, can, + return ExprCallCall._translate_va_start_sugar(pool, builder, mod, cargs, can, funcs_ptr, func_count, trans) elif string.strcmp(func_name, "va_end") == 0: - return HandlesExprCall._translate_va_end_sugar(pool, builder, mod, cargs, can, + return ExprCallCall._translate_va_end_sugar(pool, builder, mod, cargs, can, funcs_ptr, func_count, trans) # 内置强转函数: str(x)/bytes(x) → i8*, int(x) → i32 @@ -195,7 +199,7 @@ class CallGenDispatch(CallGenBase.CallGenBase): builder, pool, mod, cargs.get(0), funcs_ptr, func_count, trans) if cast_arg is not None: i8_ptr_ty_builtin: llvmlite.LLVMType | t.CPtr = llvmlite.Ptr(pool, llvmlite.Int8(pool)) - return HandlesExprCall._translate_t_type_cast(pool, builder, cast_arg, i8_ptr_ty_builtin) + return ExprCallCtor._translate_t_type_cast(pool, builder, cast_arg, i8_ptr_ty_builtin) return None elif string.strcmp(cast_fn_name, "int") == 0: # int(x) → i32 @@ -203,7 +207,7 @@ class CallGenDispatch(CallGenBase.CallGenBase): builder, pool, mod, cargs.get(0), funcs_ptr, func_count, trans) if cast_arg_int is not None: i32_ty_builtin: llvmlite.LLVMType | t.CPtr = llvmlite.Int32(pool) - return HandlesExprCall._translate_t_type_cast(pool, builder, cast_arg_int, i32_ty_builtin) + return ExprCallCtor._translate_t_type_cast(pool, builder, cast_arg_int, i32_ty_builtin) return None elif string.strcmp(cast_fn_name, "bool") == 0: # bool(x) → i1(严格 != 0 归一化) @@ -295,7 +299,7 @@ class CallGenDispatch(CallGenBase.CallGenBase): tc_arg_val: llvmlite.Value | t.CPtr = HandlesExpr.translate_value( builder, pool, mod, tc_arg_node, None, 0, trans) if tc_arg_val is not None: - return HandlesExprCall._translate_t_type_cast( + return ExprCallCtor._translate_t_type_cast( pool, builder, tc_arg_val, target_ty, func_name, tc_arg_node, trans) # t.XXX 类型转换已确认但不满足参数条件:返回 None,不跌落到跨模块 FATAL @@ -331,7 +335,7 @@ class CallGenDispatch(CallGenBase.CallGenBase): mt_arg_val: llvmlite.Value | t.CPtr = HandlesExpr.translate_value( builder, pool, mod, cargs.get(0), funcs_ptr, func_count, trans) if mt_arg_val is not None: - return HandlesExprCall._translate_t_type_cast( + return ExprCallCtor._translate_t_type_cast( pool, builder, mt_arg_val, mod_td_ty, func_name, cargs.get(0), trans) @@ -399,7 +403,7 @@ class CallGenDispatch(CallGenBase.CallGenBase): bare_arg_val: llvmlite.Value | t.CPtr = HandlesExpr.translate_value( builder, pool, mod, bare_arg_node, None, 0, trans) if bare_arg_val is not None: - return HandlesExprCall._translate_t_type_cast( + return ExprCallCtor._translate_t_type_cast( pool, builder, bare_arg_val, bare_ty, bare_fn_name, bare_arg_node, trans) if bare_ty is not None and can == 1: @@ -408,7 +412,7 @@ class CallGenDispatch(CallGenBase.CallGenBase): bare_arg_val: llvmlite.Value | t.CPtr = HandlesExpr.translate_value( builder, pool, mod, bare_arg_node, None, 0, trans) if bare_arg_val is not None: - return HandlesExprCall._translate_t_type_cast( + return ExprCallCtor._translate_t_type_cast( pool, builder, bare_arg_val, bare_ty, bare_fn_name, bare_arg_node, trans) @@ -513,7 +517,7 @@ class CallGenDispatch(CallGenBase.CallGenBase): if sub_sz.value is not None and sub_sz.value.kind() == ast.ASTKind.Name: gen_nm_sz: ast.Name | t.CPtr = (ast.Name | t.CPtr)(sub_sz.value) if gen_nm_sz.id is not None: - gen_args_sz: list[str] | t.CPtr = HandlesExprCall._extract_type_args_from_slice(pool, sub_sz.slice) + gen_args_sz: list[str] | t.CPtr = ExprCallCtor._extract_type_args_from_slice(pool, sub_sz.slice) if gen_args_sz is not None and len(gen_args_sz) > 0: gargs_resolved: list[str] | t.CPtr = list[str](pool, 8) if gargs_resolved is not None: @@ -655,7 +659,7 @@ class CallGenDispatch(CallGenBase.CallGenBase): len_arg_node, "len() 参数类型推断失败(结构体类名未知)", "TypeError") # list 内置 __len__:读 __count__(GEP 偏移 1,i64) - if HandlesExprCall._is_list_builtin_method(len_cls_nm, "__len__") != 0: + if ExprCallHandle._is_list_builtin_method(len_cls_nm, "__len__") != 0: i64_ty_lb: llvmlite.LLVMType | t.CPtr = llvmlite.Int64(pool) idx_one_lb: llvmlite.Value | t.CPtr = llvmlite.const_int64(pool, 1) cnt_ptr_lb: llvmlite.Value | t.CPtr = llvmlite.build_gep( @@ -772,7 +776,7 @@ class CallGenDispatch(CallGenBase.CallGenBase): if cl.func is not None and cl.func.kind() == ast.ASTKind.Name: if func_name is not None and string.strcmp(func_name, "isinstance") == 0: if can >= 2: - is_res: llvmlite.Value | t.CPtr = HandlesExprCall._translate_isinstance( + is_res: llvmlite.Value | t.CPtr = ExprCallHandle._translate_isinstance( pool, builder, mod, cargs.get(0), cargs.get(1), trans) if is_res is not None: return is_res @@ -826,10 +830,10 @@ class CallGenDispatch(CallGenBase.CallGenBase): rc_tag_sc: int = HandlesClassDef._lookup_renum_variant_in_class( st_nm.id, func_name) if rc_tag_sc >= 0: - return HandlesExprCall._translate_renum_construct( + return ExprCallCtor._translate_renum_construct( pool, builder, mod, st_nm.id, func_name, rc_tag_sc, cargs, can, trans) - st_res: llvmlite.Value | t.CPtr = HandlesExprCall._translate_static_class_call( + st_res: llvmlite.Value | t.CPtr = ExprCallCtor._translate_static_class_call( pool, builder, mod, st_nm.id, func_name, cl, trans) if st_res is not None: return st_res @@ -861,7 +865,7 @@ class CallGenDispatch(CallGenBase.CallGenBase): builder, pool, mod, cargs.get(ri_im + 1), None, 0, trans) if im_rv is not None: im_rem[ri_im] = t.CSizeT(im_rv) - im_res: llvmlite.Value | t.CPtr = HandlesExprCall._call_method_on_ptr( + im_res: llvmlite.Value | t.CPtr = ExprCallCtor._call_method_on_ptr( pool, builder, mod, st_nm.id, func_name, im_self, im_rem, can - 1, trans) if im_res is not None: @@ -878,7 +882,7 @@ class CallGenDispatch(CallGenBase.CallGenBase): if st_at2.value.kind() == ast.ASTKind.Name: # ClassName 是已注册结构体类名时尝试静态/类方法 if HandlesStruct.get_struct_type(st_at2.attr) is not None: - st_res2: llvmlite.Value | t.CPtr = HandlesExprCall._translate_static_class_call( + st_res2: llvmlite.Value | t.CPtr = ExprCallCtor._translate_static_class_call( pool, builder, mod, st_at2.attr, func_name, cl, trans) if st_res2 is not None: return st_res2 @@ -908,8 +912,8 @@ class CallGenDispatch(CallGenBase.CallGenBase): # _translate_method_call 会查 append 返回类型(函数/text.ll/ # vpi stub 均未命中)→ fail-fast。检测到 list 方法时 # 跳过 method_call,落到内置分支(NewAstTest body.append 根因)。 - if HandlesExprCall._is_list_builtin_method(class_nm, func_name) == 0: - return HandlesExprCall._translate_method_call( + if ExprCallHandle._is_list_builtin_method(class_nm, func_name) == 0: + return ExprCallCtor._translate_method_call( pool, builder, mod, class_nm, func_name, obj_var, cl, trans) # 指针变量: alloca 类型是 Ptr(Ptr(Struct)) @@ -920,18 +924,18 @@ class CallGenDispatch(CallGenBase.CallGenBase): pool, inner_struct_ty) if inner_nm is not None: # list 内置方法同样跳过(同 Ptr(Struct) 分支) - if HandlesExprCall._is_list_builtin_method(inner_nm, func_name) == 0: + if ExprCallHandle._is_list_builtin_method(inner_nm, func_name) == 0: obj_ptr: llvmlite.Value | t.CPtr = llvmlite.build_load( builder, obj_struct_ty, obj_var) if obj_ptr is not None: - return HandlesExprCall._translate_method_call( + return ExprCallCtor._translate_method_call( pool, builder, mod, inner_nm, func_name, obj_ptr, cl, trans) # FakeDuck: str/bytes 变量(Ptr(i8),AnnotClassName 为空) # 方法调用 → 扩展类 _Type/_str(a.type_id() / a.upper())。 # 前置拦截:常规结构体方法分支全落空时,尝试扩展类方法 # (find_func_in_module 未命中返回 None,不影响正常路径)。 - fd_name_res: llvmlite.Value | t.CPtr = HandlesExprCall._translate_fakeduck_call( + fd_name_res: llvmlite.Value | t.CPtr = ExprCallHandle._translate_fakeduck_call( pool, builder, mod, None, func_name, cl, trans) if fd_name_res is not None: return fd_name_res @@ -958,25 +962,25 @@ class CallGenDispatch(CallGenBase.CallGenBase): if HandlesStruct.get_struct_type(cls_nm2) is not None: # list 内置方法跳过 method_call(同 Ptr(Struct) 分支), # 落到下方 list 内置分支 - if HandlesExprCall._is_list_builtin_method(cls_nm2, func_name) == 0: + if ExprCallHandle._is_list_builtin_method(cls_nm2, func_name) == 0: # 结构体已注册:load obj_ptr 走方法调用 i8_ptr_ty2: llvmlite.LLVMType | t.CPtr = llvmlite.Ptr( pool, llvmlite.Int8(pool)) obj_ptr2: llvmlite.Value | t.CPtr = llvmlite.build_load( builder, i8_ptr_ty2, obj_var) if obj_ptr2 is not None: - return HandlesExprCall._translate_method_call( + return ExprCallCtor._translate_method_call( pool, builder, mod, cls_nm2, func_name, obj_ptr2, cl, trans) else: # list 内置方法跳过(结构体未注册路径同样不能 # 构造 {sha1}.{cls}.append 调用名——list 方法无此函数) - if HandlesExprCall._is_list_builtin_method(cls_nm2, func_name) == 0: + if ExprCallHandle._is_list_builtin_method(cls_nm2, func_name) == 0: # FakeDuck: str 变量方法调用 → 扩展类 _Type/_str # a.type_id() / a.upper() / " ".isspace() 等 # AnnotClassName=="str" 且对象是 char* 时触发, # self 用影子结构体 {a}__meta__(或临时影子)。 - fd_res: llvmlite.Value | t.CPtr = HandlesExprCall._translate_fakeduck_call( + fd_res: llvmlite.Value | t.CPtr = ExprCallHandle._translate_fakeduck_call( pool, builder, mod, cls_nm2, func_name, cl, trans) if fd_res is not None: return fd_res @@ -1115,13 +1119,13 @@ class CallGenDispatch(CallGenBase.CallGenBase): builder, pool, mod, expr_method_at.value, trans) if expr_addr is not None: expr_obj = expr_addr - return HandlesExprCall._translate_method_call( + return ExprCallCtor._translate_method_call( pool, builder, mod, expr_cls_nm, func_name, expr_obj, cl, trans) # FakeDuck: 表达式接收者解析失败且对象是 char* 时 # (如 " ".isspace()),尝试扩展类 _Type/_str 方法 # (self 用临时影子,对齐 TPC L2858-2873) - fd_expr_res: llvmlite.Value | t.CPtr = HandlesExprCall._translate_fakeduck_call( + fd_expr_res: llvmlite.Value | t.CPtr = ExprCallHandle._translate_fakeduck_call( pool, builder, mod, None, func_name, cl, trans) if fd_expr_res is not None: return fd_expr_res @@ -1188,7 +1192,7 @@ class CallGenDispatch(CallGenBase.CallGenBase): builder, pool, mod, attr_method_at.value, trans) if field_addr is not None: field_obj = field_addr - return HandlesExprCall._translate_method_call( + return ExprCallCtor._translate_method_call( pool, builder, mod, field_cls_nm, func_name, field_obj, cl, trans) diff --git a/App/lib/core/Gen/CallGenLib.vp b/App/lib/core/Gen/CallGenLib.vp index 4fba861..e1e7a46 100644 --- a/App/lib/core/Gen/CallGenLib.vp +++ b/App/lib/core/Gen/CallGenLib.vp @@ -27,6 +27,7 @@ import lib.core.CompilerFactory as CompilerFactory import lib.core.Gen.CallGenBase as CallGenBase +import lib.core.Handles.ExprCallCtor as ExprCallCtor # ============================================================ # CallGenLib - CallGenMixin 拆分(阶段 C):C 库声明 / 返回类型推断 / @@ -528,7 +529,7 @@ class CallGenLib(CallGenBase.CallGenBase): kw: ast.Keyword | t.CPtr = (ast.Keyword | t.CPtr)(keywords.get(ki)) if kw is None or kw.arg is None or kw.value is None: continue - if HandlesExprCall._kwarg_name_matches(kw.arg, param_name) == 1: + if ExprCallCtor._kwarg_name_matches(kw.arg, param_name) == 1: arg_val = HandlesExpr.translate_value( builder, pool, mod, kw.value, None, 0, trans) break diff --git a/App/lib/core/Gen/CallGenMixin.vp b/App/lib/core/Gen/CallGenMixin.vp index a3ce443..eb485ec 100644 --- a/App/lib/core/Gen/CallGenMixin.vp +++ b/App/lib/core/Gen/CallGenMixin.vp @@ -27,6 +27,11 @@ import lib.core.CompilerFactory as CompilerFactory import lib.core.Gen.CallGenBase as CallGenBase +import lib.core.Handles.ExprCallBase as ExprCallBase +import lib.core.Handles.ExprCallCall as ExprCallCall +import lib.core.Handles.ExprCallCtor as ExprCallCtor +import lib.core.Handles.ExprCallHandle as ExprCallHandle +import lib.core.Handles.ExprCallTable as ExprCallTable # ============================================================ @@ -92,7 +97,7 @@ class CallGenMixin(CallGenBase.CallGenBase): if cargs is not None: can = len(cargs) - _tc_h1_super_ctraits_res: llvmlite.Value | t.CPtr = HandlesExprCall._tc_h1_super_ctraits( + _tc_h1_super_ctraits_res: llvmlite.Value | t.CPtr = ExprCallHandle._tc_h1_super_ctraits( pool, builder, mod, cl, funcs_ptr, func_count, trans, func_name, cargs, can) if _tc_h1_super_ctraits_res is not None: return _tc_h1_super_ctraits_res @@ -110,7 +115,7 @@ class CallGenMixin(CallGenBase.CallGenBase): template_cd: ast.ClassDef | t.CPtr = HandlesClassDef._find_generic_template(gen_class_name) if template_cd is not None: # 提取类型实参 - gen_type_args: list[str] | t.CPtr = HandlesExprCall._extract_type_args_from_slice(pool, sub_node.slice) + gen_type_args: list[str] | t.CPtr = ExprCallCtor._extract_type_args_from_slice(pool, sub_node.slice) if gen_type_args is not None and len(gen_type_args) > 0: # 特化泛型类,返回特化类名 spec_name: str = HandlesClassDef._specialize_generic_class( @@ -119,7 +124,7 @@ class CallGenMixin(CallGenBase.CallGenBase): # 泛型类构造调用: list[str](pool, 8) → __new__ + __before_init__ + __init__ # 不能直接用 spec_name 作为 func_name(会走裸名调用路径, # 被 star import 回退误导用错误的 SHA1,且缺少 __new__ 方法名后缀) - return HandlesExprCall._translate_generic_ctor_call( + return ExprCallCtor._translate_generic_ctor_call( pool, builder, mod, spec_name, cl, trans) else: # 泛型类模板未找到:可能是泛型函数手动传类型参数调用 xxx[T](x) @@ -148,30 +153,30 @@ class CallGenMixin(CallGenBase.CallGenBase): binop_arg_val: llvmlite.Value | t.CPtr = HandlesExpr.translate_value( builder, pool, mod, binop_args.get(0), funcs_ptr, func_count, trans) if binop_arg_val is not None: - return HandlesExprCall._translate_t_type_cast(pool, builder, binop_arg_val, binop_ty) + return ExprCallCtor._translate_t_type_cast(pool, builder, binop_arg_val, binop_ty) return None - _tc_h2_c_special_res: llvmlite.Value | t.CPtr = HandlesExprCall._tc_h2_c_special( + _tc_h2_c_special_res: llvmlite.Value | t.CPtr = ExprCallHandle._tc_h2_c_special( pool, builder, mod, cl, funcs_ptr, func_count, trans, func_name, cargs, can) if _tc_h2_c_special_res is not None: return _tc_h2_c_special_res - _tc_h3_stdarg_cast_res: llvmlite.Value | t.CPtr = HandlesExprCall._tc_h3_stdarg_cast( + _tc_h3_stdarg_cast_res: llvmlite.Value | t.CPtr = ExprCallHandle._tc_h3_stdarg_cast( pool, builder, mod, cl, funcs_ptr, func_count, trans, func_name, cargs, can) if _tc_h3_stdarg_cast_res is not None: return _tc_h3_stdarg_cast_res - _tc_h4_type_casts_res: llvmlite.Value | t.CPtr = HandlesExprCall._tc_h4_type_casts( + _tc_h4_type_casts_res: llvmlite.Value | t.CPtr = ExprCallHandle._tc_h4_type_casts( pool, builder, mod, cl, funcs_ptr, func_count, trans, func_name, cargs, can) if _tc_h4_type_casts_res is not None: return _tc_h4_type_casts_res - _tc_h5_sizeof_len_isinst_res: llvmlite.Value | t.CPtr = HandlesExprCall._tc_h5_sizeof_len_isinst( + _tc_h5_sizeof_len_isinst_res: llvmlite.Value | t.CPtr = ExprCallHandle._tc_h5_sizeof_len_isinst( pool, builder, mod, cl, funcs_ptr, func_count, trans, func_name, cargs, can) if _tc_h5_sizeof_len_isinst_res is not None: return _tc_h5_sizeof_len_isinst_res - _tc_h6_method_dispatch_res: llvmlite.Value | t.CPtr = HandlesExprCall._tc_h6_method_dispatch( + _tc_h6_method_dispatch_res: llvmlite.Value | t.CPtr = ExprCallHandle._tc_h6_method_dispatch( pool, builder, mod, cl, funcs_ptr, func_count, trans, func_name, cargs, can) if _tc_h6_method_dispatch_res is not None: return _tc_h6_method_dispatch_res @@ -267,7 +272,7 @@ class CallGenMixin(CallGenBase.CallGenBase): if gen_ctor_entry is not None: ctor_is_oop = gen_ctor_entry.IsOOP if ctor_is_oop != 0: - return HandlesExprCall._translate_struct_ctor( + return ExprCallCtor._translate_struct_ctor( pool, builder, mod, struct_ty, func_name, cargs, 0, trans) # @t.NoVTable 类(无方法、类语义/指针对象):无参构造也应分配内存 # 返回指针。否则按值结构体返回 ConstZero(struct_ty),LHS 联合注解 @@ -277,7 +282,7 @@ class CallGenMixin(CallGenBase.CallGenBase): if gen_ctor_entry is not None: ctor_is_novt = gen_ctor_entry.IsNoVTable if ctor_is_novt != 0: - return HandlesExprCall._translate_struct_ctor( + return ExprCallCtor._translate_struct_ctor( pool, builder, mod, struct_ty, func_name, cargs, 0, trans) # 普通结构体:检查是否有默认值(用 entry 直接访问) gen_has_defaults: int = 0 @@ -292,18 +297,18 @@ class CallGenMixin(CallGenBase.CallGenBase): gen_has_defaults = HandlesStruct.struct_has_defaults(func_name) if gen_has_defaults == 1: # 有默认值:走构造函数路径应用默认值 - return HandlesExprCall._translate_struct_ctor( + return ExprCallCtor._translate_struct_ctor( pool, builder, mod, struct_ty, func_name, cargs, 0, trans) # 无默认值:返回 zeroinitializer ret: llvmlite.Value | t.CPtr = llvmlite.ConstZero(pool, struct_ty) return ret if kw_count > 0: # 有关键字参数:按字段名赋值 - return HandlesExprCall._translate_struct_ctor_kw( + return ExprCallCtor._translate_struct_ctor_kw( pool, builder, mod, struct_ty, func_name, cargs, can, keywords, kw_count, trans) # 仅位置参数:按字段顺序构建 - return HandlesExprCall._translate_struct_ctor( + return ExprCallCtor._translate_struct_ctor( pool, builder, mod, struct_ty, func_name, cargs, can, trans) # 裸名泛型类模板构造: Box(42) → 从实参推断类型实参 → 特化 → 构造 @@ -340,7 +345,7 @@ class CallGenMixin(CallGenBase.CallGenBase): if hint_bare is not None: hi_bare: t.CSizeT for hi_bare in range(can): - hty_bare: str = HandlesExprCall._infer_generic_ctor_type_arg(pool, cargs.get(hi_bare), func_name) + hty_bare: str = ExprCallCtor._infer_generic_ctor_type_arg(pool, cargs.get(hi_bare), func_name) if string.strcmp(hty_bare, "int") != 0: hint_bare.append(hty_bare) tpi_bare: t.CSizeT = 0 @@ -349,12 +354,12 @@ class CallGenMixin(CallGenBase.CallGenBase): if tpi_bare < len(hint_bare): ta_bare = hint_bare.get(tpi_bare) elif tpi_bare < can: - ta_bare = HandlesExprCall._infer_generic_ctor_type_arg(pool, cargs.get(tpi_bare), func_name) + ta_bare = ExprCallCtor._infer_generic_ctor_type_arg(pool, cargs.get(tpi_bare), func_name) inferred_args_bare.append(ta_bare) spec_name_bare: str = HandlesClassDef._specialize_generic_class( trans, func_name, inferred_args_bare) if spec_name_bare is not None: - return HandlesExprCall._translate_generic_ctor_call( + return ExprCallCtor._translate_generic_ctor_call( pool, builder, mod, spec_name_bare, cl, trans) # REnum 变体构造检测: ClassName.VariantName(args...) @@ -373,7 +378,7 @@ class CallGenMixin(CallGenBase.CallGenBase): rc_tag: int = HandlesClassDef._lookup_renum_variant_in_class( rc_cls_name, func_name) if rc_tag >= 0: - return HandlesExprCall._translate_renum_construct( + return ExprCallCtor._translate_renum_construct( pool, builder, mod, rc_cls_name, func_name, rc_tag, cargs, can, trans) @@ -507,7 +512,7 @@ class CallGenMixin(CallGenBase.CallGenBase): # C 库函数裸名调用支持:若模块中找不到且是已知 C 库函数,自动创建 declare # 对应 TPC 的 _C_LIB_FUNCS 机制,支持 memset/memmove/memcmp/strcmp 等裸名调用 if found_func is None and cl.func is not None and cl.func.kind() == ast.ASTKind.Name: - found_func = HandlesExprCall._ensure_c_lib_declare(pool, mod, func_name) + found_func = ExprCallBase._ensure_c_lib_declare(pool, mod, func_name) # builtins 自动关联:C 库未命中时,自动关联 builtins 模块的内置函数(ord/chr 等)。 # builtins 已由编译链预加入(StubMerger 预加入列表)。PhaseA 期 builtins 尚未编译, # 因此按约定签名创建 {builtins_sha1}.{name} 的 mangled declare(链接时解析到 @@ -576,18 +581,18 @@ class CallGenMixin(CallGenBase.CallGenBase): if vpi_ret_ty is not None: call_ret_ty = vpi_ret_ty else: - call_ret_ty = HandlesExprCall._infer_external_func_ret_ty(pool, func_name) + call_ret_ty = ExprCallBase._infer_external_func_ret_ty(pool, func_name) # 如果模块中找不到函数,检查是否是变量(函数指针 / 闭包调用) if found_func is None: fp_alloca: llvmlite.Value | t.CPtr = HandlesVar.lookup_var(trans.SymTab, func_name) if fp_alloca is not None: # 闭包变量(嵌套函数提升,已注册到闭包名集合):提取 fn_ptr/env_ptr 间接调用 - if HandlesExprCall.is_closure_name(func_name) != 0: - return HandlesExprCall.translate_closure_call(pool, builder, mod, fp_alloca, + if ExprCallCall.is_closure_name(func_name) != 0: + return ExprCallCall.translate_closure_call(pool, builder, mod, fp_alloca, cargs, can, trans) # 函数指针变量(t.Callable 注解 → i8** alloca):按实参构造签名间接调用 - if HandlesExprCall._is_func_ptr_alloca(fp_alloca) != 0: + if ExprCallCall._is_func_ptr_alloca(fp_alloca) != 0: # 区分 t.Callable(真函数指针)vs t.CPtr(闭包指针): # t.CPtr 变量(如 f: t.CPtr = make_counter())存的是闭包结构 # {fn_ptr, env_ptr},调用必须提取 env 传参;若按函数指针直接 @@ -599,18 +604,18 @@ class CallGenMixin(CallGenBase.CallGenBase): if string.strstr(ve_fp.AnnotClassName, "CPtr") is not None: is_cptr_annot_fp = 1 if is_cptr_annot_fp == 0: - return HandlesExprCall._translate_func_ptr_call(pool, builder, mod, fp_alloca, + return ExprCallCall._translate_func_ptr_call(pool, builder, mod, fp_alloca, func_name, cargs, can, trans) - return HandlesExprCall.translate_closure_call(pool, builder, mod, fp_alloca, + return ExprCallCall.translate_closure_call(pool, builder, mod, fp_alloca, cargs, can, trans) # 其他 i8* 变量按闭包调用路径处理 - return HandlesExprCall.translate_closure_call(pool, builder, mod, fp_alloca, + return ExprCallCall.translate_closure_call(pool, builder, mod, fp_alloca, cargs, can, trans) # 翻译参数并链接 # 有关键字参数且找到函数定义时,按参数名匹配 if kw_count > 0 and found_func is not None and found_params is not None: - return HandlesExprCall._translate_call_with_kwargs( + return ExprCallCtor._translate_call_with_kwargs( pool, builder, mod, func_name, found_func, cargs, can, keywords, kw_count, trans) @@ -644,7 +649,7 @@ class CallGenMixin(CallGenBase.CallGenBase): arg_val = decayed_fc case _: pass - ext_param_ty: llvmlite.LLVMType | t.CPtr = HandlesExprCall._get_external_func_param_ty( + ext_param_ty: llvmlite.LLVMType | t.CPtr = ExprCallBase._get_external_func_param_ty( pool, func_name, ai) if ext_param_ty is not None: val_bits_ap: int = HandlesExpr.get_llvm_type_bits(arg_val.Ty) @@ -703,7 +708,7 @@ class CallGenMixin(CallGenBase.CallGenBase): df_param_count: int = 0 # 先从当前模块函数表查找 FuncEntry if trans is not None and trans._funcs is not None: - df_entry: FuncEntry | t.CPtr = HandlesExprCall.find_func_entry_in_table( + df_entry: FuncEntry | t.CPtr = ExprCallTable.find_func_entry_in_table( trans._funcs, trans._func_count, func_name) if df_entry is not None: df_defaults = df_entry.Defaults @@ -714,7 +719,7 @@ class CallGenMixin(CallGenBase.CallGenBase): # 快照才是跨文件永久存活。同模块命中时 gd_entry 也必须已赋值, # 否则下方 _build_const_from_snapshot 读到未初始化栈垃圾指针崩溃。 # 与 _translate_method_call 的 mdf_gd 无条件查询(L2677)保持一致。 - gd_entry: FuncDefaultsEntry | t.CPtr = HandlesExprCall.find_func_defaults(func_name) + gd_entry: FuncDefaultsEntry | t.CPtr = ExprCallTable.find_func_defaults(func_name) if df_defaults is None and gd_entry is not None: df_defaults = gd_entry.Defaults df_default_count = gd_entry.DefaultCount @@ -729,7 +734,7 @@ class CallGenMixin(CallGenBase.CallGenBase): # 优先用 stdlib 常量快照重建(gd_entry.Defaults 的 pool 内 AST 可能已被 reset 回收) df_arg_val: llvmlite.Value | t.CPtr = None if gd_entry is not None: - df_arg_val = HandlesExprCall._build_const_from_snapshot( + df_arg_val = ExprCallTable._build_const_from_snapshot( pool, mod, gd_entry, df_di, trans, builder) if df_arg_val is None: df_defaults_list: list[ast.AST | t.CPtr] | t.CPtr = (list[ast.AST | t.CPtr] | t.CPtr)(t.CVoid(t.CUInt64T(df_defaults), t.CPtr)) @@ -959,13 +964,13 @@ class CallGenMixin(CallGenBase.CallGenBase): # 直接调用 # memcpy → @llvm.memcpy 内联函数(避免 monomorphization 跨模块 @memcpy 声明缺失) if string.strcmp(func_name, "memcpy") == 0 and can >= 3: - return HandlesExprCall._emit_llvm_memcpy_intrinsic(pool, builder, mod, mc_dst2, mc_src2, mc_num2) + return ExprCallBase._emit_llvm_memcpy_intrinsic(pool, builder, mod, mc_dst2, mc_src2, mc_num2) # 别名导入重新推断返回类型: # from X import parse as json_parse → func_name="json_parse" 时 _infer_external_func_ret_ty 返回默认 i32 # 用 orig_func_name="parse" 重新推断,能正确匹配返回 i8*(JsonValue*) # 避免指针被截断为 i32 后 inttoptr 丢失高 32 位导致崩溃 if orig_func_name is not None and orig_func_name != func_name: - re_inferred_ty: llvmlite.LLVMType | t.CPtr = HandlesExprCall._infer_external_func_ret_ty(pool, orig_func_name) + re_inferred_ty: llvmlite.LLVMType | t.CPtr = ExprCallBase._infer_external_func_ret_ty(pool, orig_func_name) if re_inferred_ty is not None: call_ret_ty = re_inferred_ty # ============================================================ @@ -979,7 +984,7 @@ class CallGenMixin(CallGenBase.CallGenBase): # 仅对 mangled("{16位hex}.func")调用生效;C 库/Win32 裸名走原白名单。 # Phase 1a(declare_only)期间依赖 text.ll 未生成,保持原白名单行为不 fail-fast。 # ============================================================ - if HandlesExprCall._is_sha1_mangled_call(call_name) != 0: + if ExprCallHandle._is_sha1_mangled_call(call_name) != 0: if trans is None or trans._declare_only == 0: cf_dot: str = string.strchr(call_name, '.') cf_last: str = string.strrchr(call_name, '.') @@ -1052,10 +1057,10 @@ class CallGenMixin(CallGenBase.CallGenBase): self._ensure_method_declare(pool, mod, call_name, call_ret_ty, head, can) # 检查被调用函数是否为变长函数(*args),若是则对变长参数进行 C ABI 提升 # (cargs 为本函数参数 AST 链表,self_offset=0 普通函数调用) - is_variadic_call: int = HandlesExprCall._check_and_promote_variadic_call( + is_variadic_call: int = ExprCallCall._check_and_promote_variadic_call( pool, builder, mod, call_name, head, can, cargs, 0, trans) # try-except:被调函数带 EH 输出参数时,追加输出实参 + 调用后检测异常 - return HandlesExprCall._emit_eh_guarded_call( + return ExprCallHandle._emit_eh_guarded_call( builder, pool, mod, trans, found_func, call_name, head, can, call_ret_ty, is_variadic_call) diff --git a/App/lib/core/Gen/CallGenVt.vp b/App/lib/core/Gen/CallGenVt.vp index 924bc40..423dbc3 100644 --- a/App/lib/core/Gen/CallGenVt.vp +++ b/App/lib/core/Gen/CallGenVt.vp @@ -27,6 +27,8 @@ import lib.core.CompilerFactory as CompilerFactory import lib.core.Gen.CallGenBase as CallGenBase +import lib.core.Handles.ExprCallBase as ExprCallBase +import lib.core.Handles.ExprCallHandle as ExprCallHandle # ============================================================ # CallGenVt - CallGenMixin 拆分(阶段 B):vtable 槽位写入 @@ -116,7 +118,7 @@ class CallGenVt(CallGenBase.CallGenBase): if vtable_ptr is None: return 0 # 类默认 vtable 地址(比较用) - class_vt: llvmlite.Value | t.CPtr = HandlesExprCall._make_vtable_ref_i8( + class_vt: llvmlite.Value | t.CPtr = ExprCallHandle._make_vtable_ref_i8( pool, builder, mod, class_name, trans) if class_vt is None: return 0 @@ -162,7 +164,7 @@ class CallGenVt(CallGenBase.CallGenBase): vt_size: llvmlite.Value | t.CPtr = llvmlite.ConstInt( pool, llvmlite.Int64(pool), method_count * 8, "vtsz") if vt_size is not None: - HandlesExprCall._emit_llvm_memcpy_intrinsic( + ExprCallBase._emit_llvm_memcpy_intrinsic( pool, builder, mod, vcopy_i8, class_vt, vt_size) llvmlite.build_store(builder, vcopy_i8, vtable_slot) llvmlite.build_br(builder, vt_skip_bb) diff --git a/App/lib/core/Gen/ClassGenVTable.vp b/App/lib/core/Gen/ClassGenVTable.vp index e8abe09..62660e5 100644 --- a/App/lib/core/Gen/ClassGenVTable.vp +++ b/App/lib/core/Gen/ClassGenVTable.vp @@ -21,6 +21,7 @@ import lib.core.CompilerFactory as CompilerFactory import lib.core.Gen.ClassGenBase as ClassGenBase +import lib.core.Handles.ExprCallTable as ExprCallTable # 方法元数据 flag:TLS(@t.TLS 装饰器,对齐 ClassGenBase 本地常量;本地副本避免跨模块 CDefine 查找) @@ -232,7 +233,7 @@ class ClassGenVTable(ClassGenBase.ClassGenBase): probe_buf: str = pool.alloc(128) if probe_buf is not None: viperlib.snprintf(probe_buf, 128, "%s.%s", anc, pmethod_name) - if HandlesExprCall.find_func_global(probe_buf) is not None: + if ExprCallTable.find_func_global(probe_buf) is not None: def_class = anc break mro_i += 1 @@ -407,15 +408,15 @@ class ClassGenVTable(ClassGenBase.ClassGenBase): parent_sha1: str = (str | t.CPtr)(t.CVoid(parent_sha1_addr, t.CPtr)) mangled_name: str = HandlesFunctions._mangle_name_with_sha1(parent_sha1, full_name) # 从全局函数表查找(跨模块函数不在当前模块表中) - func: llvmlite.Function | t.CPtr = HandlesExprCall.find_func_global(full_name) + func: llvmlite.Function | t.CPtr = ExprCallTable.find_func_global(full_name) else: # 当前类方法: 用当前模块 SHA1 mangled_name: str = HandlesFunctions._mangle_name(trans, full_name) - func: llvmlite.Function | t.CPtr = HandlesExprCall.find_func_in_table( + func: llvmlite.Function | t.CPtr = ExprCallTable.find_func_in_table( trans._funcs, trans._func_count, full_name) # 当前模块表找不到时,回退到全局表 if func is None: - func = HandlesExprCall.find_func_global(full_name) + func = ExprCallTable.find_func_global(full_name) # func 可能已被 1b reset_to(mark1) 回收(跨模块继承方法在定义文件翻译后被 reset)。 # 悬空指针非 NULL 但内容已被复用,_format_func_type_str 解引用会沿垃圾 Next 链 @@ -433,7 +434,7 @@ class ClassGenVTable(ClassGenBase.ClassGenBase): func_valid = 1 if func_valid == 0: # 回退到全局表完整 entry 的 TypeStr(stdlib 深拷贝,跨文件永久存活)。 - ge: HandlesExprCall.FuncEntry | t.CPtr = HandlesExprCall.find_func_entry_global(full_name) + ge: HandlesExprCall.FuncEntry | t.CPtr = ExprCallTable.find_func_entry_global(full_name) if ge is not None and ge.TypeStr is not None: self._vtable_strcat(init_buf, 16384, "i8* bitcast (") self._vtable_strcat(init_buf, 16384, ge.TypeStr) @@ -777,7 +778,7 @@ class ClassGenVTable(ClassGenBase.ClassGenBase): # 注册到函数表(用 ClassName.method_name 作为查找名,支持后缀匹配) max_funcs: int = 1024 - if HandlesExprCall.add_func_to_table(funcs_ptr, func_count, full_name, func, max_funcs, + if ExprCallTable.add_func_to_table(funcs_ptr, func_count, full_name, func, max_funcs, md_defaults, md_default_count, md_param_count, pool) == 0: trans._func_count = func_count + 1 @@ -842,7 +843,7 @@ class ClassGenVTable(ClassGenBase.ClassGenBase): llvmlite.add_param(pool, func, i1_ptr_ty_si, "%__stop_iter_flag__") # 参数添加完成,补全全局函数表的 TypeStr(供 vtable 在 func 被 reset 后使用) - HandlesExprCall.update_global_func_typestr(pool, full_name, func) + ExprCallTable.update_global_func_typestr(pool, full_name, func) # 创建 entry 块 entry_blk: llvmlite.BasicBlock | t.CPtr = llvmlite.create_block(pool, func, "entry") @@ -1174,7 +1175,7 @@ class ClassGenVTable(ClassGenBase.ClassGenBase): # 注册到函数表 max_funcs: int = 1024 - rc_add: int = HandlesExprCall.add_func_to_table(funcs_ptr, func_count, full_name, func, max_funcs, None, 0, 0, pool) + rc_add: int = ExprCallTable.add_func_to_table(funcs_ptr, func_count, full_name, func, max_funcs, None, 0, 0, pool) if rc_add == 0: trans._func_count = func_count + 1 @@ -1182,7 +1183,7 @@ class ClassGenVTable(ClassGenBase.ClassGenBase): llvmlite.add_param(pool, func, self_ptr_ty, "%self") # 参数添加完成,补全全局函数表的 TypeStr - rc_ut: int = HandlesExprCall.update_global_func_typestr(pool, full_name, func) + rc_ut: int = ExprCallTable.update_global_func_typestr(pool, full_name, func) # 创建 entry 块 + builder entry_blk: llvmlite.BasicBlock | t.CPtr = llvmlite.create_block(pool, func, "entry") diff --git a/App/lib/core/Gen/ExprGenAttr.vp b/App/lib/core/Gen/ExprGenAttr.vp index 802c7ff..a95f645 100644 --- a/App/lib/core/Gen/ExprGenAttr.vp +++ b/App/lib/core/Gen/ExprGenAttr.vp @@ -28,6 +28,7 @@ import lib.Projectrans.Utils as Utils import lib.core.Gen.ExprGenBase as ExprGenBase +import lib.core.Handles.ExprCallCtor as ExprCallCtor # ============================================================ # ExprGenAttr - ExprGenMixin 拆分(阶段 D):Attribute/属性访问/全局引用 @@ -735,7 +736,7 @@ class ExprGenAttr(ExprGenBase.ExprGenBase): # (字段未找到时先尝试,避免报误导性的"字段未找到"错误) if field_info is None and at.value is not None and trans is not None: prop_cls_fb: str = HandlesStruct.get_class_name_by_type(pool, struct_ty) - prop_val: llvmlite.Value | t.CPtr = HandlesExprCall._try_property_getter_attr( + prop_val: llvmlite.Value | t.CPtr = ExprCallCtor._try_property_getter_attr( pool, builder, mod, at, obj_ptr, trans, prop_cls_fb) if prop_val is not None: return prop_val diff --git a/App/lib/core/Gen/ExprGenBase.vp b/App/lib/core/Gen/ExprGenBase.vp index 0b75f16..c3b11fb 100644 --- a/App/lib/core/Gen/ExprGenBase.vp +++ b/App/lib/core/Gen/ExprGenBase.vp @@ -25,6 +25,7 @@ import lib.core.StubMerger as StubMerger import lib.core.VLogger as VLogger import lib.Projectrans.Config as Config import lib.Projectrans.Utils as Utils +import lib.core.Handles.ExprCallBase as ExprCallBase # ============================================================ @@ -347,7 +348,7 @@ class ExprGenBase: if lookup_ugi is None: return 0 viperlib.snprintf(lookup_ugi, 128, "%s.__getitem__", cls_ugi) - if HandlesExprCall.find_func_in_module(mod, lookup_ugi) is not None: + if ExprCallBase.find_func_in_module(mod, lookup_ugi) is not None: return 1 return 0 # ============================================================ diff --git a/App/lib/core/Gen/ExprGenCdef.vp b/App/lib/core/Gen/ExprGenCdef.vp index 62cfbf4..84b4fdc 100644 --- a/App/lib/core/Gen/ExprGenCdef.vp +++ b/App/lib/core/Gen/ExprGenCdef.vp @@ -30,6 +30,7 @@ import lib.Projectrans.Utils as Utils import lib.core.Gen.ExprGenBase as ExprGenBase import lib.core.StubMergerCollect as StubMergerCollect import lib.core.StubMergerStore as StubMergerStore +import lib.core.Handles.ExprCallBase as ExprCallBase # ============================================================ # ExprGenCdef - ExprGenMixin 拆分(阶段 D):跨模块 CDefine 查找 @@ -292,7 +293,7 @@ class ExprGenCdef(ExprGenBase.ExprGenBase): return -1 # 2. 截断模块名 → 去前导点 → 精确+后缀查找 SHA1(复用 HandlesExprCall 公共逻辑) - sha1: str = HandlesExprCall._lookup_sha1_from_modname_raw(pool, mod_name_raw) + sha1: str = ExprCallBase._lookup_sha1_from_modname_raw(pool, mod_name_raw) if sha1 is None: return -1 diff --git a/App/lib/core/Gen/ExprGenCls.vp b/App/lib/core/Gen/ExprGenCls.vp index b315c16..b137358 100644 --- a/App/lib/core/Gen/ExprGenCls.vp +++ b/App/lib/core/Gen/ExprGenCls.vp @@ -29,6 +29,7 @@ import lib.Projectrans.Utils as Utils import lib.core.Gen.ExprGenBase as ExprGenBase import lib.core.StubMergerStore as StubMergerStore +import lib.core.Handles.ExprCallBase as ExprCallBase # ============================================================ # ExprGenCls - ExprGenMixin 拆分(阶段 D):类名推断/docstring 登记 @@ -422,7 +423,7 @@ class ExprGenCls(ExprGenBase.ExprGenBase): if lookup_name is None: return 0 viperlib.snprintf(lookup_name, 128, "%s.%s", class_name, dunder) - if HandlesExprCall.find_func_in_module(mod, lookup_name) is not None: + if ExprCallBase.find_func_in_module(mod, lookup_name) is not None: return 1 # 继承链祖先查找 mro_ptr: t.CSizeT | t.CPtr = HandlesStruct.get_mro_chain(pool, class_name) @@ -433,7 +434,7 @@ class ExprGenCls(ExprGenBase.ExprGenBase): anc_lookup: str = pool.alloc(128) if anc_lookup is not None: viperlib.snprintf(anc_lookup, 128, "%s.%s", anc, dunder) - if HandlesExprCall.find_func_in_module(mod, anc_lookup) is not None: + if ExprCallBase.find_func_in_module(mod, anc_lookup) is not None: return 1 mi += 1 # 跨模块:类有 SHA1(stub 中声明该方法)视为存在 diff --git a/App/lib/core/Gen/ExprGenConst.vp b/App/lib/core/Gen/ExprGenConst.vp index f2128dd..30db3a0 100644 --- a/App/lib/core/Gen/ExprGenConst.vp +++ b/App/lib/core/Gen/ExprGenConst.vp @@ -28,6 +28,7 @@ import lib.Projectrans.Utils as Utils import lib.core.Gen.ExprGenBase as ExprGenBase +import lib.core.Handles.ExprCallCtor as ExprCallCtor # ============================================================ # ExprGenConst - ExprGenMixin 拆分(阶段 D):常量/全局字符串/list 字面量翻译 @@ -338,13 +339,13 @@ class ExprGenConst(ExprGenBase.ExprGenBase): return None string.memset(new_args, 0, 8 * 32) new_args[0] = t.CSizeT(pool_val) - new_ptr: llvmlite.Value | t.CPtr = HandlesExprCall._call_method_on_ptr( + new_ptr: llvmlite.Value | t.CPtr = ExprCallCtor._call_method_on_ptr( pool, builder, mod, spec_name, "__new__", tmp, new_args, 1, trans) if new_ptr is not None: storage_ptr = new_ptr # 调用 __before_init__(storage_ptr) - HandlesExprCall._call_method_on_ptr( + ExprCallCtor._call_method_on_ptr( pool, builder, mod, spec_name, "__before_init__", storage_ptr, None, 0, trans) # 调用 __init__(storage_ptr, pool_val, elem_size=0) @@ -355,7 +356,7 @@ class ExprGenConst(ExprGenBase.ExprGenBase): init_args[0] = t.CSizeT(pool_val) elem_size_val: llvmlite.Value | t.CPtr = llvmlite.const_int64(pool, 0) init_args[1] = t.CSizeT(elem_size_val) - HandlesExprCall._call_method_on_ptr( + ExprCallCtor._call_method_on_ptr( pool, builder, mod, spec_name, "__init__", storage_ptr, init_args, 2, trans) # 对每个元素调用 append(storage_ptr, elem_val) @@ -366,7 +367,7 @@ class ExprGenConst(ExprGenBase.ExprGenBase): if append_args is not None: string.memset(append_args, 0, 8 * 32) append_args[0] = t.CSizeT(first_elem_val) - HandlesExprCall._call_method_on_ptr( + ExprCallCtor._call_method_on_ptr( pool, builder, mod, spec_name, "append", storage_ptr, append_args, 1, trans) # 翻译剩余元素 @@ -379,7 +380,7 @@ class ExprGenConst(ExprGenBase.ExprGenBase): if ap_args is not None: string.memset(ap_args, 0, 8 * 32) ap_args[0] = t.CSizeT(elem_val_i) - HandlesExprCall._call_method_on_ptr( + ExprCallCtor._call_method_on_ptr( pool, builder, mod, spec_name, "append", storage_ptr, ap_args, 1, trans) i += 1 diff --git a/App/lib/core/Gen/ExprGenMixin.vp b/App/lib/core/Gen/ExprGenMixin.vp index d7211a8..1cc15ac 100644 --- a/App/lib/core/Gen/ExprGenMixin.vp +++ b/App/lib/core/Gen/ExprGenMixin.vp @@ -26,6 +26,7 @@ import lib.core.VLogger as VLogger import lib.Projectrans.Config as Config import lib.Projectrans.Utils as Utils import lib.core.Gen.ExprGenBase as ExprGenBase +import lib.core.Handles.ExprCallCall as ExprCallCall # ============================================================ # docstring 登记表容量(__doc__ 魔法属性支持) @@ -99,7 +100,7 @@ class ExprGenMixin(ExprGenBase.ExprGenBase): elif k == ast.ASTKind.BinOp: return HandlesExpr.translate_binop(pool, builder, mod, node, trans) elif k == ast.ASTKind.Call: - return HandlesExprCall.translate_call(pool, builder, mod, node, + return ExprCallCall.translate_call(pool, builder, mod, node, funcs_ptr, func_count, trans) elif k == ast.ASTKind.Compare: return HandlesExpr.translate_compare(builder, pool, mod, node, trans) diff --git a/App/lib/core/Gen/ExprGenName.vp b/App/lib/core/Gen/ExprGenName.vp index f3dee7b..cdb03bc 100644 --- a/App/lib/core/Gen/ExprGenName.vp +++ b/App/lib/core/Gen/ExprGenName.vp @@ -28,6 +28,8 @@ import lib.Projectrans.Utils as Utils import lib.core.Gen.ExprGenBase as ExprGenBase +import lib.core.Handles.ExprCallBase as ExprCallBase +import lib.core.Handles.ExprCallCtor as ExprCallCtor # ============================================================ # ExprGenName - ExprGenMixin 拆分(阶段 D):Name/Subscript/下标访问 @@ -178,7 +180,7 @@ class ExprGenName(ExprGenBase.ExprGenBase): # 最终打印出 `declare void @()` 空名函数。正确做法:按 Function 的 # RetTy/Params 构造真实函数类型,用 new_value 包装成普通 Value 再 bitcast。 if trans is not None and trans.Module is not None: - fn_ref: llvmlite.Function | t.CPtr = HandlesExprCall.find_func_in_module( + fn_ref: llvmlite.Function | t.CPtr = ExprCallBase.find_func_in_module( trans.Module, nm_id) if fn_ref is not None: fn_name: str = llvmlite.function_get_name(fn_ref) @@ -674,14 +676,14 @@ class ExprGenName(ExprGenBase.ExprGenBase): gi_lookup_rd: str = pool.alloc(128) if gi_lookup_rd is not None: viperlib.snprintf(gi_lookup_rd, 128, "%s.__getitem__", cls_nm_rd_ptr) - if HandlesExprCall.find_func_in_module(mod, gi_lookup_rd) is not None: + if ExprCallBase.find_func_in_module(mod, gi_lookup_rd) is not None: obj_ptr_rd: llvmlite.Value | t.CPtr = llvmlite.build_load( builder, pointee, alloca) if not (obj_ptr_rd is None): arg_vals_rd_p: t.CSizeT | t.CPtr = pool.alloc(8) if not (arg_vals_rd_p is None): arg_vals_rd_p[0] = t.CSizeT(idx_val) - ret_rd_p: llvmlite.Value | t.CPtr = HandlesExprCall._call_method_on_ptr( + ret_rd_p: llvmlite.Value | t.CPtr = ExprCallCtor._call_method_on_ptr( pool, builder, mod, cls_nm_rd_ptr, "__getitem__", obj_ptr_rd, arg_vals_rd_p, 1, trans, sub) if not (ret_rd_p is None): @@ -752,14 +754,14 @@ class ExprGenName(ExprGenBase.ExprGenBase): gi_lookup_sub: str = pool.alloc(128) if gi_lookup_sub is not None: viperlib.snprintf(gi_lookup_sub, 128, "%s.__getitem__", cls_nm_sub) - if HandlesExprCall.find_func_in_module(mod, gi_lookup_sub) is not None: + if ExprCallBase.find_func_in_module(mod, gi_lookup_sub) is not None: obj_val_sub: llvmlite.Value | t.CPtr = llvmlite.build_load( builder, pointee, alloca) if not (obj_val_sub is None): arg_vals_sub: t.CSizeT | t.CPtr = pool.alloc(8) if not (arg_vals_sub is None): arg_vals_sub[0] = t.CSizeT(idx_val) - ret_sub: llvmlite.Value | t.CPtr = HandlesExprCall._call_method_on_ptr( + ret_sub: llvmlite.Value | t.CPtr = ExprCallCtor._call_method_on_ptr( pool, builder, mod, cls_nm_sub, "__getitem__", obj_val_sub, arg_vals_sub, 1, trans, sub) if not (ret_sub is None): @@ -803,11 +805,11 @@ class ExprGenName(ExprGenBase.ExprGenBase): gi_lookup_gen: str = pool.alloc(128) if gi_lookup_gen is not None: viperlib.snprintf(gi_lookup_gen, 128, "%s.__getitem__", cls_nm_rd_gen) - if HandlesExprCall.find_func_in_module(mod, gi_lookup_gen) is not None: + if ExprCallBase.find_func_in_module(mod, gi_lookup_gen) is not None: arg_vals_rd_g: t.CSizeT | t.CPtr = pool.alloc(8) if not (arg_vals_rd_g is None): arg_vals_rd_g[0] = t.CSizeT(idx_val) - ret_rd_g: llvmlite.Value | t.CPtr = HandlesExprCall._call_method_on_ptr( + ret_rd_g: llvmlite.Value | t.CPtr = ExprCallCtor._call_method_on_ptr( pool, builder, mod, cls_nm_rd_gen, "__getitem__", ptr_val, arg_vals_rd_g, 1, trans, sub) if not (ret_rd_g is None): @@ -886,7 +888,7 @@ class ExprGenName(ExprGenBase.ExprGenBase): si_lookup_gsp: str = pool.alloc(128) if si_lookup_gsp is not None: viperlib.snprintf(si_lookup_gsp, 128, "%s.__setitem__", cls_nm_ptr_chk) - if HandlesExprCall.find_func_in_module(mod, si_lookup_gsp) is not None: + if ExprCallBase.find_func_in_module(mod, si_lookup_gsp) is not None: return None # bytes|t.CPtr / str|t.CPtr: alloca 是 i8**, # 直接 GEP 按 i8* 步长(8 字节),不 load diff --git a/App/lib/core/Gen/ExprGenOps.vp b/App/lib/core/Gen/ExprGenOps.vp index 9a975ee..b5a0666 100644 --- a/App/lib/core/Gen/ExprGenOps.vp +++ b/App/lib/core/Gen/ExprGenOps.vp @@ -28,6 +28,8 @@ import lib.Projectrans.Utils as Utils import lib.core.Gen.ExprGenBase as ExprGenBase +import lib.core.Handles.ExprCallBase as ExprCallBase +import lib.core.Handles.ExprCallCtor as ExprCallCtor # ============================================================ # ExprGenOps - ExprGenMixin 拆分(阶段 D):比较/一元/布尔/binop 运算 @@ -417,7 +419,7 @@ class ExprGenOps(ExprGenBase.ExprGenBase): cn_lookup: str = pool.alloc(128) if cn_lookup is not None: viperlib.snprintf(cn_lookup, 128, "%s.__contains__", cn_cls) - cn_fn: llvmlite.Function | t.CPtr = HandlesExprCall.find_func_in_module( + cn_fn: llvmlite.Function | t.CPtr = ExprCallBase.find_func_in_module( mod, cn_lookup) if cn_fn is not None: cn_ret: llvmlite.LLVMType | t.CPtr = llvmlite.function_get_ret_ty(cn_fn) @@ -917,7 +919,7 @@ class ExprGenOps(ExprGenBase.ExprGenBase): if lookup_name is None: return None viperlib.snprintf(lookup_name, 128, "%s.%s", class_name, dunder) - found_func: llvmlite.Function | t.CPtr = HandlesExprCall.find_func_in_module(mod, lookup_name) + found_func: llvmlite.Function | t.CPtr = ExprCallBase.find_func_in_module(mod, lookup_name) search_class: str = class_name if found_func is None: @@ -930,7 +932,7 @@ class ExprGenOps(ExprGenBase.ExprGenBase): parent_lookup: str = pool.alloc(128) if parent_lookup is not None: viperlib.snprintf(parent_lookup, 128, "%s.%s", anc, dunder) - parent_func: llvmlite.Function | t.CPtr = HandlesExprCall.find_func_in_module(mod, parent_lookup) + parent_func: llvmlite.Function | t.CPtr = ExprCallBase.find_func_in_module(mod, parent_lookup) if parent_func is not None: found_func = parent_func search_class = anc @@ -969,7 +971,7 @@ class ExprGenOps(ExprGenBase.ExprGenBase): # vpi 未命中(依赖模块确实无此 dunder)→ 回退原生比较(icmp), # 绝不发幽灵 call——`call @{cls_sha1}.{Class}.{dunder}` 链接 undefined # (MemBuddy 无 __eq__ 时 os._mbuddy == sys._mbuddy,SysLibTest 根因)。 - vpi_dup: llvmlite.LLVMType | t.CPtr = HandlesExprCall._lookup_method_ret_ty_via_vpi( + vpi_dup: llvmlite.LLVMType | t.CPtr = ExprCallCtor._lookup_method_ret_ty_via_vpi( pool, cls_sha1, search_class, dunder) if vpi_dup is None: return None @@ -981,7 +983,7 @@ class ExprGenOps(ExprGenBase.ExprGenBase): extra_args[0] = t.CSizeT(rhs) # 调用方法: lhs.__dunder__(rhs) - return HandlesExprCall._call_method_on_ptr( + return ExprCallCtor._call_method_on_ptr( pool, builder, mod, search_class, dunder, lhs, extra_args, 1, trans) # ============================================================ @@ -1024,7 +1026,7 @@ class ExprGenOps(ExprGenBase.ExprGenBase): if lookup_name is None: return None viperlib.snprintf(lookup_name, 128, "%s.%s", class_name, dunder) - found_func: llvmlite.Function | t.CPtr = HandlesExprCall.find_func_in_module(mod, lookup_name) + found_func: llvmlite.Function | t.CPtr = ExprCallBase.find_func_in_module(mod, lookup_name) search_class: str = class_name if found_func is None: @@ -1037,7 +1039,7 @@ class ExprGenOps(ExprGenBase.ExprGenBase): parent_lookup: str = pool.alloc(128) if parent_lookup is not None: viperlib.snprintf(parent_lookup, 128, "%s.%s", anc, dunder) - parent_func: llvmlite.Function | t.CPtr = HandlesExprCall.find_func_in_module(mod, parent_lookup) + parent_func: llvmlite.Function | t.CPtr = ExprCallBase.find_func_in_module(mod, parent_lookup) if parent_func is not None: found_func = parent_func search_class = anc @@ -1071,7 +1073,7 @@ class ExprGenOps(ExprGenBase.ExprGenBase): return None # 一元方法无额外参数(extra_args 为空) - return HandlesExprCall._call_method_on_ptr( + return ExprCallCtor._call_method_on_ptr( pool, builder, mod, search_class, dunder, operand, None, 0, trans) # ============================================================ diff --git a/App/lib/core/Gen/FuncGenDef.vp b/App/lib/core/Gen/FuncGenDef.vp index 31aaa85..5062afe 100644 --- a/App/lib/core/Gen/FuncGenDef.vp +++ b/App/lib/core/Gen/FuncGenDef.vp @@ -17,6 +17,9 @@ import lib.core.Handles.HandlesType as HandlesType import lib.core.Handles.HandlesBody as HandlesBody import lib.core.Handles.HandlesImports as HandlesImports import lib.core.Handles.HandlesClassDef as HandlesClassDef +import lib.core.Handles.ExprCallBase as ExprCallBase +import lib.core.Handles.ExprCallHandle as ExprCallHandle +import lib.core.Handles.ExprCallTable as ExprCallTable # ============================================================ @@ -129,10 +132,10 @@ class FuncGenDef(CallGenBase.CallGenBase): if has_extern != 0 or has_state != 0 or has_export != 0 or string.strcmp(fd.name, "main") == 0: mangled_name: str = fd.name else: - mangled_name = HandlesExprCall._mangle_func_name(trans, fd.name, 0) + mangled_name = ExprCallHandle._mangle_func_name(trans, fd.name, 0) # 如果函数已存在(如重复定义),跳过 - existing: llvmlite.Function | t.CPtr = HandlesExprCall.find_func_in_module(mod, mangled_name) + existing: llvmlite.Function | t.CPtr = ExprCallBase.find_func_in_module(mod, mangled_name) if existing is not None: continue @@ -162,14 +165,14 @@ class FuncGenDef(CallGenBase.CallGenBase): # 注册到函数表(用裸名 fd.name,不是 mangled_name) max_funcs: int = 1024 cur_count: int = trans._func_count - if HandlesExprCall.add_func_to_table(funcs_ptr, cur_count, fd.name, func, max_funcs, + if ExprCallTable.add_func_to_table(funcs_ptr, cur_count, fd.name, func, max_funcs, fd_defaults, fd_default_count, fd_param_count, trans.Pool) == 0: trans._func_count = cur_count + 1 # 注册 CExport 函数到全局表 if (has_export != 0 or has_state != 0) and trans.ModuleSha1 is not None: - HandlesExprCall.register_cexport_func(trans.ModuleSha1, fd.name) + ExprCallBase.register_cexport_func(trans.ModuleSha1, fd.name) # 添加参数 args_node: ast.Arguments | t.CPtr = fd.args @@ -210,7 +213,7 @@ class FuncGenDef(CallGenBase.CallGenBase): func.IsVarArg = 1 # 参数添加完成,补全全局函数表的 TypeStr(供 vtable 在 func 被 reset 后使用) - HandlesExprCall.update_global_func_typestr(trans.Pool, fd.name, func) + ExprCallTable.update_global_func_typestr(trans.Pool, fd.name, func) # 恢复原始声明模式 trans._declare_only = saved_declare_only @@ -353,17 +356,17 @@ class FuncGenDef(CallGenBase.CallGenBase): if has_extern != 0 or has_state != 0 or has_export != 0 or string.strcmp(fd.name, "main") == 0: mangled_name: str = fd.name else: - mangled_name: str = HandlesExprCall._mangle_func_name(trans, fd.name, 0) + mangled_name: str = ExprCallHandle._mangle_func_name(trans, fd.name, 0) # 注册 CExport 函数到全局表(供跨模块调用查表) # t.CExport 函数定义用裸名(@strlen),跨模块调用需查表确认用裸名而非 @{sha1}.func if (has_export != 0 or has_state != 0) and trans.ModuleSha1 is not None: - HandlesExprCall.register_cexport_func(trans.ModuleSha1, fd.name) + ExprCallBase.register_cexport_func(trans.ModuleSha1, fd.name) if is_extern_decl != 0: # 外部声明函数:生成 declare(仅声明,不定义) # 先检查是否已由 forward_declare_functions 创建,避免重复 declare - existing_extern: llvmlite.Function | t.CPtr = HandlesExprCall.find_func_in_module(mod, mangled_name) + existing_extern: llvmlite.Function | t.CPtr = ExprCallBase.find_func_in_module(mod, mangled_name) if existing_extern is not None: # 已存在前向声明,复用之,不再重复创建 return 0 @@ -375,7 +378,7 @@ class FuncGenDef(CallGenBase.CallGenBase): # 注册到函数表 max_funcs_extern: int = 256 - if HandlesExprCall.add_func_to_table(funcs_ptr, func_count, fd.name, func, max_funcs_extern, None, 0, 0, pool) == 0: + if ExprCallTable.add_func_to_table(funcs_ptr, func_count, fd.name, func, max_funcs_extern, None, 0, 0, pool) == 0: trans._func_count = func_count + 1 # 添加参数(支持类型注解) @@ -419,12 +422,12 @@ class FuncGenDef(CallGenBase.CallGenBase): llvmlite.add_param(pool, func, param_ty_e, pname_e) # 提取 @c.Attribute 装饰器属性并设置到函数 - func_attrs_e: str = HandlesExprCall.extract_func_attrs(pool, fd.decorator_list, imported_modules) + func_attrs_e: str = ExprCallHandle.extract_func_attrs(pool, fd.decorator_list, imported_modules) if func_attrs_e is not None: llvmlite.function_set_attrs(func, func_attrs_e) # 参数添加完成,补全全局函数表的 TypeStr - HandlesExprCall.update_global_func_typestr(pool, fd.name, func) + ExprCallTable.update_global_func_typestr(pool, fd.name, func) return 0 @@ -432,12 +435,12 @@ class FuncGenDef(CallGenBase.CallGenBase): args_node: ast.Arguments | t.CPtr = fd.args # 检查是否已有前向声明(由 forward_declare_functions 创建) - func: llvmlite.Function | t.CPtr = HandlesExprCall.find_func_in_module(mod, mangled_name) + func: llvmlite.Function | t.CPtr = ExprCallBase.find_func_in_module(mod, mangled_name) if func is not None and llvmlite.function_is_declared(func) != 0: # 复用前向声明:清除 IsDeclared 标记,转为 define func.IsDeclared = 0 # 装饰器属性设置(前向声明时未设置) - func_attrs_reuse: str = HandlesExprCall.extract_func_attrs(pool, fd.decorator_list, imported_modules) + func_attrs_reuse: str = ExprCallHandle.extract_func_attrs(pool, fd.decorator_list, imported_modules) if func_attrs_reuse is not None: llvmlite.function_set_attrs(func, func_attrs_reuse) else: @@ -451,7 +454,7 @@ class FuncGenDef(CallGenBase.CallGenBase): return 0 # 提取 @c.Attribute 装饰器属性并设置到函数 - func_attrs: str = HandlesExprCall.extract_func_attrs(pool, fd.decorator_list, imported_modules) + func_attrs: str = ExprCallHandle.extract_func_attrs(pool, fd.decorator_list, imported_modules) if func_attrs is not None: llvmlite.function_set_attrs(func, func_attrs) @@ -471,7 +474,7 @@ class FuncGenDef(CallGenBase.CallGenBase): # 注册到函数表 max_funcs: int = 1024 - if HandlesExprCall.add_func_to_table(funcs_ptr, func_count, fd.name, func, max_funcs, + if ExprCallTable.add_func_to_table(funcs_ptr, func_count, fd.name, func, max_funcs, tfd_defaults, tfd_default_count, tfd_param_count, trans.Pool) == 0: trans._func_count = func_count + 1 @@ -522,7 +525,7 @@ class FuncGenDef(CallGenBase.CallGenBase): # (def f())的 args_node 为 None,若放在其内会被跳过,导致函数体 # store %__eh_code_out__ 但签名无此参数(llc: use of undefined value)。 if string.strcmp(fd.name, "main") != 0: - if HandlesExprCall._body_has_raise(fd) != 0: + if ExprCallHandle._body_has_raise(fd) != 0: i8_ty_eh: llvmlite.LLVMType | t.CPtr = llvmlite.Int8(pool) i8_ptr_ty_eh: llvmlite.LLVMType | t.CPtr = llvmlite.Ptr(pool, i8_ty_eh) i8_ptr_ptr_ty_eh: llvmlite.LLVMType | t.CPtr = llvmlite.Ptr(pool, i8_ptr_ty_eh) @@ -533,7 +536,7 @@ class FuncGenDef(CallGenBase.CallGenBase): llvmlite.add_param(pool, func, i32_ptr_ty_eh, "%__eh_code_out__") # 参数添加完成,补全全局函数表的 TypeStr - HandlesExprCall.update_global_func_typestr(trans.Pool, fd.name, func) + ExprCallTable.update_global_func_typestr(trans.Pool, fd.name, func) # 创建 entry 块 entry_blk: llvmlite.BasicBlock | t.CPtr = llvmlite.create_block(pool, func, "entry") @@ -731,7 +734,7 @@ class FuncGenDef(CallGenBase.CallGenBase): # try-except:保存当前函数的 EH 输出参数(__eh_msg_out__/__eh_code_out__) # 供 translate_raise / UnhandledBB 写入并向上传播。无 EH 参数的函数置空。 - if string.strcmp(fd.name, "main") != 0 and HandlesExprCall._body_has_raise(fd) != 0: + if string.strcmp(fd.name, "main") != 0 and ExprCallHandle._body_has_raise(fd) != 0: i8_ty_eh2: llvmlite.LLVMType | t.CPtr = llvmlite.Int8(pool) i8_ptr_ty_eh2: llvmlite.LLVMType | t.CPtr = llvmlite.Ptr(pool, i8_ty_eh2) i8_ptr_ptr_ty_eh2: llvmlite.LLVMType | t.CPtr = llvmlite.Ptr(pool, i8_ptr_ty_eh2) @@ -788,7 +791,7 @@ class FuncGenDef(CallGenBase.CallGenBase): # 嵌套函数定义前:预扫描其链内 nonlocal 并建堆 # (不同层捕获不同变量的场景,见 _prepare_chain_nonlocals) if stmt2.kind() == ast.ASTKind.FunctionDef: - HandlesExprCall._prepare_chain_nonlocals( + ExprCallHandle._prepare_chain_nonlocals( trans, stmt2, pool, func_builder, mod, llvmlite.Int8(pool), llvmlite.Ptr(pool, llvmlite.Int8(pool))) HandlesBody.translate_stmt(trans, stmt2) @@ -1126,7 +1129,7 @@ class FuncGenDef(CallGenBase.CallGenBase): fn_str = llvmlite.ConstNull(pool, i8_ptr_ty, "null") # 5. handler 声明(未翻译时 declare,固定签名 i32 (i8*,i8*,i32,i8*,i8*,i8*)) - if HandlesExprCall.find_func_in_module(mod, handler_name) is None: + if ExprCallBase.find_func_in_module(mod, handler_name) is None: handler_d: llvmlite.Function | t.CPtr = llvmlite.create_declare( pool, mod, handler_name, i32_ty) if handler_d is not None: diff --git a/App/lib/core/Gen/FuncGenMixin.vp b/App/lib/core/Gen/FuncGenMixin.vp index 666ee6d..4fad5cd 100644 --- a/App/lib/core/Gen/FuncGenMixin.vp +++ b/App/lib/core/Gen/FuncGenMixin.vp @@ -18,6 +18,8 @@ import lib.core.Handles.HandlesBody as HandlesBody import lib.core.Handles.HandlesImports as HandlesImports import lib.core.Handles.HandlesClassDef as HandlesClassDef import lib.core.Gen.CallGenBase as CallGenBase +import lib.core.Handles.ExprCallCall as ExprCallCall +import lib.core.Handles.ExprCallHandle as ExprCallHandle # ============================================================ @@ -99,7 +101,7 @@ class FuncGenMixin(CallGenBase.CallGenBase): promoted_name: str = pool.alloc(64) if promoted_name is not None: viperlib.snprintf(promoted_name, 64, "__closure_%s", func_name) - mangled_promoted: str = HandlesExprCall._mangle_name(trans, promoted_name) + mangled_promoted: str = ExprCallHandle._mangle_name(trans, promoted_name) # 2. 创建提升后的函数: define i32 @__closure_{name}(i8* %env, args...) func: llvmlite.Function | t.CPtr = llvmlite.create_function( @@ -459,7 +461,7 @@ class FuncGenMixin(CallGenBase.CallGenBase): HandlesVar.define_var(trans.SymTab, func_name, closure_alloca) # 注册闭包变量名(供调用时区分闭包 vs 函数指针变量, # 两者 alloca 类型同为 i8**,_is_func_ptr_alloca 无法区分) - HandlesExprCall.register_closure_name(func_name) + ExprCallCall.register_closure_name(func_name) # 14. 恢复 scope names(含 nonlocal 集合指针) trans._cur_func_name = old_func_name @@ -515,7 +517,7 @@ class FuncGenMixin(CallGenBase.CallGenBase): """构造 nonlocal 堆地址全局映射变量名 nlheap_{sha1}.{name}""" if pool is None or trans is None or name is None: return None - mangled: str = HandlesExprCall._mangle_name(trans, name) + mangled: str = ExprCallHandle._mangle_name(trans, name) buf: str = pool.alloc(160) if buf is not None: viperlib.snprintf(buf, 160, "nlheap_%s", mangled) @@ -745,7 +747,7 @@ class FuncGenMixin(CallGenBase.CallGenBase): if pname_buf is None: return None viperlib.snprintf(pname_buf, 64, "__lambda_%d", lambda_id) - mangled_promoted: str = HandlesExprCall._mangle_name(trans, pname_buf) + mangled_promoted: str = ExprCallHandle._mangle_name(trans, pname_buf) # 2. 解析参数(名称 + 类型,类型默认 i32,有注解则解析) param_names: str = pool.alloc(32 * 64) # 64 参数 × 32 字节名 diff --git a/App/lib/core/Gen/StmtGenMixin.vp b/App/lib/core/Gen/StmtGenMixin.vp index 1259d56..51f9937 100644 --- a/App/lib/core/Gen/StmtGenMixin.vp +++ b/App/lib/core/Gen/StmtGenMixin.vp @@ -27,6 +27,8 @@ import lib.core.Handles.HandlesEnum as HandlesEnum import lib.core.CompilerFactory as CompilerFactory import lib.Projectrans.Config as Config import lib.core.Gen.StmtGenDeclMixin as StmtGenDeclMixin +import lib.core.Handles.ExprCallBase as ExprCallBase +import lib.core.Handles.ExprCallCtor as ExprCallCtor # ============================================================ @@ -128,7 +130,7 @@ class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin): if tgt.kind() == ast.ASTKind.Attribute: del_at: ast.Attribute | t.CPtr = (ast.Attribute | t.CPtr)(tgt) if del_at is not None: - HandlesExprCall._try_property_deleter( + ExprCallCtor._try_property_deleter( pool, builder, mod, del_at, trans) # del obj[key] → __delitem__(obj, key) # (对齐 TPC HandlesDelete.py L14-25;此前 Subscript 目标被静默 @@ -149,7 +151,7 @@ class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin): dl_lookup: str = pool.alloc(128) if dl_lookup is not None: viperlib.snprintf(dl_lookup, 128, "%s.__delitem__", dl_cls) - dl_fn: llvmlite.Function | t.CPtr = HandlesExprCall.find_func_in_module( + dl_fn: llvmlite.Function | t.CPtr = ExprCallBase.find_func_in_module( mod, dl_lookup) if dl_fn is not None: dl_ret: llvmlite.LLVMType | t.CPtr = llvmlite.function_get_ret_ty(dl_fn) diff --git a/App/lib/core/Gen/TranslatorGenMixin.vp b/App/lib/core/Gen/TranslatorGenMixin.vp index b73090b..776b621 100644 --- a/App/lib/core/Gen/TranslatorGenMixin.vp +++ b/App/lib/core/Gen/TranslatorGenMixin.vp @@ -17,6 +17,7 @@ import lib.core.Handles.HandlesFunctions as HandlesFunctions import lib.core.Handles.HandlesType as HandlesType import lib.core.Handles.HandlesClassDef as HandlesClassDef import lib.core.Handles.HandlesAnnAssign as HandlesAnnAssign +import lib.core.Handles.ExprCallBase as ExprCallBase # ============================================================ @@ -80,7 +81,7 @@ class TranslatorGenMixin: has_state = HandlesType.has_decorator_marker(fd.returns, "State") if has_export != 0 or has_state != 0: - HandlesExprCall.register_cexport_func(trans.ModuleSha1, fd.name) + ExprCallBase.register_cexport_func(trans.ModuleSha1, fd.name) return 0 diff --git a/App/lib/core/Gen/TypeGenResolve.vp b/App/lib/core/Gen/TypeGenResolve.vp index b854d8b..06b5604 100644 --- a/App/lib/core/Gen/TypeGenResolve.vp +++ b/App/lib/core/Gen/TypeGenResolve.vp @@ -25,6 +25,7 @@ import lib.core.CompilerFactory as CompilerFactory import lib.core.Gen.TypeGenBase as TypeGenBase +import lib.core.Handles.ExprCallCtor as ExprCallCtor # ============================================================ # TypeGenResolve - TypeGenMixin 拆分(阶段 D):类型映射/注解解析(map_t_type/resolve_annotation_type 等) @@ -895,7 +896,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): import lib.core.Handles.HandlesExprCall as HandlesExprCall template_cd_chk: ast.ClassDef | t.CPtr = HandlesClassDef._find_generic_template(gen_cls_name) if template_cd_chk is not None: - type_args_chk: list[str] | t.CPtr = HandlesExprCall._extract_type_args_from_slice( + type_args_chk: list[str] | t.CPtr = ExprCallCtor._extract_type_args_from_slice( pool, sub.slice) if type_args_chk is not None and len(type_args_chk) > 0: # 错误定位:压入触发特化的调用方帧(注解所在文件+行号) diff --git a/App/lib/core/Handles/ExprCallBase.vp b/App/lib/core/Handles/ExprCallBase.vp new file mode 100644 index 0000000..168f4af --- /dev/null +++ b/App/lib/core/Handles/ExprCallBase.vp @@ -0,0 +1,246 @@ +import t, c +from stdint import * +import ast +import llvmlite +import memhub +import string +import stdio +import stdlib +import sys +import viperlib +import w32.fileio as fileio +import lib.core.VLogger as VLogger +import lib.core.Handles.HandlesBase as HandlesBase +import lib.core.Handles.HandlesTranslator as HT +import lib.core.Handles.HandlesExpr as HandlesExpr +import lib.core.Handles.HandlesVar as HandlesVar +import lib.core.Handles.HandlesType as HandlesType +import lib.core.Handles.HandlesNonlocal as HandlesNonlocal +import lib.core.Handles.HandlesStruct as HandlesStruct +import lib.core.Handles.HandlesImports as HandlesImports +import lib.core.Handles.HandlesClassDef as HandlesClassDef +import lib.core.StubMerger as StubMerger + + +import lib.core.Handles.ExprCallDeref as ExprCallDeref +import lib.core.Handles.ExprCallCtor as ExprCallCtor +import lib.core.Handles.ExprCallCall as ExprCallCall +import lib.core.Handles.ExprCallTable as ExprCallTable +import lib.core.Handles.ExprCallHandle as ExprCallHandle +import lib.core.Handles.HandlesExprCall as HandlesExprCall + +# ============================================================ +# ExprCallBase - HandlesExprCall 拆分(阶段 E):ExprCallBase +# +# 直接移动模式:委托函数迁至此模块,原 HandlesExprCall.vp 仅 +# 保留 _g_gen/常量/类;调用方经本模块前缀访问。 +# ============================================================ + +# ============================================================ +# _lookup_module_sha1 — 按模块名查找 SHA1(委托到 gen._lookup_module_sha1) +# ============================================================ + + +# ============================================================ +# 模块 SHA1 查询(委托给 StubMerger 全局存储器) +# +# 翻译时用于跨模块函数调用名混淆: +# string.strchr(...) → call @{sha1_of_string}.strchr(...) +# +# 数据来源是 StubMerger.PopulateSha1MapStore/AppendToSha1MapStore +# 填充的全局存储器,不再维护独立的 SHA1 映射表副本。 +# ============================================================ + +def _lookup_module_sha1(mod_name: str) -> str: + """查找模块名对应的 SHA1,找不到返回 None(委托到 gen._lookup_module_sha1)""" + import lib.core.Gen.Generator as Generator + g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr)) + if g is not None: + return g._lookup_module_sha1(mod_name) + return None +def _lookup_module_sha1_suffix(mod_suffix: str) -> str: + """后缀匹配查找模块 SHA1(委托到 gen._lookup_module_sha1_suffix)""" + import lib.core.Gen.Generator as Generator + g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr)) + if g is not None: + return g._lookup_module_sha1_suffix(mod_suffix) + return None + +# ============================================================ +# 全局 CExport 函数表(module_sha1 + func_name) +# +# t.CExport 函数定义时不加 SHA1 前缀(如 @strlen), +# 跨模块调用时需要查表确认目标函数是否是 CExport 函数。 +# 若是,使用裸名调用(@strlen);否则使用 @{sha1}.func。 +# 必须包含模块 SHA1 记录,避免同名跨模块函数冲突 +# (一个模块有 CExport 的 strlen→@strlen,另一个没有→@{sha1}.strlen)。 +# +# 注:表数据已迁入 gen 字段(CallGenMixin.CexportSha1Arr/CexportFuncArr/ +# CexportCount),本模块不再持有(P4 簇 1+2)。 +# ============================================================ +_CEXPORT_MAX: t.CDefine = 256 +def register_cexport_func(sha1: str, func_name: str) -> int: + """注册 CExport 函数到全局表(委托到 gen.register_cexport_func)""" + import lib.core.Gen.Generator as Generator + g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr)) + if g is not None: + return g.register_cexport_func(sha1, func_name) + return 0 +def is_cexport_func(sha1: str, func_name: str) -> int: + """检查(sha1, func_name) 是否是 CExport 函数(委托到 gen.is_cexport_func)""" + import lib.core.Gen.Generator as Generator + g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr)) + if g is not None: + return g.is_cexport_func(sha1, func_name) + return 0 +# ============================================================ +# _lookup_mod_sha1 - 从 from_imports 查找类所属模块的 SHA1 +# +# lookup_from_import 返回指向 from_imports 内部的指针,不是 null 终止 +# (如 "namespace_defs Gadget:namespace_defs ...")。此函数手动截断 +# 模块名,复制到新缓冲区,再查找 SHA1(精确+后缀匹配)。 +# ============================================================ +def _lookup_mod_sha1(pool: memhub.MemBuddy | t.CPtr, + from_imports: str, class_name: str, + allow_star_fallback: int = 1) -> str: + """从 from_imports 查找类所属模块的 SHA1(委托到 gen._lookup_mod_sha1)""" + import lib.core.Gen.Generator as Generator + g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr)) + if g is not None: + return g._lookup_mod_sha1(pool, from_imports, class_name, allow_star_fallback) + return None +# ============================================================ +# _lookup_sha1_from_modname_raw - 原始模块名 → SHA1 +# +# 截断模块名(lookup_from_import 返回内部指针,空格/冒号/null 分隔), +# 去掉相对导入前导点,再精确+后缀查找 SHA1。 +# 供 _lookup_mod_sha1 与 HandlesExpr._lookup_cross_module_cdefine 复用。 +# ============================================================ +def _lookup_sha1_from_modname_raw(pool: memhub.MemBuddy | t.CPtr, + mod_name_raw: str) -> str: + """从原始模块名查找 SHA1(委托到 gen._lookup_sha1_from_modname_raw)""" + import lib.core.Gen.Generator as Generator + g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr)) + if g is not None: + return g._lookup_sha1_from_modname_raw(pool, mod_name_raw) + return None +# ============================================================ +# HandlesExprCall - 函数调用表达式处理(Mixin 继承模式) +# +# 工具函数和 HandlesExprCall.FuncEntry 保留为模块级,HandlesExprCall.ExprCallHandle 提供 trans 接口 +# ============================================================ + +# ============================================================ +# 在模块函数链表中按名称查找函数 +# ============================================================ +def find_func_in_module(mod: llvmlite.LLVMModule | t.CPtr, + name: str) -> llvmlite.Function | t.CPtr: + """在模块的函数链表中按名称查找函数(委托到 gen.find_func_in_module)""" + import lib.core.Gen.Generator as Generator + g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr)) + if g is not None: + return g.find_func_in_module(mod, name) + return None +# ============================================================ +# _ensure_c_lib_declare - 为已知的 C 库函数创建 declare 声明 +# +# 对应 TPC 的 _C_LIB_FUNCS 机制。当裸名调用 memset/memmove/memcmp/ +# strcmp/strlen 等已知 C 库函数时,自动在当前模块创建 declare, +# 避免报 "裸名调用未定义且未导入" 错误。 +# memcpy 不在此处理(已有 _emit_llvm_memcpy_intrinsic 映射到 @llvm.memcpy)。 +# +# Args: +# pool: 内存池 +# mod: LLVM 模块 +# name: 函数名 +# +# Returns: +# Function 指针(已创建 declare),或 None 如果不是已知 C 库函数 +# ============================================================ +def _ensure_c_lib_declare(pool: memhub.MemBuddy | t.CPtr, + mod: llvmlite.LLVMModule | t.CPtr, + name: str) -> llvmlite.Function | t.CPtr: + """为已知的 C 库函数创建 declare 声明(委托到 gen._ensure_c_lib_declare)""" + import lib.core.Gen.Generator as Generator + g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr)) + if g is not None: + return g._ensure_c_lib_declare(pool, mod, name) + return None +# ============================================================ +# _infer_external_func_ret_ty - 根据函数名推断外部函数返回类型 +# +# stubs 在翻译后才注入 IR,翻译时模块中无 stub 函数声明, +# 因此对 includes 库函数(如 string.strchr 返回 i8*)需根据 +# 函数名推断返回类型,避免指针被截断为 i32。 +# +# 覆盖 includes/string.py 所有导出函数: +# i8*: strcpy, strncpy, strchr, strrchr, strstr, memset, memset32, memcpy, memmove +# i64: strlen, atoll +# double: atof +# i8: samestr +# i32(默认): strcmp, strncmp, memcmp, strspn, atoi, split +# ============================================================ +def _infer_external_func_ret_ty(pool: memhub.MemBuddy | t.CPtr, + func_name: str) -> llvmlite.LLVMType | t.CPtr: + """根据函数名推断外部 includes 函数的返回类型(委托到 gen._infer_external_func_ret_ty)""" + import lib.core.Gen.Generator as Generator + g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr)) + if g is not None: + return g._infer_external_func_ret_ty(pool, func_name) + return None +# ============================================================ +# _get_external_func_param_ty - 获取外部函数第 idx 个参数的期望类型 +# +# stubs 翻译时未注入,需推断参数类型以提升字面量(如 i32→i64), +# 避免 declare(i64) 与 call(i32) 类型不匹配。 +# +# 注意:stubs 翻译时 ULONG(t.CUnsignedLong) 在 LLVM IR 中被翻译为 i64 +# (因为 LLVM 中 long 是 64 位),因此 Win32 API 中所有 ULONG/DWORD/SIZE_T +# 参数在 declare 中都是 i64。call 时必须匹配,否则类型不匹配。 +# +# 策略:对 Win32 API 函数的所有非指针参数(字面量)都提升为 i64, +# 以匹配 declare 中 ULONG 被翻译为 i64 的情况。 +# +# 指针参数(VOIDPTR/HANDLE)不在此处理,由调用点的 inttoptr 处理。 +# ============================================================ +def _get_external_func_param_ty(pool: memhub.MemBuddy | t.CPtr, + func_name: str, + param_idx: int) -> llvmlite.LLVMType | t.CPtr: + """获取外部函数第 param_idx 个参数的期望类型(委托到 gen._get_external_func_param_ty)""" + import lib.core.Gen.Generator as Generator + g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr)) + if g is not None: + return g._get_external_func_param_ty(pool, func_name, param_idx) + return None +# ============================================================ +# _emit_llvm_memcpy_intrinsic — 将 memcpy 调用映射到 @llvm.memcpy 内联函数 +# +# 背景: string.memcpy 是 t.CExport 函数,跨模块调用生成 @memcpy 裸名调用。 +# 但在 monomorphization 场景下,目标模块的 deps.txt 可能不含 string, +# 导致 @memcpy 声明缺失,链接器报 undefined value。 +# +# 解决: 将 memcpy 调用映射到 LLVM 内联函数 @llvm.memcpy, +# 该内联函数在当前模块内声明,无需跨模块依赖。 +# +# @llvm.memcpy 签名: void(i8* dst, i8* src, i64 len, i1 isvolatile) +# C memcpy 签名: i8* (i8* dst, i8* src, i64 len) — 返回 dst +# +# Args: +# args_head: 参数链表头(dst, src, num),通过 Value.Next 链接 +# arg_count: 参数数量(应为 3) +# +# Returns: +# dst 值(匹配 C memcpy 语义: 返回 dest 指针) +# ============================================================ +def _emit_llvm_memcpy_intrinsic(pool: memhub.MemBuddy | t.CPtr, + builder: llvmlite.IRBuilder | t.CPtr, + mod: llvmlite.LLVMModule | t.CPtr, + dst_val: llvmlite.Value | t.CPtr, + src_val: llvmlite.Value | t.CPtr, + num_val: llvmlite.Value | t.CPtr) -> llvmlite.Value | t.CPtr: + """将 memcpy 调用映射到 @llvm.memcpy 内联函数(委托到 gen._emit_llvm_memcpy_intrinsic)""" + import lib.core.Gen.Generator as Generator + g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr)) + if g is not None: + return g._emit_llvm_memcpy_intrinsic(pool, builder, mod, dst_val, src_val, num_val) + return None diff --git a/App/lib/core/Handles/ExprCallCall.vp b/App/lib/core/Handles/ExprCallCall.vp new file mode 100644 index 0000000..a405511 --- /dev/null +++ b/App/lib/core/Handles/ExprCallCall.vp @@ -0,0 +1,338 @@ +import t, c +from stdint import * +import ast +import llvmlite +import memhub +import string +import stdio +import stdlib +import sys +import viperlib +import w32.fileio as fileio +import lib.core.VLogger as VLogger +import lib.core.Handles.HandlesBase as HandlesBase +import lib.core.Handles.HandlesTranslator as HT +import lib.core.Handles.HandlesExpr as HandlesExpr +import lib.core.Handles.HandlesVar as HandlesVar +import lib.core.Handles.HandlesType as HandlesType +import lib.core.Handles.HandlesNonlocal as HandlesNonlocal +import lib.core.Handles.HandlesStruct as HandlesStruct +import lib.core.Handles.HandlesImports as HandlesImports +import lib.core.Handles.HandlesClassDef as HandlesClassDef +import lib.core.StubMerger as StubMerger + + +import lib.core.Handles.ExprCallBase as ExprCallBase +import lib.core.Handles.ExprCallDeref as ExprCallDeref +import lib.core.Handles.ExprCallCtor as ExprCallCtor +import lib.core.Handles.ExprCallTable as ExprCallTable +import lib.core.Handles.ExprCallHandle as ExprCallHandle +import lib.core.Handles.HandlesExprCall as HandlesExprCall + +# ============================================================ +# ExprCallCall - HandlesExprCall 拆分(阶段 E):ExprCallCall +# +# 直接移动模式:委托函数迁至此模块,原 HandlesExprCall.vp 仅 +# 保留 _g_gen/常量/类;调用方经本模块前缀访问。 +# ============================================================ + +# ============================================================ +# 翻译函数调用 Call(func, args) — 模块级版本 +# ============================================================ +def translate_call(pool: memhub.MemBuddy | t.CPtr, + builder: llvmlite.IRBuilder | t.CPtr, + mod: llvmlite.LLVMModule | t.CPtr, + node: ast.AST | t.CPtr, + funcs_ptr: t.CPtr, + func_count: int, + trans: HT.Translator | t.CPtr = None) -> llvmlite.Value | t.CPtr: + """翻译函数调用,返回 call 结果 Value(委托到 gen.translate_call)""" + import lib.core.Gen.Generator as Generator + g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr)) + if g is not None: + return g.translate_call(pool, builder, mod, node, funcs_ptr, func_count, trans) + return None +# ============================================================ +# 翻译闭包调用 — 通过闭包指针间接调用 +# +# 闭包结构: {i8* fn_ptr, i8* env_ptr} (16 字节) +# 调用过程: +# 1. load closure_ptr 从变量 alloca +# 2. load fn_ptr 从 offset 0 +# 3. load env_ptr 从 offset 8 +# 4. bitcast fn_ptr to i32(i8*)* +# 5. call i32 %fn_typed(i8* %env_ptr) +# ============================================================ +def translate_closure_call(pool: memhub.MemBuddy | t.CPtr, + builder: llvmlite.IRBuilder | t.CPtr, + mod: llvmlite.LLVMModule | t.CPtr, + closure_alloca: llvmlite.Value | t.CPtr, + cargs: list[ast.AST | t.CPtr] | t.CPtr, + can: t.CSizeT, + trans: HT.Translator | t.CPtr = None) -> llvmlite.Value | t.CPtr: + """通过闭包指针间接调用(委托到 gen.translate_closure_call)""" + import lib.core.Gen.Generator as Generator + g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr)) + if g is not None: + return g.translate_closure_call(pool, builder, mod, closure_alloca, cargs, can, trans) + return None +# ============================================================ +# _is_func_ptr_alloca - 判断变量 alloca 是否为函数指针变量 +# +# 函数指针变量(t.Callable 注解 → i8*)的 alloca 类型是 Ptr(Ptr(i8)) = i8**; +# 闭包变量 alloca 是 i8*(Ptr(i8))。通过类型层级区分。 +# ============================================================ +def _is_func_ptr_alloca(alloca: llvmlite.Value | t.CPtr) -> int: + """判断 alloca 是否为函数指针变量(类型 Ptr(Ptr(i8))),1=是 / 0=否(委托到 gen._is_func_ptr_alloca)""" + import lib.core.Gen.Generator as Generator + g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr)) + if g is not None: + return g._is_func_ptr_alloca(alloca) + return 0 + + +# ============================================================ +# 闭包变量名集合(stdlib 分配,懒初始化) +# +# 背景: 嵌套函数提升后闭包变量 alloca 类型是 i8**(alloca i8*), +# 与函数指针变量(t.Callable → i8** alloca)类型完全相同,_is_func_ptr_alloca +# 无法区分,导致 inner() 被误判为函数指针调用(直接 bitcast 闭包对象到函数指针、 +# 无 env 参数调用 → 运行时崩溃)。translate_nested_function_def 创建闭包时 +# 注册嵌套函数名,调用时优先按闭包调用处理。 +# ============================================================ +MAX_CLOSURE_NAMES: t.CDefine = 128 +def _ensure_closure_names() -> int: + """确保闭包名表已分配,0 失败(委托到 gen._ensure_closure_names)""" + import lib.core.Gen.Generator as Generator + g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr)) + if g is not None: + return g._ensure_closure_names() + return 0 +def register_closure_name(name: str) -> int: + """注册嵌套函数(闭包变量)名,0 成功(委托到 gen.register_closure_name)""" + import lib.core.Gen.Generator as Generator + g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr)) + if g is not None: + return g.register_closure_name(name) + return 0 +def is_closure_name(name: str) -> int: + """检查 name 是否已注册为闭包变量名,1=是 / 0=否(委托到 gen.is_closure_name)""" + import lib.core.Gen.Generator as Generator + g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr)) + if g is not None: + return g.is_closure_name(name) + return 0 + +# ============================================================ +# 函数指针变量签名表(变量名 → 返回类型) +# +# AnnAssign 处理 t.Callable 注解时注册,函数指针间接调用时 +# 按注册的返回类型构造签名(而非默认 i32)。 +# ============================================================ +MAX_FUNC_PTR_SIGS: t.CDefine = 64 +def _ensure_funcptr_sigs() -> int: + """确保函数指针签名表已分配(stdlib.malloc,懒初始化)(委托到 gen._ensure_funcptr_sigs)""" + import lib.core.Gen.Generator as Generator + g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr)) + if g is not None: + return g._ensure_funcptr_sigs() + return 0 +def register_func_ptr_sig(name: str, + ret_ty: llvmlite.LLVMType | t.CPtr) -> int: + """注册函数指针变量的返回类型签名,0 成功(委托到 gen.register_func_ptr_sig)""" + import lib.core.Gen.Generator as Generator + g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr)) + if g is not None: + return g.register_func_ptr_sig(name, ret_ty) + return 0 +def lookup_func_ptr_ret(name: str) -> llvmlite.LLVMType | t.CPtr: + """查函数指针变量的返回类型,None=未注册(调用时默认 i32)(委托到 gen.lookup_func_ptr_ret)""" + import lib.core.Gen.Generator as Generator + g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr)) + if g is not None: + return g.lookup_func_ptr_ret(name) + return None +# ============================================================ +# _translate_func_ptr_call - 函数指针变量间接调用 +# +# func_p: t.Callable[[A, B], Ret] 后调用 func_p(a, b): +# 1. load 函数地址(i8*) +# 2. 翻译实参并链接为 Value 链表 +# 3. 按实参类型 + 注册的返回类型构造签名(未注册时默认 i32) +# 4. bitcast i8* → 函数指针类型,间接调用 +# ============================================================ +def _translate_func_ptr_call(pool: memhub.MemBuddy | t.CPtr, + builder: llvmlite.IRBuilder | t.CPtr, + mod: llvmlite.LLVMModule | t.CPtr, + fp_alloca: llvmlite.Value | t.CPtr, + func_name: str, + cargs: list[ast.AST | t.CPtr] | t.CPtr, + can: t.CSizeT, + trans: HT.Translator | t.CPtr) -> llvmlite.Value | t.CPtr: + """函数指针变量间接调用,返回结果 Value(委托到 gen._translate_func_ptr_call)""" + import lib.core.Gen.Generator as Generator + g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr)) + if g is not None: + return g._translate_func_ptr_call(pool, builder, mod, fp_alloca, func_name, cargs, can, trans) + return None +# ============================================================ +# 翻译 printf 调用 — 模块级版本 +# ============================================================ +def translate_printf_call(pool: memhub.MemBuddy | t.CPtr, + builder: llvmlite.IRBuilder | t.CPtr, + mod: llvmlite.LLVMModule | t.CPtr, + cl: ast.Call | t.CPtr, + trans: HT.Translator | t.CPtr = None): + """翻译 printf 调用(特殊处理格式字符串)(委托到 gen.translate_printf_call)""" + import lib.core.Gen.Generator as Generator + g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr)) + if g is not None: + g.translate_printf_call(pool, builder, mod, cl, trans) +# ============================================================ +# 翻译 print 调用 — 类型感知格式化 + 默认换行 +# +# 与 printf 不同,print 不需要用户提供格式串:每个参数按 LLVM +# 类型自动选择格式(%s/%d/%f/0x%llx),结尾追加 "\n"(对齐 Python +# print 默认 end="\n",以及 TPC HandlesExprBuiltin._HandlePrintLlvm)。 +# +# 类型分派规则: +# i8*(str/bytes) → %s +# 其他指针(struct*/int*) → 0x%llx(ptrtoint 到 i64) +# i1(bool) → %d(zext 到 i32) +# i8/i16/i32 → %d(sext 到 i32,C ABI 整数提升) +# i64 → %lld +# float/double → %f(float fpext 到 double,C ABI 提升) +# 无法识别的类型 → "(unknown)"(不传参) +# ============================================================ +def translate_print_call(pool: memhub.MemBuddy | t.CPtr, + builder: llvmlite.IRBuilder | t.CPtr, + mod: llvmlite.LLVMModule | t.CPtr, + cl: ast.Call | t.CPtr, + trans: HT.Translator | t.CPtr = None): + """翻译 print 调用(类型感知格式化 + 默认换行)(委托到 gen.translate_print_call)""" + import lib.core.Gen.Generator as Generator + g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr)) + if g is not None: + g.translate_print_call(pool, builder, mod, cl, trans) +# ============================================================ +# stdarg 糖函数实现: va_arg / arg / va_start / va_end +# +# 这些函数对应 stdarg.vp 中的 pass 体声明,由编译器在翻译期 +# 转换为 LLVM 指令或 intrinsic 调用,不生成函数 call。 +# +# va_list 在 TPV 中表示为 i8*(与 stdarg.vp 中 va_list = t.CUnsignedChar | t.CPtr 一致)。 +# va_list 对象存储在 alloca 中(i8**),va_arg/va_start/va_end 需要传入 alloca 指针。 +# ============================================================ + +def _va_arg_get_alloca_ptr(pool: memhub.MemBuddy | t.CPtr, + builder: llvmlite.IRBuilder | t.CPtr, + mod: llvmlite.LLVMModule | t.CPtr, + arg_node: ast.AST | t.CPtr, + funcs_ptr: t.CPtr, + func_count: int, + trans: HT.Translator | t.CPtr) -> llvmlite.Value | t.CPtr: + """获取 va_list 变量的 alloca 指针(不 load)(委托到 gen._va_arg_get_alloca_ptr)""" + import lib.core.Gen.Generator as Generator + g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr)) + if g is not None: + return g._va_arg_get_alloca_ptr(pool, builder, mod, arg_node, funcs_ptr, func_count, trans) + return None +def _resolve_va_arg_type(pool: memhub.MemBuddy | t.CPtr, + type_node: ast.AST | t.CPtr, + trans: HT.Translator | t.CPtr) -> llvmlite.LLVMType | t.CPtr: + """解析 va_arg/arg 的类型参数为 LLVMType(委托到 gen._resolve_va_arg_type)""" + import lib.core.Gen.Generator as Generator + g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr)) + if g is not None: + return g._resolve_va_arg_type(pool, type_node, trans) + return None +def _translate_va_arg_sugar(pool: memhub.MemBuddy | t.CPtr, + builder: llvmlite.IRBuilder | t.CPtr, + mod: llvmlite.LLVMModule | t.CPtr, + cl: ast.Call | t.CPtr, + cargs: list[ast.AST | t.CPtr] | t.CPtr, + can: t.CSizeT, + funcs_ptr: t.CPtr, + func_count: int, + trans: HT.Translator | t.CPtr) -> llvmlite.Value | t.CPtr: + """va_arg(ap, type) / va_arg(ap) → %N = va_arg , (委托到 gen._translate_va_arg_sugar)""" + import lib.core.Gen.Generator as Generator + g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr)) + if g is not None: + return g._translate_va_arg_sugar(pool, builder, mod, cl, cargs, can, funcs_ptr, func_count, trans) + return None +def _translate_arg_sugar(pool: memhub.MemBuddy | t.CPtr, + builder: llvmlite.IRBuilder | t.CPtr, + mod: llvmlite.LLVMModule | t.CPtr, + cl: ast.Call | t.CPtr, + cargs: list[ast.AST | t.CPtr] | t.CPtr, + can: t.CSizeT, + funcs_ptr: t.CPtr, + func_count: int, + trans: HT.Translator | t.CPtr) -> llvmlite.Value | t.CPtr: + """arg(type) → %N = va_arg , (委托到 gen._translate_arg_sugar)""" + import lib.core.Gen.Generator as Generator + g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr)) + if g is not None: + return g._translate_arg_sugar(pool, builder, mod, cl, cargs, can, funcs_ptr, func_count, trans) + return None +def _translate_va_start_sugar(pool: memhub.MemBuddy | t.CPtr, + builder: llvmlite.IRBuilder | t.CPtr, + mod: llvmlite.LLVMModule | t.CPtr, + cargs: list[ast.AST | t.CPtr] | t.CPtr, + can: t.CSizeT, + funcs_ptr: t.CPtr, + func_count: int, + trans: HT.Translator | t.CPtr) -> llvmlite.Value | t.CPtr: + """va_start(ap, last_arg) → call void @llvm.va_start(i8* %ap)(委托到 gen._translate_va_start_sugar)""" + import lib.core.Gen.Generator as Generator + g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr)) + if g is not None: + return g._translate_va_start_sugar(pool, builder, mod, cargs, can, funcs_ptr, func_count, trans) + return None +def _translate_va_end_sugar(pool: memhub.MemBuddy | t.CPtr, + builder: llvmlite.IRBuilder | t.CPtr, + mod: llvmlite.LLVMModule | t.CPtr, + cargs: list[ast.AST | t.CPtr] | t.CPtr, + can: t.CSizeT, + funcs_ptr: t.CPtr, + func_count: int, + trans: HT.Translator | t.CPtr) -> llvmlite.Value | t.CPtr: + """va_end(ap) → call void @llvm.va_end(i8* %ap)(委托到 gen._translate_va_end_sugar)""" + import lib.core.Gen.Generator as Generator + g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr)) + if g is not None: + return g._translate_va_end_sugar(pool, builder, mod, cargs, can, funcs_ptr, func_count, trans) + return None +# ============================================================ +# 变长函数调用支持: 检查 IsVarArg + C ABI 参数提升 +# +# C ABI 要求变长参数(...部分)进行默认提升: +# 整数提升: i8/i16 → i32(sext/zext) +# 浮点提升: float → double(fpext) +# 固定参数不需要提升(有明确类型签名)。 +# ============================================================ + +def _get_func_fixed_param_count(func: llvmlite.Function | t.CPtr) -> int: + """获取函数的固定参数数量(遍历 Params 链表)(委托到 gen._get_func_fixed_param_count)""" + import lib.core.Gen.Generator as Generator + g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr)) + if g is not None: + return g._get_func_fixed_param_count(func) + return 0 +def _check_and_promote_variadic_call(pool: memhub.MemBuddy | t.CPtr, + builder: llvmlite.IRBuilder | t.CPtr, + mod: llvmlite.LLVMModule | t.CPtr, + call_name: str, + head: llvmlite.Value | t.CPtr, + can: t.CSizeT, + arg_nodes: list[ast.AST | t.CPtr] | t.CPtr = None, + self_offset: int = 0, + trans: HT.Translator | t.CPtr = None) -> int: + """检查被调用函数是否为变长函数,若是则对变长参数进行 C ABI 提升(委托到 gen._check_and_promote_variadic_call)""" + import lib.core.Gen.Generator as Generator + g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr)) + if g is not None: + return g._check_and_promote_variadic_call(pool, builder, mod, call_name, head, can, + arg_nodes, self_offset, trans) + return 0 diff --git a/App/lib/core/Handles/ExprCallCtor.vp b/App/lib/core/Handles/ExprCallCtor.vp new file mode 100644 index 0000000..f5e9466 --- /dev/null +++ b/App/lib/core/Handles/ExprCallCtor.vp @@ -0,0 +1,622 @@ +import t, c +from stdint import * +import ast +import llvmlite +import memhub +import string +import stdio +import stdlib +import sys +import viperlib +import w32.fileio as fileio +import lib.core.VLogger as VLogger +import lib.core.Handles.HandlesBase as HandlesBase +import lib.core.Handles.HandlesTranslator as HT +import lib.core.Handles.HandlesExpr as HandlesExpr +import lib.core.Handles.HandlesVar as HandlesVar +import lib.core.Handles.HandlesType as HandlesType +import lib.core.Handles.HandlesNonlocal as HandlesNonlocal +import lib.core.Handles.HandlesStruct as HandlesStruct +import lib.core.Handles.HandlesImports as HandlesImports +import lib.core.Handles.HandlesClassDef as HandlesClassDef +import lib.core.StubMerger as StubMerger + + +import lib.core.Handles.ExprCallBase as ExprCallBase +import lib.core.Handles.ExprCallDeref as ExprCallDeref +import lib.core.Handles.ExprCallCall as ExprCallCall +import lib.core.Handles.ExprCallTable as ExprCallTable +import lib.core.Handles.ExprCallHandle as ExprCallHandle +import lib.core.Handles.HandlesExprCall as HandlesExprCall + +# ============================================================ +# ExprCallCtor - HandlesExprCall 拆分(阶段 E):ExprCallCtor +# +# 直接移动模式:委托函数迁至此模块,原 HandlesExprCall.vp 仅 +# 保留 _g_gen/常量/类;调用方经本模块前缀访问。 +# ============================================================ + +# ============================================================ +# _apply_struct_defaults — 应用结构体字段的默认值 +# +# 在 zeroinitializer 之后、显式参数之前调用 +# 遍历所有字段,对有默认值的字段翻译并 store +# 显式参数(位置/关键字)后续会覆盖默认值 +# ============================================================ +def _apply_struct_defaults(pool: memhub.MemBuddy | t.CPtr, + builder: llvmlite.IRBuilder | t.CPtr, + mod: llvmlite.LLVMModule | t.CPtr, + struct_ty: llvmlite.LLVMType | t.CPtr, + class_name: str, + tmp: llvmlite.Value | t.CPtr, + trans: HT.Translator | t.CPtr): + """应用结构体字段的默认值(委托到 gen._apply_struct_defaults)""" + import lib.core.Gen.Generator as Generator + g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr)) + if g is not None: + g._apply_struct_defaults(pool, builder, mod, struct_ty, class_name, tmp, trans) +# ============================================================ +# _translate_struct_ctor — 结构体构造函数 Point(10, 20) +# +# 生成: +# %tmp = alloca {i32, i32} +# store {i32, i32} zeroinitializer, {i32, i32}* %tmp +# %f0 = getelementptr {i32, i32}, {i32, i32}* %tmp, i32 0, i32 0 +# store i32 10, i32* %f0 +# %f1 = getelementptr {i32, i32}, {i32, i32}* %tmp, i32 0, i32 1 +# store i32 20, i32* %f1 +# %result = load {i32, i32}, {i32, i32}* %tmp +# ============================================================ +def _translate_struct_ctor(pool: memhub.MemBuddy | t.CPtr, + builder: llvmlite.IRBuilder | t.CPtr, + mod: llvmlite.LLVMModule | t.CPtr, + struct_ty: llvmlite.LLVMType | t.CPtr, + class_name: str, + cargs: list[ast.AST | t.CPtr] | t.CPtr, + can: t.CSizeT, + trans: HT.Translator | t.CPtr) -> llvmlite.Value | t.CPtr: + """结构体构造函数:按字段顺序 store 参数值,返回结构体值(委托到 gen._translate_struct_ctor)""" + import lib.core.Gen.Generator as Generator + g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr)) + if g is not None: + return g._translate_struct_ctor(pool, builder, mod, struct_ty, class_name, cargs, can, trans) + return None +# ============================================================ +# _translate_renum_construct — REnum 变体构造函数 +# +# 语法: ClassName.VariantName(args...) +# 如 LLVMType.Int(1) → 构造 LLVMType 的 Int 变体,__tag=0,_p1=1 +# +# 生成 IR: +# %tmp = alloca {i32, i32, ...} ; REnum 类型 +# store zeroinitializer, %tmp ; 清零 +# %tag_ptr = gep %tmp, 0, 0 ; __tag 字段 +# store i32 , %tag_ptr ; 写入 tag +# %p1_ptr = gep %tmp, 0, 1 ; _p1 字段 +# store , %p1_ptr ; 写入 payload[0] +# ... (更多 payload 字段) +# return %tmp ; 返回指针 +# +# 对应 TPC 的 _HandleREnumConstructLlvm +# ============================================================ +def _translate_renum_construct(pool: memhub.MemBuddy | t.CPtr, + builder: llvmlite.IRBuilder | t.CPtr, + mod: llvmlite.LLVMModule | t.CPtr, + class_name: str, + variant_name: str, + tag_value: int, + cargs: list[ast.AST | t.CPtr] | t.CPtr, + can: t.CSizeT, + trans: HT.Translator | t.CPtr) -> llvmlite.Value | t.CPtr: + """构造 REnum 变体实例,返回指向 alloca 的指针(委托到 gen._translate_renum_construct)""" + import lib.core.Gen.Generator as Generator + g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr)) + if g is not None: + return g._translate_renum_construct(pool, builder, mod, class_name, variant_name, + tag_value, cargs, can, trans) + return None +# ============================================================ +# _do_virtual_call — 通过虚表间接调用虚方法 +# +# IR 模式: +# %1 = getelementptr StructTy, StructTy* %self, i32 0, i32 0 ; i8** +# %2 = load i8*, i8** %1 ; i8* (vtable ptr) +# %3 = bitcast i8* %2 to {i8*, ...}* ; vtable typed ptr +# %4 = getelementptr {i8*, ...}, {i8*, ...}* %3, i32 0, i32 N ; i8** +# %5 = load i8*, i8** %4 ; i8* (func ptr) +# %6 = bitcast i8* %5 to RetTy(Params)* ; func typed ptr +# call RetTy %6(Params %self, ...) +# +# 参数: +# args_head — 已构建好的参数链表头(self_ptr 为首节点) +# args_count — 参数总数(含 self) +# found_func — 方法对应的 Function 对象(用于推断函数签名) +# ret_ty — 返回类型 +# ============================================================ +def _do_virtual_call(pool: memhub.MemBuddy | t.CPtr, + builder: llvmlite.IRBuilder | t.CPtr, + mod: llvmlite.LLVMModule | t.CPtr, + class_name: str, + method_name: str, + self_ptr: llvmlite.Value | t.CPtr, + args_head: llvmlite.Value | t.CPtr, + args_count: int, + found_func: llvmlite.Function | t.CPtr, + ret_ty: llvmlite.LLVMType | t.CPtr, + vtable_base: llvmlite.Value | t.CPtr = None) -> llvmlite.Value | t.CPtr: + """通过虚表间接调用虚方法,返回 call 结果(void 方法返回 None)(委托到 gen._do_virtual_call)""" + import lib.core.Gen.Generator as Generator + g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr)) + if g is not None: + return g._do_virtual_call(pool, builder, mod, class_name, method_name, + self_ptr, args_head, args_count, found_func, ret_ty, vtable_base) + return None +# ============================================================ +# _call_method_on_ptr — 在结构体指针上调用方法 +# +# 辅助函数:构造 ClassName.method_name 调用,self 指针为首个参数 +# 如果该方法在虚表中,则走虚方法分发路径(间接调用) +# ============================================================ +def _call_method_on_ptr(pool: memhub.MemBuddy | t.CPtr, + builder: llvmlite.IRBuilder | t.CPtr, + mod: llvmlite.LLVMModule | t.CPtr, + class_name: str, + method_name: str, + self_ptr: llvmlite.Value | t.CPtr, + extra_args: t.CSizeT | t.CPtr, + extra_count: int, + trans: HT.Translator | t.CPtr, + node: ast.AST | t.CPtr = None) -> llvmlite.Value | t.CPtr: + """在结构体指针上调用方法,返回 call 结果(void 方法返回 None)(委托到 gen._call_method_on_ptr)""" + import lib.core.Gen.Generator as Generator + g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr)) + if g is not None: + return g._call_method_on_ptr(pool, builder, mod, class_name, method_name, + self_ptr, extra_args, extra_count, trans, node) + return None +# ============================================================ +# _ensure_method_declare - 为跨模块方法调用创建 declare 声明 +# +# 当 found_func 为 None(stub 未注入或跨模块调用)时, +# 在当前模块中创建函数声明,避免 llc 报 undefined value。 +# ============================================================ +def _ensure_method_declare(pool: memhub.MemBuddy | t.CPtr, + mod: llvmlite.LLVMModule | t.CPtr, + call_name: str, + ret_ty: llvmlite.LLVMType | t.CPtr, + param_head: llvmlite.ParamNode | t.CPtr, + param_count: int): + """为跨模块方法调用创建 declare 声明(委托到 gen._ensure_method_declare)""" + import lib.core.Gen.Generator as Generator + g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr)) + if g is not None: + g._ensure_method_declare(pool, mod, call_name, ret_ty, param_head, param_count) +# ============================================================ +# _lookup_method_ret_ty_via_vpi - 从 vpi stub 返回注解缓存精确获取方法返回类型 +# +# 方法定义处(.vpi stub)的返回注解(如 json.JsonValue._pool_alloc → +# "str")在 stub 注入时由 VpiReader 缓存(_cache_vpi_return_annots_text)。 +# 此函数按 模块SHA1 + 类名 + 方法名 查缓存并纯字符串解析为 LLVMType。 +# 无需硬编码白名单——返回类型始终来自方法定义处。 +# ============================================================ +def _lookup_method_ret_ty_via_vpi(pool: memhub.MemBuddy | t.CPtr, + cls_sha1: str, + cls_name: str, + method_name: str) -> llvmlite.LLVMType | t.CPtr: + """从 vpi stub 返回注解缓存获取方法返回类型,未命中返回 None(委托到 gen._lookup_method_ret_ty_via_vpi)""" + import lib.core.Gen.Generator as Generator + g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr)) + if g is not None: + return g._lookup_method_ret_ty_via_vpi(pool, cls_sha1, cls_name, method_name) + return None +# ============================================================ +# _special_method_ret_ty - 编译器内置特殊方法的固定返回类型 +# +# __before_init__ / __init__:编译器生成/约定返回 void +# __new__:返回 Ptr(StructTy)(存储空间指针) +# +# 这些方法不存在于源码(vpi stub 无条目),跨模块调用时 +# found_func/text.ll/vpi 缓存必然未命中,但返回类型是编译器 +# 确定性语义(与 HandlesClassDef._translate_method 3543-3548 一致), +# 在此直接固定,不触发 fail-fast 误报。非特殊方法返回 None。 +# ============================================================ +def _special_method_ret_ty(pool: memhub.MemBuddy | t.CPtr, + class_name: str, + method_name: str) -> llvmlite.LLVMType | t.CPtr: + """编译器内置特殊方法的固定返回类型;非特殊返回 None(委托到 gen._special_method_ret_ty)""" + import lib.core.Gen.Generator as Generator + g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr)) + if g is not None: + return g._special_method_ret_ty(pool, class_name, method_name) + return None +# ============================================================ +# _fail_method_ret_ty - 方法返回类型无法精确获取时 fail-fast +# +# 返回类型来源(按序):当前模块函数 → text.ll define → vpi stub 返回注解缓存。 +# 全部未命中时立即 ERROR + 错误堆栈终止,绝不按名推断白名单/静默默认 i32。 +# +# node: 调用点 AST 节点(可选,用于 ERROR 堆栈定位) +# ============================================================ +def _fail_method_ret_ty(method_name: str, + node: ast.AST | t.CPtr = None) -> llvmlite.LLVMType | t.CPtr: + """方法返回类型无法精确获取时 fail-fast(ERROR + 错误堆栈)(委托到 gen._fail_method_ret_ty)""" + import lib.core.Gen.Generator as Generator + g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr)) + if g is not None: + return g._fail_method_ret_ty(method_name, node) + return None +# ============================================================ +# 跨模块方法返回类型查找(从 text.ll) +# +# Phase A 翻译每个源文件后生成 text.ll,其中 define 行包含 +# 方法的实际返回类型。当 Phase A 翻译后续文件调用跨模块方法时, +# 方法调用默认返回 i32,导致指针返回值被截断。 +# _LookupMethodRetTyFromTextLL 读取依赖模块的 text.ll,从 define +# 行提取实际返回类型,避免指针截断(未命中时回退 vpi stub 缓存)。 +# ============================================================ + +# ============================================================ +# SetTempDir - 设置 temp 目录路径 +# +# 在 Phase2.py 的 Phase A 翻译前调用,使 CallGenMixin +# 能够读取依赖模块的 text.ll 文件。 +# ============================================================ +def SetTempDir(temp_dir: str): + """设置 temp 目录路径(供跨模块方法返回类型查找使用)(委托到 gen.SetTempDir)""" + import lib.core.Gen.Generator as Generator + g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr)) + if g is not None: + g.SetTempDir(temp_dir) +# ============================================================ +# _ParseLLVMRetTyStr - 将 LLVM IR 返回类型字符串转换为 llvmlite.LLVMType +# +# 从 define 行中提取的返回类型字符串(define 与 @ 之间的内容), +# 转换为 llvmlite.LLVMType 对象。 +# +# 支持的类型: +# void → Void +# i8/i16/i32/i64 → Int8/Int16/Int32/Int64 +# double → Double, float → Float +# 任何含 * 的类型 → Ptr(Int8)(通用指针,保留 64 位地址) +# +# Args: +# pool: 内存池 +# buf: 包含类型字符串的缓冲区 +# start: 类型字符串起始位置 +# end: 类型字符串结束位置(不含) +# +# Returns: +# LLVM 类型对象,或 None(无法解析) +# ============================================================ +def _ParseLLVMRetTyStr(pool: memhub.MemBuddy | t.CPtr, + buf: bytes, + start: t.CSizeT, + end: t.CSizeT) -> llvmlite.LLVMType | t.CPtr: + """将 LLVM IR 返回类型字符串转换为 llvmlite.LLVMType(委托到 gen._ParseLLVMRetTyStr)""" + import lib.core.Gen.Generator as Generator + g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr)) + if g is not None: + return g._ParseLLVMRetTyStr(pool, buf, start, end) + return None +# ============================================================ +# _LookupMethodRetTyFromTextLL - 从依赖模块的 text.ll 查找方法返回类型 +# +# 读取 {temp_dir}/{sha1[0:2]}/{sha1}.text.ll(level=1),搜索 +# define 行中包含 "{sha1}.{class_name}.{method_name}" 的函数, +# 提取返回类型并转换为 llvmlite.LLVMType。 +# +# 解决问题: 旧实现 _infer_method_ret_ty(已移除)默认返回 i32,导致指针返回值 +# 被 inttoptr 截断为 32 位(coerce_to_type line 238-239)。 +# 本函数从 text.ll 获取实际返回类型,避免截断。 +# +# Args: +# pool: 内存池 +# class_sha1: 类所属模块的 SHA1 +# class_name: 类名 +# method_name: 方法名 +# +# Returns: +# LLVM 类型对象,或 None(未找到/text.ll 不存在) +# ============================================================ +def _LookupMethodRetTyFromTextLL(pool: memhub.MemBuddy | t.CPtr, + class_sha1: str, + class_name: str, + method_name: str, + use_bare: int = 0) -> llvmlite.LLVMType | t.CPtr: + """从依赖模块的 text.ll 中查找方法返回类型(委托到 gen._LookupMethodRetTyFromTextLL)""" + import lib.core.Gen.Generator as Generator + g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr)) + if g is not None: + return g._LookupMethodRetTyFromTextLL(pool, class_sha1, class_name, method_name, use_bare) + return None +# ============================================================ +# 属性方法(@property/@x.setter/@x.deleter)与静态/类方法调用辅助 +# +# 元数据表由 HandlesClassDef 在类翻译/预注册阶段填充, +# 这里负责把 obj.prop / obj.prop=v / del obj.prop / Class.method() +# 翻译为对应的 {sha1}.ClassName.prop 系列函数调用。 +# ============================================================ + +# ============================================================ +# _translate_property_call — 翻译属性方法调用 +# +# 与 _translate_method_call 的调用名/返回类型解析逻辑一致: +# 1. 优先用模块中已有的函数(精确/后缀匹配,来自 stub 注入) +# 2. 否则用类所属模块的 SHA1 构造 "{sha1}.ClassName.method" 调用名 +# 3. 返回类型:函数实类型 → text.ll 查找 → 按方法名推断(默认 i32) +# +# call_head/call_count: 已构建好的参数链表(如 getter 只有 obj 一个参数) +# ============================================================ +def _translate_property_call(pool: memhub.MemBuddy | t.CPtr, + builder: llvmlite.IRBuilder | t.CPtr, + mod: llvmlite.LLVMModule | t.CPtr, + class_name: str, + method_name: str, + call_head: llvmlite.Value | t.CPtr, + call_count: int, + trans: HT.Translator | t.CPtr) -> llvmlite.Value | t.CPtr: + """翻译属性/静态方法调用,返回 call 结果 Value(委托到 gen._translate_property_call)""" + import lib.core.Gen.Generator as Generator + g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr)) + if g is not None: + return g._translate_property_call(pool, builder, mod, class_name, method_name, + call_head, call_count, trans) + return None +# ============================================================ +# _resolve_obj_class_name — 解析对象表达式的类名(短名) +# +# 优先从变量注解(AnnotClassName)解析(如 "memhub.MemBuddy" → "MemBuddy"), +# 失败时从 LLVM 类型解析(Ptr(Struct) → 类名)。 +# 供属性访问/赋值/删除识别 property 时使用。 +# ============================================================ +def _resolve_obj_class_name(pool: memhub.MemBuddy | t.CPtr, + trans: HT.Translator | t.CPtr, + obj_node: ast.AST | t.CPtr) -> str: + """解析对象表达式的类名(短名),失败返回 None(委托到 gen._resolve_obj_class_name)""" + import lib.core.Gen.Generator as Generator + g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr)) + if g is not None: + return g._resolve_obj_class_name(pool, trans, obj_node) + return None +# ============================================================ +# _try_property_getter_attr — 尝试将 obj.attr 翻译为 property getter 调用 +# +# 检查 obj 的类是否有 @property/@x.getter 的 attr 方法; +# 若有则生成 call Class.attr(obj) 并返回调用结果 Value;否则返回 None。 +# ============================================================ +def _try_property_getter_attr(pool: memhub.MemBuddy | t.CPtr, + builder: llvmlite.IRBuilder | t.CPtr, + mod: llvmlite.LLVMModule | t.CPtr, + at_node: ast.Attribute | t.CPtr, + obj_ptr: llvmlite.Value | t.CPtr, + trans: HT.Translator | t.CPtr, + fallback_class_name: str = None) -> llvmlite.Value | t.CPtr: + """尝试 property getter 属性访问,返回调用结果 Value;非 getter 返回 None(委托到 gen._try_property_getter_attr)""" + import lib.core.Gen.Generator as Generator + g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr)) + if g is not None: + return g._try_property_getter_attr(pool, builder, mod, at_node, obj_ptr, + trans, fallback_class_name) + return None +# ============================================================ +# _try_property_setter — 尝试将 obj.attr = v 翻译为 property setter 调用 +# +# 检查 obj 的类是否有 @x.setter 的 attr 方法; +# 若有则生成 call Class.attr$set(obj, v),返回 1;否则返回 0。 +# ============================================================ +def _try_property_setter(pool: memhub.MemBuddy | t.CPtr, + builder: llvmlite.IRBuilder | t.CPtr, + mod: llvmlite.LLVMModule | t.CPtr, + target_attr: ast.Attribute | t.CPtr, + rhs_val: llvmlite.Value | t.CPtr, + trans: HT.Translator | t.CPtr) -> int: + """尝试 property setter 赋值,返回 1=已处理(生成调用)(委托到 gen._try_property_setter)""" + import lib.core.Gen.Generator as Generator + g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr)) + if g is not None: + return g._try_property_setter(pool, builder, mod, target_attr, rhs_val, trans) + return 0 +# ============================================================ +# _try_property_deleter — 尝试将 del obj.attr 翻译为 property deleter 调用 +# +# 检查 obj 的类是否有 @x.deleter 的 attr 方法; +# 若有则生成 call Class.attr$del(obj),返回 1;否则返回 0。 +# ============================================================ +def _try_property_deleter(pool: memhub.MemBuddy | t.CPtr, + builder: llvmlite.IRBuilder | t.CPtr, + mod: llvmlite.LLVMModule | t.CPtr, + target_attr: ast.Attribute | t.CPtr, + trans: HT.Translator | t.CPtr) -> int: + """尝试 property deleter 删除,返回 1=已处理(生成调用)(委托到 gen._try_property_deleter)""" + import lib.core.Gen.Generator as Generator + g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr)) + if g is not None: + return g._try_property_deleter(pool, builder, mod, target_attr, trans) + return 0 +# ============================================================ +# _translate_static_class_call — 翻译 ClassName.method(args) 静态/类方法调用 +# +# @staticmethod: 直接 call Class.method(args...),无 self +# @classmethod: 在参数前插入栈上分配的类实例指针(与 TPC 一致) +# ============================================================ +def _translate_static_class_call(pool: memhub.MemBuddy | t.CPtr, + builder: llvmlite.IRBuilder | t.CPtr, + mod: llvmlite.LLVMModule | t.CPtr, + class_name: str, + method_name: str, + cl: ast.Call | t.CPtr, + trans: HT.Translator | t.CPtr) -> llvmlite.Value | t.CPtr: + """翻译类名静态/类方法调用,返回 call 结果 Value;非静态/类方法返回 None(委托到 gen._translate_static_class_call)""" + import lib.core.Gen.Generator as Generator + g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr)) + if g is not None: + return g._translate_static_class_call(pool, builder, mod, class_name, method_name, cl, trans) + return None +# ============================================================ +# _translate_method_call - 翻译方法调用 obj.method(args) +# +# 生成: call @SHA1.ClassName.method_name(Ptr(StructTy) %obj, args...) +# +# obj_ptr 是对象变量的 alloca(Ptr(StructTy)),作为 self 参数传入 +# ============================================================ +def _translate_method_call(pool: memhub.MemBuddy | t.CPtr, + builder: llvmlite.IRBuilder | t.CPtr, + mod: llvmlite.LLVMModule | t.CPtr, + class_name: str, + method_name: str, + obj_ptr: llvmlite.Value | t.CPtr, + cl: ast.Call | t.CPtr, + trans: HT.Translator | t.CPtr) -> llvmlite.Value | t.CPtr: + """翻译方法调用,返回 call 结果 Value(委托到 gen._translate_method_call)""" + import lib.core.Gen.Generator as Generator + g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr)) + if g is not None: + return g._translate_method_call(pool, builder, mod, class_name, method_name, + obj_ptr, cl, trans) + return None +# ============================================================ +# _kwarg_name_matches — 检查关键字参数名是否匹配函数参数名 +# +# 函数参数名在 LLVM IR 中带 % 前缀(如 "%a"),关键字参数名无前缀(如 "a") +# 跳过 % 前缀后逐字符比较 +# ============================================================ +def _kwarg_name_matches(kw_arg: str, + param_name: str) -> int: + """检查关键字参数名 kw_arg 是否匹配参数名 param_name(跳过 % 前缀)(委托到 gen._kwarg_name_matches)""" + import lib.core.Gen.Generator as Generator + g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr)) + if g is not None: + return g._kwarg_name_matches(kw_arg, param_name) + return 0 +# ============================================================ +# _translate_struct_ctor_kw — 结构体构造函数(关键字参数) +# +# 支持两种语法: +# Point(x=10, y=20) — 全关键字 +# Point(10, y=20) — 混合(位置 + 关键字) +# +# 位置参数按字段索引赋值,关键字参数按字段名查找赋值 +# ============================================================ +def _translate_struct_ctor_kw(pool: memhub.MemBuddy | t.CPtr, + builder: llvmlite.IRBuilder | t.CPtr, + mod: llvmlite.LLVMModule | t.CPtr, + struct_ty: llvmlite.LLVMType | t.CPtr, + class_name: str, + cargs: list[ast.AST | t.CPtr] | t.CPtr, + can: t.CSizeT, + keywords: list[ast.AST | t.CPtr] | t.CPtr, + kw_count: t.CSizeT, + trans: HT.Translator | t.CPtr) -> llvmlite.Value | t.CPtr: + """结构体构造函数(关键字参数版本)(委托到 gen._translate_struct_ctor_kw)""" + import lib.core.Gen.Generator as Generator + g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr)) + if g is not None: + return g._translate_struct_ctor_kw(pool, builder, mod, struct_ty, class_name, + cargs, can, keywords, kw_count, trans) + return None +# ============================================================ +# _translate_call_with_kwargs — 带关键字参数的函数调用 +# +# 支持两种语法: +# add(b=4, a=3) — 全关键字乱序 +# greet("Hello", name="World") — 位置 + 关键字混合 +# +# 策略: 遍历 found_func.Params 链表,对每个参数: +# 1. 若位置参数仍有剩余(param_idx < can),取位置参数 +# 2. 否则按参数名匹配关键字参数 +# 3. 按参数顺序构建调用参数链表 +# ============================================================ +def _translate_call_with_kwargs(pool: memhub.MemBuddy | t.CPtr, + builder: llvmlite.IRBuilder | t.CPtr, + mod: llvmlite.LLVMModule | t.CPtr, + func_name: str, + found_func: llvmlite.Function | t.CPtr, + cargs: list[ast.AST | t.CPtr] | t.CPtr, + can: t.CSizeT, + keywords: list[ast.AST | t.CPtr] | t.CPtr, + kw_count: t.CSizeT, + trans: HT.Translator | t.CPtr) -> llvmlite.Value | t.CPtr: + """带关键字参数的函数调用,按参数顺序构建调用链表(委托到 gen._translate_call_with_kwargs)""" + import lib.core.Gen.Generator as Generator + g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr)) + if g is not None: + return g._translate_call_with_kwargs(pool, builder, mod, func_name, found_func, + cargs, can, keywords, kw_count, trans) + return None +# ============================================================ +# _translate_t_type_cast - 翻译 t.XXX(value) 类型转换 +# +# 当 func 是 t.XXX 形式且 XXX 是已知类型名(map_t_type 能映射)时, +# 将 value 转换为目标类型: +# - 指针 → 整数: ptrtoint(如 t.CUInt64T(ptr) → i64) +# - 整数 → 指针: inttoptr(如 t.CPtr(int_val) → i8*) +# - 整数 → 整数: trunc/zext(如 t.CInt8T(i32_val) → i8) +# - 指针 → 指针: bitcast(如 t.CPtr(ptr_val) → i8*) +# - 整数 → 浮点: sitofp(如 t.CDouble(i32_val) → double) +# - 浮点 → 整数: fptosi(如 t.CInt(double_val) → i32) +# - 浮点 → 浮点: fpext/fptrunc(如 t.CFloat(double_val) → float) +# ============================================================ +def _translate_t_type_cast(pool: memhub.MemBuddy | t.CPtr, + builder: llvmlite.IRBuilder | t.CPtr, + val: llvmlite.Value | t.CPtr, + target_ty: llvmlite.LLVMType | t.CPtr, + target_name: str = None, + src_node: ast.AST | t.CPtr = None, + trans: HT.Translator | t.CPtr = None) -> llvmlite.Value | t.CPtr: + """类型转换:根据参数类型和目标类型选择转换方式(委托到 gen._translate_t_type_cast)""" + import lib.core.Gen.Generator as Generator + g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr)) + if g is not None: + return g._translate_t_type_cast(pool, builder, val, target_ty, + target_name, src_node, trans) + return None +# ============================================================ +# 泛型实例化辅助:从 Subscript slice 提取类型实参名 +# ============================================================ +# _get_type_name_from_annotation 已移至 HandlesType.py(支持 BinOp/Attribute) +# HandlesExprCall 通过 HandlesType._get_type_name_from_annotation 调用 + +def _extract_type_args_from_slice(pool: memhub.MemBuddy | t.CPtr, + slice_node: ast.AST | t.CPtr) -> list[str] | t.CPtr: + """从 Subscript.slice 提取类型实参名列表(委托到 gen._extract_type_args_from_slice)""" + import lib.core.Gen.Generator as Generator + g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr)) + if g is not None: + return g._extract_type_args_from_slice(pool, slice_node) + return None +# ============================================================ +# 泛型类构造调用辅助: list[str](pool, 8) → __new__ + __before_init__ + __init__ +# +# 复用 translate_list_literal 的构造逻辑: +# 1. alloca tmp(特化类临时空间,作为 __new__ 的 self) +# 2. 翻译 cl.args 为参数指针数组 +# 3. call __new__(tmp, *args) → storage_ptr +# 4. call __before_init__(storage_ptr) +# 5. call __init__(storage_ptr, *args) +# 6. return storage_ptr +# +# 必须独立于 translate_call 的普通函数路径:spec_name 是类名不是函数名, +# 走裸名路径会被 _lookup_mod_sha1 的 star import 回退误导,用错误的 SHA1 +# 且缺少 __new__ 方法名后缀,导致链接报 undefined reference。 +# ============================================================ +def _infer_generic_ctor_type_arg(pool: memhub.MemBuddy | t.CPtr, + arg_node: ast.AST | t.CPtr, + class_name: str) -> str: + """从构造实参 AST 推断泛型类型实参名;无法推断时默认 "int"(与 TPC 一致)(委托到 gen._infer_generic_ctor_type_arg)""" + import lib.core.Gen.Generator as Generator + g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr)) + if g is not None: + return g._infer_generic_ctor_type_arg(pool, arg_node, class_name) + return "int" +def _translate_generic_ctor_call(pool: memhub.MemBuddy | t.CPtr, + builder: llvmlite.IRBuilder | t.CPtr, + mod: llvmlite.LLVMModule | t.CPtr, + spec_name: str, + cl: ast.Call | t.CPtr, + trans: HT.Translator | t.CPtr) -> llvmlite.Value | t.CPtr: + """泛型类构造调用: list[str](pool, 8) → __new__ + __before_init__ + __init__(委托到 gen._translate_generic_ctor_call)""" + import lib.core.Gen.Generator as Generator + g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr)) + if g is not None: + return g._translate_generic_ctor_call(pool, builder, mod, spec_name, cl, trans) + return None diff --git a/App/lib/core/Handles/ExprCallDeref.vp b/App/lib/core/Handles/ExprCallDeref.vp new file mode 100644 index 0000000..2db6191 --- /dev/null +++ b/App/lib/core/Handles/ExprCallDeref.vp @@ -0,0 +1,291 @@ +import t, c +from stdint import * +import ast +import llvmlite +import memhub +import string +import stdio +import stdlib +import sys +import viperlib +import w32.fileio as fileio +import lib.core.VLogger as VLogger +import lib.core.Handles.HandlesBase as HandlesBase +import lib.core.Handles.HandlesTranslator as HT +import lib.core.Handles.HandlesExpr as HandlesExpr +import lib.core.Handles.HandlesVar as HandlesVar +import lib.core.Handles.HandlesType as HandlesType +import lib.core.Handles.HandlesNonlocal as HandlesNonlocal +import lib.core.Handles.HandlesStruct as HandlesStruct +import lib.core.Handles.HandlesImports as HandlesImports +import lib.core.Handles.HandlesClassDef as HandlesClassDef +import lib.core.StubMerger as StubMerger + + +import lib.core.Handles.ExprCallBase as ExprCallBase +import lib.core.Handles.ExprCallCtor as ExprCallCtor +import lib.core.Handles.ExprCallCall as ExprCallCall +import lib.core.Handles.ExprCallTable as ExprCallTable +import lib.core.Handles.ExprCallHandle as ExprCallHandle +import lib.core.Handles.HandlesExprCall as HandlesExprCall + +# ============================================================ +# ExprCallDeref - HandlesExprCall 拆分(阶段 E):ExprCallDeref +# +# 直接移动模式:委托函数迁至此模块,原 HandlesExprCall.vp 仅 +# 保留 _g_gen/常量/类;调用方经本模块前缀访问。 +# ============================================================ + +# ============================================================ +# c.Deref(ptr) — 解引用指针,按指针 pointee 类型读取 +# +# 生成: %N = load , * %ptr +# 返回 pointee 类型的值 +# +# 注意: 必须按 ptr 的 pointee 类型决定读取宽度。 +# - i8* (str/bytes/字符遍历) → load i8 +# - i64* (t.CUInt64T, 块头部) → load i64(memhub 的 free list 链表读 8 字节头部) +# 之前固定 load i8 导致 memhub 读块头部只读到低 8 位, +# free list 的 next 指针被截断成 0x88 等垃圾值,alloc 崩溃。 +# ============================================================ +def translate_c_deref(pool: memhub.MemBuddy | t.CPtr, + builder: llvmlite.IRBuilder | t.CPtr, + mod: llvmlite.LLVMModule | t.CPtr, + cl: ast.Call | t.CPtr, + trans: HT.Translator | t.CPtr = None) -> llvmlite.Value | t.CPtr: + """c.Deref(ptr) → load 按 ptr 的 pointee 类型(委托到 gen.translate_c_deref)""" + import lib.core.Gen.Generator as Generator + g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr)) + if g is not None: + return g.translate_c_deref(pool, builder, mod, cl, trans) + return None +# ============================================================ +# c.DerefAs(ptr, val) — 解引用写入,*ptr = val +# +# 生成: %pc = bitcast i8* %ptr to * +# store %val, * %pc +# ============================================================ +def translate_c_derefas(pool: memhub.MemBuddy | t.CPtr, + builder: llvmlite.IRBuilder | t.CPtr, + mod: llvmlite.LLVMModule | t.CPtr, + cl: ast.Call | t.CPtr, + trans: HT.Translator | t.CPtr = None) -> llvmlite.Value | t.CPtr: + """c.DerefAs(ptr, val) → store val to ptr(bitcast 后 store)(委托到 gen.translate_c_derefas)""" + import lib.core.Gen.Generator as Generator + g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr)) + if g is not None: + return g.translate_c_derefas(pool, builder, mod, cl, trans) + return None +# ============================================================ +# c.Set(a, b) — 赋值语义 a = b(与 c.DerefAs 的指针语义不同) +# +# c.DerefAs(ptr, val) 是 *ptr = val(指针解引用写); +# c.Set(a, b) 是 a = b(a 为左值),a 支持三种形态: +# 1. c.Deref(ptr) → *ptr = b(zlib/vipermath 的 c.Set(c.Deref(p), v) 用法) +# 2. Name 变量 → 变量赋值(含 global/nonlocal/局部) +# 3. Attribute → 字段赋值(GEP + store) +# ============================================================ +def translate_c_set(pool: memhub.MemBuddy | t.CPtr, + builder: llvmlite.IRBuilder | t.CPtr, + mod: llvmlite.LLVMModule | t.CPtr, + cl: ast.Call | t.CPtr, + trans: HT.Translator | t.CPtr = None) -> llvmlite.Value | t.CPtr: + """c.Set(a, b) → a = b(赋值语义,a 为左值)(委托到 gen.translate_c_set)""" + import lib.core.Gen.Generator as Generator + g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr)) + if g is not None: + return g.translate_c_set(pool, builder, mod, cl, trans) + return None +# ============================================================ +# c.Addr(var) — 取变量地址,返回 alloca 指针(不 load) +# +# 用于获取栈变量的可写地址,配合 c.DerefAs 使用 +# ============================================================ +def translate_c_addr(pool: memhub.MemBuddy | t.CPtr, + builder: llvmlite.IRBuilder | t.CPtr, + mod: llvmlite.LLVMModule | t.CPtr, + cl: ast.Call | t.CPtr, + trans: HT.Translator | t.CPtr = None) -> llvmlite.Value | t.CPtr: + """c.Addr(var) → 返回变量的 alloca 指针(不 load)(委托到 gen.translate_c_addr)""" + import lib.core.Gen.Generator as Generator + g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr)) + if g is not None: + return g.translate_c_addr(pool, builder, mod, cl, trans) + return None +# ============================================================ +# c.Load(a, b) — 指针间复制: *a = *b +# +# 加载 b 指向的值,存储到 a 指向的地址。 +# 生成: %pc_src = bitcast i8* %src to * +# %loaded = load , * %pc_src +# %pc_dst = bitcast i8* %dst to * +# store %loaded, * %pc_dst +# ============================================================ +def translate_c_load(pool: memhub.MemBuddy | t.CPtr, + builder: llvmlite.IRBuilder | t.CPtr, + mod: llvmlite.LLVMModule | t.CPtr, + cl: ast.Call | t.CPtr, + trans: HT.Translator | t.CPtr = None) -> llvmlite.Value | t.CPtr: + """c.Load(a, b) → *a = *b(加载 b 的值,存储到 a)(委托到 gen.translate_c_load)""" + import lib.core.Gen.Generator as Generator + g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr)) + if g is not None: + return g.translate_c_load(pool, builder, mod, cl, trans) + return None + +# ============================================================ +# c.Asm — 内联汇编支持 +# +# 生成: %N = call asm sideeffect "", ""() +# 或: call void asm sideeffect "", ""() +# +# 操作数按出现顺序编号 $0, $1, ...(用户需按输出在前写 f-string) +# ============================================================ + +ASM_MAX_OPERANDS: t.CDefine = 16 +ASM_TEXT_BUF_SIZE: t.CDefine = 2048 +ASM_CONST_BUF_SIZE: t.CDefine = 512 +ASM_ARGS_BUF_SIZE: t.CDefine = 512 +ASM_LINE_BUF_SIZE: t.CDefine = 4096 +# ============================================================ +# _asm_append_cstr — 将 C 字符串 src 追加到 dst 末尾 +# ============================================================ +def _asm_append_cstr(dst: str, dst_size: t.CSizeT, + src: str): + """将 C 字符串 src 追加到 dst 末尾(委托到 gen._asm_append_cstr)""" + import lib.core.Gen.Generator as Generator + g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr)) + if g is not None: + g._asm_append_cstr(dst, dst_size, src) +# ============================================================ +# _asm_escape_for_ir — 将汇编文本转义为 LLVM IR 字符串内容 +# +# \n → \0A, " → \22, \ → \5C +# ============================================================ +def _asm_escape_for_ir(pool: memhub.MemBuddy | t.CPtr, + src: str) -> str: + """转义汇编文本用于 LLVM IR 字符串字面量(委托到 gen._asm_escape_for_ir)""" + import lib.core.Gen.Generator as Generator + g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr)) + if g is not None: + return g._asm_escape_for_ir(pool, src) + return None +# ============================================================ +# _resolve_register — 将 ASM_DESCR 属性名映射到约束字符串 +# ============================================================ +def _resolve_register(attr_name: str) -> str: + """将 t.ASM_DESCR.XXX 的属性名映射到约束字符串值(委托到 gen._resolve_register)""" + import lib.core.Gen.Generator as Generator + g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr)) + if g is not None: + return g._resolve_register(attr_name) + return "" +# ============================================================ +# _resolve_asm_descr — 递归解析约束表达式 +# +# 支持: +# t.ASM_DESCR.XXX → _resolve_register(XXX) +# expr | expr(BinOp BitOr) → 拼接 +# "string" (Constant) → 直接返回 +# ============================================================ +def _resolve_asm_descr(pool: memhub.MemBuddy | t.CPtr, + node: ast.AST | t.CPtr) -> str: + """递归解析约束表达式,返回约束字符串(委托到 gen._resolve_asm_descr)""" + import lib.core.Gen.Generator as Generator + g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr)) + if g is not None: + return g._resolve_asm_descr(pool, node) + return "" +# ============================================================ +# _asm_get_operand — 获取操作数数组中第 idx 个元素的指针 +# ============================================================ +def _asm_get_operand(base: HandlesExprCall.AsmOperand | t.CPtr, + idx: int) -> HandlesExprCall.AsmOperand | t.CPtr: + """获取操作数数组中第 idx 个元素的指针(委托到 gen._asm_get_operand)""" + import lib.core.Gen.Generator as Generator + g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr)) + if g is not None: + return g._asm_get_operand(base, idx) + return None +# ============================================================ +# _asm_is_c_call — 检查 Call 节点是否是 c.XXX 调用 +# +# 返回 attr_name(如 "AsmInp"/"AsmOut"),不是则返回 None +# ============================================================ +def _asm_is_c_call(node: ast.Call | t.CPtr) -> str: + """检查 Call 节点是否是 c.XXX 调用,返回属性名或 None(委托到 gen._asm_is_c_call)""" + import lib.core.Gen.Generator as Generator + g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr)) + if g is not None: + return g._asm_is_c_call(node) + return None +# ============================================================ +# _asm_add_operand — 添加操作数到数组 +# +# 返回 1 成功, 0 失败(数组已满) +# ============================================================ +def _asm_add_operand(operands: HandlesExprCall.AsmOperand | t.CPtr, + count: int, + val: llvmlite.Value | t.CPtr, + constraint: str, + is_output: int) -> int: + """添加操作数到数组,返回新计数(失败返回原计数)(委托到 gen._asm_add_operand)""" + import lib.core.Gen.Generator as Generator + g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr)) + if g is not None: + return g._asm_add_operand(operands, count, val, constraint, is_output) + return 0 +# ============================================================ +# translate_c_asm — 翻译 c.Asm 内联汇编 +# +# 语法: +# c.Asm("nop", [t.ASM_DESCR.CLOBBER_MEMORY]) +# c.Asm(f"mov rax, {c.AsmInp(val, t.ASM_DESCR.REG_ANY)}", op=[...]) +# c.Asm(f"...", out=[c.AsmOut(var, t.ASM_DESCR.OUTPUT_REG)], op=[...]) +# ============================================================ +def translate_c_asm(pool: memhub.MemBuddy | t.CPtr, + builder: llvmlite.IRBuilder | t.CPtr, + mod: llvmlite.LLVMModule | t.CPtr, + cl: ast.Call | t.CPtr, + trans: HT.Translator | t.CPtr = None) -> llvmlite.Value | t.CPtr: + """翻译 c.Asm 内联汇编,返回结果 Value(委托到 gen.translate_c_asm)""" + import lib.core.Gen.Generator as Generator + g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr)) + if g is not None: + return g.translate_c_asm(pool, builder, mod, cl, trans) + return None + +# ============================================================ +# c.LLVMIR — 内联 LLVM IR(无返回值,直接嵌入原始 IR 文本) +# +# 语法: +# c.LLVMIR(f"add i32 {c.LInp(a)}, {c.LInp(b)}") +# c.LLVMIR(f"{c.LOut(result)} = add i32 {c.LInp(a)}, {c.LInp(b)}") +# +# c.LInp(expr) - 输入操作数,替换为 expr 的 LLVM 值引用文本(SSA 名 "%x" 或常量 "42") +# c.LOut(expr) - 输出操作数:为 expr 变量分配唯一 SSA 寄存器 %llvmirN, +# 模板嵌入后自动追加 store %llvmirN, * %expr 写回变量 +# +# 语义(2026-08-08 用户决策):不做指令解析,模板文本直接嵌入当前基本块, +# 返回 None(无返回值)。ret_ty 第二参数已废弃(兼容忽略)。 +# ============================================================ + +LLVMIR_MAX_OPS: t.CDefine = 16 +LLVMIR_TEMPLATE_BUF: t.CDefine = 512 +# 注:LOut 唯一 SSA 寄存器名计数器已迁入 gen 字段(CallGenMixin.LLVMIRRegSeq), +# 本模块不再持有(P4 簇 1+2)。 + +# ============================================================ +# translate_c_llvmir — 翻译 c.LLVMIR 内联 LLVM IR +# ============================================================ +def translate_c_llvmir(pool: memhub.MemBuddy | t.CPtr, + builder: llvmlite.IRBuilder | t.CPtr, + mod: llvmlite.LLVMModule | t.CPtr, + cl: ast.Call | t.CPtr, + trans: HT.Translator | t.CPtr = None) -> llvmlite.Value | t.CPtr: + """c.LLVMIR 内联 LLVM IR:无返回值,直接嵌入原始 IR 文本(委托到 gen.translate_c_llvmir)""" + import lib.core.Gen.Generator as Generator + g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr)) + if g is not None: + return g.translate_c_llvmir(pool, builder, mod, cl, trans) + return None diff --git a/App/lib/core/Handles/ExprCallHandle.vp b/App/lib/core/Handles/ExprCallHandle.vp new file mode 100644 index 0000000..d179567 --- /dev/null +++ b/App/lib/core/Handles/ExprCallHandle.vp @@ -0,0 +1,284 @@ +import t, c +from stdint import * +import ast +import llvmlite +import memhub +import string +import stdio +import stdlib +import sys +import viperlib +import w32.fileio as fileio +import lib.core.VLogger as VLogger +import lib.core.Handles.HandlesBase as HandlesBase +import lib.core.Handles.HandlesTranslator as HT +import lib.core.Handles.HandlesExpr as HandlesExpr +import lib.core.Handles.HandlesVar as HandlesVar +import lib.core.Handles.HandlesType as HandlesType +import lib.core.Handles.HandlesNonlocal as HandlesNonlocal +import lib.core.Handles.HandlesStruct as HandlesStruct +import lib.core.Handles.HandlesImports as HandlesImports +import lib.core.Handles.HandlesClassDef as HandlesClassDef +import lib.core.StubMerger as StubMerger + + +import lib.core.Handles.ExprCallBase as ExprCallBase +import lib.core.Handles.ExprCallDeref as ExprCallDeref +import lib.core.Handles.ExprCallCtor as ExprCallCtor +import lib.core.Handles.ExprCallCall as ExprCallCall +import lib.core.Handles.ExprCallTable as ExprCallTable +import lib.core.Handles.HandlesExprCall as HandlesExprCall + +# ============================================================ +# ExprCallHandle - HandlesExprCall 拆分(阶段 E):ExprCallHandle +# +# 直接移动模式:委托函数迁至此模块,原 HandlesExprCall.vp 仅 +# 保留 _g_gen/常量/类;调用方经本模块前缀访问。 +# ============================================================ + +# ============================================================ +# NewExprCallHandle - 工厂函数 +# ============================================================ +def NewExprCallHandle(pool: memhub.MemBuddy | t.CPtr, + trans: HT.Translator | t.CPtr) -> HandlesExprCall.ExprCallHandle | t.CPtr: + """新建 HandlesExprCall.ExprCallHandle 工厂(委托到 gen.NewExprCallHandle)""" + import lib.core.Gen.Generator as Generator + g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr)) + if g is not None: + return g.NewExprCallHandle(pool, trans) + return None +# ============================================================ +# _make_vtable_ref_i8 / _emit_eh_guarded_call / _translate_isinstance +# (追加91:CallGenMixin 拆分后顶层经委托调用 CallGenLeafKit 方法—— +# TPV self 调用仅支持 1 级父类,跨 Mixin 统一走 HandlesExprCall._g_gen 委托) +# ============================================================ +def _make_vtable_ref_i8(pool: memhub.MemBuddy | t.CPtr, + builder: llvmlite.IRBuilder | t.CPtr, + mod: llvmlite.LLVMModule | t.CPtr, + class_name: str, + trans: HT.Translator | t.CPtr = None) -> llvmlite.Value | t.CPtr: + """构造类 vtable 地址引用(i8*)(委托到 gen._make_vtable_ref_i8)""" + import lib.core.Gen.Generator as Generator + g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr)) + if g is not None: + return g._make_vtable_ref_i8(pool, builder, mod, class_name, trans) + return None +def _emit_eh_guarded_call(builder: llvmlite.IRBuilder | t.CPtr, + pool: memhub.MemBuddy | t.CPtr, + mod: llvmlite.LLVMModule | t.CPtr, + trans: HT.Translator | t.CPtr, + func: llvmlite.Function | t.CPtr, + call_name: str, + head: llvmlite.Value | t.CPtr, + count: int, + ret_ty: llvmlite.LLVMType | t.CPtr, + is_variadic: int) -> llvmlite.Value | t.CPtr: + """带 try-except EH 检测的函数调用(委托到 gen._emit_eh_guarded_call)""" + import lib.core.Gen.Generator as Generator + g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr)) + if g is not None: + return g._emit_eh_guarded_call(builder, pool, mod, trans, func, call_name, head, count, ret_ty, is_variadic) + return None +def _translate_isinstance(pool: memhub.MemBuddy | t.CPtr, + builder: llvmlite.IRBuilder | t.CPtr, + mod: llvmlite.LLVMModule | t.CPtr, + obj_node: ast.AST | t.CPtr, + cls_node: ast.AST | t.CPtr, + trans: HT.Translator | t.CPtr = None) -> llvmlite.Value | t.CPtr: + """翻译 isinstance()(委托到 gen._translate_isinstance)""" + import lib.core.Gen.Generator as Generator + g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr)) + if g is not None: + return g._translate_isinstance(pool, builder, mod, obj_node, cls_node, trans) + return None +# ============================================================ +# _is_sha1_mangled_call / _is_list_builtin_method / _translate_fakeduck_call / +# _translate_super_call(阶段 B:CallGenMixin 拆分后顶层经委托调用这些方法) +# ============================================================ +def _is_sha1_mangled_call(call_name: str) -> int: + """判断 call_name 是否为跨模块 Viper 函数(委托到 gen._is_sha1_mangled_call)""" + import lib.core.Gen.Generator as Generator + g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr)) + if g is not None: + return g._is_sha1_mangled_call(call_name) + return 0 +def _is_list_builtin_method(class_name: str, method_name: str) -> int: + """判断(class_name, method_name) 是否是 list 泛型内置方法(委托到 gen._is_list_builtin_method)""" + import lib.core.Gen.Generator as Generator + g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr)) + if g is not None: + return g._is_list_builtin_method(class_name, method_name) + return 0 +def _translate_fakeduck_call(pool: memhub.MemBuddy | t.CPtr, + builder: llvmlite.IRBuilder | t.CPtr, + mod: llvmlite.LLVMModule | t.CPtr, + cls_name: str, + method_name: str, + cl: ast.Call | t.CPtr, + trans: HT.Translator | t.CPtr) -> llvmlite.Value | t.CPtr: + """FakeDuck: str 变量方法调用(委托到 gen._translate_fakeduck_call)""" + import lib.core.Gen.Generator as Generator + g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr)) + if g is not None: + return g._translate_fakeduck_call(pool, builder, mod, cls_name, method_name, cl, trans) + return None +def _translate_super_call(pool: memhub.MemBuddy | t.CPtr, + builder: llvmlite.IRBuilder | t.CPtr, + mod: llvmlite.LLVMModule | t.CPtr, + cl: ast.Call | t.CPtr, + method_name: str, + trans: HT.Translator | t.CPtr) -> llvmlite.Value | t.CPtr: + """super().method(args) → 父类方法静态调用(委托到 gen._translate_super_call)""" + import lib.core.Gen.Generator as Generator + g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr)) + if g is not None: + return g._translate_super_call(pool, builder, mod, cl, method_name, trans) + return None +# ============================================================ +# translate_call 前置检测 helper(阶段 C:CallGenMixin 拆分后顶层经委托 +# 调用 CallGenDispatch 方法。每个返回 Value|CPtr,None = 未命中继续主路径) +# ============================================================ +def _tc_h1_super_ctraits(pool: memhub.MemBuddy | t.CPtr, + builder: llvmlite.IRBuilder | t.CPtr, + mod: llvmlite.LLVMModule | t.CPtr, + cl: ast.Call | t.CPtr, + funcs_ptr: t.CPtr, + func_count: int, + trans: HT.Translator | t.CPtr, + func_name: str, + cargs: list[ast.AST | t.CPtr] | t.CPtr, + can: t.CSizeT) -> llvmlite.Value | t.CPtr: + """super()/ctraits 编译期检测(委托到 gen._tc_h1_super_ctraits)""" + import lib.core.Gen.Generator as Generator + g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr)) + if g is not None: + return g._tc_h1_super_ctraits(pool, builder, mod, cl, funcs_ptr, func_count, trans, func_name, cargs, can) + return None +def _tc_h2_c_special(pool: memhub.MemBuddy | t.CPtr, + builder: llvmlite.IRBuilder | t.CPtr, + mod: llvmlite.LLVMModule | t.CPtr, + cl: ast.Call | t.CPtr, + funcs_ptr: t.CPtr, + func_count: int, + trans: HT.Translator | t.CPtr, + func_name: str, + cargs: list[ast.AST | t.CPtr] | t.CPtr, + can: t.CSizeT) -> llvmlite.Value | t.CPtr: + """c.Deref/Asm/LLVMIR 等特殊调用(委托到 gen._tc_h2_c_special)""" + import lib.core.Gen.Generator as Generator + g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr)) + if g is not None: + return g._tc_h2_c_special(pool, builder, mod, cl, funcs_ptr, func_count, trans, func_name, cargs, can) + return None +def _tc_h3_stdarg_cast(pool: memhub.MemBuddy | t.CPtr, + builder: llvmlite.IRBuilder | t.CPtr, + mod: llvmlite.LLVMModule | t.CPtr, + cl: ast.Call | t.CPtr, + funcs_ptr: t.CPtr, + func_count: int, + trans: HT.Translator | t.CPtr, + func_name: str, + cargs: list[ast.AST | t.CPtr] | t.CPtr, + can: t.CSizeT) -> llvmlite.Value | t.CPtr: + """stdarg 糖 + str/int/bool 内置强转(委托到 gen._tc_h3_stdarg_cast)""" + import lib.core.Gen.Generator as Generator + g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr)) + if g is not None: + return g._tc_h3_stdarg_cast(pool, builder, mod, cl, funcs_ptr, func_count, trans, func_name, cargs, can) + return None +def _tc_h4_type_casts(pool: memhub.MemBuddy | t.CPtr, + builder: llvmlite.IRBuilder | t.CPtr, + mod: llvmlite.LLVMModule | t.CPtr, + cl: ast.Call | t.CPtr, + funcs_ptr: t.CPtr, + func_count: int, + trans: HT.Translator | t.CPtr, + func_name: str, + cargs: list[ast.AST | t.CPtr] | t.CPtr, + can: t.CSizeT) -> llvmlite.Value | t.CPtr: + """t.XXX / typedef 类型转换(委托到 gen._tc_h4_type_casts)""" + import lib.core.Gen.Generator as Generator + g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr)) + if g is not None: + return g._tc_h4_type_casts(pool, builder, mod, cl, funcs_ptr, func_count, trans, func_name, cargs, can) + return None +def _tc_h5_sizeof_len_isinst(pool: memhub.MemBuddy | t.CPtr, + builder: llvmlite.IRBuilder | t.CPtr, + mod: llvmlite.LLVMModule | t.CPtr, + cl: ast.Call | t.CPtr, + funcs_ptr: t.CPtr, + func_count: int, + trans: HT.Translator | t.CPtr, + func_name: str, + cargs: list[ast.AST | t.CPtr] | t.CPtr, + can: t.CSizeT) -> llvmlite.Value | t.CPtr: + """__sizeof__/len/isinstance 内置(委托到 gen._tc_h5_sizeof_len_isinst)""" + import lib.core.Gen.Generator as Generator + g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr)) + if g is not None: + return g._tc_h5_sizeof_len_isinst(pool, builder, mod, cl, funcs_ptr, func_count, trans, func_name, cargs, can) + return None +def _tc_h6_method_dispatch(pool: memhub.MemBuddy | t.CPtr, + builder: llvmlite.IRBuilder | t.CPtr, + mod: llvmlite.LLVMModule | t.CPtr, + cl: ast.Call | t.CPtr, + funcs_ptr: t.CPtr, + func_count: int, + trans: HT.Translator | t.CPtr, + func_name: str, + cargs: list[ast.AST | t.CPtr] | t.CPtr, + can: t.CSizeT) -> llvmlite.Value | t.CPtr: + """静态类/方法调用/表达式接收者/self.field/list 内置(委托到 gen._tc_h6_method_dispatch)""" + import lib.core.Gen.Generator as Generator + g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr)) + if g is not None: + return g._tc_h6_method_dispatch(pool, builder, mod, cl, funcs_ptr, func_count, trans, func_name, cargs, can) + return None +# ============================================================ +# FuncGen 跨 Mixin 委托(阶段 D:FuncGenMixin 拆 Base/Def 后顶层经 +# 此调用这些方法。参数与目标方法一致,去 self) +# ============================================================ +def extract_func_attrs(pool: memhub.MemBuddy | t.CPtr, + decorator_list: list[ast.AST | t.CPtr] | t.CPtr, + imported_modules: str) -> str: + """从 decorator_list 提取 c.Attribute 属性(委托到 gen.extract_func_attrs)""" + import lib.core.Gen.Generator as Generator + g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr)) + if g is not None: + return g.extract_func_attrs(pool, decorator_list, imported_modules) + return None +def _mangle_name(trans: HT.Translator | t.CPtr, name: str) -> str: + """为任意名称添加 SHA1 前缀(委托到 gen._mangle_name)""" + import lib.core.Gen.Generator as Generator + g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr)) + if g is not None: + return g._mangle_name(trans, name) + return name +def _mangle_func_name(trans: HT.Translator | t.CPtr, name: str, + has_export: int) -> str: + """为函数名添加 SHA1 前缀(委托到 gen._mangle_func_name)""" + import lib.core.Gen.Generator as Generator + g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr)) + if g is not None: + return g._mangle_func_name(trans, name, has_export) + return name +def _body_has_raise(fd: ast.FunctionDef | t.CPtr) -> int: + """函数体顶层是否含 raise(委托到 gen._body_has_raise)""" + import lib.core.Gen.Generator as Generator + g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr)) + if g is not None: + return g._body_has_raise(fd) + return 0 +def _prepare_chain_nonlocals(trans: HT.Translator | t.CPtr, + node: ast.AST | t.CPtr, + pool: memhub.MemBuddy | t.CPtr, + builder: llvmlite.IRBuilder | t.CPtr, + mod: llvmlite.LLVMModule | t.CPtr, + i8_ty: llvmlite.LLVMType | t.CPtr, + i8_ptr_ty: llvmlite.LLVMType | t.CPtr) -> int: + """准备嵌套函数 nonlocals 链(委托到 gen._prepare_chain_nonlocals)""" + import lib.core.Gen.Generator as Generator + g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr)) + if g is not None: + return g._prepare_chain_nonlocals(trans, node, pool, builder, mod, i8_ty, i8_ptr_ty) + return 0 diff --git a/App/lib/core/Handles/ExprCallTable.vp b/App/lib/core/Handles/ExprCallTable.vp new file mode 100644 index 0000000..27b2fde --- /dev/null +++ b/App/lib/core/Handles/ExprCallTable.vp @@ -0,0 +1,206 @@ +import t, c +from stdint import * +import ast +import llvmlite +import memhub +import string +import stdio +import stdlib +import sys +import viperlib +import w32.fileio as fileio +import lib.core.VLogger as VLogger +import lib.core.Handles.HandlesBase as HandlesBase +import lib.core.Handles.HandlesTranslator as HT +import lib.core.Handles.HandlesExpr as HandlesExpr +import lib.core.Handles.HandlesVar as HandlesVar +import lib.core.Handles.HandlesType as HandlesType +import lib.core.Handles.HandlesNonlocal as HandlesNonlocal +import lib.core.Handles.HandlesStruct as HandlesStruct +import lib.core.Handles.HandlesImports as HandlesImports +import lib.core.Handles.HandlesClassDef as HandlesClassDef +import lib.core.StubMerger as StubMerger + + +import lib.core.Handles.ExprCallBase as ExprCallBase +import lib.core.Handles.ExprCallDeref as ExprCallDeref +import lib.core.Handles.ExprCallCtor as ExprCallCtor +import lib.core.Handles.ExprCallCall as ExprCallCall +import lib.core.Handles.ExprCallHandle as ExprCallHandle +import lib.core.Handles.HandlesExprCall as HandlesExprCall + +# ============================================================ +# ExprCallTable - HandlesExprCall 拆分(阶段 E):ExprCallTable +# +# 直接移动模式:委托函数迁至此模块,原 HandlesExprCall.vp 仅 +# 保留 _g_gen/常量/类;调用方经本模块前缀访问。 +# ============================================================ + +# ============================================================ +# 初始化函数表 +# ============================================================ +def init_func_table(pool: memhub.MemBuddy | t.CPtr, + max_count: int) -> HandlesExprCall.FuncEntry | t.CPtr: + """分配并清零函数表数组(委托到 gen.init_func_table)""" + import lib.core.Gen.Generator as Generator + g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr)) + if g is not None: + return g.init_func_table(pool, max_count) + return None +# ============================================================ +# 查找函数 +# ============================================================ +def find_func_in_table(funcs: HandlesExprCall.FuncEntry | t.CPtr, + func_count: int, + name: str) -> llvmlite.Function | t.CPtr: + """在函数表中按名称查找,返回 Function 指针或 None(委托到 gen.find_func_in_table)""" + import lib.core.Gen.Generator as Generator + g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr)) + if g is not None: + return g.find_func_in_table(funcs, func_count, name) + return None +# ============================================================ +# 添加函数到函数表 +# ============================================================ +def add_func_to_table(funcs: HandlesExprCall.FuncEntry | t.CPtr, + func_count: int, + name: str, + func: llvmlite.Function | t.CPtr, + max_count: int, + defaults: t.CVoid | t.CPtr = None, + default_count: int = 0, + param_count: int = 0, + pool: memhub.MemBuddy | t.CPtr = None) -> int: + """添加函数到函数表,返回 0 成功(委托到 gen.add_func_to_table)""" + import lib.core.Gen.Generator as Generator + g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr)) + if g is not None: + return g.add_func_to_table(funcs, func_count, name, func, max_count, + defaults, default_count, param_count, pool) + return 0 + +# ============================================================ +# 全局函数注册表(跨模块函数查找) +# +# 所有模块翻译的函数都会注册到此表(通过 add_func_to_table 自动注册)。 +# 主要用途: vtable 初始化时查找跨模块继承方法的 Function 对象, +# 以获取函数类型信息构造 bitcast 字符串。 +# ============================================================ +GLOBAL_FUNC_MAX: t.CDefine = 8192 +def _init_global_func_table() -> int: + """初始化全局函数表(用 stdlib.malloc 分配,生命周期=整个程序)(委托到 gen._init_global_func_table)""" + import lib.core.Gen.Generator as Generator + g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr)) + if g is not None: + return g._init_global_func_table() + return 0 +# _build_func_type_str — 从 Function 对象生成函数类型文本(stdlib 存储) +# +# 格式: ret_ty(param1_ty, param2_ty, ...),与 vtable bitcast 需要一致。 +# 用 stdlib.malloc 分配返回,跨文件永久存活(1b reset 不回收)。 +# 返回 None 表示失败。 +def _build_func_type_str(pool: memhub.MemBuddy | t.CPtr, + func: llvmlite.Function | t.CPtr) -> str: + """生成函数类型文本(stdlib 分配)(委托到 gen._build_func_type_str)""" + import lib.core.Gen.Generator as Generator + g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr)) + if g is not None: + return g._build_func_type_str(pool, func) + return None +def _register_global_func(name: str, func: llvmlite.Function | t.CPtr, + pool: memhub.MemBuddy | t.CPtr = None) -> int: + """注册函数到全局表(已存在则跳过),返回 0 成功(委托到 gen._register_global_func)""" + import lib.core.Gen.Generator as Generator + g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr)) + if g is not None: + return g._register_global_func(name, func, pool) + return 0 +def update_global_func_typestr(pool: memhub.MemBuddy | t.CPtr, + name: str, + func: llvmlite.Function | t.CPtr) -> int: + """更新全局函数表的 TypeStr(在函数参数全部添加完成后调用)(委托到 gen.update_global_func_typestr)""" + import lib.core.Gen.Generator as Generator + g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr)) + if g is not None: + return g.update_global_func_typestr(pool, name, func) + return 0 +def find_func_global(name: str) -> llvmlite.Function | t.CPtr: + """在全局函数表中按名称查找,返回 Function 指针或 None(委托到 gen.find_func_global)""" + import lib.core.Gen.Generator as Generator + g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr)) + if g is not None: + return g.find_func_global(name) + return None +def find_func_entry_global(name: str) -> HandlesExprCall.FuncEntry | t.CPtr: + """在全局函数表中按名称查找,返回完整 HandlesExprCall.FuncEntry(含 TypeStr)或 None(委托到 gen.find_func_entry_global)""" + import lib.core.Gen.Generator as Generator + g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr)) + if g is not None: + return g.find_func_entry_global(name) + return None + + +# ============================================================ +# 全局默认参数注册表(跨模块默认参数填充) +# +# 独立于 _global_funcs,因为 _register_global_func 可能在 +# add_func_to_table 之前被调用(如 stub 注入),此时 defaults 还不可用。 +# ============================================================ +GLOBAL_DEFAULTS_MAX: t.CDefine = 4096 +def _init_global_defaults_table() -> int: + """初始化全局默认参数表(委托到 gen._init_global_defaults_table)""" + import lib.core.Gen.Generator as Generator + g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr)) + if g is not None: + return g._init_global_defaults_table() + return 0 +def _register_global_defaults(name: str, + defaults: t.CVoid | t.CPtr, + default_count: int, + param_count: int) -> int: + """注册函数默认参数到全局表,返回 0 成功(委托到 gen._register_global_defaults)""" + import lib.core.Gen.Generator as Generator + g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr)) + if g is not None: + return g._register_global_defaults(name, defaults, default_count, param_count) + return 0 +def find_func_defaults(name: str) -> HandlesExprCall.FuncDefaultsEntry | t.CPtr: + """按函数名查找默认参数信息,返回 HandlesExprCall.FuncDefaultsEntry 或 None(委托到 gen.find_func_defaults)""" + import lib.core.Gen.Generator as Generator + g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr)) + if g is not None: + return g.find_func_defaults(name) + return None +# _build_const_from_snapshot — 从常量快照重建常量 IR 值 +# +# 用于跨模块默认参数填充:gd_entry.Defaults(pool 内 AST)可能已被 reset 回收, +# 改用注册时提取的 stdlib 常量快照(ConstKinds/ConstInts/ConstStrs)重建常量 IR。 +# 返回 llvmlite.Value*,失败返回 None。 +def _build_const_from_snapshot(pool: memhub.MemBuddy | t.CPtr, + mod: llvmlite.LLVMModule | t.CPtr, + gd_entry: HandlesExprCall.FuncDefaultsEntry | t.CPtr, + di: int, + trans: HT.Translator | t.CPtr, + builder: llvmlite.IRBuilder | t.CPtr) -> llvmlite.Value | t.CPtr: + """从快照重建第 di 个默认值常量 IR(委托到 gen._build_const_from_snapshot)""" + import lib.core.Gen.Generator as Generator + g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr)) + if g is not None: + return g._build_const_from_snapshot(pool, mod, gd_entry, di, trans, builder) + return None +def find_func_entry_in_table(funcs: HandlesExprCall.FuncEntry | t.CPtr, + func_count: int, + name: str) -> HandlesExprCall.FuncEntry | t.CPtr: + """在函数表中按名称查找,返回完整 HandlesExprCall.FuncEntry 或 None""" + if name is None or funcs is None: + return None + entry_size: t.CSizeT = HandlesExprCall.FuncEntry.__sizeof__() + i: int = 0 + while i < func_count: + entry_addr: t.CUInt64T = t.CUInt64T(funcs) + i * entry_size + entry: HandlesExprCall.FuncEntry | t.CPtr = (HandlesExprCall.FuncEntry | t.CPtr)(t.CVoid(entry_addr, t.CPtr)) + if entry.Name is not None: + if string.strcmp(entry.Name, name) == 0: + return entry + i += 1 + return None diff --git a/App/lib/core/Handles/HandlesAnnAssign.vp b/App/lib/core/Handles/HandlesAnnAssign.vp index 1e34553..e4d72de 100644 --- a/App/lib/core/Handles/HandlesAnnAssign.vp +++ b/App/lib/core/Handles/HandlesAnnAssign.vp @@ -17,6 +17,8 @@ import lib.core.Handles.HandlesClassDef as HandlesClassDef import lib.core.Handles.HandlesExprCall as HandlesExprCall import lib.core.Handles.HandlesStruct as HandlesStruct import lib.core.VLogger as VLogger +import lib.core.Handles.ExprCallCall as ExprCallCall +import lib.core.Handles.ExprCallCtor as ExprCallCtor # ============================================================ @@ -364,7 +366,7 @@ class AnnAssignHandle(HandlesBase.Mixin): template_cd: ast.ClassDef | t.CPtr = HandlesClassDef._find_generic_template(sub_nm.id) spec_name_ps: str = None if template_cd is not None: - type_args_ps: list[str] | t.CPtr = HandlesExprCall._extract_type_args_from_slice(pool, sub_annot.slice) + type_args_ps: list[str] | t.CPtr = ExprCallCtor._extract_type_args_from_slice(pool, sub_annot.slice) if type_args_ps is not None and len(type_args_ps) > 0: spec_name_ps = HandlesClassDef._specialize_generic_class( self.Trans, sub_nm.id, type_args_ps) @@ -470,7 +472,7 @@ class AnnAssignHandle(HandlesBase.Mixin): callable_ret: llvmlite.LLVMType | t.CPtr = HandlesType.try_extract_callable_ret( pool, annot, self.Trans._imported_modules, self.Trans._from_imports, self.Trans) if callable_ret is not None: - HandlesExprCall.register_func_ptr_sig(nm.id, callable_ret) + ExprCallCall.register_func_ptr_sig(nm.id, callable_ret) # global 变量:写入模块作用域中的全局变量 if HT.is_global_name(self.Trans, nm.id) != 0: diff --git a/App/lib/core/Handles/HandlesAssign.vp b/App/lib/core/Handles/HandlesAssign.vp index 9131d8b..ee11a3f 100644 --- a/App/lib/core/Handles/HandlesAssign.vp +++ b/App/lib/core/Handles/HandlesAssign.vp @@ -17,6 +17,9 @@ import lib.core.Handles.HandlesType as HandlesType import lib.core.Handles.HandlesStruct as HandlesStruct import lib.core.StubMerger as StubMerger import lib.core.StubMergerStore as StubMergerStore +import lib.core.Handles.ExprCallBase as ExprCallBase +import lib.core.Handles.ExprCallCall as ExprCallCall +import lib.core.Handles.ExprCallCtor as ExprCallCtor # ============================================================ @@ -267,7 +270,7 @@ class AssignHandle(HandlesBase.Mixin): if arg_vals_set is not None: arg_vals_set[0] = t.CSizeT(key_val_set) arg_vals_set[1] = t.CSizeT(rhs_val) - HandlesExprCall._call_method_on_ptr( + ExprCallCtor._call_method_on_ptr( pool, builder, mod, cls_nm_set, "__setitem__", obj_val_set, arg_vals_set, 2, self.Trans) setitem_done = 1 @@ -300,7 +303,7 @@ class AssignHandle(HandlesBase.Mixin): if arg_vals_attr is not None: arg_vals_attr[0] = t.CSizeT(key_val_attr) arg_vals_attr[1] = t.CSizeT(rhs_val) - HandlesExprCall._call_method_on_ptr( + ExprCallCtor._call_method_on_ptr( pool, builder, mod, cls_nm_attr, "__setitem__", obj_val_attr, arg_vals_attr, 2, self.Trans) setitem_done = 1 @@ -327,7 +330,7 @@ class AssignHandle(HandlesBase.Mixin): if arg_vals_gen is not None: arg_vals_gen[0] = t.CSizeT(key_val_gen) arg_vals_gen[1] = t.CSizeT(rhs_val) - HandlesExprCall._call_method_on_ptr( + ExprCallCtor._call_method_on_ptr( pool, builder, mod, cls_nm_gen, "__setitem__", obj_val_gen, arg_vals_gen, 2, self.Trans) setitem_done = 1 @@ -364,7 +367,7 @@ class AssignHandle(HandlesBase.Mixin): # 旧代码传 (builder, pool, ...) 导致 pool/builder 错位,pool 参数 # 实际是 IRBuilder 对象,pool.alloc 虚调用读 IRBuilder[0] 当 vtable # 跳到垃圾地址崩溃(BuiltinDecoratorTest Phase A 崩溃根因)。 - if HandlesExprCall._try_property_setter( + if ExprCallCtor._try_property_setter( pool, builder, mod, target, rhs_val, self.Trans) == 1: continue # FakeDuck: 影子结构体属性写入 (str 变量的 per-instance 字段) @@ -531,7 +534,7 @@ class AssignHandle(HandlesBase.Mixin): # 函数指针,无参 call 直接跳闭包数据崩溃 if asgn.value is not None \ and asgn.value.kind() == ast.ASTKind.Lambda: - HandlesExprCall.register_closure_name(nm.id) + ExprCallCall.register_closure_name(nm.id) existing: llvmlite.Value | t.CPtr = HandlesVar.lookup_current( self.Trans.SymTab, nm.id) if existing is None: @@ -604,7 +607,7 @@ class AssignHandle(HandlesBase.Mixin): if ca.value.kind() == ast.ASTKind.Name: mod_nm_rhs: ast.Name | t.CPtr = (ast.Name | t.CPtr)(ca.value) if mod_nm_rhs.id is not None: - mod_sha1_rhs: str = HandlesExprCall._lookup_module_sha1( + mod_sha1_rhs: str = ExprCallBase._lookup_module_sha1( mod_nm_rhs.id) if mod_sha1_rhs is not None: import lib.StubGen.VpiReader as VpiReader @@ -786,7 +789,7 @@ class AssignHandle(HandlesBase.Mixin): if lookup_name is None: return 0 viperlib.snprintf(lookup_name, 128, "%s.%s", class_name, dunder) - if HandlesExprCall.find_func_in_module(mod, lookup_name) is not None: + if ExprCallBase.find_func_in_module(mod, lookup_name) is not None: return 1 # 继承链祖先查找 mro_ptr: t.CSizeT | t.CPtr = HandlesStruct.get_mro_chain(pool, class_name) @@ -797,7 +800,7 @@ class AssignHandle(HandlesBase.Mixin): anc_lookup: str = pool.alloc(128) if anc_lookup is not None: viperlib.snprintf(anc_lookup, 128, "%s.%s", anc, dunder) - if HandlesExprCall.find_func_in_module(mod, anc_lookup) is not None: + if ExprCallBase.find_func_in_module(mod, anc_lookup) is not None: return 1 mi += 1 # 跨模块:类有 SHA1(stub 中声明该方法)视为存在 diff --git a/App/lib/core/Handles/HandlesExprCall.vp b/App/lib/core/Handles/HandlesExprCall.vp index dfb5f92..3e37b39 100644 --- a/App/lib/core/Handles/HandlesExprCall.vp +++ b/App/lib/core/Handles/HandlesExprCall.vp @@ -32,348 +32,25 @@ import lib.core.StubMerger as StubMerger _g_gen: t.CVoid | t.CPtr = None -def set_global_gen(gen: t.CVoid | t.CPtr) -> None: - """注入全局 gen 单例(BuildPipeline/main 调用)""" - global _g_gen - _g_gen = gen -# ============================================================ -# _lookup_module_sha1 — 按模块名查找 SHA1(委托到 gen._lookup_module_sha1) -# ============================================================ -# ============================================================ -# 模块 SHA1 查询(委托给 StubMerger 全局存储器) -# -# 翻译时用于跨模块函数调用名混淆: -# string.strchr(...) → call @{sha1_of_string}.strchr(...) -# -# 数据来源是 StubMerger.PopulateSha1MapStore/AppendToSha1MapStore -# 填充的全局存储器,不再维护独立的 SHA1 映射表副本。 -# ============================================================ - -def _lookup_module_sha1(mod_name: str) -> str: - """查找模块名对应的 SHA1,找不到返回 None(委托到 gen._lookup_module_sha1)""" - import lib.core.Gen.Generator as Generator - g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr)) - if g is not None: - return g._lookup_module_sha1(mod_name) - return None - -def _lookup_module_sha1_suffix(mod_suffix: str) -> str: - """后缀匹配查找模块 SHA1(委托到 gen._lookup_module_sha1_suffix)""" - import lib.core.Gen.Generator as Generator - g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr)) - if g is not None: - return g._lookup_module_sha1_suffix(mod_suffix) - return None - -# ============================================================ -# 全局 CExport 函数表(module_sha1 + func_name) -# -# t.CExport 函数定义时不加 SHA1 前缀(如 @strlen), -# 跨模块调用时需要查表确认目标函数是否是 CExport 函数。 -# 若是,使用裸名调用(@strlen);否则使用 @{sha1}.func。 -# 必须包含模块 SHA1 记录,避免同名跨模块函数冲突 -# (一个模块有 CExport 的 strlen→@strlen,另一个没有→@{sha1}.strlen)。 -# -# 注:表数据已迁入 gen 字段(CallGenMixin.CexportSha1Arr/CexportFuncArr/ -# CexportCount),本模块不再持有(P4 簇 1+2)。 -# ============================================================ -_CEXPORT_MAX: t.CDefine = 256 - -def register_cexport_func(sha1: str, func_name: str) -> int: - """注册 CExport 函数到全局表(委托到 gen.register_cexport_func)""" - import lib.core.Gen.Generator as Generator - g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr)) - if g is not None: - return g.register_cexport_func(sha1, func_name) - return 0 - -def is_cexport_func(sha1: str, func_name: str) -> int: - """检查 (sha1, func_name) 是否是 CExport 函数(委托到 gen.is_cexport_func)""" - import lib.core.Gen.Generator as Generator - g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr)) - if g is not None: - return g.is_cexport_func(sha1, func_name) - return 0 - -# ============================================================ -# _lookup_mod_sha1 - 从 from_imports 查找类所属模块的 SHA1 -# -# lookup_from_import 返回指向 from_imports 内部的指针,不是 null 终止 -# (如 "namespace_defs Gadget:namespace_defs ...")。此函数手动截断 -# 模块名,复制到新缓冲区,再查找 SHA1(精确+后缀匹配)。 -# ============================================================ -def _lookup_mod_sha1(pool: memhub.MemBuddy | t.CPtr, - from_imports: str, class_name: str, - allow_star_fallback: int = 1) -> str: - """从 from_imports 查找类所属模块的 SHA1(委托到 gen._lookup_mod_sha1)""" - import lib.core.Gen.Generator as Generator - g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr)) - if g is not None: - return g._lookup_mod_sha1(pool, from_imports, class_name, allow_star_fallback) - return None -# ============================================================ -# _lookup_sha1_from_modname_raw - 原始模块名 → SHA1 -# -# 截断模块名(lookup_from_import 返回内部指针,空格/冒号/null 分隔), -# 去掉相对导入前导点,再精确+后缀查找 SHA1。 -# 供 _lookup_mod_sha1 与 HandlesExpr._lookup_cross_module_cdefine 复用。 -# ============================================================ -def _lookup_sha1_from_modname_raw(pool: memhub.MemBuddy | t.CPtr, - mod_name_raw: str) -> str: - """从原始模块名查找 SHA1(委托到 gen._lookup_sha1_from_modname_raw)""" - import lib.core.Gen.Generator as Generator - g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr)) - if g is not None: - return g._lookup_sha1_from_modname_raw(pool, mod_name_raw) - return None - -# ============================================================ -# HandlesExprCall - 函数调用表达式处理(Mixin 继承模式) -# -# 工具函数和 FuncEntry 保留为模块级,ExprCallHandle 提供 trans 接口 -# ============================================================ - -# ============================================================ -# 在模块函数链表中按名称查找函数 -# ============================================================ -def find_func_in_module(mod: llvmlite.LLVMModule | t.CPtr, - name: str) -> llvmlite.Function | t.CPtr: - """在模块的函数链表中按名称查找函数(委托到 gen.find_func_in_module)""" - import lib.core.Gen.Generator as Generator - g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr)) - if g is not None: - return g.find_func_in_module(mod, name) - return None - -# ============================================================ -# _ensure_c_lib_declare - 为已知的 C 库函数创建 declare 声明 -# -# 对应 TPC 的 _C_LIB_FUNCS 机制。当裸名调用 memset/memmove/memcmp/ -# strcmp/strlen 等已知 C 库函数时,自动在当前模块创建 declare, -# 避免报 "裸名调用未定义且未导入" 错误。 -# memcpy 不在此处理(已有 _emit_llvm_memcpy_intrinsic 映射到 @llvm.memcpy)。 -# -# Args: -# pool: 内存池 -# mod: LLVM 模块 -# name: 函数名 -# -# Returns: -# Function 指针(已创建 declare),或 None 如果不是已知 C 库函数 -# ============================================================ -def _ensure_c_lib_declare(pool: memhub.MemBuddy | t.CPtr, - mod: llvmlite.LLVMModule | t.CPtr, - name: str) -> llvmlite.Function | t.CPtr: - """为已知的 C 库函数创建 declare 声明(委托到 gen._ensure_c_lib_declare)""" - import lib.core.Gen.Generator as Generator - g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr)) - if g is not None: - return g._ensure_c_lib_declare(pool, mod, name) - return None - -# ============================================================ -# _infer_external_func_ret_ty - 根据函数名推断外部函数返回类型 -# -# stubs 在翻译后才注入 IR,翻译时模块中无 stub 函数声明, -# 因此对 includes 库函数(如 string.strchr 返回 i8*)需根据 -# 函数名推断返回类型,避免指针被截断为 i32。 -# -# 覆盖 includes/string.py 所有导出函数: -# i8*: strcpy, strncpy, strchr, strrchr, strstr, memset, memset32, memcpy, memmove -# i64: strlen, atoll -# double: atof -# i8: samestr -# i32(默认): strcmp, strncmp, memcmp, strspn, atoi, split -# ============================================================ -def _infer_external_func_ret_ty(pool: memhub.MemBuddy | t.CPtr, - func_name: str) -> llvmlite.LLVMType | t.CPtr: - """根据函数名推断外部 includes 函数的返回类型(委托到 gen._infer_external_func_ret_ty)""" - import lib.core.Gen.Generator as Generator - g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr)) - if g is not None: - return g._infer_external_func_ret_ty(pool, func_name) - return None - -# ============================================================ -# _get_external_func_param_ty - 获取外部函数第 idx 个参数的期望类型 -# -# stubs 翻译时未注入,需推断参数类型以提升字面量(如 i32→i64), -# 避免 declare(i64) 与 call(i32) 类型不匹配。 -# -# 注意:stubs 翻译时 ULONG(t.CUnsignedLong) 在 LLVM IR 中被翻译为 i64 -# (因为 LLVM 中 long 是 64 位),因此 Win32 API 中所有 ULONG/DWORD/SIZE_T -# 参数在 declare 中都是 i64。call 时必须匹配,否则类型不匹配。 -# -# 策略:对 Win32 API 函数的所有非指针参数(字面量)都提升为 i64, -# 以匹配 declare 中 ULONG 被翻译为 i64 的情况。 -# -# 指针参数(VOIDPTR/HANDLE)不在此处理,由调用点的 inttoptr 处理。 -# ============================================================ -def _get_external_func_param_ty(pool: memhub.MemBuddy | t.CPtr, - func_name: str, - param_idx: int) -> llvmlite.LLVMType | t.CPtr: - """获取外部函数第 param_idx 个参数的期望类型(委托到 gen._get_external_func_param_ty)""" - import lib.core.Gen.Generator as Generator - g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr)) - if g is not None: - return g._get_external_func_param_ty(pool, func_name, param_idx) - return None - -# ============================================================ -# _emit_llvm_memcpy_intrinsic — 将 memcpy 调用映射到 @llvm.memcpy 内联函数 -# -# 背景: string.memcpy 是 t.CExport 函数,跨模块调用生成 @memcpy 裸名调用。 -# 但在 monomorphization 场景下,目标模块的 deps.txt 可能不含 string, -# 导致 @memcpy 声明缺失,链接器报 undefined value。 -# -# 解决: 将 memcpy 调用映射到 LLVM 内联函数 @llvm.memcpy, -# 该内联函数在当前模块内声明,无需跨模块依赖。 -# -# @llvm.memcpy 签名: void (i8* dst, i8* src, i64 len, i1 isvolatile) -# C memcpy 签名: i8* (i8* dst, i8* src, i64 len) — 返回 dst -# -# Args: -# args_head: 参数链表头(dst, src, num),通过 Value.Next 链接 -# arg_count: 参数数量(应为 3) -# -# Returns: -# dst 值(匹配 C memcpy 语义: 返回 dest 指针) -# ============================================================ -def _emit_llvm_memcpy_intrinsic(pool: memhub.MemBuddy | t.CPtr, - builder: llvmlite.IRBuilder | t.CPtr, - mod: llvmlite.LLVMModule | t.CPtr, - dst_val: llvmlite.Value | t.CPtr, - src_val: llvmlite.Value | t.CPtr, - num_val: llvmlite.Value | t.CPtr) -> llvmlite.Value | t.CPtr: - """将 memcpy 调用映射到 @llvm.memcpy 内联函数(委托到 gen._emit_llvm_memcpy_intrinsic)""" - import lib.core.Gen.Generator as Generator - g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr)) - if g is not None: - return g._emit_llvm_memcpy_intrinsic(pool, builder, mod, dst_val, src_val, num_val) - return None - -# ============================================================ -# c.Deref(ptr) — 解引用指针,按指针 pointee 类型读取 -# -# 生成: %N = load , * %ptr -# 返回 pointee 类型的值 -# -# 注意: 必须按 ptr 的 pointee 类型决定读取宽度。 -# - i8* (str/bytes/字符遍历) → load i8 -# - i64* (t.CUInt64T, 块头部) → load i64(memhub 的 free list 链表读 8 字节头部) -# 之前固定 load i8 导致 memhub 读块头部只读到低 8 位, -# free list 的 next 指针被截断成 0x88 等垃圾值,alloc 崩溃。 -# ============================================================ -def translate_c_deref(pool: memhub.MemBuddy | t.CPtr, - builder: llvmlite.IRBuilder | t.CPtr, - mod: llvmlite.LLVMModule | t.CPtr, - cl: ast.Call | t.CPtr, - trans: HT.Translator | t.CPtr = None) -> llvmlite.Value | t.CPtr: - """c.Deref(ptr) → load 按 ptr 的 pointee 类型(委托到 gen.translate_c_deref)""" - import lib.core.Gen.Generator as Generator - g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr)) - if g is not None: - return g.translate_c_deref(pool, builder, mod, cl, trans) - return None - -# ============================================================ -# c.DerefAs(ptr, val) — 解引用写入,*ptr = val -# -# 生成: %pc = bitcast i8* %ptr to * -# store %val, * %pc -# ============================================================ -def translate_c_derefas(pool: memhub.MemBuddy | t.CPtr, - builder: llvmlite.IRBuilder | t.CPtr, - mod: llvmlite.LLVMModule | t.CPtr, - cl: ast.Call | t.CPtr, - trans: HT.Translator | t.CPtr = None) -> llvmlite.Value | t.CPtr: - """c.DerefAs(ptr, val) → store val to ptr(bitcast 后 store)(委托到 gen.translate_c_derefas)""" - import lib.core.Gen.Generator as Generator - g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr)) - if g is not None: - return g.translate_c_derefas(pool, builder, mod, cl, trans) - return None - -# ============================================================ -# c.Set(a, b) — 赋值语义 a = b(与 c.DerefAs 的指针语义不同) -# -# c.DerefAs(ptr, val) 是 *ptr = val(指针解引用写); -# c.Set(a, b) 是 a = b(a 为左值),a 支持三种形态: -# 1. c.Deref(ptr) → *ptr = b(zlib/vipermath 的 c.Set(c.Deref(p), v) 用法) -# 2. Name 变量 → 变量赋值(含 global/nonlocal/局部) -# 3. Attribute → 字段赋值(GEP + store) -# ============================================================ -def translate_c_set(pool: memhub.MemBuddy | t.CPtr, - builder: llvmlite.IRBuilder | t.CPtr, - mod: llvmlite.LLVMModule | t.CPtr, - cl: ast.Call | t.CPtr, - trans: HT.Translator | t.CPtr = None) -> llvmlite.Value | t.CPtr: - """c.Set(a, b) → a = b(赋值语义,a 为左值)(委托到 gen.translate_c_set)""" - import lib.core.Gen.Generator as Generator - g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr)) - if g is not None: - return g.translate_c_set(pool, builder, mod, cl, trans) - return None -# ============================================================ -# c.Addr(var) — 取变量地址,返回 alloca 指针(不 load) -# -# 用于获取栈变量的可写地址,配合 c.DerefAs 使用 -# ============================================================ -def translate_c_addr(pool: memhub.MemBuddy | t.CPtr, - builder: llvmlite.IRBuilder | t.CPtr, - mod: llvmlite.LLVMModule | t.CPtr, - cl: ast.Call | t.CPtr, - trans: HT.Translator | t.CPtr = None) -> llvmlite.Value | t.CPtr: - """c.Addr(var) → 返回变量的 alloca 指针(不 load)(委托到 gen.translate_c_addr)""" - import lib.core.Gen.Generator as Generator - g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr)) - if g is not None: - return g.translate_c_addr(pool, builder, mod, cl, trans) - return None -# ============================================================ -# c.Load(a, b) — 指针间复制: *a = *b -# -# 加载 b 指向的值,存储到 a 指向的地址。 -# 生成: %pc_src = bitcast i8* %src to * -# %loaded = load , * %pc_src -# %pc_dst = bitcast i8* %dst to * -# store %loaded, * %pc_dst -# ============================================================ -def translate_c_load(pool: memhub.MemBuddy | t.CPtr, - builder: llvmlite.IRBuilder | t.CPtr, - mod: llvmlite.LLVMModule | t.CPtr, - cl: ast.Call | t.CPtr, - trans: HT.Translator | t.CPtr = None) -> llvmlite.Value | t.CPtr: - """c.Load(a, b) → *a = *b(加载 b 的值,存储到 a)(委托到 gen.translate_c_load)""" - import lib.core.Gen.Generator as Generator - g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr)) - if g is not None: - return g.translate_c_load(pool, builder, mod, cl, trans) - return None -# ============================================================ -# c.Asm — 内联汇编支持 -# -# 生成: %N = call asm sideeffect "", ""() -# 或: call void asm sideeffect "", ""() -# -# 操作数按出现顺序编号 $0, $1, ...(用户需按输出在前写 f-string) -# ============================================================ -ASM_MAX_OPERANDS: t.CDefine = 16 -ASM_TEXT_BUF_SIZE: t.CDefine = 2048 -ASM_CONST_BUF_SIZE: t.CDefine = 512 -ASM_ARGS_BUF_SIZE: t.CDefine = 512 -ASM_LINE_BUF_SIZE: t.CDefine = 4096 + + + + + + + + # ============================================================ # AsmOperand - 内联汇编操作数条目 @@ -385,1119 +62,93 @@ class AsmOperand: Constraint: str # 约束字符串 (如 "r", "=r") IsOutput: int # 1=输出, 0=输入 -# ============================================================ -# _asm_append_cstr — 将 C 字符串 src 追加到 dst 末尾 -# ============================================================ -def _asm_append_cstr(dst: str, dst_size: t.CSizeT, - src: str): - """将 C 字符串 src 追加到 dst 末尾(委托到 gen._asm_append_cstr)""" - import lib.core.Gen.Generator as Generator - g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr)) - if g is not None: - g._asm_append_cstr(dst, dst_size, src) - -# ============================================================ -# _asm_escape_for_ir — 将汇编文本转义为 LLVM IR 字符串内容 -# -# \n → \0A, " → \22, \ → \5C -# ============================================================ -def _asm_escape_for_ir(pool: memhub.MemBuddy | t.CPtr, - src: str) -> str: - """转义汇编文本用于 LLVM IR 字符串字面量(委托到 gen._asm_escape_for_ir)""" - import lib.core.Gen.Generator as Generator - g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr)) - if g is not None: - return g._asm_escape_for_ir(pool, src) - return None - -# ============================================================ -# _resolve_register — 将 ASM_DESCR 属性名映射到约束字符串 -# ============================================================ -def _resolve_register(attr_name: str) -> str: - """将 t.ASM_DESCR.XXX 的属性名映射到约束字符串值(委托到 gen._resolve_register)""" - import lib.core.Gen.Generator as Generator - g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr)) - if g is not None: - return g._resolve_register(attr_name) - return "" - -# ============================================================ -# _resolve_asm_descr — 递归解析约束表达式 -# -# 支持: -# t.ASM_DESCR.XXX → _resolve_register(XXX) -# expr | expr (BinOp BitOr) → 拼接 -# "string" (Constant) → 直接返回 -# ============================================================ -def _resolve_asm_descr(pool: memhub.MemBuddy | t.CPtr, - node: ast.AST | t.CPtr) -> str: - """递归解析约束表达式,返回约束字符串(委托到 gen._resolve_asm_descr)""" - import lib.core.Gen.Generator as Generator - g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr)) - if g is not None: - return g._resolve_asm_descr(pool, node) - return "" - -# ============================================================ -# _asm_get_operand — 获取操作数数组中第 idx 个元素的指针 -# ============================================================ -def _asm_get_operand(base: AsmOperand | t.CPtr, - idx: int) -> AsmOperand | t.CPtr: - """获取操作数数组中第 idx 个元素的指针(委托到 gen._asm_get_operand)""" - import lib.core.Gen.Generator as Generator - g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr)) - if g is not None: - return g._asm_get_operand(base, idx) - return None - -# ============================================================ -# _asm_is_c_call — 检查 Call 节点是否是 c.XXX 调用 -# -# 返回 attr_name(如 "AsmInp"/"AsmOut"),不是则返回 None -# ============================================================ -def _asm_is_c_call(node: ast.Call | t.CPtr) -> str: - """检查 Call 节点是否是 c.XXX 调用,返回属性名或 None(委托到 gen._asm_is_c_call)""" - import lib.core.Gen.Generator as Generator - g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr)) - if g is not None: - return g._asm_is_c_call(node) - return None - -# ============================================================ -# _asm_add_operand — 添加操作数到数组 -# -# 返回 1 成功, 0 失败(数组已满) -# ============================================================ -def _asm_add_operand(operands: AsmOperand | t.CPtr, - count: int, - val: llvmlite.Value | t.CPtr, - constraint: str, - is_output: int) -> int: - """添加操作数到数组,返回新计数(失败返回原计数)(委托到 gen._asm_add_operand)""" - import lib.core.Gen.Generator as Generator - g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr)) - if g is not None: - return g._asm_add_operand(operands, count, val, constraint, is_output) - return 0 - -# ============================================================ -# translate_c_asm — 翻译 c.Asm 内联汇编 -# -# 语法: -# c.Asm("nop", [t.ASM_DESCR.CLOBBER_MEMORY]) -# c.Asm(f"mov rax, {c.AsmInp(val, t.ASM_DESCR.REG_ANY)}", op=[...]) -# c.Asm(f"...", out=[c.AsmOut(var, t.ASM_DESCR.OUTPUT_REG)], op=[...]) -# ============================================================ -def translate_c_asm(pool: memhub.MemBuddy | t.CPtr, - builder: llvmlite.IRBuilder | t.CPtr, - mod: llvmlite.LLVMModule | t.CPtr, - cl: ast.Call | t.CPtr, - trans: HT.Translator | t.CPtr = None) -> llvmlite.Value | t.CPtr: - """翻译 c.Asm 内联汇编,返回结果 Value(委托到 gen.translate_c_asm)""" - import lib.core.Gen.Generator as Generator - g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr)) - if g is not None: - return g.translate_c_asm(pool, builder, mod, cl, trans) - return None - -# ============================================================ -# c.LLVMIR — 内联 LLVM IR(无返回值,直接嵌入原始 IR 文本) -# -# 语法: -# c.LLVMIR(f"add i32 {c.LInp(a)}, {c.LInp(b)}") -# c.LLVMIR(f"{c.LOut(result)} = add i32 {c.LInp(a)}, {c.LInp(b)}") -# -# c.LInp(expr) - 输入操作数,替换为 expr 的 LLVM 值引用文本(SSA 名 "%x" 或常量 "42") -# c.LOut(expr) - 输出操作数:为 expr 变量分配唯一 SSA 寄存器 %llvmirN, -# 模板嵌入后自动追加 store %llvmirN, * %expr 写回变量 -# -# 语义(2026-08-08 用户决策):不做指令解析,模板文本直接嵌入当前基本块, -# 返回 None(无返回值)。ret_ty 第二参数已废弃(兼容忽略)。 -# ============================================================ - -LLVMIR_MAX_OPS: t.CDefine = 16 -LLVMIR_TEMPLATE_BUF: t.CDefine = 512 - -# 注:LOut 唯一 SSA 寄存器名计数器已迁入 gen 字段(CallGenMixin.LLVMIRRegSeq), -# 本模块不再持有(P4 簇 1+2)。 - -# ============================================================ -# translate_c_llvmir — 翻译 c.LLVMIR 内联 LLVM IR -# ============================================================ -def translate_c_llvmir(pool: memhub.MemBuddy | t.CPtr, - builder: llvmlite.IRBuilder | t.CPtr, - mod: llvmlite.LLVMModule | t.CPtr, - cl: ast.Call | t.CPtr, - trans: HT.Translator | t.CPtr = None) -> llvmlite.Value | t.CPtr: - """c.LLVMIR 内联 LLVM IR:无返回值,直接嵌入原始 IR 文本(委托到 gen.translate_c_llvmir)""" - import lib.core.Gen.Generator as Generator - g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr)) - if g is not None: - return g.translate_c_llvmir(pool, builder, mod, cl, trans) - return None - -# ============================================================ -# _apply_struct_defaults — 应用结构体字段的默认值 -# -# 在 zeroinitializer 之后、显式参数之前调用 -# 遍历所有字段,对有默认值的字段翻译并 store -# 显式参数(位置/关键字)后续会覆盖默认值 -# ============================================================ -def _apply_struct_defaults(pool: memhub.MemBuddy | t.CPtr, - builder: llvmlite.IRBuilder | t.CPtr, - mod: llvmlite.LLVMModule | t.CPtr, - struct_ty: llvmlite.LLVMType | t.CPtr, - class_name: str, - tmp: llvmlite.Value | t.CPtr, - trans: HT.Translator | t.CPtr): - """应用结构体字段的默认值(委托到 gen._apply_struct_defaults)""" - import lib.core.Gen.Generator as Generator - g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr)) - if g is not None: - g._apply_struct_defaults(pool, builder, mod, struct_ty, class_name, tmp, trans) - -# ============================================================ -# _translate_struct_ctor — 结构体构造函数 Point(10, 20) -# -# 生成: -# %tmp = alloca {i32, i32} -# store {i32, i32} zeroinitializer, {i32, i32}* %tmp -# %f0 = getelementptr {i32, i32}, {i32, i32}* %tmp, i32 0, i32 0 -# store i32 10, i32* %f0 -# %f1 = getelementptr {i32, i32}, {i32, i32}* %tmp, i32 0, i32 1 -# store i32 20, i32* %f1 -# %result = load {i32, i32}, {i32, i32}* %tmp -# ============================================================ -def _translate_struct_ctor(pool: memhub.MemBuddy | t.CPtr, - builder: llvmlite.IRBuilder | t.CPtr, - mod: llvmlite.LLVMModule | t.CPtr, - struct_ty: llvmlite.LLVMType | t.CPtr, - class_name: str, - cargs: list[ast.AST | t.CPtr] | t.CPtr, - can: t.CSizeT, - trans: HT.Translator | t.CPtr) -> llvmlite.Value | t.CPtr: - """结构体构造函数:按字段顺序 store 参数值,返回结构体值(委托到 gen._translate_struct_ctor)""" - import lib.core.Gen.Generator as Generator - g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr)) - if g is not None: - return g._translate_struct_ctor(pool, builder, mod, struct_ty, class_name, cargs, can, trans) - return None - - -# ============================================================ -# _translate_renum_construct — REnum 变体构造函数 -# -# 语法: ClassName.VariantName(args...) -# 如 LLVMType.Int(1) → 构造 LLVMType 的 Int 变体,__tag=0,_p1=1 -# -# 生成 IR: -# %tmp = alloca {i32, i32, ...} ; REnum 类型 -# store zeroinitializer, %tmp ; 清零 -# %tag_ptr = gep %tmp, 0, 0 ; __tag 字段 -# store i32 , %tag_ptr ; 写入 tag -# %p1_ptr = gep %tmp, 0, 1 ; _p1 字段 -# store , %p1_ptr ; 写入 payload[0] -# ... (更多 payload 字段) -# return %tmp ; 返回指针 -# -# 对应 TPC 的 _HandleREnumConstructLlvm -# ============================================================ -def _translate_renum_construct(pool: memhub.MemBuddy | t.CPtr, - builder: llvmlite.IRBuilder | t.CPtr, - mod: llvmlite.LLVMModule | t.CPtr, - class_name: str, - variant_name: str, - tag_value: int, - cargs: list[ast.AST | t.CPtr] | t.CPtr, - can: t.CSizeT, - trans: HT.Translator | t.CPtr) -> llvmlite.Value | t.CPtr: - """构造 REnum 变体实例,返回指向 alloca 的指针(委托到 gen._translate_renum_construct)""" - import lib.core.Gen.Generator as Generator - g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr)) - if g is not None: - return g._translate_renum_construct(pool, builder, mod, class_name, variant_name, - tag_value, cargs, can, trans) - return None - - -# ============================================================ -# _do_virtual_call — 通过虚表间接调用虚方法 -# -# IR 模式: -# %1 = getelementptr StructTy, StructTy* %self, i32 0, i32 0 ; i8** -# %2 = load i8*, i8** %1 ; i8* (vtable ptr) -# %3 = bitcast i8* %2 to {i8*, ...}* ; vtable typed ptr -# %4 = getelementptr {i8*, ...}, {i8*, ...}* %3, i32 0, i32 N ; i8** -# %5 = load i8*, i8** %4 ; i8* (func ptr) -# %6 = bitcast i8* %5 to RetTy(Params)* ; func typed ptr -# call RetTy %6(Params %self, ...) -# -# 参数: -# args_head — 已构建好的参数链表头(self_ptr 为首节点) -# args_count — 参数总数(含 self) -# found_func — 方法对应的 Function 对象(用于推断函数签名) -# ret_ty — 返回类型 -# ============================================================ -def _do_virtual_call(pool: memhub.MemBuddy | t.CPtr, - builder: llvmlite.IRBuilder | t.CPtr, - mod: llvmlite.LLVMModule | t.CPtr, - class_name: str, - method_name: str, - self_ptr: llvmlite.Value | t.CPtr, - args_head: llvmlite.Value | t.CPtr, - args_count: int, - found_func: llvmlite.Function | t.CPtr, - ret_ty: llvmlite.LLVMType | t.CPtr, - vtable_base: llvmlite.Value | t.CPtr = None) -> llvmlite.Value | t.CPtr: - """通过虚表间接调用虚方法,返回 call 结果(void 方法返回 None)(委托到 gen._do_virtual_call)""" - import lib.core.Gen.Generator as Generator - g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr)) - if g is not None: - return g._do_virtual_call(pool, builder, mod, class_name, method_name, - self_ptr, args_head, args_count, found_func, ret_ty, vtable_base) - return None - -# ============================================================ -# _call_method_on_ptr — 在结构体指针上调用方法 -# -# 辅助函数:构造 ClassName.method_name 调用,self 指针为首个参数 -# 如果该方法在虚表中,则走虚方法分发路径(间接调用) -# ============================================================ -def _call_method_on_ptr(pool: memhub.MemBuddy | t.CPtr, - builder: llvmlite.IRBuilder | t.CPtr, - mod: llvmlite.LLVMModule | t.CPtr, - class_name: str, - method_name: str, - self_ptr: llvmlite.Value | t.CPtr, - extra_args: t.CSizeT | t.CPtr, - extra_count: int, - trans: HT.Translator | t.CPtr, - node: ast.AST | t.CPtr = None) -> llvmlite.Value | t.CPtr: - """在结构体指针上调用方法,返回 call 结果(void 方法返回 None)(委托到 gen._call_method_on_ptr)""" - import lib.core.Gen.Generator as Generator - g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr)) - if g is not None: - return g._call_method_on_ptr(pool, builder, mod, class_name, method_name, - self_ptr, extra_args, extra_count, trans, node) - return None - - -# ============================================================ -# _ensure_method_declare - 为跨模块方法调用创建 declare 声明 -# -# 当 found_func 为 None(stub 未注入或跨模块调用)时, -# 在当前模块中创建函数声明,避免 llc 报 undefined value。 -# ============================================================ -def _ensure_method_declare(pool: memhub.MemBuddy | t.CPtr, - mod: llvmlite.LLVMModule | t.CPtr, - call_name: str, - ret_ty: llvmlite.LLVMType | t.CPtr, - param_head: llvmlite.ParamNode | t.CPtr, - param_count: int): - """为跨模块方法调用创建 declare 声明(委托到 gen._ensure_method_declare)""" - import lib.core.Gen.Generator as Generator - g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr)) - if g is not None: - g._ensure_method_declare(pool, mod, call_name, ret_ty, param_head, param_count) - -# ============================================================ -# _lookup_method_ret_ty_via_vpi - 从 vpi stub 返回注解缓存精确获取方法返回类型 -# -# 方法定义处(.vpi stub)的返回注解(如 json.JsonValue._pool_alloc → -# "str")在 stub 注入时由 VpiReader 缓存(_cache_vpi_return_annots_text)。 -# 此函数按 模块SHA1 + 类名 + 方法名 查缓存并纯字符串解析为 LLVMType。 -# 无需硬编码白名单——返回类型始终来自方法定义处。 -# ============================================================ -def _lookup_method_ret_ty_via_vpi(pool: memhub.MemBuddy | t.CPtr, - cls_sha1: str, - cls_name: str, - method_name: str) -> llvmlite.LLVMType | t.CPtr: - """从 vpi stub 返回注解缓存获取方法返回类型,未命中返回 None(委托到 gen._lookup_method_ret_ty_via_vpi)""" - import lib.core.Gen.Generator as Generator - g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr)) - if g is not None: - return g._lookup_method_ret_ty_via_vpi(pool, cls_sha1, cls_name, method_name) - return None - - -# ============================================================ -# _special_method_ret_ty - 编译器内置特殊方法的固定返回类型 -# -# __before_init__ / __init__:编译器生成/约定返回 void -# __new__:返回 Ptr(StructTy)(存储空间指针) -# -# 这些方法不存在于源码(vpi stub 无条目),跨模块调用时 -# found_func/text.ll/vpi 缓存必然未命中,但返回类型是编译器 -# 确定性语义(与 HandlesClassDef._translate_method 3543-3548 一致), -# 在此直接固定,不触发 fail-fast 误报。非特殊方法返回 None。 -# ============================================================ -def _special_method_ret_ty(pool: memhub.MemBuddy | t.CPtr, - class_name: str, - method_name: str) -> llvmlite.LLVMType | t.CPtr: - """编译器内置特殊方法的固定返回类型;非特殊返回 None(委托到 gen._special_method_ret_ty)""" - import lib.core.Gen.Generator as Generator - g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr)) - if g is not None: - return g._special_method_ret_ty(pool, class_name, method_name) - return None - - -# ============================================================ -# _fail_method_ret_ty - 方法返回类型无法精确获取时 fail-fast -# -# 返回类型来源(按序):当前模块函数 → text.ll define → vpi stub 返回注解缓存。 -# 全部未命中时立即 ERROR + 错误堆栈终止,绝不按名推断白名单/静默默认 i32。 -# -# node: 调用点 AST 节点(可选,用于 ERROR 堆栈定位) -# ============================================================ -def _fail_method_ret_ty(method_name: str, - node: ast.AST | t.CPtr = None) -> llvmlite.LLVMType | t.CPtr: - """方法返回类型无法精确获取时 fail-fast(ERROR + 错误堆栈)(委托到 gen._fail_method_ret_ty)""" - import lib.core.Gen.Generator as Generator - g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr)) - if g is not None: - return g._fail_method_ret_ty(method_name, node) - return None - - -# ============================================================ -# 跨模块方法返回类型查找(从 text.ll) -# -# Phase A 翻译每个源文件后生成 text.ll,其中 define 行包含 -# 方法的实际返回类型。当 Phase A 翻译后续文件调用跨模块方法时, -# 方法调用默认返回 i32,导致指针返回值被截断。 -# _LookupMethodRetTyFromTextLL 读取依赖模块的 text.ll,从 define -# 行提取实际返回类型,避免指针截断(未命中时回退 vpi stub 缓存)。 -# ============================================================ - -# ============================================================ -# SetTempDir - 设置 temp 目录路径 -# -# 在 Phase2.py 的 Phase A 翻译前调用,使 CallGenMixin -# 能够读取依赖模块的 text.ll 文件。 -# ============================================================ -def SetTempDir(temp_dir: str): - """设置 temp 目录路径(供跨模块方法返回类型查找使用)(委托到 gen.SetTempDir)""" - import lib.core.Gen.Generator as Generator - g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr)) - if g is not None: - g.SetTempDir(temp_dir) - - -# ============================================================ -# _ParseLLVMRetTyStr - 将 LLVM IR 返回类型字符串转换为 llvmlite.LLVMType -# -# 从 define 行中提取的返回类型字符串(define 与 @ 之间的内容), -# 转换为 llvmlite.LLVMType 对象。 -# -# 支持的类型: -# void → Void -# i8/i16/i32/i64 → Int8/Int16/Int32/Int64 -# double → Double, float → Float -# 任何含 * 的类型 → Ptr(Int8)(通用指针,保留 64 位地址) -# -# Args: -# pool: 内存池 -# buf: 包含类型字符串的缓冲区 -# start: 类型字符串起始位置 -# end: 类型字符串结束位置(不含) -# -# Returns: -# LLVM 类型对象,或 None(无法解析) -# ============================================================ -def _ParseLLVMRetTyStr(pool: memhub.MemBuddy | t.CPtr, - buf: bytes, - start: t.CSizeT, - end: t.CSizeT) -> llvmlite.LLVMType | t.CPtr: - """将 LLVM IR 返回类型字符串转换为 llvmlite.LLVMType(委托到 gen._ParseLLVMRetTyStr)""" - import lib.core.Gen.Generator as Generator - g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr)) - if g is not None: - return g._ParseLLVMRetTyStr(pool, buf, start, end) - return None - - -# ============================================================ -# _LookupMethodRetTyFromTextLL - 从依赖模块的 text.ll 查找方法返回类型 -# -# 读取 {temp_dir}/{sha1[0:2]}/{sha1}.text.ll (level=1),搜索 -# define 行中包含 "{sha1}.{class_name}.{method_name}" 的函数, -# 提取返回类型并转换为 llvmlite.LLVMType。 -# -# 解决问题: 旧实现 _infer_method_ret_ty(已移除)默认返回 i32,导致指针返回值 -# 被 inttoptr 截断为 32 位(coerce_to_type line 238-239)。 -# 本函数从 text.ll 获取实际返回类型,避免截断。 -# -# Args: -# pool: 内存池 -# class_sha1: 类所属模块的 SHA1 -# class_name: 类名 -# method_name: 方法名 -# -# Returns: -# LLVM 类型对象,或 None(未找到/text.ll 不存在) -# ============================================================ -def _LookupMethodRetTyFromTextLL(pool: memhub.MemBuddy | t.CPtr, - class_sha1: str, - class_name: str, - method_name: str, - use_bare: int = 0) -> llvmlite.LLVMType | t.CPtr: - """从依赖模块的 text.ll 中查找方法返回类型(委托到 gen._LookupMethodRetTyFromTextLL)""" - import lib.core.Gen.Generator as Generator - g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr)) - if g is not None: - return g._LookupMethodRetTyFromTextLL(pool, class_sha1, class_name, method_name, use_bare) - return None - - -# ============================================================ -# 属性方法(@property/@x.setter/@x.deleter)与静态/类方法调用辅助 -# -# 元数据表由 HandlesClassDef 在类翻译/预注册阶段填充, -# 这里负责把 obj.prop / obj.prop=v / del obj.prop / Class.method() -# 翻译为对应的 {sha1}.ClassName.prop 系列函数调用。 -# ============================================================ - -# ============================================================ -# _translate_property_call — 翻译属性方法调用 -# -# 与 _translate_method_call 的调用名/返回类型解析逻辑一致: -# 1. 优先用模块中已有的函数(精确/后缀匹配,来自 stub 注入) -# 2. 否则用类所属模块的 SHA1 构造 "{sha1}.ClassName.method" 调用名 -# 3. 返回类型:函数实类型 → text.ll 查找 → 按方法名推断(默认 i32) -# -# call_head/call_count: 已构建好的参数链表(如 getter 只有 obj 一个参数) -# ============================================================ -def _translate_property_call(pool: memhub.MemBuddy | t.CPtr, - builder: llvmlite.IRBuilder | t.CPtr, - mod: llvmlite.LLVMModule | t.CPtr, - class_name: str, - method_name: str, - call_head: llvmlite.Value | t.CPtr, - call_count: int, - trans: HT.Translator | t.CPtr) -> llvmlite.Value | t.CPtr: - """翻译属性/静态方法调用,返回 call 结果 Value(委托到 gen._translate_property_call)""" - import lib.core.Gen.Generator as Generator - g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr)) - if g is not None: - return g._translate_property_call(pool, builder, mod, class_name, method_name, - call_head, call_count, trans) - return None - - -# ============================================================ -# _resolve_obj_class_name — 解析对象表达式的类名(短名) -# -# 优先从变量注解(AnnotClassName)解析(如 "memhub.MemBuddy" → "MemBuddy"), -# 失败时从 LLVM 类型解析(Ptr(Struct) → 类名)。 -# 供属性访问/赋值/删除识别 property 时使用。 -# ============================================================ -def _resolve_obj_class_name(pool: memhub.MemBuddy | t.CPtr, - trans: HT.Translator | t.CPtr, - obj_node: ast.AST | t.CPtr) -> str: - """解析对象表达式的类名(短名),失败返回 None(委托到 gen._resolve_obj_class_name)""" - import lib.core.Gen.Generator as Generator - g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr)) - if g is not None: - return g._resolve_obj_class_name(pool, trans, obj_node) - return None - - -# ============================================================ -# _try_property_getter_attr — 尝试将 obj.attr 翻译为 property getter 调用 -# -# 检查 obj 的类是否有 @property/@x.getter 的 attr 方法; -# 若有则生成 call Class.attr(obj) 并返回调用结果 Value;否则返回 None。 -# ============================================================ -def _try_property_getter_attr(pool: memhub.MemBuddy | t.CPtr, - builder: llvmlite.IRBuilder | t.CPtr, - mod: llvmlite.LLVMModule | t.CPtr, - at_node: ast.Attribute | t.CPtr, - obj_ptr: llvmlite.Value | t.CPtr, - trans: HT.Translator | t.CPtr, - fallback_class_name: str = None) -> llvmlite.Value | t.CPtr: - """尝试 property getter 属性访问,返回调用结果 Value;非 getter 返回 None(委托到 gen._try_property_getter_attr)""" - import lib.core.Gen.Generator as Generator - g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr)) - if g is not None: - return g._try_property_getter_attr(pool, builder, mod, at_node, obj_ptr, - trans, fallback_class_name) - return None - - -# ============================================================ -# _try_property_setter — 尝试将 obj.attr = v 翻译为 property setter 调用 -# -# 检查 obj 的类是否有 @x.setter 的 attr 方法; -# 若有则生成 call Class.attr$set(obj, v),返回 1;否则返回 0。 -# ============================================================ -def _try_property_setter(pool: memhub.MemBuddy | t.CPtr, - builder: llvmlite.IRBuilder | t.CPtr, - mod: llvmlite.LLVMModule | t.CPtr, - target_attr: ast.Attribute | t.CPtr, - rhs_val: llvmlite.Value | t.CPtr, - trans: HT.Translator | t.CPtr) -> int: - """尝试 property setter 赋值,返回 1=已处理(生成调用)(委托到 gen._try_property_setter)""" - import lib.core.Gen.Generator as Generator - g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr)) - if g is not None: - return g._try_property_setter(pool, builder, mod, target_attr, rhs_val, trans) - return 0 - - -# ============================================================ -# _try_property_deleter — 尝试将 del obj.attr 翻译为 property deleter 调用 -# -# 检查 obj 的类是否有 @x.deleter 的 attr 方法; -# 若有则生成 call Class.attr$del(obj),返回 1;否则返回 0。 -# ============================================================ -def _try_property_deleter(pool: memhub.MemBuddy | t.CPtr, - builder: llvmlite.IRBuilder | t.CPtr, - mod: llvmlite.LLVMModule | t.CPtr, - target_attr: ast.Attribute | t.CPtr, - trans: HT.Translator | t.CPtr) -> int: - """尝试 property deleter 删除,返回 1=已处理(生成调用)(委托到 gen._try_property_deleter)""" - import lib.core.Gen.Generator as Generator - g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr)) - if g is not None: - return g._try_property_deleter(pool, builder, mod, target_attr, trans) - return 0 - - -# ============================================================ -# _translate_static_class_call — 翻译 ClassName.method(args) 静态/类方法调用 -# -# @staticmethod: 直接 call Class.method(args...),无 self -# @classmethod: 在参数前插入栈上分配的类实例指针(与 TPC 一致) -# ============================================================ -def _translate_static_class_call(pool: memhub.MemBuddy | t.CPtr, - builder: llvmlite.IRBuilder | t.CPtr, - mod: llvmlite.LLVMModule | t.CPtr, - class_name: str, - method_name: str, - cl: ast.Call | t.CPtr, - trans: HT.Translator | t.CPtr) -> llvmlite.Value | t.CPtr: - """翻译类名静态/类方法调用,返回 call 结果 Value;非静态/类方法返回 None(委托到 gen._translate_static_class_call)""" - import lib.core.Gen.Generator as Generator - g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr)) - if g is not None: - return g._translate_static_class_call(pool, builder, mod, class_name, method_name, cl, trans) - return None - - -# ============================================================ -# _translate_method_call - 翻译方法调用 obj.method(args) -# -# 生成: call @SHA1.ClassName.method_name(Ptr(StructTy) %obj, args...) -# -# obj_ptr 是对象变量的 alloca(Ptr(StructTy)),作为 self 参数传入 -# ============================================================ -def _translate_method_call(pool: memhub.MemBuddy | t.CPtr, - builder: llvmlite.IRBuilder | t.CPtr, - mod: llvmlite.LLVMModule | t.CPtr, - class_name: str, - method_name: str, - obj_ptr: llvmlite.Value | t.CPtr, - cl: ast.Call | t.CPtr, - trans: HT.Translator | t.CPtr) -> llvmlite.Value | t.CPtr: - """翻译方法调用,返回 call 结果 Value(委托到 gen._translate_method_call)""" - import lib.core.Gen.Generator as Generator - g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr)) - if g is not None: - return g._translate_method_call(pool, builder, mod, class_name, method_name, - obj_ptr, cl, trans) - return None - -# ============================================================ -# _kwarg_name_matches — 检查关键字参数名是否匹配函数参数名 -# -# 函数参数名在 LLVM IR 中带 % 前缀(如 "%a"),关键字参数名无前缀(如 "a") -# 跳过 % 前缀后逐字符比较 -# ============================================================ -def _kwarg_name_matches(kw_arg: str, - param_name: str) -> int: - """检查关键字参数名 kw_arg 是否匹配参数名 param_name(跳过 % 前缀)(委托到 gen._kwarg_name_matches)""" - import lib.core.Gen.Generator as Generator - g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr)) - if g is not None: - return g._kwarg_name_matches(kw_arg, param_name) - return 0 - -# ============================================================ -# _translate_struct_ctor_kw — 结构体构造函数(关键字参数) -# -# 支持两种语法: -# Point(x=10, y=20) — 全关键字 -# Point(10, y=20) — 混合(位置 + 关键字) -# -# 位置参数按字段索引赋值,关键字参数按字段名查找赋值 -# ============================================================ -def _translate_struct_ctor_kw(pool: memhub.MemBuddy | t.CPtr, - builder: llvmlite.IRBuilder | t.CPtr, - mod: llvmlite.LLVMModule | t.CPtr, - struct_ty: llvmlite.LLVMType | t.CPtr, - class_name: str, - cargs: list[ast.AST | t.CPtr] | t.CPtr, - can: t.CSizeT, - keywords: list[ast.AST | t.CPtr] | t.CPtr, - kw_count: t.CSizeT, - trans: HT.Translator | t.CPtr) -> llvmlite.Value | t.CPtr: - """结构体构造函数(关键字参数版本)(委托到 gen._translate_struct_ctor_kw)""" - import lib.core.Gen.Generator as Generator - g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr)) - if g is not None: - return g._translate_struct_ctor_kw(pool, builder, mod, struct_ty, class_name, - cargs, can, keywords, kw_count, trans) - return None - -# ============================================================ -# _translate_call_with_kwargs — 带关键字参数的函数调用 -# -# 支持两种语法: -# add(b=4, a=3) — 全关键字乱序 -# greet("Hello", name="World") — 位置 + 关键字混合 -# -# 策略: 遍历 found_func.Params 链表,对每个参数: -# 1. 若位置参数仍有剩余(param_idx < can),取位置参数 -# 2. 否则按参数名匹配关键字参数 -# 3. 按参数顺序构建调用参数链表 -# ============================================================ -def _translate_call_with_kwargs(pool: memhub.MemBuddy | t.CPtr, - builder: llvmlite.IRBuilder | t.CPtr, - mod: llvmlite.LLVMModule | t.CPtr, - func_name: str, - found_func: llvmlite.Function | t.CPtr, - cargs: list[ast.AST | t.CPtr] | t.CPtr, - can: t.CSizeT, - keywords: list[ast.AST | t.CPtr] | t.CPtr, - kw_count: t.CSizeT, - trans: HT.Translator | t.CPtr) -> llvmlite.Value | t.CPtr: - """带关键字参数的函数调用,按参数顺序构建调用链表(委托到 gen._translate_call_with_kwargs)""" - import lib.core.Gen.Generator as Generator - g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr)) - if g is not None: - return g._translate_call_with_kwargs(pool, builder, mod, func_name, found_func, - cargs, can, keywords, kw_count, trans) - return None - -# ============================================================ -# _translate_t_type_cast - 翻译 t.XXX(value) 类型转换 -# -# 当 func 是 t.XXX 形式且 XXX 是已知类型名(map_t_type 能映射)时, -# 将 value 转换为目标类型: -# - 指针 → 整数: ptrtoint (如 t.CUInt64T(ptr) → i64) -# - 整数 → 指针: inttoptr (如 t.CPtr(int_val) → i8*) -# - 整数 → 整数: trunc/zext (如 t.CInt8T(i32_val) → i8) -# - 指针 → 指针: bitcast (如 t.CPtr(ptr_val) → i8*) -# - 整数 → 浮点: sitofp (如 t.CDouble(i32_val) → double) -# - 浮点 → 整数: fptosi (如 t.CInt(double_val) → i32) -# - 浮点 → 浮点: fpext/fptrunc (如 t.CFloat(double_val) → float) -# ============================================================ -def _translate_t_type_cast(pool: memhub.MemBuddy | t.CPtr, - builder: llvmlite.IRBuilder | t.CPtr, - val: llvmlite.Value | t.CPtr, - target_ty: llvmlite.LLVMType | t.CPtr, - target_name: str = None, - src_node: ast.AST | t.CPtr = None, - trans: HT.Translator | t.CPtr = None) -> llvmlite.Value | t.CPtr: - """类型转换:根据参数类型和目标类型选择转换方式(委托到 gen._translate_t_type_cast)""" - import lib.core.Gen.Generator as Generator - g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr)) - if g is not None: - return g._translate_t_type_cast(pool, builder, val, target_ty, - target_name, src_node, trans) - return None - -# ============================================================ -# 泛型实例化辅助:从 Subscript slice 提取类型实参名 -# ============================================================ -# _get_type_name_from_annotation 已移至 HandlesType.py(支持 BinOp/Attribute) -# HandlesExprCall 通过 HandlesType._get_type_name_from_annotation 调用 - -def _extract_type_args_from_slice(pool: memhub.MemBuddy | t.CPtr, - slice_node: ast.AST | t.CPtr) -> list[str] | t.CPtr: - """从 Subscript.slice 提取类型实参名列表(委托到 gen._extract_type_args_from_slice)""" - import lib.core.Gen.Generator as Generator - g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr)) - if g is not None: - return g._extract_type_args_from_slice(pool, slice_node) - return None - -# ============================================================ -# 泛型类构造调用辅助: list[str](pool, 8) → __new__ + __before_init__ + __init__ -# -# 复用 translate_list_literal 的构造逻辑: -# 1. alloca tmp(特化类临时空间,作为 __new__ 的 self) -# 2. 翻译 cl.args 为参数指针数组 -# 3. call __new__(tmp, *args) → storage_ptr -# 4. call __before_init__(storage_ptr) -# 5. call __init__(storage_ptr, *args) -# 6. return storage_ptr -# -# 必须独立于 translate_call 的普通函数路径:spec_name 是类名不是函数名, -# 走裸名路径会被 _lookup_mod_sha1 的 star import 回退误导,用错误的 SHA1 -# 且缺少 __new__ 方法名后缀,导致链接报 undefined reference。 -# ============================================================ -def _infer_generic_ctor_type_arg(pool: memhub.MemBuddy | t.CPtr, - arg_node: ast.AST | t.CPtr, - class_name: str) -> str: - """从构造实参 AST 推断泛型类型实参名;无法推断时默认 "int"(与 TPC 一致)(委托到 gen._infer_generic_ctor_type_arg)""" - import lib.core.Gen.Generator as Generator - g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr)) - if g is not None: - return g._infer_generic_ctor_type_arg(pool, arg_node, class_name) - return "int" - - -def _translate_generic_ctor_call(pool: memhub.MemBuddy | t.CPtr, - builder: llvmlite.IRBuilder | t.CPtr, - mod: llvmlite.LLVMModule | t.CPtr, - spec_name: str, - cl: ast.Call | t.CPtr, - trans: HT.Translator | t.CPtr) -> llvmlite.Value | t.CPtr: - """泛型类构造调用: list[str](pool, 8) → __new__ + __before_init__ + __init__(委托到 gen._translate_generic_ctor_call)""" - import lib.core.Gen.Generator as Generator - g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr)) - if g is not None: - return g._translate_generic_ctor_call(pool, builder, mod, spec_name, cl, trans) - return None - - -# ============================================================ -# 翻译函数调用 Call(func, args) — 模块级版本 -# ============================================================ -def translate_call(pool: memhub.MemBuddy | t.CPtr, - builder: llvmlite.IRBuilder | t.CPtr, - mod: llvmlite.LLVMModule | t.CPtr, - node: ast.AST | t.CPtr, - funcs_ptr: t.CPtr, - func_count: int, - trans: HT.Translator | t.CPtr = None) -> llvmlite.Value | t.CPtr: - """翻译函数调用,返回 call 结果 Value(委托到 gen.translate_call)""" - import lib.core.Gen.Generator as Generator - g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr)) - if g is not None: - return g.translate_call(pool, builder, mod, node, funcs_ptr, func_count, trans) - return None - -# ============================================================ -# 翻译闭包调用 — 通过闭包指针间接调用 -# -# 闭包结构: {i8* fn_ptr, i8* env_ptr} (16 字节) -# 调用过程: -# 1. load closure_ptr 从变量 alloca -# 2. load fn_ptr 从 offset 0 -# 3. load env_ptr 从 offset 8 -# 4. bitcast fn_ptr to i32 (i8*)* -# 5. call i32 %fn_typed(i8* %env_ptr) -# ============================================================ -def translate_closure_call(pool: memhub.MemBuddy | t.CPtr, - builder: llvmlite.IRBuilder | t.CPtr, - mod: llvmlite.LLVMModule | t.CPtr, - closure_alloca: llvmlite.Value | t.CPtr, - cargs: list[ast.AST | t.CPtr] | t.CPtr, - can: t.CSizeT, - trans: HT.Translator | t.CPtr = None) -> llvmlite.Value | t.CPtr: - """通过闭包指针间接调用(委托到 gen.translate_closure_call)""" - import lib.core.Gen.Generator as Generator - g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr)) - if g is not None: - return g.translate_closure_call(pool, builder, mod, closure_alloca, cargs, can, trans) - return None - -# ============================================================ -# _is_func_ptr_alloca - 判断变量 alloca 是否为函数指针变量 -# -# 函数指针变量(t.Callable 注解 → i8*)的 alloca 类型是 Ptr(Ptr(i8)) = i8**; -# 闭包变量 alloca 是 i8*(Ptr(i8))。通过类型层级区分。 -# ============================================================ -def _is_func_ptr_alloca(alloca: llvmlite.Value | t.CPtr) -> int: - """判断 alloca 是否为函数指针变量(类型 Ptr(Ptr(i8))),1=是 / 0=否(委托到 gen._is_func_ptr_alloca)""" - import lib.core.Gen.Generator as Generator - g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr)) - if g is not None: - return g._is_func_ptr_alloca(alloca) - return 0 - - -# ============================================================ -# 闭包变量名集合(stdlib 分配,懒初始化) -# -# 背景: 嵌套函数提升后闭包变量 alloca 类型是 i8**(alloca i8*), -# 与函数指针变量(t.Callable → i8** alloca)类型完全相同,_is_func_ptr_alloca -# 无法区分,导致 inner() 被误判为函数指针调用(直接 bitcast 闭包对象到函数指针、 -# 无 env 参数调用 → 运行时崩溃)。translate_nested_function_def 创建闭包时 -# 注册嵌套函数名,调用时优先按闭包调用处理。 -# ============================================================ -MAX_CLOSURE_NAMES: t.CDefine = 128 - - -def _ensure_closure_names() -> int: - """确保闭包名表已分配,0 失败(委托到 gen._ensure_closure_names)""" - import lib.core.Gen.Generator as Generator - g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr)) - if g is not None: - return g._ensure_closure_names() - return 0 - - -def register_closure_name(name: str) -> int: - """注册嵌套函数(闭包变量)名,0 成功(委托到 gen.register_closure_name)""" - import lib.core.Gen.Generator as Generator - g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr)) - if g is not None: - return g.register_closure_name(name) - return 0 - - -def is_closure_name(name: str) -> int: - """检查 name 是否已注册为闭包变量名,1=是 / 0=否(委托到 gen.is_closure_name)""" - import lib.core.Gen.Generator as Generator - g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr)) - if g is not None: - return g.is_closure_name(name) - return 0 - -# ============================================================ -# 函数指针变量签名表(变量名 → 返回类型) -# -# AnnAssign 处理 t.Callable 注解时注册,函数指针间接调用时 -# 按注册的返回类型构造签名(而非默认 i32)。 -# ============================================================ -MAX_FUNC_PTR_SIGS: t.CDefine = 64 - - -def _ensure_funcptr_sigs() -> int: - """确保函数指针签名表已分配(stdlib.malloc,懒初始化)(委托到 gen._ensure_funcptr_sigs)""" - import lib.core.Gen.Generator as Generator - g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr)) - if g is not None: - return g._ensure_funcptr_sigs() - return 0 - - -def register_func_ptr_sig(name: str, - ret_ty: llvmlite.LLVMType | t.CPtr) -> int: - """注册函数指针变量的返回类型签名,0 成功(委托到 gen.register_func_ptr_sig)""" - import lib.core.Gen.Generator as Generator - g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr)) - if g is not None: - return g.register_func_ptr_sig(name, ret_ty) - return 0 - - -def lookup_func_ptr_ret(name: str) -> llvmlite.LLVMType | t.CPtr: - """查函数指针变量的返回类型,None=未注册(调用时默认 i32)(委托到 gen.lookup_func_ptr_ret)""" - import lib.core.Gen.Generator as Generator - g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr)) - if g is not None: - return g.lookup_func_ptr_ret(name) - return None - - -# ============================================================ -# _translate_func_ptr_call - 函数指针变量间接调用 -# -# func_p: t.Callable[[A, B], Ret] 后调用 func_p(a, b): -# 1. load 函数地址 (i8*) -# 2. 翻译实参并链接为 Value 链表 -# 3. 按实参类型 + 注册的返回类型构造签名(未注册时默认 i32) -# 4. bitcast i8* → 函数指针类型,间接调用 -# ============================================================ -def _translate_func_ptr_call(pool: memhub.MemBuddy | t.CPtr, - builder: llvmlite.IRBuilder | t.CPtr, - mod: llvmlite.LLVMModule | t.CPtr, - fp_alloca: llvmlite.Value | t.CPtr, - func_name: str, - cargs: list[ast.AST | t.CPtr] | t.CPtr, - can: t.CSizeT, - trans: HT.Translator | t.CPtr) -> llvmlite.Value | t.CPtr: - """函数指针变量间接调用,返回结果 Value(委托到 gen._translate_func_ptr_call)""" - import lib.core.Gen.Generator as Generator - g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr)) - if g is not None: - return g._translate_func_ptr_call(pool, builder, mod, fp_alloca, func_name, cargs, can, trans) - return None - -# ============================================================ -# 翻译 printf 调用 — 模块级版本 -# ============================================================ -def translate_printf_call(pool: memhub.MemBuddy | t.CPtr, - builder: llvmlite.IRBuilder | t.CPtr, - mod: llvmlite.LLVMModule | t.CPtr, - cl: ast.Call | t.CPtr, - trans: HT.Translator | t.CPtr = None): - """翻译 printf 调用(特殊处理格式字符串)(委托到 gen.translate_printf_call)""" - import lib.core.Gen.Generator as Generator - g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr)) - if g is not None: - g.translate_printf_call(pool, builder, mod, cl, trans) - - -# ============================================================ -# 翻译 print 调用 — 类型感知格式化 + 默认换行 -# -# 与 printf 不同,print 不需要用户提供格式串:每个参数按 LLVM -# 类型自动选择格式(%s/%d/%f/0x%llx),结尾追加 "\n"(对齐 Python -# print 默认 end="\n",以及 TPC HandlesExprBuiltin._HandlePrintLlvm)。 -# -# 类型分派规则: -# i8*(str/bytes) → %s -# 其他指针(struct*/int*) → 0x%llx(ptrtoint 到 i64) -# i1(bool) → %d(zext 到 i32) -# i8/i16/i32 → %d(sext 到 i32,C ABI 整数提升) -# i64 → %lld -# float/double → %f(float fpext 到 double,C ABI 提升) -# 无法识别的类型 → "(unknown)"(不传参) -# ============================================================ -def translate_print_call(pool: memhub.MemBuddy | t.CPtr, - builder: llvmlite.IRBuilder | t.CPtr, - mod: llvmlite.LLVMModule | t.CPtr, - cl: ast.Call | t.CPtr, - trans: HT.Translator | t.CPtr = None): - """翻译 print 调用(类型感知格式化 + 默认换行)(委托到 gen.translate_print_call)""" - import lib.core.Gen.Generator as Generator - g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr)) - if g is not None: - g.translate_print_call(pool, builder, mod, cl, trans) - - -# ============================================================ -# stdarg 糖函数实现: va_arg / arg / va_start / va_end -# -# 这些函数对应 stdarg.vp 中的 pass 体声明,由编译器在翻译期 -# 转换为 LLVM 指令或 intrinsic 调用,不生成函数 call。 -# -# va_list 在 TPV 中表示为 i8*(与 stdarg.vp 中 va_list = t.CUnsignedChar | t.CPtr 一致)。 -# va_list 对象存储在 alloca 中(i8**),va_arg/va_start/va_end 需要传入 alloca 指针。 -# ============================================================ - -def _va_arg_get_alloca_ptr(pool: memhub.MemBuddy | t.CPtr, - builder: llvmlite.IRBuilder | t.CPtr, - mod: llvmlite.LLVMModule | t.CPtr, - arg_node: ast.AST | t.CPtr, - funcs_ptr: t.CPtr, - func_count: int, - trans: HT.Translator | t.CPtr) -> llvmlite.Value | t.CPtr: - """获取 va_list 变量的 alloca 指针(不 load)(委托到 gen._va_arg_get_alloca_ptr)""" - import lib.core.Gen.Generator as Generator - g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr)) - if g is not None: - return g._va_arg_get_alloca_ptr(pool, builder, mod, arg_node, funcs_ptr, func_count, trans) - return None - - -def _resolve_va_arg_type(pool: memhub.MemBuddy | t.CPtr, - type_node: ast.AST | t.CPtr, - trans: HT.Translator | t.CPtr) -> llvmlite.LLVMType | t.CPtr: - """解析 va_arg/arg 的类型参数为 LLVMType(委托到 gen._resolve_va_arg_type)""" - import lib.core.Gen.Generator as Generator - g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr)) - if g is not None: - return g._resolve_va_arg_type(pool, type_node, trans) - return None - - -def _translate_va_arg_sugar(pool: memhub.MemBuddy | t.CPtr, - builder: llvmlite.IRBuilder | t.CPtr, - mod: llvmlite.LLVMModule | t.CPtr, - cl: ast.Call | t.CPtr, - cargs: list[ast.AST | t.CPtr] | t.CPtr, - can: t.CSizeT, - funcs_ptr: t.CPtr, - func_count: int, - trans: HT.Translator | t.CPtr) -> llvmlite.Value | t.CPtr: - """va_arg(ap, type) / va_arg(ap) → %N = va_arg , (委托到 gen._translate_va_arg_sugar)""" - import lib.core.Gen.Generator as Generator - g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr)) - if g is not None: - return g._translate_va_arg_sugar(pool, builder, mod, cl, cargs, can, funcs_ptr, func_count, trans) - return None - - -def _translate_arg_sugar(pool: memhub.MemBuddy | t.CPtr, - builder: llvmlite.IRBuilder | t.CPtr, - mod: llvmlite.LLVMModule | t.CPtr, - cl: ast.Call | t.CPtr, - cargs: list[ast.AST | t.CPtr] | t.CPtr, - can: t.CSizeT, - funcs_ptr: t.CPtr, - func_count: int, - trans: HT.Translator | t.CPtr) -> llvmlite.Value | t.CPtr: - """arg(type) → %N = va_arg , (委托到 gen._translate_arg_sugar)""" - import lib.core.Gen.Generator as Generator - g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr)) - if g is not None: - return g._translate_arg_sugar(pool, builder, mod, cl, cargs, can, funcs_ptr, func_count, trans) - return None - - -def _translate_va_start_sugar(pool: memhub.MemBuddy | t.CPtr, - builder: llvmlite.IRBuilder | t.CPtr, - mod: llvmlite.LLVMModule | t.CPtr, - cargs: list[ast.AST | t.CPtr] | t.CPtr, - can: t.CSizeT, - funcs_ptr: t.CPtr, - func_count: int, - trans: HT.Translator | t.CPtr) -> llvmlite.Value | t.CPtr: - """va_start(ap, last_arg) → call void @llvm.va_start(i8* %ap)(委托到 gen._translate_va_start_sugar)""" - import lib.core.Gen.Generator as Generator - g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr)) - if g is not None: - return g._translate_va_start_sugar(pool, builder, mod, cargs, can, funcs_ptr, func_count, trans) - return None - - -def _translate_va_end_sugar(pool: memhub.MemBuddy | t.CPtr, - builder: llvmlite.IRBuilder | t.CPtr, - mod: llvmlite.LLVMModule | t.CPtr, - cargs: list[ast.AST | t.CPtr] | t.CPtr, - can: t.CSizeT, - funcs_ptr: t.CPtr, - func_count: int, - trans: HT.Translator | t.CPtr) -> llvmlite.Value | t.CPtr: - """va_end(ap) → call void @llvm.va_end(i8* %ap)(委托到 gen._translate_va_end_sugar)""" - import lib.core.Gen.Generator as Generator - g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr)) - if g is not None: - return g._translate_va_end_sugar(pool, builder, mod, cargs, can, funcs_ptr, func_count, trans) - return None - - -# ============================================================ -# 变长函数调用支持: 检查 IsVarArg + C ABI 参数提升 -# -# C ABI 要求变长参数(...部分)进行默认提升: -# 整数提升: i8/i16 → i32 (sext/zext) -# 浮点提升: float → double (fpext) -# 固定参数不需要提升(有明确类型签名)。 -# ============================================================ - -def _get_func_fixed_param_count(func: llvmlite.Function | t.CPtr) -> int: - """获取函数的固定参数数量(遍历 Params 链表)(委托到 gen._get_func_fixed_param_count)""" - import lib.core.Gen.Generator as Generator - g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr)) - if g is not None: - return g._get_func_fixed_param_count(func) - return 0 - - -def _check_and_promote_variadic_call(pool: memhub.MemBuddy | t.CPtr, - builder: llvmlite.IRBuilder | t.CPtr, - mod: llvmlite.LLVMModule | t.CPtr, - call_name: str, - head: llvmlite.Value | t.CPtr, - can: t.CSizeT, - arg_nodes: list[ast.AST | t.CPtr] | t.CPtr = None, - self_offset: int = 0, - trans: HT.Translator | t.CPtr = None) -> int: - """检查被调用函数是否为变长函数,若是则对变长参数进行 C ABI 提升(委托到 gen._check_and_promote_variadic_call)""" - import lib.core.Gen.Generator as Generator - g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr)) - if g is not None: - return g._check_and_promote_variadic_call(pool, builder, mod, call_name, head, can, - arg_nodes, self_offset, trans) - return 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + # ============================================================ @@ -1516,129 +167,18 @@ class FuncEntry: # vtable 生成 find_func_global 读类型改用此文本,避免悬空。 TypeStr: str -# ============================================================ -# 初始化函数表 -# ============================================================ -def init_func_table(pool: memhub.MemBuddy | t.CPtr, - max_count: int) -> FuncEntry | t.CPtr: - """分配并清零函数表数组(委托到 gen.init_func_table)""" - import lib.core.Gen.Generator as Generator - g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr)) - if g is not None: - return g.init_func_table(pool, max_count) - return None - -# ============================================================ -# 查找函数 -# ============================================================ -def find_func_in_table(funcs: FuncEntry | t.CPtr, - func_count: int, - name: str) -> llvmlite.Function | t.CPtr: - """在函数表中按名称查找,返回 Function 指针或 None(委托到 gen.find_func_in_table)""" - import lib.core.Gen.Generator as Generator - g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr)) - if g is not None: - return g.find_func_in_table(funcs, func_count, name) - return None - -# ============================================================ -# 添加函数到函数表 -# ============================================================ -def add_func_to_table(funcs: FuncEntry | t.CPtr, - func_count: int, - name: str, - func: llvmlite.Function | t.CPtr, - max_count: int, - defaults: t.CVoid | t.CPtr = None, - default_count: int = 0, - param_count: int = 0, - pool: memhub.MemBuddy | t.CPtr = None) -> int: - """添加函数到函数表,返回 0 成功(委托到 gen.add_func_to_table)""" - import lib.core.Gen.Generator as Generator - g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr)) - if g is not None: - return g.add_func_to_table(funcs, func_count, name, func, max_count, - defaults, default_count, param_count, pool) - return 0 - -# ============================================================ -# 全局函数注册表(跨模块函数查找) -# -# 所有模块翻译的函数都会注册到此表(通过 add_func_to_table 自动注册)。 -# 主要用途: vtable 初始化时查找跨模块继承方法的 Function 对象, -# 以获取函数类型信息构造 bitcast 字符串。 -# ============================================================ -GLOBAL_FUNC_MAX: t.CDefine = 8192 - -def _init_global_func_table() -> int: - """初始化全局函数表(用 stdlib.malloc 分配,生命周期=整个程序)(委托到 gen._init_global_func_table)""" - import lib.core.Gen.Generator as Generator - g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr)) - if g is not None: - return g._init_global_func_table() - return 0 -# _build_func_type_str — 从 Function 对象生成函数类型文本(stdlib 存储) -# -# 格式: ret_ty (param1_ty, param2_ty, ...),与 vtable bitcast 需要一致。 -# 用 stdlib.malloc 分配返回,跨文件永久存活(1b reset 不回收)。 -# 返回 None 表示失败。 -def _build_func_type_str(pool: memhub.MemBuddy | t.CPtr, - func: llvmlite.Function | t.CPtr) -> str: - """生成函数类型文本(stdlib 分配)(委托到 gen._build_func_type_str)""" - import lib.core.Gen.Generator as Generator - g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr)) - if g is not None: - return g._build_func_type_str(pool, func) - return None -def _register_global_func(name: str, func: llvmlite.Function | t.CPtr, - pool: memhub.MemBuddy | t.CPtr = None) -> int: - """注册函数到全局表(已存在则跳过),返回 0 成功(委托到 gen._register_global_func)""" - import lib.core.Gen.Generator as Generator - g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr)) - if g is not None: - return g._register_global_func(name, func, pool) - return 0 -def update_global_func_typestr(pool: memhub.MemBuddy | t.CPtr, - name: str, - func: llvmlite.Function | t.CPtr) -> int: - """更新全局函数表的 TypeStr(在函数参数全部添加完成后调用)(委托到 gen.update_global_func_typestr)""" - import lib.core.Gen.Generator as Generator - g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr)) - if g is not None: - return g.update_global_func_typestr(pool, name, func) - return 0 - -def find_func_global(name: str) -> llvmlite.Function | t.CPtr: - """在全局函数表中按名称查找,返回 Function 指针或 None(委托到 gen.find_func_global)""" - import lib.core.Gen.Generator as Generator - g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr)) - if g is not None: - return g.find_func_global(name) - return None -def find_func_entry_global(name: str) -> FuncEntry | t.CPtr: - """在全局函数表中按名称查找,返回完整 FuncEntry(含 TypeStr)或 None(委托到 gen.find_func_entry_global)""" - import lib.core.Gen.Generator as Generator - g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr)) - if g is not None: - return g.find_func_entry_global(name) - return None -# ============================================================ -# 全局默认参数注册表(跨模块默认参数填充) -# -# 独立于 _global_funcs,因为 _register_global_func 可能在 -# add_func_to_table 之前被调用(如 stub 注入),此时 defaults 还不可用。 -# ============================================================ -GLOBAL_DEFAULTS_MAX: t.CDefine = 4096 + + @t.NoVTable class FuncDefaultsEntry: @@ -1654,68 +194,11 @@ class FuncDefaultsEntry: ConstInts: t.CInt64T | t.CPtr # int_val 数组(DefaultCount 个 i64) ConstStrs: t.CSizeT | t.CPtr # str_val 指针数组(DefaultCount 个 i8*) -def _init_global_defaults_table() -> int: - """初始化全局默认参数表(委托到 gen._init_global_defaults_table)""" - import lib.core.Gen.Generator as Generator - g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr)) - if g is not None: - return g._init_global_defaults_table() - return 0 - -def _register_global_defaults(name: str, - defaults: t.CVoid | t.CPtr, - default_count: int, - param_count: int) -> int: - """注册函数默认参数到全局表,返回 0 成功(委托到 gen._register_global_defaults)""" - import lib.core.Gen.Generator as Generator - g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr)) - if g is not None: - return g._register_global_defaults(name, defaults, default_count, param_count) - return 0 - -def find_func_defaults(name: str) -> FuncDefaultsEntry | t.CPtr: - """按函数名查找默认参数信息,返回 FuncDefaultsEntry 或 None(委托到 gen.find_func_defaults)""" - import lib.core.Gen.Generator as Generator - g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr)) - if g is not None: - return g.find_func_defaults(name) - return None -# _build_const_from_snapshot — 从常量快照重建常量 IR 值 -# -# 用于跨模块默认参数填充:gd_entry.Defaults(pool 内 AST)可能已被 reset 回收, -# 改用注册时提取的 stdlib 常量快照(ConstKinds/ConstInts/ConstStrs)重建常量 IR。 -# 返回 llvmlite.Value*,失败返回 None。 -def _build_const_from_snapshot(pool: memhub.MemBuddy | t.CPtr, - mod: llvmlite.LLVMModule | t.CPtr, - gd_entry: FuncDefaultsEntry | t.CPtr, - di: int, - trans: HT.Translator | t.CPtr, - builder: llvmlite.IRBuilder | t.CPtr) -> llvmlite.Value | t.CPtr: - """从快照重建第 di 个默认值常量 IR(委托到 gen._build_const_from_snapshot)""" - import lib.core.Gen.Generator as Generator - g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr)) - if g is not None: - return g._build_const_from_snapshot(pool, mod, gd_entry, di, trans, builder) - return None -def find_func_entry_in_table(funcs: FuncEntry | t.CPtr, - func_count: int, - name: str) -> FuncEntry | t.CPtr: - """在函数表中按名称查找,返回完整 FuncEntry 或 None""" - if name is None or funcs is None: - return None - entry_size: t.CSizeT = FuncEntry.__sizeof__() - i: int = 0 - while i < func_count: - entry_addr: t.CUInt64T = t.CUInt64T(funcs) + i * entry_size - entry: FuncEntry | t.CPtr = (FuncEntry | t.CPtr)(t.CVoid(entry_addr, t.CPtr)) - if entry.Name is not None: - if string.strcmp(entry.Name, name) == 0: - return entry - i += 1 - return None + + # ============================================================ # ExprCallHandle - 函数调用处理器(Mixin 继承模式) @@ -1756,286 +239,3 @@ class ExprCallHandle(HandlesBase.Mixin): translate_print_call( self.Trans.Pool, self.Trans._cur_builder, self.Trans.Module, cl, self.Trans) - -# ============================================================ -# NewExprCallHandle - 工厂函数 -# ============================================================ -def NewExprCallHandle(pool: memhub.MemBuddy | t.CPtr, - trans: HT.Translator | t.CPtr) -> ExprCallHandle | t.CPtr: - """新建 ExprCallHandle 工厂(委托到 gen.NewExprCallHandle)""" - import lib.core.Gen.Generator as Generator - g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr)) - if g is not None: - return g.NewExprCallHandle(pool, trans) - return None - - -# ============================================================ -# _make_vtable_ref_i8 / _emit_eh_guarded_call / _translate_isinstance -# (追加91:CallGenMixin 拆分后顶层经委托调用 CallGenLeafKit 方法—— -# TPV self 调用仅支持 1 级父类,跨 Mixin 统一走 _g_gen 委托) -# ============================================================ -def _make_vtable_ref_i8(pool: memhub.MemBuddy | t.CPtr, - builder: llvmlite.IRBuilder | t.CPtr, - mod: llvmlite.LLVMModule | t.CPtr, - class_name: str, - trans: HT.Translator | t.CPtr = None) -> llvmlite.Value | t.CPtr: - """构造类 vtable 地址引用(i8*)(委托到 gen._make_vtable_ref_i8)""" - import lib.core.Gen.Generator as Generator - g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr)) - if g is not None: - return g._make_vtable_ref_i8(pool, builder, mod, class_name, trans) - return None - - -def _emit_eh_guarded_call(builder: llvmlite.IRBuilder | t.CPtr, - pool: memhub.MemBuddy | t.CPtr, - mod: llvmlite.LLVMModule | t.CPtr, - trans: HT.Translator | t.CPtr, - func: llvmlite.Function | t.CPtr, - call_name: str, - head: llvmlite.Value | t.CPtr, - count: int, - ret_ty: llvmlite.LLVMType | t.CPtr, - is_variadic: int) -> llvmlite.Value | t.CPtr: - """带 try-except EH 检测的函数调用(委托到 gen._emit_eh_guarded_call)""" - import lib.core.Gen.Generator as Generator - g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr)) - if g is not None: - return g._emit_eh_guarded_call(builder, pool, mod, trans, func, call_name, head, count, ret_ty, is_variadic) - return None - - -def _translate_isinstance(pool: memhub.MemBuddy | t.CPtr, - builder: llvmlite.IRBuilder | t.CPtr, - mod: llvmlite.LLVMModule | t.CPtr, - obj_node: ast.AST | t.CPtr, - cls_node: ast.AST | t.CPtr, - trans: HT.Translator | t.CPtr = None) -> llvmlite.Value | t.CPtr: - """翻译 isinstance()(委托到 gen._translate_isinstance)""" - import lib.core.Gen.Generator as Generator - g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr)) - if g is not None: - return g._translate_isinstance(pool, builder, mod, obj_node, cls_node, trans) - return None - - -# ============================================================ -# _is_sha1_mangled_call / _is_list_builtin_method / _translate_fakeduck_call / -# _translate_super_call(阶段 B:CallGenMixin 拆分后顶层经委托调用这些方法) -# ============================================================ -def _is_sha1_mangled_call(call_name: str) -> int: - """判断 call_name 是否为跨模块 Viper 函数(委托到 gen._is_sha1_mangled_call)""" - import lib.core.Gen.Generator as Generator - g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr)) - if g is not None: - return g._is_sha1_mangled_call(call_name) - return 0 - - -def _is_list_builtin_method(class_name: str, method_name: str) -> int: - """判断 (class_name, method_name) 是否是 list 泛型内置方法(委托到 gen._is_list_builtin_method)""" - import lib.core.Gen.Generator as Generator - g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr)) - if g is not None: - return g._is_list_builtin_method(class_name, method_name) - return 0 - - -def _translate_fakeduck_call(pool: memhub.MemBuddy | t.CPtr, - builder: llvmlite.IRBuilder | t.CPtr, - mod: llvmlite.LLVMModule | t.CPtr, - cls_name: str, - method_name: str, - cl: ast.Call | t.CPtr, - trans: HT.Translator | t.CPtr) -> llvmlite.Value | t.CPtr: - """FakeDuck: str 变量方法调用(委托到 gen._translate_fakeduck_call)""" - import lib.core.Gen.Generator as Generator - g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr)) - if g is not None: - return g._translate_fakeduck_call(pool, builder, mod, cls_name, method_name, cl, trans) - return None - - -def _translate_super_call(pool: memhub.MemBuddy | t.CPtr, - builder: llvmlite.IRBuilder | t.CPtr, - mod: llvmlite.LLVMModule | t.CPtr, - cl: ast.Call | t.CPtr, - method_name: str, - trans: HT.Translator | t.CPtr) -> llvmlite.Value | t.CPtr: - """super().method(args) → 父类方法静态调用(委托到 gen._translate_super_call)""" - import lib.core.Gen.Generator as Generator - g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr)) - if g is not None: - return g._translate_super_call(pool, builder, mod, cl, method_name, trans) - return None - - -# ============================================================ -# translate_call 前置检测 helper(阶段 C:CallGenMixin 拆分后顶层经委托 -# 调用 CallGenDispatch 方法。每个返回 Value|CPtr,None = 未命中继续主路径) -# ============================================================ -def _tc_h1_super_ctraits(pool: memhub.MemBuddy | t.CPtr, - builder: llvmlite.IRBuilder | t.CPtr, - mod: llvmlite.LLVMModule | t.CPtr, - cl: ast.Call | t.CPtr, - funcs_ptr: t.CPtr, - func_count: int, - trans: HT.Translator | t.CPtr, - func_name: str, - cargs: list[ast.AST | t.CPtr] | t.CPtr, - can: t.CSizeT) -> llvmlite.Value | t.CPtr: - """super()/ctraits 编译期检测(委托到 gen._tc_h1_super_ctraits)""" - import lib.core.Gen.Generator as Generator - g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr)) - if g is not None: - return g._tc_h1_super_ctraits(pool, builder, mod, cl, funcs_ptr, func_count, trans, func_name, cargs, can) - return None - - -def _tc_h2_c_special(pool: memhub.MemBuddy | t.CPtr, - builder: llvmlite.IRBuilder | t.CPtr, - mod: llvmlite.LLVMModule | t.CPtr, - cl: ast.Call | t.CPtr, - funcs_ptr: t.CPtr, - func_count: int, - trans: HT.Translator | t.CPtr, - func_name: str, - cargs: list[ast.AST | t.CPtr] | t.CPtr, - can: t.CSizeT) -> llvmlite.Value | t.CPtr: - """c.Deref/Asm/LLVMIR 等特殊调用(委托到 gen._tc_h2_c_special)""" - import lib.core.Gen.Generator as Generator - g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr)) - if g is not None: - return g._tc_h2_c_special(pool, builder, mod, cl, funcs_ptr, func_count, trans, func_name, cargs, can) - return None - - -def _tc_h3_stdarg_cast(pool: memhub.MemBuddy | t.CPtr, - builder: llvmlite.IRBuilder | t.CPtr, - mod: llvmlite.LLVMModule | t.CPtr, - cl: ast.Call | t.CPtr, - funcs_ptr: t.CPtr, - func_count: int, - trans: HT.Translator | t.CPtr, - func_name: str, - cargs: list[ast.AST | t.CPtr] | t.CPtr, - can: t.CSizeT) -> llvmlite.Value | t.CPtr: - """stdarg 糖 + str/int/bool 内置强转(委托到 gen._tc_h3_stdarg_cast)""" - import lib.core.Gen.Generator as Generator - g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr)) - if g is not None: - return g._tc_h3_stdarg_cast(pool, builder, mod, cl, funcs_ptr, func_count, trans, func_name, cargs, can) - return None - - -def _tc_h4_type_casts(pool: memhub.MemBuddy | t.CPtr, - builder: llvmlite.IRBuilder | t.CPtr, - mod: llvmlite.LLVMModule | t.CPtr, - cl: ast.Call | t.CPtr, - funcs_ptr: t.CPtr, - func_count: int, - trans: HT.Translator | t.CPtr, - func_name: str, - cargs: list[ast.AST | t.CPtr] | t.CPtr, - can: t.CSizeT) -> llvmlite.Value | t.CPtr: - """t.XXX / typedef 类型转换(委托到 gen._tc_h4_type_casts)""" - import lib.core.Gen.Generator as Generator - g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr)) - if g is not None: - return g._tc_h4_type_casts(pool, builder, mod, cl, funcs_ptr, func_count, trans, func_name, cargs, can) - return None - - -def _tc_h5_sizeof_len_isinst(pool: memhub.MemBuddy | t.CPtr, - builder: llvmlite.IRBuilder | t.CPtr, - mod: llvmlite.LLVMModule | t.CPtr, - cl: ast.Call | t.CPtr, - funcs_ptr: t.CPtr, - func_count: int, - trans: HT.Translator | t.CPtr, - func_name: str, - cargs: list[ast.AST | t.CPtr] | t.CPtr, - can: t.CSizeT) -> llvmlite.Value | t.CPtr: - """__sizeof__/len/isinstance 内置(委托到 gen._tc_h5_sizeof_len_isinst)""" - import lib.core.Gen.Generator as Generator - g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr)) - if g is not None: - return g._tc_h5_sizeof_len_isinst(pool, builder, mod, cl, funcs_ptr, func_count, trans, func_name, cargs, can) - return None - - -def _tc_h6_method_dispatch(pool: memhub.MemBuddy | t.CPtr, - builder: llvmlite.IRBuilder | t.CPtr, - mod: llvmlite.LLVMModule | t.CPtr, - cl: ast.Call | t.CPtr, - funcs_ptr: t.CPtr, - func_count: int, - trans: HT.Translator | t.CPtr, - func_name: str, - cargs: list[ast.AST | t.CPtr] | t.CPtr, - can: t.CSizeT) -> llvmlite.Value | t.CPtr: - """静态类/方法调用/表达式接收者/self.field/list 内置(委托到 gen._tc_h6_method_dispatch)""" - import lib.core.Gen.Generator as Generator - g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr)) - if g is not None: - return g._tc_h6_method_dispatch(pool, builder, mod, cl, funcs_ptr, func_count, trans, func_name, cargs, can) - return None - - -# ============================================================ -# FuncGen 跨 Mixin 委托(阶段 D:FuncGenMixin 拆 Base/Def 后顶层经 -# 此调用这些方法。参数与目标方法一致,去 self) -# ============================================================ -def extract_func_attrs(pool: memhub.MemBuddy | t.CPtr, - decorator_list: list[ast.AST | t.CPtr] | t.CPtr, - imported_modules: str) -> str: - """从 decorator_list 提取 c.Attribute 属性(委托到 gen.extract_func_attrs)""" - import lib.core.Gen.Generator as Generator - g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr)) - if g is not None: - return g.extract_func_attrs(pool, decorator_list, imported_modules) - return None - - -def _mangle_name(trans: HT.Translator | t.CPtr, name: str) -> str: - """为任意名称添加 SHA1 前缀(委托到 gen._mangle_name)""" - import lib.core.Gen.Generator as Generator - g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr)) - if g is not None: - return g._mangle_name(trans, name) - return name - - -def _mangle_func_name(trans: HT.Translator | t.CPtr, name: str, - has_export: int) -> str: - """为函数名添加 SHA1 前缀(委托到 gen._mangle_func_name)""" - import lib.core.Gen.Generator as Generator - g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr)) - if g is not None: - return g._mangle_func_name(trans, name, has_export) - return name - - -def _body_has_raise(fd: ast.FunctionDef | t.CPtr) -> int: - """函数体顶层是否含 raise(委托到 gen._body_has_raise)""" - import lib.core.Gen.Generator as Generator - g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr)) - if g is not None: - return g._body_has_raise(fd) - return 0 - - -def _prepare_chain_nonlocals(trans: HT.Translator | t.CPtr, - node: ast.AST | t.CPtr, - pool: memhub.MemBuddy | t.CPtr, - builder: llvmlite.IRBuilder | t.CPtr, - mod: llvmlite.LLVMModule | t.CPtr, - i8_ty: llvmlite.LLVMType | t.CPtr, - i8_ptr_ty: llvmlite.LLVMType | t.CPtr) -> int: - """准备嵌套函数 nonlocals 链(委托到 gen._prepare_chain_nonlocals)""" - import lib.core.Gen.Generator as Generator - g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr)) - if g is not None: - return g._prepare_chain_nonlocals(trans, node, pool, builder, mod, i8_ty, i8_ptr_ty) - return 0 diff --git a/App/lib/core/Handles/HandlesFor.vp b/App/lib/core/Handles/HandlesFor.vp index 2ba73bc..83dd5d4 100644 --- a/App/lib/core/Handles/HandlesFor.vp +++ b/App/lib/core/Handles/HandlesFor.vp @@ -14,6 +14,7 @@ import lib.core.Handles.HandlesBody as HandlesBody import lib.core.Handles.HandlesType as HandlesType import lib.core.Handles.HandlesExprCall as HandlesExprCall import lib.core.Handles.HandlesStruct as HandlesStruct +import lib.core.Handles.ExprCallBase as ExprCallBase # ============================================================ @@ -204,13 +205,13 @@ class ForHandle(HandlesBase.Mixin): oi_lookup: str = pool.alloc(128) if oi_lookup is not None: viperlib.snprintf(oi_lookup, 128, "%s.__iter__", ov_cn) - oi_fn: llvmlite.Function | t.CPtr = HandlesExprCall.find_func_in_module( + oi_fn: llvmlite.Function | t.CPtr = ExprCallBase.find_func_in_module( trans.Module, oi_lookup) if oi_fn is not None: on_lookup: str = pool.alloc(128) if on_lookup is not None: viperlib.snprintf(on_lookup, 128, "%s.__next__", ov_cn) - on_fn: llvmlite.Function | t.CPtr = HandlesExprCall.find_func_in_module( + on_fn: llvmlite.Function | t.CPtr = ExprCallBase.find_func_in_module( trans.Module, on_lookup) if on_fn is not None: return self._handle_oop_iter( @@ -1061,7 +1062,7 @@ class ForHandle(HandlesBase.Mixin): if iter_lookup is None: return 0 viperlib.snprintf(iter_lookup, 128, "%s.__iter__", class_name) - iter_fn: llvmlite.Function | t.CPtr = HandlesExprCall.find_func_in_module( + iter_fn: llvmlite.Function | t.CPtr = ExprCallBase.find_func_in_module( mod, iter_lookup) if iter_fn is None: HandlesType.fatal_error( @@ -1090,7 +1091,7 @@ class ForHandle(HandlesBase.Mixin): if next_lookup is None: return 0 viperlib.snprintf(next_lookup, 128, "%s.__next__", class_name) - next_fn: llvmlite.Function | t.CPtr = HandlesExprCall.find_func_in_module( + next_fn: llvmlite.Function | t.CPtr = ExprCallBase.find_func_in_module( mod, next_lookup) if next_fn is None: HandlesType.fatal_error( diff --git a/App/lib/core/Handles/HandlesTranslator.vp b/App/lib/core/Handles/HandlesTranslator.vp index 8baed28..f6aee51 100644 --- a/App/lib/core/Handles/HandlesTranslator.vp +++ b/App/lib/core/Handles/HandlesTranslator.vp @@ -26,6 +26,8 @@ import lib.core.Handles.HandlesType as HandlesType import lib.core.Handles.HandlesStruct as HandlesStruct import lib.Projectrans.Config as Config import lib.core.StubMergerBuild as StubMergerBuild +import lib.core.Handles.ExprCallHandle as ExprCallHandle +import lib.core.Handles.ExprCallTable as ExprCallTable # ============================================================ # HandlesTranslator - 翻译器状态管理 + 主入口 @@ -265,7 +267,7 @@ class Translator: """初始化变量表、函数表和子 Handle""" self.Pool = pool if self._funcs is None: - self._funcs = HandlesExprCall.init_func_table(pool, MAX_FUNCS) + self._funcs = ExprCallTable.init_func_table(pool, MAX_FUNCS) # 嵌套作用域符号表(新版) if self.SymTab is None: self.SymTab = HandlesVar.init_symbol_table(pool) @@ -307,7 +309,7 @@ class Translator: if self.ExprH is None: self.ExprH = HandlesExpr.NewExprHandle(pool, self) if self.ExprCallH is None: - self.ExprCallH = HandlesExprCall.NewExprCallHandle(pool, self) + self.ExprCallH = ExprCallHandle.NewExprCallHandle(pool, self) # ============================================================ # 主翻译入口 diff --git a/App/lib/core/Phase1.vp b/App/lib/core/Phase1.vp index 521da7c..c401e0e 100644 --- a/App/lib/core/Phase1.vp +++ b/App/lib/core/Phase1.vp @@ -27,6 +27,7 @@ import lib.core.StubMergerBuild as StubMergerBuild import lib.core.StubMergerCollect as StubMergerCollect import lib.core.StubMergerIR as StubMergerIR import lib.core.StubMergerStore as StubMergerStore +import lib.core.Handles.ExprCallCtor as ExprCallCtor # 全局 mbuddy 指针 _mbuddy: memhub.MemBuddy | t.CPtr @@ -920,7 +921,7 @@ def RunPhase1(mb: memhub.MemBuddy | t.CPtr, includes_dir: str, temp_dir: str, # 必须在 includes 翻译前设置:Phase1 翻译 json 等 includes 时,"同模块方法 # 调用(定义在后)"(如 json.__setitem__ 调 _pool_alloc)需要读 # {temp_dir}/{sha1[0:2]}/{sha1}.vpi 兜底,而 Phase2 的 SetTempDir 太晚。 - HandlesExprCall.SetTempDir(temp_dir) + ExprCallCtor.SetTempDir(temp_dir) # 确保 temp 目录存在(build_dir/temp 可能尚未创建) BuildPipeline.ensure_dir(temp_dir) diff --git a/App/lib/core/Phase2.vp b/App/lib/core/Phase2.vp index dab1532..78020d6 100644 --- a/App/lib/core/Phase2.vp +++ b/App/lib/core/Phase2.vp @@ -31,6 +31,7 @@ import lib.core.StubMergerCollect as StubMergerCollect import lib.core.StubMergerIR as StubMergerIR import lib.core.StubMergerStore as StubMergerStore import lib.core.StubMergerTopo as StubMergerTopo +import lib.core.Handles.ExprCallCtor as ExprCallCtor # 全局 mbuddy 指针 _mbuddy: memhub.MemBuddy | t.CPtr @@ -538,7 +539,7 @@ def RunMultiFileProject(mb: memhub.MemBuddy | t.CPtr, # 设置 temp 目录路径,使 HandlesExprCall 能读取依赖模块的 text.ll # 用于跨模块方法返回类型查找(避免指针返回值被截断为 i32) - HandlesExprCall.SetTempDir(temp_dir) + ExprCallCtor.SetTempDir(temp_dir) # app_deps_buf: 收集所有 App 源文件的直接依赖模块名(空格分隔) # 供 Phase B+ 的 _BuildReachableSha1Set 作为初始 worklist 使用