feat(codegen): 值引用自动取址收口到 _adjust_args,补齐 vtable/方法/构造等路径

查表键统一为真实发射出的函数名:FuncGen._adjust_args 开头以 func.name 调用 _apply_auto_addr,于是 direct/vtable 虚分派/构造/静态/__call__/下标赋值/c.Addr 构造/闭包/泛型/方法兜底全部自动取址,不再依赖每个调用点手写;同时删除 16 处冗余显式取址(t.CAutoPtr 的 always 模式不幂等,重复应用会多包一层指针)。登记侧:HandlesImports 把模式登记提前到 FuncName-in-Gen.functions 早退之前并按 func.name 主键写表,_TryLoadStructFromStub 改为无条件调用;HandlesFunctions 在函数对象就绪后按真实名登记,并在 _EmitFunctionForwardDeclLlvm 把逻辑名下的模式播种到 MangledName,覆盖同模块先调用后定义的场景。
This commit is contained in:
TermiNexus committed 2026-10-07 19:59:36 +08:00
1 parent b49b5c3ba6
commit 9656bb161a
6 files changed
+82 -32

No files matched your search

+35 -16
View File
@@ -1692,6 +1692,21 @@ class ImportHandle(BaseHandle):
_src_sha1 = Gen.ModuleSha1Map[_init_name]
if _src_sha1:
Gen._export_extern_funcs[FuncName] = _src_sha1
# 自动取址模式(ref/temp/always)的登记**必须先于下面的 `FuncName in Gen.functions`
# 早退**:该函数已存在(stub / 调用点先建)时本函数会在此直接返回,若把登记放在
# 后面 func 创建处(约 :1885)就永远不会执行 ⇒ 跨模块函数的取址模式静默失效。
# 查表键与查表侧 FuncGen._adjust_args 的 func.name 逐字一致,故这里按"真实名候选"
# 双写:新算出的 mangled 名,以及已存在函数对象的实际名字(若已存在)。
_auto_modes: list[str | None] = [
FindAutoAddrMode(a.annotation) for a in Node.args.args]
if any(m is not None for m in _auto_modes):
_early_mangled: str = Gen._mangle_func_name(FuncName, module_name=source_module_name)
Gen._auto_addr_params[_early_mangled] = _auto_modes
Gen._auto_addr_params[FuncName] = _auto_modes
_early_existing = Gen.functions.get(FuncName)
_early_real: str | None = getattr(_early_existing, 'name', None)
if _early_real:
Gen._auto_addr_params[_early_real] = _auto_modes
if FuncName in Gen.functions:
return
if Node.decorator_list:
@@ -1870,11 +1885,12 @@ class ImportHandle(BaseHandle):
func = Gen._get_or_declare_function(MangledName, FuncType)
Gen.functions[MangledName] = func
Gen.functions[FuncName] = func
# 跨模块自动取址模式登记(ref/temp/always):调用点 Gen._apply_auto_addr 按函数名
# 查表,命中才做取址适配。ParamTypes 与 Node.args.args 逐位对齐(含方法 self)。
_auto_modes: list[str | None] = [
FindAutoAddrMode(a.annotation) for a in Node.args.args]
# 跨模块自动取址模式登记(ref/temp/always):以**真实发射名** func.name 为主键,
# 与查表侧 FuncGen._adjust_args 的 func.name 逐字一致;MangledName / FuncName
# 保留为别名键。ParamTypes 与 Node.args.args 逐位对齐(含方法 self)。
# (_auto_modes 已在函数开头"早退之前"处计算,此处复用。)
if any(m is not None for m in _auto_modes):
Gen._auto_addr_params[func.name] = _auto_modes
Gen._auto_addr_params[MangledName] = _auto_modes
Gen._auto_addr_params[FuncName] = _auto_modes
func_meta = FuncMeta.NONE
@@ -2526,18 +2542,21 @@ class ImportHandle(BaseHandle):
DeclFuncName = FuncFullName + '$set'
elif is_item_prop_deleter:
DeclFuncName = FuncFullName + '$del'
if DeclFuncName not in Gen.functions:
FuncDeclNode = ast.FunctionDef(
name=DeclFuncName,
args=item.args,
body=item.body,
decorator_list=item.decorator_list,
returns=item.returns
)
try:
self._EmitExternalFuncDeclLlvm(FuncDeclNode, Gen, is_class_method=not is_item_static and not is_item_classmethod, source_module_name=module_name)
except Exception as e:
raise
# 无条件调用:即使 DeclFuncName 已在 Gen.functions 中,也必须让
# _EmitExternalFuncDeclLlvm 走到其**早退之前**的自动取址登记逻辑
# (该函数在早退前完成登记后即返回,对已存在符号无其它副作用);
# 否则下面的守卫会让整个调用被跳过,stub 方法的取址模式永不生效。
FuncDeclNode = ast.FunctionDef(
name=DeclFuncName,
args=item.args,
body=item.body,
decorator_list=item.decorator_list,
returns=item.returns
)
try:
self._EmitExternalFuncDeclLlvm(FuncDeclNode, Gen, is_class_method=not is_item_static and not is_item_classmethod, source_module_name=module_name)
except Exception as e:
raise
func_meta = FuncMeta.NONE
if is_item_static:
func_meta |= FuncMeta.STATIC_METHOD