refactor(tpv): 新语法 R10 括号内隐式续行并一行(1140 处 / 67 文件)
This commit is contained in:
1 parent
4a685d478f
commit
f2ef1bb240
67 files changed
+1140
-3775
No files matched your search
+49
-121
@@ -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<sym>\t<defline>\t<file>`。"""
|
||||
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<caller>\t<callee>\t<line>\t<file>`。"""
|
||||
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 = "链接失败"
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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 终止。
|
||||
|
||||
@@ -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
|
||||
# 找依赖文件在列表中的索引(跳过自身)
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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。
|
||||
|
||||
@@ -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',]
|
||||
@@ -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:
|
||||
|
||||
@@ -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 名 @<src_sha1>.<name>)"""
|
||||
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 结构体(命名 "%<sha1>.<类名>",与定义侧同口径)
|
||||
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
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 中的条目。
|
||||
|
||||
@@ -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__" 回退,
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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)))
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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_<name>(帧分配,M2 带参数)与 resume_<name>(状态机),
|
||||
@@ -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_<name> 按参数顺序收值入帧。"""
|
||||
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_<name> = { 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_<name>() -> %Coro_<name>*
|
||||
# ============================================================
|
||||
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_<name>(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_<name> 全局(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_<name>(%Coro_<name>*) -> 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_<name>(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; <body>; __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_<call_name>(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_<name>(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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.<method>() 绑到同名的兄弟类方法上。
|
||||
# ============================================================
|
||||
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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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):整型↔整型
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 会把依赖模块的同名函数
|
||||
|
||||
@@ -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:
|
||||
# 类型转换(按参数类型,使用访问器)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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 <ap_ty> <ap>, <type>
|
||||
|
||||
生成 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_ty> <trans._va_list_ptr>, <type>
|
||||
|
||||
使用当前函数的隐式 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=普通调用)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.<attr_name>(@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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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* 作为类型提示 (模块级变量通常存储指针)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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))
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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 长度修饰)
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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>()` 的取址结果(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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
+13
-40
@@ -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
|
||||
@@ -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 内(不内联——内联新增分支会干扰本函数
|
||||
|
||||
@@ -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: <body> → 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 <cond>` 暂不支持 guard 守卫",
|
||||
"NotImplementedError")
|
||||
self.Gen.TypeGenErr.fatal_error(pat, "序列匹配的顶层 `case _ if <cond>` 暂不支持 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
|
||||
|
||||
@@ -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 参数缺失
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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.<method_name>() 调用(__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)
|
||||
|
||||
@@ -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 遍历类型树
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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] <ptr> 类型不匹配。
|
||||
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.<want_name> 节点。
|
||||
|
||||
注解形态是 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
|
||||
|
||||
@@ -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 弹出恢复,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 查找上下文
|
||||
|
||||
@@ -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` 以
|
||||
|
||||
@@ -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 "<subscript>"
|
||||
|
||||
@@ -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 "<binop>"
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
+59
-193
@@ -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;宿主据此打印 <struct 值>)
|
||||
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 分支调用),
|
||||
|
||||
@@ -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
|
||||
|
||||
+60
-166
@@ -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 <path/to/repl.vpj> 指定\n"
|
||||
" 模板位置: 仓库 TransPyV/repl.vpj;拷到 TransPyV.exe 同目录"
|
||||
"或当前工作目录即可被自动找到\n",
|
||||
c1, c2)
|
||||
viperlib.snprintf(Diag, DiagCap, " 已查找(1): %s\n" " 已查找(2): %s\n" " 需要 --project: 未找到 repl.vpj 时 REPL 拿不到工程配置," "请用 --project <path/to/repl.vpj> 指定\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:
|
||||
# ② 会话目录:<TEMP>TransPyV_repl/<pid>(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(<exe 名>.dll.a)——"
|
||||
"跨模块符号(形如 <16位hex>.<函数名>)无法解析;"
|
||||
"宿主需按 TransPyV/project.vpj 构建(含 -Wl,--export-all-symbols),"
|
||||
"且 <exe 名>.dll.a 与 exe 同目录\n")
|
||||
stdio.printf(" 原因提示: 未找到宿主 import lib(<exe 名>.dll.a)——" "跨模块符号(形如 <16位hex>.<函数名>)无法解析;" "宿主需按 TransPyV/project.vpj 构建(含 -Wl,--export-all-symbols)," "且 <exe 名>.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("宿主符号导入库: 未找到 <exe 名>.dll.a;片段调用 includes 模块级"
|
||||
"函数会在链接期报 undefined symbol(会话不终止)。请用 "
|
||||
"TransPyV/project.vpj(已声明 -Wl,--export-all-symbols)构建宿主,"
|
||||
"并让 exe 与 .dll.a 同目录\n")
|
||||
stdio.printf("宿主符号导入库: 未找到 <exe 名>.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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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])
|
||||
|
||||
+2
-7
@@ -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
|
||||
|
||||
Reference in new issue
Block a user