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:
1 parent
b49b5c3ba6
commit
9656bb161a
6 files changed
+82
-32
No files matched your search
@@ -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
|
||||
|
||||
Reference in new issue
Block a user