refactor(backend): 单端 MLIR —— 发射器全树改名 mlirlite 并删除 --backend 开关

- App/Test 的 .vp 中 llvmlite 全部改名为 mlirlite(import、限定名、类型注解、注释)

- 删除后端开关:Config.set_backend/is_mlir_backend/alias_module_name、BackendTarget/BackendIsMlir、CLI --backend、options.backend/options.target 读取,以及 IncludesScanner/StubMergerIR 的模块别名调用

- BuildPipeline 的 mlir-opt -> mlir-translate 降级管线去掉开关门,改为恒执行

- backend_dir_suffix 改名 mlir_dir_suffix 并恒返回 _mlir:TempDir/OutputDir/includes 缓存继续落在 *_mlir,避免复用旧 LLVM 后端的 .ll/obj

- project.vpj 删除已失效的 options.target
This commit is contained in:
TermiNexus committed 2026-10-03 19:26:24 +08:00
1 parent 1dcd29db9c
commit 7b3e814524
70 files changed
+5670 -5746

No files matched your search

+175 -175
View File
@@ -9,7 +9,7 @@ import stdio
import stdlib
import sys
import memhub
import llvmlite
import mlirlite
import viperlib
import w32.fileio as fileio
import lib.core.VLogger as VLogger
@@ -774,8 +774,8 @@ def _resolve_vpi_param_annot_seg_template(pool: memhub.MemBuddy*,
cls_name: str,
method_name: str,
seg_idx: int,
i32_ty: llvmlite.LLVMType*,
i8_ptr_ty: llvmlite.LLVMType*) -> llvmlite.LLVMType*:
i32_ty: mlirlite.LLVMType*,
i8_ptr_ty: mlirlite.LLVMType*) -> mlirlite.LLVMType*:
"""特化类 X[arg] 的参数注解段解析(模板 X[T] 注解 + T→arg 替换);未命中 None"""
if pool is None or src_sha1 is None or cls_name is None or method_name is None \
or _g_vpi_param_keys is None:
@@ -802,7 +802,7 @@ def _resolve_vpi_param_annot_seg_template(pool: memhub.MemBuddy*,
string.strncpy(arg_t, lbkt_t + 1, arg_len_t)
arg_t[arg_len_t] = '\0'
sha1_len_t: sizet = string.strlen(src_sha1)
ty_t: llvmlite.LLVMType* = None
ty_t: mlirlite.LLVMType* = None
ki_t: int
for ki_t in range(_g_vpi_param_count):
gk_t: bytes = _g_vpi_param_keys + ki_t * VPI_PARAM_KEY_LEN
@@ -873,13 +873,13 @@ def _resolve_vpi_param_annot_seg_template(pool: memhub.MemBuddy*,
# 补全后 declare 参数数与 define 一致,调用点默认参数填充才能生效,避免被调函数读栈垃圾。
# ============================================================
def _repair_declare_params_from_text(pool: memhub.MemBuddy*,
func: llvmlite.Function*,
func: mlirlite.Function*,
src_sha1: str,
cls_name: str,
method_name: str,
param_count: int,
i32_ty: llvmlite.LLVMType*,
i8_ptr_ty: llvmlite.LLVMType*) -> int:
i32_ty: mlirlite.LLVMType*,
i8_ptr_ty: mlirlite.LLVMType*) -> int:
"""用 vpi 文本缓存的参数注解补全 declare 参数;返回补全后参数数"""
if func is None or src_sha1 is None or method_name is None:
return param_count
@@ -906,18 +906,18 @@ def _repair_declare_params_from_text(pool: memhub.MemBuddy*,
if prm_annots[cur2] == '@':
cur2 += 1
if seg_idx >= param_count:
param_ty_r: llvmlite.LLVMType* = i8_ptr_ty
param_ty_r: mlirlite.LLVMType* = i8_ptr_ty
if seg_len2 > 0:
seg_buf_r: bytes = stdlib.malloc(seg_len2 + 1)
if seg_buf_r is not None:
string.strncpy(seg_buf_r, prm_annots + seg_start2, seg_len2)
seg_buf_r[seg_len2] = '\0'
rt: llvmlite.LLVMType* = _resolve_vpi_ret_annot_str(
rt: mlirlite.LLVMType* = _resolve_vpi_ret_annot_str(
pool, seg_buf_r, i32_ty, i8_ptr_ty)
if rt is not None:
param_ty_r = rt
stdlib.free(seg_buf_r)
llvmlite.add_param(pool, func, param_ty_r, "arg")
mlirlite.add_param(pool, func, param_ty_r, "arg")
seg_start2 = cur2
seg_idx += 1
return pa_count
@@ -935,8 +935,8 @@ def _resolve_vpi_param_annot_seg(pool: memhub.MemBuddy*,
cls_name: str,
method_name: str,
seg_idx: int,
i32_ty: llvmlite.LLVMType*,
i8_ptr_ty: llvmlite.LLVMType*) -> llvmlite.LLVMType*:
i32_ty: mlirlite.LLVMType*,
i8_ptr_ty: mlirlite.LLVMType*) -> mlirlite.LLVMType*:
"""按段索引解析 vpi 参数注解段为 LLVMType,空段/失败返回 None"""
if pool is None or src_sha1 is None or method_name is None:
return None
@@ -963,7 +963,7 @@ def _resolve_vpi_param_annot_seg(pool: memhub.MemBuddy*,
return None
string.strncpy(seg_buf_p, prm_annots_p + seg_start_p, seg_len_p)
seg_buf_p[seg_len_p] = '\0'
seg_ty_p: llvmlite.LLVMType* = _resolve_vpi_ret_annot_str(
seg_ty_p: mlirlite.LLVMType* = _resolve_vpi_ret_annot_str(
pool, seg_buf_p, i32_ty, i8_ptr_ty)
stdlib.free(seg_buf_p)
return seg_ty_p
@@ -1317,7 +1317,7 @@ def _lookup_vpi_ret_annot(src_sha1: str, cls_name: str, method_name: str) -> str
# 纯字符串解析,不构造 AST 节点。
# ============================================================
def _resolve_single_vpi_type_str(pool: memhub.MemBuddy*,
seg: str) -> llvmlite.LLVMType*:
seg: str) -> mlirlite.LLVMType*:
"""解析单个类型段为 LLVMType,无法识别返回 None"""
if seg is None or pool is None:
return None
@@ -1359,37 +1359,37 @@ def _resolve_single_vpi_type_str(pool: memhub.MemBuddy*,
while star_k_ps < star_cnt_ps:
string.strcat(star_buf_ps, "]")
star_k_ps += 1
star_ty_ps: llvmlite.LLVMType* = _resolve_single_vpi_type_str(pool, star_buf_ps)
star_ty_ps: mlirlite.LLVMType* = _resolve_single_vpi_type_str(pool, star_buf_ps)
stdlib.free(star_buf_ps)
return star_ty_ps
i8_ty: llvmlite.LLVMType* = llvmlite.Int8(pool)
i8_ptr_ty: llvmlite.LLVMType* = llvmlite.Ptr(pool, i8_ty)
i8_ty: mlirlite.LLVMType* = mlirlite.Int8(pool)
i8_ptr_ty: mlirlite.LLVMType* = mlirlite.Ptr(pool, i8_ty)
# 内置别名
if string.strcmp(seg, "str") == 0 or string.strcmp(seg, "bytes") == 0:
return i8_ptr_ty
if string.strcmp(seg, "int") == 0:
return llvmlite.Int32(pool)
return mlirlite.Int32(pool)
if string.strcmp(seg, "bool") == 0:
return llvmlite.Int1(pool)
return mlirlite.Int1(pool)
# LLVM 类型串:vpi 缓存对无返回注解方法默认存 "i32"
# (见 _cache_vpi_return_annots_text;push 等无注解方法返回 i32)。
# 之前缺分支导致解析返回 None → 泛型模板方法(Vector[int].push)调用
# 走 fail-fast"方法返回类型无法精确获取",实际是约定不一致。
if string.strcmp(seg, "i32") == 0: return llvmlite.Int32(pool)
if string.strcmp(seg, "i64") == 0: return llvmlite.Int64(pool)
if string.strcmp(seg, "i16") == 0: return llvmlite.Int16(pool)
if string.strcmp(seg, "i32") == 0: return mlirlite.Int32(pool)
if string.strcmp(seg, "i64") == 0: return mlirlite.Int64(pool)
if string.strcmp(seg, "i16") == 0: return mlirlite.Int16(pool)
if string.strcmp(seg, "i8") == 0: return i8_ty
if string.strcmp(seg, "i1") == 0: return llvmlite.Int1(pool)
if string.strcmp(seg, "f32") == 0: return llvmlite.Float(pool)
if string.strcmp(seg, "f64") == 0: return llvmlite.Double(pool)
if string.strcmp(seg, "void") == 0: return llvmlite.Void(pool)
if string.strcmp(seg, "i1") == 0: return mlirlite.Int1(pool)
if string.strcmp(seg, "f32") == 0: return mlirlite.Float(pool)
if string.strcmp(seg, "f64") == 0: return mlirlite.Double(pool)
if string.strcmp(seg, "void") == 0: return mlirlite.Void(pool)
# vpi 源文本中 `-> None` 被原样缓存为 "None"(_cache_vpi_return_annots_text
# 提取 arrow_pos 后到 ':' 前的内容)。此前无 "None" 分支 → 解析返回 None →
# `-> None` 的跨模块方法(如 AssignGenMixin._register_cdefine_from_value)vpi
# 缓存命中也解析不出 void → 方法返回类型 fail-fast 误报(追加80e 断点 B)。
# None 与 void 同义,归一到 Void。
if string.strcmp(seg, "None") == 0:
return llvmlite.Void(pool)
return mlirlite.Void(pool)
# rawptr[T] 内建裸指针(等价 t.CPtr[T] → Ptr(T)):vpi 返回/参数注解按源码
# 原样保留 Subscript 形态(如 tokens.vp `new_token -> rawptr[Token]`)。
# 此前无此分支 → 整个注解解析返回 None → text.ll 尚未生成(合法时序:依赖
@@ -1404,10 +1404,10 @@ def _resolve_single_vpi_type_str(pool: memhub.MemBuddy*,
if inner_buf_rp is not None:
string.strncpy(inner_buf_rp, seg + 7, inner_len_rp)
inner_buf_rp[inner_len_rp] = '\0'
inner_ty_rp: llvmlite.LLVMType* = _resolve_single_vpi_type_str(pool, inner_buf_rp)
inner_ty_rp: mlirlite.LLVMType* = _resolve_single_vpi_type_str(pool, inner_buf_rp)
stdlib.free(inner_buf_rp)
if inner_ty_rp is not None:
return llvmlite.Ptr(pool, inner_ty_rp)
return mlirlite.Ptr(pool, inner_ty_rp)
return None
# t.CPtr[T] / c.CPtr[T] 下标指针(含嵌套,如 t.CPtr[t.CPtr] → Ptr(Ptr(i8))):与定义侧 TypeGenResolve 的 Subscript(CPtr) 分支同口径 Ptr(resolve(T))。
# vpi 注解文本按源码原样缓存;本函数若对该形态返回 None 会让该段被丢弃 → 联合坍缩到首段(i8),与定义侧指针层级不一致(跨模块 declare/define ABI 错位)。
@@ -1422,11 +1422,11 @@ def _resolve_single_vpi_type_str(pool: memhub.MemBuddy*,
if inner_buf_cp is not None:
string.strncpy(inner_buf_cp, seg + cptr_sub_pfx, inner_len_cp)
inner_buf_cp[inner_len_cp] = '\0'
inner_ty_cp: llvmlite.LLVMType* = _resolve_single_vpi_type_str(
inner_ty_cp: mlirlite.LLVMType* = _resolve_single_vpi_type_str(
pool, inner_buf_cp)
stdlib.free(inner_buf_cp)
if inner_ty_cp is not None:
return llvmlite.Ptr(pool, inner_ty_cp)
return mlirlite.Ptr(pool, inner_ty_cp)
return None
# t.XXX / c.XXX 内置类型映射
if string.strncmp(seg, "t.", 2) == 0 or string.strncmp(seg, "c.", 2) == 0:
@@ -1437,10 +1437,10 @@ def _resolve_single_vpi_type_str(pool: memhub.MemBuddy*,
# 返回类型无法精确获取 fail-fast 误报(VKernel mm.free -> t.CExport
# "1fdad1c76fb116bc.free 返回类型无法精确获取" 根因)。
if string.strcmp(attr_nm, "CExport") == 0:
return llvmlite.Void(pool)
return mlirlite.Void(pool)
# [阶段2] 统一口径:CTypedef 动态表优先(库 typedef 走正常库分析),
# miss 回退 map_t_type(t/c 库内部特判)。
mapped_ty: llvmlite.LLVMType* = GenApi.resolve_typedef_or_map(pool, attr_nm, None, None)
mapped_ty: mlirlite.LLVMType* = GenApi.resolve_typedef_or_map(pool, attr_nm, None, None)
if mapped_ty is not None:
return mapped_ty
return None
@@ -1448,7 +1448,7 @@ def _resolve_single_vpi_type_str(pool: memhub.MemBuddy*,
last_dot: str = string.strrchr(seg, '.')
if last_dot is not None:
cls_nm2: str = last_dot + 1
mod_struct_ty: llvmlite.LLVMType* = GenApi.get_struct_type(cls_nm2)
mod_struct_ty: mlirlite.LLVMType* = GenApi.get_struct_type(cls_nm2)
if mod_struct_ty is not None:
return mod_struct_ty
# 枚举兜底:t.CEnum 注册在独立 EnumTable(EnumEntry),不进 StructTable,
@@ -1456,20 +1456,20 @@ def _resolve_single_vpi_type_str(pool: memhub.MemBuddy*,
# struct 落空必须回退枚举表取 BaseTy(通常 i32)。否则 vpi 返回注解解析
# 失败 → 跨模块函数返回类型无法精确获取 → text.ll 缺失(依赖环)时
# 永久 pending(VKernel fat32→sched→process→fat32 Phase A 死锁根因)。
mod_enum_ty: llvmlite.LLVMType* = GenApi.get_enum_base_type(cls_nm2)
mod_enum_ty: mlirlite.LLVMType* = GenApi.get_enum_base_type(cls_nm2)
if mod_enum_ty is not None:
return mod_enum_ty
return None
# 裸类名 → 全局 struct 注册表
bare_struct_ty: llvmlite.LLVMType* = GenApi.get_struct_type(seg)
bare_struct_ty: mlirlite.LLVMType* = GenApi.get_struct_type(seg)
if bare_struct_ty is not None:
return bare_struct_ty
# 裸枚举名 → EnumTable 兜底(同上:枚举不在 StructTable)
bare_enum_ty: llvmlite.LLVMType* = GenApi.get_enum_base_type(seg)
bare_enum_ty: mlirlite.LLVMType* = GenApi.get_enum_base_type(seg)
if bare_enum_ty is not None:
return bare_enum_ty
# 裸 typedef 名(如 VOIDPTR):CTypedef 动态表优先,miss 回退 map_t_type
mapped_bare: llvmlite.LLVMType* = GenApi.resolve_typedef_or_map(pool, seg, None, None)
mapped_bare: mlirlite.LLVMType* = GenApi.resolve_typedef_or_map(pool, seg, None, None)
if mapped_bare is not None:
return mapped_bare
return None
@@ -1484,8 +1484,8 @@ def _resolve_single_vpi_type_str(pool: memhub.MemBuddy*,
# ============================================================
def _resolve_vpi_ret_annot_str(pool: memhub.MemBuddy*,
ret_annot: str,
i32_ty: llvmlite.LLVMType*,
i8_ptr_ty: llvmlite.LLVMType*) -> llvmlite.LLVMType*:
i32_ty: mlirlite.LLVMType*,
i8_ptr_ty: mlirlite.LLVMType*) -> mlirlite.LLVMType*:
"""直接解析 vpi 返回注解字符串为 LLVMType(不构造 AST 节点)"""
if ret_annot is None or pool is None:
return None
@@ -1500,10 +1500,10 @@ def _resolve_vpi_ret_annot_str(pool: memhub.MemBuddy*,
inner_len_t += 1
if ret_annot[6 + inner_len_t] != ']' or inner_len_t == 0:
return None
# tuple 返回类型的字段链表是 llvmlite.ParamNode(new_param_node / paramnode_set_next /
# tuple 返回类型的字段链表是 mlirlite.ParamNode(new_param_node / paramnode_set_next /
# Struct 形参均为 rawptr[ParamNode])——原先误注解为 Function*。
tup_head_t: llvmlite.ParamNode* = None
tup_tail_t: llvmlite.ParamNode* = None
tup_head_t: mlirlite.ParamNode* = None
tup_tail_t: mlirlite.ParamNode* = None
tup_count_t: int = 0
p_t: sizet = 0
while p_t < inner_len_t:
@@ -1523,26 +1523,26 @@ def _resolve_vpi_ret_annot_str(pool: memhub.MemBuddy*,
return None
string.strncpy(seg_buf_t, ret_annot + 6 + seg_s_t, seg_len_t)
seg_buf_t[seg_len_t] = '\0'
seg_ty_t: llvmlite.LLVMType* = _resolve_single_vpi_type_str(pool, seg_buf_t)
seg_ty_t: mlirlite.LLVMType* = _resolve_single_vpi_type_str(pool, seg_buf_t)
stdlib.free(seg_buf_t)
if seg_ty_t is None:
return None
tup_node_t: llvmlite.ParamNode* = llvmlite.new_param_node(pool, seg_ty_t)
tup_node_t: mlirlite.ParamNode* = mlirlite.new_param_node(pool, seg_ty_t)
if tup_node_t is None:
return None
if tup_head_t is None:
tup_head_t = tup_node_t
else:
llvmlite.paramnode_set_next(tup_tail_t, tup_node_t)
mlirlite.paramnode_set_next(tup_tail_t, tup_node_t)
tup_tail_t = tup_node_t
tup_count_t += 1
if tup_head_t is None:
return None
return llvmlite.Struct(pool, tup_head_t, tup_count_t, None)
return mlirlite.Struct(pool, tup_head_t, tup_count_t, None)
has_cptr: int = 0
has_cvoid: int = 0
first_ty: llvmlite.LLVMType* = None
first_ty: mlirlite.LLVMType* = None
# 产生 first_ty 那一段文本的属性(供末尾 has_cptr 分支复刻定义侧规则,N12):
# first_qual=1 段是限定名(含 '.',如 mod.Class / int64)
# first_wl =1 段是白名单裸标量名(int/char/str/bytes/bool/float/double)
@@ -1557,7 +1557,7 @@ def _resolve_vpi_ret_annot_str(pool: memhub.MemBuddy*,
# 与定义侧 `X | t.CPtr[T]` 分支同口径:CPtr 侧贡献 N 层指针、另一侧提供基类型 ⇒ Ptr^N(基类型)。
# 与 has_cptr(裸 t.CPtr 段)分开记录:裸标记恒「追加 1 层」且有 struct 吸收特例,下标路径无吸收,两者在定义侧分属互斥分支。
cptr_sub_lvl: int = 0
cptr_sub_ty: llvmlite.LLVMType* = None
cptr_sub_ty: mlirlite.LLVMType* = None
buf_len: sizet = string.strlen(ret_annot)
pos: sizet = 0
@@ -1601,18 +1601,18 @@ def _resolve_vpi_ret_annot_str(pool: memhub.MemBuddy*,
# 语义不同(如 X=struct S、t.CPtr[t.CPtr]:定义侧 Ptr(Ptr(S)),
# 取该段本身则得 i8**)。此处只记录 N 与段类型,末尾统一合并。
if string.strncmp(seg_buf, "t.CPtr[", 7) == 0 or string.strncmp(seg_buf, "c.CPtr[", 7) == 0:
seg_ty_cs: llvmlite.LLVMType* = _resolve_single_vpi_type_str(pool, seg_buf)
seg_ty_cs: mlirlite.LLVMType* = _resolve_single_vpi_type_str(pool, seg_buf)
if seg_ty_cs is not None:
# 计算外层 Ptr 嵌套数(定义侧 L2616-2632 同口径)。注意不能在
# case body 内更新 while 条件变量(自举编译的 match 会写到 subject
# 快照槽 → 条件读旧槽死循环,见 TypeGenResolve.vp L2620-2624):
# case 绑定 pointee 到局部变量,match 外更新循环变量。
lvl_cs: int = 0
cur_cs: llvmlite.LLVMType* = seg_ty_cs
cur_cs: mlirlite.LLVMType* = seg_ty_cs
while cur_cs is not None:
nxt_cs: llvmlite.LLVMType* = None
nxt_cs: mlirlite.LLVMType* = None
match cur_cs:
case llvmlite.LLVMType.Ptr(pointee_cs):
case mlirlite.LLVMType.Ptr(pointee_cs):
lvl_cs += 1
nxt_cs = pointee_cs
case _:
@@ -1631,7 +1631,7 @@ def _resolve_vpi_ret_annot_str(pool: memhub.MemBuddy*,
# (void* 应为 i8*,由下方 has_cptr 分支统一给出)。
has_cvoid = 1
else:
seg_ty: llvmlite.LLVMType* = _resolve_single_vpi_type_str(pool, seg_buf)
seg_ty: mlirlite.LLVMType* = _resolve_single_vpi_type_str(pool, seg_buf)
if seg_ty is not None and first_ty is None:
first_ty = seg_ty
# 记录该段属性(N12):定义侧 TypeGenResolve.resolve_annotation_type
@@ -1652,7 +1652,7 @@ def _resolve_vpi_ret_annot_str(pool: memhub.MemBuddy*,
# 而定义侧已改为「解析成功即保留」⇒ 跨模块同型收敛被破坏。判据直接用 GenApi.resolve_typedef_or_map(与定义侧同一 API),命中即置位保留;
# 仅对**非指针**解析结果置位(指针别名 BYTEPTR/HANDLE/VOIDPTR 不置位 → 仍坍缩 i8*,与定义侧守卫对称)。
if first_qual == 0 and first_wl == 0:
if first_ty.kind() != llvmlite.LLVMType.Ptr:
if first_ty.kind() != mlirlite.LLVMType.Ptr:
if GenApi.resolve_typedef_or_map(pool, seg_buf, None, None) is not None:
first_td = 1
stdlib.free(seg_buf)
@@ -1666,7 +1666,7 @@ def _resolve_vpi_ret_annot_str(pool: memhub.MemBuddy*,
# 解析出 void)⇒ 与 t.CPtr 合并即 void* = i8*,与 has_cvoid 分支同结论
# (否则会拼出非法的 Ptr(void))。
match first_ty:
case llvmlite.LLVMType.Void():
case mlirlite.LLVMType.Void():
return i8_ptr_ty
case _:
pass
@@ -1675,17 +1675,17 @@ def _resolve_vpi_ret_annot_str(pool: memhub.MemBuddy*,
# 指针别名(first_td 不置位,如 VOIDPTR = CVoid|CPtr → i8*):`| t.CPtr`
# **恒追加恰好 1 层** → i8**(不吸收);指针型 T 同理(见下)。
if first_qual != 0 or first_wl != 0 or first_td != 0:
return llvmlite.Ptr(pool, first_ty)
if first_ty.kind() == llvmlite.LLVMType.Struct:
return llvmlite.Ptr(pool, first_ty)
if first_ty.kind() == llvmlite.LLVMType.Ptr:
return mlirlite.Ptr(pool, first_ty)
if first_ty.kind() == mlirlite.LLVMType.Struct:
return mlirlite.Ptr(pool, first_ty)
if first_ty.kind() == mlirlite.LLVMType.Ptr:
# `| t.CPtr` **恒追加恰好 1 层**(与定义侧 TypeGenResolve 的 BinOp 分支同口径):
# 这里原先还做"pointee 命中 find_struct_by_type(类引用语义)就吸收 1 层",
# 那是"裸类名自动升指针"时代的补偿,自裸类名恒为**原型 struct** 后已无对象;
# 而泛型形参实例化为指针类型时(T 的实参文本 `{sha}.AST*`)first_ty 正是
# Ptr(已注册 struct) ⇒ 误吸收把 `T*` 降成 AST*(应为 AST**),
# 现场 includes/_list.vp:54 `elem_ptr[0] = item`。
return llvmlite.Ptr(pool, first_ty)
return mlirlite.Ptr(pool, first_ty)
return i8_ptr_ty
return i8_ptr_ty
# CPtr 下标段联合合并(与定义侧同口径):有另一侧基类型 first_ty → 结果 = Ptr^N(first_ty)(N=cptr_sub_lvl);仅 CPtr 下标段自身 → 该段解析类型本身。
@@ -1693,17 +1693,17 @@ def _resolve_vpi_ret_annot_str(pool: memhub.MemBuddy*,
if cptr_sub_lvl > 0:
if first_ty is None:
return cptr_sub_ty
res_ty_cs: llvmlite.LLVMType* = first_ty
res_ty_cs: mlirlite.LLVMType* = first_ty
wrap_i_cs: int = 0
while wrap_i_cs < cptr_sub_lvl:
res_ty_cs = llvmlite.Ptr(pool, res_ty_cs)
res_ty_cs = mlirlite.Ptr(pool, res_ty_cs)
wrap_i_cs += 1
return res_ty_cs
if has_cvoid != 0:
# t\.CVoid | t.State:State 是装饰器标记(编译侧忽略),t\.CVoid → void。
# 此前缺此分支 → first_ty=None → 返回 None → 跨模块函数返回类型
# fail-fast(CPythonTest Py_Initialize() -> t\.CVoid | t.State 根因)。
return llvmlite.Void(pool)
return mlirlite.Void(pool)
if first_ty is not None:
return first_ty
return None
@@ -2034,7 +2034,7 @@ def _vpi_register_typedef_closure(pool: memhub.MemBuddy*,
# Returns: 1=成功,0=失败
# ============================================================
def ParseVpiIntoModule(pool: memhub.MemBuddy*,
mod: llvmlite.LLVMModule*,
mod: mlirlite.LLVMModule*,
vpi_path: str,
trans: HT.Translator*) -> int:
"""解析 .vpi 文件,将函数声明注入到当前模块
@@ -2053,7 +2053,7 @@ def ParseVpiIntoModule(pool: memhub.MemBuddy*,
def _ParseVpiIntoModuleImpl(pool: memhub.MemBuddy*,
mod: llvmlite.LLVMModule*,
mod: mlirlite.LLVMModule*,
vpi_path: str,
trans: HT.Translator*) -> int:
"""解析 .vpi 文件,将函数声明注入到当前模块(ParseVpiIntoModule 实际实现)"""
@@ -2331,9 +2331,9 @@ def _ParseVpiIntoModuleImpl(pool: memhub.MemBuddy*,
if imported_modules is not None:
_vpi_register_typedef_closure(pool, imported_modules, GenApi.get_temp_dir(), 0)
i32_ty: llvmlite.LLVMType* = llvmlite.Int32(pool)
i8_ty: llvmlite.LLVMType* = llvmlite.Int8(pool)
i8_ptr_ty: llvmlite.LLVMType* = llvmlite.Ptr(pool, i8_ty)
i32_ty: mlirlite.LLVMType* = mlirlite.Int32(pool)
i8_ty: mlirlite.LLVMType* = mlirlite.Int8(pool)
i8_ptr_ty: mlirlite.LLVMType* = mlirlite.Ptr(pool, i8_ty)
# 函数表信息
funcs_ptr: GenTypes.FuncEntry* = trans._funcs
@@ -2542,7 +2542,7 @@ def ResetVpiInjectVisited() -> None:
def _ensure_dep_vpi_injected(pool: memhub.MemBuddy*,
mod: llvmlite.LLVMModule*,
mod: mlirlite.LLVMModule*,
dep_sha1: str,
trans: HT.Translator*) -> int:
"""按需注入 dep_sha1 对应的 .vpi 到当前模块(防重入),1=就绪 / 0=失败"""
@@ -2617,7 +2617,7 @@ def _ensure_dep_vpi_injected(pool: memhub.MemBuddy*,
# Args: src_name 子模块中的原类名;local_name 包命名空间中的名字(或 as 别名);sub_sha1 子模块(定义文件)sha1;pkg_sha1 当前包 __init__ 的 sha1;trans 翻译器对象(源 entry 缺失时按需注入子模块 vpi 需要)
# ============================================================
def _inject_reexport_class_declare(pool: memhub.MemBuddy*,
mod: llvmlite.LLVMModule*,
mod: mlirlite.LLVMModule*,
src_name: str,
local_name: str,
sub_sha1: str,
@@ -2745,7 +2745,7 @@ def _vpi_class_is_renum(class_cd: ast.ClassDef*) -> int:
# 字段解析失败不 fatal(不注册该类,留给源模块编译注册,后续裸类名引用由调用侧 fail-fast 暴露)。
# ============================================================
def _inject_class_struct_declare(pool: memhub.MemBuddy*,
mod: llvmlite.LLVMModule*,
mod: mlirlite.LLVMModule*,
class_cd: ast.ClassDef*,
cls_name: str,
trans: HT.Translator*,
@@ -2859,7 +2859,7 @@ def _inject_class_struct_declare(pool: memhub.MemBuddy*,
m_tgt_c: ast.Name* = ast.Name*(m_aa_c.target)
if m_tgt_c.id is None:
continue
field_ty_c: llvmlite.LLVMType* = GenApi.resolve_annotation_type(
field_ty_c: mlirlite.LLVMType* = GenApi.resolve_annotation_type(
pool, m_aa_c.annotation, imported_modules, from_imports, trans, 0)
if field_ty_c is None:
# 字段类型解析失败:不注册该类(留给源模块编译注册),不 fatal
@@ -2873,14 +2873,14 @@ def _inject_class_struct_declare(pool: memhub.MemBuddy*,
if field_count == 0:
return 0
# 4. 构建 ParamNode 链表
first_node_c: rawptr[llvmlite.ParamNode] = None
prev_node_c: rawptr[llvmlite.ParamNode] = None
first_node_c: rawptr[mlirlite.ParamNode] = None
prev_node_c: rawptr[mlirlite.ParamNode] = None
for fi_c in range(field_count):
fty_c: llvmlite.LLVMType* = (llvmlite.LLVMType*)(field_types_buf[fi_c])
pnode_c: rawptr[llvmlite.ParamNode] = pool.alloc(llvmlite.ParamNode.__sizeof__())
fty_c: mlirlite.LLVMType* = (mlirlite.LLVMType*)(field_types_buf[fi_c])
pnode_c: rawptr[mlirlite.ParamNode] = pool.alloc(mlirlite.ParamNode.__sizeof__())
if pnode_c is None:
continue
string.memset(pnode_c, 0, llvmlite.ParamNode.__sizeof__())
string.memset(pnode_c, 0, mlirlite.ParamNode.__sizeof__())
pnode_c.Ty = fty_c
if first_node_c is None:
first_node_c = pnode_c
@@ -2904,14 +2904,14 @@ def _inject_class_struct_declare(pool: memhub.MemBuddy*,
name_buf_c[sh_len_c] = '.'
string.strcpy(name_buf_c + sh_len_c + 1, real_name)
type_name_c = name_buf_c
struct_ty_c: llvmlite.LLVMType* = llvmlite.Struct(
struct_ty_c: mlirlite.LLVMType* = mlirlite.Struct(
pool, first_node_c, field_count, type_name_c)
if struct_ty_c is None:
return 0
# 5. StdlibAlloc(Phase B)时深拷贝到 perm_pool,跨文件 reset 存活
# (对齐 ClassGenDef.translate_class_def L489-494)
if GenApi.get_stdlib_alloc() != 0:
st_copy_c: llvmlite.LLVMType* = llvmlite.DeepCopyType(
st_copy_c: mlirlite.LLVMType* = mlirlite.DeepCopyType(
CompilerFactory.factory.PermPool, struct_ty_c)
if st_copy_c is not None:
struct_ty_c = st_copy_c
@@ -2923,21 +2923,21 @@ def _inject_class_struct_declare(pool: memhub.MemBuddy*,
# ⇒ StructTable 爆表(现场:table full, cannot register Translator)。
# 必须早于 module_add_named_type:避免同一名字先以占位名注册、又以新对象重复注册。
if fill_fwd_c != 0 and existing_c is not None and existing_c.Ty is not None:
fwd_name_c: str = llvmlite.get_struct_name(existing_c.Ty)
fwd_fields_c: rawptr[llvmlite.ParamNode] = llvmlite.get_struct_fields(struct_ty_c)
fwd_fc_c: int = llvmlite.get_struct_fcount(struct_ty_c)
*existing_c.Ty = llvmlite.LLVMType.Struct(fwd_fields_c, fwd_fc_c, fwd_name_c)
fwd_name_c: str = mlirlite.get_struct_name(existing_c.Ty)
fwd_fields_c: rawptr[mlirlite.ParamNode] = mlirlite.get_struct_fields(struct_ty_c)
fwd_fc_c: int = mlirlite.get_struct_fcount(struct_ty_c)
*existing_c.Ty = mlirlite.LLVMType.Struct(fwd_fields_c, fwd_fc_c, fwd_name_c)
struct_ty_c = existing_c.Ty
type_name_c = fwd_name_c
existing_c.IsForwardDecl = 0
existing_c.FieldCount = 0
# 6. 注册到当前模块(输出类型定义行)+ 全局 StructTable + 可见性
llvmlite.module_add_named_type(mod, pool, struct_ty_c)
mlirlite.module_add_named_type(mod, pool, struct_ty_c)
# B5:vpi 保留 @c.Attribute(t.attr.packed) 装饰器,stub 注入的跨模块
# struct 必须同样 packed(<{...}>),否则引用模块 GEP 按非 packed 布局
# 算偏移,与定义侧 packed 布局错位(gdt/elf/fat32 二进制格式字段错读)。
if _vpi_class_has_packed(class_cd.decorator_list) != 0:
llvmlite.module_set_named_type_packed(mod, pool, struct_ty_c, 1)
mlirlite.module_set_named_type_packed(mod, pool, struct_ty_c, 1)
# 注册名用扁平名 real_name:跨模块引用 `外类.内类` 时 TypeGenResolve 查的是
# 扁平名条目(与定义端 StructGen 的登记名同源)。
entry_c: GenTypes.StructEntry* = GenApi.register_struct(
@@ -2955,7 +2955,7 @@ def _inject_class_struct_declare(pool: memhub.MemBuddy*,
afi_c: int = 0
for afi_c in range(field_count):
af_name_c: str = str(field_names_buf[afi_c])
af_ty_c: llvmlite.LLVMType* = (llvmlite.LLVMType*)(field_types_buf[afi_c])
af_ty_c: mlirlite.LLVMType* = (mlirlite.LLVMType*)(field_types_buf[afi_c])
GenApi.add_field(pool, entry_c, af_name_c, af_ty_c)
GenApi.add_visible_struct(pool, real_name)
return 1
@@ -2977,7 +2977,7 @@ def _inject_class_struct_declare(pool: memhub.MemBuddy*,
# mark_module_class 还原(见 _inject_class_struct_declare 内注释)。
# ============================================================
def _inject_nested_class_declares(pool: memhub.MemBuddy*,
mod: llvmlite.LLVMModule*,
mod: mlirlite.LLVMModule*,
class_cd: ast.ClassDef*,
prefix_name: str,
trans: HT.Translator*,
@@ -3012,23 +3012,23 @@ def _inject_nested_class_declares(pool: memhub.MemBuddy*,
# 均报 "use of undefined type"(值类型大小需已知)。vpi 注入类已 add_field 含字段(完整 Ty),在注册表可查时注册完整定义;
# 指针引用(Ptr(Struct))无需——_scan_type_for_cross_module_refs 的 Ptr 分支添加 opaque 即可。
# ============================================================
def _ensure_full_value_types(mod: llvmlite.LLVMModule*,
def _ensure_full_value_types(mod: mlirlite.LLVMModule*,
pool: memhub.MemBuddy*,
ty: llvmlite.LLVMType*) -> None:
ty: mlirlite.LLVMType*) -> None:
"""递归为值 struct / 数组元素 struct 注册完整定义(递归深度守卫)"""
if mod is None or pool is None or ty is None: return
match ty:
case llvmlite.LLVMType.Struct(_, _, _):
case mlirlite.LLVMType.Struct(_, _, _):
full_se_h: GenTypes.StructEntry* = GenApi.find_struct_by_type(ty)
if full_se_h is not None and full_se_h.Ty is not None:
llvmlite.module_add_named_type(mod, pool, full_se_h.Ty)
mlirlite.module_add_named_type(mod, pool, full_se_h.Ty)
# B5:值类型注入同步 packed 标记(对齐 ensure_struct_def_in_module)——
# vpi 全局变量(@_per_cpu = global %per_cpu_data)/值返回类型注入完整
# 定义时若只 add 不 set_packed → 引用模块节点 IsPacked=0 → 输出 {…}
# 非 packed(GEP 与定义侧 packed 布局错位,stub packed 失效根因)。
if full_se_h.IsPacked != 0:
llvmlite.module_set_named_type_packed(mod, pool, full_se_h.Ty, 1)
case llvmlite.LLVMType.Array(aelem_h, _):
mlirlite.module_set_named_type_packed(mod, pool, full_se_h.Ty, 1)
case mlirlite.LLVMType.Array(aelem_h, _):
if aelem_h is not None:
_ensure_full_value_types(mod, pool, aelem_h)
case _:
@@ -3049,18 +3049,18 @@ def _ensure_full_value_types(mod: llvmlite.LLVMModule*,
# Windows x64 ABI 小结构体(≤8 字节)按整数寄存器传、位兼容,且与定义侧同样降级 ⇒ 同符号签名仍逐字一致)。
# * TPV 内部函数/方法(存在 define 侧)→ Ptr(struct):与定义侧逐字一致,指针目标只需 opaque 声明(module_ensure_opaque_for_type)。
# ============================================================
def _AggregateParamTy(mod: llvmlite.LLVMModule*,
def _AggregateParamTy(mod: mlirlite.LLVMModule*,
pool: memhub.MemBuddy*,
ty: llvmlite.LLVMType*,
is_c_abi: int) -> llvmlite.LLVMType*:
ty: mlirlite.LLVMType*,
is_c_abi: int) -> mlirlite.LLVMType*:
"""裸结构体形参类型(C ABI 按值 / 内部 Ptr(struct),见上方注释)"""
if mod is None or pool is None or ty is None:
return ty
if is_c_abi != 0:
# 真 opaque 哨兵:fcount < 0(includes/llvmlite/__module.vp L491)
# 真 opaque 哨兵:fcount < 0(includes/mlirlite/__module.vp L491)
is_opaque_ap: int = 0
match ty:
case llvmlite.LLVMType.Struct(_, fcount_ap, _):
case mlirlite.LLVMType.Struct(_, fcount_ap, _):
if fcount_ap < 0:
is_opaque_ap = 1
case _:
@@ -3068,9 +3068,9 @@ def _AggregateParamTy(mod: llvmlite.LLVMModule*,
if is_opaque_ap == 0 and GenApi.find_struct_by_type(ty) is not None:
_ensure_full_value_types(mod, pool, ty)
return ty
return llvmlite.Int64(pool)
ptr_ty_ap: llvmlite.LLVMType* = llvmlite.Ptr(pool, ty)
llvmlite.module_ensure_opaque_for_type(mod, pool, ptr_ty_ap)
return mlirlite.Int64(pool)
ptr_ty_ap: mlirlite.LLVMType* = mlirlite.Ptr(pool, ty)
mlirlite.module_ensure_opaque_for_type(mod, pool, ptr_ty_ap)
return ptr_ty_ap
@@ -3081,13 +3081,13 @@ def _AggregateParamTy(mod: llvmlite.LLVMModule*,
# 否则跨模块 from-import 读取全局变量时 find_global_in_module 找不到 → 误杀「跨模块全局变量类型未知(stub 未注入)」。
# ============================================================
def _inject_global_variable_declare(pool: memhub.MemBuddy*,
mod: llvmlite.LLVMModule*,
mod: mlirlite.LLVMModule*,
aa: ast.AnnAssign*,
trans: HT.Translator*,
imported_modules: str,
from_imports: str,
i32_ty: llvmlite.LLVMType*,
i8_ptr_ty: llvmlite.LLVMType*,
i32_ty: mlirlite.LLVMType*,
i8_ptr_ty: mlirlite.LLVMType*,
src_sha1: str) -> None:
"""从 vpi AnnAssign 创建模块级全局变量 external declare(mangled 名 @<src_sha1>.<name>)"""
if pool is None or mod is None or aa is None or trans is None:
@@ -3130,30 +3130,30 @@ def _inject_global_variable_declare(pool: memhub.MemBuddy*,
if gv_name_m is not None:
viperlib.snprintf(gv_name_m, ml_v, "%s.%s", src_sha1, gname_v)
# 去重:遍历模块全局变量链表(mangled 名匹配)
cur_v: llvmlite.GlobalVariable* = mod.GlobalHead
cur_v: mlirlite.GlobalVariable* = mod.GlobalHead
while cur_v is not None:
if cur_v.Name is not None and string.strcmp(cur_v.Name, gv_name_m) == 0:
return
cur_v = cur_v.Next
# 解析注解类型(裸类 → Ptr(struct),CArray → 元素指针)
resolved_v: llvmlite.LLVMType* = None
resolved_v: mlirlite.LLVMType* = None
if aa.annotation is not None:
resolved_v = GenApi.resolve_annotation_type(
pool, aa.annotation, imported_modules, from_imports, trans)
if resolved_v is None:
return # 类型解析失败跳过:调用侧有 fail-fast 定位
gv_ty_v: llvmlite.LLVMType* = resolved_v
gv_ty_v: mlirlite.LLVMType* = resolved_v
match resolved_v:
case llvmlite.LLVMType.Struct(_, _, _):
case mlirlite.LLVMType.Struct(_, _, _):
# 对象类(@t.Object/@t.CVTable:对象即指针,HasNew/HasVTable/IsOOP)→ Ptr(struct),与定义端 handle_module_level_var 一致;
# 纯 t.CStruct 值类(如 pci_device)保持值实例——一律转 Ptr 会把实例前 8 字节当指针解引用(#GP),一律保持值则 @t.Object 类模块级变量按指针访问读错 vtable(#PF)。
gv_entry_v: GenTypes.StructEntry* = GenApi.find_struct_by_type(resolved_v)
if gv_entry_v is not None \
and (gv_entry_v.HasNew != 0 or gv_entry_v.HasVTable != 0 or gv_entry_v.IsOOP != 0):
gv_ty_v = llvmlite.Ptr(pool, resolved_v)
gv_ty_v = mlirlite.Ptr(pool, resolved_v)
else:
gv_ty_v = resolved_v
case llvmlite.LLVMType.Array(aelem_v, acount_v):
case mlirlite.LLVMType.Array(aelem_v, acount_v):
# 定长数组(CArray[T, N]):保留完整数组类型 [N x T],与定义端
# handle_module_level_var 生成的 global [N x T] 一致——此前一律
# 衰减为元素指针 i32*,链接后引用端 load 把数组前 8 字节当指针
@@ -3163,7 +3163,7 @@ def _inject_global_variable_declare(pool: memhub.MemBuddy*,
gv_ty_v = resolved_v
else:
# 不定长数组(CArray[T, None]):元素指针(C 数组衰减)
gv_ty_v = llvmlite.Ptr(pool, aelem_v)
gv_ty_v = mlirlite.Ptr(pool, aelem_v)
case _:
gv_ty_v = resolved_v
# 确保跨模块结构体类型在模块中有 opaque 声明:external global 类型
@@ -3173,11 +3173,11 @@ def _inject_global_variable_declare(pool: memhub.MemBuddy*,
# (_scan_type_for_cross_module_refs 递归 Array/Struct/Ptr)。
# 值类型(struct 值 / 数组元素 struct)注册完整定义(见 _ensure_full_value_types)
_ensure_full_value_types(mod, pool, gv_ty_v)
llvmlite.module_ensure_opaque_for_type(mod, pool, gv_ty_v)
gv_v: llvmlite.GlobalVariable* = llvmlite.new_global_variable(pool, gv_name_m, gv_ty_v)
mlirlite.module_ensure_opaque_for_type(mod, pool, gv_ty_v)
gv_v: mlirlite.GlobalVariable* = mlirlite.new_global_variable(pool, gv_name_m, gv_ty_v)
if gv_v is None:
return
llvmlite.module_add_global(mod, gv_v)
mlirlite.module_add_global(mod, gv_v)
gv_v.Linkage = "external"
@@ -3189,14 +3189,14 @@ def _inject_global_variable_declare(pool: memhub.MemBuddy*,
# 注册到函数表。
# ============================================================
def _inject_function_declare(pool: memhub.MemBuddy*,
mod: llvmlite.LLVMModule*,
mod: mlirlite.LLVMModule*,
fd: ast.FunctionDef*,
trans: HT.Translator*,
src_sha1: str,
imported_modules: str,
from_imports: str,
i32_ty: llvmlite.LLVMType*,
i8_ptr_ty: llvmlite.LLVMType*,
i32_ty: mlirlite.LLVMType*,
i8_ptr_ty: mlirlite.LLVMType*,
funcs_ptr: GenTypes.FuncEntry*,
max_funcs: int) -> None:
"""为 FunctionDef 创建 declare 声明并注入到模块"""
@@ -3253,12 +3253,12 @@ def _inject_function_declare(pool: memhub.MemBuddy*,
return
# 去重:如果函数已存在则跳过
existing: llvmlite.Function* = GenApi.find_func_in_module(mod, mangled_name)
existing: mlirlite.Function* = GenApi.find_func_in_module(mod, mangled_name)
if existing is not None:
return
# 也检查裸名(非裸名模式时,CExport 函数可能已通过其他途径注册)
if use_bare_name == 0:
existing_bare: llvmlite.Function* = GenApi.find_func_in_module(mod, fd.name)
existing_bare: mlirlite.Function* = GenApi.find_func_in_module(mod, fd.name)
if existing_bare is not None:
return
@@ -3266,7 +3266,7 @@ def _inject_function_declare(pool: memhub.MemBuddy*,
# 优先用缓存的返回注解字符串(tree 解析后立即提取,节点未损坏)
# 直接字符串解析(绕开 _parse_type_string 跨模块 AST 构造在 TPV 中的
# __init__/vtable 未执行问题,节点 kind() 异常导致 resolve 得垃圾类型)
ret_ty: llvmlite.LLVMType* = None
ret_ty: mlirlite.LLVMType* = None
ret_annot_fd: str = _lookup_vpi_ret_annot(src_sha1, None, fd.name)
if ret_annot_fd is not None:
ret_ty = _resolve_vpi_ret_annot_str(pool, ret_annot_fd, i32_ty, i8_ptr_ty)
@@ -3291,7 +3291,7 @@ def _inject_function_declare(pool: memhub.MemBuddy*,
or string.strcmp(pm_at.attr, "CExport") == 0):
is_pure_marker_rt = 1
if is_pure_marker_rt != 0:
ret_ty = llvmlite.Void(pool)
ret_ty = mlirlite.Void(pool)
elif has_state != 0 or has_extern != 0 or has_export != 0:
# 含真实类型但解析失败:回退外部函数返回类型白名单
# (FindFirstFileA/GetStdHandle → i8* HANDLE 等),避免默认 i32
@@ -3310,10 +3310,10 @@ def _inject_function_declare(pool: memhub.MemBuddy*,
# 值 struct 返回类型(如 gfx.vp Mat4_Identity -> Mat4)需要完整定义:
# declare %Mat4 opaque → llc "use of undefined type"。注册完整定义。
_ensure_full_value_types(mod, pool, ret_ty)
llvmlite.module_ensure_opaque_for_type(mod, pool, ret_ty)
mlirlite.module_ensure_opaque_for_type(mod, pool, ret_ty)
# 创建 declare
func: llvmlite.Function* = llvmlite.create_declare(
func: mlirlite.Function* = mlirlite.create_declare(
pool, mod, mangled_name, ret_ty)
if func is None:
return
@@ -3346,35 +3346,35 @@ def _inject_function_declare(pool: memhub.MemBuddy*,
if pname is None:
pname = "arg"
# 解析参数类型
param_ty: llvmlite.LLVMType* = i8_ptr_ty
param_ty: mlirlite.LLVMType* = i8_ptr_ty
# 优先用 vpi 文本注解缓存解析参数类型(与返回类型同源——vpi
# tree 深层节点 kind() 可能损坏,AST resolve 得垃圾类型如
# sizet→i32,跨模块 declare 参数宽错 → 调用侧 trunc 传参、
# callee 按宽类型读栈残留垃圾高位 → 参数巨值崩溃(SlotsBugTest
# 根因)。段索引 = pi(模块级函数无 self,0=首参)。
pseg_ty: llvmlite.LLVMType* = _resolve_vpi_param_annot_seg(
pseg_ty: mlirlite.LLVMType* = _resolve_vpi_param_annot_seg(
pool, src_sha1, None, fd.name, pi, i32_ty, i8_ptr_ty)
if pseg_ty is not None:
match pseg_ty:
case llvmlite.LLVMType.Struct(_, _, _):
case mlirlite.LLVMType.Struct(_, _, _):
# 裸结构体形参:C ABI 按值 / 内部 Ptr(struct)
# (判据与降级见 _AggregateParamTy,三处必须同步)
param_ty = _AggregateParamTy(mod, pool, pseg_ty, agg_is_c_abi)
case llvmlite.LLVMType.Array(aelem_ty, _):
param_ty = llvmlite.Ptr(pool, aelem_ty)
case mlirlite.LLVMType.Array(aelem_ty, _):
param_ty = mlirlite.Ptr(pool, aelem_ty)
case _:
param_ty = pseg_ty
elif ag.annotation is not None:
resolved_ty: llvmlite.LLVMType* = GenApi.resolve_annotation_type(
resolved_ty: mlirlite.LLVMType* = GenApi.resolve_annotation_type(
pool, ag.annotation, imported_modules, from_imports, trans)
if resolved_ty is not None:
# CArray 参数 → 元素指针 ty*(C 数组衰减,与编译侧一致)。
# 裸结构体参数 → _AggregateParamTy(同一判据)。
match resolved_ty:
case llvmlite.LLVMType.Struct(_, _, _):
case mlirlite.LLVMType.Struct(_, _, _):
param_ty = _AggregateParamTy(mod, pool, resolved_ty, agg_is_c_abi)
case llvmlite.LLVMType.Array(aelem_ty, _):
param_ty = llvmlite.Ptr(pool, aelem_ty)
case mlirlite.LLVMType.Array(aelem_ty, _):
param_ty = mlirlite.Ptr(pool, aelem_ty)
case _:
param_ty = resolved_ty
else:
@@ -3384,7 +3384,7 @@ def _inject_function_declare(pool: memhub.MemBuddy*,
ag.annotation,
f"extern 声明 '{fd.name}' 形参 '{pname}' 类型注解解析失败",
"NameError")
llvmlite.add_param(pool, func, param_ty, pname)
mlirlite.add_param(pool, func, param_ty, pname)
# 文本缓存校验/修复:vpi tree args 可能被覆盖损坏(尾部默认参数丢失)
# → declare 参数数不足 → 调用点缺参 → 被调函数读栈垃圾。用 vpi 文本
# 缓存的参数注解补全 declare 参数(与 define 参数数一致)。
@@ -3434,15 +3434,15 @@ def _inject_function_declare(pool: memhub.MemBuddy*,
# 注入正确签名可避免调用时 _ensure_method_declare 用实参类型创建错误 declare(如 size: sizet 被写成 i32 而非 i64)。
# ============================================================
def _inject_method_declare(pool: memhub.MemBuddy*,
mod: llvmlite.LLVMModule*,
mod: mlirlite.LLVMModule*,
m_fd: ast.FunctionDef*,
cls_name: str,
trans: HT.Translator*,
src_sha1: str,
imported_modules: str,
from_imports: str,
i32_ty: llvmlite.LLVMType*,
i8_ptr_ty: llvmlite.LLVMType*,
i32_ty: mlirlite.LLVMType*,
i8_ptr_ty: mlirlite.LLVMType*,
funcs_ptr: GenTypes.FuncEntry*,
max_funcs: int) -> None:
"""为 ClassDef 内方法创建 declare 声明并注入到模块"""
@@ -3476,7 +3476,7 @@ def _inject_method_declare(pool: memhub.MemBuddy*,
viperlib.snprintf(mangled_name, mangled_len, "%s.%s", src_sha1, lookup_name)
# 去重:如果方法已存在则跳过
existing: llvmlite.Function* = GenApi.find_func_in_module(mod, mangled_name)
existing: mlirlite.Function* = GenApi.find_func_in_module(mod, mangled_name)
if existing is not None:
return
@@ -3484,7 +3484,7 @@ def _inject_method_declare(pool: memhub.MemBuddy*,
# 优先用缓存的返回注解字符串(tree 解析后立即提取,节点未损坏),
# 用 _parse_type_string 重新解析成新 AST(立即使用不被覆盖)。
# 直接解析 m_fd.returns 可能因 vpi tree 深层节点被覆盖而得到垃圾类型。
ret_ty: llvmlite.LLVMType* = None
ret_ty: mlirlite.LLVMType* = None
ret_annot: str = _lookup_vpi_ret_annot(src_sha1, cls_name, m_fd.name)
if ret_annot is not None:
ret_ty = _resolve_vpi_ret_annot_str(pool, ret_annot, i32_ty, i8_ptr_ty)
@@ -3493,9 +3493,9 @@ def _inject_method_declare(pool: memhub.MemBuddy*,
pool, m_fd.returns, imported_modules, from_imports, trans)
# __new__ 无返回注解时推断为类指针(__new__ 返回 self 指针,默认 i32 会截断指针)
if ret_ty is None and string.strcmp(m_fd.name, "__new__") == 0:
cls_ty: llvmlite.LLVMType* = GenApi.get_struct_type(cls_name)
cls_ty: mlirlite.LLVMType* = GenApi.get_struct_type(cls_name)
if cls_ty is not None:
ret_ty = llvmlite.Ptr(pool, cls_ty)
ret_ty = mlirlite.Ptr(pool, cls_ty)
# [S4 fail-fast] 有返回注解却解析不出类型 → 不再静默退 i32;
# __new__ 无注解、普通方法无注解均走下方 i32 合法默认。
if ret_ty is None and m_fd.returns is not None:
@@ -3508,12 +3508,12 @@ def _inject_method_declare(pool: memhub.MemBuddy*,
# 退成下方 i32 默认,就会出现 declare i32 / define void 的返回类型分裂:
# 同模块内 llc 报 value doesn't match function result type,跨模块是静默 ABI 不一致。
if ret_ty is None and string.strcmp(m_fd.name, "__init__") == 0:
ret_ty = llvmlite.Void(pool)
ret_ty = mlirlite.Void(pool)
if ret_ty is None:
ret_ty = i32_ty
# 创建 declare
func: llvmlite.Function* = llvmlite.create_declare(
func: mlirlite.Function* = mlirlite.create_declare(
pool, mod, mangled_name, ret_ty)
if func is None:
return
@@ -3550,41 +3550,41 @@ def _inject_method_declare(pool: memhub.MemBuddy*,
# 块)。类类型未注册时兜底走下方注解解析/i8*(保持原行为)。
if pi == 0 and (string.strcmp(pname, "self") == 0
or string.strcmp(pname, "cls") == 0):
cls_ty_sd: llvmlite.LLVMType* = GenApi.get_struct_type(cls_name)
cls_ty_sd: mlirlite.LLVMType* = GenApi.get_struct_type(cls_name)
if cls_ty_sd is not None:
llvmlite.add_param(pool, func, llvmlite.Ptr(pool, cls_ty_sd), pname)
mlirlite.add_param(pool, func, mlirlite.Ptr(pool, cls_ty_sd), pname)
continue
param_ty: llvmlite.LLVMType* = i8_ptr_ty
param_ty: mlirlite.LLVMType* = i8_ptr_ty
# 优先用 vpi 文本注解缓存解析参数类型(与返回类型同源——vpi
# tree 深层节点 kind() 可能损坏,AST resolve 得垃圾类型如
# sizet→i32,declare 参数宽错 → 调用侧 trunc i64→i32 传参、
# callee 按 i64 读栈残留垃圾高位 → can=巨值读未写槽位崩溃,
# SlotsBugTest 根因)。段索引 = pi(0=self 空段)。
pseg_ty: llvmlite.LLVMType* = _resolve_vpi_param_annot_seg(
pseg_ty: mlirlite.LLVMType* = _resolve_vpi_param_annot_seg(
pool, src_sha1, cls_name, m_fd.name, pi, i32_ty, i8_ptr_ty)
if pseg_ty is not None:
match pseg_ty:
case llvmlite.LLVMType.Struct(_, _, _):
case mlirlite.LLVMType.Struct(_, _, _):
# 裸结构体形参:方法恒为 TPV 内部符号(mangled =
# {sha1}.{Class}.{method},无 C ABI 外部 define),
# 故 is_c_abi=0 → Ptr(struct),与定义侧
# ClassGenVTable L744-750 逐字一致(三处必须同步)。
param_ty = _AggregateParamTy(mod, pool, pseg_ty, 0)
case llvmlite.LLVMType.Array(aelem_ty, _):
param_ty = llvmlite.Ptr(pool, aelem_ty)
case mlirlite.LLVMType.Array(aelem_ty, _):
param_ty = mlirlite.Ptr(pool, aelem_ty)
case _:
param_ty = pseg_ty
elif ag.annotation is not None:
resolved_ty: llvmlite.LLVMType* = GenApi.resolve_annotation_type(
resolved_ty: mlirlite.LLVMType* = GenApi.resolve_annotation_type(
pool, ag.annotation, imported_modules, from_imports, trans)
if resolved_ty is not None:
# CArray 参数 → 元素指针 ty*(C 数组衰减,与编译侧一致)。
# 裸结构体参数 → _AggregateParamTy(同一判据,is_c_abi=0)。
match resolved_ty:
case llvmlite.LLVMType.Struct(_, _, _):
case mlirlite.LLVMType.Struct(_, _, _):
param_ty = _AggregateParamTy(mod, pool, resolved_ty, 0)
case llvmlite.LLVMType.Array(aelem_ty, _):
param_ty = llvmlite.Ptr(pool, aelem_ty)
case mlirlite.LLVMType.Array(aelem_ty, _):
param_ty = mlirlite.Ptr(pool, aelem_ty)
case _:
param_ty = resolved_ty
else:
@@ -3594,7 +3594,7 @@ def _inject_method_declare(pool: memhub.MemBuddy*,
ag.annotation,
f"extern 方法 '{cls_name}.{m_fd.name}' 形参 '{pname}' 类型注解解析失败",
"NameError")
llvmlite.add_param(pool, func, param_ty, pname)
mlirlite.add_param(pool, func, param_ty, pname)
# 文本缓存校验/修复:vpi tree args 可能被覆盖损坏(尾部默认参数丢失)
# → declare 参数数不足 → 调用点缺参 → 被调函数读栈垃圾(跨模块 CDefine
@@ -3607,11 +3607,11 @@ def _inject_method_declare(pool: memhub.MemBuddy*,
# 与 _translate_method 的 define 签名一致(对齐 TPC HandlesFunctions.py
# L703-705)。for x in obj 循环会以 2 个实参调用 __next__(self, flag)。
if m_fd.name is not None and string.strcmp(m_fd.name, "__next__") == 0:
i1_ty_si: llvmlite.LLVMType* = llvmlite.Int1(pool)
i1_ty_si: mlirlite.LLVMType* = mlirlite.Int1(pool)
if i1_ty_si is not None:
i1_ptr_ty_si: llvmlite.LLVMType* = llvmlite.Ptr(pool, i1_ty_si)
i1_ptr_ty_si: mlirlite.LLVMType* = mlirlite.Ptr(pool, i1_ty_si)
if i1_ptr_ty_si is not None:
llvmlite.add_param(pool, func, i1_ptr_ty_si, "__stop_iter_flag__")
mlirlite.add_param(pool, func, i1_ptr_ty_si, "__stop_iter_flag__")
# 默认参数:vpi 签名含 '= <default>'(Converter 已输出),提取 defaults
# 列表注册默认参数表——跨模块缺参调用(如 resolve_annotation_type 的
# depth=0)才能按表填充,否则被调函数读到栈垃圾(假报递归过深/崩溃)。
@@ -3686,7 +3686,7 @@ def _register_ctypedef_from_annassign(pool: memhub.MemBuddy*,
# (静默读错字段)。
#
# 布局真源 = .stub.ll(批处理落盘点:Phase1Main.vp:1078 / Phase2/__init__.vp:1050
# 用 tr.dump_ir(..., llvmlite.OUTPUT_STUB)):
# 用 tr.dump_ir(..., mlirlite.OUTPUT_STUB)):
# - `%"<sha1>.<Class>" = type { ... }` 是**展平后**的完整布局(ClassGenDef 的
# 字段展平:__vtable__ 首字段 + 父类字段 + 本类字段);
# - `@...<sha1>.<Class>.vtable` 全局的类型槽数 = 该类的虚方法数
@@ -4110,7 +4110,7 @@ def _repl_stub_warn_parent(e: rawptr[ReplStubClass], detail: str, pname: str) ->
"被拒绝(方法调用不受影响)\n", e.Sha1, e.ClassName, detail, pname)
def _repl_stub_try(e: rawptr[ReplStubClass], mod: llvmlite.LLVMModule*) -> int:
def _repl_stub_try(e: rawptr[ReplStubClass], mod: mlirlite.LLVMModule*) -> int:
"""按存根校验并登记完整布局:1=已登记 / 0=父类未就绪(推迟)/ -1=拒绝"""
global ReplStubOk, ReplStubVtOk, ReplStubWarnLeft
if e is None:
@@ -4244,35 +4244,35 @@ def _repl_stub_try(e: rawptr[ReplStubClass], mod: llvmlite.LLVMModule*) -> int:
e.Sha1, e.ClassName, vn, e.VtArity)
# ⑥ 建 LLVM 结构体(命名 "%<sha1>.<类名>",与定义侧同口径)
total: int = cn + hv
i8_ptr: llvmlite.LLVMType* = llvmlite.Ptr(pool, llvmlite.Int8(pool))
i8_ptr: mlirlite.LLVMType* = mlirlite.Ptr(pool, mlirlite.Int8(pool))
if i8_ptr is None:
return 0
first_node: rawptr[llvmlite.ParamNode] = None
prev_node: rawptr[llvmlite.ParamNode] = None
first_node: rawptr[mlirlite.ParamNode] = None
prev_node: rawptr[mlirlite.ParamNode] = None
if hv == 1:
nd0: rawptr[llvmlite.ParamNode] = pool.alloc(llvmlite.ParamNode.__sizeof__())
nd0: rawptr[mlirlite.ParamNode] = pool.alloc(mlirlite.ParamNode.__sizeof__())
if nd0 is None:
return 0
string.memset(nd0, 0, llvmlite.ParamNode.__sizeof__())
string.memset(nd0, 0, mlirlite.ParamNode.__sizeof__())
nd0.Ty = i8_ptr
first_node = nd0
prev_node = nd0
fi2: int
for fi2 in range(cn):
fty: llvmlite.LLVMType* = (llvmlite.LLVMType*)(e.Types[fi2])
fty: mlirlite.LLVMType* = (mlirlite.LLVMType*)(e.Types[fi2])
if fty is None:
continue
nd: rawptr[llvmlite.ParamNode] = pool.alloc(llvmlite.ParamNode.__sizeof__())
nd: rawptr[mlirlite.ParamNode] = pool.alloc(mlirlite.ParamNode.__sizeof__())
if nd is None:
continue
string.memset(nd, 0, llvmlite.ParamNode.__sizeof__())
string.memset(nd, 0, mlirlite.ParamNode.__sizeof__())
nd.Ty = fty
if first_node is None:
first_node = nd
if prev_node is not None:
prev_node.Next = nd
prev_node = nd
struct_ty: llvmlite.LLVMType* = llvmlite.Struct(pool, first_node, total, e.Key)
struct_ty: mlirlite.LLVMType* = mlirlite.Struct(pool, first_node, total, e.Key)
if struct_ty is None:
return 0
# ⑦ 登记(StdlibAlloc=1 期间的注册走 PermPool,跨片段存活)
@@ -4282,18 +4282,18 @@ def _repl_stub_try(e: rawptr[ReplStubClass], mod: llvmlite.LLVMModule*) -> int:
e.State = _REPL_SS_REFUSED
return -1
if mod is not None:
llvmlite.module_add_named_type(mod, pool, struct_ty)
mlirlite.module_add_named_type(mod, pool, struct_ty)
if (e.Flags & _REPL_SF_PACKED) != 0:
entry.IsPacked = 1
if mod is not None:
llvmlite.module_set_named_type_packed(mod, pool, struct_ty, 1)
mlirlite.module_set_named_type_packed(mod, pool, struct_ty, 1)
if hv == 1:
entry.HasVTable = 1
GenApi.add_field(pool, entry, "__vtable__", i8_ptr)
fi3: int
for fi3 in range(cn):
fname: str = rawptr(e.Names[fi3])
fty3: llvmlite.LLVMType* = (llvmlite.LLVMType*)(e.Types[fi3])
fty3: mlirlite.LLVMType* = (mlirlite.LLVMType*)(e.Types[fi3])
if fname is None or fty3 is None:
continue
GenApi.add_field(pool, entry, fname, fty3)
@@ -4327,7 +4327,7 @@ def _repl_stub_try(e: rawptr[ReplStubClass], mod: llvmlite.LLVMModule*) -> int:
def _repl_stub_add_class(pool: memhub.MemBuddy*,
mod: llvmlite.LLVMModule*,
mod: mlirlite.LLVMModule*,
cd: ast.ClassDef*,
sha1: str,
txt: str,
@@ -4425,7 +4425,7 @@ def _repl_stub_add_class(pool: memhub.MemBuddy*,
tg: ast.Name* = ast.Name*(aa2.target)
if tg.id is None or tg.id[0] == '\0':
continue
fty2: llvmlite.LLVMType* = GenApi.resolve_annotation_type(
fty2: mlirlite.LLVMType* = GenApi.resolve_annotation_type(
pool, aa2.annotation, imported_modules, from_imports, trans, 0)
if fty2 is None:
own_fail = 1
@@ -4501,7 +4501,7 @@ def _repl_stub_add_class(pool: memhub.MemBuddy*,
def _repl_stub_collect_module(pool: memhub.MemBuddy*,
mod: llvmlite.LLVMModule*,
mod: mlirlite.LLVMModule*,
ch: list[ast.AST*]*,
n: sizet,
trans: HT.Translator*,
+2 -2
View File
@@ -4,7 +4,7 @@ from stdint import *
import memhub
import string
import stdlib
import llvmlite
import mlirlite
import w32.win32file as win32file
import w32.win32base as win32base
import w32.fileio as fileio
@@ -614,7 +614,7 @@ def LoadFullIR(temp_dir: str, sha1: str,
# Returns: 成功加载的 .vpi 文件数
# ============================================================
def LoadDepVpiIntoModule(pool: memhub.MemBuddy*,
mod: llvmlite.LLVMModule*,
mod: mlirlite.LLVMModule*,
imported_modules: str,
from_imports: str,
temp_dir: str,
+1 -1
View File
@@ -3,7 +3,7 @@ from stdint import *
import memhub
import string
import stdlib
import llvmlite
import mlirlite
import w32.win32file as win32file
import w32.win32base as win32base
import w32.fileio as fileio
+11 -16
View File
@@ -4,7 +4,7 @@ from stdint import *
import memhub
import string
import stdlib
import llvmlite
import mlirlite
import w32.win32file as win32file
import w32.win32base as win32base
import w32.fileio as fileio
@@ -47,7 +47,7 @@ import lib.Stub.StubMerger as StubMerger
# Args: mod 已翻译完成的 LLVM 模块;temp_dir 基础目录;td_len temp_dir 长度;sha1 模块 SHA1
# Returns: 0=成功(失败经 VLogger.error 终止进程)
# ============================================================
def WriteModuleMeta(mod: llvmlite.LLVMModule*, temp_dir: str,
def WriteModuleMeta(mod: mlirlite.LLVMModule*, temp_dir: str,
td_len: sizet, sha1: str) -> int:
"""把本模块的函数定义/结构体布局/虚表清单写入 {sha1}.meta"""
if mod is None or temp_dir is None or sha1 is None:
@@ -61,14 +61,14 @@ def WriteModuleMeta(mod: llvmlite.LLVMModule*, temp_dir: str,
if mf.closed:
VLogger.error(f"meta 写出:无法打开 {mpath}", "Meta")
return 1
cur: llvmlite.Function* = mod.FuncHead
cur: mlirlite.Function* = mod.FuncHead
steps: sizet = 0
while cur is not None:
steps += 1
if steps > 100000:
VLogger.error("meta 写出:函数链表成环/超限", "Meta")
break
nm: str = llvmlite.function_get_name(cur)
nm: str = mlirlite.function_get_name(cur)
if nm is not None:
nlen: sizet = string.strlen(nm)
line: bytes = stdlib.malloc(nlen + 16)
@@ -76,28 +76,28 @@ def WriteModuleMeta(mod: llvmlite.LLVMModule*, temp_dir: str,
VLogger.error("meta 写出:行缓冲分配失败", "Meta")
break
mark: str = "DECL"
if llvmlite.function_is_declared(cur) == 0:
if mlirlite.function_is_declared(cur) == 0:
mark = "DEF"
viperlib.snprintf(line, nlen + 16, "FUNC %s %s\n", nm, mark)
mf.write(line, string.strlen(line))
stdlib.free(line)
cur = llvmlite.function_get_next(cur)
cur = mlirlite.function_get_next(cur)
# 2) 结构体布局:STRUCT <name> FIELDS <n> PACKED <0|1>(opaque → STRUCT <name> OPAQUE)
nt: llvmlite.NamedTypeNode* = mod.NamedTypeHead
nt: mlirlite.NamedTypeNode* = mod.NamedTypeHead
nt_steps: sizet = 0
while nt is not None:
nt_steps += 1
if nt_steps > 100000:
VLogger.error("meta 写出:命名类型链表成环/超限", "Meta")
break
tn: str = llvmlite.get_struct_name(nt.Ty)
tn: str = mlirlite.get_struct_name(nt.Ty)
if tn is not None and tn[0] != '\0':
tl: sizet = string.strlen(tn)
lb: bytes = stdlib.malloc(tl + 48)
if lb is None:
VLogger.error("meta 写出:行缓冲分配失败", "Meta")
break
fc: int = llvmlite.get_struct_fcount(nt.Ty)
fc: int = mlirlite.get_struct_fcount(nt.Ty)
if fc < 0:
viperlib.snprintf(lb, tl + 48, "STRUCT %s OPAQUE\n", tn)
else:
@@ -106,7 +106,7 @@ def WriteModuleMeta(mod: llvmlite.LLVMModule*, temp_dir: str,
stdlib.free(lb)
nt = nt.Next
# 3) 虚表槽数:VTABLE <class> SLOTS <n>(全局名 <class>.vtable,Ty 匿名结构体 fcount=槽数)
gv: llvmlite.GlobalVariable* = mod.GlobalHead
gv: mlirlite.GlobalVariable* = mod.GlobalHead
gv_steps: sizet = 0
while gv is not None:
gv_steps += 1
@@ -122,7 +122,7 @@ def WriteModuleMeta(mod: llvmlite.LLVMModule*, temp_dir: str,
if base is not None:
string.strncpy(base, gn, base_len)
base[base_len] = '\0'
ar: int = llvmlite.get_struct_fcount(gv.Ty)
ar: int = mlirlite.get_struct_fcount(gv.Ty)
if ar < 0:
ar = 0
lb2: bytes = stdlib.malloc(base_len + 40)
@@ -274,11 +274,6 @@ def _FindSha1ByModName(sha1_arr: str, mod_arr: str,
return None
if count <= 0:
return None
# MLIR 后端:依赖名 "llvmlite" 重定向到 "mlirlite"
#(与 IncludesScanner.ResolveModuleToPath 同口径;LLVM 后端恒等)
mod_name = Config.alias_module_name(mod_name)
if mod_name is None:
return None
# 第一遍:精确匹配
for i in range(count):
idx: sizet = sizet(i) * 64
+1 -1
View File
@@ -3,7 +3,7 @@ from stdint import *
import memhub
import string
import stdlib
import llvmlite
import mlirlite
import w32.win32file as win32file
import w32.win32base as win32base
import w32.fileio as fileio
+1 -1
View File
@@ -3,7 +3,7 @@ from stdint import *
import memhub
import string
import stdlib
import llvmlite
import mlirlite
import w32.win32file as win32file
import w32.win32base as win32base
import w32.fileio as fileio
+1 -1
View File
@@ -3,7 +3,7 @@ from stdint import *
import memhub
import string
import stdlib
import llvmlite
import mlirlite
import w32.win32file as win32file
import w32.win32base as win32base
import w32.fileio as fileio