refactor(handles): HandlesExprCall 拆 6 组(Base/Deref/Ctor/Call/Table/Handle,2041→241 行)

直接移动+改调用方:~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 验证通过
This commit is contained in:
TermiNexus committed 2026-08-17 08:10:55 +08:00
1 parent 278893d203
commit 2cb974ae5a
34 files changed
+2319 -2083

No files matched your search

+7 -5
View File
@@ -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
+13 -10
View File
@@ -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)
# ============================================================
+13 -11
View File
@@ -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
+41 -37
View File
@@ -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)
+2 -1
View File
@@ -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
+41 -36
View File
@@ -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)
+4 -2
View File
@@ -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)
+10 -9
View File
@@ -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")
+2 -1
View File
@@ -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
+2 -1
View File
@@ -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
# ============================================================
+2 -1
View File
@@ -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
+3 -2
View File
@@ -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 中声明该方法)视为存在
+6 -5
View File
@@ -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
+2 -1
View File
@@ -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)
+10 -8
View File
@@ -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
+10 -8
View File
@@ -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)
# ============================================================
+23 -20
View File
@@ -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:
+6 -4
View File
@@ -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 字节名
+4 -2
View File
@@ -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)
+2 -1
View File
@@ -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
+2 -1
View File
@@ -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:
# 错误定位:压入触发特化的调用方帧(注解所在文件+行号)
+246
View File
@@ -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
+338
View File
@@ -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 <ap_ty> <ap>, <type>(委托到 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 <va_list_ty> <trans._va_list_ptr>, <type>(委托到 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
+622
View File
@@ -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_value>, %tag_ptr ; 写入 tag
# %p1_ptr = gep %tmp, 0, 1 ; _p1 字段
# store <coerced_arg0>, %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 <ret_ty> @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
+291
View File
@@ -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 <pointee_ty>, <pointee_ty>* %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 <val_ty>*
# store <val_ty> %val, <val_ty>* %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 <ty>*
# %loaded = load <ty>, <ty>* %pc_src
# %pc_dst = bitcast i8* %dst to <ty>*
# store <ty> %loaded, <ty>* %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 <ret_ty> asm sideeffect "<asm>", "<constraints>"(<args>)
# 或: call void asm sideeffect "<asm>", "<constraints>"(<args>)
#
# 操作数按出现顺序编号 $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 <ty> %llvmirN, <ty>* %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
+284
View File
@@ -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
+206
View File
@@ -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
+4 -2
View File
@@ -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:
+11 -8
View File
@@ -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 中声明该方法)视为存在
File diff suppressed because it is too large. Load diff
+5 -4
View File
@@ -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(
+4 -2
View File
@@ -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)
# ============================================================
# 主翻译入口
+2 -1
View File
@@ -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)
+2 -1
View File
@@ -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 使用