修复了一些错误,更改了一点语法
This commit is contained in:
1 parent
9e2ccbfab7
commit
9910e05760
61 files changed
+2810
-2810
No files matched your search
@@ -65,7 +65,7 @@ def TranslateFileGetTrans(mb: rawptr[memhub.MemBuddy], file_path: str,
|
||||
sha1_val: str,
|
||||
current_package: str = None,
|
||||
declare_only: int = 0,
|
||||
temp_dir: str = None) -> HandlesTranslator.Translator | t.CPtr:
|
||||
temp_dir: str = None) -> rawptr[HandlesTranslator.Translator]:
|
||||
"""翻译文件,返回 Translator 对象(调用者负责 dump_ir),None 失败
|
||||
|
||||
current_package: 当前文件所属包名(用于解析相对导入),None 表示顶级模块
|
||||
@@ -127,7 +127,7 @@ def TranslateFileGetTrans(mb: rawptr[memhub.MemBuddy], file_path: str,
|
||||
pf.close()
|
||||
stdlib.free(pyi_path)
|
||||
stdlib.free(pyi_buf)
|
||||
tr: HandlesTranslator.Translator | t.CPtr = mb.alloc(HandlesTranslator.Translator.__sizeof__())
|
||||
tr: rawptr[HandlesTranslator.Translator] = mb.alloc(HandlesTranslator.Translator.__sizeof__())
|
||||
tr.__before_init__()
|
||||
tr.__init__()
|
||||
tr.ModuleSha1 = sha1_val
|
||||
@@ -596,7 +596,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)(uint64(tasks) + sizet(batch_start + j) * slot_size)
|
||||
th: vthreading.Thread | t.CPtr = vthreading.Thread(_llc_task_worker, t.CPtr(tsk))
|
||||
th: rawptr[vthreading.Thread] = vthreading.Thread(_llc_task_worker, t.CPtr(tsk))
|
||||
th.start()
|
||||
# start() 后立即取出句柄(Thread 对象栈地址可能被后续构造复用,
|
||||
# join 时再读 self.handle 可能已被 close 清空/覆盖)
|
||||
@@ -794,7 +794,7 @@ def link_obj_to_exe(output_dir: str, module_name: str, linker_cmd: str, linker_f
|
||||
_phase2_write_cmd(cmd)
|
||||
return 0
|
||||
|
||||
result: subprocess.CompletedProcess | t.CPtr = subprocess.run(cmd, True, True)
|
||||
result: rawptr[subprocess.CompletedProcess] = subprocess.run(cmd, True, True)
|
||||
if result is None:
|
||||
VLogger.error("subprocess.run 返回 None", "link")
|
||||
return 1
|
||||
@@ -852,7 +852,7 @@ def asm_to_obj(asm_path: str, sha1_val: str, output_dir: str,
|
||||
_phase2_write_cmd(cmd)
|
||||
return 0
|
||||
|
||||
result: subprocess.CompletedProcess | t.CPtr = subprocess.run(cmd, True, True)
|
||||
result: rawptr[subprocess.CompletedProcess] = subprocess.run(cmd, True, True)
|
||||
if result is None:
|
||||
VLogger.error("llvm-mc subprocess.run 返回 None", "asm")
|
||||
return 1
|
||||
@@ -1032,7 +1032,7 @@ def link_objs_to_exe(obj_paths: str, obj_paths_len: sizet,
|
||||
if _phase2_cmd_path is not None:
|
||||
_phase2_write_cmd(cmd)
|
||||
return 0
|
||||
result: subprocess.CompletedProcess | t.CPtr = subprocess.run(cmd, True, True)
|
||||
result: rawptr[subprocess.CompletedProcess] = subprocess.run(cmd, True, True)
|
||||
if result is None:
|
||||
VLogger.error("subprocess.run 返回 None", "link")
|
||||
return 1
|
||||
|
||||
@@ -35,7 +35,7 @@ import lib.core.Gen.GenApi as GenApi
|
||||
# 注入 _list/_dict 前检查被注入模块自身的依赖是否已含当前模块,命中(如 memhub↔_list)则跳过注入——
|
||||
# 否则 Phase A 多遍收敛死锁("无法完成翻译");去掉环边后 _list 仍因当前模块被其依赖而处于闭包,list 类仍由 Phase1b 注册。
|
||||
# ============================================================
|
||||
def _InjectedCreatesCycle(entry: IncludesScanner.FileEntry | t.CPtr,
|
||||
def _InjectedCreatesCycle(entry: rawptr[IncludesScanner.FileEntry],
|
||||
mod_name: str) -> int:
|
||||
"""注入 mod_name 到当前模块前检查是否成环,返回 1=成环需跳过注入"""
|
||||
if entry is None or entry.RelPath is None or mod_name is None:
|
||||
@@ -235,14 +235,14 @@ def _BreakContainerCyclesInDeps(temp_dir: str) -> int:
|
||||
# Returns: ScanResult 指针(stdlib 分配,调用方负责释放);失败返回 None
|
||||
# ============================================================
|
||||
def _BuildReachableResult(mb: rawptr[memhub.MemBuddy],
|
||||
includes_dir: str) -> IncludesScanner.ScanResult | t.CPtr:
|
||||
includes_dir: str) -> rawptr[IncludesScanner.ScanResult]:
|
||||
"""从 Sha1Store(仅可达 includes + App)构建可达 FileEntry 列表"""
|
||||
if mb is None:
|
||||
return None
|
||||
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)
|
||||
result: rawptr[IncludesScanner.ScanResult] = IncludesScanner.create_scan_result(mb)
|
||||
if result is None:
|
||||
return None
|
||||
entry_size: sizet = IncludesScanner.FileEntry.__sizeof__()
|
||||
@@ -256,7 +256,7 @@ def _BuildReachableResult(mb: rawptr[memhub.MemBuddy],
|
||||
if StubMerger._sha1_store_incdir[iidx] == '\0':
|
||||
continue
|
||||
eaddr: uint64 = uint64(result.Entries) + uint64(result.Count) * entry_size
|
||||
entry: IncludesScanner.FileEntry | t.CPtr = (IncludesScanner.FileEntry | t.CPtr)(eaddr)
|
||||
entry: rawptr[IncludesScanner.FileEntry] = rawptr[IncludesScanner.FileEntry](eaddr)
|
||||
if entry is None:
|
||||
continue
|
||||
# SHA1 深拷贝(store 槽 17 字节)
|
||||
@@ -319,7 +319,7 @@ def _BuildReachableResult(mb: rawptr[memhub.MemBuddy],
|
||||
# Returns: 0 成功,非 0 失败
|
||||
# ============================================================
|
||||
def RunPhase1(mb: rawptr[memhub.MemBuddy], includes_dir: str, temp_dir: str,
|
||||
log: VLogger.Logger | t.CPtr) -> int:
|
||||
log: rawptr[VLogger.Logger]) -> int:
|
||||
"""Phase1: 扫描 includes 目录,按需翻译并生成 stub"""
|
||||
if includes_dir is None or temp_dir is None:
|
||||
VLogger.error("includes_dir 或 temp_dir 为空,无法运行 Phase1", "Phase1")
|
||||
@@ -374,7 +374,7 @@ def RunPhase1(mb: rawptr[memhub.MemBuddy], includes_dir: str, temp_dir: str,
|
||||
# 从 Sha1Store(仅可达 includes + App)构造可达 FileEntry 列表:
|
||||
# 后续 1a/1b-pre/1b 直接遍历 result(incdir 非空条目=includes),
|
||||
# use_reachable 过滤幂等保留(result 即可达子集)
|
||||
result: IncludesScanner.ScanResult | t.CPtr = _BuildReachableResult(mb, includes_dir)
|
||||
result: rawptr[IncludesScanner.ScanResult] = _BuildReachableResult(mb, includes_dir)
|
||||
if result is None:
|
||||
VLogger.error("可达 FileEntry 列表构建失败,终止编译", "Phase1")
|
||||
return 1
|
||||
@@ -523,7 +523,7 @@ def RunPhase1(mb: rawptr[memhub.MemBuddy], includes_dir: str, temp_dir: str,
|
||||
#
|
||||
# 非可达泛型文件(_list/_dict/linkedlist/llvmlite 等)的模板若在 Phase2(mark2 之后)才注册会被 reset 回收 → list[int]/dict[...] 特化失败。
|
||||
# 故对全部 includes 轻量预注册,使模板表与节点都落在 mark1 之前(_PreRegisterAllGenericTemplates 内有 generic marker 文本预筛,不 parse 全部 AST,OOM 风险可控)。
|
||||
full_scan_g: IncludesScanner.ScanResult | t.CPtr = IncludesScanner.scan_includes(mb, includes_dir)
|
||||
full_scan_g: rawptr[IncludesScanner.ScanResult] = IncludesScanner.scan_includes(mb, includes_dir)
|
||||
if full_scan_g is not None:
|
||||
Phase1Scan._PreRegisterAllGenericTemplates(mb, full_scan_g)
|
||||
else:
|
||||
@@ -555,7 +555,7 @@ def RunPhase1(mb: rawptr[memhub.MemBuddy], includes_dir: str, temp_dir: str,
|
||||
file_idx = od_ptr[0]
|
||||
|
||||
entry_addr_r: uint64 = uint64(result.Entries) + file_idx * entry_size
|
||||
entry_r: IncludesScanner.FileEntry | t.CPtr = (IncludesScanner.FileEntry | t.CPtr)(entry_addr_r)
|
||||
entry_r: rawptr[IncludesScanner.FileEntry] = rawptr[IncludesScanner.FileEntry](entry_addr_r)
|
||||
if entry_r is None:
|
||||
p1a_fl += 1
|
||||
continue
|
||||
@@ -626,7 +626,7 @@ def RunPhase1(mb: rawptr[memhub.MemBuddy], includes_dir: str, temp_dir: str,
|
||||
t_fa1: uint64 = w32.win32base.GetTickCount64()
|
||||
|
||||
# 创建 Translator,设置 _declare_only=1(注册 struct/enum/union)
|
||||
tr_r: HandlesTranslator.Translator | t.CPtr = HandlesTranslator.Translator()
|
||||
tr_r: rawptr[HandlesTranslator.Translator] = HandlesTranslator.Translator()
|
||||
if tr_r is None:
|
||||
stdlib.free(src_buf_r)
|
||||
p1a_fl += 1
|
||||
@@ -715,7 +715,7 @@ def RunPhase1(mb: rawptr[memhub.MemBuddy], includes_dir: str, temp_dir: str,
|
||||
t_pv0: uint64 = w32.win32base.GetTickCount64()
|
||||
for i_pv in range(result.Count):
|
||||
entry_addr_pv: uint64 = uint64(result.Entries) + i_pv * entry_size
|
||||
entry_pv: IncludesScanner.FileEntry | t.CPtr = (IncludesScanner.FileEntry | t.CPtr)(entry_addr_pv)
|
||||
entry_pv: rawptr[IncludesScanner.FileEntry] = rawptr[IncludesScanner.FileEntry](entry_addr_pv)
|
||||
if entry_pv is None or entry_pv.Sha1 is None:
|
||||
p1bpre_failed += 1
|
||||
continue
|
||||
@@ -840,7 +840,7 @@ def RunPhase1(mb: rawptr[memhub.MemBuddy], includes_dir: str, temp_dir: str,
|
||||
if od_ptr_b is not None:
|
||||
file_idx_b = od_ptr_b[0]
|
||||
entry_addr: uint64 = uint64(result.Entries) + sizet(file_idx_b) * entry_size
|
||||
entry: IncludesScanner.FileEntry | t.CPtr = (IncludesScanner.FileEntry | t.CPtr)(entry_addr)
|
||||
entry: rawptr[IncludesScanner.FileEntry] = rawptr[IncludesScanner.FileEntry](entry_addr)
|
||||
if entry is None:
|
||||
failed += 1
|
||||
continue
|
||||
@@ -1017,7 +1017,7 @@ def RunPhase1(mb: rawptr[memhub.MemBuddy], includes_dir: str, temp_dir: str,
|
||||
stdlib.free(vpi_path_1b)
|
||||
|
||||
# 翻译 AST → LLVM IR
|
||||
tr: HandlesTranslator.Translator | t.CPtr = HandlesTranslator.Translator()
|
||||
tr: rawptr[HandlesTranslator.Translator] = HandlesTranslator.Translator()
|
||||
if tr is None:
|
||||
stdlib.free(src_buf)
|
||||
failed += 1
|
||||
|
||||
@@ -54,7 +54,7 @@ import lib.core.Gen.GenApi as GenApi
|
||||
# Returns: 收集到的类数量,-1 失败
|
||||
# ============================================================
|
||||
def _ScanClassInheritance(mb: rawptr[memhub.MemBuddy],
|
||||
result: IncludesScanner.ScanResult | t.CPtr,
|
||||
result: rawptr[IncludesScanner.ScanResult],
|
||||
reachable_set: str, reachable_count: int,
|
||||
use_reachable: int,
|
||||
sha1_set: str, set_count: int,
|
||||
@@ -79,7 +79,7 @@ def _ScanClassInheritance(mb: rawptr[memhub.MemBuddy],
|
||||
# class_names_buf/parent_names_buf/def_sha1s_buf 与 generic_file_indices 在调用前分配、位于本 mark 之前,reset 不影响。
|
||||
scan_mark: sizet = mb.mark()
|
||||
entry_addr: uint64 = uint64(result.Entries) + i * entry_size
|
||||
entry: IncludesScanner.FileEntry | t.CPtr = (IncludesScanner.FileEntry | t.CPtr)(entry_addr)
|
||||
entry: rawptr[IncludesScanner.FileEntry] = rawptr[IncludesScanner.FileEntry](entry_addr)
|
||||
if entry is None or entry.Sha1 is None:
|
||||
continue
|
||||
|
||||
@@ -133,7 +133,7 @@ def _ScanClassInheritance(mb: rawptr[memhub.MemBuddy],
|
||||
continue
|
||||
|
||||
# 遍历 AST 顶层节点,收集 ClassDef
|
||||
ch: list[rawptr[ast.AST]] | t.CPtr = tree.children
|
||||
ch: rawptr[list[rawptr[ast.AST]]] = tree.children
|
||||
if ch is not None:
|
||||
cn: sizet = len(ch)
|
||||
for ci in range(cn):
|
||||
@@ -253,7 +253,7 @@ def _BufHasGenericClassMarker(buf: bytes, blen: sizet) -> int:
|
||||
# 仅对命中文件用**永久池(perm_pool)**解析(模板节点与表直接进 perm_pool,跨 mark 永久存活、不占主 pool);重复注册由 _register_generic_template 内部查重跳过。
|
||||
# ============================================================
|
||||
def _PreRegisterAllGenericTemplates(mb: rawptr[memhub.MemBuddy],
|
||||
result: IncludesScanner.ScanResult | t.CPtr) -> int:
|
||||
result: rawptr[IncludesScanner.ScanResult]) -> int:
|
||||
"""预注册全部 includes 文件的泛型类模板,返回处理到的泛型类数量"""
|
||||
if result is None or mb is None:
|
||||
return 0
|
||||
@@ -264,8 +264,8 @@ def _PreRegisterAllGenericTemplates(mb: rawptr[memhub.MemBuddy],
|
||||
handled_count: int = 0
|
||||
for i in range(result.Count):
|
||||
entry_addr_pg: uint64 = uint64(result.Entries) + i * p1e_size
|
||||
entry_pg: IncludesScanner.FileEntry | t.CPtr = (
|
||||
IncludesScanner.FileEntry | t.CPtr)(entry_addr_pg)
|
||||
entry_pg: rawptr[IncludesScanner.FileEntry] = (
|
||||
rawptr[IncludesScanner.FileEntry])(entry_addr_pg)
|
||||
if entry_pg is None or entry_pg.Sha1 is None:
|
||||
continue
|
||||
# 读取文件
|
||||
@@ -305,7 +305,7 @@ def _PreRegisterAllGenericTemplates(mb: rawptr[memhub.MemBuddy],
|
||||
stdlib.free(src_buf_pg)
|
||||
continue
|
||||
# 遍历顶层 ClassDef,注册泛型模板(type_params 非 None)
|
||||
ch_pg: list[rawptr[ast.AST]] | t.CPtr = tree_pg.children
|
||||
ch_pg: rawptr[list[rawptr[ast.AST]]] = tree_pg.children
|
||||
if ch_pg is not None:
|
||||
cn_pg: sizet = len(ch_pg)
|
||||
for ci_pg in range(cn_pg):
|
||||
@@ -405,24 +405,24 @@ def _ScanTreeForContainers(node: rawptr[ast.AST],
|
||||
elif k_s == ast.ASTKind.Call:
|
||||
cl_s2: rawptr[ast.Call] = rawptr[ast.Call](node)
|
||||
_ScanTreeForContainers(cl_s2.func, need_list_box, need_dict_box, depth + 1)
|
||||
cl_args_s: list[rawptr[ast.AST]] | t.CPtr = cl_s2.args
|
||||
cl_args_s: rawptr[list[rawptr[ast.AST]]] = cl_s2.args
|
||||
if cl_args_s is not None:
|
||||
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[rawptr[ast.AST]] | t.CPtr = cl_s2.keywords
|
||||
cl_kws_s: rawptr[list[rawptr[ast.AST]]] = cl_s2.keywords
|
||||
if cl_kws_s is not None:
|
||||
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))
|
||||
kw_s: rawptr[ast.Keyword] = rawptr[ast.Keyword](cl_kws_s.get(i_k2))
|
||||
if kw_s is not None:
|
||||
_ScanTreeForContainers(kw_s.value, need_list_box, need_dict_box, depth + 1)
|
||||
elif k_s == ast.ASTKind.Assign:
|
||||
asn_s: rawptr[ast.Assign] = rawptr[ast.Assign](node)
|
||||
_ScanTreeForContainers(asn_s.value, need_list_box, need_dict_box, depth + 1)
|
||||
tgts_s: list[rawptr[ast.AST]] | t.CPtr = asn_s.targets
|
||||
tgts_s: rawptr[list[rawptr[ast.AST]]] = asn_s.targets
|
||||
if tgts_s is not None:
|
||||
nt_s: sizet = len(tgts_s)
|
||||
i_t2: sizet
|
||||
@@ -437,7 +437,7 @@ def _ScanTreeForContainers(node: rawptr[ast.AST],
|
||||
_ScanTreeForContainers(fn_s.returns, need_list_box, need_dict_box, depth + 1)
|
||||
fn_args_s: rawptr[ast.Arguments] = rawptr[ast.Arguments](fn_s.args)
|
||||
if fn_args_s is not None:
|
||||
fa_s: list[rawptr[ast.AST]] | t.CPtr = fn_args_s.args
|
||||
fa_s: rawptr[list[rawptr[ast.AST]]] = fn_args_s.args
|
||||
if fa_s is not None:
|
||||
nf_s: sizet = len(fa_s)
|
||||
i_f2: sizet
|
||||
@@ -447,7 +447,7 @@ def _ScanTreeForContainers(node: rawptr[ast.AST],
|
||||
_ScanTreeForContainers(arg_s.annotation, need_list_box, need_dict_box, depth + 1)
|
||||
elif k_s == ast.ASTKind.ClassDef:
|
||||
cd_s: rawptr[ast.ClassDef] = rawptr[ast.ClassDef](node)
|
||||
bases_s: list[rawptr[ast.AST]] | t.CPtr = cd_s.bases
|
||||
bases_s: rawptr[list[rawptr[ast.AST]]] = cd_s.bases
|
||||
if bases_s is not None:
|
||||
nb_s: sizet = len(bases_s)
|
||||
i_b2: sizet
|
||||
@@ -458,7 +458,7 @@ def _ScanTreeForContainers(node: rawptr[ast.AST],
|
||||
_ScanTreeForContainers(at_s.value, need_list_box, need_dict_box, depth + 1)
|
||||
elif k_s == ast.ASTKind.Tuple:
|
||||
tu_s: rawptr[ast.Tuple] = rawptr[ast.Tuple](node)
|
||||
elts_s: list[rawptr[ast.AST]] | t.CPtr = tu_s.elts
|
||||
elts_s: rawptr[list[rawptr[ast.AST]]] = tu_s.elts
|
||||
if elts_s is not None:
|
||||
ne_s: sizet = len(elts_s)
|
||||
i_e2: sizet
|
||||
@@ -468,23 +468,23 @@ def _ScanTreeForContainers(node: rawptr[ast.AST],
|
||||
uop_s: rawptr[ast.UnaryOp] = rawptr[ast.UnaryOp](node)
|
||||
_ScanTreeForContainers(uop_s.operand, need_list_box, need_dict_box, depth + 1)
|
||||
elif k_s == ast.ASTKind.Expr:
|
||||
ex_s: ast.Expr | t.CPtr = (ast.Expr | t.CPtr)(node)
|
||||
ex_s: rawptr[ast.Expr] = rawptr[ast.Expr](node)
|
||||
_ScanTreeForContainers(ex_s.value, need_list_box, need_dict_box, depth + 1)
|
||||
elif k_s == ast.ASTKind.Return:
|
||||
rt_s: ast.Return | t.CPtr = (ast.Return | t.CPtr)(node)
|
||||
rt_s: rawptr[ast.Return] = rawptr[ast.Return](node)
|
||||
_ScanTreeForContainers(rt_s.value, need_list_box, need_dict_box, depth + 1)
|
||||
elif k_s == ast.ASTKind.Compare:
|
||||
cp_s: ast.Compare | t.CPtr = (ast.Compare | t.CPtr)(node)
|
||||
cp_s: rawptr[ast.Compare] = rawptr[ast.Compare](node)
|
||||
_ScanTreeForContainers(cp_s.left, need_list_box, need_dict_box, depth + 1)
|
||||
cps_s: list[rawptr[ast.AST]] | t.CPtr = cp_s.comparators
|
||||
cps_s: rawptr[list[rawptr[ast.AST]]] = cp_s.comparators
|
||||
if cps_s is not None:
|
||||
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[rawptr[ast.AST]] | t.CPtr = bo_s.values
|
||||
bo_s: rawptr[ast.BoolOp] = rawptr[ast.BoolOp](node)
|
||||
bvs_s: rawptr[list[rawptr[ast.AST]]] = bo_s.values
|
||||
if bvs_s is not None:
|
||||
nv_s: sizet = len(bvs_s)
|
||||
i_v2: sizet
|
||||
@@ -498,7 +498,7 @@ def _ScanTreeForContainers(node: rawptr[ast.AST],
|
||||
# need_dict_box[0] = 1
|
||||
# 递归语句块子节点
|
||||
if node.children is not None:
|
||||
ch_s: list[rawptr[ast.AST]] | t.CPtr = node.children
|
||||
ch_s: rawptr[list[rawptr[ast.AST]]] = node.children
|
||||
n_s: sizet = len(ch_s)
|
||||
ci_s: sizet
|
||||
for ci_s in range(n_s):
|
||||
|
||||
@@ -46,7 +46,7 @@ import lib.Phase.Phase1 as Phase1
|
||||
# Returns: 0 成功,-1 失败
|
||||
# ============================================================
|
||||
def _TopoSortFiles(mb: rawptr[memhub.MemBuddy],
|
||||
result: IncludesScanner.ScanResult | t.CPtr,
|
||||
result: rawptr[IncludesScanner.ScanResult],
|
||||
reachable_set: str, reachable_count: int,
|
||||
use_reachable: int,
|
||||
sha1_set: str, set_count: int,
|
||||
@@ -91,7 +91,7 @@ def _TopoSortFiles(mb: rawptr[memhub.MemBuddy],
|
||||
# sha1→file_index 映射(简单线性查找,文件数不多)
|
||||
for i in range(result.Count):
|
||||
entry_addr: uint64 = uint64(result.Entries) + i * entry_size
|
||||
entry: IncludesScanner.FileEntry | t.CPtr = (IncludesScanner.FileEntry | t.CPtr)(entry_addr)
|
||||
entry: rawptr[IncludesScanner.FileEntry] = rawptr[IncludesScanner.FileEntry](entry_addr)
|
||||
if entry is None or entry.Sha1 is None:
|
||||
continue
|
||||
|
||||
@@ -263,7 +263,7 @@ def _TopoSortFiles(mb: rawptr[memhub.MemBuddy],
|
||||
target_sha1: str = file_sha1s_buf + fi * Phase1.SHA1_LEN
|
||||
for ri in range(result.Count):
|
||||
ea_r: uint64 = uint64(result.Entries) + ri * entry_size
|
||||
ent_r: IncludesScanner.FileEntry | t.CPtr = (IncludesScanner.FileEntry | t.CPtr)(ea_r)
|
||||
ent_r: rawptr[IncludesScanner.FileEntry] = rawptr[IncludesScanner.FileEntry](ea_r)
|
||||
if ent_r is not None and ent_r.Sha1 is not None:
|
||||
if string.strcmp(ent_r.Sha1, target_sha1) == 0:
|
||||
# 写入输出索引数组
|
||||
@@ -353,7 +353,7 @@ def _TopoSortFiles(mb: rawptr[memhub.MemBuddy],
|
||||
target_sha1_2: str = file_sha1s_buf + fi_a2 * Phase1.SHA1_LEN
|
||||
for ri in range(result.Count):
|
||||
ea_r2: uint64 = uint64(result.Entries) + ri * entry_size
|
||||
ent_r2: IncludesScanner.FileEntry | t.CPtr = (IncludesScanner.FileEntry | t.CPtr)(ea_r2)
|
||||
ent_r2: rawptr[IncludesScanner.FileEntry] = rawptr[IncludesScanner.FileEntry](ea_r2)
|
||||
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: uint64 = uint64(out_order) + out_idx * 4
|
||||
|
||||
@@ -304,7 +304,7 @@ def _PreRegisterAppGenericTemplates(mb: rawptr[memhub.MemBuddy],
|
||||
stdlib.free(src_buf_pa)
|
||||
continue
|
||||
# 遍历顶层 ClassDef,注册泛型模板(type_params 非 None)
|
||||
ch_pa: list[rawptr[ast.AST]] | t.CPtr = tree_pa.children
|
||||
ch_pa: rawptr[list[rawptr[ast.AST]]] = tree_pa.children
|
||||
if ch_pa is not None:
|
||||
cn_pa: sizet = len(ch_pa)
|
||||
for ci_pa in range(cn_pa):
|
||||
@@ -615,8 +615,8 @@ def RunMultiFileProject(mb: rawptr[memhub.MemBuddy],
|
||||
includes_binary_dir: str,
|
||||
includes_dir: str,
|
||||
do_phase1: int, do_phase2: int,
|
||||
log: VLogger.Logger | t.CPtr,
|
||||
args: argparse.ParsedArgs | t.CPtr,
|
||||
log: rawptr[VLogger.Logger],
|
||||
args: rawptr[argparse.ParsedArgs],
|
||||
linker_static_libs: str = None,
|
||||
linker_dynamic_libs: str = None) -> int:
|
||||
"""多文件项目编译
|
||||
@@ -894,7 +894,7 @@ def RunMultiFileProject(mb: rawptr[memhub.MemBuddy],
|
||||
viperlib.snprintf(full_path_pre, incdir_len_pre + rel_len_pre + 2,
|
||||
"%s/%s", incdir_pre, inc_rel_pre)
|
||||
pkg_inc_pre: str = GenApi.compute_package_from_relpath(mb, inc_rel_pre)
|
||||
tr_inc_pre: HandlesTranslator.Translator | t.CPtr = BuildPipeline.TranslateFileGetTrans(
|
||||
tr_inc_pre: rawptr[HandlesTranslator.Translator] = BuildPipeline.TranslateFileGetTrans(
|
||||
mb, full_path_pre, inc_sha1_pre, pkg_inc_pre, 1)
|
||||
stdlib.free(full_path_pre)
|
||||
if tr_inc_pre is not None:
|
||||
@@ -942,7 +942,7 @@ def RunMultiFileProject(mb: rawptr[memhub.MemBuddy],
|
||||
if string.strlen(ent_pre.Path) > src_dir_len_pre + 1:
|
||||
rel_path_pre: str = ent_pre.Path + src_dir_len_pre + 1
|
||||
pkg_pre = GenApi.compute_package_from_relpath(mb, rel_path_pre)
|
||||
tr_pre: HandlesTranslator.Translator | t.CPtr = BuildPipeline.TranslateFileGetTrans(mb, ent_pre.Path, ent_pre.Sha1, pkg_pre, 1)
|
||||
tr_pre: rawptr[HandlesTranslator.Translator] = BuildPipeline.TranslateFileGetTrans(mb, ent_pre.Path, ent_pre.Sha1, pkg_pre, 1)
|
||||
if tr_pre is None:
|
||||
VLogger.error(f"预注册失败: {ent_pre.Path}", "PhaseA")
|
||||
# OOM 清理:回收本 App 文件预注册翻译的瞬时数据
|
||||
@@ -999,7 +999,7 @@ def RunMultiFileProject(mb: rawptr[memhub.MemBuddy],
|
||||
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)
|
||||
tr_a: rawptr[HandlesTranslator.Translator] = BuildPipeline.TranslateFileGetTrans(mb, ent.Path, ent.Sha1, pkg_pa, 0, temp_dir)
|
||||
# 计时点 1:translate 返回
|
||||
t_pa1: uint64 = w32.win32base.GetTickCount64()
|
||||
if tr_a is None:
|
||||
@@ -1198,7 +1198,7 @@ def RunMultiFileProject(mb: rawptr[memhub.MemBuddy],
|
||||
if llc_ir_path is None:
|
||||
VLogger.error("llc 输入路径构造失败", "PhaseB")
|
||||
sys.exit(1)
|
||||
tslot: BuildPipeline.LlcTask | t.CPtr = (BuildPipeline.LlcTask | t.CPtr)(uint64(llc_tasks) + sizet(llc_task_count) * BuildPipeline.LlcTask.__sizeof__())
|
||||
tslot: rawptr[BuildPipeline.LlcTask] = rawptr[BuildPipeline.LlcTask](uint64(llc_tasks) + sizet(llc_task_count) * BuildPipeline.LlcTask.__sizeof__())
|
||||
if BuildPipeline.init_llc_task(tslot, llc_ir_path, output_dir, ent.Sha1,
|
||||
cc_cmd, cc_flags) != 0:
|
||||
VLogger.error(f"llc 任务构造失败: {ent.Path}", "PhaseB")
|
||||
@@ -1251,7 +1251,7 @@ def RunMultiFileProject(mb: rawptr[memhub.MemBuddy],
|
||||
# 释放 llc 任务(命令串 + 记录)
|
||||
ti: int = 0
|
||||
while ti < llc_task_count:
|
||||
tfree: BuildPipeline.LlcTask | t.CPtr = (BuildPipeline.LlcTask | t.CPtr)(uint64(llc_tasks) + sizet(ti) * BuildPipeline.LlcTask.__sizeof__())
|
||||
tfree: rawptr[BuildPipeline.LlcTask] = rawptr[BuildPipeline.LlcTask](uint64(llc_tasks) + sizet(ti) * BuildPipeline.LlcTask.__sizeof__())
|
||||
BuildPipeline.free_llc_task(tfree)
|
||||
ti += 1
|
||||
stdlib.free(llc_tasks)
|
||||
@@ -1466,7 +1466,7 @@ def RunMultiFileProject(mb: rawptr[memhub.MemBuddy],
|
||||
if string.strlen(src_fp_mi) > inc_dir_len_mi + 1:
|
||||
inc_rel_mi2: str = src_fp_mi + inc_dir_len_mi + 1
|
||||
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)
|
||||
tr_mi: rawptr[HandlesTranslator.Translator] = 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: sizet = 8388608
|
||||
@@ -1696,7 +1696,7 @@ def RunMultiFileProject(mb: rawptr[memhub.MemBuddy],
|
||||
VLogger.info("phase2command 模式:跳过 --run(exe 尚未链接)", "phase2cmd")
|
||||
elif args.get_bool("run"):
|
||||
VLogger.info(f"执行: {exe_path}", "run")
|
||||
rp: subprocess.CompletedProcess | t.CPtr = subprocess.run(exe_path, False, False)
|
||||
rp: rawptr[subprocess.CompletedProcess] = subprocess.run(exe_path, False, False)
|
||||
if rp is not None:
|
||||
VLogger.info(f"退出码: {rp.returncode}", "run")
|
||||
else:
|
||||
|
||||
@@ -16,7 +16,7 @@ import w32.fileio as fileio
|
||||
# ============================================================
|
||||
|
||||
# 全局 mbuddy 指针
|
||||
_mbuddy: memhub.MemManager | t.CPtr
|
||||
_mbuddy: rawptr[memhub.MemManager]
|
||||
|
||||
# 配置值(从 project.vpj 加载);默认 None/0:未加载时字段为 null,调用方须 is not None 检查兜底(否则垃圾指针 → 崩溃)
|
||||
SourceDir: str = None
|
||||
|
||||
@@ -70,7 +70,7 @@ def compute_sha1(pool: rawptr[memhub.MemBuddy], content: str) -> str:
|
||||
|
||||
# 构造 sha1 对象(__init__ 会初始化 state/count/buf)
|
||||
# ctx 在栈上分配(alloca),函数内使用完即丢弃,无需堆分配
|
||||
ctx: hashlib.sha1 | t.CPtr = hashlib.sha1()
|
||||
ctx: rawptr[hashlib.sha1] = hashlib.sha1()
|
||||
if ctx is None: return None
|
||||
|
||||
# 计算摘要
|
||||
|
||||
@@ -284,7 +284,7 @@ def _PyiTypeStr(buf: bytes, buf_size: sizet, pos: sizet,
|
||||
if k == ast.ASTKind.Tuple:
|
||||
tup: rawptr[ast.Tuple] = rawptr[ast.Tuple](annot)
|
||||
if tup.elts is not None:
|
||||
tup_elts: list[rawptr[ast.AST]] | t.CPtr = tup.elts
|
||||
tup_elts: rawptr[list[rawptr[ast.AST]]] = tup.elts
|
||||
tn: sizet = len(tup_elts)
|
||||
ti: sizet = 0
|
||||
while ti < tn:
|
||||
@@ -301,7 +301,7 @@ def _PyiTypeStr(buf: bytes, buf_size: sizet, pos: sizet,
|
||||
pos = _PyiTypeStr(buf, buf_size, pos, cl.func, depth + 1)
|
||||
pos = _PyiEmit(buf, buf_size, pos, "(")
|
||||
if cl.args is not None:
|
||||
cl_args: list[rawptr[ast.AST]] | t.CPtr = cl.args
|
||||
cl_args: rawptr[list[rawptr[ast.AST]]] = cl.args
|
||||
can: sizet = len(cl_args)
|
||||
cai: sizet = 0
|
||||
while cai < can:
|
||||
@@ -395,7 +395,7 @@ def _PyiDefaultStr(buf: bytes, buf_size: sizet, pos: sizet,
|
||||
# 据此合成 `-> tuple[a, b, c]`(tuple 分支同样打包成 Struct),使 stub declare 与 define 的返回类型一致。
|
||||
# 返回 None = 装饰器列表里没有 CReturn。
|
||||
# ============================================================
|
||||
def _PyiCreturnArgs(decorators: list[rawptr[ast.AST]] | t.CPtr) -> list[rawptr[ast.AST]] | t.CPtr:
|
||||
def _PyiCreturnArgs(decorators: rawptr[list[rawptr[ast.AST]]]) -> rawptr[list[rawptr[ast.AST]]]:
|
||||
"""在装饰器列表里找 @c.CReturn(...),返回其实参列表;未找到返回 None"""
|
||||
if decorators is None:
|
||||
return None
|
||||
@@ -426,7 +426,7 @@ def _PyiFunction(buf: bytes, buf_size: sizet, pos: sizet,
|
||||
"""生成函数签名到 buf,返回新的 pos"""
|
||||
# 装饰器
|
||||
if fn.decorator_list is not None:
|
||||
fn_decorator_list: list[rawptr[ast.AST]] | t.CPtr = fn.decorator_list
|
||||
fn_decorator_list: rawptr[list[rawptr[ast.AST]]] = fn.decorator_list
|
||||
dn: sizet = len(fn_decorator_list)
|
||||
di: sizet = 0
|
||||
while di < dn:
|
||||
@@ -452,12 +452,12 @@ def _PyiFunction(buf: bytes, buf_size: sizet, pos: sizet,
|
||||
|
||||
# 位置参数
|
||||
if args.args is not None:
|
||||
args_args: list[rawptr[ast.AST]] | t.CPtr = args.args
|
||||
args_args: rawptr[list[rawptr[ast.AST]]] = args.args
|
||||
an: sizet = len(args_args)
|
||||
# 默认值右对齐到 args 尾部:defaults[i] 对应 args[an - dn + i]。
|
||||
# 必须输出 '= <default>',否则 VpiReader 解析出的默认参数表无条目,跨模块缺参调用(如 depth=0)读到栈垃圾。
|
||||
# arg_defaults 必须内联声明:联合接收者的 .get 会被误分派,预声明 + 重赋值会解析成 list[int].get 返回 i32 截断指针而崩溃。
|
||||
arg_defaults: list[rawptr[ast.AST]] | t.CPtr = args.defaults
|
||||
arg_defaults: rawptr[list[rawptr[ast.AST]]] = args.defaults
|
||||
dn: sizet = 0
|
||||
if arg_defaults is not None:
|
||||
dn = len(arg_defaults)
|
||||
@@ -508,7 +508,7 @@ def _PyiFunction(buf: bytes, buf_size: sizet, pos: sizet,
|
||||
pos = _PyiTypeStr(buf, buf_size, pos, fn.returns)
|
||||
else:
|
||||
# 无 `->` 注解但带 @c.CReturn(...):合成 " -> tuple[a, b, c]"(N11)
|
||||
cre_args: list[rawptr[ast.AST]] | t.CPtr = _PyiCreturnArgs(fn.decorator_list)
|
||||
cre_args: rawptr[list[rawptr[ast.AST]]] = _PyiCreturnArgs(fn.decorator_list)
|
||||
if cre_args is not None:
|
||||
cre_n: sizet = len(cre_args)
|
||||
if cre_n > 0:
|
||||
@@ -538,7 +538,7 @@ def _PyiClass(buf: bytes, buf_size: sizet, pos: sizet,
|
||||
"""生成类定义到 buf,返回新的 pos"""
|
||||
# 装饰器
|
||||
if cls.decorator_list is not None:
|
||||
cls_decorator_list: list[rawptr[ast.AST]] | t.CPtr = cls.decorator_list
|
||||
cls_decorator_list: rawptr[list[rawptr[ast.AST]]] = cls.decorator_list
|
||||
dcn: sizet = len(cls_decorator_list)
|
||||
dci: sizet = 0
|
||||
while dci < dcn:
|
||||
@@ -557,7 +557,7 @@ def _PyiClass(buf: bytes, buf_size: sizet, pos: sizet,
|
||||
|
||||
# PEP 695 类型参数 (class Foo[T]:)
|
||||
if cls.type_params is not None:
|
||||
cls_type_params: list[rawptr[ast.AST]] | t.CPtr = cls.type_params
|
||||
cls_type_params: rawptr[list[rawptr[ast.AST]]] = cls.type_params
|
||||
tpn: sizet = len(cls_type_params)
|
||||
if tpn > 0:
|
||||
pos = _PyiEmit(buf, buf_size, pos, "[")
|
||||
@@ -573,7 +573,7 @@ def _PyiClass(buf: bytes, buf_size: sizet, pos: sizet,
|
||||
|
||||
# 基类
|
||||
if cls.bases is not None:
|
||||
cls_bases: list[rawptr[ast.AST]] | t.CPtr = cls.bases
|
||||
cls_bases: rawptr[list[rawptr[ast.AST]]] = cls.bases
|
||||
bn: sizet = len(cls_bases)
|
||||
if bn > 0:
|
||||
pos = _PyiEmit(buf, buf_size, pos, "(")
|
||||
@@ -592,7 +592,7 @@ def _PyiClass(buf: bytes, buf_size: sizet, pos: sizet,
|
||||
has_member: int = 0
|
||||
|
||||
if cls.children is not None:
|
||||
cls_children: list[rawptr[ast.AST]] | t.CPtr = cls.children
|
||||
cls_children: rawptr[list[rawptr[ast.AST]]] = cls.children
|
||||
cn: sizet = len(cls_children)
|
||||
ci: sizet = 0
|
||||
while ci < cn:
|
||||
@@ -606,7 +606,7 @@ def _PyiClass(buf: bytes, buf_size: sizet, pos: sizet,
|
||||
# __init__ 方法:先提取 self.x: Type 属性
|
||||
if mfn.name is not None and string.strcmp(mfn.name, "__init__") == 0:
|
||||
if mfn.children is not None:
|
||||
mfn_children: list[rawptr[ast.AST]] | t.CPtr = mfn.children
|
||||
mfn_children: rawptr[list[rawptr[ast.AST]]] = mfn.children
|
||||
icn: sizet = len(mfn_children)
|
||||
ici: sizet = 0
|
||||
while ici < icn:
|
||||
@@ -679,7 +679,7 @@ def _GeneratePyiFromAst(mb: rawptr[memhub.MemBuddy], tree: rawptr[ast.AST],
|
||||
# 必须带 global 声明:TPV 语义下函数内对模块级变量赋值无 global 时会创建局部变量,_lookup_cdefine_for_pyi 读到的仍是模块级 None,缓存永不命中。
|
||||
global _g_pyi_cdef_names, _g_pyi_cdef_vals, _g_pyi_cdef_count
|
||||
if tree.children is not None:
|
||||
pre_children: list[rawptr[ast.AST]] | t.CPtr = tree.children
|
||||
pre_children: rawptr[list[rawptr[ast.AST]]] = tree.children
|
||||
pcn: sizet = len(pre_children)
|
||||
# 第一遍:数本文件 t.CDefine 声明数(C 数组需先定长分配)
|
||||
_g_pyi_cdef_count = 0
|
||||
@@ -724,7 +724,7 @@ def _GeneratePyiFromAst(mb: rawptr[memhub.MemBuddy], tree: rawptr[ast.AST],
|
||||
buf[pos] = 0
|
||||
return pos
|
||||
|
||||
tree_children: list[rawptr[ast.AST]] | t.CPtr = tree.children
|
||||
tree_children: rawptr[list[rawptr[ast.AST]]] = tree.children
|
||||
n: sizet = len(tree_children)
|
||||
|
||||
# 第一遍扫描:检测 import t/c
|
||||
@@ -735,7 +735,7 @@ def _GeneratePyiFromAst(mb: rawptr[memhub.MemBuddy], tree: rawptr[ast.AST],
|
||||
if stmt is not None and stmt.kind() == ast.ASTKind.Import:
|
||||
imp: rawptr[ast.Import] = rawptr[ast.Import](stmt)
|
||||
if imp.names is not None:
|
||||
imp_names: list[rawptr[ast.AST]] | t.CPtr = imp.names
|
||||
imp_names: rawptr[list[rawptr[ast.AST]]] = imp.names
|
||||
an: sizet = len(imp_names)
|
||||
for ai in range(an):
|
||||
al: rawptr[ast.Alias] = rawptr[ast.Alias](imp_names.get(ai))
|
||||
@@ -766,7 +766,7 @@ def _GeneratePyiFromAst(mb: rawptr[memhub.MemBuddy], tree: rawptr[ast.AST],
|
||||
imp2: rawptr[ast.Import] = rawptr[ast.Import](stmt)
|
||||
pos = _PyiEmit(buf, buf_size, pos, "import ")
|
||||
if imp2.names is not None:
|
||||
imp2_names: list[rawptr[ast.AST]] | t.CPtr = imp2.names
|
||||
imp2_names: rawptr[list[rawptr[ast.AST]]] = imp2.names
|
||||
an2: sizet = len(imp2_names)
|
||||
ai2: sizet = 0
|
||||
while ai2 < an2:
|
||||
@@ -793,7 +793,7 @@ def _GeneratePyiFromAst(mb: rawptr[memhub.MemBuddy], tree: rawptr[ast.AST],
|
||||
pos = _PyiEmit(buf, buf_size, pos, ifr.module)
|
||||
pos = _PyiEmit(buf, buf_size, pos, " import ")
|
||||
if ifr.names is not None:
|
||||
ifr_names: list[rawptr[ast.AST]] | t.CPtr = ifr.names
|
||||
ifr_names: rawptr[list[rawptr[ast.AST]]] = ifr.names
|
||||
an3: sizet = len(ifr_names)
|
||||
ai3: sizet = 0
|
||||
while ai3 < an3:
|
||||
@@ -884,7 +884,7 @@ def _GeneratePyiFromAst(mb: rawptr[memhub.MemBuddy], tree: rawptr[ast.AST],
|
||||
# 提取第一个参数的整数值并输出
|
||||
call_cv: rawptr[ast.Call] = rawptr[ast.Call](aa.value)
|
||||
if call_cv.args is not None:
|
||||
call_args_cv: list[rawptr[ast.AST]] | t.CPtr = call_cv.args
|
||||
call_args_cv: rawptr[list[rawptr[ast.AST]]] = call_cv.args
|
||||
if len(call_args_cv) > 0:
|
||||
first_arg: rawptr[ast.AST] = call_args_cv.get(0)
|
||||
if first_arg is not None:
|
||||
@@ -952,7 +952,7 @@ def _GeneratePyiFromAst(mb: rawptr[memhub.MemBuddy], tree: rawptr[ast.AST],
|
||||
elif k == ast.ASTKind.Assign:
|
||||
asg: rawptr[ast.Assign] = rawptr[ast.Assign](stmt)
|
||||
if asg.targets is not None and asg.value is not None:
|
||||
asg_targets: list[rawptr[ast.AST]] | t.CPtr = asg.targets
|
||||
asg_targets: rawptr[list[rawptr[ast.AST]]] = asg.targets
|
||||
atn: sizet = len(asg_targets)
|
||||
if atn == 1:
|
||||
atg: rawptr[ast.AST] = asg_targets.get(0)
|
||||
|
||||
@@ -1785,7 +1785,7 @@ def _vpi_register_typedef_closure(pool: rawptr[memhub.MemBuddy],
|
||||
tokens_r: rawptr[ast.Token] = ast.tokenize(lx_r)
|
||||
tree_r: rawptr[ast.AST] = ast.parse_tokens(pool, tokens_r)
|
||||
if tree_r is not None and tree_r.children is not None:
|
||||
ch_r: list[rawptr[ast.AST]] | t.CPtr = tree_r.children
|
||||
ch_r: rawptr[list[rawptr[ast.AST]]] = tree_r.children
|
||||
cn_r: sizet = len(ch_r)
|
||||
# 收集子模块 imports(递归闭包):两遍处理——先累计所需长度,再按精确长度分配后填充,不存在长度上限,故无需丢弃。
|
||||
# (定长缓冲 + "装不下就静默丢弃" 会让闭包缺模块 ⇒ 该模块的 CTypedef/CDefine 不可见 ⇒ 注解解析退化。)
|
||||
@@ -1960,7 +1960,7 @@ def _ParseVpiIntoModuleImpl(pool: rawptr[memhub.MemBuddy],
|
||||
_cache_vpi_param_annots_text(vpi_buf, src_sha1)
|
||||
|
||||
# 3. 遍历 AST 顶层节点
|
||||
ch: list[rawptr[ast.AST]] | t.CPtr = tree.children
|
||||
ch: rawptr[list[rawptr[ast.AST]]] = tree.children
|
||||
if ch is None:
|
||||
if src_sha1 is not None:
|
||||
stdlib.free(src_sha1)
|
||||
@@ -2173,7 +2173,7 @@ def _ParseVpiIntoModuleImpl(pool: rawptr[memhub.MemBuddy],
|
||||
tp_stub1: list[str] | t.CPtr = class_cd1.type_params
|
||||
if tp_stub1 is not None and len(tp_stub1) > 0:
|
||||
continue
|
||||
cls_children1: list[rawptr[ast.AST]] | t.CPtr = class_cd1.children
|
||||
cls_children1: rawptr[list[rawptr[ast.AST]]] = class_cd1.children
|
||||
if cls_children1 is None:
|
||||
continue
|
||||
cn21: sizet = len(cls_children1)
|
||||
@@ -2394,7 +2394,7 @@ def _inject_reexport_class_declare(pool: rawptr[memhub.MemBuddy],
|
||||
if GenApi.find_struct_by_module(local_name, pkg_sha1) is not None:
|
||||
return 1
|
||||
# 找子模块源 entry(仅类有 entry;函数/常量查不到自然跳过)
|
||||
src_entry: GenTypes.StructEntry | t.CPtr = GenApi.find_struct_by_module(src_name, sub_sha1)
|
||||
src_entry: rawptr[GenTypes.StructEntry] = GenApi.find_struct_by_module(src_name, sub_sha1)
|
||||
if src_entry is None or src_entry.Ty is None:
|
||||
# 源模块 stub 尚未注入(包 __init__ 与子模块互相等待,见
|
||||
# _ensure_dep_vpi_injected 顶部说明):按需注入 sub_sha1 的 vpi 后
|
||||
@@ -2434,7 +2434,7 @@ def _vpi_tattr_name(node: rawptr[ast.AST], attr_name: str) -> int:
|
||||
return 0
|
||||
|
||||
|
||||
def _vpi_class_has_packed(decorator_list: list[rawptr[ast.AST]] | t.CPtr) -> int:
|
||||
def _vpi_class_has_packed(decorator_list: rawptr[list[rawptr[ast.AST]]]) -> int:
|
||||
"""检查 vpi ClassDef 装饰器列表是否含 t.attr.packed"""
|
||||
if decorator_list is None:
|
||||
return 0
|
||||
@@ -2475,7 +2475,7 @@ def _vpi_class_is_renum(class_cd: rawptr[ast.ClassDef]) -> int:
|
||||
"""
|
||||
if class_cd is None or class_cd.bases is None:
|
||||
return 0
|
||||
bases: list[rawptr[ast.AST]] | t.CPtr = class_cd.bases
|
||||
bases: rawptr[list[rawptr[ast.AST]]] = class_cd.bases
|
||||
bn: sizet = len(bases)
|
||||
for bi in range(bn):
|
||||
base_node: rawptr[ast.AST] = bases.get(bi)
|
||||
@@ -2517,7 +2517,7 @@ def _inject_class_struct_declare(pool: rawptr[memhub.MemBuddy],
|
||||
return 0
|
||||
# 1. 已注册检查(含源模块编译时注册的 entry):仅标记可见,避免重复注册
|
||||
if src_sha1 is not None and src_sha1[0] != '\0':
|
||||
existing_c: GenTypes.StructEntry | t.CPtr = GenApi.find_struct_by_module(cls_name, src_sha1)
|
||||
existing_c: rawptr[GenTypes.StructEntry] = GenApi.find_struct_by_module(cls_name, src_sha1)
|
||||
if existing_c is not None and existing_c.Ty is not None:
|
||||
GenApi.add_visible_struct(pool, cls_name)
|
||||
return 1
|
||||
@@ -2536,7 +2536,7 @@ def _inject_class_struct_declare(pool: rawptr[memhub.MemBuddy],
|
||||
string.memset(field_names_buf, 0, 8 * GenTypes.FIELD_MAX)
|
||||
string.memset(field_types_buf, 0, 8 * GenTypes.FIELD_MAX)
|
||||
field_count: int = 0
|
||||
cls_children_c: list[rawptr[ast.AST]] | t.CPtr = class_cd.children
|
||||
cls_children_c: rawptr[list[rawptr[ast.AST]]] = class_cd.children
|
||||
if cls_children_c is not None:
|
||||
cn_c: sizet = len(cls_children_c)
|
||||
for ci_c in range(cn_c):
|
||||
@@ -2567,11 +2567,11 @@ def _inject_class_struct_declare(pool: rawptr[memhub.MemBuddy],
|
||||
if field_count == 0:
|
||||
return 0
|
||||
# 4. 构建 ParamNode 链表
|
||||
first_node_c: rawptr[llvmlite.Function] = None
|
||||
prev_node_c: rawptr[llvmlite.Function] = None
|
||||
first_node_c: rawptr[llvmlite.ParamNode] = None
|
||||
prev_node_c: rawptr[llvmlite.ParamNode] = None
|
||||
for fi_c in range(field_count):
|
||||
fty_c: rawptr[llvmlite.LLVMType] = (rawptr[llvmlite.LLVMType])(field_types_buf[fi_c])
|
||||
pnode_c: rawptr[llvmlite.Function] = pool.alloc(llvmlite.ParamNode.__sizeof__())
|
||||
pnode_c: rawptr[llvmlite.ParamNode] = pool.alloc(llvmlite.ParamNode.__sizeof__())
|
||||
if pnode_c is None:
|
||||
continue
|
||||
string.memset(pnode_c, 0, llvmlite.ParamNode.__sizeof__())
|
||||
@@ -2614,7 +2614,7 @@ def _inject_class_struct_declare(pool: rawptr[memhub.MemBuddy],
|
||||
# 算偏移,与定义侧 packed 布局错位(gdt/elf/fat32 二进制格式字段错读)。
|
||||
if _vpi_class_has_packed(class_cd.decorator_list) != 0:
|
||||
llvmlite.module_set_named_type_packed(mod, pool, struct_ty_c, 1)
|
||||
entry_c: GenTypes.StructEntry | t.CPtr = GenApi.register_struct(
|
||||
entry_c: rawptr[GenTypes.StructEntry] = GenApi.register_struct(
|
||||
pool, cls_name, struct_ty_c, src_sha1)
|
||||
if entry_c is None:
|
||||
return 0
|
||||
@@ -2650,7 +2650,7 @@ def _ensure_full_value_types(mod: rawptr[llvmlite.LLVMModule],
|
||||
return
|
||||
match ty:
|
||||
case llvmlite.LLVMType.Struct(_, _, _):
|
||||
full_se_h: GenTypes.StructEntry | t.CPtr = GenApi.find_struct_by_type(ty)
|
||||
full_se_h: rawptr[GenTypes.StructEntry] = GenApi.find_struct_by_type(ty)
|
||||
if full_se_h is not None and full_se_h.Ty is not None:
|
||||
llvmlite.module_add_named_type(mod, pool, full_se_h.Ty)
|
||||
# B5:值类型注入同步 packed 标记(对齐 ensure_struct_def_in_module)——
|
||||
@@ -2750,7 +2750,7 @@ def _inject_global_variable_declare(pool: rawptr[memhub.MemBuddy],
|
||||
if gv_name_m is not None:
|
||||
viperlib.snprintf(gv_name_m, ml_v, "%s.%s", src_sha1, gname_v)
|
||||
# 去重:遍历模块全局变量链表(mangled 名匹配)
|
||||
cur_v: llvmlite.GlobalVariable | t.CPtr = mod.GlobalHead
|
||||
cur_v: rawptr[llvmlite.GlobalVariable] = mod.GlobalHead
|
||||
while cur_v is not None:
|
||||
if cur_v.Name is not None and string.strcmp(cur_v.Name, gv_name_m) == 0:
|
||||
return
|
||||
@@ -2767,7 +2767,7 @@ def _inject_global_variable_declare(pool: rawptr[memhub.MemBuddy],
|
||||
case llvmlite.LLVMType.Struct(_, _, _):
|
||||
# 对象类(@t.Object/@t.CVTable:对象即指针,HasNew/HasVTable/IsOOP)→ Ptr(struct),与定义端 handle_module_level_var 一致;
|
||||
# 纯 t.CStruct 值类(如 pci_device)保持值实例——一律转 Ptr 会把实例前 8 字节当指针解引用(#GP),一律保持值则 @t.Object 类模块级变量按指针访问读错 vtable(#PF)。
|
||||
gv_entry_v: GenTypes.StructEntry | t.CPtr = GenApi.find_struct_by_type(resolved_v)
|
||||
gv_entry_v: rawptr[GenTypes.StructEntry] = GenApi.find_struct_by_type(resolved_v)
|
||||
if gv_entry_v is not None \
|
||||
and (gv_entry_v.HasNew != 0 or gv_entry_v.HasVTable != 0 or gv_entry_v.IsOOP != 0):
|
||||
gv_ty_v = llvmlite.Ptr(pool, resolved_v)
|
||||
@@ -2794,7 +2794,7 @@ def _inject_global_variable_declare(pool: rawptr[memhub.MemBuddy],
|
||||
# 值类型(struct 值 / 数组元素 struct)注册完整定义(见 _ensure_full_value_types)
|
||||
_ensure_full_value_types(mod, pool, gv_ty_v)
|
||||
llvmlite.module_ensure_opaque_for_type(mod, pool, gv_ty_v)
|
||||
gv_v: llvmlite.GlobalVariable | t.CPtr = llvmlite.new_global_variable(pool, gv_name_m, gv_ty_v)
|
||||
gv_v: rawptr[llvmlite.GlobalVariable] = llvmlite.new_global_variable(pool, gv_name_m, gv_ty_v)
|
||||
if gv_v is None:
|
||||
return
|
||||
llvmlite.module_add_global(mod, gv_v)
|
||||
@@ -2921,7 +2921,7 @@ def _inject_function_declare(pool: rawptr[memhub.MemBuddy],
|
||||
if fd.args is not None:
|
||||
args_node: rawptr[ast.Arguments] = rawptr[ast.Arguments](fd.args)
|
||||
if args_node.args is not None:
|
||||
args_list: list[rawptr[ast.AST]] | t.CPtr = args_node.args
|
||||
args_list: rawptr[list[rawptr[ast.AST]]] = args_node.args
|
||||
param_count = len(args_list)
|
||||
# 参数数上限哨兵(fail-fast):vpi tree 深层节点在遍历处理过程中
|
||||
# 可能被覆盖损坏(见本文件顶部注释),fd.args 悬空时 __len__()
|
||||
@@ -2994,7 +2994,7 @@ def _inject_function_declare(pool: rawptr[memhub.MemBuddy],
|
||||
# 列表注册默认参数表——跨模块缺参调用(如 resolve_annotation_type 的
|
||||
# depth=0)才能按表填充,否则被调函数读到栈垃圾(假报递归过深/崩溃)。
|
||||
if args_node.defaults is not None:
|
||||
fd_dlist: list[rawptr[ast.AST]] | t.CPtr = args_node.defaults
|
||||
fd_dlist: rawptr[list[rawptr[ast.AST]]] = args_node.defaults
|
||||
fd_default_count = len(fd_dlist)
|
||||
if fd_default_count < 0 or fd_default_count > 128:
|
||||
# vpi tree 深层节点(args.defaults)可能被覆盖损坏,len 返回
|
||||
@@ -3104,7 +3104,7 @@ def _inject_method_declare(pool: rawptr[memhub.MemBuddy],
|
||||
if m_fd.args is not None:
|
||||
args_node: rawptr[ast.Arguments] = rawptr[ast.Arguments](m_fd.args)
|
||||
if args_node.args is not None:
|
||||
args_list: list[rawptr[ast.AST]] | t.CPtr = args_node.args
|
||||
args_list: rawptr[list[rawptr[ast.AST]]] = args_node.args
|
||||
param_count = len(args_list)
|
||||
# 参数数上限哨兵(fail-fast):与 _inject_function_declare 同因
|
||||
# (vpi tree 深层节点被覆盖损坏时 __len__() 返回垃圾大数)。
|
||||
@@ -3196,7 +3196,7 @@ def _inject_method_declare(pool: rawptr[memhub.MemBuddy],
|
||||
if m_fd.args is not None:
|
||||
md_args_node: rawptr[ast.Arguments] = rawptr[ast.Arguments](m_fd.args)
|
||||
if md_args_node.defaults is not None:
|
||||
md_dlist: list[rawptr[ast.AST]] | t.CPtr = md_args_node.defaults
|
||||
md_dlist: rawptr[list[rawptr[ast.AST]]] = md_args_node.defaults
|
||||
md_default_count = len(md_dlist)
|
||||
if md_default_count < 0 or md_default_count > 128:
|
||||
# 同 _inject_function_declare:vpi tree 深层节点被覆盖时
|
||||
|
||||
@@ -789,11 +789,11 @@ def _BuildReachableSha1Set(mb: rawptr[memhub.MemBuddy], source_dir: str,
|
||||
# 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)
|
||||
scan_res_r: rawptr[IncludesScanner.ScanResult] = IncludesScanner.scan_includes(mb, source_dir)
|
||||
if scan_res_r is not None:
|
||||
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)(uint64(scan_res_r.Entries) + uint64(e_i_r) * es_r)
|
||||
e_r: rawptr[IncludesScanner.FileEntry] = rawptr[IncludesScanner.FileEntry](uint64(scan_res_r.Entries) + uint64(e_i_r) * es_r)
|
||||
if e_r is None or e_r.Path is None:
|
||||
continue
|
||||
# 文件级 mark:parse 完立即回收 AST(App 全量 parse 驻留会 OOM)
|
||||
@@ -809,7 +809,7 @@ def _BuildReachableSha1Set(mb: rawptr[memhub.MemBuddy], source_dir: str,
|
||||
tokens: rawptr[ast.Token] = ast.tokenize(lx)
|
||||
tree = ast.parse_tokens(mb, tokens)
|
||||
if tree is not None:
|
||||
tr: HandlesTranslator.Translator | t.CPtr = HandlesTranslator.Translator()
|
||||
tr: rawptr[HandlesTranslator.Translator] = HandlesTranslator.Translator()
|
||||
if tr is not None:
|
||||
tr._declare_only = 2
|
||||
# 源文件包名:用 RelPath(相对 source_dir,支持子目录),
|
||||
@@ -1083,7 +1083,7 @@ def _BuildReachableSha1Set(mb: rawptr[memhub.MemBuddy], source_dir: str,
|
||||
stdlib.free(wl_pos)
|
||||
mb.reset_to(scan_mark_r)
|
||||
return -1
|
||||
tr_r2: HandlesTranslator.Translator | t.CPtr = HandlesTranslator.Translator()
|
||||
tr_r2: rawptr[HandlesTranslator.Translator] = HandlesTranslator.Translator()
|
||||
if tr_r2 is None:
|
||||
stdlib.free(abs_path)
|
||||
stdlib.free(rel_path)
|
||||
@@ -1765,7 +1765,7 @@ def LoadDepVpiIntoModule(pool: rawptr[memhub.MemBuddy],
|
||||
imported_modules: str,
|
||||
from_imports: str,
|
||||
temp_dir: str,
|
||||
trans: HandlesTranslator.Translator | t.CPtr) -> int:
|
||||
trans: rawptr[HandlesTranslator.Translator]) -> int:
|
||||
"""加载依赖模块的 .vpi 文件,将函数声明注入到当前模块"""
|
||||
if pool is None or mod is None or temp_dir is None or trans is None:
|
||||
return 0
|
||||
|
||||
@@ -36,7 +36,7 @@ import lib.Stub.StubMerger as StubMerger
|
||||
# Args: scan_result IncludesScanner 扫描结果
|
||||
# Returns: 填充的条目数,-1 表示失败
|
||||
# ============================================================
|
||||
def PopulateSha1MapStore(scan_result: IncludesScanner.ScanResult | t.CPtr) -> int:
|
||||
def PopulateSha1MapStore(scan_result: rawptr[IncludesScanner.ScanResult]) -> int:
|
||||
"""从扫描结果填充全局 SHA1 映射存储器
|
||||
|
||||
遍历 ScanResult.Entries,为每个条目构建 sha1→module_name 映射。
|
||||
@@ -71,7 +71,7 @@ def PopulateSha1MapStore(scan_result: IncludesScanner.ScanResult | t.CPtr) -> in
|
||||
if StubMerger._sha1_store_count >= StubMerger.MAX_INCLUDES:
|
||||
VLogger.error("includes SHA1 存储超上限,终止", "StubMerger")
|
||||
ea: uint64 = uint64(scan_result.Entries) + i * entry_size_p
|
||||
ent: IncludesScanner.FileEntry | t.CPtr = (IncludesScanner.FileEntry | t.CPtr)(ea)
|
||||
ent: rawptr[IncludesScanner.FileEntry] = rawptr[IncludesScanner.FileEntry](ea)
|
||||
if ent is None or ent.Sha1 is None or ent.RelPath is None:
|
||||
p_bad += 1
|
||||
continue
|
||||
|
||||
+107
-107
@@ -125,7 +125,7 @@ class AssignGenMixin:
|
||||
cl: rawptr[ast.Call] = rawptr[ast.Call](val_node)
|
||||
# 必须先把属性赋给显式类型为 list[...] | t.CPtr 的局部变量再调用 __len__(),
|
||||
# 否则编译器无法识别属性返回的 list 类型,GEP base 会变成 i32 0 导致 llc 报错
|
||||
cl_args_list: list[rawptr[ast.AST]] | t.CPtr = cl.args
|
||||
cl_args_list: rawptr[list[rawptr[ast.AST]]] = cl.args
|
||||
if cl_args_list is not None and len(cl_args_list) > 0:
|
||||
first_arg: rawptr[ast.AST] = cl_args_list.get(0)
|
||||
arg_val: int64 = self.extract_cdefine_int_value(first_arg)
|
||||
@@ -167,7 +167,7 @@ class AssignGenMixin:
|
||||
if val_node is not None and val_node.kind() == ast.ASTKind.Call:
|
||||
cl_cd: rawptr[ast.Call] = rawptr[ast.Call](val_node)
|
||||
if cl_cd is not None and cl_cd.args is not None:
|
||||
cl_args_cd: list[rawptr[ast.AST]] | t.CPtr = cl_cd.args
|
||||
cl_args_cd: rawptr[list[rawptr[ast.AST]]] = cl_cd.args
|
||||
if len(cl_args_cd) > 0:
|
||||
first_arg_cd: rawptr[ast.AST] = cl_args_cd.get(0)
|
||||
if first_arg_cd is not None and first_arg_cd.kind() == ast.ASTKind.Constant:
|
||||
@@ -609,10 +609,10 @@ class AssignGenMixin:
|
||||
# Returns:
|
||||
# 0 成功,1 失败
|
||||
# ============================================================
|
||||
def _init_global_array_from_list(self, builder: llvmlite.IRBuilder | t.CPtr,
|
||||
def _init_global_array_from_list(self, builder: rawptr[llvmlite.IRBuilder],
|
||||
pool: rawptr[memhub.MemBuddy],
|
||||
mod: rawptr[llvmlite.LLVMModule],
|
||||
array_alloca: llvmlite.Value | t.CPtr,
|
||||
array_alloca: rawptr[llvmlite.Value],
|
||||
list_node: rawptr[ast.AST],
|
||||
trans: rawptr[HT.Translator]) -> int:
|
||||
"""从列表字面量初始化全局数组,为每个元素生成 GEP + store"""
|
||||
@@ -637,10 +637,10 @@ class AssignGenMixin:
|
||||
return 1
|
||||
|
||||
# 获取列表元素
|
||||
lst: ast.List | t.CPtr = (ast.List | t.CPtr)(list_node)
|
||||
lst: rawptr[ast.List] = rawptr[ast.List](list_node)
|
||||
if lst is None or lst.elts is None:
|
||||
return 1
|
||||
elts: list[rawptr[ast.AST]] | t.CPtr = lst.elts
|
||||
elts: rawptr[list[rawptr[ast.AST]]] = lst.elts
|
||||
elts_count: sizet = len(elts)
|
||||
|
||||
# 特例:单个字符串字面量初始化字符数组([N x i8],N = strlen+1)
|
||||
@@ -660,13 +660,13 @@ class AssignGenMixin:
|
||||
"OverflowError")
|
||||
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(
|
||||
bidx_s: rawptr[llvmlite.Value] = llvmlite.const_int32(pool, bi_s)
|
||||
bp_s: rawptr[llvmlite.Value] = llvmlite.build_gep_array(
|
||||
builder, arr_ty, elem_ty, array_alloca, bidx_s)
|
||||
if bp_s is None:
|
||||
break
|
||||
bvv: llvmlite.Value | t.CPtr = llvmlite.const_int32(pool, sv_s[bi_s])
|
||||
bsv: llvmlite.Value | t.CPtr = self.Gen.ExprGenBase.coerce_to_type(
|
||||
bvv: rawptr[llvmlite.Value] = llvmlite.const_int32(pool, sv_s[bi_s])
|
||||
bsv: rawptr[llvmlite.Value] = self.Gen.ExprGenBase.coerce_to_type(
|
||||
builder, bvv, elem_ty, e0_s)
|
||||
llvmlite.build_store(builder, bsv, bp_s)
|
||||
bi_s += 1
|
||||
@@ -682,8 +682,8 @@ class AssignGenMixin:
|
||||
# 为每个元素生成 GEP + store
|
||||
for i in range(elts_count):
|
||||
elem_node: rawptr[ast.AST] = elts.get(i)
|
||||
idx_val: llvmlite.Value | t.CPtr = llvmlite.const_int32(pool, i)
|
||||
elem_ptr: llvmlite.Value | t.CPtr = llvmlite.build_gep_array(
|
||||
idx_val: rawptr[llvmlite.Value] = llvmlite.const_int32(pool, i)
|
||||
elem_ptr: rawptr[llvmlite.Value] = llvmlite.build_gep_array(
|
||||
builder, arr_ty, elem_ty, array_alloca, idx_val)
|
||||
if elem_ptr is None:
|
||||
continue
|
||||
@@ -697,13 +697,13 @@ class AssignGenMixin:
|
||||
if inner_arr != 0:
|
||||
self._init_global_array_from_list(builder, pool, mod, elem_ptr, elem_node, trans)
|
||||
continue
|
||||
elem_val: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
|
||||
elem_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, elem_node, None, 0, trans)
|
||||
if elem_val is None:
|
||||
# 元素翻译失败:直接报错终止(fail-fast),暴露上游根因
|
||||
self.Gen.TypeGenErr.fatal_error(elem_node, "全局数组初始化元素翻译失败", "TypeError")
|
||||
# 类型转换(如 i32 → i8 截断)
|
||||
store_val: llvmlite.Value | t.CPtr = elem_val
|
||||
store_val: rawptr[llvmlite.Value] = elem_val
|
||||
if elem_ptr.Ty is not None and elem_ptr.Ty.Pointee is not None:
|
||||
store_val = self.Gen.ExprGenBase.coerce_to_type(
|
||||
builder, elem_val, elem_ptr.Ty.Pointee, elem_node)
|
||||
@@ -718,13 +718,13 @@ class AssignGenMixin:
|
||||
# 整数运算自动类型提升
|
||||
# ============================================================
|
||||
def _apply_aug_op(self, pool: rawptr[memhub.MemBuddy],
|
||||
builder: llvmlite.IRBuilder | t.CPtr,
|
||||
builder: rawptr[llvmlite.IRBuilder],
|
||||
op: int,
|
||||
lhs: llvmlite.Value | t.CPtr,
|
||||
rhs: llvmlite.Value | t.CPtr,
|
||||
lhs: rawptr[llvmlite.Value],
|
||||
rhs: rawptr[llvmlite.Value],
|
||||
node: rawptr[ast.AST] = None,
|
||||
trans: rawptr[HT.Translator] = None,
|
||||
lhs_node: rawptr[ast.AST] = None) -> llvmlite.Value | t.CPtr:
|
||||
lhs_node: rawptr[ast.AST] = None) -> rawptr[llvmlite.Value]:
|
||||
"""应用增强赋值的二元运算(浮点 + 指针算术 + 整数运算)"""
|
||||
lhs_bits: int = self.Gen.ExprGenBase.get_llvm_type_bits(lhs.Ty)
|
||||
rhs_bits: int = self.Gen.ExprGenBase.get_llvm_type_bits(rhs.Ty)
|
||||
@@ -808,7 +808,7 @@ class AssignGenMixin:
|
||||
if node is None:
|
||||
return 0
|
||||
|
||||
aug: ast.AugAssign | t.CPtr = (ast.AugAssign | t.CPtr)(node)
|
||||
aug: rawptr[ast.AugAssign] = rawptr[ast.AugAssign](node)
|
||||
if aug is None:
|
||||
return 0
|
||||
|
||||
@@ -822,11 +822,11 @@ class AssignGenMixin:
|
||||
# 流程: get_attribute_ptr → load → binop → store
|
||||
if tk == ast.ASTKind.Attribute:
|
||||
pool: rawptr[memhub.MemBuddy] = trans.Pool
|
||||
builder: llvmlite.IRBuilder | t.CPtr = trans._cur_builder
|
||||
builder: rawptr[llvmlite.IRBuilder] = trans._cur_builder
|
||||
mod: rawptr[llvmlite.LLVMModule] = trans.Module
|
||||
|
||||
# 1. 获取字段指针
|
||||
field_ptr: llvmlite.Value | t.CPtr = self.Gen.ExprGenAttr.get_attribute_ptr(
|
||||
field_ptr: rawptr[llvmlite.Value] = self.Gen.ExprGenAttr.get_attribute_ptr(
|
||||
builder, pool, mod, target, trans)
|
||||
if field_ptr is None:
|
||||
# fail-fast: 属性指针解析失败
|
||||
@@ -839,21 +839,21 @@ class AssignGenMixin:
|
||||
if target_ty is None:
|
||||
# fail-fast: 字段类型信息缺失,禁止兜底 i32
|
||||
self.Gen.TypeGenErr.fatal_error(target, "字段类型信息缺失", "TypeError")
|
||||
cur_val: llvmlite.Value | t.CPtr = llvmlite.build_load(
|
||||
cur_val: rawptr[llvmlite.Value] = llvmlite.build_load(
|
||||
builder, target_ty, field_ptr)
|
||||
if cur_val is None:
|
||||
# fail-fast: 属性当前值加载失败
|
||||
self.Gen.TypeGenErr.fatal_error(target, "无法加载 attribute 当前值", "TypeError")
|
||||
|
||||
# 3. 翻译 RHS 值
|
||||
rhs_val: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
|
||||
rhs_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, aug.value, None, 0, trans)
|
||||
if rhs_val is None:
|
||||
# fail-fast: RHS 翻译失败
|
||||
self.Gen.TypeGenErr.fatal_error(target, "rhs 翻译失败", "TypeError")
|
||||
|
||||
# 4. 应用二元运算
|
||||
result: llvmlite.Value | t.CPtr = self._apply_aug_op(
|
||||
result: rawptr[llvmlite.Value] = self._apply_aug_op(
|
||||
pool, builder, aug.op, cur_val, rhs_val, node, trans, target)
|
||||
if result is None:
|
||||
# fail-fast: attribute 二元运算失败
|
||||
@@ -871,11 +871,11 @@ class AssignGenMixin:
|
||||
# 流程: get_subscript_ptr → load → binop → store
|
||||
if tk == ast.ASTKind.Subscript:
|
||||
pool: rawptr[memhub.MemBuddy] = trans.Pool
|
||||
builder: llvmlite.IRBuilder | t.CPtr = trans._cur_builder
|
||||
builder: rawptr[llvmlite.IRBuilder] = trans._cur_builder
|
||||
mod: rawptr[llvmlite.LLVMModule] = trans.Module
|
||||
|
||||
# 1. 获取元素指针
|
||||
elem_ptr: llvmlite.Value | t.CPtr = self.Gen.ExprGenName.get_subscript_ptr(
|
||||
elem_ptr: rawptr[llvmlite.Value] = self.Gen.ExprGenName.get_subscript_ptr(
|
||||
builder, pool, mod, target, trans)
|
||||
if elem_ptr is None:
|
||||
# fail-fast: 下标指针解析失败
|
||||
@@ -888,21 +888,21 @@ class AssignGenMixin:
|
||||
if target_ty is None:
|
||||
# fail-fast: 元素类型信息缺失,禁止兜底 i32
|
||||
self.Gen.TypeGenErr.fatal_error(target, "元素类型信息缺失", "TypeError")
|
||||
cur_val: llvmlite.Value | t.CPtr = llvmlite.build_load(
|
||||
cur_val: rawptr[llvmlite.Value] = llvmlite.build_load(
|
||||
builder, target_ty, elem_ptr)
|
||||
if cur_val is None:
|
||||
# fail-fast: 元素当前值加载失败
|
||||
self.Gen.TypeGenErr.fatal_error(target, "无法加载 subscript 元素当前值", "TypeError")
|
||||
|
||||
# 3. 翻译 RHS 值
|
||||
rhs_val: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
|
||||
rhs_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, aug.value, None, 0, trans)
|
||||
if rhs_val is None:
|
||||
# fail-fast: RHS 翻译失败
|
||||
self.Gen.TypeGenErr.fatal_error(target, "rhs 翻译失败", "TypeError")
|
||||
|
||||
# 4. 应用二元运算
|
||||
result: llvmlite.Value | t.CPtr = self._apply_aug_op(
|
||||
result: rawptr[llvmlite.Value] = self._apply_aug_op(
|
||||
pool, builder, aug.op, cur_val, rhs_val, node, trans, target)
|
||||
if result is None:
|
||||
# fail-fast: subscript 二元运算失败
|
||||
@@ -926,7 +926,7 @@ class AssignGenMixin:
|
||||
return 0
|
||||
|
||||
pool: rawptr[memhub.MemBuddy] = trans.Pool
|
||||
builder: llvmlite.IRBuilder | t.CPtr = trans._cur_builder
|
||||
builder: rawptr[llvmlite.IRBuilder] = trans._cur_builder
|
||||
mod: rawptr[llvmlite.LLVMModule] = trans.Module
|
||||
|
||||
# 1. 确定变量作用域类型: 0=local, 1=global, 2=nonlocal
|
||||
@@ -937,8 +937,8 @@ class AssignGenMixin:
|
||||
scope_type = 2
|
||||
|
||||
# 2. 加载当前值
|
||||
cur_val: llvmlite.Value | t.CPtr = None
|
||||
target_alloca: llvmlite.Value | t.CPtr = None
|
||||
cur_val: rawptr[llvmlite.Value] = None
|
||||
target_alloca: rawptr[llvmlite.Value] = None
|
||||
target_ty: rawptr[llvmlite.LLVMType] = None
|
||||
|
||||
if scope_type == 1:
|
||||
@@ -970,7 +970,7 @@ class AssignGenMixin:
|
||||
self.Gen.TypeGenErr.fatal_error(target, f"无法加载目标变量 '{nm.id}' 的当前值", "TypeError")
|
||||
|
||||
# 3. 翻译 RHS 值
|
||||
rhs_val: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
|
||||
rhs_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, aug.value, None, 0, trans)
|
||||
if rhs_val is None:
|
||||
# fail-fast: RHS 翻译失败
|
||||
@@ -978,7 +978,7 @@ class AssignGenMixin:
|
||||
|
||||
# 4. 类型对齐 + 应用二元运算
|
||||
# 注意: AugAssign 不走运算符重载(语义上需要 __iadd__ 而非 __add__)
|
||||
result: llvmlite.Value | t.CPtr = self._apply_aug_op(
|
||||
result: rawptr[llvmlite.Value] = self._apply_aug_op(
|
||||
pool, builder, aug.op, cur_val, rhs_val, node, trans, target)
|
||||
if result is None:
|
||||
# fail-fast: 二元运算失败
|
||||
@@ -999,7 +999,7 @@ class AssignGenMixin:
|
||||
llvmlite.build_store(builder, result, target_alloca)
|
||||
elif scope_type == 2:
|
||||
# nonlocal 变量
|
||||
nl_ptr: llvmlite.Value | t.CPtr = self.Gen.StmtGenDecl.get_nonlocal_var_ptr(
|
||||
nl_ptr: rawptr[llvmlite.Value] = self.Gen.StmtGenDecl.get_nonlocal_var_ptr(
|
||||
trans, nm.id)
|
||||
if nl_ptr is not None:
|
||||
llvmlite.build_store(builder, result, nl_ptr)
|
||||
@@ -1083,7 +1083,7 @@ class AssignGenMixin:
|
||||
if value is not None and value.kind() == ast.ASTKind.List and resolved_ty is not None:
|
||||
if self._is_single_param_carray_annot(annot) != 0:
|
||||
elem_ty_arr: rawptr[llvmlite.LLVMType] = resolved_ty.Pointee
|
||||
lst_arr: ast.List | t.CPtr = (ast.List | t.CPtr)(value)
|
||||
lst_arr: rawptr[ast.List] = rawptr[ast.List](value)
|
||||
cnt_arr: int = 0
|
||||
if lst_arr.elts is not None:
|
||||
cnt_arr = len(lst_arr.elts)
|
||||
@@ -1190,13 +1190,13 @@ class AssignGenMixin:
|
||||
return 0
|
||||
|
||||
# 检查是否已存在
|
||||
existing: llvmlite.Value | t.CPtr = self.Gen.VarGen.lookup_current(
|
||||
existing: rawptr[llvmlite.Value] = self.Gen.VarGen.lookup_current(
|
||||
trans.SymTab, nm.id)
|
||||
if existing is not None:
|
||||
return 0
|
||||
|
||||
pool: rawptr[memhub.MemBuddy] = trans.Pool
|
||||
builder: llvmlite.IRBuilder | t.CPtr = trans._cur_builder
|
||||
builder: rawptr[llvmlite.IRBuilder] = trans._cur_builder
|
||||
|
||||
# 从 annotation 推断类型(修复:原硬编码 i32 导致 str 等类型错误)
|
||||
var_ty: rawptr[llvmlite.LLVMType] = None
|
||||
@@ -1235,7 +1235,7 @@ class AssignGenMixin:
|
||||
|
||||
# 确保跨模块结构体的完整定义在当前模块中可用(供 alloca 分配空间)
|
||||
self.Gen.StructGen.ensure_struct_def_in_module(pool, trans.Module, var_ty)
|
||||
alloca: llvmlite.Value | t.CPtr = self.Gen.VarGen._alloca_at_entry(builder, var_ty)
|
||||
alloca: rawptr[llvmlite.Value] = self.Gen.VarGen._alloca_at_entry(builder, var_ty)
|
||||
if alloca is not None:
|
||||
if self.Gen.VarGen.define_var(
|
||||
trans.SymTab, nm.id, alloca) == 0:
|
||||
@@ -1402,7 +1402,7 @@ class AssignGenMixin:
|
||||
return 0
|
||||
|
||||
pool: rawptr[memhub.MemBuddy] = trans.Pool
|
||||
builder: llvmlite.IRBuilder | t.CPtr = trans._cur_builder
|
||||
builder: rawptr[llvmlite.IRBuilder] = trans._cur_builder
|
||||
mod: rawptr[llvmlite.LLVMModule] = trans.Module
|
||||
|
||||
# 确定类型(从 annotation 推断)
|
||||
@@ -1438,7 +1438,7 @@ class AssignGenMixin:
|
||||
|
||||
# global 变量:写入模块作用域中的全局变量
|
||||
if GenApi.is_global_name(trans, nm.id) != 0:
|
||||
mod_alloca: llvmlite.Value | t.CPtr = self.Gen.VarGen.lookup_module_var(
|
||||
mod_alloca: rawptr[llvmlite.Value] = self.Gen.VarGen.lookup_module_var(
|
||||
trans.SymTab, nm.id)
|
||||
if mod_alloca is not None and aa.value is not None:
|
||||
# P1-A(上下文位宽传播):把目标变量的类型作为 target_ty 传入,
|
||||
@@ -1455,12 +1455,12 @@ class AssignGenMixin:
|
||||
# 的类型实参推断都会拿不到注解。
|
||||
trans.CurAssignAnnot = aa.annotation
|
||||
trans.CurAssignNode = aa.value
|
||||
rhs_val: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
|
||||
rhs_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, aa.value,
|
||||
None, 0, trans, aa_glob_ty)
|
||||
if rhs_val is not None:
|
||||
# 对象类全局(有静态 storage):对象构造/赋值 → 绑定 storage + 复制对象
|
||||
stg_ref_aa: llvmlite.Value | t.CPtr = None
|
||||
stg_ref_aa: rawptr[llvmlite.Value] = None
|
||||
if nm.id is not None:
|
||||
stg_key_aa: str = pool.alloc(sizet(string.strlen(nm.id)) + 8)
|
||||
if stg_key_aa is not None:
|
||||
@@ -1479,7 +1479,7 @@ class AssignGenMixin:
|
||||
if rhs_inner_aa is not None and rhs_inner_aa.kind() == llvmlite.LLVMType.Struct \
|
||||
and self._stg_ty_equal(pool, stg_ty_aa, rhs_inner_aa) != 0:
|
||||
llvmlite.build_store(builder, stg_ref_aa, mod_alloca)
|
||||
stg_obj_val_aa: llvmlite.Value | t.CPtr = llvmlite.build_load(
|
||||
stg_obj_val_aa: rawptr[llvmlite.Value] = llvmlite.build_load(
|
||||
builder, stg_ty_aa, rhs_val)
|
||||
if stg_obj_val_aa is not None:
|
||||
llvmlite.build_store(builder, stg_obj_val_aa, stg_ref_aa)
|
||||
@@ -1508,7 +1508,7 @@ class AssignGenMixin:
|
||||
# P1-A:先把 nonlocal 槽位指针取出(原先在 RHS 翻译之后),以便把
|
||||
# 槽位类型作为 target_ty 传入;槽位/类型缺失时直接返回,不再发射
|
||||
# 无用的 RHS 死值。
|
||||
nl_ptr: llvmlite.Value | t.CPtr = self.Gen.StmtGenDecl.get_nonlocal_var_ptr(
|
||||
nl_ptr: rawptr[llvmlite.Value] = self.Gen.StmtGenDecl.get_nonlocal_var_ptr(
|
||||
trans, nm.id)
|
||||
# 从 nl_ptr 的类型推断 nonlocal 变量实际类型,
|
||||
# 不再强制 i32(会截断指针/结构体/i64 导致闭包数据损坏)
|
||||
@@ -1523,7 +1523,7 @@ class AssignGenMixin:
|
||||
# `nonlocal s: Stack[int] = Stack()` 的类型实参推断都会拿不到注解。
|
||||
trans.CurAssignAnnot = aa.annotation
|
||||
trans.CurAssignNode = aa.value
|
||||
rhs_val: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
|
||||
rhs_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, aa.value,
|
||||
None, 0, trans, nl_target_ty)
|
||||
if rhs_val is not None:
|
||||
@@ -1538,7 +1538,7 @@ class AssignGenMixin:
|
||||
trans.CurAssignAnnot = None
|
||||
trans.CurAssignNode = None
|
||||
return 0
|
||||
rhs_coerced: llvmlite.Value | t.CPtr = self.Gen.ExprGenBase.coerce_to_type(
|
||||
rhs_coerced: rawptr[llvmlite.Value] = self.Gen.ExprGenBase.coerce_to_type(
|
||||
builder, rhs_val, nl_target_ty, node)
|
||||
llvmlite.build_store(builder, rhs_coerced, nl_ptr)
|
||||
# 清除赋值上下文(防残留):与主分支清空时机同款。四处(主分支 /
|
||||
@@ -1553,7 +1553,7 @@ class AssignGenMixin:
|
||||
# Python 语义:仅模块级代码(Current == Root)时修改全局变量;
|
||||
# 函数内无 global 声明时应创建局部变量(走后面的 get_or_create_sym 路径)。
|
||||
if self.Gen.VarGen.is_module_scope(trans.SymTab) != 0:
|
||||
mod_glob: llvmlite.Value | t.CPtr = self.Gen.VarGen.lookup_module_var(
|
||||
mod_glob: rawptr[llvmlite.Value] = self.Gen.VarGen.lookup_module_var(
|
||||
trans.SymTab, nm.id)
|
||||
else:
|
||||
mod_glob = None
|
||||
@@ -1575,12 +1575,12 @@ class AssignGenMixin:
|
||||
# 上方 nonlocal 分支)必须同步。
|
||||
trans.CurAssignAnnot = aa.annotation
|
||||
trans.CurAssignNode = aa.value
|
||||
rhs_val_mg: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
|
||||
rhs_val_mg: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, aa.value,
|
||||
None, 0, trans, mg_val_ty)
|
||||
if rhs_val_mg is not None:
|
||||
# 对象类全局(有静态 storage):对象构造/赋值 → 绑定 storage + 复制对象
|
||||
stg_ref_mg: llvmlite.Value | t.CPtr = None
|
||||
stg_ref_mg: rawptr[llvmlite.Value] = None
|
||||
if nm.id is not None:
|
||||
stg_key_mg: str = pool.alloc(sizet(string.strlen(nm.id)) + 8)
|
||||
if stg_key_mg is not None:
|
||||
@@ -1599,7 +1599,7 @@ class AssignGenMixin:
|
||||
if rhs_inner_mg is not None and rhs_inner_mg.kind() == llvmlite.LLVMType.Struct \
|
||||
and self._stg_ty_equal(pool, stg_ty_mg, rhs_inner_mg) != 0:
|
||||
llvmlite.build_store(builder, stg_ref_mg, mod_glob)
|
||||
stg_obj_val_mg: llvmlite.Value | t.CPtr = llvmlite.build_load(
|
||||
stg_obj_val_mg: rawptr[llvmlite.Value] = llvmlite.build_load(
|
||||
builder, stg_ty_mg, rhs_val_mg)
|
||||
if stg_obj_val_mg is not None:
|
||||
llvmlite.build_store(builder, stg_obj_val_mg, stg_ref_mg)
|
||||
@@ -1631,7 +1631,7 @@ class AssignGenMixin:
|
||||
|
||||
# 普通局部变量
|
||||
# 创建 alloca
|
||||
alloca: llvmlite.Value | t.CPtr = self.Gen.VarGen.get_or_create_sym(
|
||||
alloca: rawptr[llvmlite.Value] = self.Gen.VarGen.get_or_create_sym(
|
||||
trans.SymTab, pool, builder, nm.id, var_ty)
|
||||
if alloca is None:
|
||||
# fail-fast: 存储创建失败,立即终止(禁止静默跳过)
|
||||
@@ -1675,7 +1675,7 @@ class AssignGenMixin:
|
||||
# a 保持为 i8*(可 printf/len),a__meta__ 存 __data__/__mbuddy__ 等字段,
|
||||
# 属性读写(fd3)与方法调用(fd5)均通过该影子解析。
|
||||
fd_str_ty: rawptr[llvmlite.LLVMType] = None
|
||||
fd_meta_alloca: llvmlite.Value | t.CPtr = None
|
||||
fd_meta_alloca: rawptr[llvmlite.Value] = None
|
||||
fd_meta_name: str = None
|
||||
if annot is not None and annot.kind() == ast.ASTKind.Name:
|
||||
fd_annot: rawptr[ast.Name] = rawptr[ast.Name](annot)
|
||||
@@ -1713,7 +1713,7 @@ class AssignGenMixin:
|
||||
trans.SymTab, nm.id)
|
||||
|
||||
new_vars: int = 0
|
||||
existing: llvmlite.Value | t.CPtr = self.Gen.VarGen.lookup_current(
|
||||
existing: rawptr[llvmlite.Value] = self.Gen.VarGen.lookup_current(
|
||||
trans.SymTab, nm.id)
|
||||
if existing is None:
|
||||
new_vars = 1
|
||||
@@ -1752,7 +1752,7 @@ class AssignGenMixin:
|
||||
if self.Gen.ExprGenBase.is_array_type(pt_l) != 0:
|
||||
local_arr_ty = pt_l
|
||||
if local_arr_ty is not None:
|
||||
zero_arr: llvmlite.Value | t.CPtr = llvmlite.ConstZero(
|
||||
zero_arr: rawptr[llvmlite.Value] = llvmlite.ConstZero(
|
||||
pool, local_arr_ty)
|
||||
if zero_arr is not None:
|
||||
llvmlite.build_store(builder, zero_arr, alloca)
|
||||
@@ -1772,7 +1772,7 @@ class AssignGenMixin:
|
||||
lv_target_ty: rawptr[llvmlite.LLVMType] = None
|
||||
if alloca.Ty is not None:
|
||||
lv_target_ty = alloca.Ty.Pointee
|
||||
rhs_val: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
|
||||
rhs_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, aa.value,
|
||||
None, 0, trans, lv_target_ty)
|
||||
if rhs_val is not None:
|
||||
@@ -1839,10 +1839,10 @@ class AssignGenMixin:
|
||||
if alloca_pt is not None and \
|
||||
uint64(alloca_pt) != uint64(precise_rhs_ty) \
|
||||
and rb_is_bare_generic == 0:
|
||||
new_alloca: llvmlite.Value | t.CPtr = self.Gen.VarGen._alloca_at_entry(
|
||||
new_alloca: rawptr[llvmlite.Value] = self.Gen.VarGen._alloca_at_entry(
|
||||
builder, precise_rhs_ty)
|
||||
if new_alloca is not None:
|
||||
v_entry_rb: GenTypes.VarEntry | t.CPtr = self.Gen.VarGen.lookup_var_entry(
|
||||
v_entry_rb: rawptr[GenTypes.VarEntry] = self.Gen.VarGen.lookup_var_entry(
|
||||
trans.SymTab, nm.id)
|
||||
if v_entry_rb is not None:
|
||||
v_entry_rb.Alloca = new_alloca
|
||||
@@ -1858,10 +1858,10 @@ class AssignGenMixin:
|
||||
# FakeDuck: 初始化影子结构体 __data__ 字段 = 初始字符串指针
|
||||
# (对齐 TPC HandlesAnnAssign.py: 仅当有初值时写入 __data__)
|
||||
if fd_str_ty is not None and fd_meta_alloca is not None:
|
||||
fd_data_fe: GenTypes.FieldEntry | t.CPtr = \
|
||||
fd_data_fe: rawptr[GenTypes.FieldEntry] = \
|
||||
self.Gen.StructGen.lookup_field(fd_str_ty, "__data__")
|
||||
if fd_data_fe is not None:
|
||||
fd_data_ptr: llvmlite.Value | t.CPtr = \
|
||||
fd_data_ptr: rawptr[llvmlite.Value] = \
|
||||
llvmlite.build_gep_struct(
|
||||
builder, fd_str_ty, fd_data_fe.Ty,
|
||||
fd_meta_alloca, fd_data_fe.Index)
|
||||
@@ -1878,12 +1878,12 @@ class AssignGenMixin:
|
||||
# with 上下文提供的 __mbuddy__ 注入由 _inject_requires_fields(fd4)完成,
|
||||
# 此处仅确保影子结构体初始为空指针(对齐 TPC HandlesAnnAssign.py L667-670)。
|
||||
if fd_str_ty is not None and fd_meta_alloca is not None:
|
||||
fd_buddy_fe: GenTypes.FieldEntry | t.CPtr = \
|
||||
fd_buddy_fe: rawptr[GenTypes.FieldEntry] = \
|
||||
self.Gen.StructGen.lookup_field(fd_str_ty, "__mbuddy__")
|
||||
if fd_buddy_fe is not None and fd_buddy_fe.Ty is not None:
|
||||
fd_null: llvmlite.Value | t.CPtr = llvmlite.ConstNull(
|
||||
fd_null: rawptr[llvmlite.Value] = llvmlite.ConstNull(
|
||||
pool, fd_buddy_fe.Ty, "null")
|
||||
fd_buddy_ptr: llvmlite.Value | t.CPtr = \
|
||||
fd_buddy_ptr: rawptr[llvmlite.Value] = \
|
||||
llvmlite.build_gep_struct(
|
||||
builder, fd_str_ty, fd_buddy_fe.Ty,
|
||||
fd_meta_alloca, fd_buddy_fe.Index)
|
||||
@@ -1911,14 +1911,14 @@ class AssignGenMixin:
|
||||
VLogger.error("cast failed", "ASGN")
|
||||
return 0
|
||||
|
||||
targets: list[rawptr[ast.AST]] | t.CPtr = asgn.targets
|
||||
targets: rawptr[list[rawptr[ast.AST]]] = asgn.targets
|
||||
if targets is None:
|
||||
VLogger.error("targets is None", "ASGN")
|
||||
return 0
|
||||
|
||||
# 从 trans 取共享状态(替代 11 个参数)
|
||||
pool: rawptr[memhub.MemBuddy] = trans.Pool
|
||||
builder: llvmlite.IRBuilder | t.CPtr = trans._cur_builder
|
||||
builder: rawptr[llvmlite.IRBuilder] = trans._cur_builder
|
||||
mod: rawptr[llvmlite.LLVMModule] = trans.Module
|
||||
|
||||
# 翻译 RHS 值
|
||||
@@ -1936,14 +1936,14 @@ class AssignGenMixin:
|
||||
if asg_t0 is not None and asg_t0.kind() == ast.ASTKind.Name:
|
||||
asg_nm0: rawptr[ast.Name] = rawptr[ast.Name](asg_t0)
|
||||
if asg_nm0.id is not None:
|
||||
asg_slot: llvmlite.Value | t.CPtr = self.Gen.VarGen.lookup_var(
|
||||
asg_slot: rawptr[llvmlite.Value] = self.Gen.VarGen.lookup_var(
|
||||
trans.SymTab, asg_nm0.id)
|
||||
if asg_slot is None:
|
||||
asg_slot = self.Gen.VarGen.lookup_module_var(
|
||||
trans.SymTab, asg_nm0.id)
|
||||
if asg_slot is not None and asg_slot.Ty is not None:
|
||||
asg_target_ty = asg_slot.Ty.Pointee
|
||||
rhs_val: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
|
||||
rhs_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, asgn.value, None, 0, trans, asg_target_ty)
|
||||
if rhs_val is None:
|
||||
# 增强错误信息:包含文件名 + lineno + AST 节点详情,便于定位
|
||||
@@ -2008,14 +2008,14 @@ class AssignGenMixin:
|
||||
# store + GEP 逐字段 load → store 到各 Name 目标。
|
||||
if tk == ast.ASTKind.Tuple:
|
||||
tgt_tup: rawptr[ast.Tuple] = rawptr[ast.Tuple](target)
|
||||
tgt_elts: list[rawptr[ast.AST]] | t.CPtr = tgt_tup.elts
|
||||
tgt_elts: rawptr[list[rawptr[ast.AST]]] = tgt_tup.elts
|
||||
# 守卫:rhs 不是 struct(tuple 打包)时跳过本 target
|
||||
if tgt_elts is None or rhs_val is None or rhs_val.Ty is None:
|
||||
continue
|
||||
match rhs_val.Ty:
|
||||
case llvmlite.LLVMType.Struct(_, _, _):
|
||||
tgt_n: sizet = len(tgt_elts)
|
||||
tmp_s: llvmlite.Value | t.CPtr = llvmlite.build_alloca(builder, rhs_val.Ty)
|
||||
tmp_s: rawptr[llvmlite.Value] = llvmlite.build_alloca(builder, rhs_val.Ty)
|
||||
if tmp_s is not None:
|
||||
llvmlite.build_store(builder, rhs_val, tmp_s)
|
||||
fchain: rawptr[llvmlite.Function] = llvmlite.get_struct_fields(rhs_val.Ty)
|
||||
@@ -2036,19 +2036,19 @@ class AssignGenMixin:
|
||||
tgt_nm2: rawptr[ast.Name] = rawptr[ast.Name](tgt_elt)
|
||||
if tgt_nm2.id is None:
|
||||
continue
|
||||
fp2: llvmlite.Value | t.CPtr = llvmlite.build_gep_struct(
|
||||
fp2: rawptr[llvmlite.Value] = llvmlite.build_gep_struct(
|
||||
builder, rhs_val.Ty, fty, tmp_s, fti)
|
||||
if fp2 is None:
|
||||
continue
|
||||
fv2: llvmlite.Value | t.CPtr = llvmlite.build_load(builder, fty, fp2)
|
||||
tgt_alloca: llvmlite.Value | t.CPtr = self.Gen.VarGen.lookup_var(
|
||||
fv2: rawptr[llvmlite.Value] = llvmlite.build_load(builder, fty, fp2)
|
||||
tgt_alloca: rawptr[llvmlite.Value] = self.Gen.VarGen.lookup_var(
|
||||
trans.SymTab, tgt_nm2.id)
|
||||
if tgt_alloca is None:
|
||||
tgt_alloca = self.Gen.VarGen.get_or_create_sym(
|
||||
trans.SymTab, pool, builder, tgt_nm2.id, fty)
|
||||
if tgt_alloca is None:
|
||||
continue
|
||||
sval: llvmlite.Value | t.CPtr = fv2
|
||||
sval: rawptr[llvmlite.Value] = fv2
|
||||
if tgt_alloca.Ty is not None and tgt_alloca.Ty.Pointee is not None:
|
||||
sval = self.Gen.ExprGenBase.coerce_to_type(
|
||||
builder, fv2, tgt_alloca.Ty.Pointee, node, trans)
|
||||
@@ -2061,13 +2061,13 @@ class AssignGenMixin:
|
||||
if tk == ast.ASTKind.Subscript:
|
||||
# 检查是否是 list[T] 类型的 Subscript(泛型类不注册 struct)
|
||||
# list 的 subscript 赋值走 __setitem__ 内联路径
|
||||
list_obj: llvmlite.Value | t.CPtr = self.Gen.ExprGenName.is_list_subscript(
|
||||
list_obj: rawptr[llvmlite.Value] = self.Gen.ExprGenName.is_list_subscript(
|
||||
target, trans)
|
||||
if list_obj is not None:
|
||||
# list[T] 类型: 内联生成 __setitem__ 逻辑
|
||||
sub_node: rawptr[ast.Subscript] = rawptr[ast.Subscript](target)
|
||||
if sub_node is not None and sub_node.slice is not None:
|
||||
list_idx_val: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
|
||||
list_idx_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, sub_node.slice, None, 0, trans)
|
||||
if list_idx_val is None:
|
||||
# fail-fast: list 下标翻译失败,立即终止
|
||||
@@ -2076,10 +2076,10 @@ class AssignGenMixin:
|
||||
builder, pool, list_obj, list_idx_val, rhs_val, target)
|
||||
continue
|
||||
# 普通 Subscript 赋值
|
||||
elem_ptr: llvmlite.Value | t.CPtr = self.Gen.ExprGenName.get_subscript_ptr(
|
||||
elem_ptr: rawptr[llvmlite.Value] = self.Gen.ExprGenName.get_subscript_ptr(
|
||||
builder, pool, mod, target, trans)
|
||||
if elem_ptr is not None:
|
||||
store_val: llvmlite.Value | t.CPtr = rhs_val
|
||||
store_val: rawptr[llvmlite.Value] = rhs_val
|
||||
# 守卫短路:elem 类型完整才做类型转换
|
||||
if elem_ptr.Ty is not None and elem_ptr.Ty.Pointee is not None:
|
||||
store_val = self.Gen.ExprGenBase.coerce_to_type(
|
||||
@@ -2094,14 +2094,14 @@ class AssignGenMixin:
|
||||
if sub_asgn.value.kind() == ast.ASTKind.Name:
|
||||
sub_nm: rawptr[ast.Name] = rawptr[ast.Name](sub_asgn.value)
|
||||
if sub_nm.id is not None:
|
||||
sub_alloca: llvmlite.Value | t.CPtr = self.Gen.VarGen.lookup_var(
|
||||
sub_alloca: rawptr[llvmlite.Value] = self.Gen.VarGen.lookup_var(
|
||||
trans.SymTab, sub_nm.id)
|
||||
if sub_alloca is not None and sub_alloca.Ty is not None \
|
||||
and sub_alloca.Ty.Pointee is not None \
|
||||
and self.Gen.ExprGenBase.is_ptr_type(sub_alloca.Ty) != 0:
|
||||
sub_pointee: rawptr[llvmlite.LLVMType] = sub_alloca.Ty.Pointee
|
||||
cls_nm_set: str = self.Gen.StructGen.get_class_name_by_type(pool, sub_pointee)
|
||||
obj_val_set: llvmlite.Value | t.CPtr = llvmlite.build_load(
|
||||
obj_val_set: rawptr[llvmlite.Value] = llvmlite.build_load(
|
||||
builder, sub_pointee, sub_alloca)
|
||||
# 指针类型变量 (X|t.CPtr): sub_pointee 是 Ptr(Struct),
|
||||
# 需 load 获取 Ptr(Struct) 再检查 inner struct
|
||||
@@ -2111,7 +2111,7 @@ class AssignGenMixin:
|
||||
cls_nm_set = self.Gen.StructGen.get_class_name_by_type(
|
||||
pool, sub_pointee.Pointee)
|
||||
if cls_nm_set is not None and obj_val_set is not None:
|
||||
key_val_set: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
|
||||
key_val_set: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, sub_asgn.slice, None, 0, trans)
|
||||
if key_val_set is not None:
|
||||
arg_vals_set: sizet | t.CPtr = pool.alloc(16)
|
||||
@@ -2125,14 +2125,14 @@ class AssignGenMixin:
|
||||
elif sub_asgn.value.kind() == ast.ASTKind.Attribute:
|
||||
# self._ht[key] = val → self._ht.__setitem__(key, val)
|
||||
# 通过 get_attribute_ptr 获取字段指针,再调用 __setitem__
|
||||
field_ptr_set: llvmlite.Value | t.CPtr = self.Gen.ExprGenAttr.get_attribute_ptr(
|
||||
field_ptr_set: rawptr[llvmlite.Value] = self.Gen.ExprGenAttr.get_attribute_ptr(
|
||||
builder, pool, mod, sub_asgn.value, trans)
|
||||
if field_ptr_set is not None and field_ptr_set.Ty is not None \
|
||||
and field_ptr_set.Ty.Pointee is not None \
|
||||
and self.Gen.ExprGenBase.is_ptr_type(field_ptr_set.Ty) != 0:
|
||||
field_pointee_set: rawptr[llvmlite.LLVMType] = field_ptr_set.Ty.Pointee
|
||||
cls_nm_attr: str = self.Gen.StructGen.get_class_name_by_type(pool, field_pointee_set)
|
||||
obj_val_attr: llvmlite.Value | t.CPtr = field_ptr_set
|
||||
obj_val_attr: rawptr[llvmlite.Value] = field_ptr_set
|
||||
# field_ptr 是 Ptr(Ptr(Struct)) (X|t.CPtr 字段):
|
||||
# load 解引用获取 Ptr(Struct)
|
||||
if cls_nm_attr is None \
|
||||
@@ -2144,7 +2144,7 @@ class AssignGenMixin:
|
||||
obj_val_attr = llvmlite.build_load(
|
||||
builder, field_pointee_set, field_ptr_set)
|
||||
if cls_nm_attr is not None and obj_val_attr is not None:
|
||||
key_val_attr: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
|
||||
key_val_attr: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, sub_asgn.slice, None, 0, trans)
|
||||
if key_val_attr is not None:
|
||||
arg_vals_attr: sizet | t.CPtr = pool.alloc(16)
|
||||
@@ -2159,9 +2159,9 @@ class AssignGenMixin:
|
||||
# 通用 fallback: 翻译 sub.value 并尝试 __setitem__ 或直接 GEP+store
|
||||
# 处理 Name/Attribute 之外的节点以及 SymTab 查找失败的情况
|
||||
if sub_asgn is not None and sub_asgn.value is not None:
|
||||
obj_val_gen: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
|
||||
obj_val_gen: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, sub_asgn.value, None, 0, trans)
|
||||
key_val_gen: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
|
||||
key_val_gen: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, sub_asgn.slice, None, 0, trans)
|
||||
if obj_val_gen is not None and key_val_gen is not None \
|
||||
and obj_val_gen.Ty is not None:
|
||||
@@ -2187,8 +2187,8 @@ class AssignGenMixin:
|
||||
# 非自定义结构体: 直接 GEP + store
|
||||
# 处理 get_subscript_ptr 因边界情况返回 None 的指针下标
|
||||
elem_gen: rawptr[llvmlite.LLVMType] = obj_val_gen.Ty.Pointee
|
||||
store_val_gen: llvmlite.Value | t.CPtr = rhs_val
|
||||
elem_ptr_gen: llvmlite.Value | t.CPtr = None
|
||||
store_val_gen: rawptr[llvmlite.Value] = rhs_val
|
||||
elem_ptr_gen: rawptr[llvmlite.Value] = None
|
||||
match elem_gen:
|
||||
case llvmlite.LLVMType.Array(arr_elem_gen, _):
|
||||
elem_ptr_gen = llvmlite.build_gep_array(
|
||||
@@ -2228,21 +2228,21 @@ class AssignGenMixin:
|
||||
fd_meta_w: str = pool.alloc(256)
|
||||
if fd_meta_w is not None:
|
||||
viperlib.snprintf(fd_meta_w, 256, "%s__meta__", fd_obj_nm.id)
|
||||
fd_meta_vw: llvmlite.Value | t.CPtr = self.Gen.VarGen.lookup_current(
|
||||
fd_meta_vw: rawptr[llvmlite.Value] = self.Gen.VarGen.lookup_current(
|
||||
trans.SymTab, fd_meta_w)
|
||||
if fd_meta_vw is not None:
|
||||
fd_sty_w: rawptr[llvmlite.LLVMType] = \
|
||||
self.Gen.StructGen.get_struct_type("_str")
|
||||
if fd_sty_w is not None:
|
||||
fd_fe_w: GenTypes.FieldEntry | t.CPtr = \
|
||||
fd_fe_w: rawptr[GenTypes.FieldEntry] = \
|
||||
self.Gen.StructGen.lookup_field(fd_sty_w, fd_an.attr)
|
||||
if fd_fe_w is not None and fd_fe_w.Ty is not None:
|
||||
fd_fp_w: llvmlite.Value | t.CPtr = \
|
||||
fd_fp_w: rawptr[llvmlite.Value] = \
|
||||
llvmlite.build_gep_struct(
|
||||
builder, fd_sty_w, fd_fe_w.Ty,
|
||||
fd_meta_vw, fd_fe_w.Index)
|
||||
if fd_fp_w is not None:
|
||||
sv_fd: llvmlite.Value | t.CPtr = \
|
||||
sv_fd: rawptr[llvmlite.Value] = \
|
||||
self.Gen.ExprGenBase.coerce_to_type(
|
||||
builder, rhs_val, fd_fe_w.Ty, node)
|
||||
llvmlite.build_store(builder, sv_fd, fd_fp_w)
|
||||
@@ -2254,11 +2254,11 @@ class AssignGenMixin:
|
||||
if self.Gen.CallGenVt._write_vtable_attr(
|
||||
builder, pool, mod, target, rhs_val, trans) == 1:
|
||||
continue
|
||||
field_ptr: llvmlite.Value | t.CPtr = self.Gen.ExprGenAttr.get_attribute_ptr(
|
||||
field_ptr: rawptr[llvmlite.Value] = self.Gen.ExprGenAttr.get_attribute_ptr(
|
||||
builder, pool, mod, target, trans)
|
||||
if field_ptr is not None:
|
||||
# 获取字段类型,对 rhs_val 进行类型转换(如 i32 → i64)
|
||||
store_val: llvmlite.Value | t.CPtr = rhs_val
|
||||
store_val: rawptr[llvmlite.Value] = rhs_val
|
||||
if field_ptr.Ty is not None and field_ptr.Ty.Pointee is not None:
|
||||
store_val = self.Gen.ExprGenBase.coerce_to_type(
|
||||
builder, rhs_val, field_ptr.Ty.Pointee, node, trans)
|
||||
@@ -2291,7 +2291,7 @@ class AssignGenMixin:
|
||||
continue
|
||||
# global 变量:写入模块作用域中的全局变量
|
||||
if GenApi.is_global_name(trans, nm.id) != 0:
|
||||
mod_alloca: llvmlite.Value | t.CPtr = self.Gen.VarGen.lookup_module_var(
|
||||
mod_alloca: rawptr[llvmlite.Value] = self.Gen.VarGen.lookup_module_var(
|
||||
trans.SymTab, nm.id)
|
||||
if mod_alloca is None:
|
||||
# fail-fast: global 变量未注册,无法赋值
|
||||
@@ -2302,7 +2302,7 @@ class AssignGenMixin:
|
||||
# 对象类全局(裸类名注解 → 静态 storage):对象构造/赋值 → 引用绑定
|
||||
# 到 storage + 复制对象到 storage;否则 store 栈 alloca 指针悬垂,
|
||||
# 或模块级构造初始化器被丢弃后全局保持 NULL(见 TranslatorGenMixin)。
|
||||
stg_ref_as: llvmlite.Value | t.CPtr = None
|
||||
stg_ref_as: rawptr[llvmlite.Value] = None
|
||||
if nm.id is not None:
|
||||
stg_key_as: str = pool.alloc(sizet(string.strlen(nm.id)) + 8)
|
||||
if stg_key_as is not None:
|
||||
@@ -2323,7 +2323,7 @@ class AssignGenMixin:
|
||||
# 1) @g 引用绑定到 storage(丢弃临时 alloca,避免悬垂)
|
||||
llvmlite.build_store(builder, stg_ref_as, mod_alloca)
|
||||
# 2) 复制构造结果(临时对象)到 storage(函数内复制,alloca 仍有效)
|
||||
stg_obj_val_as: llvmlite.Value | t.CPtr = llvmlite.build_load(
|
||||
stg_obj_val_as: rawptr[llvmlite.Value] = llvmlite.build_load(
|
||||
builder, stg_ty_as, rhs_val)
|
||||
if stg_obj_val_as is not None:
|
||||
llvmlite.build_store(builder, stg_obj_val_as, stg_ref_as)
|
||||
@@ -2338,7 +2338,7 @@ class AssignGenMixin:
|
||||
|
||||
# nonlocal 变量:通过闭包 env 写入
|
||||
if GenApi.is_nonlocal_name(trans, nm.id) != 0:
|
||||
nl_ptr: llvmlite.Value | t.CPtr = self.Gen.StmtGenDecl.get_nonlocal_var_ptr(
|
||||
nl_ptr: rawptr[llvmlite.Value] = self.Gen.StmtGenDecl.get_nonlocal_var_ptr(
|
||||
trans, nm.id)
|
||||
if nl_ptr is None:
|
||||
# fail-fast: nonlocal 变量指针解析失败
|
||||
@@ -2357,7 +2357,7 @@ class AssignGenMixin:
|
||||
target,
|
||||
f"nonlocal 变量 '{nm.id}' 类型信息丢失,无法写入",
|
||||
"TypeError")
|
||||
rhs_coerced: llvmlite.Value | t.CPtr = self.Gen.ExprGenBase.coerce_to_type(
|
||||
rhs_coerced: rawptr[llvmlite.Value] = self.Gen.ExprGenBase.coerce_to_type(
|
||||
builder, rhs_val, nl_target_ty, node, trans)
|
||||
llvmlite.build_store(builder, rhs_coerced, nl_ptr)
|
||||
continue
|
||||
@@ -2366,13 +2366,13 @@ class AssignGenMixin:
|
||||
# 否则静默创建局部变量遮蔽全局,全局保持 null 导致运行时崩溃
|
||||
# (_mbuddy = mb 缺 global 声明即此类 bug:Int32 解引用 null 崩溃)
|
||||
if self.Gen.VarGen.is_module_scope(trans.SymTab) == 0:
|
||||
mod_gv: llvmlite.Value | t.CPtr = self.Gen.VarGen.lookup_module_var(
|
||||
mod_gv: rawptr[llvmlite.Value] = self.Gen.VarGen.lookup_module_var(
|
||||
trans.SymTab, nm.id)
|
||||
if mod_gv is not None:
|
||||
self.Gen.TypeGenErr.fatal_error(target, f"变量 '{nm.id}' 是模块级全局变量,函数内赋值需用 global 声明(否则创建局部变量遮蔽全局,导致全局保持 null 崩溃)", "SyntaxError")
|
||||
|
||||
# 普通局部变量
|
||||
alloca: llvmlite.Value | t.CPtr = self.Gen.VarGen.get_or_create_sym(
|
||||
alloca: rawptr[llvmlite.Value] = self.Gen.VarGen.get_or_create_sym(
|
||||
trans.SymTab, pool, builder, nm.id, rhs_val.Ty)
|
||||
if alloca is not None:
|
||||
# 无注解赋值:从 RHS 表达式推断类名设置变量注解
|
||||
@@ -2383,7 +2383,7 @@ class AssignGenMixin:
|
||||
self.Gen.VarGen.set_var_annot_class_name(
|
||||
trans.SymTab, nm.id, cls_inf)
|
||||
# 按 alloca 类型对值进行转换(如 double → float)
|
||||
store_val: llvmlite.Value | t.CPtr = rhs_val
|
||||
store_val: rawptr[llvmlite.Value] = rhs_val
|
||||
if alloca.Ty is not None and alloca.Ty.Pointee is not None:
|
||||
store_val = self.Gen.ExprGenBase.coerce_to_type(
|
||||
builder, rhs_val, alloca.Ty.Pointee, node, trans)
|
||||
@@ -2395,7 +2395,7 @@ class AssignGenMixin:
|
||||
if asgn.value is not None \
|
||||
and asgn.value.kind() == ast.ASTKind.Lambda:
|
||||
self.Gen.CallGenLeafKit.register_closure_name(nm.id)
|
||||
existing: llvmlite.Value | t.CPtr = self.Gen.VarGen.lookup_current(
|
||||
existing: rawptr[llvmlite.Value] = self.Gen.VarGen.lookup_current(
|
||||
trans.SymTab, nm.id)
|
||||
if existing is None:
|
||||
new_vars += 1
|
||||
@@ -2427,7 +2427,7 @@ class AssignGenMixin:
|
||||
mod: rawptr[llvmlite.LLVMModule],
|
||||
node: rawptr[ast.AST],
|
||||
trans: rawptr[HT.Translator],
|
||||
rhs_val: llvmlite.Value | t.CPtr = None) -> str:
|
||||
rhs_val: rawptr[llvmlite.Value] = None) -> str:
|
||||
"""从 RHS 表达式推断类名,无法推断返回 None"""
|
||||
if node is None or trans is None:
|
||||
return None
|
||||
@@ -2442,7 +2442,7 @@ class AssignGenMixin:
|
||||
cand: str = (rawptr[ast.Name](cl.func)).id
|
||||
if cand is None:
|
||||
return None
|
||||
se: GenTypes.StructEntry | t.CPtr = self.Gen.StructGen.find_struct(cand)
|
||||
se: rawptr[GenTypes.StructEntry] = self.Gen.StructGen.find_struct(cand)
|
||||
if se is not None:
|
||||
return cand
|
||||
return None
|
||||
@@ -2504,7 +2504,7 @@ class AssignGenMixin:
|
||||
nm: rawptr[ast.Name] = rawptr[ast.Name](node)
|
||||
if nm is None or nm.id is None:
|
||||
return None
|
||||
ve: GenTypes.VarEntry | t.CPtr = self.Gen.VarGen.lookup_var_entry(
|
||||
ve: rawptr[GenTypes.VarEntry] = self.Gen.VarGen.lookup_var_entry(
|
||||
trans.SymTab, nm.id)
|
||||
if ve is None:
|
||||
return None
|
||||
@@ -2572,7 +2572,7 @@ class AssignGenMixin:
|
||||
if seglen > 0 and seglen < 256:
|
||||
string.strncpy(seg, annot + s, seglen)
|
||||
seg[seglen] = '\0'
|
||||
se: GenTypes.StructEntry | t.CPtr = self.Gen.StructGen.find_struct(seg)
|
||||
se: rawptr[GenTypes.StructEntry] = self.Gen.StructGen.find_struct(seg)
|
||||
if se is not None:
|
||||
return seg
|
||||
start = i + 1
|
||||
@@ -2587,7 +2587,7 @@ class AssignGenMixin:
|
||||
if seglen > 0 and seglen < 256:
|
||||
string.strncpy(seg, annot + s, seglen)
|
||||
seg[seglen] = '\0'
|
||||
se: GenTypes.StructEntry | t.CPtr = self.Gen.StructGen.find_struct(seg)
|
||||
se: rawptr[GenTypes.StructEntry] = self.Gen.StructGen.find_struct(seg)
|
||||
if se is not None:
|
||||
return seg
|
||||
return None
|
||||
|
||||
+274
-274
File diff suppressed because it is too large.
Load diff
@@ -17,9 +17,9 @@ class BaseGenMixin:
|
||||
Gen: rawptr[Generator.Generator]
|
||||
Pool: rawptr[memhub.MemBuddy] # 内存池
|
||||
Module: rawptr[llvmlite.LLVMModule] # 当前 LLVM 模块
|
||||
Builder: llvmlite.IRBuilder | t.CPtr # 当前 IRBuilder
|
||||
Builder: rawptr[llvmlite.IRBuilder] # 当前 IRBuilder
|
||||
# 符号表/函数表
|
||||
SymTab: GenTypes.SymbolTable | t.CPtr
|
||||
SymTab: rawptr[GenTypes.SymbolTable]
|
||||
Funcs: rawptr[GenTypes.FuncEntry]
|
||||
FuncCount: int
|
||||
# 导入/模块信息
|
||||
@@ -28,7 +28,7 @@ class BaseGenMixin:
|
||||
ModuleSha1: str
|
||||
# 当前翻译上下文
|
||||
CurFunc: rawptr[llvmlite.Function]
|
||||
CurBuilder: llvmlite.IRBuilder | t.CPtr
|
||||
CurBuilder: rawptr[llvmlite.IRBuilder]
|
||||
CurClassName: str
|
||||
|
||||
def InitBaseGen(self, pool: rawptr[memhub.MemBuddy]) -> int:
|
||||
|
||||
@@ -89,12 +89,12 @@ class CallGenBase:
|
||||
GlobalFuncNameIdxBuilt: int
|
||||
|
||||
# --- 全局默认参数表(原 _global_defaults/_global_defaults_count) ---
|
||||
GlobalDefaults: GenTypes.FuncDefaultsEntry | t.CPtr
|
||||
GlobalDefaults: rawptr[GenTypes.FuncDefaultsEntry]
|
||||
GlobalDefaultsCount: int
|
||||
|
||||
# --- 依赖模块 text.ll「方法返回类型文本」缓存(_LookupMethodRetTyFromTextLL 性能优化) ---
|
||||
# key = define 的完整 mangled 函数名("{sha1}.{后缀}"),值只存文本(绝不存 LLVMType*,其分配在每文件 reset 失效的 pool 中);表与键/值均 PermPool 分配,命中后用调用方 pool 重建类型,建表失败即不缓存并回退原扫描。
|
||||
MethodRetTyMap: hashtable.HashTable | t.CPtr
|
||||
MethodRetTyMap: rawptr[hashtable.HashTable]
|
||||
|
||||
def InitCallGen(self) -> int:
|
||||
"""初始化调用 Mixin 字段(子类构造时内联调用,规避 NoVTable 继承符号不转发)"""
|
||||
@@ -582,7 +582,7 @@ class CallGenBase:
|
||||
mod: rawptr[llvmlite.LLVMModule],
|
||||
call_name: str,
|
||||
ret_ty: rawptr[llvmlite.LLVMType],
|
||||
param_head: rawptr[llvmlite.Function],
|
||||
param_head: rawptr[llvmlite.Value],
|
||||
param_count: int):
|
||||
"""为跨模块方法调用创建 declare 声明
|
||||
|
||||
@@ -617,7 +617,7 @@ class CallGenBase:
|
||||
return
|
||||
# 遍历现有参数链表计数(避免依赖 GSList.Count 字段的类型推断)
|
||||
cur_count: int = 0
|
||||
cur_p: llvmlite.Param | t.CPtr = llvmlite.function_get_param_head(existing)
|
||||
cur_p: rawptr[llvmlite.Param] = llvmlite.function_get_param_head(existing)
|
||||
while cur_p is not None:
|
||||
cur_count += 1
|
||||
if cur_count > DECLARE_CHAIN_LIMIT:
|
||||
@@ -627,7 +627,7 @@ class CallGenBase:
|
||||
# 只追加缺失的参数(cur_count < param_count 时)
|
||||
if cur_count < param_count:
|
||||
# 定位到 param_head 的第 cur_count 个节点开始追加
|
||||
pnode2: rawptr[llvmlite.Function] = param_head
|
||||
pnode2: rawptr[llvmlite.Value] = param_head
|
||||
pi2: int = 0
|
||||
# 跳过已有的 cur_count 个参数
|
||||
while pnode2 is not None and pi2 < cur_count:
|
||||
@@ -636,7 +636,7 @@ class CallGenBase:
|
||||
# 追加剩余参数
|
||||
while pnode2 is not None and pi2 < param_count:
|
||||
if pnode2.Ty is not None:
|
||||
param2: llvmlite.Param | t.CPtr = llvmlite.new_param(pool, pnode2.Ty, None)
|
||||
param2: rawptr[llvmlite.Param] = llvmlite.new_param(pool, pnode2.Ty, None)
|
||||
if param2 is not None:
|
||||
llvmlite.function_add_param(existing, param2)
|
||||
pnode2 = pnode2.Next
|
||||
@@ -688,7 +688,7 @@ class CallGenBase:
|
||||
i32_ty_d: rawptr[llvmlite.LLVMType] = llvmlite.Int32(pool)
|
||||
i8_ptr_d: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, llvmlite.Int8(pool))
|
||||
# 添加参数(declare 中参数名无意义,设为 None 只输出类型)
|
||||
pnode: rawptr[llvmlite.Function] = param_head
|
||||
pnode: rawptr[llvmlite.Value] = param_head
|
||||
pi: int = 0
|
||||
while pnode is not None and pi < param_count:
|
||||
param_ty_d: rawptr[llvmlite.LLVMType] = pnode.Ty
|
||||
@@ -707,7 +707,7 @@ class CallGenBase:
|
||||
case _:
|
||||
pass
|
||||
if param_ty_d is not None:
|
||||
param: llvmlite.Param | t.CPtr = llvmlite.new_param(pool, param_ty_d, None)
|
||||
param: rawptr[llvmlite.Param] = llvmlite.new_param(pool, param_ty_d, None)
|
||||
if param is not None:
|
||||
llvmlite.function_add_param(func, param)
|
||||
pnode = pnode.Next
|
||||
@@ -937,7 +937,7 @@ class CallGenBase:
|
||||
"""查返回类型文本缓存:命中返回文本,未命中返回 None"""
|
||||
if self.Gen is None or class_sha1 is None or method_name is None:
|
||||
return None
|
||||
ht: hashtable.HashTable | t.CPtr = self.Gen.CallGenBase.MethodRetTyMap
|
||||
ht: rawptr[hashtable.HashTable] = self.Gen.CallGenBase.MethodRetTyMap
|
||||
if ht is None:
|
||||
return None
|
||||
sha1_len: sizet = string.strlen(class_sha1)
|
||||
@@ -972,7 +972,7 @@ class CallGenBase:
|
||||
perm: rawptr[memhub.MemBuddy] = CompilerFactory.factory.PermPool
|
||||
if perm is None:
|
||||
return
|
||||
ht: hashtable.HashTable | t.CPtr = self.Gen.CallGenBase.MethodRetTyMap
|
||||
ht: rawptr[hashtable.HashTable] = self.Gen.CallGenBase.MethodRetTyMap
|
||||
if ht is None:
|
||||
ht = hashtable.HashTable(perm)
|
||||
if ht is None:
|
||||
|
||||
@@ -83,18 +83,18 @@ class CallGenCBuiltin(CallGenBase.CallGenBase):
|
||||
|
||||
|
||||
def translate_c_deref(self, pool: rawptr[memhub.MemBuddy],
|
||||
builder: llvmlite.IRBuilder | t.CPtr,
|
||||
builder: rawptr[llvmlite.IRBuilder],
|
||||
mod: rawptr[llvmlite.LLVMModule],
|
||||
cl: rawptr[ast.Call],
|
||||
trans: rawptr[HT.Translator] = None) -> llvmlite.Value | t.CPtr:
|
||||
trans: rawptr[HT.Translator] = None) -> rawptr[llvmlite.Value]:
|
||||
"""c.Deref(ptr) → load 按 ptr 的 pointee 类型"""
|
||||
if cl is None:
|
||||
return None
|
||||
cargs: list[rawptr[ast.AST]] | t.CPtr = cl.args
|
||||
cargs: rawptr[list[rawptr[ast.AST]]] = cl.args
|
||||
if cargs is None or len(cargs) < 1:
|
||||
return None
|
||||
|
||||
ptr_val: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
|
||||
ptr_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, cargs.get(0), None, 0, trans)
|
||||
if ptr_val is None:
|
||||
return None
|
||||
@@ -135,7 +135,7 @@ class CallGenCBuiltin(CallGenBase.CallGenBase):
|
||||
dref_is_ptr: int = self.Gen.ExprGenBase.is_ptr_type(dref_ty)
|
||||
# 整数/浮点/指针目标均推断(指针 → bitcast 后
|
||||
# load 8 字节;struct 值目标不推断,保持 i8 读)
|
||||
dref_ptr: llvmlite.Value | t.CPtr = None
|
||||
dref_ptr: rawptr[llvmlite.Value] = None
|
||||
if (dref_bits != 0 or dref_fbits != 0 or dref_is_ptr != 0) \
|
||||
and dref_bits != 8:
|
||||
dref_ptr_ty: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, dref_ty)
|
||||
@@ -152,16 +152,16 @@ class CallGenCBuiltin(CallGenBase.CallGenBase):
|
||||
|
||||
|
||||
def translate_c_derefas(self, pool: rawptr[memhub.MemBuddy],
|
||||
builder: llvmlite.IRBuilder | t.CPtr,
|
||||
builder: rawptr[llvmlite.IRBuilder],
|
||||
mod: rawptr[llvmlite.LLVMModule],
|
||||
cl: rawptr[ast.Call],
|
||||
trans: rawptr[HT.Translator] = None) -> llvmlite.Value | t.CPtr:
|
||||
trans: rawptr[HT.Translator] = None) -> rawptr[llvmlite.Value]:
|
||||
"""c.DerefAs(ptr, val) → store val to ptr(bitcast 后 store)
|
||||
单参形式 c.DerefAs(ptr) → 读取 ptr 指向的值(等价 c.Deref(ptr))。
|
||||
"""
|
||||
if cl is None:
|
||||
return None
|
||||
cargs: list[rawptr[ast.AST]] | t.CPtr = cl.args
|
||||
cargs: rawptr[list[rawptr[ast.AST]]] = cl.args
|
||||
if cargs is None or len(cargs) < 1:
|
||||
return None
|
||||
# 单参形式:deref 读(paging.vp save_pt_range L263
|
||||
@@ -172,9 +172,9 @@ class CallGenCBuiltin(CallGenBase.CallGenBase):
|
||||
if len(cargs) < 2:
|
||||
return self.translate_c_deref(pool, builder, mod, cl, trans)
|
||||
|
||||
ptr_val: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
|
||||
ptr_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, cargs.get(0), None, 0, trans)
|
||||
val: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
|
||||
val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, cargs.get(1), None, 0, trans)
|
||||
if ptr_val is None or val is None:
|
||||
return None
|
||||
@@ -192,13 +192,13 @@ class CallGenCBuiltin(CallGenBase.CallGenBase):
|
||||
if self.Gen.StructGen.find_struct_by_type(ptr_pointee) is not None:
|
||||
if ptr_pointee is val_pointee:
|
||||
# 同一结构体类型:load 值再 store(结构体拷贝)
|
||||
loaded: llvmlite.Value | t.CPtr = llvmlite.build_load(
|
||||
loaded: rawptr[llvmlite.Value] = llvmlite.build_load(
|
||||
builder, val_pointee, val)
|
||||
if loaded is not None:
|
||||
# bitcast ptr 到结构体指针再 store
|
||||
struct_ptr_ty: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(
|
||||
pool, ptr_pointee)
|
||||
casted_ptr: llvmlite.Value | t.CPtr = llvmlite.build_bitcast(
|
||||
casted_ptr: rawptr[llvmlite.Value] = llvmlite.build_bitcast(
|
||||
builder, ptr_val, struct_ptr_ty)
|
||||
if casted_ptr is not None:
|
||||
llvmlite.build_store(builder, loaded, casted_ptr)
|
||||
@@ -206,7 +206,7 @@ class CallGenCBuiltin(CallGenBase.CallGenBase):
|
||||
|
||||
# bitcast ptr 到 val.Ty* 再 store
|
||||
val_ptr_ty: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, val.Ty)
|
||||
casted_ptr: llvmlite.Value | t.CPtr = llvmlite.build_bitcast(builder, ptr_val, val_ptr_ty)
|
||||
casted_ptr: rawptr[llvmlite.Value] = llvmlite.build_bitcast(builder, ptr_val, val_ptr_ty)
|
||||
if casted_ptr is None:
|
||||
return None
|
||||
llvmlite.build_store(builder, val, casted_ptr)
|
||||
@@ -214,18 +214,18 @@ class CallGenCBuiltin(CallGenBase.CallGenBase):
|
||||
|
||||
|
||||
def translate_c_set(self, pool: rawptr[memhub.MemBuddy],
|
||||
builder: llvmlite.IRBuilder | t.CPtr,
|
||||
builder: rawptr[llvmlite.IRBuilder],
|
||||
mod: rawptr[llvmlite.LLVMModule],
|
||||
cl: rawptr[ast.Call],
|
||||
trans: rawptr[HT.Translator] = None) -> llvmlite.Value | t.CPtr:
|
||||
trans: rawptr[HT.Translator] = None) -> rawptr[llvmlite.Value]:
|
||||
"""c.Set(a, b) → a = b(赋值语义,a 为左值)"""
|
||||
if cl is None:
|
||||
return None
|
||||
cargs: list[rawptr[ast.AST]] | t.CPtr = cl.args
|
||||
cargs: rawptr[list[rawptr[ast.AST]]] = cl.args
|
||||
if cargs is None or len(cargs) < 2:
|
||||
return None
|
||||
a_node: rawptr[ast.AST] = cargs.get(0)
|
||||
b_val: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
|
||||
b_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, cargs.get(1), None, 0, trans)
|
||||
if b_val is None:
|
||||
return None
|
||||
@@ -236,9 +236,9 @@ class CallGenCBuiltin(CallGenBase.CallGenBase):
|
||||
if d_call.func is not None and d_call.func.kind() == ast.ASTKind.Attribute:
|
||||
d_at: rawptr[ast.Attribute] = rawptr[ast.Attribute](d_call.func)
|
||||
if d_at.attr is not None and string.strcmp(d_at.attr, "Deref") == 0:
|
||||
d_args: list[rawptr[ast.AST]] | t.CPtr = d_call.args
|
||||
d_args: rawptr[list[rawptr[ast.AST]]] = d_call.args
|
||||
if d_args is not None and len(d_args) >= 1:
|
||||
ptr_val: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
|
||||
ptr_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, d_args.get(0), None, 0, trans)
|
||||
if ptr_val is not None:
|
||||
# 写入宽度以「左值指针自身的元素类型」为准:
|
||||
@@ -248,8 +248,8 @@ class CallGenCBuiltin(CallGenBase.CallGenBase):
|
||||
# c.Deref(uint32(p)) 被 0xFFFFFFFF(i64) 写成 8 字节(越界 4 字节)。
|
||||
# 无类型指针(元素为 i8,如 t.CPtr/i8* 形参)维持原行为:
|
||||
# 按 RHS 类型重解释指针 store(如 paging save_count 写 i32)。
|
||||
store_ptr: llvmlite.Value | t.CPtr = ptr_val
|
||||
store_val: llvmlite.Value | t.CPtr = b_val
|
||||
store_ptr: rawptr[llvmlite.Value] = ptr_val
|
||||
store_val: rawptr[llvmlite.Value] = b_val
|
||||
typed_elem: int = 0
|
||||
elem_ty: rawptr[llvmlite.LLVMType] = None
|
||||
if ptr_val.Ty is not None:
|
||||
@@ -269,7 +269,7 @@ class CallGenCBuiltin(CallGenBase.CallGenBase):
|
||||
builder, b_val, elem_ty, a_node)
|
||||
else:
|
||||
val_ptr_ty: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, b_val.Ty)
|
||||
casted_ptr: llvmlite.Value | t.CPtr = llvmlite.build_bitcast(
|
||||
casted_ptr: rawptr[llvmlite.Value] = llvmlite.build_bitcast(
|
||||
builder, ptr_val, val_ptr_ty)
|
||||
if casted_ptr is not None:
|
||||
store_ptr = casted_ptr
|
||||
@@ -284,36 +284,36 @@ class CallGenCBuiltin(CallGenBase.CallGenBase):
|
||||
nm_set: rawptr[ast.Name] = rawptr[ast.Name](a_node)
|
||||
if nm_set.id is not None:
|
||||
if GenApi.is_global_name(trans, nm_set.id) != 0:
|
||||
mod_alloca: llvmlite.Value | t.CPtr = self.Gen.VarGen.lookup_module_var(
|
||||
mod_alloca: rawptr[llvmlite.Value] = self.Gen.VarGen.lookup_module_var(
|
||||
trans.SymTab, nm_set.id)
|
||||
if mod_alloca is not None:
|
||||
tg_ty: rawptr[llvmlite.LLVMType] = None
|
||||
if mod_alloca.Ty is not None:
|
||||
tg_ty = mod_alloca.Ty.Pointee
|
||||
sv: llvmlite.Value | t.CPtr = b_val
|
||||
sv: rawptr[llvmlite.Value] = b_val
|
||||
if tg_ty is not None:
|
||||
sv = self.Gen.ExprGenBase.coerce_to_type(builder, b_val, tg_ty, a_node)
|
||||
llvmlite.build_store(builder, sv, mod_alloca)
|
||||
return b_val
|
||||
if GenApi.is_nonlocal_name(trans, nm_set.id) != 0:
|
||||
nl_ptr: llvmlite.Value | t.CPtr = self.Gen.StmtGenDecl.get_nonlocal_var_ptr(
|
||||
nl_ptr: rawptr[llvmlite.Value] = self.Gen.StmtGenDecl.get_nonlocal_var_ptr(
|
||||
trans, nm_set.id)
|
||||
if nl_ptr is not None:
|
||||
nl_ty: rawptr[llvmlite.LLVMType] = None
|
||||
if nl_ptr.Ty is not None:
|
||||
nl_ty = nl_ptr.Ty.Pointee
|
||||
sv2: llvmlite.Value | t.CPtr = b_val
|
||||
sv2: rawptr[llvmlite.Value] = b_val
|
||||
if nl_ty is not None:
|
||||
sv2 = self.Gen.ExprGenBase.coerce_to_type(builder, b_val, nl_ty, a_node)
|
||||
llvmlite.build_store(builder, sv2, nl_ptr)
|
||||
return b_val
|
||||
alloca: llvmlite.Value | t.CPtr = self.Gen.VarGen.get_or_create_sym(
|
||||
alloca: rawptr[llvmlite.Value] = self.Gen.VarGen.get_or_create_sym(
|
||||
trans.SymTab, pool, builder, nm_set.id, b_val.Ty)
|
||||
if alloca is not None:
|
||||
ac_ty: rawptr[llvmlite.LLVMType] = None
|
||||
if alloca.Ty is not None:
|
||||
ac_ty = alloca.Ty.Pointee
|
||||
sv3: llvmlite.Value | t.CPtr = b_val
|
||||
sv3: rawptr[llvmlite.Value] = b_val
|
||||
if ac_ty is not None:
|
||||
sv3 = self.Gen.ExprGenBase.coerce_to_type(builder, b_val, ac_ty, a_node)
|
||||
llvmlite.build_store(builder, sv3, alloca)
|
||||
@@ -322,13 +322,13 @@ class CallGenCBuiltin(CallGenBase.CallGenBase):
|
||||
|
||||
# 形态 3: Attribute 字段赋值
|
||||
if a_node is not None and a_node.kind() == ast.ASTKind.Attribute:
|
||||
field_ptr: llvmlite.Value | t.CPtr = self.Gen.ExprGenAttr.get_attribute_ptr(
|
||||
field_ptr: rawptr[llvmlite.Value] = self.Gen.ExprGenAttr.get_attribute_ptr(
|
||||
builder, pool, mod, a_node, trans)
|
||||
if field_ptr is not None:
|
||||
fd_ty: rawptr[llvmlite.LLVMType] = None
|
||||
if field_ptr.Ty is not None:
|
||||
fd_ty = field_ptr.Ty.Pointee
|
||||
sv4: llvmlite.Value | t.CPtr = b_val
|
||||
sv4: rawptr[llvmlite.Value] = b_val
|
||||
if fd_ty is not None:
|
||||
sv4 = self.Gen.ExprGenBase.coerce_to_type(builder, b_val, fd_ty, a_node)
|
||||
llvmlite.build_store(builder, sv4, field_ptr)
|
||||
@@ -338,14 +338,14 @@ class CallGenCBuiltin(CallGenBase.CallGenBase):
|
||||
|
||||
|
||||
def translate_c_addr(self, pool: rawptr[memhub.MemBuddy],
|
||||
builder: llvmlite.IRBuilder | t.CPtr,
|
||||
builder: rawptr[llvmlite.IRBuilder],
|
||||
mod: rawptr[llvmlite.LLVMModule],
|
||||
cl: rawptr[ast.Call],
|
||||
trans: rawptr[HT.Translator] = None) -> llvmlite.Value | t.CPtr:
|
||||
trans: rawptr[HT.Translator] = None) -> rawptr[llvmlite.Value]:
|
||||
"""c.Addr(var) → 返回变量的 alloca 指针(不 load)"""
|
||||
if cl is None:
|
||||
return None
|
||||
cargs: list[rawptr[ast.AST]] | t.CPtr = cl.args
|
||||
cargs: rawptr[list[rawptr[ast.AST]]] = cl.args
|
||||
if cargs is None or len(cargs) < 1:
|
||||
return None
|
||||
|
||||
@@ -362,7 +362,7 @@ class CallGenCBuiltin(CallGenBase.CallGenBase):
|
||||
# self/cls 对象引用:c.Addr(self) 返回对象指针本身(Ptr(Struct)),
|
||||
# 而非指针变量的地址(Ptr(Ptr(Struct)))。方法与 Attribute 分支
|
||||
if string.strcmp(nm.id, "self") == 0 or string.strcmp(nm.id, "cls") == 0:
|
||||
self_entry: GenTypes.VarEntry | t.CPtr = self.Gen.VarGen.lookup_var_entry(
|
||||
self_entry: rawptr[GenTypes.VarEntry] = self.Gen.VarGen.lookup_var_entry(
|
||||
trans.SymTab, nm.id)
|
||||
if self_entry is not None and self_entry.Alloca is not None and self_entry.Alloca.Ty is not None:
|
||||
match self_entry.Alloca.Ty:
|
||||
@@ -380,14 +380,14 @@ class CallGenCBuiltin(CallGenBase.CallGenBase):
|
||||
# 与普通局部 c.Addr(obj) 返回对象指针(load 一次)语义一致。
|
||||
if trans is not None:
|
||||
if GenApi.is_nonlocal_name(trans, nm.id) != 0:
|
||||
nl_addr: llvmlite.Value | t.CPtr = self.Gen.StmtGenDecl.load_nonlocal_var(
|
||||
nl_addr: rawptr[llvmlite.Value] = self.Gen.StmtGenDecl.load_nonlocal_var(
|
||||
trans, nm.id)
|
||||
if nl_addr is not None:
|
||||
return nl_addr
|
||||
return_var: llvmlite.Value | t.CPtr = self.Gen.VarGen.lookup_var(trans.SymTab, nm.id)
|
||||
return_var: rawptr[llvmlite.Value] = self.Gen.VarGen.lookup_var(trans.SymTab, nm.id)
|
||||
if return_var is None and mod is not None:
|
||||
# 模块全局变量 c.Addr(模块全局) → 返回全局变量指针:必须经 make_global_ref 转成带引号的 Ptr(Ty) 引用(直接返回 GlobalVariable 节点时其 Ty 是 pointee、Name 无 @ 引号,参与 ptrtoint 会渲染成 "ptrtoint void to i64")
|
||||
gv_ref_nm: llvmlite.GlobalVariable | t.CPtr = self.Gen.ExprGenAttr.find_global_in_module(mod, nm.id)
|
||||
gv_ref_nm: rawptr[llvmlite.GlobalVariable] = self.Gen.ExprGenAttr.find_global_in_module(mod, nm.id)
|
||||
if gv_ref_nm is not None and gv_ref_nm.Name is not None and gv_ref_nm.Ty is not None:
|
||||
return_var = self.Gen.ExprGenAttr.make_global_ref(pool, gv_ref_nm.Name, gv_ref_nm.Ty)
|
||||
# 模块函数地址:c.Addr(_on_int_complete) → 函数符号本身(@sha1.func)。
|
||||
@@ -400,9 +400,9 @@ class CallGenCBuiltin(CallGenBase.CallGenBase):
|
||||
if f_addr_ref is not None:
|
||||
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_head_ca: rawptr[llvmlite.Param] = llvmlite.function_get_param_head(f_addr_ref)
|
||||
p_cnt_ca: sizet = 0
|
||||
p_cur_ca: llvmlite.Param | t.CPtr = p_head_ca
|
||||
p_cur_ca: rawptr[llvmlite.Param] = p_head_ca
|
||||
while p_cur_ca is not None:
|
||||
p_cnt_ca += 1
|
||||
p_cur_ca = llvmlite.param_get_next(p_cur_ca)
|
||||
@@ -476,9 +476,9 @@ class CallGenCBuiltin(CallGenBase.CallGenBase):
|
||||
fname2: str = llvmlite.function_get_name(f_ref2)
|
||||
if fname2 is not None:
|
||||
# 构造带 @ 名的 SSAValue(Ptr(FuncTy)):直接返回 Function 节点会被 IRBuilder 格式化成 RetTy(void)→ "bitcast void to i8*"。Function 无 Ty 字段,用 RetTy+Params 重建函数类型;Params 是 GSList,必须经 function_get_param_head 取链表头(当 Param 直接遍历会读出垃圾参数类型)
|
||||
p_head2: llvmlite.Param | t.CPtr = llvmlite.function_get_param_head(f_ref2)
|
||||
p_head2: rawptr[llvmlite.Param] = llvmlite.function_get_param_head(f_ref2)
|
||||
p_cnt2: sizet = 0
|
||||
p_cur2: llvmlite.Param | t.CPtr = p_head2
|
||||
p_cur2: rawptr[llvmlite.Param] = p_head2
|
||||
while p_cur2 is not None:
|
||||
p_cnt2 += 1
|
||||
p_cur2 = llvmlite.param_get_next(p_cur2)
|
||||
@@ -498,12 +498,12 @@ class CallGenCBuiltin(CallGenBase.CallGenBase):
|
||||
pool, llvmlite.Ptr(pool, fn_ty2), faddr_buf2)
|
||||
else:
|
||||
# 模块限定全局 c.Addr(gdt.gp) → 全局符号本身(@gp):跨模块全局(含 CExport 裸名)已注入为 external global,经 make_global_ref 转成带引号的 Ptr(Ty) 引用(直接返回 GlobalVariable 节点会渲染 "ptrtoint void")
|
||||
g_ref2: llvmlite.GlobalVariable | t.CPtr = self.Gen.ExprGenAttr.find_global_in_module(
|
||||
g_ref2: rawptr[llvmlite.GlobalVariable] = self.Gen.ExprGenAttr.find_global_in_module(
|
||||
mod, at_addr.attr)
|
||||
if g_ref2 is not None and g_ref2.Name is not None and g_ref2.Ty is not None:
|
||||
return self.Gen.ExprGenAttr.make_global_ref(pool, g_ref2.Name, g_ref2.Ty)
|
||||
# 解析 base(Name 变量 / Subscript 数组元素)→ 对象指针
|
||||
obj_ptr: llvmlite.Value | t.CPtr = None
|
||||
obj_ptr: rawptr[llvmlite.Value] = None
|
||||
struct_ty: rawptr[llvmlite.LLVMType] = None
|
||||
if at_addr.value.kind() == ast.ASTKind.Subscript:
|
||||
# c.Addr(s.threads[0].rsp):base 是数组元素(Subscript)→ 先取
|
||||
@@ -514,9 +514,9 @@ class CallGenCBuiltin(CallGenBase.CallGenBase):
|
||||
sub_base: rawptr[ast.Subscript] = rawptr[ast.Subscript](at_addr.value)
|
||||
if sub_base.value is None or sub_base.slice is None:
|
||||
return None
|
||||
bval: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
|
||||
bval: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, sub_base.value, None, 0, trans)
|
||||
bidx: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
|
||||
bidx: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, sub_base.slice, None, 0, trans)
|
||||
if bval is None or bidx is None or bval.Ty is None:
|
||||
return None
|
||||
@@ -537,7 +537,7 @@ class CallGenCBuiltin(CallGenBase.CallGenBase):
|
||||
self_nm: rawptr[ast.Name] = rawptr[ast.Name](at_addr.value)
|
||||
if self_nm.id is None:
|
||||
return None
|
||||
self_alloca: llvmlite.Value | t.CPtr = self.Gen.VarGen.lookup_var(
|
||||
self_alloca: rawptr[llvmlite.Value] = self.Gen.VarGen.lookup_var(
|
||||
trans.SymTab, self_nm.id)
|
||||
if self_alloca is None or self_alloca.Ty is None:
|
||||
return None
|
||||
@@ -563,7 +563,7 @@ class CallGenCBuiltin(CallGenBase.CallGenBase):
|
||||
if obj_ptr is None or struct_ty is None:
|
||||
return None
|
||||
# 查找字段
|
||||
fe_addr: GenTypes.FieldEntry | t.CPtr = self.Gen.StructGen.lookup_field(
|
||||
fe_addr: rawptr[GenTypes.FieldEntry] = self.Gen.StructGen.lookup_field(
|
||||
struct_ty, at_addr.attr)
|
||||
if fe_addr is None:
|
||||
return None
|
||||
@@ -580,7 +580,7 @@ class CallGenCBuiltin(CallGenBase.CallGenBase):
|
||||
if arg0.kind() == ast.ASTKind.Subscript:
|
||||
if trans is None:
|
||||
return None
|
||||
elem_ptr_ca: llvmlite.Value | t.CPtr = self.Gen.ExprGenName.get_subscript_ptr(
|
||||
elem_ptr_ca: rawptr[llvmlite.Value] = self.Gen.ExprGenName.get_subscript_ptr(
|
||||
builder, pool, mod, arg0, trans)
|
||||
if elem_ptr_ca is not None:
|
||||
return elem_ptr_ca
|
||||
@@ -588,11 +588,11 @@ class CallGenCBuiltin(CallGenBase.CallGenBase):
|
||||
sub_addr: rawptr[ast.Subscript] = rawptr[ast.Subscript](arg0)
|
||||
if sub_addr is None or sub_addr.value is None or sub_addr.slice is None:
|
||||
return None
|
||||
arr_val: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
|
||||
arr_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, sub_addr.value, None, 0, trans)
|
||||
if arr_val is None or arr_val.Ty is None:
|
||||
return None
|
||||
idx_val: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
|
||||
idx_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, sub_addr.slice, None, 0, trans)
|
||||
if idx_val is None:
|
||||
return None
|
||||
@@ -617,11 +617,11 @@ class CallGenCBuiltin(CallGenBase.CallGenBase):
|
||||
# 供就地解读使用:tt: Coroutine = c.Addr(task()) —— coerce 指针→结构体时
|
||||
# 从槽地址 load(target 是 NoVTable 结构体,如 Coroutine={__ptr__} 8 字节)。
|
||||
if arg0.kind() == ast.ASTKind.Call:
|
||||
call_val: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
|
||||
call_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, arg0, None, 0, trans)
|
||||
if call_val is None or call_val.Ty is None:
|
||||
return None
|
||||
tmp_slot: llvmlite.Value | t.CPtr = llvmlite.build_alloca_at_entry(
|
||||
tmp_slot: rawptr[llvmlite.Value] = llvmlite.build_alloca_at_entry(
|
||||
builder, call_val.Ty)
|
||||
if tmp_slot is None:
|
||||
return None
|
||||
@@ -639,20 +639,20 @@ class CallGenCBuiltin(CallGenBase.CallGenBase):
|
||||
|
||||
|
||||
def translate_c_load(self, pool: rawptr[memhub.MemBuddy],
|
||||
builder: llvmlite.IRBuilder | t.CPtr,
|
||||
builder: rawptr[llvmlite.IRBuilder],
|
||||
mod: rawptr[llvmlite.LLVMModule],
|
||||
cl: rawptr[ast.Call],
|
||||
trans: rawptr[HT.Translator] = None) -> llvmlite.Value | t.CPtr:
|
||||
trans: rawptr[HT.Translator] = None) -> rawptr[llvmlite.Value]:
|
||||
"""c.Load(a, b) → *a = *b(加载 b 的值,存储到 a)"""
|
||||
if cl is None:
|
||||
return None
|
||||
cargs: list[rawptr[ast.AST]] | t.CPtr = cl.args
|
||||
cargs: rawptr[list[rawptr[ast.AST]]] = cl.args
|
||||
if cargs is None or len(cargs) < 2:
|
||||
return None
|
||||
|
||||
dst_ptr: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
|
||||
dst_ptr: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, cargs.get(0), None, 0, trans)
|
||||
src_ptr: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
|
||||
src_ptr: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, cargs.get(1), None, 0, trans)
|
||||
if dst_ptr is None or src_ptr is None:
|
||||
return None
|
||||
@@ -668,15 +668,15 @@ class CallGenCBuiltin(CallGenBase.CallGenBase):
|
||||
|
||||
# bitcast src 到 pointee* 并 load
|
||||
target_ptr_ty: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, pointee)
|
||||
src_cast: llvmlite.Value | t.CPtr = llvmlite.build_bitcast(builder, src_ptr, target_ptr_ty)
|
||||
src_cast: rawptr[llvmlite.Value] = llvmlite.build_bitcast(builder, src_ptr, target_ptr_ty)
|
||||
if src_cast is None:
|
||||
return None
|
||||
loaded: llvmlite.Value | t.CPtr = llvmlite.build_load(builder, pointee, src_cast)
|
||||
loaded: rawptr[llvmlite.Value] = llvmlite.build_load(builder, pointee, src_cast)
|
||||
if loaded is None:
|
||||
return None
|
||||
|
||||
# bitcast dst 到 pointee* 并 store
|
||||
dst_cast: llvmlite.Value | t.CPtr = llvmlite.build_bitcast(builder, dst_ptr, target_ptr_ty)
|
||||
dst_cast: rawptr[llvmlite.Value] = llvmlite.build_bitcast(builder, dst_ptr, target_ptr_ty)
|
||||
if dst_cast is None:
|
||||
return None
|
||||
llvmlite.build_store(builder, loaded, dst_cast)
|
||||
@@ -725,7 +725,7 @@ class CallGenCBuiltin(CallGenBase.CallGenBase):
|
||||
i: sizet = 0
|
||||
while i < src_len:
|
||||
matched: int = 0
|
||||
cur: llvmlite.GlobalVariable | t.CPtr = mod.GlobalHead
|
||||
cur: rawptr[llvmlite.GlobalVariable] = mod.GlobalHead
|
||||
while cur is not None:
|
||||
gname: str = cur.Name
|
||||
if gname is not None and string.strchr(gname, 46) is not None:
|
||||
@@ -961,12 +961,12 @@ class CallGenCBuiltin(CallGenBase.CallGenBase):
|
||||
return ""
|
||||
|
||||
|
||||
def _asm_get_operand(self, base: GenTypes.AsmOperand | t.CPtr,
|
||||
idx: int) -> GenTypes.AsmOperand | t.CPtr:
|
||||
def _asm_get_operand(self, base: rawptr[GenTypes.AsmOperand],
|
||||
idx: int) -> rawptr[GenTypes.AsmOperand]:
|
||||
"""获取操作数数组中第 idx 个元素的指针"""
|
||||
entry_size: sizet = GenTypes.AsmOperand.__sizeof__()
|
||||
entry_addr: uint64 = uint64(base) + idx * entry_size
|
||||
return (GenTypes.AsmOperand | t.CPtr)(entry_addr)
|
||||
return rawptr[GenTypes.AsmOperand](entry_addr)
|
||||
|
||||
|
||||
def _asm_is_c_call(self, node: rawptr[ast.Call]) -> str:
|
||||
@@ -1006,9 +1006,9 @@ class CallGenCBuiltin(CallGenBase.CallGenBase):
|
||||
return 0
|
||||
|
||||
|
||||
def _asm_add_operand(self, operands: GenTypes.AsmOperand | t.CPtr,
|
||||
def _asm_add_operand(self, operands: rawptr[GenTypes.AsmOperand],
|
||||
count: int,
|
||||
val: llvmlite.Value | t.CPtr,
|
||||
val: rawptr[llvmlite.Value],
|
||||
constraint: str,
|
||||
is_output: int) -> int:
|
||||
"""添加操作数到数组,返回新计数(失败返回原计数)
|
||||
@@ -1032,10 +1032,10 @@ class CallGenCBuiltin(CallGenBase.CallGenBase):
|
||||
"TypeError")
|
||||
if val is not None:
|
||||
for ei in range(count):
|
||||
eop: GenTypes.AsmOperand | t.CPtr = self._asm_get_operand(operands, ei)
|
||||
eop: rawptr[GenTypes.AsmOperand] = self._asm_get_operand(operands, ei)
|
||||
if eop is not None and eop.Value == val and eop.IsOutput == is_output:
|
||||
return count
|
||||
op: GenTypes.AsmOperand | t.CPtr = self._asm_get_operand(operands, count)
|
||||
op: rawptr[GenTypes.AsmOperand] = self._asm_get_operand(operands, count)
|
||||
op.Value = val
|
||||
# 缺省约束:AsmInp(reg) 只传 1 参无 descr → 约束空 → llc
|
||||
# "number of input constraints does not match number of parameters"
|
||||
@@ -1053,21 +1053,21 @@ class CallGenCBuiltin(CallGenBase.CallGenBase):
|
||||
|
||||
|
||||
def translate_c_asm(self, pool: rawptr[memhub.MemBuddy],
|
||||
builder: llvmlite.IRBuilder | t.CPtr,
|
||||
builder: rawptr[llvmlite.IRBuilder],
|
||||
mod: rawptr[llvmlite.LLVMModule],
|
||||
cl: rawptr[ast.Call],
|
||||
trans: rawptr[HT.Translator] = None) -> llvmlite.Value | t.CPtr:
|
||||
trans: rawptr[HT.Translator] = None) -> rawptr[llvmlite.Value]:
|
||||
"""翻译 c.Asm 内联汇编,返回结果 Value(无输出时返回 None)"""
|
||||
if cl is None:
|
||||
return None
|
||||
|
||||
cargs: list[rawptr[ast.AST]] | t.CPtr = cl.args
|
||||
cargs: rawptr[list[rawptr[ast.AST]]] = cl.args
|
||||
if cargs is None or len(cargs) < 1:
|
||||
return None
|
||||
|
||||
# 分配操作数数组
|
||||
operand_size: sizet = GenTypes.AsmOperand.__sizeof__()
|
||||
operands: GenTypes.AsmOperand | t.CPtr = pool.alloc(operand_size * ASM_MAX_OPERANDS)
|
||||
operands: rawptr[GenTypes.AsmOperand] = pool.alloc(operand_size * ASM_MAX_OPERANDS)
|
||||
if operands is None:
|
||||
return None
|
||||
string.memset(operands, 0, operand_size * ASM_MAX_OPERANDS)
|
||||
@@ -1116,8 +1116,8 @@ class CallGenCBuiltin(CallGenBase.CallGenBase):
|
||||
tk: int = tmpl_node.kind()
|
||||
|
||||
if tk == ast.ASTKind.JoinedStr:
|
||||
js: ast.JoinedStr | t.CPtr = (ast.JoinedStr | t.CPtr)(tmpl_node)
|
||||
jvalues: list[rawptr[ast.AST]] | t.CPtr = js.values
|
||||
js: rawptr[ast.JoinedStr] = rawptr[ast.JoinedStr](tmpl_node)
|
||||
jvalues: rawptr[list[rawptr[ast.AST]]] = js.values
|
||||
if jvalues is not None:
|
||||
jvlen: sizet = len(jvalues)
|
||||
for vi in range(jvlen):
|
||||
@@ -1127,7 +1127,7 @@ class CallGenCBuiltin(CallGenBase.CallGenBase):
|
||||
pk: int = part.kind()
|
||||
|
||||
if pk == ast.ASTKind.FormattedValue:
|
||||
fv: ast.FormattedValue | t.CPtr = (ast.FormattedValue | t.CPtr)(part)
|
||||
fv: rawptr[ast.FormattedValue] = rawptr[ast.FormattedValue](part)
|
||||
fexpr: rawptr[ast.AST] = fv.value
|
||||
if fexpr is None or fexpr.kind() != ast.ASTKind.Call:
|
||||
continue
|
||||
@@ -1144,7 +1144,7 @@ class CallGenCBuiltin(CallGenBase.CallGenBase):
|
||||
else:
|
||||
continue
|
||||
|
||||
fargs: list[rawptr[ast.AST]] | t.CPtr = fcall.args
|
||||
fargs: rawptr[list[rawptr[ast.AST]]] = fcall.args
|
||||
if fargs is None or len(fargs) < 1:
|
||||
continue
|
||||
|
||||
@@ -1158,7 +1158,7 @@ class CallGenCBuiltin(CallGenBase.CallGenBase):
|
||||
# Attribute 字段地址)
|
||||
if val_node is None:
|
||||
continue
|
||||
alloca: llvmlite.Value | t.CPtr = None
|
||||
alloca: rawptr[llvmlite.Value] = None
|
||||
if val_node.kind() == ast.ASTKind.Name:
|
||||
nm: rawptr[ast.Name] = rawptr[ast.Name](val_node)
|
||||
if nm.id is None:
|
||||
@@ -1182,7 +1182,7 @@ class CallGenCBuiltin(CallGenBase.CallGenBase):
|
||||
and at_a.value.kind() == ast.ASTKind.Name:
|
||||
base_nm_a: rawptr[ast.Name] = rawptr[ast.Name](at_a.value)
|
||||
if base_nm_a.id is not None:
|
||||
base_alloca_a: llvmlite.Value | t.CPtr = self.Gen.VarGen.lookup_var(
|
||||
base_alloca_a: rawptr[llvmlite.Value] = self.Gen.VarGen.lookup_var(
|
||||
trans.SymTab, base_nm_a.id)
|
||||
if base_alloca_a is not None and base_alloca_a.Ty is not None:
|
||||
struct_ty_a: rawptr[llvmlite.LLVMType] = None
|
||||
@@ -1198,10 +1198,10 @@ class CallGenCBuiltin(CallGenBase.CallGenBase):
|
||||
case _:
|
||||
pass
|
||||
if struct_ty_a is not None:
|
||||
fe_a: GenTypes.FieldEntry | t.CPtr = self.Gen.StructGen.lookup_field(
|
||||
fe_a: rawptr[GenTypes.FieldEntry] = self.Gen.StructGen.lookup_field(
|
||||
struct_ty_a, at_a.attr)
|
||||
if fe_a is not None:
|
||||
obj_ptr_a: llvmlite.Value | t.CPtr = base_alloca_a
|
||||
obj_ptr_a: rawptr[llvmlite.Value] = base_alloca_a
|
||||
if self_is_ptr_ptr_a == 1:
|
||||
obj_ptr_a = llvmlite.build_load(
|
||||
builder, llvmlite.Ptr(pool, struct_ty_a), base_alloca_a)
|
||||
@@ -1222,7 +1222,7 @@ class CallGenCBuiltin(CallGenBase.CallGenBase):
|
||||
out_pty_n += 1
|
||||
else:
|
||||
# 输入:翻译值
|
||||
ival: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
|
||||
ival: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, val_node, None, 0, trans)
|
||||
if ival is None:
|
||||
continue
|
||||
@@ -1237,11 +1237,11 @@ class CallGenCBuiltin(CallGenBase.CallGenBase):
|
||||
# ============================================================
|
||||
# 2. 解析关键字参数 out=/inp=/op=/clobber=
|
||||
# ============================================================
|
||||
keywords: list[rawptr[ast.AST]] | t.CPtr = cl.keywords
|
||||
keywords: rawptr[list[rawptr[ast.AST]]] = cl.keywords
|
||||
if keywords is not None:
|
||||
kwlen: sizet = len(keywords)
|
||||
for ki in range(kwlen):
|
||||
kw: ast.Keyword | t.CPtr = (ast.Keyword | t.CPtr)(keywords.get(ki))
|
||||
kw: rawptr[ast.Keyword] = rawptr[ast.Keyword](keywords.get(ki))
|
||||
if kw is None or kw.arg is None or kw.value is None:
|
||||
continue
|
||||
kwk: int = kw.value.kind()
|
||||
@@ -1250,8 +1250,8 @@ class CallGenCBuiltin(CallGenBase.CallGenBase):
|
||||
# 输出操作数列表
|
||||
if kwk != ast.ASTKind.List:
|
||||
continue
|
||||
out_lst: ast.List | t.CPtr = (ast.List | t.CPtr)(kw.value)
|
||||
out_elts: list[rawptr[ast.AST]] | t.CPtr = out_lst.elts
|
||||
out_lst: rawptr[ast.List] = rawptr[ast.List](kw.value)
|
||||
out_elts: rawptr[list[rawptr[ast.AST]]] = out_lst.elts
|
||||
if out_elts is None:
|
||||
continue
|
||||
oelen: sizet = len(out_elts)
|
||||
@@ -1263,7 +1263,7 @@ class CallGenCBuiltin(CallGenBase.CallGenBase):
|
||||
oattr: str = self._asm_is_c_call(ocall)
|
||||
if oattr is None or string.strcmp(oattr, "AsmOut") != 0:
|
||||
continue
|
||||
oargs: list[rawptr[ast.AST]] | t.CPtr = ocall.args
|
||||
oargs: rawptr[list[rawptr[ast.AST]]] = ocall.args
|
||||
if oargs is None or len(oargs) < 1:
|
||||
continue
|
||||
oval_node: rawptr[ast.AST] = oargs.get(0)
|
||||
@@ -1275,7 +1275,7 @@ class CallGenCBuiltin(CallGenBase.CallGenBase):
|
||||
onm: rawptr[ast.Name] = rawptr[ast.Name](oval_node)
|
||||
if onm.id is None:
|
||||
continue
|
||||
oalloca: llvmlite.Value | t.CPtr = self.Gen.VarGen.lookup_var(trans.SymTab, onm.id)
|
||||
oalloca: rawptr[llvmlite.Value] = self.Gen.VarGen.lookup_var(trans.SymTab, onm.id)
|
||||
if oalloca is None:
|
||||
continue
|
||||
operand_count = self._asm_add_operand(
|
||||
@@ -1293,8 +1293,8 @@ class CallGenCBuiltin(CallGenBase.CallGenBase):
|
||||
# 输入操作数列表
|
||||
if kwk != ast.ASTKind.List:
|
||||
continue
|
||||
in_lst: ast.List | t.CPtr = (ast.List | t.CPtr)(kw.value)
|
||||
in_elts: list[rawptr[ast.AST]] | t.CPtr = in_lst.elts
|
||||
in_lst: rawptr[ast.List] = rawptr[ast.List](kw.value)
|
||||
in_elts: rawptr[list[rawptr[ast.AST]]] = in_lst.elts
|
||||
if in_elts is None:
|
||||
continue
|
||||
ielen: sizet = len(in_elts)
|
||||
@@ -1306,14 +1306,14 @@ class CallGenCBuiltin(CallGenBase.CallGenBase):
|
||||
iattr: str = self._asm_is_c_call(icall)
|
||||
if iattr is None or string.strcmp(iattr, "AsmInp") != 0:
|
||||
continue
|
||||
iargs: list[rawptr[ast.AST]] | t.CPtr = icall.args
|
||||
iargs: rawptr[list[rawptr[ast.AST]]] = icall.args
|
||||
if iargs is None or len(iargs) < 1:
|
||||
continue
|
||||
ival_node: rawptr[ast.AST] = iargs.get(0)
|
||||
icons: str = ""
|
||||
if len(iargs) >= 2:
|
||||
icons = self._resolve_asm_descr(pool, iargs.get(1))
|
||||
ival2: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
|
||||
ival2: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, ival_node, None, 0, trans)
|
||||
if ival2 is None:
|
||||
continue
|
||||
@@ -1324,8 +1324,8 @@ class CallGenCBuiltin(CallGenBase.CallGenBase):
|
||||
# 破坏列表
|
||||
if kwk != ast.ASTKind.List:
|
||||
continue
|
||||
cl_lst: ast.List | t.CPtr = (ast.List | t.CPtr)(kw.value)
|
||||
cl_elts: list[rawptr[ast.AST]] | t.CPtr = cl_lst.elts
|
||||
cl_lst: rawptr[ast.List] = rawptr[ast.List](kw.value)
|
||||
cl_elts: rawptr[list[rawptr[ast.AST]]] = cl_lst.elts
|
||||
if cl_elts is None:
|
||||
continue
|
||||
clen: sizet = len(cl_elts)
|
||||
@@ -1348,8 +1348,8 @@ class CallGenCBuiltin(CallGenBase.CallGenBase):
|
||||
if len(cargs) >= 2:
|
||||
pos_node: rawptr[ast.AST] = cargs.get(1)
|
||||
if pos_node is not None and pos_node.kind() == ast.ASTKind.List:
|
||||
pos_lst: ast.List | t.CPtr = (ast.List | t.CPtr)(pos_node)
|
||||
pos_elts: list[rawptr[ast.AST]] | t.CPtr = pos_lst.elts
|
||||
pos_lst: rawptr[ast.List] = rawptr[ast.List](pos_node)
|
||||
pos_elts: rawptr[list[rawptr[ast.AST]]] = pos_lst.elts
|
||||
if pos_elts is not None:
|
||||
plen: sizet = len(pos_elts)
|
||||
for pi in range(plen):
|
||||
@@ -1372,7 +1372,7 @@ class CallGenCBuiltin(CallGenBase.CallGenBase):
|
||||
input_count: int = 0
|
||||
first_output_idx: int = -1
|
||||
for oi2 in range(operand_count):
|
||||
op2: GenTypes.AsmOperand | t.CPtr = self._asm_get_operand(operands, oi2)
|
||||
op2: rawptr[GenTypes.AsmOperand] = self._asm_get_operand(operands, oi2)
|
||||
if op2.IsOutput != 0:
|
||||
if first_output_idx < 0:
|
||||
first_output_idx = oi2
|
||||
@@ -1392,7 +1392,7 @@ class CallGenCBuiltin(CallGenBase.CallGenBase):
|
||||
out_pn_n: int = 0
|
||||
out_seq: int = 0
|
||||
for oi5 in range(operand_count):
|
||||
op5: GenTypes.AsmOperand | t.CPtr = self._asm_get_operand(operands, oi5)
|
||||
op5: rawptr[GenTypes.AsmOperand] = self._asm_get_operand(operands, oi5)
|
||||
if op5 is None or op5.IsOutput == 0:
|
||||
continue
|
||||
pty5: rawptr[llvmlite.LLVMType] = None
|
||||
@@ -1420,7 +1420,7 @@ class CallGenCBuiltin(CallGenBase.CallGenBase):
|
||||
cl, "c.Asm 输出操作数类型缺失(变量 alloca 类型退化)", "TypeError")
|
||||
ret_ty = llvmlite.Int32(pool)
|
||||
else:
|
||||
out_op: GenTypes.AsmOperand | t.CPtr = self._asm_get_operand(operands, first_output_idx)
|
||||
out_op: rawptr[GenTypes.AsmOperand] = self._asm_get_operand(operands, first_output_idx)
|
||||
out_pt: rawptr[llvmlite.LLVMType] = None
|
||||
# 优先用收集时缓存的元素类型(对齐 python 参考),再回退从槽读回
|
||||
if out_ret_ty_first is not None:
|
||||
@@ -1450,7 +1450,7 @@ class CallGenCBuiltin(CallGenBase.CallGenBase):
|
||||
case llvmlite.LLVMType.Void():
|
||||
ret_re: rawptr[llvmlite.LLVMType] = None
|
||||
for re_i in range(operand_count):
|
||||
re_op: GenTypes.AsmOperand | t.CPtr = self._asm_get_operand(
|
||||
re_op: rawptr[GenTypes.AsmOperand] = self._asm_get_operand(
|
||||
operands, re_i)
|
||||
if re_op is None or re_op.IsOutput == 0:
|
||||
continue
|
||||
@@ -1479,13 +1479,13 @@ class CallGenCBuiltin(CallGenBase.CallGenBase):
|
||||
new_idx: int = 0
|
||||
# 先放输出
|
||||
for oi3 in range(operand_count):
|
||||
op3: GenTypes.AsmOperand | t.CPtr = self._asm_get_operand(operands, oi3)
|
||||
op3: rawptr[GenTypes.AsmOperand] = self._asm_get_operand(operands, oi3)
|
||||
if op3.IsOutput != 0:
|
||||
new_order[new_idx] = oi3
|
||||
new_idx += 1
|
||||
# 再放输入
|
||||
for oi4 in range(operand_count):
|
||||
op4: GenTypes.AsmOperand | t.CPtr = self._asm_get_operand(operands, oi4)
|
||||
op4: rawptr[GenTypes.AsmOperand] = self._asm_get_operand(operands, oi4)
|
||||
if op4.IsOutput == 0:
|
||||
new_order[new_idx] = oi4
|
||||
new_idx += 1
|
||||
@@ -1500,8 +1500,8 @@ class CallGenCBuiltin(CallGenBase.CallGenBase):
|
||||
if tmpl_node is not None:
|
||||
tk2: int = tmpl_node.kind()
|
||||
if tk2 == ast.ASTKind.JoinedStr:
|
||||
js2: ast.JoinedStr | t.CPtr = (ast.JoinedStr | t.CPtr)(tmpl_node)
|
||||
jvalues2: list[rawptr[ast.AST]] | t.CPtr = js2.values
|
||||
js2: rawptr[ast.JoinedStr] = rawptr[ast.JoinedStr](tmpl_node)
|
||||
jvalues2: rawptr[list[rawptr[ast.AST]]] = js2.values
|
||||
if jvalues2 is not None:
|
||||
jvlen2: sizet = len(jvalues2)
|
||||
fv_fi: int = 0
|
||||
@@ -1539,7 +1539,7 @@ class CallGenCBuiltin(CallGenBase.CallGenBase):
|
||||
first_const: int = 1
|
||||
for ci2 in range(operand_count):
|
||||
orig_i: int = new_order[ci2]
|
||||
cop: GenTypes.AsmOperand | t.CPtr = self._asm_get_operand(operands, orig_i)
|
||||
cop: rawptr[GenTypes.AsmOperand] = self._asm_get_operand(operands, orig_i)
|
||||
cons_val: str = cop.Constraint
|
||||
if cons_val is None:
|
||||
cons_val = "r"
|
||||
@@ -1580,10 +1580,10 @@ class CallGenCBuiltin(CallGenBase.CallGenBase):
|
||||
first_arg: int = 1
|
||||
for ai3 in range(operand_count):
|
||||
orig_i2: int = new_order[ai3]
|
||||
aop: GenTypes.AsmOperand | t.CPtr = self._asm_get_operand(operands, orig_i2)
|
||||
aop: rawptr[GenTypes.AsmOperand] = self._asm_get_operand(operands, orig_i2)
|
||||
if aop.IsOutput != 0:
|
||||
continue
|
||||
aval: llvmlite.Value | t.CPtr = aop.Value
|
||||
aval: rawptr[llvmlite.Value] = aop.Value
|
||||
if aval is None or aval.Ty is None or aval.Name is None:
|
||||
continue
|
||||
|
||||
@@ -1648,11 +1648,11 @@ class CallGenCBuiltin(CallGenBase.CallGenBase):
|
||||
# 9. 处理输出:存储结果到输出变量
|
||||
# ============================================================
|
||||
if is_void == 0 and first_output_idx >= 0:
|
||||
result_val: llvmlite.Value | t.CPtr = llvmlite.SSAValue(pool, ret_ty, ssa_name)
|
||||
result_val: rawptr[llvmlite.Value] = llvmlite.SSAValue(pool, ret_ty, ssa_name)
|
||||
out_emit_idx: int = 0
|
||||
for oi_out in range(operand_count):
|
||||
orig_o: int = new_order[oi_out]
|
||||
oo: GenTypes.AsmOperand | t.CPtr = self._asm_get_operand(operands, orig_o)
|
||||
oo: rawptr[GenTypes.AsmOperand] = self._asm_get_operand(operands, orig_o)
|
||||
if oo is None or oo.IsOutput == 0:
|
||||
continue
|
||||
if output_count > 1:
|
||||
@@ -1670,7 +1670,7 @@ class CallGenCBuiltin(CallGenBase.CallGenBase):
|
||||
"%s = extractvalue %s %s, %d",
|
||||
ev_name, ret_ty_buf, ssa_name, out_emit_idx)
|
||||
llvmlite.block_append_text(pool, builder.CurBlock, ev_line)
|
||||
ev_val: llvmlite.Value | t.CPtr = llvmlite.SSAValue(
|
||||
ev_val: rawptr[llvmlite.Value] = llvmlite.SSAValue(
|
||||
pool, oo.Value.Ty.Pointee, ev_name)
|
||||
llvmlite.build_store(builder, ev_val, oo.Value)
|
||||
else:
|
||||
@@ -1683,10 +1683,10 @@ class CallGenCBuiltin(CallGenBase.CallGenBase):
|
||||
|
||||
|
||||
def translate_c_llvmir(self, pool: rawptr[memhub.MemBuddy],
|
||||
builder: llvmlite.IRBuilder | t.CPtr,
|
||||
builder: rawptr[llvmlite.IRBuilder],
|
||||
mod: rawptr[llvmlite.LLVMModule],
|
||||
cl: rawptr[ast.Call],
|
||||
trans: rawptr[HT.Translator] = None) -> llvmlite.Value | t.CPtr:
|
||||
trans: rawptr[HT.Translator] = None) -> rawptr[llvmlite.Value]:
|
||||
"""c.LLVMIR 内联 LLVM IR:无返回值,直接嵌入原始 IR 文本
|
||||
|
||||
不做指令解析,模板文本(c.LInp/c.LOut 替换后)用 block_append_text
|
||||
@@ -1696,7 +1696,7 @@ class CallGenCBuiltin(CallGenBase.CallGenBase):
|
||||
if cl is None or builder is None or pool is None or trans is None:
|
||||
return None
|
||||
|
||||
cargs: list[rawptr[ast.AST]] | t.CPtr = cl.args
|
||||
cargs: rawptr[list[rawptr[ast.AST]]] = cl.args
|
||||
if cargs is None or len(cargs) < 1:
|
||||
self.Gen.TypeGenErr.fatal_error(cl, "c.LLVMIR 缺少模板参数", "TypeError")
|
||||
|
||||
@@ -1725,8 +1725,8 @@ class CallGenCBuiltin(CallGenBase.CallGenBase):
|
||||
tk: int = first_arg.kind()
|
||||
|
||||
if tk == ast.ASTKind.JoinedStr:
|
||||
js: ast.JoinedStr | t.CPtr = (ast.JoinedStr | t.CPtr)(first_arg)
|
||||
jvalues: list[rawptr[ast.AST]] | t.CPtr = js.values
|
||||
js: rawptr[ast.JoinedStr] = rawptr[ast.JoinedStr](first_arg)
|
||||
jvalues: rawptr[list[rawptr[ast.AST]]] = js.values
|
||||
if jvalues is not None:
|
||||
jvlen: sizet = len(jvalues)
|
||||
for vi in range(jvlen):
|
||||
@@ -1742,7 +1742,7 @@ class CallGenCBuiltin(CallGenBase.CallGenBase):
|
||||
self._asm_append_cstr(text, LLVMIR_TEMPLATE_BUF, cn.str_val)
|
||||
|
||||
elif pk == ast.ASTKind.FormattedValue:
|
||||
fv: ast.FormattedValue | t.CPtr = (ast.FormattedValue | t.CPtr)(part)
|
||||
fv: rawptr[ast.FormattedValue] = rawptr[ast.FormattedValue](part)
|
||||
fexpr: rawptr[ast.AST] = fv.value
|
||||
if fexpr is None:
|
||||
continue
|
||||
@@ -1751,14 +1751,14 @@ class CallGenCBuiltin(CallGenBase.CallGenBase):
|
||||
fcall: rawptr[ast.Call] = rawptr[ast.Call](fexpr)
|
||||
attr_nm: str = self._asm_is_c_call(fcall)
|
||||
if attr_nm is not None:
|
||||
fargs: list[rawptr[ast.AST]] | t.CPtr = fcall.args
|
||||
fargs: rawptr[list[rawptr[ast.AST]]] = fcall.args
|
||||
if fargs is None or len(fargs) < 1:
|
||||
continue
|
||||
val_node: rawptr[ast.AST] = fargs.get(0)
|
||||
|
||||
if string.strcmp(attr_nm, "LInp") == 0:
|
||||
# 输入操作数:翻译值,替换为 LLVM 值引用文本(%x 或常量文本)
|
||||
inp_val: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
|
||||
inp_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, val_node, None, 0, trans)
|
||||
if inp_val is not None and inp_val.Name is not None:
|
||||
self._asm_append_cstr(text, LLVMIR_TEMPLATE_BUF, inp_val.Name)
|
||||
@@ -1769,7 +1769,7 @@ class CallGenCBuiltin(CallGenBase.CallGenBase):
|
||||
if val_node is not None and val_node.kind() == ast.ASTKind.Name:
|
||||
nm: rawptr[ast.Name] = rawptr[ast.Name](val_node)
|
||||
if nm.id is not None:
|
||||
alloca: llvmlite.Value | t.CPtr = self.Gen.VarGen.lookup_var(
|
||||
alloca: rawptr[llvmlite.Value] = self.Gen.VarGen.lookup_var(
|
||||
trans.SymTab, nm.id)
|
||||
if alloca is None or out_count >= LLVMIR_MAX_OPS:
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
@@ -1786,7 +1786,7 @@ class CallGenCBuiltin(CallGenBase.CallGenBase):
|
||||
out_count += 1
|
||||
continue
|
||||
# 非 c.LInp/c.LOut 的 f-string 表达式:翻译值并嵌入值文本
|
||||
ival: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
|
||||
ival: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, fexpr, None, 0, trans)
|
||||
if ival is not None and ival.Name is not None:
|
||||
self._asm_append_cstr(text, LLVMIR_TEMPLATE_BUF, ival.Name)
|
||||
@@ -1806,11 +1806,11 @@ class CallGenCBuiltin(CallGenBase.CallGenBase):
|
||||
# LOut 写回: store <ty> %llvmirN, <ty>* %var
|
||||
oi: int
|
||||
for oi in range(out_count):
|
||||
oa: llvmlite.Value | t.CPtr = (llvmlite.Value | t.CPtr)(out_alloca[oi])
|
||||
oa: rawptr[llvmlite.Value] = rawptr[llvmlite.Value](out_alloca[oi])
|
||||
rn: str = str(out_regname[oi])
|
||||
if oa is None or oa.Ty is None or oa.Ty.Pointee is None or rn is None:
|
||||
continue
|
||||
reg_val: llvmlite.Value | t.CPtr = llvmlite.new_value(pool)
|
||||
reg_val: rawptr[llvmlite.Value] = llvmlite.new_value(pool)
|
||||
if reg_val is None:
|
||||
continue
|
||||
reg_val.Ty = oa.Ty.Pointee
|
||||
|
||||
@@ -40,16 +40,16 @@ class CallGenCall(CallGenBase.CallGenBase):
|
||||
|
||||
# ============================================================
|
||||
def _do_virtual_call(self, pool: rawptr[memhub.MemBuddy],
|
||||
builder: llvmlite.IRBuilder | t.CPtr,
|
||||
builder: rawptr[llvmlite.IRBuilder],
|
||||
mod: rawptr[llvmlite.LLVMModule],
|
||||
class_name: str,
|
||||
method_name: str,
|
||||
self_ptr: llvmlite.Value | t.CPtr,
|
||||
args_head: llvmlite.Value | t.CPtr,
|
||||
self_ptr: rawptr[llvmlite.Value],
|
||||
args_head: rawptr[llvmlite.Value],
|
||||
args_count: int,
|
||||
found_func: rawptr[llvmlite.Function],
|
||||
ret_ty: rawptr[llvmlite.LLVMType],
|
||||
vtable_base: llvmlite.Value | t.CPtr = None) -> llvmlite.Value | t.CPtr:
|
||||
vtable_base: rawptr[llvmlite.Value] = None) -> rawptr[llvmlite.Value]:
|
||||
"""通过虚表间接调用虚方法,返回 call 结果(void 方法返回 None)
|
||||
|
||||
vtable_base: 对象头指针(vtable 所在位置,即未调整的 obj_ptr)。
|
||||
@@ -71,7 +71,7 @@ class CallGenCall(CallGenBase.CallGenBase):
|
||||
# GEP 槽位错位读到别的函数(MultiInheritTest color_code 虚调用读到
|
||||
# area FAILED 根因)。vtable_base 是接收者静态类型指针(vtable 所在
|
||||
# 位置),其 VTableMethods 才是最终对象实际存储的完整 vtable 布局。
|
||||
vc_entry: GenTypes.StructEntry | t.CPtr = None
|
||||
vc_entry: rawptr[GenTypes.StructEntry] = None
|
||||
struct_ty: rawptr[llvmlite.LLVMType] = None
|
||||
if vtable_base is not None and vtable_base.Ty is not None:
|
||||
vc_entry = self.Gen.StructGen.get_struct_type_from_value(vtable_base)
|
||||
@@ -119,13 +119,13 @@ class CallGenCall(CallGenBase.CallGenBase):
|
||||
# 这样即使 struct_ty 是 opaque(跨模块未加载完整定义)也能正常工作。
|
||||
# 注意用 vtable_base(对象头)而非 self_ptr:多继承 this 调整后
|
||||
# self_ptr 已前移,其头部不是 vtable 而是父类字段值。
|
||||
vtable_slot: llvmlite.Value | t.CPtr = llvmlite.build_bitcast(
|
||||
vtable_slot: rawptr[llvmlite.Value] = llvmlite.build_bitcast(
|
||||
builder, vtable_base, i8_ptr_ptr_ty)
|
||||
if vtable_slot is None:
|
||||
return None
|
||||
|
||||
# 5. load vtable 指针 (i8*)
|
||||
vtable_ptr: llvmlite.Value | t.CPtr = llvmlite.build_load(builder, i8_ptr_ty, vtable_slot)
|
||||
vtable_ptr: rawptr[llvmlite.Value] = llvmlite.build_load(builder, i8_ptr_ty, vtable_slot)
|
||||
if vtable_ptr is None:
|
||||
return None
|
||||
|
||||
@@ -156,19 +156,19 @@ class CallGenCall(CallGenBase.CallGenBase):
|
||||
vtable_ptr_ty: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, vtable_ty)
|
||||
|
||||
# 7. bitcast i8* 到 vtable 类型指针
|
||||
vtable_typed: llvmlite.Value | t.CPtr = llvmlite.build_bitcast(
|
||||
vtable_typed: rawptr[llvmlite.Value] = llvmlite.build_bitcast(
|
||||
builder, vtable_ptr, vtable_ptr_ty)
|
||||
if vtable_typed is None:
|
||||
return None
|
||||
|
||||
# 8. GEP 到方法槽位
|
||||
func_slot: llvmlite.Value | t.CPtr = llvmlite.build_gep_struct(
|
||||
func_slot: rawptr[llvmlite.Value] = llvmlite.build_gep_struct(
|
||||
builder, vtable_ty, i8_ptr_ty, vtable_typed, method_index)
|
||||
if func_slot is None:
|
||||
return None
|
||||
|
||||
# 9. load 函数指针 (i8*)
|
||||
func_i8: llvmlite.Value | t.CPtr = llvmlite.build_load(builder, i8_ptr_ty, func_slot)
|
||||
func_i8: rawptr[llvmlite.Value] = llvmlite.build_load(builder, i8_ptr_ty, func_slot)
|
||||
if func_i8 is None:
|
||||
return None
|
||||
|
||||
@@ -177,7 +177,7 @@ class CallGenCall(CallGenBase.CallGenBase):
|
||||
fp_first: rawptr[llvmlite.Function] = None
|
||||
fp_prev: rawptr[llvmlite.Function] = None
|
||||
fp_count: int = 0
|
||||
cur_val: llvmlite.Value | t.CPtr = args_head
|
||||
cur_val: rawptr[llvmlite.Value] = args_head
|
||||
for vi in range(args_count):
|
||||
if cur_val is None:
|
||||
break
|
||||
@@ -198,7 +198,7 @@ class CallGenCall(CallGenBase.CallGenBase):
|
||||
func_ptr_ty: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, func_ty)
|
||||
|
||||
# 11. bitcast i8* 到函数指针类型
|
||||
func_ptr: llvmlite.Value | t.CPtr = llvmlite.build_bitcast(builder, func_i8, func_ptr_ty)
|
||||
func_ptr: rawptr[llvmlite.Value] = llvmlite.build_bitcast(builder, func_i8, func_ptr_ty)
|
||||
if func_ptr is None:
|
||||
return None
|
||||
|
||||
@@ -213,15 +213,15 @@ class CallGenCall(CallGenBase.CallGenBase):
|
||||
|
||||
# ============================================================
|
||||
def _call_method_on_ptr(self, pool: rawptr[memhub.MemBuddy],
|
||||
builder: llvmlite.IRBuilder | t.CPtr,
|
||||
builder: rawptr[llvmlite.IRBuilder],
|
||||
mod: rawptr[llvmlite.LLVMModule],
|
||||
class_name: str,
|
||||
method_name: str,
|
||||
self_ptr: llvmlite.Value | t.CPtr,
|
||||
self_ptr: rawptr[llvmlite.Value],
|
||||
extra_args: sizet | t.CPtr,
|
||||
extra_count: int,
|
||||
trans: rawptr[HT.Translator],
|
||||
node: rawptr[ast.AST] = None) -> llvmlite.Value | t.CPtr:
|
||||
node: rawptr[ast.AST] = None) -> rawptr[llvmlite.Value]:
|
||||
"""在结构体指针上调用方法,返回 call 结果(void 方法返回 None)
|
||||
|
||||
node: 触发本次调用的 AST 节点(如 Subscript 下标节点),用于 fatal_error
|
||||
@@ -233,7 +233,7 @@ class CallGenCall(CallGenBase.CallGenBase):
|
||||
|
||||
# 提前获取结构体 entry(用 find_struct_by_type 规避跨模块同名 find_struct 找错)
|
||||
# 用于 SHA1 查找和虚表分派
|
||||
cmop_entry: GenTypes.StructEntry | t.CPtr = None
|
||||
cmop_entry: rawptr[GenTypes.StructEntry] = None
|
||||
cmop_struct_ty: rawptr[llvmlite.LLVMType] = self.Gen.StructGen.get_struct_type_from_value(self_ptr)
|
||||
if cmop_struct_ty is not None:
|
||||
cmop_entry = self.Gen.StructGen.find_struct_by_type(cmop_struct_ty)
|
||||
@@ -399,15 +399,15 @@ class CallGenCall(CallGenBase.CallGenBase):
|
||||
|
||||
# 构建参数链表: self_ptr → extra_args...
|
||||
llvmlite.value_set_next(self_ptr, None)
|
||||
head: llvmlite.Value | t.CPtr = self_ptr
|
||||
tail: llvmlite.Value | t.CPtr = self_ptr
|
||||
head: rawptr[llvmlite.Value] = self_ptr
|
||||
tail: rawptr[llvmlite.Value] = self_ptr
|
||||
|
||||
if extra_args is not None and extra_count > 0:
|
||||
for ei in range(extra_count):
|
||||
arg_addr: sizet = extra_args[ei]
|
||||
if arg_addr == 0:
|
||||
continue
|
||||
av: llvmlite.Value | t.CPtr = (llvmlite.Value | t.CPtr)(arg_addr)
|
||||
av: rawptr[llvmlite.Value] = rawptr[llvmlite.Value](arg_addr)
|
||||
if av is not None:
|
||||
llvmlite.value_set_next(av, None)
|
||||
llvmlite.value_set_next(tail, av)
|
||||
@@ -432,7 +432,7 @@ class CallGenCall(CallGenBase.CallGenBase):
|
||||
# 调用方函数表)Defaults 非 None 会短路跳过,但下方"用快照重建默认值"
|
||||
# 分支依赖 mdf_gd(唯一持有 stdlib 常量快照处)——缺它必 fatal_error
|
||||
# (ListTest list[int].__new__ 根因)
|
||||
mdf_gd: GenTypes.FuncDefaultsEntry | t.CPtr = self.Gen.CallGenLeafKit.find_func_defaults(lookup_name)
|
||||
mdf_gd: rawptr[GenTypes.FuncDefaultsEntry] = self.Gen.CallGenLeafKit.find_func_defaults(lookup_name)
|
||||
if mdf_defaults is None and mdf_gd is not None:
|
||||
mdf_defaults = mdf_gd.Defaults
|
||||
mdf_default_count = mdf_gd.DefaultCount
|
||||
@@ -470,7 +470,7 @@ class CallGenCall(CallGenBase.CallGenBase):
|
||||
# raise_disk() 崩溃根因,与 CallGenMixin 零值兜底同源)。
|
||||
if mdf_param_count == 0 and found_func is not None:
|
||||
ppcnt_f2: int = 0
|
||||
ppn_f2: llvmlite.Param | t.CPtr = llvmlite.function_get_param_head(found_func)
|
||||
ppn_f2: rawptr[llvmlite.Param] = llvmlite.function_get_param_head(found_func)
|
||||
while ppn_f2 is not None:
|
||||
fp_nm_f2: str = llvmlite.param_get_name(ppn_f2)
|
||||
if fp_nm_f2 is None or (string.strcmp(fp_nm_f2, "%__eh_msg_out__") != 0
|
||||
@@ -493,7 +493,7 @@ class CallGenCall(CallGenBase.CallGenBase):
|
||||
if mdf_di < mdf_default_count:
|
||||
# 用 stdlib 常量快照重建(mdf_gd.Defaults 的 pool 内 AST 可能已被 reset 回收,
|
||||
# 直接回退读 AST 会 use-after-free——快照失败时 fail-fast 暴露,绝不读悬空 AST)
|
||||
mdf_val: llvmlite.Value | t.CPtr = None
|
||||
mdf_val: rawptr[llvmlite.Value] = None
|
||||
if mdf_gd is not None:
|
||||
mdf_val = self.Gen.CallGenLeafKit._build_const_from_snapshot(
|
||||
pool, mod, mdf_gd, mdf_di, trans, builder)
|
||||
@@ -517,14 +517,14 @@ class CallGenCall(CallGenBase.CallGenBase):
|
||||
# 查找常查不到——查不到 ≠ 无默认值(如 Buf.__init__(data, capacity)
|
||||
# 缺的 length=0/owned=False 恰为零值),零值兜底语义一致。
|
||||
if found_func is not None:
|
||||
param_node_z: llvmlite.Param | t.CPtr = llvmlite.function_get_param_head(found_func)
|
||||
param_node_z: rawptr[llvmlite.Param] = llvmlite.function_get_param_head(found_func)
|
||||
skip_z: int = 0
|
||||
while skip_z <= mdf_pi and param_node_z is not None:
|
||||
param_node_z = llvmlite.param_get_next(param_node_z)
|
||||
skip_z += 1
|
||||
if param_node_z is not None:
|
||||
zero_ty: rawptr[llvmlite.LLVMType] = llvmlite.param_get_ty(param_node_z)
|
||||
zero_val: llvmlite.Value | t.CPtr = llvmlite.ConstZero(pool, zero_ty)
|
||||
zero_val: rawptr[llvmlite.Value] = llvmlite.ConstZero(pool, zero_ty)
|
||||
if zero_val is not None:
|
||||
llvmlite.value_set_next(zero_val, None)
|
||||
llvmlite.value_set_next(tail, zero_val)
|
||||
@@ -558,7 +558,7 @@ class CallGenCall(CallGenBase.CallGenBase):
|
||||
if rty_v is not None:
|
||||
pty_v = rty_v
|
||||
stdlib.free(seg_buf_v)
|
||||
zero_val_v: llvmlite.Value | t.CPtr = llvmlite.ConstZero(pool, pty_v)
|
||||
zero_val_v: rawptr[llvmlite.Value] = llvmlite.ConstZero(pool, pty_v)
|
||||
if zero_val_v is not None:
|
||||
llvmlite.value_set_next(zero_val_v, None)
|
||||
llvmlite.value_set_next(tail, zero_val_v)
|
||||
@@ -568,14 +568,14 @@ class CallGenCall(CallGenBase.CallGenBase):
|
||||
elif found_func is not None:
|
||||
# 无默认参数信息但有 found_func:用零值兜底填充缺失参数
|
||||
# (原逻辑;禁止 fail-fast 误杀——同上,查不到默认参数表 ≠ 无默认值)
|
||||
param_node: llvmlite.Param | t.CPtr = llvmlite.function_get_param_head(found_func)
|
||||
param_node: rawptr[llvmlite.Param] = llvmlite.function_get_param_head(found_func)
|
||||
skip_idx: int = 0
|
||||
while skip_idx < total_count and param_node is not None:
|
||||
param_node = llvmlite.param_get_next(param_node)
|
||||
skip_idx += 1
|
||||
while param_node is not None:
|
||||
missing_ty: rawptr[llvmlite.LLVMType] = llvmlite.param_get_ty(param_node)
|
||||
zero_val2: llvmlite.Value | t.CPtr = llvmlite.ConstZero(pool, missing_ty)
|
||||
zero_val2: rawptr[llvmlite.Value] = llvmlite.ConstZero(pool, missing_ty)
|
||||
if zero_val2 is not None:
|
||||
llvmlite.value_set_next(zero_val2, None)
|
||||
llvmlite.value_set_next(tail, zero_val2)
|
||||
@@ -591,17 +591,17 @@ class CallGenCall(CallGenBase.CallGenBase):
|
||||
# 与形参 Vec3* 不匹配,需 bitcast(coerce 指针→指针生成 bitcast),
|
||||
# 否则 call 参数类型与声明不一致 llc 报错。
|
||||
if found_func is not None and head is not None:
|
||||
pc_param: llvmlite.Param | t.CPtr = llvmlite.function_get_param_head(found_func)
|
||||
pc_node: llvmlite.Value | t.CPtr = head
|
||||
new_head_pc: llvmlite.Value | t.CPtr = head
|
||||
prev_pc: llvmlite.Value | t.CPtr = None
|
||||
pc_param: rawptr[llvmlite.Param] = llvmlite.function_get_param_head(found_func)
|
||||
pc_node: rawptr[llvmlite.Value] = head
|
||||
new_head_pc: rawptr[llvmlite.Value] = head
|
||||
prev_pc: rawptr[llvmlite.Value] = None
|
||||
while pc_node is not None:
|
||||
pc_next_save: llvmlite.Value | t.CPtr = pc_node.Next
|
||||
coerced_pc: llvmlite.Value | t.CPtr = pc_node
|
||||
pc_next_save: rawptr[llvmlite.Value] = pc_node.Next
|
||||
coerced_pc: rawptr[llvmlite.Value] = pc_node
|
||||
if pc_param is not None:
|
||||
pty_pc: rawptr[llvmlite.LLVMType] = llvmlite.param_get_ty(pc_param)
|
||||
if pty_pc is not None:
|
||||
c_pc: llvmlite.Value | t.CPtr = self.Gen.ExprGenBase.coerce_to_type(
|
||||
c_pc: rawptr[llvmlite.Value] = self.Gen.ExprGenBase.coerce_to_type(
|
||||
builder, pc_node, pty_pc, None)
|
||||
if c_pc is not None:
|
||||
coerced_pc = c_pc
|
||||
@@ -674,13 +674,13 @@ class CallGenCall(CallGenBase.CallGenBase):
|
||||
|
||||
# ============================================================
|
||||
def _translate_method_call(self, pool: rawptr[memhub.MemBuddy],
|
||||
builder: llvmlite.IRBuilder | t.CPtr,
|
||||
builder: rawptr[llvmlite.IRBuilder],
|
||||
mod: rawptr[llvmlite.LLVMModule],
|
||||
class_name: str,
|
||||
method_name: str,
|
||||
obj_ptr: llvmlite.Value | t.CPtr,
|
||||
obj_ptr: rawptr[llvmlite.Value],
|
||||
cl: rawptr[ast.Call],
|
||||
trans: rawptr[HT.Translator]) -> llvmlite.Value | t.CPtr:
|
||||
trans: rawptr[HT.Translator]) -> rawptr[llvmlite.Value]:
|
||||
"""翻译方法调用,返回 call 结果 Value"""
|
||||
if pool is None or builder is None or class_name is None or method_name is None:
|
||||
return None
|
||||
@@ -712,7 +712,7 @@ class CallGenCall(CallGenBase.CallGenBase):
|
||||
# 双指针槽形态(rawptr[list[...]] 局部变量 alloca Ptr(Ptr(Struct))
|
||||
# 直接传入时先 load 一层得到对象指针 Ptr(Struct),与分派方
|
||||
# _translate_method_call 调用点的 obj_ptr 语义一致)。
|
||||
lb_obj: llvmlite.Value | t.CPtr = obj_ptr
|
||||
lb_obj: rawptr[llvmlite.Value] = obj_ptr
|
||||
if lb_obj is not None and lb_obj.Ty is not None:
|
||||
match lb_obj.Ty:
|
||||
case llvmlite.LLVMType.Ptr(lb_inner):
|
||||
@@ -724,7 +724,7 @@ class CallGenCall(CallGenBase.CallGenBase):
|
||||
case _:
|
||||
pass
|
||||
if lb_obj is not None:
|
||||
lb_cargs: list[rawptr[ast.AST]] | t.CPtr = cl.args
|
||||
lb_cargs: rawptr[list[rawptr[ast.AST]]] = cl.args
|
||||
lb_can: sizet = 0
|
||||
if lb_cargs is not None:
|
||||
lb_can = len(lb_cargs)
|
||||
@@ -756,7 +756,7 @@ class CallGenCall(CallGenBase.CallGenBase):
|
||||
|
||||
# 提前获取结构体 entry(用 find_struct_by_type 规避跨模块同名 find_struct 找错)
|
||||
# 用于继承链遍历、SHA1 查找和虚表分派
|
||||
mc_entry: GenTypes.StructEntry | t.CPtr = None
|
||||
mc_entry: rawptr[GenTypes.StructEntry] = None
|
||||
mc_struct_ty: rawptr[llvmlite.LLVMType] = self.Gen.StructGen.get_struct_type_from_value(obj_ptr)
|
||||
if mc_struct_ty is not None:
|
||||
mc_entry = self.Gen.StructGen.find_struct_by_type(mc_struct_ty)
|
||||
@@ -843,7 +843,7 @@ class CallGenCall(CallGenBase.CallGenBase):
|
||||
# 且本模块存在同名方法"的任意条目,需逐条枚举探测,不可改为按名
|
||||
# find_struct(会退化为单条精确查找、漏掉全部兄弟候选)。
|
||||
while sc_i < sc_n and found_func is None and mixin_hit == 0:
|
||||
cand_entry: GenTypes.StructEntry | t.CPtr = self.Gen.StructGen._get_struct_entry(sc_i)
|
||||
cand_entry: rawptr[GenTypes.StructEntry] = self.Gen.StructGen._get_struct_entry(sc_i)
|
||||
if cand_entry is not None and cand_entry.Name is not None:
|
||||
cand_name: str = cand_entry.Name
|
||||
if string.strcmp(cand_name, class_name) != 0:
|
||||
@@ -1191,17 +1191,17 @@ class CallGenCall(CallGenBase.CallGenBase):
|
||||
"TypeError")
|
||||
|
||||
# 翻译调用参数
|
||||
cargs: list[rawptr[ast.AST]] | t.CPtr = cl.args
|
||||
cargs: rawptr[list[rawptr[ast.AST]]] = cl.args
|
||||
can: sizet = 0
|
||||
if cargs is not None:
|
||||
can = len(cargs)
|
||||
kw_calls: list[rawptr[ast.AST]] | t.CPtr = cl.keywords
|
||||
kw_calls: rawptr[list[rawptr[ast.AST]]] = cl.keywords
|
||||
kwc: sizet = 0
|
||||
if kw_calls is not None:
|
||||
kwc = len(kw_calls)
|
||||
|
||||
# 多继承 this 调整(字节偏移法,与 TPC HandlesExprCall._adjust_this_for_inherited_method 一致):继承方法体按"定义类自身布局"读 self 字段,父类字段区在子类中字节偏移可能不同,故 delta = 字段在子类中字节偏移 − 字段在父类自身布局中字节偏移;delta==0(第一父类,字段区前缀对齐)无需调整,delta>0 时按字节 GEP 到父类字段区在子类中的等效基址再 bitcast 成父类指针
|
||||
self_arg: llvmlite.Value | t.CPtr = obj_ptr
|
||||
self_arg: rawptr[llvmlite.Value] = obj_ptr
|
||||
if mc_anc is not None and string.strcmp(mc_anc, class_name) != 0:
|
||||
# 判断 mc_anc 是否为 class_name 的第一父类:第一父类字段区前缀对齐
|
||||
# (delta==0)无需调整;非第一父类必须调整 self,任何一步失败都
|
||||
@@ -1213,7 +1213,7 @@ class CallGenCall(CallGenBase.CallGenBase):
|
||||
first_parent_th: str = (str | t.CPtr)(mro_fp_th[1])
|
||||
if first_parent_th is not None and string.strcmp(first_parent_th, mc_anc) == 0:
|
||||
is_first_parent_th = 1
|
||||
anc_entry_th: GenTypes.StructEntry | t.CPtr = self.Gen.StructGen.find_struct(mc_anc)
|
||||
anc_entry_th: rawptr[GenTypes.StructEntry] = self.Gen.StructGen.find_struct(mc_anc)
|
||||
# 无字段父类(FieldCount==0,如多继承中的纯方法类 Vec2Extra):
|
||||
# 继承方法体按"定义类字段"读 self,定义类无字段则方法体不读
|
||||
# self 布局 → this 无需字节调整,原样传入即可(对齐 TPC
|
||||
@@ -1222,7 +1222,7 @@ class CallGenCall(CallGenBase.CallGenBase):
|
||||
anc_first_name_th: str = None
|
||||
afi_th: int = 0
|
||||
while afi_th < anc_entry_th.FieldCount:
|
||||
afe_th: GenTypes.FieldEntry | t.CPtr = self.Gen.StructGen._get_field_entry(
|
||||
afe_th: rawptr[GenTypes.FieldEntry] = self.Gen.StructGen._get_field_entry(
|
||||
anc_entry_th, afi_th)
|
||||
if afe_th is not None:
|
||||
afn_th: str = self.Gen.StructGen.get_field_name_ptr(afe_th)
|
||||
@@ -1231,12 +1231,12 @@ class CallGenCall(CallGenBase.CallGenBase):
|
||||
break
|
||||
afi_th += 1
|
||||
if anc_first_name_th is not None:
|
||||
sub_entry_th: GenTypes.StructEntry | t.CPtr = self.Gen.StructGen.find_struct(
|
||||
sub_entry_th: rawptr[GenTypes.StructEntry] = self.Gen.StructGen.find_struct(
|
||||
class_name)
|
||||
if sub_entry_th is not None:
|
||||
anc_field_th: GenTypes.FieldEntry | t.CPtr = self.Gen.StructGen.lookup_field(
|
||||
anc_field_th: rawptr[GenTypes.FieldEntry] = self.Gen.StructGen.lookup_field(
|
||||
anc_entry_th.Ty, anc_first_name_th)
|
||||
sub_field_th: GenTypes.FieldEntry | t.CPtr = self.Gen.StructGen.lookup_field(
|
||||
sub_field_th: rawptr[GenTypes.FieldEntry] = self.Gen.StructGen.lookup_field(
|
||||
sub_entry_th.Ty, anc_first_name_th)
|
||||
if anc_field_th is not None and sub_field_th is not None:
|
||||
anc_off_th: int = self._field_byte_offset(
|
||||
@@ -1247,10 +1247,10 @@ class CallGenCall(CallGenBase.CallGenBase):
|
||||
if delta_th > 0:
|
||||
i8_ty_th: rawptr[llvmlite.LLVMType] = llvmlite.Int8(pool)
|
||||
i8_ptr_th: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, i8_ty_th)
|
||||
obj_i8_th: llvmlite.Value | t.CPtr = llvmlite.build_bitcast(
|
||||
obj_i8_th: rawptr[llvmlite.Value] = llvmlite.build_bitcast(
|
||||
builder, obj_ptr, i8_ptr_th)
|
||||
delta_val_th: llvmlite.Value | t.CPtr = llvmlite.const_int32(pool, delta_th)
|
||||
adj_th: llvmlite.Value | t.CPtr = llvmlite.build_gep(
|
||||
delta_val_th: rawptr[llvmlite.Value] = llvmlite.const_int32(pool, delta_th)
|
||||
adj_th: rawptr[llvmlite.Value] = llvmlite.build_gep(
|
||||
builder, i8_ty_th, obj_i8_th, delta_val_th)
|
||||
if adj_th is not None:
|
||||
anc_ptr_ty_th: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, anc_entry_th.Ty)
|
||||
@@ -1272,11 +1272,11 @@ class CallGenCall(CallGenBase.CallGenBase):
|
||||
if anc_size_th > 0:
|
||||
i8_ty_th2: rawptr[llvmlite.LLVMType] = llvmlite.Int8(pool)
|
||||
i8_ptr_th2: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, i8_ty_th2)
|
||||
obj_i8_th2: llvmlite.Value | t.CPtr = llvmlite.build_bitcast(
|
||||
obj_i8_th2: rawptr[llvmlite.Value] = llvmlite.build_bitcast(
|
||||
builder, obj_ptr, i8_ptr_th2)
|
||||
sib_delta_th: llvmlite.Value | t.CPtr = llvmlite.const_int32(
|
||||
sib_delta_th: rawptr[llvmlite.Value] = llvmlite.const_int32(
|
||||
pool, 0 - anc_size_th)
|
||||
adj_th2: llvmlite.Value | t.CPtr = llvmlite.build_gep(
|
||||
adj_th2: rawptr[llvmlite.Value] = llvmlite.build_gep(
|
||||
builder, i8_ty_th2, obj_i8_th2, sib_delta_th)
|
||||
if adj_th2 is not None:
|
||||
anc_ptr_ty_th2: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(
|
||||
@@ -1324,25 +1324,25 @@ class CallGenCall(CallGenBase.CallGenBase):
|
||||
# bitcast 匹配声明签名(对齐 _call_method_on_ptr 的 coerce 块),
|
||||
# 否则 llc 报 call 参数类型与 declare 不一致。
|
||||
if found_func is not None:
|
||||
pp_self: llvmlite.Param | t.CPtr = llvmlite.function_get_param_head(found_func)
|
||||
pp_self: rawptr[llvmlite.Param] = llvmlite.function_get_param_head(found_func)
|
||||
if pp_self is not None:
|
||||
pty_self: rawptr[llvmlite.LLVMType] = llvmlite.param_get_ty(pp_self)
|
||||
if pty_self is not None:
|
||||
cself_tm: llvmlite.Value | t.CPtr = self.Gen.ExprGenBase.coerce_to_type(
|
||||
cself_tm: rawptr[llvmlite.Value] = self.Gen.ExprGenBase.coerce_to_type(
|
||||
builder, self_arg, pty_self, None)
|
||||
if cself_tm is not None:
|
||||
self_arg = cself_tm
|
||||
# 构建参数链表: self → arg1 → arg2 → ...
|
||||
llvmlite.value_set_next(self_arg, None)
|
||||
head: llvmlite.Value | t.CPtr = self_arg
|
||||
tail: llvmlite.Value | t.CPtr = self_arg
|
||||
head: rawptr[llvmlite.Value] = self_arg
|
||||
tail: rawptr[llvmlite.Value] = self_arg
|
||||
arg_count_eff: int = 0
|
||||
|
||||
if kwc > 0 and found_func is not None:
|
||||
# 关键字参数:遍历函数定义参数(跳过 self),位置参数优先,其余按名匹配。
|
||||
# 未提供的形参按类型补占位零值以保持参数序列位置(见下方 (b)/(c) 注释);
|
||||
# 实参表达式翻译失败则 fail-fast,绝不静默零值替换。
|
||||
cur_param_k: llvmlite.Param | t.CPtr = llvmlite.function_get_param_head(found_func)
|
||||
cur_param_k: rawptr[llvmlite.Param] = llvmlite.function_get_param_head(found_func)
|
||||
if cur_param_k is not None:
|
||||
cur_param_k = llvmlite.param_get_next(cur_param_k) # 跳过 self
|
||||
pi_k: int = 0
|
||||
@@ -1355,13 +1355,13 @@ class CallGenCall(CallGenBase.CallGenBase):
|
||||
if pname_k is not None:
|
||||
ki_k: int
|
||||
for ki_k in range(kwc):
|
||||
kw_k: ast.Keyword | t.CPtr = (ast.Keyword | t.CPtr)(kw_calls.get(ki_k))
|
||||
kw_k: rawptr[ast.Keyword] = rawptr[ast.Keyword](kw_calls.get(ki_k))
|
||||
if kw_k is None or kw_k.arg is None or kw_k.value is None:
|
||||
continue
|
||||
if self._kwarg_name_matches(kw_k.arg, pname_k) == 1:
|
||||
arg_node_k = kw_k.value
|
||||
break
|
||||
arg_val_k: llvmlite.Value | t.CPtr = None
|
||||
arg_val_k: rawptr[llvmlite.Value] = None
|
||||
if arg_node_k is not None:
|
||||
# 先取形参类型(char 字面量 → str 形参需物化字符串,见 translate_constant)
|
||||
pty_k0: rawptr[llvmlite.LLVMType] = llvmlite.param_get_ty(cur_param_k)
|
||||
@@ -1411,7 +1411,7 @@ class CallGenCall(CallGenBase.CallGenBase):
|
||||
# 先取形参类型:单引号单字符字面量(CONST_CHAR)传给 str/指针
|
||||
# 形参时需物化 1 字符字符串(translate_constant 依据 target_ty 判定),
|
||||
# 否则 coerce inttoptr 把字符值当指针 → strlen 访问低地址崩溃。
|
||||
pp: llvmlite.Param | t.CPtr = None
|
||||
pp: rawptr[llvmlite.Param] = None
|
||||
pty: rawptr[llvmlite.LLVMType] = None
|
||||
if found_func is not None:
|
||||
pp = llvmlite.function_get_param_head(found_func)
|
||||
@@ -1423,7 +1423,7 @@ class CallGenCall(CallGenBase.CallGenBase):
|
||||
pi += 1
|
||||
if pp is not None:
|
||||
pty = llvmlite.param_get_ty(pp)
|
||||
arg_val: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
|
||||
arg_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, arg_node, None, 0, trans, pty)
|
||||
if arg_val is None:
|
||||
# (a) 实参表达式翻译失败(translate_value 返回 None)→ fail-fast。
|
||||
@@ -1454,7 +1454,7 @@ class CallGenCall(CallGenBase.CallGenBase):
|
||||
if arr_pointee_ma is not None:
|
||||
match arr_pointee_ma:
|
||||
case llvmlite.LLVMType.Array(arr_et_ma, _):
|
||||
decayed_ma: llvmlite.Value | t.CPtr = llvmlite.build_gep_array(
|
||||
decayed_ma: rawptr[llvmlite.Value] = llvmlite.build_gep_array(
|
||||
builder, arr_pointee_ma, arr_et_ma, arg_val,
|
||||
llvmlite.const_int32(pool, 0))
|
||||
if decayed_ma is not None:
|
||||
@@ -1484,7 +1484,7 @@ class CallGenCall(CallGenBase.CallGenBase):
|
||||
# 调用方函数表)Defaults 非 None 会短路跳过,但下方"用快照重建默认值"
|
||||
# 分支依赖 mdf_gd(唯一持有 stdlib 常量快照处)——缺它必 fatal_error
|
||||
# (ListTest list[int].__new__ 根因)
|
||||
mdf_gd: GenTypes.FuncDefaultsEntry | t.CPtr = self.Gen.CallGenLeafKit.find_func_defaults(lookup_name)
|
||||
mdf_gd: rawptr[GenTypes.FuncDefaultsEntry] = self.Gen.CallGenLeafKit.find_func_defaults(lookup_name)
|
||||
if mdf_defaults is None and mdf_gd is not None:
|
||||
mdf_defaults = mdf_gd.Defaults
|
||||
mdf_default_count = mdf_gd.DefaultCount
|
||||
@@ -1527,7 +1527,7 @@ class CallGenCall(CallGenBase.CallGenBase):
|
||||
# raise_disk() 崩溃同源,与 _call_method_on_ptr/CallGenMixin 一致)。
|
||||
if mdf_param_count == 0 and found_func is not None:
|
||||
ppcnt_f: int = 0
|
||||
ppn_f: llvmlite.Param | t.CPtr = llvmlite.function_get_param_head(found_func)
|
||||
ppn_f: rawptr[llvmlite.Param] = llvmlite.function_get_param_head(found_func)
|
||||
while ppn_f is not None:
|
||||
fp_nm_f: str = llvmlite.param_get_name(ppn_f)
|
||||
if fp_nm_f is None or (string.strcmp(fp_nm_f, "%__eh_msg_out__") != 0
|
||||
@@ -1550,7 +1550,7 @@ class CallGenCall(CallGenBase.CallGenBase):
|
||||
if mdf_di < mdf_default_count:
|
||||
# 用 stdlib 常量快照重建(mdf_gd.Defaults 的 pool 内 AST 可能已被 reset 回收,
|
||||
# 直接回退读 AST 会 use-after-free——快照失败时 fail-fast 暴露,绝不读悬空 AST)
|
||||
mdf_val: llvmlite.Value | t.CPtr = None
|
||||
mdf_val: rawptr[llvmlite.Value] = None
|
||||
if mdf_gd is not None:
|
||||
mdf_val = self.Gen.CallGenLeafKit._build_const_from_snapshot(
|
||||
pool, mod, mdf_gd, mdf_di, trans, builder)
|
||||
@@ -1584,14 +1584,14 @@ class CallGenCall(CallGenBase.CallGenBase):
|
||||
# call/declare 的形参数量、填补尾随的声明可选参数;这**不是**
|
||||
# "表达式翻译失败"的兜底 —— 那条通路已在实参装配处 fail-fast。
|
||||
if found_func is not None:
|
||||
param_node_z: llvmlite.Param | t.CPtr = llvmlite.function_get_param_head(found_func)
|
||||
param_node_z: rawptr[llvmlite.Param] = llvmlite.function_get_param_head(found_func)
|
||||
skip_z: int = 0
|
||||
while skip_z <= mdf_pi and param_node_z is not None:
|
||||
param_node_z = llvmlite.param_get_next(param_node_z)
|
||||
skip_z += 1
|
||||
if param_node_z is not None:
|
||||
zero_ty: rawptr[llvmlite.LLVMType] = llvmlite.param_get_ty(param_node_z)
|
||||
zero_val: llvmlite.Value | t.CPtr = llvmlite.ConstZero(pool, zero_ty)
|
||||
zero_val: rawptr[llvmlite.Value] = llvmlite.ConstZero(pool, zero_ty)
|
||||
if zero_val is not None:
|
||||
llvmlite.value_set_next(zero_val, None)
|
||||
llvmlite.value_set_next(tail, zero_val)
|
||||
@@ -1625,7 +1625,7 @@ class CallGenCall(CallGenBase.CallGenBase):
|
||||
if rty_v is not None:
|
||||
pty_v = rty_v
|
||||
stdlib.free(seg_buf_v)
|
||||
zero_val_v: llvmlite.Value | t.CPtr = llvmlite.ConstZero(pool, pty_v)
|
||||
zero_val_v: rawptr[llvmlite.Value] = llvmlite.ConstZero(pool, pty_v)
|
||||
if zero_val_v is not None:
|
||||
llvmlite.value_set_next(zero_val_v, None)
|
||||
llvmlite.value_set_next(tail, zero_val_v)
|
||||
@@ -1684,14 +1684,14 @@ class CallGenCall(CallGenBase.CallGenBase):
|
||||
# lm_obj 必须是已 load 的 list 对象指针 Ptr(list-struct)。
|
||||
# ============================================================
|
||||
def _translate_list_builtin_call(self, pool: rawptr[memhub.MemBuddy],
|
||||
builder: llvmlite.IRBuilder | t.CPtr,
|
||||
builder: rawptr[llvmlite.IRBuilder],
|
||||
mod: rawptr[llvmlite.LLVMModule],
|
||||
cl: rawptr[ast.Call],
|
||||
lm_name: str,
|
||||
lm_obj: llvmlite.Value | t.CPtr,
|
||||
cargs: list[rawptr[ast.AST]] | t.CPtr,
|
||||
lm_obj: rawptr[llvmlite.Value],
|
||||
cargs: rawptr[list[rawptr[ast.AST]]],
|
||||
can: sizet,
|
||||
trans: rawptr[HT.Translator]) -> llvmlite.Value | t.CPtr:
|
||||
trans: rawptr[HT.Translator]) -> rawptr[llvmlite.Value]:
|
||||
"""翻译 list 内置方法调用,返回 call 结果 Value(void 方法返回 None)"""
|
||||
if pool is None or builder is None or lm_obj is None or lm_name is None:
|
||||
return None
|
||||
@@ -1716,24 +1716,24 @@ class CallGenCall(CallGenBase.CallGenBase):
|
||||
if string.strcmp(lm_name, "get") == 0 or string.strcmp(lm_name, "__getitem__") == 0:
|
||||
if can >= 1 and cargs is not None:
|
||||
# 加载 __data__ (偏移 0)
|
||||
g_idx0: llvmlite.Value | t.CPtr = llvmlite.const_int64(pool, 0)
|
||||
g_dpp: llvmlite.Value | t.CPtr = llvmlite.build_gep(builder, i64_ty, lm_obj, g_idx0)
|
||||
g_data: llvmlite.Value | t.CPtr = llvmlite.build_load(builder, i8_ptr_ty, g_dpp)
|
||||
g_idx0: rawptr[llvmlite.Value] = llvmlite.const_int64(pool, 0)
|
||||
g_dpp: rawptr[llvmlite.Value] = llvmlite.build_gep(builder, i64_ty, lm_obj, g_idx0)
|
||||
g_data: rawptr[llvmlite.Value] = llvmlite.build_load(builder, i8_ptr_ty, g_dpp)
|
||||
# 加载 __elem_size__ (偏移 32, index 4)
|
||||
g_idx4: llvmlite.Value | t.CPtr = llvmlite.const_int64(pool, 4)
|
||||
g_epp: llvmlite.Value | t.CPtr = llvmlite.build_gep(builder, i64_ty, lm_obj, g_idx4)
|
||||
g_esize: llvmlite.Value | t.CPtr = llvmlite.build_load(builder, i64_ty, g_epp)
|
||||
g_idx4: rawptr[llvmlite.Value] = llvmlite.const_int64(pool, 4)
|
||||
g_epp: rawptr[llvmlite.Value] = llvmlite.build_gep(builder, i64_ty, lm_obj, g_idx4)
|
||||
g_esize: rawptr[llvmlite.Value] = llvmlite.build_load(builder, i64_ty, g_epp)
|
||||
# 翻译 index
|
||||
g_idx_node: rawptr[ast.AST] = cargs.get(0)
|
||||
g_idx_val: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
|
||||
g_idx_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, g_idx_node, None, 0, trans)
|
||||
if g_data is not None and g_esize is not None and g_idx_val is not None:
|
||||
g_idx_i64: llvmlite.Value | t.CPtr = self.Gen.ExprGenBase.coerce_to_type(
|
||||
g_idx_i64: rawptr[llvmlite.Value] = self.Gen.ExprGenBase.coerce_to_type(
|
||||
builder, g_idx_val, i64_ty, g_idx_node)
|
||||
g_offset: llvmlite.Value | t.CPtr = llvmlite.build_mul(builder, g_idx_i64, g_esize)
|
||||
g_addr: llvmlite.Value | t.CPtr = llvmlite.build_gep(builder, i8_ty, g_data, g_offset)
|
||||
g_offset: rawptr[llvmlite.Value] = llvmlite.build_mul(builder, g_idx_i64, g_esize)
|
||||
g_addr: rawptr[llvmlite.Value] = llvmlite.build_gep(builder, i8_ty, g_data, g_offset)
|
||||
if g_addr is not None:
|
||||
g_ep: llvmlite.Value | t.CPtr = llvmlite.build_bitcast(
|
||||
g_ep: rawptr[llvmlite.Value] = llvmlite.build_bitcast(
|
||||
builder, g_addr, llvmlite.Ptr(pool, lm_elem_ty))
|
||||
if g_ep is not None:
|
||||
return llvmlite.build_load(builder, lm_elem_ty, g_ep)
|
||||
@@ -1741,27 +1741,27 @@ class CallGenCall(CallGenBase.CallGenBase):
|
||||
# set / __setitem__: 设置 index 处的元素
|
||||
elif string.strcmp(lm_name, "set") == 0 or string.strcmp(lm_name, "__setitem__") == 0:
|
||||
if can >= 2 and cargs is not None:
|
||||
s_idx0: llvmlite.Value | t.CPtr = llvmlite.const_int64(pool, 0)
|
||||
s_dpp: llvmlite.Value | t.CPtr = llvmlite.build_gep(builder, i64_ty, lm_obj, s_idx0)
|
||||
s_data: llvmlite.Value | t.CPtr = llvmlite.build_load(builder, i8_ptr_ty, s_dpp)
|
||||
s_idx4: llvmlite.Value | t.CPtr = llvmlite.const_int64(pool, 4)
|
||||
s_epp: llvmlite.Value | t.CPtr = llvmlite.build_gep(builder, i64_ty, lm_obj, s_idx4)
|
||||
s_esize: llvmlite.Value | t.CPtr = llvmlite.build_load(builder, i64_ty, s_epp)
|
||||
s_idx0: rawptr[llvmlite.Value] = llvmlite.const_int64(pool, 0)
|
||||
s_dpp: rawptr[llvmlite.Value] = llvmlite.build_gep(builder, i64_ty, lm_obj, s_idx0)
|
||||
s_data: rawptr[llvmlite.Value] = llvmlite.build_load(builder, i8_ptr_ty, s_dpp)
|
||||
s_idx4: rawptr[llvmlite.Value] = llvmlite.const_int64(pool, 4)
|
||||
s_epp: rawptr[llvmlite.Value] = llvmlite.build_gep(builder, i64_ty, lm_obj, s_idx4)
|
||||
s_esize: rawptr[llvmlite.Value] = llvmlite.build_load(builder, i64_ty, s_epp)
|
||||
s_idx_node: rawptr[ast.AST] = cargs.get(0)
|
||||
s_val_node: rawptr[ast.AST] = cargs.get(1)
|
||||
s_idx_val: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
|
||||
s_idx_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, s_idx_node, None, 0, trans)
|
||||
s_val_val: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
|
||||
s_val_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, s_val_node, None, 0, trans)
|
||||
if s_data is not None and s_esize is not None and s_idx_val is not None and s_val_val is not None:
|
||||
s_idx_i64: llvmlite.Value | t.CPtr = self.Gen.ExprGenBase.coerce_to_type(
|
||||
s_idx_i64: rawptr[llvmlite.Value] = self.Gen.ExprGenBase.coerce_to_type(
|
||||
builder, s_idx_val, i64_ty, s_idx_node)
|
||||
s_offset: llvmlite.Value | t.CPtr = llvmlite.build_mul(builder, s_idx_i64, s_esize)
|
||||
s_addr: llvmlite.Value | t.CPtr = llvmlite.build_gep(builder, i8_ty, s_data, s_offset)
|
||||
s_offset: rawptr[llvmlite.Value] = llvmlite.build_mul(builder, s_idx_i64, s_esize)
|
||||
s_addr: rawptr[llvmlite.Value] = llvmlite.build_gep(builder, i8_ty, s_data, s_offset)
|
||||
if s_addr is not None:
|
||||
s_val_elem: llvmlite.Value | t.CPtr = self.Gen.ExprGenBase.coerce_to_type(
|
||||
s_val_elem: rawptr[llvmlite.Value] = self.Gen.ExprGenBase.coerce_to_type(
|
||||
builder, s_val_val, lm_elem_ty, s_val_node)
|
||||
s_ep: llvmlite.Value | t.CPtr = llvmlite.build_bitcast(
|
||||
s_ep: rawptr[llvmlite.Value] = llvmlite.build_bitcast(
|
||||
builder, s_addr, llvmlite.Ptr(pool, lm_elem_ty))
|
||||
if s_ep is not None:
|
||||
llvmlite.build_store(builder, s_val_elem, s_ep)
|
||||
@@ -1769,45 +1769,45 @@ class CallGenCall(CallGenBase.CallGenBase):
|
||||
|
||||
# pop: 返回最后一个元素,count--
|
||||
elif string.strcmp(lm_name, "pop") == 0:
|
||||
p_idx1: llvmlite.Value | t.CPtr = llvmlite.const_int64(pool, 1)
|
||||
p_cpp: llvmlite.Value | t.CPtr = llvmlite.build_gep(builder, i64_ty, lm_obj, p_idx1)
|
||||
p_count: llvmlite.Value | t.CPtr = llvmlite.build_load(builder, i64_ty, p_cpp)
|
||||
p_nc: llvmlite.Value | t.CPtr = llvmlite.build_sub(
|
||||
p_idx1: rawptr[llvmlite.Value] = llvmlite.const_int64(pool, 1)
|
||||
p_cpp: rawptr[llvmlite.Value] = llvmlite.build_gep(builder, i64_ty, lm_obj, p_idx1)
|
||||
p_count: rawptr[llvmlite.Value] = llvmlite.build_load(builder, i64_ty, p_cpp)
|
||||
p_nc: rawptr[llvmlite.Value] = llvmlite.build_sub(
|
||||
builder, p_count, llvmlite.const_int64(pool, 1))
|
||||
llvmlite.build_store(builder, p_nc, p_cpp)
|
||||
p_idx0: llvmlite.Value | t.CPtr = llvmlite.const_int64(pool, 0)
|
||||
p_dpp: llvmlite.Value | t.CPtr = llvmlite.build_gep(builder, i64_ty, lm_obj, p_idx0)
|
||||
p_data: llvmlite.Value | t.CPtr = llvmlite.build_load(builder, i8_ptr_ty, p_dpp)
|
||||
p_idx4: llvmlite.Value | t.CPtr = llvmlite.const_int64(pool, 4)
|
||||
p_epp: llvmlite.Value | t.CPtr = llvmlite.build_gep(builder, i64_ty, lm_obj, p_idx4)
|
||||
p_esize: llvmlite.Value | t.CPtr = llvmlite.build_load(builder, i64_ty, p_epp)
|
||||
p_idx0: rawptr[llvmlite.Value] = llvmlite.const_int64(pool, 0)
|
||||
p_dpp: rawptr[llvmlite.Value] = llvmlite.build_gep(builder, i64_ty, lm_obj, p_idx0)
|
||||
p_data: rawptr[llvmlite.Value] = llvmlite.build_load(builder, i8_ptr_ty, p_dpp)
|
||||
p_idx4: rawptr[llvmlite.Value] = llvmlite.const_int64(pool, 4)
|
||||
p_epp: rawptr[llvmlite.Value] = llvmlite.build_gep(builder, i64_ty, lm_obj, p_idx4)
|
||||
p_esize: rawptr[llvmlite.Value] = llvmlite.build_load(builder, i64_ty, p_epp)
|
||||
if p_data is not None and p_esize is not None and p_nc is not None:
|
||||
p_offset: llvmlite.Value | t.CPtr = llvmlite.build_mul(builder, p_nc, p_esize)
|
||||
p_addr: llvmlite.Value | t.CPtr = llvmlite.build_gep(builder, i8_ty, p_data, p_offset)
|
||||
p_offset: rawptr[llvmlite.Value] = llvmlite.build_mul(builder, p_nc, p_esize)
|
||||
p_addr: rawptr[llvmlite.Value] = llvmlite.build_gep(builder, i8_ty, p_data, p_offset)
|
||||
if p_addr is not None:
|
||||
p_ep: llvmlite.Value | t.CPtr = llvmlite.build_bitcast(
|
||||
p_ep: rawptr[llvmlite.Value] = llvmlite.build_bitcast(
|
||||
builder, p_addr, llvmlite.Ptr(pool, lm_elem_ty))
|
||||
if p_ep is not None:
|
||||
return llvmlite.build_load(builder, lm_elem_ty, p_ep)
|
||||
|
||||
# clear: count = 0
|
||||
elif string.strcmp(lm_name, "clear") == 0:
|
||||
c_idx1: llvmlite.Value | t.CPtr = llvmlite.const_int64(pool, 1)
|
||||
c_cpp: llvmlite.Value | t.CPtr = llvmlite.build_gep(builder, i64_ty, lm_obj, c_idx1)
|
||||
c_idx1: rawptr[llvmlite.Value] = llvmlite.const_int64(pool, 1)
|
||||
c_cpp: rawptr[llvmlite.Value] = llvmlite.build_gep(builder, i64_ty, lm_obj, c_idx1)
|
||||
llvmlite.build_store(builder, llvmlite.const_int64(pool, 0), c_cpp)
|
||||
return None
|
||||
|
||||
# __iter__: iter_index = 0, return self
|
||||
elif string.strcmp(lm_name, "__iter__") == 0:
|
||||
it_idx5: llvmlite.Value | t.CPtr = llvmlite.const_int64(pool, 5)
|
||||
it_ipp: llvmlite.Value | t.CPtr = llvmlite.build_gep(builder, i64_ty, lm_obj, it_idx5)
|
||||
it_idx5: rawptr[llvmlite.Value] = llvmlite.const_int64(pool, 5)
|
||||
it_ipp: rawptr[llvmlite.Value] = llvmlite.build_gep(builder, i64_ty, lm_obj, it_idx5)
|
||||
llvmlite.build_store(builder, llvmlite.const_int64(pool, 0), it_ipp)
|
||||
return lm_obj
|
||||
|
||||
# __len__: 返回 __count__ (偏移 8, index 1)
|
||||
elif string.strcmp(lm_name, "__len__") == 0:
|
||||
l_idx1: llvmlite.Value | t.CPtr = llvmlite.const_int64(pool, 1)
|
||||
l_cpp: llvmlite.Value | t.CPtr = llvmlite.build_gep(builder, i64_ty, lm_obj, l_idx1)
|
||||
l_idx1: rawptr[llvmlite.Value] = llvmlite.const_int64(pool, 1)
|
||||
l_cpp: rawptr[llvmlite.Value] = llvmlite.build_gep(builder, i64_ty, lm_obj, l_idx1)
|
||||
if l_cpp is not None:
|
||||
return llvmlite.build_load(builder, i64_ty, l_cpp)
|
||||
|
||||
@@ -1878,7 +1878,7 @@ class CallGenCall(CallGenBase.CallGenBase):
|
||||
viperlib.snprintf(ap_mangled, ap_mlen, "%s.%s.append",
|
||||
ap_sha1, ap_spec_nm)
|
||||
ap_item_node: rawptr[ast.AST] = cargs.get(0)
|
||||
ap_item_val: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
|
||||
ap_item_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, ap_item_node, None, 0, trans)
|
||||
if ap_item_val is not None:
|
||||
llvmlite.value_set_next(lm_obj, None)
|
||||
@@ -1904,11 +1904,11 @@ class CallGenCall(CallGenBase.CallGenBase):
|
||||
|
||||
# ============================================================
|
||||
def _translate_super_call(self, pool: rawptr[memhub.MemBuddy],
|
||||
builder: llvmlite.IRBuilder | t.CPtr,
|
||||
builder: rawptr[llvmlite.IRBuilder],
|
||||
mod: rawptr[llvmlite.LLVMModule],
|
||||
cl: rawptr[ast.Call],
|
||||
method_name: str,
|
||||
trans: rawptr[HT.Translator]) -> llvmlite.Value | t.CPtr:
|
||||
trans: rawptr[HT.Translator]) -> rawptr[llvmlite.Value]:
|
||||
"""super().method(args) → 父类方法静态调用,返回 call 结果 Value"""
|
||||
if pool is None or builder is None or cl is None or method_name is None:
|
||||
return None
|
||||
@@ -1919,7 +1919,7 @@ class CallGenCall(CallGenBase.CallGenBase):
|
||||
# 不用 Mixin 字段:TPV Mixin 字段按声明类独立布局(Generator 多继承
|
||||
# 去重只保留首个声明),ClassGenMixin 写的 CurClassName 与 CallGenMixin
|
||||
# 读的位置偏移不一致 → 运行时读到空 → super() 误报"只能在类方法内使用"。
|
||||
self_entry: GenTypes.VarEntry | t.CPtr = self.Gen.VarGen.lookup_var_entry(
|
||||
self_entry: rawptr[GenTypes.VarEntry] = self.Gen.VarGen.lookup_var_entry(
|
||||
trans.SymTab, "self")
|
||||
if self_entry is None:
|
||||
self_entry = self.Gen.VarGen.lookup_var_entry(trans.SymTab, "cls")
|
||||
@@ -1956,7 +1956,7 @@ class CallGenCall(CallGenBase.CallGenBase):
|
||||
if self_entry.Alloca is None or self_entry.Alloca.Ty is None:
|
||||
self.Gen.TypeGenErr.fatal_error(cl, "super(): 当前作用域无 self 变量(静态方法内不可用)", "TypeError")
|
||||
return None
|
||||
self_ptr: llvmlite.Value | t.CPtr = None
|
||||
self_ptr: rawptr[llvmlite.Value] = None
|
||||
match self_entry.Alloca.Ty:
|
||||
case llvmlite.LLVMType.Ptr(inner1):
|
||||
match inner1:
|
||||
@@ -1970,14 +1970,14 @@ class CallGenCall(CallGenBase.CallGenBase):
|
||||
if self_ptr is None:
|
||||
return None
|
||||
# 3. this_adjust(字节偏移法:父类字段区在子类中的偏移差)
|
||||
self_arg: llvmlite.Value | t.CPtr = self_ptr
|
||||
self_arg: rawptr[llvmlite.Value] = self_ptr
|
||||
if string.strcmp(anc, cur_class) != 0:
|
||||
anc_entry_sp: GenTypes.StructEntry | t.CPtr = self.Gen.StructGen.find_struct(anc)
|
||||
anc_entry_sp: rawptr[GenTypes.StructEntry] = self.Gen.StructGen.find_struct(anc)
|
||||
if anc_entry_sp is not None and anc_entry_sp.FieldCount > 0:
|
||||
first_name_sp: str = None
|
||||
afi_sp: int = 0
|
||||
while afi_sp < anc_entry_sp.FieldCount:
|
||||
afe_sp: GenTypes.FieldEntry | t.CPtr = self.Gen.StructGen._get_field_entry(
|
||||
afe_sp: rawptr[GenTypes.FieldEntry] = self.Gen.StructGen._get_field_entry(
|
||||
anc_entry_sp, afi_sp)
|
||||
if afe_sp is not None:
|
||||
afn_sp: str = self.Gen.StructGen.get_field_name_ptr(afe_sp)
|
||||
@@ -1986,12 +1986,12 @@ class CallGenCall(CallGenBase.CallGenBase):
|
||||
break
|
||||
afi_sp += 1
|
||||
if first_name_sp is not None:
|
||||
sub_entry_sp: GenTypes.StructEntry | t.CPtr = self.Gen.StructGen.find_struct(
|
||||
sub_entry_sp: rawptr[GenTypes.StructEntry] = self.Gen.StructGen.find_struct(
|
||||
cur_class)
|
||||
if sub_entry_sp is not None:
|
||||
anc_field_sp: GenTypes.FieldEntry | t.CPtr = self.Gen.StructGen.lookup_field(
|
||||
anc_field_sp: rawptr[GenTypes.FieldEntry] = self.Gen.StructGen.lookup_field(
|
||||
anc_entry_sp.Ty, first_name_sp)
|
||||
sub_field_sp: GenTypes.FieldEntry | t.CPtr = self.Gen.StructGen.lookup_field(
|
||||
sub_field_sp: rawptr[GenTypes.FieldEntry] = self.Gen.StructGen.lookup_field(
|
||||
sub_entry_sp.Ty, first_name_sp)
|
||||
if anc_field_sp is not None and sub_field_sp is not None:
|
||||
anc_off_sp: int = self._field_byte_offset(
|
||||
@@ -2002,10 +2002,10 @@ class CallGenCall(CallGenBase.CallGenBase):
|
||||
if delta_sp > 0:
|
||||
i8_ty_sp: rawptr[llvmlite.LLVMType] = llvmlite.Int8(pool)
|
||||
i8_ptr_sp: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, i8_ty_sp)
|
||||
obj_i8_sp: llvmlite.Value | t.CPtr = llvmlite.build_bitcast(
|
||||
obj_i8_sp: rawptr[llvmlite.Value] = llvmlite.build_bitcast(
|
||||
builder, self_ptr, i8_ptr_sp)
|
||||
dval_sp: llvmlite.Value | t.CPtr = llvmlite.const_int32(pool, delta_sp)
|
||||
adj_sp: llvmlite.Value | t.CPtr = llvmlite.build_gep(
|
||||
dval_sp: rawptr[llvmlite.Value] = llvmlite.const_int32(pool, delta_sp)
|
||||
adj_sp: rawptr[llvmlite.Value] = llvmlite.build_gep(
|
||||
builder, i8_ty_sp, obj_i8_sp, dval_sp)
|
||||
if adj_sp is not None:
|
||||
anc_ptr_sp: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, anc_entry_sp.Ty)
|
||||
@@ -2033,20 +2033,20 @@ class CallGenCall(CallGenBase.CallGenBase):
|
||||
if mangled_sp is not None:
|
||||
call_name = mangled_sp
|
||||
# 5. 翻译参数 + 按形参 coerce(self 是形参 0,第 ai 个实参对应形参 ai+1)
|
||||
cargs_sp: list[rawptr[ast.AST]] | t.CPtr = cl.args
|
||||
cargs_sp: rawptr[list[rawptr[ast.AST]]] = cl.args
|
||||
can_sp: sizet = 0
|
||||
if cargs_sp is not None:
|
||||
can_sp = len(cargs_sp)
|
||||
llvmlite.value_set_next(self_arg, None)
|
||||
head: llvmlite.Value | t.CPtr = self_arg
|
||||
tail: llvmlite.Value | t.CPtr = self_arg
|
||||
head: rawptr[llvmlite.Value] = self_arg
|
||||
tail: rawptr[llvmlite.Value] = self_arg
|
||||
arg_count_sp: int = 1
|
||||
for ai_sp in range(can_sp):
|
||||
arg_node_sp: rawptr[ast.AST] = cargs_sp.get(ai_sp)
|
||||
if arg_node_sp is None:
|
||||
continue
|
||||
# 先取形参类型(char 字面量 → str 形参需物化字符串,见 translate_constant)
|
||||
pp_sp: llvmlite.Param | t.CPtr = None
|
||||
pp_sp: rawptr[llvmlite.Param] = None
|
||||
pty_sp: rawptr[llvmlite.LLVMType] = None
|
||||
if found_func is not None:
|
||||
pp_sp = llvmlite.function_get_param_head(found_func)
|
||||
@@ -2058,7 +2058,7 @@ class CallGenCall(CallGenBase.CallGenBase):
|
||||
pi_sp += 1
|
||||
if pp_sp is not None:
|
||||
pty_sp = llvmlite.param_get_ty(pp_sp)
|
||||
arg_val_sp: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
|
||||
arg_val_sp: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, arg_node_sp, None, 0, trans, pty_sp)
|
||||
if arg_val_sp is None:
|
||||
continue
|
||||
@@ -2073,7 +2073,7 @@ class CallGenCall(CallGenBase.CallGenBase):
|
||||
if arr_pointee_sp is not None:
|
||||
match arr_pointee_sp:
|
||||
case llvmlite.LLVMType.Array(arr_et_sp, _):
|
||||
decayed_sp: llvmlite.Value | t.CPtr = llvmlite.build_gep_array(
|
||||
decayed_sp: rawptr[llvmlite.Value] = llvmlite.build_gep_array(
|
||||
builder, arr_pointee_sp, arr_et_sp, arg_val_sp,
|
||||
llvmlite.const_int32(pool, 0))
|
||||
if decayed_sp is not None:
|
||||
@@ -2128,7 +2128,7 @@ class CallGenCall(CallGenBase.CallGenBase):
|
||||
|
||||
# ============================================================
|
||||
def _field_byte_offset(self, pool: rawptr[memhub.MemBuddy],
|
||||
entry: GenTypes.StructEntry | t.CPtr,
|
||||
entry: rawptr[GenTypes.StructEntry],
|
||||
field_index: int) -> int:
|
||||
"""计算字段在结构体中的字节偏移(含对齐 padding),无法计算返回 0"""
|
||||
if pool is None or entry is None or entry.Ty is None or field_index < 0:
|
||||
@@ -2139,7 +2139,7 @@ class CallGenCall(CallGenBase.CallGenBase):
|
||||
# packed(@c.Attribute(t.attr.packed))结构体无字段填充:
|
||||
# 偏移 = 前序字段尺寸之和(LLVM packed struct 布局)。
|
||||
is_packed_fb: int = entry.IsPacked
|
||||
cur_fb: rawptr[llvmlite.Function] = fields
|
||||
cur_fb: rawptr[llvmlite.ParamNode] = fields
|
||||
i_fb: int = 0
|
||||
while cur_fb is not None and i_fb < field_index:
|
||||
if cur_fb.Ty is not None:
|
||||
|
||||
@@ -33,15 +33,15 @@ class CallGenCtor(CallGenBase.CallGenBase):
|
||||
# 显式参数(位置/关键字)后续会覆盖默认值
|
||||
# ============================================================
|
||||
def _apply_struct_defaults(self, pool: rawptr[memhub.MemBuddy],
|
||||
builder: llvmlite.IRBuilder | t.CPtr,
|
||||
builder: rawptr[llvmlite.IRBuilder],
|
||||
mod: rawptr[llvmlite.LLVMModule],
|
||||
struct_ty: rawptr[llvmlite.LLVMType],
|
||||
class_name: str,
|
||||
tmp: llvmlite.Value | t.CPtr,
|
||||
tmp: rawptr[llvmlite.Value],
|
||||
trans: rawptr[HT.Translator]):
|
||||
"""应用结构体字段的默认值"""
|
||||
# 用类型指针定位 entry,规避跨模块同名 find_struct 找错
|
||||
entry: GenTypes.StructEntry | t.CPtr = self.Gen.StructGen.find_struct_by_type(struct_ty)
|
||||
entry: rawptr[GenTypes.StructEntry] = self.Gen.StructGen.find_struct_by_type(struct_ty)
|
||||
if entry is None:
|
||||
# fast-fail: 结构体类型未注册,静默 return 会导致字段未初始化
|
||||
VLogger.error(
|
||||
@@ -49,7 +49,7 @@ class CallGenCtor(CallGenBase.CallGenBase):
|
||||
"HandlesExprCall")
|
||||
return
|
||||
for fi in range(entry.FieldCount):
|
||||
fe: GenTypes.FieldEntry | t.CPtr = self.Gen.StructGen._get_field_entry(
|
||||
fe: rawptr[GenTypes.FieldEntry] = self.Gen.StructGen._get_field_entry(
|
||||
entry, fi)
|
||||
if fe is None:
|
||||
# fast-fail: 字段索引越界(entry.FieldCount 与实际不一致)
|
||||
@@ -65,16 +65,16 @@ class CallGenCtor(CallGenBase.CallGenBase):
|
||||
# Mixin 静态绑定:跨 Mixin 方法必须走 HandlesAnnAssign 模块级委托。
|
||||
if fe.Ty is not None and self.Gen.ExprGenBase.is_array_type(fe.Ty) != 0 \
|
||||
and fe.DefaultVal.kind() == ast.ASTKind.List:
|
||||
field_ptr_arr2: llvmlite.Value | t.CPtr = llvmlite.build_gep_struct(
|
||||
field_ptr_arr2: rawptr[llvmlite.Value] = llvmlite.build_gep_struct(
|
||||
builder, struct_ty, fe.Ty, tmp, fe.Index)
|
||||
if field_ptr_arr2 is not None:
|
||||
zero_arr2: llvmlite.Value | t.CPtr = llvmlite.ConstZero(pool, fe.Ty)
|
||||
zero_arr2: rawptr[llvmlite.Value] = llvmlite.ConstZero(pool, fe.Ty)
|
||||
if zero_arr2 is not None:
|
||||
llvmlite.build_store(builder, zero_arr2, field_ptr_arr2)
|
||||
self.Gen.AssignGen._init_global_array_from_list(
|
||||
builder, pool, mod, field_ptr_arr2, fe.DefaultVal, trans)
|
||||
continue
|
||||
default_val: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
|
||||
default_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, fe.DefaultVal, None, 0, trans, fe.Ty)
|
||||
if default_val is None:
|
||||
# fast-fail: 默认值翻译失败(如引用了未定义符号)
|
||||
@@ -82,7 +82,7 @@ class CallGenCtor(CallGenBase.CallGenBase):
|
||||
f"字段默认值翻译失败: {class_name}",
|
||||
"HandlesExprCall")
|
||||
continue
|
||||
field_ptr: llvmlite.Value | t.CPtr = llvmlite.build_gep_struct(
|
||||
field_ptr: rawptr[llvmlite.Value] = llvmlite.build_gep_struct(
|
||||
builder, struct_ty, fe.Ty, tmp, fe.Index)
|
||||
if field_ptr is None:
|
||||
# fast-fail: GEP 失败(struct_ty 与 fe.Ty 不匹配)
|
||||
@@ -107,13 +107,13 @@ class CallGenCtor(CallGenBase.CallGenBase):
|
||||
|
||||
# ============================================================
|
||||
def _translate_struct_ctor(self, pool: rawptr[memhub.MemBuddy],
|
||||
builder: llvmlite.IRBuilder | t.CPtr,
|
||||
builder: rawptr[llvmlite.IRBuilder],
|
||||
mod: rawptr[llvmlite.LLVMModule],
|
||||
struct_ty: rawptr[llvmlite.LLVMType],
|
||||
class_name: str,
|
||||
cargs: list[rawptr[ast.AST]] | t.CPtr,
|
||||
cargs: rawptr[list[rawptr[ast.AST]]],
|
||||
can: sizet,
|
||||
trans: rawptr[HT.Translator]) -> llvmlite.Value | t.CPtr:
|
||||
trans: rawptr[HT.Translator]) -> rawptr[llvmlite.Value]:
|
||||
"""结构体构造函数:按字段顺序 store 参数值,返回结构体值
|
||||
|
||||
OOP 结构体:alloca → call __before_init__(ptr) → call __init__(ptr, args) 或 store 参数 → load
|
||||
@@ -122,7 +122,7 @@ class CallGenCtor(CallGenBase.CallGenBase):
|
||||
# 创建临时 alloca
|
||||
# 确保跨模块结构体的完整定义在当前模块中可用(供 alloca 分配空间)
|
||||
self.Gen.StructGen.ensure_struct_def_in_module(pool, mod, struct_ty)
|
||||
tmp: llvmlite.Value | t.CPtr = self.Gen.VarGen._alloca_at_entry(builder, struct_ty)
|
||||
tmp: rawptr[llvmlite.Value] = self.Gen.VarGen._alloca_at_entry(builder, struct_ty)
|
||||
if tmp is None:
|
||||
return llvmlite.ConstZero(pool, struct_ty)
|
||||
# 诊断节点:取第一个构造实参(有行号),供 _call_method_on_ptr 的
|
||||
@@ -132,7 +132,7 @@ class CallGenCtor(CallGenBase.CallGenBase):
|
||||
diag_node_ct = cargs.get(0)
|
||||
|
||||
# 检查是否为 OOP 结构体(用类型指针定位 entry,规避跨模块同名 find_struct 找错)
|
||||
ctor_entry: GenTypes.StructEntry | t.CPtr = self.Gen.StructGen.find_struct_by_type(struct_ty)
|
||||
ctor_entry: rawptr[GenTypes.StructEntry] = self.Gen.StructGen.find_struct_by_type(struct_ty)
|
||||
is_oop: int = 0
|
||||
if ctor_entry is not None:
|
||||
is_oop = ctor_entry.IsOOP
|
||||
@@ -153,7 +153,7 @@ class CallGenCtor(CallGenBase.CallGenBase):
|
||||
ctor_entry.HasInit = 1
|
||||
else:
|
||||
# 方案2: 检查全局默认参数表(翻译时填充,不依赖 stub 注入)
|
||||
init_defaults_entry: GenTypes.FuncDefaultsEntry | t.CPtr = self.Gen.CallGenLeafKit.find_func_defaults(init_lookup_name)
|
||||
init_defaults_entry: rawptr[GenTypes.FuncDefaultsEntry] = self.Gen.CallGenLeafKit.find_func_defaults(init_lookup_name)
|
||||
if init_defaults_entry is not None:
|
||||
is_oop = 1
|
||||
if ctor_entry is not None:
|
||||
@@ -162,7 +162,7 @@ class CallGenCtor(CallGenBase.CallGenBase):
|
||||
|
||||
if is_oop != 0:
|
||||
# 存储指针:默认用 alloca,如果有 __new__ 则用 __new__ 返回的指针
|
||||
storage_ptr: llvmlite.Value | t.CPtr = tmp
|
||||
storage_ptr: rawptr[llvmlite.Value] = tmp
|
||||
|
||||
# 如果有 __new__,调用 __new__(tmp, args...) 获取实际存储指针
|
||||
# __new__ 签名与 __init__ 一样(self + args),返回 Ptr(struct_ty)
|
||||
@@ -179,14 +179,14 @@ class CallGenCtor(CallGenBase.CallGenBase):
|
||||
new_arg_node: rawptr[ast.AST] = cargs.get(nai)
|
||||
if new_arg_node is None:
|
||||
continue
|
||||
new_av: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
|
||||
new_av: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
|
||||
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] = sizet(new_av)
|
||||
new_arg_count += 1
|
||||
|
||||
new_ptr: llvmlite.Value | t.CPtr = self.Gen.CallGenCall._call_method_on_ptr(
|
||||
new_ptr: rawptr[llvmlite.Value] = self.Gen.CallGenCall._call_method_on_ptr(
|
||||
pool, builder, mod, class_name,
|
||||
"__new__", tmp, new_arg_vals, new_arg_count, trans, diag_node_ct)
|
||||
if new_ptr is not None:
|
||||
@@ -200,7 +200,7 @@ class CallGenCtor(CallGenBase.CallGenBase):
|
||||
if new_ptr.Ty is not None:
|
||||
nw_ty: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, struct_ty)
|
||||
if uint64(new_ptr.Ty) != uint64(nw_ty):
|
||||
nw_bc: llvmlite.Value | t.CPtr = llvmlite.build_bitcast(builder, new_ptr, nw_ty)
|
||||
nw_bc: rawptr[llvmlite.Value] = llvmlite.build_bitcast(builder, new_ptr, nw_ty)
|
||||
if nw_bc is not None:
|
||||
storage_ptr = nw_bc
|
||||
|
||||
@@ -224,7 +224,7 @@ class CallGenCtor(CallGenBase.CallGenBase):
|
||||
arg_node: rawptr[ast.AST] = cargs.get(ai)
|
||||
if arg_node is None:
|
||||
continue
|
||||
av: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
|
||||
av: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, arg_node, None, 0, trans)
|
||||
if av is not None:
|
||||
if real_arg_count < 32:
|
||||
@@ -242,12 +242,12 @@ class CallGenCtor(CallGenBase.CallGenBase):
|
||||
continue
|
||||
# 先取字段(fe.Ty 用于 char 字面量 → str 字段的物化判定,
|
||||
# 见 translate_constant;否则 coerce inttoptr 字符值当指针崩溃)
|
||||
fe: GenTypes.FieldEntry | t.CPtr = None
|
||||
fe: rawptr[GenTypes.FieldEntry] = None
|
||||
if ctor_entry is not None:
|
||||
# 结构体字段表第 0 个字段是 __vtable__(vtable 指针占位):构造参数按用户字段顺序存储,必须跳过 __vtable__,否则参数覆盖 vtable 槽(对象头读到垃圾指针 → isinstance 全部不匹配 + 方法分派错乱)
|
||||
target_idx: int = 0
|
||||
for fi in range(ctor_entry.FieldCount):
|
||||
cand_fe: GenTypes.FieldEntry | t.CPtr = self.Gen.StructGen._get_field_entry(
|
||||
cand_fe: rawptr[GenTypes.FieldEntry] = self.Gen.StructGen._get_field_entry(
|
||||
ctor_entry, fi)
|
||||
if cand_fe is None:
|
||||
continue
|
||||
@@ -266,7 +266,7 @@ class CallGenCtor(CallGenBase.CallGenBase):
|
||||
f"构造函数参数过多,字段索引越界: {class_name}",
|
||||
"HandlesExprCall")
|
||||
continue
|
||||
arg_val: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
|
||||
arg_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, arg, None, 0, trans, fe.Ty)
|
||||
if arg_val is None:
|
||||
# fast-fail: 参数翻译失败
|
||||
@@ -274,7 +274,7 @@ class CallGenCtor(CallGenBase.CallGenBase):
|
||||
f"构造函数参数翻译失败: {class_name}",
|
||||
"HandlesExprCall")
|
||||
continue
|
||||
field_ptr: llvmlite.Value | t.CPtr = llvmlite.build_gep_struct(
|
||||
field_ptr: rawptr[llvmlite.Value] = llvmlite.build_gep_struct(
|
||||
builder, struct_ty, fe.Ty, storage_ptr, fe.Index)
|
||||
if field_ptr is None:
|
||||
# fast-fail: GEP 失败(struct_ty 与 fe.Ty 不匹配)
|
||||
@@ -289,7 +289,7 @@ class CallGenCtor(CallGenBase.CallGenBase):
|
||||
return storage_ptr
|
||||
|
||||
# 普通结构体:先 store zeroinitializer 清零(确保未赋值字段为零)
|
||||
zero: llvmlite.Value | t.CPtr = llvmlite.ConstZero(pool, struct_ty)
|
||||
zero: rawptr[llvmlite.Value] = llvmlite.ConstZero(pool, struct_ty)
|
||||
llvmlite.build_store(builder, zero, tmp)
|
||||
|
||||
# 应用默认值(显式参数会覆盖默认值)
|
||||
@@ -301,7 +301,7 @@ class CallGenCtor(CallGenBase.CallGenBase):
|
||||
if arg is None:
|
||||
continue
|
||||
# 先取字段(fe.Ty 用于 char 字面量 → str 字段的物化判定,见 translate_constant)
|
||||
fe: GenTypes.FieldEntry | t.CPtr = None
|
||||
fe: rawptr[GenTypes.FieldEntry] = None
|
||||
if ctor_entry is not None:
|
||||
fe = self.Gen.StructGen._get_field_entry(ctor_entry, ai)
|
||||
else:
|
||||
@@ -312,7 +312,7 @@ class CallGenCtor(CallGenBase.CallGenBase):
|
||||
f"构造函数参数过多,字段索引越界: {class_name}",
|
||||
"HandlesExprCall")
|
||||
continue
|
||||
arg_val: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
|
||||
arg_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, arg, None, 0, trans, fe.Ty)
|
||||
if arg_val is None:
|
||||
# fast-fail: 参数翻译失败
|
||||
@@ -321,7 +321,7 @@ class CallGenCtor(CallGenBase.CallGenBase):
|
||||
"HandlesExprCall")
|
||||
continue
|
||||
# GEP 到字段 ai
|
||||
field_ptr: llvmlite.Value | t.CPtr = llvmlite.build_gep_struct(
|
||||
field_ptr: rawptr[llvmlite.Value] = llvmlite.build_gep_struct(
|
||||
builder, struct_ty, fe.Ty, tmp, fe.Index)
|
||||
if field_ptr is None:
|
||||
# fast-fail: GEP 失败(struct_ty 与 fe.Ty 不匹配)
|
||||
@@ -356,14 +356,14 @@ class CallGenCtor(CallGenBase.CallGenBase):
|
||||
|
||||
# ============================================================
|
||||
def _translate_renum_construct(self, pool: rawptr[memhub.MemBuddy],
|
||||
builder: llvmlite.IRBuilder | t.CPtr,
|
||||
builder: rawptr[llvmlite.IRBuilder],
|
||||
mod: rawptr[llvmlite.LLVMModule],
|
||||
class_name: str,
|
||||
variant_name: str,
|
||||
tag_value: int,
|
||||
cargs: list[rawptr[ast.AST]] | t.CPtr,
|
||||
cargs: rawptr[list[rawptr[ast.AST]]],
|
||||
can: sizet,
|
||||
trans: rawptr[HT.Translator]) -> llvmlite.Value | t.CPtr:
|
||||
trans: rawptr[HT.Translator]) -> rawptr[llvmlite.Value]:
|
||||
"""构造 REnum 变体实例,返回指向 alloca 的指针
|
||||
|
||||
class_name: REnum 类名(如 "LLVMType")
|
||||
@@ -376,7 +376,7 @@ class CallGenCtor(CallGenBase.CallGenBase):
|
||||
return None
|
||||
|
||||
# 查找 REnum 结构体类型(用 find_struct_by_module 规避跨模块同名)
|
||||
renum_entry: GenTypes.StructEntry | t.CPtr = None
|
||||
renum_entry: rawptr[GenTypes.StructEntry] = None
|
||||
if trans is not None:
|
||||
renum_entry = self.Gen.StructGen.find_struct_by_module(class_name, trans.ModuleSha1)
|
||||
if renum_entry is None:
|
||||
@@ -392,12 +392,12 @@ class CallGenCtor(CallGenBase.CallGenBase):
|
||||
# alloca REnum 类型
|
||||
# 确保跨模块结构体的完整定义在当前模块中可用(供 alloca 分配空间)
|
||||
self.Gen.StructGen.ensure_struct_def_in_module(pool, mod, renum_ty)
|
||||
tmp: llvmlite.Value | t.CPtr = self.Gen.VarGen._alloca_at_entry(builder, renum_ty)
|
||||
tmp: rawptr[llvmlite.Value] = self.Gen.VarGen._alloca_at_entry(builder, renum_ty)
|
||||
if tmp is None:
|
||||
return llvmlite.ConstZero(pool, renum_ty)
|
||||
|
||||
# 清零(确保未赋值的 payload 位置为零)
|
||||
zero: llvmlite.Value | t.CPtr = llvmlite.ConstZero(pool, renum_ty)
|
||||
zero: rawptr[llvmlite.Value] = llvmlite.ConstZero(pool, renum_ty)
|
||||
llvmlite.build_store(builder, zero, tmp)
|
||||
|
||||
# 写入 __tag 字段(索引 0)
|
||||
@@ -405,14 +405,14 @@ class CallGenCtor(CallGenBase.CallGenBase):
|
||||
tag_name_buf: str = pool.alloc(32)
|
||||
if tag_name_buf is not None:
|
||||
viperlib.snprintf(tag_name_buf, 32, "%d", tag_value)
|
||||
tag_const: llvmlite.Value | t.CPtr = llvmlite.ConstInt(
|
||||
tag_const: rawptr[llvmlite.Value] = llvmlite.ConstInt(
|
||||
pool, i32_ty, tag_value,
|
||||
tag_name_buf if tag_name_buf is not None else "0")
|
||||
tag_field: GenTypes.FieldEntry | t.CPtr = self.Gen.StructGen._get_field_entry(renum_entry, 0)
|
||||
tag_field: rawptr[GenTypes.FieldEntry] = self.Gen.StructGen._get_field_entry(renum_entry, 0)
|
||||
tag_field_ty: rawptr[llvmlite.LLVMType] = i32_ty
|
||||
if tag_field is not None and tag_field.Ty is not None:
|
||||
tag_field_ty = tag_field.Ty
|
||||
tag_ptr: llvmlite.Value | t.CPtr = llvmlite.build_gep_struct(
|
||||
tag_ptr: rawptr[llvmlite.Value] = llvmlite.build_gep_struct(
|
||||
builder, renum_ty, tag_field_ty, tmp, 0)
|
||||
if tag_ptr is not None:
|
||||
llvmlite.build_store(builder, tag_const, tag_ptr)
|
||||
@@ -428,15 +428,15 @@ class CallGenCtor(CallGenBase.CallGenBase):
|
||||
payload_idx: int = ai + 1
|
||||
if payload_idx >= renum_entry.FieldCount:
|
||||
break
|
||||
pfe: GenTypes.FieldEntry | t.CPtr = self.Gen.StructGen._get_field_entry(
|
||||
pfe: rawptr[GenTypes.FieldEntry] = self.Gen.StructGen._get_field_entry(
|
||||
renum_entry, payload_idx)
|
||||
if pfe is None:
|
||||
continue
|
||||
arg_val: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
|
||||
arg_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, arg, None, 0, trans, pfe.Ty)
|
||||
if arg_val is None:
|
||||
continue
|
||||
payload_ptr: llvmlite.Value | t.CPtr = llvmlite.build_gep_struct(
|
||||
payload_ptr: rawptr[llvmlite.Value] = llvmlite.build_gep_struct(
|
||||
builder, renum_ty, pfe.Ty, tmp, payload_idx)
|
||||
if payload_ptr is None:
|
||||
continue
|
||||
@@ -458,20 +458,20 @@ class CallGenCtor(CallGenBase.CallGenBase):
|
||||
|
||||
# ============================================================
|
||||
def _translate_struct_ctor_kw(self, pool: rawptr[memhub.MemBuddy],
|
||||
builder: llvmlite.IRBuilder | t.CPtr,
|
||||
builder: rawptr[llvmlite.IRBuilder],
|
||||
mod: rawptr[llvmlite.LLVMModule],
|
||||
struct_ty: rawptr[llvmlite.LLVMType],
|
||||
class_name: str,
|
||||
cargs: list[rawptr[ast.AST]] | t.CPtr,
|
||||
cargs: rawptr[list[rawptr[ast.AST]]],
|
||||
can: sizet,
|
||||
keywords: list[rawptr[ast.AST]] | t.CPtr,
|
||||
keywords: rawptr[list[rawptr[ast.AST]]],
|
||||
kw_count: sizet,
|
||||
trans: rawptr[HT.Translator]) -> llvmlite.Value | t.CPtr:
|
||||
trans: rawptr[HT.Translator]) -> rawptr[llvmlite.Value]:
|
||||
"""结构体构造函数(关键字参数版本)"""
|
||||
# 创建临时 alloca
|
||||
# 确保跨模块结构体的完整定义在当前模块中可用(供 alloca 分配空间)
|
||||
self.Gen.StructGen.ensure_struct_def_in_module(pool, mod, struct_ty)
|
||||
tmp: llvmlite.Value | t.CPtr = self.Gen.VarGen._alloca_at_entry(builder, struct_ty)
|
||||
tmp: rawptr[llvmlite.Value] = self.Gen.VarGen._alloca_at_entry(builder, struct_ty)
|
||||
if tmp is None:
|
||||
return llvmlite.ConstZero(pool, struct_ty)
|
||||
# 诊断节点:取第一个构造实参(有行号),供 _call_method_on_ptr 的
|
||||
@@ -482,7 +482,7 @@ class CallGenCtor(CallGenBase.CallGenBase):
|
||||
|
||||
# OOP 结构体:调用 __before_init__ 进行零值填充和默认值赋值
|
||||
# 用 find_struct_by_type 规避跨模块同名 find_struct 找错
|
||||
kw_entry: GenTypes.StructEntry | t.CPtr = self.Gen.StructGen.find_struct_by_type(struct_ty)
|
||||
kw_entry: rawptr[GenTypes.StructEntry] = self.Gen.StructGen.find_struct_by_type(struct_ty)
|
||||
is_oop: int = 0
|
||||
if kw_entry is not None:
|
||||
is_oop = kw_entry.IsOOP
|
||||
@@ -503,7 +503,7 @@ class CallGenCtor(CallGenBase.CallGenBase):
|
||||
kw_entry.HasInit = 1
|
||||
else:
|
||||
# 方案2: 检查全局默认参数表(翻译时填充,不依赖 stub 注入)
|
||||
kw_init_defaults: GenTypes.FuncDefaultsEntry | t.CPtr = self.Gen.CallGenLeafKit.find_func_defaults(kw_init_lookup)
|
||||
kw_init_defaults: rawptr[GenTypes.FuncDefaultsEntry] = self.Gen.CallGenLeafKit.find_func_defaults(kw_init_lookup)
|
||||
if kw_init_defaults is not None:
|
||||
is_oop = 1
|
||||
if kw_entry is not None:
|
||||
@@ -515,7 +515,7 @@ class CallGenCtor(CallGenBase.CallGenBase):
|
||||
"__before_init__", tmp, None, 0, trans)
|
||||
else:
|
||||
# 普通结构体:store zeroinitializer + 应用默认值
|
||||
zero: llvmlite.Value | t.CPtr = llvmlite.ConstZero(pool, struct_ty)
|
||||
zero: rawptr[llvmlite.Value] = llvmlite.ConstZero(pool, struct_ty)
|
||||
llvmlite.build_store(builder, zero, tmp)
|
||||
self._apply_struct_defaults(pool, builder, mod, struct_ty, class_name, tmp, trans)
|
||||
|
||||
@@ -536,7 +536,7 @@ class CallGenCtor(CallGenBase.CallGenBase):
|
||||
|
||||
if is_oop != 0 and has_init_flag != 0:
|
||||
# 有 __init__:构建参数数组并调用 __init__
|
||||
storage_ptr: llvmlite.Value | t.CPtr = tmp
|
||||
storage_ptr: rawptr[llvmlite.Value] = tmp
|
||||
|
||||
# 如果有 __new__,调用 __new__ 获取实际存储指针
|
||||
if has_new_flag != 0:
|
||||
@@ -548,7 +548,7 @@ class CallGenCtor(CallGenBase.CallGenBase):
|
||||
new_arg_node: rawptr[ast.AST] = cargs.get(nai)
|
||||
if new_arg_node is None:
|
||||
continue
|
||||
new_av: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
|
||||
new_av: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, new_arg_node, None, 0, trans)
|
||||
if new_av is not None:
|
||||
if new_arg_count < 32:
|
||||
@@ -556,16 +556,16 @@ class CallGenCtor(CallGenBase.CallGenBase):
|
||||
new_arg_count += 1
|
||||
# 关键字参数也传递给 __new__
|
||||
for nki in range(kw_count):
|
||||
nkw: ast.Keyword | t.CPtr = (ast.Keyword | t.CPtr)(keywords.get(nki))
|
||||
nkw: rawptr[ast.Keyword] = rawptr[ast.Keyword](keywords.get(nki))
|
||||
if nkw is None or nkw.value is None:
|
||||
continue
|
||||
nkw_av: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
|
||||
nkw_av: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
|
||||
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] = sizet(nkw_av)
|
||||
new_arg_count += 1
|
||||
new_ptr: llvmlite.Value | t.CPtr = self.Gen.CallGenCall._call_method_on_ptr(
|
||||
new_ptr: rawptr[llvmlite.Value] = self.Gen.CallGenCall._call_method_on_ptr(
|
||||
pool, builder, mod, class_name,
|
||||
"__new__", tmp, new_arg_vals, new_arg_count, trans, diag_node_ct)
|
||||
if new_ptr is not None:
|
||||
@@ -579,7 +579,7 @@ class CallGenCtor(CallGenBase.CallGenBase):
|
||||
if new_ptr.Ty is not None:
|
||||
nw_ty: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, struct_ty)
|
||||
if uint64(new_ptr.Ty) != uint64(nw_ty):
|
||||
nw_bc: llvmlite.Value | t.CPtr = llvmlite.build_bitcast(builder, new_ptr, nw_ty)
|
||||
nw_bc: rawptr[llvmlite.Value] = llvmlite.build_bitcast(builder, new_ptr, nw_ty)
|
||||
if nw_bc is not None:
|
||||
storage_ptr = nw_bc
|
||||
|
||||
@@ -593,7 +593,7 @@ class CallGenCtor(CallGenBase.CallGenBase):
|
||||
arg_node_init: rawptr[ast.AST] = cargs.get(ai_init)
|
||||
if arg_node_init is None:
|
||||
continue
|
||||
av_init: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
|
||||
av_init: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, arg_node_init, None, 0, trans)
|
||||
if av_init is not None:
|
||||
if init_arg_count < 32:
|
||||
@@ -601,10 +601,10 @@ class CallGenCtor(CallGenBase.CallGenBase):
|
||||
init_arg_count += 1
|
||||
# 关键字参数(追加到末尾,按出现顺序)
|
||||
for ki_init in range(kw_count):
|
||||
kw_init: ast.Keyword | t.CPtr = (ast.Keyword | t.CPtr)(keywords.get(ki_init))
|
||||
kw_init: rawptr[ast.Keyword] = rawptr[ast.Keyword](keywords.get(ki_init))
|
||||
if kw_init is None or kw_init.value is None:
|
||||
continue
|
||||
kw_av_init: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
|
||||
kw_av_init: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, kw_init.value, None, 0, trans)
|
||||
if kw_av_init is not None:
|
||||
if init_arg_count < 32:
|
||||
@@ -625,7 +625,7 @@ class CallGenCtor(CallGenBase.CallGenBase):
|
||||
if arg is None:
|
||||
continue
|
||||
# 先取字段(fe.Ty 用于 char 字面量 → str 字段的物化判定,见 translate_constant)
|
||||
fe: GenTypes.FieldEntry | t.CPtr = None
|
||||
fe: rawptr[GenTypes.FieldEntry] = None
|
||||
if kw_entry is not None:
|
||||
fe = self.Gen.StructGen._get_field_entry(kw_entry, ai)
|
||||
else:
|
||||
@@ -635,11 +635,11 @@ class CallGenCtor(CallGenBase.CallGenBase):
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
arg, f"结构体 '{class_name}' 位置参数越界(无对应字段)", "TypeError")
|
||||
continue
|
||||
arg_val: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
|
||||
arg_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, arg, None, 0, trans, fe.Ty)
|
||||
if arg_val is None:
|
||||
continue
|
||||
field_ptr: llvmlite.Value | t.CPtr = llvmlite.build_gep_struct(
|
||||
field_ptr: rawptr[llvmlite.Value] = llvmlite.build_gep_struct(
|
||||
builder, struct_ty, fe.Ty, tmp, fe.Index)
|
||||
if field_ptr is None:
|
||||
continue
|
||||
@@ -652,21 +652,21 @@ class CallGenCtor(CallGenBase.CallGenBase):
|
||||
if kw_entry is not None:
|
||||
kw_sha1 = kw_entry.ModuleSha1
|
||||
for ki in range(kw_count):
|
||||
kw: ast.Keyword | t.CPtr = (ast.Keyword | t.CPtr)(keywords.get(ki))
|
||||
kw: rawptr[ast.Keyword] = rawptr[ast.Keyword](keywords.get(ki))
|
||||
if kw is None or kw.arg is None or kw.value is None:
|
||||
continue
|
||||
fe: GenTypes.FieldEntry | t.CPtr = self.Gen.StructGen.lookup_field_by_class(
|
||||
fe: rawptr[GenTypes.FieldEntry] = self.Gen.StructGen.lookup_field_by_class(
|
||||
class_name, kw.arg, kw_sha1, kw, trans._from_imports)
|
||||
if fe is None:
|
||||
# 关键字字段不存在:fail-fast(AttributeError),绝不静默跳过
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
kw, f"结构体 '{class_name}' 无字段 '{kw.arg}'", "AttributeError")
|
||||
continue
|
||||
kw_val: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
|
||||
kw_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, kw.value, None, 0, trans, fe.Ty)
|
||||
if kw_val is None:
|
||||
continue
|
||||
field_ptr: llvmlite.Value | t.CPtr = llvmlite.build_gep_struct(
|
||||
field_ptr: rawptr[llvmlite.Value] = llvmlite.build_gep_struct(
|
||||
builder, struct_ty, fe.Ty, tmp, fe.Index)
|
||||
if field_ptr is None:
|
||||
continue
|
||||
@@ -691,11 +691,11 @@ class CallGenCtor(CallGenBase.CallGenBase):
|
||||
|
||||
# ============================================================
|
||||
def _translate_t_type_cast(self, pool: rawptr[memhub.MemBuddy],
|
||||
builder: llvmlite.IRBuilder | t.CPtr,
|
||||
val: llvmlite.Value | t.CPtr,
|
||||
builder: rawptr[llvmlite.IRBuilder],
|
||||
val: rawptr[llvmlite.Value],
|
||||
target_ty: rawptr[llvmlite.LLVMType],
|
||||
src_node: rawptr[ast.AST] = None,
|
||||
trans: rawptr[HT.Translator] = None) -> llvmlite.Value | t.CPtr:
|
||||
trans: rawptr[HT.Translator] = None) -> rawptr[llvmlite.Value]:
|
||||
"""类型转换:根据参数类型和目标类型选择转换方式
|
||||
|
||||
整数 → 整数拓宽:拓宽方向由**源**的符号性决定(与 coerce_to_type 的
|
||||
@@ -791,7 +791,7 @@ class CallGenCtor(CallGenBase.CallGenBase):
|
||||
tn: str = None
|
||||
if k == ast.ASTKind.Tuple:
|
||||
tp: rawptr[ast.Tuple] = rawptr[ast.Tuple](slice_node)
|
||||
elts: list[rawptr[ast.AST]] | t.CPtr = tp.elts
|
||||
elts: rawptr[list[rawptr[ast.AST]]] = tp.elts
|
||||
if elts is not None:
|
||||
n: sizet = len(elts)
|
||||
i: sizet
|
||||
@@ -888,7 +888,7 @@ class CallGenCtor(CallGenBase.CallGenBase):
|
||||
if k == ast.ASTKind.Name:
|
||||
nm_i: rawptr[ast.Name] = rawptr[ast.Name](arg_node)
|
||||
if nm_i.id is not None and trans is not None:
|
||||
ve_i: GenTypes.VarEntry | t.CPtr = self.Gen.VarGen.lookup_var_entry(
|
||||
ve_i: rawptr[GenTypes.VarEntry] = self.Gen.VarGen.lookup_var_entry(
|
||||
trans.SymTab, nm_i.id)
|
||||
if ve_i is not None:
|
||||
return self.Gen.VarGen.var_annot_class_name(ve_i)
|
||||
@@ -922,7 +922,7 @@ class CallGenCtor(CallGenBase.CallGenBase):
|
||||
return self._annotation_refers_type_param(bop_a.right, tp_name)
|
||||
return 0
|
||||
|
||||
def _get_ctor_init_params(self, class_name: str) -> list[rawptr[ast.AST]] | t.CPtr:
|
||||
def _get_ctor_init_params(self, class_name: str) -> rawptr[list[rawptr[ast.AST]]]:
|
||||
"""取泛型类模板 __init__ 的形参列表(含 self,形参 0)
|
||||
|
||||
模板不存在 / 无 __init__ / args 形态不可用 → None。
|
||||
@@ -937,7 +937,7 @@ class CallGenCtor(CallGenBase.CallGenBase):
|
||||
template_cd: rawptr[ast.ClassDef] = self.Gen.ClassGenGeneric._find_generic_template(class_name)
|
||||
if template_cd is None or template_cd.children is None:
|
||||
return None
|
||||
children: list[rawptr[ast.AST]] | t.CPtr = template_cd.children
|
||||
children: rawptr[list[rawptr[ast.AST]]] = template_cd.children
|
||||
cn: sizet = len(children)
|
||||
ci: sizet
|
||||
for ci in range(cn):
|
||||
@@ -967,7 +967,7 @@ class CallGenCtor(CallGenBase.CallGenBase):
|
||||
"""
|
||||
if class_name is None or tp_name is None:
|
||||
return -1
|
||||
plist: list[rawptr[ast.AST]] | t.CPtr = self._get_ctor_init_params(class_name)
|
||||
plist: rawptr[list[rawptr[ast.AST]]] = self._get_ctor_init_params(class_name)
|
||||
if plist is None:
|
||||
return -1
|
||||
pn: sizet = len(plist)
|
||||
@@ -1011,7 +1011,7 @@ class CallGenCtor(CallGenBase.CallGenBase):
|
||||
"""
|
||||
if class_name is None or kw_name is None:
|
||||
return -1
|
||||
plist_sb: list[rawptr[ast.AST]] | t.CPtr = self._get_ctor_init_params(class_name)
|
||||
plist_sb: rawptr[list[rawptr[ast.AST]]] = self._get_ctor_init_params(class_name)
|
||||
if plist_sb is None:
|
||||
return -1
|
||||
pn_sb: sizet = len(plist_sb)
|
||||
@@ -1029,7 +1029,7 @@ class CallGenCtor(CallGenBase.CallGenBase):
|
||||
|
||||
def _find_ctor_type_param_kw_arg_index(self, class_name: str,
|
||||
tp_name: str,
|
||||
keywords: list[rawptr[ast.AST]] | t.CPtr,
|
||||
keywords: rawptr[list[rawptr[ast.AST]]],
|
||||
kw_count: sizet,
|
||||
pos_count: int) -> int:
|
||||
"""仅关键字实参的泛型构造:类型形参 tp_name 对应的关键字实参下标
|
||||
@@ -1051,7 +1051,7 @@ class CallGenCtor(CallGenBase.CallGenBase):
|
||||
return -1 # 未找到,或落在 self 位(0 不是实参)
|
||||
if pi_kw - 1 < pos_count:
|
||||
return -1 # 该形参位已被位置实参占用
|
||||
plist_kw: list[rawptr[ast.AST]] | t.CPtr = self._get_ctor_init_params(class_name)
|
||||
plist_kw: rawptr[list[rawptr[ast.AST]]] = self._get_ctor_init_params(class_name)
|
||||
if plist_kw is None:
|
||||
return -1
|
||||
pa_kw: rawptr[ast.AST] = plist_kw.get(sizet(pi_kw))
|
||||
@@ -1062,7 +1062,7 @@ class CallGenCtor(CallGenBase.CallGenBase):
|
||||
return -1
|
||||
ki_kw: sizet
|
||||
for ki_kw in range(kw_count):
|
||||
kw_tp: ast.Keyword | t.CPtr = (ast.Keyword | t.CPtr)(keywords.get(ki_kw))
|
||||
kw_tp: rawptr[ast.Keyword] = rawptr[ast.Keyword](keywords.get(ki_kw))
|
||||
if kw_tp is None or kw_tp.arg is None or kw_tp.value is None:
|
||||
continue
|
||||
if string.strcmp(kw_tp.arg, ag_kw.arg) == 0:
|
||||
@@ -1134,18 +1134,18 @@ class CallGenCtor(CallGenBase.CallGenBase):
|
||||
return type_args_ctx
|
||||
|
||||
def _translate_generic_ctor_call(self, pool: rawptr[memhub.MemBuddy],
|
||||
builder: llvmlite.IRBuilder | t.CPtr,
|
||||
builder: rawptr[llvmlite.IRBuilder],
|
||||
mod: rawptr[llvmlite.LLVMModule],
|
||||
spec_name: str,
|
||||
cl: rawptr[ast.Call],
|
||||
trans: rawptr[HT.Translator],
|
||||
tmpl_name: str = None) -> llvmlite.Value | t.CPtr:
|
||||
tmpl_name: str = None) -> rawptr[llvmlite.Value]:
|
||||
"""泛型类构造调用: list[str](pool, 8) → __new__ + __before_init__ + __init__"""
|
||||
if pool is None or builder is None or mod is None or spec_name is None or cl is None:
|
||||
return None
|
||||
|
||||
# 查找 struct entry 获取类型
|
||||
struct_entry: GenTypes.StructEntry | t.CPtr = self.Gen.StructGen.find_struct(spec_name)
|
||||
struct_entry: rawptr[GenTypes.StructEntry] = self.Gen.StructGen.find_struct(spec_name)
|
||||
if struct_entry is None:
|
||||
self.Gen.TypeGenErr.fatal_error(cl, "泛型类构造调用: 特化类未注册")
|
||||
return None
|
||||
@@ -1157,16 +1157,16 @@ class CallGenCtor(CallGenBase.CallGenBase):
|
||||
self.Gen.StructGen.ensure_struct_def_in_module(pool, mod, struct_ty)
|
||||
|
||||
# alloca tmp(self 指针)
|
||||
tmp: llvmlite.Value | t.CPtr = self.Gen.VarGen._alloca_at_entry(builder, struct_ty)
|
||||
tmp: rawptr[llvmlite.Value] = self.Gen.VarGen._alloca_at_entry(builder, struct_ty)
|
||||
if tmp is None:
|
||||
return None
|
||||
|
||||
# 翻译实参为参数指针数组(extra_args[slot] = Value 指针):位置实参 → 槽 0..can-1;关键字实参 → 按 __init__ 形参名定位槽位(与 _find_ctor_type_param_kw_arg_index 共用同一套形参遍历)。位置实参优先,关键字不可按出现顺序追加——乱序会串位
|
||||
cargs: list[rawptr[ast.AST]] | t.CPtr = cl.args
|
||||
cargs: rawptr[list[rawptr[ast.AST]]] = cl.args
|
||||
can: sizet = 0
|
||||
if cargs is not None:
|
||||
can = len(cargs)
|
||||
keywords: list[rawptr[ast.AST]] | t.CPtr = cl.keywords
|
||||
keywords: rawptr[list[rawptr[ast.AST]]] = cl.keywords
|
||||
kw_count: sizet = 0
|
||||
if keywords is not None:
|
||||
kw_count = len(keywords)
|
||||
@@ -1189,7 +1189,7 @@ class CallGenCtor(CallGenBase.CallGenBase):
|
||||
break
|
||||
arg_node: rawptr[ast.AST] = cargs.get(ai)
|
||||
if arg_node is not None:
|
||||
arg_val: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
|
||||
arg_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, arg_node, None, 0, trans)
|
||||
if arg_val is not None:
|
||||
extra_args[ai] = sizet(arg_val)
|
||||
@@ -1199,7 +1199,7 @@ class CallGenCtor(CallGenBase.CallGenBase):
|
||||
if kw_count > 0:
|
||||
ki_slot: sizet
|
||||
for ki_slot in range(kw_count):
|
||||
kw_slot: ast.Keyword | t.CPtr = (ast.Keyword | t.CPtr)(keywords.get(ki_slot))
|
||||
kw_slot: rawptr[ast.Keyword] = rawptr[ast.Keyword](keywords.get(ki_slot))
|
||||
if kw_slot is None or kw_slot.arg is None or kw_slot.value is None:
|
||||
continue
|
||||
slot_kw: int = self._ctor_init_arg_slot_by_name(tmpl_name, kw_slot.arg)
|
||||
@@ -1220,7 +1220,7 @@ class CallGenCtor(CallGenBase.CallGenBase):
|
||||
# 该形参位已被位置实参/先前关键字占用:位置优先,本次跳过
|
||||
# (先例 same as 上方:_translate_method_call 名匹配)
|
||||
continue
|
||||
kw_val: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
|
||||
kw_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, kw_slot.value, None, 0, trans)
|
||||
if kw_val is None:
|
||||
continue
|
||||
@@ -1247,12 +1247,12 @@ class CallGenCtor(CallGenBase.CallGenBase):
|
||||
# 存储指针:默认用 alloca,如果有 __new__ 则用 __new__ 返回的指针
|
||||
# __new__ 是可选的,仅当泛型类模板定义了 __new__ 方法时才调用
|
||||
# (与 _translate_struct_ctor 保持一致,避免为无 __new__ 的类生成过度声明)
|
||||
storage_ptr: llvmlite.Value | t.CPtr = tmp
|
||||
storage_ptr: rawptr[llvmlite.Value] = tmp
|
||||
has_new_flag: int = 0
|
||||
if struct_entry is not None:
|
||||
has_new_flag = struct_entry.HasNew
|
||||
if has_new_flag != 0:
|
||||
new_ptr: llvmlite.Value | t.CPtr = self.Gen.CallGenCall._call_method_on_ptr(
|
||||
new_ptr: rawptr[llvmlite.Value] = self.Gen.CallGenCall._call_method_on_ptr(
|
||||
pool, builder, mod, spec_name, "__new__", tmp, extra_args, arg_count, trans)
|
||||
if new_ptr is not None:
|
||||
storage_ptr = new_ptr
|
||||
@@ -1265,7 +1265,7 @@ class CallGenCtor(CallGenBase.CallGenBase):
|
||||
if new_ptr.Ty is not None:
|
||||
nw_ty: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, struct_ty)
|
||||
if uint64(new_ptr.Ty) != uint64(nw_ty):
|
||||
nw_bc: llvmlite.Value | t.CPtr = llvmlite.build_bitcast(builder, new_ptr, nw_ty)
|
||||
nw_bc: rawptr[llvmlite.Value] = llvmlite.build_bitcast(builder, new_ptr, nw_ty)
|
||||
if nw_bc is not None:
|
||||
storage_ptr = nw_bc
|
||||
|
||||
|
||||
@@ -34,16 +34,16 @@ class CallGenDispatch(CallGenBase.CallGenBase):
|
||||
"""translate_call 前置检测 helper(继承 Base)"""
|
||||
|
||||
def _tc_h1_super_ctraits(self, pool: rawptr[memhub.MemBuddy],
|
||||
builder: llvmlite.IRBuilder | t.CPtr,
|
||||
builder: rawptr[llvmlite.IRBuilder],
|
||||
mod: rawptr[llvmlite.LLVMModule],
|
||||
cl: rawptr[ast.Call],
|
||||
funcs_ptr: t.CPtr,
|
||||
func_count: int,
|
||||
trans: rawptr[HT.Translator],
|
||||
func_name: str,
|
||||
cargs: list[rawptr[ast.AST]] | t.CPtr,
|
||||
cargs: rawptr[list[rawptr[ast.AST]]],
|
||||
can: sizet,
|
||||
hit_box: t.CPtr = None) -> llvmlite.Value | t.CPtr:
|
||||
hit_box: t.CPtr = None) -> rawptr[llvmlite.Value]:
|
||||
"""super()/ctraits 编译期检测(未命中返回 None)
|
||||
|
||||
hit_box: 命中标志字节([0]=1 表示被本 helper 拦截处理)。
|
||||
@@ -77,7 +77,7 @@ class CallGenDispatch(CallGenBase.CallGenBase):
|
||||
ct_nm: rawptr[ast.Name] = rawptr[ast.Name](ct_at.value)
|
||||
if ct_nm.id is not None and string.strcmp(ct_nm.id, "ctraits") == 0 \
|
||||
and string.strcmp(func_name, "isptr") == 0:
|
||||
ct_args: list[rawptr[ast.AST]] | t.CPtr = cl.args
|
||||
ct_args: rawptr[list[rawptr[ast.AST]]] = cl.args
|
||||
if ct_args is not None and len(ct_args) >= 1:
|
||||
ct_arg0: rawptr[ast.AST] = ct_args.get(0)
|
||||
if ct_arg0 is not None and ct_arg0.kind() == ast.ASTKind.Name:
|
||||
@@ -90,16 +90,16 @@ class CallGenDispatch(CallGenBase.CallGenBase):
|
||||
return None
|
||||
|
||||
def _tc_h2_c_special(self, pool: rawptr[memhub.MemBuddy],
|
||||
builder: llvmlite.IRBuilder | t.CPtr,
|
||||
builder: rawptr[llvmlite.IRBuilder],
|
||||
mod: rawptr[llvmlite.LLVMModule],
|
||||
cl: rawptr[ast.Call],
|
||||
funcs_ptr: t.CPtr,
|
||||
func_count: int,
|
||||
trans: rawptr[HT.Translator],
|
||||
func_name: str,
|
||||
cargs: list[rawptr[ast.AST]] | t.CPtr,
|
||||
cargs: rawptr[list[rawptr[ast.AST]]],
|
||||
can: sizet,
|
||||
hit_box: t.CPtr = None) -> llvmlite.Value | t.CPtr:
|
||||
hit_box: t.CPtr = None) -> rawptr[llvmlite.Value]:
|
||||
"""c.Deref/Asm/LLVMIR 等特殊调用(未命中返回 None)
|
||||
|
||||
hit_box: 命中标记(t.CPtr,[0]=1 表示已识别为 c.* 特殊调用)。
|
||||
@@ -146,20 +146,20 @@ class CallGenDispatch(CallGenBase.CallGenBase):
|
||||
elif string.strcmp(func_name, "CIf") == 0:
|
||||
# 运行时 c.CIf(expr)(编译期求值失败回退):expr 与 0 比较得到 i1
|
||||
# 对齐 TPC HandlesExprCall.py L2434-2444
|
||||
cif_args: list[rawptr[ast.AST]] | t.CPtr = cl.args
|
||||
cif_args: rawptr[list[rawptr[ast.AST]]] = cl.args
|
||||
if cif_args is not None and len(cif_args) >= 1:
|
||||
cif_arg_val: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
|
||||
cif_arg_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, cif_args.get(0), funcs_ptr, func_count, trans)
|
||||
if cif_arg_val is not None:
|
||||
cif_bits: int = self.Gen.ExprGenBase.get_llvm_type_bits(cif_arg_val.Ty)
|
||||
if cif_bits == 1:
|
||||
return cif_arg_val
|
||||
if self.Gen.ExprGenBase.is_ptr_type(cif_arg_val.Ty) != 0:
|
||||
cif_null: llvmlite.Value | t.CPtr = llvmlite.ConstNull(
|
||||
cif_null: rawptr[llvmlite.Value] = llvmlite.ConstNull(
|
||||
pool, cif_arg_val.Ty, "null")
|
||||
return llvmlite.build_icmp(
|
||||
builder, llvmlite.ICMP_NE, cif_arg_val, cif_null)
|
||||
cif_zero: llvmlite.Value | t.CPtr = llvmlite.const_int32(pool, 0)
|
||||
cif_zero: rawptr[llvmlite.Value] = llvmlite.const_int32(pool, 0)
|
||||
return llvmlite.build_icmp(
|
||||
builder, llvmlite.ICMP_NE, cif_arg_val, cif_zero)
|
||||
return llvmlite.ConstInt(pool, llvmlite.Int1(pool), 0, "0")
|
||||
@@ -194,15 +194,15 @@ class CallGenDispatch(CallGenBase.CallGenBase):
|
||||
return None
|
||||
|
||||
def _tc_h3_stdarg_cast(self, pool: rawptr[memhub.MemBuddy],
|
||||
builder: llvmlite.IRBuilder | t.CPtr,
|
||||
builder: rawptr[llvmlite.IRBuilder],
|
||||
mod: rawptr[llvmlite.LLVMModule],
|
||||
cl: rawptr[ast.Call],
|
||||
funcs_ptr: t.CPtr,
|
||||
func_count: int,
|
||||
trans: rawptr[HT.Translator],
|
||||
func_name: str,
|
||||
cargs: list[rawptr[ast.AST]] | t.CPtr,
|
||||
can: sizet) -> llvmlite.Value | t.CPtr:
|
||||
cargs: rawptr[list[rawptr[ast.AST]]],
|
||||
can: sizet) -> rawptr[llvmlite.Value]:
|
||||
"""stdarg 糖 + str/int/bool 内置强转(未命中返回 None)"""
|
||||
# stdarg 糖函数处理: va_arg / arg / va_start / va_end
|
||||
# 这些函数在 stdarg.vp 中声明为 pass 体,由编译器在翻译期处理:
|
||||
@@ -237,7 +237,7 @@ class CallGenDispatch(CallGenBase.CallGenBase):
|
||||
cast_fn_name: str = self.Gen.TypeGenBase.resolve_generic_type_name(func_name)
|
||||
if string.strcmp(cast_fn_name, "str") == 0 or string.strcmp(cast_fn_name, "bytes") == 0:
|
||||
# str(x) / bytes(x) → i8* (bitcast)
|
||||
cast_arg: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
|
||||
cast_arg: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, cargs.get(0), funcs_ptr, func_count, trans)
|
||||
if cast_arg is not None:
|
||||
i8_ptr_ty_builtin: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, llvmlite.Int8(pool))
|
||||
@@ -245,7 +245,7 @@ class CallGenDispatch(CallGenBase.CallGenBase):
|
||||
return None
|
||||
elif string.strcmp(cast_fn_name, "int") == 0:
|
||||
# int(x) → i32
|
||||
cast_arg_int: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
|
||||
cast_arg_int: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, cargs.get(0), funcs_ptr, func_count, trans)
|
||||
if cast_arg_int is not None:
|
||||
i32_ty_builtin: rawptr[llvmlite.LLVMType] = llvmlite.Int32(pool)
|
||||
@@ -256,26 +256,26 @@ class CallGenDispatch(CallGenBase.CallGenBase):
|
||||
# 整数: icmp ne x, 0 → i1
|
||||
# 浮点: fcmp one x, 0.0 → i1
|
||||
# 指针: icmp ne x, null → i1
|
||||
cast_arg_bool: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
|
||||
cast_arg_bool: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, cargs.get(0), funcs_ptr, func_count, trans)
|
||||
if cast_arg_bool is not None:
|
||||
arg_bits: int = self.Gen.ExprGenBase.get_llvm_type_bits(cast_arg_bool.Ty)
|
||||
arg_fbits: int = self.Gen.ExprGenBase.get_llvm_float_bits(cast_arg_bool.Ty)
|
||||
# 整数: icmp ne x, 0
|
||||
if arg_bits != 0:
|
||||
zero_int: llvmlite.Value | t.CPtr = llvmlite.const_int(pool, arg_bits, 0)
|
||||
zero_int: rawptr[llvmlite.Value] = llvmlite.const_int(pool, arg_bits, 0)
|
||||
if zero_int is not None:
|
||||
return llvmlite.build_icmp(builder, llvmlite.ICMP_NE, cast_arg_bool, zero_int)
|
||||
return None
|
||||
# 浮点: fcmp one x, 0.0
|
||||
if arg_fbits != 0:
|
||||
zero_ty: rawptr[llvmlite.LLVMType] = cast_arg_bool.Ty
|
||||
zero_flt: llvmlite.Value | t.CPtr = llvmlite.ConstFloat(pool, zero_ty, 0.0)
|
||||
zero_flt: rawptr[llvmlite.Value] = llvmlite.ConstFloat(pool, zero_ty, 0.0)
|
||||
if zero_flt is not None:
|
||||
return llvmlite.build_fcmp(builder, llvmlite.FCMP_ONE, cast_arg_bool, zero_flt)
|
||||
return None
|
||||
# 指针: icmp ne x, null
|
||||
ptr_null: llvmlite.Value | t.CPtr = llvmlite.ConstNull(pool, cast_arg_bool.Ty, "null")
|
||||
ptr_null: rawptr[llvmlite.Value] = llvmlite.ConstNull(pool, cast_arg_bool.Ty, "null")
|
||||
if ptr_null is not None:
|
||||
return llvmlite.build_icmp(builder, llvmlite.ICMP_NE, cast_arg_bool, ptr_null)
|
||||
return None
|
||||
@@ -283,15 +283,15 @@ class CallGenDispatch(CallGenBase.CallGenBase):
|
||||
return None
|
||||
|
||||
def _tc_h4_type_casts(self, pool: rawptr[memhub.MemBuddy],
|
||||
builder: llvmlite.IRBuilder | t.CPtr,
|
||||
builder: rawptr[llvmlite.IRBuilder],
|
||||
mod: rawptr[llvmlite.LLVMModule],
|
||||
cl: rawptr[ast.Call],
|
||||
funcs_ptr: t.CPtr,
|
||||
func_count: int,
|
||||
trans: rawptr[HT.Translator],
|
||||
func_name: str,
|
||||
cargs: list[rawptr[ast.AST]] | t.CPtr,
|
||||
can: sizet) -> llvmlite.Value | t.CPtr:
|
||||
cargs: rawptr[list[rawptr[ast.AST]]],
|
||||
can: sizet) -> rawptr[llvmlite.Value]:
|
||||
"""t.XXX / typedef 类型转换(未命中返回 None)"""
|
||||
# 检测 t.XXX 类型转换: uint64(ptr), t.CPtr(val), int(val) 等
|
||||
# 当 func 是 t.XXX 形式且 XXX 是已知类型名时,当作类型转换处理(而非函数调用)
|
||||
@@ -349,7 +349,7 @@ class CallGenDispatch(CallGenBase.CallGenBase):
|
||||
ctype_target = llvmlite.Ptr(pool, ctype_target)
|
||||
cty_arg0: rawptr[ast.AST] = cargs.get(0)
|
||||
if cty_arg0 is not None:
|
||||
cty_val: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
|
||||
cty_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, cty_arg0, funcs_ptr, func_count, trans)
|
||||
if cty_val is not None:
|
||||
return self.Gen.CallGenCtor._translate_t_type_cast(
|
||||
@@ -369,7 +369,7 @@ class CallGenDispatch(CallGenBase.CallGenBase):
|
||||
if can >= 2:
|
||||
cconst_ptr_ty: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(
|
||||
pool, llvmlite.Int8(pool))
|
||||
cconst_arg: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
|
||||
cconst_arg: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, cargs.get(0), funcs_ptr, func_count, trans)
|
||||
if cconst_arg is not None:
|
||||
return self.Gen.CallGenCtor._translate_t_type_cast(
|
||||
@@ -417,7 +417,7 @@ class CallGenDispatch(CallGenBase.CallGenBase):
|
||||
# translate_constant 里按「是否超出 i32 范围」选位宽,
|
||||
# `uint64(0xFFFFFFFFFFFFFFFF)`(词法回绕为 -1)被
|
||||
# 物化成 i32 -1 再 zext → 0x00000000FFFFFFFF(N1)。
|
||||
tc_arg_val: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
|
||||
tc_arg_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, tc_arg_node, None, 0, trans, target_ty)
|
||||
if tc_arg_val is not None:
|
||||
return self.Gen.CallGenCtor._translate_t_type_cast(
|
||||
@@ -453,7 +453,7 @@ class CallGenDispatch(CallGenBase.CallGenBase):
|
||||
mod_td_ty = self.Gen.TypeGenResolve.resolve_annotation_type(
|
||||
pool, mod_td_ast, mod_imp_td, mod_fi_td, trans, 0)
|
||||
if mod_td_ty is not None and can == 1:
|
||||
mt_arg_val: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
|
||||
mt_arg_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, cargs.get(0), funcs_ptr, func_count, trans, mod_td_ty)
|
||||
if mt_arg_val is not None:
|
||||
return self.Gen.CallGenCtor._translate_t_type_cast(
|
||||
@@ -530,7 +530,7 @@ class CallGenDispatch(CallGenBase.CallGenBase):
|
||||
bare_ty = llvmlite.Ptr(pool, bare_ty)
|
||||
bare_arg_node: rawptr[ast.AST] = cargs.get(0)
|
||||
if bare_arg_node is not None:
|
||||
bare_arg_val: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
|
||||
bare_arg_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, bare_arg_node, None, 0, trans, bare_ty)
|
||||
if bare_arg_val is not None:
|
||||
return self.Gen.CallGenCtor._translate_t_type_cast(
|
||||
@@ -541,7 +541,7 @@ class CallGenDispatch(CallGenBase.CallGenBase):
|
||||
if bare_arg_node is not None:
|
||||
# 第 8 参 target_ty 下传:裸名 typedef 强转(如 uint64(x))的
|
||||
# 目标位宽必须参与常量物化(N1)。
|
||||
bare_arg_val: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
|
||||
bare_arg_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, bare_arg_node, None, 0, trans, bare_ty)
|
||||
if bare_arg_val is not None:
|
||||
return self.Gen.CallGenCtor._translate_t_type_cast(
|
||||
@@ -551,15 +551,15 @@ class CallGenDispatch(CallGenBase.CallGenBase):
|
||||
return None
|
||||
|
||||
def _tc_h5_sizeof_len_isinst(self, pool: rawptr[memhub.MemBuddy],
|
||||
builder: llvmlite.IRBuilder | t.CPtr,
|
||||
builder: rawptr[llvmlite.IRBuilder],
|
||||
mod: rawptr[llvmlite.LLVMModule],
|
||||
cl: rawptr[ast.Call],
|
||||
funcs_ptr: t.CPtr,
|
||||
func_count: int,
|
||||
trans: rawptr[HT.Translator],
|
||||
func_name: str,
|
||||
cargs: list[rawptr[ast.AST]] | t.CPtr,
|
||||
can: sizet) -> llvmlite.Value | t.CPtr:
|
||||
cargs: rawptr[list[rawptr[ast.AST]]],
|
||||
can: sizet) -> rawptr[llvmlite.Value]:
|
||||
"""__sizeof__/len/isinstance 内置(未命中返回 None)"""
|
||||
# 检测 ClassName.__sizeof__() — 返回结构体大小常量(i64)
|
||||
# __sizeof__ 是内置方法,不走跨模块调用路径
|
||||
@@ -722,7 +722,7 @@ class CallGenDispatch(CallGenBase.CallGenBase):
|
||||
szf_sha1: str = self.Gen.StructGen._resolve_module_sha1(
|
||||
szf_mod, trans._from_imports if trans is not None else None)
|
||||
if szf_sha1 is not None:
|
||||
szf_entry: GenTypes.StructEntry | t.CPtr = self.Gen.StructGen.find_struct_by_module(sz_cls_name, szf_sha1)
|
||||
szf_entry: rawptr[GenTypes.StructEntry] = self.Gen.StructGen.find_struct_by_module(sz_cls_name, szf_sha1)
|
||||
if szf_entry is not None and szf_entry.Ty is not None:
|
||||
sz_resolved_ty = szf_entry.Ty
|
||||
if sz_resolved_ty is None:
|
||||
@@ -755,7 +755,7 @@ class CallGenDispatch(CallGenBase.CallGenBase):
|
||||
# 指针 Ptr([N x T]),算 N*elem_size(TPC _HandleSizeofLlvm 数组分支;
|
||||
# zhuff.vp memset(bl_count, 0, bl_count.__sizeof__()) 依赖)
|
||||
if sz_resolved_ty is None:
|
||||
inst_sz_val: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
|
||||
inst_sz_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, sz_at.value, None, 0, trans)
|
||||
if inst_sz_val is not None and inst_sz_val.Ty is not None:
|
||||
match inst_sz_val.Ty:
|
||||
@@ -801,7 +801,7 @@ class CallGenDispatch(CallGenBase.CallGenBase):
|
||||
len_at: rawptr[ast.Attribute] = rawptr[ast.Attribute](cl.func)
|
||||
if len_at.attr is not None and string.strcmp(len_at.attr, "__len__") == 0:
|
||||
if len_at.value is not None and can == 0:
|
||||
obj_val: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
|
||||
obj_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, len_at.value, funcs_ptr, func_count, trans)
|
||||
if obj_val is not None and obj_val.Ty is not None:
|
||||
# 防御性类型检查: obj_val 必须是指针类型才能做 GEP
|
||||
@@ -816,8 +816,8 @@ class CallGenDispatch(CallGenBase.CallGenBase):
|
||||
# 注意: 必须用 const_int64 而非 ConstInt(...,"0")
|
||||
# ConstInt 的 name 参数 "0" 会被当作 IR 文本值输出 i64 0
|
||||
# 导致 GEP 索引为 0(访问 __data__)而非 1(访问 __count__)
|
||||
idx_one: llvmlite.Value | t.CPtr = llvmlite.const_int64(pool, 1)
|
||||
count_ptr: llvmlite.Value | t.CPtr = llvmlite.build_gep(
|
||||
idx_one: rawptr[llvmlite.Value] = llvmlite.const_int64(pool, 1)
|
||||
count_ptr: rawptr[llvmlite.Value] = llvmlite.build_gep(
|
||||
builder, i64_ty_len, obj_val, idx_one)
|
||||
if count_ptr is not None:
|
||||
return llvmlite.build_load(builder, i64_ty_len, count_ptr)
|
||||
@@ -829,7 +829,7 @@ class CallGenDispatch(CallGenBase.CallGenBase):
|
||||
if can == 1:
|
||||
len_arg_node: rawptr[ast.AST] = cargs.get(0)
|
||||
if len_arg_node is not None:
|
||||
len_val: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
|
||||
len_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, len_arg_node, None, 0, trans)
|
||||
if len_val is not None:
|
||||
# len(数组):t.CArray[T, N] → 常量 N(对齐 TPC
|
||||
@@ -880,8 +880,8 @@ class CallGenDispatch(CallGenBase.CallGenBase):
|
||||
if self.Gen.CallGenProp._is_list_builtin_receiver(
|
||||
pool, len_val, len_cls_nm, "__len__", len_arg_node) != 0:
|
||||
i64_ty_lb: rawptr[llvmlite.LLVMType] = llvmlite.Int64(pool)
|
||||
idx_one_lb: llvmlite.Value | t.CPtr = llvmlite.const_int64(pool, 1)
|
||||
cnt_ptr_lb: llvmlite.Value | t.CPtr = llvmlite.build_gep(
|
||||
idx_one_lb: rawptr[llvmlite.Value] = llvmlite.const_int64(pool, 1)
|
||||
cnt_ptr_lb: rawptr[llvmlite.Value] = llvmlite.build_gep(
|
||||
builder, i64_ty_lb, len_val, idx_one_lb)
|
||||
if cnt_ptr_lb is not None:
|
||||
return llvmlite.build_load(builder, i64_ty_lb, cnt_ptr_lb)
|
||||
@@ -897,8 +897,8 @@ class CallGenDispatch(CallGenBase.CallGenBase):
|
||||
llvmlite.function_get_name(len_fn2)
|
||||
if len_ret_ty2 is not None and len_fn_name2 is not None:
|
||||
# self 参数类型对齐(按方法首个形参 bitcast)
|
||||
len_self_arg2: llvmlite.Value | t.CPtr = len_val
|
||||
len_first_param2: llvmlite.Param | t.CPtr = \
|
||||
len_self_arg2: rawptr[llvmlite.Value] = len_val
|
||||
len_first_param2: rawptr[llvmlite.Param] = \
|
||||
llvmlite.function_get_param_head(len_fn2)
|
||||
if len_first_param2 is not None:
|
||||
len_self_ty2: rawptr[llvmlite.LLVMType] = \
|
||||
@@ -938,7 +938,7 @@ class CallGenDispatch(CallGenBase.CallGenBase):
|
||||
# self 参数按对象实际类型 Ptr(len_struct_ty)(与定义侧
|
||||
# 同名类型链接匹配);len_val 已是 load 后的对象指针。
|
||||
# Value 链直接作 param_head(同跨模块调用模式)。
|
||||
len_self_x: llvmlite.Value | t.CPtr = len_val
|
||||
len_self_x: rawptr[llvmlite.Value] = len_val
|
||||
len_self_x.Next = None
|
||||
self._ensure_method_declare(
|
||||
pool, mod, len_mangled_x, len_ret_x,
|
||||
@@ -977,7 +977,7 @@ class CallGenDispatch(CallGenBase.CallGenBase):
|
||||
llvmlite.add_param(pool, strlen_fn, i8_ptr_ty_ln, "s")
|
||||
# 参数类型转换为 i8*
|
||||
i8_ptr_ty_ln2: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, llvmlite.Int8(pool))
|
||||
len_coerced: llvmlite.Value | t.CPtr = len_val
|
||||
len_coerced: rawptr[llvmlite.Value] = len_val
|
||||
if self.Gen.ExprGenBase.is_ptr_type(len_arg_ty) != 0:
|
||||
len_coerced = llvmlite.build_bitcast(builder, len_val, i8_ptr_ty_ln2)
|
||||
# 构建单参数链表并调用 strlen
|
||||
@@ -995,7 +995,7 @@ class CallGenDispatch(CallGenBase.CallGenBase):
|
||||
if cl.func is not None and cl.func.kind() == ast.ASTKind.Name:
|
||||
if func_name is not None and string.strcmp(func_name, "isinstance") == 0:
|
||||
if can >= 2:
|
||||
is_res: llvmlite.Value | t.CPtr = self.Gen.CallGenLeafKit._translate_isinstance(
|
||||
is_res: rawptr[llvmlite.Value] = self.Gen.CallGenLeafKit._translate_isinstance(
|
||||
pool, builder, mod, cargs.get(0), cargs.get(1), trans)
|
||||
if is_res is not None:
|
||||
return is_res
|
||||
@@ -1003,16 +1003,16 @@ class CallGenDispatch(CallGenBase.CallGenBase):
|
||||
return None
|
||||
|
||||
def _tc_h6_method_dispatch(self, pool: rawptr[memhub.MemBuddy],
|
||||
builder: llvmlite.IRBuilder | t.CPtr,
|
||||
builder: rawptr[llvmlite.IRBuilder],
|
||||
mod: rawptr[llvmlite.LLVMModule],
|
||||
cl: rawptr[ast.Call],
|
||||
funcs_ptr: t.CPtr,
|
||||
func_count: int,
|
||||
trans: rawptr[HT.Translator],
|
||||
func_name: str,
|
||||
cargs: list[rawptr[ast.AST]] | t.CPtr,
|
||||
cargs: rawptr[list[rawptr[ast.AST]]],
|
||||
can: sizet,
|
||||
hit_box: t.CPtr = None) -> llvmlite.Value | t.CPtr:
|
||||
hit_box: t.CPtr = None) -> rawptr[llvmlite.Value]:
|
||||
"""静态类/方法调用/表达式接收者/self.field/list 内置(未命中返回 None)
|
||||
|
||||
hit_box: 命中标记(t.CPtr,[0]=1 表示已识别为方法调用路径)。
|
||||
@@ -1029,7 +1029,7 @@ class CallGenDispatch(CallGenBase.CallGenBase):
|
||||
rk_at: rawptr[ast.Attribute] = rawptr[ast.Attribute](cl.func)
|
||||
if rk_at is not None and rk_at.attr is not None \
|
||||
and string.strcmp(rk_at.attr, "kind") == 0:
|
||||
rk_obj: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
|
||||
rk_obj: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, rk_at.value, None, 0, trans)
|
||||
if rk_obj is not None and rk_obj.Ty is not None:
|
||||
rk_ty: rawptr[llvmlite.LLVMType] = rk_obj.Ty
|
||||
@@ -1054,7 +1054,7 @@ class CallGenDispatch(CallGenBase.CallGenBase):
|
||||
and rk_at.value.kind() == ast.ASTKind.Name and trans is not None:
|
||||
rk_nm: rawptr[ast.Name] = rawptr[ast.Name](rk_at.value)
|
||||
if rk_nm.id is not None:
|
||||
rk_ve: GenTypes.VarEntry | t.CPtr = self.Gen.VarGen.lookup_var_entry(
|
||||
rk_ve: rawptr[GenTypes.VarEntry] = self.Gen.VarGen.lookup_var_entry(
|
||||
trans.SymTab, rk_nm.id)
|
||||
rk_annot_raw: str = self.Gen.VarGen.var_annot_class_name(rk_ve)
|
||||
if rk_annot_raw is not None:
|
||||
@@ -1076,7 +1076,7 @@ class CallGenDispatch(CallGenBase.CallGenBase):
|
||||
if self.Gen.ClassGenEnum._is_renum_class_name(rk_cls) == 0:
|
||||
rk_cls = None
|
||||
if rk_cls is not None:
|
||||
rk_val: llvmlite.Value | t.CPtr = rk_obj
|
||||
rk_val: rawptr[llvmlite.Value] = rk_obj
|
||||
if rk_load != 0:
|
||||
rk_val = llvmlite.build_load(builder, rk_ty, rk_obj)
|
||||
if rk_val is not None:
|
||||
@@ -1084,7 +1084,7 @@ class CallGenDispatch(CallGenBase.CallGenBase):
|
||||
hit_box[0] = 1
|
||||
rk_i32p: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(
|
||||
pool, llvmlite.Int32(pool))
|
||||
rk_cast: llvmlite.Value | t.CPtr = llvmlite.build_bitcast(
|
||||
rk_cast: rawptr[llvmlite.Value] = llvmlite.build_bitcast(
|
||||
builder, rk_val, rk_i32p)
|
||||
return llvmlite.build_load(builder, rk_i32p, rk_cast)
|
||||
# 检测类名静态/类方法调用: ClassName.method(args)
|
||||
@@ -1096,7 +1096,7 @@ class CallGenDispatch(CallGenBase.CallGenBase):
|
||||
if st_at.value.kind() == ast.ASTKind.Name:
|
||||
st_nm: rawptr[ast.Name] = rawptr[ast.Name](st_at.value)
|
||||
if st_nm.id is not None:
|
||||
st_var: llvmlite.Value | t.CPtr = self.Gen.VarGen.lookup_var(
|
||||
st_var: rawptr[llvmlite.Value] = self.Gen.VarGen.lookup_var(
|
||||
trans.SymTab, st_nm.id)
|
||||
if st_var is None and self.Gen.StructGen.get_struct_type(st_nm.id) is not None \
|
||||
and self.Gen.ImportsGen.is_module_imported(
|
||||
@@ -1109,14 +1109,14 @@ class CallGenDispatch(CallGenBase.CallGenBase):
|
||||
return self.Gen.CallGenCtor._translate_renum_construct(
|
||||
pool, builder, mod, st_nm.id, func_name,
|
||||
rc_tag_sc, cargs, can, trans)
|
||||
st_res: llvmlite.Value | t.CPtr = self.Gen.CallGenProp._translate_static_class_call(
|
||||
st_res: rawptr[llvmlite.Value] = self.Gen.CallGenProp._translate_static_class_call(
|
||||
pool, builder, mod, st_nm.id, func_name, cl, trans)
|
||||
if st_res is not None:
|
||||
return st_res
|
||||
# 实例方法经类名调用 ClassName.method(obj, args) → obj.method(args)(Python 语义,首参是 self 对象);但 st_nm.id == func_name(类名==方法名,如 CompilerFactory.CompilerFactory(...))是构造调用而非实例方法调用——本分支会误把模块限定类构造当 ClassName.method(obj,args) 且首实参当 self 传,导致返回类型查 "X.X" 永远落空 fail-fast。故跳过本分支,落到 translate_call 尾部的 ctor 检测
|
||||
if can >= 1 and cargs is not None \
|
||||
and string.strcmp(st_nm.id, func_name) != 0:
|
||||
im_self: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
|
||||
im_self: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, cargs.get(0), None, 0, trans)
|
||||
if im_self is not None:
|
||||
im_rem: sizet | t.CPtr = None
|
||||
@@ -1125,11 +1125,11 @@ class CallGenDispatch(CallGenBase.CallGenBase):
|
||||
if im_rem is not None:
|
||||
ri_im: sizet
|
||||
for ri_im in range(can - 1):
|
||||
im_rv: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
|
||||
im_rv: rawptr[llvmlite.Value] = 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] = sizet(im_rv)
|
||||
im_res: llvmlite.Value | t.CPtr = self.Gen.CallGenCall._call_method_on_ptr(
|
||||
im_res: rawptr[llvmlite.Value] = self.Gen.CallGenCall._call_method_on_ptr(
|
||||
pool, builder, mod, st_nm.id, func_name,
|
||||
im_self, im_rem, can - 1, trans)
|
||||
if im_res is not None:
|
||||
@@ -1146,7 +1146,7 @@ class CallGenDispatch(CallGenBase.CallGenBase):
|
||||
if st_at2.value.kind() == ast.ASTKind.Name:
|
||||
# ClassName 是已注册结构体类名时尝试静态/类方法
|
||||
if self.Gen.StructGen.get_struct_type(st_at2.attr) is not None:
|
||||
st_res2: llvmlite.Value | t.CPtr = self.Gen.CallGenProp._translate_static_class_call(
|
||||
st_res2: rawptr[llvmlite.Value] = self.Gen.CallGenProp._translate_static_class_call(
|
||||
pool, builder, mod, st_at2.attr, func_name, cl, trans)
|
||||
if st_res2 is not None:
|
||||
return st_res2
|
||||
@@ -1161,7 +1161,7 @@ class CallGenDispatch(CallGenBase.CallGenBase):
|
||||
# 非 Name 跳过方法分支 → 通用路径把 eye.Sub 当属性解析 →
|
||||
# "属性写入失败: .Sub"。先翻译内层调用得接收者,再方法调用。
|
||||
if method_at.value.kind() == ast.ASTKind.Call and trans is not None:
|
||||
recv_val_c: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
|
||||
recv_val_c: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, method_at.value, None, 0, trans)
|
||||
if recv_val_c is not None and recv_val_c.Ty is not None:
|
||||
recv_ty_c: rawptr[llvmlite.LLVMType] = recv_val_c.Ty
|
||||
@@ -1175,7 +1175,7 @@ class CallGenDispatch(CallGenBase.CallGenBase):
|
||||
if recv_cls_c is not None:
|
||||
if self.Gen.CallGenProp._is_list_builtin_receiver(
|
||||
pool, recv_val_c, recv_cls_c, method_at.attr, cl) == 0:
|
||||
obj_ptr_c: llvmlite.Value | t.CPtr = recv_val_c
|
||||
obj_ptr_c: rawptr[llvmlite.Value] = recv_val_c
|
||||
if self.Gen.ExprGenBase.is_ptr_type(recv_val_c.Ty) != 0 \
|
||||
and recv_val_c.Ty.Pointee is not None \
|
||||
and self.Gen.ExprGenBase.is_ptr_type(recv_val_c.Ty.Pointee) != 0:
|
||||
@@ -1198,10 +1198,10 @@ class CallGenDispatch(CallGenBase.CallGenBase):
|
||||
# Ptr(Struct)(load_nonlocal_var 已 load)与
|
||||
# Ptr(Ptr(Struct))(联合简化未解引用)两种形态。
|
||||
if GenApi.is_nonlocal_name(trans, method_obj_nm.id) != 0:
|
||||
nl_obj: llvmlite.Value | t.CPtr = self.Gen.StmtGenDecl.load_nonlocal_var(
|
||||
nl_obj: rawptr[llvmlite.Value] = self.Gen.StmtGenDecl.load_nonlocal_var(
|
||||
trans, method_obj_nm.id)
|
||||
if nl_obj is not None and nl_obj.Ty is not None:
|
||||
nl_deref: llvmlite.Value | t.CPtr = self.Gen.ExprGenBase._deref_if_ptr_ptr(
|
||||
nl_deref: rawptr[llvmlite.Value] = self.Gen.ExprGenBase._deref_if_ptr_ptr(
|
||||
builder, nl_obj)
|
||||
if nl_deref is None:
|
||||
nl_deref = nl_obj
|
||||
@@ -1223,11 +1223,11 @@ class CallGenDispatch(CallGenBase.CallGenBase):
|
||||
# 返回 None 让上层 fast-fail 暴露类型解析问题。
|
||||
return None
|
||||
# 查找对象变量
|
||||
obj_var: llvmlite.Value | t.CPtr = self.Gen.VarGen.lookup_var(
|
||||
obj_var: rawptr[llvmlite.Value] = self.Gen.VarGen.lookup_var(
|
||||
trans.SymTab, method_obj_nm.id)
|
||||
if obj_var is not None and obj_var.Ty is not None:
|
||||
# list 泛型容器注解先行识别(早期拦截,供下方各 class 分支共用):rawptr[list[rawptr[AST]]] 的 LLVM 形态为 Ptr(Ptr(Struct('list[sha.AST]'))),而 list 特化 struct 不注册为普通类,get_class_name_by_type 或返回 None、或后缀误命中内层元素类 ⇒ 下方两个 Ptr 分支的 list 内置拦截落空/错判。此处再兜底剥一次最外层 rawptr,内层以 'list' 开头且方法属 list 内置集合时置位 is_list_annot_builtin,交给本方法尾部 list 内置分支(内联 GEP)翻译
|
||||
var_entry: GenTypes.VarEntry | t.CPtr = self.Gen.VarGen.lookup_var_entry(
|
||||
var_entry: rawptr[GenTypes.VarEntry] = self.Gen.VarGen.lookup_var_entry(
|
||||
trans.SymTab, method_obj_nm.id)
|
||||
is_list_annot_builtin: int = 0
|
||||
la_buf: str = self.Gen.VarGen.var_annot_class_name(var_entry)
|
||||
@@ -1274,7 +1274,7 @@ class CallGenDispatch(CallGenBase.CallGenBase):
|
||||
if self.Gen.CallGenProp._is_list_builtin_receiver(
|
||||
pool, obj_var, inner_nm, func_name, cl) == 0 \
|
||||
and is_list_annot_builtin == 0:
|
||||
obj_ptr: llvmlite.Value | t.CPtr = llvmlite.build_load(
|
||||
obj_ptr: rawptr[llvmlite.Value] = llvmlite.build_load(
|
||||
builder, obj_struct_ty, obj_var)
|
||||
if obj_ptr is not None:
|
||||
if hit_box is not None:
|
||||
@@ -1289,7 +1289,7 @@ class CallGenDispatch(CallGenBase.CallGenBase):
|
||||
# list 容器注解命中(is_list_annot_builtin=1)时跳过 FakeDuck:
|
||||
# 接收者非 str/bytes,此调用必须由尾部 list 内置分支翻译。
|
||||
if is_list_annot_builtin == 0:
|
||||
fd_name_res: llvmlite.Value | t.CPtr = self.Gen.CallGenFd._translate_fakeduck_call(
|
||||
fd_name_res: rawptr[llvmlite.Value] = self.Gen.CallGenFd._translate_fakeduck_call(
|
||||
pool, builder, mod, None, func_name, cl, trans)
|
||||
if fd_name_res is not None:
|
||||
return fd_name_res
|
||||
@@ -1326,7 +1326,7 @@ class CallGenDispatch(CallGenBase.CallGenBase):
|
||||
# 结构体已注册:load obj_ptr 走方法调用
|
||||
i8_ptr_ty2: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(
|
||||
pool, llvmlite.Int8(pool))
|
||||
obj_ptr2: llvmlite.Value | t.CPtr = llvmlite.build_load(
|
||||
obj_ptr2: rawptr[llvmlite.Value] = llvmlite.build_load(
|
||||
builder, i8_ptr_ty2, obj_var)
|
||||
if obj_ptr2 is not None:
|
||||
if hit_box is not None:
|
||||
@@ -1343,7 +1343,7 @@ class CallGenDispatch(CallGenBase.CallGenBase):
|
||||
# a.type_id() / a.upper() / " ".isspace() 等
|
||||
# AnnotClassName=="str" 且对象是 char* 时触发,
|
||||
# self 用影子结构体 {a}__meta__(或临时影子)。
|
||||
fd_res: llvmlite.Value | t.CPtr = self.Gen.CallGenFd._translate_fakeduck_call(
|
||||
fd_res: rawptr[llvmlite.Value] = self.Gen.CallGenFd._translate_fakeduck_call(
|
||||
pool, builder, mod, cls_nm2, func_name, cl, trans)
|
||||
if fd_res is not None:
|
||||
return fd_res
|
||||
@@ -1361,17 +1361,17 @@ class CallGenDispatch(CallGenBase.CallGenBase):
|
||||
# load obj_ptr (self)
|
||||
i8_ptr_ty3: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(
|
||||
pool, llvmlite.Int8(pool))
|
||||
obj_ptr3: llvmlite.Value | t.CPtr = llvmlite.build_load(
|
||||
obj_ptr3: rawptr[llvmlite.Value] = llvmlite.build_load(
|
||||
builder, i8_ptr_ty3, obj_var)
|
||||
if obj_ptr3 is not None:
|
||||
# 构建参数链表: obj_ptr3 (self) → 其他参数
|
||||
llvmlite.value_set_next(obj_ptr3, None)
|
||||
head3: llvmlite.Value | t.CPtr = obj_ptr3
|
||||
tail3: llvmlite.Value | t.CPtr = obj_ptr3
|
||||
head3: rawptr[llvmlite.Value] = obj_ptr3
|
||||
tail3: rawptr[llvmlite.Value] = obj_ptr3
|
||||
for ai3 in range(can):
|
||||
arg3: rawptr[ast.AST] = cargs.get(ai3)
|
||||
if arg3 is not None:
|
||||
arg_val3: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
|
||||
arg_val3: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, arg3, None, 0, trans)
|
||||
if arg_val3 is not None:
|
||||
llvmlite.value_set_next(arg_val3, None)
|
||||
@@ -1419,7 +1419,7 @@ class CallGenDispatch(CallGenBase.CallGenBase):
|
||||
if sp_ty4 is not None:
|
||||
i8_ptr_ty4: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(
|
||||
pool, llvmlite.Int8(pool))
|
||||
obj_ptr4: llvmlite.Value | t.CPtr = llvmlite.build_load(
|
||||
obj_ptr4: rawptr[llvmlite.Value] = llvmlite.build_load(
|
||||
builder, i8_ptr_ty4, obj_var)
|
||||
if obj_ptr4 is not None:
|
||||
if hit_box is not None:
|
||||
@@ -1463,7 +1463,7 @@ class CallGenDispatch(CallGenBase.CallGenBase):
|
||||
is_mod_path_expr = 1
|
||||
if evk != ast.ASTKind.Name and is_mod_path_expr == 0:
|
||||
# 翻译接收者表达式(求值结果应为 Ptr(Struct))
|
||||
expr_obj: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
|
||||
expr_obj: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, expr_method_at.value, funcs_ptr, func_count, trans)
|
||||
if expr_obj is not None and expr_obj.Ty is not None:
|
||||
expr_cls_nm: str = None
|
||||
@@ -1496,7 +1496,7 @@ class CallGenDispatch(CallGenBase.CallGenBase):
|
||||
case _:
|
||||
expr_is_ptr = 0
|
||||
if expr_is_ptr == 0:
|
||||
expr_addr: llvmlite.Value | t.CPtr = self.Gen.ExprGenAttr.get_attribute_ptr(
|
||||
expr_addr: rawptr[llvmlite.Value] = self.Gen.ExprGenAttr.get_attribute_ptr(
|
||||
builder, pool, mod, expr_method_at.value, trans)
|
||||
if expr_addr is not None:
|
||||
expr_obj = expr_addr
|
||||
@@ -1508,7 +1508,7 @@ class CallGenDispatch(CallGenBase.CallGenBase):
|
||||
# FakeDuck: 表达式接收者解析失败且对象是 char* 时
|
||||
# (如 " ".isspace()),尝试扩展类 _Type/_str 方法
|
||||
# (self 用临时影子,对齐 TPC L2858-2873)
|
||||
fd_expr_res: llvmlite.Value | t.CPtr = self.Gen.CallGenFd._translate_fakeduck_call(
|
||||
fd_expr_res: rawptr[llvmlite.Value] = self.Gen.CallGenFd._translate_fakeduck_call(
|
||||
pool, builder, mod, None, func_name, cl, trans)
|
||||
if fd_expr_res is not None:
|
||||
return fd_expr_res
|
||||
@@ -1529,7 +1529,7 @@ class CallGenDispatch(CallGenBase.CallGenBase):
|
||||
inner_attr: rawptr[ast.Attribute] = rawptr[ast.Attribute](attr_method_at.value)
|
||||
if inner_attr is not None and inner_attr.attr is not None:
|
||||
# 翻译 self.__pool__ 获取字段值(已 load 的对象指针)
|
||||
field_obj: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
|
||||
field_obj: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, attr_method_at.value, funcs_ptr, func_count, trans)
|
||||
if field_obj is not None and field_obj.Ty is not None:
|
||||
field_cls_nm: str = None
|
||||
@@ -1543,12 +1543,12 @@ class CallGenDispatch(CallGenBase.CallGenBase):
|
||||
if inner_attr.value is not None and inner_attr.value.kind() == ast.ASTKind.Name:
|
||||
inner_name_node: rawptr[ast.Name] = rawptr[ast.Name](inner_attr.value)
|
||||
if inner_name_node is not None and inner_name_node.id is not None:
|
||||
inner_var: llvmlite.Value | t.CPtr = self.Gen.VarGen.lookup_var(
|
||||
inner_var: rawptr[llvmlite.Value] = self.Gen.VarGen.lookup_var(
|
||||
trans.SymTab, inner_name_node.id)
|
||||
if inner_var is not None and inner_var.Ty is not None:
|
||||
match inner_var.Ty:
|
||||
case llvmlite.LLVMType.Ptr(field_owner_struct_ty):
|
||||
field_info: GenTypes.FieldEntry | t.CPtr = self.Gen.StructGen.lookup_field(
|
||||
field_info: rawptr[GenTypes.FieldEntry] = self.Gen.StructGen.lookup_field(
|
||||
field_owner_struct_ty, inner_attr.attr)
|
||||
if field_info is not None:
|
||||
field_annot: str = self.Gen.StructGen.get_field_annot_class_name(field_info)
|
||||
@@ -1571,7 +1571,7 @@ class CallGenDispatch(CallGenBase.CallGenBase):
|
||||
case _:
|
||||
is_val_field = 1
|
||||
if is_val_field != 0:
|
||||
field_addr: llvmlite.Value | t.CPtr = self.Gen.ExprGenAttr.get_attribute_ptr(
|
||||
field_addr: rawptr[llvmlite.Value] = self.Gen.ExprGenAttr.get_attribute_ptr(
|
||||
builder, pool, mod, attr_method_at.value, trans)
|
||||
if field_addr is not None:
|
||||
field_obj = field_addr
|
||||
@@ -1605,7 +1605,7 @@ class CallGenDispatch(CallGenBase.CallGenBase):
|
||||
|
||||
if lm_is_list == 1 and trans is not None:
|
||||
# 翻译 list 对象
|
||||
lm_obj: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
|
||||
lm_obj: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, lm_at.value, funcs_ptr, func_count, trans)
|
||||
if lm_obj is not None:
|
||||
# 防御性类型检查: lm_obj 必须是指针类型才能做 GEP
|
||||
@@ -1669,24 +1669,24 @@ class CallGenDispatch(CallGenBase.CallGenBase):
|
||||
if string.strcmp(lm_name, "get") == 0 or string.strcmp(lm_name, "__getitem__") == 0:
|
||||
if can >= 1:
|
||||
# 加载 __data__ (偏移 0)
|
||||
g_idx0: llvmlite.Value | t.CPtr = llvmlite.const_int64(pool, 0)
|
||||
g_dpp: llvmlite.Value | t.CPtr = llvmlite.build_gep(builder, i64_ty, lm_obj, g_idx0)
|
||||
g_data: llvmlite.Value | t.CPtr = llvmlite.build_load(builder, i8_ptr_ty, g_dpp)
|
||||
g_idx0: rawptr[llvmlite.Value] = llvmlite.const_int64(pool, 0)
|
||||
g_dpp: rawptr[llvmlite.Value] = llvmlite.build_gep(builder, i64_ty, lm_obj, g_idx0)
|
||||
g_data: rawptr[llvmlite.Value] = llvmlite.build_load(builder, i8_ptr_ty, g_dpp)
|
||||
# 加载 __elem_size__ (偏移 32, index 4)
|
||||
g_idx4: llvmlite.Value | t.CPtr = llvmlite.const_int64(pool, 4)
|
||||
g_epp: llvmlite.Value | t.CPtr = llvmlite.build_gep(builder, i64_ty, lm_obj, g_idx4)
|
||||
g_esize: llvmlite.Value | t.CPtr = llvmlite.build_load(builder, i64_ty, g_epp)
|
||||
g_idx4: rawptr[llvmlite.Value] = llvmlite.const_int64(pool, 4)
|
||||
g_epp: rawptr[llvmlite.Value] = llvmlite.build_gep(builder, i64_ty, lm_obj, g_idx4)
|
||||
g_esize: rawptr[llvmlite.Value] = llvmlite.build_load(builder, i64_ty, g_epp)
|
||||
# 翻译 index
|
||||
g_idx_node: rawptr[ast.AST] = cargs.get(0)
|
||||
g_idx_val: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
|
||||
g_idx_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, g_idx_node, None, 0, trans)
|
||||
if g_data is not None and g_esize is not None and g_idx_val is not None:
|
||||
g_idx_i64: llvmlite.Value | t.CPtr = self.Gen.ExprGenBase.coerce_to_type(
|
||||
g_idx_i64: rawptr[llvmlite.Value] = self.Gen.ExprGenBase.coerce_to_type(
|
||||
builder, g_idx_val, i64_ty, g_idx_node)
|
||||
g_offset: llvmlite.Value | t.CPtr = llvmlite.build_mul(builder, g_idx_i64, g_esize)
|
||||
g_addr: llvmlite.Value | t.CPtr = llvmlite.build_gep(builder, i8_ty, g_data, g_offset)
|
||||
g_offset: rawptr[llvmlite.Value] = llvmlite.build_mul(builder, g_idx_i64, g_esize)
|
||||
g_addr: rawptr[llvmlite.Value] = llvmlite.build_gep(builder, i8_ty, g_data, g_offset)
|
||||
if g_addr is not None:
|
||||
g_ep: llvmlite.Value | t.CPtr = llvmlite.build_bitcast(
|
||||
g_ep: rawptr[llvmlite.Value] = llvmlite.build_bitcast(
|
||||
builder, g_addr, llvmlite.Ptr(pool, lm_elem_ty))
|
||||
if g_ep is not None:
|
||||
return llvmlite.build_load(builder, lm_elem_ty, g_ep)
|
||||
@@ -1694,27 +1694,27 @@ class CallGenDispatch(CallGenBase.CallGenBase):
|
||||
# set / __setitem__: 设置 index 处的元素
|
||||
elif string.strcmp(lm_name, "set") == 0 or string.strcmp(lm_name, "__setitem__") == 0:
|
||||
if can >= 2:
|
||||
s_idx0: llvmlite.Value | t.CPtr = llvmlite.const_int64(pool, 0)
|
||||
s_dpp: llvmlite.Value | t.CPtr = llvmlite.build_gep(builder, i64_ty, lm_obj, s_idx0)
|
||||
s_data: llvmlite.Value | t.CPtr = llvmlite.build_load(builder, i8_ptr_ty, s_dpp)
|
||||
s_idx4: llvmlite.Value | t.CPtr = llvmlite.const_int64(pool, 4)
|
||||
s_epp: llvmlite.Value | t.CPtr = llvmlite.build_gep(builder, i64_ty, lm_obj, s_idx4)
|
||||
s_esize: llvmlite.Value | t.CPtr = llvmlite.build_load(builder, i64_ty, s_epp)
|
||||
s_idx0: rawptr[llvmlite.Value] = llvmlite.const_int64(pool, 0)
|
||||
s_dpp: rawptr[llvmlite.Value] = llvmlite.build_gep(builder, i64_ty, lm_obj, s_idx0)
|
||||
s_data: rawptr[llvmlite.Value] = llvmlite.build_load(builder, i8_ptr_ty, s_dpp)
|
||||
s_idx4: rawptr[llvmlite.Value] = llvmlite.const_int64(pool, 4)
|
||||
s_epp: rawptr[llvmlite.Value] = llvmlite.build_gep(builder, i64_ty, lm_obj, s_idx4)
|
||||
s_esize: rawptr[llvmlite.Value] = llvmlite.build_load(builder, i64_ty, s_epp)
|
||||
s_idx_node: rawptr[ast.AST] = cargs.get(0)
|
||||
s_val_node: rawptr[ast.AST] = cargs.get(1)
|
||||
s_idx_val: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
|
||||
s_idx_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, s_idx_node, None, 0, trans)
|
||||
s_val_val: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
|
||||
s_val_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, s_val_node, None, 0, trans)
|
||||
if s_data is not None and s_esize is not None and s_idx_val is not None and s_val_val is not None:
|
||||
s_idx_i64: llvmlite.Value | t.CPtr = self.Gen.ExprGenBase.coerce_to_type(
|
||||
s_idx_i64: rawptr[llvmlite.Value] = self.Gen.ExprGenBase.coerce_to_type(
|
||||
builder, s_idx_val, i64_ty, s_idx_node)
|
||||
s_offset: llvmlite.Value | t.CPtr = llvmlite.build_mul(builder, s_idx_i64, s_esize)
|
||||
s_addr: llvmlite.Value | t.CPtr = llvmlite.build_gep(builder, i8_ty, s_data, s_offset)
|
||||
s_offset: rawptr[llvmlite.Value] = llvmlite.build_mul(builder, s_idx_i64, s_esize)
|
||||
s_addr: rawptr[llvmlite.Value] = llvmlite.build_gep(builder, i8_ty, s_data, s_offset)
|
||||
if s_addr is not None:
|
||||
s_val_elem: llvmlite.Value | t.CPtr = self.Gen.ExprGenBase.coerce_to_type(
|
||||
s_val_elem: rawptr[llvmlite.Value] = self.Gen.ExprGenBase.coerce_to_type(
|
||||
builder, s_val_val, lm_elem_ty, s_val_node)
|
||||
s_ep: llvmlite.Value | t.CPtr = llvmlite.build_bitcast(
|
||||
s_ep: rawptr[llvmlite.Value] = llvmlite.build_bitcast(
|
||||
builder, s_addr, llvmlite.Ptr(pool, lm_elem_ty))
|
||||
if s_ep is not None:
|
||||
llvmlite.build_store(builder, s_val_elem, s_ep)
|
||||
@@ -1722,38 +1722,38 @@ class CallGenDispatch(CallGenBase.CallGenBase):
|
||||
|
||||
# pop: 返回最后一个元素,count--
|
||||
elif string.strcmp(lm_name, "pop") == 0:
|
||||
p_idx1: llvmlite.Value | t.CPtr = llvmlite.const_int64(pool, 1)
|
||||
p_cpp: llvmlite.Value | t.CPtr = llvmlite.build_gep(builder, i64_ty, lm_obj, p_idx1)
|
||||
p_count: llvmlite.Value | t.CPtr = llvmlite.build_load(builder, i64_ty, p_cpp)
|
||||
p_nc: llvmlite.Value | t.CPtr = llvmlite.build_sub(
|
||||
p_idx1: rawptr[llvmlite.Value] = llvmlite.const_int64(pool, 1)
|
||||
p_cpp: rawptr[llvmlite.Value] = llvmlite.build_gep(builder, i64_ty, lm_obj, p_idx1)
|
||||
p_count: rawptr[llvmlite.Value] = llvmlite.build_load(builder, i64_ty, p_cpp)
|
||||
p_nc: rawptr[llvmlite.Value] = llvmlite.build_sub(
|
||||
builder, p_count, llvmlite.const_int64(pool, 1))
|
||||
llvmlite.build_store(builder, p_nc, p_cpp)
|
||||
p_idx0: llvmlite.Value | t.CPtr = llvmlite.const_int64(pool, 0)
|
||||
p_dpp: llvmlite.Value | t.CPtr = llvmlite.build_gep(builder, i64_ty, lm_obj, p_idx0)
|
||||
p_data: llvmlite.Value | t.CPtr = llvmlite.build_load(builder, i8_ptr_ty, p_dpp)
|
||||
p_idx4: llvmlite.Value | t.CPtr = llvmlite.const_int64(pool, 4)
|
||||
p_epp: llvmlite.Value | t.CPtr = llvmlite.build_gep(builder, i64_ty, lm_obj, p_idx4)
|
||||
p_esize: llvmlite.Value | t.CPtr = llvmlite.build_load(builder, i64_ty, p_epp)
|
||||
p_idx0: rawptr[llvmlite.Value] = llvmlite.const_int64(pool, 0)
|
||||
p_dpp: rawptr[llvmlite.Value] = llvmlite.build_gep(builder, i64_ty, lm_obj, p_idx0)
|
||||
p_data: rawptr[llvmlite.Value] = llvmlite.build_load(builder, i8_ptr_ty, p_dpp)
|
||||
p_idx4: rawptr[llvmlite.Value] = llvmlite.const_int64(pool, 4)
|
||||
p_epp: rawptr[llvmlite.Value] = llvmlite.build_gep(builder, i64_ty, lm_obj, p_idx4)
|
||||
p_esize: rawptr[llvmlite.Value] = llvmlite.build_load(builder, i64_ty, p_epp)
|
||||
if p_data is not None and p_esize is not None and p_nc is not None:
|
||||
p_offset: llvmlite.Value | t.CPtr = llvmlite.build_mul(builder, p_nc, p_esize)
|
||||
p_addr: llvmlite.Value | t.CPtr = llvmlite.build_gep(builder, i8_ty, p_data, p_offset)
|
||||
p_offset: rawptr[llvmlite.Value] = llvmlite.build_mul(builder, p_nc, p_esize)
|
||||
p_addr: rawptr[llvmlite.Value] = llvmlite.build_gep(builder, i8_ty, p_data, p_offset)
|
||||
if p_addr is not None:
|
||||
p_ep: llvmlite.Value | t.CPtr = llvmlite.build_bitcast(
|
||||
p_ep: rawptr[llvmlite.Value] = llvmlite.build_bitcast(
|
||||
builder, p_addr, llvmlite.Ptr(pool, lm_elem_ty))
|
||||
if p_ep is not None:
|
||||
return llvmlite.build_load(builder, lm_elem_ty, p_ep)
|
||||
|
||||
# clear: count = 0
|
||||
elif string.strcmp(lm_name, "clear") == 0:
|
||||
c_idx1: llvmlite.Value | t.CPtr = llvmlite.const_int64(pool, 1)
|
||||
c_cpp: llvmlite.Value | t.CPtr = llvmlite.build_gep(builder, i64_ty, lm_obj, c_idx1)
|
||||
c_idx1: rawptr[llvmlite.Value] = llvmlite.const_int64(pool, 1)
|
||||
c_cpp: rawptr[llvmlite.Value] = llvmlite.build_gep(builder, i64_ty, lm_obj, c_idx1)
|
||||
llvmlite.build_store(builder, llvmlite.const_int64(pool, 0), c_cpp)
|
||||
return None
|
||||
|
||||
# __iter__: iter_index = 0, return self
|
||||
elif string.strcmp(lm_name, "__iter__") == 0:
|
||||
it_idx5: llvmlite.Value | t.CPtr = llvmlite.const_int64(pool, 5)
|
||||
it_ipp: llvmlite.Value | t.CPtr = llvmlite.build_gep(builder, i64_ty, lm_obj, it_idx5)
|
||||
it_idx5: rawptr[llvmlite.Value] = llvmlite.const_int64(pool, 5)
|
||||
it_ipp: rawptr[llvmlite.Value] = llvmlite.build_gep(builder, i64_ty, lm_obj, it_idx5)
|
||||
llvmlite.build_store(builder, llvmlite.const_int64(pool, 0), it_ipp)
|
||||
return lm_obj
|
||||
|
||||
@@ -1830,7 +1830,7 @@ class CallGenDispatch(CallGenBase.CallGenBase):
|
||||
viperlib.snprintf(ap_mangled, ap_mlen, "%s.%s.append",
|
||||
ap_sha1, ap_spec_nm)
|
||||
ap_item_node: rawptr[ast.AST] = cargs.get(0)
|
||||
ap_item_val: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
|
||||
ap_item_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, ap_item_node, None, 0, trans)
|
||||
if ap_item_val is not None:
|
||||
llvmlite.value_set_next(lm_obj, None)
|
||||
|
||||
@@ -27,12 +27,12 @@ class CallGenFd(CallGenBase.CallGenBase):
|
||||
|
||||
# ============================================================
|
||||
def _translate_fakeduck_call(self, pool: rawptr[memhub.MemBuddy],
|
||||
builder: llvmlite.IRBuilder | t.CPtr,
|
||||
builder: rawptr[llvmlite.IRBuilder],
|
||||
mod: rawptr[llvmlite.LLVMModule],
|
||||
cls_name: str,
|
||||
method_name: str,
|
||||
cl: rawptr[ast.Call],
|
||||
trans: rawptr[HT.Translator]) -> llvmlite.Value | t.CPtr:
|
||||
trans: rawptr[HT.Translator]) -> rawptr[llvmlite.Value]:
|
||||
"""FakeDuck: str 变量方法调用解析到扩展类 _Type/_str,返回 call 结果或 None"""
|
||||
if pool is None or builder is None or cl is None or trans is None:
|
||||
return None
|
||||
@@ -71,12 +71,12 @@ class CallGenFd(CallGenBase.CallGenBase):
|
||||
return None
|
||||
# 扩展类字段数:有字段(_str)时 self 用影子结构体指针;
|
||||
# 无字段(_Type)时 self 用对象值 bitcast 到扩展类指针(对齐 TPC L2856-2876)
|
||||
fd_entry_fd: GenTypes.StructEntry | t.CPtr = self.Gen.StructGen.find_struct_by_type(fd_sty)
|
||||
fd_entry_fd: rawptr[GenTypes.StructEntry] = self.Gen.StructGen.find_struct_by_type(fd_sty)
|
||||
fd_has_fields: int = 0
|
||||
if fd_entry_fd is not None and fd_entry_fd.FieldCount > 0:
|
||||
fd_has_fields = 1
|
||||
# self 参数:优先使用已有影子 {var}__meta__(fd2 创建,仅当扩展类有字段时)
|
||||
fd_self: llvmlite.Value | t.CPtr = None
|
||||
fd_self: rawptr[llvmlite.Value] = None
|
||||
if fd_at.value.kind() == ast.ASTKind.Name:
|
||||
fd_onm: rawptr[ast.Name] = rawptr[ast.Name](fd_at.value)
|
||||
if fd_onm.id is not None:
|
||||
@@ -84,7 +84,7 @@ class CallGenFd(CallGenBase.CallGenBase):
|
||||
fd_mn: str = pool.alloc(256)
|
||||
if fd_mn is not None:
|
||||
viperlib.snprintf(fd_mn, 256, "%s__meta__", fd_onm.id)
|
||||
fd_meta: llvmlite.Value | t.CPtr = self.Gen.VarGen.lookup_current(
|
||||
fd_meta: rawptr[llvmlite.Value] = self.Gen.VarGen.lookup_current(
|
||||
trans.SymTab, fd_mn)
|
||||
if fd_meta is not None and fd_has_fields != 0:
|
||||
fd_self = fd_meta
|
||||
@@ -96,22 +96,22 @@ class CallGenFd(CallGenBase.CallGenBase):
|
||||
fd_self = self.Gen.VarGen._alloca_at_entry(builder, fd_sty)
|
||||
if fd_self is None:
|
||||
return None
|
||||
fd_obj_val: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
|
||||
fd_obj_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, fd_at.value, None, 0, trans)
|
||||
if fd_obj_val is not None:
|
||||
fd_dfe: GenTypes.FieldEntry | t.CPtr = \
|
||||
fd_dfe: rawptr[GenTypes.FieldEntry] = \
|
||||
self.Gen.StructGen.lookup_field(fd_sty, "__data__")
|
||||
if fd_dfe is not None and fd_dfe.Ty is not None:
|
||||
fd_dp: llvmlite.Value | t.CPtr = llvmlite.build_gep_struct(
|
||||
fd_dp: rawptr[llvmlite.Value] = llvmlite.build_gep_struct(
|
||||
builder, fd_sty, fd_dfe.Ty, fd_self, fd_dfe.Index)
|
||||
if fd_dp is not None:
|
||||
llvmlite.build_store(builder, fd_obj_val, fd_dp)
|
||||
fd_bfe: GenTypes.FieldEntry | t.CPtr = \
|
||||
fd_bfe: rawptr[GenTypes.FieldEntry] = \
|
||||
self.Gen.StructGen.lookup_field(fd_sty, "__mbuddy__")
|
||||
if fd_bfe is not None and fd_bfe.Ty is not None:
|
||||
fd_bp: llvmlite.Value | t.CPtr = llvmlite.build_gep_struct(
|
||||
fd_bp: rawptr[llvmlite.Value] = llvmlite.build_gep_struct(
|
||||
builder, fd_sty, fd_bfe.Ty, fd_self, fd_bfe.Index)
|
||||
fd_null: llvmlite.Value | t.CPtr = llvmlite.ConstNull(
|
||||
fd_null: rawptr[llvmlite.Value] = llvmlite.ConstNull(
|
||||
pool, fd_bfe.Ty, "null")
|
||||
if fd_bp is not None and fd_null is not None:
|
||||
llvmlite.build_store(builder, fd_null, fd_bp)
|
||||
@@ -120,7 +120,7 @@ class CallGenFd(CallGenBase.CallGenBase):
|
||||
trans, pool, builder, mod, fd_self, fd_cls)
|
||||
else:
|
||||
# 无字段扩展类(_Type):对象值 bitcast 到扩展类指针
|
||||
fd_obj_v: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
|
||||
fd_obj_v: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, fd_at.value, None, 0, trans)
|
||||
if fd_obj_v is None:
|
||||
return None
|
||||
@@ -130,16 +130,16 @@ class CallGenFd(CallGenBase.CallGenBase):
|
||||
return None
|
||||
# 构建参数链表: self → 其余参数
|
||||
llvmlite.value_set_next(fd_self, None)
|
||||
fd_head: llvmlite.Value | t.CPtr = fd_self
|
||||
fd_tail: llvmlite.Value | t.CPtr = fd_self
|
||||
fd_args: list[rawptr[ast.AST]] | t.CPtr = cl.args
|
||||
fd_head: rawptr[llvmlite.Value] = fd_self
|
||||
fd_tail: rawptr[llvmlite.Value] = fd_self
|
||||
fd_args: rawptr[list[rawptr[ast.AST]]] = cl.args
|
||||
fd_can: int = 0
|
||||
if fd_args is not None:
|
||||
fd_can = len(fd_args)
|
||||
for fd_ai in range(fd_can):
|
||||
fd_arg: rawptr[ast.AST] = fd_args.get(fd_ai)
|
||||
if fd_arg is not None:
|
||||
fd_av: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
|
||||
fd_av: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, fd_arg, None, 0, trans)
|
||||
# char 常量参数 → 单字符字符串(char 隐式转 str,
|
||||
# 如 s1.split(','):',' 是 i32 值 44,传给 str 参数须先字符串化,
|
||||
@@ -190,9 +190,9 @@ class CallGenFd(CallGenBase.CallGenBase):
|
||||
# ============================================================
|
||||
def _inject_requires_fields(self, trans: rawptr[HT.Translator],
|
||||
pool: rawptr[memhub.MemBuddy],
|
||||
builder: llvmlite.IRBuilder | t.CPtr,
|
||||
builder: rawptr[llvmlite.IRBuilder],
|
||||
mod: rawptr[llvmlite.LLVMModule],
|
||||
meta_ptr: llvmlite.Value | t.CPtr,
|
||||
meta_ptr: rawptr[llvmlite.Value],
|
||||
class_name: str) -> int:
|
||||
"""在 with 上下文注入 requires 字段,返回注入字段数"""
|
||||
if trans is None or pool is None or builder is None or mod is None:
|
||||
@@ -233,28 +233,28 @@ class CallGenFd(CallGenBase.CallGenBase):
|
||||
GenTypes.CLASS_META_REQUIRES, class_name, ji)
|
||||
if fname is None:
|
||||
continue
|
||||
fe: GenTypes.FieldEntry | t.CPtr = self.Gen.StructGen.lookup_field(
|
||||
fe: rawptr[GenTypes.FieldEntry] = self.Gen.StructGen.lookup_field(
|
||||
sty, fname)
|
||||
if fe is None or fe.Ty is None:
|
||||
continue
|
||||
# 参数:字段名字符串(i8*)
|
||||
fd_fstr: llvmlite.Value | t.CPtr = self.Gen.ExprGenConst.create_global_string(
|
||||
fd_fstr: rawptr[llvmlite.Value] = self.Gen.ExprGenConst.create_global_string(
|
||||
builder, pool, mod, fname, trans)
|
||||
if fd_fstr is None:
|
||||
continue
|
||||
llvmlite.value_set_next(fd_fstr, None)
|
||||
self._ensure_method_declare(
|
||||
pool, mod, fd_fname, i8_ptr_ty_j, fd_fstr, 1)
|
||||
fd_ptr: llvmlite.Value | t.CPtr = llvmlite.build_call(
|
||||
fd_ptr: rawptr[llvmlite.Value] = llvmlite.build_call(
|
||||
builder, fd_fname, fd_fstr, 1, i8_ptr_ty_j, 0)
|
||||
if fd_ptr is None:
|
||||
continue
|
||||
# 条件注入:ptr != NULL 才写入(保留用户手动设置的值)
|
||||
fd_null: llvmlite.Value | t.CPtr = llvmlite.ConstNull(
|
||||
fd_null: rawptr[llvmlite.Value] = llvmlite.ConstNull(
|
||||
pool, i8_ptr_ty_j, "null")
|
||||
if fd_null is None:
|
||||
continue
|
||||
fd_cmp: llvmlite.Value | t.CPtr = llvmlite.build_icmp(
|
||||
fd_cmp: rawptr[llvmlite.Value] = llvmlite.build_icmp(
|
||||
builder, llvmlite.ICMP_NE, fd_ptr, fd_null)
|
||||
if fd_cmp is None:
|
||||
continue
|
||||
@@ -266,20 +266,20 @@ class CallGenFd(CallGenBase.CallGenBase):
|
||||
if fd_bb_buf2 is None:
|
||||
continue
|
||||
viperlib.snprintf(fd_bb_buf2, 64, "fd.skip.%d", vtc2)
|
||||
fd_skip_bb: llvmlite.BasicBlock | t.CPtr = llvmlite.create_block(
|
||||
fd_skip_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(
|
||||
pool, cur_func, fd_bb_buf2)
|
||||
viperlib.snprintf(fd_bb_buf2, 64, "fd.inject.%d", vtc2)
|
||||
fd_inject_bb: llvmlite.BasicBlock | t.CPtr = llvmlite.create_block(
|
||||
fd_inject_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(
|
||||
pool, cur_func, fd_bb_buf2)
|
||||
if fd_skip_bb is None or fd_inject_bb is None:
|
||||
continue
|
||||
llvmlite.build_cond_br(builder, fd_cmp, fd_inject_bb, fd_skip_bb)
|
||||
# inject 块:bitcast + GEP + store,跳回 skip
|
||||
llvmlite.position_at_end(builder, fd_inject_bb)
|
||||
fd_cast: llvmlite.Value | t.CPtr = llvmlite.build_bitcast(
|
||||
fd_cast: rawptr[llvmlite.Value] = llvmlite.build_bitcast(
|
||||
builder, fd_ptr, fe.Ty)
|
||||
if fd_cast is not None:
|
||||
fd_fp: llvmlite.Value | t.CPtr = llvmlite.build_gep_struct(
|
||||
fd_fp: rawptr[llvmlite.Value] = llvmlite.build_gep_struct(
|
||||
builder, sty, fe.Ty, meta_ptr, fe.Index)
|
||||
if fd_fp is not None:
|
||||
llvmlite.build_store(builder, fd_cast, fd_fp)
|
||||
@@ -301,10 +301,10 @@ class CallGenFd(CallGenBase.CallGenBase):
|
||||
# ============================================================
|
||||
def _emit_provider_push(self, trans: rawptr[HT.Translator],
|
||||
pool: rawptr[memhub.MemBuddy],
|
||||
builder: llvmlite.IRBuilder | t.CPtr,
|
||||
builder: rawptr[llvmlite.IRBuilder],
|
||||
mod: rawptr[llvmlite.LLVMModule],
|
||||
cls_name: str,
|
||||
ctx_val: llvmlite.Value | t.CPtr) -> int:
|
||||
ctx_val: rawptr[llvmlite.Value]) -> int:
|
||||
"""生成 _push_provider(field, ctx_i8) 调用(每提供字段一次),返回字段数"""
|
||||
if trans is None or pool is None or builder is None or mod is None:
|
||||
return 0
|
||||
@@ -333,7 +333,7 @@ class CallGenFd(CallGenBase.CallGenBase):
|
||||
if ret_i32_p is None:
|
||||
return 0
|
||||
# ctx 值 bitcast 到 i8*(provider 栈存 void*)
|
||||
fd_ctx_i8: llvmlite.Value | t.CPtr = llvmlite.build_bitcast(
|
||||
fd_ctx_i8: rawptr[llvmlite.Value] = llvmlite.build_bitcast(
|
||||
builder, ctx_val, i8_ptr_ty_p)
|
||||
if fd_ctx_i8 is None:
|
||||
return 0
|
||||
@@ -342,7 +342,7 @@ class CallGenFd(CallGenBase.CallGenBase):
|
||||
GenTypes.CLASS_META_PROVIDES, cls_name, pi)
|
||||
if fname is None:
|
||||
continue
|
||||
fd_fstr: llvmlite.Value | t.CPtr = self.Gen.ExprGenConst.create_global_string(
|
||||
fd_fstr: rawptr[llvmlite.Value] = self.Gen.ExprGenConst.create_global_string(
|
||||
builder, pool, mod, fname, trans)
|
||||
if fd_fstr is None:
|
||||
continue
|
||||
@@ -354,7 +354,7 @@ class CallGenFd(CallGenBase.CallGenBase):
|
||||
return fd_pc
|
||||
def _emit_provider_pop(self, trans: rawptr[HT.Translator],
|
||||
pool: rawptr[memhub.MemBuddy],
|
||||
builder: llvmlite.IRBuilder | t.CPtr,
|
||||
builder: rawptr[llvmlite.IRBuilder],
|
||||
mod: rawptr[llvmlite.LLVMModule],
|
||||
cls_name: str) -> int:
|
||||
"""生成 _pop_provider() 调用(每提供字段一次),返回字段数"""
|
||||
|
||||
@@ -141,7 +141,7 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin):
|
||||
"""返回 1=函数带 EH 输出参数 / 0=不带"""
|
||||
if func is None:
|
||||
return 0
|
||||
cur_p: llvmlite.Param | t.CPtr = llvmlite.function_get_param_head(func)
|
||||
cur_p: rawptr[llvmlite.Param] = llvmlite.function_get_param_head(func)
|
||||
while cur_p is not None:
|
||||
pn: str = llvmlite.param_get_name(cur_p)
|
||||
if pn is not None and string.strcmp(pn, "%__eh_msg_out__") == 0:
|
||||
@@ -168,16 +168,16 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin):
|
||||
# ============================================================
|
||||
|
||||
# ============================================================
|
||||
def _emit_eh_guarded_call(self, builder: llvmlite.IRBuilder | t.CPtr,
|
||||
def _emit_eh_guarded_call(self, builder: rawptr[llvmlite.IRBuilder],
|
||||
pool: rawptr[memhub.MemBuddy],
|
||||
mod: rawptr[llvmlite.LLVMModule],
|
||||
trans: rawptr[HT.Translator],
|
||||
func: rawptr[llvmlite.Function],
|
||||
call_name: str,
|
||||
head: llvmlite.Value | t.CPtr,
|
||||
head: rawptr[llvmlite.Value],
|
||||
count: int,
|
||||
ret_ty: rawptr[llvmlite.LLVMType],
|
||||
is_variadic: int) -> llvmlite.Value | t.CPtr:
|
||||
is_variadic: int) -> rawptr[llvmlite.Value]:
|
||||
"""带 try-except EH 检测的函数调用,返回 call 结果(检查后位于 ok 块)"""
|
||||
if trans is None or self._func_has_eh_params(func) == 0:
|
||||
return llvmlite.build_call(builder, call_name, head, count, ret_ty, is_variadic)
|
||||
@@ -187,8 +187,8 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin):
|
||||
i32_ty_g: rawptr[llvmlite.LLVMType] = llvmlite.Int32(pool)
|
||||
if i8_ty_g is None or i8_ptr_ty_g is None or i32_ty_g is None:
|
||||
return llvmlite.build_call(builder, call_name, head, count, ret_ty, is_variadic)
|
||||
msg_ptr: llvmlite.Value | t.CPtr = None
|
||||
code_ptr: llvmlite.Value | t.CPtr = None
|
||||
msg_ptr: rawptr[llvmlite.Value] = None
|
||||
code_ptr: rawptr[llvmlite.Value] = None
|
||||
if trans._eh_msg_ptr is not None and trans._eh_code_ptr is not None:
|
||||
msg_ptr = trans._eh_msg_ptr
|
||||
code_ptr = trans._eh_code_ptr
|
||||
@@ -200,8 +200,8 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin):
|
||||
msg_ptr = self.Gen.VarGen._alloca_at_entry(builder, i8_ptr_ty_g)
|
||||
code_ptr = self.Gen.VarGen._alloca_at_entry(builder, i32_ty_g)
|
||||
# ---- 2. 调用前清零 ----
|
||||
null_msg_g: llvmlite.Value | t.CPtr = llvmlite.ConstNull(pool, i8_ptr_ty_g, "null")
|
||||
zero_code_g: llvmlite.Value | t.CPtr = llvmlite.const_int32(pool, 0)
|
||||
null_msg_g: rawptr[llvmlite.Value] = llvmlite.ConstNull(pool, i8_ptr_ty_g, "null")
|
||||
zero_code_g: rawptr[llvmlite.Value] = llvmlite.const_int32(pool, 0)
|
||||
if null_msg_g is not None:
|
||||
llvmlite.build_store(builder, null_msg_g, msg_ptr)
|
||||
if zero_code_g is not None:
|
||||
@@ -212,22 +212,22 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin):
|
||||
if head is None:
|
||||
head = msg_ptr
|
||||
else:
|
||||
tail_g: llvmlite.Value | t.CPtr = head
|
||||
tail_g: rawptr[llvmlite.Value] = head
|
||||
while tail_g.Next is not None:
|
||||
tail_g = tail_g.Next
|
||||
tail_g.Next = msg_ptr
|
||||
count = count + 2
|
||||
# ---- 4. 调用 + 检查 ----
|
||||
result: llvmlite.Value | t.CPtr = llvmlite.build_call(
|
||||
result: rawptr[llvmlite.Value] = llvmlite.build_call(
|
||||
builder, call_name, head, count, ret_ty, is_variadic)
|
||||
cur_func_g: rawptr[llvmlite.Function] = trans._cur_func
|
||||
if cur_func_g is None or null_msg_g is None:
|
||||
return result
|
||||
msg_val_g: llvmlite.Value | t.CPtr = llvmlite.build_load(
|
||||
msg_val_g: rawptr[llvmlite.Value] = llvmlite.build_load(
|
||||
builder, i8_ptr_ty_g, msg_ptr)
|
||||
if msg_val_g is None:
|
||||
return result
|
||||
is_err_g: llvmlite.Value | t.CPtr = llvmlite.build_icmp(
|
||||
is_err_g: rawptr[llvmlite.Value] = llvmlite.build_icmp(
|
||||
builder, llvmlite.ICMP_NE, msg_val_g, null_msg_g)
|
||||
if is_err_g is None:
|
||||
return result
|
||||
@@ -237,10 +237,10 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin):
|
||||
if bb_buf_g is None:
|
||||
return result
|
||||
viperlib.snprintf(bb_buf_g, 64, "eh.err.%d", lc_g)
|
||||
err_bb_g: llvmlite.BasicBlock | t.CPtr = llvmlite.create_block(
|
||||
err_bb_g: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(
|
||||
pool, cur_func_g, bb_buf_g)
|
||||
viperlib.snprintf(bb_buf_g, 64, "eh.ok.%d", lc_g)
|
||||
ok_bb_g: llvmlite.BasicBlock | t.CPtr = llvmlite.create_block(
|
||||
ok_bb_g: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(
|
||||
pool, cur_func_g, bb_buf_g)
|
||||
if err_bb_g is None or ok_bb_g is None:
|
||||
return result
|
||||
@@ -262,17 +262,17 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin):
|
||||
case llvmlite.LLVMType.Void():
|
||||
llvmlite.build_ret_void(builder)
|
||||
case llvmlite.LLVMType.Ptr(_pg):
|
||||
nv_g: llvmlite.Value | t.CPtr = llvmlite.ConstNull(
|
||||
nv_g: rawptr[llvmlite.Value] = llvmlite.ConstNull(
|
||||
pool, ret_ty_g2, "null")
|
||||
if nv_g is not None:
|
||||
llvmlite.build_ret(builder, nv_g)
|
||||
case llvmlite.LLVMType.Float(_fg):
|
||||
zf_g: llvmlite.Value | t.CPtr = llvmlite.ConstFloat(
|
||||
zf_g: rawptr[llvmlite.Value] = llvmlite.ConstFloat(
|
||||
pool, ret_ty_g2, 0.0)
|
||||
if zf_g is not None:
|
||||
llvmlite.build_ret(builder, zf_g)
|
||||
case _:
|
||||
zv_g: llvmlite.Value | t.CPtr = llvmlite.ConstZero(
|
||||
zv_g: rawptr[llvmlite.Value] = llvmlite.ConstZero(
|
||||
pool, ret_ty_g2)
|
||||
if zv_g is not None:
|
||||
llvmlite.build_ret(builder, zv_g)
|
||||
@@ -294,27 +294,27 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin):
|
||||
|
||||
|
||||
def _translate_isinstance(self, pool: rawptr[memhub.MemBuddy],
|
||||
builder: llvmlite.IRBuilder | t.CPtr,
|
||||
builder: rawptr[llvmlite.IRBuilder],
|
||||
mod: rawptr[llvmlite.LLVMModule],
|
||||
obj_node: rawptr[ast.AST],
|
||||
cls_node: rawptr[ast.AST],
|
||||
trans: rawptr[HT.Translator] = None) -> llvmlite.Value | t.CPtr:
|
||||
trans: rawptr[HT.Translator] = None) -> rawptr[llvmlite.Value]:
|
||||
"""isinstance(obj, Cls):运行时 vtable 子类集合比较,返回 i1"""
|
||||
if obj_node is None or cls_node is None:
|
||||
# 参数缺失即调用错误:fail-fast,绝不返回 True 掩盖
|
||||
self.Gen.TypeGenErr.fatal_error(cls_node, "isinstance() 参数类型推断失败", "TypeError")
|
||||
obj_val: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
|
||||
obj_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, obj_node, None, 0, trans)
|
||||
if obj_val is None or obj_val.Ty is None:
|
||||
# obj 类型推断失败:fail-fast,绝不返回 True 掩盖
|
||||
self.Gen.TypeGenErr.fatal_error(cls_node, "isinstance() 参数类型推断失败", "TypeError")
|
||||
# 对象指针规整:二级指针(变量 alloca / 联合 Class|t.CPtr)先 load
|
||||
obj_ptr: llvmlite.Value | t.CPtr = obj_val
|
||||
obj_ptr: rawptr[llvmlite.Value] = obj_val
|
||||
match obj_val.Ty:
|
||||
case llvmlite.LLVMType.Ptr(inner_ty):
|
||||
match inner_ty:
|
||||
case llvmlite.LLVMType.Ptr(_):
|
||||
loaded: llvmlite.Value | t.CPtr = llvmlite.build_load(
|
||||
loaded: rawptr[llvmlite.Value] = llvmlite.build_load(
|
||||
builder, inner_ty, obj_val)
|
||||
if loaded is not None:
|
||||
obj_ptr = loaded
|
||||
@@ -325,9 +325,9 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin):
|
||||
i8_ptr_ty: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, i8_ty)
|
||||
i8_ptr_ptr_ty: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, i8_ptr_ty)
|
||||
# 对象 vtable 指针惰性读取(首个 CVTable 类比较时执行一次)
|
||||
vtable_ptr: llvmlite.Value | t.CPtr = None
|
||||
vtable_ptr: rawptr[llvmlite.Value] = None
|
||||
vtable_ready: int = 0
|
||||
res: llvmlite.Value | t.CPtr = None
|
||||
res: rawptr[llvmlite.Value] = None
|
||||
cls_names: sizet | t.CPtr = self._extract_isinstance_class_names(pool, cls_node)
|
||||
if cls_names is None:
|
||||
# 类名提取失败:fail-fast,绝不返回 True 掩盖
|
||||
@@ -340,7 +340,7 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin):
|
||||
or self.Gen.StructGen.has_vtable_by_name(cn) == 0:
|
||||
# NoVTable / 未知类 → 编译时静态判断(obj 静态类型 MRO)
|
||||
st: int = self._isinstance_compile_time(pool, obj_ptr, cn)
|
||||
c1: llvmlite.Value | t.CPtr = llvmlite.const_int(pool, 1, 1 if st > 0 else 0)
|
||||
c1: rawptr[llvmlite.Value] = llvmlite.const_int(pool, 1, 1 if st > 0 else 0)
|
||||
if res is None:
|
||||
res = c1
|
||||
else:
|
||||
@@ -348,7 +348,7 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin):
|
||||
elif obj_is_ptr != 0:
|
||||
# CVTable → 运行时 vtable 比较(读对象头部 vtable 指针)
|
||||
if vtable_ready == 0:
|
||||
vtable_slot: llvmlite.Value | t.CPtr = llvmlite.build_bitcast(
|
||||
vtable_slot: rawptr[llvmlite.Value] = llvmlite.build_bitcast(
|
||||
builder, obj_ptr, i8_ptr_ptr_ty)
|
||||
if vtable_slot is not None:
|
||||
vtable_ptr = llvmlite.build_load(builder, i8_ptr_ty, vtable_slot)
|
||||
@@ -360,10 +360,10 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin):
|
||||
while subs[k] != 0:
|
||||
scn: str = (str | t.CPtr)(subs[k])
|
||||
if scn is not None:
|
||||
sub_i8: llvmlite.Value | t.CPtr = self._make_vtable_ref_i8(
|
||||
sub_i8: rawptr[llvmlite.Value] = self._make_vtable_ref_i8(
|
||||
pool, builder, mod, scn, trans)
|
||||
if sub_i8 is not None:
|
||||
cmp: llvmlite.Value | t.CPtr = llvmlite.build_icmp(
|
||||
cmp: rawptr[llvmlite.Value] = llvmlite.build_icmp(
|
||||
builder, llvmlite.ICMP_EQ, vtable_ptr, sub_i8)
|
||||
if cmp is not None:
|
||||
if res is None:
|
||||
@@ -402,7 +402,7 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin):
|
||||
arr[0] = sizet(at.attr)
|
||||
elif k == ast.ASTKind.Tuple:
|
||||
tp: rawptr[ast.Tuple] = rawptr[ast.Tuple](node)
|
||||
elts: list[rawptr[ast.AST]] | t.CPtr = tp.elts
|
||||
elts: rawptr[list[rawptr[ast.AST]]] = tp.elts
|
||||
if elts is not None:
|
||||
n: sizet = len(elts)
|
||||
for i in range(n):
|
||||
@@ -462,7 +462,7 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin):
|
||||
if vcount < ISINSTANCE_CLASS_MAX:
|
||||
visited[vcount] = sizet(cur)
|
||||
vcount += 1
|
||||
centry: GenTypes.StructEntry | t.CPtr = self.Gen.StructGen.find_struct(cur)
|
||||
centry: rawptr[GenTypes.StructEntry] = self.Gen.StructGen.find_struct(cur)
|
||||
if centry is not None and centry.HasVTable != 0:
|
||||
if outcount < ISINSTANCE_CLASS_MAX:
|
||||
names[outcount] = sizet(cur)
|
||||
@@ -473,7 +473,7 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin):
|
||||
# 取条目,语义等价于"扫描全表收集子类",不可改为 find_struct。
|
||||
scnt: int = self.Gen.StructGen.get_struct_count()
|
||||
for i in range(scnt):
|
||||
e2: GenTypes.StructEntry | t.CPtr = self.Gen.StructGen._get_struct_entry(i)
|
||||
e2: rawptr[GenTypes.StructEntry] = self.Gen.StructGen._get_struct_entry(i)
|
||||
if e2 is None or e2.Name is None:
|
||||
continue
|
||||
if e2.ParentCount > 0 and e2.ParentNames is not None:
|
||||
@@ -492,10 +492,10 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin):
|
||||
|
||||
|
||||
def _make_vtable_ref_i8(self, pool: rawptr[memhub.MemBuddy],
|
||||
builder: llvmlite.IRBuilder | t.CPtr,
|
||||
builder: rawptr[llvmlite.IRBuilder],
|
||||
mod: rawptr[llvmlite.LLVMModule],
|
||||
class_name: str,
|
||||
trans: rawptr[HT.Translator] = None) -> llvmlite.Value | t.CPtr:
|
||||
trans: rawptr[HT.Translator] = None) -> rawptr[llvmlite.Value]:
|
||||
"""构造类 vtable 地址引用(i8*):本模块已定义直接引用,跨模块声明 external"""
|
||||
if class_name is None:
|
||||
return None
|
||||
@@ -519,27 +519,27 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin):
|
||||
return None
|
||||
# vtable 名含 sha1 点号前缀,一律 @"..." 引号形式
|
||||
viperlib.snprintf(ref_name, 256, "@\"%s\"", mangled)
|
||||
gv: llvmlite.GlobalVariable | t.CPtr = self.Gen.ExprGenAttr.find_global_in_module(mod, mangled)
|
||||
gv: rawptr[llvmlite.GlobalVariable] = self.Gen.ExprGenAttr.find_global_in_module(mod, mangled)
|
||||
ref_ty: rawptr[llvmlite.LLVMType] = None
|
||||
if gv is not None:
|
||||
# 本模块已定义 vtable(constant {i8* x N})→ 引用类型 Ptr(struct)
|
||||
ref_ty = llvmlite.Ptr(pool, gv.Ty)
|
||||
else:
|
||||
# 跨模块:声明 @mangled = external global i8*,引用类型 i8**
|
||||
gv2: llvmlite.GlobalVariable | t.CPtr = llvmlite.new_global_variable(
|
||||
gv2: rawptr[llvmlite.GlobalVariable] = llvmlite.new_global_variable(
|
||||
pool, mangled, i8_ptr_ty)
|
||||
if gv2 is None:
|
||||
return None
|
||||
llvmlite.module_add_global(mod, gv2)
|
||||
ref_ty = llvmlite.Ptr(pool, i8_ptr_ty)
|
||||
ref: llvmlite.Value | t.CPtr = llvmlite.SSAValue(pool, ref_ty, ref_name)
|
||||
ref: rawptr[llvmlite.Value] = llvmlite.SSAValue(pool, ref_ty, ref_name)
|
||||
if ref is None:
|
||||
return None
|
||||
return llvmlite.build_bitcast(builder, ref, i8_ptr_ty)
|
||||
|
||||
|
||||
def _isinstance_compile_time(self, pool: rawptr[memhub.MemBuddy],
|
||||
obj_ptr: llvmlite.Value | t.CPtr,
|
||||
obj_ptr: rawptr[llvmlite.Value],
|
||||
class_name: str) -> int:
|
||||
"""编译时静态判断:obj 静态类型 == class_name 或 class_name 在其 MRO 中"""
|
||||
if obj_ptr is None or obj_ptr.Ty is None or class_name is None:
|
||||
@@ -571,12 +571,12 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin):
|
||||
|
||||
|
||||
def translate_closure_call(self, pool: rawptr[memhub.MemBuddy],
|
||||
builder: llvmlite.IRBuilder | t.CPtr,
|
||||
builder: rawptr[llvmlite.IRBuilder],
|
||||
mod: rawptr[llvmlite.LLVMModule],
|
||||
closure_alloca: llvmlite.Value | t.CPtr,
|
||||
cargs: list[rawptr[ast.AST]] | t.CPtr,
|
||||
closure_alloca: rawptr[llvmlite.Value],
|
||||
cargs: rawptr[list[rawptr[ast.AST]]],
|
||||
can: sizet,
|
||||
trans: rawptr[HT.Translator] = None) -> llvmlite.Value | t.CPtr:
|
||||
trans: rawptr[HT.Translator] = None) -> rawptr[llvmlite.Value]:
|
||||
"""通过闭包指针间接调用(支持带参 lambda:i32(i8*, args...))"""
|
||||
if builder is None or closure_alloca is None:
|
||||
return None
|
||||
@@ -586,31 +586,31 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin):
|
||||
i32_ty: rawptr[llvmlite.LLVMType] = llvmlite.Int32(pool)
|
||||
|
||||
# 1. 加载闭包指针 (i8*)
|
||||
closure_ptr: llvmlite.Value | t.CPtr = llvmlite.build_load(builder, i8_ptr_ty, closure_alloca)
|
||||
closure_ptr: rawptr[llvmlite.Value] = llvmlite.build_load(builder, i8_ptr_ty, closure_alloca)
|
||||
if closure_ptr is None:
|
||||
return None
|
||||
|
||||
# 2. 加载 fn_ptr (offset 0): bitcast to i8**, load i8*
|
||||
fn_ptr_addr: llvmlite.Value | t.CPtr = llvmlite.build_bitcast(builder, closure_ptr, llvmlite.Ptr(pool, i8_ptr_ty))
|
||||
fn_ptr_addr: rawptr[llvmlite.Value] = llvmlite.build_bitcast(builder, closure_ptr, llvmlite.Ptr(pool, i8_ptr_ty))
|
||||
if fn_ptr_addr is None:
|
||||
return None
|
||||
fn_raw: llvmlite.Value | t.CPtr = llvmlite.build_load(builder, i8_ptr_ty, fn_ptr_addr)
|
||||
fn_raw: rawptr[llvmlite.Value] = llvmlite.build_load(builder, i8_ptr_ty, fn_ptr_addr)
|
||||
if fn_raw is None:
|
||||
return None
|
||||
|
||||
# 3. 加载 env_ptr (offset 8): GEP i8, closure, 8; load i8*
|
||||
eight_val: llvmlite.Value | t.CPtr = llvmlite.const_int32(pool, 8)
|
||||
env_addr: llvmlite.Value | t.CPtr = llvmlite.build_gep(builder, i8_ty, closure_ptr, eight_val)
|
||||
eight_val: rawptr[llvmlite.Value] = llvmlite.const_int32(pool, 8)
|
||||
env_addr: rawptr[llvmlite.Value] = llvmlite.build_gep(builder, i8_ty, closure_ptr, eight_val)
|
||||
if env_addr is None:
|
||||
return None
|
||||
env_ptr: llvmlite.Value | t.CPtr = llvmlite.build_load(builder, i8_ptr_ty, env_addr)
|
||||
env_ptr: rawptr[llvmlite.Value] = llvmlite.build_load(builder, i8_ptr_ty, env_addr)
|
||||
if env_ptr is None:
|
||||
return None
|
||||
|
||||
# 4. 构建参数:env 头 + 实参尾(带参 lambda 时翻译实参)
|
||||
total_args: int = 1
|
||||
arg_head: llvmlite.Value | t.CPtr = env_ptr
|
||||
arg_tail: llvmlite.Value | t.CPtr = env_ptr
|
||||
arg_head: rawptr[llvmlite.Value] = env_ptr
|
||||
arg_tail: rawptr[llvmlite.Value] = env_ptr
|
||||
param_node: rawptr[llvmlite.Function] = llvmlite.new_param_node(pool, i8_ptr_ty)
|
||||
pn_tail: rawptr[llvmlite.Function] = param_node
|
||||
if can > 0 and cargs is not None and trans is not None:
|
||||
@@ -618,7 +618,7 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin):
|
||||
arg: rawptr[ast.AST] = cargs.get(ai)
|
||||
if arg is None:
|
||||
continue
|
||||
arg_val: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
|
||||
arg_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, arg, None, 0, trans)
|
||||
if arg_val is None or arg_val.Ty is None:
|
||||
continue
|
||||
@@ -637,7 +637,7 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin):
|
||||
# 5. bitcast fn_raw 到函数指针类型 i32(i8*, [args...])*
|
||||
func_ty: rawptr[llvmlite.LLVMType] = llvmlite.Func(pool, i32_ty, param_node, total_args)
|
||||
func_ptr_ty: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, func_ty)
|
||||
fn_typed: llvmlite.Value | t.CPtr = llvmlite.build_bitcast(builder, fn_raw, func_ptr_ty)
|
||||
fn_typed: rawptr[llvmlite.Value] = llvmlite.build_bitcast(builder, fn_raw, func_ptr_ty)
|
||||
if fn_typed is None:
|
||||
return None
|
||||
|
||||
@@ -645,7 +645,7 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin):
|
||||
return llvmlite.build_call_indirect(builder, fn_typed, arg_head, total_args, i32_ty)
|
||||
|
||||
|
||||
def _is_func_ptr_alloca(self, alloca: llvmlite.Value | t.CPtr) -> int:
|
||||
def _is_func_ptr_alloca(self, alloca: rawptr[llvmlite.Value]) -> int:
|
||||
"""判断 alloca 是否为函数指针变量(类型 Ptr(Ptr(i8))),1=是 / 0=否"""
|
||||
if alloca is None or alloca.Ty is None:
|
||||
return 0
|
||||
@@ -739,13 +739,13 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin):
|
||||
|
||||
|
||||
def _translate_func_ptr_call(self, pool: rawptr[memhub.MemBuddy],
|
||||
builder: llvmlite.IRBuilder | t.CPtr,
|
||||
builder: rawptr[llvmlite.IRBuilder],
|
||||
mod: rawptr[llvmlite.LLVMModule],
|
||||
fp_alloca: llvmlite.Value | t.CPtr,
|
||||
fp_alloca: rawptr[llvmlite.Value],
|
||||
func_name: str,
|
||||
cargs: list[rawptr[ast.AST]] | t.CPtr,
|
||||
cargs: rawptr[list[rawptr[ast.AST]]],
|
||||
can: sizet,
|
||||
trans: rawptr[HT.Translator]) -> llvmlite.Value | t.CPtr:
|
||||
trans: rawptr[HT.Translator]) -> rawptr[llvmlite.Value]:
|
||||
"""函数指针变量间接调用,返回结果 Value"""
|
||||
if builder is None or fp_alloca is None:
|
||||
return None
|
||||
@@ -754,19 +754,19 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin):
|
||||
i32_ty: rawptr[llvmlite.LLVMType] = llvmlite.Int32(pool)
|
||||
|
||||
# 1. load 函数地址 (i8*)
|
||||
fn_i8: llvmlite.Value | t.CPtr = llvmlite.build_load(builder, i8_ptr_ty, fp_alloca)
|
||||
fn_i8: rawptr[llvmlite.Value] = llvmlite.build_load(builder, i8_ptr_ty, fp_alloca)
|
||||
if fn_i8 is None:
|
||||
return None
|
||||
|
||||
# 2. 翻译实参并链接为 Value 链表
|
||||
head: llvmlite.Value | t.CPtr = None
|
||||
tail: llvmlite.Value | t.CPtr = None
|
||||
head: rawptr[llvmlite.Value] = None
|
||||
tail: rawptr[llvmlite.Value] = None
|
||||
arg_count: int = 0
|
||||
ai: sizet
|
||||
for ai in range(can):
|
||||
arg: rawptr[ast.AST] = cargs.get(ai)
|
||||
if arg is not None:
|
||||
arg_val: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
|
||||
arg_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, arg, None, 0, trans)
|
||||
if arg_val is not None:
|
||||
arg_val.Next = None
|
||||
@@ -787,7 +787,7 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin):
|
||||
ret_ty = i32_ty
|
||||
fp_first: rawptr[llvmlite.Function] = None
|
||||
fp_prev: rawptr[llvmlite.Function] = None
|
||||
cur_v: llvmlite.Value | t.CPtr = head
|
||||
cur_v: rawptr[llvmlite.Value] = head
|
||||
for pi in range(arg_count):
|
||||
if cur_v is None:
|
||||
break
|
||||
@@ -807,19 +807,19 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin):
|
||||
func_ptr_ty: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, func_ty)
|
||||
|
||||
# 4. bitcast i8* → 函数指针类型,间接调用
|
||||
fn_typed: llvmlite.Value | t.CPtr = llvmlite.build_bitcast(builder, fn_i8, func_ptr_ty)
|
||||
fn_typed: rawptr[llvmlite.Value] = llvmlite.build_bitcast(builder, fn_i8, func_ptr_ty)
|
||||
if fn_typed is None:
|
||||
return None
|
||||
return llvmlite.build_call_indirect(builder, fn_typed, head, arg_count, ret_ty)
|
||||
|
||||
|
||||
def translate_printf_call(self, pool: rawptr[memhub.MemBuddy],
|
||||
builder: llvmlite.IRBuilder | t.CPtr,
|
||||
builder: rawptr[llvmlite.IRBuilder],
|
||||
mod: rawptr[llvmlite.LLVMModule],
|
||||
cl: rawptr[ast.Call],
|
||||
trans: rawptr[HT.Translator] = None) -> None:
|
||||
"""翻译 printf 调用(特殊处理格式字符串)"""
|
||||
cargs: list[rawptr[ast.AST]] | t.CPtr = cl.args
|
||||
cargs: rawptr[list[rawptr[ast.AST]]] = cl.args
|
||||
if cargs is None:
|
||||
return
|
||||
can: sizet = len(cargs)
|
||||
@@ -840,7 +840,7 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin):
|
||||
if fmt_str is None:
|
||||
return
|
||||
|
||||
fmt_ptr: llvmlite.Value | t.CPtr = self.Gen.ExprGenConst.create_global_string(
|
||||
fmt_ptr: rawptr[llvmlite.Value] = self.Gen.ExprGenConst.create_global_string(
|
||||
builder, pool, mod, fmt_str, trans)
|
||||
if fmt_ptr is None:
|
||||
return
|
||||
@@ -848,11 +848,11 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin):
|
||||
i32_ty: rawptr[llvmlite.LLVMType] = llvmlite.Int32(pool)
|
||||
|
||||
# 翻译额外参数并链接
|
||||
prev: llvmlite.Value | t.CPtr = fmt_ptr
|
||||
prev: rawptr[llvmlite.Value] = fmt_ptr
|
||||
for ai in range(1, can):
|
||||
arg: rawptr[ast.AST] = cargs.get(ai)
|
||||
if arg is not None:
|
||||
arg_val: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
|
||||
arg_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, arg, None, 0, trans)
|
||||
if arg_val is not None:
|
||||
# C ABI integer promotion: i8/i16 → i32(printf 变参函数要求)
|
||||
@@ -875,12 +875,12 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin):
|
||||
|
||||
|
||||
def translate_print_call(self, pool: rawptr[memhub.MemBuddy],
|
||||
builder: llvmlite.IRBuilder | t.CPtr,
|
||||
builder: rawptr[llvmlite.IRBuilder],
|
||||
mod: rawptr[llvmlite.LLVMModule],
|
||||
cl: rawptr[ast.Call],
|
||||
trans: rawptr[HT.Translator] = None) -> None:
|
||||
"""翻译 print 调用(类型感知格式化 + 默认换行)"""
|
||||
cargs: list[rawptr[ast.AST]] | t.CPtr = cl.args
|
||||
cargs: rawptr[list[rawptr[ast.AST]]] = cl.args
|
||||
if cargs is None:
|
||||
return
|
||||
|
||||
@@ -895,15 +895,15 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin):
|
||||
dbl_ty: rawptr[llvmlite.LLVMType] = llvmlite.Double(pool)
|
||||
|
||||
can: sizet = len(cargs)
|
||||
arg_head: llvmlite.Value | t.CPtr = None
|
||||
arg_tail: llvmlite.Value | t.CPtr = None
|
||||
arg_head: rawptr[llvmlite.Value] = None
|
||||
arg_tail: rawptr[llvmlite.Value] = None
|
||||
arg_count: int = 1 # 格式串本身是第 1 个 printf 参数
|
||||
|
||||
for ai in range(can):
|
||||
arg: rawptr[ast.AST] = cargs.get(ai)
|
||||
if arg is None:
|
||||
continue
|
||||
arg_val: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
|
||||
arg_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, arg, None, 0, trans)
|
||||
if arg_val is None or arg_val.Ty is None:
|
||||
# fail-fast:print 参数翻译失败必须终止编译,绝不在格式串写
|
||||
@@ -916,12 +916,12 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin):
|
||||
# translate_value 会 load 出数组值([N x T]),print 无法格式化;
|
||||
# 按数组退化语义取数组 alloca 地址——字符数组 → %s(打印字符串内容),
|
||||
# 其他元素类型 → 0x%llx(打印数组地址)。
|
||||
array_ptr: llvmlite.Value | t.CPtr = None
|
||||
array_ptr: rawptr[llvmlite.Value] = None
|
||||
array_elem_bits: int = 0
|
||||
if arg.kind() == ast.ASTKind.Name and trans is not None:
|
||||
anm: rawptr[ast.Name] = rawptr[ast.Name](arg)
|
||||
if anm.id is not None:
|
||||
arr_alloca: llvmlite.Value | t.CPtr = self.Gen.VarGen.lookup_var(
|
||||
arr_alloca: rawptr[llvmlite.Value] = self.Gen.VarGen.lookup_var(
|
||||
trans.SymTab, anm.id)
|
||||
if arr_alloca is not None and arr_alloca.Ty is not None \
|
||||
and self.Gen.ExprGenBase.is_ptr_type(arr_alloca.Ty) != 0:
|
||||
@@ -997,7 +997,7 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin):
|
||||
if string.strlen(fmt_buf) < FMT_BUF_SIZE - 2:
|
||||
viperlib.snprintf(fmt_buf + string.strlen(fmt_buf), 2, "\n")
|
||||
|
||||
fmt_ptr: llvmlite.Value | t.CPtr = self.Gen.ExprGenConst.create_global_string(
|
||||
fmt_ptr: rawptr[llvmlite.Value] = self.Gen.ExprGenConst.create_global_string(
|
||||
builder, pool, mod, fmt_buf, trans)
|
||||
stdlib.free(fmt_buf)
|
||||
if fmt_ptr is None:
|
||||
@@ -1203,20 +1203,20 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin):
|
||||
|
||||
|
||||
# _build_func_spec:由函数对象构造整签名 TypeSpec(S3 条目双写)——Kind=TS_FUNC,含 Ret + 形参 Spec 数组 + ParamCount + IsVarArg,必须在形参全部 add_param 完成后调用。参数沿 function_get_param_head 的 Param 链表两遍遍历(先计数再填充,llvmlite 无按下标取参且无法预知长度)。与 TSpec.SpecFromLLVMType 的 Func 分支不同:后者不含变参信息(恒置 IsVarArg=0),故此处直接用 NewTypeFunc(..., func.IsVarArg)。失败返回 None,调用方保留 None 不造伪 spec
|
||||
def _build_func_spec(self, func: rawptr[llvmlite.Function]) -> TSpec.TypeSpec | t.CPtr:
|
||||
def _build_func_spec(self, func: rawptr[llvmlite.Function]) -> rawptr[TSpec.TypeSpec]:
|
||||
"""由函数对象构造整签名 TypeSpec,失败返回 None"""
|
||||
if func is None:
|
||||
return None
|
||||
arena: TSpec.TypeSpecArena | t.CPtr = self.Gen.TypeGenBase.ensure_spec_arena()
|
||||
arena: rawptr[TSpec.TypeSpecArena] = self.Gen.TypeGenBase.ensure_spec_arena()
|
||||
if arena is None:
|
||||
return None
|
||||
ret_s: TSpec.TypeSpec | t.CPtr = TSpec.SpecFromLLVMType(
|
||||
ret_s: rawptr[TSpec.TypeSpec] = TSpec.SpecFromLLVMType(
|
||||
arena, llvmlite.function_get_ret_ty(func))
|
||||
if ret_s is None:
|
||||
return None
|
||||
# 第一遍:计数
|
||||
cnt: int = 0
|
||||
cur: llvmlite.Param | t.CPtr = llvmlite.function_get_param_head(func)
|
||||
cur: rawptr[llvmlite.Param] = llvmlite.function_get_param_head(func)
|
||||
while cur is not None and cnt < 256:
|
||||
cnt += 1
|
||||
cur = llvmlite.param_get_next(cur)
|
||||
@@ -1229,7 +1229,7 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin):
|
||||
cur = llvmlite.function_get_param_head(func)
|
||||
i: int = 0
|
||||
while cur is not None and i < cnt:
|
||||
ps: TSpec.TypeSpec | t.CPtr = TSpec.SpecFromLLVMType(
|
||||
ps: rawptr[TSpec.TypeSpec] = TSpec.SpecFromLLVMType(
|
||||
arena, llvmlite.param_get_ty(cur))
|
||||
if ps is None:
|
||||
return None
|
||||
@@ -1325,7 +1325,7 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin):
|
||||
return 1
|
||||
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)(entry_addr)
|
||||
entry: rawptr[GenTypes.FuncDefaultsEntry] = rawptr[GenTypes.FuncDefaultsEntry](entry_addr)
|
||||
# Name 深拷贝到 stdlib(全局表跨文件永久存活)
|
||||
nm_len: sizet = string.strlen(name)
|
||||
nm_copy: str = CompilerFactory.factory.PermPool.alloc(nm_len + 1)
|
||||
@@ -1359,7 +1359,7 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin):
|
||||
string.memset(kinds, 0, default_count * 4)
|
||||
string.memset(ints, 0, default_count * 8)
|
||||
string.memset(strs, 0, default_count * 8)
|
||||
dl: list[rawptr[ast.AST]] | t.CPtr = (list[rawptr[ast.AST]] | t.CPtr)(uint64(defaults))
|
||||
dl: rawptr[list[rawptr[ast.AST]]] = rawptr[list[rawptr[ast.AST]]](uint64(defaults))
|
||||
di: int
|
||||
for di in range(default_count):
|
||||
dnode: rawptr[ast.AST] = dl.get(di)
|
||||
@@ -1413,7 +1413,7 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin):
|
||||
|
||||
|
||||
def find_func_defaults(self, name: str,
|
||||
module_sha1: str = None) -> GenTypes.FuncDefaultsEntry | t.CPtr:
|
||||
module_sha1: str = None) -> rawptr[GenTypes.FuncDefaultsEntry]:
|
||||
"""按函数名(可选按定义模块 SHA1)查找默认参数信息,返回 FuncDefaultsEntry 或 None
|
||||
|
||||
module_sha1 非 None 时要求条目定义模块完全一致(限定名匹配,消除跨模块同名串味);
|
||||
@@ -1424,7 +1424,7 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin):
|
||||
entry_size: sizet = GenTypes.FuncDefaultsEntry.__sizeof__()
|
||||
for i in range(self.GlobalDefaultsCount):
|
||||
entry_addr: uint64 = uint64(self.GlobalDefaults) + i * entry_size
|
||||
entry: GenTypes.FuncDefaultsEntry | t.CPtr = (GenTypes.FuncDefaultsEntry | t.CPtr)(entry_addr)
|
||||
entry: rawptr[GenTypes.FuncDefaultsEntry] = rawptr[GenTypes.FuncDefaultsEntry](entry_addr)
|
||||
if entry.Name is None:
|
||||
continue
|
||||
if string.strcmp(entry.Name, name) != 0:
|
||||
@@ -1440,10 +1440,10 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin):
|
||||
|
||||
def _build_const_from_snapshot(self, pool: rawptr[memhub.MemBuddy],
|
||||
mod: rawptr[llvmlite.LLVMModule],
|
||||
gd_entry: GenTypes.FuncDefaultsEntry | t.CPtr,
|
||||
gd_entry: rawptr[GenTypes.FuncDefaultsEntry],
|
||||
di: int,
|
||||
trans: rawptr[HT.Translator],
|
||||
builder: llvmlite.IRBuilder | t.CPtr) -> llvmlite.Value | t.CPtr:
|
||||
builder: rawptr[llvmlite.IRBuilder]) -> rawptr[llvmlite.Value]:
|
||||
"""从快照重建第 di 个默认值常量 IR"""
|
||||
if gd_entry is None or gd_entry.ConstKinds is None or gd_entry.ConstInts is None:
|
||||
return None
|
||||
@@ -1549,7 +1549,7 @@ class ExprCallHandle(HT.Mixin):
|
||||
# ============================================================
|
||||
# HandleCall - 翻译函数调用,返回 call 结果 Value
|
||||
# ============================================================
|
||||
def HandleCall(self, node: rawptr[ast.AST]) -> llvmlite.Value | t.CPtr:
|
||||
def HandleCall(self, node: rawptr[ast.AST]) -> rawptr[llvmlite.Value]:
|
||||
"""翻译函数调用,从 self.Trans 获取共享状态"""
|
||||
return GenApi.translate_call(
|
||||
self.Trans.Pool, self.Trans._cur_builder, self.Trans.Module,
|
||||
|
||||
@@ -114,11 +114,11 @@ class CallGenLib(CallGenBase.CallGenBase):
|
||||
return fn
|
||||
|
||||
def _promote_clib_call_args(self, pool: rawptr[memhub.MemBuddy],
|
||||
builder: llvmlite.IRBuilder | t.CPtr,
|
||||
builder: rawptr[llvmlite.IRBuilder],
|
||||
mod: rawptr[llvmlite.LLVMModule],
|
||||
call_name: str,
|
||||
head: llvmlite.Value | t.CPtr,
|
||||
count: int) -> llvmlite.Value | t.CPtr:
|
||||
head: rawptr[llvmlite.Value],
|
||||
count: int) -> rawptr[llvmlite.Value]:
|
||||
"""裸名 C 库函数实参按标准签名提升(B3)。
|
||||
|
||||
跨模块裸名调用(string.memset → @memset)时 _ensure_method_declare 用
|
||||
@@ -146,7 +146,7 @@ class CallGenLib(CallGenBase.CallGenBase):
|
||||
if size_idx < 0 or count <= size_idx:
|
||||
return head
|
||||
# 定位长度参数(index size_idx)
|
||||
cur: llvmlite.Value | t.CPtr = head
|
||||
cur: rawptr[llvmlite.Value] = head
|
||||
idx: int = 0
|
||||
while cur is not None and idx < size_idx:
|
||||
cur = cur.Next
|
||||
@@ -154,7 +154,7 @@ class CallGenLib(CallGenBase.CallGenBase):
|
||||
if cur is None or cur.Ty is None:
|
||||
return head
|
||||
i64_ty: rawptr[llvmlite.LLVMType] = llvmlite.Int64(pool)
|
||||
promoted: llvmlite.Value | t.CPtr = None
|
||||
promoted: rawptr[llvmlite.Value] = None
|
||||
match cur.Ty:
|
||||
case llvmlite.LLVMType.Int(bits):
|
||||
if bits >= 64:
|
||||
@@ -170,12 +170,12 @@ class CallGenLib(CallGenBase.CallGenBase):
|
||||
if promoted is None:
|
||||
return head
|
||||
# 重建实参链表:index size_idx 替换为提升后的值
|
||||
new_head: llvmlite.Value | t.CPtr = None
|
||||
new_tail: llvmlite.Value | t.CPtr = None
|
||||
cur2: llvmlite.Value | t.CPtr = head
|
||||
new_head: rawptr[llvmlite.Value] = None
|
||||
new_tail: rawptr[llvmlite.Value] = None
|
||||
cur2: rawptr[llvmlite.Value] = head
|
||||
i2: int = 0
|
||||
while cur2 is not None:
|
||||
node_v: llvmlite.Value | t.CPtr = cur2
|
||||
node_v: rawptr[llvmlite.Value] = cur2
|
||||
if i2 == size_idx:
|
||||
node_v = promoted
|
||||
if new_head is None:
|
||||
@@ -189,13 +189,13 @@ class CallGenLib(CallGenBase.CallGenBase):
|
||||
|
||||
# _coerce_args_to_def_params:按 vpi 定义侧形参注解把跨模块调用实参 coerce 到目标类型并重建实参链,使 call/declare/define 宽度一致;支持 {sha1}.{func} 与 {sha1}.{cls}.{method} 两形态(段下标与实参下标一一对应),裸名 C 库走 _promote_clib_call_args/_ensure_c_lib_declare,未命中原样保留
|
||||
def _coerce_args_to_def_params(self, pool: rawptr[memhub.MemBuddy],
|
||||
builder: llvmlite.IRBuilder | t.CPtr,
|
||||
builder: rawptr[llvmlite.IRBuilder],
|
||||
call_name: str,
|
||||
head: llvmlite.Value | t.CPtr,
|
||||
head: rawptr[llvmlite.Value],
|
||||
count: int,
|
||||
cargs: list[rawptr[ast.AST]] | t.CPtr = None,
|
||||
cargs: rawptr[list[rawptr[ast.AST]]] = None,
|
||||
self_off: int = 0,
|
||||
trans: rawptr[HT.Translator] = None) -> llvmlite.Value | t.CPtr:
|
||||
trans: rawptr[HT.Translator] = None) -> rawptr[llvmlite.Value]:
|
||||
"""把跨模块调用实参 coerce 到 vpi 定义侧形参类型,返回重建的实参链
|
||||
|
||||
cargs/self_off/trans:实参 AST 列表与其在实参链中的偏移(模块级函数 0、
|
||||
@@ -251,12 +251,12 @@ class CallGenLib(CallGenBase.CallGenBase):
|
||||
return head
|
||||
i32_ty: rawptr[llvmlite.LLVMType] = llvmlite.Int32(pool)
|
||||
i8_ptr_ty: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, llvmlite.Int8(pool))
|
||||
new_head: llvmlite.Value | t.CPtr = None
|
||||
new_tail: llvmlite.Value | t.CPtr = None
|
||||
cur: llvmlite.Value | t.CPtr = head
|
||||
new_head: rawptr[llvmlite.Value] = None
|
||||
new_tail: rawptr[llvmlite.Value] = None
|
||||
cur: rawptr[llvmlite.Value] = head
|
||||
idx: int = 0
|
||||
while cur is not None and idx < count:
|
||||
node_v: llvmlite.Value | t.CPtr = cur
|
||||
node_v: rawptr[llvmlite.Value] = cur
|
||||
tgt_ty: rawptr[llvmlite.LLVMType] = None
|
||||
if tpl_src != 0:
|
||||
tgt_ty = VpiReader._resolve_vpi_param_annot_seg_template(
|
||||
@@ -286,12 +286,12 @@ class CallGenLib(CallGenBase.CallGenBase):
|
||||
|
||||
# _coerce_arg_value_to_ty:单个实参 Value 转换到目标形参类型——整型同宽原样、窄化 trunc/按宽度重建常量、扩宽按源符号性 zext/sext;指针 i8* 性不同则 bitcast;其余原样返回(不可转换亦不改型)
|
||||
def _coerce_arg_value_to_ty(self, pool: rawptr[memhub.MemBuddy],
|
||||
builder: llvmlite.IRBuilder | t.CPtr,
|
||||
val: llvmlite.Value | t.CPtr,
|
||||
builder: rawptr[llvmlite.IRBuilder],
|
||||
val: rawptr[llvmlite.Value],
|
||||
tgt_ty: rawptr[llvmlite.LLVMType],
|
||||
node: rawptr[ast.AST] = None,
|
||||
trans: rawptr[HT.Translator] = None,
|
||||
tpl_src: int = 0) -> llvmlite.Value | t.CPtr:
|
||||
tpl_src: int = 0) -> rawptr[llvmlite.Value]:
|
||||
"""把单个实参 Value 转换到目标形参类型,无法安全转换时原样返回
|
||||
|
||||
node/trans:实参 AST 与其翻译器(仅 SSA 整型扩宽的源符号性判定用,
|
||||
@@ -310,18 +310,18 @@ class CallGenLib(CallGenBase.CallGenBase):
|
||||
return val
|
||||
if bits_b < bits_a:
|
||||
if val.IsConst != 0:
|
||||
nv_c: llvmlite.Value | t.CPtr = llvmlite.const_int(
|
||||
nv_c: rawptr[llvmlite.Value] = llvmlite.const_int(
|
||||
pool, bits_b, val.IntVal)
|
||||
if nv_c is not None:
|
||||
return nv_c
|
||||
else:
|
||||
nv_t: llvmlite.Value | t.CPtr = llvmlite.build_trunc(
|
||||
nv_t: rawptr[llvmlite.Value] = llvmlite.build_trunc(
|
||||
builder, val, tgt_ty)
|
||||
if nv_t is not None:
|
||||
return nv_t
|
||||
# 扩宽(实参窄于形参):编译期常量按十进制值重建,各自保持原类型数值,无需 AST 判符号性
|
||||
if val.IsConst != 0:
|
||||
nv_w: llvmlite.Value | t.CPtr = llvmlite.const_int(
|
||||
nv_w: rawptr[llvmlite.Value] = llvmlite.const_int(
|
||||
pool, bits_b, val.IntVal)
|
||||
if nv_w is not None:
|
||||
return nv_w
|
||||
@@ -330,12 +330,12 @@ class CallGenLib(CallGenBase.CallGenBase):
|
||||
if bits_b > bits_a:
|
||||
if self.Gen.ExprGenBase._zext_or_sext_val(
|
||||
pool, val, node, trans) != 0:
|
||||
nv_zw: llvmlite.Value | t.CPtr = llvmlite.build_zext(
|
||||
nv_zw: rawptr[llvmlite.Value] = llvmlite.build_zext(
|
||||
builder, val, tgt_ty)
|
||||
if nv_zw is not None:
|
||||
return nv_zw
|
||||
else:
|
||||
nv_sw: llvmlite.Value | t.CPtr = llvmlite.build_sext(
|
||||
nv_sw: rawptr[llvmlite.Value] = llvmlite.build_sext(
|
||||
builder, val, tgt_ty)
|
||||
if nv_sw is not None:
|
||||
return nv_sw
|
||||
@@ -360,13 +360,13 @@ class CallGenLib(CallGenBase.CallGenBase):
|
||||
case _:
|
||||
pass
|
||||
if ia != ib:
|
||||
nv_p: llvmlite.Value | t.CPtr = llvmlite.build_bitcast(
|
||||
nv_p: rawptr[llvmlite.Value] = llvmlite.build_bitcast(
|
||||
builder, val, tgt_ty)
|
||||
if nv_p is not None:
|
||||
return nv_p
|
||||
elif tpl_src != 0:
|
||||
# 模板注解来源:两侧同为具体结构体指针但基类型不同(实参 MemBuddy* vs 定义侧形参 MemManager*)⇒ bitcast 使 declare 指针口径与 define 一致
|
||||
nv_p2: llvmlite.Value | t.CPtr = llvmlite.build_bitcast(
|
||||
nv_p2: rawptr[llvmlite.Value] = llvmlite.build_bitcast(
|
||||
builder, val, tgt_ty)
|
||||
if nv_p2 is not None:
|
||||
return nv_p2
|
||||
@@ -378,7 +378,7 @@ class CallGenLib(CallGenBase.CallGenBase):
|
||||
case llvmlite.LLVMType.Ptr(_):
|
||||
vk_a: int = val.Ty.kind()
|
||||
if vk_a == llvmlite.LLVMType.Struct or vk_a == llvmlite.LLVMType.Array:
|
||||
tmp_a: llvmlite.Value | t.CPtr = self.Gen.VarGen._alloca_at_entry(
|
||||
tmp_a: rawptr[llvmlite.Value] = self.Gen.VarGen._alloca_at_entry(
|
||||
builder, val.Ty)
|
||||
if tmp_a is not None:
|
||||
llvmlite.build_store(builder, val, tmp_a)
|
||||
@@ -645,11 +645,11 @@ class CallGenLib(CallGenBase.CallGenBase):
|
||||
return 1
|
||||
return 0
|
||||
def _emit_llvm_memcpy_intrinsic(self, pool: rawptr[memhub.MemBuddy],
|
||||
builder: llvmlite.IRBuilder | t.CPtr,
|
||||
builder: rawptr[llvmlite.IRBuilder],
|
||||
mod: rawptr[llvmlite.LLVMModule],
|
||||
dst_val: llvmlite.Value | t.CPtr,
|
||||
src_val: llvmlite.Value | t.CPtr,
|
||||
num_val: llvmlite.Value | t.CPtr) -> llvmlite.Value | t.CPtr:
|
||||
dst_val: rawptr[llvmlite.Value],
|
||||
src_val: rawptr[llvmlite.Value],
|
||||
num_val: rawptr[llvmlite.Value]) -> rawptr[llvmlite.Value]:
|
||||
"""将 memcpy 调用映射到 @llvm.memcpy 内联函数
|
||||
|
||||
直接接收三个 Value 参数,避免通过 Next 链表遍历(共享 alloca 对象的
|
||||
@@ -682,7 +682,7 @@ class CallGenLib(CallGenBase.CallGenBase):
|
||||
i64_ty: rawptr[llvmlite.LLVMType] = llvmlite.Int64(pool)
|
||||
|
||||
# dst → i8*
|
||||
dst_coerced: llvmlite.Value | t.CPtr = dst_val
|
||||
dst_coerced: rawptr[llvmlite.Value] = dst_val
|
||||
dst_ty: rawptr[llvmlite.LLVMType] = llvmlite.value_get_ty(dst_val)
|
||||
if self.Gen.ExprGenBase.is_ptr_type(dst_ty) != 0:
|
||||
dst_coerced = llvmlite.build_bitcast(builder, dst_val, i8_ptr_ty)
|
||||
@@ -694,7 +694,7 @@ class CallGenLib(CallGenBase.CallGenBase):
|
||||
dst_coerced = llvmlite.build_inttoptr(builder, dst_coerced, i8_ptr_ty)
|
||||
|
||||
# src → i8*
|
||||
src_coerced: llvmlite.Value | t.CPtr = src_val
|
||||
src_coerced: rawptr[llvmlite.Value] = src_val
|
||||
src_ty: rawptr[llvmlite.LLVMType] = llvmlite.value_get_ty(src_val)
|
||||
if self.Gen.ExprGenBase.is_ptr_type(src_ty) != 0:
|
||||
src_coerced = llvmlite.build_bitcast(builder, src_val, i8_ptr_ty)
|
||||
@@ -706,13 +706,13 @@ class CallGenLib(CallGenBase.CallGenBase):
|
||||
src_coerced = llvmlite.build_inttoptr(builder, src_coerced, i8_ptr_ty)
|
||||
|
||||
# num → i64
|
||||
num_coerced: llvmlite.Value | t.CPtr = self.Gen.ExprGenBase.coerce_to_type(builder, num_val, i64_ty)
|
||||
num_coerced: rawptr[llvmlite.Value] = self.Gen.ExprGenBase.coerce_to_type(builder, num_val, i64_ty)
|
||||
|
||||
if dst_coerced is None or src_coerced is None or num_coerced is None:
|
||||
return None
|
||||
|
||||
# 添加 i1 false 参数(isvolatile)— llvm.memcpy 需要 4 个参数
|
||||
false_val: llvmlite.Value | t.CPtr = llvmlite.ConstInt(pool, llvmlite.Int1(pool), 0, "false")
|
||||
false_val: rawptr[llvmlite.Value] = llvmlite.ConstInt(pool, llvmlite.Int1(pool), 0, "false")
|
||||
|
||||
# 使用 includes 中的访问器函数构建参数链表,避免本地 Value 类型字段索引偏移
|
||||
# (f26cd4c78b4d554c.Value 缺少 GSListNode 的 Next 字段,直接访问 .Next 会修改 .Ty)
|
||||
@@ -726,7 +726,7 @@ class CallGenLib(CallGenBase.CallGenBase):
|
||||
|
||||
# 使用 build_call 发射 call 指令(内部用 includes Value 类型访问字段,索引正确)
|
||||
# _ll_name_needs_quote 已对 llvm. 前缀豁免引号
|
||||
result: llvmlite.Value | t.CPtr = llvmlite.build_call(builder, "llvm.memcpy", dst_coerced, 4, void_ty, 0)
|
||||
result: rawptr[llvmlite.Value] = llvmlite.build_call(builder, "llvm.memcpy", dst_coerced, 4, void_ty, 0)
|
||||
|
||||
# 返回 dst(匹配 C memcpy 语义: 返回 dest 指针)
|
||||
return dst_coerced
|
||||
@@ -734,35 +734,35 @@ class CallGenLib(CallGenBase.CallGenBase):
|
||||
|
||||
# ============================================================
|
||||
def _translate_call_with_kwargs(self, pool: rawptr[memhub.MemBuddy],
|
||||
builder: llvmlite.IRBuilder | t.CPtr,
|
||||
builder: rawptr[llvmlite.IRBuilder],
|
||||
mod: rawptr[llvmlite.LLVMModule],
|
||||
func_name: str,
|
||||
found_func: rawptr[llvmlite.Function],
|
||||
cargs: list[rawptr[ast.AST]] | t.CPtr,
|
||||
cargs: rawptr[list[rawptr[ast.AST]]],
|
||||
can: sizet,
|
||||
keywords: list[rawptr[ast.AST]] | t.CPtr,
|
||||
keywords: rawptr[list[rawptr[ast.AST]]],
|
||||
kw_count: sizet,
|
||||
trans: rawptr[HT.Translator]) -> llvmlite.Value | t.CPtr:
|
||||
trans: rawptr[HT.Translator]) -> rawptr[llvmlite.Value]:
|
||||
"""带关键字参数的函数调用,按参数顺序构建调用链表
|
||||
|
||||
使用 llvmlite 访问器函数绕过 stub 类型限制:
|
||||
found_func.Params/RetTy/Name 和 cur_param.Name/Ty/Next 在 stub
|
||||
类型中字段不足,直接访问会被 TransPyC 静默跳过。
|
||||
"""
|
||||
head: llvmlite.Value | t.CPtr = None
|
||||
tail: llvmlite.Value | t.CPtr = None
|
||||
head: rawptr[llvmlite.Value] = None
|
||||
tail: rawptr[llvmlite.Value] = None
|
||||
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
|
||||
mc_dst1: rawptr[llvmlite.Value] = None
|
||||
mc_src1: rawptr[llvmlite.Value] = None
|
||||
mc_num1: rawptr[llvmlite.Value] = None
|
||||
|
||||
# 遍历函数参数链表(使用访问器获取 Head)
|
||||
param_idx: sizet = 0
|
||||
cur_param: llvmlite.Param | t.CPtr = llvmlite.function_get_param_head(found_func)
|
||||
cur_param: rawptr[llvmlite.Param] = llvmlite.function_get_param_head(found_func)
|
||||
|
||||
while cur_param is not None:
|
||||
arg_val: llvmlite.Value | t.CPtr = None
|
||||
arg_val: rawptr[llvmlite.Value] = None
|
||||
param_ty: rawptr[llvmlite.LLVMType] = llvmlite.param_get_ty(cur_param)
|
||||
if param_idx < can:
|
||||
# 优先使用位置参数
|
||||
@@ -776,7 +776,7 @@ class CallGenLib(CallGenBase.CallGenBase):
|
||||
param_name: str = llvmlite.param_get_name(cur_param)
|
||||
if param_name is not None:
|
||||
for ki in range(kw_count):
|
||||
kw: ast.Keyword | t.CPtr = (ast.Keyword | t.CPtr)(keywords.get(ki))
|
||||
kw: rawptr[ast.Keyword] = rawptr[ast.Keyword](keywords.get(ki))
|
||||
if kw is None or kw.arg is None or kw.value is None:
|
||||
continue
|
||||
if self.Gen.CallGenCall._kwarg_name_matches(kw.arg, param_name) == 1:
|
||||
|
||||
@@ -62,12 +62,12 @@ class CallGenMixin(CallGenBase.CallGenBase):
|
||||
# 翻译函数调用 Call(func, args) — 模块级版本
|
||||
# ============================================================
|
||||
def translate_call(self, pool: rawptr[memhub.MemBuddy],
|
||||
builder: llvmlite.IRBuilder | t.CPtr,
|
||||
builder: rawptr[llvmlite.IRBuilder],
|
||||
mod: rawptr[llvmlite.LLVMModule],
|
||||
node: rawptr[ast.AST],
|
||||
funcs_ptr: t.CPtr,
|
||||
func_count: int,
|
||||
trans: rawptr[HT.Translator] = None) -> llvmlite.Value | t.CPtr:
|
||||
trans: rawptr[HT.Translator] = None) -> rawptr[llvmlite.Value]:
|
||||
"""翻译函数调用,返回 call 结果 Value"""
|
||||
cl: rawptr[ast.Call] = rawptr[ast.Call](node)
|
||||
if cl is None:
|
||||
@@ -75,7 +75,7 @@ class CallGenMixin(CallGenBase.CallGenBase):
|
||||
|
||||
func_name: str = self.Gen.ExprGenBase.get_func_name(cl.func)
|
||||
|
||||
cargs: list[rawptr[ast.AST]] | t.CPtr = cl.args
|
||||
cargs: rawptr[list[rawptr[ast.AST]]] = cl.args
|
||||
can: sizet = 0
|
||||
if cargs is not None:
|
||||
can = len(cargs)
|
||||
@@ -86,7 +86,7 @@ class CallGenMixin(CallGenBase.CallGenBase):
|
||||
h1_hit: t.CPtr = stdlib.malloc(4)
|
||||
if h1_hit is not None:
|
||||
h1_hit[0] = 0
|
||||
_tc_h1_super_ctraits_res: llvmlite.Value | t.CPtr = self.Gen.CallGenDispatch._tc_h1_super_ctraits(
|
||||
_tc_h1_super_ctraits_res: rawptr[llvmlite.Value] = self.Gen.CallGenDispatch._tc_h1_super_ctraits(
|
||||
pool, builder, mod, cl, funcs_ptr, func_count, trans, func_name, cargs, can, h1_hit)
|
||||
h1_hit_val: int = 0
|
||||
if h1_hit is not None:
|
||||
@@ -140,7 +140,7 @@ class CallGenMixin(CallGenBase.CallGenBase):
|
||||
sub_cast_ty: rawptr[llvmlite.LLVMType] = self.Gen.TypeGenResolve.resolve_annotation_type(
|
||||
pool, cl.func, trans._imported_modules, trans._from_imports, trans, 0)
|
||||
if sub_cast_ty is not None:
|
||||
sub_cast_arg: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
|
||||
sub_cast_arg: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, cl.args.get(0), funcs_ptr, func_count, trans)
|
||||
if sub_cast_arg is not None:
|
||||
return self.Gen.CallGenCtor._translate_t_type_cast(
|
||||
@@ -159,9 +159,9 @@ class CallGenMixin(CallGenBase.CallGenBase):
|
||||
binop_ty: rawptr[llvmlite.LLVMType] = self.Gen.TypeGenResolve.resolve_annotation_type(
|
||||
pool, cl.func, trans._imported_modules, trans._from_imports, trans, 0)
|
||||
if binop_ty is not None:
|
||||
binop_args: list[rawptr[ast.AST]] | t.CPtr = cl.args
|
||||
binop_args: rawptr[list[rawptr[ast.AST]]] = cl.args
|
||||
if binop_args is not None and len(binop_args) == 1:
|
||||
binop_arg_val: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
|
||||
binop_arg_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, binop_args.get(0), funcs_ptr, func_count, trans)
|
||||
if binop_arg_val is not None:
|
||||
return self.Gen.CallGenCtor._translate_t_type_cast(pool, builder, binop_arg_val, binop_ty)
|
||||
@@ -174,7 +174,7 @@ class CallGenMixin(CallGenBase.CallGenBase):
|
||||
h2_hit: t.CPtr = stdlib.malloc(4)
|
||||
if h2_hit is not None:
|
||||
h2_hit[0] = 0
|
||||
_tc_h2_c_special_res: llvmlite.Value | t.CPtr = self.Gen.CallGenDispatch._tc_h2_c_special(
|
||||
_tc_h2_c_special_res: rawptr[llvmlite.Value] = self.Gen.CallGenDispatch._tc_h2_c_special(
|
||||
pool, builder, mod, cl, funcs_ptr, func_count, trans, func_name, cargs, can, h2_hit)
|
||||
h2_hit_val: int = 0
|
||||
if h2_hit is not None:
|
||||
@@ -186,17 +186,17 @@ class CallGenMixin(CallGenBase.CallGenBase):
|
||||
# 命中 c.Asm/c.LLVMIR 但无返回值(void):视为已处理
|
||||
return None
|
||||
|
||||
_tc_h3_stdarg_cast_res: llvmlite.Value | t.CPtr = self.Gen.CallGenDispatch._tc_h3_stdarg_cast(
|
||||
_tc_h3_stdarg_cast_res: rawptr[llvmlite.Value] = self.Gen.CallGenDispatch._tc_h3_stdarg_cast(
|
||||
pool, builder, mod, cl, funcs_ptr, func_count, trans, func_name, cargs, can)
|
||||
if _tc_h3_stdarg_cast_res is not None:
|
||||
return _tc_h3_stdarg_cast_res
|
||||
|
||||
_tc_h4_type_casts_res: llvmlite.Value | t.CPtr = self.Gen.CallGenDispatch._tc_h4_type_casts(
|
||||
_tc_h4_type_casts_res: rawptr[llvmlite.Value] = self.Gen.CallGenDispatch._tc_h4_type_casts(
|
||||
pool, builder, mod, cl, funcs_ptr, func_count, trans, func_name, cargs, can)
|
||||
if _tc_h4_type_casts_res is not None:
|
||||
return _tc_h4_type_casts_res
|
||||
|
||||
_tc_h5_sizeof_len_isinst_res: llvmlite.Value | t.CPtr = self.Gen.CallGenDispatch._tc_h5_sizeof_len_isinst(
|
||||
_tc_h5_sizeof_len_isinst_res: rawptr[llvmlite.Value] = self.Gen.CallGenDispatch._tc_h5_sizeof_len_isinst(
|
||||
pool, builder, mod, cl, funcs_ptr, func_count, trans, func_name, cargs, can)
|
||||
if _tc_h5_sizeof_len_isinst_res is not None:
|
||||
return _tc_h5_sizeof_len_isinst_res
|
||||
@@ -210,7 +210,7 @@ class CallGenMixin(CallGenBase.CallGenBase):
|
||||
h6_hit: t.CPtr = stdlib.malloc(4)
|
||||
if h6_hit is not None:
|
||||
h6_hit[0] = 0
|
||||
_tc_h6_method_dispatch_res: llvmlite.Value | t.CPtr = self.Gen.CallGenDispatch._tc_h6_method_dispatch(
|
||||
_tc_h6_method_dispatch_res: rawptr[llvmlite.Value] = self.Gen.CallGenDispatch._tc_h6_method_dispatch(
|
||||
pool, builder, mod, cl, funcs_ptr, func_count, trans, func_name, cargs, can, h6_hit)
|
||||
h6_hit_val: int = 0
|
||||
if h6_hit is not None:
|
||||
@@ -223,7 +223,7 @@ class CallGenMixin(CallGenBase.CallGenBase):
|
||||
return None
|
||||
|
||||
# 获取关键字参数
|
||||
keywords: list[rawptr[ast.AST]] | t.CPtr = cl.keywords
|
||||
keywords: rawptr[list[rawptr[ast.AST]]] = cl.keywords
|
||||
kw_count: sizet = 0
|
||||
if keywords is not None:
|
||||
kw_count = len(keywords)
|
||||
@@ -234,7 +234,7 @@ class CallGenMixin(CallGenBase.CallGenBase):
|
||||
# - 模块限定 Module.Class(): 需要 import Module
|
||||
# 用 find_struct_by_module 规避跨模块同名 find_struct 找错
|
||||
struct_ty: rawptr[llvmlite.LLVMType] = None
|
||||
gen_ctor_entry: GenTypes.StructEntry | t.CPtr = None
|
||||
gen_ctor_entry: rawptr[GenTypes.StructEntry] = None
|
||||
# 模块限定构造 Module.Class(...) 优先:按模块名解析 SHA1 精确命中类。
|
||||
# 必须在裸名可见性分支之前——跨模块同名类(VKernel gfx 与 App gfx 都
|
||||
# 定义 Scene3D)存在时,裸名 find_struct 返回先注册的错误 entry
|
||||
@@ -361,7 +361,7 @@ class CallGenMixin(CallGenBase.CallGenBase):
|
||||
gen_has_defaults: int = 0
|
||||
if gen_ctor_entry is not None:
|
||||
for gdi in range(gen_ctor_entry.FieldCount):
|
||||
gdf: GenTypes.FieldEntry | t.CPtr = self.Gen.StructGen._get_field_entry(
|
||||
gdf: rawptr[GenTypes.FieldEntry] = self.Gen.StructGen._get_field_entry(
|
||||
gen_ctor_entry, gdi)
|
||||
if gdf is not None and gdf.DefaultVal is not None:
|
||||
gen_has_defaults = 1
|
||||
@@ -373,7 +373,7 @@ class CallGenMixin(CallGenBase.CallGenBase):
|
||||
return self.Gen.CallGenCtor._translate_struct_ctor(
|
||||
pool, builder, mod, struct_ty, func_name, cargs, sizet(0), trans)
|
||||
# 无默认值:返回 zeroinitializer
|
||||
ret: llvmlite.Value | t.CPtr = llvmlite.ConstZero(pool, struct_ty)
|
||||
ret: rawptr[llvmlite.Value] = llvmlite.ConstZero(pool, struct_ty)
|
||||
return ret
|
||||
if kw_count > 0:
|
||||
# 有关键字参数:按字段名赋值
|
||||
@@ -437,7 +437,7 @@ class CallGenMixin(CallGenBase.CallGenBase):
|
||||
func_name, tp_bare.get(tpi_bare),
|
||||
keywords, kw_count, int(can))
|
||||
if kwi_bare >= 0:
|
||||
kwn_bare: ast.Keyword | t.CPtr = (ast.Keyword | t.CPtr)(
|
||||
kwn_bare: rawptr[ast.Keyword] = rawptr[ast.Keyword](
|
||||
keywords.get(sizet(kwi_bare)))
|
||||
if kwn_bare is not None and kwn_bare.value is not None:
|
||||
ta_bare = self.Gen.CallGenCtor._infer_generic_ctor_type_arg(
|
||||
@@ -552,14 +552,14 @@ class CallGenMixin(CallGenBase.CallGenBase):
|
||||
i8_ptr_ty_an: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(
|
||||
pool, llvmlite.Int8(pool))
|
||||
# M2:async 调用参数(task(5, 6) → create_task(5, 6))
|
||||
arg_head_an: llvmlite.Value | t.CPtr = None
|
||||
arg_tail_an: llvmlite.Value | t.CPtr = None
|
||||
arg_head_an: rawptr[llvmlite.Value] = None
|
||||
arg_tail_an: rawptr[llvmlite.Value] = None
|
||||
arg_cnt_an: int = 0
|
||||
if cl.args is not None:
|
||||
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(
|
||||
av_an: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, cl.args.get(j_an),
|
||||
None, 0, trans)
|
||||
if av_an is None:
|
||||
@@ -572,7 +572,7 @@ class CallGenMixin(CallGenBase.CallGenBase):
|
||||
arg_tail_an.Next = av_an
|
||||
arg_tail_an = av_an
|
||||
arg_cnt_an = arg_cnt_an + 1
|
||||
child_an: llvmlite.Value | t.CPtr = llvmlite.build_call(
|
||||
child_an: rawptr[llvmlite.Value] = llvmlite.build_call(
|
||||
builder, create_an, arg_head_an, arg_cnt_an,
|
||||
ret_ptr_ty_an, 0)
|
||||
if child_an is not None:
|
||||
@@ -935,7 +935,7 @@ class CallGenMixin(CallGenBase.CallGenBase):
|
||||
pool, func_name, node, 1 - bare_resolvable)
|
||||
|
||||
if found_func is None:
|
||||
fp_alloca: llvmlite.Value | t.CPtr = None
|
||||
fp_alloca: rawptr[llvmlite.Value] = None
|
||||
if cl.func is None or cl.func.kind() == ast.ASTKind.Name:
|
||||
# 闭包内调用捕获的闭包变量(如 _cmd_cd 调 _build_path):
|
||||
# 从 env 读闭包对象指针,不能 lookup_var 跨函数命中父函数
|
||||
@@ -949,7 +949,7 @@ class CallGenMixin(CallGenBase.CallGenBase):
|
||||
# alloca 暂存
|
||||
i8_ty_nl: rawptr[llvmlite.LLVMType] = llvmlite.Int8(pool)
|
||||
i8_ptr_ty_nl: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, i8_ty_nl)
|
||||
tmp_alloca_nl: llvmlite.Value | t.CPtr = self.Gen.VarGen._alloca_at_entry(
|
||||
tmp_alloca_nl: rawptr[llvmlite.Value] = self.Gen.VarGen._alloca_at_entry(
|
||||
builder, i8_ptr_ty_nl)
|
||||
if tmp_alloca_nl is not None:
|
||||
llvmlite.build_store(builder, fp_alloca, tmp_alloca_nl)
|
||||
@@ -967,7 +967,7 @@ class CallGenMixin(CallGenBase.CallGenBase):
|
||||
# t.CPtr 变量(如 f: t.CPtr = make_counter())存的是闭包结构
|
||||
# {fn_ptr, env_ptr},调用必须提取 env 传参;若按函数指针直接
|
||||
# call,跳转到闭包结构数据地址崩溃(ClosureCallTest 运行时崩溃)。
|
||||
ve_fp: GenTypes.VarEntry | t.CPtr = self.Gen.VarGen.lookup_var_entry(
|
||||
ve_fp: rawptr[GenTypes.VarEntry] = self.Gen.VarGen.lookup_var_entry(
|
||||
trans.SymTab, func_name)
|
||||
is_cptr_annot_fp: int = 0
|
||||
fp_annot: str = self.Gen.VarGen.var_annot_class_name(ve_fp)
|
||||
@@ -999,12 +999,12 @@ class CallGenMixin(CallGenBase.CallGenBase):
|
||||
pool, builder, mod, func_name, found_func,
|
||||
cargs, can, keywords, kw_count, trans)
|
||||
|
||||
head: llvmlite.Value | t.CPtr = None
|
||||
tail: llvmlite.Value | t.CPtr = None
|
||||
head: rawptr[llvmlite.Value] = None
|
||||
tail: rawptr[llvmlite.Value] = None
|
||||
# memcpy 专用: 收集前三个 Value 的独立引用(避免共享 alloca 对象的 Next 被污染)
|
||||
mc_dst2: llvmlite.Value | t.CPtr = None
|
||||
mc_src2: llvmlite.Value | t.CPtr = None
|
||||
mc_num2: llvmlite.Value | t.CPtr = None
|
||||
mc_dst2: rawptr[llvmlite.Value] = None
|
||||
mc_src2: rawptr[llvmlite.Value] = None
|
||||
mc_num2: rawptr[llvmlite.Value] = None
|
||||
for ai in range(can):
|
||||
arg: rawptr[ast.AST] = cargs.get(ai)
|
||||
if arg is not None:
|
||||
@@ -1012,7 +1012,7 @@ class CallGenMixin(CallGenBase.CallGenBase):
|
||||
# 形参时需物化 1 字符字符串(translate_constant 依据 target_ty
|
||||
# 判定),否则 coerce inttoptr 把字符值当指针(如 '"'=0x22)→
|
||||
# strlen 访问低地址 ASan 崩溃(二代编 StringTest PyI 生成根因)。
|
||||
fp: llvmlite.Param | t.CPtr = None
|
||||
fp: rawptr[llvmlite.Param] = None
|
||||
fpty: rawptr[llvmlite.LLVMType] = None
|
||||
if found_func is not None:
|
||||
fp = llvmlite.function_get_param_head(found_func)
|
||||
@@ -1022,7 +1022,7 @@ class CallGenMixin(CallGenBase.CallGenBase):
|
||||
fpi += 1
|
||||
if fp is not None:
|
||||
fpty = llvmlite.param_get_ty(fp)
|
||||
arg_val: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
|
||||
arg_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, arg, None, 0, trans, fpty)
|
||||
if arg_val is not None:
|
||||
# 参数类型提升:当 found_func 为 None(stub 未注入)时,
|
||||
@@ -1036,7 +1036,7 @@ class CallGenMixin(CallGenBase.CallGenBase):
|
||||
if arr_pointee_fc is not None:
|
||||
match arr_pointee_fc:
|
||||
case llvmlite.LLVMType.Array(arr_et_fc, _):
|
||||
decayed_fc: llvmlite.Value | t.CPtr = llvmlite.build_gep_array(
|
||||
decayed_fc: rawptr[llvmlite.Value] = llvmlite.build_gep_array(
|
||||
builder, arr_pointee_fc, arr_et_fc, arg_val,
|
||||
llvmlite.const_int32(pool, 0))
|
||||
if decayed_fc is not None:
|
||||
@@ -1138,7 +1138,7 @@ class CallGenMixin(CallGenBase.CallGenBase):
|
||||
# 快照才是跨文件永久存活。同模块命中时 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)
|
||||
gd_entry: rawptr[GenTypes.FuncDefaultsEntry] = 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
|
||||
df_default_count = gd_entry.DefaultCount
|
||||
@@ -1150,7 +1150,7 @@ class CallGenMixin(CallGenBase.CallGenBase):
|
||||
# 交由下方 `elif found_func is not None` 分支按真实形参数零值兜底。
|
||||
if found_func is not None and df_default_count > 0:
|
||||
dfx_cnt: int = 0
|
||||
dfx_p: llvmlite.Param | t.CPtr = llvmlite.function_get_param_head(found_func)
|
||||
dfx_p: rawptr[llvmlite.Param] = llvmlite.function_get_param_head(found_func)
|
||||
while dfx_p is not None:
|
||||
dfx_nm: str = llvmlite.param_get_name(dfx_p)
|
||||
if dfx_nm is None or (string.strcmp(dfx_nm, "%__eh_msg_out__") != 0
|
||||
@@ -1168,12 +1168,12 @@ class CallGenMixin(CallGenBase.CallGenBase):
|
||||
df_param_idx: int = df_offset + df_di
|
||||
if df_param_idx >= can:
|
||||
# 优先用 stdlib 常量快照重建(gd_entry.Defaults 的 pool 内 AST 可能已被 reset 回收)
|
||||
df_arg_val: llvmlite.Value | t.CPtr = None
|
||||
df_arg_val: rawptr[llvmlite.Value] = None
|
||||
if gd_entry is not None:
|
||||
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[rawptr[ast.AST]] | t.CPtr = (list[rawptr[ast.AST]] | t.CPtr)(uint64(df_defaults))
|
||||
df_defaults_list: rawptr[list[rawptr[ast.AST]]] = rawptr[list[rawptr[ast.AST]]](uint64(df_defaults))
|
||||
df_default_node: rawptr[ast.AST] = df_defaults_list.get(df_di)
|
||||
if df_default_node is not None:
|
||||
df_arg_val = self.Gen.ExprGen.translate_value(
|
||||
@@ -1188,7 +1188,7 @@ class CallGenMixin(CallGenBase.CallGenBase):
|
||||
elif found_func is not None:
|
||||
# 默认参数缺失/表信息不全时的零值兜底:函数表有参数数但无默认值记录、或调用方先于定义文件编译导致查不到默认值时,用 found_func 实际参数数(stub declare,与 define 一致)兜底并缺参填零值(对齐 TPC _fill_default_args 语义)。注意排除 EH 输出参数(%__eh_msg_out__/%__eh_code_out__),否则会与 _emit_eh_guarded_call 追加的真实 EH 实参重复导致 ABI 错位
|
||||
fc_cnt: int = 0
|
||||
fc_p: llvmlite.Param | t.CPtr = llvmlite.function_get_param_head(found_func)
|
||||
fc_p: rawptr[llvmlite.Param] = llvmlite.function_get_param_head(found_func)
|
||||
while fc_p is not None:
|
||||
fp_nm_z: str = llvmlite.param_get_name(fc_p)
|
||||
if fp_nm_z is None or (string.strcmp(fp_nm_z, "%__eh_msg_out__") != 0
|
||||
@@ -1198,14 +1198,14 @@ class CallGenMixin(CallGenBase.CallGenBase):
|
||||
if fc_cnt == 0:
|
||||
fc_cnt = df_param_count if df_param_count > 0 else 0
|
||||
if can < fc_cnt:
|
||||
fp_z: llvmlite.Param | t.CPtr = llvmlite.function_get_param_head(found_func)
|
||||
fp_z: rawptr[llvmlite.Param] = llvmlite.function_get_param_head(found_func)
|
||||
fpi_z: int = 0
|
||||
while fp_z is not None and fpi_z < can:
|
||||
fp_z = llvmlite.param_get_next(fp_z)
|
||||
fpi_z += 1
|
||||
while fp_z is not None and fpi_z < fc_cnt:
|
||||
zero_ty_z: rawptr[llvmlite.LLVMType] = llvmlite.param_get_ty(fp_z)
|
||||
zero_val_z: llvmlite.Value | t.CPtr = llvmlite.ConstZero(pool, zero_ty_z)
|
||||
zero_val_z: rawptr[llvmlite.Value] = llvmlite.ConstZero(pool, zero_ty_z)
|
||||
if zero_val_z is not None:
|
||||
zero_val_z.Next = None
|
||||
if head is None:
|
||||
|
||||
@@ -50,13 +50,13 @@ class CallGenProp(CallGenBase.CallGenBase):
|
||||
# call_head/call_count: 已构建好的参数链表(如 getter 只有 obj 一个参数)
|
||||
# ============================================================
|
||||
def _translate_property_call(self, pool: rawptr[memhub.MemBuddy],
|
||||
builder: llvmlite.IRBuilder | t.CPtr,
|
||||
builder: rawptr[llvmlite.IRBuilder],
|
||||
mod: rawptr[llvmlite.LLVMModule],
|
||||
class_name: str,
|
||||
method_name: str,
|
||||
call_head: llvmlite.Value | t.CPtr,
|
||||
call_head: rawptr[llvmlite.Value],
|
||||
call_count: int,
|
||||
trans: rawptr[HT.Translator]) -> llvmlite.Value | t.CPtr:
|
||||
trans: rawptr[HT.Translator]) -> rawptr[llvmlite.Value]:
|
||||
"""翻译属性/静态方法调用,返回 call 结果 Value"""
|
||||
if pool is None or builder is None or class_name is None or method_name is None:
|
||||
return None
|
||||
@@ -126,13 +126,13 @@ class CallGenProp(CallGenBase.CallGenBase):
|
||||
if tgt_func_pc is None:
|
||||
tgt_func_pc = self.find_func_in_module(mod, call_name)
|
||||
if tgt_func_pc is not None:
|
||||
prev_pc: llvmlite.Value | t.CPtr = None
|
||||
cur_arg_pc: llvmlite.Value | t.CPtr = call_head
|
||||
cur_param_pc: llvmlite.Param | t.CPtr = llvmlite.function_get_param_head(tgt_func_pc)
|
||||
prev_pc: rawptr[llvmlite.Value] = None
|
||||
cur_arg_pc: rawptr[llvmlite.Value] = call_head
|
||||
cur_param_pc: rawptr[llvmlite.Param] = llvmlite.function_get_param_head(tgt_func_pc)
|
||||
while cur_arg_pc is not None and cur_param_pc is not None:
|
||||
param_ty_pc: rawptr[llvmlite.LLVMType] = llvmlite.param_get_ty(cur_param_pc)
|
||||
if param_ty_pc is not None and cur_arg_pc.Ty is not None:
|
||||
coerced_pc: llvmlite.Value | t.CPtr = self.Gen.ExprGenBase.coerce_to_type(
|
||||
coerced_pc: rawptr[llvmlite.Value] = self.Gen.ExprGenBase.coerce_to_type(
|
||||
builder, cur_arg_pc, param_ty_pc)
|
||||
if coerced_pc is not None and coerced_pc != cur_arg_pc:
|
||||
# 保持链表完整性:新 Value 继承原节点的 Next,前驱指向新节点
|
||||
@@ -167,7 +167,7 @@ class CallGenProp(CallGenBase.CallGenBase):
|
||||
if obj_node.kind() == ast.ASTKind.Name:
|
||||
obj_nm: rawptr[ast.Name] = rawptr[ast.Name](obj_node)
|
||||
if obj_nm.id is not None:
|
||||
var_entry: GenTypes.VarEntry | t.CPtr = self.Gen.VarGen.lookup_var_entry(
|
||||
var_entry: rawptr[GenTypes.VarEntry] = self.Gen.VarGen.lookup_var_entry(
|
||||
trans.SymTab, obj_nm.id)
|
||||
annot_val: str = self.Gen.VarGen.var_annot_class_name(var_entry)
|
||||
if annot_val is not None:
|
||||
@@ -202,12 +202,12 @@ class CallGenProp(CallGenBase.CallGenBase):
|
||||
|
||||
# ============================================================
|
||||
def _try_property_getter_attr(self, pool: rawptr[memhub.MemBuddy],
|
||||
builder: llvmlite.IRBuilder | t.CPtr,
|
||||
builder: rawptr[llvmlite.IRBuilder],
|
||||
mod: rawptr[llvmlite.LLVMModule],
|
||||
at_node: rawptr[ast.Attribute],
|
||||
obj_ptr: llvmlite.Value | t.CPtr,
|
||||
obj_ptr: rawptr[llvmlite.Value],
|
||||
trans: rawptr[HT.Translator],
|
||||
fallback_class_name: str = None) -> llvmlite.Value | t.CPtr:
|
||||
fallback_class_name: str = None) -> rawptr[llvmlite.Value]:
|
||||
"""尝试 property getter 属性访问,返回调用结果 Value;非 getter 返回 None
|
||||
|
||||
fallback_class_name: 对象表达式非 Name 时从 LLVM 类型解析出的类名兜底。
|
||||
@@ -235,10 +235,10 @@ class CallGenProp(CallGenBase.CallGenBase):
|
||||
|
||||
# ============================================================
|
||||
def _try_property_setter(self, pool: rawptr[memhub.MemBuddy],
|
||||
builder: llvmlite.IRBuilder | t.CPtr,
|
||||
builder: rawptr[llvmlite.IRBuilder],
|
||||
mod: rawptr[llvmlite.LLVMModule],
|
||||
target_attr: rawptr[ast.Attribute],
|
||||
rhs_val: llvmlite.Value | t.CPtr,
|
||||
rhs_val: rawptr[llvmlite.Value],
|
||||
trans: rawptr[HT.Translator]) -> int:
|
||||
"""尝试 property setter 赋值,返回 1=已处理(生成调用)"""
|
||||
if pool is None or builder is None or mod is None or trans is None:
|
||||
@@ -252,7 +252,7 @@ class CallGenProp(CallGenBase.CallGenBase):
|
||||
if meta & GenTypes.META_PROP_SETTER == 0:
|
||||
return 0
|
||||
# 翻译对象值(self 参数)
|
||||
obj_val: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
|
||||
obj_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, target_attr.value, None, 0, trans)
|
||||
if obj_val is None:
|
||||
return 0
|
||||
@@ -277,7 +277,7 @@ class CallGenProp(CallGenBase.CallGenBase):
|
||||
|
||||
# ============================================================
|
||||
def _try_property_deleter(self, pool: rawptr[memhub.MemBuddy],
|
||||
builder: llvmlite.IRBuilder | t.CPtr,
|
||||
builder: rawptr[llvmlite.IRBuilder],
|
||||
mod: rawptr[llvmlite.LLVMModule],
|
||||
target_attr: rawptr[ast.Attribute],
|
||||
trans: rawptr[HT.Translator]) -> int:
|
||||
@@ -293,7 +293,7 @@ class CallGenProp(CallGenBase.CallGenBase):
|
||||
if meta & GenTypes.META_PROP_DELETER == 0:
|
||||
return 0
|
||||
# 翻译对象值(self 参数)
|
||||
obj_val: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
|
||||
obj_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, target_attr.value, None, 0, trans)
|
||||
if obj_val is None:
|
||||
return 0
|
||||
@@ -315,12 +315,12 @@ class CallGenProp(CallGenBase.CallGenBase):
|
||||
|
||||
# ============================================================
|
||||
def _translate_static_class_call(self, pool: rawptr[memhub.MemBuddy],
|
||||
builder: llvmlite.IRBuilder | t.CPtr,
|
||||
builder: rawptr[llvmlite.IRBuilder],
|
||||
mod: rawptr[llvmlite.LLVMModule],
|
||||
class_name: str,
|
||||
method_name: str,
|
||||
cl: rawptr[ast.Call],
|
||||
trans: rawptr[HT.Translator]) -> llvmlite.Value | t.CPtr:
|
||||
trans: rawptr[HT.Translator]) -> rawptr[llvmlite.Value]:
|
||||
"""翻译类名静态/类方法调用,返回 call 结果 Value;非静态/类方法返回 None"""
|
||||
if pool is None or builder is None or mod is None or trans is None:
|
||||
return None
|
||||
@@ -337,7 +337,7 @@ class CallGenProp(CallGenBase.CallGenBase):
|
||||
return None
|
||||
|
||||
# 构建参数链表
|
||||
head: llvmlite.Value | t.CPtr = None
|
||||
head: rawptr[llvmlite.Value] = None
|
||||
total_count: int = 0
|
||||
|
||||
# @classmethod: 插入栈上分配的类实例指针作为 cls 参数
|
||||
@@ -345,7 +345,7 @@ class CallGenProp(CallGenBase.CallGenBase):
|
||||
struct_ty_cc: rawptr[llvmlite.LLVMType] = self.Gen.StructGen.get_struct_type(class_name)
|
||||
if struct_ty_cc is None:
|
||||
return None
|
||||
cls_ptr: llvmlite.Value | t.CPtr = self.Gen.VarGen._alloca_at_entry(builder, struct_ty_cc)
|
||||
cls_ptr: rawptr[llvmlite.Value] = self.Gen.VarGen._alloca_at_entry(builder, struct_ty_cc)
|
||||
if cls_ptr is None:
|
||||
return None
|
||||
llvmlite.value_set_next(cls_ptr, None)
|
||||
@@ -353,16 +353,16 @@ class CallGenProp(CallGenBase.CallGenBase):
|
||||
total_count = 1
|
||||
|
||||
# 翻译调用参数
|
||||
cargs: list[rawptr[ast.AST]] | t.CPtr = cl.args
|
||||
cargs: rawptr[list[rawptr[ast.AST]]] = cl.args
|
||||
can: sizet = 0
|
||||
if cargs is not None:
|
||||
can = len(cargs)
|
||||
tail: llvmlite.Value | t.CPtr = head
|
||||
tail: rawptr[llvmlite.Value] = head
|
||||
for ai in range(can):
|
||||
arg_node: rawptr[ast.AST] = cargs.get(ai)
|
||||
if arg_node is None:
|
||||
continue
|
||||
arg_val: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
|
||||
arg_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, arg_node, None, 0, trans)
|
||||
if arg_val is None:
|
||||
continue
|
||||
@@ -472,7 +472,7 @@ class CallGenProp(CallGenBase.CallGenBase):
|
||||
|
||||
# _is_list_builtin_receiver:基于接收者实际类型判定 list 内建方法,判据与 _resolve_generic_receiver_name 同源——优先采用接收者实际 LLVM 结构体类型名(去 sha1 判基名),不可得时回退注解名/注册名判定。返回 1=list 内置方法 / 0=非
|
||||
def _is_list_builtin_receiver(self, pool: rawptr[memhub.MemBuddy],
|
||||
recv_val: llvmlite.Value | t.CPtr,
|
||||
recv_val: rawptr[llvmlite.Value],
|
||||
fallback_name: str,
|
||||
method_name: str,
|
||||
cl: rawptr[ast.Call]) -> int:
|
||||
|
||||
@@ -28,12 +28,12 @@ class CallGenVa(CallGenBase.CallGenBase):
|
||||
# ============================================================
|
||||
|
||||
def _va_arg_get_alloca_ptr(self, pool: rawptr[memhub.MemBuddy],
|
||||
builder: llvmlite.IRBuilder | t.CPtr,
|
||||
builder: rawptr[llvmlite.IRBuilder],
|
||||
mod: rawptr[llvmlite.LLVMModule],
|
||||
arg_node: rawptr[ast.AST],
|
||||
funcs_ptr: t.CPtr,
|
||||
func_count: int,
|
||||
trans: rawptr[HT.Translator]) -> llvmlite.Value | t.CPtr:
|
||||
trans: rawptr[HT.Translator]) -> rawptr[llvmlite.Value]:
|
||||
"""获取 va_list 变量的 alloca 指针(不 load)
|
||||
|
||||
va_arg/va_start/va_end 需要的是 va_list 对象的地址(alloca 指针),
|
||||
@@ -46,7 +46,7 @@ class CallGenVa(CallGenBase.CallGenBase):
|
||||
if arg_node.kind() == ast.ASTKind.Name:
|
||||
nm: rawptr[ast.Name] = rawptr[ast.Name](arg_node)
|
||||
if nm.id is not None:
|
||||
alloca: llvmlite.Value | t.CPtr = self.Gen.VarGen.lookup_var(trans.SymTab, nm.id)
|
||||
alloca: rawptr[llvmlite.Value] = self.Gen.VarGen.lookup_var(trans.SymTab, nm.id)
|
||||
if alloca is not None:
|
||||
return alloca
|
||||
# 回退:translate_value(可能返回 load 后的值,仅适用于已是指针的情况)
|
||||
@@ -75,14 +75,14 @@ class CallGenVa(CallGenBase.CallGenBase):
|
||||
self.Gen.TypeGenErr.fatal_error(type_node, "va_arg 类型解析失败", "TypeError")
|
||||
return llvmlite.Int32(pool)
|
||||
def _translate_va_arg_sugar(self, pool: rawptr[memhub.MemBuddy],
|
||||
builder: llvmlite.IRBuilder | t.CPtr,
|
||||
builder: rawptr[llvmlite.IRBuilder],
|
||||
mod: rawptr[llvmlite.LLVMModule],
|
||||
cl: rawptr[ast.Call],
|
||||
cargs: list[rawptr[ast.AST]] | t.CPtr,
|
||||
cargs: rawptr[list[rawptr[ast.AST]]],
|
||||
can: sizet,
|
||||
funcs_ptr: t.CPtr,
|
||||
func_count: int,
|
||||
trans: rawptr[HT.Translator]) -> llvmlite.Value | t.CPtr:
|
||||
trans: rawptr[HT.Translator]) -> rawptr[llvmlite.Value]:
|
||||
"""va_arg(ap, type) / va_arg(ap) → %N = va_arg <ap_ty> <ap>, <type>
|
||||
|
||||
生成 LLVM va_arg 指令,从 va_list 读取下一个变长参数。
|
||||
@@ -94,11 +94,11 @@ class CallGenVa(CallGenBase.CallGenBase):
|
||||
# 当前函数 *args:translate_value 经 vararg 名映射直接返回 va_list 缓冲区地址;
|
||||
# 转发场景(sprintf → vsnprintf 的 ap 参数):translate_value load 参数得到地址值。
|
||||
ap_node: rawptr[ast.AST] = cargs.get(0)
|
||||
ap_val: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
|
||||
ap_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, ap_node, None, 0, trans)
|
||||
if ap_val is None:
|
||||
return llvmlite.const_int32(pool, 0)
|
||||
ap_ptr: llvmlite.Value | t.CPtr = ap_val
|
||||
ap_ptr: rawptr[llvmlite.Value] = ap_val
|
||||
|
||||
# 第二个参数:目标类型(可选,默认 i32)
|
||||
arg_ty: rawptr[llvmlite.LLVMType] = llvmlite.Int32(pool)
|
||||
@@ -114,7 +114,7 @@ class CallGenVa(CallGenBase.CallGenBase):
|
||||
abits_va: int = self.Gen.ExprGenBase.get_llvm_type_bits(arg_ty)
|
||||
if abits_va != 0 and abits_va < 64:
|
||||
read_ty = llvmlite.Int64(pool)
|
||||
va_raw: llvmlite.Value | t.CPtr = llvmlite.build_va_arg(builder, ap_ptr, read_ty)
|
||||
va_raw: rawptr[llvmlite.Value] = llvmlite.build_va_arg(builder, ap_ptr, read_ty)
|
||||
if va_raw is None:
|
||||
return llvmlite.const_int32(pool, 0)
|
||||
# 8 字节槽 → 目标宽度(低 bits 位);调用方 int64(...) 会再 sext/zext
|
||||
@@ -123,14 +123,14 @@ class CallGenVa(CallGenBase.CallGenBase):
|
||||
# 生成 va_arg 指令
|
||||
return llvmlite.build_va_arg(builder, ap_ptr, read_ty)
|
||||
def _translate_arg_sugar(self, pool: rawptr[memhub.MemBuddy],
|
||||
builder: llvmlite.IRBuilder | t.CPtr,
|
||||
builder: rawptr[llvmlite.IRBuilder],
|
||||
mod: rawptr[llvmlite.LLVMModule],
|
||||
cl: rawptr[ast.Call],
|
||||
cargs: list[rawptr[ast.AST]] | t.CPtr,
|
||||
cargs: rawptr[list[rawptr[ast.AST]]],
|
||||
can: sizet,
|
||||
funcs_ptr: t.CPtr,
|
||||
func_count: int,
|
||||
trans: rawptr[HT.Translator]) -> llvmlite.Value | t.CPtr:
|
||||
trans: rawptr[HT.Translator]) -> rawptr[llvmlite.Value]:
|
||||
"""arg(type) → %N = va_arg <va_list_ty> <trans._va_list_ptr>, <type>
|
||||
|
||||
使用当前函数的隐式 va_list(trans._va_list_ptr),
|
||||
@@ -151,7 +151,7 @@ class CallGenVa(CallGenBase.CallGenBase):
|
||||
abits_arg: int = self.Gen.ExprGenBase.get_llvm_type_bits(arg_ty)
|
||||
if abits_arg != 0 and abits_arg < 64:
|
||||
read_ty = llvmlite.Int64(pool)
|
||||
arg_raw: llvmlite.Value | t.CPtr = llvmlite.build_va_arg(builder, trans._va_list_ptr, read_ty)
|
||||
arg_raw: rawptr[llvmlite.Value] = llvmlite.build_va_arg(builder, trans._va_list_ptr, read_ty)
|
||||
if arg_raw is None:
|
||||
return llvmlite.const_int32(pool, 0)
|
||||
return llvmlite.build_trunc(builder, arg_raw, arg_ty)
|
||||
@@ -159,13 +159,13 @@ class CallGenVa(CallGenBase.CallGenBase):
|
||||
# 生成 va_arg 指令(使用 trans._va_list_ptr 作为 va_list 地址)
|
||||
return llvmlite.build_va_arg(builder, trans._va_list_ptr, read_ty)
|
||||
def _translate_va_start_sugar(self, pool: rawptr[memhub.MemBuddy],
|
||||
builder: llvmlite.IRBuilder | t.CPtr,
|
||||
builder: rawptr[llvmlite.IRBuilder],
|
||||
mod: rawptr[llvmlite.LLVMModule],
|
||||
cargs: list[rawptr[ast.AST]] | t.CPtr,
|
||||
cargs: rawptr[list[rawptr[ast.AST]]],
|
||||
can: sizet,
|
||||
funcs_ptr: t.CPtr,
|
||||
func_count: int,
|
||||
trans: rawptr[HT.Translator]) -> llvmlite.Value | t.CPtr:
|
||||
trans: rawptr[HT.Translator]) -> rawptr[llvmlite.Value]:
|
||||
"""va_start(ap, last_arg) → call void @llvm.va_start(i8* %ap)
|
||||
|
||||
初始化 va_list。第二个参数 last_arg 在 LLVM intrinsic 中不使用(C 宏兼容)。
|
||||
@@ -175,7 +175,7 @@ class CallGenVa(CallGenBase.CallGenBase):
|
||||
|
||||
# 第一个参数:va_list 指针(获取 alloca,不 load)
|
||||
ap_node: rawptr[ast.AST] = cargs.get(0)
|
||||
ap_ptr: llvmlite.Value | t.CPtr = self._va_arg_get_alloca_ptr(
|
||||
ap_ptr: rawptr[llvmlite.Value] = self._va_arg_get_alloca_ptr(
|
||||
pool, builder, mod, ap_node, funcs_ptr, func_count, trans)
|
||||
if ap_ptr is None:
|
||||
return llvmlite.const_int32(pool, 0)
|
||||
@@ -183,7 +183,7 @@ class CallGenVa(CallGenBase.CallGenBase):
|
||||
# bitcast 到 i8*(@llvm.va_start 接受 i8*)
|
||||
i8_ty_vs: rawptr[llvmlite.LLVMType] = llvmlite.Int8(pool)
|
||||
i8_ptr_ty_vs: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, i8_ty_vs)
|
||||
ap_i8: llvmlite.Value | t.CPtr = llvmlite.build_bitcast(builder, ap_ptr, i8_ptr_ty_vs)
|
||||
ap_i8: rawptr[llvmlite.Value] = llvmlite.build_bitcast(builder, ap_ptr, i8_ptr_ty_vs)
|
||||
if ap_i8 is None:
|
||||
return llvmlite.const_int32(pool, 0)
|
||||
|
||||
@@ -191,13 +191,13 @@ class CallGenVa(CallGenBase.CallGenBase):
|
||||
llvmlite.build_call(builder, "llvm.va_start", ap_i8, 1, void_ty_vs, 0)
|
||||
return llvmlite.const_int32(pool, 0)
|
||||
def _translate_va_end_sugar(self, pool: rawptr[memhub.MemBuddy],
|
||||
builder: llvmlite.IRBuilder | t.CPtr,
|
||||
builder: rawptr[llvmlite.IRBuilder],
|
||||
mod: rawptr[llvmlite.LLVMModule],
|
||||
cargs: list[rawptr[ast.AST]] | t.CPtr,
|
||||
cargs: rawptr[list[rawptr[ast.AST]]],
|
||||
can: sizet,
|
||||
funcs_ptr: t.CPtr,
|
||||
func_count: int,
|
||||
trans: rawptr[HT.Translator]) -> llvmlite.Value | t.CPtr:
|
||||
trans: rawptr[HT.Translator]) -> rawptr[llvmlite.Value]:
|
||||
"""va_end(ap) → call void @llvm.va_end(i8* %ap)
|
||||
|
||||
清理 va_list。在大多数平台上是 no-op,但调用它是良好的 C ABI 习惯。
|
||||
@@ -207,7 +207,7 @@ class CallGenVa(CallGenBase.CallGenBase):
|
||||
|
||||
# 第一个参数:va_list 指针(获取 alloca,不 load)
|
||||
ap_node: rawptr[ast.AST] = cargs.get(0)
|
||||
ap_ptr: llvmlite.Value | t.CPtr = self._va_arg_get_alloca_ptr(
|
||||
ap_ptr: rawptr[llvmlite.Value] = self._va_arg_get_alloca_ptr(
|
||||
pool, builder, mod, ap_node, funcs_ptr, func_count, trans)
|
||||
if ap_ptr is None:
|
||||
return llvmlite.const_int32(pool, 0)
|
||||
@@ -215,7 +215,7 @@ class CallGenVa(CallGenBase.CallGenBase):
|
||||
# bitcast 到 i8*(@llvm.va_end 接受 i8*)
|
||||
i8_ty_ve: rawptr[llvmlite.LLVMType] = llvmlite.Int8(pool)
|
||||
i8_ptr_ty_ve: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, i8_ty_ve)
|
||||
ap_i8: llvmlite.Value | t.CPtr = llvmlite.build_bitcast(builder, ap_ptr, i8_ptr_ty_ve)
|
||||
ap_i8: rawptr[llvmlite.Value] = llvmlite.build_bitcast(builder, ap_ptr, i8_ptr_ty_ve)
|
||||
if ap_i8 is None:
|
||||
return llvmlite.const_int32(pool, 0)
|
||||
|
||||
@@ -227,7 +227,7 @@ class CallGenVa(CallGenBase.CallGenBase):
|
||||
if func is None:
|
||||
return 0
|
||||
count: int = 0
|
||||
param: llvmlite.Param | t.CPtr = llvmlite.function_get_param_head(func)
|
||||
param: rawptr[llvmlite.Param] = llvmlite.function_get_param_head(func)
|
||||
while param is not None:
|
||||
count += 1
|
||||
param = llvmlite.param_get_next(param)
|
||||
@@ -277,12 +277,12 @@ class CallGenVa(CallGenBase.CallGenBase):
|
||||
return None
|
||||
return None
|
||||
def _check_and_promote_variadic_call(self, pool: rawptr[memhub.MemBuddy],
|
||||
builder: llvmlite.IRBuilder | t.CPtr,
|
||||
builder: rawptr[llvmlite.IRBuilder],
|
||||
mod: rawptr[llvmlite.LLVMModule],
|
||||
call_name: str,
|
||||
head: llvmlite.Value | t.CPtr,
|
||||
head: rawptr[llvmlite.Value],
|
||||
can: sizet,
|
||||
arg_nodes: list[rawptr[ast.AST]] | t.CPtr = None,
|
||||
arg_nodes: rawptr[list[rawptr[ast.AST]]] = None,
|
||||
self_offset: int = 0,
|
||||
trans: rawptr[HT.Translator] = None) -> int:
|
||||
"""检查被调用函数是否为变长函数,若是则对变长参数进行 C ABI 提升
|
||||
@@ -312,8 +312,8 @@ class CallGenVa(CallGenBase.CallGenBase):
|
||||
return 1
|
||||
|
||||
# 遍历到第 fixed_count 个节点(固定参数的最后一个)
|
||||
cur: llvmlite.Value | t.CPtr = head
|
||||
prev: llvmlite.Value | t.CPtr = None
|
||||
cur: rawptr[llvmlite.Value] = head
|
||||
prev: rawptr[llvmlite.Value] = None
|
||||
idx: int = 0
|
||||
while cur is not None and idx < fixed_count:
|
||||
prev = cur
|
||||
@@ -326,8 +326,8 @@ class CallGenVa(CallGenBase.CallGenBase):
|
||||
double_ty_promote: rawptr[llvmlite.LLVMType] = llvmlite.Double(pool)
|
||||
v_idx: int = fixed_count
|
||||
while cur is not None:
|
||||
next_node: llvmlite.Value | t.CPtr = cur.Next
|
||||
promoted: llvmlite.Value | t.CPtr = cur
|
||||
next_node: rawptr[llvmlite.Value] = cur.Next
|
||||
promoted: rawptr[llvmlite.Value] = cur
|
||||
# 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:
|
||||
@@ -374,7 +374,7 @@ class CallGenVa(CallGenBase.CallGenBase):
|
||||
i64_ty_promote: rawptr[llvmlite.LLVMType] = llvmlite.Int64(pool)
|
||||
pb_va: int = self.Gen.ExprGenBase.get_llvm_type_bits(promoted.Ty)
|
||||
if pb_va != 0 and pb_va < 64:
|
||||
promoted_va2: llvmlite.Value | t.CPtr = None
|
||||
promoted_va2: rawptr[llvmlite.Value] = None
|
||||
is_u_va2: int = 0
|
||||
if arg_nodes is not None and trans is not None:
|
||||
ast_idx_va2: int = v_idx - self_offset
|
||||
|
||||
@@ -26,12 +26,12 @@ class CallGenVt(CallGenBase.CallGenBase):
|
||||
|
||||
# ============================================================
|
||||
def _write_vtable_slot(self, pool: rawptr[memhub.MemBuddy],
|
||||
builder: llvmlite.IRBuilder | t.CPtr,
|
||||
builder: rawptr[llvmlite.IRBuilder],
|
||||
mod: rawptr[llvmlite.LLVMModule],
|
||||
obj_ptr: llvmlite.Value | t.CPtr,
|
||||
obj_ptr: rawptr[llvmlite.Value],
|
||||
class_name: str,
|
||||
method_index: int,
|
||||
func_val: llvmlite.Value | t.CPtr,
|
||||
func_val: rawptr[llvmlite.Value],
|
||||
trans: rawptr[HT.Translator]) -> int:
|
||||
"""生成 vtable 槽位写入(写时复制),成功返回 1"""
|
||||
if pool is None or builder is None or mod is None or trans is None:
|
||||
@@ -68,20 +68,20 @@ class CallGenVt(CallGenBase.CallGenBase):
|
||||
if vtable_ty is None:
|
||||
return 0
|
||||
# 对象 vtable 槽位(对象头 → i8**,vtable 指针总是第一个字段)
|
||||
vtable_slot: llvmlite.Value | t.CPtr = llvmlite.build_bitcast(
|
||||
vtable_slot: rawptr[llvmlite.Value] = llvmlite.build_bitcast(
|
||||
builder, obj_ptr, i8_ptr_ptr_ty)
|
||||
if vtable_slot is None:
|
||||
return 0
|
||||
vtable_ptr: llvmlite.Value | t.CPtr = llvmlite.build_load(
|
||||
vtable_ptr: rawptr[llvmlite.Value] = llvmlite.build_load(
|
||||
builder, i8_ptr_ty, vtable_slot)
|
||||
if vtable_ptr is None:
|
||||
return 0
|
||||
# 类默认 vtable 地址(比较用)
|
||||
class_vt: llvmlite.Value | t.CPtr = self.Gen.CallGenLeafKit._make_vtable_ref_i8(
|
||||
class_vt: rawptr[llvmlite.Value] = self.Gen.CallGenLeafKit._make_vtable_ref_i8(
|
||||
pool, builder, mod, class_name, trans)
|
||||
if class_vt is None:
|
||||
return 0
|
||||
cmp_vt: llvmlite.Value | t.CPtr = llvmlite.build_icmp(
|
||||
cmp_vt: rawptr[llvmlite.Value] = llvmlite.build_icmp(
|
||||
builder, llvmlite.ICMP_EQ, vtable_ptr, class_vt)
|
||||
if cmp_vt is None:
|
||||
return 0
|
||||
@@ -93,10 +93,10 @@ class CallGenVt(CallGenBase.CallGenBase):
|
||||
if vt_bb_buf3 is None:
|
||||
return 0
|
||||
viperlib.snprintf(vt_bb_buf3, 64, "vt.copy.%d", vtc3)
|
||||
vt_copy_bb: llvmlite.BasicBlock | t.CPtr = llvmlite.create_block(
|
||||
vt_copy_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(
|
||||
pool, trans._cur_func, vt_bb_buf3)
|
||||
viperlib.snprintf(vt_bb_buf3, 64, "vt.skip.%d", vtc3)
|
||||
vt_skip_bb: llvmlite.BasicBlock | t.CPtr = llvmlite.create_block(
|
||||
vt_skip_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(
|
||||
pool, trans._cur_func, vt_bb_buf3)
|
||||
if vt_copy_bb is None or vt_skip_bb is None:
|
||||
return 0
|
||||
@@ -108,7 +108,7 @@ class CallGenVt(CallGenBase.CallGenBase):
|
||||
vcopy_buf: str = pool.alloc(256)
|
||||
if vcopy_buf is not None:
|
||||
viperlib.snprintf(vcopy_buf, 256, "%s.vtable.copy.%d", class_name, vtc)
|
||||
vcopy_gv: llvmlite.GlobalVariable | t.CPtr = llvmlite.new_global_variable(
|
||||
vcopy_gv: rawptr[llvmlite.GlobalVariable] = llvmlite.new_global_variable(
|
||||
pool, vcopy_buf, vtable_ty)
|
||||
if vcopy_gv is not None:
|
||||
llvmlite.module_add_global(mod, vcopy_gv)
|
||||
@@ -123,10 +123,10 @@ class CallGenVt(CallGenBase.CallGenBase):
|
||||
vcopy_ref_nm = vcopy_buf
|
||||
else:
|
||||
viperlib.snprintf(vcopy_ref_nm, 272, "@%s", vcopy_buf)
|
||||
vcopy_ref: llvmlite.Value | t.CPtr = llvmlite.SSAValue(
|
||||
vcopy_ref: rawptr[llvmlite.Value] = llvmlite.SSAValue(
|
||||
pool, llvmlite.Ptr(pool, vtable_ty), vcopy_ref_nm)
|
||||
if vcopy_ref is not None:
|
||||
vcopy_i8: llvmlite.Value | t.CPtr = llvmlite.build_bitcast(
|
||||
vcopy_i8: rawptr[llvmlite.Value] = llvmlite.build_bitcast(
|
||||
builder, vcopy_ref, i8_ptr_ty)
|
||||
if vcopy_i8 is not None:
|
||||
# ConstInt 的 name 必须是数字文本(如 "56"),不能是
|
||||
@@ -135,7 +135,7 @@ class CallGenVt(CallGenBase.CallGenBase):
|
||||
vtsz_buf: str = pool.alloc(32)
|
||||
if vtsz_buf is not None:
|
||||
viperlib.snprintf(vtsz_buf, 32, "%lld", method_count * 8)
|
||||
vt_size: llvmlite.Value | t.CPtr = llvmlite.ConstInt(
|
||||
vt_size: rawptr[llvmlite.Value] = llvmlite.ConstInt(
|
||||
pool, llvmlite.Int64(pool), method_count * 8, vtsz_buf)
|
||||
if vt_size is not None:
|
||||
self.Gen.CallGenLib._emit_llvm_memcpy_intrinsic(
|
||||
@@ -144,28 +144,28 @@ class CallGenVt(CallGenBase.CallGenBase):
|
||||
llvmlite.build_br(builder, vt_skip_bb)
|
||||
# skip 块:reload vtable → GEP 槽位 → store 函数指针(i8*)
|
||||
llvmlite.position_at_end(builder, vt_skip_bb)
|
||||
vt_ptr2: llvmlite.Value | t.CPtr = llvmlite.build_load(
|
||||
vt_ptr2: rawptr[llvmlite.Value] = llvmlite.build_load(
|
||||
builder, i8_ptr_ty, vtable_slot)
|
||||
if vt_ptr2 is None:
|
||||
return 0
|
||||
vt_typed: llvmlite.Value | t.CPtr = llvmlite.build_bitcast(
|
||||
vt_typed: rawptr[llvmlite.Value] = llvmlite.build_bitcast(
|
||||
builder, vt_ptr2, llvmlite.Ptr(pool, vtable_ty))
|
||||
if vt_typed is None:
|
||||
return 0
|
||||
vt_slotp: llvmlite.Value | t.CPtr = llvmlite.build_gep_struct(
|
||||
vt_slotp: rawptr[llvmlite.Value] = llvmlite.build_gep_struct(
|
||||
builder, vtable_ty, i8_ptr_ty, vt_typed, method_index)
|
||||
if vt_slotp is None:
|
||||
return 0
|
||||
fptr_i8: llvmlite.Value | t.CPtr = llvmlite.build_bitcast(
|
||||
fptr_i8: rawptr[llvmlite.Value] = llvmlite.build_bitcast(
|
||||
builder, func_val, i8_ptr_ty)
|
||||
if fptr_i8 is not None:
|
||||
llvmlite.build_store(builder, fptr_i8, vt_slotp)
|
||||
return 1
|
||||
def _write_vtable_attr(self, builder: llvmlite.IRBuilder | t.CPtr,
|
||||
def _write_vtable_attr(self, builder: rawptr[llvmlite.IRBuilder],
|
||||
pool: rawptr[memhub.MemBuddy],
|
||||
mod: rawptr[llvmlite.LLVMModule],
|
||||
node: rawptr[ast.AST],
|
||||
rhs_val: llvmlite.Value | t.CPtr,
|
||||
rhs_val: rawptr[llvmlite.Value],
|
||||
trans: rawptr[HT.Translator]) -> int:
|
||||
"""属性写入 obj.method = func:检测 vtable 方法并生成槽位写入(成功返回 1)"""
|
||||
if node is None or builder is None or pool is None or mod is None:
|
||||
@@ -180,7 +180,7 @@ class CallGenVt(CallGenBase.CallGenBase):
|
||||
if at.value.kind() == ast.ASTKind.Name:
|
||||
nm_v: rawptr[ast.Name] = rawptr[ast.Name](at.value)
|
||||
if nm_v.id is not None:
|
||||
ve_v: GenTypes.VarEntry | t.CPtr = self.Gen.VarGen.lookup_var_entry(
|
||||
ve_v: rawptr[GenTypes.VarEntry] = self.Gen.VarGen.lookup_var_entry(
|
||||
trans.SymTab, nm_v.id)
|
||||
if ve_v is not None:
|
||||
class_nm_v = self.Gen.VarGen.var_annot_class_name(ve_v)
|
||||
@@ -198,7 +198,7 @@ class CallGenVt(CallGenBase.CallGenBase):
|
||||
if vm_idx_v < 0:
|
||||
return 0
|
||||
# 解析 obj_ptr(对齐 get_attribute_ptr 前半段:Name 直接查 alloca)
|
||||
obj_ptr_v: llvmlite.Value | t.CPtr = None
|
||||
obj_ptr_v: rawptr[llvmlite.Value] = None
|
||||
if at.value.kind() == ast.ASTKind.Name:
|
||||
obj_ptr_v = self.Gen.VarGen.lookup_var(
|
||||
trans.SymTab, (rawptr[ast.Name](at.value)).id)
|
||||
|
||||
@@ -192,7 +192,7 @@ class ClassGenBase:
|
||||
return 1
|
||||
if cd.bases is None:
|
||||
return 0
|
||||
bases: list[rawptr[ast.AST]] | t.CPtr = cd.bases
|
||||
bases: rawptr[list[rawptr[ast.AST]]] = cd.bases
|
||||
bn: sizet = len(bases)
|
||||
if bn == 0:
|
||||
return 0
|
||||
@@ -245,7 +245,7 @@ class ClassGenBase:
|
||||
return 1
|
||||
if cd.bases is None:
|
||||
return 0
|
||||
bases: list[rawptr[ast.AST]] | t.CPtr = cd.bases
|
||||
bases: rawptr[list[rawptr[ast.AST]]] = cd.bases
|
||||
bn: sizet = len(bases)
|
||||
if bn == 0:
|
||||
return 0
|
||||
@@ -298,7 +298,7 @@ class ClassGenBase:
|
||||
return 1
|
||||
if cd.bases is None:
|
||||
return 0
|
||||
bases: list[rawptr[ast.AST]] | t.CPtr = cd.bases
|
||||
bases: rawptr[list[rawptr[ast.AST]]] = cd.bases
|
||||
bn: sizet = len(bases)
|
||||
if bn == 0:
|
||||
return 0
|
||||
@@ -309,7 +309,7 @@ class ClassGenBase:
|
||||
if self._is_crenum_base(base_node, trans) == 1:
|
||||
return 1
|
||||
return 0
|
||||
def _has_decorator(self, decorator_list: list[rawptr[ast.AST]] | t.CPtr,
|
||||
def _has_decorator(self, decorator_list: rawptr[list[rawptr[ast.AST]]],
|
||||
deco_name: str) -> int:
|
||||
"""检查 decorator_list 中是否有指定装饰器名"""
|
||||
if decorator_list is None:
|
||||
@@ -356,7 +356,7 @@ class ClassGenBase:
|
||||
return 0
|
||||
return 1 if string.strcmp(at2.attr, attr_name) == 0 else 0
|
||||
return 0
|
||||
def _class_has_tattr(self, decorator_list: list[rawptr[ast.AST]] | t.CPtr,
|
||||
def _class_has_tattr(self, decorator_list: rawptr[list[rawptr[ast.AST]]],
|
||||
attr_name: str) -> int:
|
||||
"""检查装饰器列表是否含 t.attr.<attr_name>(@c.Attribute(t.attr.xxx) 或 @t.attr.xxx)。
|
||||
|
||||
@@ -413,7 +413,7 @@ class ClassGenBase:
|
||||
return 0
|
||||
return int(cn.int_val)
|
||||
return 0
|
||||
def _class_aligned_value(self, decorator_list: list[rawptr[ast.AST]] | t.CPtr) -> int:
|
||||
def _class_aligned_value(self, decorator_list: rawptr[list[rawptr[ast.AST]]]) -> int:
|
||||
"""取 @c.Attribute(t.attr.aligned(N)) 的对齐字节数,无 aligned 返回 0"""
|
||||
if decorator_list is None:
|
||||
return 0
|
||||
@@ -445,7 +445,7 @@ class ClassGenBase:
|
||||
if av2 > 0:
|
||||
return av2
|
||||
return 0
|
||||
def _extract_func_meta(self, decorator_list: list[rawptr[ast.AST]] | t.CPtr) -> int:
|
||||
def _extract_func_meta(self, decorator_list: rawptr[list[rawptr[ast.AST]]]) -> int:
|
||||
"""从装饰器列表提取元数据位掩码,返回 0=无装饰器元数据"""
|
||||
meta: int = 0
|
||||
if decorator_list is None:
|
||||
@@ -734,7 +734,7 @@ class ClassGenBase:
|
||||
"""类定义是否是异常类:基类是 Exception 或已注册异常类(1=是)"""
|
||||
if cd is None or cd.bases is None:
|
||||
return 0
|
||||
bases_e: list[rawptr[ast.AST]] | t.CPtr = cd.bases
|
||||
bases_e: rawptr[list[rawptr[ast.AST]]] = cd.bases
|
||||
bn_e: sizet = len(bases_e)
|
||||
for bi_e in range(bn_e):
|
||||
base_e: rawptr[ast.AST] = bases_e.get(bi_e)
|
||||
@@ -758,7 +758,7 @@ class ClassGenBase:
|
||||
"""返回异常类定义的真实父类名(第一个非 Exception 的已注册异常类),无则 None"""
|
||||
if cd is None or cd.bases is None:
|
||||
return None
|
||||
bases_e2: list[rawptr[ast.AST]] | t.CPtr = cd.bases
|
||||
bases_e2: rawptr[list[rawptr[ast.AST]]] = cd.bases
|
||||
bn_e2: sizet = len(bases_e2)
|
||||
for bi_e2 in range(bn_e2):
|
||||
base_e2: rawptr[ast.AST] = bases_e2.get(bi_e2)
|
||||
@@ -792,10 +792,10 @@ class ClassGenBase:
|
||||
return
|
||||
if value_node.kind() != ast.ASTKind.List:
|
||||
return
|
||||
lst_rcm: ast.List | t.CPtr = (ast.List | t.CPtr)(value_node)
|
||||
lst_rcm: rawptr[ast.List] = rawptr[ast.List](value_node)
|
||||
if lst_rcm.elts is None:
|
||||
return
|
||||
elts_rcm: list[rawptr[ast.AST]] | t.CPtr = lst_rcm.elts
|
||||
elts_rcm: rawptr[list[rawptr[ast.AST]]] = lst_rcm.elts
|
||||
en_rcm: sizet = len(elts_rcm)
|
||||
for ei_rcm in range(en_rcm):
|
||||
el_rcm: rawptr[ast.AST] = elts_rcm.get(ei_rcm)
|
||||
@@ -960,7 +960,7 @@ class ClassGenBase:
|
||||
pool: rawptr[memhub.MemBuddy] = None
|
||||
if trans is not None:
|
||||
pool = trans.Pool
|
||||
bases: list[rawptr[ast.AST]] | t.CPtr = cd.bases
|
||||
bases: rawptr[list[rawptr[ast.AST]]] = cd.bases
|
||||
bn: sizet = len(bases)
|
||||
if bn == 0:
|
||||
return None
|
||||
@@ -1012,7 +1012,7 @@ class ClassGenBase:
|
||||
"""收集所有非 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[rawptr[ast.AST]] | t.CPtr = cd.bases
|
||||
bases: rawptr[list[rawptr[ast.AST]]] = cd.bases
|
||||
bn: sizet = len(bases)
|
||||
count: int = 0
|
||||
for bi in range(bn):
|
||||
@@ -1059,7 +1059,7 @@ class ClassGenBase:
|
||||
if trans is None or cd is None or cd.bases is None:
|
||||
return
|
||||
pool: rawptr[memhub.MemBuddy] = trans.Pool
|
||||
bases: list[rawptr[ast.AST]] | t.CPtr = cd.bases
|
||||
bases: rawptr[list[rawptr[ast.AST]]] = cd.bases
|
||||
bn: sizet = len(bases)
|
||||
if bn == 0:
|
||||
return
|
||||
@@ -1099,7 +1099,7 @@ class ClassGenBase:
|
||||
"""检查类中是否有任何函数标记了 @t.CVTable,返回 1=有 / 0=无"""
|
||||
if cd is None or cd.children is None:
|
||||
return 0
|
||||
children: list[rawptr[ast.AST]] | t.CPtr = cd.children
|
||||
children: rawptr[list[rawptr[ast.AST]]] = cd.children
|
||||
cn: sizet = len(children)
|
||||
for ci in range(cn):
|
||||
stmt: rawptr[ast.AST] = children.get(ci)
|
||||
@@ -1146,7 +1146,7 @@ class ClassGenBase:
|
||||
# 用 SHA1 感知查找父类,规避跨模块同名找错
|
||||
is_nvt: int = 0
|
||||
if trans is not None:
|
||||
p_entry: GenTypes.StructEntry | t.CPtr = self.Gen.StructGen.find_struct_by_module(
|
||||
p_entry: rawptr[GenTypes.StructEntry] = self.Gen.StructGen.find_struct_by_module(
|
||||
parent_name, trans.ModuleSha1)
|
||||
if p_entry is None:
|
||||
# 跨模块父类回退全局查找(父类注册在父模块 SHA1 下,如 linkedlist.LinkedNode),
|
||||
@@ -1189,7 +1189,7 @@ class ClassGenBase:
|
||||
# 用 SHA1 感知查找父类,规避跨模块同名找错
|
||||
is_nvt: int = 0
|
||||
if trans is not None:
|
||||
p_entry: GenTypes.StructEntry | t.CPtr = self.Gen.StructGen.find_struct_by_module(
|
||||
p_entry: rawptr[GenTypes.StructEntry] = self.Gen.StructGen.find_struct_by_module(
|
||||
parent_name, trans.ModuleSha1)
|
||||
if p_entry is None:
|
||||
# 跨模块父类回退全局查找(同 _detect_vtable_status 的回退)
|
||||
|
||||
@@ -85,7 +85,7 @@ class ClassGenDef(ClassGenBase.ClassGenBase):
|
||||
return self.Gen.ClassGenBase._register_exception_class_def(trans, cd)
|
||||
|
||||
# 检查是否已注册(用 SHA1 区分跨模块同名类)
|
||||
existing: GenTypes.StructEntry | t.CPtr = self.Gen.StructGen.find_struct_by_module(
|
||||
existing: rawptr[GenTypes.StructEntry] = self.Gen.StructGen.find_struct_by_module(
|
||||
class_name, trans.ModuleSha1)
|
||||
# 空类注册不完整检测:existing FieldCount==0 但源类体声明了字段(vpi 注入/注册缺陷)。
|
||||
# 标记 _deps_pending 延迟会让空 entry 持久存在、多遍死锁不收敛 ⇒ 改为中和旧 entry
|
||||
@@ -185,7 +185,7 @@ class ClassGenDef(ClassGenBase.ClassGenBase):
|
||||
# Phase B(declare_only==0)不延迟,避免死锁。
|
||||
# ============================================================
|
||||
if trans._declare_only == 1 and parent_name is not None:
|
||||
parent_check: GenTypes.StructEntry | t.CPtr = self.Gen.StructGen.find_struct_by_module(
|
||||
parent_check: rawptr[GenTypes.StructEntry] = self.Gen.StructGen.find_struct_by_module(
|
||||
parent_name, trans.ModuleSha1)
|
||||
if parent_check is None:
|
||||
parent_check = self.Gen.StructGen.find_struct(parent_name)
|
||||
@@ -229,7 +229,7 @@ class ClassGenDef(ClassGenBase.ClassGenBase):
|
||||
if pname is None:
|
||||
continue
|
||||
# 用 SHA1 感知查找父类,规避跨模块同名找错
|
||||
parent_entry: GenTypes.StructEntry | t.CPtr = self.Gen.StructGen.find_struct_by_module(
|
||||
parent_entry: rawptr[GenTypes.StructEntry] = self.Gen.StructGen.find_struct_by_module(
|
||||
pname, trans.ModuleSha1)
|
||||
if parent_entry is None:
|
||||
# 父类可能定义在另一个模块(不同 SHA1,如 HandlesBase.Mixin),
|
||||
@@ -245,7 +245,7 @@ class ClassGenDef(ClassGenBase.ClassGenBase):
|
||||
return 0
|
||||
pfc: int = parent_entry.FieldCount
|
||||
for pfi in range(pfc):
|
||||
pfe: GenTypes.FieldEntry | t.CPtr = self.Gen.StructGen._get_field_entry(
|
||||
pfe: rawptr[GenTypes.FieldEntry] = self.Gen.StructGen._get_field_entry(
|
||||
parent_entry, pfi)
|
||||
if pfe is None:
|
||||
continue
|
||||
@@ -275,7 +275,7 @@ class ClassGenDef(ClassGenBase.ClassGenBase):
|
||||
field_annot_buf[field_count] = 0
|
||||
field_count += 1
|
||||
|
||||
children: list[rawptr[ast.AST]] | t.CPtr = cd.children
|
||||
children: rawptr[list[rawptr[ast.AST]]] = cd.children
|
||||
if children is None:
|
||||
return 0
|
||||
|
||||
@@ -430,14 +430,14 @@ class ClassGenDef(ClassGenBase.ClassGenBase):
|
||||
# 2. 创建 LLVM StructType
|
||||
# ============================================================
|
||||
# 构建 ParamNode 链表
|
||||
first_node: rawptr[llvmlite.Function] = None
|
||||
prev_node: rawptr[llvmlite.Function] = None
|
||||
first_node: rawptr[llvmlite.ParamNode] = None
|
||||
prev_node: rawptr[llvmlite.ParamNode] = None
|
||||
total_field_count: int = field_count
|
||||
|
||||
# 如果有虚表,首字段添加 i8* vtable 指针
|
||||
if has_vtable == 1:
|
||||
i8_ptr_ty: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, llvmlite.Int8(pool))
|
||||
vtable_node: rawptr[llvmlite.Function] = pool.alloc(llvmlite.ParamNode.__sizeof__())
|
||||
vtable_node: rawptr[llvmlite.ParamNode] = pool.alloc(llvmlite.ParamNode.__sizeof__())
|
||||
if vtable_node is None:
|
||||
VLogger.error(f"failed to alloc vtable node for {class_name}", "CLASS")
|
||||
return 0
|
||||
@@ -454,7 +454,7 @@ class ClassGenDef(ClassGenBase.ClassGenBase):
|
||||
fty: rawptr[llvmlite.LLVMType] = (rawptr[llvmlite.LLVMType])(fty_addr)
|
||||
|
||||
# 创建 ParamNode
|
||||
pnode: rawptr[llvmlite.Function] = pool.alloc(llvmlite.ParamNode.__sizeof__())
|
||||
pnode: rawptr[llvmlite.ParamNode] = pool.alloc(llvmlite.ParamNode.__sizeof__())
|
||||
if pnode is None:
|
||||
continue
|
||||
string.memset(pnode, 0, llvmlite.ParamNode.__sizeof__())
|
||||
@@ -528,7 +528,7 @@ class ClassGenDef(ClassGenBase.ClassGenBase):
|
||||
# ============================================================
|
||||
# 3. 注册到 HandlesStruct
|
||||
# ============================================================
|
||||
entry: GenTypes.StructEntry | t.CPtr = self.Gen.StructGen.register_struct(
|
||||
entry: rawptr[GenTypes.StructEntry] = self.Gen.StructGen.register_struct(
|
||||
pool, class_name, struct_ty, trans.ModuleSha1)
|
||||
if entry is None:
|
||||
VLogger.error(f"failed to register {class_name}", "CLASS")
|
||||
|
||||
@@ -159,7 +159,7 @@ class ClassGenEnum(ClassGenBase.ClassGenBase):
|
||||
# 成员缺失(FR_OK 找不到)。register_enum 幂等返回已有 entry,
|
||||
# add_enum_member 成员名去重,重复处理安全合并。
|
||||
|
||||
children: list[rawptr[ast.AST]] | t.CPtr = cd.children
|
||||
children: rawptr[list[rawptr[ast.AST]]] = cd.children
|
||||
if children is None:
|
||||
VLogger.warning(f"{class_name} has no body", "ENUM")
|
||||
return 0
|
||||
@@ -226,7 +226,7 @@ class ClassGenEnum(ClassGenBase.ClassGenBase):
|
||||
ag: rawptr[ast.Assign] = rawptr[ast.Assign](stmt)
|
||||
if ag is None or ag.targets is None:
|
||||
continue
|
||||
tgts: list[rawptr[ast.AST]] | t.CPtr = ag.targets
|
||||
tgts: rawptr[list[rawptr[ast.AST]]] = ag.targets
|
||||
tn: sizet = len(tgts)
|
||||
if tn == 0:
|
||||
continue
|
||||
@@ -276,7 +276,7 @@ class ClassGenEnum(ClassGenBase.ClassGenBase):
|
||||
base_ty = mty
|
||||
|
||||
# 注册枚举
|
||||
entry: GenTypes.EnumEntry | t.CPtr = self.Gen.StmtGenDecl.register_enum(
|
||||
entry: rawptr[GenTypes.EnumEntry] = self.Gen.StmtGenDecl.register_enum(
|
||||
pool, class_name, base_ty)
|
||||
if entry is None:
|
||||
VLogger.error("failed to register {class_name}", "ENUM")
|
||||
@@ -322,7 +322,7 @@ class ClassGenEnum(ClassGenBase.ClassGenBase):
|
||||
is_packed: int = self.Gen.StructGen.struct_type_is_packed(ty)
|
||||
total: int = 0
|
||||
max_align: int = 1
|
||||
cur: rawptr[llvmlite.Function] = fields
|
||||
cur: rawptr[llvmlite.ParamNode] = fields
|
||||
i: int = 0
|
||||
while cur is not None and i < fcount:
|
||||
if cur.Ty is not None:
|
||||
@@ -377,7 +377,7 @@ class ClassGenEnum(ClassGenBase.ClassGenBase):
|
||||
return 1
|
||||
# 结构体的对齐 = 最大字段对齐
|
||||
max_align: int = 1
|
||||
cur: rawptr[llvmlite.Function] = fields
|
||||
cur: rawptr[llvmlite.ParamNode] = fields
|
||||
i: int = 0
|
||||
while cur is not None and i < fcount:
|
||||
if cur.Ty is not None:
|
||||
@@ -403,7 +403,7 @@ class ClassGenEnum(ClassGenBase.ClassGenBase):
|
||||
self.Gen.StructGen.add_visible_struct(pool, class_name)
|
||||
|
||||
# 检查是否已注册(用 SHA1 区分跨模块同名类)
|
||||
existing: GenTypes.StructEntry | t.CPtr = self.Gen.StructGen.find_struct_by_module(
|
||||
existing: rawptr[GenTypes.StructEntry] = self.Gen.StructGen.find_struct_by_module(
|
||||
class_name, trans.ModuleSha1)
|
||||
if existing is not None:
|
||||
# Phase B: 将已存在的命名结构体注册到当前模块
|
||||
@@ -412,7 +412,7 @@ class ClassGenEnum(ClassGenBase.ClassGenBase):
|
||||
# SHA1 已在 register_struct 时设置,无需再补
|
||||
return 0
|
||||
|
||||
children: list[rawptr[ast.AST]] | t.CPtr = cd.children
|
||||
children: rawptr[list[rawptr[ast.AST]]] = cd.children
|
||||
if children is None:
|
||||
VLogger.warning("{class_name} has no body", "UNION")
|
||||
return 0
|
||||
@@ -488,7 +488,7 @@ class ClassGenEnum(ClassGenBase.ClassGenBase):
|
||||
array_ty: rawptr[llvmlite.LLVMType] = llvmlite.Array(pool, i8_ty, max_size)
|
||||
|
||||
# 构建 ParamNode 链表(单字段:字节数组)
|
||||
pnode: rawptr[llvmlite.Function] = pool.alloc(llvmlite.ParamNode.__sizeof__())
|
||||
pnode: rawptr[llvmlite.ParamNode] = pool.alloc(llvmlite.ParamNode.__sizeof__())
|
||||
if pnode is None:
|
||||
return 0
|
||||
string.memset(pnode, 0, llvmlite.ParamNode.__sizeof__())
|
||||
@@ -522,7 +522,7 @@ class ClassGenEnum(ClassGenBase.ClassGenBase):
|
||||
llvmlite.module_add_named_type(trans.Module, pool, union_ty)
|
||||
|
||||
# 注册到 HandlesStruct(传递 SHA1 在注册时直接设置,避免跨模块同名找错 entry)
|
||||
entry: GenTypes.StructEntry | t.CPtr = self.Gen.StructGen.register_struct(
|
||||
entry: rawptr[GenTypes.StructEntry] = self.Gen.StructGen.register_struct(
|
||||
pool, class_name, union_ty, trans.ModuleSha1)
|
||||
if entry is None:
|
||||
VLogger.error(f"failed to register {class_name}", "UNION")
|
||||
@@ -626,7 +626,7 @@ class ClassGenEnum(ClassGenBase.ClassGenBase):
|
||||
self.Gen.StructGen.add_visible_struct(pool, class_name)
|
||||
|
||||
# 检查是否已注册(用 SHA1 区分跨模块同名类)
|
||||
existing: GenTypes.StructEntry | t.CPtr = self.Gen.StructGen.find_struct_by_module(
|
||||
existing: rawptr[GenTypes.StructEntry] = self.Gen.StructGen.find_struct_by_module(
|
||||
class_name, trans.ModuleSha1)
|
||||
if existing is not None:
|
||||
# existing 只保证 struct entry 在,不保证 REnum 语义(变体表)在:struct entry
|
||||
@@ -646,7 +646,7 @@ class ClassGenEnum(ClassGenBase.ClassGenBase):
|
||||
existing.Ty = None
|
||||
existing.FieldCount = 0
|
||||
|
||||
children: list[rawptr[ast.AST]] | t.CPtr = cd.children
|
||||
children: rawptr[list[rawptr[ast.AST]]] = cd.children
|
||||
if children is None:
|
||||
# [D32 fail-fast] 此前只 warning + return 0:变体表**静默不注册** →
|
||||
# _is_renum_class_name 恒 0、变体构造拿不到 tag(__types.vp L703
|
||||
@@ -680,7 +680,7 @@ class ClassGenEnum(ClassGenBase.ClassGenBase):
|
||||
if variant_cd is None or variant_cd.children is None:
|
||||
variant_count += 1
|
||||
continue
|
||||
variant_children: list[rawptr[ast.AST]] | t.CPtr = variant_cd.children
|
||||
variant_children: rawptr[list[rawptr[ast.AST]]] = variant_cd.children
|
||||
vcn: sizet = len(variant_children)
|
||||
field_idx: int = 0
|
||||
for vi in range(vcn):
|
||||
@@ -732,7 +732,7 @@ class ClassGenEnum(ClassGenBase.ClassGenBase):
|
||||
ag_v: rawptr[ast.Assign] = rawptr[ast.Assign](stmt)
|
||||
if ag_v is None or ag_v.targets is None:
|
||||
continue
|
||||
tgts_v: list[rawptr[ast.AST]] | t.CPtr = ag_v.targets
|
||||
tgts_v: rawptr[list[rawptr[ast.AST]]] = ag_v.targets
|
||||
if len(tgts_v) == 0:
|
||||
continue
|
||||
t0_v: rawptr[ast.AST] = tgts_v.get(0)
|
||||
@@ -831,7 +831,7 @@ class ClassGenEnum(ClassGenBase.ClassGenBase):
|
||||
llvmlite.module_add_named_type(trans.Module, pool, renum_ty)
|
||||
|
||||
# 注册到 HandlesStruct
|
||||
entry: GenTypes.StructEntry | t.CPtr = self.Gen.StructGen.register_struct(
|
||||
entry: rawptr[GenTypes.StructEntry] = self.Gen.StructGen.register_struct(
|
||||
pool, class_name, renum_ty, trans.ModuleSha1)
|
||||
if entry is None:
|
||||
VLogger.error(f"failed to register {class_name}", "RENUM")
|
||||
@@ -886,7 +886,7 @@ class ClassGenEnum(ClassGenBase.ClassGenBase):
|
||||
"""
|
||||
if trans is None or pool is None or class_name is None or cd is None:
|
||||
return
|
||||
children: list[rawptr[ast.AST]] | t.CPtr = cd.children
|
||||
children: rawptr[list[rawptr[ast.AST]]] = cd.children
|
||||
if children is None:
|
||||
return
|
||||
cn: sizet = len(children)
|
||||
@@ -898,7 +898,7 @@ class ClassGenEnum(ClassGenBase.ClassGenBase):
|
||||
if variant_cd is None or variant_cd.name is None \
|
||||
or variant_cd.children is None:
|
||||
continue
|
||||
vchildren: list[rawptr[ast.AST]] | t.CPtr = variant_cd.children
|
||||
vchildren: rawptr[list[rawptr[ast.AST]]] = variant_cd.children
|
||||
vcn: sizet = len(vchildren)
|
||||
field_idx: int = 0
|
||||
for vi in range(vcn):
|
||||
@@ -938,7 +938,7 @@ class ClassGenEnum(ClassGenBase.ClassGenBase):
|
||||
return
|
||||
if variant_count == 0:
|
||||
return
|
||||
children: list[rawptr[ast.AST]] | t.CPtr = cd.children
|
||||
children: rawptr[list[rawptr[ast.AST]]] = cd.children
|
||||
if children is None:
|
||||
return
|
||||
|
||||
@@ -1011,7 +1011,7 @@ class ClassGenEnum(ClassGenBase.ClassGenBase):
|
||||
ag_p: rawptr[ast.Assign] = rawptr[ast.Assign](stmt_p)
|
||||
if ag_p is None or ag_p.targets is None or ag_p.value is None:
|
||||
continue
|
||||
tgts_p: list[rawptr[ast.AST]] | t.CPtr = ag_p.targets
|
||||
tgts_p: rawptr[list[rawptr[ast.AST]]] = ag_p.targets
|
||||
if len(tgts_p) == 0:
|
||||
continue
|
||||
t0_p: rawptr[ast.AST] = tgts_p.get(0)
|
||||
@@ -1054,7 +1054,7 @@ class ClassGenEnum(ClassGenBase.ClassGenBase):
|
||||
ag_rv: rawptr[ast.Assign] = rawptr[ast.Assign](stmt)
|
||||
if ag_rv is None or ag_rv.targets is None:
|
||||
continue
|
||||
tgts_rv: list[rawptr[ast.AST]] | t.CPtr = ag_rv.targets
|
||||
tgts_rv: rawptr[list[rawptr[ast.AST]]] = ag_rv.targets
|
||||
if len(tgts_rv) == 0:
|
||||
continue
|
||||
t0_rv: rawptr[ast.AST] = tgts_rv.get(0)
|
||||
|
||||
@@ -298,9 +298,9 @@ class ClassGenGeneric(ClassGenBase.ClassGenBase):
|
||||
# Tuple: (T, int) 等
|
||||
if k == ast.ASTKind.Tuple:
|
||||
tup: rawptr[ast.Tuple] = rawptr[ast.Tuple](node)
|
||||
new_elts: list[rawptr[ast.AST]] | t.CPtr = list[rawptr[ast.AST]](pool, 8)
|
||||
new_elts: rawptr[list[rawptr[ast.AST]]] = list[rawptr[ast.AST]](pool, 8)
|
||||
if tup.elts is not None:
|
||||
tup_elts: list[rawptr[ast.AST]] | t.CPtr = tup.elts
|
||||
tup_elts: rawptr[list[rawptr[ast.AST]]] = tup.elts
|
||||
en: sizet = len(tup_elts)
|
||||
ei: sizet
|
||||
for ei in range(en):
|
||||
@@ -329,9 +329,9 @@ class ClassGenGeneric(ClassGenBase.ClassGenBase):
|
||||
return args
|
||||
old_args: rawptr[ast.Arguments] = rawptr[ast.Arguments](args)
|
||||
# 拷贝 args 列表,替换每个 Arg 的 annotation
|
||||
new_arg_list: list[rawptr[ast.AST]] | t.CPtr = list[rawptr[ast.AST]](pool, 8)
|
||||
new_arg_list: rawptr[list[rawptr[ast.AST]]] = list[rawptr[ast.AST]](pool, 8)
|
||||
if old_args.args is not None:
|
||||
old_arg_list: list[rawptr[ast.AST]] | t.CPtr = old_args.args
|
||||
old_arg_list: rawptr[list[rawptr[ast.AST]]] = old_args.args
|
||||
an: sizet = len(old_arg_list)
|
||||
ai: sizet
|
||||
for ai in range(an):
|
||||
@@ -364,7 +364,7 @@ class ClassGenGeneric(ClassGenBase.ClassGenBase):
|
||||
cd.decorator_list, None)
|
||||
# 拷贝 children
|
||||
if cd.children is not None:
|
||||
cd_children: list[rawptr[ast.AST]] | t.CPtr = cd.children
|
||||
cd_children: rawptr[list[rawptr[ast.AST]]] = cd.children
|
||||
cn: sizet = len(cd_children)
|
||||
ci: sizet
|
||||
for ci in range(cn):
|
||||
@@ -389,7 +389,7 @@ class ClassGenGeneric(ClassGenBase.ClassGenBase):
|
||||
fd.decorator_list, new_returns2, 0)
|
||||
# 方法体直接引用原始节点
|
||||
if fd.children is not None:
|
||||
fd_children: list[rawptr[ast.AST]] | t.CPtr = fd.children
|
||||
fd_children: rawptr[list[rawptr[ast.AST]]] = fd.children
|
||||
bcn: sizet = len(fd_children)
|
||||
bci: sizet
|
||||
for bci in range(bcn):
|
||||
@@ -474,7 +474,7 @@ class ClassGenGeneric(ClassGenBase.ClassGenBase):
|
||||
"""
|
||||
if spec_name is None or trigger_sha1 is None:
|
||||
return 0
|
||||
entry_rt: GenTypes.StructEntry | t.CPtr = self.Gen.StructGen.find_struct(spec_name)
|
||||
entry_rt: rawptr[GenTypes.StructEntry] = self.Gen.StructGen.find_struct(spec_name)
|
||||
if entry_rt is None:
|
||||
return 0
|
||||
if string.strcmp(entry_rt.Name, spec_name) != 0:
|
||||
@@ -547,7 +547,7 @@ class ClassGenGeneric(ClassGenBase.ClassGenBase):
|
||||
# define,避免符号只有 declare 无 define → 链接失败。
|
||||
# 首次 Phase B 特化(Phase 1a 未特化)find_struct 返回 None,不补译,走下方正常全量翻译。
|
||||
if trans._declare_only == 0:
|
||||
pre_existing: GenTypes.StructEntry | t.CPtr = self.Gen.StructGen.find_struct(spec_name)
|
||||
pre_existing: rawptr[GenTypes.StructEntry] = self.Gen.StructGen.find_struct(spec_name)
|
||||
if pre_existing is not None and pre_existing.MethodsEmitted == 0:
|
||||
# 防重入:先标记 MethodsEmitted=1,避免补译过程中方法体/返回类型注解
|
||||
# 再次触发 _specialize_generic_class(如 __iter__ 返回 list[T]|t.CPtr)
|
||||
@@ -624,7 +624,7 @@ class ClassGenGeneric(ClassGenBase.ClassGenBase):
|
||||
return cached
|
||||
|
||||
# 4. 检查是否已注册(Phase B 重复特化)
|
||||
existing: GenTypes.StructEntry | t.CPtr = self.Gen.StructGen.find_struct(spec_name)
|
||||
existing: rawptr[GenTypes.StructEntry] = self.Gen.StructGen.find_struct(spec_name)
|
||||
if existing is not None:
|
||||
self._cache_spec(pool, spec_key, spec_name)
|
||||
self._record_spec_trigger(pool, spec_name, spec_trigger_sha1)
|
||||
@@ -687,11 +687,11 @@ class ClassGenGeneric(ClassGenBase.ClassGenBase):
|
||||
# 特化结果字段名完整性检查(fail-fast:字段名缺失 = 字段表损坏,
|
||||
# 静默继续会让后续 GEP 按错索引访问)
|
||||
if string.strcmp(class_name, "GSListNode") == 0:
|
||||
result_entry: GenTypes.StructEntry | t.CPtr = self.Gen.StructGen.find_struct(spec_name)
|
||||
result_entry: rawptr[GenTypes.StructEntry] = self.Gen.StructGen.find_struct(spec_name)
|
||||
if result_entry is not None:
|
||||
ri: int
|
||||
for ri in range(result_entry.FieldCount):
|
||||
rfe: GenTypes.FieldEntry | t.CPtr = self.Gen.StructGen._get_field_entry(
|
||||
rfe: rawptr[GenTypes.FieldEntry] = self.Gen.StructGen._get_field_entry(
|
||||
result_entry, ri)
|
||||
if rfe is not None:
|
||||
rfn: str = self.Gen.StructGen.get_field_name_ptr(rfe)
|
||||
|
||||
@@ -87,7 +87,7 @@ class ClassGenVTable(ClassGenBase.ClassGenBase):
|
||||
pool: rawptr[memhub.MemBuddy] = trans.Pool
|
||||
mod: rawptr[llvmlite.LLVMModule] = trans.Module
|
||||
|
||||
children: list[rawptr[ast.AST]] | t.CPtr = cd.children
|
||||
children: rawptr[list[rawptr[ast.AST]]] = cd.children
|
||||
if children is None:
|
||||
return 0
|
||||
cn: sizet = len(children)
|
||||
@@ -114,7 +114,7 @@ class ClassGenVTable(ClassGenBase.ClassGenBase):
|
||||
# 如果子类覆盖了方法,full_name 用子类的;否则用父类的。
|
||||
# 用 SHA1 感知查找,规避跨模块同名 find_struct 找错
|
||||
# ============================================================
|
||||
vt_self_entry: GenTypes.StructEntry | t.CPtr = self.Gen.StructGen.find_struct_by_module(
|
||||
vt_self_entry: rawptr[GenTypes.StructEntry] = self.Gen.StructGen.find_struct_by_module(
|
||||
class_name, trans.ModuleSha1)
|
||||
# 多继承:遍历所有父类(声明顺序),vtable 方法合并(短名去重,先声明父类优先)
|
||||
parent_count: int = self.Gen.StructGen.get_parent_count(class_name)
|
||||
@@ -124,7 +124,7 @@ class ClassGenVTable(ClassGenBase.ClassGenBase):
|
||||
if pname is None:
|
||||
continue
|
||||
# 查找父类 entry(优先同模块 SHA1 匹配)
|
||||
vt_parent_entry: GenTypes.StructEntry | t.CPtr = self.Gen.StructGen.find_struct_by_module(
|
||||
vt_parent_entry: rawptr[GenTypes.StructEntry] = self.Gen.StructGen.find_struct_by_module(
|
||||
pname, trans.ModuleSha1)
|
||||
if vt_parent_entry is None:
|
||||
# 跨模块继承: 父类在不同模块定义(SHA1 不同),回退到按类名查找
|
||||
@@ -204,7 +204,7 @@ class ClassGenVTable(ClassGenBase.ClassGenBase):
|
||||
method_parent_sha1s[method_count] = 0
|
||||
else:
|
||||
# 继承未覆盖: 用实际定义类的模块 SHA1(跨模块继承时 mangling 正确)
|
||||
def_entry2: GenTypes.StructEntry | t.CPtr = self.Gen.StructGen.find_struct(
|
||||
def_entry2: rawptr[GenTypes.StructEntry] = 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] = sizet(def_entry2.ModuleSha1)
|
||||
@@ -308,7 +308,7 @@ class ClassGenVTable(ClassGenBase.ClassGenBase):
|
||||
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(
|
||||
vt_self_entry: rawptr[GenTypes.StructEntry] = self.Gen.StructGen.find_struct_by_module(
|
||||
class_name, trans.ModuleSha1)
|
||||
|
||||
# 2. 构造 VTable 类型: { i8*, i8*, ..., i8* }
|
||||
@@ -397,7 +397,7 @@ class ClassGenVTable(ClassGenBase.ClassGenBase):
|
||||
vtable_mangled: str = self.Gen.FuncGenBase._mangle_name(trans, vtable_name_buf)
|
||||
|
||||
# 5. 创建全局变量
|
||||
gv: llvmlite.GlobalVariable | t.CPtr = llvmlite.new_global_variable(
|
||||
gv: rawptr[llvmlite.GlobalVariable] = llvmlite.new_global_variable(
|
||||
pool, vtable_mangled, vtable_ty)
|
||||
if gv is None:
|
||||
return 0
|
||||
@@ -444,7 +444,7 @@ class ClassGenVTable(ClassGenBase.ClassGenBase):
|
||||
if trans is None or cd is None or struct_ty is None or class_name is None:
|
||||
return 0
|
||||
|
||||
children: list[rawptr[ast.AST]] | t.CPtr = cd.children
|
||||
children: rawptr[list[rawptr[ast.AST]]] = cd.children
|
||||
if children is None:
|
||||
return 0
|
||||
|
||||
@@ -454,7 +454,7 @@ class ClassGenVTable(ClassGenBase.ClassGenBase):
|
||||
has_new: int = 0
|
||||
|
||||
# 提前用类型指针定位 entry(规避跨模块同名类 find_struct 找错)
|
||||
oop_entry: GenTypes.StructEntry | t.CPtr = self.Gen.StructGen.find_struct_by_type(struct_ty)
|
||||
oop_entry: rawptr[GenTypes.StructEntry] = self.Gen.StructGen.find_struct_by_type(struct_ty)
|
||||
|
||||
# 第一遍:检测是否有方法,标记 OOP,并注册装饰器元数据
|
||||
for ci in range(cn):
|
||||
@@ -681,13 +681,13 @@ class ClassGenVTable(ClassGenBase.ClassGenBase):
|
||||
if md_args_node is not None:
|
||||
md_ags: rawptr[ast.Arguments] = rawptr[ast.Arguments](md_args_node)
|
||||
if md_ags.args is not None:
|
||||
md_alist: list[rawptr[ast.AST]] | t.CPtr = md_ags.args
|
||||
md_alist: rawptr[list[rawptr[ast.AST]]] = md_ags.args
|
||||
if is_static_m != 0:
|
||||
md_param_count = len(md_alist)
|
||||
else:
|
||||
md_param_count = len(md_alist) - 1
|
||||
if md_ags.defaults is not None:
|
||||
md_dlist: list[rawptr[ast.AST]] | t.CPtr = md_ags.defaults
|
||||
md_dlist: rawptr[list[rawptr[ast.AST]]] = md_ags.defaults
|
||||
md_defaults = md_dlist
|
||||
md_default_count = len(md_dlist)
|
||||
|
||||
@@ -718,7 +718,7 @@ class ClassGenVTable(ClassGenBase.ClassGenBase):
|
||||
if args_node is not None:
|
||||
ags: rawptr[ast.Arguments] = rawptr[ast.Arguments](args_node)
|
||||
if ags.args is not None:
|
||||
alist: list[rawptr[ast.AST]] | t.CPtr = ags.args
|
||||
alist: rawptr[list[rawptr[ast.AST]]] = ags.args
|
||||
an: sizet = len(alist)
|
||||
start_idx: int = 0
|
||||
if is_static_m == 0:
|
||||
@@ -767,12 +767,12 @@ class ClassGenVTable(ClassGenBase.ClassGenBase):
|
||||
self.Gen.CallGenLeafKit.update_global_func_spec(full_name, func)
|
||||
|
||||
# 创建 entry 块
|
||||
entry_blk: llvmlite.BasicBlock | t.CPtr = llvmlite.create_block(pool, func, "entry")
|
||||
entry_blk: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(pool, func, "entry")
|
||||
if entry_blk is None:
|
||||
return 0
|
||||
|
||||
# 创建方法专属 builder
|
||||
func_builder: llvmlite.IRBuilder | t.CPtr = llvmlite.new_builder(pool, func)
|
||||
func_builder: rawptr[llvmlite.IRBuilder] = llvmlite.new_builder(pool, func)
|
||||
if func_builder is None:
|
||||
return 0
|
||||
llvmlite.position_at_end(func_builder, entry_blk)
|
||||
@@ -783,7 +783,7 @@ class ClassGenVTable(ClassGenBase.ClassGenBase):
|
||||
tls_m_flag_name: str = pool.alloc(128)
|
||||
if tls_m_flag_name is not None:
|
||||
viperlib.snprintf(tls_m_flag_name, 128, "__tls_init_done_%s", method_name)
|
||||
tls_m_gv: llvmlite.GlobalVariable | t.CPtr = llvmlite.create_global_int(
|
||||
tls_m_gv: rawptr[llvmlite.GlobalVariable] = llvmlite.create_global_int(
|
||||
pool, mod, tls_m_flag_name, 1, 0)
|
||||
if tls_m_gv is not None:
|
||||
i1_ty_m: rawptr[llvmlite.LLVMType] = llvmlite.Int1(pool)
|
||||
@@ -793,20 +793,20 @@ class ClassGenVTable(ClassGenBase.ClassGenBase):
|
||||
tls_m_rn: str = pool.alloc(64)
|
||||
if tls_m_rn is not None:
|
||||
viperlib.snprintf(tls_m_rn, 64, "@%s", tls_m_flag_name)
|
||||
tls_m_ref: llvmlite.Value | t.CPtr = llvmlite.SSAValue(
|
||||
tls_m_ref: rawptr[llvmlite.Value] = llvmlite.SSAValue(
|
||||
pool, tls_m_ptr_ty, tls_m_rn)
|
||||
if tls_m_ref is not None:
|
||||
tls_m_ld: llvmlite.Value | t.CPtr = llvmlite.build_load(
|
||||
tls_m_ld: rawptr[llvmlite.Value] = llvmlite.build_load(
|
||||
func_builder, i1_ty_m, tls_m_ref)
|
||||
lc_m: int = trans._label_counter
|
||||
trans._label_counter = lc_m + 1
|
||||
tls_m_buf: str = pool.alloc(64)
|
||||
if tls_m_buf is not None:
|
||||
viperlib.snprintf(tls_m_buf, 64, "tls.skip.%d", lc_m)
|
||||
tls_m_skip: llvmlite.BasicBlock | t.CPtr = llvmlite.create_block(
|
||||
tls_m_skip: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(
|
||||
pool, func, tls_m_buf)
|
||||
viperlib.snprintf(tls_m_buf, 64, "tls.cont.%d", lc_m)
|
||||
tls_m_cont: llvmlite.BasicBlock | t.CPtr = llvmlite.create_block(
|
||||
tls_m_cont: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(
|
||||
pool, func, tls_m_buf)
|
||||
if tls_m_skip is not None and tls_m_cont is not None:
|
||||
llvmlite.build_cond_br(
|
||||
@@ -816,22 +816,22 @@ class ClassGenVTable(ClassGenBase.ClassGenBase):
|
||||
case llvmlite.LLVMType.Void():
|
||||
llvmlite.build_ret_void(func_builder)
|
||||
case llvmlite.LLVMType.Int(_):
|
||||
tlm0: llvmlite.Value | t.CPtr = llvmlite.ConstInt(
|
||||
tlm0: rawptr[llvmlite.Value] = llvmlite.ConstInt(
|
||||
pool, ret_ty, 0, "0")
|
||||
if tlm0 is not None:
|
||||
llvmlite.build_ret(func_builder, tlm0)
|
||||
case llvmlite.LLVMType.Float(_):
|
||||
tlmf: llvmlite.Value | t.CPtr = llvmlite.ConstFloat(
|
||||
tlmf: rawptr[llvmlite.Value] = llvmlite.ConstFloat(
|
||||
pool, ret_ty, 0.0)
|
||||
if tlmf is not None:
|
||||
llvmlite.build_ret(func_builder, tlmf)
|
||||
case _:
|
||||
tlmn: llvmlite.Value | t.CPtr = llvmlite.ConstNull(
|
||||
tlmn: rawptr[llvmlite.Value] = llvmlite.ConstNull(
|
||||
pool, ret_ty, "null")
|
||||
if tlmn is not None:
|
||||
llvmlite.build_ret(func_builder, tlmn)
|
||||
llvmlite.position_at_end(func_builder, tls_m_cont)
|
||||
tlmo: llvmlite.Value | t.CPtr = llvmlite.ConstInt(
|
||||
tlmo: rawptr[llvmlite.Value] = llvmlite.ConstInt(
|
||||
pool, i1_ty_m, 1, "1")
|
||||
if tlmo is not None:
|
||||
llvmlite.build_store(func_builder, tlmo, tls_m_ref)
|
||||
@@ -843,7 +843,7 @@ class ClassGenVTable(ClassGenBase.ClassGenBase):
|
||||
# self 必须走 alloca:注册为 SSA 值会让 translate_name_value 多 load 一次,
|
||||
# 把 Ptr(struct_ty) 变成 struct 值 → 变参函数 ABI 不匹配崩溃。
|
||||
if is_static_m == 0:
|
||||
self_alloca: llvmlite.Value | t.CPtr = llvmlite.build_alloca(func_builder, self_ptr_ty)
|
||||
self_alloca: rawptr[llvmlite.Value] = llvmlite.build_alloca(func_builder, self_ptr_ty)
|
||||
if self_alloca is not None:
|
||||
self_var_name: str = "self"
|
||||
self_ssa_name: str = "%self"
|
||||
@@ -860,7 +860,7 @@ class ClassGenVTable(ClassGenBase.ClassGenBase):
|
||||
self.Gen.VarGen.define_var(trans.SymTab, self_var_name, self_alloca)
|
||||
# 设置 self/cls 的类型注解类名(属性访问 lookup_field 回退查找用)
|
||||
self.Gen.VarGen.set_var_annot_class_name(trans.SymTab, self_var_name, class_name)
|
||||
self_val: llvmlite.Value | t.CPtr = llvmlite.SSAValue(pool, self_ptr_ty, self_ssa_name)
|
||||
self_val: rawptr[llvmlite.Value] = llvmlite.SSAValue(pool, self_ptr_ty, self_ssa_name)
|
||||
llvmlite.build_store(func_builder, self_val, self_alloca)
|
||||
|
||||
# 为其他参数创建 alloca 并 store(与普通函数一致;
|
||||
@@ -868,7 +868,7 @@ class ClassGenVTable(ClassGenBase.ClassGenBase):
|
||||
if args_node is not None:
|
||||
ags2: rawptr[ast.Arguments] = rawptr[ast.Arguments](args_node)
|
||||
if ags2.args is not None:
|
||||
alist2: list[rawptr[ast.AST]] | t.CPtr = ags2.args
|
||||
alist2: rawptr[list[rawptr[ast.AST]]] = ags2.args
|
||||
an2: sizet = len(alist2)
|
||||
start_idx2: int = 0
|
||||
if is_static_m == 0:
|
||||
@@ -896,7 +896,7 @@ class ClassGenVTable(ClassGenBase.ClassGenBase):
|
||||
param_ty2 = llvmlite.Ptr(pool, aelem_ty2)
|
||||
case _:
|
||||
param_ty2 = resolved2
|
||||
alloca: llvmlite.Value | t.CPtr = llvmlite.build_alloca(func_builder, param_ty2)
|
||||
alloca: rawptr[llvmlite.Value] = llvmlite.build_alloca(func_builder, param_ty2)
|
||||
if alloca is not None:
|
||||
self.Gen.VarGen.define_var(trans.SymTab, arg2.arg, alloca)
|
||||
# 存储原始类型注解的类名(方法调用检测时,Ptr(i8) 回退到类名查找结构体)
|
||||
@@ -910,7 +910,7 @@ class ClassGenVTable(ClassGenBase.ClassGenBase):
|
||||
pname2: str = pool.alloc(32)
|
||||
if pname2 is not None:
|
||||
viperlib.snprintf(pname2, 32, "%%%s", arg2.arg)
|
||||
param_val: llvmlite.Value | t.CPtr = llvmlite.SSAValue(
|
||||
param_val: rawptr[llvmlite.Value] = llvmlite.SSAValue(
|
||||
pool, param_ty2, pname2)
|
||||
llvmlite.build_store(func_builder, param_val, alloca)
|
||||
|
||||
@@ -922,22 +922,22 @@ class ClassGenVTable(ClassGenBase.ClassGenBase):
|
||||
if i1_ty_sf is not None:
|
||||
i1_ptr_ty_sf: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, i1_ty_sf)
|
||||
if i1_ptr_ty_sf is not None:
|
||||
flag_ref_sf: llvmlite.Value | t.CPtr = llvmlite.SSAValue(
|
||||
flag_ref_sf: rawptr[llvmlite.Value] = llvmlite.SSAValue(
|
||||
pool, i1_ptr_ty_sf, "%__stop_iter_flag__")
|
||||
if flag_ref_sf is not None:
|
||||
trans._stop_iter_flag_ptr = flag_ref_sf
|
||||
zero_i1_sf: llvmlite.Value | t.CPtr = llvmlite.ConstInt(
|
||||
zero_i1_sf: rawptr[llvmlite.Value] = llvmlite.ConstInt(
|
||||
pool, i1_ty_sf, 0, "0")
|
||||
if zero_i1_sf is not None:
|
||||
llvmlite.build_store(func_builder, zero_i1_sf, flag_ref_sf)
|
||||
|
||||
# 保存模块级作用域状态
|
||||
old_func: rawptr[llvmlite.Function] = trans._cur_func
|
||||
old_builder: llvmlite.IRBuilder | t.CPtr = trans._cur_builder
|
||||
old_builder: rawptr[llvmlite.IRBuilder] = trans._cur_builder
|
||||
old_global_count: int = trans._global_name_count
|
||||
old_nonlocal_count: int = trans._nonlocal_name_count
|
||||
old_env_count: int = trans._closure_env_count
|
||||
old_stop_iter_flag: llvmlite.Value | t.CPtr = trans._stop_iter_flag_ptr
|
||||
old_stop_iter_flag: rawptr[llvmlite.Value] = trans._stop_iter_flag_ptr
|
||||
|
||||
trans._cur_func = func
|
||||
trans._cur_builder = func_builder
|
||||
@@ -948,7 +948,7 @@ class ClassGenVTable(ClassGenBase.ClassGenBase):
|
||||
# 否则 `global BootInfo` 未注册时 prescan 把 BootInfo 当局部创建 alloca,
|
||||
# 后续翻译 is_global_name 为真又写全局 → 局部 alloca 永不写入 → 读全 0
|
||||
# (main.vp __init__ BootInfo memmap 全 0 根因)。
|
||||
body: list[rawptr[ast.AST]] | t.CPtr = fd.children
|
||||
body: rawptr[list[rawptr[ast.AST]]] = fd.children
|
||||
if body is not None:
|
||||
bn: sizet = len(body)
|
||||
for bi in range(bn):
|
||||
@@ -1032,7 +1032,7 @@ class ClassGenVTable(ClassGenBase.ClassGenBase):
|
||||
elif fd.returns is None:
|
||||
# 无返回类型注解 → 无返回值过程方法,默认零值返回
|
||||
if ret_ty is not None:
|
||||
_m_zero_val: llvmlite.Value | t.CPtr = llvmlite.ConstZero(pool, ret_ty)
|
||||
_m_zero_val: rawptr[llvmlite.Value] = llvmlite.ConstZero(pool, ret_ty)
|
||||
if _m_zero_val is not None:
|
||||
llvmlite.build_ret(func_builder, _m_zero_val)
|
||||
else:
|
||||
@@ -1122,16 +1122,16 @@ class ClassGenVTable(ClassGenBase.ClassGenBase):
|
||||
rc_ut: int = self.Gen.CallGenLeafKit.update_global_func_spec(full_name, func)
|
||||
|
||||
# 创建 entry 块 + builder
|
||||
entry_blk: llvmlite.BasicBlock | t.CPtr = llvmlite.create_block(pool, func, "entry")
|
||||
entry_blk: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(pool, func, "entry")
|
||||
if entry_blk is None:
|
||||
return 0
|
||||
func_builder: llvmlite.IRBuilder | t.CPtr = llvmlite.new_builder(pool, func)
|
||||
func_builder: rawptr[llvmlite.IRBuilder] = llvmlite.new_builder(pool, func)
|
||||
if func_builder is None:
|
||||
return 0
|
||||
llvmlite.position_at_end(func_builder, entry_blk)
|
||||
|
||||
# 注册 self 为 SSA 值
|
||||
self_val: llvmlite.Value | t.CPtr = llvmlite.SSAValue(pool, self_ptr_ty, "%self")
|
||||
self_val: rawptr[llvmlite.Value] = llvmlite.SSAValue(pool, self_ptr_ty, "%self")
|
||||
|
||||
# 1. 零值填充: store zeroinitializer, Ptr(struct_ty)* %self
|
||||
# 空 struct({})在 LLVM 中不允许 zeroinitializer(invalid type for null constant),
|
||||
@@ -1139,13 +1139,13 @@ class ClassGenVTable(ClassGenBase.ClassGenBase):
|
||||
# @t.CVTable 类必有 vtable 指针字段(非空),不受影响。
|
||||
struct_fcount_zi: int = llvmlite.get_struct_fcount(struct_ty)
|
||||
if struct_fcount_zi > 0:
|
||||
zero: llvmlite.Value | t.CPtr = llvmlite.ConstZero(pool, struct_ty)
|
||||
zero: rawptr[llvmlite.Value] = llvmlite.ConstZero(pool, struct_ty)
|
||||
if zero is not None:
|
||||
llvmlite.build_store(func_builder, zero, self_val)
|
||||
|
||||
# 1.5 如果有虚表,store vtable 全局地址到 __vtable__ 字段(索引 0)
|
||||
# 用 find_struct_by_type 定位 entry,规避跨模块同名 find_struct 找错
|
||||
bi_entry: GenTypes.StructEntry | t.CPtr = self.Gen.StructGen.find_struct_by_type(struct_ty)
|
||||
bi_entry: rawptr[GenTypes.StructEntry] = self.Gen.StructGen.find_struct_by_type(struct_ty)
|
||||
bi_has_vt: int = 0
|
||||
if bi_entry is not None:
|
||||
bi_has_vt = bi_entry.HasVTable
|
||||
@@ -1181,11 +1181,11 @@ class ClassGenVTable(ClassGenBase.ClassGenBase):
|
||||
vt_mangled: str = self.Gen.FuncGenBase._mangle_name(trans, vt_full_name)
|
||||
|
||||
# GEP 到 __vtable__ 字段(索引 0)
|
||||
vt_slot: llvmlite.Value | t.CPtr = llvmlite.build_gep_struct(
|
||||
vt_slot: rawptr[llvmlite.Value] = llvmlite.build_gep_struct(
|
||||
func_builder, struct_ty, vt_i8_ptr_ty, self_val, 0)
|
||||
if vt_slot is not None:
|
||||
# 创建全局变量引用 Value
|
||||
vt_ref: llvmlite.Value | t.CPtr = llvmlite.new_value(pool)
|
||||
vt_ref: rawptr[llvmlite.Value] = llvmlite.new_value(pool)
|
||||
if vt_ref is not None:
|
||||
llvmlite.value_set_ty(vt_ref, vt_ptr_ty)
|
||||
llvmlite.value_set_isconst(vt_ref, 1)
|
||||
@@ -1200,7 +1200,7 @@ class ClassGenVTable(ClassGenBase.ClassGenBase):
|
||||
llvmlite.value_set_name(vt_ref, vt_ref_name)
|
||||
|
||||
# bitcast 到 i8*
|
||||
vt_as_i8: llvmlite.Value | t.CPtr = llvmlite.build_bitcast(
|
||||
vt_as_i8: rawptr[llvmlite.Value] = llvmlite.build_bitcast(
|
||||
func_builder, vt_ref, vt_i8_ptr_ty)
|
||||
if vt_as_i8 is not None:
|
||||
llvmlite.build_store(func_builder, vt_as_i8, vt_slot)
|
||||
@@ -1208,7 +1208,7 @@ class ClassGenVTable(ClassGenBase.ClassGenBase):
|
||||
# 2. 逐字段 store 默认值(用 bi_entry 直接访问,规避跨模块同名 find_struct 找错)
|
||||
if bi_entry is not None:
|
||||
for fi in range(bi_entry.FieldCount):
|
||||
fe: GenTypes.FieldEntry | t.CPtr = self.Gen.StructGen._get_field_entry(
|
||||
fe: rawptr[GenTypes.FieldEntry] = self.Gen.StructGen._get_field_entry(
|
||||
bi_entry, fi)
|
||||
if fe is None or fe.DefaultVal is None:
|
||||
continue
|
||||
@@ -1219,10 +1219,10 @@ class ClassGenVTable(ClassGenBase.ClassGenBase):
|
||||
# 推断为静态数组,此处保证 __before_init__ 填充真实字符串指针。
|
||||
if fe.Ty is not None and self.Gen.ExprGenBase.is_array_type(fe.Ty) != 0 \
|
||||
and fe.DefaultVal.kind() == ast.ASTKind.List:
|
||||
field_ptr_arr: llvmlite.Value | t.CPtr = llvmlite.build_gep_struct(
|
||||
field_ptr_arr: rawptr[llvmlite.Value] = llvmlite.build_gep_struct(
|
||||
func_builder, struct_ty, fe.Ty, self_val, fe.Index)
|
||||
if field_ptr_arr is not None:
|
||||
zero_arr_f: llvmlite.Value | t.CPtr = llvmlite.ConstZero(pool, fe.Ty)
|
||||
zero_arr_f: rawptr[llvmlite.Value] = llvmlite.ConstZero(pool, fe.Ty)
|
||||
if zero_arr_f is not None:
|
||||
llvmlite.build_store(func_builder, zero_arr_f, field_ptr_arr)
|
||||
# Mixin 静态绑定:self._xxx 只沿本类查找,跨 Mixin 方法
|
||||
@@ -1232,12 +1232,12 @@ class ClassGenVTable(ClassGenBase.ClassGenBase):
|
||||
func_builder, pool, mod, field_ptr_arr, fe.DefaultVal, trans)
|
||||
continue
|
||||
# 翻译默认值表达式
|
||||
default_val: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
|
||||
default_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
|
||||
func_builder, pool, mod, fe.DefaultVal, None, 0, trans)
|
||||
if default_val is None:
|
||||
continue
|
||||
# GEP 到字段
|
||||
field_ptr: llvmlite.Value | t.CPtr = llvmlite.build_gep_struct(
|
||||
field_ptr: rawptr[llvmlite.Value] = llvmlite.build_gep_struct(
|
||||
func_builder, struct_ty, fe.Ty, self_val, fe.Index)
|
||||
if field_ptr is None:
|
||||
continue
|
||||
|
||||
@@ -36,12 +36,12 @@ class ExprGenAttr(ExprGenBase.ExprGenBase):
|
||||
# 2. 后缀匹配 (如 "_mbuddy" 匹配 @"sha1._mbuddy")
|
||||
# ============================================================
|
||||
def find_global_in_module(self, mod: rawptr[llvmlite.LLVMModule],
|
||||
name: str) -> llvmlite.GlobalVariable | t.CPtr:
|
||||
name: str) -> rawptr[llvmlite.GlobalVariable]:
|
||||
"""在模块全局变量链表中按名称查找全局变量"""
|
||||
if mod is None or name is None:
|
||||
return None
|
||||
name_len: sizet = string.strlen(name)
|
||||
cur: llvmlite.GlobalVariable | t.CPtr = mod.GlobalHead
|
||||
cur: rawptr[llvmlite.GlobalVariable] = mod.GlobalHead
|
||||
# 第一遍: 精确匹配
|
||||
while cur is not None:
|
||||
if cur.Name is not None:
|
||||
@@ -73,7 +73,7 @@ class ExprGenAttr(ExprGenBase.ExprGenBase):
|
||||
# ============================================================
|
||||
def make_global_ref(self, pool: rawptr[memhub.MemBuddy],
|
||||
name: str,
|
||||
ty: rawptr[llvmlite.LLVMType]) -> llvmlite.Value | t.CPtr:
|
||||
ty: rawptr[llvmlite.LLVMType]) -> rawptr[llvmlite.Value]:
|
||||
"""创建全局变量引用 (类型为 ty*,名称为 @name)"""
|
||||
if name is None or ty is None:
|
||||
return None
|
||||
@@ -217,7 +217,7 @@ class ExprGenAttr(ExprGenBase.ExprGenBase):
|
||||
mod: rawptr[llvmlite.LLVMModule],
|
||||
trans: rawptr[HT.Translator],
|
||||
at: rawptr[ast.Attribute],
|
||||
ty_hint: rawptr[llvmlite.LLVMType]) -> llvmlite.Value | t.CPtr:
|
||||
ty_hint: rawptr[llvmlite.LLVMType]) -> rawptr[llvmlite.Value]:
|
||||
"""解析模块属性访问,返回全局变量引用 (用于跨模块 global 访问)"""
|
||||
if at is None or at.value is None or at.attr is None:
|
||||
return None
|
||||
@@ -256,7 +256,7 @@ class ExprGenAttr(ExprGenBase.ExprGenBase):
|
||||
# 匹配返回错误模块的全局(串扰)。目标 sha1 未知时退化裸名(后缀匹配兜底)
|
||||
gv_q: str = self.Gen.FuncGenBase._mangle_name_with_sha1(
|
||||
self._lookup_module_sha1(mod_path_w), at.attr)
|
||||
gv: llvmlite.GlobalVariable | t.CPtr = self.find_global_in_module(mod, gv_q)
|
||||
gv: rawptr[llvmlite.GlobalVariable] = self.find_global_in_module(mod, gv_q)
|
||||
# CExport 全局(定义端裸名 @_sched_ptr):mangled 名查不到时回退裸名精确
|
||||
# 查找。此前只查 mangled 名 → 找不到 → 新建 mangled external global 声明
|
||||
# (@"ef5b0ba0dc895058._sched_ptr")→ 与定义端裸名不匹配 → ld.lld
|
||||
@@ -292,7 +292,7 @@ class ExprGenAttr(ExprGenBase.ExprGenBase):
|
||||
if is_t_type_obj == 0:
|
||||
gv_name_ba = self.Gen.FuncGenBase._mangle_name_with_sha1(
|
||||
self._lookup_module_sha1(mod_path_w), at.attr)
|
||||
ext_gv: llvmlite.GlobalVariable | t.CPtr = llvmlite.new_global_variable(pool, gv_name_ba, use_ty)
|
||||
ext_gv: rawptr[llvmlite.GlobalVariable] = llvmlite.new_global_variable(pool, gv_name_ba, use_ty)
|
||||
if ext_gv is not None:
|
||||
if is_t_type_obj != 0:
|
||||
# t.CPtr 等类型对象: 创建带 null 初值的定义(linkonce_odr)
|
||||
@@ -342,11 +342,11 @@ class ExprGenAttr(ExprGenBase.ExprGenBase):
|
||||
# ptr 指针值(Ptr(Struct) 或 Ptr(Ptr(Struct)),交由 _deref_if_ptr_ptr 解层级)
|
||||
# 非 c.Deref 模式返回 None
|
||||
# ============================================================
|
||||
def _get_cderef_attr_base(self, builder: llvmlite.IRBuilder | t.CPtr,
|
||||
def _get_cderef_attr_base(self, builder: rawptr[llvmlite.IRBuilder],
|
||||
pool: rawptr[memhub.MemBuddy],
|
||||
mod: rawptr[llvmlite.LLVMModule],
|
||||
at_value: rawptr[ast.AST],
|
||||
trans: rawptr[HT.Translator] = None) -> llvmlite.Value | t.CPtr:
|
||||
trans: rawptr[HT.Translator] = None) -> rawptr[llvmlite.Value]:
|
||||
"""检测 at.value 是否为 c.Deref(ptr) 调用,返回 ptr 指针(不做 load)"""
|
||||
if at_value is None or at_value.kind() != ast.ASTKind.Call:
|
||||
return None
|
||||
@@ -363,16 +363,16 @@ class ExprGenAttr(ExprGenBase.ExprGenBase):
|
||||
return None
|
||||
if cl_cd.args is None or len(cl_cd.args) < 1:
|
||||
return None
|
||||
inner_cd: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
|
||||
inner_cd: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, cl_cd.args.get(0), None, 0, trans)
|
||||
if inner_cd is not None and self.is_ptr_type(inner_cd.Ty) != 0:
|
||||
return inner_cd
|
||||
return None
|
||||
def translate_attribute(self, builder: llvmlite.IRBuilder | t.CPtr,
|
||||
def translate_attribute(self, builder: rawptr[llvmlite.IRBuilder],
|
||||
pool: rawptr[memhub.MemBuddy],
|
||||
mod: rawptr[llvmlite.LLVMModule],
|
||||
node: rawptr[ast.AST],
|
||||
trans: rawptr[HT.Translator] = None) -> llvmlite.Value | t.CPtr:
|
||||
trans: rawptr[HT.Translator] = None) -> rawptr[llvmlite.Value]:
|
||||
"""翻译属性访问,返回加载的字段值"""
|
||||
if node is None or builder is None:
|
||||
return None
|
||||
@@ -432,7 +432,7 @@ class ExprGenAttr(ExprGenBase.ExprGenBase):
|
||||
enum_nm: rawptr[ast.Name] = rawptr[ast.Name](at.value)
|
||||
if enum_nm.id is not None:
|
||||
if self.Gen.StmtGenDecl.is_enum_class(enum_nm.id) == 1:
|
||||
member: GenTypes.EnumMember | t.CPtr = self.Gen.StmtGenDecl.lookup_enum_member(
|
||||
member: rawptr[GenTypes.EnumMember] = self.Gen.StmtGenDecl.lookup_enum_member(
|
||||
enum_nm.id, at.attr)
|
||||
if member is not None:
|
||||
base_ty: rawptr[llvmlite.LLVMType] = self.Gen.StmtGenDecl.get_enum_base_type(
|
||||
@@ -460,7 +460,7 @@ class ExprGenAttr(ExprGenBase.ExprGenBase):
|
||||
inner_at_e: rawptr[ast.Attribute] = rawptr[ast.Attribute](at.value)
|
||||
if inner_at_e.attr is not None:
|
||||
if self.Gen.StmtGenDecl.is_enum_class(inner_at_e.attr) == 1:
|
||||
member_e: GenTypes.EnumMember | t.CPtr = self.Gen.StmtGenDecl.lookup_enum_member(
|
||||
member_e: rawptr[GenTypes.EnumMember] = self.Gen.StmtGenDecl.lookup_enum_member(
|
||||
inner_at_e.attr, at.attr)
|
||||
if member_e is not None:
|
||||
base_ty_e: rawptr[llvmlite.LLVMType] = self.Gen.StmtGenDecl.get_enum_base_type(
|
||||
@@ -472,7 +472,7 @@ class ExprGenAttr(ExprGenBase.ExprGenBase):
|
||||
return llvmlite.ConstInt(pool, base_ty_e, member_e.Value, name_buf_e)
|
||||
return llvmlite.const_int32(pool, member_e.Value)
|
||||
# fast-fail: 嵌套枚举成员未找到
|
||||
dbg_ee: GenTypes.EnumEntry | t.CPtr = self.Gen.StmtGenDecl.find_enum(
|
||||
dbg_ee: rawptr[GenTypes.EnumEntry] = self.Gen.StmtGenDecl.find_enum(
|
||||
inner_at_e.attr)
|
||||
dbg_mc: int = -1
|
||||
if dbg_ee is not None:
|
||||
@@ -518,16 +518,16 @@ class ExprGenAttr(ExprGenBase.ExprGenBase):
|
||||
fd_meta_buf: str = pool.alloc(256)
|
||||
if fd_meta_buf is not None:
|
||||
viperlib.snprintf(fd_meta_buf, 256, "%s__meta__", fd_nm.id)
|
||||
fd_meta_v: llvmlite.Value | t.CPtr = self.Gen.VarGen.lookup_current(
|
||||
fd_meta_v: rawptr[llvmlite.Value] = self.Gen.VarGen.lookup_current(
|
||||
trans.SymTab, fd_meta_buf)
|
||||
if fd_meta_v is not None:
|
||||
fd_sty: rawptr[llvmlite.LLVMType] = self.Gen.StructGen.get_struct_type(
|
||||
"_str")
|
||||
if fd_sty is not None:
|
||||
fd_fe: GenTypes.FieldEntry | t.CPtr = \
|
||||
fd_fe: rawptr[GenTypes.FieldEntry] = \
|
||||
self.Gen.StructGen.lookup_field(fd_sty, at.attr)
|
||||
if fd_fe is not None and fd_fe.Ty is not None:
|
||||
fd_fp: llvmlite.Value | t.CPtr = llvmlite.build_gep_struct(
|
||||
fd_fp: rawptr[llvmlite.Value] = llvmlite.build_gep_struct(
|
||||
builder, fd_sty, fd_fe.Ty, fd_meta_v, fd_fe.Index)
|
||||
if fd_fp is not None:
|
||||
return llvmlite.build_load(builder, fd_fe.Ty, fd_fp)
|
||||
@@ -538,7 +538,7 @@ class ExprGenAttr(ExprGenBase.ExprGenBase):
|
||||
nm_ma: rawptr[ast.Name] = rawptr[ast.Name](at.value)
|
||||
if nm_ma.id is not None:
|
||||
# 先检查是否是普通变量 (优先级高于模块属性)
|
||||
ma_is_var: llvmlite.Value | t.CPtr = self.Gen.VarGen.lookup_var(
|
||||
ma_is_var: rawptr[llvmlite.Value] = self.Gen.VarGen.lookup_var(
|
||||
trans.SymTab, nm_ma.id)
|
||||
if ma_is_var is None:
|
||||
# 先检查是否是 CDefine 编译期常量 (如 ast.CONST_INT / win32base.INVALID_HANDLE_VALUE)
|
||||
@@ -643,7 +643,7 @@ class ExprGenAttr(ExprGenBase.ExprGenBase):
|
||||
# 命中跨模块全局 → 落到下方跨模块全局加载路径
|
||||
# 非 CDefine: 使用 i8* 作为类型提示 (模块级变量通常存储指针)
|
||||
i8_ptr_hint: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, llvmlite.Int8(pool))
|
||||
mod_gv_ref: llvmlite.Value | t.CPtr = self._resolve_module_attribute_global(
|
||||
mod_gv_ref: rawptr[llvmlite.Value] = self._resolve_module_attribute_global(
|
||||
pool, mod, trans, at, i8_ptr_hint)
|
||||
if mod_gv_ref is not None and mod_gv_ref.Ty is not None:
|
||||
load_ty_mod: rawptr[llvmlite.LLVMType] = mod_gv_ref.Ty.Pointee
|
||||
@@ -688,13 +688,13 @@ class ExprGenAttr(ExprGenBase.ExprGenBase):
|
||||
# 避免多模块同名全局后缀匹配串扰;sha1 未知退化裸名)
|
||||
gv_nested_q: str = self.Gen.FuncGenBase._mangle_name_with_sha1(
|
||||
self._lookup_module_sha1(qual_buf), at.attr)
|
||||
gv_nested: llvmlite.GlobalVariable | t.CPtr = self.find_global_in_module(mod, gv_nested_q)
|
||||
gv_nested: rawptr[llvmlite.GlobalVariable] = self.find_global_in_module(mod, gv_nested_q)
|
||||
# CExport 全局(定义端裸名 @idt)mangled 名查不到时回退
|
||||
# 裸名精确查找(对齐读路径 _resolve_module_attribute_global)
|
||||
if gv_nested is None:
|
||||
gv_nested = self.find_global_in_module(mod, at.attr)
|
||||
if gv_nested is not None and gv_nested.Ty is not None:
|
||||
gv_ref_nested: llvmlite.Value | t.CPtr = self.make_global_ref(
|
||||
gv_ref_nested: rawptr[llvmlite.Value] = self.make_global_ref(
|
||||
pool, gv_nested.Name, gv_nested.Ty)
|
||||
if gv_ref_nested is not None and gv_ref_nested.Ty is not None:
|
||||
load_ty_nested: rawptr[llvmlite.LLVMType] = gv_ref_nested.Ty.Pointee
|
||||
@@ -738,12 +738,12 @@ class ExprGenAttr(ExprGenBase.ExprGenBase):
|
||||
# 对于 Name 类型的 obj,直接查找 alloca(不 load 结构体);
|
||||
# nonlocal 变量(提升函数内)从 env 读共享堆值,避免 lookup_var
|
||||
# 跨函数引用外层 alloca(SSA 编号跨函数错乱崩溃)
|
||||
obj_ptr: llvmlite.Value | t.CPtr = None
|
||||
obj_ptr: rawptr[llvmlite.Value] = None
|
||||
if at.value.kind() == ast.ASTKind.Name and trans is not None:
|
||||
nm: rawptr[ast.Name] = rawptr[ast.Name](at.value)
|
||||
if nm.id is not None:
|
||||
if GenApi.is_nonlocal_name(trans, nm.id) != 0:
|
||||
raw_nl_a: llvmlite.Value | t.CPtr = self.Gen.StmtGenDecl._load_raw_var_ptr(
|
||||
raw_nl_a: rawptr[llvmlite.Value] = self.Gen.StmtGenDecl._load_raw_var_ptr(
|
||||
trans, nm.id)
|
||||
if raw_nl_a is not None:
|
||||
nl_ty_a: rawptr[llvmlite.LLVMType] = GenApi.get_nonlocal_type(
|
||||
@@ -760,7 +760,7 @@ class ExprGenAttr(ExprGenBase.ExprGenBase):
|
||||
obj_ptr = llvmlite.build_bitcast(
|
||||
builder, raw_nl_a, llvmlite.Ptr(pool, nl_ty_a))
|
||||
case _:
|
||||
nl_val_ptr_a: llvmlite.Value | t.CPtr = \
|
||||
nl_val_ptr_a: rawptr[llvmlite.Value] = \
|
||||
llvmlite.build_bitcast(
|
||||
builder, raw_nl_a, llvmlite.Ptr(pool, nl_ty_a))
|
||||
if nl_val_ptr_a is not None:
|
||||
@@ -773,7 +773,7 @@ class ExprGenAttr(ExprGenBase.ExprGenBase):
|
||||
if obj_ptr is None:
|
||||
# c.Deref(ptr).attr: 属性访问 base 取指针本身而非 load 后的结构体值
|
||||
# (如 c.Deref(p).a 语义是 (*p).a,直接对 p 做 GEP)
|
||||
cd_base_rd: llvmlite.Value | t.CPtr = self._get_cderef_attr_base(
|
||||
cd_base_rd: rawptr[llvmlite.Value] = self._get_cderef_attr_base(
|
||||
builder, pool, mod, at.value, trans)
|
||||
if cd_base_rd is not None:
|
||||
obj_ptr = cd_base_rd
|
||||
@@ -808,12 +808,12 @@ class ExprGenAttr(ExprGenBase.ExprGenBase):
|
||||
# 确保跨模块结构体的完整定义在当前模块中可用(供 getelementptr 访问字段)
|
||||
self.Gen.StructGen.ensure_struct_def_in_module(pool, mod, struct_ty)
|
||||
# 查找字段索引和类型
|
||||
field_info: GenTypes.FieldEntry | t.CPtr = self.Gen.StructGen.lookup_field(
|
||||
field_info: rawptr[GenTypes.FieldEntry] = self.Gen.StructGen.lookup_field(
|
||||
struct_ty, at.attr)
|
||||
# REnum 变体字段查找: lookup_field 失败时,尝试 REnum 别名
|
||||
# REnum 结构体字段名是 _p1/_p2/...,但源码用变体字段名访问(如 ty.Pointee)
|
||||
if field_info is None:
|
||||
renum_se: GenTypes.StructEntry | t.CPtr = self.Gen.StructGen.find_struct_by_type(
|
||||
renum_se: rawptr[GenTypes.StructEntry] = self.Gen.StructGen.find_struct_by_type(
|
||||
struct_ty)
|
||||
if renum_se is not None and renum_se.Name is not None:
|
||||
is_rn: int = self.Gen.ClassGenEnum._is_renum_class_name(renum_se.Name)
|
||||
@@ -821,10 +821,10 @@ class ExprGenAttr(ExprGenBase.ExprGenBase):
|
||||
alias_idx: int = self.Gen.ClassGenEnum._lookup_renum_field_alias(
|
||||
renum_se.Name, at.attr)
|
||||
if alias_idx >= 1:
|
||||
alias_fe: GenTypes.FieldEntry | t.CPtr = \
|
||||
alias_fe: rawptr[GenTypes.FieldEntry] = \
|
||||
self.Gen.StructGen._get_field_entry(renum_se, alias_idx)
|
||||
if alias_fe is not None and alias_fe.Ty is not None:
|
||||
alias_ptr: llvmlite.Value | t.CPtr = llvmlite.build_gep_struct(
|
||||
alias_ptr: rawptr[llvmlite.Value] = llvmlite.build_gep_struct(
|
||||
builder, struct_ty, alias_fe.Ty, obj_ptr, alias_idx)
|
||||
if alias_ptr is not None:
|
||||
# REnum 变体字段按声明类型读取(对齐 match 绑定 _lookup_renum_member_ty):槽位是 i32/i64(布局按最大字段大小),直接 load 得整数位模式,赋给 X|t.CPtr 指针变量会触发 int→ptr 禁令误报。用别名表存的成员声明类型(自引用退化为 i8*)把槽位地址 bitcast 后按声明类型 load——同宽无信息丢失,指针字段读出真正的指针值
|
||||
@@ -835,7 +835,7 @@ class ExprGenAttr(ExprGenBase.ExprGenBase):
|
||||
decl_ptr_rn: rawptr[llvmlite.LLVMType] = \
|
||||
llvmlite.Ptr(pool, decl_ty_rn)
|
||||
if decl_ptr_rn is not None:
|
||||
cast_ptr_rn: llvmlite.Value | t.CPtr = \
|
||||
cast_ptr_rn: rawptr[llvmlite.Value] = \
|
||||
llvmlite.build_bitcast(builder, alias_ptr, decl_ptr_rn)
|
||||
if cast_ptr_rn is not None:
|
||||
return llvmlite.build_load(builder, decl_ty_rn, cast_ptr_rn)
|
||||
@@ -844,7 +844,7 @@ class ExprGenAttr(ExprGenBase.ExprGenBase):
|
||||
# (字段未找到时先尝试,避免报误导性的"字段未找到"错误)
|
||||
if field_info is None and at.value is not None and trans is not None:
|
||||
prop_cls_fb: str = self.Gen.StructGen.get_class_name_by_type(pool, struct_ty)
|
||||
prop_val: llvmlite.Value | t.CPtr = self.Gen.CallGenProp._try_property_getter_attr(
|
||||
prop_val: rawptr[llvmlite.Value] = self.Gen.CallGenProp._try_property_getter_attr(
|
||||
pool, builder, mod, at, obj_ptr, trans, prop_cls_fb)
|
||||
if prop_val is not None:
|
||||
return prop_val
|
||||
@@ -856,7 +856,7 @@ class ExprGenAttr(ExprGenBase.ExprGenBase):
|
||||
if at.value.kind() == ast.ASTKind.Name and trans is not None:
|
||||
nm_fb: rawptr[ast.Name] = rawptr[ast.Name](at.value)
|
||||
if nm_fb.id is not None:
|
||||
var_entry: GenTypes.VarEntry | t.CPtr = self.Gen.VarGen.lookup_var_entry(
|
||||
var_entry: rawptr[GenTypes.VarEntry] = self.Gen.VarGen.lookup_var_entry(
|
||||
trans.SymTab, nm_fb.id)
|
||||
if var_entry is not None:
|
||||
base_class = self.Gen.VarGen.var_annot_class_name(var_entry)
|
||||
@@ -876,10 +876,10 @@ class ExprGenAttr(ExprGenBase.ExprGenBase):
|
||||
rn_alias: int = self.Gen.ClassGenEnum._lookup_renum_field_alias(
|
||||
base_class, at.attr)
|
||||
if rn_alias >= 1:
|
||||
rn_se: GenTypes.StructEntry | t.CPtr = \
|
||||
rn_se: rawptr[GenTypes.StructEntry] = \
|
||||
self.Gen.StructGen.find_struct(base_class)
|
||||
if rn_se is not None:
|
||||
rn_fe: GenTypes.FieldEntry | t.CPtr = \
|
||||
rn_fe: rawptr[GenTypes.FieldEntry] = \
|
||||
self.Gen.StructGen._get_field_entry(rn_se, rn_alias)
|
||||
if rn_fe is not None and rn_fe.Ty is not None:
|
||||
field_info = rn_fe
|
||||
@@ -887,12 +887,12 @@ class ExprGenAttr(ExprGenBase.ExprGenBase):
|
||||
# 原始 struct_ty 可能是 i8(X|t.CPtr 简化为 Ptr(i8)),
|
||||
# 需用实际结构体类型做 GEP,否则 GEP i8 失败
|
||||
if field_info is not None:
|
||||
annot_se: GenTypes.StructEntry | t.CPtr = \
|
||||
annot_se: rawptr[GenTypes.StructEntry] = \
|
||||
self.Gen.StructGen.find_struct(base_class)
|
||||
if annot_se is not None and annot_se.Ty is not None:
|
||||
annot_ptr_ty: rawptr[llvmlite.LLVMType] = \
|
||||
llvmlite.Ptr(pool, annot_se.Ty)
|
||||
casted_ptr: llvmlite.Value | t.CPtr = \
|
||||
casted_ptr: rawptr[llvmlite.Value] = \
|
||||
llvmlite.build_bitcast(builder, obj_ptr, annot_ptr_ty)
|
||||
if casted_ptr is not None:
|
||||
obj_ptr = casted_ptr
|
||||
@@ -907,21 +907,21 @@ class ExprGenAttr(ExprGenBase.ExprGenBase):
|
||||
# 联合体:bitcast obj_ptr 到 field_ty* 后 load
|
||||
if self.Gen.StructGen.is_union_by_type(struct_ty) == 1:
|
||||
field_ptr_ty: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, field_ty)
|
||||
casted: llvmlite.Value | t.CPtr = llvmlite.build_bitcast(
|
||||
casted: rawptr[llvmlite.Value] = llvmlite.build_bitcast(
|
||||
builder, obj_ptr, field_ptr_ty)
|
||||
if casted is not None:
|
||||
return llvmlite.build_load(builder, field_ty, casted)
|
||||
return None
|
||||
# 普通结构体:GEP + load
|
||||
field_idx: int = field_info.Index
|
||||
field_ptr: llvmlite.Value | t.CPtr = llvmlite.build_gep_struct(
|
||||
field_ptr: rawptr[llvmlite.Value] = llvmlite.build_gep_struct(
|
||||
builder, struct_ty, field_ty, obj_ptr, field_idx)
|
||||
if field_ptr is not None:
|
||||
# [FIX 2026-08-31] REnum 变体字段按声明类型读取(与主路径
|
||||
# 变体别名回退一致):field_info 是 _pN 槽位(i32/i64),
|
||||
# 直接 load 得整数位模式 → 赋给 X|t.CPtr 指针变量触发 int→ptr
|
||||
# 误报。bitcast 槽位地址后按声明类型 load(同宽无信息丢失)。
|
||||
rn_rd_se: GenTypes.StructEntry | t.CPtr = \
|
||||
rn_rd_se: rawptr[GenTypes.StructEntry] = \
|
||||
self.Gen.StructGen.find_struct_by_type(struct_ty)
|
||||
if rn_rd_se is not None and rn_rd_se.Name is not None \
|
||||
and self.Gen.ClassGenEnum._is_renum_class_name(rn_rd_se.Name) != 0:
|
||||
@@ -932,7 +932,7 @@ class ExprGenAttr(ExprGenBase.ExprGenBase):
|
||||
decl_ptr_rd: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(
|
||||
pool, decl_ty_rd)
|
||||
if decl_ptr_rd is not None:
|
||||
cast_ptr_rd: llvmlite.Value | t.CPtr = llvmlite.build_bitcast(
|
||||
cast_ptr_rd: rawptr[llvmlite.Value] = llvmlite.build_bitcast(
|
||||
builder, field_ptr, decl_ptr_rd)
|
||||
if cast_ptr_rd is not None:
|
||||
return llvmlite.build_load(builder, decl_ty_rd, cast_ptr_rd)
|
||||
@@ -940,7 +940,7 @@ class ExprGenAttr(ExprGenBase.ExprGenBase):
|
||||
# 用于后续下标访问: self.state[0] → GEP state 字段 → GEP 数组元素
|
||||
if self.is_array_type(field_ty) != 0:
|
||||
return field_ptr
|
||||
loaded_val: llvmlite.Value | t.CPtr = llvmlite.build_load(builder, field_ty, field_ptr)
|
||||
loaded_val: rawptr[llvmlite.Value] = llvmlite.build_load(builder, field_ty, field_ptr)
|
||||
# 联合类型字段(如 Token | t.CPtr)被编译为 i8*,
|
||||
# 若 AnnotClassName 指示了具体结构体类型,bitcast 为正确的结构体指针。
|
||||
# 注意:仅当字段类型本身是指针时才 bitcast(指针→指针);
|
||||
@@ -949,7 +949,7 @@ class ExprGenAttr(ExprGenBase.ExprGenBase):
|
||||
fc_annot: str = self.Gen.StructGen.get_field_annot_class_name(field_info)
|
||||
if loaded_val is not None and fc_annot is not None \
|
||||
and self.is_ptr_type(field_ty) != 0:
|
||||
annot_struct: GenTypes.StructEntry | t.CPtr = self.Gen.StructGen.find_struct(
|
||||
annot_struct: rawptr[GenTypes.StructEntry] = self.Gen.StructGen.find_struct(
|
||||
fc_annot)
|
||||
if annot_struct is not None and annot_struct.Ty is not None:
|
||||
# 确保目标结构体类型在当前模块有声明(可能未定义/未 opaque):
|
||||
@@ -974,7 +974,7 @@ class ExprGenAttr(ExprGenBase.ExprGenBase):
|
||||
dnm: rawptr[ast.Name] = rawptr[ast.Name](at.value)
|
||||
diag_var_nm = dnm.id
|
||||
if dnm.id is not None:
|
||||
dve: GenTypes.VarEntry | t.CPtr = self.Gen.VarGen.lookup_var_entry(
|
||||
dve: rawptr[GenTypes.VarEntry] = self.Gen.VarGen.lookup_var_entry(
|
||||
trans.SymTab, dnm.id)
|
||||
if dve is not None:
|
||||
diag_annot = self.Gen.VarGen.var_annot_class_name(dve)
|
||||
@@ -1040,7 +1040,7 @@ class ExprGenAttr(ExprGenBase.ExprGenBase):
|
||||
nm: rawptr[ast.Name] = rawptr[ast.Name](at.value)
|
||||
if nm.id is None:
|
||||
return None
|
||||
var_entry: GenTypes.VarEntry | t.CPtr = self.Gen.VarGen.lookup_var_entry(
|
||||
var_entry: rawptr[GenTypes.VarEntry] = self.Gen.VarGen.lookup_var_entry(
|
||||
trans.SymTab, nm.id)
|
||||
if var_entry is None:
|
||||
return None
|
||||
@@ -1058,16 +1058,16 @@ class ExprGenAttr(ExprGenBase.ExprGenBase):
|
||||
lfi_pc: str = None
|
||||
if trans is not None:
|
||||
lfi_pc = trans._from_imports
|
||||
fe: GenTypes.FieldEntry | t.CPtr = self.Gen.StructGen.lookup_field_by_class(
|
||||
fe: rawptr[GenTypes.FieldEntry] = self.Gen.StructGen.lookup_field_by_class(
|
||||
parent_class, at.attr, cur_sha1, at, lfi_pc)
|
||||
if fe is None:
|
||||
return None
|
||||
return self.Gen.StructGen.get_field_annot_class_name(fe)
|
||||
def get_attribute_ptr(self, builder: llvmlite.IRBuilder | t.CPtr,
|
||||
def get_attribute_ptr(self, builder: rawptr[llvmlite.IRBuilder],
|
||||
pool: rawptr[memhub.MemBuddy],
|
||||
mod: rawptr[llvmlite.LLVMModule],
|
||||
node: rawptr[ast.AST],
|
||||
trans: rawptr[HT.Translator] = None) -> llvmlite.Value | t.CPtr:
|
||||
trans: rawptr[HT.Translator] = None) -> rawptr[llvmlite.Value]:
|
||||
"""获取属性访问的字段指针(用于赋值 lhs)"""
|
||||
if node is None or builder is None:
|
||||
return None
|
||||
@@ -1078,12 +1078,12 @@ class ExprGenAttr(ExprGenBase.ExprGenBase):
|
||||
# 对于 Name 类型的 obj,直接查找 alloca(不 load 结构体);
|
||||
# nonlocal 变量(提升函数内)从 env 读共享堆值,避免 lookup_var
|
||||
# 跨函数引用外层 alloca(SSA 编号跨函数错乱崩溃)
|
||||
obj_ptr: llvmlite.Value | t.CPtr = None
|
||||
obj_ptr: rawptr[llvmlite.Value] = None
|
||||
if at.value.kind() == ast.ASTKind.Name and trans is not None:
|
||||
nm: rawptr[ast.Name] = rawptr[ast.Name](at.value)
|
||||
if nm.id is not None:
|
||||
if GenApi.is_nonlocal_name(trans, nm.id) != 0:
|
||||
raw_nl_a: llvmlite.Value | t.CPtr = self.Gen.StmtGenDecl._load_raw_var_ptr(
|
||||
raw_nl_a: rawptr[llvmlite.Value] = self.Gen.StmtGenDecl._load_raw_var_ptr(
|
||||
trans, nm.id)
|
||||
if raw_nl_a is not None:
|
||||
nl_ty_a: rawptr[llvmlite.LLVMType] = GenApi.get_nonlocal_type(
|
||||
@@ -1100,7 +1100,7 @@ class ExprGenAttr(ExprGenBase.ExprGenBase):
|
||||
obj_ptr = llvmlite.build_bitcast(
|
||||
builder, raw_nl_a, llvmlite.Ptr(pool, nl_ty_a))
|
||||
case _:
|
||||
nl_val_ptr_a: llvmlite.Value | t.CPtr = \
|
||||
nl_val_ptr_a: rawptr[llvmlite.Value] = \
|
||||
llvmlite.build_bitcast(
|
||||
builder, raw_nl_a, llvmlite.Ptr(pool, nl_ty_a))
|
||||
if nl_val_ptr_a is not None:
|
||||
@@ -1130,7 +1130,7 @@ class ExprGenAttr(ExprGenBase.ExprGenBase):
|
||||
return None
|
||||
# 使用 i8* 作为类型提示 (模块级变量通常存储指针)
|
||||
i8_ptr_w: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, llvmlite.Int8(pool))
|
||||
wma_ref: llvmlite.Value | t.CPtr = self._resolve_module_attribute_global(
|
||||
wma_ref: rawptr[llvmlite.Value] = self._resolve_module_attribute_global(
|
||||
pool, mod, trans, at, i8_ptr_w)
|
||||
if wma_ref is not None:
|
||||
return wma_ref
|
||||
@@ -1139,7 +1139,7 @@ class ExprGenAttr(ExprGenBase.ExprGenBase):
|
||||
if obj_ptr is None:
|
||||
# c.Deref(ptr).attr: 属性写入 base 取指针本身而非 load 后的结构体值
|
||||
# (如 c.Deref(p).a = val 语义是 (*p).a = val,直接对 p 做 GEP)
|
||||
cd_base_wr: llvmlite.Value | t.CPtr = self._get_cderef_attr_base(
|
||||
cd_base_wr: rawptr[llvmlite.Value] = self._get_cderef_attr_base(
|
||||
builder, pool, mod, at.value, trans)
|
||||
if cd_base_wr is not None:
|
||||
obj_ptr = cd_base_wr
|
||||
@@ -1172,7 +1172,7 @@ class ExprGenAttr(ExprGenBase.ExprGenBase):
|
||||
# 确保跨模块结构体的完整定义在当前模块中可用(供 getelementptr 访问字段)
|
||||
# 与 translate_attribute 一致,避免 opaque 类型导致 GEP 报错
|
||||
self.Gen.StructGen.ensure_struct_def_in_module(pool, mod, struct_ty)
|
||||
field_info: GenTypes.FieldEntry | t.CPtr = self.Gen.StructGen.lookup_field(
|
||||
field_info: rawptr[GenTypes.FieldEntry] = self.Gen.StructGen.lookup_field(
|
||||
struct_ty, at.attr)
|
||||
# 按需过滤: struct_ty 为 i8(简化联合类型)时,通过 AnnotClassName 按类名查找
|
||||
# 传递 SHA1 以区分跨模块同名类
|
||||
@@ -1183,7 +1183,7 @@ class ExprGenAttr(ExprGenBase.ExprGenBase):
|
||||
if at.value.kind() == ast.ASTKind.Name and trans is not None:
|
||||
nm_fb: rawptr[ast.Name] = rawptr[ast.Name](at.value)
|
||||
if nm_fb.id is not None:
|
||||
var_entry: GenTypes.VarEntry | t.CPtr = self.Gen.VarGen.lookup_var_entry(
|
||||
var_entry: rawptr[GenTypes.VarEntry] = self.Gen.VarGen.lookup_var_entry(
|
||||
trans.SymTab, nm_fb.id)
|
||||
if var_entry is not None:
|
||||
base_class = self.Gen.VarGen.var_annot_class_name(var_entry)
|
||||
@@ -1205,10 +1205,10 @@ class ExprGenAttr(ExprGenBase.ExprGenBase):
|
||||
rn_alias_g: int = self.Gen.ClassGenEnum._lookup_renum_field_alias(
|
||||
base_class, at.attr)
|
||||
if rn_alias_g >= 1:
|
||||
rn_se_g: GenTypes.StructEntry | t.CPtr = \
|
||||
rn_se_g: rawptr[GenTypes.StructEntry] = \
|
||||
self.Gen.StructGen.find_struct(base_class)
|
||||
if rn_se_g is not None:
|
||||
rn_fe_g: GenTypes.FieldEntry | t.CPtr = \
|
||||
rn_fe_g: rawptr[GenTypes.FieldEntry] = \
|
||||
self.Gen.StructGen._get_field_entry(rn_se_g, rn_alias_g)
|
||||
if rn_fe_g is not None and rn_fe_g.Ty is not None:
|
||||
field_info = rn_fe_g
|
||||
@@ -1216,12 +1216,12 @@ class ExprGenAttr(ExprGenBase.ExprGenBase):
|
||||
# 原始 struct_ty 可能是 i8(X|t.CPtr 简化为 Ptr(i8)),
|
||||
# 需用实际结构体类型做 GEP,否则 GEP i8 失败
|
||||
if field_info is not None:
|
||||
annot_se: GenTypes.StructEntry | t.CPtr = \
|
||||
annot_se: rawptr[GenTypes.StructEntry] = \
|
||||
self.Gen.StructGen.find_struct(base_class)
|
||||
if annot_se is not None and annot_se.Ty is not None:
|
||||
annot_ptr_ty: rawptr[llvmlite.LLVMType] = \
|
||||
llvmlite.Ptr(pool, annot_se.Ty)
|
||||
casted_ptr: llvmlite.Value | t.CPtr = \
|
||||
casted_ptr: rawptr[llvmlite.Value] = \
|
||||
llvmlite.build_bitcast(builder, obj_ptr, annot_ptr_ty)
|
||||
if casted_ptr is not None:
|
||||
obj_ptr = casted_ptr
|
||||
@@ -1248,7 +1248,7 @@ class ExprGenAttr(ExprGenBase.ExprGenBase):
|
||||
dnm_g: rawptr[ast.Name] = rawptr[ast.Name](at.value)
|
||||
diag_var_nm_g = dnm_g.id
|
||||
if dnm_g.id is not None:
|
||||
dve_g: GenTypes.VarEntry | t.CPtr = self.Gen.VarGen.lookup_var_entry(
|
||||
dve_g: rawptr[GenTypes.VarEntry] = self.Gen.VarGen.lookup_var_entry(
|
||||
trans.SymTab, dnm_g.id)
|
||||
if dve_g is not None:
|
||||
diag_annot_g = self.Gen.VarGen.var_annot_class_name(dve_g)
|
||||
|
||||
@@ -198,8 +198,8 @@ class ExprGenBase:
|
||||
# 数组下标语义为非负,<32 位整数索引一律 zext 到 i32。
|
||||
# 仅用于数组 GEP;指针负偏移(p[-1])不经过此路径,不受影响。
|
||||
# ============================================================
|
||||
def _zext_index_to_i32(self, builder: llvmlite.IRBuilder | t.CPtr,
|
||||
idx_val: llvmlite.Value | t.CPtr) -> llvmlite.Value | t.CPtr:
|
||||
def _zext_index_to_i32(self, builder: rawptr[llvmlite.IRBuilder],
|
||||
idx_val: rawptr[llvmlite.Value]) -> rawptr[llvmlite.Value]:
|
||||
"""将 <32 位整数下标零扩展到 i32(数组下标非负语义)"""
|
||||
if idx_val is None or idx_val.Ty is None or builder is None:
|
||||
return idx_val
|
||||
@@ -253,7 +253,7 @@ class ExprGenBase:
|
||||
nm: rawptr[ast.Name] = rawptr[ast.Name](sub.value)
|
||||
if nm.id is None:
|
||||
return 0
|
||||
alloca: llvmlite.Value | t.CPtr = self.Gen.VarGen.lookup_var(trans.SymTab, nm.id)
|
||||
alloca: rawptr[llvmlite.Value] = self.Gen.VarGen.lookup_var(trans.SymTab, nm.id)
|
||||
if alloca is None or alloca.Ty is None:
|
||||
return 0
|
||||
if self.is_ptr_type(alloca.Ty) == 0:
|
||||
@@ -289,7 +289,7 @@ class ExprGenBase:
|
||||
nm: rawptr[ast.Name] = rawptr[ast.Name](sub.value)
|
||||
if nm.id is None:
|
||||
return None
|
||||
alloca: llvmlite.Value | t.CPtr = self.Gen.VarGen.lookup_var(trans.SymTab, nm.id)
|
||||
alloca: rawptr[llvmlite.Value] = self.Gen.VarGen.lookup_var(trans.SymTab, nm.id)
|
||||
if alloca is None or alloca.Ty is None:
|
||||
return None
|
||||
if self.is_ptr_type(alloca.Ty) == 0:
|
||||
@@ -335,8 +335,8 @@ class ExprGenBase:
|
||||
# - 值类型变量 (cnt: Counter): alloca 类型是 Ptr(Struct) → 不解引用
|
||||
# - 指针类型变量 (r: Vec2|t.CPtr): alloca 类型是 Ptr(Ptr(Struct)) → load 解引用
|
||||
# ============================================================
|
||||
def _deref_if_ptr_ptr(self, builder: llvmlite.IRBuilder | t.CPtr,
|
||||
obj_ptr: llvmlite.Value | t.CPtr) -> llvmlite.Value | t.CPtr:
|
||||
def _deref_if_ptr_ptr(self, builder: rawptr[llvmlite.IRBuilder],
|
||||
obj_ptr: rawptr[llvmlite.Value]) -> rawptr[llvmlite.Value]:
|
||||
"""如果 obj_ptr 是 Ptr(Ptr(...)),load 解引用获取内层指针"""
|
||||
if obj_ptr is None or obj_ptr.Ty is None:
|
||||
return obj_ptr
|
||||
@@ -348,18 +348,18 @@ class ExprGenBase:
|
||||
if self.is_ptr_type(pointee) == 0:
|
||||
return obj_ptr
|
||||
# obj_ptr 是 Ptr(Ptr(...)),load 解引用
|
||||
loaded: llvmlite.Value | t.CPtr = llvmlite.build_load(builder, pointee, obj_ptr)
|
||||
loaded: rawptr[llvmlite.Value] = llvmlite.build_load(builder, pointee, obj_ptr)
|
||||
if loaded is None:
|
||||
return obj_ptr
|
||||
return loaded
|
||||
# ============================================================
|
||||
# 类型强制转换:整数 sext/trunc,浮点 fpext/fptrunc,int↔float si2fp/fp2si
|
||||
# ============================================================
|
||||
def coerce_to_type(self, builder: llvmlite.IRBuilder | t.CPtr,
|
||||
val: llvmlite.Value | t.CPtr,
|
||||
def coerce_to_type(self, builder: rawptr[llvmlite.IRBuilder],
|
||||
val: rawptr[llvmlite.Value],
|
||||
target_ty: rawptr[llvmlite.LLVMType],
|
||||
node: rawptr[ast.AST] = None,
|
||||
trans: rawptr[HT.Translator] = None) -> llvmlite.Value | t.CPtr:
|
||||
trans: rawptr[HT.Translator] = None) -> rawptr[llvmlite.Value]:
|
||||
"""将 val 强制转换为 target_ty
|
||||
|
||||
整数: sext(扩展)/ trunc(截断)
|
||||
@@ -463,7 +463,7 @@ class ExprGenBase:
|
||||
if self.is_ptr_type(val.Ty) == 0 and self.is_ptr_type(target_ty) != 0:
|
||||
vk_agg: int = val.Ty.kind()
|
||||
if vk_agg == llvmlite.LLVMType.Struct or vk_agg == llvmlite.LLVMType.Array:
|
||||
tmp_agg: llvmlite.Value | t.CPtr = self.Gen.VarGen._alloca_at_entry(
|
||||
tmp_agg: rawptr[llvmlite.Value] = self.Gen.VarGen._alloca_at_entry(
|
||||
builder, val.Ty)
|
||||
if tmp_agg is not None:
|
||||
llvmlite.build_store(builder, val, tmp_agg)
|
||||
@@ -474,7 +474,7 @@ class ExprGenBase:
|
||||
return tmp_agg
|
||||
case _:
|
||||
pass
|
||||
bc_agg: llvmlite.Value | t.CPtr = llvmlite.build_bitcast(
|
||||
bc_agg: rawptr[llvmlite.Value] = llvmlite.build_bitcast(
|
||||
builder, tmp_agg, target_ty)
|
||||
if bc_agg is not None:
|
||||
return bc_agg
|
||||
@@ -490,7 +490,7 @@ class ExprGenBase:
|
||||
return val
|
||||
|
||||
def _zext_or_sext_val(self, pool: rawptr[memhub.MemBuddy],
|
||||
val: llvmlite.Value | t.CPtr,
|
||||
val: rawptr[llvmlite.Value],
|
||||
node: rawptr[ast.AST] = None,
|
||||
trans: rawptr[HT.Translator] = None) -> int:
|
||||
"""统一整数拓宽方向:1=zext(无符号语义),0=sext
|
||||
@@ -510,10 +510,10 @@ class ExprGenBase:
|
||||
|
||||
# translate_ptr_arith:指针算术 ptr±int,用 getelementptr(按 pointee 元素大小缩放索引,对齐 TPC ExprGen.emit_binary_op / HandlesAugAssign.py);数组 pointee([N x ty]*)先 decay 为元素指针(GEP 0,0),避免以整个数组为步长
|
||||
def translate_ptr_arith(self, pool: rawptr[memhub.MemBuddy],
|
||||
builder: llvmlite.IRBuilder | t.CPtr,
|
||||
ptr_val: llvmlite.Value | t.CPtr,
|
||||
int_val: llvmlite.Value | t.CPtr,
|
||||
op: int) -> llvmlite.Value | t.CPtr:
|
||||
builder: rawptr[llvmlite.IRBuilder],
|
||||
ptr_val: rawptr[llvmlite.Value],
|
||||
int_val: rawptr[llvmlite.Value],
|
||||
op: int) -> rawptr[llvmlite.Value]:
|
||||
"""指针算术: ptr + int / ptr - int → GEP(按元素大小缩放索引)"""
|
||||
if ptr_val is None or int_val is None or ptr_val.Ty is None:
|
||||
return None
|
||||
@@ -528,12 +528,12 @@ class ExprGenBase:
|
||||
return None
|
||||
# 索引统一到 i64(对齐 TPC zext 到 i64)
|
||||
i64_ty: rawptr[llvmlite.LLVMType] = llvmlite.Int64(pool)
|
||||
idx: llvmlite.Value | t.CPtr = self.coerce_to_type(builder, int_val, i64_ty, None)
|
||||
idx: rawptr[llvmlite.Value] = self.coerce_to_type(builder, int_val, i64_ty, None)
|
||||
if idx is None:
|
||||
return None
|
||||
# ptr - int → 负索引(LLVM GEP 索引为加法语义)
|
||||
if op == ast.OpKind.Sub:
|
||||
neg_idx: llvmlite.Value | t.CPtr = llvmlite.build_sub(
|
||||
neg_idx: rawptr[llvmlite.Value] = llvmlite.build_sub(
|
||||
builder, llvmlite.const_int64(pool, 0), idx)
|
||||
if neg_idx is None:
|
||||
return None
|
||||
@@ -548,7 +548,7 @@ class ExprGenBase:
|
||||
return None
|
||||
if inner_ty is None:
|
||||
return None
|
||||
decayed: llvmlite.Value | t.CPtr = llvmlite.build_gep_array(
|
||||
decayed: rawptr[llvmlite.Value] = llvmlite.build_gep_array(
|
||||
builder, elem_ty, inner_ty, ptr_val, llvmlite.const_int64(pool, 0))
|
||||
if decayed is None:
|
||||
return None
|
||||
|
||||
@@ -1070,7 +1070,7 @@ class ExprGenCdef(ExprGenBase.ExprGenBase):
|
||||
# 翻译变量引用(Name 节点)→ load
|
||||
# ============================================================
|
||||
def _const_int_for_cdefine(self, pool: rawptr[memhub.MemBuddy],
|
||||
value: int64) -> llvmlite.Value | t.CPtr:
|
||||
value: int64) -> rawptr[llvmlite.Value]:
|
||||
"""CDefine 整数常量 → LLVM 常量(对齐 TPC TypeConvert 的 64 位升级)
|
||||
|
||||
规则(与 translate_constant 的 i32 溢出升级一致,但保留 0xFFFFFFFF 语义):
|
||||
|
||||
@@ -46,14 +46,14 @@ class ExprGenCls(ExprGenBase.ExprGenBase):
|
||||
# 符号依赖),未命中返回 null。幂等查重,多遍翻译安全。
|
||||
# ============================================================
|
||||
|
||||
def _extract_docstring_from_body(self, body: list[rawptr[ast.AST]] | t.CPtr) -> str:
|
||||
def _extract_docstring_from_body(self, body: rawptr[list[rawptr[ast.AST]]]) -> str:
|
||||
"""从函数/类体提取 docstring:body[0] 为 Expr(Constant str) 时返回内容"""
|
||||
if body is None or len(body) == 0:
|
||||
return None
|
||||
first: rawptr[ast.AST] = body.get(0)
|
||||
if first is None or first.kind() != ast.ASTKind.Expr:
|
||||
return None
|
||||
ex: ast.Expr | t.CPtr = (ast.Expr | t.CPtr)(first)
|
||||
ex: rawptr[ast.Expr] = rawptr[ast.Expr](first)
|
||||
if ex is None or ex.value is None or ex.value.kind() != ast.ASTKind.Constant:
|
||||
return None
|
||||
cn: rawptr[ast.Constant] = rawptr[ast.Constant](ex.value)
|
||||
@@ -111,7 +111,7 @@ class ExprGenCls(ExprGenBase.ExprGenBase):
|
||||
"""扫描模块 AST:登记模块级函数/类/方法的 docstring(幂等)"""
|
||||
if tree is None or module_sha1 is None:
|
||||
return
|
||||
ch: list[rawptr[ast.AST]] | t.CPtr = tree.children
|
||||
ch: rawptr[list[rawptr[ast.AST]]] = tree.children
|
||||
if ch is None:
|
||||
return
|
||||
cn: sizet = len(ch)
|
||||
@@ -123,7 +123,7 @@ class ExprGenCls(ExprGenBase.ExprGenBase):
|
||||
if kd == ast.ASTKind.FunctionDef:
|
||||
fd: rawptr[ast.FunctionDef] = rawptr[ast.FunctionDef](child)
|
||||
if fd is not None and fd.name is not None:
|
||||
fd_body: list[rawptr[ast.AST]] | t.CPtr = fd.children
|
||||
fd_body: rawptr[list[rawptr[ast.AST]]] = fd.children
|
||||
fdoc: str = self._extract_docstring_from_body(fd_body)
|
||||
if fdoc is not None:
|
||||
self.register_docstring(module_sha1, fd.name, fdoc)
|
||||
@@ -131,12 +131,12 @@ class ExprGenCls(ExprGenBase.ExprGenBase):
|
||||
cd: rawptr[ast.ClassDef] = rawptr[ast.ClassDef](child)
|
||||
if cd is None or cd.name is None:
|
||||
continue
|
||||
cd_body0: list[rawptr[ast.AST]] | t.CPtr = cd.children
|
||||
cd_body0: rawptr[list[rawptr[ast.AST]]] = cd.children
|
||||
cdoc: str = self._extract_docstring_from_body(cd_body0)
|
||||
if cdoc is not None:
|
||||
self.register_docstring(module_sha1, cd.name, cdoc)
|
||||
# 类方法 docstring(key="{ClassName}.{method}")
|
||||
cd_body: list[rawptr[ast.AST]] | t.CPtr = cd.children
|
||||
cd_body: rawptr[list[rawptr[ast.AST]]] = cd.children
|
||||
if cd_body is not None:
|
||||
cbn: sizet = len(cd_body)
|
||||
for mi in range(cbn):
|
||||
@@ -171,7 +171,7 @@ class ExprGenCls(ExprGenBase.ExprGenBase):
|
||||
string.strcpy(out_sym, name_id)
|
||||
return 1
|
||||
# 2. 结构体类(entry.ModuleSha1 区分跨模块预注册的类)
|
||||
se: GenTypes.StructEntry | t.CPtr = self.Gen.StructGen.find_struct(name_id)
|
||||
se: rawptr[GenTypes.StructEntry] = self.Gen.StructGen.find_struct(name_id)
|
||||
if se is not None:
|
||||
if se.ModuleSha1 is not None:
|
||||
string.strcpy(out_mod, se.ModuleSha1)
|
||||
@@ -274,7 +274,7 @@ class ExprGenCls(ExprGenBase.ExprGenBase):
|
||||
for j in range(n_items):
|
||||
string.strcat(sym2, ".")
|
||||
string.strcat(sym2, items + (n_items - 1 - j) * 128)
|
||||
se2: GenTypes.StructEntry | t.CPtr = self.Gen.StructGen.find_struct(head_id)
|
||||
se2: rawptr[GenTypes.StructEntry] = self.Gen.StructGen.find_struct(head_id)
|
||||
if se2 is not None and se2.ModuleSha1 is not None:
|
||||
string.strcpy(out_mod, se2.ModuleSha1)
|
||||
else:
|
||||
@@ -370,7 +370,7 @@ class ExprGenCls(ExprGenBase.ExprGenBase):
|
||||
nm: rawptr[ast.Name] = rawptr[ast.Name](node)
|
||||
if nm is None or nm.id is None:
|
||||
return None
|
||||
ve: GenTypes.VarEntry | t.CPtr = self.Gen.VarGen.lookup_var_entry(
|
||||
ve: rawptr[GenTypes.VarEntry] = self.Gen.VarGen.lookup_var_entry(
|
||||
trans.SymTab, nm.id)
|
||||
if ve is None:
|
||||
return None
|
||||
|
||||
@@ -27,11 +27,11 @@ class ExprGenConst(ExprGenBase.ExprGenBase):
|
||||
# ============================================================
|
||||
# 创建全局字符串常量
|
||||
# ============================================================
|
||||
def create_global_string(self, builder: llvmlite.IRBuilder | t.CPtr,
|
||||
def create_global_string(self, builder: rawptr[llvmlite.IRBuilder],
|
||||
pool: rawptr[memhub.MemBuddy],
|
||||
mod: rawptr[llvmlite.LLVMModule],
|
||||
str_val: str,
|
||||
trans: rawptr[HT.Translator]) -> llvmlite.Value | t.CPtr:
|
||||
trans: rawptr[HT.Translator]) -> rawptr[llvmlite.Value]:
|
||||
"""创建全局字符串常量并返回 i8* bitcast"""
|
||||
escaped: str = self.escape_llvm_string(pool, str_val)
|
||||
if escaped is None:
|
||||
@@ -56,7 +56,7 @@ class ExprGenConst(ExprGenBase.ExprGenBase):
|
||||
else:
|
||||
viperlib.snprintf(gv_name, 48, ".str.%d", str_idx)
|
||||
|
||||
gv: llvmlite.GlobalVariable | t.CPtr = llvmlite.new_global_variable(pool, gv_name, arr_ty)
|
||||
gv: rawptr[llvmlite.GlobalVariable] = llvmlite.new_global_variable(pool, gv_name, arr_ty)
|
||||
if gv is None:
|
||||
return None
|
||||
llvmlite.module_add_global(mod, gv)
|
||||
@@ -73,21 +73,21 @@ class ExprGenConst(ExprGenBase.ExprGenBase):
|
||||
if gv_ref_name is None:
|
||||
return None
|
||||
viperlib.snprintf(gv_ref_name, 64, "@%s", gv.Name)
|
||||
gv_ref: llvmlite.Value | t.CPtr = llvmlite.SSAValue(pool, arr_ptr_ty, gv_ref_name)
|
||||
gv_ref: rawptr[llvmlite.Value] = llvmlite.SSAValue(pool, arr_ptr_ty, gv_ref_name)
|
||||
|
||||
i8_ptr_ty: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, i8_ty)
|
||||
|
||||
bc: llvmlite.Value | t.CPtr = llvmlite.build_bitcast(builder, gv_ref, i8_ptr_ty)
|
||||
bc: rawptr[llvmlite.Value] = llvmlite.build_bitcast(builder, gv_ref, i8_ptr_ty)
|
||||
return bc
|
||||
# ============================================================
|
||||
# 翻译常量表达式
|
||||
# ============================================================
|
||||
def translate_constant(self, builder: llvmlite.IRBuilder | t.CPtr,
|
||||
def translate_constant(self, builder: rawptr[llvmlite.IRBuilder],
|
||||
pool: rawptr[memhub.MemBuddy],
|
||||
mod: rawptr[llvmlite.LLVMModule],
|
||||
node: rawptr[ast.AST],
|
||||
trans: rawptr[HT.Translator] = None,
|
||||
target_ty: rawptr[llvmlite.LLVMType] = None) -> llvmlite.Value | t.CPtr:
|
||||
target_ty: rawptr[llvmlite.LLVMType] = None) -> rawptr[llvmlite.Value]:
|
||||
"""翻译常量(int/str/bool)"""
|
||||
cn: rawptr[ast.Constant] = rawptr[ast.Constant](node)
|
||||
if cn is None:
|
||||
@@ -121,7 +121,7 @@ class ExprGenConst(ExprGenBase.ExprGenBase):
|
||||
return llvmlite.const_int32(pool, 0)
|
||||
cbuf[0] = char(cn.int_val)
|
||||
cbuf[1] = '\0'
|
||||
r_cs: llvmlite.Value | t.CPtr = self.create_global_string(builder, pool, mod, cbuf, trans)
|
||||
r_cs: rawptr[llvmlite.Value] = self.create_global_string(builder, pool, mod, cbuf, trans)
|
||||
stdlib.free(cbuf)
|
||||
return r_cs
|
||||
cv: int64 = cn.int_val
|
||||
@@ -130,7 +130,7 @@ class ExprGenConst(ExprGenBase.ExprGenBase):
|
||||
sv: str = cn.str_val
|
||||
if sv is None:
|
||||
return None
|
||||
r: llvmlite.Value | t.CPtr = self.create_global_string(builder, pool, mod, sv, trans)
|
||||
r: rawptr[llvmlite.Value] = self.create_global_string(builder, pool, mod, sv, trans)
|
||||
return r
|
||||
elif cn.const_kind == ast.CONST_BOOL:
|
||||
if cn.int_val != 0:
|
||||
@@ -144,7 +144,7 @@ class ExprGenConst(ExprGenBase.ExprGenBase):
|
||||
i8_ptr_ty: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, i8_ty)
|
||||
if i8_ptr_ty is None:
|
||||
return None
|
||||
rv_none: llvmlite.Value | t.CPtr = llvmlite.ConstNull(pool, i8_ptr_ty, "null")
|
||||
rv_none: rawptr[llvmlite.Value] = llvmlite.ConstNull(pool, i8_ptr_ty, "null")
|
||||
return rv_none
|
||||
return None
|
||||
# ============================================================
|
||||
@@ -153,7 +153,7 @@ class ExprGenConst(ExprGenBase.ExprGenBase):
|
||||
# 用于 list 字面量 [a, b, c] 的元素类型推断
|
||||
# ============================================================
|
||||
def _infer_elem_type_from_value(self, pool: rawptr[memhub.MemBuddy],
|
||||
value: llvmlite.Value | t.CPtr) -> str:
|
||||
value: rawptr[llvmlite.Value]) -> str:
|
||||
"""从 LLVM Value 的类型推断 list 元素类型名
|
||||
|
||||
fail-fast:值类型缺失/无法映射时返回 None(调用方携带节点报错终止),
|
||||
@@ -187,7 +187,7 @@ class ExprGenConst(ExprGenBase.ExprGenBase):
|
||||
#
|
||||
# 依次尝试 "pool", "_mbuddy", "mbuddy", "mb"
|
||||
# ============================================================
|
||||
def _find_pool_var(self, trans: rawptr[HT.Translator]) -> llvmlite.Value | t.CPtr:
|
||||
def _find_pool_var(self, trans: rawptr[HT.Translator]) -> rawptr[llvmlite.Value]:
|
||||
"""查找上下文中的 pool 变量,返回 alloca 或 None
|
||||
|
||||
查找顺序: pool → _mbuddy → mbuddy → mb
|
||||
@@ -198,7 +198,7 @@ class ExprGenConst(ExprGenBase.ExprGenBase):
|
||||
"""
|
||||
if trans is None:
|
||||
return None
|
||||
alloca: llvmlite.Value | t.CPtr = self.Gen.VarGen.lookup_var(trans.SymTab, "pool")
|
||||
alloca: rawptr[llvmlite.Value] = self.Gen.VarGen.lookup_var(trans.SymTab, "pool")
|
||||
if alloca is not None:
|
||||
return alloca
|
||||
alloca = self.Gen.VarGen.lookup_var(trans.SymTab, "_mbuddy")
|
||||
@@ -220,7 +220,7 @@ class ExprGenConst(ExprGenBase.ExprGenBase):
|
||||
if pool is None or trans.Module is None or trans.SymTab is None:
|
||||
return None
|
||||
# 先检查是否已注册到模块作用域(避免重复创建全局变量)
|
||||
existing: llvmlite.Value | t.CPtr = self.Gen.VarGen.lookup_module_var(trans.SymTab, "_mbuddy")
|
||||
existing: rawptr[llvmlite.Value] = self.Gen.VarGen.lookup_module_var(trans.SymTab, "_mbuddy")
|
||||
if existing is not None:
|
||||
return existing
|
||||
# 创建 i8* 类型(t.CPtr = i8*)
|
||||
@@ -229,7 +229,7 @@ class ExprGenConst(ExprGenBase.ExprGenBase):
|
||||
# 当前模块 mangled 名(@<模块sha1>._mbuddy)
|
||||
mb_name_fb: str = self.Gen.FuncGenBase._mangle_name(trans, "_mbuddy")
|
||||
# 创建 linkonce_odr 定义(可被链接器合并,自给自足保证链接通过)
|
||||
gv_ext: llvmlite.GlobalVariable | t.CPtr = llvmlite.new_global_variable(pool, mb_name_fb, i8_ptr_ty_fb)
|
||||
gv_ext: rawptr[llvmlite.GlobalVariable] = llvmlite.new_global_variable(pool, mb_name_fb, i8_ptr_ty_fb)
|
||||
if gv_ext is not None:
|
||||
gv_ext.Linkage = "linkonce_odr"
|
||||
gv_ext.Initializer = "zeroinitializer"
|
||||
@@ -243,33 +243,33 @@ class ExprGenConst(ExprGenBase.ExprGenBase):
|
||||
viperlib.snprintf(ref_name_fb, 96, "@\"%s\"", mb_name_fb)
|
||||
else:
|
||||
viperlib.snprintf(ref_name_fb, 96, "@%s", mb_name_fb)
|
||||
gv_ref_fb: llvmlite.Value | t.CPtr = llvmlite.SSAValue(pool, i8_ptr_ptr_ty_fb, ref_name_fb)
|
||||
gv_ref_fb: rawptr[llvmlite.Value] = llvmlite.SSAValue(pool, i8_ptr_ptr_ty_fb, ref_name_fb)
|
||||
# 注册到模块作用域,避免重复创建
|
||||
self.Gen.VarGen.define_module_var(trans.SymTab, "_mbuddy", gv_ref_fb)
|
||||
return gv_ref_fb
|
||||
# translate_list_literal:把 list 字面量 [a, b, c] 翻译为 list[T](pool) 构造 + append 调用序列。elem_type_name 为元素类型名(如 "str"/"int"),None 表示从元素推断。返回 list 对象指针(Ptr(list[T] struct)),失败返回 None
|
||||
def translate_list_literal(self, builder: llvmlite.IRBuilder | t.CPtr,
|
||||
def translate_list_literal(self, builder: rawptr[llvmlite.IRBuilder],
|
||||
pool: rawptr[memhub.MemBuddy],
|
||||
mod: rawptr[llvmlite.LLVMModule],
|
||||
node: rawptr[ast.AST],
|
||||
elem_type_name: str,
|
||||
trans: rawptr[HT.Translator]) -> llvmlite.Value | t.CPtr:
|
||||
trans: rawptr[HT.Translator]) -> rawptr[llvmlite.Value]:
|
||||
"""翻译 list 字面量 [a, b, c] → list[T](pool) + append 序列"""
|
||||
if node is None or trans is None:
|
||||
return None
|
||||
|
||||
list_node: ast.List | t.CPtr = (ast.List | t.CPtr)(node)
|
||||
list_node: rawptr[ast.List] = rawptr[ast.List](node)
|
||||
if list_node is None:
|
||||
return None
|
||||
|
||||
elts: list[rawptr[ast.AST]] | t.CPtr = list_node.elts
|
||||
elts: rawptr[list[rawptr[ast.AST]]] = list_node.elts
|
||||
elts_count: sizet = 0
|
||||
if elts is not None:
|
||||
elts_count = len(elts)
|
||||
|
||||
# 推断元素类型
|
||||
inferred_type_name: str = elem_type_name
|
||||
first_elem_val: llvmlite.Value | t.CPtr = None
|
||||
first_elem_val: rawptr[llvmlite.Value] = None
|
||||
if inferred_type_name is None:
|
||||
if elts_count > 0:
|
||||
first_elem_node: rawptr[ast.AST] = elts.get(0)
|
||||
@@ -288,7 +288,7 @@ class ExprGenConst(ExprGenBase.ExprGenBase):
|
||||
inferred_type_name = "str"
|
||||
|
||||
# 查找 pool 变量
|
||||
pool_alloca: llvmlite.Value | t.CPtr = self._find_pool_var(trans)
|
||||
pool_alloca: rawptr[llvmlite.Value] = self._find_pool_var(trans)
|
||||
if pool_alloca is None:
|
||||
self.Gen.TypeGenErr.fatal_error(node, "list literal requires pool variable in context")
|
||||
return None
|
||||
@@ -296,7 +296,7 @@ class ExprGenConst(ExprGenBase.ExprGenBase):
|
||||
# load pool 变量值(i8*)
|
||||
i8_ty: rawptr[llvmlite.LLVMType] = llvmlite.Int8(pool)
|
||||
i8_ptr_ty: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, i8_ty)
|
||||
pool_val: llvmlite.Value | t.CPtr = llvmlite.build_load(builder, i8_ptr_ty, pool_alloca)
|
||||
pool_val: rawptr[llvmlite.Value] = llvmlite.build_load(builder, i8_ptr_ty, pool_alloca)
|
||||
if pool_val is None:
|
||||
return None
|
||||
|
||||
@@ -309,7 +309,7 @@ class ExprGenConst(ExprGenBase.ExprGenBase):
|
||||
return None
|
||||
|
||||
# 查找 struct entry
|
||||
struct_entry: GenTypes.StructEntry | t.CPtr = self.Gen.StructGen.find_struct(spec_name)
|
||||
struct_entry: rawptr[GenTypes.StructEntry] = self.Gen.StructGen.find_struct(spec_name)
|
||||
if struct_entry is None:
|
||||
self.Gen.TypeGenErr.fatal_error(node, "list literal specialized class not registered")
|
||||
return None
|
||||
@@ -320,7 +320,7 @@ class ExprGenConst(ExprGenBase.ExprGenBase):
|
||||
# alloca 临时 list 空间
|
||||
# 确保跨模块结构体的完整定义在当前模块中可用(供 alloca 分配空间)
|
||||
self.Gen.StructGen.ensure_struct_def_in_module(pool, mod, struct_ty)
|
||||
tmp: llvmlite.Value | t.CPtr = self.Gen.VarGen._alloca_at_entry(builder, struct_ty)
|
||||
tmp: rawptr[llvmlite.Value] = self.Gen.VarGen._alloca_at_entry(builder, struct_ty)
|
||||
if tmp is None:
|
||||
return None
|
||||
|
||||
@@ -328,7 +328,7 @@ class ExprGenConst(ExprGenBase.ExprGenBase):
|
||||
# __new__ 是可选的,仅当泛型类模板定义了 __new__ 方法时才调用
|
||||
# (与 _translate_struct_ctor/_translate_generic_ctor_call 保持一致,
|
||||
# 避免为无 __new__ 的类生成过度声明)
|
||||
storage_ptr: llvmlite.Value | t.CPtr = tmp
|
||||
storage_ptr: rawptr[llvmlite.Value] = tmp
|
||||
has_new_flag: int = 0
|
||||
if struct_entry is not None:
|
||||
has_new_flag = struct_entry.HasNew
|
||||
@@ -338,7 +338,7 @@ class ExprGenConst(ExprGenBase.ExprGenBase):
|
||||
return None
|
||||
string.memset(new_args, 0, 8 * 32)
|
||||
new_args[0] = sizet(pool_val)
|
||||
new_ptr: llvmlite.Value | t.CPtr = self.Gen.CallGenCall._call_method_on_ptr(
|
||||
new_ptr: rawptr[llvmlite.Value] = self.Gen.CallGenCall._call_method_on_ptr(
|
||||
pool, builder, mod, spec_name, "__new__", tmp, new_args, 1, trans)
|
||||
if new_ptr is not None:
|
||||
storage_ptr = new_ptr
|
||||
@@ -353,7 +353,7 @@ class ExprGenConst(ExprGenBase.ExprGenBase):
|
||||
return None
|
||||
string.memset(init_args, 0, 8 * 32)
|
||||
init_args[0] = sizet(pool_val)
|
||||
elem_size_val: llvmlite.Value | t.CPtr = llvmlite.const_int64(pool, 0)
|
||||
elem_size_val: rawptr[llvmlite.Value] = llvmlite.const_int64(pool, 0)
|
||||
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)
|
||||
@@ -373,7 +373,7 @@ class ExprGenConst(ExprGenBase.ExprGenBase):
|
||||
i: sizet = 1
|
||||
while i < elts_count:
|
||||
elem_node_i: rawptr[ast.AST] = elts.get(i)
|
||||
elem_val_i: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(builder, pool, mod, elem_node_i, None, 0, trans)
|
||||
elem_val_i: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(builder, pool, mod, elem_node_i, None, 0, trans)
|
||||
if elem_val_i is not None:
|
||||
ap_args: sizet | t.CPtr = pool.alloc(8 * 32)
|
||||
if ap_args is not None:
|
||||
|
||||
@@ -35,15 +35,15 @@ class ExprGenFstr(ExprGenBase.ExprGenBase):
|
||||
# 栈缓冲。之前 f-string 未翻译导致 print/赋值拿到 NULL 指针
|
||||
# ("(null)"输出 + printf("%s", 垃圾) 崩溃 0xC0000005)。
|
||||
# ============================================================
|
||||
def translate_joined_str(self, builder: llvmlite.IRBuilder | t.CPtr,
|
||||
def translate_joined_str(self, builder: rawptr[llvmlite.IRBuilder],
|
||||
pool: rawptr[memhub.MemBuddy],
|
||||
mod: rawptr[llvmlite.LLVMModule],
|
||||
node: rawptr[ast.AST],
|
||||
trans: rawptr[HT.Translator] = None) -> llvmlite.Value | t.CPtr:
|
||||
trans: rawptr[HT.Translator] = None) -> rawptr[llvmlite.Value]:
|
||||
"""f-string → snprintf 生成 i8* 栈缓冲"""
|
||||
if node is None or builder is None or trans is None:
|
||||
return None
|
||||
js: ast.JoinedStr | t.CPtr = (ast.JoinedStr | t.CPtr)(node)
|
||||
js: rawptr[ast.JoinedStr] = rawptr[ast.JoinedStr](node)
|
||||
if js is None or js.values is None:
|
||||
return None
|
||||
|
||||
@@ -54,11 +54,11 @@ class ExprGenFstr(ExprGenBase.ExprGenBase):
|
||||
fmt_buf[0] = '\0'
|
||||
|
||||
# 运行时参数链表(Value.Next 链接,与 printf 调用一致)
|
||||
arg_head: llvmlite.Value | t.CPtr = None
|
||||
arg_tail: llvmlite.Value | t.CPtr = None
|
||||
arg_head: rawptr[llvmlite.Value] = None
|
||||
arg_tail: rawptr[llvmlite.Value] = None
|
||||
arg_count: int = 0
|
||||
|
||||
parts: list[rawptr[ast.AST]] | t.CPtr = js.values
|
||||
parts: rawptr[list[rawptr[ast.AST]]] = js.values
|
||||
pn: sizet = len(parts)
|
||||
for pi in range(pn):
|
||||
part: rawptr[ast.AST] = parts.get(pi)
|
||||
@@ -71,10 +71,10 @@ class ExprGenFstr(ExprGenBase.ExprGenBase):
|
||||
continue
|
||||
if part.kind() != ast.ASTKind.FormattedValue:
|
||||
continue
|
||||
fv: ast.FormattedValue | t.CPtr = (ast.FormattedValue | t.CPtr)(part)
|
||||
fv: rawptr[ast.FormattedValue] = rawptr[ast.FormattedValue](part)
|
||||
if fv.value is None:
|
||||
continue
|
||||
val: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
|
||||
val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, fv.value, None, 0, trans)
|
||||
if val is None:
|
||||
# fail-fast:f-string 格式化值翻译失败必须终止编译,绝不在
|
||||
@@ -94,7 +94,7 @@ class ExprGenFstr(ExprGenBase.ExprGenBase):
|
||||
if string.strlen(fmt_buf) + string.strlen(c_fmt) < FSTR_BUF_SIZE - 1:
|
||||
string.strcat(fmt_buf, c_fmt)
|
||||
# 转换参数类型(i8/i16→i32、bool→i32、f32→f64)
|
||||
cast_val: llvmlite.Value | t.CPtr = self._fstr_cast_value(
|
||||
cast_val: rawptr[llvmlite.Value] = self._fstr_cast_value(
|
||||
builder, pool, val, c_fmt, fv.value, trans)
|
||||
if cast_val is None:
|
||||
cast_val = val
|
||||
@@ -107,25 +107,25 @@ class ExprGenFstr(ExprGenBase.ExprGenBase):
|
||||
arg_count += 1
|
||||
|
||||
return self._fstr_finalize(builder, pool, mod, fmt_buf, arg_head, arg_tail, arg_count, trans)
|
||||
def translate_formatted_value(self, builder: llvmlite.IRBuilder | t.CPtr,
|
||||
def translate_formatted_value(self, builder: rawptr[llvmlite.IRBuilder],
|
||||
pool: rawptr[memhub.MemBuddy],
|
||||
mod: rawptr[llvmlite.LLVMModule],
|
||||
node: rawptr[ast.AST],
|
||||
trans: rawptr[HT.Translator] = None) -> llvmlite.Value | t.CPtr:
|
||||
trans: rawptr[HT.Translator] = None) -> rawptr[llvmlite.Value]:
|
||||
"""翻译裸 FormattedValue(f"{expr:spec}" 无字面量时解析器返回 FormattedValue 而非 JoinedStr)"""
|
||||
if node is None or builder is None or trans is None:
|
||||
return None
|
||||
fv: ast.FormattedValue | t.CPtr = (ast.FormattedValue | t.CPtr)(node)
|
||||
fv: rawptr[ast.FormattedValue] = rawptr[ast.FormattedValue](node)
|
||||
if fv is None or fv.value is None:
|
||||
return None
|
||||
fmt_buf: str = pool.alloc(FSTR_BUF_SIZE)
|
||||
if fmt_buf is None:
|
||||
return None
|
||||
fmt_buf[0] = '\0'
|
||||
arg_head: llvmlite.Value | t.CPtr = None
|
||||
arg_tail: llvmlite.Value | t.CPtr = None
|
||||
arg_head: rawptr[llvmlite.Value] = None
|
||||
arg_tail: rawptr[llvmlite.Value] = None
|
||||
arg_count: int = 0
|
||||
val: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
|
||||
val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, fv.value, None, 0, trans)
|
||||
if val is None:
|
||||
# fail-fast:裸 FormattedValue 翻译失败必须终止编译,绝不在
|
||||
@@ -142,7 +142,7 @@ class ExprGenFstr(ExprGenBase.ExprGenBase):
|
||||
self.Gen.TypeGenErr.fatal_error(fv.value, "f-string 格式无法推断(值类型缺失)", "TypeError")
|
||||
if string.strlen(fmt_buf) + string.strlen(c_fmt) < FSTR_BUF_SIZE - 1:
|
||||
string.strcat(fmt_buf, c_fmt)
|
||||
cast_val: llvmlite.Value | t.CPtr = self._fstr_cast_value(
|
||||
cast_val: rawptr[llvmlite.Value] = self._fstr_cast_value(
|
||||
builder, pool, val, c_fmt, fv.value, trans)
|
||||
if cast_val is None:
|
||||
cast_val = val
|
||||
@@ -151,14 +151,14 @@ class ExprGenFstr(ExprGenBase.ExprGenBase):
|
||||
arg_tail = cast_val
|
||||
arg_count = 1
|
||||
return self._fstr_finalize(builder, pool, mod, fmt_buf, arg_head, arg_tail, arg_count, trans)
|
||||
def _fstr_finalize(self, builder: llvmlite.IRBuilder | t.CPtr,
|
||||
def _fstr_finalize(self, builder: rawptr[llvmlite.IRBuilder],
|
||||
pool: rawptr[memhub.MemBuddy],
|
||||
mod: rawptr[llvmlite.LLVMModule],
|
||||
fmt_buf: str,
|
||||
arg_head: llvmlite.Value | t.CPtr,
|
||||
arg_tail: llvmlite.Value | t.CPtr,
|
||||
arg_head: rawptr[llvmlite.Value],
|
||||
arg_tail: rawptr[llvmlite.Value],
|
||||
arg_count: int,
|
||||
trans: rawptr[HT.Translator]) -> llvmlite.Value | t.CPtr:
|
||||
trans: rawptr[HT.Translator]) -> rawptr[llvmlite.Value]:
|
||||
"""f-string 尾部:全局格式串 + 固定栈缓冲 + snprintf,返回 i8*"""
|
||||
i32_ty: rawptr[llvmlite.LLVMType] = llvmlite.Int32(pool)
|
||||
i8_ty: rawptr[llvmlite.LLVMType] = llvmlite.Int8(pool)
|
||||
@@ -166,22 +166,22 @@ class ExprGenFstr(ExprGenBase.ExprGenBase):
|
||||
# 空 f-string(f"")→ 空字符串常量
|
||||
return self.Gen.ExprGenConst.create_global_string(builder, pool, mod, "", trans)
|
||||
# 格式串 → 全局字符串常量(i8*)
|
||||
fmt_ptr: llvmlite.Value | t.CPtr = self.Gen.ExprGenConst.create_global_string(
|
||||
fmt_ptr: rawptr[llvmlite.Value] = self.Gen.ExprGenConst.create_global_string(
|
||||
builder, pool, mod, fmt_buf, trans)
|
||||
if fmt_ptr is None:
|
||||
return None
|
||||
# 固定栈缓冲 [FSTR_BUF_SIZE x i8],GEP(0,0) 取 i8*
|
||||
buf_ty: rawptr[llvmlite.LLVMType] = llvmlite.Array(pool, i8_ty, FSTR_BUF_SIZE)
|
||||
buf_alloca: llvmlite.Value | t.CPtr = self.Gen.VarGen._alloca_at_entry(builder, buf_ty)
|
||||
buf_alloca: rawptr[llvmlite.Value] = self.Gen.VarGen._alloca_at_entry(builder, buf_ty)
|
||||
if buf_alloca is None:
|
||||
return None
|
||||
zero_i32: llvmlite.Value | t.CPtr = llvmlite.const_int32(pool, 0)
|
||||
buf_ptr: llvmlite.Value | t.CPtr = llvmlite.build_gep_array(
|
||||
zero_i32: rawptr[llvmlite.Value] = llvmlite.const_int32(pool, 0)
|
||||
buf_ptr: rawptr[llvmlite.Value] = llvmlite.build_gep_array(
|
||||
builder, buf_ty, i8_ty, buf_alloca, zero_i32)
|
||||
if buf_ptr is None:
|
||||
return None
|
||||
# snprintf(buf, FSTR_BUF_SIZE, fmt, args...)
|
||||
size_val: llvmlite.Value | t.CPtr = llvmlite.const_int64(pool, FSTR_BUF_SIZE)
|
||||
size_val: rawptr[llvmlite.Value] = llvmlite.const_int64(pool, FSTR_BUF_SIZE)
|
||||
buf_ptr.Next = size_val
|
||||
size_val.Next = fmt_ptr
|
||||
fmt_ptr.Next = arg_head
|
||||
@@ -225,7 +225,7 @@ class ExprGenFstr(ExprGenBase.ExprGenBase):
|
||||
string.strcpy(fmt_buf + cur_len, s)
|
||||
def _fstr_parse_format_spec(self, pool: rawptr[memhub.MemBuddy],
|
||||
spec_node: rawptr[ast.AST],
|
||||
val: llvmlite.Value | t.CPtr,
|
||||
val: rawptr[llvmlite.Value],
|
||||
arg_node: rawptr[ast.AST]) -> str:
|
||||
"""Python format_spec → C printf 格式串(pool 分配),无法解析返回 None"""
|
||||
if spec_node is None or pool is None or val is None:
|
||||
@@ -237,7 +237,7 @@ class ExprGenFstr(ExprGenBase.ExprGenBase):
|
||||
spec[0] = '\0'
|
||||
sk: int = spec_node.kind()
|
||||
if sk == ast.ASTKind.JoinedStr:
|
||||
jss: ast.JoinedStr | t.CPtr = (ast.JoinedStr | t.CPtr)(spec_node)
|
||||
jss: rawptr[ast.JoinedStr] = rawptr[ast.JoinedStr](spec_node)
|
||||
if jss.values is None:
|
||||
return None
|
||||
vn: sizet = len(jss.values)
|
||||
@@ -407,7 +407,7 @@ class ExprGenFstr(ExprGenBase.ExprGenBase):
|
||||
return None
|
||||
return out
|
||||
def _fstr_infer_c_fmt(self, pool: rawptr[memhub.MemBuddy],
|
||||
val: llvmlite.Value | t.CPtr,
|
||||
val: rawptr[llvmlite.Value],
|
||||
arg_node: rawptr[ast.AST],
|
||||
trans: rawptr[HT.Translator]) -> str:
|
||||
"""无 format_spec 时按值类型推断 C printf 格式(对齐 TPC 无 spec 分支,带 % 前缀)"""
|
||||
@@ -442,12 +442,12 @@ class ExprGenFstr(ExprGenBase.ExprGenBase):
|
||||
# fail-fast:值类型缺失(非整数/浮点/指针),无法推断 C 格式,立即终止编译
|
||||
self.Gen.TypeGenErr.fatal_error(arg_node, "f-string 格式无法推断(值类型缺失)", "TypeError")
|
||||
return None
|
||||
def _fstr_cast_value(self, builder: llvmlite.IRBuilder | t.CPtr,
|
||||
def _fstr_cast_value(self, builder: rawptr[llvmlite.IRBuilder],
|
||||
pool: rawptr[memhub.MemBuddy],
|
||||
val: llvmlite.Value | t.CPtr,
|
||||
val: rawptr[llvmlite.Value],
|
||||
c_fmt: str,
|
||||
arg_node: rawptr[ast.AST],
|
||||
trans: rawptr[HT.Translator]) -> llvmlite.Value | t.CPtr:
|
||||
trans: rawptr[HT.Translator]) -> rawptr[llvmlite.Value]:
|
||||
"""按 C 格式转换值类型(i8/i16→i32、bool→i32、f32→f64)"""
|
||||
if val is None or c_fmt is None:
|
||||
return None
|
||||
|
||||
@@ -60,14 +60,14 @@ class ExprGenMixin(ExprGenBase.ExprGenBase):
|
||||
# ============================================================
|
||||
# 翻译值表达式(RHS 分派)— 模块级版本
|
||||
# ============================================================
|
||||
def translate_value(self, builder: llvmlite.IRBuilder | t.CPtr,
|
||||
def translate_value(self, builder: rawptr[llvmlite.IRBuilder],
|
||||
pool: rawptr[memhub.MemBuddy],
|
||||
mod: rawptr[llvmlite.LLVMModule],
|
||||
node: rawptr[ast.AST],
|
||||
funcs_ptr: t.CPtr = None,
|
||||
func_count: int = 0,
|
||||
trans: rawptr[HT.Translator] = None,
|
||||
target_ty: rawptr[llvmlite.LLVMType] = None) -> llvmlite.Value | t.CPtr:
|
||||
target_ty: rawptr[llvmlite.LLVMType] = None) -> rawptr[llvmlite.Value]:
|
||||
"""翻译值表达式为 LLVM Value(深度守卫包装器,原逻辑见 _translate_value_impl)
|
||||
|
||||
target_ty: 目标类型上下文(如调用形参类型/赋值目标类型),用于单引号
|
||||
@@ -78,26 +78,26 @@ class ExprGenMixin(ExprGenBase.ExprGenBase):
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
node, "表达式翻译嵌套过深(疑似 AST 自引用环或翻译 bug)", "RecursionError")
|
||||
trans.TranslateDepth += 1
|
||||
rv: llvmlite.Value | t.CPtr = self._translate_value_impl(
|
||||
rv: rawptr[llvmlite.Value] = self._translate_value_impl(
|
||||
builder, pool, mod, node, funcs_ptr, func_count, trans, target_ty)
|
||||
if trans is not None:
|
||||
trans.TranslateDepth -= 1
|
||||
return rv
|
||||
|
||||
def _translate_value_impl(self, builder: llvmlite.IRBuilder | t.CPtr,
|
||||
def _translate_value_impl(self, builder: rawptr[llvmlite.IRBuilder],
|
||||
pool: rawptr[memhub.MemBuddy],
|
||||
mod: rawptr[llvmlite.LLVMModule],
|
||||
node: rawptr[ast.AST],
|
||||
funcs_ptr: t.CPtr = None,
|
||||
func_count: int = 0,
|
||||
trans: rawptr[HT.Translator] = None,
|
||||
target_ty: rawptr[llvmlite.LLVMType] = None) -> llvmlite.Value | t.CPtr:
|
||||
target_ty: rawptr[llvmlite.LLVMType] = None) -> rawptr[llvmlite.Value]:
|
||||
"""翻译值表达式为 LLVM Value"""
|
||||
if node is None:
|
||||
return None
|
||||
k: int = node.kind()
|
||||
if k == ast.ASTKind.Constant:
|
||||
rv: llvmlite.Value | t.CPtr = self.Gen.ExprGenConst.translate_constant(builder, pool, mod, node, trans, target_ty)
|
||||
rv: rawptr[llvmlite.Value] = self.Gen.ExprGenConst.translate_constant(builder, pool, mod, node, trans, target_ty)
|
||||
return rv
|
||||
elif k == ast.ASTKind.Name:
|
||||
return self.Gen.ExprGenName.translate_name_value(builder, pool, node, trans)
|
||||
@@ -137,7 +137,7 @@ class ExprGenMixin(ExprGenBase.ExprGenBase):
|
||||
# 返回子协程 ret 值(i32)。顶层 await(AnnAssign/Assign 的 value 直接
|
||||
# 是 Await)由 AsyncGen 段翻译特判处理,本分支覆盖表达式上下文中的
|
||||
# await(M1 覆盖有限场景,详见 AsyncGenMixin._emit_await)。
|
||||
aw: ast.Await | t.CPtr = (ast.Await | t.CPtr)(node)
|
||||
aw: rawptr[ast.Await] = rawptr[ast.Await](node)
|
||||
if aw is not None and aw.value is not None and aw.value.kind() == ast.ASTKind.Call:
|
||||
aw_cl: rawptr[ast.Call] = rawptr[ast.Call](aw.value)
|
||||
if aw_cl.func is not None and aw_cl.func.kind() == ast.ASTKind.Name:
|
||||
@@ -152,7 +152,7 @@ class ExprGenMixin(ExprGenBase.ExprGenBase):
|
||||
# '*' 按 Python *args 解包语义归类为 Starred,但 Viper 未实现解包,
|
||||
# 全代码库无调用点使用;按 C 语义视为单目解引用(*ptr → load pointee,
|
||||
# 对齐 UnaryOp(Deref))。构造 Deref UnaryOp 复用既有翻译/错误路径。
|
||||
st: ast.Starred | t.CPtr = (ast.Starred | t.CPtr)(node)
|
||||
st: rawptr[ast.Starred] = rawptr[ast.Starred](node)
|
||||
if st is None or st.value is None:
|
||||
return None
|
||||
deref_node: rawptr[ast.AST] = ast.UnaryOp(pool, ast.OpKind.Deref, st.value)
|
||||
|
||||
@@ -50,10 +50,10 @@ class ExprGenName(ExprGenBase.ExprGenBase):
|
||||
buf_c[mbl_c] = '\0'
|
||||
return buf_c
|
||||
|
||||
def translate_name_value(self, builder: llvmlite.IRBuilder | t.CPtr,
|
||||
def translate_name_value(self, builder: rawptr[llvmlite.IRBuilder],
|
||||
pool: rawptr[memhub.MemBuddy],
|
||||
node: rawptr[ast.AST],
|
||||
trans: rawptr[HT.Translator] = None) -> llvmlite.Value | t.CPtr:
|
||||
trans: rawptr[HT.Translator] = None) -> rawptr[llvmlite.Value]:
|
||||
"""翻译变量引用(Name 节点)→ load"""
|
||||
# mod 必须取自 trans.Module:函数签名无 mod 参数,若用裸名 mod 会被
|
||||
# 解析为 None → create_global_string 的 module_add_global(None, gv) 被
|
||||
@@ -128,10 +128,10 @@ class ExprGenName(ExprGenBase.ExprGenBase):
|
||||
fi_mod_cut = fi_mod_raw
|
||||
fi_gv_q: str = self.Gen.FuncGenBase._mangle_name_with_sha1(
|
||||
StubMergerStore.LookupSha1ByModName(fi_mod_cut), nm_id)
|
||||
fi_gv: llvmlite.GlobalVariable | t.CPtr = self.Gen.ExprGenAttr.find_global_in_module(
|
||||
fi_gv: rawptr[llvmlite.GlobalVariable] = self.Gen.ExprGenAttr.find_global_in_module(
|
||||
trans.Module, fi_gv_q)
|
||||
if fi_gv is not None and fi_gv.Ty is not None:
|
||||
fi_ref: llvmlite.Value | t.CPtr = self.Gen.ExprGenAttr.make_global_ref(
|
||||
fi_ref: rawptr[llvmlite.Value] = self.Gen.ExprGenAttr.make_global_ref(
|
||||
pool, fi_gv.Name, fi_gv.Ty)
|
||||
if fi_ref is not None and fi_ref.Ty is not None:
|
||||
fi_pty: rawptr[llvmlite.LLVMType] = fi_ref.Ty.Pointee
|
||||
@@ -147,7 +147,7 @@ class ExprGenName(ExprGenBase.ExprGenBase):
|
||||
# global 变量:从模块作用域查找(global 声明优先级最高)
|
||||
if trans is not None:
|
||||
if GenApi.is_global_name(trans, nm_id) != 0:
|
||||
mod_alloca: llvmlite.Value | t.CPtr = self.Gen.VarGen.lookup_module_var(
|
||||
mod_alloca: rawptr[llvmlite.Value] = self.Gen.VarGen.lookup_module_var(
|
||||
trans.SymTab, nm_id)
|
||||
if mod_alloca is not None:
|
||||
load_ty: rawptr[llvmlite.LLVMType] = None
|
||||
@@ -184,7 +184,7 @@ class ExprGenName(ExprGenBase.ExprGenBase):
|
||||
# 局部变量查找(必须先于模块别名检查)
|
||||
# 否则与模块同名的局部变量(如 `import t, c` 后的局部变量 c)会被误判为模块别名,
|
||||
# 导致 SymTab 已注册的局部变量查找不到(rhs_val is None bug 根因)
|
||||
alloca: llvmlite.Value | t.CPtr = self.Gen.VarGen.lookup_var(trans.SymTab, nm_id)
|
||||
alloca: rawptr[llvmlite.Value] = self.Gen.VarGen.lookup_var(trans.SymTab, nm_id)
|
||||
if alloca is not None:
|
||||
load_ty: rawptr[llvmlite.LLVMType] = None
|
||||
if alloca.Ty is not None:
|
||||
@@ -237,7 +237,7 @@ class ExprGenName(ExprGenBase.ExprGenBase):
|
||||
# fail-fast:函数返回类型缺失,无法构造函数指针(暴露上游根因)
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
node, f"函数 '{nm_id}' 返回类型缺失,无法构造函数指针", "TypeError")
|
||||
fn_pp: llvmlite.Param | t.CPtr = llvmlite.function_get_param_head(fn_ref)
|
||||
fn_pp: rawptr[llvmlite.Param] = llvmlite.function_get_param_head(fn_ref)
|
||||
fn_first_node: rawptr[llvmlite.Function] = None
|
||||
fn_prev_node: rawptr[llvmlite.Function] = None
|
||||
fn_pcount: int = 0
|
||||
@@ -257,7 +257,7 @@ class ExprGenName(ExprGenBase.ExprGenBase):
|
||||
if fn_ty is None:
|
||||
return None
|
||||
# 构造函数指针 Value(new_value 包装,避免触碰 Function.Next)
|
||||
fn_ref_v: llvmlite.Value | t.CPtr = llvmlite.new_value(pool)
|
||||
fn_ref_v: rawptr[llvmlite.Value] = llvmlite.new_value(pool)
|
||||
if fn_ref_v is None:
|
||||
return None
|
||||
llvmlite.value_set_ty(fn_ref_v, llvmlite.Ptr(pool, fn_ty))
|
||||
@@ -320,9 +320,9 @@ class ExprGenName(ExprGenBase.ExprGenBase):
|
||||
fi_mod_cut2 = fi_mod
|
||||
gv_fi_q: str = self.Gen.FuncGenBase._mangle_name_with_sha1(
|
||||
StubMergerStore.LookupSha1ByModName(fi_mod_cut2), fi_gname)
|
||||
gv_fi: llvmlite.GlobalVariable | t.CPtr = self.Gen.ExprGenAttr.find_global_in_module(
|
||||
gv_fi: rawptr[llvmlite.GlobalVariable] = self.Gen.ExprGenAttr.find_global_in_module(
|
||||
trans.Module, gv_fi_q)
|
||||
ref_fi: llvmlite.Value | t.CPtr = None
|
||||
ref_fi: rawptr[llvmlite.Value] = None
|
||||
if gv_fi is not None and gv_fi.Ty is not None:
|
||||
ref_fi = self.Gen.ExprGenAttr.make_global_ref(pool, gv_fi.Name, gv_fi.Ty)
|
||||
else:
|
||||
@@ -362,11 +362,11 @@ class ExprGenName(ExprGenBase.ExprGenBase):
|
||||
# __data__(0) __count__(8) __capacity__(16) __pool__(24) __elem_size__(32) __iter_index__(40)
|
||||
# 返回元素地址 (i8*),调用方根据元素类型 load 正确的值
|
||||
# ============================================================
|
||||
def list_getitem_inline(self, builder: llvmlite.IRBuilder | t.CPtr,
|
||||
def list_getitem_inline(self, builder: rawptr[llvmlite.IRBuilder],
|
||||
pool: rawptr[memhub.MemBuddy],
|
||||
lm_obj: llvmlite.Value | t.CPtr,
|
||||
idx_val: llvmlite.Value | t.CPtr,
|
||||
node: rawptr[ast.AST] = None) -> llvmlite.Value | t.CPtr:
|
||||
lm_obj: rawptr[llvmlite.Value],
|
||||
idx_val: rawptr[llvmlite.Value],
|
||||
node: rawptr[ast.AST] = None) -> rawptr[llvmlite.Value]:
|
||||
"""内联生成 list __getitem__ 逻辑,返回元素地址 (i8*)"""
|
||||
if builder is None or pool is None or lm_obj is None or idx_val is None:
|
||||
return None
|
||||
@@ -374,23 +374,23 @@ class ExprGenName(ExprGenBase.ExprGenBase):
|
||||
i8_ty: rawptr[llvmlite.LLVMType] = llvmlite.Int8(pool)
|
||||
i8_ptr_ty: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, i8_ty)
|
||||
# 加载 __data__ (偏移 0, index 0)
|
||||
g_idx0: llvmlite.Value | t.CPtr = llvmlite.const_int64(pool, 0)
|
||||
g_dpp: llvmlite.Value | t.CPtr = llvmlite.build_gep(builder, i64_ty, lm_obj, g_idx0)
|
||||
g_idx0: rawptr[llvmlite.Value] = llvmlite.const_int64(pool, 0)
|
||||
g_dpp: rawptr[llvmlite.Value] = llvmlite.build_gep(builder, i64_ty, lm_obj, g_idx0)
|
||||
if g_dpp is None:
|
||||
return None
|
||||
g_data: llvmlite.Value | t.CPtr = llvmlite.build_load(builder, i8_ptr_ty, g_dpp)
|
||||
g_data: rawptr[llvmlite.Value] = llvmlite.build_load(builder, i8_ptr_ty, g_dpp)
|
||||
# 加载 __elem_size__ (偏移 32, index 4)
|
||||
g_idx4: llvmlite.Value | t.CPtr = llvmlite.const_int64(pool, 4)
|
||||
g_epp: llvmlite.Value | t.CPtr = llvmlite.build_gep(builder, i64_ty, lm_obj, g_idx4)
|
||||
g_idx4: rawptr[llvmlite.Value] = llvmlite.const_int64(pool, 4)
|
||||
g_epp: rawptr[llvmlite.Value] = llvmlite.build_gep(builder, i64_ty, lm_obj, g_idx4)
|
||||
if g_epp is None:
|
||||
return None
|
||||
g_esize: llvmlite.Value | t.CPtr = llvmlite.build_load(builder, i64_ty, g_epp)
|
||||
g_esize: rawptr[llvmlite.Value] = llvmlite.build_load(builder, i64_ty, g_epp)
|
||||
if g_data is None or g_esize is None:
|
||||
return None
|
||||
g_idx_i64: llvmlite.Value | t.CPtr = self.coerce_to_type(builder, idx_val, i64_ty, node)
|
||||
g_idx_i64: rawptr[llvmlite.Value] = self.coerce_to_type(builder, idx_val, i64_ty, node)
|
||||
if g_idx_i64 is None:
|
||||
return None
|
||||
g_offset: llvmlite.Value | t.CPtr = llvmlite.build_mul(builder, g_idx_i64, g_esize)
|
||||
g_offset: rawptr[llvmlite.Value] = llvmlite.build_mul(builder, g_idx_i64, g_esize)
|
||||
if g_offset is None:
|
||||
return None
|
||||
# 返回元素地址 (i8*),不 load
|
||||
@@ -517,7 +517,7 @@ class ExprGenName(ExprGenBase.ExprGenBase):
|
||||
if seg_buf_e is not None:
|
||||
string.strncpy(seg_buf_e, cur_e + a_e, seg_len_e)
|
||||
seg_buf_e[seg_len_e] = '\0'
|
||||
s_entry_e: GenTypes.StructEntry | t.CPtr = \
|
||||
s_entry_e: rawptr[GenTypes.StructEntry] = \
|
||||
self.Gen.StructGen.find_struct(seg_buf_e)
|
||||
if s_entry_e is not None and s_entry_e.Ty is not None:
|
||||
return llvmlite.Ptr(pool, s_entry_e.Ty)
|
||||
@@ -531,11 +531,11 @@ class ExprGenName(ExprGenBase.ExprGenBase):
|
||||
#
|
||||
# 直接存储 rhs_val 到元素地址 (coerce 为 i8* 后 store)
|
||||
# ============================================================
|
||||
def list_setitem_inline(self, builder: llvmlite.IRBuilder | t.CPtr,
|
||||
def list_setitem_inline(self, builder: rawptr[llvmlite.IRBuilder],
|
||||
pool: rawptr[memhub.MemBuddy],
|
||||
lm_obj: llvmlite.Value | t.CPtr,
|
||||
idx_val: llvmlite.Value | t.CPtr,
|
||||
rhs_val: llvmlite.Value | t.CPtr,
|
||||
lm_obj: rawptr[llvmlite.Value],
|
||||
idx_val: rawptr[llvmlite.Value],
|
||||
rhs_val: rawptr[llvmlite.Value],
|
||||
node: rawptr[ast.AST] = None) -> int:
|
||||
"""内联生成 list __setitem__ 逻辑,返回 0"""
|
||||
if builder is None or pool is None or lm_obj is None or idx_val is None or rhs_val is None:
|
||||
@@ -544,26 +544,26 @@ class ExprGenName(ExprGenBase.ExprGenBase):
|
||||
i8_ty: rawptr[llvmlite.LLVMType] = llvmlite.Int8(pool)
|
||||
i8_ptr_ty: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, i8_ty)
|
||||
# 加载 __data__ (偏移 0, index 0)
|
||||
s_idx0: llvmlite.Value | t.CPtr = llvmlite.const_int64(pool, 0)
|
||||
s_dpp: llvmlite.Value | t.CPtr = llvmlite.build_gep(builder, i64_ty, lm_obj, s_idx0)
|
||||
s_idx0: rawptr[llvmlite.Value] = llvmlite.const_int64(pool, 0)
|
||||
s_dpp: rawptr[llvmlite.Value] = llvmlite.build_gep(builder, i64_ty, lm_obj, s_idx0)
|
||||
if s_dpp is None:
|
||||
return 0
|
||||
s_data: llvmlite.Value | t.CPtr = llvmlite.build_load(builder, i8_ptr_ty, s_dpp)
|
||||
s_data: rawptr[llvmlite.Value] = llvmlite.build_load(builder, i8_ptr_ty, s_dpp)
|
||||
# 加载 __elem_size__ (偏移 32, index 4)
|
||||
s_idx4: llvmlite.Value | t.CPtr = llvmlite.const_int64(pool, 4)
|
||||
s_epp: llvmlite.Value | t.CPtr = llvmlite.build_gep(builder, i64_ty, lm_obj, s_idx4)
|
||||
s_idx4: rawptr[llvmlite.Value] = llvmlite.const_int64(pool, 4)
|
||||
s_epp: rawptr[llvmlite.Value] = llvmlite.build_gep(builder, i64_ty, lm_obj, s_idx4)
|
||||
if s_epp is None:
|
||||
return 0
|
||||
s_esize: llvmlite.Value | t.CPtr = llvmlite.build_load(builder, i64_ty, s_epp)
|
||||
s_esize: rawptr[llvmlite.Value] = llvmlite.build_load(builder, i64_ty, s_epp)
|
||||
if s_data is None or s_esize is None:
|
||||
return 0
|
||||
s_idx_i64: llvmlite.Value | t.CPtr = self.coerce_to_type(builder, idx_val, i64_ty, node)
|
||||
s_idx_i64: rawptr[llvmlite.Value] = self.coerce_to_type(builder, idx_val, i64_ty, node)
|
||||
if s_idx_i64 is None:
|
||||
return 0
|
||||
s_offset: llvmlite.Value | t.CPtr = llvmlite.build_mul(builder, s_idx_i64, s_esize)
|
||||
s_offset: rawptr[llvmlite.Value] = llvmlite.build_mul(builder, s_idx_i64, s_esize)
|
||||
if s_offset is None:
|
||||
return 0
|
||||
s_addr: llvmlite.Value | t.CPtr = llvmlite.build_gep(builder, i8_ty, s_data, s_offset)
|
||||
s_addr: rawptr[llvmlite.Value] = llvmlite.build_gep(builder, i8_ty, s_data, s_offset)
|
||||
if s_addr is None:
|
||||
return 0
|
||||
# 元素类型 T:从 list 特化类型名解析(list[int]→i32、list[str]→i8*)。
|
||||
@@ -578,10 +578,10 @@ class ExprGenName(ExprGenBase.ExprGenBase):
|
||||
s_elem_ty = self._list_elem_type_from_name(pool, s_name)
|
||||
if s_elem_ty is None:
|
||||
s_elem_ty = i8_ptr_ty
|
||||
s_val_ptr: llvmlite.Value | t.CPtr = self.coerce_to_type(builder, rhs_val, s_elem_ty, node)
|
||||
s_val_ptr: rawptr[llvmlite.Value] = self.coerce_to_type(builder, rhs_val, s_elem_ty, node)
|
||||
if s_val_ptr is None:
|
||||
return 0
|
||||
s_ep: llvmlite.Value | t.CPtr = llvmlite.build_bitcast(
|
||||
s_ep: rawptr[llvmlite.Value] = llvmlite.build_bitcast(
|
||||
builder, s_addr, llvmlite.Ptr(pool, s_elem_ty))
|
||||
if s_ep is not None:
|
||||
llvmlite.build_store(builder, s_val_ptr, s_ep)
|
||||
@@ -592,7 +592,7 @@ class ExprGenName(ExprGenBase.ExprGenBase):
|
||||
# 返回 list 对象指针 (Ptr(list[T])) 或 None
|
||||
# ============================================================
|
||||
def is_list_subscript(self, node: rawptr[ast.AST],
|
||||
trans: rawptr[HT.Translator]) -> llvmlite.Value | t.CPtr:
|
||||
trans: rawptr[HT.Translator]) -> rawptr[llvmlite.Value]:
|
||||
"""检查 Subscript 节点是否是 list[T] 类型,返回 list 对象指针或 None"""
|
||||
if node is None or trans is None:
|
||||
return None
|
||||
@@ -604,7 +604,7 @@ class ExprGenName(ExprGenBase.ExprGenBase):
|
||||
nm: rawptr[ast.Name] = rawptr[ast.Name](sub.value)
|
||||
if nm is None or nm.id is None:
|
||||
return None
|
||||
alloca: llvmlite.Value | t.CPtr = self.Gen.VarGen.lookup_var(trans.SymTab, nm.id)
|
||||
alloca: rawptr[llvmlite.Value] = self.Gen.VarGen.lookup_var(trans.SymTab, nm.id)
|
||||
if alloca is None or alloca.Ty is None:
|
||||
return None
|
||||
if self.is_ptr_type(alloca.Ty) == 0:
|
||||
@@ -633,26 +633,26 @@ class ExprGenName(ExprGenBase.ExprGenBase):
|
||||
if string.strstr(struct_name, "list[") is None:
|
||||
return None
|
||||
# 是 list 类型: load 出 list 对象指针
|
||||
builder: llvmlite.IRBuilder | t.CPtr = trans._cur_builder
|
||||
builder: rawptr[llvmlite.IRBuilder] = trans._cur_builder
|
||||
return llvmlite.build_load(builder, pointee, alloca)
|
||||
# _nonlocal_subscript_ptr:nonlocal 数组/指针的下标元素指针——嵌套(提升)函数体内访问 nonlocal 变量时,其实际存储是运行时共享堆(env[ni] 存堆地址),不能 lookup_var 找外层函数 alloca(其 SSA 编号属外层函数,当前函数引用会错乱崩溃)。正确路径:从 env 读堆地址(_load_raw_var_ptr)→ bitcast → GEP
|
||||
def _nonlocal_subscript_ptr(self, builder: llvmlite.IRBuilder | t.CPtr,
|
||||
def _nonlocal_subscript_ptr(self, builder: rawptr[llvmlite.IRBuilder],
|
||||
pool: rawptr[memhub.MemBuddy],
|
||||
trans: rawptr[HT.Translator],
|
||||
nm_id: str,
|
||||
idx_val: llvmlite.Value | t.CPtr) -> llvmlite.Value | t.CPtr:
|
||||
idx_val: rawptr[llvmlite.Value]) -> rawptr[llvmlite.Value]:
|
||||
"""nonlocal 数组/指针下标:从 env 读堆地址 → bitcast → GEP,返回元素指针"""
|
||||
if trans is None or nm_id is None or idx_val is None:
|
||||
return None
|
||||
nl_ty: rawptr[llvmlite.LLVMType] = GenApi.get_nonlocal_type(trans, nm_id)
|
||||
if nl_ty is None:
|
||||
return None
|
||||
raw_nl: llvmlite.Value | t.CPtr = self.Gen.StmtGenDecl._load_raw_var_ptr(trans, nm_id)
|
||||
raw_nl: rawptr[llvmlite.Value] = self.Gen.StmtGenDecl._load_raw_var_ptr(trans, nm_id)
|
||||
if raw_nl is None:
|
||||
return None
|
||||
match nl_ty:
|
||||
case llvmlite.LLVMType.Array(elem_ty_nl, _cnt_nl):
|
||||
arr_ptr_nl: llvmlite.Value | t.CPtr = llvmlite.build_bitcast(
|
||||
arr_ptr_nl: rawptr[llvmlite.Value] = llvmlite.build_bitcast(
|
||||
builder, raw_nl, llvmlite.Ptr(pool, nl_ty))
|
||||
if arr_ptr_nl is None:
|
||||
return None
|
||||
@@ -660,13 +660,13 @@ class ExprGenName(ExprGenBase.ExprGenBase):
|
||||
builder, nl_ty, elem_ty_nl, arr_ptr_nl,
|
||||
self._zext_index_to_i32(builder, idx_val))
|
||||
case llvmlite.LLVMType.Ptr(inner_nl):
|
||||
arr_ptr_nl2: llvmlite.Value | t.CPtr = llvmlite.build_bitcast(
|
||||
arr_ptr_nl2: rawptr[llvmlite.Value] = llvmlite.build_bitcast(
|
||||
builder, raw_nl, llvmlite.Ptr(pool, nl_ty))
|
||||
if arr_ptr_nl2 is None:
|
||||
return None
|
||||
return llvmlite.build_gep(builder, inner_nl, arr_ptr_nl2, idx_val)
|
||||
case _:
|
||||
arr_ptr_nl3: llvmlite.Value | t.CPtr = llvmlite.build_bitcast(
|
||||
arr_ptr_nl3: rawptr[llvmlite.Value] = llvmlite.build_bitcast(
|
||||
builder, raw_nl, llvmlite.Ptr(pool, nl_ty))
|
||||
if arr_ptr_nl3 is None:
|
||||
return None
|
||||
@@ -679,11 +679,11 @@ class ExprGenName(ExprGenBase.ExprGenBase):
|
||||
# 数组遍历: arr 是数组变量,用 alloca 指针做双索引 GEP [0, i] + load
|
||||
# list[T]: 泛型类不注册 struct,subscript 走 __getitem__ 内联路径
|
||||
# ============================================================
|
||||
def translate_subscript(self, builder: llvmlite.IRBuilder | t.CPtr,
|
||||
def translate_subscript(self, builder: rawptr[llvmlite.IRBuilder],
|
||||
pool: rawptr[memhub.MemBuddy],
|
||||
mod: rawptr[llvmlite.LLVMModule],
|
||||
node: rawptr[ast.AST],
|
||||
trans: rawptr[HT.Translator] = None) -> llvmlite.Value | t.CPtr:
|
||||
trans: rawptr[HT.Translator] = None) -> rawptr[llvmlite.Value]:
|
||||
"""翻译下标表达式,返回加载的元素值"""
|
||||
if node is None or builder is None:
|
||||
return None
|
||||
@@ -697,19 +697,19 @@ class ExprGenName(ExprGenBase.ExprGenBase):
|
||||
# create_process(path[n:], entry) 丢 name → entry 错位成第一参数 →
|
||||
# p.entry 垃圾 → 用户进程 iretq 到垃圾地址 → PF)。
|
||||
if sub.slice is not None and sub.slice.kind() == ast.ASTKind.Slice:
|
||||
slc: ast.Slice | t.CPtr = (ast.Slice | t.CPtr)(sub.slice)
|
||||
base_v: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
|
||||
slc: rawptr[ast.Slice] = rawptr[ast.Slice](sub.slice)
|
||||
base_v: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, sub.value, None, 0, trans)
|
||||
if base_v is None:
|
||||
return None
|
||||
if slc.lower is None:
|
||||
return base_v
|
||||
start_v: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
|
||||
start_v: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, slc.lower, None, 0, trans)
|
||||
if start_v is None:
|
||||
return None
|
||||
i64_sc: rawptr[llvmlite.LLVMType] = llvmlite.Int64(pool)
|
||||
start_w: llvmlite.Value | t.CPtr = start_v
|
||||
start_w: rawptr[llvmlite.Value] = start_v
|
||||
if start_v.Ty is not None:
|
||||
bt_sc: int = self.Gen.ExprGenBase.get_llvm_type_bits(start_v.Ty)
|
||||
if bt_sc != 0 and bt_sc < 64:
|
||||
@@ -720,7 +720,7 @@ class ExprGenName(ExprGenBase.ExprGenBase):
|
||||
return llvmlite.build_gep(builder, i8_sc, base_v, start_w)
|
||||
|
||||
# 翻译索引
|
||||
idx_val: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
|
||||
idx_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, sub.slice, None, 0, trans)
|
||||
if idx_val is None:
|
||||
return None
|
||||
@@ -730,7 +730,7 @@ class ExprGenName(ExprGenBase.ExprGenBase):
|
||||
# a.m[i][k] * b.m[k][j],内层 translate_value 会把行加载为
|
||||
# Array 值(非指针)→ 通用路径失败 → "rhs 翻译失败")
|
||||
if sub.value is not None and sub.value.kind() == ast.ASTKind.Subscript:
|
||||
inner_ptr_r: llvmlite.Value | t.CPtr = self.get_subscript_ptr(
|
||||
inner_ptr_r: rawptr[llvmlite.Value] = self.get_subscript_ptr(
|
||||
builder, pool, mod, sub.value, trans)
|
||||
if inner_ptr_r is None or inner_ptr_r.Ty is None:
|
||||
return None
|
||||
@@ -739,14 +739,14 @@ class ExprGenName(ExprGenBase.ExprGenBase):
|
||||
return None
|
||||
match inner_elem_r:
|
||||
case llvmlite.LLVMType.Array(arr_ie_r, _):
|
||||
elem_ptr_r: llvmlite.Value | t.CPtr = llvmlite.build_gep_array(
|
||||
elem_ptr_r: rawptr[llvmlite.Value] = llvmlite.build_gep_array(
|
||||
builder, inner_elem_r, arr_ie_r, inner_ptr_r,
|
||||
self._zext_index_to_i32(builder, idx_val))
|
||||
if elem_ptr_r is not None:
|
||||
return llvmlite.build_load(builder, arr_ie_r, elem_ptr_r)
|
||||
return None
|
||||
case _:
|
||||
elem_ptr_r2: llvmlite.Value | t.CPtr = llvmlite.build_gep(
|
||||
elem_ptr_r2: rawptr[llvmlite.Value] = llvmlite.build_gep(
|
||||
builder, inner_elem_r, inner_ptr_r, idx_val)
|
||||
if elem_ptr_r2 is not None:
|
||||
return llvmlite.build_load(builder, inner_elem_r, elem_ptr_r2)
|
||||
@@ -760,14 +760,14 @@ class ExprGenName(ExprGenBase.ExprGenBase):
|
||||
# lookup_var 外层 alloca——SSA 编号跨函数错乱崩溃)
|
||||
# 读路径:元素指针 load 出元素值
|
||||
if GenApi.is_nonlocal_name(trans, nm.id) != 0:
|
||||
nl_ptr_r: llvmlite.Value | t.CPtr = self._nonlocal_subscript_ptr(
|
||||
nl_ptr_r: rawptr[llvmlite.Value] = self._nonlocal_subscript_ptr(
|
||||
builder, pool, trans, nm.id, idx_val)
|
||||
if nl_ptr_r is not None and nl_ptr_r.Ty is not None:
|
||||
nl_elem_ty: rawptr[llvmlite.LLVMType] = nl_ptr_r.Ty.Pointee
|
||||
if nl_elem_ty is not None:
|
||||
return llvmlite.build_load(builder, nl_elem_ty, nl_ptr_r)
|
||||
return None
|
||||
alloca: llvmlite.Value | t.CPtr = self.Gen.VarGen.lookup_var(trans.SymTab, nm.id)
|
||||
alloca: rawptr[llvmlite.Value] = self.Gen.VarGen.lookup_var(trans.SymTab, nm.id)
|
||||
if alloca is not None and alloca.Ty is not None:
|
||||
if self.is_ptr_type(alloca.Ty) != 0:
|
||||
pointee: rawptr[llvmlite.LLVMType] = alloca.Ty.Pointee
|
||||
@@ -777,7 +777,7 @@ class ExprGenName(ExprGenBase.ExprGenBase):
|
||||
match pointee:
|
||||
case llvmlite.LLVMType.Array(elem_ty, count):
|
||||
# 数组遍历: getelementptr [N x elem_ty], ... , i32 0, i32 %idx
|
||||
elem_ptr: llvmlite.Value | t.CPtr = llvmlite.build_gep_array(
|
||||
elem_ptr: rawptr[llvmlite.Value] = llvmlite.build_gep_array(
|
||||
builder, pointee, elem_ty, alloca,
|
||||
self._zext_index_to_i32(builder, idx_val))
|
||||
if elem_ptr is not None:
|
||||
@@ -791,7 +791,7 @@ class ExprGenName(ExprGenBase.ExprGenBase):
|
||||
#(对齐 Ptr(Ptr(list)) 变量路径,修复 parts[0] 崩溃)
|
||||
if lsn_v is not None:
|
||||
if string.strstr(lsn_v, "list[") is not None:
|
||||
elem_addr_v: llvmlite.Value | t.CPtr = \
|
||||
elem_addr_v: rawptr[llvmlite.Value] = \
|
||||
self.list_getitem_inline(
|
||||
builder, pool, alloca, idx_val, node)
|
||||
if elem_addr_v is not None:
|
||||
@@ -800,7 +800,7 @@ class ExprGenName(ExprGenBase.ExprGenBase):
|
||||
if elem_ty_v is not None:
|
||||
elem_ptr_ty_v: rawptr[llvmlite.LLVMType] = \
|
||||
llvmlite.Ptr(pool, elem_ty_v)
|
||||
casted_v: llvmlite.Value | t.CPtr = \
|
||||
casted_v: rawptr[llvmlite.Value] = \
|
||||
llvmlite.build_bitcast(
|
||||
builder, elem_addr_v, elem_ptr_ty_v)
|
||||
if casted_v is not None:
|
||||
@@ -819,10 +819,10 @@ class ExprGenName(ExprGenBase.ExprGenBase):
|
||||
if list_struct_name is not None:
|
||||
if string.strstr(list_struct_name, "list[") is not None:
|
||||
# list[T] 类型: 内联生成 __getitem__ 逻辑
|
||||
ptr_val_list: llvmlite.Value | t.CPtr = llvmlite.build_load(
|
||||
ptr_val_list: rawptr[llvmlite.Value] = llvmlite.build_load(
|
||||
builder, pointee, alloca)
|
||||
if ptr_val_list is not None:
|
||||
elem_addr_list: llvmlite.Value | t.CPtr = self.list_getitem_inline(
|
||||
elem_addr_list: rawptr[llvmlite.Value] = self.list_getitem_inline(
|
||||
builder, pool, ptr_val_list, idx_val, node)
|
||||
if elem_addr_list is not None:
|
||||
# 根据类型名提取元素类型,bitcast 后 load
|
||||
@@ -831,7 +831,7 @@ class ExprGenName(ExprGenBase.ExprGenBase):
|
||||
if elem_ty_list is not None:
|
||||
elem_ptr_ty_list: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(
|
||||
pool, elem_ty_list)
|
||||
casted_addr_list: llvmlite.Value | t.CPtr = llvmlite.build_bitcast(
|
||||
casted_addr_list: rawptr[llvmlite.Value] = llvmlite.build_bitcast(
|
||||
builder, elem_addr_list, elem_ptr_ty_list)
|
||||
if casted_addr_list is not None:
|
||||
return llvmlite.build_load(
|
||||
@@ -844,10 +844,10 @@ class ExprGenName(ExprGenBase.ExprGenBase):
|
||||
# 对比 HashTable|t.CPtr: alloca.Ty=HashTable**, inner_ty=Struct(HashTable)
|
||||
# (非 Ptr), 仍走下面的方法调用转发路径。
|
||||
if self.is_ptr_type(inner_ty) != 0:
|
||||
ptr_val_pp: llvmlite.Value | t.CPtr = llvmlite.build_load(
|
||||
ptr_val_pp: rawptr[llvmlite.Value] = llvmlite.build_load(
|
||||
builder, pointee, alloca)
|
||||
if ptr_val_pp is not None:
|
||||
elem_ptr_pp: llvmlite.Value | t.CPtr = llvmlite.build_gep(
|
||||
elem_ptr_pp: rawptr[llvmlite.Value] = llvmlite.build_gep(
|
||||
builder, inner_ty, ptr_val_pp, idx_val)
|
||||
if elem_ptr_pp is not None:
|
||||
return llvmlite.build_load(builder, inner_ty, elem_ptr_pp)
|
||||
@@ -862,22 +862,22 @@ class ExprGenName(ExprGenBase.ExprGenBase):
|
||||
if gi_lookup_rd is not None:
|
||||
viperlib.snprintf(gi_lookup_rd, 128, "%s.__getitem__", cls_nm_rd_ptr)
|
||||
if self.Gen.CallGenBase.find_func_in_module(mod, gi_lookup_rd) is not None:
|
||||
obj_ptr_rd: llvmlite.Value | t.CPtr = llvmlite.build_load(
|
||||
obj_ptr_rd: rawptr[llvmlite.Value] = llvmlite.build_load(
|
||||
builder, pointee, alloca)
|
||||
if not (obj_ptr_rd is None):
|
||||
arg_vals_rd_p: sizet | t.CPtr = pool.alloc(8)
|
||||
if not (arg_vals_rd_p is None):
|
||||
arg_vals_rd_p[0] = sizet(idx_val)
|
||||
ret_rd_p: llvmlite.Value | t.CPtr = self.Gen.CallGenCall._call_method_on_ptr(
|
||||
ret_rd_p: rawptr[llvmlite.Value] = 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)
|
||||
if not (ret_rd_p is None):
|
||||
return ret_rd_p
|
||||
# 无 __getitem__:结构体指针数组访问(GEP + load)
|
||||
ptr_val_rd_g: llvmlite.Value | t.CPtr = llvmlite.build_load(
|
||||
ptr_val_rd_g: rawptr[llvmlite.Value] = llvmlite.build_load(
|
||||
builder, pointee, alloca)
|
||||
if ptr_val_rd_g is not None:
|
||||
elem_rd_g: llvmlite.Value | t.CPtr = llvmlite.build_gep(
|
||||
elem_rd_g: rawptr[llvmlite.Value] = llvmlite.build_gep(
|
||||
builder, inner_ty, ptr_val_rd_g, idx_val)
|
||||
if elem_rd_g is not None:
|
||||
return llvmlite.build_load(builder, inner_ty, elem_rd_g)
|
||||
@@ -886,7 +886,7 @@ class ExprGenName(ExprGenBase.ExprGenBase):
|
||||
# 直接 GEP 按 i8* 步长(8 字节),load i8*
|
||||
# 仅当 inner_ty 不是自定义结构体时才走指针遍历
|
||||
if trans is not None:
|
||||
ve_pe_ts: GenTypes.VarEntry | t.CPtr = \
|
||||
ve_pe_ts: rawptr[GenTypes.VarEntry] = \
|
||||
self.Gen.VarGen.lookup_var_entry(trans.SymTab, nm.id)
|
||||
if self.Gen.VarGen.var_is_ptr_element(ve_pe_ts) != 0:
|
||||
# bytes|t.CPtr / str|t.CPtr / T|t.CPtr:变量存指针值(i8*),
|
||||
@@ -894,19 +894,19 @@ class ExprGenName(ExprGenBase.ExprGenBase):
|
||||
# 必须先 load alloca 得指针值,再 GEP i8*(步长 8)——
|
||||
# 否则 GEP base 用 alloca(&elem_ptr)读到栈变量而非数据区,
|
||||
# list.get 返回"元素地址"而非"元素值"(dump 虚调用读错 vtable)。
|
||||
ptr_val_pe_ts: llvmlite.Value | t.CPtr = llvmlite.build_load(
|
||||
ptr_val_pe_ts: rawptr[llvmlite.Value] = llvmlite.build_load(
|
||||
builder, pointee, alloca)
|
||||
if ptr_val_pe_ts is not None:
|
||||
elem_ptr_ts: llvmlite.Value | t.CPtr = llvmlite.build_gep(
|
||||
elem_ptr_ts: rawptr[llvmlite.Value] = llvmlite.build_gep(
|
||||
builder, pointee, ptr_val_pe_ts, idx_val)
|
||||
if elem_ptr_ts is not None:
|
||||
return llvmlite.build_load(builder, pointee, elem_ptr_ts)
|
||||
return None
|
||||
# 普通指针遍历: 先 load 指针值,再 GEP
|
||||
ptr_val: llvmlite.Value | t.CPtr = llvmlite.build_load(
|
||||
ptr_val: rawptr[llvmlite.Value] = llvmlite.build_load(
|
||||
builder, pointee, alloca)
|
||||
if ptr_val is not None:
|
||||
elem_ptr2: llvmlite.Value | t.CPtr = llvmlite.build_gep(
|
||||
elem_ptr2: rawptr[llvmlite.Value] = llvmlite.build_gep(
|
||||
builder, inner_ty, ptr_val, idx_val)
|
||||
if elem_ptr2 is not None:
|
||||
return llvmlite.build_load(builder, inner_ty, elem_ptr2)
|
||||
@@ -917,7 +917,7 @@ class ExprGenName(ExprGenBase.ExprGenBase):
|
||||
# 元素是 8 字节指针,须按 i8* 步长 GEP + load i8*——
|
||||
# 否则 list.get 只读 1 字节,指针截断 inttoptr 崩溃。
|
||||
if trans is not None:
|
||||
ve_pe_rd: GenTypes.VarEntry | t.CPtr = \
|
||||
ve_pe_rd: rawptr[GenTypes.VarEntry] = \
|
||||
self.Gen.VarGen.lookup_var_entry(trans.SymTab, nm.id)
|
||||
if self.Gen.VarGen.var_is_ptr_element(ve_pe_rd) != 0:
|
||||
match pointee:
|
||||
@@ -925,7 +925,7 @@ class ExprGenName(ExprGenBase.ExprGenBase):
|
||||
if bits_rd == 8:
|
||||
i8_ptr_rd: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(
|
||||
pool, llvmlite.Int8(pool))
|
||||
elem_ptr_rd: llvmlite.Value | t.CPtr = llvmlite.build_gep(
|
||||
elem_ptr_rd: rawptr[llvmlite.Value] = llvmlite.build_gep(
|
||||
builder, i8_ptr_rd, alloca, idx_val)
|
||||
if elem_ptr_rd is not None:
|
||||
return llvmlite.build_load(
|
||||
@@ -941,22 +941,22 @@ class ExprGenName(ExprGenBase.ExprGenBase):
|
||||
if gi_lookup_sub is not None:
|
||||
viperlib.snprintf(gi_lookup_sub, 128, "%s.__getitem__", cls_nm_sub)
|
||||
if self.Gen.CallGenBase.find_func_in_module(mod, gi_lookup_sub) is not None:
|
||||
obj_val_sub: llvmlite.Value | t.CPtr = llvmlite.build_load(
|
||||
obj_val_sub: rawptr[llvmlite.Value] = llvmlite.build_load(
|
||||
builder, pointee, alloca)
|
||||
if not (obj_val_sub is None):
|
||||
arg_vals_sub: sizet | t.CPtr = pool.alloc(8)
|
||||
if not (arg_vals_sub is None):
|
||||
arg_vals_sub[0] = sizet(idx_val)
|
||||
ret_sub: llvmlite.Value | t.CPtr = self.Gen.CallGenCall._call_method_on_ptr(
|
||||
ret_sub: rawptr[llvmlite.Value] = self.Gen.CallGenCall._call_method_on_ptr(
|
||||
pool, builder, mod, cls_nm_sub, "__getitem__",
|
||||
obj_val_sub, arg_vals_sub, 1, trans, sub)
|
||||
if not (ret_sub is None):
|
||||
return ret_sub
|
||||
# 无 __getitem__:结构体指针数组访问(GEP + load)
|
||||
ptr_val_sub_g: llvmlite.Value | t.CPtr = llvmlite.build_load(
|
||||
ptr_val_sub_g: rawptr[llvmlite.Value] = llvmlite.build_load(
|
||||
builder, pointee, alloca)
|
||||
if ptr_val_sub_g is not None:
|
||||
elem_sub_g: llvmlite.Value | t.CPtr = llvmlite.build_gep(
|
||||
elem_sub_g: rawptr[llvmlite.Value] = llvmlite.build_gep(
|
||||
builder, pointee, ptr_val_sub_g, idx_val)
|
||||
if elem_sub_g is not None:
|
||||
return llvmlite.build_load(builder, pointee, elem_sub_g)
|
||||
@@ -964,7 +964,7 @@ class ExprGenName(ExprGenBase.ExprGenBase):
|
||||
pass
|
||||
|
||||
# 通用路径:翻译 value 获取指针
|
||||
ptr_val: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
|
||||
ptr_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, sub.value, None, 0, trans)
|
||||
if ptr_val is None or ptr_val.Ty is None:
|
||||
return None
|
||||
@@ -976,7 +976,7 @@ class ExprGenName(ExprGenBase.ExprGenBase):
|
||||
# 数组类型: 双索引 GEP + load 元素
|
||||
match elem_ty2:
|
||||
case llvmlite.LLVMType.Array(arr_elem_ty2, arr_count2):
|
||||
elem_ptr3: llvmlite.Value | t.CPtr = llvmlite.build_gep_array(
|
||||
elem_ptr3: rawptr[llvmlite.Value] = llvmlite.build_gep_array(
|
||||
builder, elem_ty2, arr_elem_ty2, ptr_val,
|
||||
self._zext_index_to_i32(builder, idx_val))
|
||||
if elem_ptr3 is not None:
|
||||
@@ -1000,7 +1000,7 @@ class ExprGenName(ExprGenBase.ExprGenBase):
|
||||
match elem_ty2:
|
||||
case llvmlite.LLVMType.Int(eb_u64):
|
||||
if eb_u64 == 64:
|
||||
cell_p_u64: llvmlite.Value | t.CPtr = \
|
||||
cell_p_u64: rawptr[llvmlite.Value] = \
|
||||
llvmlite.build_gep(builder, elem_ty2, ptr_val, idx_val)
|
||||
if cell_p_u64 is not None:
|
||||
i8_ty_u64: rawptr[llvmlite.LLVMType] = \
|
||||
@@ -1009,7 +1009,7 @@ class ExprGenName(ExprGenBase.ExprGenBase):
|
||||
llvmlite.Ptr(pool, i8_ty_u64)
|
||||
i8pp_ty_u64: rawptr[llvmlite.LLVMType] = \
|
||||
llvmlite.Ptr(pool, i8p_ty_u64)
|
||||
cast_cell_u64: llvmlite.Value | t.CPtr = \
|
||||
cast_cell_u64: rawptr[llvmlite.Value] = \
|
||||
llvmlite.build_bitcast(
|
||||
builder, cell_p_u64, i8pp_ty_u64)
|
||||
if cast_cell_u64 is not None:
|
||||
@@ -1028,19 +1028,19 @@ class ExprGenName(ExprGenBase.ExprGenBase):
|
||||
arg_vals_rd_g: sizet | t.CPtr = pool.alloc(8)
|
||||
if not (arg_vals_rd_g is None):
|
||||
arg_vals_rd_g[0] = sizet(idx_val)
|
||||
ret_rd_g: llvmlite.Value | t.CPtr = self.Gen.CallGenCall._call_method_on_ptr(
|
||||
ret_rd_g: rawptr[llvmlite.Value] = self.Gen.CallGenCall._call_method_on_ptr(
|
||||
pool, builder, mod, cls_nm_rd_gen, "__getitem__",
|
||||
ptr_val, arg_vals_rd_g, 1, trans, sub)
|
||||
if not (ret_rd_g is None):
|
||||
return ret_rd_g
|
||||
# 无 __getitem__:结构体指针数组访问(GEP + load)
|
||||
elem_ptr_gen: llvmlite.Value | t.CPtr = llvmlite.build_gep(
|
||||
elem_ptr_gen: rawptr[llvmlite.Value] = llvmlite.build_gep(
|
||||
builder, elem_ty2, ptr_val, idx_val)
|
||||
if elem_ptr_gen is not None:
|
||||
return llvmlite.build_load(builder, elem_ty2, elem_ptr_gen)
|
||||
return None
|
||||
# 指针类型: 单索引 GEP + load
|
||||
elem_ptr4: llvmlite.Value | t.CPtr = llvmlite.build_gep(
|
||||
elem_ptr4: rawptr[llvmlite.Value] = llvmlite.build_gep(
|
||||
builder, elem_ty2, ptr_val, idx_val)
|
||||
if elem_ptr4 is not None:
|
||||
return llvmlite.build_load(builder, elem_ty2, elem_ptr4)
|
||||
@@ -1062,11 +1062,11 @@ class ExprGenName(ExprGenBase.ExprGenBase):
|
||||
return 1
|
||||
return 0
|
||||
|
||||
def get_subscript_ptr(self, builder: llvmlite.IRBuilder | t.CPtr,
|
||||
def get_subscript_ptr(self, builder: rawptr[llvmlite.IRBuilder],
|
||||
pool: rawptr[memhub.MemBuddy],
|
||||
mod: rawptr[llvmlite.LLVMModule],
|
||||
node: rawptr[ast.AST],
|
||||
trans: rawptr[HT.Translator] = None) -> llvmlite.Value | t.CPtr:
|
||||
trans: rawptr[HT.Translator] = None) -> rawptr[llvmlite.Value]:
|
||||
"""获取下标表达式的元素指针(用于赋值 lhs)"""
|
||||
if node is None or builder is None:
|
||||
return None
|
||||
@@ -1075,7 +1075,7 @@ class ExprGenName(ExprGenBase.ExprGenBase):
|
||||
return None
|
||||
|
||||
# 翻译索引
|
||||
idx_val: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
|
||||
idx_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, sub.slice, None, 0, trans)
|
||||
if idx_val is None:
|
||||
return None
|
||||
@@ -1086,7 +1086,7 @@ class ExprGenName(ExprGenBase.ExprGenBase):
|
||||
# 会把内层元素加载为值(Array 类型)→ is_ptr_type 失败 → 返回 None →
|
||||
# "subscript ptr is None" fail-fast。递归取内层指针再 GEP 根治。)
|
||||
if sub.value is not None and sub.value.kind() == ast.ASTKind.Subscript:
|
||||
inner_ptr: llvmlite.Value | t.CPtr = self.get_subscript_ptr(
|
||||
inner_ptr: rawptr[llvmlite.Value] = self.get_subscript_ptr(
|
||||
builder, pool, mod, sub.value, trans)
|
||||
if inner_ptr is None or inner_ptr.Ty is None:
|
||||
return None
|
||||
@@ -1110,7 +1110,7 @@ class ExprGenName(ExprGenBase.ExprGenBase):
|
||||
if GenApi.is_nonlocal_name(trans, nm.id) != 0:
|
||||
return self._nonlocal_subscript_ptr(
|
||||
builder, pool, trans, nm.id, idx_val)
|
||||
alloca: llvmlite.Value | t.CPtr = self.Gen.VarGen.lookup_var(trans.SymTab, nm.id)
|
||||
alloca: rawptr[llvmlite.Value] = self.Gen.VarGen.lookup_var(trans.SymTab, nm.id)
|
||||
if alloca is not None and alloca.Ty is not None:
|
||||
if self.is_ptr_type(alloca.Ty) != 0:
|
||||
pointee: rawptr[llvmlite.LLVMType] = alloca.Ty.Pointee
|
||||
@@ -1127,7 +1127,7 @@ class ExprGenName(ExprGenBase.ExprGenBase):
|
||||
# 即 X|t.CPtr 当 X 本身是指针类型 (如 T=AST|t.CPtr, T|t.CPtr=AST**)。
|
||||
# 此时 [i]=val 应该是指针解引用赋值, 而非调用 __setitem__。
|
||||
if self.is_ptr_type(inner_ty) != 0:
|
||||
ptr_val_gsp: llvmlite.Value | t.CPtr = llvmlite.build_load(
|
||||
ptr_val_gsp: rawptr[llvmlite.Value] = llvmlite.build_load(
|
||||
builder, pointee, alloca)
|
||||
if ptr_val_gsp is not None:
|
||||
return llvmlite.build_gep(
|
||||
@@ -1148,7 +1148,7 @@ class ExprGenName(ExprGenBase.ExprGenBase):
|
||||
# 直接 GEP 按 i8* 步长(8 字节),不 load
|
||||
# 仅当 inner_ty 不是自定义结构体时才走指针遍历
|
||||
if trans is not None:
|
||||
ve_pe: GenTypes.VarEntry | t.CPtr = \
|
||||
ve_pe: rawptr[GenTypes.VarEntry] = \
|
||||
self.Gen.VarGen.lookup_var_entry(trans.SymTab, nm.id)
|
||||
if self.Gen.VarGen.var_is_ptr_element(ve_pe) != 0:
|
||||
# bytes|t.CPtr / str|t.CPtr / T|t.CPtr:变量存指针值,
|
||||
@@ -1156,7 +1156,7 @@ class ExprGenName(ExprGenBase.ExprGenBase):
|
||||
# alloca 得指针值,再 GEP——否则 GEP base 用 alloca(&elem_ptr)
|
||||
# 读到栈变量而非数据区,赋值写不进 list 数据
|
||||
# (data 全 0xbaadf00d,dump 虚调用读错 vtable 崩溃)。
|
||||
ptr_val_pe: llvmlite.Value | t.CPtr = llvmlite.build_load(
|
||||
ptr_val_pe: rawptr[llvmlite.Value] = llvmlite.build_load(
|
||||
builder, pointee, alloca)
|
||||
if ptr_val_pe is not None:
|
||||
# [FIX 2026-08-30] 64 位标量联合(int64|t.CPtr /
|
||||
@@ -1183,11 +1183,11 @@ class ExprGenName(ExprGenBase.ExprGenBase):
|
||||
builder, pointee, ptr_val_pe, idx_val)
|
||||
return None
|
||||
# 普通指针遍历: 先 load 指针值,再 GEP
|
||||
ptr_val: llvmlite.Value | t.CPtr = llvmlite.build_load(
|
||||
ptr_val: rawptr[llvmlite.Value] = llvmlite.build_load(
|
||||
builder, pointee, alloca)
|
||||
if ptr_val is None:
|
||||
return None
|
||||
gep_r: llvmlite.Value | t.CPtr = llvmlite.build_gep(
|
||||
gep_r: rawptr[llvmlite.Value] = llvmlite.build_gep(
|
||||
builder, inner_ty, ptr_val, idx_val)
|
||||
return gep_r
|
||||
case _:
|
||||
@@ -1198,7 +1198,7 @@ class ExprGenName(ExprGenBase.ExprGenBase):
|
||||
# elem_ptr: T | t.CPtr 退化为 i8*):pointee=i8 但
|
||||
# 元素是 8 字节指针,须按 i8* 步长 GEP(防只写 1 字节截断)
|
||||
if trans is not None:
|
||||
ve_pe_cs: GenTypes.VarEntry | t.CPtr = \
|
||||
ve_pe_cs: rawptr[GenTypes.VarEntry] = \
|
||||
self.Gen.VarGen.lookup_var_entry(trans.SymTab, nm.id)
|
||||
if self.Gen.VarGen.var_is_ptr_element(ve_pe_cs) != 0:
|
||||
# T|t.CPtr(退化为 i8*,如 _list.vp 的 elem_ptr)变量
|
||||
@@ -1206,7 +1206,7 @@ class ExprGenName(ExprGenBase.ExprGenBase):
|
||||
# 得指针值,再按 i8* 步长 GEP——否则 GEP base 用 alloca
|
||||
# (&elem_ptr)算到栈地址,赋值写不进 list 数据区
|
||||
# (append 只增 count、data 全 0xbaadf00d)。
|
||||
ptr_val_cs: llvmlite.Value | t.CPtr = llvmlite.build_load(
|
||||
ptr_val_cs: rawptr[llvmlite.Value] = llvmlite.build_load(
|
||||
builder, pointee, alloca)
|
||||
if ptr_val_cs is not None:
|
||||
match pointee:
|
||||
@@ -1224,7 +1224,7 @@ class ExprGenName(ExprGenBase.ExprGenBase):
|
||||
return llvmlite.build_gep(builder, pointee, alloca, idx_val)
|
||||
|
||||
# 通用路径
|
||||
ptr_val: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
|
||||
ptr_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, sub.value, None, 0, trans)
|
||||
if ptr_val is None or ptr_val.Ty is None:
|
||||
return None
|
||||
|
||||
@@ -31,15 +31,15 @@ class ExprGenOps(ExprGenBase.ExprGenBase):
|
||||
# else_blk: 翻译 orelse → br merge
|
||||
# merge_blk: phi [body_val, then_blk], [orelse_val, else_blk]
|
||||
# ============================================================
|
||||
def translate_ifexp(self, builder: llvmlite.IRBuilder | t.CPtr,
|
||||
def translate_ifexp(self, builder: rawptr[llvmlite.IRBuilder],
|
||||
pool: rawptr[memhub.MemBuddy],
|
||||
mod: rawptr[llvmlite.LLVMModule],
|
||||
node: rawptr[ast.AST],
|
||||
trans: rawptr[HT.Translator] = None) -> llvmlite.Value | t.CPtr:
|
||||
trans: rawptr[HT.Translator] = None) -> rawptr[llvmlite.Value]:
|
||||
"""翻译三元表达式 (body if test else orelse),返回 phi 结果 Value"""
|
||||
if node is None or builder is None or trans is None:
|
||||
return None
|
||||
ie: ast.IfExp | t.CPtr = (ast.IfExp | t.CPtr)(node)
|
||||
ie: rawptr[ast.IfExp] = rawptr[ast.IfExp](node)
|
||||
if ie is None:
|
||||
return None
|
||||
|
||||
@@ -48,21 +48,21 @@ class ExprGenOps(ExprGenBase.ExprGenBase):
|
||||
return None
|
||||
|
||||
# 1. 求值条件
|
||||
cond_val: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
|
||||
cond_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, ie.test, None, 0, trans)
|
||||
if cond_val is None:
|
||||
return None
|
||||
# 转换为 i1
|
||||
cond_bits: int = self.get_llvm_type_bits(cond_val.Ty)
|
||||
if cond_bits == 1:
|
||||
cond_i1: llvmlite.Value | t.CPtr = cond_val
|
||||
cond_i1: rawptr[llvmlite.Value] = cond_val
|
||||
else:
|
||||
if self.is_ptr_type(cond_val.Ty) != 0:
|
||||
# 指针类型:与 null 比较
|
||||
null_cond: llvmlite.Value | t.CPtr = llvmlite.ConstNull(pool, cond_val.Ty, "null")
|
||||
null_cond: rawptr[llvmlite.Value] = llvmlite.ConstNull(pool, cond_val.Ty, "null")
|
||||
cond_i1 = llvmlite.build_icmp(builder, llvmlite.ICMP_NE, cond_val, null_cond)
|
||||
else:
|
||||
zero: llvmlite.Value | t.CPtr = llvmlite.const_int32(pool, 0)
|
||||
zero: rawptr[llvmlite.Value] = llvmlite.const_int32(pool, 0)
|
||||
cond_i1 = llvmlite.build_icmp(builder, llvmlite.ICMP_NE, cond_val, zero)
|
||||
|
||||
# 2. 创建三个基本块
|
||||
@@ -72,11 +72,11 @@ class ExprGenOps(ExprGenBase.ExprGenBase):
|
||||
if name_buf is None:
|
||||
return None
|
||||
viperlib.snprintf(name_buf, 32, "ifexp.then.%d", cnt)
|
||||
then_bb: llvmlite.BasicBlock | t.CPtr = llvmlite.create_block(pool, func, name_buf)
|
||||
then_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(pool, func, name_buf)
|
||||
viperlib.snprintf(name_buf, 32, "ifexp.else.%d", cnt)
|
||||
else_bb: llvmlite.BasicBlock | t.CPtr = llvmlite.create_block(pool, func, name_buf)
|
||||
else_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(pool, func, name_buf)
|
||||
viperlib.snprintf(name_buf, 32, "ifexp.merge.%d", cnt)
|
||||
merge_bb: llvmlite.BasicBlock | t.CPtr = llvmlite.create_block(pool, func, name_buf)
|
||||
merge_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(pool, func, name_buf)
|
||||
|
||||
if then_bb is None or else_bb is None or merge_bb is None:
|
||||
return None
|
||||
@@ -86,9 +86,9 @@ class ExprGenOps(ExprGenBase.ExprGenBase):
|
||||
|
||||
# 4. then 分支
|
||||
llvmlite.position_at_end(builder, then_bb)
|
||||
body_val: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
|
||||
body_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, ie.body, None, 0, trans)
|
||||
then_blk_for_phi: llvmlite.BasicBlock | t.CPtr = trans._cur_builder.CurBlock
|
||||
then_blk_for_phi: rawptr[llvmlite.BasicBlock] = trans._cur_builder.CurBlock
|
||||
if body_val is None:
|
||||
# fail-fast:三元表达式 then 分支翻译失败,立即终止编译(暴露上游根因)
|
||||
self.Gen.TypeGenErr.fatal_error(ie.body, "三元表达式分支翻译失败", "TypeError")
|
||||
@@ -106,9 +106,9 @@ class ExprGenOps(ExprGenBase.ExprGenBase):
|
||||
if self.is_ptr_type(body_val.Ty) != 0:
|
||||
orelse_target_ty = body_val.Ty
|
||||
llvmlite.position_at_end(builder, else_bb)
|
||||
orelse_val: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
|
||||
orelse_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, ie.orelse, None, 0, trans, orelse_target_ty)
|
||||
else_blk_for_phi: llvmlite.BasicBlock | t.CPtr = trans._cur_builder.CurBlock
|
||||
else_blk_for_phi: rawptr[llvmlite.BasicBlock] = trans._cur_builder.CurBlock
|
||||
if orelse_val is None:
|
||||
# fail-fast:三元表达式 else 分支翻译失败,立即终止编译(暴露上游根因)
|
||||
self.Gen.TypeGenErr.fatal_error(ie.orelse, "三元表达式分支翻译失败", "TypeError")
|
||||
@@ -157,9 +157,9 @@ class ExprGenOps(ExprGenBase.ExprGenBase):
|
||||
# fail-fast:三元表达式分支类型缺失,立即终止编译(暴露上游根因)
|
||||
self.Gen.TypeGenErr.fatal_error(node, "三元表达式分支类型缺失", "TypeError")
|
||||
|
||||
inc1: llvmlite.PhiIncoming | t.CPtr = llvmlite.new_phi_incoming(
|
||||
inc1: rawptr[llvmlite.PhiIncoming] = llvmlite.new_phi_incoming(
|
||||
pool, body_val, then_blk_for_phi)
|
||||
inc2: llvmlite.PhiIncoming | t.CPtr = llvmlite.new_phi_incoming(
|
||||
inc2: rawptr[llvmlite.PhiIncoming] = llvmlite.new_phi_incoming(
|
||||
pool, orelse_val, else_blk_for_phi)
|
||||
if inc1 is None or inc2 is None:
|
||||
return None
|
||||
@@ -173,8 +173,8 @@ class ExprGenOps(ExprGenBase.ExprGenBase):
|
||||
# 翻译比较表达式 Compare(left, ops, comparators)
|
||||
# ============================================================
|
||||
def should_zext_widen(self, pool: rawptr[memhub.MemBuddy],
|
||||
narrow_val: llvmlite.Value | t.CPtr,
|
||||
wide_val: llvmlite.Value | t.CPtr,
|
||||
narrow_val: rawptr[llvmlite.Value],
|
||||
wide_val: rawptr[llvmlite.Value],
|
||||
narrow_node: rawptr[ast.AST] = None,
|
||||
trans: rawptr[HT.Translator] = None) -> int:
|
||||
"""判断整数拓宽方向:1=zext(无符号语义),0=sext
|
||||
@@ -272,7 +272,7 @@ class ExprGenOps(ExprGenBase.ExprGenBase):
|
||||
return 1
|
||||
# 2) 变量注解类型为无符号类型(trans 可用时查 SymTab)
|
||||
if trans is not None:
|
||||
ve: GenTypes.VarEntry | t.CPtr = self.Gen.VarGen.lookup_var_entry(
|
||||
ve: rawptr[GenTypes.VarEntry] = self.Gen.VarGen.lookup_var_entry(
|
||||
trans.SymTab, nm.id)
|
||||
if ve is not None:
|
||||
# [S4 切读] Spec 明确无符号(TS_UINT)优先于字符串判定
|
||||
@@ -302,7 +302,7 @@ class ExprGenOps(ExprGenBase.ExprGenBase):
|
||||
if sub_su.value is not None and sub_su.value.kind() == ast.ASTKind.Name:
|
||||
snm_su: rawptr[ast.Name] = rawptr[ast.Name](sub_su.value)
|
||||
if snm_su.id is not None and trans is not None:
|
||||
ve_su: GenTypes.VarEntry | t.CPtr = self.Gen.VarGen.lookup_var_entry(
|
||||
ve_su: rawptr[GenTypes.VarEntry] = self.Gen.VarGen.lookup_var_entry(
|
||||
trans.SymTab, snm_su.id)
|
||||
if ve_su is not None:
|
||||
# [S4 切读] Spec 明确无符号优先(数组元素为无符号的联合注解场景
|
||||
@@ -322,7 +322,7 @@ class ExprGenOps(ExprGenBase.ExprGenBase):
|
||||
if at_u.value.kind() == ast.ASTKind.Name:
|
||||
vn_u: rawptr[ast.Name] = rawptr[ast.Name](at_u.value)
|
||||
if vn_u.id is not None:
|
||||
ve_u: GenTypes.VarEntry | t.CPtr = self.Gen.VarGen.lookup_var_entry(
|
||||
ve_u: rawptr[GenTypes.VarEntry] = self.Gen.VarGen.lookup_var_entry(
|
||||
trans.SymTab, vn_u.id)
|
||||
if ve_u is not None:
|
||||
cls_nm_u = self.Gen.VarGen.var_annot_class_name(ve_u)
|
||||
@@ -333,11 +333,11 @@ class ExprGenOps(ExprGenBase.ExprGenBase):
|
||||
if dot_u is not None:
|
||||
bare_u = dot_u + 1
|
||||
if bare_u is not None:
|
||||
st_u: GenTypes.StructEntry | t.CPtr = self.Gen.StructGen.find_struct(bare_u)
|
||||
st_u: rawptr[GenTypes.StructEntry] = self.Gen.StructGen.find_struct(bare_u)
|
||||
if st_u is not None:
|
||||
fi_u: int = 0
|
||||
while fi_u < st_u.FieldCount:
|
||||
fe_u: GenTypes.FieldEntry | t.CPtr = \
|
||||
fe_u: rawptr[GenTypes.FieldEntry] = \
|
||||
self.Gen.StructGen._get_field_entry(st_u, fi_u)
|
||||
if fe_u is not None and fe_u.Name is not None \
|
||||
and string.strcmp(fe_u.Name, at_u.attr) == 0:
|
||||
@@ -383,7 +383,7 @@ class ExprGenOps(ExprGenBase.ExprGenBase):
|
||||
if self._spec_sign_from_annot(nm.id) == TSpec.TS_SIGN_SIGNED:
|
||||
return 1
|
||||
if trans is not None:
|
||||
ve: GenTypes.VarEntry | t.CPtr = self.Gen.VarGen.lookup_var_entry(
|
||||
ve: rawptr[GenTypes.VarEntry] = self.Gen.VarGen.lookup_var_entry(
|
||||
trans.SymTab, nm.id)
|
||||
if ve is not None:
|
||||
ncn_s: str = self.Gen.VarGen.var_annot_class_name(ve)
|
||||
@@ -396,7 +396,7 @@ class ExprGenOps(ExprGenBase.ExprGenBase):
|
||||
if sub_s.value is not None and sub_s.value.kind() == ast.ASTKind.Name:
|
||||
snm: rawptr[ast.Name] = rawptr[ast.Name](sub_s.value)
|
||||
if snm.id is not None and trans is not None:
|
||||
ve_s: GenTypes.VarEntry | t.CPtr = self.Gen.VarGen.lookup_var_entry(
|
||||
ve_s: rawptr[GenTypes.VarEntry] = self.Gen.VarGen.lookup_var_entry(
|
||||
trans.SymTab, snm.id)
|
||||
if ve_s is not None:
|
||||
scn_s: str = self.Gen.VarGen.var_annot_class_name(ve_s)
|
||||
@@ -436,7 +436,7 @@ class ExprGenOps(ExprGenBase.ExprGenBase):
|
||||
# (SpecFromLLVMType 默认),**不可**据此断言 SIGNED —— 故只切无符号方向,
|
||||
# 有符号仍走注解名(Spec.SourceName)真源(避免把未表态误判成 signed)。
|
||||
# ============================================================
|
||||
def _entry_spec_unsigned(self, sp: TSpec.TypeSpec | t.CPtr) -> int:
|
||||
def _entry_spec_unsigned(self, sp: rawptr[TSpec.TypeSpec]) -> int:
|
||||
"""Spec 是否明确无符号整数(TS_UINT);其它一律 0(未表态/不适用)"""
|
||||
if sp is None:
|
||||
return 0
|
||||
@@ -464,13 +464,13 @@ class ExprGenOps(ExprGenBase.ExprGenBase):
|
||||
if self._spec_sign_from_annot(annot) == TSpec.TS_SIGN_UNSIGNED:
|
||||
return 1
|
||||
return 0
|
||||
def translate_compare(self, builder: llvmlite.IRBuilder | t.CPtr,
|
||||
def translate_compare(self, builder: rawptr[llvmlite.IRBuilder],
|
||||
pool: rawptr[memhub.MemBuddy],
|
||||
mod: rawptr[llvmlite.LLVMModule],
|
||||
node: rawptr[ast.AST],
|
||||
trans: rawptr[HT.Translator] = None) -> llvmlite.Value | t.CPtr:
|
||||
trans: rawptr[HT.Translator] = None) -> rawptr[llvmlite.Value]:
|
||||
"""翻译比较表达式,返回 i1 结果"""
|
||||
cmp: ast.Compare | t.CPtr = (ast.Compare | t.CPtr)(node)
|
||||
cmp: rawptr[ast.Compare] = rawptr[ast.Compare](node)
|
||||
if cmp is None:
|
||||
return None
|
||||
|
||||
@@ -479,11 +479,11 @@ class ExprGenOps(ExprGenBase.ExprGenBase):
|
||||
return None
|
||||
op: int = ops_list.get(0)
|
||||
|
||||
comparators: list[rawptr[ast.AST]] | t.CPtr = cmp.comparators
|
||||
comparators: rawptr[list[rawptr[ast.AST]]] = cmp.comparators
|
||||
if comparators is None or len(comparators) == 0:
|
||||
return None
|
||||
rhs_node: rawptr[ast.AST] = comparators.get(0)
|
||||
rhs: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
|
||||
rhs: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, rhs_node, None, 0, trans)
|
||||
if rhs is None:
|
||||
return None
|
||||
@@ -523,26 +523,26 @@ class ExprGenOps(ExprGenBase.ExprGenBase):
|
||||
if cmp_with_none == 0 and lhs_node is not None and lhs_node.kind() == ast.ASTKind.Name and trans is not None:
|
||||
nm: rawptr[ast.Name] = rawptr[ast.Name](lhs_node)
|
||||
if nm is not None and nm.id is not None:
|
||||
lhs_alloca: llvmlite.Value | t.CPtr = self.Gen.VarGen.lookup_var(
|
||||
lhs_alloca: rawptr[llvmlite.Value] = self.Gen.VarGen.lookup_var(
|
||||
trans.SymTab, nm.id)
|
||||
if lhs_alloca is not None:
|
||||
if cmp_zero == 0 or self.get_ptr_level(lhs_alloca.Ty) == 0:
|
||||
ovl_self1: llvmlite.Value | t.CPtr = lhs_alloca
|
||||
ovl_self1: rawptr[llvmlite.Value] = lhs_alloca
|
||||
# Ptr(Ptr(Struct)) 对象存储槽:load 出对象指针作 self
|
||||
# (与 translate_binop 路径 1 一致,避免槽地址当对象地址)
|
||||
if lhs_alloca.Ty is not None and lhs_alloca.Ty.Pointee is not None \
|
||||
and self.Gen.ExprGenBase.is_ptr_type(lhs_alloca.Ty.Pointee) != 0:
|
||||
load_self1: llvmlite.Value | t.CPtr = llvmlite.build_load(
|
||||
load_self1: rawptr[llvmlite.Value] = llvmlite.build_load(
|
||||
builder, lhs_alloca.Ty.Pointee, lhs_alloca)
|
||||
if load_self1 is not None:
|
||||
ovl_self1 = load_self1
|
||||
ovl_result: llvmlite.Value | t.CPtr = self.try_operator_overload(
|
||||
ovl_result: rawptr[llvmlite.Value] = self.try_operator_overload(
|
||||
pool, builder, mod, ovl_self1, rhs, op, trans, 1)
|
||||
if ovl_result is not None:
|
||||
return ovl_result
|
||||
|
||||
# 正常翻译 lhs
|
||||
lhs: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
|
||||
lhs: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, cmp.left, None, 0, trans)
|
||||
if lhs is None:
|
||||
return None
|
||||
@@ -566,8 +566,8 @@ class ExprGenOps(ExprGenBase.ExprGenBase):
|
||||
cn_fn_name: str = llvmlite.function_get_name(cn_fn)
|
||||
if cn_ret is not None and cn_fn_name is not None:
|
||||
# self 参数(容器)按 __contains__ 首参类型对齐
|
||||
cn_self: llvmlite.Value | t.CPtr = rhs
|
||||
cn_first: llvmlite.Param | t.CPtr = llvmlite.function_get_param_head(cn_fn)
|
||||
cn_self: rawptr[llvmlite.Value] = rhs
|
||||
cn_first: rawptr[llvmlite.Param] = llvmlite.function_get_param_head(cn_fn)
|
||||
if cn_first is not None:
|
||||
cn_self_ty: rawptr[llvmlite.LLVMType] = llvmlite.param_get_ty(cn_first)
|
||||
if cn_self_ty is not None:
|
||||
@@ -576,15 +576,15 @@ class ExprGenOps(ExprGenBase.ExprGenBase):
|
||||
# 参数链表: self → key(独立 null 结尾)
|
||||
cn_self.Next = lhs
|
||||
lhs.Next = None
|
||||
cn_res: llvmlite.Value | t.CPtr = llvmlite.build_call(
|
||||
cn_res: rawptr[llvmlite.Value] = llvmlite.build_call(
|
||||
builder, cn_fn_name, cn_self, 2, cn_ret, 0)
|
||||
if cn_res is not None:
|
||||
# 归一化到 i1(__contains__ 返回 int/i32 等)
|
||||
cn_i1: llvmlite.Value | t.CPtr = cn_res
|
||||
cn_i1: rawptr[llvmlite.Value] = cn_res
|
||||
match cn_ret:
|
||||
case llvmlite.LLVMType.Int(cn_bits):
|
||||
if cn_bits > 1:
|
||||
cn_zero: llvmlite.Value | t.CPtr = llvmlite.ConstInt(
|
||||
cn_zero: rawptr[llvmlite.Value] = llvmlite.ConstInt(
|
||||
pool, cn_ret, 0, "0")
|
||||
if cn_zero is not None:
|
||||
cn_i1 = llvmlite.build_icmp(
|
||||
@@ -594,7 +594,7 @@ class ExprGenOps(ExprGenBase.ExprGenBase):
|
||||
if op == ast.OpKind.NotIn:
|
||||
i1_ty_ni: rawptr[llvmlite.LLVMType] = llvmlite.Int1(pool)
|
||||
if i1_ty_ni is not None and cn_i1 is not None:
|
||||
one_i1_ni: llvmlite.Value | t.CPtr = llvmlite.ConstInt(
|
||||
one_i1_ni: rawptr[llvmlite.Value] = llvmlite.ConstInt(
|
||||
pool, i1_ty_ni, 1, "1")
|
||||
if one_i1_ni is not None:
|
||||
cn_i1 = llvmlite.build_xor(builder, cn_i1, one_i1_ni)
|
||||
@@ -610,7 +610,7 @@ class ExprGenOps(ExprGenBase.ExprGenBase):
|
||||
# Is/IsNot 不在 _cmpop_to_dunder 映射中,会自动返回 None 回退原生比较
|
||||
# None 比较跳过重载(走身份比较);指针判空(cmp_zero + 指针)同样跳过
|
||||
if cmp_with_none == 0 and (cmp_zero == 0 or self.get_ptr_level(lhs.Ty) == 0):
|
||||
ovl_result2: llvmlite.Value | t.CPtr = self.try_operator_overload(
|
||||
ovl_result2: rawptr[llvmlite.Value] = self.try_operator_overload(
|
||||
pool, builder, mod, lhs, rhs, op, trans, 1)
|
||||
if ovl_result2 is not None:
|
||||
return ovl_result2
|
||||
@@ -779,17 +779,17 @@ class ExprGenOps(ExprGenBase.ExprGenBase):
|
||||
# ============================================================
|
||||
# 翻译一元运算表达式 UnaryOp(op, operand)
|
||||
# ============================================================
|
||||
def translate_unaryop(self, builder: llvmlite.IRBuilder | t.CPtr,
|
||||
def translate_unaryop(self, builder: rawptr[llvmlite.IRBuilder],
|
||||
pool: rawptr[memhub.MemBuddy],
|
||||
mod: rawptr[llvmlite.LLVMModule],
|
||||
node: rawptr[ast.AST],
|
||||
trans: rawptr[HT.Translator] = None) -> llvmlite.Value | t.CPtr:
|
||||
trans: rawptr[HT.Translator] = None) -> rawptr[llvmlite.Value]:
|
||||
"""翻译一元运算(-x, +x, not x, ~x)"""
|
||||
uo: rawptr[ast.UnaryOp] = rawptr[ast.UnaryOp](node)
|
||||
if uo is None:
|
||||
return None
|
||||
|
||||
operand: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
|
||||
operand: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, uo.operand, None, 0, trans)
|
||||
if operand is None:
|
||||
return None
|
||||
@@ -797,7 +797,7 @@ class ExprGenOps(ExprGenBase.ExprGenBase):
|
||||
# === 一元运算符重载: -obj/+obj/~obj 调用 __neg__/__pos__/__invert__ ===
|
||||
# 仅 USub/UAdd/Invert 有重载语义(not 无 dunder 方法)
|
||||
if uo.op == ast.OpKind.USub or uo.op == ast.OpKind.UAdd or uo.op == ast.OpKind.Invert:
|
||||
ovl_u: llvmlite.Value | t.CPtr = self.try_unary_operator_overload(
|
||||
ovl_u: rawptr[llvmlite.Value] = self.try_unary_operator_overload(
|
||||
pool, builder, mod, operand, uo.op, trans)
|
||||
if ovl_u is not None:
|
||||
return ovl_u
|
||||
@@ -810,7 +810,7 @@ class ExprGenOps(ExprGenBase.ExprGenBase):
|
||||
return llvmlite.build_fneg(builder, operand)
|
||||
# 整数类型:-x = 0 - x,根据位宽选择零值常量(避免 i32 与 i64 类型不匹配)
|
||||
operand_bits: int = self.get_llvm_type_bits(operand.Ty)
|
||||
zero: llvmlite.Value | t.CPtr = llvmlite.const_int32(pool, 0)
|
||||
zero: rawptr[llvmlite.Value] = llvmlite.const_int32(pool, 0)
|
||||
if operand_bits == 64:
|
||||
zero = llvmlite.const_int64(pool, 0)
|
||||
elif operand_bits > 0 and operand_bits != 32:
|
||||
@@ -824,7 +824,7 @@ class ExprGenOps(ExprGenBase.ExprGenBase):
|
||||
# not x = (x == 0/null),返回 i1
|
||||
if self.is_ptr_type(operand.Ty) != 0:
|
||||
# 指针类型:与 null 比较
|
||||
null_op: llvmlite.Value | t.CPtr = llvmlite.ConstNull(pool, operand.Ty, "null")
|
||||
null_op: rawptr[llvmlite.Value] = llvmlite.ConstNull(pool, operand.Ty, "null")
|
||||
return llvmlite.build_icmp(builder, llvmlite.ICMP_EQ, operand, null_op)
|
||||
# 结构体值类型:永远为真(非空),not 返回 false
|
||||
operand_is_struct_not: int = 0
|
||||
@@ -843,7 +843,7 @@ class ExprGenOps(ExprGenBase.ExprGenBase):
|
||||
elif uo.op == ast.OpKind.Invert:
|
||||
# ~x = x ^ -1
|
||||
operand_bits_inv: int = self.get_llvm_type_bits(operand.Ty)
|
||||
neg1: llvmlite.Value | t.CPtr = llvmlite.const_int32(pool, -1)
|
||||
neg1: rawptr[llvmlite.Value] = llvmlite.const_int32(pool, -1)
|
||||
if operand_bits_inv == 64:
|
||||
neg1 = llvmlite.const_int64(pool, -1)
|
||||
return llvmlite.build_xor(builder, operand, neg1)
|
||||
@@ -868,7 +868,7 @@ class ExprGenOps(ExprGenBase.ExprGenBase):
|
||||
# self/cls 对象引用:返回对象指针本身(Ptr(Struct))而非
|
||||
# 指针变量的地址(Ptr(Ptr(Struct)))
|
||||
if string.strcmp(nm_ao.id, "self") == 0 or string.strcmp(nm_ao.id, "cls") == 0:
|
||||
se_ao: GenTypes.VarEntry | t.CPtr = self.Gen.VarGen.lookup_var_entry(
|
||||
se_ao: rawptr[GenTypes.VarEntry] = self.Gen.VarGen.lookup_var_entry(
|
||||
trans.SymTab, nm_ao.id)
|
||||
if se_ao is not None and se_ao.Alloca is not None and se_ao.Alloca.Ty is not None:
|
||||
match se_ao.Alloca.Ty:
|
||||
@@ -881,10 +881,10 @@ class ExprGenOps(ExprGenBase.ExprGenBase):
|
||||
pass
|
||||
case _:
|
||||
pass
|
||||
v_ao: llvmlite.Value | t.CPtr = self.Gen.VarGen.lookup_var(trans.SymTab, nm_ao.id)
|
||||
v_ao: rawptr[llvmlite.Value] = self.Gen.VarGen.lookup_var(trans.SymTab, nm_ao.id)
|
||||
if v_ao is None and mod is not None:
|
||||
# 模块全局变量:经 make_global_ref 转成带引号的 Ptr(Ty) 引用
|
||||
gv_ao: llvmlite.GlobalVariable | t.CPtr = self.Gen.ExprGenAttr.find_global_in_module(mod, nm_ao.id)
|
||||
gv_ao: rawptr[llvmlite.GlobalVariable] = self.Gen.ExprGenAttr.find_global_in_module(mod, nm_ao.id)
|
||||
if gv_ao is not None and gv_ao.Name is not None and gv_ao.Ty is not None:
|
||||
v_ao = self.Gen.ExprGenAttr.make_global_ref(pool, gv_ao.Name, gv_ao.Ty)
|
||||
if v_ao is not None and v_ao.Ty is not None:
|
||||
@@ -911,9 +911,9 @@ class ExprGenOps(ExprGenBase.ExprGenBase):
|
||||
if f_ao is not None:
|
||||
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_head_ao: rawptr[llvmlite.Param] = llvmlite.function_get_param_head(f_ao)
|
||||
p_cnt_ao: sizet = 0
|
||||
p_cur_ao: llvmlite.Param | t.CPtr = p_head_ao
|
||||
p_cur_ao: rawptr[llvmlite.Param] = p_head_ao
|
||||
while p_cur_ao is not None:
|
||||
p_cnt_ao += 1
|
||||
p_cur_ao = llvmlite.param_get_next(p_cur_ao)
|
||||
@@ -930,13 +930,13 @@ class ExprGenOps(ExprGenBase.ExprGenBase):
|
||||
return llvmlite.SSAValue(pool, llvmlite.Ptr(pool, fn_ty_ao), fbuf_ao)
|
||||
elif uo.operand.kind() == ast.ASTKind.Attribute:
|
||||
# 字段地址(GEP,不 load)
|
||||
fptr_ao: llvmlite.Value | t.CPtr = self.Gen.ExprGenAttr.get_attribute_ptr(
|
||||
fptr_ao: rawptr[llvmlite.Value] = self.Gen.ExprGenAttr.get_attribute_ptr(
|
||||
builder, pool, mod, uo.operand, trans)
|
||||
if fptr_ao is not None:
|
||||
return fptr_ao
|
||||
elif uo.operand.kind() == ast.ASTKind.Subscript:
|
||||
# 元素地址(GEP,不 load)
|
||||
sptr_ao: llvmlite.Value | t.CPtr = self.Gen.ExprGenName.get_subscript_ptr(
|
||||
sptr_ao: rawptr[llvmlite.Value] = self.Gen.ExprGenName.get_subscript_ptr(
|
||||
builder, pool, mod, uo.operand, trans)
|
||||
if sptr_ao is not None:
|
||||
return sptr_ao
|
||||
@@ -953,20 +953,20 @@ class ExprGenOps(ExprGenBase.ExprGenBase):
|
||||
# 最后一个值直接求值并跳 merge
|
||||
# merge 块用 phi 合并所有入边的 i1
|
||||
# ============================================================
|
||||
def translate_boolop(self, builder: llvmlite.IRBuilder | t.CPtr,
|
||||
def translate_boolop(self, builder: rawptr[llvmlite.IRBuilder],
|
||||
pool: rawptr[memhub.MemBuddy],
|
||||
mod: rawptr[llvmlite.LLVMModule],
|
||||
node: rawptr[ast.AST],
|
||||
funcs_ptr: t.CPtr = None,
|
||||
func_count: int = 0,
|
||||
trans: rawptr[HT.Translator] = None) -> llvmlite.Value | t.CPtr:
|
||||
trans: rawptr[HT.Translator] = None) -> rawptr[llvmlite.Value]:
|
||||
"""翻译布尔运算(and/or)的短路求值,返回 i1"""
|
||||
bo: ast.BoolOp | t.CPtr = (ast.BoolOp | t.CPtr)(node)
|
||||
bo: rawptr[ast.BoolOp] = rawptr[ast.BoolOp](node)
|
||||
if bo is None:
|
||||
return None
|
||||
|
||||
op: int = bo.op
|
||||
values: list[rawptr[ast.AST]] | t.CPtr = bo.values
|
||||
values: rawptr[list[rawptr[ast.AST]]] = bo.values
|
||||
if values is None:
|
||||
return None
|
||||
count: sizet = len(values)
|
||||
@@ -988,17 +988,17 @@ class ExprGenOps(ExprGenBase.ExprGenBase):
|
||||
if name_buf is None:
|
||||
return None
|
||||
viperlib.snprintf(name_buf, 32, "bool.merge.%d", cnt)
|
||||
merge_bb: llvmlite.BasicBlock | t.CPtr = llvmlite.create_block(pool, func, name_buf)
|
||||
merge_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(pool, func, name_buf)
|
||||
|
||||
# phi 入边链表头/尾
|
||||
phi_head: llvmlite.PhiIncoming | t.CPtr = None
|
||||
phi_tail: llvmlite.PhiIncoming | t.CPtr = None
|
||||
phi_head: rawptr[llvmlite.PhiIncoming] = None
|
||||
phi_tail: rawptr[llvmlite.PhiIncoming] = None
|
||||
phi_count: int = count - 1 # 循环次数
|
||||
|
||||
# 对每个值(除最后一个)求值并短路
|
||||
for i in range(count - 1):
|
||||
val_node: rawptr[ast.AST] = values.get(i)
|
||||
val: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
|
||||
val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, val_node,
|
||||
funcs_ptr, func_count, trans)
|
||||
if val is None:
|
||||
@@ -1006,21 +1006,21 @@ class ExprGenOps(ExprGenBase.ExprGenBase):
|
||||
|
||||
# 转为 i1(已经是 i1 的直接用,否则与 0/null 比较)
|
||||
val_bits: int = self.get_llvm_type_bits(val.Ty)
|
||||
val_i1: llvmlite.Value | t.CPtr = val
|
||||
val_i1: rawptr[llvmlite.Value] = val
|
||||
if val_bits != 1:
|
||||
if self.is_ptr_type(val.Ty) != 0:
|
||||
# 指针类型:与 null 比较(避免 i8* 与 i32 类型不匹配)
|
||||
null_val: llvmlite.Value | t.CPtr = llvmlite.ConstNull(pool, val.Ty, "null")
|
||||
null_val: rawptr[llvmlite.Value] = llvmlite.ConstNull(pool, val.Ty, "null")
|
||||
val_i1 = llvmlite.build_icmp(builder, llvmlite.ICMP_NE, val, null_val)
|
||||
else:
|
||||
zero: llvmlite.Value | t.CPtr = llvmlite.const_int32(pool, 0)
|
||||
zero: rawptr[llvmlite.Value] = llvmlite.const_int32(pool, 0)
|
||||
val_i1 = llvmlite.build_icmp(builder, llvmlite.ICMP_NE, val, zero)
|
||||
|
||||
# 创建 next BB(求值下一个值)
|
||||
cnt = builder.Counter
|
||||
builder.Counter = cnt + 1
|
||||
viperlib.snprintf(name_buf, 32, "bool.next.%d", cnt)
|
||||
next_bb: llvmlite.BasicBlock | t.CPtr = llvmlite.create_block(pool, func, name_buf)
|
||||
next_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(pool, func, name_buf)
|
||||
|
||||
# and: 短路假→merge,真→next;or: 短路真→merge,假→next
|
||||
if op == ast.OpKind.And:
|
||||
@@ -1029,8 +1029,8 @@ class ExprGenOps(ExprGenBase.ExprGenBase):
|
||||
llvmlite.build_cond_br(builder, val_i1, merge_bb, next_bb)
|
||||
|
||||
# 添加 phi 入边:(val_i1, cond_br 所在 BB)
|
||||
cur_bb: llvmlite.BasicBlock | t.CPtr = builder.CurBlock
|
||||
inc: llvmlite.PhiIncoming | t.CPtr = llvmlite.new_phi_incoming(pool, val_i1, cur_bb)
|
||||
cur_bb: rawptr[llvmlite.BasicBlock] = builder.CurBlock
|
||||
inc: rawptr[llvmlite.PhiIncoming] = llvmlite.new_phi_incoming(pool, val_i1, cur_bb)
|
||||
if phi_head is None:
|
||||
phi_head = inc
|
||||
phi_tail = inc
|
||||
@@ -1043,17 +1043,17 @@ class ExprGenOps(ExprGenBase.ExprGenBase):
|
||||
|
||||
# 最后一个值:求值后直接跳 merge
|
||||
last_node: rawptr[ast.AST] = values.get(count - 1)
|
||||
last_val: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
|
||||
last_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, last_node,
|
||||
funcs_ptr, func_count, trans)
|
||||
if last_val is None:
|
||||
return None
|
||||
last_bits: int = self.get_llvm_type_bits(last_val.Ty)
|
||||
last_i1: llvmlite.Value | t.CPtr = last_val
|
||||
last_i1: rawptr[llvmlite.Value] = last_val
|
||||
if last_bits != 1:
|
||||
if self.is_ptr_type(last_val.Ty) != 0:
|
||||
# 指针类型:与 null 比较(避免 i8* 与 i32 类型不匹配)
|
||||
null_val2: llvmlite.Value | t.CPtr = llvmlite.ConstNull(pool, last_val.Ty, "null")
|
||||
null_val2: rawptr[llvmlite.Value] = llvmlite.ConstNull(pool, last_val.Ty, "null")
|
||||
last_i1 = llvmlite.build_icmp(builder, llvmlite.ICMP_NE, last_val, null_val2)
|
||||
else:
|
||||
zero = llvmlite.const_int32(pool, 0)
|
||||
@@ -1122,13 +1122,13 @@ class ExprGenOps(ExprGenBase.ExprGenBase):
|
||||
# 调用结果;未找到返回 None,调用方回退到原生运算。
|
||||
# ============================================================
|
||||
def try_operator_overload(self, pool: rawptr[memhub.MemBuddy],
|
||||
builder: llvmlite.IRBuilder | t.CPtr,
|
||||
builder: rawptr[llvmlite.IRBuilder],
|
||||
mod: rawptr[llvmlite.LLVMModule],
|
||||
lhs: llvmlite.Value | t.CPtr,
|
||||
rhs: llvmlite.Value | t.CPtr,
|
||||
lhs: rawptr[llvmlite.Value],
|
||||
rhs: rawptr[llvmlite.Value],
|
||||
op: int,
|
||||
trans: rawptr[HT.Translator],
|
||||
is_compare: int) -> llvmlite.Value | t.CPtr:
|
||||
is_compare: int) -> rawptr[llvmlite.Value]:
|
||||
"""尝试运算符重载:lhs 是结构体指针时调用 dunder 方法,否则返回 None"""
|
||||
if lhs is None or rhs is None:
|
||||
return None
|
||||
@@ -1179,7 +1179,7 @@ class ExprGenOps(ExprGenBase.ExprGenBase):
|
||||
# 方法不在当前模块中时,检查类(含父类)是否有 SHA1(stub 可能未注入)
|
||||
# 优先用类型指针定位 entry 获取 SHA1(规避跨模块同名 find_struct 找错)
|
||||
cls_sha1: str = None
|
||||
op_entry: GenTypes.StructEntry | t.CPtr = self.Gen.StructGen.find_struct_by_type(struct_ty)
|
||||
op_entry: rawptr[GenTypes.StructEntry] = self.Gen.StructGen.find_struct_by_type(struct_ty)
|
||||
if op_entry is not None:
|
||||
cls_sha1 = op_entry.ModuleSha1
|
||||
if cls_sha1 is None:
|
||||
@@ -1231,11 +1231,11 @@ class ExprGenOps(ExprGenBase.ExprGenBase):
|
||||
# operand.__dunder__(),返回调用结果;未找到返回 None,调用方回退到原生运算。
|
||||
# ============================================================
|
||||
def try_unary_operator_overload(self, pool: rawptr[memhub.MemBuddy],
|
||||
builder: llvmlite.IRBuilder | t.CPtr,
|
||||
builder: rawptr[llvmlite.IRBuilder],
|
||||
mod: rawptr[llvmlite.LLVMModule],
|
||||
operand: llvmlite.Value | t.CPtr,
|
||||
operand: rawptr[llvmlite.Value],
|
||||
op: int,
|
||||
trans: rawptr[HT.Translator]) -> llvmlite.Value | t.CPtr:
|
||||
trans: rawptr[HT.Translator]) -> rawptr[llvmlite.Value]:
|
||||
"""尝试一元运算符重载:operand 是结构体指针时调用 dunder 方法,否则返回 None"""
|
||||
if operand is None:
|
||||
return None
|
||||
@@ -1280,7 +1280,7 @@ class ExprGenOps(ExprGenBase.ExprGenBase):
|
||||
|
||||
# 方法不在当前模块中时,检查类(含父类)是否有 SHA1(stub 可能未注入)
|
||||
cls_sha1: str = None
|
||||
uop_entry: GenTypes.StructEntry | t.CPtr = self.Gen.StructGen.find_struct_by_type(struct_ty)
|
||||
uop_entry: rawptr[GenTypes.StructEntry] = self.Gen.StructGen.find_struct_by_type(struct_ty)
|
||||
if uop_entry is not None:
|
||||
cls_sha1 = uop_entry.ModuleSha1
|
||||
if cls_sha1 is None:
|
||||
@@ -1312,10 +1312,10 @@ class ExprGenOps(ExprGenBase.ExprGenBase):
|
||||
# 翻译二元运算(自动类型提升)
|
||||
# ============================================================
|
||||
def translate_binop(self, pool: rawptr[memhub.MemBuddy],
|
||||
builder: llvmlite.IRBuilder | t.CPtr,
|
||||
builder: rawptr[llvmlite.IRBuilder],
|
||||
mod: rawptr[llvmlite.LLVMModule],
|
||||
node: rawptr[ast.AST],
|
||||
trans: rawptr[HT.Translator] = None) -> llvmlite.Value | t.CPtr:
|
||||
trans: rawptr[HT.Translator] = None) -> rawptr[llvmlite.Value]:
|
||||
"""翻译二元运算(自动类型提升)"""
|
||||
binop: rawptr[ast.BinOp] = rawptr[ast.BinOp](node)
|
||||
if binop is None:
|
||||
@@ -1326,7 +1326,7 @@ class ExprGenOps(ExprGenBase.ExprGenBase):
|
||||
op: int = binop.op
|
||||
|
||||
# 先翻译 rhs(只翻译一次,避免副作用重复)
|
||||
rhs: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
|
||||
rhs: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, rhs_node, None, 0, trans)
|
||||
if rhs is None:
|
||||
return None
|
||||
@@ -1337,10 +1337,10 @@ class ExprGenOps(ExprGenBase.ExprGenBase):
|
||||
if lhs_node is not None and lhs_node.kind() == ast.ASTKind.Name and trans is not None:
|
||||
nm: rawptr[ast.Name] = rawptr[ast.Name](lhs_node)
|
||||
if nm is not None and nm.id is not None:
|
||||
lhs_alloca: llvmlite.Value | t.CPtr = self.Gen.VarGen.lookup_var(
|
||||
lhs_alloca: rawptr[llvmlite.Value] = self.Gen.VarGen.lookup_var(
|
||||
trans.SymTab, nm.id)
|
||||
if lhs_alloca is not None:
|
||||
ovl_self1: llvmlite.Value | t.CPtr = lhs_alloca
|
||||
ovl_self1: rawptr[llvmlite.Value] = lhs_alloca
|
||||
# alloca 是 Ptr(Ptr(Struct))(X|t.CPtr 对象存储槽)时,
|
||||
# load 出对象指针作为 self——若把槽地址当 self,dunder 内
|
||||
# load 槽内容(对象指针值)当字段读 → 垃圾(MultiInheritTest
|
||||
@@ -1348,23 +1348,23 @@ class ExprGenOps(ExprGenBase.ExprGenBase):
|
||||
# 递归解指针后路径 1 能识别 alloca,需同步修正 self 语义)
|
||||
if lhs_alloca.Ty is not None and lhs_alloca.Ty.Pointee is not None \
|
||||
and self.Gen.ExprGenBase.is_ptr_type(lhs_alloca.Ty.Pointee) != 0:
|
||||
load_self1: llvmlite.Value | t.CPtr = llvmlite.build_load(
|
||||
load_self1: rawptr[llvmlite.Value] = llvmlite.build_load(
|
||||
builder, lhs_alloca.Ty.Pointee, lhs_alloca)
|
||||
if load_self1 is not None:
|
||||
ovl_self1 = load_self1
|
||||
ovl_result: llvmlite.Value | t.CPtr = self.try_operator_overload(
|
||||
ovl_result: rawptr[llvmlite.Value] = self.try_operator_overload(
|
||||
pool, builder, mod, ovl_self1, rhs, op, trans, 0)
|
||||
if ovl_result is not None:
|
||||
return ovl_result
|
||||
|
||||
# 正常翻译 lhs
|
||||
lhs: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
|
||||
lhs: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, lhs_node, None, 0, trans)
|
||||
if lhs is None:
|
||||
return None
|
||||
|
||||
# === 运算符重载路径 2: lhs 是 Ptr(Struct)(如 Counter|t.CPtr 变量 load 后)===
|
||||
ovl_result2: llvmlite.Value | t.CPtr = self.try_operator_overload(
|
||||
ovl_result2: rawptr[llvmlite.Value] = self.try_operator_overload(
|
||||
pool, builder, mod, lhs, rhs, op, trans, 0)
|
||||
if ovl_result2 is not None:
|
||||
return ovl_result2
|
||||
|
||||
@@ -32,7 +32,7 @@ class FuncGenBase(CallGenBase.CallGenBase):
|
||||
# 返回 LLVM IR 属性字符串(如 "alwaysinline nounwind"),无属性返回 None
|
||||
# ============================================================
|
||||
def extract_func_attrs(self, pool: rawptr[memhub.MemBuddy],
|
||||
decorator_list: list[rawptr[ast.AST]] | t.CPtr,
|
||||
decorator_list: rawptr[list[rawptr[ast.AST]]],
|
||||
imported_modules: str) -> str:
|
||||
"""从 decorator_list 提取 c.Attribute 属性,返回 LLVM IR 属性字符串"""
|
||||
if decorator_list is None:
|
||||
@@ -84,7 +84,7 @@ class FuncGenBase(CallGenBase.CallGenBase):
|
||||
# 遍历参数提取属性
|
||||
if call_node.args is None:
|
||||
continue
|
||||
args_list: list[rawptr[ast.AST]] | t.CPtr = call_node.args
|
||||
args_list: rawptr[list[rawptr[ast.AST]]] = call_node.args
|
||||
an: sizet = len(args_list)
|
||||
for ai in range(an):
|
||||
arg_node: rawptr[ast.AST] = args_list.get(ai)
|
||||
@@ -108,7 +108,7 @@ class FuncGenBase(CallGenBase.CallGenBase):
|
||||
return None
|
||||
return attrs_buf
|
||||
def extract_func_section(self, pool: rawptr[memhub.MemBuddy],
|
||||
decorator_list: list[rawptr[ast.AST]] | t.CPtr,
|
||||
decorator_list: rawptr[list[rawptr[ast.AST]]],
|
||||
imported_modules: str) -> str:
|
||||
"""提取 @c.Attribute(t.attr.section("xxx")) 为属性组文本 '"section"="xxx"'。
|
||||
|
||||
@@ -133,7 +133,7 @@ class FuncGenBase(CallGenBase.CallGenBase):
|
||||
continue
|
||||
if call_node.args is None:
|
||||
continue
|
||||
args_list: list[rawptr[ast.AST]] | t.CPtr = call_node.args
|
||||
args_list: rawptr[list[rawptr[ast.AST]]] = call_node.args
|
||||
an: sizet = len(args_list)
|
||||
for ai in range(an):
|
||||
arg_node: rawptr[ast.AST] = args_list.get(ai)
|
||||
@@ -331,7 +331,7 @@ class FuncGenBase(CallGenBase.CallGenBase):
|
||||
"""函数体顶层是否含 raise(非 StopIteration),1=是 / 0=否"""
|
||||
if fd is None or fd.children is None:
|
||||
return 0
|
||||
body_f: list[rawptr[ast.AST]] | t.CPtr = fd.children
|
||||
body_f: rawptr[list[rawptr[ast.AST]]] = fd.children
|
||||
bn_f: sizet = len(body_f)
|
||||
for bi_f in range(bn_f):
|
||||
stmt_f: rawptr[ast.AST] = body_f.get(bi_f)
|
||||
@@ -339,7 +339,7 @@ class FuncGenBase(CallGenBase.CallGenBase):
|
||||
continue
|
||||
if stmt_f.kind() != ast.ASTKind.Raise:
|
||||
continue
|
||||
rn_f: ast.Raise | t.CPtr = (ast.Raise | t.CPtr)(stmt_f)
|
||||
rn_f: rawptr[ast.Raise] = rawptr[ast.Raise](stmt_f)
|
||||
if rn_f is None or rn_f.exc is None:
|
||||
continue
|
||||
ek_f: int = rn_f.exc.kind()
|
||||
@@ -388,7 +388,7 @@ class FuncGenBase(CallGenBase.CallGenBase):
|
||||
deco_fa_cr: rawptr[ast.Attribute] = rawptr[ast.Attribute](deco_call_cr.func)
|
||||
if deco_fa_cr.attr is None or string.strcmp(deco_fa_cr.attr, "CReturn") != 0:
|
||||
continue
|
||||
cr_args: list[rawptr[ast.AST]] | t.CPtr = deco_call_cr.args
|
||||
cr_args: rawptr[list[rawptr[ast.AST]]] = deco_call_cr.args
|
||||
if cr_args is None:
|
||||
continue
|
||||
cr_an: sizet = len(cr_args)
|
||||
@@ -427,7 +427,7 @@ class FuncGenBase(CallGenBase.CallGenBase):
|
||||
if args_node is not None:
|
||||
ags: rawptr[ast.Arguments] = rawptr[ast.Arguments](args_node)
|
||||
if ags.args is not None:
|
||||
alist: list[rawptr[ast.AST]] | t.CPtr = ags.args
|
||||
alist: rawptr[list[rawptr[ast.AST]]] = ags.args
|
||||
an: sizet = len(alist)
|
||||
i32_ty: rawptr[llvmlite.LLVMType] = llvmlite.Int32(pool)
|
||||
for ai in range(an):
|
||||
|
||||
@@ -49,7 +49,7 @@ class FuncGenDef(CallGenBase.CallGenBase):
|
||||
i8_ty: rawptr[llvmlite.LLVMType] = llvmlite.Int8(pool)
|
||||
i8_ptr_ty: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, i8_ty)
|
||||
|
||||
ch: list[rawptr[ast.AST]] | t.CPtr = tree.children
|
||||
ch: rawptr[list[rawptr[ast.AST]]] = tree.children
|
||||
if ch is None:
|
||||
return 0
|
||||
|
||||
@@ -85,7 +85,7 @@ class FuncGenDef(CallGenBase.CallGenBase):
|
||||
pre_cd: rawptr[ast.ClassDef] = rawptr[ast.ClassDef](pre_child)
|
||||
if pre_cd is None or pre_cd.name is None:
|
||||
continue
|
||||
pre_ex: GenTypes.StructEntry | t.CPtr = self.Gen.StructGen.find_struct_by_module(
|
||||
pre_ex: rawptr[GenTypes.StructEntry] = self.Gen.StructGen.find_struct_by_module(
|
||||
pre_cd.name, trans.ModuleSha1)
|
||||
if pre_ex is not None and pre_ex.FieldCount > 0:
|
||||
continue
|
||||
@@ -210,10 +210,10 @@ class FuncGenDef(CallGenBase.CallGenBase):
|
||||
if fd_args_node is not None:
|
||||
fd_ags: rawptr[ast.Arguments] = rawptr[ast.Arguments](fd_args_node)
|
||||
if fd_ags.args is not None:
|
||||
fd_alist: list[rawptr[ast.AST]] | t.CPtr = fd_ags.args
|
||||
fd_alist: rawptr[list[rawptr[ast.AST]]] = fd_ags.args
|
||||
fd_param_count = len(fd_alist)
|
||||
if fd_ags.defaults is not None:
|
||||
fd_dlist: list[rawptr[ast.AST]] | t.CPtr = fd_ags.defaults
|
||||
fd_dlist: rawptr[list[rawptr[ast.AST]]] = fd_ags.defaults
|
||||
fd_defaults = fd_dlist
|
||||
fd_default_count = len(fd_dlist)
|
||||
|
||||
@@ -234,7 +234,7 @@ class FuncGenDef(CallGenBase.CallGenBase):
|
||||
if args_node is not None:
|
||||
ags: rawptr[ast.Arguments] = rawptr[ast.Arguments](args_node)
|
||||
if ags.args is not None:
|
||||
alist: list[rawptr[ast.AST]] | t.CPtr = ags.args
|
||||
alist: rawptr[list[rawptr[ast.AST]]] = ags.args
|
||||
an: sizet = len(alist)
|
||||
for ai in range(an):
|
||||
arg: rawptr[ast.Arg] = rawptr[ast.Arg](alist.get(ai))
|
||||
@@ -512,7 +512,7 @@ class FuncGenDef(CallGenBase.CallGenBase):
|
||||
if args_node_extern is not None:
|
||||
ags_e: rawptr[ast.Arguments] = rawptr[ast.Arguments](args_node_extern)
|
||||
if ags_e.args is not None:
|
||||
alist_e: list[rawptr[ast.AST]] | t.CPtr = ags_e.args
|
||||
alist_e: rawptr[list[rawptr[ast.AST]]] = ags_e.args
|
||||
an_e: sizet = len(alist_e)
|
||||
for ai_e in range(an_e):
|
||||
arg_e: rawptr[ast.Arg] = rawptr[ast.Arg](alist_e.get(ai_e))
|
||||
@@ -611,10 +611,10 @@ class FuncGenDef(CallGenBase.CallGenBase):
|
||||
if args_node is not None:
|
||||
tfd_ags: rawptr[ast.Arguments] = rawptr[ast.Arguments](args_node)
|
||||
if tfd_ags.args is not None:
|
||||
tfd_alist: list[rawptr[ast.AST]] | t.CPtr = tfd_ags.args
|
||||
tfd_alist: rawptr[list[rawptr[ast.AST]]] = tfd_ags.args
|
||||
tfd_param_count = len(tfd_alist)
|
||||
if tfd_ags.defaults is not None:
|
||||
tfd_dlist: list[rawptr[ast.AST]] | t.CPtr = tfd_ags.defaults
|
||||
tfd_dlist: rawptr[list[rawptr[ast.AST]]] = tfd_ags.defaults
|
||||
tfd_defaults = tfd_dlist
|
||||
tfd_default_count = len(tfd_dlist)
|
||||
|
||||
@@ -629,7 +629,7 @@ class FuncGenDef(CallGenBase.CallGenBase):
|
||||
if args_node is not None:
|
||||
ags: rawptr[ast.Arguments] = rawptr[ast.Arguments](args_node)
|
||||
if ags.args is not None:
|
||||
alist: list[rawptr[ast.AST]] | t.CPtr = ags.args
|
||||
alist: rawptr[list[rawptr[ast.AST]]] = ags.args
|
||||
an: sizet = len(alist)
|
||||
for ai in range(an):
|
||||
arg: rawptr[ast.Arg] = rawptr[ast.Arg](alist.get(ai))
|
||||
@@ -690,12 +690,12 @@ class FuncGenDef(CallGenBase.CallGenBase):
|
||||
self.Gen.CallGenLeafKit.update_global_func_spec(fd.name, func)
|
||||
|
||||
# 创建 entry 块
|
||||
entry_blk: llvmlite.BasicBlock | t.CPtr = llvmlite.create_block(pool, func, "entry")
|
||||
entry_blk: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(pool, func, "entry")
|
||||
if entry_blk is None:
|
||||
return 0
|
||||
|
||||
# 创建函数专属 builder
|
||||
func_builder: llvmlite.IRBuilder | t.CPtr = llvmlite.new_builder(pool, func)
|
||||
func_builder: rawptr[llvmlite.IRBuilder] = llvmlite.new_builder(pool, func)
|
||||
if func_builder is None:
|
||||
return 0
|
||||
llvmlite.position_at_end(func_builder, entry_blk)
|
||||
@@ -707,7 +707,7 @@ class FuncGenDef(CallGenBase.CallGenBase):
|
||||
tls_flag_name: str = pool.alloc(128)
|
||||
if tls_flag_name is not None:
|
||||
viperlib.snprintf(tls_flag_name, 128, "__tls_init_done_%s", fd.name)
|
||||
tls_flag_gv: llvmlite.GlobalVariable | t.CPtr = llvmlite.create_global_int(
|
||||
tls_flag_gv: rawptr[llvmlite.GlobalVariable] = llvmlite.create_global_int(
|
||||
pool, mod, tls_flag_name, 1, 0)
|
||||
if tls_flag_gv is not None:
|
||||
i1_ty_t: rawptr[llvmlite.LLVMType] = llvmlite.Int1(pool)
|
||||
@@ -719,10 +719,10 @@ class FuncGenDef(CallGenBase.CallGenBase):
|
||||
tls_ref_name: str = pool.alloc(64)
|
||||
if tls_ref_name is not None:
|
||||
viperlib.snprintf(tls_ref_name, 64, "@%s", tls_flag_name)
|
||||
tls_flag_ref: llvmlite.Value | t.CPtr = llvmlite.SSAValue(
|
||||
tls_flag_ref: rawptr[llvmlite.Value] = llvmlite.SSAValue(
|
||||
pool, tls_gv_ptr_ty, tls_ref_name)
|
||||
if tls_flag_ref is not None:
|
||||
tls_flag_ld: llvmlite.Value | t.CPtr = llvmlite.build_load(
|
||||
tls_flag_ld: rawptr[llvmlite.Value] = llvmlite.build_load(
|
||||
func_builder, i1_ty_t, tls_flag_ref)
|
||||
# 块名唯一化(create_block 不自动编号,同函数同名 label 冲突)
|
||||
lc_t: int = trans._label_counter
|
||||
@@ -730,10 +730,10 @@ class FuncGenDef(CallGenBase.CallGenBase):
|
||||
tls_bb_buf: str = pool.alloc(64)
|
||||
if tls_bb_buf is not None:
|
||||
viperlib.snprintf(tls_bb_buf, 64, "tls.skip.%d", lc_t)
|
||||
tls_skip_bb: llvmlite.BasicBlock | t.CPtr = llvmlite.create_block(
|
||||
tls_skip_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(
|
||||
pool, func, tls_bb_buf)
|
||||
viperlib.snprintf(tls_bb_buf, 64, "tls.cont.%d", lc_t)
|
||||
tls_cont_bb: llvmlite.BasicBlock | t.CPtr = llvmlite.create_block(
|
||||
tls_cont_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(
|
||||
pool, func, tls_bb_buf)
|
||||
if tls_skip_bb is not None and tls_cont_bb is not None:
|
||||
llvmlite.build_cond_br(
|
||||
@@ -744,23 +744,23 @@ class FuncGenDef(CallGenBase.CallGenBase):
|
||||
case llvmlite.LLVMType.Void():
|
||||
llvmlite.build_ret_void(func_builder)
|
||||
case llvmlite.LLVMType.Int(_):
|
||||
tlz0: llvmlite.Value | t.CPtr = llvmlite.ConstInt(
|
||||
tlz0: rawptr[llvmlite.Value] = llvmlite.ConstInt(
|
||||
pool, ret_ty, 0, "0")
|
||||
if tlz0 is not None:
|
||||
llvmlite.build_ret(func_builder, tlz0)
|
||||
case llvmlite.LLVMType.Float(_):
|
||||
tlf0: llvmlite.Value | t.CPtr = llvmlite.ConstFloat(
|
||||
tlf0: rawptr[llvmlite.Value] = llvmlite.ConstFloat(
|
||||
pool, ret_ty, 0.0)
|
||||
if tlf0 is not None:
|
||||
llvmlite.build_ret(func_builder, tlf0)
|
||||
case _:
|
||||
tln0: llvmlite.Value | t.CPtr = llvmlite.ConstNull(
|
||||
tln0: rawptr[llvmlite.Value] = llvmlite.ConstNull(
|
||||
pool, ret_ty, "null")
|
||||
if tln0 is not None:
|
||||
llvmlite.build_ret(func_builder, tln0)
|
||||
# cont 块:置标志=1,继续函数体
|
||||
llvmlite.position_at_end(func_builder, tls_cont_bb)
|
||||
tlone: llvmlite.Value | t.CPtr = llvmlite.ConstInt(
|
||||
tlone: rawptr[llvmlite.Value] = llvmlite.ConstInt(
|
||||
pool, i1_ty_t, 1, "1")
|
||||
if tlone is not None:
|
||||
llvmlite.build_store(func_builder, tlone, tls_flag_ref)
|
||||
@@ -787,7 +787,7 @@ class FuncGenDef(CallGenBase.CallGenBase):
|
||||
if args_node is not None:
|
||||
ags2: rawptr[ast.Arguments] = rawptr[ast.Arguments](args_node)
|
||||
if ags2.args is not None:
|
||||
alist2: list[rawptr[ast.AST]] | t.CPtr = ags2.args
|
||||
alist2: rawptr[list[rawptr[ast.AST]]] = ags2.args
|
||||
an2: sizet = len(alist2)
|
||||
for ai2 in range(an2):
|
||||
arg2: rawptr[ast.Arg] = rawptr[ast.Arg](alist2.get(ai2))
|
||||
@@ -817,7 +817,7 @@ class FuncGenDef(CallGenBase.CallGenBase):
|
||||
param_ty2 = llvmlite.Ptr(pool, aelem_ty2)
|
||||
case _:
|
||||
param_ty2 = resolved2
|
||||
alloca: llvmlite.Value | t.CPtr = llvmlite.build_alloca(func_builder, param_ty2)
|
||||
alloca: rawptr[llvmlite.Value] = llvmlite.build_alloca(func_builder, param_ty2)
|
||||
if alloca is not None:
|
||||
self.Gen.VarGen.define_var(trans.SymTab, arg2.arg, alloca)
|
||||
# 存储原始类型注解的类名(方法调用检测时,Ptr(i8) 回退到类名查找结构体)
|
||||
@@ -832,7 +832,7 @@ class FuncGenDef(CallGenBase.CallGenBase):
|
||||
pname2: str = pool.alloc(32)
|
||||
if pname2 is not None:
|
||||
viperlib.snprintf(pname2, 32, "%%%s", arg2.arg)
|
||||
param_val: llvmlite.Value | t.CPtr = llvmlite.SSAValue(
|
||||
param_val: rawptr[llvmlite.Value] = llvmlite.SSAValue(
|
||||
pool, param_ty2, pname2)
|
||||
llvmlite.build_store(func_builder, param_val, alloca)
|
||||
|
||||
@@ -854,11 +854,11 @@ class FuncGenDef(CallGenBase.CallGenBase):
|
||||
i8_ty_va: rawptr[llvmlite.LLVMType] = llvmlite.Int8(pool)
|
||||
i8_ptr_ty_va: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, i8_ty_va)
|
||||
va_buf_ty: rawptr[llvmlite.LLVMType] = llvmlite.Array(pool, i8_ty_va, 24)
|
||||
va_list_alloca: llvmlite.Value | t.CPtr = llvmlite.build_alloca_aligned(
|
||||
va_list_alloca: rawptr[llvmlite.Value] = llvmlite.build_alloca_aligned(
|
||||
func_builder, va_buf_ty, 16)
|
||||
if va_list_alloca is not None:
|
||||
# i8* 地址(指向 24 字节 va_list 缓冲区)——vararg 名的值语义
|
||||
va_list_addr: llvmlite.Value | t.CPtr = llvmlite.build_bitcast(
|
||||
va_list_addr: rawptr[llvmlite.Value] = llvmlite.build_bitcast(
|
||||
func_builder, va_list_alloca, i8_ptr_ty_va)
|
||||
if va_list_addr is not None:
|
||||
# 注册到符号表(translate_name_value 对 vararg 名特殊处理返回地址)
|
||||
@@ -875,8 +875,8 @@ class FuncGenDef(CallGenBase.CallGenBase):
|
||||
# (调用方/包围函数)的 EH 输出参数,翻译完本函数后再恢复——否则
|
||||
# 下方设置本函数 EH 参数会覆盖外层值,恢复时 old_eh_* 拿到的是
|
||||
# 本函数自身参数(嵌套函数/多函数链 EH 状态错乱)。
|
||||
old_eh_msg_out: llvmlite.Value | t.CPtr = trans._eh_msg_out_param
|
||||
old_eh_code_out: llvmlite.Value | t.CPtr = trans._eh_code_out_param
|
||||
old_eh_msg_out: rawptr[llvmlite.Value] = trans._eh_msg_out_param
|
||||
old_eh_code_out: rawptr[llvmlite.Value] = trans._eh_code_out_param
|
||||
old_cur_func_has_eh: int = trans._cur_func_has_eh
|
||||
trans._eh_msg_out_param = None
|
||||
trans._eh_code_out_param = None
|
||||
@@ -891,9 +891,9 @@ class FuncGenDef(CallGenBase.CallGenBase):
|
||||
i32_ty_eh2: rawptr[llvmlite.LLVMType] = llvmlite.Int32(pool)
|
||||
i32_ptr_ty_eh2: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, i32_ty_eh2)
|
||||
if i8_ptr_ptr_ty_eh2 is not None and i32_ptr_ty_eh2 is not None:
|
||||
msg_out_ref: llvmlite.Value | t.CPtr = llvmlite.SSAValue(
|
||||
msg_out_ref: rawptr[llvmlite.Value] = llvmlite.SSAValue(
|
||||
pool, i8_ptr_ptr_ty_eh2, "%__eh_msg_out__")
|
||||
code_out_ref: llvmlite.Value | t.CPtr = llvmlite.SSAValue(
|
||||
code_out_ref: rawptr[llvmlite.Value] = llvmlite.SSAValue(
|
||||
pool, i32_ptr_ty_eh2, "%__eh_code_out__")
|
||||
trans._eh_msg_out_param = msg_out_ref
|
||||
trans._eh_code_out_param = code_out_ref
|
||||
@@ -901,11 +901,11 @@ class FuncGenDef(CallGenBase.CallGenBase):
|
||||
|
||||
# 保存模块级作用域状态(仅非变量表相关)
|
||||
old_func: rawptr[llvmlite.Function] = trans._cur_func
|
||||
old_builder: llvmlite.IRBuilder | t.CPtr = trans._cur_builder
|
||||
old_builder: rawptr[llvmlite.IRBuilder] = trans._cur_builder
|
||||
old_global_count: int = trans._global_name_count
|
||||
old_nonlocal_count: int = trans._nonlocal_name_count
|
||||
old_env_count: int = trans._closure_env_count
|
||||
old_va_list_ptr: llvmlite.Value | t.CPtr = trans._va_list_ptr
|
||||
old_va_list_ptr: rawptr[llvmlite.Value] = trans._va_list_ptr
|
||||
old_vararg_name: str = trans._vararg_name
|
||||
# 返回注解上下文([C①] 裸名泛型构造的类型实参回退来源之一):
|
||||
# 进入函数体前记录本函数返回注解,退出时恢复外层函数的值
|
||||
@@ -924,7 +924,7 @@ class FuncGenDef(CallGenBase.CallGenBase):
|
||||
# 1. 先预扫描 Global/Nonlocal 声明(Python 语义:global/nonlocal
|
||||
# 对整个函数作用域生效,与声明位置无关,故须在任何赋值前注册)
|
||||
# 2. 再预扫描 AnnAssign 为局部变量提前创建 alloca
|
||||
body: list[rawptr[ast.AST]] | t.CPtr = fd.children
|
||||
body: rawptr[list[rawptr[ast.AST]]] = fd.children
|
||||
if body is not None:
|
||||
bn: sizet = len(body)
|
||||
for bi in range(bn):
|
||||
@@ -1023,7 +1023,7 @@ class FuncGenDef(CallGenBase.CallGenBase):
|
||||
elif fd.returns is None:
|
||||
# 无返回类型注解 → 无返回值过程函数,默认零值返回
|
||||
if ret_ty is not None:
|
||||
zero_val: llvmlite.Value | t.CPtr = llvmlite.ConstZero(pool, ret_ty)
|
||||
zero_val: rawptr[llvmlite.Value] = llvmlite.ConstZero(pool, ret_ty)
|
||||
if zero_val is not None:
|
||||
llvmlite.build_ret(func_builder, zero_val)
|
||||
else:
|
||||
@@ -1131,7 +1131,7 @@ class FuncGenDef(CallGenBase.CallGenBase):
|
||||
if param_tys is None:
|
||||
return None
|
||||
string.memset(param_tys, 0, 16 * 8)
|
||||
pp: llvmlite.Param | t.CPtr = llvmlite.function_get_param_head(func)
|
||||
pp: rawptr[llvmlite.Param] = llvmlite.function_get_param_head(func)
|
||||
while pp is not None:
|
||||
pty: rawptr[llvmlite.LLVMType] = llvmlite.param_get_ty(pp)
|
||||
if pty is not None and n_params < 16:
|
||||
@@ -1152,15 +1152,15 @@ class FuncGenDef(CallGenBase.CallGenBase):
|
||||
llvmlite.add_param(pool, wrapper, (rawptr[llvmlite.LLVMType])(param_tys[pi]), pname_w)
|
||||
|
||||
# ---- 创建块 ----
|
||||
entry_bb: llvmlite.BasicBlock | t.CPtr = llvmlite.create_block(pool, wrapper, "entry")
|
||||
loop_h_bb: llvmlite.BasicBlock | t.CPtr = llvmlite.create_block(pool, wrapper, "loop.header")
|
||||
loop_b_bb: llvmlite.BasicBlock | t.CPtr = llvmlite.create_block(pool, wrapper, "loop.body")
|
||||
post_bb: llvmlite.BasicBlock | t.CPtr = llvmlite.create_block(pool, wrapper, "post")
|
||||
entry_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(pool, wrapper, "entry")
|
||||
loop_h_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(pool, wrapper, "loop.header")
|
||||
loop_b_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(pool, wrapper, "loop.body")
|
||||
post_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(pool, wrapper, "post")
|
||||
if entry_bb is None or loop_h_bb is None or loop_b_bb is None or post_bb is None:
|
||||
return None
|
||||
|
||||
# 递归保护标志(最外层):@__decor_rec_{wrapper} = global i8 0
|
||||
rec_flag_ref: llvmlite.Value | t.CPtr = None
|
||||
rec_flag_ref: rawptr[llvmlite.Value] = None
|
||||
rec_flag_name: str = pool.alloc(128)
|
||||
if rec_flag_name is not None:
|
||||
viperlib.snprintf(rec_flag_name, 128, "__decor_rec_%s", wrapper_name)
|
||||
@@ -1170,7 +1170,7 @@ class FuncGenDef(CallGenBase.CallGenBase):
|
||||
viperlib.snprintf(rec_ref_nm, 96, "@%s", rec_flag_name)
|
||||
rec_flag_ref = llvmlite.SSAValue(pool, llvmlite.Ptr(pool, i8_ty), rec_ref_nm)
|
||||
|
||||
wb: llvmlite.IRBuilder | t.CPtr = llvmlite.new_builder(pool, wrapper)
|
||||
wb: rawptr[llvmlite.IRBuilder] = llvmlite.new_builder(pool, wrapper)
|
||||
if wb is None:
|
||||
return None
|
||||
|
||||
@@ -1184,27 +1184,27 @@ class FuncGenDef(CallGenBase.CallGenBase):
|
||||
|
||||
# ---- entry:递归保护检查(最外层)----
|
||||
llvmlite.position_at_end(wb, entry_bb)
|
||||
loop_pred_bb: llvmlite.BasicBlock | t.CPtr = entry_bb
|
||||
loop_pred_bb: rawptr[llvmlite.BasicBlock] = entry_bb
|
||||
if rec_flag_ref is not None:
|
||||
rec_bb: llvmlite.BasicBlock | t.CPtr = llvmlite.create_block(pool, wrapper, "recursive_call")
|
||||
dec_bb: llvmlite.BasicBlock | t.CPtr = llvmlite.create_block(pool, wrapper, "decorated_entry")
|
||||
rec_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(pool, wrapper, "recursive_call")
|
||||
dec_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(pool, wrapper, "decorated_entry")
|
||||
if rec_bb is None or dec_bb is None:
|
||||
return None
|
||||
rec_val: llvmlite.Value | t.CPtr = llvmlite.build_load(wb, i8_ty, rec_flag_ref)
|
||||
rec_zero: llvmlite.Value | t.CPtr = llvmlite.ConstInt(pool, i8_ty, 0, "0")
|
||||
rec_is: llvmlite.Value | t.CPtr = llvmlite.build_icmp(
|
||||
rec_val: rawptr[llvmlite.Value] = llvmlite.build_load(wb, i8_ty, rec_flag_ref)
|
||||
rec_zero: rawptr[llvmlite.Value] = llvmlite.ConstInt(pool, i8_ty, 0, "0")
|
||||
rec_is: rawptr[llvmlite.Value] = llvmlite.build_icmp(
|
||||
wb, llvmlite.ICMP_NE, rec_val, rec_zero)
|
||||
llvmlite.build_cond_br(wb, rec_is, rec_bb, dec_bb)
|
||||
# recursive_call:直接调用原函数返回(跳过所有装饰逻辑)
|
||||
llvmlite.position_at_end(wb, rec_bb)
|
||||
rec_args: llvmlite.Value | t.CPtr = None
|
||||
rec_args: rawptr[llvmlite.Value] = None
|
||||
ri: int = 0
|
||||
for ri in range(n_params):
|
||||
an_r: str = pool.alloc(16)
|
||||
if an_r is None:
|
||||
continue
|
||||
viperlib.snprintf(an_r, 16, "%%a%d", ri)
|
||||
av_r: llvmlite.Value | t.CPtr = llvmlite.SSAValue(
|
||||
av_r: rawptr[llvmlite.Value] = llvmlite.SSAValue(
|
||||
pool, (rawptr[llvmlite.LLVMType])(param_tys[ri]), an_r)
|
||||
if av_r is not None:
|
||||
llvmlite.value_set_next(av_r, None)
|
||||
@@ -1212,7 +1212,7 @@ class FuncGenDef(CallGenBase.CallGenBase):
|
||||
rec_args = av_r
|
||||
else:
|
||||
# 链尾追加
|
||||
rt: llvmlite.Value | t.CPtr = rec_args
|
||||
rt: rawptr[llvmlite.Value] = rec_args
|
||||
while rt.Next is not None:
|
||||
rt = rt.Next
|
||||
llvmlite.value_set_next(rt, av_r)
|
||||
@@ -1220,7 +1220,7 @@ class FuncGenDef(CallGenBase.CallGenBase):
|
||||
llvmlite.build_call(wb, orig_call_name, rec_args, n_params, ret_ty, 0)
|
||||
llvmlite.build_ret_void(wb)
|
||||
else:
|
||||
rc_res: llvmlite.Value | t.CPtr = llvmlite.build_call(
|
||||
rc_res: rawptr[llvmlite.Value] = llvmlite.build_call(
|
||||
wb, orig_call_name, rec_args, n_params, ret_ty, 0)
|
||||
if rc_res is not None:
|
||||
llvmlite.build_ret(wb, rc_res)
|
||||
@@ -1228,7 +1228,7 @@ class FuncGenDef(CallGenBase.CallGenBase):
|
||||
llvmlite.build_ret_void(wb)
|
||||
# decorated_entry:置递归标志,继续装饰路径
|
||||
llvmlite.position_at_end(wb, dec_bb)
|
||||
rec_one: llvmlite.Value | t.CPtr = llvmlite.ConstInt(pool, i8_ty, 1, "1")
|
||||
rec_one: rawptr[llvmlite.Value] = llvmlite.ConstInt(pool, i8_ty, 1, "1")
|
||||
if rec_one is not None:
|
||||
llvmlite.build_store(wb, rec_one, rec_flag_ref)
|
||||
loop_pred_bb = dec_bb
|
||||
@@ -1236,12 +1236,12 @@ class FuncGenDef(CallGenBase.CallGenBase):
|
||||
# ---- 公共装饰路径(entry 或 decorated_entry)----
|
||||
# 1. ctx = alloca [32 x i8]; ctx_ptr = bitcast i8*
|
||||
ctx_ty: rawptr[llvmlite.LLVMType] = llvmlite.Array(pool, i8_ty, 32)
|
||||
ctx_alloca: llvmlite.Value | t.CPtr = llvmlite.build_alloca(wb, ctx_ty)
|
||||
ctx_ptr: llvmlite.Value | t.CPtr = llvmlite.build_bitcast(wb, ctx_alloca, i8_ptr_ty)
|
||||
ctx_alloca: rawptr[llvmlite.Value] = llvmlite.build_alloca(wb, ctx_ty)
|
||||
ctx_ptr: rawptr[llvmlite.Value] = llvmlite.build_bitcast(wb, ctx_alloca, i8_ptr_ty)
|
||||
|
||||
# 2. 打包函数参数到结构体 {param_types}(装饰器可读写 args_ptr)
|
||||
args_alloca: llvmlite.Value | t.CPtr = None
|
||||
args_ptr: llvmlite.Value | t.CPtr = None
|
||||
args_alloca: rawptr[llvmlite.Value] = None
|
||||
args_ptr: rawptr[llvmlite.Value] = None
|
||||
if n_params > 0:
|
||||
fields_head: rawptr[llvmlite.Function] = None
|
||||
fk: int = 0
|
||||
@@ -1258,13 +1258,13 @@ class FuncGenDef(CallGenBase.CallGenBase):
|
||||
fi2: int = 0
|
||||
for fi2 in range(n_params):
|
||||
fld_ty: rawptr[llvmlite.LLVMType] = (rawptr[llvmlite.LLVMType])(param_tys[fi2])
|
||||
fld_ptr: llvmlite.Value | t.CPtr = llvmlite.build_gep_struct(
|
||||
fld_ptr: rawptr[llvmlite.Value] = llvmlite.build_gep_struct(
|
||||
wb, args_ty, fld_ty, args_alloca, fi2)
|
||||
if fld_ptr is not None:
|
||||
fld_nm: str = pool.alloc(16)
|
||||
if fld_nm is not None:
|
||||
viperlib.snprintf(fld_nm, 16, "%%a%d", fi2)
|
||||
fld_v: llvmlite.Value | t.CPtr = llvmlite.SSAValue(
|
||||
fld_v: rawptr[llvmlite.Value] = llvmlite.SSAValue(
|
||||
pool, fld_ty, fld_nm)
|
||||
if fld_v is not None:
|
||||
llvmlite.build_store(wb, fld_v, fld_ptr)
|
||||
@@ -1273,10 +1273,10 @@ class FuncGenDef(CallGenBase.CallGenBase):
|
||||
args_ptr = llvmlite.ConstNull(pool, i8_ptr_ty, "null")
|
||||
|
||||
# 3. 返回值存储(零初始化;跳过原函数时返回安全默认值)
|
||||
ret_alloca: llvmlite.Value | t.CPtr = None
|
||||
ret_alloca: rawptr[llvmlite.Value] = None
|
||||
if ret_is_void == 0:
|
||||
ret_alloca = llvmlite.build_alloca(wb, ret_ty)
|
||||
ret_zero: llvmlite.Value | t.CPtr = None
|
||||
ret_zero: rawptr[llvmlite.Value] = None
|
||||
match ret_ty:
|
||||
case llvmlite.LLVMType.Int(_):
|
||||
ret_zero = llvmlite.ConstInt(pool, ret_ty, 0, "0")
|
||||
@@ -1288,7 +1288,7 @@ class FuncGenDef(CallGenBase.CallGenBase):
|
||||
llvmlite.build_store(wb, ret_zero, ret_alloca)
|
||||
|
||||
# 4. 函数名字符串常量
|
||||
fn_str: llvmlite.Value | t.CPtr = self.Gen.ExprGenConst.create_global_string(
|
||||
fn_str: rawptr[llvmlite.Value] = self.Gen.ExprGenConst.create_global_string(
|
||||
wb, pool, mod, func_name, trans)
|
||||
if fn_str is None:
|
||||
fn_str = llvmlite.ConstNull(pool, i8_ptr_ty, "null")
|
||||
@@ -1306,9 +1306,9 @@ class FuncGenDef(CallGenBase.CallGenBase):
|
||||
llvmlite.add_param(pool, handler_d, i8_ptr_ty, "decor_args_ptr")
|
||||
|
||||
# 6. 前置阶段:handler 返回调用次数 n_calls
|
||||
ph0: llvmlite.Value | t.CPtr = llvmlite.ConstInt(pool, i32_ty, 0, "0")
|
||||
null_ret: llvmlite.Value | t.CPtr = llvmlite.ConstNull(pool, i8_ptr_ty, "null")
|
||||
null_dec: llvmlite.Value | t.CPtr = llvmlite.ConstNull(pool, i8_ptr_ty, "null")
|
||||
ph0: rawptr[llvmlite.Value] = llvmlite.ConstInt(pool, i32_ty, 0, "0")
|
||||
null_ret: rawptr[llvmlite.Value] = llvmlite.ConstNull(pool, i8_ptr_ty, "null")
|
||||
null_dec: rawptr[llvmlite.Value] = llvmlite.ConstNull(pool, i8_ptr_ty, "null")
|
||||
# 参数链表(6 个独立值):ctx_ptr → fn_str → 0 → args_ptr → null → null
|
||||
# 注意:不能 self 链接(null.Next = null 会让 build_call 遍历死循环)
|
||||
if ctx_ptr is not None:
|
||||
@@ -1321,49 +1321,49 @@ class FuncGenDef(CallGenBase.CallGenBase):
|
||||
llvmlite.value_set_next(args_ptr, null_ret)
|
||||
if null_ret is not None:
|
||||
llvmlite.value_set_next(null_ret, null_dec)
|
||||
n_calls: llvmlite.Value | t.CPtr = llvmlite.build_call(
|
||||
n_calls: rawptr[llvmlite.Value] = llvmlite.build_call(
|
||||
wb, handler_name, ctx_ptr, 6, i32_ty, 0)
|
||||
|
||||
# 7. 计数器 alloca(TPV 用 alloca 计数器替代 phi)
|
||||
cnt_alloca: llvmlite.Value | t.CPtr = llvmlite.build_alloca(wb, i32_ty)
|
||||
cnt_zero: llvmlite.Value | t.CPtr = llvmlite.ConstInt(pool, i32_ty, 0, "0")
|
||||
cnt_alloca: rawptr[llvmlite.Value] = llvmlite.build_alloca(wb, i32_ty)
|
||||
cnt_zero: rawptr[llvmlite.Value] = llvmlite.ConstInt(pool, i32_ty, 0, "0")
|
||||
if cnt_alloca is not None and cnt_zero is not None:
|
||||
llvmlite.build_store(wb, cnt_zero, cnt_alloca)
|
||||
llvmlite.build_br(wb, loop_h_bb)
|
||||
|
||||
# 8. loop.header:cur = load cnt; cur < n_calls → body / post
|
||||
llvmlite.position_at_end(wb, loop_h_bb)
|
||||
cur_i: llvmlite.Value | t.CPtr = llvmlite.build_load(wb, i32_ty, cnt_alloca)
|
||||
loop_cond: llvmlite.Value | t.CPtr = llvmlite.build_icmp(
|
||||
cur_i: rawptr[llvmlite.Value] = llvmlite.build_load(wb, i32_ty, cnt_alloca)
|
||||
loop_cond: rawptr[llvmlite.Value] = llvmlite.build_icmp(
|
||||
wb, llvmlite.ICMP_SLT, cur_i, n_calls)
|
||||
llvmlite.build_cond_br(wb, loop_cond, loop_b_bb, post_bb)
|
||||
|
||||
# 9. loop.body:读回参数(装饰器可能已修改)→ 调用原函数 → store ret
|
||||
llvmlite.position_at_end(wb, loop_b_bb)
|
||||
call_args: llvmlite.Value | t.CPtr = None
|
||||
call_args: rawptr[llvmlite.Value] = None
|
||||
if n_params > 0:
|
||||
k: int = 0
|
||||
for k in range(n_params):
|
||||
fld_ty_k: rawptr[llvmlite.LLVMType] = (rawptr[llvmlite.LLVMType])(param_tys[k])
|
||||
fld_pk: llvmlite.Value | t.CPtr = llvmlite.build_gep_struct(
|
||||
fld_pk: rawptr[llvmlite.Value] = llvmlite.build_gep_struct(
|
||||
wb, args_ty, fld_ty_k, args_alloca, k)
|
||||
if fld_pk is None:
|
||||
continue
|
||||
fld_vk: llvmlite.Value | t.CPtr = llvmlite.build_load(wb, fld_ty_k, fld_pk)
|
||||
fld_vk: rawptr[llvmlite.Value] = llvmlite.build_load(wb, fld_ty_k, fld_pk)
|
||||
if fld_vk is not None:
|
||||
llvmlite.value_set_next(fld_vk, None)
|
||||
if call_args is None:
|
||||
call_args = fld_vk
|
||||
else:
|
||||
ct: llvmlite.Value | t.CPtr = call_args
|
||||
ct: rawptr[llvmlite.Value] = call_args
|
||||
while ct.Next is not None:
|
||||
ct = ct.Next
|
||||
llvmlite.value_set_next(ct, fld_vk)
|
||||
res_v: llvmlite.Value | t.CPtr = llvmlite.build_call(
|
||||
res_v: rawptr[llvmlite.Value] = llvmlite.build_call(
|
||||
wb, orig_call_name, call_args, n_params, ret_ty, 0)
|
||||
if ret_alloca is not None and res_v is not None:
|
||||
llvmlite.build_store(wb, res_v, ret_alloca)
|
||||
nxt_i: llvmlite.Value | t.CPtr = llvmlite.build_add(
|
||||
nxt_i: rawptr[llvmlite.Value] = llvmlite.build_add(
|
||||
wb, cur_i, llvmlite.ConstInt(pool, i32_ty, 1, "1"))
|
||||
if nxt_i is not None and cnt_alloca is not None:
|
||||
llvmlite.build_store(wb, nxt_i, cnt_alloca)
|
||||
@@ -1371,10 +1371,10 @@ class FuncGenDef(CallGenBase.CallGenBase):
|
||||
|
||||
# 10. post:handler 后置 → 清递归标志 → 返回结果
|
||||
llvmlite.position_at_end(wb, post_bb)
|
||||
ret_ptr: llvmlite.Value | t.CPtr = null_ret
|
||||
ret_ptr: rawptr[llvmlite.Value] = null_ret
|
||||
if ret_alloca is not None:
|
||||
ret_ptr = llvmlite.build_bitcast(wb, ret_alloca, i8_ptr_ty)
|
||||
ph1: llvmlite.Value | t.CPtr = llvmlite.ConstInt(pool, i32_ty, 1, "1")
|
||||
ph1: rawptr[llvmlite.Value] = llvmlite.ConstInt(pool, i32_ty, 1, "1")
|
||||
# 后置参数链:ctx_ptr → fn_str → 1 → args_ptr → ret_ptr → null
|
||||
if ctx_ptr is not None:
|
||||
llvmlite.value_set_next(ctx_ptr, fn_str)
|
||||
@@ -1388,13 +1388,13 @@ class FuncGenDef(CallGenBase.CallGenBase):
|
||||
llvmlite.value_set_next(ret_ptr, null_dec)
|
||||
llvmlite.build_call(wb, handler_name, ctx_ptr, 6, i32_ty, 0)
|
||||
if rec_flag_ref is not None:
|
||||
rec_zero2: llvmlite.Value | t.CPtr = llvmlite.ConstInt(pool, i8_ty, 0, "0")
|
||||
rec_zero2: rawptr[llvmlite.Value] = llvmlite.ConstInt(pool, i8_ty, 0, "0")
|
||||
if rec_zero2 is not None:
|
||||
llvmlite.build_store(wb, rec_zero2, rec_flag_ref)
|
||||
if ret_is_void != 0:
|
||||
llvmlite.build_ret_void(wb)
|
||||
else:
|
||||
final_v: llvmlite.Value | t.CPtr = llvmlite.build_load(wb, ret_ty, ret_alloca)
|
||||
final_v: rawptr[llvmlite.Value] = llvmlite.build_load(wb, ret_ty, ret_alloca)
|
||||
if final_v is not None:
|
||||
llvmlite.build_ret(wb, final_v)
|
||||
else:
|
||||
|
||||
@@ -113,7 +113,7 @@ class FuncGenMixin(CallGenBase.CallGenBase):
|
||||
if fd.args is not None:
|
||||
ags_n: rawptr[ast.Arguments] = rawptr[ast.Arguments](fd.args)
|
||||
if ags_n.args is not None:
|
||||
alist_n: list[rawptr[ast.AST]] | t.CPtr = ags_n.args
|
||||
alist_n: rawptr[list[rawptr[ast.AST]]] = ags_n.args
|
||||
an_n: sizet = len(alist_n)
|
||||
for ai_n in range(an_n):
|
||||
arg_n: rawptr[ast.Arg] = rawptr[ast.Arg](alist_n.get(ai_n))
|
||||
@@ -145,10 +145,10 @@ class FuncGenMixin(CallGenBase.CallGenBase):
|
||||
param_count += 1
|
||||
|
||||
# 3. 创建 entry 块 + builder
|
||||
entry_blk: llvmlite.BasicBlock | t.CPtr = llvmlite.create_block(pool, func, "entry")
|
||||
entry_blk: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(pool, func, "entry")
|
||||
if entry_blk is None:
|
||||
return 0
|
||||
func_builder: llvmlite.IRBuilder | t.CPtr = llvmlite.new_builder(pool, func)
|
||||
func_builder: rawptr[llvmlite.IRBuilder] = llvmlite.new_builder(pool, func)
|
||||
if func_builder is None:
|
||||
return 0
|
||||
llvmlite.position_at_end(func_builder, entry_blk)
|
||||
@@ -157,10 +157,10 @@ class FuncGenMixin(CallGenBase.CallGenBase):
|
||||
self.Gen.VarGen.enter_scope(trans.SymTab, SCOPE_FUNCTION)
|
||||
|
||||
# 5. 创建 _env_ptr alloca 并存储 %env 参数
|
||||
env_alloca: llvmlite.Value | t.CPtr = llvmlite.build_alloca(func_builder, i8_ptr_ty)
|
||||
env_alloca: rawptr[llvmlite.Value] = llvmlite.build_alloca(func_builder, i8_ptr_ty)
|
||||
if env_alloca is not None:
|
||||
self.Gen.VarGen.define_var(trans.SymTab, "_env_ptr", env_alloca)
|
||||
env_param_val: llvmlite.Value | t.CPtr = llvmlite.SSAValue(pool, i8_ptr_ty, "%env")
|
||||
env_param_val: rawptr[llvmlite.Value] = llvmlite.SSAValue(pool, i8_ptr_ty, "%env")
|
||||
llvmlite.build_store(func_builder, env_param_val, env_alloca)
|
||||
|
||||
# 5a. 创建嵌套函数参数 alloca(函数体内参数名可引用,如
|
||||
@@ -168,7 +168,7 @@ class FuncGenMixin(CallGenBase.CallGenBase):
|
||||
if fd.args is not None:
|
||||
ags_p: rawptr[ast.Arguments] = rawptr[ast.Arguments](fd.args)
|
||||
if ags_p.args is not None:
|
||||
alist_p: list[rawptr[ast.AST]] | t.CPtr = ags_p.args
|
||||
alist_p: rawptr[list[rawptr[ast.AST]]] = ags_p.args
|
||||
idx_p: int = 0
|
||||
apn: sizet = len(alist_p)
|
||||
for api in range(apn):
|
||||
@@ -187,7 +187,7 @@ class FuncGenMixin(CallGenBase.CallGenBase):
|
||||
pty2_n = (rawptr[llvmlite.LLVMType])(ty_slot_n[0])
|
||||
if pty2_n is None:
|
||||
pty2_n = i32_ty
|
||||
p_alloca: llvmlite.Value | t.CPtr = llvmlite.build_alloca(func_builder, pty2_n)
|
||||
p_alloca: rawptr[llvmlite.Value] = llvmlite.build_alloca(func_builder, pty2_n)
|
||||
if p_alloca is not None:
|
||||
self.Gen.VarGen.define_var(trans.SymTab, arg_p.arg, p_alloca)
|
||||
if arg_p.annotation is not None:
|
||||
@@ -199,13 +199,13 @@ class FuncGenMixin(CallGenBase.CallGenBase):
|
||||
pname2_n: str = pool.alloc(32)
|
||||
if pname2_n is not None:
|
||||
viperlib.snprintf(pname2_n, 32, "%%%s", arg_p.arg)
|
||||
p_val: llvmlite.Value | t.CPtr = llvmlite.SSAValue(pool, pty2_n, pname2_n)
|
||||
p_val: rawptr[llvmlite.Value] = llvmlite.SSAValue(pool, pty2_n, pname2_n)
|
||||
llvmlite.build_store(func_builder, p_val, p_alloca)
|
||||
idx_p += 1
|
||||
|
||||
# 6. 保存父函数作用域状态(仅非变量表相关)
|
||||
old_func: rawptr[llvmlite.Function] = trans._cur_func
|
||||
old_builder: llvmlite.IRBuilder | t.CPtr = trans._cur_builder
|
||||
old_builder: rawptr[llvmlite.IRBuilder] = trans._cur_builder
|
||||
old_func_name: str = trans._cur_func_name
|
||||
old_global_count: int = trans._global_name_count
|
||||
old_nonlocal_count: int = trans._nonlocal_name_count
|
||||
@@ -232,7 +232,7 @@ class FuncGenMixin(CallGenBase.CallGenBase):
|
||||
# 8. 预扫描函数体:
|
||||
# a. 先预扫描 Global/Nonlocal 声明(Python 语义:对整个函数作用域生效)
|
||||
# b. 再预扫描 AnnAssign 为局部变量提前创建 alloca
|
||||
body: list[rawptr[ast.AST]] | t.CPtr = fd.children
|
||||
body: rawptr[list[rawptr[ast.AST]]] = fd.children
|
||||
if body is not None:
|
||||
bn: sizet = len(body)
|
||||
for bi in range(bn):
|
||||
@@ -273,7 +273,7 @@ class FuncGenMixin(CallGenBase.CallGenBase):
|
||||
if last_stmt is not None and last_stmt.kind() == ast.ASTKind.Return:
|
||||
last_is_return = 1
|
||||
if last_is_return == 0:
|
||||
zero_val: llvmlite.Value | t.CPtr = llvmlite.const_int32(pool, 0)
|
||||
zero_val: rawptr[llvmlite.Value] = llvmlite.const_int32(pool, 0)
|
||||
llvmlite.build_ret(func_builder, zero_val)
|
||||
|
||||
# 11. 保存嵌套函数的 nonlocal 信息
|
||||
@@ -286,7 +286,7 @@ class FuncGenMixin(CallGenBase.CallGenBase):
|
||||
# NOTE: _nonlocal_names 和 _nonlocal_name_count 仍为嵌套函数的值
|
||||
|
||||
# 13. 在父函数中创建闭包对象
|
||||
parent_builder: llvmlite.IRBuilder | t.CPtr = old_builder
|
||||
parent_builder: rawptr[llvmlite.IRBuilder] = old_builder
|
||||
if parent_builder is None:
|
||||
# 无 builder(模块级嵌套函数?)→ 无法创建闭包,仅恢复状态
|
||||
trans._cur_func_name = old_func_name
|
||||
@@ -299,10 +299,10 @@ class FuncGenMixin(CallGenBase.CallGenBase):
|
||||
|
||||
# 13a. 创建 env: malloc(8 * nested_nonlocal_count) — env 存储指针数组
|
||||
# 每个 nonlocal 变量占 8 字节(i8*),指向父函数的 alloca(共享存储)
|
||||
env_ptr: llvmlite.Value | t.CPtr = None
|
||||
env_ptr: rawptr[llvmlite.Value] = None
|
||||
if nested_nonlocal_count > 0:
|
||||
env_size: int64 = nested_nonlocal_count * 8
|
||||
env_size_val: llvmlite.Value | t.CPtr = llvmlite.const_int64(pool, env_size)
|
||||
env_size_val: rawptr[llvmlite.Value] = llvmlite.const_int64(pool, env_size)
|
||||
if env_size_val is not None:
|
||||
env_size_val.Next = None
|
||||
env_ptr = llvmlite.build_call(
|
||||
@@ -327,7 +327,7 @@ class FuncGenMixin(CallGenBase.CallGenBase):
|
||||
nl_name: str = nl_slot[0]
|
||||
if nl_name is None:
|
||||
continue
|
||||
heap_store: llvmlite.Value | t.CPtr = None
|
||||
heap_store: rawptr[llvmlite.Value] = None
|
||||
# 1. 优先查全局堆地址映射(_prepare_chain_nonlocals 已为
|
||||
# 链内 nonlocal 建堆并 store 到 @nlheap.*;不同层捕获
|
||||
# 不同变量时(ClosureTest2 Test 7)level2 的 b 经此共享)
|
||||
@@ -335,47 +335,47 @@ class FuncGenMixin(CallGenBase.CallGenBase):
|
||||
pool, trans, nl_name)
|
||||
if gname_ck is not None \
|
||||
and self._nl_heap_global_exists(mod, gname_ck) != 0:
|
||||
gv_ref0: llvmlite.Value | t.CPtr = self._nl_heap_global_ref(
|
||||
gv_ref0: rawptr[llvmlite.Value] = self._nl_heap_global_ref(
|
||||
pool, trans, nl_name)
|
||||
if gv_ref0 is not None:
|
||||
heap_store = llvmlite.build_load(
|
||||
parent_builder, i8_ptr_ty, gv_ref0)
|
||||
if heap_store is None:
|
||||
local_alloca: llvmlite.Value | t.CPtr = self.Gen.VarGen.lookup_current(
|
||||
local_alloca: rawptr[llvmlite.Value] = self.Gen.VarGen.lookup_current(
|
||||
trans.SymTab, nl_name)
|
||||
if local_alloca is not None and local_alloca.Ty is not None:
|
||||
# 父函数局部变量:新建堆存储 + 拷贝当前值 + 重定向
|
||||
nl_load_ty: rawptr[llvmlite.LLVMType] = local_alloca.Ty.Pointee
|
||||
if nl_load_ty is not None:
|
||||
cur_val_nl: llvmlite.Value | t.CPtr = llvmlite.build_load(
|
||||
cur_val_nl: rawptr[llvmlite.Value] = llvmlite.build_load(
|
||||
parent_builder, nl_load_ty, local_alloca)
|
||||
# 堆存储大小按类型字节数:数组(如 [4 x i32]=16 字节)
|
||||
# 不能固定 8 字节(越界写崩溃);指针/标量 ≥ 8 字节
|
||||
st_size: int = self._type_byte_size(pool, nl_load_ty)
|
||||
st_size_val: llvmlite.Value | t.CPtr = llvmlite.const_int64(
|
||||
st_size_val: rawptr[llvmlite.Value] = llvmlite.const_int64(
|
||||
pool, st_size)
|
||||
if st_size_val is not None:
|
||||
st_size_val.Next = None
|
||||
var_storage: llvmlite.Value | t.CPtr = llvmlite.build_call(
|
||||
var_storage: rawptr[llvmlite.Value] = llvmlite.build_call(
|
||||
parent_builder, "malloc", st_size_val, 1, i8_ptr_ty, 0)
|
||||
if var_storage is not None:
|
||||
# 拷贝当前值到堆存储
|
||||
st_slot_nl: llvmlite.Value | t.CPtr = llvmlite.build_bitcast(
|
||||
st_slot_nl: rawptr[llvmlite.Value] = llvmlite.build_bitcast(
|
||||
parent_builder, var_storage, llvmlite.Ptr(pool, nl_load_ty))
|
||||
if st_slot_nl is not None and cur_val_nl is not None:
|
||||
llvmlite.build_store(parent_builder, cur_val_nl, st_slot_nl)
|
||||
# 父函数 VarEntry.Alloca 重定向到堆(父函数读写走共享堆)
|
||||
ve_nl: GenTypes.VarEntry | t.CPtr = self.Gen.VarGen.lookup_var_entry(
|
||||
ve_nl: rawptr[GenTypes.VarEntry] = self.Gen.VarGen.lookup_var_entry(
|
||||
trans.SymTab, nl_name)
|
||||
heap_typed: llvmlite.Value | t.CPtr = llvmlite.build_bitcast(
|
||||
heap_typed: rawptr[llvmlite.Value] = llvmlite.build_bitcast(
|
||||
parent_builder, var_storage, llvmlite.Ptr(pool, nl_load_ty))
|
||||
if ve_nl is not None and heap_typed is not None:
|
||||
ve_nl.Alloca = heap_typed
|
||||
# 记录到全局映射(后续层/父函数可见)
|
||||
gv_ref_new: llvmlite.Value | t.CPtr = None
|
||||
gv_ref_new: rawptr[llvmlite.Value] = None
|
||||
if gname_ck is not None \
|
||||
and self._nl_heap_global_exists(mod, gname_ck) == 0:
|
||||
gv_new: llvmlite.GlobalVariable | t.CPtr = \
|
||||
gv_new: rawptr[llvmlite.GlobalVariable] = \
|
||||
llvmlite.new_global_variable(pool, gname_ck, i8_ptr_ty)
|
||||
if gv_new is not None:
|
||||
# 清除 external linkage + 零初始化(防 undefined reference)
|
||||
@@ -394,20 +394,20 @@ class FuncGenMixin(CallGenBase.CallGenBase):
|
||||
if heap_store is None:
|
||||
continue
|
||||
# env[ni] = 堆存储地址(共享)
|
||||
offset_val: llvmlite.Value | t.CPtr = llvmlite.const_int32(pool, ni * 8)
|
||||
slot: llvmlite.Value | t.CPtr = llvmlite.build_gep(
|
||||
offset_val: rawptr[llvmlite.Value] = llvmlite.const_int32(pool, ni * 8)
|
||||
slot: rawptr[llvmlite.Value] = llvmlite.build_gep(
|
||||
parent_builder, i8_ty, env_ptr, offset_val)
|
||||
if slot is not None:
|
||||
slot_typed: llvmlite.Value | t.CPtr = llvmlite.build_bitcast(
|
||||
slot_typed: rawptr[llvmlite.Value] = llvmlite.build_bitcast(
|
||||
parent_builder, slot, i8_ptr_ptr_ty)
|
||||
if slot_typed is not None:
|
||||
llvmlite.build_store(parent_builder, heap_store, slot_typed)
|
||||
|
||||
# 13b. 创建闭包结构: malloc(16)
|
||||
closure_size_val: llvmlite.Value | t.CPtr = llvmlite.const_int64(pool, 16)
|
||||
closure_size_val: rawptr[llvmlite.Value] = llvmlite.const_int64(pool, 16)
|
||||
if closure_size_val is not None:
|
||||
closure_size_val.Next = None
|
||||
closure_ptr: llvmlite.Value | t.CPtr = llvmlite.build_call(
|
||||
closure_ptr: rawptr[llvmlite.Value] = llvmlite.build_call(
|
||||
parent_builder, "malloc", closure_size_val, 1, i8_ptr_ty, 0)
|
||||
if closure_ptr is None:
|
||||
# malloc 失败,恢复状态
|
||||
@@ -433,33 +433,33 @@ class FuncGenMixin(CallGenBase.CallGenBase):
|
||||
viperlib.snprintf(fn_ptr_name, 64, "@\"%s\"", mangled_promoted)
|
||||
else:
|
||||
viperlib.snprintf(fn_ptr_name, 64, "@%s", mangled_promoted)
|
||||
fn_ptr_val: llvmlite.Value | t.CPtr = llvmlite.SSAValue(pool, fn_func_ptr_ty, fn_ptr_name)
|
||||
fn_ptr_val: rawptr[llvmlite.Value] = llvmlite.SSAValue(pool, fn_func_ptr_ty, fn_ptr_name)
|
||||
|
||||
# bitcast 函数指针到 i8*(闭包存储 i8* 类型)
|
||||
fn_as_i8ptr: llvmlite.Value | t.CPtr = llvmlite.build_bitcast(
|
||||
fn_as_i8ptr: rawptr[llvmlite.Value] = llvmlite.build_bitcast(
|
||||
parent_builder, fn_ptr_val, i8_ptr_ty)
|
||||
fn_slot: llvmlite.Value | t.CPtr = llvmlite.build_bitcast(
|
||||
fn_slot: rawptr[llvmlite.Value] = llvmlite.build_bitcast(
|
||||
parent_builder, closure_ptr, llvmlite.Ptr(pool, i8_ptr_ty))
|
||||
if fn_slot is not None and fn_as_i8ptr is not None:
|
||||
llvmlite.build_store(parent_builder, fn_as_i8ptr, fn_slot)
|
||||
|
||||
# 13d. 存储 env_ptr 到 offset 8
|
||||
eight_val: llvmlite.Value | t.CPtr = llvmlite.const_int32(pool, 8)
|
||||
env_slot_addr: llvmlite.Value | t.CPtr = llvmlite.build_gep(
|
||||
eight_val: rawptr[llvmlite.Value] = llvmlite.const_int32(pool, 8)
|
||||
env_slot_addr: rawptr[llvmlite.Value] = llvmlite.build_gep(
|
||||
parent_builder, i8_ty, closure_ptr, eight_val)
|
||||
if env_slot_addr is not None:
|
||||
env_slot: llvmlite.Value | t.CPtr = llvmlite.build_bitcast(
|
||||
env_slot: rawptr[llvmlite.Value] = llvmlite.build_bitcast(
|
||||
parent_builder, env_slot_addr, llvmlite.Ptr(pool, i8_ptr_ty))
|
||||
if env_slot is not None:
|
||||
if env_ptr is not None:
|
||||
llvmlite.build_store(parent_builder, env_ptr, env_slot)
|
||||
else:
|
||||
# 无 nonlocal 变量,存储 null
|
||||
null_val: llvmlite.Value | t.CPtr = llvmlite.SSAValue(pool, i8_ptr_ty, "null")
|
||||
null_val: rawptr[llvmlite.Value] = llvmlite.SSAValue(pool, i8_ptr_ty, "null")
|
||||
llvmlite.build_store(parent_builder, null_val, env_slot)
|
||||
|
||||
# 13e. 将闭包指针存储到父函数的局部变量 {func_name}
|
||||
closure_alloca: llvmlite.Value | t.CPtr = self.Gen.VarGen._alloca_at_entry(parent_builder, i8_ptr_ty)
|
||||
closure_alloca: rawptr[llvmlite.Value] = self.Gen.VarGen._alloca_at_entry(parent_builder, i8_ptr_ty)
|
||||
if closure_alloca is not None:
|
||||
llvmlite.build_store(parent_builder, closure_ptr, closure_alloca)
|
||||
self.Gen.VarGen.define_var(trans.SymTab, func_name, closure_alloca)
|
||||
@@ -499,7 +499,7 @@ class FuncGenMixin(CallGenBase.CallGenBase):
|
||||
# 已注册 nonlocal(显式 nonlocal 语句 / 已捕获)→ 跳过
|
||||
if GenApi.is_nonlocal_name(trans, nm.id) != 0:
|
||||
return 1
|
||||
ve: GenTypes.VarEntry | t.CPtr = self.Gen.VarGen.lookup_var_entry(
|
||||
ve: rawptr[GenTypes.VarEntry] = self.Gen.VarGen.lookup_var_entry(
|
||||
trans.SymTab, nm.id)
|
||||
if ve is None or ve.Alloca is None or ve.Alloca.Ty is None:
|
||||
return 1
|
||||
@@ -507,7 +507,7 @@ class FuncGenMixin(CallGenBase.CallGenBase):
|
||||
if nl_ty is None:
|
||||
return 1
|
||||
# 模块级全局直接解析,无需 env 捕获
|
||||
mod_gv: llvmlite.Value | t.CPtr = self.Gen.VarGen.lookup_module_var(
|
||||
mod_gv: rawptr[llvmlite.Value] = self.Gen.VarGen.lookup_module_var(
|
||||
trans.SymTab, nm.id)
|
||||
if mod_gv is not None:
|
||||
if uint64(mod_gv) == uint64(ve.Alloca):
|
||||
@@ -527,7 +527,7 @@ class FuncGenMixin(CallGenBase.CallGenBase):
|
||||
self._closure_scan_captures(trans, aan.value)
|
||||
return 1
|
||||
if k == ast.ASTKind.AugAssign:
|
||||
aun: ast.AugAssign | t.CPtr = (ast.AugAssign | t.CPtr)(node)
|
||||
aun: rawptr[ast.AugAssign] = rawptr[ast.AugAssign](node)
|
||||
# 目标同时是读(先读旧值),参与捕获
|
||||
if aun.target is not None:
|
||||
self._closure_scan_captures(trans, aun.target)
|
||||
@@ -535,7 +535,7 @@ class FuncGenMixin(CallGenBase.CallGenBase):
|
||||
self._closure_scan_captures(trans, aun.value)
|
||||
return 1
|
||||
if k == ast.ASTKind.If:
|
||||
ifn: ast.If | t.CPtr = (ast.If | t.CPtr)(node)
|
||||
ifn: rawptr[ast.If] = rawptr[ast.If](node)
|
||||
if ifn.test is not None:
|
||||
self._closure_scan_captures(trans, ifn.test)
|
||||
if ifn.children is not None:
|
||||
@@ -548,7 +548,7 @@ class FuncGenMixin(CallGenBase.CallGenBase):
|
||||
self._closure_scan_captures(trans, ifn.orelse.get(bi_el))
|
||||
return 1
|
||||
if k == ast.ASTKind.For:
|
||||
for_n: ast.For | t.CPtr = (ast.For | t.CPtr)(node)
|
||||
for_n: rawptr[ast.For] = rawptr[ast.For](node)
|
||||
# 循环目标是新局部变量,不参与捕获
|
||||
if for_n.iter is not None:
|
||||
self._closure_scan_captures(trans, for_n.iter)
|
||||
@@ -562,7 +562,7 @@ class FuncGenMixin(CallGenBase.CallGenBase):
|
||||
self._closure_scan_captures(trans, for_n.orelse.get(bi_fe))
|
||||
return 1
|
||||
if k == ast.ASTKind.While:
|
||||
wh_n: ast.While | t.CPtr = (ast.While | t.CPtr)(node)
|
||||
wh_n: rawptr[ast.While] = rawptr[ast.While](node)
|
||||
if wh_n.test is not None:
|
||||
self._closure_scan_captures(trans, wh_n.test)
|
||||
if wh_n.children is not None:
|
||||
@@ -575,12 +575,12 @@ class FuncGenMixin(CallGenBase.CallGenBase):
|
||||
self._closure_scan_captures(trans, wh_n.orelse.get(bi_we))
|
||||
return 1
|
||||
if k == ast.ASTKind.Return:
|
||||
rt_n: ast.Return | t.CPtr = (ast.Return | t.CPtr)(node)
|
||||
rt_n: rawptr[ast.Return] = rawptr[ast.Return](node)
|
||||
if rt_n.value is not None:
|
||||
self._closure_scan_captures(trans, rt_n.value)
|
||||
return 1
|
||||
if k == ast.ASTKind.Expr:
|
||||
ex_n: ast.Expr | t.CPtr = (ast.Expr | t.CPtr)(node)
|
||||
ex_n: rawptr[ast.Expr] = rawptr[ast.Expr](node)
|
||||
if ex_n.value is not None:
|
||||
self._closure_scan_captures(trans, ex_n.value)
|
||||
return 1
|
||||
@@ -591,7 +591,7 @@ class FuncGenMixin(CallGenBase.CallGenBase):
|
||||
for bi_wi in range(bn_wi):
|
||||
wi_n: rawptr[ast.AST] = wth.items.get(bi_wi)
|
||||
if wi_n is not None and wi_n.kind() == ast.ASTKind.WithItem:
|
||||
wi_c: ast.WithItem | t.CPtr = (ast.WithItem | t.CPtr)(wi_n)
|
||||
wi_c: rawptr[ast.WithItem] = rawptr[ast.WithItem](wi_n)
|
||||
if wi_c.context_expr is not None:
|
||||
self._closure_scan_captures(trans, wi_c.context_expr)
|
||||
if wth.children is not None:
|
||||
@@ -600,14 +600,14 @@ class FuncGenMixin(CallGenBase.CallGenBase):
|
||||
self._closure_scan_captures(trans, wth.children.get(bi_wb))
|
||||
return 1
|
||||
if k == ast.ASTKind.Raise:
|
||||
rs_n: ast.Raise | t.CPtr = (ast.Raise | t.CPtr)(node)
|
||||
rs_n: rawptr[ast.Raise] = rawptr[ast.Raise](node)
|
||||
if rs_n.exc is not None:
|
||||
self._closure_scan_captures(trans, rs_n.exc)
|
||||
if rs_n.cause is not None:
|
||||
self._closure_scan_captures(trans, rs_n.cause)
|
||||
return 1
|
||||
if k == ast.ASTKind.Assert:
|
||||
as_n: ast.Assert | t.CPtr = (ast.Assert | t.CPtr)(node)
|
||||
as_n: rawptr[ast.Assert] = rawptr[ast.Assert](node)
|
||||
if as_n.test is not None:
|
||||
self._closure_scan_captures(trans, as_n.test)
|
||||
if as_n.msg is not None:
|
||||
@@ -647,7 +647,7 @@ class FuncGenMixin(CallGenBase.CallGenBase):
|
||||
for bi_mc in range(bn_mc):
|
||||
mc_n: rawptr[ast.AST] = mt_n.cases.get(bi_mc)
|
||||
if mc_n is not None and mc_n.kind() == ast.ASTKind.MatchCase:
|
||||
mc_c: ast.MatchCase | t.CPtr = (ast.MatchCase | t.CPtr)(mc_n)
|
||||
mc_c: rawptr[ast.MatchCase] = rawptr[ast.MatchCase](mc_n)
|
||||
if mc_c.guard is not None:
|
||||
self._closure_scan_captures(trans, mc_c.guard)
|
||||
if mc_c.children is not None:
|
||||
@@ -669,14 +669,14 @@ class FuncGenMixin(CallGenBase.CallGenBase):
|
||||
self._closure_scan_captures(trans, uop.operand)
|
||||
return 1
|
||||
if k == ast.ASTKind.BoolOp:
|
||||
bop2: ast.BoolOp | t.CPtr = (ast.BoolOp | t.CPtr)(node)
|
||||
bop2: rawptr[ast.BoolOp] = rawptr[ast.BoolOp](node)
|
||||
if bop2.values is not None:
|
||||
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
|
||||
if k == ast.ASTKind.Compare:
|
||||
cmp: ast.Compare | t.CPtr = (ast.Compare | t.CPtr)(node)
|
||||
cmp: rawptr[ast.Compare] = rawptr[ast.Compare](node)
|
||||
if cmp.left is not None:
|
||||
self._closure_scan_captures(trans, cmp.left)
|
||||
if cmp.comparators is not None:
|
||||
@@ -697,7 +697,7 @@ class FuncGenMixin(CallGenBase.CallGenBase):
|
||||
for bi_ck in range(bn_ck):
|
||||
kw_n: rawptr[ast.AST] = cal.keywords.get(bi_ck)
|
||||
if kw_n is not None and kw_n.kind() == ast.ASTKind.Keyword:
|
||||
kw_c: ast.Keyword | t.CPtr = (ast.Keyword | t.CPtr)(kw_n)
|
||||
kw_c: rawptr[ast.Keyword] = rawptr[ast.Keyword](kw_n)
|
||||
if kw_c.value is not None:
|
||||
self._closure_scan_captures(trans, kw_c.value)
|
||||
return 1
|
||||
@@ -714,7 +714,7 @@ class FuncGenMixin(CallGenBase.CallGenBase):
|
||||
self._closure_scan_captures(trans, at_n.value)
|
||||
return 1
|
||||
if k == ast.ASTKind.IfExp:
|
||||
ie: ast.IfExp | t.CPtr = (ast.IfExp | t.CPtr)(node)
|
||||
ie: rawptr[ast.IfExp] = rawptr[ast.IfExp](node)
|
||||
if ie.test is not None:
|
||||
self._closure_scan_captures(trans, ie.test)
|
||||
if ie.body is not None:
|
||||
@@ -723,7 +723,7 @@ class FuncGenMixin(CallGenBase.CallGenBase):
|
||||
self._closure_scan_captures(trans, ie.orelse)
|
||||
return 1
|
||||
if k == ast.ASTKind.Dict:
|
||||
dc: ast.Dict | t.CPtr = (ast.Dict | t.CPtr)(node)
|
||||
dc: rawptr[ast.Dict] = rawptr[ast.Dict](node)
|
||||
if dc.keys is not None:
|
||||
bn_dk: sizet = len(dc.keys)
|
||||
for bi_dk in range(bn_dk):
|
||||
@@ -734,14 +734,14 @@ class FuncGenMixin(CallGenBase.CallGenBase):
|
||||
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)
|
||||
st_n: rawptr[ast.Set] = rawptr[ast.Set](node)
|
||||
if st_n.elts is not None:
|
||||
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)
|
||||
ls_n: rawptr[ast.List] = rawptr[ast.List](node)
|
||||
if ls_n.elts is not None:
|
||||
bn_ls: sizet = len(ls_n.elts)
|
||||
for bi_ls in range(bn_ls):
|
||||
@@ -755,17 +755,17 @@ class FuncGenMixin(CallGenBase.CallGenBase):
|
||||
self._closure_scan_captures(trans, tp_n.elts.get(bi_tp))
|
||||
return 1
|
||||
if k == ast.ASTKind.Starred:
|
||||
sr_n: ast.Starred | t.CPtr = (ast.Starred | t.CPtr)(node)
|
||||
sr_n: rawptr[ast.Starred] = rawptr[ast.Starred](node)
|
||||
if sr_n.value is not None:
|
||||
self._closure_scan_captures(trans, sr_n.value)
|
||||
return 1
|
||||
if k == ast.ASTKind.NamedExpr:
|
||||
ne_n: ast.NamedExpr | t.CPtr = (ast.NamedExpr | t.CPtr)(node)
|
||||
ne_n: rawptr[ast.NamedExpr] = rawptr[ast.NamedExpr](node)
|
||||
if ne_n.value is not None:
|
||||
self._closure_scan_captures(trans, ne_n.value)
|
||||
return 1
|
||||
if k == ast.ASTKind.Slice:
|
||||
sl_n: ast.Slice | t.CPtr = (ast.Slice | t.CPtr)(node)
|
||||
sl_n: rawptr[ast.Slice] = rawptr[ast.Slice](node)
|
||||
if sl_n.lower is not None:
|
||||
self._closure_scan_captures(trans, sl_n.lower)
|
||||
if sl_n.upper is not None:
|
||||
@@ -774,31 +774,31 @@ class FuncGenMixin(CallGenBase.CallGenBase):
|
||||
self._closure_scan_captures(trans, sl_n.step)
|
||||
return 1
|
||||
if k == ast.ASTKind.JoinedStr:
|
||||
js_n: ast.JoinedStr | t.CPtr = (ast.JoinedStr | t.CPtr)(node)
|
||||
js_n: rawptr[ast.JoinedStr] = rawptr[ast.JoinedStr](node)
|
||||
if js_n.values is not None:
|
||||
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
|
||||
if k == ast.ASTKind.FormattedValue:
|
||||
fv_n: ast.FormattedValue | t.CPtr = (ast.FormattedValue | t.CPtr)(node)
|
||||
fv_n: rawptr[ast.FormattedValue] = rawptr[ast.FormattedValue](node)
|
||||
if fv_n.value is not None:
|
||||
self._closure_scan_captures(trans, fv_n.value)
|
||||
if fv_n.format_spec is not None:
|
||||
self._closure_scan_captures(trans, fv_n.format_spec)
|
||||
return 1
|
||||
if k == ast.ASTKind.Await:
|
||||
aw_n: ast.Await | t.CPtr = (ast.Await | t.CPtr)(node)
|
||||
aw_n: rawptr[ast.Await] = rawptr[ast.Await](node)
|
||||
if aw_n.value is not None:
|
||||
self._closure_scan_captures(trans, aw_n.value)
|
||||
return 1
|
||||
if k == ast.ASTKind.Yield:
|
||||
yd_n: ast.Yield | t.CPtr = (ast.Yield | t.CPtr)(node)
|
||||
yd_n: rawptr[ast.Yield] = rawptr[ast.Yield](node)
|
||||
if yd_n.value is not None:
|
||||
self._closure_scan_captures(trans, yd_n.value)
|
||||
return 1
|
||||
if k == ast.ASTKind.YieldFrom:
|
||||
yf_n: ast.YieldFrom | t.CPtr = (ast.YieldFrom | t.CPtr)(node)
|
||||
yf_n: rawptr[ast.YieldFrom] = rawptr[ast.YieldFrom](node)
|
||||
if yf_n.value is not None:
|
||||
self._closure_scan_captures(trans, yf_n.value)
|
||||
return 1
|
||||
@@ -810,7 +810,7 @@ class FuncGenMixin(CallGenBase.CallGenBase):
|
||||
elif k == ast.ASTKind.GeneratorExp:
|
||||
is_comp = 1
|
||||
if is_comp != 0:
|
||||
lc_n: ast.ListComp | t.CPtr = (ast.ListComp | t.CPtr)(node)
|
||||
lc_n: rawptr[ast.ListComp] = rawptr[ast.ListComp](node)
|
||||
if lc_n.elt is not None:
|
||||
self._closure_scan_captures(trans, lc_n.elt)
|
||||
if lc_n.generators is not None:
|
||||
@@ -818,7 +818,7 @@ class FuncGenMixin(CallGenBase.CallGenBase):
|
||||
for bi_gen in range(bn_gen):
|
||||
cp_n: rawptr[ast.AST] = lc_n.generators.get(bi_gen)
|
||||
if cp_n is not None and cp_n.kind() == ast.ASTKind.Comprehension:
|
||||
cp_c: ast.Comprehension | t.CPtr = (ast.Comprehension | t.CPtr)(cp_n)
|
||||
cp_c: rawptr[ast.Comprehension] = rawptr[ast.Comprehension](cp_n)
|
||||
if cp_c.iter is not None:
|
||||
self._closure_scan_captures(trans, cp_c.iter)
|
||||
if cp_c.ifs is not None:
|
||||
@@ -827,7 +827,7 @@ class FuncGenMixin(CallGenBase.CallGenBase):
|
||||
self._closure_scan_captures(trans, cp_c.ifs.get(bi_cpi))
|
||||
return 1
|
||||
if k == ast.ASTKind.DictComp:
|
||||
dcn: ast.DictComp | t.CPtr = (ast.DictComp | t.CPtr)(node)
|
||||
dcn: rawptr[ast.DictComp] = rawptr[ast.DictComp](node)
|
||||
if dcn.key is not None:
|
||||
self._closure_scan_captures(trans, dcn.key)
|
||||
if dcn.value is not None:
|
||||
@@ -837,7 +837,7 @@ class FuncGenMixin(CallGenBase.CallGenBase):
|
||||
for bi_dgen in range(bn_dgen):
|
||||
cp_dn: rawptr[ast.AST] = dcn.generators.get(bi_dgen)
|
||||
if cp_dn is not None and cp_dn.kind() == ast.ASTKind.Comprehension:
|
||||
cp_dc: ast.Comprehension | t.CPtr = (ast.Comprehension | t.CPtr)(cp_dn)
|
||||
cp_dc: rawptr[ast.Comprehension] = rawptr[ast.Comprehension](cp_dn)
|
||||
if cp_dc.iter is not None:
|
||||
self._closure_scan_captures(trans, cp_dc.iter)
|
||||
if cp_dc.ifs is not None:
|
||||
@@ -905,7 +905,7 @@ class FuncGenMixin(CallGenBase.CallGenBase):
|
||||
# ============================================================
|
||||
def _nl_heap_global_ref(self, pool: rawptr[memhub.MemBuddy],
|
||||
trans: rawptr[HT.Translator],
|
||||
name: str) -> llvmlite.Value | t.CPtr:
|
||||
name: str) -> rawptr[llvmlite.Value]:
|
||||
"""获取 nonlocal 堆地址全局映射变量的引用(@"..." 引号包裹)"""
|
||||
if pool is None or trans is None or name is None:
|
||||
return None
|
||||
@@ -928,7 +928,7 @@ class FuncGenMixin(CallGenBase.CallGenBase):
|
||||
"""检查全局映射变量 gname 是否已在模块中,1=存在"""
|
||||
if mod is None or gname is None:
|
||||
return 0
|
||||
gcur: llvmlite.GlobalVariable | t.CPtr = mod.GlobalHead
|
||||
gcur: rawptr[llvmlite.GlobalVariable] = mod.GlobalHead
|
||||
while gcur is not None:
|
||||
if gcur.Name is not None and string.strcmp(gcur.Name, gname) == 0:
|
||||
return 1
|
||||
@@ -951,7 +951,7 @@ class FuncGenMixin(CallGenBase.CallGenBase):
|
||||
fd: rawptr[ast.FunctionDef] = rawptr[ast.FunctionDef](node)
|
||||
if fd is None or fd.children is None:
|
||||
return count
|
||||
ch: list[rawptr[ast.AST]] | t.CPtr = fd.children
|
||||
ch: rawptr[list[rawptr[ast.AST]]] = fd.children
|
||||
cn: sizet = len(ch)
|
||||
for ci in range(cn):
|
||||
st: rawptr[ast.AST] = ch.get(ci)
|
||||
@@ -961,9 +961,9 @@ class FuncGenMixin(CallGenBase.CallGenBase):
|
||||
if k == ast.ASTKind.FunctionDef:
|
||||
count = self._collect_chain_nonlocals(trans, st, names, count)
|
||||
elif k == ast.ASTKind.Nonlocal:
|
||||
nl_node: ast.Nonlocal | t.CPtr = (ast.Nonlocal | t.CPtr)(st)
|
||||
nl_node: rawptr[ast.Nonlocal] = rawptr[ast.Nonlocal](st)
|
||||
if nl_node is not None and nl_node.names is not None:
|
||||
nl_list: list[rawptr[ast.AST]] | t.CPtr = nl_node.names
|
||||
nl_list: rawptr[list[rawptr[ast.AST]]] = nl_node.names
|
||||
nn: sizet = len(nl_list)
|
||||
for ni in range(nn):
|
||||
nm_node: rawptr[ast.AST] = nl_list.get(ni)
|
||||
@@ -998,7 +998,7 @@ class FuncGenMixin(CallGenBase.CallGenBase):
|
||||
def _prepare_chain_nonlocals(self, trans: rawptr[HT.Translator],
|
||||
node: rawptr[ast.AST],
|
||||
pool: rawptr[memhub.MemBuddy],
|
||||
builder: llvmlite.IRBuilder | t.CPtr,
|
||||
builder: rawptr[llvmlite.IRBuilder],
|
||||
mod: rawptr[llvmlite.LLVMModule],
|
||||
i8_ty: rawptr[llvmlite.LLVMType],
|
||||
i8_ptr_ty: rawptr[llvmlite.LLVMType]) -> int:
|
||||
@@ -1025,7 +1025,7 @@ class FuncGenMixin(CallGenBase.CallGenBase):
|
||||
if nl_name is None:
|
||||
continue
|
||||
# 只在"定义它的函数"(当前顶层作用域有 alloca)中建堆
|
||||
local_alloca: llvmlite.Value | t.CPtr = self.Gen.VarGen.lookup_current(
|
||||
local_alloca: rawptr[llvmlite.Value] = self.Gen.VarGen.lookup_current(
|
||||
trans.SymTab, nl_name)
|
||||
if local_alloca is None or local_alloca.Ty is None:
|
||||
continue
|
||||
@@ -1040,30 +1040,30 @@ class FuncGenMixin(CallGenBase.CallGenBase):
|
||||
# @nlheap.* 保持上一函数的堆地址,env 读到错堆。映射变量仅首次 add(模块去重),
|
||||
# store 指令每次照发。
|
||||
st_size: int = self._type_byte_size(pool, nl_ty)
|
||||
st_size_val: llvmlite.Value | t.CPtr = llvmlite.const_int64(pool, st_size)
|
||||
st_size_val: rawptr[llvmlite.Value] = llvmlite.const_int64(pool, st_size)
|
||||
if st_size_val is not None:
|
||||
st_size_val.Next = None
|
||||
var_storage: llvmlite.Value | t.CPtr = llvmlite.build_call(
|
||||
var_storage: rawptr[llvmlite.Value] = llvmlite.build_call(
|
||||
builder, "malloc", st_size_val, 1, i8_ptr_ty, 0)
|
||||
if var_storage is None:
|
||||
continue
|
||||
cur_val: llvmlite.Value | t.CPtr = llvmlite.build_load(
|
||||
cur_val: rawptr[llvmlite.Value] = llvmlite.build_load(
|
||||
builder, nl_ty, local_alloca)
|
||||
st_slot: llvmlite.Value | t.CPtr = llvmlite.build_bitcast(
|
||||
st_slot: rawptr[llvmlite.Value] = llvmlite.build_bitcast(
|
||||
builder, var_storage, llvmlite.Ptr(pool, nl_ty))
|
||||
if st_slot is not None and cur_val is not None:
|
||||
llvmlite.build_store(builder, cur_val, st_slot)
|
||||
# 重定向 VarEntry(父函数读写走共享堆)
|
||||
ve: GenTypes.VarEntry | t.CPtr = self.Gen.VarGen.lookup_var_entry(
|
||||
ve: rawptr[GenTypes.VarEntry] = self.Gen.VarGen.lookup_var_entry(
|
||||
trans.SymTab, nl_name)
|
||||
if ve is not None:
|
||||
heap_typed: llvmlite.Value | t.CPtr = llvmlite.build_bitcast(
|
||||
heap_typed: rawptr[llvmlite.Value] = llvmlite.build_bitcast(
|
||||
builder, var_storage, llvmlite.Ptr(pool, nl_ty))
|
||||
if heap_typed is not None:
|
||||
ve.Alloca = heap_typed
|
||||
# 创建/复用全局映射变量并 store 堆地址(跨函数可见)
|
||||
gv_found: llvmlite.GlobalVariable | t.CPtr = None
|
||||
gcur: llvmlite.GlobalVariable | t.CPtr = mod.GlobalHead
|
||||
gv_found: rawptr[llvmlite.GlobalVariable] = None
|
||||
gcur: rawptr[llvmlite.GlobalVariable] = mod.GlobalHead
|
||||
while gcur is not None:
|
||||
if gcur.Name is not None and string.strcmp(gcur.Name, gname) == 0:
|
||||
gv_found = gcur
|
||||
@@ -1078,7 +1078,7 @@ class FuncGenMixin(CallGenBase.CallGenBase):
|
||||
gv_found.Initializer = "null"
|
||||
llvmlite.module_add_global(mod, gv_found)
|
||||
if gv_found is not None:
|
||||
gv_ref: llvmlite.Value | t.CPtr = self._nl_heap_global_ref(
|
||||
gv_ref: rawptr[llvmlite.Value] = self._nl_heap_global_ref(
|
||||
pool, trans, nl_name)
|
||||
if gv_ref is not None:
|
||||
llvmlite.build_store(builder, var_storage, gv_ref)
|
||||
@@ -1095,15 +1095,15 @@ class FuncGenMixin(CallGenBase.CallGenBase):
|
||||
# 3. 创建闭包 {fn_ptr, env_ptr},返回 i8* 闭包指针
|
||||
# 赋值语句据此创建 i8** alloca,调用走 translate_closure_call
|
||||
# ============================================================
|
||||
def translate_lambda(self, builder: llvmlite.IRBuilder | t.CPtr,
|
||||
def translate_lambda(self, builder: rawptr[llvmlite.IRBuilder],
|
||||
pool: rawptr[memhub.MemBuddy],
|
||||
mod: rawptr[llvmlite.LLVMModule],
|
||||
node: rawptr[ast.AST],
|
||||
trans: rawptr[HT.Translator] = None) -> llvmlite.Value | t.CPtr:
|
||||
trans: rawptr[HT.Translator] = None) -> rawptr[llvmlite.Value]:
|
||||
"""翻译 lambda 表达式,返回闭包指针(i8*)"""
|
||||
if node is None or trans is None or builder is None:
|
||||
return None
|
||||
lam: ast.Lambda | t.CPtr = (ast.Lambda | t.CPtr)(node)
|
||||
lam: rawptr[ast.Lambda] = rawptr[ast.Lambda](node)
|
||||
if lam is None:
|
||||
return None
|
||||
|
||||
@@ -1137,7 +1137,7 @@ class FuncGenMixin(CallGenBase.CallGenBase):
|
||||
if lam.args is not None:
|
||||
ags: rawptr[ast.Arguments] = rawptr[ast.Arguments](lam.args)
|
||||
if ags.args is not None:
|
||||
alist: list[rawptr[ast.AST]] | t.CPtr = ags.args
|
||||
alist: rawptr[list[rawptr[ast.AST]]] = ags.args
|
||||
pn: sizet = len(alist)
|
||||
for pi in range(pn):
|
||||
if param_count >= 64:
|
||||
@@ -1204,10 +1204,10 @@ class FuncGenMixin(CallGenBase.CallGenBase):
|
||||
llvmlite.add_param(pool, func, p_ty2, pname_l)
|
||||
|
||||
# 5. entry 块 + builder
|
||||
entry_blk: llvmlite.BasicBlock | t.CPtr = llvmlite.create_block(pool, func, "entry")
|
||||
entry_blk: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(pool, func, "entry")
|
||||
if entry_blk is None:
|
||||
return None
|
||||
func_builder: llvmlite.IRBuilder | t.CPtr = llvmlite.new_builder(pool, func)
|
||||
func_builder: rawptr[llvmlite.IRBuilder] = llvmlite.new_builder(pool, func)
|
||||
if func_builder is None:
|
||||
return None
|
||||
llvmlite.position_at_end(func_builder, entry_blk)
|
||||
@@ -1216,15 +1216,15 @@ class FuncGenMixin(CallGenBase.CallGenBase):
|
||||
self.Gen.VarGen.enter_scope(trans.SymTab, SCOPE_FUNCTION)
|
||||
|
||||
# 7. _env_ptr alloca(存储 %env 参数)
|
||||
env_alloca: llvmlite.Value | t.CPtr = llvmlite.build_alloca(func_builder, i8_ptr_ty)
|
||||
env_alloca: rawptr[llvmlite.Value] = llvmlite.build_alloca(func_builder, i8_ptr_ty)
|
||||
if env_alloca is not None:
|
||||
self.Gen.VarGen.define_var(trans.SymTab, "_env_ptr", env_alloca)
|
||||
env_param_val: llvmlite.Value | t.CPtr = llvmlite.SSAValue(pool, i8_ptr_ty, "%env")
|
||||
env_param_val: rawptr[llvmlite.Value] = llvmlite.SSAValue(pool, i8_ptr_ty, "%env")
|
||||
llvmlite.build_store(func_builder, env_param_val, env_alloca)
|
||||
|
||||
# 8. 保存父函数状态并切换到提升函数
|
||||
old_func: rawptr[llvmlite.Function] = trans._cur_func
|
||||
old_builder: llvmlite.IRBuilder | t.CPtr = trans._cur_builder
|
||||
old_builder: rawptr[llvmlite.IRBuilder] = trans._cur_builder
|
||||
old_func_name: str = trans._cur_func_name
|
||||
old_global_count: int = trans._global_name_count
|
||||
old_nonlocal_count: int = trans._nonlocal_name_count
|
||||
@@ -1247,24 +1247,24 @@ class FuncGenMixin(CallGenBase.CallGenBase):
|
||||
cap_ty: rawptr[llvmlite.LLVMType] = (rawptr[llvmlite.LLVMType])(ty_slot3[0])
|
||||
if cap_ty is None:
|
||||
continue
|
||||
off_val: llvmlite.Value | t.CPtr = llvmlite.const_int32(pool, ci * 8)
|
||||
slot_addr: llvmlite.Value | t.CPtr = llvmlite.build_gep(
|
||||
off_val: rawptr[llvmlite.Value] = llvmlite.const_int32(pool, ci * 8)
|
||||
slot_addr: rawptr[llvmlite.Value] = llvmlite.build_gep(
|
||||
func_builder, i8_ty, env_param_val, off_val)
|
||||
if slot_addr is None:
|
||||
continue
|
||||
storage_addr: llvmlite.Value | t.CPtr = llvmlite.build_load(
|
||||
storage_addr: rawptr[llvmlite.Value] = llvmlite.build_load(
|
||||
func_builder, i8_ptr_ty, slot_addr)
|
||||
if storage_addr is None:
|
||||
continue
|
||||
st_typed: llvmlite.Value | t.CPtr = llvmlite.build_bitcast(
|
||||
st_typed: rawptr[llvmlite.Value] = llvmlite.build_bitcast(
|
||||
func_builder, storage_addr, llvmlite.Ptr(pool, cap_ty))
|
||||
if st_typed is None:
|
||||
continue
|
||||
cap_val: llvmlite.Value | t.CPtr = llvmlite.build_load(
|
||||
cap_val: rawptr[llvmlite.Value] = llvmlite.build_load(
|
||||
func_builder, cap_ty, st_typed)
|
||||
if cap_val is None:
|
||||
continue
|
||||
var_alloca: llvmlite.Value | t.CPtr = llvmlite.build_alloca(func_builder, cap_ty)
|
||||
var_alloca: rawptr[llvmlite.Value] = llvmlite.build_alloca(func_builder, cap_ty)
|
||||
if var_alloca is not None:
|
||||
llvmlite.build_store(func_builder, cap_val, var_alloca)
|
||||
self.Gen.VarGen.define_var(trans.SymTab, cap_slot, var_alloca)
|
||||
@@ -1282,21 +1282,21 @@ class FuncGenMixin(CallGenBase.CallGenBase):
|
||||
pname_ref: str = pool.alloc(32)
|
||||
if pname_ref is not None:
|
||||
viperlib.snprintf(pname_ref, 32, "%%%s", param_names + pi3 * 32)
|
||||
param_ref: llvmlite.Value | t.CPtr = llvmlite.SSAValue(pool, p_ty3, pname_ref)
|
||||
arg_alloca: llvmlite.Value | t.CPtr = llvmlite.build_alloca(func_builder, p_ty3)
|
||||
param_ref: rawptr[llvmlite.Value] = llvmlite.SSAValue(pool, p_ty3, pname_ref)
|
||||
arg_alloca: rawptr[llvmlite.Value] = llvmlite.build_alloca(func_builder, p_ty3)
|
||||
if arg_alloca is not None:
|
||||
llvmlite.build_store(func_builder, param_ref, arg_alloca)
|
||||
self.Gen.VarGen.define_var(trans.SymTab, param_names + pi3 * 32, arg_alloca)
|
||||
|
||||
# 11. 翻译 body 表达式,coerce 到 i32 后 ret
|
||||
body_val: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
|
||||
body_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
|
||||
func_builder, pool, mod, lam.body, None, 0, trans)
|
||||
if body_val is not None and body_val.Ty is not None:
|
||||
if self.Gen.ExprGenBase.get_llvm_type_bits(body_val.Ty) == 32 \
|
||||
and self.Gen.ExprGenBase.is_ptr_type(body_val.Ty) == 0:
|
||||
llvmlite.build_ret(func_builder, body_val)
|
||||
else:
|
||||
ret_val: llvmlite.Value | t.CPtr = self.Gen.ExprGenBase.coerce_to_type(
|
||||
ret_val: rawptr[llvmlite.Value] = self.Gen.ExprGenBase.coerce_to_type(
|
||||
func_builder, body_val, i32_ty, lam.body)
|
||||
if ret_val is not None:
|
||||
llvmlite.build_ret(func_builder, ret_val)
|
||||
@@ -1317,10 +1317,10 @@ class FuncGenMixin(CallGenBase.CallGenBase):
|
||||
trans._closure_env_count = old_env_count
|
||||
|
||||
# 13. 在父函数中创建 env(每个捕获变量 8 字节堆存储,env[i] = 堆地址)
|
||||
env_ptr: llvmlite.Value | t.CPtr = None
|
||||
env_ptr: rawptr[llvmlite.Value] = None
|
||||
if cap_count > 0:
|
||||
env_size: int64 = cap_count * 8
|
||||
env_size_val: llvmlite.Value | t.CPtr = llvmlite.const_int64(pool, env_size)
|
||||
env_size_val: rawptr[llvmlite.Value] = llvmlite.const_int64(pool, env_size)
|
||||
if env_size_val is not None:
|
||||
env_size_val.Next = None
|
||||
env_ptr = llvmlite.build_call(
|
||||
@@ -1333,8 +1333,8 @@ class FuncGenMixin(CallGenBase.CallGenBase):
|
||||
continue
|
||||
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])
|
||||
var_alloca2: rawptr[llvmlite.Value] = (
|
||||
rawptr[llvmlite.Value])(al_slot[0])
|
||||
if var_alloca2 is None:
|
||||
continue
|
||||
ty_addr5: uint64 = uint64(cap_tys) + ci3 * 8
|
||||
@@ -1348,33 +1348,33 @@ class FuncGenMixin(CallGenBase.CallGenBase):
|
||||
st_size: int = 8
|
||||
if ty_bits > 64:
|
||||
st_size = ty_bits // 8
|
||||
st_size_val: llvmlite.Value | t.CPtr = llvmlite.const_int64(pool, st_size)
|
||||
st_size_val: rawptr[llvmlite.Value] = llvmlite.const_int64(pool, st_size)
|
||||
if st_size_val is not None:
|
||||
st_size_val.Next = None
|
||||
var_storage: llvmlite.Value | t.CPtr = llvmlite.build_call(
|
||||
var_storage: rawptr[llvmlite.Value] = llvmlite.build_call(
|
||||
builder, "malloc", st_size_val, 1, i8_ptr_ty, 0)
|
||||
if var_storage is not None:
|
||||
cur_val: llvmlite.Value | t.CPtr = llvmlite.build_load(
|
||||
cur_val: rawptr[llvmlite.Value] = llvmlite.build_load(
|
||||
builder, cap_ty2, var_alloca2)
|
||||
if cur_val is not None:
|
||||
st_slot5: llvmlite.Value | t.CPtr = llvmlite.build_bitcast(
|
||||
st_slot5: rawptr[llvmlite.Value] = llvmlite.build_bitcast(
|
||||
builder, var_storage, llvmlite.Ptr(pool, cap_ty2))
|
||||
if st_slot5 is not None:
|
||||
llvmlite.build_store(builder, cur_val, st_slot5)
|
||||
off_val2: llvmlite.Value | t.CPtr = llvmlite.const_int32(pool, ci3 * 8)
|
||||
slot2: llvmlite.Value | t.CPtr = llvmlite.build_gep(
|
||||
off_val2: rawptr[llvmlite.Value] = llvmlite.const_int32(pool, ci3 * 8)
|
||||
slot2: rawptr[llvmlite.Value] = llvmlite.build_gep(
|
||||
builder, i8_ty, env_ptr, off_val2)
|
||||
if slot2 is not None:
|
||||
slot_typed2: llvmlite.Value | t.CPtr = llvmlite.build_bitcast(
|
||||
slot_typed2: rawptr[llvmlite.Value] = llvmlite.build_bitcast(
|
||||
builder, slot2, i8_ptr_ptr_ty)
|
||||
if slot_typed2 is not None:
|
||||
llvmlite.build_store(builder, var_storage, slot_typed2)
|
||||
|
||||
# 14. 在父函数中创建闭包 malloc(16)
|
||||
closure_size_val: llvmlite.Value | t.CPtr = llvmlite.const_int64(pool, 16)
|
||||
closure_size_val: rawptr[llvmlite.Value] = llvmlite.const_int64(pool, 16)
|
||||
if closure_size_val is not None:
|
||||
closure_size_val.Next = None
|
||||
closure_ptr: llvmlite.Value | t.CPtr = llvmlite.build_call(
|
||||
closure_ptr: rawptr[llvmlite.Value] = llvmlite.build_call(
|
||||
builder, "malloc", closure_size_val, 1, i8_ptr_ty, 0)
|
||||
if closure_ptr is None:
|
||||
return None
|
||||
@@ -1389,26 +1389,26 @@ class FuncGenMixin(CallGenBase.CallGenBase):
|
||||
viperlib.snprintf(fn_ptr_name, 64, "@\"%s\"", mangled_promoted)
|
||||
else:
|
||||
viperlib.snprintf(fn_ptr_name, 64, "@%s", mangled_promoted)
|
||||
fn_ptr_val: llvmlite.Value | t.CPtr = llvmlite.SSAValue(pool, fn_func_ptr_ty, fn_ptr_name)
|
||||
fn_as_i8ptr: llvmlite.Value | t.CPtr = llvmlite.build_bitcast(
|
||||
fn_ptr_val: rawptr[llvmlite.Value] = llvmlite.SSAValue(pool, fn_func_ptr_ty, fn_ptr_name)
|
||||
fn_as_i8ptr: rawptr[llvmlite.Value] = llvmlite.build_bitcast(
|
||||
builder, fn_ptr_val, i8_ptr_ty)
|
||||
fn_slot: llvmlite.Value | t.CPtr = llvmlite.build_bitcast(
|
||||
fn_slot: rawptr[llvmlite.Value] = llvmlite.build_bitcast(
|
||||
builder, closure_ptr, llvmlite.Ptr(pool, i8_ptr_ty))
|
||||
if fn_slot is not None and fn_as_i8ptr is not None:
|
||||
llvmlite.build_store(builder, fn_as_i8ptr, fn_slot)
|
||||
|
||||
# 16. [8] = env_ptr(无捕获存 null)
|
||||
eight_val: llvmlite.Value | t.CPtr = llvmlite.const_int32(pool, 8)
|
||||
env_slot_addr: llvmlite.Value | t.CPtr = llvmlite.build_gep(
|
||||
eight_val: rawptr[llvmlite.Value] = llvmlite.const_int32(pool, 8)
|
||||
env_slot_addr: rawptr[llvmlite.Value] = llvmlite.build_gep(
|
||||
builder, i8_ty, closure_ptr, eight_val)
|
||||
if env_slot_addr is not None:
|
||||
env_slot: llvmlite.Value | t.CPtr = llvmlite.build_bitcast(
|
||||
env_slot: rawptr[llvmlite.Value] = llvmlite.build_bitcast(
|
||||
builder, env_slot_addr, llvmlite.Ptr(pool, i8_ptr_ty))
|
||||
if env_slot is not None:
|
||||
if env_ptr is not None:
|
||||
llvmlite.build_store(builder, env_ptr, env_slot)
|
||||
else:
|
||||
null_val: llvmlite.Value | t.CPtr = llvmlite.SSAValue(pool, i8_ptr_ty, "null")
|
||||
null_val: rawptr[llvmlite.Value] = llvmlite.SSAValue(pool, i8_ptr_ty, "null")
|
||||
llvmlite.build_store(builder, null_val, env_slot)
|
||||
|
||||
# 17. 返回闭包指针(i8*)
|
||||
@@ -1446,14 +1446,14 @@ class FuncGenMixin(CallGenBase.CallGenBase):
|
||||
if string.strcmp(cap_names + ci * 64, nm.id) == 0:
|
||||
return cap_count
|
||||
# 查当前作用域链
|
||||
alloca: llvmlite.Value | t.CPtr = self.Gen.VarGen.lookup_var(trans.SymTab, nm.id)
|
||||
alloca: rawptr[llvmlite.Value] = self.Gen.VarGen.lookup_var(trans.SymTab, nm.id)
|
||||
if alloca is None or alloca.Ty is None:
|
||||
return cap_count
|
||||
pointee: rawptr[llvmlite.LLVMType] = alloca.Ty.Pointee
|
||||
if pointee is None:
|
||||
return cap_count
|
||||
# 跳过模块级全局(body 直接解析全局,无需 env 捕获)
|
||||
mod_gv: llvmlite.Value | t.CPtr = self.Gen.VarGen.lookup_module_var(trans.SymTab, nm.id)
|
||||
mod_gv: rawptr[llvmlite.Value] = self.Gen.VarGen.lookup_module_var(trans.SymTab, nm.id)
|
||||
if mod_gv is not None:
|
||||
if uint64(mod_gv) == uint64(alloca):
|
||||
return cap_count
|
||||
@@ -1479,21 +1479,21 @@ class FuncGenMixin(CallGenBase.CallGenBase):
|
||||
return self._lambda_scan_body(trans, uop.operand, param_names, param_count,
|
||||
cap_names, cap_allocas, cap_tys, cap_count)
|
||||
if k == ast.ASTKind.BoolOp:
|
||||
bop2: ast.BoolOp | t.CPtr = (ast.BoolOp | t.CPtr)(node)
|
||||
bop2: rawptr[ast.BoolOp] = rawptr[ast.BoolOp](node)
|
||||
cc2: int = cap_count
|
||||
if bop2.values is not None:
|
||||
vs: list[rawptr[ast.AST]] | t.CPtr = bop2.values
|
||||
vs: rawptr[list[rawptr[ast.AST]]] = bop2.values
|
||||
vn: sizet = len(vs)
|
||||
for vi in range(vn):
|
||||
cc2 = self._lambda_scan_body(trans, vs.get(vi), param_names, param_count,
|
||||
cap_names, cap_allocas, cap_tys, cc2)
|
||||
return cc2
|
||||
if k == ast.ASTKind.Compare:
|
||||
cmp: ast.Compare | t.CPtr = (ast.Compare | t.CPtr)(node)
|
||||
cmp: rawptr[ast.Compare] = rawptr[ast.Compare](node)
|
||||
cc3: int = self._lambda_scan_body(trans, cmp.left, param_names, param_count,
|
||||
cap_names, cap_allocas, cap_tys, cap_count)
|
||||
if cmp.comparators is not None:
|
||||
cl: list[rawptr[ast.AST]] | t.CPtr = cmp.comparators
|
||||
cl: rawptr[list[rawptr[ast.AST]]] = cmp.comparators
|
||||
cn: sizet = len(cl)
|
||||
for cvi in range(cn):
|
||||
cc3 = self._lambda_scan_body(trans, cl.get(cvi), param_names, param_count,
|
||||
@@ -1504,16 +1504,16 @@ class FuncGenMixin(CallGenBase.CallGenBase):
|
||||
cc4: int = self._lambda_scan_body(trans, cal.func, param_names, param_count,
|
||||
cap_names, cap_allocas, cap_tys, cap_count)
|
||||
if cal.args is not None:
|
||||
als: list[rawptr[ast.AST]] | t.CPtr = cal.args
|
||||
als: rawptr[list[rawptr[ast.AST]]] = cal.args
|
||||
an: sizet = len(als)
|
||||
for ai in range(an):
|
||||
cc4 = self._lambda_scan_body(trans, als.get(ai), param_names, param_count,
|
||||
cap_names, cap_allocas, cap_tys, cc4)
|
||||
if cal.keywords is not None:
|
||||
kws: list[rawptr[ast.AST]] | t.CPtr = cal.keywords
|
||||
kws: rawptr[list[rawptr[ast.AST]]] = cal.keywords
|
||||
kn: sizet = len(kws)
|
||||
for ki in range(kn):
|
||||
kw: ast.Keyword | t.CPtr = (ast.Keyword | t.CPtr)(kws.get(ki))
|
||||
kw: rawptr[ast.Keyword] = rawptr[ast.Keyword](kws.get(ki))
|
||||
if kw is not None and kw.value is not None:
|
||||
cc4 = self._lambda_scan_body(trans, kw.value, param_names, param_count,
|
||||
cap_names, cap_allocas, cap_tys, cc4)
|
||||
@@ -1531,7 +1531,7 @@ class FuncGenMixin(CallGenBase.CallGenBase):
|
||||
return self._lambda_scan_body(trans, at.value, param_names, param_count,
|
||||
cap_names, cap_allocas, cap_tys, cap_count)
|
||||
if k == ast.ASTKind.IfExp:
|
||||
ie: ast.IfExp | t.CPtr = (ast.IfExp | t.CPtr)(node)
|
||||
ie: rawptr[ast.IfExp] = rawptr[ast.IfExp](node)
|
||||
cc6: int = self._lambda_scan_body(trans, ie.test, param_names, param_count,
|
||||
cap_names, cap_allocas, cap_tys, cap_count)
|
||||
cc6 = self._lambda_scan_body(trans, ie.body, param_names, param_count,
|
||||
@@ -1539,17 +1539,17 @@ class FuncGenMixin(CallGenBase.CallGenBase):
|
||||
return self._lambda_scan_body(trans, ie.orelse, param_names, param_count,
|
||||
cap_names, cap_allocas, cap_tys, cc6)
|
||||
if k == ast.ASTKind.List:
|
||||
ls: ast.List | t.CPtr = (ast.List | t.CPtr)(node)
|
||||
ls: rawptr[ast.List] = rawptr[ast.List](node)
|
||||
cc7: int = cap_count
|
||||
if ls.elts is not None:
|
||||
es: list[rawptr[ast.AST]] | t.CPtr = ls.elts
|
||||
es: rawptr[list[rawptr[ast.AST]]] = ls.elts
|
||||
en: sizet = len(es)
|
||||
for ei in range(en):
|
||||
cc7 = self._lambda_scan_body(trans, es.get(ei), param_names, param_count,
|
||||
cap_names, cap_allocas, cap_tys, cc7)
|
||||
return cc7
|
||||
if k == ast.ASTKind.Lambda:
|
||||
lam2: ast.Lambda | t.CPtr = (ast.Lambda | t.CPtr)(node)
|
||||
lam2: rawptr[ast.Lambda] = rawptr[ast.Lambda](node)
|
||||
return self._lambda_scan_body(trans, lam2.body, param_names, param_count,
|
||||
cap_names, cap_allocas, cap_tys, cap_count)
|
||||
return cap_count
|
||||
@@ -319,7 +319,7 @@ def add_visible_struct(pool: rawptr[memhub.MemBuddy], name: str):
|
||||
|
||||
|
||||
# ---------------- find_struct_by_module(委托 StructGenMixin.find_struct_by_module) ----------------
|
||||
def find_struct_by_module(name: str, sha1: str) -> GenTypes.StructEntry | t.CPtr:
|
||||
def find_struct_by_module(name: str, sha1: str) -> rawptr[GenTypes.StructEntry]:
|
||||
"""委托到 gen.find_struct_by_module(原 Handles 壳)"""
|
||||
if _g_gen is not None:
|
||||
return _g_gen.StructGen.find_struct_by_module(name, sha1)
|
||||
@@ -327,7 +327,7 @@ def find_struct_by_module(name: str, sha1: str) -> GenTypes.StructEntry | t.CPtr
|
||||
|
||||
|
||||
# ---------------- find_struct_by_type(委托 StructGenMixin.find_struct_by_type) ----------------
|
||||
def find_struct_by_type(struct_ty: rawptr[llvmlite.LLVMType]) -> GenTypes.StructEntry | t.CPtr:
|
||||
def find_struct_by_type(struct_ty: rawptr[llvmlite.LLVMType]) -> rawptr[GenTypes.StructEntry]:
|
||||
"""委托到 gen.find_struct_by_type(原 Handles 壳)"""
|
||||
if _g_gen is not None:
|
||||
return _g_gen.StructGen.find_struct_by_type(struct_ty)
|
||||
@@ -338,7 +338,7 @@ def find_struct_by_type(struct_ty: rawptr[llvmlite.LLVMType]) -> GenTypes.Struct
|
||||
def register_struct(pool: rawptr[memhub.MemBuddy],
|
||||
name: str,
|
||||
struct_ty: rawptr[llvmlite.LLVMType],
|
||||
sha1: str = None) -> GenTypes.StructEntry | t.CPtr:
|
||||
sha1: str = None) -> rawptr[GenTypes.StructEntry]:
|
||||
"""委托到 gen.register_struct(原 Handles 壳)"""
|
||||
if _g_gen is not None:
|
||||
return _g_gen.StructGen.register_struct(pool, name, struct_ty, sha1)
|
||||
@@ -347,7 +347,7 @@ def register_struct(pool: rawptr[memhub.MemBuddy],
|
||||
|
||||
# ---------------- add_field(委托 StructGenMixin.add_field) ----------------
|
||||
def add_field(pool: rawptr[memhub.MemBuddy],
|
||||
struct_entry: GenTypes.StructEntry | t.CPtr,
|
||||
struct_entry: rawptr[GenTypes.StructEntry],
|
||||
field_name: str,
|
||||
field_ty: rawptr[llvmlite.LLVMType]) -> int:
|
||||
"""委托到 gen.add_field(原 Handles 壳)"""
|
||||
@@ -360,7 +360,7 @@ def add_field(pool: rawptr[memhub.MemBuddy],
|
||||
def register_struct_alias(pool: rawptr[memhub.MemBuddy],
|
||||
name: str,
|
||||
sha1: str,
|
||||
src_entry: GenTypes.StructEntry | t.CPtr) -> GenTypes.StructEntry | t.CPtr:
|
||||
src_entry: rawptr[GenTypes.StructEntry]) -> rawptr[GenTypes.StructEntry]:
|
||||
"""委托到 gen.StructGen.register_struct_alias(包重导出类别名注册,原 Handles 壳)"""
|
||||
if _g_gen is not None:
|
||||
return _g_gen.StructGen.register_struct_alias(pool, name, sha1, src_entry)
|
||||
@@ -522,7 +522,7 @@ def translate_children(trans: rawptr[HT.Translator], tree: rawptr[ast.AST]) -> i
|
||||
|
||||
|
||||
# ---------------- init_symbol_table(委托 VarGenMixin.init_symbol_table) ----------------
|
||||
def init_symbol_table(pool: rawptr[memhub.MemBuddy]) -> GenTypes.SymbolTable | t.CPtr:
|
||||
def init_symbol_table(pool: rawptr[memhub.MemBuddy]) -> rawptr[GenTypes.SymbolTable]:
|
||||
"""委托到 gen.init_symbol_table(原 Handles 壳)"""
|
||||
if _g_gen is not None:
|
||||
return _g_gen.VarGen.init_symbol_table(pool)
|
||||
@@ -564,7 +564,7 @@ def init_func_table(pool: rawptr[memhub.MemBuddy], max_count: int) -> rawptr[Gen
|
||||
|
||||
|
||||
# ---------------- translate_call(委托 CallGenMixin.translate_call) ----------------
|
||||
def translate_call(pool: rawptr[memhub.MemBuddy], builder: llvmlite.IRBuilder | t.CPtr, mod: rawptr[llvmlite.LLVMModule], node: rawptr[ast.AST], funcs_ptr: t.CPtr, func_count: int, trans: rawptr[HT.Translator] = None) -> llvmlite.Value | t.CPtr:
|
||||
def translate_call(pool: rawptr[memhub.MemBuddy], builder: rawptr[llvmlite.IRBuilder], mod: rawptr[llvmlite.LLVMModule], node: rawptr[ast.AST], funcs_ptr: t.CPtr, func_count: int, trans: rawptr[HT.Translator] = None) -> rawptr[llvmlite.Value]:
|
||||
"""委托到 gen.translate_call(原 Handles 壳)"""
|
||||
if _g_gen is not None:
|
||||
return _g_gen.CallGen.translate_call(pool, builder, mod, node, funcs_ptr, func_count, trans)
|
||||
@@ -572,14 +572,14 @@ def translate_call(pool: rawptr[memhub.MemBuddy], builder: llvmlite.IRBuilder |
|
||||
|
||||
|
||||
# ---------------- translate_printf_call(委托 CallGenLeafKit.translate_printf_call) ----------------
|
||||
def translate_printf_call(pool: rawptr[memhub.MemBuddy], builder: llvmlite.IRBuilder | t.CPtr, mod: rawptr[llvmlite.LLVMModule], cl: rawptr[ast.Call], trans: rawptr[HT.Translator] = None):
|
||||
def translate_printf_call(pool: rawptr[memhub.MemBuddy], builder: rawptr[llvmlite.IRBuilder], mod: rawptr[llvmlite.LLVMModule], cl: rawptr[ast.Call], trans: rawptr[HT.Translator] = None):
|
||||
"""委托到 gen.translate_printf_call(原 Handles 壳)"""
|
||||
if _g_gen is not None:
|
||||
_g_gen.CallGenLeafKit.translate_printf_call(pool, builder, mod, cl, trans)
|
||||
|
||||
|
||||
# ---------------- translate_print_call(委托 CallGenLeafKit.translate_print_call) ----------------
|
||||
def translate_print_call(pool: rawptr[memhub.MemBuddy], builder: llvmlite.IRBuilder | t.CPtr, mod: rawptr[llvmlite.LLVMModule], cl: rawptr[ast.Call], trans: rawptr[HT.Translator] = None):
|
||||
def translate_print_call(pool: rawptr[memhub.MemBuddy], builder: rawptr[llvmlite.IRBuilder], mod: rawptr[llvmlite.LLVMModule], cl: rawptr[ast.Call], trans: rawptr[HT.Translator] = None):
|
||||
"""委托到 gen.translate_print_call(原 Handles 壳)"""
|
||||
if _g_gen is not None:
|
||||
_g_gen.CallGenLeafKit.translate_print_call(pool, builder, mod, cl, trans)
|
||||
|
||||
@@ -63,7 +63,7 @@ class TraceFrame:
|
||||
class VarEntry:
|
||||
"""变量表条目"""
|
||||
Name: str
|
||||
Alloca: llvmlite.Value | t.CPtr
|
||||
Alloca: rawptr[llvmlite.Value]
|
||||
Used: int
|
||||
# TypeSpec(S3 起为**唯一类型承载**):由 add_var 用 SpecFromLLVMType 从
|
||||
# alloca.Ty 的 pointee 填充(PermPool 分配 ⇒ 跨文件安全),注解侧再由
|
||||
@@ -71,7 +71,7 @@ class VarEntry:
|
||||
# 注解来源名(Spec.SourceName,原 AnnotClassName 字段已并入),由
|
||||
# set_var_ptr_element 经 SpecWithElemBits 补「指针元素」语义(原
|
||||
# IsPtrElement 字段已并入 Spec.ElemBits)。
|
||||
Spec: TSpec.TypeSpec | t.CPtr
|
||||
Spec: rawptr[TSpec.TypeSpec]
|
||||
|
||||
|
||||
# ============================================================
|
||||
@@ -109,7 +109,7 @@ class FieldEntry:
|
||||
# field_ty 填充(PermPool 分配 ⇒ 跨 1b reset 安全,无需 DeepCopyType),
|
||||
# 注解侧再经 SpecWithSign / SpecWithSource 补符号性与注解来源名
|
||||
# (Spec.SourceName,原 AnnotClassName 字段已并入)。
|
||||
Spec: TSpec.TypeSpec | t.CPtr
|
||||
Spec: rawptr[TSpec.TypeSpec]
|
||||
|
||||
|
||||
# ============================================================
|
||||
@@ -167,7 +167,7 @@ class EnumEntry:
|
||||
# ============================================================
|
||||
class AsmOperand:
|
||||
"""内联汇编操作数条目"""
|
||||
Value: llvmlite.Value | t.CPtr # 输入值或输出 alloca
|
||||
Value: rawptr[llvmlite.Value] # 输入值或输出 alloca
|
||||
Constraint: str # 约束字符串 (如 "r", "=r")
|
||||
IsOutput: int # 1=输出, 0=输入
|
||||
|
||||
@@ -187,7 +187,7 @@ class FuncEntry:
|
||||
# 都在其内),由 update_global_func_spec 在形参 add_param 完成后用 NewTypeFunc 构造。
|
||||
# PermPool 驻留 ⇒ 跨 1b reset 安全。单字段即可完整表达签名,与 VarEntry/FieldEntry
|
||||
# 的 Spec 命名一致,避免参数数组重复。
|
||||
Spec: TSpec.TypeSpec | t.CPtr
|
||||
Spec: rawptr[TSpec.TypeSpec]
|
||||
|
||||
|
||||
# ============================================================
|
||||
|
||||
@@ -68,381 +68,381 @@ class Generator:
|
||||
"""生成器:持所有 GenMixin 子对象指针(双向引用组合)"""
|
||||
|
||||
# ---- 子对象指针(46 个,永久池) ----
|
||||
BaseGen: BaseGenMixin.BaseGenMixin | t.CPtr
|
||||
TypeGenBase: TypeGenBase.TypeGenBase | t.CPtr
|
||||
TypeGen: TypeGenMixin.TypeGenMixin | t.CPtr
|
||||
TypeGenCDef: TypeGenCDef.TypeGenCDef | t.CPtr
|
||||
TypeGenCType: TypeGenCType.TypeGenCType | t.CPtr
|
||||
TypeGenResolve: TypeGenResolve.TypeGenResolve | t.CPtr
|
||||
TypeGenErr: TypeGenErr.TypeGenErr | t.CPtr
|
||||
StructGen: StructGenMixin.StructGenMixin | t.CPtr
|
||||
ExprGenBase: ExprGenBase.ExprGenBase | t.CPtr
|
||||
ExprGen: ExprGenMixin.ExprGenMixin | t.CPtr
|
||||
ExprGenConst: ExprGenConst.ExprGenConst | t.CPtr
|
||||
ExprGenFstr: ExprGenFstr.ExprGenFstr | t.CPtr
|
||||
ExprGenOps: ExprGenOps.ExprGenOps | t.CPtr
|
||||
ExprGenCdef: ExprGenCdef.ExprGenCdef | t.CPtr
|
||||
ExprGenName: ExprGenName.ExprGenName | t.CPtr
|
||||
ExprGenAttr: ExprGenAttr.ExprGenAttr | t.CPtr
|
||||
ExprGenCls: ExprGenCls.ExprGenCls | t.CPtr
|
||||
CallGenBase: CallGenBase.CallGenBase | t.CPtr
|
||||
CallGenCBuiltin: CallGenCBuiltin.CallGenCBuiltin | t.CPtr
|
||||
CallGenLeafKit: CallGenLeafKit.CallGenLeafKit | t.CPtr
|
||||
CallGenCtor: CallGenCtor.CallGenCtor | t.CPtr
|
||||
CallGenCall: CallGenCall.CallGenCall | t.CPtr
|
||||
CallGen: CallGenMixin.CallGenMixin | t.CPtr
|
||||
CallGenDispatch: CallGenDispatch.CallGenDispatch | t.CPtr
|
||||
CallGenLib: CallGenLib.CallGenLib | t.CPtr
|
||||
CallGenVt: CallGenVt.CallGenVt | t.CPtr
|
||||
CallGenVa: CallGenVa.CallGenVa | t.CPtr
|
||||
CallGenProp: CallGenProp.CallGenProp | t.CPtr
|
||||
CallGenFd: CallGenFd.CallGenFd | t.CPtr
|
||||
FuncGenBase: FuncGenBase.FuncGenBase | t.CPtr
|
||||
FuncGenDef: FuncGenDef.FuncGenDef | t.CPtr
|
||||
FuncGen: FuncGenMixin.FuncGenMixin | t.CPtr
|
||||
ClassGenBase: ClassGenBase.ClassGenBase | t.CPtr
|
||||
ClassGen: ClassGenMixin.ClassGenMixin | t.CPtr
|
||||
ClassGenEnum: ClassGenEnum.ClassGenEnum | t.CPtr
|
||||
ClassGenGeneric: ClassGenGeneric.ClassGenGeneric | t.CPtr
|
||||
ClassGenVTable: ClassGenVTable.ClassGenVTable | t.CPtr
|
||||
ClassGenDef: ClassGenDef.ClassGenDef | t.CPtr
|
||||
ImportsGen: ImportsGenMixin.ImportsGenMixin | t.CPtr
|
||||
StmtGenCif: StmtGenCifMixin.StmtGenCifMixin | t.CPtr
|
||||
StmtGenDecl: StmtGenDeclMixin.StmtGenDeclMixin | t.CPtr
|
||||
StmtGen: StmtGenMixin.StmtGenMixin | t.CPtr
|
||||
MatchGen: MatchGenMixin.MatchGenMixin | t.CPtr
|
||||
AssignGen: AssignGenMixin.AssignGenMixin | t.CPtr
|
||||
AsyncGen: AsyncGenMixin.AsyncGenMixin | t.CPtr
|
||||
VarGen: VarGenMixin.VarGenMixin | t.CPtr
|
||||
TranslatorGen: TranslatorGenMixin.TranslatorGenMixin | t.CPtr
|
||||
BaseGen: rawptr[BaseGenMixin.BaseGenMixin]
|
||||
TypeGenBase: rawptr[TypeGenBase.TypeGenBase]
|
||||
TypeGen: rawptr[TypeGenMixin.TypeGenMixin]
|
||||
TypeGenCDef: rawptr[TypeGenCDef.TypeGenCDef]
|
||||
TypeGenCType: rawptr[TypeGenCType.TypeGenCType]
|
||||
TypeGenResolve: rawptr[TypeGenResolve.TypeGenResolve]
|
||||
TypeGenErr: rawptr[TypeGenErr.TypeGenErr]
|
||||
StructGen: rawptr[StructGenMixin.StructGenMixin]
|
||||
ExprGenBase: rawptr[ExprGenBase.ExprGenBase]
|
||||
ExprGen: rawptr[ExprGenMixin.ExprGenMixin]
|
||||
ExprGenConst: rawptr[ExprGenConst.ExprGenConst]
|
||||
ExprGenFstr: rawptr[ExprGenFstr.ExprGenFstr]
|
||||
ExprGenOps: rawptr[ExprGenOps.ExprGenOps]
|
||||
ExprGenCdef: rawptr[ExprGenCdef.ExprGenCdef]
|
||||
ExprGenName: rawptr[ExprGenName.ExprGenName]
|
||||
ExprGenAttr: rawptr[ExprGenAttr.ExprGenAttr]
|
||||
ExprGenCls: rawptr[ExprGenCls.ExprGenCls]
|
||||
CallGenBase: rawptr[CallGenBase.CallGenBase]
|
||||
CallGenCBuiltin: rawptr[CallGenCBuiltin.CallGenCBuiltin]
|
||||
CallGenLeafKit: rawptr[CallGenLeafKit.CallGenLeafKit]
|
||||
CallGenCtor: rawptr[CallGenCtor.CallGenCtor]
|
||||
CallGenCall: rawptr[CallGenCall.CallGenCall]
|
||||
CallGen: rawptr[CallGenMixin.CallGenMixin]
|
||||
CallGenDispatch: rawptr[CallGenDispatch.CallGenDispatch]
|
||||
CallGenLib: rawptr[CallGenLib.CallGenLib]
|
||||
CallGenVt: rawptr[CallGenVt.CallGenVt]
|
||||
CallGenVa: rawptr[CallGenVa.CallGenVa]
|
||||
CallGenProp: rawptr[CallGenProp.CallGenProp]
|
||||
CallGenFd: rawptr[CallGenFd.CallGenFd]
|
||||
FuncGenBase: rawptr[FuncGenBase.FuncGenBase]
|
||||
FuncGenDef: rawptr[FuncGenDef.FuncGenDef]
|
||||
FuncGen: rawptr[FuncGenMixin.FuncGenMixin]
|
||||
ClassGenBase: rawptr[ClassGenBase.ClassGenBase]
|
||||
ClassGen: rawptr[ClassGenMixin.ClassGenMixin]
|
||||
ClassGenEnum: rawptr[ClassGenEnum.ClassGenEnum]
|
||||
ClassGenGeneric: rawptr[ClassGenGeneric.ClassGenGeneric]
|
||||
ClassGenVTable: rawptr[ClassGenVTable.ClassGenVTable]
|
||||
ClassGenDef: rawptr[ClassGenDef.ClassGenDef]
|
||||
ImportsGen: rawptr[ImportsGenMixin.ImportsGenMixin]
|
||||
StmtGenCif: rawptr[StmtGenCifMixin.StmtGenCifMixin]
|
||||
StmtGenDecl: rawptr[StmtGenDeclMixin.StmtGenDeclMixin]
|
||||
StmtGen: rawptr[StmtGenMixin.StmtGenMixin]
|
||||
MatchGen: rawptr[MatchGenMixin.MatchGenMixin]
|
||||
AssignGen: rawptr[AssignGenMixin.AssignGenMixin]
|
||||
AsyncGen: rawptr[AsyncGenMixin.AsyncGenMixin]
|
||||
VarGen: rawptr[VarGenMixin.VarGenMixin]
|
||||
TranslatorGen: rawptr[TranslatorGenMixin.TranslatorGenMixin]
|
||||
|
||||
def __init__(self, pool: rawptr[memhub.MemBuddy]):
|
||||
if self is None:
|
||||
return
|
||||
# ---- alloc 46 个子对象 + 回指(永久池,fail-fast) ----
|
||||
SubBaseGen: BaseGenMixin.BaseGenMixin | t.CPtr = CompilerFactory.factory.PermPool.alloc(BaseGenMixin.BaseGenMixin.__sizeof__())
|
||||
SubBaseGen: rawptr[BaseGenMixin.BaseGenMixin] = CompilerFactory.factory.PermPool.alloc(BaseGenMixin.BaseGenMixin.__sizeof__())
|
||||
if SubBaseGen is None:
|
||||
stdio.printf("FAIL: BaseGenMixin alloc failed\n")
|
||||
stdlib.exit(1)
|
||||
string.memset(SubBaseGen, 0, BaseGenMixin.BaseGenMixin.__sizeof__())
|
||||
SubBaseGen.Gen = self
|
||||
self.BaseGen = SubBaseGen
|
||||
SubTypeGenBase: TypeGenBase.TypeGenBase | t.CPtr = CompilerFactory.factory.PermPool.alloc(TypeGenBase.TypeGenBase.__sizeof__())
|
||||
SubTypeGenBase: rawptr[TypeGenBase.TypeGenBase] = CompilerFactory.factory.PermPool.alloc(TypeGenBase.TypeGenBase.__sizeof__())
|
||||
if SubTypeGenBase is None:
|
||||
stdio.printf("FAIL: TypeGenBase alloc failed\n")
|
||||
stdlib.exit(1)
|
||||
string.memset(SubTypeGenBase, 0, TypeGenBase.TypeGenBase.__sizeof__())
|
||||
SubTypeGenBase.Gen = self
|
||||
self.TypeGenBase = SubTypeGenBase
|
||||
SubTypeGen: TypeGenMixin.TypeGenMixin | t.CPtr = CompilerFactory.factory.PermPool.alloc(TypeGenMixin.TypeGenMixin.__sizeof__())
|
||||
SubTypeGen: rawptr[TypeGenMixin.TypeGenMixin] = CompilerFactory.factory.PermPool.alloc(TypeGenMixin.TypeGenMixin.__sizeof__())
|
||||
if SubTypeGen is None:
|
||||
stdio.printf("FAIL: TypeGenMixin alloc failed\n")
|
||||
stdlib.exit(1)
|
||||
string.memset(SubTypeGen, 0, TypeGenMixin.TypeGenMixin.__sizeof__())
|
||||
SubTypeGen.Gen = self
|
||||
self.TypeGen = SubTypeGen
|
||||
SubTypeGenCDef: TypeGenCDef.TypeGenCDef | t.CPtr = CompilerFactory.factory.PermPool.alloc(TypeGenCDef.TypeGenCDef.__sizeof__())
|
||||
SubTypeGenCDef: rawptr[TypeGenCDef.TypeGenCDef] = CompilerFactory.factory.PermPool.alloc(TypeGenCDef.TypeGenCDef.__sizeof__())
|
||||
if SubTypeGenCDef is None:
|
||||
stdio.printf("FAIL: TypeGenCDef alloc failed\n")
|
||||
stdlib.exit(1)
|
||||
string.memset(SubTypeGenCDef, 0, TypeGenCDef.TypeGenCDef.__sizeof__())
|
||||
SubTypeGenCDef.Gen = self
|
||||
self.TypeGenCDef = SubTypeGenCDef
|
||||
SubTypeGenCType: TypeGenCType.TypeGenCType | t.CPtr = CompilerFactory.factory.PermPool.alloc(TypeGenCType.TypeGenCType.__sizeof__())
|
||||
SubTypeGenCType: rawptr[TypeGenCType.TypeGenCType] = CompilerFactory.factory.PermPool.alloc(TypeGenCType.TypeGenCType.__sizeof__())
|
||||
if SubTypeGenCType is None:
|
||||
stdio.printf("FAIL: TypeGenCType alloc failed\n")
|
||||
stdlib.exit(1)
|
||||
string.memset(SubTypeGenCType, 0, TypeGenCType.TypeGenCType.__sizeof__())
|
||||
SubTypeGenCType.Gen = self
|
||||
self.TypeGenCType = SubTypeGenCType
|
||||
SubTypeGenResolve: TypeGenResolve.TypeGenResolve | t.CPtr = CompilerFactory.factory.PermPool.alloc(TypeGenResolve.TypeGenResolve.__sizeof__())
|
||||
SubTypeGenResolve: rawptr[TypeGenResolve.TypeGenResolve] = CompilerFactory.factory.PermPool.alloc(TypeGenResolve.TypeGenResolve.__sizeof__())
|
||||
if SubTypeGenResolve is None:
|
||||
stdio.printf("FAIL: TypeGenResolve alloc failed\n")
|
||||
stdlib.exit(1)
|
||||
string.memset(SubTypeGenResolve, 0, TypeGenResolve.TypeGenResolve.__sizeof__())
|
||||
SubTypeGenResolve.Gen = self
|
||||
self.TypeGenResolve = SubTypeGenResolve
|
||||
SubTypeGenErr: TypeGenErr.TypeGenErr | t.CPtr = CompilerFactory.factory.PermPool.alloc(TypeGenErr.TypeGenErr.__sizeof__())
|
||||
SubTypeGenErr: rawptr[TypeGenErr.TypeGenErr] = CompilerFactory.factory.PermPool.alloc(TypeGenErr.TypeGenErr.__sizeof__())
|
||||
if SubTypeGenErr is None:
|
||||
stdio.printf("FAIL: TypeGenErr alloc failed\n")
|
||||
stdlib.exit(1)
|
||||
string.memset(SubTypeGenErr, 0, TypeGenErr.TypeGenErr.__sizeof__())
|
||||
SubTypeGenErr.Gen = self
|
||||
self.TypeGenErr = SubTypeGenErr
|
||||
SubStructGen: StructGenMixin.StructGenMixin | t.CPtr = CompilerFactory.factory.PermPool.alloc(StructGenMixin.StructGenMixin.__sizeof__())
|
||||
SubStructGen: rawptr[StructGenMixin.StructGenMixin] = CompilerFactory.factory.PermPool.alloc(StructGenMixin.StructGenMixin.__sizeof__())
|
||||
if SubStructGen is None:
|
||||
stdio.printf("FAIL: StructGenMixin alloc failed\n")
|
||||
stdlib.exit(1)
|
||||
string.memset(SubStructGen, 0, StructGenMixin.StructGenMixin.__sizeof__())
|
||||
SubStructGen.Gen = self
|
||||
self.StructGen = SubStructGen
|
||||
SubExprGenBase: ExprGenBase.ExprGenBase | t.CPtr = CompilerFactory.factory.PermPool.alloc(ExprGenBase.ExprGenBase.__sizeof__())
|
||||
SubExprGenBase: rawptr[ExprGenBase.ExprGenBase] = CompilerFactory.factory.PermPool.alloc(ExprGenBase.ExprGenBase.__sizeof__())
|
||||
if SubExprGenBase is None:
|
||||
stdio.printf("FAIL: ExprGenBase alloc failed\n")
|
||||
stdlib.exit(1)
|
||||
string.memset(SubExprGenBase, 0, ExprGenBase.ExprGenBase.__sizeof__())
|
||||
SubExprGenBase.Gen = self
|
||||
self.ExprGenBase = SubExprGenBase
|
||||
SubExprGen: ExprGenMixin.ExprGenMixin | t.CPtr = CompilerFactory.factory.PermPool.alloc(ExprGenMixin.ExprGenMixin.__sizeof__())
|
||||
SubExprGen: rawptr[ExprGenMixin.ExprGenMixin] = CompilerFactory.factory.PermPool.alloc(ExprGenMixin.ExprGenMixin.__sizeof__())
|
||||
if SubExprGen is None:
|
||||
stdio.printf("FAIL: ExprGenMixin alloc failed\n")
|
||||
stdlib.exit(1)
|
||||
string.memset(SubExprGen, 0, ExprGenMixin.ExprGenMixin.__sizeof__())
|
||||
SubExprGen.Gen = self
|
||||
self.ExprGen = SubExprGen
|
||||
SubExprGenConst: ExprGenConst.ExprGenConst | t.CPtr = CompilerFactory.factory.PermPool.alloc(ExprGenConst.ExprGenConst.__sizeof__())
|
||||
SubExprGenConst: rawptr[ExprGenConst.ExprGenConst] = CompilerFactory.factory.PermPool.alloc(ExprGenConst.ExprGenConst.__sizeof__())
|
||||
if SubExprGenConst is None:
|
||||
stdio.printf("FAIL: ExprGenConst alloc failed\n")
|
||||
stdlib.exit(1)
|
||||
string.memset(SubExprGenConst, 0, ExprGenConst.ExprGenConst.__sizeof__())
|
||||
SubExprGenConst.Gen = self
|
||||
self.ExprGenConst = SubExprGenConst
|
||||
SubExprGenFstr: ExprGenFstr.ExprGenFstr | t.CPtr = CompilerFactory.factory.PermPool.alloc(ExprGenFstr.ExprGenFstr.__sizeof__())
|
||||
SubExprGenFstr: rawptr[ExprGenFstr.ExprGenFstr] = CompilerFactory.factory.PermPool.alloc(ExprGenFstr.ExprGenFstr.__sizeof__())
|
||||
if SubExprGenFstr is None:
|
||||
stdio.printf("FAIL: ExprGenFstr alloc failed\n")
|
||||
stdlib.exit(1)
|
||||
string.memset(SubExprGenFstr, 0, ExprGenFstr.ExprGenFstr.__sizeof__())
|
||||
SubExprGenFstr.Gen = self
|
||||
self.ExprGenFstr = SubExprGenFstr
|
||||
SubExprGenOps: ExprGenOps.ExprGenOps | t.CPtr = CompilerFactory.factory.PermPool.alloc(ExprGenOps.ExprGenOps.__sizeof__())
|
||||
SubExprGenOps: rawptr[ExprGenOps.ExprGenOps] = CompilerFactory.factory.PermPool.alloc(ExprGenOps.ExprGenOps.__sizeof__())
|
||||
if SubExprGenOps is None:
|
||||
stdio.printf("FAIL: ExprGenOps alloc failed\n")
|
||||
stdlib.exit(1)
|
||||
string.memset(SubExprGenOps, 0, ExprGenOps.ExprGenOps.__sizeof__())
|
||||
SubExprGenOps.Gen = self
|
||||
self.ExprGenOps = SubExprGenOps
|
||||
SubExprGenCdef: ExprGenCdef.ExprGenCdef | t.CPtr = CompilerFactory.factory.PermPool.alloc(ExprGenCdef.ExprGenCdef.__sizeof__())
|
||||
SubExprGenCdef: rawptr[ExprGenCdef.ExprGenCdef] = CompilerFactory.factory.PermPool.alloc(ExprGenCdef.ExprGenCdef.__sizeof__())
|
||||
if SubExprGenCdef is None:
|
||||
stdio.printf("FAIL: ExprGenCdef alloc failed\n")
|
||||
stdlib.exit(1)
|
||||
string.memset(SubExprGenCdef, 0, ExprGenCdef.ExprGenCdef.__sizeof__())
|
||||
SubExprGenCdef.Gen = self
|
||||
self.ExprGenCdef = SubExprGenCdef
|
||||
SubExprGenName: ExprGenName.ExprGenName | t.CPtr = CompilerFactory.factory.PermPool.alloc(ExprGenName.ExprGenName.__sizeof__())
|
||||
SubExprGenName: rawptr[ExprGenName.ExprGenName] = CompilerFactory.factory.PermPool.alloc(ExprGenName.ExprGenName.__sizeof__())
|
||||
if SubExprGenName is None:
|
||||
stdio.printf("FAIL: ExprGenName alloc failed\n")
|
||||
stdlib.exit(1)
|
||||
string.memset(SubExprGenName, 0, ExprGenName.ExprGenName.__sizeof__())
|
||||
SubExprGenName.Gen = self
|
||||
self.ExprGenName = SubExprGenName
|
||||
SubExprGenAttr: ExprGenAttr.ExprGenAttr | t.CPtr = CompilerFactory.factory.PermPool.alloc(ExprGenAttr.ExprGenAttr.__sizeof__())
|
||||
SubExprGenAttr: rawptr[ExprGenAttr.ExprGenAttr] = CompilerFactory.factory.PermPool.alloc(ExprGenAttr.ExprGenAttr.__sizeof__())
|
||||
if SubExprGenAttr is None:
|
||||
stdio.printf("FAIL: ExprGenAttr alloc failed\n")
|
||||
stdlib.exit(1)
|
||||
string.memset(SubExprGenAttr, 0, ExprGenAttr.ExprGenAttr.__sizeof__())
|
||||
SubExprGenAttr.Gen = self
|
||||
self.ExprGenAttr = SubExprGenAttr
|
||||
SubExprGenCls: ExprGenCls.ExprGenCls | t.CPtr = CompilerFactory.factory.PermPool.alloc(ExprGenCls.ExprGenCls.__sizeof__())
|
||||
SubExprGenCls: rawptr[ExprGenCls.ExprGenCls] = CompilerFactory.factory.PermPool.alloc(ExprGenCls.ExprGenCls.__sizeof__())
|
||||
if SubExprGenCls is None:
|
||||
stdio.printf("FAIL: ExprGenCls alloc failed\n")
|
||||
stdlib.exit(1)
|
||||
string.memset(SubExprGenCls, 0, ExprGenCls.ExprGenCls.__sizeof__())
|
||||
SubExprGenCls.Gen = self
|
||||
self.ExprGenCls = SubExprGenCls
|
||||
SubCallGenBase: CallGenBase.CallGenBase | t.CPtr = CompilerFactory.factory.PermPool.alloc(CallGenBase.CallGenBase.__sizeof__())
|
||||
SubCallGenBase: rawptr[CallGenBase.CallGenBase] = CompilerFactory.factory.PermPool.alloc(CallGenBase.CallGenBase.__sizeof__())
|
||||
if SubCallGenBase is None:
|
||||
stdio.printf("FAIL: CallGenBase alloc failed\n")
|
||||
stdlib.exit(1)
|
||||
string.memset(SubCallGenBase, 0, CallGenBase.CallGenBase.__sizeof__())
|
||||
SubCallGenBase.Gen = self
|
||||
self.CallGenBase = SubCallGenBase
|
||||
SubCallGenCBuiltin: CallGenCBuiltin.CallGenCBuiltin | t.CPtr = CompilerFactory.factory.PermPool.alloc(CallGenCBuiltin.CallGenCBuiltin.__sizeof__())
|
||||
SubCallGenCBuiltin: rawptr[CallGenCBuiltin.CallGenCBuiltin] = CompilerFactory.factory.PermPool.alloc(CallGenCBuiltin.CallGenCBuiltin.__sizeof__())
|
||||
if SubCallGenCBuiltin is None:
|
||||
stdio.printf("FAIL: CallGenCBuiltin alloc failed\n")
|
||||
stdlib.exit(1)
|
||||
string.memset(SubCallGenCBuiltin, 0, CallGenCBuiltin.CallGenCBuiltin.__sizeof__())
|
||||
SubCallGenCBuiltin.Gen = self
|
||||
self.CallGenCBuiltin = SubCallGenCBuiltin
|
||||
SubCallGenLeafKit: CallGenLeafKit.CallGenLeafKit | t.CPtr = CompilerFactory.factory.PermPool.alloc(CallGenLeafKit.CallGenLeafKit.__sizeof__())
|
||||
SubCallGenLeafKit: rawptr[CallGenLeafKit.CallGenLeafKit] = CompilerFactory.factory.PermPool.alloc(CallGenLeafKit.CallGenLeafKit.__sizeof__())
|
||||
if SubCallGenLeafKit is None:
|
||||
stdio.printf("FAIL: CallGenLeafKit alloc failed\n")
|
||||
stdlib.exit(1)
|
||||
string.memset(SubCallGenLeafKit, 0, CallGenLeafKit.CallGenLeafKit.__sizeof__())
|
||||
SubCallGenLeafKit.Gen = self
|
||||
self.CallGenLeafKit = SubCallGenLeafKit
|
||||
SubCallGenCtor: CallGenCtor.CallGenCtor | t.CPtr = CompilerFactory.factory.PermPool.alloc(CallGenCtor.CallGenCtor.__sizeof__())
|
||||
SubCallGenCtor: rawptr[CallGenCtor.CallGenCtor] = CompilerFactory.factory.PermPool.alloc(CallGenCtor.CallGenCtor.__sizeof__())
|
||||
if SubCallGenCtor is None:
|
||||
stdio.printf("FAIL: CallGenCtor alloc failed\n")
|
||||
stdlib.exit(1)
|
||||
string.memset(SubCallGenCtor, 0, CallGenCtor.CallGenCtor.__sizeof__())
|
||||
SubCallGenCtor.Gen = self
|
||||
self.CallGenCtor = SubCallGenCtor
|
||||
SubCallGenCall: CallGenCall.CallGenCall | t.CPtr = CompilerFactory.factory.PermPool.alloc(CallGenCall.CallGenCall.__sizeof__())
|
||||
SubCallGenCall: rawptr[CallGenCall.CallGenCall] = CompilerFactory.factory.PermPool.alloc(CallGenCall.CallGenCall.__sizeof__())
|
||||
if SubCallGenCall is None:
|
||||
stdio.printf("FAIL: CallGenCall alloc failed\n")
|
||||
stdlib.exit(1)
|
||||
string.memset(SubCallGenCall, 0, CallGenCall.CallGenCall.__sizeof__())
|
||||
SubCallGenCall.Gen = self
|
||||
self.CallGenCall = SubCallGenCall
|
||||
SubCallGen: CallGenMixin.CallGenMixin | t.CPtr = CompilerFactory.factory.PermPool.alloc(CallGenMixin.CallGenMixin.__sizeof__())
|
||||
SubCallGen: rawptr[CallGenMixin.CallGenMixin] = CompilerFactory.factory.PermPool.alloc(CallGenMixin.CallGenMixin.__sizeof__())
|
||||
if SubCallGen is None:
|
||||
stdio.printf("FAIL: CallGenMixin alloc failed\n")
|
||||
stdlib.exit(1)
|
||||
string.memset(SubCallGen, 0, CallGenMixin.CallGenMixin.__sizeof__())
|
||||
SubCallGen.Gen = self
|
||||
self.CallGen = SubCallGen
|
||||
SubCallGenDispatch: CallGenDispatch.CallGenDispatch | t.CPtr = CompilerFactory.factory.PermPool.alloc(CallGenDispatch.CallGenDispatch.__sizeof__())
|
||||
SubCallGenDispatch: rawptr[CallGenDispatch.CallGenDispatch] = CompilerFactory.factory.PermPool.alloc(CallGenDispatch.CallGenDispatch.__sizeof__())
|
||||
if SubCallGenDispatch is None:
|
||||
stdio.printf("FAIL: CallGenDispatch alloc failed\n")
|
||||
stdlib.exit(1)
|
||||
string.memset(SubCallGenDispatch, 0, CallGenDispatch.CallGenDispatch.__sizeof__())
|
||||
SubCallGenDispatch.Gen = self
|
||||
self.CallGenDispatch = SubCallGenDispatch
|
||||
SubCallGenLib: CallGenLib.CallGenLib | t.CPtr = CompilerFactory.factory.PermPool.alloc(CallGenLib.CallGenLib.__sizeof__())
|
||||
SubCallGenLib: rawptr[CallGenLib.CallGenLib] = CompilerFactory.factory.PermPool.alloc(CallGenLib.CallGenLib.__sizeof__())
|
||||
if SubCallGenLib is None:
|
||||
stdio.printf("FAIL: CallGenLib alloc failed\n")
|
||||
stdlib.exit(1)
|
||||
string.memset(SubCallGenLib, 0, CallGenLib.CallGenLib.__sizeof__())
|
||||
SubCallGenLib.Gen = self
|
||||
self.CallGenLib = SubCallGenLib
|
||||
SubCallGenVt: CallGenVt.CallGenVt | t.CPtr = CompilerFactory.factory.PermPool.alloc(CallGenVt.CallGenVt.__sizeof__())
|
||||
SubCallGenVt: rawptr[CallGenVt.CallGenVt] = CompilerFactory.factory.PermPool.alloc(CallGenVt.CallGenVt.__sizeof__())
|
||||
if SubCallGenVt is None:
|
||||
stdio.printf("FAIL: CallGenVt alloc failed\n")
|
||||
stdlib.exit(1)
|
||||
string.memset(SubCallGenVt, 0, CallGenVt.CallGenVt.__sizeof__())
|
||||
SubCallGenVt.Gen = self
|
||||
self.CallGenVt = SubCallGenVt
|
||||
SubCallGenVa: CallGenVa.CallGenVa | t.CPtr = CompilerFactory.factory.PermPool.alloc(CallGenVa.CallGenVa.__sizeof__())
|
||||
SubCallGenVa: rawptr[CallGenVa.CallGenVa] = CompilerFactory.factory.PermPool.alloc(CallGenVa.CallGenVa.__sizeof__())
|
||||
if SubCallGenVa is None:
|
||||
stdio.printf("FAIL: CallGenVa alloc failed\n")
|
||||
stdlib.exit(1)
|
||||
string.memset(SubCallGenVa, 0, CallGenVa.CallGenVa.__sizeof__())
|
||||
SubCallGenVa.Gen = self
|
||||
self.CallGenVa = SubCallGenVa
|
||||
SubCallGenProp: CallGenProp.CallGenProp | t.CPtr = CompilerFactory.factory.PermPool.alloc(CallGenProp.CallGenProp.__sizeof__())
|
||||
SubCallGenProp: rawptr[CallGenProp.CallGenProp] = CompilerFactory.factory.PermPool.alloc(CallGenProp.CallGenProp.__sizeof__())
|
||||
if SubCallGenProp is None:
|
||||
stdio.printf("FAIL: CallGenProp alloc failed\n")
|
||||
stdlib.exit(1)
|
||||
string.memset(SubCallGenProp, 0, CallGenProp.CallGenProp.__sizeof__())
|
||||
SubCallGenProp.Gen = self
|
||||
self.CallGenProp = SubCallGenProp
|
||||
SubCallGenFd: CallGenFd.CallGenFd | t.CPtr = CompilerFactory.factory.PermPool.alloc(CallGenFd.CallGenFd.__sizeof__())
|
||||
SubCallGenFd: rawptr[CallGenFd.CallGenFd] = CompilerFactory.factory.PermPool.alloc(CallGenFd.CallGenFd.__sizeof__())
|
||||
if SubCallGenFd is None:
|
||||
stdio.printf("FAIL: CallGenFd alloc failed\n")
|
||||
stdlib.exit(1)
|
||||
string.memset(SubCallGenFd, 0, CallGenFd.CallGenFd.__sizeof__())
|
||||
SubCallGenFd.Gen = self
|
||||
self.CallGenFd = SubCallGenFd
|
||||
SubFuncGenBase: FuncGenBase.FuncGenBase | t.CPtr = CompilerFactory.factory.PermPool.alloc(FuncGenBase.FuncGenBase.__sizeof__())
|
||||
SubFuncGenBase: rawptr[FuncGenBase.FuncGenBase] = CompilerFactory.factory.PermPool.alloc(FuncGenBase.FuncGenBase.__sizeof__())
|
||||
if SubFuncGenBase is None:
|
||||
stdio.printf("FAIL: FuncGenBase alloc failed\n")
|
||||
stdlib.exit(1)
|
||||
string.memset(SubFuncGenBase, 0, FuncGenBase.FuncGenBase.__sizeof__())
|
||||
SubFuncGenBase.Gen = self
|
||||
self.FuncGenBase = SubFuncGenBase
|
||||
SubFuncGenDef: FuncGenDef.FuncGenDef | t.CPtr = CompilerFactory.factory.PermPool.alloc(FuncGenDef.FuncGenDef.__sizeof__())
|
||||
SubFuncGenDef: rawptr[FuncGenDef.FuncGenDef] = CompilerFactory.factory.PermPool.alloc(FuncGenDef.FuncGenDef.__sizeof__())
|
||||
if SubFuncGenDef is None:
|
||||
stdio.printf("FAIL: FuncGenDef alloc failed\n")
|
||||
stdlib.exit(1)
|
||||
string.memset(SubFuncGenDef, 0, FuncGenDef.FuncGenDef.__sizeof__())
|
||||
SubFuncGenDef.Gen = self
|
||||
self.FuncGenDef = SubFuncGenDef
|
||||
SubFuncGen: FuncGenMixin.FuncGenMixin | t.CPtr = CompilerFactory.factory.PermPool.alloc(FuncGenMixin.FuncGenMixin.__sizeof__())
|
||||
SubFuncGen: rawptr[FuncGenMixin.FuncGenMixin] = CompilerFactory.factory.PermPool.alloc(FuncGenMixin.FuncGenMixin.__sizeof__())
|
||||
if SubFuncGen is None:
|
||||
stdio.printf("FAIL: FuncGenMixin alloc failed\n")
|
||||
stdlib.exit(1)
|
||||
string.memset(SubFuncGen, 0, FuncGenMixin.FuncGenMixin.__sizeof__())
|
||||
SubFuncGen.Gen = self
|
||||
self.FuncGen = SubFuncGen
|
||||
SubClassGenBase: ClassGenBase.ClassGenBase | t.CPtr = CompilerFactory.factory.PermPool.alloc(ClassGenBase.ClassGenBase.__sizeof__())
|
||||
SubClassGenBase: rawptr[ClassGenBase.ClassGenBase] = CompilerFactory.factory.PermPool.alloc(ClassGenBase.ClassGenBase.__sizeof__())
|
||||
if SubClassGenBase is None:
|
||||
stdio.printf("FAIL: ClassGenBase alloc failed\n")
|
||||
stdlib.exit(1)
|
||||
string.memset(SubClassGenBase, 0, ClassGenBase.ClassGenBase.__sizeof__())
|
||||
SubClassGenBase.Gen = self
|
||||
self.ClassGenBase = SubClassGenBase
|
||||
SubClassGen: ClassGenMixin.ClassGenMixin | t.CPtr = CompilerFactory.factory.PermPool.alloc(ClassGenMixin.ClassGenMixin.__sizeof__())
|
||||
SubClassGen: rawptr[ClassGenMixin.ClassGenMixin] = CompilerFactory.factory.PermPool.alloc(ClassGenMixin.ClassGenMixin.__sizeof__())
|
||||
if SubClassGen is None:
|
||||
stdio.printf("FAIL: ClassGenMixin alloc failed\n")
|
||||
stdlib.exit(1)
|
||||
string.memset(SubClassGen, 0, ClassGenMixin.ClassGenMixin.__sizeof__())
|
||||
SubClassGen.Gen = self
|
||||
self.ClassGen = SubClassGen
|
||||
SubClassGenEnum: ClassGenEnum.ClassGenEnum | t.CPtr = CompilerFactory.factory.PermPool.alloc(ClassGenEnum.ClassGenEnum.__sizeof__())
|
||||
SubClassGenEnum: rawptr[ClassGenEnum.ClassGenEnum] = CompilerFactory.factory.PermPool.alloc(ClassGenEnum.ClassGenEnum.__sizeof__())
|
||||
if SubClassGenEnum is None:
|
||||
stdio.printf("FAIL: ClassGenEnum alloc failed\n")
|
||||
stdlib.exit(1)
|
||||
string.memset(SubClassGenEnum, 0, ClassGenEnum.ClassGenEnum.__sizeof__())
|
||||
SubClassGenEnum.Gen = self
|
||||
self.ClassGenEnum = SubClassGenEnum
|
||||
SubClassGenGeneric: ClassGenGeneric.ClassGenGeneric | t.CPtr = CompilerFactory.factory.PermPool.alloc(ClassGenGeneric.ClassGenGeneric.__sizeof__())
|
||||
SubClassGenGeneric: rawptr[ClassGenGeneric.ClassGenGeneric] = CompilerFactory.factory.PermPool.alloc(ClassGenGeneric.ClassGenGeneric.__sizeof__())
|
||||
if SubClassGenGeneric is None:
|
||||
stdio.printf("FAIL: ClassGenGeneric alloc failed\n")
|
||||
stdlib.exit(1)
|
||||
string.memset(SubClassGenGeneric, 0, ClassGenGeneric.ClassGenGeneric.__sizeof__())
|
||||
SubClassGenGeneric.Gen = self
|
||||
self.ClassGenGeneric = SubClassGenGeneric
|
||||
SubClassGenVTable: ClassGenVTable.ClassGenVTable | t.CPtr = CompilerFactory.factory.PermPool.alloc(ClassGenVTable.ClassGenVTable.__sizeof__())
|
||||
SubClassGenVTable: rawptr[ClassGenVTable.ClassGenVTable] = CompilerFactory.factory.PermPool.alloc(ClassGenVTable.ClassGenVTable.__sizeof__())
|
||||
if SubClassGenVTable is None:
|
||||
stdio.printf("FAIL: ClassGenVTable alloc failed\n")
|
||||
stdlib.exit(1)
|
||||
string.memset(SubClassGenVTable, 0, ClassGenVTable.ClassGenVTable.__sizeof__())
|
||||
SubClassGenVTable.Gen = self
|
||||
self.ClassGenVTable = SubClassGenVTable
|
||||
SubClassGenDef: ClassGenDef.ClassGenDef | t.CPtr = CompilerFactory.factory.PermPool.alloc(ClassGenDef.ClassGenDef.__sizeof__())
|
||||
SubClassGenDef: rawptr[ClassGenDef.ClassGenDef] = CompilerFactory.factory.PermPool.alloc(ClassGenDef.ClassGenDef.__sizeof__())
|
||||
if SubClassGenDef is None:
|
||||
stdio.printf("FAIL: ClassGenDef alloc failed\n")
|
||||
stdlib.exit(1)
|
||||
string.memset(SubClassGenDef, 0, ClassGenDef.ClassGenDef.__sizeof__())
|
||||
SubClassGenDef.Gen = self
|
||||
self.ClassGenDef = SubClassGenDef
|
||||
SubImportsGen: ImportsGenMixin.ImportsGenMixin | t.CPtr = CompilerFactory.factory.PermPool.alloc(ImportsGenMixin.ImportsGenMixin.__sizeof__())
|
||||
SubImportsGen: rawptr[ImportsGenMixin.ImportsGenMixin] = CompilerFactory.factory.PermPool.alloc(ImportsGenMixin.ImportsGenMixin.__sizeof__())
|
||||
if SubImportsGen is None:
|
||||
stdio.printf("FAIL: ImportsGenMixin alloc failed\n")
|
||||
stdlib.exit(1)
|
||||
string.memset(SubImportsGen, 0, ImportsGenMixin.ImportsGenMixin.__sizeof__())
|
||||
SubImportsGen.Gen = self
|
||||
self.ImportsGen = SubImportsGen
|
||||
SubStmtGenCif: StmtGenCifMixin.StmtGenCifMixin | t.CPtr = CompilerFactory.factory.PermPool.alloc(StmtGenCifMixin.StmtGenCifMixin.__sizeof__())
|
||||
SubStmtGenCif: rawptr[StmtGenCifMixin.StmtGenCifMixin] = CompilerFactory.factory.PermPool.alloc(StmtGenCifMixin.StmtGenCifMixin.__sizeof__())
|
||||
if SubStmtGenCif is None:
|
||||
stdio.printf("FAIL: StmtGenCifMixin alloc failed\n")
|
||||
stdlib.exit(1)
|
||||
string.memset(SubStmtGenCif, 0, StmtGenCifMixin.StmtGenCifMixin.__sizeof__())
|
||||
SubStmtGenCif.Gen = self
|
||||
self.StmtGenCif = SubStmtGenCif
|
||||
SubStmtGenDecl: StmtGenDeclMixin.StmtGenDeclMixin | t.CPtr = CompilerFactory.factory.PermPool.alloc(StmtGenDeclMixin.StmtGenDeclMixin.__sizeof__())
|
||||
SubStmtGenDecl: rawptr[StmtGenDeclMixin.StmtGenDeclMixin] = CompilerFactory.factory.PermPool.alloc(StmtGenDeclMixin.StmtGenDeclMixin.__sizeof__())
|
||||
if SubStmtGenDecl is None:
|
||||
stdio.printf("FAIL: StmtGenDeclMixin alloc failed\n")
|
||||
stdlib.exit(1)
|
||||
string.memset(SubStmtGenDecl, 0, StmtGenDeclMixin.StmtGenDeclMixin.__sizeof__())
|
||||
SubStmtGenDecl.Gen = self
|
||||
self.StmtGenDecl = SubStmtGenDecl
|
||||
SubStmtGen: StmtGenMixin.StmtGenMixin | t.CPtr = CompilerFactory.factory.PermPool.alloc(StmtGenMixin.StmtGenMixin.__sizeof__())
|
||||
SubStmtGen: rawptr[StmtGenMixin.StmtGenMixin] = CompilerFactory.factory.PermPool.alloc(StmtGenMixin.StmtGenMixin.__sizeof__())
|
||||
if SubStmtGen is None:
|
||||
stdio.printf("FAIL: StmtGenMixin alloc failed\n")
|
||||
stdlib.exit(1)
|
||||
string.memset(SubStmtGen, 0, StmtGenMixin.StmtGenMixin.__sizeof__())
|
||||
SubStmtGen.Gen = self
|
||||
self.StmtGen = SubStmtGen
|
||||
SubMatchGen: MatchGenMixin.MatchGenMixin | t.CPtr = CompilerFactory.factory.PermPool.alloc(MatchGenMixin.MatchGenMixin.__sizeof__())
|
||||
SubMatchGen: rawptr[MatchGenMixin.MatchGenMixin] = CompilerFactory.factory.PermPool.alloc(MatchGenMixin.MatchGenMixin.__sizeof__())
|
||||
if SubMatchGen is None:
|
||||
stdio.printf("FAIL: MatchGenMixin alloc failed\n")
|
||||
stdlib.exit(1)
|
||||
string.memset(SubMatchGen, 0, MatchGenMixin.MatchGenMixin.__sizeof__())
|
||||
SubMatchGen.Gen = self
|
||||
self.MatchGen = SubMatchGen
|
||||
SubAssignGen: AssignGenMixin.AssignGenMixin | t.CPtr = CompilerFactory.factory.PermPool.alloc(AssignGenMixin.AssignGenMixin.__sizeof__())
|
||||
SubAssignGen: rawptr[AssignGenMixin.AssignGenMixin] = CompilerFactory.factory.PermPool.alloc(AssignGenMixin.AssignGenMixin.__sizeof__())
|
||||
if SubAssignGen is None:
|
||||
stdio.printf("FAIL: AssignGenMixin alloc failed\n")
|
||||
stdlib.exit(1)
|
||||
string.memset(SubAssignGen, 0, AssignGenMixin.AssignGenMixin.__sizeof__())
|
||||
SubAssignGen.Gen = self
|
||||
self.AssignGen = SubAssignGen
|
||||
SubVarGen: VarGenMixin.VarGenMixin | t.CPtr = CompilerFactory.factory.PermPool.alloc(VarGenMixin.VarGenMixin.__sizeof__())
|
||||
SubVarGen: rawptr[VarGenMixin.VarGenMixin] = CompilerFactory.factory.PermPool.alloc(VarGenMixin.VarGenMixin.__sizeof__())
|
||||
if SubVarGen is None:
|
||||
stdio.printf("FAIL: VarGenMixin alloc failed\n")
|
||||
stdlib.exit(1)
|
||||
string.memset(SubVarGen, 0, VarGenMixin.VarGenMixin.__sizeof__())
|
||||
SubVarGen.Gen = self
|
||||
self.VarGen = SubVarGen
|
||||
SubTranslatorGen: TranslatorGenMixin.TranslatorGenMixin | t.CPtr = CompilerFactory.factory.PermPool.alloc(TranslatorGenMixin.TranslatorGenMixin.__sizeof__())
|
||||
SubTranslatorGen: rawptr[TranslatorGenMixin.TranslatorGenMixin] = CompilerFactory.factory.PermPool.alloc(TranslatorGenMixin.TranslatorGenMixin.__sizeof__())
|
||||
if SubTranslatorGen is None:
|
||||
stdio.printf("FAIL: TranslatorGenMixin alloc failed\n")
|
||||
stdlib.exit(1)
|
||||
string.memset(SubTranslatorGen, 0, TranslatorGenMixin.TranslatorGenMixin.__sizeof__())
|
||||
SubTranslatorGen.Gen = self
|
||||
self.TranslatorGen = SubTranslatorGen
|
||||
SubAsyncGen: AsyncGenMixin.AsyncGenMixin | t.CPtr = CompilerFactory.factory.PermPool.alloc(AsyncGenMixin.AsyncGenMixin.__sizeof__())
|
||||
SubAsyncGen: rawptr[AsyncGenMixin.AsyncGenMixin] = CompilerFactory.factory.PermPool.alloc(AsyncGenMixin.AsyncGenMixin.__sizeof__())
|
||||
if SubAsyncGen is None:
|
||||
stdio.printf("FAIL: AsyncGenMixin alloc failed\n")
|
||||
stdlib.exit(1)
|
||||
|
||||
@@ -53,10 +53,10 @@ class ImportsGenMixin:
|
||||
# 索引表用 PermPool 分配(跨文件/Phase 存活),由对应 add_* 增量维护;key/value
|
||||
# 均为指向该扁平串内部的指针,串在文件级 reset 前始终有效。
|
||||
CurImportedModulesPtr: str
|
||||
CurImportedModulesNames: hashtable.HashTable | t.CPtr
|
||||
CurImportedModulesNames: rawptr[hashtable.HashTable]
|
||||
CurFromImportsPtr: str
|
||||
CurFromImportsMods: hashtable.HashTable | t.CPtr
|
||||
CurFromImportsOrigs: hashtable.HashTable | t.CPtr
|
||||
CurFromImportsMods: rawptr[hashtable.HashTable]
|
||||
CurFromImportsOrigs: rawptr[hashtable.HashTable]
|
||||
|
||||
# 注意:不声明 CurrentFile 字段——TypeGenMixin 已声明(Generator 展平块
|
||||
# 只有一份,跨父类不去重规则下重复声明会导致字段错位)。本 Mixin 的
|
||||
@@ -76,7 +76,7 @@ class ImportsGenMixin:
|
||||
perm: rawptr[memhub.MemBuddy] = CompilerFactory.factory.PermPool
|
||||
if perm is None:
|
||||
return
|
||||
idx: hashtable.HashTable | t.CPtr = None
|
||||
idx: rawptr[hashtable.HashTable] = None
|
||||
if old_ptr is None:
|
||||
# 新文件/新链首:建全新索引(旧索引随旧串一起废弃)
|
||||
idx = hashtable.HashTable(perm)
|
||||
@@ -112,8 +112,8 @@ class ImportsGenMixin:
|
||||
perm: rawptr[memhub.MemBuddy] = CompilerFactory.factory.PermPool
|
||||
if perm is None:
|
||||
return
|
||||
idx_m: hashtable.HashTable | t.CPtr = None
|
||||
idx_o: hashtable.HashTable | t.CPtr = None
|
||||
idx_m: rawptr[hashtable.HashTable] = None
|
||||
idx_o: rawptr[hashtable.HashTable] = None
|
||||
if old_ptr is None:
|
||||
idx_m = hashtable.HashTable(perm)
|
||||
idx_o = hashtable.HashTable(perm)
|
||||
@@ -819,7 +819,7 @@ class ImportsGenMixin:
|
||||
imp: rawptr[ast.Import] = rawptr[ast.Import](node)
|
||||
if imp is None:
|
||||
return 0
|
||||
names: list[rawptr[ast.AST]] | t.CPtr = imp.names
|
||||
names: rawptr[list[rawptr[ast.AST]]] = imp.names
|
||||
if names is None:
|
||||
return 0
|
||||
nn: sizet = len(names)
|
||||
@@ -893,7 +893,7 @@ class ImportsGenMixin:
|
||||
# 否则别名 "syscall" 精确匹配不到包名 "vpsdk" → is_module_imported 返回 0
|
||||
# → syscall._syscall1 / syscall.LOAD_SO 跨模块解析失败。
|
||||
if impf.module is None:
|
||||
names_m: list[rawptr[ast.AST]] | t.CPtr = impf.names
|
||||
names_m: rawptr[list[rawptr[ast.AST]]] = impf.names
|
||||
if names_m is not None:
|
||||
nn_m: sizet = len(names_m)
|
||||
for ni_m in range(nn_m):
|
||||
@@ -937,7 +937,7 @@ class ImportsGenMixin:
|
||||
trans.Pool, trans.CurrentPackage,
|
||||
impf.level, impf.module)
|
||||
if resolved is not None:
|
||||
names: list[rawptr[ast.AST]] | t.CPtr = impf.names
|
||||
names: rawptr[list[rawptr[ast.AST]]] = impf.names
|
||||
if names is not None:
|
||||
nn: sizet = len(names)
|
||||
for ni in range(nn):
|
||||
|
||||
+130
-130
@@ -38,8 +38,8 @@ class MatchGenMixin:
|
||||
# 不含 Try/With:其处理器不维护 _ctrl_merge_reachable,避免残留值误判。
|
||||
Gen: rawptr[Generator.Generator]
|
||||
def _case_tail_unreachable(self, trans: rawptr[HT.Translator],
|
||||
builder: llvmlite.IRBuilder | t.CPtr,
|
||||
body_list: list[rawptr[ast.AST]] | t.CPtr) -> int:
|
||||
builder: rawptr[llvmlite.IRBuilder],
|
||||
body_list: rawptr[list[rawptr[ast.AST]]]) -> int:
|
||||
if trans is None or builder is None:
|
||||
return 0
|
||||
if llvmlite.builder_cur_block_is_terminated(builder) != 0:
|
||||
@@ -80,7 +80,7 @@ class MatchGenMixin:
|
||||
if node is None:
|
||||
return 0
|
||||
pool: rawptr[memhub.MemBuddy] = trans.Pool
|
||||
builder: llvmlite.IRBuilder | t.CPtr = trans._cur_builder
|
||||
builder: rawptr[llvmlite.IRBuilder] = trans._cur_builder
|
||||
func: rawptr[llvmlite.Function] = trans._cur_func
|
||||
if builder is None or func is None:
|
||||
return 0
|
||||
@@ -102,7 +102,7 @@ class MatchGenMixin:
|
||||
sk_seq: int = subject_node.kind()
|
||||
if sk_seq == ast.ASTKind.Tuple or sk_seq == ast.ASTKind.List:
|
||||
return self._handle_sequence_match(trans, m_node, subject_node)
|
||||
subject_val: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
|
||||
subject_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, trans.Module, subject_node,
|
||||
trans._funcs, trans._func_count, trans)
|
||||
if subject_val is None:
|
||||
@@ -112,13 +112,13 @@ class MatchGenMixin:
|
||||
# 2. 检测是否 REnum match
|
||||
is_renum: int = 0
|
||||
renum_name: str = None
|
||||
subject_ptr: llvmlite.Value | t.CPtr = None
|
||||
subject_ptr: rawptr[llvmlite.Value] = None
|
||||
|
||||
# 2a. 若 subject 是 Name,查变量注解类名
|
||||
if subject_node.kind() == ast.ASTKind.Name:
|
||||
nm: rawptr[ast.Name] = rawptr[ast.Name](subject_node)
|
||||
if nm.id is not None:
|
||||
entry: GenTypes.VarEntry | t.CPtr = self.Gen.VarGen.lookup_var_entry(
|
||||
entry: rawptr[GenTypes.VarEntry] = self.Gen.VarGen.lookup_var_entry(
|
||||
trans.SymTab, nm.id)
|
||||
entry_annot: str = self.Gen.VarGen.var_annot_class_name(entry)
|
||||
if entry_annot is not None \
|
||||
@@ -132,7 +132,7 @@ class MatchGenMixin:
|
||||
|
||||
# 2b. 若未确定,遍历 cases 查 MatchClass 变体
|
||||
if is_renum == 0:
|
||||
cases_list: list[rawptr[ast.AST]] | t.CPtr = m_node.cases
|
||||
cases_list: rawptr[list[rawptr[ast.AST]]] = m_node.cases
|
||||
if cases_list is not None:
|
||||
cn: sizet = len(cases_list)
|
||||
ci: int = 0
|
||||
@@ -140,8 +140,8 @@ class MatchGenMixin:
|
||||
case_node: rawptr[ast.AST] = cases_list.get(ci)
|
||||
if case_node is not None \
|
||||
and case_node.kind() == ast.ASTKind.MatchCase:
|
||||
mc: ast.MatchCase | t.CPtr = (
|
||||
ast.MatchCase | t.CPtr)(case_node)
|
||||
mc: rawptr[ast.MatchCase] = (
|
||||
rawptr[ast.MatchCase])(case_node)
|
||||
pat: rawptr[ast.AST] = mc.pattern
|
||||
if pat is not None \
|
||||
and pat.kind() == ast.ASTKind.MatchClass:
|
||||
@@ -171,7 +171,7 @@ class MatchGenMixin:
|
||||
pattern: rawptr[ast.AST]) -> str:
|
||||
if pattern is None:
|
||||
return None
|
||||
mc: ast.MatchClass | t.CPtr = (ast.MatchClass | t.CPtr)(pattern)
|
||||
mc: rawptr[ast.MatchClass] = rawptr[ast.MatchClass](pattern)
|
||||
cls_node: rawptr[ast.AST] = mc.cls
|
||||
if cls_node is None:
|
||||
return None
|
||||
@@ -199,7 +199,7 @@ class MatchGenMixin:
|
||||
pattern: rawptr[ast.AST]) -> str:
|
||||
if pattern is None:
|
||||
return None
|
||||
mc: ast.MatchClass | t.CPtr = (ast.MatchClass | t.CPtr)(pattern)
|
||||
mc: rawptr[ast.MatchClass] = rawptr[ast.MatchClass](pattern)
|
||||
cls_node: rawptr[ast.AST] = mc.cls
|
||||
if cls_node is None:
|
||||
return None
|
||||
@@ -227,7 +227,7 @@ class MatchGenMixin:
|
||||
#
|
||||
# 遍历 case body 顶层语句,查找 Expr(Call(Attribute(Name('c'), 'NoBreak')))
|
||||
# ============================================================
|
||||
def _has_no_break(self, body_list: list[rawptr[ast.AST]] | t.CPtr) -> int:
|
||||
def _has_no_break(self, body_list: rawptr[list[rawptr[ast.AST]]]) -> int:
|
||||
if body_list is None:
|
||||
return 0
|
||||
n: sizet = len(body_list)
|
||||
@@ -235,7 +235,7 @@ class MatchGenMixin:
|
||||
while i < n:
|
||||
stmt: rawptr[ast.AST] = body_list.get(i)
|
||||
if stmt is not None and stmt.kind() == ast.ASTKind.Expr:
|
||||
expr_node: ast.Expr | t.CPtr = (ast.Expr | t.CPtr)(stmt)
|
||||
expr_node: rawptr[ast.Expr] = rawptr[ast.Expr](stmt)
|
||||
val: rawptr[ast.AST] = expr_node.value
|
||||
if val is not None and val.kind() == ast.ASTKind.Call:
|
||||
call_node: rawptr[ast.Call] = rawptr[ast.Call](val)
|
||||
@@ -266,9 +266,9 @@ class MatchGenMixin:
|
||||
def _handle_renum_match(self, trans: rawptr[HT.Translator],
|
||||
node: rawptr[ast.Match],
|
||||
renum_name: str,
|
||||
subject_ptr: llvmlite.Value | t.CPtr) -> int:
|
||||
subject_ptr: rawptr[llvmlite.Value]) -> int:
|
||||
pool: rawptr[memhub.MemBuddy] = trans.Pool
|
||||
builder: llvmlite.IRBuilder | t.CPtr = trans._cur_builder
|
||||
builder: rawptr[llvmlite.IRBuilder] = trans._cur_builder
|
||||
func: rawptr[llvmlite.Function] = trans._cur_func
|
||||
# 局部记录本 renum match 是否有 br 进入 end_bb,收尾时覆盖
|
||||
# _ctrl_merge_reachable(case 体内嵌套 If 无 else + return 会把全局
|
||||
@@ -288,7 +288,7 @@ class MatchGenMixin:
|
||||
and subj_ty.Pointee is not None \
|
||||
and self.Gen.ExprGenBase.is_ptr_type(subj_ty.Pointee) != 0:
|
||||
# 情况1: T** → load 一次得 T*
|
||||
loaded_sub: llvmlite.Value | t.CPtr = llvmlite.build_load(
|
||||
loaded_sub: rawptr[llvmlite.Value] = llvmlite.build_load(
|
||||
builder, subj_ty.Pointee, subject_ptr)
|
||||
if loaded_sub is not None:
|
||||
subject_ptr = loaded_sub
|
||||
@@ -296,7 +296,7 @@ class MatchGenMixin:
|
||||
# 值型 subject 来自 REnum payload 槽位 load(槽位类型 i64,存的是指针),
|
||||
# 所以直接 inttoptr 到 renum_sty* 即可,无需 alloca+store
|
||||
if subject_ptr.Ty is None or self.Gen.ExprGenBase.is_ptr_type(subject_ptr.Ty) == 0:
|
||||
renum_se: GenTypes.StructEntry | t.CPtr = self.Gen.StructGen.find_struct(
|
||||
renum_se: rawptr[GenTypes.StructEntry] = self.Gen.StructGen.find_struct(
|
||||
renum_name)
|
||||
renum_sty: rawptr[llvmlite.LLVMType] = None
|
||||
if renum_se is not None:
|
||||
@@ -308,7 +308,7 @@ class MatchGenMixin:
|
||||
f"REnum 结构体 '{renum_name}' 未注册",
|
||||
"NameError")
|
||||
i64_ty0: rawptr[llvmlite.LLVMType] = llvmlite.Int64(pool)
|
||||
int_val: llvmlite.Value | t.CPtr = subject_ptr
|
||||
int_val: rawptr[llvmlite.Value] = subject_ptr
|
||||
# 非 i64 整数值先扩展/截断到 i64(inttoptr 要求同宽)
|
||||
# 仅当 subj_ty 是已知整数类型时转换;类型未知时保持原值
|
||||
if subj_ty is not None and self.Gen.ExprGenBase.get_llvm_type_bits(subj_ty) != 64 \
|
||||
@@ -318,7 +318,7 @@ class MatchGenMixin:
|
||||
else:
|
||||
int_val = llvmlite.build_zext(builder, subject_ptr, i64_ty0)
|
||||
renum_ptr_ty0: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, renum_sty)
|
||||
subj_ptr0: llvmlite.Value | t.CPtr = llvmlite.build_inttoptr(
|
||||
subj_ptr0: rawptr[llvmlite.Value] = llvmlite.build_inttoptr(
|
||||
builder, int_val, renum_ptr_ty0)
|
||||
if subj_ptr0 is not None:
|
||||
subject_ptr = subj_ptr0
|
||||
@@ -326,12 +326,12 @@ class MatchGenMixin:
|
||||
# 1. bitcast subject 到 i32* 读 __tag
|
||||
i32_ty: rawptr[llvmlite.LLVMType] = llvmlite.Int32(pool)
|
||||
i32_ptr_ty: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, i32_ty)
|
||||
tag_ptr: llvmlite.Value | t.CPtr = llvmlite.build_bitcast(
|
||||
tag_ptr: rawptr[llvmlite.Value] = llvmlite.build_bitcast(
|
||||
builder, subject_ptr, i32_ptr_ty)
|
||||
if tag_ptr is None:
|
||||
# fail-fast: REnum tag 指针转换失败
|
||||
self.Gen.TypeGenErr.fatal_error(node, "REnum tag 指针转换失败", "TypeError")
|
||||
tag_val: llvmlite.Value | t.CPtr = llvmlite.build_load(
|
||||
tag_val: rawptr[llvmlite.Value] = llvmlite.build_load(
|
||||
builder, i32_ty, tag_ptr)
|
||||
if tag_val is None:
|
||||
# fail-fast: REnum tag 读取失败
|
||||
@@ -345,14 +345,14 @@ class MatchGenMixin:
|
||||
# fail-fast: 标签缓冲区分配失败
|
||||
self.Gen.TypeGenErr.fatal_error(node, "标签缓冲区分配失败", "TypeError")
|
||||
viperlib.snprintf(name_buf, 32, "match.default.%d", cnt)
|
||||
default_bb: llvmlite.BasicBlock | t.CPtr = llvmlite.create_block(
|
||||
default_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(
|
||||
pool, func, name_buf)
|
||||
viperlib.snprintf(name_buf, 32, "match.end.%d", cnt)
|
||||
end_bb: llvmlite.BasicBlock | t.CPtr = llvmlite.create_block(
|
||||
end_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(
|
||||
pool, func, name_buf)
|
||||
|
||||
# 3. 准备收集数组(用 CSizeT 数组存指针)
|
||||
cases_list: list[rawptr[ast.AST]] | t.CPtr = node.cases
|
||||
cases_list: rawptr[list[rawptr[ast.AST]]] = node.cases
|
||||
if cases_list is None:
|
||||
# fail-fast: match cases 缺失
|
||||
self.Gen.TypeGenErr.fatal_error(node, "match cases 缺失", "TypeError")
|
||||
@@ -374,8 +374,8 @@ class MatchGenMixin:
|
||||
has_default: int = 0
|
||||
|
||||
# SwitchCase 链表
|
||||
sw_head: llvmlite.SwitchCase | t.CPtr = None
|
||||
sw_tail: llvmlite.SwitchCase | t.CPtr = None
|
||||
sw_head: rawptr[llvmlite.SwitchCase] = None
|
||||
sw_tail: rawptr[llvmlite.SwitchCase] = None
|
||||
sw_count: int = 0
|
||||
|
||||
# 应提交 case 的臂计数(非 default 且模式必须产出 case 值:MatchClass
|
||||
@@ -410,11 +410,11 @@ class MatchGenMixin:
|
||||
if case_node.kind() != ast.ASTKind.MatchCase:
|
||||
i = i + 1
|
||||
continue
|
||||
mc: ast.MatchCase | t.CPtr = (ast.MatchCase | t.CPtr)(case_node)
|
||||
mc: rawptr[ast.MatchCase] = rawptr[ast.MatchCase](case_node)
|
||||
pat: rawptr[ast.AST] = mc.pattern
|
||||
|
||||
is_def: int = 0
|
||||
cv: llvmlite.Value | t.CPtr = None
|
||||
cv: rawptr[llvmlite.Value] = None
|
||||
# 修复: 提升到臂作用域(原先声明在 MatchClass 分支内),供下方
|
||||
# "未取到 case 值"诊断打印变体名/tag
|
||||
vnm: str = None
|
||||
@@ -440,25 +440,25 @@ class MatchGenMixin:
|
||||
cv = llvmlite.ConstInt(pool, i32_ty, tag,
|
||||
tag_buf if tag_buf is not None else "0")
|
||||
elif pk == ast.ASTKind.MatchAs:
|
||||
ma: ast.MatchAs | t.CPtr = (ast.MatchAs | t.CPtr)(pat)
|
||||
ma: rawptr[ast.MatchAs] = rawptr[ast.MatchAs](pat)
|
||||
if ma.pattern is None:
|
||||
is_def = 1
|
||||
has_default = 1
|
||||
elif pk == ast.ASTKind.MatchValue:
|
||||
mv: ast.MatchValue | t.CPtr = (ast.MatchValue | t.CPtr)(pat)
|
||||
mv: rawptr[ast.MatchValue] = rawptr[ast.MatchValue](pat)
|
||||
cv = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, trans.Module, mv.value,
|
||||
trans._funcs, trans._func_count, trans)
|
||||
elif pk == ast.ASTKind.MatchOr:
|
||||
# MatchOr: 多个值共享一个 BB(取第一个值做 case)
|
||||
mo: ast.MatchOr | t.CPtr = (ast.MatchOr | t.CPtr)(pat)
|
||||
pats: list[rawptr[ast.AST]] | t.CPtr = mo.patterns
|
||||
mo: rawptr[ast.MatchOr] = rawptr[ast.MatchOr](pat)
|
||||
pats: rawptr[list[rawptr[ast.AST]]] = mo.patterns
|
||||
if pats is not None and len(pats) > 0:
|
||||
first_pat: rawptr[ast.AST] = pats.get(0)
|
||||
if first_pat is not None \
|
||||
and first_pat.kind() == ast.ASTKind.MatchValue:
|
||||
mv2: ast.MatchValue | t.CPtr = (
|
||||
ast.MatchValue | t.CPtr)(first_pat)
|
||||
mv2: rawptr[ast.MatchValue] = (
|
||||
rawptr[ast.MatchValue])(first_pat)
|
||||
cv = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, trans.Module, mv2.value,
|
||||
trans._funcs, trans._func_count, trans)
|
||||
@@ -468,13 +468,13 @@ class MatchGenMixin:
|
||||
if collected >= MAX_MATCH_CASES:
|
||||
break
|
||||
viperlib.snprintf(name_buf, 32, "match.case.%d.%d", cnt, i)
|
||||
bb: llvmlite.BasicBlock | t.CPtr = llvmlite.create_block(
|
||||
bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(
|
||||
pool, func, name_buf)
|
||||
else:
|
||||
bb = default_bb
|
||||
|
||||
# 检测 NoBreak
|
||||
body_list: list[rawptr[ast.AST]] | t.CPtr = mc.children
|
||||
body_list: rawptr[list[rawptr[ast.AST]]] = mc.children
|
||||
nb: int = self._has_no_break(body_list)
|
||||
|
||||
# 存入数组
|
||||
@@ -496,7 +496,7 @@ class MatchGenMixin:
|
||||
|
||||
# 构建 SwitchCase 链表(非 default case 且有值)
|
||||
if is_def == 0 and cv is not None:
|
||||
sc: llvmlite.SwitchCase | t.CPtr = llvmlite.new_switch_case(
|
||||
sc: rawptr[llvmlite.SwitchCase] = llvmlite.new_switch_case(
|
||||
pool, cv, bb)
|
||||
if sc is not None:
|
||||
if sw_head is None:
|
||||
@@ -533,9 +533,9 @@ class MatchGenMixin:
|
||||
llvmlite.build_switch(builder, tag_val, default_bb, sw_head, sw_count)
|
||||
|
||||
# 6. 查找 REnum 结构体类型(用于变体字段绑定的 GEP)
|
||||
renum_entry: GenTypes.StructEntry | t.CPtr = None
|
||||
renum_entry: rawptr[GenTypes.StructEntry] = None
|
||||
renum_ty: rawptr[llvmlite.LLVMType] = None
|
||||
se: GenTypes.StructEntry | t.CPtr = self.Gen.StructGen.find_struct(renum_name)
|
||||
se: rawptr[GenTypes.StructEntry] = self.Gen.StructGen.find_struct(renum_name)
|
||||
if se is not None:
|
||||
renum_entry = se
|
||||
renum_ty = se.Ty
|
||||
@@ -544,7 +544,7 @@ class MatchGenMixin:
|
||||
i = 0
|
||||
while i < collected:
|
||||
# pass2 用 pass1 缓存的 mc(避免重索引错位)
|
||||
mc: ast.MatchCase | t.CPtr = (ast.MatchCase | t.CPtr)(mc_arr[i])
|
||||
mc: rawptr[ast.MatchCase] = rawptr[ast.MatchCase](mc_arr[i])
|
||||
if mc is None:
|
||||
i = i + 1
|
||||
continue
|
||||
@@ -552,8 +552,8 @@ class MatchGenMixin:
|
||||
|
||||
# 取 BB
|
||||
bb_addr: sizet = bb_arr[i]
|
||||
case_bb: llvmlite.BasicBlock | t.CPtr = (
|
||||
llvmlite.BasicBlock | t.CPtr)(bb_addr)
|
||||
case_bb: rawptr[llvmlite.BasicBlock] = (
|
||||
rawptr[llvmlite.BasicBlock])(bb_addr)
|
||||
is_def: int = def_arr[i]
|
||||
nb: int = nb_arr[i]
|
||||
|
||||
@@ -576,7 +576,7 @@ class MatchGenMixin:
|
||||
subject_ptr, trans, pool, builder)
|
||||
|
||||
# 翻译 case body
|
||||
body_list: list[rawptr[ast.AST]] | t.CPtr = mc.children
|
||||
body_list: rawptr[list[rawptr[ast.AST]]] = mc.children
|
||||
if body_list is not None:
|
||||
bc: sizet = len(body_list)
|
||||
bi: int = 0
|
||||
@@ -614,20 +614,20 @@ class MatchGenMixin:
|
||||
rm_merge_reach = 1
|
||||
else:
|
||||
# 有显式 default:翻译 default case body(找到 is_def==1 的 case)
|
||||
dbody: list[rawptr[ast.AST]] | t.CPtr = None
|
||||
dbody: rawptr[list[rawptr[ast.AST]]] = None
|
||||
di: int = 0
|
||||
while di < collected:
|
||||
if def_arr[di] == 1:
|
||||
dcase: rawptr[ast.AST] = cases_list.get(di)
|
||||
if dcase is not None:
|
||||
dmc: ast.MatchCase | t.CPtr = (
|
||||
ast.MatchCase | t.CPtr)(dcase)
|
||||
dmc: rawptr[ast.MatchCase] = (
|
||||
rawptr[ast.MatchCase])(dcase)
|
||||
self.Gen.VarGen.enter_scope(trans.SymTab, SCOPE_MATCH)
|
||||
# dbody 预声明+重赋值会使 .get 误分派成 list[int].get
|
||||
# (i32→inttoptr 截断指针 → translate_stmt 读垃圾节点崩溃,
|
||||
# gen1 IR 证据)。用 dbody2 内联声明接收者遍历(对齐
|
||||
# Converter arg_defaults 内联声明规避模式)。
|
||||
dbody2: list[rawptr[ast.AST]] | t.CPtr = dmc.children
|
||||
dbody2: rawptr[list[rawptr[ast.AST]]] = dmc.children
|
||||
dbody = dbody2
|
||||
if dbody2 is not None:
|
||||
dn: sizet = len(dbody2)
|
||||
@@ -661,21 +661,21 @@ class MatchGenMixin:
|
||||
# ============================================================
|
||||
def _bind_variant_fields(self, pat: rawptr[ast.AST],
|
||||
renum_name: str,
|
||||
renum_entry: GenTypes.StructEntry | t.CPtr,
|
||||
renum_entry: rawptr[GenTypes.StructEntry],
|
||||
renum_ty: rawptr[llvmlite.LLVMType],
|
||||
subject_ptr: llvmlite.Value | t.CPtr,
|
||||
subject_ptr: rawptr[llvmlite.Value],
|
||||
trans: rawptr[HT.Translator],
|
||||
pool: rawptr[memhub.MemBuddy],
|
||||
builder: llvmlite.IRBuilder | t.CPtr):
|
||||
builder: rawptr[llvmlite.IRBuilder]):
|
||||
if pat is None or renum_entry is None or renum_ty is None:
|
||||
return
|
||||
mc: ast.MatchClass | t.CPtr = (ast.MatchClass | t.CPtr)(pat)
|
||||
pats: list[rawptr[ast.AST]] | t.CPtr = mc.patterns
|
||||
mc: rawptr[ast.MatchClass] = rawptr[ast.MatchClass](pat)
|
||||
pats: rawptr[list[rawptr[ast.AST]]] = mc.patterns
|
||||
if pats is None:
|
||||
return
|
||||
# bitcast subject_ptr 到 renum_ptr_ty(确保 GEP 类型匹配)
|
||||
renum_ptr_ty: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, renum_ty)
|
||||
casted_ptr: llvmlite.Value | t.CPtr = llvmlite.build_bitcast(
|
||||
casted_ptr: rawptr[llvmlite.Value] = llvmlite.build_bitcast(
|
||||
builder, subject_ptr, renum_ptr_ty)
|
||||
if casted_ptr is None:
|
||||
casted_ptr = subject_ptr
|
||||
@@ -684,7 +684,7 @@ class MatchGenMixin:
|
||||
while j < pn:
|
||||
sub_pat: rawptr[ast.AST] = pats.get(j)
|
||||
if sub_pat is not None and sub_pat.kind() == ast.ASTKind.MatchAs:
|
||||
ma: ast.MatchAs | t.CPtr = (ast.MatchAs | t.CPtr)(sub_pat)
|
||||
ma: rawptr[ast.MatchAs] = rawptr[ast.MatchAs](sub_pat)
|
||||
bind_name: str = ma.name
|
||||
if bind_name is not None:
|
||||
# 按位置绑定:MatchClass 第 j 个参数 → payload 索引 j+1
|
||||
@@ -709,7 +709,7 @@ class MatchGenMixin:
|
||||
f"REnum 变体字段 '{bind_name}' 在结构体 '{renum_name}' 中越界且别名查找失败",
|
||||
"TypeError")
|
||||
# 获取字段类型
|
||||
fe: GenTypes.FieldEntry | t.CPtr = (
|
||||
fe: rawptr[GenTypes.FieldEntry] = (
|
||||
self.Gen.StructGen._get_field_entry(
|
||||
renum_entry, payload_idx))
|
||||
field_ty: rawptr[llvmlite.LLVMType] = None
|
||||
@@ -722,7 +722,7 @@ class MatchGenMixin:
|
||||
f"REnum 变体字段类型缺失: {bind_name}",
|
||||
"TypeError")
|
||||
# GEP 取字段地址
|
||||
elem_ptr: llvmlite.Value | t.CPtr = (
|
||||
elem_ptr: rawptr[llvmlite.Value] = (
|
||||
llvmlite.build_gep_struct(
|
||||
builder, renum_ty, field_ty,
|
||||
casted_ptr, payload_idx))
|
||||
@@ -749,7 +749,7 @@ class MatchGenMixin:
|
||||
mem_ptr_m: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(
|
||||
pool, mem_ty_m)
|
||||
if mem_ptr_m is not None:
|
||||
cast_m: llvmlite.Value | t.CPtr = llvmlite.build_bitcast(
|
||||
cast_m: rawptr[llvmlite.Value] = llvmlite.build_bitcast(
|
||||
builder, elem_ptr, mem_ptr_m)
|
||||
if cast_m is not None:
|
||||
elem_ptr = cast_m
|
||||
@@ -764,9 +764,9 @@ class MatchGenMixin:
|
||||
# 生成 icmp eq,返回 i1 条件。
|
||||
# ============================================================
|
||||
def _seq_cmp_eq(self, trans: rawptr[HT.Translator],
|
||||
builder: llvmlite.IRBuilder | t.CPtr,
|
||||
lhs: llvmlite.Value | t.CPtr,
|
||||
rhs: llvmlite.Value | t.CPtr) -> llvmlite.Value | t.CPtr:
|
||||
builder: rawptr[llvmlite.IRBuilder],
|
||||
lhs: rawptr[llvmlite.Value],
|
||||
rhs: rawptr[llvmlite.Value]) -> rawptr[llvmlite.Value]:
|
||||
"""对齐 lhs/rhs 后生成 icmp eq(指针统一 ptrtoint i64)"""
|
||||
if lhs is None or rhs is None or builder is None:
|
||||
return None
|
||||
@@ -812,7 +812,7 @@ class MatchGenMixin:
|
||||
node: rawptr[ast.Match],
|
||||
subject_node: rawptr[ast.AST]) -> int:
|
||||
pool: rawptr[memhub.MemBuddy] = trans.Pool
|
||||
builder: llvmlite.IRBuilder | t.CPtr = trans._cur_builder
|
||||
builder: rawptr[llvmlite.IRBuilder] = trans._cur_builder
|
||||
func: rawptr[llvmlite.Function] = trans._cur_func
|
||||
if builder is None or func is None:
|
||||
return 0
|
||||
@@ -821,13 +821,13 @@ class MatchGenMixin:
|
||||
sq_merge_reach: int = 0
|
||||
|
||||
# 1. 求值 subject 各元素
|
||||
elts: list[rawptr[ast.AST]] | t.CPtr = None
|
||||
elts: rawptr[list[rawptr[ast.AST]]] = None
|
||||
if subject_node.kind() == ast.ASTKind.Tuple:
|
||||
st: rawptr[ast.Tuple] = rawptr[ast.Tuple](subject_node)
|
||||
if st is not None:
|
||||
elts = st.elts
|
||||
elif subject_node.kind() == ast.ASTKind.List:
|
||||
sl2: ast.List | t.CPtr = (ast.List | t.CPtr)(subject_node)
|
||||
sl2: rawptr[ast.List] = rawptr[ast.List](subject_node)
|
||||
if sl2 is not None:
|
||||
elts = sl2.elts
|
||||
if elts is None:
|
||||
@@ -841,9 +841,9 @@ class MatchGenMixin:
|
||||
for ei in range(ecount):
|
||||
# elts 预声明+重赋值会把 .get 误分派成 list[int].get(i32 截断);
|
||||
# 用内联别名接收者规避(对齐 Converter arg_defaults 内联模式)
|
||||
elts_inl: list[rawptr[ast.AST]] | t.CPtr = elts
|
||||
elts_inl: rawptr[list[rawptr[ast.AST]]] = elts
|
||||
elt: rawptr[ast.AST] = elts_inl.get(ei)
|
||||
sv: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
|
||||
sv: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, trans.Module, elt,
|
||||
trans._funcs, trans._func_count, trans)
|
||||
if sv is None:
|
||||
@@ -858,14 +858,14 @@ class MatchGenMixin:
|
||||
if name_buf is None:
|
||||
return 0
|
||||
viperlib.snprintf(name_buf, 32, "match.seq.default.%d", cnt)
|
||||
default_bb: llvmlite.BasicBlock | t.CPtr = llvmlite.create_block(
|
||||
default_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(
|
||||
pool, func, name_buf)
|
||||
viperlib.snprintf(name_buf, 32, "match.seq.end.%d", cnt)
|
||||
end_bb: llvmlite.BasicBlock | t.CPtr = llvmlite.create_block(
|
||||
end_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(
|
||||
pool, func, name_buf)
|
||||
|
||||
# 3. 第一遍:收集 case 信息(check/body BB、default 标记、nobreak、guard)
|
||||
cases_list: list[rawptr[ast.AST]] | t.CPtr = node.cases
|
||||
cases_list: rawptr[list[rawptr[ast.AST]]] = node.cases
|
||||
if cases_list is None:
|
||||
return 0
|
||||
case_count: sizet = len(cases_list)
|
||||
@@ -897,13 +897,13 @@ class MatchGenMixin:
|
||||
if case_node is None or case_node.kind() != ast.ASTKind.MatchCase:
|
||||
i = i + 1
|
||||
continue
|
||||
mc: ast.MatchCase | t.CPtr = (ast.MatchCase | t.CPtr)(case_node)
|
||||
mc: rawptr[ast.MatchCase] = rawptr[ast.MatchCase](case_node)
|
||||
pat: rawptr[ast.AST] = mc.pattern
|
||||
is_def: int = 0
|
||||
if pat is not None:
|
||||
pk: int = pat.kind()
|
||||
if pk == ast.ASTKind.MatchAs:
|
||||
ma0: ast.MatchAs | t.CPtr = (ast.MatchAs | t.CPtr)(pat)
|
||||
ma0: rawptr[ast.MatchAs] = rawptr[ast.MatchAs](pat)
|
||||
if ma0.pattern is None:
|
||||
is_def = 1
|
||||
elif pk != ast.ASTKind.MatchSequence:
|
||||
@@ -918,16 +918,16 @@ class MatchGenMixin:
|
||||
if collected >= MAX_MATCH_CASES:
|
||||
break
|
||||
viperlib.snprintf(name_buf, 32, "match.seq.check.%d.%d", cnt, i)
|
||||
cbb: llvmlite.BasicBlock | t.CPtr = llvmlite.create_block(
|
||||
cbb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(
|
||||
pool, func, name_buf)
|
||||
viperlib.snprintf(name_buf, 32, "match.seq.body.%d.%d", cnt, i)
|
||||
bbb: llvmlite.BasicBlock | t.CPtr = llvmlite.create_block(
|
||||
bbb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(
|
||||
pool, func, name_buf)
|
||||
check_arr[collected] = sizet(cbb)
|
||||
body_arr[collected] = sizet(bbb)
|
||||
if first_check < 0:
|
||||
first_check = collected
|
||||
body_list: list[rawptr[ast.AST]] | t.CPtr = mc.children
|
||||
body_list: rawptr[list[rawptr[ast.AST]]] = mc.children
|
||||
nb: int = self._has_no_break(body_list)
|
||||
def_arr[collected] = is_def
|
||||
nb_arr[collected] = nb
|
||||
@@ -937,7 +937,7 @@ class MatchGenMixin:
|
||||
|
||||
# 4. 入口 → 第一个 check(或 default/end)
|
||||
if first_check >= 0:
|
||||
head_bb: llvmlite.BasicBlock | t.CPtr = (llvmlite.BasicBlock | t.CPtr)(check_arr[first_check])
|
||||
head_bb: rawptr[llvmlite.BasicBlock] = rawptr[llvmlite.BasicBlock](check_arr[first_check])
|
||||
llvmlite.build_br(builder, head_bb)
|
||||
elif has_default == 1:
|
||||
llvmlite.build_br(builder, default_bb)
|
||||
@@ -950,17 +950,17 @@ class MatchGenMixin:
|
||||
if def_arr[ci] == 1:
|
||||
ci = ci + 1
|
||||
continue
|
||||
cbb2: llvmlite.BasicBlock | t.CPtr = (llvmlite.BasicBlock | t.CPtr)(check_arr[ci], t.CPtr)
|
||||
bbb2: llvmlite.BasicBlock | t.CPtr = (llvmlite.BasicBlock | t.CPtr)(body_arr[ci], t.CPtr)
|
||||
cbb2: rawptr[llvmlite.BasicBlock] = rawptr[llvmlite.BasicBlock](check_arr[ci], t.CPtr)
|
||||
bbb2: rawptr[llvmlite.BasicBlock] = rawptr[llvmlite.BasicBlock](body_arr[ci], t.CPtr)
|
||||
llvmlite.position_at_end(builder, cbb2)
|
||||
|
||||
# 计算匹配条件(元素比较 && guard)
|
||||
cond: llvmlite.Value | t.CPtr = None
|
||||
cond: rawptr[llvmlite.Value] = None
|
||||
cnode: rawptr[ast.AST] = cases_list.get(ci)
|
||||
mc2: ast.MatchCase | t.CPtr = (ast.MatchCase | t.CPtr)(cnode)
|
||||
ms: ast.MatchSequence | t.CPtr = (
|
||||
ast.MatchSequence | t.CPtr)(mc2.pattern)
|
||||
pats: list[rawptr[ast.AST]] | t.CPtr = None
|
||||
mc2: rawptr[ast.MatchCase] = rawptr[ast.MatchCase](cnode)
|
||||
ms: rawptr[ast.MatchSequence] = (
|
||||
rawptr[ast.MatchSequence])(mc2.pattern)
|
||||
pats: rawptr[list[rawptr[ast.AST]]] = None
|
||||
if ms is not None:
|
||||
pats = ms.patterns
|
||||
pcount: sizet = 0
|
||||
@@ -973,22 +973,22 @@ class MatchGenMixin:
|
||||
for pi in range(ecount):
|
||||
# pats 预声明+重赋值会把 .get 误分派成 list[int].get(i32 截断);
|
||||
# 用内联别名接收者规避(对齐 Converter arg_defaults 内联模式)
|
||||
pats_inl: list[rawptr[ast.AST]] | t.CPtr = pats
|
||||
pats_inl: rawptr[list[rawptr[ast.AST]]] = pats
|
||||
pat1: rawptr[ast.AST] = pats_inl.get(pi)
|
||||
if pat1 is None:
|
||||
continue
|
||||
pk1: int = pat1.kind()
|
||||
if pk1 == ast.ASTKind.MatchValue:
|
||||
mv: ast.MatchValue | t.CPtr = (
|
||||
ast.MatchValue | t.CPtr)(pat1)
|
||||
pv: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
|
||||
mv: rawptr[ast.MatchValue] = (
|
||||
rawptr[ast.MatchValue])(pat1)
|
||||
pv: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, trans.Module, mv.value,
|
||||
trans._funcs, trans._func_count, trans)
|
||||
if pv is None:
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
pat1, f"序列模式元素 {pi} 翻译失败", "TypeError")
|
||||
sv1: llvmlite.Value | t.CPtr = (llvmlite.Value | t.CPtr)(subj_vals[pi], t.CPtr)
|
||||
c1: llvmlite.Value | t.CPtr = self._seq_cmp_eq(trans, builder, sv1, pv)
|
||||
sv1: rawptr[llvmlite.Value] = rawptr[llvmlite.Value](subj_vals[pi], t.CPtr)
|
||||
c1: rawptr[llvmlite.Value] = self._seq_cmp_eq(trans, builder, sv1, pv)
|
||||
if c1 is None:
|
||||
self.Gen.TypeGenErr.fatal_error(pat1, "序列模式元素比较失败", "TypeError")
|
||||
if cond is None:
|
||||
@@ -996,7 +996,7 @@ class MatchGenMixin:
|
||||
else:
|
||||
cond = llvmlite.build_and(builder, cond, c1)
|
||||
elif pk1 == ast.ASTKind.MatchAs:
|
||||
ma2: ast.MatchAs | t.CPtr = (ast.MatchAs | t.CPtr)(pat1)
|
||||
ma2: rawptr[ast.MatchAs] = rawptr[ast.MatchAs](pat1)
|
||||
if ma2.pattern is None:
|
||||
continue # _ 通配:恒真
|
||||
if ma2.name is not None:
|
||||
@@ -1012,7 +1012,7 @@ class MatchGenMixin:
|
||||
g_addr: sizet = guard_arr[ci]
|
||||
if g_addr != 0:
|
||||
gnode: rawptr[ast.AST] = (rawptr[ast.AST])(g_addr)
|
||||
gv: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
|
||||
gv: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, trans.Module, gnode,
|
||||
trans._funcs, trans._func_count, trans)
|
||||
if gv is None:
|
||||
@@ -1020,9 +1020,9 @@ class MatchGenMixin:
|
||||
gnode, "match guard 翻译失败", "TypeError")
|
||||
gbits: int = self.Gen.ExprGenBase.get_llvm_type_bits(gv.Ty)
|
||||
if gbits == 1:
|
||||
g1: llvmlite.Value | t.CPtr = gv
|
||||
g1: rawptr[llvmlite.Value] = gv
|
||||
else:
|
||||
gzero: llvmlite.Value | t.CPtr = llvmlite.const_int(
|
||||
gzero: rawptr[llvmlite.Value] = llvmlite.const_int(
|
||||
pool, gbits if gbits > 0 else 32, 0)
|
||||
g1 = llvmlite.build_icmp(
|
||||
builder, llvmlite.ICMP_NE, gv, gzero)
|
||||
@@ -1034,12 +1034,12 @@ class MatchGenMixin:
|
||||
cond = llvmlite.const_int(pool, 1, 1)
|
||||
|
||||
# 下一个 check(或 default/end)
|
||||
nxt: llvmlite.BasicBlock | t.CPtr = None
|
||||
nxt: rawptr[llvmlite.BasicBlock] = None
|
||||
nj: int = ci + 1
|
||||
while nj < collected and def_arr[nj] == 1:
|
||||
nj = nj + 1
|
||||
if nj < collected:
|
||||
nxt = (llvmlite.BasicBlock | t.CPtr)(check_arr[nj])
|
||||
nxt = rawptr[llvmlite.BasicBlock](check_arr[nj])
|
||||
elif has_default == 1:
|
||||
nxt = default_bb
|
||||
else:
|
||||
@@ -1053,13 +1053,13 @@ class MatchGenMixin:
|
||||
if def_arr[ci] == 1:
|
||||
ci = ci + 1
|
||||
continue
|
||||
bbb3: llvmlite.BasicBlock | t.CPtr = (llvmlite.BasicBlock | t.CPtr)(body_arr[ci])
|
||||
bbb3: rawptr[llvmlite.BasicBlock] = rawptr[llvmlite.BasicBlock](body_arr[ci])
|
||||
llvmlite.position_at_end(builder, bbb3)
|
||||
cnode2: rawptr[ast.AST] = cases_list.get(ci)
|
||||
mc3: ast.MatchCase | t.CPtr = (
|
||||
ast.MatchCase | t.CPtr)(cnode2)
|
||||
mc3: rawptr[ast.MatchCase] = (
|
||||
rawptr[ast.MatchCase])(cnode2)
|
||||
self.Gen.VarGen.enter_scope(trans.SymTab, SCOPE_MATCH)
|
||||
body_list2: list[rawptr[ast.AST]] | t.CPtr = mc3.children
|
||||
body_list2: rawptr[list[rawptr[ast.AST]]] = mc3.children
|
||||
if body_list2 is not None:
|
||||
bc: sizet = len(body_list2)
|
||||
bi: int = 0
|
||||
@@ -1080,7 +1080,7 @@ class MatchGenMixin:
|
||||
while nj2 < collected and def_arr[nj2] == 1:
|
||||
nj2 = nj2 + 1
|
||||
if nj2 < collected:
|
||||
nbb: llvmlite.BasicBlock | t.CPtr = (llvmlite.BasicBlock | t.CPtr)(body_arr[nj2])
|
||||
nbb: rawptr[llvmlite.BasicBlock] = rawptr[llvmlite.BasicBlock](body_arr[nj2])
|
||||
llvmlite.build_br(builder, nbb)
|
||||
elif has_default == 1:
|
||||
llvmlite.build_br(builder, default_bb)
|
||||
@@ -1092,21 +1092,21 @@ class MatchGenMixin:
|
||||
|
||||
# 7. default 块
|
||||
llvmlite.position_at_end(builder, default_bb)
|
||||
dbody: list[rawptr[ast.AST]] | t.CPtr = None
|
||||
dbody: rawptr[list[rawptr[ast.AST]]] = None
|
||||
if has_default == 1:
|
||||
di: int = 0
|
||||
while di < collected:
|
||||
if def_arr[di] == 1:
|
||||
dnode: rawptr[ast.AST] = cases_list.get(di)
|
||||
if dnode is not None:
|
||||
dmc: ast.MatchCase | t.CPtr = (
|
||||
ast.MatchCase | t.CPtr)(dnode)
|
||||
dmc: rawptr[ast.MatchCase] = (
|
||||
rawptr[ast.MatchCase])(dnode)
|
||||
self.Gen.VarGen.enter_scope(trans.SymTab, SCOPE_MATCH)
|
||||
# dbody 预声明+重赋值会使 .get 误分派成 list[int].get
|
||||
# (i32→inttoptr 截断指针 → translate_stmt 读垃圾节点崩溃,
|
||||
# gen1 IR 证据)。用 dbody2 内联声明接收者遍历(对齐
|
||||
# Converter arg_defaults 内联声明规避模式)。
|
||||
dbody2: list[rawptr[ast.AST]] | t.CPtr = dmc.children
|
||||
dbody2: rawptr[list[rawptr[ast.AST]]] = dmc.children
|
||||
dbody = dbody2
|
||||
if dbody2 is not None:
|
||||
dn: sizet = len(dbody2)
|
||||
@@ -1138,9 +1138,9 @@ class MatchGenMixin:
|
||||
# ============================================================
|
||||
def _handle_simple_match(self, trans: rawptr[HT.Translator],
|
||||
node: rawptr[ast.Match],
|
||||
subject_val: llvmlite.Value | t.CPtr) -> int:
|
||||
subject_val: rawptr[llvmlite.Value]) -> int:
|
||||
pool: rawptr[memhub.MemBuddy] = trans.Pool
|
||||
builder: llvmlite.IRBuilder | t.CPtr = trans._cur_builder
|
||||
builder: rawptr[llvmlite.IRBuilder] = trans._cur_builder
|
||||
func: rawptr[llvmlite.Function] = trans._cur_func
|
||||
# 同主路径:局部记录本 simple match 的 br end_bb,收尾覆盖
|
||||
# _ctrl_merge_reachable,消除 case 体内嵌套控制流污染
|
||||
@@ -1149,7 +1149,7 @@ class MatchGenMixin:
|
||||
# 1. subject 转 i32(若已 i32 直接用,否则 ptrtoint)
|
||||
i32_ty: rawptr[llvmlite.LLVMType] = llvmlite.Int32(pool)
|
||||
subj_bits: int = self.Gen.ExprGenBase.get_llvm_type_bits(subject_val.Ty)
|
||||
subj_val: llvmlite.Value | t.CPtr = subject_val
|
||||
subj_val: rawptr[llvmlite.Value] = subject_val
|
||||
if subj_bits != 32:
|
||||
if self.Gen.ExprGenBase.is_ptr_type(subject_val.Ty) != 0:
|
||||
subj_val = llvmlite.build_ptrtoint(builder, subject_val, i32_ty)
|
||||
@@ -1171,14 +1171,14 @@ class MatchGenMixin:
|
||||
# fail-fast: 标签缓冲区分配失败
|
||||
self.Gen.TypeGenErr.fatal_error(node, "标签缓冲区分配失败", "TypeError")
|
||||
viperlib.snprintf(name_buf, 32, "match.default.%d", cnt)
|
||||
default_bb: llvmlite.BasicBlock | t.CPtr = llvmlite.create_block(
|
||||
default_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(
|
||||
pool, func, name_buf)
|
||||
viperlib.snprintf(name_buf, 32, "match.end.%d", cnt)
|
||||
end_bb: llvmlite.BasicBlock | t.CPtr = llvmlite.create_block(
|
||||
end_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(
|
||||
pool, func, name_buf)
|
||||
|
||||
# 3. 收集 case 信息
|
||||
cases_list: list[rawptr[ast.AST]] | t.CPtr = node.cases
|
||||
cases_list: rawptr[list[rawptr[ast.AST]]] = node.cases
|
||||
if cases_list is None:
|
||||
# fail-fast: match cases 缺失
|
||||
self.Gen.TypeGenErr.fatal_error(node, "match cases 缺失", "TypeError")
|
||||
@@ -1194,8 +1194,8 @@ class MatchGenMixin:
|
||||
|
||||
collected: int = 0
|
||||
has_default: int = 0
|
||||
sw_head: llvmlite.SwitchCase | t.CPtr = None
|
||||
sw_tail: llvmlite.SwitchCase | t.CPtr = None
|
||||
sw_head: rawptr[llvmlite.SwitchCase] = None
|
||||
sw_tail: rawptr[llvmlite.SwitchCase] = None
|
||||
sw_count: int = 0
|
||||
|
||||
# 4. 第一遍:收集 + 创建 BB + 构建链表
|
||||
@@ -1208,38 +1208,38 @@ class MatchGenMixin:
|
||||
if case_node.kind() != ast.ASTKind.MatchCase:
|
||||
i = i + 1
|
||||
continue
|
||||
mc: ast.MatchCase | t.CPtr = (ast.MatchCase | t.CPtr)(case_node)
|
||||
mc: rawptr[ast.MatchCase] = rawptr[ast.MatchCase](case_node)
|
||||
pat: rawptr[ast.AST] = mc.pattern
|
||||
|
||||
is_def: int = 0
|
||||
cv: llvmlite.Value | t.CPtr = None
|
||||
cv: rawptr[llvmlite.Value] = None
|
||||
|
||||
if pat is not None:
|
||||
pk: int = pat.kind()
|
||||
if pk == ast.ASTKind.MatchValue:
|
||||
mv: ast.MatchValue | t.CPtr = (ast.MatchValue | t.CPtr)(pat)
|
||||
mv: rawptr[ast.MatchValue] = rawptr[ast.MatchValue](pat)
|
||||
cv = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, trans.Module, mv.value,
|
||||
trans._funcs, trans._func_count, trans)
|
||||
elif pk == ast.ASTKind.MatchSingleton:
|
||||
ms: ast.MatchSingleton | t.CPtr = (
|
||||
ast.MatchSingleton | t.CPtr)(pat)
|
||||
ms: rawptr[ast.MatchSingleton] = (
|
||||
rawptr[ast.MatchSingleton])(pat)
|
||||
# None -> 0
|
||||
cv = llvmlite.const_int32(pool, 0)
|
||||
elif pk == ast.ASTKind.MatchAs:
|
||||
ma: ast.MatchAs | t.CPtr = (ast.MatchAs | t.CPtr)(pat)
|
||||
ma: rawptr[ast.MatchAs] = rawptr[ast.MatchAs](pat)
|
||||
if ma.pattern is None:
|
||||
is_def = 1
|
||||
has_default = 1
|
||||
elif pk == ast.ASTKind.MatchOr:
|
||||
mo: ast.MatchOr | t.CPtr = (ast.MatchOr | t.CPtr)(pat)
|
||||
pats: list[rawptr[ast.AST]] | t.CPtr = mo.patterns
|
||||
mo: rawptr[ast.MatchOr] = rawptr[ast.MatchOr](pat)
|
||||
pats: rawptr[list[rawptr[ast.AST]]] = mo.patterns
|
||||
if pats is not None and len(pats) > 0:
|
||||
first_pat: rawptr[ast.AST] = pats.get(0)
|
||||
if first_pat is not None \
|
||||
and first_pat.kind() == ast.ASTKind.MatchValue:
|
||||
mv2: ast.MatchValue | t.CPtr = (
|
||||
ast.MatchValue | t.CPtr)(first_pat)
|
||||
mv2: rawptr[ast.MatchValue] = (
|
||||
rawptr[ast.MatchValue])(first_pat)
|
||||
cv = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, trans.Module, mv2.value,
|
||||
trans._funcs, trans._func_count, trans)
|
||||
@@ -1261,12 +1261,12 @@ class MatchGenMixin:
|
||||
if collected >= MAX_MATCH_CASES:
|
||||
break
|
||||
viperlib.snprintf(name_buf, 32, "match.case.%d.%d", cnt, i)
|
||||
bb: llvmlite.BasicBlock | t.CPtr = llvmlite.create_block(
|
||||
bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(
|
||||
pool, func, name_buf)
|
||||
else:
|
||||
bb = default_bb
|
||||
|
||||
body_list: list[rawptr[ast.AST]] | t.CPtr = mc.children
|
||||
body_list: rawptr[list[rawptr[ast.AST]]] = mc.children
|
||||
nb: int = self._has_no_break(body_list)
|
||||
|
||||
if collected < MAX_MATCH_CASES:
|
||||
@@ -1277,7 +1277,7 @@ class MatchGenMixin:
|
||||
collected = collected + 1
|
||||
|
||||
if is_def == 0 and cv is not None:
|
||||
sc: llvmlite.SwitchCase | t.CPtr = llvmlite.new_switch_case(
|
||||
sc: rawptr[llvmlite.SwitchCase] = llvmlite.new_switch_case(
|
||||
pool, cv, bb)
|
||||
if sc is not None:
|
||||
if sw_head is None:
|
||||
@@ -1300,10 +1300,10 @@ class MatchGenMixin:
|
||||
if case_node is None:
|
||||
i = i + 1
|
||||
continue
|
||||
mc: ast.MatchCase | t.CPtr = (ast.MatchCase | t.CPtr)(case_node)
|
||||
mc: rawptr[ast.MatchCase] = rawptr[ast.MatchCase](case_node)
|
||||
|
||||
bb_addr: sizet = bb_arr[i]
|
||||
case_bb: llvmlite.BasicBlock | t.CPtr = (llvmlite.BasicBlock | t.CPtr)(bb_addr)
|
||||
case_bb: rawptr[llvmlite.BasicBlock] = rawptr[llvmlite.BasicBlock](bb_addr)
|
||||
is_def: int = def_arr[i]
|
||||
nb: int = nb_arr[i]
|
||||
|
||||
@@ -1316,7 +1316,7 @@ class MatchGenMixin:
|
||||
|
||||
self.Gen.VarGen.enter_scope(trans.SymTab, SCOPE_MATCH)
|
||||
|
||||
body_list: list[rawptr[ast.AST]] | t.CPtr = mc.children
|
||||
body_list: rawptr[list[rawptr[ast.AST]]] = mc.children
|
||||
if body_list is not None:
|
||||
bc: sizet = len(body_list)
|
||||
bi: int = 0
|
||||
@@ -1346,20 +1346,20 @@ class MatchGenMixin:
|
||||
trans._ctrl_merge_reachable = 1
|
||||
sm_merge_reach = 1
|
||||
else:
|
||||
dbody: list[rawptr[ast.AST]] | t.CPtr = None
|
||||
dbody: rawptr[list[rawptr[ast.AST]]] = None
|
||||
di: int = 0
|
||||
while di < collected:
|
||||
if def_arr[di] == 1:
|
||||
dcase: rawptr[ast.AST] = cases_list.get(di)
|
||||
if dcase is not None:
|
||||
dmc: ast.MatchCase | t.CPtr = (
|
||||
ast.MatchCase | t.CPtr)(dcase)
|
||||
dmc: rawptr[ast.MatchCase] = (
|
||||
rawptr[ast.MatchCase])(dcase)
|
||||
self.Gen.VarGen.enter_scope(trans.SymTab, SCOPE_MATCH)
|
||||
# dbody 预声明+重赋值会使 .get 误分派成 list[int].get
|
||||
# (i32→inttoptr 截断指针 → translate_stmt 读垃圾节点崩溃,
|
||||
# gen1 IR 证据)。用 dbody2 内联声明接收者遍历(对齐
|
||||
# Converter arg_defaults 内联声明规避模式)。
|
||||
dbody2: list[rawptr[ast.AST]] | t.CPtr = dmc.children
|
||||
dbody2: rawptr[list[rawptr[ast.AST]]] = dmc.children
|
||||
dbody = dbody2
|
||||
if dbody2 is not None:
|
||||
dn: sizet = len(dbody2)
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -43,10 +43,10 @@ class StmtGenDeclMixin(StmtGenCifMixin.StmtGenCifMixin):
|
||||
def translate_global(self, trans: rawptr[HT.Translator],
|
||||
node: rawptr[ast.AST]) -> int:
|
||||
"""翻译 global 语句:记录 global 变量名"""
|
||||
gn: ast.Global | t.CPtr = (ast.Global | t.CPtr)(node)
|
||||
gn: rawptr[ast.Global] = rawptr[ast.Global](node)
|
||||
if gn is None:
|
||||
return 0
|
||||
names: list[rawptr[ast.AST]] | t.CPtr = gn.names
|
||||
names: rawptr[list[rawptr[ast.AST]]] = gn.names
|
||||
if names is None:
|
||||
return 0
|
||||
n: sizet = len(names)
|
||||
@@ -64,10 +64,10 @@ class StmtGenDeclMixin(StmtGenCifMixin.StmtGenCifMixin):
|
||||
|
||||
类型信息通过查找父作用域的 alloca 获取(用于 env 指针数组方案的类型恢复)。
|
||||
"""
|
||||
nl: ast.Nonlocal | t.CPtr = (ast.Nonlocal | t.CPtr)(node)
|
||||
nl: rawptr[ast.Nonlocal] = rawptr[ast.Nonlocal](node)
|
||||
if nl is None:
|
||||
return 0
|
||||
names: list[rawptr[ast.AST]] | t.CPtr = nl.names
|
||||
names: rawptr[list[rawptr[ast.AST]]] = nl.names
|
||||
if names is None:
|
||||
return 0
|
||||
n: sizet = len(names)
|
||||
@@ -78,7 +78,7 @@ class StmtGenDeclMixin(StmtGenCifMixin.StmtGenCifMixin):
|
||||
if nm.id is not None:
|
||||
# 查找父作用域中的变量 alloca,获取类型信息
|
||||
var_ty: rawptr[llvmlite.LLVMType] = None
|
||||
var_alloca: llvmlite.Value | t.CPtr = self.Gen.VarGen.lookup_var(
|
||||
var_alloca: rawptr[llvmlite.Value] = self.Gen.VarGen.lookup_var(
|
||||
trans.SymTab, nm.id)
|
||||
if var_alloca is not None and var_alloca.Ty is not None:
|
||||
var_ty = var_alloca.Ty.Pointee
|
||||
@@ -97,7 +97,7 @@ class StmtGenDeclMixin(StmtGenCifMixin.StmtGenCifMixin):
|
||||
def translate_expr_stmt(self, trans: rawptr[HT.Translator],
|
||||
node: rawptr[ast.AST]) -> int:
|
||||
"""翻译表达式语句(printf 调用等)"""
|
||||
ex: ast.Expr | t.CPtr = (ast.Expr | t.CPtr)(node)
|
||||
ex: rawptr[ast.Expr] = rawptr[ast.Expr](node)
|
||||
if ex is None:
|
||||
return 0
|
||||
call_node: rawptr[ast.AST] = ex.value
|
||||
@@ -149,7 +149,7 @@ class StmtGenDeclMixin(StmtGenCifMixin.StmtGenCifMixin):
|
||||
if k == ast.ASTKind.AnnAssign:
|
||||
return self.Gen.AssignGen.translate_annassign_prescan(trans, node)
|
||||
if k == ast.ASTKind.If:
|
||||
ifn: ast.If | t.CPtr = (ast.If | t.CPtr)(node)
|
||||
ifn: rawptr[ast.If] = rawptr[ast.If](node)
|
||||
if ifn.children is not None:
|
||||
bn_pre_i: sizet = len(ifn.children)
|
||||
for bi_pre_i in range(bn_pre_i):
|
||||
@@ -160,7 +160,7 @@ class StmtGenDeclMixin(StmtGenCifMixin.StmtGenCifMixin):
|
||||
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)
|
||||
for_n: rawptr[ast.For] = rawptr[ast.For](node)
|
||||
if for_n.children is not None:
|
||||
bn_pre_f: sizet = len(for_n.children)
|
||||
for bi_pre_f in range(bn_pre_f):
|
||||
@@ -171,7 +171,7 @@ class StmtGenDeclMixin(StmtGenCifMixin.StmtGenCifMixin):
|
||||
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)
|
||||
wh_n: rawptr[ast.While] = rawptr[ast.While](node)
|
||||
if wh_n.children is not None:
|
||||
bn_pre_w: sizet = len(wh_n.children)
|
||||
for bi_pre_w in range(bn_pre_w):
|
||||
@@ -220,7 +220,7 @@ class StmtGenDeclMixin(StmtGenCifMixin.StmtGenCifMixin):
|
||||
for bi_pre_mc in range(bn_pre_mc):
|
||||
mc_pre: rawptr[ast.AST] = 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)
|
||||
mcc_pre: rawptr[ast.MatchCase] = rawptr[ast.MatchCase](mc_pre)
|
||||
if mcc_pre.children is not None:
|
||||
bn_pre_mcb: sizet = len(mcc_pre.children)
|
||||
for bi_pre_mcb in range(bn_pre_mcb):
|
||||
@@ -242,7 +242,7 @@ class StmtGenDeclMixin(StmtGenCifMixin.StmtGenCifMixin):
|
||||
|
||||
def translate_break(self, trans: rawptr[HT.Translator]) -> int:
|
||||
"""翻译 break 语句:跳转到循环 end 块"""
|
||||
builder: llvmlite.IRBuilder | t.CPtr = trans._cur_builder
|
||||
builder: rawptr[llvmlite.IRBuilder] = trans._cur_builder
|
||||
func: rawptr[llvmlite.Function] = trans._cur_func
|
||||
pool: rawptr[memhub.MemBuddy] = trans.Pool
|
||||
|
||||
@@ -259,13 +259,13 @@ class StmtGenDeclMixin(StmtGenCifMixin.StmtGenCifMixin):
|
||||
trans._label_counter = cnt + 1
|
||||
name_buf: str = pool.alloc(32)
|
||||
viperlib.snprintf(name_buf, 32, "dead.%d", cnt)
|
||||
dead_bb: llvmlite.BasicBlock | t.CPtr = llvmlite.create_block(pool, func, name_buf)
|
||||
dead_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(pool, func, name_buf)
|
||||
llvmlite.position_at_end(builder, dead_bb)
|
||||
return 0
|
||||
|
||||
def translate_continue(self, trans: rawptr[HT.Translator]) -> int:
|
||||
"""翻译 continue 语句:跳转到循环 cond/incr 块"""
|
||||
builder: llvmlite.IRBuilder | t.CPtr = trans._cur_builder
|
||||
builder: rawptr[llvmlite.IRBuilder] = trans._cur_builder
|
||||
func: rawptr[llvmlite.Function] = trans._cur_func
|
||||
pool: rawptr[memhub.MemBuddy] = trans.Pool
|
||||
|
||||
@@ -282,7 +282,7 @@ class StmtGenDeclMixin(StmtGenCifMixin.StmtGenCifMixin):
|
||||
trans._label_counter = cnt + 1
|
||||
name_buf: str = pool.alloc(32)
|
||||
viperlib.snprintf(name_buf, 32, "dead.%d", cnt)
|
||||
dead_bb: llvmlite.BasicBlock | t.CPtr = llvmlite.create_block(pool, func, name_buf)
|
||||
dead_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(pool, func, name_buf)
|
||||
llvmlite.position_at_end(builder, dead_bb)
|
||||
return 0
|
||||
|
||||
@@ -306,25 +306,25 @@ class StmtGenDeclMixin(StmtGenCifMixin.StmtGenCifMixin):
|
||||
case _:
|
||||
return 0
|
||||
|
||||
def get_env_ptr_var(self, trans: rawptr[HT.Translator]) -> llvmlite.Value | t.CPtr:
|
||||
def get_env_ptr_var(self, trans: rawptr[HT.Translator]) -> rawptr[llvmlite.Value]:
|
||||
"""获取或创建 _env_ptr 变量(存储闭包 env 指针)"""
|
||||
env_var: llvmlite.Value | t.CPtr = self.Gen.VarGen.lookup_var(
|
||||
env_var: rawptr[llvmlite.Value] = self.Gen.VarGen.lookup_var(
|
||||
trans.SymTab, "_env_ptr")
|
||||
if env_var is not None:
|
||||
return env_var
|
||||
# 创建 alloca 存储 env
|
||||
pool: rawptr[memhub.MemBuddy] = trans.Pool
|
||||
builder: llvmlite.IRBuilder | t.CPtr = trans._cur_builder
|
||||
builder: rawptr[llvmlite.IRBuilder] = trans._cur_builder
|
||||
i8_ty: rawptr[llvmlite.LLVMType] = llvmlite.Int8(pool)
|
||||
i8_ptr_ty: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, i8_ty)
|
||||
alloca: llvmlite.Value | t.CPtr = llvmlite.build_alloca(builder, i8_ptr_ty)
|
||||
alloca: rawptr[llvmlite.Value] = llvmlite.build_alloca(builder, i8_ptr_ty)
|
||||
if alloca is None:
|
||||
return None
|
||||
self.Gen.VarGen.define_var(trans.SymTab, "_env_ptr", alloca)
|
||||
return alloca
|
||||
|
||||
def _load_raw_var_ptr(self, trans: rawptr[HT.Translator],
|
||||
name: str) -> llvmlite.Value | t.CPtr:
|
||||
name: str) -> rawptr[llvmlite.Value]:
|
||||
"""从闭包 env 加载 nonlocal 变量的原始指针(i8*)
|
||||
|
||||
返回 i8* 类型的 Value,调用方需 bitcast 为具体类型指针后 load/store。
|
||||
@@ -334,43 +334,43 @@ class StmtGenDeclMixin(StmtGenCifMixin.StmtGenCifMixin):
|
||||
return None
|
||||
|
||||
pool: rawptr[memhub.MemBuddy] = trans.Pool
|
||||
builder: llvmlite.IRBuilder | t.CPtr = trans._cur_builder
|
||||
builder: rawptr[llvmlite.IRBuilder] = trans._cur_builder
|
||||
i8_ty: rawptr[llvmlite.LLVMType] = llvmlite.Int8(pool)
|
||||
i8_ptr_ty: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, i8_ty)
|
||||
i8_ptr_ptr_ty: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, i8_ptr_ty)
|
||||
|
||||
# 1. 加载 env_ptr
|
||||
env_alloca: llvmlite.Value | t.CPtr = self.get_env_ptr_var(trans)
|
||||
env_alloca: rawptr[llvmlite.Value] = self.get_env_ptr_var(trans)
|
||||
if env_alloca is None:
|
||||
return None
|
||||
env_ptr: llvmlite.Value | t.CPtr = llvmlite.build_load(builder, i8_ptr_ty, env_alloca)
|
||||
env_ptr: rawptr[llvmlite.Value] = llvmlite.build_load(builder, i8_ptr_ty, env_alloca)
|
||||
if env_ptr is None:
|
||||
return None
|
||||
|
||||
# 2. GEP to offset (idx * 8) — env 存储指针数组,每槽 8 字节
|
||||
offset_val: llvmlite.Value | t.CPtr = llvmlite.const_int32(pool, idx * 8)
|
||||
addr: llvmlite.Value | t.CPtr = llvmlite.build_gep(builder, i8_ty, env_ptr, offset_val)
|
||||
offset_val: rawptr[llvmlite.Value] = llvmlite.const_int32(pool, idx * 8)
|
||||
addr: rawptr[llvmlite.Value] = llvmlite.build_gep(builder, i8_ty, env_ptr, offset_val)
|
||||
if addr is None:
|
||||
return None
|
||||
|
||||
# 3. Bitcast to i8** and load the raw pointer
|
||||
ptr_addr: llvmlite.Value | t.CPtr = llvmlite.build_bitcast(builder, addr, i8_ptr_ptr_ty)
|
||||
ptr_addr: rawptr[llvmlite.Value] = llvmlite.build_bitcast(builder, addr, i8_ptr_ptr_ty)
|
||||
if ptr_addr is None:
|
||||
return None
|
||||
return llvmlite.build_load(builder, i8_ptr_ty, ptr_addr)
|
||||
|
||||
def load_nonlocal_var(self, trans: rawptr[HT.Translator],
|
||||
name: str) -> llvmlite.Value | t.CPtr:
|
||||
name: str) -> rawptr[llvmlite.Value]:
|
||||
"""从闭包 env 加载 nonlocal 变量值
|
||||
|
||||
通过 HT.get_nonlocal_type 获取变量类型,bitcast 原始指针后 load。
|
||||
"""
|
||||
raw_ptr: llvmlite.Value | t.CPtr = self._load_raw_var_ptr(trans, name)
|
||||
raw_ptr: rawptr[llvmlite.Value] = self._load_raw_var_ptr(trans, name)
|
||||
if raw_ptr is None:
|
||||
return None
|
||||
|
||||
pool: rawptr[memhub.MemBuddy] = trans.Pool
|
||||
builder: llvmlite.IRBuilder | t.CPtr = trans._cur_builder
|
||||
builder: rawptr[llvmlite.IRBuilder] = trans._cur_builder
|
||||
|
||||
# 获取变量类型(从注册时存储的类型信息)
|
||||
var_ty: rawptr[llvmlite.LLVMType] = GenApi.get_nonlocal_type(trans, name)
|
||||
@@ -380,23 +380,23 @@ class StmtGenDeclMixin(StmtGenCifMixin.StmtGenCifMixin):
|
||||
|
||||
# bitcast raw i8* to var_ty*
|
||||
var_ptr_ty: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, var_ty)
|
||||
var_ptr: llvmlite.Value | t.CPtr = llvmlite.build_bitcast(builder, raw_ptr, var_ptr_ty)
|
||||
var_ptr: rawptr[llvmlite.Value] = llvmlite.build_bitcast(builder, raw_ptr, var_ptr_ty)
|
||||
if var_ptr is None:
|
||||
return None
|
||||
return llvmlite.build_load(builder, var_ty, var_ptr)
|
||||
|
||||
def get_nonlocal_var_ptr(self, trans: rawptr[HT.Translator],
|
||||
name: str) -> llvmlite.Value | t.CPtr:
|
||||
name: str) -> rawptr[llvmlite.Value]:
|
||||
"""获取 nonlocal 变量的存储指针(var_ty*),用于 store 操作
|
||||
|
||||
返回的指针指向父函数的 alloca,store 操作对父函数可见。
|
||||
"""
|
||||
raw_ptr: llvmlite.Value | t.CPtr = self._load_raw_var_ptr(trans, name)
|
||||
raw_ptr: rawptr[llvmlite.Value] = self._load_raw_var_ptr(trans, name)
|
||||
if raw_ptr is None:
|
||||
return None
|
||||
|
||||
pool: rawptr[memhub.MemBuddy] = trans.Pool
|
||||
builder: llvmlite.IRBuilder | t.CPtr = trans._cur_builder
|
||||
builder: rawptr[llvmlite.IRBuilder] = trans._cur_builder
|
||||
|
||||
# 获取变量类型
|
||||
var_ty: rawptr[llvmlite.LLVMType] = GenApi.get_nonlocal_type(trans, name)
|
||||
@@ -430,32 +430,32 @@ class StmtGenDeclMixin(StmtGenCifMixin.StmtGenCifMixin):
|
||||
self.EnumCount = 0
|
||||
return 1
|
||||
|
||||
def _get_enum_entry(self, i: int) -> GenTypes.EnumEntry | t.CPtr:
|
||||
def _get_enum_entry(self, i: int) -> rawptr[GenTypes.EnumEntry]:
|
||||
"""获取第 i 个枚举条目"""
|
||||
if self.EnumTable is None or i < 0 or i >= ENUM_MAX:
|
||||
return None
|
||||
entry_size: sizet = GenTypes.EnumEntry.__sizeof__()
|
||||
addr: uint64 = uint64(self.EnumTable) + i * entry_size
|
||||
return (GenTypes.EnumEntry | t.CPtr)(addr)
|
||||
return rawptr[GenTypes.EnumEntry](addr)
|
||||
|
||||
def _get_enum_member(self, enum_entry: GenTypes.EnumEntry | t.CPtr,
|
||||
i: int) -> GenTypes.EnumMember | t.CPtr:
|
||||
def _get_enum_member(self, enum_entry: rawptr[GenTypes.EnumEntry],
|
||||
i: int) -> rawptr[GenTypes.EnumMember]:
|
||||
"""获取枚举中第 i 个成员条目"""
|
||||
if enum_entry is None or i < 0 or i >= ENUM_MEMBER_MAX:
|
||||
return None
|
||||
member_size: sizet = GenTypes.EnumMember.__sizeof__()
|
||||
addr: uint64 = uint64(enum_entry.Members) + i * member_size
|
||||
return (GenTypes.EnumMember | t.CPtr)(addr)
|
||||
return rawptr[GenTypes.EnumMember](addr)
|
||||
|
||||
def register_enum(self, pool: rawptr[memhub.MemBuddy],
|
||||
name: str,
|
||||
base_ty: rawptr[llvmlite.LLVMType]) -> GenTypes.EnumEntry | t.CPtr:
|
||||
base_ty: rawptr[llvmlite.LLVMType]) -> rawptr[GenTypes.EnumEntry]:
|
||||
"""注册枚举类型,返回 EnumEntry 指针"""
|
||||
if self.init_enum_table(pool) == 0:
|
||||
return None
|
||||
|
||||
# 检查是否已注册
|
||||
existing: GenTypes.EnumEntry | t.CPtr = self.find_enum(name)
|
||||
existing: rawptr[GenTypes.EnumEntry] = self.find_enum(name)
|
||||
if existing is not None:
|
||||
return existing
|
||||
|
||||
@@ -463,7 +463,7 @@ class StmtGenDeclMixin(StmtGenCifMixin.StmtGenCifMixin):
|
||||
VLogger.error(f"table full, cannot register {name}", "ENUM")
|
||||
return None
|
||||
|
||||
entry: GenTypes.EnumEntry | t.CPtr = self._get_enum_entry(self.EnumCount)
|
||||
entry: rawptr[GenTypes.EnumEntry] = self._get_enum_entry(self.EnumCount)
|
||||
if entry is None:
|
||||
return None
|
||||
|
||||
@@ -501,7 +501,7 @@ class StmtGenDeclMixin(StmtGenCifMixin.StmtGenCifMixin):
|
||||
return entry
|
||||
|
||||
def add_enum_member(self, pool: rawptr[memhub.MemBuddy],
|
||||
enum_entry: GenTypes.EnumEntry | t.CPtr,
|
||||
enum_entry: rawptr[GenTypes.EnumEntry],
|
||||
member_name: str,
|
||||
member_val: int64,
|
||||
member_ty: rawptr[llvmlite.LLVMType]) -> int:
|
||||
@@ -512,7 +512,7 @@ class StmtGenDeclMixin(StmtGenCifMixin.StmtGenCifMixin):
|
||||
# 去重:同名成员已存在则跳过(跨模块同名枚举合并注册 / 同模块
|
||||
# 重复处理幂等——如 w32.fileio 与 fat32_types 都有 FRESULT)
|
||||
for ei_d in range(enum_entry.MemberCount):
|
||||
ex_d: GenTypes.EnumMember | t.CPtr = self._get_enum_member(
|
||||
ex_d: rawptr[GenTypes.EnumMember] = self._get_enum_member(
|
||||
enum_entry, ei_d)
|
||||
if ex_d is not None and ex_d.Name is not None:
|
||||
if string.strcmp(ex_d.Name, member_name) == 0:
|
||||
@@ -523,7 +523,7 @@ class StmtGenDeclMixin(StmtGenCifMixin.StmtGenCifMixin):
|
||||
return -1
|
||||
|
||||
idx: int = enum_entry.MemberCount
|
||||
me: GenTypes.EnumMember | t.CPtr = self._get_enum_member(enum_entry, idx)
|
||||
me: rawptr[GenTypes.EnumMember] = self._get_enum_member(enum_entry, idx)
|
||||
if me is None:
|
||||
return -1
|
||||
|
||||
@@ -540,27 +540,27 @@ class StmtGenDeclMixin(StmtGenCifMixin.StmtGenCifMixin):
|
||||
enum_entry.MemberCount = idx + 1
|
||||
return idx
|
||||
|
||||
def find_enum(self, name: str) -> GenTypes.EnumEntry | t.CPtr:
|
||||
def find_enum(self, name: str) -> rawptr[GenTypes.EnumEntry]:
|
||||
"""按枚举类名查找,返回 EnumEntry 或 None"""
|
||||
if name is None or self.EnumTable is None:
|
||||
return None
|
||||
for i in range(self.EnumCount):
|
||||
entry: GenTypes.EnumEntry | t.CPtr = self._get_enum_entry(i)
|
||||
entry: rawptr[GenTypes.EnumEntry] = self._get_enum_entry(i)
|
||||
if entry is not None and entry.Name is not None:
|
||||
if string.strcmp(entry.Name, name) == 0:
|
||||
return entry
|
||||
return None
|
||||
|
||||
def lookup_enum_member(self, enum_name: str,
|
||||
member_name: str) -> GenTypes.EnumMember | t.CPtr:
|
||||
member_name: str) -> rawptr[GenTypes.EnumMember]:
|
||||
"""按枚举类名和成员名查找,返回 EnumMember 或 None"""
|
||||
if enum_name is None or member_name is None:
|
||||
return None
|
||||
entry: GenTypes.EnumEntry | t.CPtr = self.find_enum(enum_name)
|
||||
entry: rawptr[GenTypes.EnumEntry] = self.find_enum(enum_name)
|
||||
if entry is None:
|
||||
return None
|
||||
for mi in range(entry.MemberCount):
|
||||
me: GenTypes.EnumMember | t.CPtr = self._get_enum_member(entry, mi)
|
||||
me: rawptr[GenTypes.EnumMember] = self._get_enum_member(entry, mi)
|
||||
if me is not None and me.Name is not None:
|
||||
if string.strcmp(me.Name, member_name) == 0:
|
||||
return me
|
||||
@@ -576,7 +576,7 @@ class StmtGenDeclMixin(StmtGenCifMixin.StmtGenCifMixin):
|
||||
|
||||
def get_enum_base_type(self, enum_name: str) -> rawptr[llvmlite.LLVMType]:
|
||||
"""按枚举类名获取基准类型"""
|
||||
entry: GenTypes.EnumEntry | t.CPtr = self.find_enum(enum_name)
|
||||
entry: rawptr[GenTypes.EnumEntry] = self.find_enum(enum_name)
|
||||
if entry is not None:
|
||||
return entry.BaseTy
|
||||
return None
|
||||
@@ -112,12 +112,12 @@ class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin):
|
||||
"""翻译 del 语句,返回 0"""
|
||||
if trans is None or node is None:
|
||||
return 0
|
||||
dnode: ast.Delete | t.CPtr = (ast.Delete | t.CPtr)(node)
|
||||
dnode: rawptr[ast.Delete] = rawptr[ast.Delete](node)
|
||||
if dnode is None or dnode.targets is None:
|
||||
return 0
|
||||
pool: rawptr[memhub.MemBuddy] = trans.Pool
|
||||
mod: rawptr[llvmlite.LLVMModule] = trans.Module
|
||||
builder: llvmlite.IRBuilder | t.CPtr = trans._cur_builder
|
||||
builder: rawptr[llvmlite.IRBuilder] = trans._cur_builder
|
||||
if pool is None or mod is None or builder is None:
|
||||
return 0
|
||||
tn: sizet = len(dnode.targets)
|
||||
@@ -136,9 +136,9 @@ class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin):
|
||||
elif tgt.kind() == ast.ASTKind.Subscript:
|
||||
dl_sub: rawptr[ast.Subscript] = rawptr[ast.Subscript](tgt)
|
||||
if dl_sub is not None and dl_sub.value is not None and dl_sub.slice is not None:
|
||||
dl_obj: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
|
||||
dl_obj: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, dl_sub.value, None, 0, trans)
|
||||
dl_idx: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
|
||||
dl_idx: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, dl_sub.slice, None, 0, trans)
|
||||
if dl_obj is not None and dl_idx is not None:
|
||||
dl_st: rawptr[llvmlite.LLVMType] = self.Gen.StructGen.get_struct_type_from_value(
|
||||
@@ -156,8 +156,8 @@ class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin):
|
||||
dl_fn_name: str = llvmlite.function_get_name(dl_fn)
|
||||
if dl_ret is not None and dl_fn_name is not None:
|
||||
# self 参数(容器)按 __delitem__ 首参类型对齐
|
||||
dl_self: llvmlite.Value | t.CPtr = dl_obj
|
||||
dl_first: llvmlite.Param | t.CPtr = llvmlite.function_get_param_head(dl_fn)
|
||||
dl_self: rawptr[llvmlite.Value] = dl_obj
|
||||
dl_first: rawptr[llvmlite.Param] = llvmlite.function_get_param_head(dl_fn)
|
||||
if dl_first is not None:
|
||||
dl_self_ty: rawptr[llvmlite.LLVMType] = llvmlite.param_get_ty(dl_first)
|
||||
if dl_self_ty is not None:
|
||||
@@ -194,7 +194,7 @@ class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin):
|
||||
if tr is None:
|
||||
return 0
|
||||
pool: rawptr[memhub.MemBuddy] = trans.Pool
|
||||
builder: llvmlite.IRBuilder | t.CPtr = trans._cur_builder
|
||||
builder: rawptr[llvmlite.IRBuilder] = trans._cur_builder
|
||||
func: rawptr[llvmlite.Function] = trans._cur_func
|
||||
if pool is None or builder is None or func is None:
|
||||
return 0
|
||||
@@ -207,12 +207,12 @@ class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin):
|
||||
i8_ptr_ty_t: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, i8_ty_t)
|
||||
if i32_ty_t is None or i8_ptr_ty_t is None:
|
||||
return 0
|
||||
exception_code: llvmlite.Value | t.CPtr = llvmlite.build_alloca(builder, i32_ty_t)
|
||||
eh_message: llvmlite.Value | t.CPtr = llvmlite.build_alloca(builder, i8_ptr_ty_t)
|
||||
exception_code: rawptr[llvmlite.Value] = llvmlite.build_alloca(builder, i32_ty_t)
|
||||
eh_message: rawptr[llvmlite.Value] = llvmlite.build_alloca(builder, i8_ptr_ty_t)
|
||||
if exception_code is None or eh_message is None:
|
||||
return 0
|
||||
init_code_t: llvmlite.Value | t.CPtr = llvmlite.const_int32(pool, 0)
|
||||
init_msg_t: llvmlite.Value | t.CPtr = llvmlite.ConstNull(pool, i8_ptr_ty_t, "null")
|
||||
init_code_t: rawptr[llvmlite.Value] = llvmlite.const_int32(pool, 0)
|
||||
init_msg_t: rawptr[llvmlite.Value] = llvmlite.ConstNull(pool, i8_ptr_ty_t, "null")
|
||||
if init_code_t is not None:
|
||||
llvmlite.build_store(builder, init_code_t, exception_code)
|
||||
if init_msg_t is not None:
|
||||
@@ -225,16 +225,16 @@ class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin):
|
||||
if bb_buf_t is None:
|
||||
return 0
|
||||
viperlib.snprintf(bb_buf_t, 64, "try.dispatch.%d", lc_t)
|
||||
dispatch_bb: llvmlite.BasicBlock | t.CPtr = llvmlite.create_block(pool, func, bb_buf_t)
|
||||
dispatch_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(pool, func, bb_buf_t)
|
||||
viperlib.snprintf(bb_buf_t, 64, "try.after.%d", lc_t)
|
||||
after_bb: llvmlite.BasicBlock | t.CPtr = llvmlite.create_block(pool, func, bb_buf_t)
|
||||
after_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(pool, func, bb_buf_t)
|
||||
viperlib.snprintf(bb_buf_t, 64, "try.unhandled.%d", lc_t)
|
||||
unhandled_bb: llvmlite.BasicBlock | t.CPtr = llvmlite.create_block(pool, func, bb_buf_t)
|
||||
unhandled_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(pool, func, bb_buf_t)
|
||||
viperlib.snprintf(bb_buf_t, 64, "try.body.%d", lc_t)
|
||||
try_bb: llvmlite.BasicBlock | t.CPtr = llvmlite.create_block(pool, func, bb_buf_t)
|
||||
try_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(pool, func, bb_buf_t)
|
||||
if dispatch_bb is None or after_bb is None or unhandled_bb is None or try_bb is None:
|
||||
return 0
|
||||
else_bb: llvmlite.BasicBlock | t.CPtr = None
|
||||
else_bb: rawptr[llvmlite.BasicBlock] = None
|
||||
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)
|
||||
@@ -244,24 +244,24 @@ class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin):
|
||||
# 注意:list[ptr](pool, N) 第二参数是 elem_size 不是容量!
|
||||
# 指针元素必须显式传 8(T.__sizeof__ 对联合类型不可靠),
|
||||
# 否则 append 按 N 字节步长错位存取 → 读出垃圾指针(崩溃)。
|
||||
except_bbs: list[llvmlite.BasicBlock | t.CPtr] | t.CPtr = \
|
||||
list[llvmlite.BasicBlock | t.CPtr](pool, 8)
|
||||
match_bbs: list[llvmlite.BasicBlock | t.CPtr] | t.CPtr = \
|
||||
list[llvmlite.BasicBlock | t.CPtr](pool, 8)
|
||||
except_bbs: list[rawptr[llvmlite.BasicBlock]] | t.CPtr = \
|
||||
list[rawptr[llvmlite.BasicBlock]](pool, 8)
|
||||
match_bbs: list[rawptr[llvmlite.BasicBlock]] | t.CPtr = \
|
||||
list[rawptr[llvmlite.BasicBlock]](pool, 8)
|
||||
if except_bbs is None or match_bbs is None:
|
||||
return 0
|
||||
for i_t in range(n_handlers_t):
|
||||
viperlib.snprintf(bb_buf_t, 64, "try.except.%d.%d", lc_t, i_t)
|
||||
eb_t: llvmlite.BasicBlock | t.CPtr = llvmlite.create_block(pool, func, bb_buf_t)
|
||||
eb_t: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(pool, func, bb_buf_t)
|
||||
viperlib.snprintf(bb_buf_t, 64, "try.match.%d.%d", lc_t, i_t)
|
||||
mb_t: llvmlite.BasicBlock | t.CPtr = llvmlite.create_block(pool, func, bb_buf_t)
|
||||
mb_t: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(pool, func, bb_buf_t)
|
||||
except_bbs.append(eb_t)
|
||||
match_bbs.append(mb_t)
|
||||
|
||||
# ---- 3. 保存外层 try 上下文,设置本 try 上下文 ----
|
||||
old_dispatch_t: llvmlite.BasicBlock | t.CPtr = trans._eh_dispatch_bb
|
||||
old_code_t: llvmlite.Value | t.CPtr = trans._eh_code_ptr
|
||||
old_msg_t: llvmlite.Value | t.CPtr = trans._eh_msg_ptr
|
||||
old_dispatch_t: rawptr[llvmlite.BasicBlock] = trans._eh_dispatch_bb
|
||||
old_code_t: rawptr[llvmlite.Value] = trans._eh_code_ptr
|
||||
old_msg_t: rawptr[llvmlite.Value] = trans._eh_msg_ptr
|
||||
trans._eh_dispatch_bb = dispatch_bb
|
||||
trans._eh_code_ptr = exception_code
|
||||
trans._eh_msg_ptr = eh_message
|
||||
@@ -290,13 +290,13 @@ class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin):
|
||||
# 无 except(非法 try,防御):直接吞掉
|
||||
llvmlite.build_br(builder, unhandled_bb)
|
||||
else:
|
||||
eh_code_val: llvmlite.Value | t.CPtr = llvmlite.build_load(
|
||||
eh_code_val: rawptr[llvmlite.Value] = llvmlite.build_load(
|
||||
builder, i32_ty_t, exception_code)
|
||||
next_check_t: llvmlite.BasicBlock | t.CPtr = None
|
||||
next_check_t: rawptr[llvmlite.BasicBlock] = None
|
||||
for i_t in range(n_handlers_t):
|
||||
hdr_t: rawptr[ast.ExceptHandler] = rawptr[ast.ExceptHandler](
|
||||
tr.handlers.get(i_t))
|
||||
match_bb_t: llvmlite.BasicBlock | t.CPtr = match_bbs.get(i_t)
|
||||
match_bb_t: rawptr[llvmlite.BasicBlock] = match_bbs.get(i_t)
|
||||
if i_t > 0 and next_check_t is not None:
|
||||
llvmlite.position_at_end(builder, next_check_t)
|
||||
eh_code_val = llvmlite.build_load(
|
||||
@@ -330,11 +330,11 @@ class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin):
|
||||
c0_t = 1
|
||||
codes_buf_t[0] = c0_t
|
||||
n_codes_t = 1
|
||||
match_cond_t: llvmlite.Value | t.CPtr = None
|
||||
match_cond_t: rawptr[llvmlite.Value] = None
|
||||
for ci_t in range(n_codes_t):
|
||||
code_val_t: llvmlite.Value | t.CPtr = llvmlite.const_int32(
|
||||
code_val_t: rawptr[llvmlite.Value] = llvmlite.const_int32(
|
||||
pool, codes_buf_t[ci_t])
|
||||
is_match_t: llvmlite.Value | t.CPtr = llvmlite.build_icmp(
|
||||
is_match_t: rawptr[llvmlite.Value] = llvmlite.build_icmp(
|
||||
builder, llvmlite.ICMP_EQ, eh_code_val, code_val_t)
|
||||
if match_cond_t is None:
|
||||
match_cond_t = is_match_t
|
||||
@@ -355,29 +355,29 @@ class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin):
|
||||
# 重复 define_var 不 shadow——多 try 共用 `as e` 时各 MatchBB
|
||||
# 各自 store 消息,各 ExceptBB 读同一入口 alloca,避免
|
||||
# 非支配 alloca 触发 "does not dominate all uses")。
|
||||
h_ent_t: GenTypes.VarEntry | t.CPtr = self.Gen.VarGen.lookup_var_entry(
|
||||
h_ent_t: rawptr[GenTypes.VarEntry] = self.Gen.VarGen.lookup_var_entry(
|
||||
trans.SymTab, hdr_t.name)
|
||||
if h_ent_t is not None and h_ent_t.Alloca is not None:
|
||||
h_alloca_t: llvmlite.Value | t.CPtr = h_ent_t.Alloca
|
||||
h_alloca_t: rawptr[llvmlite.Value] = h_ent_t.Alloca
|
||||
else:
|
||||
h_alloca_t = self.Gen.VarGen._alloca_at_entry(builder, i8_ptr_ty_t)
|
||||
if h_alloca_t is not None:
|
||||
self.Gen.VarGen.define_var(trans.SymTab, hdr_t.name, h_alloca_t)
|
||||
if h_alloca_t is not None:
|
||||
h_msg_t: llvmlite.Value | t.CPtr = llvmlite.build_load(
|
||||
h_msg_t: rawptr[llvmlite.Value] = llvmlite.build_load(
|
||||
builder, i8_ptr_ty_t, eh_message)
|
||||
if h_msg_t is not None:
|
||||
llvmlite.build_store(builder, h_msg_t, h_alloca_t)
|
||||
except_bb_t: llvmlite.BasicBlock | t.CPtr = except_bbs.get(i_t)
|
||||
except_bb_t: rawptr[llvmlite.BasicBlock] = except_bbs.get(i_t)
|
||||
llvmlite.build_br(builder, except_bb_t)
|
||||
|
||||
# ---- 6. UnhandledBB:无 except 匹配 → 向上传播或吞掉 ----
|
||||
llvmlite.position_at_end(builder, unhandled_bb)
|
||||
if trans._cur_func_has_eh != 0 and trans._eh_msg_out_param is not None \
|
||||
and trans._eh_code_out_param is not None:
|
||||
un_msg_t: llvmlite.Value | t.CPtr = llvmlite.build_load(
|
||||
un_msg_t: rawptr[llvmlite.Value] = llvmlite.build_load(
|
||||
builder, i8_ptr_ty_t, eh_message)
|
||||
un_code_t: llvmlite.Value | t.CPtr = llvmlite.build_load(
|
||||
un_code_t: rawptr[llvmlite.Value] = llvmlite.build_load(
|
||||
builder, i32_ty_t, exception_code)
|
||||
if un_msg_t is not None:
|
||||
llvmlite.build_store(builder, un_msg_t, trans._eh_msg_out_param)
|
||||
@@ -393,7 +393,7 @@ class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin):
|
||||
for i_t in range(n_handlers_t):
|
||||
hdr2_t: rawptr[ast.ExceptHandler] = rawptr[ast.ExceptHandler](
|
||||
tr.handlers.get(i_t))
|
||||
except_bb2_t: llvmlite.BasicBlock | t.CPtr = except_bbs.get(i_t)
|
||||
except_bb2_t: rawptr[llvmlite.BasicBlock] = 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: sizet = len(hdr2_t.children)
|
||||
@@ -439,11 +439,11 @@ class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin):
|
||||
if trans is None or node is None:
|
||||
return 0
|
||||
pool: rawptr[memhub.MemBuddy] = trans.Pool
|
||||
builder: llvmlite.IRBuilder | t.CPtr = trans._cur_builder
|
||||
builder: rawptr[llvmlite.IRBuilder] = trans._cur_builder
|
||||
mod: rawptr[llvmlite.LLVMModule] = trans.Module
|
||||
if pool is None or builder is None or mod is None:
|
||||
return 0
|
||||
rn: ast.Raise | t.CPtr = (ast.Raise | t.CPtr)(node)
|
||||
rn: rawptr[ast.Raise] = rawptr[ast.Raise](node)
|
||||
if rn is None or rn.exc is None:
|
||||
# bare raise(无 exc):v1 无活动异常可再抛,仅返回默认值
|
||||
self._eh_ret_default(trans, pool, builder)
|
||||
@@ -467,7 +467,7 @@ class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin):
|
||||
if trans._stop_iter_flag_ptr is not None:
|
||||
i1_ty_r: rawptr[llvmlite.LLVMType] = llvmlite.Int1(pool)
|
||||
if i1_ty_r is not None:
|
||||
one_i1_r: llvmlite.Value | t.CPtr = llvmlite.ConstInt(
|
||||
one_i1_r: rawptr[llvmlite.Value] = llvmlite.ConstInt(
|
||||
pool, i1_ty_r, 1, "1")
|
||||
if one_i1_r is not None:
|
||||
llvmlite.build_store(
|
||||
@@ -477,7 +477,7 @@ class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin):
|
||||
|
||||
# ---- 非 StopIteration:计算异常编码与消息 ----
|
||||
exc_code: int = 1
|
||||
exc_msg: llvmlite.Value | t.CPtr = None
|
||||
exc_msg: rawptr[llvmlite.Value] = None
|
||||
if ek == ast.ASTKind.Constant:
|
||||
cst_r: rawptr[ast.Constant] = rawptr[ast.Constant](rn.exc)
|
||||
if cst_r is not None and cst_r.const_kind == ast.CONST_INT:
|
||||
@@ -503,7 +503,7 @@ class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin):
|
||||
# ---- 异常分发 ----
|
||||
# 1. try 内:写入 try 的 eh_code/eh_message alloca,分支 DispatchBB
|
||||
if trans._eh_dispatch_bb is not None and trans._eh_code_ptr is not None:
|
||||
code_val_r: llvmlite.Value | t.CPtr = llvmlite.const_int32(pool, exc_code)
|
||||
code_val_r: rawptr[llvmlite.Value] = llvmlite.const_int32(pool, exc_code)
|
||||
if code_val_r is not None:
|
||||
llvmlite.build_store(builder, code_val_r, trans._eh_code_ptr)
|
||||
if exc_msg is None:
|
||||
@@ -516,7 +516,7 @@ class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin):
|
||||
# 2. 函数有 EH 输出参数:写入 out 参数(异常向调用方传播)
|
||||
if trans._cur_func_has_eh != 0 and trans._eh_msg_out_param is not None \
|
||||
and trans._eh_code_out_param is not None:
|
||||
code_val_r2: llvmlite.Value | t.CPtr = llvmlite.const_int32(pool, exc_code)
|
||||
code_val_r2: rawptr[llvmlite.Value] = llvmlite.const_int32(pool, exc_code)
|
||||
if code_val_r2 is not None:
|
||||
llvmlite.build_store(builder, code_val_r2, trans._eh_code_out_param)
|
||||
if exc_msg is None:
|
||||
@@ -539,7 +539,7 @@ class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin):
|
||||
# ============================================================
|
||||
def _eh_ret_default(self, trans: rawptr[HT.Translator],
|
||||
pool: rawptr[memhub.MemBuddy],
|
||||
builder: llvmlite.IRBuilder | t.CPtr) -> int:
|
||||
builder: rawptr[llvmlite.IRBuilder]) -> int:
|
||||
"""异常路径返回当前函数默认零值,返回 0"""
|
||||
if trans is None or builder is None:
|
||||
return 0
|
||||
@@ -555,15 +555,15 @@ class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin):
|
||||
case llvmlite.LLVMType.Void():
|
||||
llvmlite.build_ret_void(builder)
|
||||
case llvmlite.LLVMType.Ptr(_pe):
|
||||
null_v: llvmlite.Value | t.CPtr = llvmlite.ConstNull(pool, ret_ty, "null")
|
||||
null_v: rawptr[llvmlite.Value] = llvmlite.ConstNull(pool, ret_ty, "null")
|
||||
if null_v is not None:
|
||||
llvmlite.build_ret(builder, null_v)
|
||||
case llvmlite.LLVMType.Float(_fb):
|
||||
zero_f: llvmlite.Value | t.CPtr = llvmlite.ConstFloat(pool, ret_ty, 0.0)
|
||||
zero_f: rawptr[llvmlite.Value] = llvmlite.ConstFloat(pool, ret_ty, 0.0)
|
||||
if zero_f is not None:
|
||||
llvmlite.build_ret(builder, zero_f)
|
||||
case _:
|
||||
zero_v: llvmlite.Value | t.CPtr = llvmlite.ConstZero(pool, ret_ty)
|
||||
zero_v: rawptr[llvmlite.Value] = llvmlite.ConstZero(pool, ret_ty)
|
||||
if zero_v is not None:
|
||||
llvmlite.build_ret(builder, zero_v)
|
||||
return 0
|
||||
@@ -593,17 +593,17 @@ class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin):
|
||||
if wt is None:
|
||||
return 0
|
||||
pool: rawptr[memhub.MemBuddy] = trans.Pool
|
||||
builder: llvmlite.IRBuilder | t.CPtr = trans._cur_builder
|
||||
builder: rawptr[llvmlite.IRBuilder] = trans._cur_builder
|
||||
mod: rawptr[llvmlite.LLVMModule] = trans.Module
|
||||
if pool is None or builder is None or mod is None:
|
||||
return 0
|
||||
items: list[rawptr[ast.AST]] | t.CPtr = wt.items
|
||||
items: rawptr[list[rawptr[ast.AST]]] = wt.items
|
||||
if items is None:
|
||||
return 0
|
||||
n: sizet = len(items)
|
||||
|
||||
# 保存外层 __with_ctx(嵌套 with 时退出后恢复)
|
||||
old_ctx_alloca: llvmlite.Value | t.CPtr = self.Gen.VarGen.lookup_var(
|
||||
old_ctx_alloca: rawptr[llvmlite.Value] = self.Gen.VarGen.lookup_var(
|
||||
trans.SymTab, "__with_ctx")
|
||||
|
||||
# 记录每个 item 的类名(__exit__ 调用时设置 __with_ctx 类型用)
|
||||
@@ -619,11 +619,11 @@ class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin):
|
||||
continue
|
||||
if item_node.kind() != ast.ASTKind.WithItem:
|
||||
continue
|
||||
item: ast.WithItem | t.CPtr = (ast.WithItem | t.CPtr)(item_node)
|
||||
item: rawptr[ast.WithItem] = rawptr[ast.WithItem](item_node)
|
||||
if item is None or item.context_expr is None:
|
||||
continue
|
||||
# 翻译 context_expr(对象构造,如 MemPool(arena, 4096))
|
||||
ctx_val: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
|
||||
ctx_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, item.context_expr,
|
||||
trans._funcs, trans._func_count, trans)
|
||||
if ctx_val is None:
|
||||
@@ -651,7 +651,7 @@ class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin):
|
||||
elif cfn.kind() == ast.ASTKind.Name:
|
||||
cls_name = (rawptr[ast.Name](cfn)).id
|
||||
# context 对象存入 __with_ctx(方法调用解析 self 用)
|
||||
ctx_alloca: llvmlite.Value | t.CPtr = llvmlite.build_alloca(
|
||||
ctx_alloca: rawptr[llvmlite.Value] = llvmlite.build_alloca(
|
||||
builder, ctx_val.Ty)
|
||||
if ctx_alloca is None:
|
||||
continue
|
||||
@@ -662,7 +662,7 @@ class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin):
|
||||
trans.SymTab, "__with_ctx", cls_name)
|
||||
ctx_class_buf[i] = sizet(cls_name)
|
||||
# 调用 __enter__()
|
||||
enter_val: llvmlite.Value | t.CPtr = self._with_ctx_call(
|
||||
enter_val: rawptr[llvmlite.Value] = self._with_ctx_call(
|
||||
trans, pool, builder, mod, "__enter__")
|
||||
# asname 绑定(__enter__ 返回值,缺失时退回 context 对象)
|
||||
if item.optional_vars is not None:
|
||||
@@ -670,11 +670,11 @@ class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin):
|
||||
if ov.kind() == ast.ASTKind.Name:
|
||||
asname: str = (rawptr[ast.Name](ov)).id
|
||||
if asname is not None:
|
||||
bind_val: llvmlite.Value | t.CPtr = enter_val
|
||||
bind_val: rawptr[llvmlite.Value] = enter_val
|
||||
if bind_val is None:
|
||||
bind_val = ctx_val
|
||||
if bind_val is not None:
|
||||
asn_alloca: llvmlite.Value | t.CPtr = llvmlite.build_alloca(
|
||||
asn_alloca: rawptr[llvmlite.Value] = llvmlite.build_alloca(
|
||||
builder, bind_val.Ty)
|
||||
if asn_alloca is not None:
|
||||
llvmlite.build_store(builder, bind_val, asn_alloca)
|
||||
@@ -695,7 +695,7 @@ class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin):
|
||||
trans, pool, builder, mod, fd_cls_bare, ctx_val)
|
||||
|
||||
# 2. 翻译 body
|
||||
body: list[rawptr[ast.AST]] | t.CPtr = wt.children
|
||||
body: rawptr[list[rawptr[ast.AST]]] = wt.children
|
||||
if body is not None:
|
||||
bn: sizet = len(body)
|
||||
for bi in range(bn):
|
||||
@@ -733,9 +733,9 @@ class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin):
|
||||
|
||||
def _with_ctx_call(self, trans: rawptr[HT.Translator],
|
||||
pool: rawptr[memhub.MemBuddy],
|
||||
builder: llvmlite.IRBuilder | t.CPtr,
|
||||
builder: rawptr[llvmlite.IRBuilder],
|
||||
mod: rawptr[llvmlite.LLVMModule],
|
||||
method_name: str) -> llvmlite.Value | t.CPtr:
|
||||
method_name: str) -> rawptr[llvmlite.Value]:
|
||||
"""构造并翻译 __with_ctx.<method_name>() 调用(__enter__/__exit__)"""
|
||||
if pool is None or method_name is None:
|
||||
return None
|
||||
|
||||
@@ -86,14 +86,14 @@ class StructGenMixin:
|
||||
|
||||
# --- 全局注册表(原 _struct_table/_struct_count) ---
|
||||
Gen: rawptr[Generator.Generator]
|
||||
StructTable: GenTypes.StructEntry | t.CPtr # STRUCT_MAX 槽位数组
|
||||
StructTable: rawptr[GenTypes.StructEntry] # STRUCT_MAX 槽位数组
|
||||
StructCount: int
|
||||
|
||||
# --- OOM 回收分配模式(原 _g_stdlib_alloc) ---
|
||||
StdlibAlloc: int
|
||||
|
||||
# --- 跨模块命名空间隔离(原 _visible_structs/_strict_visibility) ---
|
||||
VisibleStructs: hashtable.HashTable | t.CPtr
|
||||
VisibleStructs: rawptr[hashtable.HashTable]
|
||||
StrictVisibility: int
|
||||
|
||||
# --- 名 | 类型 下标索引(查找快速路径;索引不可信时回退原线性扫描) ---
|
||||
@@ -208,13 +208,13 @@ class StructGenMixin:
|
||||
self.StructIdxBuilt = 0
|
||||
return 1
|
||||
|
||||
def _get_struct_entry(self, i: int) -> GenTypes.StructEntry | t.CPtr:
|
||||
def _get_struct_entry(self, i: int) -> rawptr[GenTypes.StructEntry]:
|
||||
"""获取第 i 个结构体条目"""
|
||||
if self.StructTable is None or i < 0 or i >= STRUCT_MAX:
|
||||
return None
|
||||
entry_size: sizet = GenTypes.StructEntry.__sizeof__()
|
||||
addr: uint64 = uint64(self.StructTable) + i * entry_size
|
||||
return (GenTypes.StructEntry | t.CPtr)(addr)
|
||||
return rawptr[GenTypes.StructEntry](addr)
|
||||
|
||||
# 名 | 类型 索引(开放寻址 | 线性探测;槽存 index+1,0=空槽)
|
||||
# 目的:把 find_struct/find_struct_by_module(名)与 find_struct_by_type(类型指针)
|
||||
@@ -224,14 +224,14 @@ class StructGenMixin:
|
||||
# 条目被中和(Name[0]=0 / Ty=None)后索引槽成失效键,探测时键不等即判定未命中。
|
||||
def _struct_entry_name(self, i: int) -> str:
|
||||
"""取第 i 个条目的 Name(供索引探测比较),越界/空返回 None"""
|
||||
e: GenTypes.StructEntry | t.CPtr = self._get_struct_entry(i)
|
||||
e: rawptr[GenTypes.StructEntry] = self._get_struct_entry(i)
|
||||
if e is None:
|
||||
return None
|
||||
return e.Name
|
||||
|
||||
def _struct_entry_tyval(self, i: int) -> uint64:
|
||||
"""取第 i 个条目的 Ty 指针值(Ty=None 返回 0)"""
|
||||
e: GenTypes.StructEntry | t.CPtr = self._get_struct_entry(i)
|
||||
e: rawptr[GenTypes.StructEntry] = self._get_struct_entry(i)
|
||||
if e is None or e.Ty is None:
|
||||
return 0
|
||||
return uint64(e.Ty)
|
||||
@@ -281,7 +281,7 @@ class StructGenMixin:
|
||||
i += 1
|
||||
return 1
|
||||
|
||||
def _struct_idx_add(self, ei: int, entry: GenTypes.StructEntry | t.CPtr) -> None:
|
||||
def _struct_idx_add(self, ei: int, entry: rawptr[GenTypes.StructEntry]) -> None:
|
||||
"""新增条目后同步两张索引;任一写入失败 → 标记索引不可信(查找回退扫描)"""
|
||||
if self.StructNameIdx is None or self.StructTypeIdx is None or self.StructIdxCap <= 0:
|
||||
self.StructIdxBuilt = -1
|
||||
@@ -355,18 +355,18 @@ class StructGenMixin:
|
||||
i += 1
|
||||
return -1
|
||||
|
||||
def _get_field_entry(self, struct_entry: GenTypes.StructEntry | t.CPtr, i: int) -> GenTypes.FieldEntry | t.CPtr:
|
||||
def _get_field_entry(self, struct_entry: rawptr[GenTypes.StructEntry], i: int) -> rawptr[GenTypes.FieldEntry]:
|
||||
"""获取结构体中第 i 个字段条目"""
|
||||
if struct_entry is None or i < 0 or i >= FIELD_MAX:
|
||||
return None
|
||||
field_size: sizet = GenTypes.FieldEntry.__sizeof__()
|
||||
addr: uint64 = uint64(struct_entry.Fields) + i * field_size
|
||||
return (GenTypes.FieldEntry | t.CPtr)(addr)
|
||||
return rawptr[GenTypes.FieldEntry](addr)
|
||||
|
||||
def register_struct(self, pool: rawptr[memhub.MemBuddy],
|
||||
name: str,
|
||||
struct_ty: rawptr[llvmlite.LLVMType],
|
||||
sha1: str = None) -> GenTypes.StructEntry | t.CPtr:
|
||||
sha1: str = None) -> rawptr[GenTypes.StructEntry]:
|
||||
"""注册结构体类型,返回 StructEntry 指针
|
||||
|
||||
用类型指针去重(is 比较),不用类名去重。
|
||||
@@ -380,7 +380,7 @@ class StructGenMixin:
|
||||
# 用 uint64 指针值比较(is 比较会触发类型安全检查解引用悬空 Ty)
|
||||
# 走 find_struct_by_type(其 Ty 索引判定已整体停用、恢复原线性扫描),
|
||||
# 去重语义 = 原去重扫描"首个 Ty 指针相等条目"(首注册优先),逐字节一致。
|
||||
existing: GenTypes.StructEntry | t.CPtr = self.find_struct_by_type(struct_ty)
|
||||
existing: rawptr[GenTypes.StructEntry] = self.find_struct_by_type(struct_ty)
|
||||
if existing is not None:
|
||||
return existing
|
||||
|
||||
@@ -388,7 +388,7 @@ class StructGenMixin:
|
||||
VLogger.error(f"table full, cannot register {name}", "STRUCT")
|
||||
return None
|
||||
|
||||
entry: GenTypes.StructEntry | t.CPtr = self._get_struct_entry(self.StructCount)
|
||||
entry: rawptr[GenTypes.StructEntry] = self._get_struct_entry(self.StructCount)
|
||||
if entry is None:
|
||||
return None
|
||||
|
||||
@@ -438,7 +438,7 @@ class StructGenMixin:
|
||||
def register_struct_alias(self, pool: rawptr[memhub.MemBuddy],
|
||||
name: str,
|
||||
sha1: str,
|
||||
src_entry: GenTypes.StructEntry | t.CPtr) -> GenTypes.StructEntry | t.CPtr:
|
||||
src_entry: rawptr[GenTypes.StructEntry]) -> rawptr[GenTypes.StructEntry]:
|
||||
"""为已注册类追加包重导出别名 entry(方案A:ast.Attribute 归属 ast 包)
|
||||
|
||||
子模块类从包 __init__ 重导出时,查找端 _resolve_module_sha1 按
|
||||
@@ -456,12 +456,12 @@ class StructGenMixin:
|
||||
return None
|
||||
# 幂等:目标 (name, sha1) 已注册则跳过(find_struct_by_module 不回退裸名)
|
||||
if sha1[0] != '\0':
|
||||
existing: GenTypes.StructEntry | t.CPtr = self.find_struct_by_module(name, sha1)
|
||||
existing: rawptr[GenTypes.StructEntry] = self.find_struct_by_module(name, sha1)
|
||||
if existing is not None:
|
||||
return existing
|
||||
if self.StructCount >= STRUCT_MAX:
|
||||
return None
|
||||
entry: GenTypes.StructEntry | t.CPtr = self._get_struct_entry(self.StructCount)
|
||||
entry: rawptr[GenTypes.StructEntry] = self._get_struct_entry(self.StructCount)
|
||||
if entry is None:
|
||||
return None
|
||||
# 复制类名与 SHA1(别名注册同样按 StdlibAlloc 选分配源,跨 1a/1b reset 存活)
|
||||
@@ -510,7 +510,7 @@ class StructGenMixin:
|
||||
"""设置结构体所属模块的 SHA1,返回 1=成功 / 0=失败"""
|
||||
if class_name is None or sha1 is None:
|
||||
return 0
|
||||
entry: GenTypes.StructEntry | t.CPtr = self.find_struct(class_name)
|
||||
entry: rawptr[GenTypes.StructEntry] = self.find_struct(class_name)
|
||||
if entry is None:
|
||||
return 0
|
||||
# 复制 SHA1 字符串(StdlibAlloc=1 用永久池,跨 1a/1b 存活防 strcmp 悬空)
|
||||
@@ -531,13 +531,13 @@ class StructGenMixin:
|
||||
"""获取结构体所属模块的 SHA1,返回 None=无 SHA1"""
|
||||
if class_name is None or self.StructTable is None:
|
||||
return None
|
||||
entry: GenTypes.StructEntry | t.CPtr = self.find_struct(class_name)
|
||||
entry: rawptr[GenTypes.StructEntry] = self.find_struct(class_name)
|
||||
if entry is None:
|
||||
return None
|
||||
return entry.ModuleSha1
|
||||
|
||||
def add_field(self, pool: rawptr[memhub.MemBuddy],
|
||||
struct_entry: GenTypes.StructEntry | t.CPtr,
|
||||
struct_entry: rawptr[GenTypes.StructEntry],
|
||||
field_name: str,
|
||||
field_ty: rawptr[llvmlite.LLVMType],
|
||||
default_val: rawptr[ast.AST] = None,
|
||||
@@ -555,7 +555,7 @@ class StructGenMixin:
|
||||
return -1
|
||||
|
||||
idx: int = struct_entry.FieldCount
|
||||
fe: GenTypes.FieldEntry | t.CPtr = self._get_field_entry(struct_entry, idx)
|
||||
fe: rawptr[GenTypes.FieldEntry] = self._get_field_entry(struct_entry, idx)
|
||||
if fe is None:
|
||||
return -1
|
||||
|
||||
@@ -597,7 +597,7 @@ class StructGenMixin:
|
||||
|
||||
# [S3 条目双写] 字段类型 Spec(唯一类型承载,含注解来源名)。TypeSpec
|
||||
# 实例一律 PermPool 分配(驻留或独立副本)⇒ 天然跨 1b reset 存活。
|
||||
arena_f: TSpec.TypeSpecArena | t.CPtr = self.Gen.TypeGenBase.ensure_spec_arena()
|
||||
arena_f: rawptr[TSpec.TypeSpecArena] = self.Gen.TypeGenBase.ensure_spec_arena()
|
||||
if arena_f is not None:
|
||||
fe.Spec = TSpec.SpecFromLLVMType(arena_f, field_ty)
|
||||
# [S4 注解侧填 Spec] 补字段 Spec 的符号性与注解来源名(annot_class_name
|
||||
@@ -668,8 +668,8 @@ class StructGenMixin:
|
||||
只被只读访问 get/__len__/迭代,不 append,不会触发 pool 扩容)。
|
||||
元素递归调用 _deep_copy_default_ast(支持 Constant 与嵌套 List)。
|
||||
"""
|
||||
src_l: ast.List | t.CPtr = (ast.List | t.CPtr)(default_val)
|
||||
dst_l: ast.List | t.CPtr = (ast.List | t.CPtr)(
|
||||
src_l: rawptr[ast.List] = rawptr[ast.List](default_val)
|
||||
dst_l: rawptr[ast.List] = rawptr[ast.List](
|
||||
pool.alloc(ast.List.__sizeof__()))
|
||||
if dst_l is None:
|
||||
return None
|
||||
@@ -684,10 +684,10 @@ class StructGenMixin:
|
||||
dst_l.end_col_offset = src_l.end_col_offset
|
||||
dst_l.ctx = src_l.ctx
|
||||
# 深拷贝 elts:stdlib 手动构造 list[AST | t.CPtr] 容器
|
||||
src_elts_l: list[rawptr[ast.AST]] | t.CPtr = src_l.elts
|
||||
src_elts_l: rawptr[list[rawptr[ast.AST]]] = src_l.elts
|
||||
if src_elts_l is not None:
|
||||
cnt_l: sizet = len(src_elts_l)
|
||||
lst_copy_l: list[rawptr[ast.AST]] | t.CPtr = (list[rawptr[ast.AST]] | t.CPtr)(
|
||||
lst_copy_l: rawptr[list[rawptr[ast.AST]]] = rawptr[list[rawptr[ast.AST]]](
|
||||
pool.alloc(list[rawptr[ast.AST]].__sizeof__()))
|
||||
if lst_copy_l is not None:
|
||||
string.memset(lst_copy_l, 0, list[rawptr[ast.AST]].__sizeof__())
|
||||
@@ -743,7 +743,7 @@ class StructGenMixin:
|
||||
s_rm = StubMergerStore.LookupSha1ByModNameSuffix(mod_name)
|
||||
return s_rm
|
||||
|
||||
def find_struct(self, name: str) -> GenTypes.StructEntry | t.CPtr:
|
||||
def find_struct(self, name: str) -> rawptr[GenTypes.StructEntry]:
|
||||
"""按类名查找结构体,返回 StructEntry 或 None
|
||||
|
||||
支持模块限定名(如 "HT.Translator"):
|
||||
@@ -775,7 +775,7 @@ class StructGenMixin:
|
||||
name_idx_trusted = 1
|
||||
if name_idx_trusted == 0 or name[0] == '\0':
|
||||
for i in range(self.StructCount):
|
||||
entry: GenTypes.StructEntry | t.CPtr = self._get_struct_entry(i)
|
||||
entry: rawptr[GenTypes.StructEntry] = self._get_struct_entry(i)
|
||||
if entry is not None and entry.Name is not None:
|
||||
if string.strcmp(entry.Name, name) == 0:
|
||||
return entry
|
||||
@@ -805,22 +805,22 @@ class StructGenMixin:
|
||||
# 统一走 GenApi.is_sha1_hex16(该判定的唯一真源)。
|
||||
mod_hex_ok: int = GenApi.is_sha1_hex16(mod_buf_f)
|
||||
if mod_hex_ok != 0:
|
||||
me_h: GenTypes.StructEntry | t.CPtr = \
|
||||
me_h: rawptr[GenTypes.StructEntry] = \
|
||||
self.find_struct_by_module(bare_f, mod_buf_f)
|
||||
stdlib.free(mod_buf_f)
|
||||
return me_h
|
||||
mod_sha1_f: str = self._resolve_module_sha1(mod_buf_f)
|
||||
if mod_sha1_f is not None:
|
||||
me_f: GenTypes.StructEntry | t.CPtr = \
|
||||
me_f: rawptr[GenTypes.StructEntry] = \
|
||||
self.find_struct_by_module(bare_f, mod_sha1_f)
|
||||
if me_f is not None:
|
||||
stdlib.free(mod_buf_f)
|
||||
return me_f
|
||||
# 模块类未注册:统计裸名同名类数量,唯一时回退(无冲突)
|
||||
same_cnt_f: int = 0
|
||||
same_entry_f: GenTypes.StructEntry | t.CPtr = None
|
||||
same_entry_f: rawptr[GenTypes.StructEntry] = None
|
||||
for i2 in range(self.StructCount):
|
||||
e2: GenTypes.StructEntry | t.CPtr = self._get_struct_entry(i2)
|
||||
e2: rawptr[GenTypes.StructEntry] = self._get_struct_entry(i2)
|
||||
if e2 is not None and e2.Name is not None:
|
||||
if string.strcmp(e2.Name, bare_f) == 0:
|
||||
same_cnt_f += 1
|
||||
@@ -840,9 +840,9 @@ class StructGenMixin:
|
||||
# 与 App gfx 都定义 Scene3D)存在时不得返回先注册的错误 entry——否则
|
||||
# 模块段无法解析的限定名被劫持到错误模块 → 返回类型解析查错 text.ll。
|
||||
same_cnt_b: int = 0
|
||||
same_entry_b: GenTypes.StructEntry | t.CPtr = None
|
||||
same_entry_b: rawptr[GenTypes.StructEntry] = None
|
||||
for i in range(self.StructCount):
|
||||
entry: GenTypes.StructEntry | t.CPtr = self._get_struct_entry(i)
|
||||
entry: rawptr[GenTypes.StructEntry] = self._get_struct_entry(i)
|
||||
if entry is not None and entry.Name is not None:
|
||||
if string.strcmp(entry.Name, class_name) == 0:
|
||||
same_cnt_b += 1
|
||||
@@ -851,7 +851,7 @@ class StructGenMixin:
|
||||
return same_entry_b
|
||||
return None
|
||||
|
||||
def find_struct_by_module(self, name: str, sha1: str) -> GenTypes.StructEntry | t.CPtr:
|
||||
def find_struct_by_module(self, name: str, sha1: str) -> rawptr[GenTypes.StructEntry]:
|
||||
"""按类名 + SHA1 查找结构体,返回 StructEntry 或 None
|
||||
|
||||
SHA1 非 None 时:精确匹配 name+sha1,未找到返回 None(不回退,避免跨模块同名找错)
|
||||
@@ -872,7 +872,7 @@ class StructGenMixin:
|
||||
if fri >= 0:
|
||||
start = fri
|
||||
for i in range(start, self.StructCount):
|
||||
entry: GenTypes.StructEntry | t.CPtr = self._get_struct_entry(i)
|
||||
entry: rawptr[GenTypes.StructEntry] = self._get_struct_entry(i)
|
||||
if entry is not None and entry.Name is not None:
|
||||
# 快速路径:strcmp 判等蕴含首字符相等,首字符不同者跳过 strcmp。
|
||||
if entry.Name[0] == name[0] and string.strcmp(entry.Name, name) == 0:
|
||||
@@ -906,7 +906,7 @@ class StructGenMixin:
|
||||
return 0
|
||||
reset_count: int = 0
|
||||
for i in range(self.StructCount):
|
||||
entry: GenTypes.StructEntry | t.CPtr = self._get_struct_entry(i)
|
||||
entry: rawptr[GenTypes.StructEntry] = self._get_struct_entry(i)
|
||||
if entry is not None:
|
||||
# 普通类按 ModuleSha1 匹配
|
||||
if entry.ModuleSha1 is not None:
|
||||
@@ -923,7 +923,7 @@ class StructGenMixin:
|
||||
reset_count += 1
|
||||
return reset_count
|
||||
|
||||
def find_struct_by_type(self, struct_ty: rawptr[llvmlite.LLVMType]) -> GenTypes.StructEntry | t.CPtr:
|
||||
def find_struct_by_type(self, struct_ty: rawptr[llvmlite.LLVMType]) -> rawptr[GenTypes.StructEntry]:
|
||||
"""按类型指针查找结构体(指针值比较),返回 StructEntry 或 None
|
||||
|
||||
注意: 不能用 `entry.Ty is struct_ty` 的 is 比较——TPV 编译 is 时会触发
|
||||
@@ -944,7 +944,7 @@ class StructGenMixin:
|
||||
# 首个 Ty 相等条目",命中路径与原语义不等价、且无法低成本保证等价。故此处
|
||||
# 恢复原线性精确扫描(未命中/命中行为均与未加索引前逐字节一致)。
|
||||
for i in range(self.StructCount):
|
||||
entry: GenTypes.StructEntry | t.CPtr = self._get_struct_entry(i)
|
||||
entry: rawptr[GenTypes.StructEntry] = self._get_struct_entry(i)
|
||||
if entry is not None and entry.Ty is not None:
|
||||
if uint64(entry.Ty) == st_val:
|
||||
return entry
|
||||
@@ -963,7 +963,7 @@ class StructGenMixin:
|
||||
sname: str = llvmlite.get_struct_name(struct_ty)
|
||||
if sname is None:
|
||||
return 0
|
||||
entry: GenTypes.StructEntry | t.CPtr = self.find_struct_by_type(struct_ty)
|
||||
entry: rawptr[GenTypes.StructEntry] = self.find_struct_by_type(struct_ty)
|
||||
if entry is None:
|
||||
entry = self.find_struct(sname)
|
||||
if entry is None:
|
||||
@@ -971,7 +971,7 @@ class StructGenMixin:
|
||||
return entry.IsPacked
|
||||
|
||||
def lookup_field(self, struct_ty: rawptr[llvmlite.LLVMType],
|
||||
field_name: str) -> GenTypes.FieldEntry | t.CPtr:
|
||||
field_name: str) -> rawptr[GenTypes.FieldEntry]:
|
||||
"""按结构体类型和字段名查找字段信息
|
||||
|
||||
两遍查找策略(跨模块同名类冲突的根本修复):
|
||||
@@ -997,10 +997,10 @@ class StructGenMixin:
|
||||
# find_struct_by_type 的语义 = 原扫描"首个 Ty 指针相等条目"(首注册优先);
|
||||
# 其 Ty 索引判定已整体停用、恢复原线性扫描 ⇒ 选中的 entry 与原 is 身份扫描
|
||||
# 完全一致。类型唯一确定 entry:命中后查字段,字段未找到直接返回 None。
|
||||
lk_entry: GenTypes.StructEntry | t.CPtr = self.find_struct_by_type(struct_ty)
|
||||
lk_entry: rawptr[GenTypes.StructEntry] = self.find_struct_by_type(struct_ty)
|
||||
if lk_entry is not None:
|
||||
for fi in range(lk_entry.FieldCount):
|
||||
fe: GenTypes.FieldEntry | t.CPtr = self._get_field_entry(lk_entry, fi)
|
||||
fe: rawptr[GenTypes.FieldEntry] = self._get_field_entry(lk_entry, fi)
|
||||
if fe is not None and fe.Name is not None:
|
||||
if string.strcmp(fe.Name, field_name) == 0:
|
||||
return fe
|
||||
@@ -1018,7 +1018,7 @@ class StructGenMixin:
|
||||
if GenApi.sha1_prefix_len(ty_name) != 0:
|
||||
ty_has_sha1_lf = 1
|
||||
for i in range(self.StructCount):
|
||||
entry: GenTypes.StructEntry | t.CPtr = self._get_struct_entry(i)
|
||||
entry: rawptr[GenTypes.StructEntry] = self._get_struct_entry(i)
|
||||
if entry is not None and entry.Name is not None:
|
||||
# 类型名带 SHA1 前缀:必须与 entry.ModuleSha1 前 16 字符
|
||||
# 精确一致,否则跳过(跨模块同名类命名空间隔离)
|
||||
@@ -1035,7 +1035,7 @@ class StructGenMixin:
|
||||
if matched != 0:
|
||||
# 查找字段
|
||||
for fi in range(entry.FieldCount):
|
||||
fe: GenTypes.FieldEntry | t.CPtr = self._get_field_entry(entry, fi)
|
||||
fe: rawptr[GenTypes.FieldEntry] = self._get_field_entry(entry, fi)
|
||||
if fe is not None and fe.Name is not None:
|
||||
if string.strcmp(fe.Name, field_name) == 0:
|
||||
return fe
|
||||
@@ -1075,7 +1075,7 @@ class StructGenMixin:
|
||||
field_name: str,
|
||||
sha1: str = None,
|
||||
node: rawptr[ast.AST] = None,
|
||||
from_imports: str = None) -> GenTypes.FieldEntry | t.CPtr:
|
||||
from_imports: str = None) -> rawptr[GenTypes.FieldEntry]:
|
||||
"""按类名和字段名查找字段信息
|
||||
|
||||
优先用 SHA1 匹配(跨模块同名类区分),无 SHA1 时按类名查找第一个。
|
||||
@@ -1101,7 +1101,7 @@ class StructGenMixin:
|
||||
if bare_name is None or bare_name[0] == '\0':
|
||||
bare_name = class_name
|
||||
for i in range(self.StructCount):
|
||||
entry: GenTypes.StructEntry | t.CPtr = self._get_struct_entry(i)
|
||||
entry: rawptr[GenTypes.StructEntry] = self._get_struct_entry(i)
|
||||
if entry is not None and entry.Name is not None:
|
||||
# 精确匹配或类名回退匹配
|
||||
name_match: int = 0
|
||||
@@ -1115,7 +1115,7 @@ class StructGenMixin:
|
||||
sha1_matched = 1
|
||||
# SHA1 + 类名匹配,查找字段
|
||||
for fi in range(entry.FieldCount):
|
||||
fe: GenTypes.FieldEntry | t.CPtr = self._get_field_entry(entry, fi)
|
||||
fe: rawptr[GenTypes.FieldEntry] = self._get_field_entry(entry, fi)
|
||||
if fe is not None and fe.Name is not None \
|
||||
and string.strcmp(fe.Name, field_name) == 0:
|
||||
return fe
|
||||
@@ -1159,7 +1159,7 @@ class StructGenMixin:
|
||||
else:
|
||||
mod_sha1_q = self._resolve_module_sha1(mod_buf_q, from_imports)
|
||||
if mod_sha1_q is not None:
|
||||
mod_entry_q: GenTypes.StructEntry | t.CPtr = \
|
||||
mod_entry_q: rawptr[GenTypes.StructEntry] = \
|
||||
self.find_struct_by_module(bare_q, mod_sha1_q)
|
||||
if mod_entry_q is not None:
|
||||
# 依赖未就绪容忍(对齐裸名路径):FieldCount==0 的空类
|
||||
@@ -1169,7 +1169,7 @@ class StructGenMixin:
|
||||
stdlib.free(mod_buf_q)
|
||||
return None
|
||||
for fi_q in range(mod_entry_q.FieldCount):
|
||||
fe_q: GenTypes.FieldEntry | t.CPtr = \
|
||||
fe_q: rawptr[GenTypes.FieldEntry] = \
|
||||
self._get_field_entry(mod_entry_q, fi_q)
|
||||
if fe_q is not None and fe_q.Name is not None:
|
||||
if string.strcmp(fe_q.Name, field_name) == 0:
|
||||
@@ -1195,7 +1195,7 @@ class StructGenMixin:
|
||||
rn_alias_q = self.Gen.ClassGenEnum._lookup_renum_field_alias(
|
||||
bare_q, field_name)
|
||||
if rn_alias_q >= 1:
|
||||
rn_fe_q: GenTypes.FieldEntry | t.CPtr = \
|
||||
rn_fe_q: rawptr[GenTypes.FieldEntry] = \
|
||||
self._get_field_entry(mod_entry_q, rn_alias_q)
|
||||
if rn_fe_q is not None and rn_fe_q.Ty is not None:
|
||||
stdlib.free(mod_buf_q)
|
||||
@@ -1229,7 +1229,7 @@ class StructGenMixin:
|
||||
return None
|
||||
# 先查找字段(诊断/error 之前返回,否则 error 立即退出导致查找永远失败)
|
||||
for fi in range(entry.FieldCount):
|
||||
fe: GenTypes.FieldEntry | t.CPtr = self._get_field_entry(entry, fi)
|
||||
fe: rawptr[GenTypes.FieldEntry] = self._get_field_entry(entry, fi)
|
||||
if fe is not None and fe.Name is not None:
|
||||
if string.strcmp(fe.Name, field_name) == 0:
|
||||
return fe
|
||||
@@ -1255,7 +1255,7 @@ class StructGenMixin:
|
||||
rn_alias_l = self.Gen.ClassGenEnum._lookup_renum_field_alias(
|
||||
class_name, field_name)
|
||||
if rn_alias_l >= 1:
|
||||
rn_fe_l: GenTypes.FieldEntry | t.CPtr = \
|
||||
rn_fe_l: rawptr[GenTypes.FieldEntry] = \
|
||||
self.Gen.StructGen._get_field_entry(entry, rn_alias_l)
|
||||
if rn_fe_l is not None and rn_fe_l.Ty is not None:
|
||||
return rn_fe_l
|
||||
@@ -1265,7 +1265,7 @@ class StructGenMixin:
|
||||
if fb_flds_lst is not None:
|
||||
fb_flds_lst[0] = '\0'
|
||||
for fi in range(entry.FieldCount):
|
||||
fe: GenTypes.FieldEntry | t.CPtr = self._get_field_entry(entry, fi)
|
||||
fe: rawptr[GenTypes.FieldEntry] = self._get_field_entry(entry, fi)
|
||||
if fe is not None and fe.Name is not None:
|
||||
if string.strlen(fb_flds_lst) > 0 and string.strlen(fb_flds_lst) + 3 < 1024:
|
||||
string.strcat(fb_flds_lst, ", ")
|
||||
@@ -1304,17 +1304,17 @@ class StructGenMixin:
|
||||
|
||||
def get_struct_type(self, class_name: str) -> rawptr[llvmlite.LLVMType]:
|
||||
"""按类名获取结构体的 LLVM 类型"""
|
||||
entry: GenTypes.StructEntry | t.CPtr = self.find_struct(class_name)
|
||||
entry: rawptr[GenTypes.StructEntry] = self.find_struct(class_name)
|
||||
if entry is not None:
|
||||
return entry.Ty
|
||||
return None
|
||||
|
||||
def get_field_by_index(self, class_name: str,
|
||||
idx: int) -> GenTypes.FieldEntry | t.CPtr:
|
||||
idx: int) -> rawptr[GenTypes.FieldEntry]:
|
||||
"""按类名和字段索引获取字段信息"""
|
||||
if class_name is None:
|
||||
return None
|
||||
entry: GenTypes.StructEntry | t.CPtr = self.find_struct(class_name)
|
||||
entry: rawptr[GenTypes.StructEntry] = self.find_struct(class_name)
|
||||
if entry is None:
|
||||
return None
|
||||
if idx < 0 or idx >= entry.FieldCount:
|
||||
@@ -1325,16 +1325,16 @@ class StructGenMixin:
|
||||
"""检查结构体是否有任何带默认值的字段,返回 1=有 / 0=无"""
|
||||
if class_name is None:
|
||||
return 0
|
||||
entry: GenTypes.StructEntry | t.CPtr = self.find_struct(class_name)
|
||||
entry: rawptr[GenTypes.StructEntry] = self.find_struct(class_name)
|
||||
if entry is None:
|
||||
return 0
|
||||
for fi in range(entry.FieldCount):
|
||||
fe: GenTypes.FieldEntry | t.CPtr = self._get_field_entry(entry, fi)
|
||||
fe: rawptr[GenTypes.FieldEntry] = self._get_field_entry(entry, fi)
|
||||
if fe is not None and fe.DefaultVal is not None:
|
||||
return 1
|
||||
return 0
|
||||
|
||||
def get_struct_type_from_value(self, val: llvmlite.Value | t.CPtr) -> rawptr[llvmlite.LLVMType]:
|
||||
def get_struct_type_from_value(self, val: rawptr[llvmlite.Value]) -> rawptr[llvmlite.LLVMType]:
|
||||
"""从 Value 的类型推断结构体类型
|
||||
|
||||
递归解 Ptr:支持 X|t.CPtr 联合简化产生的 Ptr(Ptr(Struct)) 对象指针
|
||||
@@ -1365,7 +1365,7 @@ class StructGenMixin:
|
||||
"""标记已注册的结构体为联合体,返回 1=成功 / 0=失败"""
|
||||
if name is None:
|
||||
return 0
|
||||
entry: GenTypes.StructEntry | t.CPtr = self.find_struct(name)
|
||||
entry: rawptr[GenTypes.StructEntry] = self.find_struct(name)
|
||||
if entry is None:
|
||||
return 0
|
||||
entry.IsUnion = 1
|
||||
@@ -1375,7 +1375,7 @@ class StructGenMixin:
|
||||
"""按类名检查是否为联合体,返回 1=是 / 0=否"""
|
||||
if name is None:
|
||||
return 0
|
||||
entry: GenTypes.StructEntry | t.CPtr = self.find_struct(name)
|
||||
entry: rawptr[GenTypes.StructEntry] = self.find_struct(name)
|
||||
if entry is None:
|
||||
return 0
|
||||
return entry.IsUnion
|
||||
@@ -1390,7 +1390,7 @@ class StructGenMixin:
|
||||
ty_name: str = self._extract_struct_name(struct_ty)
|
||||
st_iu: uint64 = uint64(struct_ty)
|
||||
for i in range(self.StructCount):
|
||||
entry: GenTypes.StructEntry | t.CPtr = self._get_struct_entry(i)
|
||||
entry: rawptr[GenTypes.StructEntry] = self._get_struct_entry(i)
|
||||
if entry is not None and entry.Ty is not None:
|
||||
matched: int = 0
|
||||
if uint64(entry.Ty) == st_iu:
|
||||
@@ -1408,7 +1408,7 @@ class StructGenMixin:
|
||||
"""标记已注册的结构体为 OOP,返回 1=成功 / 0=失败"""
|
||||
if name is None:
|
||||
return 0
|
||||
entry: GenTypes.StructEntry | t.CPtr = self.find_struct(name)
|
||||
entry: rawptr[GenTypes.StructEntry] = self.find_struct(name)
|
||||
if entry is None:
|
||||
return 0
|
||||
entry.IsOOP = 1
|
||||
@@ -1418,7 +1418,7 @@ class StructGenMixin:
|
||||
"""按类名检查是否为 OOP 结构体,返回 1=是 / 0=否"""
|
||||
if name is None:
|
||||
return 0
|
||||
entry: GenTypes.StructEntry | t.CPtr = self.find_struct(name)
|
||||
entry: rawptr[GenTypes.StructEntry] = self.find_struct(name)
|
||||
if entry is None:
|
||||
return 0
|
||||
return entry.IsOOP
|
||||
@@ -1427,7 +1427,7 @@ class StructGenMixin:
|
||||
"""标记结构体拥有 __init__ 方法,返回 1=成功 / 0=失败"""
|
||||
if name is None:
|
||||
return 0
|
||||
entry: GenTypes.StructEntry | t.CPtr = self.find_struct(name)
|
||||
entry: rawptr[GenTypes.StructEntry] = self.find_struct(name)
|
||||
if entry is None:
|
||||
return 0
|
||||
entry.HasInit = 1
|
||||
@@ -1437,7 +1437,7 @@ class StructGenMixin:
|
||||
"""按类名检查是否有 __init__ 方法,返回 1=有 / 0=无"""
|
||||
if name is None:
|
||||
return 0
|
||||
entry: GenTypes.StructEntry | t.CPtr = self.find_struct(name)
|
||||
entry: rawptr[GenTypes.StructEntry] = self.find_struct(name)
|
||||
if entry is None:
|
||||
return 0
|
||||
return entry.HasInit
|
||||
@@ -1446,7 +1446,7 @@ class StructGenMixin:
|
||||
"""标记结构体拥有 __new__ 方法,返回 1=成功 / 0=失败"""
|
||||
if name is None:
|
||||
return 0
|
||||
entry: GenTypes.StructEntry | t.CPtr = self.find_struct(name)
|
||||
entry: rawptr[GenTypes.StructEntry] = self.find_struct(name)
|
||||
if entry is None:
|
||||
return 0
|
||||
entry.HasNew = 1
|
||||
@@ -1456,7 +1456,7 @@ class StructGenMixin:
|
||||
"""按类名检查是否有 __new__ 方法,返回 1=有 / 0=无"""
|
||||
if name is None:
|
||||
return 0
|
||||
entry: GenTypes.StructEntry | t.CPtr = self.find_struct(name)
|
||||
entry: rawptr[GenTypes.StructEntry] = self.find_struct(name)
|
||||
if entry is None:
|
||||
return 0
|
||||
return entry.HasNew
|
||||
@@ -1468,7 +1468,7 @@ class StructGenMixin:
|
||||
return None
|
||||
# find_struct_by_type 的语义 = 原扫描"首个 Ty 指针相等条目"(首注册优先),
|
||||
# 返回其 Name;其 Ty 索引判定已整体停用、恢复原线性扫描 ⇒ 逐字节一致。
|
||||
fast_cn: GenTypes.StructEntry | t.CPtr = self.find_struct_by_type(struct_ty)
|
||||
fast_cn: rawptr[GenTypes.StructEntry] = self.find_struct_by_type(struct_ty)
|
||||
if fast_cn is not None:
|
||||
return fast_cn.Name
|
||||
# 回退: 类型指针比较失败时,遍历所有注册的结构体按名称匹配
|
||||
@@ -1476,7 +1476,7 @@ class StructGenMixin:
|
||||
ty_name: str = self._extract_struct_name(struct_ty)
|
||||
if ty_name is not None:
|
||||
for j in range(self.StructCount):
|
||||
entry2: GenTypes.StructEntry | t.CPtr = self._get_struct_entry(j)
|
||||
entry2: rawptr[GenTypes.StructEntry] = self._get_struct_entry(j)
|
||||
if entry2 is not None and entry2.Name is not None:
|
||||
# 构造 "SHA1.ClassName" 格式进行比较
|
||||
entry2_sha1: str = entry2.ModuleSha1
|
||||
@@ -1523,7 +1523,7 @@ class StructGenMixin:
|
||||
"""标记结构体拥有虚表,返回 1=成功 / 0=失败"""
|
||||
if name is None:
|
||||
return 0
|
||||
entry: GenTypes.StructEntry | t.CPtr = self.find_struct(name)
|
||||
entry: rawptr[GenTypes.StructEntry] = self.find_struct(name)
|
||||
if entry is None:
|
||||
return 0
|
||||
entry.HasVTable = 1
|
||||
@@ -1533,7 +1533,7 @@ class StructGenMixin:
|
||||
"""按类名检查是否有虚表,返回 1=有 / 0=无"""
|
||||
if name is None:
|
||||
return 0
|
||||
entry: GenTypes.StructEntry | t.CPtr = self.find_struct(name)
|
||||
entry: rawptr[GenTypes.StructEntry] = self.find_struct(name)
|
||||
if entry is None:
|
||||
return 0
|
||||
return entry.HasVTable
|
||||
@@ -1542,7 +1542,7 @@ class StructGenMixin:
|
||||
"""标记结构体为 NoVTable,返回 1=成功 / 0=失败"""
|
||||
if name is None:
|
||||
return 0
|
||||
entry: GenTypes.StructEntry | t.CPtr = self.find_struct(name)
|
||||
entry: rawptr[GenTypes.StructEntry] = self.find_struct(name)
|
||||
if entry is None:
|
||||
return 0
|
||||
entry.IsNoVTable = 1
|
||||
@@ -1552,7 +1552,7 @@ class StructGenMixin:
|
||||
"""按类名检查是否为 NoVTable,返回 1=是 / 0=否"""
|
||||
if name is None:
|
||||
return 0
|
||||
entry: GenTypes.StructEntry | t.CPtr = self.find_struct(name)
|
||||
entry: rawptr[GenTypes.StructEntry] = self.find_struct(name)
|
||||
if entry is None:
|
||||
return 0
|
||||
return entry.IsNoVTable
|
||||
@@ -1561,7 +1561,7 @@ class StructGenMixin:
|
||||
"""设置结构体的父类名,返回 1=成功 / 0=失败"""
|
||||
if name is None:
|
||||
return 0
|
||||
entry: GenTypes.StructEntry | t.CPtr = self.find_struct(name)
|
||||
entry: rawptr[GenTypes.StructEntry] = self.find_struct(name)
|
||||
if entry is None:
|
||||
return 0
|
||||
entry.ParentName = parent_name
|
||||
@@ -1573,7 +1573,7 @@ class StructGenMixin:
|
||||
"""设置结构体的父类名数组(永久池深拷贝,跨文件永久存活)"""
|
||||
if name is None:
|
||||
return 0
|
||||
entry: GenTypes.StructEntry | t.CPtr = self.find_struct(name)
|
||||
entry: rawptr[GenTypes.StructEntry] = self.find_struct(name)
|
||||
if entry is None:
|
||||
return 0
|
||||
if names_ptr is None or count <= 0:
|
||||
@@ -1609,7 +1609,7 @@ class StructGenMixin:
|
||||
"""获取父类数量(0=无父类,1=单继承,>1=多继承)"""
|
||||
if name is None:
|
||||
return 0
|
||||
entry: GenTypes.StructEntry | t.CPtr = self.find_struct(name)
|
||||
entry: rawptr[GenTypes.StructEntry] = self.find_struct(name)
|
||||
if entry is None:
|
||||
return 0
|
||||
return entry.ParentCount
|
||||
@@ -1618,7 +1618,7 @@ class StructGenMixin:
|
||||
"""获取第 idx 个父类名,越界返回 None"""
|
||||
if name is None or idx < 0:
|
||||
return None
|
||||
entry: GenTypes.StructEntry | t.CPtr = self.find_struct(name)
|
||||
entry: rawptr[GenTypes.StructEntry] = self.find_struct(name)
|
||||
if entry is None or entry.ParentNames is None:
|
||||
return None
|
||||
if idx >= entry.ParentCount:
|
||||
@@ -1674,7 +1674,7 @@ class StructGenMixin:
|
||||
visited[visit_count] = sizet(cur)
|
||||
visit_count += 1
|
||||
# 父类逆序压栈(正向 range 计算逆序索引,保证声明顺序弹出)
|
||||
entry: GenTypes.StructEntry | t.CPtr = self.find_struct(cur)
|
||||
entry: rawptr[GenTypes.StructEntry] = self.find_struct(cur)
|
||||
if entry is not None and entry.ParentCount > 0 and entry.ParentNames is not None:
|
||||
pc: int = entry.ParentCount
|
||||
parr: sizet | t.CPtr = (sizet | t.CPtr)(entry.ParentNames)
|
||||
@@ -1691,7 +1691,7 @@ class StructGenMixin:
|
||||
"""获取结构体的父类名,返回 None=无父类"""
|
||||
if name is None:
|
||||
return None
|
||||
entry: GenTypes.StructEntry | t.CPtr = self.find_struct(name)
|
||||
entry: rawptr[GenTypes.StructEntry] = self.find_struct(name)
|
||||
if entry is None:
|
||||
return None
|
||||
return entry.ParentName
|
||||
@@ -1700,7 +1700,7 @@ class StructGenMixin:
|
||||
"""设置虚表方法名数组,返回 1=成功 / 0=失败"""
|
||||
if name is None:
|
||||
return 0
|
||||
entry: GenTypes.StructEntry | t.CPtr = self.find_struct(name)
|
||||
entry: rawptr[GenTypes.StructEntry] = self.find_struct(name)
|
||||
if entry is None:
|
||||
return 0
|
||||
entry.VTableMethods = methods
|
||||
@@ -1711,7 +1711,7 @@ class StructGenMixin:
|
||||
"""获取方法在虚表中的索引,返回 -1=未找到"""
|
||||
if name is None or method_name is None:
|
||||
return -1
|
||||
entry: GenTypes.StructEntry | t.CPtr = self.find_struct(name)
|
||||
entry: rawptr[GenTypes.StructEntry] = self.find_struct(name)
|
||||
if entry is None or entry.VTableMethods is None:
|
||||
return -1
|
||||
# VTableMethods 字段声明为 char*,但实际存储的是 sizet 数组
|
||||
@@ -1730,7 +1730,7 @@ class StructGenMixin:
|
||||
"""获取虚表方法数量"""
|
||||
if name is None:
|
||||
return 0
|
||||
entry: GenTypes.StructEntry | t.CPtr = self.find_struct(name)
|
||||
entry: rawptr[GenTypes.StructEntry] = self.find_struct(name)
|
||||
if entry is None:
|
||||
return 0
|
||||
return entry.VTableMethodCount
|
||||
@@ -1739,7 +1739,7 @@ class StructGenMixin:
|
||||
"""获取虚表中第 idx 个方法名,返回 None=越界"""
|
||||
if name is None or idx < 0:
|
||||
return None
|
||||
entry: GenTypes.StructEntry | t.CPtr = self.find_struct(name)
|
||||
entry: rawptr[GenTypes.StructEntry] = self.find_struct(name)
|
||||
if entry is None or entry.VTableMethods is None:
|
||||
return None
|
||||
if idx >= entry.VTableMethodCount:
|
||||
@@ -1754,7 +1754,7 @@ class StructGenMixin:
|
||||
"""获取结构体字段数量,返回 -1=未找到"""
|
||||
if name is None:
|
||||
return -1
|
||||
entry: GenTypes.StructEntry | t.CPtr = self.find_struct(name)
|
||||
entry: rawptr[GenTypes.StructEntry] = self.find_struct(name)
|
||||
if entry is None:
|
||||
return -1
|
||||
return entry.FieldCount
|
||||
@@ -1811,7 +1811,7 @@ class StructGenMixin:
|
||||
string.strncpy(sha1_buf, sname, sha1_cp)
|
||||
sha1_buf[sha1_cp] = '\0'
|
||||
# 按类名 + SHA1 查找结构体定义
|
||||
entry: GenTypes.StructEntry | t.CPtr = self.find_struct_by_module(class_name, sha1_buf)
|
||||
entry: rawptr[GenTypes.StructEntry] = self.find_struct_by_module(class_name, sha1_buf)
|
||||
if entry is None:
|
||||
# 回退到按类名查找(可能找到不同模块的同名类,但总比没有好)
|
||||
entry = self.find_struct(class_name)
|
||||
@@ -1841,7 +1841,7 @@ class StructGenMixin:
|
||||
case llvmlite.LLVMType.Struct(fields, fcount, sname):
|
||||
# 遍历字段链表
|
||||
if fields is not None:
|
||||
fld: rawptr[llvmlite.Function] = fields
|
||||
fld: rawptr[llvmlite.ParamNode] = fields
|
||||
cnt_ef: int = 0
|
||||
while fld is not None:
|
||||
# 步数守卫:字段链表成环(内存损坏)导致无限遍历挂起
|
||||
@@ -1879,25 +1879,25 @@ class StructGenMixin:
|
||||
case _:
|
||||
pass
|
||||
|
||||
def get_field_name_ptr(self, fe: GenTypes.FieldEntry | t.CPtr) -> str:
|
||||
def get_field_name_ptr(self, fe: rawptr[GenTypes.FieldEntry]) -> str:
|
||||
"""获取 FieldEntry 的字段名,返回 None=未设置"""
|
||||
if fe is None:
|
||||
return None
|
||||
return fe.Name
|
||||
|
||||
def get_field_type_ptr(self, fe: GenTypes.FieldEntry | t.CPtr) -> rawptr[llvmlite.LLVMType]:
|
||||
def get_field_type_ptr(self, fe: rawptr[GenTypes.FieldEntry]) -> rawptr[llvmlite.LLVMType]:
|
||||
"""获取 FieldEntry 的字段类型,返回 None=未设置"""
|
||||
if fe is None:
|
||||
return None
|
||||
return fe.Ty
|
||||
|
||||
def get_field_default_ptr(self, fe: GenTypes.FieldEntry | t.CPtr) -> rawptr[ast.AST]:
|
||||
def get_field_default_ptr(self, fe: rawptr[GenTypes.FieldEntry]) -> rawptr[ast.AST]:
|
||||
"""获取 FieldEntry 的默认值 AST 节点,返回 None=无默认值"""
|
||||
if fe is None:
|
||||
return None
|
||||
return fe.DefaultVal
|
||||
|
||||
def get_field_annot_class_name(self, fe: GenTypes.FieldEntry | t.CPtr) -> str:
|
||||
def get_field_annot_class_name(self, fe: rawptr[GenTypes.FieldEntry]) -> str:
|
||||
"""获取 FieldEntry 的原始类型注解类名(Spec.SourceName),返回 None=未设置
|
||||
|
||||
[S4] 原 FieldEntry.AnnotClassName 字段已删除,注解名承载在 Spec.SourceName
|
||||
|
||||
@@ -92,12 +92,12 @@ class Translator:
|
||||
_coro_frames: str
|
||||
_coro_frame_count: int
|
||||
# resume_<name> 翻译上下文(AsyncGenMixin 段翻译共享)
|
||||
_coro_state_ptr: llvmlite.Value | t.CPtr
|
||||
_coro_done_ptr: llvmlite.Value | t.CPtr
|
||||
_coro_ret_ptr: llvmlite.Value | t.CPtr
|
||||
_coro_exit_bb: llvmlite.BasicBlock | t.CPtr
|
||||
_coro_await_slot: llvmlite.Value | t.CPtr
|
||||
_coro_frame: llvmlite.Value | t.CPtr
|
||||
_coro_state_ptr: rawptr[llvmlite.Value]
|
||||
_coro_done_ptr: rawptr[llvmlite.Value]
|
||||
_coro_ret_ptr: rawptr[llvmlite.Value]
|
||||
_coro_exit_bb: rawptr[llvmlite.BasicBlock]
|
||||
_coro_await_slot: rawptr[llvmlite.Value]
|
||||
_coro_frame: rawptr[llvmlite.Value]
|
||||
_coro_next_state: int
|
||||
_coro_nseg: int
|
||||
# M2:async 参数表(char* 数组,8 字节/项)+ 预扫描计数
|
||||
@@ -107,13 +107,13 @@ class Translator:
|
||||
_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_break_bb: rawptr[llvmlite.BasicBlock] # While break 目标(M2 单层)
|
||||
_coro_continue_bb: rawptr[llvmlite.BasicBlock] # While continue 目标
|
||||
_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_exc_ptr: rawptr[llvmlite.Value] # 帧 exc 槽(i32,M4)
|
||||
_coro_msg_ptr: rawptr[llvmlite.Value] # 帧 msg 槽(i8*,M7)
|
||||
_coro_wake_ptr: rawptr[llvmlite.Value] # 帧 wake 槽(i64,M3 coro_sleep)
|
||||
_coro_try_stack: sizet | t.CPtr # try 栈:except/finally 块指针数组(8B/项)
|
||||
_coro_try_stack_count: int
|
||||
_coro_for_counter: int # range-For 编号(M3,翻译期递增)
|
||||
@@ -134,7 +134,7 @@ class Translator:
|
||||
|
||||
# 当前翻译上下文
|
||||
_cur_func: rawptr[llvmlite.Function]
|
||||
_cur_builder: llvmlite.IRBuilder | t.CPtr
|
||||
_cur_builder: rawptr[llvmlite.IRBuilder]
|
||||
|
||||
# 当前赋值语句的注解节点(AnnAssign 翻译 rhs 前设置,Assign 翻译前清空)。
|
||||
# 供 c.Deref(i8*) 推断读取宽度:v: int = c.Deref(p) → bitcast i32* load
|
||||
@@ -160,8 +160,8 @@ class Translator:
|
||||
CurRetNode: rawptr[ast.AST]
|
||||
|
||||
# 循环控制流目标(break/continue)
|
||||
_break_bb: llvmlite.BasicBlock | t.CPtr
|
||||
_continue_bb: llvmlite.BasicBlock | t.CPtr
|
||||
_break_bb: rawptr[llvmlite.BasicBlock]
|
||||
_continue_bb: rawptr[llvmlite.BasicBlock]
|
||||
|
||||
# 独立标签计数器(不与 builder.Counter 共享,避免 SSA 编号非单调)
|
||||
_label_counter: int
|
||||
@@ -195,7 +195,7 @@ class Translator:
|
||||
|
||||
# *args 变长参数支持:当前函数的 va_list 指针(i8* alloca)
|
||||
# 仅当函数声明了 *args 时设置,供 arg(type) 糖函数使用
|
||||
_va_list_ptr: llvmlite.Value | t.CPtr
|
||||
_va_list_ptr: rawptr[llvmlite.Value]
|
||||
# *args 参数名(如 "args"),用于符号表注册
|
||||
_vararg_name: str
|
||||
|
||||
@@ -203,19 +203,19 @@ class Translator:
|
||||
# _translate_method 注入 __stop_iter_flag__ 参数时设置;translate_raise
|
||||
# 检测 raise StopIteration 时对该指针 store 1(对齐 TPC HandlesRaise.py)。
|
||||
# 非 __next__ 函数中为 None。
|
||||
_stop_iter_flag_ptr: llvmlite.Value | t.CPtr
|
||||
_stop_iter_flag_ptr: rawptr[llvmlite.Value]
|
||||
|
||||
# try-except 机制(对齐 TPC HandlesTry.py):当前最内层 try 的
|
||||
# 分发块 + 异常编码/消息 alloca。translate_try 设置,translate_raise
|
||||
# 与调用侧 EH 检测写入/跳转。try 外为 None。
|
||||
_eh_dispatch_bb: llvmlite.BasicBlock | t.CPtr
|
||||
_eh_code_ptr: llvmlite.Value | t.CPtr
|
||||
_eh_msg_ptr: llvmlite.Value | t.CPtr
|
||||
_eh_dispatch_bb: rawptr[llvmlite.BasicBlock]
|
||||
_eh_code_ptr: rawptr[llvmlite.Value]
|
||||
_eh_msg_ptr: rawptr[llvmlite.Value]
|
||||
# 当前函数的 __eh_msg_out__(i8**)/__eh_code_out__(i32*)输出参数
|
||||
# (函数签名含 raise 时由 translate_function_def/_translate_method 注入)。
|
||||
# 无 EH 参数时 _cur_func_has_eh == 0。
|
||||
_eh_msg_out_param: llvmlite.Value | t.CPtr
|
||||
_eh_code_out_param: llvmlite.Value | t.CPtr
|
||||
_eh_msg_out_param: rawptr[llvmlite.Value]
|
||||
_eh_code_out_param: rawptr[llvmlite.Value]
|
||||
_cur_func_has_eh: int
|
||||
|
||||
# 模块 SHA1 前缀(16 字符),用于函数名混淆(SHA1 命名空间)
|
||||
@@ -252,7 +252,7 @@ class Translator:
|
||||
_declare_only: int
|
||||
|
||||
# 嵌套作用域符号表
|
||||
SymTab: GenTypes.SymbolTable | t.CPtr
|
||||
SymTab: rawptr[GenTypes.SymbolTable]
|
||||
|
||||
def __init__(self):
|
||||
self.Module = None
|
||||
@@ -475,7 +475,7 @@ class Translator:
|
||||
|
||||
# 检查用户是否定义了 main 函数
|
||||
has_user_main: int = 0
|
||||
ch: list[rawptr[ast.AST]] | t.CPtr = tree.children
|
||||
ch: rawptr[list[rawptr[ast.AST]]] = tree.children
|
||||
if ch is not None:
|
||||
cn_count: sizet = len(ch)
|
||||
for ci in range(cn_count):
|
||||
@@ -523,7 +523,7 @@ class Translator:
|
||||
# (前向声明需要解析类型注解,如 t.CArray[str] 依赖 t 模块已导入)
|
||||
# 记录最后处理的 import 行号,供 vpi 注入错误上下文帧定位
|
||||
cur_imp_lineno: int = 0
|
||||
ch: list[rawptr[ast.AST]] | t.CPtr = tree.children
|
||||
ch: rawptr[list[rawptr[ast.AST]]] = tree.children
|
||||
if ch is not None:
|
||||
cn_count: sizet = len(ch)
|
||||
for ci in range(cn_count):
|
||||
@@ -711,7 +711,7 @@ class Translator:
|
||||
if fd_s.args is not None:
|
||||
args_s: rawptr[ast.Arguments] = rawptr[ast.Arguments](fd_s.args)
|
||||
if args_s.args is not None:
|
||||
args_list_s: list[rawptr[ast.AST]] | t.CPtr = args_s.args
|
||||
args_list_s: rawptr[list[rawptr[ast.AST]]] = args_s.args
|
||||
an_s: sizet = len(args_list_s)
|
||||
ai_s: sizet
|
||||
for ai_s in range(an_s):
|
||||
@@ -729,7 +729,7 @@ class Translator:
|
||||
# translate_list_literal 阶段 fail-fast 提示 _list 未注册(需显式注解)。
|
||||
# 递归语句块子节点
|
||||
if node.children is not None:
|
||||
ch_s: list[rawptr[ast.AST]] | t.CPtr = node.children
|
||||
ch_s: rawptr[list[rawptr[ast.AST]]] = node.children
|
||||
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)
|
||||
|
||||
@@ -83,7 +83,7 @@ class TranslatorGenMixin:
|
||||
Returns:
|
||||
int: 新增的变量数
|
||||
"""
|
||||
ch: list[rawptr[ast.AST]] | t.CPtr = tree.children
|
||||
ch: rawptr[list[rawptr[ast.AST]]] = tree.children
|
||||
if ch is None:
|
||||
return 0
|
||||
|
||||
@@ -164,7 +164,7 @@ class TranslatorGenMixin:
|
||||
if fd.args is not None:
|
||||
ags: rawptr[ast.Arguments] = rawptr[ast.Arguments](fd.args)
|
||||
if ags.args is not None:
|
||||
al: list[rawptr[ast.AST]] | t.CPtr = ags.args
|
||||
al: rawptr[list[rawptr[ast.AST]]] = ags.args
|
||||
an: sizet = len(al)
|
||||
ai: sizet
|
||||
for ai in range(an):
|
||||
@@ -180,14 +180,14 @@ class TranslatorGenMixin:
|
||||
# ============================================================
|
||||
def _build_array_initializer_text(self, pool: rawptr[memhub.MemBuddy],
|
||||
var_ty: rawptr[llvmlite.LLVMType],
|
||||
list_node: ast.List | t.CPtr) -> str:
|
||||
list_node: rawptr[ast.List]) -> str:
|
||||
"""从 AST List 节点生成 LLVM IR 数组初始化器文本,None 失败"""
|
||||
if var_ty is None or list_node is None:
|
||||
return None
|
||||
|
||||
# 重新进行类型转换,确保 TPV 编译器正确识别 ast.List 类型
|
||||
# (避免 init_list_node 初始值为 None 时类型推断退化为 t.CPtr)
|
||||
ln: ast.List | t.CPtr = (ast.List | t.CPtr)(list_node)
|
||||
ln: rawptr[ast.List] = rawptr[ast.List](list_node)
|
||||
if ln is None:
|
||||
return None
|
||||
|
||||
@@ -220,7 +220,7 @@ class TranslatorGenMixin:
|
||||
is_int_elem = 0
|
||||
|
||||
# 获取列表元素(通过 ln.elts 而非 list_node.elts,确保类型正确识别)
|
||||
elts: list[rawptr[ast.AST]] | t.CPtr = ln.elts
|
||||
elts: rawptr[list[rawptr[ast.AST]]] = ln.elts
|
||||
if elts is None:
|
||||
return None
|
||||
elts_count: sizet = len(elts)
|
||||
@@ -271,11 +271,11 @@ class TranslatorGenMixin:
|
||||
ek_n: int = en_n.kind()
|
||||
if ek_n == ast.ASTKind.List:
|
||||
sub_n = self._build_array_initializer_text(
|
||||
pool, elem_ty, (ast.List | t.CPtr)(en_n))
|
||||
pool, elem_ty, rawptr[ast.List](en_n))
|
||||
elif ek_n == ast.ASTKind.Set:
|
||||
# 花括号行字面量(如点阵字库 {0x00, ...}):Set.elts
|
||||
# 与 List 同构,包装为临时 List 递归生成子数组文本
|
||||
se_n: ast.Set | t.CPtr = (ast.Set | t.CPtr)(en_n)
|
||||
se_n: rawptr[ast.Set] = rawptr[ast.Set](en_n)
|
||||
if se_n is not None and se_n.elts is not None:
|
||||
sub_n = self._build_array_initializer_text(
|
||||
pool, elem_ty, ast.List(pool, se_n.elts, ast.ASTCtx.Load))
|
||||
@@ -426,7 +426,7 @@ class TranslatorGenMixin:
|
||||
viperlib.snprintf(str_name_buf, 64, ".str.%s", var_name)
|
||||
|
||||
# 调用 llvmlite.create_global_string 创建字符串常量全局
|
||||
str_gv: llvmlite.GlobalVariable | t.CPtr = llvmlite.create_global_string(
|
||||
str_gv: rawptr[llvmlite.GlobalVariable] = llvmlite.create_global_string(
|
||||
pool, mod, str_name_buf, str_val)
|
||||
if str_gv is None:
|
||||
return None
|
||||
@@ -512,7 +512,7 @@ class TranslatorGenMixin:
|
||||
# - vtable 对象 storage:首元素为 vtable 指针,其后追加本函数结果(start_idx=1 跳过字段 0)。
|
||||
# 无任何非零默认值时返回 None,调用方据此保持原零值路径(避免无谓文本)。
|
||||
def _build_stg_struct_body_text(self, pool: rawptr[memhub.MemBuddy],
|
||||
se: GenTypes.StructEntry | t.CPtr,
|
||||
se: rawptr[GenTypes.StructEntry],
|
||||
start_idx: int) -> str:
|
||||
"""按字段默认值生成 "e0, e1, ..." 元素文本;无非零默认值返回 None"""
|
||||
if se is None or se.Fields is None:
|
||||
@@ -529,7 +529,7 @@ class TranslatorGenMixin:
|
||||
has_nonzero: int = 0
|
||||
i: int = start_idx
|
||||
while i < fc:
|
||||
fe: GenTypes.FieldEntry | t.CPtr = self.Gen.StructGen._get_field_entry(se, i)
|
||||
fe: rawptr[GenTypes.FieldEntry] = self.Gen.StructGen._get_field_entry(se, i)
|
||||
i += 1
|
||||
if fe is None or fe.Ty is None:
|
||||
continue
|
||||
@@ -562,7 +562,7 @@ class TranslatorGenMixin:
|
||||
# (LLVM 要求列全每个字段);不生成则字段默认值全丢。
|
||||
# 无任何非零默认值时返回 None,由调用方保持 zeroinitializer(避免无谓文本)。
|
||||
def _build_stg_struct_init_text(self, pool: rawptr[memhub.MemBuddy],
|
||||
se: GenTypes.StructEntry | t.CPtr,
|
||||
se: rawptr[GenTypes.StructEntry],
|
||||
start_idx: int) -> str:
|
||||
"""按字段默认值生成完整 struct 初始化器;无非零默认值返回 None"""
|
||||
body: str = self._build_stg_struct_body_text(pool, se, start_idx)
|
||||
@@ -621,12 +621,12 @@ class TranslatorGenMixin:
|
||||
var_name: str = None
|
||||
var_ty: rawptr[llvmlite.LLVMType] = llvmlite.Int32(pool)
|
||||
resolved_stg_ty: rawptr[llvmlite.LLVMType] = None # 对象类全局:静态 storage 类型(BSS 实例)
|
||||
resolved_stg_entry: GenTypes.StructEntry | t.CPtr = None # 对象类全局:对应 StructEntry(vtable 初始化用)
|
||||
resolved_stg_entry: rawptr[GenTypes.StructEntry] = None # 对象类全局:对应 StructEntry(vtable 初始化用)
|
||||
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
|
||||
init_list_node: ast.List | t.CPtr = None
|
||||
init_list_node: rawptr[ast.List] = None
|
||||
# = None 显式初始化(如 tokens.vp `_kw_head: KwEntry | t.CPtr = None`):
|
||||
# 对象类全局的懒初始化指针语义——必须保持 NULL,不能创建 BSS storage
|
||||
# (storage 会让 @g = &g.stg 恒非 NULL,破坏 `if _kw_head != None` 守卫,
|
||||
@@ -653,7 +653,7 @@ class TranslatorGenMixin:
|
||||
# 值实例,跨模块字段访问/虚表调用会按指针处理读首 8 字节当 vtable → 崩溃。
|
||||
# 纯 t.CStruct(无方法无虚表无 __new__)保持值实例。
|
||||
if resolved.kind() == llvmlite.LLVMType.Struct:
|
||||
gv_entry: GenTypes.StructEntry | t.CPtr = self.Gen.StructGen.find_struct_by_type(resolved)
|
||||
gv_entry: rawptr[GenTypes.StructEntry] = self.Gen.StructGen.find_struct_by_type(resolved)
|
||||
if gv_entry is not None \
|
||||
and (gv_entry.HasNew != 0 or gv_entry.HasVTable != 0 or gv_entry.IsOOP != 0):
|
||||
# 对象类全局(裸类名注解 → 对象即指针):记录原 Struct 值类型,
|
||||
@@ -668,7 +668,7 @@ class TranslatorGenMixin:
|
||||
# var_ty 保持 Ptr(联合注解语义:指针全局),storage 承载对象实例。
|
||||
pointee_uv: rawptr[llvmlite.LLVMType] = resolved.Pointee
|
||||
if pointee_uv is not None and pointee_uv.kind() == llvmlite.LLVMType.Struct:
|
||||
gv_entry_u: GenTypes.StructEntry | t.CPtr = self.Gen.StructGen.find_struct_by_type(pointee_uv)
|
||||
gv_entry_u: rawptr[GenTypes.StructEntry] = self.Gen.StructGen.find_struct_by_type(pointee_uv)
|
||||
if gv_entry_u is not None \
|
||||
and (gv_entry_u.HasNew != 0 or gv_entry_u.HasVTable != 0 or gv_entry_u.IsOOP != 0):
|
||||
resolved_stg_ty = pointee_uv
|
||||
@@ -705,13 +705,13 @@ class TranslatorGenMixin:
|
||||
init_val = self.Gen.AssignGen.extract_cdefine_int_value(aa.value)
|
||||
init_kind = 1
|
||||
elif val_kind == ast.ASTKind.List:
|
||||
init_list_node = (ast.List | t.CPtr)(aa.value)
|
||||
init_list_node = rawptr[ast.List](aa.value)
|
||||
init_kind = 2
|
||||
elif k == ast.ASTKind.Assign:
|
||||
asgn: rawptr[ast.Assign] = rawptr[ast.Assign](node)
|
||||
if asgn is None or asgn.targets is None:
|
||||
return 0
|
||||
targets: list[rawptr[ast.AST]] | t.CPtr = asgn.targets
|
||||
targets: rawptr[list[rawptr[ast.AST]]] = asgn.targets
|
||||
if len(targets) < 1:
|
||||
return 0
|
||||
t0: rawptr[ast.AST] = targets.get(0)
|
||||
@@ -741,7 +741,7 @@ class TranslatorGenMixin:
|
||||
init_val = self.Gen.AssignGen.extract_cdefine_int_value(asgn.value)
|
||||
init_kind = 1
|
||||
elif val_kind2 == ast.ASTKind.List:
|
||||
init_list_node = (ast.List | t.CPtr)(asgn.value)
|
||||
init_list_node = rawptr[ast.List](asgn.value)
|
||||
init_kind = 2
|
||||
elif val_kind2 == ast.ASTKind.Attribute:
|
||||
# 模块级 re-export 别名(如 fat32_core.vp `_read32 = types._read32`):
|
||||
@@ -786,7 +786,7 @@ class TranslatorGenMixin:
|
||||
return 0
|
||||
|
||||
# 检查是否已注册
|
||||
existing: llvmlite.Value | t.CPtr = self.Gen.VarGen.lookup_module_var(
|
||||
existing: rawptr[llvmlite.Value] = self.Gen.VarGen.lookup_module_var(
|
||||
trans.SymTab, var_name)
|
||||
if existing is not None:
|
||||
return 0
|
||||
@@ -795,7 +795,7 @@ class TranslatorGenMixin:
|
||||
# 先确保 var_ty 中的跨模块结构体类型在模块中有 opaque 声明
|
||||
# 否则 @var_name = global %"sha1.ClassName"* zeroinitializer 会报
|
||||
# "use of undefined type named 'sha1.ClassName'" 错误
|
||||
# (如 _mbuddy: memhub.MemManager | t.CPtr → Ptr(Struct("aeb3...MemManager")))
|
||||
# (如 _mbuddy: rawptr[memhub.MemManager] → Ptr(Struct("aeb3...MemManager")))
|
||||
llvmlite.module_ensure_opaque_for_type(mod, pool, var_ty)
|
||||
# 模块级全局命名带 SHA1 前缀(对齐函数名 mangling):多个模块声明同名
|
||||
# 全局(如 _mbuddy)时各自独立命名,消除 ld.lld duplicate symbol。
|
||||
@@ -810,7 +810,7 @@ class TranslatorGenMixin:
|
||||
mangled_name: str = var_name
|
||||
if is_global_cexport == 0:
|
||||
mangled_name = self.Gen.FuncGenBase._mangle_name(trans, var_name)
|
||||
gv: llvmlite.GlobalVariable | t.CPtr = llvmlite.new_global_variable(pool, mangled_name, var_ty)
|
||||
gv: rawptr[llvmlite.GlobalVariable] = llvmlite.new_global_variable(pool, mangled_name, var_ty)
|
||||
if gv is None:
|
||||
return 0
|
||||
llvmlite.module_add_global(mod, gv)
|
||||
@@ -823,7 +823,7 @@ class TranslatorGenMixin:
|
||||
al_ty = pointee_al
|
||||
case _:
|
||||
pass
|
||||
al_entry: GenTypes.StructEntry | t.CPtr = None
|
||||
al_entry: rawptr[GenTypes.StructEntry] = None
|
||||
if al_ty is not None and al_ty.kind() == llvmlite.LLVMType.Struct:
|
||||
al_entry = self.Gen.StructGen.find_struct_by_type(al_ty)
|
||||
if al_entry is not None and al_entry.Align > 0:
|
||||
@@ -876,7 +876,7 @@ class TranslatorGenMixin:
|
||||
# 浮点初始值:LLVM IR 的浮点常量必须写成位模式文本(0x%016llx / 0x%08x)——
|
||||
# 十进制文本经 llc 解析对部分值有 ±1 ulp 误差(见 llvmlite.ConstFloat 注释)。
|
||||
# 浮点分支缺失时模块级 t.CDouble 全局会退化成 zeroinitializer(值全变 0)。
|
||||
fc_g: llvmlite.Value | t.CPtr = llvmlite.ConstFloat(pool, var_ty, init_fval)
|
||||
fc_g: rawptr[llvmlite.Value] = llvmlite.ConstFloat(pool, var_ty, init_fval)
|
||||
if fc_g is not None and fc_g.Name is not None:
|
||||
gv.Initializer = fc_g.Name
|
||||
else:
|
||||
@@ -946,7 +946,7 @@ class TranslatorGenMixin:
|
||||
else:
|
||||
fc_v: int = resolved_stg_entry.FieldCount
|
||||
for fi_v in range(1, fc_v):
|
||||
fe_v: GenTypes.FieldEntry | t.CPtr = self.Gen.StructGen._get_field_entry(
|
||||
fe_v: rawptr[GenTypes.FieldEntry] = self.Gen.StructGen._get_field_entry(
|
||||
resolved_stg_entry, fi_v)
|
||||
if fe_v is None or fe_v.Ty is None:
|
||||
continue
|
||||
@@ -973,7 +973,7 @@ class TranslatorGenMixin:
|
||||
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)
|
||||
stg_gv: llvmlite.GlobalVariable | t.CPtr = llvmlite.new_global_variable(
|
||||
stg_gv: rawptr[llvmlite.GlobalVariable] = llvmlite.new_global_variable(
|
||||
pool, stg_name_buf, resolved_stg_ty)
|
||||
if stg_gv is not None:
|
||||
llvmlite.module_add_global(mod, stg_gv)
|
||||
@@ -993,7 +993,7 @@ class TranslatorGenMixin:
|
||||
gv.Initializer = stg_init_buf
|
||||
# 注册 storage 引用(key: var_name.__stg),供 AssignGenMixin
|
||||
# 全局赋值分支检测对象类全局并复制对象到 storage。
|
||||
stg_ref: llvmlite.Value | t.CPtr = self.Gen.ExprGenAttr.make_global_ref(
|
||||
stg_ref: rawptr[llvmlite.Value] = self.Gen.ExprGenAttr.make_global_ref(
|
||||
pool, stg_name_buf, resolved_stg_ty)
|
||||
if stg_ref is not None:
|
||||
stg_key_len: sizet = sizet(string.strlen(var_name)) + 8
|
||||
@@ -1011,7 +1011,7 @@ class TranslatorGenMixin:
|
||||
viperlib.snprintf(ref_name, 96, "@\"%s\"", mangled_name)
|
||||
else:
|
||||
viperlib.snprintf(ref_name, 96, "@%s", mangled_name)
|
||||
gv_ref: llvmlite.Value | t.CPtr = llvmlite.SSAValue(pool, var_ptr_ty, ref_name)
|
||||
gv_ref: rawptr[llvmlite.Value] = llvmlite.SSAValue(pool, var_ptr_ty, ref_name)
|
||||
|
||||
# 注册到模块作用域
|
||||
if self.Gen.VarGen.define_module_var(trans.SymTab, var_name, gv_ref) == 0:
|
||||
@@ -1070,13 +1070,13 @@ class TranslatorGenMixin:
|
||||
VLogger.error("CreateFunction main returned NULL", "TR")
|
||||
return 0
|
||||
|
||||
entry_blk: llvmlite.BasicBlock | t.CPtr = llvmlite.create_block(
|
||||
entry_blk: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(
|
||||
pool, main_func, "entry")
|
||||
if entry_blk is None:
|
||||
VLogger.error("CreateBlock returned NULL", "TR")
|
||||
return 0
|
||||
|
||||
builder: llvmlite.IRBuilder | t.CPtr = llvmlite.new_builder(pool, main_func)
|
||||
builder: rawptr[llvmlite.IRBuilder] = llvmlite.new_builder(pool, main_func)
|
||||
if builder is None:
|
||||
VLogger.error("NewBuilder returned NULL", "TR")
|
||||
return 0
|
||||
@@ -1089,7 +1089,7 @@ class TranslatorGenMixin:
|
||||
# 预处理模块级变量:为 AnnAssign/Assign 创建 LLVM 全局变量
|
||||
# 必须在 pre_scan_allocas 之前执行,否则 PreScan 会创建局部 alloca,
|
||||
# 导致其他函数通过 SSA 编号引用 wrapper main 的局部变量(无效 IR)
|
||||
ch: list[rawptr[ast.AST]] | t.CPtr = tree.children
|
||||
ch: rawptr[list[rawptr[ast.AST]]] = tree.children
|
||||
if ch is not None:
|
||||
cn_count: sizet = len(ch)
|
||||
for ci in range(cn_count):
|
||||
@@ -1111,7 +1111,7 @@ class TranslatorGenMixin:
|
||||
added_total: int = self.translate_children(trans, tree)
|
||||
|
||||
# 返回 0
|
||||
zero_val: llvmlite.Value | t.CPtr = llvmlite.const_int32(pool, 0)
|
||||
zero_val: rawptr[llvmlite.Value] = llvmlite.const_int32(pool, 0)
|
||||
llvmlite.build_ret(builder, zero_val)
|
||||
|
||||
return added_total
|
||||
|
||||
@@ -33,7 +33,7 @@ class TypeGenBase:
|
||||
|
||||
# --- 仿 Python Traceback 调用栈(原 _g_trace_frames/_g_trace_count) ---
|
||||
Gen: rawptr[Generator.Generator]
|
||||
TraceFrames: GenTypes.TraceFrame | t.CPtr # malloc 数组(TypeGenMixin.TRACE_MAX 槽)
|
||||
TraceFrames: rawptr[GenTypes.TraceFrame] # malloc 数组(TypeGenMixin.TRACE_MAX 槽)
|
||||
TraceCount: int
|
||||
|
||||
# --- 全局泛型特化上下文(原 _g_generic_tp_names/_g_generic_type_args) ---
|
||||
@@ -113,8 +113,8 @@ class TypeGenBase:
|
||||
# LibTypedefTypeMap: key="模块名|typedef 名" → 源中原始类型表达式。
|
||||
# 每次查询都读 64KB 库源全文扫描会使单文件 translate 耗时 7–12s;库源单次编译内
|
||||
# 不变,故缓存命中结果与逐次读源等价。
|
||||
LibTypedefScannedMods: hashtable.HashTable | t.CPtr
|
||||
LibTypedefTypeMap: hashtable.HashTable | t.CPtr
|
||||
LibTypedefScannedMods: rawptr[hashtable.HashTable]
|
||||
LibTypedefTypeMap: rawptr[hashtable.HashTable]
|
||||
|
||||
# --- 常量整数表达式计算成功标志(原 _g_const_eval_ok) ---
|
||||
ConstEvalOk: int
|
||||
@@ -125,7 +125,7 @@ class TypeGenBase:
|
||||
# --- TypeSpec 驻留表(统一类型描述符,Debugger/_Type.md 第 6 节) ---
|
||||
# 惰性创建(ensure_spec_arena);由类型子系统自身持有,避免模块级全局表。
|
||||
# 实例与内部数组均 PermPool 分配 ⇒ 跨文件/跨 mark 存活。
|
||||
Specs: TSpec.TypeSpecArena | t.CPtr
|
||||
Specs: rawptr[TSpec.TypeSpecArena]
|
||||
def InitTypeGen(self) -> int:
|
||||
"""初始化类型 Mixin 字段(子类构造时内联调用,规避 NoVTable 继承符号不转发)"""
|
||||
if self is None:
|
||||
@@ -179,12 +179,12 @@ class TypeGenBase:
|
||||
# 用 PermPool 分配 arena 本体;表内部缓冲由 TSpec.SpecArenaInit 分配
|
||||
# (同样 PermPool)。失败返回 None(调用方按 fail-fast 处理,不静默退化)。
|
||||
# ============================================================
|
||||
def ensure_spec_arena(self) -> TSpec.TypeSpecArena | t.CPtr:
|
||||
def ensure_spec_arena(self) -> rawptr[TSpec.TypeSpecArena]:
|
||||
"""确保 TypeSpec 驻留表已创建,返回 arena;失败返回 None"""
|
||||
if self.Specs is not None:
|
||||
return self.Specs
|
||||
size: sizet = TSpec.TypeSpecArena.__sizeof__()
|
||||
arena: TSpec.TypeSpecArena | t.CPtr = (TSpec.TypeSpecArena | t.CPtr)(CompilerFactory.factory.PermPool.alloc(size))
|
||||
arena: rawptr[TSpec.TypeSpecArena] = rawptr[TSpec.TypeSpecArena](CompilerFactory.factory.PermPool.alloc(size))
|
||||
if arena is None:
|
||||
return None
|
||||
string.memset(arena, 0, size)
|
||||
@@ -207,20 +207,20 @@ class TypeGenBase:
|
||||
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:
|
||||
def _get_trace_frame(self, i: int) -> rawptr[GenTypes.TraceFrame]:
|
||||
"""获取第 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)(addr)
|
||||
return rawptr[GenTypes.TraceFrame](addr)
|
||||
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)
|
||||
frame: rawptr[GenTypes.TraceFrame] = self._get_trace_frame(self.TraceCount)
|
||||
if frame is None:
|
||||
return
|
||||
frame.file_name = file_name
|
||||
@@ -233,7 +233,7 @@ class TypeGenBase:
|
||||
if self.TraceCount <= 0:
|
||||
return
|
||||
self.TraceCount -= 1
|
||||
frame: GenTypes.TraceFrame | t.CPtr = self._get_trace_frame(self.TraceCount)
|
||||
frame: rawptr[GenTypes.TraceFrame] = self._get_trace_frame(self.TraceCount)
|
||||
if frame is not None:
|
||||
frame.file_name = None
|
||||
frame.lineno = 0
|
||||
@@ -243,7 +243,7 @@ class TypeGenBase:
|
||||
"""清空调用栈(每个文件翻译开始前调用)"""
|
||||
i: int
|
||||
for i in range(self.TraceCount):
|
||||
frame: GenTypes.TraceFrame | t.CPtr = self._get_trace_frame(i)
|
||||
frame: rawptr[GenTypes.TraceFrame] = self._get_trace_frame(i)
|
||||
if frame is not None:
|
||||
frame.file_name = None
|
||||
frame.lineno = 0
|
||||
|
||||
@@ -499,7 +499,7 @@ class TypeGenCType(TypeGenBase.TypeGenBase):
|
||||
"""
|
||||
if pool is None or tree is None:
|
||||
return 0
|
||||
ch: list[rawptr[ast.AST]] | t.CPtr = tree.children
|
||||
ch: rawptr[list[rawptr[ast.AST]]] = tree.children
|
||||
if ch is None:
|
||||
return 0
|
||||
n: sizet = len(ch)
|
||||
|
||||
@@ -116,7 +116,7 @@ class TypeGenErr(TypeGenBase.TypeGenBase):
|
||||
# 输出调用栈帧(从底到顶)
|
||||
i: int
|
||||
for i in range(self.Gen.TypeGenBase.TraceCount):
|
||||
frame: GenTypes.TraceFrame | t.CPtr = self.Gen.TypeGenBase._get_trace_frame(i)
|
||||
frame: rawptr[GenTypes.TraceFrame] = self.Gen.TypeGenBase._get_trace_frame(i)
|
||||
if frame is not None and frame.file_name is not None:
|
||||
if frame.lineno > 0:
|
||||
stdio.printf(' File "%s", line %d\n', frame.file_name, frame.lineno)
|
||||
@@ -139,7 +139,7 @@ class TypeGenErr(TypeGenBase.TypeGenBase):
|
||||
if lineno <= 0 and self.Gen.TypeGenBase.TraceCount > 0:
|
||||
ti_b: int = self.Gen.TypeGenBase.TraceCount - 1
|
||||
while ti_b >= 0:
|
||||
tfb: GenTypes.TraceFrame | t.CPtr = self.Gen.TypeGenBase._get_trace_frame(ti_b)
|
||||
tfb: rawptr[GenTypes.TraceFrame] = self.Gen.TypeGenBase._get_trace_frame(ti_b)
|
||||
if tfb is not None and tfb.file_name is not None and tfb.lineno > 0:
|
||||
file_name = tfb.file_name
|
||||
lineno = tfb.lineno
|
||||
@@ -241,7 +241,7 @@ class TypeGenErr(TypeGenBase.TypeGenBase):
|
||||
return 0
|
||||
|
||||
return 0
|
||||
def is_pass_body(self, body: list[rawptr[ast.AST]] | t.CPtr) -> int:
|
||||
def is_pass_body(self, body: rawptr[list[rawptr[ast.AST]]]) -> int:
|
||||
"""检测函数体是否为 pass(空体或仅含 pass 语句)"""
|
||||
if body is None:
|
||||
return 1
|
||||
@@ -319,7 +319,7 @@ class TypeGenErr(TypeGenBase.TypeGenBase):
|
||||
|
||||
return llvmlite.Int32(pool)
|
||||
def infer_return_type(self, pool: rawptr[memhub.MemBuddy],
|
||||
body: list[rawptr[ast.AST]] | t.CPtr,
|
||||
body: rawptr[list[rawptr[ast.AST]]],
|
||||
param_types: str) -> rawptr[llvmlite.LLVMType]:
|
||||
"""扫描函数体中的 return 语句,推断返回类型"""
|
||||
if body is None:
|
||||
@@ -330,7 +330,7 @@ class TypeGenErr(TypeGenBase.TypeGenBase):
|
||||
for bi in range(bn):
|
||||
stmt: rawptr[ast.AST] = body.get(bi)
|
||||
if stmt is not None and stmt.kind() == ast.ASTKind.Return:
|
||||
rt: ast.Return | t.CPtr = (ast.Return | t.CPtr)(stmt)
|
||||
rt: rawptr[ast.Return] = rawptr[ast.Return](stmt)
|
||||
if rt.value is not None:
|
||||
expr_ty: rawptr[llvmlite.LLVMType] = self.infer_expr_type(
|
||||
pool, rt.value, param_types)
|
||||
@@ -341,7 +341,7 @@ class TypeGenErr(TypeGenBase.TypeGenBase):
|
||||
ret_ty = expr_ty
|
||||
return ret_ty
|
||||
def body_has_value_return(self, pool: rawptr[memhub.MemBuddy],
|
||||
body: list[rawptr[ast.AST]] | t.CPtr) -> int:
|
||||
body: rawptr[list[rawptr[ast.AST]]]) -> int:
|
||||
"""扫描函数体,判断是否存在返回非 None 值的 return
|
||||
|
||||
递归检查控制流语句(if/while/for/try/with/match)内层 return,但跳过
|
||||
@@ -360,7 +360,7 @@ class TypeGenErr(TypeGenBase.TypeGenBase):
|
||||
continue
|
||||
k: int = stmt.kind()
|
||||
if k == ast.ASTKind.Return:
|
||||
rt: ast.Return | t.CPtr = (ast.Return | t.CPtr)(stmt)
|
||||
rt: rawptr[ast.Return] = rawptr[ast.Return](stmt)
|
||||
if rt.value is not None:
|
||||
# return None(CONST_NONE)不算返回非 None 值
|
||||
if rt.value.kind() == ast.ASTKind.Constant:
|
||||
@@ -373,7 +373,7 @@ class TypeGenErr(TypeGenBase.TypeGenBase):
|
||||
elif k == ast.ASTKind.If or k == ast.ASTKind.While or \
|
||||
k == ast.ASTKind.For or k == ast.ASTKind.Try or \
|
||||
k == ast.ASTKind.With or k == ast.ASTKind.Match:
|
||||
sub: list[rawptr[ast.AST]] | t.CPtr = stmt.children
|
||||
sub: rawptr[list[rawptr[ast.AST]]] = stmt.children
|
||||
if sub is not None and len(sub) > 0:
|
||||
if self.body_has_value_return(pool, sub) != 0:
|
||||
return 1
|
||||
@@ -395,7 +395,7 @@ class TypeGenErr(TypeGenBase.TypeGenBase):
|
||||
ags: rawptr[ast.Arguments] = rawptr[ast.Arguments](args_node)
|
||||
if ags.args is None:
|
||||
return None
|
||||
alist: list[rawptr[ast.AST]] | t.CPtr = ags.args
|
||||
alist: rawptr[list[rawptr[ast.AST]]] = ags.args
|
||||
an: sizet = len(alist)
|
||||
if an == 0:
|
||||
return None
|
||||
|
||||
@@ -140,7 +140,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
|
||||
return None
|
||||
# List:Callable 参数列表([[A], B]),元素递归,逗号连接
|
||||
if k2 == ast.ASTKind.List:
|
||||
lst: ast.List | t.CPtr = (ast.List | t.CPtr)(node)
|
||||
lst: rawptr[ast.List] = rawptr[ast.List](node)
|
||||
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
|
||||
@@ -151,7 +151,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
|
||||
return self._list_elts_to_type_str(pool, tup.elts, "", "")
|
||||
return None
|
||||
def _list_elts_to_type_str(self, pool: rawptr[memhub.MemBuddy],
|
||||
elts: list[rawptr[ast.AST]] | t.CPtr,
|
||||
elts: rawptr[list[rawptr[ast.AST]]],
|
||||
open_ch: str, close_ch: str) -> str:
|
||||
"""元素列表转逗号分隔字符串(List/Tuple 共用),包上 open/close 括号
|
||||
|
||||
@@ -599,7 +599,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
|
||||
if inner_buf_m is not None:
|
||||
stdlib.free(inner_buf_m)
|
||||
# 优先 ast.parse_expression(单表达式入口,返回 Expression 包装节点)
|
||||
expr_node: ast.Expression | t.CPtr = ast.parse_expression(type_str, pool)
|
||||
expr_node: rawptr[ast.Expression] = ast.parse_expression(type_str, pool)
|
||||
if expr_node is not None:
|
||||
expr_body: rawptr[ast.AST] = expr_node.body
|
||||
if expr_body is not None:
|
||||
@@ -610,11 +610,11 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
|
||||
# parse_tokens 成功,故此处用文件级 parse 兜底)
|
||||
tree_s: rawptr[ast.AST] = ast.parse(type_str, pool)
|
||||
if tree_s is not None:
|
||||
ch_s: list[rawptr[ast.AST]] | t.CPtr = tree_s.children
|
||||
ch_s: rawptr[list[rawptr[ast.AST]]] = tree_s.children
|
||||
if ch_s is not None and len(ch_s) > 0:
|
||||
st0: rawptr[ast.AST] = ch_s.get(0)
|
||||
if st0 is not None and st0.kind() == ast.ASTKind.Expr:
|
||||
ex0: ast.Expr | t.CPtr = (ast.Expr | t.CPtr)(st0)
|
||||
ex0: rawptr[ast.Expr] = rawptr[ast.Expr](st0)
|
||||
if ex0.value is not None:
|
||||
return ex0.value
|
||||
return None
|
||||
@@ -1766,7 +1766,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
|
||||
# Tuple slice: dict[str, int] → "str,int"
|
||||
sub_tup: rawptr[ast.Tuple] = rawptr[ast.Tuple](sub.slice)
|
||||
if sub_tup.elts is not None:
|
||||
tup_elts_sn: list[rawptr[ast.AST]] | t.CPtr = sub_tup.elts
|
||||
tup_elts_sn: rawptr[list[rawptr[ast.AST]]] = sub_tup.elts
|
||||
tn_sn: sizet = len(tup_elts_sn)
|
||||
# 计算总长度
|
||||
tup_total: sizet = 1
|
||||
@@ -1827,7 +1827,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
|
||||
# 用于函数 `-> tuple[str, t.CUnsignedShort]`(如 binascii.b2a_hqx)
|
||||
# 与调用端 `a, b = f()` 的打包/解包。
|
||||
if string.strcmp(gen_cls_name, "tuple") == 0:
|
||||
tp_elts: list[rawptr[ast.AST]] | t.CPtr = None
|
||||
tp_elts: rawptr[list[rawptr[ast.AST]]] = None
|
||||
tp_count: sizet = 0
|
||||
if sub.slice.kind() == ast.ASTKind.Tuple:
|
||||
tp_tup: rawptr[ast.Tuple] = rawptr[ast.Tuple](sub.slice)
|
||||
@@ -1837,7 +1837,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
|
||||
else:
|
||||
# [FIX] elem_size=8(rawptr[ast.AST] 指针 8 字节),原传 1 → get 只读
|
||||
# 1 字节拼指针(高 56 位残留)→ tuple 元素解析垃圾
|
||||
tp_single: list[rawptr[ast.AST]] | t.CPtr = list[rawptr[ast.AST]](pool, 8)
|
||||
tp_single: rawptr[list[rawptr[ast.AST]]] = list[rawptr[ast.AST]](pool, 8)
|
||||
if tp_single is not None:
|
||||
tp_single.append(sub.slice)
|
||||
tp_elts = tp_single
|
||||
@@ -1870,7 +1870,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
|
||||
gen_arg_names: list[str] | t.CPtr = list[str](pool, 8)
|
||||
if sub.slice.kind() == ast.ASTKind.Tuple:
|
||||
gen_tp: rawptr[ast.Tuple] = rawptr[ast.Tuple](sub.slice)
|
||||
gen_elts: list[rawptr[ast.AST]] | t.CPtr = gen_tp.elts
|
||||
gen_elts: rawptr[list[rawptr[ast.AST]]] = gen_tp.elts
|
||||
if gen_elts is not None:
|
||||
gen_en: sizet = len(gen_elts)
|
||||
gen_ei: sizet
|
||||
@@ -1916,7 +1916,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
|
||||
# Phase B 解析字段类型命中已注册结构体时本会早返回 → 方法体永不生成
|
||||
# → 符号只有 declare 无 define → 链接失败。故这里走补译分支。
|
||||
if trans is not None and trans._declare_only == 0:
|
||||
gen_spec_entry: GenTypes.StructEntry | t.CPtr = self.Gen.StructGen.find_struct(gen_mangled)
|
||||
gen_spec_entry: rawptr[GenTypes.StructEntry] = self.Gen.StructGen.find_struct(gen_mangled)
|
||||
if gen_spec_entry is not None and gen_spec_entry.MethodsEmitted == 0:
|
||||
# 错误定位:压入触发特化的调用方帧(注解所在文件+行号),
|
||||
# 使特化方法体报错(如参数类型解析失败)能追溯到用户代码
|
||||
@@ -2079,7 +2079,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
|
||||
if sp_sha_buf2 is not None:
|
||||
string.strncpy(sp_sha_buf2, nm.id, sp_len2 - 1)
|
||||
sp_sha_buf2[sp_len2 - 1] = '\0'
|
||||
sp_entry2: GenTypes.StructEntry | t.CPtr = self.Gen.StructGen.find_struct_by_module(
|
||||
sp_entry2: rawptr[GenTypes.StructEntry] = self.Gen.StructGen.find_struct_by_module(
|
||||
nm.id + sp_len2, sp_sha_buf2)
|
||||
if sp_entry2 is not None and sp_entry2.Ty is not None:
|
||||
if sp_entry2.HasNew != 0:
|
||||
@@ -2118,7 +2118,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
|
||||
# G5Node 顶掉,避免 alloca 用本模块类型、load 用他模块类型的混用)。
|
||||
# 本模块未定义时回退按裸名全局查找(import 来的类走此路径)。
|
||||
if trans is not None and trans.ModuleSha1 is not None:
|
||||
own_entry: GenTypes.StructEntry | t.CPtr = self.Gen.StructGen.find_struct_by_module(nm.id, trans.ModuleSha1)
|
||||
own_entry: rawptr[GenTypes.StructEntry] = self.Gen.StructGen.find_struct_by_module(nm.id, trans.ModuleSha1)
|
||||
if own_entry is not None and own_entry.Ty is not None:
|
||||
# 有 __new__ 的类(堆对象)注解 → Ptr(struct)(引用语义,对齐 TPC)。
|
||||
# 否则无 __new__ 的类(栈对象,如 Point)保持 struct 值语义:
|
||||
@@ -2142,7 +2142,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
|
||||
fi_sha1 = StubMergerStore.LookupSha1ByModNameSuffix(fi_mod)
|
||||
stdlib.free(fi_mod)
|
||||
if fi_sha1 is not None:
|
||||
fi_entry: GenTypes.StructEntry | t.CPtr = self.Gen.StructGen.find_struct_by_module(nm.id, fi_sha1)
|
||||
fi_entry: rawptr[GenTypes.StructEntry] = self.Gen.StructGen.find_struct_by_module(nm.id, fi_sha1)
|
||||
if fi_entry is not None and fi_entry.Ty is not None:
|
||||
if fi_entry.HasNew != 0:
|
||||
return llvmlite.Ptr(pool, fi_entry.Ty)
|
||||
@@ -2150,7 +2150,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
|
||||
if self.Gen.StructGen.is_struct_visible(nm.id) != 0:
|
||||
struct_ty: rawptr[llvmlite.LLVMType] = self.Gen.StructGen.get_struct_type(nm.id)
|
||||
if struct_ty is not None:
|
||||
nm_entry_s: GenTypes.StructEntry | t.CPtr = self.Gen.StructGen.find_struct_by_type(struct_ty)
|
||||
nm_entry_s: rawptr[GenTypes.StructEntry] = self.Gen.StructGen.find_struct_by_type(struct_ty)
|
||||
nm_has_new_s: int = 0
|
||||
if nm_entry_s is not None:
|
||||
nm_has_new_s = nm_entry_s.HasNew
|
||||
@@ -2330,7 +2330,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
|
||||
full_ty_v: rawptr[llvmlite.LLVMType] = self.Gen.StructGen.get_struct_type(full_q_v)
|
||||
if full_ty_v is not None:
|
||||
return full_ty_v
|
||||
mod_entry_v: GenTypes.StructEntry | t.CPtr = self.Gen.StructGen.find_struct_by_module(at.attr, mod_sha1_v)
|
||||
mod_entry_v: rawptr[GenTypes.StructEntry] = self.Gen.StructGen.find_struct_by_module(at.attr, mod_sha1_v)
|
||||
if mod_entry_v is not None and mod_entry_v.Ty is not None:
|
||||
if mod_entry_v.HasNew != 0:
|
||||
return llvmlite.Ptr(pool, mod_entry_v.Ty)
|
||||
@@ -2755,7 +2755,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
|
||||
tup: rawptr[ast.Tuple] = rawptr[ast.Tuple](sub.slice)
|
||||
if tup.elts is None:
|
||||
self.Gen.TypeGenErr.fatal_type_error(node, "t.CArray Tuple 缺少 elts")
|
||||
elts_list: list[rawptr[ast.AST]] | t.CPtr = tup.elts
|
||||
elts_list: rawptr[list[rawptr[ast.AST]]] = tup.elts
|
||||
elts_n: sizet = len(elts_list)
|
||||
if elts_n < 2:
|
||||
self.Gen.TypeGenErr.fatal_type_error(node, "t.CArray Tuple 元素不足")
|
||||
|
||||
@@ -47,10 +47,10 @@ class VarGenMixin:
|
||||
# init_vars — 分配并清零 VarEntry 数组
|
||||
# ============================================================
|
||||
Gen: rawptr[Generator.Generator]
|
||||
def init_vars(self, pool: rawptr[memhub.MemBuddy]) -> GenTypes.VarEntry | t.CPtr:
|
||||
def init_vars(self, pool: rawptr[memhub.MemBuddy]) -> rawptr[GenTypes.VarEntry]:
|
||||
"""分配并清零变量表数组"""
|
||||
size: sizet = MAX_VARS * GenTypes.VarEntry.__sizeof__()
|
||||
vars_ptr: GenTypes.VarEntry | t.CPtr = pool.alloc(size)
|
||||
vars_ptr: rawptr[GenTypes.VarEntry] = pool.alloc(size)
|
||||
if vars_ptr is not None:
|
||||
string.memset(vars_ptr, 0, size)
|
||||
return vars_ptr
|
||||
@@ -58,16 +58,16 @@ class VarGenMixin:
|
||||
# ============================================================
|
||||
# find_var — 在变量表中按名称查找
|
||||
# ============================================================
|
||||
def find_var(self, vars_ptr: GenTypes.VarEntry | t.CPtr,
|
||||
def find_var(self, vars_ptr: rawptr[GenTypes.VarEntry],
|
||||
var_count: int,
|
||||
name: str) -> llvmlite.Value | t.CPtr:
|
||||
name: str) -> rawptr[llvmlite.Value]:
|
||||
"""在变量表中按名称查找"""
|
||||
if name is None or vars_ptr is None:
|
||||
return None
|
||||
entry_size: sizet = GenTypes.VarEntry.__sizeof__()
|
||||
for i in range(var_count):
|
||||
entry_addr: uint64 = uint64(vars_ptr) + i * entry_size
|
||||
entry: GenTypes.VarEntry | t.CPtr = (GenTypes.VarEntry | t.CPtr)(entry_addr)
|
||||
entry: rawptr[GenTypes.VarEntry] = rawptr[GenTypes.VarEntry](entry_addr)
|
||||
if entry.Name is not None and entry.Used != 0:
|
||||
# 快速路径:strcmp 判等蕴含首字符相等,首字符不同者跳过 strcmp
|
||||
if entry.Name[0] == name[0] and string.strcmp(entry.Name, name) == 0:
|
||||
@@ -77,16 +77,16 @@ class VarGenMixin:
|
||||
# ============================================================
|
||||
# find_var_entry — 在变量表中按名称查找,返回 VarEntry(含 AnnotTy)
|
||||
# ============================================================
|
||||
def find_var_entry(self, vars_ptr: GenTypes.VarEntry | t.CPtr,
|
||||
def find_var_entry(self, vars_ptr: rawptr[GenTypes.VarEntry],
|
||||
var_count: int,
|
||||
name: str) -> GenTypes.VarEntry | t.CPtr:
|
||||
name: str) -> rawptr[GenTypes.VarEntry]:
|
||||
"""在变量表中按名称查找,返回 VarEntry 或 None"""
|
||||
if name is None or vars_ptr is None:
|
||||
return None
|
||||
entry_size: sizet = GenTypes.VarEntry.__sizeof__()
|
||||
for i in range(var_count):
|
||||
entry_addr: uint64 = uint64(vars_ptr) + i * entry_size
|
||||
entry: GenTypes.VarEntry | t.CPtr = (GenTypes.VarEntry | t.CPtr)(entry_addr)
|
||||
entry: rawptr[GenTypes.VarEntry] = rawptr[GenTypes.VarEntry](entry_addr)
|
||||
if entry.Name is not None and entry.Used != 0:
|
||||
if string.strcmp(entry.Name, name) == 0:
|
||||
return entry
|
||||
@@ -95,14 +95,14 @@ class VarGenMixin:
|
||||
# ============================================================
|
||||
# lookup_var_entry — 从当前作用域逐级向上查找变量,返回 VarEntry
|
||||
# ============================================================
|
||||
def lookup_var_entry(self, symtab: GenTypes.SymbolTable | t.CPtr,
|
||||
name: str) -> GenTypes.VarEntry | t.CPtr:
|
||||
def lookup_var_entry(self, symtab: rawptr[GenTypes.SymbolTable],
|
||||
name: str) -> rawptr[GenTypes.VarEntry]:
|
||||
"""从当前作用域逐级向上查找变量,返回 VarEntry 或 None"""
|
||||
if symtab is None or name is None:
|
||||
return None
|
||||
scope: GenTypes.Scope | t.CPtr = symtab.Current
|
||||
scope: rawptr[GenTypes.Scope] = symtab.Current
|
||||
while scope is not None:
|
||||
result: GenTypes.VarEntry | t.CPtr = self.find_var_entry(scope.Vars, scope.VarCount, name)
|
||||
result: rawptr[GenTypes.VarEntry] = self.find_var_entry(scope.Vars, scope.VarCount, name)
|
||||
if result is not None:
|
||||
return result
|
||||
scope = scope.Parent
|
||||
@@ -115,7 +115,7 @@ class VarGenMixin:
|
||||
# 方法调用检测时,当 alloca 类型是 Ptr(i8)(联合类型简化),
|
||||
# 通过 Spec.SourceName 查找实际结构体类型。
|
||||
# ============================================================
|
||||
def set_var_annot_class_name(self, symtab: GenTypes.SymbolTable | t.CPtr,
|
||||
def set_var_annot_class_name(self, symtab: rawptr[GenTypes.SymbolTable],
|
||||
name: str,
|
||||
class_name: str) -> int:
|
||||
"""设置变量的原始类型注解类名(写入 Spec.SourceName),返回 0=成功 / 1=失败
|
||||
@@ -130,13 +130,13 @@ class VarGenMixin:
|
||||
"""
|
||||
if symtab is None or name is None:
|
||||
return 1
|
||||
entry: GenTypes.VarEntry | t.CPtr = self.lookup_var_entry(symtab, name)
|
||||
entry: rawptr[GenTypes.VarEntry] = self.lookup_var_entry(symtab, name)
|
||||
if entry is None:
|
||||
return 1
|
||||
if class_name is None:
|
||||
# 无注解名:不写入(VarEntry 槽位不复用,原值恒为 None,与清空等价)。
|
||||
return 0
|
||||
arena_sn: TSpec.TypeSpecArena | t.CPtr = self.Gen.TypeGenBase.ensure_spec_arena()
|
||||
arena_sn: rawptr[TSpec.TypeSpecArena] = self.Gen.TypeGenBase.ensure_spec_arena()
|
||||
if arena_sn is None:
|
||||
return 1
|
||||
if entry.Spec is None:
|
||||
@@ -156,7 +156,7 @@ class VarGenMixin:
|
||||
# 注解侧由 set_var_annot_class_name 经 SpecWithSource 写入 Spec.SourceName。
|
||||
# 变量侧类名恢复读取点统一走此入口。
|
||||
# ============================================================
|
||||
def var_annot_class_name(self, entry: GenTypes.VarEntry | t.CPtr) -> str:
|
||||
def var_annot_class_name(self, entry: rawptr[GenTypes.VarEntry]) -> str:
|
||||
"""变量条目注解类名(Spec.SourceName);未设置返回 None"""
|
||||
if entry is None:
|
||||
return None
|
||||
@@ -169,12 +169,12 @@ class VarGenMixin:
|
||||
# 该语义由 Spec.ElemBits 承载:上述四类在 LLVM 层都是 Ptr(Int8)(ElemBits=8,
|
||||
# 无法区分),故注解侧把元素槽宽覆盖为 8 字节,消费点经 var_is_ptr_element 读取。
|
||||
# 由 AnnAssign 按注解形式(_is_ptr_element_annotation)调用。
|
||||
def set_var_ptr_element(self, symtab: GenTypes.SymbolTable | t.CPtr,
|
||||
def set_var_ptr_element(self, symtab: rawptr[GenTypes.SymbolTable],
|
||||
name: str) -> int:
|
||||
"""标记变量为 ptr-element(Spec.ElemBits=64),返回 0=成功 / 1=失败"""
|
||||
if symtab is None or name is None:
|
||||
return 1
|
||||
entry: GenTypes.VarEntry | t.CPtr = self.lookup_var_entry(symtab, name)
|
||||
entry: rawptr[GenTypes.VarEntry] = self.lookup_var_entry(symtab, name)
|
||||
if entry is None:
|
||||
return 1
|
||||
# ptr-element 变量的 alloca 是 Ptr(Ptr(Int8)),其值类型 Ptr(Int8) ⇒ Spec 必为
|
||||
@@ -192,11 +192,11 @@ class VarGenMixin:
|
||||
# 判据:PtrLevel>=1 且元素位宽为 8(LLVM 层退化后的 i8*)且 ElemBits==64
|
||||
# (注解侧覆盖的 8 字节槽)。后两个条件缺一不可:真实 i64* 变量 ElemBits 也为 64
|
||||
# 但 Elem.Bits=64,不命中;纯 str/bytes/char|t.CPtr 变量 ElemBits=8,同样不命中。
|
||||
def var_is_ptr_element(self, entry: GenTypes.VarEntry | t.CPtr) -> int:
|
||||
def var_is_ptr_element(self, entry: rawptr[GenTypes.VarEntry]) -> int:
|
||||
"""变量是否为 ptr-element 语义(1=是 / 0=否)"""
|
||||
if entry is None or entry.Spec is None:
|
||||
return 0
|
||||
sp: TSpec.TypeSpec | t.CPtr = entry.Spec
|
||||
sp: rawptr[TSpec.TypeSpec] = entry.Spec
|
||||
if sp.PtrLevel < 1 or sp.Elem is None:
|
||||
return 0
|
||||
if sp.Elem.Bits != 8:
|
||||
@@ -208,10 +208,10 @@ class VarGenMixin:
|
||||
# ============================================================
|
||||
# add_var — 添加变量到变量表
|
||||
# ============================================================
|
||||
def add_var(self, vars_ptr: GenTypes.VarEntry | t.CPtr,
|
||||
def add_var(self, vars_ptr: rawptr[GenTypes.VarEntry],
|
||||
var_count: int,
|
||||
name: str,
|
||||
alloca: llvmlite.Value | t.CPtr) -> int:
|
||||
alloca: rawptr[llvmlite.Value]) -> int:
|
||||
"""添加变量到变量表"""
|
||||
if name is None or alloca is None or vars_ptr is None:
|
||||
return 1
|
||||
@@ -219,7 +219,7 @@ class VarGenMixin:
|
||||
return 1
|
||||
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)(entry_addr)
|
||||
entry: rawptr[GenTypes.VarEntry] = rawptr[GenTypes.VarEntry](entry_addr)
|
||||
# 变量名必须深拷贝到 stdlib(跨 pool reset 存活):entry.Name 直接存 AST
|
||||
# 节点 Name.id 指针时,该段内存被后续分配覆盖会使 find_var 的 strcmp 静默
|
||||
# 失配 → Handle 阶段找不到 PreScan 已建的同名 alloca → 另建类型退化的
|
||||
@@ -245,14 +245,14 @@ class VarGenMixin:
|
||||
# SpecFromLLVMType 不支持者)返回 None —— 后者是设计内的「不适用」,非兜底。
|
||||
# 分配一律 PermPool 驻留 ⇒ 跨文件/跨 1b reset 安全。
|
||||
# ============================================================
|
||||
def _spec_of_var_alloca(self, alloca: llvmlite.Value | t.CPtr) -> TSpec.TypeSpec | t.CPtr:
|
||||
def _spec_of_var_alloca(self, alloca: rawptr[llvmlite.Value]) -> rawptr[TSpec.TypeSpec]:
|
||||
"""由 alloca 的值类型构造 TypeSpec,不适用/失败返回 None"""
|
||||
if alloca is None or alloca.Ty is None:
|
||||
return None
|
||||
ty: rawptr[llvmlite.LLVMType] = alloca.Ty
|
||||
if self.Gen.ExprGenBase.is_ptr_type(ty) != 0:
|
||||
ty = ty.Pointee
|
||||
arena: TSpec.TypeSpecArena | t.CPtr = self.Gen.TypeGenBase.ensure_spec_arena()
|
||||
arena: rawptr[TSpec.TypeSpecArena] = self.Gen.TypeGenBase.ensure_spec_arena()
|
||||
if arena is None:
|
||||
return None
|
||||
return TSpec.SpecFromLLVMType(arena, ty)
|
||||
@@ -260,8 +260,8 @@ class VarGenMixin:
|
||||
# _alloca_at_entry - 在函数入口块生成 alloca(确保支配性)
|
||||
# LLVM IR 要求指令支配所有使用点,故所有 alloca 须在函数入口块生成。
|
||||
# 实现:临时切换 builder.CurBlock 到入口块,生成 alloca 后恢复。
|
||||
def _alloca_at_entry(self, builder: llvmlite.IRBuilder | t.CPtr,
|
||||
ty: rawptr[llvmlite.LLVMType]) -> llvmlite.Value | t.CPtr:
|
||||
def _alloca_at_entry(self, builder: rawptr[llvmlite.IRBuilder],
|
||||
ty: rawptr[llvmlite.LLVMType]) -> rawptr[llvmlite.Value]:
|
||||
"""在函数入口块生成 alloca,返回 alloca 值
|
||||
|
||||
使用 llvmlite.build_alloca_at_entry 在入口块终止指令之前插入 alloca,
|
||||
@@ -273,16 +273,16 @@ class VarGenMixin:
|
||||
|
||||
# get_or_create_var — 查找或创建变量 alloca(旧版兼容)
|
||||
def get_or_create_var(self, pool: rawptr[memhub.MemBuddy],
|
||||
builder: llvmlite.IRBuilder | t.CPtr,
|
||||
vars_ptr: GenTypes.VarEntry | t.CPtr,
|
||||
builder: rawptr[llvmlite.IRBuilder],
|
||||
vars_ptr: rawptr[GenTypes.VarEntry],
|
||||
var_count: int,
|
||||
name: str,
|
||||
ty: rawptr[llvmlite.LLVMType]) -> llvmlite.Value | t.CPtr:
|
||||
ty: rawptr[llvmlite.LLVMType]) -> rawptr[llvmlite.Value]:
|
||||
"""查找或创建变量 alloca"""
|
||||
existing: llvmlite.Value | t.CPtr = self.find_var(vars_ptr, var_count, name)
|
||||
existing: rawptr[llvmlite.Value] = self.find_var(vars_ptr, var_count, name)
|
||||
if existing is not None:
|
||||
return existing
|
||||
alloca: llvmlite.Value | t.CPtr = self._alloca_at_entry(builder, ty)
|
||||
alloca: rawptr[llvmlite.Value] = self._alloca_at_entry(builder, ty)
|
||||
if alloca is None:
|
||||
return None
|
||||
if self.add_var(vars_ptr, var_count, name, alloca) != 0:
|
||||
@@ -293,10 +293,10 @@ class VarGenMixin:
|
||||
# _create_scope — 创建新作用域节点(内部辅助函数)
|
||||
# ============================================================
|
||||
def _create_scope(self, pool: rawptr[memhub.MemBuddy],
|
||||
parent: GenTypes.Scope | t.CPtr,
|
||||
kind: int) -> GenTypes.Scope | t.CPtr:
|
||||
parent: rawptr[GenTypes.Scope],
|
||||
kind: int) -> rawptr[GenTypes.Scope]:
|
||||
"""创建并初始化作用域节点"""
|
||||
scope: GenTypes.Scope | t.CPtr = pool.alloc(GenTypes.Scope.__sizeof__())
|
||||
scope: rawptr[GenTypes.Scope] = pool.alloc(GenTypes.Scope.__sizeof__())
|
||||
if scope is None:
|
||||
return None
|
||||
string.memset(scope, 0, GenTypes.Scope.__sizeof__())
|
||||
@@ -311,18 +311,18 @@ class VarGenMixin:
|
||||
# ============================================================
|
||||
# init_symbol_table — 创建符号表(含模块级根作用域)
|
||||
# ============================================================
|
||||
def init_symbol_table(self, pool: rawptr[memhub.MemBuddy]) -> GenTypes.SymbolTable | t.CPtr:
|
||||
def init_symbol_table(self, pool: rawptr[memhub.MemBuddy]) -> rawptr[GenTypes.SymbolTable]:
|
||||
"""创建并初始化符号表,包含模块级根作用域"""
|
||||
if pool is None:
|
||||
return None
|
||||
symtab: GenTypes.SymbolTable | t.CPtr = pool.alloc(GenTypes.SymbolTable.__sizeof__())
|
||||
symtab: rawptr[GenTypes.SymbolTable] = pool.alloc(GenTypes.SymbolTable.__sizeof__())
|
||||
if symtab is None:
|
||||
return None
|
||||
string.memset(symtab, 0, GenTypes.SymbolTable.__sizeof__())
|
||||
symtab.Pool = pool
|
||||
|
||||
# 创建根作用域(模块级)
|
||||
root: GenTypes.Scope | t.CPtr = self._create_scope(pool, None, SCOPE_MODULE)
|
||||
root: rawptr[GenTypes.Scope] = self._create_scope(pool, None, SCOPE_MODULE)
|
||||
if root is None:
|
||||
return None
|
||||
|
||||
@@ -333,13 +333,13 @@ class VarGenMixin:
|
||||
# ============================================================
|
||||
# enter_scope — 进入新作用域
|
||||
# ============================================================
|
||||
def enter_scope(self, symtab: GenTypes.SymbolTable | t.CPtr,
|
||||
kind: int) -> GenTypes.Scope | t.CPtr:
|
||||
def enter_scope(self, symtab: rawptr[GenTypes.SymbolTable],
|
||||
kind: int) -> rawptr[GenTypes.Scope]:
|
||||
"""进入新作用域,返回新创建的作用域"""
|
||||
if symtab is None:
|
||||
return None
|
||||
pool: rawptr[memhub.MemBuddy] = symtab.Pool
|
||||
scope: GenTypes.Scope | t.CPtr = self._create_scope(pool, symtab.Current, kind)
|
||||
scope: rawptr[GenTypes.Scope] = self._create_scope(pool, symtab.Current, kind)
|
||||
if scope is None:
|
||||
return None
|
||||
symtab.Current = scope
|
||||
@@ -348,7 +348,7 @@ class VarGenMixin:
|
||||
# ============================================================
|
||||
# exit_scope — 退出当前作用域
|
||||
# ============================================================
|
||||
def exit_scope(self, symtab: GenTypes.SymbolTable | t.CPtr):
|
||||
def exit_scope(self, symtab: rawptr[GenTypes.SymbolTable]):
|
||||
"""退出当前作用域,恢复到父作用域"""
|
||||
if symtab is not None and symtab.Current is not None:
|
||||
symtab.Current = symtab.Current.Parent
|
||||
@@ -356,13 +356,13 @@ class VarGenMixin:
|
||||
# ============================================================
|
||||
# define_var — 在当前作用域定义变量
|
||||
# ============================================================
|
||||
def define_var(self, symtab: GenTypes.SymbolTable | t.CPtr,
|
||||
def define_var(self, symtab: rawptr[GenTypes.SymbolTable],
|
||||
name: str,
|
||||
alloca: llvmlite.Value | t.CPtr) -> int:
|
||||
alloca: rawptr[llvmlite.Value]) -> int:
|
||||
"""在当前作用域定义变量,返回 0 成功"""
|
||||
if symtab is None or name is None or alloca is None:
|
||||
return 1
|
||||
scope: GenTypes.Scope | t.CPtr = symtab.Current
|
||||
scope: rawptr[GenTypes.Scope] = symtab.Current
|
||||
if scope is None:
|
||||
return 1
|
||||
ret: int = self.add_var(scope.Vars, scope.VarCount, name, alloca)
|
||||
@@ -373,13 +373,13 @@ class VarGenMixin:
|
||||
# ============================================================
|
||||
# define_module_var — 在模块作用域定义变量
|
||||
# ============================================================
|
||||
def define_module_var(self, symtab: GenTypes.SymbolTable | t.CPtr,
|
||||
def define_module_var(self, symtab: rawptr[GenTypes.SymbolTable],
|
||||
name: str,
|
||||
alloca: llvmlite.Value | t.CPtr) -> int:
|
||||
alloca: rawptr[llvmlite.Value]) -> int:
|
||||
"""在模块作用域定义变量,返回 0 成功"""
|
||||
if symtab is None or name is None or alloca is None:
|
||||
return 1
|
||||
scope: GenTypes.Scope | t.CPtr = symtab.Root
|
||||
scope: rawptr[GenTypes.Scope] = symtab.Root
|
||||
if scope is None:
|
||||
return 1
|
||||
ret: int = self.add_var(scope.Vars, scope.VarCount, name, alloca)
|
||||
@@ -390,14 +390,14 @@ class VarGenMixin:
|
||||
# ============================================================
|
||||
# lookup_var — 从当前作用域逐级向上查找变量
|
||||
# ============================================================
|
||||
def lookup_var(self, symtab: GenTypes.SymbolTable | t.CPtr,
|
||||
name: str) -> llvmlite.Value | t.CPtr:
|
||||
def lookup_var(self, symtab: rawptr[GenTypes.SymbolTable],
|
||||
name: str) -> rawptr[llvmlite.Value]:
|
||||
"""从当前作用域逐级向上查找变量,返回 alloca 或 None"""
|
||||
if symtab is None or name is None:
|
||||
return None
|
||||
scope: GenTypes.Scope | t.CPtr = symtab.Current
|
||||
scope: rawptr[GenTypes.Scope] = symtab.Current
|
||||
while scope is not None:
|
||||
result: llvmlite.Value | t.CPtr = self.find_var(
|
||||
result: rawptr[llvmlite.Value] = self.find_var(
|
||||
scope.Vars, scope.VarCount, name)
|
||||
if result is not None:
|
||||
return result
|
||||
@@ -407,12 +407,12 @@ class VarGenMixin:
|
||||
# ============================================================
|
||||
# lookup_current — 仅在当前作用域查找变量
|
||||
# ============================================================
|
||||
def lookup_current(self, symtab: GenTypes.SymbolTable | t.CPtr,
|
||||
name: str) -> llvmlite.Value | t.CPtr:
|
||||
def lookup_current(self, symtab: rawptr[GenTypes.SymbolTable],
|
||||
name: str) -> rawptr[llvmlite.Value]:
|
||||
"""仅在当前作用域查找变量"""
|
||||
if symtab is None or name is None:
|
||||
return None
|
||||
scope: GenTypes.Scope | t.CPtr = symtab.Current
|
||||
scope: rawptr[GenTypes.Scope] = symtab.Current
|
||||
if scope is None:
|
||||
return None
|
||||
return self.find_var(scope.Vars, scope.VarCount, name)
|
||||
@@ -420,12 +420,12 @@ class VarGenMixin:
|
||||
# ============================================================
|
||||
# lookup_module_var — 在模块作用域查找变量
|
||||
# ============================================================
|
||||
def lookup_module_var(self, symtab: GenTypes.SymbolTable | t.CPtr,
|
||||
name: str) -> llvmlite.Value | t.CPtr:
|
||||
def lookup_module_var(self, symtab: rawptr[GenTypes.SymbolTable],
|
||||
name: str) -> rawptr[llvmlite.Value]:
|
||||
"""在模块作用域查找变量"""
|
||||
if symtab is None or name is None:
|
||||
return None
|
||||
scope: GenTypes.Scope | t.CPtr = symtab.Root
|
||||
scope: rawptr[GenTypes.Scope] = symtab.Root
|
||||
if scope is None:
|
||||
return None
|
||||
return self.find_var(scope.Vars, scope.VarCount, name)
|
||||
@@ -437,7 +437,7 @@ class VarGenMixin:
|
||||
# - 模块级代码:AnnAssign 应修改模块级变量(Python 语义)
|
||||
# - 函数内代码:无 global 声明时 AnnAssign 应创建局部变量(Python 语义)
|
||||
# ============================================================
|
||||
def is_module_scope(self, symtab: GenTypes.SymbolTable | t.CPtr) -> int:
|
||||
def is_module_scope(self, symtab: rawptr[GenTypes.SymbolTable]) -> int:
|
||||
"""判断当前作用域是否为模块级作用域(Current == Root)
|
||||
|
||||
Returns: 1=模块级作用域, 0=函数内作用域
|
||||
@@ -458,14 +458,14 @@ class VarGenMixin:
|
||||
# 遍历规则:逐级向上查找;SCOPE_MATCH 边界可穿越(可命中外层 case 声明的变量),
|
||||
# 遇到第一个非 match 作用域(函数/模块)后停止——不跨函数边界(闭包 nonlocal
|
||||
# 语义由 is_nonlocal_name 单独处理)。
|
||||
def _lookup_through_match_scope(self, symtab: GenTypes.SymbolTable | t.CPtr,
|
||||
name: str) -> llvmlite.Value | t.CPtr:
|
||||
def _lookup_through_match_scope(self, symtab: rawptr[GenTypes.SymbolTable],
|
||||
name: str) -> rawptr[llvmlite.Value]:
|
||||
"""从当前作用域向上,仅穿越 SCOPE_MATCH 作用域查找变量 alloca"""
|
||||
if symtab is None or name is None:
|
||||
return None
|
||||
scope: GenTypes.Scope | t.CPtr = symtab.Current
|
||||
scope: rawptr[GenTypes.Scope] = symtab.Current
|
||||
while scope is not None:
|
||||
result: llvmlite.Value | t.CPtr = self.find_var(
|
||||
result: rawptr[llvmlite.Value] = self.find_var(
|
||||
scope.Vars, scope.VarCount, name)
|
||||
if result is not None:
|
||||
return result
|
||||
@@ -478,13 +478,13 @@ class VarGenMixin:
|
||||
# ============================================================
|
||||
# get_or_create_sym — 查找或创建变量(在当前作用域)
|
||||
# ============================================================
|
||||
def get_or_create_sym(self, symtab: GenTypes.SymbolTable | t.CPtr,
|
||||
def get_or_create_sym(self, symtab: rawptr[GenTypes.SymbolTable],
|
||||
pool: rawptr[memhub.MemBuddy],
|
||||
builder: llvmlite.IRBuilder | t.CPtr,
|
||||
builder: rawptr[llvmlite.IRBuilder],
|
||||
name: str,
|
||||
ty: rawptr[llvmlite.LLVMType]) -> llvmlite.Value | t.CPtr:
|
||||
ty: rawptr[llvmlite.LLVMType]) -> rawptr[llvmlite.Value]:
|
||||
"""查找或创建变量 alloca(在当前作用域)"""
|
||||
existing: llvmlite.Value | t.CPtr = self.lookup_current(symtab, name)
|
||||
existing: rawptr[llvmlite.Value] = self.lookup_current(symtab, name)
|
||||
if existing is not None:
|
||||
return existing
|
||||
# SCOPE_MATCH 隔离作用域对"赋值"必须透明(详见 _lookup_through_match_scope):
|
||||
@@ -493,7 +493,7 @@ class VarGenMixin:
|
||||
existing = self._lookup_through_match_scope(symtab, name)
|
||||
if existing is not None:
|
||||
return existing
|
||||
alloca: llvmlite.Value | t.CPtr = self._alloca_at_entry(builder, ty)
|
||||
alloca: rawptr[llvmlite.Value] = self._alloca_at_entry(builder, ty)
|
||||
if alloca is None:
|
||||
return None
|
||||
if self.define_var(symtab, name, alloca) != 0:
|
||||
|
||||
@@ -164,7 +164,7 @@ def compute_file_sha1(pool: rawptr[memhub.MemBuddy],
|
||||
buf[write_pos] = 0
|
||||
|
||||
# 计算 SHA1
|
||||
ctx: hashlib.sha1 | t.CPtr = hashlib.sha1()
|
||||
ctx: rawptr[hashlib.sha1] = hashlib.sha1()
|
||||
if ctx is None:
|
||||
stdlib.free(buf)
|
||||
return None
|
||||
@@ -206,7 +206,7 @@ def scan_directory_recursive(pool: rawptr[memhub.MemBuddy],
|
||||
|
||||
# find_data 缓冲 +16 余量:TPV 的 WIN32_FIND_DATAA.__sizeof__() 小于 Windows 实际写入,越界写会破坏相邻堆块
|
||||
fd_size_s: sizet = win32file.WIN32_FIND_DATAA.__sizeof__()
|
||||
find_data: win32file.WIN32_FIND_DATAA | t.CPtr = stdlib.malloc(fd_size_s + 16)
|
||||
find_data: rawptr[win32file.WIN32_FIND_DATAA] = stdlib.malloc(fd_size_s + 16)
|
||||
if find_data is None:
|
||||
return 1
|
||||
string.memset(find_data, 0, fd_size_s + 16)
|
||||
|
||||
+3
-3
@@ -445,7 +445,7 @@ Target: %s
|
||||
|
||||
# === 翻译 AST → LLVM IR ===
|
||||
log.banner("LLVM IR 翻译")
|
||||
tr: HandlesTranslator.Translator | t.CPtr = HandlesTranslator.Translator()
|
||||
tr: rawptr[HandlesTranslator.Translator] = HandlesTranslator.Translator()
|
||||
result: int = tr.translate(tree)
|
||||
if result == 0:
|
||||
IR_BUF_SIZE: sizet = 262144
|
||||
@@ -576,7 +576,7 @@ Target: %s
|
||||
stdlib.free(combined_buf)
|
||||
VLogger.error("BuildCombinedIR 失败,终止编译", "stub")
|
||||
|
||||
br: BuildPipeline.BuildResult | t.CPtr = BuildPipeline.run_pipeline(
|
||||
br: rawptr[BuildPipeline.BuildResult] = BuildPipeline.run_pipeline(
|
||||
final_ir, final_ir_len, temp_dir, output_dir, module_name,
|
||||
cc_cmd, cc_flags, linker_cmd, linker_flags, linker_output,
|
||||
includes_binary_dir, linker_static_libs, linker_dynamic_libs
|
||||
@@ -591,7 +591,7 @@ Target: %s
|
||||
if exe_path is not None:
|
||||
viperlib.snprintf(exe_path, 256, "%s/%s", output_dir, linker_output)
|
||||
log.info(f"执行: {exe_path}")
|
||||
r: subprocess.CompletedProcess | t.CPtr = subprocess.run(exe_path, False, False)
|
||||
r: rawptr[subprocess.CompletedProcess] = subprocess.run(exe_path, False, False)
|
||||
if r is not None:
|
||||
log.info(f"退出码: {r.returncode}")
|
||||
else:
|
||||
|
||||
Reference in new issue
Block a user