初步清理 t. 类型异味
This commit is contained in:
1 parent
4ce55e3ea3
commit
cfb92e5da5
84 files changed
+7769
-7907
No files matched your search
@@ -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,
|
||||
|
||||
@@ -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 使用的拓扑排序资源
|
||||
|
||||
@@ -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)
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
@@ -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:
|
||||
|
||||
+746
-746
File diff suppressed because it is too large.
Load diff
+265
-265
@@ -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
|
||||
@@ -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
@@ -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(
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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,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
|
||||
@@ -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
|
||||
@@ -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:
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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]
|
||||
@@ -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()
|
||||
|
||||
@@ -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 表达式:翻译值并嵌入值文本
|
||||
|
||||
@@ -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':
|
||||
|
||||
@@ -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,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:
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 # ","
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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}],赋值将被静默截断",
|
||||
|
||||
@@ -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))
|
||||
@@ -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'
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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'):
|
||||
|
||||
@@ -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 存储触发整数隐式转指针
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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
@@ -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
@@ -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*)
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
@@ -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(仅代码)
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
@@ -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:
|
||||
|
||||
@@ -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] = '*'
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
+544
-544
File diff suppressed because it is too large.
Load diff
+259
-259
@@ -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
@@ -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
|
||||
|
||||
Reference in new issue
Block a user