diff --git a/App/lib/Phase/BuildPipeline.vp b/App/lib/Phase/BuildPipeline.vp index 6fc5c90..b6197b4 100644 --- a/App/lib/Phase/BuildPipeline.vp +++ b/App/lib/Phase/BuildPipeline.vp @@ -188,12 +188,7 @@ def _tb_basename_is_traceback(file_path: str) -> int: # Args: mb 内存池;file_path 源文件路径;sha1_val 文件内容的 SHA1 前16字符(用于函数名混淆);current_package 当前文件所属包名(用于解析相对导入),None 表示顶级模块;declare_only 0=全量翻译(默认),1=仅注册 struct/enum/union(不翻译方法体);temp_dir temp 目录路径(非 None 时在翻译前生成 .vpi 存根文件) # Returns: Translator 对象(None 失败) # ============================================================ -def TranslateFileGetTrans(mb: memhub.MemBuddy*, file_path: str, - sha1_val: str, - current_package: str = None, - declare_only: int = 0, - temp_dir: str = None, - pre_allow_dep_inject: int = 0) -> rawptr[HandlesTranslator.Translator]: +def TranslateFileGetTrans(mb: memhub.MemBuddy*, file_path: str, sha1_val: str, current_package: str = None, declare_only: int = 0, temp_dir: str = None, pre_allow_dep_inject: int = 0) -> rawptr[HandlesTranslator.Translator]: """翻译文件,返回 Translator 对象(调用者负责 dump_ir),None 失败 current_package: 当前文件所属包名(用于解析相对导入),None 表示顶级模块 @@ -501,16 +496,13 @@ def compile_ll_to_obj(ir_path: str, output_dir: str, module_name: str, cc_cmd: s p2_olen: sizet = len(p2_asan) + len(compile_input) + 192 p2_opt_cmd = _mbuddy.alloc(p2_olen) if p2_opt_cmd is not None: - viperlib.snprintf(p2_opt_cmd, p2_olen, - "opt -passes=forceattrs,asan -force-attribute=sanitize_address -asan-globals=false -o %s %s", - p2_asan, compile_input) + viperlib.snprintf(p2_opt_cmd, p2_olen, "opt -passes=forceattrs,asan -force-attribute=sanitize_address -asan-globals=false -o %s %s", p2_asan, compile_input) compile_input = p2_asan llc_fp: str = _llc_frame_ptr_flag() p2_clen: sizet = len(cc_cmd) + len(cc_flags) + len(llc_fp) + len(obj_path) + len(compile_input) + 64 p2_cmd: bytes = _mbuddy.alloc(p2_clen) if p2_cmd is not None: - viperlib.snprintf(p2_cmd, p2_clen, "%s %s%s -o %s %s", - cc_cmd, cc_flags, llc_fp, obj_path, compile_input) + viperlib.snprintf(p2_cmd, p2_clen, "%s %s%s -o %s %s", cc_cmd, cc_flags, llc_fp, obj_path, compile_input) if p2_opt_cmd is not None: _phase2_write_cmd(p2_opt_cmd) if p2_cmd is not None: _phase2_write_cmd(p2_cmd) return 0 @@ -521,9 +513,7 @@ def compile_ll_to_obj(ir_path: str, output_dir: str, module_name: str, cc_cmd: s opt_cmd_len: sizet = len(asan_path) + len(compile_input) + 192 opt_cmd: bytes = _mbuddy.alloc(opt_cmd_len) if opt_cmd is None: return 1 - viperlib.snprintf(opt_cmd, opt_cmd_len, - "opt -passes=forceattrs,asan -force-attribute=sanitize_address -asan-globals=false -o %s %s", - asan_path, compile_input) + viperlib.snprintf(opt_cmd, opt_cmd_len, "opt -passes=forceattrs,asan -force-attribute=sanitize_address -asan-globals=false -o %s %s", asan_path, compile_input) opt_ret: int = stdlib.system(opt_cmd) if opt_ret != 0: VLogger.error(f"opt ASan 插桩失败 (module={module_name})", "ASAN") @@ -535,8 +525,7 @@ def compile_ll_to_obj(ir_path: str, output_dir: str, module_name: str, cc_cmd: s cmd_len: sizet = len(cc_cmd) + len(cc_flags) + len(llc_fp2) + len(obj_path) + len(compile_input) + 64 cmd: bytes = _mbuddy.alloc(cmd_len) if cmd is None: return 1 - viperlib.snprintf(cmd, cmd_len, "%s %s%s -o %s %s", - cc_cmd, cc_flags, llc_fp2, obj_path, compile_input) + viperlib.snprintf(cmd, cmd_len, "%s %s%s -o %s %s", cc_cmd, cc_flags, llc_fp2, obj_path, compile_input) # 用 CreateProcessA 直启 llc(避开 cmd/c 在 asan 下挂起),子进程继承父控制台: # stdout|stderr 直接显示;失败时打印模块 sha1 + 退出码 + 完整命令(退出码同步返回) @@ -586,8 +575,7 @@ class LlcTask: FailStage: int # worker 写:失败发生在哪一步 -def init_llc_task(task: LlcTask*, ir_path: str, output_dir: str, - module_name: str, cc_cmd: str, cc_flags: str) -> int: +def init_llc_task(task: LlcTask*, ir_path: str, output_dir: str, module_name: str, cc_cmd: str, cc_flags: str) -> int: """填充 llc 任务(全部 stdlib.malloc,线程运行期不被回收),0 成功""" if task is None or ir_path is None or output_dir is None or module_name is None: return 1 string.memset(task, 0, LlcTask.__sizeof__()) @@ -615,8 +603,7 @@ def init_llc_task(task: LlcTask*, ir_path: str, output_dir: str, mt_len: sizet = len(MLIR_TRANSLATE_CMD) + len(mlir_opt_out) + len(ll_local_path) + 40 task.MlirTranslateCmd = stdlib.malloc(mt_len) if task.MlirTranslateCmd is None: return 1 - viperlib.snprintf(task.MlirTranslateCmd, mt_len, "%s --mlir-to-llvmir %s -o %s", - MLIR_TRANSLATE_CMD, mlir_opt_out, ll_local_path) + viperlib.snprintf(task.MlirTranslateCmd, mt_len, "%s --mlir-to-llvmir %s -o %s", MLIR_TRANSLATE_CMD, mlir_opt_out, ll_local_path) compile_input = ll_local_path # ASan 模式:opt 插桩命令(worker 先跑 MLIR 降级/opt 再跑 llc,故 LlcCmd 的输入 # 必须指向 asan_path;失败即置 Result) @@ -626,18 +613,14 @@ def init_llc_task(task: LlcTask*, ir_path: str, output_dir: str, opt_len: sizet = len(asan_path) + len(compile_input) + 192 task.OptCmd = stdlib.malloc(opt_len) if task.OptCmd is None: return 1 - viperlib.snprintf(task.OptCmd, opt_len, - "opt -passes=forceattrs,asan -force-attribute=sanitize_address" - " -asan-globals=false -o %s %s", - asan_path, compile_input) + viperlib.snprintf(task.OptCmd, opt_len, "opt -passes=forceattrs,asan -force-attribute=sanitize_address" " -asan-globals=false -o %s %s", asan_path, compile_input) compile_input = asan_path # llc 命令(输入 = compile_input:非 ASan 为 .ll,ASan 为 .asan.ll) llc_fp3: str = _llc_frame_ptr_flag() cmd_len: sizet = len(cc_cmd) + len(cc_flags) + len(llc_fp3) + len(obj_path) + len(compile_input) + 64 task.LlcCmd = stdlib.malloc(cmd_len) if task.LlcCmd is None: return 1 - viperlib.snprintf(task.LlcCmd, cmd_len, "%s %s%s -o %s %s", - cc_cmd, cc_flags, llc_fp3, obj_path, compile_input) + viperlib.snprintf(task.LlcCmd, cmd_len, "%s %s%s -o %s %s", cc_cmd, cc_flags, llc_fp3, obj_path, compile_input) return 0 @@ -716,9 +699,7 @@ def _run_cmd_wait(cmd: str) -> int: si.cb = win32process.STARTUPINFOA.__sizeof__() # create_flags=0:子进程继承父控制台(输出直接显示,同 system 语义); # si.dwFlags 保持 memset 后的 0(不置 STARTF_USESTDHANDLES、不设 std 句柄) - ok: int = win32process.CreateProcessA( - t.CPtr(0), cmd_line, t.CPtr(0), t.CPtr(0), 1, 0, - t.CPtr(0), t.CPtr(0), t.CPtr(&si), t.CPtr(&pi)) + ok: int = win32process.CreateProcessA(t.CPtr(0), cmd_line, t.CPtr(0), t.CPtr(0), 1, 0, t.CPtr(0), t.CPtr(0), t.CPtr(&si), t.CPtr(&pi)) # CreateProcessA 失败诊断:GetLastError 必须在返回后立即取(此后 stdlib.free/ # CloseHandle/SetConsoleTextAttribute 等都会覆盖它)。用 warning 不用 error—— # VLogger.error 会 sys.exit(1),而本函数可能在 worker 线程里执行;warning 只走 @@ -847,8 +828,7 @@ def run_llc_parallel(tasks: bytes, task_count: int, max_threads: int) -> int: return ret -def _CollectObjFilesImpl(base_dir: str, bd_len: sizet, - out_buf: bytes, out_pos: sizet, out_size: sizet) -> sizet: +def _CollectObjFilesImpl(base_dir: str, bd_len: sizet, out_buf: bytes, out_pos: sizet, out_size: sizet) -> sizet: """递归扫描 base_dir,收集 .obj 文件路径到 out_buf,返回新的 out_pos 支持切片子目录(如 dir/43/{sha1}.obj)。 @@ -954,14 +934,12 @@ def _append_host_export_implib(linker_flags: str, implib_path: str) -> str: if buf is None: VLogger.warning("宿主导出:import lib 参数缓冲分配失败(片段将无法导入宿主符号)", "link") return linker_flags - viperlib.snprintf(buf, string.strlen(linker_flags) + extra, - "%s -Wl,--out-implib=%s", linker_flags, implib_path) + viperlib.snprintf(buf, string.strlen(linker_flags) + extra, "%s -Wl,--out-implib=%s", linker_flags, implib_path) VLogger.info(f"宿主导出:产出 import lib {implib_path}", "link") return buf -def link_obj_to_exe(output_dir: str, module_name: str, linker_cmd: str, linker_flags: str, linker_output: str, - includes_binary_dir: str, linker_static_libs: str = None, linker_dynamic_libs: str = None) -> int: +def link_obj_to_exe(output_dir: str, module_name: str, linker_cmd: str, linker_flags: str, linker_output: str, includes_binary_dir: str, linker_static_libs: str = None, linker_dynamic_libs: str = None) -> int: """调用 clang++ 链接 .obj 为 .exe Args: @@ -1019,32 +997,22 @@ def link_obj_to_exe(output_dir: str, module_name: str, linker_cmd: str, linker_f merged_sl: str = _mbuddy.alloc(len(static_libs) + len(linker_dynamic_libs) + 2) if merged_sl is not None: if len(static_libs) > 0: - viperlib.snprintf(merged_sl, len(static_libs) + len(linker_dynamic_libs) + 2, - "%s %s", static_libs, linker_dynamic_libs) + viperlib.snprintf(merged_sl, len(static_libs) + len(linker_dynamic_libs) + 2, "%s %s", static_libs, linker_dynamic_libs) else: - viperlib.snprintf(merged_sl, len(static_libs) + len(linker_dynamic_libs) + 2, - "%s", linker_dynamic_libs) + viperlib.snprintf(merged_sl, len(static_libs) + len(linker_dynamic_libs) + 2, "%s", linker_dynamic_libs) static_libs = merged_sl sl_len: sizet = len(static_libs) cmd_len: sizet = len(linker_cmd) + len(obj_path) + len(use_flags) + len(output_dir) + len(linker_output) + extra_len + sl_len + 128 cmd: bytes = _mbuddy.alloc(cmd_len) if cmd is None: return 1 if sl_len > 0 and extra_len > 0: - viperlib.snprintf(cmd, cmd_len, "%s %s %s %s -o %s/%s %s", - linker_cmd, obj_path, extra_objs, static_libs, - output_dir, linker_output, use_flags) + viperlib.snprintf(cmd, cmd_len, "%s %s %s %s -o %s/%s %s", linker_cmd, obj_path, extra_objs, static_libs, output_dir, linker_output, use_flags) elif sl_len > 0: - viperlib.snprintf(cmd, cmd_len, "%s %s %s -o %s/%s %s", - linker_cmd, obj_path, static_libs, - output_dir, linker_output, use_flags) + viperlib.snprintf(cmd, cmd_len, "%s %s %s -o %s/%s %s", linker_cmd, obj_path, static_libs, output_dir, linker_output, use_flags) elif extra_len > 0: - viperlib.snprintf(cmd, cmd_len, "%s %s %s -o %s/%s %s", - linker_cmd, obj_path, extra_objs, - output_dir, linker_output, use_flags) + viperlib.snprintf(cmd, cmd_len, "%s %s %s -o %s/%s %s", linker_cmd, obj_path, extra_objs, output_dir, linker_output, use_flags) else: - viperlib.snprintf(cmd, cmd_len, "%s %s -o %s/%s %s", - linker_cmd, obj_path, output_dir, linker_output, - use_flags) + viperlib.snprintf(cmd, cmd_len, "%s %s -o %s/%s %s", linker_cmd, obj_path, output_dir, linker_output, use_flags) # --phase2command 模式:不执行链接,命令写入 bat if _phase2_cmd_path is not None: @@ -1067,8 +1035,7 @@ def link_obj_to_exe(output_dir: str, module_name: str, linker_cmd: str, linker_f return 0 -def asm_to_obj(asm_path: str, sha1_val: str, output_dir: str, - triple: str) -> int: +def asm_to_obj(asm_path: str, sha1_val: str, output_dir: str, triple: str) -> int: """用 llvm-mc 汇编 .s 源文件为 .obj(切片路径) 裸机项目(VKernel 等)含 .s 汇编文件(如 Kernel/intr/isr.s 定义 @@ -1093,8 +1060,7 @@ def asm_to_obj(asm_path: str, sha1_val: str, output_dir: str, cmd_len: sizet = len("llvm-mc -triple=") + len(trip) + len(" -filetype=obj -o ") + len(obj_path) + len(asm_path) + 64 cmd: bytes = _mbuddy.alloc(cmd_len) if cmd is None: return 1 - viperlib.snprintf(cmd, cmd_len, "llvm-mc -triple=%s -filetype=obj -o %s %s", - trip, obj_path, asm_path) + viperlib.snprintf(cmd, cmd_len, "llvm-mc -triple=%s -filetype=obj -o %s %s", trip, obj_path, asm_path) # --phase2command 模式:命令写入 bat(与 llc/链接一致) if _phase2_cmd_path is not None: @@ -1113,9 +1079,7 @@ def asm_to_obj(asm_path: str, sha1_val: str, output_dir: str, return 0 -def compile_module_to_obj(ir_buf: bytes, ir_len: sizet, - temp_dir: str, output_dir: str, module_name: str, - cc_cmd: str, cc_flags: str) -> int: +def compile_module_to_obj(ir_buf: bytes, ir_len: sizet, temp_dir: str, output_dir: str, module_name: str, cc_cmd: str, cc_flags: str) -> int: """编译 IR 到 .obj(不链接) Args: @@ -1149,9 +1113,7 @@ def compile_module_to_obj(ir_buf: bytes, ir_len: sizet, return 0 -def link_objs_to_exe(obj_paths: str, obj_paths_len: sizet, - linker_cmd: str, linker_flags: str, linker_output: str, - includes_binary_dir: str, linker_static_libs: str = None, linker_dynamic_libs: str = None) -> int: +def link_objs_to_exe(obj_paths: str, obj_paths_len: sizet, linker_cmd: str, linker_flags: str, linker_output: str, includes_binary_dir: str, linker_static_libs: str = None, linker_dynamic_libs: str = None) -> int: """链接多个 .obj 文件为 .exe Args: @@ -1241,11 +1203,9 @@ def link_objs_to_exe(obj_paths: str, obj_paths_len: sizet, merged_sl2: str = _mbuddy.alloc(len(static_libs2) + len(linker_dynamic_libs) + 2) if merged_sl2 is not None: if len(static_libs2) > 0: - viperlib.snprintf(merged_sl2, len(static_libs2) + len(linker_dynamic_libs) + 2, - "%s %s", static_libs2, linker_dynamic_libs) + viperlib.snprintf(merged_sl2, len(static_libs2) + len(linker_dynamic_libs) + 2, "%s %s", static_libs2, linker_dynamic_libs) else: - viperlib.snprintf(merged_sl2, len(static_libs2) + len(linker_dynamic_libs) + 2, - "%s", linker_dynamic_libs) + viperlib.snprintf(merged_sl2, len(static_libs2) + len(linker_dynamic_libs) + 2, "%s", linker_dynamic_libs) static_libs2 = merged_sl2 sl2_len: sizet = len(static_libs2) cmd_len: sizet = len(linker_cmd) + obj_paths_len + len(use_flags) + len(linker_output) + extra_len + sl2_len + 128 @@ -1253,20 +1213,13 @@ def link_objs_to_exe(obj_paths: str, obj_paths_len: sizet, if cmd is None: return 1 # linker.static_libs 显式静态链接文件位于 .obj 之后、-o 之前 if sl2_len > 0 and extra_len > 0: - viperlib.snprintf(cmd, cmd_len, "%s %s %s %s -o %s %s", - linker_cmd, obj_paths, extra_objs, static_libs2, - linker_output, use_flags) + viperlib.snprintf(cmd, cmd_len, "%s %s %s %s -o %s %s", linker_cmd, obj_paths, extra_objs, static_libs2, linker_output, use_flags) elif sl2_len > 0: - viperlib.snprintf(cmd, cmd_len, "%s %s %s -o %s %s", - linker_cmd, obj_paths, static_libs2, - linker_output, use_flags) + viperlib.snprintf(cmd, cmd_len, "%s %s %s -o %s %s", linker_cmd, obj_paths, static_libs2, linker_output, use_flags) elif extra_len > 0: - viperlib.snprintf(cmd, cmd_len, "%s %s %s -o %s %s", - linker_cmd, obj_paths, extra_objs, - linker_output, use_flags) + viperlib.snprintf(cmd, cmd_len, "%s %s %s -o %s %s", linker_cmd, obj_paths, extra_objs, linker_output, use_flags) else: - viperlib.snprintf(cmd, cmd_len, "%s %s -o %s %s", - linker_cmd, obj_paths, linker_output, use_flags) + viperlib.snprintf(cmd, cmd_len, "%s %s -o %s %s", linker_cmd, obj_paths, linker_output, use_flags) # 用 subprocess.run 捕获 clang++ 的 stdout/stderr 输出 # 之前用 stdlib.system() 无法捕获具体错误(undefined reference 等), @@ -1616,8 +1569,7 @@ def _tb_file_rec(files: bytes, count: int, idx: int) -> int: return -1 -def _tb_resolve_file(mb: memhub.MemBuddy*, files: bytes, fcount: int, - dirs: bytes, dcount: int, frec: int) -> str: +def _tb_resolve_file(mb: memhub.MemBuddy*, files: bytes, fcount: int, dirs: bytes, dcount: int, frec: int) -> str: """Resolve a file-table entry to a path (absolute name wins, else dir join).""" roff: sizet = sizet(frec) * TB_FILE_SIZE cached: uint64 = _tb_rd_u64(files, roff + 24) @@ -1637,8 +1589,7 @@ def _tb_resolve_file(mb: memhub.MemBuddy*, files: bytes, fcount: int, return path -def _tb_grow_rec(mb: memhub.MemBuddy*, buf: bytes, old_cap: int, - rec_size: int, new_cap: int) -> bytes: +def _tb_grow_rec(mb: memhub.MemBuddy*, buf: bytes, old_cap: int, rec_size: int, new_cap: int) -> bytes: nb: bytes = mb.alloc(sizet(new_cap) * sizet(rec_size)) if nb is None: return None string.memcpy(nb, buf, sizet(old_cap) * sizet(rec_size)) @@ -1646,8 +1597,7 @@ def _tb_grow_rec(mb: memhub.MemBuddy*, buf: bytes, old_cap: int, return nb -def _tb_emit_row(mb: memhub.MemBuddy*, d: TbDump*, - addr: uint64, path: str, line: int, fname: str = None) -> int: +def _tb_emit_row(mb: memhub.MemBuddy*, d: TbDump*, addr: uint64, path: str, line: int, fname: str = None) -> int: if d is None: return 1 if d.RowCount >= d.RowCap: ncap: int = d.RowCap * 2 @@ -1669,8 +1619,7 @@ def _tb_emit_row(mb: memhub.MemBuddy*, d: TbDump*, return 0 -def _tb_emit_func(mb: memhub.MemBuddy*, d: TbDump*, - low: uint64, high: uint64, name: str) -> int: +def _tb_emit_func(mb: memhub.MemBuddy*, d: TbDump*, low: uint64, high: uint64, name: str) -> int: if d is None: return 1 if d.FuncCount >= d.FuncCap: ncap: int = d.FuncCap * 2 @@ -2097,8 +2046,7 @@ def _tb_cp_init(mb: memhub.MemBuddy*) -> TbCallParse*: return cp -def _tb_cp_add_cr(mb: memhub.MemBuddy*, cp: TbCallParse*, - caller: str, callee: str, file: str, line: int) -> int: +def _tb_cp_add_cr(mb: memhub.MemBuddy*, cp: TbCallParse*, caller: str, callee: str, file: str, line: int) -> int: if cp.CrN >= cp.CrCap: ncap: int = cp.CrCap * 2 nb: bytes = _tb_grow_rec(mb, cp.Cr, cp.CrCap, TB_CR_SIZE, ncap) @@ -2117,8 +2065,7 @@ def _tb_cp_add_cr(mb: memhub.MemBuddy*, cp: TbCallParse*, return 0 -def _tb_cp_add_fr(mb: memhub.MemBuddy*, cp: TbCallParse*, - sym: str, file: str, defline: int) -> int: +def _tb_cp_add_fr(mb: memhub.MemBuddy*, cp: TbCallParse*, sym: str, file: str, defline: int) -> int: if cp.FrN >= cp.FrCap: ncap: int = cp.FrCap * 2 nb: bytes = _tb_grow_rec(mb, cp.Fr, cp.FrCap, TB_FR_SIZE, ncap) @@ -2153,8 +2100,7 @@ def _tb_read_whole(mb: memhub.MemBuddy*, path: str) -> str: return buf -def _tb_parse_f_line(mb: memhub.MemBuddy*, s: str, a: sizet, b: sizet, - cp: TbCallParse*) -> int: +def _tb_parse_f_line(mb: memhub.MemBuddy*, s: str, a: sizet, b: sizet, cp: TbCallParse*) -> int: """解析 `F\t\t\t`。""" p: sizet = a while p < b and _tb_cc(s, p) != 9: p += 1 @@ -2175,8 +2121,7 @@ def _tb_parse_f_line(mb: memhub.MemBuddy*, s: str, a: sizet, b: sizet, return _tb_cp_add_fr(mb, cp, sym, file, defline) -def _tb_parse_c_line(mb: memhub.MemBuddy*, s: str, a: sizet, b: sizet, - cp: TbCallParse*) -> int: +def _tb_parse_c_line(mb: memhub.MemBuddy*, s: str, a: sizet, b: sizet, cp: TbCallParse*) -> int: """解析 `C\t\t\t\t`。""" p: sizet = a while p < b and _tb_cc(s, p) != 9: p += 1 @@ -2202,8 +2147,7 @@ def _tb_parse_c_line(mb: memhub.MemBuddy*, s: str, a: sizet, b: sizet, return _tb_cp_add_cr(mb, cp, caller, callee, file, line) -def _tb_parse_vpcall_file(mb: memhub.MemBuddy*, path: str, - cp: TbCallParse*) -> int: +def _tb_parse_vpcall_file(mb: memhub.MemBuddy*, path: str, cp: TbCallParse*) -> int: whole: str = _tb_read_whole(mb, path) if whole is None: VLogger.error(f"--traceback: 读取 .vpcall 失败:{path},终止编译", "TRACEBACK") @@ -2269,9 +2213,7 @@ def _tb_build_groups(mb: memhub.MemBuddy*, cp: TbCallParse*) -> int: return 0 -def _tb_emit_call_row(mb: memhub.MemBuddy*, d: TbDump*, - cp: TbCallParse*, img_lo: uint64, - caller: str, callee: str, ret_va: uint64) -> int: +def _tb_emit_call_row(mb: memhub.MemBuddy*, d: TbDump*, cp: TbCallParse*, img_lo: uint64, caller: str, callee: str, ret_va: uint64) -> int: """按 (caller,callee) 的下一条未消费 C 记录为返回地址生成一条行记录。""" if caller is None or callee is None or cp.Grp is None or ret_va < img_lo: return 0 slot: int = _tb_grp_get(cp.Grp, cp.GrpCap, caller, callee, 0) @@ -2288,9 +2230,7 @@ def _tb_emit_call_row(mb: memhub.MemBuddy*, d: TbDump*, return _tb_emit_row(mb, d, ret_va, file, line, caller) -def _tb_emit_entry_row(mb: memhub.MemBuddy*, d: TbDump*, - cp: TbCallParse*, img_lo: uint64, - addr: uint64, sym: str) -> int: +def _tb_emit_entry_row(mb: memhub.MemBuddy*, d: TbDump*, cp: TbCallParse*, img_lo: uint64, addr: uint64, sym: str) -> int: """为 objdump 标签 `sym` 生成函数入口兜底行(文件/定义行取自 F 记录)。""" if sym is None or cp.Fr is None or cp.FrN <= 0 or addr < img_lo: return 0 i: int = 0 @@ -2336,8 +2276,7 @@ def _tb_run_objdump(mb: memhub.MemBuddy*, exe_path: str) -> str: return dump -def _tb_scan_objdump(mb: memhub.MemBuddy*, dump: str, img_lo: uint64, - d: TbDump*, cp: TbCallParse*) -> int: +def _tb_scan_objdump(mb: memhub.MemBuddy*, dump: str, img_lo: uint64, d: TbDump*, cp: TbCallParse*) -> int: """解析 `llvm-objdump -d` 文本,匹配 C/F 记录并把我方行写入 d。""" dlen: sizet = string.strlen(dump) pos: sizet = 0 @@ -2499,12 +2438,9 @@ def WriteStackMap(mb: memhub.MemBuddy*, exe_path: str) -> int: continue if kept != i: _tb_wr_u64(d.RowBuf, sizet(kept) * TB_ROW_SIZE, a - img_lo) - _tb_wr_u64(d.RowBuf, sizet(kept) * TB_ROW_SIZE + TB_ROW_OFF_FILE, - _tb_rd_u64(d.RowBuf, sizet(i) * TB_ROW_SIZE + TB_ROW_OFF_FILE)) - _tb_wr_u32(d.RowBuf, sizet(kept) * TB_ROW_SIZE + TB_ROW_OFF_LINE, - uint64(_tb_rd_u32(d.RowBuf, sizet(i) * TB_ROW_SIZE + TB_ROW_OFF_LINE))) - _tb_wr_u64(d.RowBuf, sizet(kept) * TB_ROW_SIZE + TB_ROW_OFF_FUNC, - _tb_rd_u64(d.RowBuf, sizet(i) * TB_ROW_SIZE + TB_ROW_OFF_FUNC)) + _tb_wr_u64(d.RowBuf, sizet(kept) * TB_ROW_SIZE + TB_ROW_OFF_FILE, _tb_rd_u64(d.RowBuf, sizet(i) * TB_ROW_SIZE + TB_ROW_OFF_FILE)) + _tb_wr_u32(d.RowBuf, sizet(kept) * TB_ROW_SIZE + TB_ROW_OFF_LINE, uint64(_tb_rd_u32(d.RowBuf, sizet(i) * TB_ROW_SIZE + TB_ROW_OFF_LINE))) + _tb_wr_u64(d.RowBuf, sizet(kept) * TB_ROW_SIZE + TB_ROW_OFF_FUNC, _tb_rd_u64(d.RowBuf, sizet(i) * TB_ROW_SIZE + TB_ROW_OFF_FUNC)) else: _tb_wr_u64(d.RowBuf, sizet(kept) * TB_ROW_SIZE, a - img_lo) kept += 1 i += 1 @@ -2518,8 +2454,7 @@ def WriteStackMap(mb: memhub.MemBuddy*, exe_path: str) -> int: sj: int = si2 while sj > 0: if _tb_rd_u64(d.RowBuf, sizet(sj - 1) * TB_ROW_SIZE) <= _tb_rd_u64(tmp, 0): break - string.memcpy(d.RowBuf + sizet(sj) * TB_ROW_SIZE, - d.RowBuf + sizet(sj - 1) * TB_ROW_SIZE, TB_ROW_SIZE) + string.memcpy(d.RowBuf + sizet(sj) * TB_ROW_SIZE, d.RowBuf + sizet(sj - 1) * TB_ROW_SIZE, TB_ROW_SIZE) sj -= 1 string.memcpy(d.RowBuf + sizet(sj) * TB_ROW_SIZE, tmp, TB_ROW_SIZE) si2 += 1 @@ -2568,8 +2503,7 @@ def WriteStackMap(mb: memhub.MemBuddy*, exe_path: str) -> int: if hi_rva > size_of_image: hi_rva = size_of_image _tb_wr_u64(d.FuncBuf, sizet(fkept) * TB_FUNC_SIZE, lo_rva) _tb_wr_u64(d.FuncBuf, sizet(fkept) * TB_FUNC_SIZE + 8, hi_rva) - _tb_wr_u64(d.FuncBuf, sizet(fkept) * TB_FUNC_SIZE + 16, - _tb_rd_u64(d.FuncBuf, sizet(fi) * TB_FUNC_SIZE + 16)) + _tb_wr_u64(d.FuncBuf, sizet(fkept) * TB_FUNC_SIZE + 16, _tb_rd_u64(d.FuncBuf, sizet(fi) * TB_FUNC_SIZE + 16)) fkept += 1 fi += 1 ftmp: bytes = mb.alloc(TB_FUNC_SIZE) @@ -2582,8 +2516,7 @@ def WriteStackMap(mb: memhub.MemBuddy*, exe_path: str) -> int: fk: int = fj while fk > 0: if _tb_rd_u64(d.FuncBuf, sizet(fk - 1) * TB_FUNC_SIZE) <= _tb_rd_u64(ftmp, 0): break - string.memcpy(d.FuncBuf + sizet(fk) * TB_FUNC_SIZE, - d.FuncBuf + sizet(fk - 1) * TB_FUNC_SIZE, TB_FUNC_SIZE) + string.memcpy(d.FuncBuf + sizet(fk) * TB_FUNC_SIZE, d.FuncBuf + sizet(fk - 1) * TB_FUNC_SIZE, TB_FUNC_SIZE) fk -= 1 string.memcpy(d.FuncBuf + sizet(fk) * TB_FUNC_SIZE, ftmp, TB_FUNC_SIZE) fj += 1 @@ -2714,11 +2647,7 @@ def WriteStackMap(mb: memhub.MemBuddy*, exe_path: str) -> int: return 0 -def run_pipeline(ir_buf: bytes, ir_len: sizet, - temp_dir: str, output_dir: str, module_name: str, - cc_cmd: str, cc_flags: str, - linker_cmd: str, linker_flags: str, linker_output: str, - includes_binary_dir: str, linker_static_libs: str = None, linker_dynamic_libs: str = None) -> BuildResult*: +def run_pipeline(ir_buf: bytes, ir_len: sizet, temp_dir: str, output_dir: str, module_name: str, cc_cmd: str, cc_flags: str, linker_cmd: str, linker_flags: str, linker_output: str, includes_binary_dir: str, linker_static_libs: str = None, linker_dynamic_libs: str = None) -> BuildResult*: """执行完整编译管线 Args: @@ -2767,8 +2696,7 @@ def run_pipeline(ir_buf: bytes, ir_len: sizet, return result # Step 3: clang++ 链接 .obj → .exe(附加 includes.binary 预编译 .obj 与 static_libs/dynamic_libs) - ret = link_obj_to_exe(output_dir, module_name, linker_cmd, linker_flags, linker_output, - includes_binary_dir, linker_static_libs, linker_dynamic_libs) + ret = link_obj_to_exe(output_dir, module_name, linker_cmd, linker_flags, linker_output, includes_binary_dir, linker_static_libs, linker_dynamic_libs) if ret != 0: result.Success = 0 result.ErrorMsg = "链接失败" diff --git a/App/lib/Phase/Phase1/Phase1Main.vp b/App/lib/Phase/Phase1/Phase1Main.vp index 19751e5..8ba3a44 100644 --- a/App/lib/Phase/Phase1/Phase1Main.vp +++ b/App/lib/Phase/Phase1/Phase1Main.vp @@ -36,8 +36,7 @@ import lib.core.Gen.DebugInfoGen as DebugInfoGen # 注入 _list/_dict 前检查被注入模块自身的依赖是否已含当前模块,命中(如 memhub↔_list)则跳过注入—— # 否则 Phase A 多遍收敛死锁("无法完成翻译");去掉环边后 _list 仍因当前模块被其依赖而处于闭包,list 类仍由 Phase1b 注册。 # ============================================================ -def _InjectedCreatesCycle(entry: rawptr[IncludesScanner.FileEntry], - mod_name: str) -> int: +def _InjectedCreatesCycle(entry: rawptr[IncludesScanner.FileEntry], mod_name: str) -> int: """注入 mod_name 到当前模块前检查是否成环,返回 1=成环需跳过注入""" if entry is None or entry.RelPath is None or mod_name is None: return 0 inj_sha1: str = StubMergerStore.LookupSha1ByModName(mod_name) @@ -202,8 +201,7 @@ def _BreakContainerCyclesInDeps(temp_dir: str) -> int: # Args: mb 内存池;includes_dir includes 根目录(仅用于失败诊断,路径以 store 为准) # Returns: ScanResult 指针(stdlib 分配,调用方负责释放);失败返回 None # ============================================================ -def _BuildReachableResult(mb: memhub.MemBuddy*, - includes_dir: str) -> rawptr[IncludesScanner.ScanResult]: +def _BuildReachableResult(mb: memhub.MemBuddy*, includes_dir: str) -> rawptr[IncludesScanner.ScanResult]: """从 Sha1Store(仅可达 includes + App)构建可达 FileEntry 列表""" if mb is None: return None store_count: sizet = sizet(StubMerger._sha1_store_count) @@ -277,8 +275,7 @@ def _BuildReachableResult(mb: memhub.MemBuddy*, # Args: mb 内存池;includes_dir includes 目录路径;temp_dir 临时目录(保存 stub);log 日志器 # Returns: 0 成功,非 0 失败 # ============================================================ -def RunPhase1(mb: memhub.MemBuddy*, includes_dir: str, temp_dir: str, - log: rawptr[VLogger.Logger]) -> int: +def RunPhase1(mb: memhub.MemBuddy*, includes_dir: str, temp_dir: str, log: rawptr[VLogger.Logger]) -> int: """Phase1: 扫描 includes 目录,按需翻译并生成 stub""" if includes_dir is None or temp_dir is None: VLogger.error("includes_dir 或 temp_dir 为空,无法运行 Phase1", "Phase1") @@ -310,8 +307,7 @@ def RunPhase1(mb: memhub.MemBuddy*, includes_dir: str, temp_dir: str, reachable_set = stdlib.malloc(StubMerger.MAX_INCLUDES_SHA1 * 17) if reachable_set is not None: string.memset(reachable_set, 0, StubMerger.MAX_INCLUDES_SHA1 * 17) - reachable_count = StubMergerBuild._BuildReachableSha1Set( - mb, Config.SourceDir, temp_dir, reachable_set, None, includes_dir) + reachable_count = StubMergerBuild._BuildReachableSha1Set(mb, Config.SourceDir, temp_dir, reachable_set, None, includes_dir) if reachable_count < 0: VLogger.error("可达集合构建失败(依赖图扫描失败),终止编译", "Phase1") return 1 @@ -387,14 +383,8 @@ def RunPhase1(mb: memhub.MemBuddy*, includes_dir: str, temp_dir: str, p1_base_addr: uint64 = uint64(mb.base) p1_usable_addr: uint64 = uint64(mb.usable) p1_chkbase_addr: uint64 = uint64(mb.chk_base) - VLogger.info( - f"[取证] mb={p1_mb_addr} base={p1_base_addr} usable={p1_usable_addr} " - f"usable_size={mb.usable_size} max_order={mb.max_order} self_check={p1_sc} " - f"detection={mb.detection}", "Phase1") - VLogger.info( - f"[取证] chk_base={p1_chkbase_addr} chk_depth={mb.chk_depth} " - f"chk_cap={mb.chk_cap} free_lists[clamp={p1_mo}]={p1_fl_head}", - "Phase1") + VLogger.info(f"[取证] mb={p1_mb_addr} base={p1_base_addr} usable={p1_usable_addr} " f"usable_size={mb.usable_size} max_order={mb.max_order} self_check={p1_sc} " f"detection={mb.detection}", "Phase1") + VLogger.info(f"[取证] chk_base={p1_chkbase_addr} chk_depth={mb.chk_depth} " f"chk_cap={mb.chk_cap} free_lists[clamp={p1_mo}]={p1_fl_head}", "Phase1") p1_sz_cn: sizet = sizet(Phase1.MAX_CLASSES * Phase1.CLASS_NAME_LEN) p1_sz_ds: sizet = sizet(Phase1.MAX_CLASSES * Phase1.SHA1_LEN) p1_sz_tp: sizet = sizet(4 * Phase1.MAX_FILE_DEPS) @@ -405,13 +395,7 @@ def RunPhase1(mb: memhub.MemBuddy*, includes_dir: str, temp_dir: str, p1_o_bx: int = mb._order_for_size(p1_sz_bx + 16) p1_fl_cn: uint64 = uint64(mb.free_lists[p1_o_cn]) p1_fl_ds: uint64 = uint64(mb.free_lists[p1_o_ds]) - VLogger.info( - f"[取证] order(class_names {p1_sz_cn}B+16)={p1_o_cn} fl={p1_fl_cn} " - f"order(def_sha1s {p1_sz_ds}B+16)={p1_o_ds} fl={p1_fl_ds} " - f"order(topo {p1_sz_tp}B+16)={p1_o_tp} order(box {p1_sz_bx}B+16)={p1_o_bx} " - f"(fl==0 只说明该阶空、仍可由更高阶拆分;若 alloc 失败而 dump_stats 的 free>0 才是元数据损坏铁证," - f"任一 order>max_order={mb.max_order} 则是 size 异常)", - "Phase1") + VLogger.info(f"[取证] order(class_names {p1_sz_cn}B+16)={p1_o_cn} fl={p1_fl_cn} " f"order(def_sha1s {p1_sz_ds}B+16)={p1_o_ds} fl={p1_fl_ds} " f"order(topo {p1_sz_tp}B+16)={p1_o_tp} order(box {p1_sz_bx}B+16)={p1_o_bx} " f"(fl==0 只说明该阶空、仍可由更高阶拆分;若 alloc 失败而 dump_stats 的 free>0 才是元数据损坏铁证," f"任一 order>max_order={mb.max_order} 则是 size 异常)", "Phase1") # 预扫描类继承关系,构建拓扑顺序(用扁平字节数组,避免结构体 str 指针 NULL 崩溃) class_names_buf: bytes = mb.alloc(Phase1.MAX_CLASSES * Phase1.CLASS_NAME_LEN) @@ -440,20 +424,11 @@ def RunPhase1(mb: memhub.MemBuddy*, includes_dir: str, temp_dir: str, if generic_file_indices is not None: string.memset(generic_file_indices, 0, 4 * Phase1.MAX_FILE_DEPS) if generic_file_count_box is not None: string.memset(generic_file_count_box, 0, 4) - class_count_scanned: int = Phase1Scan._ScanClassInheritance( - mb, result, reachable_set, reachable_count, - use_reachable, sha1_set, set_count, - class_names_buf, parent_names_buf, def_sha1s_buf, - generic_file_indices, generic_file_count_box) + class_count_scanned: int = Phase1Scan._ScanClassInheritance(mb, result, reachable_set, reachable_count, use_reachable, sha1_set, set_count, class_names_buf, parent_names_buf, def_sha1s_buf, generic_file_indices, generic_file_count_box) if class_count_scanned > 0: td_len_ts_call: sizet = string.strlen(temp_dir) - ret_topo: int = Phase1Topo._TopoSortFiles( - mb, result, reachable_set, reachable_count, - use_reachable, sha1_set, set_count, - class_names_buf, parent_names_buf, def_sha1s_buf, class_count_scanned, - topo_order, topo_count_box, - temp_dir, td_len_ts_call) + ret_topo: int = Phase1Topo._TopoSortFiles(mb, result, reachable_set, reachable_count, use_reachable, sha1_set, set_count, class_names_buf, parent_names_buf, def_sha1s_buf, class_count_scanned, topo_order, topo_count_box, temp_dir, td_len_ts_call) if ret_topo == 0: tc_ptr: t.CPtr = (int*)(topo_count_box) if tc_ptr is not None: topo_count = tc_ptr[0] @@ -949,8 +924,7 @@ def RunPhase1(mb: memhub.MemBuddy*, includes_dir: str, temp_dir: str, if vpi_exists_1b == 0: pyi_buf: bytes = stdlib.malloc(Phase1.PYI_BUF_SIZE) if pyi_buf is not None: - pyi_pos: sizet = StubConverter._GeneratePyiFromAst( - mb, tree, entry.Path, pyi_buf, Phase1.PYI_BUF_SIZE) + pyi_pos: sizet = StubConverter._GeneratePyiFromAst(mb, tree, entry.Path, pyi_buf, Phase1.PYI_BUF_SIZE) if pyi_pos > 0: pf_1b: rawptr[fileio.File] = fileio.File(vpi_path_1b, fileio.MODE.W) if not pf_1b.closed: diff --git a/App/lib/Phase/Phase1/Phase1Scan.vp b/App/lib/Phase/Phase1/Phase1Scan.vp index 3ef0821..06fd3bc 100644 --- a/App/lib/Phase/Phase1/Phase1Scan.vp +++ b/App/lib/Phase/Phase1/Phase1Scan.vp @@ -53,16 +53,7 @@ import lib.core.Gen.GenApi as GenApi # parent_names_buf 父类名扁平数组(每个 Phase1.CLASS_NAME_LEN 字节,无父类填 '\0');def_sha1s_buf 定义 SHA1 扁平数组(每个 Phase1.SHA1_LEN 字节) # Returns: 收集到的类数量,-1 失败 # ============================================================ -def _ScanClassInheritance(mb: memhub.MemBuddy*, - result: rawptr[IncludesScanner.ScanResult], - reachable_set: str, reachable_count: int, - use_reachable: int, - sha1_set: str, set_count: int, - class_names_buf: bytes, - parent_names_buf: bytes, - def_sha1s_buf: bytes, - generic_file_indices: t.CPtr, - generic_file_count_box: t.CPtr) -> int: +def _ScanClassInheritance(mb: memhub.MemBuddy*, result: rawptr[IncludesScanner.ScanResult], reachable_set: str, reachable_count: int, use_reachable: int, sha1_set: str, set_count: int, class_names_buf: bytes, parent_names_buf: bytes, def_sha1s_buf: bytes, generic_file_indices: t.CPtr, generic_file_count_box: t.CPtr) -> int: """预扫描 includes 文件,收集类继承关系""" if result is None: return -1 # class_names_buf/parent_names_buf/def_sha1s_buf 由调用方 mb.alloc 分配(Phase1Main 预扫描前),本函数把其地址直接作为 strcpy 目的缓冲; @@ -208,12 +199,8 @@ def _BufHasGenericClassMarker(buf: bytes, blen: sizet) -> int: # 跳过空白 while p < blen and(buf[p] == ' ' or buf[p] == '\t'): p += 1 # 读类名标识符 - if p < blen and((buf[p] >= 'a' and buf[p] <= 'z') - or(buf[p] >= 'A' and buf[p] <= 'Z') or buf[p] == '_'): - while p < blen and((buf[p] >= 'a' and buf[p] <= 'z') - or(buf[p] >= 'A' and buf[p] <= 'Z') - or(buf[p] >= '0' and buf[p] <= '9') - or buf[p] == '_'): + if p < blen and((buf[p] >= 'a' and buf[p] <= 'z') or(buf[p] >= 'A' and buf[p] <= 'Z') or buf[p] == '_'): + while p < blen and((buf[p] >= 'a' and buf[p] <= 'z') or(buf[p] >= 'A' and buf[p] <= 'Z') or(buf[p] >= '0' and buf[p] <= '9') or buf[p] == '_'): p += 1 # 类名后非空白是 '[' → 泛型类 while p < blen and(buf[p] == ' ' or buf[p] == '\t'): p += 1 @@ -245,12 +232,8 @@ def _BufHasGenericFuncMarker(buf: bytes, blen: sizet) -> int: # 跳过空白 while p < blen and(buf[p] == ' ' or buf[p] == '\t'): p += 1 # 读函数名标识符 - if p < blen and((buf[p] >= 'a' and buf[p] <= 'z') - or(buf[p] >= 'A' and buf[p] <= 'Z') or buf[p] == '_'): - while p < blen and((buf[p] >= 'a' and buf[p] <= 'z') - or(buf[p] >= 'A' and buf[p] <= 'Z') - or(buf[p] >= '0' and buf[p] <= '9') - or buf[p] == '_'): + if p < blen and((buf[p] >= 'a' and buf[p] <= 'z') or(buf[p] >= 'A' and buf[p] <= 'Z') or buf[p] == '_'): + while p < blen and((buf[p] >= 'a' and buf[p] <= 'z') or(buf[p] >= 'A' and buf[p] <= 'Z') or(buf[p] >= '0' and buf[p] <= '9') or buf[p] == '_'): p += 1 # 函数名后非空白是 '[' → 泛型函数 while p < blen and(buf[p] == ' ' or buf[p] == '\t'): p += 1 @@ -266,8 +249,7 @@ def _BufHasGenericFuncMarker(buf: bytes, blen: sizet) -> int: # _find_generic_template 遍历悬空内存 strcmp 崩溃。本函数先文本扫描(_BufHasGenericClassMarker,不 parse)筛选出含泛型类的文件, # 仅对命中文件用**永久池(perm_pool)**解析(模板节点与表直接进 perm_pool,跨 mark 永久存活、不占主 pool);重复注册由 _register_generic_template 内部查重跳过。 # ============================================================ -def _PreRegisterAllGenericTemplates(mb: memhub.MemBuddy*, - result: rawptr[IncludesScanner.ScanResult]) -> int: +def _PreRegisterAllGenericTemplates(mb: memhub.MemBuddy*, result: rawptr[IncludesScanner.ScanResult]) -> int: """预注册全部 includes 文件的泛型类模板,返回处理到的泛型类数量""" if result is None or mb is None: return 0 perm: memhub.MemBuddy* = CompilerFactory.factory.PermPool @@ -276,8 +258,7 @@ def _PreRegisterAllGenericTemplates(mb: memhub.MemBuddy*, handled_count: int = 0 for i in range(result.Count): entry_addr_pg: uint64 = uint64(result.Entries) + i * p1e_size - entry_pg: rawptr[IncludesScanner.FileEntry] = ( - rawptr[IncludesScanner.FileEntry])(entry_addr_pg) + entry_pg: rawptr[IncludesScanner.FileEntry] = (rawptr[IncludesScanner.FileEntry])(entry_addr_pg) if entry_pg is None or entry_pg.Sha1 is None: continue # 读取文件 file_path_pg: str = entry_pg.Path @@ -348,8 +329,7 @@ def _PreRegisterAllGenericTemplates(mb: memhub.MemBuddy*, # Args: class_names_buf 类名扁平数组;def_sha1s_buf 定义 SHA1 扁平数组;class_count 类数量;class_name 要查找的类名 # Returns: SHA1 字符串指针(指向 def_sha1s_buf 内部偏移),None 未找到 # ============================================================ -def _FindClassDefSha1(class_names_buf: bytes, def_sha1s_buf: bytes, - class_count: int, class_name: str) -> str: +def _FindClassDefSha1(class_names_buf: bytes, def_sha1s_buf: bytes, class_count: int, class_name: str) -> str: """查找类名对应的定义文件 SHA1""" if class_names_buf is None or def_sha1s_buf is None or class_name is None: return None for i in range(class_count): @@ -385,10 +365,7 @@ def _AnnIsContainer(ann: ast.AST*) -> int: return 0 -def _ScanTreeForContainers(node: ast.AST*, - need_list_box: t.CPtr, - need_dict_box: t.CPtr, - depth: int = 0): +def _ScanTreeForContainers(node: ast.AST*, need_list_box: t.CPtr, need_dict_box: t.CPtr, depth: int = 0): """递归扫描 AST(字段 + 语句块),检测 list/dict 容器使用""" # 递归深度守卫:AST 损坏成自引用环(字段/children 回指祖先)时无限 # 递归直至栈耗尽(每个 includes 文件 parse 后必执行)。fail-fast 终止。 diff --git a/App/lib/Phase/Phase1/Phase1Topo.vp b/App/lib/Phase/Phase1/Phase1Topo.vp index e13ddf1..af91dad 100644 --- a/App/lib/Phase/Phase1/Phase1Topo.vp +++ b/App/lib/Phase/Phase1/Phase1Topo.vp @@ -45,15 +45,7 @@ import lib.Phase.Phase1 as Phase1 # class_count 类数量;out_order 输出拓扑顺序的文件索引数组(调用者分配,int 数组);out_count 输出文件数量 # Returns: 0 成功,-1 失败 # ============================================================ -def _TopoSortFiles(mb: memhub.MemBuddy*, - result: rawptr[IncludesScanner.ScanResult], - reachable_set: str, reachable_count: int, - use_reachable: int, - sha1_set: str, set_count: int, - class_names_buf: bytes, parent_names_buf: bytes, - def_sha1s_buf: bytes, class_count: int, - out_order: t.CPtr, out_count: t.CPtr, - temp_dir: str, td_len_ts: sizet) -> int: +def _TopoSortFiles(mb: memhub.MemBuddy*, result: rawptr[IncludesScanner.ScanResult], reachable_set: str, reachable_count: int, use_reachable: int, sha1_set: str, set_count: int, class_names_buf: bytes, parent_names_buf: bytes, def_sha1s_buf: bytes, class_count: int, out_order: t.CPtr, out_count: t.CPtr, temp_dir: str, td_len_ts: sizet) -> int: """根据类继承关系对文件进行拓扑排序""" if result is None or out_order is None or out_count is None: return -1 @@ -155,8 +147,7 @@ def _TopoSortFiles(mb: memhub.MemBuddy*, mod_arr_ts: bytes = stdlib.malloc(StubMerger.MAX_INCLUDES * 64) map_count_ts: int = 0 if sha1_arr_ts is not None and mod_arr_ts is not None: - map_count_ts = StubMergerIR._BuildIncludesSha1Map( - temp_dir, td_len_ts, sha1_arr_ts, mod_arr_ts) + map_count_ts = StubMergerIR._BuildIncludesSha1Map(temp_dir, td_len_ts, sha1_arr_ts, mod_arr_ts) for fi_imp in range(file_count): if map_count_ts <= 0: break fsha1_imp: str = file_sha1s_buf + fi_imp * Phase1.SHA1_LEN @@ -174,8 +165,7 @@ def _TopoSortFiles(mb: memhub.MemBuddy*, if dname_imp is None: continue string.strncpy(dname_imp, deps_imp + dstart_imp, dlen_imp) dname_imp[dlen_imp] = '\0' - dsha1_imp: str = StubMergerIR._FindSha1ByModName( - sha1_arr_ts, mod_arr_ts, map_count_ts, dname_imp) + dsha1_imp: str = StubMergerIR._FindSha1ByModName(sha1_arr_ts, mod_arr_ts, map_count_ts, dname_imp) stdlib.free(dname_imp) if dsha1_imp is None: continue # 找依赖文件在列表中的索引(跳过自身) diff --git a/App/lib/Phase/Phase2/__init__.vp b/App/lib/Phase/Phase2/__init__.vp index 53a705e..017d78b 100644 --- a/App/lib/Phase/Phase2/__init__.vp +++ b/App/lib/Phase/Phase2/__init__.vp @@ -50,11 +50,7 @@ class SrcFileEntry: # Args: mb 内存池;dir_path 当前扫描目录;entries SrcFileEntry 数组;entry_size 单个条目大小(SrcFileEntry.__sizeof__());file_count 当前已收集的文件数;max_files 最大文件数 # Returns: 新的 file_count # ============================================================ -def _ScanDirForPyFiles(mb: memhub.MemBuddy*, - dir_path: str, - entries: SrcFileEntry*, - entry_size: sizet, - file_count: int, max_files: int) -> int: +def _ScanDirForPyFiles(mb: memhub.MemBuddy*, dir_path: str, entries: SrcFileEntry*, entry_size: sizet, file_count: int, max_files: int) -> int: """递归扫描目录,收集 .vp/.py 文件到 entries,返回新的 file_count""" if dir_path is None or entries is None: return file_count if file_count >= max_files: return file_count @@ -143,11 +139,7 @@ def _ScanDirForPyFiles(mb: memhub.MemBuddy*, # Kernel/intr/isr.s 定义 isr0/syscall_entry/_per_cpu 等符号)。 # TPV 不对 .s 翻译,直接用 llvm-mc 汇编为 .obj 参与链接。 # ============================================================ -def _ScanDirForAsmFiles(mb: memhub.MemBuddy*, - dir_path: str, - entries: SrcFileEntry*, - entry_size: sizet, - file_count: int, max_files: int) -> int: +def _ScanDirForAsmFiles(mb: memhub.MemBuddy*, dir_path: str, entries: SrcFileEntry*, entry_size: sizet, file_count: int, max_files: int) -> int: """递归扫描目录,收集 .s 汇编文件到 entries,返回新的 file_count""" if dir_path is None or entries is None: return file_count if file_count >= max_files: return file_count @@ -231,10 +223,7 @@ def _ScanDirForAsmFiles(mb: memhub.MemBuddy*, # 才首次注册,reset_to(mark2) 会回收表与节点 → 后续查重/特化遍历悬空内存崩溃;App 文件数量少,mark2 前预注册的 AST 驻留内存可忽略。 # 重复注册由 _register_generic_template 查重跳过。 # ============================================================ -def _PreRegisterAppGenericTemplates(mb: memhub.MemBuddy*, - entries: SrcFileEntry*, - file_count: int, - entry_size: sizet) -> int: +def _PreRegisterAppGenericTemplates(mb: memhub.MemBuddy*, entries: SrcFileEntry*, file_count: int, entry_size: sizet) -> int: """mark2 前预注册 App 源文件的泛型类模板,返回处理到的泛型类数量""" if mb is None or entries is None or file_count <= 0: return 0 handled: int = 0 @@ -429,8 +418,7 @@ def _PhaseAResolveDepSha1(mod_name: str) -> str: return StubMergerStore.LookupSha1ByModNameSuffix(mod_name) -def _PhaseADumpNode(temp_dir: str, td_len: sizet, sha1: str, - depth: int, prefix: bytes) -> None: +def _PhaseADumpNode(temp_dir: str, td_len: sizet, sha1: str, depth: int, prefix: bytes) -> None: """递归打印依赖子图;[MISS]=缺 text.ll(下钻整链),[OK]=就绪(仅探测 1 层)""" deps: bytes = None if sha1 is not None: deps = _PhaseADiagDepsLookup(sha1) @@ -532,8 +520,7 @@ def _PhaseADumpFailGraph(temp_dir: str, td_len: sizet, path: str, sha1: str) -> if miss[0] != 0: stdio.printf("[PhaseA-Fail] pending reason: %s\n", miss) stdlib.free(miss) stdio.fflush(None) - stdio.printf("[PhaseA-Fail] dep graph ([MISS]=missing text.ll, [OK]=ready, depth<=%d):\n", - PA_GRAPH_DEPTH_MAX) + stdio.printf("[PhaseA-Fail] dep graph ([MISS]=missing text.ll, [OK]=ready, depth<=%d):\n", PA_GRAPH_DEPTH_MAX) stdio.fflush(None) root_prefix: bytes = stdlib.malloc(1) if root_prefix is not None: @@ -543,17 +530,7 @@ def _PhaseADumpFailGraph(temp_dir: str, td_len: sizet, path: str, sha1: str) -> stdio.fflush(None) -def RunMultiFileProject(mb: 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, - includes_binary_dir: str, - includes_dir: str, - do_phase1: int, do_phase2: int, - log: rawptr[VLogger.Logger], - args: rawptr[argparse.ParsedArgs], - linker_static_libs: str = None, - linker_dynamic_libs: str = None) -> int: +def RunMultiFileProject(mb: 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, includes_binary_dir: str, includes_dir: str, do_phase1: int, do_phase2: int, log: rawptr[VLogger.Logger], args: rawptr[argparse.ParsedArgs], linker_static_libs: str = None, linker_dynamic_libs: str = None) -> int: """多文件项目编译 Returns: 0 成功,非 0 失败 @@ -615,8 +592,7 @@ def RunMultiFileProject(mb: memhub.MemBuddy*, if rs_05 is None: VLogger.error("reachable_set 分配失败,无法填充 Sha1Store", "project") else: string.memset(rs_05, 0, StubMerger.MAX_INCLUDES_SHA1 * 17) - rc_05: int = StubMergerBuild._BuildReachableSha1Set( - mb, source_dir, temp_dir, rs_05, None, includes_dir) + rc_05: int = StubMergerBuild._BuildReachableSha1Set(mb, source_dir, temp_dir, rs_05, None, includes_dir) if rc_05 < 0: VLogger.error("依赖图扫描失败,无法填充 Sha1Store", "project") elif rc_05 > 0: VLogger.info(f"Phase2 依赖图按需填充 Sha1Store: {rc_05} 个", "project") stdlib.free(rs_05) @@ -740,8 +716,7 @@ def RunMultiFileProject(mb: memhub.MemBuddy*, continue pyi_buf_vp2: bytes = stdlib.malloc(PYI_BUF_SIZE_P2) if pyi_buf_vp2 is not None: - pyi_pos_vp2: sizet = StubConverter._GeneratePyiFromAst( - mb, tree_vp2, ent_vp2.Path, pyi_buf_vp2, PYI_BUF_SIZE_P2) + pyi_pos_vp2: sizet = StubConverter._GeneratePyiFromAst(mb, tree_vp2, ent_vp2.Path, pyi_buf_vp2, PYI_BUF_SIZE_P2) if pyi_pos_vp2 > 0: pyi_path_vp2: str = StubMergerCollect._sliced_path(temp_dir, td_len_vpa, ent_vp2.Sha1, "vpi") if pyi_path_vp2 is not None: @@ -815,11 +790,9 @@ def RunMultiFileProject(mb: memhub.MemBuddy*, incdir_len_pre: sizet = string.strlen(incdir_pre) full_path_pre: bytes = stdlib.malloc(incdir_len_pre + rel_len_pre + 2) if full_path_pre is None: continue - viperlib.snprintf(full_path_pre, incdir_len_pre + rel_len_pre + 2, - "%s/%s", incdir_pre, inc_rel_pre) + viperlib.snprintf(full_path_pre, incdir_len_pre + rel_len_pre + 2, "%s/%s", incdir_pre, inc_rel_pre) pkg_inc_pre: str = GenApi.compute_package_from_relpath(mb, inc_rel_pre) - tr_inc_pre: rawptr[HandlesTranslator.Translator] = BuildPipeline.TranslateFileGetTrans( - mb, full_path_pre, inc_sha1_pre, pkg_inc_pre, 1) + tr_inc_pre: rawptr[HandlesTranslator.Translator] = BuildPipeline.TranslateFileGetTrans(mb, full_path_pre, inc_sha1_pre, pkg_inc_pre, 1) stdlib.free(full_path_pre) if tr_inc_pre is not None: # 记录本文件依赖(供收敛失败依赖图诊断;stdlib 表跨 reset 存活) @@ -828,8 +801,7 @@ def RunMultiFileProject(mb: memhub.MemBuddy*, if inc_fail_flags is not None: inc_fail_flags[si_inc] = 0 # 依赖填充只在第一遍执行(PopulateIncludesDeps 内部有去重) # 注意:必须在 reset_to(mark2) 之前调用——内部深拷贝到 stdlib - if pass_inc_i == 0 and tr_inc_pre._imported_modules is not None and StubMergerStore.PopulateIncludesDeps( - inc_sha1_pre, tr_inc_pre._imported_modules) == 0: + if pass_inc_i == 0 and tr_inc_pre._imported_modules is not None and StubMergerStore.PopulateIncludesDeps(inc_sha1_pre, tr_inc_pre._imported_modules) == 0: deps_filled_pre = deps_filled_pre + 1 # OOM 清理:回收本 includes 文件预注册翻译的瞬时数据 # (AST/tokens/lexer/IR/Handler);struct 注册表条目 stdlib 分配不受影响 @@ -866,8 +838,7 @@ def RunMultiFileProject(mb: memhub.MemBuddy*, # 使类字段注解在预注册期即与阶段 A 同上下文(否则包重导出类 # list[ast.ClassDef*] 的票名前缀会在预注册期被冻结成包前缀,与阶段 A # 解析出的真定义前缀分裂 → 结构体布局不兼容,见 Translator 字段说明)。 - tr_pre: rawptr[HandlesTranslator.Translator] = BuildPipeline.TranslateFileGetTrans( - mb, ent_pre.Path, ent_pre.Sha1, pkg_pre, 1, None, 1) + tr_pre: rawptr[HandlesTranslator.Translator] = BuildPipeline.TranslateFileGetTrans(mb, ent_pre.Path, ent_pre.Sha1, pkg_pre, 1, None, 1) if tr_pre is None: VLogger.error(f"预注册失败: {ent_pre.Path}", "PhaseA") # OOM 清理:回收本 App 文件预注册翻译的瞬时数据 mb.reset_to(mark2) @@ -1134,8 +1105,7 @@ def RunMultiFileProject(mb: memhub.MemBuddy*, VLogger.error("llc 输入路径构造失败", "PhaseB") sys.exit(1) tslot: rawptr[BuildPipeline.LlcTask] = rawptr[BuildPipeline.LlcTask](uint64(llc_tasks) + sizet(llc_task_count) * BuildPipeline.LlcTask.__sizeof__()) - if BuildPipeline.init_llc_task(tslot, llc_ir_path, output_dir, ent.Sha1, - cc_cmd, cc_flags) != 0: + if BuildPipeline.init_llc_task(tslot, llc_ir_path, output_dir, ent.Sha1, cc_cmd, cc_flags) != 0: VLogger.error(f"llc 任务构造失败: {ent.Path}", "PhaseB") sys.exit(1) # 计时点 3:llc 任务构造完成 @@ -1172,8 +1142,7 @@ def RunMultiFileProject(mb: memhub.MemBuddy*, stdlib.free(obj_path_sliced) # 并行执行全部 llc(分批 LLC_MAX_THREADS 线程) - ret_p: int = BuildPipeline.run_llc_parallel(llc_tasks, llc_task_count, - BuildPipeline.LLC_MAX_THREADS) + ret_p: int = BuildPipeline.run_llc_parallel(llc_tasks, llc_task_count, BuildPipeline.LLC_MAX_THREADS) if ret_p != 0: VLogger.error("llc 编译失败,终止编译", "PhaseB") sys.exit(1) @@ -1194,8 +1163,7 @@ def RunMultiFileProject(mb: memhub.MemBuddy*, ea_as: uint64 = uint64(asm_entries) + ai_as * entry_size ent_as: SrcFileEntry* = (SrcFileEntry*)(ea_as) if ent_as is None or ent_as.Path is None or ent_as.Sha1 is None: continue - aret_as: int = BuildPipeline.asm_to_obj( - ent_as.Path, ent_as.Sha1, output_dir, Config.TargetTriple) + aret_as: int = BuildPipeline.asm_to_obj(ent_as.Path, ent_as.Sha1, output_dir, Config.TargetTriple) if aret_as != 0: VLogger.error(f"llvm-mc 汇编失败,终止编译: {ent_as.Path}", "PhaseB") sys.exit(1) @@ -1245,8 +1213,7 @@ def RunMultiFileProject(mb: memhub.MemBuddy*, reachable_count: int = 0 if reachable_set is not None: string.memset(reachable_set, 0, REACHABLE_SET_SIZE) - reachable_count = StubMergerBuild._BuildReachableSha1Set( - mb, source_dir, temp_dir, reachable_set, app_deps_buf, includes_dir) + reachable_count = StubMergerBuild._BuildReachableSha1Set(mb, source_dir, temp_dir, reachable_set, app_deps_buf, includes_dir) VLogger.info(f"可达 includes SHA1: {reachable_count} 个", "PhaseB+") # fast-fail: 可达集合构建失败(依赖未找到),永不回退,直接终止 if reachable_count < 0: @@ -1268,8 +1235,7 @@ def RunMultiFileProject(mb: memhub.MemBuddy*, store_mod_arr_mi: bytes = stdlib.malloc(StubMerger.MAX_INCLUDES * 64) store_count_mi: int = 0 if store_sha1_arr_mi is not None and store_mod_arr_mi is not None: - store_count_mi = StubMergerIR._BuildIncludesSha1Map( - temp_dir, td_len_pb, store_sha1_arr_mi, store_mod_arr_mi) + store_count_mi = StubMergerIR._BuildIncludesSha1Map(temp_dir, td_len_pb, store_sha1_arr_mi, store_mod_arr_mi) store_rel_arr_mi: bytes = StubMergerStore.GetSha1StoreRelArrPtr() store_incdir_arr_mi: bytes = StubMergerStore.GetSha1StoreIncdirArrPtr() if store_count_mi > 0: @@ -1282,9 +1248,7 @@ def RunMultiFileProject(mb: memhub.MemBuddy*, VLogger.error("拓扑排序索引分配失败,终止编译", "PhaseB+") topo_count = 0 else: - topo_count = StubMergerTopo.BuildTopoSortedIndices( - store_count_mi, store_sha1_arr_mi, store_mod_arr_mi, - reachable_set, reachable_count, topo_idx) + topo_count = StubMergerTopo.BuildTopoSortedIndices(store_count_mi, store_sha1_arr_mi, store_mod_arr_mi, reachable_set, reachable_count, topo_idx) for si_mi in range(topo_count): # 当前条目(拓扑序索引,仅含可达模块) @@ -1450,9 +1414,7 @@ def RunMultiFileProject(mb: memhub.MemBuddy*, continue # 编译为 .obj(输出到 includes_binary_dir,与存在性检查和链接收集一致) - inc_cret_mi: int = BuildPipeline.compile_module_to_obj( - inc_combined_mi, inc_combined_len_mi, temp_dir, includes_binary_dir, inc_sha1_mi, - cc_cmd, cc_flags) + inc_cret_mi: int = BuildPipeline.compile_module_to_obj(inc_combined_mi, inc_combined_len_mi, temp_dir, includes_binary_dir, inc_sha1_mi, cc_cmd, cc_flags) stdlib.free(inc_combined_mi) if inc_cret_mi != 0: @@ -1594,10 +1556,7 @@ def RunMultiFileProject(mb: memhub.MemBuddy*, reachable_set = None # 按图链接:不传 includes_binary_dir(传 None),避免全量收集 - lret: int = BuildPipeline.link_objs_to_exe( - final_obj_paths, obj_paths_len, - linker_cmd, linker_flags, exe_path, - None, linker_static_libs, linker_dynamic_libs) + lret: int = BuildPipeline.link_objs_to_exe(final_obj_paths, obj_paths_len, linker_cmd, linker_flags, exe_path, None, linker_static_libs, linker_dynamic_libs) if lret == 0: VLogger.success(f"输出: {exe_path}", "PhaseC") diff --git a/App/lib/Projectrans/Utils.vp b/App/lib/Projectrans/Utils.vp index f91db8e..1002fc7 100644 --- a/App/lib/Projectrans/Utils.vp +++ b/App/lib/Projectrans/Utils.vp @@ -31,11 +31,7 @@ def nibble_to_hex_char(n: int, uppercase: int) -> char: # ============================================================ # bytes_to_hex - 字节序列转十六进制字符串 # ============================================================ -def bytes_to_hex(pool: memhub.MemBuddy*, - digest: bytes, - nbytes: sizet, - uppercase: int, - use_malloc: int) -> str: +def bytes_to_hex(pool: memhub.MemBuddy*, digest: bytes, nbytes: sizet, uppercase: int, use_malloc: int) -> str: """将 digest 前 nbytes 字节转为 2*nbytes 个十六进制字符(含 null 终止) use_malloc=1 时用 stdlib.malloc(调用方负责 free),否则 pool.alloc。 diff --git a/App/lib/Projectrans/__init__.vp b/App/lib/Projectrans/__init__.vp index 64656ea..50b4cf9 100644 --- a/App/lib/Projectrans/__init__.vp +++ b/App/lib/Projectrans/__init__.vp @@ -4,9 +4,4 @@ from stdint import * from .Config import Load_project_config, resolve_paths from .Utils import compute_sha1, CleanDir -__all__ = [ - 'Load_project_config', - 'resolve_paths', - 'compute_sha1', - 'CleanDir', -] +__all__ = ['Load_project_config', 'resolve_paths', 'compute_sha1', 'CleanDir',] diff --git a/App/lib/Stub/StubGen/Converter.vp b/App/lib/Stub/StubGen/Converter.vp index 0e5ccd4..0f1ddfd 100644 --- a/App/lib/Stub/StubGen/Converter.vp +++ b/App/lib/Stub/StubGen/Converter.vp @@ -153,8 +153,7 @@ def _pyi_cdefine_found() -> int: # 将 text 追加到 buf 的 pos 位置,返回新的 pos。 # 自动处理缓冲区溢出(截断)。 # ============================================================ -def _PyiEmit(buf: bytes, buf_size: sizet, pos: sizet, - text: str) -> sizet: +def _PyiEmit(buf: bytes, buf_size: sizet, pos: sizet, text: str) -> sizet: """追加 text 到 buf 的 pos 位置,返回新的 pos""" if buf is None or text is None or pos >= buf_size: return pos tlen: sizet = string.strlen(text) @@ -170,8 +169,7 @@ def _PyiEmit(buf: bytes, buf_size: sizet, pos: sizet, # # 追加 level*4 个空格到 buf 的 pos 位置。 # ============================================================ -def _PyiIndent(buf: bytes, buf_size: sizet, pos: sizet, - level: int) -> sizet: +def _PyiIndent(buf: bytes, buf_size: sizet, pos: sizet, level: int) -> sizet: """追加 level*4 个空格到 buf,返回新的 pos""" i: int = 0 while i < level: @@ -191,8 +189,7 @@ def _PyiIndent(buf: bytes, buf_size: sizet, pos: sizet, # 表外运算符 fail-fast:静默写错运算符会生成错误的类型/长度文本, # 让下游按错误结果解析(与 TPC 落到未知节点 fail-fast 同语义)。 # ============================================================ -def _PyiBinOpOpText(buf: bytes, buf_size: sizet, pos: sizet, - op: int, node: ast.AST*) -> sizet: +def _PyiBinOpOpText(buf: bytes, buf_size: sizet, pos: sizet, op: int, node: ast.AST*) -> sizet: """按运算符种类输出 " OP " 文本,表外运算符 fail-fast""" if op == ast.OpKind.BitOr: return _PyiEmit(buf, buf_size, pos, " | ") if op == ast.OpKind.Add: return _PyiEmit(buf, buf_size, pos, " + ") @@ -216,9 +213,7 @@ def _PyiBinOpOpText(buf: bytes, buf_size: sizet, pos: sizet, # 差异项:TPV 额外支持裸 Tuple(TPC 仅在 Subscript.slice 位置接受 Tuple); # TPC 额外有 Index 分支(vast 遗留类,解析器不产出该节点)。 # ============================================================ -def _PyiTypeStr(buf: bytes, buf_size: sizet, pos: sizet, - annot: ast.AST*, - depth: int = 0) -> sizet: +def _PyiTypeStr(buf: bytes, buf_size: sizet, pos: sizet, annot: ast.AST*, depth: int = 0) -> sizet: """递归生成类型注解字符串,返回新的 pos""" # 递归深度守卫:AST 损坏成自引用环(Attribute.value/Subscript.slice/ # BinOp.left 等回指祖先)时无限递归直至栈耗尽(Phase1 vpi 生成最先 @@ -404,9 +399,7 @@ def _PyiTypeStr(buf: bytes, buf_size: sizet, pos: sizet, # 用默认值填充,否则被调函数读到栈垃圾(假报递归过深/崩溃)。 # 支持: Constant(int/str/bool/None), Name(CDefine 常量), UnaryOp。 # ============================================================ -def _PyiDefaultStr(buf: bytes, buf_size: sizet, pos: sizet, - node: ast.AST*, - depth: int = 0) -> sizet: +def _PyiDefaultStr(buf: bytes, buf_size: sizet, pos: sizet, node: ast.AST*, depth: int = 0) -> sizet: """生成默认值表达式文本到 buf,返回新的 pos""" # 递归深度守卫:AST 损坏成自引用环时 fail-fast 终止(同 _PyiTypeStr) if depth > 64: @@ -462,8 +455,7 @@ def _PyiDefaultStr(buf: bytes, buf_size: sizet, pos: sizet, # (既有 tuple → struct 通路保留)。vpi 里仍带该装饰器意味着存根过旧, # fail-fast 提示重新生成,不静默忽略。返回 0 = 装饰器列表里没有 CReturn。 # ============================================================ -def _PyiRejectCReturnDecorator(node: ast.AST*, - decorators: list[ast.AST*]*) -> int: +def _PyiRejectCReturnDecorator(node: ast.AST*, decorators: list[ast.AST*]*) -> int: """装饰器列表里出现 @c.CReturn 即 fatal_error(返回 0 = 无该装饰器)""" if decorators is None: return 0 dn: sizet = len(decorators) @@ -490,9 +482,7 @@ def _PyiRejectCReturnDecorator(node: ast.AST*, # # 格式: def name(param: Type, ...) -> ReturnType: pass # ============================================================ -def _PyiFunction(buf: bytes, buf_size: sizet, pos: sizet, - fn: ast.FunctionDef*, - indent_level: int, class_name: str) -> sizet: +def _PyiFunction(buf: bytes, buf_size: sizet, pos: sizet, fn: ast.FunctionDef*, indent_level: int, class_name: str) -> sizet: """生成函数签名到 buf,返回新的 pos""" # 装饰器 if fn.decorator_list is not None: @@ -584,8 +574,7 @@ def _PyiFunction(buf: bytes, buf_size: sizet, pos: sizet, # field: Type # def method(self: Name, ...) -> RetType: pass # ============================================================ -def _PyiClass(buf: bytes, buf_size: sizet, pos: sizet, - cls: ast.ClassDef*, indent_level: int) -> sizet: +def _PyiClass(buf: bytes, buf_size: sizet, pos: sizet, cls: ast.ClassDef*, indent_level: int) -> sizet: """生成类定义到 buf,返回新的 pos""" # 装饰器 if cls.decorator_list is not None: @@ -720,9 +709,7 @@ def _PyiClass(buf: bytes, buf_size: sizet, pos: sizet, # Args: mb 内存池(保留以符合调用约定,实际未使用);tree AST Module 根节点;rel_path 源文件路径(仅用于报错归因的"当前文件",应传绝对路径以便 fatal_error 读取源码行);buf 输出缓冲区;buf_size 缓冲区大小 # Returns: 写入的字节数(0 表示失败) # ============================================================ -def _GeneratePyiFromAst(mb: memhub.MemBuddy*, tree: ast.AST*, - rel_path: str, buf: bytes, - buf_size: sizet) -> sizet: +def _GeneratePyiFromAst(mb: memhub.MemBuddy*, tree: ast.AST*, rel_path: str, buf: bytes, buf_size: sizet) -> sizet: """从 AST 生成 .vpi 存根文件内容到 buf""" if tree is None or buf is None or buf_size == 0: return 0 @@ -822,9 +809,7 @@ def _GeneratePyiFromAst(mb: memhub.MemBuddy*, tree: ast.AST*, # fail-fast:别名列表为空 ⇒ 写出 `import ` 这种残缺行,import 名字 # 全丢,包重导出注册随之失效(与下面逐个别名为空的检查互补)。 if imp2.names is None or len(imp2.names) == 0: - GenApi.fatal_error(stmt, - "vpi 生成:import 语句别名列表为空(应为 ≥1 个别名)——AST 构造/解析异常", - "NameError") + GenApi.fatal_error(stmt, "vpi 生成:import 语句别名列表为空(应为 ≥1 个别名)——AST 构造/解析异常", "NameError") if imp2.names is not None: imp2_names: list[ast.AST*]* = imp2.names an2: sizet = len(imp2_names) @@ -842,15 +827,9 @@ def _GeneratePyiFromAst(mb: memhub.MemBuddy*, tree: ast.AST*, # 两种成因分开报,便于一次定位:节点指针为空 = Alias 构造失败; # 节点在而 name 为空 = _copy_str/__init__ 未生效。 if al2 is None: - GenApi.fatal_error(stmt, - "vpi 生成:import 别名**节点指针为空**(Alias(...) 构造未产出对象:" - "pool.alloc 失败或 __init__ 未执行)——import 名字丢失会破坏包重导出注册", - "NameError") + GenApi.fatal_error(stmt, "vpi 生成:import 别名**节点指针为空**(Alias(...) 构造未产出对象:" "pool.alloc 失败或 __init__ 未执行)——import 名字丢失会破坏包重导出注册", "NameError") if al2.name is None or al2.name[0] == '\0': - GenApi.fatal_error(stmt, - "vpi 生成:import 别名节点存在但 **name 为空**(_copy_str 返回 None / " - "__init__ 未赋值 name)——import 名字丢失会破坏包重导出注册", - "NameError") + GenApi.fatal_error(stmt, "vpi 生成:import 别名节点存在但 **name 为空**(_copy_str 返回 None / " "__init__ 未赋值 name)——import 名字丢失会破坏包重导出注册", "NameError") pos = _PyiEmit(buf, buf_size, pos, al2.name) if al2.asname is not None and string.strlen(al2.asname) > 0: pos = _PyiEmit(buf, buf_size, pos, " as ") @@ -872,10 +851,7 @@ def _GeneratePyiFromAst(mb: memhub.MemBuddy*, tree: ast.AST*, # 列表为空或名字为空都说明 AST 坏;静默写出 `from X import ` 会让 # 包重导出注册失效(star 也用于 re-export 判断)。 if ifr.names is None or len(ifr.names) == 0: - GenApi.fatal_error(stmt, - "vpi 生成:from-import 语句别名列表为空(应为 ≥1 个别名,含 '*')" - "——AST 构造/解析异常", - "NameError") + GenApi.fatal_error(stmt, "vpi 生成:from-import 语句别名列表为空(应为 ≥1 个别名,含 '*')" "——AST 构造/解析异常", "NameError") if ifr.names is not None: ifr_names: list[ast.AST*]* = ifr.names an3: sizet = len(ifr_names) @@ -885,15 +861,9 @@ def _GeneratePyiFromAst(mb: memhub.MemBuddy*, tree: ast.AST*, al3: ast.Alias* = ast.Alias*(ifr_names.get(ai3)) # fail-fast:同 Import 分支(两种成因分开报,一次定位)。 if al3 is None: - GenApi.fatal_error(stmt, - "vpi 生成:from-import 别名**节点指针为空**(Alias(...) 构造未产出对象:" - "pool.alloc 失败或 __init__ 未执行)——包重导出注册会因此失效", - "NameError") + GenApi.fatal_error(stmt, "vpi 生成:from-import 别名**节点指针为空**(Alias(...) 构造未产出对象:" "pool.alloc 失败或 __init__ 未执行)——包重导出注册会因此失效", "NameError") if al3.name is None or al3.name[0] == '\0': - GenApi.fatal_error(stmt, - "vpi 生成:from-import 别名节点存在但 **name 为空**(_copy_str 返回 None / " - "__init__ 未赋值 name)——包重导出注册会因此失效", - "NameError") + GenApi.fatal_error(stmt, "vpi 生成:from-import 别名节点存在但 **name 为空**(_copy_str 返回 None / " "__init__ 未赋值 name)——包重导出注册会因此失效", "NameError") pos = _PyiEmit(buf, buf_size, pos, al3.name) if al3.asname is not None and string.strlen(al3.asname) > 0: pos = _PyiEmit(buf, buf_size, pos, " as ") @@ -958,8 +928,7 @@ def _GeneratePyiFromAst(mb: memhub.MemBuddy*, tree: ast.AST*, # 字符串 CDefine(pyzlib.ZLIB_VERSION = "1.3.2" 等)必须输出值,让 stub 自包含(读回端按目标名判定会回退源文件) sbuf_c: bytes = mb.alloc(string.strlen(cv.str_val) + 6) if sbuf_c is not None: - viperlib.snprintf(sbuf_c, string.strlen(cv.str_val) + 6, - " = \"%s\"", cv.str_val) + viperlib.snprintf(sbuf_c, string.strlen(cv.str_val) + 6, " = \"%s\"", cv.str_val) pos = _PyiEmit(buf, buf_size, pos, sbuf_c) elif cv.const_kind == ast.CONST_NONE: pos = _PyiEmit(buf, buf_size, pos, " = None") elif aa.value is not None and aa.value.kind() == ast.ASTKind.UnaryOp: diff --git a/App/lib/Stub/StubGen/VpiReader.vp b/App/lib/Stub/StubGen/VpiReader.vp index 1e68e7c..e04cb75 100644 --- a/App/lib/Stub/StubGen/VpiReader.vp +++ b/App/lib/Stub/StubGen/VpiReader.vp @@ -169,8 +169,7 @@ def _vpi_idx_slot(idx_base: bytes, si: sizet) -> sizet*: return (sizet*)(uint64(idx_base) + uint64(si) * 8) -def _vpi_idx_find(keys: bytes, key_stride: int, idx_base: bytes, - cap: int, key: bytes) -> int: +def _vpi_idx_find(keys: bytes, key_stride: int, idx_base: bytes, cap: int, key: bytes) -> int: """在索引中探测 key,返回命中槽下标(>=0);未命中/索引不可用返回 -1 命中判据是"当前键相等"(strcmp),不能只比哈希。 @@ -235,8 +234,7 @@ def _vpi_rebuild_ret_idx(new_cap: int) -> int: fail: int = 0 ri: int for ri in range(_g_vpi_ret_count): - if _vpi_idx_insert(new_idx, new_cap, ri, - _g_vpi_ret_keys + ri * VPI_KEY_LEN) != 0: + if _vpi_idx_insert(new_idx, new_cap, ri, _g_vpi_ret_keys + ri * VPI_KEY_LEN) != 0: fail = 1 break if fail != 0: @@ -268,8 +266,7 @@ def _vpi_rebuild_param_idx(new_cap: int) -> int: fail: int = 0 ri: int for ri in range(_g_vpi_param_count): - if _vpi_idx_insert(new_idx, new_cap, ri, - _g_vpi_param_keys + ri * VPI_PARAM_KEY_LEN) != 0: + if _vpi_idx_insert(new_idx, new_cap, ri, _g_vpi_param_keys + ri * VPI_PARAM_KEY_LEN) != 0: fail = 1 break if fail != 0: @@ -389,8 +386,7 @@ def _cache_vpi_return_annots_text(vpi_buf: bytes, src_sha1: str) -> int: mname_buf[mname_len] = '\0' # 无注解的特殊方法(构造/析构)跳过:它们有专门调用路径 skip_def: int = 0 - if arrow_pos >= le and ( - string.strcmp(mname_buf, "__init__") == 0 or string.strcmp(mname_buf, "__new__") == 0 or string.strcmp(mname_buf, "__before_init__") == 0 or string.strcmp(mname_buf, "__after_init__") == 0): + if arrow_pos >= le and (string.strcmp(mname_buf, "__init__") == 0 or string.strcmp(mname_buf, "__new__") == 0 or string.strcmp(mname_buf, "__before_init__") == 0 or string.strcmp(mname_buf, "__after_init__") == 0): skip_def = 1 if skip_def == 0: key_buf: bytes = stdlib.malloc(key_len + 1) @@ -404,8 +400,7 @@ def _cache_vpi_return_annots_text(vpi_buf: bytes, src_sha1: str) -> int: # 重复(命中即"首个注册优先"= 原线性扫描首个同名); # 未命中 | 索引不可信 → 回退原线性扫描(正确性保证)。 if _g_vpi_ret_idx_built == _g_vpi_ret_count and _g_vpi_ret_idx is not None and _g_vpi_ret_idx_cap > 0: - if _vpi_idx_find(_g_vpi_ret_keys, VPI_KEY_LEN, - _g_vpi_ret_idx, _g_vpi_ret_idx_cap, key_buf) >= 0: + if _vpi_idx_find(_g_vpi_ret_keys, VPI_KEY_LEN, _g_vpi_ret_idx, _g_vpi_ret_idx_cap, key_buf) >= 0: dup_key = 1 else: # 快速路径:重复键必首字节相同(strcmp 判等蕴含首字节 @@ -420,14 +415,12 @@ def _cache_vpi_return_annots_text(vpi_buf: bytes, src_sha1: str) -> int: if dup_key == 0 and _g_vpi_ret_count >= _g_vpi_ret_cap: grow_ok = _grow_vpi_ret_cache() if dup_key == 0 and grow_ok != 0: string.strcpy(_g_vpi_ret_keys + _g_vpi_ret_count * VPI_KEY_LEN, key_buf) - string.strncpy(_g_vpi_ret_strs + _g_vpi_ret_count * VPI_RET_LEN, - ret_src, rtype_len) + string.strncpy(_g_vpi_ret_strs + _g_vpi_ret_count * VPI_RET_LEN, ret_src, rtype_len) (_g_vpi_ret_strs + _g_vpi_ret_count * VPI_RET_LEN)[rtype_len] = '\0' _g_vpi_ret_count += 1 # 同步索引:仅当插入前可信(Built==Count-1,含扩容 # 重建后)且插入成功;否则标记不可信(查找回退扫描)。 - if _g_vpi_ret_idx_built == _g_vpi_ret_count - 1 and _vpi_idx_insert(_g_vpi_ret_idx, _g_vpi_ret_idx_cap, - _g_vpi_ret_count - 1, key_buf) == 0: + if _g_vpi_ret_idx_built == _g_vpi_ret_count - 1 and _vpi_idx_insert(_g_vpi_ret_idx, _g_vpi_ret_idx_cap, _g_vpi_ret_count - 1, key_buf) == 0: _g_vpi_ret_idx_built = _g_vpi_ret_count else: _g_vpi_ret_idx_built = -1 stdlib.free(key_buf) @@ -598,8 +591,7 @@ def _cache_vpi_param_annots_text(vpi_buf: bytes, src_sha1: str) -> int: # 重复(命中即"首个注册优先"= 原线性扫描首个同名); # 未命中 | 索引不可信 → 回退原线性扫描(正确性保证)。 if _g_vpi_param_idx_built == _g_vpi_param_count and _g_vpi_param_idx is not None and _g_vpi_param_idx_cap > 0: - if _vpi_idx_find(_g_vpi_param_keys, VPI_PARAM_KEY_LEN, - _g_vpi_param_idx, _g_vpi_param_idx_cap, key_buf) >= 0: + if _vpi_idx_find(_g_vpi_param_keys, VPI_PARAM_KEY_LEN, _g_vpi_param_idx, _g_vpi_param_idx_cap, key_buf) >= 0: dup_key = 1 else: # 快速路径:重复键必首字节相同(strcmp 判等蕴含首字节 @@ -614,14 +606,12 @@ def _cache_vpi_param_annots_text(vpi_buf: bytes, src_sha1: str) -> int: if dup_key == 0 and _g_vpi_param_count >= _g_vpi_param_cap: grow_ok = _grow_vpi_param_cache() if dup_key == 0 and grow_ok != 0: string.strcpy(_g_vpi_param_keys + _g_vpi_param_count * VPI_PARAM_KEY_LEN, key_buf) - string.strncpy(_g_vpi_param_strs + _g_vpi_param_count * VPI_PARAM_LEN, - plist, plist_pos) + string.strncpy(_g_vpi_param_strs + _g_vpi_param_count * VPI_PARAM_LEN, plist, plist_pos) (_g_vpi_param_strs + _g_vpi_param_count * VPI_PARAM_LEN)[plist_pos] = '\0' _g_vpi_param_count += 1 # 同步索引:仅当插入前可信(Built==Count-1,含扩容 # 重建后)且插入成功;否则标记不可信(查找回退扫描)。 - if _g_vpi_param_idx_built == _g_vpi_param_count - 1 and _vpi_idx_insert(_g_vpi_param_idx, _g_vpi_param_idx_cap, - _g_vpi_param_count - 1, key_buf) == 0: + if _g_vpi_param_idx_built == _g_vpi_param_count - 1 and _vpi_idx_insert(_g_vpi_param_idx, _g_vpi_param_idx_cap, _g_vpi_param_count - 1, key_buf) == 0: _g_vpi_param_idx_built = _g_vpi_param_count else: _g_vpi_param_idx_built = -1 stdlib.free(key_buf) @@ -676,8 +666,7 @@ def _lookup_vpi_param_annots(src_sha1: str, cls_name: str, method_name: str) -> # 索引随扩容整体重建且覆盖全表)⇒ 无需再线性扫描;索引不可信 → 回退线性扫描。 hit_p: int = -1 if _g_vpi_param_idx_built == _g_vpi_param_count and _g_vpi_param_idx is not None and _g_vpi_param_idx_cap > 0: - hit_p = _vpi_idx_find(_g_vpi_param_keys, VPI_PARAM_KEY_LEN, - _g_vpi_param_idx, _g_vpi_param_idx_cap, key_buf) + hit_p = _vpi_idx_find(_g_vpi_param_keys, VPI_PARAM_KEY_LEN, _g_vpi_param_idx, _g_vpi_param_idx_cap, key_buf) else: # 回退原线性扫描:strcmp 判等蕴含首字节相等;键首字节 = src_sha1[0],缓存含 # 多模块条目,首字节不同者必不相等,直接跳过其 strcmp(仅做否定判定,不改命中)。 @@ -699,13 +688,7 @@ def _lookup_vpi_param_annots(src_sha1: str, cls_name: str, method_name: str) -> # 调用点 declare 停在调用点实参宽度(如 elem_size 字面量 i32 把定义侧 sizet(i64) 固化窄)。本函数按 {sha1}.{base}[T].{method} 形态定位模板条目, # 把段内独立的类型形参 token 用特化实参(cls_name 的 [...] 内容)替换后再解析;未命中/多参模板(键段含空格被截断)返回 None,不做兜底推断。 # ============================================================ -def _resolve_vpi_param_annot_seg_template(pool: memhub.MemBuddy*, - src_sha1: str, - cls_name: str, - method_name: str, - seg_idx: int, - i32_ty: mlirlite.LLVMType*, - i8_ptr_ty: mlirlite.LLVMType*) -> mlirlite.LLVMType*: +def _resolve_vpi_param_annot_seg_template(pool: memhub.MemBuddy*, src_sha1: str, cls_name: str, method_name: str, seg_idx: int, i32_ty: mlirlite.LLVMType*, i8_ptr_ty: mlirlite.LLVMType*) -> mlirlite.LLVMType*: """特化类 X[arg] 的参数注解段解析(模板 X[T] 注解 + T→arg 替换);未命中 None""" if pool is None or src_sha1 is None or cls_name is None or method_name is None or _g_vpi_param_keys is None: return None lbkt_t: str = string.strchr(cls_name, 91) # '[' = 91 @@ -783,14 +766,7 @@ def _resolve_vpi_param_annot_seg_template(pool: memhub.MemBuddy*, # vpi tree 参数列表被覆盖损坏时(param_count 偏小,尾部默认参数丢失),用 _cache_vpi_param_annots_text 的文本缓存补全:参数位置 p 对应缓存段 p(含首参空串占位)。 # 补全后 declare 参数数与 define 一致,调用点默认参数填充才能生效,避免被调函数读栈垃圾。 # ============================================================ -def _repair_declare_params_from_text(pool: memhub.MemBuddy*, - func: mlirlite.Function*, - src_sha1: str, - cls_name: str, - method_name: str, - param_count: int, - i32_ty: mlirlite.LLVMType*, - i8_ptr_ty: mlirlite.LLVMType*) -> int: +def _repair_declare_params_from_text(pool: memhub.MemBuddy*, func: mlirlite.Function*, src_sha1: str, cls_name: str, method_name: str, param_count: int, i32_ty: mlirlite.LLVMType*, i8_ptr_ty: mlirlite.LLVMType*) -> int: """用 vpi 文本缓存的参数注解补全 declare 参数;返回补全后参数数""" if func is None or src_sha1 is None or method_name is None: return param_count prm_annots: str = _lookup_vpi_param_annots(src_sha1, cls_name, method_name) @@ -817,8 +793,7 @@ def _repair_declare_params_from_text(pool: memhub.MemBuddy*, if seg_buf_r is not None: string.strncpy(seg_buf_r, prm_annots + seg_start2, seg_len2) seg_buf_r[seg_len2] = '\0' - rt: mlirlite.LLVMType* = _resolve_vpi_ret_annot_str( - pool, seg_buf_r, i32_ty, i8_ptr_ty) + rt: mlirlite.LLVMType* = _resolve_vpi_ret_annot_str(pool, seg_buf_r, i32_ty, i8_ptr_ty) if rt is not None: param_ty_r = rt stdlib.free(seg_buf_r) mlirlite.add_param(pool, func, param_ty_r, "arg") @@ -834,13 +809,7 @@ def _repair_declare_params_from_text(pool: memhub.MemBuddy*, # 参数类型错会导致调用侧 trunc 传参、callee 按 i64 读栈残留高位 → can=巨值读未写槽位崩溃(SlotsBugTest 根因)。 # 从 @-joined 注解串取第 seg_idx 段(0=self 空段),用 _resolve_vpi_ret_annot_str 解析;空段/未命中返回 None(走 AST 兜底)。 # ============================================================ -def _resolve_vpi_param_annot_seg(pool: memhub.MemBuddy*, - src_sha1: str, - cls_name: str, - method_name: str, - seg_idx: int, - i32_ty: mlirlite.LLVMType*, - i8_ptr_ty: mlirlite.LLVMType*) -> mlirlite.LLVMType*: +def _resolve_vpi_param_annot_seg(pool: memhub.MemBuddy*, src_sha1: str, cls_name: str, method_name: str, seg_idx: int, i32_ty: mlirlite.LLVMType*, i8_ptr_ty: mlirlite.LLVMType*) -> mlirlite.LLVMType*: """按段索引解析 vpi 参数注解段为 LLVMType,空段/失败返回 None""" if pool is None or src_sha1 is None or method_name is None: return None prm_annots_p: str = _lookup_vpi_param_annots(src_sha1, cls_name, method_name) @@ -859,8 +828,7 @@ def _resolve_vpi_param_annot_seg(pool: memhub.MemBuddy*, if seg_buf_p is None: return None string.strncpy(seg_buf_p, prm_annots_p + seg_start_p, seg_len_p) seg_buf_p[seg_len_p] = '\0' - seg_ty_p: mlirlite.LLVMType* = _resolve_vpi_ret_annot_str( - pool, seg_buf_p, i32_ty, i8_ptr_ty) + seg_ty_p: mlirlite.LLVMType* = _resolve_vpi_ret_annot_str(pool, seg_buf_p, i32_ty, i8_ptr_ty) stdlib.free(seg_buf_p) return seg_ty_p @@ -945,8 +913,7 @@ def _ensure_vpi_ret_annot_loaded(src_sha1: str, temp_dir: str) -> int: # ============================================================ # _vpi_param_annot_seg_is - 形参注解段等值判定(供"str/bytes 不是通用指针通配"规则) # ============================================================ -def _vpi_param_annot_seg_is(src_sha1: str, cls_name: str, method_name: str, - seg_idx: int, want: str) -> int: +def _vpi_param_annot_seg_is(src_sha1: str, cls_name: str, method_name: str, seg_idx: int, want: str) -> int: """vpi 定义侧第 seg_idx 个形参注解段是否**恰等于** want(1=是 / 0=否) 注解串格式(见 _lookup_vpi_param_annots):以 '@' 分隔的段序列,段 0 是 @@ -1105,8 +1072,7 @@ def _lookup_vpi_ret_annot(src_sha1: str, cls_name: str, method_name: str) -> str # 匹配兜底仍保留,其键形态不同、不依赖精确键命中);索引不可信 → 回退线性扫描。 hit_r: int = -1 if _g_vpi_ret_idx_built == _g_vpi_ret_count and _g_vpi_ret_idx is not None and _g_vpi_ret_idx_cap > 0: - hit_r = _vpi_idx_find(_g_vpi_ret_keys, VPI_KEY_LEN, - _g_vpi_ret_idx, _g_vpi_ret_idx_cap, key_buf) + hit_r = _vpi_idx_find(_g_vpi_ret_keys, VPI_KEY_LEN, _g_vpi_ret_idx, _g_vpi_ret_idx_cap, key_buf) else: # 回退原线性扫描:strcmp 判等蕴含首字节相等(键首字节 = src_sha1[0]),跳过首字节不同者。 key_first: int = key_buf[0] @@ -1143,16 +1109,14 @@ def _lookup_vpi_ret_annot(src_sha1: str, cls_name: str, method_name: str) -> str if string.strncmp(gk, src_sha1, sha1_len) == 0 and gk[sha1_len] == '.' and string.strncmp(gk + sha1_len + 1, base_v, base_len_v) == 0 and gk[sha1_len + 1 + base_len_v] == '[': gklb: str = string.strchr(gk + sha1_len + 1 + base_len_v, ']') if gklb is not None: - tparam_len_v: sizet = sizet( - uint64(gklb) - uint64(gk + sha1_len + 1 + base_len_v) - 1) + tparam_len_v: sizet = sizet(uint64(gklb) - uint64(gk + sha1_len + 1 + base_len_v) - 1) meth_start_v: str = gklb + 2 # 跳过 ']' 和 '.' if tparam_len_v > 0 and string.strcmp(meth_start_v, method_name) == 0: tparam_v: str = stdlib.malloc(tparam_len_v + 1) if tparam_v is not None: string.strncpy(tparam_v, gk + sha1_len + 1 + base_len_v + 1, tparam_len_v) tparam_v[tparam_len_v] = '\0' - new_annot_v: str = _subst_template_arg( - _g_vpi_ret_strs + gi * VPI_RET_LEN, tparam_v, param_v) + new_annot_v: str = _subst_template_arg(_g_vpi_ret_strs + gi * VPI_RET_LEN, tparam_v, param_v) stdlib.free(tparam_v) stdlib.free(base_v) stdlib.free(param_v) @@ -1169,8 +1133,7 @@ def _lookup_vpi_ret_annot(src_sha1: str, cls_name: str, method_name: str) -> str # # 纯字符串解析,不构造 AST 节点。 # ============================================================ -def _resolve_single_vpi_type_str(pool: memhub.MemBuddy*, - seg: str) -> mlirlite.LLVMType*: +def _resolve_single_vpi_type_str(pool: memhub.MemBuddy*, seg: str) -> mlirlite.LLVMType*: """解析单个类型段为 LLVMType,无法识别返回 None""" if seg is None or pool is None: return None # 【指针实参唯一规范形 `T*`(用户定口径,2026-09-30)】`rawptr[T]` ≡ @@ -1266,8 +1229,7 @@ def _resolve_single_vpi_type_str(pool: memhub.MemBuddy*, if inner_buf_cp is not None: string.strncpy(inner_buf_cp, seg + cptr_sub_pfx, inner_len_cp) inner_buf_cp[inner_len_cp] = '\0' - inner_ty_cp: mlirlite.LLVMType* = _resolve_single_vpi_type_str( - pool, inner_buf_cp) + inner_ty_cp: mlirlite.LLVMType* = _resolve_single_vpi_type_str(pool, inner_buf_cp) stdlib.free(inner_buf_cp) if inner_ty_cp is not None: return mlirlite.Ptr(pool, inner_ty_cp) return None @@ -1318,10 +1280,7 @@ def _resolve_single_vpi_type_str(pool: memhub.MemBuddy*, # # 支持: "str"/"bytes" → i8*; "int" → i32; "bool" → i1; "char" 等 → map_t_type 映射; "X*" → Ptr(Struct X); "t.CPtr" → i8*; "memhub.MemBuddy*" → Ptr(Struct MemBuddy)。 # ============================================================ -def _resolve_vpi_ret_annot_str(pool: memhub.MemBuddy*, - ret_annot: str, - i32_ty: mlirlite.LLVMType*, - i8_ptr_ty: mlirlite.LLVMType*) -> mlirlite.LLVMType*: +def _resolve_vpi_ret_annot_str(pool: memhub.MemBuddy*, ret_annot: str, i32_ty: mlirlite.LLVMType*, i8_ptr_ty: mlirlite.LLVMType*) -> mlirlite.LLVMType*: """直接解析 vpi 返回注解字符串为 LLVMType(不构造 AST 节点)""" if ret_annot is None or pool is None: return None @@ -1656,8 +1615,7 @@ def _vpi_typedef_visited_mark(sha1: str) -> None: new_cap: int = old_cap * 2 nb: bytes = stdlib.realloc(_g_vpi_typedef_visited, new_cap * 17) if nb is None: - stdio.printf("[VPI] 防环访问表扩容失败 cap=%d(丢标记引发重解析爆炸,终止)\n", - old_cap) + stdio.printf("[VPI] 防环访问表扩容失败 cap=%d(丢标记引发重解析爆炸,终止)\n", old_cap) stdio.fflush(None) stdlib.exit(1) _g_vpi_typedef_visited = nb @@ -1667,10 +1625,7 @@ def _vpi_typedef_visited_mark(sha1: str) -> None: _g_vpi_typedef_visited_count += 1 -def _vpi_register_typedef_closure(pool: memhub.MemBuddy*, - import_mods: str, - temp_dir: str, - depth: int) -> int: +def _vpi_register_typedef_closure(pool: memhub.MemBuddy*, import_mods: str, temp_dir: str, depth: int) -> int: """递归注册 import 闭包模块的 CTypedef/CDefine,返回 0 恒(副作用注册) 仅注册 AnnAssign 的 t.CTypedef/t.CDefine,不注入函数 declare(避免 @@ -1825,10 +1780,7 @@ def _vpi_register_typedef_closure(pool: memhub.MemBuddy*, # Args: pool 内存池;mod 当前 LLVM 模块;vpi_path .vpi 文件路径;trans 翻译器对象 # Returns: 1=成功,0=失败 # ============================================================ -def ParseVpiIntoModule(pool: memhub.MemBuddy*, - mod: mlirlite.LLVMModule*, - vpi_path: str, - trans: HT.Translator*) -> int: +def ParseVpiIntoModule(pool: memhub.MemBuddy*, mod: mlirlite.LLVMModule*, vpi_path: str, trans: HT.Translator*) -> int: """解析 .vpi 文件,将函数声明注入到当前模块 解析 stub 期间临时将错误归因切换到被读 stub 文件(.vpi): @@ -1843,10 +1795,7 @@ def ParseVpiIntoModule(pool: memhub.MemBuddy*, return ret -def _ParseVpiIntoModuleImpl(pool: memhub.MemBuddy*, - mod: mlirlite.LLVMModule*, - vpi_path: str, - trans: HT.Translator*) -> int: +def _ParseVpiIntoModuleImpl(pool: memhub.MemBuddy*, mod: mlirlite.LLVMModule*, vpi_path: str, trans: HT.Translator*) -> int: """解析 .vpi 文件,将函数声明注入到当前模块(ParseVpiIntoModule 实际实现)""" if pool is None or mod is None or vpi_path is None or trans is None: return 0 @@ -1985,8 +1934,7 @@ def _ParseVpiIntoModuleImpl(pool: memhub.MemBuddy*, sifr_mod_q = qbuf_r if sifr_mod is not None: if stub_ctx is not None: - stub_ctx.ImportedModules = StubMergerStore.AppendImportedModule( - pool, stub_ctx.ImportedModules, sifr_mod_q) + stub_ctx.ImportedModules = StubMergerStore.AppendImportedModule(pool, stub_ctx.ImportedModules, sifr_mod_q) # 方案A:包 __init__.vpi 的重导出类以包 sha1 注册别名 entry # (ast.Attribute 定义在 ast.exprs 但归属 ast 包;查找端按包 # sha1 匹配,注册端按定义文件 sha1 → name+sha1 错位 fail-fast。 @@ -2032,13 +1980,7 @@ def _ParseVpiIntoModuleImpl(pool: memhub.MemBuddy*, # Expression 定义在 ast.stmts,真因是子模块 sha1 查找/注入失败)。 # 此处直接给出包名与子模块名(含补前缀后的精确名)便于定位。 if is_pkg_init_rt != 0 and sub_sha1_rt is None and sifr_mod is not None and sifr_mod[0] != '\0': - GenApi.fatal_error( - sifr, - f"包 stub 的 from-import 子模块 sha1 查找失败:" - f"包={rel_path_rt if rel_path_rt is not None else '?'}," - f"子模块='{sifr_mod}'(补前缀后='{sifr_mod_q}');" - f"该子模块的类无法注册,引用它们的注解会在后续解析时落空", - "NameError") + GenApi.fatal_error(sifr, f"包 stub 的 from-import 子模块 sha1 查找失败:" f"包={rel_path_rt if rel_path_rt is not None else '?'}," f"子模块='{sifr_mod}'(补前缀后='{sifr_mod_q}');" f"该子模块的类无法注册,引用它们的注解会在后续解析时落空", "NameError") if sifr.names is not None: sifr_nn: sizet = len(sifr.names) sifri: sizet @@ -2056,15 +1998,12 @@ def _ParseVpiIntoModuleImpl(pool: memhub.MemBuddy*, # 在此跳过 ⇒ stub 上下文里 star 回退恒失效(同一份约定 # 的两处 loop 又一处不一致)。 if stub_ctx is not None: - stub_ctx.FromImports = StubMergerStore.AppendFromImport( - pool, stub_ctx.FromImports, slocal, sifr_mod_q, sorig) + stub_ctx.FromImports = StubMergerStore.AppendFromImport(pool, stub_ctx.FromImports, slocal, sifr_mod_q, sorig) # 重导出类以包 sha1 注册(asname 时按别名注册);star 无 # 具体类名,不参与重导出(仅记账,见上)。 if string.strcmp(sial.name, "*") != 0: if is_pkg_init_rt != 0 and sub_sha1_rt is not None: - _inject_reexport_class_declare( - pool, mod, sial.name, slocal, - sub_sha1_rt, src_sha1, trans) + _inject_reexport_class_declare(pool, mod, sial.name, slocal, sub_sha1_rt, src_sha1, trans) # 用 stub 自己的 imports 替代当前模块的(stub 注解解析上下文正确性) if stub_ctx is not None: @@ -2094,8 +2033,7 @@ def _ParseVpiIntoModuleImpl(pool: memhub.MemBuddy*, if ch_src == '/' or ch_src == '\\': src_mod_buf[sri_src] = '.' else: src_mod_buf[sri_src] = ch_src src_mod_buf[sr_len_src] = '\0' - imported_modules = StubMergerStore.AppendImportedModule( - pool, imported_modules, src_mod_buf) + imported_modules = StubMergerStore.AppendImportedModule(pool, imported_modules, src_mod_buf) stdlib.free(src_mod_buf) # 递归预注册 stub import 闭包的 CTypedef/CDefine:注解(如 codepage: @@ -2119,8 +2057,7 @@ def _ParseVpiIntoModuleImpl(pool: memhub.MemBuddy*, # 虚表恢复"段;批处理该标志恒 0,本块不执行。 # ============================================================ if ReplStubLayoutMode != 0: - _repl_stub_collect_module(pool, mod, ch, n, trans, src_sha1, - stub_imported_modules, stub_from_imports) + _repl_stub_collect_module(pool, mod, ch, n, trans, src_sha1, stub_imported_modules, stub_from_imports) # ============================================================ # 第一遍 A:先注册**所有** ClassDef(字段 + 结构体),不处理方法。 @@ -2139,8 +2076,7 @@ def _ParseVpiIntoModuleImpl(pool: memhub.MemBuddy*, # T 无法确定;特化方法 define 已在 Phase1 生成,无需 stub 模板 declare。 tp_stub0: list[str]* = class_cd0.type_params if tp_stub0 is not None and len(tp_stub0) > 0: continue - _inject_class_struct_declare(pool, mod, class_cd0, cls_name_v0, trans, - src_sha1, imported_modules, from_imports) + _inject_class_struct_declare(pool, mod, class_cd0, cls_name_v0, trans, src_sha1, imported_modules, from_imports) # App 预注册(Phase A-pre,_pre_allow_dep_inject)**跳过方法/函数 declare 注入**: # 预注册的唯一目的是注册 struct/enum/union(第一遍 A)与包重导出别名(上方 @@ -2180,9 +2116,7 @@ def _ParseVpiIntoModuleImpl(pool: memhub.MemBuddy*, if m_fd1 is None or m_fd1.name is None: continue # App 预注册跳过方法 declare(原因见上方 pre_skip_fn_declares 注释)。 if pre_skip_fn_declares == 0: - _inject_method_declare(pool, mod, m_fd1, cls_name_v1, trans, - src_sha1, imported_modules, from_imports, - i32_ty, i8_ptr_ty, funcs_ptr, max_funcs) + _inject_method_declare(pool, mod, m_fd1, cls_name_v1, trans, src_sha1, imported_modules, from_imports, i32_ty, i8_ptr_ty, funcs_ptr, max_funcs) i: sizet for i in range(n): @@ -2199,10 +2133,7 @@ def _ParseVpiIntoModuleImpl(pool: memhub.MemBuddy*, # 打断多遍收敛(现场 Translator.vpi 的 InjectTracebackInstallCtor # 形参 rawptr[Translator])。 if pre_skip_fn_declares != 0: continue - _inject_function_declare(pool, mod, fd, trans, src_sha1, - imported_modules, from_imports, - i32_ty, i8_ptr_ty, - funcs_ptr, max_funcs) + _inject_function_declare(pool, mod, fd, trans, src_sha1, imported_modules, from_imports, i32_ty, i8_ptr_ty, funcs_ptr, max_funcs) continue # AnnAssign with t.CTypedef → 注册 CTypedef; @@ -2243,9 +2174,7 @@ def _ParseVpiIntoModuleImpl(pool: memhub.MemBuddy*, cdef_val: int64 = GenApi.extract_cdefine_int_value(aa.value) GenApi.register_cdefine_constant(pool, cdef_tgt.id, cdef_val) else: - _inject_global_variable_declare(pool, mod, aa, trans, - stub_imported_modules, stub_from_imports, - i32_ty, i8_ptr_ty, src_sha1) + _inject_global_variable_declare(pool, mod, aa, trans, stub_imported_modules, stub_from_imports, i32_ty, i8_ptr_ty, src_sha1) continue # ClassDef → 已在第一遍统一注册(含字段 + 方法 declare),此处跳过 @@ -2291,10 +2220,7 @@ def ResetVpiInjectVisited() -> None: _vpi_inj_depth = 0 -def _ensure_dep_vpi_injected(pool: memhub.MemBuddy*, - mod: mlirlite.LLVMModule*, - dep_sha1: str, - trans: HT.Translator*) -> int: +def _ensure_dep_vpi_injected(pool: memhub.MemBuddy*, mod: mlirlite.LLVMModule*, dep_sha1: str, trans: HT.Translator*) -> int: """按需注入 dep_sha1 对应的 .vpi 到当前模块(防重入),1=就绪 / 0=失败""" global _vpi_inj_sha1s, _vpi_inj_count, _vpi_inj_depth if pool is None or mod is None or dep_sha1 is None or trans is None: return 0 @@ -2340,8 +2266,7 @@ def _ensure_dep_vpi_injected(pool: memhub.MemBuddy*, # 错误却表现为远处注解解析失败。 _vpi_inj_count -= 1 if my_idx_i != _vpi_inj_count: - string.strcpy(_vpi_inj_sha1s + sizet(my_idx_i) * 17, - _vpi_inj_sha1s + sizet(_vpi_inj_count) * 17) + string.strcpy(_vpi_inj_sha1s + sizet(my_idx_i) * 17, _vpi_inj_sha1s + sizet(_vpi_inj_count) * 17) return 0 return 1 @@ -2356,13 +2281,7 @@ def _ensure_dep_vpi_injected(pool: memhub.MemBuddy*, # # Args: src_name 子模块中的原类名;local_name 包命名空间中的名字(或 as 别名);sub_sha1 子模块(定义文件)sha1;pkg_sha1 当前包 __init__ 的 sha1;trans 翻译器对象(源 entry 缺失时按需注入子模块 vpi 需要) # ============================================================ -def _inject_reexport_class_declare(pool: memhub.MemBuddy*, - mod: mlirlite.LLVMModule*, - src_name: str, - local_name: str, - sub_sha1: str, - pkg_sha1: str, - trans: HT.Translator*) -> int: +def _inject_reexport_class_declare(pool: memhub.MemBuddy*, mod: mlirlite.LLVMModule*, src_name: str, local_name: str, sub_sha1: str, pkg_sha1: str, trans: HT.Translator*) -> int: """把包子模块重导出的类以包 sha1 注册别名 entry(方案A:ast.Attribute 归属 ast 包)""" if pool is None or mod is None or src_name is None or local_name is None: return 0 if sub_sha1 is None or sub_sha1[0] == '\0' or pkg_sha1 is None or pkg_sha1[0] == '\0': return 0 @@ -2462,15 +2381,7 @@ def _vpi_class_is_renum(class_cd: ast.ClassDef*) -> int: # 2) 未注册 → 解析字段类型 → 创建命名 StructType("sha1.ClassName") → register_struct + add_visible_struct。 # 字段解析失败不 fatal(不注册该类,留给源模块编译注册,后续裸类名引用由调用侧 fail-fast 暴露)。 # ============================================================ -def _inject_class_struct_declare(pool: memhub.MemBuddy*, - mod: mlirlite.LLVMModule*, - class_cd: ast.ClassDef*, - cls_name: str, - trans: HT.Translator*, - src_sha1: str, - imported_modules: str, - from_imports: str, - name_prefix: str = None) -> int: +def _inject_class_struct_declare(pool: memhub.MemBuddy*, mod: mlirlite.LLVMModule*, class_cd: ast.ClassDef*, cls_name: str, trans: HT.Translator*, src_sha1: str, imported_modules: str, from_imports: str, name_prefix: str = None) -> int: """从 vpi ClassDef 注册类为 struct 类型(含字段),使同 vpi 内裸类名注解可解析 name_prefix:非 None 表示"本类是 prefix 类的嵌套类",注册名取扁平名 @@ -2496,8 +2407,7 @@ def _inject_class_struct_declare(pool: memhub.MemBuddy*, # 不登记(片段侧字段访问明确失败,绝不按错偏移静默访问)。 # State=EMPTY 的类(无父类/无虚表/字段类型不可解析)不在此列,仍走下方既有口径。 if ReplStubLayoutMode != 0: - se: rawptr[ReplStubClass] = _repl_stub_find( - _repl_stub_key(pool, src_sha1, real_name)) + se: rawptr[ReplStubClass] = _repl_stub_find(_repl_stub_key(pool, src_sha1, real_name)) if se is not None and se.State != _REPL_SS_EMPTY: if se.State == _REPL_SS_PENDING: _repl_stub_try(se, mod) if se.State == _REPL_SS_OK: GenApi.add_visible_struct(pool, real_name) @@ -2540,8 +2450,7 @@ def _inject_class_struct_declare(pool: memhub.MemBuddy*, # (ClassGenDef._translate_nested_classdefs)⇒ 此处按同一命名**先**递归登记。 # 必须早于下方字段注解解析:外层字段可能写成 `外类.内类`,只有扁平名条目已在 # 结构体表里,TypeGenResolve._resolve_nested_class_type 才解析得出类型。 - _inject_nested_class_declares(pool, mod, class_cd, real_name, trans, - src_sha1, imported_modules, from_imports) + _inject_nested_class_declares(pool, mod, class_cd, real_name, trans, src_sha1, imported_modules, from_imports) # 还原"正在定义类"窗口:嵌套递归内的 mark_module_class 会把 CurDefClassName 改成 # 嵌套类名(A_B)。不还原会让外层字段注解的规则 5.5 自引用证据判错(裸类名票名冻结 # 成裸名版本、与定义侧带前缀形式分裂),也会让 `外类.内类` 的守卫①(CurDefClassName @@ -2566,8 +2475,7 @@ def _inject_class_struct_declare(pool: memhub.MemBuddy*, if m_aa_c.target.kind() != ast.ASTKind.Name: continue m_tgt_c: ast.Name* = ast.Name*(m_aa_c.target) if m_tgt_c.id is None: continue - field_ty_c: mlirlite.LLVMType* = GenApi.resolve_annotation_type( - pool, m_aa_c.annotation, imported_modules, from_imports, trans, 0) + field_ty_c: mlirlite.LLVMType* = GenApi.resolve_annotation_type(pool, m_aa_c.annotation, imported_modules, from_imports, trans, 0) if field_ty_c is None: # 字段类型解析失败:不注册该类(留给源模块编译注册),不 fatal return 0 @@ -2607,14 +2515,12 @@ def _inject_class_struct_declare(pool: memhub.MemBuddy*, name_buf_c[sh_len_c] = '.' string.strcpy(name_buf_c + sh_len_c + 1, real_name) type_name_c = name_buf_c - struct_ty_c: mlirlite.LLVMType* = mlirlite.Struct( - pool, first_node_c, field_count, type_name_c) + struct_ty_c: mlirlite.LLVMType* = mlirlite.Struct(pool, first_node_c, field_count, type_name_c) if struct_ty_c is None: return 0 # 5. StdlibAlloc(Phase B)时深拷贝到 perm_pool,跨文件 reset 存活 # (对齐 ClassGenDef.translate_class_def L489-494) if GenApi.get_stdlib_alloc() != 0: - st_copy_c: mlirlite.LLVMType* = mlirlite.DeepCopyType( - CompilerFactory.factory.PermPool, struct_ty_c) + st_copy_c: mlirlite.LLVMType* = mlirlite.DeepCopyType(CompilerFactory.factory.PermPool, struct_ty_c) if st_copy_c is not None: struct_ty_c = st_copy_c # 5.5 前向声明占位命中 ⇒ **占位 Ty 原地写入**(与 ClassGenDef.translate_class_def # 的 fill_fwd 段逐句同款):给已存在的类型对象 `*existing.Ty` 赋入刚构建的 @@ -2640,8 +2546,7 @@ def _inject_class_struct_declare(pool: memhub.MemBuddy*, if _vpi_class_has_packed(class_cd.decorator_list) != 0: mlirlite.module_set_named_type_packed(mod, pool, struct_ty_c, 1) # 注册名用扁平名 real_name:跨模块引用 `外类.内类` 时 TypeGenResolve 查的是 # 扁平名条目(与定义端 StructGen 的登记名同源)。 - entry_c: GenTypes.StructEntry* = GenApi.register_struct( - pool, real_name, struct_ty_c, src_sha1) + entry_c: GenTypes.StructEntry* = GenApi.register_struct(pool, real_name, struct_ty_c, src_sha1) if entry_c is None: return 0 # B5:vpi 注入注册的 entry 同步 IsPacked——后续跨模块 stub 注入 # (ensure_struct_def_in_module)按 entry.IsPacked 判定 packed,否则读 0 @@ -2674,14 +2579,7 @@ def _inject_class_struct_declare(pool: memhub.MemBuddy*, # mark_module_class 窗口留在嵌套类上;故外层调用点在其后**再调一次** # mark_module_class 还原(见 _inject_class_struct_declare 内注释)。 # ============================================================ -def _inject_nested_class_declares(pool: memhub.MemBuddy*, - mod: mlirlite.LLVMModule*, - class_cd: ast.ClassDef*, - prefix_name: str, - trans: HT.Translator*, - src_sha1: str, - imported_modules: str, - from_imports: str) -> None: +def _inject_nested_class_declares(pool: memhub.MemBuddy*, mod: mlirlite.LLVMModule*, class_cd: ast.ClassDef*, prefix_name: str, trans: HT.Translator*, src_sha1: str, imported_modules: str, from_imports: str) -> None: """递归登记 class_cd 的所有嵌套 ClassDef 为扁平名类型(前缀 = prefix_name)""" if pool is None or mod is None or class_cd is None or prefix_name is None: return children: list[ast.AST*]* = class_cd.children @@ -2693,9 +2591,7 @@ def _inject_nested_class_declares(pool: memhub.MemBuddy*, if child_ast.kind() != ast.ASTKind.ClassDef: continue child_cd: ast.ClassDef* = ast.ClassDef*(child_ast) if child_cd is None or child_cd.name is None or child_cd.name[0] == '\0': continue - _inject_class_struct_declare(pool, mod, child_cd, child_cd.name, trans, - src_sha1, imported_modules, from_imports, - prefix_name) + _inject_class_struct_declare(pool, mod, child_cd, child_cd.name, trans, src_sha1, imported_modules, from_imports, prefix_name) # ============================================================ @@ -2705,9 +2601,7 @@ def _inject_nested_class_declares(pool: memhub.MemBuddy*, # 均报 "use of undefined type"(值类型大小需已知)。vpi 注入类已 add_field 含字段(完整 Ty),在注册表可查时注册完整定义; # 指针引用(Ptr(Struct))无需——_scan_type_for_cross_module_refs 的 Ptr 分支添加 opaque 即可。 # ============================================================ -def _ensure_full_value_types(mod: mlirlite.LLVMModule*, - pool: memhub.MemBuddy*, - ty: mlirlite.LLVMType*) -> None: +def _ensure_full_value_types(mod: mlirlite.LLVMModule*, pool: memhub.MemBuddy*, ty: mlirlite.LLVMType*) -> None: """递归为值 struct / 数组元素 struct 注册完整定义(递归深度守卫)""" if mod is None or pool is None or ty is None: return match ty: @@ -2740,10 +2634,7 @@ def _ensure_full_value_types(mod: mlirlite.LLVMModule*, # Windows x64 ABI 小结构体(≤8 字节)按整数寄存器传、位兼容,且与定义侧同样降级 ⇒ 同符号签名仍逐字一致)。 # * TPV 内部函数/方法(存在 define 侧)→ Ptr(struct):与定义侧逐字一致,指针目标只需 opaque 声明(module_ensure_opaque_for_type)。 # ============================================================ -def _AggregateParamTy(mod: mlirlite.LLVMModule*, - pool: memhub.MemBuddy*, - ty: mlirlite.LLVMType*, - is_c_abi: int) -> mlirlite.LLVMType*: +def _AggregateParamTy(mod: mlirlite.LLVMModule*, pool: memhub.MemBuddy*, ty: mlirlite.LLVMType*, is_c_abi: int) -> mlirlite.LLVMType*: """裸结构体形参类型(C ABI 按值 / 内部 Ptr(struct),见上方注释)""" if mod is None or pool is None or ty is None: return ty if is_c_abi != 0: @@ -2769,15 +2660,7 @@ def _AggregateParamTy(mod: mlirlite.LLVMModule*, # vpi 里模块级全局变量(如 tokens.vp 的 _op_head: OpEntry* = None)需在当前模块创建 external global 声明(短名 @name,COFF 按名链接), # 否则跨模块 from-import 读取全局变量时 find_global_in_module 找不到 → 误杀「跨模块全局变量类型未知(stub 未注入)」。 # ============================================================ -def _inject_global_variable_declare(pool: memhub.MemBuddy*, - mod: mlirlite.LLVMModule*, - aa: ast.AnnAssign*, - trans: HT.Translator*, - imported_modules: str, - from_imports: str, - i32_ty: mlirlite.LLVMType*, - i8_ptr_ty: mlirlite.LLVMType*, - src_sha1: str) -> None: +def _inject_global_variable_declare(pool: memhub.MemBuddy*, mod: mlirlite.LLVMModule*, aa: ast.AnnAssign*, trans: HT.Translator*, imported_modules: str, from_imports: str, i32_ty: mlirlite.LLVMType*, i8_ptr_ty: mlirlite.LLVMType*, src_sha1: str) -> None: """从 vpi AnnAssign 创建模块级全局变量 external declare(mangled 名 @.)""" if pool is None or mod is None or aa is None or trans is None: return tgt_v: ast.AST* = aa.target @@ -2818,8 +2701,7 @@ def _inject_global_variable_declare(pool: memhub.MemBuddy*, # 解析注解类型(裸类 → Ptr(struct),CArray → 元素指针) resolved_v: mlirlite.LLVMType* = None if aa.annotation is not None: - resolved_v = GenApi.resolve_annotation_type( - pool, aa.annotation, imported_modules, from_imports, trans) + resolved_v = GenApi.resolve_annotation_type(pool, aa.annotation, imported_modules, from_imports, trans) if resolved_v is None: return # 类型解析失败跳过:调用侧有 fail-fast 定位 gv_ty_v: mlirlite.LLVMType* = resolved_v @@ -2863,17 +2745,7 @@ def _inject_global_variable_declare(pool: memhub.MemBuddy*, # 用 find_func_in_module 去重,创建 declare 并添加参数, # 注册到函数表。 # ============================================================ -def _inject_function_declare(pool: memhub.MemBuddy*, - mod: mlirlite.LLVMModule*, - fd: ast.FunctionDef*, - trans: HT.Translator*, - src_sha1: str, - imported_modules: str, - from_imports: str, - i32_ty: mlirlite.LLVMType*, - i8_ptr_ty: mlirlite.LLVMType*, - funcs_ptr: GenTypes.FuncEntry*, - max_funcs: int) -> None: +def _inject_function_declare(pool: memhub.MemBuddy*, mod: mlirlite.LLVMModule*, fd: ast.FunctionDef*, trans: HT.Translator*, src_sha1: str, imported_modules: str, from_imports: str, i32_ty: mlirlite.LLVMType*, i8_ptr_ty: mlirlite.LLVMType*, funcs_ptr: GenTypes.FuncEntry*, max_funcs: int) -> None: """为 FunctionDef 创建 declare 声明并注入到模块""" if fd.name is None: return @@ -2938,8 +2810,7 @@ def _inject_function_declare(pool: memhub.MemBuddy*, ret_annot_fd: str = _lookup_vpi_ret_annot(src_sha1, None, fd.name) if ret_annot_fd is not None: ret_ty = _resolve_vpi_ret_annot_str(pool, ret_annot_fd, i32_ty, i8_ptr_ty) if ret_ty is None and fd.returns is not None: - ret_ty = GenApi.resolve_annotation_type( - pool, fd.returns, imported_modules, from_imports, trans) + ret_ty = GenApi.resolve_annotation_type(pool, fd.returns, imported_modules, from_imports, trans) # 如果返回类型是纯 t.State(无实际类型),用 Void if ret_ty is None and fd.returns is not None: # t.State/t.CExtern 是存储类装饰器标记,非真实返回类型。 @@ -2952,9 +2823,7 @@ def _inject_function_declare(pool: memhub.MemBuddy*, if rk2_rt == ast.ASTKind.Name or rk2_rt == ast.ASTKind.Constant: is_pure_marker_rt = 1 elif rk2_rt == ast.ASTKind.Attribute: pm_at: ast.Attribute* = ast.Attribute*(fd.returns) - if pm_at.attr is not None and (string.strcmp(pm_at.attr, "State") == 0 - or string.strcmp(pm_at.attr, "CExtern") == 0 - or string.strcmp(pm_at.attr, "CExport") == 0): + if pm_at.attr is not None and (string.strcmp(pm_at.attr, "State") == 0 or string.strcmp(pm_at.attr, "CExtern") == 0 or string.strcmp(pm_at.attr, "CExport") == 0): is_pure_marker_rt = 1 if is_pure_marker_rt != 0: ret_ty = mlirlite.Void(pool) elif has_state != 0 or has_extern != 0 or has_export != 0: @@ -2965,9 +2834,7 @@ def _inject_function_declare(pool: memhub.MemBuddy*, # [S4 fail-fast] 有返回注解却解析不出类型 → 不再静默退 i32; # 无注解(fd.returns is None)是合法默认,保持下方 i32。 if ret_ty is None and fd.returns is not None: - GenApi.fatal_error( - fd.returns, f"extern 声明 '{fd.name}' 返回类型注解解析失败", - "NameError") + GenApi.fatal_error(fd.returns, f"extern 声明 '{fd.name}' 返回类型注解解析失败", "NameError") # 默认返回 i32 if ret_ty is None: ret_ty = i32_ty @@ -2977,8 +2844,7 @@ def _inject_function_declare(pool: memhub.MemBuddy*, mlirlite.module_ensure_opaque_for_type(mod, pool, ret_ty) # 创建 declare - func: mlirlite.Function* = mlirlite.create_declare( - pool, mod, mangled_name, ret_ty) + func: mlirlite.Function* = mlirlite.create_declare(pool, mod, mangled_name, ret_ty) if func is None: return # 提取参数并添加到 declare @@ -2995,9 +2861,7 @@ def _inject_function_declare(pool: memhub.MemBuddy*, # 返回垃圾大数 → for 循环 add_param 海量次 → Params 链超长, # dump 时步数哨兵误报"链表成环"。超限立即报错定位。 if param_count < 0 or param_count > 128: - stdio.printf( - "[VPIS] 参数数异常: 函数名=%s param_count=%d(fd.args=%llu,tree 可能被覆盖,终止)\n", - fd.name, param_count, uint64(fd.args)) + stdio.printf("[VPIS] 参数数异常: 函数名=%s param_count=%d(fd.args=%llu,tree 可能被覆盖,终止)\n", fd.name, param_count, uint64(fd.args)) # 终止点收敛:REPL 会话内 longjmp 回 REPL 循环(诊断已打印) VLogger.repl_abort() pi: sizet @@ -3013,8 +2877,7 @@ def _inject_function_declare(pool: memhub.MemBuddy*, # sizet→i32,跨模块 declare 参数宽错 → 调用侧 trunc 传参、 # callee 按宽类型读栈残留垃圾高位 → 参数巨值崩溃(SlotsBugTest # 根因)。段索引 = pi(模块级函数无 self,0=首参)。 - pseg_ty: mlirlite.LLVMType* = _resolve_vpi_param_annot_seg( - pool, src_sha1, None, fd.name, pi, i32_ty, i8_ptr_ty) + pseg_ty: mlirlite.LLVMType* = _resolve_vpi_param_annot_seg(pool, src_sha1, None, fd.name, pi, i32_ty, i8_ptr_ty) if pseg_ty is not None: match pseg_ty: case mlirlite.LLVMType.Struct(_, _, _): @@ -3026,8 +2889,7 @@ def _inject_function_declare(pool: memhub.MemBuddy*, case _: param_ty = pseg_ty elif ag.annotation is not None: - resolved_ty: mlirlite.LLVMType* = GenApi.resolve_annotation_type( - pool, ag.annotation, imported_modules, from_imports, trans) + resolved_ty: mlirlite.LLVMType* = GenApi.resolve_annotation_type(pool, ag.annotation, imported_modules, from_imports, trans) if resolved_ty is not None: # CArray 参数 → 元素指针 ty*(C 数组衰减,与编译侧一致)。 # 裸结构体参数 → _AggregateParamTy(同一判据)。 @@ -3041,16 +2903,12 @@ def _inject_function_declare(pool: memhub.MemBuddy*, else: # [S4 fail-fast] 有注解却解析不出类型 → 不再静默退 i8* # (无注解 ag.annotation is None 是合法默认,保持 i8*) - GenApi.fatal_error( - ag.annotation, - f"extern 声明 '{fd.name}' 形参 '{pname}' 类型注解解析失败", - "NameError") + GenApi.fatal_error(ag.annotation, f"extern 声明 '{fd.name}' 形参 '{pname}' 类型注解解析失败", "NameError") mlirlite.add_param(pool, func, param_ty, pname) # 文本缓存校验/修复:vpi tree args 可能被覆盖损坏(尾部默认参数丢失) # → declare 参数数不足 → 调用点缺参 → 被调函数读栈垃圾。用 vpi 文本 # 缓存的参数注解补全 declare 参数(与 define 参数数一致)。 - param_count = _repair_declare_params_from_text( - pool, func, src_sha1, None, fd.name, param_count, i32_ty, i8_ptr_ty) + param_count = _repair_declare_params_from_text(pool, func, src_sha1, None, fd.name, param_count, i32_ty, i8_ptr_ty) # *args 变长参数:标记 IsVarArg=1,使调用侧走 C ABI 参数提升 # (i8/i16 → i32,float → double),避免 %d/%x 等格式因参数按 i64 # 传递而读错(第二个 %x 读到第一个 i64 槽的高 4 字节)。 @@ -3067,9 +2925,7 @@ def _inject_function_declare(pool: memhub.MemBuddy*, # 越界写 perm_pool(覆盖当前模块 AST/表,SlotsBugTest 崩溃根因 # 候选)。与 param_count 哨兵(L1493-1497)对齐:垃圾值放弃 # 注册默认值(跨模块缺参调用走零值兜底),阻断越界写。 - stdio.printf( - "[VPIS] 默认参数数异常: 函数名=%s default_count=%d(tree 可能被覆盖,跳过默认值注册)\n", - fd.name, fd_default_count) + stdio.printf("[VPIS] 默认参数数异常: 函数名=%s default_count=%d(tree 可能被覆盖,跳过默认值注册)\n", fd.name, fd_default_count) fd_defaults = None fd_default_count = 0 else: fd_defaults = fd_dlist @@ -3077,8 +2933,7 @@ def _inject_function_declare(pool: memhub.MemBuddy*, # 注册到函数表(用裸名 fd.name,不是 mangled_name) if funcs_ptr is not None: cur_count: int = trans._func_count - if GenApi.add_func_to_table(funcs_ptr, cur_count, fd.name, func, max_funcs, - fd_defaults, fd_default_count, param_count, None, src_sha1) == 0: + if GenApi.add_func_to_table(funcs_ptr, cur_count, fd.name, func, max_funcs, fd_defaults, fd_default_count, param_count, None, src_sha1) == 0: trans._func_count = cur_count + 1 # 补全全局函数表 Spec(参数已全部添加,对齐 FuncGenDef 行为): # vpi 注入路径若不补全,跨模块 vtable 生成 find_func_entry_global() @@ -3092,18 +2947,7 @@ def _inject_function_declare(pool: memhub.MemBuddy*, # 方法混淆名 {src_sha1}.{ClassName}.{method};参数类型从 vpi 注解解析(self 无注解时默认为 i8*)。 # 注入正确签名可避免调用时 _ensure_method_declare 用实参类型创建错误 declare(如 size: sizet 被写成 i32 而非 i64)。 # ============================================================ -def _inject_method_declare(pool: memhub.MemBuddy*, - mod: mlirlite.LLVMModule*, - m_fd: ast.FunctionDef*, - cls_name: str, - trans: HT.Translator*, - src_sha1: str, - imported_modules: str, - from_imports: str, - i32_ty: mlirlite.LLVMType*, - i8_ptr_ty: mlirlite.LLVMType*, - funcs_ptr: GenTypes.FuncEntry*, - max_funcs: int) -> None: +def _inject_method_declare(pool: memhub.MemBuddy*, mod: mlirlite.LLVMModule*, m_fd: ast.FunctionDef*, cls_name: str, trans: HT.Translator*, src_sha1: str, imported_modules: str, from_imports: str, i32_ty: mlirlite.LLVMType*, i8_ptr_ty: mlirlite.LLVMType*, funcs_ptr: GenTypes.FuncEntry*, max_funcs: int) -> None: """为 ClassDef 内方法创建 declare 声明并注入到模块""" if m_fd is None or m_fd.name is None or cls_name is None: return if src_sha1 is None: return @@ -3141,8 +2985,7 @@ def _inject_method_declare(pool: memhub.MemBuddy*, ret_annot: str = _lookup_vpi_ret_annot(src_sha1, cls_name, m_fd.name) if ret_annot is not None: ret_ty = _resolve_vpi_ret_annot_str(pool, ret_annot, i32_ty, i8_ptr_ty) if ret_ty is None and m_fd.returns is not None: - ret_ty = GenApi.resolve_annotation_type( - pool, m_fd.returns, imported_modules, from_imports, trans) + ret_ty = GenApi.resolve_annotation_type(pool, m_fd.returns, imported_modules, from_imports, trans) # __new__ 无返回注解时推断为类指针(__new__ 返回 self 指针,默认 i32 会截断指针) if ret_ty is None and string.strcmp(m_fd.name, "__new__") == 0: cls_ty: mlirlite.LLVMType* = GenApi.get_struct_type(cls_name) @@ -3150,10 +2993,7 @@ def _inject_method_declare(pool: memhub.MemBuddy*, # [S4 fail-fast] 有返回注解却解析不出类型 → 不再静默退 i32; # __new__ 无注解、普通方法无注解均走下方 i32 合法默认。 if ret_ty is None and m_fd.returns is not None: - GenApi.fatal_error( - m_fd.returns, - f"extern 方法 '{cls_name}.{m_fd.name}' 返回类型注解解析失败", - "NameError") + GenApi.fatal_error(m_fd.returns, f"extern 方法 '{cls_name}.{m_fd.name}' 返回类型注解解析失败", "NameError") # __init__ 无返回注解 → 与定义端一致取 Void(定义端 # ClassGenVTable._translate_method 对 __init__ 恒 Void)。若按"普通方法无注解" # 退成下方 i32 默认,就会出现 declare i32 / define void 的返回类型分裂: @@ -3162,8 +3002,7 @@ def _inject_method_declare(pool: memhub.MemBuddy*, if ret_ty is None: ret_ty = i32_ty # 创建 declare - func: mlirlite.Function* = mlirlite.create_declare( - pool, mod, mangled_name, ret_ty) + func: mlirlite.Function* = mlirlite.create_declare(pool, mod, mangled_name, ret_ty) if func is None: return # 提取参数并添加到 declare @@ -3178,9 +3017,7 @@ def _inject_method_declare(pool: memhub.MemBuddy*, # 参数数上限哨兵(fail-fast):与 _inject_function_declare 同因 # (vpi tree 深层节点被覆盖损坏时 __len__() 返回垃圾大数)。 if param_count < 0 or param_count > 128: - stdio.printf( - "[VPIS] 参数数异常: 方法名=%s.%s param_count=%d(m_fd.args=%llu,tree 可能被覆盖,终止)\n", - cls_name, m_fd.name, param_count, uint64(m_fd.args)) + stdio.printf("[VPIS] 参数数异常: 方法名=%s.%s param_count=%d(m_fd.args=%llu,tree 可能被覆盖,终止)\n", cls_name, m_fd.name, param_count, uint64(m_fd.args)) # 终止点收敛:REPL 会话内 longjmp 回 REPL 循环(诊断已打印) VLogger.repl_abort() pi: sizet @@ -3194,8 +3031,7 @@ def _inject_method_declare(pool: memhub.MemBuddy*, # 签名一致,消除跨模块声明/定义歧义。调用侧按形参 coerce 自动 # bitcast(见 _call_method_on_ptr/_translate_method_call 的 coerce # 块)。类类型未注册时兜底走下方注解解析/i8*(保持原行为)。 - if pi == 0 and (string.strcmp(pname, "self") == 0 - or string.strcmp(pname, "cls") == 0): + if pi == 0 and (string.strcmp(pname, "self") == 0 or string.strcmp(pname, "cls") == 0): cls_ty_sd: mlirlite.LLVMType* = GenApi.get_struct_type(cls_name) if cls_ty_sd is not None: mlirlite.add_param(pool, func, mlirlite.Ptr(pool, cls_ty_sd), pname) @@ -3206,8 +3042,7 @@ def _inject_method_declare(pool: memhub.MemBuddy*, # sizet→i32,declare 参数宽错 → 调用侧 trunc i64→i32 传参、 # callee 按 i64 读栈残留垃圾高位 → can=巨值读未写槽位崩溃, # SlotsBugTest 根因)。段索引 = pi(0=self 空段)。 - pseg_ty: mlirlite.LLVMType* = _resolve_vpi_param_annot_seg( - pool, src_sha1, cls_name, m_fd.name, pi, i32_ty, i8_ptr_ty) + pseg_ty: mlirlite.LLVMType* = _resolve_vpi_param_annot_seg(pool, src_sha1, cls_name, m_fd.name, pi, i32_ty, i8_ptr_ty) if pseg_ty is not None: match pseg_ty: case mlirlite.LLVMType.Struct(_, _, _): @@ -3221,8 +3056,7 @@ def _inject_method_declare(pool: memhub.MemBuddy*, case _: param_ty = pseg_ty elif ag.annotation is not None: - resolved_ty: mlirlite.LLVMType* = GenApi.resolve_annotation_type( - pool, ag.annotation, imported_modules, from_imports, trans) + resolved_ty: mlirlite.LLVMType* = GenApi.resolve_annotation_type(pool, ag.annotation, imported_modules, from_imports, trans) if resolved_ty is not None: # CArray 参数 → 元素指针 ty*(C 数组衰减,与编译侧一致)。 # 裸结构体参数 → _AggregateParamTy(同一判据,is_c_abi=0)。 @@ -3236,18 +3070,14 @@ def _inject_method_declare(pool: memhub.MemBuddy*, else: # [S4 fail-fast] 有注解却解析不出类型 → 不再静默退 i8* # (无注解 ag.annotation is None 是合法默认,保持 i8*) - GenApi.fatal_error( - ag.annotation, - f"extern 方法 '{cls_name}.{m_fd.name}' 形参 '{pname}' 类型注解解析失败", - "NameError") + GenApi.fatal_error(ag.annotation, f"extern 方法 '{cls_name}.{m_fd.name}' 形参 '{pname}' 类型注解解析失败", "NameError") mlirlite.add_param(pool, func, param_ty, pname) # 文本缓存校验/修复:vpi tree args 可能被覆盖损坏(尾部默认参数丢失) # → declare 参数数不足 → 调用点缺参 → 被调函数读栈垃圾(跨模块 CDefine # 查找 depth=160 假递归根因)。用 vpi 文本缓存的参数注解补全 declare # 参数(与 define 参数数一致,调用点默认参数填充才能生效)。 - param_count = _repair_declare_params_from_text( - pool, func, src_sha1, cls_name, m_fd.name, param_count, i32_ty, i8_ptr_ty) + param_count = _repair_declare_params_from_text(pool, func, src_sha1, cls_name, m_fd.name, param_count, i32_ty, i8_ptr_ty) # OOP iter 协议:__next__ 方法 stub 声明带隐藏 __stop_iter_flag__(i1*), # 与 _translate_method 的 define 签名一致(对齐 TPC HandlesFunctions.py @@ -3268,9 +3098,7 @@ def _inject_method_declare(pool: memhub.MemBuddy*, if md_default_count < 0 or md_default_count > 128: # 同 _inject_function_declare:vpi tree 深层节点被覆盖时 # defaults len 可能为垃圾大数 → 越界写 perm_pool。放弃注册。 - stdio.printf( - "[VPIS] 默认参数数异常: 方法名=%s.%s default_count=%d(tree 可能被覆盖,跳过默认值注册)\n", - cls_name, m_fd.name, md_default_count) + stdio.printf("[VPIS] 默认参数数异常: 方法名=%s.%s default_count=%d(tree 可能被覆盖,跳过默认值注册)\n", cls_name, m_fd.name, md_default_count) md_defaults = None md_default_count = 0 else: md_defaults = md_dlist @@ -3283,8 +3111,7 @@ def _inject_method_declare(pool: memhub.MemBuddy*, cur_count: int = trans._func_count param_count_no_self: int = param_count if param_count_no_self > 0: param_count_no_self -= 1 - if GenApi.add_func_to_table(funcs_ptr, cur_count, lookup_name, func, max_funcs, - md_defaults, md_default_count, param_count_no_self, None, src_sha1) == 0: + if GenApi.add_func_to_table(funcs_ptr, cur_count, lookup_name, func, max_funcs, md_defaults, md_default_count, param_count_no_self, None, src_sha1) == 0: trans._func_count = cur_count + 1 # 补全全局函数表 Spec(参数已全部添加,对齐 ClassGenVTable 行为): # vpi 注入的方法声明若不补全 Spec,跨模块继承 vtable 生成时 @@ -3299,8 +3126,7 @@ def _inject_method_declare(pool: memhub.MemBuddy*, # 提取 NAME: t.CTypedef = Type 中的名称和类型表达式字符串, # 调用 register_ctypedef 注册到动态 CTypedef 表。 # ============================================================ -def _register_ctypedef_from_annassign(pool: memhub.MemBuddy*, - aa: ast.AnnAssign*) -> None: +def _register_ctypedef_from_annassign(pool: memhub.MemBuddy*, aa: ast.AnnAssign*) -> None: """从 AnnAssign 节点提取并注册 CTypedef""" if aa is None or pool is None: return # 提取目标名称(必须是 Name 节点) @@ -3610,8 +3436,7 @@ def _repl_stub_deco_flags(deco_list: list[ast.AST*]*) -> int: return flags -def _repl_stub_is_virtual(e: rawptr[ReplStubClass], mi: int, - first: rawptr[ReplStubClass]) -> int: +def _repl_stub_is_virtual(e: rawptr[ReplStubClass], mi: int, first: rawptr[ReplStubClass]) -> int: """本类第 mi 个方法是否进虚表(转写 ClassGenBase._should_method_be_virtual)""" if e is None or e.MethodFlags is None or mi < 0 or mi >= e.MethodCount: return 0 mf: int = int(e.MethodFlags[mi]) @@ -3630,10 +3455,7 @@ def _repl_stub_warn_refuse(e: rawptr[ReplStubClass], why: str, a: int, b: int) - ReplStubRefused += 1 if ReplStubWarnLeft <= 0: return ReplStubWarnLeft -= 1 - stdio.printf("includes 类布局: %s.%s 布局不可信 ⇒ 明确拒绝(原因=判据拒绝:%s;" - "存根字段数=%d ≠ 展平字段数+虚表位=%d)。该类字段访问被明确拒绝" - "(方法调用不受影响)\n", - e.Sha1, e.ClassName, why, a, b) + stdio.printf("includes 类布局: %s.%s 布局不可信 ⇒ 明确拒绝(原因=判据拒绝:%s;" "存根字段数=%d ≠ 展平字段数+虚表位=%d)。该类字段访问被明确拒绝" "(方法调用不受影响)\n", e.Sha1, e.ClassName, why, a, b) def _repl_stub_warn_nodata(e: rawptr[ReplStubClass], cause: int) -> None: @@ -3655,25 +3477,13 @@ def _repl_stub_warn_nodata(e: rawptr[ReplStubClass], cause: int) -> None: ReplStubWarnLeft -= 1 if cause == _REPL_SU_NOSTUB: # 数据缺失:连模块布局元数据都没有(LayoutCount = -1 只是"没读到"的哨兵) - stdio.printf("includes 类布局: %s.%s 布局不可用 ⇒ 明确拒绝(原因=『数据缺失』:" - "模块 %s 没有 {sha1}.meta 布局元数据;meta 字段数=无 / 推断字段数=未计算 ⇒ " - "两侧都没数据,『未做比较』,不是字段数不符)。该类字段访问被" - "拒绝(方法调用不受影响);补上该模块 meta(同一工程先跑一次批处理," - "Phase A/B 会落盘 {sha1}.meta)后用同一 --project 重跑 REPL 即恢复\n", - e.Sha1, e.ClassName, e.Sha1) + stdio.printf("includes 类布局: %s.%s 布局不可用 ⇒ 明确拒绝(原因=『数据缺失』:" "模块 %s 没有 {sha1}.meta 布局元数据;meta 字段数=无 / 推断字段数=未计算 ⇒ " "两侧都没数据,『未做比较』,不是字段数不符)。该类字段访问被" "拒绝(方法调用不受影响);补上该模块 meta(同一工程先跑一次批处理," "Phase A/B 会落盘 {sha1}.meta)后用同一 --project 重跑 REPL 即恢复\n", e.Sha1, e.ClassName, e.Sha1) elif cause == _REPL_SU_OPAQUE: # 判据拒绝:meta 里该 key 是 OPAQUE(无 body ⇒ 无字段数可比) - stdio.printf("includes 类布局: %s.%s 布局不可用 ⇒ 明确拒绝(原因=『判据拒绝』:" - "meta %s.meta 里键 %s 为 OPAQUE 声明(无 body);meta 字段数=不可得 / " - "推断字段数=未计算 ⇒ 『未做比较』)。该类字段访问被拒绝" - "(方法调用不受影响)\n", e.Sha1, e.ClassName, e.Sha1, e.Key) + stdio.printf("includes 类布局: %s.%s 布局不可用 ⇒ 明确拒绝(原因=『判据拒绝』:" "meta %s.meta 里键 %s 为 OPAQUE 声明(无 body);meta 字段数=不可得 / " "推断字段数=未计算 ⇒ 『未做比较』)。该类字段访问被拒绝" "(方法调用不受影响)\n", e.Sha1, e.ClassName, e.Sha1, e.Key) else: # 判据拒绝:meta 在,但没有该类的 STRUCT 行(LayoutCount = -1 只是"未找到"的哨兵) - stdio.printf("includes 类布局: %s.%s 布局不可用 ⇒ 明确拒绝(原因=『判据拒绝』:" - "meta %s.meta 存在但其中没有键 %s 的 `STRUCT … FIELDS n / OPAQUE` 记录;" - "meta 字段数=未找到 / 推断字段数=未计算 ⇒ 『未做比较』)。该类字段访问" - "被拒绝(方法调用不受影响);若该类确实定义于该模块,说明 meta 陈旧/" - "不完整,请重建\n", e.Sha1, e.ClassName, e.Sha1, e.Key) + stdio.printf("includes 类布局: %s.%s 布局不可用 ⇒ 明确拒绝(原因=『判据拒绝』:" "meta %s.meta 存在但其中没有键 %s 的 `STRUCT … FIELDS n / OPAQUE` 记录;" "meta 字段数=未找到 / 推断字段数=未计算 ⇒ 『未做比较』)。该类字段访问" "被拒绝(方法调用不受影响);若该类确实定义于该模块,说明 meta 陈旧/" "不完整,请重建\n", e.Sha1, e.ClassName, e.Sha1, e.Key) def _repl_stub_warn_parent(e: rawptr[ReplStubClass], detail: str, pname: str) -> None: @@ -3683,9 +3493,7 @@ def _repl_stub_warn_parent(e: rawptr[ReplStubClass], detail: str, pname: str) -> ReplStubRefusedParent += 1 if ReplStubWarnLeft <= 0: return ReplStubWarnLeft -= 1 - stdio.printf("includes 类布局: %s.%s 布局不可用 ⇒ 明确拒绝(原因=『上游无数据』:%s," - "父类=%s;父类字段与虚表位无法展平 ⇒ 本类未做字段数比较)。该类字段访问" - "被拒绝(方法调用不受影响)\n", e.Sha1, e.ClassName, detail, pname) + stdio.printf("includes 类布局: %s.%s 布局不可用 ⇒ 明确拒绝(原因=『上游无数据』:%s," "父类=%s;父类字段与虚表位无法展平 ⇒ 本类未做字段数比较)。该类字段访问" "被拒绝(方法调用不受影响)\n", e.Sha1, e.ClassName, detail, pname) def _repl_stub_try(e: rawptr[ReplStubClass], mod: mlirlite.LLVMModule*) -> int: @@ -3714,8 +3522,7 @@ def _repl_stub_try(e: rawptr[ReplStubClass], mod: mlirlite.LLVMModule*) -> int: # ⇒ 展平出来的本类字段数不可用:既不比较(避免误报"字段数不符")、也不放行 # (M4.2:布局不可信 ⇒ 明确拒绝)。 e.State = _REPL_SS_REFUSED - _repl_stub_warn_parent(e, "父类的字段类型未全部解析(其字段数不完整)", - pe.ClassName) + _repl_stub_warn_parent(e, "父类的字段类型未全部解析(其字段数不完整)", pe.ClassName) return -1 first: rawptr[ReplStubClass] = None if e.BaseCount > 0: first = _repl_stub_find_base(e, 0) @@ -3788,9 +3595,7 @@ def _repl_stub_try(e: rawptr[ReplStubClass], mod: mlirlite.LLVMModule*) -> int: if vn == e.VtArity: e.VtTrust = 1 elif ReplStubWarnLeft > 0: ReplStubWarnLeft -= 1 - stdio.printf("includes 类布局: %s.%s 的虚表槽数与存根不符(%d vs %d)" - "——该类不做虚分派(退化为直接调用,会话继续)\n", - e.Sha1, e.ClassName, vn, e.VtArity) + stdio.printf("includes 类布局: %s.%s 的虚表槽数与存根不符(%d vs %d)" "——该类不做虚分派(退化为直接调用,会话继续)\n", e.Sha1, e.ClassName, vn, e.VtArity) # ⑥ 建 LLVM 结构体(命名 "%.<类名>",与定义侧同口径) total: int = cn + hv i8_ptr: mlirlite.LLVMType* = mlirlite.Ptr(pool, mlirlite.Int8(pool)) @@ -3818,8 +3623,7 @@ def _repl_stub_try(e: rawptr[ReplStubClass], mod: mlirlite.LLVMModule*) -> int: struct_ty: mlirlite.LLVMType* = mlirlite.Struct(pool, first_node, total, e.Key) if struct_ty is None: return 0 # ⑦ 登记(StdlibAlloc=1 期间的注册走 PermPool,跨片段存活) - entry: GenTypes.StructEntry* = GenApi.register_struct( - pool, e.ClassName, struct_ty, e.Sha1) + entry: GenTypes.StructEntry* = GenApi.register_struct(pool, e.ClassName, struct_ty, e.Sha1) if entry is None: e.State = _REPL_SS_REFUSED return -1 @@ -3863,15 +3667,7 @@ def _repl_stub_try(e: rawptr[ReplStubClass], mod: mlirlite.LLVMModule*) -> int: return 1 -def _repl_stub_add_class(pool: memhub.MemBuddy*, - mod: mlirlite.LLVMModule*, - cd: ast.ClassDef*, - sha1: str, - txt: str, - have_stub: int, - trans: HT.Translator*, - imported_modules: str, - from_imports: str) -> int: +def _repl_stub_add_class(pool: memhub.MemBuddy*, mod: mlirlite.LLVMModule*, cd: ast.ClassDef*, sha1: str, txt: str, have_stub: int, trans: HT.Translator*, imported_modules: str, from_imports: str) -> int: """收集单个 vpi ClassDef 的布局要素并尝试登记(1=已登记/推迟处理,0=跳过) have_stub:本模块是否读到了 {sha1}.meta 布局元数据(0 时本模块带父类/虚表的类按 @@ -3918,8 +3714,7 @@ def _repl_stub_add_class(pool: memhub.MemBuddy*, bcnt: int = 0 if pb is not None and GenApi._g_gen is not None: string.memset(pb, 0, 8 * GenTypes.PARENT_MAX) - bcnt = GenApi._g_gen.ClassGenBase._collect_parents( - pool, cd, pb, GenTypes.PARENT_MAX, trans) + bcnt = GenApi._g_gen.ClassGenBase._collect_parents(pool, cd, pb, GenTypes.PARENT_MAX, trans) if bcnt > 0: if bcnt > _REPL_STUB_FIELD_MAX: bcnt = _REPL_STUB_FIELD_MAX bi: int @@ -3945,8 +3740,7 @@ def _repl_stub_add_class(pool: memhub.MemBuddy*, if aa2.target.kind() != ast.ASTKind.Name: continue tg: ast.Name* = ast.Name*(aa2.target) if tg.id is None or tg.id[0] == '\0': continue - fty2: mlirlite.LLVMType* = GenApi.resolve_annotation_type( - pool, aa2.annotation, imported_modules, from_imports, trans, 0) + fty2: mlirlite.LLVMType* = GenApi.resolve_annotation_type(pool, aa2.annotation, imported_modules, from_imports, trans, 0) if fty2 is None: own_fail = 1 continue @@ -4010,14 +3804,7 @@ def _repl_stub_add_class(pool: memhub.MemBuddy*, return 1 -def _repl_stub_collect_module(pool: memhub.MemBuddy*, - mod: mlirlite.LLVMModule*, - ch: list[ast.AST*]*, - n: sizet, - trans: HT.Translator*, - src_sha1: str, - imported_modules: str, - from_imports: str) -> int: +def _repl_stub_collect_module(pool: memhub.MemBuddy*, mod: mlirlite.LLVMModule*, ch: list[ast.AST*]*, n: sizet, trans: HT.Translator*, src_sha1: str, imported_modules: str, from_imports: str) -> int: """(REPL)为当前模块的类收集布局要素 + 尝试登记;返回处理的类数""" global ReplStubNoStub, ReplStubWarnLeft if ReplStubLayoutMode == 0 or pool is None or ch is None: return 0 @@ -4034,11 +3821,7 @@ def _repl_stub_collect_module(pool: memhub.MemBuddy*, ReplStubNoStub += 1 if ReplStubWarnLeft > 0: ReplStubWarnLeft -= 1 - stdio.printf("includes 类布局: 模块 %s 无 .meta 存根(数据缺失)—— 该模块" - "带父类/虚表的类将逐个按『数据缺失』明确拒绝(读不到布局元数据 ⇒ 无" - "字段数可比,不是字段数不符)。用同一工程先跑一次批处理生成存根," - "再 `--project .\\project.vpj --repl`(TransPyV 目录)即可复用\n", - src_sha1) + stdio.printf("includes 类布局: 模块 %s 无 .meta 存根(数据缺失)—— 该模块" "带父类/虚表的类将逐个按『数据缺失』明确拒绝(读不到布局元数据 ⇒ 无" "字段数可比,不是字段数不符)。用同一工程先跑一次批处理生成存根," "再 `--project .\\project.vpj --repl`(TransPyV 目录)即可复用\n", src_sha1) cnt: int = 0 i: sizet for i in range(n): @@ -4057,8 +3840,7 @@ def _repl_stub_collect_module(pool: memhub.MemBuddy*, continue # REnum 类:布局 {i32 tag, payload} 由 ClassGenEnum 计算,既有路径整体跳过 if _vpi_class_is_renum(cd) != 0: continue - if _repl_stub_add_class(pool, mod, cd, src_sha1, txt, have_stub, trans, - imported_modules, from_imports) != 0: + if _repl_stub_add_class(pool, mod, cd, src_sha1, txt, have_stub, trans, imported_modules, from_imports) != 0: cnt += 1 if txt is not None: stdlib.free(txt) return cnt @@ -4092,30 +3874,14 @@ def ReplStubLayoutFinish() -> int: if peb is not None and peb.ClassName is not None: pbad = peb.ClassName break _repl_stub_warn_parent(e2, "父类未在会话注册或其布局被拒", pbad) - stdio.printf("includes 类布局: 完整布局 %d 个(其中虚表索引可用 %d 个)/ " - "被拒 %d 个 / 缺布局元数据模块 %d 个\n", - ReplStubOk, ReplStubVtOk, ReplStubRefused, ReplStubNoStub) - stdio.printf(" 拒绝原因分布(自证数据来源):数据缺失-模块无 {sha1}.meta %d 个类 / " - "判据拒绝-meta 无此类 %d 个 / 判据拒绝-meta 为 opaque %d 个 / " - "上游无数据-父类不可用 %d 个\n", - ReplStubRefusedNoStub, ReplStubRefusedNoClass, - ReplStubRefusedOpaque, ReplStubRefusedParent) + stdio.printf("includes 类布局: 完整布局 %d 个(其中虚表索引可用 %d 个)/ " "被拒 %d 个 / 缺布局元数据模块 %d 个\n", ReplStubOk, ReplStubVtOk, ReplStubRefused, ReplStubNoStub) + stdio.printf(" 拒绝原因分布(自证数据来源):数据缺失-模块无 {sha1}.meta %d 个类 / " "判据拒绝-meta 无此类 %d 个 / 判据拒绝-meta 为 opaque %d 个 / " "上游无数据-父类不可用 %d 个\n", ReplStubRefusedNoStub, ReplStubRefusedNoClass, ReplStubRefusedOpaque, ReplStubRefusedParent) if ReplStubRefused > 0 or ReplStubNoStub > 0: - stdio.printf(" 说明:被拒类的字段访问会报『类未注册/属性访问失败』" - "(不按错偏移静默访问);方法调用不受影响。\n") + stdio.printf(" 说明:被拒类的字段访问会报『类未注册/属性访问失败』" "(不按错偏移静默访问);方法调用不受影响。\n") if ReplStubRefusedNoStub > 0: - stdio.printf(" 其中『数据缺失』的 %d 个类只是没读到模块布局元数据(本会话临时目录 %s " - "缺这些 {sha1}.meta):批处理才会落盘 meta(REPL 分支在 Phase1 之前" - "返回,故 --repl 自身不生成存根)。修法:用同一个工程跑一次批处理" - "(TransPyV 目录:.\\tpv_build\\output\\TransPyV.exe --project " - ".\\project.vpj;includes 有改动时加 --rebuild-includes),随后 " - "--project .\\project.vpj --repl 复用其临时目录即可\n", ReplStubRefusedNoStub, - ReplStubTempDir) + stdio.printf(" 其中『数据缺失』的 %d 个类只是没读到模块布局元数据(本会话临时目录 %s " "缺这些 {sha1}.meta):批处理才会落盘 meta(REPL 分支在 Phase1 之前" "返回,故 --repl 自身不生成存根)。修法:用同一个工程跑一次批处理" "(TransPyV 目录:.\\tpv_build\\output\\TransPyV.exe --project " ".\\project.vpj;includes 有改动时加 --rebuild-includes),随后 " "--project .\\project.vpj --repl 复用其临时目录即可\n", ReplStubRefusedNoStub, ReplStubTempDir) if ReplStubRefusedNoClass + ReplStubRefusedOpaque > 0: - stdio.printf(" 其中『判据拒绝』的 %d 个类:数据在但不可信(存根里没有该类的字段数、" - "或其声明为 opaque),按 M4.2 一律不放行——请确认该类是否本应按结构体" - "登记:应按结构体登记而存根里查不到 ⇒ 存根陈旧/不完整(重建 includes " - "存根)\n", ReplStubRefusedNoClass + ReplStubRefusedOpaque) + stdio.printf(" 其中『判据拒绝』的 %d 个类:数据在但不可信(存根里没有该类的字段数、" "或其声明为 opaque),按 M4.2 一律不放行——请确认该类是否本应按结构体" "登记:应按结构体登记而存根里查不到 ⇒ 存根陈旧/不完整(重建 includes " "存根)\n", ReplStubRefusedNoClass + ReplStubRefusedOpaque) return ReplStubOk diff --git a/App/lib/Stub/StubMerger/StubMergerBuild.vp b/App/lib/Stub/StubMerger/StubMergerBuild.vp index d9991f8..3855562 100644 --- a/App/lib/Stub/StubMerger/StubMergerBuild.vp +++ b/App/lib/Stub/StubMerger/StubMergerBuild.vp @@ -53,8 +53,7 @@ def _IsAppModule(mod_name: str) -> int: # Args: worklist 队列缓冲(原地修改);wl_len 当前长度(值);deps_str 要追加的模块名(空格分隔);processed 已处理集合(空格分隔,查重) # Returns: 追加后的新长度(>=0);溢出/参数错误返回 -1(调用方 fail-fast) # ============================================================ -def _AppendDepsToWorklist(worklist: bytes, wl_len: sizet, - deps_str: str, processed: str) -> int: +def _AppendDepsToWorklist(worklist: bytes, wl_len: sizet, deps_str: str, processed: str) -> int: if worklist is None or deps_str is None: return -1 cur_len: sizet = wl_len dl: sizet = string.strlen(deps_str) @@ -103,11 +102,7 @@ def _AppendDepsToWorklist(worklist: bytes, wl_len: sizet, # Args: mb 内存池;source_dir App 源文件目录(Config.SourceDir);temp_dir 临时目录(deps.txt 所在位置);reachable_set 输出参数,可达 SHA1 集合缓冲区(MAX_INCLUDES_SHA1 * 17 字节);app_deps App 源文件直接依赖模块名(空格分隔),非空则跳过 App 扫描;includes_dirs includes 根目录(空格分隔) # Returns: 可达 SHA1 数量(>0 成功;0 无 includes 依赖;<0 失败) # ============================================================ -def _BuildReachableSha1Set(mb: memhub.MemBuddy*, source_dir: str, - temp_dir: str, - reachable_set: str, - app_deps: str = None, - includes_dirs: str = None) -> int: +def _BuildReachableSha1Set(mb: memhub.MemBuddy*, source_dir: str, temp_dir: str, reachable_set: str, app_deps: str = None, includes_dirs: str = None) -> int: """构建可达 SHA1 集合(依赖图按需扫描,App 优先)""" if source_dir is None or temp_dir is None or reachable_set is None: return -1 if includes_dirs is None: @@ -241,8 +236,7 @@ def _BuildReachableSha1Set(mb: memhub.MemBuddy*, source_dir: str, tb_abs_slot[0] = 0 tb_rel_slot[0] = 0 tb_inc_slot[0] = 0 - tb_found = IncludesScanner.ResolveModuleToPath( - includes_dirs, "traceback", tb_abs, tb_rel, tb_inc) + tb_found = IncludesScanner.ResolveModuleToPath(includes_dirs, "traceback", tb_abs, tb_rel, tb_inc) if tb_abs is not None: stdlib.free(tb_abs) if tb_rel is not None: stdlib.free(tb_rel) if tb_inc is not None: stdlib.free(tb_inc) @@ -344,8 +338,7 @@ def _BuildReachableSha1Set(mb: memhub.MemBuddy*, source_dir: str, abs_slot[0] = 0 rel_slot[0] = 0 inc_slot[0] = 0 - rcode: int = IncludesScanner.ResolveModuleToPath( - includes_dirs, mod_buf, out_abs, out_rel, out_inc) + rcode: int = IncludesScanner.ResolveModuleToPath(includes_dirs, mod_buf, out_abs, out_rel, out_inc) if rcode != 0: # 内建模块(t/c/builtins 等内部库)或未找到:静默跳过 stdlib.free(out_abs) @@ -542,8 +535,7 @@ def _BuildReachableSha1Set(mb: memhub.MemBuddy*, source_dir: str, # (类型定义 + external 声明 + 定义 + DI 一次齐全,类型定义天然在声明之前), # 无需再把 stub + 依赖 stub/text 文本合并。 # ============================================================ -def LoadFullIR(temp_dir: str, sha1: str, - out_buf: bytes, out_size: sizet) -> sizet: +def LoadFullIR(temp_dir: str, sha1: str, out_buf: bytes, out_size: sizet) -> sizet: """读取 {sha1}.full.ll 到 out_buf;返回长度(0=失败)""" if temp_dir is None or sha1 is None or out_buf is None or out_size == 0: return 0 td_len: sizet = string.strlen(temp_dir) @@ -573,12 +565,7 @@ def LoadFullIR(temp_dir: str, sha1: str, # Args: pool 内存池;mod 当前 LLVM 模块;imported_modules 已导入模块名字符串(空格分隔);from_imports from-import 映射字符串("name:module name:module" 格式);temp_dir temp 目录路径;trans 翻译器对象 # Returns: 成功加载的 .vpi 文件数 # ============================================================ -def LoadDepVpiIntoModule(pool: memhub.MemBuddy*, - mod: mlirlite.LLVMModule*, - imported_modules: str, - from_imports: str, - temp_dir: str, - trans: rawptr[HandlesTranslator.Translator]) -> int: +def LoadDepVpiIntoModule(pool: memhub.MemBuddy*, mod: mlirlite.LLVMModule*, imported_modules: str, from_imports: str, temp_dir: str, trans: rawptr[HandlesTranslator.Translator]) -> int: """加载依赖模块的 .vpi 文件,将函数声明注入到当前模块""" if pool is None or mod is None or temp_dir is None or trans is None: return 0 if imported_modules is None: return 0 diff --git a/App/lib/Stub/StubMerger/StubMergerCollect.vp b/App/lib/Stub/StubMerger/StubMergerCollect.vp index c57eeb3..a3e2ac1 100644 --- a/App/lib/Stub/StubMerger/StubMergerCollect.vp +++ b/App/lib/Stub/StubMerger/StubMergerCollect.vp @@ -84,9 +84,7 @@ def _sliced_path(temp_dir: str, td_len: sizet, sha1: str, ext: str) -> str: # 数据来源是 PopulateSha1MapStore 填充的全局存储器(不读取 _sha1_map.txt)。 # 用于过滤 stub 文件,避免加载 TransPyV 自身源文件(lib/*)的 stub 导致链接失败。 # ============================================================ -def _load_includes_sha1_set(pool: memhub.MemBuddy*, - temp_dir: str, - sha1_set: str) -> int: +def _load_includes_sha1_set(pool: memhub.MemBuddy*, temp_dir: str, sha1_set: str) -> int: """从全局内存存储器将 includes 的 SHA1 写入 sha1_set pool/temp_dir 参数保留以兼容现有调用者,但不再使用。 @@ -118,10 +116,7 @@ def _is_in_sha1_set(sha1: str, sha1_set: str, set_count: int) -> int: # Args: mb 内存池;temp_dir 临时目录(_sha1_map.txt 写入位置);scan_result IncludesScanner 扫描结果 # Returns: 0 成功,非 0 失败 # ============================================================ -def WriteIncludesSha1Map(mb: memhub.MemBuddy*, temp_dir: str, - scan_result: rawptr[IncludesScanner.ScanResult], - filter_set: str, - filter_count: int) -> int: +def WriteIncludesSha1Map(mb: memhub.MemBuddy*, temp_dir: str, scan_result: rawptr[IncludesScanner.ScanResult], filter_set: str, filter_count: int) -> int: """将 includes 扫描结果写入 _sha1_map.txt(人类可读输出,程序内部使用内存存储器) 若 filter_set 不为 None 且 filter_count > 0,只写入 filter_set 中的条目。 diff --git a/App/lib/Stub/StubMerger/StubMergerIR.vp b/App/lib/Stub/StubMerger/StubMergerIR.vp index cf2bac4..d19275e 100644 --- a/App/lib/Stub/StubMerger/StubMergerIR.vp +++ b/App/lib/Stub/StubMerger/StubMergerIR.vp @@ -47,8 +47,7 @@ import lib.Stub.StubMerger as StubMerger # Args: mod 已翻译完成的 LLVM 模块;temp_dir 基础目录;td_len temp_dir 长度;sha1 模块 SHA1 # Returns: 0=成功(失败经 VLogger.error 终止进程) # ============================================================ -def WriteModuleMeta(mod: mlirlite.LLVMModule*, temp_dir: str, - td_len: sizet, sha1: str) -> int: +def WriteModuleMeta(mod: mlirlite.LLVMModule*, temp_dir: str, td_len: sizet, sha1: str) -> int: """把本模块的函数定义/结构体布局/虚表清单写入 {sha1}.meta""" if mod is None or temp_dir is None or sha1 is None: VLogger.error("meta 写出:参数为空", "Meta") @@ -216,9 +215,7 @@ def _is_submodule_of_imported(deps_buf: str, mod_name: str) -> int: # 返回两个数组(sha1_list 和 mod_list),长度存储在 count 中。 # 所有内存由 stdlib.malloc 分配,调用者负责释放。 # ============================================================ -def _BuildIncludesSha1Map(temp_dir: str, td_len: sizet, - sha1_list: str, - mod_list: str) -> int: +def _BuildIncludesSha1Map(temp_dir: str, td_len: sizet, sha1_list: str, mod_list: str) -> int: """从全局内存存储器复制 sha1→module_name 映射到调用者数组 temp_dir/td_len 参数保留以兼容现有调用者,但不再使用。 @@ -241,8 +238,7 @@ def _BuildIncludesSha1Map(temp_dir: str, td_len: sizet, # Args: sha1_arr SHA1 数组(每个 17 字节);mod_arr 模块名数组(每个 64 字节);count 映射条目数;mod_name 要查找的模块名 # Returns: SHA1 字符串指针(指向 sha1_arr 内部,无需释放),未找到返回 None # ============================================================ -def _FindSha1ByModName(sha1_arr: str, mod_arr: str, - count: int, mod_name: str) -> str: +def _FindSha1ByModName(sha1_arr: str, mod_arr: str, count: int, mod_name: str) -> str: """从模块名查找 SHA1(精确匹配 + 包名回退) 精确匹配失败时,尝试 "{mod_name}.__init__" 回退, diff --git a/App/lib/Stub/StubMerger/StubMergerStore.vp b/App/lib/Stub/StubMerger/StubMergerStore.vp index 1d0bb1b..e89a05b 100644 --- a/App/lib/Stub/StubMerger/StubMergerStore.vp +++ b/App/lib/Stub/StubMerger/StubMergerStore.vp @@ -80,8 +80,7 @@ def AppendImportedModule(pool: memhub.MemBuddy*, cur: str, name: str) -> str: # 该条目在查找侧仍被当作合法条目解析出错误的 local/mod/orig ⇒ 跨模块类名/ # 别名还原取到错名字(污染 Spec.SourceName)。此处按精确长度分配,无上限。 # ============================================================ -def AppendFromImport(pool: memhub.MemBuddy*, cur: str, - local: str, mod: str, orig: str) -> str: +def AppendFromImport(pool: memhub.MemBuddy*, cur: str, local: str, mod: str, orig: str) -> str: """追加 from-import 映射(pool 分配),返回新列表""" if local is None or mod is None: return cur llen: sizet = string.strlen(local) @@ -116,8 +115,7 @@ def AppendFromImport(pool: memhub.MemBuddy*, cur: str, # ============================================================ # AllocImportCtx - 用两个既有上下文串构造记账容器 # ============================================================ -def AllocImportCtx(pool: memhub.MemBuddy*, - imported_modules: str, from_imports: str) -> ImportCtx*: +def AllocImportCtx(pool: memhub.MemBuddy*, imported_modules: str, from_imports: str) -> ImportCtx*: """构造导入上下文容器(pool 分配);两串可为 None""" ctx: ImportCtx* = pool.alloc(ImportCtx.__sizeof__()) if ctx is None: return None @@ -134,8 +132,7 @@ def AllocImportCtx(pool: memhub.MemBuddy*, # 无别名:`import a.b.c` 时把顶层包名 `a` 也追加(使 a.b.c 作为属性访问 base # 时 is_module_imported("a") 放行)。 # ============================================================ -def NotePlainImport(pool: memhub.MemBuddy*, ctx: ImportCtx*, - name: str, asname: str) -> int: +def NotePlainImport(pool: memhub.MemBuddy*, ctx: ImportCtx*, name: str, asname: str) -> int: """记账单条 import(就地更新 ctx),返回 0""" if ctx is None or name is None: return 1 ctx.ImportedModules = AppendImportedModule(pool, ctx.ImportedModules, name) @@ -151,8 +148,7 @@ def NotePlainImport(pool: memhub.MemBuddy*, ctx: ImportCtx*, if pkg_buf is not None: string.strncpy(pkg_buf, name, pkg_len) pkg_buf[pkg_len] = '\0' - ctx.ImportedModules = AppendImportedModule( - pool, ctx.ImportedModules, pkg_buf) + ctx.ImportedModules = AppendImportedModule(pool, ctx.ImportedModules, pkg_buf) return 0 diff --git a/App/lib/Stub/StubMerger/StubMergerTopo.vp b/App/lib/Stub/StubMerger/StubMergerTopo.vp index 19f25fc..7ef74a1 100644 --- a/App/lib/Stub/StubMerger/StubMergerTopo.vp +++ b/App/lib/Stub/StubMerger/StubMergerTopo.vp @@ -41,10 +41,7 @@ import lib.Stub.StubMerger as StubMerger # Args: store_count / store_sha1_arr / store_mod_arr store 元数据;reachable_set / reachable_count 可达集合(_BuildReachableSha1Set 输出);sorted_idx 输出数组(store_count+1 个 8 字节槽),前 N 个为拓扑序 store 索引 # Returns: 拓扑序条数;有环时剩余条目按 store 顺序补齐(避免漏编译) # ============================================================ -def BuildTopoSortedIndices(store_count: int, store_sha1_arr: bytes, - store_mod_arr: bytes, reachable_set: bytes, - reachable_count: int, - sorted_idx: sizet*) -> int: +def BuildTopoSortedIndices(store_count: int, store_sha1_arr: bytes, store_mod_arr: bytes, reachable_set: bytes, reachable_count: int, sorted_idx: sizet*) -> int: """对可达 includes 逆拓扑排序(被依赖者先),store 索引写入 sorted_idx""" if store_count <= 0 or store_sha1_arr is None or store_mod_arr is None or sorted_idx is None: return 0 indegree: sizet* = (sizet*)(stdlib.malloc(8 * (store_count + 1))) diff --git a/App/lib/core/Gen/AssignGenMixin.vp b/App/lib/core/Gen/AssignGenMixin.vp index d3ccecb..7193a1b 100644 --- a/App/lib/core/Gen/AssignGenMixin.vp +++ b/App/lib/core/Gen/AssignGenMixin.vp @@ -208,8 +208,7 @@ novirtual class AssignGenMixin: if self._is_cdefine_marker_node(bop.left) != 0: return None return bop.left - def _annot_int_bits(self, pool: memhub.MemBuddy*, - annot: ast.AST*) -> int: + def _annot_int_bits(self, pool: memhub.MemBuddy*, annot: ast.AST*) -> int: """任意整数类型注解节点 → 位宽(bit);无注解 / 非整数 / 无法判定 → 0。 名称解析与 TPC EnumMemberAnnotationIntWidth 同源:t 模块类型名走 @@ -246,8 +245,7 @@ novirtual class AssignGenMixin: case _: return 0 - def _define_annot_bits(self, pool: memhub.MemBuddy*, - annot: ast.AST*) -> int: + def _define_annot_bits(self, pool: memhub.MemBuddy*, annot: ast.AST*) -> int: """CDefine 声明注解 → 显式类型 T 的整数位宽(bit)。 无显式类型(`t.CDefine` 单标记 / T 不在联合首位)⇒ 0(走 64 位口径)。 @@ -344,8 +342,7 @@ novirtual class AssignGenMixin: c2: char = text[j2] j2 += 1 if c2 == '_': continue - if not ((c2 >= '0' and c2 <= '9') or (c2 >= 'a' and c2 <= 'f') - or (c2 >= 'A' and c2 <= 'F')): + if not ((c2 >= '0' and c2 <= '9') or (c2 >= 'a' and c2 <= 'f') or (c2 >= 'A' and c2 <= 'F')): return 0 if leading != 0 and c2 == '0': continue leading = 0 @@ -384,9 +381,7 @@ novirtual class AssignGenMixin: d += 1 return 0 - def require_cdefine_storable(self, pool: memhub.MemBuddy*, - node: ast.AST*, name: str, - value: int64, annot: ast.AST*) -> None: + def require_cdefine_storable(self, pool: memhub.MemBuddy*, node: ast.AST*, name: str, value: int64, annot: ast.AST*) -> None: """CDefine / define 常量注册前的可存储性校验(fail-fast,与 TPC 同口径)。 判据(顺序固定): @@ -400,15 +395,7 @@ novirtual class AssignGenMixin: bits: int = self._define_annot_bits(pool, annot) wmin: int = self.define_min_width(value) if self._int_text_exceeds_64(text) != 0: - self.Gen.TypeGenErr.fatal_error(node, - f"[TPV] define 常量数值不可存储: 常量 '{name}' 的初始值 {text} 超出 64 位" - f"(本语言最宽的整数类型为 64 位,按有符号/无符号两种解释的可存储范围为 " - f"-9223372036854775808..18446744073709551615,不存在更宽的整数类型 ⇒ 需要扩容)。" - f"禁止静默截断/降级,已终止编译。可用整数类型: int8/uint8、" - f"int16/uint16、int32/uint32、int64/uint64" - f"(或 int8/uint8/…/uint64、char、sizet)。" - f"修法: 把值改到 64 位范围内,或为该数字引入更大的整数类型(扩容)。", - "TypeError") + self.Gen.TypeGenErr.fatal_error(node, f"[TPV] define 常量数值不可存储: 常量 '{name}' 的初始值 {text} 超出 64 位" f"(本语言最宽的整数类型为 64 位,按有符号/无符号两种解释的可存储范围为 " f"-9223372036854775808..18446744073709551615,不存在更宽的整数类型 ⇒ 需要扩容)。" f"禁止静默截断/降级,已终止编译。可用整数类型: int8/uint8、" f"int16/uint16、int32/uint32、int64/uint64" f"(或 int8/uint8/…/uint64、char、sizet)。" f"修法: 把值改到 64 位范围内,或为该数字引入更大的整数类型(扩容)。", "TypeError") return if bits == 0: return # 32 位档的上下界用**安全字面量**构造(同一字面量纪律,见 define_min_width): @@ -426,19 +413,9 @@ novirtual class AssignGenMixin: hi = 65535 elif bits == 64: return if value < lo or value > hi: - self.Gen.TypeGenErr.fatal_error(node, - f"[TPV] define 常量数值不可存储: 常量 '{name}' 的初始值 {value} 不可存储。" - f"最小可容纳宽度 W_min: {wmin} 位;声明类型位宽 {bits} 位," - f"该声明可存储范围: {lo}..{hi}。" - f"禁止静默截断/降级,已终止编译。" - f"修法: 把显式类型改为更宽的类型(如 int32 / int64 / uint64)," - f"或修正该字面量。", - "TypeError") + self.Gen.TypeGenErr.fatal_error(node, f"[TPV] define 常量数值不可存储: 常量 '{name}' 的初始值 {value} 不可存储。" f"最小可容纳宽度 W_min: {wmin} 位;声明类型位宽 {bits} 位," f"该声明可存储范围: {lo}..{hi}。" f"禁止静默截断/降级,已终止编译。" f"修法: 把显式类型改为更宽的类型(如 int32 / int64 / uint64)," f"或修正该字面量。", "TypeError") - def require_cdefine_use_width(self, pool: memhub.MemBuddy*, - trans: HT.Translator*, - target_annot: ast.AST*, - value_node: ast.AST*) -> None: + def require_cdefine_use_width(self, pool: memhub.MemBuddy*, trans: HT.Translator*, target_annot: ast.AST*, value_node: ast.AST*) -> None: """**使用处宽度**校验(`a: T = C` 场景,fail-fast;与 TPC 同口径)。 仅当满足全部条件时生效(其余情况零副作用、原样返回): @@ -462,14 +439,7 @@ novirtual class AssignGenMixin: if bits == 0: return wmin: int = self.define_min_width(cdef_val) if bits >= wmin: return - self.Gen.TypeGenErr.fatal_error(value_node, - f"[TPV] define 常量使用处宽度不足: 常量 '{rn.id}' 的实际值 {cdef_val} " - f"需要至少 {wmin} 位(最小可容纳宽度 W_min)," - f"但使用处(变量声明注解)只提供 {bits} 位。" - f"禁止静默截断/降级,已终止编译。" - f"修法: 把变量声明注解加宽到至少 {wmin} 位(如 int{wmin}T / CUInt{wmin}T)," - f"或改用更小的常量值。", - "TypeError") + self.Gen.TypeGenErr.fatal_error(value_node, f"[TPV] define 常量使用处宽度不足: 常量 '{rn.id}' 的实际值 {cdef_val} " f"需要至少 {wmin} 位(最小可容纳宽度 W_min)," f"但使用处(变量声明注解)只提供 {bits} 位。" f"禁止静默截断/降级,已终止编译。" f"修法: 把变量声明注解加宽到至少 {wmin} 位(如 int{wmin}T / CUInt{wmin}T)," f"或改用更小的常量值。", "TypeError") # ============================================================ # _register_cdefine_from_value - 注册 CDefine 常量(浮点/整数自动识别) @@ -481,9 +451,7 @@ novirtual class AssignGenMixin: # annot:该 AnnAssign 的注解(`T | t.CDefine` / `t.CDefine`),用于注册前的 # 可存储性校验(require_cdefine_storable);不传则退化为"无显式类型"口径。 # ============================================================ - def _register_cdefine_from_value(self, pool: memhub.MemBuddy*, - name: str, val_node: ast.AST*, - annot: ast.AST* = None) -> None: + def _register_cdefine_from_value(self, pool: memhub.MemBuddy*, name: str, val_node: ast.AST*, annot: ast.AST* = None) -> None: """注册 CDefine 常量(浮点字面量 → register_cdefine_double,否则整数)""" if pool is None or name is None: return # Call 包装的常量:如 PI: t.CDefine = float(3.14159...) / @@ -545,8 +513,7 @@ novirtual class AssignGenMixin: """检查最近一次 _recover_cdefine_float 是否成功""" return self.RecoverFound - def _recover_float_literal(self, name: str, out: double*, - require_cdefine: int) -> int: + def _recover_float_literal(self, name: str, out: double*, require_cdefine: int) -> int: """从当前模块源文件按变量名恢复浮点字面量,写入 out[0],成功返回 1 用输出参数传递 double,避免 TPV 跨模块 double 返回值传递 bug。 @@ -617,9 +584,7 @@ novirtual class AssignGenMixin: has_cd: int = 0 ci: sizet = line_start + name_len + 1 while ci + 8 <= line_start + line_len: - if (buf[ci] == 't' and buf[ci + 1] == '.' and buf[ci + 2] == 'C' and - buf[ci + 3] == 'D' and buf[ci + 4] == 'e' and buf[ci + 5] == 'f' and - buf[ci + 6] == 'i' and buf[ci + 7] == 'n' and buf[ci + 8] == 'e'): + if (buf[ci] == 't' and buf[ci + 1] == '.' and buf[ci + 2] == 'C' and buf[ci + 3] == 'D' and buf[ci + 4] == 'e' and buf[ci + 5] == 'f' and buf[ci + 6] == 'i' and buf[ci + 7] == 'n' and buf[ci + 8] == 'e'): has_cd = 1 break ci += 1 @@ -743,9 +708,7 @@ novirtual class AssignGenMixin: if self._is_64bit_scalar_ty(bop.left) != 0 or self._is_64bit_scalar_ty(bop.right) != 0: return 1 return 0 - def _stg_ty_equal(self, pool: memhub.MemBuddy*, - ta: mlirlite.LLVMType*, - tb: mlirlite.LLVMType*) -> int: + def _stg_ty_equal(self, pool: memhub.MemBuddy*, ta: mlirlite.LLVMType*, tb: mlirlite.LLVMType*) -> int: """类型内容相等比较(storage 绑定判定用)。 mlirlite 类型非 canonical:Ptr/Struct 每次构造都 pool.alloc 新实例 @@ -934,13 +897,7 @@ novirtual class AssignGenMixin: # Returns: # 0 成功,1 失败 # ============================================================ - def _init_global_array_from_list(self, builder: mlirlite.IRBuilder*, - pool: memhub.MemBuddy*, - mod: mlirlite.LLVMModule*, - array_alloca: mlirlite.Value*, - list_node: ast.AST*, - trans: HT.Translator*, - owner_ctx: str = None) -> int: + def _init_global_array_from_list(self, builder: mlirlite.IRBuilder*, pool: memhub.MemBuddy*, mod: mlirlite.LLVMModule*, array_alloca: mlirlite.Value*, list_node: ast.AST*, trans: HT.Translator*, owner_ctx: str = None) -> int: """从列表字面量初始化全局数组,为每个元素生成 GEP + store owner_ctx: 站点描述(如 "类 X 字段 y"),仅用于空元素 fail-fast 报文, @@ -979,9 +936,7 @@ novirtual class AssignGenMixin: if sv_s is not None: n_s: sizet = string.strlen(sv_s) if sizet(arr_count) < n_s: - self.Gen.TypeGenErr.fatal_error(list_node, - f"字符串字面量长度 {n_s} 超过字符数组声明长度 {arr_count},不允许越界写入", - "OverflowError") + self.Gen.TypeGenErr.fatal_error(list_node, f"字符串字面量长度 {n_s} 超过字符数组声明长度 {arr_count},不允许越界写入", "OverflowError") bi_s: sizet = 0 while bi_s < n_s: bidx_s: mlirlite.Value* = mlirlite.const_int32(pool, bi_s) @@ -995,9 +950,7 @@ novirtual class AssignGenMixin: # 元素数超过声明长度 → fail-fast(否则会生成 idx>=N 的越界 GEP 写) if arr_count > 0 and sizet(arr_count) < elts_count: - self.Gen.TypeGenErr.fatal_error(list_node, - f"数组初始化元素数 {elts_count} 超过数组声明长度 {arr_count},不允许越界写入", - "OverflowError") + self.Gen.TypeGenErr.fatal_error(list_node, f"数组初始化元素数 {elts_count} 超过数组声明长度 {arr_count},不允许越界写入", "OverflowError") # 为每个元素生成 GEP + store for i in range(elts_count): @@ -1041,12 +994,7 @@ novirtual class AssignGenMixin: if list_node is not None: src_line = list_node.lineno src_col = list_node.col_offset - self.Gen.TypeGenErr.fatal_error(list_node, - f"全局数组初始化遇到空 AST 元素:{ctx_dbg}第 {i} 个元素为裸空指针(0)," - f"但列表元素计数为 {elts_count}(元素与计数不一致)。" - f"上层某处产生了空 AST 元素(列表字面量节点 {src_line}:{src_col} 的第 {i} 槽未被填充)," - f"拒绝静默跳过/补零,已终止编译。", - "ValueError") + self.Gen.TypeGenErr.fatal_error(list_node, f"全局数组初始化遇到空 AST 元素:{ctx_dbg}第 {i} 个元素为裸空指针(0)," f"但列表元素计数为 {elts_count}(元素与计数不一致)。" f"上层某处产生了空 AST 元素(列表字面量节点 {src_line}:{src_col} 的第 {i} 槽未被填充)," f"拒绝静默跳过/补零,已终止编译。", "ValueError") return 1 # === 对象有效性校验(vptr 非 0)=== # 上一条只判"指针非 0";@t.CVTable 类的虚调用(kind()/dump()/...) 经对象首字 @@ -1067,14 +1015,7 @@ novirtual class AssignGenMixin: if list_node is not None: vt_line = list_node.lineno vt_col = list_node.col_offset - self.Gen.TypeGenErr.fatal_error(list_node, - f"全局数组初始化遇到【对象无效】的 AST 元素(vptr 为 0):{ctx_vt}" - f"第 {i} 个元素指针非 0(地址 {uint64(elem_node)})但其对象首字(vtable 指针)为 0," - f"对它的任何虚调用(kind()/dump()/…) 都会在 `load [0+slot]` 处读地址 0。" - f"列表字面量节点位置 {vt_line}:{vt_col},元素计数 {elts_count}。" - f"上层某处产生了「未初始化 vptr 的 AST 节点」(典型源:深拷贝/整块拷贝只搬字段未搬 vptr)," - f"拒绝继续,已终止编译。", - "ValueError", vt_col) + self.Gen.TypeGenErr.fatal_error(list_node, f"全局数组初始化遇到【对象无效】的 AST 元素(vptr 为 0):{ctx_vt}" f"第 {i} 个元素指针非 0(地址 {uint64(elem_node)})但其对象首字(vtable 指针)为 0," f"对它的任何虚调用(kind()/dump()/…) 都会在 `load [0+slot]` 处读地址 0。" f"列表字面量节点位置 {vt_line}:{vt_col},元素计数 {elts_count}。" f"上层某处产生了「未初始化 vptr 的 AST 节点」(典型源:深拷贝/整块拷贝只搬字段未搬 vptr)," f"拒绝继续,已终止编译。", "ValueError", vt_col) return 1 idx_val: mlirlite.Value* = mlirlite.const_int32(pool, i) elem_ptr: mlirlite.Value* = mlirlite.build_gep_array(builder, arr_ty, elem_ty, array_alloca, idx_val) @@ -1108,14 +1049,7 @@ novirtual class AssignGenMixin: # 支持浮点运算、指针算术: ptr += int / ptr -= int # 整数运算自动类型提升 # ============================================================ - def _apply_aug_op(self, pool: memhub.MemBuddy*, - builder: mlirlite.IRBuilder*, - op: int, - lhs: mlirlite.Value*, - rhs: mlirlite.Value*, - node: ast.AST* = None, - trans: HT.Translator* = None, - lhs_node: ast.AST* = None) -> mlirlite.Value*: + def _apply_aug_op(self, pool: memhub.MemBuddy*, builder: mlirlite.IRBuilder*, op: int, lhs: mlirlite.Value*, rhs: mlirlite.Value*, node: ast.AST* = None, trans: HT.Translator* = None, lhs_node: ast.AST* = None) -> mlirlite.Value*: """应用增强赋值的二元运算(浮点 + 指针算术 + 整数运算)""" # `**=` 幂运算:基础类型 → llvm.pow(与 BinOp 共用 ExprGenOps.emit_pow) if op == ast.OpKind.Pow: @@ -1222,14 +1156,12 @@ novirtual class AssignGenMixin: if src_name is not None: decl = f"t.CConst | {src_name}" return GenApi.escape_fstring_copy(f"不能对 const 变量 '{name}' {kind}" f"(声明处类型(含 const):{decl}" f";修法:删掉该声明里的 const 描述符 / t.CConst,或改为声明时一次赋值、" f"之后只用非 const 的副本/中间量;const 对象在其作用域内禁止赋值、" f"增量赋值与元素赋值,且不会降级为警告)") - def const_assign_fail(self, node: ast.AST*, kind: str, - name: str, src_name: str) -> int: + def const_assign_fail(self, node: ast.AST*, kind: str, name: str, src_name: str) -> int: """const 目标被写入 → 立即 fail-fast(不降级为警告、不静默继续)。""" self.Gen.TypeGenErr.fatal_error(node, self.const_assign_msg(kind, name, src_name), "TypeError") return 0 - def translate_augassign(self, trans: HT.Translator*, - node: ast.AST*) -> int: + def translate_augassign(self, trans: HT.Translator*, node: ast.AST*) -> int: """翻译增强赋值语句 (x += 1, y -= 2, etc.)""" if node is None: return 0 @@ -1252,8 +1184,7 @@ novirtual class AssignGenMixin: at_ca: ast.Attribute* = ast.Attribute*(target) if at_ca is not None and at_ca.attr is not None: if self.Gen.ExprGenAttr.attr_field_is_const(pool, trans, target) != 0: - self.const_assign_fail(target, "字段赋值", at_ca.attr, - self.Gen.ExprGenAttr.attr_field_decl_src(pool, trans, target)) + self.const_assign_fail(target, "字段赋值", at_ca.attr, self.Gen.ExprGenAttr.attr_field_decl_src(pool, trans, target)) # 1. 获取字段指针 field_ptr: mlirlite.Value* = self.Gen.ExprGenAttr.get_attribute_ptr(builder, pool, mod, target, trans) @@ -1315,14 +1246,12 @@ novirtual class AssignGenMixin: if nm_ca.id is not None: ve_ca: GenTypes.VarEntry* = self.Gen.VarGen.lookup_var_entry(trans.SymTab, nm_ca.id) if self.Gen.VarGen.var_is_const(ve_ca) != 0: - self.const_assign_fail(target, "的元素赋值", nm_ca.id, - self.Gen.VarGen.var_annot_class_name(ve_ca)) + self.const_assign_fail(target, "的元素赋值", nm_ca.id, self.Gen.VarGen.var_annot_class_name(ve_ca)) elif sub_ca.value.kind() == ast.ASTKind.Attribute: at_ca2: ast.Attribute* = ast.Attribute*(sub_ca.value) if at_ca2.attr is not None: if self.Gen.ExprGenAttr.attr_field_is_const(pool, trans, sub_ca.value) != 0: - self.const_assign_fail(target, "的元素赋值", at_ca2.attr, - self.Gen.ExprGenAttr.attr_field_decl_src(pool, trans, sub_ca.value)) + self.const_assign_fail(target, "的元素赋值", at_ca2.attr, self.Gen.ExprGenAttr.attr_field_decl_src(pool, trans, sub_ca.value)) # 1. 获取元素指针 elem_ptr: mlirlite.Value* = self.Gen.ExprGenName.get_subscript_ptr(builder, pool, mod, target, trans) @@ -1374,19 +1303,16 @@ novirtual class AssignGenMixin: uo_ag: ast.UnaryOp* = ast.UnaryOp*(target) if uo_ag is None or uo_ag.operand is None: self.Gen.TypeGenErr.fatal_error(target, "增量赋值目标单目运算缺少操作数", "TypeError") if uo_ag.op != ast.OpKind.Deref: - self.Gen.TypeGenErr.fatal_error(target, - "增量赋值目标只支持单目 '*' 解引用(&x / -x / ~x 不是合法左值)", "SyntaxError") + self.Gen.TypeGenErr.fatal_error(target, "增量赋值目标只支持单目 '*' 解引用(&x / -x / ~x 不是合法左值)", "SyntaxError") pool: memhub.MemBuddy* = trans.Pool builder: mlirlite.IRBuilder* = trans._cur_builder mod: mlirlite.LLVMModule* = trans.Module ptr_ag: mlirlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, mod, uo_ag.operand, None, 0, trans) if ptr_ag is None or ptr_ag.Ty is None or self.Gen.ExprGenBase.is_ptr_type(ptr_ag.Ty) == 0: - self.Gen.TypeGenErr.fatal_error(target, - "增量赋值 '*' 的操作数必须是指针类型(类型推断退化)", "TypeError") + self.Gen.TypeGenErr.fatal_error(target, "增量赋值 '*' 的操作数必须是指针类型(类型推断退化)", "TypeError") ty_ag: mlirlite.LLVMType* = ptr_ag.Ty.Pointee if ty_ag is None: - self.Gen.TypeGenErr.fatal_error(target, - "解引用增量赋值的目标类型缺失(pointee 为空)", "TypeError") + self.Gen.TypeGenErr.fatal_error(target, "解引用增量赋值的目标类型缺失(pointee 为空)", "TypeError") old_ag: mlirlite.Value* = mlirlite.build_load(builder, ty_ag, ptr_ag, 0) if old_ag is None: self.Gen.TypeGenErr.fatal_error(target, "无法加载解引用当前值", "TypeError") rhs_ag: mlirlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, mod, aug.value, None, 0, trans) @@ -1408,8 +1334,7 @@ novirtual class AssignGenMixin: # const 变量:+= 立即 fail-fast(与 TPC HandlesAugAssign 同判据/同报文) ve_aug: GenTypes.VarEntry* = self.Gen.VarGen.lookup_var_entry(trans.SymTab, nm.id) if self.Gen.VarGen.var_is_const(ve_aug) != 0: - self.const_assign_fail(target, "增量赋值", nm.id, - self.Gen.VarGen.var_annot_class_name(ve_aug)) + self.const_assign_fail(target, "增量赋值", nm.id, self.Gen.VarGen.var_annot_class_name(ve_aug)) # REPL 模式(M2/M3)会话变量增强赋值:读槽 → 二元运算 → 写槽 → 写结果区。 # 未登记的会话名返回 0(继续原路径 → 明确的"无法加载…当前值"报错)。 @@ -1508,9 +1433,7 @@ novirtual class AssignGenMixin: result: mlirlite.Value* = self._apply_aug_op(pool, builder, aug.op, cur_val, rhs_val, node, trans, target) if result is None: # fail-fast: 二元运算失败 - self.Gen.TypeGenErr.fatal_error(target, - f"对变量 '{nm.id}' 应用二元运算失败 op={aug.op}", - "TypeError") + self.Gen.TypeGenErr.fatal_error(target, f"对变量 '{nm.id}' 应用二元运算失败 op={aug.op}", "TypeError") # 5. 存储结果 result = self.Gen.ExprGenBase.coerce_to_type(builder, result, target_ty, node) @@ -1587,10 +1510,7 @@ novirtual class AssignGenMixin: # 单参 t.CArray[elem_ty] 本解析为 Ptr(elem_ty),RHS 为列表字面量时按 TPC # ParseListAnnotation 语义推断为静态数组(否则误走动态 list 构造 → 链接期 undefined)。 # PreScan 与 Handle 都必须调用:两处 alloca 类型须一致,否则复用旧 alloca 使推断失效。 - def _infer_static_array_ty_from_literal(self, pool: memhub.MemBuddy*, - annot: ast.AST*, - value: ast.AST*, - resolved_ty: mlirlite.LLVMType*) -> mlirlite.LLVMType*: + def _infer_static_array_ty_from_literal(self, pool: memhub.MemBuddy*, annot: ast.AST*, value: ast.AST*, resolved_ty: mlirlite.LLVMType*) -> mlirlite.LLVMType*: """单参 CArray + 列表字面量 → Array(elem_ty, len);否则返回原类型""" if value is not None and value.kind() == ast.ASTKind.List and resolved_ty is not None: if self._is_single_param_carray_annot(annot) != 0: @@ -1618,8 +1538,7 @@ novirtual class AssignGenMixin: # 以及 builtins 最后匹配的诊断结果(_lookup_builtins_typedef 记录), # 便于直接定位是"注解本身未注册"还是"builtins 扫描未命中/未展开"。 # ============================================================ - def _build_ann_fail_msg(self, pool: memhub.MemBuddy*, - annot: ast.AST*, nm_id: str) -> str: + def _build_ann_fail_msg(self, pool: memhub.MemBuddy*, annot: ast.AST*, nm_id: str) -> str: """构建变量类型注解解析失败的详细报错信息 注意:f-string 翻译产物是栈上 alloca 缓冲,在助手函数返回后帧销毁, @@ -1645,8 +1564,7 @@ novirtual class AssignGenMixin: # # 为有类型注解的变量提前创建 alloca 到 entry block 顶部;返回新增的变量数 # ============================================================ - def translate_annassign_prescan(self, trans: HT.Translator*, - node: ast.AST*) -> int: + def translate_annassign_prescan(self, trans: HT.Translator*, node: ast.AST*) -> int: """预扫描 AnnAssign,提前创建 alloca 到 entry block 顶部""" if node is None: return 0 k: int = node.kind() @@ -1762,9 +1680,7 @@ novirtual class AssignGenMixin: # 保证两处解析结果一致(未复用预扫描 alloca 的路径也必须先特化)。 # _specialize_generic_class 幂等,重复调用安全。 # 返回 1=执行过特化尝试;0=注解形态不适用(非泛型 Subscript)。 - def _prespecialize_generic_annotation(self, trans: HT.Translator*, - pool: memhub.MemBuddy*, - annot: ast.AST*) -> int: + def _prespecialize_generic_annotation(self, trans: HT.Translator*, pool: memhub.MemBuddy*, annot: ast.AST*) -> int: """泛型注解预特化(见上方注释),返回 1=已尝试 / 0=不适用""" if annot is None or trans is None: return 0 # 取注解中的泛型 Subscript 一侧:Subscript 本身,或 A* 的 Subscript 分支 @@ -1793,11 +1709,7 @@ novirtual class AssignGenMixin: # # 返回新增的变量数 # ============================================================ - def _fail_on_degenerated_generic_annotation(self, - aa: ast.AnnAssign*, - var_name: str, - annot: ast.AST*, - var_ty: mlirlite.LLVMType*) -> int: + def _fail_on_degenerated_generic_annotation(self, aa: ast.AnnAssign*, var_name: str, annot: ast.AST*, var_ty: mlirlite.LLVMType*) -> int: """fail-fast:泛型注解解析成了「裸泛型基类指针」(丢失类型实参) 场景:注解是泛型下标 `list[X]` 或 `list[X]*`,但 @@ -1834,16 +1746,10 @@ novirtual class AssignGenMixin: vt_short_ff: str = vt_nm_ff + vt_pf_ff if vt_pf_ff != 0 else vt_nm_ff if string.strchr(vt_short_ff, '[') is not None: return 0 # 带类型实参:未退化 - self.Gen.TypeGenErr.fatal_error(aa, - f"变量 '{var_name}' 的泛型注解 '{base_nm_ff.id}[...]' 解析成了裸基类 " - f"'{vt_nm_ff}*'(丢失类型实参);后续 .get()/.set() 会按错误元素类型" - f"特化(如 list[int].get 返回 i32)→ inttoptr 截断指针崩溃。" - f"禁止静默继续——请检查该注解在 resolve_annotation_type 中的退化点。", - "TypeError") + self.Gen.TypeGenErr.fatal_error(aa, f"变量 '{var_name}' 的泛型注解 '{base_nm_ff.id}[...]' 解析成了裸基类 " f"'{vt_nm_ff}*'(丢失类型实参);后续 .get()/.set() 会按错误元素类型" f"特化(如 list[int].get 返回 i32)→ inttoptr 截断指针崩溃。" f"禁止静默继续——请检查该注解在 resolve_annotation_type 中的退化点。", "TypeError") return 0 - def translate_annassign(self, trans: HT.Translator*, - node: ast.AST*) -> int: + def translate_annassign(self, trans: HT.Translator*, node: ast.AST*) -> int: """翻译 AnnAssign(target=Name, annotation=..., value=expr)""" aa: ast.AnnAssign* = ast.AnnAssign*(node) if aa is None: return 0 @@ -1907,16 +1813,9 @@ novirtual class AssignGenMixin: dup_decl: int = 0 if GenApi.is_global_name(trans, nm.id) != 0 or GenApi.is_nonlocal_name(trans, nm.id) != 0: dup_decl = 1 if dup_decl != 0: - self.Gen.TypeGenErr.fatal_error(aa, - f"重复声明:'{nm.id}' 已是模块级变量,此处声明 global/nonlocal 之后" - f"又用类型注解重新声明。请删除本行的类型注解,直接赋值即可修改全局", - "TypeError") + self.Gen.TypeGenErr.fatal_error(aa, f"重复声明:'{nm.id}' 已是模块级变量,此处声明 global/nonlocal 之后" f"又用类型注解重新声明。请删除本行的类型注解,直接赋值即可修改全局", "TypeError") else: - self.Gen.TypeGenErr.fatal_error(aa, - f"重复声明:'{nm.id}' 已是模块级变量,函数内未声明 global 时不得再用" - f"类型注解声明同名变量(会把全局遮蔽为局部)。如需独立局部变量请换名;" - f"如需修改全局请在函数内加 global 声明并删除本行注解", - "TypeError") + self.Gen.TypeGenErr.fatal_error(aa, f"重复声明:'{nm.id}' 已是模块级变量,函数内未声明 global 时不得再用" f"类型注解声明同名变量(会把全局遮蔽为局部)。如需独立局部变量请换名;" f"如需修改全局请在函数内加 global 声明并删除本行注解", "TypeError") pool: memhub.MemBuddy* = trans.Pool builder: mlirlite.IRBuilder* = trans._cur_builder @@ -1934,21 +1833,15 @@ novirtual class AssignGenMixin: if resolved is not None: var_ty = resolved else: # fast-fail: 注解类型解析失败,Python traceback 立即终止(不静默回退 i32) - self.Gen.TypeGenErr.fatal_error(aa, - self._build_ann_fail_msg(pool, annot, nm.id), - "TypeError") + self.Gen.TypeGenErr.fatal_error(aa, self._build_ann_fail_msg(pool, annot, nm.id), "TypeError") else: # fail-fast: AnnAssign 必须有 annotation,缺少时立即终止(禁止兜底 i32) - self.Gen.TypeGenErr.fatal_error(aa, - f"AnnAssign 缺少类型注解,变量名: {nm.id}", - "SyntaxError") + self.Gen.TypeGenErr.fatal_error(aa, f"AnnAssign 缺少类型注解,变量名: {nm.id}", "SyntaxError") # void 不能声明为变量(用户 2026-10-01:void 只能用于 `void*` 与 # `typedef 不透明结构体 = void`)——否则会按 LLVM void 建槽,生成非法 IR。 if var_ty is not None and self.Gen.StmtGenDecl._is_void_type(var_ty) != 0: - self.Gen.TypeGenErr.fatal_error(aa, - f"不能声明 void 类型的变量 '{nm.id}'(void 只能用于 void* 与 typedef 别名)", - "TypeError") + self.Gen.TypeGenErr.fatal_error(aa, f"不能声明 void 类型的变量 '{nm.id}'(void 只能用于 void* 与 typedef 别名)", "TypeError") # t.Callable 函数指针:注册返回类型签名(供函数指针间接调用精确返回类型) callable_ret: mlirlite.LLVMType* = self.Gen.TypeGenErr.try_extract_callable_ret(pool, annot, trans._imported_modules, trans._from_imports, trans) @@ -1985,8 +1878,7 @@ novirtual class AssignGenMixin: # 会拿不到注解。 trans.CurAssignAnnot = aa.annotation trans.CurAssignNode = aa.value - rhs_val: mlirlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, mod, aa.value, - None, 0, trans, aa_glob_ty, "模块级全局") + rhs_val: mlirlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, mod, aa.value, None, 0, trans, aa_glob_ty, "模块级全局") if rhs_val is not None: # 对象类全局(有静态 storage):对象构造/赋值 → 绑定 storage + 复制对象 stg_ref_aa: mlirlite.Value* = None @@ -2047,8 +1939,7 @@ novirtual class AssignGenMixin: # `nonlocal s: Stack[int] = Stack()` 的类型实参推断会拿不到注解。 trans.CurAssignAnnot = aa.annotation trans.CurAssignNode = aa.value - rhs_val: mlirlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, mod, aa.value, - None, 0, trans, nl_target_ty, "闭包变量(nonlocal)") + rhs_val: mlirlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, mod, aa.value, None, 0, trans, nl_target_ty, "闭包变量(nonlocal)") if rhs_val is not None: if nl_ptr is not None: if nl_target_ty is None: @@ -2166,11 +2057,7 @@ novirtual class AssignGenMixin: if string.strchr(av_short, '[') is None: av_tpl: ast.ClassDef* = self.Gen.ClassGenGeneric._find_generic_template(av_short) if av_tpl is not None: - self.Gen.TypeGenErr.fatal_error(aa, - f"变量 '{nm.id}' 复用到的存储类型为裸泛型基类 '{av_nm_d}*'" - f"(丢了类型实参),与注解解析类型 '{vt_nm_d}*' 不一致;" - f"禁止静默混用——方法调用会按错误元素类型特化并截断指针", - "TypeError") + self.Gen.TypeGenErr.fatal_error(aa, f"变量 '{nm.id}' 复用到的存储类型为裸泛型基类 '{av_nm_d}*'" f"(丢了类型实参),与注解解析类型 '{vt_nm_d}*' 不一致;" f"禁止静默混用——方法调用会按错误元素类型特化并截断指针", "TypeError") # FakeDuck: str 变量创建影子结构体 {var}__meta__(per-instance 字段存储) # 仅裸 str 注解(Name("str"))且 _str 已注册时创建;bytes / char* 不创建。 @@ -2382,8 +2269,7 @@ novirtual class AssignGenMixin: fd_buddy_fe: GenTypes.FieldEntry* = self.Gen.StructGen.lookup_field(fd_str_ty, "__mbuddy__") if fd_buddy_fe is not None and fd_buddy_fe.Ty is not None: fd_null: mlirlite.Value* = mlirlite.ConstNull(pool, fd_buddy_fe.Ty, "null") - fd_buddy_ptr: mlirlite.Value* = mlirlite.build_gep_struct(builder, fd_str_ty, fd_buddy_fe.Ty, - fd_meta_alloca, fd_buddy_fe.Index) + fd_buddy_ptr: mlirlite.Value* = mlirlite.build_gep_struct(builder, fd_str_ty, fd_buddy_fe.Ty, fd_meta_alloca, fd_buddy_fe.Index) if fd_buddy_ptr is not None and fd_null is not None: mlirlite.build_store(builder, fd_null, fd_buddy_ptr) # FakeDuck: with 上下文自动注入 requires 字段(如 __mbuddy__)。 # 跨 Mixin 经 self.Gen 调用 CallGenFd._inject_requires_fields。 @@ -2397,8 +2283,7 @@ novirtual class AssignGenMixin: # 迁移自 HandlesAssign.AssignHandle.Handle(对应 TransPyC # AssignHandle._HandleAssignLlvm)。共享状态从 trans 获取。 # ============================================================ - def translate_assign(self, trans: HT.Translator*, - node: ast.AST*) -> int: + def translate_assign(self, trans: HT.Translator*, node: ast.AST*) -> int: """翻译 Assign 语句,返回新增变量数(0 或 1)""" asgn: ast.Assign* = ast.Assign*(node) @@ -2428,14 +2313,12 @@ novirtual class AssignGenMixin: if nm_c.id is None: continue ve_c: GenTypes.VarEntry* = self.Gen.VarGen.lookup_var_entry(trans.SymTab, nm_c.id) if self.Gen.VarGen.var_is_const(ve_c) != 0: - self.const_assign_fail(tgt_c, "赋值", nm_c.id, - self.Gen.VarGen.var_annot_class_name(ve_c)) + self.const_assign_fail(tgt_c, "赋值", nm_c.id, self.Gen.VarGen.var_annot_class_name(ve_c)) elif tgt_c.kind() == ast.ASTKind.Attribute: at_c: ast.Attribute* = ast.Attribute*(tgt_c) if at_c.attr is None: continue if self.Gen.ExprGenAttr.attr_field_is_const(pool, trans, tgt_c) != 0: - self.const_assign_fail(tgt_c, "字段赋值", at_c.attr, - self.Gen.ExprGenAttr.attr_field_decl_src(pool, trans, tgt_c)) + self.const_assign_fail(tgt_c, "字段赋值", at_c.attr, self.Gen.ExprGenAttr.attr_field_decl_src(pool, trans, tgt_c)) elif tgt_c.kind() == ast.ASTKind.Subscript: sub_c: ast.Subscript* = ast.Subscript*(tgt_c) if sub_c.value is None: continue @@ -2444,14 +2327,12 @@ novirtual class AssignGenMixin: if nm_c2.id is None: continue ve_c2: GenTypes.VarEntry* = self.Gen.VarGen.lookup_var_entry(trans.SymTab, nm_c2.id) if self.Gen.VarGen.var_is_const(ve_c2) != 0: - self.const_assign_fail(tgt_c, "的元素赋值", nm_c2.id, - self.Gen.VarGen.var_annot_class_name(ve_c2)) + self.const_assign_fail(tgt_c, "的元素赋值", nm_c2.id, self.Gen.VarGen.var_annot_class_name(ve_c2)) elif sub_c.value.kind() == ast.ASTKind.Attribute: at_c2: ast.Attribute* = ast.Attribute*(sub_c.value) if at_c2.attr is None: continue if self.Gen.ExprGenAttr.attr_field_is_const(pool, trans, sub_c.value) != 0: - self.const_assign_fail(tgt_c, "的元素赋值", at_c2.attr, - self.Gen.ExprGenAttr.attr_field_decl_src(pool, trans, sub_c.value)) + self.const_assign_fail(tgt_c, "的元素赋值", at_c2.attr, self.Gen.ExprGenAttr.attr_field_decl_src(pool, trans, sub_c.value)) # f-string 逃逸:f-string 结果是**当前函数内的临时值**(栈缓冲,见 # ExprGenFstr._fstr_finalize),写进字段 / 元素 / 全局等函数外可见的位置即 @@ -2648,8 +2529,7 @@ novirtual class AssignGenMixin: if arg_vals_set is not None: arg_vals_set[0] = sizet(key_val_set) arg_vals_set[1] = sizet(rhs_val) - self.Gen.CallGenCall._call_method_on_ptr(pool, builder, mod, cls_nm_set, "__setitem__", - obj_val_set, arg_vals_set, 2, trans) + self.Gen.CallGenCall._call_method_on_ptr(pool, builder, mod, cls_nm_set, "__setitem__", obj_val_set, arg_vals_set, 2, trans) setitem_done = 1 elif sub_asgn.value.kind() == ast.ASTKind.Attribute: # self._ht[key] = val → self._ht.__setitem__(key, val) @@ -2671,8 +2551,7 @@ novirtual class AssignGenMixin: if arg_vals_attr is not None: arg_vals_attr[0] = sizet(key_val_attr) arg_vals_attr[1] = sizet(rhs_val) - self.Gen.CallGenCall._call_method_on_ptr(pool, builder, mod, cls_nm_attr, "__setitem__", - obj_val_attr, arg_vals_attr, 2, trans) + self.Gen.CallGenCall._call_method_on_ptr(pool, builder, mod, cls_nm_attr, "__setitem__", obj_val_attr, arg_vals_attr, 2, trans) setitem_done = 1 if setitem_done == 0: # 通用 fallback: 翻译 sub.value 并尝试 __setitem__ 或直接 GEP+store @@ -2691,8 +2570,7 @@ novirtual class AssignGenMixin: if arg_vals_gen is not None: arg_vals_gen[0] = sizet(key_val_gen) arg_vals_gen[1] = sizet(rhs_val) - self.Gen.CallGenCall._call_method_on_ptr(pool, builder, mod, cls_nm_gen, "__setitem__", - obj_val_gen, arg_vals_gen, 2, trans) + self.Gen.CallGenCall._call_method_on_ptr(pool, builder, mod, cls_nm_gen, "__setitem__", obj_val_gen, arg_vals_gen, 2, trans) setitem_done = 1 elif self.Gen.ExprGenBase.is_ptr_type(obj_val_gen.Ty) != 0 and obj_val_gen.Ty.Pointee != 0: # 非自定义结构体: 直接 GEP + store @@ -2702,8 +2580,7 @@ novirtual class AssignGenMixin: elem_ptr_gen: mlirlite.Value* = None match elem_gen: case mlirlite.LLVMType.Array(arr_elem_gen, _): - elem_ptr_gen = mlirlite.build_gep_array(builder, elem_gen, arr_elem_gen, - obj_val_gen, key_val_gen) + elem_ptr_gen = mlirlite.build_gep_array(builder, elem_gen, arr_elem_gen, obj_val_gen, key_val_gen) case _: elem_ptr_gen = mlirlite.build_gep(builder, elem_gen, obj_val_gen, key_val_gen) if elem_ptr_gen is not None and elem_ptr_gen.Ty is not None: @@ -2728,16 +2605,13 @@ novirtual class AssignGenMixin: uo_w: ast.UnaryOp* = ast.UnaryOp*(target) if uo_w is None or uo_w.operand is None: self.Gen.TypeGenErr.fatal_error(target, "赋值目标单目运算缺少操作数", "TypeError") if uo_w.op != ast.OpKind.Deref: - self.Gen.TypeGenErr.fatal_error(target, - "赋值目标只支持单目 '*' 解引用(&x / -x / ~x 不是合法左值)", "SyntaxError") + self.Gen.TypeGenErr.fatal_error(target, "赋值目标只支持单目 '*' 解引用(&x / -x / ~x 不是合法左值)", "SyntaxError") ptr_w: mlirlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, mod, uo_w.operand, None, 0, trans) if ptr_w is None or ptr_w.Ty is None or self.Gen.ExprGenBase.is_ptr_type(ptr_w.Ty) == 0: - self.Gen.TypeGenErr.fatal_error(target, - "单目 '*' 赋值的操作数必须是指针类型(类型推断退化)", "TypeError") + self.Gen.TypeGenErr.fatal_error(target, "单目 '*' 赋值的操作数必须是指针类型(类型推断退化)", "TypeError") pointee_w: mlirlite.LLVMType* = ptr_w.Ty.Pointee if pointee_w is None: - self.Gen.TypeGenErr.fatal_error(target, - "解引用写入的目标类型缺失(pointee 为空)", "TypeError") + self.Gen.TypeGenErr.fatal_error(target, "解引用写入的目标类型缺失(pointee 为空)", "TypeError") sv_w: mlirlite.Value* = self.Gen.ExprGenBase.coerce_to_type(builder, rhs_val, pointee_w, node, trans) mlirlite.build_store(builder, sv_w, ptr_w) continue @@ -2770,8 +2644,7 @@ novirtual class AssignGenMixin: if fd_sty_w is not None: fd_fe_w: GenTypes.FieldEntry* = self.Gen.StructGen.lookup_field(fd_sty_w, fd_an.attr) if fd_fe_w is not None and fd_fe_w.Ty is not None: - fd_fp_w: mlirlite.Value* = mlirlite.build_gep_struct(builder, fd_sty_w, fd_fe_w.Ty, - fd_meta_vw, fd_fe_w.Index) + fd_fp_w: mlirlite.Value* = mlirlite.build_gep_struct(builder, fd_sty_w, fd_fe_w.Ty, fd_meta_vw, fd_fe_w.Index) if fd_fp_w is not None: sv_fd: mlirlite.Value* = self.Gen.ExprGenBase.coerce_to_type(builder, rhs_val, fd_fe_w.Ty, node) mlirlite.build_store(builder, sv_fd, fd_fp_w) @@ -2806,9 +2679,7 @@ novirtual class AssignGenMixin: obj_name = obj_nm.id err_buf: str = pool.alloc(256) if err_buf is not None: - viperlib.snprintf(err_buf, 256, - "attribute ptr is None: %s.%s", - obj_name, attr_name) + viperlib.snprintf(err_buf, 256, "attribute ptr is None: %s.%s", obj_name, attr_name) self.Gen.TypeGenErr.fatal_error(target, err_buf) else: self.Gen.TypeGenErr.fatal_error(target, "attribute ptr is None") continue @@ -2942,11 +2813,7 @@ novirtual class AssignGenMixin: # · list[rawptr[T]].set / list.__setitem__:走 is_list_subscript 的 # 内联路径或 list_setitem_inline,不经过本函数。 # ============================================================ - def _reject_whole_object_copy_into_ptr_slot(self, pool: memhub.MemBuddy*, - trans: HT.Translator*, - target: ast.AST*, - elem_ptr: mlirlite.Value*, - rhs_val: mlirlite.Value*) -> None: + def _reject_whole_object_copy_into_ptr_slot(self, pool: memhub.MemBuddy*, trans: HT.Translator*, target: ast.AST*, elem_ptr: mlirlite.Value*, rhs_val: mlirlite.Value*) -> None: """rawptr[T] 下标赋值 + RHS 为指向 T 的指针 ⇒ fatal_error(整对象拷贝)""" if elem_ptr is None or elem_ptr.Ty is None: return if rhs_val is None or rhs_val.Ty is None: return @@ -2986,16 +2853,7 @@ novirtual class AssignGenMixin: if target is not None: col_s_wo = target.col_offset + 1 col_e_wo = target.end_col_offset + 1 - self.Gen.TypeGenErr.fatal_error(target, - f"下标赋值的左值元素是对象 '{elem_nm_wo}'({elem_sz_wo} 字节)," - f"右值却是指向 '{rhs_nm_wo}' 的指针:编译器会静默生成整对象拷贝" - f"(load {elem_nm_wo} + store {elem_nm_wo},写 {elem_sz_wo} 字节)," - f"而不是按指针写 {ptr_sz_wo} 字节。若该地址实际按 8 字节槽存放指针" - f"(如 rawptr[T] 缓冲/空闲链表),每写一个元素就越界 {over_wo} 字节," - f"直接写穿相邻块。修法:把指针槽的基座类型写成指针元素形态" - f"(`rawptr[T]*` 或 `rawptr[rawptr[T]]`)后再赋值;" - f"或把基座显式转为 t.CPtr(无类型指针)后按 8 字节指针语义写入。", - "TypeError", col_s_wo, col_e_wo) + self.Gen.TypeGenErr.fatal_error(target, f"下标赋值的左值元素是对象 '{elem_nm_wo}'({elem_sz_wo} 字节)," f"右值却是指向 '{rhs_nm_wo}' 的指针:编译器会静默生成整对象拷贝" f"(load {elem_nm_wo} + store {elem_nm_wo},写 {elem_sz_wo} 字节)," f"而不是按指针写 {ptr_sz_wo} 字节。若该地址实际按 8 字节槽存放指针" f"(如 rawptr[T] 缓冲/空闲链表),每写一个元素就越界 {over_wo} 字节," f"直接写穿相邻块。修法:把指针槽的基座类型写成指针元素形态" f"(`rawptr[T]*` 或 `rawptr[rawptr[T]]`)后再赋值;" f"或把基座显式转为 t.CPtr(无类型指针)后按 8 字节指针语义写入。", "TypeError", col_s_wo, col_e_wo) # ============================================================ # _infer_rhs_annot - 从 RHS 表达式推断变量注解类名 @@ -3012,11 +2870,7 @@ novirtual class AssignGenMixin: # Attribute → 字段注解类名(委托 Generator 单例 _resolve_attr_field_class) # 仅当目标为已注册结构体时采用,与"按需过滤,找不到 fast-fail"原则一致。 # ============================================================ - def _infer_rhs_annot(self, pool: memhub.MemBuddy*, - mod: mlirlite.LLVMModule*, - node: ast.AST*, - trans: HT.Translator*, - rhs_val: mlirlite.Value* = None) -> str: + def _infer_rhs_annot(self, pool: memhub.MemBuddy*, mod: mlirlite.LLVMModule*, node: ast.AST*, trans: HT.Translator*, rhs_val: mlirlite.Value* = None) -> str: """从 RHS 表达式推断类名,无法推断返回 None""" if node is None or trans is None: return None k: int = node.kind() @@ -3106,8 +2960,7 @@ novirtual class AssignGenMixin: # CFloat64T/t.CPtr 等均不注册 struct,天然过滤)。"A | B" 联合 # 多候选时取首个命中段。 # ============================================================ - def _extract_annot_class_name(self, pool: memhub.MemBuddy*, - annot: str) -> str: + def _extract_annot_class_name(self, pool: memhub.MemBuddy*, annot: str) -> str: """从返回注解文本提取已注册结构体类名,无命中返回 None""" if pool is None or annot is None: return None alen: sizet = string.strlen(annot) @@ -3204,9 +3057,7 @@ novirtual class AssignGenMixin: # 或跨模块类有 SHA1(stub 中声明)即视为存在。仅在确实存在时 # 才采用运算符重载推断的类名,避免把原生运算误标为类类型。 # ============================================================ - def _cls_has_dunder(self, pool: memhub.MemBuddy*, - mod: mlirlite.LLVMModule*, - class_name: str, dunder: str) -> int: + def _cls_has_dunder(self, pool: memhub.MemBuddy*, mod: mlirlite.LLVMModule*, class_name: str, dunder: str) -> int: """类及其 MRO 祖先链中是否存在 dunder 方法,存在返回 1""" if class_name is None or dunder is None or mod is None: return 0 lookup_name: str = pool.alloc(128) diff --git a/App/lib/core/Gen/AsyncGenMixin.vp b/App/lib/core/Gen/AsyncGenMixin.vp index 064b0bd..1c3745b 100644 --- a/App/lib/core/Gen/AsyncGenMixin.vp +++ b/App/lib/core/Gen/AsyncGenMixin.vp @@ -27,8 +27,7 @@ novirtual class AsyncGenMixin(CallGenBase.CallGenBase): # 由 FuncGenDef.translate_function_def 检测 fd.flags & FLAG_IS_ASYNC # (=1,见 includes/ast/stmts.vp L342-345)后调用,早返回不进普通函数路径。 # ============================================================ - def translate_async_function(self, trans: HT.Translator*, - node: ast.AST*) -> int: + def translate_async_function(self, trans: HT.Translator*, node: ast.AST*) -> int: """翻译 async 函数定义,返回 0 成功 生成 create_(帧分配,M2 带参数)与 resume_(状态机), @@ -90,8 +89,7 @@ novirtual class AsyncGenMixin(CallGenBase.CallGenBase): self.Gen.VarGen.enter_scope(trans.SymTab, SCOPE_FUNCTION) self._emit_create(pool, mod, trans, name, frame_ty, nparams) - self._emit_resume(pool, mod, trans, name, fd, frame_ty, - nparams, nlocals, nextra) + self._emit_resume(pool, mod, trans, name, fd, frame_ty, nparams, nlocals, nextra) self.Gen.VarGen.exit_scope(trans.SymTab) return 0 @@ -99,8 +97,7 @@ novirtual class AsyncGenMixin(CallGenBase.CallGenBase): # ============================================================ # M2:参数收集(帧参数槽 index 3+i) # ============================================================ - def _collect_param_names(self, trans: HT.Translator*, - fd: ast.FunctionDef*) -> int: + def _collect_param_names(self, trans: HT.Translator*, fd: ast.FunctionDef*) -> int: """收集 async 函数参数名到 trans._coro_params(char* 数组,8 字节/项)。 参数槽 index = 3 + i,create_ 按参数顺序收值入帧。""" if fd is None or fd.args is None or trans is None: return 0 @@ -139,8 +136,7 @@ novirtual class AsyncGenMixin(CallGenBase.CallGenBase): # 位置数组:_coro_await_slots[M]=__await_M 相对序号;_coro_for_slots[N]=__f_idx_N 相对序号 # _coro_await_count = 恢复块数(顶层 + 嵌套 await) # ============================================================ - def _pre_scan_awaits(self, trans: HT.Translator*, - fd: ast.FunctionDef*) -> int: + def _pre_scan_awaits(self, trans: HT.Translator*, fd: ast.FunctionDef*) -> int: """DFS 预扫描协程体,填额外槽表并返回额外槽总数""" if fd is None or fd.children is None or trans is None: return 0 trans._coro_extra_count = 0 @@ -154,20 +150,17 @@ novirtual class AsyncGenMixin(CallGenBase.CallGenBase): return trans._coro_extra_count # ---------- 第一遍:coro_sleep 检测(wake 槽决定) ---------- - def _scan_sleep_usage(self, trans: HT.Translator*, - fd: ast.FunctionDef*): + def _scan_sleep_usage(self, trans: HT.Translator*, fd: ast.FunctionDef*): if fd is None or fd.children is None or trans is None: return self._scan_sleep_stmts(trans, fd.children) - def _scan_sleep_stmts(self, trans: HT.Translator*, - stmts: list[ast.AST*]*): + def _scan_sleep_stmts(self, trans: HT.Translator*, stmts: list[ast.AST*]*): if stmts is None or trans._coro_uses_sleep != 0: return bn: sizet = len(stmts) i: sizet = 0 for i in range(bn): self._scan_sleep_stmt(trans, stmts.get(i)) - def _scan_sleep_stmt(self, trans: HT.Translator*, - stmt: ast.AST*): + def _scan_sleep_stmt(self, trans: HT.Translator*, stmt: ast.AST*): if stmt is None or trans._coro_uses_sleep != 0: return sk: int = stmt.kind() if sk == ast.ASTKind.If: @@ -217,8 +210,7 @@ novirtual class AsyncGenMixin(CallGenBase.CallGenBase): self._scan_sleep_expr(trans, e.value) return - def _scan_sleep_expr(self, trans: HT.Translator*, - node: ast.AST*): + def _scan_sleep_expr(self, trans: HT.Translator*, node: ast.AST*): if node is None or trans._coro_uses_sleep != 0: return k: int = node.kind() if k == ast.ASTKind.Call: @@ -285,15 +277,13 @@ novirtual class AsyncGenMixin(CallGenBase.CallGenBase): return # ---------- 第二遍:填额外槽表 + 状态号计数 ---------- - def _scan_stmts(self, trans: HT.Translator*, - stmts: list[ast.AST*]*): + def _scan_stmts(self, trans: HT.Translator*, stmts: list[ast.AST*]*): if stmts is None: return bn: sizet = len(stmts) i: sizet = 0 for i in range(bn): self._scan_stmt(trans, stmts.get(i)) - def _scan_stmt(self, trans: HT.Translator*, - stmt: ast.AST*): + def _scan_stmt(self, trans: HT.Translator*, stmt: ast.AST*): if stmt is None: return sk: int = stmt.kind() if sk == ast.ASTKind.If: @@ -361,8 +351,7 @@ novirtual class AsyncGenMixin(CallGenBase.CallGenBase): # 语句内嵌套 await:DFS 表达式(AnnAssign.value / Assign.value / Expr.value) self._scan_stmt_exprs(trans, stmt) - def _scan_stmt_exprs(self, trans: HT.Translator*, - stmt: ast.AST*): + def _scan_stmt_exprs(self, trans: HT.Translator*, stmt: ast.AST*): """扫描语句的值表达式找嵌套 await""" if stmt is None: return sk: int = stmt.kind() @@ -380,8 +369,7 @@ novirtual class AsyncGenMixin(CallGenBase.CallGenBase): return # 其它语句类型:翻译端 fail-fast - def _scan_expr(self, trans: HT.Translator*, - node: ast.AST*): + def _scan_expr(self, trans: HT.Translator*, node: ast.AST*): """DFS 扫描表达式找 Await:命中分配 __await_N 槽并计数状态号""" if node is None: return k: int = node.kind() @@ -521,8 +509,7 @@ novirtual class AsyncGenMixin(CallGenBase.CallGenBase): # ============================================================ # 局部变量收集(顶层 AnnAssign / Assign 的 Name 目标) # ============================================================ - def _collect_local_names(self, trans: HT.Translator*, - fd: ast.FunctionDef*) -> int: + def _collect_local_names(self, trans: HT.Translator*, fd: ast.FunctionDef*) -> int: """收集帧局部变量名(_coro_locals,8 字节/项): - 顶层 AnnAssign/Assign 的 Name 目标(M2) - try 的 except as e 绑定名(M5/M6,跨 handler 需要帧槽) @@ -534,15 +521,13 @@ novirtual class AsyncGenMixin(CallGenBase.CallGenBase): self._collect_locals_stmts(trans, fd.children) return trans._coro_local_count - def _collect_locals_stmts(self, trans: HT.Translator*, - stmts: list[ast.AST*]*): + def _collect_locals_stmts(self, trans: HT.Translator*, stmts: list[ast.AST*]*): if stmts is None: return bn: sizet = len(stmts) i: sizet = 0 for i in range(bn): self._collect_locals_stmt(trans, stmts.get(i)) - def _collect_locals_stmt(self, trans: HT.Translator*, - stmt: ast.AST*): + def _collect_locals_stmt(self, trans: HT.Translator*, stmt: ast.AST*): if stmt is None: return sk: int = stmt.kind() if sk == ast.ASTKind.AnnAssign: @@ -594,8 +579,7 @@ novirtual class AsyncGenMixin(CallGenBase.CallGenBase): self._collect_locals_stmts(trans, tr.finalbody) return - def _add_local(self, trans: HT.Translator*, - name: str): + def _add_local(self, trans: HT.Translator*, name: str): if name is None: return cnt: int = trans._coro_local_count if cnt >= HT.MAX_CORO_VARS: return @@ -608,12 +592,7 @@ novirtual 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*, - mod: mlirlite.LLVMModule*, - trans: HT.Translator*, - name: str, - nparams: int, nlocals: int, - nextra: int) -> mlirlite.LLVMType*: + def _build_frame_ty(self, pool: memhub.MemBuddy*, mod: mlirlite.LLVMModule*, trans: HT.Translator*, name: str, nparams: int, nlocals: int, nextra: int) -> mlirlite.LLVMType*: """构造帧结构体并注册到模块与结构体表,返回 LLVMType M7 布局:{i32 state, i32 done, i32 ret, i32 exc, i8* msg, 参数槽(5+i), 局部槽(5+nparams+i), 额外槽(extra_base+i, 按类型表 1=i32 2=i64)}""" @@ -652,12 +631,7 @@ novirtual class AsyncGenMixin(CallGenBase.CallGenBase): # ============================================================ # create_() -> %Coro_* # ============================================================ - def _emit_create(self, pool: memhub.MemBuddy*, - mod: mlirlite.LLVMModule*, - trans: HT.Translator*, - name: str, - frame_ty: mlirlite.LLVMType*, - nparams: int) -> int: + def _emit_create(self, pool: memhub.MemBuddy*, mod: mlirlite.LLVMModule*, trans: HT.Translator*, name: str, frame_ty: mlirlite.LLVMType*, nparams: int) -> int: """生成 create_(args...):M7 帧池弹帧(i64 池头 free-list)或 malloc, 5 头清零 + 参数存槽(帧槽 5+i)+ ret 帧指针""" if frame_ty is None: return 0 @@ -764,10 +738,7 @@ novirtual class AsyncGenMixin(CallGenBase.CallGenBase): # ============================================================ # M7:每帧类型的全局 free-list 池头(i64,0 = 空) # ============================================================ - def _get_coro_pool(self, pool: memhub.MemBuddy*, - mod: mlirlite.LLVMModule*, - trans: HT.Translator*, - name: str) -> mlirlite.GlobalVariable*: + def _get_coro_pool(self, pool: memhub.MemBuddy*, mod: mlirlite.LLVMModule*, trans: HT.Translator*, name: str) -> mlirlite.GlobalVariable*: """取/建 coro_pool_ 全局(i64 池头)。池节点 next 存帧首 8 字节。""" pn_buf: str = pool.alloc(128) if pn_buf is not None: viperlib.snprintf(pn_buf, 128, "coro_pool_%s", name) @@ -778,8 +749,7 @@ novirtual class AsyncGenMixin(CallGenBase.CallGenBase): g = g.Next return mlirlite.create_global_int(pool, mod, pn_buf, 64, 0) - def _register_coro_wake(self, trans: HT.Translator*, - name: str, wake_idx: int): + def _register_coro_wake(self, trans: HT.Translator*, name: str, wake_idx: int): """记录 async 名的 wake 槽 index(_coro_wake_names/_coro_wake_idxs 平行表)""" if trans is None or name is None or trans._coro_wake_names is None: return cnt: int = trans._coro_wake_count @@ -790,8 +760,7 @@ novirtual class AsyncGenMixin(CallGenBase.CallGenBase): trans._coro_wake_idxs[cnt] = wake_idx trans._coro_wake_count = cnt + 1 - def _lookup_coro_wake(self, trans: HT.Translator*, - name: str) -> int: + def _lookup_coro_wake(self, trans: HT.Translator*, name: str) -> int: """查 async 名的 wake 槽 index,无 wake 槽返回 -1""" if trans is None or name is None or trans._coro_wake_names is None: return -1 i: int = 0 @@ -804,14 +773,7 @@ novirtual class AsyncGenMixin(CallGenBase.CallGenBase): # ============================================================ # resume_(%Coro_*) -> i32 状态机(静态段切分) # ============================================================ - def _emit_resume(self, pool: memhub.MemBuddy*, - mod: mlirlite.LLVMModule*, - trans: HT.Translator*, - name: str, - fd: ast.FunctionDef*, - frame_ty: mlirlite.LLVMType*, - nparams: int, nlocals: int, - nextra: int) -> int: + def _emit_resume(self, pool: memhub.MemBuddy*, mod: mlirlite.LLVMModule*, trans: HT.Translator*, name: str, fd: ast.FunctionDef*, frame_ty: mlirlite.LLVMType*, nparams: int, nlocals: int, nextra: int) -> int: """生成 resume_(frame) -> i32 状态机(M2): entry 读 state → switch → state0 主入口递归翻译整个函数体; 每个 await(顶层或嵌套,DFS 序)分配 state{N} 恢复块(预建 case); @@ -828,8 +790,7 @@ novirtual class AsyncGenMixin(CallGenBase.CallGenBase): mlirlite.add_param(pool, func, frame_ptr_ty, "%frame") funcs_ptr: GenTypes.FuncEntry* = trans._funcs cur_count: int = trans._func_count - if self.Gen.CallGenLeafKit.add_func_to_table(funcs_ptr, cur_count, rname_buf, func, 1024, - None, 0, 1, trans.Pool) == 0: + if self.Gen.CallGenLeafKit.add_func_to_table(funcs_ptr, cur_count, rname_buf, func, 1024, None, 0, 1, trans.Pool) == 0: trans._func_count = cur_count + 1 entry: rawptr[mlirlite.BasicBlock] = mlirlite.create_block(pool, func, "entry") @@ -863,8 +824,7 @@ novirtual class AsyncGenMixin(CallGenBase.CallGenBase): for li in range(nlocals): lname: str = self._read_local_name(trans, li) if lname is None: continue - slot: mlirlite.Value* = mlirlite.build_gep_struct(builder, frame_ty, i32_ty, frame_arg, - trans._coro_local_base + li) + slot: mlirlite.Value* = mlirlite.build_gep_struct(builder, frame_ty, i32_ty, frame_arg, trans._coro_local_base + li) if slot is not None: self.Gen.VarGen.define_var(trans.SymTab, lname, slot) # M3-M7:额外槽注册(wake i64 / __f_idx/__f_len/__await i32)。 @@ -876,8 +836,7 @@ novirtual class AsyncGenMixin(CallGenBase.CallGenBase): if trans._coro_extra_types is not None: ety = trans._coro_extra_types[ei] ety_llvm: mlirlite.LLVMType* = i32_ty if ety == 2: ety_llvm = i64_ty_r - eslot: mlirlite.Value* = mlirlite.build_gep_struct(builder, frame_ty, ety_llvm, frame_arg, - trans._coro_extra_base + ei) + eslot: mlirlite.Value* = mlirlite.build_gep_struct(builder, frame_ty, ety_llvm, frame_arg, trans._coro_extra_base + ei) if eslot is None: continue # wake 槽:只存指针,不注册 SymTab(coro_run 轮询用) if trans._coro_uses_sleep != 0 and ei == 0: @@ -989,11 +948,7 @@ novirtual class AsyncGenMixin(CallGenBase.CallGenBase): # ============================================================ # M2:协程体递归翻译(Return/顶层 await/If/While/嵌套 await/普通) # ============================================================ - def _handle_segment(self, trans: HT.Translator*, - builder: mlirlite.IRBuilder*, - pool: memhub.MemBuddy*, - mod: mlirlite.LLVMModule*, - stmts: list[ast.AST*]*): + def _handle_segment(self, trans: HT.Translator*, builder: mlirlite.IRBuilder*, pool: memhub.MemBuddy*, mod: mlirlite.LLVMModule*, stmts: list[ast.AST*]*): """递归翻译协程体语句。builder 当前块 = 活跃执行块(state0 或某恢复块)。""" if stmts is None: return bn: sizet = len(stmts) @@ -1067,11 +1022,7 @@ novirtual class AsyncGenMixin(CallGenBase.CallGenBase): # ============================================================ # M2:协程版 If(分支内 await 就地挂起/恢复) # ============================================================ - def _handle_coro_if(self, trans: HT.Translator*, - builder: mlirlite.IRBuilder*, - pool: memhub.MemBuddy*, - mod: mlirlite.LLVMModule*, - stmt: ast.AST*): + def _handle_coro_if(self, trans: HT.Translator*, builder: mlirlite.IRBuilder*, pool: memhub.MemBuddy*, mod: mlirlite.LLVMModule*, stmt: ast.AST*): ifn: rawptr[ast.If] = rawptr[ast.If](stmt) if ifn is None or ifn.test is None: return if self._find_expr_await(ifn.test) is not None: @@ -1091,8 +1042,7 @@ novirtual class AsyncGenMixin(CallGenBase.CallGenBase): else_bb: rawptr[mlirlite.BasicBlock] = None if has_else != 0: else_bb = mlirlite.create_block(pool, func, "coro.else") if cond1 is None or then_bb is None or merge_bb is None: return - mlirlite.build_cond_br(builder, cond1, then_bb, - else_bb if else_bb is not None else merge_bb) + mlirlite.build_cond_br(builder, cond1, then_bb, else_bb if else_bb is not None else merge_bb) # then 分支 mlirlite.position_at_end(builder, then_bb) self._handle_segment(trans, builder, pool, mod, stmt.children) @@ -1107,11 +1057,7 @@ novirtual class AsyncGenMixin(CallGenBase.CallGenBase): # ============================================================ # M2:协程版 While(条件块 + 循环体,body 内 await 就地挂起/恢复) # ============================================================ - def _handle_coro_while(self, trans: HT.Translator*, - builder: mlirlite.IRBuilder*, - pool: memhub.MemBuddy*, - mod: mlirlite.LLVMModule*, - stmt: ast.AST*): + def _handle_coro_while(self, trans: HT.Translator*, builder: mlirlite.IRBuilder*, pool: memhub.MemBuddy*, mod: mlirlite.LLVMModule*, stmt: ast.AST*): whn: rawptr[ast.While] = rawptr[ast.While](stmt) if whn is None: return if whn.test is not None and self._find_expr_await(whn.test) is not None: @@ -1149,11 +1095,7 @@ novirtual class AsyncGenMixin(CallGenBase.CallGenBase): # ============================================================ # M2:嵌套 await 提升:a = b + await f() → __await_N = await f(); a = b + __await_N # ============================================================ - def _handle_nested_await_stmt(self, trans: HT.Translator*, - builder: mlirlite.IRBuilder*, - pool: memhub.MemBuddy*, - mod: mlirlite.LLVMModule*, - stmt: ast.AST*): + def _handle_nested_await_stmt(self, trans: HT.Translator*, builder: mlirlite.IRBuilder*, pool: memhub.MemBuddy*, mod: mlirlite.LLVMModule*, stmt: ast.AST*): """把语句中所有嵌套 await 提升为顶层临时赋值(与预扫描 DFS 顺序一致)""" guard: int = 0 while True: @@ -1166,8 +1108,7 @@ novirtual class AsyncGenMixin(CallGenBase.CallGenBase): # 目标槽 = __await_N 帧额外槽(预扫描位置数组,wake/for 槽穿插在前) slot_idx: int = trans._coro_extra_base + trans._coro_await_slots[trans._coro_hoist_count] trans._coro_hoist_count = trans._coro_hoist_count + 1 - slot: mlirlite.Value* = mlirlite.build_gep_struct(builder, self._lookup_coro_frame_by_trans(trans), - mlirlite.Int32(pool), trans._coro_frame, slot_idx) + slot: mlirlite.Value* = mlirlite.build_gep_struct(builder, self._lookup_coro_frame_by_trans(trans), mlirlite.Int32(pool), trans._coro_frame, slot_idx) trans._coro_await_slot = slot call_name: str = self._extract_await_call_name(aw_node) if call_name is None: break @@ -1264,9 +1205,7 @@ novirtual class AsyncGenMixin(CallGenBase.CallGenBase): return self._find_expr_await(sb.slice) return None - def _replace_await_with_name(self, pool: memhub.MemBuddy*, - stmt: ast.AST*, - temp_name: str) -> int: + def _replace_await_with_name(self, pool: memhub.MemBuddy*, stmt: ast.AST*, temp_name: str) -> int: """把语句树中第一个 Await 替换为 Name(temp_name)(DFS 字段序)""" if stmt is None or temp_name is None: return 0 sk: int = stmt.kind() @@ -1288,9 +1227,7 @@ novirtual class AsyncGenMixin(CallGenBase.CallGenBase): return 0 return 0 - def _replace_expr_await(self, pool: memhub.MemBuddy*, - node: ast.AST*, - temp_name: str) -> int: + def _replace_expr_await(self, pool: memhub.MemBuddy*, node: ast.AST*, temp_name: str) -> int: """在表达式树中把第一个 Await 替换为 Name(temp_name, Load)。 node 本身是 Await 时返回 2(由父字段替换)。返回 1=已替换 0=无 2=node 即 Await。""" if node is None: return 0 @@ -1408,19 +1345,14 @@ novirtual class AsyncGenMixin(CallGenBase.CallGenBase): # ============================================================ # 条件归一化(i1 直通;其余 icmp ne 0) # ============================================================ - def _normalize_cond(self, builder: mlirlite.IRBuilder*, - pool: memhub.MemBuddy*, - mod: mlirlite.LLVMModule*, - cond: mlirlite.Value*, - trans: HT.Translator*) -> mlirlite.Value*: + def _normalize_cond(self, builder: mlirlite.IRBuilder*, pool: memhub.MemBuddy*, mod: mlirlite.LLVMModule*, cond: mlirlite.Value*, trans: HT.Translator*) -> mlirlite.Value*: """条件归一到 i1(协程 if/while 用):委托 coerce_cond_to_bool,优先调度 __bool__""" return self.Gen.ExprGenOps.coerce_cond_to_bool(pool, builder, mod, cond, trans) # ============================================================ # 参数名读取(_coro_params 表) # ============================================================ - def _read_param_name(self, trans: HT.Translator*, - idx: int) -> str: + def _read_param_name(self, trans: HT.Translator*, idx: int) -> str: if trans is None or trans._coro_params is None: return None addr: uint64 = uint64(trans._coro_params) + idx * 8 slot: str* = (str*)(addr) @@ -1429,8 +1361,7 @@ novirtual class AsyncGenMixin(CallGenBase.CallGenBase): # ============================================================ # 恢复块定位(state{N},预建数组) # ============================================================ - def _get_state_bb(self, trans: HT.Translator*, - state_no: int) -> rawptr[mlirlite.BasicBlock]: + def _get_state_bb(self, trans: HT.Translator*, state_no: int) -> rawptr[mlirlite.BasicBlock]: if trans is None or trans._coro_state_bbs is None: return None if state_no < 0 or state_no >= trans._coro_nseg: return None # 注意:state_bbs 数组存的是块指针(sizet),必须下标取值, @@ -1454,11 +1385,7 @@ novirtual class AsyncGenMixin(CallGenBase.CallGenBase): # ============================================================ # M3:await coro_sleep(ms) —— wake 槽挂起(coro_run 轮询续跑) # ============================================================ - def _emit_await_sleep(self, builder: mlirlite.IRBuilder*, - pool: memhub.MemBuddy*, - mod: mlirlite.LLVMModule*, - trans: HT.Translator*, - node: ast.AST*) -> mlirlite.Value*: + def _emit_await_sleep(self, builder: mlirlite.IRBuilder*, pool: memhub.MemBuddy*, mod: mlirlite.LLVMModule*, trans: HT.Translator*, node: ast.AST*) -> mlirlite.Value*: """await coro_sleep(ms):wake = GetTickCount64() + ms 存帧 wake 槽, 父挂起(state 分配 + br exit + position 恢复块);coro_run 轮询续跑。""" i64_ty: mlirlite.LLVMType* = mlirlite.Int64(pool) @@ -1493,11 +1420,7 @@ novirtual class AsyncGenMixin(CallGenBase.CallGenBase): # ============================================================ # M4-M6:协程内 raise(异常类型/值 → 帧 exc 槽) # ============================================================ - def _handle_coro_raise(self, builder: mlirlite.IRBuilder*, - pool: memhub.MemBuddy*, - mod: mlirlite.LLVMModule*, - trans: HT.Translator*, - stmt: ast.AST*): + def _handle_coro_raise(self, builder: mlirlite.IRBuilder*, pool: memhub.MemBuddy*, mod: mlirlite.LLVMModule*, trans: HT.Translator*, stmt: ast.AST*): """协程内 raise:解析异常类型/值 → 帧 exc 槽(+msg); try 栈非空跳 except 处理器,否则 done=1 + br exit 终止。""" i32_ty: mlirlite.LLVMType* = mlirlite.Int32(pool) @@ -1523,8 +1446,7 @@ novirtual class AsyncGenMixin(CallGenBase.CallGenBase): mlirlite.build_store(builder, done_r, trans._coro_done_ptr) mlirlite.build_br(builder, trans._coro_exit_bb) - def _resolve_raise_code(self, pool: memhub.MemBuddy*, - exc_node: ast.AST*) -> int: + def _resolve_raise_code(self, pool: memhub.MemBuddy*, exc_node: ast.AST*) -> int: """解析 raise 目标的异常码(内置/用户异常类名);非异常类返回 0""" if exc_node is None: return 0 name: str = None @@ -1542,11 +1464,7 @@ novirtual class AsyncGenMixin(CallGenBase.CallGenBase): if name is None: return 0 return self.Gen.ClassGenBase.lookup_exception_code(name) - def _resolve_raise_msg(self, builder: mlirlite.IRBuilder*, - pool: memhub.MemBuddy*, - mod: mlirlite.LLVMModule*, - trans: HT.Translator*, - exc_node: ast.AST*) -> mlirlite.Value*: + def _resolve_raise_msg(self, builder: mlirlite.IRBuilder*, pool: memhub.MemBuddy*, mod: mlirlite.LLVMModule*, trans: HT.Translator*, exc_node: ast.AST*) -> mlirlite.Value*: """取异常消息表达式(Exception("msg") 首参),无则返回 None""" if exc_node is None or exc_node.kind() != ast.ASTKind.Call: return None cl: ast.Call* = ast.Call*(exc_node) @@ -1556,11 +1474,7 @@ novirtual class AsyncGenMixin(CallGenBase.CallGenBase): # ============================================================ # M5-M6:协程内 try/except(多 except 链式匹配 + 类型码 + as e 绑定) # ============================================================ - def _handle_coro_try(self, trans: HT.Translator*, - builder: mlirlite.IRBuilder*, - pool: memhub.MemBuddy*, - mod: mlirlite.LLVMModule*, - stmt: ast.AST*): + def _handle_coro_try(self, trans: HT.Translator*, builder: mlirlite.IRBuilder*, pool: memhub.MemBuddy*, mod: mlirlite.LLVMModule*, stmt: ast.AST*): """协程内 try/except:raise/await 传播异常在 try 栈内改跳 except 处理器; 多 except 按声明序匹配(含子类码集合),Exception/裸 except 捕获所有; 全不匹配重新传播(done=1 + br exit)。""" @@ -1633,8 +1547,7 @@ novirtual class AsyncGenMixin(CallGenBase.CallGenBase): match_cond: mlirlite.Value* = None ci: int = 0 for ci in range(ncodes): - eq_v: mlirlite.Value* = mlirlite.build_icmp(builder, mlirlite.ICMP_EQ, exc_val, - mlirlite.const_int32(pool, codes_buf[ci])) + eq_v: mlirlite.Value* = mlirlite.build_icmp(builder, mlirlite.ICMP_EQ, exc_val, mlirlite.const_int32(pool, codes_buf[ci])) if match_cond is None: match_cond = eq_v else: match_cond = mlirlite.build_or(builder, match_cond, eq_v) if match_cond is None: mlirlite.build_br(builder, next_check) @@ -1664,8 +1577,7 @@ novirtual class AsyncGenMixin(CallGenBase.CallGenBase): if mlirlite.builder_cur_block_is_terminated(builder) == 0: mlirlite.build_br(builder, merge_bb) mlirlite.position_at_end(builder, merge_bb) - def _exception_type_name(self, pool: memhub.MemBuddy*, - type_node: ast.AST*) -> str: + def _exception_type_name(self, pool: memhub.MemBuddy*, type_node: ast.AST*) -> str: """取 except 类型名(Name/Attribute),未命中返回 None""" if type_node is None: return None if type_node.kind() == ast.ASTKind.Name: @@ -1679,11 +1591,7 @@ novirtual class AsyncGenMixin(CallGenBase.CallGenBase): # ============================================================ # M7:协程内 try/finally(无 except) # ============================================================ - def _handle_coro_try_finally(self, trans: HT.Translator*, - builder: mlirlite.IRBuilder*, - pool: memhub.MemBuddy*, - mod: mlirlite.LLVMModule*, - stmt: ast.AST*): + def _handle_coro_try_finally(self, trans: HT.Translator*, builder: mlirlite.IRBuilder*, pool: memhub.MemBuddy*, mod: mlirlite.LLVMModule*, stmt: ast.AST*): """协程内 try/finally:正常/异常路径都执行 fbody; 异常时 finally 后重新传播(done=1 + br exit);finally 内不支持 await。""" i32_ty: mlirlite.LLVMType* = mlirlite.Int32(pool) @@ -1709,9 +1617,7 @@ novirtual class AsyncGenMixin(CallGenBase.CallGenBase): if trans._coro_try_stack_count > 0: trans._coro_try_stack_count = trans._coro_try_stack_count - 1 # fin_bb:记录异常标志 + 执行 fbody mlirlite.position_at_end(builder, fin_bb) - was_exc: mlirlite.Value* = mlirlite.build_icmp(builder, mlirlite.ICMP_NE, - mlirlite.build_load(builder, i32_ty, trans._coro_exc_ptr), - mlirlite.const_int32(pool, 0)) + was_exc: mlirlite.Value* = mlirlite.build_icmp(builder, mlirlite.ICMP_NE, mlirlite.build_load(builder, i32_ty, trans._coro_exc_ptr), mlirlite.const_int32(pool, 0)) self._handle_segment(trans, builder, pool, mod, tr.finalbody) if mlirlite.builder_cur_block_is_terminated(builder) == 0: mlirlite.build_cond_br(builder, was_exc, fin_exc_bb, merge_bb) # fin_exc:finally 后异常继续传播 @@ -1724,11 +1630,7 @@ novirtual class AsyncGenMixin(CallGenBase.CallGenBase): # ============================================================ # M3:协程内 range-For(含 await)变换为 While(__f_idx/__f_len 帧槽) # ============================================================ - def _handle_coro_for(self, trans: HT.Translator*, - builder: mlirlite.IRBuilder*, - pool: memhub.MemBuddy*, - mod: mlirlite.LLVMModule*, - stmt: ast.AST*): + def _handle_coro_for(self, trans: HT.Translator*, builder: mlirlite.IRBuilder*, pool: memhub.MemBuddy*, mod: mlirlite.LLVMModule*, stmt: ast.AST*): """range-For(含 await):__f_idx_N = start; __f_len_N = end; while __f_idx_N < __f_len_N: target = __f_idx_N; ; __f_idx_N += 1""" i32_ty: mlirlite.LLVMType* = mlirlite.Int32(pool) @@ -1743,10 +1645,8 @@ novirtual class AsyncGenMixin(CallGenBase.CallGenBase): trans._coro_for_counter = k + 1 idx_idx: int = trans._coro_extra_base + trans._coro_for_slots[k] len_idx: int = idx_idx + 1 - idx_slot: mlirlite.Value* = mlirlite.build_gep_struct(builder, self._lookup_coro_frame_by_trans(trans), - i32_ty, trans._coro_frame, idx_idx) - len_slot: mlirlite.Value* = mlirlite.build_gep_struct(builder, self._lookup_coro_frame_by_trans(trans), - i32_ty, trans._coro_frame, len_idx) + idx_slot: mlirlite.Value* = mlirlite.build_gep_struct(builder, self._lookup_coro_frame_by_trans(trans), i32_ty, trans._coro_frame, idx_idx) + len_slot: mlirlite.Value* = mlirlite.build_gep_struct(builder, self._lookup_coro_frame_by_trans(trans), i32_ty, trans._coro_frame, len_idx) if idx_slot is None or len_slot is None: return # start/end(range 1/2 参数) cl: ast.Call* = ast.Call*(fn.iter) @@ -1802,11 +1702,7 @@ novirtual class AsyncGenMixin(CallGenBase.CallGenBase): # ============================================================ # M3/M4/M7:coro.coro_destroy / coro_exception / coro_exception_msg / coro_gather # ============================================================ - def translate_coro_destroy(self, builder: mlirlite.IRBuilder*, - pool: memhub.MemBuddy*, - mod: mlirlite.LLVMModule*, - cl: ast.Call*, - trans: HT.Translator*) -> mlirlite.Value*: + def translate_coro_destroy(self, builder: mlirlite.IRBuilder*, pool: memhub.MemBuddy*, mod: mlirlite.LLVMModule*, cl: ast.Call*, trans: HT.Translator*) -> mlirlite.Value*: """coro.coro_destroy(帧):帧回池(free-list,帧首 8 字节存 next)""" i32_ty: mlirlite.LLVMType* = mlirlite.Int32(pool) i64_ty: mlirlite.LLVMType* = mlirlite.Int64(pool) @@ -1834,11 +1730,7 @@ novirtual class AsyncGenMixin(CallGenBase.CallGenBase): mlirlite.build_store(builder, frame_i64, pool_ref) return mlirlite.const_int32(pool, 0) - def translate_coro_exception(self, builder: mlirlite.IRBuilder*, - pool: memhub.MemBuddy*, - mod: mlirlite.LLVMModule*, - cl: ast.Call*, - trans: HT.Translator*) -> mlirlite.Value*: + def translate_coro_exception(self, builder: mlirlite.IRBuilder*, pool: memhub.MemBuddy*, mod: mlirlite.LLVMModule*, cl: ast.Call*, trans: HT.Translator*) -> mlirlite.Value*: """coro.coro_exception(帧):返回帧 exc 槽(异常码,0=无异常)""" i32_ty: mlirlite.LLVMType* = mlirlite.Int32(pool) if cl is None or trans is None or cl.args is None or len(cl.args) < 1: return mlirlite.const_int32(pool, 0) @@ -1854,11 +1746,7 @@ novirtual class AsyncGenMixin(CallGenBase.CallGenBase): exc_ptr: mlirlite.Value* = mlirlite.build_gep_struct(builder, frame_ty, i32_ty, frame_ptr, 3) return mlirlite.build_load(builder, i32_ty, exc_ptr) - def translate_coro_exception_msg(self, builder: mlirlite.IRBuilder*, - pool: memhub.MemBuddy*, - mod: mlirlite.LLVMModule*, - cl: ast.Call*, - trans: HT.Translator*) -> mlirlite.Value*: + def translate_coro_exception_msg(self, builder: mlirlite.IRBuilder*, pool: memhub.MemBuddy*, mod: mlirlite.LLVMModule*, cl: ast.Call*, trans: HT.Translator*) -> mlirlite.Value*: """coro.coro_exception_msg(帧):返回帧 msg 槽(异常消息指针,null=无)""" i8_ptr_ty: mlirlite.LLVMType* = mlirlite.Ptr(pool, mlirlite.Int8(pool)) if cl is None or trans is None or cl.args is None or len(cl.args) < 1: return mlirlite.ConstNull(pool, i8_ptr_ty, "null") @@ -1874,11 +1762,7 @@ novirtual class AsyncGenMixin(CallGenBase.CallGenBase): msg_ptr: mlirlite.Value* = mlirlite.build_gep_struct(builder, frame_ty, i8_ptr_ty, frame_ptr, 4) return mlirlite.build_load(builder, i8_ptr_ty, msg_ptr) - def translate_coro_gather(self, builder: mlirlite.IRBuilder*, - pool: memhub.MemBuddy*, - mod: mlirlite.LLVMModule*, - cl: ast.Call*, - trans: HT.Translator*) -> mlirlite.Value*: + def translate_coro_gather(self, builder: mlirlite.IRBuilder*, pool: memhub.MemBuddy*, mod: mlirlite.LLVMModule*, cl: ast.Call*, trans: HT.Translator*) -> mlirlite.Value*: """coro.coro_gather(帧...):并发推进全部协程到完成,返回完成数(M4 纯 resume 循环)""" i32_ty: mlirlite.LLVMType* = mlirlite.Int32(pool) if cl is None or trans is None or cl.args is None: return mlirlite.const_int32(pool, 0) @@ -1912,8 +1796,7 @@ novirtual class AsyncGenMixin(CallGenBase.CallGenBase): mlirlite.position_at_end(builder, after_bb) return mlirlite.const_int32(pool, 0) - def _var_to_async(self, trans: HT.Translator*, - arg0: ast.AST*) -> str: + def _var_to_async(self, trans: HT.Translator*, arg0: ast.AST*) -> str: """变量节点 → async 函数名(_coro_var_async 反查),未命中返回 None""" if trans is None or arg0 is None or arg0.kind() != ast.ASTKind.Name: return None nm: ast.Name* = ast.Name*(arg0) @@ -1923,12 +1806,7 @@ novirtual class AsyncGenMixin(CallGenBase.CallGenBase): # ============================================================ # await 表达式翻译(顶层段尾 / translate_value Await 分支共用) # ============================================================ - def _emit_await(self, builder: mlirlite.IRBuilder*, - pool: memhub.MemBuddy*, - mod: mlirlite.LLVMModule*, - trans: HT.Translator*, - node: ast.AST*, - call_name: str) -> mlirlite.Value*: + def _emit_await(self, builder: mlirlite.IRBuilder*, pool: memhub.MemBuddy*, mod: mlirlite.LLVMModule*, trans: HT.Translator*, node: ast.AST*, call_name: str) -> mlirlite.Value*: """await async_fn(args...) 内联翻译(M2 带参数): 1. 求值调用参数(表达式逐个翻译,i32) 2. create_(args...) 创建子帧 @@ -2027,11 +1905,7 @@ novirtual class AsyncGenMixin(CallGenBase.CallGenBase): # ============================================================ # coro.coro_run(帧) 内联翻译 # ============================================================ - def translate_coro_run(self, builder: mlirlite.IRBuilder*, - pool: memhub.MemBuddy*, - mod: mlirlite.LLVMModule*, - cl: ast.Call*, - trans: HT.Translator*) -> mlirlite.Value*: + def translate_coro_run(self, builder: mlirlite.IRBuilder*, pool: memhub.MemBuddy*, mod: mlirlite.LLVMModule*, cl: ast.Call*, trans: HT.Translator*) -> mlirlite.Value*: """coro.coro_run(frame) 内联翻译: 参数是 Name 变量 → 经 _coro_var_async 反查 async 名 → _coro_frames 取帧类型 → bitcast 变量值到 Ptr(帧) → 循环 resume_(frame) 直到 @@ -2084,8 +1958,7 @@ novirtual class AsyncGenMixin(CallGenBase.CallGenBase): wake_ptr_r: mlirlite.Value* = mlirlite.build_gep_struct(builder, frame_ty, i64_ty_r2, frame_ptr, wake_idx_r) wake_v_r: mlirlite.Value* = mlirlite.build_load(builder, i64_ty_r2, wake_ptr_r) now_v_r: mlirlite.Value* = mlirlite.build_call(builder, "GetTickCount64", None, 0, i64_ty_r2, 0) - not_wake_r: mlirlite.Value* = mlirlite.build_icmp(builder, mlirlite.ICMP_EQ, wake_v_r, - mlirlite.const_int64(pool, 0)) + not_wake_r: mlirlite.Value* = mlirlite.build_icmp(builder, mlirlite.ICMP_EQ, wake_v_r, mlirlite.const_int64(pool, 0)) due_r: mlirlite.Value* = mlirlite.build_icmp(builder, mlirlite.ICMP_UGE, now_v_r, wake_v_r) cont_r: mlirlite.Value* = mlirlite.build_or(builder, not_wake_r, due_r) wsleep_bb: rawptr[mlirlite.BasicBlock] = mlirlite.create_block(pool, func, "coro.wsleep") @@ -2093,8 +1966,7 @@ novirtual class AsyncGenMixin(CallGenBase.CallGenBase): mlirlite.build_cond_br(builder, cont_r, wdue_bb, wsleep_bb) mlirlite.position_at_end(builder, wsleep_bb) sleep_one: mlirlite.Value* = mlirlite.const_int32(pool, 1) - mlirlite.build_call(builder, "Sleep", sleep_one, 1, - mlirlite.Void(pool), 0) + mlirlite.build_call(builder, "Sleep", sleep_one, 1, mlirlite.Void(pool), 0) mlirlite.build_br(builder, loop_bb) mlirlite.position_at_end(builder, wdue_bb) mlirlite.build_br(builder, loop_bb) @@ -2106,8 +1978,7 @@ novirtual class AsyncGenMixin(CallGenBase.CallGenBase): # ============================================================ # 公共查询 / 登记 # ============================================================ - def is_async_func(self, trans: HT.Translator*, - name: str) -> int: + def is_async_func(self, trans: HT.Translator*, name: str) -> int: """查询 name 是否已注册为 async 函数(_async_funcs 表),1=是 0=否""" if trans is None or name is None or trans._async_funcs is None: return 0 cnt: int = trans._async_func_count @@ -2118,8 +1989,7 @@ novirtual class AsyncGenMixin(CallGenBase.CallGenBase): if slot[0] is not None and string.strcmp(slot[0], name) == 0: return 1 return 0 - def register_coro_var(self, trans: HT.Translator*, - var_name: str, func_name: str) -> int: + def register_coro_var(self, trans: HT.Translator*, var_name: str, func_name: str) -> int: """记录 变量名→async 函数名 映射(coro.coro_run 反查帧类型用)。 对齐 TPC HandlesAnnAssign.py L319-326。返回 0 成功。""" if trans is None or var_name is None or func_name is None: return 1 @@ -2138,8 +2008,7 @@ novirtual class AsyncGenMixin(CallGenBase.CallGenBase): trans._coro_var_async_count = cnt + 1 return 0 - def _register_async_func(self, trans: HT.Translator*, - name: str) -> int: + def _register_async_func(self, trans: HT.Translator*, name: str) -> int: """注册 async 函数裸名到 _async_funcs 表""" if trans is None or name is None or trans._async_funcs is None: return 1 cnt: int = trans._async_func_count @@ -2155,9 +2024,7 @@ novirtual class AsyncGenMixin(CallGenBase.CallGenBase): trans._async_func_count = cnt + 1 return 0 - def _register_coro_frame(self, trans: HT.Translator*, - name: str, - frame_ty: mlirlite.LLVMType*) -> int: + def _register_coro_frame(self, trans: HT.Translator*, name: str, frame_ty: mlirlite.LLVMType*) -> int: """注册 async 名→帧类型 到 _coro_frames 表(16 字节/项 = char* + LLVMType*)""" if trans is None or name is None or frame_ty is None: return 1 if trans._coro_frames is None: return 1 @@ -2177,8 +2044,7 @@ novirtual class AsyncGenMixin(CallGenBase.CallGenBase): trans._coro_frame_count = cnt + 1 return 0 - def _lookup_coro_frame(self, trans: HT.Translator*, - name: str) -> mlirlite.LLVMType*: + def _lookup_coro_frame(self, trans: HT.Translator*, name: str) -> mlirlite.LLVMType*: """按 async 名查帧类型,未命中返回 None""" if trans is None or name is None or trans._coro_frames is None: return None cnt: int = trans._coro_frame_count @@ -2193,8 +2059,7 @@ novirtual class AsyncGenMixin(CallGenBase.CallGenBase): return None return None - def _lookup_coro_var(self, trans: HT.Translator*, - var_name: str) -> str: + def _lookup_coro_var(self, trans: HT.Translator*, var_name: str) -> str: """按变量名反查 async 函数名(_coro_var_async 表),未命中返回 None""" if trans is None or var_name is None or trans._coro_var_async is None: return None cnt: int = trans._coro_var_async_count @@ -2208,11 +2073,7 @@ novirtual class AsyncGenMixin(CallGenBase.CallGenBase): # ============================================================ # 段翻译辅助 # ============================================================ - def _emit_coro_return(self, builder: mlirlite.IRBuilder*, - pool: memhub.MemBuddy*, - mod: mlirlite.LLVMModule*, - trans: HT.Translator*, - stmt: ast.AST*) -> None: + def _emit_coro_return(self, builder: mlirlite.IRBuilder*, pool: memhub.MemBuddy*, mod: mlirlite.LLVMModule*, trans: HT.Translator*, stmt: ast.AST*) -> None: """协程内 Return 特判:store ret 槽 + done=1 + br exit。 M1 不支持 return await(顶层 await 仅限 AnnAssign/Assign)。 @@ -2307,8 +2168,7 @@ novirtual class AsyncGenMixin(CallGenBase.CallGenBase): if at.attr is not None and string.strcmp(at.attr, "coro_sleep") == 0: return "coro_sleep" return None - def _read_local_name(self, trans: HT.Translator*, - idx: int) -> str: + def _read_local_name(self, trans: HT.Translator*, idx: int) -> str: """读 trans._coro_locals 第 idx 个局部变量名,越界返回 None""" if trans is None or trans._coro_locals is None: return None addr: uint64 = uint64(trans._coro_locals) + idx * 8 diff --git a/App/lib/core/Gen/Call/CallGenBase.vp b/App/lib/core/Gen/Call/CallGenBase.vp index 185500b..a133783 100644 --- a/App/lib/core/Gen/Call/CallGenBase.vp +++ b/App/lib/core/Gen/Call/CallGenBase.vp @@ -430,8 +430,7 @@ novirtual class CallGenBase: return 0 - def _is_state_func_from_vpi(self, pool: memhub.MemBuddy*, - sha1: str, func_name: str) -> int: + def _is_state_func_from_vpi(self, pool: memhub.MemBuddy*, sha1: str, func_name: str) -> int: """vpi 返回注解含 t.State → 外部 C 函数(定义端用裸名,跨模块调用无 sha1 头) t.State(同 t.CExtern/t.CExport)是外部函数标记:定义端生成裸名 @@ -448,9 +447,7 @@ novirtual class CallGenBase: return 0 - def _lookup_mod_sha1(self, pool: memhub.MemBuddy*, - from_imports: str, class_name: str, - allow_star_fallback: int = 1) -> str: + def _lookup_mod_sha1(self, pool: memhub.MemBuddy*, from_imports: str, class_name: str, allow_star_fallback: int = 1) -> str: """从 from_imports 查找类所属模块的 SHA1,返回 None=未找到 allow_star_fallback: 传 0 禁用 star import 回退(用于明确模块名/函数名查找) @@ -460,8 +457,7 @@ novirtual class CallGenBase: return self._lookup_sha1_from_modname_raw(pool, mod_name_raw) - def _lookup_sha1_from_modname_raw(self, pool: memhub.MemBuddy*, - mod_name_raw: str) -> str: + def _lookup_sha1_from_modname_raw(self, pool: memhub.MemBuddy*, mod_name_raw: str) -> str: """从原始模块名查找 SHA1,返回 None=未找到""" # 手动找到模块名结束位置(空格、null、或 ':' 别名分隔符),复制到新缓冲区 mod_len: sizet = 0 @@ -478,8 +474,7 @@ novirtual class CallGenBase: return sha1 - def _FuncTyFromFunction(self, pool: memhub.MemBuddy*, - f_ref: mlirlite.Function*) -> mlirlite.LLVMType*: + def _FuncTyFromFunction(self, pool: memhub.MemBuddy*, f_ref: mlirlite.Function*) -> mlirlite.LLVMType*: """由 mlirlite.Function 的形参链表(Param 链)构造 LLVMType.Func 类型。 为什么不能直接把 Param 链交给 mlirlite.Func:`Function.Params` 是 **Param** 链 @@ -506,9 +501,7 @@ novirtual class CallGenBase: p_cur = mlirlite.param_get_next(p_cur) return mlirlite.Func(pool, f_ref.RetTy, pn_head, p_cnt) - def find_func_in_module(self, mod: mlirlite.LLVMModule*, - name: str, - owner_sha1: str = None) -> mlirlite.Function*: + def find_func_in_module(self, mod: mlirlite.LLVMModule*, name: str, owner_sha1: str = None) -> mlirlite.Function*: """在模块的函数链表中按名称查找函数 查找策略: @@ -575,12 +568,7 @@ novirtual class CallGenBase: # _ensure_method_declare:found_func 为 None(stub 未注入或跨模块调用)时在当前模块创建 declare,避免 llc 报 undefined value - def _ensure_method_declare(self, pool: memhub.MemBuddy*, - mod: mlirlite.LLVMModule*, - call_name: str, - ret_ty: mlirlite.LLVMType*, - param_head: mlirlite.Value*, - param_count: int): + def _ensure_method_declare(self, pool: memhub.MemBuddy*, mod: mlirlite.LLVMModule*, call_name: str, ret_ty: mlirlite.LLVMType*, param_head: mlirlite.Value*, param_count: int): """为跨模块方法调用创建 declare 声明 若模块中已存在同名 declare 且参数数量较少(例如 File.__init__ 的 @@ -718,10 +706,7 @@ novirtual class CallGenBase: # _lookup_method_ret_ty_via_vpi:按 模块SHA1 + 类名 + 方法名 查 vpi 返回注解缓存并解析为 LLVMType,未命中返回 None(不硬编码白名单,类型始终来自定义处) # ============================================================ - def _lookup_method_ret_ty_via_vpi(self, pool: memhub.MemBuddy*, - cls_sha1: str, - cls_name: str, - method_name: str) -> mlirlite.LLVMType*: + def _lookup_method_ret_ty_via_vpi(self, pool: memhub.MemBuddy*, cls_sha1: str, cls_name: str, method_name: str) -> mlirlite.LLVMType*: """从 vpi stub 返回注解缓存获取方法返回类型,未命中返回 None""" if pool is None or cls_sha1 is None or method_name is None: return None # 函数内懒 import:VpiReader imports HandlesExprCall,顶层 import 会成环 @@ -735,10 +720,7 @@ novirtual class CallGenBase: return VpiReader._resolve_vpi_ret_annot_str(pool, annot, i32_ty, i8_ptr_ty) # _vpi_method_param_annot:按需加载并查询 vpi 参数注解串('@' 分隔,含首参 self 空串占位),供调用方补全 declare/call 缺失参数;未命中返回 None - def _vpi_method_param_annot(self, pool: memhub.MemBuddy*, - cls_sha1: str, - cls_name: str, - method_name: str) -> str: + def _vpi_method_param_annot(self, pool: memhub.MemBuddy*, cls_sha1: str, cls_name: str, method_name: str) -> str: """按需加载并查询 vpi 参数注解串,未命中返回 None""" if pool is None or cls_sha1 is None or cls_name is None or method_name is None: return None # 按需加载:缓存未命中时直接读 {temp_dir}/{sha1[0:2]}/{sha1}.vpi @@ -746,8 +728,7 @@ novirtual class CallGenBase: return VpiReader._lookup_vpi_param_annots(cls_sha1, cls_name, method_name) # _vpi_resolve_param_annot_ty:解析 vpi 参数注解段为 LLVMType,失败返回 None(调用方以 i8* 兜底) - def _vpi_resolve_param_annot_ty(self, pool: memhub.MemBuddy*, - seg: str) -> mlirlite.LLVMType*: + def _vpi_resolve_param_annot_ty(self, pool: memhub.MemBuddy*, seg: str) -> mlirlite.LLVMType*: """解析单个 vpi 参数注解段为 LLVMType,失败返回 None""" if pool is None or seg is None: return None i32_ty: mlirlite.LLVMType* = mlirlite.Int32(pool) @@ -757,9 +738,7 @@ novirtual class CallGenBase: # _special_method_ret_ty:编译器内置特殊方法的固定返回类型——__before_init__/__init__ → void,__new__ → Ptr(StructTy),非特殊返回 None(vpi 无条目,固定即可避免 fail-fast 误报) # ============================================================ - def _special_method_ret_ty(self, pool: memhub.MemBuddy*, - class_name: str, - method_name: str) -> mlirlite.LLVMType*: + def _special_method_ret_ty(self, pool: memhub.MemBuddy*, class_name: str, method_name: str) -> mlirlite.LLVMType*: """编译器内置特殊方法的固定返回类型;非特殊返回 None""" if pool is None or method_name is None: return None if string.strcmp(method_name, "__before_init__") == 0 or string.strcmp(method_name, "__init__") == 0: return mlirlite.Void(pool) @@ -773,8 +752,7 @@ novirtual class CallGenBase: # _fail_method_ret_ty:方法返回类型无法精确获取时 ERROR + 错误堆栈终止(node 为调用点 AST,用于定位),绝不静默默认 i32 # ============================================================ - def _fail_method_ret_ty(self, method_name: str, - node: ast.AST* = None) -> mlirlite.LLVMType*: + def _fail_method_ret_ty(self, method_name: str, node: ast.AST* = None) -> mlirlite.LLVMType*: """方法返回类型无法精确获取时 fail-fast(ERROR + 错误堆栈) 返回类型来源(按序):当前模块函数 → text.ll define → vpi stub 返回注解缓存。 @@ -797,10 +775,7 @@ novirtual class CallGenBase: # _ParseLLVMRetTyStr:把 LLVM IR 返回类型字符串(define 与 @ 之间)转为 LLVMType——void / iN / double / float,含 * 者返回通用 Ptr(Int8);无法解析返回 None # ============================================================ - def _ParseLLVMRetTyStr(self, pool: memhub.MemBuddy*, - buf: bytes, - start: sizet, - end: sizet) -> mlirlite.LLVMType*: + def _ParseLLVMRetTyStr(self, pool: memhub.MemBuddy*, buf: bytes, start: sizet, end: sizet) -> mlirlite.LLVMType*: """将 LLVM IR 返回类型字符串转换为 mlirlite.LLVMType""" if pool is None or buf is None or start >= end: return None @@ -931,10 +906,7 @@ novirtual class CallGenBase: return None # ============================================================ - def _ParseMlirRetTyStr(self, pool: memhub.MemBuddy*, - buf: bytes, - start: sizet, - end: sizet) -> mlirlite.LLVMType*: + def _ParseMlirRetTyStr(self, pool: memhub.MemBuddy*, buf: bytes, start: sizet, end: sizet) -> mlirlite.LLVMType*: """把 mlirlite 的 MLIR 返回类型文本转成 mlirlite.LLVMType 覆盖 `llvm.func` 签名里会出现的形态(includes/mlirlite/README.md §2.1): @@ -1099,8 +1071,7 @@ novirtual class CallGenBase: return None # _LookupCachedRetTyText:查「依赖模块 text.ll 方法返回类型文本」持久缓存——键为 define 完整 mangled 名("{sha1}.{class}.{method}",bare 模式 "{sha1}.{method}"),命中返回文本,未命中/表未建返回 None - def _LookupCachedRetTyText(self, class_sha1: str, class_name: str, - method_name: str, use_bare: int) -> str: + def _LookupCachedRetTyText(self, class_sha1: str, class_name: str, method_name: str, use_bare: int) -> str: """查返回类型文本缓存:命中返回文本,未命中返回 None""" if self.Gen is None or class_sha1 is None or method_name is None: return None ht: hashtable.HashTable* = self.Gen.CallGenBase.MethodRetTyMap @@ -1116,17 +1087,14 @@ novirtual class CallGenBase: if key_buf is None: return None if use_bare != 0: viperlib.snprintf(key_buf, key_len, "%s.%s", class_sha1, method_name) else: - viperlib.snprintf(key_buf, key_len, "%s.%s.%s", - class_sha1, class_name, method_name) + viperlib.snprintf(key_buf, key_len, "%s.%s.%s", class_sha1, class_name, method_name) v: t.CPtr = ht.__getitem__(key_buf) stdlib.free(key_buf) if v is None: return None return rawptr(v) # _CacheModuleRetTyTexts:单趟扫描某模块 text.ll——把全部 define 行的返回类型写入持久缓存(键/值深拷贝进 PermPool,同名只记首次,只登记 "{sha1}." 开头的本模块 mangled 名),并在同一趟里返回首个匹配 search_buf 的 define 的返回类型(未匹配返回 None);仅在成功读到 text.ll 后调用,负结果绝不缓存 - def _CacheModuleRetTyTexts(self, class_sha1: str, text_buf: bytes, - text_len: sizet, pool: memhub.MemBuddy*, - search_buf: str, search_str_len: sizet) -> mlirlite.LLVMType*: + def _CacheModuleRetTyTexts(self, class_sha1: str, text_buf: bytes, text_len: sizet, pool: memhub.MemBuddy*, search_buf: str, search_str_len: sizet) -> mlirlite.LLVMType*: """单趟「登记 + 查找」text.ll 全部 define 行(建表/分配失败时只查找不登记)""" if text_buf is None or text_len == 0: return None # 合并原「先全量登记一遍、再二次扫描查找」的两趟全文件遍历(PROF:两次扫描合计约 14%)。 @@ -1267,11 +1235,7 @@ novirtual class CallGenBase: # _LookupMethodRetTyFromTextLL:读取 {temp_dir}/{sha1[0:2]}/{sha1}.text.ll (level=1),按 "{sha1}.{class_name}.{method_name}" 搜索 define 行并解析返回类型;未找到/文件不存在返回 None # ============================================================ - def _LookupMethodRetTyFromTextLL(self, pool: memhub.MemBuddy*, - class_sha1: str, - class_name: str, - method_name: str, - use_bare: int = 0) -> mlirlite.LLVMType*: + def _LookupMethodRetTyFromTextLL(self, pool: memhub.MemBuddy*, class_sha1: str, class_name: str, method_name: str, use_bare: int = 0) -> mlirlite.LLVMType*: """从依赖模块的 text.ll 中查找方法返回类型 use_bare: 1=按模块级函数查找(搜索 "{sha1}.{method_name}" define, @@ -1302,8 +1266,7 @@ novirtual class CallGenBase: subdir_buf[0] = class_sha1[0] subdir_buf[1] = class_sha1[1] subdir_buf[2] = '\0' - viperlib.snprintf(path_buf, path_len, "%s/%s/%s.text.ll", - self.Gen.CallGenBase.TempDir, subdir_buf, class_sha1) + viperlib.snprintf(path_buf, path_len, "%s/%s/%s.text.ll", self.Gen.CallGenBase.TempDir, subdir_buf, class_sha1) stdlib.free(subdir_buf) # 按文件实际大小读取 text.ll(固定缓冲区会截断大模块导致末尾定义查不到);64MB 上限防御异常超大文件 @@ -1342,17 +1305,14 @@ novirtual class CallGenBase: stdlib.free(read_buf) return None if use_bare != 0: - viperlib.snprintf(search_buf, search_len, "%s.%s", - class_sha1, method_name) + viperlib.snprintf(search_buf, search_len, "%s.%s", class_sha1, method_name) else: - viperlib.snprintf(search_buf, search_len, "%s.%s.%s", - class_sha1, class_name, method_name) + viperlib.snprintf(search_buf, search_len, "%s.%s.%s", class_sha1, class_name, method_name) search_str_len: sizet = string.strlen(search_buf) # 单趟扫描 text.ll:登记其全部 define 行供后续 O(1) 命中,并同趟取出首个匹配项。 # 文件长度直接用 read_all 的返回值,省掉一次整文件 strlen。 - result_ty: mlirlite.LLVMType* = self._CacheModuleRetTyTexts( - class_sha1, read_buf, sizet(text_len), pool, search_buf, search_str_len) + result_ty: mlirlite.LLVMType* = self._CacheModuleRetTyTexts(class_sha1, read_buf, sizet(text_len), pool, search_buf, search_str_len) stdlib.free(search_buf) stdlib.free(read_buf) @@ -1361,8 +1321,7 @@ novirtual class CallGenBase: # _dep_text_ll_exists:探测 {temp_dir}/{sha1[0:2]}/{sha1}.text.ll 是否存在(1=存在),用于区分「依赖已编译但函数缺失」与「依赖模块尚未翻译」 # ============================================================ - def _dep_text_ll_exists(self, pool: memhub.MemBuddy*, - sha1: str) -> int: + def _dep_text_ll_exists(self, pool: 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: return 0 sha1_len: sizet = string.strlen(sha1) @@ -1377,8 +1336,7 @@ novirtual class CallGenBase: subdir_buf[0] = sha1[0] subdir_buf[1] = sha1[1] subdir_buf[2] = '\0' - viperlib.snprintf(path_buf, path_len, "%s/%s/%s.text.ll", - self.Gen.CallGenBase.TempDir, subdir_buf, sha1) + viperlib.snprintf(path_buf, path_len, "%s/%s/%s.text.ll", self.Gen.CallGenBase.TempDir, subdir_buf, sha1) stdlib.free(subdir_buf) # 存在性判定用 GetFileAttributesA(属性查询,不开文件句柄) attr: ULONG = win32file.GetFileAttributesA(path_buf) diff --git a/App/lib/core/Gen/Call/CallGenCBuiltin.vp b/App/lib/core/Gen/Call/CallGenCBuiltin.vp index 704bbdd..eeaa7c3 100644 --- a/App/lib/core/Gen/Call/CallGenCBuiltin.vp +++ b/App/lib/core/Gen/Call/CallGenCBuiltin.vp @@ -40,11 +40,7 @@ define LLVMIR_TEMPLATE_BUF = 512 novirtual class CallGenCBuiltin(CallGenBase.CallGenBase): """c.* 内建 + 内联汇编 + LLVMIR 翻译(继承 Base)""" - def translate_c_deref(self, pool: memhub.MemBuddy*, - builder: mlirlite.IRBuilder*, - mod: mlirlite.LLVMModule*, - cl: ast.Call*, - trans: HT.Translator* = None) -> mlirlite.Value*: + def translate_c_deref(self, pool: memhub.MemBuddy*, builder: mlirlite.IRBuilder*, mod: mlirlite.LLVMModule*, cl: ast.Call*, trans: HT.Translator* = None) -> mlirlite.Value*: """*ptr → load,宽度只由 ptr 的 pointee 类型决定 pointee 是 i8(t.CPtr / void* / str / bytes)恒读 1 字节;不再按赋值 目标注解(CurAssignAnnot)反推宽度——那会让同一处 *(i8*) 的读取 @@ -74,11 +70,7 @@ novirtual class CallGenCBuiltin(CallGenBase.CallGenBase): return None - def translate_c_derefas(self, pool: memhub.MemBuddy*, - builder: mlirlite.IRBuilder*, - mod: mlirlite.LLVMModule*, - cl: ast.Call*, - trans: HT.Translator* = None) -> mlirlite.Value*: + def translate_c_derefas(self, pool: memhub.MemBuddy*, builder: mlirlite.IRBuilder*, mod: mlirlite.LLVMModule*, cl: ast.Call*, trans: HT.Translator* = None) -> mlirlite.Value*: """c.DerefAs(ptr, val) → store val to ptr(bitcast 后 store) 单参形式 c.DerefAs(ptr) → 读取 ptr 指向的值(等价 *ptr)。 """ @@ -126,11 +118,7 @@ novirtual class CallGenCBuiltin(CallGenBase.CallGenBase): return val - def translate_c_set(self, pool: memhub.MemBuddy*, - builder: mlirlite.IRBuilder*, - mod: mlirlite.LLVMModule*, - cl: ast.Call*, - trans: HT.Translator* = None) -> mlirlite.Value*: + def translate_c_set(self, pool: memhub.MemBuddy*, builder: mlirlite.IRBuilder*, mod: mlirlite.LLVMModule*, cl: ast.Call*, trans: HT.Translator* = None) -> mlirlite.Value*: """c.Set(a, b) → a = b(赋值语义,a 为左值)""" if cl is None: return None cargs: list[ast.AST*]* = cl.args @@ -223,11 +211,7 @@ novirtual class CallGenCBuiltin(CallGenBase.CallGenBase): return b_val - def translate_c_addr(self, pool: memhub.MemBuddy*, - builder: mlirlite.IRBuilder*, - mod: mlirlite.LLVMModule*, - cl: ast.Call*, - trans: HT.Translator* = None) -> mlirlite.Value*: + def translate_c_addr(self, pool: memhub.MemBuddy*, builder: mlirlite.IRBuilder*, mod: mlirlite.LLVMModule*, cl: ast.Call*, trans: HT.Translator* = None) -> mlirlite.Value*: """&var → 返回变量的 alloca 指针(不 load)""" if cl is None: return None cargs: list[ast.AST*]* = cl.args @@ -468,11 +452,7 @@ novirtual class CallGenCBuiltin(CallGenBase.CallGenBase): return None - def translate_c_load(self, pool: memhub.MemBuddy*, - builder: mlirlite.IRBuilder*, - mod: mlirlite.LLVMModule*, - cl: ast.Call*, - trans: HT.Translator* = None) -> mlirlite.Value*: + def translate_c_load(self, pool: memhub.MemBuddy*, builder: mlirlite.IRBuilder*, mod: mlirlite.LLVMModule*, cl: ast.Call*, trans: HT.Translator* = None) -> mlirlite.Value*: """c.Load(a, b) → *a = *b(加载 b 的值,存储到 a)""" if cl is None: return None cargs: list[ast.AST*]* = cl.args @@ -498,8 +478,7 @@ novirtual class CallGenCBuiltin(CallGenBase.CallGenBase): return loaded - def _asm_append_cstr(self, dst: str, dst_size: sizet, - src: str): + def _asm_append_cstr(self, dst: str, dst_size: sizet, src: str): """将 C 字符串 src 追加到 dst 末尾""" if dst is None or src is None: return dlen: sizet = string.strlen(dst) @@ -513,9 +492,7 @@ novirtual class CallGenCBuiltin(CallGenBase.CallGenBase): dst[dlen + i] = '\0' - def _asm_mangle_global_symbols(self, pool: memhub.MemBuddy*, - asm_text: str, asm_size: sizet, - mod: mlirlite.LLVMModule*) -> str: + def _asm_mangle_global_symbols(self, pool: memhub.MemBuddy*, asm_text: str, asm_size: sizet, mod: mlirlite.LLVMModule*) -> str: """asm 模板中裸符号引用模块全局的检查(fail-fast) 内联汇编 `lea rax, [rip + gdt]` 的 gdt 是汇编器符号,若对应模块全局 @@ -570,8 +547,7 @@ novirtual class CallGenCBuiltin(CallGenBase.CallGenBase): return out - def _asm_escape_for_ir(self, pool: memhub.MemBuddy*, - src: str) -> str: + def _asm_escape_for_ir(self, pool: memhub.MemBuddy*, src: str) -> str: """转义汇编文本用于 LLVM IR 字符串字面量""" if src is None: return None slen: sizet = string.strlen(src) @@ -702,8 +678,7 @@ novirtual class CallGenCBuiltin(CallGenBase.CallGenBase): return "" - def _resolve_asm_descr(self, pool: memhub.MemBuddy*, - node: ast.AST*) -> str: + def _resolve_asm_descr(self, pool: memhub.MemBuddy*, node: ast.AST*) -> str: """递归解析约束表达式,返回约束字符串""" if node is None: return "" @@ -752,8 +727,7 @@ novirtual class CallGenCBuiltin(CallGenBase.CallGenBase): return "" - def _asm_get_operand(self, base: rawptr[GenTypes.AsmOperand], - idx: int) -> rawptr[GenTypes.AsmOperand]: + def _asm_get_operand(self, base: rawptr[GenTypes.AsmOperand], idx: int) -> rawptr[GenTypes.AsmOperand]: """获取操作数数组中第 idx 个元素的指针""" entry_size: sizet = GenTypes.AsmOperand.__sizeof__() entry_addr: uint64 = uint64(base) + idx * entry_size @@ -803,11 +777,7 @@ novirtual class CallGenCBuiltin(CallGenBase.CallGenBase): return 0 - def _asm_add_operand(self, operands: rawptr[GenTypes.AsmOperand], - count: int, - val: mlirlite.Value*, - constraint: str, - is_output: int) -> int: + def _asm_add_operand(self, operands: rawptr[GenTypes.AsmOperand], count: int, val: mlirlite.Value*, constraint: str, is_output: int) -> int: """添加操作数到数组,返回新计数(失败返回原计数) 去重:f-string 模板内嵌的 AsmOut/AsmInp 与 out=/inp= 声明指向 @@ -840,11 +810,7 @@ novirtual class CallGenCBuiltin(CallGenBase.CallGenBase): return count + 1 - def translate_c_asm(self, pool: memhub.MemBuddy*, - builder: mlirlite.IRBuilder*, - mod: mlirlite.LLVMModule*, - cl: ast.Call*, - trans: HT.Translator* = None) -> mlirlite.Value*: + def translate_c_asm(self, pool: memhub.MemBuddy*, builder: mlirlite.IRBuilder*, mod: mlirlite.LLVMModule*, cl: ast.Call*, trans: HT.Translator* = None) -> mlirlite.Value*: """翻译 __asm__ 内联汇编,返回结果 Value(无输出时返回 None)""" if cl is None: return None @@ -1338,11 +1304,9 @@ novirtual class CallGenCBuiltin(CallGenBase.CallGenBase): if line is None: return None if is_void == 1: - viperlib.snprintf(line, line_cap, "call %s asm sideeffect inteldialect \"%s\", \"%s\"(%s)", - ret_ty_buf, escaped_asm, const_buf, args_buf) + viperlib.snprintf(line, line_cap, "call %s asm sideeffect inteldialect \"%s\", \"%s\"(%s)", ret_ty_buf, escaped_asm, const_buf, args_buf) else: - viperlib.snprintf(line, line_cap, "%s = call %s asm sideeffect inteldialect \"%s\", \"%s\"(%s)", - ssa_name, ret_ty_buf, escaped_asm, const_buf, args_buf) + viperlib.snprintf(line, line_cap, "%s = call %s asm sideeffect inteldialect \"%s\", \"%s\"(%s)", ssa_name, ret_ty_buf, escaped_asm, const_buf, args_buf) # 发射 IR 到当前块 mlirlite.block_append_text(pool, builder.CurBlock, line) @@ -1367,9 +1331,7 @@ novirtual class CallGenCBuiltin(CallGenBase.CallGenBase): # "%asm.N.e{i}"(字母开头,避免 %N.e{i} 被解析为 # 数字 ID + 非法后缀导致 "expected '=' after id") viperlib.snprintf(ev_name, 32, "%%asm.%s.e%d", ssa_name + 1, out_emit_idx) - viperlib.snprintf(ev_line, ASM_LINE_BUF_SIZE, - "%s = extractvalue %s %s, %d", - ev_name, ret_ty_buf, ssa_name, out_emit_idx) + viperlib.snprintf(ev_line, ASM_LINE_BUF_SIZE, "%s = extractvalue %s %s, %d", ev_name, ret_ty_buf, ssa_name, out_emit_idx) mlirlite.block_append_text(pool, builder.CurBlock, ev_line) ev_val: mlirlite.Value* = mlirlite.SSAValue(pool, oo.Value.Ty.Pointee, ev_name) mlirlite.build_store(builder, ev_val, oo.Value) @@ -1381,11 +1343,7 @@ novirtual class CallGenCBuiltin(CallGenBase.CallGenBase): return None - def translate_c_llvmir(self, pool: memhub.MemBuddy*, - builder: mlirlite.IRBuilder*, - mod: mlirlite.LLVMModule*, - cl: ast.Call*, - trans: HT.Translator* = None) -> mlirlite.Value*: + def translate_c_llvmir(self, pool: memhub.MemBuddy*, builder: mlirlite.IRBuilder*, mod: mlirlite.LLVMModule*, cl: ast.Call*, trans: HT.Translator* = None) -> mlirlite.Value*: """c.LLVMIR 内联 LLVM IR:无返回值,直接嵌入原始 IR 文本 不做指令解析,模板文本(c.LInp/c.LOut 替换后)用 block_append_text diff --git a/App/lib/core/Gen/Call/CallGenCall.vp b/App/lib/core/Gen/Call/CallGenCall.vp index 1f75b6c..dfbad71 100644 --- a/App/lib/core/Gen/Call/CallGenCall.vp +++ b/App/lib/core/Gen/Call/CallGenCall.vp @@ -38,17 +38,7 @@ novirtual class CallGenCall(CallGenBase.CallGenBase): # ============================================================ # ============================================================ - def _do_virtual_call(self, pool: memhub.MemBuddy*, - builder: mlirlite.IRBuilder*, - mod: mlirlite.LLVMModule*, - class_name: str, - method_name: str, - self_ptr: mlirlite.Value*, - args_head: mlirlite.Value*, - args_count: int, - found_func: mlirlite.Function*, - ret_ty: mlirlite.LLVMType*, - vtable_base: mlirlite.Value* = None) -> mlirlite.Value*: + def _do_virtual_call(self, pool: memhub.MemBuddy*, builder: mlirlite.IRBuilder*, mod: mlirlite.LLVMModule*, class_name: str, method_name: str, self_ptr: mlirlite.Value*, args_head: mlirlite.Value*, args_count: int, found_func: mlirlite.Function*, ret_ty: mlirlite.LLVMType*, vtable_base: mlirlite.Value* = None) -> mlirlite.Value*: """通过虚表间接调用虚方法,返回 call 结果(void 方法返回 None) vtable_base: 对象头指针(vtable 所在位置,即未调整的 obj_ptr)。 @@ -191,17 +181,7 @@ novirtual class CallGenCall(CallGenBase.CallGenBase): # ============================================================ # ============================================================ - def _call_method_on_ptr(self, pool: memhub.MemBuddy*, - builder: mlirlite.IRBuilder*, - mod: mlirlite.LLVMModule*, - class_name: str, - method_name: str, - self_ptr: mlirlite.Value*, - extra_args: sizet*, - extra_count: int, - trans: HT.Translator*, - node: ast.AST* = None, - is_volatile: int = 0) -> mlirlite.Value*: + def _call_method_on_ptr(self, pool: memhub.MemBuddy*, builder: mlirlite.IRBuilder*, mod: mlirlite.LLVMModule*, class_name: str, method_name: str, self_ptr: mlirlite.Value*, extra_args: sizet*, extra_count: int, trans: HT.Translator*, node: ast.AST* = None, is_volatile: int = 0) -> mlirlite.Value*: """在结构体指针上调用方法,返回 call 结果(void 方法返回 None) node: 触发本次调用的 AST 节点(如 Subscript 下标节点),用于 fatal_error @@ -259,8 +239,7 @@ novirtual class CallGenCall(CallGenBase.CallGenBase): # 生成调用名: {cls_sha1}.{lookup_name}(Hash Namespace 单前缀) mangled2: str = pool.alloc(string.strlen(cls_sha1) + string.strlen(lookup_name) + 2) if mangled2 is not None: - viperlib.snprintf(mangled2, string.strlen(cls_sha1) + string.strlen(lookup_name) + 2, - "%s.%s", cls_sha1, lookup_name) + viperlib.snprintf(mangled2, string.strlen(cls_sha1) + string.strlen(lookup_name) + 2, "%s.%s", cls_sha1, lookup_name) call_name = mangled2 # 确定返回类型(__before_init__ 和 __init__ 返回 void) @@ -329,9 +308,7 @@ novirtual class CallGenCall(CallGenBase.CallGenBase): if cls_sha1 is not None and trans is not None and trans.ModuleSha1 is not None and string.strncmp(cls_sha1, trans.ModuleSha1, 16) == 0: local_lk_cm2: str = pool.alloc(string.strlen(class_name) + string.strlen(method_name) + 2) if local_lk_cm2 is not None: - viperlib.snprintf(local_lk_cm2, - string.strlen(class_name) + string.strlen(method_name) + 2, - "%s.%s", class_name, method_name) + viperlib.snprintf(local_lk_cm2, string.strlen(class_name) + string.strlen(method_name) + 2, "%s.%s", class_name, method_name) local_fn_cm2: mlirlite.Function* = self.find_func_in_module(mod, local_lk_cm2) if local_fn_cm2 is not None: lrt_cm2: mlirlite.LLVMType* = mlirlite.function_get_ret_ty(local_fn_cm2) @@ -441,8 +418,7 @@ novirtual class CallGenCall(CallGenBase.CallGenBase): ppn_f2: mlirlite.Param* = mlirlite.function_get_param_head(found_func) while ppn_f2 is not None: fp_nm_f2: str = mlirlite.param_get_name(ppn_f2) - if fp_nm_f2 is None or (string.strcmp(fp_nm_f2, "%__eh_msg_out__") != 0 - and string.strcmp(fp_nm_f2, "%__eh_code_out__") != 0): + if fp_nm_f2 is None or (string.strcmp(fp_nm_f2, "%__eh_msg_out__") != 0 and string.strcmp(fp_nm_f2, "%__eh_code_out__") != 0): ppcnt_f2 += 1 ppn_f2 = mlirlite.param_get_next(ppn_f2) if ppcnt_f2 > 1: @@ -586,8 +562,7 @@ novirtual class CallGenCall(CallGenBase.CallGenBase): cmop_method_idx = cmop_mi break if cmop_has_vt == 1 and cmop_method_idx >= 0: - return self._do_virtual_call(pool, builder, mod, class_name, method_name, - self_ptr, head, total_count, found_func, call_ret_ty) + return self._do_virtual_call(pool, builder, mod, class_name, method_name, self_ptr, head, total_count, found_func, call_ret_ty) # 防御:返回类型为 i0(0 位整数)时 fail-fast,绝不输出非法 IR。 # 根因已修(gen_done 成功后不再读未初始化的 looked_up_ty,见 L3970); # 此兜底防止未来任何路径产出零值 LLVMType 导致 llc @@ -638,14 +613,7 @@ novirtual class CallGenCall(CallGenBase.CallGenBase): # ============================================================ # ============================================================ - def _translate_method_call(self, pool: memhub.MemBuddy*, - builder: mlirlite.IRBuilder*, - mod: mlirlite.LLVMModule*, - class_name: str, - method_name: str, - obj_ptr: mlirlite.Value*, - cl: ast.Call*, - trans: HT.Translator*) -> mlirlite.Value*: + def _translate_method_call(self, pool: memhub.MemBuddy*, builder: mlirlite.IRBuilder*, mod: mlirlite.LLVMModule*, class_name: str, method_name: str, obj_ptr: mlirlite.Value*, cl: ast.Call*, trans: HT.Translator*) -> mlirlite.Value*: """翻译方法调用,返回 call 结果 Value""" if pool is None or builder is None or class_name is None or method_name is None: return None if obj_ptr is None or cl is None: return None @@ -702,12 +670,7 @@ novirtual class CallGenCall(CallGenBase.CallGenBase): if cm_bare is not None and string.strchr(cm_bare, '[') is None: cm_tpl: ast.ClassDef* = self.Gen.ClassGenGeneric._find_generic_template(cm_bare) if cm_tpl is not None: - self.Gen.TypeGenErr.fatal_error(cl, - f"泛型类 '{cm_bare}' 的方法 '{method_name}' 调用缺少类型实参" - f"(接收者静态类型是裸泛型基类,元素类型未知);" - f"禁止静默按默认 list[int] 特化(元素按 i32 处理会截断指针)," - f"请让该变量的注解/类型带上实参(如 list[ast.AST*])", - "TypeError") + self.Gen.TypeGenErr.fatal_error(cl, f"泛型类 '{cm_bare}' 的方法 '{method_name}' 调用缺少类型实参" f"(接收者静态类型是裸泛型基类,元素类型未知);" f"禁止静默按默认 list[int] 特化(元素按 i32 处理会截断指针)," f"请让该变量的注解/类型带上实参(如 list[ast.AST*])", "TypeError") # 提前获取结构体 entry(用 find_struct_by_type 规避跨模块同名 find_struct 找错) # 用于继承链遍历、SHA1 查找和虚表分派 @@ -849,8 +812,7 @@ novirtual class CallGenCall(CallGenBase.CallGenBase): ml_sp: sizet = string.strlen(sp_anc_sha1) + string.strlen(sp_anc_name) + string.strlen(method_name) + 3 mangled_sp: str = pool.alloc(ml_sp) if mangled_sp is not None: - viperlib.snprintf(mangled_sp, ml_sp, "%s.%s.%s", - sp_anc_sha1, sp_anc_name, method_name) + viperlib.snprintf(mangled_sp, ml_sp, "%s.%s.%s", sp_anc_sha1, sp_anc_name, method_name) call_name = mangled_sp else: # 方法实际定义类(跨模块调用名/返回类型来源;Module.append 定义在 AST) @@ -1059,8 +1021,7 @@ novirtual class CallGenCall(CallGenBase.CallGenBase): ml_anc: sizet = string.strlen(ret_anc_sha1) + string.strlen(ret_anc_name) + string.strlen(method_name) + 3 mangled_anc: str = pool.alloc(ml_anc) if mangled_anc is not None: - viperlib.snprintf(mangled_anc, ml_anc, "%s.%s.%s", - ret_anc_sha1, ret_anc_name, method_name) + viperlib.snprintf(mangled_anc, ml_anc, "%s.%s.%s", ret_anc_sha1, ret_anc_name, method_name) call_name = mangled_anc # 类型名提取的 sha1 已按 "{16hex}." 前缀格式校验(sha1_prefix_len); # 不校验它是否为真实已注册模块 sha1(跨模块 stub 类型名带前缀但 @@ -1344,8 +1305,7 @@ novirtual class CallGenCall(CallGenBase.CallGenBase): ppn_f: mlirlite.Param* = mlirlite.function_get_param_head(found_func) while ppn_f is not None: fp_nm_f: str = mlirlite.param_get_name(ppn_f) - if fp_nm_f is None or (string.strcmp(fp_nm_f, "%__eh_msg_out__") != 0 - and string.strcmp(fp_nm_f, "%__eh_code_out__") != 0): + if fp_nm_f is None or (string.strcmp(fp_nm_f, "%__eh_msg_out__") != 0 and string.strcmp(fp_nm_f, "%__eh_code_out__") != 0): ppcnt_f += 1 ppn_f = mlirlite.param_get_next(ppn_f) if ppcnt_f > 1: @@ -1452,9 +1412,7 @@ novirtual class CallGenCall(CallGenBase.CallGenBase): # 虚分派 self 必须用调整后的 self_arg(多继承 this 调整), # 否则 B.get_b 收到未调整的 AB*,方法体内按 B 布局读字段错位。 # vtable 读取必须用对象头 obj_ptr(调整后 self 头部是父类字段值)。 - return self._do_virtual_call(pool, builder, mod, class_name, method_name, - self_arg, head, total_count, found_func, call_ret_ty, - obj_ptr) + return self._do_virtual_call(pool, builder, mod, class_name, method_name, self_arg, head, total_count, found_func, call_ret_ty, obj_ptr) # 跨模块调用:创建 declare 声明,避免 llc 报 undefined value # 先按 vpi 定义侧形参 coerce 实参(宽度对齐),再建 declare(ABI 通用化) @@ -1477,15 +1435,7 @@ novirtual class CallGenCall(CallGenBase.CallGenBase): # 翻译,绝不生成对 list 方法函数的跨模块调用(list 方法无对应 C 函数)。 # lm_obj 必须是已 load 的 list 对象指针 Ptr(list-struct)。 # ============================================================ - def _translate_list_builtin_call(self, pool: memhub.MemBuddy*, - builder: mlirlite.IRBuilder*, - mod: mlirlite.LLVMModule*, - cl: ast.Call*, - lm_name: str, - lm_obj: mlirlite.Value*, - cargs: list[ast.AST*]*, - can: sizet, - trans: HT.Translator*) -> mlirlite.Value*: + def _translate_list_builtin_call(self, pool: memhub.MemBuddy*, builder: mlirlite.IRBuilder*, mod: mlirlite.LLVMModule*, cl: ast.Call*, lm_name: str, lm_obj: mlirlite.Value*, cargs: list[ast.AST*]*, can: sizet, trans: HT.Translator*) -> mlirlite.Value*: """翻译 list 内置方法调用,返回 call 结果 Value(void 方法返回 None)""" if pool is None or builder is None or lm_obj is None or lm_name is None: return None i64_ty: mlirlite.LLVMType* = mlirlite.Int64(pool) @@ -1668,12 +1618,7 @@ novirtual class CallGenCall(CallGenBase.CallGenBase): # ============================================================ # ============================================================ - def _translate_super_call(self, pool: memhub.MemBuddy*, - builder: mlirlite.IRBuilder*, - mod: mlirlite.LLVMModule*, - cl: ast.Call*, - method_name: str, - trans: HT.Translator*) -> mlirlite.Value*: + def _translate_super_call(self, pool: memhub.MemBuddy*, builder: mlirlite.IRBuilder*, mod: mlirlite.LLVMModule*, cl: ast.Call*, method_name: str, trans: HT.Translator*) -> mlirlite.Value*: """super().method(args) → 父类方法静态调用,返回 call 结果 Value""" if pool is None or builder is None or cl is None or method_name is None: return None if trans is None: return None @@ -1708,8 +1653,7 @@ novirtual class CallGenCall(CallGenBase.CallGenBase): if anc is None: err_sp: str = pool.alloc(256) if err_sp is not None: - viperlib.snprintf(err_sp, 256, "super(): 当前类 %s 的父类链未定义方法 %s", - cur_class, method_name) + viperlib.snprintf(err_sp, 256, "super(): 当前类 %s 的父类链未定义方法 %s", cur_class, method_name) self.Gen.TypeGenErr.fatal_error(cl, err_sp, "TypeError") self.Gen.TypeGenErr.fatal_error(cl, "super(): 父类链未定义方法", "TypeError") return None @@ -1877,8 +1821,7 @@ novirtual class CallGenCall(CallGenBase.CallGenBase): # cand_name(如 Combined(BaseA, BaseB):MRO 含 BaseA 与 BaseB ⇒ 二者是兄弟)。 # 只有满足它才允许把 self.() 绑到同名的兄弟类方法上。 # ============================================================ - def _mixin_sibling_same_composite(self, pool: memhub.MemBuddy*, - class_name: str, cand_name: str) -> int: + def _mixin_sibling_same_composite(self, pool: memhub.MemBuddy*, class_name: str, cand_name: str) -> int: """两类是否同处某个已注册组合类的 MRO(1=是 / 0=否)""" if class_name is None or cand_name is None or pool is None: return 0 if self.Gen is None: return 0 @@ -1909,9 +1852,7 @@ novirtual class CallGenCall(CallGenBase.CallGenBase): # 的 padding 规则一致)。field_index 是 FieldEntry.Index(OOP 类 __vtable__ 占 0)。 # 供多继承 this 调整(字节偏移法)计算 delta。 # ============================================================ - def _field_byte_offset(self, pool: memhub.MemBuddy*, - entry: GenTypes.StructEntry*, - field_index: int) -> int: + def _field_byte_offset(self, pool: memhub.MemBuddy*, entry: GenTypes.StructEntry*, field_index: int) -> int: """计算字段在结构体中的字节偏移(含对齐 padding),无法计算返回 0""" if pool is None or entry is None or entry.Ty is None or field_index < 0: return 0 match entry.Ty: @@ -1949,8 +1890,7 @@ novirtual class CallGenCall(CallGenBase.CallGenBase): # 函数参数名在 LLVM IR 中带 % 前缀(如 "%a"),关键字参数名无前缀(如 "a") # 跳过 % 前缀后逐字符比较 # ============================================================ - def _kwarg_name_matches(self, kw_arg: str, - param_name: str) -> int: + def _kwarg_name_matches(self, kw_arg: str, param_name: str) -> int: """检查关键字参数名 kw_arg 是否匹配参数名 param_name(跳过 % 前缀)""" if kw_arg is None or param_name is None: return 0 start: sizet = 0 diff --git a/App/lib/core/Gen/Call/CallGenCtor.vp b/App/lib/core/Gen/Call/CallGenCtor.vp index 26c71e8..37ad015 100644 --- a/App/lib/core/Gen/Call/CallGenCtor.vp +++ b/App/lib/core/Gen/Call/CallGenCtor.vp @@ -28,14 +28,7 @@ novirtual class CallGenCtor(CallGenBase.CallGenBase): # 遍历所有字段,对有默认值的字段翻译并 store # 显式参数(位置/关键字)后续会覆盖默认值 # ============================================================ - def _apply_struct_defaults(self, pool: memhub.MemBuddy*, - builder: mlirlite.IRBuilder*, - mod: mlirlite.LLVMModule*, - struct_ty: mlirlite.LLVMType*, - class_name: str, - tmp: mlirlite.Value*, - trans: HT.Translator*, - is_volatile: int = 0): + def _apply_struct_defaults(self, pool: memhub.MemBuddy*, builder: mlirlite.IRBuilder*, mod: mlirlite.LLVMModule*, struct_ty: mlirlite.LLVMType*, class_name: str, tmp: mlirlite.Value*, trans: HT.Translator*, is_volatile: int = 0): """应用结构体字段的默认值 is_volatile=1:`volatile S(...)` 构造——默认值写入也带 LLVM volatile @@ -96,15 +89,7 @@ novirtual class CallGenCtor(CallGenBase.CallGenBase): # ============================================================ # ============================================================ - def _translate_struct_ctor(self, pool: memhub.MemBuddy*, - builder: mlirlite.IRBuilder*, - mod: mlirlite.LLVMModule*, - struct_ty: mlirlite.LLVMType*, - class_name: str, - cargs: list[ast.AST*]*, - can: sizet, - trans: HT.Translator*, - is_volatile: int = 0) -> mlirlite.Value*: + def _translate_struct_ctor(self, pool: memhub.MemBuddy*, builder: mlirlite.IRBuilder*, mod: mlirlite.LLVMModule*, struct_ty: mlirlite.LLVMType*, class_name: str, cargs: list[ast.AST*]*, can: sizet, trans: HT.Translator*, is_volatile: int = 0) -> mlirlite.Value*: """结构体构造函数:按字段顺序 store 参数值,返回结构体值 OOP 结构体:alloca → call __before_init__(ptr) → call __init__(ptr, args) 或 store 参数 → load @@ -311,16 +296,7 @@ novirtual class CallGenCtor(CallGenBase.CallGenBase): # ============================================================ # ============================================================ - def _translate_renum_construct(self, pool: memhub.MemBuddy*, - builder: mlirlite.IRBuilder*, - mod: mlirlite.LLVMModule*, - class_name: str, - variant_name: str, - tag_value: int, - cargs: list[ast.AST*]*, - can: sizet, - trans: HT.Translator*, - is_volatile: int = 0) -> mlirlite.Value*: + def _translate_renum_construct(self, pool: memhub.MemBuddy*, builder: mlirlite.IRBuilder*, mod: mlirlite.LLVMModule*, class_name: str, variant_name: str, tag_value: int, cargs: list[ast.AST*]*, can: sizet, trans: HT.Translator*, is_volatile: int = 0) -> mlirlite.Value*: """构造 REnum 变体实例,返回指向 alloca 的指针 class_name: REnum 类名(如 "LLVMType") @@ -363,8 +339,7 @@ novirtual class CallGenCtor(CallGenBase.CallGenBase): if tag_field is not None and tag_field.Ty is not None: tag_field_ty = tag_field.Ty tag_name_buf: str = pool.alloc(32) if tag_name_buf is not None: viperlib.snprintf(tag_name_buf, 32, "%d", tag_value) - tag_const: mlirlite.Value* = mlirlite.ConstInt(pool, tag_field_ty, tag_value, - tag_name_buf if tag_name_buf is not None else "0") + tag_const: mlirlite.Value* = mlirlite.ConstInt(pool, tag_field_ty, tag_value, tag_name_buf if tag_name_buf is not None else "0") tag_ptr: mlirlite.Value* = mlirlite.build_gep_struct(builder, renum_ty, tag_field_ty, tmp, 0) if tag_ptr is not None: mlirlite.build_store(builder, tag_const, tag_ptr, is_volatile) @@ -388,9 +363,7 @@ novirtual class CallGenCtor(CallGenBase.CallGenBase): # 这是编译器自身的表示转换(tagged union 打包),不是用户代码的隐式转换: # 必须显式 ptrtoint 后存入,读取侧按成员类型 bitcast 槽位地址再 load(对称)。 # 禁止隐式转换后此处不能再依赖 coerce_to_type 的静默 ptrtoint。 - if (self.Gen.ExprGenBase.is_ptr_type(arg_val.Ty) != 0 - and self.Gen.ExprGenBase.is_ptr_type(pfe.Ty) == 0 - and self.Gen.ExprGenBase.get_llvm_type_bits(pfe.Ty) != 0): + if (self.Gen.ExprGenBase.is_ptr_type(arg_val.Ty) != 0 and self.Gen.ExprGenBase.is_ptr_type(pfe.Ty) == 0 and self.Gen.ExprGenBase.get_llvm_type_bits(pfe.Ty) != 0): casted_arg: mlirlite.Value* = mlirlite.build_ptrtoint(builder, arg_val, pfe.Ty) if casted_arg is None: continue arg_val = casted_arg @@ -411,17 +384,7 @@ novirtual class CallGenCtor(CallGenBase.CallGenBase): # ============================================================ # ============================================================ - def _translate_struct_ctor_kw(self, pool: memhub.MemBuddy*, - builder: mlirlite.IRBuilder*, - mod: mlirlite.LLVMModule*, - struct_ty: mlirlite.LLVMType*, - class_name: str, - cargs: list[ast.AST*]*, - can: sizet, - keywords: list[ast.AST*]*, - kw_count: sizet, - trans: HT.Translator*, - is_volatile: int = 0) -> mlirlite.Value*: + def _translate_struct_ctor_kw(self, pool: memhub.MemBuddy*, builder: mlirlite.IRBuilder*, mod: mlirlite.LLVMModule*, struct_ty: mlirlite.LLVMType*, class_name: str, cargs: list[ast.AST*]*, can: sizet, keywords: list[ast.AST*]*, kw_count: sizet, trans: HT.Translator*, is_volatile: int = 0) -> mlirlite.Value*: """结构体构造函数(关键字参数版本) is_volatile=1:`volatile S(x=1)` 构造——同 _translate_struct_ctor, @@ -467,8 +430,7 @@ novirtual class CallGenCtor(CallGenBase.CallGenBase): kw_entry.HasInit = 1 if is_oop != 0: - self.Gen.CallGenCall._call_method_on_ptr(pool, builder, mod, class_name, - "__before_init__", tmp, None, 0, trans, None, is_volatile) + self.Gen.CallGenCall._call_method_on_ptr(pool, builder, mod, class_name, "__before_init__", tmp, None, 0, trans, None, is_volatile) else: # 普通结构体:store zeroinitializer + 应用默认值 zero: mlirlite.Value* = mlirlite.ConstZero(pool, struct_ty) @@ -615,12 +577,7 @@ novirtual class CallGenCtor(CallGenBase.CallGenBase): # ============================================================ # ============================================================ - def _translate_t_type_cast(self, pool: memhub.MemBuddy*, - builder: mlirlite.IRBuilder*, - val: mlirlite.Value*, - target_ty: mlirlite.LLVMType*, - src_node: ast.AST* = None, - trans: HT.Translator* = None) -> mlirlite.Value*: + def _translate_t_type_cast(self, pool: memhub.MemBuddy*, builder: mlirlite.IRBuilder*, val: mlirlite.Value*, target_ty: mlirlite.LLVMType*, src_node: ast.AST* = None, trans: HT.Translator* = None) -> mlirlite.Value*: """类型转换:根据参数类型和目标类型选择转换方式 整数 → 整数拓宽:拓宽方向由**源**的符号性决定(与 coerce_to_type 的 @@ -690,9 +647,7 @@ novirtual 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*, - slice_node: ast.AST*, - from_imports: str = None) -> list[str]*: + def _extract_type_args_from_slice(self, pool: memhub.MemBuddy*, slice_node: ast.AST*, from_imports: str = None) -> list[str]*: """从 Subscript.slice 提取类型实参名列表 list[int] -> ["int"] @@ -748,9 +703,7 @@ novirtual class CallGenCtor(CallGenBase.CallGenBase): # 非类名(typedef/内置标量/裸指针标记 CPtr/泛型形参,名域即自身、无 `X*` # 归一形)原样返回,不引入新分裂。 # ============================================================ - def _ptr_layer_type_arg(self, pool: memhub.MemBuddy*, - cls_nm: str, ptr_level: int, - from_imports: str) -> str: + def _ptr_layer_type_arg(self, pool: memhub.MemBuddy*, cls_nm: str, ptr_level: int, from_imports: str) -> str: """注解类名 → 与注解侧同票名的类型实参文本(按 PtrLevel 补 `*`,非类名原样)""" if cls_nm is None: return None res_pl: str = self.Gen.TypeGenResolve._norm_type_arg_name(pool, cls_nm, from_imports) @@ -768,10 +721,7 @@ novirtual class CallGenCtor(CallGenBase.CallGenBase): return res_pl # ============================================================ - def _infer_generic_ctor_type_arg(self, pool: memhub.MemBuddy*, - arg_node: ast.AST*, - class_name: str, - trans: HT.Translator*) -> str: + def _infer_generic_ctor_type_arg(self, pool: memhub.MemBuddy*, arg_node: ast.AST*, class_name: str, trans: HT.Translator*) -> str: """从构造实参 AST 推断泛型类型实参名 裸名泛型类构造(Box(42) → Box[int])需要从实参推断类型实参。 @@ -803,8 +753,7 @@ novirtual class CallGenCtor(CallGenBase.CallGenBase): # 与泛型函数路径 ClassGenGeneric._infer_generic_func_type_arg 同口径。 fk_c: int = cl_f.func.kind() if (fk_c == ast.ASTKind.Name or fk_c == ast.ASTKind.Attribute) and trans is not None: - cty_c: mlirlite.LLVMType* = self.Gen.TypeGenResolve.resolve_annotation_type( - pool, cl_f.func, trans._imported_modules, trans._from_imports, trans, 0) + cty_c: mlirlite.LLVMType* = self.Gen.TypeGenResolve.resolve_annotation_type(pool, cl_f.func, trans._imported_modules, trans._from_imports, trans, 0) if cty_c is not None: # 符号性从被调名源码文本取(LLVM 层 iN/uN 同形),复用注解侧 # 唯一真源 spec_sign_of_annot(白名单 + CTypedef 链回退): @@ -853,8 +802,7 @@ novirtual class CallGenCtor(CallGenBase.CallGenBase): return self._ptr_layer_type_arg(pool, cn_at_i, pl_at_i, fi_at_i) return None - def _annotation_refers_type_param(self, node: ast.AST*, - tp_name: str) -> int: + def _annotation_refers_type_param(self, node: ast.AST*, tp_name: str) -> int: """注解是否引用类型形参 tp_name(1=是 / 0=否) 只认「T」与「T | X」两种形态(T 直接充当该形参的类型)。 @@ -900,8 +848,7 @@ novirtual class CallGenCtor(CallGenBase.CallGenBase): return fargs.args return None - def _find_ctor_type_param_param_index(self, class_name: str, - tp_name: str) -> int: + def _find_ctor_type_param_param_index(self, class_name: str, tp_name: str) -> int: """泛型类模板 __init__ 中注解为类型形参 tp_name 的形参序号(含 self,0 起) 找不到返回 -1。位置实参下标 = 本返回值 - 1(形参 0 是 self)。 @@ -923,8 +870,7 @@ novirtual class CallGenCtor(CallGenBase.CallGenBase): if self._annotation_refers_type_param(ag.annotation, tp_name) != 0: return int(pi) return -1 - def _find_ctor_type_param_arg_index(self, class_name: str, - tp_name: str) -> int: + def _find_ctor_type_param_arg_index(self, class_name: str, tp_name: str) -> int: """查找泛型类模板 __init__ 中注解为类型形参 tp_name 的形参对应的位置实参下标 返回「位置实参下标」(0 = 第 1 个位置实参;形参 0 是 self,故等于形参 @@ -937,8 +883,7 @@ novirtual class CallGenCtor(CallGenBase.CallGenBase): if pi_arg < 0: return -1 return pi_arg - 1 - def _ctor_init_arg_slot_by_name(self, class_name: str, - kw_name: str) -> int: + def _ctor_init_arg_slot_by_name(self, class_name: str, kw_name: str) -> int: """按形参名把关键字实参定位到非 self 形参序号(= 位置实参槽位) 返回 >= 0 的槽位下标;模板/__init__ 缺失或无形参名 kw_name → -1。 @@ -961,11 +906,7 @@ novirtual class CallGenCtor(CallGenBase.CallGenBase): if ag_sb.arg is not None and string.strcmp(ag_sb.arg, kw_name) == 0: return int(pi_sb) - 1 return -1 - def _find_ctor_type_param_kw_arg_index(self, class_name: str, - tp_name: str, - keywords: list[ast.AST*]*, - kw_count: sizet, - pos_count: int) -> int: + def _find_ctor_type_param_kw_arg_index(self, class_name: str, tp_name: str, keywords: list[ast.AST*]*, kw_count: sizet, pos_count: int) -> int: """仅关键字实参的泛型构造:类型形参 tp_name 对应的关键字实参下标 返回 keywords 列表下标(0 = 第 1 个关键字实参);找不到返回 -1。 @@ -997,11 +938,7 @@ novirtual class CallGenCtor(CallGenBase.CallGenBase): if string.strcmp(kw_tp.arg, ag_kw.arg) == 0: return int(ki_kw) return -1 - def _infer_ctor_type_args_from_ctx(self, pool: memhub.MemBuddy*, - trans: HT.Translator*, - class_name: str, - tp_count: int, - cl: ast.Call*) -> list[str]*: + def _infer_ctor_type_args_from_ctx(self, pool: memhub.MemBuddy*, trans: HT.Translator*, class_name: str, tp_count: int, cl: ast.Call*) -> list[str]*: """从「赋值目标注解 / 函数返回注解」上下文取泛型构造的类型实参 场景:`s: Stack[int] = Stack()`(__init__ 无参 ⇒ 实参推断不到 T)、 @@ -1047,13 +984,7 @@ novirtual class CallGenCtor(CallGenBase.CallGenBase): if len(type_args_ctx) != sizet(tp_count): return None return type_args_ctx - def _translate_generic_ctor_call(self, pool: memhub.MemBuddy*, - builder: mlirlite.IRBuilder*, - mod: mlirlite.LLVMModule*, - spec_name: str, - cl: ast.Call*, - trans: HT.Translator*, - tmpl_name: str = None) -> mlirlite.Value*: + def _translate_generic_ctor_call(self, pool: memhub.MemBuddy*, builder: mlirlite.IRBuilder*, mod: mlirlite.LLVMModule*, spec_name: str, cl: ast.Call*, trans: HT.Translator*, tmpl_name: str = None) -> mlirlite.Value*: """泛型类构造调用: list[str](pool, 8) → __new__ + __before_init__ + __init__""" if pool is None or builder is None or mod is None or spec_name is None or cl is None: return None diff --git a/App/lib/core/Gen/Call/CallGenDispatch.vp b/App/lib/core/Gen/Call/CallGenDispatch.vp index 3949c68..043780c 100644 --- a/App/lib/core/Gen/Call/CallGenDispatch.vp +++ b/App/lib/core/Gen/Call/CallGenDispatch.vp @@ -35,17 +35,7 @@ novirtual class CallGenDispatch(CallGenBase.CallGenBase): # 必须在普通函数/类构造分派之前拦截:泛型函数模板在定义处不发射普通函数, # 走主路径会"裸名调用未定义"。 # ============================================================ - def _tc_h0_generic_func(self, pool: memhub.MemBuddy*, - builder: mlirlite.IRBuilder*, - mod: mlirlite.LLVMModule*, - cl: ast.Call*, - funcs_ptr: t.CPtr, - func_count: int, - trans: HT.Translator*, - func_name: str, - cargs: list[ast.AST*]*, - can: sizet, - hit_box: t.CPtr = None) -> mlirlite.Value*: + def _tc_h0_generic_func(self, pool: memhub.MemBuddy*, builder: mlirlite.IRBuilder*, mod: mlirlite.LLVMModule*, cl: ast.Call*, funcs_ptr: t.CPtr, func_count: int, trans: HT.Translator*, func_name: str, cargs: list[ast.AST*]*, can: sizet, hit_box: t.CPtr = None) -> mlirlite.Value*: if cl is None or trans is None: return None if self.Gen.ClassGenGeneric.GenericFuncKeys is None: return None if cl.func is None: return None @@ -104,9 +94,7 @@ novirtual class CallGenDispatch(CallGenBase.CallGenBase): if explicit_slice is not None: type_args = self.Gen.CallGenCtor._extract_type_args_from_slice(pool, explicit_slice, trans._from_imports) if type_args is None or len(type_args) != tp_count: - self.Gen.TypeGenErr.fatal_error(cl, - f"泛型函数 '{tpl_name}' 显式类型实参个数不匹配(需要 {tp_count}):请写 {tpl_name}[类型1, 类型2](...)", - "TypeError") + self.Gen.TypeGenErr.fatal_error(cl, f"泛型函数 '{tpl_name}' 显式类型实参个数不匹配(需要 {tp_count}):请写 {tpl_name}[类型1, 类型2](...)", "TypeError") return None else: # 隐式推断:按模板签名的形参位对齐(形参注解恰为 T 的那一位实参) @@ -127,10 +115,7 @@ novirtual class CallGenDispatch(CallGenBase.CallGenBase): if kwn is not None and kwn.value is not None: ta = self.Gen.ClassGenGeneric._infer_generic_func_type_arg(pool, kwn.value, tpl_name, trans) if ta is None and ctx_args is not None and sizet(tpi) < len(ctx_args): ta = ctx_args.get(tpi) if ta is None: - self.Gen.TypeGenErr.fatal_error(cl, - f"无法从实参推断泛型函数 '{tpl_name}' 的第 {tpi + 1} 个类型实参(类型形参 {tp_name});" - f"禁止静默默认 int。请显式标注如 {tpl_name}[类型](...) 或为对应实参标注类型", - "TypeError") + self.Gen.TypeGenErr.fatal_error(cl, f"无法从实参推断泛型函数 '{tpl_name}' 的第 {tpi + 1} 个类型实参(类型形参 {tp_name});" f"禁止静默默认 int。请显式标注如 {tpl_name}[类型](...) 或为对应实参标注类型", "TypeError") return None type_args.append(ta) # ---- 单态化 ---- @@ -141,8 +126,7 @@ novirtual class CallGenDispatch(CallGenBase.CallGenBase): # ---- 发射调用 ---- return self._emit_generic_func_call(pool, builder, mod, trans, cl, spec_name, cargs, can, hit_box) - def _generic_func_key(self, pool: memhub.MemBuddy*, - sha1: str, name: str) -> str: + def _generic_func_key(self, pool: memhub.MemBuddy*, sha1: str, name: str) -> str: """构造泛型函数模板键 "{sha1}.{name}"(新缓冲区)""" if sha1 is None or name is None: return None klen: sizet = string.strlen(sha1) + string.strlen(name) + 2 @@ -151,9 +135,7 @@ novirtual class CallGenDispatch(CallGenBase.CallGenBase): viperlib.snprintf(kbuf, klen, "%s.%s", sha1, name) return kbuf - def _generic_func_kw_arg_index(self, template_fd: ast.FunctionDef*, - slot: int, keywords: list[ast.AST*]*, - pos_count: int) -> int: + def _generic_func_kw_arg_index(self, template_fd: ast.FunctionDef*, slot: int, keywords: list[ast.AST*]*, pos_count: int) -> int: """类型形参对应的形参槽位由关键字实参传入时,返回 keywords 下标;否则 -1 slot 已被位置实参占用(slot < pos_count)时返回 -1(位置优先)。 @@ -177,23 +159,14 @@ novirtual class CallGenDispatch(CallGenBase.CallGenBase): if string.strcmp(kw.arg, ag.arg) == 0: return int(ki) return -1 - def _emit_generic_func_call(self, pool: memhub.MemBuddy*, - builder: mlirlite.IRBuilder*, - mod: mlirlite.LLVMModule*, - trans: HT.Translator*, - cl: ast.Call*, - spec_name: str, - cargs: list[ast.AST*]*, - can: sizet, - hit_box: t.CPtr = None) -> mlirlite.Value*: + def _emit_generic_func_call(self, pool: memhub.MemBuddy*, builder: mlirlite.IRBuilder*, mod: mlirlite.LLVMModule*, trans: HT.Translator*, cl: ast.Call*, spec_name: str, cargs: list[ast.AST*]*, can: sizet, hit_box: t.CPtr = None) -> mlirlite.Value*: """发射对特化函数的调用(按特化 define/declare 的形参类型 coerce 实参) 泛型函数调用只支持位置实参(关键字实参/默认参数缺口 fail-fast,不静默)。 """ func: mlirlite.Function* = self.Gen.CallGenBase.find_func_in_module(mod, spec_name) if func is None: - self.Gen.TypeGenErr.fatal_error(cl, - f"泛型函数特化符号未在当前模块注册: {spec_name}", "InternalCompilerError") + self.Gen.TypeGenErr.fatal_error(cl, f"泛型函数特化符号未在当前模块注册: {spec_name}", "InternalCompilerError") return None kw: list[ast.AST*]* = cl.keywords if kw is not None and len(kw) > 0: @@ -206,8 +179,7 @@ novirtual class CallGenDispatch(CallGenBase.CallGenBase): param_count += 1 pp = mlirlite.param_get_next(pp) if int(can) < param_count: - self.Gen.TypeGenErr.fatal_error(cl, - "泛型函数调用实参个数少于形参个数(默认参数暂不支持),请补齐实参", "TypeError") + self.Gen.TypeGenErr.fatal_error(cl, "泛型函数调用实参个数少于形参个数(默认参数暂不支持),请补齐实参", "TypeError") return None ret_ty: mlirlite.LLVMType* = mlirlite.function_get_ret_ty(func) head: mlirlite.Value* = None @@ -233,17 +205,7 @@ novirtual class CallGenDispatch(CallGenBase.CallGenBase): # `call i32 @(i32 7)`(空名字)这种非法 IR。这里用查找时同一符号名。 return mlirlite.build_call(builder, spec_name, head, int(can), ret_ty, 0) - def _tc_h1_super_ctraits(self, pool: memhub.MemBuddy*, - builder: mlirlite.IRBuilder*, - mod: mlirlite.LLVMModule*, - cl: ast.Call*, - funcs_ptr: t.CPtr, - func_count: int, - trans: HT.Translator*, - func_name: str, - cargs: list[ast.AST*]*, - can: sizet, - hit_box: t.CPtr = None) -> mlirlite.Value*: + def _tc_h1_super_ctraits(self, pool: memhub.MemBuddy*, builder: mlirlite.IRBuilder*, mod: mlirlite.LLVMModule*, cl: ast.Call*, funcs_ptr: t.CPtr, func_count: int, trans: HT.Translator*, func_name: str, cargs: list[ast.AST*]*, can: sizet, hit_box: t.CPtr = None) -> mlirlite.Value*: """super()/ctraits 编译期检测(未命中返回 None) hit_box: 命中标志字节([0]=1 表示被本 helper 拦截处理)。 @@ -285,17 +247,7 @@ novirtual class CallGenDispatch(CallGenBase.CallGenBase): return mlirlite.const_int32(pool, 0) return None - def _tc_h2_c_special(self, pool: memhub.MemBuddy*, - builder: mlirlite.IRBuilder*, - mod: mlirlite.LLVMModule*, - cl: ast.Call*, - funcs_ptr: t.CPtr, - func_count: int, - trans: HT.Translator*, - func_name: str, - cargs: list[ast.AST*]*, - can: sizet, - hit_box: t.CPtr = None) -> mlirlite.Value*: + def _tc_h2_c_special(self, pool: memhub.MemBuddy*, builder: mlirlite.IRBuilder*, mod: mlirlite.LLVMModule*, cl: ast.Call*, funcs_ptr: t.CPtr, func_count: int, trans: HT.Translator*, func_name: str, cargs: list[ast.AST*]*, can: sizet, hit_box: t.CPtr = None) -> mlirlite.Value*: """c.Deref/Asm/LLVMIR 等特殊调用(未命中返回 None) hit_box: 命中标记(t.CPtr,[0]=1 表示已识别为 c.* 特殊调用)。 @@ -390,16 +342,7 @@ novirtual class CallGenDispatch(CallGenBase.CallGenBase): return self.Gen.AsyncGen.translate_coro_gather(builder, pool, mod, cl, trans) return None - def _tc_h3_stdarg_cast(self, pool: memhub.MemBuddy*, - builder: mlirlite.IRBuilder*, - mod: mlirlite.LLVMModule*, - cl: ast.Call*, - funcs_ptr: t.CPtr, - func_count: int, - trans: HT.Translator*, - func_name: str, - cargs: list[ast.AST*]*, - can: sizet) -> mlirlite.Value*: + def _tc_h3_stdarg_cast(self, pool: memhub.MemBuddy*, builder: mlirlite.IRBuilder*, mod: mlirlite.LLVMModule*, cl: ast.Call*, funcs_ptr: t.CPtr, func_count: int, trans: HT.Translator*, func_name: str, cargs: list[ast.AST*]*, can: sizet) -> mlirlite.Value*: """stdarg 糖 + str/int/bool 内置强转(未命中返回 None)""" # stdarg 糖函数处理: va_arg / arg / va_start / va_end # 这些函数在 stdarg.vp 中声明为 pass 体,由编译器在翻译期处理: @@ -411,17 +354,13 @@ novirtual class CallGenDispatch(CallGenBase.CallGenBase): # ============================================================ if func_name is not None and trans is not None: if string.strcmp(func_name, "va_arg") == 0: - return self.Gen.CallGenVa._translate_va_arg_sugar(pool, builder, mod, cl, cargs, can, - funcs_ptr, func_count, trans) + return self.Gen.CallGenVa._translate_va_arg_sugar(pool, builder, mod, cl, cargs, can, funcs_ptr, func_count, trans) elif string.strcmp(func_name, "arg") == 0: - return self.Gen.CallGenVa._translate_arg_sugar(pool, builder, mod, cl, cargs, can, - funcs_ptr, func_count, trans) + return self.Gen.CallGenVa._translate_arg_sugar(pool, builder, mod, cl, cargs, can, funcs_ptr, func_count, trans) elif string.strcmp(func_name, "va_start") == 0: - return self.Gen.CallGenVa._translate_va_start_sugar(pool, builder, mod, cargs, can, - funcs_ptr, func_count, trans) + return self.Gen.CallGenVa._translate_va_start_sugar(pool, builder, mod, cargs, can, funcs_ptr, func_count, trans) elif string.strcmp(func_name, "va_end") == 0: - return self.Gen.CallGenVa._translate_va_end_sugar(pool, builder, mod, cargs, can, - funcs_ptr, func_count, trans) + return self.Gen.CallGenVa._translate_va_end_sugar(pool, builder, mod, cargs, can, funcs_ptr, func_count, trans) # 内置强转函数: str(x)/bytes(x) → i8*, int(x) → i32 # 等价于 (str)(x) / (int32)(x) @@ -477,16 +416,7 @@ novirtual class CallGenDispatch(CallGenBase.CallGenBase): return None return None - def _tc_h4_type_casts(self, pool: memhub.MemBuddy*, - builder: mlirlite.IRBuilder*, - mod: mlirlite.LLVMModule*, - cl: ast.Call*, - funcs_ptr: t.CPtr, - func_count: int, - trans: HT.Translator*, - func_name: str, - cargs: list[ast.AST*]*, - can: sizet) -> mlirlite.Value*: + def _tc_h4_type_casts(self, pool: memhub.MemBuddy*, builder: mlirlite.IRBuilder*, mod: mlirlite.LLVMModule*, cl: ast.Call*, funcs_ptr: t.CPtr, func_count: int, trans: HT.Translator*, func_name: str, cargs: list[ast.AST*]*, can: sizet) -> mlirlite.Value*: """t.XXX / typedef 类型转换(未命中返回 None)""" # 检测 t.XXX 类型转换: uint64(ptr), t.CPtr(val), int(val) 等 # 当 func 是 t.XXX 形式且 XXX 是已知类型名时,当作类型转换处理(而非函数调用) @@ -704,16 +634,7 @@ novirtual class CallGenDispatch(CallGenBase.CallGenBase): return None - def _tc_h5_sizeof_len_isinst(self, pool: memhub.MemBuddy*, - builder: mlirlite.IRBuilder*, - mod: mlirlite.LLVMModule*, - cl: ast.Call*, - funcs_ptr: t.CPtr, - func_count: int, - trans: HT.Translator*, - func_name: str, - cargs: list[ast.AST*]*, - can: sizet) -> mlirlite.Value*: + def _tc_h5_sizeof_len_isinst(self, pool: memhub.MemBuddy*, builder: mlirlite.IRBuilder*, mod: mlirlite.LLVMModule*, cl: ast.Call*, funcs_ptr: t.CPtr, func_count: int, trans: HT.Translator*, func_name: str, cargs: list[ast.AST*]*, can: sizet) -> mlirlite.Value*: """__sizeof__/len/isinstance 内置(未命中返回 None)""" # 检测 ClassName.__sizeof__() — 返回结构体大小常量(i64) # __sizeof__ 是内置方法,不走跨模块调用路径 @@ -814,9 +735,7 @@ novirtual class CallGenDispatch(CallGenBase.CallGenBase): # MyInt 来自 from t import CInt as MyInt),不传则别名链解析失败 # → get_type_size_bytes 返回 0 → 落到"回退 2"把 Name 当值翻译 # → NameError: 未定义名称 'MyWord'(T8 根因)。 - dyn_sz_c: int = self.Gen.TypeGenResolve.get_type_size_bytes(pool, sz_cls_name, - trans._imported_modules if trans is not None else None, - trans._from_imports if trans is not None else None) + dyn_sz_c: int = self.Gen.TypeGenResolve.get_type_size_bytes(pool, sz_cls_name, trans._imported_modules if trans is not None else None, trans._from_imports if trans is not None else None) if dyn_sz_c > 0: return mlirlite.const_int64(pool, dyn_sz_c) # 内置类型 sizeof(int=4, str/bytes=8 指针, double=8 等) sz_builtin: int = -1 @@ -1096,17 +1015,7 @@ novirtual class CallGenDispatch(CallGenBase.CallGenBase): return None - def _tc_h6_method_dispatch(self, pool: memhub.MemBuddy*, - builder: mlirlite.IRBuilder*, - mod: mlirlite.LLVMModule*, - cl: ast.Call*, - funcs_ptr: t.CPtr, - func_count: int, - trans: HT.Translator*, - func_name: str, - cargs: list[ast.AST*]*, - can: sizet, - hit_box: t.CPtr = None) -> mlirlite.Value*: + def _tc_h6_method_dispatch(self, pool: memhub.MemBuddy*, builder: mlirlite.IRBuilder*, mod: mlirlite.LLVMModule*, cl: ast.Call*, funcs_ptr: t.CPtr, func_count: int, trans: HT.Translator*, func_name: str, cargs: list[ast.AST*]*, can: sizet, hit_box: t.CPtr = None) -> mlirlite.Value*: """静态类/方法调用/表达式接收者/self.field/list 内置(未命中返回 None) hit_box: 命中标记(t.CPtr,[0]=1 表示已识别为方法调用路径)。 @@ -1257,9 +1166,7 @@ novirtual class CallGenDispatch(CallGenBase.CallGenBase): # fail-fast:已判定为 REnum(判据命中),双指针解一层 load 却拿不到 # 值——绝不静默跳过:跳过会让 .kind() 掉进通用调用路径、返回类型落空, # 报错点漂到几百行外的赋值处(如 CallGenLib.vp:355)。 - self.Gen.TypeGenErr.fatal_error(cl, - f"REnum.kind() 翻译失败:接收者已判定为 REnum(变体表/__tag 判据命中)," - f"但接收者指针解一层 load 失败(rk_load={rk_load})", "TypeError") + self.Gen.TypeGenErr.fatal_error(cl, f"REnum.kind() 翻译失败:接收者已判定为 REnum(变体表/__tag 判据命中)," f"但接收者指针解一层 load 失败(rk_load={rk_load})", "TypeError") if hit_box is not None: hit_box[0] = 1 # 第 2 层:按 __tag 的**字段声明类型**取址并 load,不再硬编码 i32。 # 宽度口径交给赋值侧的隐式转换规则(coerce_to_type):整型↔整型 diff --git a/App/lib/core/Gen/Call/CallGenFd.vp b/App/lib/core/Gen/Call/CallGenFd.vp index e21d2b8..5d1f607 100644 --- a/App/lib/core/Gen/Call/CallGenFd.vp +++ b/App/lib/core/Gen/Call/CallGenFd.vp @@ -17,13 +17,7 @@ from . import CallGenBase # ============================================================ novirtual class CallGenFd(CallGenBase.CallGenBase): """FakeDuck / requires 字段注入 / provider 栈""" - def _translate_fakeduck_call(self, pool: memhub.MemBuddy*, - builder: mlirlite.IRBuilder*, - mod: mlirlite.LLVMModule*, - cls_name: str, - method_name: str, - cl: ast.Call*, - trans: HT.Translator*) -> mlirlite.Value*: + def _translate_fakeduck_call(self, pool: memhub.MemBuddy*, builder: mlirlite.IRBuilder*, mod: mlirlite.LLVMModule*, cls_name: str, method_name: str, cl: ast.Call*, trans: HT.Translator*) -> mlirlite.Value*: """FakeDuck: str 变量方法调用解析到扩展类 _Type/_str,返回 call 结果或 None""" if pool is None or builder is None or cl is None or trans is None: return None if method_name is None: return None @@ -146,12 +140,7 @@ novirtual class CallGenFd(CallGenBase.CallGenBase): # ============================================================ # ============================================================ - def _inject_requires_fields(self, trans: HT.Translator*, - pool: memhub.MemBuddy*, - builder: mlirlite.IRBuilder*, - mod: mlirlite.LLVMModule*, - meta_ptr: mlirlite.Value*, - class_name: str) -> int: + def _inject_requires_fields(self, trans: HT.Translator*, pool: memhub.MemBuddy*, builder: mlirlite.IRBuilder*, mod: mlirlite.LLVMModule*, meta_ptr: mlirlite.Value*, class_name: str) -> int: """在 with 上下文注入 requires 字段,返回注入字段数""" if trans is None or pool is None or builder is None or mod is None: return 0 if meta_ptr is None or class_name is None: return 0 @@ -226,12 +215,7 @@ novirtual class CallGenFd(CallGenBase.CallGenBase): # ============================================================ # ============================================================ - def _emit_provider_push(self, trans: HT.Translator*, - pool: memhub.MemBuddy*, - builder: mlirlite.IRBuilder*, - mod: mlirlite.LLVMModule*, - cls_name: str, - ctx_val: mlirlite.Value*) -> int: + def _emit_provider_push(self, trans: HT.Translator*, pool: memhub.MemBuddy*, builder: mlirlite.IRBuilder*, mod: mlirlite.LLVMModule*, cls_name: str, ctx_val: mlirlite.Value*) -> int: """生成 _push_provider(field, ctx_i8) 调用(每提供字段一次),返回字段数""" if trans is None or pool is None or builder is None or mod is None: return 0 if cls_name is None or ctx_val is None: return 0 @@ -262,11 +246,7 @@ novirtual class CallGenFd(CallGenBase.CallGenBase): self._ensure_method_declare(pool, mod, fd_pfn, ret_i32_p, fd_fstr, 2) mlirlite.build_call(builder, fd_pfn, fd_fstr, 2, ret_i32_p, 0) return fd_pc - def _emit_provider_pop(self, trans: HT.Translator*, - pool: memhub.MemBuddy*, - builder: mlirlite.IRBuilder*, - mod: mlirlite.LLVMModule*, - cls_name: str) -> int: + def _emit_provider_pop(self, trans: HT.Translator*, pool: memhub.MemBuddy*, builder: mlirlite.IRBuilder*, mod: mlirlite.LLVMModule*, cls_name: str) -> int: """生成 _pop_provider() 调用(每提供字段一次),返回字段数""" if trans is None or pool is None or builder is None or mod is None: return 0 if cls_name is None: return 0 diff --git a/App/lib/core/Gen/Call/CallGenLeafKit.vp b/App/lib/core/Gen/Call/CallGenLeafKit.vp index 382a3b6..573d04e 100644 --- a/App/lib/core/Gen/Call/CallGenLeafKit.vp +++ b/App/lib/core/Gen/Call/CallGenLeafKit.vp @@ -67,8 +67,7 @@ def _gfn_idx_slot(idx_base: sizet*, si: sizet) -> sizet*: return (sizet*)(uint64(idx_base) + uint64(si) * 8) -def _gfn_idx_find(funcs: GenTypes.FuncEntry*, - idx_base: sizet*, cap: int, name: str) -> int: +def _gfn_idx_find(funcs: GenTypes.FuncEntry*, idx_base: sizet*, cap: int, name: str) -> int: """在全局函数表名索引中探测 name,返回命中槽下标(>=0);未命中/不可用返回 -1""" if funcs is None or idx_base is None or cap <= 0 or name is None: return -1 h: uint64 = _gfn_hash(name) @@ -149,16 +148,7 @@ novirtual class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin): # ============================================================ # ============================================================ - def _emit_eh_guarded_call(self, builder: mlirlite.IRBuilder*, - pool: memhub.MemBuddy*, - mod: mlirlite.LLVMModule*, - trans: HT.Translator*, - func: mlirlite.Function*, - call_name: str, - head: mlirlite.Value*, - count: int, - ret_ty: mlirlite.LLVMType*, - is_variadic: int) -> mlirlite.Value*: + def _emit_eh_guarded_call(self, builder: mlirlite.IRBuilder*, pool: memhub.MemBuddy*, mod: mlirlite.LLVMModule*, trans: HT.Translator*, func: mlirlite.Function*, call_name: str, head: mlirlite.Value*, count: int, ret_ty: mlirlite.LLVMType*, is_variadic: int) -> mlirlite.Value*: """带 try-except EH 检测的函数调用,返回 call 结果(检查后位于 ok 块)""" if trans is None or self._func_has_eh_params(func) == 0: return mlirlite.build_call(builder, call_name, head, count, ret_ty, is_variadic) # ---- 1. 确定输出指针 ---- @@ -250,12 +240,7 @@ novirtual class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin): - def _translate_isinstance(self, pool: memhub.MemBuddy*, - builder: mlirlite.IRBuilder*, - mod: mlirlite.LLVMModule*, - obj_node: ast.AST*, - cls_node: ast.AST*, - trans: HT.Translator* = None) -> mlirlite.Value*: + def _translate_isinstance(self, pool: memhub.MemBuddy*, builder: mlirlite.IRBuilder*, mod: mlirlite.LLVMModule*, obj_node: ast.AST*, cls_node: ast.AST*, trans: HT.Translator* = None) -> mlirlite.Value*: """isinstance(obj, Cls):运行时 vtable 子类集合比较,返回 i1""" if obj_node is None or cls_node is None: # 参数缺失即调用错误:fail-fast,绝不返回 True 掩盖 @@ -323,8 +308,7 @@ novirtual class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin): return res - def _extract_isinstance_class_names(self, pool: memhub.MemBuddy*, - node: ast.AST*) -> sizet*: + def _extract_isinstance_class_names(self, pool: memhub.MemBuddy*, node: ast.AST*) -> sizet*: """从 isinstance 第二参数提取类名数组(Name→id / Attribute→attr / Tuple→遍历)""" arr: sizet* = pool.alloc(8 * 16) if arr is None: return None @@ -365,8 +349,7 @@ novirtual class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin): return arr - def _collect_subclass_vtable_classes(self, pool: memhub.MemBuddy*, - class_name: str) -> sizet*: + def _collect_subclass_vtable_classes(self, pool: memhub.MemBuddy*, class_name: str) -> sizet*: """反向 BFS 收集目标类及全部子类(含自身,仅 HasVTable==1),返回 0 结尾数组""" if class_name is None: return None names: sizet* = pool.alloc(8 * (CallGenBase.ISINSTANCE_CLASS_MAX + 1)) @@ -425,11 +408,7 @@ novirtual class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin): return names - def _make_vtable_ref_i8(self, pool: memhub.MemBuddy*, - builder: mlirlite.IRBuilder*, - mod: mlirlite.LLVMModule*, - class_name: str, - trans: HT.Translator* = None) -> mlirlite.Value*: + def _make_vtable_ref_i8(self, pool: memhub.MemBuddy*, builder: mlirlite.IRBuilder*, mod: mlirlite.LLVMModule*, class_name: str, trans: HT.Translator* = None) -> mlirlite.Value*: """构造类 vtable 地址引用(i8*):本模块已定义直接引用,跨模块声明 external""" if class_name is None: return None i8_ty: mlirlite.LLVMType* = mlirlite.Int8(pool) @@ -464,9 +443,7 @@ novirtual class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin): return mlirlite.build_bitcast(builder, ref, i8_ptr_ty) - def _isinstance_compile_time(self, pool: memhub.MemBuddy*, - obj_ptr: mlirlite.Value*, - class_name: str) -> int: + def _isinstance_compile_time(self, pool: memhub.MemBuddy*, obj_ptr: mlirlite.Value*, class_name: str) -> int: """编译时静态判断:obj 静态类型 == class_name 或 class_name 在其 MRO 中""" if obj_ptr is None or obj_ptr.Ty is None or class_name is None: return 0 match obj_ptr.Ty: @@ -493,13 +470,7 @@ novirtual class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin): - def translate_closure_call(self, pool: memhub.MemBuddy*, - builder: mlirlite.IRBuilder*, - mod: mlirlite.LLVMModule*, - closure_alloca: mlirlite.Value*, - cargs: list[ast.AST*]*, - can: sizet, - trans: HT.Translator* = None) -> mlirlite.Value*: + def translate_closure_call(self, pool: memhub.MemBuddy*, builder: mlirlite.IRBuilder*, mod: mlirlite.LLVMModule*, closure_alloca: mlirlite.Value*, cargs: list[ast.AST*]*, can: sizet, trans: HT.Translator* = None) -> mlirlite.Value*: """通过闭包指针间接调用(支持带参 lambda:i32(i8*, args...))""" if builder is None or closure_alloca is None: return None @@ -606,10 +577,7 @@ novirtual class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin): return 1 - def _func_ptr_sig_fatal(self, pool: memhub.MemBuddy*, - node: ast.AST*, name: str, - ret_ty: mlirlite.LLVMType*, - reason: str) -> None: + def _func_ptr_sig_fatal(self, pool: memhub.MemBuddy*, node: ast.AST*, name: str, ret_ty: mlirlite.LLVMType*, reason: str) -> None: """函数指针签名登记失败 → 编译期报错(文案含变量名/返回类型/上限/处置建议) 原实现满表时静默 return 1:登记被丢弃后,调用点才以 @@ -627,21 +595,12 @@ novirtual class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin): if typed_buf[0] != '\0': ret_str = typed_buf msg_buf: str = pool.alloc(1024) if msg_buf is not None: - viperlib.snprintf( - msg_buf, 1024, - "函数指针签名表登记失败:变量 '%s'(返回类型 %s)——%s。" - "当前上限 MAX_FUNC_PTR_SIGS=%d,已登记 %d 条。" - "同名同返回类型的重复登记已做原地命中、不占新槽位;" - "若确实需要更多函数指针变量,请上调 CallGenBase.vp 的 " - "MAX_FUNC_PTR_SIGS(全仓唯一来源,改此一处即全仓生效)", - name, ret_str, reason, cap, self.FuncptrCount) + viperlib.snprintf(msg_buf, 1024, "函数指针签名表登记失败:变量 '%s'(返回类型 %s)——%s。" "当前上限 MAX_FUNC_PTR_SIGS=%d,已登记 %d 条。" "同名同返回类型的重复登记已做原地命中、不占新槽位;" "若确实需要更多函数指针变量,请上调 CallGenBase.vp 的 " "MAX_FUNC_PTR_SIGS(全仓唯一来源,改此一处即全仓生效)", name, ret_str, reason, cap, self.FuncptrCount) self.Gen.TypeGenErr.fatal_error(node, msg_buf, "TypeError") return self.Gen.TypeGenErr.fatal_error(node, "函数指针签名表登记失败(签名表已满或变量名冲突)", "TypeError") - def register_func_ptr_sig(self, pool: memhub.MemBuddy*, name: str, - ret_ty: mlirlite.LLVMType*, - node: ast.AST* = None) -> int: + def register_func_ptr_sig(self, pool: memhub.MemBuddy*, name: str, ret_ty: mlirlite.LLVMType*, node: ast.AST* = None) -> int: """注册函数指针变量的返回类型签名,0=成功(含幂等命中)/ 1=失败(已报错终止) 表按**裸变量名**全局共享(PermPool,跨文件/跨阶段存活),同一变量可能被 @@ -655,8 +614,7 @@ novirtual class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin): """ if name is None or ret_ty is None: return 1 if self._ensure_funcptr_sigs() == 0: - self._func_ptr_sig_fatal(pool, node, name, ret_ty, - "签名表分配失败(PermPool 内存不足)") + self._func_ptr_sig_fatal(pool, node, name, ret_ty, "签名表分配失败(PermPool 内存不足)") return 1 # 幂等/冲突检查:线性扫已登记裸名(FuncptrCount 上限 64,代价可忽略) i: sizet @@ -691,14 +649,7 @@ novirtual class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin): return None - def _translate_func_ptr_call(self, pool: memhub.MemBuddy*, - builder: mlirlite.IRBuilder*, - mod: mlirlite.LLVMModule*, - fp_alloca: mlirlite.Value*, - func_name: str, - cargs: list[ast.AST*]*, - can: sizet, - trans: HT.Translator*) -> mlirlite.Value*: + def _translate_func_ptr_call(self, pool: memhub.MemBuddy*, builder: mlirlite.IRBuilder*, mod: mlirlite.LLVMModule*, fp_alloca: mlirlite.Value*, func_name: str, cargs: list[ast.AST*]*, can: sizet, trans: HT.Translator*) -> mlirlite.Value*: """函数指针变量间接调用,返回结果 Value""" if builder is None or fp_alloca is None: return None i8_ty: mlirlite.LLVMType* = mlirlite.Int8(pool) @@ -753,11 +704,7 @@ novirtual class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin): return mlirlite.build_call_indirect(builder, fn_typed, head, arg_count, ret_ty) - def translate_printf_call(self, pool: memhub.MemBuddy*, - builder: mlirlite.IRBuilder*, - mod: mlirlite.LLVMModule*, - cl: ast.Call*, - trans: HT.Translator* = None) -> None: + def translate_printf_call(self, pool: memhub.MemBuddy*, builder: mlirlite.IRBuilder*, mod: mlirlite.LLVMModule*, cl: ast.Call*, trans: HT.Translator* = None) -> None: """翻译 printf 调用(特殊处理格式字符串)""" cargs: list[ast.AST*]* = cl.args if cargs is None: return @@ -805,11 +752,7 @@ novirtual class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin): mlirlite.build_call(builder, "printf", fmt_ptr, can, i32_ty, 1) - def translate_print_call(self, pool: memhub.MemBuddy*, - builder: mlirlite.IRBuilder*, - mod: mlirlite.LLVMModule*, - cl: ast.Call*, - trans: HT.Translator* = None) -> None: + def translate_print_call(self, pool: memhub.MemBuddy*, builder: mlirlite.IRBuilder*, mod: mlirlite.LLVMModule*, cl: ast.Call*, trans: HT.Translator* = None) -> None: """翻译 print 调用(类型感知格式化 + 默认换行)""" cargs: list[ast.AST*]* = cl.args if cargs is None: return @@ -933,10 +876,7 @@ novirtual class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin): return funcs_ptr - def find_func_in_table(self, funcs: GenTypes.FuncEntry*, - func_count: int, - name: str, - owner_sha1: str = None) -> mlirlite.Function*: + def find_func_in_table(self, funcs: GenTypes.FuncEntry*, func_count: int, name: str, owner_sha1: str = None) -> mlirlite.Function*: """在函数表中按名称查找,返回 Function 指针或 None owner_sha1: 当前模块 SHA1。非 None 时"本模块函数优先"——表里同名条目 @@ -956,8 +896,7 @@ novirtual class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin): if owner_sha1 is None and self.GlobalFuncs is not None: if uint64(funcs) == uint64(self.GlobalFuncs) and func_count == self.GlobalFuncCount: gfuncs_match = 1 if gfuncs_match != 0 and self.GlobalFuncNameIdxBuilt == self.GlobalFuncCount and self.GlobalFuncNameIdx is not None and self.GlobalFuncNameIdxCap > 0: - fi_t: int = _gfn_idx_find(self.GlobalFuncs, self.GlobalFuncNameIdx, - self.GlobalFuncNameIdxCap, name) + fi_t: int = _gfn_idx_find(self.GlobalFuncs, self.GlobalFuncNameIdx, self.GlobalFuncNameIdxCap, name) if fi_t >= 0: fe_t: GenTypes.FuncEntry* = GenTypes.FuncEntry*((uint64(self.GlobalFuncs) + fi_t * entry_size)) if fe_t is not None: return fe_t.Func @@ -984,16 +923,7 @@ novirtual class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin): return None - def add_func_to_table(self, funcs: GenTypes.FuncEntry*, - func_count: int, - name: str, - func: mlirlite.Function*, - max_count: int, - defaults: t.CPtr = None, - default_count: int = 0, - param_count: int = 0, - pool: memhub.MemBuddy* = None, - def_sha1: str = None) -> int: + def add_func_to_table(self, funcs: GenTypes.FuncEntry*, func_count: int, name: str, func: mlirlite.Function*, max_count: int, defaults: t.CPtr = None, default_count: int = 0, param_count: int = 0, pool: memhub.MemBuddy* = None, def_sha1: str = None) -> int: """添加函数到函数表,返回 0 成功 Args: @@ -1045,8 +975,7 @@ novirtual class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin): return 1 - def _register_global_func(self, name: str, func: mlirlite.Function*, - pool: memhub.MemBuddy* = None) -> int: + def _register_global_func(self, name: str, func: mlirlite.Function*, pool: memhub.MemBuddy* = None) -> int: """注册函数到全局表(已存在则跳过),返回 0 成功 直接操作全局表,不调用 add_func_to_table,避免递归。 @@ -1075,15 +1004,13 @@ novirtual class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin): self.GlobalFuncCount += 1 # 同步名索引(槽下标 = 新条目下标):仅当插入前可信(Built==Count-1) # 且插入成功;否则标记不可信(查找回退线性扫描)。 - if self.GlobalFuncNameIdxBuilt == self.GlobalFuncCount - 1 and _gfn_idx_insert(self.GlobalFuncNameIdx, self.GlobalFuncNameIdxCap, - self.GlobalFuncCount - 1, name_copy) == 0: + if self.GlobalFuncNameIdxBuilt == self.GlobalFuncCount - 1 and _gfn_idx_insert(self.GlobalFuncNameIdx, self.GlobalFuncNameIdxCap, self.GlobalFuncCount - 1, name_copy) == 0: self.GlobalFuncNameIdxBuilt = self.GlobalFuncCount else: self.GlobalFuncNameIdxBuilt = -1 return 0 - def update_global_func_spec(self, name: str, - func: mlirlite.Function*) -> int: + def update_global_func_spec(self, name: str, func: mlirlite.Function*) -> int: """更新全局函数表的 Spec(在函数参数全部添加完成后调用) 调用时机:add_func_to_table 注册后、mlirlite.add_param 全部执行完。 @@ -1170,11 +1097,7 @@ novirtual class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin): return 1 - def _register_global_defaults(self, name: str, - defaults: t.CPtr, - default_count: int, - param_count: int, - def_sha1: str = None) -> int: + def _register_global_defaults(self, name: str, defaults: t.CPtr, default_count: int, param_count: int, def_sha1: str = None) -> int: """注册函数默认参数到全局表,返回 0 成功 注册时提取每个默认值 Constant 的常量快照到 stdlib(ConstKinds/ConstInts/ConstStrs), @@ -1286,8 +1209,7 @@ novirtual class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin): return 0 - def find_func_defaults(self, name: str, - module_sha1: str = None) -> GenTypes.FuncDefaultsEntry*: + def find_func_defaults(self, name: str, module_sha1: str = None) -> GenTypes.FuncDefaultsEntry*: """按函数名(可选按定义模块 SHA1)查找默认参数信息,返回 FuncDefaultsEntry 或 None module_sha1 非 None 时要求条目定义模块完全一致(限定名匹配,消除跨模块同名串味); @@ -1307,12 +1229,7 @@ novirtual class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin): return None - def _build_const_from_snapshot(self, pool: memhub.MemBuddy*, - mod: mlirlite.LLVMModule*, - gd_entry: GenTypes.FuncDefaultsEntry*, - di: int, - trans: HT.Translator*, - builder: mlirlite.IRBuilder*) -> mlirlite.Value*: + def _build_const_from_snapshot(self, pool: memhub.MemBuddy*, mod: mlirlite.LLVMModule*, gd_entry: GenTypes.FuncDefaultsEntry*, di: int, trans: HT.Translator*, builder: mlirlite.IRBuilder*) -> mlirlite.Value*: """从快照重建第 di 个默认值常量 IR""" if gd_entry is None or gd_entry.ConstKinds is None or gd_entry.ConstInts is None: return None if di < 0 or di >= gd_entry.DefaultCount: return None @@ -1336,9 +1253,7 @@ novirtual class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin): return None - def find_func_entry_in_table(self, funcs: GenTypes.FuncEntry*, - func_count: int, - name: str) -> GenTypes.FuncEntry*: + def find_func_entry_in_table(self, funcs: GenTypes.FuncEntry*, func_count: int, name: str) -> GenTypes.FuncEntry*: """在函数表中按名称查找,返回完整 FuncEntry 或 None""" if name is None or funcs is None: return None entry_size: sizet = GenTypes.FuncEntry.__sizeof__() @@ -1350,10 +1265,7 @@ novirtual class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin): if entry.Name[0] == name[0] and string.strcmp(entry.Name, name) == 0: return entry return None - def find_func_entry_in_table_owned(self, funcs: GenTypes.FuncEntry*, - func_count: int, - name: str, - owner_sha1: str) -> GenTypes.FuncEntry*: + def find_func_entry_in_table_owned(self, funcs: GenTypes.FuncEntry*, func_count: int, name: str, owner_sha1: str) -> GenTypes.FuncEntry*: """按「裸名 + 定义模块 SHA1」查找函数表条目,返回 FuncEntry 或 None 函数表以**裸名**登记,且 LoadDepVpiIntoModule 会把依赖模块的同名函数 diff --git a/App/lib/core/Gen/Call/CallGenLib.vp b/App/lib/core/Gen/Call/CallGenLib.vp index c95c79d..654f970 100644 --- a/App/lib/core/Gen/Call/CallGenLib.vp +++ b/App/lib/core/Gen/Call/CallGenLib.vp @@ -19,9 +19,7 @@ from . import CallGenBase novirtual class CallGenLib(CallGenBase.CallGenBase): """C 库声明 / 返回类型推断 / kwargs 调用辅助(继承 Base)""" - def _ensure_c_lib_declare(self, pool: memhub.MemBuddy*, - mod: mlirlite.LLVMModule*, - name: str) -> mlirlite.Function*: + def _ensure_c_lib_declare(self, pool: memhub.MemBuddy*, mod: mlirlite.LLVMModule*, name: str) -> mlirlite.Function*: """为已知的 C 库函数创建 declare 声明""" if pool is None or mod is None or name is None: return None @@ -102,12 +100,7 @@ novirtual class CallGenLib(CallGenBase.CallGenBase): mlirlite.add_param(pool, fn, i64_ty, "n") return fn - def _promote_clib_call_args(self, pool: memhub.MemBuddy*, - builder: mlirlite.IRBuilder*, - mod: mlirlite.LLVMModule*, - call_name: str, - head: mlirlite.Value*, - count: int) -> mlirlite.Value*: + def _promote_clib_call_args(self, pool: memhub.MemBuddy*, builder: mlirlite.IRBuilder*, mod: mlirlite.LLVMModule*, call_name: str, head: mlirlite.Value*, count: int) -> mlirlite.Value*: """裸名 C 库函数实参按标准签名提升(B3)。 跨模块裸名调用(string.memset → @memset)时 _ensure_method_declare 用 @@ -168,14 +161,7 @@ novirtual class CallGenLib(CallGenBase.CallGenBase): return new_head # _coerce_args_to_def_params:按 vpi 定义侧形参注解把跨模块调用实参 coerce 到目标类型并重建实参链,使 call/declare/define 宽度一致;支持 {sha1}.{func} 与 {sha1}.{cls}.{method} 两形态(段下标与实参下标一一对应),裸名 C 库走 _promote_clib_call_args/_ensure_c_lib_declare,未命中原样保留 - def _coerce_args_to_def_params(self, pool: memhub.MemBuddy*, - builder: mlirlite.IRBuilder*, - call_name: str, - head: mlirlite.Value*, - count: int, - cargs: list[ast.AST*]* = None, - self_off: int = 0, - trans: HT.Translator* = None) -> mlirlite.Value*: + def _coerce_args_to_def_params(self, pool: memhub.MemBuddy*, builder: mlirlite.IRBuilder*, call_name: str, head: mlirlite.Value*, count: int, cargs: list[ast.AST*]* = None, self_off: int = 0, trans: HT.Translator* = None) -> mlirlite.Value*: """把跨模块调用实参 coerce 到 vpi 定义侧形参类型,返回重建的实参链 cargs/self_off/trans:实参 AST 列表与其在实参链中的偏移(模块级函数 0、 @@ -260,13 +246,7 @@ novirtual class CallGenLib(CallGenBase.CallGenBase): return new_head # _coerce_arg_value_to_ty:单个实参 Value 转换到目标形参类型——整型同宽原样、窄化 trunc/按宽度重建常量、扩宽按源符号性 zext/sext;同层指针类型不一致则 bitcast 到目标类型;其余原样返回(不可转换亦不改型) - def _coerce_arg_value_to_ty(self, pool: memhub.MemBuddy*, - builder: mlirlite.IRBuilder*, - val: mlirlite.Value*, - tgt_ty: mlirlite.LLVMType*, - node: ast.AST* = None, - trans: HT.Translator* = None, - tpl_src: int = 0) -> mlirlite.Value*: + def _coerce_arg_value_to_ty(self, pool: memhub.MemBuddy*, builder: mlirlite.IRBuilder*, val: mlirlite.Value*, tgt_ty: mlirlite.LLVMType*, node: ast.AST* = None, trans: HT.Translator* = None, tpl_src: int = 0) -> mlirlite.Value*: """把单个实参 Value 转换到目标形参类型,无法安全转换时原样返回 node/trans:实参 AST 与其翻译器(仅 SSA 整型扩宽的源符号性判定用, @@ -333,10 +313,7 @@ novirtual class CallGenLib(CallGenBase.CallGenBase): pass return val - def _infer_external_func_ret_ty(self, pool: memhub.MemBuddy*, - func_name: str, - node: ast.AST*, - fatal_if_unknown: int) -> mlirlite.LLVMType*: + def _infer_external_func_ret_ty(self, pool: memhub.MemBuddy*, func_name: str, node: ast.AST*, fatal_if_unknown: int) -> mlirlite.LLVMType*: """根据函数名推断外部 includes 函数的返回类型 支持三种函数名形式: @@ -458,9 +435,7 @@ novirtual class CallGenLib(CallGenBase.CallGenBase): # 默认 i32 占位:fatal_if_unknown=1 → fail-fast 报错;=0(Phase A 中间遍)保持占位,不输出 WARN if fatal_if_unknown != 0: self.Gen.TypeGenErr.fatal_error(node, f"外部函数返回类型未登记且无法收敛推断(默认 i32 会截断指针/i64,需提供 stub 声明或加入白名单): {func_name}", "TypeError") return mlirlite.Int32(pool) - def _get_external_func_param_ty(self, pool: memhub.MemBuddy*, - func_name: str, - param_idx: int) -> mlirlite.LLVMType*: + def _get_external_func_param_ty(self, pool: memhub.MemBuddy*, func_name: str, param_idx: int) -> mlirlite.LLVMType*: """获取外部函数第 param_idx 个参数的期望类型,None 表示用字面量原类型 ⚠ **兜底专用**:调用方应先按**定义侧 vpi 形参注解**取真实类型 @@ -479,17 +454,7 @@ novirtual class CallGenLib(CallGenBase.CallGenBase): # Win32 API 函数列表:所有非指针参数在 declare 中都是 i64 # (因为 ULONG/DWORD/SIZE_T 在 LLVM stubs 翻译时都被映射为 i64) - win32_apis: list[str]* = [ - "VirtualAlloc", "VirtualFree", "VirtualProtect", "VirtualQuery", - "VirtualLock", "VirtualUnlock", - "HeapCreate", "HeapDestroy", "HeapAlloc", "HeapReAlloc", - "HeapFree", "HeapSize", "HeapValidate", "HeapCompact", - "GlobalAlloc", "GlobalFree", "GlobalLock", "GlobalUnlock", "GlobalSize", - "LocalAlloc", "LocalFree", - "GetLastError", "SetLastError", - "Sleep", "SleepEx", - "GetTickCount", "GetProcessHeap" - ] + win32_apis: list[str]* = ["VirtualAlloc", "VirtualFree", "VirtualProtect", "VirtualQuery", "VirtualLock", "VirtualUnlock", "HeapCreate", "HeapDestroy", "HeapAlloc", "HeapReAlloc", "HeapFree", "HeapSize", "HeapValidate", "HeapCompact", "GlobalAlloc", "GlobalFree", "GlobalLock", "GlobalUnlock", "GlobalSize", "LocalAlloc", "LocalFree", "GetLastError", "SetLastError", "Sleep", "SleepEx", "GetTickCount", "GetProcessHeap"] # list 迭代不支持,用 range + get 替代 api_count: sizet = len(win32_apis) @@ -516,12 +481,7 @@ novirtual class CallGenLib(CallGenBase.CallGenBase): if call_name is None: return 0 if GenApi.sha1_prefix_len(call_name) != 0: return 1 return 0 - def _emit_llvm_memcpy_intrinsic(self, pool: memhub.MemBuddy*, - builder: mlirlite.IRBuilder*, - mod: mlirlite.LLVMModule*, - dst_val: mlirlite.Value*, - src_val: mlirlite.Value*, - num_val: mlirlite.Value*) -> mlirlite.Value*: + def _emit_llvm_memcpy_intrinsic(self, pool: memhub.MemBuddy*, builder: mlirlite.IRBuilder*, mod: mlirlite.LLVMModule*, dst_val: mlirlite.Value*, src_val: mlirlite.Value*, num_val: mlirlite.Value*) -> mlirlite.Value*: """将 memcpy 调用映射到 @llvm.memcpy 内联函数 直接接收三个 Value 参数,避免通过 Next 链表遍历(共享 alloca 对象的 @@ -597,16 +557,7 @@ novirtual class CallGenLib(CallGenBase.CallGenBase): # _translate_call_with_kwargs:带关键字参数的函数调用,按 found_func.Params 顺序构建实参链表(位置参数优先,否则按参数名匹配关键字) # ============================================================ - def _translate_call_with_kwargs(self, pool: memhub.MemBuddy*, - builder: mlirlite.IRBuilder*, - mod: mlirlite.LLVMModule*, - func_name: str, - found_func: mlirlite.Function*, - cargs: list[ast.AST*]*, - can: sizet, - keywords: list[ast.AST*]*, - kw_count: sizet, - trans: HT.Translator*) -> mlirlite.Value*: + def _translate_call_with_kwargs(self, pool: memhub.MemBuddy*, builder: mlirlite.IRBuilder*, mod: mlirlite.LLVMModule*, func_name: str, found_func: mlirlite.Function*, cargs: list[ast.AST*]*, can: sizet, keywords: list[ast.AST*]*, kw_count: sizet, trans: HT.Translator*) -> mlirlite.Value*: """带关键字参数的函数调用,按参数顺序构建调用链表 使用 mlirlite 访问器函数绕过 stub 类型限制: @@ -679,16 +630,11 @@ novirtual class CallGenLib(CallGenBase.CallGenBase): if kw_default_count > 0 and int(param_idx) >= kw_default_off: kw_di: int = int(param_idx) - kw_default_off if kw_di >= 0 and kw_di < kw_default_count: - arg_val = self.Gen.CallGenLeafKit._build_const_from_snapshot( - pool, mod, kw_gd, kw_di, trans, builder) + arg_val = self.Gen.CallGenLeafKit._build_const_from_snapshot(pool, mod, kw_gd, kw_di, trans, builder) if arg_val is None: kw_node: ast.AST* = None if keywords is not None and kw_count > 0: kw_node = keywords.get(0) - self.Gen.TypeGenErr.fatal_error( - kw_node, - f"调用 '{func_name}' 的某个形参既未按位置/关键字传入," - f"定义处也无默认值可填充(拒绝静默漏参/填零)", - "TypeError") + self.Gen.TypeGenErr.fatal_error(kw_node, f"调用 '{func_name}' 的某个形参既未按位置/关键字传入," f"定义处也无默认值可填充(拒绝静默漏参/填零)", "TypeError") if arg_val is not None: # 类型转换(按参数类型,使用访问器) diff --git a/App/lib/core/Gen/Call/CallGenMixin.vp b/App/lib/core/Gen/Call/CallGenMixin.vp index 44c11b3..6d1ba83 100644 --- a/App/lib/core/Gen/Call/CallGenMixin.vp +++ b/App/lib/core/Gen/Call/CallGenMixin.vp @@ -50,9 +50,7 @@ novirtual class CallGenMixin(CallGenBase.CallGenBase): # Class.static_method)时放行;同模块自引用(sha1 相同)放行。 # 独立成函数:translate_call 极大,内联该检查会干扰其类型推断。 # ============================================================ - def _CheckStaticCallCrossModule(self, pool: memhub.MemBuddy*, - trans: HT.Translator*, - cl: ast.Call*) -> int: + def _CheckStaticCallCrossModule(self, pool: memhub.MemBuddy*, trans: HT.Translator*, cl: ast.Call*) -> int: if cl is None or cl.func is None or trans is None: return 0 if cl.func.kind() != ast.ASTKind.Attribute: return 0 if trans.ModuleSha1 is None or trans._imported_modules is None: return 0 @@ -71,22 +69,14 @@ novirtual class CallGenMixin(CallGenBase.CallGenBase): if sc_sha1 is None: return 0 if string.strncmp(sc_sha1, trans.ModuleSha1, 16) == 0: return 0 if self.Gen.CallGenBase.IsStaticSymbol(sc_sha1, sc_at.attr) == 0: return 0 - self.Gen.TypeGenErr.fatal_error(cl, - f"'{sc_mod}.{sc_at.attr}' 是 static 符号,禁止跨模块使用(static 仅限定义模块内可见)", - "NameError") + self.Gen.TypeGenErr.fatal_error(cl, f"'{sc_mod}.{sc_at.attr}' 是 static 符号,禁止跨模块使用(static 仅限定义模块内可见)", "NameError") return 0 # ============================================================ # 翻译函数调用 Call(func, args) — 模块级版本 # ============================================================ - def translate_call(self, pool: memhub.MemBuddy*, - builder: mlirlite.IRBuilder*, - mod: mlirlite.LLVMModule*, - node: ast.AST*, - funcs_ptr: t.CPtr, - func_count: int, - trans: HT.Translator* = None) -> mlirlite.Value*: + def translate_call(self, pool: memhub.MemBuddy*, builder: mlirlite.IRBuilder*, mod: mlirlite.LLVMModule*, node: ast.AST*, funcs_ptr: t.CPtr, func_count: int, trans: HT.Translator* = None) -> mlirlite.Value*: """翻译函数调用,返回 call 结果 Value""" cl: ast.Call* = ast.Call*(node) # static 符号(禁止跨模块使用):`mod.fn(...)` 命中别的模块登记的 static 函数 @@ -169,8 +159,7 @@ novirtual class CallGenMixin(CallGenBase.CallGenBase): if sub_cast_ty is not None: sub_cast_arg: mlirlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, mod, cl.args.get(0), funcs_ptr, func_count, trans) if sub_cast_arg is not None: - return self.Gen.CallGenCtor._translate_t_type_cast(pool, builder, sub_cast_arg, sub_cast_ty, - cl.args.get(0), trans) + return self.Gen.CallGenCtor._translate_t_type_cast(pool, builder, sub_cast_arg, sub_cast_ty, cl.args.get(0), trans) # 泛型类模板未找到:可能未 import 定义模块 gt_err: str = pool.alloc(256) if gt_err is not None: @@ -424,12 +413,7 @@ novirtual class CallGenMixin(CallGenBase.CallGenBase): # s: Stack[int] = Stack())⇒ 用它特化,而非 fail-fast ta_bare = ctx_args_bare.get(tpi_bare) if ta_bare is None: - self.Gen.TypeGenErr.fatal_error( - cl, - f"无法从实参推断泛型类 '{func_name}' 的第 {tpi_bare + 1} 个类型实参," - f"禁止静默默认 int(会产生 list[int] 等错误特化 → 元素按 4 字节/i32 处理 → 指针截断崩溃);" - f"请为该实参标注类型或显式标注如 {func_name}[类型](...)", - "TypeError") + self.Gen.TypeGenErr.fatal_error(cl, f"无法从实参推断泛型类 '{func_name}' 的第 {tpi_bare + 1} 个类型实参," f"禁止静默默认 int(会产生 list[int] 等错误特化 → 元素按 4 字节/i32 处理 → 指针截断崩溃);" f"请为该实参标注类型或显式标注如 {func_name}[类型](...)", "TypeError") inferred_args_bare.append(ta_bare) spec_name_bare: str = self.Gen.ClassGenGeneric._specialize_generic_class(trans, func_name, inferred_args_bare) if spec_name_bare is not None: return self.Gen.CallGenCtor._translate_generic_ctor_call(pool, builder, mod, spec_name_bare, cl, trans, func_name) @@ -455,12 +439,7 @@ novirtual class CallGenMixin(CallGenBase.CallGenBase): if rc_tag < 0: # [D32 fail-fast] 是 REnum 却查不到变体名 ⇒ 变体表不完整, # 继续走外部函数路径会报无关的 "外部函数返回类型未登记"。 - self.Gen.TypeGenErr.fatal_error( - cl, - f"REnum 类 '{rc_cls_name}' 的变体 '{func_name}' 未在变体表中找到" - f"({self.Gen.ClassGenEnum.RenumTableDump()});" - f"变体表未注册或变体名不匹配", - "NameError") + self.Gen.TypeGenErr.fatal_error(cl, f"REnum 类 '{rc_cls_name}' 的变体 '{func_name}' 未在变体表中找到" f"({self.Gen.ClassGenEnum.RenumTableDump()});" f"变体表未注册或变体名不匹配", "NameError") if rc_tag >= 0: return self.Gen.CallGenCtor._translate_renum_construct(pool, builder, mod, rc_cls_name, func_name, rc_tag, cargs, can, trans, cl.IsVolatile) elif rc_at.value is not None and rc_at.value.kind() == ast.ASTKind.Attribute: # 模块限定 REnum 变体构造: mod.Class.Variant(args...) @@ -892,8 +871,7 @@ novirtual class CallGenMixin(CallGenBase.CallGenBase): if c_call_cls is not None: return self.Gen.CallGenCall._translate_method_call(pool, builder, mod, c_call_cls, "__call__", c_obj, cl, trans) # 闭包变量(嵌套函数提升,已注册到闭包名集合):提取 fn_ptr/env_ptr 间接调用 if self.Gen.CallGenLeafKit.is_closure_name(func_name) != 0: - return self.Gen.CallGenLeafKit.translate_closure_call(pool, builder, mod, fp_alloca, - cargs, can, trans) + return self.Gen.CallGenLeafKit.translate_closure_call(pool, builder, mod, fp_alloca, cargs, can, trans) # 函数指针变量(t.Callable 注解 → i8** alloca):按实参构造签名间接调用 if self.Gen.CallGenLeafKit._is_func_ptr_alloca(fp_alloca) != 0: # 区分 t.Callable(真函数指针)vs t.CPtr(闭包指针): @@ -915,13 +893,10 @@ novirtual class CallGenMixin(CallGenBase.CallGenBase): # SourceName 只留 "Foo"(取非 CPtr 侧类名)⇒ 此处判为非标记。 if TSpec.SpecTypeNameBaseIs(fp_annot, "CPtr") != 0: is_cptr_annot_fp = 1 if is_cptr_annot_fp == 0: - return self.Gen.CallGenLeafKit._translate_func_ptr_call(pool, builder, mod, fp_alloca, - func_name, cargs, can, trans) - return self.Gen.CallGenLeafKit.translate_closure_call(pool, builder, mod, fp_alloca, - cargs, can, trans) + return self.Gen.CallGenLeafKit._translate_func_ptr_call(pool, builder, mod, fp_alloca, func_name, cargs, can, trans) + return self.Gen.CallGenLeafKit.translate_closure_call(pool, builder, mod, fp_alloca, cargs, can, trans) # 其他 i8* 变量按闭包调用路径处理 - return self.Gen.CallGenLeafKit.translate_closure_call(pool, builder, mod, fp_alloca, - cargs, can, trans) + return self.Gen.CallGenLeafKit.translate_closure_call(pool, builder, mod, fp_alloca, cargs, can, trans) # ---- M3:会话函数表命中 → ctx 函数指针槽取址 + 间接调用 ---- # 位置(为什么在这里):本步位于 `if found_func is None:` 块**末尾**—— # ① found_func 为 None ⇒ 本片段的 LLVM 模块里没有该函数的定义/前向声明 @@ -1028,9 +1003,7 @@ novirtual class CallGenMixin(CallGenBase.CallGenBase): sha_pt: str = self.Gen.StructGen._resolve_module_sha1(mpath_pt, fi_pt) if sha_pt is not None: if self.Gen.CallGenBase.TempDir is not None and self.Gen.CallGenBase.TempDirLen > 0: VpiReader._ensure_vpi_param_annot_loaded(sha_pt, self.Gen.CallGenBase.TempDir) - ext_param_ty = VpiReader._resolve_vpi_param_annot_seg( - pool, sha_pt, None, func_name, ai, - mlirlite.Int32(pool), mlirlite.Ptr(pool, mlirlite.Int8(pool))) + ext_param_ty = VpiReader._resolve_vpi_param_annot_seg(pool, sha_pt, None, func_name, ai, mlirlite.Int32(pool), mlirlite.Ptr(pool, mlirlite.Int8(pool))) # ② 白名单仅作**兜底**(定义侧注解不可得时) if ext_param_ty is None: ext_param_ty = self.Gen.CallGenLib._get_external_func_param_ty(pool, func_name, ai) if ext_param_ty is not None: @@ -1145,8 +1118,7 @@ novirtual class CallGenMixin(CallGenBase.CallGenBase): dfx_p: mlirlite.Param* = mlirlite.function_get_param_head(found_func) while dfx_p is not None: dfx_nm: str = mlirlite.param_get_name(dfx_p) - if dfx_nm is None or (string.strcmp(dfx_nm, "%__eh_msg_out__") != 0 - and string.strcmp(dfx_nm, "%__eh_code_out__") != 0): + if dfx_nm is None or (string.strcmp(dfx_nm, "%__eh_msg_out__") != 0 and string.strcmp(dfx_nm, "%__eh_code_out__") != 0): dfx_cnt += 1 dfx_p = mlirlite.param_get_next(dfx_p) if dfx_cnt > 0 and dfx_cnt != df_param_count: @@ -1183,8 +1155,7 @@ novirtual class CallGenMixin(CallGenBase.CallGenBase): fc_p: mlirlite.Param* = mlirlite.function_get_param_head(found_func) while fc_p is not None: fp_nm_z: str = mlirlite.param_get_name(fc_p) - if fp_nm_z is None or (string.strcmp(fp_nm_z, "%__eh_msg_out__") != 0 - and string.strcmp(fp_nm_z, "%__eh_code_out__") != 0): + if fp_nm_z is None or (string.strcmp(fp_nm_z, "%__eh_msg_out__") != 0 and string.strcmp(fp_nm_z, "%__eh_code_out__") != 0): fc_cnt += 1 fc_p = mlirlite.param_get_next(fc_p) if fc_cnt == 0: fc_cnt = df_param_count if df_param_count > 0 else 0 @@ -1242,8 +1213,7 @@ novirtual class CallGenMixin(CallGenBase.CallGenBase): # 如 string.strchr(...) → @{sha1_of_string}.strchr if cl.func is not None and cl.func.kind() == ast.ASTKind.Attribute: xmod_at: ast.Attribute* = ast.Attribute*(cl.func) - if xmod_at.value is not None and (xmod_at.value.kind() == ast.ASTKind.Name - or xmod_at.value.kind() == ast.ASTKind.Attribute): + if xmod_at.value is not None and (xmod_at.value.kind() == ast.ASTKind.Name or xmod_at.value.kind() == ast.ASTKind.Attribute): # 模块路径:单层 Name(string.strchr)或嵌套 Attribute # (os._win32.exists)。嵌套路径此前不支持 → os/__init__.vp # 内部调 os._win32.exists 只能被 find_func_in_module 后缀匹配 @@ -1268,9 +1238,7 @@ novirtual class CallGenMixin(CallGenBase.CallGenBase): if is_xmod_imported == 0: err_ni: str = pool.alloc(256) if err_ni is not None: - viperlib.snprintf(err_ni, 256, - "跨模块调用 '%s.%s':模块 '%s' 未导入(请先 import %s)", - xmod_path, func_name, xmod_path, xmod_path) + viperlib.snprintf(err_ni, 256, "跨模块调用 '%s.%s':模块 '%s' 未导入(请先 import %s)", xmod_path, func_name, xmod_path, xmod_path) self.Gen.TypeGenErr.fatal_error(xmod_at, err_ni) self.Gen.TypeGenErr.fatal_error(xmod_at, "跨模块调用:模块未导入") # 检查是否是 re-export 函数(如 ast._lexer_init 实际定义在 ast.lexer) diff --git a/App/lib/core/Gen/Call/CallGenProp.vp b/App/lib/core/Gen/Call/CallGenProp.vp index 79fcae2..a23b01c 100644 --- a/App/lib/core/Gen/Call/CallGenProp.vp +++ b/App/lib/core/Gen/Call/CallGenProp.vp @@ -37,14 +37,7 @@ novirtual class CallGenProp(CallGenBase.CallGenBase): # # call_head/call_count: 已构建好的参数链表(如 getter 只有 obj 一个参数) # ============================================================ - def _translate_property_call(self, pool: memhub.MemBuddy*, - builder: mlirlite.IRBuilder*, - mod: mlirlite.LLVMModule*, - class_name: str, - method_name: str, - call_head: mlirlite.Value*, - call_count: int, - trans: HT.Translator*) -> mlirlite.Value*: + def _translate_property_call(self, pool: memhub.MemBuddy*, builder: mlirlite.IRBuilder*, mod: mlirlite.LLVMModule*, class_name: str, method_name: str, call_head: mlirlite.Value*, call_count: int, trans: HT.Translator*) -> mlirlite.Value*: """翻译属性/静态方法调用,返回 call 结果 Value""" if pool is None or builder is None or class_name is None or method_name is None: return None @@ -131,9 +124,7 @@ novirtual class CallGenProp(CallGenBase.CallGenBase): # ============================================================ # ============================================================ - def _resolve_obj_class_name(self, pool: memhub.MemBuddy*, - trans: HT.Translator*, - obj_node: ast.AST*) -> str: + def _resolve_obj_class_name(self, pool: memhub.MemBuddy*, trans: HT.Translator*, obj_node: ast.AST*) -> str: """解析对象表达式的类名(短名),失败返回 None""" if pool is None or trans is None or obj_node is None: return None if obj_node.kind() == ast.ASTKind.Name: @@ -168,13 +159,7 @@ novirtual class CallGenProp(CallGenBase.CallGenBase): # ============================================================ # ============================================================ - def _try_property_getter_attr(self, pool: memhub.MemBuddy*, - builder: mlirlite.IRBuilder*, - mod: mlirlite.LLVMModule*, - at_node: ast.Attribute*, - obj_ptr: mlirlite.Value*, - trans: HT.Translator*, - fallback_class_name: str = None) -> mlirlite.Value*: + def _try_property_getter_attr(self, pool: memhub.MemBuddy*, builder: mlirlite.IRBuilder*, mod: mlirlite.LLVMModule*, at_node: ast.Attribute*, obj_ptr: mlirlite.Value*, trans: HT.Translator*, fallback_class_name: str = None) -> mlirlite.Value*: """尝试 property getter 属性访问,返回调用结果 Value;非 getter 返回 None fallback_class_name: 对象表达式非 Name 时从 LLVM 类型解析出的类名兜底。 @@ -196,12 +181,7 @@ novirtual class CallGenProp(CallGenBase.CallGenBase): # ============================================================ # ============================================================ - def _try_property_setter(self, pool: memhub.MemBuddy*, - builder: mlirlite.IRBuilder*, - mod: mlirlite.LLVMModule*, - target_attr: ast.Attribute*, - rhs_val: mlirlite.Value*, - trans: HT.Translator*) -> int: + def _try_property_setter(self, pool: memhub.MemBuddy*, builder: mlirlite.IRBuilder*, mod: mlirlite.LLVMModule*, target_attr: ast.Attribute*, rhs_val: mlirlite.Value*, trans: HT.Translator*) -> int: """尝试 property setter 赋值,返回 1=已处理(生成调用)""" if pool is None or builder is None or mod is None or trans is None: return 0 if target_attr is None or target_attr.attr is None or rhs_val is None: return 0 @@ -220,8 +200,7 @@ novirtual class CallGenProp(CallGenBase.CallGenBase): setter_name_buf: str = pool.alloc(128) if setter_name_buf is None: return 0 viperlib.snprintf(setter_name_buf, 128, "%s$set", target_attr.attr) - self._translate_property_call(pool, builder, mod, class_name, - setter_name_buf, obj_val, 2, trans) + self._translate_property_call(pool, builder, mod, class_name, setter_name_buf, obj_val, 2, trans) return 1 # ============================================================ # _try_property_deleter — 尝试将 del obj.attr 翻译为 property deleter 调用 @@ -231,11 +210,7 @@ novirtual class CallGenProp(CallGenBase.CallGenBase): # ============================================================ # ============================================================ - def _try_property_deleter(self, pool: memhub.MemBuddy*, - builder: mlirlite.IRBuilder*, - mod: mlirlite.LLVMModule*, - target_attr: ast.Attribute*, - trans: HT.Translator*) -> int: + def _try_property_deleter(self, pool: memhub.MemBuddy*, builder: mlirlite.IRBuilder*, mod: mlirlite.LLVMModule*, target_attr: ast.Attribute*, trans: HT.Translator*) -> int: """尝试 property deleter 删除,返回 1=已处理(生成调用)""" if pool is None or builder is None or mod is None or trans is None: return 0 if target_attr is None or target_attr.attr is None: return 0 @@ -251,8 +226,7 @@ novirtual class CallGenProp(CallGenBase.CallGenBase): del_name_buf: str = pool.alloc(128) if del_name_buf is None: return 0 viperlib.snprintf(del_name_buf, 128, "%s$del", target_attr.attr) - self._translate_property_call(pool, builder, mod, class_name, - del_name_buf, obj_val, 1, trans) + self._translate_property_call(pool, builder, mod, class_name, del_name_buf, obj_val, 1, trans) return 1 # ============================================================ # _translate_static_class_call — 翻译 ClassName.method(args) 静态/类方法调用 @@ -262,13 +236,7 @@ novirtual class CallGenProp(CallGenBase.CallGenBase): # ============================================================ # ============================================================ - def _translate_static_class_call(self, pool: memhub.MemBuddy*, - builder: mlirlite.IRBuilder*, - mod: mlirlite.LLVMModule*, - class_name: str, - method_name: str, - cl: ast.Call*, - trans: HT.Translator*) -> mlirlite.Value*: + def _translate_static_class_call(self, pool: memhub.MemBuddy*, builder: mlirlite.IRBuilder*, mod: mlirlite.LLVMModule*, class_name: str, method_name: str, cl: ast.Call*, trans: HT.Translator*) -> mlirlite.Value*: """翻译类名静态/类方法调用,返回 call 结果 Value;非静态/类方法返回 None""" if pool is None or builder is None or mod is None or trans is None: return None if class_name is None or method_name is None or cl is None: return None @@ -332,8 +300,7 @@ novirtual class CallGenProp(CallGenBase.CallGenBase): # ============================================================ # ============================================================ - def _is_list_builtin_method(self, class_name: str, - method_name: str) -> int: + def _is_list_builtin_method(self, class_name: str, method_name: str) -> int: """判断 (class_name, method_name) 是否是 list 泛型内置方法""" if class_name is None or method_name is None: return 0 # 类名必须以 "list" 开头(list / list[AST*] 特化名) @@ -364,10 +331,7 @@ novirtual class CallGenProp(CallGenBase.CallGenBase): return name + pfx if pfx != 0 else name # _resolve_generic_receiver_name:解析接收者实际泛型特化名(IR 真值)——接收者实际 LLVM 结构体类型名比可能退化的注解/注册名可靠,故泛型判定以此为准:去 sha1 前缀取 '[' 前基名,基名是已注册泛型模板时含类型实参 ⇒ 返回实际特化名,无类型实参 ⇒ fail-fast(D25);基名非泛型模板或实际类型不可得 ⇒ 返回 None(调用方各自回退)。与 CallGenCall._translate_method_call 的 D25 分派修复共用本函数(唯一口径) - def _resolve_generic_receiver_name(self, pool: memhub.MemBuddy*, - struct_ty: mlirlite.LLVMType*, - method_name: str, - cl: ast.Call*) -> str: + def _resolve_generic_receiver_name(self, pool: memhub.MemBuddy*, struct_ty: mlirlite.LLVMType*, method_name: str, cl: ast.Call*) -> str: """返回实际泛型特化名(去 sha1)或 None;裸泛型基类 fail-fast""" if struct_ty is None: return None ty_nm: str = mlirlite.get_struct_name(struct_ty) @@ -386,21 +350,11 @@ novirtual class CallGenProp(CallGenBase.CallGenBase): if self.Gen.ClassGenGeneric._find_generic_template(base_nm) is None: return None if lb is not None: return short_nm # 裸泛型基类(无类型实参):接收者元素类型未知 → fail-fast(D25 口径) - self.Gen.TypeGenErr.fatal_error( - cl, - f"方法 '{method_name}' 的接收者实际结构体类型是裸泛型基类 " - f"'{short_nm}*'(丢失类型实参),元素类型未知;" - f"禁止静默按默认元素类型处理(元素按 i32 处理会截断指针)," - f"请让该变量的注解/类型带上实参(如 list[ast.AST*])", - "TypeError") + self.Gen.TypeGenErr.fatal_error(cl, f"方法 '{method_name}' 的接收者实际结构体类型是裸泛型基类 " f"'{short_nm}*'(丢失类型实参),元素类型未知;" f"禁止静默按默认元素类型处理(元素按 i32 处理会截断指针)," f"请让该变量的注解/类型带上实参(如 list[ast.AST*])", "TypeError") return None # _is_list_builtin_receiver:基于接收者实际类型判定 list 内建方法,判据与 _resolve_generic_receiver_name 同源——优先采用接收者实际 LLVM 结构体类型名(去 sha1 判基名),不可得时回退注解名/注册名判定。返回 1=list 内置方法 / 0=非 - def _is_list_builtin_receiver(self, pool: memhub.MemBuddy*, - recv_val: mlirlite.Value*, - fallback_name: str, - method_name: str, - cl: ast.Call*) -> int: + def _is_list_builtin_receiver(self, pool: memhub.MemBuddy*, recv_val: mlirlite.Value*, fallback_name: str, method_name: str, cl: ast.Call*) -> int: """基于接收者实际类型判定 list 内建方法(实际类型不可得回退注解名)""" sty: mlirlite.LLVMType* = self.Gen.StructGen.get_struct_type_from_value(recv_val) if sty is not None: diff --git a/App/lib/core/Gen/Call/CallGenVa.vp b/App/lib/core/Gen/Call/CallGenVa.vp index 5a1d904..a68f962 100644 --- a/App/lib/core/Gen/Call/CallGenVa.vp +++ b/App/lib/core/Gen/Call/CallGenVa.vp @@ -22,13 +22,7 @@ novirtual class CallGenVa(CallGenBase.CallGenBase): # _translate_method 在含 raise 的函数签名末尾注入(main 除外)。 # ============================================================ - def _va_arg_get_alloca_ptr(self, pool: memhub.MemBuddy*, - builder: mlirlite.IRBuilder*, - mod: mlirlite.LLVMModule*, - arg_node: ast.AST*, - funcs_ptr: t.CPtr, - func_count: int, - trans: HT.Translator*) -> mlirlite.Value*: + def _va_arg_get_alloca_ptr(self, pool: memhub.MemBuddy*, builder: mlirlite.IRBuilder*, mod: mlirlite.LLVMModule*, arg_node: ast.AST*, funcs_ptr: t.CPtr, func_count: int, trans: HT.Translator*) -> mlirlite.Value*: """获取 va_list 变量的 alloca 指针(不 load) va_arg/va_start/va_end 需要的是 va_list 对象的地址(alloca 指针), @@ -44,9 +38,7 @@ novirtual class CallGenVa(CallGenBase.CallGenBase): if alloca is not None: 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*, - type_node: ast.AST*, - trans: HT.Translator*) -> mlirlite.LLVMType*: + def _resolve_va_arg_type(self, pool: memhub.MemBuddy*, type_node: ast.AST*, trans: HT.Translator*) -> mlirlite.LLVMType*: """解析 va_arg/arg 的类型参数为 LLVMType 支持的类型表达式: @@ -64,15 +56,7 @@ novirtual class CallGenVa(CallGenBase.CallGenBase): # 类型节点存在但解析失败:fail-fast,绝不回退 i32(会按错宽度读变参槽位) self.Gen.TypeGenErr.fatal_error(type_node, "va_arg 类型解析失败", "TypeError") return mlirlite.Int32(pool) - def _translate_va_arg_sugar(self, pool: memhub.MemBuddy*, - builder: mlirlite.IRBuilder*, - mod: mlirlite.LLVMModule*, - cl: ast.Call*, - cargs: list[ast.AST*]*, - can: sizet, - funcs_ptr: t.CPtr, - func_count: int, - trans: HT.Translator*) -> mlirlite.Value*: + def _translate_va_arg_sugar(self, pool: memhub.MemBuddy*, builder: mlirlite.IRBuilder*, mod: mlirlite.LLVMModule*, cl: ast.Call*, cargs: list[ast.AST*]*, can: sizet, funcs_ptr: t.CPtr, func_count: int, trans: HT.Translator*) -> mlirlite.Value*: """va_arg(ap, type) / va_arg(ap) → %N = va_arg , 生成 LLVM va_arg 指令,从 va_list 读取下一个变长参数。 @@ -108,15 +92,7 @@ novirtual class CallGenVa(CallGenBase.CallGenBase): # 生成 va_arg 指令 return mlirlite.build_va_arg(builder, ap_ptr, read_ty) - def _translate_arg_sugar(self, pool: memhub.MemBuddy*, - builder: mlirlite.IRBuilder*, - mod: mlirlite.LLVMModule*, - cl: ast.Call*, - cargs: list[ast.AST*]*, - can: sizet, - funcs_ptr: t.CPtr, - func_count: int, - trans: HT.Translator*) -> mlirlite.Value*: + def _translate_arg_sugar(self, pool: memhub.MemBuddy*, builder: mlirlite.IRBuilder*, mod: mlirlite.LLVMModule*, cl: ast.Call*, cargs: list[ast.AST*]*, can: sizet, funcs_ptr: t.CPtr, func_count: int, trans: HT.Translator*) -> mlirlite.Value*: """arg(type) → %N = va_arg , 使用当前函数的隐式 va_list(trans._va_list_ptr), @@ -142,14 +118,7 @@ novirtual class CallGenVa(CallGenBase.CallGenBase): # 生成 va_arg 指令(使用 trans._va_list_ptr 作为 va_list 地址) return mlirlite.build_va_arg(builder, trans._va_list_ptr, read_ty) - def _translate_va_start_sugar(self, pool: memhub.MemBuddy*, - builder: mlirlite.IRBuilder*, - mod: mlirlite.LLVMModule*, - cargs: list[ast.AST*]*, - can: sizet, - funcs_ptr: t.CPtr, - func_count: int, - trans: HT.Translator*) -> mlirlite.Value*: + def _translate_va_start_sugar(self, pool: memhub.MemBuddy*, builder: mlirlite.IRBuilder*, mod: mlirlite.LLVMModule*, cargs: list[ast.AST*]*, can: sizet, funcs_ptr: t.CPtr, func_count: int, trans: HT.Translator*) -> mlirlite.Value*: """va_start(ap, last_arg) → call void @llvm.va_start(i8* %ap) 初始化 va_list。第二个参数 last_arg 在 LLVM intrinsic 中不使用(C 宏兼容)。 @@ -170,14 +139,7 @@ novirtual class CallGenVa(CallGenBase.CallGenBase): void_ty_vs: mlirlite.LLVMType* = mlirlite.Void(pool) mlirlite.build_call(builder, "llvm.va_start", ap_i8, 1, void_ty_vs, 0) return mlirlite.const_int32(pool, 0) - def _translate_va_end_sugar(self, pool: memhub.MemBuddy*, - builder: mlirlite.IRBuilder*, - mod: mlirlite.LLVMModule*, - cargs: list[ast.AST*]*, - can: sizet, - funcs_ptr: t.CPtr, - func_count: int, - trans: HT.Translator*) -> mlirlite.Value*: + def _translate_va_end_sugar(self, pool: memhub.MemBuddy*, builder: mlirlite.IRBuilder*, mod: mlirlite.LLVMModule*, cargs: list[ast.AST*]*, can: sizet, funcs_ptr: t.CPtr, func_count: int, trans: HT.Translator*) -> mlirlite.Value*: """va_end(ap) → call void @llvm.va_end(i8* %ap) 清理 va_list。在大多数平台上是 no-op,但调用它是良好的 C ABI 习惯。 @@ -221,8 +183,7 @@ novirtual class CallGenVa(CallGenBase.CallGenBase): if string.strcmp(name, "vsprintf") == 0: return 2 return -1 - def _get_known_vararg_cfunc_param_ty(self, pool: memhub.MemBuddy*, - name: str, idx: int) -> mlirlite.LLVMType*: + def _get_known_vararg_cfunc_param_ty(self, pool: memhub.MemBuddy*, name: str, idx: int) -> mlirlite.LLVMType*: """已知变参 C 库函数第 idx 个固定参数类型(变参位置/未知返回 None) 固定参数类型是 C ABI 硬约束(snprintf 的 size 为 i64),stub 未注入 @@ -241,15 +202,7 @@ novirtual class CallGenVa(CallGenBase.CallGenBase): if idx == 1: return i8_ptr_kv return None return None - def _check_and_promote_variadic_call(self, pool: memhub.MemBuddy*, - builder: mlirlite.IRBuilder*, - mod: mlirlite.LLVMModule*, - call_name: str, - head: mlirlite.Value*, - can: sizet, - arg_nodes: list[ast.AST*]* = None, - self_offset: int = 0, - trans: HT.Translator* = None) -> int: + def _check_and_promote_variadic_call(self, pool: memhub.MemBuddy*, builder: mlirlite.IRBuilder*, mod: mlirlite.LLVMModule*, call_name: str, head: mlirlite.Value*, can: sizet, arg_nodes: list[ast.AST*]* = None, self_offset: int = 0, trans: HT.Translator* = None) -> int: """检查被调用函数是否为变长函数,若是则对变长参数进行 C ABI 提升 返回: is_variadic (1=变长调用, 0=普通调用) diff --git a/App/lib/core/Gen/Call/CallGenVt.vp b/App/lib/core/Gen/Call/CallGenVt.vp index 643f0f7..56e6d01 100644 --- a/App/lib/core/Gen/Call/CallGenVt.vp +++ b/App/lib/core/Gen/Call/CallGenVt.vp @@ -20,14 +20,7 @@ novirtual class CallGenVt(CallGenBase.CallGenBase): # _write_vtable_slot / _write_vtable_attr:把模块级函数指针写入对象 vtable 的方法槽位(devfs 驱动注册模式,对齐 TPC HandlesAssign.py L905-949 写时复制)——vtable 方法不是数据字段,get_attribute_ptr 查不到;对象 vtable 仍指向类默认 vtable 时先复制一份(internal 全局 + llvm.memcpy)并让对象指向副本,再 GEP method_index 槽位 store i8*。多次写入互不覆盖 # ============================================================ - def _write_vtable_slot(self, pool: memhub.MemBuddy*, - builder: mlirlite.IRBuilder*, - mod: mlirlite.LLVMModule*, - obj_ptr: mlirlite.Value*, - class_name: str, - method_index: int, - func_val: mlirlite.Value*, - trans: HT.Translator*) -> int: + def _write_vtable_slot(self, pool: memhub.MemBuddy*, builder: mlirlite.IRBuilder*, mod: mlirlite.LLVMModule*, obj_ptr: mlirlite.Value*, class_name: str, method_index: int, func_val: mlirlite.Value*, trans: HT.Translator*) -> int: """生成 vtable 槽位写入(写时复制),成功返回 1""" if pool is None or builder is None or mod is None or trans is None: return 0 if obj_ptr is None or class_name is None or func_val is None: return 0 @@ -119,12 +112,7 @@ novirtual class CallGenVt(CallGenBase.CallGenBase): fptr_i8: mlirlite.Value* = mlirlite.build_bitcast(builder, func_val, i8_ptr_ty) if fptr_i8 is not None: mlirlite.build_store(builder, fptr_i8, vt_slotp) return 1 - def _write_vtable_attr(self, builder: mlirlite.IRBuilder*, - pool: memhub.MemBuddy*, - mod: mlirlite.LLVMModule*, - node: ast.AST*, - rhs_val: mlirlite.Value*, - trans: HT.Translator*) -> int: + def _write_vtable_attr(self, builder: mlirlite.IRBuilder*, pool: memhub.MemBuddy*, mod: mlirlite.LLVMModule*, node: ast.AST*, rhs_val: mlirlite.Value*, trans: HT.Translator*) -> int: """属性写入 obj.method = func:检测 vtable 方法并生成槽位写入(成功返回 1)""" if node is None or builder is None or pool is None or mod is None: return 0 if rhs_val is None or trans is None: return 0 diff --git a/App/lib/core/Gen/Class/ClassGenBase.vp b/App/lib/core/Gen/Class/ClassGenBase.vp index 0516950..b0ada3e 100644 --- a/App/lib/core/Gen/Class/ClassGenBase.vp +++ b/App/lib/core/Gen/Class/ClassGenBase.vp @@ -156,8 +156,7 @@ novirtual class ClassGenBase: # 本模块函数调用改 self.,外部模块调用保留模块前缀) # ============================================================ - def _is_cenum_base(self, base_node: ast.AST*, - trans: HT.Translator* = None) -> int: + def _is_cenum_base(self, base_node: ast.AST*, trans: HT.Translator* = None) -> int: """检查 base 节点是否为 t.CEnum,返回 1=是 / 0=否""" if base_node is None: return 0 k: int = base_node.kind() @@ -181,8 +180,7 @@ novirtual class ClassGenBase: if at.attr is not None and string.strcmp(at.attr, "CEnum") == 0: return 1 return 0 return 0 - def _is_enum_class(self, cd: ast.ClassDef*, - trans: HT.Translator* = None) -> int: + def _is_enum_class(self, cd: ast.ClassDef*, trans: HT.Translator* = None) -> int: """检查 ClassDef 是否为 CEnum:继承自 t.CEnum 或 @t.CEnum 装饰器形式""" if cd is None: return 0 # 装饰器形式: @t.CEnum class Color:(无基类,等价 class Color(t.CEnum):) @@ -197,8 +195,7 @@ novirtual class ClassGenBase: if base_node is None: continue if self._is_cenum_base(base_node, trans) == 1: return 1 return 0 - def _is_cunion_base(self, base_node: ast.AST*, - trans: HT.Translator* = None) -> int: + def _is_cunion_base(self, base_node: ast.AST*, trans: HT.Translator* = None) -> int: """检查 base 节点是否为 t.CUnion,返回 1=是 / 0=否""" if base_node is None: return 0 k: int = base_node.kind() @@ -221,8 +218,7 @@ novirtual class ClassGenBase: if at.attr is not None and string.strcmp(at.attr, "CUnion") == 0: return 1 return 0 return 0 - def _is_union_class(self, cd: ast.ClassDef*, - trans: HT.Translator* = None) -> int: + def _is_union_class(self, cd: ast.ClassDef*, trans: HT.Translator* = None) -> int: """检查 ClassDef 是否为 CUnion:继承自 t.CUnion 或 @t.CUnion 装饰器形式""" if cd is None: return 0 # 装饰器形式: @t.CUnion class Data: @@ -237,8 +233,7 @@ novirtual class ClassGenBase: if base_node is None: continue if self._is_cunion_base(base_node, trans) == 1: return 1 return 0 - def _is_crenum_base(self, base_node: ast.AST*, - trans: HT.Translator* = None) -> int: + def _is_crenum_base(self, base_node: ast.AST*, trans: HT.Translator* = None) -> int: """检查 base 节点是否为 t.REnum,返回 1=是 / 0=否""" if base_node is None: return 0 k: int = base_node.kind() @@ -261,8 +256,7 @@ novirtual class ClassGenBase: if at.attr is not None and string.strcmp(at.attr, "REnum") == 0: return 1 return 0 return 0 - def _is_renum_class(self, cd: ast.ClassDef*, - trans: HT.Translator* = None) -> int: + def _is_renum_class(self, cd: ast.ClassDef*, trans: HT.Translator* = None) -> int: """检查 ClassDef 是否为 REnum:继承自 t.REnum 或 @t.REnum 装饰器形式""" if cd is None: return 0 # 装饰器形式: @t.REnum class X: @@ -277,8 +271,7 @@ novirtual class ClassGenBase: if base_node is None: continue if self._is_crenum_base(base_node, trans) == 1: return 1 return 0 - def _has_decorator(self, decorator_list: list[ast.AST*]*, - deco_name: str) -> int: + def _has_decorator(self, decorator_list: list[ast.AST*]*, deco_name: str) -> int: """检查 decorator_list 中是否有指定装饰器名""" if decorator_list is None: return 0 dn: sizet = len(decorator_list) @@ -316,8 +309,7 @@ novirtual class ClassGenBase: if at2.attr is None: return 0 return 1 if string.strcmp(at2.attr, attr_name) == 0 else 0 return 0 - def _class_has_tattr(self, decorator_list: list[ast.AST*]*, - attr_name: str) -> int: + def _class_has_tattr(self, decorator_list: list[ast.AST*]*, attr_name: str) -> int: """检查装饰器列表是否含 t.attr.(@c.Attribute(t.attr.xxx) 或 @t.attr.xxx)。 覆盖 packed/aligned/naked/section 等所有 t.attr 属性(B5)。 @@ -416,8 +408,7 @@ novirtual class ClassGenBase: elif string.strcmp(at.attr, "getter") == 0: meta |= GenTypes.META_PROP_GETTER elif string.strcmp(at.attr, "deleter") == 0: meta |= GenTypes.META_PROP_DELETER return meta - def register_class_meta(self, pool: memhub.MemBuddy*, - kind: int, cls: str, field: str) -> int: + def register_class_meta(self, pool: 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: return -1 if self.ClassMetaKinds is None: @@ -461,9 +452,7 @@ novirtual class ClassGenBase: if n_cm2 == idx: return self.ClassMetaFields + i * 64 n_cm2 += 1 return None - def register_decorator(self, pool: memhub.MemBuddy*, - func_name: str, wrapper_name: str, - arg0: int64) -> int: + def register_decorator(self, pool: memhub.MemBuddy*, func_name: str, wrapper_name: str, arg0: int64) -> int: """注册自定义装饰器函数(@log/@skip/@repeat(3) → __decor_wrap_{name}) 对齐 TPC HandlesFunctions.py L1621-1631 的 _decorated_funcs 注册。 @@ -580,8 +569,7 @@ novirtual class ClassGenBase: for i in range(self.ExceptionCount): if string.strcmp(self.ExceptionNames + i * EXCEPTION_NAME_LEN, name) == 0: return 1 return 0 - def collect_descendant_codes(self, name: str, out_codes: int*, - max_codes: int) -> int: + def collect_descendant_codes(self, name: str, out_codes: int*, max_codes: int) -> int: """把 name 及其所有子孙异常类的编码收集到 out_codes,返回数量 (对齐 TPC HandlesTry.py _get_all_match_codes/_collect_descendant_codes: 编译期静态展开继承树,except X 匹配 X 及全部子孙)。""" @@ -589,8 +577,7 @@ novirtual class ClassGenBase: self._exception_codes_tmp_count = 0 self._collect_desc_codes_rec(name, out_codes, max_codes, 0) return self._exception_codes_tmp_count - def _collect_desc_codes_rec(self, name: str, out_codes: int*, - max_codes: int, depth: int) -> None: + def _collect_desc_codes_rec(self, name: str, out_codes: int*, max_codes: int, depth: int) -> None: """递归收集 name 编码 + 全部子孙编码(BFS 语义对齐 TPC)""" if depth > 32: return code_e: int = self.lookup_exception_code(name) @@ -644,15 +631,13 @@ novirtual class ClassGenBase: if base_name_e2 is None: continue if string.strcmp(base_name_e2, "Exception") != 0 and self.is_exception_name(base_name_e2) != 0: return base_name_e2 return None - def _register_exception_class_def(self, trans: HT.Translator*, - cd: ast.ClassDef*) -> int: + def _register_exception_class_def(self, trans: HT.Translator*, cd: ast.ClassDef*) -> int: """注册异常类(分配编码 + 记录父类),不生成 struct,返回 0""" if cd is None or cd.name is None: return 0 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*, - kind: int, cls: str, value_node: ast.AST*) -> None: + def _register_class_meta_list(self, pool: memhub.MemBuddy*, kind: int, cls: str, value_node: ast.AST*) -> None: """解析类体 __provides__/__requires__ 的 list[str] 字面量并注册""" if value_node is None or cls is None: return if value_node.kind() != ast.ASTKind.List: return @@ -665,8 +650,7 @@ novirtual class ClassGenBase: if el_rcm is None or el_rcm.kind() != ast.ASTKind.Constant: continue ec_rcm: ast.Constant* = ast.Constant*(el_rcm) if ec_rcm.str_val is not None: self.register_class_meta(pool, kind, cls, ec_rcm.str_val) - def register_method_meta(self, class_name: str, method_name: str, - meta: int) -> None: + def register_method_meta(self, class_name: str, method_name: str, meta: int) -> None: """注册方法元数据(幂等)""" if class_name is None or method_name is None or meta == 0: return # 懒初始化 @@ -697,8 +681,7 @@ novirtual class ClassGenBase: return if self.MethodMetaCount < META_MAX: # 槽位定长 META_KEY_LEN=128 字节,key 超长时 strncpy 钳制防越界写相邻槽 - string.strncpy(self.MethodMetaKeys + self.MethodMetaCount * META_KEY_LEN, - key_buf, META_KEY_LEN - 1) + string.strncpy(self.MethodMetaKeys + self.MethodMetaCount * META_KEY_LEN, key_buf, META_KEY_LEN - 1) flags_ptr2: t.CPtr = (int*)(uint64(self.MethodMetaFlags) + self.MethodMetaCount * 4) flags_ptr2[0] = meta self.MethodMetaCount += 1 @@ -744,9 +727,7 @@ novirtual class ClassGenBase: if string.strcmp(base_name, "CUnion") == 0: return 1 if string.strcmp(base_name, "REnum") == 0: return 1 return 0 - def _get_base_name(self, base_node: ast.AST*, - pool: memhub.MemBuddy* = None, - from_imports: str = None) -> str: + def _get_base_name(self, base_node: ast.AST*, pool: memhub.MemBuddy* = None, from_imports: str = None) -> str: """从 base AST 节点提取基类名,返回 None=失败 对于 Subscript 节点,需要 pool 分配内存拼接特化名; @@ -801,8 +782,7 @@ novirtual class ClassGenBase: string.strcat(mangled, "]") return mangled return None - def _get_parent_class(self, cd: ast.ClassDef*, - trans: HT.Translator* = None) -> str: + def _get_parent_class(self, cd: ast.ClassDef*, trans: HT.Translator* = None) -> str: """获取 ClassDef 的真实父类名,返回 None=无真实父类""" if cd is None or cd.bases is None: return None pool: memhub.MemBuddy* = None @@ -822,8 +802,7 @@ novirtual class ClassGenBase: bname = self._resolve_base_alias(bname, trans) if self._is_marker_base(bname) == 0: return bname return None - def _resolve_base_alias(self, base_name: str, - trans: HT.Translator* = None) -> str: + def _resolve_base_alias(self, base_name: str, trans: HT.Translator* = None) -> str: """解析基类别名:from t import CStruct as cs → 基类 cs 实际是 CStruct。 别名不解析时 "cs" 会被当作真实父类名 → find_struct("cs") 失败 → @@ -847,11 +826,7 @@ novirtual class ClassGenBase: og_buf[og_len] = '\0' return og_buf return base_name - def _collect_parents(self, pool: memhub.MemBuddy*, - cd: ast.ClassDef*, - parents_buf: sizet*, - max_parents: int, - trans: HT.Translator* = None) -> int: + def _collect_parents(self, pool: memhub.MemBuddy*, cd: ast.ClassDef*, parents_buf: sizet*, max_parents: int, trans: HT.Translator* = None) -> int: """收集所有非 marker 父类名到 parents_buf,返回数量""" if pool is None or cd is None or cd.bases is None or parents_buf is None: return 0 bases: list[ast.AST*]* = cd.bases @@ -871,8 +846,7 @@ novirtual class ClassGenBase: parents_buf[count] = sizet(bname) count += 1 return count - def _field_name_exists(self, names_buf: sizet*, - count: int, name: str) -> int: + def _field_name_exists(self, names_buf: sizet*, count: int, name: str) -> int: """检查字段名是否已在 names_buf 中(先声明父类优先,重复跳过)""" if names_buf is None or name is None: return 0 for fi in range(count): @@ -890,8 +864,7 @@ novirtual class ClassGenBase: if stmt is None: continue if stmt.kind() == ast.ASTKind.AnnAssign: return 1 return 0 - def _trigger_base_specialization(self, trans: HT.Translator*, - cd: ast.ClassDef*): + def _trigger_base_specialization(self, trans: HT.Translator*, cd: ast.ClassDef*): """触发 base 中 Subscript 的泛型特化(如 GSListNode[Value])""" if trans is None or cd is None or cd.bases is None: return pool: memhub.MemBuddy* = trans.Pool @@ -941,9 +914,7 @@ novirtual class ClassGenBase: if fd.decorator_list is not None: if self._has_decorator(fd.decorator_list, "CVTable") == 1: return 1 return 0 - def _should_method_be_virtual(self, cd: ast.ClassDef*, - fd: ast.FunctionDef*, - trans: HT.Translator* = None) -> int: + def _should_method_be_virtual(self, cd: ast.ClassDef*, fd: ast.FunctionDef*, trans: HT.Translator* = None) -> int: """判断方法是否应该进入虚表,返回 1=包含 / 0=排除""" if fd is None: return 0 # 1. 检查函数级 @t.NoVTable(最高优先级,排除) @@ -980,8 +951,7 @@ novirtual class ClassGenBase: # 5. 默认排除 return 0 - def _detect_vtable_status(self, cd: ast.ClassDef*, - trans: HT.Translator* = None) -> int: + def _detect_vtable_status(self, cd: ast.ClassDef*, trans: HT.Translator* = None) -> int: """检测类是否应该启用虚表""" if cd is None: return 0 diff --git a/App/lib/core/Gen/Class/ClassGenDef.vp b/App/lib/core/Gen/Class/ClassGenDef.vp index baf79d8..5169da3 100644 --- a/App/lib/core/Gen/Class/ClassGenDef.vp +++ b/App/lib/core/Gen/Class/ClassGenDef.vp @@ -23,8 +23,7 @@ novirtual class ClassGenDef(ClassGenBase.ClassGenBase): # ============================================================ # translate_class_def — 翻译 class 定义(簇 D) # ============================================================ - def translate_class_def(self, trans: HT.Translator*, - node: ast.AST*) -> int: + def translate_class_def(self, trans: HT.Translator*, node: ast.AST*) -> int: """翻译 class 定义,返回 0""" if node is None or trans is None: return 0 @@ -55,11 +54,7 @@ novirtual class ClassGenDef(ClassGenBase.ClassGenBase): # ⇒ _is_renum_class_name 恒 0、变体构造拿不到 tag。两者语义互斥,禁止静默按枚举处理。 if self.Gen.ClassGenBase._is_enum_class(cd, trans) == 1: if self.Gen.ClassGenBase._is_renum_class(cd, trans) == 1: - self.Gen.TypeGenErr.fatal_error( - cd, - f"类 '{class_name}' 同时被判定为 CEnum 与 REnum(分派歧义)," - f"REnum 变体表将无法注册", - "TypeError") + self.Gen.TypeGenErr.fatal_error(cd, f"类 '{class_name}' 同时被判定为 CEnum 与 REnum(分派歧义)," f"REnum 变体表将无法注册", "TypeError") return self.Gen.ClassGenEnum._translate_enum_def(trans, cd) # 联合体类:交给联合体处理 @@ -670,8 +665,7 @@ novirtual class ClassGenDef(ClassGenBase.ClassGenBase): # 内层 mark_module_class 覆盖)——不还原会让外层随后的字段注解解析误判 # "当前定义类"(规则 5.5 的自引用窗口据此判定,误判会冻结裸名票名)。 # ============================================================ - def _translate_nested_classdefs(self, trans: HT.Translator*, - cd: ast.ClassDef*) -> None: + def _translate_nested_classdefs(self, trans: HT.Translator*, cd: ast.ClassDef*) -> None: """把本类体内的嵌套 ClassDef 逐个按 `{外类}_{内类}` 递归翻译""" if trans is None or cd is None or cd.name is None: return children: list[ast.AST*]* = cd.children diff --git a/App/lib/core/Gen/Class/ClassGenEnum.vp b/App/lib/core/Gen/Class/ClassGenEnum.vp index 0a024b6..fd9da00 100644 --- a/App/lib/core/Gen/Class/ClassGenEnum.vp +++ b/App/lib/core/Gen/Class/ClassGenEnum.vp @@ -29,10 +29,7 @@ define RENUM_ALIAS_MAX = 512 novirtual class ClassGenEnum(ClassGenBase.ClassGenBase): """enum/union/renum 定义与变体表""" - def _resolve_enum_member_type(self, pool: memhub.MemBuddy*, - ann_node: ast.AST*, - imported_modules: str, - from_imports: str) -> mlirlite.LLVMType*: + def _resolve_enum_member_type(self, pool: memhub.MemBuddy*, ann_node: ast.AST*, imported_modules: str, from_imports: str) -> mlirlite.LLVMType*: """解析枚举成员的类型注解为 LLVM 整数类型""" if ann_node is None: return mlirlite.Int32(pool) @@ -265,8 +262,7 @@ novirtual class ClassGenEnum(ClassGenBase.ClassGenBase): tgt: ast.AST* = ag.targets.get(ti) if tgt is not None and tgt.kind() != ast.ASTKind.Name and self._enum_target_visible_names(tgt) > 0: return stmt return None - def _translate_enum_def(self, trans: HT.Translator*, - cd: ast.ClassDef*) -> int: + def _translate_enum_def(self, trans: HT.Translator*, cd: ast.ClassDef*) -> int: """翻译枚举类定义,返回 0""" if cd is None or cd.name is None or trans is None: return 0 @@ -395,18 +391,7 @@ novirtual class ClassGenEnum(ClassGenBase.ClassGenBase): bad: ast.AST* = self._enum_first_unregistered_node(children) bad_desc: str = "(无法定位到具体语句,请检查枚举体)" if bad is not None: bad_desc = bad.type_name() - self.Gen.TypeGenErr.fatal_error( - bad if bad is not None else cd, - f"枚举 '{class_name}' 成员登记数不一致:源码里可见的成员名 {visible_count} 个," - f"实际只登记 {member_count} 个(差额 {diff_count} 个会被静默丢弃)。" - f"未识别的成员写法(首个): {bad_desc} 形态的语句——如逗号组带值 `A, B = 1`、" - f"逗号组带注解 `A, B: T`、单名尾随逗号 `A,`。" - f"期望形态: 每行一个 `Name` / `Name: T` / `Name = 值`," - f"或多个简单标识符用逗号分隔(`A, B, C`,可带尾随逗号)。" - f"修法: 把该行改写为逐个成员一行,或改写为纯标识符逗号组(去掉 `= 值` / `: T`)。" - f"(本判据在注册处比对『可见名数 vs 登记数』,任何未识别形态都会命中," - f"不再静默丢成员)", - "TypeError") + self.Gen.TypeGenErr.fatal_error(bad if bad is not None else cd, f"枚举 '{class_name}' 成员登记数不一致:源码里可见的成员名 {visible_count} 个," f"实际只登记 {member_count} 个(差额 {diff_count} 个会被静默丢弃)。" f"未识别的成员写法(首个): {bad_desc} 形态的语句——如逗号组带值 `A, B = 1`、" f"逗号组带注解 `A, B: T`、单名尾随逗号 `A,`。" f"期望形态: 每行一个 `Name` / `Name: T` / `Name = 值`," f"或多个简单标识符用逗号分隔(`A, B, C`,可带尾随逗号)。" f"修法: 把该行改写为逐个成员一行,或改写为纯标识符逗号组(去掉 `= 值` / `: T`)。" f"(本判据在注册处比对『可见名数 vs 登记数』,任何未识别形态都会命中," f"不再静默丢成员)", "TypeError") return 0 if member_count == 0: @@ -522,8 +507,7 @@ novirtual class ClassGenEnum(ClassGenBase.ClassGenBase): return max_align case _: return 8 - def _translate_union_def(self, trans: HT.Translator*, - cd: ast.ClassDef*) -> int: + def _translate_union_def(self, trans: HT.Translator*, cd: ast.ClassDef*) -> int: """翻译联合体定义,返回 0""" if cd is None or cd.name is None or trans is None: return 0 @@ -659,8 +643,7 @@ novirtual 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*, - annotation: ast.AST*) -> int: + def _get_annotation_field_size(self, pool: memhub.MemBuddy*, annotation: ast.AST*) -> int: """计算注解类型的字节大小,用于 REnum 布局计算""" if annotation is None: return 8 k: int = annotation.kind() @@ -701,8 +684,7 @@ novirtual class ClassGenEnum(ClassGenBase.ClassGenBase): if sz > 0: return sz # 未注册类型 → 默认指针大小 8(可能是自引用或前向引用) return 8 - def _translate_renum_def(self, trans: HT.Translator*, - cd: ast.ClassDef*) -> int: + def _translate_renum_def(self, trans: HT.Translator*, cd: ast.ClassDef*) -> int: """翻译 REnum 类定义,返回 0""" if cd is None or cd.name is None or trans is None: return 0 @@ -916,10 +898,7 @@ novirtual 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*, - pool: memhub.MemBuddy*, - class_name: str, - cd: ast.ClassDef*): + def _refill_renum_field_types(self, trans: HT.Translator*, pool: memhub.MemBuddy*, class_name: str, cd: ast.ClassDef*): """REnum 注册完成后补解析变体字段类型(仅回填类型槽为 0 的别名记录) 第一遍变体字段遍历发生在 register_struct 之前:字段注解引用本 REnum 类 @@ -967,10 +946,7 @@ novirtual class ClassGenEnum(ClassGenBase.ClassGenBase): # 解析成功 → 触发别名表去重路径(类型槽为 0 时回填;非 0 跳过) if mem_ty_l is not None: self._register_renum_field_alias(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*, - class_name: str, - cd: ast.ClassDef*, - variant_count: int): + def _register_renum_variants(self, pool: memhub.MemBuddy*, class_name: str, cd: ast.ClassDef*, variant_count: int): """注册 REnum 类的变体名和 tag 值到全局变体表""" if pool is None or class_name is None or cd is None: return if variant_count == 0: return @@ -986,8 +962,7 @@ novirtual class ClassGenEnum(ClassGenBase.ClassGenBase): self.RenumClassVariantCounts = CompilerFactory.factory.PermPool.alloc(8 * RENUM_CLASS_MAX) self.RenumVariantNames = CompilerFactory.factory.PermPool.alloc(8 * RENUM_CLASS_MAX * RENUM_VARIANT_PER_CLASS) self.RenumVariantTags = CompilerFactory.factory.PermPool.alloc(8 * RENUM_CLASS_MAX * RENUM_VARIANT_PER_CLASS) - if (self.RenumClassNames is None or self.RenumClassVariantCounts is None - or self.RenumVariantNames is None or self.RenumVariantTags is None): + if (self.RenumClassNames is None or self.RenumClassVariantCounts is None or self.RenumVariantNames is None or self.RenumVariantTags is None): # A None table means the perm-pool request failed (size 0 or pool # exhausted). Returning here left the table empty while the caller # still reported "registered", so match dispatch silently lost every @@ -1152,8 +1127,7 @@ novirtual class ClassGenEnum(ClassGenBase.ClassGenBase): if self.RenumVariantNames is not None and self.RenumClassVariantCounts is not None: n_first_v = self.RenumClassVariantCounts[0] if n_first_v > 0: v_first = str(self.RenumVariantNames[0]) - viperlib.snprintf(buf, 256, "count=%d first=%s vcount=%d vfirst=%s", - self.RenumClassCount, cls_first, n_first_v, v_first) + viperlib.snprintf(buf, 256, "count=%d first=%s vcount=%d vfirst=%s", self.RenumClassCount, cls_first, n_first_v, v_first) return buf def _is_renum_by_entry(self, class_name: str) -> int: @@ -1191,12 +1165,7 @@ novirtual class ClassGenEnum(ClassGenBase.ClassGenBase): if vname is not None and string.strcmp(vname, variant_name) == 0: return self.RenumVariantTags[name_offset] return -1 return -1 - def _register_renum_field_alias(self, pool: memhub.MemBuddy*, - class_name: str, - field_name: str, - payload_idx: int, - field_ty: mlirlite.LLVMType* = None, - variant_name: str = None): + def _register_renum_field_alias(self, pool: memhub.MemBuddy*, class_name: str, field_name: str, payload_idx: int, field_ty: mlirlite.LLVMType* = None, variant_name: str = None): """注册 REnum 变体字段名别名到全局表 field_ty: 变体成员的实际 LLVM 类型(可选;自引用类型如 @@ -1214,9 +1183,7 @@ novirtual class ClassGenEnum(ClassGenBase.ClassGenBase): self.RenumAliasIndex = alias_pool_rfa.alloc(8 * RENUM_ALIAS_MAX) self.RenumAliasTy = alias_pool_rfa.alloc(8 * RENUM_ALIAS_MAX) self.RenumAliasVariant = alias_pool_rfa.alloc(8 * RENUM_ALIAS_MAX) - if (self.RenumAliasClass is None or self.RenumAliasField is None - or self.RenumAliasIndex is None or self.RenumAliasTy is None - or self.RenumAliasVariant is None): + if (self.RenumAliasClass is None or self.RenumAliasField is None or self.RenumAliasIndex is None or self.RenumAliasTy is None or self.RenumAliasVariant is None): # Same as the variant table: a silent bail left the alias table empty, # so match bindings later failed with an unrelated NameError. self.RenumAliasClass = None @@ -1304,8 +1271,7 @@ novirtual class ClassGenEnum(ClassGenBase.ClassGenBase): fld_existing_ptr: str = rawptr(self.RenumAliasField[i]) if fld_existing_ptr is not None and string.strcmp(fld_existing_ptr, field_name) == 0: return self.RenumAliasIndex[i] return -1 - def _lookup_renum_field_alias_ty(self, class_name: str, - field_name: str) -> mlirlite.LLVMType*: + def _lookup_renum_field_alias_ty(self, class_name: str, field_name: str) -> mlirlite.LLVMType*: """查找 REnum 变体成员的实际 LLVM 类型,返回类型或 None 与 _lookup_renum_field_alias 同表同键(class/field 均 strcmp 内容比较)。 @@ -1320,9 +1286,7 @@ novirtual class ClassGenEnum(ClassGenBase.ClassGenBase): if self.RenumAliasTy[i] == 0: return None return (mlirlite.LLVMType*)(self.RenumAliasTy[i]) return None - def _lookup_renum_member_ty(self, class_name: str, - variant_name: str, - payload_idx: int) -> mlirlite.LLVMType*: + def _lookup_renum_member_ty(self, class_name: str, variant_name: str, payload_idx: int) -> mlirlite.LLVMType*: """按 (class, 变体名, payload 位置) 查找变体成员的实际 LLVM 类型 match 绑定用:同一 payload 位置跨变体类型不同(Int.Bits=i32 vs diff --git a/App/lib/core/Gen/Class/ClassGenGeneric.vp b/App/lib/core/Gen/Class/ClassGenGeneric.vp index 20c3fd1..39774fc 100644 --- a/App/lib/core/Gen/Class/ClassGenGeneric.vp +++ b/App/lib/core/Gen/Class/ClassGenGeneric.vp @@ -59,9 +59,7 @@ novirtual class ClassGenGeneric(ClassGenBase.ClassGenBase): if b is None: return s string.strcpy(b, s) return b - def _register_generic_template(self, pool: memhub.MemBuddy*, - cd: ast.ClassDef*, - module_sha1: str) -> None: + def _register_generic_template(self, pool: memhub.MemBuddy*, cd: ast.ClassDef*, module_sha1: str) -> None: """注册泛型类模板(类名 + ClassDef 节点 + 来源模块 SHA1) [池归属修复] 这四张表 + GenericClassTpParams 的语义都是**永久表**: @@ -177,9 +175,7 @@ novirtual class ClassGenGeneric(ClassGenBase.ClassGenBase): if tp is None: return 0 return 1 - def _register_generic_func_template(self, pool: memhub.MemBuddy*, - fd: ast.FunctionDef*, - module_sha1: str) -> None: + def _register_generic_func_template(self, pool: memhub.MemBuddy*, fd: ast.FunctionDef*, module_sha1: str) -> None: """注册泛型函数模板(键 "{module_sha1}.{函数名}" + 节点 + tp 名) 表体一律落永久池(同 _register_generic_template 的池归属修复):扫描 @@ -254,8 +250,7 @@ novirtual class ClassGenGeneric(ClassGenBase.ClassGenBase): if knm is not None and string.strcmp(knm, key) == 0: return files_local.get(i) return None - def _find_generic_func_tp_params(self, pool: memhub.MemBuddy*, - key: str) -> list[str]*: + def _find_generic_func_tp_params(self, pool: memhub.MemBuddy*, key: str) -> list[str]*: """查找泛型函数模板的类型参数名列表,未找到返回 None 从注册时深拷贝的 stdlib 缓冲区重建当前 pool 的 list[str](特化期间 @@ -292,8 +287,7 @@ novirtual class ClassGenGeneric(ClassGenBase.ClassGenBase): return tp_list return None - def _find_generic_func_param_slot(self, fd: ast.FunctionDef*, - tp_name: str) -> int: + def _find_generic_func_param_slot(self, fd: ast.FunctionDef*, tp_name: str) -> int: """函数模板形参列表中注解恰为类型形参 tp_name 的形参槽位(0 起) module 级函数无 self,槽位即位置实参下标;找不到返回 -1。判据复用 @@ -314,10 +308,7 @@ novirtual class ClassGenGeneric(ClassGenBase.ClassGenBase): if self.Gen.CallGenCtor._annotation_refers_type_param(ag.annotation, tp_name) != 0: return int(ai) return -1 - def _infer_generic_func_type_arg(self, pool: memhub.MemBuddy*, - arg_node: ast.AST*, - func_name: str, - trans: HT.Translator*) -> str: + def _infer_generic_func_type_arg(self, pool: memhub.MemBuddy*, arg_node: ast.AST*, func_name: str, trans: HT.Translator*) -> str: """从调用实参 AST 推断泛型函数的类型实参名(不发射 IR,非 fatal) 与 CallGenCtor._infer_generic_ctor_type_arg 同源,但函数调用实参可以是 @@ -376,8 +367,7 @@ novirtual class ClassGenGeneric(ClassGenBase.ClassGenBase): # (现场:GenericOopTest `fxi2(a, b, CUInt64T(178900))` 的 T3=u64 # 被猜成 i32)。此处不做兜底猜测,宁缺毋错。 if (fk_f == ast.ASTKind.Name or fk_f == ast.ASTKind.Attribute) and trans is not None: - cty_f: mlirlite.LLVMType* = self.Gen.TypeGenResolve.resolve_annotation_type( - pool, cl_f.func, trans._imported_modules, trans._from_imports, trans, 0) + cty_f: mlirlite.LLVMType* = self.Gen.TypeGenResolve.resolve_annotation_type(pool, cl_f.func, trans._imported_modules, trans._from_imports, trans, 0) if cty_f is not None: # 符号性只能从**被调名源码文本**取(LLVM 层 iN/uN 同形, # SpecFromLLVMType 恒给 SIGNED)。复用注解侧唯一真源 @@ -394,9 +384,7 @@ novirtual class ClassGenGeneric(ClassGenBase.ClassGenBase): return None return None - def _infer_scalar_type_name_from_spec(self, pool: memhub.MemBuddy*, - sp: TSpec.TypeSpec*, - sign_override: int = SIGN_FROM_SPEC) -> str: + def _infer_scalar_type_name_from_spec(self, pool: memhub.MemBuddy*, sp: TSpec.TypeSpec*, sign_override: int = SIGN_FROM_SPEC) -> str: """从变量的 TypeSpec 反推可解析的内建标量类型名 仅覆盖 extract_class_name_from_annotation 会跳过的内建标量 @@ -476,9 +464,7 @@ novirtual class ClassGenGeneric(ClassGenBase.ClassGenBase): if string.strcmp(buf, "fp128") == 0: return "t.CFloat128T" return None - def infer_scalar_type_arg_from_llvm_ty(self, pool: memhub.MemBuddy*, - ty: mlirlite.LLVMType*, - sign: int) -> str: + def infer_scalar_type_arg_from_llvm_ty(self, pool: memhub.MemBuddy*, ty: mlirlite.LLVMType*, sign: int) -> str: """LLVM **标量**类型 → 泛型类型实参票名(精确位宽;非标量返回 None) 泛型函数(ClassGenGeneric._infer_generic_func_type_arg)与泛型类构造 @@ -497,11 +483,7 @@ novirtual class ClassGenGeneric(ClassGenBase.ClassGenBase): if arena is None: return None return self._infer_scalar_type_name_from_spec(pool, TSpec.SpecFromLLVMType(arena, ty), sign) - def _clone_funcdef_for_spec(self, pool: memhub.MemBuddy*, - fd: ast.FunctionDef*, - spec_base: str, - tp_names: list[str]*, - type_args: list[str]*) -> ast.FunctionDef*: + def _clone_funcdef_for_spec(self, pool: memhub.MemBuddy*, fd: ast.FunctionDef*, spec_base: str, tp_names: list[str]*, type_args: list[str]*) -> ast.FunctionDef*: """拷贝 FunctionDef 用于泛型函数特化 - 函数名替换为 spec_base(如 "f[int,double]") @@ -513,8 +495,7 @@ novirtual class ClassGenGeneric(ClassGenBase.ClassGenBase): if fd is None: return None new_args: ast.AST* = self._clone_arguments(pool, fd.args, tp_names, type_args) new_returns: ast.AST* = self._clone_annotation(pool, fd.returns, tp_names, type_args) - new_fd: ast.FunctionDef* = ast.FunctionDef(pool, spec_base, new_args, - fd.decorator_list, new_returns, 0) + new_fd: ast.FunctionDef* = ast.FunctionDef(pool, spec_base, new_args, fd.decorator_list, new_returns, 0) if fd.children is not None: body: list[ast.AST*]* = fd.children bn: sizet = len(body) @@ -524,12 +505,7 @@ novirtual class ClassGenGeneric(ClassGenBase.ClassGenBase): if stmt is not None: new_fd.append(stmt) return new_fd - def _ensure_generic_func_declare(self, trans: HT.Translator*, - pool: memhub.MemBuddy*, - spec_name: str, - template_key: str, - tp_names: list[str]*, - type_args: list[str]*) -> mlirlite.Function*: + def _ensure_generic_func_declare(self, trans: HT.Translator*, pool: memhub.MemBuddy*, spec_name: str, template_key: str, tp_names: list[str]*, type_args: list[str]*) -> mlirlite.Function*: """确保当前模块存在特化函数的 declare(跨模块缓存命中时用) 特化 define 全局只发射一份(SpecKeys 去重);命中缓存的调用方模块里没有 @@ -599,9 +575,7 @@ novirtual class ClassGenGeneric(ClassGenBase.ClassGenBase): self.Gen.TypeGenBase.clear_generic_context() return func - def _specialize_generic_function(self, trans: HT.Translator*, - template_key: str, - type_args: list[str]*) -> str: + def _specialize_generic_function(self, trans: HT.Translator*, template_key: str, type_args: list[str]*) -> str: """特化泛型函数,返回特化函数 mangled 名("{模板sha1}.{f}[args]") 1. 查找模板;2. 逐实参规范化生成特化名;3. SpecKeys 去重 @@ -637,9 +611,7 @@ novirtual class ClassGenGeneric(ClassGenBase.ClassGenBase): if len(tp_names) != len(type_args): err_tp: str = pool.alloc(256) if err_tp is not None: - viperlib.snprintf(err_tp, 256, - "泛型函数 '%s' 类型实参个数不匹配(需要 %d,给定 %d)", - template_fd.name, len(tp_names), len(type_args)) + viperlib.snprintf(err_tp, 256, "泛型函数 '%s' 类型实参个数不匹配(需要 %d,给定 %d)", template_fd.name, len(tp_names), len(type_args)) self.Gen.TypeGenErr.fatal_error(None, err_tp, "TypeError") self.GenericSpecDepth -= 1 return None @@ -721,8 +693,7 @@ novirtual class ClassGenGeneric(ClassGenBase.ClassGenBase): self.GenericSpecDepth -= 1 return spec_name - def _find_generic_template_tp_params(self, pool: memhub.MemBuddy*, - class_name: str) -> list[str]*: + def _find_generic_template_tp_params(self, pool: memhub.MemBuddy*, class_name: str) -> list[str]*: """查找泛型类模板的类型参数名列表,未找到返回 None 从注册时深拷贝的 stdlib 缓冲区重建当前 pool 的 list[str] @@ -807,10 +778,7 @@ novirtual 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*, - class_name: str, - type_args: list[str]*, - from_imports: str = None) -> str: + def _mangle_generic_class_name(self, pool: memhub.MemBuddy*, class_name: str, type_args: list[str]*, from_imports: str = None) -> str: """生成特化类名: list + [int] -> list[int] **唯一生成器 + 唯一规范化点**:所有特化名(结构体注册名、方法符号里的 @@ -860,10 +828,7 @@ novirtual class ClassGenGeneric(ClassGenBase.ClassGenBase): if ta is not None: string.strcat(mangled, ta) string.strcat(mangled, "]") return mangled - def _clone_annotation(self, pool: memhub.MemBuddy*, - node: ast.AST*, - tp_names: list[str]*, - type_args: list[str]*) -> ast.AST*: + def _clone_annotation(self, pool: memhub.MemBuddy*, node: ast.AST*, tp_names: list[str]*, type_args: list[str]*) -> ast.AST*: """拷贝类型注解表达式,替换类型参数 T 为具体类型名 tp_names: 类型参数名列表 ['T'] @@ -925,15 +890,11 @@ novirtual class ClassGenGeneric(ClassGenBase.ClassGenBase): # Constant: 默认值等 if k == ast.ASTKind.Constant: cnst: ast.Constant* = ast.Constant*(node) - return ast.Constant(pool, cnst.const_kind, cnst.int_val, cnst.float_val, - cnst.str_val, cnst.lineno, cnst.col_offset) + return ast.Constant(pool, cnst.const_kind, cnst.int_val, cnst.float_val, cnst.str_val, cnst.lineno, cnst.col_offset) # 其他: 直接引用(不拷贝) return node - def _clone_arguments(self, pool: memhub.MemBuddy*, - args: ast.AST*, - tp_names: list[str]*, - type_args: list[str]*) -> ast.AST*: + def _clone_arguments(self, pool: memhub.MemBuddy*, args: ast.AST*, tp_names: list[str]*, type_args: list[str]*) -> ast.AST*: """拷贝 Arguments 节点,替换 arg annotation 中的 T""" if args is None: return None if args.kind() != ast.ASTKind.Arguments: return args @@ -953,13 +914,8 @@ novirtual class ClassGenGeneric(ClassGenBase.ClassGenBase): new_arg: ast.Arg* = ast.Arg(pool, ag.arg, new_anno) new_arg_list.append(new_arg) else: 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*, - cd: ast.ClassDef*, - spec_name: str, - tp_names: list[str]*, - type_args: list[str]*) -> ast.ClassDef*: + 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*, cd: ast.ClassDef*, spec_name: str, tp_names: list[str]*, type_args: list[str]*) -> ast.ClassDef*: """拷贝 ClassDef 节点用于泛型特化 - 替换类名为 spec_name @@ -968,8 +924,7 @@ novirtual class ClassGenGeneric(ClassGenBase.ClassGenBase): - 方法体直接引用原始节点(通过 type_map 上下文处理 T) """ # 创建新 ClassDef(type_params=None 表示非泛型) - new_cd: ast.ClassDef* = ast.ClassDef(pool, spec_name, cd.bases, cd.keywords, - cd.decorator_list, None) + new_cd: ast.ClassDef* = ast.ClassDef(pool, spec_name, cd.bases, cd.keywords, cd.decorator_list, None) # 拷贝 children if cd.children is not None: cd_children: list[ast.AST*]* = cd.children @@ -992,8 +947,7 @@ novirtual class ClassGenGeneric(ClassGenBase.ClassGenBase): fd: ast.FunctionDef* = ast.FunctionDef*(child) new_args2: ast.AST* = self._clone_arguments(pool, fd.args, tp_names, type_args) new_returns2: ast.AST* = self._clone_annotation(pool, fd.returns, tp_names, type_args) - new_fd: ast.FunctionDef* = ast.FunctionDef(pool, fd.name, new_args2, - fd.decorator_list, new_returns2, 0) + new_fd: ast.FunctionDef* = ast.FunctionDef(pool, fd.name, new_args2, fd.decorator_list, new_returns2, 0) # 方法体直接引用原始节点 if fd.children is not None: fd_children: list[ast.AST*]* = fd.children @@ -1041,8 +995,7 @@ novirtual class ClassGenGeneric(ClassGenBase.ClassGenBase): self.SpecKeys[self.SpecCount] = sizet(key_copy) self.SpecNames[self.SpecCount] = sizet(name_copy) self.SpecCount += 1 - def _merge_template_imports(self, trans: HT.Translator*, - template_sha1: str) -> None: + def _merge_template_imports(self, trans: HT.Translator*, template_sha1: str) -> None: """将模板模块的 imports 并入 trans._imported_modules(空格分隔)""" if trans is None or template_sha1 is None: return tdeps: str = StubMergerStore.LookupIncludesDeps(template_sha1) @@ -1059,8 +1012,7 @@ novirtual 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*, - spec_name: str, trigger_sha1: str) -> int: + def _record_spec_trigger(self, pool: memhub.MemBuddy*, spec_name: str, trigger_sha1: str) -> int: """记录泛型特化类的触发文件 sha1(StructEntry.SpecTriggerSha1) 特化类 ModuleSha1=模板 sha1(方法名带模板前缀),Phase A _deps_pending @@ -1078,8 +1030,7 @@ novirtual class ClassGenGeneric(ClassGenBase.ClassGenBase): string.strcpy(ts_buf_r, trigger_sha1) entry_rt.SpecTriggerSha1 = ts_buf_r return 1 - def _tp_names_for_spec(self, pool: memhub.MemBuddy*, class_name: str, - template_cd: ast.ClassDef*) -> list[str]*: + def _tp_names_for_spec(self, pool: memhub.MemBuddy*, class_name: str, template_cd: ast.ClassDef*) -> list[str]*: """取特化用的类型参数名列表(优先 stdlib 深拷贝表,退化模板节点) 两条来源都拿不到/为空时 fail-fast,**绝不**用空泛型上下文继续特化: @@ -1089,14 +1040,10 @@ novirtual class ClassGenGeneric(ClassGenBase.ClassGenBase): tp: list[str]* = self._find_generic_template_tp_params(pool, class_name) if tp is not None and len(tp) > 0: return tp if template_cd is not None and template_cd.type_params is not None and len(template_cd.type_params) > 0: return template_cd.type_params - self.Gen.TypeGenErr.fatal_error(None, - f"泛型类模板 '{class_name}' 的类型参数名缺失(GenericClassTpParams 对应槽为空," - f"模板节点也无 type_params)——拒绝用空泛型上下文特化", "InternalCompilerError") + self.Gen.TypeGenErr.fatal_error(None, f"泛型类模板 '{class_name}' 的类型参数名缺失(GenericClassTpParams 对应槽为空," f"模板节点也无 type_params)——拒绝用空泛型上下文特化", "InternalCompilerError") return None - def _specialize_generic_class(self, trans: HT.Translator*, - class_name: str, - type_args: list[str]*) -> str: + def _specialize_generic_class(self, trans: HT.Translator*, class_name: str, type_args: list[str]*) -> str: """特化泛型类,返回特化类名 1. 查找泛型模板 @@ -1118,9 +1065,7 @@ novirtual class ClassGenGeneric(ClassGenBase.ClassGenBase): if self.GenericSpecDepth > GENERIC_SPEC_MAX_DEPTH: err_spec: str = trans.Pool.alloc(256) if err_spec is not None: - viperlib.snprintf(err_spec, 256, - "泛型特化递归过深(疑似泛型循环套用),类: %s 深度=%d", - class_name, self.GenericSpecDepth) + viperlib.snprintf(err_spec, 256, "泛型特化递归过深(疑似泛型循环套用),类: %s 深度=%d", class_name, self.GenericSpecDepth) self.Gen.TypeGenErr.fatal_error(None, err_spec, "InternalCompilerError") self.Gen.TypeGenErr.fatal_error(None, "泛型特化递归过深(疑似泛型循环套用)", "InternalCompilerError") # 防御:泛型上下文内收集的 type_args 若残留未替换的类型参数名(如 "T"), @@ -1255,17 +1200,11 @@ novirtual class ClassGenGeneric(ClassGenBase.ClassGenBase): tp_n_c: sizet = len(tp_names) if tp_names is not None else 0 ta_n_c: sizet = len(type_args) if type_args is not None else 0 if tp_n_c == 0 or ta_n_c != tp_n_c: - self.Gen.TypeGenErr.fatal_error(None, - f"泛型类 '{class_name}' 的类型实参个数({ta_n_c})与模板类型形参个数({tp_n_c})不匹配," - f"无法建立特化上下文(特化键 {spec_key})", - "InternalCompilerError") + self.Gen.TypeGenErr.fatal_error(None, f"泛型类 '{class_name}' 的类型实参个数({ta_n_c})与模板类型形参个数({tp_n_c})不匹配," f"无法建立特化上下文(特化键 {spec_key})", "InternalCompilerError") probe_tp: str = tp_names.get(0) if probe_tp is not None: if string.strcmp(self.Gen.TypeGenBase.resolve_generic_type_name(probe_tp), probe_tp) == 0: - self.Gen.TypeGenErr.fatal_error(None, - f"泛型类 '{class_name}' 的特化上下文装不上:类型形参 '{probe_tp}' 解析不到具体类型" - f"(特化键 {spec_key})——类型实参缺失/为空", - "InternalCompilerError") + self.Gen.TypeGenErr.fatal_error(None, f"泛型类 '{class_name}' 的特化上下文装不上:类型形参 '{probe_tp}' 解析不到具体类型" f"(特化键 {spec_key})——类型实参缺失/为空", "InternalCompilerError") # 7. 翻译特化类 # 切换 trans.ModuleSha1 为泛型模板定义模块的 SHA1, diff --git a/App/lib/core/Gen/Class/ClassGenVTable.vp b/App/lib/core/Gen/Class/ClassGenVTable.vp index bee4cae..8b23898 100644 --- a/App/lib/core/Gen/Class/ClassGenVTable.vp +++ b/App/lib/core/Gen/Class/ClassGenVTable.vp @@ -32,8 +32,7 @@ novirtual class ClassGenVTable(ClassGenBase.ClassGenBase): # ============================================================ # _vtable_strcat — 将 src 追加到 dst 末尾 # ============================================================ - def _vtable_strcat(self, dst: str, dst_size: sizet, - src: str): + def _vtable_strcat(self, dst: str, dst_size: sizet, src: str): """将 src 追加到 dst 末尾""" if dst is None or src is None: return dlen: sizet = string.strlen(dst) @@ -67,9 +66,7 @@ novirtual class ClassGenVTable(ClassGenBase.ClassGenBase): # # 返回 1=有虚方法 / 0=无方法或失败 # ============================================================ - def _collect_vtable_methods(self, trans: HT.Translator*, - cd: ast.ClassDef*, - class_name: str) -> int: + def _collect_vtable_methods(self, trans: HT.Translator*, cd: ast.ClassDef*, class_name: str) -> int: """收集虚方法信息,设置 entry.VTableMethods/VTableMethodCount""" if trans is None or cd is None or class_name is None: return 0 @@ -250,9 +247,7 @@ novirtual class ClassGenVTable(ClassGenBase.ClassGenBase): # 4. 创建全局变量 @"SHA1.ClassName.vtable" # 5. 存储虚方法名列表到 StructEntry # ============================================================ - def _generate_vtable(self, trans: HT.Translator*, - cd: ast.ClassDef*, - class_name: str) -> int: + def _generate_vtable(self, trans: HT.Translator*, cd: ast.ClassDef*, class_name: str) -> int: """生成 VTable 全局变量""" if trans is None or cd is None or class_name is None: return 0 @@ -376,12 +371,7 @@ novirtual class ClassGenVTable(ClassGenBase.ClassGenBase): # - 翻译方法(生成 SHA1.ClassName.method_name 函数) # 翻译完所有方法后,生成 __before_init__ 函数 # ============================================================ - def _translate_oop_methods(self, trans: HT.Translator*, - cd: ast.ClassDef*, - struct_ty: mlirlite.LLVMType*, - class_name: str, - mark_only: int = 0, - reemit: int = 0) -> int: + def _translate_oop_methods(self, trans: HT.Translator*, cd: ast.ClassDef*, struct_ty: mlirlite.LLVMType*, class_name: str, mark_only: int = 0, reemit: int = 0) -> int: """扫描 class body 中的方法并翻译,生成 __before_init__ mark_only: 0=全量翻译(默认),1=只设置 IsOOP/HasNew/HasInit 标志(不翻译方法体) @@ -514,11 +504,7 @@ novirtual class ClassGenVTable(ClassGenBase.ClassGenBase): # - 类型 Ptr(struct_ty),直接注册为 SSA 值(不创建 alloca) # - 使 self.field 能通过 GEP 直接访问原始结构体 # ============================================================ - def _translate_method(self, trans: HT.Translator*, - fd: ast.FunctionDef*, - struct_ty: mlirlite.LLVMType*, - class_name: str, - sig_only: int = 0) -> int: + def _translate_method(self, trans: HT.Translator*, fd: ast.FunctionDef*, struct_ty: mlirlite.LLVMType*, class_name: str, sig_only: int = 0) -> int: """翻译单个方法,返回 0 sig_only: 1=只建前向声明(declare + 参数 + 函数表登记),不发射函数体。 @@ -655,9 +641,7 @@ novirtual class ClassGenVTable(ClassGenBase.ClassGenBase): # 注册到函数表(用 ClassName.method_name 作为查找名,支持后缀匹配) max_funcs: int = 1024 - if self.Gen.CallGenLeafKit.add_func_to_table(funcs_ptr, func_count, full_name, func, max_funcs, - md_defaults, md_default_count, md_param_count, - pool) == 0: + if self.Gen.CallGenLeafKit.add_func_to_table(funcs_ptr, func_count, full_name, func, max_funcs, md_defaults, md_default_count, md_param_count, pool) == 0: trans._func_count = func_count + 1 # 添加 self/cls 参数(Ptr(struct_ty));@staticmethod 无 self,跳过 @@ -741,8 +725,7 @@ novirtual class ClassGenVTable(ClassGenBase.ClassGenBase): # --traceback: attach a DISubprogram to this method define (same as the # module-level function path). No-op when DI is disabled. - dbg_pushed: int = DebugInfoGen.PushFunction(pool, func_builder, func, - fd.lineno, fd.col_offset + 1) + dbg_pushed: int = DebugInfoGen.PushFunction(pool, func_builder, func, fd.lineno, fd.col_offset + 1) # @t.TLS 一次性初始化守卫(对齐 TPC HandlesFunctions.py L1763-1792; # 与 FuncGenMixin.translate_function_def 同一实现,类方法同样支持) @@ -1007,9 +990,7 @@ novirtual class ClassGenVTable(ClassGenBase.ClassGenBase): # 2. 逐字段 store 默认值(如有) # 3. ret void # ============================================================ - def _generate_before_init(self, trans: HT.Translator*, - struct_ty: mlirlite.LLVMType*, - class_name: str) -> int: + def _generate_before_init(self, trans: HT.Translator*, struct_ty: mlirlite.LLVMType*, class_name: str) -> int: """生成 __before_init__ 函数,返回 0""" if trans is None or struct_ty is None or class_name is None: return 0 diff --git a/App/lib/core/Gen/DebugInfoGen.vp b/App/lib/core/Gen/DebugInfoGen.vp index 34fa2f3..868b59f 100644 --- a/App/lib/core/Gen/DebugInfoGen.vp +++ b/App/lib/core/Gen/DebugInfoGen.vp @@ -237,9 +237,7 @@ def _EnsureModuleNodes(pool: memhub.MemBuddy*) -> int: if cbuf is None: VLogger.error("--traceback: DICompileUnit 缓冲分配失败,终止编译", "DWARF") return 1 - viperlib.snprintf(cbuf, 256, - "distinct !DICompileUnit(language: DW_LANG_C99, file: !%d, producer: \"TPC\", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug)", - _g_file_id) + viperlib.snprintf(cbuf, 256, "distinct !DICompileUnit(language: DW_LANG_C99, file: !%d, producer: \"TPC\", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug)", _g_file_id) cid: int = mlirlite.module_add_di_node(mod, pool, cbuf) if cid < 0: VLogger.error("--traceback: DICompileUnit 元数据节点分配失败,终止编译", "DWARF") @@ -299,8 +297,7 @@ def _EnsureLocation(pool: memhub.MemBuddy*, sp: int, line: int, col: int) -> str # ============================================================ # PushFunction - create the DISubprogram for one define # ============================================================ -def PushFunction(pool: memhub.MemBuddy*, builder: mlirlite.IRBuilder*, - func: mlirlite.Function*, line: int, col: int) -> int: +def PushFunction(pool: memhub.MemBuddy*, builder: mlirlite.IRBuilder*, func: mlirlite.Function*, line: int, col: int) -> int: """Attach a DISubprogram to one define and set the builder's entry DILocation. Returns 1 when pushed (caller must call PopFunction), 0 when DI is disabled @@ -327,9 +324,7 @@ def PushFunction(pool: memhub.MemBuddy*, builder: mlirlite.IRBuilder*, if spbuf is None: VLogger.error("--traceback: DISubprogram 缓冲分配失败,终止编译", "DWARF") return 0 - viperlib.snprintf(spbuf, ssize, - "distinct !DISubprogram(name: \"%s\", scope: !%d, file: !%d, type: !%d, line: %d, scopeLine: %d, unit: !%d, spFlags: DISPFlagDefinition)", - name, _g_file_id, _g_file_id, _g_subtype_id, dline, dline, _g_cu_id) + viperlib.snprintf(spbuf, ssize, "distinct !DISubprogram(name: \"%s\", scope: !%d, file: !%d, type: !%d, line: %d, scopeLine: %d, unit: !%d, spFlags: DISPFlagDefinition)", name, _g_file_id, _g_file_id, _g_subtype_id, dline, dline, _g_cu_id) sp_id: int = mlirlite.module_add_di_node(_g_mod, pool, spbuf) if sp_id < 0: VLogger.error("--traceback: DISubprogram 元数据节点分配失败,终止编译", "DWARF") @@ -382,8 +377,7 @@ def PopFunction(builder: mlirlite.IRBuilder*) -> int: # ============================================================ # SetStatement - point the current builder at a statement DILocation # ============================================================ -def SetStatement(pool: memhub.MemBuddy*, builder: mlirlite.IRBuilder*, - line: int, col: int) -> int: +def SetStatement(pool: memhub.MemBuddy*, builder: mlirlite.IRBuilder*, line: int, col: int) -> int: """Update the builder's DILocation to the current statement (line precision). No-op outside a DI-attached define (module-level code / synthetic defines), diff --git a/App/lib/core/Gen/Expr/ExprGenAttr.vp b/App/lib/core/Gen/Expr/ExprGenAttr.vp index 6075c56..11a57d8 100644 --- a/App/lib/core/Gen/Expr/ExprGenAttr.vp +++ b/App/lib/core/Gen/Expr/ExprGenAttr.vp @@ -29,8 +29,7 @@ novirtual class ExprGenAttr(ExprGenBase.ExprGenBase): # 1. 精确匹配 (如 "_mbuddy" 匹配 @_mbuddy) # 2. 后缀匹配 (如 "_mbuddy" 匹配 @"sha1._mbuddy") # ============================================================ - def find_global_in_module(self, mod: mlirlite.LLVMModule*, - name: str) -> mlirlite.GlobalVariable*: + def find_global_in_module(self, mod: mlirlite.LLVMModule*, name: str) -> mlirlite.GlobalVariable*: """在模块全局变量链表中按名称查找全局变量""" if mod is None or name is None: return None name_len: sizet = string.strlen(name) @@ -62,9 +61,7 @@ novirtual class ExprGenAttr(ExprGenBase.ExprGenBase): # 用于跨模块全局变量访问: stub 未注入时,翻译阶段生成 @name 引用, # 链接时由 stub 提供 external global 声明。 # ============================================================ - def make_global_ref(self, pool: memhub.MemBuddy*, - name: str, - ty: mlirlite.LLVMType*) -> mlirlite.Value*: + def make_global_ref(self, pool: memhub.MemBuddy*, name: str, ty: mlirlite.LLVMType*) -> mlirlite.Value*: """创建全局变量引用 (类型为 ty*,名称为 @name)""" if name is None or ty is None: return None ptr_ty: mlirlite.LLVMType* = mlirlite.Ptr(pool, ty) @@ -134,8 +131,7 @@ novirtual class ExprGenAttr(ExprGenBase.ExprGenBase): if string.strcmp(name, "CNeedPtr") == 0: return 1 if string.strcmp(name, "CAutoPtr") == 0: return 1 return 0 - def _attr_module_path_str(self, pool: memhub.MemBuddy*, - node: ast.AST*) -> str: + def _attr_module_path_str(self, pool: memhub.MemBuddy*, node: ast.AST*) -> str: """把模块引用 AST 转成模块路径字符串(递归拼接 Attribute 链): Name('sys') → "sys";Attribute(Attribute(Name('os'),'_win32')) → "os._win32"。 非模块引用形态(Call/Subscript 等)返回 None。""" @@ -171,9 +167,7 @@ novirtual class ExprGenAttr(ExprGenBase.ExprGenBase): # 会改变该大函数的类型推断结果,曾使其后续 `match obj_ptr.Ty` 报 # "指针隐式转整数已禁止"(MemManager* → i32)。 # ============================================================ - def _CheckStaticCrossModule(self, pool: memhub.MemBuddy*, - trans: HT.Translator*, - at: ast.Attribute*) -> int: + def _CheckStaticCrossModule(self, pool: memhub.MemBuddy*, trans: HT.Translator*, at: ast.Attribute*) -> int: if at is None or at.value is None or trans is None: return 0 if trans.ModuleSha1 is None or trans._imported_modules is None: return 0 # 快速短路:项目内无 static 符号时零开销(不查 sha1、不扫表) @@ -197,15 +191,9 @@ novirtual class ExprGenAttr(ExprGenBase.ExprGenBase): if cs_sha1 is None: return 0 if string.strncmp(cs_sha1, trans.ModuleSha1, 16) == 0: return 0 if self.Gen.CallGenBase.IsStaticSymbol(cs_sha1, at.attr) == 0: return 0 - self.Gen.TypeGenErr.fatal_error(at, - f"'{cs_path}.{at.attr}' 是 static 符号,禁止跨模块使用(static 仅限定义模块内可见)", - "NameError") + self.Gen.TypeGenErr.fatal_error(at, f"'{cs_path}.{at.attr}' 是 static 符号,禁止跨模块使用(static 仅限定义模块内可见)", "NameError") return 0 - def _resolve_module_attribute_global(self, pool: memhub.MemBuddy*, - mod: mlirlite.LLVMModule*, - trans: HT.Translator*, - at: ast.Attribute*, - ty_hint: mlirlite.LLVMType*) -> mlirlite.Value*: + def _resolve_module_attribute_global(self, pool: memhub.MemBuddy*, mod: mlirlite.LLVMModule*, trans: HT.Translator*, at: ast.Attribute*, ty_hint: mlirlite.LLVMType*) -> mlirlite.Value*: """解析模块属性访问,返回全局变量引用 (用于跨模块 global 访问)""" if at is None or at.value is None or at.attr is None: return None if trans is None or trans._imported_modules is None: return None @@ -318,11 +306,7 @@ novirtual class ExprGenAttr(ExprGenBase.ExprGenBase): # ptr 指针值(Ptr(Struct) 或 Ptr(Ptr(Struct)),交由 _deref_if_ptr_ptr 解层级) # 非 c.Deref 模式返回 None # ============================================================ - def _get_cderef_attr_base(self, builder: mlirlite.IRBuilder*, - pool: memhub.MemBuddy*, - mod: mlirlite.LLVMModule*, - at_value: ast.AST*, - trans: HT.Translator* = None) -> mlirlite.Value*: + def _get_cderef_attr_base(self, builder: mlirlite.IRBuilder*, pool: memhub.MemBuddy*, mod: mlirlite.LLVMModule*, at_value: ast.AST*, trans: HT.Translator* = None) -> mlirlite.Value*: """检测 at.value 是否为 *ptr 调用,返回 ptr 指针(不做 load)""" if at_value is None or at_value.kind() != ast.ASTKind.Call: return None cl_cd: ast.Call* = ast.Call*(at_value) @@ -336,11 +320,7 @@ novirtual class ExprGenAttr(ExprGenBase.ExprGenBase): inner_cd: mlirlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, mod, cl_cd.args.get(0), None, 0, trans) if inner_cd is not None and self.is_ptr_type(inner_cd.Ty) != 0: return inner_cd return None - def translate_attribute(self, builder: mlirlite.IRBuilder*, - pool: memhub.MemBuddy*, - mod: mlirlite.LLVMModule*, - node: ast.AST*, - trans: HT.Translator* = None) -> mlirlite.Value*: + def translate_attribute(self, builder: mlirlite.IRBuilder*, pool: memhub.MemBuddy*, mod: mlirlite.LLVMModule*, node: ast.AST*, trans: HT.Translator* = None) -> mlirlite.Value*: """翻译属性访问,返回加载的字段值""" if node is None or builder is None: return None at: ast.Attribute* = ast.Attribute*(node) @@ -352,11 +332,7 @@ novirtual class ExprGenAttr(ExprGenBase.ExprGenBase): if at is not None: if at.value is None: missing_an = "value" elif at.attr is None: missing_an = "attr" - viperlib.snprintf(diag_buf_an, 256, - "属性访问失败: AST 节点字段缺失 (%s sha1=%s:%d)", - missing_an, - trans.ModuleSha1 if trans is not None and trans.ModuleSha1 is not None else "?", - at.lineno if at is not None and at.lineno is not None else 0) + viperlib.snprintf(diag_buf_an, 256, "属性访问失败: AST 节点字段缺失 (%s sha1=%s:%d)", missing_an, trans.ModuleSha1 if trans is not None and trans.ModuleSha1 is not None else "?", at.lineno if at is not None and at.lineno is not None else 0) VLogger.error(diag_buf_an, "ATTR") return None @@ -889,10 +865,7 @@ novirtual class ExprGenAttr(ExprGenBase.ExprGenBase): # 获取属性访问的字段指针(不加载值,用于赋值) # 对于 Name 类型的 obj,直接使用 alloca 指针(不 load 结构体) # ============================================================ - def _resolve_attr_field_class(self, pool: memhub.MemBuddy*, - trans: HT.Translator*, - attr_node: ast.AST*, - allow_module_global: int = 0) -> str: + def _resolve_attr_field_class(self, pool: memhub.MemBuddy*, trans: HT.Translator*, attr_node: ast.AST*, allow_module_global: int = 0) -> str: """解析属性链(a.b.c)中 c 字段的注解类名。 联合类型字段(X*)被简化为 Ptr(i8),属性链写入时 @@ -965,9 +938,7 @@ novirtual class ExprGenAttr(ExprGenBase.ExprGenBase): # entry 的 ModuleSha1 却是子模块 exprs 的,find_struct_by_module 必失败)。 # 裸名走「按类名查找第一个」回退,与 TPC _extract_union_base_class 同口径。 # ============================================================ - def _base_class_from_cast_base(self, pool: memhub.MemBuddy*, - trans: HT.Translator*, - node: ast.AST*) -> str: + def _base_class_from_cast_base(self, pool: memhub.MemBuddy*, trans: HT.Translator*, node: ast.AST*) -> str: """`T*(x)` 强转基座的裸类名;非该形态返回 None""" if node is None or trans is None: return None if node.kind() != ast.ASTKind.Call: return None @@ -1002,10 +973,7 @@ novirtual class ExprGenAttr(ExprGenBase.ExprGenBase): # → 模块已知性 → SHA1 前缀名精确匹配 → 裸名回退)。未识别为模块限定全局时 # 返回 None,调用方保持原语义(不新增报错、不改变既有可编译路径)。 # ============================================================ - def _resolve_module_global_class_name(self, pool: memhub.MemBuddy*, - trans: HT.Translator*, - mod_name: str, - global_name: str) -> str: + def _resolve_module_global_class_name(self, pool: memhub.MemBuddy*, trans: HT.Translator*, mod_name: str, global_name: str) -> str: """解析模块限定全局 Mod.g 的元素类型类名;非该形态返回 None""" if pool is None or trans is None or mod_name is None or global_name is None: return None mod: mlirlite.LLVMModule* = trans.Module @@ -1041,9 +1009,7 @@ novirtual class ExprGenAttr(ExprGenBase.ExprGenBase): level_mg += 1 return None - def attr_field_is_volatile(self, pool: memhub.MemBuddy*, - trans: HT.Translator*, - attr_node: ast.AST*) -> int: + def attr_field_is_volatile(self, pool: memhub.MemBuddy*, trans: HT.Translator*, attr_node: ast.AST*) -> int: """obj.field 访问的字段是否 volatile(1=是 / 0=否) 仅解析一层属性:先定基座(Name 变量注解名 / 属性链字段注解名)得到父类, @@ -1071,9 +1037,7 @@ novirtual class ExprGenAttr(ExprGenBase.ExprGenBase): # 基址→VarEntry/FieldEntry 解析与消费点。仅在基址能解析到具体条目时生效, # 其余(函数返回/复杂表达式等)返回 0(明确不支持,见限制清单)。 # ============================================================ - def _resolve_attr_field_entry(self, pool: memhub.MemBuddy*, - trans: HT.Translator*, - attr_node: ast.AST*) -> GenTypes.FieldEntry*: + def _resolve_attr_field_entry(self, pool: memhub.MemBuddy*, trans: HT.Translator*, attr_node: ast.AST*) -> GenTypes.FieldEntry*: """obj.field 访问的 FieldEntry(**非 fatal 只读解析**,失败返回 None) 与 attr_field_is_volatile 的区别:后者走 lookup_field_by_class(模块限定名 @@ -1107,9 +1071,7 @@ novirtual class ExprGenAttr(ExprGenBase.ExprGenBase): fi += 1 return None - def attr_field_pointee_is_volatile(self, pool: memhub.MemBuddy*, - trans: HT.Translator*, - attr_node: ast.AST*) -> int: + def attr_field_pointee_is_volatile(self, pool: memhub.MemBuddy*, trans: HT.Translator*, attr_node: ast.AST*) -> int: """obj.field 字段的**所指物**是否 volatile(1=是 / 0=否) 即该字段注解是否为 rawptr[t.CVolatile | T](等价 C 的 volatile T*)。 @@ -1119,9 +1081,7 @@ novirtual class ExprGenAttr(ExprGenBase.ExprGenBase): fe: GenTypes.FieldEntry* = self._resolve_attr_field_entry(pool, trans, attr_node) return self.Gen.StructGen.field_pointee_is_volatile(fe) - def attr_field_is_const(self, pool: memhub.MemBuddy*, - trans: HT.Translator*, - attr_node: ast.AST*) -> int: + def attr_field_is_const(self, pool: memhub.MemBuddy*, trans: HT.Translator*, attr_node: ast.AST*) -> int: """obj.field 字段**自身**是否 const 对象(1=是 / 0=否) 即该字段注解含 t.CConst 且字段类型非指针(FieldEntry.IsConst 承载)。 @@ -1132,16 +1092,12 @@ novirtual class ExprGenAttr(ExprGenBase.ExprGenBase): fe: GenTypes.FieldEntry* = self._resolve_attr_field_entry(pool, trans, attr_node) return self.Gen.StructGen.field_is_const(fe) - def attr_field_decl_src(self, pool: memhub.MemBuddy*, - trans: HT.Translator*, - attr_node: ast.AST*) -> str: + def attr_field_decl_src(self, pool: memhub.MemBuddy*, trans: HT.Translator*, attr_node: ast.AST*) -> str: """字段注解来源名(供 const 报文的『声明处类型(含 const)』),无则 None。""" fe: GenTypes.FieldEntry* = self._resolve_attr_field_entry(pool, trans, attr_node) return self.Gen.StructGen.get_field_annot_class_name(fe) - def base_pointee_is_volatile(self, pool: memhub.MemBuddy*, - trans: HT.Translator*, - base_node: ast.AST*) -> int: + def base_pointee_is_volatile(self, pool: memhub.MemBuddy*, trans: HT.Translator*, base_node: ast.AST*) -> int: """指针基址的所指物是否 volatile(rawptr[t.CVolatile|T] 变量/字段) 仅当基址可解析到具体 VarEntry(Name)/ FieldEntry(Attribute)时生效; @@ -1157,11 +1113,7 @@ novirtual class ExprGenAttr(ExprGenBase.ExprGenBase): if base_node.kind() == ast.ASTKind.Attribute: return self.attr_field_pointee_is_volatile(pool, trans, base_node) return 0 - def get_attribute_ptr(self, builder: mlirlite.IRBuilder*, - pool: memhub.MemBuddy*, - mod: mlirlite.LLVMModule*, - node: ast.AST*, - trans: HT.Translator* = None) -> mlirlite.Value*: + def get_attribute_ptr(self, builder: mlirlite.IRBuilder*, pool: memhub.MemBuddy*, mod: mlirlite.LLVMModule*, node: ast.AST*, trans: HT.Translator* = None) -> mlirlite.Value*: """获取属性访问的字段指针(用于赋值 lhs)""" if node is None or builder is None: return None at: ast.Attribute* = ast.Attribute*(node) @@ -1206,9 +1158,7 @@ novirtual class ExprGenAttr(ExprGenBase.ExprGenBase): if self.Gen.ExprGenCdef._is_cdefine_name_pattern(at.attr) != 0: err_buf_wma: str = pool.alloc(256) if err_buf_wma is not None: - viperlib.snprintf(err_buf_wma, 256, - "[CD] FATAL: Cannot assign to CDefine constant '%s.%s'\n", - nm_wma.id, at.attr) + viperlib.snprintf(err_buf_wma, 256, "[CD] FATAL: Cannot assign to CDefine constant '%s.%s'\n", nm_wma.id, at.attr) VLogger.error(err_buf_wma, "CD") return None # 使用 i8* 作为类型提示 (模块级变量通常存储指针) diff --git a/App/lib/core/Gen/Expr/ExprGenBase.vp b/App/lib/core/Gen/Expr/ExprGenBase.vp index 3d65789..2955912 100644 --- a/App/lib/core/Gen/Expr/ExprGenBase.vp +++ b/App/lib/core/Gen/Expr/ExprGenBase.vp @@ -70,8 +70,7 @@ novirtual class ExprGenBase: # ============================================================ # 转义 LLVM IR 字符串字面量 # ============================================================ - def escape_llvm_string(self, pool: memhub.MemBuddy*, - src: str) -> str: + def escape_llvm_string(self, pool: memhub.MemBuddy*, src: str) -> str: """将字符串转换为 LLVM IR 字符串字面量 c"...\\00" """ if src is None: return None slen: sizet = string.strlen(src) @@ -203,8 +202,7 @@ novirtual class ExprGenBase: # 返回类名字符串或 None。用于 subscript 操作中判断是否需要 # 转发到 __getitem__/__setitem__ 而非生成 GEP。 # ============================================================ - def _get_custom_struct_cls_nm(self, pool: memhub.MemBuddy*, - ty: mlirlite.LLVMType*) -> str: + def _get_custom_struct_cls_nm(self, pool: memhub.MemBuddy*, ty: mlirlite.LLVMType*) -> str: """检查 ty 或 ty 的 pointee 是否是已注册的自定义结构体,返回类名或 None""" if ty is None: return None # 直接检查 ty 是否是注册的结构体 @@ -223,9 +221,7 @@ novirtual class ExprGenBase: # - 普通结构体指针数组(如 pts: Point*):get_subscript_ptr 返回元素地址 # 路由错误会让 list[T] 被当作结构体数组 GEP,访问错位崩溃。 # ============================================================ - def _is_list_subscript_base(self, pool: memhub.MemBuddy*, - trans: HT.Translator*, - sub_node: ast.AST*) -> int: + def _is_list_subscript_base(self, pool: memhub.MemBuddy*, trans: HT.Translator*, sub_node: ast.AST*) -> int: """判断下标基座是否为 list[T] 变量(1=是)""" if sub_node is None or trans is None: return 0 sub: ast.Subscript* = ast.Subscript*(sub_node) @@ -252,9 +248,7 @@ novirtual class ExprGenBase: # ============================================================ # _sub_base_class_name - 解析下标基座变量的结构体类名 # ============================================================ - def _sub_base_class_name(self, pool: memhub.MemBuddy*, - trans: HT.Translator*, - sub_node: ast.AST*) -> str: + def _sub_base_class_name(self, pool: memhub.MemBuddy*, trans: HT.Translator*, sub_node: ast.AST*) -> str: """解析下标基座变量的结构体类名(无则 None)""" if sub_node is None or trans is None: return None sub: ast.Subscript* = ast.Subscript*(sub_node) @@ -279,10 +273,7 @@ novirtual class ExprGenBase: # - 普通结构体指针数组(如 pts: Point*)→ get_subscript_ptr # (GEP 元素地址,避免结构体值 base=非指针 报错) # ============================================================ - def _sub_base_uses_getitem(self, pool: memhub.MemBuddy*, - mod: mlirlite.LLVMModule*, - trans: HT.Translator*, - sub_node: ast.AST*) -> int: + def _sub_base_uses_getitem(self, pool: memhub.MemBuddy*, mod: mlirlite.LLVMModule*, trans: HT.Translator*, sub_node: ast.AST*) -> int: """下标基座应走 __getitem__ 语义时返回 1,否则 0(应走 GEP 地址语义)""" if self._is_list_subscript_base(pool, trans, sub_node) != 0: return 1 cls_ugi: str = self._sub_base_class_name(pool, trans, sub_node) @@ -299,8 +290,7 @@ novirtual class ExprGenBase: # - 值类型变量 (cnt: Counter): alloca 类型是 Ptr(Struct) → 不解引用 # - 指针类型变量 (r: Vec2*): alloca 类型是 Ptr(Ptr(Struct)) → load 解引用 # ============================================================ - def _deref_if_ptr_ptr(self, builder: mlirlite.IRBuilder*, - obj_ptr: mlirlite.Value*) -> mlirlite.Value*: + def _deref_if_ptr_ptr(self, builder: mlirlite.IRBuilder*, obj_ptr: mlirlite.Value*) -> mlirlite.Value*: """如果 obj_ptr 是 Ptr(Ptr(...)),load 解引用获取内层指针""" if obj_ptr is None or obj_ptr.Ty is None: return obj_ptr if self.is_ptr_type(obj_ptr.Ty) == 0: return obj_ptr @@ -356,8 +346,7 @@ novirtual class ExprGenBase: # (实测上述用例 node 是 Assign,kind=3,col_offset=-1),拿不到 Constant # 节点,只能靠已经生成好的值来判定。 # ============================================================ - def IsNoneValue(self, val: mlirlite.Value*, - node: ast.AST* = None) -> int: + def IsNoneValue(self, val: mlirlite.Value*, node: ast.AST* = None) -> int: """判据:val/node 是否表示 None(空值常量),1=是 / 0=否""" # 判据①:AST 是 None 字面量 if node is not None and node.kind() == ast.ASTKind.Constant: @@ -377,8 +366,7 @@ novirtual class ExprGenBase: # 指针目标不在此处处理:coerce_to_type 的「指针→指针 bitcast」路径已能 # 接受 None(i8* null → T*),保留其原有 IR 形态。 # ============================================================ - def _NoneValueAsTarget(self, builder: mlirlite.IRBuilder*, - target_ty: mlirlite.LLVMType*) -> mlirlite.Value*: + def _NoneValueAsTarget(self, builder: mlirlite.IRBuilder*, target_ty: mlirlite.LLVMType*) -> mlirlite.Value*: """把 None 转换为目标类型的空值/零值""" if target_ty is None: return None pool: memhub.MemBuddy* = builder.Pool @@ -452,9 +440,7 @@ novirtual class ExprGenBase: pass return 2 return 0 - def fail_if_str_annot_agg_ptr(self, val: mlirlite.Value*, - annot_is_str: int, - node: ast.AST* = None) -> int: + def fail_if_str_annot_agg_ptr(self, val: mlirlite.Value*, annot_is_str: int, node: ast.AST* = None) -> int: """注解侧是裸 str/bytes 而值是指向聚合类型的指针 → fail-fast(返回 1) 判据见 _str_rejects_ptr_kind(结构体/类/联合/非字符数组/函数指针拒绝; @@ -463,14 +449,9 @@ novirtual class ExprGenBase: """ if annot_is_str == 0 or val is None or val.Ty is None: return 0 if self._str_rejects_ptr_kind(val) == 0: return 0 - self.Gen.TypeGenErr.fatal_error(self._value_node_of(node), - "str/bytes 不接受指向非基本类型(结构体/类/非字符数组/函数)的指针:两者在 IR 层" - "同为 i8*,但语义不同(str/bytes 不是通用指针通配)。若确需传递指针," - "请改用 t.CPtr/rawptr 形参,或显式转换(如 t.CPtr(p))", "CastError") + self.Gen.TypeGenErr.fatal_error(self._value_node_of(node), "str/bytes 不接受指向非基本类型(结构体/类/非字符数组/函数)的指针:两者在 IR 层" "同为 i8*,但语义不同(str/bytes 不是通用指针通配)。若确需传递指针," "请改用 t.CPtr/rawptr 形参,或显式转换(如 t.CPtr(p))", "CastError") return 1 - def fail_if_str_annot_ast_agg_ptr(self, val: mlirlite.Value*, - annot: ast.AST*, - node: ast.AST* = None) -> int: + def fail_if_str_annot_ast_agg_ptr(self, val: mlirlite.Value*, annot: ast.AST*, node: ast.AST* = None) -> int: """注解 AST 形态的入口:注解为裸 str/bytes 且值是指向聚合类型的指针 → fail-fast 供注解来源是 AST 的三条路径复用:赋值侧 aa.annotation、返回侧 @@ -497,8 +478,7 @@ novirtual class ExprGenBase: # ≥ 整数位宽;浮点→整数不允许)。 # 返回 PC_OK(无损/允许)或 PC_LOSSY(有损/禁止)。 # ============================================================ - def _scalar_convert_reason(self, src_pt: mlirlite.LLVMType*, - dst_pt: mlirlite.LLVMType*) -> int: + def _scalar_convert_reason(self, src_pt: mlirlite.LLVMType*, dst_pt: mlirlite.LLVMType*) -> int: """基本标量 src_pt → dst_pt 的隐式转换判定码(PC_OK / PC_LOSSY)""" s_int: int = self.get_llvm_type_bits(src_pt) d_int: int = self.get_llvm_type_bits(dst_pt) @@ -522,8 +502,7 @@ novirtual class ExprGenBase: # 优先匹配 + 按名/后缀回退),把 LLVM 被指类型映射到类名;非结构体/未注册 # 返回 None。不新造表。 # ============================================================ - def _class_name_of_ptr_pointee(self, pool: memhub.MemBuddy*, - pt: mlirlite.LLVMType*) -> str: + def _class_name_of_ptr_pointee(self, pool: memhub.MemBuddy*, pt: mlirlite.LLVMType*) -> str: """指针被指类型映射到已注册类名;失败返回 None""" if pt is None: return None return self.Gen.StructGen.get_class_name_by_type(pool, pt) @@ -536,9 +515,7 @@ novirtual class ExprGenBase: # 不引入新表。下转(Base* → Derived*:派生类不在基类 MRO 链里)与无关 # 类型(Foo* ↔ Bar*)都不命中 ⇒ 返回 0,仍按规则 2/3 禁止。 # ============================================================ - def _is_inheritance_upcast(self, pool: memhub.MemBuddy*, - src_pt: mlirlite.LLVMType*, - dst_pt: mlirlite.LLVMType*) -> int: + def _is_inheritance_upcast(self, pool: memhub.MemBuddy*, src_pt: mlirlite.LLVMType*, dst_pt: mlirlite.LLVMType*) -> int: """派生类指针 → 基类指针(含多级):1=允许上转 / 0=否""" src_name: str = self._class_name_of_ptr_pointee(pool, src_pt) if src_name is None: return 0 @@ -565,9 +542,7 @@ novirtual class ExprGenBase: # 元素类型同一性复用本仓既有 AssignGen._stg_ty_equal(内容比较),不新造表。 # 返回 1=允许退让 / 0=否。 # ============================================================ - def _is_array_decay(self, pool: memhub.MemBuddy*, - src_pt: mlirlite.LLVMType*, - dst_pt: mlirlite.LLVMType*) -> int: + def _is_array_decay(self, pool: memhub.MemBuddy*, src_pt: mlirlite.LLVMType*, dst_pt: mlirlite.LLVMType*) -> int: """源被指类型是定长数组且目标被指类型是其元素类型:1=是 / 0=否""" if src_pt is None or dst_pt is None: return 0 if self.is_array_type(src_pt) == 0: return 0 @@ -592,9 +567,7 @@ novirtual class ExprGenBase: # 时一律不匹配 ⇒ PC_NONBASIC。 # 被指类型仍是指针(T** → U**):递归按指针规则判。 # ============================================================ - def _pointee_convert_reason(self, pool: memhub.MemBuddy*, - src_pt: mlirlite.LLVMType*, - dst_pt: mlirlite.LLVMType*) -> int: + def _pointee_convert_reason(self, pool: memhub.MemBuddy*, src_pt: mlirlite.LLVMType*, dst_pt: mlirlite.LLVMType*) -> int: """被指类型 src_pt → dst_pt 的判定码(PC_OK/PC_NONBASIC/PC_LOSSY/PC_DEPTH)""" if src_pt is None or dst_pt is None: return PC_OK s_is_ptr: int = self.is_ptr_type(src_pt) @@ -624,9 +597,7 @@ novirtual class ExprGenBase: # 规则 4:完全相同类型(指针深度与被指类型都相同,含 Foo* → Foo*)不算转换 ⇒ PC_OK。 # 返回 PC_OK(允许)/ PC_DEPTH / PC_NONBASIC / PC_LOSSY。 # ============================================================ - def _ptr_cast_reason(self, pool: memhub.MemBuddy*, - src_ty: mlirlite.LLVMType*, - dst_ty: mlirlite.LLVMType*) -> int: + def _ptr_cast_reason(self, pool: memhub.MemBuddy*, src_ty: mlirlite.LLVMType*, dst_ty: mlirlite.LLVMType*) -> int: """指针 → 指针对隐式转换的判定码(PC_OK 表示允许)""" if src_ty is None or dst_ty is None: return PC_OK slev: int = self.get_ptr_level(src_ty) @@ -643,8 +614,7 @@ novirtual class ExprGenBase: # ============================================================ # _type_text - LLVM 类型的可读文本(TypePrint),供报文使用(失败返回 "?") # ============================================================ - def _type_text(self, pool: memhub.MemBuddy*, - ty: mlirlite.LLVMType*) -> str: + def _type_text(self, pool: memhub.MemBuddy*, ty: mlirlite.LLVMType*) -> str: """LLVM 类型文本(TypePrint);失败返回 "?" """ if ty is None: return "?" buf: str = pool.alloc(512) @@ -658,9 +628,7 @@ novirtual class ExprGenBase: # 报文写清「哪一级不允许 + 为什么(非基本类型 / 有损 / 层数不同)」,并给出 # 源/目标 LLVM 类型文本。返回值会逃逸 ⇒ 经 escape_fstring_copy 拷到 stdlib 堆。 # ============================================================ - def _ptr_cast_reason_text(self, code: int, pool: memhub.MemBuddy*, - src_ty: mlirlite.LLVMType*, - dst_ty: mlirlite.LLVMType*) -> str: + def _ptr_cast_reason_text(self, code: int, pool: memhub.MemBuddy*, src_ty: mlirlite.LLVMType*, dst_ty: mlirlite.LLVMType*) -> str: """指针间隐式转换禁止原因的可读文本(含源/目标类型)""" why: str = "原因未知" if code == PC_DEPTH: why = f"指针层数不同(源 {self.get_ptr_level(src_ty)} 级 → 目标 {self.get_ptr_level(dst_ty)} 级)" @@ -718,19 +686,14 @@ novirtual class ExprGenBase: # ============================================================ # _same_agg_ty - 两个聚合类型是否为「同一非基本类型」(构造物化豁免的类型匹配) # ============================================================ - def _same_agg_ty(self, pool: memhub.MemBuddy*, - a: mlirlite.LLVMType*, b: mlirlite.LLVMType*) -> int: + def _same_agg_ty(self, pool: memhub.MemBuddy*, a: mlirlite.LLVMType*, b: mlirlite.LLVMType*) -> int: """a、b 是否为同一聚合类型,1=是 / 0=否""" if a is None or b is None: return 0 return self.Gen.AssignGen._stg_ty_equal(pool, a, b) # ============================================================ # 类型强制转换:整数 sext/trunc,浮点 fpext/fptrunc,int↔float si2fp/fp2si # ============================================================ - def coerce_to_type(self, builder: mlirlite.IRBuilder*, - val: mlirlite.Value*, - target_ty: mlirlite.LLVMType*, - node: ast.AST* = None, - trans: HT.Translator* = None) -> mlirlite.Value*: + def coerce_to_type(self, builder: mlirlite.IRBuilder*, val: mlirlite.Value*, target_ty: mlirlite.LLVMType*, node: ast.AST* = None, trans: HT.Translator* = None) -> mlirlite.Value*: """将 val 强制转换为 target_ty 整数: sext(扩展)/ trunc(截断) @@ -759,8 +722,7 @@ novirtual class ExprGenBase: # 属「无值传递」,放行。 if self.Gen.StmtGenDecl._is_void_type(val.Ty) != 0: if self.Gen.StmtGenDecl._is_void_type(target_ty) == 0: - self.Gen.TypeGenErr.fatal_error(self._value_node_of(node), - "void 类型的值不能参与任何操作(void 只能用于 void* 与 typedef 别名)", "TypeError") + self.Gen.TypeGenErr.fatal_error(self._value_node_of(node), "void 类型的值不能参与任何操作(void 只能用于 void* 与 typedef 别名)", "TypeError") return val # 函数 → 指针: bitcast(如 CreateThread(..., _thread_alloc_free, ...) 传函数指针) # 函数 Value 的 Ty 是 Func,既不是整数也不是指针,需在整数/浮点转换之前处理 @@ -788,8 +750,7 @@ novirtual class ExprGenBase: # (inttoptr 要求同宽,对齐 MatchGenMixin 模式),再 inttoptr 成空指针。 if val.IsConst == 1 and val.IntVal == 0: return mlirlite.build_inttoptr(builder, mlirlite.const_int64(builder.Pool, 0), target_ty) m_i2p: str = "整数隐式转指针已禁止:必须显式强转为指针(如 t.CPtr(x))才能把整数赋给指针类型" - self.Gen.TypeGenErr.fatal_error(self._value_node_of(node), - m_i2p, "CastError") + self.Gen.TypeGenErr.fatal_error(self._value_node_of(node), m_i2p, "CastError") return val # Pointer -> integer: rejected (symmetric with the integer -> pointer rule above). # No implicit pointer <-> integer conversion is allowed; an explicit cast is @@ -797,8 +758,7 @@ novirtual class ExprGenBase: # through to the build_load branch below, copying the pointee's first byte.) if self.is_ptr_type(val.Ty) != 0 and target_bits != 0 and self.is_ptr_type(target_ty) == 0: m_p2i: str = "指针隐式转整数已禁止:必须显式强转(如 uint64(p) / int64(p) / int(p))才能把指针赋给整数类型" - self.Gen.TypeGenErr.fatal_error(self._value_node_of(node), - m_p2i, "CastError") + self.Gen.TypeGenErr.fatal_error(self._value_node_of(node), m_p2i, "CastError") return val if val_bits != 0 and target_bits != 0: if val_bits == target_bits: return val @@ -840,8 +800,7 @@ novirtual class ExprGenBase: target_fbits: int = self.get_llvm_float_bits(target_ty) # float ↔ ptr: 禁止(无意义的转换,fast-fail 防止误走入 build_load 路径) if (val_fbits != 0 and self.is_ptr_type(target_ty) != 0) or (self.is_ptr_type(val.Ty) != 0 and target_fbits != 0): - self.Gen.TypeGenErr.fatal_error(self._value_node_of(node), - "unsupported type conversion: float <-> ptr", "CastError") + self.Gen.TypeGenErr.fatal_error(self._value_node_of(node), "unsupported type conversion: float <-> ptr", "CastError") return val if val_fbits != 0 and target_fbits != 0: if val_fbits == target_fbits: return val @@ -860,10 +819,8 @@ novirtual class ExprGenBase: ctor_v2p: mlirlite.LLVMType* = self._ctor_call_agg_ty(node) if self._same_agg_ty(builder.Pool, ctor_v2p, val.Ty) == 0: m_v2p: str = "非基本类型的值/指针隐式转换已禁止(构造物化除外):不能把非基本类型值隐式转为指针(Foo → Foo*),如需取址请显式 c.addr(...) / &v,或显式强转" - v2p_txt: str = GenApi.escape_fstring_copy( - f";源值类型 {self._type_text(builder.Pool, val.Ty)} → 目标类型 {self._type_text(builder.Pool, target_ty)}") - self.Gen.TypeGenErr.fatal_error(self._value_node_of(node), - f"{m_v2p}{v2p_txt}", "CastError") + v2p_txt: str = GenApi.escape_fstring_copy(f";源值类型 {self._type_text(builder.Pool, val.Ty)} → 目标类型 {self._type_text(builder.Pool, target_ty)}") + self.Gen.TypeGenErr.fatal_error(self._value_node_of(node), f"{m_v2p}{v2p_txt}", "CastError") return val tmp_agg: mlirlite.Value* = self.Gen.VarGen._alloca_at_entry(builder, val.Ty) if tmp_agg is not None: @@ -888,14 +845,11 @@ novirtual class ExprGenBase: ctor_p2v: mlirlite.LLVMType* = self._ctor_call_agg_ty(node) if self._same_agg_ty(builder.Pool, ctor_p2v, target_ty) == 0: m_p2v: str = "非基本类型的值/指针隐式转换已禁止(构造物化除外):不能把指针类型隐式转为非基本类型值(Foo* → Foo),如需解引用请显式 c.deref(p) / *p,或显式强转" - p2v_txt: str = GenApi.escape_fstring_copy( - f";源类型 {self._type_text(builder.Pool, val.Ty)} → 目标值类型 {self._type_text(builder.Pool, target_ty)}") - self.Gen.TypeGenErr.fatal_error(self._value_node_of(node), - f"{m_p2v}{p2v_txt}", "CastError") + p2v_txt: str = GenApi.escape_fstring_copy(f";源类型 {self._type_text(builder.Pool, val.Ty)} → 目标值类型 {self._type_text(builder.Pool, target_ty)}") + self.Gen.TypeGenErr.fatal_error(self._value_node_of(node), f"{m_p2v}{p2v_txt}", "CastError") return val return mlirlite.build_load(builder, target_ty, val) - self.Gen.TypeGenErr.fatal_error(self._value_node_of(node), - f"指针隐式转非指针值已禁止:必须显式解引用(*p / *p)或显式强转(uint64(p))", "CastError") + self.Gen.TypeGenErr.fatal_error(self._value_node_of(node), f"指针隐式转非指针值已禁止:必须显式解引用(*p / *p)或显式强转(uint64(p))", "CastError") return val # 指针 → 指针: 隐式转换须满足两条新规则(见 _ptr_cast_reason 单一真源): # 规则 1 通用指针(t.CPtr / i8*)与任何 T* 双向互转都放行; @@ -907,16 +861,12 @@ novirtual class ExprGenBase: pc: int = self._ptr_cast_reason(builder.Pool, val.Ty, target_ty) if pc != PC_OK: reason: str = self._ptr_cast_reason_text(pc, builder.Pool, val.Ty, target_ty) - self.Gen.TypeGenErr.fatal_error(self._value_node_of(node), - reason, "CastError") + self.Gen.TypeGenErr.fatal_error(self._value_node_of(node), reason, "CastError") return val return mlirlite.build_bitcast(builder, val, target_ty) return val - def _zext_or_sext_val(self, pool: memhub.MemBuddy*, - val: mlirlite.Value*, - node: ast.AST* = None, - trans: HT.Translator* = None) -> int: + def _zext_or_sext_val(self, pool: memhub.MemBuddy*, val: mlirlite.Value*, node: ast.AST* = None, trans: HT.Translator* = None) -> int: """统一整数拓宽方向:1=zext(无符号语义),0=sext 委托到 ExprGenOps.should_zext_widen(拓宽方向的**单一真源**),避免两套 @@ -932,11 +882,7 @@ novirtual class ExprGenBase: return self.Gen.ExprGenOps.should_zext_widen(pool, val, None, node, trans) # translate_ptr_arith:指针算术 ptr±int,用 getelementptr(按 pointee 元素大小缩放索引,对齐 TPC ExprGen.emit_binary_op / HandlesAugAssign.py);数组 pointee([N x ty]*)先 decay 为元素指针(GEP 0,0),避免以整个数组为步长 - def translate_ptr_arith(self, pool: memhub.MemBuddy*, - builder: mlirlite.IRBuilder*, - ptr_val: mlirlite.Value*, - int_val: mlirlite.Value*, - op: int) -> mlirlite.Value*: + def translate_ptr_arith(self, pool: memhub.MemBuddy*, builder: mlirlite.IRBuilder*, ptr_val: mlirlite.Value*, int_val: mlirlite.Value*, op: int) -> mlirlite.Value*: """指针算术: ptr + int / ptr - int → GEP(按元素大小缩放索引)""" if ptr_val is None or int_val is None or ptr_val.Ty is None: return None # 提取 pointee 类型(非指针 → 不处理返回 None) diff --git a/App/lib/core/Gen/Expr/ExprGenCdef.vp b/App/lib/core/Gen/Expr/ExprGenCdef.vp index 43c835e..cbf547b 100644 --- a/App/lib/core/Gen/Expr/ExprGenCdef.vp +++ b/App/lib/core/Gen/Expr/ExprGenCdef.vp @@ -58,15 +58,10 @@ novirtual class ExprGenCdef(ExprGenBase.ExprGenBase): inc_dir: str = inc_arr_ptr + iidx if inc_dir[0] != '\0': base_dir = inc_dir if base_dir is None and string.strlen(rel_path) >= 4: - if (rel_path[0] == 'l' and rel_path[1] == 'i' and - rel_path[2] == 'b' and rel_path[3] == '/'): + if (rel_path[0] == 'l' and rel_path[1] == 'i' and rel_path[2] == 'b' and rel_path[3] == '/'): base_dir = Config.SourceDir if Config.SourceDir is not None else Config.IncludesDir if base_dir is None and string.strlen(rel_path) >= 9: - if (rel_path[0] == 'i' and rel_path[1] == 'n' and - rel_path[2] == 'c' and rel_path[3] == 'l' and - rel_path[4] == 'u' and rel_path[5] == 'd' and - rel_path[6] == 'e' and rel_path[7] == 's' and - rel_path[8] == '/'): + if (rel_path[0] == 'i' and rel_path[1] == 'n' and rel_path[2] == 'c' and rel_path[3] == 'l' and rel_path[4] == 'u' and rel_path[5] == 'd' and rel_path[6] == 'e' and rel_path[7] == 's' and rel_path[8] == '/'): rel_used = rel_path + 9 base_dir = Config.IncludesDir if base_dir is None: base_dir = Config.SourceDir if Config.SourceDir is not None else Config.IncludesDir @@ -108,12 +103,7 @@ novirtual class ExprGenCdef(ExprGenBase.ExprGenBase): # # pyi 文件格式: "NAME: t.CDefine = value" # ============================================================ - def _lookup_cross_module_cdefine(self, pool: memhub.MemBuddy*, - name: str, - from_imports: str, - imported_modules: str = None, - depth: int = 0, - node: ast.AST* = None) -> int64: + def _lookup_cross_module_cdefine(self, pool: memhub.MemBuddy*, name: str, from_imports: str, imported_modules: str = None, depth: int = 0, node: ast.AST* = None) -> int64: """跨模块查找 CDefine 常量,返回值(64 位)或 -1(未找到) 查找顺序: @@ -135,13 +125,9 @@ novirtual class ExprGenCdef(ExprGenBase.ExprGenBase): if depth > 32: err_buf: str = pool.alloc(256) if err_buf is not None: - viperlib.snprintf(err_buf, 256, - "跨模块 CDefine 查找递归过深(疑似模块循环 import/re-export): %s (depth=%d fi=%s)", - name, depth, - from_imports if from_imports is not None else "(nil)") + viperlib.snprintf(err_buf, 256, "跨模块 CDefine 查找递归过深(疑似模块循环 import/re-export): %s (depth=%d fi=%s)", name, depth, from_imports if from_imports is not None else "(nil)") self.Gen.TypeGenErr.fatal_error(node, err_buf, "InternalCompilerError") - self.Gen.TypeGenErr.fatal_error(node, - "跨模块 CDefine 查找递归过深(疑似模块循环 import/re-export)", "InternalCompilerError") + self.Gen.TypeGenErr.fatal_error(node, "跨模块 CDefine 查找递归过深(疑似模块循环 import/re-export)", "InternalCompilerError") # 入口处清零标志,确保所有早退路径(return -1)都返回"未找到"状态 # 避免递归调用时前一次成功的标志残留导致误判 self.Gen.TypeGenCDef.set_cdefine_found(0) @@ -286,11 +272,7 @@ novirtual class ExprGenCdef(ExprGenBase.ExprGenBase): cs_total: sizet = string.strlen(pyi_buf) cs_i: sizet = 0 while cs_i + 9 < cs_total: - if (pyi_buf[cs_i] == 't' and pyi_buf[cs_i + 1] == '.' and - pyi_buf[cs_i + 2] == 'C' and pyi_buf[cs_i + 3] == 'D' and - pyi_buf[cs_i + 4] == 'e' and pyi_buf[cs_i + 5] == 'f' and - pyi_buf[cs_i + 6] == 'i' and pyi_buf[cs_i + 7] == 'n' and - pyi_buf[cs_i + 8] == 'e'): + if (pyi_buf[cs_i] == 't' and pyi_buf[cs_i + 1] == '.' and pyi_buf[cs_i + 2] == 'C' and pyi_buf[cs_i + 3] == 'D' and pyi_buf[cs_i + 4] == 'e' and pyi_buf[cs_i + 5] == 'f' and pyi_buf[cs_i + 6] == 'i' and pyi_buf[cs_i + 7] == 'n' and pyi_buf[cs_i + 8] == 'e'): # 检查该行剩余部分是否有 '='(带值声明才在 vpi 中匹配) cd_eq: int = 0 cs_j: sizet = cs_i + 9 @@ -323,10 +305,7 @@ novirtual class ExprGenCdef(ExprGenBase.ExprGenBase): # 报错终止,不静默返回 -1(避免后续生成错误的 @UNDEFINED 全局变量引用) err_buf: str = pool.alloc(512) if err_buf is not None: - viperlib.snprintf(err_buf, 512, - "跨模块 CDefine 查找失败:SHA1 %s 不在存储器中(base_mod=%s name=%s)。" - "Phase1/Phase2 未正确填充 PopulateSha1MapStore/AppendToSha1MapStore", - sha1, base_mod, name) + viperlib.snprintf(err_buf, 512, "跨模块 CDefine 查找失败:SHA1 %s 不在存储器中(base_mod=%s name=%s)。" "Phase1/Phase2 未正确填充 PopulateSha1MapStore/AppendToSha1MapStore", sha1, base_mod, name) VLogger.error(err_buf, "XMOD-CD") stdlib.free(pyi_buf) return -1 @@ -375,11 +354,7 @@ novirtual class ExprGenCdef(ExprGenBase.ExprGenBase): has_cdefine: int = 0 ci: sizet = line_start + name_len + 1 while ci + 8 <= line_start + line_len: - if (pyi_buf[ci] == 't' and pyi_buf[ci + 1] == '.' and - pyi_buf[ci + 2] == 'C' and pyi_buf[ci + 3] == 'D' and - pyi_buf[ci + 4] == 'e' and pyi_buf[ci + 5] == 'f' and - pyi_buf[ci + 6] == 'i' and pyi_buf[ci + 7] == 'n' and - pyi_buf[ci + 8] == 'e'): + if (pyi_buf[ci] == 't' and pyi_buf[ci + 1] == '.' and pyi_buf[ci + 2] == 'C' and pyi_buf[ci + 3] == 'D' and pyi_buf[ci + 4] == 'e' and pyi_buf[ci + 5] == 'f' and pyi_buf[ci + 6] == 'i' and pyi_buf[ci + 7] == 'n' and pyi_buf[ci + 8] == 'e'): has_cdefine = 1 break ci += 1 @@ -457,9 +432,7 @@ novirtual class ExprGenCdef(ExprGenBase.ExprGenBase): while eq_pos < line_start + line_len and is_name_val == 0 and is_str_val == 0: ch: char = pyi_buf[eq_pos] if is_hex == 1: - if ((ch >= '0' and ch <= '9') or - (ch >= 'a' and ch <= 'f') or - (ch >= 'A' and ch <= 'F')): + if ((ch >= '0' and ch <= '9') or (ch >= 'a' and ch <= 'f') or (ch >= 'A' and ch <= 'F')): val_str_len += 1 eq_pos += 1 else: break @@ -589,9 +562,7 @@ novirtual class ExprGenCdef(ExprGenBase.ExprGenBase): while eq_pos < line_start + line_len and r_name == 0: c_r2: char = pyi_buf[eq_pos] if r_hex == 1: - if ((c_r2 >= '0' and c_r2 <= '9') or - (c_r2 >= 'a' and c_r2 <= 'f') or - (c_r2 >= 'A' and c_r2 <= 'F')): + if ((c_r2 >= '0' and c_r2 <= '9') or (c_r2 >= 'a' and c_r2 <= 'f') or (c_r2 >= 'A' and c_r2 <= 'F')): r_len += 1 eq_pos += 1 else: break @@ -933,8 +904,7 @@ novirtual class ExprGenCdef(ExprGenBase.ExprGenBase): # ============================================================ # 翻译变量引用(Name 节点)→ load # ============================================================ - def _const_int_for_cdefine(self, pool: memhub.MemBuddy*, - value: int64) -> mlirlite.Value*: + def _const_int_for_cdefine(self, pool: memhub.MemBuddy*, value: int64) -> mlirlite.Value*: """CDefine 整数常量 → LLVM 常量(对齐 TPC TypeConvert 的 64 位升级) **使用处宽度("W_min + 使用处宽度"规则)与物化宽度的关系**(与 TPC 同口径, @@ -1002,11 +972,7 @@ novirtual class ExprGenCdef(ExprGenBase.ExprGenBase): return value return value - def cdefine_use_width_value(self, pool: memhub.MemBuddy*, - node: ast.AST*, name: str, - value: int64, - target_ty: mlirlite.LLVMType*, - use_ctx: str = None) -> mlirlite.Value*: + def cdefine_use_width_value(self, pool: memhub.MemBuddy*, node: ast.AST*, name: str, value: int64, target_ty: mlirlite.LLVMType*, use_ctx: str = None) -> mlirlite.Value*: """CDefine 整数常量在**已知使用处类型**时的物化(与 TPC 同口径)。 返回 None ⇒ "取不到使用处宽度"(调用方沿用 _const_int_for_cdefine 的 @@ -1048,15 +1014,6 @@ novirtual class ExprGenCdef(ExprGenBase.ExprGenBase): # 构建字符串一律用本仓库惯用法:f-string 插值 / string.strcat / # viperlib.snprintf。 ctx = f"({use_ctx})" - self.Gen.TypeGenErr.fatal_error( - node, - f"[TPV] define 常量使用处宽度不足: 常量 '{name}' 的实际值 {value} " - f"需要至少 {wmin} 位(最小可容纳宽度 W_min)," - f"但使用处{ctx}只提供 {bits} 位" - f"(该位宽按有符号/无符号两种解释可接受的范围: {lo}..{hi})。" - f"禁止静默截断/降级,已终止编译。" - f"修法: 把使用处{ctx}的类型加宽到至少 {wmin} 位" - f"(如 int{wmin}T / CUInt{wmin}T 及更宽类型),或改用更小的常量值。", - "TypeError") + self.Gen.TypeGenErr.fatal_error(node, f"[TPV] define 常量使用处宽度不足: 常量 '{name}' 的实际值 {value} " f"需要至少 {wmin} 位(最小可容纳宽度 W_min)," f"但使用处{ctx}只提供 {bits} 位" f"(该位宽按有符号/无符号两种解释可接受的范围: {lo}..{hi})。" f"禁止静默截断/降级,已终止编译。" f"修法: 把使用处{ctx}的类型加宽到至少 {wmin} 位" f"(如 int{wmin}T / CUInt{wmin}T 及更宽类型),或改用更小的常量值。", "TypeError") return None return mlirlite.const_int(pool, bits, self._cdefine_bits_value(value, bits)) \ No newline at end of file diff --git a/App/lib/core/Gen/Expr/ExprGenCls.vp b/App/lib/core/Gen/Expr/ExprGenCls.vp index c487771..1e3c813 100644 --- a/App/lib/core/Gen/Expr/ExprGenCls.vp +++ b/App/lib/core/Gen/Expr/ExprGenCls.vp @@ -127,8 +127,7 @@ novirtual class ExprGenCls(ExprGenBase.ExprGenBase): viperlib.snprintf(sym_buf, cl_nl + mt_nl + 2, "%s.%s", cd.name, mfd.name) self.register_docstring(module_sha1, sym_buf, mdoc) stdlib.free(sym_buf) - def _resolve_doc_symbol_name(self, trans: HT.Translator*, name_id: str, - out_mod: str, out_sym: str) -> int: + def _resolve_doc_symbol_name(self, trans: HT.Translator*, name_id: str, out_mod: str, out_sym: str) -> int: """解析 Name 符号的 docstring 归属,写入 out_mod/out_sym,成功返回 1 判定顺序:本地变量(函数变量)→ 结构体类(含跨模块预注册)→ 模块名。 @@ -159,9 +158,7 @@ novirtual class ExprGenCls(ExprGenBase.ExprGenBase): string.strcpy(out_mod, trans.ModuleSha1) string.strcpy(out_sym, name_id) return 1 - def _resolve_doc_symbol_attr(self, trans: HT.Translator*, - at: ast.Attribute*, - out_mod: str, out_sym: str) -> int: + def _resolve_doc_symbol_attr(self, trans: HT.Translator*, at: ast.Attribute*, out_mod: str, out_sym: str) -> int: """解析嵌套 Attribute 链的 docstring 归属,写入 out_mod/out_sym 支持形态:remote.remote_func / remote.RemoteClass / @@ -254,10 +251,7 @@ novirtual class ExprGenCls(ExprGenBase.ExprGenBase): # Attribute → 字段注解类名(_resolve_attr_field_class) # 仅采用已注册结构体;无法精确推断返回 None(fail-fast 由调用方暴露)。 # ============================================================ - def infer_expr_class(self, pool: memhub.MemBuddy*, - mod: mlirlite.LLVMModule*, - node: ast.AST*, - trans: HT.Translator*) -> str: + def infer_expr_class(self, pool: memhub.MemBuddy*, mod: mlirlite.LLVMModule*, node: ast.AST*, trans: HT.Translator*) -> str: """从表达式推断结构体类名,无法推断返回 None""" if node is None or trans is None: return None k: int = node.kind() @@ -279,14 +273,12 @@ novirtual class ExprGenCls(ExprGenBase.ExprGenBase): if ca.value.kind() == ast.ASTKind.Name: mod_nm2: str = (ast.Name*(ca.value)).id if mod_nm2 is not None and trans._from_imports is not None: - mod_sha1_2: str = self.Gen.CallGenBase._lookup_mod_sha1( - pool, trans._from_imports, mod_nm2) + mod_sha1_2: str = self.Gen.CallGenBase._lookup_mod_sha1(pool, trans._from_imports, mod_nm2) if mod_sha1_2 is not None: temp_dir2: str = None if self.Gen.CallGenBase.TempDir is not None: temp_dir2 = self.Gen.CallGenBase.TempDir if temp_dir2 is not None: VpiReader._ensure_vpi_ret_annot_loaded(mod_sha1_2, temp_dir2) - annot_ret2: str = VpiReader._lookup_vpi_ret_annot( - mod_sha1_2, None, ca.attr) + annot_ret2: str = VpiReader._lookup_vpi_ret_annot(mod_sha1_2, None, ca.attr) if annot_ret2 is not None: ret_cls2: str = self._extract_annot_class_name(pool, annot_ret2) if ret_cls2 is not None: return ret_cls2 diff --git a/App/lib/core/Gen/Expr/ExprGenConst.vp b/App/lib/core/Gen/Expr/ExprGenConst.vp index 5fe4913..9b9406e 100644 --- a/App/lib/core/Gen/Expr/ExprGenConst.vp +++ b/App/lib/core/Gen/Expr/ExprGenConst.vp @@ -22,11 +22,7 @@ novirtual class ExprGenConst(ExprGenBase.ExprGenBase): # ============================================================ # 创建全局字符串常量 # ============================================================ - def create_global_string(self, builder: mlirlite.IRBuilder*, - pool: memhub.MemBuddy*, - mod: mlirlite.LLVMModule*, - str_val: str, - trans: HT.Translator*) -> mlirlite.Value*: + def create_global_string(self, builder: mlirlite.IRBuilder*, pool: memhub.MemBuddy*, mod: mlirlite.LLVMModule*, str_val: str, trans: HT.Translator*) -> mlirlite.Value*: """创建全局字符串常量并返回 i8* bitcast""" escaped: str = self.escape_llvm_string(pool, str_val) if escaped is None: return None @@ -71,12 +67,7 @@ novirtual class ExprGenConst(ExprGenBase.ExprGenBase): # ============================================================ # 翻译常量表达式 # ============================================================ - def translate_constant(self, builder: mlirlite.IRBuilder*, - pool: memhub.MemBuddy*, - mod: mlirlite.LLVMModule*, - node: ast.AST*, - trans: HT.Translator* = None, - target_ty: mlirlite.LLVMType* = None) -> mlirlite.Value*: + def translate_constant(self, builder: mlirlite.IRBuilder*, pool: memhub.MemBuddy*, mod: mlirlite.LLVMModule*, node: ast.AST*, trans: HT.Translator* = None, target_ty: mlirlite.LLVMType* = None) -> mlirlite.Value*: """翻译常量(int/str/bool)""" cn: ast.Constant* = ast.Constant*(node) if cn is None: return None @@ -131,8 +122,7 @@ novirtual class ExprGenConst(ExprGenBase.ExprGenBase): # # 用于 list 字面量 [a, b, c] 的元素类型推断 # ============================================================ - def _infer_elem_type_from_value(self, pool: memhub.MemBuddy*, - value: mlirlite.Value*) -> str: + def _infer_elem_type_from_value(self, pool: memhub.MemBuddy*, value: mlirlite.Value*) -> str: """从 LLVM Value 的类型推断 list 元素类型名 fail-fast:值类型缺失/无法映射时返回 None(调用方携带节点报错终止), @@ -210,12 +200,7 @@ novirtual class ExprGenConst(ExprGenBase.ExprGenBase): self.Gen.VarGen.define_module_var(trans.SymTab, "_mbuddy", gv_ref_fb) return gv_ref_fb # translate_list_literal:把 list 字面量 [a, b, c] 翻译为 list[T](pool) 构造 + append 调用序列。elem_type_name 为元素类型名(如 "str"/"int"),None 表示从元素推断。返回 list 对象指针(Ptr(list[T] struct)),失败返回 None - def translate_list_literal(self, builder: mlirlite.IRBuilder*, - pool: memhub.MemBuddy*, - mod: mlirlite.LLVMModule*, - node: ast.AST*, - elem_type_name: str, - trans: HT.Translator*) -> mlirlite.Value*: + def translate_list_literal(self, builder: mlirlite.IRBuilder*, pool: memhub.MemBuddy*, mod: mlirlite.LLVMModule*, node: ast.AST*, elem_type_name: str, trans: HT.Translator*) -> mlirlite.Value*: """翻译 list 字面量 [a, b, c] → list[T](pool) + append 序列""" if node is None or trans is None: return None diff --git a/App/lib/core/Gen/Expr/ExprGenFstr.vp b/App/lib/core/Gen/Expr/ExprGenFstr.vp index 266a4b0..50725e8 100644 --- a/App/lib/core/Gen/Expr/ExprGenFstr.vp +++ b/App/lib/core/Gen/Expr/ExprGenFstr.vp @@ -33,11 +33,7 @@ novirtual class ExprGenFstr(ExprGenBase.ExprGenBase): # 之前 f-string 未翻译导致 print/赋值拿到 NULL 指针 # ("(null)"输出 + printf("%s", 垃圾) 崩溃 0xC0000005)。 # ============================================================ - def translate_joined_str(self, builder: mlirlite.IRBuilder*, - pool: memhub.MemBuddy*, - mod: mlirlite.LLVMModule*, - node: ast.AST*, - trans: HT.Translator* = None) -> mlirlite.Value*: + def translate_joined_str(self, builder: mlirlite.IRBuilder*, pool: memhub.MemBuddy*, mod: mlirlite.LLVMModule*, node: ast.AST*, trans: HT.Translator* = None) -> mlirlite.Value*: """f-string → snprintf 生成 i8* 栈缓冲(函数内临时值,禁止逃逸)""" if node is None or builder is None or trans is None: return None js: rawptr[ast.JoinedStr] = rawptr[ast.JoinedStr](node) @@ -94,11 +90,7 @@ novirtual class ExprGenFstr(ExprGenBase.ExprGenBase): arg_count += 1 return self._fstr_finalize(builder, pool, mod, fmt_buf, arg_head, arg_tail, arg_count, trans) - def translate_formatted_value(self, builder: mlirlite.IRBuilder*, - pool: memhub.MemBuddy*, - mod: mlirlite.LLVMModule*, - node: ast.AST*, - trans: HT.Translator* = None) -> mlirlite.Value*: + def translate_formatted_value(self, builder: mlirlite.IRBuilder*, pool: memhub.MemBuddy*, mod: mlirlite.LLVMModule*, node: ast.AST*, trans: HT.Translator* = None) -> mlirlite.Value*: """翻译裸 FormattedValue(f"{expr:spec}" 无字面量时解析器返回 FormattedValue 而非 JoinedStr)""" if node is None or builder is None or trans is None: return None fv: rawptr[ast.FormattedValue] = rawptr[ast.FormattedValue](node) @@ -132,14 +124,7 @@ novirtual class ExprGenFstr(ExprGenBase.ExprGenBase): arg_tail = cast_val arg_count = 1 return self._fstr_finalize(builder, pool, mod, fmt_buf, arg_head, arg_tail, arg_count, trans) - def _fstr_finalize(self, builder: mlirlite.IRBuilder*, - pool: memhub.MemBuddy*, - mod: mlirlite.LLVMModule*, - fmt_buf: str, - arg_head: mlirlite.Value*, - arg_tail: mlirlite.Value*, - arg_count: int, - trans: HT.Translator*) -> mlirlite.Value*: + def _fstr_finalize(self, builder: mlirlite.IRBuilder*, pool: memhub.MemBuddy*, mod: mlirlite.LLVMModule*, fmt_buf: str, arg_head: mlirlite.Value*, arg_tail: mlirlite.Value*, arg_count: int, trans: HT.Translator*) -> mlirlite.Value*: """f-string 尾部:全局格式串 + 每站点栈缓冲 + snprintf,返回 i8*(函数内临时值)""" i32_ty: mlirlite.LLVMType* = mlirlite.Int32(pool) i8_ty: mlirlite.LLVMType* = mlirlite.Int8(pool) @@ -193,8 +178,7 @@ novirtual class ExprGenFstr(ExprGenBase.ExprGenBase): if arg_tail is not None: arg_tail.Next = None mlirlite.build_call(builder, "snprintf", buf_ptr, 3 + arg_count, i32_ty, 1) return buf_ptr - def _fstr_append_literal(self, fmt_buf: str, - lit: str) -> None: + def _fstr_append_literal(self, fmt_buf: str, lit: str) -> None: """追加字面量到格式串(% 转义为 %%)""" if fmt_buf is None or lit is None: return cur_len: sizet = string.strlen(fmt_buf) @@ -222,10 +206,7 @@ novirtual class ExprGenFstr(ExprGenBase.ExprGenBase): cur_len: sizet = string.strlen(fmt_buf) 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*, - spec_node: ast.AST*, - val: mlirlite.Value*, - arg_node: ast.AST*) -> str: + def _fstr_parse_format_spec(self, pool: memhub.MemBuddy*, spec_node: ast.AST*, val: mlirlite.Value*, arg_node: ast.AST*) -> str: """Python format_spec → C printf 格式串(pool 分配),无法解析返回 None""" if spec_node is None or pool is None or val is None: return None # 1. 提取 spec 字符串(JoinedStr 仅常量拼接) @@ -372,10 +353,7 @@ novirtual class ExprGenFstr(ExprGenBase.ExprGenBase): string.strcat(out, tmp_ch2) else: return None return out - def _fstr_infer_c_fmt(self, pool: memhub.MemBuddy*, - val: mlirlite.Value*, - arg_node: ast.AST*, - trans: HT.Translator*) -> str: + def _fstr_infer_c_fmt(self, pool: memhub.MemBuddy*, val: mlirlite.Value*, arg_node: ast.AST*, trans: HT.Translator*) -> str: """无 format_spec 时按值类型推断 C printf 格式(对齐 TPC 无 spec 分支,带 % 前缀)""" if val is None or pool is None: return None out: str = pool.alloc(16) @@ -398,12 +376,7 @@ novirtual class ExprGenFstr(ExprGenBase.ExprGenBase): # fail-fast:值类型缺失(非整数/浮点/指针),无法推断 C 格式,立即终止编译 self.Gen.TypeGenErr.fatal_error(arg_node, "f-string 格式无法推断(值类型缺失)", "TypeError") return None - def _fstr_cast_value(self, builder: mlirlite.IRBuilder*, - pool: memhub.MemBuddy*, - val: mlirlite.Value*, - c_fmt: str, - arg_node: ast.AST*, - trans: HT.Translator*) -> mlirlite.Value*: + def _fstr_cast_value(self, builder: mlirlite.IRBuilder*, pool: memhub.MemBuddy*, val: mlirlite.Value*, c_fmt: str, arg_node: ast.AST*, trans: HT.Translator*) -> mlirlite.Value*: """按 C 格式转换值类型(i8/i16→i32、bool→i32、f32→f64)""" if val is None or c_fmt is None: return None # 找格式类型字符(最后一个字母,忽略 l/h 长度修饰) diff --git a/App/lib/core/Gen/Expr/ExprGenMixin.vp b/App/lib/core/Gen/Expr/ExprGenMixin.vp index 4cc7731..e2ee9d2 100644 --- a/App/lib/core/Gen/Expr/ExprGenMixin.vp +++ b/App/lib/core/Gen/Expr/ExprGenMixin.vp @@ -45,15 +45,7 @@ novirtual class ExprGenMixin(ExprGenBase.ExprGenBase): # ============================================================ # 翻译值表达式(RHS 分派)— 模块级版本 # ============================================================ - def translate_value(self, builder: mlirlite.IRBuilder*, - pool: memhub.MemBuddy*, - mod: mlirlite.LLVMModule*, - node: ast.AST*, - funcs_ptr: t.CPtr = None, - func_count: int = 0, - trans: HT.Translator* = None, - target_ty: mlirlite.LLVMType* = None, - use_ctx: str = None) -> mlirlite.Value*: + def translate_value(self, builder: mlirlite.IRBuilder*, pool: memhub.MemBuddy*, mod: mlirlite.LLVMModule*, node: ast.AST*, funcs_ptr: t.CPtr = None, func_count: int = 0, trans: HT.Translator* = None, target_ty: mlirlite.LLVMType* = None, use_ctx: str = None) -> mlirlite.Value*: """翻译值表达式为 LLVM Value(深度守卫包装器,原逻辑见 _translate_value_impl) target_ty: 目标类型上下文(如调用形参类型/赋值目标类型),用于单引号 @@ -68,15 +60,7 @@ novirtual class ExprGenMixin(ExprGenBase.ExprGenBase): if trans is not None: trans.TranslateDepth -= 1 return rv - def _translate_value_impl(self, builder: mlirlite.IRBuilder*, - pool: memhub.MemBuddy*, - mod: mlirlite.LLVMModule*, - node: ast.AST*, - funcs_ptr: t.CPtr = None, - func_count: int = 0, - trans: HT.Translator* = None, - target_ty: mlirlite.LLVMType* = None, - use_ctx: str = None) -> mlirlite.Value*: + def _translate_value_impl(self, builder: mlirlite.IRBuilder*, pool: memhub.MemBuddy*, mod: mlirlite.LLVMModule*, node: ast.AST*, funcs_ptr: t.CPtr = None, func_count: int = 0, trans: HT.Translator* = None, target_ty: mlirlite.LLVMType* = None, use_ctx: str = None) -> mlirlite.Value*: """翻译值表达式为 LLVM Value""" if node is None: return None k: int = node.kind() diff --git a/App/lib/core/Gen/Expr/ExprGenName.vp b/App/lib/core/Gen/Expr/ExprGenName.vp index cb2a0c5..bc68219 100644 --- a/App/lib/core/Gen/Expr/ExprGenName.vp +++ b/App/lib/core/Gen/Expr/ExprGenName.vp @@ -20,8 +20,7 @@ import lib.core.Gen.GenApi as GenApi novirtual class ExprGenName(ExprGenBase.ExprGenBase): """Name/Subscript/下标访问""" - def _cut_from_import_mod(self, pool: memhub.MemBuddy*, - raw: str) -> str: + def _cut_from_import_mod(self, pool: memhub.MemBuddy*, raw: str) -> str: """截断 lookup_from_import 返回的模块名到独立缓冲 lookup_from_import 返回指向 from_imports 内部的指针(非 NUL 结尾, @@ -41,12 +40,7 @@ novirtual class ExprGenName(ExprGenBase.ExprGenBase): buf_c[mbl_c] = '\0' return buf_c - def translate_name_value(self, builder: mlirlite.IRBuilder*, - pool: memhub.MemBuddy*, - node: ast.AST*, - trans: HT.Translator* = None, - target_ty: mlirlite.LLVMType* = None, - use_ctx: str = None) -> mlirlite.Value*: + def translate_name_value(self, builder: mlirlite.IRBuilder*, pool: memhub.MemBuddy*, node: ast.AST*, trans: HT.Translator* = None, target_ty: mlirlite.LLVMType* = None, use_ctx: str = None) -> mlirlite.Value*: """翻译变量引用(Name 节点)→ load target_ty:调用方(translate_value)下传的**使用处类型**(赋值目标 / @@ -371,11 +365,7 @@ novirtual class ExprGenName(ExprGenBase.ExprGenBase): # __data__(0) __count__(8) __capacity__(16) __pool__(24) __elem_size__(32) __iter_index__(40) # 返回元素地址 (i8*),调用方根据元素类型 load 正确的值 # ============================================================ - def list_getitem_inline(self, builder: mlirlite.IRBuilder*, - pool: memhub.MemBuddy*, - lm_obj: mlirlite.Value*, - idx_val: mlirlite.Value*, - node: ast.AST* = None) -> mlirlite.Value*: + def list_getitem_inline(self, builder: mlirlite.IRBuilder*, pool: memhub.MemBuddy*, lm_obj: mlirlite.Value*, idx_val: mlirlite.Value*, node: ast.AST* = None) -> mlirlite.Value*: """内联生成 list __getitem__ 逻辑,返回元素地址 (i8*)""" if builder is None or pool is None or lm_obj is None or idx_val is None: return None i64_ty: mlirlite.LLVMType* = mlirlite.Int64(pool) @@ -406,8 +396,7 @@ novirtual 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*, - struct_name: str) -> mlirlite.LLVMType*: + def _list_elem_type_from_name(self, pool: memhub.MemBuddy*, struct_name: str) -> mlirlite.LLVMType*: """从 list 类型名提取元素 LLVM 类型""" if pool is None or struct_name is None: return None # 用 strstr 检查完整模式 @@ -451,8 +440,7 @@ novirtual class ExprGenName(ExprGenBase.ExprGenBase): # mlirlite.Ptr(entry.Ty)(list 元素槽 8 字节存对象指针)。全部未命中 # 返回 None(调用方回退 Ptr(i8) 旧行为,不影响已支持的内置元素)。 # ============================================================ - def _list_elem_obj_ty_from_struct_name(self, pool: memhub.MemBuddy*, - struct_name: str) -> mlirlite.LLVMType*: + def _list_elem_obj_ty_from_struct_name(self, pool: memhub.MemBuddy*, struct_name: str) -> mlirlite.LLVMType*: """从 list 特化类型名还原元素对象指针 LLVM 类型,失败返回 None""" if pool is None or struct_name is None: return None lb_e: str = string.strchr(struct_name, '[') @@ -507,12 +495,7 @@ novirtual class ExprGenName(ExprGenBase.ExprGenBase): # # 直接存储 rhs_val 到元素地址 (coerce 为 i8* 后 store) # ============================================================ - def list_setitem_inline(self, builder: mlirlite.IRBuilder*, - pool: memhub.MemBuddy*, - lm_obj: mlirlite.Value*, - idx_val: mlirlite.Value*, - rhs_val: mlirlite.Value*, - node: ast.AST* = None) -> int: + def list_setitem_inline(self, builder: mlirlite.IRBuilder*, pool: memhub.MemBuddy*, lm_obj: mlirlite.Value*, idx_val: mlirlite.Value*, rhs_val: mlirlite.Value*, node: ast.AST* = None) -> int: """内联生成 list __setitem__ 逻辑,返回 0""" if builder is None or pool is None or lm_obj is None or idx_val is None or rhs_val is None: return 0 i64_ty: mlirlite.LLVMType* = mlirlite.Int64(pool) @@ -554,8 +537,7 @@ novirtual class ExprGenName(ExprGenBase.ExprGenBase): # # 返回 list 对象指针 (Ptr(list[T])) 或 None # ============================================================ - def is_list_subscript(self, node: ast.AST*, - trans: HT.Translator*) -> mlirlite.Value*: + def is_list_subscript(self, node: ast.AST*, trans: HT.Translator*) -> mlirlite.Value*: """检查 Subscript 节点是否是 list[T] 类型,返回 list 对象指针或 None""" if node is None or trans is None: return None sub: ast.Subscript* = ast.Subscript*(node) @@ -589,11 +571,7 @@ novirtual class ExprGenName(ExprGenBase.ExprGenBase): builder: mlirlite.IRBuilder* = trans._cur_builder return mlirlite.build_load(builder, pointee, alloca) # _nonlocal_subscript_ptr:nonlocal 数组/指针的下标元素指针——嵌套(提升)函数体内访问 nonlocal 变量时,其实际存储是运行时共享堆(env[ni] 存堆地址),不能 lookup_var 找外层函数 alloca(其 SSA 编号属外层函数,当前函数引用会错乱崩溃)。正确路径:从 env 读堆地址(_load_raw_var_ptr)→ bitcast → GEP - def _nonlocal_subscript_ptr(self, builder: mlirlite.IRBuilder*, - pool: memhub.MemBuddy*, - trans: HT.Translator*, - nm_id: str, - idx_val: mlirlite.Value*) -> mlirlite.Value*: + def _nonlocal_subscript_ptr(self, builder: mlirlite.IRBuilder*, pool: memhub.MemBuddy*, trans: HT.Translator*, nm_id: str, idx_val: mlirlite.Value*) -> mlirlite.Value*: """nonlocal 数组/指针下标:从 env 读堆地址 → bitcast → GEP,返回元素指针""" if trans is None or nm_id is None or idx_val is None: return None nl_ty: mlirlite.LLVMType* = GenApi.get_nonlocal_type(trans, nm_id) @@ -621,11 +599,7 @@ novirtual class ExprGenName(ExprGenBase.ExprGenBase): # 数组遍历: arr 是数组变量,用 alloca 指针做双索引 GEP [0, i] + load # list[T]: 泛型类不注册 struct,subscript 走 __getitem__ 内联路径 # ============================================================ - def translate_subscript(self, builder: mlirlite.IRBuilder*, - pool: memhub.MemBuddy*, - mod: mlirlite.LLVMModule*, - node: ast.AST*, - trans: HT.Translator* = None) -> mlirlite.Value*: + def translate_subscript(self, builder: mlirlite.IRBuilder*, pool: memhub.MemBuddy*, mod: mlirlite.LLVMModule*, node: ast.AST*, trans: HT.Translator* = None) -> mlirlite.Value*: """翻译下标表达式,返回加载的元素值""" if node is None or builder is None: return None sub: ast.Subscript* = ast.Subscript*(node) @@ -932,9 +906,7 @@ novirtual class ExprGenName(ExprGenBase.ExprGenBase): # 分派与 get_subscript_ptr 同源:Name 取变量/全局存储的元素类型, # Attribute 取字段类型。 # ============================================================ - def subscript_base_store_kind(self, pool: memhub.MemBuddy*, - trans: HT.Translator*, - node: ast.AST*) -> int: + def subscript_base_store_kind(self, pool: memhub.MemBuddy*, trans: HT.Translator*, node: ast.AST*) -> int: """下标基座存储形态:1=数组 / 0=指针 / -1=无法判定""" if node is None or trans is None: return -1 sub_bk: ast.Subscript* = ast.Subscript*(node) @@ -966,11 +938,7 @@ novirtual class ExprGenName(ExprGenBase.ExprGenBase): if inner_bk.kind() == mlirlite.LLVMType.Struct: return 0 return -1 - def get_subscript_ptr(self, builder: mlirlite.IRBuilder*, - pool: memhub.MemBuddy*, - mod: mlirlite.LLVMModule*, - node: ast.AST*, - trans: HT.Translator* = None) -> mlirlite.Value*: + def get_subscript_ptr(self, builder: mlirlite.IRBuilder*, pool: memhub.MemBuddy*, mod: mlirlite.LLVMModule*, node: ast.AST*, trans: HT.Translator* = None) -> mlirlite.Value*: """获取下标表达式的元素指针(用于赋值 lhs)""" if node is None or builder is None: return None sub: ast.Subscript* = ast.Subscript*(node) diff --git a/App/lib/core/Gen/Expr/ExprGenOps.vp b/App/lib/core/Gen/Expr/ExprGenOps.vp index b2fe439..c99c10a 100644 --- a/App/lib/core/Gen/Expr/ExprGenOps.vp +++ b/App/lib/core/Gen/Expr/ExprGenOps.vp @@ -26,11 +26,7 @@ novirtual class ExprGenOps(ExprGenBase.ExprGenBase): # else_blk: 翻译 orelse → br merge # merge_blk: phi [body_val, then_blk], [orelse_val, else_blk] # ============================================================ - def translate_ifexp(self, builder: mlirlite.IRBuilder*, - pool: memhub.MemBuddy*, - mod: mlirlite.LLVMModule*, - node: ast.AST*, - trans: HT.Translator* = None) -> mlirlite.Value*: + def translate_ifexp(self, builder: mlirlite.IRBuilder*, pool: memhub.MemBuddy*, mod: mlirlite.LLVMModule*, node: ast.AST*, trans: HT.Translator* = None) -> mlirlite.Value*: """翻译三元表达式 (body if test else orelse),返回 phi 结果 Value""" if node is None or builder is None or trans is None: return None ie: rawptr[ast.IfExp] = rawptr[ast.IfExp](node) @@ -144,11 +140,7 @@ novirtual class ExprGenOps(ExprGenBase.ExprGenBase): # ============================================================ # 翻译比较表达式 Compare(left, ops, comparators) # ============================================================ - def should_zext_widen(self, pool: memhub.MemBuddy*, - narrow_val: mlirlite.Value*, - wide_val: mlirlite.Value*, - narrow_node: ast.AST* = None, - trans: HT.Translator* = None) -> int: + def should_zext_widen(self, pool: memhub.MemBuddy*, narrow_val: mlirlite.Value*, wide_val: mlirlite.Value*, narrow_node: ast.AST* = None, trans: HT.Translator* = None) -> int: """判断整数拓宽方向:1=zext(无符号语义),0=sext **拓宽方向的单一真源**:ExprGenBase._zext_or_sext_val(coerce 路径)委托到此。 @@ -206,9 +198,7 @@ novirtual class ExprGenOps(ExprGenBase.ExprGenBase): if self.Gen.TypeGenCDef.is_cdefine_found() != 0: if cdv_zw > 0x7FFFFFFF: return 1 return 0 - def _node_type_unsigned(self, pool: memhub.MemBuddy*, - node: ast.AST*, - trans: HT.Translator* = None) -> int: + def _node_type_unsigned(self, pool: memhub.MemBuddy*, node: ast.AST*, trans: HT.Translator* = None) -> int: """轻量判断 AST 节点是否解析为无符号整数类型(1=是,0=否/未知) 覆盖常见形态(对齐 TPC _check_node_unsigned 的 Call/Subscript 分支): @@ -298,9 +288,7 @@ novirtual class ExprGenOps(ExprGenBase.ExprGenBase): fi_u += 1 return 0 return 0 - def _node_type_signed(self, pool: memhub.MemBuddy*, - node: ast.AST*, - trans: HT.Translator* = None) -> int: + def _node_type_signed(self, pool: memhub.MemBuddy*, node: ast.AST*, trans: HT.Translator* = None) -> int: """源节点是否**明确有符号**整数(独立真源的 SIGNED 分支;未知返回 0) 只服务 should_zext_widen 的 i8 分支:i8 默认按「无符号字节」zext, @@ -398,11 +386,7 @@ novirtual class ExprGenOps(ExprGenBase.ExprGenBase): if annot is not None: if self._spec_sign_from_annot(annot) == TSpec.TS_SIGN_UNSIGNED: return 1 return 0 - def translate_compare(self, builder: mlirlite.IRBuilder*, - pool: memhub.MemBuddy*, - mod: mlirlite.LLVMModule*, - node: ast.AST*, - trans: HT.Translator* = None) -> mlirlite.Value*: + def translate_compare(self, builder: mlirlite.IRBuilder*, pool: memhub.MemBuddy*, mod: mlirlite.LLVMModule*, node: ast.AST*, trans: HT.Translator* = None) -> mlirlite.Value*: """翻译比较表达式,返回 i1 结果""" cmp: rawptr[ast.Compare] = rawptr[ast.Compare](node) if cmp is None: return None @@ -666,11 +650,7 @@ novirtual class ExprGenOps(ExprGenBase.ExprGenBase): # ============================================================ # 翻译一元运算表达式 UnaryOp(op, operand) # ============================================================ - def translate_unaryop(self, builder: mlirlite.IRBuilder*, - pool: memhub.MemBuddy*, - mod: mlirlite.LLVMModule*, - node: ast.AST*, - trans: HT.Translator* = None) -> mlirlite.Value*: + def translate_unaryop(self, builder: mlirlite.IRBuilder*, pool: memhub.MemBuddy*, mod: mlirlite.LLVMModule*, node: ast.AST*, trans: HT.Translator* = None) -> mlirlite.Value*: """翻译一元运算(-x, +x, not x, ~x)""" uo: ast.UnaryOp* = ast.UnaryOp*(node) if uo is None: return None @@ -799,9 +779,7 @@ novirtual class ExprGenOps(ExprGenBase.ExprGenBase): return None return operand - def _addrof_of_call(self, builder: mlirlite.IRBuilder*, - pool: memhub.MemBuddy*, - call_val: mlirlite.Value*) -> mlirlite.Value*: + def _addrof_of_call(self, builder: mlirlite.IRBuilder*, pool: memhub.MemBuddy*, call_val: mlirlite.Value*) -> mlirlite.Value*: """`&()` 的取址结果(call_val 是调用结果,已由 translate_unaryop 求值一次) 两种形态: @@ -836,13 +814,7 @@ novirtual class ExprGenOps(ExprGenBase.ExprGenBase): # 最后一个值直接求值并跳 merge # merge 块用 phi 合并所有入边的 i1 # ============================================================ - def translate_boolop(self, builder: mlirlite.IRBuilder*, - pool: memhub.MemBuddy*, - mod: mlirlite.LLVMModule*, - node: ast.AST*, - funcs_ptr: t.CPtr = None, - func_count: int = 0, - trans: HT.Translator* = None) -> mlirlite.Value*: + def translate_boolop(self, builder: mlirlite.IRBuilder*, pool: memhub.MemBuddy*, mod: mlirlite.LLVMModule*, node: ast.AST*, funcs_ptr: t.CPtr = None, func_count: int = 0, trans: HT.Translator* = None) -> mlirlite.Value*: """翻译布尔运算(and/or)的短路求值,返回 i1""" bo: rawptr[ast.BoolOp] = rawptr[ast.BoolOp](node) if bo is None: return None @@ -853,8 +825,7 @@ novirtual class ExprGenOps(ExprGenBase.ExprGenBase): count: sizet = len(values) if count == 0: return None if count == 1: - return self.Gen.ExprGen.translate_value(builder, pool, mod, values.get(0), - funcs_ptr, func_count, trans) + return self.Gen.ExprGen.translate_value(builder, pool, mod, values.get(0), funcs_ptr, func_count, trans) func: mlirlite.Function* = builder.Func if func is None: return None @@ -932,13 +903,7 @@ novirtual class ExprGenOps(ExprGenBase.ExprGenBase): # 结果 fptosi 回写为左操作数类型(Python `int ** int = int`)。 # 自定义类型的 `**` 由重载路径(__pow__)先行处理,不进入此处。 # ============================================================ - def emit_pow(self, pool: memhub.MemBuddy*, - builder: mlirlite.IRBuilder*, - mod: mlirlite.LLVMModule*, - lhs: mlirlite.Value*, - rhs: mlirlite.Value*, - node: ast.AST* = None, - trans: HT.Translator* = None) -> mlirlite.Value*: + def emit_pow(self, pool: memhub.MemBuddy*, builder: mlirlite.IRBuilder*, mod: mlirlite.LLVMModule*, lhs: mlirlite.Value*, rhs: mlirlite.Value*, node: ast.AST* = None, trans: HT.Translator* = None) -> mlirlite.Value*: """翻译 `**` 幂运算(基础类型走 llvm.pow)""" if lhs is None or rhs is None: return None lhs_fbits: int = self.get_llvm_float_bits(lhs.Ty) @@ -961,11 +926,7 @@ novirtual class ExprGenOps(ExprGenBase.ExprGenBase): if rhs_bits != 0 and rhs.IsConst == 1 and rhs.IntVal >= 0: return self.coerce_to_type(builder, res, lhs.Ty, node, trans) return res - def _call_llvm_pow(self, pool: memhub.MemBuddy*, - builder: mlirlite.IRBuilder*, - mod: mlirlite.LLVMModule*, - lf: mlirlite.Value*, - rf: mlirlite.Value*) -> mlirlite.Value*: + def _call_llvm_pow(self, pool: memhub.MemBuddy*, builder: mlirlite.IRBuilder*, mod: mlirlite.LLVMModule*, lf: mlirlite.Value*, rf: mlirlite.Value*) -> mlirlite.Value*: """调用 llvm.pow.f64 内联函数;f32 结果再截断回 float""" if lf is None or rf is None: return None f64_ty: mlirlite.LLVMType* = mlirlite.Double(pool) @@ -1058,14 +1019,7 @@ novirtual class ExprGenOps(ExprGenBase.ExprGenBase): # dunder 方法。找到则生成方法调用 lhs.__dunder__(rhs),返回 # 调用结果;未找到返回 None,调用方回退到原生运算。 # ============================================================ - def try_operator_overload(self, pool: memhub.MemBuddy*, - builder: mlirlite.IRBuilder*, - mod: mlirlite.LLVMModule*, - lhs: mlirlite.Value*, - rhs: mlirlite.Value*, - op: int, - trans: HT.Translator*, - is_compare: int) -> mlirlite.Value*: + def try_operator_overload(self, pool: memhub.MemBuddy*, builder: mlirlite.IRBuilder*, mod: mlirlite.LLVMModule*, lhs: mlirlite.Value*, rhs: mlirlite.Value*, op: int, trans: HT.Translator*, is_compare: int) -> mlirlite.Value*: """尝试运算符重载:lhs 是结构体指针时调用 dunder 方法,否则返回 None""" if lhs is None or rhs is None: return None # 映射运算符到 dunder 方法名 @@ -1150,24 +1104,14 @@ novirtual class ExprGenOps(ExprGenBase.ExprGenBase): # dunder 方法(__neg__/__pos__/__invert__)。找到则生成方法调用 # operand.__dunder__(),返回调用结果;未找到返回 None,调用方回退到原生运算。 # ============================================================ - def try_unary_operator_overload(self, pool: memhub.MemBuddy*, - builder: mlirlite.IRBuilder*, - mod: mlirlite.LLVMModule*, - operand: mlirlite.Value*, - op: int, - trans: HT.Translator*) -> mlirlite.Value*: + def try_unary_operator_overload(self, pool: memhub.MemBuddy*, builder: mlirlite.IRBuilder*, mod: mlirlite.LLVMModule*, operand: mlirlite.Value*, op: int, trans: HT.Translator*) -> mlirlite.Value*: """尝试一元运算符重载:operand 是结构体指针时调用 dunder 方法,否则返回 None""" if operand is None: return None dunder: str = self._unaryop_to_dunder(op) if dunder is None: return None return self._try_named_dunder(pool, builder, mod, operand, dunder, trans) - def _resolve_dunder_by_class(self, pool: memhub.MemBuddy*, - mod: mlirlite.LLVMModule*, - class_name: str, - dunder: str, - trans: HT.Translator*, - struct_ty: mlirlite.LLVMType* = None) -> str: + def _resolve_dunder_by_class(self, pool: memhub.MemBuddy*, mod: mlirlite.LLVMModule*, class_name: str, dunder: str, trans: HT.Translator*, struct_ty: mlirlite.LLVMType* = None) -> str: """在 class_name(含 MRO 祖先)中解析 dunder 方法的定义类名。 返回「实际定义该方法的类名」(search_class);该类(含祖先)未定义则返回 @@ -1228,14 +1172,7 @@ novirtual class ExprGenOps(ExprGenBase.ExprGenBase): if vpi_dup is None: return None return search_class - def _try_named_dunder(self, pool: memhub.MemBuddy*, - builder: mlirlite.IRBuilder*, - mod: mlirlite.LLVMModule*, - operand: mlirlite.Value*, - dunder: str, - trans: HT.Translator*, - extra_args: sizet* = None, - extra_count: int = 0) -> mlirlite.Value*: + def _try_named_dunder(self, pool: memhub.MemBuddy*, builder: mlirlite.IRBuilder*, mod: mlirlite.LLVMModule*, operand: mlirlite.Value*, dunder: str, trans: HT.Translator*, extra_args: sizet* = None, extra_count: int = 0) -> mlirlite.Value*: """按名字在 operand 的类(含 MRO 祖先)中查找并调用 dunder 方法。 一元运算符(__neg__/__pos__/__invert__)、条件真值 __bool__ 与可调用 @@ -1268,11 +1205,7 @@ novirtual class ExprGenOps(ExprGenBase.ExprGenBase): # 4. 其他 → != 0。 # 语义唯一来源,避免各处各自演化出「struct 恒真」这类不一致判据。 # ============================================================ - def coerce_cond_to_bool(self, pool: memhub.MemBuddy*, - builder: mlirlite.IRBuilder*, - mod: mlirlite.LLVMModule*, - val: mlirlite.Value*, - trans: HT.Translator*) -> mlirlite.Value*: + def coerce_cond_to_bool(self, pool: memhub.MemBuddy*, builder: mlirlite.IRBuilder*, mod: mlirlite.LLVMModule*, val: mlirlite.Value*, trans: HT.Translator*) -> mlirlite.Value*: """把条件值归一到 i1,优先调度 __bool__(类实例),否则与 0/null 比较""" if val is None: return None bits: int = self.get_llvm_type_bits(val.Ty) @@ -1310,12 +1243,7 @@ novirtual class ExprGenOps(ExprGenBase.ExprGenBase): # 「(增量赋值)」,避免只报裸 "+",便于定位。 # 命中即 fatal_error 终止编译;未命中返回 0。 # ============================================================ - def fail_if_double_ptr_binop(self, pool: memhub.MemBuddy*, - op: int, - lhs: mlirlite.Value*, - rhs: mlirlite.Value*, - node: ast.AST* = None, - is_aug: int = 0) -> int: + def fail_if_double_ptr_binop(self, pool: memhub.MemBuddy*, op: int, lhs: mlirlite.Value*, rhs: mlirlite.Value*, node: ast.AST* = None, is_aug: int = 0) -> int: """双指针算术 fail-fast;命中即终止编译,未命中返回 0""" if lhs is None or rhs is None: return 0 if self.is_ptr_type(lhs.Ty) == 0 or self.is_ptr_type(rhs.Ty) == 0: return 0 @@ -1354,25 +1282,12 @@ novirtual class ExprGenOps(ExprGenBase.ExprGenBase): if string.strcmp(rty_buf, "i8*") == 0: rty_lbl = "str(i8*)" col_s: int = 0 if node is not None: col_s = node.col_offset + 1 - self.Gen.TypeGenErr.fatal_error( - node, - f"[TPV] 双指针运算类型非法: op = '{op_lbl}'{aug_note}," - f"左操作数类型 = {lty_lbl},右操作数类型 = {rty_lbl}。" - f"本语言的 str 是 i8*,没有 `+` 拼接语义(`str + str` 与指针 ± 指针" - f"都会退化成裸指针 add/sub ⇒ 非法 IR: opt 报 " - f"invalid operand type for instruction)。" - f"禁止静默降级,已终止编译。" - f"修法: 用 f-string 插值、string.strcat 或 viperlib.snprintf 构建字符串。", - "TypeError", col_s, col_s) + self.Gen.TypeGenErr.fatal_error(node, f"[TPV] 双指针运算类型非法: op = '{op_lbl}'{aug_note}," f"左操作数类型 = {lty_lbl},右操作数类型 = {rty_lbl}。" f"本语言的 str 是 i8*,没有 `+` 拼接语义(`str + str` 与指针 ± 指针" f"都会退化成裸指针 add/sub ⇒ 非法 IR: opt 报 " f"invalid operand type for instruction)。" f"禁止静默降级,已终止编译。" f"修法: 用 f-string 插值、string.strcat 或 viperlib.snprintf 构建字符串。", "TypeError", col_s, col_s) return 1 # ============================================================ # 翻译二元运算(自动类型提升) # ============================================================ - def translate_binop(self, pool: memhub.MemBuddy*, - builder: mlirlite.IRBuilder*, - mod: mlirlite.LLVMModule*, - node: ast.AST*, - trans: HT.Translator* = None) -> mlirlite.Value*: + def translate_binop(self, pool: memhub.MemBuddy*, builder: mlirlite.IRBuilder*, mod: mlirlite.LLVMModule*, node: ast.AST*, trans: HT.Translator* = None) -> mlirlite.Value*: """翻译二元运算(自动类型提升)""" binop: ast.BinOp* = ast.BinOp*(node) if binop is None: return None diff --git a/App/lib/core/Gen/Func/FuncGenBase.vp b/App/lib/core/Gen/Func/FuncGenBase.vp index 9a0f5e3..86f52e7 100644 --- a/App/lib/core/Gen/Func/FuncGenBase.vp +++ b/App/lib/core/Gen/Func/FuncGenBase.vp @@ -26,9 +26,7 @@ novirtual class FuncGenBase(CallGenBase.CallGenBase): # # 返回 LLVM IR 属性字符串(如 "alwaysinline nounwind"),无属性返回 None # ============================================================ - def extract_func_attrs(self, pool: memhub.MemBuddy*, - decorator_list: list[ast.AST*]*, - imported_modules: str) -> str: + def extract_func_attrs(self, pool: memhub.MemBuddy*, decorator_list: list[ast.AST*]*, imported_modules: str) -> str: """从 decorator_list 提取 c.Attribute 属性,返回 LLVM IR 属性字符串""" if decorator_list is None: return None dn: sizet = len(decorator_list) @@ -92,9 +90,7 @@ novirtual class FuncGenBase(CallGenBase.CallGenBase): if found_any == 0: return None return attrs_buf - def extract_func_section(self, pool: memhub.MemBuddy*, - decorator_list: list[ast.AST*]*, - imported_modules: str) -> str: + def extract_func_section(self, pool: memhub.MemBuddy*, decorator_list: list[ast.AST*]*, imported_modules: str) -> str: """提取 @c.Attribute(t.attr.section("xxx")) 为属性组文本 '"section"="xxx"'。 LLVM 字符串属性(带值)必须用属性组 #N(函数行输出 #N + 函数尾 @@ -187,8 +183,7 @@ novirtual class FuncGenBase(CallGenBase.CallGenBase): if attrs_buf[0] != '\0': self._append_str(attrs_buf, " ", 256) self._append_str(attrs_buf, llvm_name, 256) return 1 - def _append_str(self, buf: str, s: str, - max_len: sizet = 256) -> None: + def _append_str(self, buf: str, s: str, max_len: sizet = 256) -> None: """将字符串追加到 buf 末尾(有界,防 strcpy 越界写穿定长缓冲)""" if buf is None or s is None: return # 防御:TPV 方法默认参数注册存在缺陷(缺参调用 max_len 落到 0), @@ -250,8 +245,7 @@ novirtual class FuncGenBase(CallGenBase.CallGenBase): # - 已带 SHA1 前缀的不再加 # - ModuleSha1 为 None 时不加前缀 # ============================================================ - def _mangle_func_name(self, trans: HT.Translator*, name: str, - has_export: int) -> str: + def _mangle_func_name(self, trans: HT.Translator*, name: str, has_export: int) -> str: """为函数名添加 SHA1 前缀(检查 main/export)""" if trans is None or name is None: return name if has_export != 0: return name @@ -296,8 +290,7 @@ novirtual class FuncGenBase(CallGenBase.CallGenBase): # Converter 为模块级函数,同报文另写一份(见 StubGen/Converter.vp)。 # 无 CReturn 返回 0。 # ============================================================ - def RejectCReturnDecorator(self, node: ast.AST*, - decorators: list[ast.AST*]*) -> int: + def RejectCReturnDecorator(self, node: ast.AST*, decorators: list[ast.AST*]*) -> int: """装饰器列表里出现 @c.CReturn 即 fatal_error(返回 0 = 无该装饰器)""" if decorators is None: return 0 rcr_dn: sizet = len(decorators) @@ -318,11 +311,7 @@ novirtual class FuncGenBase(CallGenBase.CallGenBase): # ============================================================ # 创建 LLVM 函数(简单版本,仅声明) # ============================================================ - def create_function(self, pool: memhub.MemBuddy*, - mod: mlirlite.LLVMModule*, - name: str, - args_node: ast.AST*, - ret_ty: mlirlite.LLVMType*) -> mlirlite.Function*: + def create_function(self, pool: memhub.MemBuddy*, mod: mlirlite.LLVMModule*, name: str, args_node: ast.AST*, ret_ty: mlirlite.LLVMType*) -> mlirlite.Function*: """创建 LLVM 函数并添加参数""" if name is None or mod is None: return None diff --git a/App/lib/core/Gen/Func/FuncGenDef.vp b/App/lib/core/Gen/Func/FuncGenDef.vp index a78f117..53086db 100644 --- a/App/lib/core/Gen/Func/FuncGenDef.vp +++ b/App/lib/core/Gen/Func/FuncGenDef.vp @@ -28,8 +28,7 @@ novirtual class FuncGenDef(CallGenBase.CallGenBase): # 3) 创建 declare(IsDeclared=1) 4) 添加参数 5) 注册到函数表。 # 后续 translate_function_def 经 find_func_in_module 复用该 declare(清除 IsDeclared, # 跳过参数创建,直接添加函数体)。 - def forward_declare_functions(self, trans: HT.Translator*, - tree: ast.AST*) -> int: + def forward_declare_functions(self, trans: HT.Translator*, tree: ast.AST*) -> int: """预扫描所有顶层 FunctionDef,创建前向声明""" if trans is None or tree is None: return 0 pool: memhub.MemBuddy* = trans.Pool @@ -190,9 +189,7 @@ novirtual class FuncGenDef(CallGenBase.CallGenBase): # 注册到函数表(用裸名 fd.name,不是 mangled_name) max_funcs: int = 1024 cur_count: int = trans._func_count - if self.Gen.CallGenLeafKit.add_func_to_table(funcs_ptr, cur_count, fd.name, func, max_funcs, - fd_defaults, fd_default_count, fd_param_count, - trans.Pool) == 0: + if self.Gen.CallGenLeafKit.add_func_to_table(funcs_ptr, cur_count, fd.name, func, max_funcs, fd_defaults, fd_default_count, fd_param_count, trans.Pool) == 0: trans._func_count = cur_count + 1 # 注册 CExport 函数到全局表 @@ -273,8 +270,7 @@ novirtual class FuncGenDef(CallGenBase.CallGenBase): # trans 单参模式:所有共享状态从 trans 获取 # 函数局部作用域通过 enter_scope/exit_scope 管理 # ============================================================ - def translate_function_def(self, trans: HT.Translator*, - node: ast.AST*) -> int: + def translate_function_def(self, trans: HT.Translator*, node: ast.AST*) -> int: """翻译函数定义,返回新增的变量数(通常为 0,函数定义不增加当前作用域变量)""" fd: ast.FunctionDef* = ast.FunctionDef*(node) if fd is None or fd.name is None: return 0 @@ -534,9 +530,7 @@ novirtual class FuncGenDef(CallGenBase.CallGenBase): # 注册到函数表 max_funcs: int = 1024 - if self.Gen.CallGenLeafKit.add_func_to_table(funcs_ptr, func_count, fd.name, func, max_funcs, - tfd_defaults, tfd_default_count, tfd_param_count, - trans.Pool) == 0: + if self.Gen.CallGenLeafKit.add_func_to_table(funcs_ptr, func_count, fd.name, func, max_funcs, tfd_defaults, tfd_default_count, tfd_param_count, trans.Pool) == 0: trans._func_count = func_count + 1 # 添加参数(支持类型注解) @@ -613,8 +607,7 @@ novirtual class FuncGenDef(CallGenBase.CallGenBase): # --traceback: attach a DISubprogram to this define and set every # instruction in the body to the entry DILocation (the statement hook # refines it per statement). No-op when DI is disabled. - dbg_pushed: int = DebugInfoGen.PushFunction(pool, func_builder, func, - fd.lineno, fd.col_offset + 1) + dbg_pushed: int = DebugInfoGen.PushFunction(pool, func_builder, func, fd.lineno, fd.col_offset + 1) # @t.TLS 一次性初始化守卫(对齐 TPC HandlesFunctions.py):首次调用执行函数体并置 # 全局标志 __tls_init_done_{name}=1,后续调用直接返回默认值。不实现则每次调用都 @@ -762,8 +755,7 @@ novirtual class FuncGenDef(CallGenBase.CallGenBase): self.Gen.VarGen.define_var(trans.SymTab, vararg_name_str, va_list_alloca) # 调用 @llvm.va_start(i8* %va_list_addr) void_ty_va: mlirlite.LLVMType* = mlirlite.Void(pool) - mlirlite.build_call(func_builder, "llvm.va_start", - va_list_addr, 1, void_ty_va, 0) + mlirlite.build_call(func_builder, "llvm.va_start", va_list_addr, 1, void_ty_va, 0) # 保存到 trans 供 arg(type) 糖函数与 vararg 名翻译使用 trans._va_list_ptr = va_list_addr trans._vararg_name = vararg_name_str @@ -987,8 +979,7 @@ novirtual class FuncGenDef(CallGenBase.CallGenBase): # 据此 fail-fast。独立成方法:translate_function_def 含多分支,内联新增分支 # 会干扰其类型推断(同 ExprGenAttr / CallGenMixin / TranslatorGenMixin 处理)。 # ============================================================ - def _RegisterStaticFunc(self, trans: HT.Translator*, - fd: ast.FunctionDef*) -> int: + def _RegisterStaticFunc(self, trans: HT.Translator*, fd: ast.FunctionDef*) -> int: """static 函数登记:returns 注解或 @t.CStatic 装饰器命中即登记;1=已登记 / 0=未命中""" if trans is None or fd is None or fd.name is None: return 0 if trans.ModuleSha1 is None: return 0 @@ -1015,14 +1006,7 @@ novirtual class FuncGenDef(CallGenBase.CallGenBase): # i8* args_ptr, i8* ret_ptr, i8* decor_args_ptr) # 前置返回:0=跳过原函数,1=调用一次,N=循环 N 次 # ============================================================ - def _gen_decor_wrapper(self, trans: HT.Translator*, - pool: memhub.MemBuddy*, - mod: mlirlite.LLVMModule*, - func: mlirlite.Function*, - func_name: str, - wrapper_name: str, - handler_name: str, - decor_arg0: int64) -> mlirlite.Function*: + def _gen_decor_wrapper(self, trans: HT.Translator*, pool: memhub.MemBuddy*, mod: mlirlite.LLVMModule*, func: mlirlite.Function*, func_name: str, wrapper_name: str, handler_name: str, decor_arg0: int64) -> mlirlite.Function*: """生成装饰器 wrapper 函数,返回 wrapper 或 None""" if trans is None or pool is None or mod is None or func is None: return None if func_name is None or wrapper_name is None or handler_name is None: return None diff --git a/App/lib/core/Gen/Func/FuncGenMixin.vp b/App/lib/core/Gen/Func/FuncGenMixin.vp index 8b078a9..f0b7fdc 100644 --- a/App/lib/core/Gen/Func/FuncGenMixin.vp +++ b/App/lib/core/Gen/Func/FuncGenMixin.vp @@ -107,8 +107,7 @@ novirtual class FuncGenMixin(CallGenBase.CallGenBase): mlirlite.position_at_end(func_builder, entry_blk) # --traceback: promoted nested closure gets its own DISubprogram. - dbg_pushed_n: int = DebugInfoGen.PushFunction(pool, func_builder, func, - node.lineno, node.col_offset + 1) + dbg_pushed_n: int = DebugInfoGen.PushFunction(pool, func_builder, func, node.lineno, node.col_offset + 1) # 4. 进入嵌套函数作用域(嵌套符号表) self.Gen.VarGen.enter_scope(trans.SymTab, SCOPE_FUNCTION) @@ -413,8 +412,7 @@ novirtual class FuncGenMixin(CallGenBase.CallGenBase): # 属于父函数 → llc "use of undefined value")。故对嵌套 def 做等价预扫描:把"读取的外层 # 函数局部变量"注册为 nonlocal(复用 env 共享堆机制),使 read 走 _load_raw_var_ptr 从堆读。 # 注意:注册顺序必须与 step 13 的 env 构建一致(本扫描在 body 翻译前执行,顺序稳定)。 - def _closure_scan_captures(self, trans: HT.Translator*, - node: ast.AST*) -> int: + def _closure_scan_captures(self, trans: HT.Translator*, node: ast.AST*) -> int: """递归扫描节点中的隐式捕获并注册为 nonlocal""" if node is None or trans is None: return 1 k: int = node.kind() @@ -706,8 +704,7 @@ novirtual class FuncGenMixin(CallGenBase.CallGenBase): # 注:`case _`(Void/Struct/Func 等)仍返回 8——不是静默兜底,而是**算不出** # (结构体尺寸需查布局表,本函数只做 LLVMType 递归);改 fatal 会拒绝 # "nonlocal 结构体"这一合法用法,需先补布局查询能力。 - def _type_byte_size(self, pool: memhub.MemBuddy*, - ty: mlirlite.LLVMType*) -> int: + def _type_byte_size(self, pool: memhub.MemBuddy*, ty: mlirlite.LLVMType*) -> int: """计算 LLVM 类型占用的字节大小(递归)""" if ty is None: # [S4 fail-fast] 类型缺失 → 不再保守 8 字节(分配不足会越界写邻块) @@ -736,9 +733,7 @@ novirtual class FuncGenMixin(CallGenBase.CallGenBase): # 变量名: nlheap_{sha1}.{name}(全局变量,跨函数可见;SSA 编号是函数 # 局部的,跨函数传递堆地址只能经全局变量/模块级映射)。 # ============================================================ - def _nl_heap_global_name(self, pool: memhub.MemBuddy*, - trans: HT.Translator*, - name: str) -> str: + def _nl_heap_global_name(self, pool: memhub.MemBuddy*, trans: HT.Translator*, name: str) -> str: """构造 nonlocal 堆地址全局映射变量名 nlheap_{sha1}.{name}""" if pool is None or trans is None or name is None: return None mangled: str = self.Gen.FuncGenBase._mangle_name(trans, name) @@ -749,9 +744,7 @@ novirtual class FuncGenMixin(CallGenBase.CallGenBase): # ============================================================ # _nl_heap_global_ref - 全局映射变量引用 Value(i8**) # ============================================================ - def _nl_heap_global_ref(self, pool: memhub.MemBuddy*, - trans: HT.Translator*, - name: str) -> mlirlite.Value*: + def _nl_heap_global_ref(self, pool: memhub.MemBuddy*, trans: HT.Translator*, name: str) -> mlirlite.Value*: """获取 nonlocal 堆地址全局映射变量的引用(@"..." 引号包裹)""" if pool is None or trans is None or name is None: return None gname: str = self._nl_heap_global_name(pool, trans, name) @@ -766,8 +759,7 @@ novirtual class FuncGenMixin(CallGenBase.CallGenBase): # ============================================================ # _nl_heap_global_exists - 检查 nonlocal 堆地址全局映射变量是否存在 # ============================================================ - def _nl_heap_global_exists(self, mod: mlirlite.LLVMModule*, - gname: str) -> int: + def _nl_heap_global_exists(self, mod: mlirlite.LLVMModule*, gname: str) -> int: """检查全局映射变量 gname 是否已在模块中,1=存在""" if mod is None or gname is None: return 0 gcur: mlirlite.GlobalVariable* = mod.GlobalHead @@ -782,10 +774,7 @@ novirtual class FuncGenMixin(CallGenBase.CallGenBase): # 遍历 node(FunctionDef)的 children:遇嵌套 FunctionDef 递归, # 遇 Nonlocal 语句收集变量名(去重)。返回更新后的计数。 # ============================================================ - def _collect_chain_nonlocals(self, trans: HT.Translator*, - node: ast.AST*, - names: t.CPtr, - count: int) -> int: + def _collect_chain_nonlocals(self, trans: HT.Translator*, node: ast.AST*, names: t.CPtr, count: int) -> int: """递归收集 node(FunctionDef)链内所有 nonlocal 声明名(去重)""" if node is None or names is None: return count fd: ast.FunctionDef* = ast.FunctionDef*(node) @@ -828,13 +817,7 @@ novirtual class FuncGenMixin(CallGenBase.CallGenBase): # 建堆 + 重定向 VarEntry + 把堆地址 store 到模块级映射 # @nlheap.{sha1}.{name}(全局变量跨函数可见),内层闭包创建时从映射 load。 # ============================================================ - def _prepare_chain_nonlocals(self, trans: HT.Translator*, - node: ast.AST*, - pool: memhub.MemBuddy*, - builder: mlirlite.IRBuilder*, - mod: mlirlite.LLVMModule*, - i8_ty: mlirlite.LLVMType*, - i8_ptr_ty: mlirlite.LLVMType*) -> int: + def _prepare_chain_nonlocals(self, trans: HT.Translator*, node: ast.AST*, pool: memhub.MemBuddy*, builder: mlirlite.IRBuilder*, mod: mlirlite.LLVMModule*, i8_ty: mlirlite.LLVMType*, i8_ptr_ty: mlirlite.LLVMType*) -> int: """预收集嵌套函数链内 nonlocal 并建堆,1 成功""" if node is None or trans is None or builder is None or mod is None: return 0 # 每函数只预建一次:多个嵌套函数定义共享同一堆(防重复 malloc + @@ -906,11 +889,7 @@ novirtual class FuncGenMixin(CallGenBase.CallGenBase): # 3. 创建闭包 {fn_ptr, env_ptr},返回 i8* 闭包指针 # 赋值语句据此创建 i8** alloca,调用走 translate_closure_call # ============================================================ - def translate_lambda(self, builder: mlirlite.IRBuilder*, - pool: memhub.MemBuddy*, - mod: mlirlite.LLVMModule*, - node: ast.AST*, - trans: HT.Translator* = None) -> mlirlite.Value*: + def translate_lambda(self, builder: mlirlite.IRBuilder*, pool: memhub.MemBuddy*, mod: mlirlite.LLVMModule*, node: ast.AST*, trans: HT.Translator* = None) -> mlirlite.Value*: """翻译 lambda 表达式,返回闭包指针(i8*)""" if node is None or trans is None or builder is None: return None lam: rawptr[ast.Lambda] = rawptr[ast.Lambda](node) @@ -1003,8 +982,7 @@ novirtual class FuncGenMixin(CallGenBase.CallGenBase): mlirlite.position_at_end(func_builder, entry_blk) # --traceback: promoted lambda gets its own DISubprogram. - dbg_pushed_l: int = DebugInfoGen.PushFunction(pool, func_builder, func, - node.lineno, node.col_offset + 1) + dbg_pushed_l: int = DebugInfoGen.PushFunction(pool, func_builder, func, node.lineno, node.col_offset + 1) # 6. 进入 lambda 作用域 self.Gen.VarGen.enter_scope(trans.SymTab, SCOPE_FUNCTION) @@ -1184,14 +1162,7 @@ novirtual class FuncGenMixin(CallGenBase.CallGenBase): # 记录到 cap_names/cap_allocas/cap_tys 三个并行缓冲。 # 返回更新后的捕获数量(递归调用逐层累加)。 # ============================================================ - def _lambda_scan_body(self, trans: HT.Translator*, - node: ast.AST*, - param_names: str, - param_count: int, - cap_names: str, - cap_allocas: t.CPtr, - cap_tys: t.CPtr, - cap_count: int) -> int: + def _lambda_scan_body(self, trans: HT.Translator*, node: ast.AST*, param_names: str, param_count: int, cap_names: str, cap_allocas: t.CPtr, cap_tys: t.CPtr, cap_count: int) -> int: """递归扫描 lambda body 中的 Name 引用,收集捕获变量""" if node is None or trans is None: return cap_count k: int = node.kind() @@ -1223,14 +1194,11 @@ novirtual class FuncGenMixin(CallGenBase.CallGenBase): # 递归遍历常见表达式子节点 if k == ast.ASTKind.BinOp: bop: ast.BinOp* = ast.BinOp*(node) - cc1: int = self._lambda_scan_body(trans, bop.left, param_names, param_count, - cap_names, cap_allocas, cap_tys, cap_count) - return self._lambda_scan_body(trans, bop.right, param_names, param_count, - cap_names, cap_allocas, cap_tys, cc1) + cc1: int = self._lambda_scan_body(trans, bop.left, param_names, param_count, cap_names, cap_allocas, cap_tys, cap_count) + return self._lambda_scan_body(trans, bop.right, param_names, param_count, cap_names, cap_allocas, cap_tys, cc1) if k == ast.ASTKind.UnaryOp: uop: ast.UnaryOp* = ast.UnaryOp*(node) - return self._lambda_scan_body(trans, uop.operand, param_names, param_count, - cap_names, cap_allocas, cap_tys, cap_count) + return self._lambda_scan_body(trans, uop.operand, param_names, param_count, cap_names, cap_allocas, cap_tys, cap_count) if k == ast.ASTKind.BoolOp: bop2: rawptr[ast.BoolOp] = rawptr[ast.BoolOp](node) cc2: int = cap_count @@ -1238,59 +1206,47 @@ novirtual class FuncGenMixin(CallGenBase.CallGenBase): vs: list[ast.AST*]* = bop2.values vn: sizet = len(vs) for vi in range(vn): - cc2 = self._lambda_scan_body(trans, vs.get(vi), param_names, param_count, - cap_names, cap_allocas, cap_tys, cc2) + cc2 = self._lambda_scan_body(trans, vs.get(vi), param_names, param_count, cap_names, cap_allocas, cap_tys, cc2) return cc2 if k == ast.ASTKind.Compare: cmp: rawptr[ast.Compare] = rawptr[ast.Compare](node) - cc3: int = self._lambda_scan_body(trans, cmp.left, param_names, param_count, - cap_names, cap_allocas, cap_tys, cap_count) + cc3: int = self._lambda_scan_body(trans, cmp.left, param_names, param_count, cap_names, cap_allocas, cap_tys, cap_count) if cmp.comparators is not None: cl: list[ast.AST*]* = cmp.comparators cn: sizet = len(cl) for cvi in range(cn): - cc3 = self._lambda_scan_body(trans, cl.get(cvi), param_names, param_count, - cap_names, cap_allocas, cap_tys, cc3) + cc3 = self._lambda_scan_body(trans, cl.get(cvi), param_names, param_count, cap_names, cap_allocas, cap_tys, cc3) return cc3 if k == ast.ASTKind.Call: cal: ast.Call* = ast.Call*(node) - cc4: int = self._lambda_scan_body(trans, cal.func, param_names, param_count, - cap_names, cap_allocas, cap_tys, cap_count) + cc4: int = self._lambda_scan_body(trans, cal.func, param_names, param_count, cap_names, cap_allocas, cap_tys, cap_count) if cal.args is not None: als: list[ast.AST*]* = cal.args an: sizet = len(als) for ai in range(an): - cc4 = self._lambda_scan_body(trans, als.get(ai), param_names, param_count, - cap_names, cap_allocas, cap_tys, cc4) + cc4 = self._lambda_scan_body(trans, als.get(ai), param_names, param_count, cap_names, cap_allocas, cap_tys, cc4) if cal.keywords is not None: kws: list[ast.AST*]* = cal.keywords kn: sizet = len(kws) for ki in range(kn): kw: rawptr[ast.Keyword] = rawptr[ast.Keyword](kws.get(ki)) if kw is not None and kw.value is not None: - cc4 = self._lambda_scan_body(trans, kw.value, param_names, param_count, - cap_names, cap_allocas, cap_tys, cc4) + cc4 = self._lambda_scan_body(trans, kw.value, param_names, param_count, cap_names, cap_allocas, cap_tys, cc4) return cc4 if k == ast.ASTKind.Subscript: sub: ast.Subscript* = ast.Subscript*(node) - cc5: int = self._lambda_scan_body(trans, sub.value, param_names, param_count, - cap_names, cap_allocas, cap_tys, cap_count) + cc5: int = self._lambda_scan_body(trans, sub.value, param_names, param_count, cap_names, cap_allocas, cap_tys, cap_count) if sub.slice is not None: - cc5 = self._lambda_scan_body(trans, sub.slice, param_names, param_count, - cap_names, cap_allocas, cap_tys, cc5) + cc5 = self._lambda_scan_body(trans, sub.slice, param_names, param_count, cap_names, cap_allocas, cap_tys, cc5) return cc5 if k == ast.ASTKind.Attribute: at: ast.Attribute* = ast.Attribute*(node) - return self._lambda_scan_body(trans, at.value, param_names, param_count, - cap_names, cap_allocas, cap_tys, cap_count) + return self._lambda_scan_body(trans, at.value, param_names, param_count, cap_names, cap_allocas, cap_tys, cap_count) if k == ast.ASTKind.IfExp: ie: rawptr[ast.IfExp] = rawptr[ast.IfExp](node) - cc6: int = self._lambda_scan_body(trans, ie.test, param_names, param_count, - cap_names, cap_allocas, cap_tys, cap_count) - cc6 = self._lambda_scan_body(trans, ie.body, param_names, param_count, - cap_names, cap_allocas, cap_tys, cc6) - return self._lambda_scan_body(trans, ie.orelse, param_names, param_count, - cap_names, cap_allocas, cap_tys, cc6) + cc6: int = self._lambda_scan_body(trans, ie.test, param_names, param_count, cap_names, cap_allocas, cap_tys, cap_count) + cc6 = self._lambda_scan_body(trans, ie.body, param_names, param_count, cap_names, cap_allocas, cap_tys, cc6) + return self._lambda_scan_body(trans, ie.orelse, param_names, param_count, cap_names, cap_allocas, cap_tys, cc6) if k == ast.ASTKind.List: ls: ast.List* = ast.List*(node) cc7: int = cap_count @@ -1298,11 +1254,9 @@ novirtual class FuncGenMixin(CallGenBase.CallGenBase): es: list[ast.AST*]* = ls.elts en: sizet = len(es) for ei in range(en): - cc7 = self._lambda_scan_body(trans, es.get(ei), param_names, param_count, - cap_names, cap_allocas, cap_tys, cc7) + cc7 = self._lambda_scan_body(trans, es.get(ei), param_names, param_count, cap_names, cap_allocas, cap_tys, cc7) return cc7 if k == ast.ASTKind.Lambda: lam2: rawptr[ast.Lambda] = rawptr[ast.Lambda](node) - return self._lambda_scan_body(trans, lam2.body, param_names, param_count, - cap_names, cap_allocas, cap_tys, cap_count) + return self._lambda_scan_body(trans, lam2.body, param_names, param_count, cap_names, cap_allocas, cap_tys, cap_count) return cap_count diff --git a/App/lib/core/Gen/GenApi.vp b/App/lib/core/Gen/GenApi.vp index e4a7694..9a476c7 100644 --- a/App/lib/core/Gen/GenApi.vp +++ b/App/lib/core/Gen/GenApi.vp @@ -89,8 +89,7 @@ def dump_parse_traceback(file_path: str) -> None: # ---------------- fatal_error(委托 TypeGenErr.fatal_error) ---------------- -def fatal_error(node: ast.AST*, msg: str, - err_type: str = "SyntaxError") -> None: +def fatal_error(node: ast.AST*, msg: str, err_type: str = "SyntaxError") -> None: """委托到 gen.TypeGenErr.fatal_error —— 模块级函数的报错通道 VpiReader / Converter 等模块级函数没有 self.Gen,无法直接调用 @@ -115,19 +114,14 @@ def map_t_type(pool: memhub.MemBuddy*, type_name: str) -> mlirlite.LLVMType*: # ---------------- resolve_typedef_or_map(委托 TypeGenResolve.resolve_typedef_or_map) ---------------- -def resolve_typedef_or_map(pool: memhub.MemBuddy*, - name: str, - imported_modules: str, - from_imports: str, - trans: HT.Translator* = None) -> mlirlite.LLVMType*: +def resolve_typedef_or_map(pool: memhub.MemBuddy*, name: str, imported_modules: str, from_imports: str, trans: HT.Translator* = None) -> mlirlite.LLVMType*: """委托到 gen.resolve_typedef_or_map(CTypedef 动态表优先,miss 回退 map_t_type)""" if _g_gen is not None: return _g_gen.TypeGenResolve.resolve_typedef_or_map(pool, name, imported_modules, from_imports, trans) return None # ---------------- infer_external_func_ret_ty(委托 CallGenLib._infer_external_func_ret_ty) ---------------- -def infer_external_func_ret_ty(pool: memhub.MemBuddy*, - func_name: str) -> mlirlite.LLVMType*: +def infer_external_func_ret_ty(pool: memhub.MemBuddy*, func_name: str) -> mlirlite.LLVMType*: """委托到 gen.CallGenLib._infer_external_func_ret_ty(外部函数返回类型白名单) vpi 注入 extern declare 时返回类型解析 miss 的兜底:FindFirstFileA/ @@ -162,8 +156,7 @@ def resolve_annotation_type(pool: memhub.MemBuddy*, node: ast.AST*, imported_mod # ---------------- has_decorator_marker(委托 TypeGenErr.has_decorator_marker) ---------------- -def has_decorator_marker(node: ast.AST*, marker_name: str, - depth: int = 0) -> int: +def has_decorator_marker(node: ast.AST*, marker_name: str, depth: int = 0) -> int: """委托到 gen.has_decorator_marker(原 Handles 壳)""" if _g_gen is not None: return _g_gen.TypeGenErr.has_decorator_marker(node, marker_name, depth) return 0 @@ -197,15 +190,13 @@ def is_cdefine_found() -> int: # ---------------- register_cdefine_constant(委托 TypeGenCDef.register_cdefine_constant) ---------------- -def register_cdefine_constant(pool: memhub.MemBuddy*, - name: str, value: int64): +def register_cdefine_constant(pool: memhub.MemBuddy*, name: str, value: int64): """委托到 gen.register_cdefine_constant(原 Handles 壳)""" if _g_gen is not None: _g_gen.TypeGenCDef.register_cdefine_constant(pool, name, value) # ---------------- register_cdefine_double(委托 TypeGenCDef.register_cdefine_double) ---------------- -def register_cdefine_double(pool: memhub.MemBuddy*, - name: str, value: double): +def register_cdefine_double(pool: memhub.MemBuddy*, name: str, value: double): """委托到 gen.register_cdefine_double(原 Handles 壳)""" if _g_gen is not None: _g_gen.TypeGenCDef.register_cdefine_double(pool, name, value) @@ -344,30 +335,21 @@ def find_struct_by_type(struct_ty: mlirlite.LLVMType*) -> GenTypes.StructEntry*: # ---------------- register_struct(委托 StructGenMixin.register_struct) ---------------- -def register_struct(pool: memhub.MemBuddy*, - name: str, - struct_ty: mlirlite.LLVMType*, - sha1: str = None) -> GenTypes.StructEntry*: +def register_struct(pool: memhub.MemBuddy*, name: str, struct_ty: mlirlite.LLVMType*, sha1: str = None) -> GenTypes.StructEntry*: """委托到 gen.register_struct(原 Handles 壳)""" if _g_gen is not None: return _g_gen.StructGen.register_struct(pool, name, struct_ty, sha1) return None # ---------------- add_field(委托 StructGenMixin.add_field) ---------------- -def add_field(pool: memhub.MemBuddy*, - struct_entry: GenTypes.StructEntry*, - field_name: str, - field_ty: mlirlite.LLVMType*) -> int: +def add_field(pool: memhub.MemBuddy*, struct_entry: GenTypes.StructEntry*, field_name: str, field_ty: mlirlite.LLVMType*) -> int: """委托到 gen.add_field(原 Handles 壳)""" if _g_gen is not None: return _g_gen.StructGen.add_field(pool, struct_entry, field_name, field_ty) return -1 # ---------------- register_struct_alias(委托 StructGenMixin.register_struct_alias) ---------------- -def register_struct_alias(pool: memhub.MemBuddy*, - name: str, - sha1: str, - src_entry: GenTypes.StructEntry*) -> GenTypes.StructEntry*: +def register_struct_alias(pool: memhub.MemBuddy*, name: str, sha1: str, src_entry: GenTypes.StructEntry*) -> GenTypes.StructEntry*: """委托到 gen.StructGen.register_struct_alias(包重导出类别名注册,原 Handles 壳)""" if _g_gen is not None: return _g_gen.StructGen.register_struct_alias(pool, name, sha1, src_entry) return None @@ -531,13 +513,7 @@ def fail_if_fstring_escape(node: ast.AST*, where: str) -> int: i += 1 if hit == 0: return 0 if _g_gen is not None: - _g_gen.TypeGenErr.fatal_error(node, - f"f-string 结果不能用于{where}(逃逸):f-string 指向**当前函数的栈缓冲**," - f"函数返回即失效,把这个指针带出函数会读到已弹栈的帧" - f"(历史事故:ASan stack-buffer-underflow in vsnprintf)。" - f"需要带出函数时显式分配后拷贝:" - f"tmp: str = f\"...\";out: str = GenApi.escape_fstring_copy(tmp);return out。", - "TypeError") + _g_gen.TypeGenErr.fatal_error(node, f"f-string 结果不能用于{where}(逃逸):f-string 指向**当前函数的栈缓冲**," f"函数返回即失效,把这个指针带出函数会读到已弹栈的帧" f"(历史事故:ASan stack-buffer-underflow in vsnprintf)。" f"需要带出函数时显式分配后拷贝:" f"tmp: str = f\"...\";out: str = GenApi.escape_fstring_copy(tmp);return out。", "TypeError") return 0 @@ -647,15 +623,13 @@ def is_global_name(trans: HT.Translator*, name: str) -> int: # ---------------- add_nonlocal_name(委托 TranslatorGenMixin.add_nonlocal_name) ---------------- -def add_nonlocal_name(trans: HT.Translator*, name: str, - var_ty: mlirlite.LLVMType* = None): +def add_nonlocal_name(trans: HT.Translator*, name: str, var_ty: mlirlite.LLVMType* = None): """委托到 gen.TranslatorGen.add_nonlocal_name(原 Handles 壳)""" if _g_gen is not None: _g_gen.TranslatorGen.add_nonlocal_name(trans, name, var_ty) # ---------------- get_nonlocal_type(委托 TranslatorGenMixin.get_nonlocal_type) ---------------- -def get_nonlocal_type(trans: HT.Translator*, - name: str) -> mlirlite.LLVMType*: +def get_nonlocal_type(trans: HT.Translator*, name: str) -> mlirlite.LLVMType*: """委托到 gen.TranslatorGen.get_nonlocal_type(原 Handles 壳)""" if _g_gen is not None: return _g_gen.TranslatorGen.get_nonlocal_type(trans, name) return None @@ -682,8 +656,7 @@ def clear_scope_names(trans: HT.Translator*): # ---------------- update_global_func_spec(委托 CallGenLeafKit.update_global_func_spec) ---------------- -def update_global_func_spec(name: str, - func: mlirlite.Function*) -> int: +def update_global_func_spec(name: str, func: mlirlite.Function*) -> int: """委托到 gen.CallGenLeafKit.update_global_func_spec(原 ExprCallTable 壳)""" if _g_gen is not None: return _g_gen.CallGenLeafKit.update_global_func_spec(name, func) return 0 diff --git a/App/lib/core/Gen/ImportsGenMixin.vp b/App/lib/core/Gen/ImportsGenMixin.vp index b6db411..7f2becd 100644 --- a/App/lib/core/Gen/ImportsGenMixin.vp +++ b/App/lib/core/Gen/ImportsGenMixin.vp @@ -68,8 +68,7 @@ novirtual class ImportsGenMixin: # name_ptr 指向新串内的新模块名(key 直接引用串内部,无需复制)。 # 仅当 old_ptr 恰为当前索引绑定的串时复用其索引;否则放弃索引绑定并回退 # 逐字符扫描(语义不变)。 - def _index_imported_module(self, old_ptr: str, new_ptr: str, - name_ptr: str) -> None: + def _index_imported_module(self, old_ptr: str, new_ptr: str, name_ptr: str) -> None: """增量更新 imported_modules 索引(复用旧索引或新建,失败则解除绑定)""" if new_ptr is None or name_ptr is None: return perm: memhub.MemBuddy* = CompilerFactory.factory.PermPool @@ -100,9 +99,7 @@ novirtual class ImportsGenMixin: # 模块表 key=local_name → 指向模块名切片;orig 表 key=local_name → 指向原始名 # 切片(无别名时写入 None,以"名存在但无原始名"区别于未命中)。 # 语义对齐逐字符扫描:精确名首次命中为准(不覆盖),star 模块名以最后一条为准。 - def _index_from_import(self, old_ptr: str, new_ptr: str, entry_off: sizet, - local_name: str, module_name: str, - original_name: str) -> None: + def _index_from_import(self, old_ptr: str, new_ptr: str, entry_off: sizet, local_name: str, module_name: str, original_name: str) -> None: """增量更新 from_imports 索引(复用旧索引或新建,失败则解除绑定)""" if new_ptr is None or local_name is None or module_name is None: return perm: memhub.MemBuddy* = CompilerFactory.factory.PermPool @@ -157,9 +154,7 @@ novirtual class ImportsGenMixin: # ============================================================ # 添加已导入模块名 # ============================================================ - def add_imported_module(self, pool: memhub.MemBuddy*, - imported_modules: str, - name: str) -> str: + def add_imported_module(self, pool: memhub.MemBuddy*, imported_modules: str, name: str) -> str: """记录已导入的模块名,返回新的 imported_modules 字符串指针 字符串记账走 StubMergerStore.AppendImportedModule(单一真源,与 vpi @@ -247,11 +242,7 @@ novirtual class ImportsGenMixin: # ============================================================ # 添加 from-import 名称映射 # ============================================================ - def add_from_import(self, pool: memhub.MemBuddy*, - from_imports: str, - local_name: str, - module_name: str, - original_name: str = None) -> str: + def add_from_import(self, pool: memhub.MemBuddy*, from_imports: str, local_name: str, module_name: str, original_name: str = None) -> str: """添加 from-import 映射,返回新的 from_imports 字符串 格式: @@ -265,14 +256,12 @@ novirtual class ImportsGenMixin: if local_name is None or module_name is None: return from_imports old_len: sizet = 0 if from_imports is not None: old_len = string.strlen(from_imports) - buf: str = StubMergerStore.AppendFromImport( - pool, from_imports, local_name, module_name, original_name) + buf: str = StubMergerStore.AppendFromImport(pool, from_imports, local_name, module_name, original_name) if buf is None: return from_imports # 索引:首条 entry_off=0;追加时 entry 从 buf[old_len+1] 开始 entry_off: sizet = 0 if from_imports is not None: entry_off = old_len + 1 - self._index_from_import(from_imports, buf, entry_off, - local_name, module_name, original_name) + self._index_from_import(from_imports, buf, entry_off, local_name, module_name, original_name) return buf # ============================================================ @@ -281,8 +270,7 @@ novirtual class ImportsGenMixin: # 对于 from X import Y as Z,返回 Y(源模块中的真实函数名)。 # 无别名时返回 None(local_name 即为原始名)。 # ============================================================ - def lookup_from_import_original(self, from_imports: str, - local_name: str) -> str: + def lookup_from_import_original(self, from_imports: str, local_name: str) -> str: """查找 from-import 别名对应的原始函数名,返回 None=无别名或未找到""" if local_name is None or from_imports is None: return None # [索引快路径] 传入串即当前索引绑定的串 → O(名字长) 哈希查;否则回退扫描。 @@ -350,8 +338,7 @@ novirtual class ImportsGenMixin: # 避免被 star import 模块名误导(如 from stdint import * 后 # 查询 "BuildPipeline" 错误回退到 "stdint")。 # ============================================================ - def lookup_from_import(self, from_imports: str, name: str, - allow_star_fallback: int = 1) -> str: + def lookup_from_import(self, from_imports: str, name: str, allow_star_fallback: int = 1) -> str: """查找 from-import 名称,返回模块名或 None 支持 star import: 如果 from_imports 中有 "*:module" 条目, @@ -494,10 +481,7 @@ novirtual class ImportsGenMixin: # 解析后的完整模块名;绝对导入(level<=0)直接返回 module; # 无法解析时返回 module(回退到原始值) # ============================================================ - def _resolve_relative_module(self, pool: memhub.MemBuddy*, - current_package: str, - level: int, - module: str) -> str: + def _resolve_relative_module(self, pool: memhub.MemBuddy*, current_package: str, level: int, module: str) -> str: """解析相对导入为完整模块名""" if level <= 0: return module if current_package is None: @@ -566,8 +550,7 @@ novirtual class ImportsGenMixin: # "ast/parser.vp" → "ast" # "ast.vp" → None(顶级文件) # ============================================================ - def compute_package_from_relpath(self, pool: memhub.MemBuddy*, - rel_path: str) -> str: + def compute_package_from_relpath(self, pool: memhub.MemBuddy*, rel_path: str) -> str: """从相对路径计算包名(目录部分,分隔符替换为 .)""" if rel_path is None: return None rlen: sizet = string.strlen(rel_path) @@ -722,9 +705,7 @@ novirtual class ImportsGenMixin: if self._is_local_module_file(mod_name) != 0: return 1 err_buf: str = stdlib.malloc(256) if err_buf is not None: - viperlib.snprintf(err_buf, 256, - "模块 '%s' 未注册 SHA1(includes 扫描未找到该模块,请检查 project.json 的 includes 路径配置)", - mod_name) + viperlib.snprintf(err_buf, 256, "模块 '%s' 未注册 SHA1(includes 扫描未找到该模块,请检查 project.json 的 includes 路径配置)", mod_name) self._report_import_error(node, err_buf) else: self._report_import_error(node, "导入模块 SHA1 未注册(includes 扫描未找到该模块)") return 1 @@ -733,8 +714,7 @@ novirtual class ImportsGenMixin: # translate_import - 处理 import 语句,更新 trans._imported_modules # (迁移自 HandlesImports.ImportsHandle.HandleImport) # ============================================================ - def translate_import(self, trans: HT.Translator*, - node: ast.AST*) -> int: + def translate_import(self, trans: HT.Translator*, node: ast.AST*) -> int: """处理 import 语句,返回 0 记账走 StubMergerStore.NotePlainImport(**该约定的唯一实现**):与 vpi @@ -753,8 +733,7 @@ novirtual class ImportsGenMixin: if names is None: return 0 nn: sizet = len(names) pool_val: memhub.MemBuddy* = trans.Pool - ctx: StubMergerStore.ImportCtx* = StubMergerStore.AllocImportCtx( - pool_val, trans._imported_modules, trans._from_imports) + ctx: StubMergerStore.ImportCtx* = StubMergerStore.AllocImportCtx(pool_val, trans._imported_modules, trans._from_imports) if ctx is None: return 0 for ni in range(nn): alias: ast.Alias* = ast.Alias*(names.get(ni)) @@ -776,14 +755,12 @@ novirtual class ImportsGenMixin: # 完整模块名(如 __types → mlirlite.__types),确保 .deps.txt # 记录的模块名与 SHA1 映射表一致。 # ============================================================ - def translate_import_from_module(self, trans: HT.Translator*, - node: ast.AST*) -> int: + def translate_import_from_module(self, trans: HT.Translator*, node: ast.AST*) -> int: """处理 from X import Y 的模块部分,更新 trans._imported_modules""" impf: ast.ImportFrom* = ast.ImportFrom*(node) if impf is None: return 0 # 解析模块名:相对导入需补充包前缀 - resolved: str = self._resolve_relative_module(trans.Pool, trans.CurrentPackage, - impf.level, impf.module) + resolved: str = self._resolve_relative_module(trans.Pool, trans.CurrentPackage, impf.level, impf.module) if resolved is not None: # 导入时立即校验模块 SHA1 是否注册(fast-fail,仅全量翻译时检查) # from . import Y(impf.module is None):resolved 是包目录名 @@ -816,8 +793,7 @@ novirtual class ImportsGenMixin: # 文件、不注册 SHA1。仅当完整名已注册 SHA1(真子模块)或是 # 本地文件时才校验+登记;否则跳过,符号映射由 # translate_import_from_names 的 from-import / re-export 处理。 - if (StubMergerStore.LookupSha1ByModName(jb_m) is not None - or self._is_local_module_file(alias_m.name) != 0): + if (StubMergerStore.LookupSha1ByModName(jb_m) is not None or self._is_local_module_file(alias_m.name) != 0): if trans._declare_only == 0: self._check_import_sha1(node, jb_m) trans._imported_modules = self.add_imported_module(trans.Pool, trans._imported_modules, jb_m) return 0 @@ -837,10 +813,7 @@ novirtual class ImportsGenMixin: # 独立成函数:内联进 translate_import_from_names 会干扰其类型推断(同款处理 # 见 ExprGenAttr._CheckStaticCrossModule 与 CallGenMixin._CheckStaticCallCrossModule)。 # ============================================================ - def _CheckStaticFromImport(self, trans: HT.Translator*, - fi_target: str, - orig_name: str, - node: ast.AST*) -> int: + def _CheckStaticFromImport(self, trans: HT.Translator*, fi_target: str, orig_name: str, node: ast.AST*) -> int: if trans is None or fi_target is None or orig_name is None: return 0 if trans.ModuleSha1 is None: return 0 # 快速短路:项目内无 static 符号时零开销(不查 sha1、不扫表) @@ -849,20 +822,16 @@ novirtual class ImportsGenMixin: if sf_sha1 is None: return 0 if string.strncmp(sf_sha1, trans.ModuleSha1, 16) == 0: return 0 if self.Gen.CallGenBase.IsStaticSymbol(sf_sha1, orig_name) == 0: return 0 - self.Gen.TypeGenErr.fatal_error(node, - f"'{fi_target}.{orig_name}' 是 static 符号,禁止跨模块使用(static 仅限定义模块内可见)", - "NameError") + self.Gen.TypeGenErr.fatal_error(node, f"'{fi_target}.{orig_name}' 是 static 符号,禁止跨模块使用(static 仅限定义模块内可见)", "NameError") return 0 - def translate_import_from_names(self, trans: HT.Translator*, - node: ast.AST*) -> int: + def translate_import_from_names(self, trans: HT.Translator*, node: ast.AST*) -> int: """处理 from X import Y 的名称部分,更新 trans._from_imports""" impf: ast.ImportFrom* = ast.ImportFrom*(node) if impf is None: return 0 # 解析模块名:相对导入需补充包前缀 - resolved: str = self._resolve_relative_module(trans.Pool, trans.CurrentPackage, - impf.level, impf.module) + resolved: str = self._resolve_relative_module(trans.Pool, trans.CurrentPackage, impf.level, impf.module) if resolved is not None: names: list[ast.AST*]* = impf.names if names is not None: @@ -889,8 +858,7 @@ novirtual class ImportsGenMixin: jb_t[fl_t] = '.' string.strcpy(jb_t + fl_t + 1, alias.name) fi_target = jb_t - trans._from_imports = self.add_from_import(trans.Pool, trans._from_imports, - local_name, fi_target, orig_name) + trans._from_imports = self.add_from_import(trans.Pool, trans._from_imports, local_name, fi_target, orig_name) # static 符号(禁止跨模块使用):from mod import name 命中源 # 模块登记的 static 符号 → fail-fast。逻辑收敛在 # _CheckStaticFromImport 内(不内联——内联新增分支会干扰本函数 diff --git a/App/lib/core/Gen/MatchGenMixin.vp b/App/lib/core/Gen/MatchGenMixin.vp index c7b96ae..7c2a748 100644 --- a/App/lib/core/Gen/MatchGenMixin.vp +++ b/App/lib/core/Gen/MatchGenMixin.vp @@ -36,9 +36,7 @@ novirtual class MatchGenMixin: # 返回 1=已补 unreachable(调用方不应 br end_bb);0=正常收尾(应 br end_bb)。 # 不含 Try/With:其处理器不维护 _ctrl_merge_reachable,避免残留值误判。 Gen: Generator.Generator* - def _case_tail_unreachable(self, trans: HT.Translator*, - builder: mlirlite.IRBuilder*, - body_list: list[ast.AST*]*) -> int: + def _case_tail_unreachable(self, trans: HT.Translator*, builder: mlirlite.IRBuilder*, body_list: list[ast.AST*]*) -> int: if trans is None or builder is None: return 0 if mlirlite.builder_cur_block_is_terminated(builder) != 0: return 0 if body_list is None or len(body_list) == 0: return 0 @@ -54,8 +52,7 @@ novirtual class MatchGenMixin: # translate_match - match 语句主入口,返回 0 # (迁移自 HandlesMatch.MatchHandle.Handle) # ============================================================ - def translate_match(self, trans: HT.Translator*, - node: ast.AST*) -> int: + def translate_match(self, trans: HT.Translator*, node: ast.AST*) -> int: """match 语句翻译主入口(深度守卫包装器,原逻辑见 _translate_match_impl)""" if trans is not None: if trans.MatchTranslateDepth >= MATCH_TRANSLATE_MAX_DEPTH: self.Gen.TypeGenErr.fatal_error(node, "match 翻译嵌套过深(疑似 AST 自引用环或翻译 bug)", "RecursionError") @@ -64,8 +61,7 @@ novirtual class MatchGenMixin: if trans is not None: trans.MatchTranslateDepth -= 1 return mret - def _translate_match_impl(self, trans: HT.Translator*, - node: ast.AST*) -> int: + def _translate_match_impl(self, trans: HT.Translator*, node: ast.AST*) -> int: if node is None: return 0 pool: memhub.MemBuddy* = trans.Pool builder: mlirlite.IRBuilder* = trans._cur_builder @@ -112,14 +108,11 @@ novirtual class MatchGenMixin: if dcase2 is not None and dcase2.kind() == ast.ASTKind.MatchCase: dpat2: ast.AST* = rawptr[ast.MatchCase](dcase2).pattern if self._case_label_same(dpat, dpat2) != 0: - self.Gen.TypeGenErr.fatal_error(dcase2, - f"match 出现重名 case:第 {dci} 与第 {dcj} 个 case 的标签相同(match 不允许重复 case 标签)", - "SyntaxError") + self.Gen.TypeGenErr.fatal_error(dcase2, f"match 出现重名 case:第 {dci} 与第 {dcj} 个 case 的标签相同(match 不允许重复 case 标签)", "SyntaxError") dcj = dcj + 1 dci = dci + 1 if default_cnt > 1: - self.Gen.TypeGenErr.fatal_error(node, - f"{kind_label} 出现 {default_cnt} 个{default_label}(无 guard 的通配/default 只允许一个;带 guard 的 `case _ if ...` / `default if ...` 可有多个)", "SyntaxError") + self.Gen.TypeGenErr.fatal_error(node, f"{kind_label} 出现 {default_cnt} 个{default_label}(无 guard 的通配/default 只允许一个;带 guard 的 `case _ if ...` / `default if ...` 可有多个)", "SyntaxError") # 1. 求值 subject subject_node: ast.AST* = m_node.subject @@ -129,8 +122,7 @@ novirtual class MatchGenMixin: # 提前分派到 _handle_sequence_match,避免 fail-fast 误报。 sk_seq: int = subject_node.kind() if sk_seq == ast.ASTKind.Tuple or sk_seq == ast.ASTKind.List: return self._handle_sequence_match(trans, m_node, subject_node) - subject_val: mlirlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, trans.Module, subject_node, - trans._funcs, trans._func_count, trans) + subject_val: mlirlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, trans.Module, subject_node, trans._funcs, trans._func_count, trans) if subject_val is None: # fail-fast: match subject 翻译失败 self.Gen.TypeGenErr.fatal_error(subject_node, "match subject 翻译失败", "TypeError") @@ -146,8 +138,7 @@ novirtual class MatchGenMixin: if nm.id is not None: entry: GenTypes.VarEntry* = self.Gen.VarGen.lookup_var_entry(trans.SymTab, nm.id) entry_annot: str = self.Gen.VarGen.var_annot_class_name(entry) - if entry_annot is not None and (self.Gen.ClassGenEnum._is_renum_class_name(entry_annot) != 0 - or self.Gen.ClassGenEnum._is_renum_by_entry(entry_annot) != 0): + if entry_annot is not None and (self.Gen.ClassGenEnum._is_renum_class_name(entry_annot) != 0 or self.Gen.ClassGenEnum._is_renum_by_entry(entry_annot) != 0): is_renum = 1 renum_name = entry_annot subject_ptr = self.Gen.VarGen.lookup_var(trans.SymTab, nm.id) @@ -165,8 +156,7 @@ novirtual class MatchGenMixin: pat: ast.AST* = mc.pattern if pat is not None and pat.kind() == ast.ASTKind.MatchClass: rnm: str = self._extract_renum_name_from_cls(pat) - if rnm is not None and (self.Gen.ClassGenEnum._is_renum_class_name(rnm) != 0 - or self.Gen.ClassGenEnum._is_renum_by_entry(rnm) != 0): + if rnm is not None and (self.Gen.ClassGenEnum._is_renum_class_name(rnm) != 0 or self.Gen.ClassGenEnum._is_renum_by_entry(rnm) != 0): is_renum = 1 renum_name = rnm if subject_ptr is None: subject_ptr = subject_val @@ -183,8 +173,7 @@ novirtual class MatchGenMixin: # mlirlite.LLVMType.Ptr -> Attribute(Attribute(Name('mlirlite'),'LLVMType'),'Ptr') -> 'LLVMType' # Ptr -> Name('Ptr') -> 遍历查找 # ============================================================ - def _extract_renum_name_from_cls(self, - pattern: ast.AST*) -> str: + def _extract_renum_name_from_cls(self, pattern: ast.AST*) -> str: if pattern is None: return None mc: rawptr[ast.MatchClass] = rawptr[ast.MatchClass](pattern) cls_node: ast.AST* = mc.cls @@ -208,8 +197,7 @@ novirtual class MatchGenMixin: # ============================================================ # _extract_variant_name_from_cls - 从 MatchClass.cls 提取变体名 # ============================================================ - def _extract_variant_name_from_cls(self, - pattern: ast.AST*) -> str: + def _extract_variant_name_from_cls(self, pattern: ast.AST*) -> str: if pattern is None: return None mc: rawptr[ast.MatchClass] = rawptr[ast.MatchClass](pattern) cls_node: ast.AST* = mc.cls @@ -323,10 +311,7 @@ novirtual class MatchGenMixin: # 3. 发射 build_switch # 4. 翻译每个 case body(含作用域隔离 + 变体字段绑定) # ============================================================ - def _handle_renum_match(self, trans: HT.Translator*, - node: ast.Match*, - renum_name: str, - subject_ptr: mlirlite.Value*) -> int: + def _handle_renum_match(self, trans: HT.Translator*, node: ast.Match*, renum_name: str, subject_ptr: mlirlite.Value*) -> int: pool: memhub.MemBuddy* = trans.Pool builder: mlirlite.IRBuilder* = trans._cur_builder func: mlirlite.Function* = trans._cur_func @@ -348,9 +333,7 @@ novirtual class MatchGenMixin: rn_case: ast.AST* = rn_cases.get(rn_i) if rn_case is not None and rn_case.kind() == ast.ASTKind.MatchCase: if rawptr[ast.MatchCase](rn_case).guard is not None: - self.Gen.TypeGenErr.fatal_error(rn_case, - "REnum match 暂不支持 guard 守卫(该臂会被 switch(tag) 静默忽略);请改为普通 match 或去掉 guard", - "NotImplementedError") + self.Gen.TypeGenErr.fatal_error(rn_case, "REnum match 暂不支持 guard 守卫(该臂会被 switch(tag) 静默忽略);请改为普通 match 或去掉 guard", "NotImplementedError") rn_i = rn_i + 1 # 0. subject 归一化:确保 subject_ptr 是指向 REnum 结构体的指针 @@ -500,8 +483,7 @@ novirtual class MatchGenMixin: if tag >= 0: tag_buf: str = pool.alloc(32) if tag_buf is not None: viperlib.snprintf(tag_buf, 32, "%d", tag) - cv = mlirlite.ConstInt(pool, tag_ty, tag, - tag_buf if tag_buf is not None else "0") + cv = mlirlite.ConstInt(pool, tag_ty, tag, tag_buf if tag_buf is not None else "0") elif pk == ast.ASTKind.MatchAs: ma: rawptr[ast.MatchAs] = rawptr[ast.MatchAs](pat) if ma.pattern is None: @@ -565,8 +547,7 @@ novirtual class MatchGenMixin: if is_def == 0 and cv is None and miss_cnt < 8 and pat is not None: pkm_d: int = pat.kind() if pkm_d == ast.ASTKind.MatchClass or pkm_d == ast.ASTKind.MatchValue: - viperlib.snprintf(diag_tmp, 128, " #%d(%s,tag=%d)", - i, vnm if vnm is not None else "?", tag) + viperlib.snprintf(diag_tmp, 128, " #%d(%s,tag=%d)", i, vnm if vnm is not None else "?", tag) string.strcat(miss_buf, diag_tmp) miss_cnt = miss_cnt + 1 @@ -579,9 +560,7 @@ novirtual class MatchGenMixin: # 结构性不可达。故不等即 fail-fast,打印类名/查表名/应提交数/实际数/ # 各未取到值臂的 序号(变体名,tag),便于定位变体表失配。 if need_case != sw_count: - self.Gen.TypeGenErr.fatal_error(node, - f"REnum match 分派丢失 case:class='{renum_name}'(查表名='{tag_cls_bare}')应提交 {need_case} 个 case,实际提交 {sw_count} 个;未取到值的臂:{miss_buf}", - "InternalCompilerError") + self.Gen.TypeGenErr.fatal_error(node, f"REnum match 分派丢失 case:class='{renum_name}'(查表名='{tag_cls_bare}')应提交 {need_case} 个 case,实际提交 {sw_count} 个;未取到值的臂:{miss_buf}", "InternalCompilerError") mlirlite.build_switch(builder, tag_val, default_bb, sw_head, sw_count) # 6. 查找 REnum 结构体类型(用于变体字段绑定的 GEP) @@ -652,10 +631,7 @@ novirtual class MatchGenMixin: # 变体字段绑定(MatchClass) if pat is not None and pat.kind() == ast.ASTKind.MatchClass: if renum_entry is not None and renum_ty is not None: self._bind_variant_fields(pat, renum_name, renum_entry, renum_ty, subject_ptr, trans, pool, builder) - elif (self.Gen.ClassGenEnum._is_renum_class_name(tag_cls_bare) != 0 - or self.Gen.ClassGenEnum._is_renum_class_name(renum_name) != 0 - or self.Gen.ClassGenEnum._is_renum_by_entry(tag_cls_bare) != 0 - or self.Gen.ClassGenEnum._is_renum_by_entry(renum_name) != 0): + elif (self.Gen.ClassGenEnum._is_renum_class_name(tag_cls_bare) != 0 or self.Gen.ClassGenEnum._is_renum_class_name(renum_name) != 0 or self.Gen.ClassGenEnum._is_renum_by_entry(tag_cls_bare) != 0 or self.Gen.ClassGenEnum._is_renum_by_entry(renum_name) != 0): # 走到这里 ⇒ 分派判定为 REnum match(同一组判据至少一条为真),而 # MatchClass 却拿不到可用的 struct entry/类型:此前**静默跳过**绑定 # ⇒ 绑定名在 body 里未定义,最终报 NameError(__types.vp `bits`), @@ -668,12 +644,7 @@ novirtual class MatchGenMixin: ent_fc = renum_entry.FieldCount ty_present: int = 0 if renum_ty is not None: ty_present = 1 - self.Gen.TypeGenErr.fatal_error(pat, - f"REnum match 变体字段绑定失败:class='{tag_cls_bare}'(查表名='{renum_name}')" - f" entry='{ent_nm}' FieldCount={ent_fc} ty_present={ty_present};" - f"变体表已登记该类,说明结构体条目或 Ty 缺失(已不再静默跳过绑定," - f"否则绑定名未定义只会在下游报 NameError)", - "InternalCompilerError") + self.Gen.TypeGenErr.fatal_error(pat, f"REnum match 变体字段绑定失败:class='{tag_cls_bare}'(查表名='{renum_name}')" f" entry='{ent_nm}' FieldCount={ent_fc} ty_present={ty_present};" f"变体表已登记该类,说明结构体条目或 Ty 缺失(已不再静默跳过绑定," f"否则绑定名未定义只会在下游报 NameError)", "InternalCompilerError") # 翻译 case body body_list: list[ast.AST*]* = mc.children @@ -763,14 +734,7 @@ novirtual class MatchGenMixin: # # case LLVMType.Ptr(pointee) 中的 pointee 绑定到 subject 的 payload 字段 # ============================================================ - def _bind_variant_fields(self, pat: ast.AST*, - renum_name: str, - renum_entry: GenTypes.StructEntry*, - renum_ty: mlirlite.LLVMType*, - subject_ptr: mlirlite.Value*, - trans: HT.Translator*, - pool: memhub.MemBuddy*, - builder: mlirlite.IRBuilder*): + def _bind_variant_fields(self, pat: ast.AST*, renum_name: str, renum_entry: GenTypes.StructEntry*, renum_ty: mlirlite.LLVMType*, subject_ptr: mlirlite.Value*, trans: HT.Translator*, pool: memhub.MemBuddy*, builder: mlirlite.IRBuilder*): if pat is None or renum_entry is None or renum_ty is None: return mc: rawptr[ast.MatchClass] = rawptr[ast.MatchClass](pat) pats: list[ast.AST*]* = mc.patterns @@ -837,10 +801,7 @@ novirtual class MatchGenMixin: # 对齐 lhs/rhs(指针统一 ptrtoint i64,整数位宽统一到较宽者)后 # 生成 icmp eq,返回 i1 条件。 # ============================================================ - def _seq_cmp_eq(self, trans: HT.Translator*, - builder: mlirlite.IRBuilder*, - lhs: mlirlite.Value*, - rhs: mlirlite.Value*) -> mlirlite.Value*: + def _seq_cmp_eq(self, trans: HT.Translator*, builder: mlirlite.IRBuilder*, lhs: mlirlite.Value*, rhs: mlirlite.Value*) -> mlirlite.Value*: """对齐 lhs/rhs 后生成 icmp eq(指针统一 ptrtoint i64)""" if lhs is None or rhs is None or builder is None: return None pool: memhub.MemBuddy* = trans.Pool @@ -874,9 +835,7 @@ novirtual class MatchGenMixin: # body_i: → end(c.NoBreak 时 fallthrough 到下一 case body) # 全不匹配 → default → end # ============================================================ - def _handle_sequence_match(self, trans: HT.Translator*, - node: ast.Match*, - subject_node: ast.AST*) -> int: + def _handle_sequence_match(self, trans: HT.Translator*, node: ast.Match*, subject_node: ast.AST*) -> int: pool: memhub.MemBuddy* = trans.Pool builder: mlirlite.IRBuilder* = trans._cur_builder func: mlirlite.Function* = trans._cur_func @@ -903,8 +862,7 @@ novirtual class MatchGenMixin: # 用内联别名接收者规避(对齐 Converter arg_defaults 内联模式) elts_inl: list[ast.AST*]* = elts elt: ast.AST* = elts_inl.get(ei) - sv: mlirlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, trans.Module, elt, - trans._funcs, trans._func_count, trans) + sv: mlirlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, trans.Module, elt, trans._funcs, trans._func_count, trans) if sv is None: self.Gen.TypeGenErr.fatal_error(elt, f"match 序列元素 {ei} 翻译失败", "TypeError") subj_vals[ei] = sizet(sv) @@ -959,9 +917,7 @@ novirtual class MatchGenMixin: # `_` 一律当 default(恒真)处理,会**静默忽略 guard**。禁止 # 静默兜底 → 在任何 IR 产出之前 fail-fast。 if mc.guard is not None: - self.Gen.TypeGenErr.fatal_error(pat, - "序列匹配的顶层 `case _ if ` 暂不支持 guard 守卫", - "NotImplementedError") + self.Gen.TypeGenErr.fatal_error(pat, "序列匹配的顶层 `case _ if ` 暂不支持 guard 守卫", "NotImplementedError") is_def = 1 elif pk != ast.ASTKind.MatchSequence: # fail-fast:序列匹配只接受 MatchSequence / 顶层 _ 通配 @@ -1048,8 +1004,7 @@ novirtual class MatchGenMixin: g_addr: sizet = guard_arr[ci] if g_addr != 0: gnode: ast.AST* = (ast.AST*)(g_addr) - gv: mlirlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, trans.Module, gnode, - trans._funcs, trans._func_count, trans) + gv: mlirlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, trans.Module, gnode, trans._funcs, trans._func_count, trans) if gv is None: self.Gen.TypeGenErr.fatal_error(gnode, "match guard 翻译失败", "TypeError") gbits: int = self.Gen.ExprGenBase.get_llvm_type_bits(gv.Ty) if gbits == 1: g1: mlirlite.Value* = gv @@ -1157,9 +1112,7 @@ novirtual class MatchGenMixin: # # subject ptrtoint 到 i32 + switch 分派 # ============================================================ - def _handle_simple_match(self, trans: HT.Translator*, - node: ast.Match*, - subject_val: mlirlite.Value*) -> int: + def _handle_simple_match(self, trans: HT.Translator*, node: ast.Match*, subject_val: mlirlite.Value*) -> int: pool: memhub.MemBuddy* = trans.Pool builder: mlirlite.IRBuilder* = trans._cur_builder func: mlirlite.Function* = trans._cur_func @@ -1264,8 +1217,7 @@ novirtual class MatchGenMixin: pk: int = pat.kind() if pk == ast.ASTKind.MatchValue: mv: rawptr[ast.MatchValue] = rawptr[ast.MatchValue](pat) - cv = self.Gen.ExprGen.translate_value(builder, pool, trans.Module, mv.value, - trans._funcs, trans._func_count, trans) + cv = self.Gen.ExprGen.translate_value(builder, pool, trans.Module, mv.value, trans._funcs, trans._func_count, trans) elif pk == ast.ASTKind.MatchSingleton: ms: rawptr[ast.MatchSingleton] = (rawptr[ast.MatchSingleton])(pat) # None -> 0 @@ -1286,9 +1238,7 @@ novirtual class MatchGenMixin: # 分派失配,必须 fail-fast 暴露,不得静默丢 case(禁止兜底掩盖)。 rnm_nr: str = self._extract_renum_name_from_cls(pat) if rnm_nr is not None and (self.Gen.ClassGenEnum._is_renum_class_name(rnm_nr) != 0 or self.Gen.ClassGenEnum._is_renum_by_entry(rnm_nr) != 0): - self.Gen.TypeGenErr.fatal_error(pat, - f"非 REnum 路径收到 REnum 变体模式 'case {rnm_nr}.*':case 值无法产出,该臂会被静默丢弃(REnum 分派失配)", - "InternalCompilerError") + self.Gen.TypeGenErr.fatal_error(pat, f"非 REnum 路径收到 REnum 变体模式 'case {rnm_nr}.*':case 值无法产出,该臂会被静默丢弃(REnum 分派失配)", "InternalCompilerError") if is_def == 0: if collected >= MAX_MATCH_CASES: break @@ -1326,8 +1276,7 @@ novirtual class MatchGenMixin: alt_cv: mlirlite.Value* = None if alt_pat.kind() == ast.ASTKind.MatchValue: alt_mv: rawptr[ast.MatchValue] = (rawptr[ast.MatchValue])(alt_pat) - alt_cv = self.Gen.ExprGen.translate_value(builder, pool, trans.Module, alt_mv.value, - trans._funcs, trans._func_count, trans) + alt_cv = self.Gen.ExprGen.translate_value(builder, pool, trans.Module, alt_mv.value, trans._funcs, trans._func_count, trans) elif alt_pat.kind() == ast.ASTKind.MatchSingleton: # None -> 0(与单值/守卫路径同口径) alt_cv = mlirlite.const_int32(pool, 0) @@ -1478,9 +1427,7 @@ novirtual class MatchGenMixin: # 注意:**无 guard** 的 match/switch 不会进入本函数(见 _handle_simple_match # 的 has_guard 预扫描),既有 switch 分派路径逐字不变。 # ============================================================ - def _handle_guarded_simple_match(self, trans: HT.Translator*, - node: ast.Match*, - subj_val: mlirlite.Value*) -> int: + def _handle_guarded_simple_match(self, trans: HT.Translator*, node: ast.Match*, subj_val: mlirlite.Value*) -> int: pool: memhub.MemBuddy* = trans.Pool builder: mlirlite.IRBuilder* = trans._cur_builder func: mlirlite.Function* = trans._cur_func @@ -1542,8 +1489,7 @@ novirtual class MatchGenMixin: pk: int = pat.kind() if pk == ast.ASTKind.MatchValue: mv: rawptr[ast.MatchValue] = rawptr[ast.MatchValue](pat) - cv = self.Gen.ExprGen.translate_value(builder, pool, trans.Module, mv.value, - trans._funcs, trans._func_count, trans) + cv = self.Gen.ExprGen.translate_value(builder, pool, trans.Module, mv.value, trans._funcs, trans._func_count, trans) elif pk == ast.ASTKind.MatchSingleton: # None -> 0 cv = mlirlite.const_int32(pool, 0) @@ -1619,8 +1565,7 @@ novirtual class MatchGenMixin: alt_cv2: mlirlite.Value* = None if alt_pat2.kind() == ast.ASTKind.MatchValue: alt_mv2: rawptr[ast.MatchValue] = (rawptr[ast.MatchValue])(alt_pat2) - alt_cv2 = self.Gen.ExprGen.translate_value(builder, pool, trans.Module, alt_mv2.value, - trans._funcs, trans._func_count, trans) + alt_cv2 = self.Gen.ExprGen.translate_value(builder, pool, trans.Module, alt_mv2.value, trans._funcs, trans._func_count, trans) elif alt_pat2.kind() == ast.ASTKind.MatchSingleton: # None -> 0(与单值路径同口径) alt_cv2 = mlirlite.const_int32(pool, 0) @@ -1641,8 +1586,7 @@ novirtual class MatchGenMixin: g_addr: sizet = sizet(mc2.guard) if g_addr != 0: gnode: ast.AST* = (ast.AST*)(g_addr) - gv: mlirlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, trans.Module, gnode, - trans._funcs, trans._func_count, trans) + gv: mlirlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, trans.Module, gnode, trans._funcs, trans._func_count, trans) if gv is None: self.Gen.TypeGenErr.fatal_error(gnode, "match guard 翻译失败", "TypeError") gbits: int = self.Gen.ExprGenBase.get_llvm_type_bits(gv.Ty) if gbits == 1: g1: mlirlite.Value* = gv diff --git a/App/lib/core/Gen/Stmt/StmtGenCifMixin.vp b/App/lib/core/Gen/Stmt/StmtGenCifMixin.vp index 6131671..f9eebf0 100644 --- a/App/lib/core/Gen/Stmt/StmtGenCifMixin.vp +++ b/App/lib/core/Gen/Stmt/StmtGenCifMixin.vp @@ -102,9 +102,7 @@ novirtual class StmtGenCifMixin: if string.strcmp(name, "NDEBUG") == 0: self.CifEvalOk = 1; return 0 return 0 - def _cif_name_value(self, pool: memhub.MemBuddy*, - trans: HT.Translator*, - name: str) -> int: + def _cif_name_value(self, pool: memhub.MemBuddy*, trans: HT.Translator*, name: str) -> int: """查宏名值: 本地 CDefine → 跨模块 CDefine → 平台宏。 命中置 self.CifEvalOk=1(值 0 也算命中,如 DISABLED=0);未命中置 0。 @@ -123,9 +121,7 @@ novirtual class StmtGenCifMixin: if self.CifEvalOk != 0: return pv return 0 - def _cif_attr_value(self, pool: memhub.MemBuddy*, - trans: HT.Translator*, - at: ast.Attribute*) -> int: + def _cif_attr_value(self, pool: memhub.MemBuddy*, trans: HT.Translator*, at: ast.Attribute*) -> int: """Attribute 宏值: platmacro.IS_WINDOWS → 本地 CDefine(attr) → 跨模块 CDefine。 命中置 self.CifEvalOk=1;未命中置 0。 @@ -161,9 +157,7 @@ novirtual class StmtGenCifMixin: return v2 return 0 - def _cif_eval_node(self, pool: memhub.MemBuddy*, - trans: HT.Translator*, - node: ast.AST*) -> int: + def _cif_eval_node(self, pool: memhub.MemBuddy*, trans: HT.Translator*, node: ast.AST*) -> int: """递归常量求值 CIf 表达式。 支持: Constant(int) / Name(CDefine/跨模块/平台宏) / Attribute(跨模块 CDefine) @@ -289,8 +283,7 @@ novirtual class StmtGenCifMixin: self.CifEvalOk = 0 return 0 - def _eval_ctraits_isptr(self, symtab: rawptr[GenTypes.SymbolTable], - name: str) -> int: + def _eval_ctraits_isptr(self, symtab: rawptr[GenTypes.SymbolTable], name: str) -> int: """ctraits.isptr(name) 编译期求值。 按变量实际存储类型判断是否指针:alloca 的 pointee 为 Ptr 即指针 @@ -304,9 +297,7 @@ novirtual class StmtGenCifMixin: if pointee is not None and self.Gen.ExprGenBase.is_ptr_type(pointee) != 0: return 1 return 0 - def _cif_eval_call(self, pool: memhub.MemBuddy*, - trans: HT.Translator*, - node: ast.AST*) -> int: + def _cif_eval_call(self, pool: memhub.MemBuddy*, trans: HT.Translator*, node: ast.AST*) -> int: """编译期函数调用求值:ctraits.isptr(x)。 命中置 self.CifEvalOk=1 返回 1/0;未识别调用置 0 返回 0。 @@ -342,9 +333,7 @@ novirtual class StmtGenCifMixin: self.CifEvalOk = 1 return r - def _evaluate_cif_test(self, pool: memhub.MemBuddy*, - trans: HT.Translator*, - test: ast.AST*) -> int: + def _evaluate_cif_test(self, pool: memhub.MemBuddy*, trans: HT.Translator*, test: ast.AST*) -> int: """求值 CIf 调用(test 必须是 c.CIf 系调用)。 成功: 置 self.CifEvalOk=1,返回条件值(0/1) @@ -399,8 +388,7 @@ novirtual class StmtGenCifMixin: # 翻译返回值(若有)并生成 ret 指令;裸 return 按函数返回类型生成 # 默认零值(void→ret void,ptr→null,float→0.0,其余→零值)。 # ============================================================ - def translate_return(self, trans: HT.Translator*, - node: ast.AST*) -> int: + def translate_return(self, trans: HT.Translator*, node: ast.AST*) -> int: """翻译 Return 语句""" rt: rawptr[ast.Return] = rawptr[ast.Return](node) if rt is None: return 0 @@ -430,8 +418,7 @@ novirtual class StmtGenCifMixin: rt_tail: mlirlite.ParamNode* = None rvi: sizet for rvi in range(rt_n): - ev_i: mlirlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, mod, rtp_elts.get(rvi), - trans._funcs, trans._func_count, trans) + ev_i: mlirlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, mod, rtp_elts.get(rvi), trans._funcs, trans._func_count, trans) if ev_i is None: rt_val_ok = 0 break @@ -494,8 +481,7 @@ novirtual class StmtGenCifMixin: # 构造(`-> Stack[int]` 里 `return Stack()`)用 CurFuncRetAnnot # 里的类型实参特化;仅该直接值生效(identity 判定在 CallGenCtor)。 trans.CurRetNode = rt.value - val = self.Gen.ExprGen.translate_value(builder, pool, mod, rt.value, - trans._funcs, trans._func_count, trans, ret_val_ty, "返回注解") + val = self.Gen.ExprGen.translate_value(builder, pool, mod, rt.value, trans._funcs, trans._func_count, trans, ret_val_ty, "返回注解") trans.CurRetNode = None # val 为 None 时(裸 return):检查当前函数返回类型 @@ -630,8 +616,7 @@ novirtual class StmtGenCifMixin: # br label %end # end: # ============================================================ - def translate_if(self, trans: HT.Translator*, - node: ast.AST*) -> int: + def translate_if(self, trans: HT.Translator*, node: ast.AST*) -> int: """翻译 if/elif/else 语句""" if node is None: return 0 @@ -674,8 +659,7 @@ novirtual class StmtGenCifMixin: return 0 # 1. 求值条件表达式 - cond_val: mlirlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, trans.Module, if_node.test, - trans._funcs, trans._func_count, trans) + cond_val: mlirlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, trans.Module, if_node.test, trans._funcs, trans._func_count, trans) # 2. 转换为 i1 条件(优先调度 __bool__;Compare/Not 已返回 i1) if cond_val is None: @@ -778,20 +762,14 @@ novirtual class StmtGenCifMixin: if len(orelse_list) > 0: return 1 return 0 - def _MakeLoopElseBlock(self, pool: memhub.MemBuddy*, - func: mlirlite.Function*, - name_buf: str, kind: str, cnt: int, - has_else: int) -> rawptr[mlirlite.BasicBlock]: + def _MakeLoopElseBlock(self, pool: memhub.MemBuddy*, func: mlirlite.Function*, name_buf: str, kind: str, cnt: int, has_else: int) -> rawptr[mlirlite.BasicBlock]: """has_else=0 返回 None;否则 snprintf(name_buf,32,"%s.else.%d",kind,cnt) 并 create_block""" if has_else == 0: return None if func is None: return None viperlib.snprintf(name_buf, 32, "%s.else.%d", kind, cnt) return mlirlite.create_block(pool, func, name_buf) - def _EmitLoopElse(self, trans: HT.Translator*, - orelse_list: list[ast.AST*]*, - else_bb: rawptr[mlirlite.BasicBlock], - end_bb: rawptr[mlirlite.BasicBlock]) -> int: + def _EmitLoopElse(self, trans: HT.Translator*, orelse_list: list[ast.AST*]*, else_bb: rawptr[mlirlite.BasicBlock], end_bb: rawptr[mlirlite.BasicBlock]) -> int: """else_bb 非空:position_at_end(else_bb) → 逐条 translate_stmt(orelse) → 若当前块未终止则 build_br(end_bb) 并返回 1;否则返回 0。 else_bb 为空:直接返回 0(调用方自己 position_at_end(end_bb))。 @@ -826,8 +804,7 @@ novirtual class StmtGenCifMixin: # br label %cond # end: # ============================================================ - def translate_while(self, trans: HT.Translator*, - node: ast.AST*) -> int: + def translate_while(self, trans: HT.Translator*, node: ast.AST*) -> int: """翻译 while 循环语句""" if node is None: return 0 @@ -862,8 +839,7 @@ novirtual class StmtGenCifMixin: # 3. cond 块: 求值条件,条件分支 mlirlite.position_at_end(builder, cond_bb) - cond_val: mlirlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, trans.Module, while_node.test, - trans._funcs, trans._func_count, trans) + cond_val: mlirlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, trans.Module, while_node.test, trans._funcs, trans._func_count, trans) if cond_val is None: # fail-fast: while 条件表达式翻译失败 self.Gen.TypeGenErr.fatal_error(while_node.test, "while 条件表达式翻译失败", "TypeError") @@ -975,8 +951,7 @@ novirtual class StmtGenCifMixin: # br label %cond # end: # ============================================================ - def translate_for(self, trans: HT.Translator*, - node: ast.AST*) -> int: + def translate_for(self, trans: HT.Translator*, node: ast.AST*) -> int: """翻译 for i in range(...) 循环语句""" if node is None: return 0 @@ -1058,8 +1033,7 @@ novirtual class StmtGenCifMixin: # [S4] 容器基名精确比较(SpecTypeNameBaseIs):原 strstr("dict") 子串匹配 # 会误命中任何含 "dict" 的类名(如 MyDictHelper)。 if TSpec.SpecTypeNameBaseIs(lst_annot, "dict") != 0: - lst_val: mlirlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, trans.Module, iter_node, - trans._funcs, trans._func_count, trans) + lst_val: mlirlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, trans.Module, iter_node, trans._funcs, trans._func_count, trans) if lst_val is not None and lst_val.Ty is not None and self.Gen.ExprGenBase.is_ptr_type(lst_val.Ty) != 0: return self._handle_dict_iter(trans, for_node, var_name, lst_val) # [S4] 同上:原 strstr("list") 会误命中 playlist / GSList 等; # 非 list 基名的用户类改由下方 OOP __iter__/__next__ 路径处理(更正确)。 @@ -1069,8 +1043,7 @@ novirtual class StmtGenCifMixin: # OOP iter 协议:迭代源是类对象且类有 __iter__/__next__ 方法 → # 走 __iter__/__next__ 调用迭代(对齐 TPC HandlesFor.py L142-166 # _HandleForIterLlvm)。dict/list 是内置泛型容器已在上方内联处理。 - ov_val: mlirlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, trans.Module, iter_node, - trans._funcs, trans._func_count, trans) + ov_val: mlirlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, trans.Module, iter_node, trans._funcs, trans._func_count, trans) if ov_val is not None and ov_val.Ty is not None and self.Gen.ExprGenBase.is_ptr_type(ov_val.Ty) != 0: ov_st: mlirlite.LLVMType* = self.Gen.StructGen.get_struct_type_from_value(ov_val) if ov_st is not None: @@ -1348,8 +1321,7 @@ novirtual class StmtGenCifMixin: # enumerate(x) → for i, v in enumerate(x):i 为序号,v 为元素 # zip(a, b) → for x, y in zip(a, b):任一源耗尽即终止 # ============================================================ - def _extract_tuple_names(self, tup: ast.Tuple*, - out1: str, out2: str) -> int: + def _extract_tuple_names(self, tup: ast.Tuple*, out1: str, out2: str) -> int: """从 Tuple target 提取前两个 Name 变量名,写入 out1/out2,成功返回 1""" if tup is None or tup.elts is None or out1 is None or out2 is None: return 0 elts: list[ast.AST*]* = tup.elts @@ -1366,8 +1338,7 @@ novirtual class StmtGenCifMixin: string.strcpy(out2, n1.id) return 1 - def _seq_kind(self, trans: HT.Translator*, - src: ast.AST*) -> int: + def _seq_kind(self, trans: HT.Translator*, src: ast.AST*) -> int: """判断迭代源类型: SEQ_KIND_RANGE / STR / LIST,不支持返回 0""" if src is None: return 0 k: int = src.kind() @@ -1391,12 +1362,7 @@ novirtual class StmtGenCifMixin: return GenTypes.SEQ_KIND_STR return 0 - def _build_seq_loop(self, trans: HT.Translator*, - for_node: ast.For*, - t1: str, t2: str, - src1: ast.AST*, - src2: ast.AST*, - n_srcs: int) -> int: + def _build_seq_loop(self, trans: HT.Translator*, for_node: ast.For*, t1: str, t2: str, src1: ast.AST*, src2: ast.AST*, n_srcs: int) -> int: """生成序列迭代循环(enumerate: n_srcs=1 / zip: n_srcs=2) 循环变量 alloca 自动创建或复用;元素类型由源类型决定 @@ -1433,8 +1399,7 @@ novirtual class StmtGenCifMixin: if cargs1 is not None: n1: sizet = len(cargs1) if n1 >= 1: - sv: mlirlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, trans.Module, cargs1.get(0), - trans._funcs, trans._func_count, trans) + sv: mlirlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, trans.Module, cargs1.get(0), trans._funcs, trans._func_count, trans) if sv is None: # fail-fast: range 参数翻译失败 self.Gen.TypeGenErr.fatal_error(cargs1.get(0), "range 参数翻译失败", "TypeError") @@ -1685,9 +1650,7 @@ novirtual class StmtGenCifMixin: # br label %cond # end: # ============================================================ - def _handle_ptr_iter(self, trans: HT.Translator*, - for_node: ast.For*, - var_name: str) -> int: + def _handle_ptr_iter(self, trans: HT.Translator*, for_node: ast.For*, var_name: str) -> int: """指针迭代: for x in ptr: 直到解引用为空""" pool: memhub.MemBuddy* = trans.Pool builder: mlirlite.IRBuilder* = trans._cur_builder @@ -1838,10 +1801,7 @@ novirtual class StmtGenCifMixin: # %n = add i32 %i, 1 ; store %n ; br %cond # end: # ============================================================ - def _handle_array_iter(self, trans: HT.Translator*, - for_node: ast.For*, - var_name: str, - array_val: mlirlite.Value*) -> int: + def _handle_array_iter(self, trans: HT.Translator*, for_node: ast.For*, var_name: str, array_val: mlirlite.Value*) -> int: """数组迭代: for x in arr: 按数组长度迭代""" pool: memhub.MemBuddy* = trans.Pool builder: mlirlite.IRBuilder* = trans._cur_builder @@ -1975,10 +1935,7 @@ novirtual class StmtGenCifMixin: # # 元素类型取第一个元素的值类型,其余元素 coerce 到该类型。 # ============================================================ - def _handle_list_literal_iter(self, trans: HT.Translator*, - for_node: ast.For*, - var_name: str, - list_node: ast.AST*) -> int: + def _handle_list_literal_iter(self, trans: HT.Translator*, for_node: ast.For*, var_name: str, list_node: ast.AST*) -> int: """列表字面量迭代: for x in [a, b, c]: 按元素顺序迭代""" pool: memhub.MemBuddy* = trans.Pool builder: mlirlite.IRBuilder* = trans._cur_builder @@ -1997,21 +1954,13 @@ novirtual class StmtGenCifMixin: # 列表元素计数 > 实际填充 ⇒ 该槽为裸 0 ⇒ 上层某处产生了空 AST 元素。 # 不给下游 translate_value 的守卫吞掉(那会静默跳过 store、产出错值),此处响亮失败。 if first_el is None: - self.Gen.TypeGenErr.fatal_error(for_node, - f"列表字面量迭代遇到空 AST 元素:第 0 个元素为裸空指针(0)," - f"但元素计数为 {elts_count}(元素与计数不一致);上层某处产生了空 AST 元素,已终止编译。", - "ValueError") + self.Gen.TypeGenErr.fatal_error(for_node, f"列表字面量迭代遇到空 AST 元素:第 0 个元素为裸空指针(0)," f"但元素计数为 {elts_count}(元素与计数不一致);上层某处产生了空 AST 元素,已终止编译。", "ValueError") # 对象有效性校验(vptr 非 0,硬约定与证据见 AssignGenMixin.vp:1174-1183): # @t.CVTable 类对象首字即 vptr,为 0 时下游任意虚调用(kind()/dump())都会 # `load [0+slot]` ⇒ ASan READ at 0x0。读首字的唯一可用写法是 c.Deref((uint64*)(p))。 if *((uint64*)(first_el)) == 0: - self.Gen.TypeGenErr.fatal_error(for_node, - f"列表字面量迭代遇到【对象无效】的 AST 元素(vptr 为 0):第 0 个元素指针非 0" - f"(地址 {uint64(first_el)})但其对象首字(vtable 指针)为 0,元素计数 {elts_count};" - f"上层某处产生了「未初始化 vptr 的 AST 节点」(典型源:深拷贝只搬字段未搬 vptr),已终止编译。", - "ValueError") - first_val: mlirlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, trans.Module, first_el, - trans._funcs, trans._func_count, trans) + self.Gen.TypeGenErr.fatal_error(for_node, f"列表字面量迭代遇到【对象无效】的 AST 元素(vptr 为 0):第 0 个元素指针非 0" f"(地址 {uint64(first_el)})但其对象首字(vtable 指针)为 0,元素计数 {elts_count};" f"上层某处产生了「未初始化 vptr 的 AST 节点」(典型源:深拷贝只搬字段未搬 vptr),已终止编译。", "ValueError") + first_val: mlirlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, trans.Module, first_el, trans._funcs, trans._func_count, trans) if first_val is None or first_val.Ty is None: self.Gen.TypeGenErr.fatal_error(first_el, "列表字面量迭代: 无法确定元素类型") elem_ty: mlirlite.LLVMType* = first_val.Ty @@ -2028,17 +1977,10 @@ novirtual class StmtGenCifMixin: el_node: ast.AST* = elts.get(i) # 显式判空(同上,用 `is None`):不得让空元素被 translate_value 的 None 守卫静默吞掉。 if el_node is None: - self.Gen.TypeGenErr.fatal_error(for_node, - f"列表字面量迭代遇到空 AST 元素:第 {i} 个元素为裸空指针(0)," - f"但元素计数为 {elts_count}(元素与计数不一致);上层某处产生了空 AST 元素,已终止编译。", - "ValueError") + self.Gen.TypeGenErr.fatal_error(for_node, f"列表字面量迭代遇到空 AST 元素:第 {i} 个元素为裸空指针(0)," f"但元素计数为 {elts_count}(元素与计数不一致);上层某处产生了空 AST 元素,已终止编译。", "ValueError") # 对象有效性校验(vptr 非 0),同第 0 元素处:同族"取元素后即用"路径。 if *((uint64*)(el_node)) == 0: - self.Gen.TypeGenErr.fatal_error(for_node, - f"列表字面量迭代遇到【对象无效】的 AST 元素(vptr 为 0):第 {i} 个元素指针非 0" - f"(地址 {uint64(el_node)})但其对象首字(vtable 指针)为 0,元素计数 {elts_count};" - f"上层某处产生了「未初始化 vptr 的 AST 节点」(典型源:深拷贝只搬字段未搬 vptr),已终止编译。", - "ValueError") + self.Gen.TypeGenErr.fatal_error(for_node, f"列表字面量迭代遇到【对象无效】的 AST 元素(vptr 为 0):第 {i} 个元素指针非 0" f"(地址 {uint64(el_node)})但其对象首字(vtable 指针)为 0,元素计数 {elts_count};" f"上层某处产生了「未初始化 vptr 的 AST 节点」(典型源:深拷贝只搬字段未搬 vptr),已终止编译。", "ValueError") el_val: mlirlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, trans.Module, el_node, trans._funcs, trans._func_count, trans) if el_val is not None: el_val = self.Gen.ExprGenBase.coerce_to_type(builder, el_val, elem_ty, el_node) @@ -2079,10 +2021,7 @@ novirtual class StmtGenCifMixin: # %n = add i64 %i, 1 ; store ; br %cond # end: # ============================================================ - def _handle_list_iter(self, trans: HT.Translator*, - for_node: ast.For*, - var_name: str, - list_val: mlirlite.Value*) -> int: + def _handle_list_iter(self, trans: HT.Translator*, for_node: ast.For*, var_name: str, list_val: mlirlite.Value*) -> int: """list[T] 容器迭代: for v in lst: 按 __count__ 动态长度迭代""" pool: memhub.MemBuddy* = trans.Pool builder: mlirlite.IRBuilder* = trans._cur_builder @@ -2180,10 +2119,7 @@ novirtual class StmtGenCifMixin: trans._ctrl_merge_reachable = 1 return new_vars - def _handle_dict_iter(self, trans: HT.Translator*, - for_node: ast.For*, - var_name: str, - dict_val: mlirlite.Value*) -> int: + def _handle_dict_iter(self, trans: HT.Translator*, for_node: ast.For*, var_name: str, dict_val: mlirlite.Value*) -> int: """dict 容器迭代: for key in d: 按 __count__/__keys__ 布局迭代 _dict.vp 布局(8 字节槽):__keys__@0, __values__@1, __count__@2, @@ -2312,11 +2248,7 @@ novirtual class StmtGenCifMixin: # _translate_method 注入,raise StopIteration 时置 1(translate_raise); # VpiReader stub 声明同步该参数(_inject_method_declare)。 # ============================================================ - def _handle_oop_iter(self, trans: HT.Translator*, - for_node: ast.For*, - var_name: str, - class_name: str, - obj_val: mlirlite.Value*) -> int: + def _handle_oop_iter(self, trans: HT.Translator*, for_node: ast.For*, var_name: str, class_name: str, obj_val: mlirlite.Value*) -> int: """OOP iter 协议: for x in obj: 调用 __iter__/__next__ 迭代""" pool: memhub.MemBuddy* = trans.Pool builder: mlirlite.IRBuilder* = trans._cur_builder @@ -2441,20 +2373,14 @@ novirtual class StmtGenCifMixin: trans._ctrl_merge_reachable = 1 return new_vars - def _handle_enumerate_iter(self, trans: HT.Translator*, - for_node: ast.For*, - t1: str, t2: str, - call: ast.Call*) -> int: + def _handle_enumerate_iter(self, trans: HT.Translator*, for_node: ast.For*, t1: str, t2: str, call: ast.Call*) -> int: """enumerate 迭代: for i, v in enumerate(x)""" if call is None or call.args is None: return 0 cargs: list[ast.AST*]* = call.args if len(cargs) < 1: self.Gen.TypeGenErr.fatal_error(for_node, "enumerate 需要至少一个参数") return self._build_seq_loop(trans, for_node, t1, t2, cargs.get(0), None, 1) - def _handle_zip_iter(self, trans: HT.Translator*, - for_node: ast.For*, - t1: str, t2: str, - call: ast.Call*) -> int: + def _handle_zip_iter(self, trans: HT.Translator*, for_node: ast.For*, t1: str, t2: str, call: ast.Call*) -> int: """zip 迭代: for a, b in zip(x, y)""" if call is None or call.args is None: # fail-fast: zip 参数缺失 diff --git a/App/lib/core/Gen/Stmt/StmtGenDeclMixin.vp b/App/lib/core/Gen/Stmt/StmtGenDeclMixin.vp index fa5802d..58e03f4 100644 --- a/App/lib/core/Gen/Stmt/StmtGenDeclMixin.vp +++ b/App/lib/core/Gen/Stmt/StmtGenDeclMixin.vp @@ -33,8 +33,7 @@ define ENUM_MEMBER_MAX = 128 novirtual class StmtGenDeclMixin(StmtGenCifMixin.StmtGenCifMixin): """声明/枚举/nonlocal 访问(StmtGen 拆分 2/3,继承 Cif)""" - def translate_global(self, trans: HT.Translator*, - node: ast.AST*) -> int: + def translate_global(self, trans: HT.Translator*, node: ast.AST*) -> int: """翻译 global 语句:记录 global 变量名""" gn: rawptr[ast.Global] = rawptr[ast.Global](node) if gn is None: return 0 @@ -48,8 +47,7 @@ novirtual class StmtGenDeclMixin(StmtGenCifMixin.StmtGenCifMixin): if nm.id is not None: GenApi.add_global_name(trans, nm.id) return 0 - def translate_nonlocal(self, trans: HT.Translator*, - node: ast.AST*) -> int: + def translate_nonlocal(self, trans: HT.Translator*, node: ast.AST*) -> int: """翻译 nonlocal 语句:记录 nonlocal 变量名及其类型 类型信息通过查找父作用域的 alloca 获取(用于 env 指针数组方案的类型恢复)。 @@ -81,8 +79,7 @@ novirtual class StmtGenDeclMixin(StmtGenCifMixin.StmtGenCifMixin): GenApi.add_nonlocal_name(trans, nm.id, var_ty) return 0 - def translate_expr_stmt(self, trans: HT.Translator*, - node: ast.AST*) -> int: + def translate_expr_stmt(self, trans: HT.Translator*, node: ast.AST*) -> int: """翻译表达式语句(printf 调用等)""" ex: rawptr[ast.Expr] = rawptr[ast.Expr](node) if ex is None: return 0 @@ -122,19 +119,16 @@ novirtual class StmtGenDeclMixin(StmtGenCifMixin.StmtGenCifMixin): if trans is not None and trans.ReplCtx is not None and func_node.kind() == ast.ASTKind.Name and self.Gen.VarGen.repl_in_frag_scope(trans.SymTab) != 0: sfn_ent: rawptr[GenTypes.ReplFuncEntry] = self.Gen.VarGen.repl_find_func_entry(trans.ReplCtx, func_name) if sfn_ent is not None and sfn_ent.RetTag != GenTypes.REPL_TY_VOID: - sfn_v: mlirlite.Value* = self.Gen.CallGen.translate_call(trans.Pool, trans._cur_builder, trans.Module, call_node, - trans._funcs, trans._func_count, trans) + sfn_v: mlirlite.Value* = self.Gen.CallGen.translate_call(trans.Pool, trans._cur_builder, trans.Module, call_node, trans._funcs, trans._func_count, trans) if sfn_v is not None: ctx_v: mlirlite.Value* = self.Gen.VarGen.repl_ctx_ptr(trans, trans.ReplCtx, call_node) if ctx_v is not None: - self.Gen.VarGen.repl_emit_result(trans, ctx_v, sfn_v, sfn_ent.RetTag, sfn_ent.RetBits, - call_node) + self.Gen.VarGen.repl_emit_result(trans, ctx_v, sfn_v, sfn_ent.RetTag, sfn_ent.RetBits, call_node) return 0 self.Gen.CallGen.translate_call(trans.Pool, trans._cur_builder, trans.Module, call_node, trans._funcs, trans._func_count, trans) return 0 - def pre_scan_allocas(self, trans: HT.Translator*, - node: ast.AST*) -> int: + def pre_scan_allocas(self, trans: HT.Translator*, node: ast.AST*) -> int: """预扫描语句中的 AnnAssign,提前创建 alloca 递归分支/循环/异常体:if/else/for/while/try 分支内的 AnnAssign 局部 @@ -216,8 +210,7 @@ novirtual class StmtGenDeclMixin(StmtGenCifMixin.StmtGenCifMixin): return 0 return 0 - def pre_scan_scope_decls(self, trans: HT.Translator*, - node: ast.AST*) -> int: + def pre_scan_scope_decls(self, trans: HT.Translator*, node: ast.AST*) -> int: """预扫描 Global/Nonlocal 声明,提前注册作用域名称""" if node is None: return 0 k: int = node.kind() @@ -236,8 +229,7 @@ novirtual class StmtGenDeclMixin(StmtGenCifMixin.StmtGenCifMixin): # 发射 br 到 break 目标(_break_bb 由循环 / switch / match 的 case 生成侧设置) if trans._break_bb is None: # fail-fast:没有循环 / switch / match 时 break 无处可跳,禁止静默无效果 - self.Gen.TypeGenErr.fatal_error(node, - "break 只能用在循环或 switch/match 的 case 体内(当前没有可跳出的目标)", "SyntaxError") + self.Gen.TypeGenErr.fatal_error(node, "break 只能用在循环或 switch/match 的 case 体内(当前没有可跳出的目标)", "SyntaxError") if mlirlite.builder_cur_block_is_terminated(builder) == 0: mlirlite.build_br(builder, trans._break_bb) # 创建死代码 BB,用于后续语句(break 后面的代码不可达) @@ -259,9 +251,7 @@ novirtual class StmtGenDeclMixin(StmtGenCifMixin.StmtGenCifMixin): """ if trans is None: return 0 if trans._in_switch_case == 0: - self.Gen.TypeGenErr.fatal_error(node, - "fallthrough 只能用在 switch 的 case 体内(match 完全禁止 fallthrough," - "语义是落到下一个 case)", "SyntaxError") + self.Gen.TypeGenErr.fatal_error(node, "fallthrough 只能用在 switch 的 case 体内(match 完全禁止 fallthrough," "语义是落到下一个 case)", "SyntaxError") return 0 def translate_continue(self, trans: HT.Translator*, node: ast.AST*) -> int: @@ -275,8 +265,7 @@ novirtual class StmtGenDeclMixin(StmtGenCifMixin.StmtGenCifMixin): # 发射 br 到 continue 目标 if trans._continue_bb is None: # fail-fast:循环之外的 continue 无处可跳,禁止静默无效果 - self.Gen.TypeGenErr.fatal_error(node, - "continue 只能用在循环体内(当前没有可继续的循环)", "SyntaxError") + self.Gen.TypeGenErr.fatal_error(node, "continue 只能用在循环体内(当前没有可继续的循环)", "SyntaxError") if mlirlite.builder_cur_block_is_terminated(builder) == 0: mlirlite.build_br(builder, trans._continue_bb) # 创建死代码 BB,用于后续语句 @@ -320,8 +309,7 @@ novirtual class StmtGenDeclMixin(StmtGenCifMixin.StmtGenCifMixin): self.Gen.VarGen.define_var(trans.SymTab, "_env_ptr", alloca) return alloca - def _load_raw_var_ptr(self, trans: HT.Translator*, - name: str) -> mlirlite.Value*: + def _load_raw_var_ptr(self, trans: HT.Translator*, name: str) -> mlirlite.Value*: """从闭包 env 加载 nonlocal 变量的原始指针(i8*) 返回 i8* 类型的 Value,调用方需 bitcast 为具体类型指针后 load/store。 @@ -351,8 +339,7 @@ novirtual class StmtGenDeclMixin(StmtGenCifMixin.StmtGenCifMixin): if ptr_addr is None: return None return mlirlite.build_load(builder, i8_ptr_ty, ptr_addr) - def load_nonlocal_var(self, trans: HT.Translator*, - name: str) -> mlirlite.Value*: + def load_nonlocal_var(self, trans: HT.Translator*, name: str) -> mlirlite.Value*: """从闭包 env 加载 nonlocal 变量值 通过 HT.get_nonlocal_type 获取变量类型,bitcast 原始指针后 load。 @@ -375,8 +362,7 @@ novirtual class StmtGenDeclMixin(StmtGenCifMixin.StmtGenCifMixin): if var_ptr is None: return None return mlirlite.build_load(builder, var_ty, var_ptr) - def get_nonlocal_var_ptr(self, trans: HT.Translator*, - name: str) -> mlirlite.Value*: + def get_nonlocal_var_ptr(self, trans: HT.Translator*, name: str) -> mlirlite.Value*: """获取 nonlocal 变量的存储指针(var_ty*),用于 store 操作 返回的指针指向父函数的 alloca,store 操作对父函数可见。 @@ -424,17 +410,14 @@ novirtual class StmtGenDeclMixin(StmtGenCifMixin.StmtGenCifMixin): addr: uint64 = uint64(self.EnumTable) + i * entry_size return rawptr[GenTypes.EnumEntry](addr) - def _get_enum_member(self, enum_entry: rawptr[GenTypes.EnumEntry], - i: int) -> rawptr[GenTypes.EnumMember]: + def _get_enum_member(self, enum_entry: rawptr[GenTypes.EnumEntry], i: int) -> rawptr[GenTypes.EnumMember]: """获取枚举中第 i 个成员条目""" if enum_entry is None or i < 0 or i >= ENUM_MEMBER_MAX: return None member_size: sizet = GenTypes.EnumMember.__sizeof__() addr: uint64 = uint64(enum_entry.Members) + i * member_size return rawptr[GenTypes.EnumMember](addr) - def register_enum(self, pool: memhub.MemBuddy*, - name: str, - base_ty: mlirlite.LLVMType*) -> rawptr[GenTypes.EnumEntry]: + def register_enum(self, pool: memhub.MemBuddy*, name: str, base_ty: mlirlite.LLVMType*) -> rawptr[GenTypes.EnumEntry]: """注册枚举类型,返回 EnumEntry 指针""" if self.init_enum_table(pool) == 0: return None @@ -477,11 +460,7 @@ novirtual class StmtGenDeclMixin(StmtGenCifMixin.StmtGenCifMixin): self.EnumCount += 1 return entry - def add_enum_member(self, pool: memhub.MemBuddy*, - enum_entry: rawptr[GenTypes.EnumEntry], - member_name: str, - member_val: int64, - member_ty: mlirlite.LLVMType*) -> int: + def add_enum_member(self, pool: memhub.MemBuddy*, enum_entry: rawptr[GenTypes.EnumEntry], member_name: str, member_val: int64, member_ty: mlirlite.LLVMType*) -> int: """向枚举添加成员,返回成员索引(-1 失败)""" if enum_entry is None or member_name is None or member_ty is None: return -1 @@ -522,8 +501,7 @@ novirtual class StmtGenDeclMixin(StmtGenCifMixin.StmtGenCifMixin): if string.strcmp(entry.Name, name) == 0: return entry return None - def lookup_enum_member(self, enum_name: str, - member_name: str) -> rawptr[GenTypes.EnumMember]: + def lookup_enum_member(self, enum_name: str, member_name: str) -> rawptr[GenTypes.EnumMember]: """按枚举类名和成员名查找,返回 EnumMember 或 None""" if enum_name is None or member_name is None: return None entry: rawptr[GenTypes.EnumEntry] = self.find_enum(enum_name) diff --git a/App/lib/core/Gen/Stmt/StmtGenMixin.vp b/App/lib/core/Gen/Stmt/StmtGenMixin.vp index 1949e68..66065db 100644 --- a/App/lib/core/Gen/Stmt/StmtGenMixin.vp +++ b/App/lib/core/Gen/Stmt/StmtGenMixin.vp @@ -29,24 +29,21 @@ import lib.core.Gen.DebugInfoGen as DebugInfoGen novirtual class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin): """语句/流程翻译 Mixin(拆分后顶层,继承 Decl)""" - def translate_stmt(self, trans: HT.Translator*, - node: ast.AST*) -> int: + def translate_stmt(self, trans: HT.Translator*, node: ast.AST*) -> int: """翻译单条语句,返回新增的变量数(深度守卫包装器,原逻辑见 _translate_stmt_impl)""" if trans is not None: # --traceback: statement-level DWARF location (no-op outside a # DI-attached define or when DI is disabled). 此后本语句生成的每条 # 指令自动带 ", !dbg !N",保证函数体内每个 call 都有合法 !dbg。 if node is not None and trans._cur_builder is not None: - DebugInfoGen.SetStatement(trans.Pool, trans._cur_builder, - node.lineno, node.col_offset + 1) + DebugInfoGen.SetStatement(trans.Pool, trans._cur_builder, node.lineno, node.col_offset + 1) if trans.TranslateDepth >= HT.TRANSLATE_MAX_DEPTH: self.Gen.TypeGenErr.fatal_error(node, "语句翻译嵌套过深(疑似 AST 自引用环或翻译 bug)", "RecursionError") trans.TranslateDepth += 1 mret: int = self._translate_stmt_impl(trans, node) if trans is not None: trans.TranslateDepth -= 1 return mret - def _translate_stmt_impl(self, trans: HT.Translator*, - node: ast.AST*) -> int: + def _translate_stmt_impl(self, trans: HT.Translator*, node: ast.AST*) -> int: """翻译单条语句,返回新增的变量数""" if node is None: return 0 k: int = node.kind() @@ -82,8 +79,7 @@ novirtual class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin): self.Gen.TypeGenErr.fatal_error(node, f"未知语句类型 kind={k}", "SyntaxError") return 0 - def translate_delete(self, trans: HT.Translator*, - node: ast.AST*) -> int: + def translate_delete(self, trans: HT.Translator*, node: ast.AST*) -> int: """翻译 del 语句,返回 0""" if trans is None or node is None: return 0 dnode: rawptr[ast.Delete] = rawptr[ast.Delete](node) @@ -161,8 +157,7 @@ novirtual class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin): # v1 未实现 finalbody(TestFBProject 未使用;finally+return 交互复杂, # 后续按 TPC HandlesTry.py L188-214 的 pending_ret 方案扩展)。 # ============================================================ - def translate_try(self, trans: HT.Translator*, - node: ast.AST*) -> int: + def translate_try(self, trans: HT.Translator*, node: ast.AST*) -> int: """翻译 try/except 语句,返回 0""" if trans is None or node is None: return 0 tr: ast.Try* = ast.Try*(node) @@ -349,8 +344,7 @@ novirtual class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin): trans._eh_msg_ptr = old_msg_t return 0 - def translate_raise(self, trans: HT.Translator*, - node: ast.AST*) -> int: + def translate_raise(self, trans: HT.Translator*, node: ast.AST*) -> int: """翻译 raise 语句,返回 0 对齐 TPC HandlesRaise.py 的 try-except 语义(v1 迁移): @@ -442,9 +436,7 @@ novirtual class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin): # (void→ret_void,ptr→null,float→0.0,其余→零值)。当前块已 # 终结(前一条是 raise/return)时跳过,避免在终止块后插指令。 # ============================================================ - def _eh_ret_default(self, trans: HT.Translator*, - pool: memhub.MemBuddy*, - builder: mlirlite.IRBuilder*) -> int: + def _eh_ret_default(self, trans: HT.Translator*, pool: memhub.MemBuddy*, builder: mlirlite.IRBuilder*) -> int: """异常路径返回当前函数默认零值,返回 0""" if trans is None or builder is None: return 0 if mlirlite.builder_cur_block_is_terminated(builder) != 0: return 0 @@ -482,8 +474,7 @@ novirtual class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin): # 退出后恢复,避免内层覆盖导致外层 __exit__ 解析到错误对象。 # 对齐 TPC HandlesWith 语义(不含 __provides__ provider 机制)。 # ============================================================ - def translate_with(self, trans: HT.Translator*, - node: ast.AST*) -> int: + def translate_with(self, trans: HT.Translator*, node: ast.AST*) -> int: """翻译 with 语句,返回 0""" if trans is None or node is None: return 0 wt: ast.With* = ast.With*(node) @@ -598,11 +589,7 @@ novirtual class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin): if old_ctx_alloca is not None: self.Gen.VarGen.define_var(trans.SymTab, "__with_ctx", old_ctx_alloca) return 0 - def _with_ctx_call(self, trans: HT.Translator*, - pool: memhub.MemBuddy*, - builder: mlirlite.IRBuilder*, - mod: mlirlite.LLVMModule*, - method_name: str) -> mlirlite.Value*: + def _with_ctx_call(self, trans: HT.Translator*, pool: memhub.MemBuddy*, builder: mlirlite.IRBuilder*, mod: mlirlite.LLVMModule*, method_name: str) -> mlirlite.Value*: """构造并翻译 __with_ctx.() 调用(__enter__/__exit__)""" if pool is None or method_name is None: return None name_node: ast.AST* = ast.Name(pool, "__with_ctx", ast.ASTCtx.Load) diff --git a/App/lib/core/Gen/StructGenMixin.vp b/App/lib/core/Gen/StructGenMixin.vp index 3e128a8..449d861 100644 --- a/App/lib/core/Gen/StructGenMixin.vp +++ b/App/lib/core/Gen/StructGenMixin.vp @@ -543,10 +543,7 @@ novirtual class StructGenMixin: addr: uint64 = uint64(struct_entry.Fields) + i * field_size return GenTypes.FieldEntry*(addr) - def register_struct(self, pool: memhub.MemBuddy*, - name: str, - struct_ty: mlirlite.LLVMType*, - sha1: str = None) -> GenTypes.StructEntry*: + def register_struct(self, pool: memhub.MemBuddy*, name: str, struct_ty: mlirlite.LLVMType*, sha1: str = None) -> GenTypes.StructEntry*: """注册结构体类型,返回 StructEntry 指针 用类型指针去重(is 比较),不用类名去重。 @@ -645,10 +642,7 @@ novirtual class StructGenMixin: self.add_visible_struct(pool, class_name) return entry - def register_struct_alias(self, pool: memhub.MemBuddy*, - name: str, - sha1: str, - src_entry: GenTypes.StructEntry*) -> GenTypes.StructEntry*: + def register_struct_alias(self, pool: memhub.MemBuddy*, name: str, sha1: str, src_entry: GenTypes.StructEntry*) -> GenTypes.StructEntry*: """为已注册类追加包重导出别名 entry(方案A:ast.Attribute 归属 ast 包) 子模块类从包 __init__ 重导出时,查找端 _resolve_module_sha1 按 @@ -731,12 +725,7 @@ novirtual class StructGenMixin: if entry is None: return None return entry.ModuleSha1 - def add_field(self, pool: memhub.MemBuddy*, - struct_entry: GenTypes.StructEntry*, - field_name: str, - field_ty: mlirlite.LLVMType*, - default_val: ast.AST* = None, - annot_class_name: str = None) -> int: + def add_field(self, pool: memhub.MemBuddy*, struct_entry: GenTypes.StructEntry*, field_name: str, field_ty: mlirlite.LLVMType*, default_val: ast.AST* = None, annot_class_name: str = None) -> int: """向结构体添加字段,返回字段索引(-1 失败) default_val: 字段默认值 AST 节点(可选,None=无默认值) @@ -889,8 +878,7 @@ novirtual class StructGenMixin: elem_sz_l: sizet = 8 lst_copy_l.__elem_size__ = elem_sz_l lst_copy_l.__pool__ = None - data_l: t.CPtr = pool.alloc_tagged(cnt_l * elem_sz_l, - memhub.DETSITE_STRUCTGENMIXIN_698) + data_l: t.CPtr = pool.alloc_tagged(cnt_l * elem_sz_l, memhub.DETSITE_STRUCTGENMIXIN_698) if data_l is not None: string.memset(data_l, 0, cnt_l * elem_sz_l) lst_copy_l.__data__ = data_l @@ -906,20 +894,11 @@ novirtual class StructGenMixin: # 源列表自身存在空元素,说明产生源已损坏(计数 > 实际填充) # ——响亮失败,绝不静默补 0。 if elem_src_l is None: - self.Gen.TypeGenErr.fatal_error(default_val, - f"字段默认值深拷贝:列表字面量第 {li_l} 个元素为空 AST 元素(指针为 0)。" - f"上层某处产生了空 AST 元素(元素计数与实际填充不一致)," - f"拒绝静默补 0 生成残缺的默认值;已终止编译。", - "ValueError") + self.Gen.TypeGenErr.fatal_error(default_val, f"字段默认值深拷贝:列表字面量第 {li_l} 个元素为空 AST 元素(指针为 0)。" f"上层某处产生了空 AST 元素(元素计数与实际填充不一致)," f"拒绝静默补 0 生成残缺的默认值;已终止编译。", "ValueError") return None elem_dst_l: ast.AST* = self._deep_copy_default_ast(pool, elem_src_l) if elem_dst_l is None: - self.Gen.TypeGenErr.fatal_error(elem_src_l, - f"字段默认值深拷贝:列表字面量第 {li_l} 个元素(kind={elem_src_l.kind()})" - f"既非 Constant 也非 List,无法深拷贝到永久池。若在此静默跳过该槽," - f"会形成【计数 > 实际填充数】的空槽(后续 elts.get 读到裸 0 崩溃);" - f"若静默截短计数则会改变数组初始化长度。两者都是静默降级,故响亮失败。", - "TypeError") + self.Gen.TypeGenErr.fatal_error(elem_src_l, f"字段默认值深拷贝:列表字面量第 {li_l} 个元素(kind={elem_src_l.kind()})" f"既非 Constant 也非 List,无法深拷贝到永久池。若在此静默跳过该槽," f"会形成【计数 > 实际填充数】的空槽(后续 elts.get 读到裸 0 崩溃);" f"若静默截短计数则会改变数组初始化长度。两者都是静默降级,故响亮失败。", "TypeError") return None # 槽元素类型必须是**指针**:`ast.AST*` 的 `[0]` 是 # 对象 `ast.AST`(48 字节)⇒ `slot[0] = <指针>` 被静默按 @@ -941,8 +920,7 @@ novirtual class StructGenMixin: """返回当前已注册的结构体数量""" return self.StructCount - def _resolve_module_sha1(self, mod_name: str, - from_imports: str = None) -> str: + def _resolve_module_sha1(self, mod_name: str, from_imports: str = None) -> str: """模块名 → 模块 SHA1(精确 → import 别名还原后再查 → 后缀兜底) 模块名可能是:模块真名(fat32_types)、包后缀(sched.sched)、 @@ -1217,8 +1195,7 @@ novirtual class StructGenMixin: # 空字段表(FieldCount=0,vpi 注入的"仅签名类")不判:既有语义是"按名查不到 # 返回 None",由调用方处理。 # ============================================================ - def verify_field_slot_consistency(self, struct_ty: mlirlite.LLVMType*, - entry: GenTypes.StructEntry*) -> int: + def verify_field_slot_consistency(self, struct_ty: mlirlite.LLVMType*, entry: GenTypes.StructEntry*) -> int: """字段表条数须等于结构体槽位数;每条目 Ty 须与其 Index 槽位同类""" if struct_ty is None or entry is None: return 0 if entry.FieldCount <= 0: return 0 @@ -1230,11 +1207,7 @@ novirtual class StructGenMixin: fcount: int = mlirlite.get_struct_fcount(struct_ty) if fcount <= 0: return 0 if entry.FieldCount != fcount: - self.Gen.TypeGenErr.fatal_error(None, - f"结构体 '{entry.Name}' 的字段表条数({entry.FieldCount})与 LLVM 槽位数({fcount})不一致:" - f"字段条目与结构体布局由两条路径产生,错位会让字段访问按错误下标算 GEP" - f"(实证:ast.Name.id 落到 ctx 槽 ⇒ 指针被读成整数 1 ⇒ strlen(0x1) 崩溃)。", - "TypeError") + self.Gen.TypeGenErr.fatal_error(None, f"结构体 '{entry.Name}' 的字段表条数({entry.FieldCount})与 LLVM 槽位数({fcount})不一致:" f"字段条目与结构体布局由两条路径产生,错位会让字段访问按错误下标算 GEP" f"(实证:ast.Name.id 落到 ctx 槽 ⇒ 指针被读成整数 1 ⇒ strlen(0x1) 崩溃)。", "TypeError") return 0 node: rawptr[mlirlite.ParamNode] = mlirlite.get_struct_fields(struct_ty) i: int = 0 @@ -1249,19 +1222,13 @@ novirtual class StructGenMixin: fbits_f: int = self.Gen.ExprGenBase.get_llvm_float_bits(fe.Ty) fbits_s: int = self.Gen.ExprGenBase.get_llvm_float_bits(slot_ty) if ptr_f != ptr_s or bits_f != bits_s or fbits_f != fbits_s: - self.Gen.TypeGenErr.fatal_error(None, - f"结构体 '{entry.Name}' 的字段 '{fe.Name}'(条目下标 {i})与其槽位类型不同类:" - f"条目 指针性={ptr_f}/整数位宽={bits_f}/浮点位宽={fbits_f}," - f"槽位 指针性={ptr_s}/整数位宽={bits_s}/浮点位宽={fbits_s}。" - f"字段条目与结构体布局错位(实证:id 落到 ctx 槽 ⇒ 指针被读成整数 1 ⇒ strlen(0x1) 崩溃)。", - "TypeError") + self.Gen.TypeGenErr.fatal_error(None, f"结构体 '{entry.Name}' 的字段 '{fe.Name}'(条目下标 {i})与其槽位类型不同类:" f"条目 指针性={ptr_f}/整数位宽={bits_f}/浮点位宽={fbits_f}," f"槽位 指针性={ptr_s}/整数位宽={bits_s}/浮点位宽={fbits_s}。" f"字段条目与结构体布局错位(实证:id 落到 ctx 槽 ⇒ 指针被读成整数 1 ⇒ strlen(0x1) 崩溃)。", "TypeError") return 0 node = mlirlite.paramnode_get_next(node) i += 1 return 0 - def lookup_field(self, struct_ty: mlirlite.LLVMType*, - field_name: str) -> GenTypes.FieldEntry*: + def lookup_field(self, struct_ty: mlirlite.LLVMType*, field_name: str) -> GenTypes.FieldEntry*: """按结构体类型和字段名查找字段信息 两遍查找策略(跨模块同名类冲突的根本修复): @@ -1350,11 +1317,7 @@ novirtual class StructGenMixin: elif ch == '.' and depth == 0: return s + i return None - def lookup_field_by_class(self, class_name: str, - field_name: str, - sha1: str = None, - node: ast.AST* = None, - from_imports: str = None) -> GenTypes.FieldEntry*: + def lookup_field_by_class(self, class_name: str, field_name: str, sha1: str = None, node: ast.AST* = None, from_imports: str = None) -> GenTypes.FieldEntry*: """按类名和字段名查找字段信息 优先用 SHA1 匹配(跨模块同名类区分),无 SHA1 时按类名查找第一个。 @@ -1552,8 +1515,7 @@ novirtual class StructGenMixin: if entry is not None: return entry.Ty return None - def get_field_by_index(self, class_name: str, - idx: int) -> GenTypes.FieldEntry*: + def get_field_by_index(self, class_name: str, idx: int) -> GenTypes.FieldEntry*: """按类名和字段索引获取字段信息""" if class_name is None: return None entry: GenTypes.StructEntry* = self.find_struct(class_name) @@ -1676,8 +1638,7 @@ novirtual class StructGenMixin: if entry is None: return 0 return entry.HasNew - def get_class_name_by_type(self, pool: memhub.MemBuddy*, - struct_ty: mlirlite.LLVMType*) -> str: + def get_class_name_by_type(self, pool: memhub.MemBuddy*, struct_ty: mlirlite.LLVMType*) -> str: """按类型指针查找类名,返回类名字符串或 None""" if struct_ty is None or self.StructTable is None: return None # find_struct_by_type 的语义 = 原扫描"首个 Ty 指针相等条目"(首注册优先), @@ -1766,9 +1727,7 @@ novirtual class StructGenMixin: entry.ParentName = parent_name return 1 - def set_parent_names(self, pool: memhub.MemBuddy*, - name: str, names_ptr: sizet*, - count: int) -> int: + def set_parent_names(self, pool: memhub.MemBuddy*, name: str, names_ptr: sizet*, count: int) -> int: """设置结构体的父类名数组(永久池深拷贝,跨文件永久存活)""" if name is None: return 0 entry: GenTypes.StructEntry* = self.find_struct(name) @@ -1817,8 +1776,7 @@ novirtual class StructGenMixin: if addr == 0: return None return rawptr(addr) - def get_mro_chain(self, pool: memhub.MemBuddy*, - name: str) -> sizet*: + def get_mro_chain(self, pool: memhub.MemBuddy*, name: str) -> sizet*: """MRO 线性化类名数组(深度优先 + 声明顺序 + 去重,含自身)""" if pool is None or name is None: return None arr: sizet* = pool.alloc(8 * (MRO_MAX + 1)) @@ -1925,9 +1883,7 @@ novirtual class StructGenMixin: if entry is None: return -1 return entry.FieldCount - def ensure_struct_def_in_module(self, pool: memhub.MemBuddy*, - mod: mlirlite.LLVMModule*, - ty: mlirlite.LLVMType*): + def ensure_struct_def_in_module(self, pool: memhub.MemBuddy*, mod: mlirlite.LLVMModule*, ty: mlirlite.LLVMType*): """确保跨模块结构体的完整定义在当前模块中可用(供 alloca 使用) 处理两种情况: @@ -1962,8 +1918,7 @@ novirtual class StructGenMixin: total_len: sizet = string.strlen(sname) class_name_len: sizet = string.strlen(class_name) sha1_len: sizet = total_len - class_name_len - 1 - sha1_buf: str = pool.alloc_tagged(32, - memhub.DETSITE_STRUCTGENMIXIN_1804) + sha1_buf: str = pool.alloc_tagged(32, memhub.DETSITE_STRUCTGENMIXIN_1804) if sha1_buf is None: return # 32 字节缓冲:strncpy 不截断,前缀超过 31 字符会越界写 + 手动 NUL 再越界 sha1_cp: sizet = sha1_len @@ -1987,9 +1942,7 @@ novirtual 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*, - mod: mlirlite.LLVMModule*, - ty: mlirlite.LLVMType*): + def _ensure_field_types_in_module(self, pool: memhub.MemBuddy*, mod: mlirlite.LLVMModule*, ty: mlirlite.LLVMType*): """递归扫描类型树,确保值类型子结构体有完整定义""" if ty is None or mod is None or pool is None: return # 嵌套 match 遍历类型树 diff --git a/App/lib/core/Gen/Translator.vp b/App/lib/core/Gen/Translator.vp index b4954c5..f92aae3 100644 --- a/App/lib/core/Gen/Translator.vp +++ b/App/lib/core/Gen/Translator.vp @@ -533,19 +533,14 @@ novirtual class Translator: # ============================================================ # 包装 main 函数(无用户 main 时)→ 委托 HandlesMain # ============================================================ - def _translate_wrapper_main(self, pool: memhub.MemBuddy*, - mod: mlirlite.LLVMModule*, - tree: ast.AST*, - i32_ty: mlirlite.LLVMType*): + def _translate_wrapper_main(self, pool: memhub.MemBuddy*, mod: mlirlite.LLVMModule*, tree: ast.AST*, i32_ty: mlirlite.LLVMType*): """委托 GenApi.create_wrapper_main() 创建包装 main(trans 单参)""" added: int = GenApi.create_wrapper_main(self, tree, i32_ty) # ============================================================ # 模块级翻译(用户已定义 main)→ 委托 HandlesMain # ============================================================ - def _translate_module_level(self, pool: memhub.MemBuddy*, - mod: mlirlite.LLVMModule*, - tree: ast.AST*): + def _translate_module_level(self, pool: memhub.MemBuddy*, mod: mlirlite.LLVMModule*, tree: ast.AST*): """委托 GenApi.translate_children() 翻译模块级语句(trans 单参)""" # 【文件级类名预登记:三种模式都必须先做(2026-09-30)】 # `_norm_type_arg_name` 规则 5.5 的第五类证据(is_file_class + @@ -691,9 +686,7 @@ novirtual class Translator: if string.strcmp(nm.id, ctor) == 0: return 1 return 0 - def _vb_is_macro_assign(self, target: ast.AST*, value: ast.AST*, - alias: str, ctor: str, - proj_vars: list[str]*) -> int: + def _vb_is_macro_assign(self, target: ast.AST*, value: ast.AST*, alias: str, ctor: str, proj_vars: list[str]*) -> int: """赋值是否为 viperbuild 宏语句(Project 绑定 / 字段赋值);1=是且已登记""" if target is None or value is None: return 0 tk: int = target.kind() @@ -729,8 +722,7 @@ novirtual class Translator: if string.strcmp(at.attr, "build") == 0: return 1 return 0 - def _vb_is_macro_stmt(self, child: ast.AST*, alias: str, ctor: str, - proj_vars: list[str]*) -> int: + def _vb_is_macro_stmt(self, child: ast.AST*, alias: str, ctor: str, proj_vars: list[str]*) -> int: """单条模块级语句是否为 viperbuild 宏语句;1=是(应擦除)""" if child is None: return 0 kd: int = child.kind() @@ -811,8 +803,7 @@ novirtual class Translator: # - AnnAssign 注解裸名 Name(list/dict):d: dict # - 构造调用 func 裸名 Name(list/dict):dict(bd) # - Subscript 的 value 裸名 Name(list/dict):list[int] - def _inject_auto_container_visibility(self, pool: memhub.MemBuddy*, - tree: ast.AST*): + def _inject_auto_container_visibility(self, pool: memhub.MemBuddy*, tree: ast.AST*): """检测 list/dict 容器使用,注入容器类可见性""" if tree is None or tree.children is None: return # 用栈式缓冲区传递检测结果(跨函数参数用 4 字节 int 指针) @@ -891,9 +882,7 @@ novirtual class Translator: stdlib.free(nm_buf) return 0 - def _scan_container_usage(self, node: ast.AST*, - need_list_box: t.CPtr, - need_dict_box: t.CPtr): + def _scan_container_usage(self, node: ast.AST*, need_list_box: t.CPtr, need_dict_box: t.CPtr): """递归扫描 AST 语句结构,检测 list/dict 容器使用""" if node is None: return k: int = node.kind() @@ -932,9 +921,7 @@ novirtual class Translator: n_s: sizet = len(ch_s) for ci_s in range(n_s): self._scan_container_usage(ch_s.get(ci_s), need_list_box, need_dict_box) - def _check_container_type_node(self, node: ast.AST*, - need_list_box: t.CPtr, - need_dict_box: t.CPtr): + def _check_container_type_node(self, node: ast.AST*, need_list_box: t.CPtr, need_dict_box: t.CPtr): """检测类型位置节点是否为 list/dict(支持 Name / Subscript / BinOp 递归)""" if node is None: return k: int = node.kind() diff --git a/App/lib/core/Gen/TranslatorGenMixin.vp b/App/lib/core/Gen/TranslatorGenMixin.vp index 7d587cf..678eada 100644 --- a/App/lib/core/Gen/TranslatorGenMixin.vp +++ b/App/lib/core/Gen/TranslatorGenMixin.vp @@ -166,9 +166,7 @@ novirtual class TranslatorGenMixin: # 生成格式: [N x elem_ty] [elem_ty val0, elem_ty val1, ...] # 用于模块级 t.CArray 列表字面量初始化(不依赖 builder,直接生成常量初始化器) # ============================================================ - def _build_array_initializer_text(self, pool: memhub.MemBuddy*, - var_ty: mlirlite.LLVMType*, - list_node: ast.List*) -> str: + def _build_array_initializer_text(self, pool: memhub.MemBuddy*, var_ty: mlirlite.LLVMType*, list_node: ast.List*) -> str: """从 AST List 节点生成 LLVM IR 数组初始化器文本,None 失败""" if var_ty is None or list_node is None: return None @@ -330,9 +328,7 @@ novirtual class TranslatorGenMixin: # t.CArray[char, N] = "..." → [i8 b0, i8 b1, ..., i8 0, ...](字符串字节 + # 零填充到数组长度;空串返回 zeroinitializer)。 # 不能用字符串指针 GEP 初始化器:会导致 @g = global [N x i8] 类型不匹配。 - def _build_string_array_initializer_text(self, pool: memhub.MemBuddy*, - var_ty: mlirlite.LLVMType*, - str_val: str) -> str: + def _build_string_array_initializer_text(self, pool: memhub.MemBuddy*, var_ty: mlirlite.LLVMType*, str_val: str) -> str: """字符串字面量初始化数组全局,返回初始化器文本或 None""" if var_ty is None or str_val is None: return None arr_count: int = 0 @@ -367,10 +363,7 @@ novirtual 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*, - mod: mlirlite.LLVMModule*, - var_name: str, - str_val: str) -> str: + def _build_string_ptr_initializer(self, pool: memhub.MemBuddy*, mod: mlirlite.LLVMModule*, var_name: str, str_val: str) -> str: """为字符串字面量创建内部常量全局并返回 GEP 初始化器文本,None 失败""" if str_val is None or var_name is None: return None @@ -387,14 +380,10 @@ novirtual class TranslatorGenMixin: str_len: sizet = string.strlen(str_val) init_buf: str = pool.alloc(128) if init_buf is None: return None - viperlib.snprintf(init_buf, 128, - "getelementptr inbounds ([%d x i8], [%d x i8]* @%s, i32 0, i32 0)", - str_len + 1, str_len + 1, str_name_buf) + viperlib.snprintf(init_buf, 128, "getelementptr inbounds ([%d x i8], [%d x i8]* @%s, i32 0, i32 0)", str_len + 1, str_len + 1, str_name_buf) return init_buf - def _stg_field_zero_text(self, pool: memhub.MemBuddy*, - fty: mlirlite.LLVMType*, - ty_str: str) -> str: + def _stg_field_zero_text(self, pool: memhub.MemBuddy*, fty: mlirlite.LLVMType*, ty_str: str) -> str: """按 LLVM 类型生成 storage struct 字段的零值初始化器文本 LLVM struct 初始化器必须列全所有字段(部分初始化 llc 报 @@ -422,10 +411,7 @@ novirtual class TranslatorGenMixin: # 仅处理可常量折叠的整型默认值(CONST_INT/CONST_CHAR 及负号字面量); # 其余(浮点/字符串/None/名字/表达式)返回 None,由调用方按零值兜底。 # ============================================================ - def _default_val_const_text(self, pool: memhub.MemBuddy*, - fty: mlirlite.LLVMType*, - ty_str: str, - dval: ast.AST*) -> str: + def _default_val_const_text(self, pool: memhub.MemBuddy*, fty: mlirlite.LLVMType*, ty_str: str, dval: ast.AST*) -> str: """字段默认值 → "ty 值" 文本;不可折叠返回 None""" if dval is None or fty is None or ty_str is None: return None is_int: int = 0 @@ -457,9 +443,7 @@ novirtual class TranslatorGenMixin: # - _build_stg_struct_init_text:外包 "{ ... }" 作为完整初始化器; # - vtable 对象 storage:首元素为 vtable 指针,其后追加本函数结果(start_idx=1 跳过字段 0)。 # 无任何非零默认值时返回 None,调用方据此保持原零值路径(避免无谓文本)。 - def _build_stg_struct_body_text(self, pool: memhub.MemBuddy*, - se: GenTypes.StructEntry*, - start_idx: int) -> str: + def _build_stg_struct_body_text(self, pool: memhub.MemBuddy*, se: GenTypes.StructEntry*, start_idx: int) -> str: """按字段默认值生成 "e0, e1, ..." 元素文本;无非零默认值返回 None""" if se is None or se.Fields is None: return None fc: int = se.FieldCount @@ -501,9 +485,7 @@ novirtual class TranslatorGenMixin: # 用于模块级对象全局 `X: T = T()`:按字段默认值生成完整 struct 常量 # (LLVM 要求列全每个字段);不生成则字段默认值全丢。 # 无任何非零默认值时返回 None,由调用方保持 zeroinitializer(避免无谓文本)。 - def _build_stg_struct_init_text(self, pool: memhub.MemBuddy*, - se: GenTypes.StructEntry*, - start_idx: int) -> str: + def _build_stg_struct_init_text(self, pool: memhub.MemBuddy*, se: GenTypes.StructEntry*, start_idx: int) -> str: """按字段默认值生成完整 struct 初始化器;无非零默认值返回 None""" body: str = self._build_stg_struct_body_text(pool, se, start_idx) if body is None: return None @@ -525,8 +507,7 @@ novirtual class TranslatorGenMixin: # 字段,打印时由 includes/mlirlite/__module.vp 的 _print_global 补引号 # (`, section "xxx"` / `, align N`),故此处 Section 值不带引号。 # ============================================================ - def _scan_global_tattr(self, node: ast.AST*, - want_name: str) -> ast.AST*: + def _scan_global_tattr(self, node: ast.AST*, want_name: str) -> ast.AST*: """在全局变量类型注解中查找 t.attr. 节点。 注解形态是 BinOp(BitOr) 左深链(`A | B | C` = BinOp(BinOp(A,B),C)), @@ -544,8 +525,7 @@ novirtual class TranslatorGenMixin: return None if self.Gen.ClassGenBase._tattr_name(node, want_name) != 0: return node return None - def _extract_global_attr_section(self, node: ast.AST*, - var_name: str) -> str: + def _extract_global_attr_section(self, node: ast.AST*, var_name: str) -> str: """取 `T | t.attr.section("xxx")` 的段名(不含引号)。 缺参/空段名属非法值 → fail-fast(与 handle_module_level_var 既有 @@ -559,8 +539,7 @@ novirtual class TranslatorGenMixin: self.Gen.TypeGenErr.fatal_error(node, f"模块级变量 '{var_name}' 的 t.attr.section(...) 段名缺失或为空", "ValueError") return None return sec_val - def _extract_global_attr_aligned(self, node: ast.AST*, - var_name: str) -> int: + def _extract_global_attr_aligned(self, node: ast.AST*, var_name: str) -> int: """取 `T | t.attr.aligned(N)` 的对齐字节数(无该属性返回 0)。 N 必须是正整数字面量:aligned(0)/aligned(-4)/aligned("x") 均属非法值 @@ -596,9 +575,7 @@ novirtual class TranslatorGenMixin: # 预声明遍不会走到;登记接口本身也做了幂等,重复登记无副作用。 # 独立成函数:不内联(内联新增分支会干扰调用方的类型推断)。 # ============================================================ - def _RegisterStaticModuleVar(self, trans: HT.Translator*, - annot_node: ast.AST*, - var_name: str) -> int: + def _RegisterStaticModuleVar(self, trans: HT.Translator*, annot_node: ast.AST*, var_name: str) -> int: if trans is None or annot_node is None or var_name is None: return 0 if trans.ModuleSha1 is None: return 0 if self.Gen.TypeGenErr.has_decorator_marker(annot_node, "CStatic", 0) == 0: return 0 @@ -606,8 +583,7 @@ novirtual class TranslatorGenMixin: return 0 - def handle_module_level_var(self, trans: HT.Translator*, - node: ast.AST*) -> int: + def handle_module_level_var(self, trans: HT.Translator*, node: ast.AST*) -> int: """处理模块级变量声明,创建全局变量""" pool: memhub.MemBuddy* = trans.Pool mod: mlirlite.LLVMModule* = trans.Module @@ -808,8 +784,7 @@ novirtual class TranslatorGenMixin: case _: pass if is_fty_g == 0: - self.Gen.TypeGenErr.fatal_error(node, f"模块级变量 '{var_name}' 用浮点字面量初始化,但注解不是浮点类型", - "TypeError") + self.Gen.TypeGenErr.fatal_error(node, f"模块级变量 '{var_name}' 用浮点字面量初始化,但注解不是浮点类型", "TypeError") return 0 if self.Gen.AssignGen._recover_float_literal(var_name, t.CPtr(&init_fval), 0) != 1: self.Gen.TypeGenErr.fatal_error(node, f"模块级浮点变量 '{var_name}' 初始化值源文件恢复失败", "InternalCompilerError") @@ -1088,9 +1063,7 @@ novirtual class TranslatorGenMixin: # 创建 main() -> i32 函数 → 设置 trans._cur_func/_cur_builder → # 预扫描 alloca → 翻译子节点 → ret 0 # ============================================================ - def create_wrapper_main(self, trans: HT.Translator*, - tree: ast.AST*, - i32_ty: mlirlite.LLVMType*) -> int: + def create_wrapper_main(self, trans: HT.Translator*, tree: ast.AST*, i32_ty: mlirlite.LLVMType*) -> int: """创建包装 main 函数并翻译所有顶层语句 Args: @@ -1186,8 +1159,7 @@ novirtual class TranslatorGenMixin: if string.strcmp(entry, name) == 0: return 1 return 0 - def add_nonlocal_name(self, trans: HT.Translator*, name: str, - var_ty: mlirlite.LLVMType* = None): + def add_nonlocal_name(self, trans: HT.Translator*, name: str, var_ty: mlirlite.LLVMType* = None): """添加一个 nonlocal 变量名 Args: @@ -1234,8 +1206,7 @@ novirtual class TranslatorGenMixin: trans._nonlocal_name_count += 1 trans._closure_env_count += 1 - def get_nonlocal_type(self, trans: HT.Translator*, - name: str) -> mlirlite.LLVMType*: + def get_nonlocal_type(self, trans: HT.Translator*, name: str) -> mlirlite.LLVMType*: """获取 nonlocal 变量的 LLVM 类型 Returns: 找到的类型指针,找不到返回 None diff --git a/App/lib/core/Gen/Type/TypeGenBase.vp b/App/lib/core/Gen/Type/TypeGenBase.vp index 69e9962..0b86c80 100644 --- a/App/lib/core/Gen/Type/TypeGenBase.vp +++ b/App/lib/core/Gen/Type/TypeGenBase.vp @@ -243,12 +243,10 @@ novirtual 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*, - tree: ast.AST*, tag: str): + def _dbg_check_ast_floats(self, mb: memhub.MemBuddy*, tree: ast.AST*, tag: str): """已移除调试插桩(占位保留签名,避免外部调用引用失败)""" pass - def set_generic_context(self, tp_names: list[str]*, - type_args: list[str]*): + def set_generic_context(self, tp_names: list[str]*, type_args: list[str]*): """设置泛型特化上下文(进入泛型类方法体翻译时调用),嵌套安全 先压栈当前(外层)上下文,再设置新值。clear_generic_context 弹出恢复, diff --git a/App/lib/core/Gen/Type/TypeGenCDef.vp b/App/lib/core/Gen/Type/TypeGenCDef.vp index 568b228..5606283 100644 --- a/App/lib/core/Gen/Type/TypeGenCDef.vp +++ b/App/lib/core/Gen/Type/TypeGenCDef.vp @@ -121,14 +121,12 @@ novirtual class TypeGenCDef(TypeGenBase.TypeGenBase): # PermPool 不可用(无 CompilerFactory.factory 的极简单元程序)时退回入参 # pool —— 与既有语义一致,只是不再有"表本体跨 reset 存活"的隐式假设。 # ============================================================ - def _cdefine_table_pool(self, - pool: memhub.MemBuddy*) -> memhub.MemBuddy*: + def _cdefine_table_pool(self, pool: memhub.MemBuddy*) -> memhub.MemBuddy*: """CDefine 表本体的池:恒取 PermPool(不可用则退回入参 pool)""" if CompilerFactory.factory is not None and CompilerFactory.factory.PermPool is not None: return CompilerFactory.factory.PermPool return pool - def register_cdefine_constant(self, pool: memhub.MemBuddy*, - name: str, value: int64) -> None: + def register_cdefine_constant(self, pool: memhub.MemBuddy*, name: str, value: int64) -> None: """注册 CDefine 编译期常量到本地表 值以十进制字符串存储(64 位 %lld)。大整数 CDefine(如 @@ -182,8 +180,7 @@ novirtual class TypeGenCDef(TypeGenBase.TypeGenBase): if val_buf is None: self.Gen.TypeGenErr.fatal_error(None, f"CDefine '{name}' 值缓冲区分配失败", "MemoryError") if self.CDefineDoubleFlags is not None: self.CDefineDoubleFlags.append(0) if self.CDefineStrFlags is not None: self.CDefineStrFlags.append(0) - def register_cdefine_double(self, pool: memhub.MemBuddy*, - name: str, value: double) -> None: + def register_cdefine_double(self, pool: memhub.MemBuddy*, name: str, value: double) -> None: """注册浮点 CDefine 编译期常量(如 U_M_PI: t.CDefine = 3.14159...) 值以 %f 文本存储并标记浮点,供 translate_value 返回浮点常量。 @@ -231,8 +228,7 @@ novirtual 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*, - name: str, value: str) -> None: + def register_cdefine_string(self, pool: memhub.MemBuddy*, name: str, value: str) -> None: """注册字符串 CDefine 编译期常量(如 ZLIB_VERSION: t.CDefine = "1.3.2") 字符串值深拷贝到 pool(AST 节点的 str_val 可能被 pool 操作覆写, @@ -286,8 +282,7 @@ novirtual class TypeGenCDef(TypeGenBase.TypeGenBase): # ============================================================ # 跨模块 CDefine 查找缓存(perm_pool 永久分配,跨文件复用) # ============================================================ - def register_xmod_cdefine(self, name: str, value_str: str, - is_double: int, is_str: int) -> None: + def register_xmod_cdefine(self, name: str, value_str: str, is_double: int, is_str: int) -> None: """注册跨模块 CDefine 查找结果到 perm_pool 全局缓存(跨文件复用) Args: @@ -493,8 +488,7 @@ novirtual class TypeGenCDef(TypeGenBase.TypeGenBase): # 名索引清槽(槽存 index+1,0=空槽)+ Built 归零(空表与索引同步; # 与"新建表后首次 register"的索引状态逐字一致) if self.CDefineNameIdx is not None and self.CDefineNameIdxCap > 0: - string.memset(self.CDefineNameIdx, 0, - sizet(self.CDefineNameIdxCap) * 8) + string.memset(self.CDefineNameIdx, 0, sizet(self.CDefineNameIdxCap) * 8) self.CDefineNameIdxBuilt = 0 else: self.CDefineNameIdx = None diff --git a/App/lib/core/Gen/Type/TypeGenCType.vp b/App/lib/core/Gen/Type/TypeGenCType.vp index bd011f8..0bedd53 100644 --- a/App/lib/core/Gen/Type/TypeGenCType.vp +++ b/App/lib/core/Gen/Type/TypeGenCType.vp @@ -137,14 +137,12 @@ class TypeGenCType(TypeGenBase.TypeGenBase): # PermPool 不可用(无 CompilerFactory.factory 的极简单元程序)时退回入参 # pool —— 与既有语义一致,只是不再有"表本体跨 reset 存活"的隐式假设。 # ============================================================ - def _ctypedef_table_pool(self, - pool: memhub.MemBuddy*) -> memhub.MemBuddy*: + def _ctypedef_table_pool(self, pool: memhub.MemBuddy*) -> memhub.MemBuddy*: """CTypedef 表本体的池:恒取 PermPool(不可用则退回入参 pool)""" if CompilerFactory.factory is not None and CompilerFactory.factory.PermPool is not None: return CompilerFactory.factory.PermPool return pool - def register_ctypedef(self, pool: memhub.MemBuddy*, - name: str, type_str: str) -> None: + def register_ctypedef(self, pool: memhub.MemBuddy*, name: str, type_str: str) -> None: """注册 CTypedef 到本地表 Args: @@ -296,8 +294,7 @@ class TypeGenCType(TypeGenBase.TypeGenBase): """按注解文本判定其整数值符号性(独立真源),未覆盖返回 TS_SIGN_UNKNOWN""" if text is None or depth > 16: return TSpec.TS_SIGN_UNKNOWN return self._spec_sign_of_span(text, 0, string.strlen(text), depth) - def _spec_sign_of_span(self, text: str, start: sizet, end: sizet, - depth: int) -> int: + def _spec_sign_of_span(self, text: str, start: sizet, end: sizet, depth: int) -> int: """顶层 '|' 分段,返回首个能确定的符号性(`X*` 取 X)""" seg_start: sizet = start bracket_depth: int = 0 @@ -315,8 +312,7 @@ class TypeGenCType(TypeGenBase.TypeGenBase): if bracket_depth > 0: bracket_depth -= 1 i += 1 return TSpec.TS_SIGN_UNKNOWN - def _spec_sign_of_segment(self, text: str, start: sizet, end: sizet, - depth: int) -> int: + def _spec_sign_of_segment(self, text: str, start: sizet, end: sizet, depth: int) -> int: """单个片段:去空白/括号 → 指针后缀 → 下标取元素 → 末段名 → 别名链展开""" s: sizet = start e: sizet = end @@ -395,8 +391,7 @@ class TypeGenCType(TypeGenBase.TypeGenBase): # 名索引清槽(槽存 index+1,0=空槽)+ Built 归零(空表与索引同步; # 与"新建表后首次 register"的索引状态逐字一致) if self.CTypedefNameIdx is not None and self.CTypedefNameIdxCap > 0: - string.memset(self.CTypedefNameIdx, 0, - sizet(self.CTypedefNameIdxCap) * 8) + string.memset(self.CTypedefNameIdx, 0, sizet(self.CTypedefNameIdxCap) * 8) self.CTypedefNameIdxBuilt = 0 else: self.CTypedefNameIdx = None @@ -476,8 +471,7 @@ class TypeGenCType(TypeGenBase.TypeGenBase): sep_ch_m: char = mod_id_v[1] if sep_ch_m != '\0' and sep_ch_m != ' ' and sep_ch_m != '\n' and sep_ch_m != '\r' and sep_ch_m != '\t' and sep_ch_m != '|': return 0 return 1 - def ScanCTypedefDeclarations(self, pool: memhub.MemBuddy*, - tree: ast.AST*) -> int: + def ScanCTypedefDeclarations(self, pool: memhub.MemBuddy*, tree: ast.AST*) -> int: """扫描 AST 顶层节点,注册所有 NAME: t.CTypedef = Type 声明 在 _translate_module_level 中、模块级变量预注册之前调用, @@ -517,8 +511,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*, - src: str) -> int: + def register_ctypedef_from_source(self, pool: memhub.MemBuddy*, src: str) -> int: """从源码文本逐行扫描注册 CTypedef(`typedef N = V` 或 `N: t.CTypedef = V`) stdint.vp 崩溃根因修复:AST 字符串字段(attr/id)token 零拷贝指向 @@ -554,11 +547,7 @@ class TypeGenCType(TypeGenBase.TypeGenBase): line_start = i + 1 i += 1 return count - def _eval_const_int_expr(self, node: ast.AST*, - pool: memhub.MemBuddy* = None, - from_imports: str = None, - imported_modules: str = None, - depth: int = 0) -> int: + def _eval_const_int_expr(self, node: ast.AST*, pool: memhub.MemBuddy* = None, from_imports: str = None, imported_modules: str = None, depth: int = 0) -> int: """递归计算常量整数表达式 pool/from_imports/imported_modules:跨模块 CDefine 查找上下文 diff --git a/App/lib/core/Gen/Type/TypeGenErr.vp b/App/lib/core/Gen/Type/TypeGenErr.vp index 87df1ef..5a9169c 100644 --- a/App/lib/core/Gen/Type/TypeGenErr.vp +++ b/App/lib/core/Gen/Type/TypeGenErr.vp @@ -93,9 +93,7 @@ novirtual class TypeGenErr(TypeGenBase.TypeGenBase): else: stdio.printf(' File "%s"\n', file_path) if err_msg is None or err_msg[0] == 0: err_msg = "语法错误" stdio.printf("SyntaxError: %s\n", err_msg) - def fatal_error(self, node: ast.AST*, msg: str, - err_type: str = "SyntaxError", - col_start: int = 0, col_end: int = 0): + def fatal_error(self, node: ast.AST*, msg: str, err_type: str = "SyntaxError", col_start: int = 0, col_end: int = 0): """以 Python 风格报错并退出(支持多帧、错误类型、列范围) 向后兼容:err_type/col_start/col_end 有默认值,旧调用 fatal_error(node, msg) 仍可用。 @@ -138,8 +136,7 @@ novirtual class TypeGenErr(TypeGenBase.TypeGenBase): src_line = self._read_source_line(file_name, lineno) if src_line is None: line_ok = 0 if line_ok == 0: - stdio.printf(' File "%s", line %d (!! 无法读取该行源码:文件不存在或行号超出范围,错误可能来自被复用的 AST 树,请以错误消息为准)\n', - file_name, lineno) + stdio.printf(' File "%s", line %d (!! 无法读取该行源码:文件不存在或行号超出范围,错误可能来自被复用的 AST 树,请以错误消息为准)\n', file_name, lineno) else: stdio.printf(' File "%s", line %d\n', file_name, lineno) if src_line is not None: @@ -163,15 +160,10 @@ novirtual class TypeGenErr(TypeGenBase.TypeGenBase): # (Traceback 已打印,进程存活);批处理下该出口即 sys.exit(1),逐字不变。 VLogger.repl_abort() - def fatal_type_error(self, node: ast.AST*, msg: str, - col_start: int = 0, col_end: int = 0): + def fatal_type_error(self, node: ast.AST*, msg: str, 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*, - annot: ast.AST*, - imported_modules: str, - from_imports: str, - trans: HT.Translator*) -> mlirlite.LLVMType*: + def try_extract_callable_ret(self, pool: memhub.MemBuddy*, annot: ast.AST*, imported_modules: str, from_imports: str, trans: HT.Translator*) -> mlirlite.LLVMType*: """提取函数指针注解(t.Callable[[A,B], R] / callable[[A,B], R])的返回类型 LLVMType;非 Callable 注解或无签名形态([]、[[]])返回 None""" if annot is None or annot.kind() != ast.ASTKind.Subscript: return None @@ -186,9 +178,7 @@ novirtual class TypeGenErr(TypeGenBase.TypeGenBase): ret_node_cr: ast.AST* = tp_cr.elts.get(1) if ret_node_cr is None: return None return self.Gen.TypeGenResolve.resolve_annotation_type(pool, ret_node_cr, imported_modules, from_imports, trans, 0) - def has_decorator_marker(self, node: ast.AST*, - marker_name: str, - depth: int = 0) -> int: + def has_decorator_marker(self, node: ast.AST*, marker_name: str, depth: int = 0) -> int: """检测类型注解中是否包含指定的装饰器标记""" if node is None or marker_name is None: return 0 # 递归深度守卫:vpi stub 注入时对每个函数 returns 调用本函数, @@ -237,8 +227,7 @@ novirtual class TypeGenErr(TypeGenBase.TypeGenBase): if sub.slice is None: return 0 return self.has_decorator_marker(sub.slice, "CVolatile", 0) - def is_const_object_marker(self, node: ast.AST*, - var_ty: mlirlite.LLVMType*) -> int: + def is_const_object_marker(self, node: ast.AST*, var_ty: mlirlite.LLVMType*) -> int: """变量/字段本身是否 **const 对象**(1=是 / 0=否)。 判据与 TPC 的 BaseGen._IsConstObject **逐条一致**(见 Debugger/type-descriptors.md): @@ -269,9 +258,7 @@ novirtual class TypeGenErr(TypeGenBase.TypeGenBase): def get_llvm_type_bits(self, ty: mlirlite.LLVMType*) -> int: """获取 LLVM 整数类型的位宽,非整数类型返回 0(委托 SpecTypeBits)""" return TSpec.SpecTypeBits(ty) - def infer_expr_type(self, pool: memhub.MemBuddy*, - node: ast.AST*, - param_types: str) -> mlirlite.LLVMType*: + def infer_expr_type(self, pool: memhub.MemBuddy*, node: ast.AST*, param_types: str) -> mlirlite.LLVMType*: """推断表达式的 LLVM 类型 param_types 格式: "name:bits,name:bits,..." @@ -318,9 +305,7 @@ novirtual class TypeGenErr(TypeGenBase.TypeGenBase): return rhs_ty return mlirlite.Int32(pool) - def infer_return_type(self, pool: memhub.MemBuddy*, - body: list[ast.AST*]*, - param_types: str) -> mlirlite.LLVMType*: + def infer_return_type(self, pool: memhub.MemBuddy*, body: list[ast.AST*]*, param_types: str) -> mlirlite.LLVMType*: """扫描函数体中的 return 语句,推断返回类型""" if body is None: return mlirlite.Int32(pool) @@ -337,8 +322,7 @@ novirtual class TypeGenErr(TypeGenBase.TypeGenBase): new_bits: int = self.get_llvm_type_bits(expr_ty) if new_bits > cur_bits: ret_ty = expr_ty return ret_ty - def body_has_value_return(self, pool: memhub.MemBuddy*, - body: list[ast.AST*]*) -> int: + def body_has_value_return(self, pool: memhub.MemBuddy*, body: list[ast.AST*]*) -> int: """扫描函数体,判断是否存在返回非 None 值的 return 递归检查控制流语句(if/while/for/try/with/match)内层 return,但跳过 @@ -368,8 +352,7 @@ novirtual class TypeGenErr(TypeGenBase.TypeGenBase): if sub is not None and len(sub) > 0: if self.body_has_value_return(pool, sub) != 0: return 1 return 0 - def build_param_types_str(self, pool: memhub.MemBuddy*, - args_node: ast.AST*) -> str: + def build_param_types_str(self, pool: memhub.MemBuddy*, args_node: ast.AST*) -> str: """构建参数类型编码字符串 "name:bits,name:bits,..." [D5·截断纪律] 旧实现按 `an * 32 + 1` 预估缓冲,再用 `_strappend` 以 diff --git a/App/lib/core/Gen/Type/TypeGenResolve.vp b/App/lib/core/Gen/Type/TypeGenResolve.vp index c883125..db3a676 100644 --- a/App/lib/core/Gen/Type/TypeGenResolve.vp +++ b/App/lib/core/Gen/Type/TypeGenResolve.vp @@ -32,8 +32,7 @@ import w32.fileio as fileio novirtual class TypeGenResolve(TypeGenBase.TypeGenBase): """类型映射/注解解析(map_t_type/resolve_annotation_type 等)""" - def _get_type_name_from_annotation(self, pool: memhub.MemBuddy*, - node: ast.AST*) -> str: + def _get_type_name_from_annotation(self, pool: memhub.MemBuddy*, node: ast.AST*) -> str: """从类型注解节点提取类型名(支持 Name/Attribute/BinOp)""" if node is None: return None k: int = node.kind() @@ -109,8 +108,7 @@ novirtual class TypeGenResolve(TypeGenBase.TypeGenBase): return buf2 return None return None - def _subscript_slice_to_str(self, pool: memhub.MemBuddy*, - node: ast.AST*) -> str: + def _subscript_slice_to_str(self, pool: memhub.MemBuddy*, node: ast.AST*) -> str: """Subscript slice 节点转类型字符串(递归,支持 Name/Attribute/BinOp/Constant/List/Tuple/Subscript)""" if node is None: return None k2: int = node.kind() @@ -138,9 +136,7 @@ novirtual class TypeGenResolve(TypeGenBase.TypeGenBase): tup: ast.Tuple* = ast.Tuple*(node) return self._list_elts_to_type_str(pool, tup.elts, "", "") return None - def _list_elts_to_type_str(self, pool: memhub.MemBuddy*, - elts: list[ast.AST*]*, - open_ch: str, close_ch: str) -> str: + def _list_elts_to_type_str(self, pool: memhub.MemBuddy*, elts: list[ast.AST*]*, open_ch: str, close_ch: str) -> str: """元素列表转逗号分隔字符串(List/Tuple 共用),包上 open/close 括号 [D1·截断纪律] 旧实现固定 1024 缓冲 + `strlen(x) < 1024` 守卫:装不下就 @@ -198,8 +194,7 @@ novirtual class TypeGenResolve(TypeGenBase.TypeGenBase): 此处只做委托:保留本方法是因 `@t.NoVTable` 静态绑定下大量调用点依赖它存在。 """ return GenApi.sha1_prefix_len(s) - def _concat_sha1_class(self, pool: memhub.MemBuddy*, - sha1: str, cls_name: str) -> str: + def _concat_sha1_class(self, pool: 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: return None total: sizet = string.strlen(sha1) + 1 + string.strlen(cls_name) + 1 @@ -233,8 +228,7 @@ novirtual class TypeGenResolve(TypeGenBase.TypeGenBase): # · 前缀与 cand 相同 / 取不到 IR 名前缀 ⇒ 原样返回 cand(对"类与引用同模块" # "import 子模块"等已一致情形**逐字不变**)。 # ============================================================ - def _class_true_def_sha1(self, pool: memhub.MemBuddy*, - cls_name: str, cand_sha1: str) -> str: + def _class_true_def_sha1(self, pool: memhub.MemBuddy*, cls_name: str, cand_sha1: str) -> str: """类名 cls_name 的真定义模块 SHA1;无证据时原样返回 cand_sha1""" if pool is None or cls_name is None or cand_sha1 is None: return cand_sha1 e: GenTypes.StructEntry* = self.Gen.StructGen.find_struct_by_module(cls_name, cand_sha1) @@ -287,10 +281,7 @@ novirtual class TypeGenResolve(TypeGenBase.TypeGenBase): # ② 扁平名条目存在且 Ty 非空(先按本模块归属精确匹配,再退回裸名)。 # 两条都不满足即返回 None,交由调用方既有的"未解析"路径处理(绝不静默兜底)。 # ============================================================ - def _resolve_nested_class_type(self, pool: memhub.MemBuddy*, - outer_name: str, - inner_name: str, - trans: HT.Translator*) -> mlirlite.LLVMType*: + def _resolve_nested_class_type(self, pool: memhub.MemBuddy*, outer_name: str, inner_name: str, trans: HT.Translator*) -> mlirlite.LLVMType*: """`外类.内类` → 嵌套类 Ty;无证据返回 None""" if pool is None or outer_name is None or inner_name is None: return None # ① base 必须是已知类(或正定义中的本类) @@ -311,9 +302,7 @@ novirtual class TypeGenResolve(TypeGenBase.TypeGenBase): any_e: GenTypes.StructEntry* = self.Gen.StructGen.find_struct(flat_buf) if any_e is not None and any_e.Ty is not None: return any_e.Ty return None - def _repl_opaque_class_ty(self, pool: memhub.MemBuddy*, - mod_sha1: str, - cls_name: str) -> mlirlite.LLVMType*: + def _repl_opaque_class_ty(self, pool: memhub.MemBuddy*, mod_sha1: str, cls_name: str) -> mlirlite.LLVMType*: """(REPL 会话专用)未登记类别的"仅类型"占位:`%"{sha1}.{类名}"` opaque 具名结构体 背景:REPL 的 includes 类注册(M4.2)只登记**布局可信**的类;缺 `.stub.ll` @@ -487,9 +476,7 @@ novirtual class TypeGenResolve(TypeGenBase.TypeGenBase): string.strcat(_out_pst, "*") return _out_pst - def _norm_type_arg_name(self, pool: memhub.MemBuddy*, - type_name: str, - from_imports: str) -> str: + def _norm_type_arg_name(self, pool: memhub.MemBuddy*, type_name: str, from_imports: str) -> str: """泛型类型参数名 SHA1 规范化:统一为 "{定义模块SHA1}.{Class}" 形式 收敛同一类型的不同书写(ast.AST / AST → f467978339422f32.AST), @@ -930,12 +917,7 @@ novirtual class TypeGenResolve(TypeGenBase.TypeGenBase): _w_buf[0] = '\0' mlirlite.TypePrint(_w_buf, 512, _bare_entry.Ty, pool) if _w_buf[0] != '\0': _w_ty = _w_buf - VLogger.error( - f"[类型实参归属] 裸类名 '{type_name}' 本次保留裸名(可能与带前缀形式分裂):" - f"entry_present={_w_ep} entry.Ty={_w_ty} cur_def_mod={_w_mod} cur_def_cls={_w_cls} " - f"is_module_class={_w_imc} find_struct_by_module={_w_fbm} " - f"from_imports={_w_fi} file={_w_file}", - "TypeGen") + VLogger.error(f"[类型实参归属] 裸类名 '{type_name}' 本次保留裸名(可能与带前缀形式分裂):" f"entry_present={_w_ep} entry.Ty={_w_ty} cur_def_mod={_w_mod} cur_def_cls={_w_cls} " f"is_module_class={_w_imc} find_struct_by_module={_w_fbm} " f"from_imports={_w_fi} file={_w_file}", "TypeGen") # ---- 6. 查不到:保持原样(内置类型名等)---- return type_name @@ -966,9 +948,7 @@ novirtual class TypeGenResolve(TypeGenBase.TypeGenBase): if left_ok != 0 and right_ok != 0: return 1 return 0 - def _parse_type_string(self, pool: memhub.MemBuddy*, - type_str: str, - ctx: int) -> ast.AST*: + def _parse_type_string(self, pool: memhub.MemBuddy*, type_str: str, ctx: int) -> ast.AST*: """将类型名字符串解析为 AST 节点 正确处理 '|' 与 '.' 周围的空格(如 "ParsedArgs*"): @@ -1149,11 +1129,7 @@ novirtual class TypeGenResolve(TypeGenBase.TypeGenBase): def get_current_file(self) -> str: """获取当前编译的文件名(供报错归因使用)""" return self.CurrentFile - def resolve_typedef_or_map(self, pool: memhub.MemBuddy*, - name: str, - imported_modules: str, - from_imports: str, - trans: HT.Translator* = None) -> mlirlite.LLVMType*: + def resolve_typedef_or_map(self, pool: memhub.MemBuddy*, name: str, imported_modules: str, from_imports: str, trans: HT.Translator* = None) -> mlirlite.LLVMType*: """统一口径:CTypedef 动态表优先展开,miss 回退 map_t_type 硬编码 供 resolve_annotation_type 之外的旁路调用点(TypeGenErr/ClassGenEnum/ @@ -1200,10 +1176,7 @@ novirtual class TypeGenResolve(TypeGenBase.TypeGenBase): self.Gen.TypeGenCType.CTypedefResolveDepth -= 1 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*, - name: str, - imported_modules: str, - from_imports: str) -> int: + def get_type_size_bytes(self, pool: memhub.MemBuddy*, name: str, imported_modules: str, from_imports: str) -> int: """统一尺寸口径(阶段 3):resolve_typedef_or_map → 位宽/8;失败返回 0 供 __sizeof__/REnum 布局等派生表使用——库 typedef(BYTE/DWORD 等)尺寸 @@ -1316,8 +1289,7 @@ novirtual class TypeGenResolve(TypeGenBase.TypeGenBase): if al_len == mod_len: if string.strncmp(buf + al_start, mod, mod_len) == 0: return buf + tg_start return None - def _parse_typedef_line(self, out_buf: str, buf: str, - line_start: sizet, line_len: sizet) -> int: + def _parse_typedef_line(self, out_buf: str, buf: str, line_start: sizet, line_len: sizet) -> int: """一行源码 → typedef 声明写入 out_buf("NAME\\0VALUE\\0"),返回 1/0 兼容两种等价形态(对齐 TPC TypeAnnotationResolver._parse_typedef_line): @@ -1383,8 +1355,7 @@ novirtual class TypeGenResolve(TypeGenBase.TypeGenBase): ci += 1 out_buf[name_l + 1 + vlen] = '\0' return 1 - def _lookup_builtins_typedef(self, pool: memhub.MemBuddy*, - name: str) -> str: + def _lookup_builtins_typedef(self, pool: memhub.MemBuddy*, name: str) -> str: """builtins 最后匹配:查 includes/builtins.vp 的 CTypedef 声明 所有常规解析路径 miss 后("没有匹配到前面模式的注解")的最终兜底: @@ -1475,8 +1446,7 @@ novirtual class TypeGenResolve(TypeGenBase.TypeGenBase): b_al_s: sizet = b_as_i + 4 while b_al_s < b_imp_len and b_buf[b_imp_ls + b_al_s] == ' ': b_al_s += 1 b_al_e: sizet = b_imp_len - while b_al_e > b_al_s and (b_buf[b_imp_ls + b_al_e - 1] == ' ' - or b_buf[b_imp_ls + b_al_e - 1] == '\r'): + while b_al_e > b_al_s and (b_buf[b_imp_ls + b_al_e - 1] == ' ' or b_buf[b_imp_ls + b_al_e - 1] == '\r'): b_al_e -= 1 if b_tgt_e > b_tgt_s and b_al_e > b_al_s: b_tgt_buf: str = pool.alloc(b_tgt_e - b_tgt_s + 1) @@ -1533,8 +1503,7 @@ novirtual class TypeGenResolve(TypeGenBase.TypeGenBase): stdlib.free(b_buf) if b_final_r is not None: return b_final_r return None - def _register_lib_typedef_cache(self, mod: str, name_src: str, - name_len: sizet, type_str: str) -> None: + def _register_lib_typedef_cache(self, mod: str, name_src: str, name_len: sizet, type_str: str) -> None: """把库模块源中的一条 typedef 写入持久缓存(PermPool,同名首次为准) key = "模块名|typedef 名"(模块名/typedef 名均为标识符,不含 '|')。 @@ -1595,8 +1564,7 @@ novirtual class TypeGenResolve(TypeGenBase.TypeGenBase): stdlib.free(key_buf) if v is None: return None return t.CPtr(v) - def _lookup_library_typedef(self, pool: memhub.MemBuddy*, - mod: str, attr: str) -> str: + def _lookup_library_typedef(self, pool: memhub.MemBuddy*, mod: str, attr: str) -> str: """查库模块源文件中 "attr: t.CTypedef = TYPE" 并注册,返回 TYPE 或 None 仅用于 builtins 最后匹配的模块限定引用展开(如 @@ -1674,8 +1642,7 @@ novirtual class TypeGenResolve(TypeGenBase.TypeGenBase): if m_res is not None: self.Gen.TypeGenCType.register_ctypedef(pool, attr, m_res) stdlib.free(m_buf) return m_res - def _expand_typedef_ref(self, pool: memhub.MemBuddy*, - type_str: str, depth: int = 0) -> str: + def _expand_typedef_ref(self, pool: memhub.MemBuddy*, type_str: str, depth: int = 0) -> str: """展开类型表达式中的模块限定 typedef 引用(stdint.size_t → sizet) builtins 最后匹配的 typedef 值可能引用库模块 typedef(size_t: @@ -1758,10 +1725,7 @@ novirtual class TypeGenResolve(TypeGenBase.TypeGenBase): # 仅支持 Attribute(Mod.Class / 别名 Mod.Class)与 Name(from-import 裸类名)两形。 # 返回 Ptr(占位.Ty);无法确定类名/模块 SHA1 时返回 None(调用方保持旧行为)。 # ============================================================ - def _forward_declare_ptr_from_node(self, pool: memhub.MemBuddy*, - node: ast.AST*, - imported_modules: str, - from_imports: str) -> mlirlite.LLVMType*: + def _forward_declare_ptr_from_node(self, pool: memhub.MemBuddy*, node: ast.AST*, imported_modules: str, from_imports: str) -> mlirlite.LLVMType*: if node is None: return None cls_nm: str = None sha1: str = None @@ -1839,8 +1803,7 @@ novirtual class TypeGenResolve(TypeGenBase.TypeGenBase): if entry is None or entry.Ty is None: return None return mlirlite.Ptr(pool, entry.Ty) - def map_t_type(self, pool: memhub.MemBuddy*, - type_name: str) -> mlirlite.LLVMType*: + def map_t_type(self, pool: memhub.MemBuddy*, type_name: str) -> mlirlite.LLVMType*: """将 t.CXxx / c.CXxx 类型名映射到 LLVMType 注意: str = i8* = str = bytes @@ -1934,9 +1897,7 @@ novirtual class TypeGenResolve(TypeGenBase.TypeGenBase): elif string.strcmp(type_name, "float") == 0: return mlirlite.Float(pool) elif string.strcmp(type_name, "double") == 0: return mlirlite.Double(pool) return None - def _is_t_attr(self, node: ast.AST*, - attr_name: str, - imported_modules: str) -> int: + def _is_t_attr(self, node: ast.AST*, attr_name: str, imported_modules: str) -> int: """检测节点是否是 t.attr_name 形式(含 from t import attr_name 的裸名) 支持两种写法(与 TPC 的 IsTModule 检查对齐): @@ -1967,8 +1928,7 @@ novirtual class TypeGenResolve(TypeGenBase.TypeGenBase): if self.Gen.ImportsGen.is_module_imported(imported_modules, "t") == 0: return 0 return 1 return 0 - def _is_cptr_marker(self, node: ast.AST*, - imported_modules: str) -> int: + def _is_cptr_marker(self, node: ast.AST*, imported_modules: str) -> int: """检测节点是否为 CPtr 指针标记,返回 1=是 / 0=否""" if self._is_t_attr(node, "CPtr", imported_modules) != 0: return 1 if node is not None and node.kind() == ast.ASTKind.Name: @@ -2019,8 +1979,7 @@ novirtual class TypeGenResolve(TypeGenBase.TypeGenBase): if rn.id is None or string.strcmp(rn.id, "t") != 0: return 0 if string.strcmp(root.attr, "attr") != 0: return 0 return 1 - def _is_cvoid_marker(self, node: ast.AST*, - imported_modules: str) -> int: + def _is_cvoid_marker(self, node: ast.AST*, imported_modules: str) -> int: """检测节点是否为 CVoid 指针标记,返回 1=是 / 0=否""" if self._is_t_attr(node, "CVoid", imported_modules) != 0: return 1 if node is not None and node.kind() == ast.ASTKind.Name: @@ -2058,9 +2017,7 @@ novirtual class TypeGenResolve(TypeGenBase.TypeGenBase): if prefix is not None: buf: str = stdlib.malloc(string.strlen(prefix) + string.strlen(at.attr) + 2) if buf is not None: - viperlib.snprintf(buf, - string.strlen(prefix) + string.strlen(at.attr) + 2, - "%s.%s", prefix, at.attr) + viperlib.snprintf(buf, string.strlen(prefix) + string.strlen(at.attr) + 2, "%s.%s", prefix, at.attr) return buf return at.attr @@ -2071,8 +2028,7 @@ novirtual class TypeGenResolve(TypeGenBase.TypeGenBase): if base is not None: buf2: str = stdlib.malloc(string.strlen(base) + 5) if buf2 is not None: - viperlib.snprintf(buf2, string.strlen(base) + 5, - "%s[...]", base) + viperlib.snprintf(buf2, string.strlen(base) + 5, "%s[...]", base) return buf2 return "" @@ -2084,9 +2040,7 @@ novirtual class TypeGenResolve(TypeGenBase.TypeGenBase): if left_s is not None and right_s is not None: buf3: str = stdlib.malloc(string.strlen(left_s) + string.strlen(right_s) + 5) if buf3 is not None: - viperlib.snprintf(buf3, - string.strlen(left_s) + string.strlen(right_s) + 5, - "%s | %s", left_s, right_s) + viperlib.snprintf(buf3, string.strlen(left_s) + string.strlen(right_s) + 5, "%s | %s", left_s, right_s) return buf3 return "" @@ -2108,10 +2062,7 @@ novirtual class TypeGenResolve(TypeGenBase.TypeGenBase): if string.strcmp(name, "CInline") == 0: return 1 return 0 - def extract_class_name_from_annotation(self, node: ast.AST*, - imported_modules: str, - pool: memhub.MemBuddy* = None, - from_imports: str = None) -> str: + def extract_class_name_from_annotation(self, node: ast.AST*, imported_modules: str, pool: memhub.MemBuddy* = None, from_imports: str = None) -> str: """从类型注解 AST 中提取类名,返回 None=无法提取 pool 可用时,对泛型 Subscript(如 list[AST*])返回 mangled name @@ -2182,9 +2133,7 @@ novirtual class TypeGenResolve(TypeGenBase.TypeGenBase): # 返回模块限定名 "module.Class"(如 "memhub.MemBuddy") mod_qual_buf: str = stdlib.malloc(string.strlen(real_mod2) + string.strlen(at.attr) + 2) if mod_qual_buf is not None: - viperlib.snprintf(mod_qual_buf, - string.strlen(real_mod2) + string.strlen(at.attr) + 2, - "%s.%s", real_mod2, at.attr) + viperlib.snprintf(mod_qual_buf, string.strlen(real_mod2) + string.strlen(at.attr) + 2, "%s.%s", real_mod2, at.attr) if alias_mod2 is not None: stdlib.free(alias_mod2) return mod_qual_buf if alias_mod2 is not None: stdlib.free(alias_mod2) @@ -2293,13 +2242,7 @@ novirtual class TypeGenResolve(TypeGenBase.TypeGenBase): return mangled_buf return None - def _resolve_generic_subscript_ty(self, pool: memhub.MemBuddy*, - sub: ast.Subscript*, - gen_cls_name: str, - trans: HT.Translator*, - imported_modules: str, - from_imports: str, - depth: int = 0) -> mlirlite.LLVMType*: + def _resolve_generic_subscript_ty(self, pool: memhub.MemBuddy*, sub: ast.Subscript*, gen_cls_name: str, trans: HT.Translator*, imported_modules: str, from_imports: str, depth: int = 0) -> mlirlite.LLVMType*: """解析泛型类类型注解(特化或查找已注册结构体),失败返回 None""" if pool is None or sub is None or gen_cls_name is None: return None # tuple[T1, T2, ...] → 匿名结构体 {T1, T2, ...}(多返回值打包, @@ -2459,10 +2402,7 @@ novirtual class TypeGenResolve(TypeGenBase.TypeGenBase): # 后续 .get() 按错误元素类型分派 → inttoptr 截断崩溃。禁止静默退化:报出查表键 # 与实际模板名。仅当基名确为泛型模板时才触发(避免误伤 rawptr/CArray 等 builtin)。 if trans is not None and trans._declare_only == 0 and self.Gen.ClassGenGeneric._find_generic_template(gen_cls_name) is not None: - self.Gen.TypeGenErr.fatal_error(sub, - f"泛型下标 '{gen_mangled}' 未解析出特化结构体(泛型模板='{gen_cls_name}');" - f"该注解将退化为裸基类/i8* → 后续 .get() 按错误元素类型分派并截断指针", - "TypeError") + self.Gen.TypeGenErr.fatal_error(sub, f"泛型下标 '{gen_mangled}' 未解析出特化结构体(泛型模板='{gen_cls_name}');" f"该注解将退化为裸基类/i8* → 后续 .get() 按错误元素类型分派并截断指针", "TypeError") # [REPL 会话] includes 泛型模板(list/dict/Vector/…)在会话里**未注册**:会话 # 类注册只注入 `.vpi` 的类(泛型类被跳过),不跑批处理的 # _PreRegister*GenericTemplates ⇒ 泛型下标的特化恒 miss。若该注解位于形参/ @@ -2512,18 +2452,9 @@ novirtual class TypeGenResolve(TypeGenBase.TypeGenBase): if base_nm is None: return 0 # 仅当基名确实是本项目已注册的泛型模板才判定为裸泛型注解 if self.Gen.ClassGenGeneric._find_generic_template(base_nm) is None: return 0 - self.Gen.TypeGenErr.fatal_error(node, - f"泛型类 '{base_nm}' 的注解必须带类型实参(如 {base_nm}[T]);" - f"裸名会被当作无实参的裸泛型基类,元素类型丢失后方法调用会按错误元素" - f"类型特化并截断指针。正确写法示例:vector.Vector[CInt]、GSList[G5Node]。", - "TypeError") + self.Gen.TypeGenErr.fatal_error(node, f"泛型类 '{base_nm}' 的注解必须带类型实参(如 {base_nm}[T]);" f"裸名会被当作无实参的裸泛型基类,元素类型丢失后方法调用会按错误元素" f"类型特化并截断指针。正确写法示例:vector.Vector[CInt]、GSList[G5Node]。", "TypeError") return 0 - def resolve_annotation_type(self, pool: memhub.MemBuddy*, - node: ast.AST*, - imported_modules: str, - from_imports: str, - trans: HT.Translator* = None, - depth: int = 0) -> mlirlite.LLVMType*: + def resolve_annotation_type(self, pool: memhub.MemBuddy*, node: ast.AST*, imported_modules: str, from_imports: str, trans: HT.Translator* = None, depth: int = 0) -> mlirlite.LLVMType*: """解析类型注解节点为 LLVMType Args: @@ -3136,8 +3067,7 @@ novirtual class TypeGenResolve(TypeGenBase.TypeGenBase): # (定义侧随后原位填充)。无法确定类名/模块时,才退回 # Ptr(i8) 由 AnnotClassName 恢复 + 多遍注册收敛,禁止 # fail-fast(误杀合法前向引用)。 - _fwd_ptr_ty: mlirlite.LLVMType* = self._forward_declare_ptr_from_node( - pool, other_node, imported_modules, from_imports) + _fwd_ptr_ty: mlirlite.LLVMType* = self._forward_declare_ptr_from_node(pool, other_node, imported_modules, from_imports) if _fwd_ptr_ty is not None: return _fwd_ptr_ty return mlirlite.Ptr(pool, mlirlite.Int8(pool)) # `X*` **恒追加恰好 1 层**(用户口径,与 rawptr[T]/t.CPtr[T] 下标形 @@ -3301,8 +3231,7 @@ novirtual class TypeGenResolve(TypeGenBase.TypeGenBase): if rp_elem is None: return None return mlirlite.Ptr(pool, rp_elem) return None - gen_ty_nm: mlirlite.LLVMType* = self._resolve_generic_subscript_ty(pool, sub, gen_nm.id, trans, - imported_modules, from_imports, depth + 1) + gen_ty_nm: mlirlite.LLVMType* = self._resolve_generic_subscript_ty(pool, sub, gen_nm.id, trans, imported_modules, from_imports, depth + 1) if gen_ty_nm is not None: return gen_ty_nm # 泛型特化 miss 时不能 return None 直接退出——否则下面的 # [builtins 最后匹配] 兜底永远不可达(rawptr[int] 根因)。 @@ -3336,8 +3265,7 @@ novirtual class TypeGenResolve(TypeGenBase.TypeGenBase): # (在 t.CArray / t.Callable 检查之前;模板已注册即视为泛型类) if trans is not None: if self.Gen.ClassGenGeneric._find_generic_template(arr_at.attr) is not None: - return self._resolve_generic_subscript_ty(pool, sub, arr_at.attr, trans, - imported_modules, from_imports, depth + 1) + return self._resolve_generic_subscript_ty(pool, sub, arr_at.attr, trans, imported_modules, from_imports, depth + 1) if arr_at.value is None or arr_at.value.kind() != ast.ASTKind.Name: self.Gen.TypeGenErr.fatal_type_error(node, "t.CArray / t.Callable 必须通过模块名限定") arr_val_name: ast.Name* = ast.Name*(arr_at.value) if arr_val_name.id is None: self.Gen.TypeGenErr.fatal_type_error(node, "Subscript 模块名为 None") @@ -3365,8 +3293,7 @@ novirtual class TypeGenResolve(TypeGenBase.TypeGenBase): # X* 分支与 TPC);无法确定类名/模块时仍返回 None 交上层 # 多遍收敛,不在此 fatal 中断 Phase 1a 预注册(UINT 等只经 # CTypedef 动态表解析)。真实类型错误由 Phase A 收敛检查暴露。 - _fwd_cptr_ty: mlirlite.LLVMType* = self._forward_declare_ptr_from_node( - pool, sub.slice, imported_modules, from_imports) + _fwd_cptr_ty: mlirlite.LLVMType* = self._forward_declare_ptr_from_node(pool, sub.slice, imported_modules, from_imports) if _fwd_cptr_ty is not None: return _fwd_cptr_ty return None return mlirlite.Ptr(pool, inner_cptr_ty) diff --git a/App/lib/core/Gen/Type/TypeSpec.vp b/App/lib/core/Gen/Type/TypeSpec.vp index 0a2252d..f0a1b9c 100644 --- a/App/lib/core/Gen/Type/TypeSpec.vp +++ b/App/lib/core/Gen/Type/TypeSpec.vp @@ -362,8 +362,7 @@ def _spec_set_struct_name(sp: TypeSpec*, name: str) -> int: # ============================================================ # NewTypeSpec - 构造基础类型(驻留) # ============================================================ -def NewTypeSpec(arena: TypeSpecArena*, kind: int, - bits: int, is_signed: int) -> TypeSpec*: +def NewTypeSpec(arena: TypeSpecArena*, kind: int, bits: int, is_signed: int) -> TypeSpec*: """构造基础 TypeSpec 并驻留,失败返回 None""" sp: TypeSpec* = _spec_make(kind, bits, is_signed) if sp is None: return None @@ -373,8 +372,7 @@ def NewTypeSpec(arena: TypeSpecArena*, kind: int, # ============================================================ # NewTypeStruct - 构造结构体/枚举/类类型(驻留) # ============================================================ -def NewTypeStruct(arena: TypeSpecArena*, kind: int, - base_name: str) -> TypeSpec*: +def NewTypeStruct(arena: TypeSpecArena*, kind: int, base_name: str) -> TypeSpec*: """构造 struct/union/enum 类型(BaseName 深拷贝 + 驻留),失败返回 None""" sp: TypeSpec* = _spec_make(kind, 0, TS_SIGN_UNKNOWN) if sp is None: return None @@ -385,8 +383,7 @@ def NewTypeStruct(arena: TypeSpecArena*, kind: int, # ============================================================ # NewTypePtr - 构造指针类型(PtrLevel = 元素 PtrLevel + 1,驻留) # ============================================================ -def NewTypePtr(arena: TypeSpecArena*, - elem: TypeSpec*) -> TypeSpec*: +def NewTypePtr(arena: TypeSpecArena*, elem: TypeSpec*) -> TypeSpec*: """构造指针类型:指向 elem(PtrLevel 逐层递增),失败返回 None""" if elem is None: return None sp: TypeSpec* = _spec_make(TS_PTR, 0, TS_SIGN_UNKNOWN) @@ -402,8 +399,7 @@ def NewTypePtr(arena: TypeSpecArena*, # ============================================================ # NewTypeArray - 构造数组类型(ArrayCount 个 elem,驻留) # ============================================================ -def NewTypeArray(arena: TypeSpecArena*, elem: TypeSpec*, - count: int) -> TypeSpec*: +def NewTypeArray(arena: TypeSpecArena*, elem: TypeSpec*, count: int) -> TypeSpec*: """构造数组类型:elem[count](count<=0 表示长度未知/动态),失败返回 None""" if elem is None or count < 0: return None sp: TypeSpec* = _spec_make(TS_ARRAY, 0, TS_SIGN_UNKNOWN) @@ -420,9 +416,7 @@ def NewTypeArray(arena: TypeSpecArena*, elem: TypeSpec*, # NewTypeFunc - 构造函数签名类型(ret + 参数数组 + 变参,驻留) # params:TypeSpec* 连续数组(由调用方预先构造并保证存活);count 个 # ============================================================ -def NewTypeFunc(arena: TypeSpecArena*, ret: TypeSpec*, - params: sizet*, count: int, - is_vararg: int) -> TypeSpec*: +def NewTypeFunc(arena: TypeSpecArena*, ret: TypeSpec*, params: sizet*, count: int, is_vararg: int) -> TypeSpec*: """构造函数签名类型,失败返回 None""" if ret is None or count < 0: return None if count > 0 and params is None: return None @@ -489,8 +483,7 @@ def SpecToText(sp: TypeSpec*, buf: str, buf_size: sizet) -> int: return _spec_to_text(sp, buf, buf_size, 0) -def _spec_to_text(sp: TypeSpec*, buf: str, buf_size: sizet, - depth: int) -> int: +def _spec_to_text(sp: TypeSpec*, 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' @@ -716,8 +709,7 @@ def _text_to_func(text: str, depth: int) -> TypeSpec*: # 静默丢失类型信息);**键文本**装不下 SPEC_TEXT_MAX → 保留实例但放弃去重 # (绝不写入截断键)。 # ============================================================ -def InternSpec(arena: TypeSpecArena*, - sp: TypeSpec*) -> TypeSpec*: +def InternSpec(arena: TypeSpecArena*, sp: TypeSpec*) -> TypeSpec*: """按规范文本键驻留 TypeSpec;失败返回 None""" if arena is None or sp is None: return sp if SpecArenaInit(arena, 0) != 0: return None @@ -828,9 +820,7 @@ def _spec_clone(sp: TypeSpec*) -> TypeSpec*: # # 仅当符号性实际变化才复制并驻留,否则返回原实例。驻留去重 ⇒ 同「结构+符号」共享一份。 # ============================================================ -def SpecWithSign(arena: TypeSpecArena*, - sp: TypeSpec*, - is_signed: int) -> TypeSpec*: +def SpecWithSign(arena: TypeSpecArena*, sp: TypeSpec*, is_signed: int) -> TypeSpec*: """复制 sp 并覆盖整数符号性,驻留后返回;无变化返回原实例,失败返回 None""" if sp is None: return None new_kind: int = sp.Kind @@ -1017,8 +1007,7 @@ def _spec_llvm_append(buf: str, buf_size: sizet, src: str) -> int: return 0 -def _spec_llvm_text(sp: TypeSpec*, buf: str, buf_size: sizet, - depth: int) -> int: +def _spec_llvm_text(sp: TypeSpec*, 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 @@ -1108,8 +1097,7 @@ def _spec_llvm_text(sp: TypeSpec*, buf: str, buf_size: sizet, # # 本函数当前**无调用点**(S2 只入库;接线在后续步骤)。 # ============================================================ -def SpecFromLLVMType(arena: TypeSpecArena*, - ty: mlirlite.LLVMType*) -> TypeSpec*: +def SpecFromLLVMType(arena: TypeSpecArena*, ty: mlirlite.LLVMType*) -> TypeSpec*: """把已解析的 LLVM 类型翻译成 TypeSpec;不支持或为 None 时返回 None""" if arena is None or ty is None: return None match ty: @@ -1132,27 +1120,21 @@ def SpecFromLLVMType(arena: TypeSpecArena*, return None -def _spec_from_ptr(arena: TypeSpecArena*, - pointee: mlirlite.LLVMType*) -> TypeSpec*: +def _spec_from_ptr(arena: TypeSpecArena*, pointee: mlirlite.LLVMType*) -> TypeSpec*: """Ptr(pointee) → TypeSpec(PtrLevel/ElemBits/IsElemPtr 由 NewTypePtr 填)""" inner: TypeSpec* = SpecFromLLVMType(arena, pointee) if inner is None: return None return NewTypePtr(arena, inner) -def _spec_from_array(arena: TypeSpecArena*, - elem_ty: mlirlite.LLVMType*, - count: int) -> TypeSpec*: +def _spec_from_array(arena: TypeSpecArena*, elem_ty: mlirlite.LLVMType*, count: int) -> TypeSpec*: """[count x elem] → TypeSpec(ArrayCount/ElemBits/IsElemPtr 由 NewTypeArray 填)""" inner: TypeSpec* = SpecFromLLVMType(arena, elem_ty) if inner is None: return None return NewTypeArray(arena, inner, count) -def _spec_from_func(arena: TypeSpecArena*, - ret: mlirlite.LLVMType*, - params: mlirlite.ParamNode*, - pcount: int) -> TypeSpec*: +def _spec_from_func(arena: TypeSpecArena*, ret: mlirlite.LLVMType*, params: mlirlite.ParamNode*, pcount: int) -> TypeSpec*: """函数类型 → TypeSpec(形参沿 ParamNode 链表遍历;IsVarArg 恒 0,见上)""" ret_s: TypeSpec* = SpecFromLLVMType(arena, ret) if ret_s is None: return None @@ -1175,8 +1157,7 @@ def _spec_from_func(arena: TypeSpecArena*, return NewTypeFunc(arena, ret_s, params_arr, pcount, 0) -def _spec_from_struct(arena: TypeSpecArena*, - sname: str) -> TypeSpec*: +def _spec_from_struct(arena: TypeSpecArena*, sname: str) -> TypeSpec*: """有名结构体 → 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) diff --git a/App/lib/core/Gen/VarGenMixin.vp b/App/lib/core/Gen/VarGenMixin.vp index 0f20c92..b56d7be 100644 --- a/App/lib/core/Gen/VarGenMixin.vp +++ b/App/lib/core/Gen/VarGenMixin.vp @@ -46,9 +46,7 @@ novirtual class VarGenMixin: # ============================================================ # find_var — 在变量表中按名称查找 # ============================================================ - def find_var(self, vars_ptr: GenTypes.VarEntry*, - var_count: int, - name: str) -> mlirlite.Value*: + def find_var(self, vars_ptr: GenTypes.VarEntry*, var_count: int, name: str) -> mlirlite.Value*: """在变量表中按名称查找""" if name is None or vars_ptr is None: return None entry_size: sizet = GenTypes.VarEntry.__sizeof__() @@ -63,9 +61,7 @@ novirtual class VarGenMixin: # ============================================================ # find_var_entry — 在变量表中按名称查找,返回 VarEntry(含 AnnotTy) # ============================================================ - def find_var_entry(self, vars_ptr: GenTypes.VarEntry*, - var_count: int, - name: str) -> GenTypes.VarEntry*: + def find_var_entry(self, vars_ptr: GenTypes.VarEntry*, var_count: int, name: str) -> GenTypes.VarEntry*: """在变量表中按名称查找,返回 VarEntry 或 None""" if name is None or vars_ptr is None: return None entry_size: sizet = GenTypes.VarEntry.__sizeof__() @@ -79,8 +75,7 @@ novirtual class VarGenMixin: # ============================================================ # lookup_var_entry — 从当前作用域逐级向上查找变量,返回 VarEntry # ============================================================ - def lookup_var_entry(self, symtab: rawptr[GenTypes.SymbolTable], - name: str) -> GenTypes.VarEntry*: + def lookup_var_entry(self, symtab: rawptr[GenTypes.SymbolTable], name: str) -> GenTypes.VarEntry*: """从当前作用域逐级向上查找变量,返回 VarEntry 或 None""" if symtab is None or name is None: return None scope: rawptr[GenTypes.Scope] = symtab.Current @@ -97,9 +92,7 @@ novirtual class VarGenMixin: # 方法调用检测时,当 alloca 类型是 Ptr(i8)(联合类型简化), # 通过 Spec.SourceName 查找实际结构体类型。 # ============================================================ - def set_var_annot_class_name(self, symtab: rawptr[GenTypes.SymbolTable], - name: str, - class_name: str) -> int: + def set_var_annot_class_name(self, symtab: rawptr[GenTypes.SymbolTable], name: str, class_name: str) -> int: """设置变量的原始类型注解类名(写入 Spec.SourceName),返回 0=成功 / 1=失败 [S4] 原 VarEntry.AnnotClassName 字段已删除,注解名统一承载在 Spec.SourceName: @@ -119,8 +112,7 @@ novirtual class VarGenMixin: arena_sn: TSpec.TypeSpecArena* = self.Gen.TypeGenBase.ensure_spec_arena() if arena_sn is None: return 1 if entry.Spec is None: - entry.Spec = TSpec.NewTypeSpec(arena_sn, TSpec.TS_UNKNOWN, 0, - TSpec.TS_SIGN_UNKNOWN) + entry.Spec = TSpec.NewTypeSpec(arena_sn, TSpec.TS_UNKNOWN, 0, TSpec.TS_SIGN_UNKNOWN) if entry.Spec is None: return 1 sign: int = self.Gen.TypeGenCType.spec_sign_of_annot(class_name) if sign != TSpec.TS_SIGN_UNKNOWN: entry.Spec = TSpec.SpecWithSign(arena_sn, entry.Spec, sign) @@ -145,8 +137,7 @@ novirtual class VarGenMixin: # 该语义由 Spec.ElemBits 承载:上述四类在 LLVM 层都是 Ptr(Int8)(ElemBits=8, # 无法区分),故注解侧把元素槽宽覆盖为 8 字节,消费点经 var_is_ptr_element 读取。 # 由 AnnAssign 按注解形式(_is_ptr_element_annotation)调用。 - def set_var_ptr_element(self, symtab: rawptr[GenTypes.SymbolTable], - name: str) -> int: + def set_var_ptr_element(self, symtab: rawptr[GenTypes.SymbolTable], name: str) -> int: """标记变量为 ptr-element(Spec.ElemBits=64),返回 0=成功 / 1=失败""" if symtab is None or name is None: return 1 entry: GenTypes.VarEntry* = self.lookup_var_entry(symtab, name) @@ -177,8 +168,7 @@ novirtual class VarGenMixin: # 语义对齐 C 的 volatile 限定:该变量的每次 load/store 都带 LLVM volatile, # 禁止优化器把忙等循环中的重复 load 提升/消除。由注解侧 # (模块级已注册后 / 局部声明时)调用。 - def set_var_volatile(self, symtab: rawptr[GenTypes.SymbolTable], - name: str) -> int: + def set_var_volatile(self, symtab: rawptr[GenTypes.SymbolTable], name: str) -> int: """标记变量为 volatile(VarEntry.IsVolatile=1),返回 0=成功 / 1=失败""" if symtab is None or name is None: return 1 entry: GenTypes.VarEntry* = self.lookup_var_entry(symtab, name) @@ -197,8 +187,7 @@ novirtual class VarGenMixin: # 语义对齐 C 的 volatile 限定(作用于 pointee 而非指针自身):解引用 # (p[i] / p.field / c.Deref(p))的每次 load/store 都带 LLVM volatile, # 禁止优化器重排序/消除对所指对象的访问。由注解侧在登记变量时调用。 - def set_var_pointee_volatile(self, symtab: rawptr[GenTypes.SymbolTable], - name: str) -> int: + def set_var_pointee_volatile(self, symtab: rawptr[GenTypes.SymbolTable], name: str) -> int: """标记变量所指物为 volatile(VarEntry.PointeeVolatile=1),返回 0=成功 / 1=失败""" if symtab is None or name is None: return 1 entry: GenTypes.VarEntry* = self.lookup_var_entry(symtab, name) @@ -217,8 +206,7 @@ novirtual class VarGenMixin: # (见 Debugger/type-descriptors.md「两侧语义对照表」)。整个作用域内禁止对 # 该变量名赋值 / 增量赋值 / 元素赋值;由注解侧(模块级已注册后 / 局部声明时 / # 形参声明时)调用。 - def set_var_const(self, symtab: rawptr[GenTypes.SymbolTable], - name: str) -> int: + def set_var_const(self, symtab: rawptr[GenTypes.SymbolTable], name: str) -> int: """标记变量为 const 对象(VarEntry.IsConst=1),返回 0=成功 / 1=失败""" if symtab is None or name is None: return 1 entry: GenTypes.VarEntry* = self.lookup_var_entry(symtab, name) @@ -235,10 +223,7 @@ novirtual class VarGenMixin: # ============================================================ # add_var — 添加变量到变量表 # ============================================================ - def add_var(self, vars_ptr: GenTypes.VarEntry*, - var_count: int, - name: str, - alloca: mlirlite.Value*) -> int: + def add_var(self, vars_ptr: GenTypes.VarEntry*, var_count: int, name: str, alloca: mlirlite.Value*) -> int: """添加变量到变量表""" if name is None or alloca is None or vars_ptr is None: return 1 if var_count >= HT.MAX_VARS: return 1 @@ -284,8 +269,7 @@ novirtual class VarGenMixin: # _alloca_at_entry - 在函数入口块生成 alloca(确保支配性) # LLVM IR 要求指令支配所有使用点,故所有 alloca 须在函数入口块生成。 # 实现:临时切换 builder.CurBlock 到入口块,生成 alloca 后恢复。 - def _alloca_at_entry(self, builder: mlirlite.IRBuilder*, - ty: mlirlite.LLVMType*) -> mlirlite.Value*: + def _alloca_at_entry(self, builder: mlirlite.IRBuilder*, ty: mlirlite.LLVMType*) -> mlirlite.Value*: """在函数入口块生成 alloca,返回 alloca 值 使用 mlirlite.build_alloca_at_entry 在入口块终止指令之前插入 alloca, @@ -295,12 +279,7 @@ novirtual class VarGenMixin: return mlirlite.build_alloca_at_entry(builder, ty) # get_or_create_var — 查找或创建变量 alloca(旧版兼容) - def get_or_create_var(self, pool: memhub.MemBuddy*, - builder: mlirlite.IRBuilder*, - vars_ptr: GenTypes.VarEntry*, - var_count: int, - name: str, - ty: mlirlite.LLVMType*) -> mlirlite.Value*: + def get_or_create_var(self, pool: memhub.MemBuddy*, builder: mlirlite.IRBuilder*, vars_ptr: GenTypes.VarEntry*, var_count: int, name: str, ty: mlirlite.LLVMType*) -> mlirlite.Value*: """查找或创建变量 alloca""" existing: mlirlite.Value* = self.find_var(vars_ptr, var_count, name) if existing is not None: return existing @@ -312,9 +291,7 @@ novirtual class VarGenMixin: # ============================================================ # _create_scope — 创建新作用域节点(内部辅助函数) # ============================================================ - def _create_scope(self, pool: memhub.MemBuddy*, - parent: rawptr[GenTypes.Scope], - kind: int) -> rawptr[GenTypes.Scope]: + def _create_scope(self, pool: memhub.MemBuddy*, parent: rawptr[GenTypes.Scope], kind: int) -> rawptr[GenTypes.Scope]: """创建并初始化作用域节点""" scope: rawptr[GenTypes.Scope] = pool.alloc(GenTypes.Scope.__sizeof__()) if scope is None: return None @@ -348,8 +325,7 @@ novirtual class VarGenMixin: # ============================================================ # enter_scope — 进入新作用域 # ============================================================ - def enter_scope(self, symtab: rawptr[GenTypes.SymbolTable], - kind: int) -> rawptr[GenTypes.Scope]: + def enter_scope(self, symtab: rawptr[GenTypes.SymbolTable], kind: int) -> rawptr[GenTypes.Scope]: """进入新作用域,返回新创建的作用域""" if symtab is None: return None pool: memhub.MemBuddy* = symtab.Pool @@ -368,9 +344,7 @@ novirtual class VarGenMixin: # ============================================================ # define_var — 在当前作用域定义变量 # ============================================================ - def define_var(self, symtab: rawptr[GenTypes.SymbolTable], - name: str, - alloca: mlirlite.Value*) -> int: + def define_var(self, symtab: rawptr[GenTypes.SymbolTable], name: str, alloca: mlirlite.Value*) -> int: """在当前作用域定义变量,返回 0 成功""" if symtab is None or name is None or alloca is None: return 1 scope: rawptr[GenTypes.Scope] = symtab.Current @@ -382,9 +356,7 @@ novirtual class VarGenMixin: # ============================================================ # define_module_var — 在模块作用域定义变量 # ============================================================ - def define_module_var(self, symtab: rawptr[GenTypes.SymbolTable], - name: str, - alloca: mlirlite.Value*) -> int: + def define_module_var(self, symtab: rawptr[GenTypes.SymbolTable], name: str, alloca: mlirlite.Value*) -> int: """在模块作用域定义变量,返回 0 成功""" if symtab is None or name is None or alloca is None: return 1 scope: rawptr[GenTypes.Scope] = symtab.Root @@ -396,8 +368,7 @@ novirtual class VarGenMixin: # ============================================================ # lookup_var — 从当前作用域逐级向上查找变量 # ============================================================ - def lookup_var(self, symtab: rawptr[GenTypes.SymbolTable], - name: str) -> mlirlite.Value*: + def lookup_var(self, symtab: rawptr[GenTypes.SymbolTable], name: str) -> mlirlite.Value*: """从当前作用域逐级向上查找变量,返回 alloca 或 None""" if symtab is None or name is None: return None scope: rawptr[GenTypes.Scope] = symtab.Current @@ -410,8 +381,7 @@ novirtual class VarGenMixin: # ============================================================ # lookup_current — 仅在当前作用域查找变量 # ============================================================ - def lookup_current(self, symtab: rawptr[GenTypes.SymbolTable], - name: str) -> mlirlite.Value*: + def lookup_current(self, symtab: rawptr[GenTypes.SymbolTable], name: str) -> mlirlite.Value*: """仅在当前作用域查找变量""" if symtab is None or name is None: return None scope: rawptr[GenTypes.Scope] = symtab.Current @@ -421,8 +391,7 @@ novirtual class VarGenMixin: # ============================================================ # lookup_module_var — 在模块作用域查找变量 # ============================================================ - def lookup_module_var(self, symtab: rawptr[GenTypes.SymbolTable], - name: str) -> mlirlite.Value*: + def lookup_module_var(self, symtab: rawptr[GenTypes.SymbolTable], name: str) -> mlirlite.Value*: """在模块作用域查找变量""" if symtab is None or name is None: return None scope: rawptr[GenTypes.Scope] = symtab.Root @@ -448,8 +417,7 @@ novirtual class VarGenMixin: return 0 # _lookup_through_match_scope — 穿越 match case 作用域查找变量 - def _lookup_through_match_scope(self, symtab: rawptr[GenTypes.SymbolTable], - name: str) -> mlirlite.Value*: + def _lookup_through_match_scope(self, symtab: rawptr[GenTypes.SymbolTable], name: str) -> mlirlite.Value*: """从当前作用域向上,仅穿越 SCOPE_MATCH 作用域查找变量 alloca""" if symtab is None or name is None: return None scope: rawptr[GenTypes.Scope] = symtab.Current @@ -465,11 +433,7 @@ novirtual class VarGenMixin: # ============================================================ # get_or_create_sym — 查找或创建变量(在当前作用域) # ============================================================ - def get_or_create_sym(self, symtab: rawptr[GenTypes.SymbolTable], - pool: memhub.MemBuddy*, - builder: mlirlite.IRBuilder*, - name: str, - ty: mlirlite.LLVMType*) -> mlirlite.Value*: + def get_or_create_sym(self, symtab: rawptr[GenTypes.SymbolTable], pool: memhub.MemBuddy*, builder: mlirlite.IRBuilder*, name: str, ty: mlirlite.LLVMType*) -> mlirlite.Value*: """查找或创建变量 alloca(在当前作用域)""" existing: mlirlite.Value* = self.lookup_current(symtab, name) if existing is not None: return existing @@ -524,9 +488,7 @@ novirtual class VarGenMixin: return 0 # ---- repl_ctx_ptr — 取片段函数 ctx 形参的值(i8*) ---- - def repl_ctx_ptr(self, trans: HT.Translator*, - ctx: rawptr[GenTypes.ReplCtx], - node: ast.AST*) -> mlirlite.Value*: + def repl_ctx_ptr(self, trans: HT.Translator*, ctx: rawptr[GenTypes.ReplCtx], node: ast.AST*) -> mlirlite.Value*: """load 片段函数 ctx 形参(形参 alloca 由 FuncGenDef 建);失败 fail-fast""" if trans is None or ctx is None or ctx.CtxParam is None: return None symtab: rawptr[GenTypes.SymbolTable] = trans.SymTab @@ -564,8 +526,7 @@ novirtual class VarGenMixin: return 1 # ---- repl_find_func_entry — 会话函数表按名查找(M3) ---- - def repl_find_func_entry(self, ctx: rawptr[GenTypes.ReplCtx], - name: str) -> rawptr[GenTypes.ReplFuncEntry]: + def repl_find_func_entry(self, ctx: rawptr[GenTypes.ReplCtx], name: str) -> rawptr[GenTypes.ReplFuncEntry]: """在会话函数表中按名查找;ctx 无效/未登记返回 None(只读,不改表)""" if ctx is None or name is None: return None if ctx.Marker != GenTypes.REPL_CTX_MARKER: return None @@ -582,8 +543,7 @@ novirtual class VarGenMixin: # token 由宿主在注册期从定义片段的 IR define 行解析而来(唯一 ABI 真相), # 只允许可往返重建的集合:iN(N=1/8/16/32/64) / float / double / i8*。 # 其余 token(含 REPL_TY_PTR / REPL_TY_STRUCT)返回 None ⇒ 调用点明确报错。 - def repl_func_ty(self, pool: memhub.MemBuddy*, - tag: int, bits: int) -> mlirlite.LLVMType*: + def repl_func_ty(self, pool: memhub.MemBuddy*, tag: int, bits: int) -> mlirlite.LLVMType*: """签名 token → LLVM 类型;不支持的 token 返回 None""" if pool is None: return None if tag == GenTypes.REPL_TY_INT: return self.repl_scalar_ty(pool, bits, 0) @@ -612,16 +572,7 @@ novirtual class VarGenMixin: # h1_hit 同款):命中后(含命中但报错)置 1,使调用方"已处理"而不是继续走 # "裸名调用未定义且未导入"的 fail-fast 或搭上别的解析路径。 # 守卫:调用方只在 trans.ReplCtx is not None 时调用;非 REPL 恒不进入。 - def repl_try_session_func_call(self, trans: HT.Translator*, - pool: memhub.MemBuddy*, - builder: mlirlite.IRBuilder*, - mod: mlirlite.LLVMModule*, - func_name: str, - cargs: list[ast.AST*]*, - can: int, - kw_count: int, - node: ast.AST*, - hit: t.CPtr) -> mlirlite.Value*: + def repl_try_session_func_call(self, trans: HT.Translator*, pool: memhub.MemBuddy*, builder: mlirlite.IRBuilder*, mod: mlirlite.LLVMModule*, func_name: str, cargs: list[ast.AST*]*, can: int, kw_count: int, node: ast.AST*, hit: t.CPtr) -> mlirlite.Value*: """会话函数调用:命中返回 call 结果(void 函数返回 None 但 hit 已置 1)""" if trans is None or trans.ReplCtx is None or pool is None or builder is None: return None if func_name is None or hit is None: return None @@ -722,11 +673,7 @@ novirtual class VarGenMixin: return mlirlite.build_call_indirect(builder, fn_typed, head, arg_count, ret_ty) # ---- repl_slot_ptr — 槽地址(ctx + off 的字节 GEP 后 bitcast 成 Ptr(val_ty)) ---- - def repl_slot_ptr(self, pool: memhub.MemBuddy*, - builder: mlirlite.IRBuilder*, - ctx_val: mlirlite.Value*, - off: int, - val_ty: mlirlite.LLVMType*) -> mlirlite.Value*: + def repl_slot_ptr(self, pool: memhub.MemBuddy*, builder: mlirlite.IRBuilder*, ctx_val: mlirlite.Value*, off: int, val_ty: mlirlite.LLVMType*) -> mlirlite.Value*: """返回槽指针(Ptr(val_ty));参数不完整返回 None 用 i8 步长 GEP 做纯字节偏移(同 list_getitem_inline 的既有做法), @@ -746,8 +693,7 @@ novirtual class VarGenMixin: return mlirlite.build_bitcast(builder, base, target_ptr_ty) # ---- repl_scalar_ty — 位宽 → LLVM 标量类型 ---- - def repl_scalar_ty(self, pool: memhub.MemBuddy*, - bits: int, is_float: int) -> mlirlite.LLVMType*: + def repl_scalar_ty(self, pool: memhub.MemBuddy*, bits: int, is_float: int) -> mlirlite.LLVMType*: """按位宽还原 LLVM 标量类型;不支持的位宽返回 None""" if is_float != 0: if bits == 32: return mlirlite.Float(pool) @@ -761,8 +707,7 @@ novirtual class VarGenMixin: return None # ---- repl_llvm_ty — 条目 → LLVM 值类型(结构体按名重解析) ---- - def repl_llvm_ty(self, pool: memhub.MemBuddy*, - entry: rawptr[GenTypes.ReplVarEntry]) -> mlirlite.LLVMType*: + def repl_llvm_ty(self, pool: memhub.MemBuddy*, entry: rawptr[GenTypes.ReplVarEntry]) -> mlirlite.LLVMType*: """条目反推 LLVM 值类型;未定型/结构体类型不可解析返回 None TyTag=STRUCT 时返回结构体**值**类型(内联存槽,槽类型即它本身)。 @@ -789,8 +734,7 @@ novirtual class VarGenMixin: return None # ---- repl_slot_ty — 槽内存放的值类型 ---- - def repl_slot_ty(self, pool: memhub.MemBuddy*, - entry: rawptr[GenTypes.ReplVarEntry]) -> mlirlite.LLVMType*: + def repl_slot_ty(self, pool: memhub.MemBuddy*, entry: rawptr[GenTypes.ReplVarEntry]) -> mlirlite.LLVMType*: """槽内存放的值类型 = 条目的值类型本身(标量/指针/结构体值都内联在槽里) 结构体值另有体积约束:尺寸 > REPL_SLOT_SIZE 或对齐 > REPL_SLOT_SIZE 时 @@ -886,10 +830,7 @@ novirtual class VarGenMixin: return off # ---- repl_seal — 首次定型(已定型则校验类型标签一致) ---- - def repl_seal(self, trans: HT.Translator*, - entry: rawptr[GenTypes.ReplVarEntry], - val_ty: mlirlite.LLVMType*, - node: ast.AST*) -> int: + def repl_seal(self, trans: HT.Translator*, entry: rawptr[GenTypes.ReplVarEntry], val_ty: mlirlite.LLVMType*, node: ast.AST*) -> int: """按 val_ty 给条目定型;返回 0=成功(含幂等命中)/ 1=不支持或冲突(已 fail-fast) 规则: @@ -945,27 +886,17 @@ novirtual class VarGenMixin: sz: int = self.repl_type_size(val_ty) al: int = self.repl_type_align(val_ty) if sz <= 0 or al <= 0: - self.Gen.TypeGenErr.fatal_error(node, - f"REPL: 会话变量 '{entry.Name}' 的结构体值 '{sname}' 尺寸/对齐未知" - f"(无法判定能否放入 {GenTypes.REPL_SLOT_SIZE} 字节槽)", - "TypeError") + self.Gen.TypeGenErr.fatal_error(node, f"REPL: 会话变量 '{entry.Name}' 的结构体值 '{sname}' 尺寸/对齐未知" f"(无法判定能否放入 {GenTypes.REPL_SLOT_SIZE} 字节槽)", "TypeError") return 1 if sz > GenTypes.REPL_SLOT_SIZE or al > GenTypes.REPL_SLOT_SIZE: - self.Gen.TypeGenErr.fatal_error(node, - f"REPL: 会话变量 '{entry.Name}' 的结构体值 '{sname}' 体积 {sz} 字节、" - f"对齐 {al} 字节,无法放入 {GenTypes.REPL_SLOT_SIZE} 字节槽" - f"(M2 结构体值须内联进槽;大对象请改用对象指针/堆分配)", - "TypeError") + self.Gen.TypeGenErr.fatal_error(node, f"REPL: 会话变量 '{entry.Name}' 的结构体值 '{sname}' 体积 {sz} 字节、" f"对齐 {al} 字节,无法放入 {GenTypes.REPL_SLOT_SIZE} 字节槽" f"(M2 结构体值须内联进槽;大对象请改用对象指针/堆分配)", "TypeError") return 1 tag = GenTypes.REPL_TY_STRUCT bits = sz * 8 kind = GenTypes.REPL_KIND_SCALAR tname = sname else: - self.Gen.TypeGenErr.fatal_error(node, - f"REPL: 会话变量 '{entry.Name}' 的类型暂不支持" - f"(M2 支持 int/bool/浮点/str/bytes/指针/结构体值)", - "TypeError") + self.Gen.TypeGenErr.fatal_error(node, f"REPL: 会话变量 '{entry.Name}' 的类型暂不支持" f"(M2 支持 int/bool/浮点/str/bytes/指针/结构体值)", "TypeError") return 1 if entry.Kind == GenTypes.REPL_KIND_UNTYPED: entry.Kind = kind @@ -975,17 +906,13 @@ novirtual class VarGenMixin: if tname is not None: entry.TyName = self.repl_perm_strdup(perm, tname) return 0 if entry.Kind != kind or entry.TyTag != tag: - self.Gen.TypeGenErr.fatal_error(node, - f"REPL: 会话变量 '{entry.Name}' 已定型为 {self.repl_tag_label(entry.TyTag, entry.Bits)}," - f"不能再赋成 {self.repl_tag_label(tag, bits)}(如需换型请重启会话)", - "TypeError") + self.Gen.TypeGenErr.fatal_error(node, f"REPL: 会话变量 '{entry.Name}' 已定型为 {self.repl_tag_label(entry.TyTag, entry.Bits)}," f"不能再赋成 {self.repl_tag_label(tag, bits)}(如需换型请重启会话)", "TypeError") return 1 if tname is not None and entry.TyName is None: entry.TyName = self.repl_perm_strdup(perm, tname) return 0 # ---- repl_perm_strdup — 深拷贝到 PermPool(跨片段存活) ---- - def repl_perm_strdup(self, pool: memhub.MemBuddy*, - s: str) -> str: + def repl_perm_strdup(self, pool: memhub.MemBuddy*, s: str) -> str: """把 s 深拷贝进 pool(调用方传 PermPool)供会话表长期持有;失败返回 None""" if s is None or pool is None: return None n: sizet = string.strlen(s) @@ -1018,9 +945,7 @@ novirtual class VarGenMixin: # 分配时机:片段翻译期(translate_assign / translate_annassign 的 Name 目标 # 在局部表未命中时)。表满 ⇒ 明确报错(fail-fast,经 M0 setjmp 恢复点继续 # 下一行),不静默丢弃。 - def repl_ensure_entry(self, trans: HT.Translator*, - name: str, - node: ast.AST*) -> rawptr[GenTypes.ReplVarEntry]: + def repl_ensure_entry(self, trans: HT.Translator*, name: str, node: ast.AST*) -> rawptr[GenTypes.ReplVarEntry]: """按名取条目,未登记则分配槽位并登记;失败返回 None(已 fail-fast)""" if trans is None or name is None: return None ctx: rawptr[GenTypes.ReplCtx] = trans.ReplCtx @@ -1031,10 +956,7 @@ novirtual class VarGenMixin: self.Gen.TypeGenErr.fatal_error(node, "REPL: 会话变量表未初始化(宿主未建 ctx)", "InternalCompilerError") return None if ctx.Count >= ctx.Cap: - self.Gen.TypeGenErr.fatal_error(node, - f"REPL: 会话变量已达上限 {ctx.Cap} 个(ctx 槽位用尽)," - f"无法为 '{name}' 再分配槽位;请重启会话", - "ResourceError") + self.Gen.TypeGenErr.fatal_error(node, f"REPL: 会话变量已达上限 {ctx.Cap} 个(ctx 槽位用尽)," f"无法为 '{name}' 再分配槽位;请重启会话", "ResourceError") return None perm: memhub.MemBuddy* = self.repl_perm_pool(trans) if perm is None: @@ -1063,11 +985,7 @@ novirtual class VarGenMixin: return trans.ReplCtx.Perm # ---- repl_emit_result — 把本片段结果写入 ctx 结果区 ---- - def repl_emit_result(self, trans: HT.Translator*, - ctx_val: mlirlite.Value*, - val: mlirlite.Value*, - tag: int, bits: int, - node: ast.AST* = None) -> int: + def repl_emit_result(self, trans: HT.Translator*, ctx_val: mlirlite.Value*, val: mlirlite.Value*, tag: int, bits: int, node: ast.AST* = None) -> int: """按 tag 把 val 写入 ctx 结果区(见 GenTypes 的 result_kind 表);0=成功 tag: REPL_TY_INT/FLOAT/STR/PTR/STRUCT。 @@ -1087,8 +1005,7 @@ novirtual class VarGenMixin: if tag == GenTypes.REPL_TY_INT: iv: mlirlite.Value* = self.Gen.ExprGenBase.coerce_to_type(builder, val, i64_ty, node, trans) if iv is None: return 1 - if self._repl_store_res_i32(trans, ctx_val, GenTypes.REPL_RES_KIND_OFF, - GenTypes.REPL_RES_INT) != 0: + if self._repl_store_res_i32(trans, ctx_val, GenTypes.REPL_RES_KIND_OFF, GenTypes.REPL_RES_INT) != 0: return 1 if self._repl_store_res_i64(trans, ctx_val, GenTypes.REPL_RES_A_OFF, iv) != 0: return 1 return self._repl_store_res_i64(trans, ctx_val, GenTypes.REPL_RES_B_OFF, zero64) @@ -1098,8 +1015,7 @@ novirtual class VarGenMixin: # double → i64 位模式(bitcast,不做数值转换):宿主按位重解释回 double dbits: mlirlite.Value* = mlirlite.build_bitcast(builder, dv, i64_ty) if dbits is None: return 1 - if self._repl_store_res_i32(trans, ctx_val, GenTypes.REPL_RES_KIND_OFF, - GenTypes.REPL_RES_FLOAT) != 0: + if self._repl_store_res_i32(trans, ctx_val, GenTypes.REPL_RES_KIND_OFF, GenTypes.REPL_RES_FLOAT) != 0: return 1 if self._repl_store_res_i64(trans, ctx_val, GenTypes.REPL_RES_A_OFF, dbits) != 0: return 1 return self._repl_store_res_i64(trans, ctx_val, GenTypes.REPL_RES_B_OFF, zero64) @@ -1115,26 +1031,21 @@ novirtual class VarGenMixin: if pbits is None: return 1 kind: int = GenTypes.REPL_RES_OBJ if tag == GenTypes.REPL_TY_STR: kind = GenTypes.REPL_RES_STR - if self._repl_store_res_i32(trans, ctx_val, GenTypes.REPL_RES_KIND_OFF, - kind) != 0: + if self._repl_store_res_i32(trans, ctx_val, GenTypes.REPL_RES_KIND_OFF, kind) != 0: return 1 if self._repl_store_res_i64(trans, ctx_val, GenTypes.REPL_RES_A_OFF, pbits) != 0: return 1 return self._repl_store_res_i64(trans, ctx_val, GenTypes.REPL_RES_B_OFF, zero64) if tag == GenTypes.REPL_TY_STRUCT: # 结构体值:内联在会话槽里,值本身没有地址 ⇒ 结果区只报"类别" # (kind=4 且 result_a=0;宿主据此打印 ) - if self._repl_store_res_i32(trans, ctx_val, GenTypes.REPL_RES_KIND_OFF, - GenTypes.REPL_RES_OBJ) != 0: + if self._repl_store_res_i32(trans, ctx_val, GenTypes.REPL_RES_KIND_OFF, GenTypes.REPL_RES_OBJ) != 0: return 1 if self._repl_store_res_i64(trans, ctx_val, GenTypes.REPL_RES_A_OFF, zero64) != 0: return 1 return self._repl_store_res_i64(trans, ctx_val, GenTypes.REPL_RES_B_OFF, zero64) return 1 # ---- _repl_store_res_i64 / _repl_store_res_i32 — 结果区某偏移写定宽常量/值 ---- - def _repl_store_res_i64(self, trans: HT.Translator*, - ctx_val: mlirlite.Value*, - off: int, - val: mlirlite.Value*) -> int: + def _repl_store_res_i64(self, trans: HT.Translator*, ctx_val: mlirlite.Value*, off: int, val: mlirlite.Value*) -> int: """把 i64 值写到 ctx 结果区的 off 偏移(0=成功)""" if trans is None or ctx_val is None or val is None: return 1 pool: memhub.MemBuddy* = trans.Pool @@ -1144,10 +1055,7 @@ novirtual class VarGenMixin: mlirlite.build_store(builder, val, slot) return 0 - def _repl_store_res_i32(self, trans: HT.Translator*, - ctx_val: mlirlite.Value*, - off: int, - val: int) -> int: + def _repl_store_res_i32(self, trans: HT.Translator*, ctx_val: mlirlite.Value*, off: int, val: int) -> int: """把 i32 常量写到 ctx 结果区的 off 偏移(kind / var_count 等,0=成功)""" if trans is None or ctx_val is None: return 1 pool: memhub.MemBuddy* = trans.Pool @@ -1161,9 +1069,7 @@ novirtual class VarGenMixin: return 0 # ---- repl_try_read — 会话变量读取(命中返回 load 值,未命中返回 None) ---- - def repl_try_read(self, trans: HT.Translator*, - name: str, - node: ast.AST*) -> mlirlite.Value*: + def repl_try_read(self, trans: HT.Translator*, name: str, node: ast.AST*) -> mlirlite.Value*: """REPL 会话变量读:命中返回槽内值(结构体返回盒子地址);否则 None 返回 None 表示"不是会话变量",调用方继续原有查找/报错路径。 @@ -1173,18 +1079,12 @@ novirtual class VarGenMixin: if entry is None: return None if self.repl_in_frag_scope(trans.SymTab) == 0: return None if entry.Kind == GenTypes.REPL_KIND_UNTYPED: - self.Gen.TypeGenErr.fatal_error(node, - f"REPL: 会话变量 '{name}' 尚未赋值(未定型,先执行一条 'x = ...' 或 'x: int = ...')", - "NameError") + self.Gen.TypeGenErr.fatal_error(node, f"REPL: 会话变量 '{name}' 尚未赋值(未定型,先执行一条 'x = ...' 或 'x: int = ...')", "NameError") return None pool: memhub.MemBuddy* = trans.Pool slot_ty: mlirlite.LLVMType* = self.repl_slot_ty(pool, entry) if slot_ty is None: - self.Gen.TypeGenErr.fatal_error(node, - f"REPL: 会话变量 '{name}' 的类型 " - f"{self.repl_tag_label(entry.TyTag, entry.Bits)} 在当前片段不可用" - f"(跨片段类型可见性属 M4)", - "NameError") + self.Gen.TypeGenErr.fatal_error(node, f"REPL: 会话变量 '{name}' 的类型 " f"{self.repl_tag_label(entry.TyTag, entry.Bits)} 在当前片段不可用" f"(跨片段类型可见性属 M4)", "NameError") return None ctx_val: mlirlite.Value* = self.repl_ctx_ptr(trans, trans.ReplCtx, node) if ctx_val is None: return None @@ -1195,9 +1095,7 @@ novirtual class VarGenMixin: return mlirlite.build_load(trans._cur_builder, slot_ty, slot) # ---- repl_try_addr — 会话变量取址(c.Addr(x) → ctx 槽地址) ---- - def repl_try_addr(self, trans: HT.Translator*, - name: str, - node: ast.AST*) -> mlirlite.Value*: + def repl_try_addr(self, trans: HT.Translator*, name: str, node: ast.AST*) -> mlirlite.Value*: """会话变量取址:返回槽地址(Ptr(值类型)) 值只存一份(宿主持有的 ctx arena)且内联在槽里,故 &x 得到的 @@ -1209,16 +1107,12 @@ novirtual class VarGenMixin: if entry is None: return None if self.repl_in_frag_scope(trans.SymTab) == 0: return None if entry.Kind == GenTypes.REPL_KIND_UNTYPED: - self.Gen.TypeGenErr.fatal_error(node, - f"REPL: 会话变量 '{name}' 尚未赋值(未定型),无法取址(c.Addr)", - "NameError") + self.Gen.TypeGenErr.fatal_error(node, f"REPL: 会话变量 '{name}' 尚未赋值(未定型),无法取址(c.Addr)", "NameError") return None pool: memhub.MemBuddy* = trans.Pool slot_ty: mlirlite.LLVMType* = self.repl_slot_ty(pool, entry) if slot_ty is None: - self.Gen.TypeGenErr.fatal_error(node, - f"REPL: 会话变量 '{name}' 的类型在当前片段不可用(跨片段类型可见性属 M4)", - "NameError") + self.Gen.TypeGenErr.fatal_error(node, f"REPL: 会话变量 '{name}' 的类型在当前片段不可用(跨片段类型可见性属 M4)", "NameError") return None ctx_val: mlirlite.Value* = self.repl_ctx_ptr(trans, trans.ReplCtx, node) if ctx_val is None: return None @@ -1230,11 +1124,7 @@ novirtual class VarGenMixin: return slot # ---- repl_store_slot — 定型后的值写槽(并把该值写入结果区) ---- - def repl_store_slot(self, trans: HT.Translator*, - entry: rawptr[GenTypes.ReplVarEntry], - ctx_val: mlirlite.Value*, - rhs_val: mlirlite.Value*, - node: ast.AST*) -> int: + def repl_store_slot(self, trans: HT.Translator*, entry: rawptr[GenTypes.ReplVarEntry], ctx_val: mlirlite.Value*, rhs_val: mlirlite.Value*, node: ast.AST*) -> int: """coerce 到槽类型 → 写槽 → 写结果区;0=成功(失败已 fail-fast) 槽内一律"值本身"(标量/指针/≤16B 结构体值内联),无装箱间接层 ⇒ @@ -1245,17 +1135,11 @@ novirtual class VarGenMixin: builder: mlirlite.IRBuilder* = trans._cur_builder slot_ty: mlirlite.LLVMType* = self.repl_slot_ty(pool, entry) if slot_ty is None: - self.Gen.TypeGenErr.fatal_error(node, - f"REPL: 会话变量 '{entry.Name}' 的槽类型不可用" - f"(类型在当前片段不可解析,或结构体值体积超出槽容量)", - "TypeError") + self.Gen.TypeGenErr.fatal_error(node, f"REPL: 会话变量 '{entry.Name}' 的槽类型不可用" f"(类型在当前片段不可解析,或结构体值体积超出槽容量)", "TypeError") return 1 store_val: mlirlite.Value* = self.Gen.ExprGenBase.coerce_to_type(builder, rhs_val, slot_ty, node, trans) if store_val is None: - self.Gen.TypeGenErr.fatal_error(node, - f"REPL: 会话变量 '{entry.Name}' 无法把右侧值转换为" - f" {self.repl_tag_label(entry.TyTag, entry.Bits)}", - "CastError") + self.Gen.TypeGenErr.fatal_error(node, f"REPL: 会话变量 '{entry.Name}' 无法把右侧值转换为" f" {self.repl_tag_label(entry.TyTag, entry.Bits)}", "CastError") return 1 if self.Gen.ExprGenBase.is_ptr_type(slot_ty) != 0 and store_val.Ty is not None and self.Gen.ExprGenBase.is_ptr_type(store_val.Ty) != 0 and self.Gen.AssignGen._stg_ty_equal(pool, store_val.Ty, slot_ty) == 0: # 指针同型化(槽类型与右侧指针可能不是同一类型实例;位宽相同)。 @@ -1273,11 +1157,7 @@ novirtual class VarGenMixin: return 0 # ---- repl_try_assign — 会话变量赋值(命中返回 1) ---- - def repl_try_assign(self, trans: HT.Translator*, - name: str, - rhs_val: mlirlite.Value*, - rhs_node: ast.AST*, - node: ast.AST*) -> int: + def repl_try_assign(self, trans: HT.Translator*, name: str, rhs_val: mlirlite.Value*, rhs_node: ast.AST*, node: ast.AST*) -> int: """REPL 会话变量赋值:命中(已登记 + 在**片段入口函数**本体)返回 1,否则 0 命中路径:定型 → coerce 到条目类型 → 写槽 → 写结果区。 @@ -1299,11 +1179,7 @@ novirtual class VarGenMixin: return 1 # ---- repl_try_annassign — 会话变量带注解声明/赋值(命中返回 1) ---- - def repl_try_annassign(self, trans: HT.Translator*, - name: str, - annot_node: ast.AST*, - value_node: ast.AST*, - node: ast.AST*) -> int: + def repl_try_annassign(self, trans: HT.Translator*, name: str, annot_node: ast.AST*, value_node: ast.AST*, node: ast.AST*) -> int: """REPL 会话变量注解路径:x: int = 1 / x: int(仅定型) 注解先解析并定型条目,再用定型后的类型作为 RHS 的 target_ty(与普通 @@ -1325,10 +1201,7 @@ novirtual class VarGenMixin: self.Gen.AssignGen._prespecialize_generic_annotation(trans, pool, annot_node) annot_ty: mlirlite.LLVMType* = self.Gen.TypeGenResolve.resolve_annotation_type(pool, annot_node, trans._imported_modules, trans._from_imports, trans, 0) if annot_ty is None: - self.Gen.TypeGenErr.fatal_error(node, - f"REPL: 会话变量 '{name}' 的类型注解解析失败" - f"(片段无 import;仅内建名 int/str/bytes/bool/float/double/char 等可解析)", - "NameError") + self.Gen.TypeGenErr.fatal_error(node, f"REPL: 会话变量 '{name}' 的类型注解解析失败" f"(片段无 import;仅内建名 int/str/bytes/bool/float/double/char 等可解析)", "NameError") return 1 if self.repl_seal(trans, entry, annot_ty, node) != 0: return 1 if value_node is None: @@ -1350,11 +1223,7 @@ novirtual class VarGenMixin: return 1 # ---- repl_try_augassign — 会话变量增强赋值(命中返回 1) ---- - def repl_try_augassign(self, trans: HT.Translator*, - name: str, - op: int, - rhs_node: ast.AST*, - node: ast.AST*) -> int: + def repl_try_augassign(self, trans: HT.Translator*, name: str, op: int, rhs_node: ast.AST*, node: ast.AST*) -> int: """REPL 会话变量 x += v:读槽 → 二元运算 → 写槽 → 写结果(命中返回 1) 作用域判据用 repl_in_frag_entry_scope(M3):被提升的会话函数体内 @@ -1367,9 +1236,7 @@ novirtual class VarGenMixin: pool: memhub.MemBuddy* = trans.Pool builder: mlirlite.IRBuilder* = trans._cur_builder if entry.TyTag == GenTypes.REPL_TY_STRUCT: - self.Gen.TypeGenErr.fatal_error(node, - f"REPL: 会话变量 '{name}' 是结构体值,不支持增强赋值", - "TypeError") + self.Gen.TypeGenErr.fatal_error(node, f"REPL: 会话变量 '{name}' 是结构体值,不支持增强赋值", "TypeError") return 1 cur_val: mlirlite.Value* = self.repl_try_read(trans, name, node) if cur_val is None: return 1 @@ -1385,8 +1252,7 @@ novirtual class VarGenMixin: return self.repl_try_assign(trans, name, result, node, node) # ---- repl_expr_result — 片段内裸表达式语句的结果回传 ---- - def repl_expr_result(self, trans: HT.Translator*, - value_node: ast.AST*) -> int: + def repl_expr_result(self, trans: HT.Translator*, value_node: ast.AST*) -> int: """REPL 模式下把裸表达式语句(如 x + 1)求值并写入结果区;0=成功 非 REPL 模式不调用本函数(translate_expr_stmt 只在 REPL 分支调用), diff --git a/App/lib/core/IncludesScanner.vp b/App/lib/core/IncludesScanner.vp index 2683898..5256450 100644 --- a/App/lib/core/IncludesScanner.vp +++ b/App/lib/core/IncludesScanner.vp @@ -73,10 +73,7 @@ def create_scan_result(pool: memhub.MemBuddy*) -> ScanResult*: # ============================================================ # add_file_entry - 向扫描结果添加文件条目 # ============================================================ -def add_file_entry(result: ScanResult*, - pool: memhub.MemBuddy*, - abs_path: str, rel_path: str, - sha1: str, inc_dir: str) -> int: +def add_file_entry(result: ScanResult*, pool: memhub.MemBuddy*, abs_path: str, rel_path: str, sha1: str, inc_dir: str) -> int: """添加文件条目到扫描结果,返回 0 成功(inc_dir 为所属 includes 根目录)""" if result is None or pool is None: return 1 if result.Count >= result.Capacity: return 1 @@ -171,11 +168,7 @@ def compute_file_sha1(pool: memhub.MemBuddy*, file_path: str) -> str: # ============================================================ # scan_directory_recursive - 递归扫描目录(FindFirstFileA/FindNextFileA 遍历目录树) # ============================================================ -def scan_directory_recursive(pool: memhub.MemBuddy*, - root_dir: str, - rel_prefix: str, - result: ScanResult*, - inc_dir: str) -> int: +def scan_directory_recursive(pool: memhub.MemBuddy*, root_dir: str, rel_prefix: str, result: ScanResult*, inc_dir: str) -> int: """递归扫描目录,收集 .vp/.py 文件(inc_dir 为所属 includes 根目录)""" if pool is None or root_dir is None or result is None: return 1 # 子目录递归失败计数(不静默忽略,汇总处 fail-fast 终止) @@ -268,8 +261,7 @@ def scan_directory_recursive(pool: memhub.MemBuddy*, # ============================================================ # scan_includes - 扫描 includes 目录入口(返回所有 .vp 文件路径与 SHA1) # ============================================================ -def scan_includes(pool: memhub.MemBuddy*, - includes_dirs: str) -> ScanResult*: +def scan_includes(pool: memhub.MemBuddy*, includes_dirs: str) -> ScanResult*: """扫描 includes 目录(支持空格分隔的多目录),返回所有 .vp/.py 文件的扫描结果""" if pool is None or includes_dirs is None: return None @@ -299,8 +291,7 @@ def scan_includes(pool: memhub.MemBuddy*, # ============================================================ # find_entry_by_module - 按模块名查找文件条目 # ============================================================ -def find_entry_by_module(result: ScanResult*, - module_name: str) -> FileEntry*: +def find_entry_by_module(result: ScanResult*, module_name: str) -> FileEntry*: """按模块名查找文件条目""" if result is None or module_name is None: return None entry_size: sizet = FileEntry.__sizeof__() @@ -344,10 +335,7 @@ def _PathExistsA(path: str) -> int: # Returns: # 1 命中(已写输出),0 未命中 # ============================================================ -def _TryResolveModuleFile(inc_dir: str, rel_seg: bytes, rel_len: sizet, - suffix: str, - out_abs_path: t.CPtr, out_rel_path: t.CPtr, - out_inc_dir: t.CPtr) -> int: +def _TryResolveModuleFile(inc_dir: str, rel_seg: bytes, rel_len: sizet, suffix: str, out_abs_path: t.CPtr, out_rel_path: t.CPtr, out_inc_dir: t.CPtr) -> int: if inc_dir is None or rel_seg is None or suffix is None: return 0 inc_len: sizet = string.strlen(inc_dir) suf_len: sizet = string.strlen(suffix) @@ -416,9 +404,7 @@ def _TryResolveModuleFile(inc_dir: str, rel_seg: bytes, rel_len: sizet, # Returns: # 0 找到;1 未找到/参数错误 # ============================================================ -def ResolveModuleToPath(includes_dirs: str, mod_name: str, - out_abs_path: t.CPtr, out_rel_path: t.CPtr, - out_inc_dir: t.CPtr) -> int: +def ResolveModuleToPath(includes_dirs: str, mod_name: str, out_abs_path: t.CPtr, out_rel_path: t.CPtr, out_inc_dir: t.CPtr) -> int: if includes_dirs is None or mod_name is None: return 1 mn_len: sizet = string.strlen(mod_name) if mn_len == 0: return 1 @@ -448,14 +434,12 @@ def ResolveModuleToPath(includes_dirs: str, mod_name: str, string.strncpy(inc_dir_buf, includes_dirs + d_start, d_len) inc_dir_buf[d_len] = '\0' # 候选 1: {inc}/{rel}.vp(文件模块) - if _TryResolveModuleFile(inc_dir_buf, rel_seg, rel_len, ".vp", - out_abs_path, out_rel_path, out_inc_dir) != 0: + if _TryResolveModuleFile(inc_dir_buf, rel_seg, rel_len, ".vp", out_abs_path, out_rel_path, out_inc_dir) != 0: found = 1 stdlib.free(inc_dir_buf) break # 候选 2: {inc}/{rel}/__init__.vp(包模块) - if _TryResolveModuleFile(inc_dir_buf, rel_seg, rel_len, "/__init__.vp", - out_abs_path, out_rel_path, out_inc_dir) != 0: + if _TryResolveModuleFile(inc_dir_buf, rel_seg, rel_len, "/__init__.vp", out_abs_path, out_rel_path, out_inc_dir) != 0: found = 1 stdlib.free(inc_dir_buf) if found != 0: break diff --git a/App/lib/core/Repl.vp b/App/lib/core/Repl.vp index 685877b..7c4ffeb 100644 --- a/App/lib/core/Repl.vp +++ b/App/lib/core/Repl.vp @@ -273,14 +273,7 @@ def ReplFindProject(Out: bytes, Cap: int, Diag: bytes, DiagCap: int) -> int: return 1 else: string.strcpy(c2, "(GetModuleFileNameA 失败)") # 两处都没有:诊断文本(需要 --project + 两个已查位置 + 模板位置) - viperlib.snprintf(Diag, DiagCap, - " 已查找(1): %s\n" - " 已查找(2): %s\n" - " 需要 --project: 未找到 repl.vpj 时 REPL 拿不到工程配置," - "请用 --project 指定\n" - " 模板位置: 仓库 TransPyV/repl.vpj;拷到 TransPyV.exe 同目录" - "或当前工作目录即可被自动找到\n", - c1, c2) + viperlib.snprintf(Diag, DiagCap, " 已查找(1): %s\n" " 已查找(2): %s\n" " 需要 --project: 未找到 repl.vpj 时 REPL 拿不到工程配置," "请用 --project 指定\n" " 模板位置: 仓库 TransPyV/repl.vpj;拷到 TransPyV.exe 同目录" "或当前工作目录即可被自动找到\n", c1, c2) stdlib.free(c1) stdlib.free(c2) return 0 @@ -484,8 +477,7 @@ def ReplFindHostImplib() -> int: return 1 # 候选 ②:Config.OutputDir(REPL 用 repl.vpj 起、宿主用 project.vpj 建时) if Config.OutputDir is not None: - viperlib.snprintf(cand, _REPL_PATH_CAP, "%s/%s.dll.a", - Config.OutputDir, exe_buf + dlen) + viperlib.snprintf(cand, _REPL_PATH_CAP, "%s/%s.dll.a", Config.OutputDir, exe_buf + dlen) if _is_file(cand) != 0: ReplHostImplib = cand return 1 @@ -811,9 +803,7 @@ def _repl_cmd_append_implibs(cmd: bytes, cap: int, pos: int) -> int: # ---- includes 类注册(会话初始化一次;逐模块隔离,失败只告警)---- -def ReplInitIncludesClasses(mb: memhub.MemBuddy*, - sr: rawptr[IncludesScanner.ScanResult], - vpi_dir: str) -> int: +def ReplInitIncludesClasses(mb: memhub.MemBuddy*, sr: rawptr[IncludesScanner.ScanResult], vpi_dir: str) -> int: """把各 includes 模块的 .vpi 注入临时模块 ⇒ 其类进入会话 StructTable;0=完成 为什么需要:REPL 从不翻译 includes 源码 ⇒ 会话 StructTable(类型解析/字段查找/ @@ -891,9 +881,7 @@ def ReplInitIncludesClasses(mb: memhub.MemBuddy*, budget_hit = 1 break if GenApi.get_struct_count() >= _REPL_INC_CLS_STRUCT_GUARD: - stdio.printf("includes 类注册: 结构体表已达 %d 条(上限附近)," - "停止注册;未注册的类在会话里不可用(import 其模块" - "仍可按需注册)\n", GenApi.get_struct_count()) + stdio.printf("includes 类注册: 结构体表已达 %d 条(上限附近)," "停止注册;未注册的类在会话里不可用(import 其模块" "仍可按需注册)\n", GenApi.get_struct_count()) stdio.fflush(None) return 0 ent: rawptr[IncludesScanner.FileEntry] = rawptr[IncludesScanner.FileEntry](uint64(sr.Entries) + uint64(i) * uint64(es)) @@ -913,9 +901,7 @@ def ReplInitIncludesClasses(mb: memhub.MemBuddy*, # 不可用,会话继续(import 该模块时同样按缺存根退化) ReplIncClsMissing += 1 if warn_left > 0: - stdio.printf("includes 类注册: 模块 %s 无 .vpi 存根 —— 其类在" - "会话中不可用(不影响其它模块;先按 project.vpj " - "构建一次宿主可生成全部存根)\n", ent.Sha1) + stdio.printf("includes 类注册: 模块 %s 无 .vpi 存根 —— 其类在" "会话中不可用(不影响其它模块;先按 project.vpj " "构建一次宿主可生成全部存根)\n", ent.Sha1) warn_left -= 1 else: warn_dropped += 1 stdlib.free(vpi_path) @@ -939,8 +925,7 @@ def ReplInitIncludesClasses(mb: memhub.MemBuddy*, if rc_m != 0: ReplIncClsFail += 1 if warn_left > 0: - stdio.printf("includes 类注册: 模块 %d 的 .vpi 注入中断" - "(其类可能不完整;会话继续)\n", i) + stdio.printf("includes 类注册: 模块 %d 的 .vpi 注入中断" "(其类可能不完整;会话继续)\n", i) warn_left -= 1 else: warn_dropped += 1 mb.reset_to(vm) @@ -953,8 +938,7 @@ def ReplInitIncludesClasses(mb: memhub.MemBuddy*, else: ReplIncClsFail += 1 if warn_left > 0: - stdio.printf("includes 类注册: 模块 %s 的 .vpi 注入失败" - "(该模块的类不完整/不可用;会话继续)\n", ent.Sha1) + stdio.printf("includes 类注册: 模块 %s 的 .vpi 注入失败" "(该模块的类不完整/不可用;会话继续)\n", ent.Sha1) warn_left -= 1 else: warn_dropped += 1 stdlib.free(vpi_path) @@ -967,14 +951,9 @@ def ReplInitIncludesClasses(mb: memhub.MemBuddy*, si: int for si in range(n_mod): if int(st[si]) == 0: skip_cnt += 1 - stdio.printf("includes 类: 已注册 %d 个模块的 vpi 类(失败 %d,缺存根 %d," - "未尝试/待重试 %d,省略告警 %d)\n", - ReplIncClsMods, ReplIncClsFail, ReplIncClsMissing, - skip_cnt, warn_dropped) + stdio.printf("includes 类: 已注册 %d 个模块的 vpi 类(失败 %d,缺存根 %d," "未尝试/待重试 %d,省略告警 %d)\n", ReplIncClsMods, ReplIncClsFail, ReplIncClsMissing, skip_cnt, warn_dropped) if budget_hit != 0: - stdio.printf("includes 类: 启动预算 %d ms 用尽,已停止启动期注册(剩余 %d 个" - "模块的类在会话里不可用;片段 `import` 该模块时仍按需注册)\n", - _REPL_INC_CLS_BUDGET_MS, skip_cnt) + stdio.printf("includes 类: 启动预算 %d ms 用尽,已停止启动期注册(剩余 %d 个" "模块的类在会话里不可用;片段 `import` 该模块时仍按需注册)\n", _REPL_INC_CLS_BUDGET_MS, skip_cnt) stdio.fflush(None) return 0 @@ -1006,8 +985,7 @@ def ReplInitSession() -> int: # ② 会话目录:TransPyV_repl/(pid 隔离并发会话;路径统一用 '/') ReplTmpDir = _perm_pool.alloc(_REPL_PATH_CAP) if ReplTmpDir is None: return 1 - viperlib.snprintf(ReplTmpDir, _REPL_PATH_CAP, "%sTransPyV_repl/%u", - tmp_buf, win32process.GetCurrentProcessId()) + viperlib.snprintf(ReplTmpDir, _REPL_PATH_CAP, "%sTransPyV_repl/%u", tmp_buf, win32process.GetCurrentProcessId()) if BuildPipeline.ensure_dir(ReplTmpDir) != 0: return 1 # ③ 常驻缓冲(会话期存活,不按片段反复分配) ReplNameBuf = _perm_pool.alloc(_REPL_NAME_CAP) @@ -1161,9 +1139,7 @@ def ReplInitSession() -> int: # 失败口径(宽容,与 M0 的恢复点一致):includes 目录缺失/扫描为 0/存根生成失败 # 都只告警,**不终止会话**——"不带 import 的片段"仍照常可用。 # ============================================================ -def _repl_gen_includes_vpi(mb: memhub.MemBuddy*, - sr: rawptr[IncludesScanner.ScanResult], - vpi_dir: str) -> int: +def _repl_gen_includes_vpi(mb: memhub.MemBuddy*, sr: rawptr[IncludesScanner.ScanResult], vpi_dir: str) -> int: """为 includes 扫描结果预生成 .vpi 存根;返回新生成个数(-1=参数错误) 已存在同名 .vpi 直接复用(.vpi 按内容 SHA1 命名 ⇒ 同名必然同内容,与 @@ -1245,8 +1221,7 @@ def _repl_gen_includes_vpi(mb: memhub.MemBuddy*, mb.reset_to(fm) continue # rel_path 传绝对路径 ent.Path:vpi 生成期的 fatal_error 需按该路径读源码行 - pos: sizet = StubConverter._GeneratePyiFromAst(mb, tree, ent.Path, - pyi_buf, _REPL_VPI_BUF_CAP) + pos: sizet = StubConverter._GeneratePyiFromAst(mb, tree, ent.Path, pyi_buf, _REPL_VPI_BUF_CAP) if pos > 0: pf: rawptr[fileio.File] = fileio.File(vpi_path, fileio.MODE.W) if not pf.closed: @@ -1276,36 +1251,30 @@ def ReplInitIncludes(mb: memhub.MemBuddy*) -> int: if mb is None: return 1 inc_dirs: str = Config.IncludesDirs if inc_dirs is None or string.strlen(inc_dirs) == 0: - stdio.printf("REPL: 工程未配置 includes 目录(project.vpj 的 includes)," - "跳过 includes 初始化;import includes 模块会报未注册 SHA1\n") + stdio.printf("REPL: 工程未配置 includes 目录(project.vpj 的 includes)," "跳过 includes 初始化;import includes 模块会报未注册 SHA1\n") return 1 # .vpi 目录与片段侧一致:优先工程临时目录,无工程配置时退回会话目录 vpi_dir: str = Config.TempDir if vpi_dir is None: vpi_dir = ReplTmpDir if vpi_dir is None: - stdio.printf("REPL: 无可用 .vpi 目录(Config.TempDir 与会话目录均为空)," - "跳过 includes 初始化\n") + stdio.printf("REPL: 无可用 .vpi 目录(Config.TempDir 与会话目录均为空)," "跳过 includes 初始化\n") return 1 # ① 扫描 includes(可达性不判定:REPL 无 SourceDir/deps 图,取全量超集) t0: uint64 = win32base.GetTickCount64() sr: rawptr[IncludesScanner.ScanResult] = IncludesScanner.scan_includes(mb, inc_dirs) if sr is None: - stdio.printf("REPL: includes 扫描失败(目录: %s);" - "import includes 模块会报未注册 SHA1\n", inc_dirs) + stdio.printf("REPL: includes 扫描失败(目录: %s);" "import includes 模块会报未注册 SHA1\n", inc_dirs) return 1 # ② 注册"模块名 → SHA1"(同一张 StubMerger 全局表,批处理消费者直接可用) n: int = StubMergerStore.PopulateSha1MapStore(sr) ReplIncMs = int(win32base.GetTickCount64() - t0) if n <= 0: - stdio.printf("REPL: includes 扫描未注册任何模块(目录: %s):" - "请检查 includes 路径与 .vp 文件\n", inc_dirs) + stdio.printf("REPL: includes 扫描未注册任何模块(目录: %s):" "请检查 includes 路径与 .vp 文件\n", inc_dirs) return 1 ReplIncMods = n # ③ 预生成 .vpi 存根(失败逐个计数,不终止会话) _repl_gen_includes_vpi(mb, sr, vpi_dir) - stdio.printf("includes: 已注册 %d 个模块(扫描耗时 %d ms);" - "存根 新生成 %d / 复用 %d / 失败 %d\n", - n, ReplIncMs, ReplIncVpiNew, ReplIncVpiReuse, ReplIncVpiFail) + stdio.printf("includes: 已注册 %d 个模块(扫描耗时 %d ms);" "存根 新生成 %d / 复用 %d / 失败 %d\n", n, ReplIncMs, ReplIncVpiNew, ReplIncVpiReuse, ReplIncVpiFail) # ③'' 会话泛型模板注册(**真注册**,不再只造 opaque 类型占位):按批处理同一 # 机制把 includes 的泛型类模板(list/dict/Vector/…)注册进会话泛型模板表—— # Phase1Scan._PreRegisterAllGenericTemplates 复用 includes 源码,先按 @@ -1330,8 +1299,7 @@ def ReplInitIncludes(mb: memhub.MemBuddy*) -> int: n_gen_tpl: int = Phase1Scan._PreRegisterAllGenericTemplates(mb, sr) if cur_file_saved is not None: GenApi.set_current_file_type(cur_file_saved) if n_gen_tpl <= 0: - stdio.printf("includes 泛型模板: 0 个 —— 注解里的 list[...]/dict[...] 只能按" - "\"仅类型\"占位解析(元素布局与方法不可用)\n") + stdio.printf("includes 泛型模板: 0 个 —— 注解里的 list[...]/dict[...] 只能按" "\"仅类型\"占位解析(元素布局与方法不可用)\n") # ③' M4.2:开启"存根布局恢复"——随后的 vpi 注入会按 .stub.ll 校验并登记 # includes 类的**完整布局**(含父类展平字段与 __vtable__)与虚表方法索引; # 布局不可信 ⇒ 该类的 StructEntry 不登记(字段访问明确报错,不静默错位)。 @@ -1458,8 +1426,7 @@ def _repl_lift_add_name(name: str) -> int: stdio.printf("M3: 同一片段内重复定义会话函数 '%s'(请只定义一次)\n", name) return 1 if ReplLiftNameCount >= _REPL_LIFT_MAX: - stdio.printf("M3: 单个片段最多提升 %d 个会话函数(本片段已提升 %d 个)\n", - _REPL_LIFT_MAX, ReplLiftNameCount) + stdio.printf("M3: 单个片段最多提升 %d 个会话函数(本片段已提升 %d 个)\n", _REPL_LIFT_MAX, ReplLiftNameCount) return 1 string.strcpy(ReplLiftNames + ReplLiftNameCount * _REPL_FN_NAME_MAX, name) ReplLiftNameCount += 1 @@ -1486,8 +1453,7 @@ def _repl_lift_def_header(line: bytes, n: int, name_out: bytes, name_cap: int) - stdio.printf("M3: def 头缺少函数名:%s\n", _repl_show_line(line, n)) return 1 if nlen >= name_cap: - stdio.printf("M3: 会话函数名过长(上限 %d 字节):%s\n", - name_cap - 1, _repl_show_line(line, n)) + stdio.printf("M3: 会话函数名过长(上限 %d 字节):%s\n", name_cap - 1, _repl_show_line(line, n)) return 1 string.memcpy(name_out, line + ns, sizet(nlen)) name_out[nlen] = 0 @@ -1534,8 +1500,7 @@ def _repl_lift_def_header(line: bytes, n: int, name_out: bytes, name_cap: int) - break q2 += 1 if has_colon == 0: - stdio.printf("M3: def 头的 ':' 不在同一行(签名必须写在一行内):%s\n", - _repl_show_line(line, n)) + stdio.printf("M3: def 头的 ':' 不在同一行(签名必须写在一行内):%s\n", _repl_show_line(line, n)) return 1 # 形参表是否为空 empty: int = 1 @@ -1549,10 +1514,8 @@ def _repl_lift_def_header(line: bytes, n: int, name_out: bytes, name_cap: int) - if empty == 0: seg: int = lp + 1 while seg + 12 <= rp: - if line[seg] == '_' and string.strncmp(line + seg, GenTypes.REPL_CTX_PARAM, - sizet(12)) == 0: - stdio.printf("M3: 会话函数 '%s' 不能自定义 %s 形参" - "(提升时自动注入为第一个形参)\n", name_out, GenTypes.REPL_CTX_PARAM) + if line[seg] == '_' and string.strncmp(line + seg, GenTypes.REPL_CTX_PARAM, sizet(12)) == 0: + stdio.printf("M3: 会话函数 '%s' 不能自定义 %s 形参" "(提升时自动注入为第一个形参)\n", name_out, GenTypes.REPL_CTX_PARAM) return 1 seg += 1 # 写出:"export " + 原头 [0,lp] + 注入 + 原头 [lp+1,n) + '\n' @@ -1598,15 +1561,10 @@ def _repl_split_body(body: bytes) -> int: continue if ind > 0: if need_header != 0: - stdio.printf("M3: 装饰器之后必须紧跟 def 头行:%s\n", - _repl_show_line(body + i, n)) + stdio.printf("M3: 装饰器之后必须紧跟 def 头行:%s\n", _repl_show_line(body + i, n)) return 1 if in_body != 0 and _repl_line_has_kw(body + i, n, ind, "raise") != 0: - stdio.printf("M3: 会话函数 '%s' 的函数体含 raise:%s\n" - " M3 不支持跨片段异常传播(raise 会给函数追加 " - "__eh_msg_out__/__eh_code_out__ 出参," - "而经函数指针的间接调用不会补这些实参)——该片段整体不执行\n", - name_buf, _repl_show_line(body + i, n)) + stdio.printf("M3: 会话函数 '%s' 的函数体含 raise:%s\n" " M3 不支持跨片段异常传播(raise 会给函数追加 " "__eh_msg_out__/__eh_code_out__ 出参," "而经函数指针的间接调用不会补这些实参)——该片段整体不执行\n", name_buf, _repl_show_line(body + i, n)) return 1 lp1: int = int(string.strlen(ReplLiftBuf)) lp1 = _repl_cat(ReplLiftBuf, _REPL_LIFT_CAP, lp1, body + i, n) @@ -1648,8 +1606,7 @@ def _repl_split_body(body: bytes) -> int: i += n + 1 continue if _repl_line_has_kw(body + i, n, 0, "async") != 0 and _repl_line_has_kw(body + i, n, 6, "def") != 0: - stdio.printf("M3: 不支持 async def 会话函数(协程 ABI 与 M3 签名 token " - "不相容,请改写成普通 def):%s\n", _repl_show_line(body + i, n)) + stdio.printf("M3: 不支持 async def 会话函数(协程 ABI 与 M3 签名 token " "不相容,请改写成普通 def):%s\n", _repl_show_line(body + i, n)) return 1 pos = _repl_cat_str(ReplSrcBuf, _REPL_FRAG_SRC_CAP, pos, " ") pos = _repl_cat(ReplSrcBuf, _REPL_FRAG_SRC_CAP, pos, body + i, n) @@ -1671,9 +1628,7 @@ def _repl_build_frag_src_multi(name: str, body: bytes) -> int: # 提升缓冲与名表水位已由调用方 _build_frag_src 每片段清零(单行路径也必须清零, # 故清零点在调用方而非此处);这里只负责装配 # 片段函数头(与单行模板同一形态);片段体随后逐行 4 空格 - viperlib.snprintf(ReplSrcBuf, _REPL_FRAG_SRC_CAP, - "export def %s(%s: bytes) -> int:\n", - name, GenTypes.REPL_CTX_PARAM) + viperlib.snprintf(ReplSrcBuf, _REPL_FRAG_SRC_CAP, "export def %s(%s: bytes) -> int:\n", name, GenTypes.REPL_CTX_PARAM) ReplWrapPos = int(string.strlen(ReplSrcBuf)) rc: int = _repl_split_body(body) if rc != 0: return rc @@ -1737,8 +1692,7 @@ def _repl_sig_to_text(tag: int, bits: int, pc: int) -> str: i: int = 0 while i < pc: if i > 0: pos = _repl_cat_str(ReplSigText, _REPL_SIG_TEXT_CAP, pos, ", ") - pos = _repl_cat_str(ReplSigText, _REPL_SIG_TEXT_CAP, pos, - _repl_tag_text(int(ReplSigTags[i]), int(ReplSigBits[i]))) + pos = _repl_cat_str(ReplSigText, _REPL_SIG_TEXT_CAP, pos, _repl_tag_text(int(ReplSigTags[i]), int(ReplSigBits[i]))) i += 1 pos = _repl_cat_str(ReplSigText, _REPL_SIG_TEXT_CAP, pos, ") -> ") pos = _repl_cat_str(ReplSigText, _REPL_SIG_TEXT_CAP, pos, _repl_tag_text(tag, bits)) @@ -1764,25 +1718,16 @@ def _repl_precheck_session_funcs(mod: mlirlite.LLVMModule*) -> int: stdio.printf("M3: 定义片段模型里找不到函数 '%s'(提升未生效?)\n", nm) return 1 if rc == 2: - stdio.printf("M3: 会话函数 '%s' 的签名含不受支持的类型 '%s'\n" - " M3 支持 void / i1 / i8 / i16 / i32 / i64 / float / double / " - "i8*(str、bytes、rawptr);结构体值/数组/多级指针请改用指针参数" - "或等 M4\n", - nm, ReplSigResult.BadType) + stdio.printf("M3: 会话函数 '%s' 的签名含不受支持的类型 '%s'\n" " M3 支持 void / i1 / i8 / i16 / i32 / i64 / float / double / " "i8*(str、bytes、rawptr);结构体值/数组/多级指针请改用指针参数" "或等 M4\n", nm, ReplSigResult.BadType) return 1 if rc == 3: - stdio.printf("M3: 会话函数 '%s' 的签名含异常出参(%%__eh_msg_out__/" - "%%__eh_code_out__)——其函数体含 raise\n" - " M3 不支持跨片段异常传播:经函数指针的间接调用不会补这两个实参" - "(arity 不匹配);该片段整体不执行\n", nm) + stdio.printf("M3: 会话函数 '%s' 的签名含异常出参(%%__eh_msg_out__/" "%%__eh_code_out__)——其函数体含 raise\n" " M3 不支持跨片段异常传播:经函数指针的间接调用不会补这两个实参" "(arity 不匹配);该片段整体不执行\n", nm) return 1 if rc == 4: - stdio.printf("M3: 会话函数 '%s' 的 define 首形参不是 %s(提升模板与调用约定" - "不一致)\n", nm, GenTypes.REPL_CTX_PARAM) + stdio.printf("M3: 会话函数 '%s' 的 define 首形参不是 %s(提升模板与调用约定" "不一致)\n", nm, GenTypes.REPL_CTX_PARAM) return 1 if rc == 5: - stdio.printf("M3: 会话函数 '%s' 的形参超过 %d 个\n", - nm, GenTypes.REPL_FUNC_PARAM_MAX) + stdio.printf("M3: 会话函数 '%s' 的形参超过 %d 个\n", nm, GenTypes.REPL_FUNC_PARAM_MAX) return 1 if rc != 0: stdio.printf("M3: 会话函数 '%s' 的签名解析失败(rc=%d)\n", nm, rc) @@ -1803,18 +1748,10 @@ def _repl_precheck_session_funcs(mod: mlirlite.LLVMModule*) -> int: break pi += 1 if sig_same == 0: - stdio.printf("M3: 会话函数 '%s' 重定义签名不一致(旧 %s,新 %s)\n" - " M3 允许同签名覆盖(只换地址);换签名会让先前片段里已编好的" - "调用点按旧 ABI 调新代码 —— 该片段整体不执行,请换名字\n", - nm, - _repl_entry_sig_text(old), - _repl_sig_to_text(ReplSigResult.RetTag, ReplSigResult.RetBits, - ReplSigResult.ParamCount)) + stdio.printf("M3: 会话函数 '%s' 重定义签名不一致(旧 %s,新 %s)\n" " M3 允许同签名覆盖(只换地址);换签名会让先前片段里已编好的" "调用点按旧 ABI 调新代码 —— 该片段整体不执行,请换名字\n", nm, _repl_entry_sig_text(old), _repl_sig_to_text(ReplSigResult.RetTag, ReplSigResult.RetBits, ReplSigResult.ParamCount)) return 1 if ReplCtxObj.FuncCount + new_cnt > ReplCtxObj.FuncCap: - stdio.printf("M3: 会话函数已达上限 %d 个(ctx 函数指针槽用尽),本次新增 %d 个;" - "请重启会话或减少会话函数\n", - ReplCtxObj.FuncCap, new_cnt) + stdio.printf("M3: 会话函数已达上限 %d 个(ctx 函数指针槽用尽),本次新增 %d 个;" "请重启会话或减少会话函数\n", ReplCtxObj.FuncCap, new_cnt) return 1 return 0 @@ -1826,20 +1763,17 @@ def _repl_entry_sig_text(e: rawptr[GenTypes.ReplFuncEntry]) -> str: i: int = 0 while i < e.ParamCount: if i > 0: pos = _repl_cat_str(ReplSigText2, _REPL_SIG_TEXT_CAP, pos, ", ") - pos = _repl_cat_str(ReplSigText2, _REPL_SIG_TEXT_CAP, pos, - _repl_tag_text(int(e.ParamTags[i]), int(e.ParamBits[i]))) + pos = _repl_cat_str(ReplSigText2, _REPL_SIG_TEXT_CAP, pos, _repl_tag_text(int(e.ParamTags[i]), int(e.ParamBits[i]))) i += 1 pos = _repl_cat_str(ReplSigText2, _REPL_SIG_TEXT_CAP, pos, ") -> ") - pos = _repl_cat_str(ReplSigText2, _REPL_SIG_TEXT_CAP, pos, - _repl_tag_text(e.RetTag, e.RetBits)) + pos = _repl_cat_str(ReplSigText2, _REPL_SIG_TEXT_CAP, pos, _repl_tag_text(e.RetTag, e.RetBits)) if pos < 0: return "(?)" return ReplSigText2 # 注册(DLL 加载成功后调用):GetProcAddress(裸名) → 写 ctx 函数指针槽 → 追加/更新表 # 返回 0=成功;1=失败(已打印;调用方按 ReplSavedFuncCount 回滚表水位后放弃本片段) -def _repl_register_session_funcs(h_lib: win32base.HANDLE, frag_no: int, - mod: mlirlite.LLVMModule*) -> int: +def _repl_register_session_funcs(h_lib: win32base.HANDLE, frag_no: int, mod: mlirlite.LLVMModule*) -> int: if ReplLiftNameCount <= 0: return 0 if ReplCtxObj is None or ReplCtxObj.FuncTable is None or ReplCtxBuf is None: stdio.printf("M3: 会话函数表/ctx 未初始化\n") @@ -1853,8 +1787,7 @@ def _repl_register_session_funcs(h_lib: win32base.HANDLE, frag_no: int, # (FuncGenBase.vp:264);-shared 未用 DEF 文件 ⇒ 全部符号自动进导出表(M1 实测) addr: VOIDPTR = win32base.GetProcAddress(h_lib, nm) if addr is None: - stdio.printf("M3: 会话函数 '%s' 未出现在片段 DLL 的导出表" - "(GetProcAddress 返回空;本片段不执行)\n", nm) + stdio.printf("M3: 会话函数 '%s' 未出现在片段 DLL 的导出表" "(GetProcAddress 返回空;本片段不执行)\n", nm) return 1 ent: rawptr[GenTypes.ReplFuncEntry] = _repl_func_entry_find(nm) if ent is None: @@ -1894,9 +1827,7 @@ def _repl_register_session_funcs(h_lib: win32base.HANDLE, frag_no: int, sv: rawptr[ReplFuncSlotView] = rawptr[ReplFuncSlotView](uint64(ReplCtxBuf) + uint64(ent.SlotOff)) sv.Addr = addr sv.Reserved = None - stdio.printf("会话函数 %s: 导出符号 %s → ctx 槽 +%d(定义片段 %d,签名 %s)\n", - nm, nm, ent.SlotOff, frag_no, - _repl_entry_sig_text(ent)) + stdio.printf("会话函数 %s: 导出符号 %s → ctx 槽 +%d(定义片段 %d,签名 %s)\n", nm, nm, ent.SlotOff, frag_no, _repl_entry_sig_text(ent)) return 0 @@ -1968,8 +1899,7 @@ def _repl_ty_name(ty: mlirlite.LLVMType*) -> str: # 返回码与旧实现逐字一致: # 0=成功;1=模块里找不到该函数;2=类型不受支持;3=含 EH 出参(raise); # 4=首形参不是 ctx;5=形参过多(> REPL_FUNC_PARAM_MAX) -def _repl_model_func_sig(mod: mlirlite.LLVMModule*, name: str, - out: rawptr[ReplSigOut]) -> int: +def _repl_model_func_sig(mod: mlirlite.LLVMModule*, name: str, out: rawptr[ReplSigOut]) -> int: if name is None or out is None or mod is None: return 1 out.RetTag = GenTypes.REPL_TY_VOID out.RetBits = 0 @@ -2061,9 +1991,7 @@ def _build_frag_src(name: str, body: str) -> int: ReplLiftNames[0] = 0 if string.strchr(body, '\n') is None: # 单行:既有模板(ctx 形参 bytes ⇒ i8*;export ⇒ 不加 SHA1 前缀) - viperlib.snprintf(ReplSrcBuf, _REPL_FRAG_SRC_CAP, - "export def %s(%s: bytes) -> int:\n %s\n return 0\n", - name, GenTypes.REPL_CTX_PARAM, body) + viperlib.snprintf(ReplSrcBuf, _REPL_FRAG_SRC_CAP, "export def %s(%s: bytes) -> int:\n %s\n return 0\n", name, GenTypes.REPL_CTX_PARAM, body) return 0 # 多行:提升顶层 def + 逐行装配(M3;见 _repl_split_body 的规则) return _repl_build_frag_src_multi(name, body) @@ -2162,8 +2090,7 @@ def ReplExecFragment(mb: memhub.MemBuddy*, src: str) -> int: # 返回:0=成功;1=提升规则拒绝(原因已由提升函数打印);2=缓冲不足 rc_build: int = _build_frag_src(ReplNameBuf, body) if rc_build == 2: - stdio.printf("片段 %s: 包裹源码装配失败(缓冲 %d 字节不足)\n", - ReplNameBuf, _REPL_FRAG_SRC_CAP) + stdio.printf("片段 %s: 包裹源码装配失败(缓冲 %d 字节不足)\n", ReplNameBuf, _REPL_FRAG_SRC_CAP) return 1 if rc_build != 0: # 提升规则拒绝(async def / raise / 重名 / 签名非单行 / 自带 ctx 形参…): @@ -2223,8 +2150,7 @@ def ReplExecFragment(mb: memhub.MemBuddy*, src: str) -> int: ec: int = ast.get_parse_err_col() em: str = ast.get_parse_err_msg() if em is None: em = "(未知)" - stdio.printf("片段 %s: 包裹源码解析失败(第 %d 行第 %d 列: %s)\n", - ReplNameBuf, el, ec, em) + stdio.printf("片段 %s: 包裹源码解析失败(第 %d 行第 %d 列: %s)\n", ReplNameBuf, el, ec, em) return 1 # ⑦ 翻译为完整模块 IR(Translator 本体在 mb) @@ -2265,13 +2191,9 @@ def ReplExecFragment(mb: memhub.MemBuddy*, src: str) -> int: # 不含该形参 ⇒ 包裹模板/调用约定不一致,或片段含 raise 使函数被追加 # __eh_msg_out__/__eh_code_out__ 两个出参——此时宿主按单参调用是未定义行为, # 故直接明确报错(不加载、不调用)。 - viperlib.snprintf(ReplNeedleBuf, _REPL_NEEDLE_CAP, - "llvm.func @%s(%%%s: !llvm.ptr) -> i32", - ReplNameBuf, GenTypes.REPL_CTX_PARAM) + viperlib.snprintf(ReplNeedleBuf, _REPL_NEEDLE_CAP, "llvm.func @%s(%%%s: !llvm.ptr) -> i32", ReplNameBuf, GenTypes.REPL_CTX_PARAM) if string.strstr(ReplIrBuf, ReplNeedleBuf) is None: - stdio.printf("片段 %s: 未生成约定的导出函数(期望 `llvm.func @%s(%%__repl_ctx__: !llvm.ptr) -> i32`);" - "含 raise 的片段会追加异常出参,M2 不支持\n", - ReplNameBuf, ReplNameBuf) + stdio.printf("片段 %s: 未生成约定的导出函数(期望 `llvm.func @%s(%%__repl_ctx__: !llvm.ptr) -> i32`);" "含 raise 的片段会追加异常出参,M2 不支持\n", ReplNameBuf, ReplNameBuf) return 1 # ⑧' 会话函数签名校验(M3):在 llc/加载**之前**判完(EH 出参 / 类型不受支持 / @@ -2299,8 +2221,7 @@ def ReplExecFragment(mb: memhub.MemBuddy*, src: str) -> int: # 走不到这里的 llc 失败:compile_ll_to_obj 内部 VLogger.error 已打印 module/exit/cmd # 并 longjmp(BuildPipeline.vp:373-375)。能返回非 0 的只有其内部"分配失败"分支 # (obj_path/cmd 缓冲为 NULL,BuildPipeline.vp:315/367)⇒ 补一行明示,避免静默回提示符。 - stdio.printf("片段 %s: llc 编译 .obj 失败(命令/路径缓冲分配失败,见上方诊断)\n", - ReplNameBuf) + stdio.printf("片段 %s: llc 编译 .obj 失败(命令/路径缓冲分配失败,见上方诊断)\n", ReplNameBuf) return 1 # ⑪ clang++ -shared → .dll(命令拼法对齐 BuildPipeline.link_obj_to_exe 的 @@ -2341,24 +2262,15 @@ def ReplExecFragment(mb: memhub.MemBuddy*, src: str) -> int: pos_c = _repl_cat_str(cmd, _REPL_CMD_CAP, pos_c, " -Wl,--out-implib=") pos_c = _repl_cat_str(cmd, _REPL_CMD_CAP, pos_c, implib_path) if pos_c < 0: - stdio.printf("片段 %s: 链接命令行超过 %d 字节(已登记的片段 import lib 共 %d " - "个)——本片段不执行;可重启会话减少片段数\n", - ReplNameBuf, _REPL_CMD_CAP, ReplFragImplibCount) + stdio.printf("片段 %s: 链接命令行超过 %d 字节(已登记的片段 import lib 共 %d " "个)——本片段不执行;可重启会话减少片段数\n", ReplNameBuf, _REPL_CMD_CAP, ReplFragImplibCount) return 1 link_rc: int = BuildPipeline._run_cmd_wait(cmd) if link_rc != 0: - stdio.printf("片段 %s: 生成 .dll 失败 (exit=%d)\n 命令: %s\n", - ReplNameBuf, link_rc, cmd) + stdio.printf("片段 %s: 生成 .dll 失败 (exit=%d)\n 命令: %s\n", ReplNameBuf, link_rc, cmd) if ReplHostImplib is None: - stdio.printf(" 原因提示: 未找到宿主 import lib(.dll.a)——" - "跨模块符号(形如 <16位hex>.<函数名>)无法解析;" - "宿主需按 TransPyV/project.vpj 构建(含 -Wl,--export-all-symbols)," - "且 .dll.a 与 exe 同目录\n") + stdio.printf(" 原因提示: 未找到宿主 import lib(.dll.a)——" "跨模块符号(形如 <16位hex>.<函数名>)无法解析;" "宿主需按 TransPyV/project.vpj 构建(含 -Wl,--export-all-symbols)," "且 .dll.a 与 exe 同目录\n") else: - stdio.printf(" 原因提示: 若输出含 undefined symbol 且形如 <16位hex>.<名>," - "则该符号未被宿主定义/导出(宿主构建时未链入对应 includes 模块);" - "若该函数在源码里是 `export def`(CExport,裸名定义)却仍带前缀," - "多为 include 存根 .vpi 缺失(见会话开头的 includes 扫描行)\n") + stdio.printf(" 原因提示: 若输出含 undefined symbol 且形如 <16位hex>.<名>," "则该符号未被宿主定义/导出(宿主构建时未链入对应 includes 模块);" "若该函数在源码里是 `export def`(CExport,裸名定义)却仍带前缀," "多为 include 存根 .vpi 缺失(见会话开头的 includes 扫描行)\n") return 1 # ⑪' M4:若本片段 IR 里定义了会话前缀符号 ⇒ 登记其 import lib @@ -2369,28 +2281,20 @@ def ReplExecFragment(mb: memhub.MemBuddy*, src: str) -> int: # undefined(会话继续,见 ReplFragImplibCount 的上限说明)。 if needs_implib != 0: if _is_file(implib_path) != 0 and ReplFragImplibRecord(implib_path) != 0: - stdio.printf("片段 %s: 已登记片段 import lib(后续片段可解析本片段定义的" - "类型/方法符号): %s\n", ReplNameBuf, implib_path) + stdio.printf("片段 %s: 已登记片段 import lib(后续片段可解析本片段定义的" "类型/方法符号): %s\n", ReplNameBuf, implib_path) else: - stdio.printf("片段 %s: 片段 import lib 未登记(已登记 %d 个,上限 %d;或文件" - "缺失)——更晚的片段可能解析不到本片段定义的类型/方法符号\n", - ReplNameBuf, ReplFragImplibCount, _REPL_FRAG_IMPLIB_MAX) + stdio.printf("片段 %s: 片段 import lib 未登记(已登记 %d 个,上限 %d;或文件" "缺失)——更晚的片段可能解析不到本片段定义的类型/方法符号\n", ReplNameBuf, ReplFragImplibCount, _REPL_FRAG_IMPLIB_MAX) # ⑫ 动态加载 + 取地址(LoadLibraryA/GetProcAddress 见 includes/w32/win32base.vp:65/68) h_lib: win32base.HANDLE = win32base.LoadLibraryA(dll_path) if h_lib is None: stdio.printf("片段 %s: LoadLibraryA 失败: %s\n", ReplNameBuf, dll_path) if ReplHostImplib is not None: - stdio.printf(" 原因提示: 片段 DLL 的导入表指向宿主 exe(%s);" - "若 GetLastError 是 127(找不到指定过程)/ 加载器 0xC0000139," - "多为宿主与该 import lib 非同一次构建产物、或宿主缺该导出;" - "进程镜像名(%s)与 import lib 记录名不一致时同样会失败\n", - ReplHostImplib, dll_path) + stdio.printf(" 原因提示: 片段 DLL 的导入表指向宿主 exe(%s);" "若 GetLastError 是 127(找不到指定过程)/ 加载器 0xC0000139," "多为宿主与该 import lib 非同一次构建产物、或宿主缺该导出;" "进程镜像名(%s)与 import lib 记录名不一致时同样会失败\n", ReplHostImplib, dll_path) return 1 fp_addr: VOIDPTR = win32base.GetProcAddress(h_lib, ReplNameBuf) if fp_addr is None: - stdio.printf("片段 %s: GetProcAddress 返回空(导出表中无该符号): %s\n", - ReplNameBuf, dll_path) + stdio.printf("片段 %s: GetProcAddress 返回空(导出表中无该符号): %s\n", ReplNameBuf, dll_path) return 1 # ⑫' 会话函数注册(M3):DLL 已加载 ⇒ GetProcAddress(裸名) 取地址 → 写 ctx @@ -2493,8 +2397,7 @@ def run(mb: memhub.MemBuddy*) -> int: stdio.printf(" 跨片段函数:块里顶格的 def 会被提升为片段模块的 export def(裸名导出),\n") stdio.printf(" 后续片段可直接调用(如 def f(x: int) -> int: 换行 +4 空格 return x + 1);\n") stdio.printf(" 限制:签名须单行、不支持 async def、函数体内不支持 raise、不支持偏函数\n") - stdio.printf(" 跨片段类型(M4):块里的 class 会被翻译进会话(类型名 %s.<类名>),\n", - ReplSessionSha1) + stdio.printf(" 跨片段类型(M4):块里的 class 会被翻译进会话(类型名 %s.<类名>),\n", ReplSessionSha1) stdio.printf(" 后续片段可实例化、读写字段、调用方法;import 的 includes 模块\n") stdio.printf(" 其类同样注册进会话(缺 .vpi 存根时该模块的类不可用,会话继续)\n") stdio.printf(" 片段临时目录: %s\n", ReplTmpDir) @@ -2510,9 +2413,7 @@ def run(mb: memhub.MemBuddy*) -> int: inc_mark: sizet = mb.mark() rc_inc: int = _setjmp(jb, None) if rc_inc != 0: - stdio.printf("REPL: includes 初始化中断(已注册 %d 个模块、存根 %d 个):" - "import includes 模块可能失败,其余片段不受影响\n", - ReplIncMods, ReplIncVpiNew) + stdio.printf("REPL: includes 初始化中断(已注册 %d 个模块、存根 %d 个):" "import includes 模块可能失败,其余片段不受影响\n", ReplIncMods, ReplIncVpiNew) mb.reset_to(inc_mark) else: # 扫描结果/注册表都在 stdlib(create_scan_result 用 stdlib.malloc), @@ -2529,8 +2430,7 @@ def run(mb: memhub.MemBuddy*) -> int: # 之后提示符消失"(longjmp 到已返回的帧 → 未定义行为)的修复点。 rc_arm: int = _setjmp(jb, None) if rc_arm != 0: - stdio.printf("REPL: includes 类布局收尾中断(诊断见上):布局注册可能不完整," - "会话继续\n") + stdio.printf("REPL: includes 类布局收尾中断(诊断见上):布局注册可能不完整," "会话继续\n") else: # 收尾:收敛登记"父类在后续遍才就绪"的类 + 逐类告警拒绝 + 汇总。放在 # **重武装之后**:其内部可能经 GenApi.register_struct → VLogger.error 触发 @@ -2545,13 +2445,9 @@ def run(mb: memhub.MemBuddy*) -> int: # 代码与数据);未命中 ⇒ 只告警,不带 import lib 链接(跨模块调用会在链接期失败, # 由 ReplExecFragment 打印明确原因,会话继续)。 if ReplFindHostImplib() != 0: - stdio.printf("宿主符号导入库: %s(片段可跨模块调用 includes 函数/全局)\n", - ReplHostImplib) + stdio.printf("宿主符号导入库: %s(片段可跨模块调用 includes 函数/全局)\n", ReplHostImplib) else: - stdio.printf("宿主符号导入库: 未找到 .dll.a;片段调用 includes 模块级" - "函数会在链接期报 undefined symbol(会话不终止)。请用 " - "TransPyV/project.vpj(已声明 -Wl,--export-all-symbols)构建宿主," - "并让 exe 与 .dll.a 同目录\n") + stdio.printf("宿主符号导入库: 未找到 .dll.a;片段调用 includes 模块级" "函数会在链接期报 undefined symbol(会话不终止)。请用 " "TransPyV/project.vpj(已声明 -Wl,--export-all-symbols)构建宿主," "并让 exe 与 .dll.a 同目录\n") stdio.fflush(None) # === 读行循环:单行片段 + 块级续行 === @@ -2615,9 +2511,7 @@ def run(mb: memhub.MemBuddy*) -> int: continue # 续行中:每行都入缓冲;不因行尾 ':' 反复切换,也不做缩进分析 if _block_append(line, n) != 0: - stdio.printf("REPL: 块输入超过块缓冲上界 %d 字节:本块已丢弃," - "回到 >>> 继续(可减少块体积或分块执行)\n", - _REPL_BLOCK_CAP) + stdio.printf("REPL: 块输入超过块缓冲上界 %d 字节:本块已丢弃," "回到 >>> 继续(可减少块体积或分块执行)\n", _REPL_BLOCK_CAP) ReplInBlock = 0 ReplBlockLen = 0 mb.reset_to(mark) diff --git a/App/lib/core/VLogger.vp b/App/lib/core/VLogger.vp index 64b32ff..1917819 100644 --- a/App/lib/core/VLogger.vp +++ b/App/lib/core/VLogger.vp @@ -114,9 +114,7 @@ novirtual class Logger: # _log - 核心日志输出(分段着色:前缀符号 ├ / LEVEL 标签 / 消息内容) # 格式: ├ LEVEL: msg 或 ├ LEVEL[category]: msg # ============================================================ - def _log(self, level: int, prefix_sym: str, level_str: str, msg: str, - sym_color: WORD, level_color: WORD, - category: str = "") -> int: + def _log(self, level: int, prefix_sym: str, level_str: str, msg: str, sym_color: WORD, level_color: WORD, category: str = "") -> int: # 前缀符号着色 self._set_color(sym_color) stdio.printf("%s ", prefix_sym) diff --git a/App/lib/core/builtin/ViperBuild.vp b/App/lib/core/builtin/ViperBuild.vp index 8b0ffad..ee5836b 100644 --- a/App/lib/core/builtin/ViperBuild.vp +++ b/App/lib/core/builtin/ViperBuild.vp @@ -907,8 +907,7 @@ def _ResolveModuleToFile(module_name: str) -> str: abs_slot[0] = 0 rel_slot[0] = 0 inc_slot[0] = 0 - rcode: int = IncludesScanner.ResolveModuleToPath(_search_dirs, module_name, - out_abs, out_rel, out_inc) + rcode: int = IncludesScanner.ResolveModuleToPath(_search_dirs, module_name, out_abs, out_rel, out_inc) result: str = None if rcode == 0 and abs_slot[0] != 0: abs_path: str = rawptr(abs_slot[0]) diff --git a/App/main.vp b/App/main.vp index 6ca2440..fee80ee 100644 --- a/App/main.vp +++ b/App/main.vp @@ -327,8 +327,7 @@ Target: %s stdio.printf("FAIL: --repl 查找 repl.vpj 的路径缓冲分配失败\n") argparse.release(args) return 1 - if Repl.ReplFindProject(repl_proj_buf, REPL_PROJ_PATH_CAP, - repl_diag_buf, REPL_PROJ_DIAG_CAP) != 0: + if Repl.ReplFindProject(repl_proj_buf, REPL_PROJ_PATH_CAP, repl_diag_buf, REPL_PROJ_DIAG_CAP) != 0: proj_path = repl_proj_buf log.info(f"--repl: 未指定 --project,使用查找到的模板工程 {proj_path}", "repl") else: @@ -483,11 +482,7 @@ Target: %s mf_dynamic_libs: str = Config.LinkerDynamicLibs mf_includes_bin: str = Config.get_includes_binary_dir() - mf_ret: int = Phase2.RunMultiFileProject( - mb, Config.SourceDir, mf_temp, mf_output, - mf_cc, mf_cc_flags, mf_linker, mf_linker_flags, mf_linker_out, - mf_includes_bin, Config.IncludesDirs, do_phase1, do_phase2, log, args, - mf_static_libs, mf_dynamic_libs) + mf_ret: int = Phase2.RunMultiFileProject(mb, Config.SourceDir, mf_temp, mf_output, mf_cc, mf_cc_flags, mf_linker, mf_linker_flags, mf_linker_out, mf_includes_bin, Config.IncludesDirs, do_phase1, do_phase2, log, args, mf_static_libs, mf_dynamic_libs) argparse.release(args) log.success("TransPyV 完成") return mf_ret