diff --git a/App/lib/Phase/BuildPipeline.vp b/App/lib/Phase/BuildPipeline.vp index 8dd3b18..29a4162 100644 --- a/App/lib/Phase/BuildPipeline.vp +++ b/App/lib/Phase/BuildPipeline.vp @@ -34,7 +34,7 @@ import lib.Stub.StubMerger.StubMergerCollect as StubMergerCollect # ============================================================ # 全局 mbuddy 指针 -_mbuddy: memhub.MemBuddy | t.CPtr +_mbuddy: rowptr[memhub.MemBuddy] # ASan 模式(--asan):对 .ll 先 opt -passes=asan 插桩;ASan 运行库由 # project.vpj 的 linker.static_libs / dynamic_libs 显式声明(TPV 不注入) @@ -71,7 +71,7 @@ PYI_BUF_SIZE: sizet = 262144 # Returns: # Translator 对象(None 失败) # ============================================================ -def TranslateFileGetTrans(mb: memhub.MemBuddy | t.CPtr, file_path: str, +def TranslateFileGetTrans(mb: rowptr[memhub.MemBuddy], file_path: str, sha1_val: str, current_package: str = None, declare_only: int = 0, diff --git a/App/lib/Phase/Phase1/Phase1Main.vp b/App/lib/Phase/Phase1/Phase1Main.vp index 5c603f3..2d11d22 100644 --- a/App/lib/Phase/Phase1/Phase1Main.vp +++ b/App/lib/Phase/Phase1/Phase1Main.vp @@ -243,7 +243,7 @@ def _BreakContainerCyclesInDeps(temp_dir: str) -> int: # Returns: # ScanResult 指针(stdlib 分配,调用方负责释放);失败返回 None # ============================================================ -def _BuildReachableResult(mb: memhub.MemBuddy | t.CPtr, +def _BuildReachableResult(mb: rowptr[memhub.MemBuddy], includes_dir: str) -> IncludesScanner.ScanResult | t.CPtr: """从 Sha1Store(仅可达 includes + App)构建可达 FileEntry 列表""" if mb is None: @@ -335,7 +335,7 @@ def _BuildReachableResult(mb: memhub.MemBuddy | t.CPtr, # Returns: # 0 成功,非 0 失败 # ============================================================ -def RunPhase1(mb: memhub.MemBuddy | t.CPtr, includes_dir: str, temp_dir: str, +def RunPhase1(mb: rowptr[memhub.MemBuddy], includes_dir: str, temp_dir: str, log: VLogger.Logger | t.CPtr) -> int: """Phase1: 扫描 includes 目录,按需翻译并生成 stub""" if includes_dir is None or temp_dir is None: diff --git a/App/lib/Phase/Phase1/Phase1Scan.vp b/App/lib/Phase/Phase1/Phase1Scan.vp index 8fc42dc..38e1785 100644 --- a/App/lib/Phase/Phase1/Phase1Scan.vp +++ b/App/lib/Phase/Phase1/Phase1Scan.vp @@ -65,7 +65,7 @@ import lib.core.Gen.GenApi as GenApi # Returns: # 收集到的类数量,-1 失败 # ============================================================ -def _ScanClassInheritance(mb: memhub.MemBuddy | t.CPtr, +def _ScanClassInheritance(mb: rowptr[memhub.MemBuddy], result: IncludesScanner.ScanResult | t.CPtr, reachable_set: str, reachable_count: int, use_reachable: int, @@ -276,12 +276,12 @@ def _BufHasGenericClassMarker(buf: bytes, blen: sizet) -> int: # 解析 → 模板节点与表直接进 perm_pool,跨 mark 永久存活、不占主 pool。 # 重复注册由 _register_generic_template 内部查重跳过。 # ============================================================ -def _PreRegisterAllGenericTemplates(mb: memhub.MemBuddy | t.CPtr, +def _PreRegisterAllGenericTemplates(mb: rowptr[memhub.MemBuddy], result: IncludesScanner.ScanResult | t.CPtr) -> int: """预注册全部 includes 文件的泛型类模板,返回处理到的泛型类数量""" if result is None or mb is None: return 0 - perm: memhub.MemBuddy | t.CPtr = CompilerFactory.factory.PermPool + perm: rowptr[memhub.MemBuddy] = CompilerFactory.factory.PermPool if perm is None: return 0 p1e_size: sizet = IncludesScanner.FileEntry.__sizeof__() diff --git a/App/lib/Phase/Phase1/Phase1Topo.vp b/App/lib/Phase/Phase1/Phase1Topo.vp index e7e6c21..3cf7004 100644 --- a/App/lib/Phase/Phase1/Phase1Topo.vp +++ b/App/lib/Phase/Phase1/Phase1Topo.vp @@ -65,7 +65,7 @@ import lib.Phase.Phase1 as Phase1 # Returns: # 0 成功,-1 失败 # ============================================================ -def _TopoSortFiles(mb: memhub.MemBuddy | t.CPtr, +def _TopoSortFiles(mb: rowptr[memhub.MemBuddy], result: IncludesScanner.ScanResult | t.CPtr, reachable_set: str, reachable_count: int, use_reachable: int, diff --git a/App/lib/Phase/Phase1/__init__.vp b/App/lib/Phase/Phase1/__init__.vp index e96f851..cf559b9 100644 --- a/App/lib/Phase/Phase1/__init__.vp +++ b/App/lib/Phase/Phase1/__init__.vp @@ -3,7 +3,7 @@ from stdint import * import memhub # 全局 mbuddy 指针 -_mbuddy: memhub.MemBuddy | t.CPtr +_mbuddy: rowptr[memhub.MemBuddy] # 源代码缓冲区大小(1MB) SRC_BUF_SIZE: t.CDefine = 1048576 diff --git a/App/lib/Phase/Phase2/__init__.vp b/App/lib/Phase/Phase2/__init__.vp index 5b5a3cb..6f79f85 100644 --- a/App/lib/Phase/Phase2/__init__.vp +++ b/App/lib/Phase/Phase2/__init__.vp @@ -30,7 +30,7 @@ import lib.Stub.StubMerger.StubMergerTopo as StubMergerTopo import lib.Stub.StubGen.Converter as StubConverter # 全局 mbuddy 指针 -_mbuddy: memhub.MemBuddy | t.CPtr +_mbuddy: rowptr[memhub.MemBuddy] # 源代码缓冲区大小(1MB) SRC_BUF_SIZE: t.CDefine = 1048576 @@ -64,7 +64,7 @@ class SrcFileEntry: # Returns: # 新的 file_count # ============================================================ -def _ScanDirForPyFiles(mb: memhub.MemBuddy | t.CPtr, +def _ScanDirForPyFiles(mb: rowptr[memhub.MemBuddy], dir_path: str, entries: SrcFileEntry | t.CPtr, entry_size: sizet, @@ -172,7 +172,7 @@ def _ScanDirForPyFiles(mb: memhub.MemBuddy | t.CPtr, # Kernel/intr/isr.s 定义 isr0/syscall_entry/_per_cpu 等符号)。 # TPV 不对 .s 翻译,直接用 llvm-mc 汇编为 .obj 参与链接。 # ============================================================ -def _ScanDirForAsmFiles(mb: memhub.MemBuddy | t.CPtr, +def _ScanDirForAsmFiles(mb: rowptr[memhub.MemBuddy], dir_path: str, entries: SrcFileEntry | t.CPtr, entry_size: sizet, @@ -274,7 +274,7 @@ def _ScanDirForAsmFiles(mb: memhub.MemBuddy | t.CPtr, # 节点 → 后续查重/特化遍历悬空内存崩溃。App 文件数量少,mark2 前预注册 # 产生的 AST 驻留内存可忽略。重复注册由 _register_generic_template 查重跳过。 # ============================================================ -def _PreRegisterAppGenericTemplates(mb: memhub.MemBuddy | t.CPtr, +def _PreRegisterAppGenericTemplates(mb: rowptr[memhub.MemBuddy], entries: SrcFileEntry | t.CPtr, file_count: int, entry_size: sizet) -> int: @@ -308,7 +308,7 @@ def _PreRegisterAppGenericTemplates(mb: memhub.MemBuddy | t.CPtr, if bytes_read_pa < SRC_BUF_SIZE: src_buf_pa[bytes_read_pa] = 0 # 解析 AST(只解析,不完整翻译;用永久池使模板节点跨 mark2 reset 存活) - perm_pa: memhub.MemBuddy | t.CPtr = CompilerFactory.factory.PermPool + perm_pa: rowptr[memhub.MemBuddy] = CompilerFactory.factory.PermPool if perm_pa is None: perm_pa = mb lx_pa: ast.Lexer | t.CPtr = ast.new_lexer(perm_pa) @@ -756,7 +756,7 @@ def _PhaseADumpFailGraph(temp_dir: str, td_len: sizet, path: str, sha1: str) -> stdio.fflush(None) -def RunMultiFileProject(mb: memhub.MemBuddy | t.CPtr, +def RunMultiFileProject(mb: rowptr[memhub.MemBuddy], source_dir: str, temp_dir: str, output_dir: str, cc_cmd: str, cc_flags: str, linker_cmd: str, linker_flags: str, linker_output: str, diff --git a/App/lib/Projectrans/Utils.vp b/App/lib/Projectrans/Utils.vp index 1f280f2..3334813 100644 --- a/App/lib/Projectrans/Utils.vp +++ b/App/lib/Projectrans/Utils.vp @@ -17,7 +17,7 @@ import w32.fileio as fileio # ============================================================ # 全局 mbuddy 指针 -_mbuddy: memhub.MemBuddy | t.CPtr +_mbuddy: rowptr[memhub.MemBuddy] # ============================================================ @@ -33,7 +33,7 @@ def nibble_to_hex_char(n: int, uppercase: int) -> char: # ============================================================ # bytes_to_hex - 字节序列转十六进制字符串 # ============================================================ -def bytes_to_hex(pool: memhub.MemBuddy | t.CPtr, +def bytes_to_hex(pool: rowptr[memhub.MemBuddy], digest: bytes, nbytes: sizet, uppercase: int, @@ -68,7 +68,7 @@ def bytes_to_hex(pool: memhub.MemBuddy | t.CPtr, # 使用 includes/hashlib 库的 sha1 类计算摘要,转为十六进制字符串。 # 参考 Projectrans.py 的 compute_sha1(hashlib.sha1().hexdigest()[:16])。 # ============================================================ -def compute_sha1(pool: memhub.MemBuddy | t.CPtr, content: str) -> str: +def compute_sha1(pool: rowptr[memhub.MemBuddy], content: str) -> str: """计算字符串的 SHA1,返回前 16 个十六进制字符(用于文件命名)""" if content is None or pool is None: return None diff --git a/App/lib/Stub/StubGen/Converter.vp b/App/lib/Stub/StubGen/Converter.vp index b50dbbc..a8d5044 100644 --- a/App/lib/Stub/StubGen/Converter.vp +++ b/App/lib/Stub/StubGen/Converter.vp @@ -716,7 +716,7 @@ def _PyiClass(buf: bytes, buf_size: sizet, pos: sizet, # Returns: # 写入的字节数(0 表示失败) # ============================================================ -def _GeneratePyiFromAst(mb: memhub.MemBuddy | t.CPtr, tree: ast.AST | t.CPtr, +def _GeneratePyiFromAst(mb: rowptr[memhub.MemBuddy], tree: ast.AST | t.CPtr, rel_path: str, buf: bytes, buf_size: sizet) -> sizet: """从 AST 生成 .vpi 存根文件内容到 buf""" diff --git a/App/lib/Stub/StubGen/VpiReader.vp b/App/lib/Stub/StubGen/VpiReader.vp index 6c0369a..0be6672 100644 --- a/App/lib/Stub/StubGen/VpiReader.vp +++ b/App/lib/Stub/StubGen/VpiReader.vp @@ -470,7 +470,7 @@ def _lookup_vpi_param_annots(src_sha1: str, cls_name: str, method_name: str) -> # 对应缓存段 p(含首参空串占位)。补全后 declare 参数数与 define 一致, # 调用点默认参数填充才能生效,避免被调函数读栈垃圾。 # ============================================================ -def _repair_declare_params_from_text(pool: memhub.MemBuddy | t.CPtr, +def _repair_declare_params_from_text(pool: rowptr[memhub.MemBuddy], func: llvmlite.Function | t.CPtr, src_sha1: str, cls_name: str, @@ -532,7 +532,7 @@ def _repair_declare_params_from_text(pool: memhub.MemBuddy | t.CPtr, # 此处与返回类型同源:从 @-joined 注解串取第 seg_idx 段(0=self 空段), # 用 _resolve_vpi_ret_annot_str 字符串解析。空段/未命中返回 None(走 AST 兜底)。 # ============================================================ -def _resolve_vpi_param_annot_seg(pool: memhub.MemBuddy | t.CPtr, +def _resolve_vpi_param_annot_seg(pool: rowptr[memhub.MemBuddy], src_sha1: str, cls_name: str, method_name: str, @@ -862,7 +862,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 | t.CPtr, +def _resolve_single_vpi_type_str(pool: rowptr[memhub.MemBuddy], seg: str) -> llvmlite.LLVMType | t.CPtr: """解析单个类型段为 LLVMType,无法识别返回 None""" if seg is None or pool is None: @@ -960,9 +960,9 @@ def _resolve_single_vpi_type_str(pool: memhub.MemBuddy | t.CPtr, # 支持: "str"/"bytes" → i8*; "int" → i32; "bool" → i1; # "char" 等 → map_t_type 映射; # "X | t.CPtr" → Ptr(Struct X); "t.CPtr" → i8*; -# "memhub.MemBuddy | t.CPtr" → Ptr(Struct MemBuddy)。 +# "rowptr[memhub.MemBuddy]" → Ptr(Struct MemBuddy)。 # ============================================================ -def _resolve_vpi_ret_annot_str(pool: memhub.MemBuddy | t.CPtr, +def _resolve_vpi_ret_annot_str(pool: rowptr[memhub.MemBuddy], ret_annot: str, i32_ty: llvmlite.LLVMType | t.CPtr, i8_ptr_ty: llvmlite.LLVMType | t.CPtr) -> llvmlite.LLVMType | t.CPtr: @@ -1161,7 +1161,7 @@ def _extract_sha1_from_path(vpi_path: str) -> str: # 与 HandlesImports.add_imported_module 逻辑一致,但内联在本模块, # 避免 VpiReader → HandlesImports → StubMerger → VpiReader 循环依赖。 # ============================================================ -def _stub_add_imported(pool: memhub.MemBuddy | t.CPtr, +def _stub_add_imported(pool: rowptr[memhub.MemBuddy], cur: str, name: str) -> str: """追加模块名到空格分隔列表(pool 分配),返回新列表""" if name is None: @@ -1185,18 +1185,37 @@ def _stub_add_imported(pool: memhub.MemBuddy | t.CPtr, # ============================================================ # _stub_add_from - 追加 from-import 映射("local:mod[:orig]" 空格分隔) # ============================================================ -def _stub_add_from(pool: memhub.MemBuddy | t.CPtr, +def _stub_add_from(pool: rowptr[memhub.MemBuddy], cur: str, local: str, mod: str, orig: str) -> str: - """追加 from-import 映射(pool 分配),返回新列表""" + """追加 from-import 映射(pool 分配),返回新列表 + + [D7·截断纪律] 旧实现固定 256 缓冲 + `snprintf("%s:%s[:%s]")`:三者合计超长即被 + **静默截断**,该条目在 ImportsGen 侧仍被当作合法条目解析出**错误的 + local/mod/orig** ⇒ 跨模块类名/别名还原取到错名字(D16 之后即污染 + Spec.SourceName 的来源名)。改为按精确长度分配,不存在上限。 + """ if local is None or mod is None: return cur - entry: str = pool.alloc(256) + llen: sizet = string.strlen(local) + mlen: sizet = string.strlen(mod) + use_orig: int = 0 + olen: sizet = 0 + if orig is not None and string.strcmp(orig, local) != 0: + use_orig = 1 + olen = string.strlen(orig) + # local ':' mod [':' orig] '\0' + need: sizet = llen + 1 + mlen + 1 + if use_orig != 0: + need += 1 + olen + entry: str = pool.alloc(need) if entry is None: return cur - if orig is not None and string.strcmp(orig, local) != 0: - viperlib.snprintf(entry, 256, "%s:%s:%s", local, mod, orig) - else: - viperlib.snprintf(entry, 256, "%s:%s", local, mod) + string.strcpy(entry, local) + entry[llen] = ':' + string.strcpy(entry + llen + 1, mod) + if use_orig != 0: + entry[llen + 1 + mlen] = ':' + string.strcpy(entry + llen + 1 + mlen + 1, orig) if cur is None: return entry old_len: sizet = string.strlen(cur) @@ -1267,7 +1286,7 @@ def _vpi_typedef_visited_mark(sha1: str) -> None: _g_vpi_typedef_visited_count += 1 -def _vpi_register_typedef_closure(pool: memhub.MemBuddy | t.CPtr, +def _vpi_register_typedef_closure(pool: rowptr[memhub.MemBuddy], import_mods: str, temp_dir: str, depth: int) -> int: @@ -1347,8 +1366,34 @@ def _vpi_register_typedef_closure(pool: memhub.MemBuddy | t.CPtr, if tree_r is not None and tree_r.children is not None: ch_r: list[ast.AST | t.CPtr] | t.CPtr = tree_r.children cn_r: sizet = len(ch_r) - # 第一遍:收集子模块 imports(递归闭包) - sub_imports: bytes = stdlib.malloc(4096) + # 收集子模块 imports(递归闭包) + # [D7·截断纪律] 旧实现固定 4096 缓冲 + `sub_len + len + 2 < 4096` + # 守卫:装不下就**静默丢弃**该 import ⇒ 递归 typedef 预注册闭包 + # 缺模块 ⇒ 该模块的 CTypedef/CDefine 不可见 ⇒ 注解解析退化 + # (同一「定长缓冲静默截断」族)。改为**两遍**:先累计所需长度, + # 再按精确长度分配后填充——不存在长度上限,故无需丢弃。 + # 计数阶段每项多算 1 字节分隔符(首项不用),偏保守,无害。 + sub_need: sizet = 1 # 末尾 NUL + ci_c: sizet + for ci_c in range(cn_r): + child_c: ast.AST | t.CPtr = ch_r.get(ci_c) + if child_c is None: + continue + kk_c: int = child_c.kind() + if kk_c == ast.ASTKind.Import: + imp_c: ast.Import | t.CPtr = (ast.Import | t.CPtr)(child_c) + if imp_c.names is not None: + in_nc: sizet = len(imp_c.names) + ii_c: sizet + for ii_c in range(in_nc): + al_c: ast.Alias | t.CPtr = (ast.Alias | t.CPtr)(imp_c.names.get(ii_c)) + if al_c is not None and al_c.name is not None: + sub_need += string.strlen(al_c.name) + 1 + elif kk_c == ast.ASTKind.ImportFrom: + ifr_c: ast.ImportFrom | t.CPtr = (ast.ImportFrom | t.CPtr)(child_c) + if ifr_c.module is not None: + sub_need += string.strlen(ifr_c.module) + 1 + sub_imports: bytes = stdlib.malloc(sub_need) if sub_imports is not None: sub_imports[0] = '\0' sub_len: sizet = 0 @@ -1367,24 +1412,22 @@ def _vpi_register_typedef_closure(pool: memhub.MemBuddy | t.CPtr, al_r: ast.Alias | t.CPtr = (ast.Alias | t.CPtr)(imp_r.names.get(ii_r)) if al_r is not None and al_r.name is not None: il_r: sizet = string.strlen(al_r.name) - if sub_len + il_r + 2 < 4096: - if sub_len > 0: - sub_imports[sub_len] = ' ' - sub_len += 1 - string.strcpy(sub_imports + sub_len, al_r.name) - sub_len += il_r - sub_imports[sub_len] = '\0' + if sub_len > 0: + sub_imports[sub_len] = ' ' + sub_len += 1 + string.strcpy(sub_imports + sub_len, al_r.name) + sub_len += il_r + sub_imports[sub_len] = '\0' elif kk_r == ast.ASTKind.ImportFrom: ifr_r: ast.ImportFrom | t.CPtr = (ast.ImportFrom | t.CPtr)(child_r) if ifr_r.module is not None: ml_r: sizet = string.strlen(ifr_r.module) - if sub_len + ml_r + 2 < 4096: - if sub_len > 0: - sub_imports[sub_len] = ' ' - sub_len += 1 - string.strcpy(sub_imports + sub_len, ifr_r.module) - sub_len += ml_r - sub_imports[sub_len] = '\0' + if sub_len > 0: + sub_imports[sub_len] = ' ' + sub_len += 1 + string.strcpy(sub_imports + sub_len, ifr_r.module) + sub_len += ml_r + sub_imports[sub_len] = '\0' # 第二遍:注册本模块 AnnAssign 的 CTypedef/CDefine ci2_r: sizet for ci2_r in range(cn_r): @@ -1442,7 +1485,7 @@ def _vpi_register_typedef_closure(pool: memhub.MemBuddy | t.CPtr, # Returns: # 1=成功,0=失败 # ============================================================ -def ParseVpiIntoModule(pool: memhub.MemBuddy | t.CPtr, +def ParseVpiIntoModule(pool: rowptr[memhub.MemBuddy], mod: llvmlite.LLVMModule | t.CPtr, vpi_path: str, trans: HT.Translator | t.CPtr) -> int: @@ -1461,7 +1504,7 @@ def ParseVpiIntoModule(pool: memhub.MemBuddy | t.CPtr, return ret -def _ParseVpiIntoModuleImpl(pool: memhub.MemBuddy | t.CPtr, +def _ParseVpiIntoModuleImpl(pool: rowptr[memhub.MemBuddy], mod: llvmlite.LLVMModule | t.CPtr, vpi_path: str, trans: HT.Translator | t.CPtr) -> int: @@ -1790,7 +1833,7 @@ def _ParseVpiIntoModuleImpl(pool: memhub.MemBuddy | t.CPtr, # sub_sha1: 子模块(定义文件)sha1 # pkg_sha1: 当前包 __init__ 的 sha1 # ============================================================ -def _inject_reexport_class_declare(pool: memhub.MemBuddy | t.CPtr, +def _inject_reexport_class_declare(pool: rowptr[memhub.MemBuddy], mod: llvmlite.LLVMModule | t.CPtr, src_name: str, local_name: str, @@ -1889,7 +1932,7 @@ def _vpi_class_has_packed(decorator_list: list[ast.AST | t.CPtr] | t.CPtr) -> in # 字段解析失败不 fatal(不注册该类,留给源模块编译注册;若 vpi 内后续 # 裸类名引用它则由调用侧 fail-fast 暴露)。 # ============================================================ -def _inject_class_struct_declare(pool: memhub.MemBuddy | t.CPtr, +def _inject_class_struct_declare(pool: rowptr[memhub.MemBuddy], mod: llvmlite.LLVMModule | t.CPtr, class_cd: ast.ClassDef | t.CPtr, cls_name: str, @@ -1968,9 +2011,17 @@ def _inject_class_struct_declare(pool: memhub.MemBuddy | t.CPtr, # 4. 命名结构体类型名 "sha1.ClassName"(与定义侧 ClassGenDef 一致) type_name_c: str = cls_name if src_sha1 is not None and src_sha1[0] != '\0': - name_buf_c: str = pool.alloc(64) + # [D7·截断纪律] 旧实现固定 64 缓冲 + snprintf("%s.%s"):sha1(16)+'.' 占 17 + # 字节,类名超过 46 字符即被**静默截断** ⇒ 命名结构体名与定义侧 + # ClassGenDef 的 "sha1.ClassName" 不一致 → find_struct_by_module / + # lookup_field_by_class 查不到(误判"未注册")。改为精确长度分配。 + sh_len_c: sizet = string.strlen(src_sha1) + cn_len_c: sizet = string.strlen(cls_name) + name_buf_c: str = pool.alloc(sh_len_c + 1 + cn_len_c + 1) if name_buf_c is not None: - viperlib.snprintf(name_buf_c, 64, "%s.%s", src_sha1, cls_name) + string.strcpy(name_buf_c, src_sha1) + name_buf_c[sh_len_c] = '.' + string.strcpy(name_buf_c + sh_len_c + 1, cls_name) type_name_c = name_buf_c struct_ty_c: llvmlite.LLVMType | t.CPtr = llvmlite.Struct( pool, first_node_c, field_count, type_name_c) @@ -2027,7 +2078,7 @@ def _inject_class_struct_declare(pool: memhub.MemBuddy | t.CPtr, # 分支添加 opaque 即可。 # ============================================================ def _ensure_full_value_types(mod: llvmlite.LLVMModule | t.CPtr, - pool: memhub.MemBuddy | t.CPtr, + pool: rowptr[memhub.MemBuddy], ty: llvmlite.LLVMType | t.CPtr) -> None: """递归为值 struct / 数组元素 struct 注册完整定义(递归深度守卫)""" if mod is None or pool is None or ty is None: @@ -2058,7 +2109,7 @@ def _ensure_full_value_types(mod: llvmlite.LLVMModule | t.CPtr, # 跨模块 from-import 读取全局变量时 find_global_in_module 找不到 → # "跨模块全局变量类型未知(stub 未注入)" 误杀(lexer.vp 读 tokens._op_head)。 # ============================================================ -def _inject_global_variable_declare(pool: memhub.MemBuddy | t.CPtr, +def _inject_global_variable_declare(pool: rowptr[memhub.MemBuddy], mod: llvmlite.LLVMModule | t.CPtr, aa: ast.AnnAssign | t.CPtr, trans: HT.Translator | t.CPtr, @@ -2160,7 +2211,7 @@ def _inject_global_variable_declare(pool: memhub.MemBuddy | t.CPtr, # 用 find_func_in_module 去重,创建 declare 并添加参数, # 注册到函数表。 # ============================================================ -def _inject_function_declare(pool: memhub.MemBuddy | t.CPtr, +def _inject_function_declare(pool: rowptr[memhub.MemBuddy], mod: llvmlite.LLVMModule | t.CPtr, fd: ast.FunctionDef | t.CPtr, trans: HT.Translator | t.CPtr, @@ -2376,7 +2427,7 @@ def _inject_function_declare(pool: memhub.MemBuddy | t.CPtr, # 注入正确签名避免调用时 _ensure_method_declare 用实参类型 # 创建错误 declare(如 size: sizet 被写成 i32 而非 i64)。 # ============================================================ -def _inject_method_declare(pool: memhub.MemBuddy | t.CPtr, +def _inject_method_declare(pool: rowptr[memhub.MemBuddy], mod: llvmlite.LLVMModule | t.CPtr, m_fd: ast.FunctionDef | t.CPtr, cls_name: str, @@ -2581,7 +2632,7 @@ def _inject_method_declare(pool: memhub.MemBuddy | t.CPtr, # 提取 NAME: t.CTypedef = Type 中的名称和类型表达式字符串, # 调用 register_ctypedef 注册到动态 CTypedef 表。 # ============================================================ -def _register_ctypedef_from_annassign(pool: memhub.MemBuddy | t.CPtr, +def _register_ctypedef_from_annassign(pool: rowptr[memhub.MemBuddy], aa: ast.AnnAssign | t.CPtr) -> None: """从 AnnAssign 节点提取并注册 CTypedef""" if aa is None or pool is None: diff --git a/App/lib/Stub/StubMerger/StubMergerBuild.vp b/App/lib/Stub/StubMerger/StubMergerBuild.vp index c78753d..0182852 100644 --- a/App/lib/Stub/StubMerger/StubMergerBuild.vp +++ b/App/lib/Stub/StubMerger/StubMergerBuild.vp @@ -807,7 +807,7 @@ def _AppendDepsToWorklist(worklist: bytes, wl_len: sizet, # Returns: # 可达 SHA1 数量(>0 成功;0 无 includes 依赖;<0 失败) # ============================================================ -def _BuildReachableSha1Set(mb: memhub.MemBuddy | t.CPtr, source_dir: str, +def _BuildReachableSha1Set(mb: rowptr[memhub.MemBuddy], source_dir: str, temp_dir: str, reachable_set: str, app_deps: str = None, @@ -1697,7 +1697,7 @@ def BuildCombinedIR(temp_dir: str, local_sha1: str, # Returns: # 成功加载的 .vpi 文件数 # ============================================================ -def LoadDepVpiIntoModule(pool: memhub.MemBuddy | t.CPtr, +def LoadDepVpiIntoModule(pool: rowptr[memhub.MemBuddy], mod: llvmlite.LLVMModule | t.CPtr, imported_modules: str, from_imports: str, diff --git a/App/lib/__init__.vp b/App/lib/__init__.vp index ffc0f65..8425ec9 100644 --- a/App/lib/__init__.vp +++ b/App/lib/__init__.vp @@ -1,13 +1,13 @@ -import t, c -from stdint import * -import memhub -import lib.core.VLogger as VLogger - - -# ============================================================ -# lib 包入口 - 声明全局 _mbuddy 内存池指针 -# ============================================================ - -# 全局 mbuddy 内存池指针(由 App/main.vp 初始化后注入) -# 注意: 使用 MemBuddy 类型而非 MemManager,避免虚函数分派不工作时调用父类 alloc 返回 None -_mbuddy: memhub.MemBuddy | t.CPtr +import t, c +from stdint import * +import memhub +import lib.core.VLogger as VLogger + + +# ============================================================ +# lib 包入口 - 声明全局 _mbuddy 内存池指针 +# ============================================================ + +# 全局 mbuddy 内存池指针(由 App/main.vp 初始化后注入) +# 注意: 使用 MemBuddy 类型而非 MemManager,避免虚函数分派不工作时调用父类 alloc 返回 None +_mbuddy: rowptr[memhub.MemBuddy] diff --git a/App/lib/core/CompilerFactory.vp b/App/lib/core/CompilerFactory.vp index e1ba5a5..2e7b933 100644 --- a/App/lib/core/CompilerFactory.vp +++ b/App/lib/core/CompilerFactory.vp @@ -1,26 +1,19 @@ -import t, c -import memhub - - -# ============================================================ -# CompilerFactory - 编译器结构体工厂(对齐 TPC Translator 装配模式) -# ============================================================ -@t.NoVTable -class CompilerFactory: - """编译器结构体工厂(持有主池/永久池等共享对象)""" - - Pool: memhub.MemBuddy | t.CPtr # 主内存池(瞬时数据,mark/reset 回收) - PermPool: memhub.MemBuddy | t.CPtr # 永久内存池(持久数据,从不 reset) - - def __init__(self, pool: memhub.MemBuddy | t.CPtr, - perm_pool: memhub.MemBuddy | t.CPtr): - if self is None: - return - self.Pool = pool - self.PermPool = perm_pool - - -# ============================================================ -# 全局工厂单例 -# ============================================================ -factory: CompilerFactory | t.CPtr = None +import t, c +import memhub + + +# ============================================================ +# CompilerFactory - 编译器结构体工厂(对齐 TPC Translator 装配模式) +# ============================================================ +@t.NoVTable +class CompilerFactory: + """编译器结构体工厂(持有主池/永久池等共享对象)""" + Pool: rowptr[memhub.MemBuddy] # 主内存池(瞬时数据,mark/reset 回收) + PermPool: rowptr[memhub.MemBuddy] # 永久内存池(持久数据,从不 reset) + def __init__(self, pool: rowptr[memhub.MemBuddy], perm_pool: rowptr[memhub.MemBuddy]): + if self is None: return + self.Pool = pool + self.PermPool = perm_pool + +# 全局工厂单例 +factory: rowptr[CompilerFactory] = None diff --git a/App/lib/core/Gen/AssignGenMixin.vp b/App/lib/core/Gen/AssignGenMixin.vp index fc0f6dc..66bd248 100644 --- a/App/lib/core/Gen/AssignGenMixin.vp +++ b/App/lib/core/Gen/AssignGenMixin.vp @@ -156,7 +156,7 @@ class AssignGenMixin: # register_cdefine_double,否则 translate_value 查表得 0 生成 # ret i32 0(llc 报错 "value doesn't match function result type")。 # ============================================================ - def _register_cdefine_from_value(self, pool: memhub.MemBuddy | t.CPtr, + def _register_cdefine_from_value(self, pool: rowptr[memhub.MemBuddy], name: str, val_node: ast.AST | t.CPtr) -> None: """注册 CDefine 常量(浮点字面量 → register_cdefine_double,否则整数)""" if pool is None or name is None: @@ -428,7 +428,7 @@ class AssignGenMixin: return 1 return 0 - def _stg_ty_equal(self, pool: memhub.MemBuddy | t.CPtr, + def _stg_ty_equal(self, pool: rowptr[memhub.MemBuddy], ta: llvmlite.LLVMType | t.CPtr, tb: llvmlite.LLVMType | t.CPtr) -> int: """类型内容相等比较(storage 绑定判定用)。 @@ -623,7 +623,7 @@ class AssignGenMixin: # 0 成功,1 失败 # ============================================================ def _init_global_array_from_list(self, builder: llvmlite.IRBuilder | t.CPtr, - pool: memhub.MemBuddy | t.CPtr, + pool: rowptr[memhub.MemBuddy], mod: llvmlite.LLVMModule | t.CPtr, array_alloca: llvmlite.Value | t.CPtr, list_node: ast.AST | t.CPtr, @@ -732,7 +732,7 @@ class AssignGenMixin: # 支持浮点运算、指针算术: ptr += int / ptr -= int # 整数运算自动类型提升 # ============================================================ - def _apply_aug_op(self, pool: memhub.MemBuddy | t.CPtr, + def _apply_aug_op(self, pool: rowptr[memhub.MemBuddy], builder: llvmlite.IRBuilder | t.CPtr, op: int, lhs: llvmlite.Value | t.CPtr, @@ -838,7 +838,7 @@ class AssignGenMixin: # Attribute 目标: self.field += 1 # 流程: get_attribute_ptr → load → binop → store if tk == ast.ASTKind.Attribute: - pool: memhub.MemBuddy | t.CPtr = trans.Pool + pool: rowptr[memhub.MemBuddy] = trans.Pool builder: llvmlite.IRBuilder | t.CPtr = trans._cur_builder mod: llvmlite.LLVMModule | t.CPtr = trans.Module @@ -887,7 +887,7 @@ class AssignGenMixin: # Subscript 目标: self.state[i] += x / arr[i] += x # 流程: get_subscript_ptr → load → binop → store if tk == ast.ASTKind.Subscript: - pool: memhub.MemBuddy | t.CPtr = trans.Pool + pool: rowptr[memhub.MemBuddy] = trans.Pool builder: llvmlite.IRBuilder | t.CPtr = trans._cur_builder mod: llvmlite.LLVMModule | t.CPtr = trans.Module @@ -942,7 +942,7 @@ class AssignGenMixin: if nm is None or nm.id is None: return 0 - pool: memhub.MemBuddy | t.CPtr = trans.Pool + pool: rowptr[memhub.MemBuddy] = trans.Pool builder: llvmlite.IRBuilder | t.CPtr = trans._cur_builder mod: llvmlite.LLVMModule | t.CPtr = trans.Module @@ -1097,7 +1097,7 @@ class AssignGenMixin: # undefined)。PreScan 与 Handle 都调用(PreScan 预创建 alloca 的类型必须 # 与 Handle 一致,否则 get_or_create_sym 复用旧 alloca 使推断失效)。 # ============================================================ - def _infer_static_array_ty_from_literal(self, pool: memhub.MemBuddy | t.CPtr, + def _infer_static_array_ty_from_literal(self, pool: rowptr[memhub.MemBuddy], annot: ast.AST | t.CPtr, value: ast.AST | t.CPtr, resolved_ty: llvmlite.LLVMType | t.CPtr) -> llvmlite.LLVMType | t.CPtr: @@ -1131,7 +1131,7 @@ class AssignGenMixin: # 以及 builtins 最后匹配的诊断结果(_lookup_builtins_typedef 记录), # 便于直接定位是"注解本身未注册"还是"builtins 扫描未命中/未展开"。 # ============================================================ - def _build_ann_fail_msg(self, pool: memhub.MemBuddy | t.CPtr, + def _build_ann_fail_msg(self, pool: rowptr[memhub.MemBuddy], annot: ast.AST | t.CPtr, nm_id: str) -> str: """构建变量类型注解解析失败的详细报错信息 @@ -1188,7 +1188,7 @@ class AssignGenMixin: # 供后续 t.CArray[elem_ty, NAME] 编译期解析使用 # 浮点/整数自动识别(与 Handle/handle_module_level_var 路径一致) if self.is_cdefine_annotation(aa.annotation) != 0: - pool_ps: memhub.MemBuddy | t.CPtr = trans.Pool + pool_ps: rowptr[memhub.MemBuddy] = trans.Pool self._register_cdefine_from_value(pool_ps, nm.id, aa.value) return 0 @@ -1217,7 +1217,7 @@ class AssignGenMixin: if existing is not None: return 0 - pool: memhub.MemBuddy | t.CPtr = trans.Pool + pool: rowptr[memhub.MemBuddy] = trans.Pool builder: llvmlite.IRBuilder | t.CPtr = trans._cur_builder # 从 annotation 推断类型(修复:原硬编码 i32 导致 str 等类型错误) @@ -1300,7 +1300,7 @@ class AssignGenMixin: # 返回 1=执行过特化尝试;0=注解形态不适用(非泛型 Subscript)。 # ============================================================ def _prespecialize_generic_annotation(self, trans: HT.Translator | t.CPtr, - pool: memhub.MemBuddy | t.CPtr, + pool: rowptr[memhub.MemBuddy], annot: ast.AST | t.CPtr) -> int: """泛型注解预特化(见上方注释),返回 1=已尝试 / 0=不适用""" if annot is None or trans is None: @@ -1360,7 +1360,7 @@ class AssignGenMixin: # 注册到全局 CDefine 表供 t.CArray[elem_ty, NAME] 解析 # 注: PreScan 已注册过,此处保证即使跳过 PreScan 也能正确注册 if self.is_cdefine_annotation(aa.annotation) != 0: - pool_cd: memhub.MemBuddy | t.CPtr = trans.Pool + pool_cd: rowptr[memhub.MemBuddy] = trans.Pool self._register_cdefine_from_value(pool_cd, nm.id, aa.value) return 0 @@ -1371,13 +1371,13 @@ class AssignGenMixin: # 解析查表失败 → NameError: mode_t。仅登记类型表达式,不创建全局/ # 局部存储——否则生成 @mode_t 符号,链接 duplicate symbol warning。 if self.is_ctypedef_annotation(aa.annotation) != 0: - pool_ct: memhub.MemBuddy | t.CPtr = trans.Pool + pool_ct: rowptr[memhub.MemBuddy] = trans.Pool ctd_str: str = self.Gen.TypeGenResolve._get_type_name_from_annotation(pool_ct, aa.value) if ctd_str is not None: self.Gen.TypeGenCType.register_ctypedef(pool_ct, nm.id, ctd_str) return 0 - pool: memhub.MemBuddy | t.CPtr = trans.Pool + pool: rowptr[memhub.MemBuddy] = trans.Pool builder: llvmlite.IRBuilder | t.CPtr = trans._cur_builder mod: llvmlite.LLVMModule | t.CPtr = trans.Module @@ -1770,7 +1770,7 @@ class AssignGenMixin: return 0 # 从 trans 取共享状态(替代 11 个参数) - pool: memhub.MemBuddy | t.CPtr = trans.Pool + pool: rowptr[memhub.MemBuddy] = trans.Pool builder: llvmlite.IRBuilder | t.CPtr = trans._cur_builder mod: llvmlite.LLVMModule | t.CPtr = trans.Module @@ -2294,7 +2294,7 @@ class AssignGenMixin: # Attribute → 字段注解类名(委托 Generator 单例 _resolve_attr_field_class) # 仅当目标为已注册结构体时采用,与"按需过滤,找不到 fast-fail"原则一致。 # ============================================================ - def _infer_rhs_annot(self, pool: memhub.MemBuddy | t.CPtr, + def _infer_rhs_annot(self, pool: rowptr[memhub.MemBuddy], mod: llvmlite.LLVMModule | t.CPtr, node: ast.AST | t.CPtr, trans: HT.Translator | t.CPtr, @@ -2420,7 +2420,7 @@ class AssignGenMixin: # CFloat64T/t.CPtr 等均不注册 struct,天然过滤)。"A | B" 联合 # 多候选时取首个命中段。 # ============================================================ - def _extract_annot_class_name(self, pool: memhub.MemBuddy | t.CPtr, + def _extract_annot_class_name(self, pool: rowptr[memhub.MemBuddy], annot: str) -> str: """从返回注解文本提取已注册结构体类名,无命中返回 None""" if pool is None or annot is None: @@ -2496,7 +2496,7 @@ class AssignGenMixin: # 或跨模块类有 SHA1(stub 中声明)即视为存在。仅在确实存在时 # 才采用运算符重载推断的类名,避免把原生运算误标为类类型。 # ============================================================ - def _cls_has_dunder(self, pool: memhub.MemBuddy | t.CPtr, + def _cls_has_dunder(self, pool: rowptr[memhub.MemBuddy], mod: llvmlite.LLVMModule | t.CPtr, class_name: str, dunder: str) -> int: """类及其 MRO 祖先链中是否存在 dunder 方法,存在返回 1""" diff --git a/App/lib/core/Gen/AsyncGenMixin.vp b/App/lib/core/Gen/AsyncGenMixin.vp index fb1b433..8731135 100644 --- a/App/lib/core/Gen/AsyncGenMixin.vp +++ b/App/lib/core/Gen/AsyncGenMixin.vp @@ -68,7 +68,7 @@ class AsyncGenMixin(CallGenBase.CallGenBase): if fd is None or fd.name is None or trans is None: return 0 name: str = fd.name - pool: memhub.MemBuddy | t.CPtr = trans.Pool + pool: rowptr[memhub.MemBuddy] = trans.Pool mod: llvmlite.LLVMModule | t.CPtr = trans.Module if pool is None or mod is None: return 0 @@ -712,7 +712,7 @@ class AsyncGenMixin(CallGenBase.CallGenBase): # 帧结构体 %Coro_ = { i32 state, i32 done, i32 ret, <局部槽>* } # 槽索引: 0=state 1=done 2=ret 3..3+nlocals-1=局部变量 # ============================================================ - def _build_frame_ty(self, pool: memhub.MemBuddy | t.CPtr, + def _build_frame_ty(self, pool: rowptr[memhub.MemBuddy], mod: llvmlite.LLVMModule | t.CPtr, trans: HT.Translator | t.CPtr, name: str, @@ -767,7 +767,7 @@ class AsyncGenMixin(CallGenBase.CallGenBase): # ============================================================ # create_() -> %Coro_* # ============================================================ - def _emit_create(self, pool: memhub.MemBuddy | t.CPtr, + def _emit_create(self, pool: rowptr[memhub.MemBuddy], mod: llvmlite.LLVMModule | t.CPtr, trans: HT.Translator | t.CPtr, name: str, @@ -928,7 +928,7 @@ class AsyncGenMixin(CallGenBase.CallGenBase): # ============================================================ # M7:每帧类型的全局 free-list 池头(i64,0 = 空) # ============================================================ - def _get_coro_pool(self, pool: memhub.MemBuddy | t.CPtr, + def _get_coro_pool(self, pool: rowptr[memhub.MemBuddy], mod: llvmlite.LLVMModule | t.CPtr, trans: HT.Translator | t.CPtr, name: str) -> llvmlite.GlobalVariable | t.CPtr: @@ -974,7 +974,7 @@ class AsyncGenMixin(CallGenBase.CallGenBase): # ============================================================ # resume_(%Coro_*) -> i32 状态机(静态段切分) # ============================================================ - def _emit_resume(self, pool: memhub.MemBuddy | t.CPtr, + def _emit_resume(self, pool: rowptr[memhub.MemBuddy], mod: llvmlite.LLVMModule | t.CPtr, trans: HT.Translator | t.CPtr, name: str, @@ -1204,7 +1204,7 @@ class AsyncGenMixin(CallGenBase.CallGenBase): # ============================================================ def _handle_segment(self, trans: HT.Translator | t.CPtr, builder: llvmlite.IRBuilder | t.CPtr, - pool: memhub.MemBuddy | t.CPtr, + pool: rowptr[memhub.MemBuddy], mod: llvmlite.LLVMModule | t.CPtr, stmts: list[ast.AST | t.CPtr] | t.CPtr): """递归翻译协程体语句。builder 当前块 = 活跃执行块(state0 或某恢复块)。""" @@ -1300,7 +1300,7 @@ class AsyncGenMixin(CallGenBase.CallGenBase): # ============================================================ def _handle_coro_if(self, trans: HT.Translator | t.CPtr, builder: llvmlite.IRBuilder | t.CPtr, - pool: memhub.MemBuddy | t.CPtr, + pool: rowptr[memhub.MemBuddy], mod: llvmlite.LLVMModule | t.CPtr, stmt: ast.AST | t.CPtr): ifn: ast.If | t.CPtr = (ast.If | t.CPtr)(stmt) @@ -1350,7 +1350,7 @@ class AsyncGenMixin(CallGenBase.CallGenBase): # ============================================================ def _handle_coro_while(self, trans: HT.Translator | t.CPtr, builder: llvmlite.IRBuilder | t.CPtr, - pool: memhub.MemBuddy | t.CPtr, + pool: rowptr[memhub.MemBuddy], mod: llvmlite.LLVMModule | t.CPtr, stmt: ast.AST | t.CPtr): whn: ast.While | t.CPtr = (ast.While | t.CPtr)(stmt) @@ -1400,7 +1400,7 @@ class AsyncGenMixin(CallGenBase.CallGenBase): # ============================================================ def _handle_nested_await_stmt(self, trans: HT.Translator | t.CPtr, builder: llvmlite.IRBuilder | t.CPtr, - pool: memhub.MemBuddy | t.CPtr, + pool: rowptr[memhub.MemBuddy], mod: llvmlite.LLVMModule | t.CPtr, stmt: ast.AST | t.CPtr): """把语句中所有嵌套 await 提升为顶层临时赋值(与预扫描 DFS 顺序一致)""" @@ -1532,7 +1532,7 @@ class AsyncGenMixin(CallGenBase.CallGenBase): return self._find_expr_await(sb.slice) return None - def _replace_await_with_name(self, pool: memhub.MemBuddy | t.CPtr, + def _replace_await_with_name(self, pool: rowptr[memhub.MemBuddy], stmt: ast.AST | t.CPtr, temp_name: str) -> int: """把语句树中第一个 Await 替换为 Name(temp_name)(DFS 字段序)""" @@ -1561,7 +1561,7 @@ class AsyncGenMixin(CallGenBase.CallGenBase): return 0 return 0 - def _replace_expr_await(self, pool: memhub.MemBuddy | t.CPtr, + def _replace_expr_await(self, pool: rowptr[memhub.MemBuddy], node: ast.AST | t.CPtr, temp_name: str) -> int: """在表达式树中把第一个 Await 替换为 Name(temp_name, Load)。 @@ -1698,7 +1698,7 @@ class AsyncGenMixin(CallGenBase.CallGenBase): # 条件归一化(i1 直通;其余 icmp ne 0) # ============================================================ def _normalize_cond(self, builder: llvmlite.IRBuilder | t.CPtr, - pool: memhub.MemBuddy | t.CPtr, + pool: rowptr[memhub.MemBuddy], cond: llvmlite.Value | t.CPtr) -> llvmlite.Value | t.CPtr: if cond is None: return None @@ -1761,7 +1761,7 @@ class AsyncGenMixin(CallGenBase.CallGenBase): # M3:await coro_sleep(ms) —— wake 槽挂起(coro_run 轮询续跑) # ============================================================ def _emit_await_sleep(self, builder: llvmlite.IRBuilder | t.CPtr, - pool: memhub.MemBuddy | t.CPtr, + pool: rowptr[memhub.MemBuddy], mod: llvmlite.LLVMModule | t.CPtr, trans: HT.Translator | t.CPtr, node: ast.AST | t.CPtr) -> llvmlite.Value | t.CPtr: @@ -1812,7 +1812,7 @@ class AsyncGenMixin(CallGenBase.CallGenBase): # M4-M6:协程内 raise(异常类型/值 → 帧 exc 槽) # ============================================================ def _handle_coro_raise(self, builder: llvmlite.IRBuilder | t.CPtr, - pool: memhub.MemBuddy | t.CPtr, + pool: rowptr[memhub.MemBuddy], mod: llvmlite.LLVMModule | t.CPtr, trans: HT.Translator | t.CPtr, stmt: ast.AST | t.CPtr): @@ -1849,7 +1849,7 @@ class AsyncGenMixin(CallGenBase.CallGenBase): llvmlite.build_store(builder, done_r, trans._coro_done_ptr) llvmlite.build_br(builder, trans._coro_exit_bb) - def _resolve_raise_code(self, pool: memhub.MemBuddy | t.CPtr, + def _resolve_raise_code(self, pool: rowptr[memhub.MemBuddy], exc_node: ast.AST | t.CPtr) -> int: """解析 raise 目标的异常码(内置/用户异常类名);非异常类返回 0""" if exc_node is None: @@ -1871,7 +1871,7 @@ class AsyncGenMixin(CallGenBase.CallGenBase): return self.Gen.ClassGenBase.lookup_exception_code(name) def _resolve_raise_msg(self, builder: llvmlite.IRBuilder | t.CPtr, - pool: memhub.MemBuddy | t.CPtr, + pool: rowptr[memhub.MemBuddy], mod: llvmlite.LLVMModule | t.CPtr, trans: HT.Translator | t.CPtr, exc_node: ast.AST | t.CPtr) -> llvmlite.Value | t.CPtr: @@ -1889,7 +1889,7 @@ class AsyncGenMixin(CallGenBase.CallGenBase): # ============================================================ def _handle_coro_try(self, trans: HT.Translator | t.CPtr, builder: llvmlite.IRBuilder | t.CPtr, - pool: memhub.MemBuddy | t.CPtr, + pool: rowptr[memhub.MemBuddy], mod: llvmlite.LLVMModule | t.CPtr, stmt: ast.AST | t.CPtr): """协程内 try/except:raise/await 传播异常在 try 栈内改跳 except 处理器; @@ -2027,7 +2027,7 @@ class AsyncGenMixin(CallGenBase.CallGenBase): llvmlite.build_br(builder, merge_bb) llvmlite.position_at_end(builder, merge_bb) - def _exception_type_name(self, pool: memhub.MemBuddy | t.CPtr, + def _exception_type_name(self, pool: rowptr[memhub.MemBuddy], type_node: ast.AST | t.CPtr) -> str: """取 except 类型名(Name/Attribute),未命中返回 None""" if type_node is None: @@ -2045,7 +2045,7 @@ class AsyncGenMixin(CallGenBase.CallGenBase): # ============================================================ def _handle_coro_try_finally(self, trans: HT.Translator | t.CPtr, builder: llvmlite.IRBuilder | t.CPtr, - pool: memhub.MemBuddy | t.CPtr, + pool: rowptr[memhub.MemBuddy], mod: llvmlite.LLVMModule | t.CPtr, stmt: ast.AST | t.CPtr): """协程内 try/finally:正常/异常路径都执行 fbody; @@ -2099,7 +2099,7 @@ class AsyncGenMixin(CallGenBase.CallGenBase): # ============================================================ def _handle_coro_for(self, trans: HT.Translator | t.CPtr, builder: llvmlite.IRBuilder | t.CPtr, - pool: memhub.MemBuddy | t.CPtr, + pool: rowptr[memhub.MemBuddy], mod: llvmlite.LLVMModule | t.CPtr, stmt: ast.AST | t.CPtr): """range-For(含 await):__f_idx_N = start; __f_len_N = end; @@ -2194,7 +2194,7 @@ class AsyncGenMixin(CallGenBase.CallGenBase): # M3/M4/M7:coro.coro_destroy / coro_exception / coro_exception_msg / coro_gather # ============================================================ def translate_coro_destroy(self, builder: llvmlite.IRBuilder | t.CPtr, - pool: memhub.MemBuddy | t.CPtr, + pool: rowptr[memhub.MemBuddy], mod: llvmlite.LLVMModule | t.CPtr, cl: ast.Call | t.CPtr, trans: HT.Translator | t.CPtr) -> llvmlite.Value | t.CPtr: @@ -2240,7 +2240,7 @@ class AsyncGenMixin(CallGenBase.CallGenBase): return llvmlite.const_int32(pool, 0) def translate_coro_exception(self, builder: llvmlite.IRBuilder | t.CPtr, - pool: memhub.MemBuddy | t.CPtr, + pool: rowptr[memhub.MemBuddy], mod: llvmlite.LLVMModule | t.CPtr, cl: ast.Call | t.CPtr, trans: HT.Translator | t.CPtr) -> llvmlite.Value | t.CPtr: @@ -2269,7 +2269,7 @@ class AsyncGenMixin(CallGenBase.CallGenBase): return llvmlite.build_load(builder, i32_ty, exc_ptr) def translate_coro_exception_msg(self, builder: llvmlite.IRBuilder | t.CPtr, - pool: memhub.MemBuddy | t.CPtr, + pool: rowptr[memhub.MemBuddy], mod: llvmlite.LLVMModule | t.CPtr, cl: ast.Call | t.CPtr, trans: HT.Translator | t.CPtr) -> llvmlite.Value | t.CPtr: @@ -2299,7 +2299,7 @@ class AsyncGenMixin(CallGenBase.CallGenBase): return llvmlite.build_load(builder, i8_ptr_ty, msg_ptr) def translate_coro_gather(self, builder: llvmlite.IRBuilder | t.CPtr, - pool: memhub.MemBuddy | t.CPtr, + pool: rowptr[memhub.MemBuddy], mod: llvmlite.LLVMModule | t.CPtr, cl: ast.Call | t.CPtr, trans: HT.Translator | t.CPtr) -> llvmlite.Value | t.CPtr: @@ -2366,7 +2366,7 @@ class AsyncGenMixin(CallGenBase.CallGenBase): # await 表达式翻译(顶层段尾 / translate_value Await 分支共用) # ============================================================ def _emit_await(self, builder: llvmlite.IRBuilder | t.CPtr, - pool: memhub.MemBuddy | t.CPtr, + pool: rowptr[memhub.MemBuddy], mod: llvmlite.LLVMModule | t.CPtr, trans: HT.Translator | t.CPtr, node: ast.AST | t.CPtr, @@ -2501,7 +2501,7 @@ class AsyncGenMixin(CallGenBase.CallGenBase): # coro.coro_run(帧) 内联翻译 # ============================================================ def translate_coro_run(self, builder: llvmlite.IRBuilder | t.CPtr, - pool: memhub.MemBuddy | t.CPtr, + pool: rowptr[memhub.MemBuddy], mod: llvmlite.LLVMModule | t.CPtr, cl: ast.Call | t.CPtr, trans: HT.Translator | t.CPtr) -> llvmlite.Value | t.CPtr: @@ -2729,7 +2729,7 @@ class AsyncGenMixin(CallGenBase.CallGenBase): # 段翻译辅助 # ============================================================ def _emit_coro_return(self, builder: llvmlite.IRBuilder | t.CPtr, - pool: memhub.MemBuddy | t.CPtr, + pool: rowptr[memhub.MemBuddy], mod: llvmlite.LLVMModule | t.CPtr, trans: HT.Translator | t.CPtr, stmt: ast.AST | t.CPtr) -> None: diff --git a/App/lib/core/Gen/BaseGenMixin.vp b/App/lib/core/Gen/BaseGenMixin.vp index 79e002d..991e724 100644 --- a/App/lib/core/Gen/BaseGenMixin.vp +++ b/App/lib/core/Gen/BaseGenMixin.vp @@ -15,7 +15,7 @@ class BaseGenMixin: # 内存/IR 状态 Gen: Generator.Generator | t.CPtr - Pool: memhub.MemBuddy | t.CPtr # 内存池 + Pool: rowptr[memhub.MemBuddy] # 内存池 Module: llvmlite.LLVMModule | t.CPtr # 当前 LLVM 模块 Builder: llvmlite.IRBuilder | t.CPtr # 当前 IRBuilder # 符号表/函数表 @@ -31,7 +31,7 @@ class BaseGenMixin: CurBuilder: llvmlite.IRBuilder | t.CPtr CurClassName: str - def InitBaseGen(self, pool: memhub.MemBuddy | t.CPtr) -> int: + def InitBaseGen(self, pool: rowptr[memhub.MemBuddy]) -> int: """初始化生成器状态(默认值;子类构造时调用)""" if self is None: return 1 diff --git a/App/lib/core/Gen/Call/CallGenBase.vp b/App/lib/core/Gen/Call/CallGenBase.vp index aa89d1f..6599d86 100644 --- a/App/lib/core/Gen/Call/CallGenBase.vp +++ b/App/lib/core/Gen/Call/CallGenBase.vp @@ -1,5 +1,6 @@ import lib.core.Gen.GenTypes as GenTypes import lib.core.Gen.Generator as Generator +import lib.core.Gen.GenApi as GenApi import t, c from stdint import * import ast @@ -129,7 +130,7 @@ class CallGenBase: return StubMergerStore.LookupSha1ByModNameSuffix(mod_suffix) - def _module_package_from_sha1(self, pool: memhub.MemBuddy | t.CPtr, + def _module_package_from_sha1(self, pool: rowptr[memhub.MemBuddy], mod_sha1: str) -> str: """从 SHA1 存储器的 rel_path 计算模块所属包名(目录部分,'/' → '.')""" if pool is None or mod_sha1 is None: @@ -164,7 +165,7 @@ class CallGenBase: return None - def _lookup_reexport_from_vpi(self, pool: memhub.MemBuddy | t.CPtr, + def _lookup_reexport_from_vpi(self, pool: rowptr[memhub.MemBuddy], mod_sha1: str, func_name: str) -> str: """re-export 表未命中时,从模块 .vpi 按需解析 from-import 定位定义模块 @@ -439,7 +440,7 @@ class CallGenBase: return 0 - def _is_state_func_from_vpi(self, pool: memhub.MemBuddy | t.CPtr, + def _is_state_func_from_vpi(self, pool: rowptr[memhub.MemBuddy], sha1: str, func_name: str) -> int: """vpi 返回注解含 t.State → 外部 C 函数(定义端用裸名,跨模块调用无 sha1 头) @@ -461,7 +462,7 @@ class CallGenBase: return 0 - def _lookup_mod_sha1(self, pool: memhub.MemBuddy | t.CPtr, + def _lookup_mod_sha1(self, pool: rowptr[memhub.MemBuddy], from_imports: str, class_name: str, allow_star_fallback: int = 1) -> str: """从 from_imports 查找类所属模块的 SHA1,返回 None=未找到 @@ -475,7 +476,7 @@ class CallGenBase: return self._lookup_sha1_from_modname_raw(pool, mod_name_raw) - def _lookup_sha1_from_modname_raw(self, pool: memhub.MemBuddy | t.CPtr, + def _lookup_sha1_from_modname_raw(self, pool: rowptr[memhub.MemBuddy], mod_name_raw: str) -> str: """从原始模块名查找 SHA1,返回 None=未找到""" # 手动找到模块名结束位置(空格、null、或 ':' 别名分隔符),复制到新缓冲区 @@ -603,7 +604,7 @@ class CallGenBase: # 当 found_func 为 None(stub 未注入或跨模块调用)时, # 在当前模块中创建函数声明,避免 llc 报 undefined value。 # ============================================================ - def _ensure_method_declare(self, pool: memhub.MemBuddy | t.CPtr, + def _ensure_method_declare(self, pool: rowptr[memhub.MemBuddy], mod: llvmlite.LLVMModule | t.CPtr, call_name: str, ret_ty: llvmlite.LLVMType | t.CPtr, @@ -700,34 +701,30 @@ class CallGenBase: cls_d: str = None meth_d: str = None if call_name is not None: - cl_len_d: sizet = string.strlen(call_name) - if cl_len_d >= 17 and call_name[16] == '.': - sha1_ok_d: int = 1 - si_d: sizet - for si_d in range(16): - cc_d: int = call_name[si_d] - if not ((cc_d >= 48 and cc_d <= 57) or (cc_d >= 97 and cc_d <= 102)): - sha1_ok_d = 0 - break - if sha1_ok_d != 0: - sha1_buf_d: bytes = stdlib.malloc(17) - if sha1_buf_d is not None: - string.strncpy(sha1_buf_d, call_name, 16) - sha1_buf_d[16] = '\0' - sha1_d = sha1_buf_d - rest_d: str = call_name + 17 - dot2_d: str = string.strchr(rest_d, '.') - if dot2_d is not None: - cls_len_d: sizet = uint64(dot2_d) - uint64(rest_d) - if cls_len_d > 0: - cls_buf_d: bytes = stdlib.malloc(cls_len_d + 1) - if cls_buf_d is not None: - string.strncpy(cls_buf_d, rest_d, cls_len_d) - cls_buf_d[cls_len_d] = '\0' - cls_d = cls_buf_d - meth_d = dot2_d + 1 - else: - meth_d = rest_d + # [C10 收敛] SHA1 前缀判定走唯一真源 `GenApi.sha1_prefix_len` + # (旧实现自带一份 hex+'.' 校验,判据 `>= 17` 与真源一致); + # 前缀长度取返回值,不再硬编码 17/16。 + sha1_pfx_d: int = GenApi.sha1_prefix_len(call_name) + if sha1_pfx_d != 0: + pfx_len_d: sizet = sizet(sha1_pfx_d) + sha1_buf_d: bytes = stdlib.malloc(pfx_len_d) + if sha1_buf_d is not None: + string.strncpy(sha1_buf_d, call_name, pfx_len_d - 1) + sha1_buf_d[pfx_len_d - 1] = '\0' + sha1_d = sha1_buf_d + rest_d: str = call_name + pfx_len_d + dot2_d: str = string.strchr(rest_d, '.') + if dot2_d is not None: + cls_len_d: sizet = uint64(dot2_d) - uint64(rest_d) + if cls_len_d > 0: + cls_buf_d: bytes = stdlib.malloc(cls_len_d + 1) + if cls_buf_d is not None: + string.strncpy(cls_buf_d, rest_d, cls_len_d) + cls_buf_d[cls_len_d] = '\0' + cls_d = cls_buf_d + meth_d = dot2_d + 1 + else: + meth_d = rest_d prm_annots_d: str = None if sha1_d is not None and meth_d is not None: prm_annots_d = self._vpi_method_param_annot(pool, sha1_d, cls_d, meth_d) @@ -774,7 +771,7 @@ class CallGenBase: # ============================================================ # ============================================================ - def _lookup_method_ret_ty_via_vpi(self, pool: memhub.MemBuddy | t.CPtr, + def _lookup_method_ret_ty_via_vpi(self, pool: rowptr[memhub.MemBuddy], cls_sha1: str, cls_name: str, method_name: str) -> llvmlite.LLVMType | t.CPtr: @@ -803,7 +800,7 @@ class CallGenBase: # 调用方据此补全 declare/call 缺失参数(默认参数零值兜底)。 # 未命中返回 None。 # ============================================================ - def _vpi_method_param_annot(self, pool: memhub.MemBuddy | t.CPtr, + def _vpi_method_param_annot(self, pool: rowptr[memhub.MemBuddy], cls_sha1: str, cls_name: str, method_name: str) -> str: @@ -821,7 +818,7 @@ class CallGenBase: # 与 _lookup_method_ret_ty_via_vpi 的返回注解解析同源;解析失败返回 # None,调用方以 i8* 兜底(ABI 兼容,参数槽位宽度一致)。 # ============================================================ - def _vpi_resolve_param_annot_ty(self, pool: memhub.MemBuddy | t.CPtr, + def _vpi_resolve_param_annot_ty(self, pool: rowptr[memhub.MemBuddy], seg: str) -> llvmlite.LLVMType | t.CPtr: """解析单个 vpi 参数注解段为 LLVMType,失败返回 None""" if pool is None or seg is None: @@ -843,7 +840,7 @@ class CallGenBase: # ============================================================ # ============================================================ - def _special_method_ret_ty(self, pool: memhub.MemBuddy | t.CPtr, + def _special_method_ret_ty(self, pool: rowptr[memhub.MemBuddy], class_name: str, method_name: str) -> llvmlite.LLVMType | t.CPtr: """编译器内置特殊方法的固定返回类型;非特殊返回 None""" @@ -927,7 +924,7 @@ class CallGenBase: # ============================================================ # ============================================================ - def _ParseLLVMRetTyStr(self, pool: memhub.MemBuddy | t.CPtr, + def _ParseLLVMRetTyStr(self, pool: rowptr[memhub.MemBuddy], buf: bytes, start: sizet, end: sizet) -> llvmlite.LLVMType | t.CPtr: @@ -1066,7 +1063,7 @@ class CallGenBase: # ============================================================ # ============================================================ - def _LookupMethodRetTyFromTextLL(self, pool: memhub.MemBuddy | t.CPtr, + def _LookupMethodRetTyFromTextLL(self, pool: rowptr[memhub.MemBuddy], class_sha1: str, class_name: str, method_name: str, @@ -1206,7 +1203,7 @@ class CallGenBase: # ============================================================ # ============================================================ - def _dep_text_ll_exists(self, pool: memhub.MemBuddy | t.CPtr, + def _dep_text_ll_exists(self, pool: rowptr[memhub.MemBuddy], sha1: str) -> int: """探测 {temp_dir}/{sha1[0:2]}/{sha1}.text.ll 是否存在,1=存在""" if self.Gen.CallGenBase.TempDir is None or self.Gen.CallGenBase.TempDirLen == 0 or sha1 is None: diff --git a/App/lib/core/Gen/Call/CallGenCBuiltin.vp b/App/lib/core/Gen/Call/CallGenCBuiltin.vp index 3274fe2..28ada66 100644 --- a/App/lib/core/Gen/Call/CallGenCBuiltin.vp +++ b/App/lib/core/Gen/Call/CallGenCBuiltin.vp @@ -82,7 +82,7 @@ class CallGenCBuiltin(CallGenBase.CallGenBase): """c.* 内建 + 内联汇编 + LLVMIR 翻译(继承 Base)""" - def translate_c_deref(self, pool: memhub.MemBuddy | t.CPtr, + def translate_c_deref(self, pool: rowptr[memhub.MemBuddy], builder: llvmlite.IRBuilder | t.CPtr, mod: llvmlite.LLVMModule | t.CPtr, cl: ast.Call | t.CPtr, @@ -151,7 +151,7 @@ class CallGenCBuiltin(CallGenBase.CallGenBase): return None - def translate_c_derefas(self, pool: memhub.MemBuddy | t.CPtr, + def translate_c_derefas(self, pool: rowptr[memhub.MemBuddy], builder: llvmlite.IRBuilder | t.CPtr, mod: llvmlite.LLVMModule | t.CPtr, cl: ast.Call | t.CPtr, @@ -213,7 +213,7 @@ class CallGenCBuiltin(CallGenBase.CallGenBase): return val - def translate_c_set(self, pool: memhub.MemBuddy | t.CPtr, + def translate_c_set(self, pool: rowptr[memhub.MemBuddy], builder: llvmlite.IRBuilder | t.CPtr, mod: llvmlite.LLVMModule | t.CPtr, cl: ast.Call | t.CPtr, @@ -337,7 +337,7 @@ class CallGenCBuiltin(CallGenBase.CallGenBase): return b_val - def translate_c_addr(self, pool: memhub.MemBuddy | t.CPtr, + def translate_c_addr(self, pool: rowptr[memhub.MemBuddy], builder: llvmlite.IRBuilder | t.CPtr, mod: llvmlite.LLVMModule | t.CPtr, cl: ast.Call | t.CPtr, @@ -670,7 +670,7 @@ class CallGenCBuiltin(CallGenBase.CallGenBase): return None - def translate_c_load(self, pool: memhub.MemBuddy | t.CPtr, + def translate_c_load(self, pool: rowptr[memhub.MemBuddy], builder: llvmlite.IRBuilder | t.CPtr, mod: llvmlite.LLVMModule | t.CPtr, cl: ast.Call | t.CPtr, @@ -732,7 +732,7 @@ class CallGenCBuiltin(CallGenBase.CallGenBase): dst[dlen + i] = '\0' - def _asm_mangle_global_symbols(self, pool: memhub.MemBuddy | t.CPtr, + def _asm_mangle_global_symbols(self, pool: rowptr[memhub.MemBuddy], asm_text: str, asm_size: sizet, mod: llvmlite.LLVMModule | t.CPtr) -> str: """asm 模板中裸符号引用模块全局的检查(fail-fast) @@ -804,7 +804,7 @@ class CallGenCBuiltin(CallGenBase.CallGenBase): return out - def _asm_escape_for_ir(self, pool: memhub.MemBuddy | t.CPtr, + def _asm_escape_for_ir(self, pool: rowptr[memhub.MemBuddy], src: str) -> str: """转义汇编文本用于 LLVM IR 字符串字面量""" if src is None: @@ -939,7 +939,7 @@ class CallGenCBuiltin(CallGenBase.CallGenBase): return "" - def _resolve_asm_descr(self, pool: memhub.MemBuddy | t.CPtr, + def _resolve_asm_descr(self, pool: rowptr[memhub.MemBuddy], node: ast.AST | t.CPtr) -> str: """递归解析约束表达式,返回约束字符串""" if node is None: @@ -1094,7 +1094,7 @@ class CallGenCBuiltin(CallGenBase.CallGenBase): return count + 1 - def translate_c_asm(self, pool: memhub.MemBuddy | t.CPtr, + def translate_c_asm(self, pool: rowptr[memhub.MemBuddy], builder: llvmlite.IRBuilder | t.CPtr, mod: llvmlite.LLVMModule | t.CPtr, cl: ast.Call | t.CPtr, @@ -1724,7 +1724,7 @@ class CallGenCBuiltin(CallGenBase.CallGenBase): return None - def translate_c_llvmir(self, pool: memhub.MemBuddy | t.CPtr, + def translate_c_llvmir(self, pool: rowptr[memhub.MemBuddy], builder: llvmlite.IRBuilder | t.CPtr, mod: llvmlite.LLVMModule | t.CPtr, cl: ast.Call | t.CPtr, diff --git a/App/lib/core/Gen/Call/CallGenCall.vp b/App/lib/core/Gen/Call/CallGenCall.vp index 53ace18..d4c43de 100644 --- a/App/lib/core/Gen/Call/CallGenCall.vp +++ b/App/lib/core/Gen/Call/CallGenCall.vp @@ -9,6 +9,7 @@ import stdlib import viperlib import lib.core.Gen.Translator as HT import lib.core.Gen.GenTypes as GenTypes +import lib.core.Gen.GenApi as GenApi from . import CallGenBase @@ -39,7 +40,7 @@ class CallGenCall(CallGenBase.CallGenBase): # ============================================================ # ============================================================ - def _do_virtual_call(self, pool: memhub.MemBuddy | t.CPtr, + def _do_virtual_call(self, pool: rowptr[memhub.MemBuddy], builder: llvmlite.IRBuilder | t.CPtr, mod: llvmlite.LLVMModule | t.CPtr, class_name: str, @@ -212,7 +213,7 @@ class CallGenCall(CallGenBase.CallGenBase): # ============================================================ # ============================================================ - def _call_method_on_ptr(self, pool: memhub.MemBuddy | t.CPtr, + def _call_method_on_ptr(self, pool: rowptr[memhub.MemBuddy], builder: llvmlite.IRBuilder | t.CPtr, mod: llvmlite.LLVMModule | t.CPtr, class_name: str, @@ -271,9 +272,15 @@ class CallGenCall(CallGenBase.CallGenBase): # fallback: 从 from_imports 查找类所属模块的 SHA1(含截断处理) cls_sha1 = self._lookup_mod_sha1(pool, trans._from_imports, class_name) if cls_sha1 is None: - err_msg: str = pool.alloc(256) + # [D6·截断纪律] 旧实现固定 256 缓冲 + snprintf:类名/方法名超长即被 + # 静默截断 ⇒ 报错文本丢失定位信息。改为按精确长度分配 + # (-4 = 格式串里两个 "%s" 占位符各占 2 字节)。 + msg_fmt: str = "类 '%s' 方法 '%s' 找不到模块 SHA1" + msg_size: sizet = string.strlen(msg_fmt) \ + + string.strlen(class_name) + string.strlen(method_name) - 4 + 1 + err_msg: str = pool.alloc(msg_size) if err_msg is not None: - viperlib.snprintf(err_msg, 256, "类 '%s' 方法 '%s' 找不到模块 SHA1", class_name, method_name) + viperlib.snprintf(err_msg, msg_size, msg_fmt, class_name, method_name) self.Gen.TypeGenErr.fatal_error(node, err_msg) self.Gen.TypeGenErr.fatal_error(node, "找不到模块 SHA1") # 生成调用名: {cls_sha1}.{lookup_name}(Hash Namespace 单前缀) @@ -293,10 +300,12 @@ class CallGenCall(CallGenBase.CallGenBase): elif string.strcmp(method_name, "__getitem__") == 0 or string.strcmp(method_name, "__new__") == 0: # fail-fast:__getitem__/__new__ 必返回指针,返回类型缺失意味着 # stub declare 损坏,静默推断会截断指针(32 位)崩溃,立即终止。 - err_cm1: str = pool.alloc(256) + # [D6·截断纪律] 同上一处:固定 256 → 精确长度(-2 = 一个 "%s") + msg_fmt1: str = "方法 '%s' 返回类型无法确定(stub declare 返回类型缺失)" + msg_size1: sizet = string.strlen(msg_fmt1) + string.strlen(method_name) - 2 + 1 + err_cm1: str = pool.alloc(msg_size1) if err_cm1 is not None: - viperlib.snprintf(err_cm1, 256, - "方法 '%s' 返回类型无法确定(stub declare 返回类型缺失)", method_name) + viperlib.snprintf(err_cm1, msg_size1, msg_fmt1, method_name) self.Gen.TypeGenErr.fatal_error(node, err_cm1) self.Gen.TypeGenErr.fatal_error(node, "方法返回类型无法确定") else: @@ -319,18 +328,21 @@ class CallGenCall(CallGenBase.CallGenBase): if cmop_struct_ty is not None: call_ret_ty = llvmlite.Ptr(pool, cmop_struct_ty) else: - err_cm2: str = pool.alloc(256) + # [D6·截断纪律] 固定 256 → 精确长度(-2 = 一个 "%s") + msg_fmt2: str = "方法 '%s' 的 self 结构体类型未知(字段类型退化,依赖模块未预注册?)" + msg_size2: sizet = string.strlen(msg_fmt2) + string.strlen(method_name) - 2 + 1 + err_cm2: str = pool.alloc(msg_size2) if err_cm2 is not None: - viperlib.snprintf(err_cm2, 256, - "方法 '%s' 的 self 结构体类型未知(字段类型退化,依赖模块未预注册?)", method_name) + viperlib.snprintf(err_cm2, msg_size2, msg_fmt2, method_name) self.Gen.TypeGenErr.fatal_error(node, err_cm2) self.Gen.TypeGenErr.fatal_error(node, "self 结构体类型未知") elif string.strcmp(method_name, "__getitem__") == 0: - err_cm3: str = pool.alloc(256) + # [D6·截断纪律] 固定 256 → 精确长度(-2 = 一个 "%s") + msg_fmt3: str = "方法 '%s.__getitem__' 的 stub declare 未注入(依赖模块 vpi 缺失或拓扑顺序错误),无法确定返回类型" + msg_size3: sizet = string.strlen(msg_fmt3) + string.strlen(class_name) - 2 + 1 + err_cm3: str = pool.alloc(msg_size3) if err_cm3 is not None: - viperlib.snprintf(err_cm3, 256, - "方法 '%s.__getitem__' 的 stub declare 未注入(依赖模块 vpi 缺失或拓扑顺序错误),无法确定返回类型", - class_name) + viperlib.snprintf(err_cm3, msg_size3, msg_fmt3, class_name) self.Gen.TypeGenErr.fatal_error(node, err_cm3) self.Gen.TypeGenErr.fatal_error(node, "__getitem__ stub declare 未注入") else: @@ -675,7 +687,7 @@ class CallGenCall(CallGenBase.CallGenBase): # ============================================================ # ============================================================ - def _translate_method_call(self, pool: memhub.MemBuddy | t.CPtr, + def _translate_method_call(self, pool: rowptr[memhub.MemBuddy], builder: llvmlite.IRBuilder | t.CPtr, mod: llvmlite.LLVMModule | t.CPtr, class_name: str, @@ -977,16 +989,12 @@ class CallGenCall(CallGenBase.CallGenBase): # base_buf_g 可能已带模板模块 SHA1 前缀({tpl}.GSList): # 剥离后再查模板/特化,保证 _find_generic_template 命中裸模板名。 base_clean_g: str = base_buf_g - if base_len_g > 17: - is_sha1_pfx_g: int = 1 - si_g: int - for si_g in range(16): - cg_g: char = base_buf_g[si_g] - if not (('0' <= cg_g <= '9') or ('a' <= cg_g <= 'f')): - is_sha1_pfx_g = 0 - break - if is_sha1_pfx_g != 0 and base_buf_g[16] == '.': - base_clean_g = base_buf_g + 17 + # [C10 收敛] SHA1 前缀判定走唯一真源;切点长度取返回值, + # 不再硬编码 17(旧判据 `base_len_g > 17` 与真源 `>= 17` + # 只差"前缀之后为空串"这一退化形态,一并对齐)。 + base_pfx_g: int = GenApi.sha1_prefix_len(base_buf_g) + if base_pfx_g != 0: + base_clean_g = base_buf_g + sizet(base_pfx_g) spec_name_g: str = self.Gen.ClassGenGeneric._specialize_generic_class( trans, base_clean_g, ta_list_g) if spec_name_g is not None: @@ -1668,7 +1676,7 @@ class CallGenCall(CallGenBase.CallGenBase): # 翻译,绝不生成对 list 方法函数的跨模块调用(list 方法无对应 C 函数)。 # lm_obj 必须是已 load 的 list 对象指针 Ptr(list-struct)。 # ============================================================ - def _translate_list_builtin_call(self, pool: memhub.MemBuddy | t.CPtr, + def _translate_list_builtin_call(self, pool: rowptr[memhub.MemBuddy], builder: llvmlite.IRBuilder | t.CPtr, mod: llvmlite.LLVMModule | t.CPtr, cl: ast.Call | t.CPtr, @@ -1888,7 +1896,7 @@ class CallGenCall(CallGenBase.CallGenBase): # ============================================================ # ============================================================ - def _translate_super_call(self, pool: memhub.MemBuddy | t.CPtr, + def _translate_super_call(self, pool: rowptr[memhub.MemBuddy], builder: llvmlite.IRBuilder | t.CPtr, mod: llvmlite.LLVMModule | t.CPtr, cl: ast.Call | t.CPtr, @@ -2130,7 +2138,7 @@ class CallGenCall(CallGenBase.CallGenBase): # ============================================================ # ============================================================ - def _field_byte_offset(self, pool: memhub.MemBuddy | t.CPtr, + def _field_byte_offset(self, pool: rowptr[memhub.MemBuddy], entry: GenTypes.StructEntry | t.CPtr, field_index: int) -> int: """计算字段在结构体中的字节偏移(含对齐 padding),无法计算返回 0""" diff --git a/App/lib/core/Gen/Call/CallGenCtor.vp b/App/lib/core/Gen/Call/CallGenCtor.vp index 438d55d..3507df1 100644 --- a/App/lib/core/Gen/Call/CallGenCtor.vp +++ b/App/lib/core/Gen/Call/CallGenCtor.vp @@ -32,7 +32,7 @@ class CallGenCtor(CallGenBase.CallGenBase): # 遍历所有字段,对有默认值的字段翻译并 store # 显式参数(位置/关键字)后续会覆盖默认值 # ============================================================ - def _apply_struct_defaults(self, pool: memhub.MemBuddy | t.CPtr, + def _apply_struct_defaults(self, pool: rowptr[memhub.MemBuddy], builder: llvmlite.IRBuilder | t.CPtr, mod: llvmlite.LLVMModule | t.CPtr, struct_ty: llvmlite.LLVMType | t.CPtr, @@ -106,7 +106,7 @@ class CallGenCtor(CallGenBase.CallGenBase): # ============================================================ # ============================================================ - def _translate_struct_ctor(self, pool: memhub.MemBuddy | t.CPtr, + def _translate_struct_ctor(self, pool: rowptr[memhub.MemBuddy], builder: llvmlite.IRBuilder | t.CPtr, mod: llvmlite.LLVMModule | t.CPtr, struct_ty: llvmlite.LLVMType | t.CPtr, @@ -360,7 +360,7 @@ class CallGenCtor(CallGenBase.CallGenBase): # ============================================================ # ============================================================ - def _translate_renum_construct(self, pool: memhub.MemBuddy | t.CPtr, + def _translate_renum_construct(self, pool: rowptr[memhub.MemBuddy], builder: llvmlite.IRBuilder | t.CPtr, mod: llvmlite.LLVMModule | t.CPtr, class_name: str, @@ -462,7 +462,7 @@ class CallGenCtor(CallGenBase.CallGenBase): # ============================================================ # ============================================================ - def _translate_struct_ctor_kw(self, pool: memhub.MemBuddy | t.CPtr, + def _translate_struct_ctor_kw(self, pool: rowptr[memhub.MemBuddy], builder: llvmlite.IRBuilder | t.CPtr, mod: llvmlite.LLVMModule | t.CPtr, struct_ty: llvmlite.LLVMType | t.CPtr, @@ -695,7 +695,7 @@ class CallGenCtor(CallGenBase.CallGenBase): # ============================================================ # ============================================================ - def _translate_t_type_cast(self, pool: memhub.MemBuddy | t.CPtr, + def _translate_t_type_cast(self, pool: rowptr[memhub.MemBuddy], builder: llvmlite.IRBuilder | t.CPtr, val: llvmlite.Value | t.CPtr, target_ty: llvmlite.LLVMType | t.CPtr, @@ -781,7 +781,7 @@ class CallGenCtor(CallGenBase.CallGenBase): # _get_type_name_from_annotation 已移至 HandlesType.py(支持 BinOp/Attribute) # HandlesExprCall 通过 HandlesType._get_type_name_from_annotation 调用 - def _extract_type_args_from_slice(self, pool: memhub.MemBuddy | t.CPtr, + def _extract_type_args_from_slice(self, pool: rowptr[memhub.MemBuddy], slice_node: ast.AST | t.CPtr, from_imports: str = None) -> list[str] | t.CPtr: """从 Subscript.slice 提取类型实参名列表 @@ -837,7 +837,7 @@ class CallGenCtor(CallGenBase.CallGenBase): # ============================================================ # ============================================================ - def _infer_generic_ctor_type_arg(self, pool: memhub.MemBuddy | t.CPtr, + def _infer_generic_ctor_type_arg(self, pool: rowptr[memhub.MemBuddy], arg_node: ast.AST | t.CPtr, class_name: str) -> str: """从构造实参 AST 推断泛型类型实参名;无法推断时 fail-fast(绝不默认 "int") @@ -908,7 +908,7 @@ class CallGenCtor(CallGenBase.CallGenBase): # 的 pool 参数):不是 T 类型提示,返回默认 "int"(调用方"过滤纯 int" # 逻辑将其排除,只保留 float/str 等区分性提示)。 return "int" - def _translate_generic_ctor_call(self, pool: memhub.MemBuddy | t.CPtr, + def _translate_generic_ctor_call(self, pool: rowptr[memhub.MemBuddy], builder: llvmlite.IRBuilder | t.CPtr, mod: llvmlite.LLVMModule | t.CPtr, spec_name: str, diff --git a/App/lib/core/Gen/Call/CallGenDispatch.vp b/App/lib/core/Gen/Call/CallGenDispatch.vp index 79eab10..74d9bf2 100644 --- a/App/lib/core/Gen/Call/CallGenDispatch.vp +++ b/App/lib/core/Gen/Call/CallGenDispatch.vp @@ -14,7 +14,7 @@ import sys import viperlib import w32.fileio as fileio import lib.core.VLogger as VLogger -import lib.core.Gen.Translator as HT +import lib.core.Gen.Translator as HT import lib.core.Gen.Type.TypeSpec as TSpec import lib.Stub.StubMerger as StubMerger import lib.core.CompilerFactory as CompilerFactory @@ -33,7 +33,7 @@ import lib.core.Gen.GenApi as GenApi class CallGenDispatch(CallGenBase.CallGenBase): """translate_call 前置检测 helper(继承 Base)""" - def _tc_h1_super_ctraits(self, pool: memhub.MemBuddy | t.CPtr, + def _tc_h1_super_ctraits(self, pool: rowptr[memhub.MemBuddy], builder: llvmlite.IRBuilder | t.CPtr, mod: llvmlite.LLVMModule | t.CPtr, cl: ast.Call | t.CPtr, @@ -89,7 +89,7 @@ class CallGenDispatch(CallGenBase.CallGenBase): return llvmlite.const_int32(pool, 0) return None - def _tc_h2_c_special(self, pool: memhub.MemBuddy | t.CPtr, + def _tc_h2_c_special(self, pool: rowptr[memhub.MemBuddy], builder: llvmlite.IRBuilder | t.CPtr, mod: llvmlite.LLVMModule | t.CPtr, cl: ast.Call | t.CPtr, @@ -193,7 +193,7 @@ class CallGenDispatch(CallGenBase.CallGenBase): builder, pool, mod, cl, trans) return None - def _tc_h3_stdarg_cast(self, pool: memhub.MemBuddy | t.CPtr, + def _tc_h3_stdarg_cast(self, pool: rowptr[memhub.MemBuddy], builder: llvmlite.IRBuilder | t.CPtr, mod: llvmlite.LLVMModule | t.CPtr, cl: ast.Call | t.CPtr, @@ -282,7 +282,7 @@ class CallGenDispatch(CallGenBase.CallGenBase): return None return None - def _tc_h4_type_casts(self, pool: memhub.MemBuddy | t.CPtr, + def _tc_h4_type_casts(self, pool: rowptr[memhub.MemBuddy], builder: llvmlite.IRBuilder | t.CPtr, mod: llvmlite.LLVMModule | t.CPtr, cl: ast.Call | t.CPtr, @@ -550,7 +550,7 @@ class CallGenDispatch(CallGenBase.CallGenBase): return None - def _tc_h5_sizeof_len_isinst(self, pool: memhub.MemBuddy | t.CPtr, + def _tc_h5_sizeof_len_isinst(self, pool: rowptr[memhub.MemBuddy], builder: llvmlite.IRBuilder | t.CPtr, mod: llvmlite.LLVMModule | t.CPtr, cl: ast.Call | t.CPtr, @@ -1000,7 +1000,7 @@ class CallGenDispatch(CallGenBase.CallGenBase): return None - def _tc_h6_method_dispatch(self, pool: memhub.MemBuddy | t.CPtr, + def _tc_h6_method_dispatch(self, pool: rowptr[memhub.MemBuddy], builder: llvmlite.IRBuilder | t.CPtr, mod: llvmlite.LLVMModule | t.CPtr, cl: ast.Call | t.CPtr, diff --git a/App/lib/core/Gen/Call/CallGenFd.vp b/App/lib/core/Gen/Call/CallGenFd.vp index bc6cdf1..2f5bd14 100644 --- a/App/lib/core/Gen/Call/CallGenFd.vp +++ b/App/lib/core/Gen/Call/CallGenFd.vp @@ -34,7 +34,7 @@ class CallGenFd(CallGenBase.CallGenBase): # ============================================================ # ============================================================ - def _translate_fakeduck_call(self, pool: memhub.MemBuddy | t.CPtr, + def _translate_fakeduck_call(self, pool: rowptr[memhub.MemBuddy], builder: llvmlite.IRBuilder | t.CPtr, mod: llvmlite.LLVMModule | t.CPtr, cls_name: str, @@ -199,7 +199,7 @@ class CallGenFd(CallGenBase.CallGenBase): # ============================================================ def _inject_requires_fields(self, trans: HT.Translator | t.CPtr, - pool: memhub.MemBuddy | t.CPtr, + pool: rowptr[memhub.MemBuddy], builder: llvmlite.IRBuilder | t.CPtr, mod: llvmlite.LLVMModule | t.CPtr, meta_ptr: llvmlite.Value | t.CPtr, @@ -310,7 +310,7 @@ class CallGenFd(CallGenBase.CallGenBase): # ============================================================ def _emit_provider_push(self, trans: HT.Translator | t.CPtr, - pool: memhub.MemBuddy | t.CPtr, + pool: rowptr[memhub.MemBuddy], builder: llvmlite.IRBuilder | t.CPtr, mod: llvmlite.LLVMModule | t.CPtr, cls_name: str, @@ -363,7 +363,7 @@ class CallGenFd(CallGenBase.CallGenBase): llvmlite.build_call(builder, fd_pfn, fd_fstr, 2, ret_i32_p, 0) return fd_pc def _emit_provider_pop(self, trans: HT.Translator | t.CPtr, - pool: memhub.MemBuddy | t.CPtr, + pool: rowptr[memhub.MemBuddy], builder: llvmlite.IRBuilder | t.CPtr, mod: llvmlite.LLVMModule | t.CPtr, cls_name: str) -> int: diff --git a/App/lib/core/Gen/Call/CallGenLeafKit.vp b/App/lib/core/Gen/Call/CallGenLeafKit.vp index b3eed92..ea46bc6 100644 --- a/App/lib/core/Gen/Call/CallGenLeafKit.vp +++ b/App/lib/core/Gen/Call/CallGenLeafKit.vp @@ -10,7 +10,7 @@ import viperlib import lib.core.VLogger as VLogger import lib.core.Gen.GenApi as GenApi import lib.core.Gen.Translator as HT -import lib.core.CompilerFactory as CompilerFactory +import lib.core.CompilerFactory as CompilerFactory import lib.core.Gen.Type.TypeSpec as TSpec from . import CallGenCBuiltin @@ -94,7 +94,7 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin): # ============================================================ def _emit_eh_guarded_call(self, builder: llvmlite.IRBuilder | t.CPtr, - pool: memhub.MemBuddy | t.CPtr, + pool: rowptr[memhub.MemBuddy], mod: llvmlite.LLVMModule | t.CPtr, trans: HT.Translator | t.CPtr, func: llvmlite.Function | t.CPtr, @@ -218,7 +218,7 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin): - def _translate_isinstance(self, pool: memhub.MemBuddy | t.CPtr, + def _translate_isinstance(self, pool: rowptr[memhub.MemBuddy], builder: llvmlite.IRBuilder | t.CPtr, mod: llvmlite.LLVMModule | t.CPtr, obj_node: ast.AST | t.CPtr, @@ -303,7 +303,7 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin): return res - def _extract_isinstance_class_names(self, pool: memhub.MemBuddy | t.CPtr, + def _extract_isinstance_class_names(self, pool: rowptr[memhub.MemBuddy], node: ast.AST | t.CPtr) -> sizet | t.CPtr: """从 isinstance 第二参数提取类名数组(Name→id / Attribute→attr / Tuple→遍历)""" arr: sizet | t.CPtr = pool.alloc(8 * 16) @@ -351,7 +351,7 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin): return arr - def _collect_subclass_vtable_classes(self, pool: memhub.MemBuddy | t.CPtr, + def _collect_subclass_vtable_classes(self, pool: rowptr[memhub.MemBuddy], class_name: str) -> sizet | t.CPtr: """反向 BFS 收集目标类及全部子类(含自身,仅 HasVTable==1),返回 0 结尾数组""" if class_name is None: @@ -413,7 +413,7 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin): return names - def _make_vtable_ref_i8(self, pool: memhub.MemBuddy | t.CPtr, + def _make_vtable_ref_i8(self, pool: rowptr[memhub.MemBuddy], builder: llvmlite.IRBuilder | t.CPtr, mod: llvmlite.LLVMModule | t.CPtr, class_name: str, @@ -460,7 +460,7 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin): return llvmlite.build_bitcast(builder, ref, i8_ptr_ty) - def _isinstance_compile_time(self, pool: memhub.MemBuddy | t.CPtr, + def _isinstance_compile_time(self, pool: rowptr[memhub.MemBuddy], obj_ptr: llvmlite.Value | t.CPtr, class_name: str) -> int: """编译时静态判断:obj 静态类型 == class_name 或 class_name 在其 MRO 中""" @@ -492,7 +492,7 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin): - def translate_closure_call(self, pool: memhub.MemBuddy | t.CPtr, + def translate_closure_call(self, pool: rowptr[memhub.MemBuddy], builder: llvmlite.IRBuilder | t.CPtr, mod: llvmlite.LLVMModule | t.CPtr, closure_alloca: llvmlite.Value | t.CPtr, @@ -666,7 +666,7 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin): return None - def _translate_func_ptr_call(self, pool: memhub.MemBuddy | t.CPtr, + def _translate_func_ptr_call(self, pool: rowptr[memhub.MemBuddy], builder: llvmlite.IRBuilder | t.CPtr, mod: llvmlite.LLVMModule | t.CPtr, fp_alloca: llvmlite.Value | t.CPtr, @@ -741,7 +741,7 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin): return llvmlite.build_call_indirect(builder, fn_typed, head, arg_count, ret_ty) - def translate_printf_call(self, pool: memhub.MemBuddy | t.CPtr, + def translate_printf_call(self, pool: rowptr[memhub.MemBuddy], builder: llvmlite.IRBuilder | t.CPtr, mod: llvmlite.LLVMModule | t.CPtr, cl: ast.Call | t.CPtr, @@ -802,7 +802,7 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin): llvmlite.build_call(builder, "printf", fmt_ptr, can, i32_ty, 1) - def translate_print_call(self, pool: memhub.MemBuddy | t.CPtr, + def translate_print_call(self, pool: rowptr[memhub.MemBuddy], builder: llvmlite.IRBuilder | t.CPtr, mod: llvmlite.LLVMModule | t.CPtr, cl: ast.Call | t.CPtr, @@ -935,7 +935,7 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin): llvmlite.build_call(builder, "printf", fmt_ptr, arg_count, i32_ty, 1) - def init_func_table(self, pool: memhub.MemBuddy | t.CPtr, + def init_func_table(self, pool: rowptr[memhub.MemBuddy], max_count: int) -> GenTypes.FuncEntry | t.CPtr: """分配并清零函数表数组""" size: sizet = max_count * GenTypes.FuncEntry.__sizeof__() @@ -995,7 +995,7 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin): defaults: t.CPtr = None, default_count: int = 0, param_count: int = 0, - pool: memhub.MemBuddy | t.CPtr = None, + pool: rowptr[memhub.MemBuddy] = None, def_sha1: str = None) -> int: """添加函数到函数表,返回 0 成功 @@ -1041,7 +1041,7 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin): def _register_global_func(self, name: str, func: llvmlite.Function | t.CPtr, - pool: memhub.MemBuddy | t.CPtr = None) -> int: + pool: rowptr[memhub.MemBuddy] = None) -> int: """注册函数到全局表(已存在则跳过),返回 0 成功 直接操作全局表,不调用 add_func_to_table,避免递归。 @@ -1142,9 +1142,9 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin): slot[0] = sizet(ps) cur = llvmlite.param_get_next(cur) i += 1 - return TSpec.NewTypeFunc(arena, ret_s, params_arr, cnt, func.IsVarArg) - - + return TSpec.NewTypeFunc(arena, ret_s, params_arr, cnt, func.IsVarArg) + + def find_func_global(self, name: str) -> llvmlite.Function | t.CPtr: """在全局函数表中按名称查找,返回 Function 指针或 None""" if name is None or self.GlobalFuncs is None: @@ -1327,7 +1327,7 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin): return None - def _build_const_from_snapshot(self, pool: memhub.MemBuddy | t.CPtr, + def _build_const_from_snapshot(self, pool: rowptr[memhub.MemBuddy], mod: llvmlite.LLVMModule | t.CPtr, gd_entry: GenTypes.FuncDefaultsEntry | t.CPtr, di: int, @@ -1409,7 +1409,7 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin): return None - def NewExprCallHandle(self, pool: memhub.MemBuddy | t.CPtr, + def NewExprCallHandle(self, pool: rowptr[memhub.MemBuddy], trans: HT.Translator | t.CPtr) -> ExprCallHandle | t.CPtr: h: ExprCallHandle | t.CPtr = pool.alloc(ExprCallHandle.__sizeof__()) if h is None: diff --git a/App/lib/core/Gen/Call/CallGenLib.vp b/App/lib/core/Gen/Call/CallGenLib.vp index b3fedd4..62a2378 100644 --- a/App/lib/core/Gen/Call/CallGenLib.vp +++ b/App/lib/core/Gen/Call/CallGenLib.vp @@ -23,7 +23,7 @@ from . import CallGenBase class CallGenLib(CallGenBase.CallGenBase): """C 库声明 / 返回类型推断 / kwargs 调用辅助(继承 Base)""" - def _ensure_c_lib_declare(self, pool: memhub.MemBuddy | t.CPtr, + def _ensure_c_lib_declare(self, pool: rowptr[memhub.MemBuddy], mod: llvmlite.LLVMModule | t.CPtr, name: str) -> llvmlite.Function | t.CPtr: """为已知的 C 库函数创建 declare 声明""" @@ -112,7 +112,7 @@ class CallGenLib(CallGenBase.CallGenBase): llvmlite.add_param(pool, fn, i64_ty, "n") return fn - def _promote_clib_call_args(self, pool: memhub.MemBuddy | t.CPtr, + def _promote_clib_call_args(self, pool: rowptr[memhub.MemBuddy], builder: llvmlite.IRBuilder | t.CPtr, mod: llvmlite.LLVMModule | t.CPtr, call_name: str, @@ -209,7 +209,7 @@ class CallGenLib(CallGenBase.CallGenBase): # 裸名 C 库函数由 _promote_clib_call_args 与 _ensure_c_lib_declare 标准 # 签名处理。未命中/不可解原样保留(不兜底改型)。 # ============================================================ - def _coerce_args_to_def_params(self, pool: memhub.MemBuddy | t.CPtr, + def _coerce_args_to_def_params(self, pool: rowptr[memhub.MemBuddy], builder: llvmlite.IRBuilder | t.CPtr, call_name: str, head: llvmlite.Value | t.CPtr, @@ -296,7 +296,7 @@ class CallGenLib(CallGenBase.CallGenBase): # 则原样保留(避免把 list*/Struct* 无谓降级为 i8* 的 IR 噪声)。 # 其它(结构体值/void 等)→ 原样保留。不可转换亦原样返回(不兜底改型)。 # ============================================================ - def _coerce_arg_value_to_ty(self, pool: memhub.MemBuddy | t.CPtr, + def _coerce_arg_value_to_ty(self, pool: rowptr[memhub.MemBuddy], builder: llvmlite.IRBuilder | t.CPtr, val: llvmlite.Value | t.CPtr, tgt_ty: llvmlite.LLVMType | t.CPtr) -> llvmlite.Value | t.CPtr: @@ -379,7 +379,7 @@ class CallGenLib(CallGenBase.CallGenBase): pass return val - def _infer_external_func_ret_ty(self, pool: memhub.MemBuddy | t.CPtr, + def _infer_external_func_ret_ty(self, pool: rowptr[memhub.MemBuddy], func_name: str, node: ast.AST | t.CPtr, fatal_if_unknown: int) -> llvmlite.LLVMType | t.CPtr: @@ -584,7 +584,7 @@ class CallGenLib(CallGenBase.CallGenBase): f"外部函数返回类型未登记且无法收敛推断(默认 i32 会截断指针/i64,需提供 stub 声明或加入白名单): {func_name}", "TypeError") return llvmlite.Int32(pool) - def _get_external_func_param_ty(self, pool: memhub.MemBuddy | t.CPtr, + def _get_external_func_param_ty(self, pool: rowptr[memhub.MemBuddy], func_name: str, param_idx: int) -> llvmlite.LLVMType | t.CPtr: """获取外部函数第 param_idx 个参数的期望类型,None 表示用字面量原类型 @@ -656,7 +656,7 @@ class CallGenLib(CallGenBase.CallGenBase): if ch < 65 or ch > 70: return 0 return 1 - def _emit_llvm_memcpy_intrinsic(self, pool: memhub.MemBuddy | t.CPtr, + def _emit_llvm_memcpy_intrinsic(self, pool: rowptr[memhub.MemBuddy], builder: llvmlite.IRBuilder | t.CPtr, mod: llvmlite.LLVMModule | t.CPtr, dst_val: llvmlite.Value | t.CPtr, @@ -756,7 +756,7 @@ class CallGenLib(CallGenBase.CallGenBase): # ============================================================ # ============================================================ - def _translate_call_with_kwargs(self, pool: memhub.MemBuddy | t.CPtr, + def _translate_call_with_kwargs(self, pool: rowptr[memhub.MemBuddy], builder: llvmlite.IRBuilder | t.CPtr, mod: llvmlite.LLVMModule | t.CPtr, func_name: str, diff --git a/App/lib/core/Gen/Call/CallGenMixin.vp b/App/lib/core/Gen/Call/CallGenMixin.vp index ca81ebd..6a468ca 100644 --- a/App/lib/core/Gen/Call/CallGenMixin.vp +++ b/App/lib/core/Gen/Call/CallGenMixin.vp @@ -9,7 +9,7 @@ import stdio import stdlib import viperlib import lib.core.VLogger as VLogger -import lib.core.Gen.Translator as HT +import lib.core.Gen.Translator as HT import lib.core.Gen.Type.TypeSpec as TSpec import lib.Stub.StubGen.VpiReader as VpiReader @@ -61,7 +61,7 @@ class CallGenMixin(CallGenBase.CallGenBase): # ============================================================ # 翻译函数调用 Call(func, args) — 模块级版本 # ============================================================ - def translate_call(self, pool: memhub.MemBuddy | t.CPtr, + def translate_call(self, pool: rowptr[memhub.MemBuddy], builder: llvmlite.IRBuilder | t.CPtr, mod: llvmlite.LLVMModule | t.CPtr, node: ast.AST | t.CPtr, diff --git a/App/lib/core/Gen/Call/CallGenProp.vp b/App/lib/core/Gen/Call/CallGenProp.vp index 7e1485f..dace6f4 100644 --- a/App/lib/core/Gen/Call/CallGenProp.vp +++ b/App/lib/core/Gen/Call/CallGenProp.vp @@ -48,7 +48,7 @@ class CallGenProp(CallGenBase.CallGenBase): # # call_head/call_count: 已构建好的参数链表(如 getter 只有 obj 一个参数) # ============================================================ - def _translate_property_call(self, pool: memhub.MemBuddy | t.CPtr, + def _translate_property_call(self, pool: rowptr[memhub.MemBuddy], builder: llvmlite.IRBuilder | t.CPtr, mod: llvmlite.LLVMModule | t.CPtr, class_name: str, @@ -172,7 +172,7 @@ class CallGenProp(CallGenBase.CallGenBase): # ============================================================ # ============================================================ - def _resolve_obj_class_name(self, pool: memhub.MemBuddy | t.CPtr, + def _resolve_obj_class_name(self, pool: rowptr[memhub.MemBuddy], trans: HT.Translator | t.CPtr, obj_node: ast.AST | t.CPtr) -> str: """解析对象表达式的类名(短名),失败返回 None""" @@ -198,7 +198,7 @@ class CallGenProp(CallGenBase.CallGenBase): # ============================================================ # ============================================================ - def _try_property_getter_attr(self, pool: memhub.MemBuddy | t.CPtr, + def _try_property_getter_attr(self, pool: rowptr[memhub.MemBuddy], builder: llvmlite.IRBuilder | t.CPtr, mod: llvmlite.LLVMModule | t.CPtr, at_node: ast.Attribute | t.CPtr, @@ -231,7 +231,7 @@ class CallGenProp(CallGenBase.CallGenBase): # ============================================================ # ============================================================ - def _try_property_setter(self, pool: memhub.MemBuddy | t.CPtr, + def _try_property_setter(self, pool: rowptr[memhub.MemBuddy], builder: llvmlite.IRBuilder | t.CPtr, mod: llvmlite.LLVMModule | t.CPtr, target_attr: ast.Attribute | t.CPtr, @@ -273,7 +273,7 @@ class CallGenProp(CallGenBase.CallGenBase): # ============================================================ # ============================================================ - def _try_property_deleter(self, pool: memhub.MemBuddy | t.CPtr, + def _try_property_deleter(self, pool: rowptr[memhub.MemBuddy], builder: llvmlite.IRBuilder | t.CPtr, mod: llvmlite.LLVMModule | t.CPtr, target_attr: ast.Attribute | t.CPtr, @@ -311,7 +311,7 @@ class CallGenProp(CallGenBase.CallGenBase): # ============================================================ # ============================================================ - def _translate_static_class_call(self, pool: memhub.MemBuddy | t.CPtr, + def _translate_static_class_call(self, pool: rowptr[memhub.MemBuddy], builder: llvmlite.IRBuilder | t.CPtr, mod: llvmlite.LLVMModule | t.CPtr, class_name: str, diff --git a/App/lib/core/Gen/Call/CallGenVa.vp b/App/lib/core/Gen/Call/CallGenVa.vp index 0ddee6b..0b5fd5d 100644 --- a/App/lib/core/Gen/Call/CallGenVa.vp +++ b/App/lib/core/Gen/Call/CallGenVa.vp @@ -27,7 +27,7 @@ class CallGenVa(CallGenBase.CallGenBase): # _translate_method 在含 raise 的函数签名末尾注入(main 除外)。 # ============================================================ - def _va_arg_get_alloca_ptr(self, pool: memhub.MemBuddy | t.CPtr, + def _va_arg_get_alloca_ptr(self, pool: rowptr[memhub.MemBuddy], builder: llvmlite.IRBuilder | t.CPtr, mod: llvmlite.LLVMModule | t.CPtr, arg_node: ast.AST | t.CPtr, @@ -51,7 +51,7 @@ class CallGenVa(CallGenBase.CallGenBase): return alloca # 回退:translate_value(可能返回 load 后的值,仅适用于已是指针的情况) return self.Gen.ExprGen.translate_value(builder, pool, mod, arg_node, funcs_ptr, func_count, trans) - def _resolve_va_arg_type(self, pool: memhub.MemBuddy | t.CPtr, + def _resolve_va_arg_type(self, pool: rowptr[memhub.MemBuddy], type_node: ast.AST | t.CPtr, trans: HT.Translator | t.CPtr) -> llvmlite.LLVMType | t.CPtr: """解析 va_arg/arg 的类型参数为 LLVMType @@ -74,7 +74,7 @@ class CallGenVa(CallGenBase.CallGenBase): # 类型节点存在但解析失败:fail-fast,绝不回退 i32(会按错宽度读变参槽位) self.Gen.TypeGenErr.fatal_error(type_node, "va_arg 类型解析失败", "TypeError") return llvmlite.Int32(pool) - def _translate_va_arg_sugar(self, pool: memhub.MemBuddy | t.CPtr, + def _translate_va_arg_sugar(self, pool: rowptr[memhub.MemBuddy], builder: llvmlite.IRBuilder | t.CPtr, mod: llvmlite.LLVMModule | t.CPtr, cl: ast.Call | t.CPtr, @@ -122,7 +122,7 @@ class CallGenVa(CallGenBase.CallGenBase): # 生成 va_arg 指令 return llvmlite.build_va_arg(builder, ap_ptr, read_ty) - def _translate_arg_sugar(self, pool: memhub.MemBuddy | t.CPtr, + def _translate_arg_sugar(self, pool: rowptr[memhub.MemBuddy], builder: llvmlite.IRBuilder | t.CPtr, mod: llvmlite.LLVMModule | t.CPtr, cl: ast.Call | t.CPtr, @@ -158,7 +158,7 @@ class CallGenVa(CallGenBase.CallGenBase): # 生成 va_arg 指令(使用 trans._va_list_ptr 作为 va_list 地址) return llvmlite.build_va_arg(builder, trans._va_list_ptr, read_ty) - def _translate_va_start_sugar(self, pool: memhub.MemBuddy | t.CPtr, + def _translate_va_start_sugar(self, pool: rowptr[memhub.MemBuddy], builder: llvmlite.IRBuilder | t.CPtr, mod: llvmlite.LLVMModule | t.CPtr, cargs: list[ast.AST | t.CPtr] | t.CPtr, @@ -190,7 +190,7 @@ class CallGenVa(CallGenBase.CallGenBase): void_ty_vs: llvmlite.LLVMType | t.CPtr = llvmlite.Void(pool) llvmlite.build_call(builder, "llvm.va_start", ap_i8, 1, void_ty_vs, 0) return llvmlite.const_int32(pool, 0) - def _translate_va_end_sugar(self, pool: memhub.MemBuddy | t.CPtr, + def _translate_va_end_sugar(self, pool: rowptr[memhub.MemBuddy], builder: llvmlite.IRBuilder | t.CPtr, mod: llvmlite.LLVMModule | t.CPtr, cargs: list[ast.AST | t.CPtr] | t.CPtr, @@ -250,7 +250,7 @@ class CallGenVa(CallGenBase.CallGenBase): return 2 return -1 - def _get_known_vararg_cfunc_param_ty(self, pool: memhub.MemBuddy | t.CPtr, + def _get_known_vararg_cfunc_param_ty(self, pool: rowptr[memhub.MemBuddy], name: str, idx: int) -> llvmlite.LLVMType | t.CPtr: """已知变参 C 库函数第 idx 个固定参数类型(变参位置/未知返回 None) @@ -276,7 +276,7 @@ class CallGenVa(CallGenBase.CallGenBase): return i8_ptr_kv return None return None - def _check_and_promote_variadic_call(self, pool: memhub.MemBuddy | t.CPtr, + def _check_and_promote_variadic_call(self, pool: rowptr[memhub.MemBuddy], builder: llvmlite.IRBuilder | t.CPtr, mod: llvmlite.LLVMModule | t.CPtr, call_name: str, diff --git a/App/lib/core/Gen/Call/CallGenVt.vp b/App/lib/core/Gen/Call/CallGenVt.vp index 9eff0bd..ca8271f 100644 --- a/App/lib/core/Gen/Call/CallGenVt.vp +++ b/App/lib/core/Gen/Call/CallGenVt.vp @@ -36,7 +36,7 @@ class CallGenVt(CallGenBase.CallGenBase): # ============================================================ # ============================================================ - def _write_vtable_slot(self, pool: memhub.MemBuddy | t.CPtr, + def _write_vtable_slot(self, pool: rowptr[memhub.MemBuddy], builder: llvmlite.IRBuilder | t.CPtr, mod: llvmlite.LLVMModule | t.CPtr, obj_ptr: llvmlite.Value | t.CPtr, @@ -173,7 +173,7 @@ class CallGenVt(CallGenBase.CallGenBase): llvmlite.build_store(builder, fptr_i8, vt_slotp) return 1 def _write_vtable_attr(self, builder: llvmlite.IRBuilder | t.CPtr, - pool: memhub.MemBuddy | t.CPtr, + pool: rowptr[memhub.MemBuddy], mod: llvmlite.LLVMModule | t.CPtr, node: ast.AST | t.CPtr, rhs_val: llvmlite.Value | t.CPtr, diff --git a/App/lib/core/Gen/Class/ClassGenBase.vp b/App/lib/core/Gen/Class/ClassGenBase.vp index 6d1d8dd..412bf70 100644 --- a/App/lib/core/Gen/Class/ClassGenBase.vp +++ b/App/lib/core/Gen/Class/ClassGenBase.vp @@ -494,7 +494,7 @@ class ClassGenBase: elif string.strcmp(at.attr, "deleter") == 0: meta |= GenTypes.META_PROP_DELETER return meta - def register_class_meta(self, pool: memhub.MemBuddy | t.CPtr, + def register_class_meta(self, pool: rowptr[memhub.MemBuddy], kind: int, cls: str, field: str) -> int: """注册类编译期元数据字段(__provides__/__requires__/__require_must__,幂等)""" if pool is None or cls is None or field is None: @@ -547,7 +547,7 @@ class ClassGenBase: return self.ClassMetaFields + i * 64 n_cm2 += 1 return None - def register_decorator(self, pool: memhub.MemBuddy | t.CPtr, + def register_decorator(self, pool: rowptr[memhub.MemBuddy], func_name: str, wrapper_name: str, arg0: int64) -> int: """注册自定义装饰器函数(@log/@skip/@repeat(3) → __decor_wrap_{name}) @@ -608,7 +608,7 @@ class ClassGenBase: """懒初始化异常表(perm_pool),返回 0 成功""" if self.ExceptionNames is not None: return 0 - pp_e: memhub.MemBuddy | t.CPtr = CompilerFactory.factory.PermPool + pp_e: rowptr[memhub.MemBuddy] = CompilerFactory.factory.PermPool if pp_e is None: return -1 self.ExceptionNames = pp_e.alloc(EXCEPTION_MAX * EXCEPTION_NAME_LEN) @@ -787,7 +787,7 @@ class ClassGenBase: parent_e: str = self._get_exception_parent_name(cd) self.register_exception(cd.name, parent_e) return 0 - def _register_class_meta_list(self, pool: memhub.MemBuddy | t.CPtr, + def _register_class_meta_list(self, pool: rowptr[memhub.MemBuddy], kind: int, cls: str, value_node: ast.AST | t.CPtr) -> None: """解析类体 __provides__/__requires__ 的 list[str] 字面量并注册""" if value_node is None or cls is None: @@ -905,7 +905,7 @@ class ClassGenBase: return 1 return 0 def _get_base_name(self, base_node: ast.AST | t.CPtr, - pool: memhub.MemBuddy | t.CPtr = None) -> str: + pool: rowptr[memhub.MemBuddy] = None) -> str: """从 base AST 节点提取基类名,返回 None=失败 对于 Subscript 节点,需要 pool 分配内存拼接特化名; @@ -962,7 +962,7 @@ class ClassGenBase: """获取 ClassDef 的真实父类名,返回 None=无真实父类""" if cd is None or cd.bases is None: return None - pool: memhub.MemBuddy | t.CPtr = None + pool: rowptr[memhub.MemBuddy] = None if trans is not None: pool = trans.Pool bases: list[ast.AST | t.CPtr] | t.CPtr = cd.bases @@ -1011,7 +1011,7 @@ class ClassGenBase: og_buf[og_len] = '\0' return og_buf return base_name - def _collect_parents(self, pool: memhub.MemBuddy | t.CPtr, + def _collect_parents(self, pool: rowptr[memhub.MemBuddy], cd: ast.ClassDef | t.CPtr, parents_buf: sizet | t.CPtr, max_parents: int, @@ -1065,7 +1065,7 @@ class ClassGenBase: """触发 base 中 Subscript 的泛型特化(如 GSListNode[Value])""" if trans is None or cd is None or cd.bases is None: return - pool: memhub.MemBuddy | t.CPtr = trans.Pool + pool: rowptr[memhub.MemBuddy] = trans.Pool bases: list[ast.AST | t.CPtr] | t.CPtr = cd.bases bn: sizet = len(bases) if bn == 0: diff --git a/App/lib/core/Gen/Class/ClassGenDef.vp b/App/lib/core/Gen/Class/ClassGenDef.vp index 21dceed..53c1598 100644 --- a/App/lib/core/Gen/Class/ClassGenDef.vp +++ b/App/lib/core/Gen/Class/ClassGenDef.vp @@ -38,7 +38,7 @@ class ClassGenDef(ClassGenBase.ClassGenBase): if cd is None or cd.name is None: return 0 - pool: memhub.MemBuddy | t.CPtr = trans.Pool + pool: rowptr[memhub.MemBuddy] = trans.Pool class_name: str = cd.name if trans.ModuleSha1 is None: diff --git a/App/lib/core/Gen/Class/ClassGenEnum.vp b/App/lib/core/Gen/Class/ClassGenEnum.vp index eb438f0..2dfaa2a 100644 --- a/App/lib/core/Gen/Class/ClassGenEnum.vp +++ b/App/lib/core/Gen/Class/ClassGenEnum.vp @@ -35,7 +35,7 @@ RENUM_ALIAS_MAX: t.CDefine = 512 class ClassGenEnum(ClassGenBase.ClassGenBase): """enum/union/renum 定义与变体表""" - def _resolve_enum_member_type(self, pool: memhub.MemBuddy | t.CPtr, + def _resolve_enum_member_type(self, pool: rowptr[memhub.MemBuddy], ann_node: ast.AST | t.CPtr, imported_modules: str, from_imports: str) -> llvmlite.LLVMType | t.CPtr: @@ -152,7 +152,7 @@ class ClassGenEnum(ClassGenBase.ClassGenBase): if cd is None or cd.name is None or trans is None: return 0 - pool: memhub.MemBuddy | t.CPtr = trans.Pool + pool: rowptr[memhub.MemBuddy] = trans.Pool class_name: str = cd.name # 不按全局同名跳过:跨模块可能同名枚举(includes/w32/fileio.vp 的 @@ -399,7 +399,7 @@ class ClassGenEnum(ClassGenBase.ClassGenBase): if cd is None or cd.name is None or trans is None: return 0 - pool: memhub.MemBuddy | t.CPtr = trans.Pool + pool: rowptr[memhub.MemBuddy] = trans.Pool class_name: str = cd.name # 命名空间隔离:标记为当前文件可见(必须在 existing 检查之前) @@ -553,7 +553,7 @@ class ClassGenEnum(ClassGenBase.ClassGenBase): VLogger.info(f"registered {class_name} with {field_count} fields, max_size={max_size}", "UNION") return 0 - def _get_annotation_field_size(self, pool: memhub.MemBuddy | t.CPtr, + def _get_annotation_field_size(self, pool: rowptr[memhub.MemBuddy], annotation: ast.AST | t.CPtr) -> int: """计算注解类型的字节大小,用于 REnum 布局计算""" if annotation is None: @@ -623,7 +623,7 @@ class ClassGenEnum(ClassGenBase.ClassGenBase): if cd is None or cd.name is None or trans is None: return 0 - pool: memhub.MemBuddy | t.CPtr = trans.Pool + pool: rowptr[memhub.MemBuddy] = trans.Pool class_name: str = cd.name # 命名空间隔离:标记为当前文件可见 @@ -827,7 +827,7 @@ class ClassGenEnum(ClassGenBase.ClassGenBase): VLogger.info(f"registered {class_name} with {variant_count} variants, {total_positions} positions", "RENUM") return 0 def _refill_renum_field_types(self, trans: HT.Translator | t.CPtr, - pool: memhub.MemBuddy | t.CPtr, + pool: rowptr[memhub.MemBuddy], class_name: str, cd: ast.ClassDef | t.CPtr): """REnum 注册完成后补解析变体字段类型(仅回填类型槽为 0 的别名记录) @@ -892,7 +892,7 @@ class ClassGenEnum(ClassGenBase.ClassGenBase): pool, class_name, vnm.id, field_idx + 1, mem_ty_l, variant_cd.name) field_idx += 1 - def _register_renum_variants(self, pool: memhub.MemBuddy | t.CPtr, + def _register_renum_variants(self, pool: rowptr[memhub.MemBuddy], class_name: str, cd: ast.ClassDef | t.CPtr, variant_count: int): @@ -1022,7 +1022,7 @@ class ClassGenEnum(ClassGenBase.ClassGenBase): return self.RenumVariantTags[name_offset] return -1 return -1 - def _register_renum_field_alias(self, pool: memhub.MemBuddy | t.CPtr, + def _register_renum_field_alias(self, pool: rowptr[memhub.MemBuddy], class_name: str, field_name: str, payload_idx: int, @@ -1041,7 +1041,7 @@ class ClassGenEnum(ClassGenBase.ClassGenBase): # 懒初始化表(perm_pool:1a 每文件 reset 后表本体不被回收) if self.RenumAliasClass is None: - alias_pool_rfa: memhub.MemBuddy | t.CPtr = CompilerFactory.factory.PermPool + alias_pool_rfa: rowptr[memhub.MemBuddy] = CompilerFactory.factory.PermPool self.RenumAliasClass = alias_pool_rfa.alloc(8 * RENUM_ALIAS_MAX) self.RenumAliasField = alias_pool_rfa.alloc(8 * RENUM_ALIAS_MAX) self.RenumAliasIndex = alias_pool_rfa.alloc(8 * RENUM_ALIAS_MAX) diff --git a/App/lib/core/Gen/Class/ClassGenGeneric.vp b/App/lib/core/Gen/Class/ClassGenGeneric.vp index 06bc495..809047e 100644 --- a/App/lib/core/Gen/Class/ClassGenGeneric.vp +++ b/App/lib/core/Gen/Class/ClassGenGeneric.vp @@ -53,7 +53,7 @@ class ClassGenGeneric(ClassGenBase.ClassGenBase): if tp is None: return 0 return 1 - def _register_generic_template(self, pool: memhub.MemBuddy | t.CPtr, + def _register_generic_template(self, pool: rowptr[memhub.MemBuddy], cd: ast.ClassDef | t.CPtr, module_sha1: str) -> None: """注册泛型类模板(类名 + ClassDef 节点 + 来源模块 SHA1)""" @@ -116,7 +116,7 @@ class ClassGenGeneric(ClassGenBase.ClassGenBase): string.strcat(buf, " ") string.strcat(buf, tp_name) return buf - def _find_generic_template_tp_params(self, pool: memhub.MemBuddy | t.CPtr, + def _find_generic_template_tp_params(self, pool: rowptr[memhub.MemBuddy], class_name: str) -> list[str] | t.CPtr: """查找泛型类模板的类型参数名列表,未找到返回 None @@ -210,7 +210,7 @@ class ClassGenGeneric(ClassGenBase.ClassGenBase): f_val: str = files_local.get(i) return f_val return None - def _mangle_generic_class_name(self, pool: memhub.MemBuddy | t.CPtr, + def _mangle_generic_class_name(self, pool: rowptr[memhub.MemBuddy], class_name: str, type_args: list[str] | t.CPtr) -> str: """生成特化类名: list + [int] -> list[int] @@ -247,7 +247,7 @@ class ClassGenGeneric(ClassGenBase.ClassGenBase): string.strcat(mangled, ta) string.strcat(mangled, "]") return mangled - def _clone_annotation(self, pool: memhub.MemBuddy | t.CPtr, + def _clone_annotation(self, pool: rowptr[memhub.MemBuddy], node: ast.AST | t.CPtr, tp_names: list[str] | t.CPtr, type_args: list[str] | t.CPtr) -> ast.AST | t.CPtr: @@ -319,7 +319,7 @@ class ClassGenGeneric(ClassGenBase.ClassGenBase): # 其他: 直接引用(不拷贝) return node - def _clone_arguments(self, pool: memhub.MemBuddy | t.CPtr, + def _clone_arguments(self, pool: rowptr[memhub.MemBuddy], args: ast.AST | t.CPtr, tp_names: list[str] | t.CPtr, type_args: list[str] | t.CPtr) -> ast.AST | t.CPtr: @@ -348,7 +348,7 @@ class ClassGenGeneric(ClassGenBase.ClassGenBase): new_arg_list.append(arg_node) return ast.Arguments(pool, new_arg_list, old_args.vararg, old_args.kwarg, old_args.defaults, old_args.kw_defaults) - def _clone_classdef_for_spec(self, pool: memhub.MemBuddy | t.CPtr, + def _clone_classdef_for_spec(self, pool: rowptr[memhub.MemBuddy], cd: ast.ClassDef | t.CPtr, spec_name: str, tp_names: list[str] | t.CPtr, @@ -417,7 +417,7 @@ class ClassGenGeneric(ClassGenBase.ClassGenBase): if name_addr != 0: return (str | t.CPtr)(t.CVoid(name_addr, t.CPtr)) return None - def _cache_spec(self, pool: memhub.MemBuddy | t.CPtr, spec_key: str, spec_name: str): + def _cache_spec(self, pool: rowptr[memhub.MemBuddy], spec_key: str, spec_name: str): """缓存特化结果(stdlib 深拷贝存储,跨文件安全)""" if spec_key is None or spec_name is None: return @@ -464,7 +464,7 @@ class ClassGenGeneric(ClassGenBase.ClassGenBase): merged[cur_len] = ' ' string.strcpy(merged + cur_len + 1, tdeps) trans._imported_modules = merged - def _record_spec_trigger(self, pool: memhub.MemBuddy | t.CPtr, + def _record_spec_trigger(self, pool: rowptr[memhub.MemBuddy], spec_name: str, trigger_sha1: str) -> int: """记录泛型特化类的触发文件 sha1(StructEntry.SpecTriggerSha1) @@ -529,7 +529,7 @@ class ClassGenGeneric(ClassGenBase.ClassGenBase): if ta_rsv_g is not None and string.strcmp(ta_raw_g, ta_rsv_g) != 0: type_args.set(ta_i_g, ta_rsv_g) - pool: memhub.MemBuddy | t.CPtr = trans.Pool + pool: rowptr[memhub.MemBuddy] = trans.Pool # 1. 查找泛型模板 template_cd: ast.ClassDef | t.CPtr = self._find_generic_template(class_name) diff --git a/App/lib/core/Gen/Class/ClassGenVTable.vp b/App/lib/core/Gen/Class/ClassGenVTable.vp index 14b9c1d..95cb314 100644 --- a/App/lib/core/Gen/Class/ClassGenVTable.vp +++ b/App/lib/core/Gen/Class/ClassGenVTable.vp @@ -84,7 +84,7 @@ class ClassGenVTable(ClassGenBase.ClassGenBase): if trans is None or cd is None or class_name is None: return 0 - pool: memhub.MemBuddy | t.CPtr = trans.Pool + pool: rowptr[memhub.MemBuddy] = trans.Pool mod: llvmlite.LLVMModule | t.CPtr = trans.Module children: list[ast.AST | t.CPtr] | t.CPtr = cd.children @@ -296,7 +296,7 @@ class ClassGenVTable(ClassGenBase.ClassGenBase): return 0 - pool: memhub.MemBuddy | t.CPtr = trans.Pool + pool: rowptr[memhub.MemBuddy] = trans.Pool mod: llvmlite.LLVMModule | t.CPtr = trans.Module # 收集虚方法信息(继承父类 + 自身,结果存 self.VtFullNames 等暂存区) @@ -614,7 +614,7 @@ class ClassGenVTable(ClassGenBase.ClassGenBase): return 0 - pool: memhub.MemBuddy | t.CPtr = trans.Pool + pool: rowptr[memhub.MemBuddy] = trans.Pool mod: llvmlite.LLVMModule | t.CPtr = trans.Module imported_modules: str = trans._imported_modules from_imports: str = trans._from_imports @@ -1110,7 +1110,7 @@ class ClassGenVTable(ClassGenBase.ClassGenBase): return 0 - pool: memhub.MemBuddy | t.CPtr = trans.Pool + pool: rowptr[memhub.MemBuddy] = trans.Pool mod: llvmlite.LLVMModule | t.CPtr = trans.Module funcs_ptr: GenTypes.FuncEntry | t.CPtr = trans._funcs func_count: int = trans._func_count diff --git a/App/lib/core/Gen/Expr/ExprGenAttr.vp b/App/lib/core/Gen/Expr/ExprGenAttr.vp index 29e906c..669e7e2 100644 --- a/App/lib/core/Gen/Expr/ExprGenAttr.vp +++ b/App/lib/core/Gen/Expr/ExprGenAttr.vp @@ -71,7 +71,7 @@ class ExprGenAttr(ExprGenBase.ExprGenBase): # 用于跨模块全局变量访问: stub 未注入时,翻译阶段生成 @name 引用, # 链接时由 stub 提供 external global 声明。 # ============================================================ - def make_global_ref(self, pool: memhub.MemBuddy | t.CPtr, + def make_global_ref(self, pool: rowptr[memhub.MemBuddy], name: str, ty: llvmlite.LLVMType | t.CPtr) -> llvmlite.Value | t.CPtr: """创建全局变量引用 (类型为 ty*,名称为 @name)""" @@ -185,7 +185,7 @@ class ExprGenAttr(ExprGenBase.ExprGenBase): if string.strcmp(name, "CAutoPtr") == 0: return 1 return 0 - def _attr_module_path_str(self, pool: memhub.MemBuddy | t.CPtr, + def _attr_module_path_str(self, pool: rowptr[memhub.MemBuddy], node: ast.AST | t.CPtr) -> str: """把模块引用 AST 转成模块路径字符串(递归拼接 Attribute 链): Name('sys') → "sys";Attribute(Attribute(Name('os'),'_win32')) → "os._win32"。 @@ -213,7 +213,7 @@ class ExprGenAttr(ExprGenBase.ExprGenBase): viperlib.snprintf(buf_m, blen + alen + 2, "%s.%s", base_m, at_m.attr) return buf_m return None - def _resolve_module_attribute_global(self, pool: memhub.MemBuddy | t.CPtr, + def _resolve_module_attribute_global(self, pool: rowptr[memhub.MemBuddy], mod: llvmlite.LLVMModule | t.CPtr, trans: HT.Translator | t.CPtr, at: ast.Attribute | t.CPtr, @@ -340,7 +340,7 @@ class ExprGenAttr(ExprGenBase.ExprGenBase): # 非 c.Deref 模式返回 None # ============================================================ def _get_cderef_attr_base(self, builder: llvmlite.IRBuilder | t.CPtr, - pool: memhub.MemBuddy | t.CPtr, + pool: rowptr[memhub.MemBuddy], mod: llvmlite.LLVMModule | t.CPtr, at_value: ast.AST | t.CPtr, trans: HT.Translator | t.CPtr = None) -> llvmlite.Value | t.CPtr: @@ -366,7 +366,7 @@ class ExprGenAttr(ExprGenBase.ExprGenBase): return inner_cd return None def translate_attribute(self, builder: llvmlite.IRBuilder | t.CPtr, - pool: memhub.MemBuddy | t.CPtr, + pool: rowptr[memhub.MemBuddy], mod: llvmlite.LLVMModule | t.CPtr, node: ast.AST | t.CPtr, trans: HT.Translator | t.CPtr = None) -> llvmlite.Value | t.CPtr: @@ -1037,7 +1037,7 @@ class ExprGenAttr(ExprGenBase.ExprGenBase): # 获取属性访问的字段指针(不加载值,用于赋值) # 对于 Name 类型的 obj,直接使用 alloca 指针(不 load 结构体) # ============================================================ - def _resolve_attr_field_class(self, pool: memhub.MemBuddy | t.CPtr, + def _resolve_attr_field_class(self, pool: rowptr[memhub.MemBuddy], trans: HT.Translator | t.CPtr, attr_node: ast.AST | t.CPtr) -> str: """解析属性链(a.b.c)中 c 字段的注解类名。 @@ -1086,7 +1086,7 @@ class ExprGenAttr(ExprGenBase.ExprGenBase): return None return self.Gen.StructGen.get_field_annot_class_name(fe) def get_attribute_ptr(self, builder: llvmlite.IRBuilder | t.CPtr, - pool: memhub.MemBuddy | t.CPtr, + pool: rowptr[memhub.MemBuddy], mod: llvmlite.LLVMModule | t.CPtr, node: ast.AST | t.CPtr, trans: HT.Translator | t.CPtr = None) -> llvmlite.Value | t.CPtr: diff --git a/App/lib/core/Gen/Expr/ExprGenBase.vp b/App/lib/core/Gen/Expr/ExprGenBase.vp index 4fb880f..1211422 100644 --- a/App/lib/core/Gen/Expr/ExprGenBase.vp +++ b/App/lib/core/Gen/Expr/ExprGenBase.vp @@ -57,7 +57,7 @@ class ExprGenBase: # ============================================================ # 转义 LLVM IR 字符串字面量 # ============================================================ - def escape_llvm_string(self, pool: memhub.MemBuddy | t.CPtr, + def escape_llvm_string(self, pool: rowptr[memhub.MemBuddy], src: str) -> str: """将字符串转换为 LLVM IR 字符串字面量 c"...\\00" """ if src is None: @@ -218,7 +218,7 @@ class ExprGenBase: # 返回类名字符串或 None。用于 subscript 操作中判断是否需要 # 转发到 __getitem__/__setitem__ 而非生成 GEP。 # ============================================================ - def _get_custom_struct_cls_nm(self, pool: memhub.MemBuddy | t.CPtr, + def _get_custom_struct_cls_nm(self, pool: rowptr[memhub.MemBuddy], ty: llvmlite.LLVMType | t.CPtr) -> str: """检查 ty 或 ty 的 pointee 是否是已注册的自定义结构体,返回类名或 None""" if ty is None: @@ -241,7 +241,7 @@ class ExprGenBase: # - 普通结构体指针数组(如 pts: Point | t.CPtr):get_subscript_ptr 返回元素地址 # 路由错误会让 list[T] 被当作结构体数组 GEP,访问错位崩溃。 # ============================================================ - def _is_list_subscript_base(self, pool: memhub.MemBuddy | t.CPtr, + def _is_list_subscript_base(self, pool: rowptr[memhub.MemBuddy], trans: HT.Translator | t.CPtr, sub_node: ast.AST | t.CPtr) -> int: """判断下标基座是否为 list[T] 变量(1=是)""" @@ -277,7 +277,7 @@ class ExprGenBase: # ============================================================ # _sub_base_class_name - 解析下标基座变量的结构体类名 # ============================================================ - def _sub_base_class_name(self, pool: memhub.MemBuddy | t.CPtr, + def _sub_base_class_name(self, pool: rowptr[memhub.MemBuddy], trans: HT.Translator | t.CPtr, sub_node: ast.AST | t.CPtr) -> str: """解析下标基座变量的结构体类名(无则 None)""" @@ -311,7 +311,7 @@ class ExprGenBase: # - 普通结构体指针数组(如 pts: Point | t.CPtr)→ get_subscript_ptr # (GEP 元素地址,避免结构体值 base=非指针 报错) # ============================================================ - def _sub_base_uses_getitem(self, pool: memhub.MemBuddy | t.CPtr, + def _sub_base_uses_getitem(self, pool: rowptr[memhub.MemBuddy], mod: llvmlite.LLVMModule | t.CPtr, trans: HT.Translator | t.CPtr, sub_node: ast.AST | t.CPtr) -> int: @@ -506,7 +506,7 @@ class ExprGenBase: return llvmlite.build_bitcast(builder, val, target_ty) return val - def _zext_or_sext_val(self, pool: memhub.MemBuddy | t.CPtr, + def _zext_or_sext_val(self, pool: rowptr[memhub.MemBuddy], val: llvmlite.Value | t.CPtr, node: ast.AST | t.CPtr = None, trans: HT.Translator | t.CPtr = None) -> int: @@ -537,7 +537,7 @@ class ExprGenBase: # 数组 pointee([N x ty]*)先 decay 为元素指针(GEP 0,0), # 避免以整个数组为步长(对齐 TPC ExprGen L53-55)。 # ============================================================ - def translate_ptr_arith(self, pool: memhub.MemBuddy | t.CPtr, + def translate_ptr_arith(self, pool: rowptr[memhub.MemBuddy], builder: llvmlite.IRBuilder | t.CPtr, ptr_val: llvmlite.Value | t.CPtr, int_val: llvmlite.Value | t.CPtr, diff --git a/App/lib/core/Gen/Expr/ExprGenCdef.vp b/App/lib/core/Gen/Expr/ExprGenCdef.vp index 8691c25..eb281eb 100644 --- a/App/lib/core/Gen/Expr/ExprGenCdef.vp +++ b/App/lib/core/Gen/Expr/ExprGenCdef.vp @@ -146,7 +146,7 @@ class ExprGenCdef(ExprGenBase.ExprGenBase): # # pyi 文件格式: "NAME: t.CDefine = value" # ============================================================ - def _lookup_cross_module_cdefine(self, pool: memhub.MemBuddy | t.CPtr, + def _lookup_cross_module_cdefine(self, pool: rowptr[memhub.MemBuddy], name: str, from_imports: str, imported_modules: str = None, @@ -1090,7 +1090,7 @@ class ExprGenCdef(ExprGenBase.ExprGenBase): # ============================================================ # 翻译变量引用(Name 节点)→ load # ============================================================ - def _const_int_for_cdefine(self, pool: memhub.MemBuddy | t.CPtr, + def _const_int_for_cdefine(self, pool: rowptr[memhub.MemBuddy], value: int64) -> llvmlite.Value | t.CPtr: """CDefine 整数常量 → LLVM 常量(对齐 TPC TypeConvert 的 64 位升级) diff --git a/App/lib/core/Gen/Expr/ExprGenCls.vp b/App/lib/core/Gen/Expr/ExprGenCls.vp index 80cd11c..9654749 100644 --- a/App/lib/core/Gen/Expr/ExprGenCls.vp +++ b/App/lib/core/Gen/Expr/ExprGenCls.vp @@ -299,7 +299,7 @@ class ExprGenCls(ExprGenBase.ExprGenBase): # Attribute → 字段注解类名(_resolve_attr_field_class) # 仅采用已注册结构体;无法精确推断返回 None(fail-fast 由调用方暴露)。 # ============================================================ - def infer_expr_class(self, pool: memhub.MemBuddy | t.CPtr, + def infer_expr_class(self, pool: rowptr[memhub.MemBuddy], mod: llvmlite.LLVMModule | t.CPtr, node: ast.AST | t.CPtr, trans: HT.Translator | t.CPtr) -> str: @@ -420,7 +420,7 @@ class ExprGenCls(ExprGenBase.ExprGenBase): # SHA1(stub 中声明)即视为存在。仅在确实存在时采用推断类名, # 避免把原生运算误标为类类型。 # ============================================================ - def _cls_has_dunder(self, pool: memhub.MemBuddy | t.CPtr, + def _cls_has_dunder(self, pool: rowptr[memhub.MemBuddy], mod: llvmlite.LLVMModule | t.CPtr, class_name: str, dunder: str) -> int: """类及其 MRO 祖先链中是否存在 dunder 方法,存在返回 1""" @@ -456,7 +456,7 @@ class ExprGenCls(ExprGenBase.ExprGenBase): # CFloat64T/t.CPtr 等均不注册 struct,天然过滤)。"A | B" 联合 # 多候选时取首个命中段。 # ============================================================ - def _extract_annot_class_name(self, pool: memhub.MemBuddy | t.CPtr, + def _extract_annot_class_name(self, pool: rowptr[memhub.MemBuddy], annot: str) -> str: """从返回注解文本提取已注册结构体类名,无命中返回 None""" if pool is None or annot is None: diff --git a/App/lib/core/Gen/Expr/ExprGenConst.vp b/App/lib/core/Gen/Expr/ExprGenConst.vp index 7cb6f9e..830eb3b 100644 --- a/App/lib/core/Gen/Expr/ExprGenConst.vp +++ b/App/lib/core/Gen/Expr/ExprGenConst.vp @@ -28,7 +28,7 @@ class ExprGenConst(ExprGenBase.ExprGenBase): # 创建全局字符串常量 # ============================================================ def create_global_string(self, builder: llvmlite.IRBuilder | t.CPtr, - pool: memhub.MemBuddy | t.CPtr, + pool: rowptr[memhub.MemBuddy], mod: llvmlite.LLVMModule | t.CPtr, str_val: str, trans: HT.Translator | t.CPtr) -> llvmlite.Value | t.CPtr: @@ -83,7 +83,7 @@ class ExprGenConst(ExprGenBase.ExprGenBase): # 翻译常量表达式 # ============================================================ def translate_constant(self, builder: llvmlite.IRBuilder | t.CPtr, - pool: memhub.MemBuddy | t.CPtr, + pool: rowptr[memhub.MemBuddy], mod: llvmlite.LLVMModule | t.CPtr, node: ast.AST | t.CPtr, trans: HT.Translator | t.CPtr = None, @@ -162,7 +162,7 @@ class ExprGenConst(ExprGenBase.ExprGenBase): # # 用于 list 字面量 [a, b, c] 的元素类型推断 # ============================================================ - def _infer_elem_type_from_value(self, pool: memhub.MemBuddy | t.CPtr, + def _infer_elem_type_from_value(self, pool: rowptr[memhub.MemBuddy], value: llvmlite.Value | t.CPtr) -> str: """从 LLVM Value 的类型推断 list 元素类型名 @@ -226,7 +226,7 @@ class ExprGenConst(ExprGenBase.ExprGenBase): # 链接器合并同模板重复特化定义,zeroinitializer 保证编译链接通过。 # 运行时若该模块未在入口 main 赋值 _mbuddy(null pool 上动态建 list), # 由真实崩溃暴露(fail-fast 哲学,不掩盖上游未初始化)。 - pool: memhub.MemBuddy | t.CPtr = trans.Pool + pool: rowptr[memhub.MemBuddy] = trans.Pool if pool is None or trans.Module is None or trans.SymTab is None: return None # 先检查是否已注册到模块作用域(避免重复创建全局变量) @@ -274,7 +274,7 @@ class ExprGenConst(ExprGenBase.ExprGenBase): # list 对象指针(Ptr(list[T] struct)),None 失败 # ============================================================ def translate_list_literal(self, builder: llvmlite.IRBuilder | t.CPtr, - pool: memhub.MemBuddy | t.CPtr, + pool: rowptr[memhub.MemBuddy], mod: llvmlite.LLVMModule | t.CPtr, node: ast.AST | t.CPtr, elem_type_name: str, diff --git a/App/lib/core/Gen/Expr/ExprGenFstr.vp b/App/lib/core/Gen/Expr/ExprGenFstr.vp index b94c6bb..f7dacd6 100644 --- a/App/lib/core/Gen/Expr/ExprGenFstr.vp +++ b/App/lib/core/Gen/Expr/ExprGenFstr.vp @@ -36,7 +36,7 @@ class ExprGenFstr(ExprGenBase.ExprGenBase): # ("(null)"输出 + printf("%s", 垃圾) 崩溃 0xC0000005)。 # ============================================================ def translate_joined_str(self, builder: llvmlite.IRBuilder | t.CPtr, - pool: memhub.MemBuddy | t.CPtr, + pool: rowptr[memhub.MemBuddy], mod: llvmlite.LLVMModule | t.CPtr, node: ast.AST | t.CPtr, trans: HT.Translator | t.CPtr = None) -> llvmlite.Value | t.CPtr: @@ -108,7 +108,7 @@ class ExprGenFstr(ExprGenBase.ExprGenBase): return self._fstr_finalize(builder, pool, mod, fmt_buf, arg_head, arg_tail, arg_count, trans) def translate_formatted_value(self, builder: llvmlite.IRBuilder | t.CPtr, - pool: memhub.MemBuddy | t.CPtr, + pool: rowptr[memhub.MemBuddy], mod: llvmlite.LLVMModule | t.CPtr, node: ast.AST | t.CPtr, trans: HT.Translator | t.CPtr = None) -> llvmlite.Value | t.CPtr: @@ -152,7 +152,7 @@ class ExprGenFstr(ExprGenBase.ExprGenBase): arg_count = 1 return self._fstr_finalize(builder, pool, mod, fmt_buf, arg_head, arg_tail, arg_count, trans) def _fstr_finalize(self, builder: llvmlite.IRBuilder | t.CPtr, - pool: memhub.MemBuddy | t.CPtr, + pool: rowptr[memhub.MemBuddy], mod: llvmlite.LLVMModule | t.CPtr, fmt_buf: str, arg_head: llvmlite.Value | t.CPtr, @@ -223,7 +223,7 @@ class ExprGenFstr(ExprGenBase.ExprGenBase): src_len: sizet = string.strlen(s) if cur_len + src_len < FSTR_BUF_SIZE: string.strcpy(fmt_buf + cur_len, s) - def _fstr_parse_format_spec(self, pool: memhub.MemBuddy | t.CPtr, + def _fstr_parse_format_spec(self, pool: rowptr[memhub.MemBuddy], spec_node: ast.AST | t.CPtr, val: llvmlite.Value | t.CPtr, arg_node: ast.AST | t.CPtr) -> str: @@ -406,7 +406,7 @@ class ExprGenFstr(ExprGenBase.ExprGenBase): else: return None return out - def _fstr_infer_c_fmt(self, pool: memhub.MemBuddy | t.CPtr, + def _fstr_infer_c_fmt(self, pool: rowptr[memhub.MemBuddy], val: llvmlite.Value | t.CPtr, arg_node: ast.AST | t.CPtr, trans: HT.Translator | t.CPtr) -> str: @@ -443,7 +443,7 @@ class ExprGenFstr(ExprGenBase.ExprGenBase): self.Gen.TypeGenErr.fatal_error(arg_node, "f-string 格式无法推断(值类型缺失)", "TypeError") return None def _fstr_cast_value(self, builder: llvmlite.IRBuilder | t.CPtr, - pool: memhub.MemBuddy | t.CPtr, + pool: rowptr[memhub.MemBuddy], val: llvmlite.Value | t.CPtr, c_fmt: str, arg_node: ast.AST | t.CPtr, diff --git a/App/lib/core/Gen/Expr/ExprGenMixin.vp b/App/lib/core/Gen/Expr/ExprGenMixin.vp index 59e4c7a..6cdcfed 100644 --- a/App/lib/core/Gen/Expr/ExprGenMixin.vp +++ b/App/lib/core/Gen/Expr/ExprGenMixin.vp @@ -61,7 +61,7 @@ class ExprGenMixin(ExprGenBase.ExprGenBase): # 翻译值表达式(RHS 分派)— 模块级版本 # ============================================================ def translate_value(self, builder: llvmlite.IRBuilder | t.CPtr, - pool: memhub.MemBuddy | t.CPtr, + pool: rowptr[memhub.MemBuddy], mod: llvmlite.LLVMModule | t.CPtr, node: ast.AST | t.CPtr, funcs_ptr: t.CPtr = None, @@ -85,7 +85,7 @@ class ExprGenMixin(ExprGenBase.ExprGenBase): return rv def _translate_value_impl(self, builder: llvmlite.IRBuilder | t.CPtr, - pool: memhub.MemBuddy | t.CPtr, + pool: rowptr[memhub.MemBuddy], mod: llvmlite.LLVMModule | t.CPtr, node: ast.AST | t.CPtr, funcs_ptr: t.CPtr = None, diff --git a/App/lib/core/Gen/Expr/ExprGenName.vp b/App/lib/core/Gen/Expr/ExprGenName.vp index 366066a..43a5973 100644 --- a/App/lib/core/Gen/Expr/ExprGenName.vp +++ b/App/lib/core/Gen/Expr/ExprGenName.vp @@ -25,7 +25,7 @@ import lib.core.Gen.GenApi as GenApi class ExprGenName(ExprGenBase.ExprGenBase): """Name/Subscript/下标访问""" - def _cut_from_import_mod(self, pool: memhub.MemBuddy | t.CPtr, + def _cut_from_import_mod(self, pool: rowptr[memhub.MemBuddy], raw: str) -> str: """截断 lookup_from_import 返回的模块名到独立缓冲 @@ -51,7 +51,7 @@ class ExprGenName(ExprGenBase.ExprGenBase): return buf_c def translate_name_value(self, builder: llvmlite.IRBuilder | t.CPtr, - pool: memhub.MemBuddy | t.CPtr, + pool: rowptr[memhub.MemBuddy], node: ast.AST | t.CPtr, trans: HT.Translator | t.CPtr = None) -> llvmlite.Value | t.CPtr: """翻译变量引用(Name 节点)→ load""" @@ -387,7 +387,7 @@ class ExprGenName(ExprGenBase.ExprGenBase): # 返回元素地址 (i8*),调用方根据元素类型 load 正确的值 # ============================================================ def list_getitem_inline(self, builder: llvmlite.IRBuilder | t.CPtr, - pool: memhub.MemBuddy | t.CPtr, + pool: rowptr[memhub.MemBuddy], lm_obj: llvmlite.Value | t.CPtr, idx_val: llvmlite.Value | t.CPtr, node: ast.AST | t.CPtr = None) -> llvmlite.Value | t.CPtr: @@ -427,7 +427,7 @@ class ExprGenName(ExprGenBase.ExprGenBase): # 支持: list[int]→i32, list[str]/list[bytes]→i8*, list[CInt]→i32 等 # 默认: i32 # ============================================================ - def _list_elem_type_from_name(self, pool: memhub.MemBuddy | t.CPtr, + def _list_elem_type_from_name(self, pool: rowptr[memhub.MemBuddy], struct_name: str) -> llvmlite.LLVMType | t.CPtr: """从 list 类型名提取元素 LLVM 类型""" if pool is None or struct_name is None: @@ -488,7 +488,7 @@ class ExprGenName(ExprGenBase.ExprGenBase): # llvmlite.Ptr(entry.Ty)(list 元素槽 8 字节存对象指针)。全部未命中 # 返回 None(调用方回退 Ptr(i8) 旧行为,不影响已支持的内置元素)。 # ============================================================ - def _list_elem_obj_ty_from_struct_name(self, pool: memhub.MemBuddy | t.CPtr, + def _list_elem_obj_ty_from_struct_name(self, pool: rowptr[memhub.MemBuddy], struct_name: str) -> llvmlite.LLVMType | t.CPtr: """从 list 特化类型名还原元素对象指针 LLVM 类型,失败返回 None""" if pool is None or struct_name is None: @@ -556,7 +556,7 @@ class ExprGenName(ExprGenBase.ExprGenBase): # 直接存储 rhs_val 到元素地址 (coerce 为 i8* 后 store) # ============================================================ def list_setitem_inline(self, builder: llvmlite.IRBuilder | t.CPtr, - pool: memhub.MemBuddy | t.CPtr, + pool: rowptr[memhub.MemBuddy], lm_obj: llvmlite.Value | t.CPtr, idx_val: llvmlite.Value | t.CPtr, rhs_val: llvmlite.Value | t.CPtr, @@ -669,7 +669,7 @@ class ExprGenName(ExprGenBase.ExprGenBase): # 正确路径:从 env 读堆地址(_load_raw_var_ptr)→ bitcast → GEP。 # ============================================================ def _nonlocal_subscript_ptr(self, builder: llvmlite.IRBuilder | t.CPtr, - pool: memhub.MemBuddy | t.CPtr, + pool: rowptr[memhub.MemBuddy], trans: HT.Translator | t.CPtr, nm_id: str, idx_val: llvmlite.Value | t.CPtr) -> llvmlite.Value | t.CPtr: @@ -712,7 +712,7 @@ class ExprGenName(ExprGenBase.ExprGenBase): # list[T]: 泛型类不注册 struct,subscript 走 __getitem__ 内联路径 # ============================================================ def translate_subscript(self, builder: llvmlite.IRBuilder | t.CPtr, - pool: memhub.MemBuddy | t.CPtr, + pool: rowptr[memhub.MemBuddy], mod: llvmlite.LLVMModule | t.CPtr, node: ast.AST | t.CPtr, trans: HT.Translator | t.CPtr = None) -> llvmlite.Value | t.CPtr: @@ -1095,7 +1095,7 @@ class ExprGenName(ExprGenBase.ExprGenBase): return 0 def get_subscript_ptr(self, builder: llvmlite.IRBuilder | t.CPtr, - pool: memhub.MemBuddy | t.CPtr, + pool: rowptr[memhub.MemBuddy], mod: llvmlite.LLVMModule | t.CPtr, node: ast.AST | t.CPtr, trans: HT.Translator | t.CPtr = None) -> llvmlite.Value | t.CPtr: diff --git a/App/lib/core/Gen/Expr/ExprGenOps.vp b/App/lib/core/Gen/Expr/ExprGenOps.vp index 455aab8..e3abbb1 100644 --- a/App/lib/core/Gen/Expr/ExprGenOps.vp +++ b/App/lib/core/Gen/Expr/ExprGenOps.vp @@ -32,7 +32,7 @@ class ExprGenOps(ExprGenBase.ExprGenBase): # merge_blk: phi [body_val, then_blk], [orelse_val, else_blk] # ============================================================ def translate_ifexp(self, builder: llvmlite.IRBuilder | t.CPtr, - pool: memhub.MemBuddy | t.CPtr, + pool: rowptr[memhub.MemBuddy], mod: llvmlite.LLVMModule | t.CPtr, node: ast.AST | t.CPtr, trans: HT.Translator | t.CPtr = None) -> llvmlite.Value | t.CPtr: @@ -162,7 +162,7 @@ class ExprGenOps(ExprGenBase.ExprGenBase): # ============================================================ # 翻译比较表达式 Compare(left, ops, comparators) # ============================================================ - def should_zext_widen(self, pool: memhub.MemBuddy | t.CPtr, + def should_zext_widen(self, pool: rowptr[memhub.MemBuddy], narrow_val: llvmlite.Value | t.CPtr, wide_val: llvmlite.Value | t.CPtr, narrow_node: ast.AST | t.CPtr = None, @@ -180,7 +180,7 @@ class ExprGenOps(ExprGenBase.ExprGenBase): 对齐 TPC 的 _check_node_unsigned / HandlesExprOps 拓宽规则: 1. i1 (bool) → zext(1 保持 1,而非 sext 的 0xFF...) 2. i8 → zext(系统编程中 i8 几乎总是无符号字节); - 例外:源注解**明确有符号**(t.CInt8T/int8/i8/char…)→ sext 保号 + 例外:源注解**明确有符号**(int8/int8/i8/char…)→ sext 保号 (判据 _node_type_signed,见下) 3. 宽侧是常量且其值超出窄侧位宽的有符号范围 → zext (常量"想要"无符号解释,如 0xAABBCCDD > INT32_MAX 与 @@ -195,7 +195,7 @@ class ExprGenOps(ExprGenBase.ExprGenBase): if narrow_bits == 8: # i8 默认按「无符号字节」处理(系统编程惯例,保持既有行为); # 但**源注解明确为有符号类型**时必须 sext 保号: - # TypeCastTest 回归 —— `t.CInt32T(v)`(v: t.CInt8T = -50)期望 -50, + # TypeCastTest 回归 —— `int32(v)`(v: int8 = -50)期望 -50, # 此前 b8470c1 把强转路径统一到本函数后撞上无条件 zext 而变成 206。 if self._node_type_signed(pool, narrow_node, trans) != 0: return 0 @@ -230,7 +230,7 @@ class ExprGenOps(ExprGenBase.ExprGenBase): if cdv_zw > 0x7FFFFFFF: return 1 return 0 - def _node_type_unsigned(self, pool: memhub.MemBuddy | t.CPtr, + def _node_type_unsigned(self, pool: rowptr[memhub.MemBuddy], node: ast.AST | t.CPtr, trans: HT.Translator | t.CPtr = None) -> int: """轻量判断 AST 节点是否解析为无符号整数类型(1=是,0=否/未知) @@ -349,13 +349,13 @@ class ExprGenOps(ExprGenBase.ExprGenBase): fi_u += 1 return 0 return 0 - def _node_type_signed(self, pool: memhub.MemBuddy | t.CPtr, + def _node_type_signed(self, pool: rowptr[memhub.MemBuddy], node: ast.AST | t.CPtr, trans: HT.Translator | t.CPtr = None) -> int: """源节点是否**明确有符号**整数(独立真源的 SIGNED 分支;未知返回 0) 只服务 should_zext_widen 的 i8 分支:i8 默认按「无符号字节」zext, - 但源注解明确有符号(t.CInt8T / int8 / i8 / char …)时须 sext 保号。 + 但源注解明确有符号(int8 / int8 / i8 / char …)时须 sext 保号。 判据走独立符号性真源(精确名 + CTypedef 链),与 _node_type_unsigned 的 遍历形态对应,但只覆盖**注解直接可见**的节点形态(Call(t.X) / Name / Subscript);其余返回 0,即保持 i8 的既有默认行为(不扩大改动面)。 @@ -462,7 +462,7 @@ class ExprGenOps(ExprGenBase.ExprGenBase): return 1 return 0 def translate_compare(self, builder: llvmlite.IRBuilder | t.CPtr, - pool: memhub.MemBuddy | t.CPtr, + pool: rowptr[memhub.MemBuddy], mod: llvmlite.LLVMModule | t.CPtr, node: ast.AST | t.CPtr, trans: HT.Translator | t.CPtr = None) -> llvmlite.Value | t.CPtr: @@ -784,7 +784,7 @@ class ExprGenOps(ExprGenBase.ExprGenBase): # 翻译一元运算表达式 UnaryOp(op, operand) # ============================================================ def translate_unaryop(self, builder: llvmlite.IRBuilder | t.CPtr, - pool: memhub.MemBuddy | t.CPtr, + pool: rowptr[memhub.MemBuddy], mod: llvmlite.LLVMModule | t.CPtr, node: ast.AST | t.CPtr, trans: HT.Translator | t.CPtr = None) -> llvmlite.Value | t.CPtr: @@ -958,7 +958,7 @@ class ExprGenOps(ExprGenBase.ExprGenBase): # merge 块用 phi 合并所有入边的 i1 # ============================================================ def translate_boolop(self, builder: llvmlite.IRBuilder | t.CPtr, - pool: memhub.MemBuddy | t.CPtr, + pool: rowptr[memhub.MemBuddy], mod: llvmlite.LLVMModule | t.CPtr, node: ast.AST | t.CPtr, funcs_ptr: t.CPtr = None, @@ -1125,7 +1125,7 @@ class ExprGenOps(ExprGenBase.ExprGenBase): # dunder 方法。找到则生成方法调用 lhs.__dunder__(rhs),返回 # 调用结果;未找到返回 None,调用方回退到原生运算。 # ============================================================ - def try_operator_overload(self, pool: memhub.MemBuddy | t.CPtr, + def try_operator_overload(self, pool: rowptr[memhub.MemBuddy], builder: llvmlite.IRBuilder | t.CPtr, mod: llvmlite.LLVMModule | t.CPtr, lhs: llvmlite.Value | t.CPtr, @@ -1234,7 +1234,7 @@ class ExprGenOps(ExprGenBase.ExprGenBase): # dunder 方法(__neg__/__pos__/__invert__)。找到则生成方法调用 # operand.__dunder__(),返回调用结果;未找到返回 None,调用方回退到原生运算。 # ============================================================ - def try_unary_operator_overload(self, pool: memhub.MemBuddy | t.CPtr, + def try_unary_operator_overload(self, pool: rowptr[memhub.MemBuddy], builder: llvmlite.IRBuilder | t.CPtr, mod: llvmlite.LLVMModule | t.CPtr, operand: llvmlite.Value | t.CPtr, @@ -1315,7 +1315,7 @@ class ExprGenOps(ExprGenBase.ExprGenBase): # ============================================================ # 翻译二元运算(自动类型提升) # ============================================================ - def translate_binop(self, pool: memhub.MemBuddy | t.CPtr, + def translate_binop(self, pool: rowptr[memhub.MemBuddy], builder: llvmlite.IRBuilder | t.CPtr, mod: llvmlite.LLVMModule | t.CPtr, node: ast.AST | t.CPtr, diff --git a/App/lib/core/Gen/Func/FuncGenBase.vp b/App/lib/core/Gen/Func/FuncGenBase.vp index 11a45d6..9e63265 100644 --- a/App/lib/core/Gen/Func/FuncGenBase.vp +++ b/App/lib/core/Gen/Func/FuncGenBase.vp @@ -9,6 +9,7 @@ import stdio import stdlib import lib.core.VLogger as VLogger import lib.core.Gen.Translator as HT +import lib.core.Gen.GenApi as GenApi import lib.core.Gen.Call.CallGenBase as CallGenBase # ============================================================ @@ -30,7 +31,7 @@ class FuncGenBase(CallGenBase.CallGenBase): # # 返回 LLVM IR 属性字符串(如 "alwaysinline nounwind"),无属性返回 None # ============================================================ - def extract_func_attrs(self, pool: memhub.MemBuddy | t.CPtr, + def extract_func_attrs(self, pool: rowptr[memhub.MemBuddy], decorator_list: list[ast.AST | t.CPtr] | t.CPtr, imported_modules: str) -> str: """从 decorator_list 提取 c.Attribute 属性,返回 LLVM IR 属性字符串""" @@ -106,7 +107,7 @@ class FuncGenBase(CallGenBase.CallGenBase): if found_any == 0: return None return attrs_buf - def extract_func_section(self, pool: memhub.MemBuddy | t.CPtr, + def extract_func_section(self, pool: rowptr[memhub.MemBuddy], decorator_list: list[ast.AST | t.CPtr] | t.CPtr, imported_modules: str) -> str: """提取 @c.Attribute(t.attr.section("xxx")) 为属性组文本 '"section"="xxx"'。 @@ -263,16 +264,11 @@ class FuncGenBase(CallGenBase.CallGenBase): if trans.ModuleSha1 is None: return name name_len: sizet = string.strlen(name) - # 已带 SHA1 前缀(16 hex + '.')则跳过 - if name_len > 17: - is_sha1: int = 1 - for i in range(16): - c: char = name[i] - if not (('0' <= c <= '9') or ('a' <= c <= 'f')): - is_sha1 = 0 - break - if is_sha1 != 0 and name[16] == '.': - return name + # 已带 SHA1 前缀("{16hex}.")则跳过 + # [C10 收敛] 判定走唯一真源 `GenApi.sha1_prefix_len`。旧判据是 `name_len > 17`, + # 与真源的 `>= 17` 只差"前缀之后为空串"这一退化形态(无实际意义),一并对齐。 + if GenApi.sha1_prefix_len(name) != 0: + return name sha1: str = trans.ModuleSha1 sha1_len: sizet = string.strlen(sha1) mangled: str = stdlib.malloc(sha1_len + name_len + 2) @@ -293,16 +289,10 @@ class FuncGenBase(CallGenBase.CallGenBase): if sha1 is None or name is None: return name name_len: sizet = string.strlen(name) - # 已带 SHA1 前缀(16 hex + '.')则跳过 - if name_len > 17: - is_sha1: int = 1 - for i in range(16): - c2: char = name[i] - if not (('0' <= c2 <= '9') or ('a' <= c2 <= 'f')): - is_sha1 = 0 - break - if is_sha1 != 0 and name[16] == '.': - return name + # 已带 SHA1 前缀("{16hex}.")则跳过 + # [C10 收敛] 判定走唯一真源 `GenApi.sha1_prefix_len`(口径对齐同 _mangle_name)。 + if GenApi.sha1_prefix_len(name) != 0: + return name sha1_len: sizet = string.strlen(sha1) mangled: str = stdlib.malloc(sha1_len + name_len + 2) if mangled is None: @@ -376,7 +366,7 @@ class FuncGenBase(CallGenBase.CallGenBase): # 两阶段必须一致,否则 declare i32 + define {i64,i64,i64} → llc # "ret doesn't match function result type"。 # ============================================================ - def _resolve_creturn_ret_ty(self, pool: memhub.MemBuddy | t.CPtr, + def _resolve_creturn_ret_ty(self, pool: rowptr[memhub.MemBuddy], fd: ast.FunctionDef | t.CPtr, imported_modules: str, from_imports: str, @@ -421,7 +411,7 @@ class FuncGenBase(CallGenBase.CallGenBase): # ============================================================ # 创建 LLVM 函数(简单版本,仅声明) # ============================================================ - def create_function(self, pool: memhub.MemBuddy | t.CPtr, + def create_function(self, pool: rowptr[memhub.MemBuddy], mod: llvmlite.LLVMModule | t.CPtr, name: str, args_node: ast.AST | t.CPtr, diff --git a/App/lib/core/Gen/Func/FuncGenDef.vp b/App/lib/core/Gen/Func/FuncGenDef.vp index b2ee8f9..4a4a902 100644 --- a/App/lib/core/Gen/Func/FuncGenDef.vp +++ b/App/lib/core/Gen/Func/FuncGenDef.vp @@ -47,7 +47,7 @@ class FuncGenDef(CallGenBase.CallGenBase): """预扫描所有顶层 FunctionDef,创建前向声明""" if trans is None or tree is None: return 0 - pool: memhub.MemBuddy | t.CPtr = trans.Pool + pool: rowptr[memhub.MemBuddy] = trans.Pool mod: llvmlite.LLVMModule | t.CPtr = trans.Module if pool is None or mod is None: return 0 @@ -313,7 +313,7 @@ class FuncGenDef(CallGenBase.CallGenBase): if fd.flags is not None and (fd.flags & 1) != 0: return self.Gen.AsyncGen.translate_async_function(trans, node) - pool: memhub.MemBuddy | t.CPtr = trans.Pool + pool: rowptr[memhub.MemBuddy] = trans.Pool mod: llvmlite.LLVMModule | t.CPtr = trans.Module imported_modules: str = trans._imported_modules from_imports: str = trans._from_imports @@ -1072,7 +1072,7 @@ class FuncGenDef(CallGenBase.CallGenBase): # 前置返回:0=跳过原函数,1=调用一次,N=循环 N 次 # ============================================================ def _gen_decor_wrapper(self, trans: HT.Translator | t.CPtr, - pool: memhub.MemBuddy | t.CPtr, + pool: rowptr[memhub.MemBuddy], mod: llvmlite.LLVMModule | t.CPtr, func: llvmlite.Function | t.CPtr, func_name: str, diff --git a/App/lib/core/Gen/Func/FuncGenMixin.vp b/App/lib/core/Gen/Func/FuncGenMixin.vp index 8b84eab..52a5cea 100644 --- a/App/lib/core/Gen/Func/FuncGenMixin.vp +++ b/App/lib/core/Gen/Func/FuncGenMixin.vp @@ -81,7 +81,7 @@ class FuncGenMixin(CallGenBase.CallGenBase): if fd is None or fd.name is None: return 0 - pool: memhub.MemBuddy | t.CPtr = trans.Pool + pool: rowptr[memhub.MemBuddy] = trans.Pool mod: llvmlite.LLVMModule | t.CPtr = trans.Module func_name: str = fd.name @@ -867,7 +867,7 @@ class FuncGenMixin(CallGenBase.CallGenBase): # 而是**算不出**(结构体尺寸需查布局表,本函数只做 LLVMType 递归); # 改 fatal 会拒绝 "nonlocal 结构体" 这一合法用法,需先补布局查询能力。 # ============================================================ - def _type_byte_size(self, pool: memhub.MemBuddy | t.CPtr, + def _type_byte_size(self, pool: rowptr[memhub.MemBuddy], ty: llvmlite.LLVMType | t.CPtr) -> int: """计算 LLVM 类型占用的字节大小(递归)""" if ty is None: @@ -901,7 +901,7 @@ class FuncGenMixin(CallGenBase.CallGenBase): # 变量名: nlheap_{sha1}.{name}(全局变量,跨函数可见;SSA 编号是函数 # 局部的,跨函数传递堆地址只能经全局变量/模块级映射)。 # ============================================================ - def _nl_heap_global_name(self, pool: memhub.MemBuddy | t.CPtr, + def _nl_heap_global_name(self, pool: rowptr[memhub.MemBuddy], trans: HT.Translator | t.CPtr, name: str) -> str: """构造 nonlocal 堆地址全局映射变量名 nlheap_{sha1}.{name}""" @@ -916,7 +916,7 @@ class FuncGenMixin(CallGenBase.CallGenBase): # ============================================================ # _nl_heap_global_ref - 全局映射变量引用 Value(i8**) # ============================================================ - def _nl_heap_global_ref(self, pool: memhub.MemBuddy | t.CPtr, + def _nl_heap_global_ref(self, pool: rowptr[memhub.MemBuddy], trans: HT.Translator | t.CPtr, name: str) -> llvmlite.Value | t.CPtr: """获取 nonlocal 堆地址全局映射变量的引用(@"..." 引号包裹)""" @@ -1010,7 +1010,7 @@ class FuncGenMixin(CallGenBase.CallGenBase): # ============================================================ def _prepare_chain_nonlocals(self, trans: HT.Translator | t.CPtr, node: ast.AST | t.CPtr, - pool: memhub.MemBuddy | t.CPtr, + pool: rowptr[memhub.MemBuddy], builder: llvmlite.IRBuilder | t.CPtr, mod: llvmlite.LLVMModule | t.CPtr, i8_ty: llvmlite.LLVMType | t.CPtr, @@ -1111,7 +1111,7 @@ class FuncGenMixin(CallGenBase.CallGenBase): # 赋值语句据此创建 i8** alloca,调用走 translate_closure_call # ============================================================ def translate_lambda(self, builder: llvmlite.IRBuilder | t.CPtr, - pool: memhub.MemBuddy | t.CPtr, + pool: rowptr[memhub.MemBuddy], mod: llvmlite.LLVMModule | t.CPtr, node: ast.AST | t.CPtr, trans: HT.Translator | t.CPtr = None) -> llvmlite.Value | t.CPtr: diff --git a/App/lib/core/Gen/GenApi.vp b/App/lib/core/Gen/GenApi.vp index dc140b6..0addcf4 100644 --- a/App/lib/core/Gen/GenApi.vp +++ b/App/lib/core/Gen/GenApi.vp @@ -3,6 +3,7 @@ from stdint import * import ast import llvmlite import memhub +import string import lib.core.Gen.GenTypes as GenTypes import lib.core.Gen.Generator as Generator import lib.core.Gen.Translator as HT @@ -70,7 +71,7 @@ def clear_ctypedefs() -> None: # ---------------- RegisterCTypedefFromSource(委托 TypeGenCType.register_ctypedef_from_source) ---------------- -def RegisterCTypedefFromSource(pool: memhub.MemBuddy | t.CPtr, src: str) -> int: +def RegisterCTypedefFromSource(pool: rowptr[memhub.MemBuddy], src: str) -> int: """委托到 gen.register_ctypedef_from_source(原 Handles 壳)""" if _g_gen is not None: _g_gen.TypeGenCType.register_ctypedef_from_source(pool, src) @@ -105,7 +106,7 @@ def fatal_error(node: ast.AST | t.CPtr, msg: str, # ---------------- map_t_type(委托 TypeGenResolve.map_t_type) ---------------- -def map_t_type(pool: memhub.MemBuddy | t.CPtr, type_name: str) -> llvmlite.LLVMType | t.CPtr: +def map_t_type(pool: rowptr[memhub.MemBuddy], type_name: str) -> llvmlite.LLVMType | t.CPtr: """委托到 gen.map_t_type(原 Handles 壳)""" if _g_gen is not None: _g_gen.TypeGenResolve.map_t_type(pool, type_name) @@ -113,7 +114,7 @@ def map_t_type(pool: memhub.MemBuddy | t.CPtr, type_name: str) -> llvmlite.LLVMT # ---------------- resolve_typedef_or_map(委托 TypeGenResolve.resolve_typedef_or_map) ---------------- -def resolve_typedef_or_map(pool: memhub.MemBuddy | t.CPtr, +def resolve_typedef_or_map(pool: rowptr[memhub.MemBuddy], name: str, imported_modules: str, from_imports: str, @@ -125,7 +126,7 @@ def resolve_typedef_or_map(pool: memhub.MemBuddy | t.CPtr, # ---------------- infer_external_func_ret_ty(委托 CallGenLib._infer_external_func_ret_ty) ---------------- -def infer_external_func_ret_ty(pool: memhub.MemBuddy | t.CPtr, +def infer_external_func_ret_ty(pool: rowptr[memhub.MemBuddy], func_name: str) -> llvmlite.LLVMType | t.CPtr: """委托到 gen.CallGenLib._infer_external_func_ret_ty(外部函数返回类型白名单) @@ -157,7 +158,7 @@ def _is_ctypedef_annotation(annotation: ast.AST | t.CPtr) -> int: # ---------------- resolve_annotation_type(委托 TypeGenResolve.resolve_annotation_type) ---------------- -def resolve_annotation_type(pool: memhub.MemBuddy | t.CPtr, node: ast.AST | t.CPtr, imported_modules: str, from_imports: str, trans: HT.Translator | t.CPtr = None, depth: int = 0) -> llvmlite.LLVMType | t.CPtr: +def resolve_annotation_type(pool: rowptr[memhub.MemBuddy], node: ast.AST | t.CPtr, imported_modules: str, from_imports: str, trans: HT.Translator | t.CPtr = None, depth: int = 0) -> llvmlite.LLVMType | t.CPtr: """委托到 gen.resolve_annotation_type(原 Handles 壳)""" if _g_gen is not None: return _g_gen.TypeGenResolve.resolve_annotation_type(pool, node, imported_modules, from_imports, trans, depth) @@ -174,7 +175,7 @@ def has_decorator_marker(node: ast.AST | t.CPtr, marker_name: str, # ---------------- _get_type_name_from_annotation(委托 TypeGenResolve._get_type_name_from_annotation) ---------------- -def _get_type_name_from_annotation(pool: memhub.MemBuddy | t.CPtr, node: ast.AST | t.CPtr) -> str: +def _get_type_name_from_annotation(pool: rowptr[memhub.MemBuddy], node: ast.AST | t.CPtr) -> str: """委托到 gen._get_type_name_from_annotation(原 Handles 壳)""" if _g_gen is not None: return _g_gen.TypeGenResolve._get_type_name_from_annotation(pool, node) @@ -182,7 +183,7 @@ def _get_type_name_from_annotation(pool: memhub.MemBuddy | t.CPtr, node: ast.AST # ---------------- register_ctypedef(委托 TypeGenCType.register_ctypedef) ---------------- -def register_ctypedef(pool: memhub.MemBuddy | t.CPtr, name: str, type_str: str): +def register_ctypedef(pool: rowptr[memhub.MemBuddy], name: str, type_str: str): """委托到 gen.register_ctypedef(原 Handles 壳)""" if _g_gen is not None: _g_gen.TypeGenCType.register_ctypedef(pool, name, type_str) @@ -205,7 +206,7 @@ def is_cdefine_found() -> int: # ---------------- register_cdefine_constant(委托 TypeGenCDef.register_cdefine_constant) ---------------- -def register_cdefine_constant(pool: memhub.MemBuddy | t.CPtr, +def register_cdefine_constant(pool: rowptr[memhub.MemBuddy], name: str, value: int64): """委托到 gen.register_cdefine_constant(原 Handles 壳)""" if _g_gen is not None: @@ -213,7 +214,7 @@ def register_cdefine_constant(pool: memhub.MemBuddy | t.CPtr, # ---------------- register_cdefine_double(委托 TypeGenCDef.register_cdefine_double) ---------------- -def register_cdefine_double(pool: memhub.MemBuddy | t.CPtr, +def register_cdefine_double(pool: rowptr[memhub.MemBuddy], name: str, value: double): """委托到 gen.register_cdefine_double(原 Handles 壳)""" if _g_gen is not None: @@ -259,7 +260,7 @@ def get_temp_dir() -> str: # ---------------- reset_visible_structs(委托 StructGenMixin.reset_visible_structs) ---------------- -def reset_visible_structs(pool: memhub.MemBuddy | t.CPtr, strict: int): +def reset_visible_structs(pool: rowptr[memhub.MemBuddy], strict: int): """委托到 gen.reset_visible_structs(原 Handles 壳)""" if _g_gen is not None: _g_gen.StructGen.reset_visible_structs(pool, strict) @@ -311,7 +312,7 @@ def get_enum_base_type(enum_name: str) -> llvmlite.LLVMType | t.CPtr: # ---------------- add_visible_struct(委托 StructGenMixin.add_visible_struct) ---------------- -def add_visible_struct(pool: memhub.MemBuddy | t.CPtr, name: str): +def add_visible_struct(pool: rowptr[memhub.MemBuddy], name: str): """委托到 gen.add_visible_struct(原 Handles 壳)""" if _g_gen is not None: _g_gen.StructGen.add_visible_struct(pool, name) @@ -334,7 +335,7 @@ def find_struct_by_type(struct_ty: llvmlite.LLVMType | t.CPtr) -> GenTypes.Struc # ---------------- register_struct(委托 StructGenMixin.register_struct) ---------------- -def register_struct(pool: memhub.MemBuddy | t.CPtr, +def register_struct(pool: rowptr[memhub.MemBuddy], name: str, struct_ty: llvmlite.LLVMType | t.CPtr, sha1: str = None) -> GenTypes.StructEntry | t.CPtr: @@ -345,7 +346,7 @@ def register_struct(pool: memhub.MemBuddy | t.CPtr, # ---------------- add_field(委托 StructGenMixin.add_field) ---------------- -def add_field(pool: memhub.MemBuddy | t.CPtr, +def add_field(pool: rowptr[memhub.MemBuddy], struct_entry: GenTypes.StructEntry | t.CPtr, field_name: str, field_ty: llvmlite.LLVMType | t.CPtr) -> int: @@ -356,7 +357,7 @@ def add_field(pool: memhub.MemBuddy | t.CPtr, # ---------------- register_struct_alias(委托 StructGenMixin.register_struct_alias) ---------------- -def register_struct_alias(pool: memhub.MemBuddy | t.CPtr, +def register_struct_alias(pool: rowptr[memhub.MemBuddy], name: str, sha1: str, src_entry: GenTypes.StructEntry | t.CPtr) -> GenTypes.StructEntry | t.CPtr: @@ -376,7 +377,7 @@ def get_stdlib_alloc() -> int: # ---------------- compute_package_from_relpath(委托 ImportsGenMixin.compute_package_from_relpath) ---------------- -def compute_package_from_relpath(pool: memhub.MemBuddy | t.CPtr, rel_path: str) -> str: +def compute_package_from_relpath(pool: rowptr[memhub.MemBuddy], rel_path: str) -> str: """委托到 gen.compute_package_from_relpath(原 Handles 壳)""" if _g_gen is not None: return _g_gen.ImportsGen.compute_package_from_relpath(pool, rel_path) @@ -391,8 +392,56 @@ def is_module_imported(imported_modules: str, name: str) -> int: return 0 +# ============================================================ +# SHA1 前缀识别的**唯一真源**(C10 / D3 收敛) +# +# 「名字带 SHA1 前缀」有两种书写形态,各自给一个判定: +# sha1_prefix_len(name) → 完整名 "{16位小写hex}.Class" ⇒ 返回 17(前缀字节数), +# 否则 0。判据三条缺一不可:长度 >= 17、第 17 字节是 +# '.'、前 16 字节全是小写 hex(0-9a-f)。 +# is_sha1_hex16(seg) → 单独的**模块段**("16位小写hex")⇒ 1/0。 +# 用于已把 "mod.Class" 切成两段后判 mod 段(此时无从 +# 判断 '.' 存在与否)。 +# +# 为什么必须唯一:此前全仓有 8 份以上同义拷贝且**口径互不相同**——有的省略 hex +# 校验(只判 `len > 17 && s[16] == '.'`)、有的允许大写 A-F、有的只要 `len >= 16` +# 就盲取前 16 字节当 SHA1。同一名字在不同路径被判成"是/不是 SHA1 前缀",会产生 +# 「重复加前缀 / 把 SHA1 当模块名再查一次(查不到)/ 该跳过 store 查询的没跳过」 +# 等隐蔽不一致(跨模块同名类归属错乱、泛型实参解析退化均源于此族)。 +# ============================================================ +def sha1_prefix_len(name: str) -> int: + """名字若是 "{16位小写hex}." 形态返回 17(前缀字节数),否则返回 0""" + if name is None: + return 0 + if string.strlen(name) < 17: + return 0 + if name[16] != '.': + return 0 + i: sizet + for i in range(16): + c: int = name[i] + # 48-57 = '0'-'9',97-102 = 'a'-'f' + if not ((c >= 48 and c <= 57) or (c >= 97 and c <= 102)): + return 0 + return 17 + + +def is_sha1_hex16(seg: str) -> int: + """seg 是否恰为 16 位小写 hex(SHA1 模块段),1=是 / 0=否""" + if seg is None: + return 0 + if string.strlen(seg) != 16: + return 0 + i: sizet + for i in range(16): + c: int = seg[i] + if not ((c >= 48 and c <= 57) or (c >= 97 and c <= 102)): + return 0 + return 1 + + # ---------------- add_imported_module(委托 ImportsGenMixin.add_imported_module) ---------------- -def add_imported_module(pool: memhub.MemBuddy | t.CPtr, imported_modules: str, name: str) -> str: +def add_imported_module(pool: rowptr[memhub.MemBuddy], imported_modules: str, name: str) -> str: """委托到 gen.add_imported_module(原 Handles 壳)""" if _g_gen is not None: return _g_gen.ImportsGen.add_imported_module(pool, imported_modules, name) @@ -432,7 +481,7 @@ def _get_parent_class(cd: ast.ClassDef | t.CPtr, trans: HT.Translator | t.CPtr = # ---------------- _register_generic_template(委托 ClassGenGeneric._register_generic_template) ---------------- -def _register_generic_template(pool: memhub.MemBuddy | t.CPtr, cd: ast.ClassDef | t.CPtr, module_sha1: str): +def _register_generic_template(pool: rowptr[memhub.MemBuddy], cd: ast.ClassDef | t.CPtr, module_sha1: str): """委托到 gen._register_generic_template(原 Handles 壳)""" if _g_gen is not None: _g_gen.ClassGenGeneric._register_generic_template(pool, cd, module_sha1) @@ -479,7 +528,7 @@ def translate_children(trans: HT.Translator | t.CPtr, tree: ast.AST | t.CPtr) -> # ---------------- init_symbol_table(委托 VarGenMixin.init_symbol_table) ---------------- -def init_symbol_table(pool: memhub.MemBuddy | t.CPtr) -> GenTypes.SymbolTable | t.CPtr: +def init_symbol_table(pool: rowptr[memhub.MemBuddy]) -> GenTypes.SymbolTable | t.CPtr: """委托到 gen.init_symbol_table(原 Handles 壳)""" if _g_gen is not None: return _g_gen.VarGen.init_symbol_table(pool) @@ -502,7 +551,7 @@ def find_func_in_module(mod: llvmlite.LLVMModule | t.CPtr, name: str) -> llvmlit # ---------------- add_func_to_table(委托 CallGenLeafKit.add_func_to_table) ---------------- -def add_func_to_table(funcs: GenTypes.FuncEntry | t.CPtr, func_count: int, name: str, func: llvmlite.Function | t.CPtr, max_count: int, defaults: t.CPtr = None, default_count: int = 0, param_count: int = 0, pool: memhub.MemBuddy | t.CPtr = None, def_sha1: str = None) -> int: +def add_func_to_table(funcs: GenTypes.FuncEntry | t.CPtr, func_count: int, name: str, func: llvmlite.Function | t.CPtr, max_count: int, defaults: t.CPtr = None, default_count: int = 0, param_count: int = 0, pool: rowptr[memhub.MemBuddy] = None, def_sha1: str = None) -> int: """委托到 gen.add_func_to_table(原 Handles 壳) def_sha1:定义该函数的模块 SHA1(依赖注入路径必须传,避免默认值被挂到导入方名下) @@ -513,7 +562,7 @@ def add_func_to_table(funcs: GenTypes.FuncEntry | t.CPtr, func_count: int, name: # ---------------- init_func_table(委托 CallGenLeafKit.init_func_table) ---------------- -def init_func_table(pool: memhub.MemBuddy | t.CPtr, max_count: int) -> GenTypes.FuncEntry | t.CPtr: +def init_func_table(pool: rowptr[memhub.MemBuddy], max_count: int) -> GenTypes.FuncEntry | t.CPtr: """委托到 gen.init_func_table(原 Handles 壳)""" if _g_gen is not None: return _g_gen.CallGenLeafKit.init_func_table(pool, max_count) @@ -521,7 +570,7 @@ def init_func_table(pool: memhub.MemBuddy | t.CPtr, max_count: int) -> GenTypes. # ---------------- translate_call(委托 CallGenMixin.translate_call) ---------------- -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: +def translate_call(pool: rowptr[memhub.MemBuddy], 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: """委托到 gen.translate_call(原 Handles 壳)""" if _g_gen is not None: return _g_gen.CallGen.translate_call(pool, builder, mod, node, funcs_ptr, func_count, trans) @@ -529,14 +578,14 @@ def translate_call(pool: memhub.MemBuddy | t.CPtr, builder: llvmlite.IRBuilder | # ---------------- translate_printf_call(委托 CallGenLeafKit.translate_printf_call) ---------------- -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): +def translate_printf_call(pool: rowptr[memhub.MemBuddy], builder: llvmlite.IRBuilder | t.CPtr, mod: llvmlite.LLVMModule | t.CPtr, cl: ast.Call | t.CPtr, trans: HT.Translator | t.CPtr = None): """委托到 gen.translate_printf_call(原 Handles 壳)""" if _g_gen is not None: _g_gen.CallGenLeafKit.translate_printf_call(pool, builder, mod, cl, trans) # ---------------- translate_print_call(委托 CallGenLeafKit.translate_print_call) ---------------- -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): +def translate_print_call(pool: rowptr[memhub.MemBuddy], builder: llvmlite.IRBuilder | t.CPtr, mod: llvmlite.LLVMModule | t.CPtr, cl: ast.Call | t.CPtr, trans: HT.Translator | t.CPtr = None): """委托到 gen.translate_print_call(原 Handles 壳)""" if _g_gen is not None: _g_gen.CallGenLeafKit.translate_print_call(pool, builder, mod, cl, trans) diff --git a/App/lib/core/Gen/GenTypes.vp b/App/lib/core/Gen/GenTypes.vp index f9d9116..4c26baf 100644 --- a/App/lib/core/Gen/GenTypes.vp +++ b/App/lib/core/Gen/GenTypes.vp @@ -94,7 +94,7 @@ class Scope: @t.NoVTable class SymbolTable: """嵌套作用域符号表""" - Pool: memhub.MemBuddy | t.CPtr + Pool: rowptr[memhub.MemBuddy] Root: Scope | t.CPtr Current: Scope | t.CPtr @@ -185,11 +185,11 @@ class FuncEntry: Defaults: t.CPtr # defaults 列表节点指针 (list[AST | CPtr]),None=无默认值 DefaultCount: int # 默认值数量 ParamCount: int # 形参数量(不含 self) - # TypeSpec(S3 条目双写):Kind=TS_FUNC 的**整签名**(Ret/Params/ParamCount/ - # IsVarArg 都在其内),由 update_global_func_spec 在形参 add_param 完成后 - # 用 NewTypeFunc 构造(含 func.IsVarArg)。PermPool 驻留 ⇒ 跨 1b reset 安全。 - # 说明:设计 D4 原写 RetSpec+ParamSpecs 两字段,此处合并为单个 Spec —— 单字段 - # 即可完整表达签名,且与 VarEntry/FieldEntry 的 Spec 命名一致,避免参数数组重复。 + # TypeSpec(S3 条目双写):Kind=TS_FUNC 的**整签名**(Ret/Params/ParamCount/ + # IsVarArg 都在其内),由 update_global_func_spec 在形参 add_param 完成后 + # 用 NewTypeFunc 构造(含 func.IsVarArg)。PermPool 驻留 ⇒ 跨 1b reset 安全。 + # 说明:设计 D4 原写 RetSpec+ParamSpecs 两字段,此处合并为单个 Spec —— 单字段 + # 即可完整表达签名,且与 VarEntry/FieldEntry 的 Spec 命名一致,避免参数数组重复。 Spec: TSpec.TypeSpec | t.CPtr diff --git a/App/lib/core/Gen/Generator.vp b/App/lib/core/Gen/Generator.vp index f12b155..d081e6b 100644 --- a/App/lib/core/Gen/Generator.vp +++ b/App/lib/core/Gen/Generator.vp @@ -1,468 +1,468 @@ -import string -import lib.core.CompilerFactory as CompilerFactory -import t, c -from stdint import * -import stdio -import stdlib -import memhub -import llvmlite -import lib.core.Gen.BaseGenMixin as BaseGenMixin -import lib.core.Gen.Type.TypeGenBase as TypeGenBase -import lib.core.Gen.Type.TypeGenMixin as TypeGenMixin -import lib.core.Gen.Type.TypeGenCDef as TypeGenCDef -import lib.core.Gen.Type.TypeGenCType as TypeGenCType -import lib.core.Gen.Type.TypeGenResolve as TypeGenResolve -import lib.core.Gen.Type.TypeGenErr as TypeGenErr -import lib.core.Gen.StructGenMixin as StructGenMixin -import lib.core.Gen.Expr.ExprGenBase as ExprGenBase -import lib.core.Gen.Expr.ExprGenMixin as ExprGenMixin -import lib.core.Gen.Expr.ExprGenConst as ExprGenConst -import lib.core.Gen.Expr.ExprGenFstr as ExprGenFstr -import lib.core.Gen.Expr.ExprGenOps as ExprGenOps -import lib.core.Gen.Expr.ExprGenCdef as ExprGenCdef -import lib.core.Gen.Expr.ExprGenName as ExprGenName -import lib.core.Gen.Expr.ExprGenAttr as ExprGenAttr -import lib.core.Gen.Expr.ExprGenCls as ExprGenCls -import lib.core.Gen.Call.CallGenBase as CallGenBase -import lib.core.Gen.Call.CallGenCBuiltin as CallGenCBuiltin -import lib.core.Gen.Call.CallGenLeafKit as CallGenLeafKit -import lib.core.Gen.Call.CallGenCtor as CallGenCtor -import lib.core.Gen.Call.CallGenCall as CallGenCall -import lib.core.Gen.Call.CallGenMixin as CallGenMixin -import lib.core.Gen.Call.CallGenDispatch as CallGenDispatch -import lib.core.Gen.Call.CallGenLib as CallGenLib -import lib.core.Gen.Call.CallGenVt as CallGenVt -import lib.core.Gen.Call.CallGenVa as CallGenVa -import lib.core.Gen.Call.CallGenProp as CallGenProp -import lib.core.Gen.Call.CallGenFd as CallGenFd -import lib.core.Gen.Func.FuncGenBase as FuncGenBase -import lib.core.Gen.Func.FuncGenDef as FuncGenDef -import lib.core.Gen.Func.FuncGenMixin as FuncGenMixin -import lib.core.Gen.Class.ClassGenBase as ClassGenBase -import lib.core.Gen.Class.ClassGenMixin as ClassGenMixin -import lib.core.Gen.Class.ClassGenEnum as ClassGenEnum -import lib.core.Gen.Class.ClassGenGeneric as ClassGenGeneric -import lib.core.Gen.Class.ClassGenVTable as ClassGenVTable -import lib.core.Gen.Class.ClassGenDef as ClassGenDef -import lib.core.Gen.ImportsGenMixin as ImportsGenMixin -import lib.core.Gen.Stmt.StmtGenCifMixin as StmtGenCifMixin -import lib.core.Gen.Stmt.StmtGenDeclMixin as StmtGenDeclMixin -import lib.core.Gen.Stmt.StmtGenMixin as StmtGenMixin -import lib.core.Gen.MatchGenMixin as MatchGenMixin -import lib.core.Gen.AssignGenMixin as AssignGenMixin -import lib.core.Gen.AsyncGenMixin as AsyncGenMixin -import lib.core.Gen.VarGenMixin as VarGenMixin -import lib.core.Gen.TranslatorGenMixin as TranslatorGenMixin - - -# ============================================================ -# Generator - 生成器(双向引用组合架构) -# -# 不再 46 路多继承 Mixin;改为组合:Generator 持所有 GenMixin -# 子对象指针(永久池分配,全生命周期),每个 Mixin 持 Gen 回指。 -# 跨子对象访问 = self.Gen..<字段/方法>(链式有风险, -# 统一用中间变量取子对象再访问)。高亮可推导(显式类型注解)。 -# ============================================================ -@t.NoVTable -class Generator: - """生成器:持所有 GenMixin 子对象指针(双向引用组合)""" - - # ---- 子对象指针(46 个,永久池) ---- - BaseGen: BaseGenMixin.BaseGenMixin | t.CPtr - TypeGenBase: TypeGenBase.TypeGenBase | t.CPtr - TypeGen: TypeGenMixin.TypeGenMixin | t.CPtr - TypeGenCDef: TypeGenCDef.TypeGenCDef | t.CPtr - TypeGenCType: TypeGenCType.TypeGenCType | t.CPtr - TypeGenResolve: TypeGenResolve.TypeGenResolve | t.CPtr - TypeGenErr: TypeGenErr.TypeGenErr | t.CPtr - StructGen: StructGenMixin.StructGenMixin | t.CPtr - ExprGenBase: ExprGenBase.ExprGenBase | t.CPtr - ExprGen: ExprGenMixin.ExprGenMixin | t.CPtr - ExprGenConst: ExprGenConst.ExprGenConst | t.CPtr - ExprGenFstr: ExprGenFstr.ExprGenFstr | t.CPtr - ExprGenOps: ExprGenOps.ExprGenOps | t.CPtr - ExprGenCdef: ExprGenCdef.ExprGenCdef | t.CPtr - ExprGenName: ExprGenName.ExprGenName | t.CPtr - ExprGenAttr: ExprGenAttr.ExprGenAttr | t.CPtr - ExprGenCls: ExprGenCls.ExprGenCls | t.CPtr - CallGenBase: CallGenBase.CallGenBase | t.CPtr - CallGenCBuiltin: CallGenCBuiltin.CallGenCBuiltin | t.CPtr - CallGenLeafKit: CallGenLeafKit.CallGenLeafKit | t.CPtr - CallGenCtor: CallGenCtor.CallGenCtor | t.CPtr - CallGenCall: CallGenCall.CallGenCall | t.CPtr - CallGen: CallGenMixin.CallGenMixin | t.CPtr - CallGenDispatch: CallGenDispatch.CallGenDispatch | t.CPtr - CallGenLib: CallGenLib.CallGenLib | t.CPtr - CallGenVt: CallGenVt.CallGenVt | t.CPtr - CallGenVa: CallGenVa.CallGenVa | t.CPtr - CallGenProp: CallGenProp.CallGenProp | t.CPtr - CallGenFd: CallGenFd.CallGenFd | t.CPtr - FuncGenBase: FuncGenBase.FuncGenBase | t.CPtr - FuncGenDef: FuncGenDef.FuncGenDef | t.CPtr - FuncGen: FuncGenMixin.FuncGenMixin | t.CPtr - ClassGenBase: ClassGenBase.ClassGenBase | t.CPtr - ClassGen: ClassGenMixin.ClassGenMixin | t.CPtr - ClassGenEnum: ClassGenEnum.ClassGenEnum | t.CPtr - ClassGenGeneric: ClassGenGeneric.ClassGenGeneric | t.CPtr - ClassGenVTable: ClassGenVTable.ClassGenVTable | t.CPtr - ClassGenDef: ClassGenDef.ClassGenDef | t.CPtr - ImportsGen: ImportsGenMixin.ImportsGenMixin | t.CPtr - StmtGenCif: StmtGenCifMixin.StmtGenCifMixin | t.CPtr - StmtGenDecl: StmtGenDeclMixin.StmtGenDeclMixin | t.CPtr - StmtGen: StmtGenMixin.StmtGenMixin | t.CPtr - MatchGen: MatchGenMixin.MatchGenMixin | t.CPtr - AssignGen: AssignGenMixin.AssignGenMixin | t.CPtr - AsyncGen: AsyncGenMixin.AsyncGenMixin | t.CPtr - VarGen: VarGenMixin.VarGenMixin | t.CPtr - TranslatorGen: TranslatorGenMixin.TranslatorGenMixin | t.CPtr - - def __init__(self, pool: memhub.MemBuddy | t.CPtr): - if self is None: - return - # ---- alloc 46 个子对象 + 回指(永久池,fail-fast) ---- - SubBaseGen: BaseGenMixin.BaseGenMixin | t.CPtr = CompilerFactory.factory.PermPool.alloc(BaseGenMixin.BaseGenMixin.__sizeof__()) - if SubBaseGen is None: - stdio.printf("FAIL: BaseGenMixin alloc failed\n") - stdlib.exit(1) - string.memset(SubBaseGen, 0, BaseGenMixin.BaseGenMixin.__sizeof__()) - SubBaseGen.Gen = self - self.BaseGen = SubBaseGen - SubTypeGenBase: TypeGenBase.TypeGenBase | t.CPtr = CompilerFactory.factory.PermPool.alloc(TypeGenBase.TypeGenBase.__sizeof__()) - if SubTypeGenBase is None: - stdio.printf("FAIL: TypeGenBase alloc failed\n") - stdlib.exit(1) - string.memset(SubTypeGenBase, 0, TypeGenBase.TypeGenBase.__sizeof__()) - SubTypeGenBase.Gen = self - self.TypeGenBase = SubTypeGenBase - SubTypeGen: TypeGenMixin.TypeGenMixin | t.CPtr = CompilerFactory.factory.PermPool.alloc(TypeGenMixin.TypeGenMixin.__sizeof__()) - if SubTypeGen is None: - stdio.printf("FAIL: TypeGenMixin alloc failed\n") - stdlib.exit(1) - string.memset(SubTypeGen, 0, TypeGenMixin.TypeGenMixin.__sizeof__()) - SubTypeGen.Gen = self - self.TypeGen = SubTypeGen - SubTypeGenCDef: TypeGenCDef.TypeGenCDef | t.CPtr = CompilerFactory.factory.PermPool.alloc(TypeGenCDef.TypeGenCDef.__sizeof__()) - if SubTypeGenCDef is None: - stdio.printf("FAIL: TypeGenCDef alloc failed\n") - stdlib.exit(1) - string.memset(SubTypeGenCDef, 0, TypeGenCDef.TypeGenCDef.__sizeof__()) - SubTypeGenCDef.Gen = self - self.TypeGenCDef = SubTypeGenCDef - SubTypeGenCType: TypeGenCType.TypeGenCType | t.CPtr = CompilerFactory.factory.PermPool.alloc(TypeGenCType.TypeGenCType.__sizeof__()) - if SubTypeGenCType is None: - stdio.printf("FAIL: TypeGenCType alloc failed\n") - stdlib.exit(1) - string.memset(SubTypeGenCType, 0, TypeGenCType.TypeGenCType.__sizeof__()) - SubTypeGenCType.Gen = self - self.TypeGenCType = SubTypeGenCType - SubTypeGenResolve: TypeGenResolve.TypeGenResolve | t.CPtr = CompilerFactory.factory.PermPool.alloc(TypeGenResolve.TypeGenResolve.__sizeof__()) - if SubTypeGenResolve is None: - stdio.printf("FAIL: TypeGenResolve alloc failed\n") - stdlib.exit(1) - string.memset(SubTypeGenResolve, 0, TypeGenResolve.TypeGenResolve.__sizeof__()) - SubTypeGenResolve.Gen = self - self.TypeGenResolve = SubTypeGenResolve - SubTypeGenErr: TypeGenErr.TypeGenErr | t.CPtr = CompilerFactory.factory.PermPool.alloc(TypeGenErr.TypeGenErr.__sizeof__()) - if SubTypeGenErr is None: - stdio.printf("FAIL: TypeGenErr alloc failed\n") - stdlib.exit(1) - string.memset(SubTypeGenErr, 0, TypeGenErr.TypeGenErr.__sizeof__()) - SubTypeGenErr.Gen = self - self.TypeGenErr = SubTypeGenErr - SubStructGen: StructGenMixin.StructGenMixin | t.CPtr = CompilerFactory.factory.PermPool.alloc(StructGenMixin.StructGenMixin.__sizeof__()) - if SubStructGen is None: - stdio.printf("FAIL: StructGenMixin alloc failed\n") - stdlib.exit(1) - string.memset(SubStructGen, 0, StructGenMixin.StructGenMixin.__sizeof__()) - SubStructGen.Gen = self - self.StructGen = SubStructGen - SubExprGenBase: ExprGenBase.ExprGenBase | t.CPtr = CompilerFactory.factory.PermPool.alloc(ExprGenBase.ExprGenBase.__sizeof__()) - if SubExprGenBase is None: - stdio.printf("FAIL: ExprGenBase alloc failed\n") - stdlib.exit(1) - string.memset(SubExprGenBase, 0, ExprGenBase.ExprGenBase.__sizeof__()) - SubExprGenBase.Gen = self - self.ExprGenBase = SubExprGenBase - SubExprGen: ExprGenMixin.ExprGenMixin | t.CPtr = CompilerFactory.factory.PermPool.alloc(ExprGenMixin.ExprGenMixin.__sizeof__()) - if SubExprGen is None: - stdio.printf("FAIL: ExprGenMixin alloc failed\n") - stdlib.exit(1) - string.memset(SubExprGen, 0, ExprGenMixin.ExprGenMixin.__sizeof__()) - SubExprGen.Gen = self - self.ExprGen = SubExprGen - SubExprGenConst: ExprGenConst.ExprGenConst | t.CPtr = CompilerFactory.factory.PermPool.alloc(ExprGenConst.ExprGenConst.__sizeof__()) - if SubExprGenConst is None: - stdio.printf("FAIL: ExprGenConst alloc failed\n") - stdlib.exit(1) - string.memset(SubExprGenConst, 0, ExprGenConst.ExprGenConst.__sizeof__()) - SubExprGenConst.Gen = self - self.ExprGenConst = SubExprGenConst - SubExprGenFstr: ExprGenFstr.ExprGenFstr | t.CPtr = CompilerFactory.factory.PermPool.alloc(ExprGenFstr.ExprGenFstr.__sizeof__()) - if SubExprGenFstr is None: - stdio.printf("FAIL: ExprGenFstr alloc failed\n") - stdlib.exit(1) - string.memset(SubExprGenFstr, 0, ExprGenFstr.ExprGenFstr.__sizeof__()) - SubExprGenFstr.Gen = self - self.ExprGenFstr = SubExprGenFstr - SubExprGenOps: ExprGenOps.ExprGenOps | t.CPtr = CompilerFactory.factory.PermPool.alloc(ExprGenOps.ExprGenOps.__sizeof__()) - if SubExprGenOps is None: - stdio.printf("FAIL: ExprGenOps alloc failed\n") - stdlib.exit(1) - string.memset(SubExprGenOps, 0, ExprGenOps.ExprGenOps.__sizeof__()) - SubExprGenOps.Gen = self - self.ExprGenOps = SubExprGenOps - SubExprGenCdef: ExprGenCdef.ExprGenCdef | t.CPtr = CompilerFactory.factory.PermPool.alloc(ExprGenCdef.ExprGenCdef.__sizeof__()) - if SubExprGenCdef is None: - stdio.printf("FAIL: ExprGenCdef alloc failed\n") - stdlib.exit(1) - string.memset(SubExprGenCdef, 0, ExprGenCdef.ExprGenCdef.__sizeof__()) - SubExprGenCdef.Gen = self - self.ExprGenCdef = SubExprGenCdef - SubExprGenName: ExprGenName.ExprGenName | t.CPtr = CompilerFactory.factory.PermPool.alloc(ExprGenName.ExprGenName.__sizeof__()) - if SubExprGenName is None: - stdio.printf("FAIL: ExprGenName alloc failed\n") - stdlib.exit(1) - string.memset(SubExprGenName, 0, ExprGenName.ExprGenName.__sizeof__()) - SubExprGenName.Gen = self - self.ExprGenName = SubExprGenName - SubExprGenAttr: ExprGenAttr.ExprGenAttr | t.CPtr = CompilerFactory.factory.PermPool.alloc(ExprGenAttr.ExprGenAttr.__sizeof__()) - if SubExprGenAttr is None: - stdio.printf("FAIL: ExprGenAttr alloc failed\n") - stdlib.exit(1) - string.memset(SubExprGenAttr, 0, ExprGenAttr.ExprGenAttr.__sizeof__()) - SubExprGenAttr.Gen = self - self.ExprGenAttr = SubExprGenAttr - SubExprGenCls: ExprGenCls.ExprGenCls | t.CPtr = CompilerFactory.factory.PermPool.alloc(ExprGenCls.ExprGenCls.__sizeof__()) - if SubExprGenCls is None: - stdio.printf("FAIL: ExprGenCls alloc failed\n") - stdlib.exit(1) - string.memset(SubExprGenCls, 0, ExprGenCls.ExprGenCls.__sizeof__()) - SubExprGenCls.Gen = self - self.ExprGenCls = SubExprGenCls - SubCallGenBase: CallGenBase.CallGenBase | t.CPtr = CompilerFactory.factory.PermPool.alloc(CallGenBase.CallGenBase.__sizeof__()) - if SubCallGenBase is None: - stdio.printf("FAIL: CallGenBase alloc failed\n") - stdlib.exit(1) - string.memset(SubCallGenBase, 0, CallGenBase.CallGenBase.__sizeof__()) - SubCallGenBase.Gen = self - self.CallGenBase = SubCallGenBase - SubCallGenCBuiltin: CallGenCBuiltin.CallGenCBuiltin | t.CPtr = CompilerFactory.factory.PermPool.alloc(CallGenCBuiltin.CallGenCBuiltin.__sizeof__()) - if SubCallGenCBuiltin is None: - stdio.printf("FAIL: CallGenCBuiltin alloc failed\n") - stdlib.exit(1) - string.memset(SubCallGenCBuiltin, 0, CallGenCBuiltin.CallGenCBuiltin.__sizeof__()) - SubCallGenCBuiltin.Gen = self - self.CallGenCBuiltin = SubCallGenCBuiltin - SubCallGenLeafKit: CallGenLeafKit.CallGenLeafKit | t.CPtr = CompilerFactory.factory.PermPool.alloc(CallGenLeafKit.CallGenLeafKit.__sizeof__()) - if SubCallGenLeafKit is None: - stdio.printf("FAIL: CallGenLeafKit alloc failed\n") - stdlib.exit(1) - string.memset(SubCallGenLeafKit, 0, CallGenLeafKit.CallGenLeafKit.__sizeof__()) - SubCallGenLeafKit.Gen = self - self.CallGenLeafKit = SubCallGenLeafKit - SubCallGenCtor: CallGenCtor.CallGenCtor | t.CPtr = CompilerFactory.factory.PermPool.alloc(CallGenCtor.CallGenCtor.__sizeof__()) - if SubCallGenCtor is None: - stdio.printf("FAIL: CallGenCtor alloc failed\n") - stdlib.exit(1) - string.memset(SubCallGenCtor, 0, CallGenCtor.CallGenCtor.__sizeof__()) - SubCallGenCtor.Gen = self - self.CallGenCtor = SubCallGenCtor - SubCallGenCall: CallGenCall.CallGenCall | t.CPtr = CompilerFactory.factory.PermPool.alloc(CallGenCall.CallGenCall.__sizeof__()) - if SubCallGenCall is None: - stdio.printf("FAIL: CallGenCall alloc failed\n") - stdlib.exit(1) - string.memset(SubCallGenCall, 0, CallGenCall.CallGenCall.__sizeof__()) - SubCallGenCall.Gen = self - self.CallGenCall = SubCallGenCall - SubCallGen: CallGenMixin.CallGenMixin | t.CPtr = CompilerFactory.factory.PermPool.alloc(CallGenMixin.CallGenMixin.__sizeof__()) - if SubCallGen is None: - stdio.printf("FAIL: CallGenMixin alloc failed\n") - stdlib.exit(1) - string.memset(SubCallGen, 0, CallGenMixin.CallGenMixin.__sizeof__()) - SubCallGen.Gen = self - self.CallGen = SubCallGen - SubCallGenDispatch: CallGenDispatch.CallGenDispatch | t.CPtr = CompilerFactory.factory.PermPool.alloc(CallGenDispatch.CallGenDispatch.__sizeof__()) - if SubCallGenDispatch is None: - stdio.printf("FAIL: CallGenDispatch alloc failed\n") - stdlib.exit(1) - string.memset(SubCallGenDispatch, 0, CallGenDispatch.CallGenDispatch.__sizeof__()) - SubCallGenDispatch.Gen = self - self.CallGenDispatch = SubCallGenDispatch - SubCallGenLib: CallGenLib.CallGenLib | t.CPtr = CompilerFactory.factory.PermPool.alloc(CallGenLib.CallGenLib.__sizeof__()) - if SubCallGenLib is None: - stdio.printf("FAIL: CallGenLib alloc failed\n") - stdlib.exit(1) - string.memset(SubCallGenLib, 0, CallGenLib.CallGenLib.__sizeof__()) - SubCallGenLib.Gen = self - self.CallGenLib = SubCallGenLib - SubCallGenVt: CallGenVt.CallGenVt | t.CPtr = CompilerFactory.factory.PermPool.alloc(CallGenVt.CallGenVt.__sizeof__()) - if SubCallGenVt is None: - stdio.printf("FAIL: CallGenVt alloc failed\n") - stdlib.exit(1) - string.memset(SubCallGenVt, 0, CallGenVt.CallGenVt.__sizeof__()) - SubCallGenVt.Gen = self - self.CallGenVt = SubCallGenVt - SubCallGenVa: CallGenVa.CallGenVa | t.CPtr = CompilerFactory.factory.PermPool.alloc(CallGenVa.CallGenVa.__sizeof__()) - if SubCallGenVa is None: - stdio.printf("FAIL: CallGenVa alloc failed\n") - stdlib.exit(1) - string.memset(SubCallGenVa, 0, CallGenVa.CallGenVa.__sizeof__()) - SubCallGenVa.Gen = self - self.CallGenVa = SubCallGenVa - SubCallGenProp: CallGenProp.CallGenProp | t.CPtr = CompilerFactory.factory.PermPool.alloc(CallGenProp.CallGenProp.__sizeof__()) - if SubCallGenProp is None: - stdio.printf("FAIL: CallGenProp alloc failed\n") - stdlib.exit(1) - string.memset(SubCallGenProp, 0, CallGenProp.CallGenProp.__sizeof__()) - SubCallGenProp.Gen = self - self.CallGenProp = SubCallGenProp - SubCallGenFd: CallGenFd.CallGenFd | t.CPtr = CompilerFactory.factory.PermPool.alloc(CallGenFd.CallGenFd.__sizeof__()) - if SubCallGenFd is None: - stdio.printf("FAIL: CallGenFd alloc failed\n") - stdlib.exit(1) - string.memset(SubCallGenFd, 0, CallGenFd.CallGenFd.__sizeof__()) - SubCallGenFd.Gen = self - self.CallGenFd = SubCallGenFd - SubFuncGenBase: FuncGenBase.FuncGenBase | t.CPtr = CompilerFactory.factory.PermPool.alloc(FuncGenBase.FuncGenBase.__sizeof__()) - if SubFuncGenBase is None: - stdio.printf("FAIL: FuncGenBase alloc failed\n") - stdlib.exit(1) - string.memset(SubFuncGenBase, 0, FuncGenBase.FuncGenBase.__sizeof__()) - SubFuncGenBase.Gen = self - self.FuncGenBase = SubFuncGenBase - SubFuncGenDef: FuncGenDef.FuncGenDef | t.CPtr = CompilerFactory.factory.PermPool.alloc(FuncGenDef.FuncGenDef.__sizeof__()) - if SubFuncGenDef is None: - stdio.printf("FAIL: FuncGenDef alloc failed\n") - stdlib.exit(1) - string.memset(SubFuncGenDef, 0, FuncGenDef.FuncGenDef.__sizeof__()) - SubFuncGenDef.Gen = self - self.FuncGenDef = SubFuncGenDef - SubFuncGen: FuncGenMixin.FuncGenMixin | t.CPtr = CompilerFactory.factory.PermPool.alloc(FuncGenMixin.FuncGenMixin.__sizeof__()) - if SubFuncGen is None: - stdio.printf("FAIL: FuncGenMixin alloc failed\n") - stdlib.exit(1) - string.memset(SubFuncGen, 0, FuncGenMixin.FuncGenMixin.__sizeof__()) - SubFuncGen.Gen = self - self.FuncGen = SubFuncGen - SubClassGenBase: ClassGenBase.ClassGenBase | t.CPtr = CompilerFactory.factory.PermPool.alloc(ClassGenBase.ClassGenBase.__sizeof__()) - if SubClassGenBase is None: - stdio.printf("FAIL: ClassGenBase alloc failed\n") - stdlib.exit(1) - string.memset(SubClassGenBase, 0, ClassGenBase.ClassGenBase.__sizeof__()) - SubClassGenBase.Gen = self - self.ClassGenBase = SubClassGenBase - SubClassGen: ClassGenMixin.ClassGenMixin | t.CPtr = CompilerFactory.factory.PermPool.alloc(ClassGenMixin.ClassGenMixin.__sizeof__()) - if SubClassGen is None: - stdio.printf("FAIL: ClassGenMixin alloc failed\n") - stdlib.exit(1) - string.memset(SubClassGen, 0, ClassGenMixin.ClassGenMixin.__sizeof__()) - SubClassGen.Gen = self - self.ClassGen = SubClassGen - SubClassGenEnum: ClassGenEnum.ClassGenEnum | t.CPtr = CompilerFactory.factory.PermPool.alloc(ClassGenEnum.ClassGenEnum.__sizeof__()) - if SubClassGenEnum is None: - stdio.printf("FAIL: ClassGenEnum alloc failed\n") - stdlib.exit(1) - string.memset(SubClassGenEnum, 0, ClassGenEnum.ClassGenEnum.__sizeof__()) - SubClassGenEnum.Gen = self - self.ClassGenEnum = SubClassGenEnum - SubClassGenGeneric: ClassGenGeneric.ClassGenGeneric | t.CPtr = CompilerFactory.factory.PermPool.alloc(ClassGenGeneric.ClassGenGeneric.__sizeof__()) - if SubClassGenGeneric is None: - stdio.printf("FAIL: ClassGenGeneric alloc failed\n") - stdlib.exit(1) - string.memset(SubClassGenGeneric, 0, ClassGenGeneric.ClassGenGeneric.__sizeof__()) - SubClassGenGeneric.Gen = self - self.ClassGenGeneric = SubClassGenGeneric - SubClassGenVTable: ClassGenVTable.ClassGenVTable | t.CPtr = CompilerFactory.factory.PermPool.alloc(ClassGenVTable.ClassGenVTable.__sizeof__()) - if SubClassGenVTable is None: - stdio.printf("FAIL: ClassGenVTable alloc failed\n") - stdlib.exit(1) - string.memset(SubClassGenVTable, 0, ClassGenVTable.ClassGenVTable.__sizeof__()) - SubClassGenVTable.Gen = self - self.ClassGenVTable = SubClassGenVTable - SubClassGenDef: ClassGenDef.ClassGenDef | t.CPtr = CompilerFactory.factory.PermPool.alloc(ClassGenDef.ClassGenDef.__sizeof__()) - if SubClassGenDef is None: - stdio.printf("FAIL: ClassGenDef alloc failed\n") - stdlib.exit(1) - string.memset(SubClassGenDef, 0, ClassGenDef.ClassGenDef.__sizeof__()) - SubClassGenDef.Gen = self - self.ClassGenDef = SubClassGenDef - SubImportsGen: ImportsGenMixin.ImportsGenMixin | t.CPtr = CompilerFactory.factory.PermPool.alloc(ImportsGenMixin.ImportsGenMixin.__sizeof__()) - if SubImportsGen is None: - stdio.printf("FAIL: ImportsGenMixin alloc failed\n") - stdlib.exit(1) - string.memset(SubImportsGen, 0, ImportsGenMixin.ImportsGenMixin.__sizeof__()) - SubImportsGen.Gen = self - self.ImportsGen = SubImportsGen - SubStmtGenCif: StmtGenCifMixin.StmtGenCifMixin | t.CPtr = CompilerFactory.factory.PermPool.alloc(StmtGenCifMixin.StmtGenCifMixin.__sizeof__()) - if SubStmtGenCif is None: - stdio.printf("FAIL: StmtGenCifMixin alloc failed\n") - stdlib.exit(1) - string.memset(SubStmtGenCif, 0, StmtGenCifMixin.StmtGenCifMixin.__sizeof__()) - SubStmtGenCif.Gen = self - self.StmtGenCif = SubStmtGenCif - SubStmtGenDecl: StmtGenDeclMixin.StmtGenDeclMixin | t.CPtr = CompilerFactory.factory.PermPool.alloc(StmtGenDeclMixin.StmtGenDeclMixin.__sizeof__()) - if SubStmtGenDecl is None: - stdio.printf("FAIL: StmtGenDeclMixin alloc failed\n") - stdlib.exit(1) - string.memset(SubStmtGenDecl, 0, StmtGenDeclMixin.StmtGenDeclMixin.__sizeof__()) - SubStmtGenDecl.Gen = self - self.StmtGenDecl = SubStmtGenDecl - SubStmtGen: StmtGenMixin.StmtGenMixin | t.CPtr = CompilerFactory.factory.PermPool.alloc(StmtGenMixin.StmtGenMixin.__sizeof__()) - if SubStmtGen is None: - stdio.printf("FAIL: StmtGenMixin alloc failed\n") - stdlib.exit(1) - string.memset(SubStmtGen, 0, StmtGenMixin.StmtGenMixin.__sizeof__()) - SubStmtGen.Gen = self - self.StmtGen = SubStmtGen - SubMatchGen: MatchGenMixin.MatchGenMixin | t.CPtr = CompilerFactory.factory.PermPool.alloc(MatchGenMixin.MatchGenMixin.__sizeof__()) - if SubMatchGen is None: - stdio.printf("FAIL: MatchGenMixin alloc failed\n") - stdlib.exit(1) - string.memset(SubMatchGen, 0, MatchGenMixin.MatchGenMixin.__sizeof__()) - SubMatchGen.Gen = self - self.MatchGen = SubMatchGen - SubAssignGen: AssignGenMixin.AssignGenMixin | t.CPtr = CompilerFactory.factory.PermPool.alloc(AssignGenMixin.AssignGenMixin.__sizeof__()) - if SubAssignGen is None: - stdio.printf("FAIL: AssignGenMixin alloc failed\n") - stdlib.exit(1) - string.memset(SubAssignGen, 0, AssignGenMixin.AssignGenMixin.__sizeof__()) - SubAssignGen.Gen = self - self.AssignGen = SubAssignGen - SubVarGen: VarGenMixin.VarGenMixin | t.CPtr = CompilerFactory.factory.PermPool.alloc(VarGenMixin.VarGenMixin.__sizeof__()) - if SubVarGen is None: - stdio.printf("FAIL: VarGenMixin alloc failed\n") - stdlib.exit(1) - string.memset(SubVarGen, 0, VarGenMixin.VarGenMixin.__sizeof__()) - SubVarGen.Gen = self - self.VarGen = SubVarGen - SubTranslatorGen: TranslatorGenMixin.TranslatorGenMixin | t.CPtr = CompilerFactory.factory.PermPool.alloc(TranslatorGenMixin.TranslatorGenMixin.__sizeof__()) - if SubTranslatorGen is None: - stdio.printf("FAIL: TranslatorGenMixin alloc failed\n") - stdlib.exit(1) - string.memset(SubTranslatorGen, 0, TranslatorGenMixin.TranslatorGenMixin.__sizeof__()) - SubTranslatorGen.Gen = self - self.TranslatorGen = SubTranslatorGen - SubAsyncGen: AsyncGenMixin.AsyncGenMixin | t.CPtr = CompilerFactory.factory.PermPool.alloc(AsyncGenMixin.AsyncGenMixin.__sizeof__()) - if SubAsyncGen is None: - stdio.printf("FAIL: AsyncGenMixin alloc failed\n") - stdlib.exit(1) - string.memset(SubAsyncGen, 0, AsyncGenMixin.AsyncGenMixin.__sizeof__()) - SubAsyncGen.Gen = self - self.AsyncGen = SubAsyncGen - - # ---- 初始化各子对象字段(Init* 方法内联调用) ---- - SubBaseGen.InitBaseGen(pool) - SubTypeGenBase.InitTypeGen() - SubCallGenBase.InitCallGen() - SubStructGen.InitStructGen() - SubClassGenBase.InitClassGen() - SubExprGenBase.InitExprGen() - SubImportsGen.InitImportsGen() - SubStmtGenCif.InitStmtGen() - SubAssignGen.InitAssignGen() - - -# ============================================================ -# 全局生成器单例(组合架构兼容层) -# ============================================================ -_g_gen: Generator | t.CPtr = None +import string +import lib.core.CompilerFactory as CompilerFactory +import t, c +from stdint import * +import stdio +import stdlib +import memhub +import llvmlite +import lib.core.Gen.BaseGenMixin as BaseGenMixin +import lib.core.Gen.Type.TypeGenBase as TypeGenBase +import lib.core.Gen.Type.TypeGenMixin as TypeGenMixin +import lib.core.Gen.Type.TypeGenCDef as TypeGenCDef +import lib.core.Gen.Type.TypeGenCType as TypeGenCType +import lib.core.Gen.Type.TypeGenResolve as TypeGenResolve +import lib.core.Gen.Type.TypeGenErr as TypeGenErr +import lib.core.Gen.StructGenMixin as StructGenMixin +import lib.core.Gen.Expr.ExprGenBase as ExprGenBase +import lib.core.Gen.Expr.ExprGenMixin as ExprGenMixin +import lib.core.Gen.Expr.ExprGenConst as ExprGenConst +import lib.core.Gen.Expr.ExprGenFstr as ExprGenFstr +import lib.core.Gen.Expr.ExprGenOps as ExprGenOps +import lib.core.Gen.Expr.ExprGenCdef as ExprGenCdef +import lib.core.Gen.Expr.ExprGenName as ExprGenName +import lib.core.Gen.Expr.ExprGenAttr as ExprGenAttr +import lib.core.Gen.Expr.ExprGenCls as ExprGenCls +import lib.core.Gen.Call.CallGenBase as CallGenBase +import lib.core.Gen.Call.CallGenCBuiltin as CallGenCBuiltin +import lib.core.Gen.Call.CallGenLeafKit as CallGenLeafKit +import lib.core.Gen.Call.CallGenCtor as CallGenCtor +import lib.core.Gen.Call.CallGenCall as CallGenCall +import lib.core.Gen.Call.CallGenMixin as CallGenMixin +import lib.core.Gen.Call.CallGenDispatch as CallGenDispatch +import lib.core.Gen.Call.CallGenLib as CallGenLib +import lib.core.Gen.Call.CallGenVt as CallGenVt +import lib.core.Gen.Call.CallGenVa as CallGenVa +import lib.core.Gen.Call.CallGenProp as CallGenProp +import lib.core.Gen.Call.CallGenFd as CallGenFd +import lib.core.Gen.Func.FuncGenBase as FuncGenBase +import lib.core.Gen.Func.FuncGenDef as FuncGenDef +import lib.core.Gen.Func.FuncGenMixin as FuncGenMixin +import lib.core.Gen.Class.ClassGenBase as ClassGenBase +import lib.core.Gen.Class.ClassGenMixin as ClassGenMixin +import lib.core.Gen.Class.ClassGenEnum as ClassGenEnum +import lib.core.Gen.Class.ClassGenGeneric as ClassGenGeneric +import lib.core.Gen.Class.ClassGenVTable as ClassGenVTable +import lib.core.Gen.Class.ClassGenDef as ClassGenDef +import lib.core.Gen.ImportsGenMixin as ImportsGenMixin +import lib.core.Gen.Stmt.StmtGenCifMixin as StmtGenCifMixin +import lib.core.Gen.Stmt.StmtGenDeclMixin as StmtGenDeclMixin +import lib.core.Gen.Stmt.StmtGenMixin as StmtGenMixin +import lib.core.Gen.MatchGenMixin as MatchGenMixin +import lib.core.Gen.AssignGenMixin as AssignGenMixin +import lib.core.Gen.AsyncGenMixin as AsyncGenMixin +import lib.core.Gen.VarGenMixin as VarGenMixin +import lib.core.Gen.TranslatorGenMixin as TranslatorGenMixin + + +# ============================================================ +# Generator - 生成器(双向引用组合架构) +# +# 不再 46 路多继承 Mixin;改为组合:Generator 持所有 GenMixin +# 子对象指针(永久池分配,全生命周期),每个 Mixin 持 Gen 回指。 +# 跨子对象访问 = self.Gen..<字段/方法>(链式有风险, +# 统一用中间变量取子对象再访问)。高亮可推导(显式类型注解)。 +# ============================================================ +@t.NoVTable +class Generator: + """生成器:持所有 GenMixin 子对象指针(双向引用组合)""" + + # ---- 子对象指针(46 个,永久池) ---- + BaseGen: BaseGenMixin.BaseGenMixin | t.CPtr + TypeGenBase: TypeGenBase.TypeGenBase | t.CPtr + TypeGen: TypeGenMixin.TypeGenMixin | t.CPtr + TypeGenCDef: TypeGenCDef.TypeGenCDef | t.CPtr + TypeGenCType: TypeGenCType.TypeGenCType | t.CPtr + TypeGenResolve: TypeGenResolve.TypeGenResolve | t.CPtr + TypeGenErr: TypeGenErr.TypeGenErr | t.CPtr + StructGen: StructGenMixin.StructGenMixin | t.CPtr + ExprGenBase: ExprGenBase.ExprGenBase | t.CPtr + ExprGen: ExprGenMixin.ExprGenMixin | t.CPtr + ExprGenConst: ExprGenConst.ExprGenConst | t.CPtr + ExprGenFstr: ExprGenFstr.ExprGenFstr | t.CPtr + ExprGenOps: ExprGenOps.ExprGenOps | t.CPtr + ExprGenCdef: ExprGenCdef.ExprGenCdef | t.CPtr + ExprGenName: ExprGenName.ExprGenName | t.CPtr + ExprGenAttr: ExprGenAttr.ExprGenAttr | t.CPtr + ExprGenCls: ExprGenCls.ExprGenCls | t.CPtr + CallGenBase: CallGenBase.CallGenBase | t.CPtr + CallGenCBuiltin: CallGenCBuiltin.CallGenCBuiltin | t.CPtr + CallGenLeafKit: CallGenLeafKit.CallGenLeafKit | t.CPtr + CallGenCtor: CallGenCtor.CallGenCtor | t.CPtr + CallGenCall: CallGenCall.CallGenCall | t.CPtr + CallGen: CallGenMixin.CallGenMixin | t.CPtr + CallGenDispatch: CallGenDispatch.CallGenDispatch | t.CPtr + CallGenLib: CallGenLib.CallGenLib | t.CPtr + CallGenVt: CallGenVt.CallGenVt | t.CPtr + CallGenVa: CallGenVa.CallGenVa | t.CPtr + CallGenProp: CallGenProp.CallGenProp | t.CPtr + CallGenFd: CallGenFd.CallGenFd | t.CPtr + FuncGenBase: FuncGenBase.FuncGenBase | t.CPtr + FuncGenDef: FuncGenDef.FuncGenDef | t.CPtr + FuncGen: FuncGenMixin.FuncGenMixin | t.CPtr + ClassGenBase: ClassGenBase.ClassGenBase | t.CPtr + ClassGen: ClassGenMixin.ClassGenMixin | t.CPtr + ClassGenEnum: ClassGenEnum.ClassGenEnum | t.CPtr + ClassGenGeneric: ClassGenGeneric.ClassGenGeneric | t.CPtr + ClassGenVTable: ClassGenVTable.ClassGenVTable | t.CPtr + ClassGenDef: ClassGenDef.ClassGenDef | t.CPtr + ImportsGen: ImportsGenMixin.ImportsGenMixin | t.CPtr + StmtGenCif: StmtGenCifMixin.StmtGenCifMixin | t.CPtr + StmtGenDecl: StmtGenDeclMixin.StmtGenDeclMixin | t.CPtr + StmtGen: StmtGenMixin.StmtGenMixin | t.CPtr + MatchGen: MatchGenMixin.MatchGenMixin | t.CPtr + AssignGen: AssignGenMixin.AssignGenMixin | t.CPtr + AsyncGen: AsyncGenMixin.AsyncGenMixin | t.CPtr + VarGen: VarGenMixin.VarGenMixin | t.CPtr + TranslatorGen: TranslatorGenMixin.TranslatorGenMixin | t.CPtr + + def __init__(self, pool: rowptr[memhub.MemBuddy]): + if self is None: + return + # ---- alloc 46 个子对象 + 回指(永久池,fail-fast) ---- + SubBaseGen: BaseGenMixin.BaseGenMixin | t.CPtr = CompilerFactory.factory.PermPool.alloc(BaseGenMixin.BaseGenMixin.__sizeof__()) + if SubBaseGen is None: + stdio.printf("FAIL: BaseGenMixin alloc failed\n") + stdlib.exit(1) + string.memset(SubBaseGen, 0, BaseGenMixin.BaseGenMixin.__sizeof__()) + SubBaseGen.Gen = self + self.BaseGen = SubBaseGen + SubTypeGenBase: TypeGenBase.TypeGenBase | t.CPtr = CompilerFactory.factory.PermPool.alloc(TypeGenBase.TypeGenBase.__sizeof__()) + if SubTypeGenBase is None: + stdio.printf("FAIL: TypeGenBase alloc failed\n") + stdlib.exit(1) + string.memset(SubTypeGenBase, 0, TypeGenBase.TypeGenBase.__sizeof__()) + SubTypeGenBase.Gen = self + self.TypeGenBase = SubTypeGenBase + SubTypeGen: TypeGenMixin.TypeGenMixin | t.CPtr = CompilerFactory.factory.PermPool.alloc(TypeGenMixin.TypeGenMixin.__sizeof__()) + if SubTypeGen is None: + stdio.printf("FAIL: TypeGenMixin alloc failed\n") + stdlib.exit(1) + string.memset(SubTypeGen, 0, TypeGenMixin.TypeGenMixin.__sizeof__()) + SubTypeGen.Gen = self + self.TypeGen = SubTypeGen + SubTypeGenCDef: TypeGenCDef.TypeGenCDef | t.CPtr = CompilerFactory.factory.PermPool.alloc(TypeGenCDef.TypeGenCDef.__sizeof__()) + if SubTypeGenCDef is None: + stdio.printf("FAIL: TypeGenCDef alloc failed\n") + stdlib.exit(1) + string.memset(SubTypeGenCDef, 0, TypeGenCDef.TypeGenCDef.__sizeof__()) + SubTypeGenCDef.Gen = self + self.TypeGenCDef = SubTypeGenCDef + SubTypeGenCType: TypeGenCType.TypeGenCType | t.CPtr = CompilerFactory.factory.PermPool.alloc(TypeGenCType.TypeGenCType.__sizeof__()) + if SubTypeGenCType is None: + stdio.printf("FAIL: TypeGenCType alloc failed\n") + stdlib.exit(1) + string.memset(SubTypeGenCType, 0, TypeGenCType.TypeGenCType.__sizeof__()) + SubTypeGenCType.Gen = self + self.TypeGenCType = SubTypeGenCType + SubTypeGenResolve: TypeGenResolve.TypeGenResolve | t.CPtr = CompilerFactory.factory.PermPool.alloc(TypeGenResolve.TypeGenResolve.__sizeof__()) + if SubTypeGenResolve is None: + stdio.printf("FAIL: TypeGenResolve alloc failed\n") + stdlib.exit(1) + string.memset(SubTypeGenResolve, 0, TypeGenResolve.TypeGenResolve.__sizeof__()) + SubTypeGenResolve.Gen = self + self.TypeGenResolve = SubTypeGenResolve + SubTypeGenErr: TypeGenErr.TypeGenErr | t.CPtr = CompilerFactory.factory.PermPool.alloc(TypeGenErr.TypeGenErr.__sizeof__()) + if SubTypeGenErr is None: + stdio.printf("FAIL: TypeGenErr alloc failed\n") + stdlib.exit(1) + string.memset(SubTypeGenErr, 0, TypeGenErr.TypeGenErr.__sizeof__()) + SubTypeGenErr.Gen = self + self.TypeGenErr = SubTypeGenErr + SubStructGen: StructGenMixin.StructGenMixin | t.CPtr = CompilerFactory.factory.PermPool.alloc(StructGenMixin.StructGenMixin.__sizeof__()) + if SubStructGen is None: + stdio.printf("FAIL: StructGenMixin alloc failed\n") + stdlib.exit(1) + string.memset(SubStructGen, 0, StructGenMixin.StructGenMixin.__sizeof__()) + SubStructGen.Gen = self + self.StructGen = SubStructGen + SubExprGenBase: ExprGenBase.ExprGenBase | t.CPtr = CompilerFactory.factory.PermPool.alloc(ExprGenBase.ExprGenBase.__sizeof__()) + if SubExprGenBase is None: + stdio.printf("FAIL: ExprGenBase alloc failed\n") + stdlib.exit(1) + string.memset(SubExprGenBase, 0, ExprGenBase.ExprGenBase.__sizeof__()) + SubExprGenBase.Gen = self + self.ExprGenBase = SubExprGenBase + SubExprGen: ExprGenMixin.ExprGenMixin | t.CPtr = CompilerFactory.factory.PermPool.alloc(ExprGenMixin.ExprGenMixin.__sizeof__()) + if SubExprGen is None: + stdio.printf("FAIL: ExprGenMixin alloc failed\n") + stdlib.exit(1) + string.memset(SubExprGen, 0, ExprGenMixin.ExprGenMixin.__sizeof__()) + SubExprGen.Gen = self + self.ExprGen = SubExprGen + SubExprGenConst: ExprGenConst.ExprGenConst | t.CPtr = CompilerFactory.factory.PermPool.alloc(ExprGenConst.ExprGenConst.__sizeof__()) + if SubExprGenConst is None: + stdio.printf("FAIL: ExprGenConst alloc failed\n") + stdlib.exit(1) + string.memset(SubExprGenConst, 0, ExprGenConst.ExprGenConst.__sizeof__()) + SubExprGenConst.Gen = self + self.ExprGenConst = SubExprGenConst + SubExprGenFstr: ExprGenFstr.ExprGenFstr | t.CPtr = CompilerFactory.factory.PermPool.alloc(ExprGenFstr.ExprGenFstr.__sizeof__()) + if SubExprGenFstr is None: + stdio.printf("FAIL: ExprGenFstr alloc failed\n") + stdlib.exit(1) + string.memset(SubExprGenFstr, 0, ExprGenFstr.ExprGenFstr.__sizeof__()) + SubExprGenFstr.Gen = self + self.ExprGenFstr = SubExprGenFstr + SubExprGenOps: ExprGenOps.ExprGenOps | t.CPtr = CompilerFactory.factory.PermPool.alloc(ExprGenOps.ExprGenOps.__sizeof__()) + if SubExprGenOps is None: + stdio.printf("FAIL: ExprGenOps alloc failed\n") + stdlib.exit(1) + string.memset(SubExprGenOps, 0, ExprGenOps.ExprGenOps.__sizeof__()) + SubExprGenOps.Gen = self + self.ExprGenOps = SubExprGenOps + SubExprGenCdef: ExprGenCdef.ExprGenCdef | t.CPtr = CompilerFactory.factory.PermPool.alloc(ExprGenCdef.ExprGenCdef.__sizeof__()) + if SubExprGenCdef is None: + stdio.printf("FAIL: ExprGenCdef alloc failed\n") + stdlib.exit(1) + string.memset(SubExprGenCdef, 0, ExprGenCdef.ExprGenCdef.__sizeof__()) + SubExprGenCdef.Gen = self + self.ExprGenCdef = SubExprGenCdef + SubExprGenName: ExprGenName.ExprGenName | t.CPtr = CompilerFactory.factory.PermPool.alloc(ExprGenName.ExprGenName.__sizeof__()) + if SubExprGenName is None: + stdio.printf("FAIL: ExprGenName alloc failed\n") + stdlib.exit(1) + string.memset(SubExprGenName, 0, ExprGenName.ExprGenName.__sizeof__()) + SubExprGenName.Gen = self + self.ExprGenName = SubExprGenName + SubExprGenAttr: ExprGenAttr.ExprGenAttr | t.CPtr = CompilerFactory.factory.PermPool.alloc(ExprGenAttr.ExprGenAttr.__sizeof__()) + if SubExprGenAttr is None: + stdio.printf("FAIL: ExprGenAttr alloc failed\n") + stdlib.exit(1) + string.memset(SubExprGenAttr, 0, ExprGenAttr.ExprGenAttr.__sizeof__()) + SubExprGenAttr.Gen = self + self.ExprGenAttr = SubExprGenAttr + SubExprGenCls: ExprGenCls.ExprGenCls | t.CPtr = CompilerFactory.factory.PermPool.alloc(ExprGenCls.ExprGenCls.__sizeof__()) + if SubExprGenCls is None: + stdio.printf("FAIL: ExprGenCls alloc failed\n") + stdlib.exit(1) + string.memset(SubExprGenCls, 0, ExprGenCls.ExprGenCls.__sizeof__()) + SubExprGenCls.Gen = self + self.ExprGenCls = SubExprGenCls + SubCallGenBase: CallGenBase.CallGenBase | t.CPtr = CompilerFactory.factory.PermPool.alloc(CallGenBase.CallGenBase.__sizeof__()) + if SubCallGenBase is None: + stdio.printf("FAIL: CallGenBase alloc failed\n") + stdlib.exit(1) + string.memset(SubCallGenBase, 0, CallGenBase.CallGenBase.__sizeof__()) + SubCallGenBase.Gen = self + self.CallGenBase = SubCallGenBase + SubCallGenCBuiltin: CallGenCBuiltin.CallGenCBuiltin | t.CPtr = CompilerFactory.factory.PermPool.alloc(CallGenCBuiltin.CallGenCBuiltin.__sizeof__()) + if SubCallGenCBuiltin is None: + stdio.printf("FAIL: CallGenCBuiltin alloc failed\n") + stdlib.exit(1) + string.memset(SubCallGenCBuiltin, 0, CallGenCBuiltin.CallGenCBuiltin.__sizeof__()) + SubCallGenCBuiltin.Gen = self + self.CallGenCBuiltin = SubCallGenCBuiltin + SubCallGenLeafKit: CallGenLeafKit.CallGenLeafKit | t.CPtr = CompilerFactory.factory.PermPool.alloc(CallGenLeafKit.CallGenLeafKit.__sizeof__()) + if SubCallGenLeafKit is None: + stdio.printf("FAIL: CallGenLeafKit alloc failed\n") + stdlib.exit(1) + string.memset(SubCallGenLeafKit, 0, CallGenLeafKit.CallGenLeafKit.__sizeof__()) + SubCallGenLeafKit.Gen = self + self.CallGenLeafKit = SubCallGenLeafKit + SubCallGenCtor: CallGenCtor.CallGenCtor | t.CPtr = CompilerFactory.factory.PermPool.alloc(CallGenCtor.CallGenCtor.__sizeof__()) + if SubCallGenCtor is None: + stdio.printf("FAIL: CallGenCtor alloc failed\n") + stdlib.exit(1) + string.memset(SubCallGenCtor, 0, CallGenCtor.CallGenCtor.__sizeof__()) + SubCallGenCtor.Gen = self + self.CallGenCtor = SubCallGenCtor + SubCallGenCall: CallGenCall.CallGenCall | t.CPtr = CompilerFactory.factory.PermPool.alloc(CallGenCall.CallGenCall.__sizeof__()) + if SubCallGenCall is None: + stdio.printf("FAIL: CallGenCall alloc failed\n") + stdlib.exit(1) + string.memset(SubCallGenCall, 0, CallGenCall.CallGenCall.__sizeof__()) + SubCallGenCall.Gen = self + self.CallGenCall = SubCallGenCall + SubCallGen: CallGenMixin.CallGenMixin | t.CPtr = CompilerFactory.factory.PermPool.alloc(CallGenMixin.CallGenMixin.__sizeof__()) + if SubCallGen is None: + stdio.printf("FAIL: CallGenMixin alloc failed\n") + stdlib.exit(1) + string.memset(SubCallGen, 0, CallGenMixin.CallGenMixin.__sizeof__()) + SubCallGen.Gen = self + self.CallGen = SubCallGen + SubCallGenDispatch: CallGenDispatch.CallGenDispatch | t.CPtr = CompilerFactory.factory.PermPool.alloc(CallGenDispatch.CallGenDispatch.__sizeof__()) + if SubCallGenDispatch is None: + stdio.printf("FAIL: CallGenDispatch alloc failed\n") + stdlib.exit(1) + string.memset(SubCallGenDispatch, 0, CallGenDispatch.CallGenDispatch.__sizeof__()) + SubCallGenDispatch.Gen = self + self.CallGenDispatch = SubCallGenDispatch + SubCallGenLib: CallGenLib.CallGenLib | t.CPtr = CompilerFactory.factory.PermPool.alloc(CallGenLib.CallGenLib.__sizeof__()) + if SubCallGenLib is None: + stdio.printf("FAIL: CallGenLib alloc failed\n") + stdlib.exit(1) + string.memset(SubCallGenLib, 0, CallGenLib.CallGenLib.__sizeof__()) + SubCallGenLib.Gen = self + self.CallGenLib = SubCallGenLib + SubCallGenVt: CallGenVt.CallGenVt | t.CPtr = CompilerFactory.factory.PermPool.alloc(CallGenVt.CallGenVt.__sizeof__()) + if SubCallGenVt is None: + stdio.printf("FAIL: CallGenVt alloc failed\n") + stdlib.exit(1) + string.memset(SubCallGenVt, 0, CallGenVt.CallGenVt.__sizeof__()) + SubCallGenVt.Gen = self + self.CallGenVt = SubCallGenVt + SubCallGenVa: CallGenVa.CallGenVa | t.CPtr = CompilerFactory.factory.PermPool.alloc(CallGenVa.CallGenVa.__sizeof__()) + if SubCallGenVa is None: + stdio.printf("FAIL: CallGenVa alloc failed\n") + stdlib.exit(1) + string.memset(SubCallGenVa, 0, CallGenVa.CallGenVa.__sizeof__()) + SubCallGenVa.Gen = self + self.CallGenVa = SubCallGenVa + SubCallGenProp: CallGenProp.CallGenProp | t.CPtr = CompilerFactory.factory.PermPool.alloc(CallGenProp.CallGenProp.__sizeof__()) + if SubCallGenProp is None: + stdio.printf("FAIL: CallGenProp alloc failed\n") + stdlib.exit(1) + string.memset(SubCallGenProp, 0, CallGenProp.CallGenProp.__sizeof__()) + SubCallGenProp.Gen = self + self.CallGenProp = SubCallGenProp + SubCallGenFd: CallGenFd.CallGenFd | t.CPtr = CompilerFactory.factory.PermPool.alloc(CallGenFd.CallGenFd.__sizeof__()) + if SubCallGenFd is None: + stdio.printf("FAIL: CallGenFd alloc failed\n") + stdlib.exit(1) + string.memset(SubCallGenFd, 0, CallGenFd.CallGenFd.__sizeof__()) + SubCallGenFd.Gen = self + self.CallGenFd = SubCallGenFd + SubFuncGenBase: FuncGenBase.FuncGenBase | t.CPtr = CompilerFactory.factory.PermPool.alloc(FuncGenBase.FuncGenBase.__sizeof__()) + if SubFuncGenBase is None: + stdio.printf("FAIL: FuncGenBase alloc failed\n") + stdlib.exit(1) + string.memset(SubFuncGenBase, 0, FuncGenBase.FuncGenBase.__sizeof__()) + SubFuncGenBase.Gen = self + self.FuncGenBase = SubFuncGenBase + SubFuncGenDef: FuncGenDef.FuncGenDef | t.CPtr = CompilerFactory.factory.PermPool.alloc(FuncGenDef.FuncGenDef.__sizeof__()) + if SubFuncGenDef is None: + stdio.printf("FAIL: FuncGenDef alloc failed\n") + stdlib.exit(1) + string.memset(SubFuncGenDef, 0, FuncGenDef.FuncGenDef.__sizeof__()) + SubFuncGenDef.Gen = self + self.FuncGenDef = SubFuncGenDef + SubFuncGen: FuncGenMixin.FuncGenMixin | t.CPtr = CompilerFactory.factory.PermPool.alloc(FuncGenMixin.FuncGenMixin.__sizeof__()) + if SubFuncGen is None: + stdio.printf("FAIL: FuncGenMixin alloc failed\n") + stdlib.exit(1) + string.memset(SubFuncGen, 0, FuncGenMixin.FuncGenMixin.__sizeof__()) + SubFuncGen.Gen = self + self.FuncGen = SubFuncGen + SubClassGenBase: ClassGenBase.ClassGenBase | t.CPtr = CompilerFactory.factory.PermPool.alloc(ClassGenBase.ClassGenBase.__sizeof__()) + if SubClassGenBase is None: + stdio.printf("FAIL: ClassGenBase alloc failed\n") + stdlib.exit(1) + string.memset(SubClassGenBase, 0, ClassGenBase.ClassGenBase.__sizeof__()) + SubClassGenBase.Gen = self + self.ClassGenBase = SubClassGenBase + SubClassGen: ClassGenMixin.ClassGenMixin | t.CPtr = CompilerFactory.factory.PermPool.alloc(ClassGenMixin.ClassGenMixin.__sizeof__()) + if SubClassGen is None: + stdio.printf("FAIL: ClassGenMixin alloc failed\n") + stdlib.exit(1) + string.memset(SubClassGen, 0, ClassGenMixin.ClassGenMixin.__sizeof__()) + SubClassGen.Gen = self + self.ClassGen = SubClassGen + SubClassGenEnum: ClassGenEnum.ClassGenEnum | t.CPtr = CompilerFactory.factory.PermPool.alloc(ClassGenEnum.ClassGenEnum.__sizeof__()) + if SubClassGenEnum is None: + stdio.printf("FAIL: ClassGenEnum alloc failed\n") + stdlib.exit(1) + string.memset(SubClassGenEnum, 0, ClassGenEnum.ClassGenEnum.__sizeof__()) + SubClassGenEnum.Gen = self + self.ClassGenEnum = SubClassGenEnum + SubClassGenGeneric: ClassGenGeneric.ClassGenGeneric | t.CPtr = CompilerFactory.factory.PermPool.alloc(ClassGenGeneric.ClassGenGeneric.__sizeof__()) + if SubClassGenGeneric is None: + stdio.printf("FAIL: ClassGenGeneric alloc failed\n") + stdlib.exit(1) + string.memset(SubClassGenGeneric, 0, ClassGenGeneric.ClassGenGeneric.__sizeof__()) + SubClassGenGeneric.Gen = self + self.ClassGenGeneric = SubClassGenGeneric + SubClassGenVTable: ClassGenVTable.ClassGenVTable | t.CPtr = CompilerFactory.factory.PermPool.alloc(ClassGenVTable.ClassGenVTable.__sizeof__()) + if SubClassGenVTable is None: + stdio.printf("FAIL: ClassGenVTable alloc failed\n") + stdlib.exit(1) + string.memset(SubClassGenVTable, 0, ClassGenVTable.ClassGenVTable.__sizeof__()) + SubClassGenVTable.Gen = self + self.ClassGenVTable = SubClassGenVTable + SubClassGenDef: ClassGenDef.ClassGenDef | t.CPtr = CompilerFactory.factory.PermPool.alloc(ClassGenDef.ClassGenDef.__sizeof__()) + if SubClassGenDef is None: + stdio.printf("FAIL: ClassGenDef alloc failed\n") + stdlib.exit(1) + string.memset(SubClassGenDef, 0, ClassGenDef.ClassGenDef.__sizeof__()) + SubClassGenDef.Gen = self + self.ClassGenDef = SubClassGenDef + SubImportsGen: ImportsGenMixin.ImportsGenMixin | t.CPtr = CompilerFactory.factory.PermPool.alloc(ImportsGenMixin.ImportsGenMixin.__sizeof__()) + if SubImportsGen is None: + stdio.printf("FAIL: ImportsGenMixin alloc failed\n") + stdlib.exit(1) + string.memset(SubImportsGen, 0, ImportsGenMixin.ImportsGenMixin.__sizeof__()) + SubImportsGen.Gen = self + self.ImportsGen = SubImportsGen + SubStmtGenCif: StmtGenCifMixin.StmtGenCifMixin | t.CPtr = CompilerFactory.factory.PermPool.alloc(StmtGenCifMixin.StmtGenCifMixin.__sizeof__()) + if SubStmtGenCif is None: + stdio.printf("FAIL: StmtGenCifMixin alloc failed\n") + stdlib.exit(1) + string.memset(SubStmtGenCif, 0, StmtGenCifMixin.StmtGenCifMixin.__sizeof__()) + SubStmtGenCif.Gen = self + self.StmtGenCif = SubStmtGenCif + SubStmtGenDecl: StmtGenDeclMixin.StmtGenDeclMixin | t.CPtr = CompilerFactory.factory.PermPool.alloc(StmtGenDeclMixin.StmtGenDeclMixin.__sizeof__()) + if SubStmtGenDecl is None: + stdio.printf("FAIL: StmtGenDeclMixin alloc failed\n") + stdlib.exit(1) + string.memset(SubStmtGenDecl, 0, StmtGenDeclMixin.StmtGenDeclMixin.__sizeof__()) + SubStmtGenDecl.Gen = self + self.StmtGenDecl = SubStmtGenDecl + SubStmtGen: StmtGenMixin.StmtGenMixin | t.CPtr = CompilerFactory.factory.PermPool.alloc(StmtGenMixin.StmtGenMixin.__sizeof__()) + if SubStmtGen is None: + stdio.printf("FAIL: StmtGenMixin alloc failed\n") + stdlib.exit(1) + string.memset(SubStmtGen, 0, StmtGenMixin.StmtGenMixin.__sizeof__()) + SubStmtGen.Gen = self + self.StmtGen = SubStmtGen + SubMatchGen: MatchGenMixin.MatchGenMixin | t.CPtr = CompilerFactory.factory.PermPool.alloc(MatchGenMixin.MatchGenMixin.__sizeof__()) + if SubMatchGen is None: + stdio.printf("FAIL: MatchGenMixin alloc failed\n") + stdlib.exit(1) + string.memset(SubMatchGen, 0, MatchGenMixin.MatchGenMixin.__sizeof__()) + SubMatchGen.Gen = self + self.MatchGen = SubMatchGen + SubAssignGen: AssignGenMixin.AssignGenMixin | t.CPtr = CompilerFactory.factory.PermPool.alloc(AssignGenMixin.AssignGenMixin.__sizeof__()) + if SubAssignGen is None: + stdio.printf("FAIL: AssignGenMixin alloc failed\n") + stdlib.exit(1) + string.memset(SubAssignGen, 0, AssignGenMixin.AssignGenMixin.__sizeof__()) + SubAssignGen.Gen = self + self.AssignGen = SubAssignGen + SubVarGen: VarGenMixin.VarGenMixin | t.CPtr = CompilerFactory.factory.PermPool.alloc(VarGenMixin.VarGenMixin.__sizeof__()) + if SubVarGen is None: + stdio.printf("FAIL: VarGenMixin alloc failed\n") + stdlib.exit(1) + string.memset(SubVarGen, 0, VarGenMixin.VarGenMixin.__sizeof__()) + SubVarGen.Gen = self + self.VarGen = SubVarGen + SubTranslatorGen: TranslatorGenMixin.TranslatorGenMixin | t.CPtr = CompilerFactory.factory.PermPool.alloc(TranslatorGenMixin.TranslatorGenMixin.__sizeof__()) + if SubTranslatorGen is None: + stdio.printf("FAIL: TranslatorGenMixin alloc failed\n") + stdlib.exit(1) + string.memset(SubTranslatorGen, 0, TranslatorGenMixin.TranslatorGenMixin.__sizeof__()) + SubTranslatorGen.Gen = self + self.TranslatorGen = SubTranslatorGen + SubAsyncGen: AsyncGenMixin.AsyncGenMixin | t.CPtr = CompilerFactory.factory.PermPool.alloc(AsyncGenMixin.AsyncGenMixin.__sizeof__()) + if SubAsyncGen is None: + stdio.printf("FAIL: AsyncGenMixin alloc failed\n") + stdlib.exit(1) + string.memset(SubAsyncGen, 0, AsyncGenMixin.AsyncGenMixin.__sizeof__()) + SubAsyncGen.Gen = self + self.AsyncGen = SubAsyncGen + + # ---- 初始化各子对象字段(Init* 方法内联调用) ---- + SubBaseGen.InitBaseGen(pool) + SubTypeGenBase.InitTypeGen() + SubCallGenBase.InitCallGen() + SubStructGen.InitStructGen() + SubClassGenBase.InitClassGen() + SubExprGenBase.InitExprGen() + SubImportsGen.InitImportsGen() + SubStmtGenCif.InitStmtGen() + SubAssignGen.InitAssignGen() + + +# ============================================================ +# 全局生成器单例(组合架构兼容层) +# ============================================================ +_g_gen: Generator | t.CPtr = None diff --git a/App/lib/core/Gen/ImportsGenMixin.vp b/App/lib/core/Gen/ImportsGenMixin.vp index ad7dee7..67aae7f 100644 --- a/App/lib/core/Gen/ImportsGenMixin.vp +++ b/App/lib/core/Gen/ImportsGenMixin.vp @@ -56,7 +56,7 @@ class ImportsGenMixin: # ============================================================ # 添加已导入模块名 # ============================================================ - def add_imported_module(self, pool: memhub.MemBuddy | t.CPtr, + def add_imported_module(self, pool: rowptr[memhub.MemBuddy], imported_modules: str, name: str) -> str: """记录已导入的模块名,返回新的 imported_modules 字符串指针""" @@ -153,7 +153,7 @@ class ImportsGenMixin: # ============================================================ # 添加 from-import 名称映射 # ============================================================ - def add_from_import(self, pool: memhub.MemBuddy | t.CPtr, + def add_from_import(self, pool: rowptr[memhub.MemBuddy], from_imports: str, local_name: str, module_name: str, @@ -410,7 +410,7 @@ class ImportsGenMixin: # 解析后的完整模块名;绝对导入(level<=0)直接返回 module; # 无法解析时返回 module(回退到原始值) # ============================================================ - def _resolve_relative_module(self, pool: memhub.MemBuddy | t.CPtr, + def _resolve_relative_module(self, pool: rowptr[memhub.MemBuddy], current_package: str, level: int, module: str) -> str: @@ -483,7 +483,7 @@ class ImportsGenMixin: # "ast/parser.vp" → "ast" # "ast.vp" → None(顶级文件) # ============================================================ - def compute_package_from_relpath(self, pool: memhub.MemBuddy | t.CPtr, + def compute_package_from_relpath(self, pool: rowptr[memhub.MemBuddy], rel_path: str) -> str: """从相对路径计算包名(目录部分,分隔符替换为 .)""" if rel_path is None: @@ -677,7 +677,7 @@ class ImportsGenMixin: # 尚未包含后续才追加的模块(如 App 源文件),检查会造成误报 if trans._declare_only == 0: self._check_import_sha1(node, alias.name) - pool_val: memhub.MemBuddy | t.CPtr = trans.Pool + pool_val: rowptr[memhub.MemBuddy] = trans.Pool im_val: str = trans._imported_modules trans._imported_modules = self.add_imported_module( pool_val, im_val, alias.name) diff --git a/App/lib/core/Gen/MatchGenMixin.vp b/App/lib/core/Gen/MatchGenMixin.vp index e7777f9..c181cdc 100644 --- a/App/lib/core/Gen/MatchGenMixin.vp +++ b/App/lib/core/Gen/MatchGenMixin.vp @@ -91,7 +91,7 @@ class MatchGenMixin: node: ast.AST | t.CPtr) -> int: if node is None: return 0 - pool: memhub.MemBuddy | t.CPtr = trans.Pool + pool: rowptr[memhub.MemBuddy] = trans.Pool builder: llvmlite.IRBuilder | t.CPtr = trans._cur_builder func: llvmlite.Function | t.CPtr = trans._cur_func if builder is None or func is None: @@ -278,7 +278,7 @@ class MatchGenMixin: node: ast.Match | t.CPtr, renum_name: str, subject_ptr: llvmlite.Value | t.CPtr) -> int: - pool: memhub.MemBuddy | t.CPtr = trans.Pool + pool: rowptr[memhub.MemBuddy] = trans.Pool builder: llvmlite.IRBuilder | t.CPtr = trans._cur_builder func: llvmlite.Function | t.CPtr = trans._cur_func # 局部记录本 renum match 是否有 br 进入 end_bb,收尾时覆盖 @@ -618,7 +618,7 @@ class MatchGenMixin: renum_ty: llvmlite.LLVMType | t.CPtr, subject_ptr: llvmlite.Value | t.CPtr, trans: HT.Translator | t.CPtr, - pool: memhub.MemBuddy | t.CPtr, + pool: rowptr[memhub.MemBuddy], builder: llvmlite.IRBuilder | t.CPtr): if pat is None or renum_entry is None or renum_ty is None: return @@ -730,7 +730,7 @@ class MatchGenMixin: """对齐 lhs/rhs 后生成 icmp eq(指针统一 ptrtoint i64)""" if lhs is None or rhs is None or builder is None: return None - pool: memhub.MemBuddy | t.CPtr = trans.Pool + pool: rowptr[memhub.MemBuddy] = trans.Pool if self.Gen.ExprGenBase.is_ptr_type(lhs.Ty) != 0 \ or self.Gen.ExprGenBase.is_ptr_type(rhs.Ty) != 0: i64_ty: llvmlite.LLVMType | t.CPtr = llvmlite.Int64(pool) @@ -771,7 +771,7 @@ class MatchGenMixin: def _handle_sequence_match(self, trans: HT.Translator | t.CPtr, node: ast.Match | t.CPtr, subject_node: ast.AST | t.CPtr) -> int: - pool: memhub.MemBuddy | t.CPtr = trans.Pool + pool: rowptr[memhub.MemBuddy] = trans.Pool builder: llvmlite.IRBuilder | t.CPtr = trans._cur_builder func: llvmlite.Function | t.CPtr = trans._cur_func if builder is None or func is None: @@ -1105,7 +1105,7 @@ class MatchGenMixin: def _handle_simple_match(self, trans: HT.Translator | t.CPtr, node: ast.Match | t.CPtr, subject_val: llvmlite.Value | t.CPtr) -> int: - pool: memhub.MemBuddy | t.CPtr = trans.Pool + pool: rowptr[memhub.MemBuddy] = trans.Pool builder: llvmlite.IRBuilder | t.CPtr = trans._cur_builder func: llvmlite.Function | t.CPtr = trans._cur_func # 同主路径:局部记录本 simple match 的 br end_bb,收尾覆盖 diff --git a/App/lib/core/Gen/Stmt/StmtGenCifMixin.vp b/App/lib/core/Gen/Stmt/StmtGenCifMixin.vp index f4e16ca..8157d4f 100644 --- a/App/lib/core/Gen/Stmt/StmtGenCifMixin.vp +++ b/App/lib/core/Gen/Stmt/StmtGenCifMixin.vp @@ -10,7 +10,7 @@ import stdlib import stdio import viperlib import lib.core.VLogger as VLogger -import lib.core.Gen.Translator as HT +import lib.core.Gen.Translator as HT import lib.core.Gen.Type.TypeSpec as TSpec import lib.core.CompilerFactory as CompilerFactory import lib.Projectrans.Config as Config @@ -121,7 +121,7 @@ class StmtGenCifMixin: if string.strcmp(name, "NDEBUG") == 0: self.CifEvalOk = 1; return 0 return 0 - def _cif_name_value(self, pool: memhub.MemBuddy | t.CPtr, + def _cif_name_value(self, pool: rowptr[memhub.MemBuddy], trans: HT.Translator | t.CPtr, name: str) -> int: """查宏名值: 本地 CDefine → 跨模块 CDefine → 平台宏。 @@ -145,7 +145,7 @@ class StmtGenCifMixin: return pv return 0 - def _cif_attr_value(self, pool: memhub.MemBuddy | t.CPtr, + def _cif_attr_value(self, pool: rowptr[memhub.MemBuddy], trans: HT.Translator | t.CPtr, at: ast.Attribute | t.CPtr) -> int: """Attribute 宏值: platmacro.IS_WINDOWS → 本地 CDefine(attr) → 跨模块 CDefine。 @@ -190,7 +190,7 @@ class StmtGenCifMixin: return v2 return 0 - def _cif_eval_node(self, pool: memhub.MemBuddy | t.CPtr, + def _cif_eval_node(self, pool: rowptr[memhub.MemBuddy], trans: HT.Translator | t.CPtr, node: ast.AST | t.CPtr) -> int: """递归常量求值 CIf 表达式。 @@ -347,7 +347,7 @@ class StmtGenCifMixin: return 1 return 0 - def _cif_eval_call(self, pool: memhub.MemBuddy | t.CPtr, + def _cif_eval_call(self, pool: rowptr[memhub.MemBuddy], trans: HT.Translator | t.CPtr, node: ast.AST | t.CPtr) -> int: """编译期函数调用求值:ctraits.isptr(x)。 @@ -392,7 +392,7 @@ class StmtGenCifMixin: self.CifEvalOk = 1 return r - def _evaluate_cif_test(self, pool: memhub.MemBuddy | t.CPtr, + def _evaluate_cif_test(self, pool: rowptr[memhub.MemBuddy], trans: HT.Translator | t.CPtr, test: ast.AST | t.CPtr) -> int: """求值 CIf 调用(test 必须是 c.CIf 系调用)。 @@ -464,7 +464,7 @@ class StmtGenCifMixin: if rt is None: return 0 - pool: memhub.MemBuddy | t.CPtr = trans.Pool + pool: rowptr[memhub.MemBuddy] = trans.Pool builder: llvmlite.IRBuilder | t.CPtr = trans._cur_builder mod: llvmlite.LLVMModule | t.CPtr = trans.Module @@ -695,7 +695,7 @@ class StmtGenCifMixin: if node is None: return 0 - pool: memhub.MemBuddy | t.CPtr = trans.Pool + pool: rowptr[memhub.MemBuddy] = trans.Pool builder: llvmlite.IRBuilder | t.CPtr = trans._cur_builder func: llvmlite.Function | t.CPtr = trans._cur_func @@ -868,7 +868,7 @@ class StmtGenCifMixin: if node is None: return 0 - pool: memhub.MemBuddy | t.CPtr = trans.Pool + pool: rowptr[memhub.MemBuddy] = trans.Pool builder: llvmlite.IRBuilder | t.CPtr = trans._cur_builder func: llvmlite.Function | t.CPtr = trans._cur_func @@ -1039,7 +1039,7 @@ class StmtGenCifMixin: if node is None: return 0 - pool: memhub.MemBuddy | t.CPtr = trans.Pool + pool: rowptr[memhub.MemBuddy] = trans.Pool builder: llvmlite.IRBuilder | t.CPtr = trans._cur_builder func: llvmlite.Function | t.CPtr = trans._cur_func @@ -1511,7 +1511,7 @@ class StmtGenCifMixin: 循环变量 alloca 自动创建或复用;元素类型由源类型决定 (RANGE→i32, STR→i8, LIST→i8*)。索引内部统一 i64。 """ - pool: memhub.MemBuddy | t.CPtr = trans.Pool + pool: rowptr[memhub.MemBuddy] = trans.Pool builder: llvmlite.IRBuilder | t.CPtr = trans._cur_builder func: llvmlite.Function | t.CPtr = trans._cur_func @@ -1836,7 +1836,7 @@ class StmtGenCifMixin: for_node: ast.For | t.CPtr, var_name: str) -> int: """指针迭代: for x in ptr: 直到解引用为空""" - pool: memhub.MemBuddy | t.CPtr = trans.Pool + pool: rowptr[memhub.MemBuddy] = trans.Pool builder: llvmlite.IRBuilder | t.CPtr = trans._cur_builder func: llvmlite.Function | t.CPtr = trans._cur_func @@ -2001,7 +2001,7 @@ class StmtGenCifMixin: var_name: str, array_val: llvmlite.Value | t.CPtr) -> int: """数组迭代: for x in arr: 按数组长度迭代""" - pool: memhub.MemBuddy | t.CPtr = trans.Pool + pool: rowptr[memhub.MemBuddy] = trans.Pool builder: llvmlite.IRBuilder | t.CPtr = trans._cur_builder func: llvmlite.Function | t.CPtr = trans._cur_func @@ -2149,7 +2149,7 @@ class StmtGenCifMixin: var_name: str, list_node: ast.AST | t.CPtr) -> int: """列表字面量迭代: for x in [a, b, c]: 按元素顺序迭代""" - pool: memhub.MemBuddy | t.CPtr = trans.Pool + pool: rowptr[memhub.MemBuddy] = trans.Pool builder: llvmlite.IRBuilder | t.CPtr = trans._cur_builder lst: ast.List | t.CPtr = (ast.List | t.CPtr)(list_node) @@ -2234,7 +2234,7 @@ class StmtGenCifMixin: var_name: str, list_val: llvmlite.Value | t.CPtr) -> int: """list[T] 容器迭代: for v in lst: 按 __count__ 动态长度迭代""" - pool: memhub.MemBuddy | t.CPtr = trans.Pool + pool: rowptr[memhub.MemBuddy] = trans.Pool builder: llvmlite.IRBuilder | t.CPtr = trans._cur_builder func: llvmlite.Function | t.CPtr = trans._cur_func @@ -2347,7 +2347,7 @@ class StmtGenCifMixin: __iter__ 协议(__iter__ 重置 iter_index + __next__ 取 key)内联为 循环:iter_idx < __count__ → key = __keys__[iter_idx]。 """ - pool: memhub.MemBuddy | t.CPtr = trans.Pool + pool: rowptr[memhub.MemBuddy] = trans.Pool builder: llvmlite.IRBuilder | t.CPtr = trans._cur_builder func: llvmlite.Function | t.CPtr = trans._cur_func @@ -2479,7 +2479,7 @@ class StmtGenCifMixin: class_name: str, obj_val: llvmlite.Value | t.CPtr) -> int: """OOP iter 协议: for x in obj: 调用 __iter__/__next__ 迭代""" - pool: memhub.MemBuddy | t.CPtr = trans.Pool + pool: rowptr[memhub.MemBuddy] = trans.Pool builder: llvmlite.IRBuilder | t.CPtr = trans._cur_builder func: llvmlite.Function | t.CPtr = trans._cur_func mod: llvmlite.LLVMModule | t.CPtr = trans.Module diff --git a/App/lib/core/Gen/Stmt/StmtGenDeclMixin.vp b/App/lib/core/Gen/Stmt/StmtGenDeclMixin.vp index 2545225..b0ed01a 100644 --- a/App/lib/core/Gen/Stmt/StmtGenDeclMixin.vp +++ b/App/lib/core/Gen/Stmt/StmtGenDeclMixin.vp @@ -244,7 +244,7 @@ class StmtGenDeclMixin(StmtGenCifMixin.StmtGenCifMixin): """翻译 break 语句:跳转到循环 end 块""" builder: llvmlite.IRBuilder | t.CPtr = trans._cur_builder func: llvmlite.Function | t.CPtr = trans._cur_func - pool: memhub.MemBuddy | t.CPtr = trans.Pool + pool: rowptr[memhub.MemBuddy] = trans.Pool if builder is None or func is None: return 0 @@ -267,7 +267,7 @@ class StmtGenDeclMixin(StmtGenCifMixin.StmtGenCifMixin): """翻译 continue 语句:跳转到循环 cond/incr 块""" builder: llvmlite.IRBuilder | t.CPtr = trans._cur_builder func: llvmlite.Function | t.CPtr = trans._cur_func - pool: memhub.MemBuddy | t.CPtr = trans.Pool + pool: rowptr[memhub.MemBuddy] = trans.Pool if builder is None or func is None: return 0 @@ -313,7 +313,7 @@ class StmtGenDeclMixin(StmtGenCifMixin.StmtGenCifMixin): if env_var is not None: return env_var # 创建 alloca 存储 env - pool: memhub.MemBuddy | t.CPtr = trans.Pool + pool: rowptr[memhub.MemBuddy] = trans.Pool builder: llvmlite.IRBuilder | t.CPtr = trans._cur_builder i8_ty: llvmlite.LLVMType | t.CPtr = llvmlite.Int8(pool) i8_ptr_ty: llvmlite.LLVMType | t.CPtr = llvmlite.Ptr(pool, i8_ty) @@ -333,7 +333,7 @@ class StmtGenDeclMixin(StmtGenCifMixin.StmtGenCifMixin): if idx < 0: return None - pool: memhub.MemBuddy | t.CPtr = trans.Pool + pool: rowptr[memhub.MemBuddy] = trans.Pool builder: llvmlite.IRBuilder | t.CPtr = trans._cur_builder i8_ty: llvmlite.LLVMType | t.CPtr = llvmlite.Int8(pool) i8_ptr_ty: llvmlite.LLVMType | t.CPtr = llvmlite.Ptr(pool, i8_ty) @@ -369,7 +369,7 @@ class StmtGenDeclMixin(StmtGenCifMixin.StmtGenCifMixin): if raw_ptr is None: return None - pool: memhub.MemBuddy | t.CPtr = trans.Pool + pool: rowptr[memhub.MemBuddy] = trans.Pool builder: llvmlite.IRBuilder | t.CPtr = trans._cur_builder # 获取变量类型(从注册时存储的类型信息) @@ -395,7 +395,7 @@ class StmtGenDeclMixin(StmtGenCifMixin.StmtGenCifMixin): if raw_ptr is None: return None - pool: memhub.MemBuddy | t.CPtr = trans.Pool + pool: rowptr[memhub.MemBuddy] = trans.Pool builder: llvmlite.IRBuilder | t.CPtr = trans._cur_builder # 获取变量类型 @@ -412,7 +412,7 @@ class StmtGenDeclMixin(StmtGenCifMixin.StmtGenCifMixin): # 簇 E:枚举注册表(迁移自 HandlesEnum.vp) # ============================================================ - def init_enum_table(self, pool: memhub.MemBuddy | t.CPtr) -> int: + def init_enum_table(self, pool: rowptr[memhub.MemBuddy]) -> int: """初始化枚举注册表,返回 1 成功 表用 stdlib 分配(跨 Phase1 1b 的 mark/reset_to 存活——枚举表是 @@ -447,7 +447,7 @@ class StmtGenDeclMixin(StmtGenCifMixin.StmtGenCifMixin): addr: uint64 = uint64(enum_entry.Members) + i * member_size return (GenTypes.EnumMember | t.CPtr)(t.CVoid(addr, t.CPtr)) - def register_enum(self, pool: memhub.MemBuddy | t.CPtr, + def register_enum(self, pool: rowptr[memhub.MemBuddy], name: str, base_ty: llvmlite.LLVMType | t.CPtr) -> GenTypes.EnumEntry | t.CPtr: """注册枚举类型,返回 EnumEntry 指针""" @@ -501,7 +501,7 @@ class StmtGenDeclMixin(StmtGenCifMixin.StmtGenCifMixin): self.EnumCount += 1 return entry - def add_enum_member(self, pool: memhub.MemBuddy | t.CPtr, + def add_enum_member(self, pool: rowptr[memhub.MemBuddy], enum_entry: GenTypes.EnumEntry | t.CPtr, member_name: str, member_val: int64, diff --git a/App/lib/core/Gen/Stmt/StmtGenMixin.vp b/App/lib/core/Gen/Stmt/StmtGenMixin.vp index 124ab60..29fd18c 100644 --- a/App/lib/core/Gen/Stmt/StmtGenMixin.vp +++ b/App/lib/core/Gen/Stmt/StmtGenMixin.vp @@ -122,7 +122,7 @@ class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin): dnode: ast.Delete | t.CPtr = (ast.Delete | t.CPtr)(node) if dnode is None or dnode.targets is None: return 0 - pool: memhub.MemBuddy | t.CPtr = trans.Pool + pool: rowptr[memhub.MemBuddy] = trans.Pool mod: llvmlite.LLVMModule | t.CPtr = trans.Module builder: llvmlite.IRBuilder | t.CPtr = trans._cur_builder if pool is None or mod is None or builder is None: @@ -201,7 +201,7 @@ class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin): tr: ast.Try | t.CPtr = (ast.Try | t.CPtr)(node) if tr is None: return 0 - pool: memhub.MemBuddy | t.CPtr = trans.Pool + pool: rowptr[memhub.MemBuddy] = trans.Pool builder: llvmlite.IRBuilder | t.CPtr = trans._cur_builder func: llvmlite.Function | t.CPtr = trans._cur_func if pool is None or builder is None or func is None: @@ -447,7 +447,7 @@ class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin): """ if trans is None or node is None: return 0 - pool: memhub.MemBuddy | t.CPtr = trans.Pool + pool: rowptr[memhub.MemBuddy] = trans.Pool builder: llvmlite.IRBuilder | t.CPtr = trans._cur_builder mod: llvmlite.LLVMModule | t.CPtr = trans.Module if pool is None or builder is None or mod is None: @@ -547,7 +547,7 @@ class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin): # 终结(前一条是 raise/return)时跳过,避免在终止块后插指令。 # ============================================================ def _eh_ret_default(self, trans: HT.Translator | t.CPtr, - pool: memhub.MemBuddy | t.CPtr, + pool: rowptr[memhub.MemBuddy], builder: llvmlite.IRBuilder | t.CPtr) -> int: """异常路径返回当前函数默认零值,返回 0""" if trans is None or builder is None: @@ -601,7 +601,7 @@ class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin): wt: ast.With | t.CPtr = (ast.With | t.CPtr)(node) if wt is None: return 0 - pool: memhub.MemBuddy | t.CPtr = trans.Pool + pool: rowptr[memhub.MemBuddy] = trans.Pool builder: llvmlite.IRBuilder | t.CPtr = trans._cur_builder mod: llvmlite.LLVMModule | t.CPtr = trans.Module if pool is None or builder is None or mod is None: @@ -741,7 +741,7 @@ class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin): return 0 def _with_ctx_call(self, trans: HT.Translator | t.CPtr, - pool: memhub.MemBuddy | t.CPtr, + pool: rowptr[memhub.MemBuddy], builder: llvmlite.IRBuilder | t.CPtr, mod: llvmlite.LLVMModule | t.CPtr, method_name: str) -> llvmlite.Value | t.CPtr: diff --git a/App/lib/core/Gen/StructGenMixin.vp b/App/lib/core/Gen/StructGenMixin.vp index df060b1..1115d4d 100644 --- a/App/lib/core/Gen/StructGenMixin.vp +++ b/App/lib/core/Gen/StructGenMixin.vp @@ -87,7 +87,7 @@ class StructGenMixin: 避免跨 Mixin 直接读 self.StdlibAlloc——Mixin 方法体按自身块内索引编译)""" return self.StdlibAlloc - def reset_visible_structs(self, pool: memhub.MemBuddy | t.CPtr, strict: int) -> None: + def reset_visible_structs(self, pool: rowptr[memhub.MemBuddy], strict: int) -> None: """重置可见性状态(每个文件翻译前调用) pool: 内存分配器(严格模式下创建 HashTable) @@ -101,7 +101,7 @@ class StructGenMixin: # 宽松模式:全部可见,不需要 HashTable self.VisibleStructs = None - def add_visible_struct(self, pool: memhub.MemBuddy | t.CPtr, name: str) -> None: + def add_visible_struct(self, pool: rowptr[memhub.MemBuddy], name: str) -> None: """添加可见结构体名(类定义时和 from-import 时调用)""" if name is None: return @@ -123,7 +123,7 @@ class StructGenMixin: return 0 return self.VisibleStructs.__contains__(name) - def init_struct_table(self, pool: memhub.MemBuddy | t.CPtr) -> int: + def init_struct_table(self, pool: rowptr[memhub.MemBuddy]) -> int: """初始化结构体注册表,返回 1 成功 StdlibAlloc=1 时表体分配在 perm_pool:1a 每文件 reset 后表本体 @@ -134,7 +134,7 @@ class StructGenMixin: return 1 entry_size: sizet = GenTypes.StructEntry.__sizeof__() - table_pool: memhub.MemBuddy | t.CPtr = pool + table_pool: rowptr[memhub.MemBuddy] = pool if self.StdlibAlloc != 0: table_pool = CompilerFactory.factory.PermPool if table_pool is None: @@ -162,7 +162,7 @@ class StructGenMixin: addr: uint64 = uint64(struct_entry.Fields) + i * field_size return (GenTypes.FieldEntry | t.CPtr)(t.CVoid(addr, t.CPtr)) - def register_struct(self, pool: memhub.MemBuddy | t.CPtr, + def register_struct(self, pool: rowptr[memhub.MemBuddy], name: str, struct_ty: llvmlite.LLVMType | t.CPtr, sha1: str = None) -> GenTypes.StructEntry | t.CPtr: @@ -195,7 +195,7 @@ class StructGenMixin: # 分配字段数组(1b 阶段用永久池,避免 reset 回收后 Fields 悬空) field_size: sizet = GenTypes.FieldEntry.__sizeof__() if self.StdlibAlloc != 0: - perm_sg: memhub.MemBuddy | t.CPtr = CompilerFactory.factory.PermPool + perm_sg: rowptr[memhub.MemBuddy] = CompilerFactory.factory.PermPool if perm_sg is None: perm_sg = pool entry.Fields = perm_sg.alloc(field_size * FIELD_MAX) @@ -209,7 +209,7 @@ class StructGenMixin: # 1a(StdlibAlloc=0)用主 pool,mark1 前不回收同样存活。 # 此前 1a 用 pool、1b 用 stdlib,find_struct_by_module 的 strcmp # 曾读悬空 Name 越界 → G3 LinkedNode.prepend 挂起根因) - name_pool: memhub.MemBuddy | t.CPtr = pool + name_pool: rowptr[memhub.MemBuddy] = pool if self.StdlibAlloc != 0: name_pool = CompilerFactory.factory.PermPool if name_pool is None: @@ -235,7 +235,7 @@ class StructGenMixin: self.StructCount += 1 return entry - def register_struct_alias(self, pool: memhub.MemBuddy | t.CPtr, + def register_struct_alias(self, pool: rowptr[memhub.MemBuddy], name: str, sha1: str, src_entry: GenTypes.StructEntry | t.CPtr) -> GenTypes.StructEntry | t.CPtr: @@ -265,7 +265,7 @@ class StructGenMixin: if entry is None: return None # 复制类名与 SHA1(别名注册同样按 StdlibAlloc 选分配源,跨 1a/1b reset 存活) - alias_pool: memhub.MemBuddy | t.CPtr = pool + alias_pool: rowptr[memhub.MemBuddy] = pool if self.StdlibAlloc != 0: alias_pool = CompilerFactory.factory.PermPool if alias_pool is None: @@ -303,7 +303,7 @@ class StructGenMixin: self.StructCount += 1 return entry - def set_struct_sha1(self, pool: memhub.MemBuddy | t.CPtr, + def set_struct_sha1(self, pool: rowptr[memhub.MemBuddy], class_name: str, sha1: str) -> int: """设置结构体所属模块的 SHA1,返回 1=成功 / 0=失败""" if class_name is None or sha1 is None: @@ -313,7 +313,7 @@ class StructGenMixin: return 0 # 复制 SHA1 字符串(StdlibAlloc=1 用永久池,跨 1a/1b 存活防 strcmp 悬空) sha1_len: sizet = string.strlen(sha1) - sha1_pool: memhub.MemBuddy | t.CPtr = pool + sha1_pool: rowptr[memhub.MemBuddy] = pool if self.StdlibAlloc != 0: sha1_pool = CompilerFactory.factory.PermPool if sha1_pool is None: @@ -334,7 +334,7 @@ class StructGenMixin: return None return entry.ModuleSha1 - def add_field(self, pool: memhub.MemBuddy | t.CPtr, + def add_field(self, pool: rowptr[memhub.MemBuddy], struct_entry: GenTypes.StructEntry | t.CPtr, field_name: str, field_ty: llvmlite.LLVMType | t.CPtr, @@ -360,7 +360,7 @@ class StructGenMixin: # 复制字段名(StdlibAlloc=1 用永久池跨 reset 存活, # 否则 lookup_field 的 strcmp(fe.Name, ...) 读悬空越界挂起, # 与 register_struct 的 Name 悬空同根因) - fname_pool: memhub.MemBuddy | t.CPtr = pool + fname_pool: rowptr[memhub.MemBuddy] = pool if self.StdlibAlloc != 0: fname_pool = CompilerFactory.factory.PermPool if fname_pool is None: @@ -381,7 +381,7 @@ class StructGenMixin: # 注:注解类名(原 fe.AnnotClassName)已并入 Spec.SourceName,Spec 一律 # PermPool 分配 ⇒ 天然跨 reset 存活,无需在此深拷贝。 if self.StdlibAlloc != 0: - dp_pool_sg: memhub.MemBuddy | t.CPtr = CompilerFactory.factory.PermPool + dp_pool_sg: rowptr[memhub.MemBuddy] = CompilerFactory.factory.PermPool if dp_pool_sg is None: dp_pool_sg = pool ty_copy: llvmlite.LLVMType | t.CPtr = llvmlite.DeepCopyType(dp_pool_sg, field_ty) @@ -418,7 +418,7 @@ class StructGenMixin: struct_entry.FieldCount = idx + 1 return idx - def _deep_copy_default_ast(self, pool: memhub.MemBuddy | t.CPtr, + def _deep_copy_default_ast(self, pool: rowptr[memhub.MemBuddy], default_val: ast.AST | t.CPtr) -> ast.AST | t.CPtr: """深拷贝字段默认值 AST 到永久池(仅常量节点),跨 1b reset 存活。 @@ -463,7 +463,7 @@ class StructGenMixin: dst_c.str_val = s_copy return (ast.AST | t.CPtr)(dst_c) - def _deep_copy_list_ast(self, pool: memhub.MemBuddy | t.CPtr, + def _deep_copy_list_ast(self, pool: rowptr[memhub.MemBuddy], default_val: ast.AST | t.CPtr) -> ast.AST | t.CPtr: """深拷贝 List 节点(列表字面量默认值)到永久池,跨 1b reset 存活。 @@ -591,15 +591,9 @@ class StructGenMixin: # 落到第二遍裸名回退 → 跨模块同名类(VKernel gfx 与 App gfx # 都定义 Scene3D)返回先注册的错误 entry(Scene3D 归属错乱 # → ret_sha1=0ae → Phase A _deps_pending 死锁根因)。 - mod_hex_ok: int = 1 - if string.strlen(mod_buf_f) == 16: - for hi_f in range(16): - ch_h: char = mod_buf_f[hi_f] - if not ((ch_h >= 48 and ch_h <= 57) or (ch_h >= 97 and ch_h <= 102)): - mod_hex_ok = 0 - break - else: - mod_hex_ok = 0 + # [C10 收敛] 模块段恰为 16 位小写 hex = SHA1 字面量: + # 统一走 GenApi.is_sha1_hex16(该判定的唯一真源)。 + mod_hex_ok: int = GenApi.is_sha1_hex16(mod_buf_f) if mod_hex_ok != 0: me_h: GenTypes.StructEntry | t.CPtr = \ self.find_struct_by_module(bare_f, mod_buf_f) @@ -944,15 +938,9 @@ class StructGenMixin: # _is_sha1_prefixed 语义(含 sha1 前缀名的 Name/Attribute 注解 # 解析均跳过 import 检查)。泛型下标内点(GSList[sha.Param]) # 已被 _last_dot_outside_brackets 跳过,此处仅顶层 a.b 形态。 - mod_hex_ok_q: int = 1 - if string.strlen(mod_buf_q) == 16: - for hi_q in range(16): - ch_hq: char = mod_buf_q[hi_q] - if not ((ch_hq >= 48 and ch_hq <= 57) or (ch_hq >= 97 and ch_hq <= 102)): - mod_hex_ok_q = 0 - break - else: - mod_hex_ok_q = 0 + # [C10 收敛] 模块段恰为 16 位小写 hex = SHA1 字面量: + # 统一走 GenApi.is_sha1_hex16(该判定的唯一真源)。 + mod_hex_ok_q: int = GenApi.is_sha1_hex16(mod_buf_q) mod_sha1_q: str = None if mod_hex_ok_q != 0: # SHA1 前缀自身即"已登记"证据(与既有解析同语义): @@ -1270,7 +1258,7 @@ class StructGenMixin: return 0 return entry.HasNew - def get_class_name_by_type(self, pool: memhub.MemBuddy | t.CPtr, + def get_class_name_by_type(self, pool: rowptr[memhub.MemBuddy], struct_ty: llvmlite.LLVMType | t.CPtr) -> str: """按类型指针查找类名,返回类名字符串或 None""" if struct_ty is None or self.StructTable is None: @@ -1377,7 +1365,7 @@ class StructGenMixin: entry.ParentName = parent_name return 1 - def set_parent_names(self, pool: memhub.MemBuddy | t.CPtr, + def set_parent_names(self, pool: rowptr[memhub.MemBuddy], name: str, names_ptr: sizet | t.CPtr, count: int) -> int: """设置结构体的父类名数组(永久池深拷贝,跨文件永久存活)""" @@ -1392,7 +1380,7 @@ class StructGenMixin: return 1 if count > PARENT_MAX: count = PARENT_MAX - pn_pool: memhub.MemBuddy | t.CPtr = pool + pn_pool: rowptr[memhub.MemBuddy] = pool if self.StdlibAlloc != 0: pn_pool = CompilerFactory.factory.PermPool if pn_pool is None: @@ -1439,7 +1427,7 @@ class StructGenMixin: return None return (str | t.CPtr)(t.CVoid(addr, t.CPtr)) - def get_mro_chain(self, pool: memhub.MemBuddy | t.CPtr, + def get_mro_chain(self, pool: rowptr[memhub.MemBuddy], name: str) -> sizet | t.CPtr: """MRO 线性化类名数组(深度优先 + 声明顺序 + 去重,含自身)""" if pool is None or name is None: @@ -1569,7 +1557,7 @@ class StructGenMixin: return -1 return entry.FieldCount - def ensure_struct_def_in_module(self, pool: memhub.MemBuddy | t.CPtr, + def ensure_struct_def_in_module(self, pool: rowptr[memhub.MemBuddy], mod: llvmlite.LLVMModule | t.CPtr, ty: llvmlite.LLVMType | t.CPtr): """确保跨模块结构体的完整定义在当前模块中可用(供 alloca 使用) @@ -1640,7 +1628,7 @@ class StructGenMixin: # 也有完整定义。指针类型字段只需 opaque 声明(已由 module_ensure_opaque_for_type 处理)。 self._ensure_field_types_in_module(pool, mod, entry.Ty) - def _ensure_field_types_in_module(self, pool: memhub.MemBuddy | t.CPtr, + def _ensure_field_types_in_module(self, pool: rowptr[memhub.MemBuddy], mod: llvmlite.LLVMModule | t.CPtr, ty: llvmlite.LLVMType | t.CPtr): """递归扫描类型树,确保值类型子结构体有完整定义""" diff --git a/App/lib/core/Gen/Translator.vp b/App/lib/core/Gen/Translator.vp index a764545..b283031 100644 --- a/App/lib/core/Gen/Translator.vp +++ b/App/lib/core/Gen/Translator.vp @@ -77,7 +77,7 @@ class Translator: # LLVM 上下文(共享状态) Module: llvmlite.LLVMModule | t.CPtr - Pool: memhub.MemBuddy | t.CPtr + Pool: rowptr[memhub.MemBuddy] # 函数表 _funcs: GenTypes.FuncEntry | t.CPtr @@ -343,7 +343,7 @@ class Translator: # ============================================================ # 状态初始化 # ============================================================ - def _init_state(self, pool: memhub.MemBuddy | t.CPtr): + def _init_state(self, pool: rowptr[memhub.MemBuddy]): """初始化变量表、函数表和子 Handle""" self.Pool = pool if self._funcs is None: @@ -428,7 +428,7 @@ class Translator: if _mbuddy is None: return 1 - pool: memhub.MemBuddy | t.CPtr = _mbuddy + pool: rowptr[memhub.MemBuddy] = _mbuddy # 初始化状态 self._init_state(pool) @@ -510,7 +510,7 @@ class Translator: # ============================================================ # 包装 main 函数(无用户 main 时)→ 委托 HandlesMain # ============================================================ - def _translate_wrapper_main(self, pool: memhub.MemBuddy | t.CPtr, + def _translate_wrapper_main(self, pool: rowptr[memhub.MemBuddy], mod: llvmlite.LLVMModule | t.CPtr, tree: ast.AST | t.CPtr, i32_ty: llvmlite.LLVMType | t.CPtr): @@ -520,7 +520,7 @@ class Translator: # ============================================================ # 模块级翻译(用户已定义 main)→ 委托 HandlesMain # ============================================================ - def _translate_module_level(self, pool: memhub.MemBuddy | t.CPtr, + def _translate_module_level(self, pool: rowptr[memhub.MemBuddy], mod: llvmlite.LLVMModule | t.CPtr, tree: ast.AST | t.CPtr): """委托 GenApi.translate_children() 翻译模块级语句(trans 单参)""" @@ -599,7 +599,7 @@ class Translator: # - 构造调用 func 裸名 Name(list/dict):dict(bd) # - Subscript 的 value 裸名 Name(list/dict):list[int] # ============================================================ - def _inject_auto_container_visibility(self, pool: memhub.MemBuddy | t.CPtr, + def _inject_auto_container_visibility(self, pool: rowptr[memhub.MemBuddy], tree: ast.AST | t.CPtr): """检测 list/dict 容器使用,注入容器类可见性""" if tree is None or tree.children is None: @@ -835,5 +835,5 @@ class Mixin: # ============================================================ # 全局 mbuddy 指针 -_mbuddy: memhub.MemBuddy | t.CPtr +_mbuddy: rowptr[memhub.MemBuddy] diff --git a/App/lib/core/Gen/TranslatorGenMixin.vp b/App/lib/core/Gen/TranslatorGenMixin.vp index ee9f81e..e14927e 100644 --- a/App/lib/core/Gen/TranslatorGenMixin.vp +++ b/App/lib/core/Gen/TranslatorGenMixin.vp @@ -174,7 +174,7 @@ class TranslatorGenMixin: """预解析模块级函数签名的返回/参数类型,触发泛型类特化""" if trans is None or fd is None: return - pool: memhub.MemBuddy | t.CPtr = trans.Pool + pool: rowptr[memhub.MemBuddy] = trans.Pool if pool is None: return imp: str = trans._imported_modules @@ -198,7 +198,7 @@ class TranslatorGenMixin: # 生成格式: [N x elem_ty] [elem_ty val0, elem_ty val1, ...] # 用于模块级 t.CArray 列表字面量初始化(不依赖 builder,直接生成常量初始化器) # ============================================================ - def _build_array_initializer_text(self, pool: memhub.MemBuddy | t.CPtr, + def _build_array_initializer_text(self, pool: rowptr[memhub.MemBuddy], var_ty: llvmlite.LLVMType | t.CPtr, list_node: ast.List | t.CPtr) -> str: """从 AST List 节点生成 LLVM IR 数组初始化器文本,None 失败""" @@ -406,7 +406,7 @@ class TranslatorGenMixin: # 类型不匹配(llc constant expression type mismatch, # pyzlib_error_msg = global [512 x i8] 根因)。 # ============================================================ - def _build_string_array_initializer_text(self, pool: memhub.MemBuddy | t.CPtr, + def _build_string_array_initializer_text(self, pool: rowptr[memhub.MemBuddy], var_ty: llvmlite.LLVMType | t.CPtr, str_val: str) -> str: """字符串字面量初始化数组全局,返回初始化器文本或 None""" @@ -448,7 +448,7 @@ class TranslatorGenMixin: # 返回 GEP 初始化器文本: getelementptr inbounds ([len+1 x i8], [len+1 x i8]* @.str.{var_name}, i32 0, i32 0) # 用于 b64_tab: t.CArray[char, None] = "ABC..." 等字符串初始化指针类型 # ============================================================ - def _build_string_ptr_initializer(self, pool: memhub.MemBuddy | t.CPtr, + def _build_string_ptr_initializer(self, pool: rowptr[memhub.MemBuddy], mod: llvmlite.LLVMModule | t.CPtr, var_name: str, str_val: str) -> str: @@ -478,7 +478,7 @@ class TranslatorGenMixin: str_len + 1, str_len + 1, str_name_buf) return init_buf - def _stg_field_zero_text(self, pool: memhub.MemBuddy | t.CPtr, + def _stg_field_zero_text(self, pool: rowptr[memhub.MemBuddy], fty: llvmlite.LLVMType | t.CPtr, ty_str: str) -> str: """按 LLVM 类型生成 storage struct 字段的零值初始化器文本 @@ -510,7 +510,7 @@ class TranslatorGenMixin: # 仅处理可常量折叠的整型默认值(CONST_INT/CONST_CHAR 及负号字面量); # 其余(浮点/字符串/None/名字/表达式)返回 None,由调用方按零值兜底。 # ============================================================ - def _default_val_const_text(self, pool: memhub.MemBuddy | t.CPtr, + def _default_val_const_text(self, pool: rowptr[memhub.MemBuddy], fty: llvmlite.LLVMType | t.CPtr, ty_str: str, dval: ast.AST | t.CPtr) -> str: @@ -553,7 +553,7 @@ class TranslatorGenMixin: # (此时 start_idx=1 跳过字段 0)。 # 无任何非零默认值时返回 None,调用方据此保持原零值路径(避免无谓文本)。 # ============================================================ - def _build_stg_struct_body_text(self, pool: memhub.MemBuddy | t.CPtr, + def _build_stg_struct_body_text(self, pool: rowptr[memhub.MemBuddy], se: GenTypes.StructEntry | t.CPtr, start_idx: int) -> str: """按字段默认值生成 "e0, e1, ..." 元素文本;无非零默认值返回 None""" @@ -608,7 +608,7 @@ class TranslatorGenMixin: # 现按字段默认值生成完整 struct 常量(LLVM 要求列全每个字段)。 # 无任何非零默认值时返回 None,由调用方保持 zeroinitializer(避免无谓文本)。 # ============================================================ - def _build_stg_struct_init_text(self, pool: memhub.MemBuddy | t.CPtr, + def _build_stg_struct_init_text(self, pool: rowptr[memhub.MemBuddy], se: GenTypes.StructEntry | t.CPtr, start_idx: int) -> str: """按字段默认值生成完整 struct 初始化器;无非零默认值返回 None""" @@ -632,7 +632,7 @@ class TranslatorGenMixin: def handle_module_level_var(self, trans: HT.Translator | t.CPtr, node: ast.AST | t.CPtr) -> int: """处理模块级变量声明,创建全局变量""" - pool: memhub.MemBuddy | t.CPtr = trans.Pool + pool: rowptr[memhub.MemBuddy] = trans.Pool mod: llvmlite.LLVMModule | t.CPtr = trans.Module # CDefine 注解: 编译期常量,不创建全局变量 @@ -1139,7 +1139,7 @@ class TranslatorGenMixin: Returns: int: 新增的变量数 """ - pool: memhub.MemBuddy | t.CPtr = trans.Pool + pool: rowptr[memhub.MemBuddy] = trans.Pool mod: llvmlite.LLVMModule | t.CPtr = trans.Module main_func: llvmlite.Function | t.CPtr = llvmlite.create_function( @@ -1207,7 +1207,7 @@ class TranslatorGenMixin: if self.is_global_name(trans, name) != 0: return if trans._global_name_count >= MAX_GLOBAL_NAMES: - pool_err: memhub.MemBuddy | t.CPtr = trans.Pool + pool_err: rowptr[memhub.MemBuddy] = trans.Pool err_buf: str = None if pool_err is not None: err_buf = pool_err.alloc(256) @@ -1261,7 +1261,7 @@ class TranslatorGenMixin: ty_slot[0] = var_ty return if trans._nonlocal_name_count >= MAX_GLOBAL_NAMES: - pool_err_nl: memhub.MemBuddy | t.CPtr = trans.Pool + pool_err_nl: rowptr[memhub.MemBuddy] = trans.Pool err_buf_nl: str = None if pool_err_nl is not None: err_buf_nl = pool_err_nl.alloc(256) diff --git a/App/lib/core/Gen/Type/TypeGenBase.vp b/App/lib/core/Gen/Type/TypeGenBase.vp index 7d088a9..a8e359f 100644 --- a/App/lib/core/Gen/Type/TypeGenBase.vp +++ b/App/lib/core/Gen/Type/TypeGenBase.vp @@ -12,10 +12,10 @@ import stdio import stdlib import lib.core.VLogger as VLogger import lib.Stub.StubMerger as StubMerger -import lib.core.CompilerFactory as CompilerFactory -# TypeSpec 模块导入别名用 TSpec(模块内类名也叫 TypeSpec,别名同名会被解析器 -# 当成"类 TypeSpec 的静态方法",导致跨模块调用被 mangled 成 .TypeSpec. -# 并隐式补 self 实参 → undefined symbol)。 +import lib.core.CompilerFactory as CompilerFactory +# TypeSpec 模块导入别名用 TSpec(模块内类名也叫 TypeSpec,别名同名会被解析器 +# 当成"类 TypeSpec 的静态方法",导致跨模块调用被 mangled 成 .TypeSpec. +# 并隐式补 self 实参 → undefined symbol)。 import lib.core.Gen.Type.TypeSpec as TSpec @@ -98,12 +98,12 @@ class TypeGenBase: # --- 常量整数表达式计算成功标志(原 _g_const_eval_ok) --- ConstEvalOk: int - # --- 全局当前文件名(原 _g_current_filename) --- - CurrentFile: str - - # --- TypeSpec 驻留表(统一类型描述符,Debugger/_Type.md 第 6 节) --- - # 惰性创建(ensure_spec_arena);由类型子系统自身持有,避免模块级全局表。 - # 实例与内部数组均 PermPool 分配 ⇒ 跨文件/跨 mark 存活。 + # --- 全局当前文件名(原 _g_current_filename) --- + CurrentFile: str + + # --- TypeSpec 驻留表(统一类型描述符,Debugger/_Type.md 第 6 节) --- + # 惰性创建(ensure_spec_arena);由类型子系统自身持有,避免模块级全局表。 + # 实例与内部数组均 PermPool 分配 ⇒ 跨文件/跨 mark 存活。 Specs: TSpec.TypeSpecArena | t.CPtr def InitTypeGen(self) -> int: """初始化类型 Mixin 字段(子类构造时内联调用,规避 NoVTable 继承符号不转发)""" @@ -230,7 +230,7 @@ class TypeGenBase: def set_current_module_sha1(self, sha1: str) -> None: """设置当前正在编译的模块 SHA1(Phase1 在模块开始翻译前调用)""" self.CurrentModuleSha1 = sha1 - def _dbg_check_ast_floats(self, mb: memhub.MemBuddy | t.CPtr, + def _dbg_check_ast_floats(self, mb: rowptr[memhub.MemBuddy], tree: ast.AST | t.CPtr, tag: str): """已移除调试插桩(占位保留签名,避免外部调用引用失败)""" pass diff --git a/App/lib/core/Gen/Type/TypeGenCDef.vp b/App/lib/core/Gen/Type/TypeGenCDef.vp index fb5495b..e7eae11 100644 --- a/App/lib/core/Gen/Type/TypeGenCDef.vp +++ b/App/lib/core/Gen/Type/TypeGenCDef.vp @@ -26,7 +26,7 @@ import lib.core.Gen.Type.TypeGenBase as TypeGenBase class TypeGenCDef(TypeGenBase.TypeGenBase): """CDefine 编译期常量表(register/lookup/is/set/clear)""" - def register_cdefine_constant(self, pool: memhub.MemBuddy | t.CPtr, + def register_cdefine_constant(self, pool: rowptr[memhub.MemBuddy], name: str, value: int64) -> None: """注册 CDefine 编译期常量到本地表 @@ -55,7 +55,7 @@ class TypeGenCDef(TypeGenBase.TypeGenBase): self.CDefineDoubleFlags.append(0) if self.CDefineStrFlags is not None: self.CDefineStrFlags.append(0) - def register_cdefine_double(self, pool: memhub.MemBuddy | t.CPtr, + def register_cdefine_double(self, pool: rowptr[memhub.MemBuddy], name: str, value: double) -> None: """注册浮点 CDefine 编译期常量(如 U_M_PI: t.CDefine = 3.14159...) @@ -84,7 +84,7 @@ class TypeGenCDef(TypeGenBase.TypeGenBase): if val_buf is None: VLogger.error("CDefine 浮点值缓冲区分配失败", "CDEF-DBG") self.Gen.TypeGenErr.fatal_error(None, "CDefine 浮点值缓冲区分配失败", "MemoryError") - def register_cdefine_string(self, pool: memhub.MemBuddy | t.CPtr, + def register_cdefine_string(self, pool: rowptr[memhub.MemBuddy], name: str, value: str) -> None: """注册字符串 CDefine 编译期常量(如 ZLIB_VERSION: t.CDefine = "1.3.2") @@ -144,7 +144,7 @@ class TypeGenCDef(TypeGenBase.TypeGenBase): x_nm: str = self.XmodCdefNames.get(x_i) if x_nm is not None and string.strcmp(x_nm, name) == 0: return - perm: memhub.MemBuddy | t.CPtr = CompilerFactory.factory.PermPool + perm: rowptr[memhub.MemBuddy] = CompilerFactory.factory.PermPool if self.XmodCdefNames is None: self.XmodCdefNames = list[str](perm, 64) self.XmodCdefValues = list[str](perm, 64) diff --git a/App/lib/core/Gen/Type/TypeGenCType.vp b/App/lib/core/Gen/Type/TypeGenCType.vp index 8e10b7e..9130d46 100644 --- a/App/lib/core/Gen/Type/TypeGenCType.vp +++ b/App/lib/core/Gen/Type/TypeGenCType.vp @@ -13,12 +13,9 @@ import lib.Stub.StubMerger as StubMerger import lib.core.CompilerFactory as CompilerFactory -import lib.core.Gen.Type.TypeGenBase as TypeGenBase +import lib.core.Gen.Type.TypeGenBase as TypeGenBase import lib.core.Gen.Type.TypeSpec as TSpec -# builtins 诊断串自有缓冲长度(仅服务"变量类型注解解析失败"报错文本) -TYPEDEF_DIAG_BUF: t.CDefine = 256 - # ============================================================ # TypeGenCType - TypeGenMixin 拆分(阶段 D):CTypedef 表(register/lookup/ScanCTypedefDeclarations/_eval_const_int_expr) # @@ -30,7 +27,7 @@ TYPEDEF_DIAG_BUF: t.CDefine = 256 class TypeGenCType(TypeGenBase.TypeGenBase): """CTypedef 表(register/lookup/ScanCTypedefDeclarations/_eval_const_int_expr)""" - def register_ctypedef(self, pool: memhub.MemBuddy | t.CPtr, + def register_ctypedef(self, pool: rowptr[memhub.MemBuddy], name: str, type_str: str) -> None: """注册 CTypedef 到本地表 @@ -86,18 +83,28 @@ class TypeGenCType(TypeGenBase.TypeGenBase): """ if text is None: return None + # [D4·截断纪律] 旧实现固定 TYPEDEF_DIAG_BUF(256) + `strncpy(buf, text, 255)`: + # 诊断串超长被**静默截断** ⇒ 报错文本丢掉关键名字("变量类型注解解析失败" + # 的归因信息失效)。改为按需 realloc 到**精确长度**,缓冲仍为自有字段 + # (生命周期不变:仍在 reset/析构时统一 stdlib.free)。 + need: sizet = string.strlen(text) + 1 if which == 0: if self.LastBuiltinsTypedefNameBuf is None: - self.LastBuiltinsTypedefNameBuf = stdlib.malloc(TYPEDEF_DIAG_BUF) + self.LastBuiltinsTypedefNameBuf = stdlib.malloc(need) + else: + self.LastBuiltinsTypedefNameBuf = stdlib.realloc( + self.LastBuiltinsTypedefNameBuf, need) buf: str = self.LastBuiltinsTypedefNameBuf else: if self.LastBuiltinsTypedefResultBuf is None: - self.LastBuiltinsTypedefResultBuf = stdlib.malloc(TYPEDEF_DIAG_BUF) + self.LastBuiltinsTypedefResultBuf = stdlib.malloc(need) + else: + self.LastBuiltinsTypedefResultBuf = stdlib.realloc( + self.LastBuiltinsTypedefResultBuf, need) buf = self.LastBuiltinsTypedefResultBuf if buf is None: return None - string.strncpy(buf, text, TYPEDEF_DIAG_BUF - 1) - buf[TYPEDEF_DIAG_BUF - 1] = '\0' + string.strcpy(buf, text) return buf def lookup_ctypedef(self, name: str) -> str: @@ -160,7 +167,7 @@ class TypeGenCType(TypeGenBase.TypeGenBase): # # 旧实现(现降级为「真源不表态时的兜底」):strstr 子串扫描 + CTypedef 只展开一层 # ⇒ 两类错判:A4 `BYTEPTR` 含 `BYTE` 被判无符号;A5 sha1 前缀名含 `uint32` 命中; - # 多层别名(WCHAR→WORD→t.CUInt16T)因只展开一层而漏判。 + # 多层别名(WCHAR→WORD→uint16)因只展开一层而漏判。 # 本实现:精确名白名单(TSpec.SpecSignFromTypeNameSpan)+ 别名链逐层展开, # 不表态时返回 TS_SIGN_UNKNOWN(由调用方决定是否回退旧路径)。 # ============================================================ @@ -206,7 +213,7 @@ class TypeGenCType(TypeGenBase.TypeGenBase): if text[e - 1] != ' ' and text[e - 1] != '\t' and text[e - 1] != '\n': break e -= 1 - # 去外层成对括号(如 "(t.CUInt32T)") + # 去外层成对括号(如 "(uint32)") while e > s + 1: if text[s] != '(' or text[e - 1] != ')': break @@ -293,7 +300,7 @@ class TypeGenCType(TypeGenBase.TypeGenBase): if self.ImportAliasBuf is not None: stdlib.free(self.ImportAliasBuf) self.ImportAliasBuf = None - def _ctypedef_push_visiting(self, pool: memhub.MemBuddy | t.CPtr, name: str) -> int: + def _ctypedef_push_visiting(self, pool: rowptr[memhub.MemBuddy], name: str) -> int: """将 CTypedef 名加入正在解析列表(循环检测) Returns: @@ -366,7 +373,7 @@ class TypeGenCType(TypeGenBase.TypeGenBase): and sep_ch_m != '\r' and sep_ch_m != '\t' and sep_ch_m != '|': return 0 return 1 - def ScanCTypedefDeclarations(self, pool: memhub.MemBuddy | t.CPtr, + def ScanCTypedefDeclarations(self, pool: rowptr[memhub.MemBuddy], tree: ast.AST | t.CPtr) -> int: """扫描 AST 顶层节点,注册所有 NAME: t.CTypedef = Type 声明 @@ -417,7 +424,7 @@ class TypeGenCType(TypeGenBase.TypeGenBase): self.register_ctypedef(pool, tgt_id_v, type_str) count += 1 return count - def register_ctypedef_from_source(self, pool: memhub.MemBuddy | t.CPtr, + def register_ctypedef_from_source(self, pool: rowptr[memhub.MemBuddy], src: str) -> int: """从源码文本逐行扫描注册 CTypedef(NAME: t.CTypedef = TYPE) @@ -491,7 +498,7 @@ class TypeGenCType(TypeGenBase.TypeGenBase): i += 1 return count def _eval_const_int_expr(self, node: ast.AST | t.CPtr, - pool: memhub.MemBuddy | t.CPtr = None, + pool: rowptr[memhub.MemBuddy] = None, from_imports: str = None, imported_modules: str = None, depth: int = 0) -> int: diff --git a/App/lib/core/Gen/Type/TypeGenErr.vp b/App/lib/core/Gen/Type/TypeGenErr.vp index 7ebd98f..52ca620 100644 --- a/App/lib/core/Gen/Type/TypeGenErr.vp +++ b/App/lib/core/Gen/Type/TypeGenErr.vp @@ -16,7 +16,7 @@ import lib.Stub.StubMerger as StubMerger import lib.core.CompilerFactory as CompilerFactory import lib.core.Gen.Translator as HT -import lib.core.Gen.Type.TypeGenBase as TypeGenBase +import lib.core.Gen.Type.TypeGenBase as TypeGenBase import lib.core.Gen.Type.TypeSpec as TSpec @@ -183,7 +183,7 @@ class TypeGenErr(TypeGenBase.TypeGenBase): col_start: int = 0, col_end: int = 0): """以 Python 风格报错并退出(TypeError 版本)""" self.fatal_error(node, msg, "TypeError", col_start, col_end) - def try_extract_callable_ret(self, pool: memhub.MemBuddy | t.CPtr, + def try_extract_callable_ret(self, pool: rowptr[memhub.MemBuddy], annot: ast.AST | t.CPtr, imported_modules: str, from_imports: str, @@ -261,7 +261,7 @@ class TypeGenErr(TypeGenBase.TypeGenBase): def get_llvm_type_bits(self, ty: llvmlite.LLVMType | t.CPtr) -> int: """获取 LLVM 整数类型的位宽,非整数类型返回 0(委托 SpecTypeBits)""" return TSpec.SpecTypeBits(ty) - def infer_expr_type(self, pool: memhub.MemBuddy | t.CPtr, + def infer_expr_type(self, pool: rowptr[memhub.MemBuddy], node: ast.AST | t.CPtr, param_types: str) -> llvmlite.LLVMType | t.CPtr: """推断表达式的 LLVM 类型 @@ -280,12 +280,18 @@ class TypeGenErr(TypeGenBase.TypeGenBase): nm: ast.Name | t.CPtr = (ast.Name | t.CPtr)(node) if nm.id is not None and param_types is not None: # 在 param_types 中查找: "name:bits" 格式 - search_key: str = pool.alloc(64) + # [D5·截断纪律] 旧实现固定 64 缓冲 + snprintf("%s:"):参数名超长被 + # 静默截断 ⇒ 截断后的键在 param_types 里与**别的参数前缀**匹配成功 + # ⇒ 取到错误的位宽(类型误判)。改为按精确长度分配。 + id_len: sizet = string.strlen(nm.id) + search_key: str = pool.alloc(id_len + 2) if search_key is not None: - viperlib.snprintf(search_key, 64, "%s:", nm.id) + string.strcpy(search_key, nm.id) + search_key[id_len] = ':' + search_key[id_len + 1] = '\0' found: str = string.strstr(param_types, search_key) if found is not None: - colon_pos: sizet = string.strlen(nm.id) + 1 + colon_pos: sizet = id_len + 1 bits_str: str = found + colon_pos bits: int = 0 for bi in range(4): @@ -315,7 +321,7 @@ class TypeGenErr(TypeGenBase.TypeGenBase): return rhs_ty return llvmlite.Int32(pool) - def infer_return_type(self, pool: memhub.MemBuddy | t.CPtr, + def infer_return_type(self, pool: rowptr[memhub.MemBuddy], body: list[ast.AST | t.CPtr] | t.CPtr, param_types: str) -> llvmlite.LLVMType | t.CPtr: """扫描函数体中的 return 语句,推断返回类型""" @@ -337,7 +343,7 @@ class TypeGenErr(TypeGenBase.TypeGenBase): if new_bits > cur_bits: ret_ty = expr_ty return ret_ty - def body_has_value_return(self, pool: memhub.MemBuddy | t.CPtr, + def body_has_value_return(self, pool: rowptr[memhub.MemBuddy], body: list[ast.AST | t.CPtr] | t.CPtr) -> int: """扫描函数体,判断是否存在返回非 None 值的 return @@ -375,9 +381,17 @@ class TypeGenErr(TypeGenBase.TypeGenBase): if self.body_has_value_return(pool, sub) != 0: return 1 return 0 - def build_param_types_str(self, pool: memhub.MemBuddy | t.CPtr, + def build_param_types_str(self, pool: rowptr[memhub.MemBuddy], args_node: ast.AST | t.CPtr) -> str: - """构建参数类型编码字符串 "name:bits,name:bits,..." """ + """构建参数类型编码字符串 "name:bits,name:bits,..." + + [D5·截断纪律] 旧实现按 `an * 32 + 1` 预估缓冲,再用 `_strappend` 以 + `remain - 1` 截断且**不报错**:参数名偏长(或参数偏多)时编码串被静默 + 截断 ⇒ `infer_expr_type` 的 `strstr(param_types, "name:")` 查找失配 / + 命中他人前缀 ⇒ 静默回落 Int32(类型误判)。现改为**两遍精确分配**: + 先逐参数生成条目(指针暂存数组)并累计长度,再按精确长度分配后拼接—— + 不存在长度上限,故无需截断;`_strappend` 一并删除(唯一调用点在本函数)。 + """ if args_node is None: return None ags: ast.Arguments | t.CPtr = (ast.Arguments | t.CPtr)(args_node) @@ -388,50 +402,53 @@ class TypeGenErr(TypeGenBase.TypeGenBase): if an == 0: return None - buf_size: sizet = an * 32 + 1 - buf: str = pool.alloc(buf_size) - if buf is None: + # 1) 逐参数生成条目 "name:bits"(精确分配),指针暂存 + ents: sizet | t.CPtr = pool.alloc(an * 8) + if ents is None: return None - buf[0] = '\0' - + total: sizet = 1 # 末尾 NUL + cnt: sizet = 0 i32_ty: llvmlite.LLVMType | t.CPtr = llvmlite.Int32(pool) for ai in range(an): arg: ast.Arg | t.CPtr = (ast.Arg | t.CPtr)(alist.get(ai)) - if arg is not None and arg.arg is not None: - param_ty: llvmlite.LLVMType | t.CPtr = i32_ty - if arg.annotation is not None: - # 统一口径:CTypedef 动态表优先,miss 回退 map_t_type - # (阶段 2:删除 map_t_type 硬编码别名后,BYTE 等靠库 typedef) - if arg.annotation.kind() == ast.ASTKind.Attribute: - at: ast.Attribute | t.CPtr = (ast.Attribute | t.CPtr)(arg.annotation) - if at.attr is not None: - resolved: llvmlite.LLVMType | t.CPtr = self.Gen.TypeGenResolve.resolve_typedef_or_map(pool, at.attr, None, None) - if resolved is not None: - param_ty = resolved - bits: int = self.get_llvm_type_bits(param_ty) - if bits == 0: - bits = 32 - tmp: str = pool.alloc(32) - if tmp is not None: - viperlib.snprintf(tmp, 32, "%s:%d", arg.arg, bits) - if ai > 0: - self._strappend(buf, buf_size, ",") - self._strappend(buf, buf_size, tmp) - return buf - def _strappend(self, dst: str, dst_size: sizet, src: str): - """将 src 追加到 dst 末尾""" - if dst is None or src is None: - return - dlen: sizet = string.strlen(dst) - slen: sizet = string.strlen(src) - remain: sizet = dst_size - dlen - if remain <= 0: - return - # 内联 min(slen, remain - 1) 避免 builtin min 未定义(TransPyV 无 builtin min) - limit: sizet = slen - cap: sizet = remain - 1 - if cap < limit: - limit = cap - for i in range(limit): - dst[dlen + i] = src[i] - dst[dlen + i] = '\0' # i 退出值存疑 \ No newline at end of file + if arg is None or arg.arg is None: + continue + param_ty: llvmlite.LLVMType | t.CPtr = i32_ty + if arg.annotation is not None: + # 统一口径:CTypedef 动态表优先,miss 回退 map_t_type + # (阶段 2:删除 map_t_type 硬编码别名后,BYTE 等靠库 typedef) + if arg.annotation.kind() == ast.ASTKind.Attribute: + at: ast.Attribute | t.CPtr = (ast.Attribute | t.CPtr)(arg.annotation) + if at.attr is not None: + resolved: llvmlite.LLVMType | t.CPtr = self.Gen.TypeGenResolve.resolve_typedef_or_map(pool, at.attr, None, None) + if resolved is not None: + param_ty = resolved + bits: int = self.get_llvm_type_bits(param_ty) + if bits == 0: + bits = 32 + nlen: sizet = string.strlen(arg.arg) + # name + ':' + 十进制位宽(int32 最长 11 字符)+ NUL + ent: str = pool.alloc(nlen + 1 + 12 + 1) + if ent is None: + continue + string.strcpy(ent, arg.arg) + ent[nlen] = ':' + viperlib.snprintf(ent + nlen + 1, 12, "%d", bits) + ents[cnt] = sizet(ent) + cnt += 1 + total += nlen + 1 + string.strlen(ent + nlen + 1) + if cnt == 0: + return None + if cnt > 1: + total += cnt - 1 # 分隔符 "," + + # 2) 按精确长度分配 + 拼接(不会截断) + buf: str = pool.alloc(total) + if buf is None: + return None + buf[0] = '\0' + for i2 in range(cnt): + if i2 > 0: + string.strcat(buf, ",") + string.strcat(buf, (str | t.CPtr)(t.CVoid(ents[i2], t.CPtr))) + return buf \ No newline at end of file diff --git a/App/lib/core/Gen/Type/TypeGenResolve.vp b/App/lib/core/Gen/Type/TypeGenResolve.vp index 2e5aeed..192602c 100644 --- a/App/lib/core/Gen/Type/TypeGenResolve.vp +++ b/App/lib/core/Gen/Type/TypeGenResolve.vp @@ -33,7 +33,7 @@ import w32.fileio as fileio class TypeGenResolve(TypeGenBase.TypeGenBase): """类型映射/注解解析(map_t_type/resolve_annotation_type 等)""" - def _get_type_name_from_annotation(self, pool: memhub.MemBuddy | t.CPtr, + def _get_type_name_from_annotation(self, pool: rowptr[memhub.MemBuddy], node: ast.AST | t.CPtr) -> str: """从类型注解节点提取类型名(支持 Name/Attribute/BinOp)""" if node is None: @@ -115,7 +115,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): return buf2 return None return None - def _subscript_slice_to_str(self, pool: memhub.MemBuddy | t.CPtr, + def _subscript_slice_to_str(self, pool: rowptr[memhub.MemBuddy], node: ast.AST | t.CPtr) -> str: """Subscript slice 节点转类型字符串(递归,支持 Name/Attribute/BinOp/Constant/List/Tuple/Subscript)""" if node is None: @@ -148,35 +148,54 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): tup: ast.Tuple | t.CPtr = (ast.Tuple | t.CPtr)(node) return self._list_elts_to_type_str(pool, tup.elts, "", "") return None - def _list_elts_to_type_str(self, pool: memhub.MemBuddy | t.CPtr, + def _list_elts_to_type_str(self, pool: rowptr[memhub.MemBuddy], elts: list[ast.AST | t.CPtr] | t.CPtr, open_ch: str, close_ch: str) -> str: - """元素列表转逗号分隔字符串(List/Tuple 共用),包上 open/close 括号""" + """元素列表转逗号分隔字符串(List/Tuple 共用),包上 open/close 括号 + + [D1·截断纪律] 旧实现固定 1024 缓冲 + `strlen(x) < 1024` 守卫:装不下就 + **静默丢弃**该元素,产出一个"少了几段"的类型串——与 D15-1(TypeSpec 的 + `_spec_text_append` 静默截断)同类错误:截断串会与别的类型 `strcmp` 相等 + ⇒ 误判。现改为**两遍精确分配**:先逐元素解析(结果指针暂存数组)并累计 + 所需长度,再按精确长度分配后拼接——**不存在长度上限**,故无需截断。 + 元素解析不出类型名时 **fail-fast**(不兜底):静默跳过同样拼出错误类型串。 + """ if elts is None or pool is None: return None - buf3: str = pool.alloc(1024) - if buf3 is None: - return None - buf3[0] = '\0' n3: sizet = len(elts) + # 1) 解析全部元素(结果指针暂存,避免二次解析) + es_arr: sizet | t.CPtr = None + if n3 > 0: + es_arr = pool.alloc(n3 * 8) + if es_arr is None: + return None + total3: sizet = 2 # open + close + cnt3: sizet = 0 for i3 in range(n3): e3: ast.AST | t.CPtr = elts.get(i3) if e3 is None: continue es3: str = self._subscript_slice_to_str(pool, e3) if es3 is None: - continue - if string.strlen(buf3) > 0 and string.strlen(buf3) + 2 < 1024: - string.strcat(buf3, ", ") - if string.strlen(buf3) + string.strlen(es3) < 1024: - string.strcat(buf3, es3) - total3: sizet = string.strlen(buf3) + 2 + 2 - buf4: str = pool.alloc(total3) + # 类型名缺失 ⇒ 立即报错(静默丢弃会拼出错误类型串) + self.Gen.TypeGenErr.fatal_error( + e3, "类型注解的元素无法解析为类型名(列表/元组注解)", "NameError") + return None + es_arr[cnt3] = sizet(es3) + cnt3 += 1 + total3 += string.strlen(es3) + if cnt3 > 1: + total3 += (cnt3 - 1) * 2 # 分隔符 ", " + # 2) 按精确长度分配 + 拼接(无上限,不会截断) + buf4: str = pool.alloc(total3 + 1) if buf4 is None: return None buf4[0] = '\0' string.strcat(buf4, open_ch) - string.strcat(buf4, buf3) + for i4 in range(cnt3): + if i4 > 0: + string.strcat(buf4, ", ") + string.strcat(buf4, (str | t.CPtr)(t.CVoid(es_arr[i4], t.CPtr))) string.strcat(buf4, close_ch) return buf4 def _is_sha1_prefixed(self, s: str) -> int: @@ -185,21 +204,12 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): 泛型类型参数规范化为 "{SHA1}.Class" 后,可能再次进入本提取路径 (如特化方法体内 T 替换为 "f467978339422f32.AST"),必须识别并保持, 否则会把 SHA1 当模块名再查一次(查不到)或重复加前缀(名不符)。 + + [C10 收敛] 实现已收拢到 `GenApi.sha1_prefix_len`(该判定的**唯一真源**), + 此处只做委托:保留本方法是因 `@t.NoVTable` 静态绑定下大量调用点依赖它存在。 """ - if s is None: - return 0 - if string.strlen(s) < 17: - return 0 - if s[16] != '.': - return 0 - i: sizet - for i in range(16): - c: int = s[i] - # 48-57 = '0'-'9',97-102 = 'a'-'f' - if not ((c >= 48 and c <= 57) or (c >= 97 and c <= 102)): - return 0 - return 1 - def _concat_sha1_class(self, pool: memhub.MemBuddy | t.CPtr, + return GenApi.sha1_prefix_len(s) + def _concat_sha1_class(self, pool: rowptr[memhub.MemBuddy], sha1: str, cls_name: str) -> str: """拼接 "{sha1}.{cls_name}"(pool 分配),失败返回 None""" if pool is None or sha1 is None or cls_name is None: @@ -213,7 +223,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): string.strcat(buf, ".") string.strcat(buf, cls_name) return buf - def _norm_type_arg_name(self, pool: memhub.MemBuddy | t.CPtr, + def _norm_type_arg_name(self, pool: rowptr[memhub.MemBuddy], type_name: str, from_imports: str) -> str: """泛型类型参数名 SHA1 规范化:统一为 "{定义模块SHA1}.{Class}" 形式 @@ -476,7 +486,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): return 1 return 0 - def _parse_type_string(self, pool: memhub.MemBuddy | t.CPtr, + def _parse_type_string(self, pool: rowptr[memhub.MemBuddy], type_str: str, ctx: int) -> ast.AST | t.CPtr: """将类型名字符串解析为 AST 节点 @@ -652,7 +662,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): def get_current_file(self) -> str: """获取当前编译的文件名(供报错归因使用)""" return self.CurrentFile - def resolve_typedef_or_map(self, pool: memhub.MemBuddy | t.CPtr, + def resolve_typedef_or_map(self, pool: rowptr[memhub.MemBuddy], name: str, imported_modules: str, from_imports: str, @@ -711,7 +721,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): if lib_ty is not None: return lib_ty return self.map_t_type(pool, name) - def get_type_size_bytes(self, pool: memhub.MemBuddy | t.CPtr, + def get_type_size_bytes(self, pool: rowptr[memhub.MemBuddy], name: str, imported_modules: str, from_imports: str) -> int: @@ -840,7 +850,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): if string.strncmp(buf + al_start, mod, mod_len) == 0: return buf + tg_start return None - def _lookup_builtins_typedef(self, pool: memhub.MemBuddy | t.CPtr, + def _lookup_builtins_typedef(self, pool: rowptr[memhub.MemBuddy], name: str) -> str: """builtins 最后匹配:查 includes/builtins.vp 的 CTypedef 声明 @@ -1039,7 +1049,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): if b_final_r is not None: return b_final_r return None - def _lookup_library_typedef(self, pool: memhub.MemBuddy | t.CPtr, + def _lookup_library_typedef(self, pool: rowptr[memhub.MemBuddy], mod: str, attr: str) -> str: """查库模块源文件中 "attr: t.CTypedef = TYPE" 并注册,返回 TYPE 或 None @@ -1135,7 +1145,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): m_i += 1 stdlib.free(m_buf) return m_res - def _expand_typedef_ref(self, pool: memhub.MemBuddy | t.CPtr, + def _expand_typedef_ref(self, pool: rowptr[memhub.MemBuddy], type_str: str, depth: int = 0) -> str: """展开类型表达式中的模块限定 typedef 引用(stdint.size_t → sizet) @@ -1175,7 +1185,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): and string.strcmp(ts_x, type_str) != 0: return self._expand_typedef_ref(pool, ts_x, depth + 1) return type_str - def map_t_type(self, pool: memhub.MemBuddy | t.CPtr, + def map_t_type(self, pool: rowptr[memhub.MemBuddy], type_name: str) -> llvmlite.LLVMType | t.CPtr: """将 t.CXxx / c.CXxx 类型名映射到 LLVMType @@ -1463,7 +1473,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): def extract_class_name_from_annotation(self, node: ast.AST | t.CPtr, imported_modules: str, - pool: memhub.MemBuddy | t.CPtr = None, + pool: rowptr[memhub.MemBuddy] = None, from_imports: str = None) -> str: """从类型注解 AST 中提取类名,返回 None=无法提取 @@ -1669,7 +1679,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): return mangled_buf return None - def _resolve_generic_subscript_ty(self, pool: memhub.MemBuddy | t.CPtr, + def _resolve_generic_subscript_ty(self, pool: rowptr[memhub.MemBuddy], sub: ast.Subscript | t.CPtr, gen_cls_name: str, trans: HT.Translator | t.CPtr, @@ -1813,7 +1823,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): VLogger.info(f"[GENERIC-DBG] trans 为 None: {gen_cls_name}", "Phase1") # 未特化:返回 None(不报错,让后续流程处理) return None - def resolve_annotation_type(self, pool: memhub.MemBuddy | t.CPtr, + def resolve_annotation_type(self, pool: rowptr[memhub.MemBuddy], node: ast.AST | t.CPtr, imported_modules: str, from_imports: str, @@ -1911,13 +1921,17 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): # 与 Attribute 形态(L1978-1992)都要支持;否则 rowptr[sha.AST] 解析失败 # → 特化方法参数类型退化 → "方法 'list[...].append' 参数 'item' 类型解析 # 失败"(SlotsBugTest ast 包 rowptr[list[rowptr[AST]]] 根因)。 - if self._is_sha1_prefixed(nm.id) != 0: - sp_sha_buf2: str = pool.alloc(17) + sp_pre2: int = self._is_sha1_prefixed(nm.id) + if sp_pre2 != 0: + # [D3 收敛] 前缀长度取自唯一真源(不再硬编码 17/16): + # 前缀 = "{16hex}." 共 sp_len 字节,其中 hex 段 sp_len-1,类名自 sp_len 起。 + sp_len2: sizet = sizet(sp_pre2) + sp_sha_buf2: str = pool.alloc(sp_len2) if sp_sha_buf2 is not None: - string.strncpy(sp_sha_buf2, nm.id, 16) - sp_sha_buf2[16] = '\0' + string.strncpy(sp_sha_buf2, nm.id, sp_len2 - 1) + sp_sha_buf2[sp_len2 - 1] = '\0' sp_entry2: GenTypes.StructEntry | t.CPtr = self.Gen.StructGen.find_struct_by_module( - nm.id + 17, sp_sha_buf2) + nm.id + sp_len2, sp_sha_buf2) if sp_entry2 is not None and sp_entry2.Ty is not None: if sp_entry2.HasNew != 0: return llvmlite.Ptr(pool, sp_entry2.Ty) @@ -2076,18 +2090,9 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): # SHA1 前缀("{16hex}.Class",跨模块特化类型参数规范化名): # 模块段即 SHA1,天然"已导入"(SHA1 唯一对应已编译模块), # 跳过 imported_modules 检查("f467978339422f32" 不在列表中) - sha1_attr: int = 0 - if string.strlen(val_name.id) == 16: - sha1_ok: int = 1 - i_sa: sizet - for i_sa in range(16): - c_sa: int = val_name.id[i_sa] - # 48-57 = '0'-'9',97-102 = 'a'-'f' - if not ((c_sa >= 48 and c_sa <= 57) or (c_sa >= 97 and c_sa <= 102)): - sha1_ok = 0 - break - if sha1_ok != 0: - sha1_attr = 1 + # [C10 收敛] 模块段恰为 16 位小写 hex = SHA1 字面量: + # 统一走 GenApi.is_sha1_hex16(该判定的唯一真源)。 + sha1_attr: int = GenApi.is_sha1_hex16(val_name.id) if sha1_attr == 0: mod_imp: int = self.Gen.ImportsGen.is_module_imported(imported_modules, val_name.id) if mod_imp == 0: diff --git a/App/lib/core/Gen/Type/TypeSpec.vp b/App/lib/core/Gen/Type/TypeSpec.vp index cac8e3b..fca7f19 100644 --- a/App/lib/core/Gen/Type/TypeSpec.vp +++ b/App/lib/core/Gen/Type/TypeSpec.vp @@ -1,1437 +1,1437 @@ -import t, c -from stdint import * -import llvmlite -import memhub -import string -import viperlib -import lib.core.CompilerFactory as CompilerFactory -import lib.core.Gen.GenApi as GenApi - - -# ============================================================ -# TypeSpec - 统一类型描述符(对齐 TPC lib/core/TypeSpec.py,去 Python 化) -# -# 背景(见 Debugger/_Type.md 第 6 节设计): -# TPV 原有类型信息散落在「字符串 + 零散布尔」里 —— VarEntry.AnnotClassName / -# FieldEntry.AnnotClassName(注解类名串当影子类型系统,S4 已删除并并入本结构 -# 的 SourceName 字段)、VarEntry.IsPtrElement(单一布尔,只覆盖一种 8 字节 -# 步长情形,S4 已删除并并入本结构的 ElemBits 元素语义三元组)、 -# FuncEntry.TypeStr(函数类型存文本,S4 已改由本结构的 SpecToLLVMText 从 -# Spec 派生),而 llvmlite.LLVMType 只保留解析结果、已抹平指针层级/数组 -# 维度/原始注解。 -# 结果是「是否无符号/指针几层/数组几维/函数签名」到处重复解析字符串 -# (同一值被末段类名/完整限定名/精确名/mangled 前缀/截断串五种语义解释)。 -# -# 阶段:S1 只提供结构与构造/序列化;S2 各解析处「双写」;S3 逐块切读; -# S4 删旧字符串路径 —— FuncEntry.TypeStr、VarEntry/FieldEntry.AnnotClassName、 -# VarEntry.IsPtrElement 均已删除,仅「容器种类判断」(list/dict/CPtr 的 -# 字符串子串判定)待后续。 -# -# 生命周期(设计 D1):实例与内部数组一律 `CompilerFactory.factory.PermPool` -# 分配(契约见 CompilerFactory.vp:跨 mark 持久、从不 reset),故跨文件/跨模块 -# 可直接传指针,无需序列化。代价是 PermPool 只增不减 ⇒ 由 InternSpec 驻留去重。 -# -# 不用全局表:驻留表挂在 TypeSpecArena 实例上,由调用方(S2 起为 Generator) -# 持有并传入,避免模块级可变态。 -# ============================================================ - - -# ============================================================ -# Kind - 基础类型种类 -# ============================================================ -TS_UNKNOWN: t.CDefine = 0 -TS_INT: t.CDefine = 1 -TS_UINT: t.CDefine = 2 -TS_FLOAT: t.CDefine = 3 -TS_BOOL: t.CDefine = 4 -TS_PTR: t.CDefine = 5 -TS_ARRAY: t.CDefine = 6 -TS_STRUCT: t.CDefine = 7 -TS_VOID: t.CDefine = 8 -TS_FUNC: t.CDefine = 9 -TS_UNION: t.CDefine = 10 -TS_ENUM: t.CDefine = 11 - -# ============================================================ -# IsSigned - 符号性(单一真源,替代 _annot_str_unsigned 的子串扫描) -# ============================================================ -TS_SIGN_UNKNOWN: t.CDefine = -1 -TS_SIGN_UNSIGNED: t.CDefine = 0 -TS_SIGN_SIGNED: t.CDefine = 1 - -# 驻留表默认容量与单条类型文本上限(超限 fail-fast,绝不静默丢弃/截断) -# 容量 × 文本上限即驻留表键缓冲的 PermPool 占用(8192 × 256 = 2MB) -# 注:键文本超 SPEC_TEXT_MAX 的长签名/深嵌套类型 ⇒ 不驻留(保留完整实例, -# 仅放弃去重),见 InternSpec —— 截断键会让 strcmp 撞类型、返回错误实例。 -SPEC_INTERN_MAX: t.CDefine = 8192 -SPEC_TEXT_MAX: t.CDefine = 256 - - -# ============================================================ -# 符号性精确名表 - 按「名字切片」判定(**不做子串扫描**) -# -# 为什么必须精确匹配:旧实现 `_annot_str_unsigned` 用 strstr 子串扫描, -# 已确认两类误判(Debugger/_Type.md A4/A5): -# - `BYTEPTR`(本质 i8* 指针)含子串 `BYTE` → 被判为无符号整数; -# - 任何含 `uint32` 子串的名字(含 sha1 前缀名)都会命中。 -# -# 覆盖范围界定:本模块**只认 t/c 核心原语名与少数内建名**;stdint 的别名 -# (DWORD/WORD/QWORD/size_t/uint32_t/u32/…)由调用方沿 CTypedef 链**逐层展开** -# 后再落到本函数(链展开需要 CTypedef 表,不在本模块做,避免反向依赖)。 -# -# 规范性修正(相对旧表): -# - `SSizeT` 是**有符号**(旧 `_type_name_unsigned` 把它列为无符号,为 A3 缺陷); -# - `BOOL` 按 stdint.vp 定义是 `t.CInt`(**有符号**),并非布尔无符号; -# - 指针名(`BYTEPTR/UINTPTR/INTPTR/CHARPTR/…`)在此返回 UNKNOWN —— -# 指针的"无符号"语义由 PtrLevel 表达,与整数符号性无关。 -# ============================================================ - - -# ============================================================ -# _spec_name_eq - 比较 text[start:end] 与字面量 lit 是否逐字符相等(零分配) -# ============================================================ -def _spec_name_eq(text: str, start: sizet, end: sizet, lit: str) -> int: - """切片名比较:长度相同且逐字符相等返回 1,否则 0""" - if text is None or lit is None: - return 0 - if end <= start: - return 0 - ln: sizet = string.strlen(lit) - if end - start != ln: - return 0 - k: sizet = 0 - while k < ln: - if text[start + k] != lit[k]: - return 0 - k += 1 - return 1 - - -# ============================================================ -# SpecTypeNameBaseIs - 类型名的「容器基名」是否精确等于 base(零分配) -# -# 基名 = 先截断第一个 '[' 起的泛型实参,再取**最后一个 '.' 之后**的部分 -# (去模块名 / LLVM 注册名的模块 sha1 前缀)。例: -# "e94ef9e139461915.list[ast.ASTptr]" → "list" -# "list[ast.AST | t.CPtr]" → "list" -# "memhub.MemBuddy" → "MemBuddy"(≠ list/dict) -# -# 用途:替换容器种类判断里的 strstr 子串匹配(Debugger/_Type.md D20)—— -# `strstr("dict")` 会误命中 `MyDictHelper`,`strstr("list")` 会误命中 `playlist`。 -# 返回 1=是 / 0=否(含名字为空、无法提取基名的情形)。 -# ============================================================ -def SpecTypeNameBaseIs(name: str, base: str) -> int: - """类型名的容器基名是否精确等于 base(1=是 / 0=否)""" - if name is None or base is None: - return 0 - n: sizet = string.strlen(name) - if n == 0: - return 0 - # 基名上界:第一个 '['(泛型实参起点;无 '[' 则到串尾) - end: sizet = n - lb: str = string.strchr(name, '[') - if lb is not None: - end = t.CSizeT(t.CUInt64T(lb) - t.CUInt64T(name)) - # 基名下界:上界之前最后一个 '.' 之后(去模块名 / 模块 sha1 前缀) - start: sizet = 0 - dot: str = string.strchr(name, '.') - while dot is not None: - off: sizet = t.CSizeT(t.CUInt64T(dot) - t.CUInt64T(name)) - if off >= end: - break - start = off + 1 - dot = string.strchr(dot + 1, '.') - return _spec_name_eq(name, start, end, base) - - -# ============================================================ -# SpecSignFromTypeNameSpan - 按名字切片精确判定符号性(零分配) -# 返回 TS_SIGN_UNSIGNED / TS_SIGN_SIGNED / TS_SIGN_UNKNOWN(不表态) -# ============================================================ -def SpecSignFromTypeNameSpan(text: str, start: sizet, end: sizet) -> int: - """按 text[start:end] 精确判定符号性,未覆盖返回 TS_SIGN_UNKNOWN""" - if text is None: - return TS_SIGN_UNKNOWN - # --- t/c 核心无符号原语 --- - if _spec_name_eq(text, start, end, "CUInt8T") != 0: - return TS_SIGN_UNSIGNED - if _spec_name_eq(text, start, end, "CUInt16T") != 0: - return TS_SIGN_UNSIGNED - if _spec_name_eq(text, start, end, "CUInt32T") != 0: - return TS_SIGN_UNSIGNED - if _spec_name_eq(text, start, end, "CUInt64T") != 0: - return TS_SIGN_UNSIGNED - if _spec_name_eq(text, start, end, "CUnsignedChar") != 0: - return TS_SIGN_UNSIGNED - if _spec_name_eq(text, start, end, "CUnsignedShort") != 0: - return TS_SIGN_UNSIGNED - if _spec_name_eq(text, start, end, "CUnsignedInt") != 0: - return TS_SIGN_UNSIGNED - if _spec_name_eq(text, start, end, "CUnsignedLong") != 0: - return TS_SIGN_UNSIGNED - if _spec_name_eq(text, start, end, "CUnsignedLongLong") != 0: - return TS_SIGN_UNSIGNED - if _spec_name_eq(text, start, end, "CSizeT") != 0: - return TS_SIGN_UNSIGNED - if _spec_name_eq(text, start, end, "CUIntPtrT") != 0: - return TS_SIGN_UNSIGNED - if _spec_name_eq(text, start, end, "CBool") != 0: - return TS_SIGN_UNSIGNED - # --- 内建小写标量 --- - if _spec_name_eq(text, start, end, "bool") != 0: - return TS_SIGN_UNSIGNED - # --- t/c 核心有符号原语 --- - if _spec_name_eq(text, start, end, "CInt8T") != 0: - return TS_SIGN_SIGNED - if _spec_name_eq(text, start, end, "CInt16T") != 0: - return TS_SIGN_SIGNED - if _spec_name_eq(text, start, end, "CInt32T") != 0: - return TS_SIGN_SIGNED - if _spec_name_eq(text, start, end, "CInt64T") != 0: - return TS_SIGN_SIGNED - if _spec_name_eq(text, start, end, "CSignedChar") != 0: - return TS_SIGN_SIGNED - if _spec_name_eq(text, start, end, "CShort") != 0: - return TS_SIGN_SIGNED - if _spec_name_eq(text, start, end, "CInt") != 0: - return TS_SIGN_SIGNED - if _spec_name_eq(text, start, end, "CLong") != 0: - return TS_SIGN_SIGNED - if _spec_name_eq(text, start, end, "CLongLong") != 0: - return TS_SIGN_SIGNED - if _spec_name_eq(text, start, end, "CPtrDiffT") != 0: - return TS_SIGN_SIGNED - if _spec_name_eq(text, start, end, "CChar") != 0: - return TS_SIGN_SIGNED - if _spec_name_eq(text, start, end, "int") != 0: - return TS_SIGN_SIGNED - if _spec_name_eq(text, start, end, "char") != 0: - return TS_SIGN_SIGNED - return TS_SIGN_UNKNOWN - - -# ============================================================ -# SpecSignFromTypeName - 类型名(NUL 终止串)精确判定符号性 -# ============================================================ -def SpecSignFromTypeName(name: str) -> int: - """按类型名精确判定符号性,未覆盖返回 TS_SIGN_UNKNOWN""" - if name is None: - return TS_SIGN_UNKNOWN - return SpecSignFromTypeNameSpan(name, 0, string.strlen(name)) - - -# ============================================================ -# TypeSpec - 类型描述符 -# -# 元素语义三字段说明(ElemBits/IsElemPtr/DerefBase): -# 它们替代旧的 VarEntry.IsPtrElement 单一布尔。原因(_Type.md D7-4): -# `str | t.CPtr`、`bytes | t.CPtr`、泛型 `T | t.CPtr`、`64 位标量 | t.CPtr` -# 退化后的 LLVM 类型**都是单层 Ptr(i8)**,即 PtrLevel=1 同时对应两种相反语义, -# 仅靠指针层级无法区分;区分靠的是注解内容 ⇒ 需要「元素宽度 + 元素是否指针 + -# 基址是否需二次解引用」三元组。 -# ============================================================ -@t.NoVTable -class TypeSpec: - """统一类型描述符(字段语义见上)""" - Kind: int # TS_* 之一 - Bits: int # 位宽;非整型/浮点为 0 - IsSigned: int # TS_SIGN_* (-1 未知 / 0 无符号 / 1 有符号) - PtrLevel: int # 指针层级(0=非指针) - Elem: TypeSpec | t.CPtr # Ptr/Array 的指向或元素(None=无) - ArrayCount: int # Array 的元素个数(0=未知/动态) - BaseName: str # 结构体/枚举/类名(带模块 sha1;PermPool 深拷贝) - # SourceName: 注解侧「来源名」(等价旧 VarEntry/FieldEntry.AnnotClassName)。 - # - # 与 BaseName 的**本质区别**是命名域不同: - # BaseName = LLVM 结构体注册名(跨模块/特化时形如 {16hex sha1}.Class 或 - # list[f467978339422f32.AST|t.CPtr]),由 SpecFromLLVMType 反推; - # SourceName = 注解**书写形态**的名字(裸名 MemBuddy / 模块限定名 - # memhub.MemBuddy / t.XXX 裸 attr 名 uint32 / Subscript mangled 名), - # 由注解侧 SpecWithSource 填写。 - # - # 为何需要它:`X | t.CPtr` 联合被简化为 Ptr(i8) 后,BaseName 恒为 None(Spec 从 - # LLVM 反推,类名已丢),而属性访问/方法分派/结构体查找仍要靠注解侧名字恢复。 - # - # **不参与驻留键**:注解名种类远多于类型种类(每个泛型 mangled 名/别名各一份), - # 若入键会让 InternSpec 条目暴增且线性查找变慢;且驻留本意只是跨 reset 存活, - # 而 PermPool 分配天然满足。故 SpecWithSource 返回**独立副本、不进表**。 - SourceName: str - Ret: TypeSpec | t.CPtr # Func:返回类型 - Params: sizet | t.CPtr # Func:参数数组(连续 TypeSpec* 指针,ParamCount 个) - ParamCount: int # Func:参数个数 - IsVarArg: int # Func:1=变参(...) - Storage: int # 限定宏位标志(0=无) - ElemBits: int # 元素槽位宽(元素语义三元组 1/3) - IsElemPtr: int # 元素是否为指针(1=是)(2/3) - DerefBase: int # 基址是否需二次解引用(1=是)(3/3) - Ty: llvmlite.LLVMType | t.CPtr # 解析结果缓存(可空) - - -# ============================================================ -# TypeSpecArena - 驻留表(对象持有,非全局表) -# -# Keys :cap * SPEC_TEXT_MAX 的连续文本缓冲,第 i 条键位于 Keys + i*SPEC_TEXT_MAX -# Specs :cap 个 TypeSpec 指针 -# Count :已驻留条数;Cap:容量 -# ============================================================ -@t.NoVTable -class TypeSpecArena: - """TypeSpec 驻留表(按规范文本键去重,同型只存一份)""" - Keys: bytes - Specs: sizet | t.CPtr - Count: int - Cap: int - - -# ============================================================ -# _spec_key_at - 取第 i 个键的 str 指针(键缓冲内偏移 i * SPEC_TEXT_MAX) -# ============================================================ -def _spec_key_at(keys: bytes, index: int) -> str: - """返回第 index 条键的 str 指针(指向 keys 缓冲内部,不可 free)""" - if keys is None or index < 0: - return None - addr: uint64 = uint64(keys) + uint64(index * SPEC_TEXT_MAX) - return (str | t.CPtr)(t.CVoid(addr, t.CPtr)) - - -# ============================================================ -# SpecArenaInit - 初始化驻留表(幂等;cap<=0 时用 SPEC_INTERN_MAX) -# 返回 0=成功 / 1=失败(分配失败 fail-fast 由调用方处理,此处返回错误码) -# ============================================================ -def SpecArenaInit(arena: TypeSpecArena | t.CPtr, cap: int) -> int: - """初始化驻留表;已初始化则直接返回 0""" - if arena is None: - return 1 - if arena.Keys is not None: - return 0 - use_cap: int = cap - if use_cap <= 0: - use_cap = SPEC_INTERN_MAX - pp: memhub.MemBuddy | t.CPtr = CompilerFactory.factory.PermPool - keys: bytes = pp.alloc(use_cap * SPEC_TEXT_MAX) - if keys is None: - return 1 - specs: sizet | t.CPtr = pp.alloc(use_cap * 8) - if specs is None: - return 1 - string.memset(keys, 0, use_cap * SPEC_TEXT_MAX) - string.memset(specs, 0, use_cap * 8) - arena.Keys = keys - arena.Specs = specs - arena.Count = 0 - arena.Cap = use_cap - return 0 - - -# ============================================================ -# _spec_alloc - 从 PermPool 分配一个清零的 TypeSpec(不驻留,内部用) -# ============================================================ -def _spec_alloc() -> TypeSpec | t.CPtr: - """分配并清零一个 TypeSpec(PermPool)""" - pp: memhub.MemBuddy | t.CPtr = CompilerFactory.factory.PermPool - size: sizet = TypeSpec.__sizeof__() - sp: TypeSpec | t.CPtr = (TypeSpec | t.CPtr)(t.CVoid(pp.alloc(size), t.CPtr)) - if sp is None: - return None - string.memset(sp, 0, size) - sp.Kind = TS_UNKNOWN - sp.Bits = 0 - sp.IsSigned = TS_SIGN_UNKNOWN - sp.PtrLevel = 0 - sp.IsVarArg = 0 - sp.Storage = 0 - return sp - - -# ============================================================ -# _spec_make - 构造一个基础 TypeSpec(不驻留) -# ============================================================ -def _spec_make(kind: int, bits: int, is_signed: int) -> TypeSpec | t.CPtr: - """构造基础 TypeSpec(PermPool,不驻留)""" - sp: TypeSpec | t.CPtr = _spec_alloc() - if sp is None: - return None - sp.Kind = kind - sp.Bits = bits - sp.IsSigned = is_signed - return sp - - -# ============================================================ -# _spec_set_struct_name - 深拷贝类名到 PermPool(跨文件存活) -# ============================================================ -def _spec_set_struct_name(sp: TypeSpec | t.CPtr, name: str) -> int: - """把类名深拷贝到 PermPool 并写入 BaseName,返回 0=成功 / 1=失败""" - if sp is None or name is None: - return 1 - n: sizet = string.strlen(name) - if n <= 0: - return 1 - buf: str = CompilerFactory.factory.PermPool.alloc(n + 1) - if buf is None: - return 1 - string.strcpy(buf, name) - sp.BaseName = buf - return 0 - - -# ============================================================ -# NewTypeSpec - 构造基础类型(驻留) -# ============================================================ -def NewTypeSpec(arena: TypeSpecArena | t.CPtr, kind: int, - bits: int, is_signed: int) -> TypeSpec | t.CPtr: - """构造基础 TypeSpec 并驻留,失败返回 None""" - sp: TypeSpec | t.CPtr = _spec_make(kind, bits, is_signed) - if sp is None: - return None - return InternSpec(arena, sp) - - -# ============================================================ -# NewTypeStruct - 构造结构体/枚举/类类型(驻留) -# ============================================================ -def NewTypeStruct(arena: TypeSpecArena | t.CPtr, kind: int, - base_name: str) -> TypeSpec | t.CPtr: - """构造 struct/union/enum 类型(BaseName 深拷贝 + 驻留),失败返回 None""" - sp: TypeSpec | t.CPtr = _spec_make(kind, 0, TS_SIGN_UNKNOWN) - if sp is None: - return None - if _spec_set_struct_name(sp, base_name) != 0: - return None - return InternSpec(arena, sp) - - -# ============================================================ -# NewTypePtr - 构造指针类型(PtrLevel = 元素 PtrLevel + 1,驻留) -# ============================================================ -def NewTypePtr(arena: TypeSpecArena | t.CPtr, - elem: TypeSpec | t.CPtr) -> TypeSpec | t.CPtr: - """构造指针类型:指向 elem(PtrLevel 逐层递增),失败返回 None""" - if elem is None: - return None - sp: TypeSpec | t.CPtr = _spec_make(TS_PTR, 0, TS_SIGN_UNKNOWN) - if sp is None: - return None - sp.Elem = elem - sp.PtrLevel = elem.PtrLevel + 1 - sp.ElemBits = elem.Bits - sp.IsElemPtr = 0 - if elem.Kind == TS_PTR: - sp.IsElemPtr = 1 - return InternSpec(arena, sp) - - -# ============================================================ -# NewTypeArray - 构造数组类型(ArrayCount 个 elem,驻留) -# ============================================================ -def NewTypeArray(arena: TypeSpecArena | t.CPtr, elem: TypeSpec | t.CPtr, - count: int) -> TypeSpec | t.CPtr: - """构造数组类型:elem[count](count<=0 表示长度未知/动态),失败返回 None""" - if elem is None or count < 0: - return None - sp: TypeSpec | t.CPtr = _spec_make(TS_ARRAY, 0, TS_SIGN_UNKNOWN) - if sp is None: - return None - sp.Elem = elem - sp.ArrayCount = count - sp.ElemBits = elem.Bits - sp.IsElemPtr = 0 - if elem.Kind == TS_PTR: - sp.IsElemPtr = 1 - return InternSpec(arena, sp) - - -# ============================================================ -# NewTypeFunc - 构造函数签名类型(ret + 参数数组 + 变参,驻留) -# params:TypeSpec* 连续数组(由调用方预先构造并保证存活);count 个 -# ============================================================ -def NewTypeFunc(arena: TypeSpecArena | t.CPtr, ret: TypeSpec | t.CPtr, - params: sizet | t.CPtr, count: int, - is_vararg: int) -> TypeSpec | t.CPtr: - """构造函数签名类型,失败返回 None""" - if ret is None or count < 0: - return None - if count > 0 and params is None: - return None - sp: TypeSpec | t.CPtr = _spec_make(TS_FUNC, 0, TS_SIGN_UNKNOWN) - if sp is None: - return None - sp.Ret = ret - sp.Params = params - sp.ParamCount = count - sp.IsVarArg = is_vararg - return InternSpec(arena, sp) - - -# ============================================================ -# SpecBaseText - 基础类型(非 Ptr/Array/Func)的规范文本 -# 返回 0=已写入 / 1=不适用/失败 -# ============================================================ -def SpecBaseText(sp: TypeSpec | t.CPtr, buf: str, buf_size: sizet) -> int: - """把基础类型写成规范文本;Ptr/Array/Func 不适用时返回 1""" - if sp is None or buf is None or buf_size == 0: - return 1 - if sp.Kind == TS_INT: - viperlib.snprintf(buf, buf_size, "i%d", sp.Bits) - return 0 - if sp.Kind == TS_UINT: - viperlib.snprintf(buf, buf_size, "u%d", sp.Bits) - return 0 - if sp.Kind == TS_FLOAT: - viperlib.snprintf(buf, buf_size, "f%d", sp.Bits) - return 0 - if sp.Kind == TS_BOOL: - viperlib.snprintf(buf, buf_size, "bool") - return 0 - if sp.Kind == TS_STRUCT: - # 名字键可能很长(sha1 + 泛型实参),先算所需长度,装不下即失败(不截断) - if sp.BaseName is None or 3 + string.strlen(sp.BaseName) + 1 > buf_size: - return 1 - viperlib.snprintf(buf, buf_size, "st:%s", sp.BaseName) - return 0 - if sp.Kind == TS_UNION: - if sp.BaseName is None or 3 + string.strlen(sp.BaseName) + 1 > buf_size: - return 1 - viperlib.snprintf(buf, buf_size, "un:%s", sp.BaseName) - return 0 - if sp.Kind == TS_ENUM: - if sp.BaseName is None or 3 + string.strlen(sp.BaseName) + 1 > buf_size: - return 1 - viperlib.snprintf(buf, buf_size, "en:%s", sp.BaseName) - return 0 - if sp.Kind == TS_VOID: - viperlib.snprintf(buf, buf_size, "void") - return 0 - return 1 - - -# ============================================================ -# SpecToText - 规范文本编码(驻留键 / 日志 / vpi·stub 通道) -# -# 格式草案: -# i32 / u64 / f64 / bool / void -# st:{sha1}.Class 结构体(BaseName 原样);un: / en: 同构,分别表示联合/枚举 -# p:INNER 指针(每层一个 "p:" 前缀,层数即 PtrLevel) -# arr[N]:INNER 数组(N=0 表示长度未知) -# fn(INNER,INNER,...)->RET 函数签名(变参追加 "...") -# 递归深度上限 32(防环);超限或缓冲不足返回 1(fail-fast 由调用方决定) -# ============================================================ -def SpecToText(sp: TypeSpec | t.CPtr, buf: str, buf_size: sizet) -> int: - """把 TypeSpec 编码为规范文本,返回 0=成功 / 1=失败""" - return _spec_to_text(sp, buf, buf_size, 0) - - -def _spec_to_text(sp: TypeSpec | t.CPtr, buf: str, buf_size: sizet, - depth: int) -> int: - """SpecToText 的递归实现(depth 上限 32)""" - if sp is None or buf is None or buf_size == 0 or depth > 32: - return 1 - buf[0] = '\0' - if sp.Kind == TS_PTR: - # p: + 内层 - inner_buf: str = CompilerFactory.factory.PermPool.alloc(SPEC_TEXT_MAX) - if inner_buf is None: - return 1 - if _spec_to_text(sp.Elem, inner_buf, SPEC_TEXT_MAX, depth + 1) != 0: - return 1 - pos_p: sizet = _spec_text_append(buf, buf_size, 0, "p:") - if pos_p >= buf_size: - return 1 - pos_p = _spec_text_append(buf, buf_size, pos_p, inner_buf) - if pos_p >= buf_size: - return 1 - return 0 - if sp.Kind == TS_ARRAY: - # arr[N]: + 内层 - inner_buf_a: str = CompilerFactory.factory.PermPool.alloc(SPEC_TEXT_MAX) - if inner_buf_a is None: - return 1 - if _spec_to_text(sp.Elem, inner_buf_a, SPEC_TEXT_MAX, depth + 1) != 0: - return 1 - prefix_a: str = CompilerFactory.factory.PermPool.alloc(64) - if prefix_a is None: - return 1 - viperlib.snprintf(prefix_a, 64, "arr[%d]:", sp.ArrayCount) - pos_a: sizet = _spec_text_append(buf, buf_size, 0, prefix_a) - if pos_a >= buf_size: - return 1 - pos_a = _spec_text_append(buf, buf_size, pos_a, inner_buf_a) - if pos_a >= buf_size: - return 1 - return 0 - if sp.Kind == TS_FUNC: - # fn(p1,p2,...)->ret(每次追加都检查溢出哨兵,绝不静默截断键) - pos: sizet = 0 - pos = _spec_text_append(buf, buf_size, pos, "fn(") - if pos >= buf_size: - return 1 - i: int = 0 - while i < sp.ParamCount: - if i > 0: - pos = _spec_text_append(buf, buf_size, pos, ",") - if pos >= buf_size: - return 1 - param: TypeSpec | t.CPtr = _spec_param_at(sp, i) - if param is None: - return 1 - param_buf: str = CompilerFactory.factory.PermPool.alloc(SPEC_TEXT_MAX) - if param_buf is None: - return 1 - if _spec_to_text(param, param_buf, SPEC_TEXT_MAX, depth + 1) != 0: - return 1 - pos = _spec_text_append(buf, buf_size, pos, param_buf) - if pos >= buf_size: - return 1 - i += 1 - if sp.IsVarArg == 1: - if sp.ParamCount > 0: - pos = _spec_text_append(buf, buf_size, pos, ",...") - else: - pos = _spec_text_append(buf, buf_size, pos, "...") - if pos >= buf_size: - return 1 - pos = _spec_text_append(buf, buf_size, pos, ")->") - if pos >= buf_size: - return 1 - ret_buf: str = CompilerFactory.factory.PermPool.alloc(SPEC_TEXT_MAX) - if ret_buf is None: - return 1 - if _spec_to_text(sp.Ret, ret_buf, SPEC_TEXT_MAX, depth + 1) != 0: - return 1 - pos = _spec_text_append(buf, buf_size, pos, ret_buf) - if pos >= buf_size: - return 1 - return 0 - # 基础类型 - return SpecBaseText(sp, buf, buf_size) - - -# ============================================================ -# _spec_text_append - 有界尾部追加(返回新的写入位置) -# -# **溢出哨兵**:返回 `buf_size` 表示"装不下"(合法位置恒 < buf_size)。 -# 调用方**必须**据此返回失败 —— 绝不静默截断:驻留键被截断会让后续 -# strcmp 撞上别的类型,从而返回**错误的 Spec 实例**(2026-09-11 实测: -# 长函数签名键被截断 ⇒ 某函数拿到别的函数的签名 Spec,格式化闸门报 ret 不符)。 -# ============================================================ -def _spec_text_append(buf: str, buf_size: sizet, pos: sizet, text: str) -> sizet: - """把 text 追加到 buf 的 pos 处;装不下返回 buf_size(哨兵),否则返回新位置""" - if buf is None or text is None: - return buf_size - tlen: sizet = string.strlen(text) - i: sizet = 0 - while i < tlen: - if pos + 1 >= buf_size: - buf[pos] = '\0' - return buf_size - buf[pos] = text[i] - pos += 1 - i += 1 - buf[pos] = '\0' - return pos - - -# ============================================================ -# _spec_param_at - 取函数签名第 i 个参数 TypeSpec 指针 -# ============================================================ -def _spec_param_at(sp: TypeSpec | t.CPtr, index: int) -> TypeSpec | t.CPtr: - """返回 Func 类型第 index 个参数的 TypeSpec 指针,越界返回 None""" - if sp is None or sp.Params is None or index < 0 or index >= sp.ParamCount: - return None - addr: uint64 = uint64(sp.Params) + uint64(index * 8) - slot: sizet | t.CPtr = (sizet | t.CPtr)(t.CVoid(addr, t.CPtr)) - if slot is None: - return None - return (TypeSpec | t.CPtr)(t.CVoid(uint64(slot[0]), t.CPtr)) - - -# ============================================================ -# TextToSpec - 规范文本解码(SpecToText 的逆;不驻留,由调用方决定是否驻留) -# 解析失败返回 None(fail-fast 由调用方决定) -# ============================================================ -def TextToSpec(text: str) -> TypeSpec | t.CPtr: - """把规范文本解码为 TypeSpec(PermPool,不驻留),失败返回 None""" - if text is None: - return None - return _text_to_spec(text, 0) - - -def _text_to_spec(text: str, depth: int) -> TypeSpec | t.CPtr: - """TextToSpec 的递归实现(depth 上限 32)""" - if text is None or depth > 32: - return None - # 指针:p:INNER - if string.strncmp(text, "p:", 2) == 0: - inner: TypeSpec | t.CPtr = _text_to_spec(text + 2, depth + 1) - if inner is None: - return None - sp_p: TypeSpec | t.CPtr = _spec_make(TS_PTR, 0, TS_SIGN_UNKNOWN) - if sp_p is None: - return None - sp_p.Elem = inner - sp_p.PtrLevel = inner.PtrLevel + 1 - sp_p.ElemBits = inner.Bits - if inner.Kind == TS_PTR: - sp_p.IsElemPtr = 1 - return sp_p - # 数组:arr[N]:INNER - if string.strncmp(text, "arr[", 4) == 0: - rb: str = string.strchr(text, ']') - if rb is None: - return None - count: int = string.atoi(text + 4) - if count < 0: - return None - colon: str = string.strchr(rb, ':') - if colon is None: - return None - inner_a: TypeSpec | t.CPtr = _text_to_spec(colon + 1, depth + 1) - if inner_a is None: - return None - sp_a: TypeSpec | t.CPtr = _spec_make(TS_ARRAY, 0, TS_SIGN_UNKNOWN) - if sp_a is None: - return None - sp_a.Elem = inner_a - sp_a.ArrayCount = count - sp_a.ElemBits = inner_a.Bits - if inner_a.Kind == TS_PTR: - sp_a.IsElemPtr = 1 - return sp_a - # 函数:fn(...)->RET - if string.strncmp(text, "fn(", 3) == 0: - return _text_to_func(text, depth) - # 结构体/联合/枚举:st:NAME / un:NAME / en:NAME - if string.strncmp(text, "st:", 3) == 0: - return _spec_make_struct(TS_STRUCT, text + 3) - if string.strncmp(text, "un:", 3) == 0: - return _spec_make_struct(TS_UNION, text + 3) - if string.strncmp(text, "en:", 3) == 0: - return _spec_make_struct(TS_ENUM, text + 3) - if string.strcmp(text, "bool") == 0: - return _spec_make(TS_BOOL, 1, TS_SIGN_UNSIGNED) - if string.strcmp(text, "void") == 0: - return _spec_make(TS_VOID, 0, TS_SIGN_UNKNOWN) - # i32 / u64 / f64 - if text[0] == 'u' or text[0] == 'i' or text[0] == 'f': - bits: int = string.atoi(text + 1) - if bits <= 0: - return None - if text[0] == 'u': - return _spec_make(TS_UINT, bits, TS_SIGN_UNSIGNED) - if text[0] == 'i': - return _spec_make(TS_INT, bits, TS_SIGN_SIGNED) - return _spec_make(TS_FLOAT, bits, TS_SIGN_SIGNED) - return None - - -# ============================================================ -# _spec_make_struct - 构造 struct(深拷贝名字) -# ============================================================ -def _spec_make_struct(kind: int, name: str) -> TypeSpec | t.CPtr: - """构造 struct/union/enum 类型(不驻留),失败返回 None""" - if name is None or name[0] == '\0': - return None - sp: TypeSpec | t.CPtr = _spec_make(kind, 0, TS_SIGN_UNKNOWN) - if sp is None: - return None - if _spec_set_struct_name(sp, name) != 0: - return None - return sp - - -# ============================================================ -# _text_to_func - 解析 "fn(p1,p2,...)->RET" -# ============================================================ -def _text_to_func(text: str, depth: int) -> TypeSpec | t.CPtr: - """解析函数签名文本,失败返回 None""" - lp: str = string.strchr(text, '(') - if lp is None: - return None - arrow: str = string.strstr(text, ")->") - if arrow is None: - return None - # 参数段范围(lp+1 .. arrow-1) - params_buf: str = CompilerFactory.factory.PermPool.alloc(SPEC_TEXT_MAX) - if params_buf is None: - return None - params_buf[0] = '\0' - nlen: sizet = t.CSizeT(t.CUInt64T(arrow) - t.CUInt64T(lp)) - 1 - if nlen > 0: - string.strncpy(params_buf, lp + 1, nlen) - params_buf[nlen] = '\0' - is_vararg: int = 0 - if string.strstr(params_buf, "...") is not None: - is_vararg = 1 - # 逐段解析参数(按顶层 ',' 分割;变参段 "..." 跳过) - param_specs: sizet | t.CPtr = CompilerFactory.factory.PermPool.alloc(8 * 64) - if param_specs is None: - return None - pcount: int = 0 - if nlen > 0: - cur: str = params_buf - while cur is not None: - comma: str = string.strchr(cur, ',') - seg: str = cur - if comma is not None: - seg_make: str = CompilerFactory.factory.PermPool.alloc(SPEC_TEXT_MAX) - if seg_make is None: - return None - seg_len: sizet = t.CSizeT(t.CUInt64T(comma) - t.CUInt64T(cur)) - string.strncpy(seg_make, cur, seg_len) - seg_make[seg_len] = '\0' - seg = seg_make - cur = comma + 1 - else: - cur = None - if string.strcmp(seg, "...") == 0: - continue - if pcount >= 64: - return None - psp: TypeSpec | t.CPtr = _text_to_spec(seg, depth + 1) - if psp is None: - return None - slot_p: sizet | t.CPtr = (sizet | t.CPtr)( - t.CVoid(uint64(param_specs) + uint64(pcount * 8), t.CPtr)) - if slot_p is None: - return None - slot_p[0] = sizet(psp) - pcount += 1 - ret: TypeSpec | t.CPtr = _text_to_spec(arrow + 3, depth + 1) - if ret is None: - return None - sp_f: TypeSpec | t.CPtr = _spec_make(TS_FUNC, 0, TS_SIGN_UNKNOWN) - if sp_f is None: - return None - sp_f.Ret = ret - sp_f.Params = param_specs - sp_f.ParamCount = pcount - sp_f.IsVarArg = is_vararg - return sp_f - - -# ============================================================ -# InternSpec - 规范化驻留:同键只保留一份,返回驻留后的实例 -# 键 = SpecToText;**表容量**超限 → fatal_error(绝不返回 None:那会让调用方条目 -# 静默丢失类型信息);**键文本**装不下 SPEC_TEXT_MAX → 保留实例但放弃去重 -# (绝不写入截断键)。 -# ============================================================ -def InternSpec(arena: TypeSpecArena | t.CPtr, - sp: TypeSpec | t.CPtr) -> TypeSpec | t.CPtr: - """按规范文本键驻留 TypeSpec;失败返回 None""" - if arena is None or sp is None: - return sp - if SpecArenaInit(arena, 0) != 0: - return None - key_buf: str = CompilerFactory.factory.PermPool.alloc(SPEC_TEXT_MAX) - if key_buf is None: - return None - if SpecToText(sp, key_buf, SPEC_TEXT_MAX) != 0: - # 键装不下(长函数签名 / 深嵌套):**保留实例但放弃去重**。 - # 这不是语义兜底 —— sp 本身完整正确,只是失去"同型共享"这一优化; - # 关键在于**绝不能把截断键写入表**:截断键会让后续 strcmp 撞上别的类型 - # 并返回**错误实例**(2026-09-11 实测的格式化闸门误报根因)。 - return sp - # 线性查找已有键(规模与类型种数同阶,量级不大;命中即复用) - i: int = 0 - while i < arena.Count: - exist_key: str = _spec_key_at(arena.Keys, i) - if exist_key is not None and string.strcmp(exist_key, key_buf) == 0: - slot_e: sizet | t.CPtr = (sizet | t.CPtr)( - t.CVoid(uint64(arena.Specs) + uint64(i * 8), t.CPtr)) - if slot_e is None: - return None - return (TypeSpec | t.CPtr)(t.CVoid(uint64(slot_e[0]), t.CPtr)) - i += 1 - # 未命中:追加。**表满 = fail-fast**(Debugger/_Type.md D14 风险 2): - # 不能返回 None —— 调用链会把 None 一路传到 entry.Spec,条目**静默失去类型信息** - # (如 _entry_spec_unsigned 恒返回 0 ⇒ zext/sext 方向取错),属静默数据损坏, - # 与「不兜底 / fail-fast」原则直接冲突(原注释声称 fail-fast,实现却只返回 None)。 - if arena.Count >= arena.Cap: - GenApi.fatal_error( - None, - f"TypeSpec 驻留表已满(上限 {arena.Cap} 条),无法登记新类型", - "InternalCompilerError") - # 仅在 fatal_error 无 gen 通道(no-op)时可达:退化为「不驻留但返回完整实例」, - # 守住"不返回 None"这一底线 —— 宁失去同型共享,也不让条目静默丢类型。 - return sp - dst_key: str = _spec_key_at(arena.Keys, arena.Count) - if dst_key is None: - return None - string.strcpy(dst_key, key_buf) - slot_n: sizet | t.CPtr = (sizet | t.CPtr)( - t.CVoid(uint64(arena.Specs) + uint64(arena.Count * 8), t.CPtr)) - if slot_n is None: - return None - slot_n[0] = sizet(sp) - arena.Count += 1 - return sp - - -# ============================================================ -# 只读访问器(供 S3 起替换旧的字符串判定) -# ============================================================ -def SpecIsPtr(sp: TypeSpec | t.CPtr) -> int: - """是否指针类型(PtrLevel>0)""" - if sp is None: - return 0 - if sp.PtrLevel > 0: - return 1 - return 0 - - -def SpecPointedTo(sp: TypeSpec | t.CPtr) -> TypeSpec | t.CPtr: - """指针的指向类型(非指针返回 None)""" - if sp is None or sp.Kind != TS_PTR: - return None - return sp.Elem - - -# ============================================================ -# _spec_clone - 浅拷贝 TypeSpec(PermPool,**不驻留**) -# -# Elem/Ret/Params 指针共享子实例(子实例自身由 NewTypeXxx 驻留)。 -# 供 SpecWithSign / SpecWithSource / SpecWithElemBits 复用,避免多处重复 -# 逐字段拷贝(漏字段是最容易引入的隐蔽 bug:例如忘了 IsElemPtr)。 -# ============================================================ -def _spec_clone(sp: TypeSpec | t.CPtr) -> TypeSpec | t.CPtr: - """浅拷贝 sp(含全部字段),分配失败返回 None""" - if sp is None: - return None - cp: TypeSpec | t.CPtr = _spec_alloc() - if cp is None: - return None - cp.Kind = sp.Kind - cp.Bits = sp.Bits - cp.IsSigned = sp.IsSigned - cp.PtrLevel = sp.PtrLevel - cp.Elem = sp.Elem - cp.ArrayCount = sp.ArrayCount - cp.BaseName = sp.BaseName - cp.SourceName = sp.SourceName - cp.Ret = sp.Ret - cp.Params = sp.Params - cp.ParamCount = sp.ParamCount - cp.IsVarArg = sp.IsVarArg - cp.Storage = sp.Storage - cp.ElemBits = sp.ElemBits - cp.IsElemPtr = sp.IsElemPtr - cp.DerefBase = sp.DerefBase - cp.Ty = sp.Ty - return cp - - -# ============================================================ -# SpecWithSign - 复制 Spec 并按注解覆盖整数符号性(TS_INT ↔ TS_UINT) -# -# 背景(S4 注解侧填 Spec):SpecFromLLVMType 从 LLVM 类型反推时,整数恒 -# TS_INT(LLVM iN 不分符号)。但 SpecToText 对 TS_INT 编 "i%d"、TS_UINT 编 -# "u%d",符号性由 **Kind** 区分 —— 若只改 IsSigned 不改 Kind,两个符号性不同 -# 的整数会得到相同驻留键 "i%d" 而撞键(同键不同义,返回错误实例)。 -# 注解侧知道真实符号性(uint32 等无符号名),须把 TS_INT 切为 TS_UINT。 -# -# 仅当符号性实际变化才复制并驻留,否则返回原实例。驻留去重 ⇒ 同「结构+符号」共享一份。 -# ============================================================ -def SpecWithSign(arena: TypeSpecArena | t.CPtr, - sp: TypeSpec | t.CPtr, - is_signed: int) -> TypeSpec | t.CPtr: - """复制 sp 并覆盖整数符号性,驻留后返回;无变化返回原实例,失败返回 None""" - if sp is None: - return None - new_kind: int = sp.Kind - new_signed: int = sp.IsSigned - if is_signed == TS_SIGN_UNSIGNED and sp.Kind == TS_INT: - new_kind = TS_UINT - new_signed = TS_SIGN_UNSIGNED - elif is_signed == TS_SIGN_SIGNED and sp.Kind == TS_UINT: - new_kind = TS_INT - new_signed = TS_SIGN_SIGNED - if new_kind == sp.Kind: - return sp - cp: TypeSpec | t.CPtr = _spec_clone(sp) - if cp is None: - return None - cp.Kind = new_kind - cp.IsSigned = new_signed - # **清空 SourceName**:本函数走 InternSpec(键 = SpecToText,不含 SourceName), - # 若把带来源名的副本写进表,后续同键查找会把该来源名**污染**给无关条目 - # (键相同 ⇒ 语义必须相同 ⇒ 表内实例的 SourceName 恒为 None)。 - # 需要来源名时由调用方随后用 SpecWithSource(独立副本)叠加。 - cp.SourceName = None - return InternSpec(arena, cp) - - -# ============================================================ -# _spec_set_source_name - 深拷贝注解来源名到 PermPool 并写入 SourceName -# ============================================================ -def _spec_set_source_name(sp: TypeSpec | t.CPtr, name: str) -> int: - """把注解来源名深拷贝到 PermPool 并写入 SourceName,返回 0=成功 / 1=失败""" - if sp is None or name is None: - return 1 - n: sizet = string.strlen(name) - if n <= 0: - return 1 - buf: str = CompilerFactory.factory.PermPool.alloc(n + 1) - if buf is None: - return 1 - string.strcpy(buf, name) - sp.SourceName = buf - return 0 - - -# ============================================================ -# SpecWithSource - 复制 Spec 并附上注解侧来源名(独立副本,**不驻留**) -# -# 用途(S4 注解侧填 Spec 的「类名块」):`X | t.CPtr` 简化成 Ptr(i8) 后 Spec 里 -# 没有类名,而属性访问/方法分派/结构体查找要靠注解侧名字恢复,故在注解侧把 -# 来源名附到 Spec 上(SourceName),供消费点逐步切读(替代 AnnotClassName)。 -# -# 为何**不**走 InternSpec:SourceName 种类远多于类型种类(泛型 mangled 名、别名 -# 各一份),入键会让驻留条目暴增 + 线性查找变慢;而驻留只为跨 reset 存活, -# PermPool 分配天然满足。故返回独立副本(浅拷贝,Elem/Ret/Params 共享子实例)。 -# -# 幂等:sp.SourceName 已等于 name 时返回原实例(避免重复副本)。 -# ============================================================ -def SpecWithSource(sp: TypeSpec | t.CPtr, name: str) -> TypeSpec | t.CPtr: - """复制 sp 并设置 SourceName(独立副本,不驻留);name 为空返回原实例""" - if sp is None or name is None or name[0] == '\0': - return sp - if sp.SourceName is not None and string.strcmp(sp.SourceName, name) == 0: - return sp - cp: TypeSpec | t.CPtr = _spec_clone(sp) - if cp is None: - return sp - if _spec_set_source_name(cp, name) != 0: - return sp - return cp - - -# ============================================================ -# SpecWithElemBits - 复制 Spec 并覆盖元素槽位宽(独立副本,**不驻留**) -# -# 用途(S4 的 IsPtrElement 替代):`str | t.CPtr` / `bytes | t.CPtr` / -# `T | t.CPtr` / `64 位标量 | t.CPtr` 在 LLVM 层**都是单层 Ptr(i8)** -# (PtrLevel=1 同时对应两种相反语义),无法据类型区分"1 字节步长"与 -# "8 字节槽步长";区分只能靠注解判定 ⇒ 注解侧把元素槽宽覆盖为 8 字节。 -# -# ElemBits 是派生字段(**不在 SpecToText 键内**)⇒ 必须返回独立副本: -# 若走 InternSpec 会命中键相同但 ElemBits 未覆盖的实例,覆盖丢失。 -# ============================================================ -def SpecWithElemBits(sp: TypeSpec | t.CPtr, elem_bits: int) -> TypeSpec | t.CPtr: - """复制 sp 并设置 ElemBits(独立副本,不驻留);无变化返回原实例""" - if sp is None: - return sp - if sp.ElemBits == elem_bits: - return sp - cp: TypeSpec | t.CPtr = _spec_clone(sp) - if cp is None: - return sp - cp.ElemBits = elem_bits - return cp - - -def SpecSourceName(sp: TypeSpec | t.CPtr) -> str: - """Spec 的注解来源名(未设置返回 None)""" - if sp is None: - return None - return sp.SourceName - - -def SpecIsUnsigned(sp: TypeSpec | t.CPtr) -> int: - """是否无符号整数(单一真源;未知返回 0)""" - if sp is None: - return 0 - if sp.IsSigned == TS_SIGN_UNSIGNED: - return 1 - return 0 - - -def SpecBitWidth(sp: TypeSpec | t.CPtr) -> int: - """位宽(非整形/浮点返回 0)""" - if sp is None: - return 0 - return sp.Bits - - -# ============================================================ -# SpecTypePtrLevel - LLVM 类型 → 指针层级(**指针层级块的唯一实现**) -# -# S3 起由 ExprGenBase.get_ptr_level 委托调用(原实现是 Gen 层里的同码副本, -# 现收拢到本模块,成为该块切读 TypeSpec 的入口)。 -# 返回 0=非指针 / 1=一级指针 / 2=二级指针 / 3+… -# -# ⚠️ 规避自举 match codegen 缺陷(原 get_ptr_level 注释所记):`case` 体内 -# **直接更新外层 while 条件变量**会把赋值写进 subject 快照槽,while 条件读旧槽 -# ⇒ 死循环。故此处 `case` 只绑定局部 `nxt`,循环变量在 match **外**更新。 -# ============================================================ -def SpecTypePtrLevel(ty: llvmlite.LLVMType | t.CPtr) -> int: - """计算指针层级,0=非指针,1=一级指针,2=二级指针…""" - if ty is None: - return 0 - level: int = 0 - cur: llvmlite.LLVMType | t.CPtr = ty - while cur is not None: - nxt: llvmlite.LLVMType | t.CPtr = None - match cur: - case llvmlite.LLVMType.Ptr(pointee): - level += 1 - nxt = pointee - case _: - break - cur = nxt - return level - - -# ============================================================ -# SpecTypeBits - LLVM 类型 → 整数位宽(**位宽块的唯一实现**) -# -# S4 起由 ExprGenBase.get_llvm_type_bits 与 TypeGenErr.get_llvm_type_bits 委托调用 -# (原为两份同码副本:ExprGenBase.vp:104 + TypeGenErr.vp:253)。收拢理由与 -# SpecTypePtrLevel 相同:同为「LLVMType → 标量」的纯函数,属本模块职责域; -# 副本一旦分叉会出现「同一类型在两处算出不同位宽」的隐蔽不一致。 -# 非整数类型(指针/浮点/结构体等)返回 0 —— 0 是"非整数"的表态,不是兜底位宽。 -# ============================================================ -def SpecTypeBits(ty: llvmlite.LLVMType | t.CPtr) -> int: - """获取 LLVM 整数类型的位宽,非整数类型返回 0""" - if ty is None: - return 0 - match ty: - case llvmlite.LLVMType.Int(bits): - return bits - case _: - return 0 - - -# ============================================================ -# SpecToLLVMText - TypeSpec → LLVM IR 类型文本(**逐字节对齐 llvmlite.TypePrint**) -# -# 用途:作为 FuncEntry.Spec 的 LLVM 文本派生源(旧 FuncEntry.TypeStr 字符串生产者 -# 已在 S4 删除),推进去字符串化(Debugger/_Type.md D14 起)。 -# -# 对齐依据:`includes/llvmlite/__types.vp:395-511` 的 `_TypePrintDepth`,逐分支照搬: -# Int(bits) → "iN"(**无符号也是 iN** —— LLVM 文本层不分符号) -# Float(bits) → 16/32/64/128 → half/float/double/fp128;其它 → "float%x"(十六进制) -# Void → "void" -# Ptr(pointee)→ pointee 为 None/Void → "i8*";pointee 为**命名结构体** → `%""*` -# (特例,不递归);否则递归 pointee 后追加 '*' -# Array(e, N) → "[N x ELEM]" -# Struct/Union/Enum(name) → `%""`;**匿名结构体 → 显式返回失败** -# (Spec 未保留字段列表,无法还原 TypePrint 的 "{ty1, ty2}",不造伪文本) -# Func → "RET (P0, P1)";本实现**额外**按 Spec.IsVarArg 追加 ", ..." / "...", -# 以对齐 `FuncEntry.TypeStr` 的生产口径(TypePrint 的 LLVMType.Func -# **不含**变参信息,这一步是本 Spec 口径的补充而非照搬)。 -# -# 返回 0=已写入 / 1=不适用或失败(调用方显式处置,不静默兜底) -# ============================================================ -SPEC_LLVM_TEXT_MAX_DEPTH: t.CDefine = 100 - - -def SpecToLLVMText(sp: TypeSpec | t.CPtr, buf: str, buf_size: sizet) -> int: - """TypeSpec → LLVM IR 类型文本(对齐 TypePrint),返回 0=成功 / 1=失败""" - if sp is None or buf is None or buf_size == 0: - return 1 - buf[0] = '\0' - return _spec_llvm_text(sp, buf, buf_size, 0) - - -def _spec_llvm_append(buf: str, buf_size: sizet, src: str) -> int: - """把 src 追加到 buf 末尾(有界,不越写),返回 0=成功 / 1=容量不足""" - if buf is None or src is None: - return 1 - pos: sizet = string.strlen(buf) - n: sizet = string.strlen(src) - if pos + n + 1 > buf_size: - return 1 - string.strcpy(buf + pos, src) - return 0 - - -def _spec_llvm_text(sp: TypeSpec | t.CPtr, buf: str, buf_size: sizet, - depth: int) -> int: - """把 sp 的 LLVM 文本**追加**到 buf 末尾(buf 已有前缀时保持原前缀)""" - if sp is None or buf is None: - return 1 - if depth >= SPEC_LLVM_TEXT_MAX_DEPTH: - return 1 - pos: sizet = string.strlen(buf) - if pos + 1 >= buf_size: - return 1 - # --- 基础标量(无符号在 LLVM 文本层同样是 iN) --- - if sp.Kind == TS_INT or sp.Kind == TS_UINT: - viperlib.snprintf(buf + pos, buf_size - pos, "i%d", sp.Bits) - return 0 - if sp.Kind == TS_BOOL: - viperlib.snprintf(buf + pos, buf_size - pos, "i1") - return 0 - if sp.Kind == TS_FLOAT: - if sp.Bits == 16: - viperlib.snprintf(buf + pos, buf_size - pos, "half") - elif sp.Bits == 32: - viperlib.snprintf(buf + pos, buf_size - pos, "float") - elif sp.Bits == 64: - viperlib.snprintf(buf + pos, buf_size - pos, "double") - elif sp.Bits == 128: - viperlib.snprintf(buf + pos, buf_size - pos, "fp128") - else: - viperlib.snprintf(buf + pos, buf_size - pos, "float%x", sp.Bits) - return 0 - if sp.Kind == TS_VOID: - viperlib.snprintf(buf + pos, buf_size - pos, "void") - return 0 - # --- 指针 --- - if sp.Kind == TS_PTR: - inner: TypeSpec | t.CPtr = sp.Elem - if inner is None or inner.Kind == TS_VOID: - viperlib.snprintf(buf + pos, buf_size - pos, "i8*") - return 0 - if inner.Kind == TS_STRUCT or inner.Kind == TS_UNION or inner.Kind == TS_ENUM: - if inner.BaseName is not None: - viperlib.snprintf(buf + pos, buf_size - pos, "%%\"%s\"*", inner.BaseName) - return 0 - if _spec_llvm_text(inner, buf, buf_size, depth + 1) != 0: - return 1 - pos2: sizet = string.strlen(buf) - if pos2 + 1 >= buf_size: - return 1 - buf[pos2] = '*' - buf[pos2 + 1] = '\0' - return 0 - # --- 数组 --- - if sp.Kind == TS_ARRAY: - viperlib.snprintf(buf + pos, buf_size - pos, "[%d x ", sp.ArrayCount) - if _spec_llvm_text(sp.Elem, buf, buf_size, depth + 1) != 0: - return 1 - return _spec_llvm_append(buf, buf_size, "]") - # --- 命名结构体 / 联合 / 枚举 --- - if sp.Kind == TS_STRUCT or sp.Kind == TS_UNION or sp.Kind == TS_ENUM: - if sp.BaseName is None: - return 1 - viperlib.snprintf(buf + pos, buf_size - pos, "%%\"%s\"", sp.BaseName) - return 0 - # --- 函数签名 --- - if sp.Kind == TS_FUNC: - if _spec_llvm_text(sp.Ret, buf, buf_size, depth + 1) != 0: - return 1 - if _spec_llvm_append(buf, buf_size, " (") != 0: - return 1 - i: int = 0 - while i < sp.ParamCount: - if i > 0: - if _spec_llvm_append(buf, buf_size, ", ") != 0: - return 1 - ps: TypeSpec | t.CPtr = _spec_param_at(sp, i) - if ps is None: - return 1 - if _spec_llvm_text(ps, buf, buf_size, depth + 1) != 0: - return 1 - i += 1 - # 变参后缀(本 Spec 口径独有,见上方说明) - if sp.IsVarArg == 1: - if sp.ParamCount > 0: - if _spec_llvm_append(buf, buf_size, ", ...") != 0: - return 1 - else: - if _spec_llvm_append(buf, buf_size, "...") != 0: - return 1 - return _spec_llvm_append(buf, buf_size, ")") - return 1 - - -# ============================================================ -# SpecFromLLVMType - 已解析 LLVM 类型 → TypeSpec(结构翻译) -# -# 只做**结构层**翻译:Int / Float / Void / Ptr / Array / Func / Struct。 -# - 指针层级:由 Ptr 递归得到(NewTypePtr 内 PtrLevel = Elem.PtrLevel + 1) -# - 数组维度:取 Array.Count(元素语义三元组由 NewTypeArray 填) -# - 函数签名:Ret + 形参数组(沿 ParamNode 链表遍历;llvmlite **无按下标取参**) -# - 结构体:取结构体名;匿名结构体退化为无名 TS_STRUCT -# -# ⚠️ 两个**已知局限**(有意为之,避免臆造): -# 1. 符号性:LLVM 类型层**无法区分 iN 与 uN**(都是 i32)⇒ 本转换器一律给 -# `TS_INT + TS_SIGN_SIGNED`(与 SpecBaseText 的 "iN" 编码口径一致,保证驻留键 -# 不产生"同键不同义")。**无符号性必须由注解侧(符号性真源)覆盖**; -# 消费方在 S3 切读前**不要直接信任**本 spec 的 IsSigned。 -# 2. 变参:`...` 不在 `LLVMType.Func` 上(只存在于 `llvmlite.Function.IsVarArg`) -# ⇒ 本转换器恒置 IsVarArg=0;带变参的签名需由函数对象侧补写。 -# -# 本函数当前**无调用点**(S2 只入库;接线在后续步骤)。 -# ============================================================ -def SpecFromLLVMType(arena: TypeSpecArena | t.CPtr, - ty: llvmlite.LLVMType | t.CPtr) -> TypeSpec | t.CPtr: - """把已解析的 LLVM 类型翻译成 TypeSpec;不支持或为 None 时返回 None""" - if arena is None or ty is None: - return None - match ty: - case llvmlite.LLVMType.Int(bits): - if bits == 1: - return NewTypeSpec(arena, TS_BOOL, 1, TS_SIGN_UNSIGNED) - return NewTypeSpec(arena, TS_INT, bits, TS_SIGN_SIGNED) - case llvmlite.LLVMType.Float(bits): - return NewTypeSpec(arena, TS_FLOAT, bits, TS_SIGN_SIGNED) - case llvmlite.LLVMType.Void(): - return NewTypeSpec(arena, TS_VOID, 0, TS_SIGN_UNKNOWN) - case llvmlite.LLVMType.Ptr(pointee): - return _spec_from_ptr(arena, pointee) - case llvmlite.LLVMType.Array(elem_ty, count): - return _spec_from_array(arena, elem_ty, count) - case llvmlite.LLVMType.Func(ret, params, pcount): - return _spec_from_func(arena, ret, params, pcount) - case llvmlite.LLVMType.Struct(_, _, sname): - return _spec_from_struct(arena, sname) - case _: - return None - - -def _spec_from_ptr(arena: TypeSpecArena | t.CPtr, - pointee: llvmlite.LLVMType | t.CPtr) -> TypeSpec | t.CPtr: - """Ptr(pointee) → TypeSpec(PtrLevel/ElemBits/IsElemPtr 由 NewTypePtr 填)""" - inner: TypeSpec | t.CPtr = SpecFromLLVMType(arena, pointee) - if inner is None: - return None - return NewTypePtr(arena, inner) - - -def _spec_from_array(arena: TypeSpecArena | t.CPtr, - elem_ty: llvmlite.LLVMType | t.CPtr, - count: int) -> TypeSpec | t.CPtr: - """[count x elem] → TypeSpec(ArrayCount/ElemBits/IsElemPtr 由 NewTypeArray 填)""" - inner: TypeSpec | t.CPtr = SpecFromLLVMType(arena, elem_ty) - if inner is None: - return None - return NewTypeArray(arena, inner, count) - - -def _spec_from_func(arena: TypeSpecArena | t.CPtr, - ret: llvmlite.LLVMType | t.CPtr, - params: llvmlite.ParamNode | t.CPtr, - pcount: int) -> TypeSpec | t.CPtr: - """函数类型 → TypeSpec(形参沿 ParamNode 链表遍历;IsVarArg 恒 0,见上)""" - ret_s: TypeSpec | t.CPtr = SpecFromLLVMType(arena, ret) - if ret_s is None: - return None - if pcount <= 0: - no_params: sizet | t.CPtr = None - return NewTypeFunc(arena, ret_s, no_params, 0, 0) - params_arr: sizet | t.CPtr = CompilerFactory.factory.PermPool.alloc(8 * pcount) - if params_arr is None: - return None - node: llvmlite.ParamNode | t.CPtr = params - i: int = 0 - while node is not None and i < pcount: - pty: llvmlite.LLVMType | t.CPtr = llvmlite.paramnode_get_ty(node) - ps: TypeSpec | t.CPtr = SpecFromLLVMType(arena, pty) - if ps is None: - return None - slot: sizet | t.CPtr = (sizet | t.CPtr)( - t.CVoid(uint64(params_arr) + uint64(i * 8), t.CPtr)) - if slot is None: - return None - slot[0] = sizet(ps) - node = llvmlite.paramnode_get_next(node) - i += 1 - return NewTypeFunc(arena, ret_s, params_arr, pcount, 0) - - -def _spec_from_struct(arena: TypeSpecArena | t.CPtr, - sname: str) -> TypeSpec | t.CPtr: - """有名结构体 → TS_STRUCT + BaseName;匿名结构体 → 无名 TS_STRUCT""" - if sname is not None: - return NewTypeStruct(arena, TS_STRUCT, sname) - return NewTypeSpec(arena, TS_STRUCT, 0, TS_SIGN_UNKNOWN) - - -# ============================================================ -# SpecSelfCheck - S1 自检(不参与编译流程,供手动调用/后续单测) -# -# 构造若干类型 → 编码 → 解码 → 再编码,比较两次文本是否一致(往返一致)。 -# 返回 0=全部通过;否则返回失败用例编号(从 1 起) -# ============================================================ -def SpecSelfCheck() -> int: - """TypeSpec 编解码自检,返回 0=通过 / 失败用例号""" - arena: TypeSpecArena | t.CPtr = (TypeSpecArena | t.CPtr)( - t.CVoid(CompilerFactory.factory.PermPool.alloc(TypeSpecArena.__sizeof__()), t.CPtr)) - if arena is None: - return 1 - string.memset(arena, 0, TypeSpecArena.__sizeof__()) - if SpecArenaInit(arena, 64) != 0: - return 1 - - # 1) u64 - s_u64: TypeSpec | t.CPtr = NewTypeSpec(arena, TS_UINT, 64, TS_SIGN_UNSIGNED) - if s_u64 is None: - return 1 - if _check_roundtrip(s_u64, "u64") != 0: - return 1 - - # 2) i32 - s_i32: TypeSpec | t.CPtr = NewTypeSpec(arena, TS_INT, 32, TS_SIGN_SIGNED) - if s_i32 is None: - return 2 - if _check_roundtrip(s_i32, "i32") != 0: - return 2 - - # 3) u64* - s_p: TypeSpec | t.CPtr = NewTypePtr(arena, s_u64) - if s_p is None: - return 3 - if _check_roundtrip(s_p, "p:u64") != 0: - return 3 - - # 4) i8[4] - s_arr: TypeSpec | t.CPtr = NewTypeArray(arena, s_i32, 4) - if s_arr is None: - return 4 - if _check_roundtrip(s_arr, "arr[4]:i32") != 0: - return 4 - - # 5) fn(i32,u64)->i32(变参) - params: sizet | t.CPtr = CompilerFactory.factory.PermPool.alloc(8 * 2) - if params is None: - return 5 - slot0: sizet | t.CPtr = (sizet | t.CPtr)(t.CVoid(uint64(params), t.CPtr)) - if slot0 is None: - return 5 - slot0[0] = sizet(s_i32) - slot1: sizet | t.CPtr = (sizet | t.CPtr)(t.CVoid(uint64(params) + 8, t.CPtr)) - if slot1 is None: - return 5 - slot1[0] = sizet(s_u64) - s_fn: TypeSpec | t.CPtr = NewTypeFunc(arena, s_i32, params, 2, 1) - if s_fn is None: - return 5 - if _check_roundtrip(s_fn, "fn(i32,u64,...)->i32") != 0: - return 5 - - # 6) 驻留去重:同一文本第二次应返回同一实例 - s_u64_again: TypeSpec | t.CPtr = NewTypeSpec(arena, TS_UINT, 64, TS_SIGN_UNSIGNED) - if s_u64_again is None: - return 6 - if t.CUInt64T(s_u64_again) != t.CUInt64T(s_u64): - return 6 - return 0 - - -# ============================================================ -# _check_roundtrip - 自检辅助:编码应等于 expect,且解码再编码应一致 -# ============================================================ -def _check_roundtrip(sp: TypeSpec | t.CPtr, expect: str) -> int: - """编码比对 + 解码往返一致;返回 0=通过 / 1=失败""" - if sp is None or expect is None: - return 1 - buf1: str = CompilerFactory.factory.PermPool.alloc(SPEC_TEXT_MAX) - if buf1 is None: - return 1 - if SpecToText(sp, buf1, SPEC_TEXT_MAX) != 0: - return 1 - if string.strcmp(buf1, expect) != 0: - return 1 - back: TypeSpec | t.CPtr = TextToSpec(buf1) - if back is None: - return 1 - buf2: str = CompilerFactory.factory.PermPool.alloc(SPEC_TEXT_MAX) - if buf2 is None: - return 1 - if SpecToText(back, buf2, SPEC_TEXT_MAX) != 0: - return 1 - if string.strcmp(buf2, expect) != 0: - return 1 - return 0 +import t, c +from stdint import * +import llvmlite +import memhub +import string +import viperlib +import lib.core.CompilerFactory as CompilerFactory +import lib.core.Gen.GenApi as GenApi + + +# ============================================================ +# TypeSpec - 统一类型描述符(对齐 TPC lib/core/TypeSpec.py,去 Python 化) +# +# 背景(见 Debugger/_Type.md 第 6 节设计): +# TPV 原有类型信息散落在「字符串 + 零散布尔」里 —— VarEntry.AnnotClassName / +# FieldEntry.AnnotClassName(注解类名串当影子类型系统,S4 已删除并并入本结构 +# 的 SourceName 字段)、VarEntry.IsPtrElement(单一布尔,只覆盖一种 8 字节 +# 步长情形,S4 已删除并并入本结构的 ElemBits 元素语义三元组)、 +# FuncEntry.TypeStr(函数类型存文本,S4 已改由本结构的 SpecToLLVMText 从 +# Spec 派生),而 llvmlite.LLVMType 只保留解析结果、已抹平指针层级/数组 +# 维度/原始注解。 +# 结果是「是否无符号/指针几层/数组几维/函数签名」到处重复解析字符串 +# (同一值被末段类名/完整限定名/精确名/mangled 前缀/截断串五种语义解释)。 +# +# 阶段:S1 只提供结构与构造/序列化;S2 各解析处「双写」;S3 逐块切读; +# S4 删旧字符串路径 —— FuncEntry.TypeStr、VarEntry/FieldEntry.AnnotClassName、 +# VarEntry.IsPtrElement 均已删除,仅「容器种类判断」(list/dict/CPtr 的 +# 字符串子串判定)待后续。 +# +# 生命周期(设计 D1):实例与内部数组一律 `CompilerFactory.factory.PermPool` +# 分配(契约见 CompilerFactory.vp:跨 mark 持久、从不 reset),故跨文件/跨模块 +# 可直接传指针,无需序列化。代价是 PermPool 只增不减 ⇒ 由 InternSpec 驻留去重。 +# +# 不用全局表:驻留表挂在 TypeSpecArena 实例上,由调用方(S2 起为 Generator) +# 持有并传入,避免模块级可变态。 +# ============================================================ + + +# ============================================================ +# Kind - 基础类型种类 +# ============================================================ +TS_UNKNOWN: t.CDefine = 0 +TS_INT: t.CDefine = 1 +TS_UINT: t.CDefine = 2 +TS_FLOAT: t.CDefine = 3 +TS_BOOL: t.CDefine = 4 +TS_PTR: t.CDefine = 5 +TS_ARRAY: t.CDefine = 6 +TS_STRUCT: t.CDefine = 7 +TS_VOID: t.CDefine = 8 +TS_FUNC: t.CDefine = 9 +TS_UNION: t.CDefine = 10 +TS_ENUM: t.CDefine = 11 + +# ============================================================ +# IsSigned - 符号性(单一真源,替代 _annot_str_unsigned 的子串扫描) +# ============================================================ +TS_SIGN_UNKNOWN: t.CDefine = -1 +TS_SIGN_UNSIGNED: t.CDefine = 0 +TS_SIGN_SIGNED: t.CDefine = 1 + +# 驻留表默认容量与单条类型文本上限(超限 fail-fast,绝不静默丢弃/截断) +# 容量 × 文本上限即驻留表键缓冲的 PermPool 占用(8192 × 256 = 2MB) +# 注:键文本超 SPEC_TEXT_MAX 的长签名/深嵌套类型 ⇒ 不驻留(保留完整实例, +# 仅放弃去重),见 InternSpec —— 截断键会让 strcmp 撞类型、返回错误实例。 +SPEC_INTERN_MAX: t.CDefine = 8192 +SPEC_TEXT_MAX: t.CDefine = 256 + + +# ============================================================ +# 符号性精确名表 - 按「名字切片」判定(**不做子串扫描**) +# +# 为什么必须精确匹配:旧实现 `_annot_str_unsigned` 用 strstr 子串扫描, +# 已确认两类误判(Debugger/_Type.md A4/A5): +# - `BYTEPTR`(本质 i8* 指针)含子串 `BYTE` → 被判为无符号整数; +# - 任何含 `uint32` 子串的名字(含 sha1 前缀名)都会命中。 +# +# 覆盖范围界定:本模块**只认 t/c 核心原语名与少数内建名**;stdint 的别名 +# (DWORD/WORD/QWORD/size_t/uint32_t/u32/…)由调用方沿 CTypedef 链**逐层展开** +# 后再落到本函数(链展开需要 CTypedef 表,不在本模块做,避免反向依赖)。 +# +# 规范性修正(相对旧表): +# - `SSizeT` 是**有符号**(旧 `_type_name_unsigned` 把它列为无符号,为 A3 缺陷); +# - `BOOL` 按 stdint.vp 定义是 `int`(**有符号**),并非布尔无符号; +# - 指针名(`BYTEPTR/UINTPTR/INTPTR/CHARPTR/…`)在此返回 UNKNOWN —— +# 指针的"无符号"语义由 PtrLevel 表达,与整数符号性无关。 +# ============================================================ + + +# ============================================================ +# _spec_name_eq - 比较 text[start:end] 与字面量 lit 是否逐字符相等(零分配) +# ============================================================ +def _spec_name_eq(text: str, start: sizet, end: sizet, lit: str) -> int: + """切片名比较:长度相同且逐字符相等返回 1,否则 0""" + if text is None or lit is None: + return 0 + if end <= start: + return 0 + ln: sizet = string.strlen(lit) + if end - start != ln: + return 0 + k: sizet = 0 + while k < ln: + if text[start + k] != lit[k]: + return 0 + k += 1 + return 1 + + +# ============================================================ +# SpecTypeNameBaseIs - 类型名的「容器基名」是否精确等于 base(零分配) +# +# 基名 = 先截断第一个 '[' 起的泛型实参,再取**最后一个 '.' 之后**的部分 +# (去模块名 / LLVM 注册名的模块 sha1 前缀)。例: +# "e94ef9e139461915.list[ast.ASTptr]" → "list" +# "list[ast.AST | t.CPtr]" → "list" +# "memhub.MemBuddy" → "MemBuddy"(≠ list/dict) +# +# 用途:替换容器种类判断里的 strstr 子串匹配(Debugger/_Type.md D20)—— +# `strstr("dict")` 会误命中 `MyDictHelper`,`strstr("list")` 会误命中 `playlist`。 +# 返回 1=是 / 0=否(含名字为空、无法提取基名的情形)。 +# ============================================================ +def SpecTypeNameBaseIs(name: str, base: str) -> int: + """类型名的容器基名是否精确等于 base(1=是 / 0=否)""" + if name is None or base is None: + return 0 + n: sizet = string.strlen(name) + if n == 0: + return 0 + # 基名上界:第一个 '['(泛型实参起点;无 '[' 则到串尾) + end: sizet = n + lb: str = string.strchr(name, '[') + if lb is not None: + end = sizet(uint64(lb) - uint64(name)) + # 基名下界:上界之前最后一个 '.' 之后(去模块名 / 模块 sha1 前缀) + start: sizet = 0 + dot: str = string.strchr(name, '.') + while dot is not None: + off: sizet = sizet(uint64(dot) - uint64(name)) + if off >= end: + break + start = off + 1 + dot = string.strchr(dot + 1, '.') + return _spec_name_eq(name, start, end, base) + + +# ============================================================ +# SpecSignFromTypeNameSpan - 按名字切片精确判定符号性(零分配) +# 返回 TS_SIGN_UNSIGNED / TS_SIGN_SIGNED / TS_SIGN_UNKNOWN(不表态) +# ============================================================ +def SpecSignFromTypeNameSpan(text: str, start: sizet, end: sizet) -> int: + """按 text[start:end] 精确判定符号性,未覆盖返回 TS_SIGN_UNKNOWN""" + if text is None: + return TS_SIGN_UNKNOWN + # --- t/c 核心无符号原语 --- + if _spec_name_eq(text, start, end, "CUInt8T") != 0: + return TS_SIGN_UNSIGNED + if _spec_name_eq(text, start, end, "CUInt16T") != 0: + return TS_SIGN_UNSIGNED + if _spec_name_eq(text, start, end, "CUInt32T") != 0: + return TS_SIGN_UNSIGNED + if _spec_name_eq(text, start, end, "CUInt64T") != 0: + return TS_SIGN_UNSIGNED + if _spec_name_eq(text, start, end, "CUnsignedChar") != 0: + return TS_SIGN_UNSIGNED + if _spec_name_eq(text, start, end, "CUnsignedShort") != 0: + return TS_SIGN_UNSIGNED + if _spec_name_eq(text, start, end, "CUnsignedInt") != 0: + return TS_SIGN_UNSIGNED + if _spec_name_eq(text, start, end, "CUnsignedLong") != 0: + return TS_SIGN_UNSIGNED + if _spec_name_eq(text, start, end, "CUnsignedLongLong") != 0: + return TS_SIGN_UNSIGNED + if _spec_name_eq(text, start, end, "CSizeT") != 0: + return TS_SIGN_UNSIGNED + if _spec_name_eq(text, start, end, "CUIntPtrT") != 0: + return TS_SIGN_UNSIGNED + if _spec_name_eq(text, start, end, "CBool") != 0: + return TS_SIGN_UNSIGNED + # --- 内建小写标量 --- + if _spec_name_eq(text, start, end, "bool") != 0: + return TS_SIGN_UNSIGNED + # --- t/c 核心有符号原语 --- + if _spec_name_eq(text, start, end, "CInt8T") != 0: + return TS_SIGN_SIGNED + if _spec_name_eq(text, start, end, "CInt16T") != 0: + return TS_SIGN_SIGNED + if _spec_name_eq(text, start, end, "CInt32T") != 0: + return TS_SIGN_SIGNED + if _spec_name_eq(text, start, end, "CInt64T") != 0: + return TS_SIGN_SIGNED + if _spec_name_eq(text, start, end, "CSignedChar") != 0: + return TS_SIGN_SIGNED + if _spec_name_eq(text, start, end, "CShort") != 0: + return TS_SIGN_SIGNED + if _spec_name_eq(text, start, end, "CInt") != 0: + return TS_SIGN_SIGNED + if _spec_name_eq(text, start, end, "CLong") != 0: + return TS_SIGN_SIGNED + if _spec_name_eq(text, start, end, "CLongLong") != 0: + return TS_SIGN_SIGNED + if _spec_name_eq(text, start, end, "CPtrDiffT") != 0: + return TS_SIGN_SIGNED + if _spec_name_eq(text, start, end, "CChar") != 0: + return TS_SIGN_SIGNED + if _spec_name_eq(text, start, end, "int") != 0: + return TS_SIGN_SIGNED + if _spec_name_eq(text, start, end, "char") != 0: + return TS_SIGN_SIGNED + return TS_SIGN_UNKNOWN + + +# ============================================================ +# SpecSignFromTypeName - 类型名(NUL 终止串)精确判定符号性 +# ============================================================ +def SpecSignFromTypeName(name: str) -> int: + """按类型名精确判定符号性,未覆盖返回 TS_SIGN_UNKNOWN""" + if name is None: + return TS_SIGN_UNKNOWN + return SpecSignFromTypeNameSpan(name, 0, string.strlen(name)) + + +# ============================================================ +# TypeSpec - 类型描述符 +# +# 元素语义三字段说明(ElemBits/IsElemPtr/DerefBase): +# 它们替代旧的 VarEntry.IsPtrElement 单一布尔。原因(_Type.md D7-4): +# `str | t.CPtr`、`bytes | t.CPtr`、泛型 `T | t.CPtr`、`64 位标量 | t.CPtr` +# 退化后的 LLVM 类型**都是单层 Ptr(i8)**,即 PtrLevel=1 同时对应两种相反语义, +# 仅靠指针层级无法区分;区分靠的是注解内容 ⇒ 需要「元素宽度 + 元素是否指针 + +# 基址是否需二次解引用」三元组。 +# ============================================================ +@t.NoVTable +class TypeSpec: + """统一类型描述符(字段语义见上)""" + Kind: int # TS_* 之一 + Bits: int # 位宽;非整型/浮点为 0 + IsSigned: int # TS_SIGN_* (-1 未知 / 0 无符号 / 1 有符号) + PtrLevel: int # 指针层级(0=非指针) + Elem: TypeSpec | t.CPtr # Ptr/Array 的指向或元素(None=无) + ArrayCount: int # Array 的元素个数(0=未知/动态) + BaseName: str # 结构体/枚举/类名(带模块 sha1;PermPool 深拷贝) + # SourceName: 注解侧「来源名」(等价旧 VarEntry/FieldEntry.AnnotClassName)。 + # + # 与 BaseName 的**本质区别**是命名域不同: + # BaseName = LLVM 结构体注册名(跨模块/特化时形如 {16hex sha1}.Class 或 + # list[f467978339422f32.AST|t.CPtr]),由 SpecFromLLVMType 反推; + # SourceName = 注解**书写形态**的名字(裸名 MemBuddy / 模块限定名 + # memhub.MemBuddy / t.XXX 裸 attr 名 uint32 / Subscript mangled 名), + # 由注解侧 SpecWithSource 填写。 + # + # 为何需要它:`X | t.CPtr` 联合被简化为 Ptr(i8) 后,BaseName 恒为 None(Spec 从 + # LLVM 反推,类名已丢),而属性访问/方法分派/结构体查找仍要靠注解侧名字恢复。 + # + # **不参与驻留键**:注解名种类远多于类型种类(每个泛型 mangled 名/别名各一份), + # 若入键会让 InternSpec 条目暴增且线性查找变慢;且驻留本意只是跨 reset 存活, + # 而 PermPool 分配天然满足。故 SpecWithSource 返回**独立副本、不进表**。 + SourceName: str + Ret: TypeSpec | t.CPtr # Func:返回类型 + Params: sizet | t.CPtr # Func:参数数组(连续 TypeSpec* 指针,ParamCount 个) + ParamCount: int # Func:参数个数 + IsVarArg: int # Func:1=变参(...) + Storage: int # 限定宏位标志(0=无) + ElemBits: int # 元素槽位宽(元素语义三元组 1/3) + IsElemPtr: int # 元素是否为指针(1=是)(2/3) + DerefBase: int # 基址是否需二次解引用(1=是)(3/3) + Ty: llvmlite.LLVMType | t.CPtr # 解析结果缓存(可空) + + +# ============================================================ +# TypeSpecArena - 驻留表(对象持有,非全局表) +# +# Keys :cap * SPEC_TEXT_MAX 的连续文本缓冲,第 i 条键位于 Keys + i*SPEC_TEXT_MAX +# Specs :cap 个 TypeSpec 指针 +# Count :已驻留条数;Cap:容量 +# ============================================================ +@t.NoVTable +class TypeSpecArena: + """TypeSpec 驻留表(按规范文本键去重,同型只存一份)""" + Keys: bytes + Specs: sizet | t.CPtr + Count: int + Cap: int + + +# ============================================================ +# _spec_key_at - 取第 i 个键的 str 指针(键缓冲内偏移 i * SPEC_TEXT_MAX) +# ============================================================ +def _spec_key_at(keys: bytes, index: int) -> str: + """返回第 index 条键的 str 指针(指向 keys 缓冲内部,不可 free)""" + if keys is None or index < 0: + return None + addr: uint64 = uint64(keys) + uint64(index * SPEC_TEXT_MAX) + return (str | t.CPtr)(t.CVoid(addr, t.CPtr)) + + +# ============================================================ +# SpecArenaInit - 初始化驻留表(幂等;cap<=0 时用 SPEC_INTERN_MAX) +# 返回 0=成功 / 1=失败(分配失败 fail-fast 由调用方处理,此处返回错误码) +# ============================================================ +def SpecArenaInit(arena: TypeSpecArena | t.CPtr, cap: int) -> int: + """初始化驻留表;已初始化则直接返回 0""" + if arena is None: + return 1 + if arena.Keys is not None: + return 0 + use_cap: int = cap + if use_cap <= 0: + use_cap = SPEC_INTERN_MAX + pp: rowptr[memhub.MemBuddy] = CompilerFactory.factory.PermPool + keys: bytes = pp.alloc(use_cap * SPEC_TEXT_MAX) + if keys is None: + return 1 + specs: sizet | t.CPtr = pp.alloc(use_cap * 8) + if specs is None: + return 1 + string.memset(keys, 0, use_cap * SPEC_TEXT_MAX) + string.memset(specs, 0, use_cap * 8) + arena.Keys = keys + arena.Specs = specs + arena.Count = 0 + arena.Cap = use_cap + return 0 + + +# ============================================================ +# _spec_alloc - 从 PermPool 分配一个清零的 TypeSpec(不驻留,内部用) +# ============================================================ +def _spec_alloc() -> TypeSpec | t.CPtr: + """分配并清零一个 TypeSpec(PermPool)""" + pp: rowptr[memhub.MemBuddy] = CompilerFactory.factory.PermPool + size: sizet = TypeSpec.__sizeof__() + sp: TypeSpec | t.CPtr = (TypeSpec | t.CPtr)(t.CVoid(pp.alloc(size), t.CPtr)) + if sp is None: + return None + string.memset(sp, 0, size) + sp.Kind = TS_UNKNOWN + sp.Bits = 0 + sp.IsSigned = TS_SIGN_UNKNOWN + sp.PtrLevel = 0 + sp.IsVarArg = 0 + sp.Storage = 0 + return sp + + +# ============================================================ +# _spec_make - 构造一个基础 TypeSpec(不驻留) +# ============================================================ +def _spec_make(kind: int, bits: int, is_signed: int) -> TypeSpec | t.CPtr: + """构造基础 TypeSpec(PermPool,不驻留)""" + sp: TypeSpec | t.CPtr = _spec_alloc() + if sp is None: + return None + sp.Kind = kind + sp.Bits = bits + sp.IsSigned = is_signed + return sp + + +# ============================================================ +# _spec_set_struct_name - 深拷贝类名到 PermPool(跨文件存活) +# ============================================================ +def _spec_set_struct_name(sp: TypeSpec | t.CPtr, name: str) -> int: + """把类名深拷贝到 PermPool 并写入 BaseName,返回 0=成功 / 1=失败""" + if sp is None or name is None: + return 1 + n: sizet = string.strlen(name) + if n <= 0: + return 1 + buf: str = CompilerFactory.factory.PermPool.alloc(n + 1) + if buf is None: + return 1 + string.strcpy(buf, name) + sp.BaseName = buf + return 0 + + +# ============================================================ +# NewTypeSpec - 构造基础类型(驻留) +# ============================================================ +def NewTypeSpec(arena: TypeSpecArena | t.CPtr, kind: int, + bits: int, is_signed: int) -> TypeSpec | t.CPtr: + """构造基础 TypeSpec 并驻留,失败返回 None""" + sp: TypeSpec | t.CPtr = _spec_make(kind, bits, is_signed) + if sp is None: + return None + return InternSpec(arena, sp) + + +# ============================================================ +# NewTypeStruct - 构造结构体/枚举/类类型(驻留) +# ============================================================ +def NewTypeStruct(arena: TypeSpecArena | t.CPtr, kind: int, + base_name: str) -> TypeSpec | t.CPtr: + """构造 struct/union/enum 类型(BaseName 深拷贝 + 驻留),失败返回 None""" + sp: TypeSpec | t.CPtr = _spec_make(kind, 0, TS_SIGN_UNKNOWN) + if sp is None: + return None + if _spec_set_struct_name(sp, base_name) != 0: + return None + return InternSpec(arena, sp) + + +# ============================================================ +# NewTypePtr - 构造指针类型(PtrLevel = 元素 PtrLevel + 1,驻留) +# ============================================================ +def NewTypePtr(arena: TypeSpecArena | t.CPtr, + elem: TypeSpec | t.CPtr) -> TypeSpec | t.CPtr: + """构造指针类型:指向 elem(PtrLevel 逐层递增),失败返回 None""" + if elem is None: + return None + sp: TypeSpec | t.CPtr = _spec_make(TS_PTR, 0, TS_SIGN_UNKNOWN) + if sp is None: + return None + sp.Elem = elem + sp.PtrLevel = elem.PtrLevel + 1 + sp.ElemBits = elem.Bits + sp.IsElemPtr = 0 + if elem.Kind == TS_PTR: + sp.IsElemPtr = 1 + return InternSpec(arena, sp) + + +# ============================================================ +# NewTypeArray - 构造数组类型(ArrayCount 个 elem,驻留) +# ============================================================ +def NewTypeArray(arena: TypeSpecArena | t.CPtr, elem: TypeSpec | t.CPtr, + count: int) -> TypeSpec | t.CPtr: + """构造数组类型:elem[count](count<=0 表示长度未知/动态),失败返回 None""" + if elem is None or count < 0: + return None + sp: TypeSpec | t.CPtr = _spec_make(TS_ARRAY, 0, TS_SIGN_UNKNOWN) + if sp is None: + return None + sp.Elem = elem + sp.ArrayCount = count + sp.ElemBits = elem.Bits + sp.IsElemPtr = 0 + if elem.Kind == TS_PTR: + sp.IsElemPtr = 1 + return InternSpec(arena, sp) + + +# ============================================================ +# NewTypeFunc - 构造函数签名类型(ret + 参数数组 + 变参,驻留) +# params:TypeSpec* 连续数组(由调用方预先构造并保证存活);count 个 +# ============================================================ +def NewTypeFunc(arena: TypeSpecArena | t.CPtr, ret: TypeSpec | t.CPtr, + params: sizet | t.CPtr, count: int, + is_vararg: int) -> TypeSpec | t.CPtr: + """构造函数签名类型,失败返回 None""" + if ret is None or count < 0: + return None + if count > 0 and params is None: + return None + sp: TypeSpec | t.CPtr = _spec_make(TS_FUNC, 0, TS_SIGN_UNKNOWN) + if sp is None: + return None + sp.Ret = ret + sp.Params = params + sp.ParamCount = count + sp.IsVarArg = is_vararg + return InternSpec(arena, sp) + + +# ============================================================ +# SpecBaseText - 基础类型(非 Ptr/Array/Func)的规范文本 +# 返回 0=已写入 / 1=不适用/失败 +# ============================================================ +def SpecBaseText(sp: TypeSpec | t.CPtr, buf: str, buf_size: sizet) -> int: + """把基础类型写成规范文本;Ptr/Array/Func 不适用时返回 1""" + if sp is None or buf is None or buf_size == 0: + return 1 + if sp.Kind == TS_INT: + viperlib.snprintf(buf, buf_size, "i%d", sp.Bits) + return 0 + if sp.Kind == TS_UINT: + viperlib.snprintf(buf, buf_size, "u%d", sp.Bits) + return 0 + if sp.Kind == TS_FLOAT: + viperlib.snprintf(buf, buf_size, "f%d", sp.Bits) + return 0 + if sp.Kind == TS_BOOL: + viperlib.snprintf(buf, buf_size, "bool") + return 0 + if sp.Kind == TS_STRUCT: + # 名字键可能很长(sha1 + 泛型实参),先算所需长度,装不下即失败(不截断) + if sp.BaseName is None or 3 + string.strlen(sp.BaseName) + 1 > buf_size: + return 1 + viperlib.snprintf(buf, buf_size, "st:%s", sp.BaseName) + return 0 + if sp.Kind == TS_UNION: + if sp.BaseName is None or 3 + string.strlen(sp.BaseName) + 1 > buf_size: + return 1 + viperlib.snprintf(buf, buf_size, "un:%s", sp.BaseName) + return 0 + if sp.Kind == TS_ENUM: + if sp.BaseName is None or 3 + string.strlen(sp.BaseName) + 1 > buf_size: + return 1 + viperlib.snprintf(buf, buf_size, "en:%s", sp.BaseName) + return 0 + if sp.Kind == TS_VOID: + viperlib.snprintf(buf, buf_size, "void") + return 0 + return 1 + + +# ============================================================ +# SpecToText - 规范文本编码(驻留键 / 日志 / vpi·stub 通道) +# +# 格式草案: +# i32 / u64 / f64 / bool / void +# st:{sha1}.Class 结构体(BaseName 原样);un: / en: 同构,分别表示联合/枚举 +# p:INNER 指针(每层一个 "p:" 前缀,层数即 PtrLevel) +# arr[N]:INNER 数组(N=0 表示长度未知) +# fn(INNER,INNER,...)->RET 函数签名(变参追加 "...") +# 递归深度上限 32(防环);超限或缓冲不足返回 1(fail-fast 由调用方决定) +# ============================================================ +def SpecToText(sp: TypeSpec | t.CPtr, buf: str, buf_size: sizet) -> int: + """把 TypeSpec 编码为规范文本,返回 0=成功 / 1=失败""" + return _spec_to_text(sp, buf, buf_size, 0) + + +def _spec_to_text(sp: TypeSpec | t.CPtr, buf: str, buf_size: sizet, + depth: int) -> int: + """SpecToText 的递归实现(depth 上限 32)""" + if sp is None or buf is None or buf_size == 0 or depth > 32: + return 1 + buf[0] = '\0' + if sp.Kind == TS_PTR: + # p: + 内层 + inner_buf: str = CompilerFactory.factory.PermPool.alloc(SPEC_TEXT_MAX) + if inner_buf is None: + return 1 + if _spec_to_text(sp.Elem, inner_buf, SPEC_TEXT_MAX, depth + 1) != 0: + return 1 + pos_p: sizet = _spec_text_append(buf, buf_size, 0, "p:") + if pos_p >= buf_size: + return 1 + pos_p = _spec_text_append(buf, buf_size, pos_p, inner_buf) + if pos_p >= buf_size: + return 1 + return 0 + if sp.Kind == TS_ARRAY: + # arr[N]: + 内层 + inner_buf_a: str = CompilerFactory.factory.PermPool.alloc(SPEC_TEXT_MAX) + if inner_buf_a is None: + return 1 + if _spec_to_text(sp.Elem, inner_buf_a, SPEC_TEXT_MAX, depth + 1) != 0: + return 1 + prefix_a: str = CompilerFactory.factory.PermPool.alloc(64) + if prefix_a is None: + return 1 + viperlib.snprintf(prefix_a, 64, "arr[%d]:", sp.ArrayCount) + pos_a: sizet = _spec_text_append(buf, buf_size, 0, prefix_a) + if pos_a >= buf_size: + return 1 + pos_a = _spec_text_append(buf, buf_size, pos_a, inner_buf_a) + if pos_a >= buf_size: + return 1 + return 0 + if sp.Kind == TS_FUNC: + # fn(p1,p2,...)->ret(每次追加都检查溢出哨兵,绝不静默截断键) + pos: sizet = 0 + pos = _spec_text_append(buf, buf_size, pos, "fn(") + if pos >= buf_size: + return 1 + i: int = 0 + while i < sp.ParamCount: + if i > 0: + pos = _spec_text_append(buf, buf_size, pos, ",") + if pos >= buf_size: + return 1 + param: TypeSpec | t.CPtr = _spec_param_at(sp, i) + if param is None: + return 1 + param_buf: str = CompilerFactory.factory.PermPool.alloc(SPEC_TEXT_MAX) + if param_buf is None: + return 1 + if _spec_to_text(param, param_buf, SPEC_TEXT_MAX, depth + 1) != 0: + return 1 + pos = _spec_text_append(buf, buf_size, pos, param_buf) + if pos >= buf_size: + return 1 + i += 1 + if sp.IsVarArg == 1: + if sp.ParamCount > 0: + pos = _spec_text_append(buf, buf_size, pos, ",...") + else: + pos = _spec_text_append(buf, buf_size, pos, "...") + if pos >= buf_size: + return 1 + pos = _spec_text_append(buf, buf_size, pos, ")->") + if pos >= buf_size: + return 1 + ret_buf: str = CompilerFactory.factory.PermPool.alloc(SPEC_TEXT_MAX) + if ret_buf is None: + return 1 + if _spec_to_text(sp.Ret, ret_buf, SPEC_TEXT_MAX, depth + 1) != 0: + return 1 + pos = _spec_text_append(buf, buf_size, pos, ret_buf) + if pos >= buf_size: + return 1 + return 0 + # 基础类型 + return SpecBaseText(sp, buf, buf_size) + + +# ============================================================ +# _spec_text_append - 有界尾部追加(返回新的写入位置) +# +# **溢出哨兵**:返回 `buf_size` 表示"装不下"(合法位置恒 < buf_size)。 +# 调用方**必须**据此返回失败 —— 绝不静默截断:驻留键被截断会让后续 +# strcmp 撞上别的类型,从而返回**错误的 Spec 实例**(2026-09-11 实测: +# 长函数签名键被截断 ⇒ 某函数拿到别的函数的签名 Spec,格式化闸门报 ret 不符)。 +# ============================================================ +def _spec_text_append(buf: str, buf_size: sizet, pos: sizet, text: str) -> sizet: + """把 text 追加到 buf 的 pos 处;装不下返回 buf_size(哨兵),否则返回新位置""" + if buf is None or text is None: + return buf_size + tlen: sizet = string.strlen(text) + i: sizet = 0 + while i < tlen: + if pos + 1 >= buf_size: + buf[pos] = '\0' + return buf_size + buf[pos] = text[i] + pos += 1 + i += 1 + buf[pos] = '\0' + return pos + + +# ============================================================ +# _spec_param_at - 取函数签名第 i 个参数 TypeSpec 指针 +# ============================================================ +def _spec_param_at(sp: TypeSpec | t.CPtr, index: int) -> TypeSpec | t.CPtr: + """返回 Func 类型第 index 个参数的 TypeSpec 指针,越界返回 None""" + if sp is None or sp.Params is None or index < 0 or index >= sp.ParamCount: + return None + addr: uint64 = uint64(sp.Params) + uint64(index * 8) + slot: sizet | t.CPtr = (sizet | t.CPtr)(t.CVoid(addr, t.CPtr)) + if slot is None: + return None + return (TypeSpec | t.CPtr)(t.CVoid(uint64(slot[0]), t.CPtr)) + + +# ============================================================ +# TextToSpec - 规范文本解码(SpecToText 的逆;不驻留,由调用方决定是否驻留) +# 解析失败返回 None(fail-fast 由调用方决定) +# ============================================================ +def TextToSpec(text: str) -> TypeSpec | t.CPtr: + """把规范文本解码为 TypeSpec(PermPool,不驻留),失败返回 None""" + if text is None: + return None + return _text_to_spec(text, 0) + + +def _text_to_spec(text: str, depth: int) -> TypeSpec | t.CPtr: + """TextToSpec 的递归实现(depth 上限 32)""" + if text is None or depth > 32: + return None + # 指针:p:INNER + if string.strncmp(text, "p:", 2) == 0: + inner: TypeSpec | t.CPtr = _text_to_spec(text + 2, depth + 1) + if inner is None: + return None + sp_p: TypeSpec | t.CPtr = _spec_make(TS_PTR, 0, TS_SIGN_UNKNOWN) + if sp_p is None: + return None + sp_p.Elem = inner + sp_p.PtrLevel = inner.PtrLevel + 1 + sp_p.ElemBits = inner.Bits + if inner.Kind == TS_PTR: + sp_p.IsElemPtr = 1 + return sp_p + # 数组:arr[N]:INNER + if string.strncmp(text, "arr[", 4) == 0: + rb: str = string.strchr(text, ']') + if rb is None: + return None + count: int = string.atoi(text + 4) + if count < 0: + return None + colon: str = string.strchr(rb, ':') + if colon is None: + return None + inner_a: TypeSpec | t.CPtr = _text_to_spec(colon + 1, depth + 1) + if inner_a is None: + return None + sp_a: TypeSpec | t.CPtr = _spec_make(TS_ARRAY, 0, TS_SIGN_UNKNOWN) + if sp_a is None: + return None + sp_a.Elem = inner_a + sp_a.ArrayCount = count + sp_a.ElemBits = inner_a.Bits + if inner_a.Kind == TS_PTR: + sp_a.IsElemPtr = 1 + return sp_a + # 函数:fn(...)->RET + if string.strncmp(text, "fn(", 3) == 0: + return _text_to_func(text, depth) + # 结构体/联合/枚举:st:NAME / un:NAME / en:NAME + if string.strncmp(text, "st:", 3) == 0: + return _spec_make_struct(TS_STRUCT, text + 3) + if string.strncmp(text, "un:", 3) == 0: + return _spec_make_struct(TS_UNION, text + 3) + if string.strncmp(text, "en:", 3) == 0: + return _spec_make_struct(TS_ENUM, text + 3) + if string.strcmp(text, "bool") == 0: + return _spec_make(TS_BOOL, 1, TS_SIGN_UNSIGNED) + if string.strcmp(text, "void") == 0: + return _spec_make(TS_VOID, 0, TS_SIGN_UNKNOWN) + # i32 / u64 / f64 + if text[0] == 'u' or text[0] == 'i' or text[0] == 'f': + bits: int = string.atoi(text + 1) + if bits <= 0: + return None + if text[0] == 'u': + return _spec_make(TS_UINT, bits, TS_SIGN_UNSIGNED) + if text[0] == 'i': + return _spec_make(TS_INT, bits, TS_SIGN_SIGNED) + return _spec_make(TS_FLOAT, bits, TS_SIGN_SIGNED) + return None + + +# ============================================================ +# _spec_make_struct - 构造 struct(深拷贝名字) +# ============================================================ +def _spec_make_struct(kind: int, name: str) -> TypeSpec | t.CPtr: + """构造 struct/union/enum 类型(不驻留),失败返回 None""" + if name is None or name[0] == '\0': + return None + sp: TypeSpec | t.CPtr = _spec_make(kind, 0, TS_SIGN_UNKNOWN) + if sp is None: + return None + if _spec_set_struct_name(sp, name) != 0: + return None + return sp + + +# ============================================================ +# _text_to_func - 解析 "fn(p1,p2,...)->RET" +# ============================================================ +def _text_to_func(text: str, depth: int) -> TypeSpec | t.CPtr: + """解析函数签名文本,失败返回 None""" + lp: str = string.strchr(text, '(') + if lp is None: + return None + arrow: str = string.strstr(text, ")->") + if arrow is None: + return None + # 参数段范围(lp+1 .. arrow-1) + params_buf: str = CompilerFactory.factory.PermPool.alloc(SPEC_TEXT_MAX) + if params_buf is None: + return None + params_buf[0] = '\0' + nlen: sizet = sizet(uint64(arrow) - uint64(lp)) - 1 + if nlen > 0: + string.strncpy(params_buf, lp + 1, nlen) + params_buf[nlen] = '\0' + is_vararg: int = 0 + if string.strstr(params_buf, "...") is not None: + is_vararg = 1 + # 逐段解析参数(按顶层 ',' 分割;变参段 "..." 跳过) + param_specs: sizet | t.CPtr = CompilerFactory.factory.PermPool.alloc(8 * 64) + if param_specs is None: + return None + pcount: int = 0 + if nlen > 0: + cur: str = params_buf + while cur is not None: + comma: str = string.strchr(cur, ',') + seg: str = cur + if comma is not None: + seg_make: str = CompilerFactory.factory.PermPool.alloc(SPEC_TEXT_MAX) + if seg_make is None: + return None + seg_len: sizet = sizet(uint64(comma) - uint64(cur)) + string.strncpy(seg_make, cur, seg_len) + seg_make[seg_len] = '\0' + seg = seg_make + cur = comma + 1 + else: + cur = None + if string.strcmp(seg, "...") == 0: + continue + if pcount >= 64: + return None + psp: TypeSpec | t.CPtr = _text_to_spec(seg, depth + 1) + if psp is None: + return None + slot_p: sizet | t.CPtr = (sizet | t.CPtr)( + t.CVoid(uint64(param_specs) + uint64(pcount * 8), t.CPtr)) + if slot_p is None: + return None + slot_p[0] = sizet(psp) + pcount += 1 + ret: TypeSpec | t.CPtr = _text_to_spec(arrow + 3, depth + 1) + if ret is None: + return None + sp_f: TypeSpec | t.CPtr = _spec_make(TS_FUNC, 0, TS_SIGN_UNKNOWN) + if sp_f is None: + return None + sp_f.Ret = ret + sp_f.Params = param_specs + sp_f.ParamCount = pcount + sp_f.IsVarArg = is_vararg + return sp_f + + +# ============================================================ +# InternSpec - 规范化驻留:同键只保留一份,返回驻留后的实例 +# 键 = SpecToText;**表容量**超限 → fatal_error(绝不返回 None:那会让调用方条目 +# 静默丢失类型信息);**键文本**装不下 SPEC_TEXT_MAX → 保留实例但放弃去重 +# (绝不写入截断键)。 +# ============================================================ +def InternSpec(arena: TypeSpecArena | t.CPtr, + sp: TypeSpec | t.CPtr) -> TypeSpec | t.CPtr: + """按规范文本键驻留 TypeSpec;失败返回 None""" + if arena is None or sp is None: + return sp + if SpecArenaInit(arena, 0) != 0: + return None + key_buf: str = CompilerFactory.factory.PermPool.alloc(SPEC_TEXT_MAX) + if key_buf is None: + return None + if SpecToText(sp, key_buf, SPEC_TEXT_MAX) != 0: + # 键装不下(长函数签名 / 深嵌套):**保留实例但放弃去重**。 + # 这不是语义兜底 —— sp 本身完整正确,只是失去"同型共享"这一优化; + # 关键在于**绝不能把截断键写入表**:截断键会让后续 strcmp 撞上别的类型 + # 并返回**错误实例**(2026-09-11 实测的格式化闸门误报根因)。 + return sp + # 线性查找已有键(规模与类型种数同阶,量级不大;命中即复用) + i: int = 0 + while i < arena.Count: + exist_key: str = _spec_key_at(arena.Keys, i) + if exist_key is not None and string.strcmp(exist_key, key_buf) == 0: + slot_e: sizet | t.CPtr = (sizet | t.CPtr)( + t.CVoid(uint64(arena.Specs) + uint64(i * 8), t.CPtr)) + if slot_e is None: + return None + return (TypeSpec | t.CPtr)(t.CVoid(uint64(slot_e[0]), t.CPtr)) + i += 1 + # 未命中:追加。**表满 = fail-fast**(Debugger/_Type.md D14 风险 2): + # 不能返回 None —— 调用链会把 None 一路传到 entry.Spec,条目**静默失去类型信息** + # (如 _entry_spec_unsigned 恒返回 0 ⇒ zext/sext 方向取错),属静默数据损坏, + # 与「不兜底 / fail-fast」原则直接冲突(原注释声称 fail-fast,实现却只返回 None)。 + if arena.Count >= arena.Cap: + GenApi.fatal_error( + None, + f"TypeSpec 驻留表已满(上限 {arena.Cap} 条),无法登记新类型", + "InternalCompilerError") + # 仅在 fatal_error 无 gen 通道(no-op)时可达:退化为「不驻留但返回完整实例」, + # 守住"不返回 None"这一底线 —— 宁失去同型共享,也不让条目静默丢类型。 + return sp + dst_key: str = _spec_key_at(arena.Keys, arena.Count) + if dst_key is None: + return None + string.strcpy(dst_key, key_buf) + slot_n: sizet | t.CPtr = (sizet | t.CPtr)( + t.CVoid(uint64(arena.Specs) + uint64(arena.Count * 8), t.CPtr)) + if slot_n is None: + return None + slot_n[0] = sizet(sp) + arena.Count += 1 + return sp + + +# ============================================================ +# 只读访问器(供 S3 起替换旧的字符串判定) +# ============================================================ +def SpecIsPtr(sp: TypeSpec | t.CPtr) -> int: + """是否指针类型(PtrLevel>0)""" + if sp is None: + return 0 + if sp.PtrLevel > 0: + return 1 + return 0 + + +def SpecPointedTo(sp: TypeSpec | t.CPtr) -> TypeSpec | t.CPtr: + """指针的指向类型(非指针返回 None)""" + if sp is None or sp.Kind != TS_PTR: + return None + return sp.Elem + + +# ============================================================ +# _spec_clone - 浅拷贝 TypeSpec(PermPool,**不驻留**) +# +# Elem/Ret/Params 指针共享子实例(子实例自身由 NewTypeXxx 驻留)。 +# 供 SpecWithSign / SpecWithSource / SpecWithElemBits 复用,避免多处重复 +# 逐字段拷贝(漏字段是最容易引入的隐蔽 bug:例如忘了 IsElemPtr)。 +# ============================================================ +def _spec_clone(sp: TypeSpec | t.CPtr) -> TypeSpec | t.CPtr: + """浅拷贝 sp(含全部字段),分配失败返回 None""" + if sp is None: + return None + cp: TypeSpec | t.CPtr = _spec_alloc() + if cp is None: + return None + cp.Kind = sp.Kind + cp.Bits = sp.Bits + cp.IsSigned = sp.IsSigned + cp.PtrLevel = sp.PtrLevel + cp.Elem = sp.Elem + cp.ArrayCount = sp.ArrayCount + cp.BaseName = sp.BaseName + cp.SourceName = sp.SourceName + cp.Ret = sp.Ret + cp.Params = sp.Params + cp.ParamCount = sp.ParamCount + cp.IsVarArg = sp.IsVarArg + cp.Storage = sp.Storage + cp.ElemBits = sp.ElemBits + cp.IsElemPtr = sp.IsElemPtr + cp.DerefBase = sp.DerefBase + cp.Ty = sp.Ty + return cp + + +# ============================================================ +# SpecWithSign - 复制 Spec 并按注解覆盖整数符号性(TS_INT ↔ TS_UINT) +# +# 背景(S4 注解侧填 Spec):SpecFromLLVMType 从 LLVM 类型反推时,整数恒 +# TS_INT(LLVM iN 不分符号)。但 SpecToText 对 TS_INT 编 "i%d"、TS_UINT 编 +# "u%d",符号性由 **Kind** 区分 —— 若只改 IsSigned 不改 Kind,两个符号性不同 +# 的整数会得到相同驻留键 "i%d" 而撞键(同键不同义,返回错误实例)。 +# 注解侧知道真实符号性(uint32 等无符号名),须把 TS_INT 切为 TS_UINT。 +# +# 仅当符号性实际变化才复制并驻留,否则返回原实例。驻留去重 ⇒ 同「结构+符号」共享一份。 +# ============================================================ +def SpecWithSign(arena: TypeSpecArena | t.CPtr, + sp: TypeSpec | t.CPtr, + is_signed: int) -> TypeSpec | t.CPtr: + """复制 sp 并覆盖整数符号性,驻留后返回;无变化返回原实例,失败返回 None""" + if sp is None: + return None + new_kind: int = sp.Kind + new_signed: int = sp.IsSigned + if is_signed == TS_SIGN_UNSIGNED and sp.Kind == TS_INT: + new_kind = TS_UINT + new_signed = TS_SIGN_UNSIGNED + elif is_signed == TS_SIGN_SIGNED and sp.Kind == TS_UINT: + new_kind = TS_INT + new_signed = TS_SIGN_SIGNED + if new_kind == sp.Kind: + return sp + cp: TypeSpec | t.CPtr = _spec_clone(sp) + if cp is None: + return None + cp.Kind = new_kind + cp.IsSigned = new_signed + # **清空 SourceName**:本函数走 InternSpec(键 = SpecToText,不含 SourceName), + # 若把带来源名的副本写进表,后续同键查找会把该来源名**污染**给无关条目 + # (键相同 ⇒ 语义必须相同 ⇒ 表内实例的 SourceName 恒为 None)。 + # 需要来源名时由调用方随后用 SpecWithSource(独立副本)叠加。 + cp.SourceName = None + return InternSpec(arena, cp) + + +# ============================================================ +# _spec_set_source_name - 深拷贝注解来源名到 PermPool 并写入 SourceName +# ============================================================ +def _spec_set_source_name(sp: TypeSpec | t.CPtr, name: str) -> int: + """把注解来源名深拷贝到 PermPool 并写入 SourceName,返回 0=成功 / 1=失败""" + if sp is None or name is None: + return 1 + n: sizet = string.strlen(name) + if n <= 0: + return 1 + buf: str = CompilerFactory.factory.PermPool.alloc(n + 1) + if buf is None: + return 1 + string.strcpy(buf, name) + sp.SourceName = buf + return 0 + + +# ============================================================ +# SpecWithSource - 复制 Spec 并附上注解侧来源名(独立副本,**不驻留**) +# +# 用途(S4 注解侧填 Spec 的「类名块」):`X | t.CPtr` 简化成 Ptr(i8) 后 Spec 里 +# 没有类名,而属性访问/方法分派/结构体查找要靠注解侧名字恢复,故在注解侧把 +# 来源名附到 Spec 上(SourceName),供消费点逐步切读(替代 AnnotClassName)。 +# +# 为何**不**走 InternSpec:SourceName 种类远多于类型种类(泛型 mangled 名、别名 +# 各一份),入键会让驻留条目暴增 + 线性查找变慢;而驻留只为跨 reset 存活, +# PermPool 分配天然满足。故返回独立副本(浅拷贝,Elem/Ret/Params 共享子实例)。 +# +# 幂等:sp.SourceName 已等于 name 时返回原实例(避免重复副本)。 +# ============================================================ +def SpecWithSource(sp: TypeSpec | t.CPtr, name: str) -> TypeSpec | t.CPtr: + """复制 sp 并设置 SourceName(独立副本,不驻留);name 为空返回原实例""" + if sp is None or name is None or name[0] == '\0': + return sp + if sp.SourceName is not None and string.strcmp(sp.SourceName, name) == 0: + return sp + cp: TypeSpec | t.CPtr = _spec_clone(sp) + if cp is None: + return sp + if _spec_set_source_name(cp, name) != 0: + return sp + return cp + + +# ============================================================ +# SpecWithElemBits - 复制 Spec 并覆盖元素槽位宽(独立副本,**不驻留**) +# +# 用途(S4 的 IsPtrElement 替代):`str | t.CPtr` / `bytes | t.CPtr` / +# `T | t.CPtr` / `64 位标量 | t.CPtr` 在 LLVM 层**都是单层 Ptr(i8)** +# (PtrLevel=1 同时对应两种相反语义),无法据类型区分"1 字节步长"与 +# "8 字节槽步长";区分只能靠注解判定 ⇒ 注解侧把元素槽宽覆盖为 8 字节。 +# +# ElemBits 是派生字段(**不在 SpecToText 键内**)⇒ 必须返回独立副本: +# 若走 InternSpec 会命中键相同但 ElemBits 未覆盖的实例,覆盖丢失。 +# ============================================================ +def SpecWithElemBits(sp: TypeSpec | t.CPtr, elem_bits: int) -> TypeSpec | t.CPtr: + """复制 sp 并设置 ElemBits(独立副本,不驻留);无变化返回原实例""" + if sp is None: + return sp + if sp.ElemBits == elem_bits: + return sp + cp: TypeSpec | t.CPtr = _spec_clone(sp) + if cp is None: + return sp + cp.ElemBits = elem_bits + return cp + + +def SpecSourceName(sp: TypeSpec | t.CPtr) -> str: + """Spec 的注解来源名(未设置返回 None)""" + if sp is None: + return None + return sp.SourceName + + +def SpecIsUnsigned(sp: TypeSpec | t.CPtr) -> int: + """是否无符号整数(单一真源;未知返回 0)""" + if sp is None: + return 0 + if sp.IsSigned == TS_SIGN_UNSIGNED: + return 1 + return 0 + + +def SpecBitWidth(sp: TypeSpec | t.CPtr) -> int: + """位宽(非整形/浮点返回 0)""" + if sp is None: + return 0 + return sp.Bits + + +# ============================================================ +# SpecTypePtrLevel - LLVM 类型 → 指针层级(**指针层级块的唯一实现**) +# +# S3 起由 ExprGenBase.get_ptr_level 委托调用(原实现是 Gen 层里的同码副本, +# 现收拢到本模块,成为该块切读 TypeSpec 的入口)。 +# 返回 0=非指针 / 1=一级指针 / 2=二级指针 / 3+… +# +# ⚠️ 规避自举 match codegen 缺陷(原 get_ptr_level 注释所记):`case` 体内 +# **直接更新外层 while 条件变量**会把赋值写进 subject 快照槽,while 条件读旧槽 +# ⇒ 死循环。故此处 `case` 只绑定局部 `nxt`,循环变量在 match **外**更新。 +# ============================================================ +def SpecTypePtrLevel(ty: llvmlite.LLVMType | t.CPtr) -> int: + """计算指针层级,0=非指针,1=一级指针,2=二级指针…""" + if ty is None: + return 0 + level: int = 0 + cur: llvmlite.LLVMType | t.CPtr = ty + while cur is not None: + nxt: llvmlite.LLVMType | t.CPtr = None + match cur: + case llvmlite.LLVMType.Ptr(pointee): + level += 1 + nxt = pointee + case _: + break + cur = nxt + return level + + +# ============================================================ +# SpecTypeBits - LLVM 类型 → 整数位宽(**位宽块的唯一实现**) +# +# S4 起由 ExprGenBase.get_llvm_type_bits 与 TypeGenErr.get_llvm_type_bits 委托调用 +# (原为两份同码副本:ExprGenBase.vp:104 + TypeGenErr.vp:253)。收拢理由与 +# SpecTypePtrLevel 相同:同为「LLVMType → 标量」的纯函数,属本模块职责域; +# 副本一旦分叉会出现「同一类型在两处算出不同位宽」的隐蔽不一致。 +# 非整数类型(指针/浮点/结构体等)返回 0 —— 0 是"非整数"的表态,不是兜底位宽。 +# ============================================================ +def SpecTypeBits(ty: llvmlite.LLVMType | t.CPtr) -> int: + """获取 LLVM 整数类型的位宽,非整数类型返回 0""" + if ty is None: + return 0 + match ty: + case llvmlite.LLVMType.Int(bits): + return bits + case _: + return 0 + + +# ============================================================ +# SpecToLLVMText - TypeSpec → LLVM IR 类型文本(**逐字节对齐 llvmlite.TypePrint**) +# +# 用途:作为 FuncEntry.Spec 的 LLVM 文本派生源(旧 FuncEntry.TypeStr 字符串生产者 +# 已在 S4 删除),推进去字符串化(Debugger/_Type.md D14 起)。 +# +# 对齐依据:`includes/llvmlite/__types.vp:395-511` 的 `_TypePrintDepth`,逐分支照搬: +# Int(bits) → "iN"(**无符号也是 iN** —— LLVM 文本层不分符号) +# Float(bits) → 16/32/64/128 → half/float/double/fp128;其它 → "float%x"(十六进制) +# Void → "void" +# Ptr(pointee)→ pointee 为 None/Void → "i8*";pointee 为**命名结构体** → `%""*` +# (特例,不递归);否则递归 pointee 后追加 '*' +# Array(e, N) → "[N x ELEM]" +# Struct/Union/Enum(name) → `%""`;**匿名结构体 → 显式返回失败** +# (Spec 未保留字段列表,无法还原 TypePrint 的 "{ty1, ty2}",不造伪文本) +# Func → "RET (P0, P1)";本实现**额外**按 Spec.IsVarArg 追加 ", ..." / "...", +# 以对齐 `FuncEntry.TypeStr` 的生产口径(TypePrint 的 LLVMType.Func +# **不含**变参信息,这一步是本 Spec 口径的补充而非照搬)。 +# +# 返回 0=已写入 / 1=不适用或失败(调用方显式处置,不静默兜底) +# ============================================================ +SPEC_LLVM_TEXT_MAX_DEPTH: t.CDefine = 100 + + +def SpecToLLVMText(sp: TypeSpec | t.CPtr, buf: str, buf_size: sizet) -> int: + """TypeSpec → LLVM IR 类型文本(对齐 TypePrint),返回 0=成功 / 1=失败""" + if sp is None or buf is None or buf_size == 0: + return 1 + buf[0] = '\0' + return _spec_llvm_text(sp, buf, buf_size, 0) + + +def _spec_llvm_append(buf: str, buf_size: sizet, src: str) -> int: + """把 src 追加到 buf 末尾(有界,不越写),返回 0=成功 / 1=容量不足""" + if buf is None or src is None: + return 1 + pos: sizet = string.strlen(buf) + n: sizet = string.strlen(src) + if pos + n + 1 > buf_size: + return 1 + string.strcpy(buf + pos, src) + return 0 + + +def _spec_llvm_text(sp: TypeSpec | t.CPtr, buf: str, buf_size: sizet, + depth: int) -> int: + """把 sp 的 LLVM 文本**追加**到 buf 末尾(buf 已有前缀时保持原前缀)""" + if sp is None or buf is None: + return 1 + if depth >= SPEC_LLVM_TEXT_MAX_DEPTH: + return 1 + pos: sizet = string.strlen(buf) + if pos + 1 >= buf_size: + return 1 + # --- 基础标量(无符号在 LLVM 文本层同样是 iN) --- + if sp.Kind == TS_INT or sp.Kind == TS_UINT: + viperlib.snprintf(buf + pos, buf_size - pos, "i%d", sp.Bits) + return 0 + if sp.Kind == TS_BOOL: + viperlib.snprintf(buf + pos, buf_size - pos, "i1") + return 0 + if sp.Kind == TS_FLOAT: + if sp.Bits == 16: + viperlib.snprintf(buf + pos, buf_size - pos, "half") + elif sp.Bits == 32: + viperlib.snprintf(buf + pos, buf_size - pos, "float") + elif sp.Bits == 64: + viperlib.snprintf(buf + pos, buf_size - pos, "double") + elif sp.Bits == 128: + viperlib.snprintf(buf + pos, buf_size - pos, "fp128") + else: + viperlib.snprintf(buf + pos, buf_size - pos, "float%x", sp.Bits) + return 0 + if sp.Kind == TS_VOID: + viperlib.snprintf(buf + pos, buf_size - pos, "void") + return 0 + # --- 指针 --- + if sp.Kind == TS_PTR: + inner: TypeSpec | t.CPtr = sp.Elem + if inner is None or inner.Kind == TS_VOID: + viperlib.snprintf(buf + pos, buf_size - pos, "i8*") + return 0 + if inner.Kind == TS_STRUCT or inner.Kind == TS_UNION or inner.Kind == TS_ENUM: + if inner.BaseName is not None: + viperlib.snprintf(buf + pos, buf_size - pos, "%%\"%s\"*", inner.BaseName) + return 0 + if _spec_llvm_text(inner, buf, buf_size, depth + 1) != 0: + return 1 + pos2: sizet = string.strlen(buf) + if pos2 + 1 >= buf_size: + return 1 + buf[pos2] = '*' + buf[pos2 + 1] = '\0' + return 0 + # --- 数组 --- + if sp.Kind == TS_ARRAY: + viperlib.snprintf(buf + pos, buf_size - pos, "[%d x ", sp.ArrayCount) + if _spec_llvm_text(sp.Elem, buf, buf_size, depth + 1) != 0: + return 1 + return _spec_llvm_append(buf, buf_size, "]") + # --- 命名结构体 / 联合 / 枚举 --- + if sp.Kind == TS_STRUCT or sp.Kind == TS_UNION or sp.Kind == TS_ENUM: + if sp.BaseName is None: + return 1 + viperlib.snprintf(buf + pos, buf_size - pos, "%%\"%s\"", sp.BaseName) + return 0 + # --- 函数签名 --- + if sp.Kind == TS_FUNC: + if _spec_llvm_text(sp.Ret, buf, buf_size, depth + 1) != 0: + return 1 + if _spec_llvm_append(buf, buf_size, " (") != 0: + return 1 + i: int = 0 + while i < sp.ParamCount: + if i > 0: + if _spec_llvm_append(buf, buf_size, ", ") != 0: + return 1 + ps: TypeSpec | t.CPtr = _spec_param_at(sp, i) + if ps is None: + return 1 + if _spec_llvm_text(ps, buf, buf_size, depth + 1) != 0: + return 1 + i += 1 + # 变参后缀(本 Spec 口径独有,见上方说明) + if sp.IsVarArg == 1: + if sp.ParamCount > 0: + if _spec_llvm_append(buf, buf_size, ", ...") != 0: + return 1 + else: + if _spec_llvm_append(buf, buf_size, "...") != 0: + return 1 + return _spec_llvm_append(buf, buf_size, ")") + return 1 + + +# ============================================================ +# SpecFromLLVMType - 已解析 LLVM 类型 → TypeSpec(结构翻译) +# +# 只做**结构层**翻译:Int / Float / Void / Ptr / Array / Func / Struct。 +# - 指针层级:由 Ptr 递归得到(NewTypePtr 内 PtrLevel = Elem.PtrLevel + 1) +# - 数组维度:取 Array.Count(元素语义三元组由 NewTypeArray 填) +# - 函数签名:Ret + 形参数组(沿 ParamNode 链表遍历;llvmlite **无按下标取参**) +# - 结构体:取结构体名;匿名结构体退化为无名 TS_STRUCT +# +# ⚠️ 两个**已知局限**(有意为之,避免臆造): +# 1. 符号性:LLVM 类型层**无法区分 iN 与 uN**(都是 i32)⇒ 本转换器一律给 +# `TS_INT + TS_SIGN_SIGNED`(与 SpecBaseText 的 "iN" 编码口径一致,保证驻留键 +# 不产生"同键不同义")。**无符号性必须由注解侧(符号性真源)覆盖**; +# 消费方在 S3 切读前**不要直接信任**本 spec 的 IsSigned。 +# 2. 变参:`...` 不在 `LLVMType.Func` 上(只存在于 `llvmlite.Function.IsVarArg`) +# ⇒ 本转换器恒置 IsVarArg=0;带变参的签名需由函数对象侧补写。 +# +# 本函数当前**无调用点**(S2 只入库;接线在后续步骤)。 +# ============================================================ +def SpecFromLLVMType(arena: TypeSpecArena | t.CPtr, + ty: llvmlite.LLVMType | t.CPtr) -> TypeSpec | t.CPtr: + """把已解析的 LLVM 类型翻译成 TypeSpec;不支持或为 None 时返回 None""" + if arena is None or ty is None: + return None + match ty: + case llvmlite.LLVMType.Int(bits): + if bits == 1: + return NewTypeSpec(arena, TS_BOOL, 1, TS_SIGN_UNSIGNED) + return NewTypeSpec(arena, TS_INT, bits, TS_SIGN_SIGNED) + case llvmlite.LLVMType.Float(bits): + return NewTypeSpec(arena, TS_FLOAT, bits, TS_SIGN_SIGNED) + case llvmlite.LLVMType.Void(): + return NewTypeSpec(arena, TS_VOID, 0, TS_SIGN_UNKNOWN) + case llvmlite.LLVMType.Ptr(pointee): + return _spec_from_ptr(arena, pointee) + case llvmlite.LLVMType.Array(elem_ty, count): + return _spec_from_array(arena, elem_ty, count) + case llvmlite.LLVMType.Func(ret, params, pcount): + return _spec_from_func(arena, ret, params, pcount) + case llvmlite.LLVMType.Struct(_, _, sname): + return _spec_from_struct(arena, sname) + case _: + return None + + +def _spec_from_ptr(arena: TypeSpecArena | t.CPtr, + pointee: llvmlite.LLVMType | t.CPtr) -> TypeSpec | t.CPtr: + """Ptr(pointee) → TypeSpec(PtrLevel/ElemBits/IsElemPtr 由 NewTypePtr 填)""" + inner: TypeSpec | t.CPtr = SpecFromLLVMType(arena, pointee) + if inner is None: + return None + return NewTypePtr(arena, inner) + + +def _spec_from_array(arena: TypeSpecArena | t.CPtr, + elem_ty: llvmlite.LLVMType | t.CPtr, + count: int) -> TypeSpec | t.CPtr: + """[count x elem] → TypeSpec(ArrayCount/ElemBits/IsElemPtr 由 NewTypeArray 填)""" + inner: TypeSpec | t.CPtr = SpecFromLLVMType(arena, elem_ty) + if inner is None: + return None + return NewTypeArray(arena, inner, count) + + +def _spec_from_func(arena: TypeSpecArena | t.CPtr, + ret: llvmlite.LLVMType | t.CPtr, + params: llvmlite.ParamNode | t.CPtr, + pcount: int) -> TypeSpec | t.CPtr: + """函数类型 → TypeSpec(形参沿 ParamNode 链表遍历;IsVarArg 恒 0,见上)""" + ret_s: TypeSpec | t.CPtr = SpecFromLLVMType(arena, ret) + if ret_s is None: + return None + if pcount <= 0: + no_params: sizet | t.CPtr = None + return NewTypeFunc(arena, ret_s, no_params, 0, 0) + params_arr: sizet | t.CPtr = CompilerFactory.factory.PermPool.alloc(8 * pcount) + if params_arr is None: + return None + node: llvmlite.ParamNode | t.CPtr = params + i: int = 0 + while node is not None and i < pcount: + pty: llvmlite.LLVMType | t.CPtr = llvmlite.paramnode_get_ty(node) + ps: TypeSpec | t.CPtr = SpecFromLLVMType(arena, pty) + if ps is None: + return None + slot: sizet | t.CPtr = (sizet | t.CPtr)( + t.CVoid(uint64(params_arr) + uint64(i * 8), t.CPtr)) + if slot is None: + return None + slot[0] = sizet(ps) + node = llvmlite.paramnode_get_next(node) + i += 1 + return NewTypeFunc(arena, ret_s, params_arr, pcount, 0) + + +def _spec_from_struct(arena: TypeSpecArena | t.CPtr, + sname: str) -> TypeSpec | t.CPtr: + """有名结构体 → TS_STRUCT + BaseName;匿名结构体 → 无名 TS_STRUCT""" + if sname is not None: + return NewTypeStruct(arena, TS_STRUCT, sname) + return NewTypeSpec(arena, TS_STRUCT, 0, TS_SIGN_UNKNOWN) + + +# ============================================================ +# SpecSelfCheck - S1 自检(不参与编译流程,供手动调用/后续单测) +# +# 构造若干类型 → 编码 → 解码 → 再编码,比较两次文本是否一致(往返一致)。 +# 返回 0=全部通过;否则返回失败用例编号(从 1 起) +# ============================================================ +def SpecSelfCheck() -> int: + """TypeSpec 编解码自检,返回 0=通过 / 失败用例号""" + arena: TypeSpecArena | t.CPtr = (TypeSpecArena | t.CPtr)( + t.CVoid(CompilerFactory.factory.PermPool.alloc(TypeSpecArena.__sizeof__()), t.CPtr)) + if arena is None: + return 1 + string.memset(arena, 0, TypeSpecArena.__sizeof__()) + if SpecArenaInit(arena, 64) != 0: + return 1 + + # 1) u64 + s_u64: TypeSpec | t.CPtr = NewTypeSpec(arena, TS_UINT, 64, TS_SIGN_UNSIGNED) + if s_u64 is None: + return 1 + if _check_roundtrip(s_u64, "u64") != 0: + return 1 + + # 2) i32 + s_i32: TypeSpec | t.CPtr = NewTypeSpec(arena, TS_INT, 32, TS_SIGN_SIGNED) + if s_i32 is None: + return 2 + if _check_roundtrip(s_i32, "i32") != 0: + return 2 + + # 3) u64* + s_p: TypeSpec | t.CPtr = NewTypePtr(arena, s_u64) + if s_p is None: + return 3 + if _check_roundtrip(s_p, "p:u64") != 0: + return 3 + + # 4) i8[4] + s_arr: TypeSpec | t.CPtr = NewTypeArray(arena, s_i32, 4) + if s_arr is None: + return 4 + if _check_roundtrip(s_arr, "arr[4]:i32") != 0: + return 4 + + # 5) fn(i32,u64)->i32(变参) + params: sizet | t.CPtr = CompilerFactory.factory.PermPool.alloc(8 * 2) + if params is None: + return 5 + slot0: sizet | t.CPtr = (sizet | t.CPtr)(t.CVoid(uint64(params), t.CPtr)) + if slot0 is None: + return 5 + slot0[0] = sizet(s_i32) + slot1: sizet | t.CPtr = (sizet | t.CPtr)(t.CVoid(uint64(params) + 8, t.CPtr)) + if slot1 is None: + return 5 + slot1[0] = sizet(s_u64) + s_fn: TypeSpec | t.CPtr = NewTypeFunc(arena, s_i32, params, 2, 1) + if s_fn is None: + return 5 + if _check_roundtrip(s_fn, "fn(i32,u64,...)->i32") != 0: + return 5 + + # 6) 驻留去重:同一文本第二次应返回同一实例 + s_u64_again: TypeSpec | t.CPtr = NewTypeSpec(arena, TS_UINT, 64, TS_SIGN_UNSIGNED) + if s_u64_again is None: + return 6 + if uint64(s_u64_again) != uint64(s_u64): + return 6 + return 0 + + +# ============================================================ +# _check_roundtrip - 自检辅助:编码应等于 expect,且解码再编码应一致 +# ============================================================ +def _check_roundtrip(sp: TypeSpec | t.CPtr, expect: str) -> int: + """编码比对 + 解码往返一致;返回 0=通过 / 1=失败""" + if sp is None or expect is None: + return 1 + buf1: str = CompilerFactory.factory.PermPool.alloc(SPEC_TEXT_MAX) + if buf1 is None: + return 1 + if SpecToText(sp, buf1, SPEC_TEXT_MAX) != 0: + return 1 + if string.strcmp(buf1, expect) != 0: + return 1 + back: TypeSpec | t.CPtr = TextToSpec(buf1) + if back is None: + return 1 + buf2: str = CompilerFactory.factory.PermPool.alloc(SPEC_TEXT_MAX) + if buf2 is None: + return 1 + if SpecToText(back, buf2, SPEC_TEXT_MAX) != 0: + return 1 + if string.strcmp(buf2, expect) != 0: + return 1 + return 0 diff --git a/App/lib/core/Gen/VarGenMixin.vp b/App/lib/core/Gen/VarGenMixin.vp index 44386cc..580aa86 100644 --- a/App/lib/core/Gen/VarGenMixin.vp +++ b/App/lib/core/Gen/VarGenMixin.vp @@ -52,7 +52,7 @@ class VarGenMixin: # init_vars — 分配并清零 VarEntry 数组 # ============================================================ Gen: Generator.Generator | t.CPtr - def init_vars(self, pool: memhub.MemBuddy | t.CPtr) -> GenTypes.VarEntry | t.CPtr: + def init_vars(self, pool: rowptr[memhub.MemBuddy]) -> GenTypes.VarEntry | t.CPtr: """分配并清零变量表数组""" size: sizet = MAX_VARS * GenTypes.VarEntry.__sizeof__() vars_ptr: GenTypes.VarEntry | t.CPtr = pool.alloc(size) @@ -285,7 +285,7 @@ class VarGenMixin: # ============================================================ # get_or_create_var — 查找或创建变量 alloca(旧版兼容) # ============================================================ - def get_or_create_var(self, pool: memhub.MemBuddy | t.CPtr, + def get_or_create_var(self, pool: rowptr[memhub.MemBuddy], builder: llvmlite.IRBuilder | t.CPtr, vars_ptr: GenTypes.VarEntry | t.CPtr, var_count: int, @@ -305,7 +305,7 @@ class VarGenMixin: # ============================================================ # _create_scope — 创建新作用域节点(内部辅助函数) # ============================================================ - def _create_scope(self, pool: memhub.MemBuddy | t.CPtr, + def _create_scope(self, pool: rowptr[memhub.MemBuddy], parent: GenTypes.Scope | t.CPtr, kind: int) -> GenTypes.Scope | t.CPtr: """创建并初始化作用域节点""" @@ -324,7 +324,7 @@ class VarGenMixin: # ============================================================ # init_symbol_table — 创建符号表(含模块级根作用域) # ============================================================ - def init_symbol_table(self, pool: memhub.MemBuddy | t.CPtr) -> GenTypes.SymbolTable | t.CPtr: + def init_symbol_table(self, pool: rowptr[memhub.MemBuddy]) -> GenTypes.SymbolTable | t.CPtr: """创建并初始化符号表,包含模块级根作用域""" if pool is None: return None @@ -351,7 +351,7 @@ class VarGenMixin: """进入新作用域,返回新创建的作用域""" if symtab is None: return None - pool: memhub.MemBuddy | t.CPtr = symtab.Pool + pool: rowptr[memhub.MemBuddy] = symtab.Pool scope: GenTypes.Scope | t.CPtr = self._create_scope(pool, symtab.Current, kind) if scope is None: return None @@ -501,7 +501,7 @@ class VarGenMixin: # get_or_create_sym — 查找或创建变量(在当前作用域) # ============================================================ def get_or_create_sym(self, symtab: GenTypes.SymbolTable | t.CPtr, - pool: memhub.MemBuddy | t.CPtr, + pool: rowptr[memhub.MemBuddy], builder: llvmlite.IRBuilder | t.CPtr, name: str, ty: llvmlite.LLVMType | t.CPtr) -> llvmlite.Value | t.CPtr: diff --git a/App/lib/core/IncludesScanner.vp b/App/lib/core/IncludesScanner.vp index 079fcf5..b36d216 100644 --- a/App/lib/core/IncludesScanner.vp +++ b/App/lib/core/IncludesScanner.vp @@ -22,7 +22,7 @@ import lib.core.VLogger as VLogger # ============================================================ # 全局 mbuddy 指针 -_mbuddy: memhub.MemBuddy | t.CPtr +_mbuddy: rowptr[memhub.MemBuddy] # 文件路径最大长度 MAX_PATH_LEN: t.CDefine = 512 @@ -57,7 +57,7 @@ class ScanResult: # ============================================================ # create_scan_result - 创建扫描结果容器 # ============================================================ -def create_scan_result(pool: memhub.MemBuddy | t.CPtr) -> ScanResult | t.CPtr: +def create_scan_result(pool: rowptr[memhub.MemBuddy]) -> ScanResult | t.CPtr: """创建扫描结果容器,预分配 MAX_FILES 个槽位""" if pool is None: return None @@ -82,7 +82,7 @@ def create_scan_result(pool: memhub.MemBuddy | t.CPtr) -> ScanResult | t.CPtr: # add_file_entry - 向扫描结果添加文件条目 # ============================================================ def add_file_entry(result: ScanResult | t.CPtr, - pool: memhub.MemBuddy | t.CPtr, + pool: rowptr[memhub.MemBuddy], abs_path: str, rel_path: str, sha1: str, inc_dir: str) -> int: """添加文件条目到扫描结果,返回 0 成功(inc_dir 为所属 includes 根目录)""" @@ -148,7 +148,7 @@ def add_file_entry(result: ScanResult | t.CPtr, # Projectrans.py 用 Python 文本模式读取(自动 CRLF→LF), # IncludesScanner 用二进制模式读取,需手动去除 \r。 # ============================================================ -def compute_file_sha1(pool: memhub.MemBuddy | t.CPtr, +def compute_file_sha1(pool: rowptr[memhub.MemBuddy], file_path: str) -> str: """读取文件内容并计算 SHA1 前16字符(CRLF→LF 后计算,与 Projectrans.py 一致)""" if pool is None or file_path is None: @@ -199,7 +199,7 @@ def compute_file_sha1(pool: memhub.MemBuddy | t.CPtr, # 使用 FindFirstFileA/FindNextFileA 遍历目录树, # 对每个 .vp/.py 文件计算 SHA1 并添加到结果中。 # ============================================================ -def scan_directory_recursive(pool: memhub.MemBuddy | t.CPtr, +def scan_directory_recursive(pool: rowptr[memhub.MemBuddy], root_dir: str, rel_prefix: str, result: ScanResult | t.CPtr, @@ -317,7 +317,7 @@ def scan_directory_recursive(pool: memhub.MemBuddy | t.CPtr, # # 扫描指定的 includes 目录,返回所有 .vp/.py 文件的路径和 SHA1。 # ============================================================ -def scan_includes(pool: memhub.MemBuddy | t.CPtr, +def scan_includes(pool: rowptr[memhub.MemBuddy], includes_dirs: str) -> ScanResult | t.CPtr: """扫描 includes 目录(支持空格分隔的多目录),返回所有 .vp/.py 文件的扫描结果""" if pool is None or includes_dirs is None: diff --git a/App/lib/core/VLogger.vp b/App/lib/core/VLogger.vp index 8941208..e935aca 100644 --- a/App/lib/core/VLogger.vp +++ b/App/lib/core/VLogger.vp @@ -59,7 +59,7 @@ class Logger: _level: int _console_handle: win32base.HANDLE _use_color: int - __mbuddy__: memhub.MemBuddy | t.CPtr + __mbuddy__: rowptr[memhub.MemBuddy] def __init__(self, level: int = 1): self._level = level @@ -188,7 +188,7 @@ class Logger: # 全局 mbuddy 指针(由 lib.InitLib 注入) -_mbuddy: memhub.MemBuddy | t.CPtr +_mbuddy: rowptr[memhub.MemBuddy] # 全局 logger 指针 logger: Logger | t.CPtr diff --git a/Test/App/nested_match_test.vp b/Test/App/nested_match_test.vp index fa3c40c..20ebf4a 100644 --- a/Test/App/nested_match_test.vp +++ b/Test/App/nested_match_test.vp @@ -17,7 +17,7 @@ import string # ============================================================ # 内存池(测试内部使用) -_mbuddy: memhub.MemBuddy | t.CPtr +_mbuddy: rowptr[memhub.MemBuddy] # 测试用内存大小(64KB,足够构造 LLVMType 值) _NMATCH_POOL_SIZE: t.CDefine = 65536 @@ -32,7 +32,7 @@ def _init_mbuddy() -> int: if arena is None: stdio.printf("FAIL: malloc for arena failed\n") return 1 - mb: memhub.MemBuddy | t.CPtr = stdlib.malloc(memhub.MemBuddy.__sizeof__()) + mb: rowptr[memhub.MemBuddy] = stdlib.malloc(memhub.MemBuddy.__sizeof__()) stdio.printf("[DBG] _init_mbuddy: malloc mb=%d\n", mb is None) if mb is None: stdio.printf("FAIL: MemBuddy init failed\n") diff --git a/Test/Sha1Test/App/main.vp b/Test/Sha1Test/App/main.vp index 6d8dc30..37ea838 100644 --- a/Test/Sha1Test/App/main.vp +++ b/Test/Sha1Test/App/main.vp @@ -14,7 +14,7 @@ def main() -> int: arena: bytes = stdlib.malloc(POOL_SIZE) if arena is None: return 1 - mb: memhub.MemBuddy | t.CPtr = memhub.MemBuddy(arena, POOL_SIZE) + mb: rowptr[memhub.MemBuddy] = memhub.MemBuddy(arena, POOL_SIZE) if mb is None: return 1 hashlib._mbuddy = (memhub.MemManager | t.CPtr)(mb)