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:
1 parent
278893d203
commit
2cb974ae5a
34 files changed
+2319
-2083
No files matched your search
@@ -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
|
||||
|
||||
|
||||
@@ -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)
|
||||
# ============================================================
|
||||
|
||||
@@ -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
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
# ============================================================
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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 中声明该方法)视为存在
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
# ============================================================
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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 字节名
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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:
|
||||
# 错误定位:压入触发特化的调用方帧(注解所在文件+行号)
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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:
|
||||
|
||||
@@ -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
@@ -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(
|
||||
|
||||
@@ -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)
|
||||
|
||||
# ============================================================
|
||||
# 主翻译入口
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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 使用
|
||||
|
||||
Reference in new issue
Block a user