初步清理 t. 类型异味

This commit is contained in:
TermiNexus committed 2026-09-11 18:36:32 +08:00
1 parent 4ce55e3ea3
commit cfb92e5da5
84 files changed
+7769 -7907

No files matched your search

+55 -55
View File
@@ -51,7 +51,7 @@ _phase2_bat_init: int = 0
SRC_BUF_SIZE: t.CDefine = 1048576 # 2^20 = 1MB
# .vpi 存根缓冲区大小(256KB,与 Phase1 一致)
PYI_BUF_SIZE: t.CSizeT = 262144
PYI_BUF_SIZE: sizet = 262144
# ============================================================
# TranslateFileGetTrans - 翻译单个文件,返回 Translator 对象
@@ -125,10 +125,10 @@ def TranslateFileGetTrans(mb: memhub.MemBuddy | t.CPtr, file_path: str,
pyi_buf: bytes = stdlib.malloc(PYI_BUF_SIZE)
if pyi_buf is not None:
pyi_buf[0] = 0
pyi_pos: t.CSizeT = StubConverter._GeneratePyiFromAst(mb, tree, None, pyi_buf, PYI_BUF_SIZE)
pyi_pos: sizet = StubConverter._GeneratePyiFromAst(mb, tree, None, pyi_buf, PYI_BUF_SIZE)
if pyi_pos > 0:
# 写入 {sha1}.vpi 到 temp_dir(切片路径)
td_len_vpi: t.CSizeT = len(temp_dir)
td_len_vpi: sizet = len(temp_dir)
pyi_path: str = StubMergerCollect._sliced_path(temp_dir, td_len_vpi, sha1_val, "vpi")
if pyi_path is not None:
pf: fileio.File | t.CPtr = fileio.File(pyi_path, fileio.MODE.W)
@@ -191,7 +191,7 @@ def TranslateFileGetTrans(mb: memhub.MemBuddy | t.CPtr, file_path: str,
class BuildResult:
Success: t.CInt
Success: int
OutputPath: str
ErrorMsg: str
@@ -216,7 +216,7 @@ def ensure_dir(path: str) -> int:
if path is None:
return 1
path_len: t.CSizeT = len(path)
path_len: sizet = len(path)
if path_len == 0:
return 0
@@ -266,19 +266,19 @@ def build_sliced_path(base_dir: str, sha1: str, ext: str) -> str:
return None
subdir: str = Config.slice_subdir(sha1, Config.Sha1SliceLevel)
base_len: t.CSizeT = len(base_dir)
sha1_len: t.CSizeT = len(sha1)
ext_len: t.CSizeT = len(ext)
base_len: sizet = len(base_dir)
sha1_len: sizet = len(sha1)
ext_len: sizet = len(ext)
if subdir is not None:
sub_len: t.CSizeT = len(subdir)
sub_len: sizet = len(subdir)
# ensure_dir({base_dir}/{subdir})
dir_path: str = _mbuddy.alloc(base_len + sub_len + 2)
if dir_path is not None:
viperlib.snprintf(dir_path, base_len + sub_len + 2, "%s/%s", base_dir, subdir)
ensure_dir(dir_path)
# 文件路径: {base_dir}/{subdir}/{sha1}.{ext}
path_len: t.CSizeT = base_len + sub_len + sha1_len + ext_len + 4
path_len: sizet = base_len + sub_len + sha1_len + ext_len + 4
path: str = _mbuddy.alloc(path_len)
if path is None: return None
viperlib.snprintf(path, path_len, "%s/%s/%s.%s", base_dir, subdir, sha1, ext)
@@ -292,7 +292,7 @@ def build_sliced_path(base_dir: str, sha1: str, ext: str) -> str:
return path
def write_ir_to_file(ir_buf: bytes, ir_len: t.CSizeT, output_dir: str, module_name: str) -> int:
def write_ir_to_file(ir_buf: bytes, ir_len: sizet, output_dir: str, module_name: str) -> int:
"""将 IR 缓冲区写入 .ll 文件
Args:
@@ -314,7 +314,7 @@ def write_ir_to_file(ir_buf: bytes, ir_len: t.CSizeT, output_dir: str, module_na
f: fileio.File | t.CPtr = fileio.File(path, fileio.MODE.W)
if f.closed: return 1
written: t.CInt64T = f.write(ir_buf, ir_len)
written: int64 = f.write(ir_buf, ir_len)
f.close()
if written < 0: return 1
return 0
@@ -351,14 +351,14 @@ def compile_ll_to_obj(ir_path: str, output_dir: str, module_name: str, cc_cmd: s
if _asan_mode != 0:
p2_asan: str = build_sliced_path(output_dir, module_name, "asan.ll")
if p2_asan is not None:
p2_olen: t.CSizeT = len(p2_asan) + len(ir_path) + 192
p2_olen: sizet = len(p2_asan) + len(ir_path) + 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, ir_path)
compile_input = p2_asan
p2_clen: t.CSizeT = len(cc_cmd) + len(cc_flags) + len(obj_path) + len(compile_input) + 64
p2_clen: sizet = len(cc_cmd) + len(cc_flags) + 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 -o %s %s",
@@ -373,7 +373,7 @@ def compile_ll_to_obj(ir_path: str, output_dir: str, module_name: str, cc_cmd: s
asan_path: str = build_sliced_path(output_dir, module_name, "asan.ll")
if asan_path is None:
return 1
opt_cmd_len: t.CSizeT = len(asan_path) + len(ir_path) + 192
opt_cmd_len: sizet = len(asan_path) + len(ir_path) + 192
opt_cmd: bytes = _mbuddy.alloc(opt_cmd_len)
if opt_cmd is None:
return 1
@@ -387,7 +387,7 @@ def compile_ll_to_obj(ir_path: str, output_dir: str, module_name: str, cc_cmd: s
compile_input = asan_path
# 构造命令: llc -filetype=obj -o {obj_path} ir_path
cmd_len: t.CSizeT = len(cc_cmd) + len(cc_flags) + len(obj_path) + len(compile_input) + 64
cmd_len: sizet = len(cc_cmd) + len(cc_flags) + len(obj_path) + len(compile_input) + 64
cmd: bytes = _mbuddy.alloc(cmd_len)
if cmd is None:
return 1
@@ -434,13 +434,13 @@ def init_llc_task(task: LlcTask | t.CPtr, ir_path: str, output_dir: str,
if obj_path is None:
return 1
# 模块 SHA1
sl: t.CSizeT = len(module_name)
sl: sizet = len(module_name)
task.ModuleSha1 = stdlib.malloc(sl + 1)
if task.ModuleSha1 is None:
return 1
string.strcpy(task.ModuleSha1, module_name)
# llc 命令
cmd_len: t.CSizeT = len(cc_cmd) + len(cc_flags) \
cmd_len: sizet = len(cc_cmd) + len(cc_flags) \
+ len(obj_path) + len(ir_path) + 64
task.LlcCmd = stdlib.malloc(cmd_len)
if task.LlcCmd is None:
@@ -452,7 +452,7 @@ def init_llc_task(task: LlcTask | t.CPtr, ir_path: str, output_dir: str,
asan_path: str = build_sliced_path(output_dir, module_name, "asan.ll")
if asan_path is None:
return 1
opt_len: t.CSizeT = len(asan_path) + len(ir_path) + 192
opt_len: sizet = len(asan_path) + len(ir_path) + 192
task.OptCmd = stdlib.malloc(opt_len)
if task.OptCmd is None:
return 1
@@ -514,7 +514,7 @@ def _run_cmd_wait(cmd: str) -> int:
"""
if cmd is None:
return -1
cl_len: t.CSizeT = len(cmd)
cl_len: sizet = len(cmd)
cmd_line: bytes = stdlib.malloc(cl_len + 1)
if cmd_line is None:
return -1
@@ -541,11 +541,11 @@ def _run_cmd_wait(cmd: str) -> int:
if ok == 0:
return -1
win32sync.WaitForSingleObject(pi.hProcess, w32.win32base.INFINITE)
exit_code: t.CUInt32T = 0
exit_code: uint32 = 0
win32process.GetExitCodeProcess(pi.hProcess, t.CPtr(c.Addr(exit_code)))
w32.win32base.CloseHandle(pi.hProcess)
w32.win32base.CloseHandle(pi.hThread)
return t.CInt(exit_code)
return int(exit_code)
def _llc_task_worker(arg: t.CPtr) -> t.CPtr:
@@ -579,7 +579,7 @@ def run_llc_parallel(tasks: bytes, task_count: int, max_threads: int) -> int:
if _phase2_cmd_path is not None:
for pi2 in range(task_count):
tsk_p: LlcTask | t.CPtr = (LlcTask | t.CPtr)(t.CVoid(
t.CUInt64T(tasks) + t.CSizeT(pi2) * LlcTask.__sizeof__(), t.CPtr))
uint64(tasks) + sizet(pi2) * LlcTask.__sizeof__(), t.CPtr))
if tsk_p is None:
continue
if tsk_p.OptCmd is not None:
@@ -599,7 +599,7 @@ def run_llc_parallel(tasks: bytes, task_count: int, max_threads: int) -> int:
if handles is None:
VLogger.error("run_llc_parallel: 线程句柄数组分配失败", "PhaseB")
return 1
slot_size: t.CSizeT = LlcTask.__sizeof__()
slot_size: sizet = LlcTask.__sizeof__()
ret: int = 0
# 分批执行:batch_start 按 max_threads 步进(每批 spawn+join+close 一批句柄)。
for batch_start in range(0, task_count, max_threads):
@@ -609,7 +609,7 @@ def run_llc_parallel(tasks: bytes, task_count: int, max_threads: int) -> int:
# 本批 spawn
for j in range(batch_n):
tsk: LlcTask | t.CPtr = (LlcTask | t.CPtr)(t.CVoid(
t.CUInt64T(tasks) + t.CSizeT(batch_start + j) * slot_size, t.CPtr))
uint64(tasks) + sizet(batch_start + j) * slot_size, t.CPtr))
th: vthreading.Thread | t.CPtr = vthreading.Thread(_llc_task_worker, t.CPtr(tsk))
th.start()
# start() 后立即取出句柄(Thread 对象栈地址可能被后续构造复用,
@@ -617,22 +617,22 @@ def run_llc_parallel(tasks: bytes, task_count: int, max_threads: int) -> int:
handles.append(t.CPtr(th.handle))
for j in range(batch_n):
h_j: t.CPtr = t.CPtr(handles.get(batch_start + j))
wr: t.CUInt32T = win32sync.WaitForSingleObject(h_j, 600000)
wr: uint32 = win32sync.WaitForSingleObject(h_j, 600000)
if wr != 0:
VLogger.error("llc 线程 join 超时/失败(600 秒未完成)", "PhaseB")
w32.win32base.CloseHandle(h_j)
# 本批结果检查
for j in range(batch_n):
tsk2: LlcTask | t.CPtr = (LlcTask | t.CPtr)(t.CVoid(
t.CUInt64T(tasks) + t.CSizeT(batch_start + j) * slot_size, t.CPtr))
uint64(tasks) + sizet(batch_start + j) * slot_size, t.CPtr))
if tsk2 is not None and tsk2.Result != 0:
VLogger.error(f"llc 编译失败: {(tsk2.ModuleSha1 if tsk2.ModuleSha1 is not None else "?")} (cmd={(tsk2.LlcCmd if tsk2.LlcCmd is not None else "?")})", "LLC")
ret = 1
return ret
def _CollectObjFilesImpl(base_dir: str, bd_len: t.CSizeT,
out_buf: bytes, out_pos: t.CSizeT, out_size: t.CSizeT) -> t.CSizeT:
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)。
@@ -658,7 +658,7 @@ def _CollectObjFilesImpl(base_dir: str, bd_len: t.CSizeT,
while True:
fname: str = find_data.cFileName
if fname is not None:
fname_len: t.CSizeT = len(fname)
fname_len: sizet = len(fname)
if fname_len > 0:
# 跳过 . 和 ..
is_dot: int = 0
@@ -676,7 +676,7 @@ def _CollectObjFilesImpl(base_dir: str, bd_len: t.CSizeT,
sub_dir: bytes = _mbuddy.alloc(bd_len + fname_len + 2)
if sub_dir is not None:
viperlib.snprintf(sub_dir, bd_len + fname_len + 2, "%s/%s", base_dir, fname)
sub_len: t.CSizeT = len(sub_dir)
sub_len: sizet = len(sub_dir)
out_pos = _CollectObjFilesImpl(sub_dir, sub_len, out_buf, out_pos, out_size)
_mbuddy.free(sub_dir)
else:
@@ -684,7 +684,7 @@ def _CollectObjFilesImpl(base_dir: str, bd_len: t.CSizeT,
if fname_len > 4 and fname[fname_len - 4] == '.' \
and fname[fname_len - 3] == 'o' and fname[fname_len - 2] == 'b' \
and fname[fname_len - 1] == 'j':
need: t.CSizeT = bd_len + 1 + fname_len + 2
need: sizet = bd_len + 1 + fname_len + 2
if out_pos + need >= out_size:
break
if out_pos > 0:
@@ -700,7 +700,7 @@ def _CollectObjFilesImpl(base_dir: str, bd_len: t.CSizeT,
return out_pos
def collect_obj_files(includes_binary_dir: str, out_buf: bytes, out_size: t.CSizeT) -> t.CSizeT:
def collect_obj_files(includes_binary_dir: str, out_buf: bytes, out_size: sizet) -> sizet:
"""递归扫描 includes_binary_dir 目录,收集所有 .obj 文件路径到 out_buf
支持切片子目录(如 includes_binary_dir/43/{sha1}.obj)。
@@ -717,8 +717,8 @@ def collect_obj_files(includes_binary_dir: str, out_buf: bytes, out_size: t.CSiz
return 0
out_buf[0] = '\0'
dir_len: t.CSizeT = len(includes_binary_dir)
out_pos: t.CSizeT = _CollectObjFilesImpl(includes_binary_dir, dir_len, out_buf, 0, out_size)
dir_len: sizet = len(includes_binary_dir)
out_pos: sizet = _CollectObjFilesImpl(includes_binary_dir, dir_len, out_buf, 0, out_size)
out_buf[out_pos] = '\0'
return out_pos
@@ -749,11 +749,11 @@ def link_obj_to_exe(output_dir: str, module_name: str, linker_cmd: str, linker_f
return 1
# 收集 includes.binary 的 .obj 文件路径
EXTRA_BUF_SIZE: t.CSizeT = 32768
EXTRA_BUF_SIZE: sizet = 32768
extra_objs: bytes = _mbuddy.alloc(EXTRA_BUF_SIZE)
if extra_objs is None:
return 1
extra_len: t.CSizeT = 0
extra_len: sizet = 0
if includes_binary_dir is not None:
extra_len = collect_obj_files(includes_binary_dir, extra_objs, EXTRA_BUF_SIZE)
if extra_len > 0:
@@ -787,8 +787,8 @@ def link_obj_to_exe(output_dir: str, module_name: str, linker_cmd: str, linker_f
viperlib.snprintf(merged_sl, len(static_libs) + len(linker_dynamic_libs) + 2,
"%s", linker_dynamic_libs)
static_libs = merged_sl
sl_len: t.CSizeT = len(static_libs)
cmd_len: t.CSizeT = len(linker_cmd) + len(obj_path) + len(use_flags) + len(output_dir) + len(linker_output) + extra_len + sl_len + 128
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
@@ -859,7 +859,7 @@ def asm_to_obj(asm_path: str, sha1_val: str, output_dir: str,
trip: str = triple
if trip is None or trip[0] == '\0':
trip = "x86_64-none-elf"
cmd_len: t.CSizeT = len("llvm-mc -triple=") + len(trip) \
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:
@@ -886,7 +886,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: t.CSizeT,
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(不链接)
@@ -924,7 +924,7 @@ def compile_module_to_obj(ir_buf: bytes, ir_len: t.CSizeT,
return 0
def link_objs_to_exe(obj_paths: str, obj_paths_len: t.CSizeT,
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
@@ -953,33 +953,33 @@ def link_objs_to_exe(obj_paths: str, obj_paths_len: t.CSizeT,
dedup: bytes = _mbuddy.alloc(obj_paths_len + 1)
if dedup is not None:
dedup[0] = '\0'
dpos: t.CSizeT = 0
dsrc_i: t.CSizeT = 0
dpos: sizet = 0
dsrc_i: sizet = 0
while dsrc_i < obj_paths_len:
# 跳过前导空格
while dsrc_i < obj_paths_len and obj_paths[dsrc_i] == ' ':
dsrc_i += 1
if dsrc_i >= obj_paths_len:
break
dstart: t.CSizeT = dsrc_i
dstart: sizet = dsrc_i
while dsrc_i < obj_paths_len and obj_paths[dsrc_i] != ' ':
dsrc_i += 1
dtlen: t.CSizeT = dsrc_i - dstart
dtlen: sizet = dsrc_i - dstart
# 检查 dedup 中是否已有相同 token
ddup: int = 0
dj: t.CSizeT = 0
dj: sizet = 0
while dj < dpos:
while dj < dpos and dedup[dj] == ' ':
dj += 1
if dj >= dpos:
break
ds2: t.CSizeT = dj
ds2: sizet = dj
while dj < dpos and dedup[dj] != ' ':
dj += 1
dt2len: t.CSizeT = dj - ds2
dt2len: sizet = dj - ds2
if dt2len == dtlen:
deq: int = 1
dk: t.CSizeT = 0
dk: sizet = 0
while dk < dtlen:
if dedup[ds2 + dk] != obj_paths[dstart + dk]:
deq = 0
@@ -1000,11 +1000,11 @@ def link_objs_to_exe(obj_paths: str, obj_paths_len: t.CSizeT,
obj_paths_len = dpos
# 收集 includes.binary 的 .obj 文件路径
EXTRA_BUF_SIZE: t.CSizeT = 32768
EXTRA_BUF_SIZE: sizet = 32768
extra_objs: bytes = _mbuddy.alloc(EXTRA_BUF_SIZE)
if extra_objs is None:
return 1
extra_len: t.CSizeT = 0
extra_len: sizet = 0
if includes_binary_dir is not None:
extra_len = collect_obj_files(includes_binary_dir, extra_objs, EXTRA_BUF_SIZE)
@@ -1026,8 +1026,8 @@ def link_objs_to_exe(obj_paths: str, obj_paths_len: t.CSizeT,
viperlib.snprintf(merged_sl2, len(static_libs2) + len(linker_dynamic_libs) + 2,
"%s", linker_dynamic_libs)
static_libs2 = merged_sl2
sl2_len: t.CSizeT = len(static_libs2)
cmd_len: t.CSizeT = len(linker_cmd) + obj_paths_len + len(use_flags) + len(linker_output) + extra_len + sl2_len + 128
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
cmd: bytes = _mbuddy.alloc(cmd_len)
if cmd is None:
return 1
@@ -1071,7 +1071,7 @@ def link_objs_to_exe(obj_paths: str, obj_paths_len: t.CSizeT,
return 0
def run_pipeline(ir_buf: bytes, ir_len: t.CSizeT,
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,
+90 -90
View File
@@ -63,7 +63,7 @@ def _InjectedCreatesCycle(entry: IncludesScanner.FileEntry | t.CPtr,
if nm_buf is None:
return 0
if dot is not None:
nm_len: t.CSizeT = t.CSizeT(t.CUInt64T(dot) - t.CUInt64T(base))
nm_len: sizet = sizet(uint64(dot) - uint64(base))
if nm_len > 127:
nm_len = 127
string.strncpy(nm_buf, base, nm_len)
@@ -71,14 +71,14 @@ def _InjectedCreatesCycle(entry: IncludesScanner.FileEntry | t.CPtr,
else:
string.strncpy(nm_buf, base, 127)
nm_buf[127] = '\0'
nm_len2: t.CSizeT = string.strlen(nm_buf)
d_len: t.CSizeT = string.strlen(inj_deps)
dp: t.CSizeT = 0
nm_len2: sizet = string.strlen(nm_buf)
d_len: sizet = string.strlen(inj_deps)
dp: sizet = 0
while dp < d_len:
ts: t.CSizeT = dp
ts: sizet = dp
while dp < d_len and inj_deps[dp] != ' ':
dp += 1
tl: t.CSizeT = dp - ts
tl: sizet = dp - ts
if dp < d_len:
dp += 1
if tl > 0 and tl == nm_len2 and string.strncmp(inj_deps + ts, nm_buf, tl) == 0:
@@ -92,14 +92,14 @@ def _DepsContainsName(deps: str, name: str) -> int:
"""deps 字符串(空格分隔模块名)是否含 name token(词边界精确匹配)"""
if deps is None or name is None:
return 0
nl: t.CSizeT = string.strlen(name)
dl: t.CSizeT = string.strlen(deps)
dp: t.CSizeT = 0
nl: sizet = string.strlen(name)
dl: sizet = string.strlen(deps)
dp: sizet = 0
while dp < dl:
ts: t.CSizeT = dp
ts: sizet = dp
while dp < dl and deps[dp] != ' ':
dp += 1
tl: t.CSizeT = dp - ts
tl: sizet = dp - ts
if dp < dl:
dp += 1
if tl == nl and string.strncmp(deps + ts, name, nl) == 0:
@@ -111,19 +111,19 @@ def _DepsRemoveName(deps: str, name: str) -> int:
"""从 deps 字符串移除 name token(原地重建,返回 1=有改动)"""
if deps is None or name is None:
return 0
nl: t.CSizeT = string.strlen(name)
dl: t.CSizeT = string.strlen(deps)
nl: sizet = string.strlen(name)
dl: sizet = string.strlen(deps)
buf: bytes = stdlib.malloc(StubMerger.MAX_DEPS_STR_LEN)
if buf is None:
return 0
buf[0] = '\0'
bl: t.CSizeT = 0
dp: t.CSizeT = 0
bl: sizet = 0
dp: sizet = 0
while dp < dl:
ts: t.CSizeT = dp
ts: sizet = dp
while dp < dl and deps[dp] != ' ':
dp += 1
tl: t.CSizeT = dp - ts
tl: sizet = dp - ts
if dp < dl:
dp += 1
if tl == 0:
@@ -145,13 +145,13 @@ def _RewriteDepsTxt(temp_dir: str, sha1: str, deps_str: str) -> None:
"""重写 {temp_dir}/{sha1前2位}/{sha1}.deps.txt(内存破环后同步磁盘)"""
if temp_dir is None or sha1 is None or deps_str is None:
return
td_len: t.CSizeT = string.strlen(temp_dir)
td_len: sizet = string.strlen(temp_dir)
dpath: str = StubMergerCollect._sliced_path(temp_dir, td_len, sha1, "deps.txt")
if dpath is None:
return
df: fileio.File | t.CPtr = fileio.File(dpath, fileio.MODE.W)
if not df.closed:
dl: t.CSizeT = string.strlen(deps_str)
dl: sizet = string.strlen(deps_str)
if dl > 0:
df.write(deps_str, dl)
df.close()
@@ -172,11 +172,11 @@ def _BreakContainerCyclesInDeps(temp_dir: str) -> int:
"""
if StubMerger._includes_deps_sha1 is None or StubMerger._includes_deps_str is None:
return 0
cnt: t.CSizeT = StubMerger._includes_deps_count
ci: t.CSizeT
cnt: sizet = StubMerger._includes_deps_count
ci: sizet
for ci in range(cnt):
sha1_m: str = StubMerger._includes_deps_sha1 + t.CSizeT(ci) * 17
deps_m: str = StubMerger._includes_deps_str + t.CSizeT(ci) * StubMerger.MAX_DEPS_STR_LEN
sha1_m: str = StubMerger._includes_deps_sha1 + sizet(ci) * 17
deps_m: str = StubMerger._includes_deps_str + sizet(ci) * StubMerger.MAX_DEPS_STR_LEN
if sha1_m is None or deps_m is None:
continue
if string.strstr(deps_m, "_list") is None and string.strstr(deps_m, "_dict") is None:
@@ -194,7 +194,7 @@ def _BreakContainerCyclesInDeps(temp_dir: str) -> int:
base_m = rel_m
dot_m: str = string.strchr(base_m, '.')
if dot_m is not None:
nm_len_m: t.CSizeT = t.CSizeT(t.CUInt64T(dot_m) - t.CUInt64T(base_m))
nm_len_m: sizet = sizet(uint64(dot_m) - uint64(base_m))
nm_m: bytes = stdlib.malloc(nm_len_m + 1)
if nm_m is None:
continue
@@ -248,23 +248,23 @@ def _BuildReachableResult(mb: memhub.MemBuddy | t.CPtr,
"""从 Sha1Store(仅可达 includes + App)构建可达 FileEntry 列表"""
if mb is None:
return None
store_count: t.CSizeT = t.CSizeT(StubMerger._sha1_store_count)
store_count: sizet = sizet(StubMerger._sha1_store_count)
if store_count <= 0 or StubMerger._sha1_store_arr is None:
return None
result: IncludesScanner.ScanResult | t.CPtr = IncludesScanner.create_scan_result(mb)
if result is None:
return None
entry_size: t.CSizeT = IncludesScanner.FileEntry.__sizeof__()
i: t.CSizeT
entry_size: sizet = IncludesScanner.FileEntry.__sizeof__()
i: sizet
for i in range(store_count):
sidx: t.CSizeT = t.CSizeT(i) * 17
sidx: sizet = sizet(i) * 17
if StubMerger._sha1_store_arr[sidx] == '\0':
continue
# 仅 includes 条目(incdir 非空);App 条目不进入 result
iidx: t.CSizeT = t.CSizeT(i) * StubMerger.MAX_INC_DIR_LEN
iidx: sizet = sizet(i) * StubMerger.MAX_INC_DIR_LEN
if StubMerger._sha1_store_incdir[iidx] == '\0':
continue
eaddr: t.CUInt64T = t.CUInt64T(result.Entries) + t.CUInt64T(result.Count) * entry_size
eaddr: uint64 = uint64(result.Entries) + uint64(result.Count) * entry_size
entry: IncludesScanner.FileEntry | t.CPtr = (IncludesScanner.FileEntry | t.CPtr)(t.CVoid(eaddr, t.CPtr))
if entry is None:
continue
@@ -275,9 +275,9 @@ def _BuildReachableResult(mb: memhub.MemBuddy | t.CPtr,
string.strcpy(sha1_buf, StubMerger._sha1_store_arr + sidx)
entry.Sha1 = sha1_buf
# RelPath / IncDir 深拷贝
ridx: t.CSizeT = t.CSizeT(i) * StubMerger.MAX_REL_PATH_LEN
rel_len: t.CSizeT = string.strlen(StubMerger._sha1_store_rel + ridx)
inc_len: t.CSizeT = string.strlen(StubMerger._sha1_store_incdir + iidx)
ridx: sizet = sizet(i) * StubMerger.MAX_REL_PATH_LEN
rel_len: sizet = string.strlen(StubMerger._sha1_store_rel + ridx)
inc_len: sizet = string.strlen(StubMerger._sha1_store_incdir + iidx)
rel_buf: bytes = stdlib.malloc(rel_len + 1)
inc_buf: bytes = stdlib.malloc(inc_len + 1)
if rel_buf is None or inc_buf is None:
@@ -303,8 +303,8 @@ def _BuildReachableResult(mb: memhub.MemBuddy | t.CPtr,
string.strcpy(abs_buf + inc_len + 1, rel_buf)
entry.Path = abs_buf
# 模块名(store 登记时保存的绝对模块名)
midx: t.CSizeT = t.CSizeT(i) * 64
mod_len: t.CSizeT = string.strlen(StubMerger._sha1_store_mod + midx)
midx: sizet = sizet(i) * 64
mod_len: sizet = string.strlen(StubMerger._sha1_store_mod + midx)
if mod_len > 0:
mod_buf: bytes = stdlib.malloc(mod_len + 1)
if mod_buf is not None:
@@ -367,7 +367,7 @@ def RunPhase1(mb: memhub.MemBuddy | t.CPtr, includes_dir: str, temp_dir: str,
# 读文件+算 SHA1+解析 import,补充依赖图并登记 Sha1Store/
# deps 存储器/写 deps.txt
# 3) 未引用的 includes 从不读取(根本不扫描)
t_scan0: t.CUInt64T = w32.win32base.GetTickCount64()
t_scan0: uint64 = w32.win32base.GetTickCount64()
reachable_set: str = None
reachable_count: int = 0
use_reachable: int = 0
@@ -392,7 +392,7 @@ def RunPhase1(mb: memhub.MemBuddy | t.CPtr, includes_dir: str, temp_dir: str,
else:
VLogger.warning("SourceDir 不可用,无法构建依赖图,跳过 Phase1", "Phase1")
return 0
t_scan1: t.CUInt64T = w32.win32base.GetTickCount64()
t_scan1: uint64 = w32.win32base.GetTickCount64()
VLogger.info(f"依赖图扫描总耗时: {t_scan1 - t_scan0} ms(可达 {reachable_count} 个 includes)", "Phase1")
# 从 Sha1Store(仅可达 includes + App)构造可达 FileEntry 列表:
@@ -419,7 +419,7 @@ def RunPhase1(mb: memhub.MemBuddy | t.CPtr, includes_dir: str, temp_dir: str,
# HandlesExprCall._lookup_module_sha1 直接查全局存储器。
# FileEntry 结构体大小(Phase 1a 和 1b 共用)
entry_size: t.CSizeT = IncludesScanner.FileEntry.__sizeof__()
entry_size: sizet = IncludesScanner.FileEntry.__sizeof__()
# ============================================================
@@ -469,7 +469,7 @@ def RunPhase1(mb: memhub.MemBuddy | t.CPtr, includes_dir: str, temp_dir: str,
generic_file_indices, generic_file_count_box)
if class_count_scanned > 0:
td_len_ts_call: t.CSizeT = string.strlen(temp_dir)
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,
@@ -477,7 +477,7 @@ def RunPhase1(mb: memhub.MemBuddy | t.CPtr, includes_dir: str, temp_dir: str,
topo_order, topo_count_box,
temp_dir, td_len_ts_call)
if ret_topo == 0:
tc_ptr: t.CPtr = (t.CInt | t.CPtr)(t.CVoid(topo_count_box, t.CPtr))
tc_ptr: t.CPtr = (int | t.CPtr)(t.CVoid(topo_count_box, t.CPtr))
if tc_ptr is not None:
topo_count = tc_ptr[0]
VLogger.info(f"拓扑排序: {class_count_scanned} 个类, {topo_count} 个文件按依赖顺序处理", "Phase1")
@@ -494,15 +494,15 @@ def RunPhase1(mb: memhub.MemBuddy | t.CPtr, includes_dir: str, temp_dir: str,
# 1a-pre-generic 只覆盖"可达"泛型文件;非可达泛型文件(如 FuncTest
# 场景的 linkedlist/llvmlite/_list)的模板要等 Phase2 Phase A-pre-inc
# (mark2 之后)才注册 → reset 回收表/节点 → _find_generic_template
# 此处对全部 includes 轻量预注册,使模板表与节点都落在 mark1 之前。
# result 只是"可达子集",非可达的 _list/_dict/linkedlist/llvmlite 等泛型文件
# 模板不会注册 → list[int]/dict[...] 特化失败(ast/base.vp _dump_op_list 根因)。
# _PreRegisterAllGenericTemplates 内有 generic marker 文本预筛,全量扫描
# 不 parse 全部 AST,仅对含 marker 的文件轻量处理,OOM 风险可控。
full_scan_g: IncludesScanner.ScanResult | t.CPtr = IncludesScanner.scan_includes(mb, includes_dir)
if full_scan_g is not None:
Phase1Scan._PreRegisterAllGenericTemplates(mb, full_scan_g)
else:
# 此处对全部 includes 轻量预注册,使模板表与节点都落在 mark1 之前。
# result 只是"可达子集",非可达的 _list/_dict/linkedlist/llvmlite 等泛型文件
# 模板不会注册 → list[int]/dict[...] 特化失败(ast/base.vp _dump_op_list 根因)。
# _PreRegisterAllGenericTemplates 内有 generic marker 文本预筛,全量扫描
# 不 parse 全部 AST,仅对含 marker 的文件轻量处理,OOM 风险可控。
full_scan_g: IncludesScanner.ScanResult | t.CPtr = IncludesScanner.scan_includes(mb, includes_dir)
if full_scan_g is not None:
Phase1Scan._PreRegisterAllGenericTemplates(mb, full_scan_g)
else:
Phase1Scan._PreRegisterAllGenericTemplates(mb, result)
# ============================================================
@@ -523,19 +523,19 @@ def RunPhase1(mb: memhub.MemBuddy | t.CPtr, includes_dir: str, temp_dir: str,
# 遍历文件:优先使用拓扑顺序,回退到字母序
iter_count: int = topo_count if topo_count > 0 else result.Count
# 1a 阶段总耗时起点(struct/enum/union 注册)
t_a0: t.CUInt64T = w32.win32base.GetTickCount64()
t_a0: uint64 = w32.win32base.GetTickCount64()
for i in range(iter_count):
# 每文件级 mark:翻译完回收该文件 AST(注册数据在 perm_pool)
p1a_mark: t.CSizeT = mb.mark()
p1a_mark: sizet = mb.mark()
# 获取文件索引:拓扑顺序或字母序
file_idx: int = i
if topo_count > 0:
od_addr: t.CUInt64T = t.CUInt64T(topo_order) + i * 4
od_ptr: t.CPtr = (t.CInt | t.CPtr)(t.CVoid(od_addr, t.CPtr))
od_addr: uint64 = uint64(topo_order) + i * 4
od_ptr: t.CPtr = (int | t.CPtr)(t.CVoid(od_addr, t.CPtr))
if od_ptr is not None:
file_idx = od_ptr[0]
entry_addr_r: t.CUInt64T = t.CUInt64T(result.Entries) + file_idx * entry_size
entry_addr_r: uint64 = uint64(result.Entries) + file_idx * entry_size
entry_r: IncludesScanner.FileEntry | t.CPtr = (IncludesScanner.FileEntry | t.CPtr)(t.CVoid(entry_addr_r, t.CPtr))
if entry_r is None:
p1a_fl += 1
@@ -558,7 +558,7 @@ def RunPhase1(mb: memhub.MemBuddy | t.CPtr, includes_dir: str, temp_dir: str,
continue
# 单文件计时起点(读文件 + parse 段,定位 1a 卡点)
t_fa0: t.CUInt64T = w32.win32base.GetTickCount64()
t_fa0: uint64 = w32.win32base.GetTickCount64()
# 读取文件内容
file_path_r: str = entry_r.Path
@@ -604,7 +604,7 @@ def RunPhase1(mb: memhub.MemBuddy | t.CPtr, includes_dir: str, temp_dir: str,
continue
# 计时点 1:读文件 + parse 完成
t_fa1: t.CUInt64T = w32.win32base.GetTickCount64()
t_fa1: uint64 = w32.win32base.GetTickCount64()
# 创建 Translator,设置 _declare_only=1(注册 struct/enum/union)
tr_r: HandlesTranslator.Translator | t.CPtr = HandlesTranslator.Translator()
@@ -623,7 +623,7 @@ def RunPhase1(mb: memhub.MemBuddy | t.CPtr, includes_dir: str, temp_dir: str,
GenApi.reset_visible_structs(mb, 0)
ret_r: int = tr_r.translate(tree_r)
# 计时点 2:translate(declare=1) 返回
t_fa2: t.CUInt64T = w32.win32base.GetTickCount64()
t_fa2: uint64 = w32.win32base.GetTickCount64()
if ret_r != 0:
p1a_fl += 1
else:
@@ -644,7 +644,7 @@ def RunPhase1(mb: memhub.MemBuddy | t.CPtr, includes_dir: str, temp_dir: str,
mb.reset_to(p1a_mark)
# 1a 阶段总耗时(struct/enum/union 注册,含每文件读+parse+翻译声明)
t_a1: t.CUInt64T = w32.win32base.GetTickCount64()
t_a1: uint64 = w32.win32base.GetTickCount64()
VLogger.info(f"1a 总耗时: {t_a1-t_a0} ms (注册 struct/enum, reg={p1a_reg} skp={p1a_skp})", "Phase1")
if p1a_fl > 0:
@@ -672,7 +672,7 @@ def RunPhase1(mb: memhub.MemBuddy | t.CPtr, includes_dir: str, temp_dir: str,
# _renum_*/关键字表等)都落在 mark1 之前。
# 1b 每文件翻译完后 reset_to(mark1) 回收该文件的 AST/IR/Handler/dump 临时,
# 避免 90 文件累积导致 1GB 池 OOM。
mark1: t.CSizeT = mb.mark()
mark1: sizet = mb.mark()
# 1b 阶段新注册的 struct/enum 条目改 stdlib 分配(跨文件永久存活,不被 reset 回收)
GenApi.set_stdlib_alloc(1)
@@ -687,11 +687,11 @@ def RunPhase1(mb: memhub.MemBuddy | t.CPtr, includes_dir: str, temp_dir: str,
# 而 define 返回 i8*)→ 运行时返回值截断崩溃。
# ============================================================
p1bpre_failed: int = 0
dir_len_pv: t.CSizeT = string.strlen(temp_dir)
dir_len_pv: sizet = string.strlen(temp_dir)
# 1b-pre 阶段总耗时起点(vpi 预生成)
t_pv0: t.CUInt64T = w32.win32base.GetTickCount64()
t_pv0: uint64 = w32.win32base.GetTickCount64()
for i_pv in range(result.Count):
entry_addr_pv: t.CUInt64T = t.CUInt64T(result.Entries) + i_pv * entry_size
entry_addr_pv: uint64 = uint64(result.Entries) + i_pv * entry_size
entry_pv: IncludesScanner.FileEntry | t.CPtr = (IncludesScanner.FileEntry | t.CPtr)(t.CVoid(entry_addr_pv, t.CPtr))
if entry_pv is None or entry_pv.Sha1 is None:
p1bpre_failed += 1
@@ -763,7 +763,7 @@ def RunPhase1(mb: memhub.MemBuddy | t.CPtr, includes_dir: str, temp_dir: str,
continue
pyi_buf_pv: bytes = stdlib.malloc(Phase1.PYI_BUF_SIZE)
if pyi_buf_pv is not None:
pyi_pos_pv: t.CSizeT = StubConverter._GeneratePyiFromAst(mb, tree_pv, entry_pv.RelPath, pyi_buf_pv, Phase1.PYI_BUF_SIZE)
pyi_pos_pv: sizet = StubConverter._GeneratePyiFromAst(mb, tree_pv, entry_pv.RelPath, pyi_buf_pv, Phase1.PYI_BUF_SIZE)
if pyi_pos_pv > 0:
pyi_path_pv: str = StubMergerCollect._sliced_path(temp_dir, dir_len_pv, sha1_pv, "vpi")
if pyi_path_pv is not None:
@@ -781,7 +781,7 @@ def RunPhase1(mb: memhub.MemBuddy | t.CPtr, includes_dir: str, temp_dir: str,
mb.reset_to(mark1)
# 1b-pre 阶段总耗时(vpi 预生成)
t_pv1: t.CUInt64T = w32.win32base.GetTickCount64()
t_pv1: uint64 = w32.win32base.GetTickCount64()
VLogger.info(f"1b-pre 总耗时: {t_pv1-t_pv0} ms (vpi 预生成)", "Phase1")
if p1bpre_failed > 0:
@@ -794,7 +794,7 @@ def RunPhase1(mb: memhub.MemBuddy | t.CPtr, includes_dir: str, temp_dir: str,
skipped: int = 0
failed: int = 0
# 1b 阶段总耗时起点(全量翻译)
t_b0: t.CUInt64T = w32.win32base.GetTickCount64()
t_b0: uint64 = w32.win32base.GetTickCount64()
loop_n_b: int = result.Count
if topo_count > 0:
@@ -803,11 +803,11 @@ def RunPhase1(mb: memhub.MemBuddy | t.CPtr, includes_dir: str, temp_dir: str,
# 获取 entry(拓扑序:file_idx 从 topo_order 取,否则用扫描索引)
file_idx_b: int = i
if topo_count > 0:
od_addr_b: t.CUInt64T = t.CUInt64T(topo_order) + t.CSizeT(i) * 4
od_ptr_b: t.CPtr = (t.CInt | t.CPtr)(t.CVoid(od_addr_b, t.CPtr))
od_addr_b: uint64 = uint64(topo_order) + sizet(i) * 4
od_ptr_b: t.CPtr = (int | t.CPtr)(t.CVoid(od_addr_b, t.CPtr))
if od_ptr_b is not None:
file_idx_b = od_ptr_b[0]
entry_addr: t.CUInt64T = t.CUInt64T(result.Entries) + t.CSizeT(file_idx_b) * entry_size
entry_addr: uint64 = uint64(result.Entries) + sizet(file_idx_b) * entry_size
entry: IncludesScanner.FileEntry | t.CPtr = (IncludesScanner.FileEntry | t.CPtr)(t.CVoid(entry_addr, t.CPtr))
if entry is None:
failed += 1
@@ -831,8 +831,8 @@ def RunPhase1(mb: memhub.MemBuddy | t.CPtr, includes_dir: str, temp_dir: str,
continue
# 构造 stub 路径: {temp_dir}/{sha1}.stub.ll
dir_len: t.CSizeT = string.strlen(temp_dir)
sha1_len: t.CSizeT = string.strlen(sha1)
dir_len: sizet = string.strlen(temp_dir)
sha1_len: sizet = string.strlen(sha1)
stub_path: str = StubMergerCollect._sliced_path(temp_dir, dir_len, sha1, "stub.ll")
if stub_path is None:
failed += 1
@@ -857,16 +857,16 @@ def RunPhase1(mb: memhub.MemBuddy | t.CPtr, includes_dir: str, temp_dir: str,
if vrd_1b > 0:
if vrd_1b < 1048576:
vbuf_1b[vrd_1b] = 0
vtotal_1b: t.CSizeT = string.strlen(vbuf_1b)
vpos_1b: t.CSizeT = 0
vtotal_1b: sizet = string.strlen(vbuf_1b)
vpos_1b: sizet = 0
while vpos_1b < vtotal_1b:
vls_1b: t.CSizeT = vpos_1b
vls_1b: sizet = vpos_1b
while vpos_1b < vtotal_1b and vbuf_1b[vpos_1b] != '\n':
vpos_1b += 1
vll_1b: t.CSizeT = vpos_1b - vls_1b
vll_1b: sizet = vpos_1b - vls_1b
if vpos_1b < vtotal_1b:
vpos_1b += 1
vi2_1b: t.CSizeT = vls_1b
vi2_1b: sizet = vls_1b
while vi2_1b < vls_1b + vll_1b and vbuf_1b[vi2_1b] == ' ':
vi2_1b += 1
if vll_1b >= 6 and string.strncmp(vbuf_1b + vi2_1b, "class ", 6) == 0:
@@ -906,7 +906,7 @@ def RunPhase1(mb: memhub.MemBuddy | t.CPtr, includes_dir: str, temp_dir: str,
stdlib.free(stub_path)
# 单文件计时起点:读文件(parse/translate/dump 三段,对齐 Phase2 插桩)
t_f0: t.CUInt64T = w32.win32base.GetTickCount64()
t_f0: uint64 = w32.win32base.GetTickCount64()
# 读取文件内容
file_path: str = entry.Path
@@ -959,7 +959,7 @@ def RunPhase1(mb: memhub.MemBuddy | t.CPtr, includes_dir: str, temp_dir: str,
continue
# 计时点 1:读文件 + lexer/tokenize/parse 完成
t_f1: t.CUInt64T = w32.win32base.GetTickCount64()
t_f1: uint64 = w32.win32base.GetTickCount64()
# 文本扫描注册 CTypedef(stdint.vp 崩溃根因修复):AST 字符串字段
# (attr/id)token 零拷贝指向 src_buf,跨阶段内容不稳定(悬空),
@@ -980,7 +980,7 @@ def RunPhase1(mb: memhub.MemBuddy | t.CPtr, 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: t.CSizeT = StubConverter._GeneratePyiFromAst(
pyi_pos: sizet = StubConverter._GeneratePyiFromAst(
mb, tree, entry.RelPath, pyi_buf, Phase1.PYI_BUF_SIZE)
if pyi_pos > 0:
pf_1b: fileio.File | t.CPtr = fileio.File(vpi_path_1b, fileio.MODE.W)
@@ -1008,14 +1008,14 @@ def RunPhase1(mb: memhub.MemBuddy | t.CPtr, includes_dir: str, temp_dir: str,
# 翻译前哨兵:AST 解析(lexer/tokenize/parse_tokens)同样在 pool 分配,
# 若解析器越界写破坏了存活块 header,此处立即定位到当前文件
# (崩溃点漂移排查:把"翻译过程中随机崩"变成确定性定位)
pre_rc: t.CInt = mb.check_alive_blocks(mark1)
pre_rc: int = mb.check_alive_blocks(mark1)
if pre_rc != 0:
VLogger.error(f"内存损坏(翻译前存活块, rc={pre_rc}): {file_path}", "Phase1")
stdlib.exit(1)
ret: int = tr.translate(tree)
# 计时点 2:translate 返回
t_f2: t.CUInt64T = w32.win32base.GetTickCount64()
t_f2: uint64 = w32.win32base.GetTickCount64()
# 诊断:translate 正常返回(若挂起在 translate 内部,此行不会打印,
# 用于区分"translate 内部挂起"与"后续 dump 挂起")
if ret == 0:
@@ -1034,14 +1034,14 @@ def RunPhase1(mb: memhub.MemBuddy | t.CPtr, includes_dir: str, temp_dir: str,
# 覆盖不到 translate 期间的 AST/IR 写穿。dump 前立即检查存活块
# header/canary(rc=6 块尾 canary 损坏=越界写穿数据区),把"dump
# 时链表成环卡死"变成"定位到 translate 期间写穿发生的文件"。
post_rc: t.CInt = mb.check_alive_blocks(mark1)
post_rc: int = mb.check_alive_blocks(mark1)
if post_rc != 0:
VLogger.error(f"内存损坏(translate后存活块, rc={post_rc}): {file_path}", "Phase1")
# dump stub IR(declarations only)
# 1MB 不够:ast/parser.vp 的 text.ll 超 1MB 被截断 → 合并 IR 尾部丢字
# (opt: "end of file in global variable name"),提至 8MB。
PHASE1_IR_SIZE: t.CSizeT = 8388608
PHASE1_IR_SIZE: sizet = 8388608
stub_buf: bytes = stdlib.malloc(PHASE1_IR_SIZE)
if stub_buf is None:
stdlib.free(src_buf)
@@ -1052,10 +1052,10 @@ def RunPhase1(mb: memhub.MemBuddy | t.CPtr, includes_dir: str, temp_dir: str,
failed += 1
continue
tr.dump_ir(stub_buf, PHASE1_IR_SIZE, llvmlite.OUTPUT_STUB)
stub_len: t.CSizeT = string.strlen(stub_buf)
stub_len: sizet = string.strlen(stub_buf)
# save stub.ll
dir_len_p1: t.CSizeT = string.strlen(temp_dir)
dir_len_p1: sizet = string.strlen(temp_dir)
stub_path_p1: str = StubMergerCollect._sliced_path(temp_dir, dir_len_p1, sha1, "stub.ll")
if stub_path_p1 is not None:
sf_p1: fileio.File | t.CPtr = fileio.File(stub_path_p1, fileio.MODE.W)
@@ -1076,7 +1076,7 @@ def RunPhase1(mb: memhub.MemBuddy | t.CPtr, includes_dir: str, temp_dir: str,
failed += 1
continue
tr.dump_ir(text_buf, PHASE1_IR_SIZE, llvmlite.OUTPUT_TEXT)
text_len: t.CSizeT = string.strlen(text_buf)
text_len: sizet = string.strlen(text_buf)
# save text.ll
text_path_p1: str = StubMergerCollect._sliced_path(temp_dir, dir_len_p1, sha1, "text.ll")
@@ -1089,7 +1089,7 @@ def RunPhase1(mb: memhub.MemBuddy | t.CPtr, includes_dir: str, temp_dir: str,
stdlib.free(text_buf)
# 计时点 3:dump(stub+text)完成;输出单文件三段耗时
t_f3: t.CUInt64T = w32.win32base.GetTickCount64()
t_f3: uint64 = w32.win32base.GetTickCount64()
VLogger.info(f"[{i+1}/{loop_n_b}] 翻译: {file_path} (parse={t_f1-t_f0} ms, translate={t_f2-t_f1} ms, dump={t_f3-t_f2} ms, total={t_f3-t_f0} ms)", "Phase1")
# save dependencies(_imported_modules) for Phase B
@@ -1098,7 +1098,7 @@ def RunPhase1(mb: memhub.MemBuddy | t.CPtr, includes_dir: str, temp_dir: str,
df_p1: fileio.File | t.CPtr = fileio.File(deps_path_p1, fileio.MODE.W)
if not df_p1.closed:
if tr._imported_modules is not None:
dl: t.CSizeT = string.strlen(tr._imported_modules)
dl: sizet = string.strlen(tr._imported_modules)
df_p1.write(tr._imported_modules, dl)
df_p1.close()
stdlib.free(deps_path_p1)
@@ -1125,19 +1125,19 @@ def RunPhase1(mb: memhub.MemBuddy | t.CPtr, includes_dir: str, temp_dir: str,
# 3=order 为负,4=order 超 max_order,5=块未对齐到 order 大小,
# 6=块尾 canary 损坏(越界写穿数据区——事发地定位)
# rc 语义(self_check):1/2=越界,3=对齐错,4=free list 成环/超步数
chk_rc: t.CInt = mb.check_alive_blocks(mark1)
chk_rc: int = mb.check_alive_blocks(mark1)
if chk_rc != 0:
VLogger.error(f"内存损坏(存活块 header, rc={chk_rc}): {file_path}", "Phase1")
# A/B 实验结论(已确认):禁用 reset_to 后 stdarg 仍崩 → 越界写是根因,
# 与回收/UAF 无关。恢复 reset_to,改用块尾 canary(check_alive_blocks 校验)
# 定位越界写事发地到具体文件。
mb.reset_to(mark1)
sc_rc: t.CInt = mb.self_check()
sc_rc: int = mb.self_check()
if sc_rc != 0:
VLogger.error(f"内存损坏(free list, rc={sc_rc}): {file_path}", "Phase1")
# 1b 阶段总耗时(全量翻译 + dump)
t_b1: t.CUInt64T = w32.win32base.GetTickCount64()
t_b1: uint64 = w32.win32base.GetTickCount64()
VLogger.info(f"1b 总耗时: {t_b1-t_b0} ms (全量翻译, trans={translated} skip={skipped} fail={failed})", "Phase1")
# 释放 Phase 1b 使用的拓扑排序资源
+34 -34
View File
@@ -79,7 +79,7 @@ def _ScanClassInheritance(mb: memhub.MemBuddy | t.CPtr,
if result is None or class_names_buf is None or parent_names_buf is None or def_sha1s_buf is None:
return -1
entry_size: t.CSizeT = IncludesScanner.FileEntry.__sizeof__()
entry_size: sizet = IncludesScanner.FileEntry.__sizeof__()
class_count: int = 0
for i in range(result.Count):
@@ -87,8 +87,8 @@ def _ScanClassInheritance(mb: memhub.MemBuddy | t.CPtr,
# 全量 parse 的 AST 若驻留到 mark1 → 1GB 主池耗尽 OOM 根因;
# class_names_buf/parent_names_buf/def_sha1s_buf 在调用前分配,
# 位于本 mark 之前,reset 不影响;generic_file_indices 同理)
scan_mark: t.CSizeT = mb.mark()
entry_addr: t.CUInt64T = t.CUInt64T(result.Entries) + i * entry_size
scan_mark: sizet = mb.mark()
entry_addr: uint64 = uint64(result.Entries) + i * entry_size
entry: IncludesScanner.FileEntry | t.CPtr = (IncludesScanner.FileEntry | t.CPtr)(t.CVoid(entry_addr, t.CPtr))
if entry is None or entry.Sha1 is None:
continue
@@ -145,7 +145,7 @@ def _ScanClassInheritance(mb: memhub.MemBuddy | t.CPtr,
# 遍历 AST 顶层节点,收集 ClassDef
ch: list[ast.AST | t.CPtr] | t.CPtr = tree.children
if ch is not None:
cn: t.CSizeT = len(ch)
cn: sizet = len(ch)
for ci in range(cn):
child: ast.AST | t.CPtr = ch.get(ci)
if child is None:
@@ -164,12 +164,12 @@ def _ScanClassInheritance(mb: memhub.MemBuddy | t.CPtr,
if tp_scan is not None:
file_has_generic = 1
if generic_file_count_box is not None:
gfc_ptr_scan: t.CPtr = (t.CInt | t.CPtr)(t.CVoid(generic_file_count_box, t.CPtr))
gfc_ptr_scan: t.CPtr = (int | t.CPtr)(t.CVoid(generic_file_count_box, t.CPtr))
if gfc_ptr_scan is not None:
gfc_scan: int = gfc_ptr_scan[0]
if gfc_scan < Phase1.MAX_FILE_DEPS and generic_file_indices is not None:
gi_addr_scan: t.CUInt64T = t.CUInt64T(generic_file_indices) + gfc_scan * 4
gi_ptr_scan: t.CPtr = (t.CInt | t.CPtr)(t.CVoid(gi_addr_scan, t.CPtr))
gi_addr_scan: uint64 = uint64(generic_file_indices) + gfc_scan * 4
gi_ptr_scan: t.CPtr = (int | t.CPtr)(t.CVoid(gi_addr_scan, t.CPtr))
if gi_ptr_scan is not None:
gi_ptr_scan[0] = i
gfc_ptr_scan[0] = gfc_scan + 1
@@ -179,7 +179,7 @@ def _ScanClassInheritance(mb: memhub.MemBuddy | t.CPtr,
# 填充扁平数组:类名(偏移 = class_count * Phase1.CLASS_NAME_LEN)
name_dst: str = class_names_buf + class_count * Phase1.CLASS_NAME_LEN
nm_len: t.CSizeT = string.strlen(cd.name)
nm_len: sizet = string.strlen(cd.name)
if nm_len >= Phase1.CLASS_NAME_LEN:
string.strncpy(name_dst, cd.name, Phase1.CLASS_NAME_LEN - 1)
name_dst[Phase1.CLASS_NAME_LEN - 1] = '\0'
@@ -192,7 +192,7 @@ def _ScanClassInheritance(mb: memhub.MemBuddy | t.CPtr,
parent_nm: str = GenApi._get_parent_class(cd, None)
# parent_nm 是 AST 节点内部指针,不需要释放
if parent_nm is not None:
pnm_len: t.CSizeT = string.strlen(parent_nm)
pnm_len: sizet = string.strlen(parent_nm)
if pnm_len >= Phase1.CLASS_NAME_LEN:
string.strncpy(parent_dst, parent_nm, Phase1.CLASS_NAME_LEN - 1)
parent_dst[Phase1.CLASS_NAME_LEN - 1] = '\0'
@@ -223,23 +223,23 @@ def _ScanClassInheritance(mb: memhub.MemBuddy | t.CPtr,
# 漏报有害(泛型模板未预注册 → 悬空复发),模式保守匹配行内单行形式
# (TPV 源码泛型类均为单行 `class X[T]:`,grep 确认)。
# ============================================================
def _BufHasGenericClassMarker(buf: bytes, blen: t.CSizeT) -> int:
def _BufHasGenericClassMarker(buf: bytes, blen: sizet) -> int:
"""文本扫描:buf 中是否有 'class 标识符[' 泛型类标记,返回 1/0"""
if buf is None or blen <= 6:
return 0
pos: t.CSizeT = 0
pos: sizet = 0
while pos + 5 < blen:
if buf[pos] == 'c' and buf[pos + 1] == 'l' and buf[pos + 2] == 'a' \
and buf[pos + 3] == 's' and buf[pos + 4] == 's':
# class 前是词边界(行首或非标识符字符)
prev_ok: int = 1
if pos > 0:
pc: t.CChar = buf[pos - 1]
pc: char = buf[pos - 1]
if(pc >= 'a' and pc <= 'z') or(pc >= 'A' and pc <= 'Z') \
or(pc >= '0' and pc <= '9') or pc == '_':
prev_ok = 0
if prev_ok != 0:
p: t.CSizeT = pos + 5
p: sizet = pos + 5
# 跳过空白
while p < blen and(buf[p] == ' ' or buf[p] == '\t'):
p += 1
@@ -284,10 +284,10 @@ def _PreRegisterAllGenericTemplates(mb: memhub.MemBuddy | t.CPtr,
perm: memhub.MemBuddy | t.CPtr = CompilerFactory.factory.PermPool
if perm is None:
return 0
p1e_size: t.CSizeT = IncludesScanner.FileEntry.__sizeof__()
p1e_size: sizet = IncludesScanner.FileEntry.__sizeof__()
handled_count: int = 0
for i in range(result.Count):
entry_addr_pg: t.CUInt64T = t.CUInt64T(result.Entries) + i * p1e_size
entry_addr_pg: uint64 = uint64(result.Entries) + i * p1e_size
entry_pg: IncludesScanner.FileEntry | t.CPtr = (
IncludesScanner.FileEntry | t.CPtr)(t.CVoid(entry_addr_pg, t.CPtr))
if entry_pg is None or entry_pg.Sha1 is None:
@@ -331,7 +331,7 @@ def _PreRegisterAllGenericTemplates(mb: memhub.MemBuddy | t.CPtr,
# 遍历顶层 ClassDef,注册泛型模板(type_params 非 None)
ch_pg: list[ast.AST | t.CPtr] | t.CPtr = tree_pg.children
if ch_pg is not None:
cn_pg: t.CSizeT = len(ch_pg)
cn_pg: sizet = len(ch_pg)
for ci_pg in range(cn_pg):
child_pg: ast.AST | t.CPtr = ch_pg.get(ci_pg)
if child_pg is None or child_pg.kind() != ast.ASTKind.ClassDef:
@@ -440,14 +440,14 @@ def _ScanTreeForContainers(node: ast.AST | t.CPtr,
_ScanTreeForContainers(cl_s2.func, need_list_box, need_dict_box, depth + 1)
cl_args_s: list[ast.AST | t.CPtr] | t.CPtr = cl_s2.args
if cl_args_s is not None:
na_s: t.CSizeT = len(cl_args_s)
i_a2: t.CSizeT
na_s: sizet = len(cl_args_s)
i_a2: sizet
for i_a2 in range(na_s):
_ScanTreeForContainers(cl_args_s.get(i_a2), need_list_box, need_dict_box, depth + 1)
cl_kws_s: list[ast.AST | t.CPtr] | t.CPtr = cl_s2.keywords
if cl_kws_s is not None:
nk_s: t.CSizeT = len(cl_kws_s)
i_k2: t.CSizeT
nk_s: sizet = len(cl_kws_s)
i_k2: sizet
for i_k2 in range(nk_s):
kw_s: ast.Keyword | t.CPtr = (ast.Keyword | t.CPtr)(cl_kws_s.get(i_k2))
if kw_s is not None:
@@ -457,8 +457,8 @@ def _ScanTreeForContainers(node: ast.AST | t.CPtr,
_ScanTreeForContainers(asn_s.value, need_list_box, need_dict_box, depth + 1)
tgts_s: list[ast.AST | t.CPtr] | t.CPtr = asn_s.targets
if tgts_s is not None:
nt_s: t.CSizeT = len(tgts_s)
i_t2: t.CSizeT
nt_s: sizet = len(tgts_s)
i_t2: sizet
for i_t2 in range(nt_s):
_ScanTreeForContainers(tgts_s.get(i_t2), need_list_box, need_dict_box, depth + 1)
elif k_s == ast.ASTKind.AnnAssign:
@@ -472,8 +472,8 @@ def _ScanTreeForContainers(node: ast.AST | t.CPtr,
if fn_args_s is not None:
fa_s: list[ast.AST | t.CPtr] | t.CPtr = fn_args_s.args
if fa_s is not None:
nf_s: t.CSizeT = len(fa_s)
i_f2: t.CSizeT
nf_s: sizet = len(fa_s)
i_f2: sizet
for i_f2 in range(nf_s):
arg_s: ast.Arg | t.CPtr = (ast.Arg | t.CPtr)(fa_s.get(i_f2))
if arg_s is not None:
@@ -482,8 +482,8 @@ def _ScanTreeForContainers(node: ast.AST | t.CPtr,
cd_s: ast.ClassDef | t.CPtr = (ast.ClassDef | t.CPtr)(node)
bases_s: list[ast.AST | t.CPtr] | t.CPtr = cd_s.bases
if bases_s is not None:
nb_s: t.CSizeT = len(bases_s)
i_b2: t.CSizeT
nb_s: sizet = len(bases_s)
i_b2: sizet
for i_b2 in range(nb_s):
_ScanTreeForContainers(bases_s.get(i_b2), need_list_box, need_dict_box, depth + 1)
elif k_s == ast.ASTKind.Attribute:
@@ -493,8 +493,8 @@ def _ScanTreeForContainers(node: ast.AST | t.CPtr,
tu_s: ast.Tuple | t.CPtr = (ast.Tuple | t.CPtr)(node)
elts_s: list[ast.AST | t.CPtr] | t.CPtr = tu_s.elts
if elts_s is not None:
ne_s: t.CSizeT = len(elts_s)
i_e2: t.CSizeT
ne_s: sizet = len(elts_s)
i_e2: sizet
for i_e2 in range(ne_s):
_ScanTreeForContainers(elts_s.get(i_e2), need_list_box, need_dict_box, depth + 1)
elif k_s == ast.ASTKind.UnaryOp:
@@ -511,16 +511,16 @@ def _ScanTreeForContainers(node: ast.AST | t.CPtr,
_ScanTreeForContainers(cp_s.left, need_list_box, need_dict_box, depth + 1)
cps_s: list[ast.AST | t.CPtr] | t.CPtr = cp_s.comparators
if cps_s is not None:
nc_s: t.CSizeT = len(cps_s)
i_c2: t.CSizeT
nc_s: sizet = len(cps_s)
i_c2: sizet
for i_c2 in range(nc_s):
_ScanTreeForContainers(cps_s.get(i_c2), need_list_box, need_dict_box, depth + 1)
elif k_s == ast.ASTKind.BoolOp:
bo_s: ast.BoolOp | t.CPtr = (ast.BoolOp | t.CPtr)(node)
bvs_s: list[ast.AST | t.CPtr] | t.CPtr = bo_s.values
if bvs_s is not None:
nv_s: t.CSizeT = len(bvs_s)
i_v2: t.CSizeT
nv_s: sizet = len(bvs_s)
i_v2: sizet
for i_v2 in range(nv_s):
_ScanTreeForContainers(bvs_s.get(i_v2), need_list_box, need_dict_box, depth + 1)
# [FIX 2026-08-30] `[...]`/`{}` 字面量不再无条件触发 _list/_dict 导入:
@@ -534,7 +534,7 @@ def _ScanTreeForContainers(node: ast.AST | t.CPtr,
# 递归语句块子节点
if node.children is not None:
ch_s: list[ast.AST | t.CPtr] | t.CPtr = node.children
n_s: t.CSizeT = len(ch_s)
ci_s: t.CSizeT
n_s: sizet = len(ch_s)
ci_s: sizet
for ci_s in range(n_s):
_ScanTreeForContainers(ch_s.get(ci_s), need_list_box, need_dict_box, depth + 1)
+38 -38
View File
@@ -73,12 +73,12 @@ def _TopoSortFiles(mb: memhub.MemBuddy | t.CPtr,
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: t.CSizeT) -> int:
temp_dir: str, td_len_ts: sizet) -> int:
"""根据类继承关系对文件进行拓扑排序"""
if result is None or out_order is None or out_count is None:
return -1
entry_size: t.CSizeT = IncludesScanner.FileEntry.__sizeof__()
entry_size: sizet = IncludesScanner.FileEntry.__sizeof__()
# 1. 分配扁平数组:文件 SHA1、依赖 SHA1 列表、依赖数量、入度、处理状态
# 用扁平数组代替 FileDepEntry 结构体,避免 str 指针字段 NULL 崩溃
@@ -110,7 +110,7 @@ def _TopoSortFiles(mb: memhub.MemBuddy | t.CPtr,
file_count: int = 0
# sha1→file_index 映射(简单线性查找,文件数不多)
for i in range(result.Count):
entry_addr: t.CUInt64T = t.CUInt64T(result.Entries) + i * entry_size
entry_addr: uint64 = uint64(result.Entries) + i * entry_size
entry: IncludesScanner.FileEntry | t.CPtr = (IncludesScanner.FileEntry | t.CPtr)(t.CVoid(entry_addr, t.CPtr))
if entry is None or entry.Sha1 is None:
continue
@@ -160,8 +160,8 @@ def _TopoSortFiles(mb: memhub.MemBuddy | t.CPtr,
continue
# 读取当前依赖数量
cnt_addr: t.CUInt64T = t.CUInt64T(file_dep_counts) + fi * 4
cnt_ptr: t.CPtr = (t.CInt | t.CPtr)(t.CVoid(cnt_addr, t.CPtr))
cnt_addr: uint64 = uint64(file_dep_counts) + fi * 4
cnt_ptr: t.CPtr = (int | t.CPtr)(t.CVoid(cnt_addr, t.CPtr))
if cnt_ptr is None:
break
cur_cnt: int = cnt_ptr[0]
@@ -206,13 +206,13 @@ def _TopoSortFiles(mb: memhub.MemBuddy | t.CPtr,
deps_imp: str = StubMergerStore.LookupIncludesDeps(fsha1_imp)
if deps_imp is None:
continue
dl_imp: t.CSizeT = string.strlen(deps_imp)
dpos_imp: t.CSizeT = 0
dl_imp: sizet = string.strlen(deps_imp)
dpos_imp: sizet = 0
while dpos_imp < dl_imp:
dstart_imp: t.CSizeT = dpos_imp
dstart_imp: sizet = dpos_imp
while dpos_imp < dl_imp and deps_imp[dpos_imp] != ' ':
dpos_imp += 1
dlen_imp: t.CSizeT = dpos_imp - dstart_imp
dlen_imp: sizet = dpos_imp - dstart_imp
if dpos_imp < dl_imp:
dpos_imp += 1
if dlen_imp == 0:
@@ -234,8 +234,8 @@ def _TopoSortFiles(mb: memhub.MemBuddy | t.CPtr,
if fj_imp == fi_imp:
break
# 去重 + 加边:fi_imp 依赖 fj_imp(InDegree[fi_imp]++)
cnt_addr_imp: t.CUInt64T = t.CUInt64T(file_dep_counts) + fi_imp * 4
cnt_ptr_imp: t.CPtr = (t.CInt | t.CPtr)(t.CVoid(cnt_addr_imp, t.CPtr))
cnt_addr_imp: uint64 = uint64(file_dep_counts) + fi_imp * 4
cnt_ptr_imp: t.CPtr = (int | t.CPtr)(t.CVoid(cnt_addr_imp, t.CPtr))
if cnt_ptr_imp is None:
break
cur_cnt_imp: int = cnt_ptr_imp[0]
@@ -260,10 +260,10 @@ def _TopoSortFiles(mb: memhub.MemBuddy | t.CPtr,
# 3. Kahn 算法:InDegree = DepCount(依赖多少个父文件)
# 依赖为 0 的先处理,处理后减少依赖它的文件入度
for fi in range(file_count):
cnt_addr3: t.CUInt64T = t.CUInt64T(file_dep_counts) + fi * 4
cnt_ptr3: t.CPtr = (t.CInt | t.CPtr)(t.CVoid(cnt_addr3, t.CPtr))
ind_addr3: t.CUInt64T = t.CUInt64T(file_indegrees) + fi * 4
ind_ptr3: t.CPtr = (t.CInt | t.CPtr)(t.CVoid(ind_addr3, t.CPtr))
cnt_addr3: uint64 = uint64(file_dep_counts) + fi * 4
cnt_ptr3: t.CPtr = (int | t.CPtr)(t.CVoid(cnt_addr3, t.CPtr))
ind_addr3: uint64 = uint64(file_indegrees) + fi * 4
ind_ptr3: t.CPtr = (int | t.CPtr)(t.CVoid(ind_addr3, t.CPtr))
if cnt_ptr3 is not None and ind_ptr3 is not None:
ind_ptr3[0] = cnt_ptr3[0]
@@ -274,13 +274,13 @@ def _TopoSortFiles(mb: memhub.MemBuddy | t.CPtr,
changed = 0
for fi in range(file_count):
# 检查处理状态
proc_addr4: t.CUInt64T = t.CUInt64T(file_processed) + fi * 4
proc_ptr4: t.CPtr = (t.CInt | t.CPtr)(t.CVoid(proc_addr4, t.CPtr))
proc_addr4: uint64 = uint64(file_processed) + fi * 4
proc_ptr4: t.CPtr = (int | t.CPtr)(t.CVoid(proc_addr4, t.CPtr))
if proc_ptr4 is None or proc_ptr4[0] != 0:
continue
# 检查入度
ind_addr4: t.CUInt64T = t.CUInt64T(file_indegrees) + fi * 4
ind_ptr4: t.CPtr = (t.CInt | t.CPtr)(t.CVoid(ind_addr4, t.CPtr))
ind_addr4: uint64 = uint64(file_indegrees) + fi * 4
ind_ptr4: t.CPtr = (int | t.CPtr)(t.CVoid(ind_addr4, t.CPtr))
if ind_ptr4 is None or ind_ptr4[0] > 0:
continue
@@ -288,13 +288,13 @@ def _TopoSortFiles(mb: memhub.MemBuddy | t.CPtr,
# 找到对应的 result.Entries 索引
target_sha1: str = file_sha1s_buf + fi * Phase1.SHA1_LEN
for ri in range(result.Count):
ea_r: t.CUInt64T = t.CUInt64T(result.Entries) + ri * entry_size
ea_r: uint64 = uint64(result.Entries) + ri * entry_size
ent_r: IncludesScanner.FileEntry | t.CPtr = (IncludesScanner.FileEntry | t.CPtr)(t.CVoid(ea_r, t.CPtr))
if ent_r is not None and ent_r.Sha1 is not None:
if string.strcmp(ent_r.Sha1, target_sha1) == 0:
# 写入输出索引数组
out_idx_addr: t.CUInt64T = t.CUInt64T(out_order) + out_idx * 4
out_int_ptr: t.CPtr = (t.CInt | t.CPtr)(t.CVoid(out_idx_addr, t.CPtr))
out_idx_addr: uint64 = uint64(out_order) + out_idx * 4
out_int_ptr: t.CPtr = (int | t.CPtr)(t.CVoid(out_idx_addr, t.CPtr))
if out_int_ptr is not None:
out_int_ptr[0] = ri
out_idx += 1
@@ -306,21 +306,21 @@ def _TopoSortFiles(mb: memhub.MemBuddy | t.CPtr,
# 减少依赖该文件的其他文件的入度
for fj in range(file_count):
proc_addr5: t.CUInt64T = t.CUInt64T(file_processed) + fj * 4
proc_ptr5: t.CPtr = (t.CInt | t.CPtr)(t.CVoid(proc_addr5, t.CPtr))
proc_addr5: uint64 = uint64(file_processed) + fj * 4
proc_ptr5: t.CPtr = (int | t.CPtr)(t.CVoid(proc_addr5, t.CPtr))
if proc_ptr5 is None or proc_ptr5[0] != 0:
continue
# 读取 fj 的依赖数量
cnt_addr5: t.CUInt64T = t.CUInt64T(file_dep_counts) + fj * 4
cnt_ptr5: t.CPtr = (t.CInt | t.CPtr)(t.CVoid(cnt_addr5, t.CPtr))
cnt_addr5: uint64 = uint64(file_dep_counts) + fj * 4
cnt_ptr5: t.CPtr = (int | t.CPtr)(t.CVoid(cnt_addr5, t.CPtr))
if cnt_ptr5 is None:
continue
fj_dep_cnt: int = cnt_ptr5[0]
for di in range(fj_dep_cnt):
dep_slot5: str = file_deps_buf + fj * Phase1.MAX_DEP_EDGES * Phase1.SHA1_LEN + di * Phase1.SHA1_LEN
if string.strcmp(dep_slot5, target_sha1) == 0:
ind_addr5: t.CUInt64T = t.CUInt64T(file_indegrees) + fj * 4
ind_ptr5: t.CPtr = (t.CInt | t.CPtr)(t.CVoid(ind_addr5, t.CPtr))
ind_addr5: uint64 = uint64(file_indegrees) + fj * 4
ind_ptr5: t.CPtr = (int | t.CPtr)(t.CVoid(ind_addr5, t.CPtr))
if ind_ptr5 is not None:
ind_ptr5[0] = ind_ptr5[0] - 1
break
@@ -338,8 +338,8 @@ def _TopoSortFiles(mb: memhub.MemBuddy | t.CPtr,
rem_count: int = 0
if rem_idx is not None and rem_depcnt is not None:
for fi in range(file_count):
proc_addr7: t.CUInt64T = t.CUInt64T(file_processed) + fi * 4
proc_ptr7: t.CPtr = (t.CInt | t.CPtr)(t.CVoid(proc_addr7, t.CPtr))
proc_addr7: uint64 = uint64(file_processed) + fi * 4
proc_ptr7: t.CPtr = (int | t.CPtr)(t.CVoid(proc_addr7, t.CPtr))
if proc_ptr7 is not None and proc_ptr7[0] == 0:
rem_idx[rem_count] = fi
rem_depcnt[rem_count] = 0
@@ -352,8 +352,8 @@ def _TopoSortFiles(mb: memhub.MemBuddy | t.CPtr,
fi_b: int = rem_idx[i_b]
if fi_b == fi_a:
continue
cnt_addr_b: t.CUInt64T = t.CUInt64T(file_dep_counts) + fi_b * 4
cnt_ptr_b: t.CPtr = (t.CInt | t.CPtr)(t.CVoid(cnt_addr_b, t.CPtr))
cnt_addr_b: uint64 = uint64(file_dep_counts) + fi_b * 4
cnt_ptr_b: t.CPtr = (int | t.CPtr)(t.CVoid(cnt_addr_b, t.CPtr))
if cnt_ptr_b is None:
continue
cnt_b: int = cnt_ptr_b[0]
@@ -375,18 +375,18 @@ def _TopoSortFiles(mb: memhub.MemBuddy | t.CPtr,
# 按序输出剩余文件
for i_a in range(rem_count):
fi_a2: int = rem_idx[i_a]
proc_addr8: t.CUInt64T = t.CUInt64T(file_processed) + fi_a2 * 4
proc_ptr8: t.CPtr = (t.CInt | t.CPtr)(t.CVoid(proc_addr8, t.CPtr))
proc_addr8: uint64 = uint64(file_processed) + fi_a2 * 4
proc_ptr8: t.CPtr = (int | t.CPtr)(t.CVoid(proc_addr8, t.CPtr))
if proc_ptr8 is None or proc_ptr8[0] != 0:
continue
target_sha1_2: str = file_sha1s_buf + fi_a2 * Phase1.SHA1_LEN
for ri in range(result.Count):
ea_r2: t.CUInt64T = t.CUInt64T(result.Entries) + ri * entry_size
ea_r2: uint64 = uint64(result.Entries) + ri * entry_size
ent_r2: IncludesScanner.FileEntry | t.CPtr = (IncludesScanner.FileEntry | t.CPtr)(t.CVoid(ea_r2, t.CPtr))
if ent_r2 is not None and ent_r2.Sha1 is not None:
if string.strcmp(ent_r2.Sha1, target_sha1_2) == 0:
out_idx_addr2: t.CUInt64T = t.CUInt64T(out_order) + out_idx * 4
out_int_ptr2: t.CPtr = (t.CInt | t.CPtr)(t.CVoid(out_idx_addr2, t.CPtr))
out_idx_addr2: uint64 = uint64(out_order) + out_idx * 4
out_int_ptr2: t.CPtr = (int | t.CPtr)(t.CVoid(out_idx_addr2, t.CPtr))
if out_int_ptr2 is not None:
out_int_ptr2[0] = ri
out_idx += 1
@@ -396,7 +396,7 @@ def _TopoSortFiles(mb: memhub.MemBuddy | t.CPtr,
stdlib.free(rem_depcnt)
# 写入输出数量
out_count_ptr: t.CPtr = (t.CInt | t.CPtr)(t.CVoid(out_count, t.CPtr))
out_count_ptr: t.CPtr = (int | t.CPtr)(t.CVoid(out_count, t.CPtr))
if out_count_ptr is not None:
out_count_ptr[0] = out_idx
+1 -1
View File
@@ -9,7 +9,7 @@ _mbuddy: memhub.MemBuddy | t.CPtr
SRC_BUF_SIZE: t.CDefine = 1048576
# vpi 缓冲区大小(256KB)
PYI_BUF_SIZE: t.CSizeT = 262144
PYI_BUF_SIZE: sizet = 262144
# 拓扑排序相关常量
MAX_CLASSES: t.CDefine = 512
+158 -158
View File
@@ -67,7 +67,7 @@ class SrcFileEntry:
def _ScanDirForPyFiles(mb: memhub.MemBuddy | t.CPtr,
dir_path: str,
entries: SrcFileEntry | t.CPtr,
entry_size: t.CSizeT,
entry_size: sizet,
file_count: int, max_files: int) -> int:
"""递归扫描目录,收集 .vp/.py 文件到 entries,返回新的 file_count"""
if dir_path is None or entries is None:
@@ -75,13 +75,13 @@ def _ScanDirForPyFiles(mb: memhub.MemBuddy | t.CPtr,
if file_count >= max_files:
return file_count
dir_len: t.CSizeT = string.strlen(dir_path)
dir_len: sizet = string.strlen(dir_path)
pattern: bytes = stdlib.malloc(dir_len + 16)
if pattern is None:
return file_count
viperlib.snprintf(pattern, dir_len + 16, "%s/*", dir_path)
find_data_size: t.CSizeT = w32.win32file.WIN32_FIND_DATAA.__sizeof__()
find_data_size: sizet = w32.win32file.WIN32_FIND_DATAA.__sizeof__()
find_data: w32.win32file.WIN32_FIND_DATAA | t.CPtr = stdlib.malloc(find_data_size + 16)
if find_data is None:
stdlib.free(pattern)
@@ -100,7 +100,7 @@ def _ScanDirForPyFiles(mb: memhub.MemBuddy | t.CPtr,
if w32.win32file.FindNextFileA(handle, find_data) == 0:
break
continue
fname_len: t.CSizeT = string.strlen(fname)
fname_len: sizet = string.strlen(fname)
if fname_len <= 0:
if w32.win32file.FindNextFileA(handle, find_data) == 0:
break
@@ -145,7 +145,7 @@ def _ScanDirForPyFiles(mb: memhub.MemBuddy | t.CPtr,
# 符号前缀不一致 → 链接报 undefined reference。
sha1_val: str = IncludesScanner.compute_file_sha1(mb, full_path)
if sha1_val is not None:
ea: t.CUInt64T = t.CUInt64T(entries) + file_count * entry_size
ea: uint64 = uint64(entries) + file_count * entry_size
ent: SrcFileEntry | t.CPtr = (SrcFileEntry | t.CPtr)(t.CVoid(ea, t.CPtr))
if ent is not None:
ent.Path = full_path
@@ -175,7 +175,7 @@ def _ScanDirForPyFiles(mb: memhub.MemBuddy | t.CPtr,
def _ScanDirForAsmFiles(mb: memhub.MemBuddy | t.CPtr,
dir_path: str,
entries: SrcFileEntry | t.CPtr,
entry_size: t.CSizeT,
entry_size: sizet,
file_count: int, max_files: int) -> int:
"""递归扫描目录,收集 .s 汇编文件到 entries,返回新的 file_count"""
if dir_path is None or entries is None:
@@ -183,13 +183,13 @@ def _ScanDirForAsmFiles(mb: memhub.MemBuddy | t.CPtr,
if file_count >= max_files:
return file_count
dir_len: t.CSizeT = string.strlen(dir_path)
dir_len: sizet = string.strlen(dir_path)
pattern: bytes = stdlib.malloc(dir_len + 16)
if pattern is None:
return file_count
viperlib.snprintf(pattern, dir_len + 16, "%s/*", dir_path)
find_data_size: t.CSizeT = w32.win32file.WIN32_FIND_DATAA.__sizeof__()
find_data_size: sizet = w32.win32file.WIN32_FIND_DATAA.__sizeof__()
find_data: w32.win32file.WIN32_FIND_DATAA | t.CPtr = stdlib.malloc(find_data_size + 16)
if find_data is None:
stdlib.free(pattern)
@@ -208,7 +208,7 @@ def _ScanDirForAsmFiles(mb: memhub.MemBuddy | t.CPtr,
if w32.win32file.FindNextFileA(handle, find_data) == 0:
break
continue
fname_len: t.CSizeT = string.strlen(fname)
fname_len: sizet = string.strlen(fname)
if fname_len <= 0:
if w32.win32file.FindNextFileA(handle, find_data) == 0:
break
@@ -246,7 +246,7 @@ def _ScanDirForAsmFiles(mb: memhub.MemBuddy | t.CPtr,
# SHA1 与 .vp 同口径(CRLF→LF 归一化),用于切片路径
sha1_val: str = IncludesScanner.compute_file_sha1(mb, full_path)
if sha1_val is not None:
ea: t.CUInt64T = t.CUInt64T(entries) + file_count * entry_size
ea: uint64 = uint64(entries) + file_count * entry_size
ent: SrcFileEntry | t.CPtr = (SrcFileEntry | t.CPtr)(t.CVoid(ea, t.CPtr))
if ent is not None:
ent.Path = full_path
@@ -277,13 +277,13 @@ def _ScanDirForAsmFiles(mb: memhub.MemBuddy | t.CPtr,
def _PreRegisterAppGenericTemplates(mb: memhub.MemBuddy | t.CPtr,
entries: SrcFileEntry | t.CPtr,
file_count: int,
entry_size: t.CSizeT) -> int:
entry_size: sizet) -> int:
"""mark2 前预注册 App 源文件的泛型类模板,返回处理到的泛型类数量"""
if mb is None or entries is None or file_count <= 0:
return 0
handled: int = 0
for i in range(file_count):
ea_pa: t.CUInt64T = t.CUInt64T(entries) + i * entry_size
ea_pa: uint64 = uint64(entries) + i * entry_size
ent_pa: SrcFileEntry | t.CPtr = (SrcFileEntry | t.CPtr)(t.CVoid(ea_pa, t.CPtr))
if ent_pa is None or ent_pa.Path is None or ent_pa.Sha1 is None:
continue
@@ -324,7 +324,7 @@ def _PreRegisterAppGenericTemplates(mb: memhub.MemBuddy | t.CPtr,
# 遍历顶层 ClassDef,注册泛型模板(type_params 非 None)
ch_pa: list[ast.AST | t.CPtr] | t.CPtr = tree_pa.children
if ch_pa is not None:
cn_pa: t.CSizeT = len(ch_pa)
cn_pa: sizet = len(ch_pa)
for ci_pa in range(cn_pa):
child_pa: ast.AST | t.CPtr = ch_pa.get(ci_pa)
if child_pa is None or child_pa.kind() != ast.ASTKind.ClassDef:
@@ -353,18 +353,18 @@ def _PreRegisterAppGenericTemplates(mb: memhub.MemBuddy | t.CPtr,
# stdlib 全局表(跨 mb.reset_to(mark2) 存活),收敛失败时按文件输出依赖树,
# 用 [MISS]/[OK] 标出缺 text.ll 的节点,并回显 pending 明细。
# ============================================================
PA_DEPS_MAX_STR: t.CSizeT = 1024
PA_MISS_MAX_STR: t.CSizeT = 768
PA_GRAPH_DEPTH_MAX: t.CInt = 3 # 缺失链下钻深度(第 1 层开始计数)
PA_GRAPH_OK_PROBE: t.CInt = 2 # 就绪节点仅再探测 1 层(找隐藏缺失)
_pa_diag_max: t.CSizeT = 0
PA_DEPS_MAX_STR: sizet = 1024
PA_MISS_MAX_STR: sizet = 768
PA_GRAPH_DEPTH_MAX: int = 3 # 缺失链下钻深度(第 1 层开始计数)
PA_GRAPH_OK_PROBE: int = 2 # 就绪节点仅再探测 1 层(找隐藏缺失)
_pa_diag_max: sizet = 0
_pa_diag_count: int = 0
_pa_diag_sha1: bytes = None
_pa_diag_deps: bytes = None
_pa_diag_miss: bytes = None
def _PhaseADiagInit(max_count: t.CSizeT) -> None:
def _PhaseADiagInit(max_count: sizet) -> None:
"""分配 Phase A 收敛失败诊断持久表(stdlib,跨 reset 存活)"""
global _pa_diag_max, _pa_diag_count, _pa_diag_sha1, _pa_diag_deps, _pa_diag_miss
_pa_diag_max = max_count
@@ -404,24 +404,24 @@ def _PhaseADiagRecord(sha1: str, deps: str, miss: str) -> None:
if string.strlen(sha1) < 16:
return
for i in range(_pa_diag_count):
es: bytes = _pa_diag_sha1 + t.CSizeT(i) * 17
es: bytes = _pa_diag_sha1 + sizet(i) * 17
if string.strcmp(es, sha1) == 0:
if miss is not None and _pa_diag_miss is not None:
maddr: bytes = _pa_diag_miss + t.CSizeT(i) * PA_MISS_MAX_STR
maddr: bytes = _pa_diag_miss + sizet(i) * PA_MISS_MAX_STR
string.strncpy(maddr, miss, PA_MISS_MAX_STR - 1)
maddr[PA_MISS_MAX_STR - 1] = 0
return
if _pa_diag_count >= _pa_diag_max:
return
saddr: bytes = _pa_diag_sha1 + t.CSizeT(_pa_diag_count) * 17
saddr: bytes = _pa_diag_sha1 + sizet(_pa_diag_count) * 17
string.strncpy(saddr, sha1, 16)
saddr[16] = 0
daddr: bytes = _pa_diag_deps + t.CSizeT(_pa_diag_count) * PA_DEPS_MAX_STR
daddr: bytes = _pa_diag_deps + sizet(_pa_diag_count) * PA_DEPS_MAX_STR
if deps is not None:
string.strncpy(daddr, deps, PA_DEPS_MAX_STR - 1)
daddr[PA_DEPS_MAX_STR - 1] = 0
if miss is not None and _pa_diag_miss is not None:
maddr2: bytes = _pa_diag_miss + t.CSizeT(_pa_diag_count) * PA_MISS_MAX_STR
maddr2: bytes = _pa_diag_miss + sizet(_pa_diag_count) * PA_MISS_MAX_STR
string.strncpy(maddr2, miss, PA_MISS_MAX_STR - 1)
maddr2[PA_MISS_MAX_STR - 1] = 0
_pa_diag_count += 1
@@ -432,10 +432,10 @@ def _PhaseADiagDepsLookup(sha1: str) -> str:
if _pa_diag_sha1 is None or _pa_diag_deps is None or sha1 is None:
return None
for i in range(_pa_diag_count):
es: bytes = _pa_diag_sha1 + t.CSizeT(i) * 17
es: bytes = _pa_diag_sha1 + sizet(i) * 17
if string.strcmp(es, sha1) == 0:
src: bytes = _pa_diag_deps + t.CSizeT(i) * PA_DEPS_MAX_STR
ln: t.CSizeT = string.strlen(src)
src: bytes = _pa_diag_deps + sizet(i) * PA_DEPS_MAX_STR
ln: sizet = string.strlen(src)
out: bytes = stdlib.malloc(ln + 1)
if out is None:
return None
@@ -449,10 +449,10 @@ def _PhaseADiagMissLookup(sha1: str) -> str:
if _pa_diag_sha1 is None or _pa_diag_miss is None or sha1 is None:
return None
for i in range(_pa_diag_count):
es: bytes = _pa_diag_sha1 + t.CSizeT(i) * 17
es: bytes = _pa_diag_sha1 + sizet(i) * 17
if string.strcmp(es, sha1) == 0:
src: bytes = _pa_diag_miss + t.CSizeT(i) * PA_MISS_MAX_STR
ln: t.CSizeT = string.strlen(src)
src: bytes = _pa_diag_miss + sizet(i) * PA_MISS_MAX_STR
ln: sizet = string.strlen(src)
if ln == 0:
return None
out: bytes = stdlib.malloc(ln + 1)
@@ -463,7 +463,7 @@ def _PhaseADiagMissLookup(sha1: str) -> str:
return None
def _PhaseATextLLExists(temp_dir: str, td_len: t.CSizeT, sha1: str) -> int:
def _PhaseATextLLExists(temp_dir: str, td_len: sizet, sha1: str) -> int:
"""探测 {temp_dir}/{sha1前2位}/{sha1}.text.ll 是否存在,1=存在"""
if temp_dir is None or td_len == 0 or sha1 is None or string.strlen(sha1) < 2:
return 0
@@ -489,7 +489,7 @@ def _PhaseAResolveDepSha1(mod_name: str) -> str:
return StubMergerStore.LookupSha1ByModNameSuffix(mod_name)
def _PhaseADumpNode(temp_dir: str, td_len: t.CSizeT, sha1: str,
def _PhaseADumpNode(temp_dir: str, td_len: sizet, sha1: str,
depth: int, prefix: bytes) -> None:
"""递归打印依赖子图;[MISS]=缺 text.ll(下钻整链),[OK]=就绪(仅探测 1 层)"""
deps: bytes = None
@@ -503,7 +503,7 @@ def _PhaseADumpNode(temp_dir: str, td_len: t.CSizeT, sha1: str,
if not df.closed:
deps = stdlib.malloc(PA_DEPS_MAX_STR)
if deps is not None:
rl: t.CInt64T = df.read_all(deps, PA_DEPS_MAX_STR)
rl: int64 = df.read_all(deps, PA_DEPS_MAX_STR)
if rl < 0:
rl = 0
# read_all 的容量参数就是缓冲区容量(含终止符): 传真实容量
@@ -516,9 +516,9 @@ def _PhaseADumpNode(temp_dir: str, td_len: t.CSizeT, sha1: str,
if deps is not None:
stdlib.free(deps)
return
dl: t.CSizeT = string.strlen(deps)
dl: sizet = string.strlen(deps)
token_count: int = 0
pos: t.CSizeT = 0
pos: sizet = 0
while pos < dl:
while pos < dl and deps[pos] == ' ':
pos += 1
@@ -534,10 +534,10 @@ def _PhaseADumpNode(temp_dir: str, td_len: t.CSizeT, sha1: str,
pos += 1
if pos >= dl:
break
ts: t.CSizeT = pos
ts: sizet = pos
while pos < dl and deps[pos] != ' ':
pos += 1
tl: t.CSizeT = pos - ts
tl: sizet = pos - ts
nm: bytes = stdlib.malloc(tl + 1)
if nm is not None:
string.strncpy(nm, deps + ts, tl)
@@ -588,7 +588,7 @@ def _PhaseADumpNode(temp_dir: str, td_len: t.CSizeT, sha1: str,
if can_expand != 0:
# +5:strcat 追加 "| "/" "(4 字符)+ NUL;strlen+4 会溢出 1 字节
# 破坏堆元数据 → 后续 malloc/free 崩溃,图打印中断且 stdout 缓冲丢失
npl: t.CSizeT = string.strlen(prefix) + 5
npl: sizet = string.strlen(prefix) + 5
new_prefix: bytes = stdlib.malloc(npl)
if new_prefix is not None:
string.strcpy(new_prefix, prefix)
@@ -608,13 +608,13 @@ def _PhaseASha1ToModName(sha1: str) -> str:
if sha1 is None or StubMerger._sha1_store_arr is None or StubMerger._sha1_store_mod is None:
return None
for i in range(StubMerger._sha1_store_count):
es: bytes = StubMerger._sha1_store_arr + t.CSizeT(i) * 17
es: bytes = StubMerger._sha1_store_arr + sizet(i) * 17
if string.strcmp(es, sha1) == 0:
return StubMerger._sha1_store_mod + t.CSizeT(i) * 64
return StubMerger._sha1_store_mod + sizet(i) * 64
return None
def _PhaseADumpMroPending(temp_dir: str, td_len: t.CSizeT, sha1: str) -> None:
def _PhaseADumpMroPending(temp_dir: str, td_len: sizet, sha1: str) -> None:
"""输出该调用方文件的 MRO/VPI pending 调用点诊断(读取 _phaseA_pending.log)
行格式: {owner_sha1}\t{kind}\t{cls}\t{method}\t{dep_sha1}\t{extra}\n
@@ -623,7 +623,7 @@ def _PhaseADumpMroPending(temp_dir: str, td_len: t.CSizeT, sha1: str) -> None:
"""
if temp_dir is None or sha1 is None:
return
path_len: t.CSizeT = td_len + 24
path_len: sizet = td_len + 24
path_buf: bytes = stdlib.malloc(path_len)
if path_buf is None:
return
@@ -637,26 +637,26 @@ def _PhaseADumpMroPending(temp_dir: str, td_len: t.CSizeT, sha1: str) -> None:
rf.close()
return
# read_all 的容量参数就是缓冲区容量(含终止符), 传真实容量 8192 而不是 8191
n: t.CInt64T = rf.read_all(buf, 8192)
n: int64 = rf.read_all(buf, 8192)
rf.close()
if n < 0:
n = 0
if n < 8191:
buf[n] = 0
nsz: t.CSizeT = t.CSizeT(n)
pos: t.CSizeT = 0
nsz: sizet = sizet(n)
pos: sizet = 0
hits: int = 0
while pos < nsz:
ls: t.CSizeT = pos
ls: sizet = pos
while pos < nsz and buf[pos] != '\n':
pos += 1
ll: t.CSizeT = pos - ls
ll: sizet = pos - ls
if pos < nsz:
pos += 1
if ll < 8:
continue
# 首字段(tab 前)须与目标 sha1 全等
tab_pos: t.CSizeT = 0
tab_pos: sizet = 0
while tab_pos < ll and buf[ls + tab_pos] != '\t':
tab_pos += 1
if tab_pos == 0 or tab_pos >= ll:
@@ -666,23 +666,23 @@ def _PhaseADumpMroPending(temp_dir: str, td_len: t.CSizeT, sha1: str) -> None:
if string.strncmp(buf + ls, sha1, tab_pos) != 0:
continue
# 解析 tab 分隔字段:kind / cls / method / dep_sha1 / extra
f2: t.CSizeT = tab_pos + 1
f2e: t.CSizeT = f2
f2: sizet = tab_pos + 1
f2e: sizet = f2
while f2e < ll and buf[ls + f2e] != '\t':
f2e += 1
f3: t.CSizeT = f2e + 1
f3e: t.CSizeT = f3
f3: sizet = f2e + 1
f3e: sizet = f3
while f3e < ll and buf[ls + f3e] != '\t':
f3e += 1
f4: t.CSizeT = f3e + 1
f4e: t.CSizeT = f4
f4: sizet = f3e + 1
f4e: sizet = f4
while f4e < ll and buf[ls + f4e] != '\t':
f4e += 1
f5: t.CSizeT = f4e + 1
f5e: t.CSizeT = f5
f5: sizet = f4e + 1
f5e: sizet = f5
while f5e < ll and buf[ls + f5e] != '\t':
f5e += 1
f6: t.CSizeT = f5e + 1
f6: sizet = f5e + 1
if f5e >= ll:
continue
# 临时把 tab 边界置 NUL 分段,打印后复原
@@ -727,7 +727,7 @@ def _PhaseADumpMroPending(temp_dir: str, td_len: t.CSizeT, sha1: str) -> None:
stdlib.free(buf)
def _PhaseADumpFailGraph(temp_dir: str, td_len: t.CSizeT, path: str, sha1: str) -> None:
def _PhaseADumpFailGraph(temp_dir: str, td_len: sizet, path: str, sha1: str) -> None:
"""收敛失败文件诊断:pending 明细 + 依赖树(标出缺 text.ll 节点)
每步 printf 后立即 fflush:管道捕获下 stdout 全缓冲,若后续崩溃未刷出
@@ -765,7 +765,7 @@ def RunMultiFileProject(mb: memhub.MemBuddy | t.CPtr,
do_phase1: int, do_phase2: int,
log: VLogger.Logger | t.CPtr,
args: argparse.ParsedArgs | t.CPtr,
linker_static_libs: str = None,
linker_static_libs: str = None,
linker_dynamic_libs: str = None) -> int:
"""多文件项目编译
@@ -778,7 +778,7 @@ def RunMultiFileProject(mb: memhub.MemBuddy | t.CPtr,
VLogger.info(f"多文件项目编译: {source_dir}", "project")
# === 1. 递归扫描 source_dir 下的 .vp/.py 文件(包括子目录)===
entry_size: t.CSizeT = SrcFileEntry.__sizeof__()
entry_size: sizet = SrcFileEntry.__sizeof__()
entries: SrcFileEntry | t.CPtr = stdlib.malloc(MAX_SRC_FILES * entry_size)
if entries is None:
return 1
@@ -819,7 +819,7 @@ def RunMultiFileProject(mb: memhub.MemBuddy | t.CPtr,
# 此处打 mark2,各处翻译完成后 reset_to(mark2) 回收该文件瞬时数据;
# 跨文件持久表(struct/enum/docstring/CDefine/函数注册表等)已 stdlib 化
# 或落在 mark2 之前,reset 不受影响(与 Phase1 1b 同翻译路径,已验证安全)。
mark2: t.CSizeT = mb.mark()
mark2: sizet = mb.mark()
# mark2 之后新注册的 struct/enum 条目改 stdlib 分配(跨 reset 存活,对齐 Phase1)
GenApi.set_stdlib_alloc(1)
@@ -849,8 +849,8 @@ def RunMultiFileProject(mb: memhub.MemBuddy | t.CPtr,
# 追加 App 源文件 SHA1 到 _sha1_map.txt(人类可读输出,程序内部不读取此文件)
# 格式: {sha1}:{rel_path}\n (保留目录结构,如 lib/core/VLogger.vp)
# 同步追加到内存存储器(AppendToSha1MapStore,供跨模块 CDefine 查找)
td_len_am: t.CSizeT = string.strlen(temp_dir)
src_dir_len_am: t.CSizeT = string.strlen(source_dir)
td_len_am: sizet = string.strlen(temp_dir)
src_dir_len_am: sizet = string.strlen(source_dir)
map_path_am: bytes = stdlib.malloc(td_len_am + 32)
if map_path_am is not None:
viperlib.snprintf(map_path_am, td_len_am + 32, "%s/_sha1_map.txt", temp_dir)
@@ -859,13 +859,13 @@ def RunMultiFileProject(mb: memhub.MemBuddy | t.CPtr,
# 先遍历一次填充内存存储器(不依赖文件 I/O),再写入 _sha1_map.txt
app_filled: int = 0
for i in range(file_count):
ea_am: t.CUInt64T = t.CUInt64T(entries) + i * entry_size
ea_am: uint64 = uint64(entries) + i * entry_size
ent_am: SrcFileEntry | t.CPtr = (SrcFileEntry | t.CPtr)(t.CVoid(ea_am, t.CPtr))
if ent_am is None or ent_am.Path is None or ent_am.Sha1 is None:
continue
# 计算相对路径(去除 source_dir 前缀,保留目录结构)
p_str: str = ent_am.Path
p_len: t.CSizeT = string.strlen(p_str)
p_len: sizet = string.strlen(p_str)
rel_path_am: str = p_str
if p_len > src_dir_len_am + 1:
if string.strncmp(p_str, source_dir, src_dir_len_am) == 0:
@@ -878,7 +878,7 @@ def RunMultiFileProject(mb: memhub.MemBuddy | t.CPtr,
# 写入 _sha1_map.txt(人类可读输出)
if not mf.closed and line_am is not None:
viperlib.snprintf(line_am, 512, "%s:%s\n", ent_am.Sha1, rel_path_am)
ll_am: t.CSizeT = string.strlen(line_am)
ll_am: sizet = string.strlen(line_am)
mf.write(line_am, ll_am)
if line_am is not None:
stdlib.free(line_am)
@@ -903,11 +903,11 @@ def RunMultiFileProject(mb: memhub.MemBuddy | t.CPtr,
# 此处先为所有 App 源文件预生成 vpi,保证 Phase A 翻译任意模块时其依赖
# vpi 已存在(App 源文件自身的 vpi 随后由 TranslateFileGetTrans 覆盖重写,
# 内容一致,此处仅保证"先于依赖方")。
td_len_vpa: t.CSizeT = string.strlen(temp_dir)
PYI_BUF_SIZE_P2: t.CSizeT = 262144
td_len_vpa: sizet = string.strlen(temp_dir)
PYI_BUF_SIZE_P2: sizet = 262144
vpi_failed_p2: int = 0
for i_vp2 in range(file_count):
ea_vp2: t.CUInt64T = t.CUInt64T(entries) + i_vp2 * entry_size
ea_vp2: uint64 = uint64(entries) + i_vp2 * entry_size
ent_vp2: SrcFileEntry | t.CPtr = (SrcFileEntry | t.CPtr)(t.CVoid(ea_vp2, t.CPtr))
if ent_vp2 is None or ent_vp2.Path is None or ent_vp2.Sha1 is None:
vpi_failed_p2 += 1
@@ -972,7 +972,7 @@ def RunMultiFileProject(mb: memhub.MemBuddy | t.CPtr,
continue
pyi_buf_vp2: bytes = stdlib.malloc(PYI_BUF_SIZE_P2)
if pyi_buf_vp2 is not None:
pyi_pos_vp2: t.CSizeT = StubConverter._GeneratePyiFromAst(
pyi_pos_vp2: sizet = StubConverter._GeneratePyiFromAst(
mb, tree_vp2, None, 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")
@@ -1000,13 +1000,13 @@ def RunMultiFileProject(mb: memhub.MemBuddy | t.CPtr,
# 声明在 if 块外,确保 Phase B+ 和清理代码能访问
# 65536 与 StubMerger.REACH_WORKLIST_BUF 对齐:全量 App imports 拼接
# 超 8192(追加82 同源溢出),8192 会静默丢依赖致 Phase B+ 可达集合不全
APP_DEPS_BUF_SIZE: t.CSizeT = 65536
APP_DEPS_BUF_SIZE: sizet = 65536
app_deps_buf: bytes = None
app_deps_len: t.CSizeT = 0
app_deps_len: sizet = 0
if do_phase1 != 0:
log.banner("Phase A: 生成 stub + text")
# Phase A 收敛失败依赖图诊断表初始化(stdlib,跨 mark2 reset 存活)
_PhaseADiagInit(t.CSizeT(file_count) + StubMerger.MAX_INCLUDES)
_PhaseADiagInit(sizet(file_count) + StubMerger.MAX_INCLUDES)
# 清空跨次构建残留的 MRO/VPI pending 诊断日志(每次 Phase A 全新开始)
if temp_dir is not None:
ppath_t: bytes = stdlib.malloc(string.strlen(temp_dir) + 24)
@@ -1031,7 +1031,7 @@ def RunMultiFileProject(mb: memhub.MemBuddy | t.CPtr,
store_rel_inc_pre: bytes = StubMergerStore.GetSha1StoreRelArrPtr()
store_incdir_inc_pre: bytes = StubMergerStore.GetSha1StoreIncdirArrPtr()
deps_filled_pre: int = 0
PHASE_A_INC_MAX_PASSES: t.CInt = 3
PHASE_A_INC_MAX_PASSES: int = 3
# [修复] 记录预注册失败的 includes:多遍后仍失败 → 报错终止编译。
# 不允许静默降级——静默失败会让 App 源文件的跨模块类构造退化为
# 普通函数调用(返回类型默认推断成 i32),调用点报误导性的
@@ -1050,14 +1050,14 @@ def RunMultiFileProject(mb: memhub.MemBuddy | t.CPtr,
for pass_inc_i in range(PHASE_A_INC_MAX_PASSES):
struct_count_before_inc: int = GenApi.get_struct_count()
for si_inc in range(store_count_inc_pre):
inc_sha1_pre: str = store_sha1_inc_pre + t.CSizeT(si_inc) * 17
inc_rel_pre: str = store_rel_inc_pre + t.CSizeT(si_inc) * StubMerger.MAX_REL_PATH_LEN
inc_sha1_pre: str = store_sha1_inc_pre + sizet(si_inc) * 17
inc_rel_pre: str = store_rel_inc_pre + sizet(si_inc) * StubMerger.MAX_REL_PATH_LEN
if inc_rel_pre is None or inc_rel_pre[0] == '\0':
continue
# 跳过 App 源文件(main.vp 等):由 Phase A-pre 预注册,不算失败
is_app_file_inc: int = 0
for i_app_inc in range(file_count):
ea_app_inc: t.CUInt64T = t.CUInt64T(entries) + i_app_inc * entry_size
ea_app_inc: uint64 = uint64(entries) + i_app_inc * entry_size
ent_app_inc: SrcFileEntry | t.CPtr = (SrcFileEntry | t.CPtr)(t.CVoid(ea_app_inc, t.CPtr))
if ent_app_inc is not None and ent_app_inc.Sha1 is not None \
and string.strcmp(ent_app_inc.Sha1, inc_sha1_pre) == 0:
@@ -1066,12 +1066,12 @@ def RunMultiFileProject(mb: memhub.MemBuddy | t.CPtr,
if is_app_file_inc != 0 and inc_fail_flags is not None:
inc_fail_flags[si_inc] = 0
continue
rel_len_pre: t.CSizeT = string.strlen(inc_rel_pre)
rel_len_pre: sizet = string.strlen(inc_rel_pre)
# 所属 includes 根目录(多目录逐条取自 IncDir 数组,空串回退 includes_dir)
incdir_pre: str = store_incdir_inc_pre + t.CSizeT(si_inc) * StubMerger.MAX_INC_DIR_LEN
incdir_pre: str = store_incdir_inc_pre + sizet(si_inc) * StubMerger.MAX_INC_DIR_LEN
if incdir_pre is None or incdir_pre[0] == '\0':
incdir_pre = includes_dir
incdir_len_pre: t.CSizeT = string.strlen(incdir_pre)
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
@@ -1104,7 +1104,7 @@ def RunMultiFileProject(mb: memhub.MemBuddy | t.CPtr,
if inc_fail_flags is not None:
for si_inc_f in range(store_count_inc_pre):
if inc_fail_flags[si_inc_f] != 0:
rel_f: str = store_rel_inc_pre + t.CSizeT(si_inc_f) * StubMerger.MAX_REL_PATH_LEN
rel_f: str = store_rel_inc_pre + sizet(si_inc_f) * StubMerger.MAX_REL_PATH_LEN
VLogger.error(f"includes 预注册失败: {rel_f}(文件无法翻译,可能是语法/解析/编译错误),终止编译", "prePhaseA")
stdlib.free(inc_fail_flags)
VLogger.info(f"includes 预注册 + 依赖填充: {deps_filled_pre}/{store_count_inc_pre}", "prePhaseA")
@@ -1115,12 +1115,12 @@ def RunMultiFileProject(mb: memhub.MemBuddy | t.CPtr,
# 多遍扫描:解决跨文件继承的字母序问题(如 HandlesAnnAssign.vp/.py 在 HandlesBase.vp/.py 之前,
# AnnAssignHandle 继承 Mixin 时 Mixin 未注册)。每遍注册新类后,下一遍子类可继承。
VLogger.info("预注册 struct/enum/union...", "PhaseA")
src_dir_len_pre: t.CSizeT = string.strlen(source_dir)
PHASE_A_PRE_MAX_PASSES: t.CInt = 3
src_dir_len_pre: sizet = string.strlen(source_dir)
PHASE_A_PRE_MAX_PASSES: int = 3
for pass_i in range(PHASE_A_PRE_MAX_PASSES):
struct_count_before: int = GenApi.get_struct_count()
for i in range(file_count):
ea_pre: t.CUInt64T = t.CUInt64T(entries) + i * entry_size
ea_pre: uint64 = uint64(entries) + i * entry_size
ent_pre: SrcFileEntry | t.CPtr = (SrcFileEntry | t.CPtr)(t.CVoid(ea_pre, t.CPtr))
if ent_pre is None or ent_pre.Path is None:
continue
@@ -1139,10 +1139,10 @@ def RunMultiFileProject(mb: memhub.MemBuddy | t.CPtr,
break
VLogger.info("预注册完成", "PhaseA")
# Phase A IR 缓冲:1MB 不够,ast/parser.vp 的 text.ll 超 1MB 被截断 →
# 合并 IR 尾部丢字(opt: "end of file in global variable name")。
PHASE_A_IR_SIZE: t.CSizeT = 8388608
td_len_pa: t.CSizeT = string.strlen(temp_dir)
# Phase A IR 缓冲:1MB 不够,ast/parser.vp 的 text.ll 超 1MB 被截断 →
# 合并 IR 尾部丢字(opt: "end of file in global variable name")。
PHASE_A_IR_SIZE: sizet = 8388608
td_len_pa: sizet = string.strlen(temp_dir)
# 设置 temp 目录路径,使 HandlesExprCall 能读取依赖模块的 text.ll
# 用于跨模块方法返回类型查找(避免指针返回值被截断为 i32)
@@ -1167,29 +1167,29 @@ def RunMultiFileProject(mb: memhub.MemBuddy | t.CPtr,
stdlib.free(entries)
return 1
string.memset(done_flags, 0, file_count)
PHASE_A_MAX_PASSES: t.CInt = 32
PHASE_A_MAX_PASSES: int = 32
for pass_a in range(PHASE_A_MAX_PASSES):
completed_this_pass: int = 0
for i in range(file_count):
if done_flags[i] != 0:
continue
ea: t.CUInt64T = t.CUInt64T(entries) + i * entry_size
ea: uint64 = uint64(entries) + i * entry_size
ent: SrcFileEntry | t.CPtr = (SrcFileEntry | t.CPtr)(t.CVoid(ea, t.CPtr))
# 计时点 0:本文件处理开始(translate 段起点)
t_pa0: t.CUInt64T = w32.win32base.GetTickCount64()
t_pa0: uint64 = w32.win32base.GetTickCount64()
if ent is None or ent.Path is None:
done_flags[i] = 1
completed_this_pass += 1
continue
# 计算源文件的包名(相对 source_dir 的目录部分)
src_dir_len_pa: t.CSizeT = string.strlen(source_dir)
src_dir_len_pa: sizet = string.strlen(source_dir)
pkg_pa: str = None
if string.strlen(ent.Path) > src_dir_len_pa + 1:
rel_path_pa: str = ent.Path + src_dir_len_pa + 1
pkg_pa = GenApi.compute_package_from_relpath(mb, rel_path_pa)
tr_a: HandlesTranslator.Translator | t.CPtr = BuildPipeline.TranslateFileGetTrans(mb, ent.Path, ent.Sha1, pkg_pa, 0, temp_dir)
# 计时点 1:translate 返回
t_pa1: t.CUInt64T = w32.win32base.GetTickCount64()
t_pa1: uint64 = w32.win32base.GetTickCount64()
if tr_a is None:
# 翻译失败(语法/解析错误):记录待下遍重试,收敛检查统一报错
# OOM 清理:失败翻译也已产生 AST/tokens 瞬时数据,立即回收
@@ -1204,13 +1204,13 @@ def RunMultiFileProject(mb: memhub.MemBuddy | t.CPtr,
# _list/_dict/stdlib/t/c 等公共依赖)会让 app_deps 无去重
# 膨胀到接近 64KB,_BuildReachableSha1Set 的初始 worklist
# 即满 → BFS 展开必报"依赖 worklist 溢出"。
im_len_a: t.CSizeT = string.strlen(tr_a._imported_modules)
im_pos_a: t.CSizeT = 0
im_len_a: sizet = string.strlen(tr_a._imported_modules)
im_pos_a: sizet = 0
while im_pos_a < im_len_a:
im_start_a: t.CSizeT = im_pos_a
im_start_a: sizet = im_pos_a
while im_pos_a < im_len_a and tr_a._imported_modules[im_pos_a] != ' ':
im_pos_a += 1
im_mod_len: t.CSizeT = im_pos_a - im_start_a
im_mod_len: sizet = im_pos_a - im_start_a
if im_pos_a < im_len_a:
im_pos_a += 1
if im_mod_len == 0:
@@ -1250,13 +1250,13 @@ def RunMultiFileProject(mb: memhub.MemBuddy | t.CPtr,
md_cnt: int = 0
war: str = "" # warning 信息
if tr_a._imported_modules is not None:
im_dp_len: t.CSizeT = string.strlen(tr_a._imported_modules)
im_dp_pos: t.CSizeT = 0
im_dp_len: sizet = string.strlen(tr_a._imported_modules)
im_dp_pos: sizet = 0
while im_dp_pos < im_dp_len:
im_dp_start: t.CSizeT = im_dp_pos
im_dp_start: sizet = im_dp_pos
while im_dp_pos < im_dp_len and tr_a._imported_modules[im_dp_pos] != ' ':
im_dp_pos += 1
im_dp_mod_len: t.CSizeT = im_dp_pos - im_dp_start
im_dp_mod_len: sizet = im_dp_pos - im_dp_start
if im_dp_pos < im_dp_len:
im_dp_pos += 1
if im_dp_mod_len == 0:
@@ -1348,7 +1348,7 @@ def RunMultiFileProject(mb: memhub.MemBuddy | t.CPtr,
if stub_buf_a is None:
VLogger.error("stub 缓冲区分配失败", "PhaseA")
tr_a.dump_ir(stub_buf_a, PHASE_A_IR_SIZE, llvmlite.OUTPUT_STUB)
stub_len_a: t.CSizeT = string.strlen(stub_buf_a)
stub_len_a: sizet = string.strlen(stub_buf_a)
# save stub.ll (切片路径: temp_dir/{sha1前缀}/{sha1}.stub.ll)
stub_path_a: str = StubMergerCollect._sliced_path(temp_dir, td_len_pa, ent.Sha1, "stub.ll")
@@ -1365,7 +1365,7 @@ def RunMultiFileProject(mb: memhub.MemBuddy | t.CPtr,
if text_buf_a is None:
VLogger.error("text 缓冲区分配失败", "PhaseA")
tr_a.dump_ir(text_buf_a, PHASE_A_IR_SIZE, llvmlite.OUTPUT_TEXT)
text_len_a: t.CSizeT = string.strlen(text_buf_a)
text_len_a: sizet = string.strlen(text_buf_a)
# save text.ll (切片路径)
text_path_a: str = StubMergerCollect._sliced_path(temp_dir, td_len_pa, ent.Sha1, "text.ll")
@@ -1383,13 +1383,13 @@ def RunMultiFileProject(mb: memhub.MemBuddy | t.CPtr,
df_a: fileio.File | t.CPtr = fileio.File(deps_path_a, fileio.MODE.W)
if not df_a.closed:
if tr_a._imported_modules is not None:
dl_a: t.CSizeT = string.strlen(tr_a._imported_modules)
dl_a: sizet = string.strlen(tr_a._imported_modules)
df_a.write(tr_a._imported_modules, dl_a)
df_a.close()
stdlib.free(deps_path_a)
# 计时点 2:stub+text dump 及写盘完成;输出逐文件进度(对齐 Phase1 1b)
t_pa2: t.CUInt64T = w32.win32base.GetTickCount64()
t_pa2: uint64 = w32.win32base.GetTickCount64()
VLogger.info(f"[{i+1}/{file_count}] PhaseA: {ent.Path} (translate={t_pa1-t_pa0} ms, dump={t_pa2-t_pa1} ms, total={t_pa2-t_pa0} ms)", "PhaseA")
done_flags[i] = 1
@@ -1411,10 +1411,10 @@ def RunMultiFileProject(mb: memhub.MemBuddy | t.CPtr,
# 依赖树,[MISS] 标出缺 text.ll 的节点,缩小到具体缺失链。
# 注意:VLogger.error 内部调用 sys.exit(1),必须放在所有图形输出
# 之后——此前"ERROR 行后调图"导致进程在 ERROR 处即退出,图永远打不出。
td_len_fail: t.CSizeT = string.strlen(temp_dir)
td_len_fail: sizet = string.strlen(temp_dir)
for i_err in range(file_count):
if done_flags[i_err] == 0:
ea_err: t.CUInt64T = t.CUInt64T(entries) + i_err * entry_size
ea_err: uint64 = uint64(entries) + i_err * entry_size
ent_err: SrcFileEntry | t.CPtr = (SrcFileEntry | t.CPtr)(t.CVoid(ea_err, t.CPtr))
if ent_err is not None and ent_err.Path is not None:
if ent_err.Sha1 is not None:
@@ -1443,12 +1443,12 @@ def RunMultiFileProject(mb: memhub.MemBuddy | t.CPtr,
# reachable_set/reachable_count: Phase B+ 填充,Phase C 用于按需链接
reachable_set: bytes = None
reachable_count: int = 0
OBJ_PATHS_SIZE: t.CSizeT = 65536
OBJ_PATHS_SIZE: sizet = 65536
obj_paths: bytes = stdlib.malloc(OBJ_PATHS_SIZE)
if obj_paths is None:
return 1
obj_paths[0] = '\0'
obj_pos: t.CSizeT = 0
obj_pos: sizet = 0
# main_obj_path: 存放定义了用户 main 的 .obj 路径(链接时放在最前面,
# 避免 --allow-multiple-definition 选择了其他模块的 wrapper main)
main_obj_path: bytes = stdlib.malloc(512)
@@ -1458,35 +1458,35 @@ def RunMultiFileProject(mb: memhub.MemBuddy | t.CPtr,
compiled_count: int = 0
# 组合 IR 缓冲区大小(4MB,足够容纳本地 stub + 所有依赖 stub + 本地 text)
COMBINED_IR_SIZE: t.CSizeT = 4194304
COMBINED_IR_SIZE: sizet = 4194304
# llc 任务表(stdlib.malloc,跨线程存活):连续 LlcTask 记录数组,
# 循环内只写 .ll + 构造任务,循环后 run_llc_parallel 分批并行跑 llc
llc_tasks: bytes = stdlib.malloc(t.CSizeT(file_count) * BuildPipeline.LlcTask.__sizeof__())
llc_tasks: bytes = stdlib.malloc(sizet(file_count) * BuildPipeline.LlcTask.__sizeof__())
if llc_tasks is None:
VLogger.error("llc 任务表分配失败", "PhaseB")
return 1
llc_task_count: int = 0
for i in range(file_count):
ea: t.CUInt64T = t.CUInt64T(entries) + i * entry_size
ea: uint64 = uint64(entries) + i * entry_size
ent: SrcFileEntry | t.CPtr = (SrcFileEntry | t.CPtr)(t.CVoid(ea, t.CPtr))
if ent is None or ent.Path is None or ent.Sha1 is None:
continue
# 单文件三步计时起点(GetTickCount64,ms)
t_pb0: t.CUInt64T = w32.win32base.GetTickCount64()
t_pb0: uint64 = w32.win32base.GetTickCount64()
# 组合本地 stub + 所有依赖 stub + 本地 text → 完整 IR
combined_ir: bytes = stdlib.malloc(COMBINED_IR_SIZE)
if combined_ir is None:
VLogger.error(f"combined_ir 分配失败: {ent.Path}", "PhaseB")
continue
combined_len: t.CSizeT = StubMergerBuild.BuildCombinedIR(temp_dir, ent.Sha1, combined_ir, COMBINED_IR_SIZE)
combined_len: sizet = StubMergerBuild.BuildCombinedIR(temp_dir, ent.Sha1, combined_ir, COMBINED_IR_SIZE)
if combined_len == 0:
VLogger.error(f"BuildCombinedIR 失败: {ent.Path}", "PhaseB")
stdlib.free(combined_ir)
continue
# 计时点 1:BuildCombinedIR 完成
t_pb1: t.CUInt64T = w32.win32base.GetTickCount64()
t_pb1: uint64 = w32.win32base.GetTickCount64()
# 写 .ll(llc 线程只读此文件);llc 本身改为循环后批量并行
ret_w: int = BuildPipeline.write_ir_to_file(combined_ir, combined_len, temp_dir, ent.Sha1)
@@ -1495,7 +1495,7 @@ def RunMultiFileProject(mb: memhub.MemBuddy | t.CPtr,
VLogger.error(f"写 .ll 失败: {ent.Path}", "PhaseB")
sys.exit(1)
# 计时点 2:写 .ll 完成
t_pb2: t.CUInt64T = w32.win32base.GetTickCount64()
t_pb2: uint64 = w32.win32base.GetTickCount64()
# 构造 llc 任务(命令串 stdlib.malloc,线程运行期不被 reset 回收)
llc_ir_path: str = BuildPipeline.build_sliced_path(temp_dir, ent.Sha1, "ll")
@@ -1503,20 +1503,20 @@ def RunMultiFileProject(mb: memhub.MemBuddy | t.CPtr,
VLogger.error("llc 输入路径构造失败", "PhaseB")
sys.exit(1)
tslot: BuildPipeline.LlcTask | t.CPtr = (BuildPipeline.LlcTask | t.CPtr)(t.CVoid(
t.CUInt64T(llc_tasks) + t.CSizeT(llc_task_count) * BuildPipeline.LlcTask.__sizeof__(), t.CPtr))
uint64(llc_tasks) + sizet(llc_task_count) * BuildPipeline.LlcTask.__sizeof__(), t.CPtr))
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 任务构造完成
t_pb3: t.CUInt64T = w32.win32base.GetTickCount64()
t_pb3: uint64 = w32.win32base.GetTickCount64()
llc_task_count += 1
compiled_count += 1
# 显示已提交 llc 的文件(含三步计时:合并 stub / 写 .ll / 构造任务)
VLogger.info(f"[{i+1}/{file_count}] llc 已提交: {ent.Path} (merge={t_pb1-t_pb0} ms, write={t_pb2-t_pb1} ms, task={t_pb3-t_pb2} ms, total={t_pb3-t_pb0} ms)", "PhaseB")
# 构造 .obj 路径,检测是否是 main 模块(test_main.vp 或 main.vp,不再识别 .py)
od_len: t.CSizeT = string.strlen(output_dir)
od_len: sizet = string.strlen(output_dir)
is_main_mod: int = 0
if string.strstr(ent.Path, "test_main.vp") is not None:
is_main_mod = 1
@@ -1526,7 +1526,7 @@ def RunMultiFileProject(mb: memhub.MemBuddy | t.CPtr,
# 切片路径: output_dir/{sha1前缀}/{sha1}.obj
obj_path_sliced: str = StubMergerCollect._sliced_path(output_dir, od_len, ent.Sha1, "obj")
if obj_path_sliced is not None:
op_sliced_len: t.CSizeT = string.strlen(obj_path_sliced)
op_sliced_len: sizet = string.strlen(obj_path_sliced)
if is_main_mod != 0:
# main 模块: 复制到 main_obj_path(确保链接时 main 在最前)
if op_sliced_len < 512:
@@ -1557,17 +1557,17 @@ def RunMultiFileProject(mb: memhub.MemBuddy | t.CPtr,
ti: int = 0
while ti < llc_task_count:
tfree: BuildPipeline.LlcTask | t.CPtr = (BuildPipeline.LlcTask | t.CPtr)(t.CVoid(
t.CUInt64T(llc_tasks) + t.CSizeT(ti) * BuildPipeline.LlcTask.__sizeof__(), t.CPtr))
uint64(llc_tasks) + sizet(ti) * BuildPipeline.LlcTask.__sizeof__(), t.CPtr))
BuildPipeline.free_llc_task(tfree)
ti += 1
stdlib.free(llc_tasks)
# 汇编 .s 文件:llvm-mc → .obj(isr.s 等,符号为裸名,与 .vp 的
# CExport/State stub 声明匹配)。obj 加入 obj_paths 参与 Phase C 链接。
od_len_as: t.CSizeT = string.strlen(output_dir)
od_len_as: sizet = string.strlen(output_dir)
asm_compiled: int = 0
for ai_as in range(asm_file_count):
ea_as: t.CUInt64T = t.CUInt64T(asm_entries) + ai_as * entry_size
ea_as: uint64 = uint64(asm_entries) + ai_as * entry_size
ent_as: SrcFileEntry | t.CPtr = (SrcFileEntry | t.CPtr)(t.CVoid(ea_as, t.CPtr))
if ent_as is None or ent_as.Path is None or ent_as.Sha1 is None:
continue
@@ -1578,7 +1578,7 @@ def RunMultiFileProject(mb: memhub.MemBuddy | t.CPtr,
sys.exit(1)
obj_path_asm: str = StubMergerCollect._sliced_path(output_dir, od_len_as, ent_as.Sha1, "obj")
if obj_path_asm is not None:
op_len_asm: t.CSizeT = string.strlen(obj_path_asm)
op_len_asm: sizet = string.strlen(obj_path_asm)
if obj_pos + op_len_asm + 2 < OBJ_PATHS_SIZE:
if obj_pos > 0:
obj_paths[obj_pos] = ' '
@@ -1603,7 +1603,7 @@ def RunMultiFileProject(mb: memhub.MemBuddy | t.CPtr,
# 而非遍历整个 includes 目录。通过 _BuildReachableSha1Set 构建依赖图。
if includes_dir is not None and includes_binary_dir is not None:
inc_compiled: int = 0
td_len_mi: t.CSizeT = string.strlen(temp_dir)
td_len_mi: sizet = string.strlen(temp_dir)
# 诊断日志:确认 Phase B+ 入口和 Sha1Store 状态
VLogger.info(f"PhaseB+ 入口: store_count={StubMergerStore.GetSha1StoreCount()} includes_binary_dir={includes_binary_dir}", "PhaseB+")
@@ -1617,7 +1617,7 @@ def RunMultiFileProject(mb: memhub.MemBuddy | t.CPtr,
# 构建可达 SHA1 集合(依赖图遍历)
# app_deps_buf 为 None 时回退到扫描 source_dir(非递归)
REACHABLE_SET_SIZE: t.CSizeT = t.CSizeT(StubMerger.MAX_INCLUDES_SHA1) * 17
REACHABLE_SET_SIZE: sizet = sizet(StubMerger.MAX_INCLUDES_SHA1) * 17
reachable_set: bytes = stdlib.malloc(REACHABLE_SET_SIZE)
reachable_count: int = 0
if reachable_set is not None:
@@ -1642,7 +1642,7 @@ def RunMultiFileProject(mb: memhub.MemBuddy | t.CPtr,
# 避免 store 联合返回值(bytes|t.CPtr)跨函数传参/索引的地址异常
# (与 _BuildReachableSha1Set 的 BFS 一致)。
# rel/incdir 仅本函数内按索引读取(不跨函数传参),保留 store 指针。
td_len_pb: t.CSizeT = string.strlen(temp_dir)
td_len_pb: sizet = string.strlen(temp_dir)
store_sha1_arr_mi: bytes = stdlib.malloc(StubMerger.MAX_INCLUDES * 17)
store_mod_arr_mi: bytes = stdlib.malloc(StubMerger.MAX_INCLUDES * 64)
store_count_mi: int = 0
@@ -1657,7 +1657,7 @@ def RunMultiFileProject(mb: memhub.MemBuddy | t.CPtr,
# 拓扑排序可达 includes:被依赖模块先完整翻译。跨模块 vtable 生成
# 需要依赖模块的函数 TypeStr 已注册到全局表(如 astaux 继承 base 的 AST)
topo_idx: t.CSizeT | t.CPtr = (t.CSizeT | t.CPtr)(stdlib.malloc(8 * (store_count_mi + 1)))
topo_idx: sizet | t.CPtr = (sizet | t.CPtr)(stdlib.malloc(8 * (store_count_mi + 1)))
topo_count: int = 0
if topo_idx is None:
VLogger.error("拓扑排序索引分配失败,终止编译", "PhaseB+")
@@ -1673,15 +1673,15 @@ def RunMultiFileProject(mb: memhub.MemBuddy | t.CPtr,
# 诊断:dump reachable_set 内容(验证 BFS 写入的 sha1 是否有效)
ri_dbg: int = 0
for ri_dbg in range(reachable_count):
rsha1_dbg: str = reachable_set + t.CSizeT(ri_dbg) * 17
rsha1_dbg: str = reachable_set + sizet(ri_dbg) * 17
VLogger.debug(f"诊断 reachable[{ri_dbg}]={rsha1_dbg}", "PhaseB+")
for si_mi in range(topo_count):
# 当前条目(拓扑序索引,仅含可达模块)
ti: int = topo_idx[si_mi]
# 获取当前条目的 SHA1 和 rel_path
inc_sha1_mi: str = store_sha1_arr_mi + t.CSizeT(ti) * 17
inc_rel_mi: str = store_rel_arr_mi + t.CSizeT(ti) * StubMerger.MAX_REL_PATH_LEN
inc_sha1_mi: str = store_sha1_arr_mi + sizet(ti) * 17
inc_rel_mi: str = store_rel_arr_mi + sizet(ti) * StubMerger.MAX_REL_PATH_LEN
# 跳过 App 源文件:App 文件可能同时被 includes 扫描(includes
# 目录含 source_dir 上层,如 ViperOS 含 Apps/),且被其他 App
# import(Scene3D 的 gfx.vp)→ 在可达集合中。若 Phase B+ 再编译
@@ -1690,7 +1690,7 @@ def RunMultiFileProject(mb: memhub.MemBuddy | t.CPtr,
# (9aab6ff7475c1bbf.Vec3.__init__ 等,Scene3D 根因)。
app_skip_mi: int = 0
for ai_mi in range(file_count):
ea_ap: t.CUInt64T = t.CUInt64T(entries) + ai_mi * entry_size
ea_ap: uint64 = uint64(entries) + ai_mi * entry_size
ent_ap: SrcFileEntry | t.CPtr = (SrcFileEntry | t.CPtr)(t.CVoid(ea_ap, t.CPtr))
if ent_ap is not None and ent_ap.Sha1 is not None:
if string.strcmp(ent_ap.Sha1, inc_sha1_mi) == 0:
@@ -1699,7 +1699,7 @@ def RunMultiFileProject(mb: memhub.MemBuddy | t.CPtr,
if app_skip_mi != 0:
continue
# 检查 .obj 是否已存在于 includes.binary(切片子目录)
ibd_len_mi: t.CSizeT = string.strlen(includes_binary_dir)
ibd_len_mi: sizet = string.strlen(includes_binary_dir)
check_pat_mi: str = StubMergerCollect._sliced_path(includes_binary_dir, ibd_len_mi, inc_sha1_mi, "obj")
check_fd_mi: w32.win32file.WIN32_FIND_DATAA | t.CPtr = stdlib.malloc(w32.win32file.WIN32_FIND_DATAA.__sizeof__())
obj_exists_mi: int = 0
@@ -1720,11 +1720,11 @@ def RunMultiFileProject(mb: memhub.MemBuddy | t.CPtr,
# .obj 不存在,需要编译
# 构造源文件路径: {所属 includes 根目录}/{rel_path}(多目录逐条取 IncDir,空串回退 includes_dir)
rel_path_len_mi: t.CSizeT = string.strlen(inc_rel_mi)
incdir_mi: str = store_incdir_arr_mi + t.CSizeT(ti) * StubMerger.MAX_INC_DIR_LEN
rel_path_len_mi: sizet = string.strlen(inc_rel_mi)
incdir_mi: str = store_incdir_arr_mi + sizet(ti) * StubMerger.MAX_INC_DIR_LEN
if incdir_mi is None or incdir_mi[0] == '\0':
incdir_mi = includes_dir
inc_dir_len_mi: t.CSizeT = string.strlen(incdir_mi)
inc_dir_len_mi: sizet = string.strlen(incdir_mi)
src_fp_mi: bytes = stdlib.malloc(inc_dir_len_mi + 1 + rel_path_len_mi + 1)
if src_fp_mi is None:
stdlib.free(check_pat_mi)
@@ -1743,7 +1743,7 @@ def RunMultiFileProject(mb: memhub.MemBuddy | t.CPtr,
if not tf_mi.closed:
is_decl_mi = 1
tbuf_mi: bytes = stdlib.malloc(StubMerger.STUB_READ_BUF_SIZE)
tbr_mi: t.CInt64T = 0
tbr_mi: int64 = 0
if tbuf_mi is not None:
tbr_mi = tf_mi.read_all(tbuf_mi, StubMerger.STUB_READ_BUF_SIZE)
if tbuf_mi is not None and tbr_mi > 0:
@@ -1752,14 +1752,14 @@ def RunMultiFileProject(mb: memhub.MemBuddy | t.CPtr,
# 逐行扫描: 找 define 行即为实现文件
# (不再要求行中含 @",因为 memhub 等模块的函数名
# 如 @ca40915f11b8b6ad._align_up 不带引号但仍是实现文件)
tpos_mi: t.CSizeT = 0
tpos_mi: sizet = 0
while tpos_mi < tbr_mi:
tls_mi: t.CSizeT = tpos_mi
tls_mi: sizet = tpos_mi
while tpos_mi < tbr_mi:
if tbuf_mi[tpos_mi] == '\n':
break
tpos_mi += 1
tll_mi: t.CSizeT = tpos_mi - tls_mi
tll_mi: sizet = tpos_mi - tls_mi
if tpos_mi < tbr_mi:
tpos_mi += 1
if tll_mi >= 7 and string.strncmp(tbuf_mi + tls_mi, "define ", 7) == 0:
@@ -1783,7 +1783,7 @@ def RunMultiFileProject(mb: memhub.MemBuddy | t.CPtr,
# 尝试 BuildCombinedIR(stub/text 应已由 Phase1 生成)
inc_combined_mi: bytes = stdlib.malloc(COMBINED_IR_SIZE)
inc_combined_len_mi: t.CSizeT = 0
inc_combined_len_mi: sizet = 0
if inc_combined_mi is not None:
inc_combined_len_mi = StubMergerBuild.BuildCombinedIR(temp_dir, inc_sha1_mi, inc_combined_mi, COMBINED_IR_SIZE)
@@ -1796,13 +1796,13 @@ def RunMultiFileProject(mb: memhub.MemBuddy | t.CPtr,
inc_pkg_mi = GenApi.compute_package_from_relpath(mb, inc_rel_mi2)
tr_mi: HandlesTranslator.Translator | t.CPtr = BuildPipeline.TranslateFileGetTrans(mb, src_fp_mi, inc_sha1_mi, inc_pkg_mi)
if tr_mi is not None:
# PBP IR 缓冲:同 PHASE_A_IR_SIZE(parser.vp text.ll >1MB 截断根因)
PBP_IR_SIZE: t.CSizeT = 8388608
# PBP IR 缓冲:同 PHASE_A_IR_SIZE(parser.vp text.ll >1MB 截断根因)
PBP_IR_SIZE: sizet = 8388608
# 保存 stub.ll (切片路径)
inc_stub_buf: bytes = stdlib.malloc(PBP_IR_SIZE)
if inc_stub_buf is not None:
tr_mi.dump_ir(inc_stub_buf, PBP_IR_SIZE, llvmlite.OUTPUT_STUB)
inc_stub_len: t.CSizeT = string.strlen(inc_stub_buf)
inc_stub_len: sizet = string.strlen(inc_stub_buf)
inc_stub_path: str = StubMergerCollect._sliced_path(temp_dir, td_len_mi, inc_sha1_mi, "stub.ll")
if inc_stub_path is not None:
isf: fileio.File | t.CPtr = fileio.File(inc_stub_path, fileio.MODE.W)
@@ -1815,7 +1815,7 @@ def RunMultiFileProject(mb: memhub.MemBuddy | t.CPtr,
inc_text_buf: bytes = stdlib.malloc(PBP_IR_SIZE)
if inc_text_buf is not None:
tr_mi.dump_ir(inc_text_buf, PBP_IR_SIZE, llvmlite.OUTPUT_TEXT)
inc_text_len: t.CSizeT = string.strlen(inc_text_buf)
inc_text_len: sizet = string.strlen(inc_text_buf)
inc_text_path: str = StubMergerCollect._sliced_path(temp_dir, td_len_mi, inc_sha1_mi, "text.ll")
if inc_text_path is not None:
itf: fileio.File | t.CPtr = fileio.File(inc_text_path, fileio.MODE.W)
@@ -1872,11 +1872,11 @@ def RunMultiFileProject(mb: memhub.MemBuddy | t.CPtr,
VLogger.info(f"[includes {inc_compiled}] 编译完成: {src_fp_mi}", "PhaseB+")
# 添加到 obj_paths (切片路径,从 includes_binary_dir 取)
ibd_len_mi2: t.CSizeT = string.strlen(includes_binary_dir)
ibd_len_mi2: sizet = string.strlen(includes_binary_dir)
inc_obj_sliced: str = StubMergerCollect._sliced_path(includes_binary_dir, ibd_len_mi2, inc_sha1_mi, "obj")
if inc_obj_sliced is not None:
inc_obj_len: t.CSizeT = string.strlen(inc_obj_sliced)
inc_obj_len: sizet = string.strlen(inc_obj_sliced)
if obj_pos + inc_obj_len + 2 < OBJ_PATHS_SIZE:
if obj_pos > 0:
obj_paths[obj_pos] = ' '
@@ -1915,8 +1915,8 @@ def RunMultiFileProject(mb: memhub.MemBuddy | t.CPtr,
# === 4. Phase C: 链接所有 .obj → .exe ===
log.banner("Phase C: 链接")
od_len2: t.CSizeT = string.strlen(output_dir)
lo_len: t.CSizeT = string.strlen(linker_output)
od_len2: sizet = string.strlen(output_dir)
lo_len: sizet = string.strlen(linker_output)
exe_path: bytes = stdlib.malloc(od_len2 + lo_len + 2)
if exe_path is not None:
viperlib.snprintf(exe_path, od_len2 + lo_len + 2, "%s/%s", output_dir, linker_output)
@@ -1930,10 +1930,10 @@ def RunMultiFileProject(mb: memhub.MemBuddy | t.CPtr,
stdlib.free(entries)
return 1
final_obj_paths[0] = '\0'
fop_pos: t.CSizeT = 0
fop_pos: sizet = 0
# main_obj_path 放在最前面(确保 --allow-multiple-definition 选择用户 main)
if main_obj_path[0] != '\0':
mlen: t.CSizeT = string.strlen(main_obj_path)
mlen: sizet = string.strlen(main_obj_path)
string.strcpy(final_obj_paths, main_obj_path)
fop_pos = mlen
@@ -1956,11 +1956,11 @@ def RunMultiFileProject(mb: memhub.MemBuddy | t.CPtr,
# 按图链接:遍历 reachable_set,只收集可达 includes 的 .obj
# 不再全量收集 includes.binary 下的所有 .obj
if reachable_set is not None and reachable_count > 0:
ibd_len_pc: t.CSizeT = string.strlen(includes_binary_dir)
td_len_pc: t.CSizeT = string.strlen(temp_dir)
ibd_len_pc: sizet = string.strlen(includes_binary_dir)
td_len_pc: sizet = string.strlen(temp_dir)
ri_pc: int
for ri_pc in range(reachable_count):
rsha1_pc: str = reachable_set + t.CSizeT(ri_pc) * 17
rsha1_pc: str = reachable_set + sizet(ri_pc) * 17
if rsha1_pc[0] == '\0':
continue
# 跳过 App 源文件:其 .obj 已在 output/(Phase A/B 编译,obj_paths
@@ -1969,7 +1969,7 @@ def RunMultiFileProject(mb: memhub.MemBuddy | t.CPtr,
# duplicate symbol(Scene3D gfx 9aab 根因)。
app_skip_pc: int = 0
for ai_pc in range(file_count):
ea_pc: t.CUInt64T = t.CUInt64T(entries) + ai_pc * entry_size
ea_pc: uint64 = uint64(entries) + ai_pc * entry_size
ent_pc: SrcFileEntry | t.CPtr = (SrcFileEntry | t.CPtr)(t.CVoid(ea_pc, t.CPtr))
if ent_pc is not None and ent_pc.Sha1 is not None:
if string.strcmp(ent_pc.Sha1, rsha1_pc) == 0:
@@ -1984,7 +1984,7 @@ def RunMultiFileProject(mb: memhub.MemBuddy | t.CPtr,
if not cf_pc.closed:
cf_pc.close()
# .obj 存在,追加到 final_obj_paths
op_len_pc: t.CSizeT = string.strlen(obj_path_pc)
op_len_pc: sizet = string.strlen(obj_path_pc)
if fop_pos + op_len_pc + 2 < OBJ_PATHS_SIZE + 512:
if fop_pos > 0:
final_obj_paths[fop_pos] = ' '
@@ -1998,7 +1998,7 @@ def RunMultiFileProject(mb: memhub.MemBuddy | t.CPtr,
# phase2command 模式:.obj 尚未生成(由手工执行 bat 产生),
# 缺失属预期——路径照常加入链接命令,跳过缺失报错。
if BuildPipeline._phase2_cmd_path is not None:
op_len_p2: t.CSizeT = string.strlen(obj_path_pc)
op_len_p2: sizet = string.strlen(obj_path_pc)
if fop_pos + op_len_p2 + 2 < OBJ_PATHS_SIZE + 512:
if fop_pos > 0:
final_obj_paths[fop_pos] = ' '
@@ -2011,7 +2011,7 @@ def RunMultiFileProject(mb: memhub.MemBuddy | t.CPtr,
stdlib.free(obj_path_pc)
final_obj_paths[fop_pos] = '\0'
obj_paths_len: t.CSizeT = fop_pos
obj_paths_len: sizet = fop_pos
# 释放 reachable_set(Phase C 已使用完毕)
if reachable_set is not None:
File diff suppressed because it is too large. Load diff
+265 -265
View File
@@ -1,265 +1,265 @@
import t, c
from stdint import *
import memhub
import string
import stdlib
import viperlib
import hashlib
import w32.win32file
import w32.win32base
import w32.fileio as fileio
# ============================================================
# Utils - 工程工具函数
#
# 提供 SHA1 计算和目录清理等通用工具函数。
# ============================================================
# 全局 mbuddy 指针
_mbuddy: memhub.MemBuddy | t.CPtr
# ============================================================
# nibble_to_hex_char - 半字节转十六进制字符
# ============================================================
def nibble_to_hex_char(n: int, uppercase: int) -> t.CChar:
"""0-15 → '0'-'9'/'a'-'f'(uppercase=1 时用 'A'-'F')"""
if n < 10: return '0' + n
if uppercase != 0: return 'A' + (n - 10)
return 'a' + (n - 10)
# ============================================================
# bytes_to_hex - 字节序列转十六进制字符串
# ============================================================
def bytes_to_hex(pool: memhub.MemBuddy | t.CPtr,
digest: bytes,
nbytes: t.CSizeT,
uppercase: int,
use_malloc: int) -> str:
"""将 digest 前 nbytes 字节转为 2*nbytes 个十六进制字符(含 null 终止)
use_malloc=1 时用 stdlib.malloc(调用方负责 free),否则 pool.alloc。
合并自 Utils.compute_sha1 / IncludesScanner.compute_file_sha1 的重复 hex 转换。
"""
if digest is None or nbytes <= 0:
return None
hex_len: t.CSizeT = nbytes * 2 + 1
hex_buf: str = None
if use_malloc != 0:
hex_buf = stdlib.malloc(hex_len)
else:
hex_buf = pool.alloc(hex_len)
if hex_buf is None:
return None
for i in range(nbytes):
hi: int = (digest[i] >> 4) & 0xF
lo: int = digest[i] & 0xF
hex_buf[i * 2] = nibble_to_hex_char(hi, uppercase)
hex_buf[i * 2 + 1] = nibble_to_hex_char(lo, uppercase)
hex_buf[nbytes * 2] = '\0'
return hex_buf
# ============================================================
# compute_sha1 - 计算字符串的 SHA1,返回前 16 个十六进制字符
#
# 使用 includes/hashlib 库的 sha1 类计算摘要,转为十六进制字符串。
# 参考 Projectrans.py 的 compute_sha1(hashlib.sha1().hexdigest()[:16])。
# ============================================================
def compute_sha1(pool: memhub.MemBuddy | t.CPtr, content: str) -> str:
"""计算字符串的 SHA1,返回前 16 个十六进制字符(用于文件命名)"""
if content is None or pool is None:
return None
# 构造 sha1 对象(__init__ 会初始化 state/count/buf)
# ctx 在栈上分配(alloca),函数内使用完即丢弃,无需堆分配
ctx: hashlib.sha1 | t.CPtr = hashlib.sha1()
if ctx is None: return None
# 计算摘要
ctx.update(content)
digest: bytes = pool.alloc(hashlib.SHA1_DIGEST_LEN)
if digest is None: return None
ctx.final(digest)
# 转为十六进制字符串(取前 8 字节 = 16 个十六进制字符)
return bytes_to_hex(pool, digest, 8, 0, 0)
# ============================================================
# is_vp_at - 检查路径段是否以 .vp 后缀结尾
# ============================================================
def is_vp_at(p: str, start: t.CSizeT, plen: t.CSizeT) -> int:
"""检查 p[start, start+plen) 是否以 .vp 后缀结尾(1=是,0=否)。
不再识别 .py(移除 vp -> py 后缀识别回退:Viper 源文件仅 .vp)。
"""
if p is None or plen <= 3:
return 0
base: t.CSizeT = start + plen - 3
if p[base] == '.' and p[base + 1] == 'v' and p[base + 2] == 'p':
return 1
return 0
# ============================================================
# JoinPath - 拼接两个路径段为 a/b
# ============================================================
def JoinPath(a: str, b: str) -> str:
"""拼接路径段为 "a/b"(stdlib.malloc 分配,调用方负责 free),失败返回 None"""
if a is None or b is None:
return None
a_len: t.CSizeT = string.strlen(a)
b_len: t.CSizeT = string.strlen(b)
total_len: t.CSizeT = a_len + b_len + 2
buf: str = stdlib.malloc(total_len)
if buf is None: return None
viperlib.snprintf(buf, total_len, "%s/%s", a, b)
return buf
# ============================================================
# read_file_to_buf - 读取整个文件到缓冲区(null 终止)
# ============================================================
def read_file_to_buf(path: str, buf_size: t.CSizeT) -> bytes:
"""读取文件到 stdlib.malloc 缓冲区并保证 null 终止
返回缓冲区(调用方负责 free);打开失败/空文件/分配失败返回 None。
合并自 Phase2/StubMerger/IncludesScanner 的重复"打开+读取+终止"序列。
"""
if path is None or buf_size <= 0: return None
sf: fileio.File | t.CPtr = fileio.File(path, fileio.MODE.R)
if sf.closed: return None
buf: bytes = stdlib.malloc(buf_size)
if buf is None:
sf.close()
return None
br: t.CInt64T = sf.read_all(buf, buf_size)
sf.close()
if br <= 0:
stdlib.free(buf)
return None
if br < buf_size:
buf[br] = 0
return buf
# ============================================================
# PathToModuleName - 文件路径转模块名
# ============================================================
def PathToModuleName(path: str, strip_includes_prefix: int) -> str:
"""将文件路径转换为模块名(stdlib.malloc 分配,调用方负责 free)
strip_includes_prefix=1 时跳过 includes/ 前缀(如 includes/ast/__init__.vp → ast)。
特殊处理 __init__.vp:pkg/__init__.vp → pkg(而非 pkg.__init__)。
合并自 StubMerger._PathToModuleName / IncludesScanner 内联模块名计算。
"""
if path is None:
return None
plen: t.CSizeT = string.strlen(path)
# 跳过 includes/ 或 includes\ 前缀(Windows 反斜杠兼容)
prefix_len: t.CSizeT = 9
path_start: t.CSizeT = 0
if strip_includes_prefix != 0 and plen > prefix_len and string.strncmp(path, "includes", 8) == 0:
psep_ch: t.CChar = path[8]
if psep_ch == '/' or psep_ch == '\\':
path_start = prefix_len
plen = plen - prefix_len
# 去掉 .vp 后缀(Viper 源文件仅 .vp,不再识别 .py)
if is_vp_at(path, path_start, plen) != 0:
plen -= 3
if plen == 0:
return None
# 检查是否以 /__init__ 或 \__init__ 结尾(包的 __init__.vp)
# 同时支持 / 和 \ 两种分隔符(TPC 写入的路径可能混合使用)
if plen > 9:
tail_off: t.CSizeT = path_start + plen - 9
sep_char: t.CChar = path[tail_off]
if (sep_char == '/' or sep_char == '\\') \
and path[tail_off + 1] == '_' and path[tail_off + 2] == '_' \
and path[tail_off + 3] == 'i' and path[tail_off + 4] == 'n' and path[tail_off + 5] == 'i' \
and path[tail_off + 6] == 't' and path[tail_off + 7] == '_' and path[tail_off + 8] == '_':
# 去掉 分隔符+__init__ 后缀,plen 就是包名部分长度
plen = tail_off - path_start
if plen == 0:
return None
# 复制并替换 / 为 .
result: str = stdlib.malloc(plen + 1)
if result is None:
return None
for ri in range(plen):
ch: t.CChar = path[path_start + ri]
if ch == '/' or ch == '\\':
result[ri] = '.'
else:
result[ri] = ch
result[plen] = '\0'
return result
# ============================================================
# CleanDir - 递归删除目录中所有文件和子目录(保留 dir_path 本身)
#
# 用于 --clean 选项:清理 temp_dir 和 output_dir 中的旧文件。
# SHA1 分片目录结构(如 temp/1c/、temp/7a/)需要递归清理,
# 否则旧的截断文件(如 256KB text.ll)会被 Phase1 跳过逻辑复用。
# ============================================================
def CleanDir(dir_path: str) -> int:
"""递归删除目录中所有文件和子目录,保留 dir_path 本身,返回删除的文件数,-1 表示错误"""
if dir_path is None:
return -1
dir_len: t.CSizeT = string.strlen(dir_path)
pattern: bytes = stdlib.malloc(dir_len + 8)
if pattern is None:
return -1
viperlib.snprintf(pattern, dir_len + 8, "%s/*", dir_path)
find_data: w32.win32file.WIN32_FIND_DATAA | t.CPtr = stdlib.malloc(w32.win32file.WIN32_FIND_DATAA.__sizeof__())
if find_data is None:
stdlib.free(pattern)
return -1
string.memset(find_data, 0, w32.win32file.WIN32_FIND_DATAA.__sizeof__())
handle: w32.win32base.HANDLE = w32.win32file.FindFirstFileA(pattern, find_data)
if handle == w32.win32base.INVALID_HANDLE_VALUE:
stdlib.free(pattern)
stdlib.free(find_data)
return 0
deleted: int = 0
while True:
fname: str = find_data.cFileName
if fname is not None:
# 跳过 . 和 ..
if fname[0] == '.':
if fname[1] == '\0':
fname = None
elif fname[1] == '.' and fname[2] == '\0':
fname = None
if fname is not None:
full_path: bytes = JoinPath(dir_path, fname)
if full_path is not None:
# 检查是否为目录(dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
is_dir: t.CUInt32T = find_data.dwFileAttributes & w32.win32file.FILE_ATTRIBUTE_DIRECTORY
if is_dir != 0:
# 递归清理子目录中的文件
sub_deleted: int = CleanDir(full_path)
if sub_deleted > 0:
deleted += sub_deleted
# 删除空子目录(RemoveDirectoryA 要求目录为空)
w32.win32file.RemoveDirectoryA(full_path)
else:
# 删除文件
if w32.win32file.DeleteFileA(full_path) != 0:
deleted += 1
stdlib.free(full_path)
if w32.win32file.FindNextFileA(handle, find_data) == 0:
break
w32.win32file.FindClose(handle)
stdlib.free(pattern)
stdlib.free(find_data)
return deleted
import t, c
from stdint import *
import memhub
import string
import stdlib
import viperlib
import hashlib
import w32.win32file
import w32.win32base
import w32.fileio as fileio
# ============================================================
# Utils - 工程工具函数
#
# 提供 SHA1 计算和目录清理等通用工具函数。
# ============================================================
# 全局 mbuddy 指针
_mbuddy: memhub.MemBuddy | t.CPtr
# ============================================================
# nibble_to_hex_char - 半字节转十六进制字符
# ============================================================
def nibble_to_hex_char(n: int, uppercase: int) -> char:
"""0-15 → '0'-'9'/'a'-'f'(uppercase=1 时用 'A'-'F')"""
if n < 10: return '0' + n
if uppercase != 0: return 'A' + (n - 10)
return 'a' + (n - 10)
# ============================================================
# bytes_to_hex - 字节序列转十六进制字符串
# ============================================================
def bytes_to_hex(pool: memhub.MemBuddy | t.CPtr,
digest: bytes,
nbytes: sizet,
uppercase: int,
use_malloc: int) -> str:
"""将 digest 前 nbytes 字节转为 2*nbytes 个十六进制字符(含 null 终止)
use_malloc=1 时用 stdlib.malloc(调用方负责 free),否则 pool.alloc。
合并自 Utils.compute_sha1 / IncludesScanner.compute_file_sha1 的重复 hex 转换。
"""
if digest is None or nbytes <= 0:
return None
hex_len: sizet = nbytes * 2 + 1
hex_buf: str = None
if use_malloc != 0:
hex_buf = stdlib.malloc(hex_len)
else:
hex_buf = pool.alloc(hex_len)
if hex_buf is None:
return None
for i in range(nbytes):
hi: int = (digest[i] >> 4) & 0xF
lo: int = digest[i] & 0xF
hex_buf[i * 2] = nibble_to_hex_char(hi, uppercase)
hex_buf[i * 2 + 1] = nibble_to_hex_char(lo, uppercase)
hex_buf[nbytes * 2] = '\0'
return hex_buf
# ============================================================
# compute_sha1 - 计算字符串的 SHA1,返回前 16 个十六进制字符
#
# 使用 includes/hashlib 库的 sha1 类计算摘要,转为十六进制字符串。
# 参考 Projectrans.py 的 compute_sha1(hashlib.sha1().hexdigest()[:16])。
# ============================================================
def compute_sha1(pool: memhub.MemBuddy | t.CPtr, content: str) -> str:
"""计算字符串的 SHA1,返回前 16 个十六进制字符(用于文件命名)"""
if content is None or pool is None:
return None
# 构造 sha1 对象(__init__ 会初始化 state/count/buf)
# ctx 在栈上分配(alloca),函数内使用完即丢弃,无需堆分配
ctx: hashlib.sha1 | t.CPtr = hashlib.sha1()
if ctx is None: return None
# 计算摘要
ctx.update(content)
digest: bytes = pool.alloc(hashlib.SHA1_DIGEST_LEN)
if digest is None: return None
ctx.final(digest)
# 转为十六进制字符串(取前 8 字节 = 16 个十六进制字符)
return bytes_to_hex(pool, digest, 8, 0, 0)
# ============================================================
# is_vp_at - 检查路径段是否以 .vp 后缀结尾
# ============================================================
def is_vp_at(p: str, start: sizet, plen: sizet) -> int:
"""检查 p[start, start+plen) 是否以 .vp 后缀结尾(1=是,0=否)。
不再识别 .py(移除 vp -> py 后缀识别回退:Viper 源文件仅 .vp)。
"""
if p is None or plen <= 3:
return 0
base: sizet = start + plen - 3
if p[base] == '.' and p[base + 1] == 'v' and p[base + 2] == 'p':
return 1
return 0
# ============================================================
# JoinPath - 拼接两个路径段为 a/b
# ============================================================
def JoinPath(a: str, b: str) -> str:
"""拼接路径段为 "a/b"(stdlib.malloc 分配,调用方负责 free),失败返回 None"""
if a is None or b is None:
return None
a_len: sizet = string.strlen(a)
b_len: sizet = string.strlen(b)
total_len: sizet = a_len + b_len + 2
buf: str = stdlib.malloc(total_len)
if buf is None: return None
viperlib.snprintf(buf, total_len, "%s/%s", a, b)
return buf
# ============================================================
# read_file_to_buf - 读取整个文件到缓冲区(null 终止)
# ============================================================
def read_file_to_buf(path: str, buf_size: sizet) -> bytes:
"""读取文件到 stdlib.malloc 缓冲区并保证 null 终止
返回缓冲区(调用方负责 free);打开失败/空文件/分配失败返回 None。
合并自 Phase2/StubMerger/IncludesScanner 的重复"打开+读取+终止"序列。
"""
if path is None or buf_size <= 0: return None
sf: fileio.File | t.CPtr = fileio.File(path, fileio.MODE.R)
if sf.closed: return None
buf: bytes = stdlib.malloc(buf_size)
if buf is None:
sf.close()
return None
br: int64 = sf.read_all(buf, buf_size)
sf.close()
if br <= 0:
stdlib.free(buf)
return None
if br < buf_size:
buf[br] = 0
return buf
# ============================================================
# PathToModuleName - 文件路径转模块名
# ============================================================
def PathToModuleName(path: str, strip_includes_prefix: int) -> str:
"""将文件路径转换为模块名(stdlib.malloc 分配,调用方负责 free)
strip_includes_prefix=1 时跳过 includes/ 前缀(如 includes/ast/__init__.vp → ast)。
特殊处理 __init__.vp:pkg/__init__.vp → pkg(而非 pkg.__init__)。
合并自 StubMerger._PathToModuleName / IncludesScanner 内联模块名计算。
"""
if path is None:
return None
plen: sizet = string.strlen(path)
# 跳过 includes/ 或 includes\ 前缀(Windows 反斜杠兼容)
prefix_len: sizet = 9
path_start: sizet = 0
if strip_includes_prefix != 0 and plen > prefix_len and string.strncmp(path, "includes", 8) == 0:
psep_ch: char = path[8]
if psep_ch == '/' or psep_ch == '\\':
path_start = prefix_len
plen = plen - prefix_len
# 去掉 .vp 后缀(Viper 源文件仅 .vp,不再识别 .py)
if is_vp_at(path, path_start, plen) != 0:
plen -= 3
if plen == 0:
return None
# 检查是否以 /__init__ 或 \__init__ 结尾(包的 __init__.vp)
# 同时支持 / 和 \ 两种分隔符(TPC 写入的路径可能混合使用)
if plen > 9:
tail_off: sizet = path_start + plen - 9
sep_char: char = path[tail_off]
if (sep_char == '/' or sep_char == '\\') \
and path[tail_off + 1] == '_' and path[tail_off + 2] == '_' \
and path[tail_off + 3] == 'i' and path[tail_off + 4] == 'n' and path[tail_off + 5] == 'i' \
and path[tail_off + 6] == 't' and path[tail_off + 7] == '_' and path[tail_off + 8] == '_':
# 去掉 分隔符+__init__ 后缀,plen 就是包名部分长度
plen = tail_off - path_start
if plen == 0:
return None
# 复制并替换 / 为 .
result: str = stdlib.malloc(plen + 1)
if result is None:
return None
for ri in range(plen):
ch: char = path[path_start + ri]
if ch == '/' or ch == '\\':
result[ri] = '.'
else:
result[ri] = ch
result[plen] = '\0'
return result
# ============================================================
# CleanDir - 递归删除目录中所有文件和子目录(保留 dir_path 本身)
#
# 用于 --clean 选项:清理 temp_dir 和 output_dir 中的旧文件。
# SHA1 分片目录结构(如 temp/1c/、temp/7a/)需要递归清理,
# 否则旧的截断文件(如 256KB text.ll)会被 Phase1 跳过逻辑复用。
# ============================================================
def CleanDir(dir_path: str) -> int:
"""递归删除目录中所有文件和子目录,保留 dir_path 本身,返回删除的文件数,-1 表示错误"""
if dir_path is None:
return -1
dir_len: sizet = string.strlen(dir_path)
pattern: bytes = stdlib.malloc(dir_len + 8)
if pattern is None:
return -1
viperlib.snprintf(pattern, dir_len + 8, "%s/*", dir_path)
find_data: w32.win32file.WIN32_FIND_DATAA | t.CPtr = stdlib.malloc(w32.win32file.WIN32_FIND_DATAA.__sizeof__())
if find_data is None:
stdlib.free(pattern)
return -1
string.memset(find_data, 0, w32.win32file.WIN32_FIND_DATAA.__sizeof__())
handle: w32.win32base.HANDLE = w32.win32file.FindFirstFileA(pattern, find_data)
if handle == w32.win32base.INVALID_HANDLE_VALUE:
stdlib.free(pattern)
stdlib.free(find_data)
return 0
deleted: int = 0
while True:
fname: str = find_data.cFileName
if fname is not None:
# 跳过 . 和 ..
if fname[0] == '.':
if fname[1] == '\0':
fname = None
elif fname[1] == '.' and fname[2] == '\0':
fname = None
if fname is not None:
full_path: bytes = JoinPath(dir_path, fname)
if full_path is not None:
# 检查是否为目录(dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
is_dir: uint32 = find_data.dwFileAttributes & w32.win32file.FILE_ATTRIBUTE_DIRECTORY
if is_dir != 0:
# 递归清理子目录中的文件
sub_deleted: int = CleanDir(full_path)
if sub_deleted > 0:
deleted += sub_deleted
# 删除空子目录(RemoveDirectoryA 要求目录为空)
w32.win32file.RemoveDirectoryA(full_path)
else:
# 删除文件
if w32.win32file.DeleteFileA(full_path) != 0:
deleted += 1
stdlib.free(full_path)
if w32.win32file.FindNextFileA(handle, find_data) == 0:
break
w32.win32file.FindClose(handle)
stdlib.free(pattern)
stdlib.free(find_data)
return deleted
+79 -79
View File
@@ -60,7 +60,7 @@ def _eval_binop_valid(node: ast.AST | t.CPtr) -> int:
return 0
def _eval_binop_int(node: ast.AST | t.CPtr) -> t.CInt64T:
def _eval_binop_int(node: ast.AST | t.CPtr) -> int64:
"""递归计算 BinOp 节点的整数值(64 位,避免大整数 CDefine 截断)"""
if node is None:
return 0
@@ -83,8 +83,8 @@ def _eval_binop_int(node: ast.AST | t.CPtr) -> t.CInt64T:
bop: ast.BinOp | t.CPtr = (ast.BinOp | t.CPtr)(node)
if bop.left is None or bop.right is None:
return 0
lv: t.CInt64T = _eval_binop_int(bop.left)
rv: t.CInt64T = _eval_binop_int(bop.right)
lv: int64 = _eval_binop_int(bop.left)
rv: int64 = _eval_binop_int(bop.right)
if bop.op == ast.OpKind.BitOr:
return lv | rv
if bop.op == ast.OpKind.BitAnd:
@@ -126,7 +126,7 @@ _g_pyi_cdefine_found: int = 0
# WINDOW_SIZE = 1<<0 = 1、MASK = 0-1 = -1,跨模块读回错误常量根因)。
# _GeneratePyiFromAst 开头按声明顺序注册到本缓存,Name 引用先查缓存。
# 缓存一律用 C 数组而非 list[T]:
# - 值缓存用 C 数组(t.CInt64T*)而非 list[int]:TPC 对 list[int].get 会误解析
# - 值缓存用 C 数组(int64*)而非 list[int]:TPC 对 list[int].get 会误解析
# 为 list[str].get(返回元素指针 i8*)→ ptrtoint 返回元素地址而非值 → MASK
# 变成 20323785277439(地址-1)。C 数组索引 [i] 直接返回 i64 值,可靠。
# - 名缓存用 C 数组(str|t.CPtr = i8**,字符串指针数组)而非 list[str]:
@@ -135,11 +135,11 @@ _g_pyi_cdefine_found: int = 0
# _fnv1a_hash → 解引用零页 access-violation(1.LOG ASan 崩溃根因)。
# 读写沿用 argparse.vp 遍历 argv 的可靠模式:t.CPtr(base + i*8) + e[0]。
_g_pyi_cdef_names: str | t.CPtr = None
_g_pyi_cdef_vals: t.CInt64T | t.CPtr = None
_g_pyi_cdef_count: t.CInt = 0
_g_pyi_cdef_vals: int64 | t.CPtr = None
_g_pyi_cdef_count: int = 0
def _lookup_cdefine_for_pyi(name: str) -> t.CInt64T:
def _lookup_cdefine_for_pyi(name: str) -> int64:
"""从本文件缓存 / 本地 CDefine 表查找常量值(用于 .vpi 生成时的 BinOp 计算)"""
global _g_pyi_cdefine_found
# 优先查本文件 CDefine 缓存(vpi 生成早于翻译阶段注册,全局表为空)
@@ -151,15 +151,15 @@ def _lookup_cdefine_for_pyi(name: str) -> t.CInt64T:
# 碰巧正确)。且绝不能对 _g_pyi_cdef_names 调 .get —— list 联合接收者
# 会被误分派为 HashTable.get,索引 inttoptr 成 key 指针读零页崩溃
# (1.LOG)。用 t.CPtr(base + i*8) + e[0] 取第 i 个名字指针(argparse 模式)。
pn: t.CSizeT = t.CSizeT(_g_pyi_cdef_count)
pi: t.CSizeT
pn: sizet = sizet(_g_pyi_cdef_count)
pi: sizet
for pi in range(pn):
entry_pc: str | t.CPtr = t.CPtr(t.CUInt64T(_g_pyi_cdef_names) + pi * 8)
entry_pc: str | t.CPtr = t.CPtr(uint64(_g_pyi_cdef_names) + pi * 8)
pnm: str = entry_pc[0]
if pnm is not None and string.strcmp(pnm, name) == 0:
_g_pyi_cdefine_found = 1
return _g_pyi_cdef_vals[pi]
val: t.CInt64T = GenApi.lookup_cdefine_constant(name)
val: int64 = GenApi.lookup_cdefine_constant(name)
if GenApi.is_cdefine_found() != 0:
_g_pyi_cdefine_found = 1
return val
@@ -167,7 +167,7 @@ def _lookup_cdefine_for_pyi(name: str) -> t.CInt64T:
return 0
def _eval_cdefine_value_cache(node: ast.AST | t.CPtr) -> t.CInt64T:
def _eval_cdefine_value_cache(node: ast.AST | t.CPtr) -> int64:
"""求值 CDefine 值(Constant/UnaryOp/BinOp/Call/Name),供 vpi 预处理注册缓存"""
if node is None:
return 0
@@ -208,15 +208,15 @@ def _pyi_cdefine_found() -> int:
# 将 text 追加到 buf 的 pos 位置,返回新的 pos。
# 自动处理缓冲区溢出(截断)。
# ============================================================
def _PyiEmit(buf: bytes, buf_size: t.CSizeT, pos: t.CSizeT,
text: str) -> t.CSizeT:
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: t.CSizeT = string.strlen(text)
tlen: sizet = string.strlen(text)
if tlen == 0:
return pos
remain: t.CSizeT = buf_size - pos
remain: sizet = buf_size - pos
if tlen >= remain:
tlen = remain - 1
if tlen > 0:
@@ -229,8 +229,8 @@ def _PyiEmit(buf: bytes, buf_size: t.CSizeT, pos: t.CSizeT,
#
# 追加 level*4 个空格到 buf 的 pos 位置。
# ============================================================
def _PyiIndent(buf: bytes, buf_size: t.CSizeT, pos: t.CSizeT,
level: int) -> t.CSizeT:
def _PyiIndent(buf: bytes, buf_size: sizet, pos: sizet,
level: int) -> sizet:
"""追加 level*4 个空格到 buf,返回新的 pos"""
i: int = 0
while i < level:
@@ -245,9 +245,9 @@ def _PyiIndent(buf: bytes, buf_size: t.CSizeT, pos: t.CSizeT,
# 将 AST 类型注解节点转换为字符串表示,写入 buf 的 pos 位置。
# 支持: Name, Attribute, Subscript, BinOp(|), Constant(前向引用), Tuple
# ============================================================
def _PyiTypeStr(buf: bytes, buf_size: t.CSizeT, pos: t.CSizeT,
def _PyiTypeStr(buf: bytes, buf_size: sizet, pos: sizet,
annot: ast.AST | t.CPtr,
depth: int = 0) -> t.CSizeT:
depth: int = 0) -> sizet:
"""递归生成类型注解字符串,返回新的 pos"""
# 递归深度守卫:AST 损坏成自引用环(Attribute.value/Subscript.slice/
# BinOp.left 等回指祖先)时无限递归直至栈耗尽(Phase1 vpi 生成最先
@@ -256,7 +256,7 @@ def _PyiTypeStr(buf: bytes, buf_size: t.CSizeT, pos: t.CSizeT,
VLogger.error("vpi 类型注解递归过深(AST 环或嵌套超过 64 层)", "StubGen")
sys.exit(1)
if annot is None:
return _PyiEmit(buf, buf_size, pos, "t.CInt")
return _PyiEmit(buf, buf_size, pos, "int")
k: int = annot.kind()
@@ -265,9 +265,9 @@ def _PyiTypeStr(buf: bytes, buf_size: t.CSizeT, pos: t.CSizeT,
nm: ast.Name | t.CPtr = (ast.Name | t.CPtr)(annot)
if nm.id is not None:
return _PyiEmit(buf, buf_size, pos, nm.id)
return _PyiEmit(buf, buf_size, pos, "t.CInt")
return _PyiEmit(buf, buf_size, pos, "int")
# Attribute: 属性引用 (如 t.CInt, memhub.MemBuddy)
# Attribute: 属性引用 (如 int, memhub.MemBuddy)
if k == ast.ASTKind.Attribute:
at: ast.Attribute | t.CPtr = (ast.Attribute | t.CPtr)(annot)
pos = _PyiTypeStr(buf, buf_size, pos, at.value, depth + 1)
@@ -304,8 +304,8 @@ def _PyiTypeStr(buf: bytes, buf_size: t.CSizeT, pos: t.CSizeT,
return pos
if cn.const_kind == ast.CONST_NONE:
return _PyiEmit(buf, buf_size, pos, "None")
# 数字常量(t.CArray[t.CUInt32T, 64] 的 count 等):输出数值本身,
# 而不是回退 t.CInt——否则 vpi 生成 "t.CArray[..., t.CInt]" 在加载
# 数字常量(t.CArray[uint32, 64] 的 count 等):输出数值本身,
# 而不是回退 int——否则 vpi 生成 "t.CArray[..., int]" 在加载
# stub 时触发 TypeError(count 必须是整数常量、None、CDefine 常量名
# 或常量表达式)。
if cn.const_kind == ast.CONST_INT or cn.const_kind == ast.CONST_CHAR:
@@ -315,15 +315,15 @@ def _PyiTypeStr(buf: bytes, buf_size: t.CSizeT, pos: t.CSizeT,
pos = _PyiEmit(buf, buf_size, pos, num_buf_ct)
stdlib.free(num_buf_ct)
return pos
return _PyiEmit(buf, buf_size, pos, "t.CInt")
return _PyiEmit(buf, buf_size, pos, "int")
# Tuple: 多参数下标 (如 Dict[str, int])
if k == ast.ASTKind.Tuple:
tup: ast.Tuple | t.CPtr = (ast.Tuple | t.CPtr)(annot)
if tup.elts is not None:
tup_elts: list[ast.AST | t.CPtr] | t.CPtr = tup.elts
tn: t.CSizeT = len(tup_elts)
ti: t.CSizeT = 0
tn: sizet = len(tup_elts)
ti: sizet = 0
while ti < tn:
if ti > 0:
pos = _PyiEmit(buf, buf_size, pos, ", ")
@@ -339,8 +339,8 @@ def _PyiTypeStr(buf: bytes, buf_size: t.CSizeT, pos: t.CSizeT,
pos = _PyiEmit(buf, buf_size, pos, "(")
if cl.args is not None:
cl_args: list[ast.AST | t.CPtr] | t.CPtr = cl.args
can: t.CSizeT = len(cl_args)
cai: t.CSizeT = 0
can: sizet = len(cl_args)
cai: sizet = 0
while cai < can:
if cai > 0:
pos = _PyiEmit(buf, buf_size, pos, ", ")
@@ -350,8 +350,8 @@ def _PyiTypeStr(buf: bytes, buf_size: t.CSizeT, pos: t.CSizeT,
pos = _PyiEmit(buf, buf_size, pos, ")")
return pos
# 未知类型,回退到 t.CInt
return _PyiEmit(buf, buf_size, pos, "t.CInt")
# 未知类型,回退到 int
return _PyiEmit(buf, buf_size, pos, "int")
# ============================================================
@@ -363,9 +363,9 @@ def _PyiTypeStr(buf: bytes, buf_size: t.CSizeT, pos: t.CSizeT,
# 用默认值填充,否则被调函数读到栈垃圾(假报递归过深/崩溃)。
# 支持: Constant(int/str/bool/None), Name(CDefine 常量), UnaryOp。
# ============================================================
def _PyiDefaultStr(buf: bytes, buf_size: t.CSizeT, pos: t.CSizeT,
def _PyiDefaultStr(buf: bytes, buf_size: sizet, pos: sizet,
node: ast.AST | t.CPtr,
depth: int = 0) -> t.CSizeT:
depth: int = 0) -> sizet:
"""生成默认值表达式文本到 buf,返回新的 pos"""
# 递归深度守卫:AST 损坏成自引用环时 fail-fast 终止(同 _PyiTypeStr)
if depth > 64:
@@ -439,8 +439,8 @@ def _PyiCreturnArgs(decorators: list[ast.AST | t.CPtr] | t.CPtr) -> list[ast.AST
"""在装饰器列表里找 @c.CReturn(...),返回其实参列表;未找到返回 None"""
if decorators is None:
return None
dn: t.CSizeT = len(decorators)
di: t.CSizeT = 0
dn: sizet = len(decorators)
di: sizet = 0
while di < dn:
dnode: ast.AST | t.CPtr = decorators.get(di)
di += 1
@@ -460,15 +460,15 @@ def _PyiCreturnArgs(decorators: list[ast.AST | t.CPtr] | t.CPtr) -> list[ast.AST
#
# 格式: def name(param: Type, ...) -> ReturnType: pass
# ============================================================
def _PyiFunction(buf: bytes, buf_size: t.CSizeT, pos: t.CSizeT,
def _PyiFunction(buf: bytes, buf_size: sizet, pos: sizet,
fn: ast.FunctionDef | t.CPtr,
indent_level: int, class_name: str) -> t.CSizeT:
indent_level: int, class_name: str) -> sizet:
"""生成函数签名到 buf,返回新的 pos"""
# 装饰器
if fn.decorator_list is not None:
fn_decorator_list: list[ast.AST | t.CPtr] | t.CPtr = fn.decorator_list
dn: t.CSizeT = len(fn_decorator_list)
di: t.CSizeT = 0
dn: sizet = len(fn_decorator_list)
di: sizet = 0
while di < dn:
dec: ast.AST | t.CPtr = fn_decorator_list.get(di)
if dec is not None:
@@ -493,7 +493,7 @@ def _PyiFunction(buf: bytes, buf_size: t.CSizeT, pos: t.CSizeT,
# 位置参数
if args.args is not None:
args_args: list[ast.AST | t.CPtr] | t.CPtr = args.args
an: t.CSizeT = len(args_args)
an: sizet = len(args_args)
# 默认值右对齐到 args 尾部:defaults[i] 对应 args[an - dn + i]。
# vpi stub 必须输出 '= <default>',否则 VpiReader 解析后默认参数
# 表无条目,跨模块缺参调用(如 depth=0)读到栈垃圾。
@@ -501,10 +501,10 @@ def _PyiFunction(buf: bytes, buf_size: t.CSizeT, pos: t.CSizeT,
# 接收者的 .get 会被 TPC/TPV 误分派——预声明 + 重赋值会解析成
# list[int].get 返回 i32 截断指针崩溃;内联声明走 list[ast.ASTptr].get)。
arg_defaults: list[ast.AST | t.CPtr] | t.CPtr = args.defaults
dn: t.CSizeT = 0
dn: sizet = 0
if arg_defaults is not None:
dn = len(arg_defaults)
ai: t.CSizeT = 0
ai: sizet = 0
while ai < an:
if first == 0:
pos = _PyiEmit(buf, buf_size, pos, ", ")
@@ -516,7 +516,7 @@ def _PyiFunction(buf: bytes, buf_size: t.CSizeT, pos: t.CSizeT,
pos = _PyiEmit(buf, buf_size, pos, ": ")
pos = _PyiTypeStr(buf, buf_size, pos, ag.annotation)
if arg_defaults is not None and an - dn <= ai:
di: t.CSizeT = ai - (an - dn)
di: sizet = ai - (an - dn)
dnode: ast.AST | t.CPtr = arg_defaults.get(di)
if dnode is not None:
pos = _PyiEmit(buf, buf_size, pos, " = ")
@@ -553,10 +553,10 @@ def _PyiFunction(buf: bytes, buf_size: t.CSizeT, pos: t.CSizeT,
# 无 `->` 注解但带 @c.CReturn(...):合成 " -> tuple[a, b, c]"(N11)
cre_args: list[ast.AST | t.CPtr] | t.CPtr = _PyiCreturnArgs(fn.decorator_list)
if cre_args is not None:
cre_n: t.CSizeT = len(cre_args)
cre_n: sizet = len(cre_args)
if cre_n > 0:
pos = _PyiEmit(buf, buf_size, pos, " -> tuple[")
cre_i: t.CSizeT = 0
cre_i: sizet = 0
while cre_i < cre_n:
if cre_i > 0:
pos = _PyiEmit(buf, buf_size, pos, ", ")
@@ -576,14 +576,14 @@ def _PyiFunction(buf: bytes, buf_size: t.CSizeT, pos: t.CSizeT,
# field: Type
# def method(self: Name, ...) -> RetType: pass
# ============================================================
def _PyiClass(buf: bytes, buf_size: t.CSizeT, pos: t.CSizeT,
cls: ast.ClassDef | t.CPtr, indent_level: int) -> t.CSizeT:
def _PyiClass(buf: bytes, buf_size: sizet, pos: sizet,
cls: ast.ClassDef | t.CPtr, indent_level: int) -> sizet:
"""生成类定义到 buf,返回新的 pos"""
# 装饰器
if cls.decorator_list is not None:
cls_decorator_list: list[ast.AST | t.CPtr] | t.CPtr = cls.decorator_list
dcn: t.CSizeT = len(cls_decorator_list)
dci: t.CSizeT = 0
dcn: sizet = len(cls_decorator_list)
dci: sizet = 0
while dci < dcn:
ddec: ast.AST | t.CPtr = cls_decorator_list.get(dci)
if ddec is not None:
@@ -601,10 +601,10 @@ def _PyiClass(buf: bytes, buf_size: t.CSizeT, pos: t.CSizeT,
# PEP 695 类型参数 (class Foo[T]:)
if cls.type_params is not None:
cls_type_params: list[ast.AST | t.CPtr] | t.CPtr = cls.type_params
tpn: t.CSizeT = len(cls_type_params)
tpn: sizet = len(cls_type_params)
if tpn > 0:
pos = _PyiEmit(buf, buf_size, pos, "[")
tpi: t.CSizeT = 0
tpi: sizet = 0
while tpi < tpn:
if tpi > 0:
pos = _PyiEmit(buf, buf_size, pos, ", ")
@@ -617,10 +617,10 @@ def _PyiClass(buf: bytes, buf_size: t.CSizeT, pos: t.CSizeT,
# 基类
if cls.bases is not None:
cls_bases: list[ast.AST | t.CPtr] | t.CPtr = cls.bases
bn: t.CSizeT = len(cls_bases)
bn: sizet = len(cls_bases)
if bn > 0:
pos = _PyiEmit(buf, buf_size, pos, "(")
bi: t.CSizeT = 0
bi: sizet = 0
while bi < bn:
if bi > 0:
pos = _PyiEmit(buf, buf_size, pos, ", ")
@@ -636,8 +636,8 @@ def _PyiClass(buf: bytes, buf_size: t.CSizeT, pos: t.CSizeT,
if cls.children is not None:
cls_children: list[ast.AST | t.CPtr] | t.CPtr = cls.children
cn: t.CSizeT = len(cls_children)
ci: t.CSizeT = 0
cn: sizet = len(cls_children)
ci: sizet = 0
while ci < cn:
stmt: ast.AST | t.CPtr = cls_children.get(ci)
if stmt is not None:
@@ -650,8 +650,8 @@ def _PyiClass(buf: bytes, buf_size: t.CSizeT, pos: t.CSizeT,
if mfn.name is not None and string.strcmp(mfn.name, "__init__") == 0:
if mfn.children is not None:
mfn_children: list[ast.AST | t.CPtr] | t.CPtr = mfn.children
icn: t.CSizeT = len(mfn_children)
ici: t.CSizeT = 0
icn: sizet = len(mfn_children)
ici: sizet = 0
while ici < icn:
ibody: ast.AST | t.CPtr = mfn_children.get(ici)
if ibody is not None and ibody.kind() == ast.ASTKind.AnnAssign:
@@ -721,12 +721,12 @@ def _PyiClass(buf: bytes, buf_size: t.CSizeT, pos: t.CSizeT,
# ============================================================
def _GeneratePyiFromAst(mb: memhub.MemBuddy | t.CPtr, tree: ast.AST | t.CPtr,
rel_path: str, buf: bytes,
buf_size: t.CSizeT) -> t.CSizeT:
buf_size: sizet) -> sizet:
"""从 AST 生成 .vpi 存根文件内容到 buf"""
if tree is None or buf is None or buf_size == 0:
return 0
pos: t.CSizeT = 0
pos: sizet = 0
# 预处理:按声明顺序注册本文件 CDefine 到 _g_pyi 缓存(供 BinOp 求值)
# vpi 生成(Phase1 L1614)早于翻译阶段的 CDefine 注册(L1629+),直接查
@@ -737,7 +737,7 @@ def _GeneratePyiFromAst(mb: memhub.MemBuddy | t.CPtr, tree: ast.AST | t.CPtr,
global _g_pyi_cdef_names, _g_pyi_cdef_vals, _g_pyi_cdef_count
if tree.children is not None:
pre_children: list[ast.AST | t.CPtr] | t.CPtr = tree.children
pcn: t.CSizeT = len(pre_children)
pcn: sizet = len(pre_children)
# 第一遍:数本文件 t.CDefine 声明数(C 数组需先定长分配)
_g_pyi_cdef_count = 0
for pci0 in range(pcn):
@@ -752,11 +752,11 @@ def _GeneratePyiFromAst(mb: memhub.MemBuddy | t.CPtr, tree: ast.AST | t.CPtr,
if ann_pc0.attr is not None and string.strcmp(ann_pc0.attr, "CDefine") == 0:
_g_pyi_cdef_count += 1
if _g_pyi_cdef_count > 0:
_g_pyi_cdef_names = (str | t.CPtr)(mb.alloc(t.CSizeT(_g_pyi_cdef_count) * 8))
_g_pyi_cdef_vals = (t.CInt64T | t.CPtr)(mb.alloc(t.CSizeT(_g_pyi_cdef_count) * 8))
_g_pyi_cdef_names = (str | t.CPtr)(mb.alloc(sizet(_g_pyi_cdef_count) * 8))
_g_pyi_cdef_vals = (int64 | t.CPtr)(mb.alloc(sizet(_g_pyi_cdef_count) * 8))
# 第二遍:按声明顺序注册(BinOp 内 Name 引用依赖先前注册项)
pci: t.CSizeT = 0
cdi: t.CInt = 0
pci: sizet = 0
cdi: int = 0
for pci in range(pcn):
stmt_pc: ast.AST | t.CPtr = pre_children.get(pci)
if stmt_pc is not None and stmt_pc.kind() == ast.ASTKind.AnnAssign:
@@ -768,7 +768,7 @@ def _GeneratePyiFromAst(mb: memhub.MemBuddy | t.CPtr, tree: ast.AST | t.CPtr,
ann_pc: ast.Attribute | t.CPtr = (ast.Attribute | t.CPtr)(aa_pc.annotation)
if ann_pc.attr is not None and string.strcmp(ann_pc.attr, "CDefine") == 0:
if _g_pyi_cdef_names is not None and _g_pyi_cdef_vals is not None:
slot_pc: str | t.CPtr = t.CPtr(t.CUInt64T(_g_pyi_cdef_names) + cdi * 8)
slot_pc: str | t.CPtr = t.CPtr(uint64(_g_pyi_cdef_names) + cdi * 8)
slot_pc[0] = tgt_pc.id
_g_pyi_cdef_vals[cdi] = _eval_cdefine_value_cache(aa_pc.value)
cdi += 1
@@ -782,7 +782,7 @@ def _GeneratePyiFromAst(mb: memhub.MemBuddy | t.CPtr, tree: ast.AST | t.CPtr,
return pos
tree_children: list[ast.AST | t.CPtr] | t.CPtr = tree.children
n: t.CSizeT = len(tree_children)
n: sizet = len(tree_children)
# 第一遍扫描:检测 import t/c
has_import_t: int = 0
@@ -793,7 +793,7 @@ def _GeneratePyiFromAst(mb: memhub.MemBuddy | t.CPtr, tree: ast.AST | t.CPtr,
imp: ast.Import | t.CPtr = (ast.Import | t.CPtr)(stmt)
if imp.names is not None:
imp_names: list[ast.AST | t.CPtr] | t.CPtr = imp.names
an: t.CSizeT = len(imp_names)
an: sizet = len(imp_names)
for ai in range(an):
al: ast.Alias | t.CPtr = (ast.Alias | t.CPtr)(imp_names.get(ai))
if al is not None and al.name is not None:
@@ -824,8 +824,8 @@ def _GeneratePyiFromAst(mb: memhub.MemBuddy | t.CPtr, tree: ast.AST | t.CPtr,
pos = _PyiEmit(buf, buf_size, pos, "import ")
if imp2.names is not None:
imp2_names: list[ast.AST | t.CPtr] | t.CPtr = imp2.names
an2: t.CSizeT = len(imp2_names)
ai2: t.CSizeT = 0
an2: sizet = len(imp2_names)
ai2: sizet = 0
while ai2 < an2:
if ai2 > 0:
pos = _PyiEmit(buf, buf_size, pos, ", ")
@@ -851,8 +851,8 @@ def _GeneratePyiFromAst(mb: memhub.MemBuddy | t.CPtr, tree: ast.AST | t.CPtr,
pos = _PyiEmit(buf, buf_size, pos, " import ")
if ifr.names is not None:
ifr_names: list[ast.AST | t.CPtr] | t.CPtr = ifr.names
an3: t.CSizeT = len(ifr_names)
ai3: t.CSizeT = 0
an3: sizet = len(ifr_names)
ai3: sizet = 0
while ai3 < an3:
if ai3 > 0:
pos = _PyiEmit(buf, buf_size, pos, ", ")
@@ -885,7 +885,7 @@ def _GeneratePyiFromAst(mb: memhub.MemBuddy | t.CPtr, tree: ast.AST | t.CPtr,
pos = _PyiEmit(buf, buf_size, pos, ": ")
pos = _PyiTypeStr(buf, buf_size, pos, aa.annotation)
# 如果有值(如 CDefine 常量),输出 = value
# CTypedef 特殊处理:值是类型表达式(如 VOIDPTR / t.CVoid | t.CPtr),
# CTypedef 特殊处理:值是类型表达式(如 VOIDPTR / t.CPtr),
# 不是整数,用 _PyiTypeStr 输出类型字符串
is_ctypedef_ann: int = 0
if aa.annotation is not None and aa.annotation.kind() == ast.ASTKind.Attribute:
@@ -940,7 +940,7 @@ def _GeneratePyiFromAst(mb: memhub.MemBuddy | t.CPtr, tree: ast.AST | t.CPtr,
and uop_cv.operand.kind() == ast.ASTKind.Constant:
uop_const: ast.Constant | t.CPtr = (ast.Constant | t.CPtr)(uop_cv.operand)
if uop_const.const_kind == ast.CONST_INT and num_buf_u is not None:
neg_val: t.CInt64T = -uop_const.int_val
neg_val: int64 = -uop_const.int_val
viperlib.snprintf(num_buf_u, 32, " = %lld", neg_val)
pos = _PyiEmit(buf, buf_size, pos, num_buf_u)
elif aa.value is not None and aa.value.kind() == ast.ASTKind.Call:
@@ -974,7 +974,7 @@ def _GeneratePyiFromAst(mb: memhub.MemBuddy | t.CPtr, tree: ast.AST | t.CPtr,
and uop_ca.operand.kind() == ast.ASTKind.Constant:
uoc: ast.Constant | t.CPtr = (ast.Constant | t.CPtr)(uop_ca.operand)
if uoc.const_kind == ast.CONST_INT and num_buf_cu is not None:
neg_c_val: t.CInt64T = -uoc.int_val
neg_c_val: int64 = -uoc.int_val
viperlib.snprintf(num_buf_cu, 32, " = %lld", neg_c_val)
pos = _PyiEmit(buf, buf_size, pos, num_buf_cu)
elif uoc.const_kind == ast.CONST_FLOAT:
@@ -988,7 +988,7 @@ def _GeneratePyiFromAst(mb: memhub.MemBuddy | t.CPtr, tree: ast.AST | t.CPtr,
elif arg_kind == ast.ASTKind.BinOp:
# Call 内部的 BinOp(如 t.CUnsignedLong(A | B))
# 递归计算 BinOp 值
binop_val_bo: t.CInt64T = _eval_binop_int(first_arg)
binop_val_bo: int64 = _eval_binop_int(first_arg)
num_buf_bo: bytes = mb.alloc(32)
if (binop_val_bo != 0 or _eval_binop_valid(first_arg) != 0) \
and num_buf_bo is not None:
@@ -997,7 +997,7 @@ def _GeneratePyiFromAst(mb: memhub.MemBuddy | t.CPtr, tree: ast.AST | t.CPtr,
elif aa.value is not None and aa.value.kind() == ast.ASTKind.BinOp:
# 处理 BinOp 常量(如 FOREGROUND_COMBO = FOREGROUND_RED | FOREGROUND_GREEN)
# 递归计算 BinOp 值并输出
binop_val_av: t.CInt64T = _eval_binop_int(aa.value)
binop_val_av: int64 = _eval_binop_int(aa.value)
if binop_val_av != 0 or _eval_binop_valid(aa.value) != 0:
num_buf_b: bytes = mb.alloc(32)
if num_buf_b is not None:
@@ -1017,7 +1017,7 @@ def _GeneratePyiFromAst(mb: memhub.MemBuddy | t.CPtr, tree: ast.AST | t.CPtr,
asg: ast.Assign | t.CPtr = (ast.Assign | t.CPtr)(stmt)
if asg.targets is not None and asg.value is not None:
asg_targets: list[ast.AST | t.CPtr] | t.CPtr = asg.targets
atn: t.CSizeT = len(asg_targets)
atn: sizet = len(asg_targets)
if atn == 1:
atg: ast.AST | t.CPtr = asg_targets.get(0)
if atg is not None and atg.kind() == ast.ASTKind.Name:
@@ -1041,7 +1041,7 @@ def _GeneratePyiFromAst(mb: memhub.MemBuddy | t.CPtr, tree: ast.AST | t.CPtr,
pos = _PyiEmit(buf, buf_size, pos, agn.id)
pos = _PyiEmit(buf, buf_size, pos, ": ")
if inferred == 1:
pos = _PyiEmit(buf, buf_size, pos, "t.CInt")
pos = _PyiEmit(buf, buf_size, pos, "int")
elif inferred == 2:
pos = _PyiEmit(buf, buf_size, pos, "t.CDouble")
elif inferred == 3:
+155 -155
View File
@@ -85,26 +85,26 @@ def _cache_vpi_return_annots_text(vpi_buf: bytes, src_sha1: str) -> int:
string.memset(_g_vpi_ret_keys, 0, VPI_RET_MAX * VPI_KEY_LEN)
string.memset(_g_vpi_ret_strs, 0, VPI_RET_MAX * VPI_RET_LEN)
_g_vpi_ret_cap = VPI_RET_MAX
sha1_len: t.CSizeT = string.strlen(src_sha1)
buf_len: t.CSizeT = string.strlen(vpi_buf)
sha1_len: sizet = string.strlen(src_sha1)
buf_len: sizet = string.strlen(vpi_buf)
cur_cls: bytes = None
pos: t.CSizeT = 0
pos: sizet = 0
line_no: int = 0
while pos < buf_len:
ls: t.CSizeT = pos
le: t.CSizeT = pos
ls: sizet = pos
le: sizet = pos
while le < buf_len and vpi_buf[le] != '\n':
le += 1
line_len: t.CSizeT = le - ls
line_len: sizet = le - ls
# 跳过前导空格,检查 class/def
i: t.CSizeT = ls
i: sizet = ls
while i < le and vpi_buf[i] == ' ':
i += 1
if i < le:
# class X:
if line_len >= 6 and string.strncmp(vpi_buf + i, "class ", 6) == 0:
cstart: t.CSizeT = i + 6
cend: t.CSizeT = cstart
cstart: sizet = i + 6
cend: sizet = cstart
# 类名提取:到 ':' / ' ' / '(' 前停止(继承基类括号不入类名,
# 如 "class MemBuddy(MemManager):" → "MemBuddy",与调用方短名一致)
while cend < le and vpi_buf[cend] != ':' and vpi_buf[cend] != ' ' and vpi_buf[cend] != '(':
@@ -123,14 +123,14 @@ def _cache_vpi_return_annots_text(vpi_buf: bytes, src_sha1: str) -> int:
if i == ls and cur_cls is not None:
stdlib.free(cur_cls)
cur_cls = None
dstart: t.CSizeT = i + 4
dend: t.CSizeT = dstart
dstart: sizet = i + 4
dend: sizet = dstart
while dend < le and vpi_buf[dend] != '(':
dend += 1
# 方法名 = [dstart, dend)
# 找 "->"
rpos: t.CSizeT = dstart
arrow_pos: t.CSizeT = le
rpos: sizet = dstart
arrow_pos: sizet = le
while rpos < le - 1:
if vpi_buf[rpos] == '-' and vpi_buf[rpos + 1] == '>':
arrow_pos = rpos
@@ -141,13 +141,13 @@ def _cache_vpi_return_annots_text(vpi_buf: bytes, src_sha1: str) -> int:
# (与 HandlesType.infer_return_type 无 return 语句时的默认行为一致,
# 如 json._append_child / __setitem__ 无注解实际编译为 i32)。
ret_src: str = None
rtype_len: t.CSizeT = 0
rtype_len: sizet = 0
if arrow_pos < le:
# 返回类型 = arrow_pos+2 跳过空格 到 ':' 前
rstart2: t.CSizeT = arrow_pos + 2
rstart2: sizet = arrow_pos + 2
while rstart2 < le and vpi_buf[rstart2] == ' ':
rstart2 += 1
rend2: t.CSizeT = rstart2
rend2: sizet = rstart2
while rend2 < le and vpi_buf[rend2] != ':':
rend2 += 1
if rend2 > rstart2:
@@ -159,11 +159,11 @@ def _cache_vpi_return_annots_text(vpi_buf: bytes, src_sha1: str) -> int:
ret_src = "i32"
if ret_src is not None:
# 构造 key 和 ret_str,存入缓存
mname_len: t.CSizeT = dend - dstart
cls_len2: t.CSizeT = 0
mname_len: sizet = dend - dstart
cls_len2: sizet = 0
if cur_cls is not None:
cls_len2 = string.strlen(cur_cls)
key_len: t.CSizeT = sha1_len + 1 + cls_len2 + 1 + mname_len
key_len: sizet = sha1_len + 1 + cls_len2 + 1 + mname_len
if key_len < VPI_KEY_LEN and rtype_len < VPI_RET_LEN:
# 方法名复制到临时缓冲(vpi_buf+dstart 非 null 结尾,不能直接 snprintf)
mname_buf: bytes = stdlib.malloc(mname_len + 1)
@@ -234,23 +234,23 @@ def _cache_vpi_param_annots_text(vpi_buf: bytes, src_sha1: str) -> int:
string.memset(_g_vpi_param_keys, 0, VPI_PARAM_MAX * VPI_PARAM_KEY_LEN)
string.memset(_g_vpi_param_strs, 0, VPI_PARAM_MAX * VPI_PARAM_LEN)
_g_vpi_param_cap = VPI_PARAM_MAX
sha1_len: t.CSizeT = string.strlen(src_sha1)
buf_len: t.CSizeT = string.strlen(vpi_buf)
sha1_len: sizet = string.strlen(src_sha1)
buf_len: sizet = string.strlen(vpi_buf)
cur_cls: bytes = None
pos: t.CSizeT = 0
pos: sizet = 0
while pos < buf_len:
ls: t.CSizeT = pos
le: t.CSizeT = pos
ls: sizet = pos
le: sizet = pos
while le < buf_len and vpi_buf[le] != '\n':
le += 1
line_len: t.CSizeT = le - ls
i: t.CSizeT = ls
line_len: sizet = le - ls
i: sizet = ls
while i < le and vpi_buf[i] == ' ':
i += 1
if i < le:
if line_len >= 6 and string.strncmp(vpi_buf + i, "class ", 6) == 0:
cstart: t.CSizeT = i + 6
cend: t.CSizeT = cstart
cstart: sizet = i + 6
cend: sizet = cstart
while cend < le and vpi_buf[cend] != ':' and vpi_buf[cend] != ' ' and vpi_buf[cend] != '(':
cend += 1
if cend > cstart:
@@ -265,19 +265,19 @@ def _cache_vpi_param_annots_text(vpi_buf: bytes, src_sha1: str) -> int:
if i == ls and cur_cls is not None:
stdlib.free(cur_cls)
cur_cls = None
dstart: t.CSizeT = i + 4
dend: t.CSizeT = dstart
dstart: sizet = i + 4
dend: sizet = dstart
while dend < le and vpi_buf[dend] != '(':
dend += 1
if dend >= le:
pos = le + 1
continue
# 找匹配的 ')'(深度感知:注解可含 t.CArray[...] / tuple[...] 括号)
p: t.CSizeT = dend + 1
p: sizet = dend + 1
pdepth: int = 0
pend: t.CSizeT = dend
pend: sizet = dend
while p < le:
ch_p: t.CChar = vpi_buf[p]
ch_p: char = vpi_buf[p]
if ch_p == '(' or ch_p == '[' or ch_p == '{':
pdepth += 1
elif ch_p == ')' or ch_p == ']' or ch_p == '}':
@@ -292,18 +292,18 @@ def _cache_vpi_param_annots_text(vpi_buf: bytes, src_sha1: str) -> int:
pos = le + 1
continue
plist[0] = '\0'
plist_pos: t.CSizeT = 0
plist_pos: sizet = 0
seg_written: int = 0
seg_cur: t.CSizeT = dend + 1
seg_cur: sizet = dend + 1
while seg_cur < pend:
while seg_cur < pend and (vpi_buf[seg_cur] == ' ' or vpi_buf[seg_cur] == ','):
seg_cur += 1
if seg_cur >= pend:
break
s_start: t.CSizeT = seg_cur
s_start: sizet = seg_cur
sd: int = 0
while seg_cur < pend:
ch_s: t.CChar = vpi_buf[seg_cur]
ch_s: char = vpi_buf[seg_cur]
if ch_s == '(' or ch_s == '[' or ch_s == '{':
sd += 1
elif ch_s == ')' or ch_s == ']' or ch_s == '}':
@@ -311,9 +311,9 @@ def _cache_vpi_param_annots_text(vpi_buf: bytes, src_sha1: str) -> int:
elif ch_s == ',' and sd == 0:
break
seg_cur += 1
s_end: t.CSizeT = seg_cur
s_end: sizet = seg_cur
# 跳过 * / **(vararg/kwarg 不入 args 列表)
st: t.CSizeT = s_start
st: sizet = s_start
while st < s_end and vpi_buf[st] == ' ':
st += 1
if st < s_end and vpi_buf[st] == '*':
@@ -321,10 +321,10 @@ def _cache_vpi_param_annots_text(vpi_buf: bytes, src_sha1: str) -> int:
seg_cur += 1
continue
# 截断默认值(顶层 '=',如 ": str = None")
e_pos: t.CSizeT = st
e_pos: sizet = st
ed: int = 0
while e_pos < s_end:
ch_e: t.CChar = vpi_buf[e_pos]
ch_e: char = vpi_buf[e_pos]
if ch_e == '(' or ch_e == '[' or ch_e == '{':
ed += 1
elif ch_e == ')' or ch_e == ']' or ch_e == '}':
@@ -334,11 +334,11 @@ def _cache_vpi_param_annots_text(vpi_buf: bytes, src_sha1: str) -> int:
e_pos += 1
s_end = e_pos
# 提取注解:顶层 ':' 之后(无 ':' → 空串,如 self)
c_pos: t.CSizeT = st
c_pos: sizet = st
cd2: int = 0
annot_start: t.CSizeT = s_end
annot_start: sizet = s_end
while c_pos < s_end:
ch_c: t.CChar = vpi_buf[c_pos]
ch_c: char = vpi_buf[c_pos]
if ch_c == '(' or ch_c == '[' or ch_c == '{':
cd2 += 1
elif ch_c == ')' or ch_c == ']' or ch_c == '}':
@@ -347,17 +347,17 @@ def _cache_vpi_param_annots_text(vpi_buf: bytes, src_sha1: str) -> int:
annot_start = c_pos + 1
break
c_pos += 1
a_start: t.CSizeT = annot_start
a_start: sizet = annot_start
while a_start < s_end and vpi_buf[a_start] == ' ':
a_start += 1
a_end: t.CSizeT = s_end
a_end: sizet = s_end
while a_end > a_start and vpi_buf[a_end - 1] == ' ':
a_end -= 1
if plist_pos + (a_end - a_start) + 1 < VPI_PARAM_LEN:
if seg_written > 0:
plist[plist_pos] = '@'
plist_pos += 1
ai2: t.CSizeT
ai2: sizet
for ai2 in range(a_end - a_start):
plist[plist_pos] = vpi_buf[a_start + ai2]
plist_pos += 1
@@ -367,11 +367,11 @@ def _cache_vpi_param_annots_text(vpi_buf: bytes, src_sha1: str) -> int:
seg_cur += 1
# 存入缓存(key = sha1.class.method / sha1.method,去重)
if plist_pos > 0 and plist[0] != '\0':
mname_len: t.CSizeT = dend - dstart
cls_len2: t.CSizeT = 0
mname_len: sizet = dend - dstart
cls_len2: sizet = 0
if cur_cls is not None:
cls_len2 = string.strlen(cur_cls)
key_len: t.CSizeT = sha1_len + 1 + cls_len2 + 1 + mname_len
key_len: sizet = sha1_len + 1 + cls_len2 + 1 + mname_len
if key_len < VPI_PARAM_KEY_LEN:
mname_buf: bytes = stdlib.malloc(mname_len + 1)
if mname_buf is not None:
@@ -437,12 +437,12 @@ def _lookup_vpi_param_annots(src_sha1: str, cls_name: str, method_name: str) ->
"""查参数注解缓存;返回注解串('@' 分隔,含首参空串占位)或 None"""
if src_sha1 is None or method_name is None or _g_vpi_param_keys is None:
return None
sha1_len: t.CSizeT = string.strlen(src_sha1)
mlen: t.CSizeT = string.strlen(method_name)
clen: t.CSizeT = 0
sha1_len: sizet = string.strlen(src_sha1)
mlen: sizet = string.strlen(method_name)
clen: sizet = 0
if cls_name is not None:
clen = string.strlen(cls_name)
key_len: t.CSizeT = sha1_len + clen + mlen + 2
key_len: sizet = sha1_len + clen + mlen + 2
if key_len >= VPI_PARAM_KEY_LEN:
return None
key_buf: bytes = stdlib.malloc(key_len + 1)
@@ -486,7 +486,7 @@ def _repair_declare_params_from_text(pool: memhub.MemBuddy | t.CPtr,
return param_count
# 统计文本参数数('@' 分隔;段数 = 分隔符数 + 1,含首参)
pa_count: int = 1
pi2: t.CSizeT = 0
pi2: sizet = 0
while prm_annots[pi2] != '\0':
if prm_annots[pi2] == '@':
pa_count += 1
@@ -495,12 +495,12 @@ def _repair_declare_params_from_text(pool: memhub.MemBuddy | t.CPtr,
return param_count
# 补全缺失参数:段索引 >= param_count 的段即缺失参数位置
seg_idx: int = 0
seg_start2: t.CSizeT = 0
cur2: t.CSizeT = 0
seg_start2: sizet = 0
cur2: sizet = 0
while prm_annots[cur2] != '\0':
while prm_annots[cur2] != '\0' and prm_annots[cur2] != '@':
cur2 += 1
seg_len2: t.CSizeT = cur2 - seg_start2
seg_len2: sizet = cur2 - seg_start2
if prm_annots[cur2] == '@':
cur2 += 1
if seg_idx >= param_count:
@@ -526,7 +526,7 @@ def _repair_declare_params_from_text(pool: memhub.MemBuddy | t.CPtr,
#
# 返回类型已用字符串注解缓存解析(绕开 vpi tree 深层节点 kind() 损坏,见
# _inject_method_declare L1673-1675 注释);参数此前仍走 AST
# resolve_annotation_type,同样会得垃圾类型(如 t.CSizeT → i32),跨模块
# resolve_annotation_type,同样会得垃圾类型(如 sizet → i32),跨模块
# declare 参数类型错 → 调用侧 trunc i64→i32 传参、callee 按 i64 读栈残留
# 垃圾高位 → can=巨值读未写槽位崩溃(SlotsBugTest 根因)。
# 此处与返回类型同源:从 @-joined 注解串取第 seg_idx 段(0=self 空段),
@@ -545,7 +545,7 @@ def _resolve_vpi_param_annot_seg(pool: memhub.MemBuddy | t.CPtr,
prm_annots_p: str = _lookup_vpi_param_annots(src_sha1, cls_name, method_name)
if prm_annots_p is None or prm_annots_p[0] == '\0':
return None
cur_p: t.CSizeT = 0
cur_p: sizet = 0
cur_seg_p: int = 0
while cur_seg_p < seg_idx and prm_annots_p[cur_p] != '\0':
while prm_annots_p[cur_p] != '\0' and prm_annots_p[cur_p] != '@':
@@ -553,8 +553,8 @@ def _resolve_vpi_param_annot_seg(pool: memhub.MemBuddy | t.CPtr,
if prm_annots_p[cur_p] == '@':
cur_p += 1
cur_seg_p += 1
seg_start_p: t.CSizeT = cur_p
seg_len_p: t.CSizeT = 0
seg_start_p: sizet = cur_p
seg_len_p: sizet = 0
while prm_annots_p[seg_start_p + seg_len_p] != '\0' \
and prm_annots_p[seg_start_p + seg_len_p] != '@':
seg_len_p += 1
@@ -615,7 +615,7 @@ def _ensure_vpi_ret_annot_loaded(src_sha1: str, temp_dir: str) -> int:
"""按需加载模块 vpi stub 的返回注解缓存,返回 1=已就绪 / 0=失败"""
if src_sha1 is None or temp_dir is None:
return 0
sha1_len: t.CSizeT = string.strlen(src_sha1)
sha1_len: sizet = string.strlen(src_sha1)
if sha1_len < 2:
return 0
# 该模块已有缓存条目 → 跳过(幂等)
@@ -626,8 +626,8 @@ def _ensure_vpi_ret_annot_loaded(src_sha1: str, temp_dir: str) -> int:
if string.strncmp(pre_key, src_sha1, sha1_len) == 0 and pre_key[sha1_len] == '.':
return 1
# 构造路径 {temp_dir}/{sha1[0:2]}/{sha1}.vpi(逐字符拼接,避免 %c 格式化问题)
td_len: t.CSizeT = string.strlen(temp_dir)
path_len: t.CSizeT = td_len + sha1_len + 12
td_len: sizet = string.strlen(temp_dir)
path_len: sizet = td_len + sha1_len + 12
vpi_path: bytes = stdlib.malloc(path_len)
if vpi_path is None:
return 0
@@ -673,7 +673,7 @@ def _ensure_vpi_param_annot_loaded(src_sha1: str, temp_dir: str) -> int:
"""按需加载模块 vpi stub 的参数注解缓存,返回 1=已就绪 / 0=失败"""
if src_sha1 is None or temp_dir is None:
return 0
sha1_len: t.CSizeT = string.strlen(src_sha1)
sha1_len: sizet = string.strlen(src_sha1)
if sha1_len < 2:
return 0
# 该模块已有参数缓存条目 → 跳过(幂等)
@@ -684,8 +684,8 @@ def _ensure_vpi_param_annot_loaded(src_sha1: str, temp_dir: str) -> int:
if string.strncmp(pre_key, src_sha1, sha1_len) == 0 and pre_key[sha1_len] == '.':
return 1
# 构造路径 {temp_dir}/{sha1[0:2]}/{sha1}.vpi(逐字符拼接,避免 %c 格式化问题)
td_len: t.CSizeT = string.strlen(temp_dir)
path_len: t.CSizeT = td_len + sha1_len + 12
td_len: sizet = string.strlen(temp_dir)
path_len: sizet = td_len + sha1_len + 12
vpi_path: bytes = stdlib.malloc(path_len)
if vpi_path is None:
return 0
@@ -721,31 +721,31 @@ def _ensure_vpi_param_annot_loaded(src_sha1: str, temp_dir: str) -> int:
#
# 泛型模板返回注解(如 list[T].get -> T)中的类型参数名(T)
# 需替换为实际特化实参(AST|t.CPtr)后才能解析。仅替换前后
# 非字母数字下划线边界的独立 token(避免误替换 t.CSizeT 等)。
# 非字母数字下划线边界的独立 token(避免误替换 sizet 等)。
# 返回 stdlib 新分配字符串(调用者负责 free);失败返回 None。
# ============================================================
def _subst_template_arg(annot: str, tparam: str, targ: str) -> str:
"""替换 annot 中独立的 tparam token 为 targ"""
if annot is None or tparam is None or targ is None:
return None
alen: t.CSizeT = string.strlen(annot)
tplen: t.CSizeT = string.strlen(tparam)
tglen: t.CSizeT = string.strlen(targ)
alen: sizet = string.strlen(annot)
tplen: sizet = string.strlen(tparam)
tglen: sizet = string.strlen(targ)
if tplen == 0 or tplen > alen:
return annot
# 容量 = alen + tglen*8 + 16 只覆盖 ≤8 次替换;替换次数无上限时
# opos 会越界写穿 stdlib 堆(哨兵盲区 → CRT 堆损坏后任意 malloc/free
# 静默段错误、崩溃点漂移)。按最坏上界分配:每替换消耗 tplen 写 tglen,
# 最坏全部被替换 → alen + (alen/tplen)*tglen + 1。
max_sub: t.CSizeT = alen / tplen
max_sub: sizet = alen / tplen
if max_sub == 0:
max_sub = 1
out_size: t.CSizeT = alen + max_sub * tglen + 1
out_size: sizet = alen + max_sub * tglen + 1
out: bytes = stdlib.malloc(out_size)
if out is None:
return None
opos: t.CSizeT = 0
p: t.CSizeT = 0
opos: sizet = 0
p: sizet = 0
while p < alen:
# 防御:opos 超分配即 fail-fast 返回 None(绝不越界写)
if opos >= out_size:
@@ -790,12 +790,12 @@ def _lookup_vpi_ret_annot(src_sha1: str, cls_name: str, method_name: str) -> str
return None
if src_sha1 is None or method_name is None:
return None
sha1_len: t.CSizeT = string.strlen(src_sha1)
cl_len: t.CSizeT = 0
sha1_len: sizet = string.strlen(src_sha1)
cl_len: sizet = 0
if cls_name is not None:
cl_len = string.strlen(cls_name)
me_len: t.CSizeT = string.strlen(method_name)
key_len: t.CSizeT = sha1_len + 1 + cl_len + 1 + me_len
me_len: sizet = string.strlen(method_name)
key_len: sizet = sha1_len + 1 + cl_len + 1 + me_len
key_buf: bytes = stdlib.malloc(key_len + 1)
if key_buf is None:
return None
@@ -816,8 +816,8 @@ def _lookup_vpi_ret_annot(src_sha1: str, cls_name: str, method_name: str) -> str
if lbkt_v is not None:
rbkt_v: str = string.strrchr(cls_name, ']')
if rbkt_v is not None and rbkt_v > lbkt_v:
base_len_v: t.CSizeT = t.CSizeT(t.CUInt64T(lbkt_v) - t.CUInt64T(cls_name))
param_len_v: t.CSizeT = t.CSizeT(t.CUInt64T(rbkt_v) - t.CUInt64T(lbkt_v) - 1)
base_len_v: sizet = sizet(uint64(lbkt_v) - uint64(cls_name))
param_len_v: sizet = sizet(uint64(rbkt_v) - uint64(lbkt_v) - 1)
if base_len_v > 0 and param_len_v > 0:
base_v: str = stdlib.malloc(base_len_v + 1)
param_v: str = stdlib.malloc(param_len_v + 1)
@@ -836,8 +836,8 @@ def _lookup_vpi_ret_annot(src_sha1: str, cls_name: str, method_name: str) -> str
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: t.CSizeT = t.CSizeT(
t.CUInt64T(gklb) - t.CUInt64T(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)
@@ -958,8 +958,8 @@ def _resolve_single_vpi_type_str(pool: memhub.MemBuddy | t.CPtr,
# resolve 得到垃圾类型(如 Ptr(i8))。此处纯字符串解析避免该问题。
#
# 支持: "str"/"bytes" → i8*; "int" → i32; "bool" → i1;
# "t.CChar" 等 → map_t_type 映射;
# "X | t.CPtr" → Ptr(Struct X); "t.CVoid | t.CPtr" → i8*;
# "char" 等 → map_t_type 映射;
# "X | t.CPtr" → Ptr(Struct X); "t.CPtr" → i8*;
# "memhub.MemBuddy | t.CPtr" → Ptr(Struct MemBuddy)。
# ============================================================
def _resolve_vpi_ret_annot_str(pool: memhub.MemBuddy | t.CPtr,
@@ -975,7 +975,7 @@ def _resolve_vpi_ret_annot_str(pool: memhub.MemBuddy | t.CPtr,
# b2a_hqx -> tuple[str, t.CUnsignedShort] 之前按普通段解析失败 → 调用侧
# 返回类型退化 i8* → tuple 解包失效(hqx 段崩溃根因)。
if string.strncmp(ret_annot, "tuple[", 6) == 0:
inner_len_t: t.CSizeT = 0
inner_len_t: sizet = 0
while ret_annot[6 + inner_len_t] != ']' and ret_annot[6 + inner_len_t] != '\0':
inner_len_t += 1
if ret_annot[6 + inner_len_t] != ']' or inner_len_t == 0:
@@ -983,19 +983,19 @@ def _resolve_vpi_ret_annot_str(pool: memhub.MemBuddy | t.CPtr,
tup_head_t: llvmlite.ParamNode | t.CPtr = None
tup_tail_t: llvmlite.ParamNode | t.CPtr = None
tup_count_t: int = 0
p_t: t.CSizeT = 0
p_t: sizet = 0
while p_t < inner_len_t:
# 跳过前导空格/逗号
while p_t < inner_len_t and (ret_annot[6 + p_t] == ' ' or ret_annot[6 + p_t] == ','):
p_t += 1
seg_s_t: t.CSizeT = p_t
seg_s_t: sizet = p_t
while p_t < inner_len_t and ret_annot[6 + p_t] != ',':
p_t += 1
seg_e_t: t.CSizeT = p_t
seg_e_t: sizet = p_t
while seg_e_t > seg_s_t and ret_annot[6 + seg_e_t - 1] == ' ':
seg_e_t -= 1
if seg_e_t > seg_s_t:
seg_len_t: t.CSizeT = seg_e_t - seg_s_t
seg_len_t: sizet = seg_e_t - seg_s_t
seg_buf_t: bytes = stdlib.malloc(seg_len_t + 1)
if seg_buf_t is None:
return None
@@ -1022,26 +1022,26 @@ def _resolve_vpi_ret_annot_str(pool: memhub.MemBuddy | t.CPtr,
has_cvoid: int = 0
first_ty: llvmlite.LLVMType | t.CPtr = None
# 产生 first_ty 那一段文本的属性(供末尾 has_cptr 分支复刻定义侧规则,N12):
# first_qual=1 段是限定名(含 '.',如 t.CUInt64T / mod.Class)
# first_qual=1 段是限定名(含 '.',如 uint64 / mod.Class)
# first_wl =1 段是白名单裸标量名(int/char/str/bytes/bool/float/double)
first_qual: int = 0
first_wl: int = 0
buf_len: t.CSizeT = string.strlen(ret_annot)
pos: t.CSizeT = 0
buf_len: sizet = string.strlen(ret_annot)
pos: sizet = 0
while pos <= buf_len:
# 跳过前导空格
while pos < buf_len and ret_annot[pos] == ' ':
pos += 1
seg_start: t.CSizeT = pos
seg_start: sizet = pos
while pos < buf_len and ret_annot[pos] != '|':
pos += 1
seg_end: t.CSizeT = pos
seg_end: sizet = pos
# trim 尾随空格
while seg_end > seg_start and ret_annot[seg_end - 1] == ' ':
seg_end -= 1
if seg_end > seg_start:
seg_len2: t.CSizeT = seg_end - seg_start
seg_len2: sizet = seg_end - seg_start
seg_buf: bytes = stdlib.malloc(seg_len2 + 1)
if seg_buf is None:
break
@@ -1109,10 +1109,10 @@ def _resolve_vpi_ret_annot_str(pool: memhub.MemBuddy | t.CPtr,
# ============================================================
# .vpi 读取缓冲区大小(256KB,与 PYI_BUF_SIZE 一致)
VPI_READ_BUF_SIZE: t.CSizeT = 262144
VPI_READ_BUF_SIZE: sizet = 262144
# SHA1 字符串长度(16 hex 字符)
SHA1_LEN: t.CSizeT = 16
SHA1_LEN: sizet = 16
# ============================================================
@@ -1133,14 +1133,14 @@ def _extract_sha1_from_path(vpi_path: str) -> str:
if vpi_path is None:
return None
# 查找最后一个路径分隔符 / 或 \
total_len: t.CSizeT = string.strlen(vpi_path)
total_len: sizet = string.strlen(vpi_path)
if total_len < SHA1_LEN + 4: # 至少需要 "xxxx.vpi" 的长度
return None
# 从后向前查找最后一个 / 或 \
sep_pos: t.CSizeT = total_len
sep_pos: sizet = total_len
while sep_pos > 0:
sep_pos -= 1
ch: t.CChar = vpi_path[sep_pos]
ch: char = vpi_path[sep_pos]
if ch == '/' or ch == '\\':
sep_pos += 1
break
@@ -1167,13 +1167,13 @@ def _stub_add_imported(pool: memhub.MemBuddy | t.CPtr,
if name is None:
return cur
if cur is None:
nlen: t.CSizeT = string.strlen(name)
nlen: sizet = string.strlen(name)
buf: str = pool.alloc(nlen + 1)
if buf is not None:
string.strcpy(buf, name)
return buf
old_len: t.CSizeT = string.strlen(cur)
name_len: t.CSizeT = string.strlen(name)
old_len: sizet = string.strlen(cur)
name_len: sizet = string.strlen(name)
buf2: str = pool.alloc(old_len + 1 + name_len + 1)
if buf2 is not None:
string.strcpy(buf2, cur)
@@ -1199,8 +1199,8 @@ def _stub_add_from(pool: memhub.MemBuddy | t.CPtr,
viperlib.snprintf(entry, 256, "%s:%s", local, mod)
if cur is None:
return entry
old_len: t.CSizeT = string.strlen(cur)
entry_len: t.CSizeT = string.strlen(entry)
old_len: sizet = string.strlen(cur)
entry_len: sizet = string.strlen(entry)
buf: str = pool.alloc(old_len + 1 + entry_len + 1)
if buf is not None:
string.strcpy(buf, cur)
@@ -1281,18 +1281,18 @@ def _vpi_register_typedef_closure(pool: memhub.MemBuddy | t.CPtr,
return 0
if depth > 8:
return 0
td_len: t.CSizeT = string.strlen(temp_dir)
total_len: t.CSizeT = string.strlen(import_mods)
pos: t.CSizeT = 0
td_len: sizet = string.strlen(temp_dir)
total_len: sizet = string.strlen(import_mods)
pos: sizet = 0
while pos < total_len:
while pos < total_len and import_mods[pos] == ' ':
pos += 1
if pos >= total_len:
break
m_start: t.CSizeT = pos
m_start: sizet = pos
while pos < total_len and import_mods[pos] != ' ':
pos += 1
m_len: t.CSizeT = pos - m_start
m_len: sizet = pos - m_start
if m_len == 0:
continue
# t/c 内建库不编译,无 vpi stub
@@ -1311,7 +1311,7 @@ def _vpi_register_typedef_closure(pool: memhub.MemBuddy | t.CPtr,
continue
# 构造 {temp_dir}/{sha1[0:2]}/{sha1}.vpi(手写拼接,与
# _ensure_vpi_ret_annot_loaded 一致,避免引入 StubMergerCollect 环依赖)
path_len_r: t.CSizeT = td_len + 16 + 12
path_len_r: sizet = td_len + 16 + 12
vpi_path_r: bytes = stdlib.malloc(path_len_r)
if vpi_path_r is None:
continue
@@ -1346,13 +1346,13 @@ def _vpi_register_typedef_closure(pool: memhub.MemBuddy | t.CPtr,
tree_r: ast.AST | t.CPtr = ast.parse_tokens(pool, tokens_r)
if tree_r is not None and tree_r.children is not None:
ch_r: list[ast.AST | t.CPtr] | t.CPtr = tree_r.children
cn_r: t.CSizeT = len(ch_r)
cn_r: sizet = len(ch_r)
# 第一遍:收集子模块 imports(递归闭包)
sub_imports: bytes = stdlib.malloc(4096)
if sub_imports is not None:
sub_imports[0] = '\0'
sub_len: t.CSizeT = 0
ci_r: t.CSizeT
sub_len: sizet = 0
ci_r: sizet
for ci_r in range(cn_r):
child_r: ast.AST | t.CPtr = ch_r.get(ci_r)
if child_r is None:
@@ -1361,12 +1361,12 @@ def _vpi_register_typedef_closure(pool: memhub.MemBuddy | t.CPtr,
if kk_r == ast.ASTKind.Import:
imp_r: ast.Import | t.CPtr = (ast.Import | t.CPtr)(child_r)
if imp_r.names is not None:
in_n: t.CSizeT = len(imp_r.names)
ii_r: t.CSizeT
in_n: sizet = len(imp_r.names)
ii_r: sizet
for ii_r in range(in_n):
al_r: ast.Alias | t.CPtr = (ast.Alias | t.CPtr)(imp_r.names.get(ii_r))
if al_r is not None and al_r.name is not None:
il_r: t.CSizeT = string.strlen(al_r.name)
il_r: sizet = string.strlen(al_r.name)
if sub_len + il_r + 2 < 4096:
if sub_len > 0:
sub_imports[sub_len] = ' '
@@ -1377,7 +1377,7 @@ def _vpi_register_typedef_closure(pool: memhub.MemBuddy | t.CPtr,
elif kk_r == ast.ASTKind.ImportFrom:
ifr_r: ast.ImportFrom | t.CPtr = (ast.ImportFrom | t.CPtr)(child_r)
if ifr_r.module is not None:
ml_r: t.CSizeT = string.strlen(ifr_r.module)
ml_r: sizet = string.strlen(ifr_r.module)
if sub_len + ml_r + 2 < 4096:
if sub_len > 0:
sub_imports[sub_len] = ' '
@@ -1386,7 +1386,7 @@ def _vpi_register_typedef_closure(pool: memhub.MemBuddy | t.CPtr,
sub_len += ml_r
sub_imports[sub_len] = '\0'
# 第二遍:注册本模块 AnnAssign 的 CTypedef/CDefine
ci2_r: t.CSizeT
ci2_r: sizet
for ci2_r in range(cn_r):
child2_r: ast.AST | t.CPtr = ch_r.get(ci2_r)
if child2_r is None:
@@ -1409,7 +1409,7 @@ def _vpi_register_typedef_closure(pool: memhub.MemBuddy | t.CPtr,
if cn_v.const_kind == ast.CONST_FLOAT:
GenApi.register_cdefine_double(pool, cdef_t.id, cn_v.float_val)
elif cn_v.const_kind == ast.CONST_INT:
cdef_val: t.CInt64T = GenApi.extract_cdefine_int_value(aa_r.value)
cdef_val: int64 = GenApi.extract_cdefine_int_value(aa_r.value)
GenApi.register_cdefine_constant(pool, cdef_t.id, cdef_val)
# 递归处理子模块 imports(防环由 visited 标记保证)
if sub_imports[0] != '\0':
@@ -1517,7 +1517,7 @@ def _ParseVpiIntoModuleImpl(pool: memhub.MemBuddy | t.CPtr,
if src_sha1 is not None:
stdlib.free(src_sha1)
return 1
n: t.CSizeT = len(ch)
n: sizet = len(ch)
# 收集 stub 内被读模块自己的 import 语句,构建独立的注解解析上下文。
# .vpi stub 顶部含被读模块的 import(Converter 已写入,如 string.vp 的
@@ -1525,7 +1525,7 @@ def _ParseVpiIntoModuleImpl(pool: memhub.MemBuddy | t.CPtr,
# 解析注解——根治跨上下文误报(如 t.CArray[str] 需要 't' 已导入)。
stub_imported_modules: str = None
stub_from_imports: str = None
si: t.CSizeT
si: sizet
for si in range(n):
schild: ast.AST | t.CPtr = ch.get(si)
if schild is None:
@@ -1534,8 +1534,8 @@ def _ParseVpiIntoModuleImpl(pool: memhub.MemBuddy | t.CPtr,
if sk == ast.ASTKind.Import:
simp: ast.Import | t.CPtr = (ast.Import | t.CPtr)(schild)
if simp.names is not None:
sn_n: t.CSizeT = len(simp.names)
sni: t.CSizeT
sn_n: sizet = len(simp.names)
sni: sizet
for sni in range(sn_n):
sal: ast.Alias | t.CPtr = (ast.Alias | t.CPtr)(simp.names.get(sni))
if sal is not None and sal.name is not None:
@@ -1578,8 +1578,8 @@ def _ParseVpiIntoModuleImpl(pool: memhub.MemBuddy | t.CPtr,
else:
sub_sha1_rt = StubMergerStore.LookupSha1ByModName(sifr_mod)
if sifr.names is not None:
sifr_nn: t.CSizeT = len(sifr.names)
sifri: t.CSizeT
sifr_nn: sizet = len(sifr.names)
sifri: sizet
for sifri in range(sifr_nn):
sial: ast.Alias | t.CPtr = (ast.Alias | t.CPtr)(sifr.names.get(sifri))
if sial is not None and sial.name is not None:
@@ -1606,7 +1606,7 @@ def _ParseVpiIntoModuleImpl(pool: memhub.MemBuddy | t.CPtr,
if stub_from_imports is not None:
from_imports = stub_from_imports
# 把源模块自己加入 stub 注解上下文:stub 注解(如 __sha512 的 transform
# 参数 t.CArray[t.CUInt8T, SHA512_BLOCK_LEN])引用源模块自身的 CDefine,
# 参数 t.CArray[uint8, SHA512_BLOCK_LEN])引用源模块自身的 CDefine,
# 但 stub 的 import 只含被 import 的模块(t/c/string),不含自己。
# 不加则 _eval_const_int_expr 跨模块 CDefine 查找遍历不到源模块
# (imported_modules 无 __sha512)→ t.CArray count 报"必须是整数常量"。
@@ -1614,15 +1614,15 @@ def _ParseVpiIntoModuleImpl(pool: memhub.MemBuddy | t.CPtr,
if src_sha1 is not None:
stub_rel_src: str = StubMergerStore.LookupSha1RelPath(src_sha1)
if stub_rel_src is not None:
sr_len_src: t.CSizeT = string.strlen(stub_rel_src)
sr_len_src: sizet = string.strlen(stub_rel_src)
if sr_len_src > 3 and string.strncmp(stub_rel_src + sr_len_src - 3, ".vp", 3) == 0:
sr_len_src -= 3
if sr_len_src > 0:
src_mod_buf: str = stdlib.malloc(sr_len_src + 1)
if src_mod_buf is not None:
sri_src: t.CSizeT
sri_src: sizet
for sri_src in range(sr_len_src):
ch_src: t.CChar = stub_rel_src[sri_src]
ch_src: char = stub_rel_src[sri_src]
if ch_src == '/' or ch_src == '\\':
src_mod_buf[sri_src] = '.'
else:
@@ -1653,7 +1653,7 @@ def _ParseVpiIntoModuleImpl(pool: memhub.MemBuddy | t.CPtr,
# 在 `class devfs_directory` 之前),AnnAssign 全局变量解析裸类名时类
# 未注册 → CArray 元素解析失败 fatal(VKernel PhaseA 根因)。
# ============================================================
i0: t.CSizeT
i0: sizet
for i0 in range(n):
child0: ast.AST | t.CPtr = ch.get(i0)
if child0 is None:
@@ -1673,7 +1673,7 @@ def _ParseVpiIntoModuleImpl(pool: memhub.MemBuddy | t.CPtr,
src_sha1, imported_modules, from_imports)
cls_children0: list[ast.AST | t.CPtr] | t.CPtr = class_cd0.children
if cls_children0 is not None:
cn20: t.CSizeT = len(cls_children0)
cn20: sizet = len(cls_children0)
for ci20 in range(cn20):
m_child0: ast.AST | t.CPtr = cls_children0.get(ci20)
if m_child0 is None:
@@ -1687,7 +1687,7 @@ def _ParseVpiIntoModuleImpl(pool: memhub.MemBuddy | t.CPtr,
src_sha1, imported_modules, from_imports,
i32_ty, i8_ptr_ty, funcs_ptr, max_funcs)
i: t.CSizeT
i: sizet
for i in range(n):
child: ast.AST | t.CPtr = ch.get(i)
if child is None:
@@ -1746,7 +1746,7 @@ def _ParseVpiIntoModuleImpl(pool: memhub.MemBuddy | t.CPtr,
# 用 register_cdefine_double 注册(走整数提取会 fail-fast)
GenApi.register_cdefine_double(pool, cdef_tgt.id, cdef_float_val)
elif cdef_is_str == 0:
cdef_val: t.CInt64T = GenApi.extract_cdefine_int_value(aa.value)
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,
@@ -1845,7 +1845,7 @@ def _vpi_class_has_packed(decorator_list: list[ast.AST | t.CPtr] | t.CPtr) -> in
"""检查 vpi ClassDef 装饰器列表是否含 t.attr.packed"""
if decorator_list is None:
return 0
dn: t.CSizeT = len(decorator_list)
dn: sizet = len(decorator_list)
if dn == 0:
return 0
for di in range(dn):
@@ -1861,7 +1861,7 @@ def _vpi_class_has_packed(decorator_list: list[ast.AST | t.CPtr] | t.CPtr) -> in
continue
if cl.args is None:
continue
an: t.CSizeT = len(cl.args)
an: sizet = len(cl.args)
for ai in range(an):
ag: ast.AST | t.CPtr = cl.args.get(ai)
if ag is not None and _vpi_tattr_name(ag, "packed") != 0:
@@ -1907,8 +1907,8 @@ def _inject_class_struct_declare(pool: memhub.MemBuddy | t.CPtr,
GenApi.add_visible_struct(pool, cls_name)
return 1
# 2. 收集字段类型(AnnAssign 子节点,仿 ClassGenDef.translate_class_def)
field_names_buf: t.CSizeT | t.CPtr = pool.alloc(8 * GenTypes.FIELD_MAX)
field_types_buf: t.CSizeT | t.CPtr = pool.alloc(8 * GenTypes.FIELD_MAX)
field_names_buf: sizet | t.CPtr = pool.alloc(8 * GenTypes.FIELD_MAX)
field_types_buf: sizet | t.CPtr = pool.alloc(8 * GenTypes.FIELD_MAX)
if field_names_buf is None or field_types_buf is None:
return 0
string.memset(field_names_buf, 0, 8 * GenTypes.FIELD_MAX)
@@ -1916,7 +1916,7 @@ def _inject_class_struct_declare(pool: memhub.MemBuddy | t.CPtr,
field_count: int = 0
cls_children_c: list[ast.AST | t.CPtr] | t.CPtr = class_cd.children
if cls_children_c is not None:
cn_c: t.CSizeT = len(cls_children_c)
cn_c: sizet = len(cls_children_c)
for ci_c in range(cn_c):
m_child_c: ast.AST | t.CPtr = cls_children_c.get(ci_c)
if m_child_c is None:
@@ -1937,8 +1937,8 @@ def _inject_class_struct_declare(pool: memhub.MemBuddy | t.CPtr,
# 字段类型解析失败:不注册该类(留给源模块编译注册),不 fatal
return 0
if field_count < GenTypes.FIELD_MAX:
field_names_buf[field_count] = t.CSizeT(m_tgt_c.id)
field_types_buf[field_count] = t.CSizeT(field_ty_c)
field_names_buf[field_count] = sizet(m_tgt_c.id)
field_types_buf[field_count] = sizet(field_ty_c)
field_count += 1
# 3. vpi 存根不含类字段(只序列化 class 名 + def 签名,见 _cache_vpi_return_
# annots_text 的 class/def 行解析)→ field_count 恒为 0。
@@ -2092,7 +2092,7 @@ def _inject_global_variable_declare(pool: memhub.MemBuddy | t.CPtr,
if aa.annotation is not None:
is_gv_cexport = GenApi.has_decorator_marker(aa.annotation, "CExport")
if src_sha1 is not None and src_sha1[0] != '\0' and is_gv_cexport == 0:
ml_v: t.CSizeT = string.strlen(src_sha1) + 1 + string.strlen(gname_v) + 1
ml_v: sizet = string.strlen(src_sha1) + 1 + string.strlen(gname_v) + 1
gv_name_m = pool.alloc(ml_v)
if gv_name_m is not None:
viperlib.snprintf(gv_name_m, ml_v, "%s.%s", src_sha1, gname_v)
@@ -2255,7 +2255,7 @@ def _inject_function_declare(pool: memhub.MemBuddy | t.CPtr,
# 提取参数并添加到 declare
param_count: int = 0
fd_defaults: t.CVoid | t.CPtr = None
fd_defaults: t.CPtr = None
fd_default_count: int = 0
if fd.args is not None:
args_node: ast.Arguments | t.CPtr = (ast.Arguments | t.CPtr)(fd.args)
@@ -2269,9 +2269,9 @@ def _inject_function_declare(pool: memhub.MemBuddy | t.CPtr,
if param_count < 0 or param_count > 128:
stdio.printf(
"[VPIS] 参数数异常: 函数名=%s param_count=%d(fd.args=%llu,tree 可能被覆盖,终止)\n",
fd.name, param_count, t.CUInt64T(fd.args))
fd.name, param_count, uint64(fd.args))
stdlib.exit(1)
pi: t.CSizeT
pi: sizet
for pi in range(param_count):
ag: ast.Arg | t.CPtr = (ast.Arg | t.CPtr)(args_list.get(pi))
if ag is None:
@@ -2283,7 +2283,7 @@ def _inject_function_declare(pool: memhub.MemBuddy | t.CPtr,
param_ty: llvmlite.LLVMType | t.CPtr = i8_ptr_ty
# 优先用 vpi 文本注解缓存解析参数类型(与返回类型同源——vpi
# tree 深层节点 kind() 可能损坏,AST resolve 得垃圾类型如
# t.CSizeT→i32,跨模块 declare 参数宽错 → 调用侧 trunc 传参、
# sizet→i32,跨模块 declare 参数宽错 → 调用侧 trunc 传参、
# callee 按宽类型读栈残留垃圾高位 → 参数巨值崩溃(SlotsBugTest
# 根因)。段索引 = pi(模块级函数无 self,0=首参)。
pseg_ty: llvmlite.LLVMType | t.CPtr = _resolve_vpi_param_annot_seg(
@@ -2361,7 +2361,7 @@ def _inject_function_declare(pool: memhub.MemBuddy | t.CPtr,
# 方法混淆名: {src_sha1}.{ClassName}.{method}
# 参数类型从 vpi 注解解析(self 无注解时默认为 i8*)。
# 注入正确签名避免调用时 _ensure_method_declare 用实参类型
# 创建错误 declare(如 size: t.CSizeT 被写成 i32 而非 i64)。
# 创建错误 declare(如 size: sizet 被写成 i32 而非 i64)。
# ============================================================
def _inject_method_declare(pool: memhub.MemBuddy | t.CPtr,
mod: llvmlite.LLVMModule | t.CPtr,
@@ -2382,14 +2382,14 @@ def _inject_method_declare(pool: memhub.MemBuddy | t.CPtr,
return
# 构造方法查找名: ClassName.method
lookup_name_len: t.CSizeT = string.strlen(cls_name) + 1 + string.strlen(m_fd.name) + 1
lookup_name_len: sizet = string.strlen(cls_name) + 1 + string.strlen(m_fd.name) + 1
lookup_name: str = pool.alloc(lookup_name_len)
if lookup_name is None:
return
viperlib.snprintf(lookup_name, lookup_name_len, "%s.%s", cls_name, m_fd.name)
# mangled name: {src_sha1}.{ClassName}.{method}
mangled_len: t.CSizeT = string.strlen(src_sha1) + 1 + lookup_name_len
mangled_len: sizet = string.strlen(src_sha1) + 1 + lookup_name_len
mangled_name: str = pool.alloc(mangled_len)
if mangled_name is None:
return
@@ -2427,7 +2427,7 @@ def _inject_method_declare(pool: memhub.MemBuddy | t.CPtr,
# 提取参数并添加到 declare
param_count: int = 0
md_defaults: t.CVoid | t.CPtr = None
md_defaults: t.CPtr = None
md_default_count: int = 0
if m_fd.args is not None:
args_node: ast.Arguments | t.CPtr = (ast.Arguments | t.CPtr)(m_fd.args)
@@ -2439,9 +2439,9 @@ def _inject_method_declare(pool: memhub.MemBuddy | t.CPtr,
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, t.CUInt64T(m_fd.args))
cls_name, m_fd.name, param_count, uint64(m_fd.args))
stdlib.exit(1)
pi: t.CSizeT
pi: sizet
for pi in range(param_count):
ag: ast.Arg | t.CPtr = (ast.Arg | t.CPtr)(args_list.get(pi))
if ag is None:
@@ -2463,7 +2463,7 @@ def _inject_method_declare(pool: memhub.MemBuddy | t.CPtr,
param_ty: llvmlite.LLVMType | t.CPtr = i8_ptr_ty
# 优先用 vpi 文本注解缓存解析参数类型(与返回类型同源——vpi
# tree 深层节点 kind() 可能损坏,AST resolve 得垃圾类型如
# t.CSizeT→i32,declare 参数宽错 → 调用侧 trunc i64→i32 传参、
# sizet→i32,declare 参数宽错 → 调用侧 trunc i64→i32 传参、
# callee 按 i64 读栈残留垃圾高位 → can=巨值读未写槽位崩溃,
# SlotsBugTest 根因)。段索引 = pi(0=self 空段)。
pseg_ty: llvmlite.LLVMType | t.CPtr = _resolve_vpi_param_annot_seg(
+172 -172
View File
@@ -51,8 +51,8 @@ _SEEN_SLOT: t.CDefine = 274 # 8(hash)+8(pos)+1(flags)+256(name)+1(nul)
_SEEN_FUNC_CAP: t.CDefine = 16384
_SEEN_GLOBAL_CAP: t.CDefine = 16384
_SEEN_TYPE_CAP: t.CDefine = 4096
_SEEN_FNV_OFFSET: t.CUInt64T = 0xcbf29ce484222325
_SEEN_FNV_PRIME: t.CUInt64T = 0x100000001b3
_SEEN_FNV_OFFSET: uint64 = 0xcbf29ce484222325
_SEEN_FNV_PRIME: uint64 = 0x100000001b3
_seen_funcs: bytes # 已见函数签名表(@"sha1.name"( 等)
_seen_funcs_count: int
@@ -62,29 +62,29 @@ _seen_types: bytes # 已见类型名表(%name)
_seen_types_count: int
_seen_key_scratch: bytes # 注册键暂存(跨 truncation 窗口复制)
def _SeenHash(key: str) -> t.CUInt64T:
def _SeenHash(key: str) -> uint64:
"""FNV-1a 64 位哈希(对齐 includes/hashtable.vp)"""
h: t.CUInt64T = _SEEN_FNV_OFFSET
h: uint64 = _SEEN_FNV_OFFSET
p: str = key
while p[0] != 0:
h = h ^ t.CUInt64T(p[0])
h = h ^ uint64(p[0])
h = h * _SEEN_FNV_PRIME
p += 1
if h < 2:
h = 2
return h
def _SeenFind(tbl: bytes, cap: t.CSizeT, key: str, key_hash: t.CUInt64T) -> t.CSizeT:
def _SeenFind(tbl: bytes, cap: sizet, key: str, key_hash: uint64) -> sizet:
"""已见表槽位查找:命中返回槽位下标;未命中返回 cap(哨兵)"""
if tbl is None or key is None:
return cap
mask: t.CSizeT = cap - 1
idx: t.CSizeT = t.CSizeT(key_hash) & mask
i: t.CSizeT = 0
mask: sizet = cap - 1
idx: sizet = sizet(key_hash) & mask
i: sizet = 0
while i < cap:
off: t.CSizeT = idx * _SEEN_SLOT
hp: t.CUInt64T | t.CPtr = (t.CVoid | t.CPtr)(t.CUInt64T(tbl) + off)
sh: t.CUInt64T = hp[0]
off: sizet = idx * _SEEN_SLOT
hp: uint64 | t.CPtr = (t.CPtr)(uint64(tbl) + off)
sh: uint64 = hp[0]
if sh == 0:
return cap
if sh == key_hash:
@@ -95,72 +95,72 @@ def _SeenFind(tbl: bytes, cap: t.CSizeT, key: str, key_hash: t.CUInt64T) -> t.CS
i += 1
return cap
def _SeenPresent(tbl: bytes, cap: t.CSizeT, key: str, key_hash: t.CUInt64T) -> int:
def _SeenPresent(tbl: bytes, cap: sizet, key: str, key_hash: uint64) -> int:
"""已见表查找:返回 0=不存在;>0=存在(返回值 = flags+1)"""
si: t.CSizeT = _SeenFind(tbl, cap, key, key_hash)
si: sizet = _SeenFind(tbl, cap, key, key_hash)
if si >= cap:
return 0
return t.CInt(tbl[si * _SEEN_SLOT + 16]) + 1
return int(tbl[si * _SEEN_SLOT + 16]) + 1
def _SeenInsert(tbl: bytes, cap: t.CSizeT, count: int, key: str, key_hash: t.CUInt64T,
flags: int, pos: t.CSizeT) -> int:
def _SeenInsert(tbl: bytes, cap: sizet, count: int, key: str, key_hash: uint64,
flags: int, pos: sizet) -> int:
"""已见表插入/更新:key 不存在则新登记(返回 count+1);已存在则 OR flags、更新 pos"""
if tbl is None or key is None:
return count
kl: t.CSizeT = string.strlen(key)
kl: sizet = string.strlen(key)
if kl >= _SEEN_NAME_MAX:
return count
if count >= cap:
VLogger.error(f"已见符号表满(容量 {cap}),新增符号登记被丢弃——去重失效,必须增大容量", "StubMerger")
return count
mask: t.CSizeT = cap - 1
idx: t.CSizeT = t.CSizeT(key_hash) & mask
i: t.CSizeT = 0
mask: sizet = cap - 1
idx: sizet = sizet(key_hash) & mask
i: sizet = 0
while i < cap:
off: t.CSizeT = idx * _SEEN_SLOT
hp: t.CUInt64T | t.CPtr = (t.CVoid | t.CPtr)(t.CUInt64T(tbl) + off)
sh: t.CUInt64T = hp[0]
off: sizet = idx * _SEEN_SLOT
hp: uint64 | t.CPtr = (t.CPtr)(uint64(tbl) + off)
sh: uint64 = hp[0]
if sh == 0:
hp[0] = key_hash
pp: t.CUInt64T | t.CPtr = (t.CVoid | t.CPtr)(t.CUInt64T(tbl) + off + 8)
pp[0] = t.CUInt64T(pos)
tbl[off + 16] = t.CChar(flags)
pp: uint64 | t.CPtr = (t.CPtr)(uint64(tbl) + off + 8)
pp[0] = uint64(pos)
tbl[off + 16] = char(flags)
string.strcpy(tbl + off + 17, key)
return count + 1
if sh == key_hash:
nm: str = tbl + off + 17
if string.strcmp(nm, key) == 0:
pp: t.CUInt64T | t.CPtr = (t.CVoid | t.CPtr)(t.CUInt64T(tbl) + off + 8)
pp[0] = t.CUInt64T(pos)
tbl[off + 16] = t.CChar(t.CInt(tbl[off + 16]) | flags)
pp: uint64 | t.CPtr = (t.CPtr)(uint64(tbl) + off + 8)
pp[0] = uint64(pos)
tbl[off + 16] = char(int(tbl[off + 16]) | flags)
return count
idx = (idx + 1) & mask
i += 1
return count
def _SeenCommentOut(tbl: bytes, cap: t.CSizeT, key: str, key_hash: t.CUInt64T,
def _SeenCommentOut(tbl: bytes, cap: sizet, key: str, key_hash: uint64,
out_buf: bytes) -> int:
"""注释 out_buf 中该符号的活跃行(行首改 ';'),返回 1=已注释 0=无"""
si: t.CSizeT = _SeenFind(tbl, cap, key, key_hash)
si: sizet = _SeenFind(tbl, cap, key, key_hash)
if si >= cap:
return 0
if t.CInt(tbl[si * _SEEN_SLOT + 16]) != 0:
if int(tbl[si * _SEEN_SLOT + 16]) != 0:
return 0 # 类型表 flags=1:活跃行为完整定义,无可注释的 opaque
pp: t.CUInt64T | t.CPtr = (t.CVoid | t.CPtr)(t.CUInt64T(tbl) + si * _SEEN_SLOT + 8)
p: t.CUInt64T = pp[0]
pp: uint64 | t.CPtr = (t.CPtr)(uint64(tbl) + si * _SEEN_SLOT + 8)
p: uint64 = pp[0]
if out_buf is not None:
out_buf[t.CSizeT(p)] = ';'
out_buf[sizet(p)] = ';'
return 1
def _SeenGetPos(tbl: bytes, cap: t.CSizeT, key: str, key_hash: t.CUInt64T) -> t.CSizeT:
def _SeenGetPos(tbl: bytes, cap: sizet, key: str, key_hash: uint64) -> sizet:
"""读取已见表条目记录的活跃行位置;不存在返回 cap(哨兵)"""
si: t.CSizeT = _SeenFind(tbl, cap, key, key_hash)
si: sizet = _SeenFind(tbl, cap, key, key_hash)
if si >= cap:
return cap
pp: t.CUInt64T | t.CPtr = (t.CVoid | t.CPtr)(t.CUInt64T(tbl) + si * _SEEN_SLOT + 8)
return t.CSizeT(pp[0])
pp: uint64 | t.CPtr = (t.CPtr)(uint64(tbl) + si * _SEEN_SLOT + 8)
return sizet(pp[0])
def _RegisterStubLines(buf: bytes, buf_len: t.CSizeT, base_pos: t.CSizeT):
def _RegisterStubLines(buf: bytes, buf_len: sizet, base_pos: sizet):
"""把本地 stub(整体复制进 out_buf)中的 declare/global/type 全部登记到已见表
本地 stub.ll 在 BuildCombinedIR 第 1 步整体 strcpy 进 out_buf,不做逐行
@@ -174,34 +174,34 @@ def _RegisterStubLines(buf: bytes, buf_len: t.CSizeT, base_pos: t.CSizeT):
global _seen_funcs_count, _seen_globals_count, _seen_types_count
if buf is None:
return
pos: t.CSizeT = 0
pos: sizet = 0
while pos < buf_len:
ls: t.CSizeT = pos
ls: sizet = pos
while pos < buf_len:
if buf[pos] == '\n':
break
pos += 1
ll: t.CSizeT = pos - ls
ll: sizet = pos - ls
if pos < buf_len:
pos += 1
line_pos: t.CSizeT = base_pos + ls
line_pos: sizet = base_pos + ls
# declare → 函数签名 @"name"(
if ll >= 8 and string.strncmp(buf + ls, "declare ", 8) == 0:
at: t.CSizeT = ls + 8
at: sizet = ls + 8
while at < ls + ll:
if buf[at] == '@':
break
at += 1
if at < ls + ll:
lp: t.CSizeT = at + 1
lp: sizet = at + 1
while lp < ls + ll:
if buf[lp] == '(':
break
lp += 1
if lp < ls + ll:
sv_f: t.CChar = buf[lp + 1]
sv_f: char = buf[lp + 1]
buf[lp + 1] = '\0'
kh_f: t.CUInt64T = _SeenHash(buf + at)
kh_f: uint64 = _SeenHash(buf + at)
if _SeenPresent(_seen_funcs, _SEEN_FUNC_CAP, buf + at, kh_f) == 0:
_seen_funcs_count = _SeenInsert(_seen_funcs, _SEEN_FUNC_CAP, _seen_funcs_count, buf + at, kh_f, 0, line_pos)
else:
@@ -215,15 +215,15 @@ def _RegisterStubLines(buf: bytes, buf_len: t.CSizeT, base_pos: t.CSizeT):
if ll >= 5 and buf[ls + 1] == '.' and buf[ls + 2] == 's' and buf[ls + 3] == 't' and buf[ls + 4] == 'r':
buf[ls] = ';'
continue
eq: t.CSizeT = ls + 1
eq: sizet = ls + 1
while eq < ls + ll:
if buf[eq] == '=':
break
eq += 1
if eq < ls + ll:
sv_g: t.CChar = buf[eq]
sv_g: char = buf[eq]
buf[eq] = '\0'
kh_g: t.CUInt64T = _SeenHash(buf + ls)
kh_g: uint64 = _SeenHash(buf + ls)
if _SeenPresent(_seen_globals, _SEEN_GLOBAL_CAP, buf + ls, kh_g) == 0:
_seen_globals_count = _SeenInsert(_seen_globals, _SEEN_GLOBAL_CAP, _seen_globals_count, buf + ls, kh_g, 0, line_pos)
else:
@@ -232,15 +232,15 @@ def _RegisterStubLines(buf: bytes, buf_len: t.CSizeT, base_pos: t.CSizeT):
continue
# 类型 %name = type ...(完整定义 flags=1,opaque flags=0)
if ll > 0 and buf[ls] == '%':
eq: t.CSizeT = ls + 1
eq: sizet = ls + 1
while eq < ls + ll:
if buf[eq] == '=':
break
eq += 1
if eq < ls + ll:
sv_t: t.CChar = buf[eq]
sv_t: char = buf[eq]
buf[eq] = '\0'
kh_t: t.CUInt64T = _SeenHash(buf + ls)
kh_t: uint64 = _SeenHash(buf + ls)
is_full: int = 0
if eq + 8 <= ls + ll:
if buf[eq + 2] == 't' and buf[eq + 3] == 'y' and buf[eq + 4] == 'p' and buf[eq + 5] == 'e' and buf[eq + 6] == ' ':
@@ -251,7 +251,7 @@ def _RegisterStubLines(buf: bytes, buf_len: t.CSizeT, base_pos: t.CSizeT):
_seen_types_count = _SeenInsert(_seen_types, _SEEN_TYPE_CAP, _seen_types_count, buf + ls, kh_t, is_full, line_pos)
elif is_full == 1 and prev_t == 1:
# 先 opaque 后完整定义:注释旧行,表升级指向新完整定义行
old_pos: t.CSizeT = _SeenGetPos(_seen_types, _SEEN_TYPE_CAP, buf + ls, kh_t)
old_pos: sizet = _SeenGetPos(_seen_types, _SEEN_TYPE_CAP, buf + ls, kh_t)
if old_pos >= base_pos and old_pos < base_pos + buf_len:
buf[old_pos - base_pos] = ';'
_seen_types_count = _SeenInsert(_seen_types, _SEEN_TYPE_CAP, _seen_types_count, buf + ls, kh_t, 1, line_pos)
@@ -274,9 +274,9 @@ def _RegisterStubLines(buf: bytes, buf_len: t.CSizeT, base_pos: t.CSizeT):
# 读取 {temp_dir}/{sha1}.stub.ll,跳过 header(;, target, source_filename),
# 去重 declare/global,追加到 out_buf。返回新 out_pos。
# ============================================================
def _LoadAndAppendStub(temp_dir: str, td_len: t.CSizeT, dep_sha1: str,
dep_buf: bytes, out_buf: bytes, out_size: t.CSizeT,
out_pos: t.CSizeT) -> t.CSizeT:
def _LoadAndAppendStub(temp_dir: str, td_len: sizet, dep_sha1: str,
dep_buf: bytes, out_buf: bytes, out_size: sizet,
out_pos: sizet) -> sizet:
"""加载依赖 stub 并追加(跳过 header,去重)"""
global _seen_funcs_count, _seen_globals_count, _seen_types_count
if temp_dir is None or dep_sha1 is None or dep_buf is None or out_buf is None:
@@ -293,7 +293,7 @@ def _LoadAndAppendStub(temp_dir: str, td_len: t.CSizeT, dep_sha1: str,
if StubMergerStore.LookupSha1RelPath(dep_sha1) is not None:
VLogger.error(f"依赖 stub 缺失: {dep_sha1}", "StubMerger")
return out_pos
dep_br_ls: t.CInt64T = df_ls.read_all(dep_buf, StubMerger.STUB_READ_BUF_SIZE)
dep_br_ls: int64 = df_ls.read_all(dep_buf, StubMerger.STUB_READ_BUF_SIZE)
df_ls.close()
stdlib.free(dep_path)
if dep_br_ls <= 0:
@@ -305,14 +305,14 @@ def _LoadAndAppendStub(temp_dir: str, td_len: t.CSizeT, dep_sha1: str,
# 注释掉依赖 stub 中的字符串常量行(模块内部的,不需要)
# 简单方案:搜索 "= external unnamed_addr constant" 并将行首的 @ 改为 ;@
cfs_pos: t.CSizeT = 0
while cfs_pos + 30 < t.CSizeT(dep_br_ls):
cfs_pos: sizet = 0
while cfs_pos + 30 < sizet(dep_br_ls):
ext_p: t.CPtr = string.strstr(dep_buf + cfs_pos, "= external unnamed_addr constant")
if ext_p is None:
break
ext_off2: t.CSizeT = t.CSizeT(t.CUInt64T(ext_p) - t.CUInt64T(dep_buf))
ext_off2: sizet = sizet(uint64(ext_p) - uint64(dep_buf))
# 向前查找行首的 @
ls: t.CSizeT = ext_off2
ls: sizet = ext_off2
while ls > 0:
if dep_buf[ls] == '\n':
ls += 1
@@ -323,15 +323,15 @@ def _LoadAndAppendStub(temp_dir: str, td_len: t.CSizeT, dep_sha1: str,
cfs_pos = ext_off2 + 30
# 跳过 header,追加内容(去重 declare/global/type,已见符号表 O(1) 去重)
dep_pos: t.CSizeT = 0
dep_pos: sizet = 0
skipping: int = 1
while dep_pos < dep_br_ls:
line_start: t.CSizeT = dep_pos
line_start: sizet = dep_pos
while dep_pos < dep_br_ls:
if dep_buf[dep_pos] == '\n':
break
dep_pos += 1
line_len: t.CSizeT = dep_pos - line_start
line_len: sizet = dep_pos - line_start
if dep_pos < dep_br_ls:
dep_pos += 1
if skipping != 0:
@@ -350,23 +350,23 @@ def _LoadAndAppendStub(temp_dir: str, td_len: t.CSizeT, dep_sha1: str,
# 注册暂存(append 成功后才登记;reg_key 指向 scratch,insert 当轮完成)
reg_tbl: int = 0
reg_key: str = None
reg_hash: t.CUInt64T = 0
reg_hash: uint64 = 0
reg_flags: int = 0
# 去重:declare(用已见函数表,键 @"name"(,避免误匹配 call 语句)
if line_len >= 8 and string.strncmp(dep_buf + line_start, "declare ", 8) == 0:
at: t.CSizeT = line_start + 8
at: sizet = line_start + 8
while at < line_start + line_len:
if dep_buf[at] == '@':
break
at += 1
if at < line_start + line_len:
lp: t.CSizeT = at + 1
lp: sizet = at + 1
while lp < line_start + line_len:
if dep_buf[lp] == '(':
break
lp += 1
if lp < line_start + line_len:
saved: t.CChar = dep_buf[lp + 1]
saved: char = dep_buf[lp + 1]
dep_buf[lp + 1] = '\0'
reg_hash = _SeenHash(dep_buf + at)
if _SeenPresent(_seen_funcs, _SEEN_FUNC_CAP, dep_buf + at, reg_hash) != 0:
@@ -384,13 +384,13 @@ def _LoadAndAppendStub(temp_dir: str, td_len: t.CSizeT, dep_sha1: str,
if line_len >= 5 and dep_buf[line_start + 1] == '.' and dep_buf[line_start + 2] == 's' \
and dep_buf[line_start + 3] == 't' and dep_buf[line_start + 4] == 'r':
continue
eq: t.CSizeT = line_start + 1
eq: sizet = line_start + 1
while eq < line_start + line_len:
if dep_buf[eq] == '=':
break
eq += 1
if eq < line_start + line_len:
saved: t.CChar = dep_buf[eq]
saved: char = dep_buf[eq]
dep_buf[eq] = '\0'
reg_hash = _SeenHash(dep_buf + line_start)
if _SeenPresent(_seen_globals, _SEEN_GLOBAL_CAP, dep_buf + line_start, reg_hash) != 0:
@@ -406,13 +406,13 @@ def _LoadAndAppendStub(temp_dir: str, td_len: t.CSizeT, dep_sha1: str,
# 当本地 stub 有 opaque 声明而依赖 stub 有完整定义时,注释掉 opaque 行,
# 让完整定义被追加,避免 LLC "Cannot allocate unsized type" 错误。
if line_len > 0 and dep_buf[line_start] == '%':
eq2: t.CSizeT = line_start + 1
eq2: sizet = line_start + 1
while eq2 < line_start + line_len:
if dep_buf[eq2] == '=':
break
eq2 += 1
if eq2 < line_start + line_len:
saved2: t.CChar = dep_buf[eq2 + 1]
saved2: char = dep_buf[eq2 + 1]
dep_buf[eq2 + 1] = '\0'
# 检查依赖行是否为完整定义(= type { 或 = type <)
dep_is_full_def: int = 0
@@ -420,7 +420,7 @@ def _LoadAndAppendStub(temp_dir: str, td_len: t.CSizeT, dep_sha1: str,
if dep_buf[eq2 + 2] == 't' and dep_buf[eq2 + 3] == 'y' and dep_buf[eq2 + 4] == 'p' and dep_buf[eq2 + 5] == 'e' and dep_buf[eq2 + 6] == ' ':
if dep_buf[eq2 + 7] == '{' or dep_buf[eq2 + 7] == '<':
dep_is_full_def = 1
saved_eq: t.CChar = dep_buf[eq2]
saved_eq: char = dep_buf[eq2]
dep_buf[eq2] = '\0'
reg_hash = _SeenHash(dep_buf + line_start)
if dep_is_full_def == 1:
@@ -450,7 +450,7 @@ def _LoadAndAppendStub(temp_dir: str, td_len: t.CSizeT, dep_sha1: str,
dep_buf[eq2 + 1] = saved2
# 追加(append 成功后才登记已见表)
if out_pos + line_len + 2 < out_size:
reg_pos: t.CSizeT = out_pos
reg_pos: sizet = out_pos
string.strncpy(out_buf + out_pos, dep_buf + line_start, line_len)
out_pos += line_len
out_buf[out_pos] = '\n'
@@ -469,9 +469,9 @@ def _LoadAndAppendStub(temp_dir: str, td_len: t.CSizeT, dep_sha1: str,
# 读取 {temp_dir}/{sha1}.text.ll,将 define 行转为 declare(提取函数签名),
# 跳过函数体,去重后追加到 out_buf。返回新 out_pos。
# ============================================================
def _LoadAndAppendTextDeclares(temp_dir: str, td_len: t.CSizeT, dep_sha1: str,
dep_buf: bytes, out_buf: bytes, out_size: t.CSizeT,
out_pos: t.CSizeT) -> t.CSizeT:
def _LoadAndAppendTextDeclares(temp_dir: str, td_len: sizet, dep_sha1: str,
dep_buf: bytes, out_buf: bytes, out_size: sizet,
out_pos: sizet) -> sizet:
"""从依赖 text.ll 提取 declare(define 转 declare),追加到 out_buf"""
global _seen_funcs_count, _seen_globals_count, _seen_types_count
if temp_dir is None or dep_sha1 is None or dep_buf is None or out_buf is None:
@@ -488,7 +488,7 @@ def _LoadAndAppendTextDeclares(temp_dir: str, td_len: t.CSizeT, dep_sha1: str,
if StubMergerStore.LookupSha1RelPath(dep_sha1) is not None:
VLogger.error(f"依赖 text 缺失: {dep_sha1}", "StubMerger")
return out_pos
text_br: t.CInt64T = tf_lt.read_all(dep_buf, StubMerger.STUB_READ_BUF_SIZE)
text_br: int64 = tf_lt.read_all(dep_buf, StubMerger.STUB_READ_BUF_SIZE)
tf_lt.close()
stdlib.free(text_path)
if text_br <= 0:
@@ -498,15 +498,15 @@ def _LoadAndAppendTextDeclares(temp_dir: str, td_len: t.CSizeT, dep_sha1: str,
if text_br < StubMerger.STUB_READ_BUF_SIZE:
dep_buf[text_br] = '\0'
dep_pos_lt: t.CSizeT = 0
dep_pos_lt: sizet = 0
in_body: int = 0
while dep_pos_lt < text_br:
ls: t.CSizeT = dep_pos_lt
ls: sizet = dep_pos_lt
while dep_pos_lt < text_br:
if dep_buf[dep_pos_lt] == '\n':
break
dep_pos_lt += 1
ll: t.CSizeT = dep_pos_lt - ls
ll: sizet = dep_pos_lt - ls
if dep_pos_lt < text_br:
dep_pos_lt += 1
@@ -530,7 +530,7 @@ def _LoadAndAppendTextDeclares(temp_dir: str, td_len: t.CSizeT, dep_sha1: str,
# 处理 define 行:转为 declare
if ll >= 7 and string.strncmp(dep_buf + ls, "define ", 7) == 0:
# 提取 @funcname( 用于去重
at_lt: t.CSizeT = ls + 7
at_lt: sizet = ls + 7
while at_lt < ls + ll:
if dep_buf[at_lt] == '@':
break
@@ -538,7 +538,7 @@ def _LoadAndAppendTextDeclares(temp_dir: str, td_len: t.CSizeT, dep_sha1: str,
if at_lt >= ls + ll:
in_body = 1
continue
lp_lt: t.CSizeT = at_lt + 1
lp_lt: sizet = at_lt + 1
while lp_lt < ls + ll:
if dep_buf[lp_lt] == '(':
break
@@ -547,9 +547,9 @@ def _LoadAndAppendTextDeclares(temp_dir: str, td_len: t.CSizeT, dep_sha1: str,
in_body = 1
continue
# 去重检查:用已见函数表(键 @"name"(,避免误匹配 call 语句)
saved_lt: t.CChar = dep_buf[lp_lt + 1]
saved_lt: char = dep_buf[lp_lt + 1]
dep_buf[lp_lt + 1] = '\0'
fh_lt: t.CUInt64T = _SeenHash(dep_buf + at_lt)
fh_lt: uint64 = _SeenHash(dep_buf + at_lt)
if _SeenPresent(_seen_funcs, _SEEN_FUNC_CAP, dep_buf + at_lt, fh_lt) != 0:
dep_buf[lp_lt + 1] = saved_lt
in_body = 1
@@ -558,7 +558,7 @@ def _LoadAndAppendTextDeclares(temp_dir: str, td_len: t.CSizeT, dep_sha1: str,
dep_buf[lp_lt + 1] = saved_lt
# 找行尾的 ' {' 并截断
decl_end: t.CSizeT = ls + ll
decl_end: sizet = ls + ll
if decl_end > ls + 1:
if dep_buf[decl_end - 1] == '{' and dep_buf[decl_end - 2] == ' ':
decl_end -= 2
@@ -570,7 +570,7 @@ def _LoadAndAppendTextDeclares(temp_dir: str, td_len: t.CSizeT, dep_sha1: str,
# declaration"(LLVM 只允许 define 用 linkonce_odr,declare 必须
# external)。对齐 TPC Phase2Translator 的 decl_line 剥 linkage 逻辑,
# 循环跳过所有 linkage 词。
c_start_lt: t.CSizeT = ls + 7
c_start_lt: sizet = ls + 7
skipped_lt: int = 1
while skipped_lt != 0:
skipped_lt = 0
@@ -598,9 +598,9 @@ def _LoadAndAppendTextDeclares(temp_dir: str, td_len: t.CSizeT, dep_sha1: str,
string.strncmp(dep_buf + c_start_lt, "private ", 8) == 0:
c_start_lt += 8
skipped_lt = 1
copy_len_lt: t.CSizeT = decl_end - c_start_lt
copy_len_lt: sizet = decl_end - c_start_lt
if out_pos + 8 + copy_len_lt + 2 < out_size:
decl_pos_lt: t.CSizeT = out_pos
decl_pos_lt: sizet = out_pos
string.strncpy(out_buf + out_pos, "declare ", 8)
out_pos += 8
string.strncpy(out_buf + out_pos, dep_buf + c_start_lt, copy_len_lt)
@@ -616,7 +616,7 @@ def _LoadAndAppendTextDeclares(temp_dir: str, td_len: t.CSizeT, dep_sha1: str,
# stub.ll 中只有 opaque 声明,需要从 text.ll 中提取完整定义
# 用于 alloca 和 getelementptr 等需要完整类型的指令
if ll > 0 and dep_buf[ls] == '%':
eq_td: t.CSizeT = ls + 1
eq_td: sizet = ls + 1
while eq_td < ls + ll:
if dep_buf[eq_td] == '=':
break
@@ -632,9 +632,9 @@ def _LoadAndAppendTextDeclares(temp_dir: str, td_len: t.CSizeT, dep_sha1: str,
dep_is_full_td = 1
if dep_is_full_td == 1:
# 临时截断到 '=' 之前(不含 '='),键统一为 %name
saved_eq_td: t.CChar = dep_buf[eq_td]
saved_eq_td: char = dep_buf[eq_td]
dep_buf[eq_td] = '\0'
th_td: t.CUInt64T = _SeenHash(dep_buf + ls)
th_td: uint64 = _SeenHash(dep_buf + ls)
# 1. 注释掉 out_buf 中的 opaque 声明(如果有)
_SeenCommentOut(_seen_types, _SEEN_TYPE_CAP, dep_buf + ls, th_td, out_buf)
# 2. 检查是否已有完整定义(避免重复)
@@ -645,7 +645,7 @@ def _LoadAndAppendTextDeclares(temp_dir: str, td_len: t.CSizeT, dep_sha1: str,
dep_buf[eq_td] = saved_eq_td
# 追加完整类型定义
if out_pos + ll + 2 < out_size:
td_pos: t.CSizeT = out_pos
td_pos: sizet = out_pos
string.strncpy(out_buf + out_pos, dep_buf + ls, ll)
out_pos += ll
out_buf[out_pos] = '\n'
@@ -664,16 +664,16 @@ def _LoadAndAppendTextDeclares(temp_dir: str, td_len: t.CSizeT, dep_sha1: str,
if ll >= 5 and dep_buf[ls + 1] == '.' and dep_buf[ls + 2] == 's' and dep_buf[ls + 3] == 't' \
and dep_buf[ls + 4] == 'r':
continue
eq_gv: t.CSizeT = ls + 1
eq_gv: sizet = ls + 1
while eq_gv < ls + ll:
if dep_buf[eq_gv] == '=':
break
eq_gv += 1
if eq_gv < ls + ll:
# 截断到 '=' 之前(不含 '='),键统一为 @name
saved_gv: t.CChar = dep_buf[eq_gv]
saved_gv: char = dep_buf[eq_gv]
dep_buf[eq_gv] = '\0'
gh_gv: t.CUInt64T = _SeenHash(dep_buf + ls)
gh_gv: uint64 = _SeenHash(dep_buf + ls)
# 依赖方已有同名全局(stub 注入的 external 声明或先前依赖的定义)
# 时跳过:跨模块全局(如 _op_head、MemBuddy.vtable)只需一份
# 强定义(在定义模块的 text.ll 中),复制进每个依赖方会导致
@@ -684,7 +684,7 @@ def _LoadAndAppendTextDeclares(temp_dir: str, td_len: t.CSizeT, dep_sha1: str,
string.strcpy(_seen_key_scratch, dep_buf + ls)
dep_buf[eq_gv] = saved_gv
if out_pos + ll + 2 < out_size:
gv_pos: t.CSizeT = out_pos
gv_pos: sizet = out_pos
string.strncpy(out_buf + out_pos, dep_buf + ls, ll)
out_pos += ll
out_buf[out_pos] = '\n'
@@ -712,9 +712,9 @@ def _IsAppModule(mod_name: str) -> int:
if StubMerger._sha1_store_arr is None or StubMerger._sha1_store_mod is None:
return 0
for i in range(StubMerger._sha1_store_count):
midx: t.CSizeT = t.CSizeT(i) * 64
midx: sizet = sizet(i) * 64
if string.strcmp(StubMerger._sha1_store_mod + midx, mod_name) == 0:
iidx: t.CSizeT = t.CSizeT(i) * StubMerger.MAX_INC_DIR_LEN
iidx: sizet = sizet(i) * StubMerger.MAX_INC_DIR_LEN
if StubMerger._sha1_store_incdir[iidx] == '\0':
return 1
return 0
@@ -735,18 +735,18 @@ def _IsAppModule(mod_name: str) -> int:
# Returns:
# 追加后的新长度(>=0);溢出/参数错误返回 -1(调用方 fail-fast)
# ============================================================
def _AppendDepsToWorklist(worklist: bytes, wl_len: t.CSizeT,
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: t.CSizeT = wl_len
dl: t.CSizeT = string.strlen(deps_str)
dpos: t.CSizeT = 0
cur_len: sizet = wl_len
dl: sizet = string.strlen(deps_str)
dpos: sizet = 0
while dpos < dl:
dstart: t.CSizeT = dpos
dstart: sizet = dpos
while dpos < dl and deps_str[dpos] != ' ':
dpos += 1
dlen: t.CSizeT = dpos - dstart
dlen: sizet = dpos - dstart
if dpos < dl:
dpos += 1
if dlen == 0:
@@ -778,7 +778,7 @@ def _AppendDepsToWorklist(worklist: bytes, wl_len: t.CSizeT,
VLogger.error("依赖 worklist 溢出", "StubMerger")
return -1
stdlib.free(dmod)
return t.CInt(cur_len)
return int(cur_len)
# ============================================================
# _BuildReachableSha1Set - 构建可达 SHA1 集合(依赖图按需扫描)
#
@@ -819,28 +819,28 @@ def _BuildReachableSha1Set(mb: memhub.MemBuddy | t.CPtr, source_dir: str,
VLogger.error("includes_dirs 缺失,无法按需解析依赖图", "Reachable")
return -1
SRC_BUF_SIZE_R: t.CSizeT = 1048576
SRC_BUF_SIZE_R: sizet = 1048576
# 工作列表(空格分隔的模块名)
worklist: bytes = stdlib.malloc(StubMerger.REACH_WORKLIST_BUF)
if worklist is None:
return -1
worklist[0] = '\0'
wl_len: t.CSizeT = 0
wl_len: sizet = 0
# 1. App 扫描(app_deps 非空时跳过,直接用调用方提供的初始队列)
if app_deps is None or app_deps[0] == '\0':
VLogger.info("App 扫描:解析 source_dir 的 import 依赖", "Reachable")
scan_res_r: IncludesScanner.ScanResult | t.CPtr = IncludesScanner.scan_includes(mb, source_dir)
if scan_res_r is not None:
es_r: t.CSizeT = IncludesScanner.FileEntry.__sizeof__()
es_r: sizet = IncludesScanner.FileEntry.__sizeof__()
for e_i_r in range(scan_res_r.Count):
e_r: IncludesScanner.FileEntry | t.CPtr = (IncludesScanner.FileEntry | t.CPtr)(
t.CVoid(t.CUInt64T(scan_res_r.Entries) + t.CUInt64T(e_i_r) * es_r, t.CPtr))
t.CVoid(uint64(scan_res_r.Entries) + uint64(e_i_r) * es_r, t.CPtr))
if e_r is None or e_r.Path is None:
continue
# 文件级 mark:parse 完立即回收 AST(App 全量 parse 驻留会 OOM)
app_mark: t.CSizeT = mb.mark()
app_mark: sizet = mb.mark()
sbuf: bytes = Utils.read_file_to_buf(e_r.Path, SRC_BUF_SIZE_R)
if sbuf is None:
mb.reset_to(app_mark)
@@ -877,13 +877,13 @@ def _BuildReachableSha1Set(mb: memhub.MemBuddy | t.CPtr, source_dir: str,
StubMergerStore.PopulateIncludesDeps(e_r.Sha1, tr._imported_modules)
# 收集 deps 到初始队列(逐模块去重)
if tr._imported_modules is not None:
im_len_a: t.CSizeT = string.strlen(tr._imported_modules)
im_pos_a: t.CSizeT = 0
im_len_a: sizet = string.strlen(tr._imported_modules)
im_pos_a: sizet = 0
while im_pos_a < im_len_a:
im_start_a: t.CSizeT = im_pos_a
im_start_a: sizet = im_pos_a
while im_pos_a < im_len_a and tr._imported_modules[im_pos_a] != ' ':
im_pos_a += 1
im_mod_len: t.CSizeT = im_pos_a - im_start_a
im_mod_len: sizet = im_pos_a - im_start_a
if im_pos_a < im_len_a:
im_pos_a += 1
if im_mod_len == 0:
@@ -916,7 +916,7 @@ def _BuildReachableSha1Set(mb: memhub.MemBuddy | t.CPtr, source_dir: str,
mb.reset_to(app_mark)
else:
# app_deps 已提供(Phase2 场景):直接作为初始队列
ad_len: t.CSizeT = string.strlen(app_deps)
ad_len: sizet = string.strlen(app_deps)
if ad_len > 0 and ad_len < StubMerger.REACH_WORKLIST_BUF:
string.strcpy(worklist, app_deps)
wl_len = ad_len
@@ -950,23 +950,23 @@ def _BuildReachableSha1Set(mb: memhub.MemBuddy | t.CPtr, source_dir: str,
stdlib.free(worklist)
return -1
processed[0] = '\0'
proc_len: t.CSizeT = 0
proc_len: sizet = 0
reachable_count: int = 0
wl_pos: t.CPtr = stdlib.malloc(8)
if wl_pos is None:
stdlib.free(worklist)
stdlib.free(processed)
return -1
wl_pos_slot: t.CSizeT | t.CPtr = (t.CSizeT | t.CPtr)(t.CVoid(wl_pos, t.CPtr))
wl_pos_slot: sizet | t.CPtr = (sizet | t.CPtr)(t.CVoid(wl_pos, t.CPtr))
wl_pos_slot[0] = 0
while wl_pos_slot[0] < wl_len:
pos: t.CSizeT = wl_pos_slot[0]
pos: sizet = wl_pos_slot[0]
# 提取一个模块名(到空格或末尾)
name_start: t.CSizeT = pos
name_start: sizet = pos
while pos < wl_len and worklist[pos] != ' ':
pos += 1
name_len: t.CSizeT = pos - name_start
name_len: sizet = pos - name_start
if pos < wl_len:
pos += 1
wl_pos_slot[0] = pos
@@ -1010,7 +1010,7 @@ def _BuildReachableSha1Set(mb: memhub.MemBuddy | t.CPtr, source_dir: str,
stdlib.free(processed)
stdlib.free(wl_pos)
return -1
wl_len = t.CSizeT(ret_ap)
wl_len = sizet(ret_ap)
stdlib.free(mod_buf)
continue
@@ -1028,12 +1028,12 @@ def _BuildReachableSha1Set(mb: memhub.MemBuddy | t.CPtr, source_dir: str,
stdlib.free(mod_buf)
continue
# 输出槽防御性初始化(成功路径必全写;未找到/未命中时仅 free 槽本身)
# 槽联合必须用 (t.CSizeT | t.CPtr):t.CPtr|t.CPtr 会被折叠成 t.CPtr,
# 槽联合必须用 (sizet | t.CPtr):t.CPtr|t.CPtr 会被折叠成 t.CPtr,
# [0] 变成 1 字节访问 → 指针被截断(0x2e 崩溃根因)。CSizeT 成员为
# 8 字节,经 t.CVoid 显式做 u64↔指针转换。
abs_slot: t.CSizeT | t.CPtr = (t.CSizeT | t.CPtr)(t.CVoid(out_abs, t.CPtr))
rel_slot: t.CSizeT | t.CPtr = (t.CSizeT | t.CPtr)(t.CVoid(out_rel, t.CPtr))
inc_slot: t.CSizeT | t.CPtr = (t.CSizeT | t.CPtr)(t.CVoid(out_inc, t.CPtr))
abs_slot: sizet | t.CPtr = (sizet | t.CPtr)(t.CVoid(out_abs, t.CPtr))
rel_slot: sizet | t.CPtr = (sizet | t.CPtr)(t.CVoid(out_rel, t.CPtr))
inc_slot: sizet | t.CPtr = (sizet | t.CPtr)(t.CVoid(out_inc, t.CPtr))
abs_slot[0] = 0
rel_slot[0] = 0
inc_slot[0] = 0
@@ -1079,7 +1079,7 @@ def _BuildReachableSha1Set(mb: memhub.MemBuddy | t.CPtr, source_dir: str,
stdlib.free(processed)
stdlib.free(wl_pos)
return -1
wl_len = t.CSizeT(ret_ex)
wl_len = sizet(ret_ex)
stdlib.free(abs_path)
stdlib.free(rel_path)
stdlib.free(inc_dir)
@@ -1095,7 +1095,7 @@ def _BuildReachableSha1Set(mb: memhub.MemBuddy | t.CPtr, source_dir: str,
# 文件级 mark:parse import 后立即回收 AST(可达 includes 全量
# parse 的 AST 若驻留 → 主池 OOM)
scan_mark_r: t.CSizeT = mb.mark()
scan_mark_r: sizet = mb.mark()
sbuf_r: bytes = Utils.read_file_to_buf(abs_path, SRC_BUF_SIZE_R)
if sbuf_r is None:
stdlib.free(abs_path)
@@ -1178,12 +1178,12 @@ def _BuildReachableSha1Set(mb: memhub.MemBuddy | t.CPtr, source_dir: str,
deps_r2: str = tr_r2._imported_modules
StubMergerStore.PopulateIncludesDeps(sha1_r2, deps_r2)
if deps_r2 is not None:
td_len_w: t.CSizeT = string.strlen(temp_dir)
td_len_w: sizet = string.strlen(temp_dir)
deps_path_w: str = StubMergerCollect._sliced_path(temp_dir, td_len_w, sha1_r2, "deps.txt")
if deps_path_w is not None:
df_w: fileio.File | t.CPtr = fileio.File(deps_path_w, fileio.MODE.W)
if not df_w.closed:
dl_w: t.CSizeT = string.strlen(deps_r2)
dl_w: sizet = string.strlen(deps_r2)
if dl_w > 0:
df_w.write(deps_r2, dl_w)
df_w.close()
@@ -1204,7 +1204,7 @@ def _BuildReachableSha1Set(mb: memhub.MemBuddy | t.CPtr, source_dir: str,
stdlib.free(wl_pos)
mb.reset_to(scan_mark_r)
return -1
wl_len = t.CSizeT(ret_w)
wl_len = sizet(ret_w)
else:
VLogger.debug(f"无依赖: {rel_path}", "Reachable")
@@ -1239,16 +1239,16 @@ def _BuildReachableSha1Set(mb: memhub.MemBuddy | t.CPtr, source_dir: str,
# _sha1_map.txt 仅作为人类可读输出,程序内部不读取。
# ============================================================
def BuildCombinedIR(temp_dir: str, local_sha1: str,
out_buf: bytes, out_size: t.CSizeT) -> t.CSizeT:
out_buf: bytes, out_size: sizet) -> sizet:
"""组合本地 stub + 依赖 stubs + 本地 text → out_buf(按需加载)"""
global _seen_funcs, _seen_funcs_count, _seen_globals, _seen_globals_count
global _seen_types, _seen_types_count, _seen_key_scratch
if temp_dir is None or local_sha1 is None or out_buf is None or out_size == 0:
return 0
td_len: t.CSizeT = string.strlen(temp_dir)
td_len: sizet = string.strlen(temp_dir)
out_buf[0] = '\0'
out_pos: t.CSizeT = 0
out_pos: sizet = 0
# 已见符号表重置(跨构建复用缓冲,仅清零计数 + 全槽位清零)
if _seen_funcs is None:
@@ -1291,7 +1291,7 @@ def BuildCombinedIR(temp_dir: str, local_sha1: str,
sf.close()
stdlib.free(stub_path)
return 0
stub_br: t.CInt64T = sf.read_all(stub_content, StubMerger.STUB_READ_BUF_SIZE)
stub_br: int64 = sf.read_all(stub_content, StubMerger.STUB_READ_BUF_SIZE)
sf.close()
stdlib.free(stub_path)
if stub_br <= 0:
@@ -1299,18 +1299,18 @@ def BuildCombinedIR(temp_dir: str, local_sha1: str,
return 0
if stub_br < StubMerger.STUB_READ_BUF_SIZE:
stub_content[stub_br] = '\0'
slen: t.CSizeT = stub_br
slen: sizet = stub_br
# 修复本地 stub.ll 中字符串常量的非法 IR:
# llvmlite OUTPUT_STUB 模式输出 "= external unnamed_addr constant" 的非法形式。
# 简单方案:搜索 "= external unnamed_addr constant" 并将 external 替换为 8 个空格。
fix_pos: t.CSizeT = 0
fix_pos: sizet = 0
while fix_pos + 30 < slen:
ext_ptr: t.CPtr = string.strstr(stub_content + fix_pos, "= external unnamed_addr constant")
if ext_ptr is None:
break
# ext_ptr 指向 "= external ..." 中的 '='
# 'external' 开始于 ext_ptr + 2
ext_off: t.CSizeT = t.CSizeT(t.CUInt64T(ext_ptr) - t.CUInt64T(stub_content)) + 2
ext_off: sizet = sizet(uint64(ext_ptr) - uint64(stub_content)) + 2
if ext_off + 8 <= slen:
stub_content[ext_off] = ' '
stub_content[ext_off + 1] = ' '
@@ -1351,7 +1351,7 @@ def BuildCombinedIR(temp_dir: str, local_sha1: str,
if not df_deps.closed:
deps_buf = stdlib.malloc(4096)
if deps_buf is not None:
deps_br: t.CInt64T = df_deps.read_all(deps_buf, 4096)
deps_br: int64 = df_deps.read_all(deps_buf, 4096)
if deps_br > 0:
if deps_br < 4096:
deps_buf[deps_br] = '\0'
@@ -1410,7 +1410,7 @@ def BuildCombinedIR(temp_dir: str, local_sha1: str,
if dep_buf is not None:
si: int = 0
while si < all_count:
dep_sha1: str = all_sha1_arr + t.CSizeT(si) * 17
dep_sha1: str = all_sha1_arr + sizet(si) * 17
if string.strcmp(dep_sha1, local_sha1) == 0:
si += 1
continue
@@ -1419,12 +1419,12 @@ def BuildCombinedIR(temp_dir: str, local_sha1: str,
is_include: int = 0
if inc_count > 0:
for ii in range(inc_count):
idx_ii: t.CSizeT = t.CSizeT(ii) * 17
idx_ii: sizet = sizet(ii) * 17
if string.strcmp(sha1_arr + idx_ii, dep_sha1) != 0:
continue
is_include = 1
if deps_loaded != 0:
idx_mi: t.CSizeT = t.CSizeT(ii) * 64
idx_mi: sizet = sizet(ii) * 64
dep_mod_name: str = mod_arr + idx_mi
if GenApi.is_module_imported(deps_buf, dep_mod_name) != 0:
should_load = 1
@@ -1463,8 +1463,8 @@ def BuildCombinedIR(temp_dir: str, local_sha1: str,
# 避免到 llc 才报 undefined value 错误。
# 仅验证在 includes 映射中找到的模块(t/c 等内部库无 SHA1 映射,自动跳过)。
if deps_loaded != 0 and inc_count > 0:
dep_total: t.CSizeT = string.strlen(deps_buf)
dp: t.CSizeT = 0
dep_total: sizet = string.strlen(deps_buf)
dp: sizet = 0
while dp < dep_total:
# 跳过前导空格
while dp < dep_total:
@@ -1474,12 +1474,12 @@ def BuildCombinedIR(temp_dir: str, local_sha1: str,
if dp >= dep_total:
break
# 提取模块名(到下一个空格或末尾)
ms: t.CSizeT = dp
ms: sizet = dp
while dp < dep_total:
if deps_buf[dp] == ' ':
break
dp += 1
ml: t.CSizeT = dp - ms
ml: sizet = dp - ms
if ml == 0:
continue
# 复制模块名到临时缓冲区并 null 终止
@@ -1491,9 +1491,9 @@ def BuildCombinedIR(temp_dir: str, local_sha1: str,
# 在 includes 映射中查找模块对应的 SHA1
found_s: str = None
for mi2 in range(inc_count):
idx_m2: t.CSizeT = t.CSizeT(mi2) * 64
idx_m2: sizet = sizet(mi2) * 64
if string.strcmp(mod_arr + idx_m2, mod_nm) == 0:
idx_s2: t.CSizeT = t.CSizeT(mi2) * 17
idx_s2: sizet = sizet(mi2) * 17
found_s = sha1_arr + idx_s2
break
if found_s is not None:
@@ -1522,22 +1522,22 @@ def BuildCombinedIR(temp_dir: str, local_sha1: str,
tf.close()
stdlib.free(text_path)
else:
text_br: t.CInt64T = tf.read_all(text_content, StubMerger.STUB_READ_BUF_SIZE)
text_br: int64 = tf.read_all(text_content, StubMerger.STUB_READ_BUF_SIZE)
tf.close()
stdlib.free(text_path)
if text_br > 0:
if text_br < StubMerger.STUB_READ_BUF_SIZE:
text_content[text_br] = '\0'
# 行级去重追加(与 _LoadAndAppendStub 相同逻辑)
tx_pos: t.CSizeT = 0
tx_pos: sizet = 0
tx_skip: int = 1
while tx_pos < text_br:
tx_ls: t.CSizeT = tx_pos
tx_ls: sizet = tx_pos
while tx_pos < text_br:
if text_content[tx_pos] == '\n':
break
tx_pos += 1
tx_ll: t.CSizeT = tx_pos - tx_ls
tx_ll: sizet = tx_pos - tx_ls
if tx_pos < text_br:
tx_pos += 1
if tx_skip != 0:
@@ -1556,23 +1556,23 @@ def BuildCombinedIR(temp_dir: str, local_sha1: str,
# 注册暂存(append 成功后才登记;tx_key 指向 scratch,insert 当轮完成)
tx_reg: int = 0
tx_key: str = None
tx_hash: t.CUInt64T = 0
tx_hash: uint64 = 0
tx_flags: int = 0
# 去重:declare(用已见函数表,键 @"name"(,避免误匹配 call 语句)
if tx_ll >= 8 and string.strncmp(text_content + tx_ls, "declare ", 8) == 0:
tx_at: t.CSizeT = tx_ls + 8
tx_at: sizet = tx_ls + 8
while tx_at < tx_ls + tx_ll:
if text_content[tx_at] == '@':
break
tx_at += 1
if tx_at < tx_ls + tx_ll:
tx_lp: t.CSizeT = tx_at + 1
tx_lp: sizet = tx_at + 1
while tx_lp < tx_ls + tx_ll:
if text_content[tx_lp] == '(':
break
tx_lp += 1
if tx_lp < tx_ls + tx_ll:
tx_sv: t.CChar = text_content[tx_lp + 1]
tx_sv: char = text_content[tx_lp + 1]
text_content[tx_lp + 1] = '\0'
tx_hash = _SeenHash(text_content + tx_at)
if _SeenPresent(_seen_funcs, _SEEN_FUNC_CAP, text_content + tx_at, tx_hash) != 0:
@@ -1585,19 +1585,19 @@ def BuildCombinedIR(temp_dir: str, local_sha1: str,
text_content[tx_lp + 1] = tx_sv
# 去重:define(注释 out_buf 中已有 declare,避免 declare/define 冲突)
if tx_ll >= 7 and string.strncmp(text_content + tx_ls, "define ", 7) == 0:
tx_at_d: t.CSizeT = tx_ls + 7
tx_at_d: sizet = tx_ls + 7
while tx_at_d < tx_ls + tx_ll:
if text_content[tx_at_d] == '@':
break
tx_at_d += 1
if tx_at_d < tx_ls + tx_ll:
tx_lp_d: t.CSizeT = tx_at_d + 1
tx_lp_d: sizet = tx_at_d + 1
while tx_lp_d < tx_ls + tx_ll:
if text_content[tx_lp_d] == '(':
break
tx_lp_d += 1
if tx_lp_d < tx_ls + tx_ll:
tx_sv_d: t.CChar = text_content[tx_lp_d + 1]
tx_sv_d: char = text_content[tx_lp_d + 1]
text_content[tx_lp_d + 1] = '\0'
tx_hash = _SeenHash(text_content + tx_at_d)
_SeenCommentOut(_seen_funcs, _SEEN_FUNC_CAP, text_content + tx_at_d, tx_hash, out_buf)
@@ -1610,13 +1610,13 @@ def BuildCombinedIR(temp_dir: str, local_sha1: str,
# stub 中可能是 external 声明或完整定义,以 text 中的定义为准
# 注释 out_buf 中同名全局行,然后追加 text 中的定义(键 @name,截断于 '=' 前)
if tx_ll > 0 and text_content[tx_ls] == '@':
tx_eq: t.CSizeT = tx_ls + 1
tx_eq: sizet = tx_ls + 1
while tx_eq < tx_ls + tx_ll:
if text_content[tx_eq] == '=':
break
tx_eq += 1
if tx_eq < tx_ls + tx_ll:
tx_sv2: t.CChar = text_content[tx_eq]
tx_sv2: char = text_content[tx_eq]
text_content[tx_eq] = '\0'
tx_hash = _SeenHash(text_content + tx_ls)
_SeenCommentOut(_seen_globals, _SEEN_GLOBAL_CAP, text_content + tx_ls, tx_hash, out_buf)
@@ -1627,13 +1627,13 @@ def BuildCombinedIR(temp_dir: str, local_sha1: str,
text_content[tx_eq] = tx_sv2
# 去重:%type = ...(键 %name,截断于 '=' 前)
if tx_ll > 0 and text_content[tx_ls] == '%':
tx_eq2: t.CSizeT = tx_ls + 1
tx_eq2: sizet = tx_ls + 1
while tx_eq2 < tx_ls + tx_ll:
if text_content[tx_eq2] == '=':
break
tx_eq2 += 1
if tx_eq2 < tx_ls + tx_ll:
tx_sv3: t.CChar = text_content[tx_eq2]
tx_sv3: char = text_content[tx_eq2]
text_content[tx_eq2] = '\0'
tx_is_full: int = 0
if tx_eq2 + 8 <= tx_ls + tx_ll:
@@ -1653,7 +1653,7 @@ def BuildCombinedIR(temp_dir: str, local_sha1: str,
text_content[tx_eq2] = tx_sv3
# 追加(append 成功后才登记已见表)
if out_pos + tx_ll + 2 < out_size:
tx_reg_pos: t.CSizeT = out_pos
tx_reg_pos: sizet = out_pos
string.strncpy(out_buf + out_pos, text_content + tx_ls, tx_ll)
out_pos += tx_ll
out_buf[out_pos] = '\n'
@@ -1715,12 +1715,12 @@ def LoadDepVpiIntoModule(pool: memhub.MemBuddy | t.CPtr,
# → 参数类型退化 i8_ptr_ty → 整数实参误报 CastError(FuncTest 根因)。
VpiReader.ResetVpiTypedefVisited()
td_len: t.CSizeT = string.strlen(temp_dir)
total_len: t.CSizeT = string.strlen(imported_modules)
td_len: sizet = string.strlen(temp_dir)
total_len: sizet = string.strlen(imported_modules)
success_count: int = 0
# 遍历 imported_modules 中的每个模块名(空格分隔)
ci: t.CSizeT = 0
ci: sizet = 0
while ci < total_len:
# 跳过前导空格
while ci < total_len and imported_modules[ci] == ' ':
@@ -1728,10 +1728,10 @@ def LoadDepVpiIntoModule(pool: memhub.MemBuddy | t.CPtr,
if ci >= total_len:
break
# 提取模块名(到下一个空格或字符串末尾)
word_start: t.CSizeT = ci
word_start: sizet = ci
while ci < total_len and imported_modules[ci] != ' ':
ci += 1
word_len: t.CSizeT = ci - word_start
word_len: sizet = ci - word_start
if word_len == 0:
continue
+15 -15
View File
@@ -52,26 +52,26 @@ import lib.Stub.StubMerger as StubMerger
# Returns:
# 完整路径(stdlib.malloc 分配,需 stdlib.free),None 失败
# ============================================================
def _sliced_path(temp_dir: str, td_len: t.CSizeT, sha1: str, ext: str) -> str:
def _sliced_path(temp_dir: str, td_len: sizet, sha1: str, ext: str) -> str:
"""构建切片路径(stdlib.malloc 分配,调用者负责 free)
level>0 时自动调用 ensure_dir 创建子目录。
"""
if temp_dir is None or sha1 is None or ext is None:
return None
sha1_len: t.CSizeT = string.strlen(sha1)
ext_len: t.CSizeT = string.strlen(ext)
sha1_len: sizet = string.strlen(sha1)
ext_len: sizet = string.strlen(ext)
# 子目录前缀:复用 Config.slice_subdir(SHA1 切片唯一权威实现,mbuddy 分配无需 free)
subdir_buf: str = Config.slice_subdir(sha1, Config.Sha1SliceLevel)
sub_len: t.CSizeT = 0
sub_len: sizet = 0
if subdir_buf is not None:
sub_len = string.strlen(subdir_buf)
# 确保子目录存在: {temp_dir}/{subdir}
# 不创建目录会导致 fileio.File(MODE.W) 静默失败(file.closed==True),
# 进而 BuildCombinedIR 读不到文件返回 0("BuildCombinedIR 失败")。
dir_path_len: t.CSizeT = td_len + sub_len + 2
dir_path_len: sizet = td_len + sub_len + 2
dir_path: bytes = stdlib.malloc(dir_path_len)
if dir_path is not None:
viperlib.snprintf(dir_path, dir_path_len, "%s/%s", temp_dir, subdir_buf)
@@ -80,7 +80,7 @@ def _sliced_path(temp_dir: str, td_len: t.CSizeT, sha1: str, ext: str) -> str:
# 构建完整路径
path: str = None
path_len: t.CSizeT = 0
path_len: sizet = 0
if sub_len > 0:
path_len = td_len + sub_len + sha1_len + ext_len + 4
path = stdlib.malloc(path_len)
@@ -111,7 +111,7 @@ def _sliced_path(temp_dir: str, td_len: t.CSizeT, sha1: str, ext: str) -> str:
# Returns:
# 收集后的总数量
# ============================================================
def _collect_stub_sha1s(base_dir: str, bd_len: t.CSizeT, level: int,
def _collect_stub_sha1s(base_dir: str, bd_len: sizet, level: int,
out_arr: str, out_count: int, max_count: int) -> int:
"""递归扫描子目录,收集 .stub.ll 文件的 SHA1"""
if base_dir is None or out_arr is None:
@@ -159,7 +159,7 @@ def _collect_stub_sha1s(base_dir: str, bd_len: t.CSizeT, level: int,
if handle != win32base.INVALID_HANDLE_VALUE:
while True:
# 检查是否是目录(FILE_ATTRIBUTE_DIRECTORY = 0x10 = 16)
attrs: t.CUInt32T = find_data.dwFileAttributes
attrs: uint32 = find_data.dwFileAttributes
if (attrs & 16) != 0:
fname = find_data.cFileName
if fname is not None:
@@ -174,7 +174,7 @@ def _collect_stub_sha1s(base_dir: str, bd_len: t.CSizeT, level: int,
# 构建子目录路径并递归扫描
sub_dir: str = Utils.JoinPath(base_dir, fname)
if sub_dir is not None:
sub_dir_len: t.CSizeT = string.strlen(sub_dir)
sub_dir_len: sizet = string.strlen(sub_dir)
out_count = _collect_stub_sha1s(sub_dir, sub_dir_len, level - 1, out_arr, out_count, max_count)
stdlib.free(sub_dir)
if win32file.FindNextFileA(handle, find_data) == 0:
@@ -206,8 +206,8 @@ def _load_includes_sha1_set(pool: rowptr[memhub.MemBuddy],
for i in range(StubMerger._sha1_store_count):
if count >= StubMerger.MAX_INCLUDES_SHA1:
break
idx: t.CSizeT = t.CSizeT(i) * 17
string.strcpy(sha1_set + t.CSizeT(count) * 17, StubMerger._sha1_store_arr + idx)
idx: sizet = sizet(i) * 17
string.strcpy(sha1_set + sizet(count) * 17, StubMerger._sha1_store_arr + idx)
count += 1
return count
# ============================================================
@@ -247,7 +247,7 @@ def WriteIncludesSha1Map(mb: rowptr[memhub.MemBuddy], temp_dir: str,
return 1
# 构造路径 temp_dir/_sha1_map.txt
dir_len: t.CSizeT = string.strlen(temp_dir)
dir_len: sizet = string.strlen(temp_dir)
map_path: bytes = stdlib.malloc(dir_len + 32)
if map_path is None:
return 1
@@ -259,7 +259,7 @@ def WriteIncludesSha1Map(mb: rowptr[memhub.MemBuddy], temp_dir: str,
return 1
# 写入每个 include 条目: {sha1}:includes/{rel_path}\n
entry_size_w: t.CSizeT = IncludesScanner.FileEntry.__sizeof__()
entry_size_w: sizet = IncludesScanner.FileEntry.__sizeof__()
line_buf: bytes = stdlib.malloc(512)
if line_buf is None:
f.close()
@@ -267,7 +267,7 @@ def WriteIncludesSha1Map(mb: rowptr[memhub.MemBuddy], temp_dir: str,
written_count: int = 0
for i in range(scan_result.Count):
ea_w: t.CUInt64T = t.CUInt64T(scan_result.Entries) + i * entry_size_w
ea_w: uint64 = uint64(scan_result.Entries) + i * entry_size_w
ent_w: rowptr[IncludesScanner.FileEntry] = (rowptr[IncludesScanner.FileEntry])(t.CVoid(ea_w, t.CPtr))
if ent_w is None or ent_w.Sha1 is None or ent_w.RelPath is None:
continue
@@ -276,7 +276,7 @@ def WriteIncludesSha1Map(mb: rowptr[memhub.MemBuddy], temp_dir: str,
if _is_in_sha1_set(ent_w.Sha1, filter_set, filter_count) == 0:
continue
viperlib.snprintf(line_buf, 512, "%s:includes/%s\n", ent_w.Sha1, ent_w.RelPath)
line_len_w: t.CSizeT = string.strlen(line_buf)
line_len_w: sizet = string.strlen(line_buf)
f.write(line_buf, line_len_w)
written_count += 1
+41 -41
View File
@@ -41,7 +41,7 @@ import lib.Stub.StubMerger as StubMerger
# 与 Phase B+(Phase2.vp 编译缺失 includes 时)的内联判断逻辑一致,
# 供 Phase C 链接时区分"声明文件无需 .obj"与"实现文件缺失"。
# ============================================================
def IsDeclOnlyModule(temp_dir: str, td_len: t.CSizeT, sha1: str) -> int:
def IsDeclOnlyModule(temp_dir: str, td_len: sizet, sha1: str) -> int:
"""判断模块是否为纯声明文件(text.ll 无 define 行)"""
if temp_dir is None or sha1 is None:
return -1
@@ -53,7 +53,7 @@ def IsDeclOnlyModule(temp_dir: str, td_len: t.CSizeT, sha1: str) -> int:
if tf_d.closed:
return -1
tbuf_d: bytes = stdlib.malloc(StubMerger.STUB_READ_BUF_SIZE)
tbr_d: t.CInt64T = 0
tbr_d: int64 = 0
if tbuf_d is not None:
tbr_d = tf_d.read_all(tbuf_d, StubMerger.STUB_READ_BUF_SIZE)
tf_d.close()
@@ -66,14 +66,14 @@ def IsDeclOnlyModule(temp_dir: str, td_len: t.CSizeT, sha1: str) -> int:
if tbr_d < StubMerger.STUB_READ_BUF_SIZE:
tbuf_d[tbr_d] = '\0'
# 逐行扫描:找 "define " 行即为实现文件
tpos_d: t.CSizeT = 0
tpos_d: sizet = 0
while tpos_d < tbr_d:
tls_d: t.CSizeT = tpos_d
tls_d: sizet = tpos_d
while tpos_d < tbr_d:
if tbuf_d[tpos_d] == '\n':
break
tpos_d += 1
tll_d: t.CSizeT = tpos_d - tls_d
tll_d: sizet = tpos_d - tls_d
if tpos_d < tbr_d:
tpos_d += 1
if tll_d >= 7 and string.strncmp(tbuf_d + tls_d, "define ", 7) == 0:
@@ -99,14 +99,14 @@ def _IsFuncDeclaredOrDefined(out_buf: bytes, func_sig: str) -> int:
"""检查 out_buf 中是否已有函数的 declare 或 define 行"""
if out_buf is None or func_sig is None:
return 0
sig_len: t.CSizeT = string.strlen(func_sig)
out_len: t.CSizeT = string.strlen(out_buf)
sig_len: sizet = string.strlen(func_sig)
out_len: sizet = string.strlen(out_buf)
if sig_len == 0 or out_len == 0 or sig_len > out_len:
return 0
pos: t.CSizeT = 0
pos: sizet = 0
for pos in range(0, out_len - sig_len + 1):
if string.strncmp(out_buf + pos, func_sig, sig_len) == 0:
ls: t.CSizeT = pos
ls: sizet = pos
while ls > 0 and out_buf[ls - 1] != '\n':
ls -= 1
if string.strncmp(out_buf + ls, "declare ", 8) == 0:
@@ -125,14 +125,14 @@ def _CommentOutDeclareInBuf(out_buf: bytes, func_sig: str) -> int:
"""在 out_buf 中搜索 declare 行(包含 func_sig),将其注释掉"""
if out_buf is None or func_sig is None:
return 0
sig_len: t.CSizeT = string.strlen(func_sig)
out_len: t.CSizeT = string.strlen(out_buf)
sig_len: sizet = string.strlen(func_sig)
out_len: sizet = string.strlen(out_buf)
if sig_len == 0 or out_len == 0 or sig_len > out_len:
return 0
pos: t.CSizeT = 0
pos: sizet = 0
while pos + sig_len <= out_len:
if string.strncmp(out_buf + pos, func_sig, sig_len) == 0:
ls: t.CSizeT = pos
ls: sizet = pos
while ls > 0 and out_buf[ls - 1] != '\n':
ls -= 1
if string.strncmp(out_buf + ls, "declare ", 8) == 0:
@@ -158,11 +158,11 @@ def _CommentOutGlobalInBuf(out_buf: bytes, global_name: str) -> int:
"""
if out_buf is None or global_name is None:
return 0
name_len: t.CSizeT = string.strlen(global_name)
out_len: t.CSizeT = string.strlen(out_buf)
name_len: sizet = string.strlen(global_name)
out_len: sizet = string.strlen(out_buf)
if name_len == 0 or out_len == 0 or name_len > out_len:
return 0
pos: t.CSizeT = 0
pos: sizet = 0
commented: int = 0
while pos + name_len <= out_len:
if string.strncmp(out_buf + pos, global_name, name_len) == 0:
@@ -181,11 +181,11 @@ def _HasGlobalInBuf(out_buf: bytes, global_name: str) -> int:
"""
if out_buf is None or global_name is None:
return 0
name_len: t.CSizeT = string.strlen(global_name)
out_len: t.CSizeT = string.strlen(out_buf)
name_len: sizet = string.strlen(global_name)
out_len: sizet = string.strlen(out_buf)
if name_len == 0 or out_len == 0 or name_len > out_len:
return 0
pos: t.CSizeT = 0
pos: sizet = 0
while pos + name_len <= out_len:
if string.strncmp(out_buf + pos, global_name, name_len) == 0:
# 确认是行首(前一个是换行或 pos==0)
@@ -209,17 +209,17 @@ def _CommentOutOpaqueTypeInBuf(out_buf: bytes, type_name_prefix: str) -> int:
"""
if out_buf is None or type_name_prefix is None:
return 0
prefix_len: t.CSizeT = string.strlen(type_name_prefix)
out_len: t.CSizeT = string.strlen(out_buf)
prefix_len: sizet = string.strlen(type_name_prefix)
out_len: sizet = string.strlen(out_buf)
if prefix_len == 0 or out_len == 0 or prefix_len > out_len:
return 0
pos: t.CSizeT = 0
pos: sizet = 0
while pos + prefix_len <= out_len:
if string.strncmp(out_buf + pos, type_name_prefix, prefix_len) == 0:
# 确认是行首(前一个是换行或 pos==0)
if pos == 0 or out_buf[pos - 1] == '\n':
# 检查后面是否是 " = type opaque"
p: t.CSizeT = pos + prefix_len
p: sizet = pos + prefix_len
# 跳过空格
while p < out_len and out_buf[p] == ' ':
p += 1
@@ -255,12 +255,12 @@ def _is_submodule_of_imported(deps_buf: str, mod_name: str) -> int:
dot_pos: str = string.strchr(mod_name, 46) # '.' = 46
if dot_pos is None:
return 0
pkg_len: t.CSizeT = t.CSizeT(t.CUInt64T(dot_pos) - t.CUInt64T(mod_name))
pkg_len: sizet = sizet(uint64(dot_pos) - uint64(mod_name))
if pkg_len == 0 or pkg_len >= 256:
return 0
# 构造顶层包名(截断到 '.' 之前)
# 直接在 mod_name 上临时截断检查,避免分配
saved_ch: t.CChar = mod_name[pkg_len]
saved_ch: char = mod_name[pkg_len]
mod_name[pkg_len] = '\0'
result: int = GenApi.is_module_imported(deps_buf, mod_name)
mod_name[pkg_len] = saved_ch
@@ -276,11 +276,11 @@ def _HasFullTypeDefinition(out_buf: bytes, type_name_prefix: str) -> int:
"""检查 out_buf 中是否已有 type_name_prefix 的完整定义"""
if out_buf is None or type_name_prefix is None:
return 0
prefix_len: t.CSizeT = string.strlen(type_name_prefix)
out_len: t.CSizeT = string.strlen(out_buf)
prefix_len: sizet = string.strlen(type_name_prefix)
out_len: sizet = string.strlen(out_buf)
if prefix_len == 0 or out_len == 0 or prefix_len > out_len:
return 0
pos: t.CSizeT = 0
pos: sizet = 0
while pos + prefix_len <= out_len:
if string.strncmp(out_buf + pos, type_name_prefix, prefix_len) == 0:
# 确认是行首(前一个是换行或 pos==0),且未被注释(行首不是 ';')
@@ -291,7 +291,7 @@ def _HasFullTypeDefinition(out_buf: bytes, type_name_prefix: str) -> int:
is_line_start = 1
if is_line_start == 1:
# 检查后面是否是 " = type {" 或 " = type <"
p: t.CSizeT = pos + prefix_len
p: sizet = pos + prefix_len
while p < out_len and out_buf[p] == ' ':
p += 1
if p < out_len and out_buf[p] == '=':
@@ -313,7 +313,7 @@ def _HasFullTypeDefinition(out_buf: bytes, type_name_prefix: str) -> int:
# 返回两个数组(sha1_list 和 mod_list),长度存储在 count 中。
# 所有内存由 stdlib.malloc 分配,调用者负责释放。
# ============================================================
def _BuildIncludesSha1Map(temp_dir: str, td_len: t.CSizeT,
def _BuildIncludesSha1Map(temp_dir: str, td_len: sizet,
sha1_list: str,
mod_list: str) -> int:
"""从全局内存存储器复制 sha1→module_name 映射到调用者数组
@@ -329,10 +329,10 @@ def _BuildIncludesSha1Map(temp_dir: str, td_len: t.CSizeT,
for i in range(StubMerger._sha1_store_count):
if count >= StubMerger.MAX_INCLUDES:
break
idx: t.CSizeT = t.CSizeT(i) * 17
idx2: t.CSizeT = t.CSizeT(i) * 64
string.strcpy(sha1_list + t.CSizeT(count) * 17, StubMerger._sha1_store_arr + idx)
string.strcpy(mod_list + t.CSizeT(count) * 64, StubMerger._sha1_store_mod + idx2)
idx: sizet = sizet(i) * 17
idx2: sizet = sizet(i) * 64
string.strcpy(sha1_list + sizet(count) * 17, StubMerger._sha1_store_arr + idx)
string.strcpy(mod_list + sizet(count) * 64, StubMerger._sha1_store_mod + idx2)
count += 1
return count
# ============================================================
@@ -363,19 +363,19 @@ def _FindSha1ByModName(sha1_arr: str, mod_arr: str,
return None
# 第一遍:精确匹配
for i in range(count):
idx: t.CSizeT = t.CSizeT(i) * 64
idx: sizet = sizet(i) * 64
if string.strcmp(mod_arr + idx, mod_name) == 0:
sidx: t.CSizeT = t.CSizeT(i) * 17
sidx: sizet = sizet(i) * 17
return sha1_arr + sidx
# 第二遍:包名回退("ast" → "ast.__init__")
nm_len: t.CSizeT = string.strlen(mod_name)
nm_len: sizet = string.strlen(mod_name)
init_buf: bytes = stdlib.malloc(nm_len + 12)
if init_buf is not None:
viperlib.snprintf(init_buf, nm_len + 12, "%s.__init__", mod_name)
for i in range(count):
idx2: t.CSizeT = t.CSizeT(i) * 64
idx2: sizet = sizet(i) * 64
if string.strcmp(mod_arr + idx2, init_buf) == 0:
sidx2: t.CSizeT = t.CSizeT(i) * 17
sidx2: sizet = sizet(i) * 17
stdlib.free(init_buf)
return sha1_arr + sidx2
stdlib.free(init_buf)
@@ -398,11 +398,11 @@ def _AddSha1ToSet(set_buf: str, count: int, sha1: str) -> int:
if set_buf is None or sha1 is None:
return count
for i in range(count):
idx: t.CSizeT = t.CSizeT(i) * 17
idx: sizet = sizet(i) * 17
if string.strcmp(set_buf + idx, sha1) == 0:
return count
if count < StubMerger.MAX_INCLUDES_SHA1:
idx: t.CSizeT = t.CSizeT(count) * 17
idx: sizet = sizet(count) * 17
string.strcpy(set_buf + idx, sha1)
return count + 1
return count
+56 -56
View File
@@ -72,17 +72,17 @@ def PopulateSha1MapStore(scan_result: IncludesScanner.ScanResult | t.CPtr) -> in
string.memset(StubMerger._sha1_store_incdir, 0, StubMerger.MAX_INCLUDES * StubMerger.MAX_INC_DIR_LEN)
StubMerger._sha1_store_count = 0
p_bad: int = 0
entry_size_p: t.CSizeT = IncludesScanner.FileEntry.__sizeof__()
entry_size_p: sizet = IncludesScanner.FileEntry.__sizeof__()
for i in range(scan_result.Count):
if StubMerger._sha1_store_count >= StubMerger.MAX_INCLUDES:
VLogger.error("includes SHA1 存储超上限,终止", "StubMerger")
ea: t.CUInt64T = t.CUInt64T(scan_result.Entries) + i * entry_size_p
ea: uint64 = uint64(scan_result.Entries) + i * entry_size_p
ent: IncludesScanner.FileEntry | t.CPtr = (IncludesScanner.FileEntry | t.CPtr)(t.CVoid(ea, t.CPtr))
if ent is None or ent.Sha1 is None or ent.RelPath is None:
p_bad += 1
continue
# 构建完整路径 includes/{RelPath}(_PathToModuleName 需要)
rp_len: t.CSizeT = string.strlen(ent.RelPath)
rp_len: sizet = string.strlen(ent.RelPath)
full_path_buf: bytes = stdlib.malloc(rp_len + 10)
if full_path_buf is None:
p_bad += 1
@@ -91,10 +91,10 @@ def PopulateSha1MapStore(scan_result: IncludesScanner.ScanResult | t.CPtr) -> in
mod_name: str = Utils.PathToModuleName(full_path_buf, 1)
stdlib.free(full_path_buf)
if mod_name is not None:
idx: t.CSizeT = t.CSizeT(StubMerger._sha1_store_count) * 17
idx: sizet = sizet(StubMerger._sha1_store_count) * 17
string.strcpy(StubMerger._sha1_store_arr + idx, ent.Sha1)
idx2: t.CSizeT = t.CSizeT(StubMerger._sha1_store_count) * 64
mn_len: t.CSizeT = string.strlen(mod_name)
idx2: sizet = sizet(StubMerger._sha1_store_count) * 64
mn_len: sizet = string.strlen(mod_name)
if mn_len < 64:
string.strcpy(StubMerger._sha1_store_mod + idx2, mod_name)
else:
@@ -102,16 +102,16 @@ def PopulateSha1MapStore(scan_result: IncludesScanner.ScanResult | t.CPtr) -> in
StubMerger._sha1_store_mod[idx2 + 63] = '\0'
stdlib.free(mod_name)
# 保存 rel_path(供 Phase2 3.5 编译缺失 includes 使用)
idx3: t.CSizeT = t.CSizeT(StubMerger._sha1_store_count) * StubMerger.MAX_REL_PATH_LEN
idx3: sizet = sizet(StubMerger._sha1_store_count) * StubMerger.MAX_REL_PATH_LEN
if rp_len < StubMerger.MAX_REL_PATH_LEN:
string.strcpy(StubMerger._sha1_store_rel + idx3, ent.RelPath)
else:
string.strncpy(StubMerger._sha1_store_rel + idx3, ent.RelPath, StubMerger.MAX_REL_PATH_LEN - 1)
StubMerger._sha1_store_rel[idx3 + StubMerger.MAX_REL_PATH_LEN - 1] = '\0'
# 保存所属 includes 根目录(Phase2 预注册/按需编译拼路径用)
idx_inc: t.CSizeT = t.CSizeT(StubMerger._sha1_store_count) * StubMerger.MAX_INC_DIR_LEN
idx_inc: sizet = sizet(StubMerger._sha1_store_count) * StubMerger.MAX_INC_DIR_LEN
if ent.IncDir is not None:
icd_len: t.CSizeT = string.strlen(ent.IncDir)
icd_len: sizet = string.strlen(ent.IncDir)
if icd_len < StubMerger.MAX_INC_DIR_LEN:
string.strcpy(StubMerger._sha1_store_incdir + idx_inc, ent.IncDir)
else:
@@ -175,18 +175,18 @@ def AppendToSha1MapStore(sha1: str, rel_path: str) -> int:
# LookupSha1ByModName("gfx") 失败 → 后缀匹配劫持到 VKernel 同名 gfx
# (VKernel/Kernel/drivers/video/vesafb/gfx.vp,类 Scene3D 归属错乱根因)。
for i in range(StubMerger._sha1_store_count):
sidx_d: t.CSizeT = t.CSizeT(i) * 17
sidx_d: sizet = sizet(i) * 17
if string.strcmp(StubMerger._sha1_store_arr + sidx_d, sha1) == 0:
midx_d: t.CSizeT = t.CSizeT(i) * 64
midx_d: sizet = sizet(i) * 64
if string.strcmp(StubMerger._sha1_store_mod + midx_d, mod_name) == 0:
stdlib.free(mod_name)
return 0
# 写入 SHA1
idx_a: t.CSizeT = t.CSizeT(StubMerger._sha1_store_count) * 17
idx_a: sizet = sizet(StubMerger._sha1_store_count) * 17
string.strcpy(StubMerger._sha1_store_arr + idx_a, sha1)
# 写入模块名
idx_m: t.CSizeT = t.CSizeT(StubMerger._sha1_store_count) * 64
mn_len: t.CSizeT = string.strlen(mod_name)
idx_m: sizet = sizet(StubMerger._sha1_store_count) * 64
mn_len: sizet = string.strlen(mod_name)
if mn_len < 64:
string.strcpy(StubMerger._sha1_store_mod + idx_m, mod_name)
else:
@@ -194,15 +194,15 @@ def AppendToSha1MapStore(sha1: str, rel_path: str) -> int:
StubMerger._sha1_store_mod[idx_m + 63] = '\0'
stdlib.free(mod_name)
# 写入相对路径
idx_r: t.CSizeT = t.CSizeT(StubMerger._sha1_store_count) * StubMerger.MAX_REL_PATH_LEN
rp_len: t.CSizeT = string.strlen(rel_path)
idx_r: sizet = sizet(StubMerger._sha1_store_count) * StubMerger.MAX_REL_PATH_LEN
rp_len: sizet = string.strlen(rel_path)
if rp_len < StubMerger.MAX_REL_PATH_LEN:
string.strcpy(StubMerger._sha1_store_rel + idx_r, rel_path)
else:
string.strncpy(StubMerger._sha1_store_rel + idx_r, rel_path, StubMerger.MAX_REL_PATH_LEN - 1)
StubMerger._sha1_store_rel[idx_r + StubMerger.MAX_REL_PATH_LEN - 1] = '\0'
# App 源文件不属于任何 includes 目录:IncDir 留空(Phase2 回退 includes_dir 参数)
idx_inc_a: t.CSizeT = t.CSizeT(StubMerger._sha1_store_count) * StubMerger.MAX_INC_DIR_LEN
idx_inc_a: sizet = sizet(StubMerger._sha1_store_count) * StubMerger.MAX_INC_DIR_LEN
StubMerger._sha1_store_incdir[idx_inc_a] = '\0'
StubMerger._sha1_store_count += 1
return 0
@@ -244,34 +244,34 @@ def AddIncludeToSha1MapStore(sha1: str, rel_path: str, inc_dir: str, mod_name: s
return 1
# 去重:SHA1 与模块名都相同才跳过(对齐 AppendToSha1MapStore)
for i in range(StubMerger._sha1_store_count):
sidx_d: t.CSizeT = t.CSizeT(i) * 17
sidx_d: sizet = sizet(i) * 17
if string.strcmp(StubMerger._sha1_store_arr + sidx_d, sha1) == 0:
midx_d: t.CSizeT = t.CSizeT(i) * 64
midx_d: sizet = sizet(i) * 64
if string.strcmp(StubMerger._sha1_store_mod + midx_d, mod_name) == 0:
return 0
# 写 SHA1
idx_a: t.CSizeT = t.CSizeT(StubMerger._sha1_store_count) * 17
idx_a: sizet = sizet(StubMerger._sha1_store_count) * 17
string.strcpy(StubMerger._sha1_store_arr + idx_a, sha1)
# 写模块名
idx_m: t.CSizeT = t.CSizeT(StubMerger._sha1_store_count) * 64
mn_len: t.CSizeT = string.strlen(mod_name)
idx_m: sizet = sizet(StubMerger._sha1_store_count) * 64
mn_len: sizet = string.strlen(mod_name)
if mn_len < 64:
string.strcpy(StubMerger._sha1_store_mod + idx_m, mod_name)
else:
string.strncpy(StubMerger._sha1_store_mod + idx_m, mod_name, 63)
StubMerger._sha1_store_mod[idx_m + 63] = '\0'
# 写相对路径
idx_r: t.CSizeT = t.CSizeT(StubMerger._sha1_store_count) * StubMerger.MAX_REL_PATH_LEN
rp_len: t.CSizeT = string.strlen(rel_path)
idx_r: sizet = sizet(StubMerger._sha1_store_count) * StubMerger.MAX_REL_PATH_LEN
rp_len: sizet = string.strlen(rel_path)
if rp_len < StubMerger.MAX_REL_PATH_LEN:
string.strcpy(StubMerger._sha1_store_rel + idx_r, rel_path)
else:
string.strncpy(StubMerger._sha1_store_rel + idx_r, rel_path, StubMerger.MAX_REL_PATH_LEN - 1)
StubMerger._sha1_store_rel[idx_r + StubMerger.MAX_REL_PATH_LEN - 1] = '\0'
# 写所属 includes 根目录(非空 = includes 条目;App 条目留空)
idx_inc: t.CSizeT = t.CSizeT(StubMerger._sha1_store_count) * StubMerger.MAX_INC_DIR_LEN
idx_inc: sizet = sizet(StubMerger._sha1_store_count) * StubMerger.MAX_INC_DIR_LEN
if inc_dir is not None:
icd_len: t.CSizeT = string.strlen(inc_dir)
icd_len: sizet = string.strlen(inc_dir)
if icd_len < StubMerger.MAX_INC_DIR_LEN:
string.strcpy(StubMerger._sha1_store_incdir + idx_inc, inc_dir)
else:
@@ -317,34 +317,34 @@ def LookupSha1ByModNameSuffix(mod_suffix: str) -> str:
return None
if StubMerger._sha1_store_count <= 0:
return None
suffix_len_sf: t.CSizeT = string.strlen(mod_suffix)
suffix_len_sf: sizet = string.strlen(mod_suffix)
if suffix_len_sf == 0:
return None
i_sf: int
for i_sf in range(StubMerger._sha1_store_count):
idx_sf: t.CSizeT = t.CSizeT(i_sf) * 64
idx_sf: sizet = sizet(i_sf) * 64
mod_name_sf: str = StubMerger._sha1_store_mod + idx_sf
mod_len_sf: t.CSizeT = string.strlen(mod_name_sf)
mod_len_sf: sizet = string.strlen(mod_name_sf)
if mod_len_sf == 0:
continue
# 精确匹配
if mod_len_sf == suffix_len_sf:
if string.strcmp(mod_name_sf, mod_suffix) == 0:
sidx_sf: t.CSizeT = t.CSizeT(i_sf) * 17
sidx_sf: sizet = sizet(i_sf) * 17
return StubMerger._sha1_store_arr + sidx_sf
# 后缀匹配:mod_name 以 "." + mod_suffix 结尾
if mod_len_sf > suffix_len_sf:
if mod_name_sf[mod_len_sf - suffix_len_sf - 1] == '.':
cmp_start_sf: str = mod_name_sf + mod_len_sf - suffix_len_sf
if string.strcmp(cmp_start_sf, mod_suffix) == 0:
sidx2_sf: t.CSizeT = t.CSizeT(i_sf) * 17
sidx2_sf: sizet = sizet(i_sf) * 17
return StubMerger._sha1_store_arr + sidx2_sf
# 反向后缀匹配:mod_suffix 以 "." + mod_name 结尾
if suffix_len_sf > mod_len_sf:
if mod_suffix[suffix_len_sf - mod_len_sf - 1] == '.':
cmp_start_rev_sf: str = mod_suffix + suffix_len_sf - mod_len_sf
if string.strcmp(cmp_start_rev_sf, mod_name_sf) == 0:
sidx_rev_sf: t.CSizeT = t.CSizeT(i_sf) * 17
sidx_rev_sf: sizet = sizet(i_sf) * 17
return StubMerger._sha1_store_arr + sidx_rev_sf
return None
# ============================================================
@@ -361,11 +361,11 @@ def LookupSha1ByAlias(from_imports: str, alias: str) -> str:
"""从 from_imports 别名映射解析模块 SHA1(改名别名 import X as Y 场景)"""
if from_imports is None or alias is None:
return None
alias_len: t.CSizeT = string.strlen(alias)
alias_len: sizet = string.strlen(alias)
if alias_len == 0:
return None
total_len: t.CSizeT = string.strlen(from_imports)
ci: t.CSizeT = 0
total_len: sizet = string.strlen(from_imports)
ci: sizet = 0
while ci < total_len:
# 跳过前导空格
while ci < total_len and from_imports[ci] == ' ':
@@ -373,14 +373,14 @@ def LookupSha1ByAlias(from_imports: str, alias: str) -> str:
if ci >= total_len:
break
# 条目起点 ci,找 ':'(local_name 结束)
colon: t.CSizeT = ci
colon: sizet = ci
while colon < total_len and from_imports[colon] != ':' and from_imports[colon] != ' ':
colon += 1
local_len: t.CSizeT = colon - ci
local_len: sizet = colon - ci
if colon < total_len and from_imports[colon] == ':' and local_len == alias_len:
# 比较 local_name == alias
match: int = 1
li: t.CSizeT = 0
li: sizet = 0
while li < alias_len:
if from_imports[ci + li] != alias[li]:
match = 0
@@ -388,8 +388,8 @@ def LookupSha1ByAlias(from_imports: str, alias: str) -> str:
li += 1
if match == 1:
# 提取 module(colon+1 到下一个 ':' 或空格)
m_start: t.CSizeT = colon + 1
m_end: t.CSizeT = m_start
m_start: sizet = colon + 1
m_end: sizet = m_start
while m_end < total_len and from_imports[m_end] != ':' and from_imports[m_end] != ' ':
m_end += 1
if m_end > m_start:
@@ -419,11 +419,11 @@ def LookupModNameByAlias(from_imports: str, alias: str) -> str:
"""从 from_imports 别名映射解析模块真名(import X as Y → Y:X)"""
if from_imports is None or alias is None:
return None
alias_len: t.CSizeT = string.strlen(alias)
alias_len: sizet = string.strlen(alias)
if alias_len == 0:
return None
total_len: t.CSizeT = string.strlen(from_imports)
ci: t.CSizeT = 0
total_len: sizet = string.strlen(from_imports)
ci: sizet = 0
while ci < total_len:
# 跳过前导空格
while ci < total_len and from_imports[ci] == ' ':
@@ -431,14 +431,14 @@ def LookupModNameByAlias(from_imports: str, alias: str) -> str:
if ci >= total_len:
break
# 条目起点 ci,找 ':'(local_name 结束)
colon: t.CSizeT = ci
colon: sizet = ci
while colon < total_len and from_imports[colon] != ':' and from_imports[colon] != ' ':
colon += 1
local_len: t.CSizeT = colon - ci
local_len: sizet = colon - ci
if colon < total_len and from_imports[colon] == ':' and local_len == alias_len:
# 比较 local_name == alias
match: int = 1
li: t.CSizeT = 0
li: sizet = 0
while li < alias_len:
if from_imports[ci + li] != alias[li]:
match = 0
@@ -446,8 +446,8 @@ def LookupModNameByAlias(from_imports: str, alias: str) -> str:
li += 1
if match == 1:
# 提取 module(colon+1 到下一个 ':' 或空格)
m_start: t.CSizeT = colon + 1
m_end: t.CSizeT = m_start
m_start: sizet = colon + 1
m_end: sizet = m_start
while m_end < total_len and from_imports[m_end] != ':' and from_imports[m_end] != ' ':
m_end += 1
if m_end > m_start:
@@ -491,16 +491,16 @@ def PopulateIncludesDeps(sha1: str, deps_str: str) -> int:
return 1
# 去重:若 SHA1 已存在则跳过
for i in range(StubMerger._includes_deps_count):
sidx: t.CSizeT = t.CSizeT(i) * 17
sidx: sizet = sizet(i) * 17
if string.strcmp(StubMerger._includes_deps_sha1 + sidx, sha1) == 0:
return 0
# 写入 SHA1
idx: t.CSizeT = t.CSizeT(StubMerger._includes_deps_count) * 17
idx: sizet = sizet(StubMerger._includes_deps_count) * 17
string.strcpy(StubMerger._includes_deps_sha1 + idx, sha1)
# 写入依赖字符串
idx2: t.CSizeT = t.CSizeT(StubMerger._includes_deps_count) * StubMerger.MAX_DEPS_STR_LEN
idx2: sizet = sizet(StubMerger._includes_deps_count) * StubMerger.MAX_DEPS_STR_LEN
if deps_str is not None:
dl: t.CSizeT = string.strlen(deps_str)
dl: sizet = string.strlen(deps_str)
if dl < StubMerger.MAX_DEPS_STR_LEN:
string.strcpy(StubMerger._includes_deps_str + idx2, deps_str)
else:
@@ -525,9 +525,9 @@ def LookupIncludesDeps(sha1: str) -> str:
if StubMerger._includes_deps_count <= 0:
return None
for i in range(StubMerger._includes_deps_count):
sidx: t.CSizeT = t.CSizeT(i) * 17
sidx: sizet = sizet(i) * 17
if string.strcmp(StubMerger._includes_deps_sha1 + sidx, sha1) == 0:
idx2: t.CSizeT = t.CSizeT(i) * StubMerger.MAX_DEPS_STR_LEN
idx2: sizet = sizet(i) * StubMerger.MAX_DEPS_STR_LEN
return StubMerger._includes_deps_str + idx2
return None
def GetSha1StoreArrPtr() -> bytes:
@@ -590,8 +590,8 @@ def LookupSha1RelPath(sha1: str) -> str:
if StubMerger._sha1_store_arr is None or StubMerger._sha1_store_rel is None:
return None
for i in range(StubMerger._sha1_store_count):
sidx: t.CSizeT = t.CSizeT(i) * 17
sidx: sizet = sizet(i) * 17
if string.strcmp(StubMerger._sha1_store_arr + sidx, sha1) == 0:
ridx: t.CSizeT = t.CSizeT(i) * StubMerger.MAX_REL_PATH_LEN
ridx: sizet = sizet(i) * StubMerger.MAX_REL_PATH_LEN
return StubMerger._sha1_store_rel + ridx
return None
+17 -17
View File
@@ -57,13 +57,13 @@ import lib.Stub.StubMerger as StubMerger
def BuildTopoSortedIndices(store_count: int, store_sha1_arr: bytes,
store_mod_arr: bytes, reachable_set: bytes,
reachable_count: int,
sorted_idx: t.CSizeT | t.CPtr) -> int:
sorted_idx: sizet | t.CPtr) -> 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: t.CSizeT | t.CPtr = (t.CSizeT | t.CPtr)(stdlib.malloc(8 * (store_count + 1)))
queue: t.CSizeT | t.CPtr = (t.CSizeT | t.CPtr)(stdlib.malloc(8 * (store_count + 1)))
rel_idx: t.CSizeT | t.CPtr = (t.CSizeT | t.CPtr)(stdlib.malloc(8 * (store_count + 1)))
indegree: sizet | t.CPtr = (sizet | t.CPtr)(stdlib.malloc(8 * (store_count + 1)))
queue: sizet | t.CPtr = (sizet | t.CPtr)(stdlib.malloc(8 * (store_count + 1)))
rel_idx: sizet | t.CPtr = (sizet | t.CPtr)(stdlib.malloc(8 * (store_count + 1)))
if indegree is None or queue is None or rel_idx is None:
if indegree is not None:
stdlib.free(indegree)
@@ -87,7 +87,7 @@ def BuildTopoSortedIndices(store_count: int, store_sha1_arr: bytes,
rel_count += 1
else:
for i_t in range(store_count):
if StubMergerCollect._is_in_sha1_set(store_sha1_arr + t.CSizeT(i_t) * 17, reachable_set, reachable_count) != 0:
if StubMergerCollect._is_in_sha1_set(store_sha1_arr + sizet(i_t) * 17, reachable_set, reachable_count) != 0:
rel_idx[rel_count] = i_t
rel_count += 1
# 诊断:可达 store 索引数(rel_count=0 → topo_count=0 → PhaseB+ 循环不执行)
@@ -96,16 +96,16 @@ def BuildTopoSortedIndices(store_count: int, store_sha1_arr: bytes,
i_r: int
for i_r in range(rel_count):
si: int = rel_idx[i_r]
deps_si: str = StubMergerStore.LookupIncludesDeps(store_sha1_arr + t.CSizeT(si) * 17)
deps_si: str = StubMergerStore.LookupIncludesDeps(store_sha1_arr + sizet(si) * 17)
if deps_si is None:
continue
dl_si: t.CSizeT = string.strlen(deps_si)
dpos: t.CSizeT = 0
dl_si: sizet = string.strlen(deps_si)
dpos: sizet = 0
while dpos < dl_si:
dstart: t.CSizeT = dpos
dstart: sizet = dpos
while dpos < dl_si and deps_si[dpos] != ' ':
dpos += 1
dlen: t.CSizeT = dpos - dstart
dlen: sizet = dpos - dstart
if dpos < dl_si:
dpos += 1
if dlen == 0:
@@ -139,23 +139,23 @@ def BuildTopoSortedIndices(store_count: int, store_sha1_arr: bytes,
sorted_idx[out_count] = m
out_count += 1
# 对依赖 m 的可达模块减入度
mod_m: str = store_mod_arr + t.CSizeT(m) * 64
mod_m_len: t.CSizeT = string.strlen(mod_m)
mod_m: str = store_mod_arr + sizet(m) * 64
mod_m_len: sizet = string.strlen(mod_m)
for i_r in range(rel_count):
si3: int = rel_idx[i_r]
if indegree[si3] == 0:
continue
deps_si3: str = StubMergerStore.LookupIncludesDeps(store_sha1_arr + t.CSizeT(si3) * 17)
deps_si3: str = StubMergerStore.LookupIncludesDeps(store_sha1_arr + sizet(si3) * 17)
if deps_si3 is None:
continue
dl_si3: t.CSizeT = string.strlen(deps_si3)
dpos3: t.CSizeT = 0
dl_si3: sizet = string.strlen(deps_si3)
dpos3: sizet = 0
found_dep: int = 0
while dpos3 < dl_si3 and found_dep == 0:
dstart3: t.CSizeT = dpos3
dstart3: sizet = dpos3
while dpos3 < dl_si3 and deps_si3[dpos3] != ' ':
dpos3 += 1
dlen3: t.CSizeT = dpos3 - dstart3
dlen3: sizet = dpos3 - dstart3
if dpos3 < dl_si3:
dpos3 += 1
if dlen3 == 0:
+70 -70
View File
@@ -64,7 +64,7 @@ class AssignGenMixin:
# 4. Call — 如 t.CUnsignedLong(-11) → 取第一个参数
# 5. UnaryOp(USub/UAdd/Invert) — 如 -11
# ============================================================
def extract_cdefine_int_value(self, val_node: ast.AST | t.CPtr) -> t.CInt64T:
def extract_cdefine_int_value(self, val_node: ast.AST | t.CPtr) -> int64:
"""从值节点提取整数常量(支持 Constant/BinOp/Name/Call/UnaryOp)
64 位返回:大整数 CDefine(如 sys.maxsize=9223372036854775807)
@@ -89,8 +89,8 @@ class AssignGenMixin:
# Case 2: BinOp — 如 FOREGROUND_RED | FOREGROUND_GREEN、(1 << ZDEFLATE_WINDOW_BITS)
if k == ast.ASTKind.BinOp:
bop: ast.BinOp | t.CPtr = (ast.BinOp | t.CPtr)(val_node)
left_val: t.CInt64T = self.extract_cdefine_int_value(bop.left)
right_val: t.CInt64T = self.extract_cdefine_int_value(bop.right)
left_val: int64 = self.extract_cdefine_int_value(bop.left)
right_val: int64 = self.extract_cdefine_int_value(bop.right)
if bop.op == ast.OpKind.BitOr: return left_val | right_val
if bop.op == ast.OpKind.BitAnd: return left_val & right_val
if bop.op == ast.OpKind.BitXor: return left_val ^ right_val
@@ -114,7 +114,7 @@ class AssignGenMixin:
return 1
if string.strcmp(nm.id, "False") == 0:
return 0
looked_up: t.CInt64T = self.Gen.TypeGenCDef.lookup_cdefine_constant(nm.id)
looked_up: int64 = self.Gen.TypeGenCDef.lookup_cdefine_constant(nm.id)
if self.Gen.TypeGenCDef.is_cdefine_found() != 0:
return looked_up
# 引用未注册:直接报错终止(fail-fast)
@@ -128,7 +128,7 @@ class AssignGenMixin:
cl_args_list: list[ast.AST | t.CPtr] | t.CPtr = cl.args
if cl_args_list is not None and len(cl_args_list) > 0:
first_arg: ast.AST | t.CPtr = cl_args_list.get(0)
arg_val: t.CInt64T = self.extract_cdefine_int_value(first_arg)
arg_val: int64 = self.extract_cdefine_int_value(first_arg)
return arg_val
# Call 无参数:直接报错终止(fail-fast)
self.Gen.TypeGenErr.fatal_error(val_node, "CDefine 值提取失败:无法从表达式解析编译期常量", "TypeError")
@@ -136,7 +136,7 @@ class AssignGenMixin:
# Case 5: UnaryOp — 如 -11
if k == ast.ASTKind.UnaryOp:
uop: ast.UnaryOp | t.CPtr = (ast.UnaryOp | t.CPtr)(val_node)
operand_val: t.CInt64T = self.extract_cdefine_int_value(uop.operand)
operand_val: int64 = self.extract_cdefine_int_value(uop.operand)
if uop.op == ast.OpKind.USub: return -operand_val
if uop.op == ast.OpKind.UAdd: return operand_val
if uop.op == ast.OpKind.Invert: return ~operand_val
@@ -196,7 +196,7 @@ class AssignGenMixin:
# CDefine 声明缺少值节点:直接报错终止(fail-fast)
self.Gen.TypeGenErr.fatal_error(None, f"CDefine 值提取失败:'{name}' 缺少初始值", "TypeError")
return
val_fp: t.CInt64T = self.extract_cdefine_int_value(val_node)
val_fp: int64 = self.extract_cdefine_int_value(val_node)
self.Gen.TypeGenCDef.register_cdefine_constant(pool, name, val_fp)
# ============================================================
@@ -230,7 +230,7 @@ class AssignGenMixin:
f: fileio.File | t.CPtr = fileio.File(fp, fileio.MODE.R)
if f.closed:
return 0
BUF_SZ: t.CSizeT = 1048576
BUF_SZ: sizet = 1048576
buf: bytes = stdlib.malloc(BUF_SZ)
if buf is None:
f.close()
@@ -243,14 +243,14 @@ class AssignGenMixin:
if nrd < BUF_SZ:
buf[nrd] = 0
name_len: t.CSizeT = string.strlen(name)
total_len: t.CSizeT = string.strlen(buf)
pos: t.CSizeT = 0
name_len: sizet = string.strlen(name)
total_len: sizet = string.strlen(buf)
pos: sizet = 0
while pos < total_len:
line_start: t.CSizeT = pos
line_start: sizet = pos
while pos < total_len and buf[pos] != '\n':
pos += 1
line_len: t.CSizeT = pos - line_start
line_len: sizet = pos - line_start
if pos < total_len:
pos += 1
@@ -259,14 +259,14 @@ class AssignGenMixin:
if line_len < name_len + 1:
continue
match_ok: int = 1
ki: t.CSizeT
ki: sizet
for ki in range(name_len):
if buf[line_start + ki] != name[ki]:
match_ok = 0
break
if match_ok == 0:
continue
sep: t.CSizeT = line_start + name_len
sep: sizet = line_start + name_len
while sep < line_start + line_len and buf[sep] == ' ':
sep += 1
if sep >= line_start + line_len:
@@ -277,7 +277,7 @@ class AssignGenMixin:
# CDefine 路径要求行内出现 "t.CDefine";普通浮点全局路径跳过该检查
if require_cdefine != 0:
has_cd: int = 0
ci: t.CSizeT = line_start + name_len + 1
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
@@ -289,7 +289,7 @@ class AssignGenMixin:
continue
# 找 '='
eq: t.CSizeT = line_start
eq: sizet = line_start
while eq < line_start + line_len and buf[eq] != '=':
eq += 1
if eq >= line_start + line_len:
@@ -304,16 +304,16 @@ class AssignGenMixin:
# 之类前缀,从括号内首个数字/符号/'.' 起取值。
# 裸字面量(3.14 / -1.5,首字符已是数字/符号/'.')不受影响。
if eq < line_start + line_len:
c0_rf: t.CChar = buf[eq]
c0_rf: char = buf[eq]
if not ((c0_rf >= '0' and c0_rf <= '9') or c0_rf == '-' or c0_rf == '+' or c0_rf == '.'):
pfx_rf: t.CSizeT = eq
pfx_rf: sizet = eq
while pfx_rf < line_start + line_len:
cp_rf: t.CChar = buf[pfx_rf]
cp_rf: char = buf[pfx_rf]
if (cp_rf >= '0' and cp_rf <= '9') or cp_rf == '.' or cp_rf == '-' or cp_rf == '+':
eq = pfx_rf
break
pfx_rf += 1
val_start: t.CSizeT = eq
val_start: sizet = eq
while eq < line_start + line_len and buf[eq] != ' ' and buf[eq] != '\t' \
and buf[eq] != '#' and buf[eq] != '\r' and buf[eq] != '\n':
eq += 1
@@ -324,7 +324,7 @@ class AssignGenMixin:
if val_txt is None:
stdlib.free(buf)
return 0
vi: t.CSizeT
vi: sizet
for vi in range(eq - val_start):
val_txt[vi] = buf[val_start + vi]
val_txt[eq - val_start] = 0
@@ -377,7 +377,7 @@ class AssignGenMixin:
#
# 规则:
# bytes|t.CPtr / str|t.CPtr → i8**(8 字节步长)→ 返回 1
# t.CChar|t.CPtr / t.CInt8T|t.CPtr → i8*(1 字节步长)→ 返回 0
# char|t.CPtr / int8|t.CPtr → i8*(1 字节步长)→ 返回 0
# 纯 bytes / str → i8*(1 字节步长)→ 返回 0
#
# 注: 注解中的 "|" 是"和"的意思(组合类型),非右值中的位或运算
@@ -435,7 +435,7 @@ class AssignGenMixin:
llvmlite 类型非 canonical:Ptr/Struct 每次构造都 pool.alloc 新实例
(includes/llvmlite/__types.vp),同类型不同实例地址不同。
此前绑定分支用 t.CUInt64T(ta) == t.CUInt64T(tb)(地址比较)判定相等,
此前绑定分支用 uint64(ta) == uint64(tb)(地址比较)判定相等,
对象构造 X = T() 的 rhs 类型实例(CallGenCtor 的 struct_ty)与 storage
类型实例(handle_module_level_var 的 resolved_stg_ty)不同 → 绑定失败
→ 构造结果落栈 alloca 并 store 栈地址到全局(悬垂),storage 保持零
@@ -445,7 +445,7 @@ class AssignGenMixin:
if ta is None or tb is None:
return 0
# 快路径:同一实例直接相等
if t.CUInt64T(ta) == t.CUInt64T(tb):
if uint64(ta) == uint64(tb):
return 1
buf_a: str = pool.alloc(256)
buf_b: str = pool.alloc(256)
@@ -523,11 +523,11 @@ class AssignGenMixin:
if ty_name is None:
return 0
# [FIX 2026-08-31] 前缀归一化:剥离 "t."/"c." 内建命名空间前缀,使
# "t.CInt" 与裸名 "CInt" 判定一致。泛型实参经 _norm_type_arg_name 规则 3
# 保留 "t." 前缀(list[t.CInt] 的 T → "t.CInt"),不剥离则 _is_scalar_ty_name
# "int" 与裸名 "CInt" 判定一致。泛型实参经 _norm_type_arg_name 规则 3
# 保留 "t." 前缀(list[int] 的 T → "int"),不剥离则 _is_scalar_ty_name
# 匹配不到白名单裸名 "CInt" → 误判为非标量 → _is_ptr_element_annotation 返回
# 1(8 字节指针槽)→ _list.vp elem_ptr[0]=item 的 GEP 元素类型退化为指针 →
# 整数存指针误报 CastError(ast/base.vp L391 list[t.CInt] 根因)。
# 整数存指针误报 CastError(ast/base.vp L391 list[int] 根因)。
if ty_name[0] == 't' and ty_name[1] == '.':
ty_name += 2
elif ty_name[0] == 'c' and ty_name[1] == '.':
@@ -599,7 +599,7 @@ class AssignGenMixin:
nm_tp: ast.Name | t.CPtr = (ast.Name | t.CPtr)(node)
if nm_tp.id is None:
return 0
tp_len: t.CSizeT = string.strlen(nm_tp.id)
tp_len: sizet = string.strlen(nm_tp.id)
if tp_len == 1:
if nm_tp.id[0] >= 65 and nm_tp.id[0] <= 90:
return 1
@@ -654,7 +654,7 @@ class AssignGenMixin:
if lst is None or lst.elts is None:
return 1
elts: list[ast.AST | t.CPtr] | t.CPtr = lst.elts
elts_count: t.CSizeT = len(elts)
elts_count: sizet = len(elts)
# 特例:单个字符串字面量初始化字符数组([N x i8],N = strlen+1)
# 逐字节写入字符串内容;调用方已先 store zeroinitializer,末字节 NUL 由零保持。
@@ -665,13 +665,13 @@ class AssignGenMixin:
if c0_s.const_kind == ast.CONST_STR:
sv_s: str = ast.constant_get_str_val(c0_s)
if sv_s is not None:
n_s: t.CSizeT = string.strlen(sv_s)
if t.CSizeT(arr_count) < n_s:
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")
bi_s: t.CSizeT = 0
bi_s: sizet = 0
while bi_s < n_s:
bidx_s: llvmlite.Value | t.CPtr = llvmlite.const_int32(pool, bi_s)
bp_s: llvmlite.Value | t.CPtr = llvmlite.build_gep_array(
@@ -686,7 +686,7 @@ class AssignGenMixin:
return 0
# 元素数超过声明长度 → fail-fast(否则会生成 idx>=N 的越界 GEP 写)
if arr_count > 0 and t.CSizeT(arr_count) < elts_count:
if arr_count > 0 and sizet(arr_count) < elts_count:
self.Gen.TypeGenErr.fatal_error(
list_node,
f"数组初始化元素数 {elts_count} 超过数组声明长度 {arr_count},不允许越界写入",
@@ -779,7 +779,7 @@ class AssignGenMixin:
elif rhs_bits > lhs_bits and lhs_bits > 0:
lhs = self.Gen.ExprGenBase.coerce_to_type(builder, lhs, rhs.Ty, node, trans)
# 无符号操作数(如 u_num_l: t.CUInt64T 的 //= / %=)→ udiv/urem。
# 无符号操作数(如 u_num_l: uint64 的 //= / %=)→ udiv/urem。
# 此前一律 sdiv/srem(translate_binop 的 Div/Mod 已修,但 AugAssign 走本
# 函数独立发射 → viperlib %lu/%lx 的 //= 仍为 sdiv,T3 未覆盖根因)。
aug_unsigned: int = 0
@@ -1109,7 +1109,7 @@ class AssignGenMixin:
cnt_arr: int = 0
if lst_arr.elts is not None:
cnt_arr = len(lst_arr.elts)
# 特例:单个字符串字面量(如 hex_digits: t.CArray[t.CChar, None] = ["0123.."])
# 特例:单个字符串字面量(如 hex_digits: t.CArray[char, None] = ["0123.."])
# 语义是"以字符串内容初始化字符数组",长度应取 strlen+1(含结尾 NUL),
# 而不是列表元素个数 1——否则 alloca [1 x i8] 且只写首字节 → 下标 0..15 越界读。
if elem_ty_arr is not None and cnt_arr == 1 and lst_arr.elts is not None:
@@ -1146,7 +1146,7 @@ class AssignGenMixin:
ann_txt_x = "?"
btd_nm_x: str = self.Gen.TypeGenCType.LastBuiltinsTypedefName
btd_rs_x: str = self.Gen.TypeGenCType.LastBuiltinsTypedefResult
msg_len: t.CSizeT = 640
msg_len: sizet = 640
msg_buf: str = stdlib.malloc(msg_len)
if msg_buf is None:
return ann_txt_x
@@ -1364,7 +1364,7 @@ class AssignGenMixin:
self._register_cdefine_from_value(pool_cd, nm.id, aa.value)
return 0
# CTypedef 注解: 类型别名(mode_t: t.CTypedef = t.CUInt32T 等)。
# CTypedef 注解: 类型别名(mode_t: t.CTypedef = uint32 等)。
# 翻译期 CTypedef 表已被 clear_ctypedefs 清空(每文件隔离;表字符串
# pool 分配,reset_to(mark1) 回收后悬空,不能跨文件累积),必须在此
# 按需注册,否则 posix.vp S_ISREG(mode: mode_t) 等普通函数参数注解
@@ -1432,9 +1432,9 @@ class AssignGenMixin:
# 对象类全局(有静态 storage):对象构造/赋值 → 绑定 storage + 复制对象
stg_ref_aa: llvmlite.Value | t.CPtr = None
if nm.id is not None:
stg_key_aa: str = pool.alloc(t.CSizeT(string.strlen(nm.id)) + 8)
stg_key_aa: str = pool.alloc(sizet(string.strlen(nm.id)) + 8)
if stg_key_aa is not None:
viperlib.snprintf(stg_key_aa, t.CSizeT(string.strlen(nm.id)) + 8, "%s.__stg", nm.id)
viperlib.snprintf(stg_key_aa, sizet(string.strlen(nm.id)) + 8, "%s.__stg", nm.id)
stg_ref_aa = self.Gen.VarGen.lookup_module_var(trans.SymTab, stg_key_aa)
if self._is_addrlike_call(aa.value) == 0 \
and stg_ref_aa is not None and rhs_val.Ty is not None \
@@ -1517,9 +1517,9 @@ class AssignGenMixin:
# 对象类全局(有静态 storage):对象构造/赋值 → 绑定 storage + 复制对象
stg_ref_mg: llvmlite.Value | t.CPtr = None
if nm.id is not None:
stg_key_mg: str = pool.alloc(t.CSizeT(string.strlen(nm.id)) + 8)
stg_key_mg: str = pool.alloc(sizet(string.strlen(nm.id)) + 8)
if stg_key_mg is not None:
viperlib.snprintf(stg_key_mg, t.CSizeT(string.strlen(nm.id)) + 8, "%s.__stg", nm.id)
viperlib.snprintf(stg_key_mg, sizet(string.strlen(nm.id)) + 8, "%s.__stg", nm.id)
stg_ref_mg = self.Gen.VarGen.lookup_module_var(trans.SymTab, stg_key_mg)
if self._is_addrlike_call(aa.value) == 0 \
and stg_ref_mg is not None and rhs_val_mg.Ty is not None \
@@ -1563,7 +1563,7 @@ class AssignGenMixin:
f"无法为变量 {nm.id} 创建存储",
"TypeError")
# FakeDuck: str 变量创建影子结构体 {var}__meta__(per-instance 字段存储)
# 仅裸 str 注解(Name("str"))且 _str 已注册时创建;bytes / t.CChar|t.CPtr 不创建。
# 仅裸 str 注解(Name("str"))且 _str 已注册时创建;bytes / char|t.CPtr 不创建。
# a 保持为 i8*(可 printf/len),a__meta__ 存 __data__/__mbuddy__ 等字段,
# 属性读写(fd3)与方法调用(fd5)均通过该影子解析。
fd_str_ty: llvmlite.LLVMType | t.CPtr = None
@@ -1639,7 +1639,7 @@ class AssignGenMixin:
# 局部数组:列表字面量 → 逐元素 GEP + store 初始化
# 修复:此前局部 CArray[...] = [x, y] 会走 translate_list_literal,
# 错误触发 list[T] 泛型特化(堆对象)导致崩溃(如 this.vp 的
# t.CArray[t.CChar, 256] = [0])。局部 alloca 未零初始化,
# t.CArray[char, 256] = [0])。局部 alloca 未零初始化,
# 先整体置零再写列表元素(与全局数组默认零初始化语义一致)。
local_arr_ty: llvmlite.LLVMType | t.CPtr = None
if aa.value.kind() == ast.ASTKind.List and alloca.Ty is not None:
@@ -1692,7 +1692,7 @@ class AssignGenMixin:
if precise_rhs_ty is not None and alloca.Ty is not None:
alloca_pt: llvmlite.LLVMType | t.CPtr = alloca.Ty.Pointee
if alloca_pt is not None and \
t.CUInt64T(alloca_pt) != t.CUInt64T(precise_rhs_ty):
uint64(alloca_pt) != uint64(precise_rhs_ty):
new_alloca: llvmlite.Value | t.CPtr = self.Gen.VarGen._alloca_at_entry(
builder, precise_rhs_ty)
if new_alloca is not None:
@@ -1812,7 +1812,7 @@ class AssignGenMixin:
if asgn.value is not None:
sha1: str = trans.ModuleSha1
val_kind: int = asgn.value.kind()
val_line: t.CInt = asgn.value.lineno
val_line: int = asgn.value.lineno
# 通过 sha1 查找文件名(人类可读)
rel_path: str = None
if sha1 is not None:
@@ -1857,7 +1857,7 @@ class AssignGenMixin:
return 0
new_vars: int = 0
tn: t.CSizeT = len(targets)
tn: sizet = len(targets)
for ti in range(tn):
target: ast.AST | t.CPtr = targets.get(ti)
if target is None:
@@ -1876,13 +1876,13 @@ class AssignGenMixin:
continue
match rhs_val.Ty:
case llvmlite.LLVMType.Struct(_, _, _):
tgt_n: t.CSizeT = len(tgt_elts)
tgt_n: sizet = len(tgt_elts)
tmp_s: llvmlite.Value | t.CPtr = llvmlite.build_alloca(builder, rhs_val.Ty)
if tmp_s is not None:
llvmlite.build_store(builder, rhs_val, tmp_s)
fchain: llvmlite.ParamNode | t.CPtr = llvmlite.get_struct_fields(rhs_val.Ty)
fcur: llvmlite.ParamNode | t.CPtr = fchain
fti: t.CSizeT
fti: sizet
for fti in range(tgt_n):
tgt_elt: ast.AST | t.CPtr = tgt_elts.get(fti)
if tgt_elt is None or fcur is None:
@@ -1976,10 +1976,10 @@ class AssignGenMixin:
key_val_set: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
builder, pool, mod, sub_asgn.slice, None, 0, trans)
if key_val_set is not None:
arg_vals_set: t.CSizeT | t.CPtr = pool.alloc(16)
arg_vals_set: sizet | t.CPtr = pool.alloc(16)
if arg_vals_set is not None:
arg_vals_set[0] = t.CSizeT(key_val_set)
arg_vals_set[1] = t.CSizeT(rhs_val)
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)
@@ -2009,10 +2009,10 @@ class AssignGenMixin:
key_val_attr: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
builder, pool, mod, sub_asgn.slice, None, 0, trans)
if key_val_attr is not None:
arg_vals_attr: t.CSizeT | t.CPtr = pool.alloc(16)
arg_vals_attr: sizet | t.CPtr = pool.alloc(16)
if arg_vals_attr is not None:
arg_vals_attr[0] = t.CSizeT(key_val_attr)
arg_vals_attr[1] = t.CSizeT(rhs_val)
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)
@@ -2036,10 +2036,10 @@ class AssignGenMixin:
pool, obj_val_gen.Ty.Pointee)
if cls_nm_gen is not None:
# 自定义结构体: 调用 __setitem__
arg_vals_gen: t.CSizeT | t.CPtr = pool.alloc(16)
arg_vals_gen: sizet | t.CPtr = pool.alloc(16)
if arg_vals_gen is not None:
arg_vals_gen[0] = t.CSizeT(key_val_gen)
arg_vals_gen[1] = t.CSizeT(rhs_val)
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)
@@ -2175,9 +2175,9 @@ class AssignGenMixin:
# 全局保持 NULL(页 0 混叠根因,见 TranslatorGenMixin storage 逻辑)。
stg_ref_as: llvmlite.Value | t.CPtr = None
if nm.id is not None:
stg_key_as: str = pool.alloc(t.CSizeT(string.strlen(nm.id)) + 8)
stg_key_as: str = pool.alloc(sizet(string.strlen(nm.id)) + 8)
if stg_key_as is not None:
viperlib.snprintf(stg_key_as, t.CSizeT(string.strlen(nm.id)) + 8, "%s.__stg", nm.id)
viperlib.snprintf(stg_key_as, sizet(string.strlen(nm.id)) + 8, "%s.__stg", nm.id)
stg_ref_as = self.Gen.VarGen.lookup_module_var(trans.SymTab, stg_key_as)
if self._is_addrlike_call(asgn.value) == 0 \
and stg_ref_as is not None and rhs_val is not None and rhs_val.Ty is not None \
@@ -2425,20 +2425,20 @@ class AssignGenMixin:
"""从返回注解文本提取已注册结构体类名,无命中返回 None"""
if pool is None or annot is None:
return None
alen: t.CSizeT = string.strlen(annot)
alen: sizet = string.strlen(annot)
if alen == 0:
return None
seg: str = pool.alloc(256)
if seg is None:
return None
start: t.CSizeT = 0
i: t.CSizeT
start: sizet = 0
i: sizet
for i in range(alen):
if annot[i] == '|':
seglen: t.CSizeT = i - start
seglen: sizet = i - start
# 段 [start, i):去除首尾空格与引号后查注册表
s: t.CSizeT = start
e: t.CSizeT = i
s: sizet = start
e: sizet = i
while s < e and (annot[s] == ' ' or annot[s] == '\'' or annot[s] == '"'):
s += 1
while e > s and (annot[e - 1] == ' ' or annot[e - 1] == '\'' or annot[e - 1] == '"'):
@@ -2452,13 +2452,13 @@ class AssignGenMixin:
return seg
start = i + 1
# 最后一段(无 '|' 后缀)
s: t.CSizeT = start
e: t.CSizeT = alen
s: sizet = start
e: sizet = alen
while s < e and (annot[s] == ' ' or annot[s] == '\'' or annot[s] == '"'):
s += 1
while e > s and (annot[e - 1] == ' ' or annot[e - 1] == '\'' or annot[e - 1] == '"'):
e -= 1
seglen: t.CSizeT = e - s
seglen: sizet = e - s
if seglen > 0 and seglen < 256:
string.strncpy(seg, annot + s, seglen)
seg[seglen] = '\0'
@@ -2509,7 +2509,7 @@ class AssignGenMixin:
if self.Gen.CallGenBase.find_func_in_module(mod, lookup_name) is not None:
return 1
# 继承链祖先查找
mro_ptr: t.CSizeT | t.CPtr = self.Gen.StructGen.get_mro_chain(pool, class_name)
mro_ptr: sizet | t.CPtr = self.Gen.StructGen.get_mro_chain(pool, class_name)
mi: int = 1
while mro_ptr is not None and mro_ptr[mi] != 0:
anc: str = (str | t.CPtr)(t.CVoid(mro_ptr[mi], t.CPtr))
+99 -99
View File
@@ -141,8 +141,8 @@ class AsyncGenMixin(CallGenBase.CallGenBase):
cnt: int = 0
if ags.args is None:
return 0
bn: t.CSizeT = len(ags.args)
i: t.CSizeT = 0
bn: sizet = len(ags.args)
i: sizet = 0
for i in range(bn):
a0: ast.AST | t.CPtr = ags.args.get(i)
if a0 is None:
@@ -158,8 +158,8 @@ class AsyncGenMixin(CallGenBase.CallGenBase):
continue
if cnt >= HT.MAX_CORO_VARS:
break
addr: t.CUInt64T = t.CUInt64T(trans._coro_params) + cnt * 8
slot: str | t.CPtr = (t.CVoid | t.CPtr)(addr)
addr: uint64 = uint64(trans._coro_params) + cnt * 8
slot: str | t.CPtr = (t.CPtr)(addr)
slot[0] = aname
cnt = cnt + 1
trans._coro_param_count = cnt
@@ -201,8 +201,8 @@ class AsyncGenMixin(CallGenBase.CallGenBase):
stmts: list[ast.AST | t.CPtr] | t.CPtr):
if stmts is None or trans._coro_uses_sleep != 0:
return
bn: t.CSizeT = len(stmts)
i: t.CSizeT = 0
bn: sizet = len(stmts)
i: sizet = 0
for i in range(bn):
self._scan_sleep_stmt(trans, stmts.get(i))
@@ -233,8 +233,8 @@ class AsyncGenMixin(CallGenBase.CallGenBase):
trn: ast.Try | t.CPtr = (ast.Try | t.CPtr)(stmt)
self._scan_sleep_stmts(trans, stmt.children)
if trn.handlers is not None:
nh: t.CSizeT = len(trn.handlers)
hh: t.CSizeT = 0
nh: sizet = len(trn.handlers)
hh: sizet = 0
for hh in range(nh):
h0: ast.AST | t.CPtr = trn.handlers.get(hh)
if h0 is not None:
@@ -279,8 +279,8 @@ class AsyncGenMixin(CallGenBase.CallGenBase):
return
self._scan_sleep_expr(trans, cl.func)
if cl.args is not None:
nb: t.CSizeT = len(cl.args)
j: t.CSizeT = 0
nb: sizet = len(cl.args)
j: sizet = 0
for j in range(nb):
self._scan_sleep_expr(trans, cl.args.get(j))
return
@@ -297,16 +297,16 @@ class AsyncGenMixin(CallGenBase.CallGenBase):
cm: ast.Compare | t.CPtr = (ast.Compare | t.CPtr)(node)
self._scan_sleep_expr(trans, cm.left)
if cm.comparators is not None:
nb2: t.CSizeT = len(cm.comparators)
j2: t.CSizeT = 0
nb2: sizet = len(cm.comparators)
j2: sizet = 0
for j2 in range(nb2):
self._scan_sleep_expr(trans, cm.comparators.get(j2))
return
if k == ast.ASTKind.BoolOp:
bo: ast.BoolOp | t.CPtr = (ast.BoolOp | t.CPtr)(node)
if bo.values is not None:
nb3: t.CSizeT = len(bo.values)
j3: t.CSizeT = 0
nb3: sizet = len(bo.values)
j3: sizet = 0
for j3 in range(nb3):
self._scan_sleep_expr(trans, bo.values.get(j3))
return
@@ -335,8 +335,8 @@ class AsyncGenMixin(CallGenBase.CallGenBase):
stmts: list[ast.AST | t.CPtr] | t.CPtr):
if stmts is None:
return
bn: t.CSizeT = len(stmts)
i: t.CSizeT = 0
bn: sizet = len(stmts)
i: sizet = 0
for i in range(bn):
self._scan_stmt(trans, stmts.get(i))
@@ -390,8 +390,8 @@ class AsyncGenMixin(CallGenBase.CallGenBase):
tr2: ast.Try | t.CPtr = (ast.Try | t.CPtr)(stmt)
self._scan_stmts(trans, stmt.children)
if tr2.handlers is not None:
nh2: t.CSizeT = len(tr2.handlers)
hh2: t.CSizeT = 0
nh2: sizet = len(tr2.handlers)
hh2: sizet = 0
for hh2 in range(nh2):
h2: ast.AST | t.CPtr = tr2.handlers.get(hh2)
if h2 is not None:
@@ -471,8 +471,8 @@ class AsyncGenMixin(CallGenBase.CallGenBase):
if cl.func is not None:
self._scan_expr(trans, cl.func)
if cl.args is not None:
nb: t.CSizeT = len(cl.args)
j: t.CSizeT = 0
nb: sizet = len(cl.args)
j: sizet = 0
for j in range(nb):
self._scan_expr(trans, cl.args.get(j))
return
@@ -486,16 +486,16 @@ class AsyncGenMixin(CallGenBase.CallGenBase):
if cm.left is not None:
self._scan_expr(trans, cm.left)
if cm.comparators is not None:
nb2: t.CSizeT = len(cm.comparators)
j2: t.CSizeT = 0
nb2: sizet = len(cm.comparators)
j2: sizet = 0
for j2 in range(nb2):
self._scan_expr(trans, cm.comparators.get(j2))
return
if k == ast.ASTKind.BoolOp:
bo: ast.BoolOp | t.CPtr = (ast.BoolOp | t.CPtr)(node)
if bo.values is not None:
nb3: t.CSizeT = len(bo.values)
j3: t.CSizeT = 0
nb3: sizet = len(bo.values)
j3: sizet = 0
for j3 in range(nb3):
self._scan_expr(trans, bo.values.get(j3))
return
@@ -528,14 +528,14 @@ class AsyncGenMixin(CallGenBase.CallGenBase):
if fn3.iter is not None and self._find_expr_await(fn3.iter) is not None:
return 1
if stmt.children is not None:
bn4: t.CSizeT = len(stmt.children)
i4: t.CSizeT = 0
bn4: sizet = len(stmt.children)
i4: sizet = 0
for i4 in range(bn4):
if self._stmt_deep_await(stmt.children.get(i4)) != 0:
return 1
if fn3.orelse is not None:
bn5: t.CSizeT = len(fn3.orelse)
i5: t.CSizeT = 0
bn5: sizet = len(fn3.orelse)
i5: sizet = 0
for i5 in range(bn5):
if self._stmt_deep_await(fn3.orelse.get(i5)) != 0:
return 1
@@ -567,8 +567,8 @@ class AsyncGenMixin(CallGenBase.CallGenBase):
if self._stmts_deep_await(stmt.children) != 0:
return 1
if tr3.handlers is not None:
nh3: t.CSizeT = len(tr3.handlers)
hh3: t.CSizeT = 0
nh3: sizet = len(tr3.handlers)
hh3: sizet = 0
for hh3 in range(nh3):
h3: ast.AST | t.CPtr = tr3.handlers.get(hh3)
if h3 is not None and self._stmts_deep_await(h3.children) != 0:
@@ -581,8 +581,8 @@ class AsyncGenMixin(CallGenBase.CallGenBase):
def _stmts_deep_await(self, stmts: list[ast.AST | t.CPtr] | t.CPtr) -> int:
if stmts is None:
return 0
bn6: t.CSizeT = len(stmts)
i6: t.CSizeT = 0
bn6: sizet = len(stmts)
i6: sizet = 0
for i6 in range(bn6):
if self._stmt_deep_await(stmts.get(i6)) != 0:
return 1
@@ -605,10 +605,10 @@ class AsyncGenMixin(CallGenBase.CallGenBase):
return 0
if cl4.args is None:
return 0
nb7: t.CSizeT = len(cl4.args)
nb7: sizet = len(cl4.args)
if nb7 != 1 and nb7 != 2:
return 0
j7: t.CSizeT = 0
j7: sizet = 0
for j7 in range(nb7):
if self._find_expr_await(cl4.args.get(j7)) is not None:
return 0
@@ -636,8 +636,8 @@ class AsyncGenMixin(CallGenBase.CallGenBase):
stmts: list[ast.AST | t.CPtr] | t.CPtr):
if stmts is None:
return
bn: t.CSizeT = len(stmts)
i: t.CSizeT = 0
bn: sizet = len(stmts)
i: sizet = 0
for i in range(bn):
self._collect_locals_stmt(trans, stmts.get(i))
@@ -683,8 +683,8 @@ class AsyncGenMixin(CallGenBase.CallGenBase):
tr: ast.Try | t.CPtr = (ast.Try | t.CPtr)(stmt)
self._collect_locals_stmts(trans, stmt.children)
if tr.handlers is not None:
nh: t.CSizeT = len(tr.handlers)
hh: t.CSizeT = 0
nh: sizet = len(tr.handlers)
hh: sizet = 0
for hh in range(nh):
h0: ast.AST | t.CPtr = tr.handlers.get(hh)
if h0 is None:
@@ -703,8 +703,8 @@ class AsyncGenMixin(CallGenBase.CallGenBase):
cnt: int = trans._coro_local_count
if cnt >= HT.MAX_CORO_VARS:
return
addr: t.CUInt64T = t.CUInt64T(trans._coro_locals) + cnt * 8
slot: str | t.CPtr = (t.CVoid | t.CPtr)(addr)
addr: uint64 = uint64(trans._coro_locals) + cnt * 8
slot: str | t.CPtr = (t.CPtr)(addr)
slot[0] = name
trans._coro_local_count = cnt + 1
@@ -952,8 +952,8 @@ class AsyncGenMixin(CallGenBase.CallGenBase):
cnt: int = trans._coro_wake_count
if cnt >= HT.MAX_CORO_FUNCS:
return
addr: t.CUInt64T = t.CUInt64T(trans._coro_wake_names) + cnt * 8
slot: str | t.CPtr = (t.CVoid | t.CPtr)(addr)
addr: uint64 = uint64(trans._coro_wake_names) + cnt * 8
slot: str | t.CPtr = (t.CPtr)(addr)
slot[0] = name
trans._coro_wake_idxs[cnt] = wake_idx
trans._coro_wake_count = cnt + 1
@@ -965,8 +965,8 @@ class AsyncGenMixin(CallGenBase.CallGenBase):
return -1
i: int = 0
for i in range(trans._coro_wake_count):
addr: t.CUInt64T = t.CUInt64T(trans._coro_wake_names) + i * 8
slot: str | t.CPtr = (t.CVoid | t.CPtr)(addr)
addr: uint64 = uint64(trans._coro_wake_names) + i * 8
slot: str | t.CPtr = (t.CPtr)(addr)
if slot[0] is not None and string.strcmp(slot[0], name) == 0:
return trans._coro_wake_idxs[i]
return -1
@@ -1145,7 +1145,7 @@ class AsyncGenMixin(CallGenBase.CallGenBase):
if nseg <= 0:
nseg = 1
# 预建 state 块 + switch case(一次性生成,await 恢复块 position 填充)
state_bbs: t.CSizeT | t.CPtr = pool.alloc(nseg * 8)
state_bbs: sizet | t.CPtr = pool.alloc(nseg * 8)
if state_bbs is None:
return 0
trans._coro_state_bbs = state_bbs
@@ -1161,7 +1161,7 @@ class AsyncGenMixin(CallGenBase.CallGenBase):
pool, func, bb_name)
if sbb is None:
continue
state_bbs[si] = t.CSizeT(sbb)
state_bbs[si] = sizet(sbb)
sc: llvmlite.SwitchCase | t.CPtr = llvmlite.new_switch_case(
pool, llvmlite.const_int32(pool, si), sbb)
if sc is not None:
@@ -1210,8 +1210,8 @@ class AsyncGenMixin(CallGenBase.CallGenBase):
"""递归翻译协程体语句。builder 当前块 = 活跃执行块(state0 或某恢复块)。"""
if stmts is None:
return
bn: t.CSizeT = len(stmts)
i: t.CSizeT = 0
bn: sizet = len(stmts)
i: sizet = 0
for i in range(bn):
stmt: ast.AST | t.CPtr = stmts.get(i)
if stmt is None:
@@ -1479,8 +1479,8 @@ class AsyncGenMixin(CallGenBase.CallGenBase):
if r2 is not None:
return r2
if cl.args is not None:
nb: t.CSizeT = len(cl.args)
j: t.CSizeT = 0
nb: sizet = len(cl.args)
j: sizet = 0
for j in range(nb):
r3: ast.Await | t.CPtr = self._find_expr_await(cl.args.get(j))
if r3 is not None:
@@ -1495,8 +1495,8 @@ class AsyncGenMixin(CallGenBase.CallGenBase):
if r4 is not None:
return r4
if cm.comparators is not None:
nb2: t.CSizeT = len(cm.comparators)
j2: t.CSizeT = 0
nb2: sizet = len(cm.comparators)
j2: sizet = 0
for j2 in range(nb2):
r5: ast.Await | t.CPtr = self._find_expr_await(cm.comparators.get(j2))
if r5 is not None:
@@ -1505,8 +1505,8 @@ class AsyncGenMixin(CallGenBase.CallGenBase):
if k == ast.ASTKind.BoolOp:
bo: ast.BoolOp | t.CPtr = (ast.BoolOp | t.CPtr)(node)
if bo.values is not None:
nb3: t.CSizeT = len(bo.values)
j3: t.CSizeT = 0
nb3: sizet = len(bo.values)
j3: sizet = 0
for j3 in range(nb3):
r6: ast.Await | t.CPtr = self._find_expr_await(bo.values.get(j3))
if r6 is not None:
@@ -1596,8 +1596,8 @@ class AsyncGenMixin(CallGenBase.CallGenBase):
cl.func = ast.Name(pool, temp_name, 0)
return 1
if cl.args is not None:
nb: t.CSizeT = len(cl.args)
j: t.CSizeT = 0
nb: sizet = len(cl.args)
j: sizet = 0
for j in range(nb):
r4: int = self._replace_expr_await(pool, cl.args.get(j), temp_name)
if r4 == 1:
@@ -1624,8 +1624,8 @@ class AsyncGenMixin(CallGenBase.CallGenBase):
cm.left = ast.Name(pool, temp_name, 0)
return 1
if cm.comparators is not None:
nb2: t.CSizeT = len(cm.comparators)
j2: t.CSizeT = 0
nb2: sizet = len(cm.comparators)
j2: sizet = 0
for j2 in range(nb2):
r7: int = self._replace_expr_await(pool, cm.comparators.get(j2), temp_name)
if r7 == 1:
@@ -1637,8 +1637,8 @@ class AsyncGenMixin(CallGenBase.CallGenBase):
if k == ast.ASTKind.BoolOp:
bo: ast.BoolOp | t.CPtr = (ast.BoolOp | t.CPtr)(node)
if bo.values is not None:
nb3: t.CSizeT = len(bo.values)
j3: t.CSizeT = 0
nb3: sizet = len(bo.values)
j3: sizet = 0
for j3 in range(nb3):
r8: int = self._replace_expr_await(pool, bo.values.get(j3), temp_name)
if r8 == 1:
@@ -1723,8 +1723,8 @@ class AsyncGenMixin(CallGenBase.CallGenBase):
idx: int) -> str:
if trans is None or trans._coro_params is None:
return None
addr: t.CUInt64T = t.CUInt64T(trans._coro_params) + idx * 8
slot: str | t.CPtr = (t.CVoid | t.CPtr)(addr)
addr: uint64 = uint64(trans._coro_params) + idx * 8
slot: str | t.CPtr = (t.CPtr)(addr)
return slot[0]
# ============================================================
@@ -1736,8 +1736,8 @@ class AsyncGenMixin(CallGenBase.CallGenBase):
return None
if state_no < 0 or state_no >= trans._coro_nseg:
return None
# 注意:state_bbs 数组存的是块指针(t.CSizeT),必须下标取值,
# 不能取元素地址(t.CUInt64T(数组)+idx*8 是地址,会导致 position
# 注意:state_bbs 数组存的是块指针(sizet),必须下标取值,
# 不能取元素地址(uint64(数组)+idx*8 是地址,会导致 position
# 到非法块 → IR 指令链损坏 → RenumberSSA/FunctionPrint 崩溃)。
return (llvmlite.BasicBlock | t.CPtr)(
t.CVoid(trans._coro_state_bbs[state_no], t.CPtr))
@@ -1917,7 +1917,7 @@ class AsyncGenMixin(CallGenBase.CallGenBase):
return
# try 栈 push
if trans._coro_try_stack_count < HT.MAX_CORO_TRY:
trans._coro_try_stack[trans._coro_try_stack_count] = t.CSizeT(except_bb)
trans._coro_try_stack[trans._coro_try_stack_count] = sizet(except_bb)
trans._coro_try_stack_count = trans._coro_try_stack_count + 1
# try body
self._handle_segment(trans, builder, pool, mod, stmt.children)
@@ -1930,11 +1930,11 @@ class AsyncGenMixin(CallGenBase.CallGenBase):
exc_val: llvmlite.Value | t.CPtr = llvmlite.build_load(
builder, i32_ty, trans._coro_exc_ptr)
# 预建 check/handler/unmatched 块
check_bbs: t.CSizeT | t.CPtr = pool.alloc((nhandlers + 1) * 8)
handler_bbs: t.CSizeT | t.CPtr = pool.alloc(nhandlers * 8)
check_bbs: sizet | t.CPtr = pool.alloc((nhandlers + 1) * 8)
handler_bbs: sizet | t.CPtr = pool.alloc(nhandlers * 8)
if check_bbs is None or handler_bbs is None:
return
check_bbs[0] = t.CSizeT(except_bb)
check_bbs[0] = sizet(except_bb)
hi: int = 0
for hi in range(nhandlers):
# [FIX 2026-08-31] 块名用 snprintf 生成(对齐本文件其余块命名):
@@ -1947,13 +1947,13 @@ class AsyncGenMixin(CallGenBase.CallGenBase):
return
viperlib.snprintf(chk_name, 64, "coro.exc_check_%d", hi)
viperlib.snprintf(exc_name, 64, "coro.except_%d", hi)
check_bbs[hi + 1] = t.CSizeT(llvmlite.create_block(
check_bbs[hi + 1] = sizet(llvmlite.create_block(
pool, func, chk_name))
handler_bbs[hi] = t.CSizeT(llvmlite.create_block(
handler_bbs[hi] = sizet(llvmlite.create_block(
pool, func, exc_name))
unmatched_bb: llvmlite.BasicBlock | t.CPtr = llvmlite.create_block(
pool, func, "coro.try_reraise")
codes_buf: t.CInt | t.CPtr = pool.alloc(256)
codes_buf: int | t.CPtr = pool.alloc(256)
# 每个 handler:check 链
for hi in range(nhandlers):
h_node: ast.AST | t.CPtr = tr.handlers.get(hi)
@@ -2071,7 +2071,7 @@ class AsyncGenMixin(CallGenBase.CallGenBase):
return
# try 栈 push(异常跳 finally)
if trans._coro_try_stack_count < HT.MAX_CORO_TRY:
trans._coro_try_stack[trans._coro_try_stack_count] = t.CSizeT(fin_bb)
trans._coro_try_stack[trans._coro_try_stack_count] = sizet(fin_bb)
trans._coro_try_stack_count = trans._coro_try_stack_count + 1
self._handle_segment(trans, builder, pool, mod, stmt.children)
if llvmlite.builder_cur_block_is_terminated(builder) == 0:
@@ -2307,8 +2307,8 @@ class AsyncGenMixin(CallGenBase.CallGenBase):
i32_ty: llvmlite.LLVMType | t.CPtr = llvmlite.Int32(pool)
if cl is None or trans is None or cl.args is None:
return llvmlite.const_int32(pool, 0)
nb: t.CSizeT = len(cl.args)
j: t.CSizeT = 0
nb: sizet = len(cl.args)
j: sizet = 0
for j in range(nb):
arg0: ast.AST | t.CPtr = cl.args.get(j)
async_name: str = self._var_to_async(trans, arg0)
@@ -2416,8 +2416,8 @@ class AsyncGenMixin(CallGenBase.CallGenBase):
if aw_n.value is not None and aw_n.value.kind() == ast.ASTKind.Call:
cl_a: ast.Call | t.CPtr = (ast.Call | t.CPtr)(aw_n.value)
if cl_a.args is not None:
nb: t.CSizeT = len(cl_a.args)
j: t.CSizeT = 0
nb: sizet = len(cl_a.args)
j: sizet = 0
for j in range(nb):
av: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
builder, pool, mod, cl_a.args.get(j), None, 0, trans)
@@ -2619,8 +2619,8 @@ class AsyncGenMixin(CallGenBase.CallGenBase):
cnt: int = trans._async_func_count
i: int = 0
for i in range(cnt):
addr: t.CUInt64T = t.CUInt64T(trans._async_funcs) + i * 8
slot: str | t.CPtr = (t.CVoid | t.CPtr)(addr)
addr: uint64 = uint64(trans._async_funcs) + i * 8
slot: str | t.CPtr = (t.CPtr)(addr)
if slot[0] is not None and string.strcmp(slot[0], name) == 0:
return 1
return 0
@@ -2636,14 +2636,14 @@ class AsyncGenMixin(CallGenBase.CallGenBase):
cnt: int = trans._coro_var_async_count
i: int = 0
for i in range(cnt):
addr: t.CUInt64T = t.CUInt64T(trans._coro_var_async) + i * 16
pair: str | t.CPtr = (t.CVoid | t.CPtr)(addr)
addr: uint64 = uint64(trans._coro_var_async) + i * 16
pair: str | t.CPtr = (t.CPtr)(addr)
if pair[0] is not None and string.strcmp(pair[0], var_name) == 0:
return 0
if cnt >= HT.MAX_CORO_VARS:
return 1
pair2_addr: t.CUInt64T = t.CUInt64T(trans._coro_var_async) + cnt * 16
pair2: str | t.CPtr = (t.CVoid | t.CPtr)(pair2_addr)
pair2_addr: uint64 = uint64(trans._coro_var_async) + cnt * 16
pair2: str | t.CPtr = (t.CPtr)(pair2_addr)
pair2[0] = var_name
pair2[1] = func_name
trans._coro_var_async_count = cnt + 1
@@ -2657,14 +2657,14 @@ class AsyncGenMixin(CallGenBase.CallGenBase):
cnt: int = trans._async_func_count
i: int = 0
for i in range(cnt):
addr: t.CUInt64T = t.CUInt64T(trans._async_funcs) + i * 8
slot: str | t.CPtr = (t.CVoid | t.CPtr)(addr)
addr: uint64 = uint64(trans._async_funcs) + i * 8
slot: str | t.CPtr = (t.CPtr)(addr)
if slot[0] is not None and string.strcmp(slot[0], name) == 0:
return 0
if cnt >= HT.MAX_CORO_FUNCS:
return 1
addr2: t.CUInt64T = t.CUInt64T(trans._async_funcs) + cnt * 8
slot2: str | t.CPtr = (t.CVoid | t.CPtr)(addr2)
addr2: uint64 = uint64(trans._async_funcs) + cnt * 8
slot2: str | t.CPtr = (t.CPtr)(addr2)
slot2[0] = name
trans._async_func_count = cnt + 1
return 0
@@ -2680,17 +2680,17 @@ class AsyncGenMixin(CallGenBase.CallGenBase):
cnt: int = trans._coro_frame_count
i: int = 0
for i in range(cnt):
addr: t.CUInt64T = t.CUInt64T(trans._coro_frames) + i * 16
pair: str | t.CPtr = (t.CVoid | t.CPtr)(addr)
addr: uint64 = uint64(trans._coro_frames) + i * 16
pair: str | t.CPtr = (t.CPtr)(addr)
if pair[0] is not None and string.strcmp(pair[0], name) == 0:
pair[1] = (str)(t.CVoid(t.CSizeT(frame_ty), t.CPtr))
pair[1] = (str)(t.CVoid(sizet(frame_ty), t.CPtr))
return 0
if cnt >= HT.MAX_CORO_FUNCS:
return 1
pair2_addr: t.CUInt64T = t.CUInt64T(trans._coro_frames) + cnt * 16
pair2: str | t.CPtr = (t.CVoid | t.CPtr)(pair2_addr)
pair2_addr: uint64 = uint64(trans._coro_frames) + cnt * 16
pair2: str | t.CPtr = (t.CPtr)(pair2_addr)
pair2[0] = name
pair2[1] = (str)(t.CVoid(t.CSizeT(frame_ty), t.CPtr))
pair2[1] = (str)(t.CVoid(sizet(frame_ty), t.CPtr))
trans._coro_frame_count = cnt + 1
return 0
@@ -2702,11 +2702,11 @@ class AsyncGenMixin(CallGenBase.CallGenBase):
cnt: int = trans._coro_frame_count
i: int = 0
for i in range(cnt):
addr: t.CUInt64T = t.CUInt64T(trans._coro_frames) + i * 16
pair: str | t.CPtr = (t.CVoid | t.CPtr)(addr)
addr: uint64 = uint64(trans._coro_frames) + i * 16
pair: str | t.CPtr = (t.CPtr)(addr)
if pair[0] is not None and string.strcmp(pair[0], name) == 0:
if pair[1] is not None:
ty_addr: t.CSizeT = t.CSizeT(pair[1])
ty_addr: sizet = sizet(pair[1])
return (llvmlite.LLVMType | t.CPtr)(t.CVoid(ty_addr, t.CPtr))
return None
return None
@@ -2719,8 +2719,8 @@ class AsyncGenMixin(CallGenBase.CallGenBase):
cnt: int = trans._coro_var_async_count
i: int = 0
for i in range(cnt):
addr: t.CUInt64T = t.CUInt64T(trans._coro_var_async) + i * 16
pair: str | t.CPtr = (t.CVoid | t.CPtr)(addr)
addr: uint64 = uint64(trans._coro_var_async) + i * 16
pair: str | t.CPtr = (t.CPtr)(addr)
if pair[0] is not None and string.strcmp(pair[0], var_name) == 0:
return pair[1]
return None
@@ -2851,6 +2851,6 @@ class AsyncGenMixin(CallGenBase.CallGenBase):
"""读 trans._coro_locals 第 idx 个局部变量名,越界返回 None"""
if trans is None or trans._coro_locals is None:
return None
addr: t.CUInt64T = t.CUInt64T(trans._coro_locals) + idx * 8
slot: str | t.CPtr = (t.CVoid | t.CPtr)(addr)
addr: uint64 = uint64(trans._coro_locals) + idx * 8
slot: str | t.CPtr = (t.CPtr)(addr)
return slot[0]
+80 -80
View File
@@ -63,7 +63,7 @@ class CallGenBase:
# --- temp 目录(原 _g_temp_dir/_g_temp_dir_len) ---
TempDir: str
TempDirLen: t.CSizeT
TempDirLen: sizet
# --- 闭包名表(原 _g_closure_names/_g_closure_count) ---
ClosureNames: str
@@ -71,7 +71,7 @@ class CallGenBase:
# --- 函数指针签名表(原 _g_funcptr_names/_g_funcptr_rets/_g_funcptr_count) ---
FuncptrNames: str
FuncptrRets: t.CUInt64T | t.CPtr
FuncptrRets: uint64 | t.CPtr
FuncptrCount: int
# --- 全局函数注册表(原 _global_funcs/_global_func_count) ---
@@ -140,15 +140,15 @@ class CallGenBase:
if rel_arr_ptr is None or sha1_arr_ptr is None or count <= 0:
return None
for i in range(count):
sidx: t.CSizeT = t.CSizeT(i) * 17
sidx: sizet = sizet(i) * 17
if string.strcmp(sha1_arr_ptr + sidx, mod_sha1) != 0:
continue
ridx: t.CSizeT = t.CSizeT(i) * StubMerger.MAX_REL_PATH_LEN
ridx: sizet = sizet(i) * StubMerger.MAX_REL_PATH_LEN
rel: str = rel_arr_ptr + ridx
last_slash: str = string.strrchr(rel, 47) # 47 = ord('/')
if last_slash is None:
return None
pkg_len: t.CSizeT = t.CSizeT(t.CUInt64T(last_slash) - t.CUInt64T(rel))
pkg_len: sizet = sizet(uint64(last_slash) - uint64(rel))
if pkg_len == 0:
return None
pkg_buf: str = pool.alloc(pkg_len + 1)
@@ -180,15 +180,15 @@ class CallGenBase:
# func_name 归属,收集全部候选由调用方逐个验证(is_cexport_func /
# _is_state_func_from_vpi 按 vpi 返回注解确认定义模块)。
star_cands: str = None
star_cands_len: t.CSizeT = 0
star_cands_len: sizet = 0
temp_dir: str = self.Gen.TypeGenBase.get_temp_dir()
if temp_dir is None:
return None
td_len: t.CSizeT = string.strlen(temp_dir)
td_len: sizet = string.strlen(temp_dir)
vpi_path: str = StubMergerCollect._sliced_path(temp_dir, td_len, mod_sha1, "vpi")
if vpi_path is None:
return None
READ_SZ: t.CSizeT = 1048576
READ_SZ: sizet = 1048576
buf: bytes = stdlib.malloc(READ_SZ)
if buf is None:
stdlib.free(vpi_path)
@@ -205,17 +205,17 @@ class CallGenBase:
return None
if nrd < READ_SZ:
buf[nrd] = 0
name_len: t.CSizeT = string.strlen(func_name)
name_len: sizet = string.strlen(func_name)
# 模块自含定义标志:vpi 中行首 "def {func_name}(" 命中且未被同名
# from-import 覆盖 → 该模块自身定义 func_name,不是 re-export 源。
has_own_def: int = 0
total: t.CSizeT = string.strlen(buf)
pos: t.CSizeT = 0
total: sizet = string.strlen(buf)
pos: sizet = 0
while pos < total:
ls: t.CSizeT = pos
ls: sizet = pos
while pos < total and buf[pos] != '\n':
pos += 1
ll: t.CSizeT = pos - ls
ll: sizet = pos - ls
if pos < total:
pos += 1
# 自含定义检测(须在 from-import 行匹配之前,对所有行生效):
@@ -225,14 +225,14 @@ class CallGenBase:
# (类内方法 def 有缩进,首字符为空格,不会误命中)。
if ll > 4 and buf[ls] == 'd' and buf[ls + 1] == 'e' \
and buf[ls + 2] == 'f' and buf[ls + 3] == ' ':
fstart_od: t.CSizeT = ls + 4
fend_od: t.CSizeT = fstart_od
fstart_od: sizet = ls + 4
fend_od: sizet = fstart_od
while fend_od < ls + ll and buf[fend_od] != '(' and buf[fend_od] != ' ':
fend_od += 1
fl2_od: t.CSizeT = fend_od - fstart_od
fl2_od: sizet = fend_od - fstart_od
if fl2_od == name_len:
fd_eq_od: int = 1
fdi_od: t.CSizeT = 0
fdi_od: sizet = 0
while fdi_od < fl2_od:
if buf[fstart_od + fdi_od] != func_name[fdi_od]:
fd_eq_od = 0
@@ -247,7 +247,7 @@ class CallGenBase:
if buf[ls] != 'f' or buf[ls + 1] != 'r' or buf[ls + 2] != 'o' or buf[ls + 3] != 'm' or buf[ls + 4] != ' ':
continue
# 找 " import " 分隔符
imp_pos: t.CSizeT = ls + 5
imp_pos: sizet = ls + 5
while imp_pos + 7 <= ls + ll:
if buf[imp_pos] == ' ' and buf[imp_pos + 1] == 'i' and buf[imp_pos + 2] == 'm' and \
buf[imp_pos + 3] == 'p' and buf[imp_pos + 4] == 'o' and buf[imp_pos + 5] == 'r' and \
@@ -256,10 +256,10 @@ class CallGenBase:
imp_pos += 1
if imp_pos + 7 > ls + ll:
continue
mod_start: t.CSizeT = ls + 5
mod_end: t.CSizeT = imp_pos
mod_start: sizet = ls + 5
mod_end: sizet = imp_pos
# 名称列表从 "import " 之后(逗号分隔,含 "A as B" 取原名 A)
nm_start: t.CSizeT = imp_pos + 8
nm_start: sizet = imp_pos + 8
# star import 支持:from X import * → 任意函数都可能属 X 模块。
# 不立即返回(首个 star 行未必是 func_name 的定义模块,如
# fltk/__init__ 依次 from _types/_enums/_cfl import *),累积
@@ -271,7 +271,7 @@ class CallGenBase:
star_dot = 1
star_buf: str = pool.alloc(mod_end - mod_start + 1)
if star_buf is not None:
si2: t.CSizeT = 0
si2: sizet = 0
while mod_start + si2 < mod_end:
star_buf[si2] = buf[mod_start + si2]
si2 += 1
@@ -282,13 +282,13 @@ class CallGenBase:
if star_dot != 0:
spkg: str = self._module_package_from_sha1(pool, mod_sha1)
if spkg is not None:
srl: t.CSizeT = string.strlen(spkg) + string.strlen(star_buf) + 2
srl: sizet = string.strlen(spkg) + string.strlen(star_buf) + 2
sres: str = pool.alloc(srl)
if sres is not None:
viperlib.snprintf(sres, srl, "%s.%s", spkg, star_buf)
star_buf = sres
# 累积候选(空格分隔)
sbl: t.CSizeT = string.strlen(star_buf)
sbl: sizet = string.strlen(star_buf)
new_cands: str = pool.alloc(star_cands_len + sbl + 2)
if new_cands is not None:
if star_cands is not None and star_cands_len > 0:
@@ -301,18 +301,18 @@ class CallGenBase:
star_cands_len = sbl
star_cands = new_cands
continue
scan: t.CSizeT = nm_start
scan: sizet = nm_start
while scan < ls + ll:
while scan < ls + ll and (buf[scan] == ' ' or buf[scan] == ','):
scan += 1
if scan >= ls + ll:
break
n_end: t.CSizeT = scan
n_end: sizet = scan
while n_end < ls + ll and buf[n_end] != ',' and buf[n_end] != ' ':
n_end += 1
cand_start: t.CSizeT = scan
cand_len: t.CSizeT = n_end - scan
as_pos: t.CSizeT = scan
cand_start: sizet = scan
cand_len: sizet = n_end - scan
as_pos: sizet = scan
while as_pos + 4 <= n_end:
if buf[as_pos] == ' ' and buf[as_pos + 1] == 'a' and buf[as_pos + 2] == 's' and buf[as_pos + 3] == ' ':
cand_start = as_pos + 4
@@ -334,7 +334,7 @@ class CallGenBase:
if mod_buf is None:
stdlib.free(buf)
return None
mi: t.CSizeT = 0
mi: sizet = 0
while mod_start + mi < mod_end:
mod_buf[mi] = buf[mod_start + mi]
mi += 1
@@ -349,7 +349,7 @@ class CallGenBase:
if pkg is None:
stdlib.free(buf)
return None
rl: t.CSizeT = string.strlen(pkg) + string.strlen(mod_buf) + 2
rl: sizet = string.strlen(pkg) + string.strlen(mod_buf) + 2
res: str = pool.alloc(rl)
if res is None:
stdlib.free(buf)
@@ -388,11 +388,11 @@ class CallGenBase:
string.memset(self.Gen.CallGenBase.CexportSha1Arr, 0, _CEXPORT_MAX * 17)
string.memset(self.Gen.CallGenBase.CexportFuncArr, 0, _CEXPORT_MAX * 64)
if self.Gen.CallGenBase.CexportCount < _CEXPORT_MAX:
idx: t.CSizeT = t.CSizeT(self.Gen.CallGenBase.CexportCount) * 17
idx: sizet = sizet(self.Gen.CallGenBase.CexportCount) * 17
# 槽位定长 17/64 字节,strcpy 无界会越界写相邻槽(stdlib 堆区)
string.strncpy(self.Gen.CallGenBase.CexportSha1Arr + idx, sha1, 16)
self.Gen.CallGenBase.CexportSha1Arr[idx + 16] = '\0'
idx2: t.CSizeT = t.CSizeT(self.Gen.CallGenBase.CexportCount) * 64
idx2: sizet = sizet(self.Gen.CallGenBase.CexportCount) * 64
string.strncpy(self.Gen.CallGenBase.CexportFuncArr + idx2, func_name, 63)
self.Gen.CallGenBase.CexportFuncArr[idx2 + 63] = '\0'
self.Gen.CallGenBase.CexportCount += 1
@@ -412,9 +412,9 @@ class CallGenBase:
return 0
if self.Gen.CallGenBase.CexportSha1Arr is not None:
for i in range(self.Gen.CallGenBase.CexportCount):
idx: t.CSizeT = t.CSizeT(i) * 17
idx: sizet = sizet(i) * 17
if string.strcmp(self.Gen.CallGenBase.CexportSha1Arr + idx, sha1) == 0:
idx2: t.CSizeT = t.CSizeT(i) * 64
idx2: sizet = sizet(i) * 64
if string.strcmp(self.Gen.CallGenBase.CexportFuncArr + idx2, func_name) == 0:
return 1
return self._is_cexport_func_from_vpi(sha1, func_name)
@@ -455,7 +455,7 @@ class CallGenBase:
state_annot: str = VpiReader._lookup_vpi_ret_annot(sha1, None, func_name)
if state_annot is None:
return 0
# 返回注解含 "State"(如 "t.CSizeT | t.State")→ 外部 C 函数
# 返回注解含 "State"(如 "sizet | t.State")→ 外部 C 函数
if string.strstr(state_annot, "State") is not None:
return 1
return 0
@@ -479,7 +479,7 @@ class CallGenBase:
mod_name_raw: str) -> str:
"""从原始模块名查找 SHA1,返回 None=未找到"""
# 手动找到模块名结束位置(空格、null、或 ':' 别名分隔符),复制到新缓冲区
mod_len: t.CSizeT = 0
mod_len: sizet = 0
while mod_name_raw[mod_len] != ' ' and mod_name_raw[mod_len] != '\0' and mod_name_raw[mod_len] != ':':
mod_len += 1
mod_name_buf: str = pool.alloc(mod_len + 1)
@@ -519,7 +519,7 @@ class CallGenBase:
"""
if mod is None or name is None:
return None
name_len: t.CSizeT = string.strlen(name)
name_len: sizet = string.strlen(name)
cur: llvmlite.Function | t.CPtr = mod.FuncHead
# 第一遍:精确匹配
while cur is not None:
@@ -537,10 +537,10 @@ class CallGenBase:
while cur is not None:
cur_name_o: str = llvmlite.function_get_name(cur)
if cur_name_o is not None:
cur_len_o: t.CSizeT = string.strlen(cur_name_o)
cur_len_o: sizet = string.strlen(cur_name_o)
if cur_len_o == 17 + name_len:
if string.strncmp(cur_name_o, owner_sha1, 16) == 0 and cur_name_o[16] == '.':
suffix_start_o: t.CSizeT = cur_len_o - name_len
suffix_start_o: sizet = cur_len_o - name_len
if cur_name_o[suffix_start_o - 1] == '.':
match_o: int = 1
for i in range(name_len):
@@ -564,9 +564,9 @@ class CallGenBase:
while cur is not None:
cur_name2: str = llvmlite.function_get_name(cur)
if cur_name2 is not None:
cur_len: t.CSizeT = string.strlen(cur_name2)
cur_len: sizet = string.strlen(cur_name2)
if cur_len > name_len + 1:
suffix_start: t.CSizeT = cur_len - name_len
suffix_start: sizet = cur_len - name_len
if cur_name2[suffix_start - 1] == '.':
match: int = 1
for i in range(name_len):
@@ -582,9 +582,9 @@ class CallGenBase:
while cur is not None:
cur_name3: str = llvmlite.function_get_name(cur)
if cur_name3 is not None:
cur_len3: t.CSizeT = string.strlen(cur_name3)
cur_len3: sizet = string.strlen(cur_name3)
if cur_len3 > name_len + 1:
suffix_start3: t.CSizeT = cur_len3 - name_len
suffix_start3: sizet = cur_len3 - name_len
if cur_name3[suffix_start3 - 1] == '.':
match3: int = 1
for i in range(name_len):
@@ -668,7 +668,7 @@ class CallGenBase:
existing = existing.Next
# 裸名 C 库函数(如 string.memset → @memset、stdlib.memcpy → @memcpy):
# call_name 无 sha1 前缀 → 无法提取定义侧模块查 vpi 参数注解 →
# 此前用实参类型建 declare(字面量 0=i32 把定义 t.CSizeT(i64) 固化窄,
# 此前用实参类型建 declare(字面量 0=i32 把定义 sizet(i64) 固化窄,
# VKernel process.vp string.memset 声明 @memset(i8*,i32,i32) vs 定义
# @memset(i8*,i32,i64),跨模块 ABI 宽度不一致,优化路径读高位垃圾
# 写穿内存)。已知 C 库函数直接按标准签名建 declare(与 CallGenLib
@@ -686,7 +686,7 @@ class CallGenBase:
func.IsDeclared = 1
# 定义侧参数类型优先(根治实参字面量固化错误宽度):
# declare 此前用调用点实参类型(param_head)建参数,字面量 0=i32 会把
# 定义 t.CSizeT(i64) 的参数固化窄(SlotsBugTest _translate_struct_ctor
# 定义 sizet(i64) 的参数固化窄(SlotsBugTest _translate_struct_ctor
# can=i32 vs 定义 i64 → 调用侧 trunc i64→i32、callee 按 i64 读栈残留
# 垃圾高位 → can=巨值读未写槽位崩溃根因)。从 call_name 提取
# {sha1}.{cls}.{method} 查 vpi 参数注解缓存取定义侧类型:仅当实参与
@@ -700,10 +700,10 @@ class CallGenBase:
cls_d: str = None
meth_d: str = None
if call_name is not None:
cl_len_d: t.CSizeT = string.strlen(call_name)
cl_len_d: sizet = string.strlen(call_name)
if cl_len_d >= 17 and call_name[16] == '.':
sha1_ok_d: int = 1
si_d: t.CSizeT
si_d: sizet
for si_d in range(16):
cc_d: int = call_name[si_d]
if not ((cc_d >= 48 and cc_d <= 57) or (cc_d >= 97 and cc_d <= 102)):
@@ -718,7 +718,7 @@ class CallGenBase:
rest_d: str = call_name + 17
dot2_d: str = string.strchr(rest_d, '.')
if dot2_d is not None:
cls_len_d: t.CSizeT = t.CUInt64T(dot2_d) - t.CUInt64T(rest_d)
cls_len_d: sizet = uint64(dot2_d) - uint64(rest_d)
if cls_len_d > 0:
cls_buf_d: bytes = stdlib.malloc(cls_len_d + 1)
if cls_buf_d is not None:
@@ -929,14 +929,14 @@ class CallGenBase:
# ============================================================
def _ParseLLVMRetTyStr(self, pool: memhub.MemBuddy | t.CPtr,
buf: bytes,
start: t.CSizeT,
end: t.CSizeT) -> llvmlite.LLVMType | t.CPtr:
start: sizet,
end: sizet) -> llvmlite.LLVMType | t.CPtr:
"""将 LLVM IR 返回类型字符串转换为 llvmlite.LLVMType"""
if pool is None or buf is None or start >= end:
return None
# 去除前导空白
s: t.CSizeT = start
s: sizet = start
while s < end:
c: int = buf[s]
if c != ' ' and c != '\t':
@@ -944,14 +944,14 @@ class CallGenBase:
s += 1
# 去除尾部空白
e: t.CSizeT = end
e: sizet = end
while e > s:
c2: int = buf[e - 1]
if c2 != ' ' and c2 != '\t':
break
e -= 1
ty_len: t.CSizeT = e - s
ty_len: sizet = e - s
if ty_len == 0:
return None
@@ -964,16 +964,16 @@ class CallGenBase:
th_st: llvmlite.ParamNode | t.CPtr = None
tt_st: llvmlite.ParamNode | t.CPtr = None
tc_st: int = 0
ps_st: t.CSizeT = s + 1
ps_st: sizet = s + 1
while ps_st < e and buf[ps_st] != '}':
while ps_st < e and (buf[ps_st] == ' ' or buf[ps_st] == ','):
ps_st += 1
if ps_st >= e or buf[ps_st] == '}':
break
es_st: t.CSizeT = ps_st
es_st: sizet = ps_st
while ps_st < e and buf[ps_st] != ',' and buf[ps_st] != '}':
ps_st += 1
ee_st: t.CSizeT = ps_st
ee_st: sizet = ps_st
if ee_st > es_st:
et_st: llvmlite.LLVMType | t.CPtr = self._ParseLLVMRetTyStr(
pool, buf, es_st, ee_st)
@@ -1000,7 +1000,7 @@ class CallGenBase:
# 检查是否含 * (指针类型) → 返回 i8* (通用指针)
# 包括 i8*, i32*, %"name"*, { i32, i8 }* 等
ci: t.CSizeT = s
ci: sizet = s
while ci < e:
if buf[ci] == '*':
return llvmlite.Ptr(pool, llvmlite.Int8(pool))
@@ -1021,7 +1021,7 @@ class CallGenBase:
# iN (i8, i16, i32, i64)
if ty_len >= 2 and buf[s] == 'i':
bits: int = 0
di: t.CSizeT = s + 1
di: sizet = s + 1
valid: int = 1
while di < e:
d: int = buf[di]
@@ -1081,13 +1081,13 @@ class CallGenBase:
if self.Gen.CallGenBase.TempDir is None or self.Gen.CallGenBase.TempDirLen == 0:
return None
sha1_len: t.CSizeT = string.strlen(class_sha1)
sha1_len: sizet = string.strlen(class_sha1)
if sha1_len < 2:
return None
# 构造 text.ll 路径 (level=1): {temp_dir}/{sha1[0:2]}/{sha1}.text.ll
# 使用 subdir 缓冲区避免 %c 格式化问题(与 StubMerger._sliced_path 一致)
path_len: t.CSizeT = self.Gen.CallGenBase.TempDirLen + sha1_len + 14
path_len: sizet = self.Gen.CallGenBase.TempDirLen + sha1_len + 14
path_buf: bytes = stdlib.malloc(path_len)
if path_buf is None:
return None
@@ -1115,13 +1115,13 @@ class CallGenBase:
tf.close()
stdlib.free(path_buf)
return None
read_size: t.CSizeT = t.CSizeT(tfsize)
read_size: sizet = sizet(tfsize)
read_buf: bytes = stdlib.malloc(read_size + 1)
if read_buf is None:
tf.close()
stdlib.free(path_buf)
return None
text_len: t.CInt64T = tf.read_all(read_buf, ULONG(read_size + 1))
text_len: int64 = tf.read_all(read_buf, ULONG(read_size + 1))
tf.close()
stdlib.free(path_buf)
@@ -1131,11 +1131,11 @@ class CallGenBase:
read_buf[text_len] = '\0'
# 构造搜索模式: "{sha1}.{class_name}.{method_name}" 或 bare 模式 "{sha1}.{method_name}"
cls_len: t.CSizeT = 0
cls_len: sizet = 0
if class_name is not None:
cls_len = string.strlen(class_name)
meth_len: t.CSizeT = string.strlen(method_name)
search_len: t.CSizeT = sha1_len + meth_len + 2
meth_len: sizet = string.strlen(method_name)
search_len: sizet = sha1_len + meth_len + 2
if use_bare == 0:
search_len = sha1_len + cls_len + meth_len + 4
search_buf: bytes = stdlib.malloc(search_len)
@@ -1148,33 +1148,33 @@ class CallGenBase:
else:
viperlib.snprintf(search_buf, search_len, "%s.%s.%s",
class_sha1, class_name, method_name)
search_str_len: t.CSizeT = string.strlen(search_buf)
search_str_len: sizet = string.strlen(search_buf)
# 在 text.ll 中搜索 define 行包含 search_buf
buf_len: t.CSizeT = string.strlen(read_buf)
pos: t.CSizeT = 0
buf_len: sizet = string.strlen(read_buf)
pos: sizet = 0
result_ty: llvmlite.LLVMType | t.CPtr = None
while pos < buf_len and result_ty is None:
ls: t.CSizeT = pos
le: t.CSizeT = pos
ls: sizet = pos
le: sizet = pos
while le < buf_len:
if read_buf[le] == '\n':
break
le += 1
ll: t.CSizeT = le - ls
ll: sizet = le - ls
# 检查是否是 define 行
if ll >= 7 and string.strncmp(read_buf + ls, "define ", 7) == 0:
# 找 @ 符号
at_pos: t.CSizeT = ls + 7
at_pos: sizet = ls + 7
while at_pos < ls + ll:
if read_buf[at_pos] == '@':
break
at_pos += 1
if at_pos < ls + ll:
# 跳过可选引号
name_start: t.CSizeT = at_pos + 1
name_start: sizet = at_pos + 1
if name_start < ls + ll and read_buf[name_start] == '"':
name_start += 1
# 检查是否匹配 search_buf
@@ -1182,7 +1182,7 @@ class CallGenBase:
if string.strncmp(read_buf + name_start, search_buf, search_str_len) == 0:
# 函数名边界检查:search 后必须是 '"'(带引号名)、'('(参数表)或行尾,
# 否则 "sha1.func" 会误匹配 "sha1.func_helper" 等前缀同名函数
name_end: t.CSizeT = name_start + search_str_len
name_end: sizet = name_start + search_str_len
end_ch: int = 0
if name_end < ls + ll:
end_ch = read_buf[name_end]
@@ -1211,10 +1211,10 @@ class CallGenBase:
"""探测 {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: t.CSizeT = string.strlen(sha1)
sha1_len: sizet = string.strlen(sha1)
if sha1_len < 2:
return 0
path_len: t.CSizeT = self.Gen.CallGenBase.TempDirLen + sha1_len + 14
path_len: sizet = self.Gen.CallGenBase.TempDirLen + sha1_len + 14
path_buf: bytes = stdlib.malloc(path_len)
subdir_buf: bytes = stdlib.malloc(3)
if path_buf is None or subdir_buf is None:
@@ -1251,10 +1251,10 @@ class CallGenBase:
dep_sha1: str, extra: str) -> None:
"""追加一行 MRO/VPI pending 明细到诊断文件(文件不存在则创建)"""
td: str = self.Gen.CallGenBase.TempDir
td_len: t.CSizeT = self.Gen.CallGenBase.TempDirLen
td_len: sizet = self.Gen.CallGenBase.TempDirLen
if td is None or td_len == 0 or owner_sha1 is None or kind is None:
return
path_len: t.CSizeT = td_len + 24
path_len: sizet = td_len + 24
path_buf: bytes = stdlib.malloc(path_len)
if path_buf is None:
return
@@ -1271,7 +1271,7 @@ class CallGenBase:
method_name if method_name is not None else "-",
dep_sha1 if dep_sha1 is not None else "-",
extra if extra is not None else "-")
ln: t.CSizeT = string.strlen(line)
ln: sizet = string.strlen(line)
pf.write(line, ln)
stdlib.free(line)
pf.close()
+47 -47
View File
@@ -39,7 +39,7 @@ def _IsCastWrappingDeref(rhs: ast.AST | t.CPtr, deref_node: ast.AST | t.CPtr) ->
"""rhs 是否为"类型转换链包裹 c.Deref"(如 (T | t.CPtr)(t.CPtr(c.Deref(p))))"""
if rhs is None:
return 0
if t.CUInt64T(rhs) == t.CUInt64T(deref_node):
if uint64(rhs) == uint64(deref_node):
return 1
if rhs.kind() == ast.ASTKind.Call:
cl: ast.Call | t.CPtr = (ast.Call | t.CPtr)(rhs)
@@ -112,15 +112,15 @@ class CallGenCBuiltin(CallGenBase.CallGenBase):
match pointee:
case llvmlite.LLVMType.Int(pointee_width):
# 允许推断:c.Deref 是赋值语句直接 RHS(v: int = c.Deref(p))
# 或处于类型转换链包裹中(如 vt: t.CVoid | t.CPtr =
# 或处于类型转换链包裹中(如 vt: t.CPtr =
# t.CVoid(c.Deref(p)))。嵌套在 while 条件/比较/binop/
# 其他调用中(如 while c.Deref(p) != 0、total +=
# t.CInt(c.Deref(p)))不推断,否则 i8* 会被残留
# int(c.Deref(p)))不推断,否则 i8* 会被残留
# CurAssignAnnot 误判为 i32* 读 4 字节 → StringIterTest
# ASCII sum/manual strcmp 失败。
allow_infer: int = 0
if trans is not None and trans.CurAssignNode is not None:
if t.CUInt64T(cl) == t.CUInt64T(trans.CurAssignNode):
if uint64(cl) == uint64(trans.CurAssignNode):
allow_infer = 1
elif _IsCastWrappingDeref(trans.CurAssignNode, cl) != 0:
allow_infer = 1
@@ -410,7 +410,7 @@ class CallGenCBuiltin(CallGenBase.CallGenBase):
f_addr_name: str = llvmlite.function_get_name(f_addr_ref)
if f_addr_name is not None:
p_head_ca: llvmlite.Param | t.CPtr = llvmlite.function_get_param_head(f_addr_ref)
p_cnt_ca: t.CSizeT = 0
p_cnt_ca: sizet = 0
p_cur_ca: llvmlite.Param | t.CPtr = p_head_ca
while p_cur_ca is not None:
p_cnt_ca += 1
@@ -420,7 +420,7 @@ class CallGenCBuiltin(CallGenBase.CallGenBase):
# 函数引用名需按需加引号(数字开头/含 '.' 的 sha1 前缀名
# 必须 @\"...\",否则 llc "expected 'to' after cast value",
# uhci.vp c.Addr(_on_int_complete) 根因)。
fnlen_ca: t.CSizeT = string.strlen(f_addr_name)
fnlen_ca: sizet = string.strlen(f_addr_name)
needs_q_ca: int = self.Gen.ClassGenVTable._vtable_name_needs_quote(f_addr_name)
faddr_buf_ca: str = pool.alloc(fnlen_ca + 4)
if faddr_buf_ca is not None and fn_ty_ca is not None:
@@ -502,7 +502,7 @@ class CallGenCBuiltin(CallGenBase.CallGenBase):
# Next 当 Name/Ty → 垃圾参数类型
# "i32 (i1425633744, i8*)"(elf.vp L2874 根因)。
p_head2: llvmlite.Param | t.CPtr = llvmlite.function_get_param_head(f_ref2)
p_cnt2: t.CSizeT = 0
p_cnt2: sizet = 0
p_cur2: llvmlite.Param | t.CPtr = p_head2
while p_cur2 is not None:
p_cnt2 += 1
@@ -511,7 +511,7 @@ class CallGenCBuiltin(CallGenBase.CallGenBase):
pool, f_ref2.RetTy, p_head2, p_cnt2)
# 函数引用名按需加引号(数字开头/含 '.' 的
# sha1 前缀名必须 @\"...\")。
fnlen2: t.CSizeT = string.strlen(fname2)
fnlen2: sizet = string.strlen(fname2)
needs_q2: int = self.Gen.ClassGenVTable._vtable_name_needs_quote(fname2)
faddr_buf2: str = pool.alloc(fnlen2 + 4)
if faddr_buf2 is not None and fn_ty2 is not None:
@@ -715,17 +715,17 @@ class CallGenCBuiltin(CallGenBase.CallGenBase):
return loaded
def _asm_append_cstr(self, dst: str, dst_size: t.CSizeT,
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: t.CSizeT = string.strlen(dst)
slen: t.CSizeT = string.strlen(src)
remain: t.CSizeT = dst_size - dlen
dlen: sizet = string.strlen(dst)
slen: sizet = string.strlen(src)
remain: sizet = dst_size - dlen
if remain <= 0:
return
i: t.CSizeT = 0
i: sizet = 0
while i < slen and i + 1 < remain:
dst[dlen + i] = src[i]
i += 1
@@ -733,7 +733,7 @@ class CallGenCBuiltin(CallGenBase.CallGenBase):
def _asm_mangle_global_symbols(self, pool: memhub.MemBuddy | t.CPtr,
asm_text: str, asm_size: t.CSizeT,
asm_text: str, asm_size: sizet,
mod: llvmlite.LLVMModule | t.CPtr) -> str:
"""asm 模板中裸符号引用模块全局的检查(fail-fast)
@@ -746,15 +746,15 @@ class CallGenCBuiltin(CallGenBase.CallGenBase):
"""
if asm_text is None or mod is None:
return asm_text
src_len: t.CSizeT = string.strlen(asm_text)
src_len: sizet = string.strlen(asm_text)
if src_len == 0:
return asm_text
out: str = pool.alloc(asm_size * 2)
if out is None:
return asm_text
out[0] = '\0'
out_pos: t.CSizeT = 0
i: t.CSizeT = 0
out_pos: sizet = 0
i: sizet = 0
while i < src_len:
matched: int = 0
cur: llvmlite.GlobalVariable | t.CPtr = mod.GlobalHead
@@ -763,21 +763,21 @@ class CallGenCBuiltin(CallGenBase.CallGenBase):
if gname is not None and string.strchr(gname, 46) is not None:
dot_g: str = string.strchr(gname, 46)
bare_g: str = dot_g + 1
bare_len: t.CSizeT = string.strlen(bare_g)
bare_len: sizet = string.strlen(bare_g)
if bare_len > 0 and i + bare_len <= src_len:
if string.strncmp(asm_text + i, bare_g, bare_len) == 0:
# 词边界:前后非标识符字符(字母/数字/_)
prev_ok: int = 1
next_ok: int = 1
if i > 0:
prev_ch: t.CChar = asm_text[i - 1]
prev_ch: char = asm_text[i - 1]
if (prev_ch >= 'a' and prev_ch <= 'z') \
or (prev_ch >= 'A' and prev_ch <= 'Z') \
or (prev_ch >= '0' and prev_ch <= '9') \
or prev_ch == '_':
prev_ok = 0
if i + bare_len < src_len:
next_ch: t.CChar = asm_text[i + bare_len]
next_ch: char = asm_text[i + bare_len]
if (next_ch >= 'a' and next_ch <= 'z') \
or (next_ch >= 'A' and next_ch <= 'Z') \
or (next_ch >= '0' and next_ch <= '9') \
@@ -809,11 +809,11 @@ class CallGenCBuiltin(CallGenBase.CallGenBase):
"""转义汇编文本用于 LLVM IR 字符串字面量"""
if src is None:
return None
slen: t.CSizeT = string.strlen(src)
slen: sizet = string.strlen(src)
buf: str = pool.alloc(slen * 4 + 8)
if buf is None:
return None
pos: t.CSizeT = 0
pos: sizet = 0
for ch in src:
if ch == '\n':
buf[pos] = '\\'
@@ -953,8 +953,8 @@ class CallGenCBuiltin(CallGenBase.CallGenBase):
if bop.op == ast.OpKind.BitOr:
left_str: str = self._resolve_asm_descr(pool, bop.left)
right_str: str = self._resolve_asm_descr(pool, bop.right)
llen: t.CSizeT = string.strlen(left_str)
rlen: t.CSizeT = string.strlen(right_str)
llen: sizet = string.strlen(left_str)
rlen: sizet = string.strlen(right_str)
buf: str = pool.alloc(llen + rlen + 1)
if buf is None:
return ""
@@ -996,8 +996,8 @@ class CallGenCBuiltin(CallGenBase.CallGenBase):
def _asm_get_operand(self, base: GenTypes.AsmOperand | t.CPtr,
idx: int) -> GenTypes.AsmOperand | t.CPtr:
"""获取操作数数组中第 idx 个元素的指针"""
entry_size: t.CSizeT = GenTypes.AsmOperand.__sizeof__()
entry_addr: t.CUInt64T = t.CUInt64T(base) + idx * entry_size
entry_size: sizet = GenTypes.AsmOperand.__sizeof__()
entry_addr: uint64 = uint64(base) + idx * entry_size
return (GenTypes.AsmOperand | t.CPtr)(t.CVoid(entry_addr, t.CPtr))
@@ -1025,7 +1025,7 @@ class CallGenCBuiltin(CallGenBase.CallGenBase):
if name is None:
return 0
n: str = name
nlen: t.CSizeT = string.strlen(n)
nlen: sizet = string.strlen(n)
# 去掉 '@"..."' 包装(引用名)
if nlen >= 3 and n[0] == '@' and n[1] == '"' and n[nlen - 1] == '"':
n = n + 2
@@ -1039,7 +1039,7 @@ class CallGenCBuiltin(CallGenBase.CallGenBase):
if n[i] == '.':
ok: int = 1
for j in range(16):
cc: t.CChar = n[i - 16 + j]
cc: char = n[i - 16 + j]
if not (('0' <= cc <= '9') or ('a' <= cc <= 'f') or ('A' <= cc <= 'F')):
ok = 0
break
@@ -1108,7 +1108,7 @@ class CallGenCBuiltin(CallGenBase.CallGenBase):
return None
# 分配操作数数组
operand_size: t.CSizeT = GenTypes.AsmOperand.__sizeof__()
operand_size: sizet = GenTypes.AsmOperand.__sizeof__()
operands: GenTypes.AsmOperand | t.CPtr = pool.alloc(operand_size * ASM_MAX_OPERANDS)
if operands is None:
return None
@@ -1138,7 +1138,7 @@ class CallGenCBuiltin(CallGenBase.CallGenBase):
out_ret_ty_first: llvmlite.LLVMType | t.CPtr = None
# 全量输出元素类型按序缓存(多输出如 vrandom rdrand*_step 的 val+ok):
# 同样在收集时直接从 alloca 取 Pointee,绕开 AsmOperand 槽读不稳定。
out_ptys: t.CSizeT | t.CPtr = pool.alloc(8 * ASM_MAX_OPERANDS)
out_ptys: sizet | t.CPtr = pool.alloc(8 * ASM_MAX_OPERANDS)
out_pty_n: int = 0
if out_ptys is not None:
string.memset(out_ptys, 0, 8 * ASM_MAX_OPERANDS)
@@ -1161,7 +1161,7 @@ class CallGenCBuiltin(CallGenBase.CallGenBase):
js: ast.JoinedStr | t.CPtr = (ast.JoinedStr | t.CPtr)(tmpl_node)
jvalues: list[ast.AST | t.CPtr] | t.CPtr = js.values
if jvalues is not None:
jvlen: t.CSizeT = len(jvalues)
jvlen: sizet = len(jvalues)
for vi in range(jvlen):
part: ast.AST | t.CPtr = jvalues.get(vi)
if part is None:
@@ -1260,7 +1260,7 @@ class CallGenCBuiltin(CallGenBase.CallGenBase):
if out_ptys is not None and out_pty_n < ASM_MAX_OPERANDS \
and alloca is not None and alloca.Ty is not None \
and alloca.Ty.Pointee is not None:
out_ptys[out_pty_n] = t.CUInt64T(alloca.Ty.Pointee)
out_ptys[out_pty_n] = uint64(alloca.Ty.Pointee)
out_pty_n += 1
else:
# 输入:翻译值
@@ -1281,7 +1281,7 @@ class CallGenCBuiltin(CallGenBase.CallGenBase):
# ============================================================
keywords: list[ast.AST | t.CPtr] | t.CPtr = cl.keywords
if keywords is not None:
kwlen: t.CSizeT = len(keywords)
kwlen: sizet = len(keywords)
for ki in range(kwlen):
kw: ast.Keyword | t.CPtr = (ast.Keyword | t.CPtr)(keywords.get(ki))
if kw is None or kw.arg is None or kw.value is None:
@@ -1296,7 +1296,7 @@ class CallGenCBuiltin(CallGenBase.CallGenBase):
out_elts: list[ast.AST | t.CPtr] | t.CPtr = out_lst.elts
if out_elts is None:
continue
oelen: t.CSizeT = len(out_elts)
oelen: sizet = len(out_elts)
for oi in range(oelen):
oelt: ast.AST | t.CPtr = out_elts.get(oi)
if oelt is None or oelt.kind() != ast.ASTKind.Call:
@@ -1328,7 +1328,7 @@ class CallGenCBuiltin(CallGenBase.CallGenBase):
if out_ptys is not None and out_pty_n < ASM_MAX_OPERANDS \
and oalloca is not None and oalloca.Ty is not None \
and oalloca.Ty.Pointee is not None:
out_ptys[out_pty_n] = t.CUInt64T(oalloca.Ty.Pointee)
out_ptys[out_pty_n] = uint64(oalloca.Ty.Pointee)
out_pty_n += 1
elif string.strcmp(kw.arg, "inp") == 0 or string.strcmp(kw.arg, "inputs") == 0:
@@ -1339,7 +1339,7 @@ class CallGenCBuiltin(CallGenBase.CallGenBase):
in_elts: list[ast.AST | t.CPtr] | t.CPtr = in_lst.elts
if in_elts is None:
continue
ielen: t.CSizeT = len(in_elts)
ielen: sizet = len(in_elts)
for ii in range(ielen):
ielt: ast.AST | t.CPtr = in_elts.get(ii)
if ielt is None or ielt.kind() != ast.ASTKind.Call:
@@ -1370,7 +1370,7 @@ class CallGenCBuiltin(CallGenBase.CallGenBase):
cl_elts: list[ast.AST | t.CPtr] | t.CPtr = cl_lst.elts
if cl_elts is None:
continue
clen: t.CSizeT = len(cl_elts)
clen: sizet = len(cl_elts)
for ci in range(clen):
celt: ast.AST | t.CPtr = cl_elts.get(ci)
if celt is None:
@@ -1379,7 +1379,7 @@ class CallGenCBuiltin(CallGenBase.CallGenBase):
if cstr is None or cstr[0] == '\0':
continue
if clobber_count < ASM_MAX_CLOBBERS:
cl_addr: t.CUInt64T = t.CUInt64T(clobbers) + clobber_count * 8
cl_addr: uint64 = uint64(clobbers) + clobber_count * 8
cl_ptr: str | t.CPtr = (str | t.CPtr)(t.CVoid(cl_addr, t.CPtr))
cl_ptr[0] = cstr
clobber_count += 1
@@ -1393,7 +1393,7 @@ class CallGenCBuiltin(CallGenBase.CallGenBase):
pos_lst: ast.List | t.CPtr = (ast.List | t.CPtr)(pos_node)
pos_elts: list[ast.AST | t.CPtr] | t.CPtr = pos_lst.elts
if pos_elts is not None:
plen: t.CSizeT = len(pos_elts)
plen: sizet = len(pos_elts)
for pi in range(plen):
pelt: ast.AST | t.CPtr = pos_elts.get(pi)
if pelt is None:
@@ -1402,7 +1402,7 @@ class CallGenCBuiltin(CallGenBase.CallGenBase):
if pstr is None or pstr[0] == '\0':
continue
if clobber_count < ASM_MAX_CLOBBERS:
pcl_addr: t.CUInt64T = t.CUInt64T(clobbers) + clobber_count * 8
pcl_addr: uint64 = uint64(clobbers) + clobber_count * 8
pcl_ptr: str | t.CPtr = (str | t.CPtr)(t.CVoid(pcl_addr, t.CPtr))
pcl_ptr[0] = pstr
clobber_count += 1
@@ -1545,7 +1545,7 @@ class CallGenCBuiltin(CallGenBase.CallGenBase):
js2: ast.JoinedStr | t.CPtr = (ast.JoinedStr | t.CPtr)(tmpl_node)
jvalues2: list[ast.AST | t.CPtr] | t.CPtr = js2.values
if jvalues2 is not None:
jvlen2: t.CSizeT = len(jvalues2)
jvlen2: sizet = len(jvalues2)
fv_fi: int = 0
for vi2 in range(jvlen2):
part2: ast.AST | t.CPtr = jvalues2.get(vi2)
@@ -1600,7 +1600,7 @@ class CallGenCBuiltin(CallGenBase.CallGenBase):
# 追加 clobber 约束 ~{name}
for cidx in range(clobber_count):
cl_addr2: t.CUInt64T = t.CUInt64T(clobbers) + cidx * 8
cl_addr2: uint64 = uint64(clobbers) + cidx * 8
cname: str = (str | t.CPtr)(t.CVoid(cl_addr2, t.CPtr))[0]
if cname is None or cname[0] == '\0':
continue
@@ -1743,8 +1743,8 @@ class CallGenCBuiltin(CallGenBase.CallGenBase):
self.Gen.TypeGenErr.fatal_error(cl, "c.LLVMIR 缺少模板参数", "TypeError")
# LOut 写回记录(alloca 指针 + 寄存器名),最多 LLVMIR_MAX_OPS 个
out_alloca: t.CSizeT | t.CPtr = pool.alloc(8 * LLVMIR_MAX_OPS)
out_regname: t.CSizeT | t.CPtr = pool.alloc(8 * LLVMIR_MAX_OPS)
out_alloca: sizet | t.CPtr = pool.alloc(8 * LLVMIR_MAX_OPS)
out_regname: sizet | t.CPtr = pool.alloc(8 * LLVMIR_MAX_OPS)
if out_alloca is None or out_regname is None:
return None
string.memset(out_alloca, 0, 8 * LLVMIR_MAX_OPS)
@@ -1770,7 +1770,7 @@ class CallGenCBuiltin(CallGenBase.CallGenBase):
js: ast.JoinedStr | t.CPtr = (ast.JoinedStr | t.CPtr)(first_arg)
jvalues: list[ast.AST | t.CPtr] | t.CPtr = js.values
if jvalues is not None:
jvlen: t.CSizeT = len(jvalues)
jvlen: sizet = len(jvalues)
for vi in range(jvlen):
part: ast.AST | t.CPtr = jvalues.get(vi)
if part is None:
@@ -1823,8 +1823,8 @@ class CallGenCBuiltin(CallGenBase.CallGenBase):
if reg_buf is not None:
viperlib.snprintf(reg_buf, 32, "%%llvmir_%d", self.Gen.CallGenBase.LLVMIRRegSeq)
self._asm_append_cstr(text, LLVMIR_TEMPLATE_BUF, reg_buf)
out_alloca[out_count] = t.CSizeT(alloca)
out_regname[out_count] = t.CSizeT(reg_buf)
out_alloca[out_count] = sizet(alloca)
out_regname[out_count] = sizet(reg_buf)
out_count += 1
continue
# 非 c.LInp/c.LOut 的 f-string 表达式:翻译值并嵌入值文本
+46 -46
View File
@@ -95,9 +95,9 @@ class CallGenCall(CallGenBase.CallGenBase):
# 2. 获取方法在虚表中的索引(用 entry 直接查找)
method_index: int = -1
if vc_entry is not None and vc_entry.VTableMethods is not None:
methods_arr: t.CSizeT | t.CPtr = (t.CSizeT | t.CPtr)(t.CVoid(vc_entry.VTableMethods, t.CPtr))
methods_arr: sizet | t.CPtr = (sizet | t.CPtr)(t.CVoid(vc_entry.VTableMethods, t.CPtr))
for mi in range(vc_entry.VTableMethodCount):
mname_addr: t.CSizeT = methods_arr[mi]
mname_addr: sizet = methods_arr[mi]
if mname_addr == 0:
continue
mname: str = (str | t.CPtr)(t.CVoid(mname_addr, t.CPtr))
@@ -218,7 +218,7 @@ class CallGenCall(CallGenBase.CallGenBase):
class_name: str,
method_name: str,
self_ptr: llvmlite.Value | t.CPtr,
extra_args: t.CSizeT | t.CPtr,
extra_args: sizet | t.CPtr,
extra_count: int,
trans: HT.Translator | t.CPtr,
node: ast.AST | t.CPtr = None) -> llvmlite.Value | t.CPtr:
@@ -416,7 +416,7 @@ class CallGenCall(CallGenBase.CallGenBase):
if extra_args is not None and extra_count > 0:
for ei in range(extra_count):
arg_addr: t.CSizeT = extra_args[ei]
arg_addr: sizet = extra_args[ei]
if arg_addr == 0:
continue
av: llvmlite.Value | t.CPtr = (llvmlite.Value | t.CPtr)(t.CVoid(arg_addr, t.CPtr))
@@ -430,7 +430,7 @@ class CallGenCall(CallGenBase.CallGenBase):
# 默认参数填充:如果调用点参数少于函数定义参数,用默认值填充缺失参数
# 优先用函数定义的默认值,无默认值时用零值兜底
# 查找函数的 defaults 信息
mdf_defaults: t.CVoid | t.CPtr = None
mdf_defaults: t.CPtr = None
mdf_default_count: int = 0
mdf_param_count: int = 0
if trans is not None and trans._funcs is not None:
@@ -465,7 +465,7 @@ class CallGenCall(CallGenBase.CallGenBase):
pool, vpi_sha1_p, class_name, method_name)
if vpi_pa is not None and vpi_pa[0] != '\0':
vpi_pc2: int = 1
vi2: t.CSizeT = 0
vi2: sizet = 0
while vpi_pa[vi2] != '\0':
if vpi_pa[vi2] == '@':
vpi_pc2 += 1
@@ -548,13 +548,13 @@ class CallGenCall(CallGenBase.CallGenBase):
# 值取类型零值(默认参数值恰为零值;查不到 ≠ 无默认值)。
seg_idx_v: int = mdf_pi + 1
seg_no_v: int = 0
seg_cur_v: t.CSizeT = 0
seg_cur_v: sizet = 0
while seg_no_v < seg_idx_v and vpi_pa[seg_cur_v] != '\0':
if vpi_pa[seg_cur_v] == '@':
seg_no_v += 1
seg_cur_v += 1
seg_start_v: t.CSizeT = seg_cur_v
seg_len_v: t.CSizeT = 0
seg_start_v: sizet = seg_cur_v
seg_len_v: sizet = 0
while vpi_pa[seg_start_v + seg_len_v] != '\0' \
and vpi_pa[seg_start_v + seg_len_v] != '@':
seg_len_v += 1
@@ -596,7 +596,7 @@ class CallGenCall(CallGenBase.CallGenBase):
param_node = llvmlite.param_get_next(param_node)
# 参数类型强制转换:按 found_func 的形参类型 coerce 每个实参(含 self)。
# 修复: 构造器调用 __init__(ptr, base, 4096) 时 size 形参是 i64 (t.CSizeT),
# 修复: 构造器调用 __init__(ptr, base, 4096) 时 size 形参是 i64 (sizet),
# 但 4096 字面量按 i32 传递,未提升导致运行时 size 高 32 位垃圾,
# 破坏伙伴分配器的池大小元数据(如 total=2048)引发 calloc 失败/OOM。
# self 在运算符重载路径 2(lhs 为 X|t.CPtr 联合简化的 Vec3** 对象指针)时
@@ -635,9 +635,9 @@ class CallGenCall(CallGenBase.CallGenBase):
if cmop_entry is not None:
cmop_has_vt = cmop_entry.HasVTable
if cmop_has_vt == 1 and cmop_entry.VTableMethods is not None:
cmop_methods_arr: t.CSizeT | t.CPtr = (t.CSizeT | t.CPtr)(t.CVoid(cmop_entry.VTableMethods, t.CPtr))
cmop_methods_arr: sizet | t.CPtr = (sizet | t.CPtr)(t.CVoid(cmop_entry.VTableMethods, t.CPtr))
for cmop_mi in range(cmop_entry.VTableMethodCount):
cmop_mname_addr: t.CSizeT = cmop_methods_arr[cmop_mi]
cmop_mname_addr: sizet = cmop_methods_arr[cmop_mi]
if cmop_mname_addr == 0:
continue
cmop_mname: str = (str | t.CPtr)(t.CVoid(cmop_mname_addr, t.CPtr))
@@ -724,7 +724,7 @@ class CallGenCall(CallGenBase.CallGenBase):
pass
if lb_obj is not None:
lb_cargs: list[ast.AST | t.CPtr] | t.CPtr = cl.args
lb_can: t.CSizeT = 0
lb_can: sizet = 0
if lb_cargs is not None:
lb_can = len(lb_cargs)
return self._translate_list_builtin_call(
@@ -762,7 +762,7 @@ class CallGenCall(CallGenBase.CallGenBase):
# 沿 MRO 祖先链查找父类方法(子类未覆盖时回退到父类,先声明父类优先)
mc_anc: str = None # 方法实际定义类(多继承 this 调整用)
if found_func is None:
mro_ptr: t.CSizeT | t.CPtr = self.Gen.StructGen.get_mro_chain(pool, class_name)
mro_ptr: sizet | t.CPtr = self.Gen.StructGen.get_mro_chain(pool, class_name)
mi: int = 1
while mro_ptr is not None and mro_ptr[mi] != 0:
anc: str = (str | t.CPtr)(t.CVoid(mro_ptr[mi], t.CPtr))
@@ -891,7 +891,7 @@ class CallGenCall(CallGenBase.CallGenBase):
match mc_struct_ty:
case llvmlite.LLVMType.Struct(_fs_sp, _fc_sp, type_name_sp):
if type_name_sp is not None and type_name_sp[0] != '\0':
tl_sp: t.CSizeT = string.strlen(type_name_sp)
tl_sp: sizet = string.strlen(type_name_sp)
if tl_sp >= 16:
sb_sp: str = pool.alloc(17)
if sb_sp is not None:
@@ -901,7 +901,7 @@ class CallGenCall(CallGenBase.CallGenBase):
case _:
pass
if sp_anc_sha1 is not None:
ml_sp: t.CSizeT = string.strlen(sp_anc_sha1) + string.strlen(sp_anc_name) \
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:
@@ -926,7 +926,7 @@ class CallGenCall(CallGenBase.CallGenBase):
call_ret_ty = mixin_ret_ty
if ret_anc_sha1 is None:
# 沿 MRO 找第一个有 SHA1 的类
mro_s0: t.CSizeT | t.CPtr = self.Gen.StructGen.get_mro_chain(pool, class_name)
mro_s0: sizet | t.CPtr = self.Gen.StructGen.get_mro_chain(pool, class_name)
mi_s0: int = 1
while mro_s0 is not None and mro_s0[mi_s0] != 0 and ret_anc_sha1 is None:
anc_s0: str = (str | t.CPtr)(t.CVoid(mro_s0[mi_s0], t.CPtr))
@@ -948,8 +948,8 @@ class CallGenCall(CallGenBase.CallGenBase):
if lbkt_g is not None:
rbkt_g: str = string.strrchr(class_name, ']')
if rbkt_g is not None and rbkt_g > lbkt_g:
base_len_g: t.CSizeT = t.CSizeT(t.CUInt64T(lbkt_g) - t.CUInt64T(class_name))
arg_len_g: t.CSizeT = t.CSizeT(t.CUInt64T(rbkt_g) - t.CUInt64T(lbkt_g) - 1)
base_len_g: sizet = sizet(uint64(lbkt_g) - uint64(class_name))
arg_len_g: sizet = sizet(uint64(rbkt_g) - uint64(lbkt_g) - 1)
if base_len_g > 0 and arg_len_g > 0:
base_buf_g: str = pool.alloc(base_len_g + 1)
arg_buf_g: str = pool.alloc(arg_len_g + 1)
@@ -967,7 +967,7 @@ class CallGenCall(CallGenBase.CallGenBase):
if comma_g is None:
ta_list_g.append(cur_arg_g)
break
seg_len_g: t.CSizeT = t.CSizeT(t.CUInt64T(comma_g) - t.CUInt64T(cur_arg_g))
seg_len_g: sizet = sizet(uint64(comma_g) - uint64(cur_arg_g))
seg_buf_g: str = pool.alloc(seg_len_g + 1)
if seg_buf_g is not None:
string.strncpy(seg_buf_g, cur_arg_g, seg_len_g)
@@ -981,7 +981,7 @@ class CallGenCall(CallGenBase.CallGenBase):
is_sha1_pfx_g: int = 1
si_g: int
for si_g in range(16):
cg_g: t.CChar = base_buf_g[si_g]
cg_g: char = base_buf_g[si_g]
if not (('0' <= cg_g <= '9') or ('a' <= cg_g <= 'f')):
is_sha1_pfx_g = 0
break
@@ -1048,7 +1048,7 @@ class CallGenCall(CallGenBase.CallGenBase):
# 及其 sha1 查不到,需用每个祖先类的类名 + 祖先类所属模块 sha1
# 查 text.ll(NewAstTest mod.append 根因)
if looked_up_ty is None:
mro_t2: t.CSizeT | t.CPtr = self.Gen.StructGen.get_mro_chain(pool, class_name)
mro_t2: sizet | t.CPtr = self.Gen.StructGen.get_mro_chain(pool, class_name)
mi_t2: int = 1
while mro_t2 is not None and mro_t2[mi_t2] != 0 and looked_up_ty is None:
anc_t2: str = (str | t.CPtr)(t.CVoid(mro_t2[mi_t2], t.CPtr))
@@ -1068,7 +1068,7 @@ class CallGenCall(CallGenBase.CallGenBase):
pool, ret_anc_sha1, ret_anc_name, method_name)
# vpi 同样沿 MRO 祖先链重试(基类方法注解,用祖先类自身 sha1)
if vpi_ret_ty is None:
mro_v2: t.CSizeT | t.CPtr = self.Gen.StructGen.get_mro_chain(pool, class_name)
mro_v2: sizet | t.CPtr = self.Gen.StructGen.get_mro_chain(pool, class_name)
mi_v2: int = 1
while mro_v2 is not None and mro_v2[mi_v2] != 0 and vpi_ret_ty is None:
anc_v2: str = (str | t.CPtr)(t.CVoid(mro_v2[mi_v2], t.CPtr))
@@ -1130,7 +1130,7 @@ class CallGenCall(CallGenBase.CallGenBase):
# 任一祖先的 sha1 取不到或其 text.ll 未生成 → 结果不确定,
# 标记 pending 下遍重试(届时祖先 text.ll 生成,MRO 重试
# 可精确解析);全部祖先就绪仍查不到才是真错误。
mro_p2: t.CSizeT | t.CPtr = self.Gen.StructGen.get_mro_chain(pool, class_name)
mro_p2: sizet | t.CPtr = self.Gen.StructGen.get_mro_chain(pool, class_name)
mi_p2: int = 1
anc_missing_p2: int = 0
while mro_p2 is not None and mro_p2[mi_p2] != 0:
@@ -1178,7 +1178,7 @@ class CallGenCall(CallGenBase.CallGenBase):
match mc_struct_ty:
case llvmlite.LLVMType.Struct(_fields_st, _fcount_st, type_name_st):
if type_name_st is not None and type_name_st[0] != '\0':
type_len_st: t.CSizeT = string.strlen(type_name_st)
type_len_st: sizet = string.strlen(type_name_st)
if type_len_st >= 16:
sha1_from_ty: str = pool.alloc(17)
if sha1_from_ty is not None:
@@ -1188,7 +1188,7 @@ class CallGenCall(CallGenBase.CallGenBase):
case _:
pass
if ret_anc_name is not None and ret_anc_sha1 is not None:
ml_anc: t.CSizeT = string.strlen(ret_anc_sha1) + string.strlen(ret_anc_name) \
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:
@@ -1208,11 +1208,11 @@ class CallGenCall(CallGenBase.CallGenBase):
# 翻译调用参数
cargs: list[ast.AST | t.CPtr] | t.CPtr = cl.args
can: t.CSizeT = 0
can: sizet = 0
if cargs is not None:
can = len(cargs)
kw_calls: list[ast.AST | t.CPtr] | t.CPtr = cl.keywords
kwc: t.CSizeT = 0
kwc: sizet = 0
if kw_calls is not None:
kwc = len(kw_calls)
@@ -1234,7 +1234,7 @@ class CallGenCall(CallGenBase.CallGenBase):
# fail-fast——绝不静默用未调整的 obj_ptr 当 self,否则方法按自身
# 布局读字段读到垃圾(lookup_reexport strcmp 概率崩溃根因候选)。
is_first_parent_th: int = 0
mro_fp_th: t.CSizeT | t.CPtr = self.Gen.StructGen.get_mro_chain(pool, class_name)
mro_fp_th: sizet | t.CPtr = self.Gen.StructGen.get_mro_chain(pool, class_name)
if mro_fp_th is not None and mro_fp_th[1] != 0:
first_parent_th: str = (str | t.CPtr)(t.CVoid(mro_fp_th[1], t.CPtr))
if first_parent_th is not None and string.strcmp(first_parent_th, mc_anc) == 0:
@@ -1436,7 +1436,7 @@ class CallGenCall(CallGenBase.CallGenBase):
if arg_val is None:
continue
# 按形参类型 coerce(self 是形参 0,第 ai 个实参对应形参 ai+1)
# 修复: CDefine/i32 常量传给 i64 形参(如 MemBuddy.__init__ 的 size: t.CSizeT)
# 修复: CDefine/i32 常量传给 i64 形参(如 MemBuddy.__init__ 的 size: sizet)
# 未提升导致 call(i32) 与 define(i64) 不匹配,运行时读到垃圾高 32 位崩溃
if found_func is not None:
if pty is not None:
@@ -1468,7 +1468,7 @@ class CallGenCall(CallGenBase.CallGenBase):
# 默认参数填充:如果调用点参数少于函数定义参数,用默认值填充缺失参数
# 查找函数的 defaults 信息
mdf_defaults: t.CVoid | t.CPtr = None
mdf_defaults: t.CPtr = None
mdf_default_count: int = 0
mdf_param_count: int = 0
if trans is not None and trans._funcs is not None:
@@ -1506,7 +1506,7 @@ class CallGenCall(CallGenBase.CallGenBase):
pool, vpi_sha1_p, class_name, method_name)
if vpi_pa is not None and vpi_pa[0] != '\0':
vpi_pc2: int = 1
vi2: t.CSizeT = 0
vi2: sizet = 0
while vpi_pa[vi2] != '\0':
if vpi_pa[vi2] == '@':
vpi_pc2 += 1
@@ -1588,13 +1588,13 @@ class CallGenCall(CallGenBase.CallGenBase):
# 值取类型零值(默认参数值恰为零值;查不到 ≠ 无默认值)。
seg_idx_v: int = mdf_pi + 1
seg_no_v: int = 0
seg_cur_v: t.CSizeT = 0
seg_cur_v: sizet = 0
while seg_no_v < seg_idx_v and vpi_pa[seg_cur_v] != '\0':
if vpi_pa[seg_cur_v] == '@':
seg_no_v += 1
seg_cur_v += 1
seg_start_v: t.CSizeT = seg_cur_v
seg_len_v: t.CSizeT = 0
seg_start_v: sizet = seg_cur_v
seg_len_v: sizet = 0
while vpi_pa[seg_start_v + seg_len_v] != '\0' \
and vpi_pa[seg_start_v + seg_len_v] != '@':
seg_len_v += 1
@@ -1626,9 +1626,9 @@ class CallGenCall(CallGenBase.CallGenBase):
if mc_entry is not None:
mc_has_vt = mc_entry.HasVTable
if mc_has_vt == 1 and mc_entry.VTableMethods is not None:
mc_methods_arr: t.CSizeT | t.CPtr = (t.CSizeT | t.CPtr)(t.CVoid(mc_entry.VTableMethods, t.CPtr))
mc_methods_arr: sizet | t.CPtr = (sizet | t.CPtr)(t.CVoid(mc_entry.VTableMethods, t.CPtr))
for mc_mi in range(mc_entry.VTableMethodCount):
mc_mname_addr: t.CSizeT = mc_methods_arr[mc_mi]
mc_mname_addr: sizet = mc_methods_arr[mc_mi]
if mc_mname_addr == 0:
continue
mc_mname: str = (str | t.CPtr)(t.CVoid(mc_mname_addr, t.CPtr))
@@ -1675,7 +1675,7 @@ class CallGenCall(CallGenBase.CallGenBase):
lm_name: str,
lm_obj: llvmlite.Value | t.CPtr,
cargs: list[ast.AST | t.CPtr] | t.CPtr,
can: t.CSizeT,
can: sizet,
trans: HT.Translator | t.CPtr) -> llvmlite.Value | t.CPtr:
"""翻译 list 内置方法调用,返回 call 结果 Value(void 方法返回 None)"""
if pool is None or builder is None or lm_obj is None or lm_name is None:
@@ -1826,8 +1826,8 @@ class CallGenCall(CallGenBase.CallGenBase):
if lbkt_ap is not None:
rbkt_ap: str = string.strrchr(ap_spec_nm, ']')
if rbkt_ap is not None and rbkt_ap > lbkt_ap:
base_len_ap: t.CSizeT = t.CSizeT(t.CUInt64T(lbkt_ap) - t.CUInt64T(ap_spec_nm))
arg_len_ap: t.CSizeT = t.CSizeT(t.CUInt64T(rbkt_ap) - t.CUInt64T(lbkt_ap) - 1)
base_len_ap: sizet = sizet(uint64(lbkt_ap) - uint64(ap_spec_nm))
arg_len_ap: sizet = sizet(uint64(rbkt_ap) - uint64(lbkt_ap) - 1)
if base_len_ap > 0 and arg_len_ap > 0:
base_buf_ap: str = pool.alloc(base_len_ap + 1)
arg_buf_ap: str = pool.alloc(arg_len_ap + 1)
@@ -1845,7 +1845,7 @@ class CallGenCall(CallGenBase.CallGenBase):
if comma_ap is None:
args_ap.append(cur_ap)
break
seg_len_ap: t.CSizeT = t.CSizeT(t.CUInt64T(comma_ap) - t.CUInt64T(cur_ap))
seg_len_ap: sizet = sizet(uint64(comma_ap) - uint64(cur_ap))
seg_buf_ap: str = pool.alloc(seg_len_ap + 1)
if seg_buf_ap is not None:
string.strncpy(seg_buf_ap, cur_ap, seg_len_ap)
@@ -1856,7 +1856,7 @@ class CallGenCall(CallGenBase.CallGenBase):
trans, base_buf_ap, args_ap)
# 调用名 "{sha1}.{spec}.append":
# sha1(16) + '.'(1) + spec + '.append'(7) + NUL(1) = spec + 25
ap_mlen: t.CSizeT = string.strlen(ap_sha1) + \
ap_mlen: sizet = string.strlen(ap_sha1) + \
string.strlen(ap_spec_nm) + 26
ap_mangled: str = pool.alloc(ap_mlen)
if ap_mangled is not None:
@@ -1917,7 +1917,7 @@ class CallGenCall(CallGenBase.CallGenBase):
return None
# 2. 沿 MRO 跳过自身,找第一个定义 method 的祖先类
anc: str = None
mro_sp: t.CSizeT | t.CPtr = self.Gen.StructGen.get_mro_chain(pool, cur_class)
mro_sp: sizet | t.CPtr = self.Gen.StructGen.get_mro_chain(pool, cur_class)
mi_sp: int = 1
while mro_sp is not None and mro_sp[mi_sp] != 0:
anc_sp: str = (str | t.CPtr)(t.CVoid(mro_sp[mi_sp], t.CPtr))
@@ -2019,7 +2019,7 @@ class CallGenCall(CallGenBase.CallGenBase):
call_name = mangled_sp
# 5. 翻译参数 + 按形参 coerce(self 是形参 0,第 ai 个实参对应形参 ai+1)
cargs_sp: list[ast.AST | t.CPtr] | t.CPtr = cl.args
can_sp: t.CSizeT = 0
can_sp: sizet = 0
if cargs_sp is not None:
can_sp = len(cargs_sp)
llvmlite.value_set_next(self_arg, None)
@@ -2178,11 +2178,11 @@ class CallGenCall(CallGenBase.CallGenBase):
"""检查关键字参数名 kw_arg 是否匹配参数名 param_name(跳过 % 前缀)"""
if kw_arg is None or param_name is None:
return 0
start: t.CSizeT = 0
start: sizet = 0
if param_name[0] == '%':
start = 1
for i, ch in enumerate(kw_arg):
c: t.CChar = param_name[start + i]
c: char = param_name[start + i]
if c == '\0' or c != ch:
return 0
if param_name[start + i + 1] != '\0':
+27 -27
View File
@@ -112,7 +112,7 @@ class CallGenCtor(CallGenBase.CallGenBase):
struct_ty: llvmlite.LLVMType | t.CPtr,
class_name: str,
cargs: list[ast.AST | t.CPtr] | t.CPtr,
can: t.CSizeT,
can: sizet,
trans: HT.Translator | t.CPtr) -> llvmlite.Value | t.CPtr:
"""结构体构造函数:按字段顺序 store 参数值,返回结构体值
@@ -171,7 +171,7 @@ class CallGenCtor(CallGenBase.CallGenBase):
has_new_flag = ctor_entry.HasNew
# 注意: __new__ 是可选的,不推断 HasNew(仅 __init__ 是 OOP 类标准方法)
if has_new_flag != 0:
new_arg_vals: t.CSizeT | t.CPtr = pool.alloc(8 * 32)
new_arg_vals: sizet | t.CPtr = pool.alloc(8 * 32)
if new_arg_vals is not None:
string.memset(new_arg_vals, 0, 8 * 32)
new_arg_count: int = 0
@@ -183,7 +183,7 @@ class CallGenCtor(CallGenBase.CallGenBase):
builder, pool, mod, new_arg_node, None, 0, trans)
if new_av is not None:
if new_arg_count < 32:
new_arg_vals[new_arg_count] = t.CSizeT(new_av)
new_arg_vals[new_arg_count] = sizet(new_av)
new_arg_count += 1
new_ptr: llvmlite.Value | t.CPtr = self.Gen.CallGenCall._call_method_on_ptr(
@@ -199,7 +199,7 @@ class CallGenCtor(CallGenBase.CallGenBase):
# bitcast 只改类型层视图,运行时零开销(指针位不变)。
if new_ptr.Ty is not None:
nw_ty: llvmlite.LLVMType | t.CPtr = llvmlite.Ptr(pool, struct_ty)
if t.CUInt64T(new_ptr.Ty) != t.CUInt64T(nw_ty):
if uint64(new_ptr.Ty) != uint64(nw_ty):
nw_bc: llvmlite.Value | t.CPtr = llvmlite.build_bitcast(builder, new_ptr, nw_ty)
if nw_bc is not None:
storage_ptr = nw_bc
@@ -216,7 +216,7 @@ class CallGenCtor(CallGenBase.CallGenBase):
has_init_flag = ctor_entry.HasInit
if has_init_flag != 0:
# 翻译构造函数参数
arg_vals: t.CSizeT | t.CPtr = pool.alloc(8 * 32)
arg_vals: sizet | t.CPtr = pool.alloc(8 * 32)
if arg_vals is not None:
string.memset(arg_vals, 0, 8 * 32)
real_arg_count: int = 0
@@ -228,7 +228,7 @@ class CallGenCtor(CallGenBase.CallGenBase):
builder, pool, mod, arg_node, None, 0, trans)
if av is not None:
if real_arg_count < 32:
arg_vals[real_arg_count] = t.CSizeT(av)
arg_vals[real_arg_count] = sizet(av)
real_arg_count += 1
self.Gen.CallGenCall._call_method_on_ptr(pool, builder, mod, class_name,
@@ -367,7 +367,7 @@ class CallGenCtor(CallGenBase.CallGenBase):
variant_name: str,
tag_value: int,
cargs: list[ast.AST | t.CPtr] | t.CPtr,
can: t.CSizeT,
can: sizet,
trans: HT.Translator | t.CPtr) -> llvmlite.Value | t.CPtr:
"""构造 REnum 变体实例,返回指向 alloca 的指针
@@ -468,9 +468,9 @@ class CallGenCtor(CallGenBase.CallGenBase):
struct_ty: llvmlite.LLVMType | t.CPtr,
class_name: str,
cargs: list[ast.AST | t.CPtr] | t.CPtr,
can: t.CSizeT,
can: sizet,
keywords: list[ast.AST | t.CPtr] | t.CPtr,
kw_count: t.CSizeT,
kw_count: sizet,
trans: HT.Translator | t.CPtr) -> llvmlite.Value | t.CPtr:
"""结构体构造函数(关键字参数版本)"""
# 创建临时 alloca
@@ -545,7 +545,7 @@ class CallGenCtor(CallGenBase.CallGenBase):
# 如果有 __new__,调用 __new__ 获取实际存储指针
if has_new_flag != 0:
new_arg_vals: t.CSizeT | t.CPtr = pool.alloc(8 * 32)
new_arg_vals: sizet | t.CPtr = pool.alloc(8 * 32)
if new_arg_vals is not None:
string.memset(new_arg_vals, 0, 8 * 32)
new_arg_count: int = 0
@@ -557,7 +557,7 @@ class CallGenCtor(CallGenBase.CallGenBase):
builder, pool, mod, new_arg_node, None, 0, trans)
if new_av is not None:
if new_arg_count < 32:
new_arg_vals[new_arg_count] = t.CSizeT(new_av)
new_arg_vals[new_arg_count] = sizet(new_av)
new_arg_count += 1
# 关键字参数也传递给 __new__
for nki in range(kw_count):
@@ -568,7 +568,7 @@ class CallGenCtor(CallGenBase.CallGenBase):
builder, pool, mod, nkw.value, None, 0, trans)
if nkw_av is not None:
if new_arg_count < 32:
new_arg_vals[new_arg_count] = t.CSizeT(nkw_av)
new_arg_vals[new_arg_count] = sizet(nkw_av)
new_arg_count += 1
new_ptr: llvmlite.Value | t.CPtr = self.Gen.CallGenCall._call_method_on_ptr(
pool, builder, mod, class_name,
@@ -583,13 +583,13 @@ class CallGenCtor(CallGenBase.CallGenBase):
# bitcast 只改类型层视图,运行时零开销(指针位不变)。
if new_ptr.Ty is not None:
nw_ty: llvmlite.LLVMType | t.CPtr = llvmlite.Ptr(pool, struct_ty)
if t.CUInt64T(new_ptr.Ty) != t.CUInt64T(nw_ty):
if uint64(new_ptr.Ty) != uint64(nw_ty):
nw_bc: llvmlite.Value | t.CPtr = llvmlite.build_bitcast(builder, new_ptr, nw_ty)
if nw_bc is not None:
storage_ptr = nw_bc
# 构建 __init__ 参数数组:位置参数按顺序 + 关键字参数追加
init_arg_vals: t.CSizeT | t.CPtr = pool.alloc(8 * 32)
init_arg_vals: sizet | t.CPtr = pool.alloc(8 * 32)
if init_arg_vals is not None:
string.memset(init_arg_vals, 0, 8 * 32)
init_arg_count: int = 0
@@ -602,7 +602,7 @@ class CallGenCtor(CallGenBase.CallGenBase):
builder, pool, mod, arg_node_init, None, 0, trans)
if av_init is not None:
if init_arg_count < 32:
init_arg_vals[init_arg_count] = t.CSizeT(av_init)
init_arg_vals[init_arg_count] = sizet(av_init)
init_arg_count += 1
# 关键字参数(追加到末尾,按出现顺序)
for ki_init in range(kw_count):
@@ -613,7 +613,7 @@ class CallGenCtor(CallGenBase.CallGenBase):
builder, pool, mod, kw_init.value, None, 0, trans)
if kw_av_init is not None:
if init_arg_count < 32:
init_arg_vals[init_arg_count] = t.CSizeT(kw_av_init)
init_arg_vals[init_arg_count] = sizet(kw_av_init)
init_arg_count += 1
# 调用 __init__(storage_ptr, *args)
@@ -685,12 +685,12 @@ class CallGenCtor(CallGenBase.CallGenBase):
#
# 当 func 是 t.XXX 形式且 XXX 是已知类型名(map_t_type 能映射)时,
# 将 value 转换为目标类型:
# - 指针 → 整数: ptrtoint (如 t.CUInt64T(ptr) → i64)
# - 指针 → 整数: ptrtoint (如 uint64(ptr) → i64)
# - 整数 → 指针: inttoptr (如 t.CPtr(int_val) → i8*)
# - 整数 → 整数: trunc/zext (如 t.CInt8T(i32_val) → i8)
# - 整数 → 整数: trunc/zext (如 int8(i32_val) → i8)
# - 指针 → 指针: bitcast (如 t.CPtr(ptr_val) → i8*)
# - 整数 → 浮点: sitofp (如 t.CDouble(i32_val) → double)
# - 浮点 → 整数: fptosi (如 t.CInt(double_val) → i32)
# - 浮点 → 整数: fptosi (如 int(double_val) → i32)
# - 浮点 → 浮点: fpext/fptrunc (如 t.CFloat(double_val) → float)
# ============================================================
@@ -803,8 +803,8 @@ class CallGenCtor(CallGenBase.CallGenBase):
tp: ast.Tuple | t.CPtr = (ast.Tuple | t.CPtr)(slice_node)
elts: list[ast.AST | t.CPtr] | t.CPtr = tp.elts
if elts is not None:
n: t.CSizeT = len(elts)
i: t.CSizeT
n: sizet = len(elts)
i: sizet
for i in range(n):
elt: ast.AST | t.CPtr = elts.get(i)
tn_raw = self.Gen.TypeGenResolve._get_type_name_from_annotation(pool, elt)
@@ -861,7 +861,7 @@ class CallGenCtor(CallGenBase.CallGenBase):
if cn.const_kind == ast.CONST_STR:
return "str"
return "int"
# 类型转换调用: int(...)/float(...)/t.CInt(...)/t.CDouble(...)
# 类型转换调用: int(...)/float(...)/int(...)/t.CDouble(...)
if k == ast.ASTKind.Call:
cl_f: ast.Call | t.CPtr = (ast.Call | t.CPtr)(arg_node)
if cl_f.func is not None:
@@ -889,7 +889,7 @@ class CallGenCtor(CallGenBase.CallGenBase):
if fn_at.attr is not None:
if string.strstr(fn_at.attr, "Float") is not None or string.strstr(fn_at.attr, "Double") is not None:
return "double"
# char 内置类型(t.CChar(x) 等含 "Char" 的类名)→ "char"
# char 内置类型(char(x) 等含 "Char" 的类名)→ "char"
if string.strstr(fn_at.attr, "Char") is not None:
return "char"
if string.strstr(fn_at.attr, "Int") is not None or string.strstr(fn_at.attr, "UInt") is not None or string.strstr(fn_at.attr, "Short") is not None or string.strstr(fn_at.attr, "Long") is not None:
@@ -934,11 +934,11 @@ class CallGenCtor(CallGenBase.CallGenBase):
# 翻译 cl.args 为参数指针数组(extra_args[i] = Value 指针)
cargs: list[ast.AST | t.CPtr] | t.CPtr = cl.args
can: t.CSizeT = 0
can: sizet = 0
if cargs is not None:
can = len(cargs)
extra_args: t.CSizeT | t.CPtr = pool.alloc(8 * 32)
extra_args: sizet | t.CPtr = pool.alloc(8 * 32)
if extra_args is None:
return None
string.memset(extra_args, 0, 8 * 32)
@@ -954,7 +954,7 @@ class CallGenCtor(CallGenBase.CallGenBase):
arg_val: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
builder, pool, mod, arg_node, None, 0, trans)
if arg_val is not None:
extra_args[ai] = t.CSizeT(arg_val)
extra_args[ai] = sizet(arg_val)
# 存储指针:默认用 alloca,如果有 __new__ 则用 __new__ 返回的指针
# __new__ 是可选的,仅当泛型类模板定义了 __new__ 方法时才调用
@@ -976,7 +976,7 @@ class CallGenCtor(CallGenBase.CallGenBase):
# bitcast 只改类型层视图,运行时零开销(指针位不变)。
if new_ptr.Ty is not None:
nw_ty: llvmlite.LLVMType | t.CPtr = llvmlite.Ptr(pool, struct_ty)
if t.CUInt64T(new_ptr.Ty) != t.CUInt64T(nw_ty):
if uint64(new_ptr.Ty) != uint64(nw_ty):
nw_bc: llvmlite.Value | t.CPtr = llvmlite.build_bitcast(builder, new_ptr, nw_ty)
if nw_bc is not None:
storage_ptr = nw_bc
+41 -41
View File
@@ -41,7 +41,7 @@ class CallGenDispatch(CallGenBase.CallGenBase):
trans: HT.Translator | t.CPtr,
func_name: str,
cargs: list[ast.AST | t.CPtr] | t.CPtr,
can: t.CSizeT,
can: sizet,
hit_box: t.CPtr = None) -> llvmlite.Value | t.CPtr:
"""super()/ctraits 编译期检测(未命中返回 None)
@@ -97,7 +97,7 @@ class CallGenDispatch(CallGenBase.CallGenBase):
trans: HT.Translator | t.CPtr,
func_name: str,
cargs: list[ast.AST | t.CPtr] | t.CPtr,
can: t.CSizeT,
can: sizet,
hit_box: t.CPtr = None) -> llvmlite.Value | t.CPtr:
"""c.Deref/Asm/LLVMIR 等特殊调用(未命中返回 None)
@@ -201,7 +201,7 @@ class CallGenDispatch(CallGenBase.CallGenBase):
trans: HT.Translator | t.CPtr,
func_name: str,
cargs: list[ast.AST | t.CPtr] | t.CPtr,
can: t.CSizeT) -> llvmlite.Value | t.CPtr:
can: sizet) -> llvmlite.Value | t.CPtr:
"""stdarg 糖 + str/int/bool 内置强转(未命中返回 None)"""
# stdarg 糖函数处理: va_arg / arg / va_start / va_end
# 这些函数在 stdarg.vp 中声明为 pass 体,由编译器在翻译期处理:
@@ -226,7 +226,7 @@ class CallGenDispatch(CallGenBase.CallGenBase):
funcs_ptr, func_count, trans)
# 内置强转函数: str(x)/bytes(x) → i8*, int(x) → i32
# 等价于 (str)(x) / (t.CInt32T)(x)
# 等价于 (str)(x) / (int32)(x)
# 单参数:str(val) → bitcast val to i8*
# int(val) → trunc/sext val to i32
# 泛型类型参数: 类特化/泛型函数上下文中的 T(x) 先解析 T 为具体类型名
@@ -290,13 +290,13 @@ class CallGenDispatch(CallGenBase.CallGenBase):
trans: HT.Translator | t.CPtr,
func_name: str,
cargs: list[ast.AST | t.CPtr] | t.CPtr,
can: t.CSizeT) -> llvmlite.Value | t.CPtr:
can: sizet) -> llvmlite.Value | t.CPtr:
"""t.XXX / typedef 类型转换(未命中返回 None)"""
# 检测 t.XXX 类型转换: t.CUInt64T(ptr), t.CPtr(val), t.CInt(val) 等
# 检测 t.XXX 类型转换: uint64(ptr), t.CPtr(val), int(val) 等
# 当 func 是 t.XXX 形式且 XXX 是已知类型名时,当作类型转换处理(而非函数调用)
# 支持:
# 单参数: t.CInt(val) → 目标类型 = map_t_type(func_name)
# 双参数: t.CInt(val, t.CPtr) → 目标类型 = Ptr(map_t_type(func_name))
# 单参数: int(val) → 目标类型 = map_t_type(func_name)
# 双参数: int(val, t.CPtr) → 目标类型 = Ptr(map_t_type(func_name))
# t 是内部库,一旦确认为类型转换,绝不跌落到跨模块调用 FATAL 路径
if cl.func is not None and cl.func.kind() == ast.ASTKind.Attribute:
tc_at: ast.Attribute | t.CPtr = (ast.Attribute | t.CPtr)(cl.func)
@@ -357,11 +357,11 @@ class CallGenDispatch(CallGenBase.CallGenBase):
# t.CType 语法已确认:即使类型解析失败也不跌落到跨模块 FATAL
return None
# CConst const 标记:CConst(val, t.CPtr) → Ptr(i8)(const void*)。
# CConst 不是 map_t_type 具名类型——t.CConst|t.CChar|t.CPtr 注解 =
# CConst 不是 map_t_type 具名类型——t.CConst|char|t.CPtr 注解 =
# const char*(i8*),显式调用 t.CConst(addr, t.CPtr) 把整数地址转
# const 指针。此前 map_t_type 失败 → 跌落跨模块函数调用 → 生成
# call @CConst(裸名,无 obj 定义)→ ld.lld undefined symbol:
# CConst(elf.vp L650 t.CConst(t.CUInt64T(strtab_ptr)+sym.st_name,
# CConst(elf.vp L650 t.CConst(uint64(strtab_ptr)+sym.st_name,
# t.CPtr) 根因)。单参 CConst(x) 仅 const 限定,LLVM 类型不变,
# 直接返回原值。
if string.strcmp(func_name, "CConst") == 0:
@@ -380,8 +380,8 @@ class CallGenDispatch(CallGenBase.CallGenBase):
return None
target_ty: llvmlite.LLVMType | t.CPtr = self.Gen.TypeGenResolve.map_t_type(pool, func_name)
if target_ty is not None:
tc_effective_can: t.CSizeT = can
# 双参数形式: t.CInt(val, t.CPtr) → Ptr(target_ty)
tc_effective_can: sizet = can
# 双参数形式: int(val, t.CPtr) → Ptr(target_ty)
# 注意: void* 在 LLVM 中非法,CVoid* 应表示为 i8*
if can == 2:
tc_arg2_node: ast.AST | t.CPtr = cargs.get(1)
@@ -485,9 +485,9 @@ class CallGenDispatch(CallGenBase.CallGenBase):
bare_imp_c = trans._imported_modules
bare_fi_c = trans._from_imports
bare_ty = self.Gen.TypeGenResolve.resolve_typedef_or_map(pool, bare_fn_name, bare_imp_c, bare_fi_c)
# 泛型上下文替换出的类型名(如 T→"t.CInt")map_t_type 不识别(只认无前缀名),
# 泛型上下文替换出的类型名(如 T→"int")map_t_type 不识别(只认无前缀名),
# 回退用 resolve_annotation_type 解析(支持 t.CXxx / 结构体类名 / 别名等)。
# GenericTest4 Box[t.CInt].__init__ 的 self.value = T(v) 依赖此路径。
# GenericTest4 Box[int].__init__ 的 self.value = T(v) 依赖此路径。
if bare_ty is None and string.strcmp(bare_fn_name, func_name) != 0:
gp_ast: ast.AST | t.CPtr = self.Gen.TypeGenResolve._parse_type_string(pool, bare_fn_name, 0)
if gp_ast is not None:
@@ -499,7 +499,7 @@ class CallGenDispatch(CallGenBase.CallGenBase):
bare_ty = self.Gen.TypeGenResolve.resolve_annotation_type(
pool, gp_ast, imp_gp, fi_gp, trans, 0)
# 泛型类型参数双参数形式: T(val, t.CPtr) → Ptr(T)
# (与 t.CInt(val, t.CPtr) → Ptr(i32) 对齐;vector.vp get() 的
# (与 int(val, t.CPtr) → Ptr(i32) 对齐;vector.vp get() 的
# typed_ptr = T(offset, t.CPtr) 依赖此路径,否则双参数不进
# can==1 单参数分支 → 跌落到"裸名调用未定义"误报)
if bare_ty is not None and can == 2:
@@ -558,7 +558,7 @@ class CallGenDispatch(CallGenBase.CallGenBase):
trans: HT.Translator | t.CPtr,
func_name: str,
cargs: list[ast.AST | t.CPtr] | t.CPtr,
can: t.CSizeT) -> llvmlite.Value | t.CPtr:
can: sizet) -> llvmlite.Value | t.CPtr:
"""__sizeof__/len/isinstance 内置(未命中返回 None)"""
# 检测 ClassName.__sizeof__() — 返回结构体大小常量(i64)
# __sizeof__ 是内置方法,不走跨模块调用路径
@@ -582,7 +582,7 @@ class CallGenDispatch(CallGenBase.CallGenBase):
if sz_inner_at.value.kind() == ast.ASTKind.Name:
sz_inner_nm: ast.Name | t.CPtr = (ast.Name | t.CPtr)(sz_inner_at.value)
if sz_inner_nm.id is not None:
sz_full_len: t.CSizeT = string.strlen(sz_inner_nm.id) + 1 + string.strlen(sz_inner_at.attr) + 1
sz_full_len: sizet = string.strlen(sz_inner_nm.id) + 1 + string.strlen(sz_inner_at.attr) + 1
sz_full_buf: str = pool.alloc(sz_full_len)
if sz_full_buf is not None:
sz_full_buf[0] = '\0'
@@ -593,7 +593,7 @@ class CallGenDispatch(CallGenBase.CallGenBase):
elif sz_inner_at.value.kind() == ast.ASTKind.Attribute:
sz_mod_path: str = self.Gen.ExprGenAttr._attr_module_path_str(pool, sz_inner_at.value)
if sz_mod_path is not None:
sz_full_len2: t.CSizeT = string.strlen(sz_mod_path) + 1 + string.strlen(sz_inner_at.attr) + 1
sz_full_len2: sizet = string.strlen(sz_mod_path) + 1 + string.strlen(sz_inner_at.attr) + 1
sz_full_buf2: str = pool.alloc(sz_full_len2)
if sz_full_buf2 is not None:
sz_full_buf2[0] = '\0'
@@ -613,8 +613,8 @@ class CallGenDispatch(CallGenBase.CallGenBase):
# T.__sizeof__ 根因)。
if string.strcmp(sz_cls_name, sz_orig) == 0 and trans is not None \
and trans.GenericTypeParamNames is not None and trans.GenericTypeArgs is not None:
gp_n: t.CSizeT = len(trans.GenericTypeParamNames)
gp_i: t.CSizeT
gp_n: sizet = len(trans.GenericTypeParamNames)
gp_i: sizet
for gp_i in range(gp_n):
gpn: str = trans.GenericTypeParamNames.get(gp_i)
if gpn is not None and string.strcmp(sz_orig, gpn) == 0:
@@ -637,9 +637,9 @@ class CallGenDispatch(CallGenBase.CallGenBase):
# get_struct_type 裸名全局匹配会误命中跨模块同名类
# (w32.win32base.SECURITY_ATTRIBUTES 根因)。
sz_full_name: str = sz_cls_name
# 去除模块前缀: Viper 解析器将 t.CInt 解析为 Name(id="t.CInt")
# 去除模块前缀: Viper 解析器将 int 解析为 Name(id="int")
# 而非 Attribute(value=Name("t"), attr="CInt"),需要手动提取最后的类名分量
# "t.CInt" → "CInt", "w32.win32file.WIN32_FIND_DATAA" → "WIN32_FIND_DATAA"
# "int" → "CInt", "w32.win32file.WIN32_FIND_DATAA" → "WIN32_FIND_DATAA"
dot_pos: str = string.strrchr(sz_cls_name, '.')
if dot_pos is not None:
sz_cls_name = dot_pos + 1
@@ -711,12 +711,12 @@ class CallGenDispatch(CallGenBase.CallGenBase):
if sz_full_name is not None:
szf_dot: str = string.strrchr(sz_full_name, '.')
if szf_dot is not None:
szf_mod_len: t.CSizeT = t.CSizeT(t.CUInt64T(szf_dot) - t.CUInt64T(sz_full_name))
szf_mod_len: sizet = sizet(uint64(szf_dot) - uint64(sz_full_name))
szf_mod: str = pool.alloc(szf_mod_len + 1)
if szf_mod is not None:
string.strncpy(szf_mod, sz_full_name, szf_mod_len)
szf_mod[szf_mod_len] = '\0'
# t/c 内置库豁免(t.CInt 等已由内建/尺寸表处理)
# t/c 内置库豁免(int 等已由内建/尺寸表处理)
if string.strcmp(szf_mod, "t") != 0 and string.strcmp(szf_mod, "c") != 0:
szf_sha1: str = self.Gen.StructGen._resolve_module_sha1(
szf_mod, trans._from_imports if trans is not None else None)
@@ -737,8 +737,8 @@ class CallGenDispatch(CallGenBase.CallGenBase):
if gen_args_sz is not None and len(gen_args_sz) > 0:
gargs_resolved: list[str] | t.CPtr = list[str](pool, 8)
if gargs_resolved is not None:
gai_sz: t.CSizeT = len(gen_args_sz)
gai2_sz: t.CSizeT = 0
gai_sz: sizet = len(gen_args_sz)
gai2_sz: sizet = 0
for gai2_sz in range(gai_sz):
gres_sz: str = self.Gen.TypeGenBase.resolve_generic_type_name(
gen_args_sz.get(gai2_sz))
@@ -919,7 +919,7 @@ class CallGenDispatch(CallGenBase.CallGenBase):
# 2 个点 + "__len__"(7) + NUL = 10;+8 会截断
# 末两位 → 符号变 ".__len" 链接 undefined
# (NumpyTest test_len 链接错误根因)
len_ml_x: t.CSizeT = string.strlen(len_cls_sha1_x) \
len_ml_x: sizet = string.strlen(len_cls_sha1_x) \
+ string.strlen(len_cls_nm) + 10
len_mangled_x: str = pool.alloc(len_ml_x)
if len_mangled_x is not None:
@@ -1008,7 +1008,7 @@ class CallGenDispatch(CallGenBase.CallGenBase):
trans: HT.Translator | t.CPtr,
func_name: str,
cargs: list[ast.AST | t.CPtr] | t.CPtr,
can: t.CSizeT,
can: sizet,
hit_box: t.CPtr = None) -> llvmlite.Value | t.CPtr:
"""静态类/方法调用/表达式接收者/self.field/list 内置(未命中返回 None)
@@ -1056,7 +1056,7 @@ class CallGenDispatch(CallGenBase.CallGenBase):
if rk_ve is not None and rk_ve.AnnotClassName is not None:
rk_annot_raw: str = rk_ve.AnnotClassName
# 截断联合/泛型后缀(" | t.CPtr" / "[...]")
rk_ae: t.CSizeT = 0
rk_ae: sizet = 0
while rk_annot_raw[rk_ae] != '\0' and rk_annot_raw[rk_ae] != ' ' \
and rk_annot_raw[rk_ae] != '|' and rk_annot_raw[rk_ae] != '[':
rk_ae += 1
@@ -1128,16 +1128,16 @@ class CallGenDispatch(CallGenBase.CallGenBase):
im_self: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
builder, pool, mod, cargs.get(0), None, 0, trans)
if im_self is not None:
im_rem: t.CSizeT | t.CPtr = None
im_rem: sizet | t.CPtr = None
if can >= 2:
im_rem = pool.alloc(t.CSizeT(can - 1) * 8)
im_rem = pool.alloc(sizet(can - 1) * 8)
if im_rem is not None:
ri_im: t.CSizeT
ri_im: sizet
for ri_im in range(can - 1):
im_rv: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
builder, pool, mod, cargs.get(ri_im + 1), None, 0, trans)
if im_rv is not None:
im_rem[ri_im] = t.CSizeT(im_rv)
im_rem[ri_im] = sizet(im_rv)
im_res: llvmlite.Value | t.CPtr = self.Gen.CallGenCall._call_method_on_ptr(
pool, builder, mod, st_nm.id, func_name,
im_self, im_rem, can - 1, trans)
@@ -1335,9 +1335,9 @@ class CallGenDispatch(CallGenBase.CallGenBase):
mod_nm2: str = None
if dot_ptr is not None:
cls_nm2 = dot_ptr + 1
total_len_av: t.CSizeT = string.strlen(annot_val)
cls_len_av: t.CSizeT = string.strlen(cls_nm2)
mod_len2: t.CSizeT = total_len_av - cls_len_av - 1
total_len_av: sizet = string.strlen(annot_val)
cls_len_av: sizet = string.strlen(cls_nm2)
mod_len2: sizet = total_len_av - cls_len_av - 1
mod_nm2 = pool.alloc(mod_len2 + 1)
if mod_nm2 is not None:
string.strncpy(mod_nm2, annot_val, mod_len2)
@@ -1377,7 +1377,7 @@ class CallGenDispatch(CallGenBase.CallGenBase):
sha1_fc = self._lookup_module_sha1(mod_nm2)
if sha1_fc is not None:
# 构造 "{sha1}.{cls_nm2}.{func_name}" 调用名
mlen3: t.CSizeT = string.strlen(sha1_fc) + string.strlen(cls_nm2) + string.strlen(func_name) + 3
mlen3: sizet = string.strlen(sha1_fc) + string.strlen(cls_nm2) + string.strlen(func_name) + 3
mangled3: str = pool.alloc(mlen3)
if mangled3 is not None:
viperlib.snprintf(mangled3, mlen3, "%s.%s.%s", sha1_fc, cls_nm2, func_name)
@@ -1836,8 +1836,8 @@ class CallGenDispatch(CallGenBase.CallGenBase):
if lbkt_ap is not None:
rbkt_ap: str = string.strrchr(ap_spec_nm, ']')
if rbkt_ap is not None and rbkt_ap > lbkt_ap:
base_len_ap: t.CSizeT = t.CSizeT(t.CUInt64T(lbkt_ap) - t.CUInt64T(ap_spec_nm))
arg_len_ap: t.CSizeT = t.CSizeT(t.CUInt64T(rbkt_ap) - t.CUInt64T(lbkt_ap) - 1)
base_len_ap: sizet = sizet(uint64(lbkt_ap) - uint64(ap_spec_nm))
arg_len_ap: sizet = sizet(uint64(rbkt_ap) - uint64(lbkt_ap) - 1)
if base_len_ap > 0 and arg_len_ap > 0:
base_buf_ap: str = pool.alloc(base_len_ap + 1)
arg_buf_ap: str = pool.alloc(arg_len_ap + 1)
@@ -1855,7 +1855,7 @@ class CallGenDispatch(CallGenBase.CallGenBase):
if comma_ap is None:
args_ap.append(cur_ap)
break
seg_len_ap: t.CSizeT = t.CSizeT(t.CUInt64T(comma_ap) - t.CUInt64T(cur_ap))
seg_len_ap: sizet = sizet(uint64(comma_ap) - uint64(cur_ap))
seg_buf_ap: str = pool.alloc(seg_len_ap + 1)
if seg_buf_ap is not None:
string.strncpy(seg_buf_ap, cur_ap, seg_len_ap)
@@ -1868,7 +1868,7 @@ class CallGenDispatch(CallGenBase.CallGenBase):
# sha1(16) + '.'(1) + spec + '.append'(7) + NUL(1) = spec + 25。
# 此前 +8 少 1 字节,snprintf 截断末尾 'd' →
# undefined symbol: ...list[AST|CPtr].appen(缺 d)。
ap_mlen: t.CSizeT = string.strlen(ap_sha1) + \
ap_mlen: sizet = string.strlen(ap_sha1) + \
string.strlen(ap_spec_nm) + 26
ap_mangled: str = pool.alloc(ap_mlen)
if ap_mangled is not None:
+1 -1
View File
@@ -157,7 +157,7 @@ class CallGenFd(CallGenBase.CallGenBase):
if fd_ac.const_kind == ast.CONST_CHAR:
ch_buf: str = pool.alloc(2)
if ch_buf is not None:
ch_buf[0] = t.CChar(fd_ac.int_val)
ch_buf[0] = char(fd_ac.int_val)
ch_buf[1] = '\0'
fd_av = self.Gen.ExprGenConst.create_global_string(
builder, pool, mod, ch_buf, trans)
+69 -69
View File
@@ -252,7 +252,7 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin):
vtable_ptr: llvmlite.Value | t.CPtr = None
vtable_ready: int = 0
res: llvmlite.Value | t.CPtr = None
cls_names: t.CSizeT | t.CPtr = self._extract_isinstance_class_names(pool, cls_node)
cls_names: sizet | t.CPtr = self._extract_isinstance_class_names(pool, cls_node)
if cls_names is None:
# 类名提取失败:fail-fast,绝不返回 True 掩盖
self.Gen.TypeGenErr.fatal_error(cls_node, "isinstance() 参数类型推断失败", "TypeError")
@@ -278,7 +278,7 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin):
vtable_ptr = llvmlite.build_load(builder, i8_ptr_ty, vtable_slot)
vtable_ready = 1
if vtable_ptr is not None:
subs: t.CSizeT | t.CPtr = self._collect_subclass_vtable_classes(pool, cn)
subs: sizet | t.CPtr = self._collect_subclass_vtable_classes(pool, cn)
if subs is not None:
k: int = 0
while subs[k] != 0:
@@ -303,9 +303,9 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin):
def _extract_isinstance_class_names(self, pool: memhub.MemBuddy | t.CPtr,
node: ast.AST | t.CPtr) -> t.CSizeT | t.CPtr:
node: ast.AST | t.CPtr) -> sizet | t.CPtr:
"""从 isinstance 第二参数提取类名数组(Name→id / Attribute→attr / Tuple→遍历)"""
arr: t.CSizeT | t.CPtr = pool.alloc(8 * 16)
arr: sizet | t.CPtr = pool.alloc(8 * 16)
if arr is None:
return None
# 全数组清零:pool 分配内存非零时,未初始化槽位会被 while cls_names[ci]!=0
@@ -319,16 +319,16 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin):
if k == ast.ASTKind.Name:
nm: ast.Name | t.CPtr = (ast.Name | t.CPtr)(node)
if nm.id is not None:
arr[0] = t.CSizeT(nm.id)
arr[0] = sizet(nm.id)
elif k == ast.ASTKind.Attribute:
at: ast.Attribute | t.CPtr = (ast.Attribute | t.CPtr)(node)
if at.attr is not None:
arr[0] = t.CSizeT(at.attr)
arr[0] = sizet(at.attr)
elif k == ast.ASTKind.Tuple:
tp: ast.Tuple | t.CPtr = (ast.Tuple | t.CPtr)(node)
elts: list[ast.AST | t.CPtr] | t.CPtr = tp.elts
if elts is not None:
n: t.CSizeT = len(elts)
n: sizet = len(elts)
for i in range(n):
if count >= 15:
break
@@ -339,25 +339,25 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin):
if ek == ast.ASTKind.Name:
enm: ast.Name | t.CPtr = (ast.Name | t.CPtr)(elt)
if enm.id is not None:
arr[count] = t.CSizeT(enm.id)
arr[count] = sizet(enm.id)
count += 1
elif ek == ast.ASTKind.Attribute:
eat: ast.Attribute | t.CPtr = (ast.Attribute | t.CPtr)(elt)
if eat.attr is not None:
arr[count] = t.CSizeT(eat.attr)
arr[count] = sizet(eat.attr)
count += 1
arr[count] = 0
return arr
def _collect_subclass_vtable_classes(self, pool: memhub.MemBuddy | t.CPtr,
class_name: str) -> t.CSizeT | t.CPtr:
class_name: str) -> sizet | t.CPtr:
"""反向 BFS 收集目标类及全部子类(含自身,仅 HasVTable==1),返回 0 结尾数组"""
if class_name is None:
return None
names: t.CSizeT | t.CPtr = pool.alloc(8 * (ISINSTANCE_CLASS_MAX + 1))
queue: t.CSizeT | t.CPtr = pool.alloc(8 * ISINSTANCE_CLASS_MAX)
visited: t.CSizeT | t.CPtr = pool.alloc(8 * ISINSTANCE_CLASS_MAX)
names: sizet | t.CPtr = pool.alloc(8 * (ISINSTANCE_CLASS_MAX + 1))
queue: sizet | t.CPtr = pool.alloc(8 * ISINSTANCE_CLASS_MAX)
visited: sizet | t.CPtr = pool.alloc(8 * ISINSTANCE_CLASS_MAX)
if names is None or queue is None or visited is None:
return None
string.memset(names, 0, 8 * (ISINSTANCE_CLASS_MAX + 1))
@@ -366,16 +366,16 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin):
qcount: int = 1
outcount: int = 0
vcount: int = 0
queue[0] = t.CSizeT(class_name) # 存疑
queue[0] = sizet(class_name) # 存疑
while qcount > 0:
qcount -= 1
cur_addr: t.CSizeT = queue[qcount]
cur_addr: sizet = queue[qcount]
cur: str = (str | t.CPtr)(t.CVoid(cur_addr, t.CPtr))
if cur is None:
continue
dup: int = 0
for vi in range(vcount):
va: t.CSizeT = visited[vi]
va: sizet = visited[vi]
if va != 0:
vn: str = (str | t.CPtr)(t.CVoid(va, t.CPtr))
if vn is not None and string.strcmp(vn, cur) == 0:
@@ -384,12 +384,12 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin):
if dup != 0:
continue
if vcount < ISINSTANCE_CLASS_MAX:
visited[vcount] = t.CSizeT(cur)
visited[vcount] = sizet(cur)
vcount += 1
centry: GenTypes.StructEntry | t.CPtr = self.Gen.StructGen.find_struct(cur)
if centry is not None and centry.HasVTable != 0:
if outcount < ISINSTANCE_CLASS_MAX:
names[outcount] = t.CSizeT(cur)
names[outcount] = sizet(cur)
outcount += 1
# 子类入队:遍历全部已注册 struct,ParentNames 含 cur 者
scnt: int = self.Gen.StructGen.get_struct_count()
@@ -398,14 +398,14 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin):
if e2 is None or e2.Name is None:
continue
if e2.ParentCount > 0 and e2.ParentNames is not None:
parr: t.CSizeT | t.CPtr = (t.CSizeT | t.CPtr)(t.CVoid(e2.ParentNames, t.CPtr))
parr: sizet | t.CPtr = (sizet | t.CPtr)(t.CVoid(e2.ParentNames, t.CPtr))
for j in range(e2.ParentCount):
pa: t.CSizeT = parr[j]
pa: sizet = parr[j]
if pa != 0:
pn: str = (str | t.CPtr)(t.CVoid(pa, t.CPtr))
if pn is not None and string.strcmp(pn, cur) == 0:
if qcount < ISINSTANCE_CLASS_MAX:
queue[qcount] = t.CSizeT(e2.Name)
queue[qcount] = sizet(e2.Name)
qcount += 1
break
names[outcount] = 0
@@ -471,7 +471,7 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin):
if sname is not None:
if string.strcmp(sname, class_name) == 0:
return 1
mro: t.CSizeT | t.CPtr = self.Gen.StructGen.get_mro_chain(pool, sname)
mro: sizet | t.CPtr = self.Gen.StructGen.get_mro_chain(pool, sname)
if mro is not None:
k: int = 0
while mro[k] != 0:
@@ -496,7 +496,7 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin):
mod: llvmlite.LLVMModule | t.CPtr,
closure_alloca: llvmlite.Value | t.CPtr,
cargs: list[ast.AST | t.CPtr] | t.CPtr,
can: t.CSizeT,
can: sizet,
trans: HT.Translator | t.CPtr = None) -> llvmlite.Value | t.CPtr:
"""通过闭包指针间接调用(支持带参 lambda:i32(i8*, args...))"""
if builder is None or closure_alloca is None:
@@ -600,7 +600,7 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin):
return 1
if self.ClosureCount >= MAX_CLOSURE_NAMES:
return 1
idx: t.CSizeT = t.CSizeT(self.ClosureCount) * 64
idx: sizet = sizet(self.ClosureCount) * 64
string.strncpy(self.ClosureNames + idx, name, 63)
self.ClosureCount += 1
return 0
@@ -610,7 +610,7 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin):
"""检查 name 是否已注册为闭包变量名,1=是 / 0=否"""
if name is None or self.ClosureNames is None:
return 0
i: t.CSizeT
i: sizet
for i in range(self.ClosureCount):
if string.strcmp(self.ClosureNames + i * 64, name) == 0:
return 1
@@ -638,7 +638,7 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin):
return 1
if self.FuncptrCount >= MAX_FUNC_PTR_SIGS:
return 1
idx: t.CSizeT = t.CSizeT(self.FuncptrCount) * 64
idx: sizet = sizet(self.FuncptrCount) * 64
# 槽位定长 64 字节,与 register_closure_name 一致用 strncpy 钳制防越界
string.strncpy(self.FuncptrNames + idx, name, 63)
# ret_ty 是调用方 pool 分配的裸 LLVMType,1a 每文件 reset 后悬空;
@@ -646,9 +646,9 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin):
ret_copy_fp: llvmlite.LLVMType | t.CPtr = llvmlite.DeepCopyType(
CompilerFactory.factory.PermPool, ret_ty)
if ret_copy_fp is not None:
self.FuncptrRets[self.FuncptrCount] = t.CUInt64T(ret_copy_fp)
self.FuncptrRets[self.FuncptrCount] = uint64(ret_copy_fp)
else:
self.FuncptrRets[self.FuncptrCount] = t.CUInt64T(ret_ty)
self.FuncptrRets[self.FuncptrCount] = uint64(ret_ty)
self.FuncptrCount += 1
return 0
@@ -658,7 +658,7 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin):
if name is None or self.FuncptrNames is None:
return None
for i in range(self.FuncptrCount):
idx: t.CSizeT = t.CSizeT(i) * 64
idx: sizet = sizet(i) * 64
if string.strcmp(self.FuncptrNames + idx, name) == 0:
return (llvmlite.LLVMType | t.CPtr)(
t.CVoid(self.FuncptrRets[i], t.CPtr))
@@ -671,7 +671,7 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin):
fp_alloca: llvmlite.Value | t.CPtr,
func_name: str,
cargs: list[ast.AST | t.CPtr] | t.CPtr,
can: t.CSizeT,
can: sizet,
trans: HT.Translator | t.CPtr) -> llvmlite.Value | t.CPtr:
"""函数指针变量间接调用,返回结果 Value"""
if builder is None or fp_alloca is None:
@@ -689,7 +689,7 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin):
head: llvmlite.Value | t.CPtr = None
tail: llvmlite.Value | t.CPtr = None
arg_count: int = 0
ai: t.CSizeT
ai: sizet
for ai in range(can):
arg: ast.AST | t.CPtr = cargs.get(ai)
if arg is not None:
@@ -749,7 +749,7 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin):
cargs: list[ast.AST | t.CPtr] | t.CPtr = cl.args
if cargs is None:
return
can: t.CSizeT = len(cargs)
can: sizet = len(cargs)
if can == 0:
return
@@ -811,7 +811,7 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin):
if cargs is None:
return
FMT_BUF_SIZE: t.CSizeT = 256
FMT_BUF_SIZE: sizet = 256
fmt_buf: bytes = stdlib.malloc(FMT_BUF_SIZE)
if fmt_buf is None:
return
@@ -821,7 +821,7 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin):
i64_ty: llvmlite.LLVMType | t.CPtr = llvmlite.Int64(pool)
dbl_ty: llvmlite.LLVMType | t.CPtr = llvmlite.Double(pool)
can: t.CSizeT = len(cargs)
can: sizet = len(cargs)
arg_head: llvmlite.Value | t.CPtr = None
arg_tail: llvmlite.Value | t.CPtr = None
arg_count: int = 1 # 格式串本身是第 1 个 printf 参数
@@ -839,7 +839,7 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin):
self.Gen.TypeGenErr.fatal_error(arg, "print 参数翻译失败(表达式返回 None)", "TypeError")
return
# 数组名(如 print(l),l: t.CArray[t.CChar, N]):
# 数组名(如 print(l),l: t.CArray[char, N]):
# translate_value 会 load 出数组值([N x T]),print 无法格式化;
# 按数组退化语义取数组 alloca 地址——字符数组 → %s(打印字符串内容),
# 其他元素类型 → 0x%llx(打印数组地址)。
@@ -937,7 +937,7 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin):
def init_func_table(self, pool: memhub.MemBuddy | t.CPtr,
max_count: int) -> GenTypes.FuncEntry | t.CPtr:
"""分配并清零函数表数组"""
size: t.CSizeT = max_count * GenTypes.FuncEntry.__sizeof__()
size: sizet = max_count * GenTypes.FuncEntry.__sizeof__()
funcs_ptr: GenTypes.FuncEntry | t.CPtr = pool.alloc(size)
if funcs_ptr is not None:
string.memset(funcs_ptr, 0, size)
@@ -959,7 +959,7 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin):
"""
if name is None or funcs is None:
return None
entry_size: t.CSizeT = GenTypes.FuncEntry.__sizeof__()
entry_size: sizet = GenTypes.FuncEntry.__sizeof__()
# 单遍扫描(合并原 owner 优先遍 + 通用遍,语义完全一致但省一半遍历):
# 扫描中同时记录"首个同裸名条目"作通用兜底;一旦发现本模块条目
# (mangled 名以 "{owner_sha1}." 开头,16 位前缀 + '.')立即返回。
@@ -970,7 +970,7 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin):
# 由首个同裸名兜底返回(同旧语义)。
fallback_entry: GenTypes.FuncEntry | t.CPtr = None
for i in range(func_count):
entry_addr: t.CUInt64T = t.CUInt64T(funcs) + i * entry_size
entry_addr: uint64 = uint64(funcs) + i * entry_size
entry: GenTypes.FuncEntry | t.CPtr = (GenTypes.FuncEntry | t.CPtr)(t.CVoid(entry_addr, t.CPtr))
if entry is not None and entry.Name is not None:
if string.strcmp(entry.Name, name) == 0:
@@ -991,7 +991,7 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin):
name: str,
func: llvmlite.Function | t.CPtr,
max_count: int,
defaults: t.CVoid | t.CPtr = None,
defaults: t.CPtr = None,
default_count: int = 0,
param_count: int = 0,
pool: memhub.MemBuddy | t.CPtr = None,
@@ -1008,8 +1008,8 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin):
return 1
if func_count >= max_count:
return 1
entry_size: t.CSizeT = GenTypes.FuncEntry.__sizeof__()
entry_addr: t.CUInt64T = t.CUInt64T(funcs) + func_count * entry_size
entry_size: sizet = GenTypes.FuncEntry.__sizeof__()
entry_addr: uint64 = uint64(funcs) + func_count * entry_size
entry: GenTypes.FuncEntry | t.CPtr = (GenTypes.FuncEntry | t.CPtr)(t.CVoid(entry_addr, t.CPtr))
entry.Name = name
entry.Func = func
@@ -1028,7 +1028,7 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin):
"""初始化全局函数表(用 stdlib.malloc 分配,生命周期=整个程序)"""
if self.GlobalFuncs is not None:
return 1
size: t.CSizeT = GLOBAL_FUNC_MAX * GenTypes.FuncEntry.__sizeof__()
size: sizet = GLOBAL_FUNC_MAX * GenTypes.FuncEntry.__sizeof__()
self.GlobalFuncs = CompilerFactory.factory.PermPool.alloc(size)
if self.GlobalFuncs is None:
return 0
@@ -1075,7 +1075,7 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin):
self._asm_append_cstr(ty_buf, 1024, ")")
# 深拷贝到 stdlib 区(TypeStr 跨文件永久存活)
ts_len: t.CSizeT = string.strlen(ty_buf)
ts_len: sizet = string.strlen(ty_buf)
ts_copy: str = CompilerFactory.factory.PermPool.alloc(ts_len + 1)
if ts_copy is None:
return None
@@ -1100,12 +1100,12 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin):
if self.GlobalFuncCount >= GLOBAL_FUNC_MAX:
return 1
# 直接写入全局表(不调用 add_func_to_table,避免递归)
entry_size: t.CSizeT = GenTypes.FuncEntry.__sizeof__()
entry_addr: t.CUInt64T = t.CUInt64T(self.GlobalFuncs) + self.GlobalFuncCount * entry_size
entry_size: sizet = GenTypes.FuncEntry.__sizeof__()
entry_addr: uint64 = uint64(self.GlobalFuncs) + self.GlobalFuncCount * entry_size
entry: GenTypes.FuncEntry | t.CPtr = (GenTypes.FuncEntry | t.CPtr)(t.CVoid(entry_addr, t.CPtr))
# Name 深拷贝到 stdlib 区:全局表跨文件永久存活,pool 内名字会被 1b 每文件
# reset_to(mark1) 回收导致悬空(vtable 生成 find_func_global 后 strcmp 崩溃)
name_len: t.CSizeT = string.strlen(name)
name_len: sizet = string.strlen(name)
name_copy: str = CompilerFactory.factory.PermPool.alloc(name_len + 1)
if name_copy is None:
return 1
@@ -1147,9 +1147,9 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin):
"""在全局函数表中按名称查找,返回完整 FuncEntry(含 TypeStr)或 None"""
if name is None or self.GlobalFuncs is None:
return None
entry_size: t.CSizeT = GenTypes.FuncEntry.__sizeof__()
entry_size: sizet = GenTypes.FuncEntry.__sizeof__()
for i in range(self.GlobalFuncCount):
entry_addr: t.CUInt64T = t.CUInt64T(self.GlobalFuncs) + i * entry_size
entry_addr: uint64 = uint64(self.GlobalFuncs) + i * entry_size
entry: GenTypes.FuncEntry | t.CPtr = (GenTypes.FuncEntry | t.CPtr)(t.CVoid(entry_addr, t.CPtr))
if entry.Name is not None:
if string.strcmp(entry.Name, name) == 0:
@@ -1161,7 +1161,7 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin):
"""初始化全局默认参数表"""
if self.GlobalDefaults is not None:
return 1
size: t.CSizeT = GLOBAL_DEFAULTS_MAX * GenTypes.FuncDefaultsEntry.__sizeof__()
size: sizet = GLOBAL_DEFAULTS_MAX * GenTypes.FuncDefaultsEntry.__sizeof__()
self.GlobalDefaults = CompilerFactory.factory.PermPool.alloc(size)
if self.GlobalDefaults is None:
return 0
@@ -1171,7 +1171,7 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin):
def _register_global_defaults(self, name: str,
defaults: t.CVoid | t.CPtr,
defaults: t.CPtr,
default_count: int,
param_count: int,
def_sha1: str = None) -> int:
@@ -1203,11 +1203,11 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin):
return 0
if self.GlobalDefaultsCount >= GLOBAL_DEFAULTS_MAX:
return 1
entry_size: t.CSizeT = GenTypes.FuncDefaultsEntry.__sizeof__()
entry_addr: t.CUInt64T = t.CUInt64T(self.GlobalDefaults) + self.GlobalDefaultsCount * entry_size
entry_size: sizet = GenTypes.FuncDefaultsEntry.__sizeof__()
entry_addr: uint64 = uint64(self.GlobalDefaults) + self.GlobalDefaultsCount * entry_size
entry: GenTypes.FuncDefaultsEntry | t.CPtr = (GenTypes.FuncDefaultsEntry | t.CPtr)(t.CVoid(entry_addr, t.CPtr))
# Name 深拷贝到 stdlib(全局表跨文件永久存活)
nm_len: t.CSizeT = string.strlen(name)
nm_len: sizet = string.strlen(name)
nm_copy: str = CompilerFactory.factory.PermPool.alloc(nm_len + 1)
if nm_copy is None:
return 1
@@ -1215,7 +1215,7 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin):
entry.Name = nm_copy
entry.ModuleSha1 = None
if cur_sha is not None:
sh_len: t.CSizeT = string.strlen(cur_sha)
sh_len: sizet = string.strlen(cur_sha)
sh_copy: str = CompilerFactory.factory.PermPool.alloc(sh_len + 1)
if sh_copy is not None:
string.strcpy(sh_copy, cur_sha)
@@ -1232,14 +1232,14 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin):
return 0
# 提取常量快照到 stdlib
if default_count > 0:
kinds: t.CInt | t.CPtr = CompilerFactory.factory.PermPool.alloc(default_count * 4)
ints: t.CInt64T | t.CPtr = CompilerFactory.factory.PermPool.alloc(default_count * 8)
strs: t.CSizeT | t.CPtr = CompilerFactory.factory.PermPool.alloc(default_count * 8)
kinds: int | t.CPtr = CompilerFactory.factory.PermPool.alloc(default_count * 4)
ints: int64 | t.CPtr = CompilerFactory.factory.PermPool.alloc(default_count * 8)
strs: sizet | t.CPtr = CompilerFactory.factory.PermPool.alloc(default_count * 8)
if kinds is not None and ints is not None and strs is not None:
string.memset(kinds, 0, default_count * 4)
string.memset(ints, 0, default_count * 8)
string.memset(strs, 0, default_count * 8)
dl: list[ast.AST | t.CPtr] | t.CPtr = (list[ast.AST | t.CPtr] | t.CPtr)(t.CVoid(t.CUInt64T(defaults), t.CPtr))
dl: list[ast.AST | t.CPtr] | t.CPtr = (list[ast.AST | t.CPtr] | t.CPtr)(t.CVoid(uint64(defaults), t.CPtr))
di: int
for di in range(default_count):
dnode: ast.AST | t.CPtr = dl.get(di)
@@ -1248,11 +1248,11 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin):
kinds[di] = dcn.const_kind
ints[di] = dcn.int_val
if dcn.const_kind == ast.CONST_STR and dcn.str_val is not None:
slen: t.CSizeT = string.strlen(dcn.str_val)
slen: sizet = string.strlen(dcn.str_val)
scopy: str = CompilerFactory.factory.PermPool.alloc(slen + 1)
if scopy is not None:
string.strcpy(scopy, dcn.str_val)
strs[di] = t.CSizeT(scopy)
strs[di] = sizet(scopy)
elif dnode is not None and dnode.kind() == ast.ASTKind.Name:
# CDefine Name 引用默认值(如 share: ULONG = SHARE_READ):
# 注册时求值 CDefine 存快照——否则跨模块重建时快照为空
@@ -1266,7 +1266,7 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin):
kinds[di] = ast.CONST_INT
ints[di] = cdef_v
elif dnode is not None and dnode.kind() == ast.ASTKind.UnaryOp:
# 一元字面量默认值(如 ex3: t.CInt = -1):AST 是
# 一元字面量默认值(如 ex3: int = -1):AST 是
# UnaryOp(USub, Constant(1)),不是 Constant —— 此前无此分支
# → kinds[di] 保持 0 → 快照重建失败 → "跨模块默认参数无法
# 重建(快照缺失,默认值需为简单常量)"(AppGui.top_index
@@ -1301,9 +1301,9 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin):
"""
if name is None or self.GlobalDefaults is None:
return None
entry_size: t.CSizeT = GenTypes.FuncDefaultsEntry.__sizeof__()
entry_size: sizet = GenTypes.FuncDefaultsEntry.__sizeof__()
for i in range(self.GlobalDefaultsCount):
entry_addr: t.CUInt64T = t.CUInt64T(self.GlobalDefaults) + i * entry_size
entry_addr: uint64 = uint64(self.GlobalDefaults) + i * entry_size
entry: GenTypes.FuncDefaultsEntry | t.CPtr = (GenTypes.FuncDefaultsEntry | t.CPtr)(t.CVoid(entry_addr, t.CPtr))
if entry.Name is None:
continue
@@ -1329,8 +1329,8 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin):
return None
if di < 0 or di >= gd_entry.DefaultCount:
return None
kind: t.CInt = gd_entry.ConstKinds[di]
ival: t.CInt64T = gd_entry.ConstInts[di]
kind: int = gd_entry.ConstKinds[di]
ival: int64 = gd_entry.ConstInts[di]
if kind == ast.CONST_INT:
if ival > 2147483647 or ival < -2147483648:
return llvmlite.const_int64(pool, ival)
@@ -1357,9 +1357,9 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin):
"""在函数表中按名称查找,返回完整 FuncEntry 或 None"""
if name is None or funcs is None:
return None
entry_size: t.CSizeT = GenTypes.FuncEntry.__sizeof__()
entry_size: sizet = GenTypes.FuncEntry.__sizeof__()
for i in range(func_count):
entry_addr: t.CUInt64T = t.CUInt64T(funcs) + i * entry_size
entry_addr: uint64 = uint64(funcs) + i * entry_size
entry: GenTypes.FuncEntry | t.CPtr = (GenTypes.FuncEntry | t.CPtr)(t.CVoid(entry_addr, t.CPtr))
if entry.Name is not None:
if string.strcmp(entry.Name, name) == 0:
@@ -1382,9 +1382,9 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin):
"""
if name is None or funcs is None:
return None
entry_size: t.CSizeT = GenTypes.FuncEntry.__sizeof__()
entry_size: sizet = GenTypes.FuncEntry.__sizeof__()
for i in range(func_count):
entry_addr: t.CUInt64T = t.CUInt64T(funcs) + i * entry_size
entry_addr: uint64 = uint64(funcs) + i * entry_size
entry: GenTypes.FuncEntry | t.CPtr = (GenTypes.FuncEntry | t.CPtr)(t.CVoid(entry_addr, t.CPtr))
if entry is None or entry.Name is None:
continue
+10 -10
View File
@@ -120,7 +120,7 @@ class CallGenLib(CallGenBase.CallGenBase):
"""裸名 C 库函数实参按标准签名提升(B3)。
跨模块裸名调用(string.memset → @memset)时 _ensure_method_declare 用
实参类型建 declare:第三参字面量 32=i32 把定义 t.CSizeT(i64) 固化窄
实参类型建 declare:第三参字面量 32=i32 把定义 sizet(i64) 固化窄
→ declare/call @memset(i8*,i32,i32) vs 定义 @memset(i8*,i32,i64),
ABI 宽度不一致(VKernel process.vp B3)。调用点先把第三参窄整数
实参提升到 i64,declare 与 call 均按 i64 生成 → 与定义一致。
@@ -132,8 +132,8 @@ class CallGenLib(CallGenBase.CallGenBase):
if string.strchr(call_name, 46) is not None:
return head
# 白名单:size_t(i64) 长度参数所在下标(与 _ensure_c_lib_declare 一致)。
# vsnprintf 非变参(第二参即 t.CSizeT 长度)——viperlib.vp `export def
# vsnprintf(buf, size: t.CSizeT, fmt, ap)`,跨模块裸名调用时字面量 1024
# vsnprintf 非变参(第二参即 sizet 长度)——viperlib.vp `export def
# vsnprintf(buf, size: sizet, fmt, ap)`,跨模块裸名调用时字面量 1024
# 固化 i32 vs 定义 i64,与 memset 同族。
size_idx: int = -1
if string.strcmp(call_name, "memset") == 0: size_idx = 2
@@ -226,7 +226,7 @@ class CallGenLib(CallGenBase.CallGenBase):
meth_nm: str = rest
dot_r: str = string.strchr(rest, 46)
if dot_r is not None:
cls_len: t.CSizeT = t.CUInt64T(dot_r) - t.CUInt64T(rest)
cls_len: sizet = uint64(dot_r) - uint64(rest)
if cls_len <= 0:
return head
cls_buf: bytes = stdlib.malloc(cls_len + 1)
@@ -613,7 +613,7 @@ class CallGenLib(CallGenBase.CallGenBase):
]
# list 迭代不支持,用 range + get 替代
api_count: t.CSizeT = len(win32_apis)
api_count: sizet = len(win32_apis)
for ai in range(api_count):
api_name: str = win32_apis.get(ai)
if string.strcmp(api_name, func_name) == 0:
@@ -647,7 +647,7 @@ class CallGenLib(CallGenBase.CallGenBase):
first_dot: str = string.strchr(call_name, '.')
if first_dot is None:
return 0
pre_len: t.CSizeT = t.CSizeT(t.CUInt64T(first_dot) - t.CUInt64T(call_name))
pre_len: sizet = sizet(uint64(first_dot) - uint64(call_name))
if pre_len != 16:
return 0
for hx in range(16):
@@ -763,9 +763,9 @@ class CallGenLib(CallGenBase.CallGenBase):
func_name: str,
found_func: llvmlite.Function | t.CPtr,
cargs: list[ast.AST | t.CPtr] | t.CPtr,
can: t.CSizeT,
can: sizet,
keywords: list[ast.AST | t.CPtr] | t.CPtr,
kw_count: t.CSizeT,
kw_count: sizet,
trans: HT.Translator | t.CPtr) -> llvmlite.Value | t.CPtr:
"""带关键字参数的函数调用,按参数顺序构建调用链表
@@ -775,14 +775,14 @@ class CallGenLib(CallGenBase.CallGenBase):
"""
head: llvmlite.Value | t.CPtr = None
tail: llvmlite.Value | t.CPtr = None
actual_count: t.CSizeT = 0
actual_count: sizet = 0
# memcpy 专用: 收集前三个 Value 的独立引用(避免共享 alloca 对象的 Next 被污染)
mc_dst1: llvmlite.Value | t.CPtr = None
mc_src1: llvmlite.Value | t.CPtr = None
mc_num1: llvmlite.Value | t.CPtr = None
# 遍历函数参数链表(使用访问器获取 Head)
param_idx: t.CSizeT = 0
param_idx: sizet = 0
cur_param: llvmlite.Param | t.CPtr = llvmlite.function_get_param_head(found_func)
while cur_param is not None:
+79 -79
View File
@@ -75,7 +75,7 @@ class CallGenMixin(CallGenBase.CallGenBase):
func_name: str = self.Gen.ExprGenBase.get_func_name(cl.func)
cargs: list[ast.AST | t.CPtr] | t.CPtr = cl.args
can: t.CSizeT = 0
can: sizet = 0
if cargs is not None:
can = len(cargs)
# super()/ctraits 检测:void 方法(如 __init__)命中后 build_call 返回
@@ -126,7 +126,7 @@ class CallGenMixin(CallGenBase.CallGenBase):
# (对应 TPC _HandleGenericCallExplicitLlvm;TPV 无泛型函数特化,
# 泛型函数按普通函数编译,类型参数 [T] 仅在函数定义处消费)。
# 检查当前模块是否已定义同名函数(def double[T] 编译后即普通函数
# double),若是则丢弃 [t.CInt] 显式类型参数,退回普通函数调用。
# double),若是则丢弃 [int] 显式类型参数,退回普通函数调用。
if self.find_func_in_module(mod, gen_class_name) is not None:
func_name = gen_class_name
else:
@@ -222,7 +222,7 @@ class CallGenMixin(CallGenBase.CallGenBase):
# 获取关键字参数
keywords: list[ast.AST | t.CPtr] | t.CPtr = cl.keywords
kw_count: t.CSizeT = 0
kw_count: sizet = 0
if keywords is not None:
kw_count = len(keywords)
@@ -320,7 +320,7 @@ class CallGenMixin(CallGenBase.CallGenBase):
trans._from_imports, func_name)
if ctor_orig is not None:
# 复制到独立 null 终止缓冲区(from_imports 内部缓冲未终止)
co_len: t.CSizeT = 0
co_len: sizet = 0
while ctor_orig[co_len] != ' ' and ctor_orig[co_len] != '\0':
co_len += 1
co_buf: str = pool.alloc(co_len + 1)
@@ -344,7 +344,7 @@ class CallGenMixin(CallGenBase.CallGenBase):
ctor_is_oop = gen_ctor_entry.IsOOP
if ctor_is_oop != 0:
return self.Gen.CallGenCtor._translate_struct_ctor(
pool, builder, mod, struct_ty, func_name, cargs, t.CSizeT(0), trans)
pool, builder, mod, struct_ty, func_name, cargs, sizet(0), trans)
# @t.NoVTable 类(无方法、类语义/指针对象):无参构造也应分配内存
# 返回指针。否则按值结构体返回 ConstZero(struct_ty),LHS 联合注解
# (如 Plain|CPtr)存 0 指针 → p.v 解引用 NULL 段错误
@@ -354,7 +354,7 @@ class CallGenMixin(CallGenBase.CallGenBase):
ctor_is_novt = gen_ctor_entry.IsNoVTable
if ctor_is_novt != 0:
return self.Gen.CallGenCtor._translate_struct_ctor(
pool, builder, mod, struct_ty, func_name, cargs, t.CSizeT(0), trans)
pool, builder, mod, struct_ty, func_name, cargs, sizet(0), trans)
# 普通结构体:检查是否有默认值(用 entry 直接访问)
gen_has_defaults: int = 0
if gen_ctor_entry is not None:
@@ -369,7 +369,7 @@ class CallGenMixin(CallGenBase.CallGenBase):
if gen_has_defaults == 1:
# 有默认值:走构造函数路径应用默认值
return self.Gen.CallGenCtor._translate_struct_ctor(
pool, builder, mod, struct_ty, func_name, cargs, t.CSizeT(0), trans)
pool, builder, mod, struct_ty, func_name, cargs, sizet(0), trans)
# 无默认值:返回 zeroinitializer
ret: llvmlite.Value | t.CPtr = llvmlite.ConstZero(pool, struct_ty)
return ret
@@ -403,7 +403,7 @@ class CallGenMixin(CallGenBase.CallGenBase):
template_cd_bare: ast.ClassDef | t.CPtr = self.Gen.ClassGenGeneric._find_generic_template(func_name)
if template_cd_bare is not None and template_cd_bare.type_params is not None:
tp_bare: list[str] | t.CPtr = template_cd_bare.type_params
tp_count_bare: t.CSizeT = len(tp_bare)
tp_count_bare: sizet = len(tp_bare)
if tp_count_bare > 0:
inferred_args_bare: list[str] | t.CPtr = list[str](pool, 8)
if inferred_args_bare is not None:
@@ -413,12 +413,12 @@ class CallGenMixin(CallGenBase.CallGenBase):
# → Vector[double];Vector(pool,10,CInt(0)) → Vector[int])
hint_bare: list[str] | t.CPtr = list[str](pool, 8)
if hint_bare is not None:
hi_bare: t.CSizeT
hi_bare: sizet
for hi_bare in range(can):
hty_bare: str = self.Gen.CallGenCtor._infer_generic_ctor_type_arg(pool, cargs.get(hi_bare), func_name)
if string.strcmp(hty_bare, "int") != 0:
hint_bare.append(hty_bare)
tpi_bare: t.CSizeT = 0
tpi_bare: sizet = 0
for tpi_bare in range(tp_count_bare):
ta_bare: str = "int"
if tpi_bare < len(hint_bare):
@@ -466,7 +466,7 @@ class CallGenMixin(CallGenBase.CallGenBase):
# 模块路径 = 末段之前(支持多级: w32.fileio.Class.Variant)。
# 注意:不能用 rc_mq_dot - rc_mq_path 指针减法(TPC 直接发
# sub i8*, i8* 非法 IR),用 strlen 整数差扣除末段与分隔点。
rc_mq_len: t.CSizeT = string.strlen(rc_mq_path) - string.strlen(rc_mq_dot + 1) - 1
rc_mq_len: sizet = string.strlen(rc_mq_path) - string.strlen(rc_mq_dot + 1) - 1
rc_mq_mod: str = pool.alloc(rc_mq_len + 1)
if rc_mq_mod is not None:
string.memcpy(rc_mq_mod, rc_mq_path, rc_mq_len)
@@ -514,8 +514,8 @@ class CallGenMixin(CallGenBase.CallGenBase):
arg_tail_an: llvmlite.Value | t.CPtr = None
arg_cnt_an: int = 0
if cl.args is not None:
nb_an: t.CSizeT = len(cl.args)
j_an: t.CSizeT = 0
nb_an: sizet = len(cl.args)
j_an: sizet = 0
for j_an in range(nb_an):
av_an: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
builder, pool, mod, cl.args.get(j_an),
@@ -609,7 +609,7 @@ class CallGenMixin(CallGenBase.CallGenBase):
bn_name: str = llvmlite.function_get_name(found_func)
if bn_name is not None:
bn_dots: int = 0
bni2: t.CSizeT = 0
bni2: sizet = 0
while bn_name[bni2] != '\0':
if bn_name[bni2] == '.':
bn_dots += 1
@@ -619,13 +619,13 @@ class CallGenMixin(CallGenBase.CallGenBase):
bn_seg2: str = pool.alloc(64)
if bn_seg2 is not None:
bn_seg2[0] = '\0'
bsi2: t.CSizeT = 0
bsi2: sizet = 0
while bn_name[bsi2] != '\0' and bsi2 < 17:
bsi2 += 1
bse2: t.CSizeT = bsi2
bse2: sizet = bsi2
while bn_name[bse2] != '\0' and bn_name[bse2] != '.':
bse2 += 1
bsl2: t.CSizeT = bse2 - bsi2
bsl2: sizet = bse2 - bsi2
if bsl2 > 0 and bsl2 < 63:
string.strncpy(bn_seg2, bn_name + bsi2, bsl2)
bn_seg2[bsl2] = '\0'
@@ -697,7 +697,7 @@ class CallGenMixin(CallGenBase.CallGenBase):
ff_name: str = llvmlite.function_get_name(found_func)
if ff_name is not None:
ff_dots: int = 0
ffi2: t.CSizeT = 0
ffi2: sizet = 0
while ff_name[ffi2] != '\0':
if ff_name[ffi2] == '.':
ff_dots += 1
@@ -707,14 +707,14 @@ class CallGenMixin(CallGenBase.CallGenBase):
seg2: str = pool.alloc(64)
if seg2 is not None:
seg2[0] = '\0'
si: t.CSizeT = 0
si: sizet = 0
while ff_name[si] != '\0' and si < 17:
si += 1
seg_start: t.CSizeT = si
seg_end: t.CSizeT = si
seg_start: sizet = si
seg_end: sizet = si
while ff_name[seg_end] != '\0' and ff_name[seg_end] != '.':
seg_end += 1
seg_len: t.CSizeT = seg_end - seg_start
seg_len: sizet = seg_end - seg_start
if seg_len > 0 and seg_len < 63:
string.strncpy(seg2, ff_name + seg_start, seg_len)
seg2[seg_len] = '\0'
@@ -765,7 +765,7 @@ class CallGenMixin(CallGenBase.CallGenBase):
if bi_ret is not None:
bi_sym: str = func_name
if self.Gen.CallGenBase.is_cexport_func(bi_sha1, func_name) == 0:
bi_sym_len: t.CSizeT = string.strlen(bi_sha1) + string.strlen(func_name) + 2
bi_sym_len: sizet = string.strlen(bi_sha1) + string.strlen(func_name) + 2
bi_sym_buf: str = pool.alloc(bi_sym_len)
if bi_sym_buf is not None:
viperlib.snprintf(bi_sym_buf, bi_sym_len, "%s.%s", bi_sha1, func_name)
@@ -843,17 +843,17 @@ class CallGenMixin(CallGenBase.CallGenBase):
if rr_src is None:
rr_src = self._lookup_reexport_from_vpi(pool, mod_ret_sha1, func_name)
if rr_src is not None:
rr_total: t.CSizeT = string.strlen(rr_src)
rr_i: t.CSizeT = 0
rr_total: sizet = string.strlen(rr_src)
rr_i: sizet = 0
while rr_i < rr_total and ret_annot_fc is None:
while rr_i < rr_total and rr_src[rr_i] == ' ':
rr_i += 1
if rr_i >= rr_total:
break
rr_start: t.CSizeT = rr_i
rr_start: sizet = rr_i
while rr_i < rr_total and rr_src[rr_i] != ' ':
rr_i += 1
rr_len: t.CSizeT = rr_i - rr_start
rr_len: sizet = rr_i - rr_start
rr_buf: str = pool.alloc(rr_len + 1)
if rr_buf is not None:
string.strncpy(rr_buf, rr_src + rr_start, rr_len)
@@ -1051,7 +1051,7 @@ class CallGenMixin(CallGenBase.CallGenBase):
else:
arg_val = self.Gen.ExprGenBase.coerce_to_type(builder, arg_val, ext_param_ty, arg)
elif found_func is not None:
# found_func 存在:按形参类型 coerce(如 stdlib.malloc(size: t.CSizeT))
# found_func 存在:按形参类型 coerce(如 stdlib.malloc(size: sizet))
# 修复: CDefine/i32 常量传给 i64 形参未提升,导致 call(i32) 与 define(i64) 不匹配
if fp is not None:
if fpty is not None:
@@ -1088,44 +1088,44 @@ class CallGenMixin(CallGenBase.CallGenBase):
# 默认参数填充:当实参数量 < 形参数量时,用默认值填充缺失参数
# defaults 数组右对齐到 args:defaults[0] 对应 args[offset],offset = param_count - default_count
if can > 0 or (can == 0 and cargs is not None):
df_defaults: t.CVoid | t.CPtr = None
df_defaults: t.CPtr = None
df_default_count: int = 0
df_param_count: int = 0
# 计算被调模块 SHA1 作限定键(消除跨模块同名函数串味):
# module.func(...) → 该 module 的 SHA1;裸名调用 → 当前模块 SHA1。
# 模块表与全局默认参数表都按「名 + 定义模块 SHA1」精确匹配,避免
# usb.uhci.init(1 参) 误命中 mm.init(5 参/2 默认值) 而补出多余实参。
# 必须先算(模块表查找也要用它限定定义模块 → 见下)。
dfx_callee_sha: str = None
if cl.func is not None and cl.func.kind() == ast.ASTKind.Attribute:
dfx_at: ast.Attribute | t.CPtr = (ast.Attribute | t.CPtr)(cl.func)
if dfx_at.value is not None and dfx_at.value.kind() == ast.ASTKind.Name:
dfx_mn: ast.Name | t.CPtr = (ast.Name | t.CPtr)(dfx_at.value)
if dfx_mn.id is not None:
dfx_callee_sha = self._lookup_module_sha1(dfx_mn.id)
if dfx_callee_sha is None and self.Gen.TypeGenBase is not None:
dfx_callee_sha = self.Gen.TypeGenBase.CurrentModuleSha1
# 从当前模块函数表查找 FuncEntry —— 必须按**定义模块 SHA1 限定**:
# 表内含 LoadDepVpiIntoModule 以裸名注入的依赖 stub(槽位在前),
# 裸名首命中会让 usb 的 `uhci.init(io_base)`(1 形参)拿到 mm.init 的
# 5 形参/2 默认值 → 调用点被补 2 个 i32 0(N17)。
# 注:仅做「精确到定义模块」这一项改动;下方交叉校验守卫(dfx_cnt)
# 保持原样(`dfx_cnt > 0 and ...`)——收紧它会让 dfx_cnt==0 的场景
# 落入 `elif found_func is not None` 零值兜底分支,改动面更大,
# 且本项改动已足以修掉 N17(受限查找命中本模块/同定义模块条目,
# Defaults 为 None 或本模块池内 AST)。
if trans is not None and trans._funcs is not None:
df_entry: GenTypes.FuncEntry | t.CPtr = self.Gen.CallGenLeafKit.find_func_entry_in_table_owned(
trans._funcs, trans._func_count, func_name, dfx_callee_sha)
if df_entry is not None:
df_defaults = df_entry.Defaults
df_default_count = df_entry.DefaultCount
df_param_count = df_entry.ParamCount
# 无条件查询全局默认参数表(跨模块/同模块都要用 stdlib 常量快照
# 重建默认值:模块表 Defaults 指向 pool 内 AST,跨 1b reset 后悬空;
# 快照才是跨文件永久存活。同模块命中时 gd_entry 也必须已赋值,
# 否则下方 _build_const_from_snapshot 读到未初始化栈垃圾指针崩溃。
# 与 _translate_method_call 的 mdf_gd 无条件查询(L2677)保持一致。
# 计算被调模块 SHA1 作限定键(消除跨模块同名函数串味):
# module.func(...) → 该 module 的 SHA1;裸名调用 → 当前模块 SHA1。
# 模块表与全局默认参数表都按「名 + 定义模块 SHA1」精确匹配,避免
# usb.uhci.init(1 参) 误命中 mm.init(5 参/2 默认值) 而补出多余实参。
# 必须先算(模块表查找也要用它限定定义模块 → 见下)。
dfx_callee_sha: str = None
if cl.func is not None and cl.func.kind() == ast.ASTKind.Attribute:
dfx_at: ast.Attribute | t.CPtr = (ast.Attribute | t.CPtr)(cl.func)
if dfx_at.value is not None and dfx_at.value.kind() == ast.ASTKind.Name:
dfx_mn: ast.Name | t.CPtr = (ast.Name | t.CPtr)(dfx_at.value)
if dfx_mn.id is not None:
dfx_callee_sha = self._lookup_module_sha1(dfx_mn.id)
if dfx_callee_sha is None and self.Gen.TypeGenBase is not None:
dfx_callee_sha = self.Gen.TypeGenBase.CurrentModuleSha1
# 从当前模块函数表查找 FuncEntry —— 必须按**定义模块 SHA1 限定**:
# 表内含 LoadDepVpiIntoModule 以裸名注入的依赖 stub(槽位在前),
# 裸名首命中会让 usb 的 `uhci.init(io_base)`(1 形参)拿到 mm.init 的
# 5 形参/2 默认值 → 调用点被补 2 个 i32 0(N17)。
# 注:仅做「精确到定义模块」这一项改动;下方交叉校验守卫(dfx_cnt)
# 保持原样(`dfx_cnt > 0 and ...`)——收紧它会让 dfx_cnt==0 的场景
# 落入 `elif found_func is not None` 零值兜底分支,改动面更大,
# 且本项改动已足以修掉 N17(受限查找命中本模块/同定义模块条目,
# Defaults 为 None 或本模块池内 AST)。
if trans is not None and trans._funcs is not None:
df_entry: GenTypes.FuncEntry | t.CPtr = self.Gen.CallGenLeafKit.find_func_entry_in_table_owned(
trans._funcs, trans._func_count, func_name, dfx_callee_sha)
if df_entry is not None:
df_defaults = df_entry.Defaults
df_default_count = df_entry.DefaultCount
df_param_count = df_entry.ParamCount
# 无条件查询全局默认参数表(跨模块/同模块都要用 stdlib 常量快照
# 重建默认值:模块表 Defaults 指向 pool 内 AST,跨 1b reset 后悬空;
# 快照才是跨文件永久存活。同模块命中时 gd_entry 也必须已赋值,
# 否则下方 _build_const_from_snapshot 读到未初始化栈垃圾指针崩溃。
# 与 _translate_method_call 的 mdf_gd 无条件查询(L2677)保持一致。
gd_entry: GenTypes.FuncDefaultsEntry | t.CPtr = self.Gen.CallGenLeafKit.find_func_defaults(func_name, dfx_callee_sha)
if df_defaults is None and gd_entry is not None:
df_defaults = gd_entry.Defaults
@@ -1161,7 +1161,7 @@ class CallGenMixin(CallGenBase.CallGenBase):
df_arg_val = self.Gen.CallGenLeafKit._build_const_from_snapshot(
pool, mod, gd_entry, df_di, trans, builder)
if df_arg_val is None:
df_defaults_list: list[ast.AST | t.CPtr] | t.CPtr = (list[ast.AST | t.CPtr] | t.CPtr)(t.CVoid(t.CUInt64T(df_defaults), t.CPtr))
df_defaults_list: list[ast.AST | t.CPtr] | t.CPtr = (list[ast.AST | t.CPtr] | t.CPtr)(t.CVoid(uint64(df_defaults), t.CPtr))
df_default_node: ast.AST | t.CPtr = df_defaults_list.get(df_di)
if df_default_node is not None:
df_arg_val = self.Gen.ExprGen.translate_value(
@@ -1245,7 +1245,7 @@ class CallGenMixin(CallGenBase.CallGenBase):
if found_func.IsDeclared != 0:
dot_pos_cx: str = string.strchr(found_name, 46)
if dot_pos_cx is not None:
cx_pre_len: t.CSizeT = string.strlen(found_name) - string.strlen(dot_pos_cx)
cx_pre_len: sizet = string.strlen(found_name) - string.strlen(dot_pos_cx)
if cx_pre_len == 16:
cx_sha1_buf: str = pool.alloc(17)
if cx_sha1_buf is not None:
@@ -1305,17 +1305,17 @@ class CallGenMixin(CallGenBase.CallGenBase):
# from _types/_enums/_cfl import *)逐个验证定义模块:
# is_cexport_func/_is_state_func_from_vpi 按 vpi 返回注解
# 确认 func_name 真实定义处(Fl_init_all → _cfl)。
cs_total: t.CSizeT = string.strlen(reexport_src)
cs_i: t.CSizeT = 0
cs_total: sizet = string.strlen(reexport_src)
cs_i: sizet = 0
while cs_i < cs_total:
while cs_i < cs_total and reexport_src[cs_i] == ' ':
cs_i += 1
if cs_i >= cs_total:
break
cs_start: t.CSizeT = cs_i
cs_start: sizet = cs_i
while cs_i < cs_total and reexport_src[cs_i] != ' ':
cs_i += 1
cs_seg: t.CSizeT = cs_i - cs_start
cs_seg: sizet = cs_i - cs_start
cs_buf: str = pool.alloc(cs_seg + 1)
if cs_buf is not None:
string.strncpy(cs_buf, reexport_src + cs_start, cs_seg)
@@ -1368,7 +1368,7 @@ class CallGenMixin(CallGenBase.CallGenBase):
# 必须用裸名——带 sha1 前缀 → ld.lld undefined symbol
call_name = func_name
else:
mangled_len: t.CSizeT = string.strlen(mod_sha1) + string.strlen(func_name) + 2
mangled_len: sizet = string.strlen(mod_sha1) + string.strlen(func_name) + 2
mangled: str = pool.alloc(mangled_len)
if mangled is not None:
viperlib.snprintf(mangled, mangled_len, "%s.%s", mod_sha1, func_name)
@@ -1400,7 +1400,7 @@ class CallGenMixin(CallGenBase.CallGenBase):
# t.State 外部 C 函数:裸名(同主路径 L7918)
call_name = func_name
else:
AliasMangledLen: t.CSizeT = string.strlen(alias_sha1) + string.strlen(func_name) + 2
AliasMangledLen: sizet = string.strlen(alias_sha1) + string.strlen(func_name) + 2
alias_mangled: str = pool.alloc(AliasMangledLen)
if alias_mangled is not None:
viperlib.snprintf(alias_mangled, AliasMangledLen, "%s.%s", alias_sha1, func_name)
@@ -1425,7 +1425,7 @@ class CallGenMixin(CallGenBase.CallGenBase):
if self.Gen.CallGenBase.is_cexport_func(from_sha1, func_name) != 0:
call_name = func_name
else:
fmangled_len: t.CSizeT = string.strlen(from_sha1) + string.strlen(func_name) + 2
fmangled_len: sizet = string.strlen(from_sha1) + string.strlen(func_name) + 2
fmangled: str = pool.alloc(fmangled_len)
if fmangled is not None:
viperlib.snprintf(fmangled, fmangled_len, "%s.%s", from_sha1, func_name)
@@ -1455,7 +1455,7 @@ class CallGenMixin(CallGenBase.CallGenBase):
if bare_orig is not None:
# bare_orig 指向 from_imports 内部缓冲区,未 null 终止
# 需复制到独立缓冲区(截断于空格或 null)
bo_len: t.CSizeT = 0
bo_len: sizet = 0
while bare_orig[bo_len] != ' ' and bare_orig[bo_len] != '\0':
bo_len += 1
bo_buf: str = pool.alloc(bo_len + 1)
@@ -1486,7 +1486,7 @@ class CallGenMixin(CallGenBase.CallGenBase):
if self.Gen.CallGenBase.is_cexport_func(bare_sha1, bare_func_name) != 0:
call_name = bare_func_name
else:
bare_mangled_len: t.CSizeT = string.strlen(bare_sha1) + string.strlen(bare_func_name) + 2
bare_mangled_len: sizet = string.strlen(bare_sha1) + string.strlen(bare_func_name) + 2
bare_mangled: str = pool.alloc(bare_mangled_len)
if bare_mangled is not None:
viperlib.snprintf(bare_mangled, bare_mangled_len, "%s.%s", bare_sha1, bare_func_name)
@@ -1536,8 +1536,8 @@ class CallGenMixin(CallGenBase.CallGenBase):
cf_last: str = string.strrchr(call_name, '.')
if cf_dot is not None and cf_last is not None:
cf_sha1: str = stdlib.malloc(17)
cf_bare_len: t.CSizeT = string.strlen(call_name) - \
(t.CSizeT(t.CUInt64T(cf_last) - t.CUInt64T(call_name))) - 1
cf_bare_len: sizet = string.strlen(call_name) - \
(sizet(uint64(cf_last) - uint64(call_name))) - 1
cf_bare: str = stdlib.malloc(cf_bare_len + 1)
if cf_sha1 is not None and cf_bare is not None:
string.strncpy(cf_sha1, call_name, 16)
@@ -1598,7 +1598,7 @@ class CallGenMixin(CallGenBase.CallGenBase):
stdlib.free(cf_bare)
# 裸名 C 库函数(string.memset → @memset):实参按标准签名提升
# (第三参 i32 字面量 → i64),再建 declare,保证 call 实参与
# declare/定义宽度一致(B3:process 固化 i32 vs 定义 t.CSizeT=i64)。
# declare/定义宽度一致(B3:process 固化 i32 vs 定义 sizet=i64)。
head = self.Gen.CallGenLib._promote_clib_call_args(
pool, builder, mod, call_name, head, can)
# 跨模块模块级调用({sha1}.{func}):实参按 vpi 定义侧形参类型 coerce
@@ -1612,7 +1612,7 @@ class CallGenMixin(CallGenBase.CallGenBase):
# 检查被调用函数是否为变长函数(*args),若是则对变长参数进行 C ABI 提升
# (cargs 为本函数参数 AST 链表,self_offset=0 普通函数调用)
is_variadic_call: int = self.Gen.CallGenVa._check_and_promote_variadic_call(
pool, builder, mod, call_name, head, can, cargs, t.CSizeT(0), trans)
pool, builder, mod, call_name, head, can, cargs, sizet(0), trans)
# try-except:被调函数带 EH 输出参数时,追加输出实参 + 调用后检测异常
return self.Gen.CallGenLeafKit._emit_eh_guarded_call(
builder, pool, mod, trans, found_func, call_name, head, can,
+2 -2
View File
@@ -79,7 +79,7 @@ class CallGenProp(CallGenBase.CallGenBase):
# 未找到:用类所属模块的 SHA1 构造调用名
cls_sha1_pc: str = self.Gen.StructGen.get_struct_sha1(class_name)
if cls_sha1_pc is not None:
mlen_pc: t.CSizeT = string.strlen(cls_sha1_pc) + string.strlen(lookup_name) + 2
mlen_pc: sizet = string.strlen(cls_sha1_pc) + string.strlen(lookup_name) + 2
mangled_pc: str = pool.alloc(mlen_pc)
if mangled_pc is not None:
viperlib.snprintf(mangled_pc, mlen_pc, "%s.%s", cls_sha1_pc, lookup_name)
@@ -351,7 +351,7 @@ class CallGenProp(CallGenBase.CallGenBase):
# 翻译调用参数
cargs: list[ast.AST | t.CPtr] | t.CPtr = cl.args
can: t.CSizeT = 0
can: sizet = 0
if cargs is not None:
can = len(cargs)
tail: llvmlite.Value | t.CPtr = head
+10 -10
View File
@@ -57,8 +57,8 @@ class CallGenVa(CallGenBase.CallGenBase):
"""解析 va_arg/arg 的类型参数为 LLVMType
支持的类型表达式:
t.CInt / t.CInt32T → i32
t.CInt64T → i64
int / int32 → i32
int64 → i64
t.CDouble → double
t.CPtr / str → i8*
str / bytes → i8*
@@ -79,7 +79,7 @@ class CallGenVa(CallGenBase.CallGenBase):
mod: llvmlite.LLVMModule | t.CPtr,
cl: ast.Call | t.CPtr,
cargs: list[ast.AST | t.CPtr] | t.CPtr,
can: t.CSizeT,
can: sizet,
funcs_ptr: t.CPtr,
func_count: int,
trans: HT.Translator | t.CPtr) -> llvmlite.Value | t.CPtr:
@@ -108,7 +108,7 @@ class CallGenVa(CallGenBase.CallGenBase):
# Win64 变参槽位为 8 字节:<64 位整数按 i64 读取(对齐 TPC emit_va_arg L72-73),
# 再 trunc 回目标宽度——否则返回 8 字节含高位垃圾,%d/%i 语义错误
# (viperlib vsnprintf %d 非 long 分支 `t.CInt64T(va_arg(ap, t.CInt))`
# (viperlib vsnprintf %d 非 long 分支 `int64(va_arg(ap, int))`
# 编译成直接 va_arg i64,高 32 位未定义 → 负数当大正数 A6 根因)。
read_ty: llvmlite.LLVMType | t.CPtr = arg_ty
abits_va: int = self.Gen.ExprGenBase.get_llvm_type_bits(arg_ty)
@@ -117,7 +117,7 @@ class CallGenVa(CallGenBase.CallGenBase):
va_raw: llvmlite.Value | t.CPtr = llvmlite.build_va_arg(builder, ap_ptr, read_ty)
if va_raw is None:
return llvmlite.const_int32(pool, 0)
# 8 字节槽 → 目标宽度(低 bits 位);调用方 t.CInt64T(...) 会再 sext/zext
# 8 字节槽 → 目标宽度(低 bits 位);调用方 int64(...) 会再 sext/zext
return llvmlite.build_trunc(builder, va_raw, arg_ty)
# 生成 va_arg 指令
@@ -127,7 +127,7 @@ class CallGenVa(CallGenBase.CallGenBase):
mod: llvmlite.LLVMModule | t.CPtr,
cl: ast.Call | t.CPtr,
cargs: list[ast.AST | t.CPtr] | t.CPtr,
can: t.CSizeT,
can: sizet,
funcs_ptr: t.CPtr,
func_count: int,
trans: HT.Translator | t.CPtr) -> llvmlite.Value | t.CPtr:
@@ -162,7 +162,7 @@ class CallGenVa(CallGenBase.CallGenBase):
builder: llvmlite.IRBuilder | t.CPtr,
mod: llvmlite.LLVMModule | t.CPtr,
cargs: list[ast.AST | t.CPtr] | t.CPtr,
can: t.CSizeT,
can: sizet,
funcs_ptr: t.CPtr,
func_count: int,
trans: HT.Translator | t.CPtr) -> llvmlite.Value | t.CPtr:
@@ -194,7 +194,7 @@ class CallGenVa(CallGenBase.CallGenBase):
builder: llvmlite.IRBuilder | t.CPtr,
mod: llvmlite.LLVMModule | t.CPtr,
cargs: list[ast.AST | t.CPtr] | t.CPtr,
can: t.CSizeT,
can: sizet,
funcs_ptr: t.CPtr,
func_count: int,
trans: HT.Translator | t.CPtr) -> llvmlite.Value | t.CPtr:
@@ -281,7 +281,7 @@ class CallGenVa(CallGenBase.CallGenBase):
mod: llvmlite.LLVMModule | t.CPtr,
call_name: str,
head: llvmlite.Value | t.CPtr,
can: t.CSizeT,
can: sizet,
arg_nodes: list[ast.AST | t.CPtr] | t.CPtr = None,
self_offset: int = 0,
trans: HT.Translator | t.CPtr = None) -> int:
@@ -337,7 +337,7 @@ class CallGenVa(CallGenBase.CallGenBase):
# C ABI integer promotion: i8/i16 → i32
arg_bits: int = self.Gen.ExprGenBase.get_llvm_type_bits(cur.Ty)
if arg_bits != 0 and arg_bits < 32:
# 无符号整型(t.CUInt8T/CUInt16T 等)→ zext;有符号/未知 → sext。
# 无符号整型(uint8/CUInt16T 等)→ zext;有符号/未知 → sext。
# 修复: printf("%02x", buf[i]) 中 buf[i] 是 CUInt8T,sext 得
# 0xFFFFFFF3 打印 fffffff3(哈希摘要输出垃圾),应 zext 得 0xF3。
is_u_va: int = 0
+63 -63
View File
@@ -57,36 +57,36 @@ class ClassGenBase:
# --- REnum 变体表(原 _renum_class_names/_renum_class_variant_counts/
# _renum_variant_names/_renum_variant_tags/_renum_class_count) ---
RenumClassNames: t.CSizeT | t.CPtr
RenumClassVariantCounts: t.CSizeT | t.CPtr
RenumVariantNames: t.CSizeT | t.CPtr
RenumVariantTags: t.CSizeT | t.CPtr
RenumClassNames: sizet | t.CPtr
RenumClassVariantCounts: sizet | t.CPtr
RenumVariantNames: sizet | t.CPtr
RenumVariantTags: sizet | t.CPtr
RenumClassCount: int
# --- REnum 字段别名表(原 _renum_alias_class/_renum_alias_field/
# _renum_alias_index/_renum_alias_count) ---
RenumAliasClass: t.CSizeT | t.CPtr
RenumAliasField: t.CSizeT | t.CPtr
RenumAliasIndex: t.CSizeT | t.CPtr
RenumAliasClass: sizet | t.CPtr
RenumAliasField: sizet | t.CPtr
RenumAliasIndex: sizet | t.CPtr
# 变体成员实际 LLVM 类型(对齐 TPC class_members):注册时按注解解析,
# perm_pool 深拷贝持久化。match 绑定用真实成员类型 bitcast 槽位地址
# (Struct.Name: i8*,否则按槽位 i64 读 → is/subscript/strlen 失败)。
RenumAliasTy: t.CSizeT | t.CPtr
RenumAliasTy: sizet | t.CPtr
# 别名所属变体名(perm_pool 拷贝):同一 payload 位置跨变体类型不同
# (Int.Bits=i32 vs Struct.Fields=Ptr),match 绑定按 (class, 变体, 位置)
# 唯一定位成员类型。
RenumAliasVariant: t.CSizeT | t.CPtr
RenumAliasVariant: sizet | t.CPtr
RenumAliasCount: int
# --- 泛型特化缓存(原 _spec_keys/_spec_names/_spec_count) ---
SpecKeys: t.CSizeT | t.CPtr
SpecNames: t.CSizeT | t.CPtr
SpecKeys: sizet | t.CPtr
SpecNames: sizet | t.CPtr
SpecCount: int
# --- 类编译期元数据表(__provides__/__requires__/__require_must__) ---
# perm_pool 分配(跨 mark/reset 存活):每槽 kind(4B) + cls(64B) + field(64B)
# FakeDuck:_str.__requires__=['__mbuddy__'] 等(FakeDuck 移植点 1)
ClassMetaKinds: t.CInt | t.CPtr
ClassMetaKinds: int | t.CPtr
ClassMetaClss: bytes
ClassMetaFields: bytes
ClassMetaCount: int
@@ -100,7 +100,7 @@ class ClassGenBase:
DecoratorFuncNames: bytes
DecoratorWrapNames: bytes
# 装饰器首个常量参数(@repeat(3) 的 3),无参数为 0(每槽 8B,i64)
DecoratorArgs: t.CInt64T | t.CPtr
DecoratorArgs: int64 | t.CPtr
# --- 异常类注册表(try-except,对齐 TPC HandlesClassDef.py L47-61) ---
# perm_pool 分配(跨 mark/reset 存活):每槽类名(128B) + 父类名(128B) + 编码(4B)
@@ -109,7 +109,7 @@ class ClassGenBase:
ExceptionCount: int
ExceptionNames: bytes
ExceptionParents: bytes
ExceptionCodes: t.CInt | t.CPtr
ExceptionCodes: int | t.CPtr
# 下一个待分配的异常编码(用户类,从 100 起)
NextExceptionCode: int
# 递归收集子孙编码用的临时计数(collect_descendant_codes 返回后无效)。
@@ -138,13 +138,13 @@ class ClassGenBase:
# 可能失效(VectorGenericTest 特化 Vector[int].__init__ 的 T.__sizeof__()
# NameError 根因方向);注册时展平深拷贝到 stdlib,特化时从本表恢复。
# 每槽指向一个空格分隔、NUL 结尾的 stdlib 缓冲区(如 "T" 或 "T K")。
GenericClassTpParams: t.CSizeT | t.CPtr
GenericClassTpParams: sizet | t.CPtr
# --- vtable 方法收集表(原 _g_vt_full_names/_g_vt_method_names/
# _g_vt_parent_sha1s/_g_vt_method_count) ---
VtFullNames: t.CSizeT | t.CPtr
VtMethodNames: t.CSizeT | t.CPtr
VtParentSha1s: t.CSizeT | t.CPtr
VtFullNames: sizet | t.CPtr
VtMethodNames: sizet | t.CPtr
VtParentSha1s: sizet | t.CPtr
VtMethodCount: int
# ============================================================
# 以下方法由 P5-2 分簇迁移填充(函数体来自 HandlesClassDef.vp,
@@ -170,7 +170,7 @@ class ClassGenBase:
alias_orig: str = self.Gen.ImportsGen.lookup_from_import_original(
trans._from_imports, nm.id)
if alias_orig is not None:
og_len_ce: t.CSizeT = 0
og_len_ce: sizet = 0
while alias_orig[og_len_ce] != ' ' and alias_orig[og_len_ce] != '\0':
og_len_ce += 1
if og_len_ce == 5 and string.strncmp(alias_orig, "CEnum", 5) == 0:
@@ -195,7 +195,7 @@ class ClassGenBase:
if cd.bases is None:
return 0
bases: list[ast.AST | t.CPtr] | t.CPtr = cd.bases
bn: t.CSizeT = len(bases)
bn: sizet = len(bases)
if bn == 0:
return 0
for bi in range(bn):
@@ -223,7 +223,7 @@ class ClassGenBase:
alias_orig: str = self.Gen.ImportsGen.lookup_from_import_original(
trans._from_imports, nm.id)
if alias_orig is not None:
og_len_cu: t.CSizeT = 0
og_len_cu: sizet = 0
while alias_orig[og_len_cu] != ' ' and alias_orig[og_len_cu] != '\0':
og_len_cu += 1
if og_len_cu == 6 and string.strncmp(alias_orig, "CUnion", 6) == 0:
@@ -248,7 +248,7 @@ class ClassGenBase:
if cd.bases is None:
return 0
bases: list[ast.AST | t.CPtr] | t.CPtr = cd.bases
bn: t.CSizeT = len(bases)
bn: sizet = len(bases)
if bn == 0:
return 0
for bi in range(bn):
@@ -276,7 +276,7 @@ class ClassGenBase:
alias_orig: str = self.Gen.ImportsGen.lookup_from_import_original(
trans._from_imports, nm.id)
if alias_orig is not None:
og_len_cr: t.CSizeT = 0
og_len_cr: sizet = 0
while alias_orig[og_len_cr] != ' ' and alias_orig[og_len_cr] != '\0':
og_len_cr += 1
if og_len_cr == 5 and string.strncmp(alias_orig, "REnum", 5) == 0:
@@ -301,7 +301,7 @@ class ClassGenBase:
if cd.bases is None:
return 0
bases: list[ast.AST | t.CPtr] | t.CPtr = cd.bases
bn: t.CSizeT = len(bases)
bn: sizet = len(bases)
if bn == 0:
return 0
for bi in range(bn):
@@ -316,7 +316,7 @@ class ClassGenBase:
"""检查 decorator_list 中是否有指定装饰器名"""
if decorator_list is None:
return 0
dn: t.CSizeT = len(decorator_list)
dn: sizet = len(decorator_list)
if dn == 0:
return 0
for di in range(dn):
@@ -366,7 +366,7 @@ class ClassGenBase:
"""
if decorator_list is None:
return 0
dn: t.CSizeT = len(decorator_list)
dn: sizet = len(decorator_list)
if dn == 0:
return 0
for di in range(dn):
@@ -384,7 +384,7 @@ class ClassGenBase:
continue
if cl.args is None:
continue
an: t.CSizeT = len(cl.args)
an: sizet = len(cl.args)
for ai in range(an):
ag: ast.AST | t.CPtr = cl.args.get(ai)
if ag is not None and self._tattr_name(ag, attr_name) != 0:
@@ -419,7 +419,7 @@ class ClassGenBase:
"""取 @c.Attribute(t.attr.aligned(N)) 的对齐字节数,无 aligned 返回 0"""
if decorator_list is None:
return 0
dn: t.CSizeT = len(decorator_list)
dn: sizet = len(decorator_list)
if dn == 0:
return 0
for di in range(dn):
@@ -435,7 +435,7 @@ class ClassGenBase:
continue
if cl.args is None:
continue
an: t.CSizeT = len(cl.args)
an: sizet = len(cl.args)
for ai in range(an):
ag: ast.AST | t.CPtr = cl.args.get(ai)
if ag is not None:
@@ -452,7 +452,7 @@ class ClassGenBase:
meta: int = 0
if decorator_list is None:
return meta
dn: t.CSizeT = len(decorator_list)
dn: sizet = len(decorator_list)
if dn == 0:
return meta
for di in range(dn):
@@ -517,7 +517,7 @@ class ClassGenBase:
if string.strcmp(self.ClassMetaClss + i * 64, cls) == 0:
if string.strcmp(self.ClassMetaFields + i * 64, field) == 0:
return 0
idx_cm: t.CSizeT = t.CSizeT(self.ClassMetaCount) * 64
idx_cm: sizet = sizet(self.ClassMetaCount) * 64
self.ClassMetaKinds[self.ClassMetaCount] = kind
string.strncpy(self.ClassMetaClss + idx_cm, cls, 63)
self.ClassMetaClss[idx_cm + 63] = '\0'
@@ -549,7 +549,7 @@ class ClassGenBase:
return None
def register_decorator(self, pool: memhub.MemBuddy | t.CPtr,
func_name: str, wrapper_name: str,
arg0: t.CInt64T) -> int:
arg0: int64) -> int:
"""注册自定义装饰器函数(@log/@skip/@repeat(3) → __decor_wrap_{name})
对齐 TPC HandlesFunctions.py L1621-1631 的 _decorated_funcs 注册。
@@ -577,7 +577,7 @@ class ClassGenBase:
for i in range(self.DecoratorFuncCount):
if string.strcmp(self.DecoratorFuncNames + i * DECOR_NAME_LEN, func_name) == 0:
return 0
idx_dc: t.CSizeT = t.CSizeT(self.DecoratorFuncCount) * DECOR_NAME_LEN
idx_dc: sizet = sizet(self.DecoratorFuncCount) * DECOR_NAME_LEN
string.strncpy(self.DecoratorFuncNames + idx_dc, func_name, DECOR_NAME_LEN - 1)
self.DecoratorFuncNames[idx_dc + DECOR_NAME_LEN - 1] = '\0'
string.strncpy(self.DecoratorWrapNames + idx_dc, wrapper_name, DECOR_NAME_LEN - 1)
@@ -593,7 +593,7 @@ class ClassGenBase:
if string.strcmp(self.DecoratorFuncNames + i * DECOR_NAME_LEN, func_name) == 0:
return self.DecoratorWrapNames + i * DECOR_NAME_LEN
return None
def lookup_decor_arg0(self, func_name: str) -> t.CInt64T:
def lookup_decor_arg0(self, func_name: str) -> int64:
"""按原函数名查装饰器首个常量参数(无参数为 0)"""
if self.DecoratorFuncNames is None or func_name is None:
return 0
@@ -635,7 +635,7 @@ class ClassGenBase:
return self.ExceptionCodes[i]
if self.ExceptionCount >= EXCEPTION_MAX:
return -1
idx_e: t.CSizeT = t.CSizeT(self.ExceptionCount) * EXCEPTION_NAME_LEN
idx_e: sizet = sizet(self.ExceptionCount) * EXCEPTION_NAME_LEN
string.strncpy(self.ExceptionNames + idx_e, class_name, EXCEPTION_NAME_LEN - 1)
self.ExceptionNames[idx_e + EXCEPTION_NAME_LEN - 1] = '\0'
if parent_name is not None:
@@ -697,7 +697,7 @@ class ClassGenBase:
if string.strcmp(self.ExceptionNames + i * EXCEPTION_NAME_LEN, name) == 0:
return 1
return 0
def collect_descendant_codes(self, name: str, out_codes: t.CInt | t.CPtr,
def collect_descendant_codes(self, name: str, out_codes: int | t.CPtr,
max_codes: int) -> int:
"""把 name 及其所有子孙异常类的编码收集到 out_codes,返回数量
(对齐 TPC HandlesTry.py _get_all_match_codes/_collect_descendant_codes:
@@ -707,7 +707,7 @@ 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: t.CInt | t.CPtr,
def _collect_desc_codes_rec(self, name: str, out_codes: int | t.CPtr,
max_codes: int, depth: int) -> None:
"""递归收集 name 编码 + 全部子孙编码(BFS 语义对齐 TPC)"""
if depth > 32:
@@ -737,7 +737,7 @@ class ClassGenBase:
if cd is None or cd.bases is None:
return 0
bases_e: list[ast.AST | t.CPtr] | t.CPtr = cd.bases
bn_e: t.CSizeT = len(bases_e)
bn_e: sizet = len(bases_e)
for bi_e in range(bn_e):
base_e: ast.AST | t.CPtr = bases_e.get(bi_e)
if base_e is None:
@@ -761,7 +761,7 @@ class ClassGenBase:
if cd is None or cd.bases is None:
return None
bases_e2: list[ast.AST | t.CPtr] | t.CPtr = cd.bases
bn_e2: t.CSizeT = len(bases_e2)
bn_e2: sizet = len(bases_e2)
for bi_e2 in range(bn_e2):
base_e2: ast.AST | t.CPtr = bases_e2.get(bi_e2)
if base_e2 is None:
@@ -798,7 +798,7 @@ class ClassGenBase:
if lst_rcm.elts is None:
return
elts_rcm: list[ast.AST | t.CPtr] | t.CPtr = lst_rcm.elts
en_rcm: t.CSizeT = len(elts_rcm)
en_rcm: sizet = len(elts_rcm)
for ei_rcm in range(en_rcm):
el_rcm: ast.AST | t.CPtr = elts_rcm.get(ei_rcm)
if el_rcm is None or el_rcm.kind() != ast.ASTKind.Constant:
@@ -820,8 +820,8 @@ class ClassGenBase:
string.memset(self.MethodMetaKeys, 0, META_MAX * META_KEY_LEN)
string.memset(self.MethodMetaFlags, 0, META_MAX * 4)
# 构造 key "ClassName.method"
cl_len: t.CSizeT = string.strlen(class_name)
mn_len: t.CSizeT = string.strlen(method_name)
cl_len: sizet = string.strlen(class_name)
mn_len: sizet = string.strlen(method_name)
key_buf: bytes = stdlib.malloc(cl_len + mn_len + 2)
if key_buf is None:
return
@@ -830,8 +830,8 @@ class ClassGenBase:
i: int
for i in range(self.MethodMetaCount):
if string.strcmp(self.MethodMetaKeys + i * META_KEY_LEN, key_buf) == 0:
flags_ptr: t.CPtr = (t.CInt | t.CPtr)(t.CVoid(
t.CUInt64T(self.MethodMetaFlags) + i * 4, t.CPtr))
flags_ptr: t.CPtr = (int | t.CPtr)(t.CVoid(
uint64(self.MethodMetaFlags) + i * 4, t.CPtr))
# 按位或合并:同一属性名先 @property(getter=4) 再 @x.setter(8)/
# @x.deleter(16) 会多次注册(如 Config.value / Counter.value)。
# 若整值替换,后注册的位会覆盖 GETTER 位 → _try_property_getter_attr
@@ -844,8 +844,8 @@ class ClassGenBase:
# 槽位定长 META_KEY_LEN=128 字节,key 超长时 strncpy 钳制防越界写相邻槽
string.strncpy(self.MethodMetaKeys + self.MethodMetaCount * META_KEY_LEN,
key_buf, META_KEY_LEN - 1)
flags_ptr2: t.CPtr = (t.CInt | t.CPtr)(t.CVoid(
t.CUInt64T(self.MethodMetaFlags) + self.MethodMetaCount * 4, t.CPtr))
flags_ptr2: t.CPtr = (int | t.CPtr)(t.CVoid(
uint64(self.MethodMetaFlags) + self.MethodMetaCount * 4, t.CPtr))
flags_ptr2[0] = meta
self.MethodMetaCount += 1
stdlib.free(key_buf)
@@ -855,8 +855,8 @@ class ClassGenBase:
return 0
if self.MethodMetaKeys is None or self.MethodMetaCount <= 0:
return 0
cl_len: t.CSizeT = string.strlen(class_name)
mn_len: t.CSizeT = string.strlen(method_name)
cl_len: sizet = string.strlen(class_name)
mn_len: sizet = string.strlen(method_name)
key_buf: bytes = stdlib.malloc(cl_len + mn_len + 2)
if key_buf is None:
return 0
@@ -865,8 +865,8 @@ class ClassGenBase:
i: int
for i in range(self.MethodMetaCount):
if string.strcmp(self.MethodMetaKeys + i * META_KEY_LEN, key_buf) == 0:
flags_ptr: t.CPtr = (t.CInt | t.CPtr)(t.CVoid(
t.CUInt64T(self.MethodMetaFlags) + i * 4, t.CPtr))
flags_ptr: t.CPtr = (int | t.CPtr)(t.CVoid(
uint64(self.MethodMetaFlags) + i * 4, t.CPtr))
found = flags_ptr[0]
break
stdlib.free(key_buf)
@@ -944,9 +944,9 @@ class ClassGenBase:
if pool is None:
return base_nm
# 拼接特化名 "GSListNode[Value]"
base_len: t.CSizeT = string.strlen(base_nm)
arg_len: t.CSizeT = string.strlen(arg_nm)
total_len: t.CSizeT = base_len + arg_len + 3 # "[" + arg + "]" + NUL
base_len: sizet = string.strlen(base_nm)
arg_len: sizet = string.strlen(arg_nm)
total_len: sizet = base_len + arg_len + 3 # "[" + arg + "]" + NUL
mangled: str = pool.alloc(total_len)
if mangled is None:
return base_nm # 降级
@@ -966,7 +966,7 @@ class ClassGenBase:
if trans is not None:
pool = trans.Pool
bases: list[ast.AST | t.CPtr] | t.CPtr = cd.bases
bn: t.CSizeT = len(bases)
bn: sizet = len(bases)
if bn == 0:
return None
for bi in range(bn):
@@ -1001,7 +1001,7 @@ class ClassGenBase:
# 复制到独立缓冲并按空格截断出干净原始名——否则 _is_marker_base 的
# strcmp 对整串比较失败 → 别名基类(CStruct as cs)被当真实父类 →
# find_struct 失败 → 整类 defer 永不注册 → 变量注解解析失败。
og_len: t.CSizeT = 0
og_len: sizet = 0
while orig[og_len] != ' ' and orig[og_len] != '\0':
og_len += 1
if og_len > 0:
@@ -1013,14 +1013,14 @@ class ClassGenBase:
return base_name
def _collect_parents(self, pool: memhub.MemBuddy | t.CPtr,
cd: ast.ClassDef | t.CPtr,
parents_buf: t.CSizeT | t.CPtr,
parents_buf: sizet | t.CPtr,
max_parents: int,
trans: HT.Translator | t.CPtr = 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 | t.CPtr] | t.CPtr = cd.bases
bn: t.CSizeT = len(bases)
bn: sizet = len(bases)
count: int = 0
for bi in range(bn):
if count >= max_parents:
@@ -1033,16 +1033,16 @@ class ClassGenBase:
# 基类别名解析(同 _get_parent_class,见 _resolve_base_alias)
bname = self._resolve_base_alias(bname, trans)
if self._is_marker_base(bname) == 0:
parents_buf[count] = t.CSizeT(bname)
parents_buf[count] = sizet(bname)
count += 1
return count
def _field_name_exists(self, names_buf: t.CSizeT | t.CPtr,
def _field_name_exists(self, names_buf: sizet | t.CPtr,
count: int, name: str) -> int:
"""检查字段名是否已在 names_buf 中(先声明父类优先,重复跳过)"""
if names_buf is None or name is None:
return 0
for fi in range(count):
addr: t.CSizeT = names_buf[fi]
addr: sizet = names_buf[fi]
if addr != 0:
existing: str = (str | t.CPtr)(t.CVoid(addr, t.CPtr))
if existing is not None and string.strcmp(existing, name) == 0:
@@ -1052,7 +1052,7 @@ class ClassGenBase:
"""检查类体是否声明了字段(AnnAssign),0=纯方法/无字段类"""
if cd is None or cd.children is None:
return 0
cn: t.CSizeT = len(cd.children)
cn: sizet = len(cd.children)
for ci in range(cn):
stmt: ast.AST | t.CPtr = cd.children.get(ci)
if stmt is None:
@@ -1067,7 +1067,7 @@ class ClassGenBase:
return
pool: memhub.MemBuddy | t.CPtr = trans.Pool
bases: list[ast.AST | t.CPtr] | t.CPtr = cd.bases
bn: t.CSizeT = len(bases)
bn: sizet = len(bases)
if bn == 0:
return
for bi in range(bn):
@@ -1107,7 +1107,7 @@ class ClassGenBase:
if cd is None or cd.children is None:
return 0
children: list[ast.AST | t.CPtr] | t.CPtr = cd.children
cn: t.CSizeT = len(children)
cn: sizet = len(children)
for ci in range(cn):
stmt: ast.AST | t.CPtr = children.get(ci)
if stmt is None:
+27 -27
View File
@@ -111,7 +111,7 @@ class ClassGenDef(ClassGenBase.ClassGenBase):
existing.Ty = ty_deep
old_name: str = llvmlite.get_struct_name(existing.Ty)
if old_name is not None:
on_len: t.CSizeT = string.strlen(old_name)
on_len: sizet = string.strlen(old_name)
on_copy: str = CompilerFactory.factory.PermPool.alloc(on_len + 1)
if on_copy is not None:
string.strcpy(on_copy, old_name)
@@ -155,7 +155,7 @@ class ClassGenDef(ClassGenBase.ClassGenBase):
has_vtable: int = self.Gen.ClassGenBase._detect_vtable_status(cd, trans)
parent_name: str = self.Gen.ClassGenBase._get_parent_class(cd, trans)
# 多继承:收集所有真实父类名(跳过 marker base),供字段展平/vtable/MRO 使用
parents_buf: t.CSizeT | t.CPtr = pool.alloc(8 * GenTypes.PARENT_MAX)
parents_buf: sizet | t.CPtr = pool.alloc(8 * GenTypes.PARENT_MAX)
parents_count: int = 0
if parents_buf is not None:
parents_count = self.Gen.ClassGenBase._collect_parents(pool, cd, parents_buf, GenTypes.PARENT_MAX, trans)
@@ -189,10 +189,10 @@ class ClassGenDef(ClassGenBase.ClassGenBase):
# 1. 遍历 class body,收集字段信息
# ============================================================
# 用 CSizeT 数组存储指针值(64 位系统上 8 字节)
field_names_buf: t.CSizeT | t.CPtr = pool.alloc(8 * GenTypes.FIELD_MAX)
field_types_buf: t.CSizeT | t.CPtr = pool.alloc(8 * GenTypes.FIELD_MAX)
field_defaults_buf: t.CSizeT | t.CPtr = pool.alloc(8 * GenTypes.FIELD_MAX)
field_annot_buf: t.CSizeT | t.CPtr = pool.alloc(8 * GenTypes.FIELD_MAX)
field_names_buf: sizet | t.CPtr = pool.alloc(8 * GenTypes.FIELD_MAX)
field_types_buf: sizet | t.CPtr = pool.alloc(8 * GenTypes.FIELD_MAX)
field_defaults_buf: sizet | t.CPtr = pool.alloc(8 * GenTypes.FIELD_MAX)
field_annot_buf: sizet | t.CPtr = pool.alloc(8 * GenTypes.FIELD_MAX)
if field_names_buf is None or field_types_buf is None or field_defaults_buf is None:
return 0
if field_annot_buf is None:
@@ -215,7 +215,7 @@ class ClassGenDef(ClassGenBase.ClassGenBase):
# 多继承字段展平:遍历所有父类(声明顺序),字段名去重(先声明优先)
if parents_count > 0 and parents_buf is not None:
for pi in range(parents_count):
pname_addr: t.CSizeT = parents_buf[pi]
pname_addr: sizet = parents_buf[pi]
if pname_addr == 0:
continue
pname: str = (str | t.CPtr)(t.CVoid(pname_addr, t.CPtr))
@@ -270,14 +270,14 @@ class ClassGenDef(ClassGenBase.ClassGenBase):
pft: llvmlite.LLVMType | t.CPtr = self.Gen.StructGen.get_field_type_ptr(pfe)
pfd: ast.AST | t.CPtr = self.Gen.StructGen.get_field_default_ptr(pfe)
pfa: str = self.Gen.StructGen.get_field_annot_class_name(pfe)
field_names_buf[field_count] = t.CSizeT(pfn)
field_types_buf[field_count] = t.CSizeT(pft)
field_names_buf[field_count] = sizet(pfn)
field_types_buf[field_count] = sizet(pft)
if pfd is not None:
field_defaults_buf[field_count] = t.CSizeT(pfd)
field_defaults_buf[field_count] = sizet(pfd)
else:
field_defaults_buf[field_count] = 0
if pfa is not None:
stored_val: t.CSizeT = t.CSizeT(pfa)
stored_val: sizet = sizet(pfa)
field_annot_buf[field_count] = stored_val
else:
field_annot_buf[field_count] = 0
@@ -287,7 +287,7 @@ class ClassGenDef(ClassGenBase.ClassGenBase):
if children is None:
return 0
cn: t.CSizeT = len(children)
cn: sizet = len(children)
for ci in range(cn):
stmt: ast.AST | t.CPtr = children.get(ci)
if stmt is None:
@@ -323,10 +323,10 @@ class ClassGenDef(ClassGenBase.ClassGenBase):
if field_count < GenTypes.FIELD_MAX:
cdef_ty_l: llvmlite.LLVMType | t.CPtr = llvmlite.Int32(pool)
if cdef_ty_l is not None:
field_names_buf[field_count] = t.CSizeT(tgt.id)
field_types_buf[field_count] = t.CSizeT(cdef_ty_l)
field_names_buf[field_count] = sizet(tgt.id)
field_types_buf[field_count] = sizet(cdef_ty_l)
if aa.value is not None:
field_defaults_buf[field_count] = t.CSizeT(aa.value)
field_defaults_buf[field_count] = sizet(aa.value)
else:
field_defaults_buf[field_count] = 0
field_count += 1
@@ -421,12 +421,12 @@ class ClassGenDef(ClassGenBase.ClassGenBase):
# 存储到数组(指针转 CSizeT)
if field_count < GenTypes.FIELD_MAX:
diag_name_val: t.CSizeT = t.CSizeT(tgt.id)
diag_name_val: sizet = sizet(tgt.id)
field_names_buf[field_count] = diag_name_val
field_types_buf[field_count] = t.CSizeT(field_ty)
field_types_buf[field_count] = sizet(field_ty)
# 存储默认值 AST 指针(None=无默认值)
if aa.value is not None:
field_defaults_buf[field_count] = t.CSizeT(aa.value)
field_defaults_buf[field_count] = sizet(aa.value)
else:
field_defaults_buf[field_count] = 0
# 提取原始类型注解的类名(联合类型简化为 Ptr(i8) 时回退查找结构体)
@@ -435,7 +435,7 @@ class ClassGenDef(ClassGenBase.ClassGenBase):
annot_cn: str = self.Gen.TypeGenResolve.extract_class_name_from_annotation(
aa.annotation, trans._imported_modules, pool, trans._from_imports)
if annot_cn is not None:
diag_cn_val: t.CSizeT = t.CSizeT(annot_cn)
diag_cn_val: sizet = sizet(annot_cn)
field_annot_buf[field_count] = diag_cn_val
else:
field_annot_buf[field_count] = 0
@@ -475,7 +475,7 @@ class ClassGenDef(ClassGenBase.ClassGenBase):
total_field_count = field_count + 1
for fi in range(field_count):
fty_addr: t.CSizeT = field_types_buf[fi]
fty_addr: sizet = field_types_buf[fi]
if fty_addr == 0:
continue
fty: llvmlite.LLVMType | t.CPtr = (llvmlite.LLVMType | t.CPtr)(t.CVoid(fty_addr, t.CPtr))
@@ -504,7 +504,7 @@ class ClassGenDef(ClassGenBase.ClassGenBase):
viperlib.snprintf(name_buf, 64, "%s.%s", trans.ModuleSha1, class_name)
type_name = name_buf
if trans._declare_only == 0 and type_name is not None:
tn_len: t.CSizeT = string.strlen(type_name)
tn_len: sizet = string.strlen(type_name)
tn_copy: str = CompilerFactory.factory.PermPool.alloc(tn_len + 1)
if tn_copy is not None:
string.strcpy(tn_copy, type_name)
@@ -546,7 +546,7 @@ class ClassGenDef(ClassGenBase.ClassGenBase):
# 扫描字段类型,为跨模块结构体引用添加 opaque 声明
# 例如 list[int].__pool__ 引用 memhub.MemManager,需要在当前模块添加 %"sha1.MemManager" = type opaque
for fi in range(field_count):
fty_addr_op: t.CSizeT = field_types_buf[fi]
fty_addr_op: sizet = field_types_buf[fi]
if fty_addr_op == 0:
continue
fty_op: llvmlite.LLVMType | t.CPtr = (llvmlite.LLVMType | t.CPtr)(t.CVoid(fty_addr_op, t.CPtr))
@@ -580,7 +580,7 @@ class ClassGenDef(ClassGenBase.ClassGenBase):
# _translate_oop_methods/_detect_vtable_status 会在后续文件
# find_struct(ParentName) strcmp 解引用 → 用 stdlib 拷贝保证跨文件存活
if self.Gen.StructGen.get_stdlib_alloc() != 0:
pn_len: t.CSizeT = string.strlen(parent_name)
pn_len: sizet = string.strlen(parent_name)
pn_buf: str = CompilerFactory.factory.PermPool.alloc(pn_len + 1)
if pn_buf is not None:
string.strcpy(pn_buf, parent_name)
@@ -598,21 +598,21 @@ class ClassGenDef(ClassGenBase.ClassGenBase):
self.Gen.StructGen.add_field(pool, entry, "__vtable__", i8_ptr_ty2, None, None)
for fi in range(field_count):
fname_addr: t.CSizeT = field_names_buf[fi]
fname_addr: sizet = field_names_buf[fi]
if fname_addr == 0:
continue
fname: str = (str | t.CPtr)(t.CVoid(fname_addr, t.CPtr))
fty_addr2: t.CSizeT = field_types_buf[fi]
fty_addr2: sizet = field_types_buf[fi]
if fty_addr2 == 0:
continue
fty2: llvmlite.LLVMType | t.CPtr = (llvmlite.LLVMType | t.CPtr)(t.CVoid(fty_addr2, t.CPtr))
# 恢复默认值 AST 指针
fdef_addr: t.CSizeT = field_defaults_buf[fi]
fdef_addr: sizet = field_defaults_buf[fi]
fdef: ast.AST | t.CPtr = None
if fdef_addr != 0:
fdef = (ast.AST | t.CPtr)(t.CVoid(fdef_addr, t.CPtr))
# 恢复注解类名指针
fannot_addr: t.CSizeT = field_annot_buf[fi]
fannot_addr: sizet = field_annot_buf[fi]
fannot: str = None
if fannot_addr != 0:
fannot = (str)(t.CVoid(fannot_addr, t.CPtr))
+57 -57
View File
@@ -45,7 +45,7 @@ class ClassGenEnum(ClassGenBase.ClassGenBase):
k: int = ann_node.kind()
# Attribute 节点: t.State / int / t.CInt8T 等
# Attribute 节点: t.State / int / int8 等
if k == ast.ASTKind.Attribute:
at: ast.Attribute | t.CPtr = (ast.Attribute | t.CPtr)(ann_node)
if at.attr is None:
@@ -73,7 +73,7 @@ class ClassGenEnum(ClassGenBase.ClassGenBase):
return ty2
return llvmlite.Int32(pool)
# BinOp 节点: t.State | t.CInt8T(递归查找实际类型)
# BinOp 节点: t.State | int8(递归查找实际类型)
if k == ast.ASTKind.BinOp:
bop: ast.BinOp | t.CPtr = (ast.BinOp | t.CPtr)(ann_node)
if bop.op == ast.OpKind.BitOr:
@@ -117,7 +117,7 @@ class ClassGenEnum(ClassGenBase.ClassGenBase):
return 1
return 0
return 0
def _extract_int_value(self, node: ast.AST | t.CPtr) -> t.CInt64T:
def _extract_int_value(self, node: ast.AST | t.CPtr) -> int64:
"""从 AST 节点提取整数值,失败返回 0"""
if node is None:
return 0
@@ -130,7 +130,7 @@ class ClassGenEnum(ClassGenBase.ClassGenBase):
if k == ast.ASTKind.UnaryOp:
uo: ast.UnaryOp | t.CPtr = (ast.UnaryOp | t.CPtr)(node)
if uo.op == ast.OpKind.USub:
inner: t.CInt64T = self._extract_int_value(uo.operand)
inner: int64 = self._extract_int_value(uo.operand)
return -inner
return 0
return 0
@@ -153,12 +153,12 @@ class ClassGenEnum(ClassGenBase.ClassGenBase):
VLogger.warning(f"{class_name} has no body", "ENUM")
return 0
cn: t.CSizeT = len(children)
cn: sizet = len(children)
# 临时数组存储成员信息
member_names_buf: t.CSizeT | t.CPtr = pool.alloc(8 * ENUM_MEMBER_MAX_LOCAL)
member_types_buf: t.CSizeT | t.CPtr = pool.alloc(8 * ENUM_MEMBER_MAX_LOCAL)
member_values_buf: t.CInt64T | t.CPtr = pool.alloc(8 * ENUM_MEMBER_MAX_LOCAL)
member_names_buf: sizet | t.CPtr = pool.alloc(8 * ENUM_MEMBER_MAX_LOCAL)
member_types_buf: sizet | t.CPtr = pool.alloc(8 * ENUM_MEMBER_MAX_LOCAL)
member_values_buf: int64 | t.CPtr = pool.alloc(8 * ENUM_MEMBER_MAX_LOCAL)
if member_names_buf is None or member_types_buf is None or member_values_buf is None:
return 0
string.memset(member_names_buf, 0, 8 * ENUM_MEMBER_MAX_LOCAL)
@@ -166,7 +166,7 @@ class ClassGenEnum(ClassGenBase.ClassGenBase):
string.memset(member_values_buf, 0, 8 * ENUM_MEMBER_MAX_LOCAL)
member_count: int = 0
next_val: t.CInt64T = 0
next_val: int64 = 0
for ci in range(cn):
stmt: ast.AST | t.CPtr = children.get(ci)
@@ -192,7 +192,7 @@ class ClassGenEnum(ClassGenBase.ClassGenBase):
# 解析成员值
has_value: int = 0
cur_val: t.CInt64T = 0
cur_val: int64 = 0
if aa.value is not None:
cur_val = self._extract_int_value(aa.value)
has_value = 1
@@ -204,8 +204,8 @@ class ClassGenEnum(ClassGenBase.ClassGenBase):
# 存储
if member_count < ENUM_MEMBER_MAX_LOCAL:
member_names_buf[member_count] = t.CSizeT(tgt.id)
member_types_buf[member_count] = t.CSizeT(member_ty)
member_names_buf[member_count] = sizet(tgt.id)
member_types_buf[member_count] = sizet(member_ty)
member_values_buf[member_count] = cur_val
member_count += 1
@@ -216,7 +216,7 @@ class ClassGenEnum(ClassGenBase.ClassGenBase):
if ag is None or ag.targets is None:
continue
tgts: list[ast.AST | t.CPtr] | t.CPtr = ag.targets
tn: t.CSizeT = len(tgts)
tn: sizet = len(tgts)
if tn == 0:
continue
# 取第一个 target 作为成员名
@@ -231,7 +231,7 @@ class ClassGenEnum(ClassGenBase.ClassGenBase):
member_ty_a: llvmlite.LLVMType | t.CPtr = llvmlite.Int32(pool)
# 解析成员值
cur_val_a: t.CInt64T = 0
cur_val_a: int64 = 0
if ag.value is not None:
cur_val_a = self._extract_int_value(ag.value)
else:
@@ -242,8 +242,8 @@ class ClassGenEnum(ClassGenBase.ClassGenBase):
# 存储
if member_count < ENUM_MEMBER_MAX_LOCAL:
member_names_buf[member_count] = t.CSizeT(tgt_a.id)
member_types_buf[member_count] = t.CSizeT(member_ty_a)
member_names_buf[member_count] = sizet(tgt_a.id)
member_types_buf[member_count] = sizet(member_ty_a)
member_values_buf[member_count] = cur_val_a
member_count += 1
@@ -255,7 +255,7 @@ class ClassGenEnum(ClassGenBase.ClassGenBase):
base_ty: llvmlite.LLVMType | t.CPtr = llvmlite.Int32(pool)
max_bits: int = 0
for mi in range(member_count):
ty_addr: t.CSizeT = member_types_buf[mi]
ty_addr: sizet = member_types_buf[mi]
if ty_addr == 0:
continue
mty: llvmlite.LLVMType | t.CPtr = (llvmlite.LLVMType | t.CPtr)(
@@ -274,16 +274,16 @@ class ClassGenEnum(ClassGenBase.ClassGenBase):
# 添加成员
for mi in range(member_count):
fname_addr: t.CSizeT = member_names_buf[mi]
fname_addr: sizet = member_names_buf[mi]
if fname_addr == 0:
continue
mname: str = (str | t.CPtr)(t.CVoid(fname_addr, t.CPtr))
fty_addr2: t.CSizeT = member_types_buf[mi]
fty_addr2: sizet = member_types_buf[mi]
if fty_addr2 == 0:
continue
mty2: llvmlite.LLVMType | t.CPtr = (llvmlite.LLVMType | t.CPtr)(
t.CVoid(fty_addr2, t.CPtr))
mval: t.CInt64T = member_values_buf[mi]
mval: int64 = member_values_buf[mi]
if mname is not None and mty2 is not None:
self.Gen.StmtGenDecl.add_enum_member(pool, entry, mname, mval, mty2)
@@ -408,11 +408,11 @@ class ClassGenEnum(ClassGenBase.ClassGenBase):
VLogger.warning("{class_name} has no body", "UNION")
return 0
cn: t.CSizeT = len(children)
cn: sizet = len(children)
# 临时数组存储字段信息
field_names_buf: t.CSizeT | t.CPtr = pool.alloc(8 * GenTypes.FIELD_MAX)
field_types_buf: t.CSizeT | t.CPtr = pool.alloc(8 * GenTypes.FIELD_MAX)
field_names_buf: sizet | t.CPtr = pool.alloc(8 * GenTypes.FIELD_MAX)
field_types_buf: sizet | t.CPtr = pool.alloc(8 * GenTypes.FIELD_MAX)
if field_names_buf is None or field_types_buf is None:
return 0
string.memset(field_names_buf, 0, 8 * GenTypes.FIELD_MAX)
@@ -462,8 +462,8 @@ class ClassGenEnum(ClassGenBase.ClassGenBase):
# 存储到数组
if field_count < GenTypes.FIELD_MAX:
field_names_buf[field_count] = t.CSizeT(tgt.id)
field_types_buf[field_count] = t.CSizeT(field_ty)
field_names_buf[field_count] = sizet(tgt.id)
field_types_buf[field_count] = sizet(field_ty)
field_count += 1
if field_count == 0:
@@ -527,11 +527,11 @@ class ClassGenEnum(ClassGenBase.ClassGenBase):
# 添加字段信息(所有字段 Index=0,因为共享偏移 0)
for fi in range(field_count):
fname_addr: t.CSizeT = field_names_buf[fi]
fname_addr: sizet = field_names_buf[fi]
if fname_addr == 0:
continue
fname: str = (str | t.CPtr)(t.CVoid(fname_addr, t.CPtr))
fty_addr2: t.CSizeT = field_types_buf[fi]
fty_addr2: sizet = field_types_buf[fi]
if fty_addr2 == 0:
continue
fty2: llvmlite.LLVMType | t.CPtr = (llvmlite.LLVMType | t.CPtr)(
@@ -630,11 +630,11 @@ class ClassGenEnum(ClassGenBase.ClassGenBase):
VLogger.warning(f"{class_name} has no body", "RENUM")
return 0
cn: t.CSizeT = len(children)
cn: sizet = len(children)
# 变体最多 32 个,每个变体最多 16 个字段
# variant_field_sizes[i][j] = 变体 i 的第 j 个字段大小
variant_field_sizes: t.CSizeT | t.CPtr = pool.alloc(8 * 64 * 16)
variant_field_sizes: sizet | t.CPtr = pool.alloc(8 * 64 * 16)
if variant_field_sizes is None:
return 0
string.memset(variant_field_sizes, 0, 8 * 64 * 16)
@@ -655,7 +655,7 @@ class ClassGenEnum(ClassGenBase.ClassGenBase):
variant_count += 1
continue
variant_children: list[ast.AST | t.CPtr] | t.CPtr = variant_cd.children
vcn: t.CSizeT = len(variant_children)
vcn: sizet = len(variant_children)
field_idx: int = 0
for vi in range(vcn):
vstmt: ast.AST | t.CPtr = variant_children.get(vi)
@@ -675,8 +675,8 @@ class ClassGenEnum(ClassGenBase.ClassGenBase):
fsize: int = self._get_annotation_field_size(pool, vaa.annotation)
if variant_count < 32 and field_idx < 16:
# variant_field_sizes[variant_count][field_idx] = fsize
offset: t.CSizeT = variant_count * 16 + field_idx
variant_field_sizes[offset] = t.CSizeT(fsize)
offset: sizet = variant_count * 16 + field_idx
variant_field_sizes[offset] = sizet(fsize)
# 直接注册变体字段名别名(避免 CSizeT→str 转换问题)
# 同时解析成员实际类型(对齐 TPC class_members,供 match
# 绑定 bitcast 槽位地址用)。自引用注解(如
@@ -709,13 +709,13 @@ class ClassGenEnum(ClassGenBase.ClassGenBase):
if total_positions < 2:
total_positions = 2 # 至少 {i32, i32}
position_max_sizes: t.CSizeT | t.CPtr = pool.alloc(8 * total_positions)
position_max_sizes: sizet | t.CPtr = pool.alloc(8 * total_positions)
if position_max_sizes is None:
return 0
string.memset(position_max_sizes, 0, 8 * total_positions)
# 位置 0 = tag = 4 字节
position_max_sizes[0] = t.CSizeT(4)
position_max_sizes[0] = sizet(4)
# 位置 1+ = 每个位置取所有变体的最大字段大小
for pos in range(1, total_positions):
@@ -726,11 +726,11 @@ class ClassGenEnum(ClassGenBase.ClassGenBase):
field_pos: int = pos - 1 # 变体字段从位置 0 开始
if field_pos >= 16:
continue # 超出每变体 16 字段槽位:未写入(memset 为 0),跳过
offset2: t.CSizeT = vi * 16 + field_pos
fsize_val: t.CSizeT = variant_field_sizes[offset2]
offset2: sizet = vi * 16 + field_pos
fsize_val: sizet = variant_field_sizes[offset2]
if fsize_val > pos_max:
pos_max = fsize_val
position_max_sizes[pos] = t.CSizeT(pos_max)
position_max_sizes[pos] = sizet(pos_max)
# 构建 ParamNode 链表
i32_ty: llvmlite.LLVMType | t.CPtr = llvmlite.Int32(pool)
@@ -840,7 +840,7 @@ class ClassGenEnum(ClassGenBase.ClassGenBase):
children: list[ast.AST | t.CPtr] | t.CPtr = cd.children
if children is None:
return
cn: t.CSizeT = len(children)
cn: sizet = len(children)
for ci in range(cn):
stmt: ast.AST | t.CPtr = children.get(ci)
if stmt is None or stmt.kind() != ast.ASTKind.ClassDef:
@@ -850,7 +850,7 @@ class ClassGenEnum(ClassGenBase.ClassGenBase):
or variant_cd.children is None:
continue
vchildren: list[ast.AST | t.CPtr] | t.CPtr = variant_cd.children
vcn: t.CSizeT = len(vchildren)
vcn: sizet = len(vchildren)
field_idx: int = 0
for vi in range(vcn):
vstmt: ast.AST | t.CPtr = vchildren.get(vi)
@@ -912,7 +912,7 @@ class ClassGenEnum(ClassGenBase.ClassGenBase):
string.memset(self.RenumVariantTags, 0, 8 * RENUM_CLASS_MAX * RENUM_VARIANT_PER_CLASS)
self.RenumClassCount = 0
#rcv_chk: t.CUInt64T = t.CUInt64T(self.RenumClassVariantCounts)
#rcv_chk: uint64 = uint64(self.RenumClassVariantCounts)
#if rcv_chk == 0 or rcv_chk < 4096:
# VLogger.error(f"[RENUM-FAIL] RCV={rcv_chk} 异常(lazy init 后应为 perm_pool 地址),RenumClassCount={self.RenumClassCount} class={class_name}", "RENUM")
# stdlib.exit(1)
@@ -930,16 +930,16 @@ class ClassGenEnum(ClassGenBase.ClassGenBase):
# 注册类名(strcpy 到 perm_pool:1a 每文件 reset 后 AST 裸指针悬空,
# _lookup_renum_variant/_is_renum_class_name 的 strcmp 会读毒化内存)
idx: int = self.RenumClassCount
cn_len_rv: t.CSizeT = string.strlen(class_name)
cn_len_rv: sizet = string.strlen(class_name)
cn_buf_rv: str = CompilerFactory.factory.PermPool.alloc(cn_len_rv + 1)
if cn_buf_rv is None:
return
string.strcpy(cn_buf_rv, class_name)
self.RenumClassNames[idx] = t.CSizeT(cn_buf_rv)
self.RenumClassNames[idx] = sizet(cn_buf_rv)
self.RenumClassVariantCounts[idx] = variant_count
# 遍历 children,提取嵌套变体类名并注册
cn: t.CSizeT = len(children)
cn: sizet = len(children)
tag: int = 0
for ci in range(cn):
if tag >= variant_count:
@@ -956,14 +956,14 @@ class ClassGenEnum(ClassGenBase.ClassGenBase):
vcd: ast.ClassDef | t.CPtr = (ast.ClassDef | t.CPtr)(stmt)
if vcd is None or vcd.name is None:
continue
name_offset: t.CSizeT = idx * RENUM_VARIANT_PER_CLASS + tag
name_offset: sizet = idx * RENUM_VARIANT_PER_CLASS + tag
# 变体名同样 strcpy 到 perm_pool(1a 每文件 reset 后 vcd.name 悬空)
vn_len_rv: t.CSizeT = string.strlen(vcd.name)
vn_len_rv: sizet = string.strlen(vcd.name)
vn_buf_rv: str = CompilerFactory.factory.PermPool.alloc(vn_len_rv + 1)
if vn_buf_rv is None:
break
string.strcpy(vn_buf_rv, vcd.name)
self.RenumVariantNames[name_offset] = t.CSizeT(vn_buf_rv)
self.RenumVariantNames[name_offset] = sizet(vn_buf_rv)
self.RenumVariantTags[name_offset] = tag
tag += 1
@@ -979,7 +979,7 @@ class ClassGenEnum(ClassGenBase.ClassGenBase):
for i in range(self.RenumClassCount):
vcount: int = self.RenumClassVariantCounts[i]
for j in range(vcount):
name_offset: t.CSizeT = i * RENUM_VARIANT_PER_CLASS + j
name_offset: sizet = i * RENUM_VARIANT_PER_CLASS + j
vname: str = self.RenumVariantNames[name_offset]
if vname is not None and string.strcmp(vname, variant_name) == 0:
cls_nm: str = self.RenumClassNames[i]
@@ -1004,7 +1004,7 @@ class ClassGenEnum(ClassGenBase.ClassGenBase):
continue
vcount: int = self.RenumClassVariantCounts[i]
for j in range(vcount):
name_offset: t.CSizeT = i * RENUM_VARIANT_PER_CLASS + j
name_offset: sizet = i * RENUM_VARIANT_PER_CLASS + j
vname: str = self.RenumVariantNames[name_offset]
if vname is not None and string.strcmp(vname, variant_name) == 0:
return self.RenumVariantTags[name_offset]
@@ -1067,27 +1067,27 @@ class ClassGenEnum(ClassGenBase.ClassGenBase):
ty_copy_rf2: llvmlite.LLVMType | t.CPtr = llvmlite.DeepCopyType(
CompilerFactory.factory.PermPool, field_ty)
if ty_copy_rf2 is not None:
self.RenumAliasTy[i] = t.CSizeT(ty_copy_rf2)
self.RenumAliasTy[i] = sizet(ty_copy_rf2)
return
idx: int = self.RenumAliasCount
# class_name 同样 strcpy 到 perm_pool(去指针化:查找方任何来源的
# class_name 字符串都可用 strcmp 命中,无需 _update_renum_alias_class_ptr)
cls_len_rfa: t.CSizeT = string.strlen(class_name)
cls_len_rfa: sizet = string.strlen(class_name)
cls_buf_rfa: str = CompilerFactory.factory.PermPool.alloc(cls_len_rfa + 1)
if cls_buf_rfa is None:
return
string.strcpy(cls_buf_rfa, class_name)
self.RenumAliasClass[idx] = t.CSizeT(cls_buf_rfa)
self.RenumAliasClass[idx] = sizet(cls_buf_rfa)
# field_name 存 AST 裸指针,1a 每文件 reset 后悬空;_lookup_renum_field_alias
# 用 strcmp 内容比较 → strcpy 到 perm_pool 不影响查找。
fn_len_rfa: t.CSizeT = string.strlen(field_name)
fn_len_rfa: sizet = string.strlen(field_name)
fn_buf_rfa: str = CompilerFactory.factory.PermPool.alloc(fn_len_rfa + 1)
if fn_buf_rfa is None:
return
string.strcpy(fn_buf_rfa, field_name)
self.RenumAliasField[idx] = t.CSizeT(fn_buf_rfa)
self.RenumAliasIndex[idx] = t.CSizeT(payload_idx)
self.RenumAliasField[idx] = sizet(fn_buf_rfa)
self.RenumAliasIndex[idx] = sizet(payload_idx)
# 成员类型深拷贝到 perm_pool(1a 每文件 reset 后 pool 类型悬空;
# 未解析成功(自引用等)存 0,绑定回退槽位类型)
self.RenumAliasTy[idx] = 0
@@ -1095,15 +1095,15 @@ class ClassGenEnum(ClassGenBase.ClassGenBase):
ty_copy_rfa: llvmlite.LLVMType | t.CPtr = llvmlite.DeepCopyType(
CompilerFactory.factory.PermPool, field_ty)
if ty_copy_rfa is not None:
self.RenumAliasTy[idx] = t.CSizeT(ty_copy_rfa)
self.RenumAliasTy[idx] = sizet(ty_copy_rfa)
# 变体名同样 strcpy 到 perm_pool(1a reset 后 variant_cd.name 悬空)
self.RenumAliasVariant[idx] = 0
if variant_name is not None:
vn_len_rfa: t.CSizeT = string.strlen(variant_name)
vn_len_rfa: sizet = string.strlen(variant_name)
vn_buf_rfa: str = CompilerFactory.factory.PermPool.alloc(vn_len_rfa + 1)
if vn_buf_rfa is not None:
string.strcpy(vn_buf_rfa, variant_name)
self.RenumAliasVariant[idx] = t.CSizeT(vn_buf_rfa)
self.RenumAliasVariant[idx] = sizet(vn_buf_rfa)
self.RenumAliasCount = idx + 1
def _lookup_renum_field_alias(self, class_name: str, field_name: str) -> int:
"""查找 REnum 变体字段名的 payload 索引,返回索引或 -1
+46 -46
View File
@@ -69,8 +69,8 @@ class ClassGenGeneric(ClassGenBase.ClassGenBase):
string.memset(self.GenericClassTpParams, 0, GENERIC_TEMPLATE_MAX * 8)
# 用局部变量接收 list,触发类型推断(避免字段 __len__ 失败)
names_local: list[str] | t.CPtr = self.GenericClassNames
cn: t.CSizeT = len(names_local)
i: t.CSizeT
cn: sizet = len(names_local)
i: sizet
for i in range(cn):
nm: str = names_local.get(i)
if nm is not None and string.strcmp(nm, cd.name) == 0:
@@ -83,7 +83,7 @@ class ClassGenGeneric(ClassGenBase.ClassGenBase):
# 同时保存模板来源文件路径(错误定位用,见字段注释)
self.GenericClassFiles.append(self.Gen.TypeGenResolve.get_current_file())
if tp_names_buf is not None and cn < GENERIC_TEMPLATE_MAX:
self.GenericClassTpParams[cn] = t.CSizeT(tp_names_buf)
self.GenericClassTpParams[cn] = sizet(tp_names_buf)
def _copy_type_params_stdlib(self, tp: list[str] | t.CPtr) -> str:
"""将模板 type_params 深拷贝为空格分隔、NUL 结尾的 stdlib 缓冲区
@@ -94,12 +94,12 @@ class ClassGenGeneric(ClassGenBase.ClassGenBase):
"""
if tp is None:
return None
tp_n: t.CSizeT = len(tp)
tp_n: sizet = len(tp)
if tp_n == 0:
return None
# 计算总长:各名字长度 + (n-1) 个空格 + NUL
total: t.CSizeT = 1
ti: t.CSizeT
total: sizet = 1
ti: sizet
for ti in range(tp_n):
tp_name: str = tp.get(ti)
if tp_name is not None:
@@ -127,14 +127,14 @@ class ClassGenGeneric(ClassGenBase.ClassGenBase):
or self.GenericClassTpParams is None:
return None
names_local: list[str] | t.CPtr = self.GenericClassNames
cn: t.CSizeT = len(names_local)
i: t.CSizeT
cn: sizet = len(names_local)
i: sizet
for i in range(cn):
nm: str = names_local.get(i)
if nm is not None and string.strcmp(nm, class_name) == 0:
if i >= GENERIC_TEMPLATE_MAX:
return None
buf_addr: t.CSizeT = self.GenericClassTpParams[i]
buf_addr: sizet = self.GenericClassTpParams[i]
if buf_addr == 0:
return None
buf_tp: str = (str | t.CPtr)(t.CVoid(buf_addr, t.CPtr))
@@ -146,12 +146,12 @@ class ClassGenGeneric(ClassGenBase.ClassGenBase):
tp_list: list[str] | t.CPtr = list[str](pool, 8)
if tp_list is None:
return None
seg_start: t.CSizeT = 0
pos: t.CSizeT = 0
blen: t.CSizeT = string.strlen(buf_tp)
seg_start: sizet = 0
pos: sizet = 0
blen: sizet = string.strlen(buf_tp)
while pos <= blen:
if buf_tp[pos] == ' ' or buf_tp[pos] == '\0':
seg_len: t.CSizeT = pos - seg_start
seg_len: sizet = pos - seg_start
if seg_len > 0:
seg: str = pool.alloc(seg_len + 1)
if seg is not None:
@@ -169,8 +169,8 @@ class ClassGenGeneric(ClassGenBase.ClassGenBase):
# 用局部变量接收 list,触发类型推断(避免字段 __len__ 失败)
names_local: list[str] | t.CPtr = self.GenericClassNames
nodes_local: list[ast.ClassDef | t.CPtr] | t.CPtr = self.GenericClassNodes
cn: t.CSizeT = len(names_local)
i: t.CSizeT
cn: sizet = len(names_local)
i: sizet
for i in range(cn):
nm: str = names_local.get(i)
if nm is not None and string.strcmp(nm, class_name) == 0:
@@ -184,8 +184,8 @@ class ClassGenGeneric(ClassGenBase.ClassGenBase):
# 用局部变量接收 list,触发类型推断
names_local: list[str] | t.CPtr = self.GenericClassNames
sha1s_local: list[str] | t.CPtr = self.GenericClassSha1s
cn: t.CSizeT = len(names_local)
i: t.CSizeT
cn: sizet = len(names_local)
i: sizet
for i in range(cn):
nm: str = names_local.get(i)
if nm is not None and string.strcmp(nm, class_name) == 0:
@@ -202,8 +202,8 @@ class ClassGenGeneric(ClassGenBase.ClassGenBase):
return None
names_local: list[str] | t.CPtr = self.GenericClassNames
files_local: list[str] | t.CPtr = self.GenericClassFiles
cn: t.CSizeT = len(names_local)
i: t.CSizeT
cn: sizet = len(names_local)
i: sizet
for i in range(cn):
nm: str = names_local.get(i)
if nm is not None and string.strcmp(nm, class_name) == 0:
@@ -219,12 +219,12 @@ class ClassGenGeneric(ClassGenBase.ClassGenBase):
"""
if class_name is None or type_args is None or pool is None:
return class_name
n: t.CSizeT = len(type_args)
n: sizet = len(type_args)
if n == 0:
return class_name
# 计算总长度: class_name + "[" + arg0 + "," + arg1 + ... + "]" + NUL
total_len: t.CSizeT = string.strlen(class_name) + 2 # "[" 和 "]"
i: t.CSizeT
total_len: sizet = string.strlen(class_name) + 2 # "[" 和 "]"
i: sizet
for i in range(n):
if i > 0:
total_len += 1 # ","
@@ -264,8 +264,8 @@ class ClassGenGeneric(ClassGenBase.ClassGenBase):
if k == ast.ASTKind.Name:
nm: ast.Name | t.CPtr = (ast.Name | t.CPtr)(node)
if nm.id is not None:
n: t.CSizeT = len(tp_names) if tp_names is not None else 0
i: t.CSizeT
n: sizet = len(tp_names) if tp_names is not None else 0
i: sizet
for i in range(n):
tpn: str = tp_names.get(i)
if tpn is not None and string.strcmp(nm.id, tpn) == 0:
@@ -302,8 +302,8 @@ class ClassGenGeneric(ClassGenBase.ClassGenBase):
new_elts: list[ast.AST | t.CPtr] | t.CPtr = list[ast.AST | t.CPtr](pool, 8)
if tup.elts is not None:
tup_elts: list[ast.AST | t.CPtr] | t.CPtr = tup.elts
en: t.CSizeT = len(tup_elts)
ei: t.CSizeT
en: sizet = len(tup_elts)
ei: sizet
for ei in range(en):
el: ast.AST | t.CPtr = tup_elts.get(ei)
new_el: ast.AST | t.CPtr = self._clone_annotation(pool, el, tp_names, type_args)
@@ -333,8 +333,8 @@ class ClassGenGeneric(ClassGenBase.ClassGenBase):
new_arg_list: list[ast.AST | t.CPtr] | t.CPtr = list[ast.AST | t.CPtr](pool, 8)
if old_args.args is not None:
old_arg_list: list[ast.AST | t.CPtr] | t.CPtr = old_args.args
an: t.CSizeT = len(old_arg_list)
ai: t.CSizeT
an: sizet = len(old_arg_list)
ai: sizet
for ai in range(an):
arg_node: ast.AST | t.CPtr = old_arg_list.get(ai)
if arg_node is None:
@@ -366,8 +366,8 @@ class ClassGenGeneric(ClassGenBase.ClassGenBase):
# 拷贝 children
if cd.children is not None:
cd_children: list[ast.AST | t.CPtr] | t.CPtr = cd.children
cn: t.CSizeT = len(cd_children)
ci: t.CSizeT
cn: sizet = len(cd_children)
ci: sizet
for ci in range(cn):
child: ast.AST | t.CPtr = cd_children.get(ci)
if child is None:
@@ -391,8 +391,8 @@ class ClassGenGeneric(ClassGenBase.ClassGenBase):
# 方法体直接引用原始节点
if fd.children is not None:
fd_children: list[ast.AST | t.CPtr] | t.CPtr = fd.children
bcn: t.CSizeT = len(fd_children)
bci: t.CSizeT
bcn: sizet = len(fd_children)
bci: sizet
for bci in range(bcn):
body_stmt: ast.AST | t.CPtr = fd_children.get(bci)
if body_stmt is not None:
@@ -409,11 +409,11 @@ class ClassGenGeneric(ClassGenBase.ClassGenBase):
return None
i: int
for i in range(self.SpecCount):
key_addr: t.CSizeT = self.SpecKeys[i]
key_addr: sizet = self.SpecKeys[i]
if key_addr != 0:
k: str = (str | t.CPtr)(t.CVoid(key_addr, t.CPtr))
if k is not None and string.strcmp(k, spec_key) == 0:
name_addr: t.CSizeT = self.SpecNames[i]
name_addr: sizet = self.SpecNames[i]
if name_addr != 0:
return (str | t.CPtr)(t.CVoid(name_addr, t.CPtr))
return None
@@ -432,16 +432,16 @@ class ClassGenGeneric(ClassGenBase.ClassGenBase):
if self.SpecCount >= SPEC_CACHE_MAX:
return
# 深拷贝字符串到 stdlib 区
key_len: t.CSizeT = string.strlen(spec_key)
name_len: t.CSizeT = string.strlen(spec_name)
key_len: sizet = string.strlen(spec_key)
name_len: sizet = string.strlen(spec_name)
key_copy: str = CompilerFactory.factory.PermPool.alloc(key_len + 1)
name_copy: str = CompilerFactory.factory.PermPool.alloc(name_len + 1)
if key_copy is None or name_copy is None:
return
string.strcpy(key_copy, spec_key)
string.strcpy(name_copy, spec_name)
self.SpecKeys[self.SpecCount] = t.CSizeT(key_copy)
self.SpecNames[self.SpecCount] = t.CSizeT(name_copy)
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 | t.CPtr,
template_sha1: str) -> None:
@@ -455,8 +455,8 @@ class ClassGenGeneric(ClassGenBase.ClassGenBase):
if cur is None or cur[0] == '\0':
trans._imported_modules = tdeps
return
cur_len: t.CSizeT = string.strlen(cur)
td_len: t.CSizeT = string.strlen(tdeps)
cur_len: sizet = string.strlen(cur)
td_len: sizet = string.strlen(tdeps)
merged: str = trans.Pool.alloc(cur_len + td_len + 2)
if merged is None:
return
@@ -480,7 +480,7 @@ class ClassGenGeneric(ClassGenBase.ClassGenBase):
return 0
if string.strcmp(entry_rt.Name, spec_name) != 0:
return 0
ts_len_r: t.CSizeT = string.strlen(trigger_sha1)
ts_len_r: sizet = string.strlen(trigger_sha1)
ts_buf_r: str = CompilerFactory.factory.PermPool.alloc(ts_len_r + 1)
if ts_buf_r is None:
return 0
@@ -520,8 +520,8 @@ class ClassGenGeneric(ClassGenBase.ClassGenBase):
# 防御:泛型上下文内收集的 type_args 若残留未替换的类型参数名(如 "T"),
# 统一替换为具体类型名,避免 ndarray[T] 二次递归特化崩溃。
# 调用方传入的 type_args 均为临时新建列表,就地替换无共享副作用。
ta_cnt_g: t.CSizeT = len(type_args)
ta_i_g: t.CSizeT
ta_cnt_g: sizet = len(type_args)
ta_i_g: sizet
for ta_i_g in range(ta_cnt_g):
ta_raw_g: str = type_args.get(ta_i_g)
if ta_raw_g is not None:
@@ -595,9 +595,9 @@ class ClassGenGeneric(ClassGenBase.ClassGenBase):
# 3. 检查缓存(spec_key 包含所有类型实参,避免多参数泛型缓存冲突)
# 分配新缓冲区避免原地 strcat 溢出
sk_n: t.CSizeT = len(type_args)
sk_total: t.CSizeT = string.strlen(class_name) + 2 # "<" 和 ">"
sk_i: t.CSizeT
sk_n: sizet = len(type_args)
sk_total: sizet = string.strlen(class_name) + 2 # "<" 和 ">"
sk_i: sizet
for sk_i in range(sk_n):
if sk_i > 0:
sk_total += 1 # ","
+33 -33
View File
@@ -36,17 +36,17 @@ class ClassGenVTable(ClassGenBase.ClassGenBase):
# ============================================================
# _vtable_strcat — 将 src 追加到 dst 末尾
# ============================================================
def _vtable_strcat(self, dst: str, dst_size: t.CSizeT,
def _vtable_strcat(self, dst: str, dst_size: sizet,
src: str):
"""将 src 追加到 dst 末尾"""
if dst is None or src is None:
return
dlen: t.CSizeT = string.strlen(dst)
slen: t.CSizeT = string.strlen(src)
remain: t.CSizeT = dst_size - dlen
dlen: sizet = string.strlen(dst)
slen: sizet = string.strlen(src)
remain: sizet = dst_size - dlen
if remain <= 0:
return
i: t.CSizeT = 0
i: sizet = 0
while i < slen and i + 1 < remain:
dst[dlen + i] = src[i]
i += 1
@@ -71,7 +71,7 @@ class ClassGenVTable(ClassGenBase.ClassGenBase):
# 例如: void ({i32, i32}*, i32)
# ============================================================
def _format_func_type_str(self, pool: memhub.MemBuddy | t.CPtr,
buf: str, buf_size: t.CSizeT,
buf: str, buf_size: sizet,
func: llvmlite.Function | t.CPtr) -> int:
"""从 Function 对象生成函数类型字符串"""
if buf is None or func is None or buf_size == 0:
@@ -132,15 +132,15 @@ class ClassGenVTable(ClassGenBase.ClassGenBase):
children: list[ast.AST | t.CPtr] | t.CPtr = cd.children
if children is None:
return 0
cn: t.CSizeT = len(children)
cn: sizet = len(children)
# 1. 收集虚方法信息
# stdlib 分配:method_names_buf 存到 StructEntry.VTableMethods(跨文件永久存活),
# 必须迁出 mb 池 reset 区间,否则 1b 每文件 reset_to(mark1) 会回收导致悬空。
full_names_buf: t.CSizeT | t.CPtr = CompilerFactory.factory.PermPool.alloc(8 * VTBL_METHOD_MAX)
method_names_buf: t.CSizeT | t.CPtr = CompilerFactory.factory.PermPool.alloc(8 * VTBL_METHOD_MAX)
full_names_buf: sizet | t.CPtr = CompilerFactory.factory.PermPool.alloc(8 * VTBL_METHOD_MAX)
method_names_buf: sizet | t.CPtr = CompilerFactory.factory.PermPool.alloc(8 * VTBL_METHOD_MAX)
# 记录每个方法的父类 SHA1(非 0=继承方法用父模块 SHA1 mangling,0=当前类方法)
method_parent_sha1s: t.CSizeT | t.CPtr = CompilerFactory.factory.PermPool.alloc(8 * VTBL_METHOD_MAX)
method_parent_sha1s: sizet | t.CPtr = CompilerFactory.factory.PermPool.alloc(8 * VTBL_METHOD_MAX)
if full_names_buf is None or method_names_buf is None or method_parent_sha1s is None:
return 0
string.memset(full_names_buf, 0, 8 * VTBL_METHOD_MAX)
@@ -218,7 +218,7 @@ class ClassGenVTable(ClassGenBase.ClassGenBase):
else:
def_class = pname
# 多继承:沿 pname 的 MRO 祖先链探测实际定义类(跳过自身,先声明父类优先)
mro_ptr: t.CSizeT | t.CPtr = self.Gen.StructGen.get_mro_chain(pool, pname)
mro_ptr: sizet | t.CPtr = self.Gen.StructGen.get_mro_chain(pool, pname)
mro_i: int = 1
while mro_ptr is not None and mro_ptr[mro_i] != 0:
anc: str = (str | t.CPtr)(t.CVoid(mro_ptr[mro_i], t.CPtr))
@@ -233,13 +233,13 @@ class ClassGenVTable(ClassGenBase.ClassGenBase):
pfname_buf: str = CompilerFactory.factory.PermPool.alloc(128)
if pfname_buf is not None:
viperlib.snprintf(pfname_buf, 128, "%s.%s", def_class, pmethod_name)
full_names_buf[method_count] = t.CSizeT(pfname_buf)
full_names_buf[method_count] = sizet(pfname_buf)
# 复制方法名(短名)
pmname_len: t.CSizeT = string.strlen(pmethod_name)
pmname_len: sizet = string.strlen(pmethod_name)
pmname_buf: str = CompilerFactory.factory.PermPool.alloc(pmname_len + 1)
if pmname_buf is not None:
string.strcpy(pmname_buf, pmethod_name)
method_names_buf[method_count] = t.CSizeT(pmname_buf)
method_names_buf[method_count] = sizet(pmname_buf)
# 记录 mangling 用的 SHA1(继承未覆盖的方法用实际定义类的模块 SHA1)
if child_overrides == 1 and child_nvt == 0:
# 子类覆盖: 用当前模块 SHA1(保持 0)
@@ -249,7 +249,7 @@ class ClassGenVTable(ClassGenBase.ClassGenBase):
def_entry2: GenTypes.StructEntry | t.CPtr = self.Gen.StructGen.find_struct(
def_class)
if def_entry2 is not None and def_entry2.ModuleSha1 is not None:
method_parent_sha1s[method_count] = t.CSizeT(def_entry2.ModuleSha1)
method_parent_sha1s[method_count] = sizet(def_entry2.ModuleSha1)
else:
method_parent_sha1s[method_count] = 0
method_count += 1
@@ -281,7 +281,7 @@ class ClassGenVTable(ClassGenBase.ClassGenBase):
# 检查是否已从父类继承(避免重复)
already_in_vt: int = 0
for mi in range(method_count):
exist_addr: t.CSizeT = method_names_buf[mi]
exist_addr: sizet = method_names_buf[mi]
if exist_addr != 0:
exist_name: str = (str | t.CPtr)(t.CVoid(exist_addr, t.CPtr))
if exist_name is not None and string.strcmp(exist_name, mname) == 0:
@@ -295,14 +295,14 @@ class ClassGenVTable(ClassGenBase.ClassGenBase):
fname_buf: str = CompilerFactory.factory.PermPool.alloc(128)
if fname_buf is not None:
viperlib.snprintf(fname_buf, 128, "%s.%s", class_name, mname)
full_names_buf[method_count] = t.CSizeT(fname_buf)
full_names_buf[method_count] = sizet(fname_buf)
# 复制方法名
mname_len: t.CSizeT = string.strlen(mname)
mname_len: sizet = string.strlen(mname)
mname_buf: str = CompilerFactory.factory.PermPool.alloc(mname_len + 1)
if mname_buf is not None:
string.strcpy(mname_buf, mname)
method_names_buf[method_count] = t.CSizeT(mname_buf)
method_names_buf[method_count] = sizet(mname_buf)
method_count += 1
@@ -345,9 +345,9 @@ class ClassGenVTable(ClassGenBase.ClassGenBase):
# 同时设置 entry.VTableMethodCount/VTableMethods(虚分派查询用)
if self._collect_vtable_methods(trans, cd, class_name) == 0:
return 0
full_names_buf: t.CSizeT | t.CPtr = self.VtFullNames
method_names_buf: t.CSizeT | t.CPtr = self.VtMethodNames
method_parent_sha1s: t.CSizeT | t.CPtr = self.VtParentSha1s
full_names_buf: sizet | t.CPtr = self.VtFullNames
method_names_buf: sizet | t.CPtr = self.VtMethodNames
method_parent_sha1s: sizet | t.CPtr = self.VtParentSha1s
method_count: int = self.VtMethodCount
# 重新获取 entry(后续存储 VTableMethods 用)
vt_self_entry: GenTypes.StructEntry | t.CPtr = self.Gen.StructGen.find_struct_by_module(
@@ -384,7 +384,7 @@ class ClassGenVTable(ClassGenBase.ClassGenBase):
if i > 0:
self._vtable_strcat(init_buf, 16384, ", ")
full_name_addr: t.CSizeT = full_names_buf[i]
full_name_addr: sizet = full_names_buf[i]
if full_name_addr == 0:
self._vtable_strcat(init_buf, 16384, "i8* null")
continue
@@ -392,7 +392,7 @@ class ClassGenVTable(ClassGenBase.ClassGenBase):
full_name: str = (str | t.CPtr)(t.CVoid(full_name_addr, t.CPtr))
# 检查是否是继承方法(method_parent_sha1s 非 0 表示用父模块 SHA1 mangling)
parent_sha1_addr: t.CSizeT = method_parent_sha1s[i]
parent_sha1_addr: sizet = method_parent_sha1s[i]
if parent_sha1_addr != 0:
# 继承方法: 用父类模块 SHA1 做 mangling
parent_sha1: str = (str | t.CPtr)(t.CVoid(parent_sha1_addr, t.CPtr))
@@ -524,7 +524,7 @@ class ClassGenVTable(ClassGenBase.ClassGenBase):
if children is None:
return 0
cn: t.CSizeT = len(children)
cn: sizet = len(children)
has_method: int = 0
has_init: int = 0
has_new: int = 0
@@ -715,11 +715,11 @@ class ClassGenVTable(ClassGenBase.ClassGenBase):
viperlib.snprintf(method_name_buf, 128, "%s", fd.name)
if func_meta & GenTypes.META_PROP_SETTER != 0:
# 128 字节缓冲:追加 "$set" 前检查剩余容量,防 strcat 无界写穿
mn_len2: t.CSizeT = string.strlen(method_name_buf)
mn_len2: sizet = string.strlen(method_name_buf)
if mn_len2 + 5 < 128:
string.strcat(method_name_buf, "$set")
elif func_meta & GenTypes.META_PROP_DELETER != 0:
mn_len2: t.CSizeT = string.strlen(method_name_buf)
mn_len2: sizet = string.strlen(method_name_buf)
if mn_len2 + 5 < 128:
string.strcat(method_name_buf, "$del")
method_name = method_name_buf
@@ -774,7 +774,7 @@ class ClassGenVTable(ClassGenBase.ClassGenBase):
# @staticmethod 无 self,param_count 为完整参数数)
# 注意: 必须先把属性赋给显式类型为 list[...] | t.CPtr 的局部变量再调用 __len__(),
# 否则编译器无法识别属性返回的 list 类型,GEP base 会变成 i32 0 导致 llc 报错
md_defaults: t.CVoid | t.CPtr = None
md_defaults: t.CPtr = None
md_default_count: int = 0
md_param_count: int = 0
md_args_node: ast.Arguments | t.CPtr = fd.args
@@ -819,7 +819,7 @@ class ClassGenVTable(ClassGenBase.ClassGenBase):
ags: ast.Arguments | t.CPtr = (ast.Arguments | t.CPtr)(args_node)
if ags.args is not None:
alist: list[ast.AST | t.CPtr] | t.CPtr = ags.args
an: t.CSizeT = len(alist)
an: sizet = len(alist)
start_idx: int = 0
if is_static_m == 0:
start_idx = 1
@@ -963,7 +963,7 @@ class ClassGenVTable(ClassGenBase.ClassGenBase):
ags2: ast.Arguments | t.CPtr = (ast.Arguments | t.CPtr)(args_node)
if ags2.args is not None:
alist2: list[ast.AST | t.CPtr] | t.CPtr = ags2.args
an2: t.CSizeT = len(alist2)
an2: sizet = len(alist2)
start_idx2: int = 0
if is_static_m == 0:
start_idx2 = 1
@@ -1044,7 +1044,7 @@ class ClassGenVTable(ClassGenBase.ClassGenBase):
# (main.vp __init__ BootInfo memmap 全 0 根因)。
body: list[ast.AST | t.CPtr] | t.CPtr = fd.children
if body is not None:
bn: t.CSizeT = len(body)
bn: sizet = len(body)
for bi in range(bn):
stmt: ast.AST | t.CPtr = body.get(bi)
if stmt is not None:
@@ -1056,7 +1056,7 @@ class ClassGenVTable(ClassGenBase.ClassGenBase):
# 翻译方法体
if body is not None:
bn2: t.CSizeT = len(body)
bn2: sizet = len(body)
for bi2 in range(bn2):
stmt2: ast.AST | t.CPtr = body.get(bi2)
if stmt2 is not None:
@@ -1077,7 +1077,7 @@ class ClassGenVTable(ClassGenBase.ClassGenBase):
# FuncGenMixin 模块级函数路径,方法路径此处追加89 一并同步)
last_is_return: int = 0
# 追加89:bn3 提前初始化,避免 body is None 时下方引用未定义变量
bn3: t.CSizeT = 0
bn3: sizet = 0
if body is not None:
bn3 = len(body)
if bn3 > 0:
+17 -17
View File
@@ -40,7 +40,7 @@ class ExprGenAttr(ExprGenBase.ExprGenBase):
"""在模块全局变量链表中按名称查找全局变量"""
if mod is None or name is None:
return None
name_len: t.CSizeT = string.strlen(name)
name_len: sizet = string.strlen(name)
cur: llvmlite.GlobalVariable | t.CPtr = mod.GlobalHead
# 第一遍: 精确匹配
while cur is not None:
@@ -52,9 +52,9 @@ class ExprGenAttr(ExprGenBase.ExprGenBase):
cur = mod.GlobalHead
while cur is not None:
if cur.Name is not None:
cur_len: t.CSizeT = string.strlen(cur.Name)
cur_len: sizet = string.strlen(cur.Name)
if cur_len > name_len + 1:
suffix_start: t.CSizeT = cur_len - name_len
suffix_start: sizet = cur_len - name_len
if cur.Name[suffix_start - 1] == '.':
match: int = 1
for i in range(name_len):
@@ -205,8 +205,8 @@ class ExprGenAttr(ExprGenBase.ExprGenBase):
base_m: str = self._attr_module_path_str(pool, at_m.value)
if base_m is None:
return None
blen: t.CSizeT = string.strlen(base_m)
alen: t.CSizeT = string.strlen(at_m.attr)
blen: sizet = string.strlen(base_m)
alen: sizet = string.strlen(at_m.attr)
buf_m: str = pool.alloc(blen + alen + 2)
if buf_m is None:
return None
@@ -239,7 +239,7 @@ class ExprGenAttr(ExprGenBase.ExprGenBase):
orig_mw: str = self.Gen.ImportsGen.lookup_from_import(
trans._from_imports, mod_path_w, 0)
if orig_mw is not None:
oml_a: t.CSizeT = 0
oml_a: sizet = 0
while orig_mw[oml_a] != ' ' and orig_mw[oml_a] != '\0' and orig_mw[oml_a] != ':':
oml_a += 1
if oml_a > 0:
@@ -540,7 +540,7 @@ class ExprGenAttr(ExprGenBase.ExprGenBase):
if ma_is_var is None:
# 先检查是否是 CDefine 编译期常量 (如 ast.CONST_INT / win32base.INVALID_HANDLE_VALUE)
# 模块属性访问的 CDefine 常量需要跨模块查找源 .vp / .vpi 文件
cdef_ma_val: t.CInt64T = self.Gen.TypeGenCDef.lookup_cdefine_constant(at.attr)
cdef_ma_val: int64 = self.Gen.TypeGenCDef.lookup_cdefine_constant(at.attr)
cd_local: int = self.Gen.TypeGenCDef.is_cdefine_found()
if cd_local == 0:
# 确定真实模块名:优先从 _from_imports 解析别名
@@ -552,7 +552,7 @@ class ExprGenAttr(ExprGenBase.ExprGenBase):
trans._from_imports, nm_ma.id, 0)
if resolved_mod is not None:
# 复制模块名到新缓冲区(截断于空格、null、或 ':')
rm_len: t.CSizeT = 0
rm_len: sizet = 0
while resolved_mod[rm_len] != ' ' and resolved_mod[rm_len] != '\0' and resolved_mod[rm_len] != ':':
rm_len += 1
rm_buf: str = pool.alloc(rm_len + 1)
@@ -566,7 +566,7 @@ class ExprGenAttr(ExprGenBase.ExprGenBase):
# 误解析为全局变量引用 @CONST_INT(未定义符号)。
# 构建临时 from_imports "{attr}:{real_module}" 用于跨模块查找
if real_mod_name is not None:
ma_fi_len: t.CSizeT = string.strlen(at.attr) + string.strlen(real_mod_name) + 2
ma_fi_len: sizet = string.strlen(at.attr) + string.strlen(real_mod_name) + 2
ma_fi: str = pool.alloc(ma_fi_len)
if ma_fi is not None:
viperlib.snprintf(ma_fi, ma_fi_len, "%s:%s", at.attr, real_mod_name)
@@ -588,7 +588,7 @@ class ExprGenAttr(ExprGenBase.ExprGenBase):
# 如果是子模块,不应创建全局变量,让嵌套属性访问路径处理
is_submod: int = 0
if trans._imported_modules is not None:
submod_len: t.CSizeT = string.strlen(nm_ma.id) + string.strlen(at.attr) + 2
submod_len: sizet = string.strlen(nm_ma.id) + string.strlen(at.attr) + 2
submod_buf: str = pool.alloc(submod_len)
if submod_buf is not None:
viperlib.snprintf(submod_buf, submod_len, "%s.%s", nm_ma.id, at.attr)
@@ -600,7 +600,7 @@ class ExprGenAttr(ExprGenBase.ExprGenBase):
trans._from_imports, at.attr, 0)
if fi_mod_raw is not None:
# 复制模块名到新缓冲区(截断于空格、null、或 ':')
fm_len: t.CSizeT = 0
fm_len: sizet = 0
while fi_mod_raw[fm_len] != ' ' and fi_mod_raw[fm_len] != '\0' and fi_mod_raw[fm_len] != ':':
fm_len += 1
fi_mod: str = pool.alloc(fm_len + 1)
@@ -609,8 +609,8 @@ class ExprGenAttr(ExprGenBase.ExprGenBase):
fi_mod[fm_i] = fi_mod_raw[fm_i]
fi_mod[fm_len] = '\0'
# 检查 fi_mod 是否以 "nm_ma.id." 开头 (如 w32.win32file 以 w32. 开头)
prefix_len: t.CSizeT = string.strlen(nm_ma.id)
fi_mod_len: t.CSizeT = string.strlen(fi_mod)
prefix_len: sizet = string.strlen(nm_ma.id)
fi_mod_len: sizet = string.strlen(fi_mod)
if fi_mod_len > prefix_len + 1:
match_prefix: int = 1
for pi in range(prefix_len):
@@ -627,7 +627,7 @@ class ExprGenAttr(ExprGenBase.ExprGenBase):
if string.strcmp(nm_ma.id, "t") == 0 and string.strcmp(at.attr, "ASM_DESCR") == 0:
return None
# ALL_CAPS 模块属性但非 CDefine:先检查模块是否定义了同名全局
# 变量(如 Phase1.PYI_BUF_SIZE: t.CSizeT = 262144 是 i64 全局、
# 变量(如 Phase1.PYI_BUF_SIZE: sizet = 262144 是 i64 全局、
# 非宏,语义同 C 的 extern size_t PYI_BUF_SIZE)→ 按跨模块全局
# 引用加载。仅当全局变量也不存在时才 fail-fast(防 llc
# "use of undefined value")。
@@ -664,7 +664,7 @@ class ExprGenAttr(ExprGenBase.ExprGenBase):
if inner_nm.id is not None and inner_at.attr is not None:
if self.Gen.VarGen.lookup_var(trans.SymTab, inner_nm.id) is None:
# 构建限定模块名: "w32.win32file"
qual_len: t.CSizeT = string.strlen(inner_nm.id) + string.strlen(inner_at.attr) + 2
qual_len: sizet = string.strlen(inner_nm.id) + string.strlen(inner_at.attr) + 2
qual_buf: str = pool.alloc(qual_len)
if qual_buf is not None:
viperlib.snprintf(qual_buf, qual_len, "%s.%s", inner_nm.id, inner_at.attr)
@@ -707,10 +707,10 @@ class ExprGenAttr(ExprGenBase.ExprGenBase):
# 未找到全局: 尝试 CDefine 常量查找
# 对于 w32.win32base.INVALID_HANDLE_VALUE 等嵌套模块属性访问,
# 先从限定模块的 .vpi 文件中查找 CDefine 常量值并内联
cdef_val_nested: t.CInt64T = self.Gen.TypeGenCDef.lookup_cdefine_constant(at.attr)
cdef_val_nested: int64 = self.Gen.TypeGenCDef.lookup_cdefine_constant(at.attr)
if self.Gen.TypeGenCDef.is_cdefine_found() == 0:
# 构建临时 from_imports "attr:module" 用于跨模块查找
tmp_fi_len: t.CSizeT = string.strlen(at.attr) + string.strlen(qual_buf) + 2
tmp_fi_len: sizet = string.strlen(at.attr) + string.strlen(qual_buf) + 2
tmp_fi: str = pool.alloc(tmp_fi_len)
if tmp_fi is not None:
viperlib.snprintf(tmp_fi, tmp_fi_len, "%s:%s", at.attr, qual_buf)
+8 -8
View File
@@ -61,18 +61,18 @@ class ExprGenBase:
"""将字符串转换为 LLVM IR 字符串字面量 c"...\\00" """
if src is None:
return None
slen: t.CSizeT = string.strlen(src)
alloc_size: t.CSizeT = 4 * slen + 8
slen: sizet = string.strlen(src)
alloc_size: sizet = 4 * slen + 8
buf: str = pool.alloc(alloc_size)
if buf is None:
return None
pos: t.CSizeT = 0
pos: sizet = 0
buf[pos] = 'c'
pos += 1
buf[pos] = '"'
pos += 1
for i in range(slen):
ch: t.CChar = src[i]
ch: char = src[i]
if ch == '\0':
break
if ch == '\"' or ch == '\\' or ch < 0x20:
@@ -436,7 +436,7 @@ class ExprGenBase:
if val_bits < target_bits:
# 统一 zext/sext(问题2修正):i1/i8 默认 zext;AST 节点解析为
# 无符号类型(t.CUIntXXT 强转/无符号类型名)走 zext;否则 sext。
# 此前一律 sext(i1 除外)→ t.CUInt32T 等无符号值赋值/传参被符号
# 此前一律 sext(i1 除外)→ uint32 等无符号值赋值/传参被符号
# 扩展(高位置 1,如 0xFFFFFFFF 变 0xFFFFFFFFFFFFFFFF),与比较路径
# should_zext_widen(i8 默认 zext)规则相反 → 隐蔽数据损坏。
# trans 必须下传:_node_type_unsigned 对 Name/Subscript 形态需经
@@ -451,9 +451,9 @@ class ExprGenBase:
# 2^bits 语义放行(-1 → 0xFF 合法);非常量运行时窄化保留 trunc
# (值域可能安全,无法静态判定)。
if val.IsConst == 1 and val.IntVal > 0:
target_max_u: t.CUInt64T = (t.CUInt64T(1) << target_bits) - 1
if t.CUInt64T(val.IntVal) > target_max_u:
max_print: t.CInt64T = t.CInt64T(target_max_u)
target_max_u: uint64 = (uint64(1) << target_bits) - 1
if uint64(val.IntVal) > target_max_u:
max_print: int64 = int64(target_max_u)
self.Gen.TypeGenErr.fatal_error(
node,
f"窄化截断溢出:常量 {val.IntVal} 超出目标类型 {target_bits} 位范围 [0, {max_print}],赋值将被静默截断",
+93 -93
View File
@@ -57,7 +57,7 @@ class ExprGenCdef(ExprGenBase.ExprGenBase):
# 遍历查找匹配的 SHA1
idx_s: int = -1
for i in range(count):
sidx: t.CSizeT = t.CSizeT(i) * 17
sidx: sizet = sizet(i) * 17
cur_sha1: str = sha1_arr_ptr + sidx
if cur_sha1[0] == '\0':
continue
@@ -67,8 +67,8 @@ class ExprGenCdef(ExprGenBase.ExprGenBase):
if idx_s < 0:
return None
# 获取相对路径(MAX_REL_PATH_LEN=256,避免跨模块 CDefine 解析问题)
MAX_RPL: t.CSizeT = 256
ridx: t.CSizeT = t.CSizeT(idx_s) * MAX_RPL
MAX_RPL: sizet = 256
ridx: sizet = sizet(idx_s) * MAX_RPL
rel_path: str = rel_arr_ptr + ridx
if rel_path[0] == '\0':
return None
@@ -87,7 +87,7 @@ class ExprGenCdef(ExprGenBase.ExprGenBase):
rel_used: str = rel_path
inc_arr_ptr: bytes = StubMergerStore.GetSha1StoreIncdirArrPtr()
if inc_arr_ptr is not None:
iidx: t.CSizeT = t.CSizeT(idx_s) * StubMerger.MAX_INC_DIR_LEN
iidx: sizet = sizet(idx_s) * StubMerger.MAX_INC_DIR_LEN
inc_dir: str = inc_arr_ptr + iidx
if inc_dir[0] != '\0':
base_dir = inc_dir
@@ -106,9 +106,9 @@ class ExprGenCdef(ExprGenBase.ExprGenBase):
if base_dir is None:
base_dir = Config.SourceDir if Config.SourceDir is not None else Config.IncludesDir
# 构建完整路径: {base_dir}/{rel_used}
base_len: t.CSizeT = string.strlen(base_dir)
rel_len: t.CSizeT = string.strlen(rel_used)
path_len: t.CSizeT = base_len + rel_len + 2
base_len: sizet = string.strlen(base_dir)
rel_len: sizet = string.strlen(rel_used)
path_len: sizet = base_len + rel_len + 2
buf: str = stdlib.malloc(path_len)
if buf is None:
return None
@@ -119,8 +119,8 @@ class ExprGenCdef(ExprGenBase.ExprGenBase):
pf_chk.close()
if Config.IncludesDir is not None and base_dir != Config.IncludesDir:
stdlib.free(buf)
base_len2: t.CSizeT = string.strlen(Config.IncludesDir)
path_len2: t.CSizeT = base_len2 + rel_len + 2
base_len2: sizet = string.strlen(Config.IncludesDir)
path_len2: sizet = base_len2 + rel_len + 2
buf = stdlib.malloc(path_len2)
if buf is None:
return None
@@ -151,7 +151,7 @@ class ExprGenCdef(ExprGenBase.ExprGenBase):
from_imports: str,
imported_modules: str = None,
depth: int = 0,
node: ast.AST | t.CPtr = None) -> t.CInt64T:
node: ast.AST | t.CPtr = None) -> int64:
"""跨模块查找 CDefine 常量,返回值(64 位)或 -1(未找到)
查找顺序:
@@ -203,13 +203,13 @@ class ExprGenCdef(ExprGenBase.ExprGenBase):
# 与 _lookup_sha1_from_modname_raw 的截断逻辑一致(空格/冒号/NUL 分隔)。
base_mod: str = None
if mod_name_raw is not None:
mbl: t.CSizeT = 0
mbl: sizet = 0
while mod_name_raw[mbl] != ' ' and mod_name_raw[mbl] != '\0' \
and mod_name_raw[mbl] != ':':
mbl += 1
mb_buf: str = pool.alloc(mbl + 1)
if mb_buf is not None:
mi2: t.CSizeT
mi2: sizet
for mi2 in range(mbl):
mb_buf[mi2] = mod_name_raw[mi2]
mb_buf[mbl] = '\0'
@@ -226,7 +226,7 @@ class ExprGenCdef(ExprGenBase.ExprGenBase):
# 仅 ALL_CAPS 全局唯一宏名才进入本函数(_is_cdefine_name_pattern 已过滤)。
xkey_buf: str = None
if base_mod is not None:
xk_len: t.CSizeT = string.strlen(name) + string.strlen(base_mod) + 2
xk_len: sizet = string.strlen(name) + string.strlen(base_mod) + 2
xkey_buf = pool.alloc(xk_len)
if xkey_buf is not None:
viperlib.snprintf(xkey_buf, xk_len, "%s@%s", name, base_mod)
@@ -238,7 +238,7 @@ class ExprGenCdef(ExprGenBase.ExprGenBase):
xd_v: double = string.atof(xval)
self.Gen.TypeGenCDef.register_cdefine_double(pool, name, xd_v)
else:
xv_i: t.CInt64T = string.atoll(xval)
xv_i: int64 = string.atoll(xval)
self.Gen.TypeGenCDef.register_cdefine_constant(pool, name, xv_i)
return string.atoll(xval)
@@ -254,22 +254,22 @@ class ExprGenCdef(ExprGenBase.ExprGenBase):
# 设置 result_found=0 跳过步骤 3-9,直接到 9.6
self.Gen.TypeGenCDef.set_cdefine_found(0)
# 直接遍历 imported_modules
im_len: t.CSizeT = string.strlen(imported_modules)
im_ci: t.CSizeT = 0
im_len: sizet = string.strlen(imported_modules)
im_ci: sizet = 0
while im_ci < im_len:
while im_ci < im_len and imported_modules[im_ci] == ' ':
im_ci += 1
if im_ci >= im_len:
break
im_start: t.CSizeT = im_ci
im_start: sizet = im_ci
while im_ci < im_len and imported_modules[im_ci] != ' ':
im_ci += 1
im_end: t.CSizeT = im_ci
im_nlen: t.CSizeT = im_end - im_start
im_end: sizet = im_ci
im_nlen: sizet = im_end - im_start
if im_nlen > 0 and im_nlen < 256:
im_buf: str = pool.alloc(im_nlen + 1)
if im_buf is not None:
mk: t.CSizeT = 0
mk: sizet = 0
while mk < im_nlen:
im_buf[mk] = imported_modules[im_start + mk]
mk += 1
@@ -278,12 +278,12 @@ class ExprGenCdef(ExprGenBase.ExprGenBase):
if sub_fi is not None:
sub_fi[0] = '*'
sub_fi[1] = ':'
mk2: t.CSizeT = 0
mk2: sizet = 0
while mk2 < im_nlen:
sub_fi[2 + mk2] = im_buf[mk2]
mk2 += 1
sub_fi[2 + im_nlen] = '\0'
sub_val: t.CInt64T = self._lookup_cross_module_cdefine(pool, name, sub_fi, None, depth + 1, node)
sub_val: int64 = self._lookup_cross_module_cdefine(pool, name, sub_fi, None, depth + 1, node)
if self.Gen.TypeGenCDef.is_cdefine_found() != 0:
return sub_val
return -1
@@ -299,13 +299,13 @@ class ExprGenCdef(ExprGenBase.ExprGenBase):
return -1
# 6. 构建 vpi 文件路径
td_len: t.CSizeT = string.strlen(temp_dir)
td_len: sizet = string.strlen(temp_dir)
pyi_path: str = StubMergerCollect._sliced_path(temp_dir, td_len, sha1, "vpi")
if pyi_path is None:
return -1
# 7. 读取 vpi 文件;若不存在或内容过短(空 stub)则回退读取源 .vp/.py 文件
PYI_READ_BUF_SIZE: t.CSizeT = 65536
PYI_READ_BUF_SIZE: sizet = 65536
pyi_buf: bytes = stdlib.malloc(PYI_READ_BUF_SIZE)
if pyi_buf is None:
stdlib.free(pyi_path)
@@ -337,9 +337,9 @@ class ExprGenCdef(ExprGenBase.ExprGenBase):
# 一律回退读源文件。
cd_sig: int = 0
name_has_val: int = 0
cs_name_len: t.CSizeT = string.strlen(name)
cs_total: t.CSizeT = string.strlen(pyi_buf)
cs_i: t.CSizeT = 0
cs_name_len: sizet = string.strlen(name)
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
@@ -348,7 +348,7 @@ class ExprGenCdef(ExprGenBase.ExprGenBase):
pyi_buf[cs_i + 8] == 'e'):
# 检查该行剩余部分是否有 '='(带值声明才在 vpi 中匹配)
cd_eq: int = 0
cs_j: t.CSizeT = cs_i + 9
cs_j: sizet = cs_i + 9
while cs_j < cs_total and pyi_buf[cs_j] != '\n':
if pyi_buf[cs_j] == '=':
cd_eq = 1
@@ -357,7 +357,7 @@ class ExprGenCdef(ExprGenBase.ExprGenBase):
if cd_eq != 0:
cd_sig = 1
# 定位该行行首,检查是否以 "name:" 开头(目标名带值)
cs_line_start: t.CSizeT = cs_i
cs_line_start: sizet = cs_i
while cs_line_start > 0 and pyi_buf[cs_line_start - 1] != '\n':
cs_line_start -= 1
if cs_i - cs_line_start >= cs_name_len + 1:
@@ -403,20 +403,20 @@ class ExprGenCdef(ExprGenBase.ExprGenBase):
# 8. 在 pyi_buf 中查找 "name: t.CDefine = value" 行
# 格式: NAME: t.CDefine = value
name_len: t.CSizeT = string.strlen(name)
total_len: t.CSizeT = string.strlen(pyi_buf)
pos: t.CSizeT = 0
result_val: t.CInt64T = 0
name_len: sizet = string.strlen(name)
total_len: sizet = string.strlen(pyi_buf)
pos: sizet = 0
result_val: int64 = 0
result_found: int = 0
res_is_double: int = 0
res_is_str: int = 0
while pos < total_len:
# 找到行首
line_start: t.CSizeT = pos
line_start: sizet = pos
# 找到行尾
while pos < total_len and pyi_buf[pos] != '\n':
pos += 1
line_len: t.CSizeT = pos - line_start
line_len: sizet = pos - line_start
if pos < total_len:
pos += 1 # 跳过 '\n'
@@ -436,7 +436,7 @@ class ExprGenCdef(ExprGenBase.ExprGenBase):
# 检查行是否包含 "t.CDefine"
# 在行中查找 "t.CDefine"
has_cdefine: int = 0
ci: t.CSizeT = line_start + name_len + 1
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
@@ -450,7 +450,7 @@ class ExprGenCdef(ExprGenBase.ExprGenBase):
continue
# 找到 "=" 后面的值
eq_pos: t.CSizeT = line_start + name_len + 1
eq_pos: sizet = line_start + name_len + 1
while eq_pos < line_start + line_len and pyi_buf[eq_pos] != '=':
eq_pos += 1
if eq_pos >= line_start + line_len:
@@ -461,14 +461,14 @@ class ExprGenCdef(ExprGenBase.ExprGenBase):
while eq_pos < line_start + line_len and pyi_buf[eq_pos] == ' ':
eq_pos += 1
# 检查是否是 t.CUnsignedLong(...) / t.CLong(...) / t.CInt(...) 等类型构造函数
# 检查是否是 t.CUnsignedLong(...) / t.CLong(...) / int(...) 等类型构造函数
# 格式: t.CUnsignedLong(-11) / t.CUnsignedLong(0xFFFFFFFF)
# 如果是,跳过 "t.CXxx(" 前缀,解析括号内的值,忽略结尾 ')'
is_type_ctor: int = 0
if eq_pos + 2 < line_start + line_len:
if pyi_buf[eq_pos] == 't' and pyi_buf[eq_pos + 1] == '.':
# 找到 '(' 的位置
paren_pos: t.CSizeT = eq_pos + 2
paren_pos: sizet = eq_pos + 2
while paren_pos < line_start + line_len and pyi_buf[paren_pos] != '(':
paren_pos += 1
if paren_pos < line_start + line_len and pyi_buf[paren_pos] == '(':
@@ -492,8 +492,8 @@ class ExprGenCdef(ExprGenBase.ExprGenBase):
if eq_pos < line_start + line_len and pyi_buf[eq_pos] == '-':
is_neg = 1
eq_pos += 1
val_str_start: t.CSizeT = eq_pos
val_str_len: t.CSizeT = 0
val_str_start: sizet = eq_pos
val_str_len: sizet = 0
is_hex: int = 0
is_float_val: int = 0
is_name_val: int = 0
@@ -520,7 +520,7 @@ class ExprGenCdef(ExprGenBase.ExprGenBase):
pyi_buf[eq_pos] == '_':
is_name_val = 1
while eq_pos < line_start + line_len:
c_tk: t.CChar = pyi_buf[eq_pos]
c_tk: char = pyi_buf[eq_pos]
if (c_tk >= 'A' and c_tk <= 'Z') or (c_tk >= 'a' and c_tk <= 'z') or \
(c_tk >= '0' and c_tk <= '9') or c_tk == '_':
val_str_len += 1
@@ -529,7 +529,7 @@ class ExprGenCdef(ExprGenBase.ExprGenBase):
break
# 数字/hex 字符续读(字符串值已整体读取,跳过)
while eq_pos < line_start + line_len and is_name_val == 0 and is_str_val == 0:
ch: t.CChar = pyi_buf[eq_pos]
ch: char = pyi_buf[eq_pos]
if is_hex == 1:
if ((ch >= '0' and ch <= '9') or
(ch >= 'a' and ch <= 'f') or
@@ -562,7 +562,7 @@ class ExprGenCdef(ExprGenBase.ExprGenBase):
val_buf[val_str_len] = '\0'
# 左 token 求值
lval: t.CInt64T = 0
lval: int64 = 0
l_is_double: int = 0
ldbl: double = 0.0
if is_str_val != 0:
@@ -588,10 +588,10 @@ class ExprGenCdef(ExprGenBase.ExprGenBase):
elif is_hex == 1:
# 手动解析十六进制(跳过 0x 前缀)——64 位累加,
# 0xFFFFFFFF=4294967295 保持全精度(常量生成端 i32 截断回 -1)
hex_result: t.CInt64T = 0
hex_result: int64 = 0
hex_buf: str = val_buf + 2 # 跳过 "0x"
for hi in range(val_str_len - 2):
hc: t.CChar = hex_buf[hi]
hc: char = hex_buf[hi]
hd: int = 0
if hc >= '0' and hc <= '9':
hd = hc - '0'
@@ -658,8 +658,8 @@ class ExprGenCdef(ExprGenBase.ExprGenBase):
if eq_pos < line_start + line_len and pyi_buf[eq_pos] == '-':
r_neg = 1
eq_pos += 1
r_start: t.CSizeT = eq_pos
r_len: t.CSizeT = 0
r_start: sizet = eq_pos
r_len: sizet = 0
r_hex: int = 0
r_name: int = 0
if eq_pos + 1 < line_start + line_len:
@@ -672,7 +672,7 @@ class ExprGenCdef(ExprGenBase.ExprGenBase):
pyi_buf[eq_pos] == '_':
r_name = 1
while eq_pos < line_start + line_len:
c_r: t.CChar = pyi_buf[eq_pos]
c_r: char = pyi_buf[eq_pos]
if (c_r >= 'A' and c_r <= 'Z') or (c_r >= 'a' and c_r <= 'z') or \
(c_r >= '0' and c_r <= '9') or c_r == '_':
r_len += 1
@@ -680,7 +680,7 @@ class ExprGenCdef(ExprGenBase.ExprGenBase):
else:
break
while eq_pos < line_start + line_len and r_name == 0:
c_r2: t.CChar = pyi_buf[eq_pos]
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
@@ -704,7 +704,7 @@ class ExprGenCdef(ExprGenBase.ExprGenBase):
for r_i in range(r_len):
r_buf[r_i] = pyi_buf[r_start + r_i]
r_buf[r_len] = '\0'
rval: t.CInt64T = 0
rval: int64 = 0
if r_name != 0:
# True/False 布尔字面量 → 1/0
if string.strcmp(r_buf, "True") == 0:
@@ -717,10 +717,10 @@ class ExprGenCdef(ExprGenBase.ExprGenBase):
# 名称未注册:无法求值,跳过该行
continue
elif r_hex != 0:
rhex_v: t.CInt64T = 0
rhex_v: int64 = 0
rh_buf: str = r_buf + 2
for rh_i in range(r_len - 2):
rc: t.CChar = rh_buf[rh_i]
rc: char = rh_buf[rh_i]
rd: int = 0
if rc >= '0' and rc <= '9':
rd = rc - '0'
@@ -786,15 +786,15 @@ class ExprGenCdef(ExprGenBase.ExprGenBase):
if result_found == 0:
# base_mod 已在函数开头计算(mod_name_raw 去前导点),
# 供子模块递归构建 "base_mod.X" 全名。
name_len_rc: t.CSizeT = string.strlen(name)
rc_pos: t.CSizeT = 0
name_len_rc: sizet = string.strlen(name)
rc_pos: sizet = 0
while rc_pos < total_len and result_found == 0:
# 找到行首
rc_line_start: t.CSizeT = rc_pos
rc_line_start: sizet = rc_pos
# 找到行尾
while rc_pos < total_len and pyi_buf[rc_pos] != '\n':
rc_pos += 1
rc_line_len: t.CSizeT = rc_pos - rc_line_start
rc_line_len: sizet = rc_pos - rc_line_start
if rc_pos < total_len:
rc_pos += 1
@@ -815,22 +815,22 @@ class ExprGenCdef(ExprGenBase.ExprGenBase):
# 重导出 QT_ALIGN_* 等)里的 CDefine 全部查不到 →
# "跨模块 CDefine 未找到: 'vqt6.QT_ALIGN_CENTER'"。
rc_is_rel: int = 0
rc_sub_start: t.CSizeT = rc_line_start + 5
rc_sub_start: sizet = rc_line_start + 5
while rc_sub_start < rc_line_start + rc_line_len and \
pyi_buf[rc_sub_start] == '.':
rc_is_rel = 1
rc_sub_start += 1
rc_sub_end: t.CSizeT = rc_sub_start
rc_sub_end: sizet = rc_sub_start
while rc_sub_end < rc_line_start + rc_line_len and \
pyi_buf[rc_sub_end] != ' ' and pyi_buf[rc_sub_end] != '\t':
rc_sub_end += 1
rc_sub_len: t.CSizeT = rc_sub_end - rc_sub_start
rc_sub_len: sizet = rc_sub_end - rc_sub_start
if rc_sub_len == 0:
continue
# 检查行是否包含 "import"
rc_has_import: int = 0
rc_ipos: t.CSizeT = rc_sub_end
rc_ipos: sizet = rc_sub_end
while rc_ipos + 6 <= rc_line_start + rc_line_len:
if pyi_buf[rc_ipos] == 'i' and pyi_buf[rc_ipos+1] == 'm' and \
pyi_buf[rc_ipos+2] == 'p' and pyi_buf[rc_ipos+3] == 'o' and \
@@ -844,14 +844,14 @@ class ExprGenCdef(ExprGenBase.ExprGenBase):
# 检查 NAME 是否在导入列表中,或导入是 *
# 处理多行导入:from .X import (... NAME, ...)
# 从 "import" 之后扫描,如果有 "(" 则扫描到 ")" 为止
rc_imp_start: t.CSizeT = rc_ipos + 6
rc_imp_start: sizet = rc_ipos + 6
rc_star: int = 0
rc_name_match: int = 0
# 确定扫描范围:单行或跨行(括号内)
rc_scan_end: t.CSizeT = rc_line_start + rc_line_len
rc_scan_end: sizet = rc_line_start + rc_line_len
rc_has_paren: int = 0
rc_pp: t.CSizeT = rc_imp_start
rc_pp: sizet = rc_imp_start
while rc_pp < rc_line_start + rc_line_len:
if pyi_buf[rc_pp] == '(':
rc_has_paren = 1
@@ -863,7 +863,7 @@ class ExprGenCdef(ExprGenBase.ExprGenBase):
# 多行导入:从 "(" 之后扫描到 ")" 为止
rc_scan_end = rc_pp + 1
rc_paren_closed: int = 0
rc_sp: t.CSizeT = rc_pp + 1
rc_sp: sizet = rc_pp + 1
while rc_sp < total_len and rc_paren_closed == 0:
if pyi_buf[rc_sp] == ')':
rc_paren_closed = 1
@@ -874,15 +874,15 @@ class ExprGenCdef(ExprGenBase.ExprGenBase):
rc_scan_end = total_len
# 在 rc_imp_start 到 rc_scan_end 范围内查找 NAME 和 *
rc_cpos: t.CSizeT = rc_imp_start
rc_cpos: sizet = rc_imp_start
while rc_cpos < rc_scan_end:
rc_ch: t.CChar = pyi_buf[rc_cpos]
rc_ch: char = pyi_buf[rc_cpos]
if rc_ch == '*':
rc_star = 1
# 检查 NAME 是否匹配(作为完整单词)
if rc_cpos + name_len_rc <= rc_scan_end:
rc_match: int = 1
rc_ki: t.CSizeT
rc_ki: sizet
for rc_ki in range(name_len_rc):
if pyi_buf[rc_cpos + rc_ki] != name[rc_ki]:
rc_match = 0
@@ -893,18 +893,18 @@ class ExprGenCdef(ExprGenBase.ExprGenBase):
if rc_cpos == rc_imp_start:
rc_before_ok = 1
else:
rc_before_ch: t.CChar = pyi_buf[rc_cpos - 1]
rc_before_ch: char = pyi_buf[rc_cpos - 1]
if rc_before_ch == ' ' or rc_before_ch == '\t' or \
rc_before_ch == '(' or rc_before_ch == ',' or \
rc_before_ch == '\n' or rc_before_ch == '\r':
rc_before_ok = 1
# 检查后字符是否是非标识符字符
rc_after_ok: int = 0
rc_after_pos: t.CSizeT = rc_cpos + name_len_rc
rc_after_pos: sizet = rc_cpos + name_len_rc
if rc_after_pos >= rc_scan_end:
rc_after_ok = 1
else:
rc_after_ch: t.CChar = pyi_buf[rc_after_pos]
rc_after_ch: char = pyi_buf[rc_after_pos]
if rc_after_ch == ' ' or rc_after_ch == '\t' or \
rc_after_ch == ')' or rc_after_ch == ',' or \
rc_after_ch == '\r' or rc_after_ch == '\n':
@@ -920,7 +920,7 @@ class ExprGenCdef(ExprGenBase.ExprGenBase):
rc_sub_buf: str = pool.alloc(rc_sub_len + 1)
if rc_sub_buf is None:
continue
rc_si: t.CSizeT
rc_si: sizet
for rc_si in range(rc_sub_len):
rc_sub_buf[rc_si] = pyi_buf[rc_sub_start + rc_si]
rc_sub_buf[rc_sub_len] = '\0'
@@ -940,7 +940,7 @@ class ExprGenCdef(ExprGenBase.ExprGenBase):
rc_pkg: str = self.Gen.CallGenBase._module_package_from_sha1(pool, sha1)
if rc_pkg is not None:
rc_base_mod = rc_pkg
rc_full_len: t.CSizeT = string.strlen(rc_base_mod) + 1 + rc_sub_len + 1
rc_full_len: sizet = string.strlen(rc_base_mod) + 1 + rc_sub_len + 1
rc_full_buf: str = pool.alloc(rc_full_len)
if rc_full_buf is None:
continue
@@ -955,7 +955,7 @@ class ExprGenCdef(ExprGenBase.ExprGenBase):
# .base → ast.base.base),说明子模块递归在重复追加同一模块段
# (模块间循环 re-export / 后缀匹配容错命中自身),跳过该次递归
# (NewAstTest CONST_INT 查找 dump:ast.base.base.base 无限增长根因)。
rc_blen: t.CSizeT = string.strlen(base_mod)
rc_blen: sizet = string.strlen(base_mod)
if rc_blen > rc_sub_len + 1:
rc_tail: str = base_mod + (rc_blen - rc_sub_len)
if rc_tail[0] == '.' and \
@@ -963,7 +963,7 @@ class ExprGenCdef(ExprGenBase.ExprGenBase):
continue
# 构建临时 from_imports "name:full_mod"
rc_fi_len: t.CSizeT = name_len_rc + 1 + string.strlen(rc_full_mod) + 1
rc_fi_len: sizet = name_len_rc + 1 + string.strlen(rc_full_mod) + 1
rc_fi: str = pool.alloc(rc_fi_len)
if rc_fi is None:
continue
@@ -982,22 +982,22 @@ class ExprGenCdef(ExprGenBase.ExprGenBase):
# (如 SHARE_READ)实际在 `import w32.fileio` 导入的模块中时,
# 需要遍历 imported_modules 逐个查找
if result_found == 0 and imported_modules is not None:
im2_len: t.CSizeT = string.strlen(imported_modules)
im2_ci: t.CSizeT = 0
im2_len: sizet = string.strlen(imported_modules)
im2_ci: sizet = 0
while im2_ci < im2_len and result_found == 0:
while im2_ci < im2_len and imported_modules[im2_ci] == ' ':
im2_ci += 1
if im2_ci >= im2_len:
break
im2_start: t.CSizeT = im2_ci
im2_start: sizet = im2_ci
while im2_ci < im2_len and imported_modules[im2_ci] != ' ':
im2_ci += 1
im2_end: t.CSizeT = im2_ci
im2_nlen: t.CSizeT = im2_end - im2_start
im2_end: sizet = im2_ci
im2_nlen: sizet = im2_end - im2_start
if im2_nlen > 0 and im2_nlen < 256:
im2_buf: str = pool.alloc(im2_nlen + 1)
if im2_buf is not None:
mk3: t.CSizeT = 0
mk3: sizet = 0
while mk3 < im2_nlen:
im2_buf[mk3] = imported_modules[im2_start + mk3]
mk3 += 1
@@ -1006,12 +1006,12 @@ class ExprGenCdef(ExprGenBase.ExprGenBase):
if sub_fi2 is not None:
sub_fi2[0] = '*'
sub_fi2[1] = ':'
mk4: t.CSizeT = 0
mk4: sizet = 0
while mk4 < im2_nlen:
sub_fi2[2 + mk4] = im2_buf[mk4]
mk4 += 1
sub_fi2[2 + im2_nlen] = '\0'
sub_val2: t.CInt64T = self._lookup_cross_module_cdefine(pool, name, sub_fi2, None, depth + 1, node)
sub_val2: int64 = self._lookup_cross_module_cdefine(pool, name, sub_fi2, None, depth + 1, node)
if self.Gen.TypeGenCDef.is_cdefine_found() != 0:
result_val = sub_val2
result_found = 1
@@ -1024,7 +1024,7 @@ class ExprGenCdef(ExprGenBase.ExprGenBase):
# 字符串 CDefine:值已在匹配循环 register_cdefine_string(val_buf
# 是命中行的字符串内容,pool 分配跨函数有效),此处只写跨模块缓存
if base_mod is not None:
ck_len_s: t.CSizeT = string.strlen(name) + string.strlen(base_mod) + 2
ck_len_s: sizet = string.strlen(name) + string.strlen(base_mod) + 2
ckey_s: str = pool.alloc(ck_len_s)
if ckey_s is not None:
viperlib.snprintf(ckey_s, ck_len_s, "%s@%s", name, base_mod)
@@ -1035,7 +1035,7 @@ class ExprGenCdef(ExprGenBase.ExprGenBase):
# key 与入口查询一致:"name@源模块"(用截断后的 base_mod,
# 与 mod_name_raw 一致——两者都是去点后的模块名,保证 key 匹配)
if base_mod is not None:
ck_len: t.CSizeT = string.strlen(name) + string.strlen(base_mod) + 2
ck_len: sizet = string.strlen(name) + string.strlen(base_mod) + 2
ckey_buf: str = pool.alloc(ck_len)
if ckey_buf is not None:
viperlib.snprintf(ckey_buf, ck_len, "%s@%s", name, base_mod)
@@ -1046,7 +1046,7 @@ class ExprGenCdef(ExprGenBase.ExprGenBase):
else:
# 浮点:从本地表取回 %.17g 文本,写入跨模块缓存(保精度)
if base_mod is not None:
ck_len2: t.CSizeT = string.strlen(name) + string.strlen(base_mod) + 2
ck_len2: sizet = string.strlen(name) + string.strlen(base_mod) + 2
ckey2: str = pool.alloc(ck_len2)
if ckey2 is not None:
viperlib.snprintf(ckey2, ck_len2, "%s@%s", name, base_mod)
@@ -1078,9 +1078,9 @@ class ExprGenCdef(ExprGenBase.ExprGenBase):
if name is None:
return 0
has_upper: int = 0
i: t.CSizeT = 0
i: sizet = 0
while name[i] != '\0':
c: t.CChar = name[i]
c: char = name[i]
if c >= 'a' and c <= 'z':
return 0
if c >= 'A' and c <= 'Z':
@@ -1091,13 +1091,13 @@ class ExprGenCdef(ExprGenBase.ExprGenBase):
# 翻译变量引用(Name 节点)→ load
# ============================================================
def _const_int_for_cdefine(self, pool: memhub.MemBuddy | t.CPtr,
value: t.CInt64T) -> llvmlite.Value | t.CPtr:
value: int64) -> llvmlite.Value | t.CPtr:
"""CDefine 整数常量 → LLVM 常量(对齐 TPC TypeConvert 的 64 位升级)
规则(与 translate_constant 的 i32 溢出升级一致,但保留 0xFFFFFFFF 语义):
值超 32 位无符号范围(> 0xFFFFFFFF)→ i64 全精度常量
(如 sys.maxsize = 9223372036854775807);
否则 → i32 常量,内部 t.CInt 截断(0xFFFFFFFF → -1,保持既有
否则 → i32 常量,内部 int 截断(0xFFFFFFFF → -1,保持既有
INVALID_HANDLE_VALUE / WAIT_FAILED = -1 语义不变,避免 i32 4294967295
生成非法 LLVM IR 文本 "i32 4294967295")。
@@ -1105,8 +1105,8 @@ class ExprGenCdef(ExprGenBase.ExprGenBase):
(> 0x7FFFFFFF)在字面量层回绕成 i32(sext 后等于 -1),阈值恒成立导致所有
正数 CDefine 都被升 i64(INVALID_FILE_ATTRIBUTES 0xFFFFFFFF 从 i32 -1 变
i64 4294967295 → 与 _get_attrs 的 sext(-1) 比较失败,SysLibTest exists FAIL 根因)。
改用截断回比较:t.CUInt32T(value) 回绕后还原,与 value 不等即超 u32 范围。
改用截断回比较:uint32(value) 回绕后还原,与 value 不等即超 u32 范围。
"""
if value >= 0 and t.CUInt64T(t.CUInt32T(value)) != value:
if value >= 0 and uint64(uint32(value)) != value:
return llvmlite.const_int64(pool, value)
return llvmlite.const_int32(pool, t.CInt(value))
return llvmlite.const_int32(pool, int(value))
+21 -21
View File
@@ -75,8 +75,8 @@ class ExprGenCls(ExprGenBase.ExprGenBase):
string.memset(self.DocValues, 0, DOC_MAX * DOC_VAL_SZ)
if self.DocCount >= DOC_MAX:
return
ml: t.CSizeT = string.strlen(module_sha1)
sl: t.CSizeT = string.strlen(symbol)
ml: sizet = string.strlen(module_sha1)
sl: sizet = string.strlen(symbol)
key_buf: bytes = stdlib.malloc(ml + sl + 2)
if key_buf is None:
return
@@ -94,8 +94,8 @@ class ExprGenCls(ExprGenBase.ExprGenBase):
"""查找 docstring 内容(key="{module_sha1}.{symbol}"),未找到返回 None"""
if self.DocKeys is None or module_sha1 is None or symbol is None:
return None
ml: t.CSizeT = string.strlen(module_sha1)
sl: t.CSizeT = string.strlen(symbol)
ml: sizet = string.strlen(module_sha1)
sl: sizet = string.strlen(symbol)
key_buf: bytes = stdlib.malloc(ml + sl + 2)
if key_buf is None:
return None
@@ -114,7 +114,7 @@ class ExprGenCls(ExprGenBase.ExprGenBase):
ch: list[ast.AST | t.CPtr] | t.CPtr = tree.children
if ch is None:
return
cn: t.CSizeT = len(ch)
cn: sizet = len(ch)
for ci in range(cn):
child: ast.AST | t.CPtr = ch.get(ci)
if child is None:
@@ -138,7 +138,7 @@ class ExprGenCls(ExprGenBase.ExprGenBase):
# 类方法 docstring(key="{ClassName}.{method}")
cd_body: list[ast.AST | t.CPtr] | t.CPtr = cd.children
if cd_body is not None:
cbn: t.CSizeT = len(cd_body)
cbn: sizet = len(cd_body)
for mi in range(cbn):
m: ast.AST | t.CPtr = cd_body.get(mi)
if m is None or m.kind() != ast.ASTKind.FunctionDef:
@@ -148,8 +148,8 @@ class ExprGenCls(ExprGenBase.ExprGenBase):
continue
mdoc: str = self._extract_docstring_from_body(mfd.children)
if mdoc is not None:
cl_nl: t.CSizeT = string.strlen(cd.name)
mt_nl: t.CSizeT = string.strlen(mfd.name)
cl_nl: sizet = string.strlen(cd.name)
mt_nl: sizet = string.strlen(mfd.name)
sym_buf: bytes = stdlib.malloc(cl_nl + mt_nl + 2)
if sym_buf is not None:
viperlib.snprintf(sym_buf, cl_nl + mt_nl + 2, "%s.%s", cd.name, mfd.name)
@@ -206,7 +206,7 @@ class ExprGenCls(ExprGenBase.ExprGenBase):
if trans.ModuleSha1 is None:
return 0
# 收集 Attribute 链(最外层 attr 在前)
DOC_CHAIN_MAX: t.CInt = 8
DOC_CHAIN_MAX: int = 8
items: bytes = stdlib.malloc(DOC_CHAIN_MAX * 128)
if items is None:
return 0
@@ -243,7 +243,7 @@ class ExprGenCls(ExprGenBase.ExprGenBase):
string.strcpy(out_sym, head_id)
stdlib.free(items)
return 1
total: t.CSizeT = 0
total: sizet = 0
j: int
for j in range(n_items):
total += string.strlen(items + j * 128) + 1
@@ -262,7 +262,7 @@ class ExprGenCls(ExprGenBase.ExprGenBase):
stdlib.free(items)
return 1
# 变量/类:symbol = head_id + '.' + items 反转
total2: t.CSizeT = string.strlen(head_id)
total2: sizet = string.strlen(head_id)
for j in range(n_items):
total2 += string.strlen(items + j * 128) + 1
sym2: bytes = stdlib.malloc(total2 + 1)
@@ -433,7 +433,7 @@ class ExprGenCls(ExprGenBase.ExprGenBase):
if self.Gen.CallGenBase.find_func_in_module(mod, lookup_name) is not None:
return 1
# 继承链祖先查找
mro_ptr: t.CSizeT | t.CPtr = self.Gen.StructGen.get_mro_chain(pool, class_name)
mro_ptr: sizet | t.CPtr = self.Gen.StructGen.get_mro_chain(pool, class_name)
mi: int = 1
while mro_ptr is not None and mro_ptr[mi] != 0:
anc: str = (str | t.CPtr)(t.CVoid(mro_ptr[mi], t.CPtr))
@@ -461,23 +461,23 @@ class ExprGenCls(ExprGenBase.ExprGenBase):
"""从返回注解文本提取已注册结构体类名,无命中返回 None"""
if pool is None or annot is None:
return None
alen: t.CSizeT = string.strlen(annot)
alen: sizet = string.strlen(annot)
if alen == 0:
return None
seg: str = pool.alloc(256)
if seg is None:
return None
start: t.CSizeT = 0
i: t.CSizeT
start: sizet = 0
i: sizet
for i in range(alen):
if annot[i] == '|':
s: t.CSizeT = start
e: t.CSizeT = i
s: sizet = start
e: sizet = i
while s < e and (annot[s] == ' ' or annot[s] == '\'' or annot[s] == '"'):
s += 1
while e > s and (annot[e - 1] == ' ' or annot[e - 1] == '\'' or annot[e - 1] == '"'):
e -= 1
seglen: t.CSizeT = e - s
seglen: sizet = e - s
if seglen > 0 and seglen < 256:
string.strncpy(seg, annot + s, seglen)
seg[seglen] = '\0'
@@ -492,13 +492,13 @@ class ExprGenCls(ExprGenBase.ExprGenBase):
return seg_bare2
start = i + 1
# 最后一段(无 '|' 后缀)
s: t.CSizeT = start
e: t.CSizeT = alen
s: sizet = start
e: sizet = alen
while s < e and (annot[s] == ' ' or annot[s] == '\'' or annot[s] == '"'):
s += 1
while e > s and (annot[e - 1] == ' ' or annot[e - 1] == '\'' or annot[e - 1] == '"'):
e -= 1
seglen: t.CSizeT = e - s
seglen: sizet = e - s
if seglen > 0 and seglen < 256:
string.strncpy(seg, annot + s, seglen)
seg[seglen] = '\0'
+17 -17
View File
@@ -37,7 +37,7 @@ class ExprGenConst(ExprGenBase.ExprGenBase):
if escaped is None:
return None
slen: t.CSizeT = string.strlen(str_val)
slen: sizet = string.strlen(str_val)
count: int = slen + 1
i8_ty: llvmlite.LLVMType | t.CPtr = llvmlite.Int8(pool)
@@ -101,7 +101,7 @@ class ExprGenConst(ExprGenBase.ExprGenBase):
# → 0x00000000FFFFFFFF(N1:THREAD_CREATE 失败码错)。
# const_int 按十进制值打印,故 i64 -1 即全 1,语义正确。
# 2) 否则维持旧规则:超出 i32 范围用 i64,其余 i32。
iv: t.CInt64T = cn.int_val
iv: int64 = cn.int_val
if target_ty is not None and self.is_ptr_type(target_ty) == 0 \
and self.get_llvm_type_bits(target_ty) > 32:
return llvmlite.const_int64(pool, iv)
@@ -124,17 +124,17 @@ class ExprGenConst(ExprGenBase.ExprGenBase):
# 栈槽残留垃圾(0x4 等)。declare_only 不产出 IR,target_ty 无用,
# 未对齐(8 对齐失败)即视为垃圾跳过,避免 is_ptr_type 解引用崩溃
# (SlotsBugTest 1a string.vp 崩溃根因;1b found_func 非 None 正常填充)。
if target_ty is not None and (t.CUInt64T(target_ty) & 7) == 0 \
if target_ty is not None and (uint64(target_ty) & 7) == 0 \
and self.is_ptr_type(target_ty) != 0:
cbuf: bytes = stdlib.malloc(2)
if cbuf is None:
return llvmlite.const_int32(pool, 0)
cbuf[0] = t.CChar(cn.int_val)
cbuf[0] = char(cn.int_val)
cbuf[1] = '\0'
r_cs: llvmlite.Value | t.CPtr = self.create_global_string(builder, pool, mod, cbuf, trans)
stdlib.free(cbuf)
return r_cs
cv: t.CInt64T = cn.int_val
cv: int64 = cn.int_val
return llvmlite.const_int32(pool, cv)
elif cn.const_kind == ast.CONST_STR:
sv: str = cn.str_val
@@ -233,7 +233,7 @@ class ExprGenConst(ExprGenBase.ExprGenBase):
existing: llvmlite.Value | t.CPtr = self.Gen.VarGen.lookup_module_var(trans.SymTab, "_mbuddy")
if existing is not None:
return existing
# 创建 i8* 类型(t.CVoid | t.CPtr = i8*)
# 创建 i8* 类型(t.CPtr = i8*)
i8_ty_fb: llvmlite.LLVMType | t.CPtr = llvmlite.Int8(pool)
i8_ptr_ty_fb: llvmlite.LLVMType | t.CPtr = llvmlite.Ptr(pool, i8_ty_fb)
# 当前模块 mangled 名(@<模块sha1>._mbuddy)
@@ -288,7 +288,7 @@ class ExprGenConst(ExprGenBase.ExprGenBase):
return None
elts: list[ast.AST | t.CPtr] | t.CPtr = list_node.elts
elts_count: t.CSizeT = 0
elts_count: sizet = 0
if elts is not None:
elts_count = len(elts)
@@ -358,11 +358,11 @@ class ExprGenConst(ExprGenBase.ExprGenBase):
if struct_entry is not None:
has_new_flag = struct_entry.HasNew
if has_new_flag != 0:
new_args: t.CSizeT | t.CPtr = pool.alloc(8 * 32)
new_args: sizet | t.CPtr = pool.alloc(8 * 32)
if new_args is None:
return None
string.memset(new_args, 0, 8 * 32)
new_args[0] = t.CSizeT(pool_val)
new_args[0] = sizet(pool_val)
new_ptr: llvmlite.Value | t.CPtr = self.Gen.CallGenCall._call_method_on_ptr(
pool, builder, mod, spec_name, "__new__", tmp, new_args, 1, trans)
if new_ptr is not None:
@@ -373,13 +373,13 @@ class ExprGenConst(ExprGenBase.ExprGenBase):
pool, builder, mod, spec_name, "__before_init__", storage_ptr, None, 0, trans)
# 调用 __init__(storage_ptr, pool_val, elem_size=0)
init_args: t.CSizeT | t.CPtr = pool.alloc(8 * 32)
init_args: sizet | t.CPtr = pool.alloc(8 * 32)
if init_args is None:
return None
string.memset(init_args, 0, 8 * 32)
init_args[0] = t.CSizeT(pool_val)
init_args[0] = sizet(pool_val)
elem_size_val: llvmlite.Value | t.CPtr = llvmlite.const_int64(pool, 0)
init_args[1] = t.CSizeT(elem_size_val)
init_args[1] = sizet(elem_size_val)
self.Gen.CallGenCall._call_method_on_ptr(
pool, builder, mod, spec_name, "__init__", storage_ptr, init_args, 2, trans)
@@ -387,23 +387,23 @@ class ExprGenConst(ExprGenBase.ExprGenBase):
if elts_count > 0:
# 第一个元素可能已经翻译过
if first_elem_val is not None:
append_args: t.CSizeT | t.CPtr = pool.alloc(8 * 32)
append_args: sizet | t.CPtr = pool.alloc(8 * 32)
if append_args is not None:
string.memset(append_args, 0, 8 * 32)
append_args[0] = t.CSizeT(first_elem_val)
append_args[0] = sizet(first_elem_val)
self.Gen.CallGenCall._call_method_on_ptr(
pool, builder, mod, spec_name, "append", storage_ptr, append_args, 1, trans)
# 翻译剩余元素
i: t.CSizeT = 1
i: sizet = 1
while i < elts_count:
elem_node_i: ast.AST | t.CPtr = elts.get(i)
elem_val_i: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(builder, pool, mod, elem_node_i, None, 0, trans)
if elem_val_i is not None:
ap_args: t.CSizeT | t.CPtr = pool.alloc(8 * 32)
ap_args: sizet | t.CPtr = pool.alloc(8 * 32)
if ap_args is not None:
string.memset(ap_args, 0, 8 * 32)
ap_args[0] = t.CSizeT(elem_val_i)
ap_args[0] = sizet(elem_val_i)
self.Gen.CallGenCall._call_method_on_ptr(
pool, builder, mod, spec_name, "append", storage_ptr, ap_args, 1, trans)
i += 1
+21 -21
View File
@@ -59,7 +59,7 @@ class ExprGenFstr(ExprGenBase.ExprGenBase):
arg_count: int = 0
parts: list[ast.AST | t.CPtr] | t.CPtr = js.values
pn: t.CSizeT = len(parts)
pn: sizet = len(parts)
for pi in range(pn):
part: ast.AST | t.CPtr = parts.get(pi)
if part is None:
@@ -194,14 +194,14 @@ class ExprGenFstr(ExprGenBase.ExprGenBase):
"""追加字面量到格式串(% 转义为 %%)"""
if fmt_buf is None or lit is None:
return
cur_len: t.CSizeT = string.strlen(fmt_buf)
rem: t.CSizeT = FSTR_BUF_SIZE - 1 - cur_len
cur_len: sizet = string.strlen(fmt_buf)
rem: sizet = FSTR_BUF_SIZE - 1 - cur_len
if rem == 0:
return
src_len: t.CSizeT = string.strlen(lit)
si: t.CSizeT = 0
src_len: sizet = string.strlen(lit)
si: sizet = 0
while si < src_len and rem > 0:
ch: t.CChar = lit[si]
ch: char = lit[si]
if ch == '%':
if rem < 2:
break
@@ -219,8 +219,8 @@ class ExprGenFstr(ExprGenBase.ExprGenBase):
"""追加原始字符串(不做 % 转义)"""
if fmt_buf is None or s is None:
return
cur_len: t.CSizeT = string.strlen(fmt_buf)
src_len: t.CSizeT = string.strlen(s)
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 | t.CPtr,
@@ -240,7 +240,7 @@ class ExprGenFstr(ExprGenBase.ExprGenBase):
jss: ast.JoinedStr | t.CPtr = (ast.JoinedStr | t.CPtr)(spec_node)
if jss.values is None:
return None
vn: t.CSizeT = len(jss.values)
vn: sizet = len(jss.values)
for vi in range(vn):
vpart: ast.AST | t.CPtr = jss.values.get(vi)
if vpart is None:
@@ -259,20 +259,20 @@ class ExprGenFstr(ExprGenBase.ExprGenBase):
string.strncpy(spec, cn.str_val, FSTR_SPEC_MAX - 1)
else:
return None
slen: t.CSizeT = string.strlen(spec)
slen: sizet = string.strlen(spec)
if slen == 0:
return None
# 2. 逐段解析: [fill]align / sign / # / 0 / width / , / .precision / type
pos: t.CSizeT = 0
align_char: t.CChar = 0
pos: sizet = 0
align_char: char = 0
if pos < slen:
ch0: t.CChar = spec[pos]
ch0: char = spec[pos]
if ch0 == '<' or ch0 == '>' or ch0 == '^' or ch0 == '=':
align_char = ch0
pos += 1
elif pos + 1 < slen:
ch1: t.CChar = spec[pos + 1]
ch1: char = spec[pos + 1]
if ch1 == '<' or ch1 == '>' or ch1 == '^' or ch1 == '=':
align_char = ch1
pos += 2
@@ -304,7 +304,7 @@ class ExprGenFstr(ExprGenBase.ExprGenBase):
string.strcat(c_flags, "-")
# width digits
while pos < slen and spec[pos] >= '0' and spec[pos] <= '9':
wl: t.CSizeT = string.strlen(c_width)
wl: sizet = string.strlen(c_width)
if wl < 30:
c_width[wl] = spec[pos]
c_width[wl + 1] = '\0'
@@ -317,7 +317,7 @@ class ExprGenFstr(ExprGenBase.ExprGenBase):
string.strcat(c_prec, ".")
pos += 1
while pos < slen and spec[pos] >= '0' and spec[pos] <= '9':
pl: t.CSizeT = string.strlen(c_prec)
pl: sizet = string.strlen(c_prec)
if pl < 30:
c_prec[pl] = spec[pos]
c_prec[pl + 1] = '\0'
@@ -325,7 +325,7 @@ class ExprGenFstr(ExprGenBase.ExprGenBase):
if string.strlen(c_prec) == 1:
return None # 只有 '.' 无效
# type char
fmt_type: t.CChar = 0
fmt_type: char = 0
if pos < slen:
fmt_type = spec[pos]
pos += 1
@@ -452,12 +452,12 @@ class ExprGenFstr(ExprGenBase.ExprGenBase):
if val is None or c_fmt is None:
return None
# 找格式类型字符(最后一个字母,忽略 l/h 长度修饰)
fmt_char: t.CChar = 0
flen: t.CSizeT = string.strlen(c_fmt)
fi: t.CSizeT = flen
fmt_char: char = 0
flen: sizet = string.strlen(c_fmt)
fi: sizet = flen
while fi > 0:
fi -= 1
ch: t.CChar = c_fmt[fi]
ch: char = c_fmt[fi]
if ch == '%':
break
if (ch >= 'a' and ch <= 'z') or (ch >= 'A' and ch <= 'Z'):
+23 -23
View File
@@ -38,7 +38,7 @@ class ExprGenName(ExprGenBase.ExprGenBase):
"""
if raw is None:
return None
mbl_c: t.CSizeT = 0
mbl_c: sizet = 0
while raw[mbl_c] != ' ' and raw[mbl_c] != '\0' and raw[mbl_c] != ':':
mbl_c += 1
if mbl_c == 0:
@@ -91,7 +91,7 @@ class ExprGenName(ExprGenBase.ExprGenBase):
return llvmlite.ConstFloat(pool, llvmlite.Double(pool), cdef_val_d)
# 整数 CDefine:重新查表取 64 位全精度值(double 往返会丢精度,
# 9223372036854775807 → 9.223372036854776e18 舍入错位,生成错常量)
cdef_val_c: t.CInt64T = self.Gen.TypeGenCDef.lookup_cdefine_constant(nm_id)
cdef_val_c: int64 = self.Gen.TypeGenCDef.lookup_cdefine_constant(nm_id)
return self.Gen.ExprGenCdef._const_int_for_cdefine(pool, cdef_val_c)
# 本地表未找到:尝试跨模块 .vpi 查找(保证多模块查表存表一致)
@@ -107,7 +107,7 @@ class ExprGenName(ExprGenBase.ExprGenBase):
# 文件,且多 includes 目录下还可能触发 XMOD-CD 误报
# (ExprGenCdef._build_source_path_from_sha1 拼错路径)。
if self.Gen.VarGen.lookup_var(trans.SymTab, nm_id) is None:
cdef_val: t.CInt64T = self.Gen.ExprGenCdef._lookup_cross_module_cdefine(
cdef_val: int64 = self.Gen.ExprGenCdef._lookup_cross_module_cdefine(
pool, nm_id, trans._from_imports, trans._imported_modules, 0, node)
if self.Gen.TypeGenCDef.is_cdefine_found() != 0:
if self.Gen.TypeGenCDef.is_cdefine_str() != 0:
@@ -123,7 +123,7 @@ class ExprGenName(ExprGenBase.ExprGenBase):
return self.Gen.ExprGenCdef._const_int_for_cdefine(pool, cdef_val)
# CDefine 查找失败:from-import 的模块级全局变量(如
# from Phase1 import PYI_BUF_SIZE;PYI_BUF_SIZE: t.CSizeT = 262144 是
# from Phase1 import PYI_BUF_SIZE;PYI_BUF_SIZE: sizet = 262144 是
# i64 全局、非宏,语义同 C 的 extern size_t PYI_BUF_SIZE)。from-import
# 确认名称确实来自某模块后,按后缀匹配查找该全局并加载。
if trans is not None and trans._from_imports is not None:
@@ -166,7 +166,7 @@ class ExprGenName(ExprGenBase.ExprGenBase):
# fail-fast:global 变量存储类型缺失,立即终止编译(暴露上游根因)
self.Gen.TypeGenErr.fatal_error(
node, f"变量 '{nm_id}' 存储类型缺失", "TypeError")
# 全局数组(如 pyzlib.pyzlib_error_msg: CArray[t.CChar, 512]):
# 全局数组(如 pyzlib.pyzlib_error_msg: CArray[char, 512]):
# 按 C 语义衰减为基址返回(对齐下方局部数组分支 L3383-3388)。
# 否则 load [512 x i8] 数组值当 i8* 传 → set_error 的 strncpy
# dest 是数组值(栈拷贝)而非数组基址 → 写入丢失 → get_error
@@ -310,7 +310,7 @@ class ExprGenName(ExprGenBase.ExprGenBase):
fi_orig: str = self.Gen.ImportsGen.lookup_from_import_original(
trans._from_imports, nm_id)
if fi_orig is not None:
og_len_fi: t.CSizeT = 0
og_len_fi: sizet = 0
while fi_orig[og_len_fi] != ' ' and fi_orig[og_len_fi] != '\0':
og_len_fi += 1
if og_len_fi > 0:
@@ -499,7 +499,7 @@ class ExprGenName(ExprGenBase.ExprGenBase):
rb_e: str = string.strrchr(struct_name, ']')
if rb_e is None:
return None
elen_e: t.CSizeT = t.CSizeT(t.CUInt64T(rb_e) - t.CUInt64T(lb_e)) - 1
elen_e: sizet = sizet(uint64(rb_e) - uint64(lb_e)) - 1
if elen_e == 0 or elen_e > 512:
return None
elem_buf_e: str = pool.alloc(elen_e + 1)
@@ -514,9 +514,9 @@ class ExprGenName(ExprGenBase.ExprGenBase):
# 按 '|' 联合分段(A|B),段内去首尾空白/尾部 ']'/引号;段文本直接
# 交给 find_struct(内置名 CPtr/str/int 等不注册 struct → 天然返回
# None 跳过;带 "sha1.Class" 前缀走模块归属精确匹配)
total_e: t.CSizeT = string.strlen(cur_e)
seg_s_e: t.CSizeT = 0
i_e: t.CSizeT = 0
total_e: sizet = string.strlen(cur_e)
seg_s_e: sizet = 0
i_e: sizet = 0
while i_e <= total_e:
hit_e: int = 0
if i_e == total_e:
@@ -526,8 +526,8 @@ class ExprGenName(ExprGenBase.ExprGenBase):
if hit_e == 0:
i_e += 1
continue
b_e: t.CSizeT = i_e
a_e: t.CSizeT = seg_s_e
b_e: sizet = i_e
a_e: sizet = seg_s_e
while b_e > a_e and (cur_e[b_e - 1] == ' ' or cur_e[b_e - 1] == ']' \
or cur_e[b_e - 1] == '\'' or cur_e[b_e - 1] == '"'):
b_e -= 1
@@ -535,7 +535,7 @@ class ExprGenName(ExprGenBase.ExprGenBase):
or cur_e[a_e] == '"'):
a_e += 1
if b_e > a_e:
seg_len_e: t.CSizeT = b_e - a_e
seg_len_e: sizet = b_e - a_e
if seg_len_e < 256:
seg_buf_e: str = pool.alloc(seg_len_e + 1)
if seg_buf_e is not None:
@@ -897,9 +897,9 @@ class ExprGenName(ExprGenBase.ExprGenBase):
obj_ptr_rd: llvmlite.Value | t.CPtr = llvmlite.build_load(
builder, pointee, alloca)
if not (obj_ptr_rd is None):
arg_vals_rd_p: t.CSizeT | t.CPtr = pool.alloc(8)
arg_vals_rd_p: sizet | t.CPtr = pool.alloc(8)
if not (arg_vals_rd_p is None):
arg_vals_rd_p[0] = t.CSizeT(idx_val)
arg_vals_rd_p[0] = sizet(idx_val)
ret_rd_p: llvmlite.Value | t.CPtr = self.Gen.CallGenCall._call_method_on_ptr(
pool, builder, mod, cls_nm_rd_ptr, "__getitem__",
obj_ptr_rd, arg_vals_rd_p, 1, trans, sub)
@@ -976,9 +976,9 @@ class ExprGenName(ExprGenBase.ExprGenBase):
obj_val_sub: llvmlite.Value | t.CPtr = llvmlite.build_load(
builder, pointee, alloca)
if not (obj_val_sub is None):
arg_vals_sub: t.CSizeT | t.CPtr = pool.alloc(8)
arg_vals_sub: sizet | t.CPtr = pool.alloc(8)
if not (arg_vals_sub is None):
arg_vals_sub[0] = t.CSizeT(idx_val)
arg_vals_sub[0] = sizet(idx_val)
ret_sub: llvmlite.Value | t.CPtr = self.Gen.CallGenCall._call_method_on_ptr(
pool, builder, mod, cls_nm_sub, "__getitem__",
obj_val_sub, arg_vals_sub, 1, trans, sub)
@@ -1017,7 +1017,7 @@ class ExprGenName(ExprGenBase.ExprGenBase):
case _:
pass
# [FIX 2026-08-31] 64 位标量 | t.CPtr 联合字段下标读回
# (如 RenumClassNames: t.CSizeT | t.CPtr,联合解析为 i64* 8 字节
# (如 RenumClassNames: sizet | t.CPtr,联合解析为 i64* 8 字节
# 槽数组):槽位按 Int64 load 得位模式,赋给 str(i8*)触发 int→ptr
# 禁令误报(ClassGenEnum.vp existing: str = self.RenumClassNames[i]
# 根因)。槽里实际存的是 perm_pool 字符串指针——联合声明即"槽位可能
@@ -1057,9 +1057,9 @@ class ExprGenName(ExprGenBase.ExprGenBase):
if gi_lookup_gen is not None:
viperlib.snprintf(gi_lookup_gen, 128, "%s.__getitem__", cls_nm_rd_gen)
if self.Gen.CallGenBase.find_func_in_module(mod, gi_lookup_gen) is not None:
arg_vals_rd_g: t.CSizeT | t.CPtr = pool.alloc(8)
arg_vals_rd_g: sizet | t.CPtr = pool.alloc(8)
if not (arg_vals_rd_g is None):
arg_vals_rd_g[0] = t.CSizeT(idx_val)
arg_vals_rd_g[0] = sizet(idx_val)
ret_rd_g: llvmlite.Value | t.CPtr = self.Gen.CallGenCall._call_method_on_ptr(
pool, builder, mod, cls_nm_rd_gen, "__getitem__",
ptr_val, arg_vals_rd_g, 1, trans, sub)
@@ -1082,7 +1082,7 @@ class ExprGenName(ExprGenBase.ExprGenBase):
# ============================================================
def _annot_is_64bit_scalar(self, annot: str) -> int:
"""注解是否为 64 位标量 | t.CPtr 联合(AnnotClassName 为提取出的
非 CPtr 侧类型名,如 t.CInt64T|t.CPtr → "CInt64T")。此类联合的
非 CPtr 侧类型名,如 int64|t.CPtr → "CInt64T")。此类联合的
8 字节单元格存 i64 标量,下标元素类型应为 Int64 而非指针。"""
if annot is None:
return 0
@@ -1191,8 +1191,8 @@ class ExprGenName(ExprGenBase.ExprGenBase):
ptr_val_pe: llvmlite.Value | t.CPtr = llvmlite.build_load(
builder, pointee, alloca)
if ptr_val_pe is not None:
# [FIX 2026-08-30] 64 位标量联合(t.CInt64T|t.CPtr /
# t.CUInt64T|t.CPtr / t.CSizeT|t.CPtr):8 字节单元格存
# [FIX 2026-08-30] 64 位标量联合(int64|t.CPtr /
# uint64|t.CPtr / sizet|t.CPtr):8 字节单元格存
# i64 标量(viperlib %n 的 np[0]=write_count 是解引用写入,
# 语义 *np=(i64)x)。GEP 元素必须用 Int64(标量)而非指针,
# 否则元素类型为指针 → i64 存储触发整数隐式转指针
+22 -22
View File
@@ -172,7 +172,7 @@ class ExprGenOps(ExprGenBase.ExprGenBase):
2. i8 → zext(系统编程中 i8 几乎总是无符号字节)
3. 宽侧是常量且其值超出窄侧位宽的有符号范围 → zext
(常量"想要"无符号解释,如 0xAABBCCDD > INT32_MAX 与
t.CUInt32T 值比较,sext 会把 0xAABBCCDD 变成
uint32 值比较,sext 会把 0xAABBCCDD 变成
0xFFFFFFFFAABBCCDD 导致恒不等)
"""
if narrow_val is None or narrow_val.Ty is None:
@@ -186,7 +186,7 @@ class ExprGenOps(ExprGenBase.ExprGenBase):
if wide_val is not None and wide_val.IsConst == 1:
wide_bits: int = self.get_llvm_type_bits(wide_val.Ty)
if wide_bits > narrow_bits and narrow_bits < 64:
signed_max: t.CInt64T = (t.CInt64T(1) << (narrow_bits - 1)) - 1
signed_max: int64 = (int64(1) << (narrow_bits - 1)) - 1
if wide_val.IntVal > signed_max:
return 1
# 窄侧 AST 节点解析为无符号类型(如 t.CUIntXXT 字面量/强转)
@@ -207,7 +207,7 @@ class ExprGenOps(ExprGenBase.ExprGenBase):
if narrow_node is not None and narrow_node.kind() == ast.ASTKind.Name:
cdef_nm_zw: ast.Name | t.CPtr = (ast.Name | t.CPtr)(narrow_node)
if cdef_nm_zw.id is not None:
cdv_zw: t.CInt64T = self.Gen.TypeGenCDef.lookup_cdefine_constant(cdef_nm_zw.id)
cdv_zw: int64 = self.Gen.TypeGenCDef.lookup_cdefine_constant(cdef_nm_zw.id)
if self.Gen.TypeGenCDef.is_cdefine_found() != 0:
if cdv_zw > 0x7FFFFFFF:
return 1
@@ -218,9 +218,9 @@ class ExprGenOps(ExprGenBase.ExprGenBase):
"""轻量判断 AST 节点是否解析为无符号整数类型(1=是,0=否/未知)
覆盖常见形态(对齐 TPC _check_node_unsigned 的 Call/Subscript 分支):
- t.CUInt8T/CUInt16T/CUInt32T/CUInt64T/CUnsigned* 等显式无符号类型强转调用
- uint8/CUInt16T/CUInt32T/CUInt64T/CUnsigned* 等显式无符号类型强转调用
- 无符号类型名的 Name 引用(如 UInt32T 别名)
- 变量名(trans 可用时):查询 SymTab 中变量的 AnnotClassName(如 v: t.CUInt32T)
- 变量名(trans 可用时):查询 SymTab 中变量的 AnnotClassName(如 v: uint32)
"""
if node is None:
return 0
@@ -263,8 +263,8 @@ class ExprGenOps(ExprGenBase.ExprGenBase):
return 1
return 0
if k == ast.ASTKind.Subscript:
# 数组/指针下标: md5_buf[i](t.CArray[t.CUInt8T, N])或 buf[i]
# (形参 t.CUInt8T | t.CPtr)元素是无符号整型 → printf("%02x", ...) zext。
# 数组/指针下标: md5_buf[i](t.CArray[uint8, N])或 buf[i]
# (形参 uint8 | t.CPtr)元素是无符号整型 → printf("%02x", ...) zext。
sub_su: ast.Subscript | t.CPtr = (ast.Subscript | t.CPtr)(node)
if sub_su.value is not None and sub_su.value.kind() == ast.ASTKind.Name:
snm_su: ast.Name | t.CPtr = (ast.Name | t.CPtr)(sub_su.value)
@@ -276,7 +276,7 @@ class ExprGenOps(ExprGenBase.ExprGenBase):
return 1
return 0
if k == ast.ASTKind.Attribute:
# 结构体字段(如 viperio.Buf 的 self.capacity/length: t.CSizeT):
# 结构体字段(如 viperio.Buf 的 self.capacity/length: sizet):
# 经接收者变量的 AnnotClassName 取类名,再按类名+字段名查字段注解,
# 判定无符号(CSizeT/uint*)。此前 Attribute 落到末尾 return 0 →
# `self.capacity > 0` / `self.length < self.capacity` 生成 icmp sgt/slt
@@ -358,7 +358,7 @@ class ExprGenOps(ExprGenBase.ExprGenBase):
def _annot_str_unsigned(self, annot: str) -> int:
"""检查类型注解字符串是否引用无符号整型(子串扫描)
用于复合注解(t.CArray[t.CUInt8T, 16] / t.CUInt8T | t.CPtr),
用于复合注解(t.CArray[uint8, 16] / uint8 | t.CPtr),
_type_name_unsigned 的精确匹配对这类串不适用。
"""
if annot is None:
@@ -395,7 +395,7 @@ class ExprGenOps(ExprGenBase.ExprGenBase):
if cmp is None:
return None
ops_list: list[t.CInt] | t.CPtr = (list[t.CInt] | t.CPtr)(cmp.ops)
ops_list: list[int] | t.CPtr = (list[int] | t.CPtr)(cmp.ops)
if ops_list is None or len(ops_list) == 0:
return None
op: int = ops_list.get(0)
@@ -500,7 +500,7 @@ class ExprGenOps(ExprGenBase.ExprGenBase):
cn_res: llvmlite.Value | t.CPtr = llvmlite.build_call(
builder, cn_fn_name, cn_self, 2, cn_ret, 0)
if cn_res is not None:
# 归一化到 i1(__contains__ 返回 t.CInt/i32 等)
# 归一化到 i1(__contains__ 返回 int/i32 等)
cn_i1: llvmlite.Value | t.CPtr = cn_res
match cn_ret:
case llvmlite.LLVMType.Int(cn_bits):
@@ -537,7 +537,7 @@ class ExprGenOps(ExprGenBase.ExprGenBase):
return ovl_result2
# === 无符号比较(A5):操作数为无符号整数类型(CUInt64T/CUInt32T 等)时
# 用 ULT/ULE/UGT/UGE。此前固定有符号 predicate → t.CUInt64T 地址比较在
# 用 ULT/ULE/UGT/UGE。此前固定有符号 predicate → uint64 地址比较在
# 跨 2^63 边界时语义错误(paging MakeRangeRO/save_pt_range 的
# `while va < vaddr_end` 生成 icmp slt,A5 根因)。复用 _node_type_unsigned
# (Name→变量 AnnotClassName / Call→转换目标 / Attribute→类型名 / 递归)。
@@ -840,14 +840,14 @@ class ExprGenOps(ExprGenBase.ExprGenBase):
fname_ao: str = llvmlite.function_get_name(f_ao)
if fname_ao is not None:
p_head_ao: llvmlite.Param | t.CPtr = llvmlite.function_get_param_head(f_ao)
p_cnt_ao: t.CSizeT = 0
p_cnt_ao: sizet = 0
p_cur_ao: llvmlite.Param | t.CPtr = p_head_ao
while p_cur_ao is not None:
p_cnt_ao += 1
p_cur_ao = llvmlite.param_get_next(p_cur_ao)
fn_ty_ao: llvmlite.LLVMType | t.CPtr = llvmlite.Func(pool, f_ao.RetTy, p_head_ao, p_cnt_ao)
# 函数引用名按需加引号(数字开头/含 '.' 的 sha1 前缀名)
fnlen_ao: t.CSizeT = string.strlen(fname_ao)
fnlen_ao: sizet = string.strlen(fname_ao)
needs_q_ao: int = self.Gen.ClassGenVTable._vtable_name_needs_quote(fname_ao)
fbuf_ao: str = pool.alloc(fnlen_ao + 4)
if fbuf_ao is not None and fn_ty_ao is not None:
@@ -897,7 +897,7 @@ class ExprGenOps(ExprGenBase.ExprGenBase):
values: list[ast.AST | t.CPtr] | t.CPtr = bo.values
if values is None:
return None
count: t.CSizeT = len(values)
count: sizet = len(values)
if count == 0:
return None
if count == 1:
@@ -1089,7 +1089,7 @@ class ExprGenOps(ExprGenBase.ExprGenBase):
search_class: str = class_name
if found_func is None:
# 多继承:沿 MRO 祖先链查找(先声明父类优先)
mro_ptr: t.CSizeT | t.CPtr = self.Gen.StructGen.get_mro_chain(pool, class_name)
mro_ptr: sizet | t.CPtr = self.Gen.StructGen.get_mro_chain(pool, class_name)
mi: int = 1
while mro_ptr is not None and mro_ptr[mi] != 0:
anc: str = (str | t.CPtr)(t.CVoid(mro_ptr[mi], t.CPtr))
@@ -1113,7 +1113,7 @@ class ExprGenOps(ExprGenBase.ExprGenBase):
if cls_sha1 is None:
cls_sha1 = self.Gen.StructGen.get_struct_sha1(search_class)
if cls_sha1 is None:
mro_p: t.CSizeT | t.CPtr = self.Gen.StructGen.get_mro_chain(pool, search_class)
mro_p: sizet | t.CPtr = self.Gen.StructGen.get_mro_chain(pool, search_class)
mj: int = 1
while mro_p is not None and mro_p[mj] != 0 and cls_sha1 is None:
anc_p: str = (str | t.CPtr)(t.CVoid(mro_p[mj], t.CPtr))
@@ -1142,10 +1142,10 @@ class ExprGenOps(ExprGenBase.ExprGenBase):
return None
# 构建 extra_args 数组(仅含 rhs 一个参数)
extra_args: t.CSizeT | t.CPtr = pool.alloc(8)
extra_args: sizet | t.CPtr = pool.alloc(8)
if extra_args is None:
return None
extra_args[0] = t.CSizeT(rhs)
extra_args[0] = sizet(rhs)
# 调用方法: lhs.__dunder__(rhs)
return self.Gen.CallGenCall._call_method_on_ptr(
@@ -1191,7 +1191,7 @@ class ExprGenOps(ExprGenBase.ExprGenBase):
search_class: str = class_name
if found_func is None:
# 多继承:沿 MRO 祖先链查找(先声明父类优先)
mro_ptr: t.CSizeT | t.CPtr = self.Gen.StructGen.get_mro_chain(pool, class_name)
mro_ptr: sizet | t.CPtr = self.Gen.StructGen.get_mro_chain(pool, class_name)
mi: int = 1
while mro_ptr is not None and mro_ptr[mi] != 0:
anc: str = (str | t.CPtr)(t.CVoid(mro_ptr[mi], t.CPtr))
@@ -1214,7 +1214,7 @@ class ExprGenOps(ExprGenBase.ExprGenBase):
if cls_sha1 is None:
cls_sha1 = self.Gen.StructGen.get_struct_sha1(search_class)
if cls_sha1 is None:
mro_p: t.CSizeT | t.CPtr = self.Gen.StructGen.get_mro_chain(pool, search_class)
mro_p: sizet | t.CPtr = self.Gen.StructGen.get_mro_chain(pool, search_class)
mj: int = 1
while mro_p is not None and mro_p[mj] != 0 and cls_sha1 is None:
anc_p: str = (str | t.CPtr)(t.CVoid(mro_p[mj], t.CPtr))
@@ -1379,7 +1379,7 @@ class ExprGenOps(ExprGenBase.ExprGenBase):
return llvmlite.build_mul(builder, lhs, rhs)
elif op == ast.OpKind.Div:
# 无符号操作数 → udiv(binop_unsigned 经 _node_type_unsigned 判定,
# 覆盖 t.CSizeT/t.CUInt64T 及变量/数组元素的注解无符号性)。
# 覆盖 sizet/uint64 及变量/数组元素的注解无符号性)。
# 此前一律 sdiv → 无符号值 ≥ 2^63 时结果错误(viperlib %lu/%lx、
# fat32_mkfs 扇区运算等根因)。
if binop_unsigned != 0:
+18 -18
View File
@@ -36,7 +36,7 @@ class FuncGenBase(CallGenBase.CallGenBase):
"""从 decorator_list 提取 c.Attribute 属性,返回 LLVM IR 属性字符串"""
if decorator_list is None:
return None
dn: t.CSizeT = len(decorator_list)
dn: sizet = len(decorator_list)
if dn == 0:
return None
@@ -84,7 +84,7 @@ class FuncGenBase(CallGenBase.CallGenBase):
if call_node.args is None:
continue
args_list: list[ast.AST | t.CPtr] | t.CPtr = call_node.args
an: t.CSizeT = len(args_list)
an: sizet = len(args_list)
for ai in range(an):
arg_node: ast.AST | t.CPtr = args_list.get(ai)
if arg_node is None:
@@ -117,7 +117,7 @@ class FuncGenBase(CallGenBase.CallGenBase):
"""
if pool is None or decorator_list is None:
return None
dn: t.CSizeT = len(decorator_list)
dn: sizet = len(decorator_list)
if dn == 0:
return None
for di in range(dn):
@@ -133,7 +133,7 @@ class FuncGenBase(CallGenBase.CallGenBase):
if call_node.args is None:
continue
args_list: list[ast.AST | t.CPtr] | t.CPtr = call_node.args
an: t.CSizeT = len(args_list)
an: sizet = len(args_list)
for ai in range(an):
arg_node: ast.AST | t.CPtr = args_list.get(ai)
if arg_node is None:
@@ -237,7 +237,7 @@ class FuncGenBase(CallGenBase.CallGenBase):
self._append_str(attrs_buf, llvm_name, 256)
return 1
def _append_str(self, buf: str, s: str,
max_len: t.CSizeT = 256) -> None:
max_len: sizet = 256) -> None:
"""将字符串追加到 buf 末尾(有界,防 strcpy 越界写穿定长缓冲)"""
if buf is None or s is None:
return
@@ -245,8 +245,8 @@ class FuncGenBase(CallGenBase.CallGenBase):
# 显式兜底为 256,避免有界写入检查误判丢弃全部属性文本。
if max_len == 0:
max_len = 256
cur_len: t.CSizeT = string.strlen(buf)
s_len: t.CSizeT = string.strlen(s)
cur_len: sizet = string.strlen(buf)
s_len: sizet = string.strlen(s)
if cur_len + s_len + 1 > max_len:
return # 无剩余容量:丢弃本次追加,避免越界写
string.strcpy(buf + cur_len, s)
@@ -262,19 +262,19 @@ class FuncGenBase(CallGenBase.CallGenBase):
return name
if trans.ModuleSha1 is None:
return name
name_len: t.CSizeT = string.strlen(name)
name_len: sizet = string.strlen(name)
# 已带 SHA1 前缀(16 hex + '.')则跳过
if name_len > 17:
is_sha1: int = 1
for i in range(16):
c: t.CChar = name[i]
c: char = name[i]
if not (('0' <= c <= '9') or ('a' <= c <= 'f')):
is_sha1 = 0
break
if is_sha1 != 0 and name[16] == '.':
return name
sha1: str = trans.ModuleSha1
sha1_len: t.CSizeT = string.strlen(sha1)
sha1_len: sizet = string.strlen(sha1)
mangled: str = stdlib.malloc(sha1_len + name_len + 2)
if mangled is None:
return name
@@ -292,18 +292,18 @@ class FuncGenBase(CallGenBase.CallGenBase):
"""用指定 SHA1 为名称添加前缀(不做 main/export 检查)"""
if sha1 is None or name is None:
return name
name_len: t.CSizeT = string.strlen(name)
name_len: sizet = string.strlen(name)
# 已带 SHA1 前缀(16 hex + '.')则跳过
if name_len > 17:
is_sha1: int = 1
for i in range(16):
c2: t.CChar = name[i]
c2: char = name[i]
if not (('0' <= c2 <= '9') or ('a' <= c2 <= 'f')):
is_sha1 = 0
break
if is_sha1 != 0 and name[16] == '.':
return name
sha1_len: t.CSizeT = string.strlen(sha1)
sha1_len: sizet = string.strlen(sha1)
mangled: str = stdlib.malloc(sha1_len + name_len + 2)
if mangled is None:
return name
@@ -342,7 +342,7 @@ class FuncGenBase(CallGenBase.CallGenBase):
if fd is None or fd.children is None:
return 0
body_f: list[ast.AST | t.CPtr] | t.CPtr = fd.children
bn_f: t.CSizeT = len(body_f)
bn_f: sizet = len(body_f)
for bi_f in range(bn_f):
stmt_f: ast.AST | t.CPtr = body_f.get(bi_f)
if stmt_f is None:
@@ -371,7 +371,7 @@ class FuncGenBase(CallGenBase.CallGenBase):
# _resolve_creturn_ret_ty - @c.CReturn(ty1, ty2, ...) → 多返回 struct 类型
#
# 对齐 TPC DeclarationGenerator:CReturn 声明函数返回多个值(如
# GetMemoryStats @c.CReturn(t.CUInt64T, t.CUInt64T, t.CUInt64T) →
# GetMemoryStats @c.CReturn(uint64, uint64, uint64) →
# {i64, i64, i64})。pre_scan 前向声明与 translate_function_def 定义
# 两阶段必须一致,否则 declare i32 + define {i64,i64,i64} → llc
# "ret doesn't match function result type"。
@@ -387,7 +387,7 @@ class FuncGenBase(CallGenBase.CallGenBase):
cr_head: llvmlite.ParamNode | t.CPtr = None
cr_last: llvmlite.ParamNode | t.CPtr = None
cr_count: int = 0
cr_dn: t.CSizeT = len(fd.decorator_list)
cr_dn: sizet = len(fd.decorator_list)
for cdi in range(cr_dn):
deco_cr: ast.AST | t.CPtr = fd.decorator_list.get(cdi)
if deco_cr is None or deco_cr.kind() != ast.ASTKind.Call:
@@ -401,7 +401,7 @@ class FuncGenBase(CallGenBase.CallGenBase):
cr_args: list[ast.AST | t.CPtr] | t.CPtr = deco_call_cr.args
if cr_args is None:
continue
cr_an: t.CSizeT = len(cr_args)
cr_an: sizet = len(cr_args)
for cai in range(cr_an):
cr_aty: llvmlite.LLVMType | t.CPtr = self.Gen.TypeGenResolve.resolve_annotation_type(
pool, cr_args.get(cai), imported_modules, from_imports, trans, 0)
@@ -438,7 +438,7 @@ class FuncGenBase(CallGenBase.CallGenBase):
ags: ast.Arguments | t.CPtr = (ast.Arguments | t.CPtr)(args_node)
if ags.args is not None:
alist: list[ast.AST | t.CPtr] | t.CPtr = ags.args
an: t.CSizeT = len(alist)
an: sizet = len(alist)
i32_ty: llvmlite.LLVMType | t.CPtr = llvmlite.Int32(pool)
for ai in range(an):
arg: ast.Arg | t.CPtr = (ast.Arg | t.CPtr)(alist.get(ai))
+25 -25
View File
@@ -12,9 +12,9 @@ import stdlib
import lib.core.VLogger as VLogger
import lib.core.Gen.Translator as HT
import lib.core.Gen.Call.CallGenBase as CallGenBase
import lib.core.Gen.GenApi as GenApi
import lib.core.Gen.GenApi as GenApi
# ============================================================
# FuncGenDef - FuncGenMixin 拆分(阶段 D):函数声明 / translate_function_def / decorator wrapper
#
@@ -73,7 +73,7 @@ class FuncGenDef(CallGenBase.CallGenBase):
# (_specialize_generic_class 的 Phase B 补译分支)。
saved_declare_only: int = trans._declare_only
trans._declare_only = 1
cn_count: t.CSizeT = len(ch)
cn_count: sizet = len(ch)
# ============================================================
# 预注册当前模块 ClassDef(declare_only 模式,仅 struct+字段+方法声明,
@@ -86,7 +86,7 @@ class FuncGenDef(CallGenBase.CallGenBase):
# 按 AST 序预注册保证同文件类间依赖(class A 引用 class B,B 在后)
# 也能先注册。已完整注册的类(1a 成功 / 依赖方 stub 注入含字段)跳过,
# 交由 translate_children 走 existing 路径,无重复处理副作用。
pre_i: t.CSizeT
pre_i: sizet
for pre_i in range(cn_count):
pre_child: ast.AST | t.CPtr = ch.get(pre_i)
if pre_child is None:
@@ -123,8 +123,8 @@ class FuncGenDef(CallGenBase.CallGenBase):
tp_names_fd = fd.type_params
tp_args_fd: list[str] | t.CPtr = list[str](pool, 8)
if tp_args_fd is not None:
tpn_fd: t.CSizeT = len(fd.type_params)
tpi_fd: t.CSizeT = 0
tpn_fd: sizet = len(fd.type_params)
tpi_fd: sizet = 0
for tpi_fd in range(tpn_fd):
tp_args_fd.append("int")
self.Gen.TypeGenBase.set_generic_context(tp_names_fd, tp_args_fd)
@@ -137,7 +137,7 @@ class FuncGenDef(CallGenBase.CallGenBase):
# 单独 t.CExport 返回注解(def free(...) -> t.CExport:)=
# 导出修饰符,无实际返回类型 → Void(根因:CExport 被 map_t_type
# 回退为 i32 → 掉尾检查强制 return i32,mm.vp free 根因)。
# CExport 混用实际类型(-> t.CExport | t.CInt)时保持解析结果。
# CExport 混用实际类型(-> t.CExport | int)时保持解析结果。
if fd.returns.kind() == ast.ASTKind.Attribute:
ce_at: ast.Attribute | t.CPtr = (ast.Attribute | t.CPtr)(fd.returns)
if ce_at.attr is not None and string.strcmp(ce_at.attr, "CExport") == 0:
@@ -215,7 +215,7 @@ class FuncGenDef(CallGenBase.CallGenBase):
# 注意: 必须先把属性赋给显式类型为 list[...] | t.CPtr 的局部变量再调用 __len__(),
# 否则编译器无法识别属性返回的 list 类型,GEP base 会变成 i32 0 导致 llc 报错
fd_args_node: ast.Arguments | t.CPtr = fd.args
fd_defaults: t.CVoid | t.CPtr = None
fd_defaults: t.CPtr = None
fd_default_count: int = 0
fd_param_count: int = 0
if fd_args_node is not None:
@@ -246,7 +246,7 @@ class FuncGenDef(CallGenBase.CallGenBase):
ags: ast.Arguments | t.CPtr = (ast.Arguments | t.CPtr)(args_node)
if ags.args is not None:
alist: list[ast.AST | t.CPtr] | t.CPtr = ags.args
an: t.CSizeT = len(alist)
an: sizet = len(alist)
for ai in range(an):
arg: ast.Arg | t.CPtr = (ast.Arg | t.CPtr)(alist.get(ai))
if arg is None or arg.arg is None:
@@ -325,7 +325,7 @@ class FuncGenDef(CallGenBase.CallGenBase):
# 单独 t.CExport 返回注解(def free(...) -> t.CExport:)= 导出
# 修饰符,无实际返回类型 → Void(根因:CExport 被 map_t_type 回退
# 为 i32 → 掉尾检查强制 return i32,mm.vp free 根因)。
# 混合实际类型(-> t.CExport | t.CInt)时保持解析结果。
# 混合实际类型(-> t.CExport | int)时保持解析结果。
if fd.returns.kind() == ast.ASTKind.Attribute:
ce_at2: ast.Attribute | t.CPtr = (ast.Attribute | t.CPtr)(fd.returns)
if ce_at2.attr is not None and string.strcmp(ce_at2.attr, "CExport") == 0:
@@ -412,9 +412,9 @@ class FuncGenDef(CallGenBase.CallGenBase):
# decorator_list 中第一个自定义装饰器(Python 最外层),链式嵌套后续扩展。
has_custom_decor: int = 0
decor_handler: str = None
decor_arg0: t.CInt64T = 0
decor_arg0: int64 = 0
if fd.decorator_list is not None:
ddn: t.CSizeT = len(fd.decorator_list)
ddn: sizet = len(fd.decorator_list)
for ddi in range(ddn):
deco: ast.AST | t.CPtr = fd.decorator_list.get(ddi)
if deco is None:
@@ -502,7 +502,7 @@ class FuncGenDef(CallGenBase.CallGenBase):
ags_e: ast.Arguments | t.CPtr = (ast.Arguments | t.CPtr)(args_node_extern)
if ags_e.args is not None:
alist_e: list[ast.AST | t.CPtr] | t.CPtr = ags_e.args
an_e: t.CSizeT = len(alist_e)
an_e: sizet = len(alist_e)
for ai_e in range(an_e):
arg_e: ast.Arg | t.CPtr = (ast.Arg | t.CPtr)(alist_e.get(ai_e))
if arg_e is not None and arg_e.arg is not None:
@@ -586,7 +586,7 @@ class FuncGenDef(CallGenBase.CallGenBase):
llvmlite.function_set_attr_group(func, func_section)
# 提取默认参数信息
tfd_defaults: t.CVoid | t.CPtr = None
tfd_defaults: t.CPtr = None
tfd_default_count: int = 0
tfd_param_count: int = 0
if args_node is not None:
@@ -611,7 +611,7 @@ class FuncGenDef(CallGenBase.CallGenBase):
ags: ast.Arguments | t.CPtr = (ast.Arguments | t.CPtr)(args_node)
if ags.args is not None:
alist: list[ast.AST | t.CPtr] | t.CPtr = ags.args
an: t.CSizeT = len(alist)
an: sizet = len(alist)
for ai in range(an):
arg: ast.Arg | t.CPtr = (ast.Arg | t.CPtr)(alist.get(ai))
if arg is not None and arg.arg is not None:
@@ -754,8 +754,8 @@ class FuncGenDef(CallGenBase.CallGenBase):
tp_names_fn = fd.type_params
tp_args_fn: list[str] | t.CPtr = list[str](pool, 8)
if tp_args_fn is not None:
tpn_fn: t.CSizeT = len(fd.type_params)
tpi_fn: t.CSizeT = 0
tpn_fn: sizet = len(fd.type_params)
tpi_fn: sizet = 0
for tpi_fn in range(tpn_fn):
tp_args_fn.append("int")
self.Gen.TypeGenBase.set_generic_context(tp_names_fn, tp_args_fn)
@@ -765,7 +765,7 @@ class FuncGenDef(CallGenBase.CallGenBase):
ags2: ast.Arguments | t.CPtr = (ast.Arguments | t.CPtr)(args_node)
if ags2.args is not None:
alist2: list[ast.AST | t.CPtr] | t.CPtr = ags2.args
an2: t.CSizeT = len(alist2)
an2: sizet = len(alist2)
for ai2 in range(an2):
arg2: ast.Arg | t.CPtr = (ast.Arg | t.CPtr)(alist2.get(ai2))
if arg2 is not None and arg2.arg is not None:
@@ -899,7 +899,7 @@ class FuncGenDef(CallGenBase.CallGenBase):
# 2. 再预扫描 AnnAssign 为局部变量提前创建 alloca
body: list[ast.AST | t.CPtr] | t.CPtr = fd.children
if body is not None:
bn: t.CSizeT = len(body)
bn: sizet = len(body)
for bi in range(bn):
stmt: ast.AST | t.CPtr = body.get(bi)
if stmt is not None:
@@ -911,7 +911,7 @@ class FuncGenDef(CallGenBase.CallGenBase):
# 翻译函数体
if body is not None:
bn2: t.CSizeT = len(body)
bn2: sizet = len(body)
for bi2 in range(bn2):
stmt2: ast.AST | t.CPtr = body.get(bi2)
if stmt2 is not None:
@@ -927,7 +927,7 @@ class FuncGenDef(CallGenBase.CallGenBase):
last_is_return: int = 0
# 追加89:bn3 提前初始化,避免 body is None 时下方 fail-fast 分支
# 引用未定义的 bn3(追加81 同款 NameError 风险)
bn3: t.CSizeT = 0
bn3: sizet = 0
if body is not None:
bn3 = len(body)
if bn3 > 0:
@@ -1068,7 +1068,7 @@ class FuncGenDef(CallGenBase.CallGenBase):
func_name: str,
wrapper_name: str,
handler_name: str,
decor_arg0: t.CInt64T) -> llvmlite.Function | t.CPtr:
decor_arg0: int64) -> llvmlite.Function | t.CPtr:
"""生成装饰器 wrapper 函数,返回 wrapper 或 None"""
if trans is None or pool is None or mod is None or func is None:
return None
@@ -1087,7 +1087,7 @@ class FuncGenDef(CallGenBase.CallGenBase):
# ---- 收集原函数参数类型(按位置,最多 16 个)----
n_params: int = 0
param_tys: t.CSizeT | t.CPtr = pool.alloc(16 * 8)
param_tys: sizet | t.CPtr = pool.alloc(16 * 8)
if param_tys is None:
return None
string.memset(param_tys, 0, 16 * 8)
@@ -1095,7 +1095,7 @@ class FuncGenDef(CallGenBase.CallGenBase):
while pp is not None:
pty: llvmlite.LLVMType | t.CPtr = llvmlite.param_get_ty(pp)
if pty is not None and n_params < 16:
param_tys[n_params] = t.CSizeT(pty)
param_tys[n_params] = sizet(pty)
n_params += 1
pp = llvmlite.param_get_next(pp)
+88 -88
View File
@@ -106,7 +106,7 @@ class FuncGenMixin(CallGenBase.CallGenBase):
# 类型存入 param_tys 缓冲(CVoid 跳过,与 alloca 创建索引对齐)
imported_modules: str = trans._imported_modules
from_imports: str = trans._from_imports
param_tys: t.CVoid | t.CPtr = pool.alloc(8 * 64)
param_tys: t.CPtr = pool.alloc(8 * 64)
if param_tys is not None:
string.memset(param_tys, 0, 8 * 64)
param_count: int = 0
@@ -114,7 +114,7 @@ class FuncGenMixin(CallGenBase.CallGenBase):
ags_n: ast.Arguments | t.CPtr = (ast.Arguments | t.CPtr)(fd.args)
if ags_n.args is not None:
alist_n: list[ast.AST | t.CPtr] | t.CPtr = ags_n.args
an_n: t.CSizeT = len(alist_n)
an_n: sizet = len(alist_n)
for ai_n in range(an_n):
arg_n: ast.Arg | t.CPtr = (ast.Arg | t.CPtr)(alist_n.get(ai_n))
if arg_n is None or arg_n.arg is None:
@@ -135,8 +135,8 @@ class FuncGenMixin(CallGenBase.CallGenBase):
case _:
pty_n = resolved_n
if param_count < 64 and param_tys is not None:
pty_slot_n: str | t.CPtr = (t.CVoid | t.CPtr)(
t.CUInt64T(param_tys) + param_count * 8)
pty_slot_n: str | t.CPtr = (t.CPtr)(
uint64(param_tys) + param_count * 8)
pty_slot_n[0] = pty_n
pname_n: str = pool.alloc(32)
if pname_n is not None:
@@ -170,7 +170,7 @@ class FuncGenMixin(CallGenBase.CallGenBase):
if ags_p.args is not None:
alist_p: list[ast.AST | t.CPtr] | t.CPtr = ags_p.args
idx_p: int = 0
apn: t.CSizeT = len(alist_p)
apn: sizet = len(alist_p)
for api in range(apn):
arg_p: ast.Arg | t.CPtr = (ast.Arg | t.CPtr)(alist_p.get(api))
if arg_p is None or arg_p.arg is None:
@@ -182,8 +182,8 @@ class FuncGenMixin(CallGenBase.CallGenBase):
break
pty2_n: llvmlite.LLVMType | t.CPtr = i32_ty
if param_tys is not None:
ty_addr_n: t.CUInt64T = t.CUInt64T(param_tys) + idx_p * 8
ty_slot_n: str | t.CPtr = (t.CVoid | t.CPtr)(ty_addr_n)
ty_addr_n: uint64 = uint64(param_tys) + idx_p * 8
ty_slot_n: str | t.CPtr = (t.CPtr)(ty_addr_n)
pty2_n = (llvmlite.LLVMType | t.CPtr)(ty_slot_n[0])
if pty2_n is None:
pty2_n = i32_ty
@@ -213,8 +213,8 @@ class FuncGenMixin(CallGenBase.CallGenBase):
# nonlocal 集合独立缓冲:嵌套函数注册 nonlocal 写入共享缓冲 [0] 会
# 覆盖父函数集合(ClosureTest2 Test 7 不同变量场景:level2 的 b 覆盖
# level1 的 a → level1 env[0] 存错)。嵌套函数用独立缓冲,翻译完恢复。
saved_nl_names: t.CVoid | t.CPtr = trans._nonlocal_names
saved_nl_types: t.CVoid | t.CPtr = trans._nonlocal_types
saved_nl_names: t.CPtr = trans._nonlocal_names
saved_nl_types: t.CPtr = trans._nonlocal_types
# 7. 切换到嵌套函数作用域 + 清空 scope names
trans._cur_func = func
@@ -234,7 +234,7 @@ class FuncGenMixin(CallGenBase.CallGenBase):
# b. 再预扫描 AnnAssign 为局部变量提前创建 alloca
body: list[ast.AST | t.CPtr] | t.CPtr = fd.children
if body is not None:
bn: t.CSizeT = len(body)
bn: sizet = len(body)
for bi in range(bn):
stmt: ast.AST | t.CPtr = body.get(bi)
if stmt is not None:
@@ -250,7 +250,7 @@ class FuncGenMixin(CallGenBase.CallGenBase):
# 分支内 AnnAssign 局部已由 pre_scan_allocas 递归预注册
# (StmtGenDeclMixin),本扫描经 lookup_current 自然排除。
if body is not None:
bnc: t.CSizeT = len(body)
bnc: sizet = len(body)
for bic in range(bnc):
stmtc: ast.AST | t.CPtr = body.get(bic)
if stmtc is not None:
@@ -258,7 +258,7 @@ class FuncGenMixin(CallGenBase.CallGenBase):
# 9. 翻译函数体(Nonlocal 语句会填充 _nonlocal_names)
if body is not None:
bn2: t.CSizeT = len(body)
bn2: sizet = len(body)
for bi2 in range(bn2):
stmt2: ast.AST | t.CPtr = body.get(bi2)
if stmt2 is not None:
@@ -267,7 +267,7 @@ class FuncGenMixin(CallGenBase.CallGenBase):
# 10. 隐式 ret
last_is_return: int = 0
if body is not None:
bn3: t.CSizeT = len(body)
bn3: sizet = len(body)
if bn3 > 0:
last_stmt: ast.AST | t.CPtr = body.get(bn3 - 1)
if last_stmt is not None and last_stmt.kind() == ast.ASTKind.Return:
@@ -301,7 +301,7 @@ class FuncGenMixin(CallGenBase.CallGenBase):
# 每个 nonlocal 变量占 8 字节(i8*),指向父函数的 alloca(共享存储)
env_ptr: llvmlite.Value | t.CPtr = None
if nested_nonlocal_count > 0:
env_size: t.CInt64T = nested_nonlocal_count * 8
env_size: int64 = nested_nonlocal_count * 8
env_size_val: llvmlite.Value | t.CPtr = llvmlite.const_int64(pool, env_size)
if env_size_val is not None:
env_size_val.Next = None
@@ -322,8 +322,8 @@ class FuncGenMixin(CallGenBase.CallGenBase):
i8_ptr_ptr_ty: llvmlite.LLVMType | t.CPtr = llvmlite.Ptr(pool, i8_ptr_ty)
for ni in range(nested_nonlocal_count):
# 从 _nonlocal_names 缓冲区读取名称
name_addr: t.CUInt64T = t.CUInt64T(trans._nonlocal_names) + ni * 8
nl_slot: str | t.CPtr = (t.CVoid | t.CPtr)(name_addr)
name_addr: uint64 = uint64(trans._nonlocal_names) + ni * 8
nl_slot: str | t.CPtr = (t.CPtr)(name_addr)
nl_name: str = nl_slot[0]
if nl_name is None:
continue
@@ -351,7 +351,7 @@ class FuncGenMixin(CallGenBase.CallGenBase):
parent_builder, nl_load_ty, local_alloca)
# 堆存储大小按类型字节数:数组(如 [4 x i32]=16 字节)
# 不能固定 8 字节(越界写崩溃);指针/标量 ≥ 8 字节
st_size: t.CInt = self._type_byte_size(pool, nl_load_ty)
st_size: int = self._type_byte_size(pool, nl_load_ty)
st_size_val: llvmlite.Value | t.CPtr = llvmlite.const_int64(
pool, st_size)
if st_size_val is not None:
@@ -518,7 +518,7 @@ class FuncGenMixin(CallGenBase.CallGenBase):
mod_gv: llvmlite.Value | t.CPtr = self.Gen.VarGen.lookup_module_var(
trans.SymTab, nm.id)
if mod_gv is not None:
if t.CUInt64T(mod_gv) == t.CUInt64T(ve.Alloca):
if uint64(mod_gv) == uint64(ve.Alloca):
return 1
# 外层函数局部变量 → 隐式捕获(注册为 nonlocal)
GenApi.add_nonlocal_name(trans, nm.id, nl_ty)
@@ -547,11 +547,11 @@ class FuncGenMixin(CallGenBase.CallGenBase):
if ifn.test is not None:
self._closure_scan_captures(trans, ifn.test)
if ifn.children is not None:
bn_if: t.CSizeT = len(ifn.children)
bn_if: sizet = len(ifn.children)
for bi_if in range(bn_if):
self._closure_scan_captures(trans, ifn.children.get(bi_if))
if ifn.orelse is not None:
bn_el: t.CSizeT = len(ifn.orelse)
bn_el: sizet = len(ifn.orelse)
for bi_el in range(bn_el):
self._closure_scan_captures(trans, ifn.orelse.get(bi_el))
return 1
@@ -561,11 +561,11 @@ class FuncGenMixin(CallGenBase.CallGenBase):
if for_n.iter is not None:
self._closure_scan_captures(trans, for_n.iter)
if for_n.children is not None:
bn_f: t.CSizeT = len(for_n.children)
bn_f: sizet = len(for_n.children)
for bi_f in range(bn_f):
self._closure_scan_captures(trans, for_n.children.get(bi_f))
if for_n.orelse is not None:
bn_fe: t.CSizeT = len(for_n.orelse)
bn_fe: sizet = len(for_n.orelse)
for bi_fe in range(bn_fe):
self._closure_scan_captures(trans, for_n.orelse.get(bi_fe))
return 1
@@ -574,11 +574,11 @@ class FuncGenMixin(CallGenBase.CallGenBase):
if wh_n.test is not None:
self._closure_scan_captures(trans, wh_n.test)
if wh_n.children is not None:
bn_w: t.CSizeT = len(wh_n.children)
bn_w: sizet = len(wh_n.children)
for bi_w in range(bn_w):
self._closure_scan_captures(trans, wh_n.children.get(bi_w))
if wh_n.orelse is not None:
bn_we: t.CSizeT = len(wh_n.orelse)
bn_we: sizet = len(wh_n.orelse)
for bi_we in range(bn_we):
self._closure_scan_captures(trans, wh_n.orelse.get(bi_we))
return 1
@@ -595,7 +595,7 @@ class FuncGenMixin(CallGenBase.CallGenBase):
if k == ast.ASTKind.With:
wth: ast.With | t.CPtr = (ast.With | t.CPtr)(node)
if wth.items is not None:
bn_wi: t.CSizeT = len(wth.items)
bn_wi: sizet = len(wth.items)
for bi_wi in range(bn_wi):
wi_n: ast.AST | t.CPtr = wth.items.get(bi_wi)
if wi_n is not None and wi_n.kind() == ast.ASTKind.WithItem:
@@ -603,7 +603,7 @@ class FuncGenMixin(CallGenBase.CallGenBase):
if wi_c.context_expr is not None:
self._closure_scan_captures(trans, wi_c.context_expr)
if wth.children is not None:
bn_wb: t.CSizeT = len(wth.children)
bn_wb: sizet = len(wth.children)
for bi_wb in range(bn_wb):
self._closure_scan_captures(trans, wth.children.get(bi_wb))
return 1
@@ -624,25 +624,25 @@ class FuncGenMixin(CallGenBase.CallGenBase):
if k == ast.ASTKind.Try:
tr_n: ast.Try | t.CPtr = (ast.Try | t.CPtr)(node)
if tr_n.children is not None:
bn_t: t.CSizeT = len(tr_n.children)
bn_t: sizet = len(tr_n.children)
for bi_t in range(bn_t):
self._closure_scan_captures(trans, tr_n.children.get(bi_t))
if tr_n.handlers is not None:
bn_th: t.CSizeT = len(tr_n.handlers)
bn_th: sizet = len(tr_n.handlers)
for bi_th in range(bn_th):
eh_n: ast.AST | t.CPtr = tr_n.handlers.get(bi_th)
if eh_n is not None and eh_n.kind() == ast.ASTKind.ExceptHandler:
eh_c: ast.ExceptHandler | t.CPtr = (ast.ExceptHandler | t.CPtr)(eh_n)
if eh_c.children is not None:
bn_ehb: t.CSizeT = len(eh_c.children)
bn_ehb: sizet = len(eh_c.children)
for bi_ehb in range(bn_ehb):
self._closure_scan_captures(trans, eh_c.children.get(bi_ehb))
if tr_n.orelse is not None:
bn_to: t.CSizeT = len(tr_n.orelse)
bn_to: sizet = len(tr_n.orelse)
for bi_to in range(bn_to):
self._closure_scan_captures(trans, tr_n.orelse.get(bi_to))
if tr_n.finalbody is not None:
bn_tf: t.CSizeT = len(tr_n.finalbody)
bn_tf: sizet = len(tr_n.finalbody)
for bi_tf in range(bn_tf):
self._closure_scan_captures(trans, tr_n.finalbody.get(bi_tf))
return 1
@@ -651,7 +651,7 @@ class FuncGenMixin(CallGenBase.CallGenBase):
if mt_n.subject is not None:
self._closure_scan_captures(trans, mt_n.subject)
if mt_n.cases is not None:
bn_mc: t.CSizeT = len(mt_n.cases)
bn_mc: sizet = len(mt_n.cases)
for bi_mc in range(bn_mc):
mc_n: ast.AST | t.CPtr = mt_n.cases.get(bi_mc)
if mc_n is not None and mc_n.kind() == ast.ASTKind.MatchCase:
@@ -659,7 +659,7 @@ class FuncGenMixin(CallGenBase.CallGenBase):
if mc_c.guard is not None:
self._closure_scan_captures(trans, mc_c.guard)
if mc_c.children is not None:
bn_mcb: t.CSizeT = len(mc_c.children)
bn_mcb: sizet = len(mc_c.children)
for bi_mcb in range(bn_mcb):
self._closure_scan_captures(trans, mc_c.children.get(bi_mcb))
return 1
@@ -679,7 +679,7 @@ class FuncGenMixin(CallGenBase.CallGenBase):
if k == ast.ASTKind.BoolOp:
bop2: ast.BoolOp | t.CPtr = (ast.BoolOp | t.CPtr)(node)
if bop2.values is not None:
bn_bo: t.CSizeT = len(bop2.values)
bn_bo: sizet = len(bop2.values)
for bi_bo in range(bn_bo):
self._closure_scan_captures(trans, bop2.values.get(bi_bo))
return 1
@@ -688,7 +688,7 @@ class FuncGenMixin(CallGenBase.CallGenBase):
if cmp.left is not None:
self._closure_scan_captures(trans, cmp.left)
if cmp.comparators is not None:
bn_cmp: t.CSizeT = len(cmp.comparators)
bn_cmp: sizet = len(cmp.comparators)
for bi_cmp in range(bn_cmp):
self._closure_scan_captures(trans, cmp.comparators.get(bi_cmp))
return 1
@@ -697,11 +697,11 @@ class FuncGenMixin(CallGenBase.CallGenBase):
if cal.func is not None:
self._closure_scan_captures(trans, cal.func)
if cal.args is not None:
bn_ca: t.CSizeT = len(cal.args)
bn_ca: sizet = len(cal.args)
for bi_ca in range(bn_ca):
self._closure_scan_captures(trans, cal.args.get(bi_ca))
if cal.keywords is not None:
bn_ck: t.CSizeT = len(cal.keywords)
bn_ck: sizet = len(cal.keywords)
for bi_ck in range(bn_ck):
kw_n: ast.AST | t.CPtr = cal.keywords.get(bi_ck)
if kw_n is not None and kw_n.kind() == ast.ASTKind.Keyword:
@@ -733,32 +733,32 @@ class FuncGenMixin(CallGenBase.CallGenBase):
if k == ast.ASTKind.Dict:
dc: ast.Dict | t.CPtr = (ast.Dict | t.CPtr)(node)
if dc.keys is not None:
bn_dk: t.CSizeT = len(dc.keys)
bn_dk: sizet = len(dc.keys)
for bi_dk in range(bn_dk):
self._closure_scan_captures(trans, dc.keys.get(bi_dk))
if dc.values is not None:
bn_dv: t.CSizeT = len(dc.values)
bn_dv: sizet = len(dc.values)
for bi_dv in range(bn_dv):
self._closure_scan_captures(trans, dc.values.get(bi_dv))
return 1
if k == ast.ASTKind.Set:
st_n: ast.Set | t.CPtr = (ast.Set | t.CPtr)(node)
if st_n.elts is not None:
bn_set: t.CSizeT = len(st_n.elts)
bn_set: sizet = len(st_n.elts)
for bi_set in range(bn_set):
self._closure_scan_captures(trans, st_n.elts.get(bi_set))
return 1
if k == ast.ASTKind.List:
ls_n: ast.List | t.CPtr = (ast.List | t.CPtr)(node)
if ls_n.elts is not None:
bn_ls: t.CSizeT = len(ls_n.elts)
bn_ls: sizet = len(ls_n.elts)
for bi_ls in range(bn_ls):
self._closure_scan_captures(trans, ls_n.elts.get(bi_ls))
return 1
if k == ast.ASTKind.Tuple:
tp_n: ast.Tuple | t.CPtr = (ast.Tuple | t.CPtr)(node)
if tp_n.elts is not None:
bn_tp: t.CSizeT = len(tp_n.elts)
bn_tp: sizet = len(tp_n.elts)
for bi_tp in range(bn_tp):
self._closure_scan_captures(trans, tp_n.elts.get(bi_tp))
return 1
@@ -784,7 +784,7 @@ class FuncGenMixin(CallGenBase.CallGenBase):
if k == ast.ASTKind.JoinedStr:
js_n: ast.JoinedStr | t.CPtr = (ast.JoinedStr | t.CPtr)(node)
if js_n.values is not None:
bn_js: t.CSizeT = len(js_n.values)
bn_js: sizet = len(js_n.values)
for bi_js in range(bn_js):
self._closure_scan_captures(trans, js_n.values.get(bi_js))
return 1
@@ -822,7 +822,7 @@ class FuncGenMixin(CallGenBase.CallGenBase):
if lc_n.elt is not None:
self._closure_scan_captures(trans, lc_n.elt)
if lc_n.generators is not None:
bn_gen: t.CSizeT = len(lc_n.generators)
bn_gen: sizet = len(lc_n.generators)
for bi_gen in range(bn_gen):
cp_n: ast.AST | t.CPtr = lc_n.generators.get(bi_gen)
if cp_n is not None and cp_n.kind() == ast.ASTKind.Comprehension:
@@ -830,7 +830,7 @@ class FuncGenMixin(CallGenBase.CallGenBase):
if cp_c.iter is not None:
self._closure_scan_captures(trans, cp_c.iter)
if cp_c.ifs is not None:
bn_cpi: t.CSizeT = len(cp_c.ifs)
bn_cpi: sizet = len(cp_c.ifs)
for bi_cpi in range(bn_cpi):
self._closure_scan_captures(trans, cp_c.ifs.get(bi_cpi))
return 1
@@ -841,7 +841,7 @@ class FuncGenMixin(CallGenBase.CallGenBase):
if dcn.value is not None:
self._closure_scan_captures(trans, dcn.value)
if dcn.generators is not None:
bn_dgen: t.CSizeT = len(dcn.generators)
bn_dgen: sizet = len(dcn.generators)
for bi_dgen in range(bn_dgen):
cp_dn: ast.AST | t.CPtr = dcn.generators.get(bi_dgen)
if cp_dn is not None and cp_dn.kind() == ast.ASTKind.Comprehension:
@@ -849,7 +849,7 @@ class FuncGenMixin(CallGenBase.CallGenBase):
if cp_dc.iter is not None:
self._closure_scan_captures(trans, cp_dc.iter)
if cp_dc.ifs is not None:
bn_dcpi: t.CSizeT = len(cp_dc.ifs)
bn_dcpi: sizet = len(cp_dc.ifs)
for bi_dcpi in range(bn_dcpi):
self._closure_scan_captures(trans, cp_dc.ifs.get(bi_dcpi))
return 1
@@ -864,13 +864,13 @@ class FuncGenMixin(CallGenBase.CallGenBase):
# ClosureTest2 Test 4 非local 数组崩溃根因)。未知类型保守返回 8。
# ============================================================
def _type_byte_size(self, pool: memhub.MemBuddy | t.CPtr,
ty: llvmlite.LLVMType | t.CPtr) -> t.CInt:
ty: llvmlite.LLVMType | t.CPtr) -> int:
"""计算 LLVM 类型占用的字节大小(递归),未知类型返回 8"""
if ty is None:
return 8
match ty:
case llvmlite.LLVMType.Int(bits):
sz_i: t.CInt = (bits + 7) // 8
sz_i: int = (bits + 7) // 8
if sz_i < 8:
sz_i = 8
return sz_i
@@ -883,7 +883,7 @@ class FuncGenMixin(CallGenBase.CallGenBase):
return 16
return 4
case llvmlite.LLVMType.Array(et, cnt):
esz: t.CInt = self._type_byte_size(pool, et)
esz: int = self._type_byte_size(pool, et)
return esz * cnt
case _:
return 8
@@ -949,7 +949,7 @@ class FuncGenMixin(CallGenBase.CallGenBase):
# ============================================================
def _collect_chain_nonlocals(self, trans: HT.Translator | t.CPtr,
node: ast.AST | t.CPtr,
names: t.CVoid | t.CPtr,
names: t.CPtr,
count: int) -> int:
"""递归收集 node(FunctionDef)链内所有 nonlocal 声明名(去重)"""
if node is None or names is None:
@@ -958,7 +958,7 @@ class FuncGenMixin(CallGenBase.CallGenBase):
if fd is None or fd.children is None:
return count
ch: list[ast.AST | t.CPtr] | t.CPtr = fd.children
cn: t.CSizeT = len(ch)
cn: sizet = len(ch)
for ci in range(cn):
st: ast.AST | t.CPtr = ch.get(ci)
if st is None:
@@ -970,7 +970,7 @@ class FuncGenMixin(CallGenBase.CallGenBase):
nl_node: ast.Nonlocal | t.CPtr = (ast.Nonlocal | t.CPtr)(st)
if nl_node is not None and nl_node.names is not None:
nl_list: list[ast.AST | t.CPtr] | t.CPtr = nl_node.names
nn: t.CSizeT = len(nl_list)
nn: sizet = len(nl_list)
for ni in range(nn):
nm_node: ast.AST | t.CPtr = nl_list.get(ni)
if nm_node is None:
@@ -981,12 +981,12 @@ class FuncGenMixin(CallGenBase.CallGenBase):
dup: int = 0
for di in range(count):
if string.strcmp((str)(
t.CUInt64T(names) + di * 8), nm_x.id) == 0:
uint64(names) + di * 8), nm_x.id) == 0:
dup = 1
break
if dup == 0 and count < 64:
nm_slot: str | t.CPtr = (t.CVoid | t.CPtr)(
t.CUInt64T(names) + count * 8)
nm_slot: str | t.CPtr = (t.CPtr)(
uint64(names) + count * 8)
nm_slot[0] = nm_x.id
count += 1
return count
@@ -1025,8 +1025,8 @@ class FuncGenMixin(CallGenBase.CallGenBase):
trans, node, trans._nl_chain_names, 0)
trans._nl_chain_done = 1
for ci in range(trans._nl_chain_count):
nm_slot: str | t.CPtr = (t.CVoid | t.CPtr)(
t.CUInt64T(trans._nl_chain_names) + ci * 8)
nm_slot: str | t.CPtr = (t.CPtr)(
uint64(trans._nl_chain_names) + ci * 8)
nl_name: str = nm_slot[0]
if nl_name is None:
continue
@@ -1047,7 +1047,7 @@ class FuncGenMixin(CallGenBase.CallGenBase):
# 运行时 @nlheap.* 保持上一函数的堆地址,env 读到错堆。
# ClosureTest2 Test 7 根因)。映射变量仅首次 add(模块去重),
# store 指令每次照发。
st_size: t.CInt = self._type_byte_size(pool, nl_ty)
st_size: int = self._type_byte_size(pool, nl_ty)
st_size_val: llvmlite.Value | t.CPtr = llvmlite.const_int64(pool, st_size)
if st_size_val is not None:
st_size_val.Next = None
@@ -1137,7 +1137,7 @@ class FuncGenMixin(CallGenBase.CallGenBase):
if param_names is None:
return None
string.memset(param_names, 0, 32 * 64)
param_tys: t.CVoid | t.CPtr = pool.alloc(8 * 64) # LLVMType 指针槽
param_tys: t.CPtr = pool.alloc(8 * 64) # LLVMType 指针槽
if param_tys is None:
return None
string.memset(param_tys, 0, 8 * 64)
@@ -1146,7 +1146,7 @@ class FuncGenMixin(CallGenBase.CallGenBase):
ags: ast.Arguments | t.CPtr = (ast.Arguments | t.CPtr)(lam.args)
if ags.args is not None:
alist: list[ast.AST | t.CPtr] | t.CPtr = ags.args
pn: t.CSizeT = len(alist)
pn: sizet = len(alist)
for pi in range(pn):
if param_count >= 64:
break
@@ -1172,8 +1172,8 @@ class FuncGenMixin(CallGenBase.CallGenBase):
p_ty = llvmlite.Ptr(pool, aelem_ty_l)
case _:
p_ty = resolved
ty_slot_p: str | t.CPtr = (t.CVoid | t.CPtr)(
t.CUInt64T(param_tys) + param_count * 8)
ty_slot_p: str | t.CPtr = (t.CPtr)(
uint64(param_tys) + param_count * 8)
ty_slot_p[0] = p_ty
param_count += 1
@@ -1182,11 +1182,11 @@ class FuncGenMixin(CallGenBase.CallGenBase):
if cap_names is None:
return None
string.memset(cap_names, 0, 64 * 64)
cap_allocas: t.CVoid | t.CPtr = pool.alloc(8 * 64) # 父函数 alloca 指针槽
cap_allocas: t.CPtr = pool.alloc(8 * 64) # 父函数 alloca 指针槽
if cap_allocas is None:
return None
string.memset(cap_allocas, 0, 8 * 64)
cap_tys: t.CVoid | t.CPtr = pool.alloc(8 * 64) # 捕获变量类型槽
cap_tys: t.CPtr = pool.alloc(8 * 64) # 捕获变量类型槽
if cap_tys is None:
return None
string.memset(cap_tys, 0, 8 * 64)
@@ -1201,8 +1201,8 @@ class FuncGenMixin(CallGenBase.CallGenBase):
return None
llvmlite.add_param(pool, func, i8_ptr_ty, "%env")
for pi2 in range(param_count):
ty_addr2: t.CUInt64T = t.CUInt64T(param_tys) + pi2 * 8
ty_slot2: str | t.CPtr = (t.CVoid | t.CPtr)(ty_addr2)
ty_addr2: uint64 = uint64(param_tys) + pi2 * 8
ty_slot2: str | t.CPtr = (t.CPtr)(ty_addr2)
p_ty2: llvmlite.LLVMType | t.CPtr = (llvmlite.LLVMType | t.CPtr)(ty_slot2[0])
if p_ty2 is None:
p_ty2 = i32_ty
@@ -1250,8 +1250,8 @@ class FuncGenMixin(CallGenBase.CallGenBase):
cap_slot: str = cap_names + ci * 64
if cap_slot[0] == '\0':
continue
ty_addr3: t.CUInt64T = t.CUInt64T(cap_tys) + ci * 8
ty_slot3: str | t.CPtr = (t.CVoid | t.CPtr)(ty_addr3)
ty_addr3: uint64 = uint64(cap_tys) + ci * 8
ty_slot3: str | t.CPtr = (t.CPtr)(ty_addr3)
cap_ty: llvmlite.LLVMType | t.CPtr = (llvmlite.LLVMType | t.CPtr)(ty_slot3[0])
if cap_ty is None:
continue
@@ -1279,8 +1279,8 @@ class FuncGenMixin(CallGenBase.CallGenBase):
# 10. 参数 alloca
for pi3 in range(param_count):
ty_addr4: t.CUInt64T = t.CUInt64T(param_tys) + pi3 * 8
ty_slot4: str | t.CPtr = (t.CVoid | t.CPtr)(ty_addr4)
ty_addr4: uint64 = uint64(param_tys) + pi3 * 8
ty_slot4: str | t.CPtr = (t.CPtr)(ty_addr4)
p_ty3: llvmlite.LLVMType | t.CPtr = (llvmlite.LLVMType | t.CPtr)(ty_slot4[0])
if p_ty3 is None:
# fail-fast:lambda 参数类型槽缺失(内部状态不一致),不再静默保持 i32
@@ -1327,7 +1327,7 @@ class FuncGenMixin(CallGenBase.CallGenBase):
# 13. 在父函数中创建 env(每个捕获变量 8 字节堆存储,env[i] = 堆地址)
env_ptr: llvmlite.Value | t.CPtr = None
if cap_count > 0:
env_size: t.CInt64T = cap_count * 8
env_size: int64 = cap_count * 8
env_size_val: llvmlite.Value | t.CPtr = llvmlite.const_int64(pool, env_size)
if env_size_val is not None:
env_size_val.Next = None
@@ -1339,14 +1339,14 @@ class FuncGenMixin(CallGenBase.CallGenBase):
cap_slot3: str = cap_names + ci3 * 64
if cap_slot3[0] == '\0':
continue
al_addr: t.CUInt64T = t.CUInt64T(cap_allocas) + ci3 * 8
al_slot: str | t.CPtr = (t.CVoid | t.CPtr)(al_addr)
al_addr: uint64 = uint64(cap_allocas) + ci3 * 8
al_slot: str | t.CPtr = (t.CPtr)(al_addr)
var_alloca2: llvmlite.Value | t.CPtr = (
llvmlite.Value | t.CPtr)(al_slot[0])
if var_alloca2 is None:
continue
ty_addr5: t.CUInt64T = t.CUInt64T(cap_tys) + ci3 * 8
ty_slot5: str | t.CPtr = (t.CVoid | t.CPtr)(ty_addr5)
ty_addr5: uint64 = uint64(cap_tys) + ci3 * 8
ty_slot5: str | t.CPtr = (t.CPtr)(ty_addr5)
cap_ty2: llvmlite.LLVMType | t.CPtr = (
llvmlite.LLVMType | t.CPtr)(ty_slot5[0])
if cap_ty2 is None:
@@ -1434,8 +1434,8 @@ class FuncGenMixin(CallGenBase.CallGenBase):
param_names: str,
param_count: int,
cap_names: str,
cap_allocas: t.CVoid | t.CPtr,
cap_tys: t.CVoid | t.CPtr,
cap_allocas: t.CPtr,
cap_tys: t.CPtr,
cap_count: int) -> int:
"""递归扫描 lambda body 中的 Name 引用,收集捕获变量"""
if node is None or trans is None:
@@ -1463,16 +1463,16 @@ class FuncGenMixin(CallGenBase.CallGenBase):
# 跳过模块级全局(body 直接解析全局,无需 env 捕获)
mod_gv: llvmlite.Value | t.CPtr = self.Gen.VarGen.lookup_module_var(trans.SymTab, nm.id)
if mod_gv is not None:
if t.CUInt64T(mod_gv) == t.CUInt64T(alloca):
if uint64(mod_gv) == uint64(alloca):
return cap_count
if cap_count >= 64:
return cap_count
string.strncpy(cap_names + cap_count * 64, nm.id, 63)
al_slot: str | t.CPtr = (t.CVoid | t.CPtr)(
t.CUInt64T(cap_allocas) + cap_count * 8)
al_slot: str | t.CPtr = (t.CPtr)(
uint64(cap_allocas) + cap_count * 8)
al_slot[0] = alloca
ty_slot: str | t.CPtr = (t.CVoid | t.CPtr)(
t.CUInt64T(cap_tys) + cap_count * 8)
ty_slot: str | t.CPtr = (t.CPtr)(
uint64(cap_tys) + cap_count * 8)
ty_slot[0] = pointee
return cap_count + 1
# 递归遍历常见表达式子节点
@@ -1491,7 +1491,7 @@ class FuncGenMixin(CallGenBase.CallGenBase):
cc2: int = cap_count
if bop2.values is not None:
vs: list[ast.AST | t.CPtr] | t.CPtr = bop2.values
vn: t.CSizeT = len(vs)
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)
@@ -1502,7 +1502,7 @@ class FuncGenMixin(CallGenBase.CallGenBase):
cap_names, cap_allocas, cap_tys, cap_count)
if cmp.comparators is not None:
cl: list[ast.AST | t.CPtr] | t.CPtr = cmp.comparators
cn: t.CSizeT = len(cl)
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)
@@ -1513,13 +1513,13 @@ class FuncGenMixin(CallGenBase.CallGenBase):
cap_names, cap_allocas, cap_tys, cap_count)
if cal.args is not None:
als: list[ast.AST | t.CPtr] | t.CPtr = cal.args
an: t.CSizeT = len(als)
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)
if cal.keywords is not None:
kws: list[ast.AST | t.CPtr] | t.CPtr = cal.keywords
kn: t.CSizeT = len(kws)
kn: sizet = len(kws)
for ki in range(kn):
kw: ast.Keyword | t.CPtr = (ast.Keyword | t.CPtr)(kws.get(ki))
if kw is not None and kw.value is not None:
@@ -1551,7 +1551,7 @@ class FuncGenMixin(CallGenBase.CallGenBase):
cc7: int = cap_count
if ls.elts is not None:
es: list[ast.AST | t.CPtr] | t.CPtr = ls.elts
en: t.CSizeT = len(es)
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)
+168 -306
View File
@@ -6,7 +6,7 @@ import memhub
import lib.core.Gen.GenTypes as GenTypes
import lib.core.Gen.Generator as Generator
import lib.core.Gen.Translator as HT
import lib.core.Gen.Generator as Generator
# ============================================================
# GenApi - 管线/保留文件访问 Gen 的模块级委托入口(去除 Handles 层)
@@ -17,98 +17,78 @@ import lib.core.Gen.Translator as HT
# 全局 gen 单例(main/BuildPipeline 创建 gen 后注入)
_g_gen: Generator.Generator | t.CPtr = None
_g_gen: rowptr[Generator.Generator] = None
# ---------------- set_temp_dir(委托 TypeGenBase.set_temp_dir) ----------------
def set_temp_dir(temp_dir: str) -> None:
"""委托到 gen.set_temp_dir(原 Handles 壳)"""
import lib.core.Gen.Generator as Generator
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.TypeGenBase.set_temp_dir(temp_dir)
if _g_gen is not None:
_g_gen.TypeGenBase.set_temp_dir(temp_dir)
# ---------------- set_current_file_imports(委托 ImportsGenMixin.set_current_file) ----------------
def set_current_file_imports(file_path: str) -> None:
"""委托到 gen.set_current_file(原 Handles 壳)"""
import lib.core.Gen.Generator as Generator
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.ImportsGen.set_current_file(file_path)
if _g_gen is not None:
_g_gen.ImportsGen.set_current_file(file_path)
# ---------------- set_current_file_type(委托 TypeGenResolve.set_current_file) ----------------
def set_current_file_type(file_path: str) -> None:
"""委托到 gen.set_current_file(原 Handles 壳)"""
import lib.core.Gen.Generator as Generator
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.TypeGenResolve.set_current_file(file_path)
if _g_gen is not None:
_g_gen.TypeGenResolve.set_current_file(file_path)
# ---------------- set_current_module_sha1(委托 TypeGenBase.set_current_module_sha1) ----------------
def set_current_module_sha1(sha1: str) -> None:
"""委托到 gen.set_current_module_sha1(原 Handles 壳)"""
import lib.core.Gen.Generator as Generator
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.TypeGenBase.set_current_module_sha1(sha1)
if _g_gen is not None:
_g_gen.TypeGenBase.set_current_module_sha1(sha1)
# ---------------- clear_trace(委托 TypeGenBase.clear_trace) ----------------
def clear_trace() -> None:
"""委托到 gen.clear_trace(原 Handles 壳)"""
import lib.core.Gen.Generator as Generator
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.TypeGenBase.clear_trace()
if _g_gen is not None:
_g_gen.TypeGenBase.clear_trace()
# ---------------- clear_cdefine_constants(委托 TypeGenCDef.clear_cdefine_constants) ----------------
def clear_cdefine_constants() -> None:
"""委托到 gen.clear_cdefine_constants(原 Handles 壳)"""
import lib.core.Gen.Generator as Generator
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.TypeGenCDef.clear_cdefine_constants()
if _g_gen is not None:
_g_gen.TypeGenCDef.clear_cdefine_constants()
# ---------------- clear_ctypedefs(委托 TypeGenCType.clear_ctypedefs) ----------------
def clear_ctypedefs() -> None:
"""委托到 gen.clear_ctypedefs(原 Handles 壳)"""
import lib.core.Gen.Generator as Generator
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.TypeGenCType.clear_ctypedefs()
if _g_gen is not None:
_g_gen.TypeGenCType.clear_ctypedefs()
# ---------------- RegisterCTypedefFromSource(委托 TypeGenCType.register_ctypedef_from_source) ----------------
def RegisterCTypedefFromSource(pool: memhub.MemBuddy | t.CPtr, src: str) -> int:
"""委托到 gen.register_ctypedef_from_source(原 Handles 壳)"""
import lib.core.Gen.Generator as Generator
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.TypeGenCType.register_ctypedef_from_source(pool, src)
if _g_gen is not None:
_g_gen.TypeGenCType.register_ctypedef_from_source(pool, src)
return 0
# ---------------- dump_parse_traceback(委托 TypeGenErr.dump_parse_traceback) ----------------
def dump_parse_traceback(file_path: str) -> None:
"""委托到 gen.dump_parse_traceback(原 Handles 壳)"""
import lib.core.Gen.Generator as Generator
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.TypeGenErr.dump_parse_traceback(file_path)
if _g_gen is not None:
_g_gen.TypeGenErr.dump_parse_traceback(file_path)
# ---------------- map_t_type(委托 TypeGenResolve.map_t_type) ----------------
def map_t_type(pool: memhub.MemBuddy | t.CPtr, type_name: str) -> llvmlite.LLVMType | t.CPtr:
"""委托到 gen.map_t_type(原 Handles 壳)"""
import lib.core.Gen.Generator as Generator
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.TypeGenResolve.map_t_type(pool, type_name)
if _g_gen is not None:
_g_gen.TypeGenResolve.map_t_type(pool, type_name)
return None
@@ -119,10 +99,8 @@ def resolve_typedef_or_map(pool: memhub.MemBuddy | t.CPtr,
from_imports: str,
trans: HT.Translator | t.CPtr = None) -> llvmlite.LLVMType | t.CPtr:
"""委托到 gen.resolve_typedef_or_map(CTypedef 动态表优先,miss 回退 map_t_type)"""
import lib.core.Gen.Generator as Generator
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.TypeGenResolve.resolve_typedef_or_map(pool, name, imported_modules, from_imports, trans)
if _g_gen is not None:
return _g_gen.TypeGenResolve.resolve_typedef_or_map(pool, name, imported_modules, from_imports, trans)
return None
@@ -137,40 +115,32 @@ def infer_external_func_ret_ty(pool: memhub.MemBuddy | t.CPtr,
fatal_if_unknown=0:白名单未命中返回默认 i32(不 fail-fast,注入上下文
无法收敛判断交给调用侧)。
"""
import lib.core.Gen.Generator as Generator
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.CallGenLib._infer_external_func_ret_ty(pool, func_name, None, 0)
if _g_gen is not None:
return _g_gen.CallGenLib._infer_external_func_ret_ty(pool, func_name, None, 0)
return None
# ---------------- get_current_file(委托 TypeGenResolve.get_current_file) ----------------
def get_current_file() -> str:
"""委托到 gen.get_current_file(原 Handles 壳)"""
import lib.core.Gen.Generator as Generator
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.TypeGenResolve.get_current_file()
if _g_gen is not None:
return _g_gen.TypeGenResolve.get_current_file()
return None
# ---------------- _is_ctypedef_annotation(委托 TypeGenCType._is_ctypedef_annotation) ----------------
def _is_ctypedef_annotation(annotation: ast.AST | t.CPtr) -> int:
"""委托到 gen._is_ctypedef_annotation(原 Handles 壳)"""
import lib.core.Gen.Generator as Generator
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.TypeGenCType._is_ctypedef_annotation(annotation)
if _g_gen is not None:
return _g_gen.TypeGenCType._is_ctypedef_annotation(annotation)
return 0
# ---------------- resolve_annotation_type(委托 TypeGenResolve.resolve_annotation_type) ----------------
def resolve_annotation_type(pool: memhub.MemBuddy | t.CPtr, node: ast.AST | t.CPtr, imported_modules: str, from_imports: str, trans: HT.Translator | t.CPtr = None, depth: int = 0) -> llvmlite.LLVMType | t.CPtr:
"""委托到 gen.resolve_annotation_type(原 Handles 壳)"""
import lib.core.Gen.Generator as Generator
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.TypeGenResolve.resolve_annotation_type(pool, node, imported_modules, from_imports, trans, depth)
if _g_gen is not None:
return _g_gen.TypeGenResolve.resolve_annotation_type(pool, node, imported_modules, from_imports, trans, depth)
return None
@@ -178,165 +148,131 @@ def resolve_annotation_type(pool: memhub.MemBuddy | t.CPtr, node: ast.AST | t.CP
def has_decorator_marker(node: ast.AST | t.CPtr, marker_name: str,
depth: int = 0) -> int:
"""委托到 gen.has_decorator_marker(原 Handles 壳)"""
import lib.core.Gen.Generator as Generator
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.TypeGenErr.has_decorator_marker(node, marker_name, depth)
if _g_gen is not None:
return _g_gen.TypeGenErr.has_decorator_marker(node, marker_name, depth)
return 0
# ---------------- _get_type_name_from_annotation(委托 TypeGenResolve._get_type_name_from_annotation) ----------------
def _get_type_name_from_annotation(pool: memhub.MemBuddy | t.CPtr, node: ast.AST | t.CPtr) -> str:
"""委托到 gen._get_type_name_from_annotation(原 Handles 壳)"""
import lib.core.Gen.Generator as Generator
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.TypeGenResolve._get_type_name_from_annotation(pool, node)
if _g_gen is not None:
return _g_gen.TypeGenResolve._get_type_name_from_annotation(pool, node)
return None
# ---------------- register_ctypedef(委托 TypeGenCType.register_ctypedef) ----------------
def register_ctypedef(pool: memhub.MemBuddy | t.CPtr, name: str, type_str: str) -> None:
def register_ctypedef(pool: memhub.MemBuddy | t.CPtr, name: str, type_str: str):
"""委托到 gen.register_ctypedef(原 Handles 壳)"""
import lib.core.Gen.Generator as Generator
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.TypeGenCType.register_ctypedef(pool, name, type_str)
if _g_gen is not None:
_g_gen.TypeGenCType.register_ctypedef(pool, name, type_str)
# ---------------- lookup_cdefine_constant(委托 TypeGenCDef.lookup_cdefine_constant) ----------------
def lookup_cdefine_constant(name: str) -> t.CInt64T:
def lookup_cdefine_constant(name: str) -> int64:
"""委托到 gen.lookup_cdefine_constant(原 Handles 壳)"""
import lib.core.Gen.Generator as Generator
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.TypeGenCDef.lookup_cdefine_constant(name)
if _g_gen is not None:
return _g_gen.TypeGenCDef.lookup_cdefine_constant(name)
return 0
# ---------------- is_cdefine_found(委托 TypeGenCDef.is_cdefine_found) ----------------
def is_cdefine_found() -> int:
"""委托到 gen.is_cdefine_found(原 Handles 壳)"""
import lib.core.Gen.Generator as Generator
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.TypeGenCDef.is_cdefine_found()
if _g_gen is not None:
return _g_gen.TypeGenCDef.is_cdefine_found()
return 0
# ---------------- register_cdefine_constant(委托 TypeGenCDef.register_cdefine_constant) ----------------
def register_cdefine_constant(pool: memhub.MemBuddy | t.CPtr,
name: str, value: t.CInt64T) -> None:
name: str, value: int64):
"""委托到 gen.register_cdefine_constant(原 Handles 壳)"""
import lib.core.Gen.Generator as Generator
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.TypeGenCDef.register_cdefine_constant(pool, name, value)
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 | t.CPtr,
name: str, value: double) -> None:
name: str, value: double):
"""委托到 gen.register_cdefine_double(原 Handles 壳)"""
import lib.core.Gen.Generator as Generator
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.TypeGenCDef.register_cdefine_double(pool, name, value)
if _g_gen is not None:
_g_gen.TypeGenCDef.register_cdefine_double(pool, name, value)
# ---------------- is_cdefine_annotation(委托 AssignGenMixin.is_cdefine_annotation) ----------------
def is_cdefine_annotation(annot: ast.AST | t.CPtr) -> int:
"""委托到 gen.is_cdefine_annotation(原 Handles 壳)"""
import lib.core.Gen.Generator as Generator
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.AssignGen.is_cdefine_annotation(annot)
if _g_gen is not None:
return _g_gen.AssignGen.is_cdefine_annotation(annot)
return 0
# ---------------- extract_cdefine_int_value(委托 AssignGenMixin.extract_cdefine_int_value) ----------------
def extract_cdefine_int_value(val_node: ast.AST | t.CPtr) -> t.CInt64T:
def extract_cdefine_int_value(val_node: ast.AST | t.CPtr) -> int64:
"""委托到 gen.extract_cdefine_int_value(原 Handles 壳)"""
import lib.core.Gen.Generator as Generator
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.AssignGen.extract_cdefine_int_value(val_node)
if _g_gen is not None:
return _g_gen.AssignGen.extract_cdefine_int_value(val_node)
return 0
# ---------------- push_trace(委托 TypeGenBase.push_trace) ----------------
def push_trace(file_name: str, lineno: int, col_start: int = 0, col_end: int = 0) -> None:
def push_trace(file_name: str, lineno: int, col_start: int = 0, col_end: int = 0):
"""委托到 gen.push_trace(原 Handles 壳)"""
import lib.core.Gen.Generator as Generator
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.TypeGenBase.push_trace(file_name, lineno, col_start, col_end)
if _g_gen is not None:
_g_gen.TypeGenBase.push_trace(file_name, lineno, col_start, col_end)
# ---------------- pop_trace(委托 TypeGenBase.pop_trace) ----------------
def pop_trace() -> None:
def pop_trace():
"""委托到 gen.pop_trace(原 Handles 壳)"""
import lib.core.Gen.Generator as Generator
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.TypeGenBase.pop_trace()
if _g_gen is not None:
_g_gen.TypeGenBase.pop_trace()
# ---------------- get_temp_dir(委托 TypeGenBase.get_temp_dir) ----------------
def get_temp_dir() -> str:
"""委托到 gen.get_temp_dir(原 Handles 壳)"""
import lib.core.Gen.Generator as Generator
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.TypeGenBase.get_temp_dir()
if _g_gen is not None:
return _g_gen.TypeGenBase.get_temp_dir()
return None
# ---------------- reset_visible_structs(委托 StructGenMixin.reset_visible_structs) ----------------
def reset_visible_structs(pool: memhub.MemBuddy | t.CPtr, strict: int) -> None:
def reset_visible_structs(pool: memhub.MemBuddy | t.CPtr, strict: int):
"""委托到 gen.reset_visible_structs(原 Handles 壳)"""
import lib.core.Gen.Generator as Generator
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.StructGen.reset_visible_structs(pool, strict)
if _g_gen is not None:
_g_gen.StructGen.reset_visible_structs(pool, strict)
# ---------------- set_stdlib_alloc(委托 StructGenMixin.set_stdlib_alloc) ----------------
def set_stdlib_alloc(flag: int) -> None:
def set_stdlib_alloc(flag: int):
"""委托到 gen.set_stdlib_alloc(原 Handles 壳)"""
import lib.core.Gen.Generator as Generator
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.StructGen.set_stdlib_alloc(flag)
if _g_gen is not None:
_g_gen.StructGen.set_stdlib_alloc(flag)
# ---------------- get_struct_count(委托 StructGenMixin.get_struct_count) ----------------
def get_struct_count() -> int:
"""委托到 gen.get_struct_count(原 Handles 壳)"""
import lib.core.Gen.Generator as Generator
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.StructGen.get_struct_count()
if _g_gen is not None:
return _g_gen.StructGen.get_struct_count()
return 0
# ---------------- reset_module_methods_emitted(委托 StructGenMixin.reset_module_methods_emitted) ----------------
def reset_module_methods_emitted(sha1: str) -> int:
"""委托到 gen.reset_module_methods_emitted(原 Handles 壳)"""
import lib.core.Gen.Generator as Generator
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.StructGen.reset_module_methods_emitted(sha1)
if _g_gen is not None:
return _g_gen.StructGen.reset_module_methods_emitted(sha1)
return 0
# ---------------- get_struct_type(委托 StructGenMixin.get_struct_type) ----------------
def get_struct_type(class_name: str) -> llvmlite.LLVMType | t.CPtr:
"""委托到 gen.get_struct_type(原 Handles 壳)"""
import lib.core.Gen.Generator as Generator
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.StructGen.get_struct_type(class_name)
if _g_gen is not None:
return _g_gen.StructGen.get_struct_type(class_name)
return None
@@ -349,39 +285,31 @@ def get_enum_base_type(enum_name: str) -> llvmlite.LLVMType | t.CPtr:
落空必须回退枚举表取 BaseTy(通常 i32),否则跨模块函数返回类型
无法精确获取 → text.ll 缺失(依赖环)时永久 pending(Phase A 死锁根因)。
"""
import lib.core.Gen.Generator as Generator
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.StmtGenDecl.get_enum_base_type(enum_name)
if _g_gen is not None:
return _g_gen.StmtGenDecl.get_enum_base_type(enum_name)
return None
# ---------------- add_visible_struct(委托 StructGenMixin.add_visible_struct) ----------------
def add_visible_struct(pool: memhub.MemBuddy | t.CPtr, name: str) -> None:
def add_visible_struct(pool: memhub.MemBuddy | t.CPtr, name: str):
"""委托到 gen.add_visible_struct(原 Handles 壳)"""
import lib.core.Gen.Generator as Generator
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.StructGen.add_visible_struct(pool, name)
if _g_gen is not None:
_g_gen.StructGen.add_visible_struct(pool, name)
# ---------------- find_struct_by_module(委托 StructGenMixin.find_struct_by_module) ----------------
def find_struct_by_module(name: str, sha1: str) -> GenTypes.StructEntry | t.CPtr:
"""委托到 gen.find_struct_by_module(原 Handles 壳)"""
import lib.core.Gen.Generator as Generator
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.StructGen.find_struct_by_module(name, sha1)
if _g_gen is not None:
return _g_gen.StructGen.find_struct_by_module(name, sha1)
return None
# ---------------- find_struct_by_type(委托 StructGenMixin.find_struct_by_type) ----------------
def find_struct_by_type(struct_ty: llvmlite.LLVMType | t.CPtr) -> GenTypes.StructEntry | t.CPtr:
"""委托到 gen.find_struct_by_type(原 Handles 壳)"""
import lib.core.Gen.Generator as Generator
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.StructGen.find_struct_by_type(struct_ty)
if _g_gen is not None:
return _g_gen.StructGen.find_struct_by_type(struct_ty)
return None
@@ -391,46 +319,38 @@ def register_struct(pool: memhub.MemBuddy | t.CPtr,
struct_ty: llvmlite.LLVMType | t.CPtr,
sha1: str = None) -> GenTypes.StructEntry | t.CPtr:
"""委托到 gen.register_struct(原 Handles 壳)"""
import lib.core.Gen.Generator as Generator
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.StructGen.register_struct(pool, name, struct_ty, sha1)
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 | t.CPtr,
struct_entry: GenTypes.StructEntry | t.CPtr,
field_name: str,
field_ty: llvmlite.LLVMType | t.CPtr) -> int:
"""委托到 gen.add_field(原 Handles 壳)"""
import lib.core.Gen.Generator as Generator
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.StructGen.add_field(pool, struct_entry, field_name, field_ty)
return -1
# ---------------- register_struct_alias(委托 StructGenMixin.register_struct_alias) ----------------
# ---------------- add_field(委托 StructGenMixin.add_field) ----------------
def add_field(pool: memhub.MemBuddy | t.CPtr,
struct_entry: GenTypes.StructEntry | t.CPtr,
field_name: str,
field_ty: llvmlite.LLVMType | t.CPtr) -> 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 | t.CPtr,
name: str,
sha1: str,
src_entry: GenTypes.StructEntry | t.CPtr) -> GenTypes.StructEntry | t.CPtr:
"""委托到 gen.StructGen.register_struct_alias(包重导出类别名注册,原 Handles 壳)"""
import lib.core.Gen.Generator as Generator
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.StructGen.register_struct_alias(pool, name, sha1, src_entry)
if _g_gen is not None:
return _g_gen.StructGen.register_struct_alias(pool, name, sha1, src_entry)
return None
# ---------------- get_stdlib_alloc(委托 StructGenMixin.get_stdlib_alloc) ----------------
def get_stdlib_alloc() -> int:
"""委托到 gen.get_stdlib_alloc(原 Handles 壳)"""
import lib.core.Gen.Generator as Generator
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.StructGen.get_stdlib_alloc()
if _g_gen is not None:
return _g_gen.StructGen.get_stdlib_alloc()
return 0
@@ -438,279 +358,223 @@ def get_stdlib_alloc() -> int:
# ---------------- compute_package_from_relpath(委托 ImportsGenMixin.compute_package_from_relpath) ----------------
def compute_package_from_relpath(pool: memhub.MemBuddy | t.CPtr, rel_path: str) -> str:
"""委托到 gen.compute_package_from_relpath(原 Handles 壳)"""
import lib.core.Gen.Generator as Generator
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.ImportsGen.compute_package_from_relpath(pool, rel_path)
if _g_gen is not None:
return _g_gen.ImportsGen.compute_package_from_relpath(pool, rel_path)
return None
# ---------------- is_module_imported(委托 ImportsGenMixin.is_module_imported) ----------------
def is_module_imported(imported_modules: str, name: str) -> int:
"""委托到 gen.is_module_imported(原 Handles 壳)"""
import lib.core.Gen.Generator as Generator
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.ImportsGen.is_module_imported(imported_modules, name)
if _g_gen is not None:
return _g_gen.ImportsGen.is_module_imported(imported_modules, name)
return 0
# ---------------- add_imported_module(委托 ImportsGenMixin.add_imported_module) ----------------
def add_imported_module(pool: memhub.MemBuddy | t.CPtr, imported_modules: str, name: str) -> str:
"""委托到 gen.add_imported_module(原 Handles 壳)"""
import lib.core.Gen.Generator as Generator
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.ImportsGen.add_imported_module(pool, imported_modules, name)
if _g_gen is not None:
return _g_gen.ImportsGen.add_imported_module(pool, imported_modules, name)
return None
# ---------------- translate_import(委托 ImportsGenMixin.translate_import) ----------------
def translate_import(trans: HT.Translator | t.CPtr, node: ast.AST | t.CPtr) -> int:
"""委托到 gen.translate_import(原 Handles 壳)"""
import lib.core.Gen.Generator as Generator
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.ImportsGen.translate_import(trans, node)
if _g_gen is not None:
return _g_gen.ImportsGen.translate_import(trans, node)
return 0
# ---------------- translate_import_from_module(委托 ImportsGenMixin.translate_import_from_module) ----------------
def translate_import_from_module(trans: HT.Translator | t.CPtr, node: ast.AST | t.CPtr) -> int:
"""委托到 gen.translate_import_from_module(原 Handles 壳)"""
import lib.core.Gen.Generator as Generator
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.ImportsGen.translate_import_from_module(trans, node)
if _g_gen is not None:
return _g_gen.ImportsGen.translate_import_from_module(trans, node)
return 0
# ---------------- translate_import_from_names(委托 ImportsGenMixin.translate_import_from_names) ----------------
def translate_import_from_names(trans: HT.Translator | t.CPtr, node: ast.AST | t.CPtr) -> int:
"""委托到 gen.translate_import_from_names(原 Handles 壳)"""
import lib.core.Gen.Generator as Generator
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.ImportsGen.translate_import_from_names(trans, node)
if _g_gen is not None:
return _g_gen.ImportsGen.translate_import_from_names(trans, node)
return 0
# ---------------- _get_parent_class(委托 ClassGenBase._get_parent_class) ----------------
def _get_parent_class(cd: ast.ClassDef | t.CPtr, trans: HT.Translator | t.CPtr = None) -> str:
"""委托到 gen._get_parent_class(原 Handles 壳)"""
import lib.core.Gen.Generator as Generator
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.ClassGenBase._get_parent_class(cd, trans)
if _g_gen is not None:
return _g_gen.ClassGenBase._get_parent_class(cd, trans)
return None
# ---------------- _register_generic_template(委托 ClassGenGeneric._register_generic_template) ----------------
def _register_generic_template(pool: memhub.MemBuddy | t.CPtr, cd: ast.ClassDef | t.CPtr, module_sha1: str) -> None:
def _register_generic_template(pool: memhub.MemBuddy | t.CPtr, cd: ast.ClassDef | t.CPtr, module_sha1: str):
"""委托到 gen._register_generic_template(原 Handles 壳)"""
import lib.core.Gen.Generator as Generator
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.ClassGenGeneric._register_generic_template(pool, cd, module_sha1)
if _g_gen is not None:
_g_gen.ClassGenGeneric._register_generic_template(pool, cd, module_sha1)
# ---------------- _mangle_name_with_sha1(委托 FuncGenBase._mangle_name_with_sha1) ----------------
def _mangle_name_with_sha1(sha1: str, name: str) -> str:
"""委托到 gen._mangle_name_with_sha1(原 Handles 壳)"""
import lib.core.Gen.Generator as Generator
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.FuncGenBase._mangle_name_with_sha1(sha1, name)
if _g_gen is not None:
return _g_gen.FuncGenBase._mangle_name_with_sha1(sha1, name)
return None
# ---------------- forward_declare_functions(委托 FuncGenDef.forward_declare_functions) ----------------
def forward_declare_functions(trans: HT.Translator | t.CPtr, tree: ast.AST | t.CPtr) -> int:
"""委托到 gen.forward_declare_functions(原 Handles 壳)"""
import lib.core.Gen.Generator as Generator
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.FuncGenDef.forward_declare_functions(trans, tree)
if _g_gen is not None:
return _g_gen.FuncGenDef.forward_declare_functions(trans, tree)
return 0
# ---------------- create_wrapper_main(委托 TranslatorGenMixin.create_wrapper_main) ----------------
def create_wrapper_main(trans: HT.Translator | t.CPtr, tree: ast.AST | t.CPtr, i32_ty: llvmlite.LLVMType | t.CPtr) -> int:
"""委托到 gen.create_wrapper_main(原 Handles 壳)"""
import lib.core.Gen.Generator as Generator
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.TranslatorGen.create_wrapper_main(trans, tree, i32_ty)
if _g_gen is not None:
return _g_gen.TranslatorGen.create_wrapper_main(trans, tree, i32_ty)
return 0
# ---------------- handle_module_level_var(委托 TranslatorGenMixin.handle_module_level_var) ----------------
def handle_module_level_var(trans: HT.Translator | t.CPtr, node: ast.AST | t.CPtr) -> int:
"""委托到 gen.handle_module_level_var(原 Handles 壳)"""
import lib.core.Gen.Generator as Generator
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.TranslatorGen.handle_module_level_var(trans, node)
if _g_gen is not None:
return _g_gen.TranslatorGen.handle_module_level_var(trans, node)
return 0
# ---------------- translate_children(委托 TranslatorGenMixin.translate_children) ----------------
def translate_children(trans: HT.Translator | t.CPtr, tree: ast.AST | t.CPtr) -> int:
"""委托到 gen.translate_children(原 Handles 壳)"""
import lib.core.Gen.Generator as Generator
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.TranslatorGen.translate_children(trans, tree)
if _g_gen is not None:
return _g_gen.TranslatorGen.translate_children(trans, tree)
return 0
# ---------------- init_symbol_table(委托 VarGenMixin.init_symbol_table) ----------------
def init_symbol_table(pool: memhub.MemBuddy | t.CPtr) -> GenTypes.SymbolTable | t.CPtr:
"""委托到 gen.init_symbol_table(原 Handles 壳)"""
import lib.core.Gen.Generator as Generator
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.VarGen.init_symbol_table(pool)
if _g_gen is not None:
return _g_gen.VarGen.init_symbol_table(pool)
return None
# ---------------- SetTempDir(委托 CallGenBase.SetTempDir) ----------------
def SetTempDir(temp_dir: str) -> None:
def SetTempDir(temp_dir: str):
"""委托到 gen.SetTempDir(原 Handles 壳)"""
import lib.core.Gen.Generator as Generator
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.CallGenBase.SetTempDir(temp_dir)
if _g_gen is not None:
_g_gen.CallGenBase.SetTempDir(temp_dir)
# ---------------- find_func_in_module(委托 CallGenBase.find_func_in_module) ----------------
def find_func_in_module(mod: llvmlite.LLVMModule | t.CPtr, name: str) -> llvmlite.Function | t.CPtr:
"""委托到 gen.find_func_in_module(原 Handles 壳)"""
import lib.core.Gen.Generator as Generator
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.CallGenBase.find_func_in_module(mod, name)
if _g_gen is not None:
return _g_gen.CallGenBase.find_func_in_module(mod, name)
return None
# ---------------- add_func_to_table(委托 CallGenLeafKit.add_func_to_table) ----------------
def add_func_to_table(funcs: GenTypes.FuncEntry | t.CPtr, func_count: int, name: str, func: llvmlite.Function | t.CPtr, max_count: int, defaults: t.CVoid | t.CPtr = None, default_count: int = 0, param_count: int = 0, pool: memhub.MemBuddy | t.CPtr = None, def_sha1: str = None) -> int:
def add_func_to_table(funcs: GenTypes.FuncEntry | t.CPtr, func_count: int, name: str, func: llvmlite.Function | t.CPtr, max_count: int, defaults: t.CPtr = None, default_count: int = 0, param_count: int = 0, pool: memhub.MemBuddy | t.CPtr = None, def_sha1: str = None) -> int:
"""委托到 gen.add_func_to_table(原 Handles 壳)
def_sha1:定义该函数的模块 SHA1(依赖注入路径必须传,避免默认值被挂到导入方名下)
"""
import lib.core.Gen.Generator as Generator
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.CallGenLeafKit.add_func_to_table(funcs, func_count, name, func, max_count, defaults, default_count, param_count, pool, def_sha1)
if _g_gen is not None:
return _g_gen.CallGenLeafKit.add_func_to_table(funcs, func_count, name, func, max_count, defaults, default_count, param_count, pool, def_sha1)
return 0
# ---------------- init_func_table(委托 CallGenLeafKit.init_func_table) ----------------
def init_func_table(pool: memhub.MemBuddy | t.CPtr, max_count: int) -> GenTypes.FuncEntry | t.CPtr:
"""委托到 gen.init_func_table(原 Handles 壳)"""
import lib.core.Gen.Generator as Generator
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.CallGenLeafKit.init_func_table(pool, max_count)
if _g_gen is not None:
return _g_gen.CallGenLeafKit.init_func_table(pool, max_count)
return None
# ---------------- translate_call(委托 CallGenMixin.translate_call) ----------------
def translate_call(pool: memhub.MemBuddy | t.CPtr, builder: llvmlite.IRBuilder | t.CPtr, mod: llvmlite.LLVMModule | t.CPtr, node: ast.AST | t.CPtr, funcs_ptr: t.CPtr, func_count: int, trans: HT.Translator | t.CPtr = None) -> llvmlite.Value | t.CPtr:
"""委托到 gen.translate_call(原 Handles 壳)"""
import lib.core.Gen.Generator as Generator
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.CallGen.translate_call(pool, builder, mod, node, funcs_ptr, func_count, trans)
if _g_gen is not None:
return _g_gen.CallGen.translate_call(pool, builder, mod, node, funcs_ptr, func_count, trans)
return None
# ---------------- translate_printf_call(委托 CallGenLeafKit.translate_printf_call) ----------------
def translate_printf_call(pool: memhub.MemBuddy | t.CPtr, builder: llvmlite.IRBuilder | t.CPtr, mod: llvmlite.LLVMModule | t.CPtr, cl: ast.Call | t.CPtr, trans: HT.Translator | t.CPtr = None) -> None:
def translate_printf_call(pool: memhub.MemBuddy | t.CPtr, builder: llvmlite.IRBuilder | t.CPtr, mod: llvmlite.LLVMModule | t.CPtr, cl: ast.Call | t.CPtr, trans: HT.Translator | t.CPtr = None):
"""委托到 gen.translate_printf_call(原 Handles 壳)"""
import lib.core.Gen.Generator as Generator
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.CallGenLeafKit.translate_printf_call(pool, builder, mod, cl, trans)
if _g_gen is not None:
_g_gen.CallGenLeafKit.translate_printf_call(pool, builder, mod, cl, trans)
# ---------------- translate_print_call(委托 CallGenLeafKit.translate_print_call) ----------------
def translate_print_call(pool: memhub.MemBuddy | t.CPtr, builder: llvmlite.IRBuilder | t.CPtr, mod: llvmlite.LLVMModule | t.CPtr, cl: ast.Call | t.CPtr, trans: HT.Translator | t.CPtr = None) -> None:
def translate_print_call(pool: memhub.MemBuddy | t.CPtr, builder: llvmlite.IRBuilder | t.CPtr, mod: llvmlite.LLVMModule | t.CPtr, cl: ast.Call | t.CPtr, trans: HT.Translator | t.CPtr = None):
"""委托到 gen.translate_print_call(原 Handles 壳)"""
import lib.core.Gen.Generator as Generator
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.CallGenLeafKit.translate_print_call(pool, builder, mod, cl, trans)
if _g_gen is not None:
_g_gen.CallGenLeafKit.translate_print_call(pool, builder, mod, cl, trans)
# ---------------- add_global_name(委托 TranslatorGenMixin.add_global_name) ----------------
def add_global_name(trans: HT.Translator | t.CPtr, name: str) -> None:
def add_global_name(trans: HT.Translator | t.CPtr, name: str):
"""委托到 gen.TranslatorGen.add_global_name(原 Handles 壳)"""
import lib.core.Gen.Generator as Generator
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.TranslatorGen.add_global_name(trans, name)
if _g_gen is not None:
_g_gen.TranslatorGen.add_global_name(trans, name)
# ---------------- is_global_name(委托 TranslatorGenMixin.is_global_name) ----------------
def is_global_name(trans: HT.Translator | t.CPtr, name: str) -> int:
"""委托到 gen.TranslatorGen.is_global_name(原 Handles 壳)"""
import lib.core.Gen.Generator as Generator
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.TranslatorGen.is_global_name(trans, name)
if _g_gen is not None:
return _g_gen.TranslatorGen.is_global_name(trans, name)
return 0
# ---------------- add_nonlocal_name(委托 TranslatorGenMixin.add_nonlocal_name) ----------------
def add_nonlocal_name(trans: HT.Translator | t.CPtr, name: str,
var_ty: llvmlite.LLVMType | t.CPtr = None) -> None:
var_ty: llvmlite.LLVMType | t.CPtr = None):
"""委托到 gen.TranslatorGen.add_nonlocal_name(原 Handles 壳)"""
import lib.core.Gen.Generator as Generator
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.TranslatorGen.add_nonlocal_name(trans, name, var_ty)
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 | t.CPtr,
name: str) -> llvmlite.LLVMType | t.CPtr:
"""委托到 gen.TranslatorGen.get_nonlocal_type(原 Handles 壳)"""
import lib.core.Gen.Generator as Generator
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.TranslatorGen.get_nonlocal_type(trans, name)
if _g_gen is not None:
return _g_gen.TranslatorGen.get_nonlocal_type(trans, name)
return None
# ---------------- is_nonlocal_name(委托 TranslatorGenMixin.is_nonlocal_name) ----------------
def is_nonlocal_name(trans: HT.Translator | t.CPtr, name: str) -> int:
"""委托到 gen.TranslatorGen.is_nonlocal_name(原 Handles 壳)"""
import lib.core.Gen.Generator as Generator
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.TranslatorGen.is_nonlocal_name(trans, name)
if _g_gen is not None:
return _g_gen.TranslatorGen.is_nonlocal_name(trans, name)
return 0
# ---------------- get_nonlocal_index(委托 TranslatorGenMixin.get_nonlocal_index) ----------------
def get_nonlocal_index(trans: HT.Translator | t.CPtr, name: str) -> int:
"""委托到 gen.TranslatorGen.get_nonlocal_index(原 Handles 壳)"""
import lib.core.Gen.Generator as Generator
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.TranslatorGen.get_nonlocal_index(trans, name)
if _g_gen is not None:
return _g_gen.TranslatorGen.get_nonlocal_index(trans, name)
return 0
# ---------------- clear_scope_names(委托 TranslatorGenMixin.clear_scope_names) ----------------
def clear_scope_names(trans: HT.Translator | t.CPtr) -> None:
def clear_scope_names(trans: HT.Translator | t.CPtr):
"""委托到 gen.TranslatorGen.clear_scope_names(原 Handles 壳)"""
import lib.core.Gen.Generator as Generator
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.TranslatorGen.clear_scope_names(trans)
if _g_gen is not None:
_g_gen.TranslatorGen.clear_scope_names(trans)
# ---------------- update_global_func_typestr(委托 CallGenLeafKit.update_global_func_typestr) ----------------
@@ -718,8 +582,6 @@ def update_global_func_typestr(pool: memhub.MemBuddy | t.CPtr,
name: str,
func: llvmlite.Function | t.CPtr) -> int:
"""委托到 gen.CallGenLeafKit.update_global_func_typestr(原 ExprCallTable 壳)"""
import lib.core.Gen.Generator as Generator
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.CallGenLeafKit.update_global_func_typestr(pool, name, func)
if _g_gen is not None:
return _g_gen.CallGenLeafKit.update_global_func_typestr(pool, name, func)
return 0
+196 -196
View File
@@ -1,196 +1,196 @@
import t, c
from stdint import *
import ast
import llvmlite
import memhub
# ============================================================
# GenTypes - Gen 侧共享数据类型与常量(去除 Handles 层迁移目标)
#
# 原分布于 Handles 目录的数据类与常量集中于此,供 Gen 子对象、
# 管线与保留实体文件引用。删除 Handles 目录后统一经本模块访问。
# ============================================================
# ============================================================
# 类编译期元数据(原 HandlesType.CLASS_META_*)
# ============================================================
CLASS_META_PROVIDES: t.CDefine = 1
CLASS_META_REQUIRES: t.CDefine = 2
CLASS_META_REQUIRE_MUST: t.CDefine = 3
# ============================================================
# 属性/静态/类方法元数据(原 HandlesClassDef.META_*)
# ============================================================
META_STATIC: t.CDefine = 1
META_CLASS: t.CDefine = 2
META_PROP_GETTER: t.CDefine = 4
META_PROP_SETTER: t.CDefine = 8
META_PROP_DELETER: t.CDefine = 16
# ============================================================
# 结构体容量(原 HandlesStruct.FIELD_MAX/FIELD_NAME_MAX/PARENT_MAX/MRO_MAX)
# ============================================================
FIELD_MAX: t.CDefine = 256
FIELD_NAME_MAX: t.CDefine = 64
PARENT_MAX: t.CDefine = 64
MRO_MAX: t.CDefine = 64
# ============================================================
# for 迭代序列种类(原 HandlesFor.SEQ_KIND_*)
# ============================================================
SEQ_KIND_RANGE: t.CDefine = 1
SEQ_KIND_STR: t.CDefine = 2
SEQ_KIND_LIST: t.CDefine = 3
# ============================================================
# TraceFrame - 仿 Python Traceback 调用栈帧(原 HandlesType.TraceFrame)
# ============================================================
class TraceFrame:
"""仿 Python Traceback 调用栈帧(push_trace/pop_trace 使用)"""
file_name: str
lineno: int
col_start: int
col_end: int
# ============================================================
# VarEntry - 变量表条目(原 HandlesVar.VarEntry)
# ============================================================
class VarEntry:
"""变量表条目"""
Name: str
Alloca: llvmlite.Value | t.CPtr
Used: t.CInt
AnnotClassName: str # 原始类型注解的类名(str 别名在结构体字段中触发编译器 bug,改用显式联合类型)
IsPtrElement: t.CInt # 标志: 1=注解为 bytes|t.CPtr 或 str|t.CPtr, 下标按 8 字节步长
# ============================================================
# Scope - 作用域节点(原 HandlesVar.Scope)
# ============================================================
@t.NoVTable
class Scope:
"""作用域节点"""
Parent: Scope | t.CPtr
Vars: VarEntry | t.CPtr
VarCount: t.CInt
Kind: t.CInt
# ============================================================
# SymbolTable - 嵌套作用域符号表(原 HandlesVar.SymbolTable)
# ============================================================
@t.NoVTable
class SymbolTable:
"""嵌套作用域符号表"""
Pool: memhub.MemBuddy | t.CPtr
Root: Scope | t.CPtr
Current: Scope | t.CPtr
# ============================================================
# FieldEntry - 字段信息条目(原 HandlesStruct.FieldEntry)
# ============================================================
class FieldEntry:
Name: str # 字段名(字符串)
Index: int # 字段在结构体中的索引
Ty: llvmlite.LLVMType | t.CPtr # 字段的 LLVM 类型
DefaultVal: ast.AST | t.CPtr # 默认值 AST 节点(None=无默认值)
AnnotClassName: str # 原始类型注解的类名(str 别名在结构体字段中触发编译器 bug,改用显式联合类型)
# ============================================================
# StructEntry - 结构体注册条目(原 HandlesStruct.StructEntry)
# ============================================================
@t.NoVTable
class StructEntry:
Name: str # 类名
Ty: llvmlite.LLVMType | t.CPtr # LLVM StructType
FieldCount: int # 字段数量
Fields: FieldEntry | t.CPtr # 字段数组(FIELD_MAX 个槽位)
IsUnion: int # 1=联合体 / 0=普通结构体
IsPacked: int # 1=@c.Attribute(t.attr.packed) 打包结构体(无字段填充)
Align: int # @c.Attribute(t.attr.aligned(N)) 对齐字节数(0=默认,如 fpu_context=16)
IsOOP: int # 1=OOP结构体(有方法) / 0=纯内存结构体
HasInit: int # 1=有__init__方法 / 0=无
HasNew: int # 1=有__new__方法 / 0=无
HasVTable: int # 1=有虚表 / 0=无虚表
IsNoVTable: int # 1=明确标记 @t.NoVTable / 0=未标记
ParentName: str # 父类名(None=无父类,多继承时为第一个父类,兼容旧调用)
ParentNames: t.CSizeT | t.CPtr # 多继承父类名数组(每元素 str 指针,ParentCount 个;stdlib 深拷贝)
ParentCount: t.CInt # 父类数量(0=无父类,1=单继承,>1=多继承)
VTableMethodCount: int # 虚表中的方法数量
VTableMethods: str # 虚表方法名数组(每个方法名 str,VTableMethodCount 个)
ModuleSha1: str # 定义该类的模块 SHA1(None=无 SHA1)
MethodsEmitted: int # 1=方法体已翻译 / 0=未译(Phase 1a mark_only 未译,Phase B 据此补译)
SpecTriggerSha1: str # 泛型特化类的触发文件 SHA1(None=非特化类)。特化类 ModuleSha1=模板
# sha1(方法名带模板前缀),作废重译时 reset_module_methods_emitted
# 按触发文件 sha1 精确重置 MethodsEmitted,防特化方法体残留 1 不补译
# → 链接 undefined symbol(list[ast.ClassDef|t.CPtr].* 根因)
# ============================================================
# EnumMember - 枚举成员(原 HandlesEnum.EnumMember)
# ============================================================
class EnumMember:
Name: str # 成员名(字符串)
Value: t.CInt64T # 成员的整数值
Ty: llvmlite.LLVMType | t.CPtr # 成员的 LLVM 类型(用于混用类型场景)
# ============================================================
# EnumEntry - 枚举类型条目(原 HandlesEnum.EnumEntry)
# ============================================================
@t.NoVTable
class EnumEntry:
Name: str # 枚举类名
BaseTy: llvmlite.LLVMType | t.CPtr # 基准类型(所有成员类型中最大的)
MemberCount: int # 成员数量
Members: EnumMember | t.CPtr # 成员数组(ENUM_MEMBER_MAX 个槽位)
# ============================================================
# AsmOperand - 内联汇编操作数条目(原 HandlesExprCall.AsmOperand)
# ============================================================
class AsmOperand:
"""内联汇编操作数条目"""
Value: llvmlite.Value | t.CPtr # 输入值或输出 alloca
Constraint: str # 约束字符串 (如 "r", "=r")
IsOutput: int # 1=输出, 0=输入
# ============================================================
# FuncEntry - 函数表条目(原 HandlesExprCall.FuncEntry)
# ============================================================
@t.NoVTable
class FuncEntry:
"""函数表条目"""
Name: str
Func: llvmlite.Function | t.CPtr
Defaults: t.CVoid | t.CPtr # defaults 列表节点指针 (list[AST | CPtr]),None=无默认值
DefaultCount: int # 默认值数量
ParamCount: int # 形参数量(不含 self)
# TypeStr: 函数类型文本(stdlib 深拷贝,跨文件安全)
# 1b 每文件 reset_to(mark1) 回收 pool 内 Function 对象后,
# vtable 生成 find_func_global 读类型改用此文本,避免悬空。
TypeStr: str
# ============================================================
# FuncDefaultsEntry - 默认参数表条目(原 HandlesExprCall.FuncDefaultsEntry)
# ============================================================
@t.NoVTable
class FuncDefaultsEntry:
"""默认参数表条目"""
Name: str
ModuleSha1: str # 定义该函数的模块 SHA1(限定名去重,避免跨模块同名串味)
Defaults: t.CVoid | t.CPtr # defaults 列表节点指针 (list[AST | CPtr])(pool 内,可能被 reset)
DefaultCount: int
ParamCount: int # 形参数量(不含 self)
# 常量快照(stdlib 分配,跨文件永久存活):
# 注册时提取每个默认值 Constant 的值,跨模块调用时优先用快照重建常量 IR,
# 避免读取已被 1b reset_to(mark1) 回收的 pool 内 AST。
ConstKinds: t.CInt | t.CPtr # const_kind 数组(DefaultCount 个 i32)
ConstInts: t.CInt64T | t.CPtr # int_val 数组(DefaultCount 个 i64)
ConstStrs: t.CSizeT | t.CPtr # str_val 指针数组(DefaultCount 个 i8*)
import t, c
from stdint import *
import ast
import llvmlite
import memhub
# ============================================================
# GenTypes - Gen 侧共享数据类型与常量(去除 Handles 层迁移目标)
#
# 原分布于 Handles 目录的数据类与常量集中于此,供 Gen 子对象、
# 管线与保留实体文件引用。删除 Handles 目录后统一经本模块访问。
# ============================================================
# ============================================================
# 类编译期元数据(原 HandlesType.CLASS_META_*)
# ============================================================
CLASS_META_PROVIDES: t.CDefine = 1
CLASS_META_REQUIRES: t.CDefine = 2
CLASS_META_REQUIRE_MUST: t.CDefine = 3
# ============================================================
# 属性/静态/类方法元数据(原 HandlesClassDef.META_*)
# ============================================================
META_STATIC: t.CDefine = 1
META_CLASS: t.CDefine = 2
META_PROP_GETTER: t.CDefine = 4
META_PROP_SETTER: t.CDefine = 8
META_PROP_DELETER: t.CDefine = 16
# ============================================================
# 结构体容量(原 HandlesStruct.FIELD_MAX/FIELD_NAME_MAX/PARENT_MAX/MRO_MAX)
# ============================================================
FIELD_MAX: t.CDefine = 256
FIELD_NAME_MAX: t.CDefine = 64
PARENT_MAX: t.CDefine = 64
MRO_MAX: t.CDefine = 64
# ============================================================
# for 迭代序列种类(原 HandlesFor.SEQ_KIND_*)
# ============================================================
SEQ_KIND_RANGE: t.CDefine = 1
SEQ_KIND_STR: t.CDefine = 2
SEQ_KIND_LIST: t.CDefine = 3
# ============================================================
# TraceFrame - 仿 Python Traceback 调用栈帧(原 HandlesType.TraceFrame)
# ============================================================
class TraceFrame:
"""仿 Python Traceback 调用栈帧(push_trace/pop_trace 使用)"""
file_name: str
lineno: int
col_start: int
col_end: int
# ============================================================
# VarEntry - 变量表条目(原 HandlesVar.VarEntry)
# ============================================================
class VarEntry:
"""变量表条目"""
Name: str
Alloca: llvmlite.Value | t.CPtr
Used: int
AnnotClassName: str # 原始类型注解的类名(str 别名在结构体字段中触发编译器 bug,改用显式联合类型)
IsPtrElement: int # 标志: 1=注解为 bytes|t.CPtr 或 str|t.CPtr, 下标按 8 字节步长
# ============================================================
# Scope - 作用域节点(原 HandlesVar.Scope)
# ============================================================
@t.NoVTable
class Scope:
"""作用域节点"""
Parent: Scope | t.CPtr
Vars: VarEntry | t.CPtr
VarCount: int
Kind: int
# ============================================================
# SymbolTable - 嵌套作用域符号表(原 HandlesVar.SymbolTable)
# ============================================================
@t.NoVTable
class SymbolTable:
"""嵌套作用域符号表"""
Pool: memhub.MemBuddy | t.CPtr
Root: Scope | t.CPtr
Current: Scope | t.CPtr
# ============================================================
# FieldEntry - 字段信息条目(原 HandlesStruct.FieldEntry)
# ============================================================
class FieldEntry:
Name: str # 字段名(字符串)
Index: int # 字段在结构体中的索引
Ty: llvmlite.LLVMType | t.CPtr # 字段的 LLVM 类型
DefaultVal: ast.AST | t.CPtr # 默认值 AST 节点(None=无默认值)
AnnotClassName: str # 原始类型注解的类名(str 别名在结构体字段中触发编译器 bug,改用显式联合类型)
# ============================================================
# StructEntry - 结构体注册条目(原 HandlesStruct.StructEntry)
# ============================================================
@t.NoVTable
class StructEntry:
Name: str # 类名
Ty: llvmlite.LLVMType | t.CPtr # LLVM StructType
FieldCount: int # 字段数量
Fields: FieldEntry | t.CPtr # 字段数组(FIELD_MAX 个槽位)
IsUnion: int # 1=联合体 / 0=普通结构体
IsPacked: int # 1=@c.Attribute(t.attr.packed) 打包结构体(无字段填充)
Align: int # @c.Attribute(t.attr.aligned(N)) 对齐字节数(0=默认,如 fpu_context=16)
IsOOP: int # 1=OOP结构体(有方法) / 0=纯内存结构体
HasInit: int # 1=有__init__方法 / 0=无
HasNew: int # 1=有__new__方法 / 0=无
HasVTable: int # 1=有虚表 / 0=无虚表
IsNoVTable: int # 1=明确标记 @t.NoVTable / 0=未标记
ParentName: str # 父类名(None=无父类,多继承时为第一个父类,兼容旧调用)
ParentNames: sizet | t.CPtr # 多继承父类名数组(每元素 str 指针,ParentCount 个;stdlib 深拷贝)
ParentCount: int # 父类数量(0=无父类,1=单继承,>1=多继承)
VTableMethodCount: int # 虚表中的方法数量
VTableMethods: str # 虚表方法名数组(每个方法名 str,VTableMethodCount 个)
ModuleSha1: str # 定义该类的模块 SHA1(None=无 SHA1)
MethodsEmitted: int # 1=方法体已翻译 / 0=未译(Phase 1a mark_only 未译,Phase B 据此补译)
SpecTriggerSha1: str # 泛型特化类的触发文件 SHA1(None=非特化类)。特化类 ModuleSha1=模板
# sha1(方法名带模板前缀),作废重译时 reset_module_methods_emitted
# 按触发文件 sha1 精确重置 MethodsEmitted,防特化方法体残留 1 不补译
# → 链接 undefined symbol(list[ast.ClassDef|t.CPtr].* 根因)
# ============================================================
# EnumMember - 枚举成员(原 HandlesEnum.EnumMember)
# ============================================================
class EnumMember:
Name: str # 成员名(字符串)
Value: int64 # 成员的整数值
Ty: llvmlite.LLVMType | t.CPtr # 成员的 LLVM 类型(用于混用类型场景)
# ============================================================
# EnumEntry - 枚举类型条目(原 HandlesEnum.EnumEntry)
# ============================================================
@t.NoVTable
class EnumEntry:
Name: str # 枚举类名
BaseTy: llvmlite.LLVMType | t.CPtr # 基准类型(所有成员类型中最大的)
MemberCount: int # 成员数量
Members: EnumMember | t.CPtr # 成员数组(ENUM_MEMBER_MAX 个槽位)
# ============================================================
# AsmOperand - 内联汇编操作数条目(原 HandlesExprCall.AsmOperand)
# ============================================================
class AsmOperand:
"""内联汇编操作数条目"""
Value: llvmlite.Value | t.CPtr # 输入值或输出 alloca
Constraint: str # 约束字符串 (如 "r", "=r")
IsOutput: int # 1=输出, 0=输入
# ============================================================
# FuncEntry - 函数表条目(原 HandlesExprCall.FuncEntry)
# ============================================================
@t.NoVTable
class FuncEntry:
"""函数表条目"""
Name: str
Func: llvmlite.Function | t.CPtr
Defaults: t.CPtr # defaults 列表节点指针 (list[AST | CPtr]),None=无默认值
DefaultCount: int # 默认值数量
ParamCount: int # 形参数量(不含 self)
# TypeStr: 函数类型文本(stdlib 深拷贝,跨文件安全)
# 1b 每文件 reset_to(mark1) 回收 pool 内 Function 对象后,
# vtable 生成 find_func_global 读类型改用此文本,避免悬空。
TypeStr: str
# ============================================================
# FuncDefaultsEntry - 默认参数表条目(原 HandlesExprCall.FuncDefaultsEntry)
# ============================================================
@t.NoVTable
class FuncDefaultsEntry:
"""默认参数表条目"""
Name: str
ModuleSha1: str # 定义该函数的模块 SHA1(限定名去重,避免跨模块同名串味)
Defaults: t.CPtr # defaults 列表节点指针 (list[AST | CPtr])(pool 内,可能被 reset)
DefaultCount: int
ParamCount: int # 形参数量(不含 self)
# 常量快照(stdlib 分配,跨文件永久存活):
# 注册时提取每个默认值 Constant 的值,跨模块调用时优先用快照重建常量 IR,
# 避免读取已被 1b reset_to(mark1) 回收的 pool 内 AST。
ConstKinds: int | t.CPtr # const_kind 数组(DefaultCount 个 i32)
ConstInts: int64 | t.CPtr # int_val 数组(DefaultCount 个 i64)
ConstStrs: sizet | t.CPtr # str_val 指针数组(DefaultCount 个 i8*)
+68 -68
View File
@@ -63,16 +63,16 @@ class ImportsGenMixin:
if name is None:
return imported_modules
if imported_modules is None:
nlen: t.CSizeT = string.strlen(name)
nlen: sizet = string.strlen(name)
buf: str = pool.alloc(nlen + 1)
if buf is not None:
string.strcpy(buf, name)
return buf
return None
else:
old_len: t.CSizeT = string.strlen(imported_modules)
name_len: t.CSizeT = string.strlen(name)
new_len: t.CSizeT = old_len + 1 + name_len
old_len: sizet = string.strlen(imported_modules)
name_len: sizet = string.strlen(name)
new_len: sizet = old_len + 1 + name_len
buf2: str = pool.alloc(new_len + 1)
if buf2 is not None:
string.strcpy(buf2, imported_modules)
@@ -88,19 +88,19 @@ class ImportsGenMixin:
"""检查模块是否已导入(词边界精确匹配,避免子串误匹配)"""
if name is None or imported_modules is None:
return 0
name_len: t.CSizeT = string.strlen(name)
name_len: sizet = string.strlen(name)
cur: str = imported_modules
total_len: t.CSizeT = string.strlen(imported_modules)
ci: t.CSizeT = 0
total_len: sizet = string.strlen(imported_modules)
ci: sizet = 0
while ci < total_len:
while ci < total_len and cur[ci] == ' ':
ci += 1
if ci >= total_len:
break
word_start: t.CSizeT = ci
word_start: sizet = ci
while ci < total_len and cur[ci] != ' ':
ci += 1
word_len: t.CSizeT = ci - word_start
word_len: sizet = ci - word_start
if word_len == name_len:
match: int = 1
for ei in range(name_len):
@@ -135,8 +135,8 @@ class ImportsGenMixin:
return 0
if StubMergerStore.LookupSha1ByModName(name) is None:
return 0
nl: t.CSizeT = string.strlen(name)
dot_pos: t.CSizeT = 0
nl: sizet = string.strlen(name)
dot_pos: sizet = 0
while dot_pos < nl:
if name[dot_pos] == '.':
pfx: str = stdlib.malloc(dot_pos + 1)
@@ -177,9 +177,9 @@ class ImportsGenMixin:
if from_imports is None:
return entry
else:
old_len: t.CSizeT = string.strlen(from_imports)
entry_len: t.CSizeT = string.strlen(entry)
new_len: t.CSizeT = old_len + 1 + entry_len
old_len: sizet = string.strlen(from_imports)
entry_len: sizet = string.strlen(entry)
new_len: sizet = old_len + 1 + entry_len
buf: str = pool.alloc(new_len + 1)
if buf is not None:
string.strcpy(buf, from_imports)
@@ -199,10 +199,10 @@ class ImportsGenMixin:
"""查找 from-import 别名对应的原始函数名,返回 None=无别名或未找到"""
if local_name is None or from_imports is None:
return None
name_len: t.CSizeT = string.strlen(local_name)
name_len: sizet = string.strlen(local_name)
cur: str = from_imports
ci: t.CSizeT = 0
total_len: t.CSizeT = string.strlen(from_imports)
ci: sizet = 0
total_len: sizet = string.strlen(from_imports)
while ci < total_len:
# 跳过前导空格
while ci < total_len and cur[ci] == ' ':
@@ -210,12 +210,12 @@ class ImportsGenMixin:
if ci >= total_len:
break
# 找到第一个 ':' 的位置
colon1: t.CSizeT = ci
colon1: sizet = ci
while colon1 < total_len and cur[colon1] != ':' and cur[colon1] != ' ':
colon1 += 1
if colon1 >= total_len or cur[colon1] != ':':
break
entry_name_len: t.CSizeT = colon1 - ci
entry_name_len: sizet = colon1 - ci
# 跳过 star import
if entry_name_len == 1 and cur[ci] == '*':
ci = colon1
@@ -225,7 +225,7 @@ class ImportsGenMixin:
# 比较名称
if entry_name_len == name_len:
match: int = 1
ei: t.CSizeT = 0
ei: sizet = 0
while ei < name_len:
if cur[ci + ei] != local_name[ei]:
match = 0
@@ -233,17 +233,17 @@ class ImportsGenMixin:
ei += 1
if match == 1:
# 找到匹配,检查是否有第三个字段(原始名)
pos: t.CSizeT = colon1 + 1
pos: sizet = colon1 + 1
# 跳过模块名
while pos < total_len and cur[pos] != ':' and cur[pos] != ' ' and cur[pos] != '\0':
pos += 1
if pos < total_len and cur[pos] == ':':
# 有第三个字段: original_name
orig_start: t.CSizeT = pos + 1
orig_end: t.CSizeT = orig_start
orig_start: sizet = pos + 1
orig_end: sizet = orig_start
while orig_end < total_len and cur[orig_end] != ' ' and cur[orig_end] != '\0':
orig_end += 1
orig_len: t.CSizeT = orig_end - orig_start
orig_len: sizet = orig_end - orig_start
if orig_len > 0:
orig_buf: str = cur + orig_start
# 返回指向内部的指针(调用方需在使用期内保持 from_imports 有效)
@@ -273,10 +273,10 @@ class ImportsGenMixin:
"""
if name is None or from_imports is None:
return None
name_len: t.CSizeT = string.strlen(name)
name_len: sizet = string.strlen(name)
cur: str = from_imports
ci: t.CSizeT = 0
total_len: t.CSizeT = string.strlen(from_imports)
ci: sizet = 0
total_len: sizet = string.strlen(from_imports)
star_mod: str = None
while ci < total_len:
# 跳过前导空格
@@ -285,31 +285,31 @@ class ImportsGenMixin:
if ci >= total_len:
break
# 找到 ':' 的位置
colon_pos: t.CSizeT = ci
colon_pos: sizet = ci
while colon_pos < total_len and cur[colon_pos] != ':' and cur[colon_pos] != ' ':
colon_pos += 1
if colon_pos >= total_len or cur[colon_pos] != ':':
break
entry_name_len: t.CSizeT = colon_pos - ci
entry_name_len: sizet = colon_pos - ci
# 检测 star import ("*:module")
if entry_name_len == 1 and cur[ci] == '*':
mod_start: t.CSizeT = colon_pos + 1
mod_end: t.CSizeT = mod_start
mod_start: sizet = colon_pos + 1
mod_end: sizet = mod_start
while mod_end < total_len and cur[mod_end] != ' ' and cur[mod_end] != '\0' and cur[mod_end] != ':':
mod_end += 1
star_mod = cur + mod_start
# 比较名称
elif entry_name_len == name_len:
match: int = 1
ei: t.CSizeT = 0
ei: sizet = 0
while ei < name_len:
if cur[ci + ei] != name[ei]:
match = 0
break
ei += 1
if match == 1:
mod_start2: t.CSizeT = colon_pos + 1
mod_end2: t.CSizeT = mod_start2
mod_start2: sizet = colon_pos + 1
mod_end2: sizet = mod_start2
# 模块名结束于: 空格、null、或第二个':'(别名格式的分隔符)
while mod_end2 < total_len and cur[mod_end2] != ' ' and cur[mod_end2] != '\0' and cur[mod_end2] != ':':
mod_end2 += 1
@@ -350,8 +350,8 @@ class ImportsGenMixin:
return -1
# 幂等检查:查找是否已存在相同映射
for i in range(self.ReexportCount):
sidx: t.CSizeT = t.CSizeT(i) * 17
fidx: t.CSizeT = t.CSizeT(i) * 64
sidx: sizet = sizet(i) * 17
fidx: sizet = sizet(i) * 64
if string.strcmp(self.ReexportSha1s + sidx, mod_sha1) == 0:
if string.strcmp(self.ReexportFuncs + fidx, func_name) == 0:
# 已存在,更新 source_module(以防变化;64 字节槽,strncpy 钳制)
@@ -359,8 +359,8 @@ class ImportsGenMixin:
self.ReexportSrcs[fidx + 63] = '\0'
return 0
# 添加新条目(槽位定长 17/64 字节,strcpy 无界会越界写相邻槽,全部 strncpy 钳制)
idx2: t.CSizeT = t.CSizeT(self.ReexportCount) * 17
fidx2: t.CSizeT = t.CSizeT(self.ReexportCount) * 64
idx2: sizet = sizet(self.ReexportCount) * 17
fidx2: sizet = sizet(self.ReexportCount) * 64
string.strncpy(self.ReexportSha1s + idx2, mod_sha1, 16)
self.ReexportSha1s[idx2 + 16] = '\0'
string.strncpy(self.ReexportFuncs + fidx2, func_name, 63)
@@ -383,8 +383,8 @@ class ImportsGenMixin:
if self.ReexportSha1s is None or self.ReexportCount <= 0:
return None
for i in range(self.ReexportCount):
sidx: t.CSizeT = t.CSizeT(i) * 17
fidx: t.CSizeT = t.CSizeT(i) * 64
sidx: sizet = sizet(i) * 17
fidx: sizet = sizet(i) * 64
if string.strcmp(self.ReexportSha1s + sidx, mod_sha1) == 0:
if string.strcmp(self.ReexportFuncs + fidx, func_name) == 0:
return self.ReexportSrcs + fidx
@@ -412,7 +412,7 @@ class ImportsGenMixin:
# ============================================================
def _resolve_relative_module(self, pool: memhub.MemBuddy | t.CPtr,
current_package: str,
level: t.CInt,
level: int,
module: str) -> str:
"""解析相对导入为完整模块名"""
if level <= 0:
@@ -426,12 +426,12 @@ class ImportsGenMixin:
# 从 current_package 开始,上溯 (level-1) 级
pkg: str = current_package
up: t.CInt = level - 1
up: int = level - 1
while up > 0:
pkg_len: t.CSizeT = string.strlen(pkg)
last_dot: t.CSizeT = 0
pkg_len: sizet = string.strlen(pkg)
last_dot: sizet = 0
found: int = 0
i: t.CSizeT = 0
i: sizet = 0
while i < pkg_len:
if pkg[i] == '.':
last_dot = i
@@ -460,8 +460,8 @@ class ImportsGenMixin:
# 包已上溯到空(相对导入越界):回退到 module 原始值
return module
# 拼接 pkg + "." + module
pkg_len2: t.CSizeT = string.strlen(pkg)
mod_len: t.CSizeT = string.strlen(module)
pkg_len2: sizet = string.strlen(pkg)
mod_len: sizet = string.strlen(module)
buf: str = pool.alloc(pkg_len2 + 1 + mod_len + 1)
if buf is None:
self.Gen.TypeGenErr.fatal_error(None, f"相对导入解析失败:level={level} module='{module}'", "ImportError")
@@ -488,13 +488,13 @@ class ImportsGenMixin:
"""从相对路径计算包名(目录部分,分隔符替换为 .)"""
if rel_path is None:
return None
rlen: t.CSizeT = string.strlen(rel_path)
rlen: sizet = string.strlen(rel_path)
# 找最后一个 / 或 \
last_sep: t.CSizeT = 0
last_sep: sizet = 0
found: int = 0
i: t.CSizeT = 0
i: sizet = 0
while i < rlen:
ch: t.CChar = rel_path[i]
ch: char = rel_path[i]
if ch == '/' or ch == '\\':
last_sep = i
found = 1
@@ -503,13 +503,13 @@ class ImportsGenMixin:
# 无目录分隔符 → 顶级文件,无包
return None
# 复制目录部分,将 / 和 \ 替换为 .
dir_len: t.CSizeT = last_sep
dir_len: sizet = last_sep
buf: str = pool.alloc(dir_len + 1)
if buf is None:
return None
j: t.CSizeT = 0
j: sizet = 0
while j < dir_len:
ch2: t.CChar = rel_path[j]
ch2: char = rel_path[j]
if ch2 == '/' or ch2 == '\\':
buf[j] = '.'
else:
@@ -561,7 +561,7 @@ class ImportsGenMixin:
break
cur_ln += 1
if cur_ln == lineno:
ll_err: t.CSizeT = string.strlen(line_buf_err)
ll_err: sizet = string.strlen(line_buf_err)
while ll_err > 0 and (line_buf_err[ll_err - 1] == '\n' or line_buf_err[ll_err - 1] == '\r'):
ll_err -= 1
line_buf_err[ll_err] = '\0'
@@ -583,18 +583,18 @@ class ImportsGenMixin:
cur: str = self.Gen.TypeGenResolve.get_current_file()
if cur is None or mod_name is None:
return 0
cur_len: t.CSizeT = string.strlen(cur)
cur_len: sizet = string.strlen(cur)
if cur_len == 0:
return 0
sep_pos: t.CSizeT = cur_len
sep_pos: sizet = cur_len
while sep_pos > 0:
sep_pos -= 1
ch: t.CChar = cur[sep_pos]
ch: char = cur[sep_pos]
if ch == '/' or ch == '\\':
sep_pos += 1
break
mod_len: t.CSizeT = string.strlen(mod_name)
path_len: t.CSizeT = sep_pos + mod_len + 5
mod_len: sizet = string.strlen(mod_name)
path_len: sizet = sep_pos + mod_len + 5
path_buf: bytes = stdlib.malloc(path_len + 1)
if path_buf is None:
return 0
@@ -668,7 +668,7 @@ class ImportsGenMixin:
names: list[ast.AST | t.CPtr] | t.CPtr = imp.names
if names is None:
return 0
nn: t.CSizeT = len(names)
nn: sizet = len(names)
for ni in range(nn):
alias: ast.Alias | t.CPtr = (ast.Alias | t.CPtr)(names.get(ni))
if alias is not None and alias.name is not None:
@@ -695,7 +695,7 @@ class ImportsGenMixin:
# 使 a.b.c 作为属性访问的 base 被翻译时能通过 is_module_imported("a") 检查
dot_ptr: str = string.strstr(alias.name, ".")
if dot_ptr is not None:
pkg_len: t.CSizeT = t.CSizeT(t.CUInt64T(dot_ptr) - t.CUInt64T(alias.name))
pkg_len: sizet = sizet(uint64(dot_ptr) - uint64(alias.name))
if pkg_len > 0 and pkg_len < 256:
pkg_buf: bytes = pool_val.alloc(pkg_len + 1)
if pkg_buf is not None:
@@ -742,12 +742,12 @@ class ImportsGenMixin:
if impf.module is None:
names_m: list[ast.AST | t.CPtr] | t.CPtr = impf.names
if names_m is not None:
nn_m: t.CSizeT = len(names_m)
nn_m: sizet = len(names_m)
for ni_m in range(nn_m):
alias_m: ast.Alias | t.CPtr = (ast.Alias | t.CPtr)(names_m.get(ni_m))
if alias_m is not None and alias_m.name is not None:
rl_m: t.CSizeT = string.strlen(resolved)
rn_m: t.CSizeT = string.strlen(alias_m.name)
rl_m: sizet = string.strlen(resolved)
rn_m: sizet = string.strlen(alias_m.name)
jb_m: str = trans.Pool.alloc(rl_m + rn_m + 2)
if jb_m is not None:
string.strcpy(jb_m, resolved)
@@ -789,7 +789,7 @@ class ImportsGenMixin:
if resolved is not None:
names: list[ast.AST | t.CPtr] | t.CPtr = impf.names
if names is not None:
nn: t.CSizeT = len(names)
nn: sizet = len(names)
for ni in range(nn):
alias: ast.Alias | t.CPtr = (ast.Alias | t.CPtr)(names.get(ni))
if alias is not None and alias.name is not None:
@@ -806,8 +806,8 @@ class ImportsGenMixin:
# syscall as syscall` 根因)。
fi_target: str = resolved
if impf.module is None and resolved is not None:
fl_t: t.CSizeT = string.strlen(resolved)
fn_t: t.CSizeT = string.strlen(alias.name)
fl_t: sizet = string.strlen(resolved)
fn_t: sizet = string.strlen(alias.name)
jb_t: str = trans.Pool.alloc(fl_t + fn_t + 2)
if jb_t is not None:
string.strcpy(jb_t, resolved)
+43 -43
View File
@@ -145,7 +145,7 @@ class MatchGenMixin:
if is_renum == 0:
cases_list: list[ast.AST | t.CPtr] | t.CPtr = m_node.cases
if cases_list is not None:
cn: t.CSizeT = len(cases_list)
cn: sizet = len(cases_list)
ci: int = 0
while ci < cn and is_renum == 0:
case_node: ast.AST | t.CPtr = cases_list.get(ci)
@@ -240,7 +240,7 @@ class MatchGenMixin:
def _has_no_break(self, body_list: list[ast.AST | t.CPtr] | t.CPtr) -> int:
if body_list is None:
return 0
n: t.CSizeT = len(body_list)
n: sizet = len(body_list)
i: int = 0
while i < n:
stmt: ast.AST | t.CPtr = body_list.get(i)
@@ -366,15 +366,15 @@ class MatchGenMixin:
if cases_list is None:
# fail-fast: match cases 缺失
self.Gen.TypeGenErr.fatal_error(node, "match cases 缺失", "TypeError")
case_count: t.CSizeT = len(cases_list)
case_count: sizet = len(cases_list)
# BB 指针数组、case 值指针数组、default 标记数组、nobreak 标记数组
bb_arr: t.CSizeT | t.CPtr = pool.alloc(8 * MAX_MATCH_CASES)
cv_arr: t.CSizeT | t.CPtr = pool.alloc(8 * MAX_MATCH_CASES)
def_arr: t.CInt | t.CPtr = pool.alloc(4 * MAX_MATCH_CASES)
nb_arr: t.CInt | t.CPtr = pool.alloc(4 * MAX_MATCH_CASES)
bb_arr: sizet | t.CPtr = pool.alloc(8 * MAX_MATCH_CASES)
cv_arr: sizet | t.CPtr = pool.alloc(8 * MAX_MATCH_CASES)
def_arr: int | t.CPtr = pool.alloc(4 * MAX_MATCH_CASES)
nb_arr: int | t.CPtr = pool.alloc(4 * MAX_MATCH_CASES)
# pass1 缓存的 mc 指针数组(pass2 复用,避免重索引)
mc_arr: t.CSizeT | t.CPtr = pool.alloc(8 * MAX_MATCH_CASES)
mc_arr: sizet | t.CPtr = pool.alloc(8 * MAX_MATCH_CASES)
if bb_arr is None or cv_arr is None or def_arr is None or nb_arr is None \
or mc_arr is None:
# fail-fast: match 分派数组分配失败
@@ -457,12 +457,12 @@ class MatchGenMixin:
# 存入数组
if collected < MAX_MATCH_CASES:
bb_arr[collected] = t.CSizeT(bb)
cv_arr[collected] = t.CSizeT(cv)
bb_arr[collected] = sizet(bb)
cv_arr[collected] = sizet(cv)
def_arr[collected] = is_def
nb_arr[collected] = nb
# 缓存 mc 指针(pass2 复用,避免重索引)
mc_arr[collected] = t.CSizeT(mc)
mc_arr[collected] = sizet(mc)
collected = collected + 1
# 构建 SwitchCase 链表(非 default case 且有值)
@@ -503,7 +503,7 @@ class MatchGenMixin:
pat: ast.AST | t.CPtr = mc.pattern
# 取 BB
bb_addr: t.CSizeT = bb_arr[i]
bb_addr: sizet = bb_arr[i]
case_bb: llvmlite.BasicBlock | t.CPtr = (
llvmlite.BasicBlock | t.CPtr)(t.CVoid(bb_addr, t.CPtr))
is_def: int = def_arr[i]
@@ -530,7 +530,7 @@ class MatchGenMixin:
# 翻译 case body
body_list: list[ast.AST | t.CPtr] | t.CPtr = mc.children
if body_list is not None:
bc: t.CSizeT = len(body_list)
bc: sizet = len(body_list)
bi: int = 0
while bi < bc:
# 用 list.get() 读取元素值(已验证编译为 8 字节加载,与
@@ -582,7 +582,7 @@ class MatchGenMixin:
dbody2: list[ast.AST | t.CPtr] | t.CPtr = dmc.children
dbody = dbody2
if dbody2 is not None:
dn: t.CSizeT = len(dbody2)
dn: sizet = len(dbody2)
dj: int = 0
while dj < dn:
stmt: ast.AST | t.CPtr = dbody2.get(dj)
@@ -631,7 +631,7 @@ class MatchGenMixin:
builder, subject_ptr, renum_ptr_ty)
if casted_ptr is None:
casted_ptr = subject_ptr
pn: t.CSizeT = len(pats)
pn: sizet = len(pats)
j: int = 0
while j < pn:
sub_pat: ast.AST | t.CPtr = pats.get(j)
@@ -688,7 +688,7 @@ class MatchGenMixin:
# 变体成员实际类型(对齐 TPC class_members L300-307/L376-382):
# 注册时别名表存了成员注解解析出的类型(perm_pool 深拷贝)。
# 用它把槽位地址 bitcast 成 Ptr(成员类型),使绑定变量按成员
# 类型读 payload——Struct.Name: t.CChar|t.CPtr = i8*,否则按
# 类型读 payload——Struct.Name: char|t.CPtr = i8*,否则按
# 槽位 i64 读 → is 比较/下标/strlen 等字符串操作翻译失败
# (CallGenMixin L4631 type_name_sp is not None 根因)。
# 注意:必须按 (class, 变体名, 位置) 定位——MatchAs 名是局部
@@ -791,10 +791,10 @@ class MatchGenMixin:
elts = sl2.elts
if elts is None:
return 0
ecount: t.CSizeT = len(elts)
ecount: sizet = len(elts)
if ecount == 0:
return 0
subj_vals: t.CSizeT | t.CPtr = pool.alloc(8 * ecount)
subj_vals: sizet | t.CPtr = pool.alloc(8 * ecount)
if subj_vals is None:
return 0
for ei in range(ecount):
@@ -808,7 +808,7 @@ class MatchGenMixin:
if sv is None:
self.Gen.TypeGenErr.fatal_error(
elt, f"match 序列元素 {ei} 翻译失败", "TypeError")
subj_vals[ei] = t.CSizeT(sv)
subj_vals[ei] = sizet(sv)
# 2. 创建 default/end BB
cnt: int = trans._label_counter
@@ -827,12 +827,12 @@ class MatchGenMixin:
cases_list: list[ast.AST | t.CPtr] | t.CPtr = node.cases
if cases_list is None:
return 0
case_count: t.CSizeT = len(cases_list)
check_arr: t.CSizeT | t.CPtr = pool.alloc(8 * MAX_MATCH_CASES)
body_arr: t.CSizeT | t.CPtr = pool.alloc(8 * MAX_MATCH_CASES)
def_arr: t.CInt | t.CPtr = pool.alloc(4 * MAX_MATCH_CASES)
nb_arr: t.CInt | t.CPtr = pool.alloc(4 * MAX_MATCH_CASES)
guard_arr: t.CSizeT | t.CPtr = pool.alloc(8 * MAX_MATCH_CASES)
case_count: sizet = len(cases_list)
check_arr: sizet | t.CPtr = pool.alloc(8 * MAX_MATCH_CASES)
body_arr: sizet | t.CPtr = pool.alloc(8 * MAX_MATCH_CASES)
def_arr: int | t.CPtr = pool.alloc(4 * MAX_MATCH_CASES)
nb_arr: int | t.CPtr = pool.alloc(4 * MAX_MATCH_CASES)
guard_arr: sizet | t.CPtr = pool.alloc(8 * MAX_MATCH_CASES)
if check_arr is None or body_arr is None or def_arr is None \
or nb_arr is None or guard_arr is None:
return 0
@@ -861,7 +861,7 @@ class MatchGenMixin:
if is_def == 1:
has_default = 1
check_arr[collected] = 0
body_arr[collected] = t.CSizeT(default_bb)
body_arr[collected] = sizet(default_bb)
else:
if collected >= MAX_MATCH_CASES:
break
@@ -871,15 +871,15 @@ class MatchGenMixin:
viperlib.snprintf(name_buf, 32, "match.seq.body.%d.%d", cnt, i)
bbb: llvmlite.BasicBlock | t.CPtr = llvmlite.create_block(
pool, func, name_buf)
check_arr[collected] = t.CSizeT(cbb)
body_arr[collected] = t.CSizeT(bbb)
check_arr[collected] = sizet(cbb)
body_arr[collected] = sizet(bbb)
if first_check < 0:
first_check = collected
body_list: list[ast.AST | t.CPtr] | t.CPtr = mc.children
nb: int = self._has_no_break(body_list)
def_arr[collected] = is_def
nb_arr[collected] = nb
guard_arr[collected] = t.CSizeT(mc.guard)
guard_arr[collected] = sizet(mc.guard)
collected = collected + 1
i = i + 1
@@ -917,7 +917,7 @@ class MatchGenMixin:
pats: list[ast.AST | t.CPtr] | t.CPtr = None
if ms is not None:
pats = ms.patterns
pcount: t.CSizeT = 0
pcount: sizet = 0
if pats is not None:
pcount = len(pats)
if pcount != ecount:
@@ -968,7 +968,7 @@ class MatchGenMixin:
self.Gen.TypeGenErr.fatal_error(
pat1, "序列模式不支持的 pattern 类型", "TypeError")
# guard(若有):匹配成立且 guard 非零
g_addr: t.CSizeT = guard_arr[ci]
g_addr: sizet = guard_arr[ci]
if g_addr != 0:
gnode: ast.AST | t.CPtr = (
ast.AST | t.CPtr)(t.CVoid(g_addr, t.CPtr))
@@ -1024,7 +1024,7 @@ class MatchGenMixin:
self.Gen.VarGen.enter_scope(trans.SymTab, SCOPE_MATCH)
body_list2: list[ast.AST | t.CPtr] | t.CPtr = mc3.children
if body_list2 is not None:
bc: t.CSizeT = len(body_list2)
bc: sizet = len(body_list2)
bi: int = 0
while bi < bc:
stmt: ast.AST | t.CPtr = body_list2.get(bi)
@@ -1074,7 +1074,7 @@ class MatchGenMixin:
dbody2: list[ast.AST | t.CPtr] | t.CPtr = dmc.children
dbody = dbody2
if dbody2 is not None:
dn: t.CSizeT = len(dbody2)
dn: sizet = len(dbody2)
dj: int = 0
while dj < dn:
stmt: ast.AST | t.CPtr = dbody2.get(dj)
@@ -1147,12 +1147,12 @@ class MatchGenMixin:
if cases_list is None:
# fail-fast: match cases 缺失
self.Gen.TypeGenErr.fatal_error(node, "match cases 缺失", "TypeError")
case_count: t.CSizeT = len(cases_list)
case_count: sizet = len(cases_list)
bb_arr: t.CSizeT | t.CPtr = pool.alloc(8 * MAX_MATCH_CASES)
cv_arr: t.CSizeT | t.CPtr = pool.alloc(8 * MAX_MATCH_CASES)
def_arr: t.CInt | t.CPtr = pool.alloc(4 * MAX_MATCH_CASES)
nb_arr: t.CInt | t.CPtr = pool.alloc(4 * MAX_MATCH_CASES)
bb_arr: sizet | t.CPtr = pool.alloc(8 * MAX_MATCH_CASES)
cv_arr: sizet | t.CPtr = pool.alloc(8 * MAX_MATCH_CASES)
def_arr: int | t.CPtr = pool.alloc(4 * MAX_MATCH_CASES)
nb_arr: int | t.CPtr = pool.alloc(4 * MAX_MATCH_CASES)
if bb_arr is None or cv_arr is None or def_arr is None or nb_arr is None:
# fail-fast: match 分派数组分配失败
self.Gen.TypeGenErr.fatal_error(node, "match 分派数组分配失败", "TypeError")
@@ -1222,8 +1222,8 @@ class MatchGenMixin:
nb: int = self._has_no_break(body_list)
if collected < MAX_MATCH_CASES:
bb_arr[collected] = t.CSizeT(bb)
cv_arr[collected] = t.CSizeT(cv)
bb_arr[collected] = sizet(bb)
cv_arr[collected] = sizet(cv)
def_arr[collected] = is_def
nb_arr[collected] = nb
collected = collected + 1
@@ -1254,7 +1254,7 @@ class MatchGenMixin:
continue
mc: ast.MatchCase | t.CPtr = (ast.MatchCase | t.CPtr)(case_node)
bb_addr: t.CSizeT = bb_arr[i]
bb_addr: sizet = bb_arr[i]
case_bb: llvmlite.BasicBlock | t.CPtr = (
llvmlite.BasicBlock | t.CPtr)(t.CVoid(bb_addr, t.CPtr))
is_def: int = def_arr[i]
@@ -1271,7 +1271,7 @@ class MatchGenMixin:
body_list: list[ast.AST | t.CPtr] | t.CPtr = mc.children
if body_list is not None:
bc: t.CSizeT = len(body_list)
bc: sizet = len(body_list)
bi: int = 0
while bi < bc:
stmt: ast.AST | t.CPtr = body_list.get(bi)
@@ -1315,7 +1315,7 @@ class MatchGenMixin:
dbody2: list[ast.AST | t.CPtr] | t.CPtr = dmc.children
dbody = dbody2
if dbody2 is not None:
dn: t.CSizeT = len(dbody2)
dn: sizet = len(dbody2)
dj: int = 0
while dj < dn:
stmt: ast.AST | t.CPtr = dbody2.get(dj)
+39 -39
View File
@@ -38,7 +38,7 @@ class StmtGenCifMixin:
# (i32 首字段在组合布局中导致 EnumTable 相对偏移 4 vs 独立布局 8 的错位,
# this_adjust 无法同时修正,枚举表错位到相邻字段被覆盖——ASTCtx 丢失根因)。
Gen: Generator.Generator | t.CPtr
CifEvalOk: t.CSizeT
CifEvalOk: sizet
# --- 枚举注册表(原 HandlesEnum._enum_table/_enum_count) ---
EnumTable: GenTypes.EnumEntry | t.CPtr
@@ -169,7 +169,7 @@ class StmtGenCifMixin:
resolved: str = self.Gen.ImportsGen.lookup_from_import(
trans._from_imports, vn.id, 0)
if resolved is not None:
rm_len: t.CSizeT = 0
rm_len: sizet = 0
while resolved[rm_len] != ' ' and resolved[rm_len] != '\0' and resolved[rm_len] != ':':
rm_len += 1
rm_buf: str = pool.alloc(rm_len + 1)
@@ -178,7 +178,7 @@ class StmtGenCifMixin:
rm_buf[rm_i] = resolved[rm_i]
rm_buf[rm_len] = '\0'
real_mod = rm_buf
fi_len: t.CSizeT = string.strlen(at.attr) + string.strlen(real_mod) + 2
fi_len: sizet = string.strlen(at.attr) + string.strlen(real_mod) + 2
fi: str = pool.alloc(fi_len)
if fi is None:
return 0
@@ -241,7 +241,7 @@ class StmtGenCifMixin:
if vals is None:
self.CifEvalOk = 0
return 0
bn: t.CSizeT = len(vals)
bn: sizet = len(vals)
if bo.op == ast.OpKind.And:
for bi in range(bn):
rv: int = self._cif_eval_node(pool, trans, vals.get(bi))
@@ -265,13 +265,13 @@ class StmtGenCifMixin:
lv: int = self._cif_eval_node(pool, trans, cmp.left)
if self.CifEvalOk == 0:
return 0
ops_list: list[t.CInt] | t.CPtr = (list[t.CInt] | t.CPtr)(cmp.ops)
ops_list: list[int] | t.CPtr = (list[int] | t.CPtr)(cmp.ops)
comps: list[ast.AST | t.CPtr] | t.CPtr = cmp.comparators
if ops_list is None or comps is None:
self.CifEvalOk = 0
return 0
cc: t.CSizeT = len(comps)
ci: t.CSizeT
cc: sizet = len(comps)
ci: sizet
for ci in range(cc):
rv: int = self._cif_eval_node(pool, trans, comps.get(ci))
if self.CifEvalOk == 0:
@@ -473,16 +473,16 @@ class StmtGenCifMixin:
if rt.value.kind() == ast.ASTKind.Tuple:
rtp: ast.Tuple | t.CPtr = (ast.Tuple | t.CPtr)(rt.value)
rtp_elts: list[ast.AST | t.CPtr] | t.CPtr = rtp.elts
rt_n: t.CSizeT = 0
rt_n: sizet = 0
if rtp_elts is not None:
rt_n = len(rtp_elts)
if rt_n > 0 and rt_n <= 16:
rt_vals: t.CSizeT | t.CPtr = pool.alloc(8 * 16)
rt_vals: sizet | t.CPtr = pool.alloc(8 * 16)
if rt_vals is not None:
rt_val_ok: int = 1
rt_head: llvmlite.ParamNode | t.CPtr = None
rt_tail: llvmlite.ParamNode | t.CPtr = None
rvi: t.CSizeT
rvi: sizet
for rvi in range(rt_n):
ev_i: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
builder, pool, mod, rtp_elts.get(rvi),
@@ -490,10 +490,10 @@ class StmtGenCifMixin:
if ev_i is None:
rt_val_ok = 0
break
rt_vals[rvi] = t.CSizeT(ev_i)
rt_vals[rvi] = sizet(ev_i)
if rt_val_ok != 0:
# 构建匿名 struct 类型(字段类型 = 元素值类型)
rvi2: t.CSizeT
rvi2: sizet
for rvi2 in range(rt_n):
rv_i: llvmlite.Value | t.CPtr = (llvmlite.Value | t.CPtr)(
t.CVoid(rt_vals[rvi2], t.CPtr))
@@ -516,7 +516,7 @@ class StmtGenCifMixin:
if rt_struct_ty is not None:
rt_tmp = llvmlite.build_alloca(builder, rt_struct_ty)
if rt_tmp is not None:
rvi3: t.CSizeT
rvi3: sizet
for rvi3 in range(rt_n):
rv3: llvmlite.Value | t.CPtr = (llvmlite.Value | t.CPtr)(
t.CVoid(rt_vals[rvi3], t.CPtr))
@@ -660,7 +660,7 @@ class StmtGenCifMixin:
case llvmlite.LLVMType.Ptr(r_inner):
ret_pointee = r_inner
if val_pointee is not None and ret_pointee is not None \
and t.CUInt64T(val_pointee) != t.CUInt64T(ret_pointee):
and uint64(val_pointee) != uint64(ret_pointee):
val = self.Gen.ExprGenBase.coerce_to_type(builder, val, ret_ty_rt, node)
elif val_bits != 0 and ret_bits != 0 and val_bits != ret_bits:
if val_bits == 1 and val_bits < ret_bits:
@@ -712,8 +712,8 @@ class StmtGenCifMixin:
if cif_val != 0:
body_cif: list[ast.AST | t.CPtr] | t.CPtr = if_node.children
if body_cif is not None:
bc_cif: t.CSizeT = len(body_cif)
bi_cif: t.CSizeT
bc_cif: sizet = len(body_cif)
bi_cif: sizet
for bi_cif in range(bc_cif):
stmt_cif: ast.AST | t.CPtr = body_cif.get(bi_cif)
if stmt_cif is not None:
@@ -728,8 +728,8 @@ class StmtGenCifMixin:
elif sub_cif is not None:
self.Gen.StmtGen.translate_stmt(trans, sub_cif)
elif orelse_cif is not None:
oc_cif: t.CSizeT = len(orelse_cif)
oi_cif: t.CSizeT
oc_cif: sizet = len(orelse_cif)
oi_cif: sizet
for oi_cif in range(oc_cif):
stmt_cif2: ast.AST | t.CPtr = orelse_cif.get(oi_cif)
if stmt_cif2 is not None:
@@ -796,7 +796,7 @@ class StmtGenCifMixin:
llvmlite.position_at_end(builder, then_bb)
body: list[ast.AST | t.CPtr] | t.CPtr = if_node.children
if body is not None:
body_count: t.CSizeT = len(body)
body_count: sizet = len(body)
for bi in range(body_count):
stmt: ast.AST | t.CPtr = body.get(bi)
if stmt is not None:
@@ -822,7 +822,7 @@ class StmtGenCifMixin:
# 同 then:重置标志防残留(else 是普通语句时不被 then 的嵌套控制流值污染)
trans._ctrl_merge_reachable = 1
llvmlite.position_at_end(builder, else_bb)
else_count: t.CSizeT = len(orelse_list)
else_count: sizet = len(orelse_list)
for ei in range(else_count):
stmt: ast.AST | t.CPtr = orelse_list.get(ei)
if stmt is not None:
@@ -928,7 +928,7 @@ class StmtGenCifMixin:
body: list[ast.AST | t.CPtr] | t.CPtr = while_node.children
if body is not None:
body_count: t.CSizeT = len(body)
body_count: sizet = len(body)
for bi in range(body_count):
stmt: ast.AST | t.CPtr = body.get(bi)
if stmt is not None:
@@ -979,7 +979,7 @@ class StmtGenCifMixin:
return 0
ch: list[ast.AST | t.CPtr] | t.CPtr = node.children
if ch is not None:
n: t.CSizeT = len(ch)
n: sizet = len(ch)
for bi in range(n):
c: ast.AST | t.CPtr = ch.get(bi)
if c is None:
@@ -997,7 +997,7 @@ class StmtGenCifMixin:
"""语句列表是否含本层 break(嵌套循环的 break 归内层)"""
if body is None:
return 0
n: t.CSizeT = len(body)
n: sizet = len(body)
for bi in range(n):
s: ast.AST | t.CPtr = body.get(bi)
if s is None:
@@ -1189,7 +1189,7 @@ class StmtGenCifMixin:
args: list[ast.AST | t.CPtr] | t.CPtr = call.args
if args is None:
return 0
arg_count: t.CSizeT = len(args)
arg_count: sizet = len(args)
i32_ty: llvmlite.LLVMType | t.CPtr = llvmlite.Int32(pool)
start_val: llvmlite.Value | t.CPtr = llvmlite.const_int32(pool, 0)
@@ -1283,7 +1283,7 @@ class StmtGenCifMixin:
if self.Gen.ExprGenOps._node_type_unsigned(pool, target, trans) != 0:
loop_unsigned = 1
if loop_unsigned == 0:
args_u: t.CSizeT
args_u: sizet
for args_u in range(arg_count):
if self.Gen.ExprGenOps._node_type_unsigned(pool, args.get(args_u), trans) != 0:
loop_unsigned = 1
@@ -1312,7 +1312,7 @@ class StmtGenCifMixin:
new_vars = 1
# 获取循环变量的实际元素类型(alloca 是指针类型,需解引用 Pointee)
# 当循环变量已声明为 i64(如 t.CSizeT),使用 i64 而非硬编码 i32
# 当循环变量已声明为 i64(如 sizet),使用 i64 而非硬编码 i32
# 避免 load i32, i64* / store i32, i64* 类型不匹配
loop_var_ty: llvmlite.LLVMType | t.CPtr = i32_ty
if var_alloca is not None and var_alloca.Ty is not None:
@@ -1366,7 +1366,7 @@ class StmtGenCifMixin:
if cur_bits < stop_bits:
cmp_lhs = llvmlite.build_sext(builder, cur_i, stop_val.Ty)
else:
# 循环变量位宽 > stop 位宽(如 t.CSizeT 循环变量 + range(i32)):
# 循环变量位宽 > stop 位宽(如 sizet 循环变量 + range(i32)):
# 应把 cur_i 截断到 stop_val 类型(低向高才 sext/zext,高向低用
# trunc)。原实现反了——把小的 stop_val trunc 到大的 loop_var_ty,
# 生成 `trunc i32 to i64` 扩宽非法 IR,llc 报
@@ -1398,7 +1398,7 @@ class StmtGenCifMixin:
body: list[ast.AST | t.CPtr] | t.CPtr = for_node.children
if body is not None:
body_count: t.CSizeT = len(body)
body_count: sizet = len(body)
for bi in range(body_count):
stmt: ast.AST | t.CPtr = body.get(bi)
if stmt is not None:
@@ -1447,7 +1447,7 @@ class StmtGenCifMixin:
if tup is None or tup.elts is None or out1 is None or out2 is None:
return 0
elts: list[ast.AST | t.CPtr] | t.CPtr = tup.elts
n: t.CSizeT = len(elts)
n: sizet = len(elts)
if n < 2:
return 0
e0: ast.AST | t.CPtr = elts.get(0)
@@ -1533,7 +1533,7 @@ class StmtGenCifMixin:
call_src1: ast.Call | t.CPtr = (ast.Call | t.CPtr)(src1)
cargs1: list[ast.AST | t.CPtr] | t.CPtr = call_src1.args
if cargs1 is not None:
n1: t.CSizeT = len(cargs1)
n1: sizet = len(cargs1)
if n1 >= 1:
sv: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
builder, pool, trans.Module, cargs1.get(0),
@@ -1603,7 +1603,7 @@ class StmtGenCifMixin:
call_src2: ast.Call | t.CPtr = (ast.Call | t.CPtr)(src2)
cargs2: list[ast.AST | t.CPtr] | t.CPtr = call_src2.args
if cargs2 is not None:
n2: t.CSizeT = len(cargs2)
n2: sizet = len(cargs2)
if n2 >= 1:
svz: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
builder, pool, trans.Module, cargs2.get(0),
@@ -1775,7 +1775,7 @@ class StmtGenCifMixin:
body: list[ast.AST | t.CPtr] | t.CPtr = for_node.children
if body is not None:
body_count: t.CSizeT = len(body)
body_count: sizet = len(body)
for bi in range(body_count):
stmt: ast.AST | t.CPtr = body.get(bi)
if stmt is not None:
@@ -1936,7 +1936,7 @@ class StmtGenCifMixin:
body: list[ast.AST | t.CPtr] | t.CPtr = for_node.children
if body is not None:
body_count: t.CSizeT = len(body)
body_count: sizet = len(body)
for bi in range(body_count):
stmt: ast.AST | t.CPtr = body.get(bi)
if stmt is not None:
@@ -2105,7 +2105,7 @@ class StmtGenCifMixin:
body: list[ast.AST | t.CPtr] | t.CPtr = for_node.children
if body is not None:
body_count: t.CSizeT = len(body)
body_count: sizet = len(body)
for bi in range(body_count):
stmt: ast.AST | t.CPtr = body.get(bi)
if stmt is not None:
@@ -2148,7 +2148,7 @@ class StmtGenCifMixin:
if lst is None or lst.elts is None:
self.Gen.TypeGenErr.fatal_error(for_node, "列表字面量迭代: 空列表")
elts: list[ast.AST | t.CPtr] | t.CPtr = lst.elts
elts_count: t.CSizeT = len(elts)
elts_count: sizet = len(elts)
if elts_count <= 0:
self.Gen.TypeGenErr.fatal_error(for_node, "列表字面量迭代: 空列表")
@@ -2172,7 +2172,7 @@ class StmtGenCifMixin:
if first_ptr is not None:
llvmlite.build_store(builder, first_val, first_ptr)
# 写其余元素(coerce 到 elem_ty)
i: t.CSizeT = 1
i: sizet = 1
while i < elts_count:
el_node: ast.AST | t.CPtr = elts.get(i)
el_val: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
@@ -2303,7 +2303,7 @@ class StmtGenCifMixin:
body: list[ast.AST | t.CPtr] | t.CPtr = for_node.children
if body is not None:
body_count: t.CSizeT = len(body)
body_count: sizet = len(body)
for bi in range(body_count):
stmt: ast.AST | t.CPtr = body.get(bi)
if stmt is not None:
@@ -2414,7 +2414,7 @@ class StmtGenCifMixin:
body: list[ast.AST | t.CPtr] | t.CPtr = for_node.children
if body is not None:
body_count: t.CSizeT = len(body)
body_count: sizet = len(body)
for bi in range(body_count):
stmt: ast.AST | t.CPtr = body.get(bi)
if stmt is not None:
@@ -2606,7 +2606,7 @@ class StmtGenCifMixin:
trans._continue_bb = step_bb
body: list[ast.AST | t.CPtr] | t.CPtr = for_node.children
if body is not None:
body_count: t.CSizeT = len(body)
body_count: sizet = len(body)
for bi in range(body_count):
stmt: ast.AST | t.CPtr = body.get(bi)
if stmt is not None:
+25 -25
View File
@@ -49,7 +49,7 @@ class StmtGenDeclMixin(StmtGenCifMixin.StmtGenCifMixin):
names: list[ast.AST | t.CPtr] | t.CPtr = gn.names
if names is None:
return 0
n: t.CSizeT = len(names)
n: sizet = len(names)
for i in range(n):
nm_node: ast.AST | t.CPtr = names.get(i)
if nm_node is not None and nm_node.kind() == ast.ASTKind.Name:
@@ -70,7 +70,7 @@ class StmtGenDeclMixin(StmtGenCifMixin.StmtGenCifMixin):
names: list[ast.AST | t.CPtr] | t.CPtr = nl.names
if names is None:
return 0
n: t.CSizeT = len(names)
n: sizet = len(names)
for i in range(n):
nm_node: ast.AST | t.CPtr = names.get(i)
if nm_node is not None and nm_node.kind() == ast.ASTKind.Name:
@@ -151,78 +151,78 @@ class StmtGenDeclMixin(StmtGenCifMixin.StmtGenCifMixin):
if k == ast.ASTKind.If:
ifn: ast.If | t.CPtr = (ast.If | t.CPtr)(node)
if ifn.children is not None:
bn_pre_i: t.CSizeT = len(ifn.children)
bn_pre_i: sizet = len(ifn.children)
for bi_pre_i in range(bn_pre_i):
self.pre_scan_allocas(trans, ifn.children.get(bi_pre_i))
if ifn.orelse is not None:
bn_pre_e: t.CSizeT = len(ifn.orelse)
bn_pre_e: sizet = len(ifn.orelse)
for bi_pre_e in range(bn_pre_e):
self.pre_scan_allocas(trans, ifn.orelse.get(bi_pre_e))
return 0
if k == ast.ASTKind.For:
for_n: ast.For | t.CPtr = (ast.For | t.CPtr)(node)
if for_n.children is not None:
bn_pre_f: t.CSizeT = len(for_n.children)
bn_pre_f: sizet = len(for_n.children)
for bi_pre_f in range(bn_pre_f):
self.pre_scan_allocas(trans, for_n.children.get(bi_pre_f))
if for_n.orelse is not None:
bn_pre_fe: t.CSizeT = len(for_n.orelse)
bn_pre_fe: sizet = len(for_n.orelse)
for bi_pre_fe in range(bn_pre_fe):
self.pre_scan_allocas(trans, for_n.orelse.get(bi_pre_fe))
return 0
if k == ast.ASTKind.While:
wh_n: ast.While | t.CPtr = (ast.While | t.CPtr)(node)
if wh_n.children is not None:
bn_pre_w: t.CSizeT = len(wh_n.children)
bn_pre_w: sizet = len(wh_n.children)
for bi_pre_w in range(bn_pre_w):
self.pre_scan_allocas(trans, wh_n.children.get(bi_pre_w))
if wh_n.orelse is not None:
bn_pre_we: t.CSizeT = len(wh_n.orelse)
bn_pre_we: sizet = len(wh_n.orelse)
for bi_pre_we in range(bn_pre_we):
self.pre_scan_allocas(trans, wh_n.orelse.get(bi_pre_we))
return 0
if k == ast.ASTKind.Try:
tr_n: ast.Try | t.CPtr = (ast.Try | t.CPtr)(node)
if tr_n.children is not None:
bn_pre_t: t.CSizeT = len(tr_n.children)
bn_pre_t: sizet = len(tr_n.children)
for bi_pre_t in range(bn_pre_t):
self.pre_scan_allocas(trans, tr_n.children.get(bi_pre_t))
if tr_n.handlers is not None:
bn_pre_th: t.CSizeT = len(tr_n.handlers)
bn_pre_th: sizet = len(tr_n.handlers)
for bi_pre_th in range(bn_pre_th):
eh_pre: ast.AST | t.CPtr = tr_n.handlers.get(bi_pre_th)
if eh_pre is not None and eh_pre.kind() == ast.ASTKind.ExceptHandler:
ehc_pre: ast.ExceptHandler | t.CPtr = (ast.ExceptHandler | t.CPtr)(eh_pre)
if ehc_pre.children is not None:
bn_pre_ehb: t.CSizeT = len(ehc_pre.children)
bn_pre_ehb: sizet = len(ehc_pre.children)
for bi_pre_ehb in range(bn_pre_ehb):
self.pre_scan_allocas(trans, ehc_pre.children.get(bi_pre_ehb))
if tr_n.orelse is not None:
bn_pre_to: t.CSizeT = len(tr_n.orelse)
bn_pre_to: sizet = len(tr_n.orelse)
for bi_pre_to in range(bn_pre_to):
self.pre_scan_allocas(trans, tr_n.orelse.get(bi_pre_to))
if tr_n.finalbody is not None:
bn_pre_tf: t.CSizeT = len(tr_n.finalbody)
bn_pre_tf: sizet = len(tr_n.finalbody)
for bi_pre_tf in range(bn_pre_tf):
self.pre_scan_allocas(trans, tr_n.finalbody.get(bi_pre_tf))
return 0
if k == ast.ASTKind.With:
wth: ast.With | t.CPtr = (ast.With | t.CPtr)(node)
if wth.children is not None:
bn_pre_wb: t.CSizeT = len(wth.children)
bn_pre_wb: sizet = len(wth.children)
for bi_pre_wb in range(bn_pre_wb):
self.pre_scan_allocas(trans, wth.children.get(bi_pre_wb))
return 0
if k == ast.ASTKind.Match:
mt_n: ast.Match | t.CPtr = (ast.Match | t.CPtr)(node)
if mt_n.cases is not None:
bn_pre_mc: t.CSizeT = len(mt_n.cases)
bn_pre_mc: sizet = len(mt_n.cases)
for bi_pre_mc in range(bn_pre_mc):
mc_pre: ast.AST | t.CPtr = mt_n.cases.get(bi_pre_mc)
if mc_pre is not None and mc_pre.kind() == ast.ASTKind.MatchCase:
mcc_pre: ast.MatchCase | t.CPtr = (ast.MatchCase | t.CPtr)(mc_pre)
if mcc_pre.children is not None:
bn_pre_mcb: t.CSizeT = len(mcc_pre.children)
bn_pre_mcb: sizet = len(mcc_pre.children)
for bi_pre_mcb in range(bn_pre_mcb):
self.pre_scan_allocas(trans, mcc_pre.children.get(bi_pre_mcb))
return 0
@@ -422,7 +422,7 @@ class StmtGenDeclMixin(StmtGenCifMixin.StmtGenCifMixin):
if self.EnumTable is not None:
return 1
entry_size: t.CSizeT = GenTypes.EnumEntry.__sizeof__()
entry_size: sizet = GenTypes.EnumEntry.__sizeof__()
self.EnumTable = CompilerFactory.factory.PermPool.alloc(entry_size * ENUM_MAX)
if self.EnumTable is None:
return 0
@@ -434,8 +434,8 @@ class StmtGenDeclMixin(StmtGenCifMixin.StmtGenCifMixin):
"""获取第 i 个枚举条目"""
if self.EnumTable is None or i < 0 or i >= ENUM_MAX:
return None
entry_size: t.CSizeT = GenTypes.EnumEntry.__sizeof__()
addr: t.CUInt64T = t.CUInt64T(self.EnumTable) + i * entry_size
entry_size: sizet = GenTypes.EnumEntry.__sizeof__()
addr: uint64 = uint64(self.EnumTable) + i * entry_size
return (GenTypes.EnumEntry | t.CPtr)(t.CVoid(addr, t.CPtr))
def _get_enum_member(self, enum_entry: GenTypes.EnumEntry | t.CPtr,
@@ -443,8 +443,8 @@ class StmtGenDeclMixin(StmtGenCifMixin.StmtGenCifMixin):
"""获取枚举中第 i 个成员条目"""
if enum_entry is None or i < 0 or i >= ENUM_MEMBER_MAX:
return None
member_size: t.CSizeT = GenTypes.EnumMember.__sizeof__()
addr: t.CUInt64T = t.CUInt64T(enum_entry.Members) + i * member_size
member_size: sizet = GenTypes.EnumMember.__sizeof__()
addr: uint64 = uint64(enum_entry.Members) + i * member_size
return (GenTypes.EnumMember | t.CPtr)(t.CVoid(addr, t.CPtr))
def register_enum(self, pool: memhub.MemBuddy | t.CPtr,
@@ -468,14 +468,14 @@ class StmtGenDeclMixin(StmtGenCifMixin.StmtGenCifMixin):
return None
# 分配成员数组(永久池:跨 mark/reset 存活,对齐 EnumTable 永久池化)
member_size: t.CSizeT = GenTypes.EnumMember.__sizeof__()
member_size: sizet = GenTypes.EnumMember.__sizeof__()
entry.Members = CompilerFactory.factory.PermPool.alloc(member_size * ENUM_MEMBER_MAX)
if entry.Members is None:
return None
string.memset(entry.Members, 0, member_size * ENUM_MEMBER_MAX)
# 复制类名(永久池深拷贝)
name_len: t.CSizeT = string.strlen(name)
name_len: sizet = string.strlen(name)
name_buf: str = CompilerFactory.factory.PermPool.alloc(name_len + 1)
if name_buf is not None:
string.strcpy(name_buf, name)
@@ -504,7 +504,7 @@ class StmtGenDeclMixin(StmtGenCifMixin.StmtGenCifMixin):
def add_enum_member(self, pool: memhub.MemBuddy | t.CPtr,
enum_entry: GenTypes.EnumEntry | t.CPtr,
member_name: str,
member_val: t.CInt64T,
member_val: int64,
member_ty: llvmlite.LLVMType | t.CPtr) -> int:
"""向枚举添加成员,返回成员索引(-1 失败)"""
if enum_entry is None or member_name is None or member_ty is None:
@@ -529,7 +529,7 @@ class StmtGenDeclMixin(StmtGenCifMixin.StmtGenCifMixin):
return -1
# 复制成员名(永久池深拷贝:成员表跨 mark/reset 存活)
name_len: t.CSizeT = string.strlen(member_name)
name_len: sizet = string.strlen(member_name)
name_buf: str = CompilerFactory.factory.PermPool.alloc(name_len + 1)
if name_buf is not None:
string.strcpy(name_buf, member_name)
+13 -13
View File
@@ -127,7 +127,7 @@ class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin):
builder: llvmlite.IRBuilder | t.CPtr = trans._cur_builder
if pool is None or mod is None or builder is None:
return 0
tn: t.CSizeT = len(dnode.targets)
tn: sizet = len(dnode.targets)
for ti in range(tn):
tgt: ast.AST | t.CPtr = dnode.targets.get(ti)
if tgt is None:
@@ -246,7 +246,7 @@ class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin):
if tr.orelse is not None and len(tr.orelse) > 0:
viperlib.snprintf(bb_buf_t, 64, "try.else.%d", lc_t)
else_bb = llvmlite.create_block(pool, func, bb_buf_t)
n_handlers_t: t.CSizeT = 0
n_handlers_t: sizet = 0
if tr.handlers is not None:
n_handlers_t = len(tr.handlers)
# 注意:list[ptr](pool, N) 第二参数是 elem_size 不是容量!
@@ -278,7 +278,7 @@ class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin):
llvmlite.build_br(builder, try_bb)
llvmlite.position_at_end(builder, try_bb)
if tr.children is not None:
tb_n: t.CSizeT = len(tr.children)
tb_n: sizet = len(tr.children)
for tbi in range(tb_n):
stmt_t: ast.AST | t.CPtr = tr.children.get(tbi)
if stmt_t is not None:
@@ -320,11 +320,11 @@ class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin):
hname_t = ((ast.Name | t.CPtr)(htype_t)).id
elif htype_t.kind() == ast.ASTKind.Attribute:
hname_t = ((ast.Attribute | t.CPtr)(htype_t)).attr
# 匹配编码缓冲:必须是 t.CInt*(i32 步长)——collect_descendant_codes
# 按 out_codes[i](4 字节)写入;若用 t.CSizeT*(8 字节)读,
# 匹配编码缓冲:必须是 int*(i32 步长)——collect_descendant_codes
# 按 out_codes[i](4 字节)写入;若用 sizet*(8 字节)读,
# 多码时读出 (code[i+1]<<32)|code[i] 的 64 位拼接垃圾(单码时
# 高位恰为 0 掩盖;Test 2/3/8 父类多码捕获失败的根因)。
codes_buf_t: t.CInt | t.CPtr = pool.alloc(64 * 4)
codes_buf_t: int | t.CPtr = pool.alloc(64 * 4)
if codes_buf_t is None:
return 0
n_codes_t: int = 0
@@ -405,7 +405,7 @@ class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin):
except_bb2_t: llvmlite.BasicBlock | t.CPtr = except_bbs.get(i_t)
llvmlite.position_at_end(builder, except_bb2_t)
if hdr2_t is not None and hdr2_t.children is not None:
hn2_t: t.CSizeT = len(hdr2_t.children)
hn2_t: sizet = len(hdr2_t.children)
for hi2 in range(hn2_t):
stmt2_t: ast.AST | t.CPtr = hdr2_t.children.get(hi2)
if stmt2_t is not None:
@@ -417,7 +417,7 @@ class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin):
if else_bb is not None:
llvmlite.position_at_end(builder, else_bb)
if tr.orelse is not None:
en_t: t.CSizeT = len(tr.orelse)
en_t: sizet = len(tr.orelse)
for ei in range(en_t):
stmt3_t: ast.AST | t.CPtr = tr.orelse.get(ei)
if stmt3_t is not None:
@@ -609,14 +609,14 @@ class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin):
items: list[ast.AST | t.CPtr] | t.CPtr = wt.items
if items is None:
return 0
n: t.CSizeT = len(items)
n: sizet = len(items)
# 保存外层 __with_ctx(嵌套 with 时退出后恢复)
old_ctx_alloca: llvmlite.Value | t.CPtr = self.Gen.VarGen.lookup_var(
trans.SymTab, "__with_ctx")
# 记录每个 item 的类名(__exit__ 调用时设置 __with_ctx 类型用)
ctx_class_buf: t.CSizeT | t.CPtr = pool.alloc(8 * n)
ctx_class_buf: sizet | t.CPtr = pool.alloc(8 * n)
if ctx_class_buf is None:
return 0
string.memset(ctx_class_buf, 0, 8 * n)
@@ -650,7 +650,7 @@ class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin):
if ca.value is not None and ca.value.kind() == ast.ASTKind.Name:
cmn: ast.Name | t.CPtr = (ast.Name | t.CPtr)(ca.value)
if cmn.id is not None:
ml2: t.CSizeT = string.strlen(cmn.id) + string.strlen(ca.attr) + 2
ml2: sizet = string.strlen(cmn.id) + string.strlen(ca.attr) + 2
mbuf: str = pool.alloc(ml2)
if mbuf is not None:
viperlib.snprintf(mbuf, ml2, "%s.%s", cmn.id, ca.attr)
@@ -669,7 +669,7 @@ class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin):
if cls_name is not None:
self.Gen.VarGen.set_var_annot_class_name(
trans.SymTab, "__with_ctx", cls_name)
ctx_class_buf[i] = t.CSizeT(cls_name)
ctx_class_buf[i] = sizet(cls_name)
# 调用 __enter__()
enter_val: llvmlite.Value | t.CPtr = self._with_ctx_call(
trans, pool, builder, mod, "__enter__")
@@ -706,7 +706,7 @@ class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin):
# 2. 翻译 body
body: list[ast.AST | t.CPtr] | t.CPtr = wt.children
if body is not None:
bn: t.CSizeT = len(body)
bn: sizet = len(body)
for bi in range(bn):
st: ast.AST | t.CPtr = body.get(bi)
if st is not None:
+75 -75
View File
@@ -132,7 +132,7 @@ class StructGenMixin:
if self.StructTable is not None:
return 1
entry_size: t.CSizeT = GenTypes.StructEntry.__sizeof__()
entry_size: sizet = GenTypes.StructEntry.__sizeof__()
table_pool: memhub.MemBuddy | t.CPtr = pool
if self.StdlibAlloc != 0:
table_pool = CompilerFactory.factory.PermPool
@@ -149,16 +149,16 @@ class StructGenMixin:
"""获取第 i 个结构体条目"""
if self.StructTable is None or i < 0 or i >= STRUCT_MAX:
return None
entry_size: t.CSizeT = GenTypes.StructEntry.__sizeof__()
addr: t.CUInt64T = t.CUInt64T(self.StructTable) + i * entry_size
entry_size: sizet = GenTypes.StructEntry.__sizeof__()
addr: uint64 = uint64(self.StructTable) + i * entry_size
return (GenTypes.StructEntry | t.CPtr)(t.CVoid(addr, t.CPtr))
def _get_field_entry(self, struct_entry: GenTypes.StructEntry | t.CPtr, i: int) -> GenTypes.FieldEntry | t.CPtr:
"""获取结构体中第 i 个字段条目"""
if struct_entry is None or i < 0 or i >= FIELD_MAX:
return None
field_size: t.CSizeT = GenTypes.FieldEntry.__sizeof__()
addr: t.CUInt64T = t.CUInt64T(struct_entry.Fields) + i * field_size
field_size: sizet = GenTypes.FieldEntry.__sizeof__()
addr: uint64 = uint64(struct_entry.Fields) + i * field_size
return (GenTypes.FieldEntry | t.CPtr)(t.CVoid(addr, t.CPtr))
def register_struct(self, pool: memhub.MemBuddy | t.CPtr,
@@ -175,12 +175,12 @@ class StructGenMixin:
return None
# 用类型指针去重(同一类型不重复注册,支持跨模块同名类)
# 用 t.CUInt64T 指针值比较(is 比较会触发类型安全检查解引用悬空 Ty)
st_dedup: t.CUInt64T = t.CUInt64T(struct_ty)
# 用 uint64 指针值比较(is 比较会触发类型安全检查解引用悬空 Ty)
st_dedup: uint64 = uint64(struct_ty)
for i in range(self.StructCount):
existing: GenTypes.StructEntry | t.CPtr = self._get_struct_entry(i)
if existing is not None and existing.Ty is not None:
if t.CUInt64T(existing.Ty) == st_dedup:
if uint64(existing.Ty) == st_dedup:
return existing
if self.StructCount >= STRUCT_MAX:
@@ -192,7 +192,7 @@ class StructGenMixin:
return None
# 分配字段数组(1b 阶段用永久池,避免 reset 回收后 Fields 悬空)
field_size: t.CSizeT = GenTypes.FieldEntry.__sizeof__()
field_size: sizet = GenTypes.FieldEntry.__sizeof__()
if self.StdlibAlloc != 0:
perm_sg: memhub.MemBuddy | t.CPtr = CompilerFactory.factory.PermPool
if perm_sg is None:
@@ -213,7 +213,7 @@ class StructGenMixin:
name_pool = CompilerFactory.factory.PermPool
if name_pool is None:
name_pool = pool
name_len: t.CSizeT = string.strlen(name)
name_len: sizet = string.strlen(name)
name_buf: str = name_pool.alloc(name_len + 1)
if name_buf is not None:
string.strcpy(name_buf, name)
@@ -225,7 +225,7 @@ class StructGenMixin:
# 注册时直接设置 SHA1(避免 set_struct_sha1 跨模块同名时找错 entry)
# SHA1 同样按 StdlibAlloc 选分配源(跨 1a/1b 存活,防 strcmp 悬空)
if sha1 is not None:
sha1_len: t.CSizeT = string.strlen(sha1)
sha1_len: sizet = string.strlen(sha1)
sha1_buf: str = name_pool.alloc(sha1_len + 1)
if sha1_buf is not None:
string.strcpy(sha1_buf, sha1)
@@ -269,13 +269,13 @@ class StructGenMixin:
alias_pool = CompilerFactory.factory.PermPool
if alias_pool is None:
alias_pool = pool
name_len: t.CSizeT = string.strlen(name)
name_len: sizet = string.strlen(name)
name_buf: str = alias_pool.alloc(name_len + 1)
if name_buf is None:
return None
string.strcpy(name_buf, name)
entry.Name = name_buf
sha1_len: t.CSizeT = string.strlen(sha1)
sha1_len: sizet = string.strlen(sha1)
sha1_buf: str = alias_pool.alloc(sha1_len + 1)
if sha1_buf is None:
return None
@@ -311,7 +311,7 @@ class StructGenMixin:
if entry is None:
return 0
# 复制 SHA1 字符串(StdlibAlloc=1 用永久池,跨 1a/1b 存活防 strcmp 悬空)
sha1_len: t.CSizeT = string.strlen(sha1)
sha1_len: sizet = string.strlen(sha1)
sha1_pool: memhub.MemBuddy | t.CPtr = pool
if self.StdlibAlloc != 0:
sha1_pool = CompilerFactory.factory.PermPool
@@ -364,7 +364,7 @@ class StructGenMixin:
fname_pool = CompilerFactory.factory.PermPool
if fname_pool is None:
fname_pool = pool
name_len: t.CSizeT = string.strlen(field_name)
name_len: sizet = string.strlen(field_name)
name_buf: str = fname_pool.alloc(name_len + 1)
if name_buf is not None:
string.strcpy(name_buf, field_name)
@@ -387,7 +387,7 @@ class StructGenMixin:
else:
fe.Ty = field_ty
if annot_class_name is not None:
annot_len: t.CSizeT = string.strlen(annot_class_name)
annot_len: sizet = string.strlen(annot_class_name)
annot_buf: str = CompilerFactory.factory.PermPool.alloc(annot_len + 1)
if annot_buf is not None:
string.strcpy(annot_buf, annot_class_name)
@@ -429,8 +429,8 @@ class StructGenMixin:
return None
string.memset(dst_c, 0, ast.Constant.__sizeof__())
# 拷贝 vtable 指针(AST 是 @t.CVTable,kind() 虚调用依赖首字段 vptr)
vt_ptr: t.CVoid | t.CPtr = t.CVoid(
c.Deref(t.CUInt64T(default_val, t.CPtr), t.CPtr), t.CPtr)
vt_ptr: t.CPtr = t.CVoid(
c.Deref(uint64(default_val, t.CPtr), t.CPtr), t.CPtr)
c.DerefAs(dst_c, vt_ptr)
# 拷贝位置字段(报错定位用)
dst_c.lineno = src_c.lineno
@@ -442,7 +442,7 @@ class StructGenMixin:
dst_c.int_val = src_c.int_val
dst_c.float_val = src_c.float_val
if src_c.str_val is not None:
s_len: t.CSizeT = string.strlen(src_c.str_val)
s_len: sizet = string.strlen(src_c.str_val)
s_copy: str = pool.alloc(s_len + 1)
if s_copy is not None:
string.strcpy(s_copy, src_c.str_val)
@@ -464,8 +464,8 @@ class StructGenMixin:
return None
string.memset(dst_l, 0, ast.List.__sizeof__())
# 拷贝 vtable 指针(AST 是 @t.CVTable,kind() 虚调用依赖首字段 vptr)
vt_l: t.CVoid | t.CPtr = t.CVoid(
c.Deref(t.CUInt64T(default_val, t.CPtr), t.CPtr), t.CPtr)
vt_l: t.CPtr = t.CVoid(
c.Deref(uint64(default_val, t.CPtr), t.CPtr), t.CPtr)
c.DerefAs(dst_l, vt_l)
# 拷贝位置字段与 ctx
dst_l.lineno = src_l.lineno
@@ -476,7 +476,7 @@ class StructGenMixin:
# 深拷贝 elts:stdlib 手动构造 list[AST | t.CPtr] 容器
src_elts_l: list[ast.AST | t.CPtr] | t.CPtr = src_l.elts
if src_elts_l is not None:
cnt_l: t.CSizeT = len(src_elts_l)
cnt_l: sizet = len(src_elts_l)
lst_copy_l: list[ast.AST | t.CPtr] | t.CPtr = (list[ast.AST | t.CPtr] | t.CPtr)(
pool.alloc(list[ast.AST | t.CPtr].__sizeof__()))
if lst_copy_l is not None:
@@ -485,18 +485,18 @@ class StructGenMixin:
lst_copy_l.__capacity__ = cnt_l
lst_copy_l.__elem_size__ = 8
lst_copy_l.__pool__ = None
data_l: t.CVoid | t.CPtr = pool.alloc(cnt_l * 8)
data_l: t.CPtr = pool.alloc(cnt_l * 8)
if data_l is not None:
string.memset(data_l, 0, cnt_l * 8)
lst_copy_l.__data__ = data_l
li_l: t.CSizeT
li_l: sizet
for li_l in range(cnt_l):
elem_src_l: ast.AST | t.CPtr = src_elts_l.get(li_l)
if elem_src_l is not None:
elem_dst_l: ast.AST | t.CPtr = self._deep_copy_default_ast(pool, elem_src_l)
if elem_dst_l is not None:
slot_l: ast.AST | t.CPtr = (ast.AST | t.CPtr)(
t.CVoid(t.CUInt64T(data_l) + li_l * 8, t.CPtr))
t.CVoid(uint64(data_l) + li_l * 8, t.CPtr))
slot_l[0] = elem_dst_l
dst_l.elts = lst_copy_l
return (ast.AST | t.CPtr)(dst_l)
@@ -563,7 +563,7 @@ class StructGenMixin:
dot_pos_q: str = self._last_dot_outside_brackets(name)
if dot_pos_q is not None and dot_pos_q[1] != '\0':
bare_f: str = dot_pos_q + 1
mod_len_f: t.CSizeT = string.strlen(name) - string.strlen(bare_f) - 1
mod_len_f: sizet = string.strlen(name) - string.strlen(bare_f) - 1
if mod_len_f > 0:
mod_buf_f: str = stdlib.malloc(mod_len_f + 1)
if mod_buf_f is not None:
@@ -580,7 +580,7 @@ class StructGenMixin:
mod_hex_ok: int = 1
if string.strlen(mod_buf_f) == 16:
for hi_f in range(16):
ch_h: t.CChar = mod_buf_f[hi_f]
ch_h: char = mod_buf_f[hi_f]
if not ((ch_h >= 48 and ch_h <= 57) or (ch_h >= 97 and ch_h <= 102)):
mod_hex_ok = 0
break
@@ -705,7 +705,7 @@ class StructGenMixin:
注意: 不能用 `entry.Ty is struct_ty` 的 is 比较——TPV 编译 is 时会触发
translate_compare 的类型安全检查(is_ptr_type/TypePrint 递归打印),
对悬空 entry.Ty(1b 泛型特化类注册后被 reset 回收的 pool 指针)解引用崩溃。
改用 t.CUInt64T 纯指针值比较,不解引用任何内容。
改用 uint64 纯指针值比较,不解引用任何内容。
"""
if struct_ty is None or self.StructTable is None:
return None
@@ -713,11 +713,11 @@ class StructGenMixin:
if self.StructCount < 0 or self.StructCount > 200000:
VLogger.error(f"StructCount 异常: {self.StructCount} (find_struct_by_type)", "STRUCT")
stdlib.exit(1)
st_val: t.CUInt64T = t.CUInt64T(struct_ty)
st_val: uint64 = uint64(struct_ty)
for i in range(self.StructCount):
entry: GenTypes.StructEntry | t.CPtr = self._get_struct_entry(i)
if entry is not None and entry.Ty is not None:
if t.CUInt64T(entry.Ty) == st_val:
if uint64(entry.Ty) == st_val:
return entry
return None
@@ -764,12 +764,12 @@ class StructGenMixin:
# - 名称匹配但字段未找到时 continue(继续检查其他同名 entry)
# ============================================================
# 第一遍: is 身份比较(用 t.CUInt64T 指针值比较,避免 is 编译路径解引用悬空 Ty)
st_lk: t.CUInt64T = t.CUInt64T(struct_ty)
# 第一遍: is 身份比较(用 uint64 指针值比较,避免 is 编译路径解引用悬空 Ty)
st_lk: uint64 = uint64(struct_ty)
for i in range(self.StructCount):
entry: GenTypes.StructEntry | t.CPtr = self._get_struct_entry(i)
if entry is not None and entry.Ty is not None:
if t.CUInt64T(entry.Ty) == st_lk:
if uint64(entry.Ty) == st_lk:
# is 匹配,查找字段
for fi in range(entry.FieldCount):
fe: GenTypes.FieldEntry | t.CPtr = self._get_field_entry(entry, fi)
@@ -792,8 +792,8 @@ class StructGenMixin:
ty_has_sha1_lf: int = 0
dot_ty_lf: str = string.strchr(ty_name, '.')
if dot_ty_lf is not None:
pre_len_lf: t.CSizeT = t.CSizeT(
t.CUInt64T(dot_ty_lf) - t.CUInt64T(ty_name))
pre_len_lf: sizet = sizet(
uint64(dot_ty_lf) - uint64(ty_name))
if pre_len_lf == 16:
ty_has_sha1_lf = 1
for i in range(self.StructCount):
@@ -835,12 +835,12 @@ class StructGenMixin:
"""
if s is None:
return None
n: t.CSizeT = string.strlen(s)
n: sizet = string.strlen(s)
depth: int = 0
i: t.CSizeT = n
i: sizet = n
while i > 0:
i -= 1
ch: t.CChar = s[i]
ch: char = s[i]
if ch == ']':
depth += 1
elif ch == '[':
@@ -911,7 +911,7 @@ class StructGenMixin:
dot_pos_q: str = self._last_dot_outside_brackets(class_name)
if dot_pos_q is not None and dot_pos_q[1] != '\0':
bare_q: str = dot_pos_q + 1
mod_len_q: t.CSizeT = string.strlen(class_name) - string.strlen(bare_q) - 1
mod_len_q: sizet = string.strlen(class_name) - string.strlen(bare_q) - 1
if mod_len_q > 0:
mod_buf_q: str = stdlib.malloc(mod_len_q + 1)
if mod_buf_q is not None:
@@ -933,7 +933,7 @@ class StructGenMixin:
mod_hex_ok_q: int = 1
if string.strlen(mod_buf_q) == 16:
for hi_q in range(16):
ch_hq: t.CChar = mod_buf_q[hi_q]
ch_hq: char = mod_buf_q[hi_q]
if not ((ch_hq >= 48 and ch_hq <= 57) or (ch_hq >= 97 and ch_hq <= 102)):
mod_hex_ok_q = 0
break
@@ -1183,12 +1183,12 @@ class StructGenMixin:
if struct_ty is None or self.StructTable is None:
return 0
ty_name: str = self._extract_struct_name(struct_ty)
st_iu: t.CUInt64T = t.CUInt64T(struct_ty)
st_iu: uint64 = uint64(struct_ty)
for i in range(self.StructCount):
entry: GenTypes.StructEntry | t.CPtr = self._get_struct_entry(i)
if entry is not None and entry.Ty is not None:
matched: int = 0
if t.CUInt64T(entry.Ty) == st_iu:
if uint64(entry.Ty) == st_iu:
matched = 1
elif ty_name is not None and entry.Name is not None:
if string.strcmp(entry.Name, ty_name) == 0:
@@ -1261,11 +1261,11 @@ class StructGenMixin:
"""按类型指针查找类名,返回类名字符串或 None"""
if struct_ty is None or self.StructTable is None:
return None
st_cn: t.CUInt64T = t.CUInt64T(struct_ty)
st_cn: uint64 = uint64(struct_ty)
for i in range(self.StructCount):
entry: GenTypes.StructEntry | t.CPtr = self._get_struct_entry(i)
if entry is not None and entry.Ty is not None:
if t.CUInt64T(entry.Ty) == st_cn:
if uint64(entry.Ty) == st_cn:
return entry.Name
# 回退: 类型指针比较失败时,遍历所有注册的结构体按名称匹配
# 提取 struct_ty 的 Name 字段(可能是 "SHA1.ClassName" 格式)
@@ -1292,11 +1292,11 @@ class StructGenMixin:
# 误匹配 LinkedNode.append,this 前移 sizeof(LinkedNode) 写穿
# 容器前 48 字节,LLvmLiteTest Test 3 崩溃根因)。
if entry2.Name is not None and string.strlen(entry2.Name) > 0:
_tlen_cn: t.CSizeT = string.strlen(ty_name)
_nlen_cn: t.CSizeT = string.strlen(entry2.Name)
_tlen_cn: sizet = string.strlen(ty_name)
_nlen_cn: sizet = string.strlen(entry2.Name)
if _tlen_cn > _nlen_cn and ty_name[_tlen_cn - _nlen_cn - 1] == '.':
_tail_ok_cn: int = 1
_ti_cn: t.CSizeT
_ti_cn: sizet
for _ti_cn in range(_nlen_cn):
if ty_name[_tlen_cn - _nlen_cn + _ti_cn] != entry2.Name[_ti_cn]:
_tail_ok_cn = 0
@@ -1364,7 +1364,7 @@ class StructGenMixin:
return 1
def set_parent_names(self, pool: memhub.MemBuddy | t.CPtr,
name: str, names_ptr: t.CSizeT | t.CPtr,
name: str, names_ptr: sizet | t.CPtr,
count: int) -> int:
"""设置结构体的父类名数组(永久池深拷贝,跨文件永久存活)"""
if name is None:
@@ -1383,20 +1383,20 @@ class StructGenMixin:
pn_pool = CompilerFactory.factory.PermPool
if pn_pool is None:
pn_pool = pool
arr: t.CSizeT | t.CPtr = pn_pool.alloc(8 * count)
arr: sizet | t.CPtr = pn_pool.alloc(8 * count)
if arr is None:
return 0
for i in range(count):
addr: t.CSizeT = names_ptr[i]
addr: sizet = names_ptr[i]
arr[i] = 0
if addr != 0:
src: str = (str | t.CPtr)(t.CVoid(addr, t.CPtr))
if src is not None:
slen: t.CSizeT = string.strlen(src)
slen: sizet = string.strlen(src)
dup: str = pn_pool.alloc(slen + 1)
if dup is not None:
string.strcpy(dup, src)
arr[i] = t.CSizeT(dup)
arr[i] = sizet(dup)
entry.ParentNames = arr
entry.ParentCount = count
return 1
@@ -1419,42 +1419,42 @@ class StructGenMixin:
return None
if idx >= entry.ParentCount:
return None
parr: t.CSizeT | t.CPtr = (t.CSizeT | t.CPtr)(t.CVoid(entry.ParentNames, t.CPtr))
addr: t.CSizeT = parr[idx]
parr: sizet | t.CPtr = (sizet | t.CPtr)(t.CVoid(entry.ParentNames, t.CPtr))
addr: sizet = parr[idx]
if addr == 0:
return None
return (str | t.CPtr)(t.CVoid(addr, t.CPtr))
def get_mro_chain(self, pool: memhub.MemBuddy | t.CPtr,
name: str) -> t.CSizeT | t.CPtr:
name: str) -> sizet | t.CPtr:
"""MRO 线性化类名数组(深度优先 + 声明顺序 + 去重,含自身)"""
if pool is None or name is None:
return None
arr: t.CSizeT | t.CPtr = pool.alloc(8 * (MRO_MAX + 1))
arr: sizet | t.CPtr = pool.alloc(8 * (MRO_MAX + 1))
if arr is None:
return None
stack: t.CSizeT | t.CPtr = pool.alloc(8 * MRO_MAX)
stack: sizet | t.CPtr = pool.alloc(8 * MRO_MAX)
if stack is None:
return None
visited: t.CSizeT | t.CPtr = pool.alloc(8 * MRO_MAX)
visited: sizet | t.CPtr = pool.alloc(8 * MRO_MAX)
if visited is None:
return None
stack_count: int = 0
out_count: int = 0
visit_count: int = 0
# 初始压入自身
stack[0] = t.CSizeT(name)
stack[0] = sizet(name)
stack_count = 1
while stack_count > 0:
stack_count -= 1
cur_addr: t.CSizeT = stack[stack_count]
cur_addr: sizet = stack[stack_count]
cur: str = (str | t.CPtr)(t.CVoid(cur_addr, t.CPtr))
if cur is None:
continue
# 已访问检查(线性搜索)
dup: int = 0
for vi in range(visit_count):
va: t.CSizeT = visited[vi]
va: sizet = visited[vi]
if va != 0:
vn: str = (str | t.CPtr)(t.CVoid(va, t.CPtr))
if vn is not None and string.strcmp(vn, cur) == 0:
@@ -1464,16 +1464,16 @@ class StructGenMixin:
continue
# 加入结果与已访问集合
if out_count < MRO_MAX:
arr[out_count] = t.CSizeT(cur)
arr[out_count] = sizet(cur)
out_count += 1
if visit_count < MRO_MAX:
visited[visit_count] = t.CSizeT(cur)
visited[visit_count] = sizet(cur)
visit_count += 1
# 父类逆序压栈(正向 range 计算逆序索引,保证声明顺序弹出)
entry: GenTypes.StructEntry | t.CPtr = self.find_struct(cur)
if entry is not None and entry.ParentCount > 0 and entry.ParentNames is not None:
pc: int = entry.ParentCount
parr: t.CSizeT | t.CPtr = (t.CSizeT | t.CPtr)(t.CVoid(entry.ParentNames, t.CPtr))
parr: sizet | t.CPtr = (sizet | t.CPtr)(t.CVoid(entry.ParentNames, t.CPtr))
for pi2 in range(pc):
pi: int = pc - 1 - pi2
if stack_count < MRO_MAX:
@@ -1510,11 +1510,11 @@ class StructGenMixin:
entry: GenTypes.StructEntry | t.CPtr = self.find_struct(name)
if entry is None or entry.VTableMethods is None:
return -1
# VTableMethods 字段声明为 t.CChar*,但实际存储的是 t.CSizeT 数组
# 必须转换为 t.CSizeT* 才能正确读取 8 字节指针值
methods_arr: t.CSizeT | t.CPtr = (t.CSizeT | t.CPtr)(t.CVoid(entry.VTableMethods, t.CPtr))
# VTableMethods 字段声明为 char*,但实际存储的是 sizet 数组
# 必须转换为 sizet* 才能正确读取 8 字节指针值
methods_arr: sizet | t.CPtr = (sizet | t.CPtr)(t.CVoid(entry.VTableMethods, t.CPtr))
for i in range(entry.VTableMethodCount):
mname_addr: t.CSizeT = methods_arr[i]
mname_addr: sizet = methods_arr[i]
if mname_addr == 0:
continue
mname: str = (str | t.CPtr)(t.CVoid(mname_addr, t.CPtr))
@@ -1540,8 +1540,8 @@ class StructGenMixin:
return None
if idx >= entry.VTableMethodCount:
return None
methods_arr: t.CSizeT | t.CPtr = (t.CSizeT | t.CPtr)(t.CVoid(entry.VTableMethods, t.CPtr))
mname_addr: t.CSizeT = methods_arr[idx]
methods_arr: sizet | t.CPtr = (sizet | t.CPtr)(t.CVoid(entry.VTableMethods, t.CPtr))
mname_addr: sizet = methods_arr[idx]
if mname_addr == 0:
return None
return (str | t.CPtr)(t.CVoid(mname_addr, t.CPtr))
@@ -1594,14 +1594,14 @@ class StructGenMixin:
if class_name is None or class_name[0] == '\0':
return
# 提取 SHA1(sname 到 dot_pos 之间,用 strlen 避免指针减法)
total_len: t.CSizeT = string.strlen(sname)
class_name_len: t.CSizeT = string.strlen(class_name)
sha1_len: t.CSizeT = total_len - class_name_len - 1
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(32)
if sha1_buf is None:
return
# 32 字节缓冲:strncpy 不截断,前缀超过 31 字符会越界写 + 手动 NUL 再越界
sha1_cp: t.CSizeT = sha1_len
sha1_cp: sizet = sha1_len
if sha1_cp > 31:
sha1_cp = 31
string.strncpy(sha1_buf, sname, sha1_cp)
@@ -1638,7 +1638,7 @@ class StructGenMixin:
# 遍历字段链表
if fields is not None:
fld: llvmlite.ParamNode | t.CPtr = fields
cnt_ef: t.CInt = 0
cnt_ef: int = 0
while fld is not None:
# 步数守卫:字段链表成环(内存损坏)导致无限遍历挂起
# (G3 LinkedNode.prepend 挂起候选),超限立即报错终止
+107 -107
View File
@@ -44,7 +44,7 @@ import lib.core.Gen.Generator as Generator
# HandlesBody - 语句分派
# HandlesExpr - 表达式翻译
# HandlesFunctions - 函数定义处理
# 注意:str = bytes = t.CChar | t.CPtr = i8*
# 注意:str = bytes = str = i8*
#
# P6-E 对象化重构:模块级 global/nonlocal 名称管理函数已迁移为
# lib.core.Gen.TranslatorGenMixin 的方法,本模块保留同名模块级
@@ -81,7 +81,7 @@ class Translator:
# 函数表
_funcs: GenTypes.FuncEntry | t.CPtr
_func_count: t.CInt
_func_count: int
# 协程(TPV-M1 async def / await / coro.coro_run)
# _async_funcs: 已注册 async 函数裸名表(char* 数组,8 字节/项)
@@ -89,13 +89,13 @@ class Translator:
# _coro_locals: 当前 async 函数局部变量名表(char* 数组,8 字节/项)
# _coro_frames: async 名→帧类型 成对表(16 字节/项 = char* + LLVMType*)
_async_funcs: str
_async_func_count: t.CInt
_async_func_count: int
_coro_var_async: str
_coro_var_async_count: t.CInt
_coro_var_async_count: int
_coro_locals: str
_coro_local_count: t.CInt
_coro_local_count: int
_coro_frames: str
_coro_frame_count: t.CInt
_coro_frame_count: int
# resume_<name> 翻译上下文(AsyncGenMixin 段翻译共享)
_coro_state_ptr: llvmlite.Value | t.CPtr
_coro_done_ptr: llvmlite.Value | t.CPtr
@@ -103,35 +103,35 @@ class Translator:
_coro_exit_bb: llvmlite.BasicBlock | t.CPtr
_coro_await_slot: llvmlite.Value | t.CPtr
_coro_frame: llvmlite.Value | t.CPtr
_coro_next_state: t.CInt
_coro_nseg: t.CInt
_coro_next_state: int
_coro_nseg: int
# M2:async 参数表(char* 数组,8 字节/项)+ 预扫描计数
_coro_params: str
_coro_param_count: t.CInt
_coro_hoist_count: t.CInt # __await_N 槽计数(预扫描与翻译共用,序一致)
_coro_await_count: t.CInt # 总 await 数(= 恢复块数 = switch case 数)
_coro_local_base: t.CInt # 局部槽起始 index(= 3 + nparams)
_coro_extra_base: t.CInt # 额外槽(__await_N)起始 index
_coro_param_count: int
_coro_hoist_count: int # __await_N 槽计数(预扫描与翻译共用,序一致)
_coro_await_count: int # 总 await 数(= 恢复块数 = switch case 数)
_coro_local_base: int # 局部槽起始 index(= 3 + nparams)
_coro_extra_base: int # 额外槽(__await_N)起始 index
_coro_break_bb: llvmlite.BasicBlock | t.CPtr # While break 目标(M2 单层)
_coro_continue_bb: llvmlite.BasicBlock | t.CPtr # While continue 目标
_coro_state_bbs: t.CSizeT | t.CPtr # 预建 state 块数组(await 恢复块定位)
_coro_state_bbs: sizet | t.CPtr # 预建 state 块数组(await 恢复块定位)
# M3-M7 协程扩展
_coro_exc_ptr: llvmlite.Value | t.CPtr # 帧 exc 槽(i32,M4)
_coro_msg_ptr: llvmlite.Value | t.CPtr # 帧 msg 槽(i8*,M7)
_coro_wake_ptr: llvmlite.Value | t.CPtr # 帧 wake 槽(i64,M3 coro_sleep)
_coro_try_stack: t.CSizeT | t.CPtr # try 栈:except/finally 块指针数组(8B/项)
_coro_try_stack_count: t.CInt
_coro_for_counter: t.CInt # range-For 编号(M3,翻译期递增)
_coro_scan_for_count: t.CInt # 预扫描期 For 计数
_coro_uses_sleep: t.CInt # 函数体是否用 coro_sleep(预扫描置位)
_coro_try_stack: sizet | t.CPtr # try 栈:except/finally 块指针数组(8B/项)
_coro_try_stack_count: int
_coro_for_counter: int # range-For 编号(M3,翻译期递增)
_coro_scan_for_count: int # 预扫描期 For 计数
_coro_uses_sleep: int # 函数体是否用 coro_sleep(预扫描置位)
_coro_extra_types: str # 额外槽类型表(i8 数组:1=i32 2=i64)
_coro_extra_count: t.CInt # 额外槽总数
_coro_await_slots: t.CInt | t.CPtr # __await_N 的帧相对槽 index(预扫描填)
_coro_for_slots: t.CInt | t.CPtr # range-For N 的 __f_idx 帧相对槽 index(预扫描填)
_coro_extra_count: int # 额外槽总数
_coro_await_slots: int | t.CPtr # __await_N 的帧相对槽 index(预扫描填)
_coro_for_slots: int | t.CPtr # range-For N 的 __f_idx 帧相对槽 index(预扫描填)
# per-async wake 槽 index 表(coro_run/gather 轮询反查用)
_coro_wake_names: str # char* 数组(8B/项)
_coro_wake_idxs: t.CInt | t.CPtr # i32 数组(4B/项,-1=无 wake 槽)
_coro_wake_count: t.CInt
_coro_wake_idxs: int | t.CPtr # i32 数组(4B/项,-1=无 wake 槽)
_coro_wake_count: int
# 导入模块跟踪
_imported_modules: str
@@ -150,7 +150,7 @@ class Translator:
# 当前赋值语句的 RHS 节点(AnnAssign 翻译 rhs 前设置,rhs 翻译后清除)。
# 供 c.Deref 判定"是否为赋值直接 RHS":仅 v: int = c.Deref(p) 时用
# CurAssignAnnot 推断读取宽度;嵌套在 while 条件/比较/binop/类型转换
# 调用中(如 while c.Deref(p) != 0、total += t.CInt(c.Deref(p)))不推断,
# 调用中(如 while c.Deref(p) != 0、total += int(c.Deref(p)))不推断,
# 否则 i8* 会被残留 CurAssignAnnot 误判为 i32* 读 4 字节(对齐 TPC
# _infer_deref_target_type 的直接 RHS 检查)。
CurAssignNode: ast.AST | t.CPtr
@@ -160,28 +160,28 @@ class Translator:
_continue_bb: llvmlite.BasicBlock | t.CPtr
# 独立标签计数器(不与 builder.Counter 共享,避免 SSA 编号非单调)
_label_counter: t.CInt
_label_counter: int
# 追加90:控制流 merge 块可达性(1=有 br 进入可达/0=全分支 return 结构性不可达)
_ctrl_merge_reachable: t.CInt
_ctrl_merge_reachable: int
# match 翻译递归深度(match → case body → translate_value → 嵌套 match)。
# 守卫:AST 自引用环(子节点回指祖先)或翻译 bug 导致的无限递归在此
# fail-fast(对齐 TypeGenResolve 深度守卫,防 ASan stack-overflow)。
MatchTranslateDepth: t.CInt
MatchTranslateDepth: int
# 翻译主环递归深度(translate_stmt/translate_value 入口计数)。match 守卫
# 只覆盖 match 递归;语句/表达式/调用环(如 translate_value ↔ translate_call)
# 由本字段守卫,超 TRANSLATE_MAX_DEPTH 即 fail-fast(防 ASan stack-overflow)。
TranslateDepth: t.CInt
TranslateDepth: int
# global 声明的变量名集合(当前函数内)
_global_names: str
_global_name_count: t.CInt
_global_name_count: int
# nonlocal 声明的变量名集合(当前函数内)
_nonlocal_names: str
_nonlocal_name_count: t.CInt
_nonlocal_name_count: int
# nonlocal 变量的类型信息(LLVMType 指针数组,与 _nonlocal_names 一一对应)
# 用于 env 指针数组方案:子函数访问 nonlocal 变量时需要知道原始类型
_nonlocal_types: str
@@ -220,23 +220,23 @@ class Translator:
# None 表示当前文件是顶级模块(无包),相对导入无法解析
CurrentPackage: str
# 闭包 env 中的 nonlocal 变量偏移映射(每个 nonlocal 变量在 env 中的字节偏移)
_closure_env_offsets: t.CInt
_closure_env_count: t.CInt
_closure_env_offsets: int
_closure_env_count: int
# lambda 表达式全局唯一 ID 计数器(生成提升函数名 __lambda_{id})
# 独立于 _closure_env_count:后者随函数进入被 clear_scope_names 重置,
# lambda ID 需跨函数全局唯一(提升函数名避免冲突)
_lambda_count: t.CInt
_lambda_count: int
# 函数链内 nonlocal 变量集合(预扫描收集,含嵌套函数声明的 nonlocal)。
# 用于"不同层捕获不同变量"场景(如 level1→a, level2→b):b 定义在最外层
# 但 level1 不捕获——level1 env 无 b 槽,level2 无法经 env 链获取 b 的堆。
# 解决:在最外层函数中为链内所有 nonlocal 建堆,并把堆地址 store 到
# 模块级映射变量 @nlheap.{sha1}.{name};内层闭包创建时从映射 load。
_nl_chain_names: t.CVoid | t.CPtr
_nl_chain_count: t.CInt
_nl_chain_names: t.CPtr
_nl_chain_count: int
# 链内 nonlocal 堆预建标志(每函数只建一次):translate_function_def 进入
# 新函数时重置为 0;_prepare_chain_nonlocals 首次调用置 1。多个嵌套函数
# 定义共享同一堆(防重复 malloc + 二次重定向 VarEntry.Alloca)。
_nl_chain_done: t.CInt
_nl_chain_done: int
# 泛型特化上下文:当前正在特化的类型参数名/实参名列表
# 由 _specialize_generic_class 设置,方法体翻译时用于将 T 替换为具体类型
@@ -245,15 +245,15 @@ class Translator:
GenericTypeArgs: list[str] | t.CPtr
# Phase 1a 声明模式标志:1=只注册 struct/enum/union 不翻译代码体,0=全量翻译
_declare_only: t.CInt
_declare_only: int
# Phase A 依赖未就绪标志:1=本文件翻译时依赖模块的 text.ll 尚未生成
# (同项目源文件按顺序翻译,main.vp 先于其 import 的 mbuddytest.vp),
# 跨模块函数返回类型无法精确解析。Phase A 多遍循环据此下遍重试。
_deps_pending: t.CInt
_deps_pending: int
# [PF-DBG] 用后移除:语句级 pending 探针"已打第一次"标志
_pf_dbg_pend_flagged: t.CInt
_pf_dbg_pend_flagged: int
# 嵌套作用域符号表
SymTab: GenTypes.SymbolTable | t.CPtr
@@ -483,7 +483,7 @@ class Translator:
has_user_main: int = 0
ch: list[ast.AST | t.CPtr] | t.CPtr = tree.children
if ch is not None:
cn_count: t.CSizeT = len(ch)
cn_count: sizet = len(ch)
for ci in range(cn_count):
child: ast.AST | t.CPtr = ch.get(ci)
if child is not None and child.kind() == ast.ASTKind.FunctionDef:
@@ -532,7 +532,7 @@ class Translator:
cur_imp_lineno: int = 0
ch: list[ast.AST | t.CPtr] | t.CPtr = tree.children
if ch is not None:
cn_count: t.CSizeT = len(ch)
cn_count: sizet = len(ch)
for ci in range(cn_count):
child: ast.AST | t.CPtr = ch.get(ci)
if child is None:
@@ -638,67 +638,67 @@ class Translator:
stdlib.free(need_list_box)
stdlib.free(need_dict_box)
def _ContainerInjectionCreatesCycle(self, mod_name: str) -> int:
"""注入 mod_name(_list/_dict)前检查是否成环,返回 1=成环需跳过注入。
判断被注入模块自身的 deps 是否已含当前模块名。若命中(如 _list 显式
import memhub,而 memhub 因 `__provides__: list[str]` 注解要注入 _list)
→ memhub↔_list 循环依赖 → Phase A 多遍收敛死锁(gfx.vp "无法完成翻译"
根因)。对齐 Phase1Main._InjectedCreatesCycle,但本方法走 self.ModuleSha1
查 RelPath,覆盖所有 translate 路径(Phase1 1b 全量翻译、Phase2 pre-inc/
PhaseA 都会执行 _inject_auto_container_visibility)。命中则跳过注入:
去掉环边后,_list 已因当前模块被其依赖而处于闭包,list 类仍由
add_visible_struct 可见、泛型模板已由 Phase1 注册。
"""
if mod_name is None or self.ModuleSha1 is None:
return 0
inj_sha1: str = StubMergerStore.LookupSha1ByModName(mod_name)
if inj_sha1 is None:
return 0
inj_deps: str = StubMergerStore.LookupIncludesDeps(inj_sha1)
if inj_deps is None:
return 0
# 当前模块名 = RelPath 基名(最后 '/' 或 '\\' 之后)去扩展名
rel_path: str = StubMergerStore.LookupSha1RelPath(self.ModuleSha1)
if rel_path is None:
return 0
base: str = string.strrchr(rel_path, '/')
if base is None:
base = string.strrchr(rel_path, '\\')
if base is not None:
base = base + 1
else:
base = rel_path
dot: str = string.strchr(base, '.')
nm_buf: bytes = stdlib.malloc(128)
if nm_buf is None:
return 0
if dot is not None:
nm_len: t.CSizeT = t.CSizeT(t.CUInt64T(dot) - t.CUInt64T(base))
if nm_len > 127:
nm_len = 127
string.strncpy(nm_buf, base, nm_len)
nm_buf[nm_len] = '\0'
else:
string.strncpy(nm_buf, base, 127)
nm_buf[127] = '\0'
# 词边界精确匹配:inj_deps 中是否有 token 与当前模块名相同
nm_len2: t.CSizeT = string.strlen(nm_buf)
d_len: t.CSizeT = string.strlen(inj_deps)
dp: t.CSizeT = 0
while dp < d_len:
ts: t.CSizeT = dp
while dp < d_len and inj_deps[dp] != ' ':
dp += 1
tl: t.CSizeT = dp - ts
if dp < d_len:
dp += 1
if tl > 0 and tl == nm_len2 and string.strncmp(inj_deps + ts, nm_buf, tl) == 0:
stdlib.free(nm_buf)
return 1
stdlib.free(nm_buf)
return 0
def _ContainerInjectionCreatesCycle(self, mod_name: str) -> int:
"""注入 mod_name(_list/_dict)前检查是否成环,返回 1=成环需跳过注入。
判断被注入模块自身的 deps 是否已含当前模块名。若命中(如 _list 显式
import memhub,而 memhub 因 `__provides__: list[str]` 注解要注入 _list)
→ memhub↔_list 循环依赖 → Phase A 多遍收敛死锁(gfx.vp "无法完成翻译"
根因)。对齐 Phase1Main._InjectedCreatesCycle,但本方法走 self.ModuleSha1
查 RelPath,覆盖所有 translate 路径(Phase1 1b 全量翻译、Phase2 pre-inc/
PhaseA 都会执行 _inject_auto_container_visibility)。命中则跳过注入:
去掉环边后,_list 已因当前模块被其依赖而处于闭包,list 类仍由
add_visible_struct 可见、泛型模板已由 Phase1 注册。
"""
if mod_name is None or self.ModuleSha1 is None:
return 0
inj_sha1: str = StubMergerStore.LookupSha1ByModName(mod_name)
if inj_sha1 is None:
return 0
inj_deps: str = StubMergerStore.LookupIncludesDeps(inj_sha1)
if inj_deps is None:
return 0
# 当前模块名 = RelPath 基名(最后 '/' 或 '\\' 之后)去扩展名
rel_path: str = StubMergerStore.LookupSha1RelPath(self.ModuleSha1)
if rel_path is None:
return 0
base: str = string.strrchr(rel_path, '/')
if base is None:
base = string.strrchr(rel_path, '\\')
if base is not None:
base = base + 1
else:
base = rel_path
dot: str = string.strchr(base, '.')
nm_buf: bytes = stdlib.malloc(128)
if nm_buf is None:
return 0
if dot is not None:
nm_len: sizet = sizet(uint64(dot) - uint64(base))
if nm_len > 127:
nm_len = 127
string.strncpy(nm_buf, base, nm_len)
nm_buf[nm_len] = '\0'
else:
string.strncpy(nm_buf, base, 127)
nm_buf[127] = '\0'
# 词边界精确匹配:inj_deps 中是否有 token 与当前模块名相同
nm_len2: sizet = string.strlen(nm_buf)
d_len: sizet = string.strlen(inj_deps)
dp: sizet = 0
while dp < d_len:
ts: sizet = dp
while dp < d_len and inj_deps[dp] != ' ':
dp += 1
tl: sizet = dp - ts
if dp < d_len:
dp += 1
if tl > 0 and tl == nm_len2 and string.strncmp(inj_deps + ts, nm_buf, tl) == 0:
stdlib.free(nm_buf)
return 1
stdlib.free(nm_buf)
return 0
def _scan_container_usage(self, node: ast.AST | t.CPtr,
need_list_box: t.CPtr,
need_dict_box: t.CPtr):
@@ -726,8 +726,8 @@ class Translator:
args_s: ast.Arguments | t.CPtr = (ast.Arguments | t.CPtr)(fd_s.args)
if args_s.args is not None:
args_list_s: list[ast.AST | t.CPtr] | t.CPtr = args_s.args
an_s: t.CSizeT = len(args_list_s)
ai_s: t.CSizeT
an_s: sizet = len(args_list_s)
ai_s: sizet
for ai_s in range(an_s):
arg_s: ast.AST | t.CPtr = args_list_s.get(ai_s)
if arg_s is not None:
@@ -745,7 +745,7 @@ class Translator:
# 递归语句块子节点
if node.children is not None:
ch_s: list[ast.AST | t.CPtr] | t.CPtr = node.children
n_s: t.CSizeT = len(ch_s)
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)
@@ -802,7 +802,7 @@ class Translator:
# ============================================================
# IR 输出
# ============================================================
def dump_ir(self, buf: bytes, size: t.CSizeT, mode: int):
def dump_ir(self, buf: bytes, size: sizet, mode: int):
"""将 LLVM IR 输出到缓冲区
mode: 0=完整, 1=stub(仅声明), 2=text(仅代码)
+79 -79
View File
@@ -85,13 +85,13 @@ class TranslatorGenMixin:
tree: AST 模块节点
Returns:
t.CInt: 新增的变量数
int: 新增的变量数
"""
ch: list[ast.AST | t.CPtr] | t.CPtr = tree.children
if ch is None:
return 0
cn_count: t.CSizeT = len(ch)
cn_count: sizet = len(ch)
added_total: int = 0
for ci in range(cn_count):
@@ -185,8 +185,8 @@ class TranslatorGenMixin:
ags: ast.Arguments | t.CPtr = (ast.Arguments | t.CPtr)(fd.args)
if ags.args is not None:
al: list[ast.AST | t.CPtr] | t.CPtr = ags.args
an: t.CSizeT = len(al)
ai: t.CSizeT
an: sizet = len(al)
ai: sizet
for ai in range(an):
ag: ast.Arg | t.CPtr = (ast.Arg | t.CPtr)(al.get(ai))
if ag is not None and ag.annotation is not None:
@@ -213,7 +213,7 @@ class TranslatorGenMixin:
# 从 var_ty 提取数组元素类型和数量
elem_ty: llvmlite.LLVMType | t.CPtr = None
arr_count: t.CInt = 0
arr_count: int = 0
match var_ty:
case llvmlite.LLVMType.Array(et, cnt):
elem_ty = et
@@ -243,12 +243,12 @@ class TranslatorGenMixin:
elts: list[ast.AST | t.CPtr] | t.CPtr = ln.elts
if elts is None:
return None
elts_count: t.CSizeT = len(elts)
elts_count: sizet = len(elts)
# 元素数超过声明长度 → fail-fast(此前在下方循环中按声明长度截断、静默丢弃
# 多余元素:apic._trampoline_bin 声明 [128 x i8] 却给出 138 个字节 → 末尾
# mov rax,[0x7F28]; jmp rax 被丢弃,AP trampoline 失效)。
if t.CSizeT(arr_count) < elts_count:
if sizet(arr_count) < elts_count:
self.Gen.TypeGenErr.fatal_error(
list_node,
f"数组初始化元素数 {elts_count} 超过数组声明长度 {arr_count},不允许静默截断",
@@ -262,7 +262,7 @@ class TranslatorGenMixin:
# llc "constant expression type mismatch" 根因)。含非零/非整数常量
# 无法文本表达 → None → 调用方 fail-fast。
if is_int_elem == 0:
# 嵌套数组元素(t.CArray[t.CArray[t.CUInt8T, 16], 256] = [{...}, ...]):
# 嵌套数组元素(t.CArray[t.CArray[uint8, 16], 256] = [{...}, ...]):
# elem_ty 是 Array → 递归构建子数组初始化器文本。内层类型省略
# (由外层全局类型推断),llc 合法。vga.vp font 8x16 点阵字库根因:
# 此前只支持 Int 元素,嵌套数组走 zeroinitializer-only 检查,花括号
@@ -274,13 +274,13 @@ class TranslatorGenMixin:
case _:
pass
if is_nested_arr != 0:
cnt_total_n: t.CSizeT = t.CSizeT(arr_count)
buf_size_n: t.CSizeT = 128 + cnt_total_n * 192
cnt_total_n: sizet = sizet(arr_count)
buf_size_n: sizet = 128 + cnt_total_n * 192
buf_n: str = pool.alloc(buf_size_n)
if buf_n is None:
return None
written_n: t.CInt = viperlib.snprintf(buf_n, buf_size_n, "[")
pos_n: t.CSizeT = t.CSizeT(written_n)
written_n: int = viperlib.snprintf(buf_n, buf_size_n, "[")
pos_n: sizet = sizet(written_n)
# 子数组元素类型前缀(如 "[16 x i8]"):嵌套数组初始化器内层
# 必须显式类型(llc 对省略内层类型的 [[i8 0,...],...] 报
# "expected number in address space";用户规范要求
@@ -289,7 +289,7 @@ class TranslatorGenMixin:
if elem_ty_str_n is None:
return None
llvmlite.TypePrint(elem_ty_str_n, 96, elem_ty, pool)
i_n: t.CSizeT = 0
i_n: sizet = 0
while i_n < cnt_total_n:
sub_n: str = None
if i_n < elts_count:
@@ -311,10 +311,10 @@ class TranslatorGenMixin:
sub_n = "zeroinitializer"
if i_n > 0:
written_n = viperlib.snprintf(buf_n + pos_n, buf_size_n - pos_n, ", ")
pos_n += t.CSizeT(written_n)
pos_n += sizet(written_n)
written_n = viperlib.snprintf(
buf_n + pos_n, buf_size_n - pos_n, "%s%s", elem_ty_str_n, sub_n)
pos_n += t.CSizeT(written_n)
pos_n += sizet(written_n)
i_n += 1
viperlib.snprintf(buf_n + pos_n, buf_size_n - pos_n, "]")
return buf_n
@@ -344,26 +344,26 @@ class TranslatorGenMixin:
# 计算缓冲区大小: 每个元素最多 "i32 -9223372036854775808, " 约 26 字符
# 按数组声明长度 arr_count 计算(元素不足时补零,可能多于 elts_count)
cnt_total: t.CSizeT = t.CSizeT(arr_count)
buf_size: t.CSizeT = 64 + cnt_total * 32
cnt_total: sizet = sizet(arr_count)
buf_size: sizet = 64 + cnt_total * 32
buf: str = pool.alloc(buf_size)
if buf is None:
return None
# 写入前缀: "["(类型前缀由 _print_global 输出,初始化器只需元素列表)
written: t.CInt = viperlib.snprintf(buf, buf_size, "[")
pos: t.CSizeT = t.CSizeT(written)
written: int = viperlib.snprintf(buf, buf_size, "[")
pos: sizet = sizet(written)
# 逐个元素写入:元素数必须与数组声明长度 arr_count 一致,
# 列表元素不足时补零(如 g_arr: t.CArray[t.CInt, 4] = [0] →
# 列表元素不足时补零(如 g_arr: t.CArray[int, 4] = [0] →
# [i32 0, i32 0, i32 0, i32 0]),否则 llc 报
# "constant expression type mismatch: got type '[1 x i32]' but expected '[4 x i32]'"
i: t.CSizeT = 0
i: sizet = 0
while i < cnt_total:
elem_val: t.CInt64T = 0
elem_val: int64 = 0
if i < elts_count:
elem_node: ast.AST | t.CPtr = elts.get(i)
# 直接从 Constant 节点提取 int_val(避免 extract_cdefine_int_value 的 t.CInt 截断)
# 直接从 Constant 节点提取 int_val(避免 extract_cdefine_int_value 的 int 截断)
if elem_node is not None:
ek: int = elem_node.kind()
if ek == ast.ASTKind.Constant:
@@ -382,15 +382,15 @@ class TranslatorGenMixin:
# → 保持 0(由下方按声明长度补零)。
elif ec is not None and ec.const_kind == ast.CONST_STR:
if ec.str_val is not None and string.strlen(ec.str_val) == 1:
elem_val = t.CInt64T(ec.str_val[0])
elem_val = int64(ec.str_val[0])
elif ek == ast.ASTKind.UnaryOp:
# 负数: UnaryOp(USub, Constant)
elem_val = self.Gen.AssignGen.extract_cdefine_int_value(elem_node)
if i > 0:
written = viperlib.snprintf(buf + pos, buf_size - pos, ", ")
pos += t.CSizeT(written)
pos += sizet(written)
written = viperlib.snprintf(buf + pos, buf_size - pos, "%s %lld", elem_ir_ty, elem_val)
pos += t.CSizeT(written)
pos += sizet(written)
i += 1
# 写入后缀 "]"
@@ -400,7 +400,7 @@ class TranslatorGenMixin:
# ============================================================
# _build_string_array_initializer_text - 字符串字面量初始化数组全局
#
# t.CArray[t.CChar, N] = "..." → [i8 b0, i8 b1, ..., i8 0, ...]
# t.CArray[char, N] = "..." → [i8 b0, i8 b1, ..., i8 0, ...]
# (字符串字节 + 零填充到数组长度;空串返回 zeroinitializer)。
# 此前统一走字符串指针 GEP 初始化器 → @g = global [N x i8] <ptr>
# 类型不匹配(llc constant expression type mismatch,
@@ -412,31 +412,31 @@ class TranslatorGenMixin:
"""字符串字面量初始化数组全局,返回初始化器文本或 None"""
if var_ty is None or str_val is None:
return None
arr_count: t.CInt = 0
arr_count: int = 0
match var_ty:
case llvmlite.LLVMType.Array(_, cnt):
arr_count = cnt
if arr_count <= 0:
return None
slen: t.CSizeT = string.strlen(str_val)
slen: sizet = string.strlen(str_val)
if slen == 0:
return "zeroinitializer"
buf_size: t.CSizeT = 64 + t.CSizeT(arr_count) * 16
buf_size: sizet = 64 + sizet(arr_count) * 16
buf: str = pool.alloc(buf_size)
if buf is None:
return None
written: t.CInt = viperlib.snprintf(buf, buf_size, "[")
pos: t.CSizeT = t.CSizeT(written)
i: t.CSizeT = 0
while i < t.CSizeT(arr_count):
written: int = viperlib.snprintf(buf, buf_size, "[")
pos: sizet = sizet(written)
i: sizet = 0
while i < sizet(arr_count):
if i > 0:
written = viperlib.snprintf(buf + pos, buf_size - pos, ", ")
pos += t.CSizeT(written)
bv: t.CInt64T = 0
pos += sizet(written)
bv: int64 = 0
if i < slen:
bv = t.CInt64T(str_val[i])
bv = int64(str_val[i])
written = viperlib.snprintf(buf + pos, buf_size - pos, "i8 %lld", bv)
pos += t.CSizeT(written)
pos += sizet(written)
i += 1
viperlib.snprintf(buf + pos, buf_size - pos, "]")
return buf
@@ -446,7 +446,7 @@ class TranslatorGenMixin:
#
# 创建内部字符串常量全局 @.str.{var_name} = private constant [len+1 x i8] c"...\00"
# 返回 GEP 初始化器文本: getelementptr inbounds ([len+1 x i8], [len+1 x i8]* @.str.{var_name}, i32 0, i32 0)
# 用于 b64_tab: t.CArray[t.CChar, None] = "ABC..." 等字符串初始化指针类型
# 用于 b64_tab: t.CArray[char, None] = "ABC..." 等字符串初始化指针类型
# ============================================================
def _build_string_ptr_initializer(self, pool: memhub.MemBuddy | t.CPtr,
mod: llvmlite.LLVMModule | t.CPtr,
@@ -469,7 +469,7 @@ class TranslatorGenMixin:
return None
# 生成 GEP 初始化器文本
str_len: t.CSizeT = string.strlen(str_val)
str_len: sizet = string.strlen(str_val)
init_buf: str = pool.alloc(128)
if init_buf is None:
return None
@@ -518,7 +518,7 @@ class TranslatorGenMixin:
if dval is None or fty is None or ty_str is None:
return None
is_int: int = 0
dv_int: t.CInt64T = 0
dv_int: int64 = 0
if dval.kind() == ast.ASTKind.Constant:
dc: ast.Constant | t.CPtr = (ast.Constant | t.CPtr)(dval)
if dc is not None:
@@ -562,11 +562,11 @@ class TranslatorGenMixin:
fc: int = se.FieldCount
if fc <= start_idx:
return None
buf_size: t.CSizeT = 256 + t.CSizeT(fc) * 160
buf_size: sizet = 256 + sizet(fc) * 160
buf: str = pool.alloc(buf_size)
if buf is None:
return None
pos: t.CSizeT = 0
pos: sizet = 0
first: int = 1
has_nonzero: int = 0
i: int = start_idx
@@ -586,12 +586,12 @@ class TranslatorGenMixin:
is_zero = 1
if elem is None:
continue
written: t.CInt = 0
written: int = 0
if first == 0:
written = viperlib.snprintf(buf + pos, buf_size - pos, ", ")
pos += t.CSizeT(written)
pos += sizet(written)
written = viperlib.snprintf(buf + pos, buf_size - pos, "%s", elem)
pos += t.CSizeT(written)
pos += sizet(written)
first = 0
if is_zero == 0:
has_nonzero = 1
@@ -615,7 +615,7 @@ class TranslatorGenMixin:
body: str = self._build_stg_struct_body_text(pool, se, start_idx)
if body is None:
return None
body_len: t.CSizeT = t.CSizeT(string.strlen(body))
body_len: sizet = sizet(string.strlen(body))
buf: str = pool.alloc(body_len + 8)
if buf is None:
return None
@@ -649,7 +649,7 @@ class TranslatorGenMixin:
self.Gen.AssignGen._register_cdefine_from_value(
pool, nm_cd.id, aa_cd.value)
return 0
# CTypedef 注解(如 posix.vp mode_t: t.CTypedef = t.CUInt32T):
# CTypedef 注解(如 posix.vp mode_t: t.CTypedef = uint32):
# 不创建全局变量——否则生成 @mode_t 符号 → 链接 duplicate
# symbol warning。预注册阶段(forward_declare_functions
# 之前)按需注册到 CTypedef 表:翻译期表已被 clear_ctypedefs
@@ -673,7 +673,7 @@ class TranslatorGenMixin:
var_ty: llvmlite.LLVMType | t.CPtr = llvmlite.Int32(pool)
resolved_stg_ty: llvmlite.LLVMType | t.CPtr = None # 对象类全局:静态 storage 类型(BSS 实例)
resolved_stg_entry: GenTypes.StructEntry | t.CPtr = None # 对象类全局:对应 StructEntry(vtable 初始化用)
init_val: t.CInt64T = 0
init_val: int64 = 0
init_fval: t.CDouble = 0.0 # init_kind==4(浮点字面量)时的数值
init_kind: int = 0 # 0=none, 1=int, 2=list, 3=str, 4=float
init_str_val: str = None
@@ -752,7 +752,7 @@ class TranslatorGenMixin:
# 见下方 init_kind==4 的源文件恢复逻辑。
init_kind = 4
elif val_kind == ast.ASTKind.UnaryOp:
# 负数/按位取反字面量(如 `_vblank_ok: t.CInt = -1`):
# 负数/按位取反字面量(如 `_vblank_ok: int = -1`):
# AST 是 UnaryOp(USub, Constant),此前未处理 → init_kind 保持 0
# → 全局编译成 zeroinitializer(desktop 7 个 -1 初始化全部丢失
# → _drag_idx=0 无条件拖拽窗口 0 / _focused_win=0 事件错路由根因)。
@@ -905,7 +905,7 @@ class TranslatorGenMixin:
self.Gen.TypeGenErr.fatal_error(node, f"模块级变量 '{var_name}' 初始化器构建失败", "TypeError")
elif init_kind == 3:
# 字符串字面量初始化
# 数组类型(t.CArray[t.CChar, N]):字节数组初始化器(字符串内容 + 零填充)
# 数组类型(t.CArray[char, N]):字节数组初始化器(字符串内容 + 零填充)
# ——此前统一走字符串指针 GEP 初始化器 → @g = global [N x i8] <ptr> 类型
# 不匹配(llc constant expression type mismatch,pyzlib_error_msg 根因)
is_arr_g: int = 0
@@ -923,7 +923,7 @@ class TranslatorGenMixin:
self.Gen.TypeGenErr.fatal_error(
node, f"模块级数组变量 '{var_name}' 字符串初始化器构建失败", "TypeError")
else:
# 指针类型(如 b64_tab: t.CArray[t.CChar, None] = "ABC..."):
# 指针类型(如 b64_tab: t.CArray[char, None] = "ABC..."):
# 创建字符串常量全局 + GEP 引用
str_init: str = self._build_string_ptr_initializer(pool, mod, var_name, init_str_val)
if str_init is not None:
@@ -992,16 +992,16 @@ class TranslatorGenMixin:
if vt_mangled is not None:
# 完整 struct 初始化器(LLVM 拒绝部分初始化):
# 字段 0 = __vtable__(i8* @vtable),其余用户字段按类型零值。
init_full_len: t.CSizeT = 16384
init_full_len: sizet = 16384
init_full: str = pool.alloc(init_full_len)
if init_full is not None:
written_v: t.CInt = viperlib.snprintf(init_full, init_full_len, "{ ")
pos_v: t.CSizeT = t.CSizeT(written_v)
written_v: int = viperlib.snprintf(init_full, init_full_len, "{ ")
pos_v: sizet = sizet(written_v)
if self.Gen.ClassGenVTable._vtable_name_needs_quote(vt_mangled) != 0:
written_v = viperlib.snprintf(init_full + pos_v, init_full_len - pos_v, "i8* @\"%s\"", vt_mangled)
else:
written_v = viperlib.snprintf(init_full + pos_v, init_full_len - pos_v, "i8* @%s", vt_mangled)
pos_v += t.CSizeT(written_v)
pos_v += sizet(written_v)
# 字段 1..N 优先按字段默认值折叠(vtable 对象全局
# 如 `_mbuddy: MemBuddy` 的字段默认不再丢失);
# 全部默认值恰为零时回退逐字段零值,避免无谓文本。
@@ -1010,7 +1010,7 @@ class TranslatorGenMixin:
pool, resolved_stg_entry, 1)
if rest_v is not None:
written_v = viperlib.snprintf(init_full + pos_v, init_full_len - pos_v, ", %s", rest_v)
pos_v += t.CSizeT(written_v)
pos_v += sizet(written_v)
else:
fc_v: int = resolved_stg_entry.FieldCount
for fi_v in range(1, fc_v):
@@ -1026,7 +1026,7 @@ class TranslatorGenMixin:
if zero_v is None:
continue
written_v = viperlib.snprintf(init_full + pos_v, init_full_len - pos_v, ", %s", zero_v)
pos_v += t.CSizeT(written_v)
pos_v += sizet(written_v)
viperlib.snprintf(init_full + pos_v, init_full_len - pos_v, " }")
stg_init_text = init_full
elif resolved_stg_entry is not None:
@@ -1040,7 +1040,7 @@ class TranslatorGenMixin:
pool, resolved_stg_entry, 0)
if stg_default_text is not None:
stg_init_text = stg_default_text
stg_name_len: t.CSizeT = t.CSizeT(string.strlen(mangled_name)) + 8
stg_name_len: sizet = sizet(string.strlen(mangled_name)) + 8
stg_name_buf: str = pool.alloc(stg_name_len)
if stg_name_buf is not None:
viperlib.snprintf(stg_name_buf, stg_name_len, "%s.stg", mangled_name)
@@ -1054,7 +1054,7 @@ class TranslatorGenMixin:
if resolved_stg_entry is not None and resolved_stg_entry.Align > 0:
stg_gv.Align = resolved_stg_entry.Align
# @g 初始值 = &@storage(对象引用指向 BSS 实例,非 NULL)
stg_init_len: t.CSizeT = t.CSizeT(string.strlen(mangled_name)) + 8
stg_init_len: sizet = sizet(string.strlen(mangled_name)) + 8
stg_init_buf: str = pool.alloc(stg_init_len)
if stg_init_buf is not None:
if self.Gen.ClassGenVTable._vtable_name_needs_quote(stg_name_buf) != 0:
@@ -1067,7 +1067,7 @@ class TranslatorGenMixin:
stg_ref: llvmlite.Value | t.CPtr = self.Gen.ExprGenAttr.make_global_ref(
pool, stg_name_buf, resolved_stg_ty)
if stg_ref is not None:
stg_key_len: t.CSizeT = t.CSizeT(string.strlen(var_name)) + 8
stg_key_len: sizet = sizet(string.strlen(var_name)) + 8
stg_key: str = pool.alloc(stg_key_len)
if stg_key is not None:
viperlib.snprintf(stg_key, stg_key_len, "%s.__stg", var_name)
@@ -1130,7 +1130,7 @@ class TranslatorGenMixin:
i32_ty: i32 LLVMType
Returns:
t.CInt: 新增的变量数
int: 新增的变量数
"""
pool: memhub.MemBuddy | t.CPtr = trans.Pool
mod: llvmlite.LLVMModule | t.CPtr = trans.Module
@@ -1162,7 +1162,7 @@ class TranslatorGenMixin:
# 导致其他函数通过 SSA 编号引用 wrapper main 的局部变量(无效 IR)
ch: list[ast.AST | t.CPtr] | t.CPtr = tree.children
if ch is not None:
cn_count: t.CSizeT = len(ch)
cn_count: sizet = len(ch)
for ci in range(cn_count):
child: ast.AST | t.CPtr = ch.get(ci)
if child is not None:
@@ -1210,8 +1210,8 @@ class TranslatorGenMixin:
else:
VLogger.error("global 变量数量超过上限,请减少 global 声明或增大 MAX_GLOBAL_NAMES", "ScopeDecl")
return
entry_addr: t.CUInt64T = t.CUInt64T(trans._global_names) + trans._global_name_count * 8
slot_ptr: str | t.CPtr = (t.CVoid | t.CPtr)(entry_addr)
entry_addr: uint64 = uint64(trans._global_names) + trans._global_name_count * 8
slot_ptr: str | t.CPtr = (t.CPtr)(entry_addr)
slot_ptr[0] = name
trans._global_name_count += 1
@@ -1220,8 +1220,8 @@ class TranslatorGenMixin:
if trans is None or name is None or trans._global_names is None:
return 0
for i in range(trans._global_name_count):
entry_addr: t.CUInt64T = t.CUInt64T(trans._global_names) + i * 8
slot_ptr: str | t.CPtr = (t.CVoid | t.CPtr)(entry_addr)
entry_addr: uint64 = uint64(trans._global_names) + i * 8
slot_ptr: str | t.CPtr = (t.CPtr)(entry_addr)
entry: str = slot_ptr[0]
if entry is not None:
if string.strcmp(entry, name) == 0:
@@ -1249,8 +1249,8 @@ class TranslatorGenMixin:
if var_ty is not None and trans._nonlocal_types is not None:
idx: int = self.get_nonlocal_index(trans, name)
if idx >= 0:
ty_addr: t.CUInt64T = t.CUInt64T(trans._nonlocal_types) + idx * 8
ty_slot: str | t.CPtr = (t.CVoid | t.CPtr)(ty_addr)
ty_addr: uint64 = uint64(trans._nonlocal_types) + idx * 8
ty_slot: str | t.CPtr = (t.CPtr)(ty_addr)
ty_slot[0] = var_ty
return
if trans._nonlocal_name_count >= MAX_GLOBAL_NAMES:
@@ -1264,13 +1264,13 @@ class TranslatorGenMixin:
else:
VLogger.error("nonlocal 变量数量超过上限,请减少 nonlocal 声明或增大 MAX_GLOBAL_NAMES", "ScopeDecl")
return
entry_addr: t.CUInt64T = t.CUInt64T(trans._nonlocal_names) + trans._nonlocal_name_count * 8
slot_ptr: str | t.CPtr = (t.CVoid | t.CPtr)(entry_addr)
entry_addr: uint64 = uint64(trans._nonlocal_names) + trans._nonlocal_name_count * 8
slot_ptr: str | t.CPtr = (t.CPtr)(entry_addr)
slot_ptr[0] = name
# 存储类型信息(用 str|t.CPtr = i8** 二级指针,与 _nonlocal_names 一致)
if trans._nonlocal_types is not None:
ty_addr2: t.CUInt64T = t.CUInt64T(trans._nonlocal_types) + trans._nonlocal_name_count * 8
ty_slot2: str | t.CPtr = (t.CVoid | t.CPtr)(ty_addr2)
ty_addr2: uint64 = uint64(trans._nonlocal_types) + trans._nonlocal_name_count * 8
ty_slot2: str | t.CPtr = (t.CPtr)(ty_addr2)
# var_ty 为 None 时直接报错终止(fail-fast),不再默认 i32
stored_ty: llvmlite.LLVMType | t.CPtr = var_ty
if stored_ty is None:
@@ -1291,8 +1291,8 @@ class TranslatorGenMixin:
idx: int = self.get_nonlocal_index(trans, name)
if idx < 0:
return None
ty_addr: t.CUInt64T = t.CUInt64T(trans._nonlocal_types) + idx * 8
ty_slot: str | t.CPtr = (t.CVoid | t.CPtr)(ty_addr)
ty_addr: uint64 = uint64(trans._nonlocal_types) + idx * 8
ty_slot: str | t.CPtr = (t.CPtr)(ty_addr)
return (llvmlite.LLVMType | t.CPtr)(ty_slot[0])
def is_nonlocal_name(self, trans: HT.Translator | t.CPtr, name: str) -> int:
@@ -1300,8 +1300,8 @@ class TranslatorGenMixin:
if trans is None or name is None or trans._nonlocal_names is None:
return 0
for i in range(trans._nonlocal_name_count):
entry_addr: t.CUInt64T = t.CUInt64T(trans._nonlocal_names) + i * 8
slot_ptr: str | t.CPtr = (t.CVoid | t.CPtr)(entry_addr)
entry_addr: uint64 = uint64(trans._nonlocal_names) + i * 8
slot_ptr: str | t.CPtr = (t.CPtr)(entry_addr)
entry: str = slot_ptr[0]
if entry is not None:
if string.strcmp(entry, name) == 0:
@@ -1313,8 +1313,8 @@ class TranslatorGenMixin:
if trans is None or name is None or trans._nonlocal_names is None:
return -1
for i in range(trans._nonlocal_name_count):
entry_addr: t.CUInt64T = t.CUInt64T(trans._nonlocal_names) + i * 8
slot_ptr: str | t.CPtr = (t.CVoid | t.CPtr)(entry_addr)
entry_addr: uint64 = uint64(trans._nonlocal_names) + i * 8
slot_ptr: str | t.CPtr = (t.CPtr)(entry_addr)
entry: str = slot_ptr[0]
if entry is not None:
if string.strcmp(entry, name) == 0:
+255 -255
View File
@@ -1,256 +1,256 @@
import lib.core.Gen.Type.TypeGenMixin as TypeGenMixin
import lib.core.Gen.GenTypes as GenTypes
import lib.core.Gen.Generator as Generator
import t, c
from stdint import *
import ast
import llvmlite
import memhub
import string
import viperlib
import stdio
import stdlib
import lib.core.VLogger as VLogger
import lib.Stub.StubMerger as StubMerger
import lib.core.CompilerFactory as CompilerFactory
# ============================================================
# TypeGenBase - TypeGenMixin 拆分(阶段 D):字段 + InitTypeGen + trace/临时目录/generic 上下文
#
# 继承 TypeGenBase(1 级,TPV self 调用仅支持 1 级父类)。
# 跨 Mixin 调用统一走 HandlesType 委托(经 _g_gen)。
# @t.NoVTable:静态绑定。
# ============================================================
@t.NoVTable
class TypeGenBase:
"""字段 + InitTypeGen + trace/临时目录/generic 上下文"""
# --- 仿 Python Traceback 调用栈(原 _g_trace_frames/_g_trace_count) ---
Gen: Generator.Generator | t.CPtr
TraceFrames: GenTypes.TraceFrame | t.CPtr # malloc 数组(TypeGenMixin.TRACE_MAX 槽)
TraceCount: int
# --- 全局泛型特化上下文(原 _g_generic_tp_names/_g_generic_type_args) ---
GenericTpNames: list[str] | t.CPtr
GenericTypeArgs: list[str] | t.CPtr
# 嵌套安全栈:set_generic_context 压入外层值,clear_generic_context 弹出
# 恢复(原单槽赋值:嵌套特化/泛型函数翻译退出时把外层上下文清成 None →
# 外层方法体后续的 T 替换丢失 → T.__sizeof__() NameError,VectorGenericTest
# 特化 Vector[int].__init__ 回归根因)。
GenericCtxStack: t.CSizeT | t.CPtr # i64* 固定数组:每层 2 个槽(tp_names, type_args 指针)
GenericCtxDepth: int
# --- 全局 CDefine 编译期常量表(原 _g_cdefine_*) ---
CDefineNames: list[str] | t.CPtr
CDefineValues: list[str] | t.CPtr
CDefineDoubleFlags: list[int] | t.CPtr
CDefineStrFlags: list[int] | t.CPtr # 1=字符串值(如 ZLIB_VERSION: t.CDefine = "1.3.2")
CDefineIsDouble: int
CDefineIsStr: int
CDefineFound: int
# --- 跨模块 CDefine 查找缓存(perm_pool 永久分配,跨文件复用) ---
# 2026-08-14:跨模块 CDefine 查找(_lookup_cross_module_cdefine)结果缓存到
# perm_pool,reset_to(mark2)/clear_cdefine_constants 不清除 → 跨文件复用,
# CONST_INT 递归查找只做一次(NewAstTest OOM 根因)。
XmodCdefNames: list[str] | t.CPtr
XmodCdefValues: list[str] | t.CPtr
XmodCdefDoubleFlags: list[int] | t.CPtr
XmodCdefStrFlags: list[int] | t.CPtr
# --- 当前模块 SHA1(原 _g_current_module_sha1) ---
CurrentModuleSha1: str
# --- 全局 CTypedef 表(原 _g_ctypedef_*) ---
CTypedefNames: list[str] | t.CPtr
CTypedefTypeStrs: list[str] | t.CPtr
CTypedefFound: int
CTypedefResolveDepth: int
CTypedefVisiting: list[str] | t.CPtr
# builtins 源扫描标记:注解解析"最后匹配"兜底(_lookup_builtins_typedef)
# 每文件最多读一次 includes/builtins.vp;随 clear_ctypedefs 复位
BuiltinsTypedefScanned: int
# builtins 最后匹配诊断("变量类型注解解析失败"详细报错用):
# LastBuiltinsTypedefName = 最后一次请求的名称;LastBuiltinsTypedefResult =
# 展开后的类型表达式(未命中 = None)。随 clear_ctypedefs 复位。
# 两个被指串由以下自有缓冲承载(stdlib.malloc,clear_ctypedefs 释放):
# 调用方常传临时缓冲(VpiReader._resolve_single_vpi_type_str 的段缓冲
# malloc 后立刻 free),直接存指针会悬垂 → _build_ann_fail_msg 的
# snprintf 读已释放内存(ASan heap-use-after-free)。
LastBuiltinsTypedefName: str
LastBuiltinsTypedefResult: str
LastBuiltinsTypedefNameBuf: bytes
LastBuiltinsTypedefResultBuf: bytes
# builtins import 别名缓冲(stdlib.malloc,格式 "alias\0target\0" 连续段):
# _lookup_builtins_typedef 扫描 builtins.vp import 行填充;库 typedef 模块
# 限定引用按别名还原真实模块名(__stdint.size_t → stdint.size_t)。
# 用 malloc 而非 pool list——pool 每文件 reset_to 后 list 悬空(clear_ctypedefs
# 未覆盖的路径读到已释放内存 → strcmp 崩溃,1.log 根因);malloc 跨 pool
# 生命周期存活,clear_ctypedefs 释放置空。
ImportAliasBuf: bytes
# --- 常量整数表达式计算成功标志(原 _g_const_eval_ok) ---
ConstEvalOk: int
# --- 全局当前文件名(原 _g_current_file) ---
CurrentFile: str
def InitTypeGen(self) -> int:
"""初始化类型 Mixin 字段(子类构造时内联调用,规避 NoVTable 继承符号不转发)"""
if self is None:
return 1
self.TraceFrames = None
self.TraceCount = 0
self.GenericTpNames = None
self.GenericTypeArgs = None
self.GenericCtxStack = None
self.GenericCtxDepth = 0
self.CDefineNames = None
self.CDefineValues = None
self.CDefineDoubleFlags = None
self.CDefineStrFlags = None
self.CDefineIsDouble = 0
self.CDefineIsStr = 0
self.CDefineFound = 0
self.XmodCdefNames = None
self.XmodCdefValues = None
self.XmodCdefDoubleFlags = None
self.XmodCdefStrFlags = None
self.CurrentModuleSha1 = None
self.CTypedefNames = None
self.CTypedefTypeStrs = None
self.CTypedefFound = 0
self.CTypedefResolveDepth = 0
self.CTypedefVisiting = None
self.BuiltinsTypedefScanned = 0
self.LastBuiltinsTypedefName = None
self.LastBuiltinsTypedefResult = None
self.LastBuiltinsTypedefNameBuf = None
self.LastBuiltinsTypedefResultBuf = None
self.ImportAliasBuf = None
self.ConstEvalOk = 0
self.CurrentFile = None
return 0
# ============================================================
# P2 迁移方法(函数体来自 HandlesType.vp,全局变量改 self.字段,
# 同模块函数调用改 self.方法;签名与 HandlesType 原函数一致)
# ============================================================
def _ensure_trace_init(self) -> int:
"""确保调用栈已初始化(懒加载,用 malloc 不依赖 pool)"""
if self.TraceFrames is not None:
return 1
entry_size: t.CSizeT = GenTypes.TraceFrame.__sizeof__()
self.TraceFrames = CompilerFactory.factory.PermPool.alloc(entry_size * TypeGenMixin.TRACE_MAX)
if self.TraceFrames is None:
return 0
string.memset(self.TraceFrames, 0, entry_size * TypeGenMixin.TRACE_MAX)
return 1
def _get_trace_frame(self, i: int) -> GenTypes.TraceFrame | t.CPtr:
"""获取第 i 个 TraceFrame 槽位"""
if self.TraceFrames is None or i < 0 or i >= TypeGenMixin.TRACE_MAX:
return None
entry_size: t.CSizeT = GenTypes.TraceFrame.__sizeof__()
addr: t.CUInt64T = t.CUInt64T(self.TraceFrames) + i * entry_size
return (GenTypes.TraceFrame | t.CPtr)(t.CVoid(addr, t.CPtr))
def push_trace(self, file_name: str, lineno: int, col_start: int = 0, col_end: int = 0) -> None:
"""压入一个翻译上下文帧(进入新的翻译作用域时调用)"""
if self._ensure_trace_init() == 0:
return
if self.TraceCount >= TypeGenMixin.TRACE_MAX:
return
frame: GenTypes.TraceFrame | t.CPtr = self._get_trace_frame(self.TraceCount)
if frame is None:
return
frame.file_name = file_name
frame.lineno = lineno
frame.col_start = col_start
frame.col_end = col_end
self.TraceCount += 1
def pop_trace(self) -> None:
"""弹出栈顶帧(退出翻译作用域时调用)"""
if self.TraceCount <= 0:
return
self.TraceCount -= 1
frame: GenTypes.TraceFrame | t.CPtr = self._get_trace_frame(self.TraceCount)
if frame is not None:
frame.file_name = None
frame.lineno = 0
frame.col_start = 0
frame.col_end = 0
def clear_trace(self) -> None:
"""清空调用栈(每个文件翻译开始前调用)"""
i: int
for i in range(self.TraceCount):
frame: GenTypes.TraceFrame | t.CPtr = self._get_trace_frame(i)
if frame is not None:
frame.file_name = None
frame.lineno = 0
frame.col_start = 0
frame.col_end = 0
self.TraceCount = 0
def set_temp_dir(self, temp_dir: str) -> None:
"""设置全局 temp_dir(统一写入 CallGenBase.TempDir,跨子对象经 Gen 指针)"""
self.Gen.CallGenBase.SetTempDir(temp_dir)
def get_temp_dir(self) -> str:
"""获取全局 temp_dir(从 CallGenBase 读取)"""
return self.Gen.CallGenBase.TempDir
def set_current_module_sha1(self, sha1: str) -> None:
"""设置当前正在编译的模块 SHA1(Phase1 在模块开始翻译前调用)"""
self.CurrentModuleSha1 = sha1
def _dbg_check_ast_floats(self, mb: memhub.MemBuddy | t.CPtr,
tree: ast.AST | t.CPtr, tag: str):
"""已移除调试插桩(占位保留签名,避免外部调用引用失败)"""
pass
def set_generic_context(self, tp_names: list[str] | t.CPtr,
type_args: list[str] | t.CPtr):
"""设置泛型特化上下文(进入泛型类方法体翻译时调用),嵌套安全
先压栈当前(外层)上下文,再设置新值。clear_generic_context 弹出恢复,
避免嵌套特化/泛型函数翻译退出时清空外层上下文(T.__sizeof__() 回归根因)。
"""
if self.GenericCtxStack is None:
self.GenericCtxStack = stdlib.malloc(8 * 2 * 32)
if self.GenericCtxStack is None:
self.GenericTpNames = tp_names
self.GenericTypeArgs = type_args
return
self.GenericCtxDepth = 0
if self.GenericCtxDepth < 32:
self.GenericCtxStack[self.GenericCtxDepth * 2] = t.CSizeT(self.GenericTpNames)
self.GenericCtxStack[self.GenericCtxDepth * 2 + 1] = t.CSizeT(self.GenericTypeArgs)
self.GenericCtxDepth += 1
self.GenericTpNames = tp_names
self.GenericTypeArgs = type_args
def clear_generic_context(self):
"""清除泛型特化上下文(离开泛型类方法体翻译时调用),恢复外层而非置 None"""
if self.GenericCtxDepth > 0:
self.GenericCtxDepth -= 1
self.GenericTpNames = (list[str] | t.CPtr)(t.CVoid(
self.GenericCtxStack[self.GenericCtxDepth * 2], t.CPtr))
self.GenericTypeArgs = (list[str] | t.CPtr)(t.CVoid(
self.GenericCtxStack[self.GenericCtxDepth * 2 + 1], t.CPtr))
else:
self.GenericTpNames = None
self.GenericTypeArgs = None
def resolve_generic_type_name(self, name: str) -> str:
"""如果 name 是泛型类型参数,返回对应的具体类型名;否则返回 name 本身
用于表达式中的 T 替换(如 T.__sizeof__() → int.__sizeof__())
"""
if name is None:
return name
rv_d: str = name
if self.GenericTpNames is not None and self.GenericTypeArgs is not None:
rg_n: t.CSizeT = len(self.GenericTpNames)
rg_i: t.CSizeT
for rg_i in range(rg_n):
rg_tpn: str = self.GenericTpNames.get(rg_i)
if rg_tpn is not None and string.strcmp(name, rg_tpn) == 0:
rg_ta: str = self.GenericTypeArgs.get(rg_i)
if rg_ta is not None:
rv_d = rg_ta
break
import lib.core.Gen.Type.TypeGenMixin as TypeGenMixin
import lib.core.Gen.GenTypes as GenTypes
import lib.core.Gen.Generator as Generator
import t, c
from stdint import *
import ast
import llvmlite
import memhub
import string
import viperlib
import stdio
import stdlib
import lib.core.VLogger as VLogger
import lib.Stub.StubMerger as StubMerger
import lib.core.CompilerFactory as CompilerFactory
# ============================================================
# TypeGenBase - TypeGenMixin 拆分(阶段 D):字段 + InitTypeGen + trace/临时目录/generic 上下文
#
# 继承 TypeGenBase(1 级,TPV self 调用仅支持 1 级父类)。
# 跨 Mixin 调用统一走 HandlesType 委托(经 _g_gen)。
# @t.NoVTable:静态绑定。
# ============================================================
@t.NoVTable
class TypeGenBase:
"""字段 + InitTypeGen + trace/临时目录/generic 上下文"""
# --- 仿 Python Traceback 调用栈(原 _g_trace_frames/_g_trace_count) ---
Gen: Generator.Generator | t.CPtr
TraceFrames: GenTypes.TraceFrame | t.CPtr # malloc 数组(TypeGenMixin.TRACE_MAX 槽)
TraceCount: int
# --- 全局泛型特化上下文(原 _g_generic_tp_names/_g_generic_type_args) ---
GenericTpNames: list[str] | t.CPtr
GenericTypeArgs: list[str] | t.CPtr
# 嵌套安全栈:set_generic_context 压入外层值,clear_generic_context 弹出
# 恢复(原单槽赋值:嵌套特化/泛型函数翻译退出时把外层上下文清成 None →
# 外层方法体后续的 T 替换丢失 → T.__sizeof__() NameError,VectorGenericTest
# 特化 Vector[int].__init__ 回归根因)。
GenericCtxStack: sizet | t.CPtr # i64* 固定数组:每层 2 个槽(tp_names, type_args 指针)
GenericCtxDepth: int
# --- 全局 CDefine 编译期常量表(原 _g_cdefine_*) ---
CDefineNames: list[str] | t.CPtr
CDefineValues: list[str] | t.CPtr
CDefineDoubleFlags: list[int] | t.CPtr
CDefineStrFlags: list[int] | t.CPtr # 1=字符串值(如 ZLIB_VERSION: t.CDefine = "1.3.2")
CDefineIsDouble: int
CDefineIsStr: int
CDefineFound: int
# --- 跨模块 CDefine 查找缓存(perm_pool 永久分配,跨文件复用) ---
# 2026-08-14:跨模块 CDefine 查找(_lookup_cross_module_cdefine)结果缓存到
# perm_pool,reset_to(mark2)/clear_cdefine_constants 不清除 → 跨文件复用,
# CONST_INT 递归查找只做一次(NewAstTest OOM 根因)。
XmodCdefNames: list[str] | t.CPtr
XmodCdefValues: list[str] | t.CPtr
XmodCdefDoubleFlags: list[int] | t.CPtr
XmodCdefStrFlags: list[int] | t.CPtr
# --- 当前模块 SHA1(原 _g_current_module_sha1) ---
CurrentModuleSha1: str
# --- 全局 CTypedef 表(原 _g_ctypedef_*) ---
CTypedefNames: list[str] | t.CPtr
CTypedefTypeStrs: list[str] | t.CPtr
CTypedefFound: int
CTypedefResolveDepth: int
CTypedefVisiting: list[str] | t.CPtr
# builtins 源扫描标记:注解解析"最后匹配"兜底(_lookup_builtins_typedef)
# 每文件最多读一次 includes/builtins.vp;随 clear_ctypedefs 复位
BuiltinsTypedefScanned: int
# builtins 最后匹配诊断("变量类型注解解析失败"详细报错用):
# LastBuiltinsTypedefName = 最后一次请求的名称;LastBuiltinsTypedefResult =
# 展开后的类型表达式(未命中 = None)。随 clear_ctypedefs 复位。
# 两个被指串由以下自有缓冲承载(stdlib.malloc,clear_ctypedefs 释放):
# 调用方常传临时缓冲(VpiReader._resolve_single_vpi_type_str 的段缓冲
# malloc 后立刻 free),直接存指针会悬垂 → _build_ann_fail_msg 的
# snprintf 读已释放内存(ASan heap-use-after-free)。
LastBuiltinsTypedefName: str
LastBuiltinsTypedefResult: str
LastBuiltinsTypedefNameBuf: bytes
LastBuiltinsTypedefResultBuf: bytes
# builtins import 别名缓冲(stdlib.malloc,格式 "alias\0target\0" 连续段):
# _lookup_builtins_typedef 扫描 builtins.vp import 行填充;库 typedef 模块
# 限定引用按别名还原真实模块名(__stdint.size_t → stdint.size_t)。
# 用 malloc 而非 pool list——pool 每文件 reset_to 后 list 悬空(clear_ctypedefs
# 未覆盖的路径读到已释放内存 → strcmp 崩溃,1.log 根因);malloc 跨 pool
# 生命周期存活,clear_ctypedefs 释放置空。
ImportAliasBuf: bytes
# --- 常量整数表达式计算成功标志(原 _g_const_eval_ok) ---
ConstEvalOk: int
# --- 全局当前文件名(原 _g_current_file) ---
CurrentFile: str
def InitTypeGen(self) -> int:
"""初始化类型 Mixin 字段(子类构造时内联调用,规避 NoVTable 继承符号不转发)"""
if self is None:
return 1
self.TraceFrames = None
self.TraceCount = 0
self.GenericTpNames = None
self.GenericTypeArgs = None
self.GenericCtxStack = None
self.GenericCtxDepth = 0
self.CDefineNames = None
self.CDefineValues = None
self.CDefineDoubleFlags = None
self.CDefineStrFlags = None
self.CDefineIsDouble = 0
self.CDefineIsStr = 0
self.CDefineFound = 0
self.XmodCdefNames = None
self.XmodCdefValues = None
self.XmodCdefDoubleFlags = None
self.XmodCdefStrFlags = None
self.CurrentModuleSha1 = None
self.CTypedefNames = None
self.CTypedefTypeStrs = None
self.CTypedefFound = 0
self.CTypedefResolveDepth = 0
self.CTypedefVisiting = None
self.BuiltinsTypedefScanned = 0
self.LastBuiltinsTypedefName = None
self.LastBuiltinsTypedefResult = None
self.LastBuiltinsTypedefNameBuf = None
self.LastBuiltinsTypedefResultBuf = None
self.ImportAliasBuf = None
self.ConstEvalOk = 0
self.CurrentFile = None
return 0
# ============================================================
# P2 迁移方法(函数体来自 HandlesType.vp,全局变量改 self.字段,
# 同模块函数调用改 self.方法;签名与 HandlesType 原函数一致)
# ============================================================
def _ensure_trace_init(self) -> int:
"""确保调用栈已初始化(懒加载,用 malloc 不依赖 pool)"""
if self.TraceFrames is not None:
return 1
entry_size: sizet = GenTypes.TraceFrame.__sizeof__()
self.TraceFrames = CompilerFactory.factory.PermPool.alloc(entry_size * TypeGenMixin.TRACE_MAX)
if self.TraceFrames is None:
return 0
string.memset(self.TraceFrames, 0, entry_size * TypeGenMixin.TRACE_MAX)
return 1
def _get_trace_frame(self, i: int) -> GenTypes.TraceFrame | t.CPtr:
"""获取第 i 个 TraceFrame 槽位"""
if self.TraceFrames is None or i < 0 or i >= TypeGenMixin.TRACE_MAX:
return None
entry_size: sizet = GenTypes.TraceFrame.__sizeof__()
addr: uint64 = uint64(self.TraceFrames) + i * entry_size
return (GenTypes.TraceFrame | t.CPtr)(t.CVoid(addr, t.CPtr))
def push_trace(self, file_name: str, lineno: int, col_start: int = 0, col_end: int = 0) -> None:
"""压入一个翻译上下文帧(进入新的翻译作用域时调用)"""
if self._ensure_trace_init() == 0:
return
if self.TraceCount >= TypeGenMixin.TRACE_MAX:
return
frame: GenTypes.TraceFrame | t.CPtr = self._get_trace_frame(self.TraceCount)
if frame is None:
return
frame.file_name = file_name
frame.lineno = lineno
frame.col_start = col_start
frame.col_end = col_end
self.TraceCount += 1
def pop_trace(self) -> None:
"""弹出栈顶帧(退出翻译作用域时调用)"""
if self.TraceCount <= 0:
return
self.TraceCount -= 1
frame: GenTypes.TraceFrame | t.CPtr = self._get_trace_frame(self.TraceCount)
if frame is not None:
frame.file_name = None
frame.lineno = 0
frame.col_start = 0
frame.col_end = 0
def clear_trace(self) -> None:
"""清空调用栈(每个文件翻译开始前调用)"""
i: int
for i in range(self.TraceCount):
frame: GenTypes.TraceFrame | t.CPtr = self._get_trace_frame(i)
if frame is not None:
frame.file_name = None
frame.lineno = 0
frame.col_start = 0
frame.col_end = 0
self.TraceCount = 0
def set_temp_dir(self, temp_dir: str) -> None:
"""设置全局 temp_dir(统一写入 CallGenBase.TempDir,跨子对象经 Gen 指针)"""
self.Gen.CallGenBase.SetTempDir(temp_dir)
def get_temp_dir(self) -> str:
"""获取全局 temp_dir(从 CallGenBase 读取)"""
return self.Gen.CallGenBase.TempDir
def set_current_module_sha1(self, sha1: str) -> None:
"""设置当前正在编译的模块 SHA1(Phase1 在模块开始翻译前调用)"""
self.CurrentModuleSha1 = sha1
def _dbg_check_ast_floats(self, mb: memhub.MemBuddy | t.CPtr,
tree: ast.AST | t.CPtr, tag: str):
"""已移除调试插桩(占位保留签名,避免外部调用引用失败)"""
pass
def set_generic_context(self, tp_names: list[str] | t.CPtr,
type_args: list[str] | t.CPtr):
"""设置泛型特化上下文(进入泛型类方法体翻译时调用),嵌套安全
先压栈当前(外层)上下文,再设置新值。clear_generic_context 弹出恢复,
避免嵌套特化/泛型函数翻译退出时清空外层上下文(T.__sizeof__() 回归根因)。
"""
if self.GenericCtxStack is None:
self.GenericCtxStack = stdlib.malloc(8 * 2 * 32)
if self.GenericCtxStack is None:
self.GenericTpNames = tp_names
self.GenericTypeArgs = type_args
return
self.GenericCtxDepth = 0
if self.GenericCtxDepth < 32:
self.GenericCtxStack[self.GenericCtxDepth * 2] = sizet(self.GenericTpNames)
self.GenericCtxStack[self.GenericCtxDepth * 2 + 1] = sizet(self.GenericTypeArgs)
self.GenericCtxDepth += 1
self.GenericTpNames = tp_names
self.GenericTypeArgs = type_args
def clear_generic_context(self):
"""清除泛型特化上下文(离开泛型类方法体翻译时调用),恢复外层而非置 None"""
if self.GenericCtxDepth > 0:
self.GenericCtxDepth -= 1
self.GenericTpNames = (list[str] | t.CPtr)(t.CVoid(
self.GenericCtxStack[self.GenericCtxDepth * 2], t.CPtr))
self.GenericTypeArgs = (list[str] | t.CPtr)(t.CVoid(
self.GenericCtxStack[self.GenericCtxDepth * 2 + 1], t.CPtr))
else:
self.GenericTpNames = None
self.GenericTypeArgs = None
def resolve_generic_type_name(self, name: str) -> str:
"""如果 name 是泛型类型参数,返回对应的具体类型名;否则返回 name 本身
用于表达式中的 T 替换(如 T.__sizeof__() → int.__sizeof__())
"""
if name is None:
return name
rv_d: str = name
if self.GenericTpNames is not None and self.GenericTypeArgs is not None:
rg_n: sizet = len(self.GenericTpNames)
rg_i: sizet
for rg_i in range(rg_n):
rg_tpn: str = self.GenericTpNames.get(rg_i)
if rg_tpn is not None and string.strcmp(name, rg_tpn) == 0:
rg_ta: str = self.GenericTypeArgs.get(rg_i)
if rg_ta is not None:
rv_d = rg_ta
break
return rv_d
+15 -15
View File
@@ -27,7 +27,7 @@ class TypeGenCDef(TypeGenBase.TypeGenBase):
"""CDefine 编译期常量表(register/lookup/is/set/clear)"""
def register_cdefine_constant(self, pool: memhub.MemBuddy | t.CPtr,
name: str, value: t.CInt64T) -> None:
name: str, value: int64) -> None:
"""注册 CDefine 编译期常量到本地表
值以十进制字符串存储(64 位 %lld)。大整数 CDefine(如
@@ -98,7 +98,7 @@ class TypeGenCDef(TypeGenBase.TypeGenBase):
self.CDefineDoubleFlags = list[int](pool, 64)
self.CDefineStrFlags = list[int](pool, 64)
self.CDefineNames.append(name)
vlen: t.CSizeT = string.strlen(value)
vlen: sizet = string.strlen(value)
vcopy: str = pool.alloc(vlen + 1)
if vcopy is None:
self.Gen.TypeGenErr.fatal_error(None, f"CDefine 字符串值分配失败: {name}", "MemoryError")
@@ -134,8 +134,8 @@ class TypeGenCDef(TypeGenBase.TypeGenBase):
return
# 去重:同名已缓存则跳过(首次查找结果为准,CDefine 全局唯一约定)
if self.XmodCdefNames is not None:
x_n: t.CSizeT = len(self.XmodCdefNames)
x_i: t.CSizeT
x_n: sizet = len(self.XmodCdefNames)
x_i: sizet
for x_i in range(x_n):
x_nm: str = self.XmodCdefNames.get(x_i)
if x_nm is not None and string.strcmp(x_nm, name) == 0:
@@ -148,12 +148,12 @@ class TypeGenCDef(TypeGenBase.TypeGenBase):
self.XmodCdefStrFlags = list[int](perm, 64)
# key/value 深拷贝到 perm_pool:入参(pool.alloc 临时缓冲)在
# reset_to(mark2) 后悬空,append 只存指针 → 必须深拷贝跨 reset 存活
klen: t.CSizeT = string.strlen(name)
klen: sizet = string.strlen(name)
kcopy: str = perm.alloc(klen + 1)
if kcopy is None:
return
string.strcpy(kcopy, name)
vlen: t.CSizeT = string.strlen(value_str)
vlen: sizet = string.strlen(value_str)
vcopy: str = perm.alloc(vlen + 1)
if vcopy is None:
return
@@ -175,8 +175,8 @@ class TypeGenCDef(TypeGenBase.TypeGenBase):
self.CDefineIsStr = 0
if name is None or self.XmodCdefNames is None:
return None
n: t.CSizeT = len(self.XmodCdefNames)
i: t.CSizeT
n: sizet = len(self.XmodCdefNames)
i: sizet
for i in range(n):
nm: str = self.XmodCdefNames.get(i)
if nm is not None and string.strcmp(nm, name) == 0:
@@ -189,7 +189,7 @@ class TypeGenCDef(TypeGenBase.TypeGenBase):
self.CDefineIsDouble = 1
return val_str
return None
def lookup_cdefine_constant(self, name: str) -> t.CInt64T:
def lookup_cdefine_constant(self, name: str) -> int64:
"""查找 CDefine 编译期常量
返回找到的值(64 位,大整数 CDefine 如 sys.maxsize 全精度)。
@@ -203,8 +203,8 @@ class TypeGenCDef(TypeGenBase.TypeGenBase):
self.CDefineIsStr = 0
if self.CDefineNames is None:
return 0
n: t.CSizeT = len(self.CDefineNames)
i: t.CSizeT
n: sizet = len(self.CDefineNames)
i: sizet
for i in range(n):
nm: str = self.CDefineNames.get(i)
if nm is not None and string.strcmp(nm, name) == 0:
@@ -232,8 +232,8 @@ class TypeGenCDef(TypeGenBase.TypeGenBase):
self.CDefineIsStr = 0
if self.CDefineNames is None:
return 0.0
n: t.CSizeT = len(self.CDefineNames)
i: t.CSizeT
n: sizet = len(self.CDefineNames)
i: sizet
for i in range(n):
nm: str = self.CDefineNames.get(i)
if nm is not None and string.strcmp(nm, name) == 0:
@@ -261,8 +261,8 @@ class TypeGenCDef(TypeGenBase.TypeGenBase):
self.CDefineIsStr = 0
if self.CDefineNames is None:
return None
n: t.CSizeT = len(self.CDefineNames)
i: t.CSizeT
n: sizet = len(self.CDefineNames)
i: sizet
for i in range(n):
nm: str = self.CDefineNames.get(i)
if nm is not None and string.strcmp(nm, name) == 0:
+55 -55
View File
@@ -13,9 +13,9 @@ import lib.Stub.StubMerger as StubMerger
import lib.core.CompilerFactory as CompilerFactory
import lib.core.Gen.Type.TypeGenBase as TypeGenBase
# builtins 诊断串自有缓冲长度(仅服务"变量类型注解解析失败"报错文本)
import lib.core.Gen.Type.TypeGenBase as TypeGenBase
# builtins 诊断串自有缓冲长度(仅服务"变量类型注解解析失败"报错文本)
TYPEDEF_DIAG_BUF: t.CDefine = 256
# ============================================================
@@ -36,7 +36,7 @@ class TypeGenCType(TypeGenBase.TypeGenBase):
Args:
pool: 内存池
name: CTypedef 名称(如 "HANDLE")
type_str: 类型表达式字符串(如 "VOIDPTR" 或 "t.CVoid | t.CPtr")
type_str: 类型表达式字符串(如 "VOIDPTR" 或 "t.CPtr")
"""
if name is None or type_str is None or pool is None:
return
@@ -49,12 +49,12 @@ class TypeGenCType(TypeGenBase.TypeGenBase):
# (如 .vpi 读取缓冲区),缓冲区随后被 free 会导致表项悬空、
# lookup_ctypedef strcmp 失配、typedef 退化为 i8*(testcheck
# SetConsoleOutputCP 的 UINT 根因)。表须持有自己的字符串副本。
name_len: t.CSizeT = string.strlen(name)
name_len: sizet = string.strlen(name)
name_copy: str = pool.alloc(name_len + 1)
if name_copy is None:
return
string.strcpy(name_copy, name)
type_len: t.CSizeT = string.strlen(type_str)
type_len: sizet = string.strlen(type_str)
type_copy: str = pool.alloc(type_len + 1)
if type_copy is None:
return
@@ -64,8 +64,8 @@ class TypeGenCType(TypeGenBase.TypeGenBase):
self.CTypedefTypeStrs = list[str](pool, 64)
# 去重:若已存在同名 CTypedef,更新其类型字符串
if self.CTypedefNames is not None:
exist_n: t.CSizeT = len(self.CTypedefNames)
ei: t.CSizeT
exist_n: sizet = len(self.CTypedefNames)
ei: sizet
for ei in range(exist_n):
en: str = self.CTypedefNames.get(ei)
if en is not None and string.strcmp(en, name_copy) == 0:
@@ -74,31 +74,31 @@ class TypeGenCType(TypeGenBase.TypeGenBase):
return
self.CTypedefNames.append(name_copy)
self.CTypedefTypeStrs.append(type_copy)
def store_builtins_diag(self, which: int, text: str) -> str:
"""把 builtins 诊断串复制进自有缓冲并返回该缓冲(which: 0=Name, 1=Result)
调用方(VpiReader._resolve_single_vpi_type_str)传的往往是
stdlib.malloc 的临时段缓冲,返回前即 free——直接存指针会让
_build_ann_fail_msg 的 snprintf 读已释放内存(ASan
heap-use-after-free)。诊断字段必须持有自己的副本。
text 为 None 时返回 None("未命中"标记)。
"""
if text is None:
return None
if which == 0:
if self.LastBuiltinsTypedefNameBuf is None:
self.LastBuiltinsTypedefNameBuf = stdlib.malloc(TYPEDEF_DIAG_BUF)
buf: str = self.LastBuiltinsTypedefNameBuf
else:
if self.LastBuiltinsTypedefResultBuf is None:
self.LastBuiltinsTypedefResultBuf = stdlib.malloc(TYPEDEF_DIAG_BUF)
buf = self.LastBuiltinsTypedefResultBuf
if buf is None:
return None
string.strncpy(buf, text, TYPEDEF_DIAG_BUF - 1)
buf[TYPEDEF_DIAG_BUF - 1] = '\0'
return buf
def store_builtins_diag(self, which: int, text: str) -> str:
"""把 builtins 诊断串复制进自有缓冲并返回该缓冲(which: 0=Name, 1=Result)
调用方(VpiReader._resolve_single_vpi_type_str)传的往往是
stdlib.malloc 的临时段缓冲,返回前即 free——直接存指针会让
_build_ann_fail_msg 的 snprintf 读已释放内存(ASan
heap-use-after-free)。诊断字段必须持有自己的副本。
text 为 None 时返回 None("未命中"标记)。
"""
if text is None:
return None
if which == 0:
if self.LastBuiltinsTypedefNameBuf is None:
self.LastBuiltinsTypedefNameBuf = stdlib.malloc(TYPEDEF_DIAG_BUF)
buf: str = self.LastBuiltinsTypedefNameBuf
else:
if self.LastBuiltinsTypedefResultBuf is None:
self.LastBuiltinsTypedefResultBuf = stdlib.malloc(TYPEDEF_DIAG_BUF)
buf = self.LastBuiltinsTypedefResultBuf
if buf is None:
return None
string.strncpy(buf, text, TYPEDEF_DIAG_BUF - 1)
buf[TYPEDEF_DIAG_BUF - 1] = '\0'
return buf
def lookup_ctypedef(self, name: str) -> str:
"""查找 CTypedef,返回类型表达式字符串
@@ -110,8 +110,8 @@ class TypeGenCType(TypeGenBase.TypeGenBase):
return None
if self.CTypedefNames is None:
return None
n: t.CSizeT = len(self.CTypedefNames)
i: t.CSizeT
n: sizet = len(self.CTypedefNames)
i: sizet
for i in range(n):
nm: str = self.CTypedefNames.get(i)
if nm is not None and string.strcmp(nm, name) == 0:
@@ -156,8 +156,8 @@ class TypeGenCType(TypeGenBase.TypeGenBase):
self.CTypedefVisiting = list[str](pool, 32)
if self.CTypedefVisiting is None:
return 0
vn: t.CSizeT = len(self.CTypedefVisiting)
vi: t.CSizeT
vn: sizet = len(self.CTypedefVisiting)
vi: sizet
for vi in range(vn):
vs: str = self.CTypedefVisiting.get(vi)
if vs is not None and string.strcmp(vs, name) == 0:
@@ -168,7 +168,7 @@ class TypeGenCType(TypeGenBase.TypeGenBase):
"""从正在解析列表弹出最后一个 CTypedef 名"""
if self.CTypedefVisiting is None:
return
vn: t.CSizeT = len(self.CTypedefVisiting)
vn: sizet = len(self.CTypedefVisiting)
if vn > 0:
self.CTypedefVisiting.pop()
def _is_ctypedef_annotation(self, annotation: ast.AST | t.CPtr) -> int:
@@ -198,7 +198,7 @@ class TypeGenCType(TypeGenBase.TypeGenBase):
# 只读 8 字节,再校验第 9 字节为终止/分隔符(防 "CTypedefXXX" 误匹配)。
if string.strncmp(at_attr_v, "CTypedef", 8) != 0:
return 0
sep_ch_d: t.CChar = at_attr_v[8]
sep_ch_d: char = at_attr_v[8]
if sep_ch_d != '\0' and sep_ch_d != ' ' and sep_ch_d != '\n' \
and sep_ch_d != '\r' and sep_ch_d != '\t' and sep_ch_d != '|':
return 0
@@ -212,7 +212,7 @@ class TypeGenCType(TypeGenBase.TypeGenBase):
# 同样限长比较("t" 无 NUL 结尾时 strcmp 读穿)
if string.strncmp(mod_id_v, "t", 1) != 0:
return 0
sep_ch_m: t.CChar = mod_id_v[1]
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
@@ -236,9 +236,9 @@ class TypeGenCType(TypeGenBase.TypeGenBase):
ch: list[ast.AST | t.CPtr] | t.CPtr = tree.children
if ch is None:
return 0
n: t.CSizeT = len(ch)
n: sizet = len(ch)
count: int = 0
i: t.CSizeT
i: sizet
for i in range(n):
child: ast.AST | t.CPtr = ch.get(i)
if child is None:
@@ -286,19 +286,19 @@ class TypeGenCType(TypeGenBase.TypeGenBase):
# 0xC0000005(1.log: stdint.vp 翻译时 strcmp 读地址 0x4)。先清表
# 重建,杜绝悬空遍历。翻译期 Handle 按需注册不受影响(L800 会再清)。
self.clear_ctypedefs()
src_len: t.CSizeT = string.strlen(src)
src_len: sizet = string.strlen(src)
count: int = 0
line_start: t.CSizeT = 0
i: t.CSizeT = 0
line_start: sizet = 0
i: sizet = 0
while i <= src_len:
if i == src_len or src[i] == '\n':
line_len: t.CSizeT = i - line_start
line_len: sizet = i - line_start
if line_len > 0:
# 找行内第一个 ':'(跳过注释行)
j: t.CSizeT = 0
j: sizet = 0
found_colon: int = 0
while j < line_len:
ch_c: t.CChar = src[line_start + j]
ch_c: char = src[line_start + j]
if ch_c == ':':
found_colon = 1
break
@@ -307,7 +307,7 @@ class TypeGenCType(TypeGenBase.TypeGenBase):
j += 1
if found_colon != 0:
# 左段 NAME(trim 尾随空格)
name_len: t.CSizeT = j
name_len: sizet = j
while name_len > 0 and src[line_start + name_len - 1] == ' ':
name_len -= 1
if name_len > 0 and name_len < 128:
@@ -319,16 +319,16 @@ class TypeGenCType(TypeGenBase.TypeGenBase):
if eq_ptr is not None:
# '=' 相对行首偏移;值段严格限定在行尾
# (line_len)内——防止跨行吞换行+后续行内容
eq_off: t.CSizeT = t.CSizeT(t.CUInt64T(eq_ptr) - t.CUInt64T(src)) - line_start
vs: t.CSizeT = eq_off + 1
eq_off: sizet = sizet(uint64(eq_ptr) - uint64(src)) - line_start
vs: sizet = eq_off + 1
while vs < line_len and src[line_start + vs] == ' ':
vs += 1
ve: t.CSizeT = line_len
ve: sizet = line_len
while ve > vs and (src[line_start + ve - 1] == ' '
or src[line_start + ve - 1] == '\r'):
ve -= 1
if ve > vs:
vlen: t.CSizeT = ve - vs
vlen: sizet = ve - vs
name_buf: str = pool.alloc(name_len + 1)
ty_buf: str = pool.alloc(vlen + 1)
if name_buf is not None and ty_buf is not None:
@@ -397,7 +397,7 @@ class TypeGenCType(TypeGenBase.TypeGenBase):
return val
# Attribute: 模块限定常量名,如 hashlib.MD5_DIGEST_LEN
# (t.CArray[t.CUInt8T, hashlib.MD5_DIGEST_LEN] 的 count 是 Attribute,
# (t.CArray[uint8, hashlib.MD5_DIGEST_LEN] 的 count 是 Attribute,
# 复用跨模块 CDefine 查找:*:模块 → 源文件提取;re-export 常量由
# _lookup_cross_module_cdefine 的 from-import 递归子模块兜底)
if k == ast.ASTKind.Attribute:
@@ -410,7 +410,7 @@ class TypeGenCType(TypeGenBase.TypeGenBase):
if at_mod.id is not None:
if (from_imports is not None or imported_modules is not None) \
and pool is not None:
mod_len: t.CSizeT = string.strlen(at_mod.id)
mod_len: sizet = string.strlen(at_mod.id)
fi_buf: str = pool.alloc(mod_len + 3)
if fi_buf is not None:
fi_buf[0] = '*'
+16 -16
View File
@@ -44,7 +44,7 @@ class TypeGenErr(TypeGenBase.TypeGenBase):
if fsize <= 0 or fsize > 67108864:
f.close()
return None
src_size: t.CSizeT = t.CSizeT(fsize)
src_size: sizet = sizet(fsize)
buf: bytes = stdlib.malloc(src_size + 1)
if buf is None:
f.close()
@@ -56,11 +56,11 @@ class TypeGenErr(TypeGenBase.TypeGenBase):
return None
# 逐行查找第 lineno 行
cur_line: int = 1
line_start: t.CSizeT = 0
line_start: sizet = 0
for i in range(bytes_read):
if buf[i] == '\n':
if cur_line == lineno:
line_len: t.CSizeT = i - line_start
line_len: sizet = i - line_start
if line_len > 0 and buf[line_start + line_len - 1] == '\r':
line_len -= 1
line_buf: bytes = stdlib.malloc(line_len + 1)
@@ -242,7 +242,7 @@ class TypeGenErr(TypeGenBase.TypeGenBase):
"""检测函数体是否为 pass(空体或仅含 pass 语句)"""
if body is None:
return 1
bn: t.CSizeT = len(body)
bn: sizet = len(body)
if bn == 0:
return 1
if bn == 1:
@@ -283,11 +283,11 @@ class TypeGenErr(TypeGenBase.TypeGenBase):
viperlib.snprintf(search_key, 64, "%s:", nm.id)
found: str = string.strstr(param_types, search_key)
if found is not None:
colon_pos: t.CSizeT = string.strlen(nm.id) + 1
colon_pos: sizet = string.strlen(nm.id) + 1
bits_str: str = found + colon_pos
bits: int = 0
for bi in range(4):
ch: t.CChar = bits_str[bi]
ch: char = bits_str[bi]
if ch >= '0' and ch <= '9':
bits = bits * 10 + (ch - '0')
else:
@@ -321,7 +321,7 @@ class TypeGenErr(TypeGenBase.TypeGenBase):
return llvmlite.Int32(pool)
ret_ty: llvmlite.LLVMType | t.CPtr = llvmlite.Int32(pool)
bn: t.CSizeT = len(body)
bn: sizet = len(body)
for bi in range(bn):
stmt: ast.AST | t.CPtr = body.get(bi)
if stmt is not None and stmt.kind() == ast.ASTKind.Return:
@@ -348,7 +348,7 @@ class TypeGenErr(TypeGenBase.TypeGenBase):
"""
if body is None:
return 0
bn: t.CSizeT = len(body)
bn: sizet = len(body)
for bi in range(bn):
stmt: ast.AST | t.CPtr = body.get(bi)
if stmt is None:
@@ -382,11 +382,11 @@ class TypeGenErr(TypeGenBase.TypeGenBase):
if ags.args is None:
return None
alist: list[ast.AST | t.CPtr] | t.CPtr = ags.args
an: t.CSizeT = len(alist)
an: sizet = len(alist)
if an == 0:
return None
buf_size: t.CSizeT = an * 32 + 1
buf_size: sizet = an * 32 + 1
buf: str = pool.alloc(buf_size)
if buf is None:
return None
@@ -416,18 +416,18 @@ class TypeGenErr(TypeGenBase.TypeGenBase):
self._strappend(buf, buf_size, ",")
self._strappend(buf, buf_size, tmp)
return buf
def _strappend(self, dst: str, dst_size: t.CSizeT, src: str):
def _strappend(self, dst: str, dst_size: sizet, src: str):
"""将 src 追加到 dst 末尾"""
if dst is None or src is None:
return
dlen: t.CSizeT = string.strlen(dst)
slen: t.CSizeT = string.strlen(src)
remain: t.CSizeT = dst_size - dlen
dlen: sizet = string.strlen(dst)
slen: sizet = string.strlen(src)
remain: sizet = dst_size - dlen
if remain <= 0:
return
# 内联 min(slen, remain - 1) 避免 builtin min 未定义(TransPyV 无 builtin min)
limit: t.CSizeT = slen
cap: t.CSizeT = remain - 1
limit: sizet = slen
cap: sizet = remain - 1
if cap < limit:
limit = cap
for i in range(limit):
+140 -140
View File
@@ -19,7 +19,7 @@ import lib.core.CompilerFactory as CompilerFactory
import lib.Projectrans.Config as Config
import lib.core.Gen.Type.TypeGenBase as TypeGenBase
import lib.core.Gen.Type.TypeGenBase as TypeGenBase
import w32.fileio as fileio
# ============================================================
@@ -57,7 +57,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
# Attribute: 构造 "module.attr" 格式
# 直读字段 at.attr / at.value(ast.attribute_get_attr 等跨模块访问器在
# Phase A 阶段对应 text.ll 未生成时是 stub 无体返回 None → tn_raw 为空 →
# Box[t.CInt](v) 泛型实参提取失败,与 Name 分支 L53-55 同源)。
# Box[int](v) 泛型实参提取失败,与 Name 分支 L53-55 同源)。
if k == ast.ASTKind.Attribute:
at: ast.Attribute | t.CPtr = (ast.Attribute | t.CPtr)(node)
if at.attr is None:
@@ -65,7 +65,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
if at.value is not None and at.value.kind() == ast.ASTKind.Name:
mod_nm: ast.Name | t.CPtr = (ast.Name | t.CPtr)(at.value)
if mod_nm.id is not None:
total: t.CSizeT = string.strlen(mod_nm.id) + 1 + string.strlen(at.attr) + 1
total: sizet = string.strlen(mod_nm.id) + 1 + string.strlen(at.attr) + 1
buf: str = pool.alloc(total)
if buf is not None:
buf[0] = '\0'
@@ -75,7 +75,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
return buf
return at.attr
# Subscript: 构造 "value[slice]" 格式(slice 递归,List/Tuple 保留完整下标)
# 如 t.Callable[[t.CInt], t.CInt] → "t.Callable[[t.CInt], t.CInt]"。
# 如 t.Callable[[int], int] → "t.Callable[[int], int]"。
# CTypedef 值提取(_register_ctypedef_from_annassign → lookup → _parse_type_string
# 重建)需要完整类型表达式字符串,slice 不能丢(此前不支持 Subscript → 返回
# None → 注册失败 → 同 vpi 后续裸类名 lookup_ctypedef 失败 fail-fast,
@@ -88,7 +88,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
slice_s: str = self._subscript_slice_to_str(pool, sub_s.slice)
if slice_s is None:
return None
total_s: t.CSizeT = string.strlen(val_s) + 1 + string.strlen(slice_s) + 2
total_s: sizet = string.strlen(val_s) + 1 + string.strlen(slice_s) + 2
buf_s: str = pool.alloc(total_s)
if buf_s is not None:
buf_s[0] = '\0'
@@ -105,7 +105,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
left_str: str = self._get_type_name_from_annotation(pool, ast.binop_get_left(bop))
right_str: str = self._get_type_name_from_annotation(pool, ast.binop_get_right(bop))
if left_str is not None and right_str is not None:
total2: t.CSizeT = string.strlen(left_str) + 1 + string.strlen(right_str) + 1
total2: sizet = string.strlen(left_str) + 1 + string.strlen(right_str) + 1
buf2: str = pool.alloc(total2)
if buf2 is not None:
buf2[0] = '\0'
@@ -131,7 +131,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
if cn2.const_kind == ast.CONST_INT:
buf2: str = pool.alloc(24)
if buf2 is not None:
viperlib.snprintf(buf2, 24, "%lld", t.CInt64T(cn2.int_val))
viperlib.snprintf(buf2, 24, "%lld", int64(cn2.int_val))
return buf2
if cn2.const_kind == ast.CONST_STR and cn2.str_val is not None:
return cn2.str_val
@@ -142,7 +142,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
return self._list_elts_to_type_str(pool, lst.elts, "[", "]")
# Tuple:t.CArray[elem, N] 等双参形式。注意 TPV parser 把 Subscript 内
# 带逗号的 slice 统一打包为 Tuple("a[x, y]" 语法),故 slice 在 Subscript
# 内**不带括号**输出("x, y"),否则 "t.Callable[([t.CInt], t.CInt)]"
# 内**不带括号**输出("x, y"),否则 "t.Callable[([int], int)]"
# 的显式括号 Tuple slice 会让 ast.parse_expression 解析失败。
if k2 == ast.ASTKind.Tuple:
tup: ast.Tuple | t.CPtr = (ast.Tuple | t.CPtr)(node)
@@ -158,7 +158,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
if buf3 is None:
return None
buf3[0] = '\0'
n3: t.CSizeT = len(elts)
n3: sizet = len(elts)
for i3 in range(n3):
e3: ast.AST | t.CPtr = elts.get(i3)
if e3 is None:
@@ -170,7 +170,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
string.strcat(buf3, ", ")
if string.strlen(buf3) + string.strlen(es3) < 1024:
string.strcat(buf3, es3)
total3: t.CSizeT = string.strlen(buf3) + 2 + 2
total3: sizet = string.strlen(buf3) + 2 + 2
buf4: str = pool.alloc(total3)
if buf4 is None:
return None
@@ -192,7 +192,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
return 0
if s[16] != '.':
return 0
i: t.CSizeT
i: sizet
for i in range(16):
c: int = s[i]
# 48-57 = '0'-'9',97-102 = 'a'-'f'
@@ -204,7 +204,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
"""拼接 "{sha1}.{cls_name}"(pool 分配),失败返回 None"""
if pool is None or sha1 is None or cls_name is None:
return None
total: t.CSizeT = string.strlen(sha1) + 1 + string.strlen(cls_name) + 1
total: sizet = string.strlen(sha1) + 1 + string.strlen(cls_name) + 1
buf: str = pool.alloc(total)
if buf is None:
return None
@@ -240,8 +240,8 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
# strlen 收到 0x12124AE128712850 > x64 用户空间上限 2^47;低 16 位
# 0x2850 残留 pool 偏移 → pool 越界写/寄存器破坏)。解引用前 fail-fast
# 暴露根因(不静默 strlen 段错误)。
if t.CUInt64T(type_name) > 0x00007FFFFFFFFFFF:
VLogger.error(f"_norm_type_arg_name 类型名指针越界 (ptr={t.CUInt64T(type_name)}),疑似 pool 越界写破坏类型名指针", "TypeGen")
if uint64(type_name) > 0x00007FFFFFFFFFFF:
VLogger.error(f"_norm_type_arg_name 类型名指针越界 (ptr={uint64(type_name)}),疑似 pool 越界写破坏类型名指针", "TypeGen")
stdlib.exit(1)
# [FIX] 泛型实参分割(L341 "float, 4" → " 4")第二个参数带前导空格,
# 空格开头的字符串作为类型名/查表 key 是脏数据(ViperOS Mat4.m 的
@@ -254,12 +254,12 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
# ---- 1. 顶层联合 "A|B"('|' 仅在括号外才分割)----
# 括号感知:list[A|B] 的 '|' 在 '[' 内不是顶层联合,应留给第 1.5 步
# 泛型 slice 递归处理;list[A]|t.CPtr 的 '|' 在括号外才是联合分割。
seg_len: t.CSizeT = string.strlen(type_name)
seg_len: sizet = string.strlen(type_name)
if seg_len == 0:
return type_name
pipe_idx: t.CSizeT = seg_len
pipe_idx: sizet = seg_len
p_depth: int = 0
pi: t.CSizeT = 0
pi: sizet = 0
while pi < seg_len:
ch_p: int = type_name[pi]
if ch_p == '[':
@@ -277,7 +277,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
string.strncpy(left_buf, type_name, pipe_idx)
left_buf[pipe_idx] = '\0'
right_str: str = type_name + pipe_idx + 1
right_len: t.CSizeT = string.strlen(right_str)
right_len: sizet = string.strlen(right_str)
right_buf: str = pool.alloc(right_len + 1)
if right_buf is None:
return type_name
@@ -288,7 +288,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
l_n = left_buf
if r_n is None:
r_n = right_buf
total: t.CSizeT = string.strlen(l_n) + 1 + string.strlen(r_n) + 1
total: sizet = string.strlen(l_n) + 1 + string.strlen(r_n) + 1
out: str = pool.alloc(total)
if out is None:
return type_name
@@ -303,9 +303,9 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
# 顶层联合已在第 1 步分割,此处 type_name 是纯泛型表示)。内部参数按
# 顶层 ',' 分割后逐个递归 _norm_type_arg_name,再重组 "Name[arg1,arg2]"
# ——保证所有 module 表示统一为 Hash Namespace({SHA1}.Class)。
lb_idx: t.CSizeT = seg_len
lb_idx: sizet = seg_len
ld: int = 0
li2: t.CSizeT = 0
li2: sizet = 0
while li2 < seg_len:
if type_name[li2] == '[':
if ld == 0:
@@ -320,15 +320,15 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
if container_g is not None:
string.strncpy(container_g, type_name, lb_idx)
container_g[lb_idx] = '\0'
inner_len_g: t.CSizeT = seg_len - lb_idx - 2
inner_len_g: sizet = seg_len - lb_idx - 2
inner_buf_g: str = pool.alloc(inner_len_g + 1)
if inner_buf_g is not None:
string.strncpy(inner_buf_g, type_name + lb_idx + 1, inner_len_g)
inner_buf_g[inner_len_g] = '\0'
# 数参数个数(顶层 ',' 分割,跳过嵌套 '[' ']')
arg_cnt_g: t.CSizeT = 1
arg_cnt_g: sizet = 1
cur_dep_g: int = 0
ci_g: t.CSizeT = 0
ci_g: sizet = 0
while ci_g < inner_len_g:
if inner_buf_g[ci_g] == '[':
cur_dep_g += 1
@@ -346,7 +346,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
# 均为低 16 位 0x2850、高 48 位漂移)。
arg_list_g: list[str] | t.CPtr = list[str](pool, 8)
if arg_list_g is not None:
arg_start_g: t.CSizeT = 0
arg_start_g: sizet = 0
cur_dep_g = 0
ci_g = 0
while ci_g <= inner_len_g:
@@ -361,7 +361,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
else:
is_sep_g = 1 # 结尾
if is_sep_g != 0:
alen_g: t.CSizeT = ci_g - arg_start_g
alen_g: sizet = ci_g - arg_start_g
abuf_g: str = pool.alloc(alen_g + 1)
if abuf_g is not None:
string.strncpy(abuf_g, inner_buf_g + arg_start_g, alen_g)
@@ -374,8 +374,8 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
arg_start_g = ci_g + 1
ci_g += 1
# 重组 container[arg1,arg2,...]
g_total: t.CSizeT = string.strlen(container_g) + 2
gi_g: t.CSizeT
g_total: sizet = string.strlen(container_g) + 2
gi_g: sizet
for gi_g in range(len(arg_list_g)):
if gi_g > 0:
g_total += 1
@@ -405,7 +405,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
# ---- 4. "mod.Class" Attribute ----
dot_pos: str = string.strchr(type_name, '.')
if dot_pos is not None:
mod_len: t.CSizeT = t.CSizeT(t.CUInt64T(dot_pos) - t.CUInt64T(type_name))
mod_len: sizet = sizet(uint64(dot_pos) - uint64(type_name))
attr: str = dot_pos + 1
if mod_len > 0:
mod_buf: str = pool.alloc(mod_len + 1)
@@ -451,24 +451,24 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
"""
if s is None or ident is None or ident[0] == '\0':
return 0
s_len: t.CSizeT = string.strlen(s)
id_len: t.CSizeT = string.strlen(ident)
s_len: sizet = string.strlen(s)
id_len: sizet = string.strlen(ident)
if id_len == 0 or s_len < id_len:
return 0
i: t.CSizeT
i: sizet
for i in range(s_len - id_len + 1):
if string.strncmp(s + i, ident, id_len) != 0:
continue
# 左边界:i==0 或前一字符非标识符字符
left_ok: int = 1
if i > 0:
lc: t.CChar = s[i - 1]
lc: char = s[i - 1]
if (lc >= 'a' and lc <= 'z') or (lc >= 'A' and lc <= 'Z') \
or (lc >= '0' and lc <= '9') or lc == '_':
left_ok = 0
right_ok: int = 1
if i + id_len < s_len:
rc: t.CChar = s[i + id_len]
rc: char = s[i + id_len]
if (rc >= 'a' and rc <= 'z') or (rc >= 'A' and rc <= 'Z') \
or (rc >= '0' and rc <= '9') or rc == '_':
right_ok = 0
@@ -478,7 +478,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
def _parse_type_string(self, pool: memhub.MemBuddy | t.CPtr,
type_str: str,
ctx: t.CInt) -> ast.AST | t.CPtr:
ctx: int) -> ast.AST | t.CPtr:
"""将类型名字符串解析为 AST 节点
正确处理 '|' 与 '.' 周围的空格(如 "ParsedArgs | t.CPtr"):
@@ -493,14 +493,14 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
while type_str[0] == ' ':
type_str += 1
seg_len: t.CSizeT = string.strlen(type_str)
seg_len: sizet = string.strlen(type_str)
# 去除段尾随空格('|' 分割后的左段可能带尾随空格)
while seg_len > 0 and type_str[seg_len - 1] == ' ':
seg_len -= 1
# 检查是否包含 | (BinOp):只在有效段 [0, seg_len) 内查找
pipe_idx: t.CSizeT = seg_len
pi: t.CSizeT = 0
pipe_idx: sizet = seg_len
pi: sizet = 0
while pi < seg_len:
if type_str[pi] == '|':
pipe_idx = pi
@@ -508,7 +508,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
pi += 1
if pipe_idx < seg_len:
# 左段复制到独立缓冲(trim 尾随空格),不破坏原字符串
left_len: t.CSizeT = pipe_idx
left_len: sizet = pipe_idx
while left_len > 0 and type_str[left_len - 1] == ' ':
left_len -= 1
left_buf: bytes = stdlib.malloc(left_len + 1)
@@ -525,14 +525,14 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
return ast.BinOp(pool, left_node, ast.OpKind.BitOr, right_node)
return None
# 检查是否包含 [ (Subscript):t.Callable[[t.CInt], t.CInt] 等。
# 检查是否包含 [ (Subscript):t.Callable[[int], int] 等。
# 必须在 . 检查之前("t.Callable[...]" 含 '.',但本质是 Subscript,
# 若先走 Attribute 会把 "Callable[[t.CInt], t.CInt]" 当 attr → resolve
# 若先走 Attribute 会把 "Callable[[int], int]" 当 attr → resolve
# 失败)。用 ast.parse_expression 完整解析(支持 List/Tuple 字面量
# slice)。CTypedef 值如 "t.Callable[[t.CInt], t.CInt]"(irq_handler_t)
# 与返回注解 "t.CArray[t.CUInt8T, 16]" 依赖此路径。
bracket_idx: t.CSizeT = seg_len
bi: t.CSizeT = 0
# slice)。CTypedef 值如 "t.Callable[[int], int]"(irq_handler_t)
# 与返回注解 "t.CArray[uint8, 16]" 依赖此路径。
bracket_idx: sizet = seg_len
bi: sizet = 0
while bi < seg_len:
if type_str[bi] == '[':
bracket_idx = bi
@@ -547,8 +547,8 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
# 避开 lexer 的数字扫描。
first_inner_ch: int = type_str[bracket_idx + 1] if (bracket_idx + 1) < seg_len else 0
if first_inner_ch >= 48 and first_inner_ch <= 57:
close_idx_m: t.CSizeT = seg_len
ci_m: t.CSizeT = bracket_idx + 1
close_idx_m: sizet = seg_len
ci_m: sizet = bracket_idx + 1
has_nested_m: int = 0
while ci_m < seg_len:
cch_m: int = type_str[ci_m]
@@ -559,11 +559,11 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
has_nested_m = 1
ci_m += 1
if close_idx_m < seg_len and close_idx_m == seg_len - 1 and has_nested_m == 0:
base_len_m: t.CSizeT = bracket_idx
base_len_m: sizet = bracket_idx
while base_len_m > 0 and type_str[base_len_m - 1] == ' ':
base_len_m -= 1
base_buf_m: bytes = stdlib.malloc(base_len_m + 1)
inner_len_m: t.CSizeT = close_idx_m - bracket_idx - 1
inner_len_m: sizet = close_idx_m - bracket_idx - 1
inner_buf_m: bytes = stdlib.malloc(inner_len_m + 1)
if base_buf_m is not None and inner_buf_m is not None:
string.strncpy(base_buf_m, type_str, base_len_m)
@@ -588,7 +588,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
if expr_body is not None:
return expr_body
# 备选:ast.parse 文件级(TPV parser 的 _parse_test 单表达式入口对
# 复杂 slice 如 "t.Callable[[t.CInt], t.CInt]" 解析失败,但文件级
# 复杂 slice 如 "t.Callable[[int], int]" 解析失败,但文件级
# _parse_expr_stmt 可解析裸表达式语句——vpi 同语法已验证
# parse_tokens 成功,故此处用文件级 parse 兜底)
tree_s: ast.AST | t.CPtr = ast.parse(type_str, pool)
@@ -603,8 +603,8 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
return None
# 检查是否包含 . (Attribute):只在有效段 [0, seg_len) 内查找
dot_idx: t.CSizeT = seg_len
di: t.CSizeT = 0
dot_idx: sizet = seg_len
di: sizet = 0
while di < seg_len:
if type_str[di] == '.':
dot_idx = di
@@ -612,7 +612,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
di += 1
if dot_idx < seg_len:
# 模块名段 trim 尾随空格
mod_len: t.CSizeT = dot_idx
mod_len: sizet = dot_idx
while mod_len > 0 and type_str[mod_len - 1] == ' ':
mod_len -= 1
mod_buf: bytes = stdlib.malloc(mod_len + 1)
@@ -623,7 +623,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
module_node: ast.AST | t.CPtr = ast.Name(pool, mod_buf, ctx)
# attr 段 trim 尾随空格
attr_str: str = type_str + dot_idx + 1
attr_len: t.CSizeT = string.strlen(attr_str)
attr_len: sizet = string.strlen(attr_str)
while attr_len > 0 and attr_str[attr_len - 1] == ' ':
attr_len -= 1
attr_buf: bytes = stdlib.malloc(attr_len + 1)
@@ -745,13 +745,13 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
return p_t
if Config.IncludesDir is None:
return None
m_len: t.CSizeT = string.strlen(mod)
p_len: t.CSizeT = m_len + 4
full_len: t.CSizeT = string.strlen(Config.IncludesDir) + p_len + 1
m_len: sizet = string.strlen(mod)
p_len: sizet = m_len + 4
full_len: sizet = string.strlen(Config.IncludesDir) + p_len + 1
p_buf: str = stdlib.malloc(p_len)
if p_buf is None:
return None
mi: t.CSizeT
mi: sizet
for mi in range(m_len):
if mod[mi] == '.':
p_buf[mi] = '/'
@@ -788,10 +788,10 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
# 遍历读到未写入区域 → 越界读(ASan heap-buffer-overflow)。
string.memset(self.Gen.TypeGenCType.ImportAliasBuf, 0, 256)
buf: bytes = self.Gen.TypeGenCType.ImportAliasBuf
al_len: t.CSizeT = string.strlen(alias)
tg_len: t.CSizeT = string.strlen(target)
al_len: sizet = string.strlen(alias)
tg_len: sizet = string.strlen(target)
# 找缓冲末尾(跳过已有 "alias\0target\0" 对,遇首字节 '\0' 即结尾)
cur: t.CSizeT = 0
cur: sizet = 0
while True:
if buf[cur] == '\0':
break
@@ -822,17 +822,17 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
buf: bytes = self.Gen.TypeGenCType.ImportAliasBuf
if buf is None:
return None
mod_len: t.CSizeT = string.strlen(mod)
cur: t.CSizeT = 0
mod_len: sizet = string.strlen(mod)
cur: sizet = 0
while True:
if buf[cur] == '\0':
break
al_start: t.CSizeT = cur
al_start: sizet = cur
while buf[cur] != '\0':
cur += 1
al_len: t.CSizeT = cur - al_start
al_len: sizet = cur - al_start
cur += 1
tg_start: t.CSizeT = cur
tg_start: sizet = cur
while buf[cur] != '\0':
cur += 1
cur += 1
@@ -884,7 +884,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
b_path: str = self._build_lib_source_path("builtins", b_sha1)
if b_path is None:
return None
BUF_B: t.CSizeT = 65536
BUF_B: sizet = 65536
b_buf: bytes = stdlib.malloc(BUF_B)
if b_buf is None:
stdlib.free(b_path)
@@ -900,23 +900,23 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
stdlib.free(b_buf)
return None
if b_read < LONG(BUF_B):
b_buf[t.CSizeT(b_read)] = 0
b_buf[sizet(b_read)] = 0
# 逐行扫描并注册 builtins 全部 "NAME: t.CTypedef = TYPE"(一次读文件
# 注册全部,置 scanned 标记后同文件后续查表即中;对齐
# register_ctypedef_from_source 的文本匹配策略)。已存在的表条目
# 不覆盖——模块自身/import 注入的 typedef 优先于 builtins 默认。
b_total: t.CSizeT = string.strlen(b_buf)
b_total: sizet = string.strlen(b_buf)
# 预扫描 import 行注册别名(import stdint as __stdint → __stdint:stdint),
# 供库 typedef 模块限定引用展开按别名还原真实模块名(__stdint.size_t →
# stdint.size_t)。imports 位于文件顶部,typedef 扫描时别名已就绪。
b_imp_i: t.CSizeT = 0
b_imp_ls: t.CSizeT = 0
b_imp_i: sizet = 0
b_imp_ls: sizet = 0
while b_imp_i <= b_total:
if b_imp_i == b_total or b_buf[b_imp_i] == '\n':
b_imp_len: t.CSizeT = b_imp_i - b_imp_ls
b_imp_len: sizet = b_imp_i - b_imp_ls
if b_imp_len > 0:
# 跳过行首空白
b_imp_s: t.CSizeT = 0
b_imp_s: sizet = 0
while b_imp_s < b_imp_len and b_buf[b_imp_ls + b_imp_s] == ' ':
b_imp_s += 1
# "import" 前缀
@@ -925,7 +925,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
and b_buf[b_imp_ls + b_imp_s + 2] == 'p' and b_buf[b_imp_ls + b_imp_s + 3] == 'o' \
and b_buf[b_imp_ls + b_imp_s + 4] == 'r' and b_buf[b_imp_ls + b_imp_s + 5] == 't':
# 找 " as " 分隔
b_as_i: t.CSizeT = b_imp_s + 6
b_as_i: sizet = b_imp_s + 6
while b_as_i < b_imp_len - 3:
if b_buf[b_imp_ls + b_as_i] == ' ' and b_buf[b_imp_ls + b_as_i + 1] == 'a' \
and b_buf[b_imp_ls + b_as_i + 2] == 's' and b_buf[b_imp_ls + b_as_i + 3] == ' ':
@@ -935,17 +935,17 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
# target = "import" 之后跳过空格到 " as " 前
# (b_imp_s+6 是 "import" 后首个字符,可能是空格,
# 不跳过会带上前导空格 → " stdint" 查 SHA1 失败)
b_tgt_s: t.CSizeT = b_imp_s + 6
b_tgt_s: sizet = b_imp_s + 6
while b_tgt_s < b_imp_len and b_buf[b_imp_ls + b_tgt_s] == ' ':
b_tgt_s += 1
b_tgt_e: t.CSizeT = b_as_i
b_tgt_e: sizet = b_as_i
while b_tgt_e > b_tgt_s and b_buf[b_imp_ls + b_tgt_e - 1] == ' ':
b_tgt_e -= 1
# alias = " as " 之后到行尾(trim 尾随空格/\r)
b_al_s: t.CSizeT = b_as_i + 4
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: t.CSizeT = b_imp_len
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'):
b_al_e -= 1
@@ -960,18 +960,18 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
self._register_import_alias(b_al_buf, b_tgt_buf)
b_imp_ls = b_imp_i + 1
b_imp_i += 1
b_i: t.CSizeT = 0
b_line_start: t.CSizeT = 0
b_i: sizet = 0
b_line_start: sizet = 0
b_res: str = None
while b_i <= b_total:
if b_i == b_total or b_buf[b_i] == '\n':
b_line_len: t.CSizeT = b_i - b_line_start
b_line_len: sizet = b_i - b_line_start
if b_line_len > 0:
# 找行内第一个 ':'(跳过注释行)
b_j: t.CSizeT = 0
b_j: sizet = 0
b_found_colon: int = 0
while b_j < b_line_len:
b_ch: t.CChar = b_buf[b_line_start + b_j]
b_ch: char = b_buf[b_line_start + b_j]
if b_ch == ':':
b_found_colon = 1
break
@@ -980,7 +980,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
b_j += 1
if b_found_colon != 0:
# 左段 NAME(trim 尾随空格)
b_name_len: t.CSizeT = b_j
b_name_len: sizet = b_j
while b_name_len > 0 and b_buf[b_line_start + b_name_len - 1] == ' ':
b_name_len -= 1
if b_name_len > 0 and b_name_len < 128:
@@ -993,18 +993,18 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
# (b_line_len)内——此前 strlen 跨行吞掉
# 换行+下一行注释(size_t: t.CTypedef =
# stdint.size_t 后跟 "# size_t: t.CTypedef =
# t.CSizeT" → 值含 "\n# ..." → 展开取到注释
# sizet" → 值含 "\n# ..." → 展开取到注释
# 里的 '.' → 模块名垃圾,main2.vp size_t 根因)
b_eq_off: t.CSizeT = t.CSizeT(t.CUInt64T(b_eq2) - t.CUInt64T(b_buf)) - b_line_start
b_vs: t.CSizeT = b_eq_off + 1
b_eq_off: sizet = sizet(uint64(b_eq2) - uint64(b_buf)) - b_line_start
b_vs: sizet = b_eq_off + 1
while b_vs < b_line_len and b_buf[b_line_start + b_vs] == ' ':
b_vs += 1
b_ve: t.CSizeT = b_line_len
b_ve: sizet = b_line_len
while b_ve > b_vs and (b_buf[b_line_start + b_ve - 1] == ' '
or b_buf[b_line_start + b_ve - 1] == '\r'):
b_ve -= 1
if b_ve > b_vs:
b_vlen: t.CSizeT = b_ve - b_vs
b_vlen: sizet = b_ve - b_vs
b_nb: str = pool.alloc(b_name_len + 1)
b_tb: str = pool.alloc(b_vlen + 1)
if b_nb is not None and b_tb is not None:
@@ -1016,7 +1016,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
b_exist: str = self.Gen.TypeGenCType.lookup_ctypedef(b_nb)
if b_exist is None or self.Gen.TypeGenCType.CTypedefFound == 0:
# 急切展开模块限定引用再注册(size_t:
# t.CTypedef = stdint.size_t → 注册 t.CSizeT),
# t.CTypedef = stdint.size_t → 注册 sizet),
# 使表内直接持有最终类型表达式,下游查表即中
b_tb_x: str = self._expand_typedef_ref(pool, b_tb)
if b_tb_x is not None:
@@ -1060,7 +1060,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
m_path: str = self._build_lib_source_path(m_real, m_sha1)
if m_path is None:
return None
BUF_L: t.CSizeT = 65536
BUF_L: sizet = 65536
m_buf: bytes = stdlib.malloc(BUF_L)
if m_buf is None:
stdlib.free(m_path)
@@ -1076,20 +1076,20 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
stdlib.free(m_buf)
return None
if m_read < LONG(BUF_L):
m_buf[t.CSizeT(m_read)] = 0
attr_len: t.CSizeT = string.strlen(attr)
m_total: t.CSizeT = string.strlen(m_buf)
m_i: t.CSizeT = 0
m_ls: t.CSizeT = 0
m_buf[sizet(m_read)] = 0
attr_len: sizet = string.strlen(attr)
m_total: sizet = string.strlen(m_buf)
m_i: sizet = 0
m_ls: sizet = 0
m_res: str = None
while m_i <= m_total and m_res is None:
if m_i == m_total or m_buf[m_i] == '\n':
m_line_len: t.CSizeT = m_i - m_ls
m_line_len: sizet = m_i - m_ls
if m_line_len > 0:
m_j: t.CSizeT = 0
m_j: sizet = 0
m_fc: int = 0
while m_j < m_line_len:
m_ch: t.CChar = m_buf[m_ls + m_j]
m_ch: char = m_buf[m_ls + m_j]
if m_ch == ':':
m_fc = 1
break
@@ -1097,12 +1097,12 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
break
m_j += 1
if m_fc != 0:
m_nl: t.CSizeT = m_j
m_nl: sizet = m_j
while m_nl > 0 and m_buf[m_ls + m_nl - 1] == ' ':
m_nl -= 1
if m_nl == attr_len:
m_nm_ok: int = 1
m_ki: t.CSizeT = 0
m_ki: sizet = 0
while m_ki < attr_len:
if m_buf[m_ls + m_ki] != attr[m_ki]:
m_nm_ok = 0
@@ -1115,16 +1115,16 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
if m_eq is not None:
# '=' 相对行首偏移;值段严格限定在行尾
# (m_line_len)内,防止跨行吞换行+后续内容
m_eq_off: t.CSizeT = t.CSizeT(t.CUInt64T(m_eq) - t.CUInt64T(m_buf)) - m_ls
m_vs: t.CSizeT = m_eq_off + 1
m_eq_off: sizet = sizet(uint64(m_eq) - uint64(m_buf)) - m_ls
m_vs: sizet = m_eq_off + 1
while m_vs < m_line_len and m_buf[m_ls + m_vs] == ' ':
m_vs += 1
m_ve: t.CSizeT = m_line_len
m_ve: sizet = m_line_len
while m_ve > m_vs and (m_buf[m_ls + m_ve - 1] == ' '
or m_buf[m_ls + m_ve - 1] == '\r'):
m_ve -= 1
if m_ve > m_vs:
m_vlen: t.CSizeT = m_ve - m_vs
m_vlen: sizet = m_ve - m_vs
m_tb: str = pool.alloc(m_vlen + 1)
if m_tb is not None:
string.strncpy(m_tb, m_buf + m_ls + m_vs, m_vlen)
@@ -1137,7 +1137,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
return m_res
def _expand_typedef_ref(self, pool: memhub.MemBuddy | t.CPtr,
type_str: str, depth: int = 0) -> str:
"""展开类型表达式中的模块限定 typedef 引用(stdint.size_t → t.CSizeT)
"""展开类型表达式中的模块限定 typedef 引用(stdint.size_t → sizet)
builtins 最后匹配的 typedef 值可能引用库模块 typedef(size_t:
t.CTypedef = stdint.size_t)。当前文件未 import stdint 时 Attribute
@@ -1155,7 +1155,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
dot_pos: str = string.strrchr(type_str, '.')
if dot_pos is None:
return type_str
mod_len: t.CSizeT = t.CSizeT(t.CUInt64T(dot_pos) - t.CUInt64T(type_str))
mod_len: sizet = sizet(uint64(dot_pos) - uint64(type_str))
attr: str = dot_pos + 1
if mod_len == 0 or attr is None or attr[0] == '\0':
return type_str
@@ -1284,7 +1284,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
# map_t_type 仅保留 t/c 库核心原语 + 内建小写 float/double。
# ============================================================
# 内建小写裸名类型(float = t.CFloat = f32, double = t.CDouble = f64,
# char = t.CChar = i8;int/bool 由 resolve_annotation_type Name 分支直通,
# char = char = i8;int/bool 由 resolve_annotation_type Name 分支直通,
# 小写 stdint 别名由 stdint.vp CTypedef 声明提供)
elif string.strcmp(type_name, "char") == 0:
return llvmlite.Int8(pool)
@@ -1345,7 +1345,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
return 1
return 0
def _is_cptr_subscript(self, node: ast.AST | t.CPtr) -> int:
"""检测节点是否为 t.CPtr[T] 下标指针类型(t.CPtr[t.CPtr] / t.CPtr[t.CInt] 等)
"""检测节点是否为 t.CPtr[T] 下标指针类型(t.CPtr[t.CPtr] / t.CPtr[int] 等)
用于联合类型 X | t.CPtr[T] 的指针层级合并(TPC 联合合并规则:
CPtr 侧贡献 PtrCount,另一侧提供 BaseType)。t.CPtr[...] 不是
@@ -1534,7 +1534,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
at: ast.Attribute | t.CPtr = (ast.Attribute | t.CPtr)(node)
if at.attr is None:
return None
# t.XXX 内置类型:返回 XXX(如 t.CUInt32T → "CUInt32T"),
# t.XXX 内置类型:返回 XXX(如 uint32 → "CUInt32T"),
# 供 AnnotClassName 记录变量类型名(_type_name_unsigned 判断无符号性时使用)。
# 消费方(find_struct/lookup_field_by_class)对非结构体名返回 None 优雅降级。
if at.value is not None and at.value.kind() == ast.ASTKind.Name:
@@ -1624,10 +1624,10 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
sub_tup: ast.Tuple | t.CPtr = (ast.Tuple | t.CPtr)(sub.slice)
if sub_tup.elts is not None:
tup_elts_sn: list[ast.AST | t.CPtr] | t.CPtr = sub_tup.elts
tn_sn: t.CSizeT = len(tup_elts_sn)
tn_sn: sizet = len(tup_elts_sn)
# 计算总长度
tup_total: t.CSizeT = 1
ti_sn: t.CSizeT
tup_total: sizet = 1
ti_sn: sizet
for ti_sn in range(tn_sn):
if ti_sn > 0:
tup_total += 1
@@ -1657,7 +1657,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
if slice_name is None:
return base_name
# 拼接 "base_name[slice_name]"
mangled_total: t.CSizeT = string.strlen(base_name) + 1 + string.strlen(slice_name) + 1 + 1
mangled_total: sizet = string.strlen(base_name) + 1 + string.strlen(slice_name) + 1 + 1
mangled_buf: str = pool.alloc(mangled_total)
if mangled_buf is None:
return base_name
@@ -1685,7 +1685,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
# 与调用端 `a, b = f()` 的打包/解包。
if string.strcmp(gen_cls_name, "tuple") == 0:
tp_elts: list[ast.AST | t.CPtr] | t.CPtr = None
tp_count: t.CSizeT = 0
tp_count: sizet = 0
if sub.slice.kind() == ast.ASTKind.Tuple:
tp_tup: ast.Tuple | t.CPtr = (ast.Tuple | t.CPtr)(sub.slice)
if tp_tup.elts is not None:
@@ -1703,7 +1703,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
return None
tup_head: llvmlite.ParamNode | t.CPtr = None
tup_tail: llvmlite.ParamNode | t.CPtr = None
tui: t.CSizeT
tui: sizet
for tui in range(tp_count):
tup_elt: ast.AST | t.CPtr = tp_elts.get(tui)
if tup_elt is None:
@@ -1729,8 +1729,8 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
gen_tp: ast.Tuple | t.CPtr = (ast.Tuple | t.CPtr)(sub.slice)
gen_elts: list[ast.AST | t.CPtr] | t.CPtr = gen_tp.elts
if gen_elts is not None:
gen_en: t.CSizeT = len(gen_elts)
gen_ei: t.CSizeT
gen_en: sizet = len(gen_elts)
gen_ei: sizet
for gen_ei in range(gen_en):
gen_elt: ast.AST | t.CPtr = gen_elts.get(gen_ei)
gen_tn_raw: str = self._get_type_name_from_annotation(pool, gen_elt)
@@ -1743,9 +1743,9 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
gen_tn_single: str = self._norm_type_arg_name(pool, gen_tn_raw_single, from_imports)
gen_arg_names.append(gen_tn_single)
# 计算总长度并分配缓冲区
gen_total: t.CSizeT = string.strlen(gen_cls_name) + 2 # "[" 和 "]"
gen_an: t.CSizeT = len(gen_arg_names)
gen_ai: t.CSizeT
gen_total: sizet = string.strlen(gen_cls_name) + 2 # "[" 和 "]"
gen_an: sizet = len(gen_arg_names)
gen_ai: sizet
for gen_ai in range(gen_an):
if gen_ai > 0:
gen_total += 1 # ","
@@ -1860,8 +1860,8 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
tpn_g: list[str] | t.CPtr = self.Gen.TypeGenBase.GenericTpNames
tpa_g: list[str] | t.CPtr = self.Gen.TypeGenBase.GenericTypeArgs
if tpn_g is not None and tpa_g is not None:
gp_n: t.CSizeT = len(tpn_g)
gp_i: t.CSizeT
gp_n: sizet = len(tpn_g)
gp_i: sizet
for gp_i in range(gp_n):
gp_tpn: str = tpn_g.get(gp_i)
if gp_tpn is not None and string.strcmp(nm.id, gp_tpn) == 0:
@@ -1883,7 +1883,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
self.Gen.TypeGenErr.fatal_error(
nm, f"泛型类型实参污染:类型参数 '{gp_tpn}' 自映射(实参='{gp_ta}'),无法特化", "TypeError")
polluted: int = 0
gp_j: t.CSizeT
gp_j: sizet
for gp_j in range(gp_n):
gp_pn: str = tpn_g.get(gp_j)
# token 边界匹配(非 strstr 子串):实参串中必须出现
@@ -1907,7 +1907,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
return self.resolve_annotation_type(pool, gp_sub_node, imported_modules, from_imports, trans, depth + 1)
# 已规范化 sha1 前缀名 "{16hex}.Class"(_norm_type_arg_name 产物,如泛型
# 实参 rowptr[7565e081d88517ac.AST] 的括号内层):模块段即 SHA1(天然
# 已编译),无需 import 检查。解析器把 "a.b" 折叠为单 Name(t.CInt 同款),
# 已编译),无需 import 检查。解析器把 "a.b" 折叠为单 Name(int 同款),
# 与 Attribute 形态(L1978-1992)都要支持;否则 rowptr[sha.AST] 解析失败
# → 特化方法参数类型退化 → "方法 'list[...].append' 参数 'item' 类型解析
# 失败"(SlotsBugTest ast 包 rowptr[list[rowptr[AST]]] 根因)。
@@ -1935,7 +1935,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
elif string.strcmp(nm.id, "int") == 0:
return llvmlite.Int32(pool)
elif string.strcmp(nm.id, "char") == 0:
# char = t.CChar = i8(与 map_t_type 中 CChar/char 映射一致)
# char = char = i8(与 map_t_type 中 CChar/char 映射一致)
return llvmlite.Int8(pool)
elif string.strcmp(nm.id, "bytes") == 0:
return llvmlite.Ptr(pool, llvmlite.Int8(pool))
@@ -2014,13 +2014,13 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
orig_alias: str = self.Gen.ImportsGen.lookup_from_import_original(from_imports, nm.id)
if orig_alias is not None and string.strcmp(orig_alias, nm.id) != 0:
# 内部指针未 null 终止,复制到独立缓冲区(截断于空格/null)
oa_len: t.CSizeT = 0
oa_len: sizet = 0
while orig_alias[oa_len] != ' ' and orig_alias[oa_len] != '\0':
oa_len += 1
if oa_len > 0:
oa_buf: str = pool.alloc(oa_len + 1)
if oa_buf is not None:
oa_i: t.CSizeT
oa_i: sizet
for oa_i in range(oa_len):
oa_buf[oa_i] = orig_alias[oa_i]
oa_buf[oa_len] = '\0'
@@ -2058,7 +2058,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
return lib_ty_n
return None
# Attribute 节点: t.CInt, t.CUInt64T, namespace_defs.PlainStruct 等
# Attribute 节点: int, uint64, namespace_defs.PlainStruct 等
if k == ast.ASTKind.Attribute:
at: ast.Attribute | t.CPtr = (ast.Attribute | t.CPtr)(node)
if at.attr is None:
@@ -2079,7 +2079,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
sha1_attr: int = 0
if string.strlen(val_name.id) == 16:
sha1_ok: int = 1
i_sa: t.CSizeT
i_sa: sizet
for i_sa in range(16):
c_sa: int = val_name.id[i_sa]
# 48-57 = '0'-'9',97-102 = 'a'-'f'
@@ -2111,7 +2111,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
return None
# [阶段1b] 库 typedef 动态表优先(正常库分析):attr 是库声明
# 的 typedef 名(如 stdint.INT/BYTE)且表已注册 → 递归展开走库
# 定义(单一真源);miss 再 map_t_type(t/c 库内部特判,如 t.CInt)。
# 定义(单一真源);miss 再 map_t_type(t/c 库内部特判,如 int)。
# 消除双事实源:Attribute 路径不再被 map_t_type 硬编码截胡。
if self.Gen.TypeGenCType.CTypedefResolveDepth < TypeGenMixin.MAX_CTYPEDEF_DEPTH:
ctypedef_attr: str = self.Gen.TypeGenCType.lookup_ctypedef(at.attr)
@@ -2248,7 +2248,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
# BinOp 节点: 联合类型注解 A | B
# 处理三种语义:
# 1. ActualType | t.CPtr → Ptr(ActualType)(指针包装,如 MemBuddy | t.CPtr → MemBuddy*)
# 2. t.CVoid | t.CPtr → i8* (void* 等价于 i8*)
# 2. t.CPtr → i8* (void* 等价于 i8*)
# 3. ActualType | DecoratorMarker → ActualType(忽略装饰器标记如 CExport/CExtern)
if k == ast.ASTKind.BinOp:
bop: ast.BinOp | t.CPtr = (ast.BinOp | t.CPtr)(node)
@@ -2286,7 +2286,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
# 仅裸名(Name)场景验证解析结果必须是已注册 struct:
# 损坏节点可能解析出基础类型垃圾(如 Int8 → Ptr(i8))。
# Attribute 场景(Module.Class / t.XXX)resolve 结果直接可用
# (如 t.CUInt64T → i64、memhub.MemBuddy → MemBuddy*),
# (如 uint64 → i64、memhub.MemBuddy → MemBuddy*),
# 不得踢进 fallback——否则按 Name 布局读 Attribute 字段会得到
# 垃圾类名,字段类型错误(如 free_lists 从 i64* 变 i8*)导致
# 运行时 GEP 步长错误崩溃。
@@ -2305,8 +2305,8 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
tpn_g2: list[str] | t.CPtr = self.Gen.TypeGenBase.GenericTpNames
if tpn_g2 is not None:
other_nm_x: ast.Name | t.CPtr = (ast.Name | t.CPtr)(other_node)
gtn_nx: t.CSizeT = len(tpn_g2)
gtn_ix: t.CSizeT
gtn_nx: sizet = len(tpn_g2)
gtn_ix: sizet
for gtn_ix in range(gtn_nx):
gtn_nmx: str = tpn_g2.get(gtn_ix)
if gtn_nmx is not None and other_nm_x.id is not None:
@@ -2360,7 +2360,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
# t.CPtr[...] 下标指针标记(t.CPtr[T] 非普通 CPtr 标记,_is_cptr_marker
# 不识别 Subscript): X | t.CPtr[T] → 指针层级合并(对齐 TPC 联合合并
# 规则 HandlesTypeMerge.py L864-884:CPtr 侧贡献 PtrCount,另一侧提供
# BaseType)。如 t.CUInt8T | t.CPtr[t.CPtr] → u8**。此前左右都不是
# BaseType)。如 uint8 | t.CPtr[t.CPtr] → u8**。此前左右都不是
# CPtr 标记 → 落下方"无 CPtr 标记"分支返回左值 i8 → c.Deref(out) 报
# "参数不是指针类型"(zdeflate.vp compress out 根因)。
cptr_sub_side: ast.AST | t.CPtr = None
@@ -2490,7 +2490,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
if fb_td is not None:
fb_slice: str = self._get_type_name_from_annotation(pool, sub.slice)
if fb_slice is not None:
fb_total: t.CSizeT = string.strlen(fb_td) + 1 + string.strlen(fb_slice) + 2
fb_total: sizet = string.strlen(fb_td) + 1 + string.strlen(fb_slice) + 2
fb_str: str = pool.alloc(fb_total)
if fb_str is not None:
fb_str[0] = '\0'
@@ -2532,8 +2532,8 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
return llvmlite.Ptr(pool, llvmlite.Int8(pool))
# 指针类型: t.CPtr[T] → Ptr(T)(指向 T 的指针,T 自身可含指针层级)
# t.CPtr[t.CPtr] → Ptr(Ptr(CPtr=i8*)) = i8**(双指针)
# t.CPtr[t.CInt] → i32*(DeclarationGenerator.py L1014-1016 文档化语法)。
# 此前缺失 → t.CUInt8T | t.CPtr[t.CPtr] 联合退化为左值 i8 →
# t.CPtr[int] → i32*(DeclarationGenerator.py L1014-1016 文档化语法)。
# 此前缺失 → uint8 | t.CPtr[t.CPtr] 联合退化为左值 i8 →
# c.Deref(out) 报"参数不是指针类型"(zdeflate.vp compress out 根因)
if string.strcmp(arr_at.attr, "CPtr") == 0:
if string.strcmp(arr_val_name.id, "t") != 0 and string.strcmp(arr_val_name.id, "c") != 0 \
@@ -2571,7 +2571,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
if tup.elts is None:
self.Gen.TypeGenErr.fatal_type_error(node, "t.CArray Tuple 缺少 elts")
elts_list: list[ast.AST | t.CPtr] | t.CPtr = tup.elts
elts_n: t.CSizeT = len(elts_list)
elts_n: sizet = len(elts_list)
if elts_n < 2:
self.Gen.TypeGenErr.fatal_type_error(node, "t.CArray Tuple 元素不足")
elem_node: ast.AST | t.CPtr = elts_list.get(0)
+8 -8
View File
@@ -53,7 +53,7 @@ class VarGenMixin:
Gen: Generator.Generator | t.CPtr
def init_vars(self, pool: memhub.MemBuddy | t.CPtr) -> GenTypes.VarEntry | t.CPtr:
"""分配并清零变量表数组"""
size: t.CSizeT = MAX_VARS * GenTypes.VarEntry.__sizeof__()
size: sizet = MAX_VARS * GenTypes.VarEntry.__sizeof__()
vars_ptr: GenTypes.VarEntry | t.CPtr = pool.alloc(size)
if vars_ptr is not None:
string.memset(vars_ptr, 0, size)
@@ -68,9 +68,9 @@ class VarGenMixin:
"""在变量表中按名称查找"""
if name is None or vars_ptr is None:
return None
entry_size: t.CSizeT = GenTypes.VarEntry.__sizeof__()
entry_size: sizet = GenTypes.VarEntry.__sizeof__()
for i in range(var_count):
entry_addr: t.CUInt64T = t.CUInt64T(vars_ptr) + i * entry_size
entry_addr: uint64 = uint64(vars_ptr) + i * entry_size
entry: GenTypes.VarEntry | t.CPtr = (GenTypes.VarEntry | t.CPtr)(t.CVoid(entry_addr, t.CPtr))
if entry.Name is not None and entry.Used != 0:
if string.strcmp(entry.Name, name) == 0:
@@ -86,9 +86,9 @@ class VarGenMixin:
"""在变量表中按名称查找,返回 VarEntry 或 None"""
if name is None or vars_ptr is None:
return None
entry_size: t.CSizeT = GenTypes.VarEntry.__sizeof__()
entry_size: sizet = GenTypes.VarEntry.__sizeof__()
for i in range(var_count):
entry_addr: t.CUInt64T = t.CUInt64T(vars_ptr) + i * entry_size
entry_addr: uint64 = uint64(vars_ptr) + i * entry_size
entry: GenTypes.VarEntry | t.CPtr = (GenTypes.VarEntry | t.CPtr)(t.CVoid(entry_addr, t.CPtr))
if entry.Name is not None and entry.Used != 0:
if string.strcmp(entry.Name, name) == 0:
@@ -160,8 +160,8 @@ class VarGenMixin:
return 1
if var_count >= MAX_VARS:
return 1
entry_size: t.CSizeT = GenTypes.VarEntry.__sizeof__()
entry_addr: t.CUInt64T = t.CUInt64T(vars_ptr) + var_count * entry_size
entry_size: sizet = GenTypes.VarEntry.__sizeof__()
entry_addr: uint64 = uint64(vars_ptr) + var_count * entry_size
entry: GenTypes.VarEntry | t.CPtr = (GenTypes.VarEntry | t.CPtr)(t.CVoid(entry_addr, t.CPtr))
entry.Name = name
entry.Alloca = alloca
@@ -366,7 +366,7 @@ class VarGenMixin:
if symtab.Root is None or symtab.Current is None:
return 0
# 比较指针:Current 与 Root 相同则为模块级
if t.CUInt64T(symtab.Current) == t.CUInt64T(symtab.Root):
if uint64(symtab.Current) == uint64(symtab.Root):
return 1
return 0
File diff suppressed because it is too large. Load diff
+259 -259
View File
@@ -1,259 +1,259 @@
import t, c
from stdint import *
import stdio
import stdlib
import memhub
import sys
import w32.win32console as w32cmd
import w32.win32file as w32file
import w32.win32base as win32base
# ============================================================
# VLogger - 原生日志系统(Windows 控制台彩色输出)
#
# 输出格式与 TPC (lib/core/VLogger.py) 对齐:
# ├ INFO: message
# ├ INFO[category]: message
# ├ WARN: message
# ├ ERROR: message
# ├ SUCCESS: message
# ├ DEBUG: message
# ╠ CRITICAL: message (红底白字,致命错误)
# ╠ CRITICAL[category]: message
#
# 分段着色:前缀符号(├/╠) 用级别色,LEVEL 标签用亮色,消息用默认色
# CRITICAL 级别使用 ╠ 前缀和红底白字标签,与 TPC critical 对齐
# ============================================================
# 日志级别
class LogLevel(t.CEnum):
DEBUG = 0
INFO = 1
WARNING = 2
ERROR = 3
SUCCESS = 4
CRITICAL = 5
# Win32 控制台前景色属性
FOREGROUND_BLUE: t.CDefine = 0x0001
FOREGROUND_GREEN: t.CDefine = 0x0002
FOREGROUND_RED: t.CDefine = 0x0004
FOREGROUND_INTENSITY: t.CDefine = 0x0008
FOREGROUND_WHITE: t.CDefine = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE
FOREGROUND_CYAN: t.CDefine = FOREGROUND_BLUE | FOREGROUND_GREEN
FOREGROUND_YELLOW: t.CDefine = FOREGROUND_RED | FOREGROUND_GREEN
FOREGROUND_MAGENTA: t.CDefine = FOREGROUND_RED | FOREGROUND_BLUE
# Win32 控制台背景色属性
BACKGROUND_RED: t.CDefine = 0x0040
BACKGROUND_GREEN: t.CDefine = 0x0020
BACKGROUND_BLUE: t.CDefine = 0x0010
BACKGROUND_INTENSITY: t.CDefine = 0x0080
BACKGROUND_WHITE: t.CDefine = BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE
@t.NoVTable
class Logger:
_level: int
_console_handle: win32base.HANDLE
_use_color: int
__mbuddy__: memhub.MemBuddy | t.CPtr
def __init__(self, level: int = 1):
self._level = level
self._console_handle = w32file.GetStdHandle(w32file.STD_OUTPUT_HANDLE)
self._use_color = 1
self.__mbuddy__ = _mbuddy
def _set_color(self, attr: WORD) -> int:
uc: int = self._use_color
if uc:
ch: win32base.HANDLE = self._console_handle
ret: int = w32cmd.SetConsoleTextAttribute(ch, attr)
return ret
return 0
def _reset_color(self) -> int:
if self._use_color:
return w32cmd.SetConsoleTextAttribute(self._console_handle, FOREGROUND_WHITE)
return 0
# ============================================================
# _log - 核心日志输出(分段着色)
#
# 格式: ├ LEVEL: msg 或 ├ LEVEL[category]: msg
# 分三段着色:
# 1. 前缀符号 ├ (sym_color)
# 2. LEVEL 标签 (level_color)
# 3. 消息内容 (默认白色)
# ============================================================
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)
# LEVEL 标签着色
self._set_color(level_color)
stdio.printf("%s", level_str)
self._reset_color()
# category 可选
if category is not None and category[0] != 0:
stdio.printf(" [%s]", category)
stdio.printf(": %s\n", msg)
return 0
def debug(self, msg: str, category: str = "") -> int:
return self._log(LogLevel.DEBUG, "├", "DEBUG", msg,
FOREGROUND_INTENSITY, FOREGROUND_INTENSITY, category)
def info(self, msg: str, category: str = "") -> int:
ret: int = self._log(LogLevel.INFO, "├", "INFO", msg,
FOREGROUND_GREEN,
FOREGROUND_GREEN | FOREGROUND_INTENSITY, category)
return ret
def warning(self, msg: str, category: str = "") -> int:
return self._log(LogLevel.WARNING, "├", "WARN", msg,
FOREGROUND_YELLOW,
FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY,
category)
def error(self, msg: str, category: str = "") -> int:
ret: int = self._log(LogLevel.ERROR, "├", "ERROR", msg,
FOREGROUND_RED,
FOREGROUND_RED | FOREGROUND_INTENSITY, category)
# 错误立即终止进程(避免错误后继续执行导致连锁崩溃)
sys.exit(1)
return ret
def success(self, msg: str, category: str = "") -> int:
return self._log(LogLevel.SUCCESS, "├", "SUCCESS", msg,
FOREGROUND_GREEN,
FOREGROUND_GREEN | FOREGROUND_INTENSITY, category)
def critical(self, msg: str, category: str = "") -> int:
# CRITICAL 使用 ╠ 前缀(红底白字标签,对齐 TPC critical 风格)
return self._log(LogLevel.CRITICAL, "╠", "CRITICAL", msg,
FOREGROUND_RED,
BACKGROUND_RED | FOREGROUND_WHITE | FOREGROUND_INTENSITY,
category)
def set_level(self, level: int) -> int:
self._level = level
return 0
# ============================================================
# 高级日志方法
# ============================================================
def banner(self, msg: str) -> int:
"""输出分节标题(蓝色高亮,与 TPC banner 风格对齐)。"""
self._set_color(FOREGROUND_BLUE | FOREGROUND_INTENSITY)
stdio.printf("\n=== %s ===\n\n", msg)
self._reset_color()
return 0
def compile_error(self, msg: str, file: str = "", line: int = 0) -> int:
"""格式化编译错误输出(红底白字标题 + 位置 + 错误信息)。"""
self._set_color(BACKGROUND_RED | FOREGROUND_WHITE | FOREGROUND_INTENSITY)
stdio.printf(" 编译错误 ")
self._set_color(FOREGROUND_RED | FOREGROUND_INTENSITY)
stdio.printf("\n")
if file is not None:
if file[0] != 0 and line > 0:
stdio.printf(" 位置: %s:%d\n", file, line)
elif file[0] != 0:
stdio.printf(" 文件: %s\n", file)
stdio.printf(" 错误: %s\n", msg)
self._reset_color()
return 0
def compile_warning(self, msg: str, file: str = "", line: int = 0) -> int:
"""格式化编译警告输出(黄底黑字标题 + 位置 + 警告信息)。"""
self._set_color(BACKGROUND_RED | BACKGROUND_GREEN | FOREGROUND_INTENSITY)
stdio.printf(" 编译警告 ")
self._set_color(FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY)
stdio.printf("\n")
if file is not None:
if file[0] != 0 and line > 0:
stdio.printf(" 位置: %s:%d\n", file, line)
elif file[0] != 0:
stdio.printf(" 文件: %s\n", file)
stdio.printf(" 警告: %s\n", msg)
self._reset_color()
return 0
# 全局 mbuddy 指针(由 lib.InitLib 注入)
_mbuddy: memhub.MemBuddy | t.CPtr
# 全局 logger 指针
logger: Logger | t.CPtr
log: Logger | t.CPtr
def init_logger():
"""初始化全局 logger 实例。"""
global logger, log
raw: t.CVoid | t.CPtr = _mbuddy.alloc(Logger.__sizeof__())
# if raw is None: return None 存疑,如何去管理内存?
logger = raw
logger.__before_init__()
logger.__init__(LogLevel.INFO)
log = logger
# if fmtbuffer is None: return None
# ============================================================
# --nowarn-register 开关(追加):抑制 Phase A 依赖类 WARN 输出——
# ①"跨模块函数依赖模块 text.ll 尚未生成"(HandlesExprCall,Phase A 多遍
# 收敛的中间遍,下遍重译后精确解析)。自举编译中大量出现,刷屏影响日志收敛。
# 仅抑制输出,不影响内部逻辑(标记重试等照常执行)。
# ============================================================
_nowarn_register: int = 0
# ============================================================
# 模块级便捷函数(与 TPC 的 lib.core.VLogger 对齐)
#
# 调用方式: VLogger.info("msg", "category")
# 无需先 get_logger(),方便各模块直接使用
# ============================================================
def info(msg: str, category: str = "") -> int:
"""输出 INFO 级别日志。"""
if log is not None: return log.info(msg, category)
return 0
def warning(msg: str, category: str = "") -> int:
"""输出 WARN 级别日志。"""
if log is not None: return log.warning(msg, category)
return 0
def error(msg: str, category: str = "") -> int:
"""输出 ERROR 级别日志并立即终止进程。"""
if log is not None: return log.error(msg, category)
# logger 不可用时也直接退出
sys.exit(1)
return 0
def success(msg: str, category: str = "") -> int:
"""输出 SUCCESS 级别日志。"""
if log is not None: return log.success(msg, category)
return 0
def critical(msg: str, category: str = "") -> int:
"""输出 CRITICAL 级别日志(致命错误,红底白字)。"""
if log is not None: return log.critical(msg, category)
return 0
def debug(msg: str, category: str = "") -> int:
"""输出 DEBUG 级别日志。"""
if log is not None: return log.debug(msg, category)
return 0
import t, c
from stdint import *
import stdio
import stdlib
import memhub
import sys
import w32.win32console as w32cmd
import w32.win32file as w32file
import w32.win32base as win32base
# ============================================================
# VLogger - 原生日志系统(Windows 控制台彩色输出)
#
# 输出格式与 TPC (lib/core/VLogger.py) 对齐:
# ├ INFO: message
# ├ INFO[category]: message
# ├ WARN: message
# ├ ERROR: message
# ├ SUCCESS: message
# ├ DEBUG: message
# ╠ CRITICAL: message (红底白字,致命错误)
# ╠ CRITICAL[category]: message
#
# 分段着色:前缀符号(├/╠) 用级别色,LEVEL 标签用亮色,消息用默认色
# CRITICAL 级别使用 ╠ 前缀和红底白字标签,与 TPC critical 对齐
# ============================================================
# 日志级别
class LogLevel(t.CEnum):
DEBUG = 0
INFO = 1
WARNING = 2
ERROR = 3
SUCCESS = 4
CRITICAL = 5
# Win32 控制台前景色属性
FOREGROUND_BLUE: t.CDefine = 0x0001
FOREGROUND_GREEN: t.CDefine = 0x0002
FOREGROUND_RED: t.CDefine = 0x0004
FOREGROUND_INTENSITY: t.CDefine = 0x0008
FOREGROUND_WHITE: t.CDefine = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE
FOREGROUND_CYAN: t.CDefine = FOREGROUND_BLUE | FOREGROUND_GREEN
FOREGROUND_YELLOW: t.CDefine = FOREGROUND_RED | FOREGROUND_GREEN
FOREGROUND_MAGENTA: t.CDefine = FOREGROUND_RED | FOREGROUND_BLUE
# Win32 控制台背景色属性
BACKGROUND_RED: t.CDefine = 0x0040
BACKGROUND_GREEN: t.CDefine = 0x0020
BACKGROUND_BLUE: t.CDefine = 0x0010
BACKGROUND_INTENSITY: t.CDefine = 0x0080
BACKGROUND_WHITE: t.CDefine = BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE
@t.NoVTable
class Logger:
_level: int
_console_handle: win32base.HANDLE
_use_color: int
__mbuddy__: memhub.MemBuddy | t.CPtr
def __init__(self, level: int = 1):
self._level = level
self._console_handle = w32file.GetStdHandle(w32file.STD_OUTPUT_HANDLE)
self._use_color = 1
self.__mbuddy__ = _mbuddy
def _set_color(self, attr: WORD) -> int:
uc: int = self._use_color
if uc:
ch: win32base.HANDLE = self._console_handle
ret: int = w32cmd.SetConsoleTextAttribute(ch, attr)
return ret
return 0
def _reset_color(self) -> int:
if self._use_color:
return w32cmd.SetConsoleTextAttribute(self._console_handle, FOREGROUND_WHITE)
return 0
# ============================================================
# _log - 核心日志输出(分段着色)
#
# 格式: ├ LEVEL: msg 或 ├ LEVEL[category]: msg
# 分三段着色:
# 1. 前缀符号 ├ (sym_color)
# 2. LEVEL 标签 (level_color)
# 3. 消息内容 (默认白色)
# ============================================================
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)
# LEVEL 标签着色
self._set_color(level_color)
stdio.printf("%s", level_str)
self._reset_color()
# category 可选
if category is not None and category[0] != 0:
stdio.printf(" [%s]", category)
stdio.printf(": %s\n", msg)
return 0
def debug(self, msg: str, category: str = "") -> int:
return self._log(LogLevel.DEBUG, "├", "DEBUG", msg,
FOREGROUND_INTENSITY, FOREGROUND_INTENSITY, category)
def info(self, msg: str, category: str = "") -> int:
ret: int = self._log(LogLevel.INFO, "├", "INFO", msg,
FOREGROUND_GREEN,
FOREGROUND_GREEN | FOREGROUND_INTENSITY, category)
return ret
def warning(self, msg: str, category: str = "") -> int:
return self._log(LogLevel.WARNING, "├", "WARN", msg,
FOREGROUND_YELLOW,
FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY,
category)
def error(self, msg: str, category: str = "") -> int:
ret: int = self._log(LogLevel.ERROR, "├", "ERROR", msg,
FOREGROUND_RED,
FOREGROUND_RED | FOREGROUND_INTENSITY, category)
# 错误立即终止进程(避免错误后继续执行导致连锁崩溃)
sys.exit(1)
return ret
def success(self, msg: str, category: str = "") -> int:
return self._log(LogLevel.SUCCESS, "├", "SUCCESS", msg,
FOREGROUND_GREEN,
FOREGROUND_GREEN | FOREGROUND_INTENSITY, category)
def critical(self, msg: str, category: str = "") -> int:
# CRITICAL 使用 ╠ 前缀(红底白字标签,对齐 TPC critical 风格)
return self._log(LogLevel.CRITICAL, "╠", "CRITICAL", msg,
FOREGROUND_RED,
BACKGROUND_RED | FOREGROUND_WHITE | FOREGROUND_INTENSITY,
category)
def set_level(self, level: int) -> int:
self._level = level
return 0
# ============================================================
# 高级日志方法
# ============================================================
def banner(self, msg: str) -> int:
"""输出分节标题(蓝色高亮,与 TPC banner 风格对齐)。"""
self._set_color(FOREGROUND_BLUE | FOREGROUND_INTENSITY)
stdio.printf("\n=== %s ===\n\n", msg)
self._reset_color()
return 0
def compile_error(self, msg: str, file: str = "", line: int = 0) -> int:
"""格式化编译错误输出(红底白字标题 + 位置 + 错误信息)。"""
self._set_color(BACKGROUND_RED | FOREGROUND_WHITE | FOREGROUND_INTENSITY)
stdio.printf(" 编译错误 ")
self._set_color(FOREGROUND_RED | FOREGROUND_INTENSITY)
stdio.printf("\n")
if file is not None:
if file[0] != 0 and line > 0:
stdio.printf(" 位置: %s:%d\n", file, line)
elif file[0] != 0:
stdio.printf(" 文件: %s\n", file)
stdio.printf(" 错误: %s\n", msg)
self._reset_color()
return 0
def compile_warning(self, msg: str, file: str = "", line: int = 0) -> int:
"""格式化编译警告输出(黄底黑字标题 + 位置 + 警告信息)。"""
self._set_color(BACKGROUND_RED | BACKGROUND_GREEN | FOREGROUND_INTENSITY)
stdio.printf(" 编译警告 ")
self._set_color(FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY)
stdio.printf("\n")
if file is not None:
if file[0] != 0 and line > 0:
stdio.printf(" 位置: %s:%d\n", file, line)
elif file[0] != 0:
stdio.printf(" 文件: %s\n", file)
stdio.printf(" 警告: %s\n", msg)
self._reset_color()
return 0
# 全局 mbuddy 指针(由 lib.InitLib 注入)
_mbuddy: memhub.MemBuddy | t.CPtr
# 全局 logger 指针
logger: Logger | t.CPtr
log: Logger | t.CPtr
def init_logger():
"""初始化全局 logger 实例。"""
global logger, log
raw: t.CPtr = _mbuddy.alloc(Logger.__sizeof__())
# if raw is None: return None 存疑,如何去管理内存?
logger = raw
logger.__before_init__()
logger.__init__(LogLevel.INFO)
log = logger
# if fmtbuffer is None: return None
# ============================================================
# --nowarn-register 开关(追加):抑制 Phase A 依赖类 WARN 输出——
# ①"跨模块函数依赖模块 text.ll 尚未生成"(HandlesExprCall,Phase A 多遍
# 收敛的中间遍,下遍重译后精确解析)。自举编译中大量出现,刷屏影响日志收敛。
# 仅抑制输出,不影响内部逻辑(标记重试等照常执行)。
# ============================================================
_nowarn_register: int = 0
# ============================================================
# 模块级便捷函数(与 TPC 的 lib.core.VLogger 对齐)
#
# 调用方式: VLogger.info("msg", "category")
# 无需先 get_logger(),方便各模块直接使用
# ============================================================
def info(msg: str, category: str = "") -> int:
"""输出 INFO 级别日志。"""
if log is not None: return log.info(msg, category)
return 0
def warning(msg: str, category: str = "") -> int:
"""输出 WARN 级别日志。"""
if log is not None: return log.warning(msg, category)
return 0
def error(msg: str, category: str = "") -> int:
"""输出 ERROR 级别日志并立即终止进程。"""
if log is not None: return log.error(msg, category)
# logger 不可用时也直接退出
sys.exit(1)
return 0
def success(msg: str, category: str = "") -> int:
"""输出 SUCCESS 级别日志。"""
if log is not None: return log.success(msg, category)
return 0
def critical(msg: str, category: str = "") -> int:
"""输出 CRITICAL 级别日志(致命错误,红底白字)。"""
if log is not None: return log.critical(msg, category)
return 0
def debug(msg: str, category: str = "") -> int:
"""输出 DEBUG 级别日志。"""
if log is not None: return log.debug(msg, category)
return 0
+34 -34
View File
@@ -147,7 +147,7 @@ def main() -> int:
parser.add_argument("--nowarn-register", None, argparse.BOOL, 0, None, False, argparse.STORE_TRUE, "Suppress Phase A dependency WARN")
parser.add_argument("--detection", None, argparse.BOOL, 0, None, False, argparse.STORE_TRUE, "Enable MemBuddy allocation detection (0xCDCD markers + record-table probe for out-of-bounds writes; applies to both mb and perm_pool)")
parser.add_argument("--show-args", None, argparse.BOOL, 0, None, False, argparse.STORE_TRUE, "Show all parsed arguments")
parser.add_argument("--build-dir", None, argparse.STRING, 0, None, False, argparse.STORE, "Override project.vpj build_dir (default ./.tpv_build; relative paths resolve against the project dir)")
parser.add_argument("--build-dir", None, argparse.STRING, 0, None, False, argparse.STORE, "Override project.vpj build_dir (default ./.tpv_build; relative paths resolve against the project dir)")
parser.add_argument("--no-llvmpeephole", None, argparse.BOOL, 0, None, False, argparse.STORE_TRUE, "Disable all local llvmlite peephole passes (T2 store/load forward & ret-zero, T3 no-op bitcast) in FunctionPrint serialization")
parser.add_argument("--version", "-v", argparse.BOOL, 0, None, False, argparse.STORE_TRUE, "Show version and exit")
parser.add_argument("--help", "-h", argparse.BOOL, 0, None, False, argparse.STORE_TRUE, "Show help and exit")
@@ -269,11 +269,11 @@ Target: %s
proj_loaded = 1
if proj_loaded == 1:
# 提取 project.vpj 所在目录,将相对路径解析为基于该目录的路径
proj_len: t.CSizeT = string.strlen(proj_path)
slash_pos: t.CSizeT = proj_len
proj_len: sizet = string.strlen(proj_path)
slash_pos: sizet = proj_len
for i in range(proj_len):
idx: t.CSizeT = proj_len - 1 - i
ch: t.CChar = proj_path[idx]
idx: sizet = proj_len - 1 - i
ch: char = proj_path[idx]
if ch == '/' or ch == '\\':
slash_pos = idx
break
@@ -291,17 +291,17 @@ Target: %s
Config.resolve_paths(proj_dir)
Config.print_config()
# --asan 要求工程自己在 project.vpj 里声明 ASan 运行库(TPV 不再硬编码
# clang64 的 libclang_rt 路径):clang 没有给 x86_64-w64-windows-gnu 出
# ASan 运行库,只能借用 clang64(MSVC ABI) 的那两份,是否承担这个选择
# 属于工程自身的事,故在此 fail-fast 而不是给个含混的 undefined reference。
if BuildPipeline._asan_mode != 0 and Config.asan_runtime_declared() == 0:
log.error("启用 --asan 需要在 project.vpj 的 linker.static_libs 里声明 ASan 运行库:", "asan")
log.error(" D:/msys64/clang64/lib/clang/22/lib/windows/libclang_rt.asan_dynamic-x86_64.dll.a", "asan")
log.error(" D:/msys64/clang64/lib/clang/22/lib/windows/libclang_rt.asan_dynamic_runtime_thunk-x86_64.a", "asan")
log.error("运行时还需要 PATH 里有 D:/msys64/clang64/bin(libclang_rt.asan_dynamic-x86_64.dll)", "asan")
return 1
# --asan 要求工程自己在 project.vpj 里声明 ASan 运行库(TPV 不再硬编码
# clang64 的 libclang_rt 路径):clang 没有给 x86_64-w64-windows-gnu 出
# ASan 运行库,只能借用 clang64(MSVC ABI) 的那两份,是否承担这个选择
# 属于工程自身的事,故在此 fail-fast 而不是给个含混的 undefined reference。
if BuildPipeline._asan_mode != 0 and Config.asan_runtime_declared() == 0:
log.error("启用 --asan 需要在 project.vpj 的 linker.static_libs 里声明 ASan 运行库:", "asan")
log.error(" D:/msys64/clang64/lib/clang/22/lib/windows/libclang_rt.asan_dynamic-x86_64.dll.a", "asan")
log.error(" D:/msys64/clang64/lib/clang/22/lib/windows/libclang_rt.asan_dynamic_runtime_thunk-x86_64.a", "asan")
log.error("运行时还需要 PATH 里有 D:/msys64/clang64/bin(libclang_rt.asan_dynamic-x86_64.dll)", "asan")
return 1
# === --clean: 清理 temp、output 和 includes.binary 目录 ===
if _gb_clean:
log.info("清理临时目录...", "clean")
@@ -403,7 +403,7 @@ Target: %s
if src_path is None and project is not None:
if Config.SourceDir is not None:
# 构造入口路径: SourceDir/main.vp(不再做 vp -> py 后缀识别回退)
sd_len: t.CSizeT = string.strlen(Config.SourceDir)
sd_len: sizet = string.strlen(Config.SourceDir)
path_buf: bytes = stdlib.malloc(sd_len + 16)
if path_buf is not None:
viperlib.snprintf(path_buf, sd_len + 16, "%s/main.vp", Config.SourceDir)
@@ -458,7 +458,7 @@ Target: %s
tr: HandlesTranslator.Translator | t.CPtr = HandlesTranslator.Translator()
result: int = tr.translate(tree)
if result == 0:
IR_BUF_SIZE: t.CSizeT = 262144
IR_BUF_SIZE: sizet = 262144
ir_buf: bytes = stdlib.malloc(IR_BUF_SIZE)
if ir_buf is not None:
tr.dump_ir(ir_buf, IR_BUF_SIZE, llvmlite.OUTPUT_FULL)
@@ -473,31 +473,31 @@ Target: %s
VLogger.error("SHA1 计算失败", "main")
output_name: str = "test_prog.exe"
# 从文件名提取 output_name(去掉路径和 .vp/.py 扩展名)
src_len: t.CSizeT = string.strlen(src_path)
src_len: sizet = string.strlen(src_path)
if src_len > 0:
# 找到最后一个 / 或 \ 之后的部分
base_start: t.CSizeT = src_len
i: t.CSizeT = src_len
base_start: sizet = src_len
i: sizet = src_len
while i > 0:
i -= 1
ch: t.CChar = src_path[i]
ch: char = src_path[i]
if ch == '/' or ch == '\\':
base_start = i + 1
break
if i == 0:
base_start = 0
# 找到 .vp/.py 扩展名
base_end: t.CSizeT = src_len
j: t.CSizeT = base_start
base_end: sizet = src_len
j: sizet = base_start
while j < src_len:
if src_path[j] == '.':
base_end = j
break
j += 1
# 输出名 = 文件名 + ".exe"
name_len: t.CSizeT = base_end - base_start
name_len: sizet = base_end - base_start
if name_len > 0:
out_len: t.CSizeT = name_len + 5
out_len: sizet = name_len + 5
output_name = stdlib.malloc(out_len)
if output_name is not None:
# 手动复制文件名并追加 .exe(viperlib.snprintf 不支持 %.*s,string 无 strcat)
@@ -528,20 +528,20 @@ Target: %s
# 计算 includes.binary 目录路径(链接时附加预编译 .obj)
includes_binary_dir: str = Config.get_includes_binary_dir()
ir_len: t.CSizeT = string.strlen(ir_buf)
ir_len: sizet = string.strlen(ir_buf)
# (--phase 参数已在配置加载后处理,此处直接使用 do_phase1/do_phase2)
# === Phase1 stub 分离:使用 OUTPUT_STUB/TEXT 模式分别生成 stub.ll 和 text.ll ===
if do_phase1 != 0 and temp_dir is not None and module_name is not None:
log.banner("stub 分离")
SF_IR_SIZE: t.CSizeT = 262144
td_len_sf: t.CSizeT = string.strlen(temp_dir)
SF_IR_SIZE: sizet = 262144
td_len_sf: sizet = string.strlen(temp_dir)
# 保存 stub.ll
sf_stub_buf: bytes = stdlib.malloc(SF_IR_SIZE)
if sf_stub_buf is not None:
tr.dump_ir(sf_stub_buf, SF_IR_SIZE, llvmlite.OUTPUT_STUB)
sf_stub_len: t.CSizeT = string.strlen(sf_stub_buf)
sf_stub_len: sizet = string.strlen(sf_stub_buf)
sf_stub_path: str = StubMergerCollect._sliced_path(temp_dir, td_len_sf, module_name, "stub.ll")
if sf_stub_path is not None:
sf_f: fileio.File | t.CPtr = fileio.File(sf_stub_path, fileio.MODE.W)
@@ -554,7 +554,7 @@ Target: %s
sf_text_buf: bytes = stdlib.malloc(SF_IR_SIZE)
if sf_text_buf is not None:
tr.dump_ir(sf_text_buf, SF_IR_SIZE, llvmlite.OUTPUT_TEXT)
sf_text_len: t.CSizeT = string.strlen(sf_text_buf)
sf_text_len: sizet = string.strlen(sf_text_buf)
sf_text_path: str = StubMergerCollect._sliced_path(temp_dir, td_len_sf, module_name, "text.ll")
if sf_text_path is not None:
sf_tf: fileio.File | t.CPtr = fileio.File(sf_text_path, fileio.MODE.W)
@@ -572,13 +572,13 @@ Target: %s
# === Phase2: 组合本地 stub + 依赖 stubs + 本地 text → 完整 IR ===
final_ir: bytes = ir_buf
final_ir_len: t.CSizeT = ir_len
final_ir_len: sizet = ir_len
if temp_dir is not None and module_name is not None:
log.banner("IR 组合")
SF_COMBINED_SIZE: t.CSizeT = 4194304 # 4MB
SF_COMBINED_SIZE: sizet = 4194304 # 4MB
combined_buf: bytes = stdlib.malloc(SF_COMBINED_SIZE)
if combined_buf is not None:
combined_len: t.CSizeT = StubMergerBuild.BuildCombinedIR(temp_dir, module_name, combined_buf, SF_COMBINED_SIZE)
combined_len: sizet = StubMergerBuild.BuildCombinedIR(temp_dir, module_name, combined_buf, SF_COMBINED_SIZE)
if combined_len > 0:
final_ir = combined_buf
final_ir_len = combined_len