From 951b89be3632847b84d684d88f3084e0c12c621c Mon Sep 17 00:00:00 2001 From: TermiNexus Date: Wed, 23 Sep 2026 16:09:32 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=AD=A3=E4=BA=86=E9=83=A8=E5=88=86?= =?UTF-8?q?=E4=BB=A3=E7=A0=81=E7=9A=84=E8=A1=A8=E8=BE=BE=E6=96=B9=E5=BC=8F?= =?UTF-8?q?=EF=BC=8C=E6=9C=80=E5=90=8E=E5=8F=AF=E7=94=A8=E7=89=88=E6=9C=AC?= =?UTF-8?q?=EF=BC=8C=E6=AD=A3=E5=9C=A8=E4=B8=BA=20mlirlite=20=E5=81=9A?= =?UTF-8?q?=E5=87=86=E5=A4=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- App/lib/Phase/BuildPipeline.vp | 12 +- App/lib/Phase/Phase1/Phase1Main.vp | 22 +- App/lib/Phase/Phase1/Phase1Scan.vp | 64 +- App/lib/Phase/Phase1/Phase1Topo.vp | 2 +- App/lib/Phase/Phase1/__init__.vp | 2 +- App/lib/Phase/Phase2/__init__.vp | 32 +- App/lib/Projectrans/Utils.vp | 6 +- App/lib/Stub/StubGen/Converter.vp | 182 +-- App/lib/Stub/StubGen/VpiReader.vp | 467 +++--- App/lib/Stub/StubMerger/StubMergerBuild.vp | 28 +- App/lib/Stub/StubMerger/StubMergerCollect.vp | 4 +- App/lib/Stub/StubMerger/StubMergerTopo.vp | 8 +- App/lib/Stub/StubMerger/__init__.vp | 2 +- App/lib/__init__.vp | 2 +- App/lib/core/CompilerFactory.vp | 24 +- App/lib/core/Gen/AssignGenMixin.vp | 1458 +++++++++++++----- App/lib/core/Gen/AsyncGenMixin.vp | 902 ++++++----- App/lib/core/Gen/BaseGenMixin.vp | 19 +- App/lib/core/Gen/Call/CallGenBase.vp | 208 ++- App/lib/core/Gen/Call/CallGenCBuiltin.vp | 688 ++++----- App/lib/core/Gen/Call/CallGenCall.vp | 795 ++++------ App/lib/core/Gen/Call/CallGenCtor.vp | 576 +++---- App/lib/core/Gen/Call/CallGenDispatch.vp | 936 +++++------ App/lib/core/Gen/Call/CallGenFd.vp | 282 ++-- App/lib/core/Gen/Call/CallGenLeafKit.vp | 675 ++++---- App/lib/core/Gen/Call/CallGenLib.vp | 247 ++- App/lib/core/Gen/Call/CallGenMixin.vp | 447 ++---- App/lib/core/Gen/Call/CallGenProp.vp | 232 ++- App/lib/core/Gen/Call/CallGenVa.vp | 162 +- App/lib/core/Gen/Call/CallGenVt.vp | 180 +-- App/lib/core/Gen/Class/ClassGenBase.vp | 238 +-- App/lib/core/Gen/Class/ClassGenDef.vp | 104 +- App/lib/core/Gen/Class/ClassGenEnum.vp | 486 ++++-- App/lib/core/Gen/Class/ClassGenGeneric.vp | 168 +- App/lib/core/Gen/Class/ClassGenVTable.vp | 253 +-- App/lib/core/Gen/Expr/ExprGenAttr.vp | 806 +++++----- App/lib/core/Gen/Expr/ExprGenBase.vp | 126 +- App/lib/core/Gen/Expr/ExprGenCdef.vp | 110 +- App/lib/core/Gen/Expr/ExprGenCls.vp | 64 +- App/lib/core/Gen/Expr/ExprGenConst.vp | 122 +- App/lib/core/Gen/Expr/ExprGenFstr.vp | 102 +- App/lib/core/Gen/Expr/ExprGenMixin.vp | 55 +- App/lib/core/Gen/Expr/ExprGenName.vp | 446 +++--- App/lib/core/Gen/Expr/ExprGenOps.vp | 413 +++-- App/lib/core/Gen/Func/FuncGenBase.vp | 94 +- App/lib/core/Gen/Func/FuncGenDef.vp | 344 +++-- App/lib/core/Gen/Func/FuncGenMixin.vp | 389 ++--- App/lib/core/Gen/GenApi.vp | 122 +- App/lib/core/Gen/GenTypes.vp | 72 +- App/lib/core/Gen/Generator.vp | 10 +- App/lib/core/Gen/ImportsGenMixin.vp | 61 +- App/lib/core/Gen/MatchGenMixin.vp | 285 ++-- App/lib/core/Gen/Stmt/StmtGenCifMixin.vp | 758 ++++----- App/lib/core/Gen/Stmt/StmtGenDeclMixin.vp | 156 +- App/lib/core/Gen/Stmt/StmtGenMixin.vp | 214 +-- App/lib/core/Gen/StructGenMixin.vp | 595 ++++--- App/lib/core/Gen/Translator.vp | 162 +- App/lib/core/Gen/TranslatorGenMixin.vp | 260 ++-- App/lib/core/Gen/Type/TypeGenBase.vp | 48 +- App/lib/core/Gen/Type/TypeGenCDef.vp | 40 +- App/lib/core/Gen/Type/TypeGenCType.vp | 60 +- App/lib/core/Gen/Type/TypeGenErr.vp | 102 +- App/lib/core/Gen/Type/TypeGenResolve.vp | 425 ++--- App/lib/core/Gen/Type/TypeSpec.vp | 70 +- App/lib/core/Gen/VarGenMixin.vp | 879 ++++++----- App/lib/core/IncludesScanner.vp | 20 +- App/lib/core/Repl.vp | 86 +- App/lib/core/VLogger.vp | 4 +- App/main.vp | 10 +- 69 files changed, 8833 insertions(+), 8590 deletions(-) diff --git a/App/lib/Phase/BuildPipeline.vp b/App/lib/Phase/BuildPipeline.vp index 52a0cf8..24a466d 100644 --- a/App/lib/Phase/BuildPipeline.vp +++ b/App/lib/Phase/BuildPipeline.vp @@ -34,7 +34,7 @@ import lib.Stub.StubMerger.StubMergerCollect as StubMergerCollect # ============================================================ # 全局 mbuddy 指针 -_mbuddy: rawptr[memhub.MemBuddy] +_mbuddy: memhub.MemBuddy* # ASan 模式(--asan):对 .ll 先 opt -passes=asan 插桩;ASan 运行库由 # project.vpj 的 linker.static_libs / dynamic_libs 显式声明(TPV 不注入) @@ -61,7 +61,7 @@ PYI_BUF_SIZE: sizet = 262144 # Args: mb 内存池;file_path 源文件路径;sha1_val 文件内容的 SHA1 前16字符(用于函数名混淆);current_package 当前文件所属包名(用于解析相对导入),None 表示顶级模块;declare_only 0=全量翻译(默认),1=仅注册 struct/enum/union(不翻译方法体);temp_dir temp 目录路径(非 None 时在翻译前生成 .vpi 存根文件) # Returns: Translator 对象(None 失败) # ============================================================ -def TranslateFileGetTrans(mb: rawptr[memhub.MemBuddy], file_path: str, +def TranslateFileGetTrans(mb: memhub.MemBuddy*, file_path: str, sha1_val: str, current_package: str = None, declare_only: int = 0, @@ -92,10 +92,10 @@ def TranslateFileGetTrans(mb: rawptr[memhub.MemBuddy], file_path: str, return None if bytes_read < SRC_BUF_SIZE: src_buf[bytes_read] = 0 - lx: rawptr[ast.Lexer] = ast.new_lexer(mb) + lx: ast.Lexer* = ast.new_lexer(mb) ast._lexer_init(lx, src_buf, mb) - tokens: rawptr[ast.Token] = ast.tokenize(lx) - tree: rawptr[ast.AST] = ast.parse_tokens(mb, tokens) + tokens: ast.Token* = ast.tokenize(lx) + tree: ast.AST* = ast.parse_tokens(mb, tokens) # parse 完成后 AST 树已独立,释放源代码缓冲区(避免 1MB/文件泄漏) stdlib.free(src_buf) if tree is None: @@ -585,7 +585,7 @@ def run_llc_parallel(tasks: bytes, task_count: int, max_threads: int) -> int: max_threads = 1 # 线程句柄数组:list[str](str=bytes=i8*,elem_size=8 显式)存句柄值;list[t.CPtr] 特化下 append 会读零页崩溃(原因待查),list[str] 全库验证稳定。 # start() 后立即取 handle 存入,join/close 直接对句柄操作,不依赖 Thread 对象存续。 - handles: list[str] | t.CPtr = list[str](_mbuddy, 8) + handles: list[str]* = list[str](_mbuddy, 8) if handles is None: VLogger.error("run_llc_parallel: 线程句柄数组分配失败", "PhaseB") return 1 diff --git a/App/lib/Phase/Phase1/Phase1Main.vp b/App/lib/Phase/Phase1/Phase1Main.vp index 87f7927..1f4773c 100644 --- a/App/lib/Phase/Phase1/Phase1Main.vp +++ b/App/lib/Phase/Phase1/Phase1Main.vp @@ -234,7 +234,7 @@ def _BreakContainerCyclesInDeps(temp_dir: str) -> int: # Args: mb 内存池;includes_dir includes 根目录(仅用于失败诊断,路径以 store 为准) # Returns: ScanResult 指针(stdlib 分配,调用方负责释放);失败返回 None # ============================================================ -def _BuildReachableResult(mb: rawptr[memhub.MemBuddy], +def _BuildReachableResult(mb: memhub.MemBuddy*, includes_dir: str) -> rawptr[IncludesScanner.ScanResult]: """从 Sha1Store(仅可达 includes + App)构建可达 FileEntry 列表""" if mb is None: @@ -318,7 +318,7 @@ def _BuildReachableResult(mb: rawptr[memhub.MemBuddy], # Args: mb 内存池;includes_dir includes 目录路径;temp_dir 临时目录(保存 stub);log 日志器 # Returns: 0 成功,非 0 失败 # ============================================================ -def RunPhase1(mb: rawptr[memhub.MemBuddy], includes_dir: str, temp_dir: str, +def RunPhase1(mb: memhub.MemBuddy*, includes_dir: str, temp_dir: str, log: rawptr[VLogger.Logger]) -> int: """Phase1: 扫描 includes 目录,按需翻译并生成 stub""" if includes_dir is None or temp_dir is None: @@ -609,14 +609,14 @@ def RunPhase1(mb: rawptr[memhub.MemBuddy], includes_dir: str, temp_dir: str, src_buf_r[bytes_read_r] = 0 # 解析 AST - lx_r: rawptr[ast.Lexer] = ast.new_lexer(mb) + lx_r: ast.Lexer* = ast.new_lexer(mb) if lx_r is None: stdlib.free(src_buf_r) p1a_fl += 1 continue ast._lexer_init(lx_r, src_buf_r, mb) - tokens_r: rawptr[ast.Token] = ast.tokenize(lx_r) - tree_r: rawptr[ast.AST] = ast.parse_tokens(mb, tokens_r) + tokens_r: ast.Token* = ast.tokenize(lx_r) + tree_r: ast.AST* = ast.parse_tokens(mb, tokens_r) if tree_r is None: stdlib.free(src_buf_r) p1a_fl += 1 @@ -767,15 +767,15 @@ def RunPhase1(mb: rawptr[memhub.MemBuddy], includes_dir: str, temp_dir: str, continue if bytes_read_pv < Phase1.SRC_BUF_SIZE: src_buf_pv[bytes_read_pv] = 0 - lx_pv: rawptr[ast.Lexer] = ast.new_lexer(mb) + lx_pv: ast.Lexer* = ast.new_lexer(mb) if lx_pv is None: stdlib.free(src_buf_pv) p1bpre_failed += 1 VLogger.error(f"[Phase 1b-pre] {file_path_pv} | 词法器分配失败(OOM)", "Phase1") continue ast._lexer_init(lx_pv, src_buf_pv, mb) - tokens_pv: rawptr[ast.Token] = ast.tokenize(lx_pv) - tree_pv: rawptr[ast.AST] = ast.parse_tokens(mb, tokens_pv) + tokens_pv: ast.Token* = ast.tokenize(lx_pv) + tree_pv: ast.AST* = ast.parse_tokens(mb, tokens_pv) if tree_pv is None: stdlib.free(src_buf_pv) p1bpre_failed += 1 @@ -972,14 +972,14 @@ def RunPhase1(mb: rawptr[memhub.MemBuddy], includes_dir: str, temp_dir: str, src_buf[bytes_read] = 0 # 解析 AST - lx: rawptr[ast.Lexer] = ast.new_lexer(mb) + lx: ast.Lexer* = ast.new_lexer(mb) if lx is None: stdlib.free(src_buf) failed += 1 continue ast._lexer_init(lx, src_buf, mb) - tokens: rawptr[ast.Token] = ast.tokenize(lx) - tree: rawptr[ast.AST] = ast.parse_tokens(mb, tokens) + tokens: ast.Token* = ast.tokenize(lx) + tree: ast.AST* = ast.parse_tokens(mb, tokens) if tree is None: VLogger.error(f"AST 解析失败: {file_path}", "Phase1") stdlib.free(src_buf) diff --git a/App/lib/Phase/Phase1/Phase1Scan.vp b/App/lib/Phase/Phase1/Phase1Scan.vp index fe6b54a..9675e18 100644 --- a/App/lib/Phase/Phase1/Phase1Scan.vp +++ b/App/lib/Phase/Phase1/Phase1Scan.vp @@ -53,7 +53,7 @@ import lib.core.Gen.GenApi as GenApi # parent_names_buf 父类名扁平数组(每个 Phase1.CLASS_NAME_LEN 字节,无父类填 '\0');def_sha1s_buf 定义 SHA1 扁平数组(每个 Phase1.SHA1_LEN 字节) # Returns: 收集到的类数量,-1 失败 # ============================================================ -def _ScanClassInheritance(mb: rawptr[memhub.MemBuddy], +def _ScanClassInheritance(mb: memhub.MemBuddy*, result: rawptr[IncludesScanner.ScanResult], reachable_set: str, reachable_count: int, use_reachable: int, @@ -121,13 +121,13 @@ def _ScanClassInheritance(mb: rawptr[memhub.MemBuddy], src_buf[bytes_read] = 0 # 解析 AST - lx: rawptr[ast.Lexer] = ast.new_lexer(mb) + lx: ast.Lexer* = ast.new_lexer(mb) if lx is None: stdlib.free(src_buf) continue ast._lexer_init(lx, src_buf, mb) - tokens: rawptr[ast.Token] = ast.tokenize(lx) - tree: rawptr[ast.AST] = ast.parse_tokens(mb, tokens) + tokens: ast.Token* = ast.tokenize(lx) + tree: ast.AST* = ast.parse_tokens(mb, tokens) if tree is None: stdlib.free(src_buf) continue @@ -137,20 +137,20 @@ def _ScanClassInheritance(mb: rawptr[memhub.MemBuddy], if ch is not None: cn: sizet = len(ch) for ci in range(cn): - child: rawptr[ast.AST] = ch.get(ci) + child: ast.AST* = ch.get(ci) if child is None: continue kd: int = child.kind() if kd != ast.ASTKind.ClassDef: continue - cd: rawptr[ast.ClassDef] = rawptr[ast.ClassDef](child) + cd: ast.ClassDef* = ast.ClassDef*(child) if cd is None or cd.name is None: continue # 检测泛型类(有 type_params),记录文件索引以供 Phase 1a 预注册 if file_has_generic == 0: - tp_scan: list[str] | t.CPtr = cd.type_params + tp_scan: list[str]* = cd.type_params if tp_scan is not None: file_has_generic = 1 if generic_file_count_box is not None: @@ -252,12 +252,12 @@ def _BufHasGenericClassMarker(buf: bytes, blen: sizet) -> int: # _find_generic_template 遍历悬空内存 strcmp 崩溃。本函数先文本扫描(_BufHasGenericClassMarker,不 parse)筛选出含泛型类的文件, # 仅对命中文件用**永久池(perm_pool)**解析(模板节点与表直接进 perm_pool,跨 mark 永久存活、不占主 pool);重复注册由 _register_generic_template 内部查重跳过。 # ============================================================ -def _PreRegisterAllGenericTemplates(mb: rawptr[memhub.MemBuddy], +def _PreRegisterAllGenericTemplates(mb: memhub.MemBuddy*, result: rawptr[IncludesScanner.ScanResult]) -> int: """预注册全部 includes 文件的泛型类模板,返回处理到的泛型类数量""" if result is None or mb is None: return 0 - perm: rawptr[memhub.MemBuddy] = CompilerFactory.factory.PermPool + perm: memhub.MemBuddy* = CompilerFactory.factory.PermPool if perm is None: return 0 p1e_size: sizet = IncludesScanner.FileEntry.__sizeof__() @@ -294,13 +294,13 @@ def _PreRegisterAllGenericTemplates(mb: rawptr[memhub.MemBuddy], stdlib.free(src_buf_pg) continue # 泛型文件:永久池解析 → 注册模板(节点/表进 perm_pool,跨 reset 存活) - lx_pg: rawptr[ast.Lexer] = ast.new_lexer(perm) + lx_pg: ast.Lexer* = ast.new_lexer(perm) if lx_pg is None: stdlib.free(src_buf_pg) continue ast._lexer_init(lx_pg, src_buf_pg, perm) - tokens_pg: rawptr[ast.Token] = ast.tokenize(lx_pg) - tree_pg: rawptr[ast.AST] = ast.parse_tokens(perm, tokens_pg) + tokens_pg: ast.Token* = ast.tokenize(lx_pg) + tree_pg: ast.AST* = ast.parse_tokens(perm, tokens_pg) if tree_pg is None: stdlib.free(src_buf_pg) continue @@ -309,13 +309,13 @@ def _PreRegisterAllGenericTemplates(mb: rawptr[memhub.MemBuddy], if ch_pg is not None: cn_pg: sizet = len(ch_pg) for ci_pg in range(cn_pg): - child_pg: rawptr[ast.AST] = ch_pg.get(ci_pg) + child_pg: ast.AST* = ch_pg.get(ci_pg) if child_pg is None or child_pg.kind() != ast.ASTKind.ClassDef: continue - cd_pg: rawptr[ast.ClassDef] = rawptr[ast.ClassDef](child_pg) + cd_pg: ast.ClassDef* = ast.ClassDef*(child_pg) if cd_pg is None or cd_pg.name is None: continue - tp_pg: list[str] | t.CPtr = cd_pg.type_params + tp_pg: list[str]* = cd_pg.type_params if tp_pg is None: continue GenApi.set_current_file_type(file_path_pg) @@ -351,7 +351,7 @@ def _FindClassDefSha1(class_names_buf: bytes, def_sha1s_buf: bytes, # 命中即置 need_list/need_dict;误报无害(最多多编译两个空壳模块)。 # ============================================================ -def _AnnIsContainer(ann: rawptr[ast.AST]) -> int: +def _AnnIsContainer(ann: ast.AST*) -> int: """注解是否为 list/dict 容器(Name 裸名或 Subscript list[...]/dict[...]) 数组初始化(t.CArray[...] / 裸数组注解)返回 0,避免 _ScanTreeForContainers @@ -360,7 +360,7 @@ def _AnnIsContainer(ann: rawptr[ast.AST]) -> int: while ann is not None: ak_c: int = ann.kind() if ak_c == ast.ASTKind.Name: - nm_c: rawptr[ast.Name] = rawptr[ast.Name](ann) + nm_c: ast.Name* = ast.Name*(ann) if nm_c.id is not None: if string.strcmp(nm_c.id, "list") == 0: return 1 @@ -368,14 +368,14 @@ def _AnnIsContainer(ann: rawptr[ast.AST]) -> int: return 1 return 0 elif ak_c == ast.ASTKind.Subscript: - sub_c: rawptr[ast.Subscript] = rawptr[ast.Subscript](ann) + sub_c: ast.Subscript* = ast.Subscript*(ann) ann = sub_c.value else: return 0 return 0 -def _ScanTreeForContainers(node: rawptr[ast.AST], +def _ScanTreeForContainers(node: ast.AST*, need_list_box: t.CPtr, need_dict_box: t.CPtr, depth: int = 0): @@ -388,22 +388,22 @@ def _ScanTreeForContainers(node: rawptr[ast.AST], return k_s: int = node.kind() if k_s == ast.ASTKind.Name: - nm_s: rawptr[ast.Name] = rawptr[ast.Name](node) + nm_s: ast.Name* = ast.Name*(node) if nm_s.id is not None: if string.strcmp(nm_s.id, "list") == 0: need_list_box[0] = 1 elif string.strcmp(nm_s.id, "dict") == 0: need_dict_box[0] = 1 elif k_s == ast.ASTKind.Subscript: - sub_s: rawptr[ast.Subscript] = rawptr[ast.Subscript](node) + sub_s: ast.Subscript* = ast.Subscript*(node) _ScanTreeForContainers(sub_s.value, need_list_box, need_dict_box, depth + 1) _ScanTreeForContainers(sub_s.slice, need_list_box, need_dict_box, depth + 1) elif k_s == ast.ASTKind.BinOp: - bop_s: rawptr[ast.BinOp] = rawptr[ast.BinOp](node) + bop_s: ast.BinOp* = ast.BinOp*(node) _ScanTreeForContainers(bop_s.left, need_list_box, need_dict_box, depth + 1) _ScanTreeForContainers(bop_s.right, need_list_box, need_dict_box, depth + 1) elif k_s == ast.ASTKind.Call: - cl_s2: rawptr[ast.Call] = rawptr[ast.Call](node) + cl_s2: ast.Call* = ast.Call*(node) _ScanTreeForContainers(cl_s2.func, need_list_box, need_dict_box, depth + 1) cl_args_s: list[ast.AST*]* = cl_s2.args if cl_args_s is not None: @@ -420,7 +420,7 @@ def _ScanTreeForContainers(node: rawptr[ast.AST], 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) + asn_s: ast.Assign* = ast.Assign*(node) _ScanTreeForContainers(asn_s.value, need_list_box, need_dict_box, depth + 1) tgts_s: list[ast.AST*]* = asn_s.targets if tgts_s is not None: @@ -429,24 +429,24 @@ def _ScanTreeForContainers(node: rawptr[ast.AST], for i_t2 in range(nt_s): _ScanTreeForContainers(tgts_s.get(i_t2), need_list_box, need_dict_box, depth + 1) elif k_s == ast.ASTKind.AnnAssign: - aa_s2: rawptr[ast.AnnAssign] = rawptr[ast.AnnAssign](node) + aa_s2: ast.AnnAssign* = ast.AnnAssign*(node) _ScanTreeForContainers(aa_s2.annotation, need_list_box, need_dict_box, depth + 1) _ScanTreeForContainers(aa_s2.value, need_list_box, need_dict_box, depth + 1) elif k_s == ast.ASTKind.FunctionDef: - fn_s: rawptr[ast.FunctionDef] = rawptr[ast.FunctionDef](node) + fn_s: ast.FunctionDef* = ast.FunctionDef*(node) _ScanTreeForContainers(fn_s.returns, need_list_box, need_dict_box, depth + 1) - fn_args_s: rawptr[ast.Arguments] = rawptr[ast.Arguments](fn_s.args) + fn_args_s: ast.Arguments* = ast.Arguments*(fn_s.args) if fn_args_s is not None: fa_s: list[ast.AST*]* = fn_args_s.args if fa_s is not None: nf_s: sizet = len(fa_s) i_f2: sizet for i_f2 in range(nf_s): - arg_s: rawptr[ast.Arg] = rawptr[ast.Arg](fa_s.get(i_f2)) + arg_s: ast.Arg* = ast.Arg*(fa_s.get(i_f2)) if arg_s is not None: _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) + cd_s: ast.ClassDef* = ast.ClassDef*(node) bases_s: list[ast.AST*]* = cd_s.bases if bases_s is not None: nb_s: sizet = len(bases_s) @@ -454,10 +454,10 @@ def _ScanTreeForContainers(node: rawptr[ast.AST], for i_b2 in range(nb_s): _ScanTreeForContainers(bases_s.get(i_b2), need_list_box, need_dict_box, depth + 1) elif k_s == ast.ASTKind.Attribute: - at_s: rawptr[ast.Attribute] = rawptr[ast.Attribute](node) + at_s: ast.Attribute* = ast.Attribute*(node) _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) + tu_s: ast.Tuple* = ast.Tuple*(node) elts_s: list[ast.AST*]* = tu_s.elts if elts_s is not None: ne_s: sizet = len(elts_s) @@ -465,7 +465,7 @@ def _ScanTreeForContainers(node: rawptr[ast.AST], for i_e2 in range(ne_s): _ScanTreeForContainers(elts_s.get(i_e2), need_list_box, need_dict_box, depth + 1) elif k_s == ast.ASTKind.UnaryOp: - uop_s: rawptr[ast.UnaryOp] = rawptr[ast.UnaryOp](node) + uop_s: ast.UnaryOp* = ast.UnaryOp*(node) _ScanTreeForContainers(uop_s.operand, need_list_box, need_dict_box, depth + 1) elif k_s == ast.ASTKind.Expr: ex_s: rawptr[ast.Expr] = rawptr[ast.Expr](node) diff --git a/App/lib/Phase/Phase1/Phase1Topo.vp b/App/lib/Phase/Phase1/Phase1Topo.vp index 7cc0cce..5f7d7be 100644 --- a/App/lib/Phase/Phase1/Phase1Topo.vp +++ b/App/lib/Phase/Phase1/Phase1Topo.vp @@ -45,7 +45,7 @@ import lib.Phase.Phase1 as Phase1 # class_count 类数量;out_order 输出拓扑顺序的文件索引数组(调用者分配,int 数组);out_count 输出文件数量 # Returns: 0 成功,-1 失败 # ============================================================ -def _TopoSortFiles(mb: rawptr[memhub.MemBuddy], +def _TopoSortFiles(mb: memhub.MemBuddy*, result: rawptr[IncludesScanner.ScanResult], reachable_set: str, reachable_count: int, use_reachable: int, diff --git a/App/lib/Phase/Phase1/__init__.vp b/App/lib/Phase/Phase1/__init__.vp index 5afae0f..69ceea2 100644 --- a/App/lib/Phase/Phase1/__init__.vp +++ b/App/lib/Phase/Phase1/__init__.vp @@ -3,7 +3,7 @@ from stdint import * import memhub # 全局 mbuddy 指针 -_mbuddy: rawptr[memhub.MemBuddy] +_mbuddy: memhub.MemBuddy* # 源代码缓冲区大小(1MB) SRC_BUF_SIZE: t.CDefine = 1048576 diff --git a/App/lib/Phase/Phase2/__init__.vp b/App/lib/Phase/Phase2/__init__.vp index 794f41d..bd1de64 100644 --- a/App/lib/Phase/Phase2/__init__.vp +++ b/App/lib/Phase/Phase2/__init__.vp @@ -30,7 +30,7 @@ import lib.Stub.StubMerger.StubMergerTopo as StubMergerTopo import lib.Stub.StubGen.Converter as StubConverter # 全局 mbuddy 指针 -_mbuddy: rawptr[memhub.MemBuddy] +_mbuddy: memhub.MemBuddy* # 源代码缓冲区大小(1MB) SRC_BUF_SIZE: t.CDefine = 1048576 @@ -50,7 +50,7 @@ class SrcFileEntry: # Args: mb 内存池;dir_path 当前扫描目录;entries SrcFileEntry 数组;entry_size 单个条目大小(SrcFileEntry.__sizeof__());file_count 当前已收集的文件数;max_files 最大文件数 # Returns: 新的 file_count # ============================================================ -def _ScanDirForPyFiles(mb: rawptr[memhub.MemBuddy], +def _ScanDirForPyFiles(mb: memhub.MemBuddy*, dir_path: str, entries: SrcFileEntry | t.CPtr, entry_size: sizet, @@ -156,7 +156,7 @@ def _ScanDirForPyFiles(mb: rawptr[memhub.MemBuddy], # Kernel/intr/isr.s 定义 isr0/syscall_entry/_per_cpu 等符号)。 # TPV 不对 .s 翻译,直接用 llvm-mc 汇编为 .obj 参与链接。 # ============================================================ -def _ScanDirForAsmFiles(mb: rawptr[memhub.MemBuddy], +def _ScanDirForAsmFiles(mb: memhub.MemBuddy*, dir_path: str, entries: SrcFileEntry | t.CPtr, entry_size: sizet, @@ -256,7 +256,7 @@ def _ScanDirForAsmFiles(mb: rawptr[memhub.MemBuddy], # 才首次注册,reset_to(mark2) 会回收表与节点 → 后续查重/特化遍历悬空内存崩溃;App 文件数量少,mark2 前预注册的 AST 驻留内存可忽略。 # 重复注册由 _register_generic_template 查重跳过。 # ============================================================ -def _PreRegisterAppGenericTemplates(mb: rawptr[memhub.MemBuddy], +def _PreRegisterAppGenericTemplates(mb: memhub.MemBuddy*, entries: SrcFileEntry | t.CPtr, file_count: int, entry_size: sizet) -> int: @@ -290,16 +290,16 @@ def _PreRegisterAppGenericTemplates(mb: rawptr[memhub.MemBuddy], if bytes_read_pa < SRC_BUF_SIZE: src_buf_pa[bytes_read_pa] = 0 # 解析 AST(只解析,不完整翻译;用永久池使模板节点跨 mark2 reset 存活) - perm_pa: rawptr[memhub.MemBuddy] = CompilerFactory.factory.PermPool + perm_pa: memhub.MemBuddy* = CompilerFactory.factory.PermPool if perm_pa is None: perm_pa = mb - lx_pa: rawptr[ast.Lexer] = ast.new_lexer(perm_pa) + lx_pa: ast.Lexer* = ast.new_lexer(perm_pa) if lx_pa is None: stdlib.free(src_buf_pa) continue ast._lexer_init(lx_pa, src_buf_pa, perm_pa) - tokens_pa: rawptr[ast.Token] = ast.tokenize(lx_pa) - tree_pa: rawptr[ast.AST] = ast.parse_tokens(perm_pa, tokens_pa) + tokens_pa: ast.Token* = ast.tokenize(lx_pa) + tree_pa: ast.AST* = ast.parse_tokens(perm_pa, tokens_pa) if tree_pa is None: stdlib.free(src_buf_pa) continue @@ -308,13 +308,13 @@ def _PreRegisterAppGenericTemplates(mb: rawptr[memhub.MemBuddy], if ch_pa is not None: cn_pa: sizet = len(ch_pa) for ci_pa in range(cn_pa): - child_pa: rawptr[ast.AST] = ch_pa.get(ci_pa) + child_pa: ast.AST* = ch_pa.get(ci_pa) if child_pa is None or child_pa.kind() != ast.ASTKind.ClassDef: continue - cd_pa: rawptr[ast.ClassDef] = rawptr[ast.ClassDef](child_pa) + cd_pa: ast.ClassDef* = ast.ClassDef*(child_pa) if cd_pa is None or cd_pa.name is None: continue - tp_pa: list[str] | t.CPtr = cd_pa.type_params + tp_pa: list[str]* = cd_pa.type_params if tp_pa is None: continue GenApi.set_current_file_type(ent_pa.Path) @@ -608,7 +608,7 @@ def _PhaseADumpFailGraph(temp_dir: str, td_len: sizet, path: str, sha1: str) -> stdio.fflush(None) -def RunMultiFileProject(mb: rawptr[memhub.MemBuddy], +def RunMultiFileProject(mb: memhub.MemBuddy*, source_dir: str, temp_dir: str, output_dir: str, cc_cmd: str, cc_flags: str, linker_cmd: str, linker_flags: str, linker_output: str, @@ -793,15 +793,15 @@ def RunMultiFileProject(mb: rawptr[memhub.MemBuddy], continue if bytes_read_vp2 < SRC_BUF_SIZE: src_buf_vp2[bytes_read_vp2] = 0 - lx_vp2: rawptr[ast.Lexer] = ast.new_lexer(mb) + lx_vp2: ast.Lexer* = ast.new_lexer(mb) if lx_vp2 is None: stdlib.free(src_buf_vp2) vpi_failed_p2 += 1 VLogger.error(f"[Phase A-pre-vpi] {ent_vp2.Path} | 词法器分配失败(OOM)", "PhaseA") continue ast._lexer_init(lx_vp2, src_buf_vp2, mb) - tokens_vp2: rawptr[ast.Token] = ast.tokenize(lx_vp2) - tree_vp2: rawptr[ast.AST] = ast.parse_tokens(mb, tokens_vp2) + tokens_vp2: ast.Token* = ast.tokenize(lx_vp2) + tree_vp2: ast.AST* = ast.parse_tokens(mb, tokens_vp2) if tree_vp2 is None: stdlib.free(src_buf_vp2) vpi_failed_p2 += 1 @@ -1348,7 +1348,7 @@ def RunMultiFileProject(mb: rawptr[memhub.MemBuddy], # 拓扑排序可达 includes:被依赖模块先完整翻译。跨模块 vtable 生成 # 需要依赖模块的函数 TypeStr 已注册到全局表(如 astaux 继承 base 的 AST) - topo_idx: sizet | t.CPtr = (sizet | t.CPtr)(stdlib.malloc(8 * (store_count_mi + 1))) + topo_idx: sizet* = (sizet*)(stdlib.malloc(8 * (store_count_mi + 1))) topo_count: int = 0 if topo_idx is None: VLogger.error("拓扑排序索引分配失败,终止编译", "PhaseB+") diff --git a/App/lib/Projectrans/Utils.vp b/App/lib/Projectrans/Utils.vp index 4ebb903..cdd09c3 100644 --- a/App/lib/Projectrans/Utils.vp +++ b/App/lib/Projectrans/Utils.vp @@ -15,7 +15,7 @@ import w32.fileio as fileio # ============================================================ # 全局 mbuddy 指针 -_mbuddy: rawptr[memhub.MemBuddy] +_mbuddy: memhub.MemBuddy* # ============================================================ @@ -31,7 +31,7 @@ def nibble_to_hex_char(n: int, uppercase: int) -> char: # ============================================================ # bytes_to_hex - 字节序列转十六进制字符串 # ============================================================ -def bytes_to_hex(pool: rawptr[memhub.MemBuddy], +def bytes_to_hex(pool: memhub.MemBuddy*, digest: bytes, nbytes: sizet, uppercase: int, @@ -63,7 +63,7 @@ def bytes_to_hex(pool: rawptr[memhub.MemBuddy], # ============================================================ # compute_sha1 - 计算字符串的 SHA1,返回前 16 个十六进制字符(与 Projectrans.py 一致) # ============================================================ -def compute_sha1(pool: rawptr[memhub.MemBuddy], content: str) -> str: +def compute_sha1(pool: memhub.MemBuddy*, content: str) -> str: """计算字符串的 SHA1,返回前 16 个十六进制字符(用于文件命名)""" if content is None or pool is None: return None diff --git a/App/lib/Stub/StubGen/Converter.vp b/App/lib/Stub/StubGen/Converter.vp index d7e4177..0772eeb 100644 --- a/App/lib/Stub/StubGen/Converter.vp +++ b/App/lib/Stub/StubGen/Converter.vp @@ -20,22 +20,22 @@ import sys # 用于 .vpi 存根文件生成时计算 BinOp 表达式(如 A | B, A + B)的整数值。 # 支持 BitOr/BitAnd/Add/Sub 以及嵌套的 Name(引用已注册的 CDefine 常量)。 # ============================================================ -def _eval_binop_valid(node: rawptr[ast.AST]) -> int: +def _eval_binop_valid(node: ast.AST*) -> int: """检查 BinOp 节点是否可计算(所有叶子节点都是常量或已注册的 CDefine)""" if node is None: return 0 k: int = node.kind() if k == ast.ASTKind.Constant: - cn: rawptr[ast.Constant] = rawptr[ast.Constant](node) + cn: ast.Constant* = ast.Constant*(node) if cn.const_kind == ast.CONST_INT: return 1 return 0 if k == ast.ASTKind.UnaryOp: - uop: rawptr[ast.UnaryOp] = rawptr[ast.UnaryOp](node) + uop: ast.UnaryOp* = ast.UnaryOp*(node) if uop.operand is not None: return _eval_binop_valid(uop.operand) return 0 if k == ast.ASTKind.BinOp: - bop: rawptr[ast.BinOp] = rawptr[ast.BinOp](node) + bop: ast.BinOp* = ast.BinOp*(node) if bop.left is not None and bop.right is not None: if _eval_binop_valid(bop.left) != 0: if _eval_binop_valid(bop.right) != 0: @@ -43,7 +43,7 @@ def _eval_binop_valid(node: rawptr[ast.AST]) -> int: return 0 if k == ast.ASTKind.Name: # Name 引用:检查是否是已注册的 CDefine 常量 - nm: rawptr[ast.Name] = rawptr[ast.Name](node) + nm: ast.Name* = ast.Name*(node) if nm.id is not None: # 从本地 CDefine 表查找 val: int = _lookup_cdefine_for_pyi(nm.id) @@ -53,18 +53,18 @@ def _eval_binop_valid(node: rawptr[ast.AST]) -> int: return 0 -def _eval_binop_int(node: rawptr[ast.AST]) -> int64: +def _eval_binop_int(node: ast.AST*) -> int64: """递归计算 BinOp 节点的整数值(64 位,避免大整数 CDefine 截断)""" if node is None: return 0 k: int = node.kind() if k == ast.ASTKind.Constant: - cn: rawptr[ast.Constant] = rawptr[ast.Constant](node) + cn: ast.Constant* = ast.Constant*(node) if cn.const_kind == ast.CONST_INT: return cn.int_val return 0 if k == ast.ASTKind.UnaryOp: - uop: rawptr[ast.UnaryOp] = rawptr[ast.UnaryOp](node) + uop: ast.UnaryOp* = ast.UnaryOp*(node) if uop.op == ast.OpKind.USub and uop.operand is not None: return -_eval_binop_int(uop.operand) if uop.op == ast.OpKind.UAdd and uop.operand is not None: @@ -73,7 +73,7 @@ def _eval_binop_int(node: rawptr[ast.AST]) -> int64: return ~_eval_binop_int(uop.operand) return 0 if k == ast.ASTKind.BinOp: - bop: rawptr[ast.BinOp] = rawptr[ast.BinOp](node) + bop: ast.BinOp* = ast.BinOp*(node) if bop.left is None or bop.right is None: return 0 lv: int64 = _eval_binop_int(bop.left) @@ -91,7 +91,7 @@ def _eval_binop_int(node: rawptr[ast.AST]) -> int64: if bop.op == ast.OpKind.RShift: return lv >> rv return 0 if k == ast.ASTKind.Name: - nm: rawptr[ast.Name] = rawptr[ast.Name](node) + nm: ast.Name* = ast.Name*(node) if nm.id is not None: return _lookup_cdefine_for_pyi(nm.id) return 0 @@ -130,13 +130,13 @@ def _lookup_cdefine_for_pyi(name: str) -> int64: return 0 -def _eval_cdefine_value_cache(node: rawptr[ast.AST]) -> int64: +def _eval_cdefine_value_cache(node: ast.AST*) -> int64: """求值 CDefine 值(Constant/UnaryOp/BinOp/Call/Name),供 vpi 预处理注册缓存""" if node is None: return 0 k: int = node.kind() if k == ast.ASTKind.Constant: - cn_c: rawptr[ast.Constant] = rawptr[ast.Constant](node) + cn_c: ast.Constant* = ast.Constant*(node) if cn_c.const_kind == ast.CONST_INT: return cn_c.int_val if cn_c.const_kind == ast.CONST_BOOL: @@ -148,12 +148,12 @@ def _eval_cdefine_value_cache(node: rawptr[ast.AST]) -> int64: if k == ast.ASTKind.BinOp: return _eval_binop_int(node) if k == ast.ASTKind.Call: - cl_c: rawptr[ast.Call] = rawptr[ast.Call](node) + cl_c: ast.Call* = ast.Call*(node) if cl_c.args is not None and len(cl_c.args) > 0: return _eval_cdefine_value_cache(cl_c.args.get(0)) return 0 if k == ast.ASTKind.Name: - nm_c: rawptr[ast.Name] = rawptr[ast.Name](node) + nm_c: ast.Name* = ast.Name*(node) if nm_c.id is not None: return _lookup_cdefine_for_pyi(nm_c.id) return 0 @@ -214,7 +214,7 @@ def _PyiIndent(buf: bytes, buf_size: sizet, pos: sizet, # 让下游按错误结果解析(与 TPC 落到未知节点 fail-fast 同语义)。 # ============================================================ def _PyiBinOpOpText(buf: bytes, buf_size: sizet, pos: sizet, - op: int, node: rawptr[ast.AST]) -> sizet: + op: int, node: ast.AST*) -> sizet: """按运算符种类输出 " OP " 文本,表外运算符 fail-fast""" if op == ast.OpKind.BitOr: return _PyiEmit(buf, buf_size, pos, " | ") if op == ast.OpKind.Add: return _PyiEmit(buf, buf_size, pos, " + ") @@ -239,7 +239,7 @@ def _PyiBinOpOpText(buf: bytes, buf_size: sizet, pos: sizet, # TPC 额外有 Index 分支(vast 遗留类,解析器不产出该节点)。 # ============================================================ def _PyiTypeStr(buf: bytes, buf_size: sizet, pos: sizet, - annot: rawptr[ast.AST], + annot: ast.AST*, depth: int = 0) -> sizet: """递归生成类型注解字符串,返回新的 pos""" # 递归深度守卫:AST 损坏成自引用环(Attribute.value/Subscript.slice/ @@ -255,14 +255,14 @@ def _PyiTypeStr(buf: bytes, buf_size: sizet, pos: sizet, # Name: 简单类型名 (如 int, str, MyClass) if k == ast.ASTKind.Name: - nm: rawptr[ast.Name] = rawptr[ast.Name](annot) + nm: ast.Name* = ast.Name*(annot) if nm.id is not None: return _PyiEmit(buf, buf_size, pos, nm.id) return _PyiEmit(buf, buf_size, pos, "int") # Attribute: 属性引用 (如 int, memhub.MemBuddy) if k == ast.ASTKind.Attribute: - at: rawptr[ast.Attribute] = rawptr[ast.Attribute](annot) + at: ast.Attribute* = ast.Attribute*(annot) pos = _PyiTypeStr(buf, buf_size, pos, at.value, depth + 1) pos = _PyiEmit(buf, buf_size, pos, ".") if at.attr is not None: @@ -271,7 +271,7 @@ def _PyiTypeStr(buf: bytes, buf_size: sizet, pos: sizet, # Subscript: 下标类型 (如 list[int], t.CArray[elem, count]) if k == ast.ASTKind.Subscript: - sub: rawptr[ast.Subscript] = rawptr[ast.Subscript](annot) + sub: ast.Subscript* = ast.Subscript*(annot) pos = _PyiTypeStr(buf, buf_size, pos, sub.value, depth + 1) pos = _PyiEmit(buf, buf_size, pos, "[") pos = _PyiTypeStr(buf, buf_size, pos, sub.slice, depth + 1) @@ -282,7 +282,7 @@ def _PyiTypeStr(buf: bytes, buf_size: sizet, pos: sizet, # 2 * ZHUFF_MAX_CODES;条件宏实参 MASK_BYTE & 0x0F)。 # 运算符文本按 _PyiBinOpOpText 输出,与 TPC 的运算符表逐字节一致。 if k == ast.ASTKind.BinOp: - bop: rawptr[ast.BinOp] = rawptr[ast.BinOp](annot) + bop: ast.BinOp* = ast.BinOp*(annot) pos = _PyiTypeStr(buf, buf_size, pos, bop.left, depth + 1) pos = _PyiBinOpOpText(buf, buf_size, pos, bop.op, annot) pos = _PyiTypeStr(buf, buf_size, pos, bop.right, depth + 1) @@ -292,7 +292,7 @@ def _PyiTypeStr(buf: bytes, buf_size: sizet, pos: sizet, # 输出与 TPC 的 UnaryOp 分支逐字节一致:Not → "not "、Invert → "~"、 # USub → "-";其余一元运算符两侧都不支持 → fail-fast(不静默写错符号)。 if k == ast.ASTKind.UnaryOp: - uop_t: rawptr[ast.UnaryOp] = rawptr[ast.UnaryOp](annot) + uop_t: ast.UnaryOp* = ast.UnaryOp*(annot) if uop_t.op == ast.OpKind.Not: pos = _PyiEmit(buf, buf_size, pos, "not ") elif uop_t.op == ast.OpKind.Invert: @@ -351,7 +351,7 @@ def _PyiTypeStr(buf: bytes, buf_size: sizet, pos: sizet, # Constant: 字符串前向引用 (如 'MyClass')、None 或数字常量(CArray count) if k == ast.ASTKind.Constant: - cn: rawptr[ast.Constant] = rawptr[ast.Constant](annot) + cn: ast.Constant* = ast.Constant*(annot) if cn.const_kind == ast.CONST_STR: pos = _PyiEmit(buf, buf_size, pos, "'") if cn.str_val is not None: @@ -378,7 +378,7 @@ def _PyiTypeStr(buf: bytes, buf_size: sizet, pos: sizet, # 的参数表成型为 List(TypeGenResolve 的类型名提取同样按 List 递归), # 故必须输出 "[a, b]" 形式——缺失该分支时该节点落入未知类型 fail-fast。 if k == ast.ASTKind.List: - lst: rawptr[ast.List] = rawptr[ast.List](annot) + lst: ast.List* = ast.List*(annot) pos = _PyiEmit(buf, buf_size, pos, "[") if lst.elts is not None: lst_elts: list[ast.AST*]* = lst.elts @@ -387,7 +387,7 @@ def _PyiTypeStr(buf: bytes, buf_size: sizet, pos: sizet, while li < ln: if li > 0: pos = _PyiEmit(buf, buf_size, pos, ", ") - le: rawptr[ast.AST] = lst_elts.get(li) + le: ast.AST* = lst_elts.get(li) pos = _PyiTypeStr(buf, buf_size, pos, le, depth + 1) li += 1 pos = _PyiEmit(buf, buf_size, pos, "]") @@ -395,7 +395,7 @@ def _PyiTypeStr(buf: bytes, buf_size: sizet, pos: sizet, # Tuple: 多参数下标 (如 Dict[str, int]) if k == ast.ASTKind.Tuple: - tup: rawptr[ast.Tuple] = rawptr[ast.Tuple](annot) + tup: ast.Tuple* = ast.Tuple*(annot) if tup.elts is not None: tup_elts: list[ast.AST*]* = tup.elts tn: sizet = len(tup_elts) @@ -403,14 +403,14 @@ def _PyiTypeStr(buf: bytes, buf_size: sizet, pos: sizet, while ti < tn: if ti > 0: pos = _PyiEmit(buf, buf_size, pos, ", ") - el: rawptr[ast.AST] = tup_elts.get(ti) + el: ast.AST* = tup_elts.get(ti) pos = _PyiTypeStr(buf, buf_size, pos, el, depth + 1) ti += 1 return pos # Call: 函数调用表达式 (用于装饰器如 @t.NoVTable()) if k == ast.ASTKind.Call: - cl: rawptr[ast.Call] = rawptr[ast.Call](annot) + cl: ast.Call* = ast.Call*(annot) pos = _PyiTypeStr(buf, buf_size, pos, cl.func, depth + 1) pos = _PyiEmit(buf, buf_size, pos, "(") if cl.args is not None: @@ -420,7 +420,7 @@ def _PyiTypeStr(buf: bytes, buf_size: sizet, pos: sizet, while cai < can: if cai > 0: pos = _PyiEmit(buf, buf_size, pos, ", ") - ca: rawptr[ast.AST] = cl_args.get(cai) + ca: ast.AST* = cl_args.get(cai) pos = _PyiTypeStr(buf, buf_size, pos, ca, depth + 1) cai += 1 pos = _PyiEmit(buf, buf_size, pos, ")") @@ -441,7 +441,7 @@ def _PyiTypeStr(buf: bytes, buf_size: sizet, pos: sizet, # 支持: Constant(int/str/bool/None), Name(CDefine 常量), UnaryOp。 # ============================================================ def _PyiDefaultStr(buf: bytes, buf_size: sizet, pos: sizet, - node: rawptr[ast.AST], + node: ast.AST*, depth: int = 0) -> sizet: """生成默认值表达式文本到 buf,返回新的 pos""" # 递归深度守卫:AST 损坏成自引用环时 fail-fast 终止(同 _PyiTypeStr) @@ -454,7 +454,7 @@ def _PyiDefaultStr(buf: bytes, buf_size: sizet, pos: sizet, k: int = node.kind() # Constant: 数字/字符串/bool/None 直接输出字面量 if k == ast.ASTKind.Constant: - cn: rawptr[ast.Constant] = rawptr[ast.Constant](node) + cn: ast.Constant* = ast.Constant*(node) if cn.const_kind == ast.CONST_INT or cn.const_kind == ast.CONST_CHAR: num_buf_dv: str = stdlib.malloc(24) if num_buf_dv is not None: @@ -477,14 +477,14 @@ def _PyiDefaultStr(buf: bytes, buf_size: sizet, pos: sizet, # Name: CDefine 常量名(如 share: ULONG = SHARE_READ) if k == ast.ASTKind.Name: - nm: rawptr[ast.Name] = rawptr[ast.Name](node) + nm: ast.Name* = ast.Name*(node) if nm.id is not None: return _PyiEmit(buf, buf_size, pos, nm.id) return pos # UnaryOp: 一元运算(如 -1, ~0) if k == ast.ASTKind.UnaryOp: - uop: rawptr[ast.UnaryOp] = rawptr[ast.UnaryOp](node) + uop: ast.UnaryOp* = ast.UnaryOp*(node) if uop.op == ast.OpKind.USub: pos = _PyiEmit(buf, buf_size, pos, "-") elif uop.op == ast.OpKind.UAdd: @@ -515,14 +515,14 @@ def _PyiCreturnArgs(decorators: list[ast.AST*]*) -> list[ast.AST*]*: dn: sizet = len(decorators) di: sizet = 0 while di < dn: - dnode: rawptr[ast.AST] = decorators.get(di) + dnode: ast.AST* = decorators.get(di) di += 1 if dnode is None or dnode.kind() != ast.ASTKind.Call: continue - dcall: rawptr[ast.Call] = rawptr[ast.Call](dnode) + dcall: ast.Call* = ast.Call*(dnode) if dcall.func is None or dcall.func.kind() != ast.ASTKind.Attribute: continue - dat: rawptr[ast.Attribute] = rawptr[ast.Attribute](dcall.func) + dat: ast.Attribute* = ast.Attribute*(dcall.func) if dat.attr is not None and string.strcmp(dat.attr, "CReturn") == 0: return dcall.args return None @@ -534,7 +534,7 @@ def _PyiCreturnArgs(decorators: list[ast.AST*]*) -> list[ast.AST*]*: # 格式: def name(param: Type, ...) -> ReturnType: pass # ============================================================ def _PyiFunction(buf: bytes, buf_size: sizet, pos: sizet, - fn: rawptr[ast.FunctionDef], + fn: ast.FunctionDef*, indent_level: int, class_name: str) -> sizet: """生成函数签名到 buf,返回新的 pos""" # 装饰器 @@ -543,7 +543,7 @@ def _PyiFunction(buf: bytes, buf_size: sizet, pos: sizet, dn: sizet = len(fn_decorator_list) di: sizet = 0 while di < dn: - dec: rawptr[ast.AST] = fn_decorator_list.get(di) + dec: ast.AST* = fn_decorator_list.get(di) if dec is not None: pos = _PyiIndent(buf, buf_size, pos, indent_level) pos = _PyiEmit(buf, buf_size, pos, "@") @@ -558,9 +558,9 @@ def _PyiFunction(buf: bytes, buf_size: sizet, pos: sizet, pos = _PyiEmit(buf, buf_size, pos, "(") # 参数列表 - args_node: rawptr[ast.AST] = fn.args + args_node: ast.AST* = fn.args if args_node is not None: - args: rawptr[ast.Arguments] = rawptr[ast.Arguments](args_node) + args: ast.Arguments* = ast.Arguments*(args_node) first: int = 1 # 位置参数 @@ -579,7 +579,7 @@ def _PyiFunction(buf: bytes, buf_size: sizet, pos: sizet, if first == 0: pos = _PyiEmit(buf, buf_size, pos, ", ") first = 0 - ag: rawptr[ast.Arg] = rawptr[ast.Arg](args_args.get(ai)) + ag: ast.Arg* = ast.Arg*(args_args.get(ai)) if ag.arg is not None: pos = _PyiEmit(buf, buf_size, pos, ag.arg) if ag.annotation is not None: @@ -587,7 +587,7 @@ def _PyiFunction(buf: bytes, buf_size: sizet, pos: sizet, pos = _PyiTypeStr(buf, buf_size, pos, ag.annotation) if arg_defaults is not None and an - dn <= ai: di: sizet = ai - (an - dn) - dnode: rawptr[ast.AST] = arg_defaults.get(di) + dnode: ast.AST* = arg_defaults.get(di) if dnode is not None: pos = _PyiEmit(buf, buf_size, pos, " = ") pos = _PyiDefaultStr(buf, buf_size, pos, dnode) @@ -599,7 +599,7 @@ def _PyiFunction(buf: bytes, buf_size: sizet, pos: sizet, pos = _PyiEmit(buf, buf_size, pos, ", ") first = 0 pos = _PyiEmit(buf, buf_size, pos, "*") - va: rawptr[ast.Arg] = rawptr[ast.Arg](args.vararg) + va: ast.Arg* = ast.Arg*(args.vararg) if va.arg is not None: pos = _PyiEmit(buf, buf_size, pos, va.arg) @@ -609,7 +609,7 @@ def _PyiFunction(buf: bytes, buf_size: sizet, pos: sizet, pos = _PyiEmit(buf, buf_size, pos, ", ") first = 0 pos = _PyiEmit(buf, buf_size, pos, "**") - kw: rawptr[ast.Arg] = rawptr[ast.Arg](args.kwarg) + kw: ast.Arg* = ast.Arg*(args.kwarg) if kw.arg is not None: pos = _PyiEmit(buf, buf_size, pos, kw.arg) @@ -647,7 +647,7 @@ def _PyiFunction(buf: bytes, buf_size: sizet, pos: sizet, # def method(self: Name, ...) -> RetType: pass # ============================================================ def _PyiClass(buf: bytes, buf_size: sizet, pos: sizet, - cls: rawptr[ast.ClassDef], indent_level: int) -> sizet: + cls: ast.ClassDef*, indent_level: int) -> sizet: """生成类定义到 buf,返回新的 pos""" # 装饰器 if cls.decorator_list is not None: @@ -655,7 +655,7 @@ def _PyiClass(buf: bytes, buf_size: sizet, pos: sizet, dcn: sizet = len(cls_decorator_list) dci: sizet = 0 while dci < dcn: - ddec: rawptr[ast.AST] = cls_decorator_list.get(dci) + ddec: ast.AST* = cls_decorator_list.get(dci) if ddec is not None: pos = _PyiIndent(buf, buf_size, pos, indent_level) pos = _PyiEmit(buf, buf_size, pos, "@") @@ -694,7 +694,7 @@ def _PyiClass(buf: bytes, buf_size: sizet, pos: sizet, while bi < bn: if bi > 0: pos = _PyiEmit(buf, buf_size, pos, ", ") - base: rawptr[ast.AST] = cls_bases.get(bi) + base: ast.AST* = cls_bases.get(bi) pos = _PyiTypeStr(buf, buf_size, pos, base) bi += 1 pos = _PyiEmit(buf, buf_size, pos, ")") @@ -709,13 +709,13 @@ def _PyiClass(buf: bytes, buf_size: sizet, pos: sizet, cn: sizet = len(cls_children) ci: sizet = 0 while ci < cn: - stmt: rawptr[ast.AST] = cls_children.get(ci) + stmt: ast.AST* = cls_children.get(ci) if stmt is not None: sk: int = stmt.kind() # 方法 if sk == ast.ASTKind.FunctionDef: - mfn: rawptr[ast.FunctionDef] = rawptr[ast.FunctionDef](stmt) + mfn: ast.FunctionDef* = ast.FunctionDef*(stmt) # __init__ 方法:先提取 self.x: Type 属性 if mfn.name is not None and string.strcmp(mfn.name, "__init__") == 0: if mfn.children is not None: @@ -723,14 +723,14 @@ def _PyiClass(buf: bytes, buf_size: sizet, pos: sizet, icn: sizet = len(mfn_children) ici: sizet = 0 while ici < icn: - ibody: rawptr[ast.AST] = mfn_children.get(ici) + ibody: ast.AST* = mfn_children.get(ici) if ibody is not None and ibody.kind() == ast.ASTKind.AnnAssign: - iaa: rawptr[ast.AnnAssign] = rawptr[ast.AnnAssign](ibody) + iaa: ast.AnnAssign* = ast.AnnAssign*(ibody) if iaa.target is not None and iaa.target.kind() == ast.ASTKind.Attribute: - iat: rawptr[ast.Attribute] = rawptr[ast.Attribute](iaa.target) + iat: ast.Attribute* = ast.Attribute*(iaa.target) # 检查 target.value 是否为 Name("self") if iat.value is not None and iat.value.kind() == ast.ASTKind.Name: - iavn: rawptr[ast.Name] = rawptr[ast.Name](iat.value) + iavn: ast.Name* = ast.Name*(iat.value) if iavn.id is None or string.strcmp(iavn.id, "self") != 0: ici += 1 continue @@ -747,9 +747,9 @@ def _PyiClass(buf: bytes, buf_size: sizet, pos: sizet, # 带注解的属性 elif sk == ast.ASTKind.AnnAssign: - aa: rawptr[ast.AnnAssign] = rawptr[ast.AnnAssign](stmt) + aa: ast.AnnAssign* = ast.AnnAssign*(stmt) if aa.target is not None and aa.target.kind() == ast.ASTKind.Name: - tn: rawptr[ast.Name] = rawptr[ast.Name](aa.target) + tn: ast.Name* = ast.Name*(aa.target) pos = _PyiIndent(buf, buf_size, pos, indent_level + 1) if tn.id is not None: pos = _PyiEmit(buf, buf_size, pos, tn.id) @@ -760,7 +760,7 @@ def _PyiClass(buf: bytes, buf_size: sizet, pos: sizet, # 嵌套类 elif sk == ast.ASTKind.ClassDef: - ncls: rawptr[ast.ClassDef] = rawptr[ast.ClassDef](stmt) + ncls: ast.ClassDef* = ast.ClassDef*(stmt) pos = _PyiClass(buf, buf_size, pos, ncls, indent_level + 1) has_member = 1 ci += 1 @@ -779,7 +779,7 @@ def _PyiClass(buf: bytes, buf_size: sizet, pos: sizet, # Args: mb 内存池(保留以符合调用约定,实际未使用);tree AST Module 根节点;rel_path 源文件路径(仅用于报错归因的"当前文件",应传绝对路径以便 fatal_error 读取源码行);buf 输出缓冲区;buf_size 缓冲区大小 # Returns: 写入的字节数(0 表示失败) # ============================================================ -def _GeneratePyiFromAst(mb: rawptr[memhub.MemBuddy], tree: rawptr[ast.AST], +def _GeneratePyiFromAst(mb: memhub.MemBuddy*, tree: ast.AST*, rel_path: str, buf: bytes, buf_size: sizet) -> sizet: """从 AST 生成 .vpi 存根文件内容到 buf""" @@ -809,14 +809,14 @@ def _GeneratePyiFromAst(mb: rawptr[memhub.MemBuddy], tree: rawptr[ast.AST], # 第一遍:数本文件 t.CDefine 声明数(C 数组需先定长分配) _g_pyi_cdef_count = 0 for pci0 in range(pcn): - stmt_pc0: rawptr[ast.AST] = pre_children.get(pci0) + stmt_pc0: ast.AST* = pre_children.get(pci0) if stmt_pc0 is not None and stmt_pc0.kind() == ast.ASTKind.AnnAssign: - aa_pc0: rawptr[ast.AnnAssign] = rawptr[ast.AnnAssign](stmt_pc0) + aa_pc0: ast.AnnAssign* = ast.AnnAssign*(stmt_pc0) if aa_pc0.target is not None and aa_pc0.target.kind() == ast.ASTKind.Name \ and aa_pc0.annotation is not None: - tgt_pc0: rawptr[ast.Name] = rawptr[ast.Name](aa_pc0.target) + tgt_pc0: ast.Name* = ast.Name*(aa_pc0.target) if tgt_pc0.id is not None and aa_pc0.annotation.kind() == ast.ASTKind.Attribute: - ann_pc0: rawptr[ast.Attribute] = rawptr[ast.Attribute](aa_pc0.annotation) + ann_pc0: ast.Attribute* = ast.Attribute*(aa_pc0.annotation) if ann_pc0.attr is not None and string.strcmp(ann_pc0.attr, "CDefine") == 0: _g_pyi_cdef_count += 1 if _g_pyi_cdef_count > 0: @@ -826,14 +826,14 @@ def _GeneratePyiFromAst(mb: rawptr[memhub.MemBuddy], tree: rawptr[ast.AST], pci: sizet = 0 cdi: int = 0 for pci in range(pcn): - stmt_pc: rawptr[ast.AST] = pre_children.get(pci) + stmt_pc: ast.AST* = pre_children.get(pci) if stmt_pc is not None and stmt_pc.kind() == ast.ASTKind.AnnAssign: - aa_pc: rawptr[ast.AnnAssign] = rawptr[ast.AnnAssign](stmt_pc) + aa_pc: ast.AnnAssign* = ast.AnnAssign*(stmt_pc) if aa_pc.target is not None and aa_pc.target.kind() == ast.ASTKind.Name \ and aa_pc.annotation is not None: - tgt_pc: rawptr[ast.Name] = rawptr[ast.Name](aa_pc.target) + tgt_pc: ast.Name* = ast.Name*(aa_pc.target) if tgt_pc.id is not None and aa_pc.annotation.kind() == ast.ASTKind.Attribute: - ann_pc: rawptr[ast.Attribute] = rawptr[ast.Attribute](aa_pc.annotation) + ann_pc: ast.Attribute* = ast.Attribute*(aa_pc.annotation) if ann_pc.attr is not None and string.strcmp(ann_pc.attr, "CDefine") == 0: if _g_pyi_cdef_names is not None and _g_pyi_cdef_vals is not None: slot_pc: str | t.CPtr = t.CPtr(uint64(_g_pyi_cdef_names) + cdi * 8) @@ -856,14 +856,14 @@ def _GeneratePyiFromAst(mb: rawptr[memhub.MemBuddy], tree: rawptr[ast.AST], has_import_t: int = 0 has_import_c: int = 0 for i in range(n): - stmt: rawptr[ast.AST] = tree_children.get(i) + stmt: ast.AST* = tree_children.get(i) if stmt is not None and stmt.kind() == ast.ASTKind.Import: - imp: rawptr[ast.Import] = rawptr[ast.Import](stmt) + imp: ast.Import* = ast.Import*(stmt) if imp.names is not None: imp_names: list[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)) + al: ast.Alias* = ast.Alias*(imp_names.get(ai)) if al is not None and al.name is not None: if string.strcmp(al.name, "t") == 0: has_import_t = 1 @@ -888,7 +888,7 @@ def _GeneratePyiFromAst(mb: rawptr[memhub.MemBuddy], tree: rawptr[ast.AST], # Import 语句 if k == ast.ASTKind.Import: - imp2: rawptr[ast.Import] = rawptr[ast.Import](stmt) + imp2: ast.Import* = ast.Import*(stmt) pos = _PyiEmit(buf, buf_size, pos, "import ") if imp2.names is not None: imp2_names: list[ast.AST*]* = imp2.names @@ -897,7 +897,7 @@ def _GeneratePyiFromAst(mb: rawptr[memhub.MemBuddy], tree: rawptr[ast.AST], while ai2 < an2: if ai2 > 0: pos = _PyiEmit(buf, buf_size, pos, ", ") - al2: rawptr[ast.Alias] = rawptr[ast.Alias](imp2_names.get(ai2)) + al2: ast.Alias* = ast.Alias*(imp2_names.get(ai2)) if al2 is not None and al2.name is not None: pos = _PyiEmit(buf, buf_size, pos, al2.name) if al2.asname is not None and string.strlen(al2.asname) > 0: @@ -908,7 +908,7 @@ def _GeneratePyiFromAst(mb: rawptr[memhub.MemBuddy], tree: rawptr[ast.AST], # ImportFrom 语句 elif k == ast.ASTKind.ImportFrom: - ifr: rawptr[ast.ImportFrom] = rawptr[ast.ImportFrom](stmt) + ifr: ast.ImportFrom* = ast.ImportFrom*(stmt) pos = _PyiEmit(buf, buf_size, pos, "from ") lvl: int = ifr.level while lvl > 0: @@ -924,7 +924,7 @@ def _GeneratePyiFromAst(mb: rawptr[memhub.MemBuddy], tree: rawptr[ast.AST], while ai3 < an3: if ai3 > 0: pos = _PyiEmit(buf, buf_size, pos, ", ") - al3: rawptr[ast.Alias] = rawptr[ast.Alias](ifr_names.get(ai3)) + al3: ast.Alias* = ast.Alias*(ifr_names.get(ai3)) if al3 is not None and al3.name is not None: pos = _PyiEmit(buf, buf_size, pos, al3.name) if al3.asname is not None and string.strlen(al3.asname) > 0: @@ -935,19 +935,19 @@ def _GeneratePyiFromAst(mb: rawptr[memhub.MemBuddy], tree: rawptr[ast.AST], # 函数定义(_PyiFunction 已以 "\n" 收尾,不再补空行) elif k == ast.ASTKind.FunctionDef: - fn: rawptr[ast.FunctionDef] = rawptr[ast.FunctionDef](stmt) + fn: ast.FunctionDef* = ast.FunctionDef*(stmt) pos = _PyiFunction(buf, buf_size, pos, fn, 0, "") # 类定义 elif k == ast.ASTKind.ClassDef: - cls: rawptr[ast.ClassDef] = rawptr[ast.ClassDef](stmt) + cls: ast.ClassDef* = ast.ClassDef*(stmt) pos = _PyiClass(buf, buf_size, pos, cls, 0) # 带注解的变量声明 elif k == ast.ASTKind.AnnAssign: - aa: rawptr[ast.AnnAssign] = rawptr[ast.AnnAssign](stmt) + aa: ast.AnnAssign* = ast.AnnAssign*(stmt) if aa.target is not None and aa.target.kind() == ast.ASTKind.Name: - nm: rawptr[ast.Name] = rawptr[ast.Name](aa.target) + nm: ast.Name* = ast.Name*(aa.target) if nm.id is not None: pos = _PyiEmit(buf, buf_size, pos, nm.id) pos = _PyiEmit(buf, buf_size, pos, ": ") @@ -957,17 +957,17 @@ def _GeneratePyiFromAst(mb: rawptr[memhub.MemBuddy], tree: rawptr[ast.AST], # 不是整数,用 _PyiTypeStr 输出类型字符串 is_ctypedef_ann: int = 0 if aa.annotation is not None and aa.annotation.kind() == ast.ASTKind.Attribute: - ctd_at: rawptr[ast.Attribute] = rawptr[ast.Attribute](aa.annotation) + ctd_at: ast.Attribute* = ast.Attribute*(aa.annotation) if ctd_at.attr is not None and string.strcmp(ctd_at.attr, "CTypedef") == 0: if ctd_at.value is not None and ctd_at.value.kind() == ast.ASTKind.Name: - ctd_mod: rawptr[ast.Name] = rawptr[ast.Name](ctd_at.value) + ctd_mod: ast.Name* = ast.Name*(ctd_at.value) if ctd_mod.id is not None and string.strcmp(ctd_mod.id, "t") == 0: is_ctypedef_ann = 1 if is_ctypedef_ann != 0 and aa.value is not None: pos = _PyiEmit(buf, buf_size, pos, " = ") pos = _PyiTypeStr(buf, buf_size, pos, aa.value) elif aa.value is not None and aa.value.kind() == ast.ASTKind.Constant: - cv: rawptr[ast.Constant] = rawptr[ast.Constant](aa.value) + cv: ast.Constant* = ast.Constant*(aa.value) num_buf: bytes = mb.alloc(32) if cv.const_kind == ast.CONST_INT and num_buf is not None: viperlib.snprintf(num_buf, 32, " = %lld", cv.int_val) @@ -995,11 +995,11 @@ def _GeneratePyiFromAst(mb: rawptr[memhub.MemBuddy], tree: rawptr[ast.AST], elif aa.value is not None and aa.value.kind() == ast.ASTKind.UnaryOp: # 处理负值常量(如 INVALID_HANDLE_VALUE = -1) # UnaryOp(USub, Constant(1)) → -1 - uop_cv: rawptr[ast.UnaryOp] = rawptr[ast.UnaryOp](aa.value) + uop_cv: ast.UnaryOp* = ast.UnaryOp*(aa.value) num_buf_u: bytes = mb.alloc(32) if uop_cv.op == ast.OpKind.USub and uop_cv.operand is not None \ and uop_cv.operand.kind() == ast.ASTKind.Constant: - uop_const: rawptr[ast.Constant] = rawptr[ast.Constant](uop_cv.operand) + uop_const: ast.Constant* = ast.Constant*(uop_cv.operand) if uop_const.const_kind == ast.CONST_INT and num_buf_u is not None: neg_val: int64 = -uop_const.int_val viperlib.snprintf(num_buf_u, 32, " = %lld", neg_val) @@ -1007,15 +1007,15 @@ def _GeneratePyiFromAst(mb: rawptr[memhub.MemBuddy], tree: rawptr[ast.AST], elif aa.value is not None and aa.value.kind() == ast.ASTKind.Call: # 处理类型构造函数常量(如 t.CUnsignedLong(-11)) # 提取第一个参数的整数值并输出 - call_cv: rawptr[ast.Call] = rawptr[ast.Call](aa.value) + call_cv: ast.Call* = ast.Call*(aa.value) if call_cv.args is not None: call_args_cv: list[ast.AST*]* = call_cv.args if len(call_args_cv) > 0: - first_arg: rawptr[ast.AST] = call_args_cv.get(0) + first_arg: ast.AST* = call_args_cv.get(0) if first_arg is not None: arg_kind: int = first_arg.kind() if arg_kind == ast.ASTKind.Constant: - ca_cv: rawptr[ast.Constant] = rawptr[ast.Constant](first_arg) + ca_cv: ast.Constant* = ast.Constant*(first_arg) num_buf_c: bytes = mb.alloc(32) if ca_cv.const_kind == ast.CONST_INT and num_buf_c is not None: viperlib.snprintf(num_buf_c, 32, " = %lld", ca_cv.int_val) @@ -1029,11 +1029,11 @@ def _GeneratePyiFromAst(mb: rawptr[memhub.MemBuddy], tree: rawptr[ast.AST], viperlib.snprintf(fbuf_cc, 64, " = %.17g", ca_cv.float_val) pos = _PyiEmit(buf, buf_size, pos, fbuf_cc) elif arg_kind == ast.ASTKind.UnaryOp: - uop_ca: rawptr[ast.UnaryOp] = rawptr[ast.UnaryOp](first_arg) + uop_ca: ast.UnaryOp* = ast.UnaryOp*(first_arg) num_buf_cu: bytes = mb.alloc(32) if uop_ca.op == ast.OpKind.USub and uop_ca.operand is not None \ and uop_ca.operand.kind() == ast.ASTKind.Constant: - uoc: rawptr[ast.Constant] = rawptr[ast.Constant](uop_ca.operand) + uoc: ast.Constant* = ast.Constant*(uop_ca.operand) if uoc.const_kind == ast.CONST_INT and num_buf_cu is not None: neg_c_val: int64 = -uoc.int_val viperlib.snprintf(num_buf_cu, 32, " = %lld", neg_c_val) @@ -1067,7 +1067,7 @@ def _GeneratePyiFromAst(mb: rawptr[memhub.MemBuddy], tree: rawptr[ast.AST], elif aa.value is not None and aa.value.kind() == ast.ASTKind.Name: # 处理 Name 引用常量(如 ALIAS = OTHER_CONST) # 输出引用的名字,让消费方在本地查找 - name_val: rawptr[ast.Name] = rawptr[ast.Name](aa.value) + name_val: ast.Name* = ast.Name*(aa.value) if name_val.id is not None: pos = _PyiEmit(buf, buf_size, pos, " = ") pos = _PyiEmit(buf, buf_size, pos, name_val.id) @@ -1075,19 +1075,19 @@ def _GeneratePyiFromAst(mb: rawptr[memhub.MemBuddy], tree: rawptr[ast.AST], # 全局赋值(无注解)— 从 Constant value 推断类型 elif k == ast.ASTKind.Assign: - asg: rawptr[ast.Assign] = rawptr[ast.Assign](stmt) + asg: ast.Assign* = ast.Assign*(stmt) if asg.targets is not None and asg.value is not None: asg_targets: list[ast.AST*]* = asg.targets atn: sizet = len(asg_targets) if atn == 1: - atg: rawptr[ast.AST] = asg_targets.get(0) + atg: ast.AST* = asg_targets.get(0) if atg is not None and atg.kind() == ast.ASTKind.Name: - agn: rawptr[ast.Name] = rawptr[ast.Name](atg) - aval: rawptr[ast.AST] = asg.value + agn: ast.Name* = ast.Name*(atg) + aval: ast.AST* = asg.value avk: int = aval.kind() inferred: int = 0 if avk == ast.ASTKind.Constant: - acv: rawptr[ast.Constant] = rawptr[ast.Constant](aval) + acv: ast.Constant* = ast.Constant*(aval) if acv.const_kind == ast.CONST_INT: inferred = 1 elif acv.const_kind == ast.CONST_FLOAT: diff --git a/App/lib/Stub/StubGen/VpiReader.vp b/App/lib/Stub/StubGen/VpiReader.vp index 263b607..53476a2 100644 --- a/App/lib/Stub/StubGen/VpiReader.vp +++ b/App/lib/Stub/StubGen/VpiReader.vp @@ -63,26 +63,26 @@ class ReplStubClass: ClassName: str Sha1: str Flags: int - OwnNames: sizet | t.CPtr # 元素 = str 指针(本类字段名,AnnAssign 顺序) - OwnTypes: sizet | t.CPtr # 元素 = LLVMType 指针 + OwnNames: sizet* # 元素 = str 指针(本类字段名,AnnAssign 顺序) + OwnTypes: sizet* # 元素 = LLVMType 指针 OwnCount: int - MethodNames: sizet | t.CPtr - MethodFlags: sizet | t.CPtr + MethodNames: sizet* + MethodFlags: sizet* MethodCount: int - Bases: sizet | t.CPtr + Bases: sizet* BaseCount: int LayoutCount: int # 存根布局字段数(>=0 = 命中该类的 `= type {…}`;负数 = **哨兵,不是字段数**, # 见 _REPL_STUB_NOCOUNT_NOCLASS/-OPAQUE:存根里没这个类 / 没读到存根 / opaque) VtArity: int # 存根 .vtable 全局槽数(0 = 存根无该全局) - Names: sizet | t.CPtr - Types: sizet | t.CPtr + Names: sizet* + Types: sizet* Count: int HasVt: int IsNoVTable: int IsOOP: int HasInit: int HasNew: int - VtNames: sizet | t.CPtr + VtNames: sizet* VtCount: int VtTrust: int # 1 = 虚表槽数已与存根一致(可登记 VTableMethods) OwnFail: int # 1 = 本类有字段注解解析失败 ⇒ OwnCount 只是"已解析字段数"(不完整) @@ -164,9 +164,9 @@ def _vpi_idx_hash(key: bytes) -> uint64: return h -def _vpi_idx_slot(idx_base: bytes, si: sizet) -> sizet | t.CPtr: +def _vpi_idx_slot(idx_base: bytes, si: sizet) -> sizet*: """取索引第 si 个槽(8 字节,存 slot_index+1;0=空槽)""" - return (sizet | t.CPtr)(uint64(idx_base) + uint64(si) * 8) + return (sizet*)(uint64(idx_base) + uint64(si) * 8) def _vpi_idx_find(keys: bytes, key_stride: int, idx_base: bytes, @@ -182,7 +182,7 @@ def _vpi_idx_find(keys: bytes, key_stride: int, idx_base: bytes, si: sizet = sizet(h) & mask i: int = 0 while i < cap: - slot: sizet | t.CPtr = _vpi_idx_slot(idx_base, si) + slot: sizet* = _vpi_idx_slot(idx_base, si) sv: sizet = slot[0] if sv == 0: return -1 @@ -204,7 +204,7 @@ def _vpi_idx_insert(idx_base: bytes, cap: int, slot_index: int, key: bytes) -> i si: sizet = sizet(h) & mask i: int = 0 while i < cap: - slot: sizet | t.CPtr = _vpi_idx_slot(idx_base, si) + slot: sizet* = _vpi_idx_slot(idx_base, si) if slot[0] == 0: slot[0] = sizet(slot_index + 1) return 0 @@ -770,13 +770,13 @@ def _lookup_vpi_param_annots(src_sha1: str, cls_name: str, method_name: str) -> # 调用点 declare 停在调用点实参宽度(如 elem_size 字面量 i32 把定义侧 sizet(i64) 固化窄)。本函数按 {sha1}.{base}[T].{method} 形态定位模板条目, # 把段内独立的类型形参 token 用特化实参(cls_name 的 [...] 内容)替换后再解析;未命中/多参模板(键段含空格被截断)返回 None,不做兜底推断。 # ============================================================ -def _resolve_vpi_param_annot_seg_template(pool: rawptr[memhub.MemBuddy], +def _resolve_vpi_param_annot_seg_template(pool: memhub.MemBuddy*, src_sha1: str, cls_name: str, method_name: str, seg_idx: int, - i32_ty: rawptr[llvmlite.LLVMType], - i8_ptr_ty: rawptr[llvmlite.LLVMType]) -> rawptr[llvmlite.LLVMType]: + i32_ty: llvmlite.LLVMType*, + i8_ptr_ty: llvmlite.LLVMType*) -> llvmlite.LLVMType*: """特化类 X[arg] 的参数注解段解析(模板 X[T] 注解 + T→arg 替换);未命中 None""" if pool is None or src_sha1 is None or cls_name is None or method_name is None \ or _g_vpi_param_keys is None: @@ -803,7 +803,7 @@ def _resolve_vpi_param_annot_seg_template(pool: rawptr[memhub.MemBuddy], string.strncpy(arg_t, lbkt_t + 1, arg_len_t) arg_t[arg_len_t] = '\0' sha1_len_t: sizet = string.strlen(src_sha1) - ty_t: rawptr[llvmlite.LLVMType] = None + ty_t: llvmlite.LLVMType* = None ki_t: int for ki_t in range(_g_vpi_param_count): gk_t: bytes = _g_vpi_param_keys + ki_t * VPI_PARAM_KEY_LEN @@ -873,14 +873,14 @@ def _resolve_vpi_param_annot_seg_template(pool: rawptr[memhub.MemBuddy], # vpi tree 参数列表被覆盖损坏时(param_count 偏小,尾部默认参数丢失),用 _cache_vpi_param_annots_text 的文本缓存补全:参数位置 p 对应缓存段 p(含首参空串占位)。 # 补全后 declare 参数数与 define 一致,调用点默认参数填充才能生效,避免被调函数读栈垃圾。 # ============================================================ -def _repair_declare_params_from_text(pool: rawptr[memhub.MemBuddy], - func: rawptr[llvmlite.Function], +def _repair_declare_params_from_text(pool: memhub.MemBuddy*, + func: llvmlite.Function*, src_sha1: str, cls_name: str, method_name: str, param_count: int, - i32_ty: rawptr[llvmlite.LLVMType], - i8_ptr_ty: rawptr[llvmlite.LLVMType]) -> int: + i32_ty: llvmlite.LLVMType*, + i8_ptr_ty: llvmlite.LLVMType*) -> int: """用 vpi 文本缓存的参数注解补全 declare 参数;返回补全后参数数""" if func is None or src_sha1 is None or method_name is None: return param_count @@ -907,13 +907,13 @@ def _repair_declare_params_from_text(pool: rawptr[memhub.MemBuddy], if prm_annots[cur2] == '@': cur2 += 1 if seg_idx >= param_count: - param_ty_r: rawptr[llvmlite.LLVMType] = i8_ptr_ty + param_ty_r: llvmlite.LLVMType* = i8_ptr_ty if seg_len2 > 0: seg_buf_r: bytes = stdlib.malloc(seg_len2 + 1) if seg_buf_r is not None: string.strncpy(seg_buf_r, prm_annots + seg_start2, seg_len2) seg_buf_r[seg_len2] = '\0' - rt: rawptr[llvmlite.LLVMType] = _resolve_vpi_ret_annot_str( + rt: llvmlite.LLVMType* = _resolve_vpi_ret_annot_str( pool, seg_buf_r, i32_ty, i8_ptr_ty) if rt is not None: param_ty_r = rt @@ -931,13 +931,13 @@ def _repair_declare_params_from_text(pool: rawptr[memhub.MemBuddy], # 参数类型错会导致调用侧 trunc 传参、callee 按 i64 读栈残留高位 → can=巨值读未写槽位崩溃(SlotsBugTest 根因)。 # 从 @-joined 注解串取第 seg_idx 段(0=self 空段),用 _resolve_vpi_ret_annot_str 解析;空段/未命中返回 None(走 AST 兜底)。 # ============================================================ -def _resolve_vpi_param_annot_seg(pool: rawptr[memhub.MemBuddy], +def _resolve_vpi_param_annot_seg(pool: memhub.MemBuddy*, src_sha1: str, cls_name: str, method_name: str, seg_idx: int, - i32_ty: rawptr[llvmlite.LLVMType], - i8_ptr_ty: rawptr[llvmlite.LLVMType]) -> rawptr[llvmlite.LLVMType]: + i32_ty: llvmlite.LLVMType*, + i8_ptr_ty: llvmlite.LLVMType*) -> llvmlite.LLVMType*: """按段索引解析 vpi 参数注解段为 LLVMType,空段/失败返回 None""" if pool is None or src_sha1 is None or method_name is None: return None @@ -964,7 +964,7 @@ def _resolve_vpi_param_annot_seg(pool: rawptr[memhub.MemBuddy], return None string.strncpy(seg_buf_p, prm_annots_p + seg_start_p, seg_len_p) seg_buf_p[seg_len_p] = '\0' - seg_ty_p: rawptr[llvmlite.LLVMType] = _resolve_vpi_ret_annot_str( + seg_ty_p: llvmlite.LLVMType* = _resolve_vpi_ret_annot_str( pool, seg_buf_p, i32_ty, i8_ptr_ty) stdlib.free(seg_buf_p) return seg_ty_p @@ -1276,13 +1276,13 @@ def _lookup_vpi_ret_annot(src_sha1: str, cls_name: str, method_name: str) -> str # # 纯字符串解析,不构造 AST 节点。 # ============================================================ -def _resolve_single_vpi_type_str(pool: rawptr[memhub.MemBuddy], - seg: str) -> rawptr[llvmlite.LLVMType]: +def _resolve_single_vpi_type_str(pool: memhub.MemBuddy*, + seg: str) -> llvmlite.LLVMType*: """解析单个类型段为 LLVMType,无法识别返回 None""" if seg is None or pool is None: return None - i8_ty: rawptr[llvmlite.LLVMType] = llvmlite.Int8(pool) - i8_ptr_ty: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, i8_ty) + i8_ty: llvmlite.LLVMType* = llvmlite.Int8(pool) + i8_ptr_ty: llvmlite.LLVMType* = llvmlite.Ptr(pool, i8_ty) # 内置别名 if string.strcmp(seg, "str") == 0 or string.strcmp(seg, "bytes") == 0: return i8_ptr_ty @@ -1323,7 +1323,7 @@ def _resolve_single_vpi_type_str(pool: rawptr[memhub.MemBuddy], if inner_buf_rp is not None: string.strncpy(inner_buf_rp, seg + 7, inner_len_rp) inner_buf_rp[inner_len_rp] = '\0' - inner_ty_rp: rawptr[llvmlite.LLVMType] = _resolve_single_vpi_type_str(pool, inner_buf_rp) + inner_ty_rp: llvmlite.LLVMType* = _resolve_single_vpi_type_str(pool, inner_buf_rp) stdlib.free(inner_buf_rp) if inner_ty_rp is not None: return llvmlite.Ptr(pool, inner_ty_rp) @@ -1341,7 +1341,7 @@ def _resolve_single_vpi_type_str(pool: rawptr[memhub.MemBuddy], if inner_buf_cp is not None: string.strncpy(inner_buf_cp, seg + cptr_sub_pfx, inner_len_cp) inner_buf_cp[inner_len_cp] = '\0' - inner_ty_cp: rawptr[llvmlite.LLVMType] = _resolve_single_vpi_type_str( + inner_ty_cp: llvmlite.LLVMType* = _resolve_single_vpi_type_str( pool, inner_buf_cp) stdlib.free(inner_buf_cp) if inner_ty_cp is not None: @@ -1359,7 +1359,7 @@ def _resolve_single_vpi_type_str(pool: rawptr[memhub.MemBuddy], return llvmlite.Void(pool) # [阶段2] 统一口径:CTypedef 动态表优先(库 typedef 走正常库分析), # miss 回退 map_t_type(t/c 库内部特判)。 - mapped_ty: rawptr[llvmlite.LLVMType] = GenApi.resolve_typedef_or_map(pool, attr_nm, None, None) + mapped_ty: llvmlite.LLVMType* = GenApi.resolve_typedef_or_map(pool, attr_nm, None, None) if mapped_ty is not None: return mapped_ty return None @@ -1367,7 +1367,7 @@ def _resolve_single_vpi_type_str(pool: rawptr[memhub.MemBuddy], last_dot: str = string.strrchr(seg, '.') if last_dot is not None: cls_nm2: str = last_dot + 1 - mod_struct_ty: rawptr[llvmlite.LLVMType] = GenApi.get_struct_type(cls_nm2) + mod_struct_ty: llvmlite.LLVMType* = GenApi.get_struct_type(cls_nm2) if mod_struct_ty is not None: return mod_struct_ty # 枚举兜底:t.CEnum 注册在独立 EnumTable(EnumEntry),不进 StructTable, @@ -1375,20 +1375,20 @@ def _resolve_single_vpi_type_str(pool: rawptr[memhub.MemBuddy], # struct 落空必须回退枚举表取 BaseTy(通常 i32)。否则 vpi 返回注解解析 # 失败 → 跨模块函数返回类型无法精确获取 → text.ll 缺失(依赖环)时 # 永久 pending(VKernel fat32→sched→process→fat32 Phase A 死锁根因)。 - mod_enum_ty: rawptr[llvmlite.LLVMType] = GenApi.get_enum_base_type(cls_nm2) + mod_enum_ty: llvmlite.LLVMType* = GenApi.get_enum_base_type(cls_nm2) if mod_enum_ty is not None: return mod_enum_ty return None # 裸类名 → 全局 struct 注册表 - bare_struct_ty: rawptr[llvmlite.LLVMType] = GenApi.get_struct_type(seg) + bare_struct_ty: llvmlite.LLVMType* = GenApi.get_struct_type(seg) if bare_struct_ty is not None: return bare_struct_ty # 裸枚举名 → EnumTable 兜底(同上:枚举不在 StructTable) - bare_enum_ty: rawptr[llvmlite.LLVMType] = GenApi.get_enum_base_type(seg) + bare_enum_ty: llvmlite.LLVMType* = GenApi.get_enum_base_type(seg) if bare_enum_ty is not None: return bare_enum_ty # 裸 typedef 名(如 VOIDPTR):CTypedef 动态表优先,miss 回退 map_t_type - mapped_bare: rawptr[llvmlite.LLVMType] = GenApi.resolve_typedef_or_map(pool, seg, None, None) + mapped_bare: llvmlite.LLVMType* = GenApi.resolve_typedef_or_map(pool, seg, None, None) if mapped_bare is not None: return mapped_bare return None @@ -1399,12 +1399,12 @@ def _resolve_single_vpi_type_str(pool: rawptr[memhub.MemBuddy], # # 纯字符串解析,避免 _parse_type_string 跨模块构造 ast.Name/ast.BinOp 时节点 kind() 异常(可能退化为裸函数调用)导致 resolve 得到垃圾类型(如 Ptr(i8))。 # -# 支持: "str"/"bytes" → i8*; "int" → i32; "bool" → i1; "char" 等 → map_t_type 映射; "X | t.CPtr" → Ptr(Struct X); "t.CPtr" → i8*; "rawptr[memhub.MemBuddy]" → Ptr(Struct MemBuddy)。 +# 支持: "str"/"bytes" → i8*; "int" → i32; "bool" → i1; "char" 等 → map_t_type 映射; "X | t.CPtr" → Ptr(Struct X); "t.CPtr" → i8*; "memhub.MemBuddy*" → Ptr(Struct MemBuddy)。 # ============================================================ -def _resolve_vpi_ret_annot_str(pool: rawptr[memhub.MemBuddy], +def _resolve_vpi_ret_annot_str(pool: memhub.MemBuddy*, ret_annot: str, - i32_ty: rawptr[llvmlite.LLVMType], - i8_ptr_ty: rawptr[llvmlite.LLVMType]) -> rawptr[llvmlite.LLVMType]: + i32_ty: llvmlite.LLVMType*, + i8_ptr_ty: llvmlite.LLVMType*) -> llvmlite.LLVMType*: """直接解析 vpi 返回注解字符串为 LLVMType(不构造 AST 节点)""" if ret_annot is None or pool is None: return None @@ -1419,8 +1419,8 @@ def _resolve_vpi_ret_annot_str(pool: rawptr[memhub.MemBuddy], inner_len_t += 1 if ret_annot[6 + inner_len_t] != ']' or inner_len_t == 0: return None - tup_head_t: rawptr[llvmlite.Function] = None - tup_tail_t: rawptr[llvmlite.Function] = None + tup_head_t: llvmlite.Function* = None + tup_tail_t: llvmlite.Function* = None tup_count_t: int = 0 p_t: sizet = 0 while p_t < inner_len_t: @@ -1440,11 +1440,11 @@ def _resolve_vpi_ret_annot_str(pool: rawptr[memhub.MemBuddy], return None string.strncpy(seg_buf_t, ret_annot + 6 + seg_s_t, seg_len_t) seg_buf_t[seg_len_t] = '\0' - seg_ty_t: rawptr[llvmlite.LLVMType] = _resolve_single_vpi_type_str(pool, seg_buf_t) + seg_ty_t: llvmlite.LLVMType* = _resolve_single_vpi_type_str(pool, seg_buf_t) stdlib.free(seg_buf_t) if seg_ty_t is None: return None - tup_node_t: rawptr[llvmlite.Function] = llvmlite.new_param_node(pool, seg_ty_t) + tup_node_t: llvmlite.Function* = llvmlite.new_param_node(pool, seg_ty_t) if tup_node_t is None: return None if tup_head_t is None: @@ -1459,7 +1459,7 @@ def _resolve_vpi_ret_annot_str(pool: rawptr[memhub.MemBuddy], has_cptr: int = 0 has_cvoid: int = 0 - first_ty: rawptr[llvmlite.LLVMType] = None + first_ty: llvmlite.LLVMType* = None # 产生 first_ty 那一段文本的属性(供末尾 has_cptr 分支复刻定义侧规则,N12): # first_qual=1 段是限定名(含 '.',如 mod.Class / int64) # first_wl =1 段是白名单裸标量名(int/char/str/bytes/bool/float/double) @@ -1474,7 +1474,7 @@ def _resolve_vpi_ret_annot_str(pool: rawptr[memhub.MemBuddy], # 与定义侧 `X | t.CPtr[T]` 分支同口径:CPtr 侧贡献 N 层指针、另一侧提供基类型 ⇒ Ptr^N(基类型)。 # 与 has_cptr(裸 t.CPtr 段)分开记录:裸标记恒「追加 1 层」且有 struct 吸收特例,下标路径无吸收,两者在定义侧分属互斥分支。 cptr_sub_lvl: int = 0 - cptr_sub_ty: rawptr[llvmlite.LLVMType] = None + cptr_sub_ty: llvmlite.LLVMType* = None buf_len: sizet = string.strlen(ret_annot) pos: sizet = 0 @@ -1503,16 +1503,16 @@ def _resolve_vpi_ret_annot_str(pool: rawptr[memhub.MemBuddy], # 语义不同(如 X=struct S、t.CPtr[t.CPtr]:定义侧 Ptr(Ptr(S)), # 取该段本身则得 i8**)。此处只记录 N 与段类型,末尾统一合并。 if string.strncmp(seg_buf, "t.CPtr[", 7) == 0 or string.strncmp(seg_buf, "c.CPtr[", 7) == 0: - seg_ty_cs: rawptr[llvmlite.LLVMType] = _resolve_single_vpi_type_str(pool, seg_buf) + seg_ty_cs: llvmlite.LLVMType* = _resolve_single_vpi_type_str(pool, seg_buf) if seg_ty_cs is not None: # 计算外层 Ptr 嵌套数(定义侧 L2616-2632 同口径)。注意不能在 # case body 内更新 while 条件变量(自举编译的 match 会写到 subject # 快照槽 → 条件读旧槽死循环,见 TypeGenResolve.vp L2620-2624): # case 绑定 pointee 到局部变量,match 外更新循环变量。 lvl_cs: int = 0 - cur_cs: rawptr[llvmlite.LLVMType] = seg_ty_cs + cur_cs: llvmlite.LLVMType* = seg_ty_cs while cur_cs is not None: - nxt_cs: rawptr[llvmlite.LLVMType] = None + nxt_cs: llvmlite.LLVMType* = None match cur_cs: case llvmlite.LLVMType.Ptr(pointee_cs): lvl_cs += 1 @@ -1529,7 +1529,7 @@ def _resolve_vpi_ret_annot_str(pool: rawptr[memhub.MemBuddy], elif string.strcmp(seg_buf, "t.CVoid") == 0 or string.strcmp(seg_buf, "CVoid") == 0: has_cvoid = 1 else: - seg_ty: rawptr[llvmlite.LLVMType] = _resolve_single_vpi_type_str(pool, seg_buf) + seg_ty: llvmlite.LLVMType* = _resolve_single_vpi_type_str(pool, seg_buf) if seg_ty is not None and first_ty is None: first_ty = seg_ty # 记录该段属性(N12):定义侧 TypeGenResolve.resolve_annotation_type @@ -1583,7 +1583,7 @@ def _resolve_vpi_ret_annot_str(pool: rawptr[memhub.MemBuddy], if cptr_sub_lvl > 0: if first_ty is None: return cptr_sub_ty - res_ty_cs: rawptr[llvmlite.LLVMType] = first_ty + res_ty_cs: llvmlite.LLVMType* = first_ty wrap_i_cs: int = 0 while wrap_i_cs < cptr_sub_lvl: res_ty_cs = llvmlite.Ptr(pool, res_ty_cs) @@ -1658,7 +1658,7 @@ def _extract_sha1_from_path(vpi_path: str) -> str: # 与 HandlesImports.add_imported_module 逻辑一致,但内联在本模块, # 避免 VpiReader → HandlesImports → StubMerger → VpiReader 循环依赖。 # ============================================================ -def _stub_add_imported(pool: rawptr[memhub.MemBuddy], +def _stub_add_imported(pool: memhub.MemBuddy*, cur: str, name: str) -> str: """追加模块名到空格分隔列表(pool 分配),返回新列表""" if name is None: @@ -1682,7 +1682,7 @@ def _stub_add_imported(pool: rawptr[memhub.MemBuddy], # ============================================================ # _stub_add_from - 追加 from-import 映射("local:mod[:orig]" 空格分隔) # ============================================================ -def _stub_add_from(pool: rawptr[memhub.MemBuddy], +def _stub_add_from(pool: memhub.MemBuddy*, cur: str, local: str, mod: str, orig: str) -> str: """追加 from-import 映射(pool 分配),返回新列表 @@ -1778,7 +1778,7 @@ def _vpi_typedef_visited_mark(sha1: str) -> None: _g_vpi_typedef_visited_count += 1 -def _vpi_register_typedef_closure(pool: rawptr[memhub.MemBuddy], +def _vpi_register_typedef_closure(pool: memhub.MemBuddy*, import_mods: str, temp_dir: str, depth: int) -> int: @@ -1850,11 +1850,11 @@ def _vpi_register_typedef_closure(pool: rawptr[memhub.MemBuddy], _vpi_typedef_visited_mark(sha1_r) if bytes_read_r < VPI_READ_BUF_SIZE: vpi_buf_r[bytes_read_r] = 0 - lx_r: rawptr[ast.Lexer] = ast.new_lexer(pool) + lx_r: ast.Lexer* = ast.new_lexer(pool) if lx_r is not None: ast._lexer_init(lx_r, vpi_buf_r, pool) - tokens_r: rawptr[ast.Token] = ast.tokenize(lx_r) - tree_r: rawptr[ast.AST] = ast.parse_tokens(pool, tokens_r) + tokens_r: ast.Token* = ast.tokenize(lx_r) + tree_r: ast.AST* = ast.parse_tokens(pool, tokens_r) if tree_r is not None and tree_r.children is not None: ch_r: list[ast.AST*]* = tree_r.children cn_r: sizet = len(ch_r) @@ -1864,20 +1864,20 @@ def _vpi_register_typedef_closure(pool: rawptr[memhub.MemBuddy], sub_need: sizet = 1 # 末尾 NUL ci_c: sizet for ci_c in range(cn_r): - child_c: rawptr[ast.AST] = ch_r.get(ci_c) + child_c: ast.AST* = ch_r.get(ci_c) if child_c is None: continue kk_c: int = child_c.kind() if kk_c == ast.ASTKind.Import: - imp_c: rawptr[ast.Import] = rawptr[ast.Import](child_c) + imp_c: ast.Import* = ast.Import*(child_c) if imp_c.names is not None: in_nc: sizet = len(imp_c.names) for ii_c in range(in_nc): - al_c: rawptr[ast.Alias] = rawptr[ast.Alias](imp_c.names.get(ii_c)) + al_c: ast.Alias* = ast.Alias*(imp_c.names.get(ii_c)) if al_c is not None and al_c.name is not None: sub_need += string.strlen(al_c.name) + 1 elif kk_c == ast.ASTKind.ImportFrom: - ifr_c: rawptr[ast.ImportFrom] = rawptr[ast.ImportFrom](child_c) + ifr_c: ast.ImportFrom* = ast.ImportFrom*(child_c) if ifr_c.module is not None: sub_need += string.strlen(ifr_c.module) + 1 sub_imports: bytes = stdlib.malloc(sub_need) @@ -1886,17 +1886,17 @@ def _vpi_register_typedef_closure(pool: rawptr[memhub.MemBuddy], sub_len: sizet = 0 ci_r: sizet for ci_r in range(cn_r): - child_r: rawptr[ast.AST] = ch_r.get(ci_r) + child_r: ast.AST* = ch_r.get(ci_r) if child_r is None: continue kk_r: int = child_r.kind() if kk_r == ast.ASTKind.Import: - imp_r: rawptr[ast.Import] = rawptr[ast.Import](child_r) + imp_r: ast.Import* = ast.Import*(child_r) if imp_r.names is not None: in_n: sizet = len(imp_r.names) ii_r: sizet for ii_r in range(in_n): - al_r: rawptr[ast.Alias] = rawptr[ast.Alias](imp_r.names.get(ii_r)) + al_r: ast.Alias* = ast.Alias*(imp_r.names.get(ii_r)) if al_r is not None and al_r.name is not None: il_r: sizet = string.strlen(al_r.name) if sub_len > 0: @@ -1906,7 +1906,7 @@ def _vpi_register_typedef_closure(pool: rawptr[memhub.MemBuddy], sub_len += il_r sub_imports[sub_len] = '\0' elif kk_r == ast.ASTKind.ImportFrom: - ifr_r: rawptr[ast.ImportFrom] = rawptr[ast.ImportFrom](child_r) + ifr_r: ast.ImportFrom* = ast.ImportFrom*(child_r) if ifr_r.module is not None: ml_r: sizet = string.strlen(ifr_r.module) if sub_len > 0: @@ -1918,12 +1918,12 @@ def _vpi_register_typedef_closure(pool: rawptr[memhub.MemBuddy], # 第二遍:注册本模块 AnnAssign 的 CTypedef/CDefine ci2_r: sizet for ci2_r in range(cn_r): - child2_r: rawptr[ast.AST] = ch_r.get(ci2_r) + child2_r: ast.AST* = ch_r.get(ci2_r) if child2_r is None: continue if child2_r.kind() != ast.ASTKind.AnnAssign: continue - aa_r: rawptr[ast.AnnAssign] = rawptr[ast.AnnAssign](child2_r) + aa_r: ast.AnnAssign* = ast.AnnAssign*(child2_r) if aa_r.annotation is None or aa_r.target is None or aa_r.value is None: continue if GenApi._is_ctypedef_annotation(aa_r.annotation) != 0: @@ -1931,11 +1931,11 @@ def _vpi_register_typedef_closure(pool: rawptr[memhub.MemBuddy], elif GenApi.is_cdefine_annotation(aa_r.annotation) != 0: if aa_r.target.kind() != ast.ASTKind.Name: continue - cdef_t: rawptr[ast.Name] = rawptr[ast.Name](aa_r.target) + cdef_t: ast.Name* = ast.Name*(aa_r.target) if cdef_t.id is None: continue if aa_r.value.kind() == ast.ASTKind.Constant: - cn_v: rawptr[ast.Constant] = rawptr[ast.Constant](aa_r.value) + cn_v: ast.Constant* = ast.Constant*(aa_r.value) if cn_v.const_kind == ast.CONST_FLOAT: GenApi.register_cdefine_double(pool, cdef_t.id, cn_v.float_val) elif cn_v.const_kind == ast.CONST_INT: @@ -1960,10 +1960,10 @@ def _vpi_register_typedef_closure(pool: rawptr[memhub.MemBuddy], # Args: pool 内存池;mod 当前 LLVM 模块;vpi_path .vpi 文件路径;trans 翻译器对象 # Returns: 1=成功,0=失败 # ============================================================ -def ParseVpiIntoModule(pool: rawptr[memhub.MemBuddy], - mod: rawptr[llvmlite.LLVMModule], +def ParseVpiIntoModule(pool: memhub.MemBuddy*, + mod: llvmlite.LLVMModule*, vpi_path: str, - trans: rawptr[HT.Translator]) -> int: + trans: HT.Translator*) -> int: """解析 .vpi 文件,将函数声明注入到当前模块 解析 stub 期间临时将错误归因切换到被读 stub 文件(.vpi): @@ -1979,10 +1979,10 @@ def ParseVpiIntoModule(pool: rawptr[memhub.MemBuddy], return ret -def _ParseVpiIntoModuleImpl(pool: rawptr[memhub.MemBuddy], - mod: rawptr[llvmlite.LLVMModule], +def _ParseVpiIntoModuleImpl(pool: memhub.MemBuddy*, + mod: llvmlite.LLVMModule*, vpi_path: str, - trans: rawptr[HT.Translator]) -> int: + trans: HT.Translator*) -> int: """解析 .vpi 文件,将函数声明注入到当前模块(ParseVpiIntoModule 实际实现)""" if pool is None or mod is None or vpi_path is None or trans is None: return 0 @@ -2004,13 +2004,13 @@ def _ParseVpiIntoModuleImpl(pool: rawptr[memhub.MemBuddy], vpi_buf[bytes_read] = 0 # 2. 解析为 AST - lx: rawptr[ast.Lexer] = ast.new_lexer(pool) + lx: ast.Lexer* = ast.new_lexer(pool) if lx is None: stdlib.free(vpi_buf) return 0 ast._lexer_init(lx, vpi_buf, pool) - tokens: rawptr[ast.Token] = ast.tokenize(lx) - tree: rawptr[ast.AST] = ast.parse_tokens(pool, tokens) + tokens: ast.Token* = ast.tokenize(lx) + tree: ast.AST* = ast.parse_tokens(pool, tokens) # vpi_buf 延迟释放:AST 字符串字段可能引用 vpi_buf 内部(token 零拷贝), # 提前 free 会导致 Name.id/Attribute.attr 等悬空 → 后续解析返回错误类型。 # 在 ParseVpiIntoModule 末尾统一释放。 @@ -2045,17 +2045,17 @@ def _ParseVpiIntoModuleImpl(pool: rawptr[memhub.MemBuddy], stub_from_imports: str = None si: sizet for si in range(n): - schild: rawptr[ast.AST] = ch.get(si) + schild: ast.AST* = ch.get(si) if schild is None: continue sk: int = schild.kind() if sk == ast.ASTKind.Import: - simp: rawptr[ast.Import] = rawptr[ast.Import](schild) + simp: ast.Import* = ast.Import*(schild) if simp.names is not None: sn_n: sizet = len(simp.names) sni: sizet for sni in range(sn_n): - sal: rawptr[ast.Alias] = rawptr[ast.Alias](simp.names.get(sni)) + sal: ast.Alias* = ast.Alias*(simp.names.get(sni)) if sal is not None and sal.name is not None: stub_imported_modules = _stub_add_imported( pool, stub_imported_modules, sal.name) @@ -2063,7 +2063,7 @@ def _ParseVpiIntoModuleImpl(pool: rawptr[memhub.MemBuddy], stub_imported_modules = _stub_add_imported( pool, stub_imported_modules, sal.asname) elif sk == ast.ASTKind.ImportFrom: - sifr: rawptr[ast.ImportFrom] = rawptr[ast.ImportFrom](schild) + sifr: ast.ImportFrom* = ast.ImportFrom*(schild) sifr_mod: str = sifr.module # 相对导入补包前缀:vpi 里 `from .base import X` 只存 module="base"(前导点记在 level),若按字面 "base" 精确查找则查不到 "ast.base" ⇒ 裸类名(AST 等)解析失败 ⇒ rawptr[AST] 等注解 fail-fast。 # 故按 stub 自身相对路径还原包名(ast/parser.vp → "ast"),level==1 时拼成完整模块名 "ast.base" 再登记(level>1 保持原样,避免未确认路径形态时做过深上溯)。 @@ -2136,7 +2136,7 @@ def _ParseVpiIntoModuleImpl(pool: rawptr[memhub.MemBuddy], sifr_nn: sizet = len(sifr.names) sifri: sizet for sifri in range(sifr_nn): - sial: rawptr[ast.Alias] = rawptr[ast.Alias](sifr.names.get(sifri)) + sial: ast.Alias* = ast.Alias*(sifr.names.get(sifri)) if sial is not None and sial.name is not None: # '*' star import 不建 from 映射(lookup 有 star 回退) if string.strcmp(sial.name, "*") != 0: @@ -2193,12 +2193,12 @@ def _ParseVpiIntoModuleImpl(pool: rawptr[memhub.MemBuddy], if imported_modules is not None: _vpi_register_typedef_closure(pool, imported_modules, GenApi.get_temp_dir(), 0) - i32_ty: rawptr[llvmlite.LLVMType] = llvmlite.Int32(pool) - i8_ty: rawptr[llvmlite.LLVMType] = llvmlite.Int8(pool) - i8_ptr_ty: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, i8_ty) + i32_ty: llvmlite.LLVMType* = llvmlite.Int32(pool) + i8_ty: llvmlite.LLVMType* = llvmlite.Int8(pool) + i8_ptr_ty: llvmlite.LLVMType* = llvmlite.Ptr(pool, i8_ty) # 函数表信息 - funcs_ptr: rawptr[GenTypes.FuncEntry] = trans._funcs + funcs_ptr: GenTypes.FuncEntry* = trans._funcs max_funcs: int = 1024 # ============================================================ @@ -2218,18 +2218,18 @@ def _ParseVpiIntoModuleImpl(pool: rawptr[memhub.MemBuddy], # ============================================================ i0: sizet for i0 in range(n): - child0: rawptr[ast.AST] = ch.get(i0) + child0: ast.AST* = ch.get(i0) if child0 is None: continue if child0.kind() != ast.ASTKind.ClassDef: continue - class_cd0: rawptr[ast.ClassDef] = rawptr[ast.ClassDef](child0) + class_cd0: ast.ClassDef* = ast.ClassDef*(child0) if class_cd0 is None or class_cd0.name is None: continue cls_name_v0: str = class_cd0.name # 泛型类(class X[T])跳过:stub 模板签名含类级类型参数 T,注入时 # T 无法确定;特化方法 define 已在 Phase1 生成,无需 stub 模板 declare。 - tp_stub0: list[str] | t.CPtr = class_cd0.type_params + tp_stub0: list[str]* = class_cd0.type_params if tp_stub0 is not None and len(tp_stub0) > 0: continue _inject_class_struct_declare(pool, mod, class_cd0, cls_name_v0, trans, @@ -2240,17 +2240,17 @@ def _ParseVpiIntoModuleImpl(pool: rawptr[memhub.MemBuddy], # 若边注册边处理方法,前向引用的类此刻尚未注册 → 形参注解裸名解析落空 → fail-fast。 # ============================================================ for i1 in range(n): - child1: rawptr[ast.AST] = ch.get(i1) + child1: ast.AST* = ch.get(i1) if child1 is None: continue if child1.kind() != ast.ASTKind.ClassDef: continue - class_cd1: rawptr[ast.ClassDef] = rawptr[ast.ClassDef](child1) + class_cd1: ast.ClassDef* = ast.ClassDef*(child1) if class_cd1 is None or class_cd1.name is None: continue cls_name_v1: str = class_cd1.name # 泛型类跳过(与第一遍 A 同判据) - tp_stub1: list[str] | t.CPtr = class_cd1.type_params + tp_stub1: list[str]* = class_cd1.type_params if tp_stub1 is not None and len(tp_stub1) > 0: continue cls_children1: list[ast.AST*]* = class_cd1.children @@ -2258,12 +2258,12 @@ def _ParseVpiIntoModuleImpl(pool: rawptr[memhub.MemBuddy], continue cn21: sizet = len(cls_children1) for ci21 in range(cn21): - m_child1: rawptr[ast.AST] = cls_children1.get(ci21) + m_child1: ast.AST* = cls_children1.get(ci21) if m_child1 is None: continue if m_child1.kind() != ast.ASTKind.FunctionDef: continue - m_fd1: rawptr[ast.FunctionDef] = rawptr[ast.FunctionDef](m_child1) + m_fd1: ast.FunctionDef* = ast.FunctionDef*(m_child1) if m_fd1 is None or m_fd1.name is None: continue _inject_method_declare(pool, mod, m_fd1, cls_name_v1, trans, @@ -2272,14 +2272,14 @@ def _ParseVpiIntoModuleImpl(pool: rawptr[memhub.MemBuddy], i: sizet for i in range(n): - child: rawptr[ast.AST] = ch.get(i) + child: ast.AST* = ch.get(i) if child is None: continue kd: int = child.kind() # FunctionDef → 提取函数名、参数、返回类型 → 注入 declare if kd == ast.ASTKind.FunctionDef: - fd: rawptr[ast.FunctionDef] = rawptr[ast.FunctionDef](child) + fd: ast.FunctionDef* = ast.FunctionDef*(child) if fd is None or fd.name is None: continue _inject_function_declare(pool, mod, fd, trans, src_sha1, @@ -2291,11 +2291,11 @@ def _ParseVpiIntoModuleImpl(pool: rawptr[memhub.MemBuddy], # AnnAssign with t.CTypedef → 注册 CTypedef; # 普通模块级全局变量(如 tokens._op_head)→ external global declare if kd == ast.ASTKind.AnnAssign: - aa: rawptr[ast.AnnAssign] = rawptr[ast.AnnAssign](child) + aa: ast.AnnAssign* = ast.AnnAssign*(child) if aa is None: continue if aa.target is not None and aa.target.kind() == ast.ASTKind.Name: - dbg_tn: rawptr[ast.Name] = rawptr[ast.Name](aa.target) + dbg_tn: ast.Name* = ast.Name*(aa.target) if dbg_tn.id is not None and dbg_tn.id[0] != '\0': # 存疑 if string.strcmp(dbg_tn.id, "irq_handler_t") == 0 \ or string.strcmp(dbg_tn.id, "gdt") == 0 \ @@ -2310,7 +2310,7 @@ def _ParseVpiIntoModuleImpl(pool: rawptr[memhub.MemBuddy], # (否则跨模块 count 查找 [CDEF-MISS] fail-fast,VKernel PhaseA 根因) if aa.target is not None and aa.target.kind() == ast.ASTKind.Name \ and aa.value is not None: - cdef_tgt: rawptr[ast.Name] = rawptr[ast.Name](aa.target) + cdef_tgt: ast.Name* = ast.Name*(aa.target) if cdef_tgt.id is not None: # 字符串 CDefine(版本号等)跳过:extract_cdefine_int_value # 对字符串常量 fail-fast,且 count 引用只关心整数 CDefine @@ -2318,7 +2318,7 @@ def _ParseVpiIntoModuleImpl(pool: rawptr[memhub.MemBuddy], cdef_is_float: int = 0 cdef_float_val: double = 0.0 if aa.value.kind() == ast.ASTKind.Constant: - cn_v: rawptr[ast.Constant] = rawptr[ast.Constant](aa.value) + cn_v: ast.Constant* = ast.Constant*(aa.value) if cn_v.const_kind == ast.CONST_STR: cdef_is_str = 1 elif cn_v.const_kind == ast.CONST_FLOAT: @@ -2381,10 +2381,10 @@ def ResetVpiInjectVisited() -> None: _vpi_inj_depth = 0 -def _ensure_dep_vpi_injected(pool: rawptr[memhub.MemBuddy], - mod: rawptr[llvmlite.LLVMModule], +def _ensure_dep_vpi_injected(pool: memhub.MemBuddy*, + mod: llvmlite.LLVMModule*, dep_sha1: str, - trans: rawptr[HT.Translator]) -> int: + trans: HT.Translator*) -> int: """按需注入 dep_sha1 对应的 .vpi 到当前模块(防重入),1=就绪 / 0=失败""" global _vpi_inj_sha1s, _vpi_inj_count, _vpi_inj_depth if pool is None or mod is None or dep_sha1 is None or trans is None: @@ -2456,13 +2456,13 @@ def _ensure_dep_vpi_injected(pool: rawptr[memhub.MemBuddy], # # Args: src_name 子模块中的原类名;local_name 包命名空间中的名字(或 as 别名);sub_sha1 子模块(定义文件)sha1;pkg_sha1 当前包 __init__ 的 sha1;trans 翻译器对象(源 entry 缺失时按需注入子模块 vpi 需要) # ============================================================ -def _inject_reexport_class_declare(pool: rawptr[memhub.MemBuddy], - mod: rawptr[llvmlite.LLVMModule], +def _inject_reexport_class_declare(pool: memhub.MemBuddy*, + mod: llvmlite.LLVMModule*, src_name: str, local_name: str, sub_sha1: str, pkg_sha1: str, - trans: rawptr[HT.Translator]) -> int: + trans: HT.Translator*) -> int: """把包子模块重导出的类以包 sha1 注册别名 entry(方案A:ast.Attribute 归属 ast 包)""" if pool is None or mod is None or src_name is None or local_name is None: return 0 @@ -2474,7 +2474,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: rawptr[GenTypes.StructEntry] = GenApi.find_struct_by_module(src_name, sub_sha1) + src_entry: 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 后 @@ -2497,17 +2497,17 @@ def _inject_reexport_class_declare(pool: rawptr[memhub.MemBuddy], # 跨模块 stub 注入 struct 时必须同步 packed 标记(<{...}>),否则引用 # 模块按非 packed 布局 GEP,与定义侧 packed 布局错位(B5)。 # ============================================================ -def _vpi_tattr_name(node: rawptr[ast.AST], attr_name: str) -> int: +def _vpi_tattr_name(node: ast.AST*, attr_name: str) -> int: """从 t.attr. / t.attr.(args) 提取最外层属性名并比较""" if node is None: return 0 if node.kind() == ast.ASTKind.Call: - cl2: rawptr[ast.Call] = rawptr[ast.Call](node) + cl2: ast.Call* = ast.Call*(node) if cl2.func is None: return 0 return _vpi_tattr_name(cl2.func, attr_name) if node.kind() == ast.ASTKind.Attribute: - at2: rawptr[ast.Attribute] = rawptr[ast.Attribute](node) + at2: ast.Attribute* = ast.Attribute*(node) if at2.attr is None: return 0 return 1 if string.strcmp(at2.attr, attr_name) == 0 else 0 @@ -2522,21 +2522,21 @@ def _vpi_class_has_packed(decorator_list: list[ast.AST*]*) -> int: if dn == 0: return 0 for di in range(dn): - deco: rawptr[ast.AST] = decorator_list.get(di) + deco: ast.AST* = decorator_list.get(di) if deco is None: continue if deco.kind() == ast.ASTKind.Call: - cl: rawptr[ast.Call] = rawptr[ast.Call](deco) + cl: ast.Call* = ast.Call*(deco) if cl.func is None or cl.func.kind() != ast.ASTKind.Attribute: continue - at0: rawptr[ast.Attribute] = rawptr[ast.Attribute](cl.func) + at0: ast.Attribute* = ast.Attribute*(cl.func) if at0.attr is None or string.strcmp(at0.attr, "Attribute") != 0: continue if cl.args is None: continue an: sizet = len(cl.args) for ai in range(an): - ag: rawptr[ast.AST] = cl.args.get(ai) + ag: ast.AST* = cl.args.get(ai) if ag is not None and _vpi_tattr_name(ag, "packed") != 0: return 1 else: @@ -2545,7 +2545,7 @@ def _vpi_class_has_packed(decorator_list: list[ast.AST*]*) -> int: return 0 -def _vpi_class_is_renum(class_cd: rawptr[ast.ClassDef]) -> int: +def _vpi_class_is_renum(class_cd: ast.ClassDef*) -> int: """检查 vpi ClassDef 是否为 REnum(基类含 t.REnum),返回 1=是 / 0=否 vpi 文本保留原始基类(`class LLVMType(t.REnum):`),故可据此识别。 @@ -2558,18 +2558,18 @@ def _vpi_class_is_renum(class_cd: rawptr[ast.ClassDef]) -> int: bases: list[ast.AST*]* = class_cd.bases bn: sizet = len(bases) for bi in range(bn): - base_node: rawptr[ast.AST] = bases.get(bi) + base_node: ast.AST* = bases.get(bi) if base_node is None: continue bk: int = base_node.kind() # Attribute(t.REnum) 形式 if bk == ast.ASTKind.Attribute: - at: rawptr[ast.Attribute] = rawptr[ast.Attribute](base_node) + at: ast.Attribute* = ast.Attribute*(base_node) if at.attr is not None and string.strcmp(at.attr, "REnum") == 0: return 1 # Name(REnum) 形式(from t import REnum) elif bk == ast.ASTKind.Name: - nm: rawptr[ast.Name] = rawptr[ast.Name](base_node) + nm: ast.Name* = ast.Name*(base_node) if nm.id is not None and string.strcmp(nm.id, "REnum") == 0: return 1 return 0 @@ -2584,11 +2584,11 @@ def _vpi_class_is_renum(class_cd: rawptr[ast.ClassDef]) -> int: # 2) 未注册 → 解析字段类型 → 创建命名 StructType("sha1.ClassName") → register_struct + add_visible_struct。 # 字段解析失败不 fatal(不注册该类,留给源模块编译注册,后续裸类名引用由调用侧 fail-fast 暴露)。 # ============================================================ -def _inject_class_struct_declare(pool: rawptr[memhub.MemBuddy], - mod: rawptr[llvmlite.LLVMModule], - class_cd: rawptr[ast.ClassDef], +def _inject_class_struct_declare(pool: memhub.MemBuddy*, + mod: llvmlite.LLVMModule*, + class_cd: ast.ClassDef*, cls_name: str, - trans: rawptr[HT.Translator], + trans: HT.Translator*, src_sha1: str, imported_modules: str, from_imports: str) -> int: @@ -2611,7 +2611,7 @@ def _inject_class_struct_declare(pool: rawptr[memhub.MemBuddy], return 1 # 1. 已注册检查(含源模块编译时注册的 entry):仅标记可见,避免重复注册 if src_sha1 is not None and src_sha1[0] != '\0': - existing_c: rawptr[GenTypes.StructEntry] = GenApi.find_struct_by_module(cls_name, src_sha1) + existing_c: 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 @@ -2623,8 +2623,8 @@ def _inject_class_struct_declare(pool: rawptr[memhub.MemBuddy], if _vpi_class_is_renum(class_cd) != 0: return 0 # 2. 收集字段类型(AnnAssign 子节点,仿 ClassGenDef.translate_class_def) - field_names_buf: sizet | t.CPtr = pool.alloc(8 * GenTypes.FIELD_MAX) - field_types_buf: sizet | t.CPtr = pool.alloc(8 * GenTypes.FIELD_MAX) + field_names_buf: sizet* = pool.alloc(8 * GenTypes.FIELD_MAX) + field_types_buf: sizet* = pool.alloc(8 * GenTypes.FIELD_MAX) if field_names_buf is None or field_types_buf is None: return 0 string.memset(field_names_buf, 0, 8 * GenTypes.FIELD_MAX) @@ -2634,20 +2634,20 @@ def _inject_class_struct_declare(pool: rawptr[memhub.MemBuddy], if cls_children_c is not None: cn_c: sizet = len(cls_children_c) for ci_c in range(cn_c): - m_child_c: rawptr[ast.AST] = cls_children_c.get(ci_c) + m_child_c: ast.AST* = cls_children_c.get(ci_c) if m_child_c is None: continue if m_child_c.kind() != ast.ASTKind.AnnAssign: continue - m_aa_c: rawptr[ast.AnnAssign] = rawptr[ast.AnnAssign](m_child_c) + m_aa_c: ast.AnnAssign* = ast.AnnAssign*(m_child_c) if m_aa_c is None or m_aa_c.target is None: continue if m_aa_c.target.kind() != ast.ASTKind.Name: continue - m_tgt_c: rawptr[ast.Name] = rawptr[ast.Name](m_aa_c.target) + m_tgt_c: ast.Name* = ast.Name*(m_aa_c.target) if m_tgt_c.id is None: continue - field_ty_c: rawptr[llvmlite.LLVMType] = GenApi.resolve_annotation_type( + field_ty_c: llvmlite.LLVMType* = GenApi.resolve_annotation_type( pool, m_aa_c.annotation, imported_modules, from_imports, trans, 0) if field_ty_c is None: # 字段类型解析失败:不注册该类(留给源模块编译注册),不 fatal @@ -2664,7 +2664,7 @@ def _inject_class_struct_declare(pool: rawptr[memhub.MemBuddy], 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]) + fty_c: llvmlite.LLVMType* = (llvmlite.LLVMType*)(field_types_buf[fi_c]) pnode_c: rawptr[llvmlite.ParamNode] = pool.alloc(llvmlite.ParamNode.__sizeof__()) if pnode_c is None: continue @@ -2690,14 +2690,14 @@ def _inject_class_struct_declare(pool: rawptr[memhub.MemBuddy], name_buf_c[sh_len_c] = '.' string.strcpy(name_buf_c + sh_len_c + 1, cls_name) type_name_c = name_buf_c - struct_ty_c: rawptr[llvmlite.LLVMType] = llvmlite.Struct( + struct_ty_c: llvmlite.LLVMType* = llvmlite.Struct( pool, first_node_c, field_count, type_name_c) if struct_ty_c is None: return 0 # 5. StdlibAlloc(Phase B)时深拷贝到 perm_pool,跨文件 reset 存活 # (对齐 ClassGenDef.translate_class_def L489-494) if GenApi.get_stdlib_alloc() != 0: - st_copy_c: rawptr[llvmlite.LLVMType] = llvmlite.DeepCopyType( + st_copy_c: llvmlite.LLVMType* = llvmlite.DeepCopyType( CompilerFactory.factory.PermPool, struct_ty_c) if st_copy_c is not None: struct_ty_c = st_copy_c @@ -2708,7 +2708,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: rawptr[GenTypes.StructEntry] = GenApi.register_struct( + entry_c: GenTypes.StructEntry* = GenApi.register_struct( pool, cls_name, struct_ty_c, src_sha1) if entry_c is None: return 0 @@ -2723,7 +2723,7 @@ def _inject_class_struct_declare(pool: rawptr[memhub.MemBuddy], afi_c: int = 0 for afi_c in range(field_count): af_name_c: str = str(field_names_buf[afi_c]) - af_ty_c: rawptr[llvmlite.LLVMType] = (rawptr[llvmlite.LLVMType])(field_types_buf[afi_c]) + af_ty_c: llvmlite.LLVMType* = (llvmlite.LLVMType*)(field_types_buf[afi_c]) GenApi.add_field(pool, entry_c, af_name_c, af_ty_c) GenApi.add_visible_struct(pool, cls_name) return 1 @@ -2736,14 +2736,14 @@ def _inject_class_struct_declare(pool: rawptr[memhub.MemBuddy], # 均报 "use of undefined type"(值类型大小需已知)。vpi 注入类已 add_field 含字段(完整 Ty),在注册表可查时注册完整定义; # 指针引用(Ptr(Struct))无需——_scan_type_for_cross_module_refs 的 Ptr 分支添加 opaque 即可。 # ============================================================ -def _ensure_full_value_types(mod: rawptr[llvmlite.LLVMModule], - pool: rawptr[memhub.MemBuddy], - ty: rawptr[llvmlite.LLVMType]) -> None: +def _ensure_full_value_types(mod: llvmlite.LLVMModule*, + pool: memhub.MemBuddy*, + ty: llvmlite.LLVMType*) -> None: """递归为值 struct / 数组元素 struct 注册完整定义(递归深度守卫)""" if mod is None or pool is None or ty is None: return match ty: case llvmlite.LLVMType.Struct(_, _, _): - full_se_h: rawptr[GenTypes.StructEntry] = GenApi.find_struct_by_type(ty) + full_se_h: 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)—— @@ -2773,10 +2773,10 @@ def _ensure_full_value_types(mod: rawptr[llvmlite.LLVMModule], # Windows x64 ABI 小结构体(≤8 字节)按整数寄存器传、位兼容,且与定义侧同样降级 ⇒ 同符号签名仍逐字一致)。 # * TPV 内部函数/方法(存在 define 侧)→ Ptr(struct):与定义侧逐字一致,指针目标只需 opaque 声明(module_ensure_opaque_for_type)。 # ============================================================ -def _AggregateParamTy(mod: rawptr[llvmlite.LLVMModule], - pool: rawptr[memhub.MemBuddy], - ty: rawptr[llvmlite.LLVMType], - is_c_abi: int) -> rawptr[llvmlite.LLVMType]: +def _AggregateParamTy(mod: llvmlite.LLVMModule*, + pool: memhub.MemBuddy*, + ty: llvmlite.LLVMType*, + is_c_abi: int) -> llvmlite.LLVMType*: """裸结构体形参类型(C ABI 按值 / 内部 Ptr(struct),见上方注释)""" if mod is None or pool is None or ty is None: return ty @@ -2793,7 +2793,7 @@ def _AggregateParamTy(mod: rawptr[llvmlite.LLVMModule], _ensure_full_value_types(mod, pool, ty) return ty return llvmlite.Int64(pool) - ptr_ty_ap: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, ty) + ptr_ty_ap: llvmlite.LLVMType* = llvmlite.Ptr(pool, ty) llvmlite.module_ensure_opaque_for_type(mod, pool, ptr_ty_ap) return ptr_ty_ap @@ -2804,22 +2804,22 @@ def _AggregateParamTy(mod: rawptr[llvmlite.LLVMModule], # vpi 里模块级全局变量(如 tokens.vp 的 _op_head: OpEntry | t.CPtr = None)需在当前模块创建 external global 声明(短名 @name,COFF 按名链接), # 否则跨模块 from-import 读取全局变量时 find_global_in_module 找不到 → 误杀「跨模块全局变量类型未知(stub 未注入)」。 # ============================================================ -def _inject_global_variable_declare(pool: rawptr[memhub.MemBuddy], - mod: rawptr[llvmlite.LLVMModule], - aa: rawptr[ast.AnnAssign], - trans: rawptr[HT.Translator], +def _inject_global_variable_declare(pool: memhub.MemBuddy*, + mod: llvmlite.LLVMModule*, + aa: ast.AnnAssign*, + trans: HT.Translator*, imported_modules: str, from_imports: str, - i32_ty: rawptr[llvmlite.LLVMType], - i8_ptr_ty: rawptr[llvmlite.LLVMType], + i32_ty: llvmlite.LLVMType*, + i8_ptr_ty: llvmlite.LLVMType*, src_sha1: str) -> None: """从 vpi AnnAssign 创建模块级全局变量 external declare(mangled 名 @.)""" if pool is None or mod is None or aa is None or trans is None: return - tgt_v: rawptr[ast.AST] = aa.target + tgt_v: ast.AST* = aa.target if tgt_v is None or tgt_v.kind() != ast.ASTKind.Name: return - nm_v: rawptr[ast.Name] = rawptr[ast.Name](tgt_v) + nm_v: ast.Name* = ast.Name*(tgt_v) if nm_v is None or nm_v.id is None: return gname_v: str = nm_v.id @@ -2843,24 +2843,24 @@ 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: rawptr[llvmlite.GlobalVariable] = mod.GlobalHead + cur_v: 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 cur_v = cur_v.Next # 解析注解类型(裸类 → Ptr(struct),CArray → 元素指针) - resolved_v: rawptr[llvmlite.LLVMType] = None + resolved_v: llvmlite.LLVMType* = None if aa.annotation is not None: resolved_v = GenApi.resolve_annotation_type( pool, aa.annotation, imported_modules, from_imports, trans) if resolved_v is None: return # 类型解析失败跳过:调用侧有 fail-fast 定位 - gv_ty_v: rawptr[llvmlite.LLVMType] = resolved_v + gv_ty_v: llvmlite.LLVMType* = resolved_v match resolved_v: 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: rawptr[GenTypes.StructEntry] = GenApi.find_struct_by_type(resolved_v) + gv_entry_v: 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) @@ -2887,7 +2887,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: rawptr[llvmlite.GlobalVariable] = llvmlite.new_global_variable(pool, gv_name_m, gv_ty_v) + gv_v: 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) @@ -2901,16 +2901,16 @@ def _inject_global_variable_declare(pool: rawptr[memhub.MemBuddy], # 用 find_func_in_module 去重,创建 declare 并添加参数, # 注册到函数表。 # ============================================================ -def _inject_function_declare(pool: rawptr[memhub.MemBuddy], - mod: rawptr[llvmlite.LLVMModule], - fd: rawptr[ast.FunctionDef], - trans: rawptr[HT.Translator], +def _inject_function_declare(pool: memhub.MemBuddy*, + mod: llvmlite.LLVMModule*, + fd: ast.FunctionDef*, + trans: HT.Translator*, src_sha1: str, imported_modules: str, from_imports: str, - i32_ty: rawptr[llvmlite.LLVMType], - i8_ptr_ty: rawptr[llvmlite.LLVMType], - funcs_ptr: rawptr[GenTypes.FuncEntry], + i32_ty: llvmlite.LLVMType*, + i8_ptr_ty: llvmlite.LLVMType*, + funcs_ptr: GenTypes.FuncEntry*, max_funcs: int) -> None: """为 FunctionDef 创建 declare 声明并注入到模块""" if fd.name is None: @@ -2942,12 +2942,12 @@ def _inject_function_declare(pool: rawptr[memhub.MemBuddy], mangled_name = GenApi._mangle_name_with_sha1(src_sha1, fd.name) # 去重:如果函数已存在则跳过 - existing: rawptr[llvmlite.Function] = GenApi.find_func_in_module(mod, mangled_name) + existing: llvmlite.Function* = GenApi.find_func_in_module(mod, mangled_name) if existing is not None: return # 也检查裸名(非裸名模式时,CExport 函数可能已通过其他途径注册) if use_bare_name == 0: - existing_bare: rawptr[llvmlite.Function] = GenApi.find_func_in_module(mod, fd.name) + existing_bare: llvmlite.Function* = GenApi.find_func_in_module(mod, fd.name) if existing_bare is not None: return @@ -2955,7 +2955,7 @@ def _inject_function_declare(pool: rawptr[memhub.MemBuddy], # 优先用缓存的返回注解字符串(tree 解析后立即提取,节点未损坏) # 直接字符串解析(绕开 _parse_type_string 跨模块 AST 构造在 TPV 中的 # __init__/vtable 未执行问题,节点 kind() 异常导致 resolve 得垃圾类型) - ret_ty: rawptr[llvmlite.LLVMType] = None + ret_ty: llvmlite.LLVMType* = None ret_annot_fd: str = _lookup_vpi_ret_annot(src_sha1, None, fd.name) if ret_annot_fd is not None: ret_ty = _resolve_vpi_ret_annot_str(pool, ret_annot_fd, i32_ty, i8_ptr_ty) @@ -2974,7 +2974,7 @@ def _inject_function_declare(pool: rawptr[memhub.MemBuddy], if rk2_rt == ast.ASTKind.Name or rk2_rt == ast.ASTKind.Constant: is_pure_marker_rt = 1 elif rk2_rt == ast.ASTKind.Attribute: - pm_at: rawptr[ast.Attribute] = rawptr[ast.Attribute](fd.returns) + pm_at: ast.Attribute* = ast.Attribute*(fd.returns) if pm_at.attr is not None and (string.strcmp(pm_at.attr, "State") == 0 or string.strcmp(pm_at.attr, "CExtern") == 0 or string.strcmp(pm_at.attr, "CExport") == 0): @@ -3002,7 +3002,7 @@ def _inject_function_declare(pool: rawptr[memhub.MemBuddy], llvmlite.module_ensure_opaque_for_type(mod, pool, ret_ty) # 创建 declare - func: rawptr[llvmlite.Function] = llvmlite.create_declare( + func: llvmlite.Function* = llvmlite.create_declare( pool, mod, mangled_name, ret_ty) if func is None: return @@ -3012,7 +3012,7 @@ def _inject_function_declare(pool: rawptr[memhub.MemBuddy], fd_defaults: t.CPtr = None fd_default_count: int = 0 if fd.args is not None: - args_node: rawptr[ast.Arguments] = rawptr[ast.Arguments](fd.args) + args_node: ast.Arguments* = ast.Arguments*(fd.args) if args_node.args is not None: args_list: list[ast.AST*]* = args_node.args param_count = len(args_list) @@ -3028,20 +3028,20 @@ def _inject_function_declare(pool: rawptr[memhub.MemBuddy], VLogger.repl_abort() pi: sizet for pi in range(param_count): - ag: rawptr[ast.Arg] = rawptr[ast.Arg](args_list.get(pi)) + ag: ast.Arg* = ast.Arg*(args_list.get(pi)) if ag is None: continue pname: str = ag.arg if pname is None: pname = "arg" # 解析参数类型 - param_ty: rawptr[llvmlite.LLVMType] = i8_ptr_ty + param_ty: llvmlite.LLVMType* = i8_ptr_ty # 优先用 vpi 文本注解缓存解析参数类型(与返回类型同源——vpi # tree 深层节点 kind() 可能损坏,AST resolve 得垃圾类型如 # sizet→i32,跨模块 declare 参数宽错 → 调用侧 trunc 传参、 # callee 按宽类型读栈残留垃圾高位 → 参数巨值崩溃(SlotsBugTest # 根因)。段索引 = pi(模块级函数无 self,0=首参)。 - pseg_ty: rawptr[llvmlite.LLVMType] = _resolve_vpi_param_annot_seg( + pseg_ty: llvmlite.LLVMType* = _resolve_vpi_param_annot_seg( pool, src_sha1, None, fd.name, pi, i32_ty, i8_ptr_ty) if pseg_ty is not None: match pseg_ty: @@ -3054,7 +3054,7 @@ def _inject_function_declare(pool: rawptr[memhub.MemBuddy], case _: param_ty = pseg_ty elif ag.annotation is not None: - resolved_ty: rawptr[llvmlite.LLVMType] = GenApi.resolve_annotation_type( + resolved_ty: llvmlite.LLVMType* = GenApi.resolve_annotation_type( pool, ag.annotation, imported_modules, from_imports, trans) if resolved_ty is not None: # CArray 参数 → 元素指针 ty*(C 数组衰减,与编译侧一致)。 @@ -3122,17 +3122,17 @@ def _inject_function_declare(pool: rawptr[memhub.MemBuddy], # 方法混淆名 {src_sha1}.{ClassName}.{method};参数类型从 vpi 注解解析(self 无注解时默认为 i8*)。 # 注入正确签名可避免调用时 _ensure_method_declare 用实参类型创建错误 declare(如 size: sizet 被写成 i32 而非 i64)。 # ============================================================ -def _inject_method_declare(pool: rawptr[memhub.MemBuddy], - mod: rawptr[llvmlite.LLVMModule], - m_fd: rawptr[ast.FunctionDef], +def _inject_method_declare(pool: memhub.MemBuddy*, + mod: llvmlite.LLVMModule*, + m_fd: ast.FunctionDef*, cls_name: str, - trans: rawptr[HT.Translator], + trans: HT.Translator*, src_sha1: str, imported_modules: str, from_imports: str, - i32_ty: rawptr[llvmlite.LLVMType], - i8_ptr_ty: rawptr[llvmlite.LLVMType], - funcs_ptr: rawptr[GenTypes.FuncEntry], + i32_ty: llvmlite.LLVMType*, + i8_ptr_ty: llvmlite.LLVMType*, + funcs_ptr: GenTypes.FuncEntry*, max_funcs: int) -> None: """为 ClassDef 内方法创建 declare 声明并注入到模块""" if m_fd is None or m_fd.name is None or cls_name is None: @@ -3155,7 +3155,7 @@ def _inject_method_declare(pool: rawptr[memhub.MemBuddy], viperlib.snprintf(mangled_name, mangled_len, "%s.%s", src_sha1, lookup_name) # 去重:如果方法已存在则跳过 - existing: rawptr[llvmlite.Function] = GenApi.find_func_in_module(mod, mangled_name) + existing: llvmlite.Function* = GenApi.find_func_in_module(mod, mangled_name) if existing is not None: return @@ -3163,7 +3163,7 @@ def _inject_method_declare(pool: rawptr[memhub.MemBuddy], # 优先用缓存的返回注解字符串(tree 解析后立即提取,节点未损坏), # 用 _parse_type_string 重新解析成新 AST(立即使用不被覆盖)。 # 直接解析 m_fd.returns 可能因 vpi tree 深层节点被覆盖而得到垃圾类型。 - ret_ty: rawptr[llvmlite.LLVMType] = None + ret_ty: llvmlite.LLVMType* = None ret_annot: str = _lookup_vpi_ret_annot(src_sha1, cls_name, m_fd.name) if ret_annot is not None: ret_ty = _resolve_vpi_ret_annot_str(pool, ret_annot, i32_ty, i8_ptr_ty) @@ -3172,7 +3172,7 @@ def _inject_method_declare(pool: rawptr[memhub.MemBuddy], pool, m_fd.returns, imported_modules, from_imports, trans) # __new__ 无返回注解时推断为类指针(__new__ 返回 self 指针,默认 i32 会截断指针) if ret_ty is None and string.strcmp(m_fd.name, "__new__") == 0: - cls_ty: rawptr[llvmlite.LLVMType] = GenApi.get_struct_type(cls_name) + cls_ty: llvmlite.LLVMType* = GenApi.get_struct_type(cls_name) if cls_ty is not None: ret_ty = llvmlite.Ptr(pool, cls_ty) # [S4 fail-fast] 有返回注解却解析不出类型 → 不再静默退 i32; @@ -3186,7 +3186,7 @@ def _inject_method_declare(pool: rawptr[memhub.MemBuddy], ret_ty = i32_ty # 创建 declare - func: rawptr[llvmlite.Function] = llvmlite.create_declare( + func: llvmlite.Function* = llvmlite.create_declare( pool, mod, mangled_name, ret_ty) if func is None: return @@ -3196,7 +3196,7 @@ def _inject_method_declare(pool: rawptr[memhub.MemBuddy], md_defaults: t.CPtr = None md_default_count: int = 0 if m_fd.args is not None: - args_node: rawptr[ast.Arguments] = rawptr[ast.Arguments](m_fd.args) + args_node: ast.Arguments* = ast.Arguments*(m_fd.args) if args_node.args is not None: args_list: list[ast.AST*]* = args_node.args param_count = len(args_list) @@ -3210,7 +3210,7 @@ def _inject_method_declare(pool: rawptr[memhub.MemBuddy], VLogger.repl_abort() pi: sizet for pi in range(param_count): - ag: rawptr[ast.Arg] = rawptr[ast.Arg](args_list.get(pi)) + ag: ast.Arg* = ast.Arg*(args_list.get(pi)) if ag is None: continue pname: str = ag.arg @@ -3223,17 +3223,17 @@ def _inject_method_declare(pool: rawptr[memhub.MemBuddy], # 块)。类类型未注册时兜底走下方注解解析/i8*(保持原行为)。 if pi == 0 and (string.strcmp(pname, "self") == 0 or string.strcmp(pname, "cls") == 0): - cls_ty_sd: rawptr[llvmlite.LLVMType] = GenApi.get_struct_type(cls_name) + cls_ty_sd: llvmlite.LLVMType* = GenApi.get_struct_type(cls_name) if cls_ty_sd is not None: llvmlite.add_param(pool, func, llvmlite.Ptr(pool, cls_ty_sd), pname) continue - param_ty: rawptr[llvmlite.LLVMType] = i8_ptr_ty + param_ty: llvmlite.LLVMType* = i8_ptr_ty # 优先用 vpi 文本注解缓存解析参数类型(与返回类型同源——vpi # tree 深层节点 kind() 可能损坏,AST resolve 得垃圾类型如 # sizet→i32,declare 参数宽错 → 调用侧 trunc i64→i32 传参、 # callee 按 i64 读栈残留垃圾高位 → can=巨值读未写槽位崩溃, # SlotsBugTest 根因)。段索引 = pi(0=self 空段)。 - pseg_ty: rawptr[llvmlite.LLVMType] = _resolve_vpi_param_annot_seg( + pseg_ty: llvmlite.LLVMType* = _resolve_vpi_param_annot_seg( pool, src_sha1, cls_name, m_fd.name, pi, i32_ty, i8_ptr_ty) if pseg_ty is not None: match pseg_ty: @@ -3248,7 +3248,7 @@ def _inject_method_declare(pool: rawptr[memhub.MemBuddy], case _: param_ty = pseg_ty elif ag.annotation is not None: - resolved_ty: rawptr[llvmlite.LLVMType] = GenApi.resolve_annotation_type( + resolved_ty: llvmlite.LLVMType* = GenApi.resolve_annotation_type( pool, ag.annotation, imported_modules, from_imports, trans) if resolved_ty is not None: # CArray 参数 → 元素指针 ty*(C 数组衰减,与编译侧一致)。 @@ -3280,16 +3280,16 @@ def _inject_method_declare(pool: rawptr[memhub.MemBuddy], # 与 _translate_method 的 define 签名一致(对齐 TPC HandlesFunctions.py # L703-705)。for x in obj 循环会以 2 个实参调用 __next__(self, flag)。 if m_fd.name is not None and string.strcmp(m_fd.name, "__next__") == 0: - i1_ty_si: rawptr[llvmlite.LLVMType] = llvmlite.Int1(pool) + i1_ty_si: llvmlite.LLVMType* = llvmlite.Int1(pool) if i1_ty_si is not None: - i1_ptr_ty_si: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, i1_ty_si) + i1_ptr_ty_si: llvmlite.LLVMType* = llvmlite.Ptr(pool, i1_ty_si) if i1_ptr_ty_si is not None: llvmlite.add_param(pool, func, i1_ptr_ty_si, "__stop_iter_flag__") # 默认参数:vpi 签名含 '= '(Converter 已输出),提取 defaults # 列表注册默认参数表——跨模块缺参调用(如 resolve_annotation_type 的 # depth=0)才能按表填充,否则被调函数读到栈垃圾(假报递归过深/崩溃)。 if m_fd.args is not None: - md_args_node: rawptr[ast.Arguments] = rawptr[ast.Arguments](m_fd.args) + md_args_node: ast.Arguments* = ast.Arguments*(m_fd.args) if md_args_node.defaults is not None: md_dlist: list[ast.AST*]* = md_args_node.defaults md_default_count = len(md_dlist) @@ -3329,15 +3329,15 @@ def _inject_method_declare(pool: rawptr[memhub.MemBuddy], # 提取 NAME: t.CTypedef = Type 中的名称和类型表达式字符串, # 调用 register_ctypedef 注册到动态 CTypedef 表。 # ============================================================ -def _register_ctypedef_from_annassign(pool: rawptr[memhub.MemBuddy], - aa: rawptr[ast.AnnAssign]) -> None: +def _register_ctypedef_from_annassign(pool: memhub.MemBuddy*, + aa: ast.AnnAssign*) -> None: """从 AnnAssign 节点提取并注册 CTypedef""" if aa is None or pool is None: return # 提取目标名称(必须是 Name 节点) if aa.target is None or aa.target.kind() != ast.ASTKind.Name: return - tgt: rawptr[ast.Name] = rawptr[ast.Name](aa.target) + tgt: ast.Name* = ast.Name*(aa.target) if tgt.id is None: return # 提取类型表达式字符串(从 value AST 节点) @@ -3394,9 +3394,9 @@ def _register_ctypedef_from_annassign(pool: rawptr[memhub.MemBuddy], # 会话级状态(PermPool;会话初始化期间有效) ReplStubLayoutMode: int = 0 -ReplStubPool: rawptr[memhub.MemBuddy] = None +ReplStubPool: memhub.MemBuddy* = None ReplStubTempDir: str = None -ReplStubTable: sizet | t.CPtr = None +ReplStubTable: sizet* = None ReplStubCount: int = 0 ReplStubOk: int = 0 ReplStubVtOk: int = 0 @@ -3413,7 +3413,7 @@ ReplStubTmpArity: int = 0 ReplStubNameBuf: str = None -def _repl_stub_dupstr(pool: rawptr[memhub.MemBuddy], src: str) -> str: +def _repl_stub_dupstr(pool: memhub.MemBuddy*, src: str) -> str: """把字符串深拷贝到指定池""" if src is None or pool is None: return None @@ -3425,7 +3425,7 @@ def _repl_stub_dupstr(pool: rawptr[memhub.MemBuddy], src: str) -> str: return dst -def _repl_stub_key(pool: rawptr[memhub.MemBuddy], sha1: str, cls: str) -> str: +def _repl_stub_key(pool: memhub.MemBuddy*, sha1: str, cls: str) -> str: """拼接 .<类名>:与定义侧 ClassGenDef 的命名结构体名逐字一致""" if pool is None or sha1 is None or cls is None: return None @@ -3664,7 +3664,8 @@ def ReplStubLayoutBegin(temp_dir: str) -> int: global ReplStubLayoutMode, ReplStubPool, ReplStubTempDir, ReplStubTable global ReplStubCount, ReplStubOk, ReplStubVtOk, ReplStubRefused, ReplStubNoStub global ReplStubWarnLeft, ReplStubNameBuf - pool: rawptr[memhub.MemBuddy] = CompilerFactory.factory.PermPool + global ReplStubRefusedNoStub, ReplStubRefusedNoClass, ReplStubRefusedOpaque, ReplStubRefusedParent + pool: memhub.MemBuddy* = CompilerFactory.factory.PermPool if pool is None or temp_dir is None: return 1 ReplStubPool = pool @@ -3744,7 +3745,7 @@ def _repl_stub_find_base(e: rawptr[ReplStubClass], bi: int) -> rawptr[ReplStubCl return None -def _repl_stub_has_name(arr: sizet | t.CPtr, cnt: int, name: str) -> int: +def _repl_stub_has_name(arr: sizet*, cnt: int, name: str) -> int: """名单里是否已有该名(先声明优先去重)""" if arr is None or name is None: return 0 @@ -3770,20 +3771,20 @@ def _repl_stub_deco_flags(deco_list: list[ast.AST*]*) -> int: dn: sizet = len(deco_list) di: sizet for di in range(dn): - deco: rawptr[ast.AST] = deco_list.get(di) + deco: ast.AST* = deco_list.get(di) if deco is None: continue nm: str = None k: int = deco.kind() if k == ast.ASTKind.Attribute: - at: rawptr[ast.Attribute] = rawptr[ast.Attribute](deco) + at: ast.Attribute* = ast.Attribute*(deco) if at.attr is not None and at.value is not None \ and at.value.kind() == ast.ASTKind.Name: - vn: rawptr[ast.Name] = rawptr[ast.Name](at.value) + vn: ast.Name* = ast.Name*(at.value) if vn.id is not None and string.strcmp(vn.id, "t") == 0: nm = at.attr elif k == ast.ASTKind.Name: - nn: rawptr[ast.Name] = rawptr[ast.Name](deco) + nn: ast.Name* = ast.Name*(deco) nm = nn.id if nm is None: continue @@ -3883,7 +3884,7 @@ def _repl_stub_warn_parent(e: rawptr[ReplStubClass], detail: str, pname: str) -> "被拒绝(方法调用不受影响)\n", e.Sha1, e.ClassName, detail, pname) -def _repl_stub_try(e: rawptr[ReplStubClass], mod: rawptr[llvmlite.LLVMModule]) -> int: +def _repl_stub_try(e: rawptr[ReplStubClass], mod: llvmlite.LLVMModule*) -> int: """按存根校验并登记完整布局:1=已登记 / 0=父类未就绪(推迟)/ -1=拒绝""" global ReplStubOk, ReplStubVtOk, ReplStubWarnLeft if e is None: @@ -3894,7 +3895,7 @@ def _repl_stub_try(e: rawptr[ReplStubClass], mod: rawptr[llvmlite.LLVMModule]) - return -1 if e.State != _REPL_SS_PENDING: return -1 - pool: rawptr[memhub.MemBuddy] = ReplStubPool + pool: memhub.MemBuddy* = ReplStubPool if pool is None: e.State = _REPL_SS_REFUSED return -1 @@ -4017,7 +4018,7 @@ def _repl_stub_try(e: rawptr[ReplStubClass], mod: rawptr[llvmlite.LLVMModule]) - e.Sha1, e.ClassName, vn, e.VtArity) # ⑥ 建 LLVM 结构体(命名 "%.<类名>",与定义侧同口径) total: int = cn + hv - i8_ptr: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, llvmlite.Int8(pool)) + i8_ptr: llvmlite.LLVMType* = llvmlite.Ptr(pool, llvmlite.Int8(pool)) if i8_ptr is None: return 0 first_node: rawptr[llvmlite.ParamNode] = None @@ -4032,7 +4033,7 @@ def _repl_stub_try(e: rawptr[ReplStubClass], mod: rawptr[llvmlite.LLVMModule]) - prev_node = nd0 fi2: int for fi2 in range(cn): - fty: rawptr[llvmlite.LLVMType] = (rawptr[llvmlite.LLVMType])(e.Types[fi2]) + fty: llvmlite.LLVMType* = (llvmlite.LLVMType*)(e.Types[fi2]) if fty is None: continue nd: rawptr[llvmlite.ParamNode] = pool.alloc(llvmlite.ParamNode.__sizeof__()) @@ -4045,11 +4046,11 @@ def _repl_stub_try(e: rawptr[ReplStubClass], mod: rawptr[llvmlite.LLVMModule]) - if prev_node is not None: prev_node.Next = nd prev_node = nd - struct_ty: rawptr[llvmlite.LLVMType] = llvmlite.Struct(pool, first_node, total, e.Key) + struct_ty: llvmlite.LLVMType* = llvmlite.Struct(pool, first_node, total, e.Key) if struct_ty is None: return 0 # ⑦ 登记(StdlibAlloc=1 期间的注册走 PermPool,跨片段存活) - entry: rawptr[GenTypes.StructEntry] = GenApi.register_struct( + entry: GenTypes.StructEntry* = GenApi.register_struct( pool, e.ClassName, struct_ty, e.Sha1) if entry is None: e.State = _REPL_SS_REFUSED @@ -4066,7 +4067,7 @@ def _repl_stub_try(e: rawptr[ReplStubClass], mod: rawptr[llvmlite.LLVMModule]) - fi3: int for fi3 in range(cn): fname: str = (str | t.CPtr)(e.Names[fi3]) - fty3: rawptr[llvmlite.LLVMType] = (rawptr[llvmlite.LLVMType])(e.Types[fi3]) + fty3: llvmlite.LLVMType* = (llvmlite.LLVMType*)(e.Types[fi3]) if fname is None or fty3 is None: continue GenApi.add_field(pool, entry, fname, fty3) @@ -4077,7 +4078,7 @@ def _repl_stub_try(e: rawptr[ReplStubClass], mod: rawptr[llvmlite.LLVMModule]) - entry.HasNew = e.HasNew # 父类名(多继承数组;顺序同声明序,供 vtable/MRO/字段继承查询) if e.BaseCount > 0: - arr: sizet | t.CPtr = pool.alloc(8 * e.BaseCount) + arr: sizet* = pool.alloc(8 * e.BaseCount) if arr is not None: string.memset(arr, 0, 8 * e.BaseCount) bi3: int @@ -4099,13 +4100,13 @@ def _repl_stub_try(e: rawptr[ReplStubClass], mod: rawptr[llvmlite.LLVMModule]) - return 1 -def _repl_stub_add_class(pool: rawptr[memhub.MemBuddy], - mod: rawptr[llvmlite.LLVMModule], - cd: rawptr[ast.ClassDef], +def _repl_stub_add_class(pool: memhub.MemBuddy*, + mod: llvmlite.LLVMModule*, + cd: ast.ClassDef*, sha1: str, txt: str, have_stub: int, - trans: rawptr[HT.Translator], + trans: HT.Translator*, imported_modules: str, from_imports: str) -> int: """收集单个 vpi ClassDef 的布局要素并尝试登记(1=已登记/推迟处理,0=跳过) @@ -4160,7 +4161,7 @@ def _repl_stub_add_class(pool: rawptr[memhub.MemBuddy], if _vpi_class_has_packed(cd.decorator_list) != 0: e.Flags = e.Flags | _REPL_SF_PACKED # 真实父类(复用 ClassGenBase._collect_parents:别名解析 + marker 剔除) - pb: sizet | t.CPtr = pool.alloc(8 * GenTypes.PARENT_MAX) + pb: sizet* = pool.alloc(8 * GenTypes.PARENT_MAX) bcnt: int = 0 if pb is not None and GenApi._g_gen is not None: string.memset(pb, 0, 8 * GenTypes.PARENT_MAX) @@ -4183,22 +4184,22 @@ def _repl_stub_add_class(pool: rawptr[memhub.MemBuddy], cn: sizet = len(children) ci: sizet for ci in range(cn): - ch2: rawptr[ast.AST] = children.get(ci) + ch2: ast.AST* = children.get(ci) if ch2 is None: continue k2: int = ch2.kind() if k2 == ast.ASTKind.AnnAssign: if e.OwnCount >= _REPL_STUB_FIELD_MAX: continue - aa2: rawptr[ast.AnnAssign] = rawptr[ast.AnnAssign](ch2) + aa2: ast.AnnAssign* = ast.AnnAssign*(ch2) if aa2 is None or aa2.target is None or aa2.annotation is None: continue if aa2.target.kind() != ast.ASTKind.Name: continue - tg: rawptr[ast.Name] = rawptr[ast.Name](aa2.target) + tg: ast.Name* = ast.Name*(aa2.target) if tg.id is None or tg.id[0] == '\0': continue - fty2: rawptr[llvmlite.LLVMType] = GenApi.resolve_annotation_type( + fty2: llvmlite.LLVMType* = GenApi.resolve_annotation_type( pool, aa2.annotation, imported_modules, from_imports, trans, 0) if fty2 is None: own_fail = 1 @@ -4212,7 +4213,7 @@ def _repl_stub_add_class(pool: rawptr[memhub.MemBuddy], e.OwnCount += 1 continue if k2 == ast.ASTKind.FunctionDef: - fd2: rawptr[ast.FunctionDef] = rawptr[ast.FunctionDef](ch2) + fd2: ast.FunctionDef* = ast.FunctionDef*(ch2) if fd2 is None or fd2.name is None or fd2.name[0] == '\0': continue mf2: int = _repl_stub_deco_flags(fd2.decorator_list) @@ -4273,11 +4274,11 @@ def _repl_stub_add_class(pool: rawptr[memhub.MemBuddy], return 1 -def _repl_stub_collect_module(pool: rawptr[memhub.MemBuddy], - mod: rawptr[llvmlite.LLVMModule], +def _repl_stub_collect_module(pool: memhub.MemBuddy*, + mod: llvmlite.LLVMModule*, ch: list[ast.AST*]*, n: sizet, - trans: rawptr[HT.Translator], + trans: HT.Translator*, src_sha1: str, imported_modules: str, from_imports: str) -> int: @@ -4308,19 +4309,19 @@ def _repl_stub_collect_module(pool: rawptr[memhub.MemBuddy], cnt: int = 0 i: sizet for i in range(n): - child: rawptr[ast.AST] = ch.get(i) + child: ast.AST* = ch.get(i) if child is None: continue if child.kind() != ast.ASTKind.ClassDef: continue - cd: rawptr[ast.ClassDef] = rawptr[ast.ClassDef](child) + cd: ast.ClassDef* = ast.ClassDef*(child) if cd is None or cd.name is None: continue # 泛型模板类:与 _inject_class_struct_declare / 第一遍 A 同口径跳过(模板签名 # 含类级类型参数 T,注入时 T 无法确定)。但**归属模块必须登记**:REPL 会话不 # 注册 includes 泛型模板,故注解里的泛型下标(list[rawptr[AST]] 等)要靠 # "模板模块 sha1" 拼定义侧特化名造类型占位(TypeGenResolve 的 ReplCtx 分支)。 - tp: list[str] | t.CPtr = cd.type_params + tp: list[str]* = cd.type_params if tp is not None and len(tp) > 0: StubMergerStore.RegisterGenericOwner(cd.name, src_sha1) continue diff --git a/App/lib/Stub/StubMerger/StubMergerBuild.vp b/App/lib/Stub/StubMerger/StubMergerBuild.vp index 7531b59..d93d522 100644 --- a/App/lib/Stub/StubMerger/StubMergerBuild.vp +++ b/App/lib/Stub/StubMerger/StubMergerBuild.vp @@ -765,7 +765,7 @@ def _AppendDepsToWorklist(worklist: bytes, wl_len: sizet, # Args: mb 内存池;source_dir App 源文件目录(Config.SourceDir);temp_dir 临时目录(deps.txt 所在位置);reachable_set 输出参数,可达 SHA1 集合缓冲区(MAX_INCLUDES_SHA1 * 17 字节);app_deps App 源文件直接依赖模块名(空格分隔),非空则跳过 App 扫描;includes_dirs includes 根目录(空格分隔) # Returns: 可达 SHA1 数量(>0 成功;0 无 includes 依赖;<0 失败) # ============================================================ -def _BuildReachableSha1Set(mb: rawptr[memhub.MemBuddy], source_dir: str, +def _BuildReachableSha1Set(mb: memhub.MemBuddy*, source_dir: str, temp_dir: str, reachable_set: str, app_deps: str = None, @@ -802,11 +802,11 @@ def _BuildReachableSha1Set(mb: rawptr[memhub.MemBuddy], source_dir: str, if sbuf is None: mb.reset_to(app_mark) continue - lx: rawptr[ast.Lexer] = ast.new_lexer(mb) - tree: rawptr[ast.AST] = None + lx: ast.Lexer* = ast.new_lexer(mb) + tree: ast.AST* = None if lx is not None: ast._lexer_init(lx, sbuf, mb) - tokens: rawptr[ast.Token] = ast.tokenize(lx) + tokens: ast.Token* = ast.tokenize(lx) tree = ast.parse_tokens(mb, tokens) if tree is not None: tr: rawptr[HandlesTranslator.Translator] = HandlesTranslator.Translator() @@ -910,7 +910,7 @@ def _BuildReachableSha1Set(mb: rawptr[memhub.MemBuddy], source_dir: str, stdlib.free(worklist) stdlib.free(processed) return -1 - wl_pos_slot: sizet | t.CPtr = (sizet | t.CPtr)(wl_pos) + wl_pos_slot: sizet* = (sizet*)(wl_pos) wl_pos_slot[0] = 0 while wl_pos_slot[0] < wl_len: @@ -981,14 +981,14 @@ def _BuildReachableSha1Set(mb: rawptr[memhub.MemBuddy], source_dir: str, stdlib.free(mod_buf) continue # 输出槽防御性初始化(成功路径必全写;未找到/未命中时仅 free 槽本身) - # 槽联合必须用 (sizet | t.CPtr):t.CPtr|t.CPtr 会被折叠成 t.CPtr, + # 槽联合必须用 (sizet*):t.CPtr|t.CPtr 会被折叠成 t.CPtr, # [0] 变成 1 字节访问 → 指针被截断(0x2e 崩溃根因)。CSizeT 成员为 # 8 字节:写侧 sizet(ptr),读侧必须用 (str | t.CPtr)(slot[0]) 做 u64→ # 指针转换;str(slot[0]) 是内置"数字转字符串"(snprintf 到栈缓冲并返回 # 该栈地址),拿到的是十进制文本+栈指针 → free 即 bad-free。 - abs_slot: sizet | t.CPtr = (sizet | t.CPtr)(out_abs) - rel_slot: sizet | t.CPtr = (sizet | t.CPtr)(out_rel) - inc_slot: sizet | t.CPtr = (sizet | t.CPtr)(out_inc) + abs_slot: sizet* = (sizet*)(out_abs) + rel_slot: sizet* = (sizet*)(out_rel) + inc_slot: sizet* = (sizet*)(out_inc) abs_slot[0] = 0 rel_slot[0] = 0 inc_slot[0] = 0 @@ -1062,11 +1062,11 @@ def _BuildReachableSha1Set(mb: rawptr[memhub.MemBuddy], source_dir: str, stdlib.free(mod_buf) mb.reset_to(scan_mark_r) continue - lx_r: rawptr[ast.Lexer] = ast.new_lexer(mb) - tree_r: rawptr[ast.AST] = None + lx_r: ast.Lexer* = ast.new_lexer(mb) + tree_r: ast.AST* = None if lx_r is not None: ast._lexer_init(lx_r, sbuf_r, mb) - tokens_r: rawptr[ast.Token] = ast.tokenize(lx_r) + tokens_r: ast.Token* = ast.tokenize(lx_r) tree_r = ast.parse_tokens(mb, tokens_r) if tree_r is None: VLogger.error(f"可达 includes 解析失败: {abs_path}", "Reachable") @@ -1760,8 +1760,8 @@ def BuildCombinedIR(temp_dir: str, local_sha1: str, # Args: pool 内存池;mod 当前 LLVM 模块;imported_modules 已导入模块名字符串(空格分隔);from_imports from-import 映射字符串("name:module name:module" 格式);temp_dir temp 目录路径;trans 翻译器对象 # Returns: 成功加载的 .vpi 文件数 # ============================================================ -def LoadDepVpiIntoModule(pool: rawptr[memhub.MemBuddy], - mod: rawptr[llvmlite.LLVMModule], +def LoadDepVpiIntoModule(pool: memhub.MemBuddy*, + mod: llvmlite.LLVMModule*, imported_modules: str, from_imports: str, temp_dir: str, diff --git a/App/lib/Stub/StubMerger/StubMergerCollect.vp b/App/lib/Stub/StubMerger/StubMergerCollect.vp index 46caccc..c7d5507 100644 --- a/App/lib/Stub/StubMerger/StubMergerCollect.vp +++ b/App/lib/Stub/StubMerger/StubMergerCollect.vp @@ -166,7 +166,7 @@ def _collect_stub_sha1s(base_dir: str, bd_len: sizet, level: int, # 数据来源是 PopulateSha1MapStore 填充的全局存储器(不读取 _sha1_map.txt)。 # 用于过滤 stub 文件,避免加载 TransPyV 自身源文件(lib/*)的 stub 导致链接失败。 # ============================================================ -def _load_includes_sha1_set(pool: rawptr[memhub.MemBuddy], +def _load_includes_sha1_set(pool: memhub.MemBuddy*, temp_dir: str, sha1_set: str) -> int: """从全局内存存储器将 includes 的 SHA1 写入 sha1_set @@ -205,7 +205,7 @@ def _is_in_sha1_set(sha1: str, sha1_set: str, set_count: int) -> int: # Args: mb 内存池;temp_dir 临时目录(_sha1_map.txt 写入位置);scan_result IncludesScanner 扫描结果 # Returns: 0 成功,非 0 失败 # ============================================================ -def WriteIncludesSha1Map(mb: rawptr[memhub.MemBuddy], temp_dir: str, +def WriteIncludesSha1Map(mb: memhub.MemBuddy*, temp_dir: str, scan_result: rawptr[IncludesScanner.ScanResult], filter_set: str, filter_count: int) -> int: diff --git a/App/lib/Stub/StubMerger/StubMergerTopo.vp b/App/lib/Stub/StubMerger/StubMergerTopo.vp index 32c16e0..2b8a4c5 100644 --- a/App/lib/Stub/StubMerger/StubMergerTopo.vp +++ b/App/lib/Stub/StubMerger/StubMergerTopo.vp @@ -44,13 +44,13 @@ import lib.Stub.StubMerger as StubMerger def BuildTopoSortedIndices(store_count: int, store_sha1_arr: bytes, store_mod_arr: bytes, reachable_set: bytes, reachable_count: int, - sorted_idx: sizet | t.CPtr) -> int: + sorted_idx: sizet*) -> int: """对可达 includes 逆拓扑排序(被依赖者先),store 索引写入 sorted_idx""" if store_count <= 0 or store_sha1_arr is None or store_mod_arr is None or sorted_idx is None: return 0 - indegree: sizet | t.CPtr = (sizet | t.CPtr)(stdlib.malloc(8 * (store_count + 1))) - queue: sizet | t.CPtr = (sizet | t.CPtr)(stdlib.malloc(8 * (store_count + 1))) - rel_idx: sizet | t.CPtr = (sizet | t.CPtr)(stdlib.malloc(8 * (store_count + 1))) + indegree: sizet* = (sizet*)(stdlib.malloc(8 * (store_count + 1))) + queue: sizet* = (sizet*)(stdlib.malloc(8 * (store_count + 1))) + rel_idx: sizet* = (sizet*)(stdlib.malloc(8 * (store_count + 1))) if indegree is None or queue is None or rel_idx is None: if indegree is not None: stdlib.free(indegree) diff --git a/App/lib/Stub/StubMerger/__init__.vp b/App/lib/Stub/StubMerger/__init__.vp index 2eb1df1..2af57b2 100644 --- a/App/lib/Stub/StubMerger/__init__.vp +++ b/App/lib/Stub/StubMerger/__init__.vp @@ -27,7 +27,7 @@ import lib.Projectrans.Config as Config # ============================================================ # 全局 mbuddy 指针 -_mbuddy: rawptr[memhub.MemBuddy] +_mbuddy: memhub.MemBuddy* # 最大 includes SHA1 数(用于过滤) MAX_INCLUDES_SHA1: t.CDefine = 1024 diff --git a/App/lib/__init__.vp b/App/lib/__init__.vp index d0efa99..a39eb5b 100644 --- a/App/lib/__init__.vp +++ b/App/lib/__init__.vp @@ -10,4 +10,4 @@ import lib.core.VLogger as VLogger # 全局 mbuddy 内存池指针(由 App/main.vp 初始化后注入) # 注意: 使用 MemBuddy 类型而非 MemManager,避免虚函数分派不工作时调用父类 alloc 返回 None -_mbuddy: rawptr[memhub.MemBuddy] +_mbuddy: memhub.MemBuddy* diff --git a/App/lib/core/CompilerFactory.vp b/App/lib/core/CompilerFactory.vp index 0194cab..9b8585c 100644 --- a/App/lib/core/CompilerFactory.vp +++ b/App/lib/core/CompilerFactory.vp @@ -8,25 +8,25 @@ import memhub @t.NoVTable class CompilerFactory: """编译器结构体工厂(持有主池/永久池等共享对象)""" - Pool: rawptr[memhub.MemBuddy] # 主内存池(瞬时数据,mark/reset 回收) - PermPool: rawptr[memhub.MemBuddy] # 永久内存池(持久数据,从不 reset) + Pool: memhub.MemBuddy* # 主内存池(瞬时数据,mark/reset 回收) + PermPool: memhub.MemBuddy* # 永久内存池(持久数据,从不 reset) # ---- REnum 变体注册表(编译期单例持有,与 perm_pool 的 struct entry 同寿命)---- - RenumClassNames: sizet | t.CPtr - RenumClassVariantCounts: sizet | t.CPtr - RenumVariantNames: sizet | t.CPtr - RenumVariantTags: sizet | t.CPtr + RenumClassNames: sizet* + RenumClassVariantCounts: sizet* + RenumVariantNames: sizet* + RenumVariantTags: sizet* RenumClassCount: int # ---- REnum 变体字段别名表(同上,必须同寿命;_bind_variant_fields 查字段真实类型)---- - RenumAliasClass: sizet | t.CPtr - RenumAliasField: sizet | t.CPtr - RenumAliasIndex: sizet | t.CPtr - RenumAliasTy: sizet | t.CPtr - RenumAliasVariant: sizet | t.CPtr + RenumAliasClass: sizet* + RenumAliasField: sizet* + RenumAliasIndex: sizet* + RenumAliasTy: sizet* + RenumAliasVariant: sizet* RenumAliasCount: int - def __init__(self, pool: rawptr[memhub.MemBuddy], perm_pool: rawptr[memhub.MemBuddy]): + def __init__(self, pool: memhub.MemBuddy*, perm_pool: memhub.MemBuddy*): if self is None: return self.Pool = pool self.PermPool = perm_pool diff --git a/App/lib/core/Gen/AssignGenMixin.vp b/App/lib/core/Gen/AssignGenMixin.vp index f282ec6..a6b8b81 100644 --- a/App/lib/core/Gen/AssignGenMixin.vp +++ b/App/lib/core/Gen/AssignGenMixin.vp @@ -17,15 +17,10 @@ import lib.Stub.StubGen.VpiReader as VpiReader import lib.core.Gen.GenApi as GenApi # ============================================================ -# AssignGenMixin - 赋值翻译 Mixin(P6 方法化) -# -# @t.NoVTable:静态绑定(方法沿 MRO 直接调用 + this 调整)。 +# AssignGenMixin - 赋值翻译 Mixin # ============================================================ - - -@t.NoVTable -class AssignGenMixin: - Gen: rawptr[Generator.Generator] +novirtual class AssignGenMixin: + Gen: Generator.Generator* """赋值翻译 Mixin(P6 方法化)""" RecoverFound: int @@ -37,17 +32,17 @@ class AssignGenMixin: # 1. Attribute(Name('t'), 'CDefine') # 2. BinOp(... | Attribute(Name('t'), 'CDefine'))(联合注解) # ============================================================ - def is_cdefine_annotation(self, annot: rawptr[ast.AST]) -> int: + def is_cdefine_annotation(self, annot: ast.AST*) -> int: """检测注解是否为 t.CDefine,返回 1 表示是,0 表示否""" if annot is None: return 0 k: int = annot.kind() if k == ast.ASTKind.Attribute: - at: rawptr[ast.Attribute] = rawptr[ast.Attribute](annot) + at: ast.Attribute* = ast.Attribute*(annot) if at.attr is not None and string.strcmp(at.attr, "CDefine") == 0: return 1 return 0 if k == ast.ASTKind.BinOp: - bop: rawptr[ast.BinOp] = rawptr[ast.BinOp](annot) + bop: ast.BinOp* = ast.BinOp*(annot) if self.is_cdefine_annotation(bop.left) != 0: return 1 if self.is_cdefine_annotation(bop.right) != 0: @@ -64,7 +59,7 @@ class AssignGenMixin: # 4. Call — 如 t.CUnsignedLong(-11) → 取第一个参数 # 5. UnaryOp(USub/UAdd/Invert) — 如 -11 # ============================================================ - def extract_cdefine_int_value(self, val_node: rawptr[ast.AST]) -> int64: + def extract_cdefine_int_value(self, val_node: ast.AST*) -> int64: """从值节点提取整数常量(支持 Constant/BinOp/Name/Call/UnaryOp) 64 位返回:大整数 CDefine(如 sys.maxsize=9223372036854775807) @@ -76,7 +71,7 @@ class AssignGenMixin: # Case 1: Constant(INT) — 如 0x0002 if k == ast.ASTKind.Constant: - cn: rawptr[ast.Constant] = rawptr[ast.Constant](val_node) + cn: ast.Constant* = ast.Constant*(val_node) # True/False 布尔常量 → 1/0(对齐 TPC:bool 在 CDefine 语境按整数处理, # 如 SHADOW_ENABLED: t.CDefine = False) if cn.const_kind == ast.CONST_BOOL: @@ -88,7 +83,7 @@ class AssignGenMixin: # Case 2: BinOp — 如 FOREGROUND_RED | FOREGROUND_GREEN、(1 << ZDEFLATE_WINDOW_BITS) if k == ast.ASTKind.BinOp: - bop: rawptr[ast.BinOp] = rawptr[ast.BinOp](val_node) + bop: ast.BinOp* = ast.BinOp*(val_node) left_val: int64 = self.extract_cdefine_int_value(bop.left) right_val: int64 = self.extract_cdefine_int_value(bop.right) if bop.op == ast.OpKind.BitOr: return left_val | right_val @@ -107,7 +102,7 @@ class AssignGenMixin: # Case 3: Name — 引用已注册的 CDefine 常量,或 True/False 布尔字面量 if k == ast.ASTKind.Name: - nm: rawptr[ast.Name] = rawptr[ast.Name](val_node) + nm: ast.Name* = ast.Name*(val_node) if nm.id is not None: # True/False 布尔字面量 → 1/0(bool 在 CDefine 语境按整数处理) if string.strcmp(nm.id, "True") == 0: @@ -122,12 +117,12 @@ class AssignGenMixin: # Case 4: Call — 如 t.CUnsignedLong(-11) if k == ast.ASTKind.Call: - cl: rawptr[ast.Call] = rawptr[ast.Call](val_node) + cl: ast.Call* = ast.Call*(val_node) # 必须先把属性赋给显式类型为 list[...] | t.CPtr 的局部变量再调用 __len__(), # 否则编译器无法识别属性返回的 list 类型,GEP base 会变成 i32 0 导致 llc 报错 cl_args_list: list[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) + first_arg: ast.AST* = cl_args_list.get(0) arg_val: int64 = self.extract_cdefine_int_value(first_arg) return arg_val # Call 无参数:直接报错终止(fail-fast) @@ -135,7 +130,7 @@ class AssignGenMixin: # Case 5: UnaryOp — 如 -11 if k == ast.ASTKind.UnaryOp: - uop: rawptr[ast.UnaryOp] = rawptr[ast.UnaryOp](val_node) + uop: ast.UnaryOp* = ast.UnaryOp*(val_node) operand_val: int64 = self.extract_cdefine_int_value(uop.operand) if uop.op == ast.OpKind.USub: return -operand_val if uop.op == ast.OpKind.UAdd: return operand_val @@ -149,15 +144,426 @@ class AssignGenMixin: # 保证函数末尾块被正确 terminated,不做 noreturn 函数名白名单) return 0 + # ============================================================ + # define / t.CDefine 整数常量的"可存储 + 宽度"校验(与 TPC 同口径) + # + # 唯一规则源 = TransPyC/lib/core/SymbolUtils.py 的 DefineMinWidth / + # RequireDefineIntStorable / RequireDefineUseWidth(对照表见 + # Debugger/define-constants.md);本处是 TPV 侧的等价实现: + # · 自动推导(无显式类型)⇒ 64 位位模式 [-2^63, 2^64-1] + # · 显式类型 T(`T | t.CDefine`,T 在前)⇒ T 的位宽区间 [-(2^(w-1)), 2^w-1] + # · W_min = 8/16/32/64 中最小可容纳者(报文用) + # 关键差异:TPV 的整数常量是 int64,**超出 int64 的字面量在词法层就已回绕** + # (lexer.vp `string.atoll`)⇒ 溢出判定必须回到**源码文本**判定 + # (_cdefine_int_literal_text + _int_text_exceeds_64),绝不用回绕后的值。 + # ============================================================ + def define_min_width(self, value: int64) -> int: + """值 → W_min(8/16/32/64 中最小可容纳者),与 TPC DefineMinWidth 同口径。 + + 负数按有符号解释(留出符号位),非负数按无符号位模式解释(两解释口径)。 + 不做 `1 << 63` 这类会溢出 int64 的移位。 + + **本函数只使用"自编译安全"的字面量**:TPC 编译本文件时, + `HandlesExpr._HandleConstantLlvm`(HandlesExpr.py:263-265)把**无类型上下文**的 + 整数字面量按 `< 0 或 > 0xFFFFFFFF ⇒ i64,否则 i32` 物化 ⇒ 落在 + `[0x80000000, 0xFFFFFFFF]` 的字面量会被压成 i32,随后与 int64 的 `value` + 比较时按有符号 `sext` 提升(HandlesExprOps.py:401-413)⇒ 位模式 `0xFFFFFFFF` + 变成 **-1**。原实现写 `if value <= 4294967295` 正是该形态:阈值退化为 + `value <= -1`,一切正数落入 64 位档(`65536` 被误判为"需要至少 64 位", + `includes/subprocess.vp:141` 现场)。 + 故 32 位上界改用**回绕判定**(与 `_const_int_for_cdefine` 同一惯用法), + -2^31 改用**算术表达式**(`-2147483647 - 1`),两者都不含危险字面量。 + """ + if value < 0: + if value >= -128: + return 8 + if value >= -32768: + return 16 + # -2^31:字面量 2147483648 同样落 i32,改用安全字面量的算术等价式 + if value >= -2147483647 - 1: + return 32 + return 64 + if value <= 255: + return 8 + if value <= 65535: + return 16 + if value <= 2147483647: + return 32 + # 2^31 .. 2^32-1:uint32 回绕后仍等于原值 ⇒ 可容于无符号 32 位位模式 + if uint64(uint32(value)) == value: + return 32 + return 64 + + def _is_cdefine_marker_node(self, node: ast.AST*) -> int: + """节点是否为 t.CDefine 标记(Attribute.attr / Name.id == "CDefine")""" + if node is None: + return 0 + k: int = node.kind() + if k == ast.ASTKind.Attribute: + at: ast.Attribute* = ast.Attribute*(node) + if at.attr is not None and string.strcmp(at.attr, "CDefine") == 0: + return 1 + return 0 + if k == ast.ASTKind.Name: + nm: ast.Name* = ast.Name*(node) + if nm.id is not None and string.strcmp(nm.id, "CDefine") == 0: + return 1 + return 0 + + def _define_explicit_annot(self, annot: ast.AST*) -> ast.AST*: + """`T | t.CDefine` 的显式类型 T 节点;无显式类型 → None。 + + 只看联合**首个**操作数(与 TPC 的"首个非 void 基类型胜出"同口径): + `T | t.CDefine`(define 常量与 TPC 展开产物)⇒ T; + `t.CDefine | T`(既有手写惯用法,如 CODE_SEG: t.CDefine | t.CUInt16T)⇒ + 首个是 CDefine 标记 ⇒ 无显式类型 ⇒ **既有声明行为逐字不变**。 + """ + if annot is None: + return None + if annot.kind() != ast.ASTKind.BinOp: + return None + bop: ast.BinOp* = ast.BinOp*(annot) + if bop.left is None: + return None + if self._is_cdefine_marker_node(bop.left) != 0: + return None + return bop.left + + def _annot_int_bits(self, pool: memhub.MemBuddy*, + annot: ast.AST*) -> int: + """任意整数类型注解节点 → 位宽(bit);无注解 / 非整数 / 无法判定 → 0。 + + 名称解析与 TPC EnumMemberAnnotationIntWidth 同源:t 模块类型名走 + TypeGenResolve.map_t_type(CLong/CSizeT 等平台相关宽度由它权威给出); + `int` / `bool` 两个"注解直通名"补在此表(TPC: int → t.CInt 32 位、 + bool → 8 位,与 include/builtins 口径一致)。 + """ + if annot is None: + return 0 + k: int = annot.kind() + nm: str = None + if k == ast.ASTKind.Attribute: + at: ast.Attribute* = ast.Attribute*(annot) + nm = at.attr + elif k == ast.ASTKind.Name: + n2: ast.Name* = ast.Name*(annot) + nm = n2.id + if nm is None: + return 0 + if string.strcmp(nm, "int") == 0: + return 32 + if string.strcmp(nm, "bool") == 0: + return 8 + # stdint.vp / builtins 的定长小写别名(非 t 模块名,map_t_type 不认): + # 与 TPC EnumMemberAnnotationIntWidth 走 builtins typedef 表的同口径。 + if string.strcmp(nm, "int8") == 0 or string.strcmp(nm, "uint8") == 0: + return 8 + if string.strcmp(nm, "int16") == 0 or string.strcmp(nm, "uint16") == 0: + return 16 + if string.strcmp(nm, "int32") == 0 or string.strcmp(nm, "uint32") == 0: + return 32 + if string.strcmp(nm, "int64") == 0 or string.strcmp(nm, "uint64") == 0: + return 64 + if string.strcmp(nm, "sizet") == 0 or string.strcmp(nm, "size_t") == 0: + return 64 + ty: llvmlite.LLVMType* = self.Gen.TypeGenResolve.map_t_type(pool, nm) + if ty is None: + return 0 + match ty: + case llvmlite.LLVMType.Int(bits): + if bits == 1: + return 8 + if bits == 8 or bits == 16 or bits == 32 or bits == 64: + return bits + return 0 + case _: + return 0 + + def _define_annot_bits(self, pool: memhub.MemBuddy*, + annot: ast.AST*) -> int: + """CDefine 声明注解 → 显式类型 T 的整数位宽(bit)。 + + 无显式类型(`t.CDefine` 单标记 / T 不在联合首位)⇒ 0(走 64 位口径)。 + """ + return self._annot_int_bits(pool, self._define_explicit_annot(annot)) + + def _cdefine_int_literal_text(self, name: str) -> str: + """按变量名从当前模块源文件取 CDefine 行的**值文本**(原始字面量)。 + + 与 _recover_float_literal 同一套"回源文件读取"策略:AST 常量的 int_val + 是 int64,超出 int64 的字面量已在词法层回绕(lexer.vp `string.atoll`) + ⇒ 只有源文本可靠。读取失败 / 未命中 → None。 + """ + if name is None: + return None + fp: str = self.Gen.TypeGenResolve.get_current_file() + if fp is None: + return None + f: rawptr[fileio.File] = fileio.File(fp, fileio.MODE.R) + if f.closed: + return None + BUF_SZ: sizet = 1048576 + buf: bytes = stdlib.malloc(BUF_SZ) + if buf is None: + f.close() + return None + nrd: LONG = f.read_all(buf, BUF_SZ) + f.close() + if nrd <= 0: + stdlib.free(buf) + return None + if nrd < BUF_SZ: + buf[nrd] = 0 + name_len: sizet = string.strlen(name) + total_len: sizet = string.strlen(buf) + pos: sizet = 0 + result: str = None + while pos < total_len: + line_start: sizet = pos + while pos < total_len and buf[pos] != '\n': + pos += 1 + line_len: sizet = pos - line_start + if pos < total_len: + pos += 1 + if line_len < name_len + 1: + continue + ok: int = 1 + ki: sizet + for ki in range(name_len): + if buf[line_start + ki] != name[ki]: + ok = 0 + break + if ok == 0: + continue + sep: sizet = line_start + name_len + while sep < line_start + line_len and buf[sep] == ' ': + sep += 1 + if sep >= line_start + line_len: + continue + if buf[sep] != ':' and buf[sep] != '=': + continue + eq: sizet = line_start + while eq < line_start + line_len and buf[eq] != '=': + eq += 1 + if eq >= line_start + line_len: + continue + eq += 1 + while eq < line_start + line_len and buf[eq] == ' ': + eq += 1 + vstart: sizet = eq + while eq < line_start + line_len and buf[eq] != ' ' and buf[eq] != '\t' \ + and buf[eq] != '#' and buf[eq] != '\r': + eq += 1 + if eq == vstart: + continue + txt: str = stdlib.malloc(eq - vstart + 1) + if txt is None: + continue + vi: sizet + for vi in range(eq - vstart): + txt[vi] = buf[vstart + vi] + txt[eq - vstart] = 0 + result = txt + break + stdlib.free(buf) + return result + + def _int_text_exceeds_64(self, text: str) -> int: + """字面量文本是否超出 64 位位模式 [-2^63, 2^64-1](1=超出,0=未超出/不判定)。 + + **纯文本判定**(不落进任何定宽容器): + 十进制:去 '_' 与前导零后,与 '18446744073709551615'(2^64-1)按长度 + + 字典序比较;负数侧与 '9223372036854775808'(2^63)比较。 + 十六进制(0x/0X):去 '_' 与前导零后 > 16 位 ⇒ 超出。 + 其余(表达式 / 浮点 / 字符串)⇒ 0(不进入本判据,由注册处的 AST 求值判据负责)。 + """ + if text is None: + return 0 + tl: sizet = string.strlen(text) + if tl == 0: + return 0 + neg: int = 0 + i: sizet = 0 + if text[0] == '-': + neg = 1 + i = 1 + elif text[0] == '+': + i = 1 + if i >= tl: + return 0 + if i + 1 < tl and text[i] == '0' and (text[i + 1] == 'x' or text[i + 1] == 'X'): + # 十六进制:去 '_' 与前导零后的有效位数(>16 位 ⇒ 超出 64 位) + sig: sizet = 0 + j2: sizet = i + 2 + leading: int = 1 + while j2 < tl: + c2: char = text[j2] + j2 += 1 + if c2 == '_': + continue + if not ((c2 >= '0' and c2 <= '9') or (c2 >= 'a' and c2 <= 'f') + or (c2 >= 'A' and c2 <= 'F')): + return 0 + if leading != 0 and c2 == '0': + continue + leading = 0 + sig += 1 + if sig > 16: + return 1 + return 0 + # 十进制:定位首个非零有效位 + s: sizet = i + while s < tl and (text[s] == '0' or text[s] == '_'): + s += 1 + digits2: int = 0 + j3: sizet = s + while j3 < tl: + c3: char = text[j3] + j3 += 1 + if c3 == '_': + continue + if c3 < '0' or c3 > '9': + return 0 + digits2 += 1 + if digits2 == 0: + return 0 + max_text: str = "18446744073709551615" + mlen: sizet = 20 + if neg != 0: + max_text = "9223372036854775808" + mlen = 19 + if digits2 > mlen: + return 1 + if digits2 < mlen: + return 0 + # 等长(len(max_text) 位):逐位字典序比较(同位数时字典序 = 数值序) + d: sizet = 0 + k2: sizet = s + while k2 < tl and d < mlen: + c4: char = text[k2] + k2 += 1 + if c4 == '_': + continue + mc: char = max_text[d] + if c4 > mc: + return 1 + if c4 < mc: + return 0 + d += 1 + return 0 + + def require_cdefine_storable(self, pool: memhub.MemBuddy*, + node: ast.AST*, name: str, + value: int64, annot: ast.AST*) -> None: + """CDefine / define 常量注册前的可存储性校验(fail-fast,与 TPC 同口径)。 + + 判据(顺序固定): + ① 源码文本超出 64 位位模式 ⇒ 报错(词法层已回绕,value 不可信); + ② 显式类型 T(`T | t.CDefine`,T 在前)⇒ value 必须落进 T 的位宽区间。 + 报文含:常量名 / 声明类型或"自动推导" / W_min / 实际值 / 可存储范围与 + 可用类型清单 / 修法(点明"需要扩容")。位置由 fatal_error 自带 + (File + line + 源码行)。 + """ + text: str = self._cdefine_int_literal_text(name) + bits: int = self._define_annot_bits(pool, annot) + wmin: int = self.define_min_width(value) + if self._int_text_exceeds_64(text) != 0: + self.Gen.TypeGenErr.fatal_error( + node, + f"[TPV] define 常量数值不可存储: 常量 '{name}' 的初始值 {text} 超出 64 位" + f"(本语言最宽的整数类型为 64 位,按有符号/无符号两种解释的可存储范围为 " + f"-9223372036854775808..18446744073709551615,不存在更宽的整数类型 ⇒ 需要扩容)。" + f"禁止静默截断/降级,已终止编译。可用整数类型: t.CInt8T/t.CUInt8T、" + f"t.CInt16T/t.CUInt16T、t.CInt32T/t.CUInt32T、t.CInt64T/t.CUInt64T" + f"(或 int8/uint8/…/uint64、char、sizet)。" + f"修法: 把值改到 64 位范围内,或为该数字引入更大的整数类型(扩容)。", + "TypeError") + return + if bits == 0: + return + # 32 位档的上下界用**安全字面量**构造(同一字面量纪律,见 define_min_width): + # 2147483648 / 4294967295 落在 [0x80000000, 0xFFFFFFFF],被 TPC 编译时会被压成 + # i32 并在提升/赋值时按有符号解释,存在与现场同族的隐患;改用 2^31-1 的 + # 算术等价式后与 TPC DefineWidthLoHi(32) = (-2147483648, 4294967295) 逐字相同。 + m31: int64 = 2147483647 + lo: int64 = -m31 - 1 + hi: int64 = m31 * 2 + 1 + if bits == 8: + lo = -128 + hi = 255 + elif bits == 16: + lo = -32768 + hi = 65535 + elif bits == 64: + return + if value < lo or value > hi: + self.Gen.TypeGenErr.fatal_error( + node, + f"[TPV] define 常量数值不可存储: 常量 '{name}' 的初始值 {value} 不可存储。" + f"最小可容纳宽度 W_min: {wmin} 位;声明类型位宽 {bits} 位," + f"该声明可存储范围: {lo}..{hi}。" + f"禁止静默截断/降级,已终止编译。" + f"修法: 把显式类型改为更宽的类型(如 t.CInt32T / t.CInt64T / uint64)," + f"或修正该字面量。", + "TypeError") + + def require_cdefine_use_width(self, pool: memhub.MemBuddy*, + trans: HT.Translator*, + target_annot: ast.AST*, + value_node: ast.AST*) -> None: + """**使用处宽度**校验(`a: T = C` 场景,fail-fast;与 TPC 同口径)。 + + 仅当满足全部条件时生效(其余情况零副作用、原样返回): + · RHS 是裸名(`C`); + · 该名在当前作用域**不是变量**(与 translate_name_value 的同名变量 + 优先守卫一致,避免把普通变量误判为常量 ⇒ 不误伤); + · 该名是已注册的 CDefine 常量(本模块表命中); + · 目标注解解析出整数位宽 w(非整数注解 → 不判定)。 + 判定:`w >= W_min` ⇒ 通过(消费端按 T 物化/升宽,即"上下文更宽 ⇒ + 用使用处宽度");`w < W_min` ⇒ 报错终止(替换静默截断)。 + """ + if value_node is None or target_annot is None: + return + if value_node.kind() != ast.ASTKind.Name: + return + rn: ast.Name* = ast.Name*(value_node) + if rn.id is None: + return + if trans is not None: + if self.Gen.VarGen.lookup_var(trans.SymTab, rn.id) is not None: + return + cdef_val: int64 = self.Gen.TypeGenCDef.lookup_cdefine_constant(rn.id) + if self.Gen.TypeGenCDef.is_cdefine_found() == 0: + return + bits: int = self._annot_int_bits(pool, target_annot) + if bits == 0: + return + wmin: int = self.define_min_width(cdef_val) + if bits >= wmin: + return + self.Gen.TypeGenErr.fatal_error( + value_node, + f"[TPV] define 常量使用处宽度不足: 常量 '{rn.id}' 的实际值 {cdef_val} " + f"需要至少 {wmin} 位(最小可容纳宽度 W_min)," + f"但使用处(变量声明注解)只提供 {bits} 位。" + f"禁止静默截断/降级,已终止编译。" + f"修法: 把变量声明注解加宽到至少 {wmin} 位(如 t.CInt{wmin}T / CUInt{wmin}T)," + f"或改用更小的常量值。", + "TypeError") + # ============================================================ # _register_cdefine_from_value - 注册 CDefine 常量(浮点/整数自动识别) # # 浮点字面量(如 vipermath 的 U_M_PI: t.CDefine = 3.14159...)走 # register_cdefine_double,否则 translate_value 查表得 0 生成 # ret i32 0(llc 报错 "value doesn't match function result type")。 + # + # annot:该 AnnAssign 的注解(`T | t.CDefine` / `t.CDefine`),用于注册前的 + # 可存储性校验(require_cdefine_storable);不传则退化为"无显式类型"口径。 # ============================================================ - def _register_cdefine_from_value(self, pool: rawptr[memhub.MemBuddy], - name: str, val_node: rawptr[ast.AST]) -> None: + def _register_cdefine_from_value(self, pool: memhub.MemBuddy*, + name: str, val_node: ast.AST*, + annot: ast.AST* = None) -> None: """注册 CDefine 常量(浮点字面量 → register_cdefine_double,否则整数)""" if pool is None or name is None: return @@ -165,15 +571,15 @@ class AssignGenMixin: # t.CFloat64T(2.5) / t.CDouble(1.0)。取第一个参数作为真实值节点, # 再按 Constant 分支处理(浮点 → register_cdefine_double)。 if val_node is not None and val_node.kind() == ast.ASTKind.Call: - cl_cd: rawptr[ast.Call] = rawptr[ast.Call](val_node) + cl_cd: ast.Call* = ast.Call*(val_node) if cl_cd is not None and cl_cd.args is not None: cl_args_cd: list[ast.AST*]* = cl_cd.args if len(cl_args_cd) > 0: - first_arg_cd: rawptr[ast.AST] = cl_args_cd.get(0) + first_arg_cd: ast.AST* = cl_args_cd.get(0) if first_arg_cd is not None and first_arg_cd.kind() == ast.ASTKind.Constant: val_node = first_arg_cd if val_node is not None and val_node.kind() == ast.ASTKind.Constant: - cn_fp: rawptr[ast.Constant] = rawptr[ast.Constant](val_node) + cn_fp: ast.Constant* = ast.Constant*(val_node) if cn_fp.const_kind == ast.CONST_STR: # 字符串 CDefine(如 ZLIB_VERSION: t.CDefine = "1.3.2"): # 注册为字符串常量,读取端返回 global string(对齐 TPC)。 @@ -197,6 +603,9 @@ class AssignGenMixin: self.Gen.TypeGenErr.fatal_error(None, f"CDefine 值提取失败:'{name}' 缺少初始值", "TypeError") return val_fp: int64 = self.extract_cdefine_int_value(val_node) + # 注册前可存储性校验(fail-fast;唯一判据与 TPC 同口径): + # 源码文本超 64 位 / 显式类型 T 的位宽放不下 ⇒ 报错终止,不注册。 + self.require_cdefine_storable(pool, val_node, name, val_fp, annot) self.Gen.TypeGenCDef.register_cdefine_constant(pool, name, val_fp) # 源文件重读恢复 CDefine 浮点值:读 "NAME: t.CDefine = value" 行 atof 解析 @@ -337,23 +746,23 @@ class AssignGenMixin: # # 支持 BinOp(BitOr) 递归,同时检查 Attribute.attr 和 Name.id。 # ============================================================ - def _annotation_contains_name(self, annot: rawptr[ast.AST], name: str) -> int: + def _annotation_contains_name(self, annot: ast.AST*, name: str) -> int: """递归检查注解中是否包含指定名称,返回 1=包含 / 0=不包含""" if annot is None or name is None: return 0 k: int = annot.kind() if k == ast.ASTKind.Attribute: - at: rawptr[ast.Attribute] = rawptr[ast.Attribute](annot) + at: ast.Attribute* = ast.Attribute*(annot) if at.attr is not None and string.strcmp(at.attr, name) == 0: return 1 return 0 if k == ast.ASTKind.Name: - nm: rawptr[ast.Name] = rawptr[ast.Name](annot) + nm: ast.Name* = ast.Name*(annot) if nm.id is not None and string.strcmp(nm.id, name) == 0: return 1 return 0 if k == ast.ASTKind.BinOp: - bop: rawptr[ast.BinOp] = rawptr[ast.BinOp](annot) + bop: ast.BinOp* = ast.BinOp*(annot) if self._annotation_contains_name(bop.left, name) != 0: return 1 if self._annotation_contains_name(bop.right, name) != 0: @@ -372,14 +781,14 @@ class AssignGenMixin: # # 注: 注解中的 "|" 是"和"的意思(组合类型),非右值中的位或运算 # ============================================================ - def _is_ptr_element_annotation(self, annot: rawptr[ast.AST]) -> int: + def _is_ptr_element_annotation(self, annot: ast.AST*) -> int: """检查注解是否为 bytes|t.CPtr 或 str|t.CPtr 形式""" if annot is None: return 0 k: int = annot.kind() if k != ast.ASTKind.BinOp: return 0 - bop: rawptr[ast.BinOp] = rawptr[ast.BinOp](annot) + bop: ast.BinOp* = ast.BinOp*(annot) if bop.op != ast.OpKind.BitOr: return 0 if self._annotation_contains_name(annot, "str") != 0: @@ -394,10 +803,10 @@ class AssignGenMixin: if self._is_generic_tp_or_nested(bop.left) != 0 or self._is_generic_tp_or_nested(bop.right) != 0: gp_nm: str = None if bop.left is not None and bop.left.kind() == ast.ASTKind.Name: - gp_left_nm: rawptr[ast.Name] = rawptr[ast.Name](bop.left) + gp_left_nm: ast.Name* = ast.Name*(bop.left) gp_nm = gp_left_nm.id elif bop.right is not None and bop.right.kind() == ast.ASTKind.Name: - gp_right_nm: rawptr[ast.Name] = rawptr[ast.Name](bop.right) + gp_right_nm: ast.Name* = ast.Name*(bop.right) gp_nm = gp_right_nm.id if gp_nm is not None: # 经全局 gen 委托解析泛型参数(T → 具体类型名)。不能 self.GenericTpNames @@ -418,9 +827,9 @@ class AssignGenMixin: return 1 return 0 - def _stg_ty_equal(self, pool: rawptr[memhub.MemBuddy], - ta: rawptr[llvmlite.LLVMType], - tb: rawptr[llvmlite.LLVMType]) -> int: + def _stg_ty_equal(self, pool: memhub.MemBuddy*, + ta: llvmlite.LLVMType*, + tb: llvmlite.LLVMType*) -> int: """类型内容相等比较(storage 绑定判定用)。 llvmlite 类型非 canonical:Ptr/Struct 每次构造都 pool.alloc 新实例 @@ -447,7 +856,7 @@ class AssignGenMixin: return 0 return 1 if string.strcmp(buf_a, buf_b) == 0 else 0 - def _is_addrlike_call(self, node: rawptr[ast.AST]) -> int: + def _is_addrlike_call(self, node: ast.AST*) -> int: """检查 rhs 是否为 c.Addr/c.Deref 等显式指针操作调用。 此类调用返回指针(如 c.Addr(obj) 返回对象 storage 地址,类型 Ptr(Struct)), @@ -457,13 +866,13 @@ class AssignGenMixin: """ if node is None or node.kind() != ast.ASTKind.Call: return 0 - cl: rawptr[ast.Call] = rawptr[ast.Call](node) + cl: ast.Call* = ast.Call*(node) if cl.func is None or cl.func.kind() != ast.ASTKind.Attribute: return 0 - at: rawptr[ast.Attribute] = rawptr[ast.Attribute](cl.func) + at: ast.Attribute* = ast.Attribute*(cl.func) if at.value is None or at.value.kind() != ast.ASTKind.Name: return 0 - vn: rawptr[ast.Name] = rawptr[ast.Name](at.value) + vn: ast.Name* = ast.Name*(at.value) if vn.id is None or string.strcmp(vn.id, "c") != 0: return 0 if at.attr is None: @@ -474,17 +883,17 @@ class AssignGenMixin: if string.strcmp(at.attr, "Ptr") == 0: return 1 return 0 - def _is_64bit_scalar_ty(self, node: rawptr[ast.AST]) -> int: + def _is_64bit_scalar_ty(self, node: ast.AST*) -> int: """判断类型节点是否为 64 位标量数值类型(CUInt64T/CInt64T/CSizeT),元素 8 字节""" if node is None: return 0 ty_nm: str = None nk: int = node.kind() if nk == ast.ASTKind.Name: - nm64: rawptr[ast.Name] = rawptr[ast.Name](node) + nm64: ast.Name* = ast.Name*(node) ty_nm = nm64.id elif nk == ast.ASTKind.Attribute: - at64: rawptr[ast.Attribute] = rawptr[ast.Attribute](node) + at64: ast.Attribute* = ast.Attribute*(node) ty_nm = at64.attr if ty_nm is None: return 0 @@ -534,9 +943,18 @@ class AssignGenMixin: # === 白名单:已知纯标量(基础名 + stdint 大写别名) === if string.strcmp(ty_name, "int") == 0: return 1 if string.strcmp(ty_name, "char") == 0: return 1 + # Python 内建标量直通名(与上面的 int/char 同族):t.py CTypeRegistry.ResolveName + # 的 _CNAME_ALIAS 把 'float'→t.CFloat(32)、'double'→t.CDouble(64)、 + # 'bool'→t.CBool(8);泛型实参位可能原样出现这些裸名。 + if string.strcmp(ty_name, "float") == 0: return 1 + if string.strcmp(ty_name, "double") == 0: return 1 + if string.strcmp(ty_name, "bool") == 0: return 1 if string.strcmp(ty_name, "CInt") == 0: return 1 + if string.strcmp(ty_name, "CUnsignedInt") == 0: return 1 + if string.strcmp(ty_name, "CUnsigned") == 0: return 1 if string.strcmp(ty_name, "CChar") == 0: return 1 if string.strcmp(ty_name, "CUnsignedChar") == 0: return 1 + if string.strcmp(ty_name, "CSignedChar") == 0: return 1 if string.strcmp(ty_name, "CShort") == 0: return 1 if string.strcmp(ty_name, "CUnsignedShort") == 0: return 1 if string.strcmp(ty_name, "CLong") == 0: return 1 @@ -544,6 +962,13 @@ class AssignGenMixin: if string.strcmp(ty_name, "CLongLong") == 0: return 1 if string.strcmp(ty_name, "CUnsignedLongLong") == 0: return 1 if string.strcmp(ty_name, "CSizeT") == 0: return 1 + if string.strcmp(ty_name, "CBool") == 0: return 1 + # 字符宽度族(stdint.vp 的 wchar_t/char8_t/char16_t/char32_t 底层类): + # 自身宽度 8/16/32 均 ≠ 8 字节指针槽,必须走标量步长。 + if string.strcmp(ty_name, "CWCharT") == 0: return 1 + if string.strcmp(ty_name, "CChar8T") == 0: return 1 + if string.strcmp(ty_name, "CChar16T") == 0: return 1 + if string.strcmp(ty_name, "CChar32T") == 0: return 1 if string.strcmp(ty_name, "BOOL") == 0: return 1 if string.strcmp(ty_name, "BYTE") == 0: return 1 if string.strcmp(ty_name, "UCHAR") == 0: return 1 @@ -559,6 +984,17 @@ class AssignGenMixin: if string.strcmp(ty_name, "WORD") == 0: return 1 if string.strcmp(ty_name, "DWORD") == 0: return 1 if string.strcmp(ty_name, "QWORD") == 0: return 1 + # 小写裸名家族(includes/builtins.vp 的 C 基础类型裸名别名,同一张表; + # 裸名经 resolve_generic_type_name 解析后可能原样出现在泛型实参位): + # uchar/short/ushort/uint/long/ulong/longlong/ulonglong + if string.strcmp(ty_name, "uchar") == 0: return 1 + if string.strcmp(ty_name, "short") == 0: return 1 + if string.strcmp(ty_name, "ushort") == 0: return 1 + if string.strcmp(ty_name, "uint") == 0: return 1 + if string.strcmp(ty_name, "long") == 0: return 1 + if string.strcmp(ty_name, "ulong") == 0: return 1 + if string.strcmp(ty_name, "longlong") == 0: return 1 + if string.strcmp(ty_name, "ulonglong") == 0: return 1 # 定长整数/浮点(C*T 形式与裸别名,strstr 前缀匹配) if string.strstr(ty_name, "Int8") is not None: return 1 if string.strstr(ty_name, "Int16") is not None: return 1 @@ -575,7 +1011,7 @@ class AssignGenMixin: # 未知类名(结构体/类/污染类型)→ 非标量,按 8 字节指针槽 return 0 - def _is_generic_tp_or_nested(self, node: rawptr[ast.AST]) -> int: + def _is_generic_tp_or_nested(self, node: ast.AST*) -> int: """判断注解节点是否为泛型类型参数名(单字母大写,如 T)或嵌套联合(BinOp)""" if node is None: return 0 @@ -583,7 +1019,7 @@ class AssignGenMixin: if nk == ast.ASTKind.BinOp: return 1 if nk == ast.ASTKind.Name: - nm_tp: rawptr[ast.Name] = rawptr[ast.Name](node) + nm_tp: ast.Name* = ast.Name*(node) if nm_tp.id is None: return 0 tp_len: sizet = string.strlen(nm_tp.id) @@ -609,25 +1045,30 @@ class AssignGenMixin: # Returns: # 0 成功,1 失败 # ============================================================ - def _init_global_array_from_list(self, builder: rawptr[llvmlite.IRBuilder], - pool: rawptr[memhub.MemBuddy], - mod: rawptr[llvmlite.LLVMModule], - array_alloca: rawptr[llvmlite.Value], - list_node: rawptr[ast.AST], - trans: rawptr[HT.Translator]) -> int: - """从列表字面量初始化全局数组,为每个元素生成 GEP + store""" + def _init_global_array_from_list(self, builder: llvmlite.IRBuilder*, + pool: memhub.MemBuddy*, + mod: llvmlite.LLVMModule*, + array_alloca: llvmlite.Value*, + list_node: ast.AST*, + trans: HT.Translator*, + owner_ctx: str = None) -> int: + """从列表字面量初始化全局数组,为每个元素生成 GEP + store + + owner_ctx: 站点描述(如 "类 X 字段 y"),仅用于空元素 fail-fast 报文, + 便于从报错直接定位到"哪个类/哪个字段的第几个元素"。 + """ if builder is None or array_alloca is None or list_node is None: return 1 # 获取数组类型(Pointee of [N x elem_ty]*) - arr_ty: rawptr[llvmlite.LLVMType] = None + arr_ty: llvmlite.LLVMType* = None if array_alloca.Ty is not None: arr_ty = array_alloca.Ty.Pointee if arr_ty is None: return 1 # 匹配数组类型获取元素类型与声明长度 - elem_ty: rawptr[llvmlite.LLVMType] = None + elem_ty: llvmlite.LLVMType* = None arr_count: int = 0 match arr_ty: case llvmlite.LLVMType.Array(et, cnt): @@ -637,7 +1078,7 @@ class AssignGenMixin: return 1 # 获取列表元素 - lst: rawptr[ast.List] = rawptr[ast.List](list_node) + lst: ast.List* = ast.List*(list_node) if lst is None or lst.elts is None: return 1 elts: list[ast.AST*]* = lst.elts @@ -646,9 +1087,9 @@ class AssignGenMixin: # 特例:单个字符串字面量初始化字符数组([N x i8],N = strlen+1) # 逐字节写入字符串内容;调用方已先 store zeroinitializer,末字节 NUL 由零保持。 if self.Gen.ExprGenBase.get_llvm_type_bits(elem_ty) == 8 and elts_count == 1 and arr_count >= 1: - e0_s: rawptr[ast.AST] = elts.get(0) + e0_s: ast.AST* = elts.get(0) if e0_s is not None and e0_s.kind() == ast.ASTKind.Constant: - c0_s: rawptr[ast.Constant] = rawptr[ast.Constant](e0_s) + c0_s: ast.Constant* = ast.Constant*(e0_s) if c0_s.const_kind == ast.CONST_STR: sv_s: str = ast.constant_get_str_val(c0_s) if sv_s is not None: @@ -660,13 +1101,13 @@ class AssignGenMixin: "OverflowError") bi_s: sizet = 0 while bi_s < n_s: - bidx_s: rawptr[llvmlite.Value] = llvmlite.const_int32(pool, bi_s) - bp_s: rawptr[llvmlite.Value] = llvmlite.build_gep_array( + bidx_s: llvmlite.Value* = llvmlite.const_int32(pool, bi_s) + bp_s: llvmlite.Value* = llvmlite.build_gep_array( builder, arr_ty, elem_ty, array_alloca, bidx_s) if bp_s is None: break - bvv: rawptr[llvmlite.Value] = llvmlite.const_int32(pool, sv_s[bi_s]) - bsv: rawptr[llvmlite.Value] = self.Gen.ExprGenBase.coerce_to_type( + bvv: llvmlite.Value* = llvmlite.const_int32(pool, sv_s[bi_s]) + bsv: llvmlite.Value* = self.Gen.ExprGenBase.coerce_to_type( builder, bvv, elem_ty, e0_s) llvmlite.build_store(builder, bsv, bp_s) bi_s += 1 @@ -681,9 +1122,87 @@ class AssignGenMixin: # 为每个元素生成 GEP + store for i in range(elts_count): - elem_node: rawptr[ast.AST] = elts.get(i) - idx_val: rawptr[llvmlite.Value] = llvmlite.const_int32(pool, i) - elem_ptr: rawptr[llvmlite.Value] = llvmlite.build_gep_array( + elem_node: ast.AST* = elts.get(i) + # === 显式判空(本仓硬约定:指针判空一律 `is None` / `is not None`)=== + # 【反例现场·实测】上一轮曾把本判据写成整型字面量比较 `elem_node == 0`, + # 并附注"与 `is None` 完全同义",该注**结论错、但 IR 事实对**,逐字证据: + # TPC `HandlesExprOps._HandleCompareLlvm:429-431` 对"指针 vs 整型字面量 0" + # 把 0 物化为 `ir.Constant(LeftVal.type, None)`(而非折成常量 false), + # 再经 `:457-458` 的指针分支生成 `icmp eq`(命名为 `cmpresult`)。 + # 编译产物 `TransPyV\output\818a0677d1e7fe22.ll:17761-17763` 逐字为: + # %"elem_node.1" = load %"cfc4ca8da95a30e1.AST"*, ... %elem_node + # %"cmpresult.9" = icmp eq %"cfc4ca8da95a30e1.AST"* %"elem_node.1", null + # br i1 %"cmpresult.9", label %"then.12", label %"endif.12" + # (`then.12` = 本守卫的响亮报错体,`endif.12` = 正常路径;合并模块同形, + # 见 `TransPyV\output\818a0677d1e7fe22_dso.ll:75903-75904`。) + # ⇒ "`x == 0` 判空无效 / 被折成常量 false" **不成立**(`is None` 走同形比较, + # 命名 `is_cmp`,见 `TransPyV\output\5626a4dc226462fa.ll:2940`)。 + # 仍统一改用 `is None`:语义直白、不依赖"指针 vs 整型"跨类型特例分支、与 + # ExprGenMixin._translate_value_impl:100 既有写法同族。命中即响亮报错, + # 直接指名"类名/字段名/元素下标 + 位置"。 + # 该槽为空 ⇒ elts 计数 > 实际填充数 ⇒ 上层某处产生了空 AST 元素 + # (这正是 `list.get` 越界/未填充槽返回裸 0 的后果)。 + # + # 【硬约定·判据写法取决于静态类型】(wiki/02-type-system.md 同步) + # · 指针类型(AST* / Value* / str ...):`is None` 或 `== 0` **均可**, + # 两侧编译器都生成同形 `icmp eq , null`(命名 `is_cmp` / `cmpresult`)。 + # · 整型承载的地址(如 `llvmlite.LLVMType.Pointee`,静态类型 i64): + # 必须用 `== 0` / `!= 0`。写成 `is None` / `is not None` 会被折成**常量** + # ——TPC `HandlesExprOps.py:388-395`「值类型(IntType) is None ⇒ 恒 0; + # is not None ⇒ 恒 1」;IR 实证:`TransPyV\output\818a0677d1e7fe22.ll:17983` + # `%"and.result.4" = phi i1 [0, %"endif.19"], [1, %"and.rhs0.4"]` + # (`and.rhs0.4` 块内只 `load i64` 后直接 `br`,**没有任何 icmp**) + # ⇒ `X.Ty.Pointee is not None` 这一合取项恒真、守卫失效。 + # 本函数 1185 行(`elem_ptr.Ty.Pointee`)已按此约定改为 `!= 0`。 + if elem_node is None: + ctx_dbg: str = "" + if owner_ctx is not None: + ctx_dbg = owner_ctx + src_line: int = 0 + src_col: int = 0 + if list_node is not None: + src_line = list_node.lineno + src_col = list_node.col_offset + self.Gen.TypeGenErr.fatal_error( + list_node, + f"全局数组初始化遇到空 AST 元素:{ctx_dbg}第 {i} 个元素为裸空指针(0)," + f"但列表元素计数为 {elts_count}(元素与计数不一致)。" + f"上层某处产生了空 AST 元素(列表字面量节点 {src_line}:{src_col} 的第 {i} 槽未被填充)," + f"拒绝静默跳过/补零,已终止编译。", + "ValueError") + return 1 + # === 对象有效性校验(vptr 非 0)=== + # 上一条只判"指针非 0";@t.CVTable 类的虚调用(kind()/dump()/...) 经对象首字 + # (vptr)间接调用,首字为 0 时紧跟的 `elem_node.kind()` 会生成 + # `load [0 + slot]` ⇒ 立刻 ASan READ at 0x0(本仓崩溃的真实形态: + # EXPRGenBase._translate_value_impl:102 的 node.kind())。 + # 产生源实证:StructGenMixin._deep_copy_default_ast 旧写法把深拷贝节点的 + # vptr 留成 0(IR 证据见该函数注释 / b5883dc9c114a604.ll:10382-10384)。 + # 读对象首字的**唯一可用**写法是 `c.Deref((uint64*)(p))`(正常发射 + # `bitcast p → i64*` + `load i64`:b5883dc9c114a604.ll:10611-10613); + # 写成 `rawptr(*(uint64*)(p))` 会被折成裸 0(同文件 :10382),不可用。 + elem_vptr: uint64 = c.Deref((uint64*)(elem_node)) + if elem_vptr == 0: + ctx_vt: str = "" + if owner_ctx is not None: + ctx_vt = owner_ctx + vt_line: int = 0 + vt_col: int = 0 + if list_node is not None: + vt_line = list_node.lineno + vt_col = list_node.col_offset + self.Gen.TypeGenErr.fatal_error( + list_node, + f"全局数组初始化遇到【对象无效】的 AST 元素(vptr 为 0):{ctx_vt}" + f"第 {i} 个元素指针非 0(地址 {uint64(elem_node)})但其对象首字(vtable 指针)为 0," + f"对它的任何虚调用(kind()/dump()/…) 都会在 `load [0+slot]` 处读地址 0。" + f"列表字面量节点位置 {vt_line}:{vt_col},元素计数 {elts_count}。" + f"上层某处产生了「未初始化 vptr 的 AST 节点」(典型源:深拷贝/整块拷贝只搬字段未搬 vptr)," + f"拒绝继续,已终止编译。", + "ValueError", vt_col) + return 1 + idx_val: llvmlite.Value* = llvmlite.const_int32(pool, i) + elem_ptr: llvmlite.Value* = llvmlite.build_gep_array( builder, arr_ty, elem_ty, array_alloca, idx_val) if elem_ptr is None: continue @@ -692,19 +1211,22 @@ class AssignGenMixin: # list 泛型(否则 _list 未注册时报特化失败);只有显式 list[T] 注解才引入 _list。 inner_arr: int = 0 if self.Gen.ExprGenBase.is_array_type(elem_ty) != 0: + # 嵌套元素判空:同上硬约定,用 `is not None`(不用整型字面量 0 比较)。 if elem_node is not None and elem_node.kind() == ast.ASTKind.List: inner_arr = 1 if inner_arr != 0: - self._init_global_array_from_list(builder, pool, mod, elem_ptr, elem_node, trans) + self._init_global_array_from_list(builder, pool, mod, elem_ptr, elem_node, trans, owner_ctx) continue - elem_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( + elem_val: 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: rawptr[llvmlite.Value] = elem_val - if elem_ptr.Ty is not None and elem_ptr.Ty.Pointee is not None: + # 判据硬约定:`Pointee` 静态类型是 i64(REnum 载荷槽,非指针)⇒ 必须 `!= 0`; + # 写成 `is not None` 会被折成常量 true(IR 见上方 1146-1156 注释)。 + store_val: llvmlite.Value* = elem_val + if elem_ptr.Ty is not None and elem_ptr.Ty.Pointee != 0: store_val = self.Gen.ExprGenBase.coerce_to_type( builder, elem_val, elem_ptr.Ty.Pointee, elem_node) llvmlite.build_store(builder, store_val, elem_ptr) @@ -717,14 +1239,14 @@ class AssignGenMixin: # 支持浮点运算、指针算术: ptr += int / ptr -= int # 整数运算自动类型提升 # ============================================================ - def _apply_aug_op(self, pool: rawptr[memhub.MemBuddy], - builder: rawptr[llvmlite.IRBuilder], + def _apply_aug_op(self, pool: memhub.MemBuddy*, + builder: llvmlite.IRBuilder*, op: int, - lhs: rawptr[llvmlite.Value], - rhs: rawptr[llvmlite.Value], - node: rawptr[ast.AST] = None, - trans: rawptr[HT.Translator] = None, - lhs_node: rawptr[ast.AST] = None) -> rawptr[llvmlite.Value]: + lhs: llvmlite.Value*, + rhs: llvmlite.Value*, + node: ast.AST* = None, + trans: HT.Translator* = None, + lhs_node: ast.AST* = None) -> 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) @@ -738,7 +1260,7 @@ class AssignGenMixin: target_fbits: int = lhs_fbits if rhs_fbits > target_fbits: target_fbits = rhs_fbits - target_float_ty: rawptr[llvmlite.LLVMType] = llvmlite.Double(pool) + target_float_ty: llvmlite.LLVMType* = llvmlite.Double(pool) if target_fbits == 32: target_float_ty = llvmlite.Float(pool) # 将两个操作数转换为目标浮点类型(int→float via si2fp, float→float via fpext/fptrunc) @@ -758,6 +1280,13 @@ class AssignGenMixin: return self.Gen.ExprGenBase.translate_ptr_arith(pool, builder, lhs, rhs, op) return None + # 双指针算术 fail-fast:判据/报文唯一实现见 ExprGenOps.fail_if_double_ptr_binop + # (BinOp 与 AugAssign 共用,避免分叉)。指针 ± 整数(含 str += int)已在上面 + # translate_ptr_arith 分流;此处的双指针增量赋值(+=、-=、*=、<<= …)在本语言 + # 非法(str 是 i8*,无 `+` 拼接语义),落到 build_add/build_sub/… 会直出 + # `add i8*, i8*` 这类非法 IR。is_aug=1 ⇒ 报文标注「(增量赋值)」并补全符号。 + self.Gen.ExprGenOps.fail_if_double_ptr_binop(pool, op, lhs, rhs, node, 1) + # 整数运算:类型提升 if lhs_bits > rhs_bits and rhs_bits > 0: rhs = self.Gen.ExprGenBase.coerce_to_type(builder, rhs, lhs.Ty, node, trans) @@ -802,8 +1331,43 @@ class AssignGenMixin: # # 支持 += -= *= /= %= &= |= ^= <<= >>=,local/global/nonlocal 三种作用域 # ============================================================ - def translate_augassign(self, trans: rawptr[HT.Translator], - node: rawptr[ast.AST]) -> int: + # ============================================================ + # const 对象赋值拦截(与 TPC 同判据、同报文口径) + # 判据来源:VarEntry.IsConst / FieldEntry.IsConst(注解含 t.CConst 且类型非指针, + # 形参沿用 TPC 的历史判据——只看注解是否含 CConst)。见 + # Debugger/type-descriptors.md「两侧语义对照表」。 + # ============================================================ + def const_assign_msg(self, kind: str, name: str, src_name: str) -> str: + """构造与 TPC `Gen._ConstAssignMessage` 同骨架的 const 赋值报文。 + + 位置(文件/行/列 + 源码片段)由 TypeGenErr.fatal_error 的 Traceback 帧补齐, + 与 TPC `_get_node_info()` 的 `in , line N, col C` + `→ 源码行` 同口径。 + 『声明处类型(含 const)』本侧取 VarEntry/FieldEntry 的 Spec 注解来源名 + (set_var_annot_class_name/add_field 经 SpecWithSource 写入),拼成 + `t.CConst | <来源名>`;来源名缺失时只报 `注解含 t.CConst`。 + + 报文一律用 **f-string 插值**构建:本语言的 str 是 i8*,**没有** `str + str` + 的拼接语义(`+` 会退化成裸指针 add ⇒ 非法 IR: invalid operand type for + instruction),故禁止对 str 用 `+` 拼接。 + """ + decl: str = "(注解含 t.CConst,声明处来源名未记录)" + if src_name is not None: + decl = f"t.CConst | {src_name}" + return f"不能对 const 变量 '{name}' {kind}" \ + f"(声明处类型(含 const):{decl}" \ + f";修法:删掉该声明里的 const 描述符 / t.CConst,或改为声明时一次赋值、" \ + f"之后只用非 const 的副本/中间量;const 对象在其作用域内禁止赋值、" \ + f"增量赋值与元素赋值,且不会降级为警告)" + + def const_assign_fail(self, node: ast.AST*, kind: str, + name: str, src_name: str) -> int: + """const 目标被写入 → 立即 fail-fast(不降级为警告、不静默继续)。""" + self.Gen.TypeGenErr.fatal_error( + node, self.const_assign_msg(kind, name, src_name), "TypeError") + return 0 + + def translate_augassign(self, trans: HT.Translator*, + node: ast.AST*) -> int: """翻译增强赋值语句 (x += 1, y -= 2, etc.)""" if node is None: return 0 @@ -812,7 +1376,7 @@ class AssignGenMixin: if aug is None: return 0 - target: rawptr[ast.AST] = aug.target + target: ast.AST* = aug.target if target is None: return 0 @@ -821,20 +1385,28 @@ class AssignGenMixin: # Attribute 目标: self.field += 1 # 流程: get_attribute_ptr → load → binop → store if tk == ast.ASTKind.Attribute: - pool: rawptr[memhub.MemBuddy] = trans.Pool - builder: rawptr[llvmlite.IRBuilder] = trans._cur_builder - mod: rawptr[llvmlite.LLVMModule] = trans.Module + pool: memhub.MemBuddy* = trans.Pool + builder: llvmlite.IRBuilder* = trans._cur_builder + mod: llvmlite.LLVMModule* = trans.Module + + # const 字段:+= 与 TPC 的 `obj.f = ...` 同一条 fail-fast(字段赋值) + at_ca: ast.Attribute* = ast.Attribute*(target) + if at_ca is not None and at_ca.attr is not None: + if self.Gen.ExprGenAttr.attr_field_is_const( + pool, trans, target) != 0: + self.const_assign_fail(target, "字段赋值", at_ca.attr, + self.Gen.ExprGenAttr.attr_field_decl_src(pool, trans, target)) # 1. 获取字段指针 - field_ptr: rawptr[llvmlite.Value] = self.Gen.ExprGenAttr.get_attribute_ptr( + field_ptr: llvmlite.Value* = self.Gen.ExprGenAttr.get_attribute_ptr( builder, pool, mod, target, trans) if field_ptr is None: # fail-fast: 属性指针解析失败 self.Gen.TypeGenErr.fatal_error(target, "attribute ptr is None", "TypeError") # 2. 确定字段类型并加载当前值 - target_ty: rawptr[llvmlite.LLVMType] = None - if field_ptr.Ty is not None and field_ptr.Ty.Pointee is not None: + target_ty: llvmlite.LLVMType* = None + if field_ptr.Ty is not None and field_ptr.Ty.Pointee != 0: target_ty = field_ptr.Ty.Pointee if target_ty is None: # fail-fast: 字段类型信息缺失,禁止兜底 i32 @@ -843,26 +1415,26 @@ class AssignGenMixin: vol_fa: int = self.Gen.ExprGenAttr.attr_field_is_volatile(pool, trans, target) # rawptr[t.CVolatile|T] 基址(volatile 指针指向物):经其访问的 # 字段 += 的 load/store 亦带 volatile(两来源取或)。 - at_aug: rawptr[ast.Attribute] = rawptr[ast.Attribute](target) + at_aug: ast.Attribute* = ast.Attribute*(target) if at_aug is not None: if self.Gen.ExprGenAttr.base_pointee_is_volatile( pool, trans, at_aug.value) != 0: vol_fa = 1 - cur_val: rawptr[llvmlite.Value] = llvmlite.build_load( + cur_val: llvmlite.Value* = llvmlite.build_load( builder, target_ty, field_ptr, vol_fa) if cur_val is None: # fail-fast: 属性当前值加载失败 self.Gen.TypeGenErr.fatal_error(target, "无法加载 attribute 当前值", "TypeError") # 3. 翻译 RHS 值 - rhs_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( + rhs_val: 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: rawptr[llvmlite.Value] = self._apply_aug_op( + result: llvmlite.Value* = self._apply_aug_op( pool, builder, aug.op, cur_val, rhs_val, node, trans, target) if result is None: # fail-fast: attribute 二元运算失败 @@ -879,20 +1451,41 @@ class AssignGenMixin: # Subscript 目标: self.state[i] += x / arr[i] += x # 流程: get_subscript_ptr → load → binop → store if tk == ast.ASTKind.Subscript: - pool: rawptr[memhub.MemBuddy] = trans.Pool - builder: rawptr[llvmlite.IRBuilder] = trans._cur_builder - mod: rawptr[llvmlite.LLVMModule] = trans.Module + pool: memhub.MemBuddy* = trans.Pool + builder: llvmlite.IRBuilder* = trans._cur_builder + mod: llvmlite.LLVMModule* = trans.Module + + # const 元素目标:p[i] += 与 TPC 的 `p[i] = ...` 同一条 fail-fast + # (元素的元素赋值);基址变量自身或基址字段自身 const 即拒绝。 + sub_ca: ast.Subscript* = ast.Subscript*(target) + if sub_ca is not None and sub_ca.value is not None: + if sub_ca.value.kind() == ast.ASTKind.Name: + nm_ca: ast.Name* = ast.Name*(sub_ca.value) + if nm_ca.id is not None: + ve_ca: GenTypes.VarEntry* = \ + self.Gen.VarGen.lookup_var_entry(trans.SymTab, nm_ca.id) + if self.Gen.VarGen.var_is_const(ve_ca) != 0: + self.const_assign_fail(target, "的元素赋值", nm_ca.id, + self.Gen.VarGen.var_annot_class_name(ve_ca)) + elif sub_ca.value.kind() == ast.ASTKind.Attribute: + at_ca2: ast.Attribute* = ast.Attribute*(sub_ca.value) + if at_ca2.attr is not None: + if self.Gen.ExprGenAttr.attr_field_is_const( + pool, trans, sub_ca.value) != 0: + self.const_assign_fail(target, "的元素赋值", at_ca2.attr, + self.Gen.ExprGenAttr.attr_field_decl_src( + pool, trans, sub_ca.value)) # 1. 获取元素指针 - elem_ptr: rawptr[llvmlite.Value] = self.Gen.ExprGenName.get_subscript_ptr( + elem_ptr: llvmlite.Value* = self.Gen.ExprGenName.get_subscript_ptr( builder, pool, mod, target, trans) if elem_ptr is None: # fail-fast: 下标指针解析失败 self.Gen.TypeGenErr.fatal_error(target, "subscript ptr is None", "TypeError") # 2. 确定元素类型并加载当前值 - target_ty: rawptr[llvmlite.LLVMType] = None - if elem_ptr.Ty is not None and elem_ptr.Ty.Pointee is not None: + target_ty: llvmlite.LLVMType* = None + if elem_ptr.Ty is not None and elem_ptr.Ty.Pointee != 0: target_ty = elem_ptr.Ty.Pointee if target_ty is None: # fail-fast: 元素类型信息缺失,禁止兜底 i32 @@ -900,25 +1493,25 @@ class AssignGenMixin: # rawptr[t.CVolatile|T] 基址(volatile 指针指向物):p[i] += 的 # load/store 均带 volatile。仅基址可解析到 VarEntry/FieldEntry 时为 1。 vol_sa: int = 0 - sub_aug: rawptr[ast.Subscript] = rawptr[ast.Subscript](target) + sub_aug: ast.Subscript* = ast.Subscript*(target) if sub_aug is not None: vol_sa = self.Gen.ExprGenAttr.base_pointee_is_volatile( pool, trans, sub_aug.value) - cur_val: rawptr[llvmlite.Value] = llvmlite.build_load( + cur_val: llvmlite.Value* = llvmlite.build_load( builder, target_ty, elem_ptr, vol_sa) if cur_val is None: # fail-fast: 元素当前值加载失败 self.Gen.TypeGenErr.fatal_error(target, "无法加载 subscript 元素当前值", "TypeError") # 3. 翻译 RHS 值 - rhs_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( + rhs_val: 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: rawptr[llvmlite.Value] = self._apply_aug_op( + result: llvmlite.Value* = self._apply_aug_op( pool, builder, aug.op, cur_val, rhs_val, node, trans, target) if result is None: # fail-fast: subscript 二元运算失败 @@ -937,10 +1530,17 @@ class AssignGenMixin: self.Gen.TypeGenErr.fatal_error( target, "AugAssign 目标类型不支持,仅支持 Name/Attribute/Subscript", "TypeError") - nm: rawptr[ast.Name] = rawptr[ast.Name](target) + nm: ast.Name* = ast.Name*(target) if nm is None or nm.id is None: return 0 + # const 变量:+= 立即 fail-fast(与 TPC HandlesAugAssign 同判据/同报文) + ve_aug: GenTypes.VarEntry* = self.Gen.VarGen.lookup_var_entry( + trans.SymTab, nm.id) + if self.Gen.VarGen.var_is_const(ve_aug) != 0: + self.const_assign_fail(target, "增量赋值", nm.id, + self.Gen.VarGen.var_annot_class_name(ve_aug)) + # REPL 模式(M2/M3)会话变量增强赋值:读槽 → 二元运算 → 写槽 → 写结果区。 # 未登记的会话名返回 0(继续原路径 → 明确的"无法加载…当前值"报错)。 # 守卫 trans.ReplCtx:非 REPL 恒 None ⇒ 本分支整体不经过。 @@ -952,9 +1552,9 @@ class AssignGenMixin: trans, nm.id, aug.op, aug.value, node) != 0: return 0 - pool: rawptr[memhub.MemBuddy] = trans.Pool - builder: rawptr[llvmlite.IRBuilder] = trans._cur_builder - mod: rawptr[llvmlite.LLVMModule] = trans.Module + pool: memhub.MemBuddy* = trans.Pool + builder: llvmlite.IRBuilder* = trans._cur_builder + mod: llvmlite.LLVMModule* = trans.Module # 1. 确定变量作用域类型: 0=local, 1=global, 2=nonlocal scope_type: int = 0 @@ -968,9 +1568,9 @@ class AssignGenMixin: self.Gen.VarGen.lookup_var_entry(trans.SymTab, nm.id)) # 2. 加载当前值 - cur_val: rawptr[llvmlite.Value] = None - target_alloca: rawptr[llvmlite.Value] = None - target_ty: rawptr[llvmlite.LLVMType] = None + cur_val: llvmlite.Value* = None + target_alloca: llvmlite.Value* = None + target_ty: llvmlite.LLVMType* = None if scope_type == 1: # global 变量 @@ -1001,7 +1601,7 @@ class AssignGenMixin: self.Gen.TypeGenErr.fatal_error(target, f"无法加载目标变量 '{nm.id}' 的当前值", "TypeError") # 3. 翻译 RHS 值 - rhs_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( + rhs_val: llvmlite.Value* = self.Gen.ExprGen.translate_value( builder, pool, mod, aug.value, None, 0, trans) if rhs_val is None: # fail-fast: RHS 翻译失败 @@ -1009,7 +1609,7 @@ class AssignGenMixin: # 4. 类型对齐 + 应用二元运算 # 注意: AugAssign 不走运算符重载(语义上需要 __iadd__ 而非 __add__) - result: rawptr[llvmlite.Value] = self._apply_aug_op( + result: llvmlite.Value* = self._apply_aug_op( pool, builder, aug.op, cur_val, rhs_val, node, trans, target) if result is None: # fail-fast: 二元运算失败 @@ -1030,7 +1630,7 @@ class AssignGenMixin: llvmlite.build_store(builder, result, target_alloca, vol_aa) elif scope_type == 2: # nonlocal 变量 - nl_ptr: rawptr[llvmlite.Value] = self.Gen.StmtGenDecl.get_nonlocal_var_ptr( + nl_ptr: 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) @@ -1048,7 +1648,7 @@ class AssignGenMixin: # 真实实现 TypeGenCType._is_ctypedef_annotation 在另一 Mixin,经 # gen 单例(HandlesExpr._g_gen 镜像)跨链调用。 # ============================================================ - def is_ctypedef_annotation(self, annot: rawptr[ast.AST]) -> int: + def is_ctypedef_annotation(self, annot: ast.AST*) -> int: """检测注解是否为 t.CTypedef,返回 1 表示是,0 表示否""" return self.Gen.TypeGenCType._is_ctypedef_annotation(annot) @@ -1060,7 +1660,7 @@ class AssignGenMixin: # 静态数组 [len x elem_ty](对齐 TPC ParseListAnnotation 的 is_pointer 分支: # "单参数 list[type] → 指针,但如果有列表字面量初始化值则按数组 list[type, N] 处理")。 # ============================================================ - def _is_single_param_carray_annot(self, annot: rawptr[ast.AST]) -> int: + def _is_single_param_carray_annot(self, annot: ast.AST*) -> int: """检查注解是否为单参/None 长度 t.CArray[...],返回 1=是 0=否 支持两种书写形式: @@ -1069,22 +1669,23 @@ class AssignGenMixin: """ if annot is None or annot.kind() != ast.ASTKind.Subscript: return 0 - sub: rawptr[ast.Subscript] = rawptr[ast.Subscript](annot) + sub: ast.Subscript* = ast.Subscript*(annot) if sub.value is None or sub.slice is None: return 0 if sub.value.kind() == ast.ASTKind.Attribute: - at: rawptr[ast.Attribute] = rawptr[ast.Attribute](sub.value) + at: ast.Attribute* = ast.Attribute*(sub.value) if at.attr is None or string.strcmp(at.attr, "CArray") != 0: return 0 if at.value is None or at.value.kind() != ast.ASTKind.Name: return 0 - mv: rawptr[ast.Name] = rawptr[ast.Name](at.value) + mv: ast.Name* = ast.Name*(at.value) if mv.id is None or string.strcmp(mv.id, "t") != 0: return 0 elif sub.value.kind() == ast.ASTKind.Name: - # 裸名 CArray(from t import *)/ 内建 rawarray:与 t.CArray 等价 - bn: rawptr[ast.Name] = rawptr[ast.Name](sub.value) - if bn.id is None or (string.strcmp(bn.id, "CArray") != 0 and string.strcmp(bn.id, "rawarray") != 0): + # 裸名 CArray(from t import *)/ 内建 rawarray / 内建 array(软关键字): + # 三者均与 t.CArray 等价 + bn: ast.Name* = ast.Name*(sub.value) + if bn.id is None or (string.strcmp(bn.id, "CArray") != 0 and string.strcmp(bn.id, "rawarray") != 0 and string.strcmp(bn.id, "array") != 0): return 0 else: return 0 @@ -1092,12 +1693,12 @@ class AssignGenMixin: if sub.slice.kind() != ast.ASTKind.Tuple: return 1 # 双参形式:count=None(t.CArray[u64, None])→ 等价单参 - tup: rawptr[ast.Tuple] = rawptr[ast.Tuple](sub.slice) + tup: ast.Tuple* = ast.Tuple*(sub.slice) if tup.elts is None or len(tup.elts) < 2: return 0 - cnt_node: rawptr[ast.AST] = tup.elts.get(1) + cnt_node: ast.AST* = tup.elts.get(1) if cnt_node is not None and cnt_node.kind() == ast.ASTKind.Constant: - cn0: rawptr[ast.Constant] = rawptr[ast.Constant](cnt_node) + cn0: ast.Constant* = ast.Constant*(cnt_node) if cn0.const_kind == ast.CONST_NONE: return 1 return 0 @@ -1106,15 +1707,15 @@ class AssignGenMixin: # 单参 t.CArray[elem_ty] 本解析为 Ptr(elem_ty),RHS 为列表字面量时按 TPC # ParseListAnnotation 语义推断为静态数组(否则误走动态 list 构造 → 链接期 undefined)。 # PreScan 与 Handle 都必须调用:两处 alloca 类型须一致,否则复用旧 alloca 使推断失效。 - def _infer_static_array_ty_from_literal(self, pool: rawptr[memhub.MemBuddy], - annot: rawptr[ast.AST], - value: rawptr[ast.AST], - resolved_ty: rawptr[llvmlite.LLVMType]) -> rawptr[llvmlite.LLVMType]: + def _infer_static_array_ty_from_literal(self, pool: memhub.MemBuddy*, + annot: ast.AST*, + value: ast.AST*, + resolved_ty: llvmlite.LLVMType*) -> llvmlite.LLVMType*: """单参 CArray + 列表字面量 → Array(elem_ty, len);否则返回原类型""" if value is not None and value.kind() == ast.ASTKind.List and resolved_ty is not None: if self._is_single_param_carray_annot(annot) != 0: - elem_ty_arr: rawptr[llvmlite.LLVMType] = resolved_ty.Pointee - lst_arr: rawptr[ast.List] = rawptr[ast.List](value) + elem_ty_arr: llvmlite.LLVMType* = resolved_ty.Pointee + lst_arr: ast.List* = ast.List*(value) cnt_arr: int = 0 if lst_arr.elts is not None: cnt_arr = len(lst_arr.elts) @@ -1122,9 +1723,9 @@ class AssignGenMixin: # 语义是"以字符串内容初始化字符数组",长度应取 strlen+1(含结尾 NUL), # 而不是列表元素个数 1——否则 alloca [1 x i8] 且只写首字节 → 下标 0..15 越界读。 if elem_ty_arr is not None and cnt_arr == 1 and lst_arr.elts is not None: - e0_arr: rawptr[ast.AST] = lst_arr.elts.get(0) + e0_arr: ast.AST* = lst_arr.elts.get(0) if e0_arr is not None and e0_arr.kind() == ast.ASTKind.Constant: - c0_arr: rawptr[ast.Constant] = rawptr[ast.Constant](e0_arr) + c0_arr: ast.Constant* = ast.Constant*(e0_arr) if c0_arr.const_kind == ast.CONST_STR: sv0_arr: str = ast.constant_get_str_val(c0_arr) if sv0_arr is not None and self.Gen.ExprGenBase.get_llvm_type_bits(elem_ty_arr) == 8: @@ -1140,8 +1741,8 @@ class AssignGenMixin: # 以及 builtins 最后匹配的诊断结果(_lookup_builtins_typedef 记录), # 便于直接定位是"注解本身未注册"还是"builtins 扫描未命中/未展开"。 # ============================================================ - def _build_ann_fail_msg(self, pool: rawptr[memhub.MemBuddy], - annot: rawptr[ast.AST], nm_id: str) -> str: + def _build_ann_fail_msg(self, pool: memhub.MemBuddy*, + annot: ast.AST*, nm_id: str) -> str: """构建变量类型注解解析失败的详细报错信息 注意:f-string 翻译产物是栈上 alloca 缓冲,在助手函数返回后帧销毁, @@ -1173,8 +1774,8 @@ class AssignGenMixin: # # 为有类型注解的变量提前创建 alloca 到 entry block 顶部;返回新增的变量数 # ============================================================ - def translate_annassign_prescan(self, trans: rawptr[HT.Translator], - node: rawptr[ast.AST]) -> int: + def translate_annassign_prescan(self, trans: HT.Translator*, + node: ast.AST*) -> int: """预扫描 AnnAssign,提前创建 alloca 到 entry block 顶部""" if node is None: return 0 @@ -1182,14 +1783,14 @@ class AssignGenMixin: if k != ast.ASTKind.AnnAssign: return 0 - aa: rawptr[ast.AnnAssign] = rawptr[ast.AnnAssign](node) + aa: ast.AnnAssign* = ast.AnnAssign*(node) if aa is None or aa.target is None: return 0 - target: rawptr[ast.AST] = aa.target + target: ast.AST* = aa.target if target.kind() != ast.ASTKind.Name: return 0 - nm: rawptr[ast.Name] = rawptr[ast.Name](target) + nm: ast.Name* = ast.Name*(target) if nm.id is None: return 0 @@ -1197,7 +1798,7 @@ class AssignGenMixin: # 供后续 t.CArray[elem_ty, NAME] 编译期解析使用 # 浮点/整数自动识别(与 Handle/handle_module_level_var 路径一致) if self.is_cdefine_annotation(aa.annotation) != 0: - pool_ps: rawptr[memhub.MemBuddy] = trans.Pool + pool_ps: memhub.MemBuddy* = trans.Pool self._register_cdefine_from_value(pool_ps, nm.id, aa.value) return 0 @@ -1230,17 +1831,17 @@ class AssignGenMixin: return 0 # 检查是否已存在 - existing: rawptr[llvmlite.Value] = self.Gen.VarGen.lookup_current( + existing: 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: rawptr[llvmlite.IRBuilder] = trans._cur_builder + pool: memhub.MemBuddy* = trans.Pool + builder: llvmlite.IRBuilder* = trans._cur_builder # 从 annotation 推断类型(修复:原硬编码 i32 导致 str 等类型错误) - var_ty: rawptr[llvmlite.LLVMType] = None - annot: rawptr[ast.AST] = aa.annotation + var_ty: llvmlite.LLVMType* = None + annot: ast.AST* = aa.annotation if annot is not None: # 泛型特化补救(在解析之前无条件执行,_specialize_generic_class 幂等): # 注解可能是 list[X](Subscript)或 list[X] | t.CPtr(含 CPtr 的 BinOp)。 @@ -1250,7 +1851,7 @@ class AssignGenMixin: # i32→AST* 截断指针 → StmtGenMixin._translate_stmt_impl 读垃圾节点崩溃。 # 与 Handle 路径共用 _prespecialize_generic_annotation,保证两处解析一致。 self._prespecialize_generic_annotation(trans, pool, annot) - resolved: rawptr[llvmlite.LLVMType] = self.Gen.TypeGenResolve.resolve_annotation_type( + resolved: llvmlite.LLVMType* = self.Gen.TypeGenResolve.resolve_annotation_type( pool, annot, trans._imported_modules, trans._from_imports, trans, 0) if resolved is not None: var_ty = resolved @@ -1275,7 +1876,7 @@ class AssignGenMixin: # 确保跨模块结构体的完整定义在当前模块中可用(供 alloca 分配空间) self.Gen.StructGen.ensure_struct_def_in_module(pool, trans.Module, var_ty) - alloca: rawptr[llvmlite.Value] = self.Gen.VarGen._alloca_at_entry(builder, var_ty) + alloca: 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: @@ -1292,6 +1893,12 @@ class AssignGenMixin: if self._is_ptr_element_annotation(annot) != 0: self.Gen.VarGen.set_var_ptr_element( trans.SymTab, nm.id) + # const 对象(注解含 t.CConst 且声明类型非指针):整个作用域内 + # 禁止对该变量名赋值/增量赋值/元素赋值。判据与 TPC 的 + # BaseGen._IsConstObject 逐条一致(见 Debugger/type-descriptors.md)。 + if self.Gen.TypeGenErr.is_const_object_marker( + annot, var_ty) != 0: + self.Gen.VarGen.set_var_const(trans.SymTab, nm.id) # t.CVolatile:声明期即标记该变量的 load/store 带 volatile。 # 覆盖「无初值声明」`x: t.CVolatile | T`(有初值路径 # translate_annassign 亦会登记,幂等)。动机:volatile 禁优化器 @@ -1315,35 +1922,35 @@ class AssignGenMixin: # 保证两处解析结果一致(未复用预扫描 alloca 的路径也必须先特化)。 # _specialize_generic_class 幂等,重复调用安全。 # 返回 1=执行过特化尝试;0=注解形态不适用(非泛型 Subscript)。 - def _prespecialize_generic_annotation(self, trans: rawptr[HT.Translator], - pool: rawptr[memhub.MemBuddy], - annot: rawptr[ast.AST]) -> int: + def _prespecialize_generic_annotation(self, trans: HT.Translator*, + pool: memhub.MemBuddy*, + annot: ast.AST*) -> int: """泛型注解预特化(见上方注释),返回 1=已尝试 / 0=不适用""" if annot is None or trans is None: return 0 # 取注解中的泛型 Subscript 一侧:Subscript 本身,或 A | t.CPtr 的 Subscript 分支 - spec_annot: rawptr[ast.Subscript] = None + spec_annot: ast.Subscript* = None if annot.kind() == ast.ASTKind.Subscript: - spec_annot = rawptr[ast.Subscript](annot) + spec_annot = ast.Subscript*(annot) elif annot.kind() == ast.ASTKind.BinOp: - bop_ps: rawptr[ast.BinOp] = rawptr[ast.BinOp](annot) + bop_ps: ast.BinOp* = ast.BinOp*(annot) if bop_ps.op == ast.OpKind.BitOr: if bop_ps.left is not None and bop_ps.left.kind() == ast.ASTKind.Subscript: - spec_annot = rawptr[ast.Subscript](bop_ps.left) + spec_annot = ast.Subscript*(bop_ps.left) elif bop_ps.right is not None and bop_ps.right.kind() == ast.ASTKind.Subscript: - spec_annot = rawptr[ast.Subscript](bop_ps.right) + spec_annot = ast.Subscript*(bop_ps.right) if spec_annot is None: return 0 - sv_ps: rawptr[ast.AST] = spec_annot.value + sv_ps: ast.AST* = spec_annot.value if sv_ps is None or sv_ps.kind() != ast.ASTKind.Name: return 0 - sub_nm: rawptr[ast.Name] = rawptr[ast.Name](sv_ps) + sub_nm: ast.Name* = ast.Name*(sv_ps) if sub_nm.id is None: return 0 - template_cd: rawptr[ast.ClassDef] = self.Gen.ClassGenGeneric._find_generic_template(sub_nm.id) + template_cd: ast.ClassDef* = self.Gen.ClassGenGeneric._find_generic_template(sub_nm.id) if template_cd is None: return 0 - type_args_ps: list[str] | t.CPtr = self.Gen.CallGenCtor._extract_type_args_from_slice( + type_args_ps: list[str]* = self.Gen.CallGenCtor._extract_type_args_from_slice( pool, spec_annot.slice, trans._from_imports) if type_args_ps is None or len(type_args_ps) == 0: return 0 @@ -1358,10 +1965,10 @@ class AssignGenMixin: # 返回新增的变量数 # ============================================================ def _fail_on_degenerated_generic_annotation(self, - aa: rawptr[ast.AnnAssign], + aa: ast.AnnAssign*, var_name: str, - annot: rawptr[ast.AST], - var_ty: rawptr[llvmlite.LLVMType]) -> int: + annot: ast.AST*, + var_ty: llvmlite.LLVMType*) -> int: """fail-fast:泛型注解解析成了「裸泛型基类指针」(丢失类型实参) 场景:注解是泛型下标 `list[X]` 或 `list[X] | t.CPtr`,但 @@ -1380,26 +1987,26 @@ class AssignGenMixin: if aa is None or annot is None or var_ty is None: return 0 # 取注解里的泛型 Subscript 一侧:Subscript 本身,或 A | t.CPtr 的 Subscript 分支 - ann_sub: rawptr[ast.Subscript] = None + ann_sub: ast.Subscript* = None if annot.kind() == ast.ASTKind.Subscript: - ann_sub = rawptr[ast.Subscript](annot) + ann_sub = ast.Subscript*(annot) elif annot.kind() == ast.ASTKind.BinOp: - bop_ff: rawptr[ast.BinOp] = rawptr[ast.BinOp](annot) + bop_ff: ast.BinOp* = ast.BinOp*(annot) if bop_ff.op == ast.OpKind.BitOr: if bop_ff.left is not None and bop_ff.left.kind() == ast.ASTKind.Subscript: - ann_sub = rawptr[ast.Subscript](bop_ff.left) + ann_sub = ast.Subscript*(bop_ff.left) elif bop_ff.right is not None and bop_ff.right.kind() == ast.ASTKind.Subscript: - ann_sub = rawptr[ast.Subscript](bop_ff.right) + ann_sub = ast.Subscript*(bop_ff.right) if ann_sub is None or ann_sub.value is None \ or ann_sub.value.kind() != ast.ASTKind.Name: return 0 - base_nm_ff: rawptr[ast.Name] = rawptr[ast.Name](ann_sub.value) + base_nm_ff: ast.Name* = ast.Name*(ann_sub.value) if base_nm_ff.id is None: return 0 # 仅当该基名确实是泛型模板(list/GSList/...)才判定为退化 if self.Gen.ClassGenGeneric._find_generic_template(base_nm_ff.id) is None: return 0 - if var_ty.Pointee is None: + if var_ty.Pointee == 0: return 0 vt_nm_ff: str = llvmlite.get_struct_name(var_ty.Pointee) if vt_nm_ff is None: @@ -1417,18 +2024,18 @@ class AssignGenMixin: "TypeError") return 0 - def translate_annassign(self, trans: rawptr[HT.Translator], - node: rawptr[ast.AST]) -> int: + def translate_annassign(self, trans: HT.Translator*, + node: ast.AST*) -> int: """翻译 AnnAssign(target=Name, annotation=..., value=expr)""" - aa: rawptr[ast.AnnAssign] = rawptr[ast.AnnAssign](node) + aa: ast.AnnAssign* = ast.AnnAssign*(node) if aa is None: return 0 - target: rawptr[ast.AST] = aa.target + target: ast.AST* = aa.target if target is None or target.kind() != ast.ASTKind.Name: return 0 - nm: rawptr[ast.Name] = rawptr[ast.Name](target) + nm: ast.Name* = ast.Name*(target) if nm.id is None: return 0 @@ -1436,8 +2043,8 @@ class AssignGenMixin: # 注册到全局 CDefine 表供 t.CArray[elem_ty, NAME] 解析 # 注: PreScan 已注册过,此处保证即使跳过 PreScan 也能正确注册 if self.is_cdefine_annotation(aa.annotation) != 0: - pool_cd: rawptr[memhub.MemBuddy] = trans.Pool - self._register_cdefine_from_value(pool_cd, nm.id, aa.value) + pool_cd: memhub.MemBuddy* = trans.Pool + self._register_cdefine_from_value(pool_cd, nm.id, aa.value, aa.annotation) return 0 # CTypedef 注解: 类型别名(mode_t: t.CTypedef = uint32 等)。 @@ -1447,12 +2054,18 @@ class AssignGenMixin: # 解析查表失败 → NameError: mode_t。仅登记类型表达式,不创建全局/ # 局部存储——否则生成 @mode_t 符号,链接 duplicate symbol warning。 if self.is_ctypedef_annotation(aa.annotation) != 0: - pool_ct: rawptr[memhub.MemBuddy] = trans.Pool + pool_ct: memhub.MemBuddy* = trans.Pool ctd_str: str = self.Gen.TypeGenResolve._get_type_name_from_annotation(pool_ct, aa.value) if ctd_str is not None: self.Gen.TypeGenCType.register_ctypedef(pool_ct, nm.id, ctd_str) return 0 + # define / CDefine 常量的**使用处宽度**(`a: T = C` 场景):RHS 是已注册常量 + # 裸名且目标注解是整数类型时,T 的位宽不得小于该常量的 W_min(否则会静默 + # 截断);更宽则照常(消费端按 T 物化/升宽)。判据唯一源与 TPC + # SymbolUtils.RequireDefineUseWidth 同口径。 + self.require_cdefine_use_width(trans.Pool, trans, aa.annotation, aa.value) + # REPL 模式(M2/M3)会话变量:片段**入口**函数本体内的带注解声明/赋值 # (`x: int = 5` 定义并定型;`x: int` 仅定型)。注解先解析并定型条目, # 定型后的槽类型再作为 RHS 的 target_ty(与普通 AnnAssign 的 P1-A 同口径)。 @@ -1467,19 +2080,19 @@ class AssignGenMixin: trans, nm.id, aa.annotation, aa.value, aa) return 0 - pool: rawptr[memhub.MemBuddy] = trans.Pool - builder: rawptr[llvmlite.IRBuilder] = trans._cur_builder - mod: rawptr[llvmlite.LLVMModule] = trans.Module + pool: memhub.MemBuddy* = trans.Pool + builder: llvmlite.IRBuilder* = trans._cur_builder + mod: llvmlite.LLVMModule* = trans.Module # 确定类型(从 annotation 推断) - var_ty: rawptr[llvmlite.LLVMType] = None - annot: rawptr[ast.AST] = aa.annotation + var_ty: llvmlite.LLVMType* = None + annot: ast.AST* = aa.annotation if annot is not None: # 与 PreScan 同源:先注册泛型特化,避免 list[X] 退化为裸 list* 后 .get() # 误分派(返回 i32 → inttoptr 截断)。此处为循环体内重声明同名变量、 # 不复用预扫描 alloca 的路径(详见 _prespecialize_generic_annotation)。 self._prespecialize_generic_annotation(trans, pool, annot) - resolved: rawptr[llvmlite.LLVMType] = self.Gen.TypeGenResolve.resolve_annotation_type( + resolved: llvmlite.LLVMType* = self.Gen.TypeGenResolve.resolve_annotation_type( pool, annot, trans._imported_modules, trans._from_imports, trans, 0) if resolved is not None: var_ty = resolved @@ -1497,7 +2110,7 @@ class AssignGenMixin: "SyntaxError") # t.Callable 函数指针:注册返回类型签名(供函数指针间接调用精确返回类型) - callable_ret: rawptr[llvmlite.LLVMType] = self.Gen.TypeGenErr.try_extract_callable_ret( + callable_ret: llvmlite.LLVMType* = self.Gen.TypeGenErr.try_extract_callable_ret( pool, annot, trans._imported_modules, trans._from_imports, trans) if callable_ret is not None: # 返回值:0=成功/同名同类型幂等命中;非 0 已在 register_func_ptr_sig @@ -1509,13 +2122,13 @@ class AssignGenMixin: # global 变量:写入模块作用域中的全局变量 if GenApi.is_global_name(trans, nm.id) != 0: - mod_alloca: rawptr[llvmlite.Value] = self.Gen.VarGen.lookup_module_var( + mod_alloca: 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 传入, # 使整数字面量按目标位宽直接物化(如 uint64 目标 → i64 const), # 与显式 u64(...) 强转一致,且省去后续 coerce 生成的 zext。 - aa_glob_ty: rawptr[llvmlite.LLVMType] = None + aa_glob_ty: llvmlite.LLVMType* = None if mod_alloca.Ty is not None: aa_glob_ty = mod_alloca.Ty.Pointee # 供裸名泛型构造从注解推断类型实参(消费者见 CallGenCtor.vp 的 @@ -1526,12 +2139,12 @@ class AssignGenMixin: # 会拿不到注解。 trans.CurAssignAnnot = aa.annotation trans.CurAssignNode = aa.value - rhs_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( + rhs_val: llvmlite.Value* = self.Gen.ExprGen.translate_value( builder, pool, mod, aa.value, - None, 0, trans, aa_glob_ty) + None, 0, trans, aa_glob_ty, "模块级全局") if rhs_val is not None: # 对象类全局(有静态 storage):对象构造/赋值 → 绑定 storage + 复制对象 - stg_ref_aa: rawptr[llvmlite.Value] = None + stg_ref_aa: 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: @@ -1539,9 +2152,9 @@ class AssignGenMixin: stg_ref_aa = self.Gen.VarGen.lookup_module_var(trans.SymTab, stg_key_aa) if self._is_addrlike_call(aa.value) == 0 \ and stg_ref_aa is not None and rhs_val.Ty is not None \ - and stg_ref_aa.Ty is not None and stg_ref_aa.Ty.Pointee is not None: - stg_ty_aa: rawptr[llvmlite.LLVMType] = stg_ref_aa.Ty.Pointee - rhs_inner_aa: rawptr[llvmlite.LLVMType] = None + and stg_ref_aa.Ty is not None and stg_ref_aa.Ty.Pointee != 0: + stg_ty_aa: llvmlite.LLVMType* = stg_ref_aa.Ty.Pointee + rhs_inner_aa: llvmlite.LLVMType* = None match rhs_val.Ty: case llvmlite.LLVMType.Ptr(pointee_aa): rhs_inner_aa = pointee_aa @@ -1550,7 +2163,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: rawptr[llvmlite.Value] = llvmlite.build_load( + stg_obj_val_aa: 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) @@ -1559,7 +2172,7 @@ class AssignGenMixin: trans.CurAssignAnnot = None trans.CurAssignNode = None return 0 - target_ty: rawptr[llvmlite.LLVMType] = None + target_ty: llvmlite.LLVMType* = None if mod_alloca.Ty is not None: target_ty = mod_alloca.Ty.Pointee if target_ty is not None: @@ -1581,11 +2194,11 @@ class AssignGenMixin: # P1-A:先把 nonlocal 槽位指针取出(原先在 RHS 翻译之后),以便把 # 槽位类型作为 target_ty 传入;槽位/类型缺失时直接返回,不再发射 # 无用的 RHS 死值。 - nl_ptr: rawptr[llvmlite.Value] = self.Gen.StmtGenDecl.get_nonlocal_var_ptr( + nl_ptr: llvmlite.Value* = self.Gen.StmtGenDecl.get_nonlocal_var_ptr( trans, nm.id) # 从 nl_ptr 的类型推断 nonlocal 变量实际类型, # 不再强制 i32(会截断指针/结构体/i64 导致闭包数据损坏) - nl_target_ty: rawptr[llvmlite.LLVMType] = None + nl_target_ty: llvmlite.LLVMType* = None if nl_ptr is not None and nl_ptr.Ty is not None: nl_target_ty = nl_ptr.Ty.Pointee # 供裸名泛型构造从注解推断类型实参:与主分支、上方 global 分支、 @@ -1595,9 +2208,9 @@ class AssignGenMixin: # `nonlocal s: Stack[int] = Stack()` 的类型实参推断会拿不到注解。 trans.CurAssignAnnot = aa.annotation trans.CurAssignNode = aa.value - rhs_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( + rhs_val: llvmlite.Value* = self.Gen.ExprGen.translate_value( builder, pool, mod, aa.value, - None, 0, trans, nl_target_ty) + None, 0, trans, nl_target_ty, "闭包变量(nonlocal)") if rhs_val is not None: if nl_ptr is not None: if nl_target_ty is None: @@ -1610,7 +2223,7 @@ class AssignGenMixin: trans.CurAssignAnnot = None trans.CurAssignNode = None return 0 - rhs_coerced: rawptr[llvmlite.Value] = self.Gen.ExprGenBase.coerce_to_type( + rhs_coerced: llvmlite.Value* = self.Gen.ExprGenBase.coerce_to_type( builder, rhs_val, nl_target_ty, node) llvmlite.build_store(builder, rhs_coerced, nl_ptr) # 清除赋值上下文(防残留):与主分支清空时机同款。四处(主分支 / @@ -1624,7 +2237,7 @@ class AssignGenMixin: # Python 语义:仅模块级代码(Current == Root)时修改全局变量; # 函数内无 global 声明时应创建局部变量(走后面的 get_or_create_sym 路径)。 if self.Gen.VarGen.is_module_scope(trans.SymTab) != 0: - mod_glob: rawptr[llvmlite.Value] = self.Gen.VarGen.lookup_module_var( + mod_glob: llvmlite.Value* = self.Gen.VarGen.lookup_module_var( trans.SymTab, nm.id) else: mod_glob = None @@ -1636,7 +2249,7 @@ class AssignGenMixin: builder, pool, mod, mod_glob, aa.value, trans) else: # P1-A:模块级全局目标类型作为 target_ty(同上方 global 分支) - mg_val_ty: rawptr[llvmlite.LLVMType] = None + mg_val_ty: llvmlite.LLVMType* = None if mod_glob.Ty is not None: mg_val_ty = mod_glob.Ty.Pointee # 供裸名泛型构造从注解推断类型实参:与主分支、上方 global 分支 @@ -1645,12 +2258,12 @@ class AssignGenMixin: # global / 本 mod_glob 分支 / 上方 nonlocal 分支)必须同步。 trans.CurAssignAnnot = aa.annotation trans.CurAssignNode = aa.value - rhs_val_mg: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( + rhs_val_mg: llvmlite.Value* = self.Gen.ExprGen.translate_value( builder, pool, mod, aa.value, - None, 0, trans, mg_val_ty) + None, 0, trans, mg_val_ty, "模块级全局") if rhs_val_mg is not None: # 对象类全局(有静态 storage):对象构造/赋值 → 绑定 storage + 复制对象 - stg_ref_mg: rawptr[llvmlite.Value] = None + stg_ref_mg: 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: @@ -1658,9 +2271,9 @@ class AssignGenMixin: stg_ref_mg = self.Gen.VarGen.lookup_module_var(trans.SymTab, stg_key_mg) if self._is_addrlike_call(aa.value) == 0 \ and stg_ref_mg is not None and rhs_val_mg.Ty is not None \ - and stg_ref_mg.Ty is not None and stg_ref_mg.Ty.Pointee is not None: - stg_ty_mg: rawptr[llvmlite.LLVMType] = stg_ref_mg.Ty.Pointee - rhs_inner_mg: rawptr[llvmlite.LLVMType] = None + and stg_ref_mg.Ty is not None and stg_ref_mg.Ty.Pointee != 0: + stg_ty_mg: llvmlite.LLVMType* = stg_ref_mg.Ty.Pointee + rhs_inner_mg: llvmlite.LLVMType* = None match rhs_val_mg.Ty: case llvmlite.LLVMType.Ptr(pointee_mg): rhs_inner_mg = pointee_mg @@ -1669,7 +2282,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: rawptr[llvmlite.Value] = llvmlite.build_load( + stg_obj_val_mg: 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) @@ -1678,7 +2291,7 @@ class AssignGenMixin: trans.CurAssignAnnot = None trans.CurAssignNode = None return 0 - target_ty_mg: rawptr[llvmlite.LLVMType] = None + target_ty_mg: llvmlite.LLVMType* = None if mod_glob.Ty is not None: target_ty_mg = mod_glob.Ty.Pointee if target_ty_mg is not None: @@ -1703,7 +2316,7 @@ class AssignGenMixin: # 普通局部变量 # 创建 alloca - alloca: rawptr[llvmlite.Value] = self.Gen.VarGen.get_or_create_sym( + alloca: llvmlite.Value* = self.Gen.VarGen.get_or_create_sym( trans.SymTab, pool, builder, nm.id, var_ty) if alloca is None: # fail-fast: 存储创建失败,立即终止(禁止静默跳过) @@ -1716,11 +2329,11 @@ class AssignGenMixin: # 旧 alloca(同名重声明 / 退化 alloca,如裸 list* 对上 list[ast.ASTptr]*)。 # 只比较「双方都是指针且 pointee 都是结构体」:结构体名不同即 fail-fast(不兜底)。 if alloca is not None and alloca.Ty is not None and var_ty is not None: - av_pt_d: rawptr[llvmlite.LLVMType] = alloca.Ty.Pointee + av_pt_d: llvmlite.LLVMType* = alloca.Ty.Pointee if av_pt_d is not None and self.Gen.ExprGenBase.is_ptr_type(av_pt_d) != 0 \ and self.Gen.ExprGenBase.is_ptr_type(var_ty) != 0: - av_in: rawptr[llvmlite.LLVMType] = av_pt_d.Pointee - vt_in: rawptr[llvmlite.LLVMType] = var_ty.Pointee + av_in: llvmlite.LLVMType* = av_pt_d.Pointee + vt_in: llvmlite.LLVMType* = var_ty.Pointee if av_in is not None and vt_in is not None: av_nm_d: str = llvmlite.get_struct_name(av_in) vt_nm_d: str = llvmlite.get_struct_name(vt_in) @@ -1733,7 +2346,7 @@ class AssignGenMixin: av_pf: int = GenApi.sha1_prefix_len(av_nm_d) av_short: str = av_nm_d + av_pf if av_pf != 0 else av_nm_d if string.strchr(av_short, '[') is None: - av_tpl: rawptr[ast.ClassDef] = self.Gen.ClassGenGeneric._find_generic_template(av_short) + av_tpl: ast.ClassDef* = self.Gen.ClassGenGeneric._find_generic_template(av_short) if av_tpl is not None: self.Gen.TypeGenErr.fatal_error( aa, @@ -1746,11 +2359,11 @@ class AssignGenMixin: # 仅裸 str 注解(Name("str"))且 _str 已注册时创建;bytes / char|t.CPtr 不创建。 # a 保持为 i8*(可 printf/len),a__meta__ 存 __data__/__mbuddy__ 等字段, # 属性读写(fd3)与方法调用(fd5)均通过该影子解析。 - fd_str_ty: rawptr[llvmlite.LLVMType] = None - fd_meta_alloca: rawptr[llvmlite.Value] = None + fd_str_ty: llvmlite.LLVMType* = None + fd_meta_alloca: 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) + fd_annot: ast.Name* = ast.Name*(annot) if fd_annot is not None and fd_annot.id is not None: if string.strcmp(fd_annot.id, "str") == 0: fd_str_ty = self.Gen.StructGen.get_struct_type("_str") @@ -1785,7 +2398,7 @@ class AssignGenMixin: trans.SymTab, nm.id) new_vars: int = 0 - existing: rawptr[llvmlite.Value] = self.Gen.VarGen.lookup_current( + existing: llvmlite.Value* = self.Gen.VarGen.lookup_current( trans.SymTab, nm.id) if existing is None: new_vars = 1 @@ -1797,34 +2410,34 @@ class AssignGenMixin: # value 是 Call 且 func 是 Name 且该名字是 async 函数时, # 登记 _coro_var_async[target] = callee。 if aa.value.kind() == ast.ASTKind.Call: - val_cl: rawptr[ast.Call] = rawptr[ast.Call](aa.value) + val_cl: ast.Call* = ast.Call*(aa.value) if val_cl.func is not None and val_cl.func.kind() == ast.ASTKind.Name: - val_nm: rawptr[ast.Name] = rawptr[ast.Name](val_cl.func) + val_nm: ast.Name* = ast.Name*(val_cl.func) if val_nm.id is not None: if self.Gen.AsyncGen.is_async_func(trans, val_nm.id) != 0: self.Gen.AsyncGen.register_coro_var(trans, nm.id, val_nm.id) # c.Addr(async_call):tt: Coroutine = c.Addr(task()) 就地解读 elif val_cl.func is not None and val_cl.func.kind() == ast.ASTKind.Attribute: - val_at: rawptr[ast.Attribute] = rawptr[ast.Attribute](val_cl.func) + val_at: ast.Attribute* = ast.Attribute*(val_cl.func) if val_at.attr is not None and string.strcmp(val_at.attr, "Addr") == 0 \ and val_cl.args is not None and len(val_cl.args) >= 1: - icall: rawptr[ast.AST] = val_cl.args.get(0) + icall: ast.AST* = val_cl.args.get(0) if icall is not None and icall.kind() == ast.ASTKind.Call: - icl2: rawptr[ast.Call] = rawptr[ast.Call](icall) + icl2: ast.Call* = ast.Call*(icall) if icl2.func is not None and icl2.func.kind() == ast.ASTKind.Name: - inm2: rawptr[ast.Name] = rawptr[ast.Name](icl2.func) + inm2: ast.Name* = ast.Name*(icl2.func) if inm2.id is not None: if self.Gen.AsyncGen.is_async_func(trans, inm2.id) != 0: self.Gen.AsyncGen.register_coro_var(trans, nm.id, inm2.id) # 局部数组:列表字面量 → 先整体置零,再逐元素 GEP + store 初始化。 # 不走 translate_list_literal(避免误触发 list[T] 泛型特化)。 - local_arr_ty: rawptr[llvmlite.LLVMType] = None + local_arr_ty: llvmlite.LLVMType* = None if aa.value.kind() == ast.ASTKind.List and alloca.Ty is not None: - pt_l: rawptr[llvmlite.LLVMType] = alloca.Ty.Pointee + pt_l: llvmlite.LLVMType* = alloca.Ty.Pointee if self.Gen.ExprGenBase.is_array_type(pt_l) != 0: local_arr_ty = pt_l if local_arr_ty is not None: - zero_arr: rawptr[llvmlite.Value] = llvmlite.ConstZero( + zero_arr: llvmlite.Value* = llvmlite.ConstZero( pool, local_arr_ty) if zero_arr is not None: llvmlite.build_store(builder, zero_arr, alloca) @@ -1840,18 +2453,18 @@ class AssignGenMixin: trans.CurAssignNode = aa.value # P1-A:局部变量 alloca 的 pointee 类型作为 target_ty(同全局分支), # 使 `x: uint64 = 12345` 直接物化 i64 常量,与 `x: uint64 = u64(12345)` 一致。 - lv_target_ty: rawptr[llvmlite.LLVMType] = None + lv_target_ty: llvmlite.LLVMType* = None if alloca.Ty is not None: lv_target_ty = alloca.Ty.Pointee - rhs_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( + rhs_val: llvmlite.Value* = self.Gen.ExprGen.translate_value( builder, pool, mod, aa.value, - None, 0, trans, lv_target_ty) + None, 0, trans, lv_target_ty, "局部变量注解") if rhs_val is not None: # 注解退化修复(对齐 TPC 从构造结果推断类型):无实参泛型模板注解 # 会让 alloca 退化为 Ptr(i8),而 rhs 构造返回精确结构体指针 → 用 rhs # 精确类型重建 alloca 并更新符号表,使方法调用按精确特化类名解析; # 旧退化 alloca 残留为 entry 块死代码(文本 IR 即时生成无法删除,无害)。 - precise_rhs_ty: rawptr[llvmlite.LLVMType] = None + precise_rhs_ty: llvmlite.LLVMType* = None if rhs_val.Ty is not None: match rhs_val.Ty: case llvmlite.LLVMType.Ptr(inner_struct): @@ -1863,7 +2476,7 @@ class AssignGenMixin: case _: pass if precise_rhs_ty is not None and alloca.Ty is not None: - alloca_pt: rawptr[llvmlite.LLVMType] = alloca.Ty.Pointee + alloca_pt: llvmlite.LLVMType* = alloca.Ty.Pointee # 禁止「降级重建」:RHS 的 pointee 若是裸泛型基类(丢类型实参, # 如 {sha1}.list / {sha1}.GSList),以它重建会把注解已解析出的 # 带类型实参特化覆盖成裸基类 → .get() 按错误元素类型分派 → @@ -1873,24 +2486,24 @@ class AssignGenMixin: # Subscript 一侧),用于下方不依赖泛型模板注册表的方向判定。 ann_gen_base: str = None if annot is not None: - ag_side: rawptr[ast.AST] = annot + ag_side: ast.AST* = annot if ag_side.kind() == ast.ASTKind.BinOp: - ag_bop: rawptr[ast.BinOp] = rawptr[ast.BinOp](ag_side) + ag_bop: ast.BinOp* = ast.BinOp*(ag_side) if ag_bop.op == ast.OpKind.BitOr: if ag_bop.left is not None and ag_bop.left.kind() == ast.ASTKind.Subscript: ag_side = ag_bop.left elif ag_bop.right is not None and ag_bop.right.kind() == ast.ASTKind.Subscript: ag_side = ag_bop.right if ag_side.kind() == ast.ASTKind.Subscript: - ag_sub: rawptr[ast.Subscript] = rawptr[ast.Subscript](ag_side) + ag_sub: ast.Subscript* = ast.Subscript*(ag_side) if ag_sub.value is not None and ag_sub.value.kind() == ast.ASTKind.Name: - ag_nm: rawptr[ast.Name] = rawptr[ast.Name](ag_sub.value) + ag_nm: ast.Name* = ast.Name*(ag_sub.value) if ag_nm.id is not None: ann_gen_base = ag_nm.id rb_is_bare_generic: int = 0 if alloca_pt is not None \ and uint64(alloca_pt) != uint64(precise_rhs_ty): - rhs_pt_rb: rawptr[llvmlite.LLVMType] = precise_rhs_ty.Pointee + rhs_pt_rb: llvmlite.LLVMType* = precise_rhs_ty.Pointee if rhs_pt_rb is not None: rb_nm: str = llvmlite.get_struct_name(rhs_pt_rb) if rb_nm is not None: @@ -1910,17 +2523,17 @@ class AssignGenMixin: if alloca_pt is not None and \ uint64(alloca_pt) != uint64(precise_rhs_ty) \ and rb_is_bare_generic == 0: - new_alloca: rawptr[llvmlite.Value] = self.Gen.VarGen._alloca_at_entry( + new_alloca: llvmlite.Value* = self.Gen.VarGen._alloca_at_entry( builder, precise_rhs_ty) if new_alloca is not None: - v_entry_rb: rawptr[GenTypes.VarEntry] = self.Gen.VarGen.lookup_var_entry( + v_entry_rb: 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 alloca = new_alloca # 类型转换:将 rhs_val 转换为 alloca 的 pointee 类型 # 修复:整数字面量是 i32,但变量可能是 i8/i16/i64,需 trunc/sext - target_ty: rawptr[llvmlite.LLVMType] = None + target_ty: llvmlite.LLVMType* = None if alloca.Ty is not None: target_ty = alloca.Ty.Pointee if target_ty is not None: @@ -1928,6 +2541,11 @@ class AssignGenMixin: # t.CVolatile 局部变量:标记 VarEntry 并让本次 store 带 volatile vol_laa: int = 0 if aa.annotation is not None and nm.id is not None: + # const 对象局部变量:登记 VarEntry.IsConst(与 prescan 幂等)。 + # 用 alloca 的值类型(target_ty)判指针性,判据同 TPC。 + if self.Gen.TypeGenErr.is_const_object_marker( + aa.annotation, target_ty) != 0: + self.Gen.VarGen.set_var_const(trans.SymTab, nm.id) if self.Gen.TypeGenErr.has_decorator_marker( aa.annotation, "CVolatile", 0) != 0: self.Gen.VarGen.set_var_volatile(trans.SymTab, nm.id) @@ -1941,10 +2559,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: rawptr[GenTypes.FieldEntry] = \ + fd_data_fe: GenTypes.FieldEntry* = \ self.Gen.StructGen.lookup_field(fd_str_ty, "__data__") if fd_data_fe is not None: - fd_data_ptr: rawptr[llvmlite.Value] = \ + fd_data_ptr: llvmlite.Value* = \ llvmlite.build_gep_struct( builder, fd_str_ty, fd_data_fe.Ty, fd_meta_alloca, fd_data_fe.Index) @@ -1961,12 +2579,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: rawptr[GenTypes.FieldEntry] = \ + fd_buddy_fe: GenTypes.FieldEntry* = \ self.Gen.StructGen.lookup_field(fd_str_ty, "__mbuddy__") if fd_buddy_fe is not None and fd_buddy_fe.Ty is not None: - fd_null: rawptr[llvmlite.Value] = llvmlite.ConstNull( + fd_null: llvmlite.Value* = llvmlite.ConstNull( pool, fd_buddy_fe.Ty, "null") - fd_buddy_ptr: rawptr[llvmlite.Value] = \ + fd_buddy_ptr: llvmlite.Value* = \ llvmlite.build_gep_struct( builder, fd_str_ty, fd_buddy_fe.Ty, fd_meta_alloca, fd_buddy_fe.Index) @@ -1985,11 +2603,11 @@ class AssignGenMixin: # 迁移自 HandlesAssign.AssignHandle.Handle(对应 TransPyC # AssignHandle._HandleAssignLlvm)。共享状态从 trans 获取。 # ============================================================ - def translate_assign(self, trans: rawptr[HT.Translator], - node: rawptr[ast.AST]) -> int: + def translate_assign(self, trans: HT.Translator*, + node: ast.AST*) -> int: """翻译 Assign 语句,返回新增变量数(0 或 1)""" - asgn: rawptr[ast.Assign] = rawptr[ast.Assign](node) + asgn: ast.Assign* = ast.Assign*(node) if asgn is None: VLogger.error("cast failed", "ASGN") return 0 @@ -2000,9 +2618,56 @@ class AssignGenMixin: return 0 # 从 trans 取共享状态(替代 11 个参数) - pool: rawptr[memhub.MemBuddy] = trans.Pool - builder: rawptr[llvmlite.IRBuilder] = trans._cur_builder - mod: rawptr[llvmlite.LLVMModule] = trans.Module + pool: memhub.MemBuddy* = trans.Pool + builder: llvmlite.IRBuilder* = trans._cur_builder + mod: llvmlite.LLVMModule* = trans.Module + + # const 目标:赋值前即 fail-fast(与 TPC HandlesAssign 同判据/同报文)。 + # 覆盖 Name(变量自身)/ Attribute(字段自身)/ Subscript(元素赋值, + # 基址是 const 变量或 const 字段时拒绝)。放在 RHS 翻译之前,避免先发射 + # 无用 IR 再报错。 + for ti_c in range(len(targets)): + tgt_c: ast.AST* = targets.get(ti_c) + if tgt_c is None: + continue + if tgt_c.kind() == ast.ASTKind.Name: + nm_c: ast.Name* = ast.Name*(tgt_c) + if nm_c.id is None: + continue + ve_c: GenTypes.VarEntry* = self.Gen.VarGen.lookup_var_entry( + trans.SymTab, nm_c.id) + if self.Gen.VarGen.var_is_const(ve_c) != 0: + self.const_assign_fail(tgt_c, "赋值", nm_c.id, + self.Gen.VarGen.var_annot_class_name(ve_c)) + elif tgt_c.kind() == ast.ASTKind.Attribute: + at_c: ast.Attribute* = ast.Attribute*(tgt_c) + if at_c.attr is None: + continue + if self.Gen.ExprGenAttr.attr_field_is_const(pool, trans, tgt_c) != 0: + self.const_assign_fail(tgt_c, "字段赋值", at_c.attr, + self.Gen.ExprGenAttr.attr_field_decl_src(pool, trans, tgt_c)) + elif tgt_c.kind() == ast.ASTKind.Subscript: + sub_c: ast.Subscript* = ast.Subscript*(tgt_c) + if sub_c.value is None: + continue + if sub_c.value.kind() == ast.ASTKind.Name: + nm_c2: ast.Name* = ast.Name*(sub_c.value) + if nm_c2.id is None: + continue + ve_c2: GenTypes.VarEntry* = self.Gen.VarGen.lookup_var_entry( + trans.SymTab, nm_c2.id) + if self.Gen.VarGen.var_is_const(ve_c2) != 0: + self.const_assign_fail(tgt_c, "的元素赋值", nm_c2.id, + self.Gen.VarGen.var_annot_class_name(ve_c2)) + elif sub_c.value.kind() == ast.ASTKind.Attribute: + at_c2: ast.Attribute* = ast.Attribute*(sub_c.value) + if at_c2.attr is None: + continue + if self.Gen.ExprGenAttr.attr_field_is_const( + pool, trans, sub_c.value) != 0: + self.const_assign_fail(tgt_c, "的元素赋值", at_c2.attr, + self.Gen.ExprGenAttr.attr_field_decl_src( + pool, trans, sub_c.value)) # 翻译 RHS 值 # 无注解赋值无目标类型可推断,清空 CurAssignAnnot/CurAssignNode @@ -2013,13 +2678,13 @@ class AssignGenMixin: # target_ty 传入,使 `x = 12345`(x: uint64)与 `x = u64(12345)` 一致 # (直接 i64 常量,省去 coerce 生成的 zext)。多目标/非 Name 目标无法给出 # 唯一目标类型(且 RHS 只翻译一次供全部目标共用)⇒ 维持原行为(None)。 - asg_target_ty: rawptr[llvmlite.LLVMType] = None + asg_target_ty: llvmlite.LLVMType* = None if len(targets) == 1: - asg_t0: rawptr[ast.AST] = targets.get(0) + asg_t0: ast.AST* = targets.get(0) if asg_t0 is not None and asg_t0.kind() == ast.ASTKind.Name: - asg_nm0: rawptr[ast.Name] = rawptr[ast.Name](asg_t0) + asg_nm0: ast.Name* = ast.Name*(asg_t0) if asg_nm0.id is not None: - asg_slot: rawptr[llvmlite.Value] = self.Gen.VarGen.lookup_var( + asg_slot: 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( @@ -2036,7 +2701,7 @@ class AssignGenMixin: if asg_re is not None \ and asg_re.Kind != GenTypes.REPL_KIND_UNTYPED: asg_target_ty = self.Gen.VarGen.repl_slot_ty(pool, asg_re) - rhs_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( + rhs_val: 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 节点详情,便于定位 @@ -2050,29 +2715,29 @@ class AssignGenMixin: rel_path = StubMergerStore.LookupSha1RelPath(sha1) # 根据 AST 节点类型提取详情 if val_kind == ast.ASTKind.Attribute: - at_nv: rawptr[ast.Attribute] = rawptr[ast.Attribute](asgn.value) + at_nv: ast.Attribute* = ast.Attribute*(asgn.value) attr_nm: str = at_nv.attr target_nm: str = "?" if at_nv.value is not None: if at_nv.value.kind() == ast.ASTKind.Name: - tn_nm: rawptr[ast.Name] = rawptr[ast.Name](at_nv.value) + tn_nm: ast.Name* = ast.Name*(at_nv.value) target_nm = tn_nm.id if rel_path is not None: VLogger.error(f"赋值右侧为 None: {rel_path}:{val_line} '{target_nm}.{attr_nm}' 属性访问失败", "ASGN") else: VLogger.error(f"赋值右侧为 None: sha1={sha1}:{val_line} '{target_nm}.{attr_nm}' 属性访问失败", "ASGN") elif val_kind == ast.ASTKind.Name: - nm_nv: rawptr[ast.Name] = rawptr[ast.Name](asgn.value) + nm_nv: ast.Name* = ast.Name*(asgn.value) if rel_path is not None: VLogger.error(f"赋值右侧为 None: {rel_path}:{val_line} 变量 '{nm_nv.id}' 未找到", "ASGN") else: VLogger.error(f"赋值右侧为 None: sha1={sha1}:{val_line} 变量 '{nm_nv.id}' 未找到", "ASGN") elif val_kind == ast.ASTKind.Call: - cl_nv: rawptr[ast.Call] = rawptr[ast.Call](asgn.value) + cl_nv: ast.Call* = ast.Call*(asgn.value) func_nm: str = "?" if cl_nv.func is not None: if cl_nv.func.kind() == ast.ASTKind.Name: - fn_nm: rawptr[ast.Name] = rawptr[ast.Name](cl_nv.func) + fn_nm: ast.Name* = ast.Name*(cl_nv.func) func_nm = fn_nm.id if rel_path is not None: VLogger.error(f"赋值右侧为 None: {rel_path}:{val_line} 调用 '{func_nm}(...)' 返回 None", "ASGN") @@ -2090,7 +2755,7 @@ class AssignGenMixin: new_vars: int = 0 tn: sizet = len(targets) for ti in range(tn): - target: rawptr[ast.AST] = targets.get(ti) + target: ast.AST* = targets.get(ti) if target is None: continue @@ -2100,7 +2765,7 @@ class AssignGenMixin: # rhs_val 是匿名 struct 值(函数返回 tuple[T1,T2] 打包)→ alloca + # store + GEP 逐字段 load → store 到各 Name 目标。 if tk == ast.ASTKind.Tuple: - tgt_tup: rawptr[ast.Tuple] = rawptr[ast.Tuple](target) + tgt_tup: ast.Tuple* = ast.Tuple*(target) tgt_elts: list[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: @@ -2108,17 +2773,17 @@ class AssignGenMixin: match rhs_val.Ty: case llvmlite.LLVMType.Struct(_, _, _): tgt_n: sizet = len(tgt_elts) - tmp_s: rawptr[llvmlite.Value] = llvmlite.build_alloca(builder, rhs_val.Ty) + tmp_s: 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) - fcur: rawptr[llvmlite.Function] = fchain + fchain: llvmlite.Function* = llvmlite.get_struct_fields(rhs_val.Ty) + fcur: llvmlite.Function* = fchain fti: sizet for fti in range(tgt_n): - tgt_elt: rawptr[ast.AST] = tgt_elts.get(fti) + tgt_elt: ast.AST* = tgt_elts.get(fti) if tgt_elt is None or fcur is None: break - fty: rawptr[llvmlite.LLVMType] = llvmlite.paramnode_get_ty(fcur) + fty: llvmlite.LLVMType* = llvmlite.paramnode_get_ty(fcur) fcur = llvmlite.paramnode_get_next(fcur) if fty is None: # fail-fast: 字段类型缺失,立即终止 @@ -2126,23 +2791,23 @@ class AssignGenMixin: # 守卫:非 Name 元素无法解包,跳过 if tgt_elt.kind() != ast.ASTKind.Name: continue - tgt_nm2: rawptr[ast.Name] = rawptr[ast.Name](tgt_elt) + tgt_nm2: ast.Name* = ast.Name*(tgt_elt) if tgt_nm2.id is None: continue - fp2: rawptr[llvmlite.Value] = llvmlite.build_gep_struct( + fp2: llvmlite.Value* = llvmlite.build_gep_struct( builder, rhs_val.Ty, fty, tmp_s, fti) if fp2 is None: continue - fv2: rawptr[llvmlite.Value] = llvmlite.build_load(builder, fty, fp2) - tgt_alloca: rawptr[llvmlite.Value] = self.Gen.VarGen.lookup_var( + fv2: llvmlite.Value* = llvmlite.build_load(builder, fty, fp2) + tgt_alloca: 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: rawptr[llvmlite.Value] = fv2 - if tgt_alloca.Ty is not None and tgt_alloca.Ty.Pointee is not None: + sval: llvmlite.Value* = fv2 + if tgt_alloca.Ty is not None and tgt_alloca.Ty.Pointee != 0: sval = self.Gen.ExprGenBase.coerce_to_type( builder, fv2, tgt_alloca.Ty.Pointee, node, trans) llvmlite.build_store(builder, sval, tgt_alloca) @@ -2154,13 +2819,13 @@ class AssignGenMixin: if tk == ast.ASTKind.Subscript: # 检查是否是 list[T] 类型的 Subscript(泛型类不注册 struct) # list 的 subscript 赋值走 __setitem__ 内联路径 - list_obj: rawptr[llvmlite.Value] = self.Gen.ExprGenName.is_list_subscript( + list_obj: 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) + sub_node: ast.Subscript* = ast.Subscript*(target) if sub_node is not None and sub_node.slice is not None: - list_idx_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( + list_idx_val: 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 下标翻译失败,立即终止 @@ -2169,18 +2834,23 @@ class AssignGenMixin: builder, pool, list_obj, list_idx_val, rhs_val, target) continue # 普通 Subscript 赋值 - elem_ptr: rawptr[llvmlite.Value] = self.Gen.ExprGenName.get_subscript_ptr( + elem_ptr: llvmlite.Value* = self.Gen.ExprGenName.get_subscript_ptr( builder, pool, mod, target, trans) if elem_ptr is not None: - store_val: rawptr[llvmlite.Value] = rhs_val + store_val: llvmlite.Value* = rhs_val + # fail-fast:rawptr[T] 元素为对象 T、而 RHS 是指向 T 的指针时, + # 下游 coerce_to_type 会静默 load 整对象再按 sizeof(T) 存储 + # (写 sizeof(T) 而非 8 字节指针)。数组槽(t.CArray[T,N])除外。 + self._reject_whole_object_copy_into_ptr_slot( + pool, trans, target, elem_ptr, rhs_val) # 守卫短路:elem 类型完整才做类型转换 - if elem_ptr.Ty is not None and elem_ptr.Ty.Pointee is not None: + if elem_ptr.Ty is not None and elem_ptr.Ty.Pointee != 0: store_val = self.Gen.ExprGenBase.coerce_to_type( builder, rhs_val, elem_ptr.Ty.Pointee, node, trans) # rawptr[t.CVolatile|T] 基址(volatile 指针指向物):p[i] = v # 的 store 带 volatile。仅基址可解析到条目时为 1(否则文本不变)。 vol_sw: int = 0 - sub_wr: rawptr[ast.Subscript] = rawptr[ast.Subscript](target) + sub_wr: ast.Subscript* = ast.Subscript*(target) if sub_wr is not None: vol_sw = self.Gen.ExprGenAttr.base_pointee_is_volatile( pool, trans, sub_wr.value) @@ -2188,33 +2858,33 @@ class AssignGenMixin: continue # get_subscript_ptr 返回 None: 尝试 __setitem__ 运算符重载 # 适用于自定义类(如 hashtable[key]=val → hashtable.__setitem__(key, val)) - sub_asgn: rawptr[ast.Subscript] = rawptr[ast.Subscript](target) + sub_asgn: ast.Subscript* = ast.Subscript*(target) setitem_done: int = 0 if sub_asgn is not None and sub_asgn.value is not None: if sub_asgn.value.kind() == ast.ASTKind.Name: - sub_nm: rawptr[ast.Name] = rawptr[ast.Name](sub_asgn.value) + sub_nm: ast.Name* = ast.Name*(sub_asgn.value) if sub_nm.id is not None: - sub_alloca: rawptr[llvmlite.Value] = self.Gen.VarGen.lookup_var( + sub_alloca: 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 sub_alloca.Ty.Pointee != 0 \ and self.Gen.ExprGenBase.is_ptr_type(sub_alloca.Ty) != 0: - sub_pointee: rawptr[llvmlite.LLVMType] = sub_alloca.Ty.Pointee + sub_pointee: llvmlite.LLVMType* = sub_alloca.Ty.Pointee cls_nm_set: str = self.Gen.StructGen.get_class_name_by_type(pool, sub_pointee) - obj_val_set: rawptr[llvmlite.Value] = llvmlite.build_load( + obj_val_set: llvmlite.Value* = llvmlite.build_load( builder, sub_pointee, sub_alloca) # 指针类型变量 (X|t.CPtr): sub_pointee 是 Ptr(Struct), # 需 load 获取 Ptr(Struct) 再检查 inner struct if cls_nm_set is None and obj_val_set is not None \ and self.Gen.ExprGenBase.is_ptr_type(sub_pointee) != 0 \ - and sub_pointee.Pointee is not None: + and sub_pointee.Pointee != 0: 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: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( + key_val_set: 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) + arg_vals_set: sizet* = pool.alloc(16) if arg_vals_set is not None: arg_vals_set[0] = sizet(key_val_set) arg_vals_set[1] = sizet(rhs_val) @@ -2225,29 +2895,29 @@ 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: rawptr[llvmlite.Value] = self.Gen.ExprGenAttr.get_attribute_ptr( + field_ptr_set: 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 field_ptr_set.Ty.Pointee != 0 \ and self.Gen.ExprGenBase.is_ptr_type(field_ptr_set.Ty) != 0: - field_pointee_set: rawptr[llvmlite.LLVMType] = field_ptr_set.Ty.Pointee + field_pointee_set: 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: rawptr[llvmlite.Value] = field_ptr_set + obj_val_attr: llvmlite.Value* = field_ptr_set # field_ptr 是 Ptr(Ptr(Struct)) (X|t.CPtr 字段): # load 解引用获取 Ptr(Struct) if cls_nm_attr is None \ and self.Gen.ExprGenBase.is_ptr_type(field_pointee_set) != 0 \ - and field_pointee_set.Pointee is not None: + and field_pointee_set.Pointee != 0: cls_nm_attr = self.Gen.StructGen.get_class_name_by_type( pool, field_pointee_set.Pointee) if cls_nm_attr is not None: 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: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( + key_val_attr: 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) + arg_vals_attr: sizet* = pool.alloc(16) if arg_vals_attr is not None: arg_vals_attr[0] = sizet(key_val_attr) arg_vals_attr[1] = sizet(rhs_val) @@ -2259,9 +2929,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: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( + obj_val_gen: llvmlite.Value* = self.Gen.ExprGen.translate_value( builder, pool, mod, sub_asgn.value, None, 0, trans) - key_val_gen: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( + key_val_gen: 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: @@ -2269,12 +2939,12 @@ class AssignGenMixin: cls_nm_gen: str = self.Gen.StructGen.get_class_name_by_type( pool, obj_val_gen.Ty) if cls_nm_gen is None and self.Gen.ExprGenBase.is_ptr_type(obj_val_gen.Ty) != 0 \ - and obj_val_gen.Ty.Pointee is not None: + and obj_val_gen.Ty.Pointee != 0: cls_nm_gen = self.Gen.StructGen.get_class_name_by_type( pool, obj_val_gen.Ty.Pointee) if cls_nm_gen is not None: # 自定义结构体: 调用 __setitem__ - arg_vals_gen: sizet | t.CPtr = pool.alloc(16) + arg_vals_gen: sizet* = pool.alloc(16) if arg_vals_gen is not None: arg_vals_gen[0] = sizet(key_val_gen) arg_vals_gen[1] = sizet(rhs_val) @@ -2283,12 +2953,12 @@ class AssignGenMixin: obj_val_gen, arg_vals_gen, 2, trans) setitem_done = 1 elif self.Gen.ExprGenBase.is_ptr_type(obj_val_gen.Ty) != 0 \ - and obj_val_gen.Ty.Pointee is not None: + and obj_val_gen.Ty.Pointee != 0: # 非自定义结构体: 直接 GEP + store # 处理 get_subscript_ptr 因边界情况返回 None 的指针下标 - elem_gen: rawptr[llvmlite.LLVMType] = obj_val_gen.Ty.Pointee - store_val_gen: rawptr[llvmlite.Value] = rhs_val - elem_ptr_gen: rawptr[llvmlite.Value] = None + elem_gen: llvmlite.LLVMType* = obj_val_gen.Ty.Pointee + store_val_gen: llvmlite.Value* = rhs_val + elem_ptr_gen: llvmlite.Value* = None match elem_gen: case llvmlite.LLVMType.Array(arr_elem_gen, _): elem_ptr_gen = llvmlite.build_gep_array( @@ -2298,7 +2968,7 @@ class AssignGenMixin: elem_ptr_gen = llvmlite.build_gep( builder, elem_gen, obj_val_gen, key_val_gen) if elem_ptr_gen is not None and elem_ptr_gen.Ty is not None: - if elem_ptr_gen.Ty.Pointee is not None: + if elem_ptr_gen.Ty.Pointee != 0: store_val_gen = self.Gen.ExprGenBase.coerce_to_type( builder, rhs_val, elem_ptr_gen.Ty.Pointee, node) llvmlite.build_store(builder, store_val_gen, elem_ptr_gen) @@ -2319,30 +2989,30 @@ class AssignGenMixin: # a.__data__ = v → GEP {a}__meta__[field] 并 store # 对齐 TPC HandlesAssign.py L67-76:对象是 Name 变量且存在 # {var}__meta__ 影子(fd2 创建)时,属性写入改走影子结构体。 - fd_an: rawptr[ast.Attribute] = rawptr[ast.Attribute](target) + fd_an: ast.Attribute* = ast.Attribute*(target) if fd_an is not None and fd_an.value is not None and fd_an.attr is not None: if fd_an.value.kind() == ast.ASTKind.Name: - fd_obj_nm: rawptr[ast.Name] = rawptr[ast.Name](fd_an.value) + fd_obj_nm: ast.Name* = ast.Name*(fd_an.value) if fd_obj_nm.id is not None: # pool 持久缓冲(f-string 栈缓冲在函数返回后失效) 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: rawptr[llvmlite.Value] = self.Gen.VarGen.lookup_current( + fd_meta_vw: 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] = \ + fd_sty_w: llvmlite.LLVMType* = \ self.Gen.StructGen.get_struct_type("_str") if fd_sty_w is not None: - fd_fe_w: rawptr[GenTypes.FieldEntry] = \ + fd_fe_w: GenTypes.FieldEntry* = \ self.Gen.StructGen.lookup_field(fd_sty_w, fd_an.attr) if fd_fe_w is not None and fd_fe_w.Ty is not None: - fd_fp_w: rawptr[llvmlite.Value] = \ + fd_fp_w: 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: rawptr[llvmlite.Value] = \ + sv_fd: 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) @@ -2354,12 +3024,12 @@ class AssignGenMixin: if self.Gen.CallGenVt._write_vtable_attr( builder, pool, mod, target, rhs_val, trans) == 1: continue - field_ptr: rawptr[llvmlite.Value] = self.Gen.ExprGenAttr.get_attribute_ptr( + field_ptr: 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: rawptr[llvmlite.Value] = rhs_val - if field_ptr.Ty is not None and field_ptr.Ty.Pointee is not None: + store_val: llvmlite.Value* = rhs_val + if field_ptr.Ty is not None and field_ptr.Ty.Pointee != 0: store_val = self.Gen.ExprGenBase.coerce_to_type( builder, rhs_val, field_ptr.Ty.Pointee, node, trans) # t.CVolatile 字段:store 带 volatile 限定符 @@ -2367,7 +3037,7 @@ class AssignGenMixin: pool, trans, target) # rawptr[t.CVolatile|T] 基址(volatile 指针指向物):p.field = v # 的 store 亦带 volatile(两来源取或)。 - at_wr: rawptr[ast.Attribute] = rawptr[ast.Attribute](target) + at_wr: ast.Attribute* = ast.Attribute*(target) if at_wr is not None: if self.Gen.ExprGenAttr.base_pointee_is_volatile( pool, trans, at_wr.value) != 0: @@ -2375,13 +3045,13 @@ class AssignGenMixin: llvmlite.build_store(builder, store_val, field_ptr, vol_fw) continue # 守卫:field_ptr 为 None → 构造详细错误信息 - attr_node: rawptr[ast.Attribute] = rawptr[ast.Attribute](target) + attr_node: ast.Attribute* = ast.Attribute*(target) attr_name: str = "(unknown)" obj_name: str = "(unknown)" if attr_node is not None: attr_name = attr_node.attr if attr_node.value is not None and attr_node.value.kind() == ast.ASTKind.Name: - obj_nm: rawptr[ast.Name] = rawptr[ast.Name](attr_node.value) + obj_nm: ast.Name* = ast.Name*(attr_node.value) obj_name = obj_nm.id err_buf: str = pool.alloc(256) if err_buf is not None: @@ -2395,13 +3065,13 @@ class AssignGenMixin: # Name 赋值: var = val if tk == ast.ASTKind.Name: - nm: rawptr[ast.Name] = rawptr[ast.Name](target) + nm: ast.Name* = ast.Name*(target) # 守卫:target 名缺失时跳过 if nm.id is None: continue # global 变量:写入模块作用域中的全局变量 if GenApi.is_global_name(trans, nm.id) != 0: - mod_alloca: rawptr[llvmlite.Value] = self.Gen.VarGen.lookup_module_var( + mod_alloca: llvmlite.Value* = self.Gen.VarGen.lookup_module_var( trans.SymTab, nm.id) if mod_alloca is None: # fail-fast: global 变量未注册,无法赋值 @@ -2412,7 +3082,7 @@ class AssignGenMixin: # 对象类全局(裸类名注解 → 静态 storage):对象构造/赋值 → 引用绑定 # 到 storage + 复制对象到 storage;否则 store 栈 alloca 指针悬垂, # 或模块级构造初始化器被丢弃后全局保持 NULL(见 TranslatorGenMixin)。 - stg_ref_as: rawptr[llvmlite.Value] = None + stg_ref_as: 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: @@ -2420,9 +3090,9 @@ class AssignGenMixin: stg_ref_as = self.Gen.VarGen.lookup_module_var(trans.SymTab, stg_key_as) if self._is_addrlike_call(asgn.value) == 0 \ and stg_ref_as is not None and rhs_val is not None and rhs_val.Ty is not None \ - and stg_ref_as.Ty is not None and stg_ref_as.Ty.Pointee is not None: - stg_ty_as: rawptr[llvmlite.LLVMType] = stg_ref_as.Ty.Pointee - rhs_inner_as: rawptr[llvmlite.LLVMType] = None + and stg_ref_as.Ty is not None and stg_ref_as.Ty.Pointee != 0: + stg_ty_as: llvmlite.LLVMType* = stg_ref_as.Ty.Pointee + rhs_inner_as: llvmlite.LLVMType* = None match rhs_val.Ty: case llvmlite.LLVMType.Ptr(pointee_as): rhs_inner_as = pointee_as @@ -2433,12 +3103,12 @@ class AssignGenMixin: # 1) @g 引用绑定到 storage(丢弃临时 alloca,避免悬垂) llvmlite.build_store(builder, stg_ref_as, mod_alloca) # 2) 复制构造结果(临时对象)到 storage(函数内复制,alloca 仍有效) - stg_obj_val_as: rawptr[llvmlite.Value] = llvmlite.build_load( + stg_obj_val_as: 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) continue - target_ty: rawptr[llvmlite.LLVMType] = None + target_ty: llvmlite.LLVMType* = None if mod_alloca.Ty is not None: target_ty = mod_alloca.Ty.Pointee if target_ty is not None: @@ -2453,7 +3123,7 @@ class AssignGenMixin: # nonlocal 变量:通过闭包 env 写入 if GenApi.is_nonlocal_name(trans, nm.id) != 0: - nl_ptr: rawptr[llvmlite.Value] = self.Gen.StmtGenDecl.get_nonlocal_var_ptr( + nl_ptr: llvmlite.Value* = self.Gen.StmtGenDecl.get_nonlocal_var_ptr( trans, nm.id) if nl_ptr is None: # fail-fast: nonlocal 变量指针解析失败 @@ -2463,7 +3133,7 @@ class AssignGenMixin: "NameError") # 从 nl_ptr 的类型推断 nonlocal 变量实际类型, # 不再强制 i32(会截断指针/结构体/i64 导致闭包数据损坏) - nl_target_ty: rawptr[llvmlite.LLVMType] = None + nl_target_ty: llvmlite.LLVMType* = None if nl_ptr.Ty is not None: nl_target_ty = nl_ptr.Ty.Pointee if nl_target_ty is None: @@ -2472,7 +3142,7 @@ class AssignGenMixin: target, f"nonlocal 变量 '{nm.id}' 类型信息丢失,无法写入", "TypeError") - rhs_coerced: rawptr[llvmlite.Value] = self.Gen.ExprGenBase.coerce_to_type( + rhs_coerced: 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 @@ -2495,13 +3165,13 @@ class AssignGenMixin: # 否则静默创建局部变量遮蔽全局,全局保持 null 导致运行时崩溃 # (_mbuddy = mb 缺 global 声明即此类 bug:Int32 解引用 null 崩溃) if self.Gen.VarGen.is_module_scope(trans.SymTab) == 0: - mod_gv: rawptr[llvmlite.Value] = self.Gen.VarGen.lookup_module_var( + mod_gv: 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: rawptr[llvmlite.Value] = self.Gen.VarGen.get_or_create_sym( + alloca: llvmlite.Value* = self.Gen.VarGen.get_or_create_sym( trans.SymTab, pool, builder, nm.id, rhs_val.Ty) if alloca is not None: # 无注解赋值:从 RHS 表达式推断类名设置变量注解 @@ -2512,8 +3182,8 @@ class AssignGenMixin: self.Gen.VarGen.set_var_annot_class_name( trans.SymTab, nm.id, cls_inf) # 按 alloca 类型对值进行转换(如 double → float) - store_val: rawptr[llvmlite.Value] = rhs_val - if alloca.Ty is not None and alloca.Ty.Pointee is not None: + store_val: llvmlite.Value* = rhs_val + if alloca.Ty is not None and alloca.Ty.Pointee != 0: store_val = self.Gen.ExprGenBase.coerce_to_type( builder, rhs_val, alloca.Ty.Pointee, node, trans) # t.CVolatile 局部变量:store 带 volatile 限定符 @@ -2527,7 +3197,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: rawptr[llvmlite.Value] = self.Gen.VarGen.lookup_current( + existing: llvmlite.Value* = self.Gen.VarGen.lookup_current( trans.SymTab, nm.id) if existing is None: new_vars += 1 @@ -2540,6 +3210,96 @@ class AssignGenMixin: return new_vars + # ============================================================ + # _reject_whole_object_copy_into_ptr_slot - 下标赋值的"整对象拷贝"fail-fast + # + # 目标形态(唯一的判据):赋值左值是 **rawptr[T] 下标**(元素类型 = 对象/结构体 + # T,基座是指针存储),而 RHS 的**值类型是指向 T 的指针**。此时下游 + # coerce_to_type 的"指针 → 非指针值: build_load 解引用"分支会生成 + # %v = load %T, %T* %rhs + # store %T %v, %T* %elem (写 sizeof(T) 字节) + # 而语义上该槽只该写 8 字节指针(槽是按 8 字节排布的缓冲/空闲链表)⇒ + # 每写一个元素越界 sizeof(T)-8 字节,写穿相邻块(MemBuddy 空闲链表被写穿的 + # 静默降级根因)。 + # + # 不拦(判据刻意收窄,避免误伤): + # · 元素是标量(rawptr[int] 等):元素类型不是 Struct,直接返回; + # · 元素本身是指针(rawptr[rawptr[T]]、rawptr[T]|t.CPtr、str|t.CPtr): + # elem_ptr.Ty.Pointee 是 Ptr,不是 Struct,直接返回; + # · 数组槽(t.CArray[T,N] / 内建 Array):subscript_base_store_kind==1, + # `v[i] = T(...)`(构造函数返回临时对象地址)是合法的整对象复制; + # · RHS 的所指类型与元素类型不同、或基座无法静态定型(kind==-1): + # 不表态,保持既有 coerce 行为(不新增静默降级,也不误拦)。 + # · list[rawptr[T]].set / list.__setitem__:走 is_list_subscript 的 + # 内联路径或 list_setitem_inline,不经过本函数。 + # ============================================================ + def _reject_whole_object_copy_into_ptr_slot(self, pool: memhub.MemBuddy*, + trans: HT.Translator*, + target: ast.AST*, + elem_ptr: llvmlite.Value*, + rhs_val: llvmlite.Value*) -> None: + """rawptr[T] 下标赋值 + RHS 为指向 T 的指针 ⇒ fatal_error(整对象拷贝)""" + if elem_ptr is None or elem_ptr.Ty is None: + return + if rhs_val is None or rhs_val.Ty is None: + return + elem_ty: llvmlite.LLVMType* = None + match elem_ptr.Ty: + case llvmlite.LLVMType.Ptr(pointee_wo): + elem_ty = pointee_wo + case _: + return + if elem_ty is None: + return + # 元素必须是对象(结构体)。标量元素(rawptr[int])与指针元素 + # (rawptr[rawptr[T]] / X|t.CPtr)在此返回。 + if elem_ty.kind() != llvmlite.LLVMType.Struct: + return + rhs_inner_wo: llvmlite.LLVMType* = None + match rhs_val.Ty: + case llvmlite.LLVMType.Ptr(pointee_rhs_wo): + rhs_inner_wo = pointee_rhs_wo + case _: + return + if rhs_inner_wo is None: + return + if rhs_inner_wo.kind() != llvmlite.LLVMType.Struct: + return + # 所指类型必须与元素类型一致(否则不是"隐式解引用得 T 再整对象存储") + if self._stg_ty_equal(pool, elem_ty, rhs_inner_wo) == 0: + return + # 数组槽(t.CArray[T,N])整对象赋值合法 → 不拦; + # 仅基座确认为指针存储(kind==0)时才拦,-1(无法判定)不表态。 + if self.Gen.ExprGenName.subscript_base_store_kind(pool, trans, target) != 0: + return + elem_nm_wo: str = llvmlite.get_struct_name(elem_ty) + if elem_nm_wo is None: + elem_nm_wo = "<匿名结构体>" + rhs_nm_wo: str = llvmlite.get_struct_name(rhs_inner_wo) + if rhs_nm_wo is None: + rhs_nm_wo = elem_nm_wo + elem_sz_wo: int = self.Gen.ClassGenEnum._get_type_size(elem_ty) + ptr_sz_wo: int = 8 + over_wo: int = elem_sz_wo - ptr_sz_wo + if over_wo < 0: + over_wo = 0 + col_s_wo: int = 0 + col_e_wo: int = 0 + if target is not None: + col_s_wo = target.col_offset + 1 + col_e_wo = target.end_col_offset + 1 + self.Gen.TypeGenErr.fatal_error( + target, + f"下标赋值的左值元素是对象 '{elem_nm_wo}'({elem_sz_wo} 字节)," + f"右值却是指向 '{rhs_nm_wo}' 的指针:编译器会静默生成整对象拷贝" + f"(load {elem_nm_wo} + store {elem_nm_wo},写 {elem_sz_wo} 字节)," + f"而不是按指针写 {ptr_sz_wo} 字节。若该地址实际按 8 字节槽存放指针" + f"(如 rawptr[T] 缓冲/空闲链表),每写一个元素就越界 {over_wo} 字节," + f"直接写穿相邻块。修法:把指针槽的基座类型写成指针元素形态" + f"(`rawptr[T] | t.CPtr` 或 `rawptr[rawptr[T]]`)后再赋值;" + f"或把基座显式转为 t.CPtr(无类型指针)后按 8 字节指针语义写入。", + "TypeError", col_s_wo, col_e_wo) + # ============================================================ # _infer_rhs_annot - 从 RHS 表达式推断变量注解类名 # @@ -2555,26 +3315,26 @@ class AssignGenMixin: # Attribute → 字段注解类名(委托 Generator 单例 _resolve_attr_field_class) # 仅当目标为已注册结构体时采用,与"按需过滤,找不到 fast-fail"原则一致。 # ============================================================ - def _infer_rhs_annot(self, pool: rawptr[memhub.MemBuddy], - mod: rawptr[llvmlite.LLVMModule], - node: rawptr[ast.AST], - trans: rawptr[HT.Translator], - rhs_val: rawptr[llvmlite.Value] = None) -> str: + def _infer_rhs_annot(self, pool: memhub.MemBuddy*, + mod: llvmlite.LLVMModule*, + node: ast.AST*, + trans: HT.Translator*, + rhs_val: llvmlite.Value* = None) -> str: """从 RHS 表达式推断类名,无法推断返回 None""" if node is None or trans is None: return None k: int = node.kind() # Call: 类实例化 / 方法调用 if k == ast.ASTKind.Call: - cl: rawptr[ast.Call] = rawptr[ast.Call](node) + cl: ast.Call* = ast.Call*(node) if cl is None or cl.func is None: return None if cl.func.kind() == ast.ASTKind.Name: # 类实例化:func 为已注册结构体名才采用 - cand: str = (rawptr[ast.Name](cl.func)).id + cand: str = (ast.Name*(cl.func)).id if cand is None: return None - se: rawptr[GenTypes.StructEntry] = self.Gen.StructGen.find_struct(cand) + se: GenTypes.StructEntry* = self.Gen.StructGen.find_struct(cand) if se is not None: return cand return None @@ -2583,7 +3343,7 @@ class AssignGenMixin: # (方法可返回非同类对象,如 Transform.world_position → 'Vec3', # 启发式取 obj 类名会 GEP 错字段)。vpi 未命中时返回 None, # 由后续属性访问 fast-fail 暴露 vpi 缺失根因(不静默回退)。 - ca: rawptr[ast.Attribute] = rawptr[ast.Attribute](cl.func) + ca: ast.Attribute* = ast.Attribute*(cl.func) if ca is None or ca.attr is None or ca.value is None: return None obj_cls: str = self._infer_rhs_annot(pool, mod, ca.value, trans) @@ -2593,7 +3353,7 @@ class AssignGenMixin: # vpi 返回注解缓存解析返回类名(键 {sha1}.{func},cls_name=None 即模块级 # 函数,与 CallGenMixin 跨模块返回类型解析一致)。 if ca.value.kind() == ast.ASTKind.Name: - mod_nm_rhs: rawptr[ast.Name] = rawptr[ast.Name](ca.value) + mod_nm_rhs: ast.Name* = ast.Name*(ca.value) if mod_nm_rhs.id is not None: mod_sha1_rhs: str = self.Gen.CallGenBase._lookup_module_sha1( mod_nm_rhs.id) @@ -2633,17 +3393,17 @@ class AssignGenMixin: return None # Name: 源变量注解 if k == ast.ASTKind.Name: - nm: rawptr[ast.Name] = rawptr[ast.Name](node) + nm: ast.Name* = ast.Name*(node) if nm is None or nm.id is None: return None - ve: rawptr[GenTypes.VarEntry] = self.Gen.VarGen.lookup_var_entry( + ve: GenTypes.VarEntry* = self.Gen.VarGen.lookup_var_entry( trans.SymTab, nm.id) if ve is None: return None return self.Gen.VarGen.var_annot_class_name(ve) # BinOp/UnaryOp: 运算符重载返回同类对象 if k == ast.ASTKind.BinOp: - bop: rawptr[ast.BinOp] = rawptr[ast.BinOp](node) + bop: ast.BinOp* = ast.BinOp*(node) if bop is None or bop.left is None: return None dunder: str = self._op_to_dunder(bop.op) @@ -2654,7 +3414,7 @@ class AssignGenMixin: return None return lhs_cls if k == ast.ASTKind.UnaryOp: - uop: rawptr[ast.UnaryOp] = rawptr[ast.UnaryOp](node) + uop: ast.UnaryOp* = ast.UnaryOp*(node) if uop is None or uop.operand is None: return None dunder: str = self._op_to_dunder(uop.op) @@ -2677,7 +3437,7 @@ class AssignGenMixin: # CFloat64T/t.CPtr 等均不注册 struct,天然过滤)。"A | B" 联合 # 多候选时取首个命中段。 # ============================================================ - def _extract_annot_class_name(self, pool: rawptr[memhub.MemBuddy], + def _extract_annot_class_name(self, pool: memhub.MemBuddy*, annot: str) -> str: """从返回注解文本提取已注册结构体类名,无命中返回 None""" if pool is None or annot is None: @@ -2704,7 +3464,7 @@ class AssignGenMixin: if seglen > 0 and seglen < 256: string.strncpy(seg, annot + s, seglen) seg[seglen] = '\0' - se: rawptr[GenTypes.StructEntry] = self.Gen.StructGen.find_struct(seg) + se: GenTypes.StructEntry* = self.Gen.StructGen.find_struct(seg) if se is not None: return seg start = i + 1 @@ -2719,7 +3479,7 @@ class AssignGenMixin: if seglen > 0 and seglen < 256: string.strncpy(seg, annot + s, seglen) seg[seglen] = '\0' - se: rawptr[GenTypes.StructEntry] = self.Gen.StructGen.find_struct(seg) + se: GenTypes.StructEntry* = self.Gen.StructGen.find_struct(seg) if se is not None: return seg return None @@ -2753,8 +3513,8 @@ class AssignGenMixin: # 或跨模块类有 SHA1(stub 中声明)即视为存在。仅在确实存在时 # 才采用运算符重载推断的类名,避免把原生运算误标为类类型。 # ============================================================ - def _cls_has_dunder(self, pool: rawptr[memhub.MemBuddy], - mod: rawptr[llvmlite.LLVMModule], + def _cls_has_dunder(self, pool: memhub.MemBuddy*, + mod: llvmlite.LLVMModule*, class_name: str, dunder: str) -> int: """类及其 MRO 祖先链中是否存在 dunder 方法,存在返回 1""" if class_name is None or dunder is None or mod is None: @@ -2766,7 +3526,7 @@ class AssignGenMixin: if self.Gen.CallGenBase.find_func_in_module(mod, lookup_name) is not None: return 1 # 继承链祖先查找 - mro_ptr: sizet | t.CPtr = self.Gen.StructGen.get_mro_chain(pool, class_name) + mro_ptr: sizet* = self.Gen.StructGen.get_mro_chain(pool, class_name) mi: int = 1 while mro_ptr is not None and mro_ptr[mi] != 0: anc: str = (str | t.CPtr)(mro_ptr[mi]) diff --git a/App/lib/core/Gen/AsyncGenMixin.vp b/App/lib/core/Gen/AsyncGenMixin.vp index 3825d7c..b43a420 100644 --- a/App/lib/core/Gen/AsyncGenMixin.vp +++ b/App/lib/core/Gen/AsyncGenMixin.vp @@ -16,31 +16,9 @@ import lib.core.Gen.Call.CallGenBase as CallGenBase # ============================================================ # AsyncGenMixin - TPV-M1 协程翻译(async def / await / coro.coro_run) -# -# M1 最小协程闭环(对齐 TPC lib/core/Handles/HandlesAsyncFunctions.py M1): -# - async def f(): → 帧结构体 %Coro_ = -# { i32 state, i32 done, i32 ret, } -# - create_() → malloc 帧 + 置零 state/done/ret,ret 帧指针 -# - resume_(frame) → switch(state) 状态机:case i → state_i 块 -# (静态段切分,每段以顶层 await 结尾), -# exit 块 load done 返回(0=SUSPEND 1=DONE) -# - await async_fn() → 创建子帧 + resume 到 DONE + 取子帧 ret 槽存父槽 -# + 父挂起(store state=下一恢复段号 + br exit) -# - coro.coro_run(frame) → 内联循环 resume 到 done,返回帧 ret 槽值(i32) -# -# M1 限制(与 TPC M1 一致): -# - async 函数无参数(fd.args 为空) -# - await 仅限顶层 AnnAssign/Assign(value 直接是 Await) -# - 无 coro_sleep / For 内 await / If-While 控制流(后续 M2/M3 扩展) -# -# 继承 CallGenBase(1 级,TPV self 调用仅支持 1 级父类)。 -# @t.NoVTable:静态绑定。 # ============================================================ - -SCOPE_FUNCTION: t.CDefine = 1 - -@t.NoVTable -class AsyncGenMixin(CallGenBase.CallGenBase): +define SCOPE_FUNCTION = 1 +novirtual class AsyncGenMixin(CallGenBase.CallGenBase): """协程翻译 Mixin(TPV-M1 状态机)""" # ============================================================ @@ -49,8 +27,8 @@ class AsyncGenMixin(CallGenBase.CallGenBase): # 由 FuncGenDef.translate_function_def 检测 fd.flags & FLAG_IS_ASYNC # (=1,见 includes/ast/stmts.vp L342-345)后调用,早返回不进普通函数路径。 # ============================================================ - def translate_async_function(self, trans: rawptr[HT.Translator], - node: rawptr[ast.AST]) -> int: + def translate_async_function(self, trans: HT.Translator*, + node: ast.AST*) -> int: """翻译 async 函数定义,返回 0 成功 生成 create_(帧分配,M2 带参数)与 resume_(状态机), @@ -64,12 +42,12 @@ class AsyncGenMixin(CallGenBase.CallGenBase): 恢复块状态号:state0 = 入口,每个 await(顶层或嵌套)按 DFS 顺序 分配 state1..,switch case 预建(TPV build_switch 一次性生成,无法动态 add_case)。 """ - fd: rawptr[ast.FunctionDef] = rawptr[ast.FunctionDef](node) + fd: ast.FunctionDef* = ast.FunctionDef*(node) if fd is None or fd.name is None or trans is None: return 0 name: str = fd.name - pool: rawptr[memhub.MemBuddy] = trans.Pool - mod: rawptr[llvmlite.LLVMModule] = trans.Module + pool: memhub.MemBuddy* = trans.Pool + mod: llvmlite.LLVMModule* = trans.Module if pool is None or mod is None: return 0 @@ -107,7 +85,7 @@ class AsyncGenMixin(CallGenBase.CallGenBase): trans._coro_nseg = 1 + trans._coro_await_count # 帧结构体 %Coro_ - frame_ty: rawptr[llvmlite.LLVMType] = self._build_frame_ty( + frame_ty: llvmlite.LLVMType* = self._build_frame_ty( pool, mod, trans, name, nparams, nlocals, nextra) if frame_ty is None: return 0 @@ -129,30 +107,30 @@ class AsyncGenMixin(CallGenBase.CallGenBase): # ============================================================ # M2:参数收集(帧参数槽 index 3+i) # ============================================================ - def _collect_param_names(self, trans: rawptr[HT.Translator], - fd: rawptr[ast.FunctionDef]) -> int: + def _collect_param_names(self, trans: HT.Translator*, + fd: ast.FunctionDef*) -> int: """收集 async 函数参数名到 trans._coro_params(char* 数组,8 字节/项)。 参数槽 index = 3 + i,create_ 按参数顺序收值入帧。""" if fd is None or fd.args is None or trans is None: return 0 if trans._coro_params is None: return 0 - ags: rawptr[ast.Arguments] = rawptr[ast.Arguments](fd.args) + ags: ast.Arguments* = ast.Arguments*(fd.args) cnt: int = 0 if ags.args is None: return 0 bn: sizet = len(ags.args) i: sizet = 0 for i in range(bn): - a0: rawptr[ast.AST] = ags.args.get(i) + a0: ast.AST* = ags.args.get(i) if a0 is None: continue aname: str = None if a0.kind() == ast.ASTKind.Arg: - ar: rawptr[ast.Arg] = rawptr[ast.Arg](a0) + ar: ast.Arg* = ast.Arg*(a0) aname = ar.arg elif a0.kind() == ast.ASTKind.Name: - anm: rawptr[ast.Name] = rawptr[ast.Name](a0) + anm: ast.Name* = ast.Name*(a0) aname = anm.id if aname is None: continue @@ -175,8 +153,8 @@ class AsyncGenMixin(CallGenBase.CallGenBase): # 位置数组:_coro_await_slots[M]=__await_M 相对序号;_coro_for_slots[N]=__f_idx_N 相对序号 # _coro_await_count = 恢复块数(顶层 + 嵌套 await) # ============================================================ - def _pre_scan_awaits(self, trans: rawptr[HT.Translator], - fd: rawptr[ast.FunctionDef]) -> int: + def _pre_scan_awaits(self, trans: HT.Translator*, + fd: ast.FunctionDef*) -> int: """DFS 预扫描协程体,填额外槽表并返回额外槽总数""" if fd is None or fd.children is None or trans is None: return 0 @@ -191,13 +169,13 @@ class AsyncGenMixin(CallGenBase.CallGenBase): return trans._coro_extra_count # ---------- 第一遍:coro_sleep 检测(wake 槽决定) ---------- - def _scan_sleep_usage(self, trans: rawptr[HT.Translator], - fd: rawptr[ast.FunctionDef]): + def _scan_sleep_usage(self, trans: HT.Translator*, + fd: ast.FunctionDef*): if fd is None or fd.children is None or trans is None: return self._scan_sleep_stmts(trans, fd.children) - def _scan_sleep_stmts(self, trans: rawptr[HT.Translator], + def _scan_sleep_stmts(self, trans: HT.Translator*, stmts: list[ast.AST*]*): if stmts is None or trans._coro_uses_sleep != 0: return @@ -206,8 +184,8 @@ class AsyncGenMixin(CallGenBase.CallGenBase): for i in range(bn): self._scan_sleep_stmt(trans, stmts.get(i)) - def _scan_sleep_stmt(self, trans: rawptr[HT.Translator], - stmt: rawptr[ast.AST]): + def _scan_sleep_stmt(self, trans: HT.Translator*, + stmt: ast.AST*): if stmt is None or trans._coro_uses_sleep != 0: return sk: int = stmt.kind() @@ -230,13 +208,13 @@ class AsyncGenMixin(CallGenBase.CallGenBase): self._scan_sleep_stmts(trans, fn2.orelse) return if sk == ast.ASTKind.Try: - trn: rawptr[ast.Try] = rawptr[ast.Try](stmt) + trn: ast.Try* = ast.Try*(stmt) self._scan_sleep_stmts(trans, stmt.children) if trn.handlers is not None: nh: sizet = len(trn.handlers) hh: sizet = 0 for hh in range(nh): - h0: rawptr[ast.AST] = trn.handlers.get(hh) + h0: ast.AST* = trn.handlers.get(hh) if h0 is not None: self._scan_sleep_stmts(trans, h0.children) self._scan_sleep_stmts(trans, trn.orelse) @@ -247,11 +225,11 @@ class AsyncGenMixin(CallGenBase.CallGenBase): self._scan_sleep_expr(trans, rv.value) return if sk == ast.ASTKind.AnnAssign: - aa: rawptr[ast.AnnAssign] = rawptr[ast.AnnAssign](stmt) + aa: ast.AnnAssign* = ast.AnnAssign*(stmt) self._scan_sleep_expr(trans, aa.value) return if sk == ast.ASTKind.Assign: - as_: rawptr[ast.Assign] = rawptr[ast.Assign](stmt) + as_: ast.Assign* = ast.Assign*(stmt) self._scan_sleep_expr(trans, as_.value) return if sk == ast.ASTKind.Expr: @@ -259,21 +237,21 @@ class AsyncGenMixin(CallGenBase.CallGenBase): self._scan_sleep_expr(trans, e.value) return - def _scan_sleep_expr(self, trans: rawptr[HT.Translator], - node: rawptr[ast.AST]): + def _scan_sleep_expr(self, trans: HT.Translator*, + node: ast.AST*): if node is None or trans._coro_uses_sleep != 0: return k: int = node.kind() if k == ast.ASTKind.Call: - cl: rawptr[ast.Call] = rawptr[ast.Call](node) + cl: ast.Call* = ast.Call*(node) if cl.func is not None: if cl.func.kind() == ast.ASTKind.Name: - nm: rawptr[ast.Name] = rawptr[ast.Name](cl.func) + nm: ast.Name* = ast.Name*(cl.func) if nm.id is not None and string.strcmp(nm.id, "coro_sleep") == 0: trans._coro_uses_sleep = 1 return elif cl.func.kind() == ast.ASTKind.Attribute: - at: rawptr[ast.Attribute] = rawptr[ast.Attribute](cl.func) + at: ast.Attribute* = ast.Attribute*(cl.func) if at.attr is not None and string.strcmp(at.attr, "coro_sleep") == 0: trans._coro_uses_sleep = 1 return @@ -285,12 +263,12 @@ class AsyncGenMixin(CallGenBase.CallGenBase): self._scan_sleep_expr(trans, cl.args.get(j)) return if k == ast.ASTKind.BinOp: - b: rawptr[ast.BinOp] = rawptr[ast.BinOp](node) + b: ast.BinOp* = ast.BinOp*(node) self._scan_sleep_expr(trans, b.left) self._scan_sleep_expr(trans, b.right) return if k == ast.ASTKind.UnaryOp: - u: rawptr[ast.UnaryOp] = rawptr[ast.UnaryOp](node) + u: ast.UnaryOp* = ast.UnaryOp*(node) self._scan_sleep_expr(trans, u.operand) return if k == ast.ASTKind.Compare: @@ -317,11 +295,11 @@ class AsyncGenMixin(CallGenBase.CallGenBase): self._scan_sleep_expr(trans, ie.orelse) return if k == ast.ASTKind.Attribute: - at: rawptr[ast.Attribute] = rawptr[ast.Attribute](node) + at: ast.Attribute* = ast.Attribute*(node) self._scan_sleep_expr(trans, at.value) return if k == ast.ASTKind.Subscript: - sb: rawptr[ast.Subscript] = rawptr[ast.Subscript](node) + sb: ast.Subscript* = ast.Subscript*(node) self._scan_sleep_expr(trans, sb.value) self._scan_sleep_expr(trans, sb.slice) return @@ -331,7 +309,7 @@ class AsyncGenMixin(CallGenBase.CallGenBase): return # ---------- 第二遍:填额外槽表 + 状态号计数 ---------- - def _scan_stmts(self, trans: rawptr[HT.Translator], + def _scan_stmts(self, trans: HT.Translator*, stmts: list[ast.AST*]*): if stmts is None: return @@ -340,8 +318,8 @@ class AsyncGenMixin(CallGenBase.CallGenBase): for i in range(bn): self._scan_stmt(trans, stmts.get(i)) - def _scan_stmt(self, trans: rawptr[HT.Translator], - stmt: rawptr[ast.AST]): + def _scan_stmt(self, trans: HT.Translator*, + stmt: ast.AST*): if stmt is None: return sk: int = stmt.kind() @@ -387,13 +365,13 @@ class AsyncGenMixin(CallGenBase.CallGenBase): self._scan_stmts(trans, fn_.orelse) return if sk == ast.ASTKind.Try: - tr2: rawptr[ast.Try] = rawptr[ast.Try](stmt) + tr2: ast.Try* = ast.Try*(stmt) self._scan_stmts(trans, stmt.children) if tr2.handlers is not None: nh2: sizet = len(tr2.handlers) hh2: sizet = 0 for hh2 in range(nh2): - h2: rawptr[ast.AST] = tr2.handlers.get(hh2) + h2: ast.AST* = tr2.handlers.get(hh2) if h2 is not None: self._scan_stmts(trans, h2.children) self._scan_stmts(trans, tr2.orelse) @@ -419,19 +397,19 @@ class AsyncGenMixin(CallGenBase.CallGenBase): # 语句内嵌套 await:DFS 表达式(AnnAssign.value / Assign.value / Expr.value) self._scan_stmt_exprs(trans, stmt) - def _scan_stmt_exprs(self, trans: rawptr[HT.Translator], - stmt: rawptr[ast.AST]): + def _scan_stmt_exprs(self, trans: HT.Translator*, + stmt: ast.AST*): """扫描语句的值表达式找嵌套 await""" if stmt is None: return sk: int = stmt.kind() if sk == ast.ASTKind.AnnAssign: - aa: rawptr[ast.AnnAssign] = rawptr[ast.AnnAssign](stmt) + aa: ast.AnnAssign* = ast.AnnAssign*(stmt) if aa.value is not None: self._scan_expr(trans, aa.value) return if sk == ast.ASTKind.Assign: - as_: rawptr[ast.Assign] = rawptr[ast.Assign](stmt) + as_: ast.Assign* = ast.Assign*(stmt) if as_.value is not None: self._scan_expr(trans, as_.value) return @@ -442,8 +420,8 @@ class AsyncGenMixin(CallGenBase.CallGenBase): return # 其它语句类型:翻译端 fail-fast - def _scan_expr(self, trans: rawptr[HT.Translator], - node: rawptr[ast.AST]): + def _scan_expr(self, trans: HT.Translator*, + node: ast.AST*): """DFS 扫描表达式找 Await:命中分配 __await_N 槽并计数状态号""" if node is None: return @@ -462,12 +440,12 @@ class AsyncGenMixin(CallGenBase.CallGenBase): trans._coro_await_count = trans._coro_await_count + 1 return if k == ast.ASTKind.BinOp: - b: rawptr[ast.BinOp] = rawptr[ast.BinOp](node) + b: ast.BinOp* = ast.BinOp*(node) self._scan_expr(trans, b.left) self._scan_expr(trans, b.right) return if k == ast.ASTKind.Call: - cl: rawptr[ast.Call] = rawptr[ast.Call](node) + cl: ast.Call* = ast.Call*(node) if cl.func is not None: self._scan_expr(trans, cl.func) if cl.args is not None: @@ -477,7 +455,7 @@ class AsyncGenMixin(CallGenBase.CallGenBase): self._scan_expr(trans, cl.args.get(j)) return if k == ast.ASTKind.UnaryOp: - u: rawptr[ast.UnaryOp] = rawptr[ast.UnaryOp](node) + u: ast.UnaryOp* = ast.UnaryOp*(node) if u.operand is not None: self._scan_expr(trans, u.operand) return @@ -506,12 +484,12 @@ class AsyncGenMixin(CallGenBase.CallGenBase): self._scan_expr(trans, ie.orelse) return if k == ast.ASTKind.Attribute: - at: rawptr[ast.Attribute] = rawptr[ast.Attribute](node) + at: ast.Attribute* = ast.Attribute*(node) if at.value is not None: self._scan_expr(trans, at.value) return if k == ast.ASTKind.Subscript: - sb: rawptr[ast.Subscript] = rawptr[ast.Subscript](node) + sb: ast.Subscript* = ast.Subscript*(node) if sb.value is not None: self._scan_expr(trans, sb.value) if sb.slice is not None: @@ -520,7 +498,7 @@ class AsyncGenMixin(CallGenBase.CallGenBase): # Name / Constant 等叶子:无嵌套 await # ---------- For 判定辅助(M3) ---------- - def _for_deep_await(self, stmt: rawptr[ast.AST]) -> int: + def _for_deep_await(self, stmt: ast.AST*) -> int: """For 语句树(含嵌套 If/While/For/Try/body/orelse)是否含 await""" if stmt is None: return 0 @@ -541,7 +519,7 @@ class AsyncGenMixin(CallGenBase.CallGenBase): return 1 return 0 - def _stmt_deep_await(self, stmt: rawptr[ast.AST]) -> int: + def _stmt_deep_await(self, stmt: ast.AST*) -> int: """语句树(含嵌套 If/While/For/Try)是否含 await""" if stmt is None: return 0 @@ -563,14 +541,14 @@ class AsyncGenMixin(CallGenBase.CallGenBase): if sk2 == ast.ASTKind.For: return self._for_deep_await(stmt) if sk2 == ast.ASTKind.Try: - tr3: rawptr[ast.Try] = rawptr[ast.Try](stmt) + tr3: ast.Try* = ast.Try*(stmt) if self._stmts_deep_await(stmt.children) != 0: return 1 if tr3.handlers is not None: nh3: sizet = len(tr3.handlers) hh3: sizet = 0 for hh3 in range(nh3): - h3: rawptr[ast.AST] = tr3.handlers.get(hh3) + h3: ast.AST* = tr3.handlers.get(hh3) if h3 is not None and self._stmts_deep_await(h3.children) != 0: return 1 if self._stmts_deep_await(tr3.orelse) != 0: @@ -588,7 +566,7 @@ class AsyncGenMixin(CallGenBase.CallGenBase): return 1 return 0 - def _is_range_for(self, stmt: rawptr[ast.AST]) -> int: + def _is_range_for(self, stmt: ast.AST*) -> int: """range-For:单 Name target + iter 是 range(x) 或 range(a, b),参数无 await""" if stmt is None: return 0 @@ -597,10 +575,10 @@ class AsyncGenMixin(CallGenBase.CallGenBase): return 0 if fn4.iter is None or fn4.iter.kind() != ast.ASTKind.Call: return 0 - cl4: rawptr[ast.Call] = rawptr[ast.Call](fn4.iter) + cl4: ast.Call* = ast.Call*(fn4.iter) if cl4.func is None or cl4.func.kind() != ast.ASTKind.Name: return 0 - nm4: rawptr[ast.Name] = rawptr[ast.Name](cl4.func) + nm4: ast.Name* = ast.Name*(cl4.func) if nm4.id is None or string.strcmp(nm4.id, "range") != 0: return 0 if cl4.args is None: @@ -617,8 +595,8 @@ class AsyncGenMixin(CallGenBase.CallGenBase): # ============================================================ # 局部变量收集(顶层 AnnAssign / Assign 的 Name 目标) # ============================================================ - def _collect_local_names(self, trans: rawptr[HT.Translator], - fd: rawptr[ast.FunctionDef]) -> int: + def _collect_local_names(self, trans: HT.Translator*, + fd: ast.FunctionDef*) -> int: """收集帧局部变量名(_coro_locals,8 字节/项): - 顶层 AnnAssign/Assign 的 Name 目标(M2) - try 的 except as e 绑定名(M5/M6,跨 handler 需要帧槽) @@ -632,7 +610,7 @@ class AsyncGenMixin(CallGenBase.CallGenBase): self._collect_locals_stmts(trans, fd.children) return trans._coro_local_count - def _collect_locals_stmts(self, trans: rawptr[HT.Translator], + def _collect_locals_stmts(self, trans: HT.Translator*, stmts: list[ast.AST*]*): if stmts is None: return @@ -641,23 +619,23 @@ class AsyncGenMixin(CallGenBase.CallGenBase): for i in range(bn): self._collect_locals_stmt(trans, stmts.get(i)) - def _collect_locals_stmt(self, trans: rawptr[HT.Translator], - stmt: rawptr[ast.AST]): + def _collect_locals_stmt(self, trans: HT.Translator*, + stmt: ast.AST*): if stmt is None: return sk: int = stmt.kind() if sk == ast.ASTKind.AnnAssign: - aa: rawptr[ast.AnnAssign] = rawptr[ast.AnnAssign](stmt) + aa: ast.AnnAssign* = ast.AnnAssign*(stmt) if aa.target is not None and aa.target.kind() == ast.ASTKind.Name: - tn: rawptr[ast.Name] = rawptr[ast.Name](aa.target) + tn: ast.Name* = ast.Name*(aa.target) self._add_local(trans, tn.id) return if sk == ast.ASTKind.Assign: - as_: rawptr[ast.Assign] = rawptr[ast.Assign](stmt) + as_: ast.Assign* = ast.Assign*(stmt) if as_.targets is not None and len(as_.targets) == 1: - t0: rawptr[ast.AST] = as_.targets.get(0) + t0: ast.AST* = as_.targets.get(0) if t0 is not None and t0.kind() == ast.ASTKind.Name: - tn2: rawptr[ast.Name] = rawptr[ast.Name](t0) + tn2: ast.Name* = ast.Name*(t0) self._add_local(trans, tn2.id) return if sk == ast.ASTKind.If: @@ -674,29 +652,29 @@ class AsyncGenMixin(CallGenBase.CallGenBase): fn: rawptr[ast.For] = rawptr[ast.For](stmt) if self._for_deep_await(stmt) != 0: if fn.target is not None and fn.target.kind() == ast.ASTKind.Name: - tn3: rawptr[ast.Name] = rawptr[ast.Name](fn.target) + tn3: ast.Name* = ast.Name*(fn.target) self._add_local(trans, tn3.id) self._collect_locals_stmts(trans, stmt.children) self._collect_locals_stmts(trans, fn.orelse) return if sk == ast.ASTKind.Try: - tr: rawptr[ast.Try] = rawptr[ast.Try](stmt) + tr: ast.Try* = ast.Try*(stmt) self._collect_locals_stmts(trans, stmt.children) if tr.handlers is not None: nh: sizet = len(tr.handlers) hh: sizet = 0 for hh in range(nh): - h0: rawptr[ast.AST] = tr.handlers.get(hh) + h0: ast.AST* = tr.handlers.get(hh) if h0 is None: continue - hd: rawptr[ast.ExceptHandler] = rawptr[ast.ExceptHandler](h0) + hd: ast.ExceptHandler* = ast.ExceptHandler*(h0) self._add_local(trans, hd.name) self._collect_locals_stmts(trans, h0.children) self._collect_locals_stmts(trans, tr.orelse) self._collect_locals_stmts(trans, tr.finalbody) return - def _add_local(self, trans: rawptr[HT.Translator], + def _add_local(self, trans: HT.Translator*, name: str): if name is None: return @@ -712,18 +690,18 @@ class AsyncGenMixin(CallGenBase.CallGenBase): # 帧结构体 %Coro_ = { i32 state, i32 done, i32 ret, <局部槽>* } # 槽索引: 0=state 1=done 2=ret 3..3+nlocals-1=局部变量 # ============================================================ - def _build_frame_ty(self, pool: rawptr[memhub.MemBuddy], - mod: rawptr[llvmlite.LLVMModule], - trans: rawptr[HT.Translator], + def _build_frame_ty(self, pool: memhub.MemBuddy*, + mod: llvmlite.LLVMModule*, + trans: HT.Translator*, name: str, nparams: int, nlocals: int, - nextra: int) -> rawptr[llvmlite.LLVMType]: + nextra: int) -> llvmlite.LLVMType*: """构造帧结构体并注册到模块与结构体表,返回 LLVMType M7 布局:{i32 state, i32 done, i32 ret, i32 exc, i8* msg, 参数槽(5+i), 局部槽(5+nparams+i), 额外槽(extra_base+i, 按类型表 1=i32 2=i64)}""" - i32_ty: rawptr[llvmlite.LLVMType] = llvmlite.Int32(pool) - i64_ty: rawptr[llvmlite.LLVMType] = llvmlite.Int64(pool) - i8_ptr_ty: rawptr[llvmlite.LLVMType] = llvmlite.Ptr( + i32_ty: llvmlite.LLVMType* = llvmlite.Int32(pool) + i64_ty: llvmlite.LLVMType* = llvmlite.Int64(pool) + i8_ptr_ty: llvmlite.LLVMType* = llvmlite.Ptr( pool, llvmlite.Int8(pool)) # 槽基址(供 resume/await 计算槽 index) trans._coro_local_base = 5 + nparams @@ -733,7 +711,7 @@ class AsyncGenMixin(CallGenBase.CallGenBase): prev: rawptr[llvmlite.ParamNode] = None fi: int = 0 for fi in range(total): - fty: rawptr[llvmlite.LLVMType] = i32_ty + fty: llvmlite.LLVMType* = i32_ty if fi == 4: fty = i8_ptr_ty elif fi >= trans._coro_extra_base: @@ -755,7 +733,7 @@ class AsyncGenMixin(CallGenBase.CallGenBase): ty_name: str = pool.alloc(128) if ty_name is not None: viperlib.snprintf(ty_name, 128, "Coro_%s", name) - frame_ty: rawptr[llvmlite.LLVMType] = llvmlite.Struct( + frame_ty: llvmlite.LLVMType* = llvmlite.Struct( pool, head, total, ty_name) if frame_ty is None: return None @@ -767,22 +745,22 @@ class AsyncGenMixin(CallGenBase.CallGenBase): # ============================================================ # create_() -> %Coro_* # ============================================================ - def _emit_create(self, pool: rawptr[memhub.MemBuddy], - mod: rawptr[llvmlite.LLVMModule], - trans: rawptr[HT.Translator], + def _emit_create(self, pool: memhub.MemBuddy*, + mod: llvmlite.LLVMModule*, + trans: HT.Translator*, name: str, - frame_ty: rawptr[llvmlite.LLVMType], + frame_ty: llvmlite.LLVMType*, nparams: int) -> int: """生成 create_(args...):M7 帧池弹帧(i64 池头 free-list)或 malloc, 5 头清零 + 参数存槽(帧槽 5+i)+ ret 帧指针""" if frame_ty is None: return 0 - i32_ty: rawptr[llvmlite.LLVMType] = llvmlite.Int32(pool) - i64_ty: rawptr[llvmlite.LLVMType] = llvmlite.Int64(pool) - i8_ty: rawptr[llvmlite.LLVMType] = llvmlite.Int8(pool) - i8_ptr_ty: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, i8_ty) - i64_ptr_ty: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, i64_ty) - frame_ptr_ty: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, frame_ty) + i32_ty: llvmlite.LLVMType* = llvmlite.Int32(pool) + i64_ty: llvmlite.LLVMType* = llvmlite.Int64(pool) + i8_ty: llvmlite.LLVMType* = llvmlite.Int8(pool) + i8_ptr_ty: llvmlite.LLVMType* = llvmlite.Ptr(pool, i8_ty) + i64_ptr_ty: llvmlite.LLVMType* = llvmlite.Ptr(pool, i64_ty) + frame_ptr_ty: llvmlite.LLVMType* = llvmlite.Ptr(pool, frame_ty) cname_buf2: str = pool.alloc(64) if cname_buf2 is not None: @@ -791,7 +769,7 @@ class AsyncGenMixin(CallGenBase.CallGenBase): trans, cname_buf2, 0) if self.Gen.CallGenBase.find_func_in_module(mod, mangled) is not None: return 0 - func: rawptr[llvmlite.Function] = llvmlite.create_function( + func: llvmlite.Function* = llvmlite.create_function( pool, mod, mangled, frame_ptr_ty) if func is None: return 0 @@ -804,7 +782,7 @@ class AsyncGenMixin(CallGenBase.CallGenBase): viperlib.snprintf(argn_buf, 16, "%%arg%d", pi) llvmlite.add_param(pool, func, i32_ty, argn_buf) # 注册到函数表(裸名 create_) - funcs_ptr: rawptr[GenTypes.FuncEntry] = trans._funcs + funcs_ptr: GenTypes.FuncEntry* = trans._funcs cur_count: int = trans._func_count if self.Gen.CallGenLeafKit.add_func_to_table( funcs_ptr, cur_count, cname_buf2, func, 1024, @@ -815,32 +793,32 @@ class AsyncGenMixin(CallGenBase.CallGenBase): pool, func, "entry") if entry is None: return 0 - builder: rawptr[llvmlite.IRBuilder] = llvmlite.new_builder(pool, func) + builder: llvmlite.IRBuilder* = llvmlite.new_builder(pool, func) if builder is None: return 0 llvmlite.position_at_end(builder, entry) frame_size: int = self.Gen.ClassGenEnum._get_type_size(frame_ty) - size_val: rawptr[llvmlite.Value] = llvmlite.const_int64(pool, frame_size) + size_val: llvmlite.Value* = llvmlite.const_int64(pool, frame_size) if size_val is None: return 0 size_val.Next = None # M7 帧池:i64 池头(0 = 空);帧首 8 字节存 next(覆盖 state/done,弹池后统一清零) - pool_gv: rawptr[llvmlite.GlobalVariable] = self._get_coro_pool( + pool_gv: llvmlite.GlobalVariable* = self._get_coro_pool( pool, mod, trans, name) # GlobalVariable 非 Value 子类:构造 Value 视图(Ty=Ptr(i64), Name="@coro_pool_") pool_ref_name: str = pool.alloc(96) if pool_ref_name is not None: viperlib.snprintf(pool_ref_name, 96, "@coro_pool_%s", name) - pool_ref: rawptr[llvmlite.Value] = llvmlite.SSAValue( + pool_ref: llvmlite.Value* = llvmlite.SSAValue( pool, i64_ptr_ty, pool_ref_name) - pool_head: rawptr[llvmlite.Value] = llvmlite.build_load( + pool_head: llvmlite.Value* = llvmlite.build_load( builder, i64_ty, pool_ref) if pool_head is None: return 0 - zero64: rawptr[llvmlite.Value] = llvmlite.const_int64(pool, 0) - empty_cond: rawptr[llvmlite.Value] = llvmlite.build_icmp( + zero64: llvmlite.Value* = llvmlite.const_int64(pool, 0) + empty_cond: llvmlite.Value* = llvmlite.build_icmp( builder, llvmlite.ICMP_EQ, pool_head, zero64) if empty_cond is None: return 0 @@ -855,29 +833,29 @@ class AsyncGenMixin(CallGenBase.CallGenBase): llvmlite.build_cond_br(builder, empty_cond, miss_bb, hit_bb) # hit:弹池(帧首 8 字节是 next) llvmlite.position_at_end(builder, hit_bb) - node_next_ptr: rawptr[llvmlite.Value] = llvmlite.build_inttoptr( + node_next_ptr: llvmlite.Value* = llvmlite.build_inttoptr( builder, pool_head, i64_ptr_ty) - next_head: rawptr[llvmlite.Value] = llvmlite.build_load( + next_head: llvmlite.Value* = llvmlite.build_load( builder, i64_ty, node_next_ptr) if next_head is None: return 0 llvmlite.build_store(builder, next_head, pool_ref) - hit_frame: rawptr[llvmlite.Value] = llvmlite.build_inttoptr( + hit_frame: llvmlite.Value* = llvmlite.build_inttoptr( builder, pool_head, frame_ptr_ty) if hit_frame is None: return 0 llvmlite.build_br(builder, join_bb) # miss:malloc + 帧首 8 字节置 0(弹池帧的 next 残留清零) llvmlite.position_at_end(builder, miss_bb) - raw: rawptr[llvmlite.Value] = llvmlite.build_call( + raw: llvmlite.Value* = llvmlite.build_call( builder, "malloc", size_val, 1, i8_ptr_ty, 0) if raw is None: return 0 - miss_frame: rawptr[llvmlite.Value] = llvmlite.build_bitcast( + miss_frame: llvmlite.Value* = llvmlite.build_bitcast( builder, raw, frame_ptr_ty) if miss_frame is None: return 0 - miss_head_ptr: rawptr[llvmlite.Value] = llvmlite.build_bitcast( + miss_head_ptr: llvmlite.Value* = llvmlite.build_bitcast( builder, miss_frame, i64_ptr_ty) if miss_head_ptr is not None: llvmlite.build_store(builder, zero64, miss_head_ptr) @@ -891,34 +869,34 @@ class AsyncGenMixin(CallGenBase.CallGenBase): if inc1 is None or inc2 is None: return 0 inc1.Next = inc2 - frame_ref: rawptr[llvmlite.Value] = llvmlite.build_phi( + frame_ref: llvmlite.Value* = llvmlite.build_phi( builder, frame_ptr_ty, inc1, 2) if frame_ref is None: return 0 - zero: rawptr[llvmlite.Value] = llvmlite.const_int32(pool, 0) - null_p: rawptr[llvmlite.Value] = llvmlite.ConstNull(pool, i8_ptr_ty, "null") + zero: llvmlite.Value* = llvmlite.const_int32(pool, 0) + null_p: llvmlite.Value* = llvmlite.ConstNull(pool, i8_ptr_ty, "null") si: int = 0 for si in range(5): if si == 4: - mslot: rawptr[llvmlite.Value] = llvmlite.build_gep_struct( + mslot: llvmlite.Value* = llvmlite.build_gep_struct( builder, frame_ty, i8_ptr_ty, frame_ref, 4) if mslot is not None: llvmlite.build_store(builder, null_p, mslot) else: - slot: rawptr[llvmlite.Value] = llvmlite.build_gep_struct( + slot: llvmlite.Value* = llvmlite.build_gep_struct( builder, frame_ty, i32_ty, frame_ref, si) if slot is not None: llvmlite.build_store(builder, zero, slot) # 参数存帧槽(index 5+i) pj: int = 0 for pj in range(nparams): - pslot: rawptr[llvmlite.Value] = llvmlite.build_gep_struct( + pslot: llvmlite.Value* = llvmlite.build_gep_struct( builder, frame_ty, i32_ty, frame_ref, 5 + pj) if pslot is not None: arnb: str = pool.alloc(16) if arnb is not None: viperlib.snprintf(arnb, 16, "%%arg%d", pj) - arg_ref: rawptr[llvmlite.Value] = llvmlite.SSAValue( + arg_ref: llvmlite.Value* = llvmlite.SSAValue( pool, i32_ty, arnb) if arg_ref is not None: llvmlite.build_store(builder, arg_ref, pslot) @@ -928,23 +906,23 @@ class AsyncGenMixin(CallGenBase.CallGenBase): # ============================================================ # M7:每帧类型的全局 free-list 池头(i64,0 = 空) # ============================================================ - def _get_coro_pool(self, pool: rawptr[memhub.MemBuddy], - mod: rawptr[llvmlite.LLVMModule], - trans: rawptr[HT.Translator], - name: str) -> rawptr[llvmlite.GlobalVariable]: + def _get_coro_pool(self, pool: memhub.MemBuddy*, + mod: llvmlite.LLVMModule*, + trans: HT.Translator*, + name: str) -> llvmlite.GlobalVariable*: """取/建 coro_pool_ 全局(i64 池头)。池节点 next 存帧首 8 字节。""" pn_buf: str = pool.alloc(128) if pn_buf is not None: viperlib.snprintf(pn_buf, 128, "coro_pool_%s", name) # 幂等:create/destroy 都会调用,须先查模块全局链表(无 find_global API) - g: rawptr[llvmlite.GlobalVariable] = mod.GlobalHead + g: llvmlite.GlobalVariable* = mod.GlobalHead while g is not None: if g.Name is not None and string.strcmp(g.Name, pn_buf) == 0: return g g = g.Next return llvmlite.create_global_int(pool, mod, pn_buf, 64, 0) - def _register_coro_wake(self, trans: rawptr[HT.Translator], + def _register_coro_wake(self, trans: HT.Translator*, name: str, wake_idx: int): """记录 async 名的 wake 槽 index(_coro_wake_names/_coro_wake_idxs 平行表)""" if trans is None or name is None or trans._coro_wake_names is None: @@ -958,7 +936,7 @@ class AsyncGenMixin(CallGenBase.CallGenBase): trans._coro_wake_idxs[cnt] = wake_idx trans._coro_wake_count = cnt + 1 - def _lookup_coro_wake(self, trans: rawptr[HT.Translator], + def _lookup_coro_wake(self, trans: HT.Translator*, name: str) -> int: """查 async 名的 wake 槽 index,无 wake 槽返回 -1""" if trans is None or name is None or trans._coro_wake_names is None: @@ -974,12 +952,12 @@ class AsyncGenMixin(CallGenBase.CallGenBase): # ============================================================ # resume_(%Coro_*) -> i32 状态机(静态段切分) # ============================================================ - def _emit_resume(self, pool: rawptr[memhub.MemBuddy], - mod: rawptr[llvmlite.LLVMModule], - trans: rawptr[HT.Translator], + def _emit_resume(self, pool: memhub.MemBuddy*, + mod: llvmlite.LLVMModule*, + trans: HT.Translator*, name: str, - fd: rawptr[ast.FunctionDef], - frame_ty: rawptr[llvmlite.LLVMType], + fd: ast.FunctionDef*, + frame_ty: llvmlite.LLVMType*, nparams: int, nlocals: int, nextra: int) -> int: """生成 resume_(frame) -> i32 状态机(M2): @@ -988,20 +966,20 @@ class AsyncGenMixin(CallGenBase.CallGenBase): exit 块 load done 返回(0=SUSPEND 1=DONE)。""" if frame_ty is None: return 0 - i32_ty: rawptr[llvmlite.LLVMType] = llvmlite.Int32(pool) - frame_ptr_ty: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, frame_ty) + i32_ty: llvmlite.LLVMType* = llvmlite.Int32(pool) + frame_ptr_ty: llvmlite.LLVMType* = llvmlite.Ptr(pool, frame_ty) rname_buf: str = pool.alloc(64) if rname_buf is not None: viperlib.snprintf(rname_buf, 64, "resume_%s", name) mangled: str = self.Gen.FuncGenBase._mangle_func_name( trans, rname_buf, 0) - func: rawptr[llvmlite.Function] = llvmlite.create_function( + func: llvmlite.Function* = llvmlite.create_function( pool, mod, mangled, i32_ty) if func is None: return 0 llvmlite.add_param(pool, func, frame_ptr_ty, "%frame") - funcs_ptr: rawptr[GenTypes.FuncEntry] = trans._funcs + funcs_ptr: GenTypes.FuncEntry* = trans._funcs cur_count: int = trans._func_count if self.Gen.CallGenLeafKit.add_func_to_table( funcs_ptr, cur_count, rname_buf, func, 1024, @@ -1012,29 +990,29 @@ class AsyncGenMixin(CallGenBase.CallGenBase): pool, func, "entry") if entry is None: return 0 - builder: rawptr[llvmlite.IRBuilder] = llvmlite.new_builder(pool, func) + builder: llvmlite.IRBuilder* = llvmlite.new_builder(pool, func) if builder is None: return 0 llvmlite.position_at_end(builder, entry) - frame_arg: rawptr[llvmlite.Value] = llvmlite.SSAValue( + frame_arg: llvmlite.Value* = llvmlite.SSAValue( pool, frame_ptr_ty, "%frame") if frame_arg is None: return 0 # GEP 5 头槽(M4 exc / M7 msg) - i8_ptr_ty_r: rawptr[llvmlite.LLVMType] = llvmlite.Ptr( + i8_ptr_ty_r: llvmlite.LLVMType* = llvmlite.Ptr( pool, llvmlite.Int8(pool)) - i64_ty_r: rawptr[llvmlite.LLVMType] = llvmlite.Int64(pool) - state_ptr: rawptr[llvmlite.Value] = llvmlite.build_gep_struct( + i64_ty_r: llvmlite.LLVMType* = llvmlite.Int64(pool) + state_ptr: llvmlite.Value* = llvmlite.build_gep_struct( builder, frame_ty, i32_ty, frame_arg, 0) - done_ptr: rawptr[llvmlite.Value] = llvmlite.build_gep_struct( + done_ptr: llvmlite.Value* = llvmlite.build_gep_struct( builder, frame_ty, i32_ty, frame_arg, 1) - ret_ptr: rawptr[llvmlite.Value] = llvmlite.build_gep_struct( + ret_ptr: llvmlite.Value* = llvmlite.build_gep_struct( builder, frame_ty, i32_ty, frame_arg, 2) - exc_ptr: rawptr[llvmlite.Value] = llvmlite.build_gep_struct( + exc_ptr: llvmlite.Value* = llvmlite.build_gep_struct( builder, frame_ty, i32_ty, frame_arg, 3) - msg_ptr: rawptr[llvmlite.Value] = llvmlite.build_gep_struct( + msg_ptr: llvmlite.Value* = llvmlite.build_gep_struct( builder, frame_ty, i8_ptr_ty_r, frame_arg, 4) # 参数槽 GEP → 注册到符号表(index 5+i) @@ -1043,7 +1021,7 @@ class AsyncGenMixin(CallGenBase.CallGenBase): pname: str = self._read_param_name(trans, pj) if pname is None: continue - pslot: rawptr[llvmlite.Value] = llvmlite.build_gep_struct( + pslot: llvmlite.Value* = llvmlite.build_gep_struct( builder, frame_ty, i32_ty, frame_arg, 5 + pj) if pslot is not None: self.Gen.VarGen.define_var(trans.SymTab, pname, pslot) @@ -1054,7 +1032,7 @@ class AsyncGenMixin(CallGenBase.CallGenBase): lname: str = self._read_local_name(trans, li) if lname is None: continue - slot: rawptr[llvmlite.Value] = llvmlite.build_gep_struct( + slot: llvmlite.Value* = llvmlite.build_gep_struct( builder, frame_ty, i32_ty, frame_arg, trans._coro_local_base + li) if slot is not None: @@ -1068,10 +1046,10 @@ class AsyncGenMixin(CallGenBase.CallGenBase): ety: int = 1 if trans._coro_extra_types is not None: ety = trans._coro_extra_types[ei] - ety_llvm: rawptr[llvmlite.LLVMType] = i32_ty + ety_llvm: llvmlite.LLVMType* = i32_ty if ety == 2: ety_llvm = i64_ty_r - eslot: rawptr[llvmlite.Value] = llvmlite.build_gep_struct( + eslot: llvmlite.Value* = llvmlite.build_gep_struct( builder, frame_ty, ety_llvm, frame_arg, trans._coro_extra_base + ei) if eslot is None: @@ -1115,7 +1093,7 @@ class AsyncGenMixin(CallGenBase.CallGenBase): self.Gen.VarGen.define_var(trans.SymTab, ename, eslot) # state 值 + exit 块 - state_val: rawptr[llvmlite.Value] = llvmlite.build_load( + state_val: llvmlite.Value* = llvmlite.build_load( builder, i32_ty, state_ptr) exit_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block( pool, func, "coro.exit") @@ -1145,7 +1123,7 @@ class AsyncGenMixin(CallGenBase.CallGenBase): if nseg <= 0: nseg = 1 # 预建 state 块 + switch case(一次性生成,await 恢复块 position 填充) - state_bbs: sizet | t.CPtr = pool.alloc(nseg * 8) + state_bbs: sizet* = pool.alloc(nseg * 8) if state_bbs is None: return 0 trans._coro_state_bbs = state_bbs @@ -1185,15 +1163,15 @@ class AsyncGenMixin(CallGenBase.CallGenBase): self._handle_segment(trans, builder, pool, mod, fd.children) # 函数体自然结束 → 隐式 return(ret=0 + done=1 + br exit) if llvmlite.builder_cur_block_is_terminated(builder) == 0: - zret: rawptr[llvmlite.Value] = llvmlite.const_int32(pool, 0) - done_one: rawptr[llvmlite.Value] = llvmlite.const_int32(pool, 1) + zret: llvmlite.Value* = llvmlite.const_int32(pool, 0) + done_one: llvmlite.Value* = llvmlite.const_int32(pool, 1) llvmlite.build_store(builder, zret, ret_ptr) llvmlite.build_store(builder, done_one, done_ptr) llvmlite.build_br(builder, exit_bb) # exit 块:load done 返回(0=SUSPEND 1=DONE) llvmlite.position_at_end(builder, exit_bb) - done_val: rawptr[llvmlite.Value] = llvmlite.build_load( + done_val: llvmlite.Value* = llvmlite.build_load( builder, i32_ty, done_ptr) llvmlite.build_ret(builder, done_val) return 0 @@ -1201,10 +1179,10 @@ class AsyncGenMixin(CallGenBase.CallGenBase): # ============================================================ # M2:协程体递归翻译(Return/顶层 await/If/While/嵌套 await/普通) # ============================================================ - def _handle_segment(self, trans: rawptr[HT.Translator], - builder: rawptr[llvmlite.IRBuilder], - pool: rawptr[memhub.MemBuddy], - mod: rawptr[llvmlite.LLVMModule], + def _handle_segment(self, trans: HT.Translator*, + builder: llvmlite.IRBuilder*, + pool: memhub.MemBuddy*, + mod: llvmlite.LLVMModule*, stmts: list[ast.AST*]*): """递归翻译协程体语句。builder 当前块 = 活跃执行块(state0 或某恢复块)。""" if stmts is None: @@ -1212,7 +1190,7 @@ class AsyncGenMixin(CallGenBase.CallGenBase): bn: sizet = len(stmts) i: sizet = 0 for i in range(bn): - stmt: rawptr[ast.AST] = stmts.get(i) + stmt: ast.AST* = stmts.get(i) if stmt is None: continue # 当前块已终止(return/挂起后无后续)→ 停止本段 @@ -1232,7 +1210,7 @@ class AsyncGenMixin(CallGenBase.CallGenBase): self._handle_coro_raise(builder, pool, mod, trans, stmt) continue if sk == ast.ASTKind.Try: - tr_: rawptr[ast.Try] = rawptr[ast.Try](stmt) + tr_: ast.Try* = ast.Try*(stmt) has_fin: int = 0 has_exc: int = 0 if tr_.finalbody is not None and len(tr_.finalbody) > 0: @@ -1297,11 +1275,11 @@ class AsyncGenMixin(CallGenBase.CallGenBase): # ============================================================ # M2:协程版 If(分支内 await 就地挂起/恢复) # ============================================================ - def _handle_coro_if(self, trans: rawptr[HT.Translator], - builder: rawptr[llvmlite.IRBuilder], - pool: rawptr[memhub.MemBuddy], - mod: rawptr[llvmlite.LLVMModule], - stmt: rawptr[ast.AST]): + def _handle_coro_if(self, trans: HT.Translator*, + builder: llvmlite.IRBuilder*, + pool: memhub.MemBuddy*, + mod: llvmlite.LLVMModule*, + stmt: ast.AST*): ifn: rawptr[ast.If] = rawptr[ast.If](stmt) if ifn is None or ifn.test is None: return @@ -1311,12 +1289,12 @@ class AsyncGenMixin(CallGenBase.CallGenBase): viperlib.snprintf(err_b, 256, "[coro-M2] if 条件中不支持 await") self.Gen.TypeGenErr.fatal_error(stmt, err_b, "SyntaxError") return - cond: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( + cond: llvmlite.Value* = self.Gen.ExprGen.translate_value( builder, pool, mod, ifn.test, None, 0, trans) if cond is None: return - cond1: rawptr[llvmlite.Value] = self._normalize_cond(builder, pool, cond) - func: rawptr[llvmlite.Function] = trans._cur_func + cond1: llvmlite.Value* = self._normalize_cond(builder, pool, cond) + func: llvmlite.Function* = trans._cur_func then_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block( pool, func, "coro.then") merge_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block( @@ -1347,11 +1325,11 @@ class AsyncGenMixin(CallGenBase.CallGenBase): # ============================================================ # M2:协程版 While(条件块 + 循环体,body 内 await 就地挂起/恢复) # ============================================================ - def _handle_coro_while(self, trans: rawptr[HT.Translator], - builder: rawptr[llvmlite.IRBuilder], - pool: rawptr[memhub.MemBuddy], - mod: rawptr[llvmlite.LLVMModule], - stmt: rawptr[ast.AST]): + def _handle_coro_while(self, trans: HT.Translator*, + builder: llvmlite.IRBuilder*, + pool: memhub.MemBuddy*, + mod: llvmlite.LLVMModule*, + stmt: ast.AST*): whn: rawptr[ast.While] = rawptr[ast.While](stmt) if whn is None: return @@ -1361,7 +1339,7 @@ class AsyncGenMixin(CallGenBase.CallGenBase): viperlib.snprintf(err_c, 256, "[coro-M2] while 条件中不支持 await") self.Gen.TypeGenErr.fatal_error(stmt, err_c, "SyntaxError") return - func: rawptr[llvmlite.Function] = trans._cur_func + func: llvmlite.Function* = trans._cur_func cond_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block( pool, func, "coro.wcond") body_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block( @@ -1378,11 +1356,11 @@ class AsyncGenMixin(CallGenBase.CallGenBase): llvmlite.build_br(builder, cond_bb) # 条件块 llvmlite.position_at_end(builder, cond_bb) - cond: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( + cond: llvmlite.Value* = self.Gen.ExprGen.translate_value( builder, pool, mod, whn.test, None, 0, trans) if cond is None: cond = llvmlite.const_int32(pool, 0) - cond1: rawptr[llvmlite.Value] = self._normalize_cond(builder, pool, cond) + cond1: llvmlite.Value* = self._normalize_cond(builder, pool, cond) llvmlite.build_cond_br(builder, cond1, body_bb, after_bb) # 循环体 llvmlite.position_at_end(builder, body_bb) @@ -1397,11 +1375,11 @@ class AsyncGenMixin(CallGenBase.CallGenBase): # ============================================================ # M2:嵌套 await 提升:a = b + await f() → __await_N = await f(); a = b + __await_N # ============================================================ - def _handle_nested_await_stmt(self, trans: rawptr[HT.Translator], - builder: rawptr[llvmlite.IRBuilder], - pool: rawptr[memhub.MemBuddy], - mod: rawptr[llvmlite.LLVMModule], - stmt: rawptr[ast.AST]): + def _handle_nested_await_stmt(self, trans: HT.Translator*, + builder: llvmlite.IRBuilder*, + pool: memhub.MemBuddy*, + mod: llvmlite.LLVMModule*, + stmt: ast.AST*): """把语句中所有嵌套 await 提升为顶层临时赋值(与预扫描 DFS 顺序一致)""" guard: int = 0 while True: @@ -1418,7 +1396,7 @@ class AsyncGenMixin(CallGenBase.CallGenBase): # 目标槽 = __await_N 帧额外槽(预扫描位置数组,wake/for 槽穿插在前) slot_idx: int = trans._coro_extra_base + trans._coro_await_slots[trans._coro_hoist_count] trans._coro_hoist_count = trans._coro_hoist_count + 1 - slot: rawptr[llvmlite.Value] = llvmlite.build_gep_struct( + slot: llvmlite.Value* = llvmlite.build_gep_struct( builder, self._lookup_coro_frame_by_trans(trans), llvmlite.Int32(pool), trans._coro_frame, slot_idx) trans._coro_await_slot = slot @@ -1433,22 +1411,22 @@ class AsyncGenMixin(CallGenBase.CallGenBase): # ============================================================ # 嵌套 await 存在性 / 提取 / 替换(DFS 与预扫描同序) # ============================================================ - def _stmt_has_await(self, stmt: rawptr[ast.AST]) -> int: + def _stmt_has_await(self, stmt: ast.AST*) -> int: aw: rawptr[ast.Await] = self._extract_first_await(stmt) if aw is not None: return 1 return 0 - def _extract_first_await(self, stmt: rawptr[ast.AST]) -> rawptr[ast.Await]: + def _extract_first_await(self, stmt: ast.AST*) -> rawptr[ast.Await]: """取语句中第一个 Await 节点(DFS 字段序),未命中返回 None""" if stmt is None: return None sk: int = stmt.kind() if sk == ast.ASTKind.AnnAssign: - aa: rawptr[ast.AnnAssign] = rawptr[ast.AnnAssign](stmt) + aa: ast.AnnAssign* = ast.AnnAssign*(stmt) return self._find_expr_await(aa.value) if sk == ast.ASTKind.Assign: - as_: rawptr[ast.Assign] = rawptr[ast.Assign](stmt) + as_: ast.Assign* = ast.Assign*(stmt) return self._find_expr_await(as_.value) if sk == ast.ASTKind.Expr: e: rawptr[ast.Expr] = rawptr[ast.Expr](stmt) @@ -1458,7 +1436,7 @@ class AsyncGenMixin(CallGenBase.CallGenBase): return self._find_expr_await(rv.value) return None - def _find_expr_await(self, node: rawptr[ast.AST]) -> rawptr[ast.Await]: + def _find_expr_await(self, node: ast.AST*) -> rawptr[ast.Await]: """表达式树中 DFS 找第一个 Await""" if node is None: return None @@ -1466,13 +1444,13 @@ class AsyncGenMixin(CallGenBase.CallGenBase): if k == ast.ASTKind.Await: return rawptr[ast.Await](node) if k == ast.ASTKind.BinOp: - b: rawptr[ast.BinOp] = rawptr[ast.BinOp](node) + b: ast.BinOp* = ast.BinOp*(node) r: rawptr[ast.Await] = self._find_expr_await(b.left) if r is not None: return r return self._find_expr_await(b.right) if k == ast.ASTKind.Call: - cl: rawptr[ast.Call] = rawptr[ast.Call](node) + cl: ast.Call* = ast.Call*(node) if cl.func is not None: r2: rawptr[ast.Await] = self._find_expr_await(cl.func) if r2 is not None: @@ -1486,7 +1464,7 @@ class AsyncGenMixin(CallGenBase.CallGenBase): return r3 return None if k == ast.ASTKind.UnaryOp: - u: rawptr[ast.UnaryOp] = rawptr[ast.UnaryOp](node) + u: ast.UnaryOp* = ast.UnaryOp*(node) return self._find_expr_await(u.operand) if k == ast.ASTKind.Compare: cm: rawptr[ast.Compare] = rawptr[ast.Compare](node) @@ -1521,30 +1499,30 @@ class AsyncGenMixin(CallGenBase.CallGenBase): return r8 return self._find_expr_await(ie.orelse) if k == ast.ASTKind.Attribute: - at: rawptr[ast.Attribute] = rawptr[ast.Attribute](node) + at: ast.Attribute* = ast.Attribute*(node) return self._find_expr_await(at.value) if k == ast.ASTKind.Subscript: - sb: rawptr[ast.Subscript] = rawptr[ast.Subscript](node) + sb: ast.Subscript* = ast.Subscript*(node) r9: rawptr[ast.Await] = self._find_expr_await(sb.value) if r9 is not None: return r9 return self._find_expr_await(sb.slice) return None - def _replace_await_with_name(self, pool: rawptr[memhub.MemBuddy], - stmt: rawptr[ast.AST], + def _replace_await_with_name(self, pool: memhub.MemBuddy*, + stmt: ast.AST*, temp_name: str) -> int: """把语句树中第一个 Await 替换为 Name(temp_name)(DFS 字段序)""" if stmt is None or temp_name is None: return 0 sk: int = stmt.kind() if sk == ast.ASTKind.AnnAssign: - aa: rawptr[ast.AnnAssign] = rawptr[ast.AnnAssign](stmt) + aa: ast.AnnAssign* = ast.AnnAssign*(stmt) if aa.value is not None: return self._replace_expr_await(pool, aa.value, temp_name) return 0 if sk == ast.ASTKind.Assign: - as_: rawptr[ast.Assign] = rawptr[ast.Assign](stmt) + as_: ast.Assign* = ast.Assign*(stmt) if as_.value is not None: return self._replace_expr_await(pool, as_.value, temp_name) return 0 @@ -1560,8 +1538,8 @@ class AsyncGenMixin(CallGenBase.CallGenBase): return 0 return 0 - def _replace_expr_await(self, pool: rawptr[memhub.MemBuddy], - node: rawptr[ast.AST], + def _replace_expr_await(self, pool: memhub.MemBuddy*, + node: ast.AST*, temp_name: str) -> int: """在表达式树中把第一个 Await 替换为 Name(temp_name, Load)。 node 本身是 Await 时返回 2(由父字段替换)。返回 1=已替换 0=无 2=node 即 Await。""" @@ -1571,7 +1549,7 @@ class AsyncGenMixin(CallGenBase.CallGenBase): if k == ast.ASTKind.Await: return 2 if k == ast.ASTKind.BinOp: - b: rawptr[ast.BinOp] = rawptr[ast.BinOp](node) + b: ast.BinOp* = ast.BinOp*(node) r: int = self._replace_expr_await(pool, b.left, temp_name) if r == 1: return 1 @@ -1586,7 +1564,7 @@ class AsyncGenMixin(CallGenBase.CallGenBase): return 1 return 0 if k == ast.ASTKind.Call: - cl: rawptr[ast.Call] = rawptr[ast.Call](node) + cl: ast.Call* = ast.Call*(node) if cl.func is not None: r3: int = self._replace_expr_await(pool, cl.func, temp_name) if r3 == 1: @@ -1606,7 +1584,7 @@ class AsyncGenMixin(CallGenBase.CallGenBase): return 1 return 0 if k == ast.ASTKind.UnaryOp: - u: rawptr[ast.UnaryOp] = rawptr[ast.UnaryOp](node) + u: ast.UnaryOp* = ast.UnaryOp*(node) r5: int = self._replace_expr_await(pool, u.operand, temp_name) if r5 == 1: return 1 @@ -1668,7 +1646,7 @@ class AsyncGenMixin(CallGenBase.CallGenBase): return 1 return 0 if k == ast.ASTKind.Attribute: - at: rawptr[ast.Attribute] = rawptr[ast.Attribute](node) + at: ast.Attribute* = ast.Attribute*(node) r12: int = self._replace_expr_await(pool, at.value, temp_name) if r12 == 1: return 1 @@ -1677,7 +1655,7 @@ class AsyncGenMixin(CallGenBase.CallGenBase): return 1 return 0 if k == ast.ASTKind.Subscript: - sb: rawptr[ast.Subscript] = rawptr[ast.Subscript](node) + sb: ast.Subscript* = ast.Subscript*(node) r13: int = self._replace_expr_await(pool, sb.value, temp_name) if r13 == 1: return 1 @@ -1696,12 +1674,12 @@ class AsyncGenMixin(CallGenBase.CallGenBase): # ============================================================ # 条件归一化(i1 直通;其余 icmp ne 0) # ============================================================ - def _normalize_cond(self, builder: rawptr[llvmlite.IRBuilder], - pool: rawptr[memhub.MemBuddy], - cond: rawptr[llvmlite.Value]) -> rawptr[llvmlite.Value]: + def _normalize_cond(self, builder: llvmlite.IRBuilder*, + pool: memhub.MemBuddy*, + cond: llvmlite.Value*) -> llvmlite.Value*: if cond is None: return None - ty: rawptr[llvmlite.LLVMType] = cond.Ty + ty: llvmlite.LLVMType* = cond.Ty is_i1: int = 0 if ty is not None: match ty: @@ -1712,13 +1690,13 @@ class AsyncGenMixin(CallGenBase.CallGenBase): pass if is_i1 != 0: return cond - zero: rawptr[llvmlite.Value] = llvmlite.ConstZero(pool, ty) + zero: llvmlite.Value* = llvmlite.ConstZero(pool, ty) return llvmlite.build_icmp(builder, llvmlite.ICMP_NE, cond, zero) # ============================================================ # 参数名读取(_coro_params 表) # ============================================================ - def _read_param_name(self, trans: rawptr[HT.Translator], + def _read_param_name(self, trans: HT.Translator*, idx: int) -> str: if trans is None or trans._coro_params is None: return None @@ -1729,7 +1707,7 @@ class AsyncGenMixin(CallGenBase.CallGenBase): # ============================================================ # 恢复块定位(state{N},预建数组) # ============================================================ - def _get_state_bb(self, trans: rawptr[HT.Translator], + def _get_state_bb(self, trans: HT.Translator*, state_no: int) -> rawptr[llvmlite.BasicBlock]: if trans is None or trans._coro_state_bbs is None: return None @@ -1740,13 +1718,13 @@ class AsyncGenMixin(CallGenBase.CallGenBase): # 到非法块 → IR 指令链损坏 → RenumberSSA/FunctionPrint 崩溃)。 return rawptr[llvmlite.BasicBlock](trans._coro_state_bbs[state_no]) - def _lookup_coro_frame_by_trans(self, trans: rawptr[HT.Translator]) -> rawptr[llvmlite.LLVMType]: + def _lookup_coro_frame_by_trans(self, trans: HT.Translator*) -> llvmlite.LLVMType*: """取当前 resume 的帧类型:从 _coro_frames 反查(当前 async 名未知时用帧指针类型不可行, 直接返回当前协程注册的帧类型——_handle_nested_await_stmt 需要帧类型做 GEP。""" # 简化:恢复块 GEP 需要帧类型;从 _coro_frame 的 Ty(Ptr(帧))取 Pointee if trans is None or trans._coro_frame is None: return None - ft: rawptr[llvmlite.LLVMType] = trans._coro_frame.Ty + ft: llvmlite.LLVMType* = trans._coro_frame.Ty if ft is None: return None match ft: @@ -1758,38 +1736,38 @@ class AsyncGenMixin(CallGenBase.CallGenBase): # ============================================================ # M3:await coro_sleep(ms) —— wake 槽挂起(coro_run 轮询续跑) # ============================================================ - def _emit_await_sleep(self, builder: rawptr[llvmlite.IRBuilder], - pool: rawptr[memhub.MemBuddy], - mod: rawptr[llvmlite.LLVMModule], - trans: rawptr[HT.Translator], - node: rawptr[ast.AST]) -> rawptr[llvmlite.Value]: + def _emit_await_sleep(self, builder: llvmlite.IRBuilder*, + pool: memhub.MemBuddy*, + mod: llvmlite.LLVMModule*, + trans: HT.Translator*, + node: ast.AST*) -> llvmlite.Value*: """await coro_sleep(ms):wake = GetTickCount64() + ms 存帧 wake 槽, 父挂起(state 分配 + br exit + position 恢复块);coro_run 轮询续跑。""" - i64_ty: rawptr[llvmlite.LLVMType] = llvmlite.Int64(pool) - i32_ty: rawptr[llvmlite.LLVMType] = llvmlite.Int32(pool) + i64_ty: llvmlite.LLVMType* = llvmlite.Int64(pool) + i32_ty: llvmlite.LLVMType* = llvmlite.Int32(pool) if node is None or trans is None or trans._coro_wake_ptr is None: return llvmlite.const_int32(pool, 0) - ms_val: rawptr[llvmlite.Value] = llvmlite.const_int64(pool, 0) + ms_val: llvmlite.Value* = llvmlite.const_int64(pool, 0) aw_s: rawptr[ast.Await] = rawptr[ast.Await](node) if aw_s.value is not None and aw_s.value.kind() == ast.ASTKind.Call: - cl_s: rawptr[ast.Call] = rawptr[ast.Call](aw_s.value) + cl_s: ast.Call* = ast.Call*(aw_s.value) if cl_s.args is not None and len(cl_s.args) > 0: - ms_v: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( + ms_v: llvmlite.Value* = self.Gen.ExprGen.translate_value( builder, pool, mod, cl_s.args.get(0), None, 0, trans) if ms_v is not None: ms_val = ms_v # GetTickCount64() + ms(i64) - now_fn: rawptr[llvmlite.Function] = self.Gen.CallGenBase.find_func_in_module( + now_fn: llvmlite.Function* = self.Gen.CallGenBase.find_func_in_module( mod, "GetTickCount64") if now_fn is None: now_fn = llvmlite.create_declare(pool, mod, "GetTickCount64", i64_ty) if now_fn is None: return llvmlite.const_int32(pool, 0) - now_val: rawptr[llvmlite.Value] = llvmlite.build_call( + now_val: llvmlite.Value* = llvmlite.build_call( builder, "GetTickCount64", None, 0, i64_ty, 0) if now_val is None: return llvmlite.const_int32(pool, 0) - wake_val: rawptr[llvmlite.Value] = llvmlite.build_add( + wake_val: llvmlite.Value* = llvmlite.build_add( builder, now_val, ms_val) if wake_val is None: return llvmlite.const_int32(pool, 0) @@ -1797,7 +1775,7 @@ class AsyncGenMixin(CallGenBase.CallGenBase): # 父挂起:新状态号 + br exit + position 恢复块 new_state_s: int = trans._coro_next_state trans._coro_next_state = new_state_s + 1 - st_v_s: rawptr[llvmlite.Value] = llvmlite.const_int32(pool, new_state_s) + st_v_s: llvmlite.Value* = llvmlite.const_int32(pool, new_state_s) llvmlite.build_store(builder, st_v_s, trans._coro_state_ptr) llvmlite.build_br(builder, trans._coro_exit_bb) resume_bb_s: rawptr[llvmlite.BasicBlock] = self._get_state_bb( @@ -1809,27 +1787,27 @@ class AsyncGenMixin(CallGenBase.CallGenBase): # ============================================================ # M4-M6:协程内 raise(异常类型/值 → 帧 exc 槽) # ============================================================ - def _handle_coro_raise(self, builder: rawptr[llvmlite.IRBuilder], - pool: rawptr[memhub.MemBuddy], - mod: rawptr[llvmlite.LLVMModule], - trans: rawptr[HT.Translator], - stmt: rawptr[ast.AST]): + def _handle_coro_raise(self, builder: llvmlite.IRBuilder*, + pool: memhub.MemBuddy*, + mod: llvmlite.LLVMModule*, + trans: HT.Translator*, + stmt: ast.AST*): """协程内 raise:解析异常类型/值 → 帧 exc 槽(+msg); try 栈非空跳 except 处理器,否则 done=1 + br exit 终止。""" - i32_ty: rawptr[llvmlite.LLVMType] = llvmlite.Int32(pool) - exc_code: rawptr[llvmlite.Value] = llvmlite.const_int32(pool, 1) + i32_ty: llvmlite.LLVMType* = llvmlite.Int32(pool) + exc_code: llvmlite.Value* = llvmlite.const_int32(pool, 1) rz: rawptr[ast.Raise] = rawptr[ast.Raise](stmt) if rz is not None and rz.exc is not None: code: int = self._resolve_raise_code(pool, rz.exc) if code != 0: exc_code = llvmlite.const_int32(pool, code) # M7:异常消息(Exception("msg") 首参) - msg_v: rawptr[llvmlite.Value] = self._resolve_raise_msg( + msg_v: llvmlite.Value* = self._resolve_raise_msg( builder, pool, mod, trans, rz.exc) if msg_v is not None and trans._coro_msg_ptr is not None: llvmlite.build_store(builder, msg_v, trans._coro_msg_ptr) else: - v: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( + v: llvmlite.Value* = self.Gen.ExprGen.translate_value( builder, pool, mod, rz.exc, None, 0, trans) if v is not None: exc_code = v @@ -1840,40 +1818,40 @@ class AsyncGenMixin(CallGenBase.CallGenBase): tbb_r: rawptr[llvmlite.BasicBlock] = rawptr[llvmlite.BasicBlock](trans._coro_try_stack[trans._coro_try_stack_count - 1]) llvmlite.build_br(builder, tbb_r) else: - done_r: rawptr[llvmlite.Value] = llvmlite.const_int32(pool, 1) + done_r: llvmlite.Value* = llvmlite.const_int32(pool, 1) llvmlite.build_store(builder, done_r, trans._coro_done_ptr) llvmlite.build_br(builder, trans._coro_exit_bb) - def _resolve_raise_code(self, pool: rawptr[memhub.MemBuddy], - exc_node: rawptr[ast.AST]) -> int: + def _resolve_raise_code(self, pool: memhub.MemBuddy*, + exc_node: ast.AST*) -> int: """解析 raise 目标的异常码(内置/用户异常类名);非异常类返回 0""" if exc_node is None: return 0 name: str = None if exc_node.kind() == ast.ASTKind.Name: - nm: rawptr[ast.Name] = rawptr[ast.Name](exc_node) + nm: ast.Name* = ast.Name*(exc_node) name = nm.id elif exc_node.kind() == ast.ASTKind.Call: - cl: rawptr[ast.Call] = rawptr[ast.Call](exc_node) + cl: ast.Call* = ast.Call*(exc_node) if cl.func is not None and cl.func.kind() == ast.ASTKind.Name: - nm2: rawptr[ast.Name] = rawptr[ast.Name](cl.func) + nm2: ast.Name* = ast.Name*(cl.func) name = nm2.id elif exc_node.kind() == ast.ASTKind.Attribute: - at: rawptr[ast.Attribute] = rawptr[ast.Attribute](exc_node) + at: ast.Attribute* = ast.Attribute*(exc_node) name = at.attr if name is None: return 0 return self.Gen.ClassGenBase.lookup_exception_code(name) - def _resolve_raise_msg(self, builder: rawptr[llvmlite.IRBuilder], - pool: rawptr[memhub.MemBuddy], - mod: rawptr[llvmlite.LLVMModule], - trans: rawptr[HT.Translator], - exc_node: rawptr[ast.AST]) -> rawptr[llvmlite.Value]: + def _resolve_raise_msg(self, builder: llvmlite.IRBuilder*, + pool: memhub.MemBuddy*, + mod: llvmlite.LLVMModule*, + trans: HT.Translator*, + exc_node: ast.AST*) -> llvmlite.Value*: """取异常消息表达式(Exception("msg") 首参),无则返回 None""" if exc_node is None or exc_node.kind() != ast.ASTKind.Call: return None - cl: rawptr[ast.Call] = rawptr[ast.Call](exc_node) + cl: ast.Call* = ast.Call*(exc_node) if cl.args is None or len(cl.args) < 1: return None return self.Gen.ExprGen.translate_value( @@ -1882,16 +1860,16 @@ class AsyncGenMixin(CallGenBase.CallGenBase): # ============================================================ # M5-M6:协程内 try/except(多 except 链式匹配 + 类型码 + as e 绑定) # ============================================================ - def _handle_coro_try(self, trans: rawptr[HT.Translator], - builder: rawptr[llvmlite.IRBuilder], - pool: rawptr[memhub.MemBuddy], - mod: rawptr[llvmlite.LLVMModule], - stmt: rawptr[ast.AST]): + def _handle_coro_try(self, trans: HT.Translator*, + builder: llvmlite.IRBuilder*, + pool: memhub.MemBuddy*, + mod: llvmlite.LLVMModule*, + stmt: ast.AST*): """协程内 try/except:raise/await 传播异常在 try 栈内改跳 except 处理器; 多 except 按声明序匹配(含子类码集合),Exception/裸 except 捕获所有; 全不匹配重新传播(done=1 + br exit)。""" - i32_ty: rawptr[llvmlite.LLVMType] = llvmlite.Int32(pool) - tr: rawptr[ast.Try] = rawptr[ast.Try](stmt) + i32_ty: llvmlite.LLVMType* = llvmlite.Int32(pool) + tr: ast.Try* = ast.Try*(stmt) if tr is None: return nhandlers: int = 0 @@ -1903,7 +1881,7 @@ class AsyncGenMixin(CallGenBase.CallGenBase): viperlib.snprintf(err_t, 256, "[coro-M6] 协程内 try 需要 except 子句") self.Gen.TypeGenErr.fatal_error(stmt, err_t, "SyntaxError") return - func: rawptr[llvmlite.Function] = trans._cur_func + func: llvmlite.Function* = trans._cur_func except_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block( pool, func, "coro.try_except") merge_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block( @@ -1922,11 +1900,11 @@ class AsyncGenMixin(CallGenBase.CallGenBase): trans._coro_try_stack_count = trans._coro_try_stack_count - 1 # ---- 异常分发:exc 码依次匹配各 except ---- llvmlite.position_at_end(builder, except_bb) - exc_val: rawptr[llvmlite.Value] = llvmlite.build_load( + exc_val: llvmlite.Value* = llvmlite.build_load( builder, i32_ty, trans._coro_exc_ptr) # 预建 check/handler/unmatched 块 - check_bbs: sizet | t.CPtr = pool.alloc((nhandlers + 1) * 8) - handler_bbs: sizet | t.CPtr = pool.alloc(nhandlers * 8) + check_bbs: sizet* = pool.alloc((nhandlers + 1) * 8) + handler_bbs: sizet* = pool.alloc(nhandlers * 8) if check_bbs is None or handler_bbs is None: return check_bbs[0] = sizet(except_bb) @@ -1951,14 +1929,14 @@ class AsyncGenMixin(CallGenBase.CallGenBase): codes_buf: int | t.CPtr = pool.alloc(256) # 每个 handler:check 链 for hi in range(nhandlers): - h_node: rawptr[ast.AST] = tr.handlers.get(hi) + h_node: ast.AST* = tr.handlers.get(hi) check_bb: rawptr[llvmlite.BasicBlock] = ( rawptr[llvmlite.BasicBlock])(check_bbs[hi]) llvmlite.position_at_end(builder, check_bb) catch_all: int = 0 ncodes: int = 0 if h_node is not None: - hd: rawptr[ast.ExceptHandler] = rawptr[ast.ExceptHandler](h_node) + hd: ast.ExceptHandler* = ast.ExceptHandler*(h_node) if hd.type is None: catch_all = 1 else: @@ -1978,10 +1956,10 @@ class AsyncGenMixin(CallGenBase.CallGenBase): if catch_all != 0: llvmlite.build_br(builder, handler_bb) else: - match_cond: rawptr[llvmlite.Value] = None + match_cond: llvmlite.Value* = None ci: int = 0 for ci in range(ncodes): - eq_v: rawptr[llvmlite.Value] = llvmlite.build_icmp( + eq_v: llvmlite.Value* = llvmlite.build_icmp( builder, llvmlite.ICMP_EQ, exc_val, llvmlite.const_int32(pool, codes_buf[ci])) if match_cond is None: @@ -1994,58 +1972,58 @@ class AsyncGenMixin(CallGenBase.CallGenBase): llvmlite.build_cond_br(builder, match_cond, handler_bb, next_check) # 未匹配:异常继续传播(重新终止协程) llvmlite.position_at_end(builder, unmatched_bb) - done_u: rawptr[llvmlite.Value] = llvmlite.const_int32(pool, 1) + done_u: llvmlite.Value* = llvmlite.const_int32(pool, 1) llvmlite.build_store(builder, done_u, trans._coro_done_ptr) llvmlite.build_br(builder, trans._coro_exit_bb) # ---- 各 except handler ---- for hi in range(nhandlers): - h_node2: rawptr[ast.AST] = tr.handlers.get(hi) + h_node2: ast.AST* = tr.handlers.get(hi) handler_bb2: rawptr[llvmlite.BasicBlock] = ( rawptr[llvmlite.BasicBlock])(handler_bbs[hi]) llvmlite.position_at_end(builder, handler_bb2) if h_node2 is not None: - hd2: rawptr[ast.ExceptHandler] = rawptr[ast.ExceptHandler](h_node2) + hd2: ast.ExceptHandler* = ast.ExceptHandler*(h_node2) # as e:异常码绑定 e 槽(e 是局部槽,_collect_local_names 收集) if hd2.name is not None and trans._coro_exc_ptr is not None: - e_slot: rawptr[llvmlite.Value] = self.Gen.VarGen.lookup_var( + e_slot: llvmlite.Value* = self.Gen.VarGen.lookup_var( trans.SymTab, hd2.name) if e_slot is not None: - hv: rawptr[llvmlite.Value] = llvmlite.build_load( + hv: llvmlite.Value* = llvmlite.build_load( builder, i32_ty, trans._coro_exc_ptr) llvmlite.build_store(builder, hv, e_slot) # 捕获后清帧 exc - z_clr: rawptr[llvmlite.Value] = llvmlite.const_int32(pool, 0) + z_clr: llvmlite.Value* = llvmlite.const_int32(pool, 0) llvmlite.build_store(builder, z_clr, trans._coro_exc_ptr) self._handle_segment(trans, builder, pool, mod, h_node2.children) if llvmlite.builder_cur_block_is_terminated(builder) == 0: llvmlite.build_br(builder, merge_bb) llvmlite.position_at_end(builder, merge_bb) - def _exception_type_name(self, pool: rawptr[memhub.MemBuddy], - type_node: rawptr[ast.AST]) -> str: + def _exception_type_name(self, pool: memhub.MemBuddy*, + type_node: ast.AST*) -> str: """取 except 类型名(Name/Attribute),未命中返回 None""" if type_node is None: return None if type_node.kind() == ast.ASTKind.Name: - nm: rawptr[ast.Name] = rawptr[ast.Name](type_node) + nm: ast.Name* = ast.Name*(type_node) return nm.id if type_node.kind() == ast.ASTKind.Attribute: - at: rawptr[ast.Attribute] = rawptr[ast.Attribute](type_node) + at: ast.Attribute* = ast.Attribute*(type_node) return at.attr return None # ============================================================ # M7:协程内 try/finally(无 except) # ============================================================ - def _handle_coro_try_finally(self, trans: rawptr[HT.Translator], - builder: rawptr[llvmlite.IRBuilder], - pool: rawptr[memhub.MemBuddy], - mod: rawptr[llvmlite.LLVMModule], - stmt: rawptr[ast.AST]): + def _handle_coro_try_finally(self, trans: HT.Translator*, + builder: llvmlite.IRBuilder*, + pool: memhub.MemBuddy*, + mod: llvmlite.LLVMModule*, + stmt: ast.AST*): """协程内 try/finally:正常/异常路径都执行 fbody; 异常时 finally 后重新传播(done=1 + br exit);finally 内不支持 await。""" - i32_ty: rawptr[llvmlite.LLVMType] = llvmlite.Int32(pool) - tr: rawptr[ast.Try] = rawptr[ast.Try](stmt) + i32_ty: llvmlite.LLVMType* = llvmlite.Int32(pool) + tr: ast.Try* = ast.Try*(stmt) if tr is None: return if tr.finalbody is not None and self._stmts_deep_await(tr.finalbody) != 0: @@ -2054,7 +2032,7 @@ class AsyncGenMixin(CallGenBase.CallGenBase): viperlib.snprintf(err_f, 256, "[coro-M7] finally 内暂不支持 await") self.Gen.TypeGenErr.fatal_error(stmt, err_f, "SyntaxError") return - func: rawptr[llvmlite.Function] = trans._cur_func + func: llvmlite.Function* = trans._cur_func fin_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block( pool, func, "coro.fin") fin_exc_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block( @@ -2074,7 +2052,7 @@ class AsyncGenMixin(CallGenBase.CallGenBase): trans._coro_try_stack_count = trans._coro_try_stack_count - 1 # fin_bb:记录异常标志 + 执行 fbody llvmlite.position_at_end(builder, fin_bb) - was_exc: rawptr[llvmlite.Value] = llvmlite.build_icmp( + was_exc: llvmlite.Value* = llvmlite.build_icmp( builder, llvmlite.ICMP_NE, llvmlite.build_load(builder, i32_ty, trans._coro_exc_ptr), llvmlite.const_int32(pool, 0)) @@ -2083,7 +2061,7 @@ class AsyncGenMixin(CallGenBase.CallGenBase): llvmlite.build_cond_br(builder, was_exc, fin_exc_bb, merge_bb) # fin_exc:finally 后异常继续传播 llvmlite.position_at_end(builder, fin_exc_bb) - done_f: rawptr[llvmlite.Value] = llvmlite.const_int32(pool, 1) + done_f: llvmlite.Value* = llvmlite.const_int32(pool, 1) llvmlite.build_store(builder, done_f, trans._coro_done_ptr) llvmlite.build_br(builder, trans._coro_exit_bb) llvmlite.position_at_end(builder, merge_bb) @@ -2091,14 +2069,14 @@ class AsyncGenMixin(CallGenBase.CallGenBase): # ============================================================ # M3:协程内 range-For(含 await)变换为 While(__f_idx/__f_len 帧槽) # ============================================================ - def _handle_coro_for(self, trans: rawptr[HT.Translator], - builder: rawptr[llvmlite.IRBuilder], - pool: rawptr[memhub.MemBuddy], - mod: rawptr[llvmlite.LLVMModule], - stmt: rawptr[ast.AST]): + def _handle_coro_for(self, trans: HT.Translator*, + builder: llvmlite.IRBuilder*, + pool: memhub.MemBuddy*, + mod: llvmlite.LLVMModule*, + stmt: ast.AST*): """range-For(含 await):__f_idx_N = start; __f_len_N = end; while __f_idx_N < __f_len_N: target = __f_idx_N; ; __f_idx_N += 1""" - i32_ty: rawptr[llvmlite.LLVMType] = llvmlite.Int32(pool) + i32_ty: llvmlite.LLVMType* = llvmlite.Int32(pool) if self._is_range_for(stmt) == 0: err_g: str = pool.alloc(256) if err_g is not None: @@ -2110,18 +2088,18 @@ class AsyncGenMixin(CallGenBase.CallGenBase): trans._coro_for_counter = k + 1 idx_idx: int = trans._coro_extra_base + trans._coro_for_slots[k] len_idx: int = idx_idx + 1 - idx_slot: rawptr[llvmlite.Value] = llvmlite.build_gep_struct( + idx_slot: llvmlite.Value* = llvmlite.build_gep_struct( builder, self._lookup_coro_frame_by_trans(trans), i32_ty, trans._coro_frame, idx_idx) - len_slot: rawptr[llvmlite.Value] = llvmlite.build_gep_struct( + len_slot: llvmlite.Value* = llvmlite.build_gep_struct( builder, self._lookup_coro_frame_by_trans(trans), i32_ty, trans._coro_frame, len_idx) if idx_slot is None or len_slot is None: return # start/end(range 1/2 参数) - cl: rawptr[ast.Call] = rawptr[ast.Call](fn.iter) - start_val: rawptr[llvmlite.Value] = None - end_val: rawptr[llvmlite.Value] = None + cl: ast.Call* = ast.Call*(fn.iter) + start_val: llvmlite.Value* = None + end_val: llvmlite.Value* = None nargs: int = len(cl.args) if nargs == 1: start_val = llvmlite.const_int32(pool, 0) @@ -2139,7 +2117,7 @@ class AsyncGenMixin(CallGenBase.CallGenBase): llvmlite.build_store(builder, start_val, idx_slot) llvmlite.build_store(builder, end_val, len_slot) # 循环结构 - func: rawptr[llvmlite.Function] = trans._cur_func + func: llvmlite.Function* = trans._cur_func cond_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block( pool, func, "coro.fcond") body_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block( @@ -2155,29 +2133,29 @@ class AsyncGenMixin(CallGenBase.CallGenBase): llvmlite.build_br(builder, cond_bb) # 条件块 llvmlite.position_at_end(builder, cond_bb) - idx_v: rawptr[llvmlite.Value] = llvmlite.build_load( + idx_v: llvmlite.Value* = llvmlite.build_load( builder, i32_ty, idx_slot) - len_v: rawptr[llvmlite.Value] = llvmlite.build_load( + len_v: llvmlite.Value* = llvmlite.build_load( builder, i32_ty, len_slot) - cmp_v: rawptr[llvmlite.Value] = llvmlite.build_icmp( + cmp_v: llvmlite.Value* = llvmlite.build_icmp( builder, llvmlite.ICMP_SLT, idx_v, len_v) llvmlite.build_cond_br(builder, cmp_v, body_bb, after_bb) # 循环体:target = idx; ; idx += 1 llvmlite.position_at_end(builder, body_bb) if fn.target is not None and fn.target.kind() == ast.ASTKind.Name: - tn: rawptr[ast.Name] = rawptr[ast.Name](fn.target) - tgt_slot: rawptr[llvmlite.Value] = self.Gen.VarGen.lookup_var( + tn: ast.Name* = ast.Name*(fn.target) + tgt_slot: llvmlite.Value* = self.Gen.VarGen.lookup_var( trans.SymTab, tn.id) if tgt_slot is not None: - idx_v2: rawptr[llvmlite.Value] = llvmlite.build_load( + idx_v2: llvmlite.Value* = llvmlite.build_load( builder, i32_ty, idx_slot) llvmlite.build_store(builder, idx_v2, tgt_slot) self._handle_segment(trans, builder, pool, mod, stmt.children) if llvmlite.builder_cur_block_is_terminated(builder) == 0: - idx_v3: rawptr[llvmlite.Value] = llvmlite.build_load( + idx_v3: llvmlite.Value* = llvmlite.build_load( builder, i32_ty, idx_slot) - one_v: rawptr[llvmlite.Value] = llvmlite.const_int32(pool, 1) - nxt_v: rawptr[llvmlite.Value] = llvmlite.build_add(builder, idx_v3, one_v) + one_v: llvmlite.Value* = llvmlite.const_int32(pool, 1) + nxt_v: llvmlite.Value* = llvmlite.build_add(builder, idx_v3, one_v) llvmlite.build_store(builder, nxt_v, idx_slot) llvmlite.build_br(builder, cond_bb) trans._coro_break_bb = prev_break @@ -2187,137 +2165,137 @@ class AsyncGenMixin(CallGenBase.CallGenBase): # ============================================================ # M3/M4/M7:coro.coro_destroy / coro_exception / coro_exception_msg / coro_gather # ============================================================ - def translate_coro_destroy(self, builder: rawptr[llvmlite.IRBuilder], - pool: rawptr[memhub.MemBuddy], - mod: rawptr[llvmlite.LLVMModule], - cl: rawptr[ast.Call], - trans: rawptr[HT.Translator]) -> rawptr[llvmlite.Value]: + def translate_coro_destroy(self, builder: llvmlite.IRBuilder*, + pool: memhub.MemBuddy*, + mod: llvmlite.LLVMModule*, + cl: ast.Call*, + trans: HT.Translator*) -> llvmlite.Value*: """coro.coro_destroy(帧):帧回池(free-list,帧首 8 字节存 next)""" - i32_ty: rawptr[llvmlite.LLVMType] = llvmlite.Int32(pool) - i64_ty: rawptr[llvmlite.LLVMType] = llvmlite.Int64(pool) + i32_ty: llvmlite.LLVMType* = llvmlite.Int32(pool) + i64_ty: llvmlite.LLVMType* = llvmlite.Int64(pool) if cl is None or trans is None or cl.args is None or len(cl.args) < 1: return llvmlite.const_int32(pool, 0) async_name: str = self._var_to_async(trans, cl.args.get(0)) if async_name is None: return llvmlite.const_int32(pool, 0) - frame_ty: rawptr[llvmlite.LLVMType] = self._lookup_coro_frame( + frame_ty: llvmlite.LLVMType* = self._lookup_coro_frame( trans, async_name) if frame_ty is None: return llvmlite.const_int32(pool, 0) - frame_ptr_ty: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, frame_ty) - frame_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( + frame_ptr_ty: llvmlite.LLVMType* = llvmlite.Ptr(pool, frame_ty) + frame_val: llvmlite.Value* = self.Gen.ExprGen.translate_value( builder, pool, mod, cl.args.get(0), None, 0, trans) if frame_val is None: return llvmlite.const_int32(pool, 0) - frame_ptr: rawptr[llvmlite.Value] = llvmlite.build_bitcast( + frame_ptr: llvmlite.Value* = llvmlite.build_bitcast( builder, frame_val, frame_ptr_ty) if frame_ptr is None: return llvmlite.const_int32(pool, 0) # 回池:帧首 8 字节存旧池头;池头 = 本帧(i64) - pool_gv: rawptr[llvmlite.GlobalVariable] = self._get_coro_pool( + pool_gv: llvmlite.GlobalVariable* = self._get_coro_pool( pool, mod, trans, async_name) # GlobalVariable 非 Value 子类:构造 Value 视图(Ty=Ptr(i64), Name="@coro_pool_") - i64_ptr_ty: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, i64_ty) + i64_ptr_ty: llvmlite.LLVMType* = llvmlite.Ptr(pool, i64_ty) pool_ref_name: str = pool.alloc(96) if pool_ref_name is not None: viperlib.snprintf(pool_ref_name, 96, "@coro_pool_%s", async_name) - pool_ref: rawptr[llvmlite.Value] = llvmlite.SSAValue( + pool_ref: llvmlite.Value* = llvmlite.SSAValue( pool, i64_ptr_ty, pool_ref_name) - pool_head: rawptr[llvmlite.Value] = llvmlite.build_load( + pool_head: llvmlite.Value* = llvmlite.build_load( builder, i64_ty, pool_ref) - node_next: rawptr[llvmlite.Value] = llvmlite.build_bitcast( + node_next: llvmlite.Value* = llvmlite.build_bitcast( builder, frame_ptr, i64_ptr_ty) llvmlite.build_store(builder, pool_head, node_next) - frame_i64: rawptr[llvmlite.Value] = llvmlite.build_ptrtoint( + frame_i64: llvmlite.Value* = llvmlite.build_ptrtoint( builder, frame_ptr, i64_ty) llvmlite.build_store(builder, frame_i64, pool_ref) return llvmlite.const_int32(pool, 0) - def translate_coro_exception(self, builder: rawptr[llvmlite.IRBuilder], - pool: rawptr[memhub.MemBuddy], - mod: rawptr[llvmlite.LLVMModule], - cl: rawptr[ast.Call], - trans: rawptr[HT.Translator]) -> rawptr[llvmlite.Value]: + def translate_coro_exception(self, builder: llvmlite.IRBuilder*, + pool: memhub.MemBuddy*, + mod: llvmlite.LLVMModule*, + cl: ast.Call*, + trans: HT.Translator*) -> llvmlite.Value*: """coro.coro_exception(帧):返回帧 exc 槽(异常码,0=无异常)""" - i32_ty: rawptr[llvmlite.LLVMType] = llvmlite.Int32(pool) + i32_ty: llvmlite.LLVMType* = llvmlite.Int32(pool) if cl is None or trans is None or cl.args is None or len(cl.args) < 1: return llvmlite.const_int32(pool, 0) async_name: str = self._var_to_async(trans, cl.args.get(0)) if async_name is None: return llvmlite.const_int32(pool, 0) - frame_ty: rawptr[llvmlite.LLVMType] = self._lookup_coro_frame( + frame_ty: llvmlite.LLVMType* = self._lookup_coro_frame( trans, async_name) if frame_ty is None: return llvmlite.const_int32(pool, 0) - frame_ptr_ty: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, frame_ty) - frame_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( + frame_ptr_ty: llvmlite.LLVMType* = llvmlite.Ptr(pool, frame_ty) + frame_val: llvmlite.Value* = self.Gen.ExprGen.translate_value( builder, pool, mod, cl.args.get(0), None, 0, trans) if frame_val is None: return llvmlite.const_int32(pool, 0) - frame_ptr: rawptr[llvmlite.Value] = llvmlite.build_bitcast( + frame_ptr: llvmlite.Value* = llvmlite.build_bitcast( builder, frame_val, frame_ptr_ty) if frame_ptr is None: return llvmlite.const_int32(pool, 0) - exc_ptr: rawptr[llvmlite.Value] = llvmlite.build_gep_struct( + exc_ptr: llvmlite.Value* = llvmlite.build_gep_struct( builder, frame_ty, i32_ty, frame_ptr, 3) return llvmlite.build_load(builder, i32_ty, exc_ptr) - def translate_coro_exception_msg(self, builder: rawptr[llvmlite.IRBuilder], - pool: rawptr[memhub.MemBuddy], - mod: rawptr[llvmlite.LLVMModule], - cl: rawptr[ast.Call], - trans: rawptr[HT.Translator]) -> rawptr[llvmlite.Value]: + def translate_coro_exception_msg(self, builder: llvmlite.IRBuilder*, + pool: memhub.MemBuddy*, + mod: llvmlite.LLVMModule*, + cl: ast.Call*, + trans: HT.Translator*) -> llvmlite.Value*: """coro.coro_exception_msg(帧):返回帧 msg 槽(异常消息指针,null=无)""" - i8_ptr_ty: rawptr[llvmlite.LLVMType] = llvmlite.Ptr( + i8_ptr_ty: llvmlite.LLVMType* = llvmlite.Ptr( pool, llvmlite.Int8(pool)) if cl is None or trans is None or cl.args is None or len(cl.args) < 1: return llvmlite.ConstNull(pool, i8_ptr_ty, "null") async_name: str = self._var_to_async(trans, cl.args.get(0)) if async_name is None: return llvmlite.ConstNull(pool, i8_ptr_ty, "null") - frame_ty: rawptr[llvmlite.LLVMType] = self._lookup_coro_frame( + frame_ty: llvmlite.LLVMType* = self._lookup_coro_frame( trans, async_name) if frame_ty is None: return llvmlite.ConstNull(pool, i8_ptr_ty, "null") - frame_ptr_ty: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, frame_ty) - frame_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( + frame_ptr_ty: llvmlite.LLVMType* = llvmlite.Ptr(pool, frame_ty) + frame_val: llvmlite.Value* = self.Gen.ExprGen.translate_value( builder, pool, mod, cl.args.get(0), None, 0, trans) if frame_val is None: return llvmlite.ConstNull(pool, i8_ptr_ty, "null") - frame_ptr: rawptr[llvmlite.Value] = llvmlite.build_bitcast( + frame_ptr: llvmlite.Value* = llvmlite.build_bitcast( builder, frame_val, frame_ptr_ty) if frame_ptr is None: return llvmlite.ConstNull(pool, i8_ptr_ty, "null") - msg_ptr: rawptr[llvmlite.Value] = llvmlite.build_gep_struct( + msg_ptr: llvmlite.Value* = llvmlite.build_gep_struct( builder, frame_ty, i8_ptr_ty, frame_ptr, 4) return llvmlite.build_load(builder, i8_ptr_ty, msg_ptr) - def translate_coro_gather(self, builder: rawptr[llvmlite.IRBuilder], - pool: rawptr[memhub.MemBuddy], - mod: rawptr[llvmlite.LLVMModule], - cl: rawptr[ast.Call], - trans: rawptr[HT.Translator]) -> rawptr[llvmlite.Value]: + def translate_coro_gather(self, builder: llvmlite.IRBuilder*, + pool: memhub.MemBuddy*, + mod: llvmlite.LLVMModule*, + cl: ast.Call*, + trans: HT.Translator*) -> llvmlite.Value*: """coro.coro_gather(帧...):并发推进全部协程到完成,返回完成数(M4 纯 resume 循环)""" - i32_ty: rawptr[llvmlite.LLVMType] = llvmlite.Int32(pool) + i32_ty: llvmlite.LLVMType* = llvmlite.Int32(pool) if cl is None or trans is None or cl.args is None: return llvmlite.const_int32(pool, 0) nb: sizet = len(cl.args) j: sizet = 0 for j in range(nb): - arg0: rawptr[ast.AST] = cl.args.get(j) + arg0: ast.AST* = cl.args.get(j) async_name: str = self._var_to_async(trans, arg0) if async_name is None: continue - frame_ty: rawptr[llvmlite.LLVMType] = self._lookup_coro_frame( + frame_ty: llvmlite.LLVMType* = self._lookup_coro_frame( trans, async_name) if frame_ty is None: continue - frame_ptr_ty: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, frame_ty) - frame_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( + frame_ptr_ty: llvmlite.LLVMType* = llvmlite.Ptr(pool, frame_ty) + frame_val: llvmlite.Value* = self.Gen.ExprGen.translate_value( builder, pool, mod, arg0, None, 0, trans) if frame_val is None: continue - frame_ptr: rawptr[llvmlite.Value] = llvmlite.build_bitcast( + frame_ptr: llvmlite.Value* = llvmlite.build_bitcast( builder, frame_val, frame_ptr_ty) if frame_ptr is None: continue @@ -2328,7 +2306,7 @@ class AsyncGenMixin(CallGenBase.CallGenBase): trans, rn_buf, 0) if self.Gen.CallGenBase.find_func_in_module(mod, resume_mangled) is None: continue - func: rawptr[llvmlite.Function] = trans._cur_func + func: llvmlite.Function* = trans._cur_func loop_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block( pool, func, "gather.loop") after_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block( @@ -2338,20 +2316,20 @@ class AsyncGenMixin(CallGenBase.CallGenBase): llvmlite.build_br(builder, loop_bb) llvmlite.position_at_end(builder, loop_bb) frame_ptr.Next = None - status: rawptr[llvmlite.Value] = llvmlite.build_call( + status: llvmlite.Value* = llvmlite.build_call( builder, resume_mangled, frame_ptr, 1, i32_ty, 0) - done_cond: rawptr[llvmlite.Value] = llvmlite.build_icmp( + done_cond: llvmlite.Value* = llvmlite.build_icmp( builder, llvmlite.ICMP_NE, status, llvmlite.const_int32(pool, 0)) llvmlite.build_cond_br(builder, done_cond, after_bb, loop_bb) llvmlite.position_at_end(builder, after_bb) return llvmlite.const_int32(pool, 0) - def _var_to_async(self, trans: rawptr[HT.Translator], - arg0: rawptr[ast.AST]) -> str: + def _var_to_async(self, trans: HT.Translator*, + arg0: ast.AST*) -> str: """变量节点 → async 函数名(_coro_var_async 反查),未命中返回 None""" if trans is None or arg0 is None or arg0.kind() != ast.ASTKind.Name: return None - nm: rawptr[ast.Name] = rawptr[ast.Name](arg0) + nm: ast.Name* = ast.Name*(arg0) if nm.id is None: return None return self._lookup_coro_var(trans, nm.id) @@ -2359,12 +2337,12 @@ class AsyncGenMixin(CallGenBase.CallGenBase): # ============================================================ # await 表达式翻译(顶层段尾 / translate_value Await 分支共用) # ============================================================ - def _emit_await(self, builder: rawptr[llvmlite.IRBuilder], - pool: rawptr[memhub.MemBuddy], - mod: rawptr[llvmlite.LLVMModule], - trans: rawptr[HT.Translator], - node: rawptr[ast.AST], - call_name: str) -> rawptr[llvmlite.Value]: + def _emit_await(self, builder: llvmlite.IRBuilder*, + pool: memhub.MemBuddy*, + mod: llvmlite.LLVMModule*, + trans: HT.Translator*, + node: ast.AST*, + call_name: str) -> llvmlite.Value*: """await async_fn(args...) 内联翻译(M2 带参数): 1. 求值调用参数(表达式逐个翻译,i32) 2. create_(args...) 创建子帧 @@ -2373,19 +2351,19 @@ class AsyncGenMixin(CallGenBase.CallGenBase): 5. 父挂起:store state=新状态号 + br exit;恢复块 state{new_state} 立即 position(预建 case 块),后续语句在恢复块继续翻译 返回子协程 ret 值(i32)。注意 node 是 Await,须先转 ast.Await 再取 value。""" - i32_ty: rawptr[llvmlite.LLVMType] = llvmlite.Int32(pool) - i8_ptr_ty_a: rawptr[llvmlite.LLVMType] = llvmlite.Ptr( + i32_ty: llvmlite.LLVMType* = llvmlite.Int32(pool) + i8_ptr_ty_a: llvmlite.LLVMType* = llvmlite.Ptr( pool, llvmlite.Int8(pool)) if node is None or call_name is None or trans is None: return llvmlite.const_int32(pool, 0) # M3:await coro_sleep(ms) —— 挂起到 wake 时刻(帧 wake 槽) if string.strcmp(call_name, "coro_sleep") == 0: return self._emit_await_sleep(builder, pool, mod, trans, node) - child_frame_ty: rawptr[llvmlite.LLVMType] = self._lookup_coro_frame( + child_frame_ty: llvmlite.LLVMType* = self._lookup_coro_frame( trans, call_name) if child_frame_ty is None: return llvmlite.const_int32(pool, 0) - child_ptr_ty: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, child_frame_ty) + child_ptr_ty: llvmlite.LLVMType* = llvmlite.Ptr(pool, child_frame_ty) cc_buf: str = pool.alloc(64) if cc_buf is not None: @@ -2403,17 +2381,17 @@ class AsyncGenMixin(CallGenBase.CallGenBase): return llvmlite.const_int32(pool, 0) # M2:子协程调用参数(await fn(a, b) → create_fn(a, b)) - args_head: rawptr[llvmlite.Value] = None - args_tail: rawptr[llvmlite.Value] = None + args_head: llvmlite.Value* = None + args_tail: llvmlite.Value* = None args_count: int = 0 aw_n: rawptr[ast.Await] = rawptr[ast.Await](node) if aw_n.value is not None and aw_n.value.kind() == ast.ASTKind.Call: - cl_a: rawptr[ast.Call] = rawptr[ast.Call](aw_n.value) + cl_a: ast.Call* = ast.Call*(aw_n.value) if cl_a.args is not None: nb: sizet = len(cl_a.args) j: sizet = 0 for j in range(nb): - av: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( + av: llvmlite.Value* = self.Gen.ExprGen.translate_value( builder, pool, mod, cl_a.args.get(j), None, 0, trans) if av is None: av = llvmlite.const_int32(pool, 0) @@ -2427,30 +2405,30 @@ class AsyncGenMixin(CallGenBase.CallGenBase): args_count = args_count + 1 # 子协程 create(M2 带参数)+ resume - child: rawptr[llvmlite.Value] = llvmlite.build_call( + child: llvmlite.Value* = llvmlite.build_call( builder, create_mangled, args_head, args_count, child_ptr_ty, 0) if child is None: return llvmlite.const_int32(pool, 0) child.Next = None llvmlite.build_call(builder, resume_mangled, child, 1, i32_ty, 0) # 子帧 ret 槽 GEP [0,2] load - child_ret_ptr: rawptr[llvmlite.Value] = llvmlite.build_gep_struct( + child_ret_ptr: llvmlite.Value* = llvmlite.build_gep_struct( builder, child_frame_ty, i32_ty, child, 2) - child_ret: rawptr[llvmlite.Value] = llvmlite.build_load( + child_ret: llvmlite.Value* = llvmlite.build_load( builder, i32_ty, child_ret_ptr) # M4:子帧异常传播——子帧 exc != 0 → 父 exc/msg 槽 + 跳 try except 或终止 - child_exc_ptr: rawptr[llvmlite.Value] = llvmlite.build_gep_struct( + child_exc_ptr: llvmlite.Value* = llvmlite.build_gep_struct( builder, child_frame_ty, i32_ty, child, 3) - child_exc: rawptr[llvmlite.Value] = llvmlite.build_load( + child_exc: llvmlite.Value* = llvmlite.build_load( builder, i32_ty, child_exc_ptr) - zero32_x: rawptr[llvmlite.Value] = llvmlite.const_int32(pool, 0) + zero32_x: llvmlite.Value* = llvmlite.const_int32(pool, 0) exc_ok_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block( pool, trans._cur_func, "coro.ok") exc_bad_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block( pool, trans._cur_func, "coro.exc") if exc_ok_bb is None or exc_bad_bb is None: return llvmlite.const_int32(pool, 0) - exc_cond: rawptr[llvmlite.Value] = llvmlite.build_icmp( + exc_cond: llvmlite.Value* = llvmlite.build_icmp( builder, llvmlite.ICMP_EQ, child_exc, zero32_x) llvmlite.build_cond_br(builder, exc_cond, exc_ok_bb, exc_bad_bb) # exc 路径:父帧 exc/msg 槽 + 跳 try 或终止 @@ -2458,27 +2436,27 @@ class AsyncGenMixin(CallGenBase.CallGenBase): if trans._coro_exc_ptr is not None: llvmlite.build_store(builder, child_exc, trans._coro_exc_ptr) if trans._coro_msg_ptr is not None: - child_msg_ptr: rawptr[llvmlite.Value] = llvmlite.build_gep_struct( + child_msg_ptr: llvmlite.Value* = llvmlite.build_gep_struct( builder, child_frame_ty, i8_ptr_ty_a, child, 4) - child_msg: rawptr[llvmlite.Value] = llvmlite.build_load( + child_msg: llvmlite.Value* = llvmlite.build_load( builder, i8_ptr_ty_a, child_msg_ptr) llvmlite.build_store(builder, child_msg, trans._coro_msg_ptr) if trans._coro_try_stack_count > 0: tbb: rawptr[llvmlite.BasicBlock] = rawptr[llvmlite.BasicBlock](trans._coro_try_stack[trans._coro_try_stack_count - 1]) llvmlite.build_br(builder, tbb) else: - done_x: rawptr[llvmlite.Value] = llvmlite.const_int32(pool, 1) + done_x: llvmlite.Value* = llvmlite.const_int32(pool, 1) llvmlite.build_store(builder, done_x, trans._coro_done_ptr) llvmlite.build_br(builder, trans._coro_exit_bb) # 正常路径:存父帧 await 槽(若非 None)+ 挂起 llvmlite.position_at_end(builder, exc_ok_bb) - slot: rawptr[llvmlite.Value] = trans._coro_await_slot + slot: llvmlite.Value* = trans._coro_await_slot if slot is not None: llvmlite.build_store(builder, child_ret, slot) # 父挂起:新状态号(与预扫描 DFS 序一致) new_state: int = trans._coro_next_state trans._coro_next_state = new_state + 1 - st_v: rawptr[llvmlite.Value] = llvmlite.const_int32(pool, new_state) + st_v: llvmlite.Value* = llvmlite.const_int32(pool, new_state) llvmlite.build_store(builder, st_v, trans._coro_state_ptr) llvmlite.build_br(builder, trans._coro_exit_bb) # 恢复块 state{new_state}:立即 position(预建 case 块,后续翻译在此继续) @@ -2491,48 +2469,48 @@ class AsyncGenMixin(CallGenBase.CallGenBase): # ============================================================ # coro.coro_run(帧) 内联翻译 # ============================================================ - def translate_coro_run(self, builder: rawptr[llvmlite.IRBuilder], - pool: rawptr[memhub.MemBuddy], - mod: rawptr[llvmlite.LLVMModule], - cl: rawptr[ast.Call], - trans: rawptr[HT.Translator]) -> rawptr[llvmlite.Value]: + def translate_coro_run(self, builder: llvmlite.IRBuilder*, + pool: memhub.MemBuddy*, + mod: llvmlite.LLVMModule*, + cl: ast.Call*, + trans: HT.Translator*) -> llvmlite.Value*: """coro.coro_run(frame) 内联翻译: 参数是 Name 变量 → 经 _coro_var_async 反查 async 名 → _coro_frames 取帧类型 → bitcast 变量值到 Ptr(帧) → 循环 resume_(frame) 直到 done != 0 → GEP [0,2] load ret 返回。 M1 无 coro_sleep 轮询(无 wake 槽),纯忙等直到协程完成。 """ - i32_ty: rawptr[llvmlite.LLVMType] = llvmlite.Int32(pool) + i32_ty: llvmlite.LLVMType* = llvmlite.Int32(pool) if cl is None or trans is None: return llvmlite.const_int32(pool, 0) if cl.args is None or len(cl.args) < 1: return llvmlite.const_int32(pool, 0) - arg0: rawptr[ast.AST] = cl.args.get(0) + arg0: ast.AST* = cl.args.get(0) if arg0 is None or arg0.kind() != ast.ASTKind.Name: return llvmlite.const_int32(pool, 0) - nm: rawptr[ast.Name] = rawptr[ast.Name](arg0) + nm: ast.Name* = ast.Name*(arg0) if nm.id is None: return llvmlite.const_int32(pool, 0) async_name: str = self._lookup_coro_var(trans, nm.id) if async_name is None: return llvmlite.const_int32(pool, 0) - frame_ty: rawptr[llvmlite.LLVMType] = self._lookup_coro_frame( + frame_ty: llvmlite.LLVMType* = self._lookup_coro_frame( trans, async_name) if frame_ty is None: return llvmlite.const_int32(pool, 0) - frame_ptr_ty: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, frame_ty) + frame_ptr_ty: llvmlite.LLVMType* = llvmlite.Ptr(pool, frame_ty) # 帧变量值(i8* / Ptr(帧))→ bitcast 到 Ptr(帧) - frame_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( + frame_val: llvmlite.Value* = self.Gen.ExprGen.translate_value( builder, pool, mod, arg0, None, 0, trans) if frame_val is None: return llvmlite.const_int32(pool, 0) - frame_ptr: rawptr[llvmlite.Value] = llvmlite.build_bitcast( + frame_ptr: llvmlite.Value* = llvmlite.build_bitcast( builder, frame_val, frame_ptr_ty) if frame_ptr is None: return llvmlite.const_int32(pool, 0) - func: rawptr[llvmlite.Function] = trans._cur_func + func: llvmlite.Function* = trans._cur_func if func is None: return llvmlite.const_int32(pool, 0) rn_buf: str = pool.alloc(64) @@ -2554,10 +2532,10 @@ class AsyncGenMixin(CallGenBase.CallGenBase): llvmlite.build_br(builder, loop_bb) llvmlite.position_at_end(builder, loop_bb) frame_ptr.Next = None - status: rawptr[llvmlite.Value] = llvmlite.build_call( + status: llvmlite.Value* = llvmlite.build_call( builder, resume_mangled, frame_ptr, 1, i32_ty, 0) - zero_cmp: rawptr[llvmlite.Value] = llvmlite.const_int32(pool, 0) - done_cond: rawptr[llvmlite.Value] = llvmlite.build_icmp( + zero_cmp: llvmlite.Value* = llvmlite.const_int32(pool, 0) + done_cond: llvmlite.Value* = llvmlite.build_icmp( builder, llvmlite.ICMP_NE, status, zero_cmp) llvmlite.build_cond_br(builder, done_cond, after_bb, check_bb) # M3:SUSPEND → wake 轮询(GetTickCount64 >= wake 或 wake==0 继续,否则 Sleep(1)) @@ -2566,19 +2544,19 @@ class AsyncGenMixin(CallGenBase.CallGenBase): if wake_idx_r < 0: llvmlite.build_br(builder, loop_bb) else: - i64_ty_r2: rawptr[llvmlite.LLVMType] = llvmlite.Int64(pool) - wake_ptr_r: rawptr[llvmlite.Value] = llvmlite.build_gep_struct( + i64_ty_r2: llvmlite.LLVMType* = llvmlite.Int64(pool) + wake_ptr_r: llvmlite.Value* = llvmlite.build_gep_struct( builder, frame_ty, i64_ty_r2, frame_ptr, wake_idx_r) - wake_v_r: rawptr[llvmlite.Value] = llvmlite.build_load( + wake_v_r: llvmlite.Value* = llvmlite.build_load( builder, i64_ty_r2, wake_ptr_r) - now_v_r: rawptr[llvmlite.Value] = llvmlite.build_call( + now_v_r: llvmlite.Value* = llvmlite.build_call( builder, "GetTickCount64", None, 0, i64_ty_r2, 0) - not_wake_r: rawptr[llvmlite.Value] = llvmlite.build_icmp( + not_wake_r: llvmlite.Value* = llvmlite.build_icmp( builder, llvmlite.ICMP_EQ, wake_v_r, llvmlite.const_int64(pool, 0)) - due_r: rawptr[llvmlite.Value] = llvmlite.build_icmp( + due_r: llvmlite.Value* = llvmlite.build_icmp( builder, llvmlite.ICMP_UGE, now_v_r, wake_v_r) - cont_r: rawptr[llvmlite.Value] = llvmlite.build_or( + cont_r: llvmlite.Value* = llvmlite.build_or( builder, not_wake_r, due_r) wsleep_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block( pool, func, "coro.wsleep") @@ -2586,23 +2564,23 @@ class AsyncGenMixin(CallGenBase.CallGenBase): pool, func, "coro.wdue") llvmlite.build_cond_br(builder, cont_r, wdue_bb, wsleep_bb) llvmlite.position_at_end(builder, wsleep_bb) - sleep_one: rawptr[llvmlite.Value] = llvmlite.const_int32(pool, 1) + sleep_one: llvmlite.Value* = llvmlite.const_int32(pool, 1) llvmlite.build_call(builder, "Sleep", sleep_one, 1, llvmlite.Void(pool), 0) llvmlite.build_br(builder, loop_bb) llvmlite.position_at_end(builder, wdue_bb) llvmlite.build_br(builder, loop_bb) llvmlite.position_at_end(builder, after_bb) - ret_ptr: rawptr[llvmlite.Value] = llvmlite.build_gep_struct( + ret_ptr: llvmlite.Value* = llvmlite.build_gep_struct( builder, frame_ty, i32_ty, frame_ptr, 2) - ret_val: rawptr[llvmlite.Value] = llvmlite.build_load( + ret_val: llvmlite.Value* = llvmlite.build_load( builder, i32_ty, ret_ptr) return ret_val # ============================================================ # 公共查询 / 登记 # ============================================================ - def is_async_func(self, trans: rawptr[HT.Translator], + def is_async_func(self, trans: HT.Translator*, name: str) -> int: """查询 name 是否已注册为 async 函数(_async_funcs 表),1=是 0=否""" if trans is None or name is None or trans._async_funcs is None: @@ -2616,7 +2594,7 @@ class AsyncGenMixin(CallGenBase.CallGenBase): return 1 return 0 - def register_coro_var(self, trans: rawptr[HT.Translator], + def register_coro_var(self, trans: HT.Translator*, var_name: str, func_name: str) -> int: """记录 变量名→async 函数名 映射(coro.coro_run 反查帧类型用)。 对齐 TPC HandlesAnnAssign.py L319-326。返回 0 成功。""" @@ -2640,7 +2618,7 @@ class AsyncGenMixin(CallGenBase.CallGenBase): trans._coro_var_async_count = cnt + 1 return 0 - def _register_async_func(self, trans: rawptr[HT.Translator], + def _register_async_func(self, trans: HT.Translator*, name: str) -> int: """注册 async 函数裸名到 _async_funcs 表""" if trans is None or name is None or trans._async_funcs is None: @@ -2660,9 +2638,9 @@ class AsyncGenMixin(CallGenBase.CallGenBase): trans._async_func_count = cnt + 1 return 0 - def _register_coro_frame(self, trans: rawptr[HT.Translator], + def _register_coro_frame(self, trans: HT.Translator*, name: str, - frame_ty: rawptr[llvmlite.LLVMType]) -> int: + frame_ty: llvmlite.LLVMType*) -> int: """注册 async 名→帧类型 到 _coro_frames 表(16 字节/项 = char* + LLVMType*)""" if trans is None or name is None or frame_ty is None: return 1 @@ -2685,8 +2663,8 @@ class AsyncGenMixin(CallGenBase.CallGenBase): trans._coro_frame_count = cnt + 1 return 0 - def _lookup_coro_frame(self, trans: rawptr[HT.Translator], - name: str) -> rawptr[llvmlite.LLVMType]: + def _lookup_coro_frame(self, trans: HT.Translator*, + name: str) -> llvmlite.LLVMType*: """按 async 名查帧类型,未命中返回 None""" if trans is None or name is None or trans._coro_frames is None: return None @@ -2698,11 +2676,11 @@ class AsyncGenMixin(CallGenBase.CallGenBase): if pair[0] is not None and string.strcmp(pair[0], name) == 0: if pair[1] is not None: ty_addr: sizet = sizet(pair[1]) - return (rawptr[llvmlite.LLVMType])(ty_addr) + return (llvmlite.LLVMType*)(ty_addr) return None return None - def _lookup_coro_var(self, trans: rawptr[HT.Translator], + def _lookup_coro_var(self, trans: HT.Translator*, var_name: str) -> str: """按变量名反查 async 函数名(_coro_var_async 表),未命中返回 None""" if trans is None or var_name is None or trans._coro_var_async is None: @@ -2719,11 +2697,11 @@ class AsyncGenMixin(CallGenBase.CallGenBase): # ============================================================ # 段翻译辅助 # ============================================================ - def _emit_coro_return(self, builder: rawptr[llvmlite.IRBuilder], - pool: rawptr[memhub.MemBuddy], - mod: rawptr[llvmlite.LLVMModule], - trans: rawptr[HT.Translator], - stmt: rawptr[ast.AST]) -> None: + def _emit_coro_return(self, builder: llvmlite.IRBuilder*, + pool: memhub.MemBuddy*, + mod: llvmlite.LLVMModule*, + trans: HT.Translator*, + stmt: ast.AST*) -> None: """协程内 Return 特判:store ret 槽 + done=1 + br exit。 M1 不支持 return await(顶层 await 仅限 AnnAssign/Assign)。 @@ -2731,7 +2709,7 @@ class AsyncGenMixin(CallGenBase.CallGenBase): (base.vp 仅 parent/pool/lineno/col/children),直接 stmt.value 读到的是非法偏移(0/垃圾)→ ret 恒 0。必须转回 ast.Return 再取。""" rv_node: rawptr[ast.Return] = rawptr[ast.Return](stmt) - ret_val: rawptr[llvmlite.Value] = None + ret_val: llvmlite.Value* = None if rv_node is not None and rv_node.value is not None: if rv_node.value.kind() != ast.ASTKind.Await: ret_val = self.Gen.ExprGen.translate_value( @@ -2739,7 +2717,7 @@ class AsyncGenMixin(CallGenBase.CallGenBase): if ret_val is None: ret_val = llvmlite.const_int32(pool, 0) llvmlite.build_store(builder, ret_val, trans._coro_ret_ptr) - done_one: rawptr[llvmlite.Value] = llvmlite.const_int32(pool, 1) + done_one: llvmlite.Value* = llvmlite.const_int32(pool, 1) llvmlite.build_store(builder, done_one, trans._coro_done_ptr) llvmlite.build_br(builder, trans._coro_exit_bb) @@ -2749,30 +2727,30 @@ class AsyncGenMixin(CallGenBase.CallGenBase): return 0 if aw.value.kind() != ast.ASTKind.Call: return 0 - cl: rawptr[ast.Call] = rawptr[ast.Call](aw.value) + cl: ast.Call* = ast.Call*(aw.value) if cl.func is None: return 0 if cl.func.kind() == ast.ASTKind.Name: - nm: rawptr[ast.Name] = rawptr[ast.Name](cl.func) + nm: ast.Name* = ast.Name*(cl.func) if nm.id is not None and string.strcmp(nm.id, "coro_sleep") == 0: return 1 elif cl.func.kind() == ast.ASTKind.Attribute: - at: rawptr[ast.Attribute] = rawptr[ast.Attribute](cl.func) + at: ast.Attribute* = ast.Attribute*(cl.func) if at.attr is not None and string.strcmp(at.attr, "coro_sleep") == 0: return 1 return 0 - def _is_await_tail(self, stmt: rawptr[ast.AST]) -> int: + def _is_await_tail(self, stmt: ast.AST*) -> int: """判断语句是否为段尾:AnnAssign/Assign/Expr 且 value 直接是 Await""" if stmt is None: return 0 sk: int = stmt.kind() if sk == ast.ASTKind.AnnAssign: - aa: rawptr[ast.AnnAssign] = rawptr[ast.AnnAssign](stmt) + aa: ast.AnnAssign* = ast.AnnAssign*(stmt) if aa.value is not None and aa.value.kind() == ast.ASTKind.Await: return 1 elif sk == ast.ASTKind.Assign: - as_: rawptr[ast.Assign] = rawptr[ast.Assign](stmt) + as_: ast.Assign* = ast.Assign*(stmt) if as_.value is not None and as_.value.kind() == ast.ASTKind.Await: if as_.targets is not None and len(as_.targets) == 1: return 1 @@ -2782,36 +2760,36 @@ class AsyncGenMixin(CallGenBase.CallGenBase): return 1 return 0 - def _get_assign_target_name(self, stmt: rawptr[ast.AST]) -> str: + def _get_assign_target_name(self, stmt: ast.AST*) -> str: """取 AnnAssign(target=Name)/Assign(单 target=Name) 的目标名,未命中返回 None""" if stmt is None: return None sk: int = stmt.kind() if sk == ast.ASTKind.AnnAssign: - aa: rawptr[ast.AnnAssign] = rawptr[ast.AnnAssign](stmt) + aa: ast.AnnAssign* = ast.AnnAssign*(stmt) if aa.target is not None and aa.target.kind() == ast.ASTKind.Name: - tn: rawptr[ast.Name] = rawptr[ast.Name](aa.target) + tn: ast.Name* = ast.Name*(aa.target) return tn.id elif sk == ast.ASTKind.Assign: - as_: rawptr[ast.Assign] = rawptr[ast.Assign](stmt) + as_: ast.Assign* = ast.Assign*(stmt) if as_.targets is not None and len(as_.targets) == 1: - t0: rawptr[ast.AST] = as_.targets.get(0) + t0: ast.AST* = as_.targets.get(0) if t0 is not None and t0.kind() == ast.ASTKind.Name: - tn2: rawptr[ast.Name] = rawptr[ast.Name](t0) + tn2: ast.Name* = ast.Name*(t0) return tn2.id return None - def _get_await_value(self, stmt: rawptr[ast.AST]) -> rawptr[ast.Await]: + def _get_await_value(self, stmt: ast.AST*) -> rawptr[ast.Await]: """取段尾语句的 Await value 节点,未命中返回 None""" if stmt is None: return None sk: int = stmt.kind() if sk == ast.ASTKind.AnnAssign: - aa: rawptr[ast.AnnAssign] = rawptr[ast.AnnAssign](stmt) + aa: ast.AnnAssign* = ast.AnnAssign*(stmt) if aa.value is not None and aa.value.kind() == ast.ASTKind.Await: return rawptr[ast.Await](aa.value) elif sk == ast.ASTKind.Assign: - as_: rawptr[ast.Assign] = rawptr[ast.Assign](stmt) + as_: ast.Assign* = ast.Assign*(stmt) if as_.value is not None and as_.value.kind() == ast.ASTKind.Await: return rawptr[ast.Await](as_.value) elif sk == ast.ASTKind.Expr: @@ -2825,19 +2803,19 @@ class AsyncGenMixin(CallGenBase.CallGenBase): if aw_node is None or aw_node.value is None: return None if aw_node.value.kind() == ast.ASTKind.Call: - cl: rawptr[ast.Call] = rawptr[ast.Call](aw_node.value) + cl: ast.Call* = ast.Call*(aw_node.value) if cl.func is not None: if cl.func.kind() == ast.ASTKind.Name: - nm: rawptr[ast.Name] = rawptr[ast.Name](cl.func) + nm: ast.Name* = ast.Name*(cl.func) return nm.id if cl.func.kind() == ast.ASTKind.Attribute: # coro.coro_sleep(ms):M3 sleep 挂起 - at: rawptr[ast.Attribute] = rawptr[ast.Attribute](cl.func) + at: ast.Attribute* = ast.Attribute*(cl.func) if at.attr is not None and string.strcmp(at.attr, "coro_sleep") == 0: return "coro_sleep" return None - def _read_local_name(self, trans: rawptr[HT.Translator], + def _read_local_name(self, trans: HT.Translator*, idx: int) -> str: """读 trans._coro_locals 第 idx 个局部变量名,越界返回 None""" if trans is None or trans._coro_locals is None: diff --git a/App/lib/core/Gen/BaseGenMixin.vp b/App/lib/core/Gen/BaseGenMixin.vp index 7d4e728..bb8053a 100644 --- a/App/lib/core/Gen/BaseGenMixin.vp +++ b/App/lib/core/Gen/BaseGenMixin.vp @@ -9,29 +9,28 @@ import llvmlite # ============================================================ # BaseGenMixin - 生成器基座(状态容器) # ============================================================ -@t.NoVTable -class BaseGenMixin: +novirtual class BaseGenMixin: """生成器状态容器(基座)""" # 内存/IR 状态 - Gen: rawptr[Generator.Generator] - Pool: rawptr[memhub.MemBuddy] # 内存池 - Module: rawptr[llvmlite.LLVMModule] # 当前 LLVM 模块 - Builder: rawptr[llvmlite.IRBuilder] # 当前 IRBuilder + Gen: Generator.Generator* + Pool: memhub.MemBuddy* # 内存池 + Module: llvmlite.LLVMModule* # 当前 LLVM 模块 + Builder: llvmlite.IRBuilder* # 当前 IRBuilder # 符号表/函数表 SymTab: rawptr[GenTypes.SymbolTable] - Funcs: rawptr[GenTypes.FuncEntry] + Funcs: GenTypes.FuncEntry* FuncCount: int # 导入/模块信息 ImportedModules: str FromImports: str ModuleSha1: str # 当前翻译上下文 - CurFunc: rawptr[llvmlite.Function] - CurBuilder: rawptr[llvmlite.IRBuilder] + CurFunc: llvmlite.Function* + CurBuilder: llvmlite.IRBuilder* CurClassName: str - def InitBaseGen(self, pool: rawptr[memhub.MemBuddy]) -> int: + def InitBaseGen(self, pool: memhub.MemBuddy*) -> int: """初始化生成器状态(默认值;子类构造时调用)""" if self is None: return 1 diff --git a/App/lib/core/Gen/Call/CallGenBase.vp b/App/lib/core/Gen/Call/CallGenBase.vp index 6053ef8..bee949a 100644 --- a/App/lib/core/Gen/Call/CallGenBase.vp +++ b/App/lib/core/Gen/Call/CallGenBase.vp @@ -30,44 +30,35 @@ import lib.Stub.StubGen.VpiReader as VpiReader # ============================================================ # 常量(Gen 层各处容量上限) -# -# GLOBAL_FUNC_MAX / GLOBAL_DEFAULTS_MAX / MAX_CLOSURE_NAMES / -# MAX_FUNC_PTR_SIGS / ISINSTANCE_CLASS_MAX 五个容量上限以本文件为**全仓唯一 -# 来源**,消费方 CallGenLeafKit.vp 在函数体内以 CallGenBase. 取值: -# 跨模块整型 t.CDefine 在函数体内可读(与 GenTypes.FIELD_MAX / -# StubMerger.MAX_INCLUDES 走同一条 ExprGenAttr 跨模块 CDefine 查找路径), -# 限制仅在「模块级 t.CDefine 初始化式里引用跨模块常量」。改此一处即全仓生效。 # ============================================================ -# 全局函数表 / 默认参数表容量(消费方:CallGenLeafKit._init_global_func_table / -# _register_global_func / _init_global_defaults_table / _register_global_defaults) -GLOBAL_FUNC_MAX: t.CDefine = 8192 -GLOBAL_DEFAULTS_MAX: t.CDefine = 4096 -_CEXPORT_MAX: t.CDefine = 256 -ASM_MAX_OPERANDS: t.CDefine = 16 -ASM_TEXT_BUF_SIZE: t.CDefine = 2048 -ASM_CONST_BUF_SIZE: t.CDefine = 512 -ASM_ARGS_BUF_SIZE: t.CDefine = 512 -ASM_LINE_BUF_SIZE: t.CDefine = 4096 -LLVMIR_MAX_OPS: t.CDefine = 16 -LLVMIR_TEMPLATE_BUF: t.CDefine = 512 +# 全局函数表 / 默认参数表容量 +define GLOBAL_FUNC_MAX = 8192 +define GLOBAL_DEFAULTS_MAX = 4096 +define _CEXPORT_MAX = 256 +define ASM_MAX_OPERANDS = 16 +define ASM_TEXT_BUF_SIZE = 2048 +define ASM_CONST_BUF_SIZE = 512 +define ASM_ARGS_BUF_SIZE = 512 +define ASM_LINE_BUF_SIZE = 4096 +define LLVMIR_MAX_OPS = 16 +define LLVMIR_TEMPLATE_BUF = 512 # 闭包名表大小(消费方:CallGenLeafKit._ensure_closure_names/register_closure_name) -MAX_CLOSURE_NAMES: t.CDefine = 128 +define MAX_CLOSURE_NAMES = 128 # 函数指针签名表大小(消费方:CallGenLeafKit._ensure_funcptr_sigs/register_func_ptr_sig) -MAX_FUNC_PTR_SIGS: t.CDefine = 64 +define MAX_FUNC_PTR_SIGS = 64 # isinstance 子类收集上限(防数组越界;t.CDefine 注解由 TPC 解析为 i32。 # 消费方:CallGenLeafKit._collect_subclass_vtable_classes) -ISINSTANCE_CLASS_MAX: t.CDefine = 64 +define ISINSTANCE_CLASS_MAX = 64 # ============================================================ # CallGenBase - 最底层父类(字段 + 模块查找 + 返回类型解析) # ============================================================ -@t.NoVTable -class CallGenBase: +novirtual class CallGenBase: """调用分派最底层父类(字段 + 模块符号查找 + 返回类型解析基础设施)""" # --- c.cexport 注册表(原 _g_cexport_sha1_arr/_g_cexport_func_arr/_g_cexport_count) --- - Gen: rawptr[Generator.Generator] + Gen: Generator.Generator* CexportSha1Arr: bytes CexportFuncArr: bytes CexportCount: int @@ -85,31 +76,30 @@ class CallGenBase: # --- 函数指针签名表(原 _g_funcptr_names/_g_funcptr_rets/_g_funcptr_count) --- FuncptrNames: str - FuncptrRets: uint64 | t.CPtr + FuncptrRets: uint64* FuncptrCount: int # --- 全局函数注册表(原 _global_funcs/_global_func_count) --- - GlobalFuncs: rawptr[GenTypes.FuncEntry] + GlobalFuncs: GenTypes.FuncEntry* GlobalFuncCount: int # --- 全局函数表"名 → 槽下标"索引(开放寻址 | 线性探测;槽存 index+1,0=空槽) --- # GlobalFuncs 只追加不重排 ⇒ 槽下标稳定;Built == GlobalFuncCount 才可信,否则回退线性扫描。 - GlobalFuncNameIdx: sizet | t.CPtr + GlobalFuncNameIdx: sizet* GlobalFuncNameIdxCap: int GlobalFuncNameIdxBuilt: int # --- 全局默认参数表(原 _global_defaults/_global_defaults_count) --- - GlobalDefaults: rawptr[GenTypes.FuncDefaultsEntry] + GlobalDefaults: GenTypes.FuncDefaultsEntry* GlobalDefaultsCount: int # --- 依赖模块 text.ll「方法返回类型文本」缓存(_LookupMethodRetTyFromTextLL 性能优化) --- # key = define 的完整 mangled 函数名("{sha1}.{后缀}"),值只存文本(绝不存 LLVMType*,其分配在每文件 reset 失效的 pool 中);表与键/值均 PermPool 分配,命中后用调用方 pool 重建类型,建表失败即不缓存并回退原扫描。 - MethodRetTyMap: rawptr[hashtable.HashTable] + MethodRetTyMap: hashtable.HashTable* def InitCallGen(self) -> int: """初始化调用 Mixin 字段(子类构造时内联调用,规避 NoVTable 继承符号不转发)""" - if self is None: - return 1 + if self is None: return 1 self.CexportSha1Arr = None self.CexportFuncArr = None self.CexportCount = 0 @@ -153,7 +143,7 @@ class CallGenBase: return StubMergerStore.LookupSha1ByModNameSuffix(mod_suffix) - def _module_package_from_sha1(self, pool: rawptr[memhub.MemBuddy], + def _module_package_from_sha1(self, pool: memhub.MemBuddy*, mod_sha1: str) -> str: """从 SHA1 存储器的 rel_path 计算模块所属包名(目录部分,'/' → '.')""" if pool is None or mod_sha1 is None: @@ -188,7 +178,7 @@ class CallGenBase: return None - def _lookup_reexport_from_vpi(self, pool: rawptr[memhub.MemBuddy], + def _lookup_reexport_from_vpi(self, pool: memhub.MemBuddy*, mod_sha1: str, func_name: str) -> str: """re-export 表未命中时,从模块 .vpi 按需解析 from-import 定位定义模块 @@ -447,7 +437,7 @@ class CallGenBase: return 0 - def _is_state_func_from_vpi(self, pool: rawptr[memhub.MemBuddy], + def _is_state_func_from_vpi(self, pool: memhub.MemBuddy*, sha1: str, func_name: str) -> int: """vpi 返回注解含 t.State → 外部 C 函数(定义端用裸名,跨模块调用无 sha1 头) @@ -461,29 +451,25 @@ class CallGenBase: if self.Gen.CallGenBase.TempDir is not None and self.Gen.CallGenBase.TempDirLen > 0: VpiReader._ensure_vpi_ret_annot_loaded(sha1, self.Gen.CallGenBase.TempDir) state_annot: str = VpiReader._lookup_vpi_ret_annot(sha1, None, func_name) - if state_annot is None: - return 0 + if state_annot is None: return 0 # 返回注解含 "State"(如 "sizet | t.State")→ 外部 C 函数 - if string.strstr(state_annot, "State") is not None: - return 1 + if string.strstr(state_annot, "State") is not None: return 1 return 0 - def _lookup_mod_sha1(self, pool: rawptr[memhub.MemBuddy], + def _lookup_mod_sha1(self, pool: memhub.MemBuddy*, from_imports: str, class_name: str, allow_star_fallback: int = 1) -> str: """从 from_imports 查找类所属模块的 SHA1,返回 None=未找到 allow_star_fallback: 传 0 禁用 star import 回退(用于明确模块名/函数名查找) """ - mod_name_raw: str = self.Gen.ImportsGen.lookup_from_import( - from_imports, class_name, allow_star_fallback) - if mod_name_raw is None: - return None + mod_name_raw: str = self.Gen.ImportsGen.lookup_from_import(from_imports, class_name, allow_star_fallback) + if mod_name_raw is None: return None return self._lookup_sha1_from_modname_raw(pool, mod_name_raw) - def _lookup_sha1_from_modname_raw(self, pool: rawptr[memhub.MemBuddy], + def _lookup_sha1_from_modname_raw(self, pool: memhub.MemBuddy*, mod_name_raw: str) -> str: """从原始模块名查找 SHA1,返回 None=未找到""" # 手动找到模块名结束位置(空格、null、或 ':' 别名分隔符),复制到新缓冲区 @@ -506,9 +492,9 @@ class CallGenBase: return sha1 - def find_func_in_module(self, mod: rawptr[llvmlite.LLVMModule], + def find_func_in_module(self, mod: llvmlite.LLVMModule*, name: str, - owner_sha1: str = None) -> rawptr[llvmlite.Function]: + owner_sha1: str = None) -> llvmlite.Function*: """在模块的函数链表中按名称查找函数 查找策略: @@ -529,8 +515,8 @@ class CallGenBase: return None name_len: sizet = string.strlen(name) # 热点优化:原 4 趟完整链表扫描合并为 2 趟——趟 1 精确匹配(命中即返回)+ 收集首个本模块同名 mangled 候选;趟 2 收集首个 IsDeclared==0 后缀命中与首个任意后缀命中,扫描后按原优先级返回(语义不变) - cur: rawptr[llvmlite.Function] = mod.FuncHead - mangle_hit: rawptr[llvmlite.Function] = None + cur: llvmlite.Function* = mod.FuncHead + mangle_hit: llvmlite.Function* = None while cur is not None: cur_name: str = llvmlite.function_get_name(cur) if cur_name is not None: @@ -557,8 +543,8 @@ class CallGenBase: if mangle_hit is not None: return mangle_hit # 后缀匹配(.name):不跳过 declare(方法 stub 也是 declare,由调用处判断 IsDeclared 决定用裸名或 sha1 前缀名)。本模块同名 define 必须优先于跨模块 stub declare,无同名 define 时回退 stub declare - declare_hit: rawptr[llvmlite.Function] = None - any_hit: rawptr[llvmlite.Function] = None + declare_hit: llvmlite.Function* = None + any_hit: llvmlite.Function* = None cur = mod.FuncHead while cur is not None: cur_name2: str = llvmlite.function_get_name(cur) @@ -588,11 +574,11 @@ class CallGenBase: # _ensure_method_declare:found_func 为 None(stub 未注入或跨模块调用)时在当前模块创建 declare,避免 llc 报 undefined value - def _ensure_method_declare(self, pool: rawptr[memhub.MemBuddy], - mod: rawptr[llvmlite.LLVMModule], + def _ensure_method_declare(self, pool: memhub.MemBuddy*, + mod: llvmlite.LLVMModule*, call_name: str, - ret_ty: rawptr[llvmlite.LLVMType], - param_head: rawptr[llvmlite.Value], + ret_ty: llvmlite.LLVMType*, + param_head: llvmlite.Value*, param_count: int): """为跨模块方法调用创建 declare 声明 @@ -607,7 +593,7 @@ class CallGenBase: # 无上限遍历会死循环(builtins.vp dump 卡死根因排查),超限即报错终止。 DECLARE_CHAIN_LIMIT: int = 100000 # 检查模块中是否已有同名函数(declare 或 define) - existing: rawptr[llvmlite.Function] = mod.FuncHead + existing: llvmlite.Function* = mod.FuncHead existing_steps: int = 0 while existing is not None: existing_steps += 1 @@ -628,7 +614,7 @@ class CallGenBase: return # 遍历现有参数链表计数(避免依赖 GSList.Count 字段的类型推断) cur_count: int = 0 - cur_p: rawptr[llvmlite.Param] = llvmlite.function_get_param_head(existing) + cur_p: llvmlite.Param* = llvmlite.function_get_param_head(existing) while cur_p is not None: cur_count += 1 if cur_count > DECLARE_CHAIN_LIMIT: @@ -639,7 +625,7 @@ class CallGenBase: # 只追加缺失的参数(cur_count < param_count 时) if cur_count < param_count: # 定位到 param_head 的第 cur_count 个节点开始追加 - pnode2: rawptr[llvmlite.Value] = param_head + pnode2: llvmlite.Value* = param_head pi2: int = 0 # 跳过已有的 cur_count 个参数 while pnode2 is not None and pi2 < cur_count: @@ -648,7 +634,7 @@ class CallGenBase: # 追加剩余参数 while pnode2 is not None and pi2 < param_count: if pnode2.Ty is not None: - param2: rawptr[llvmlite.Param] = llvmlite.new_param(pool, pnode2.Ty, None) + param2: llvmlite.Param* = llvmlite.new_param(pool, pnode2.Ty, None) if param2 is not None: llvmlite.function_add_param(existing, param2) pnode2 = pnode2.Next @@ -657,14 +643,11 @@ class CallGenBase: existing = existing.Next # 裸名 C 库函数(如 string.memset → @memset):call_name 无 sha1 前缀,无法提取定义侧模块查 vpi 参数注解,故按标准签名建 declare(与 CallGenLib._ensure_c_lib_declare 白名单一致) if call_name is not None and string.strchr(call_name, 46) is None: - std_lib_fn: rawptr[llvmlite.Function] = self.Gen.CallGenLib._ensure_c_lib_declare( - pool, mod, call_name) - if std_lib_fn is not None: - return + std_lib_fn: llvmlite.Function* = self.Gen.CallGenLib._ensure_c_lib_declare(pool, mod, call_name) + if std_lib_fn is not None: return # 创建函数声明 - func: rawptr[llvmlite.Function] = llvmlite.new_function(pool, call_name, ret_ty) - if func is None: - return + func: llvmlite.Function* = llvmlite.new_function(pool, call_name, ret_ty) + if func is None: return func.IsDeclared = 1 # 定义侧参数类型优先:从 call_name 提取 {sha1}.{cls}.{method} 查 vpi 参数注解取定义侧类型,仅当实参与定义都是整数且定义更宽时采用定义宽度(指针/联合保持实参类型)。反方向(定义更窄)由 CallGenLib._coerce_args_to_def_params 在调用点先窄化实参 sha1_d: str = None @@ -697,16 +680,15 @@ class CallGenBase: prm_annots_d: str = None if sha1_d is not None and meth_d is not None: prm_annots_d = self._vpi_method_param_annot(pool, sha1_d, cls_d, meth_d) - i32_ty_d: rawptr[llvmlite.LLVMType] = llvmlite.Int32(pool) - i8_ptr_d: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, llvmlite.Int8(pool)) + i32_ty_d: llvmlite.LLVMType* = llvmlite.Int32(pool) + i8_ptr_d: llvmlite.LLVMType* = llvmlite.Ptr(pool, llvmlite.Int8(pool)) # 添加参数(declare 中参数名无意义,设为 None 只输出类型) - pnode: rawptr[llvmlite.Value] = param_head + pnode: llvmlite.Value* = param_head pi: int = 0 while pnode is not None and pi < param_count: - param_ty_d: rawptr[llvmlite.LLVMType] = pnode.Ty + param_ty_d: llvmlite.LLVMType* = pnode.Ty if prm_annots_d is not None and prm_annots_d[0] != '\0' and pnode.Ty is not None: - seg_ty_d: rawptr[llvmlite.LLVMType] = VpiReader._resolve_vpi_param_annot_seg( - pool, sha1_d, cls_d, meth_d, pi, i32_ty_d, i8_ptr_d) + seg_ty_d: llvmlite.LLVMType* = VpiReader._resolve_vpi_param_annot_seg(pool, sha1_d, cls_d, meth_d, pi, i32_ty_d, i8_ptr_d) if seg_ty_d is not None: match pnode.Ty: case llvmlite.LLVMType.Int(bits_a): @@ -719,7 +701,7 @@ class CallGenBase: case _: pass if param_ty_d is not None: - param: rawptr[llvmlite.Param] = llvmlite.new_param(pool, param_ty_d, None) + param: llvmlite.Param* = llvmlite.new_param(pool, param_ty_d, None) if param is not None: llvmlite.function_add_param(func, param) pnode = pnode.Next @@ -733,16 +715,16 @@ class CallGenBase: # _lookup_method_ret_ty_via_vpi:按 模块SHA1 + 类名 + 方法名 查 vpi 返回注解缓存并解析为 LLVMType,未命中返回 None(不硬编码白名单,类型始终来自定义处) # ============================================================ - def _lookup_method_ret_ty_via_vpi(self, pool: rawptr[memhub.MemBuddy], + def _lookup_method_ret_ty_via_vpi(self, pool: memhub.MemBuddy*, cls_sha1: str, cls_name: str, - method_name: str) -> rawptr[llvmlite.LLVMType]: + method_name: str) -> llvmlite.LLVMType*: """从 vpi stub 返回注解缓存获取方法返回类型,未命中返回 None""" if pool is None or cls_sha1 is None or method_name is None: return None # 函数内懒 import:VpiReader imports HandlesExprCall,顶层 import 会成环 - i32_ty: rawptr[llvmlite.LLVMType] = llvmlite.Int32(pool) - i8_ptr_ty: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, llvmlite.Int8(pool)) + i32_ty: llvmlite.LLVMType* = llvmlite.Int32(pool) + i8_ptr_ty: llvmlite.LLVMType* = llvmlite.Ptr(pool, llvmlite.Int8(pool)) # 按需加载:缓存未命中时直接读 {temp_dir}/{sha1[0:2]}/{sha1}.vpi # 覆盖"模块自身翻译时 stub 尚未注入"(同模块方法调用,定义在后)的场景 if self.Gen.CallGenBase.TempDir is not None and self.Gen.CallGenBase.TempDirLen > 0: @@ -753,7 +735,7 @@ class CallGenBase: return VpiReader._resolve_vpi_ret_annot_str(pool, annot, i32_ty, i8_ptr_ty) # _vpi_method_param_annot:按需加载并查询 vpi 参数注解串('@' 分隔,含首参 self 空串占位),供调用方补全 declare/call 缺失参数;未命中返回 None - def _vpi_method_param_annot(self, pool: rawptr[memhub.MemBuddy], + def _vpi_method_param_annot(self, pool: memhub.MemBuddy*, cls_sha1: str, cls_name: str, method_name: str) -> str: @@ -766,21 +748,21 @@ class CallGenBase: return VpiReader._lookup_vpi_param_annots(cls_sha1, cls_name, method_name) # _vpi_resolve_param_annot_ty:解析 vpi 参数注解段为 LLVMType,失败返回 None(调用方以 i8* 兜底) - def _vpi_resolve_param_annot_ty(self, pool: rawptr[memhub.MemBuddy], - seg: str) -> rawptr[llvmlite.LLVMType]: + def _vpi_resolve_param_annot_ty(self, pool: memhub.MemBuddy*, + seg: str) -> llvmlite.LLVMType*: """解析单个 vpi 参数注解段为 LLVMType,失败返回 None""" if pool is None or seg is None: return None - i32_ty: rawptr[llvmlite.LLVMType] = llvmlite.Int32(pool) - i8_ptr_ty: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, llvmlite.Int8(pool)) + i32_ty: llvmlite.LLVMType* = llvmlite.Int32(pool) + i8_ptr_ty: llvmlite.LLVMType* = llvmlite.Ptr(pool, llvmlite.Int8(pool)) return VpiReader._resolve_vpi_ret_annot_str(pool, seg, i32_ty, i8_ptr_ty) # _special_method_ret_ty:编译器内置特殊方法的固定返回类型——__before_init__/__init__ → void,__new__ → Ptr(StructTy),非特殊返回 None(vpi 无条目,固定即可避免 fail-fast 误报) # ============================================================ - def _special_method_ret_ty(self, pool: rawptr[memhub.MemBuddy], + def _special_method_ret_ty(self, pool: memhub.MemBuddy*, class_name: str, - method_name: str) -> rawptr[llvmlite.LLVMType]: + method_name: str) -> llvmlite.LLVMType*: """编译器内置特殊方法的固定返回类型;非特殊返回 None""" if pool is None or method_name is None: return None @@ -789,7 +771,7 @@ class CallGenBase: return llvmlite.Void(pool) if string.strcmp(method_name, "__new__") == 0: if class_name is not None: - sp_struct_ty: rawptr[llvmlite.LLVMType] = self.Gen.StructGen.get_struct_type(class_name) + sp_struct_ty: llvmlite.LLVMType* = self.Gen.StructGen.get_struct_type(class_name) if sp_struct_ty is not None: return llvmlite.Ptr(pool, sp_struct_ty) return None @@ -799,19 +781,14 @@ class CallGenBase: # ============================================================ def _fail_method_ret_ty(self, method_name: str, - node: rawptr[ast.AST] = None) -> rawptr[llvmlite.LLVMType]: + node: ast.AST* = None) -> llvmlite.LLVMType*: """方法返回类型无法精确获取时 fail-fast(ERROR + 错误堆栈) 返回类型来源(按序):当前模块函数 → text.ll define → vpi stub 返回注解缓存。 全部未命中说明方法定义缺失或 stub 损坏,立即终止暴露,绝不静默默认 i32。 """ - VLogger.error( - f"方法返回类型无法精确获取(函数/text.ll/vpi stub 均未命中): {method_name}", - "HandlesExprCall") - self.Gen.TypeGenErr.fatal_error( - node, - f"方法返回类型无法精确获取,默认 i32 会截断指针/i64: {method_name}", - "TypeError") + VLogger.error(f"方法返回类型无法精确获取(函数/text.ll/vpi stub 均未命中): {method_name}", "HandlesExprCall") + self.Gen.TypeGenErr.fatal_error(node, f"方法返回类型无法精确获取,默认 i32 会截断指针/i64: {method_name}", "TypeError") return None # SetTempDir:设置 temp 目录路径(Phase A 翻译前调用,供读取依赖模块 text.ll) @@ -819,8 +796,7 @@ class CallGenBase: # ============================================================ def SetTempDir(self, temp_dir: str) -> None: """设置 temp 目录路径(统一写入 Gen.CallGenBase 真源,跨子对象共享)""" - if self.Gen is None: - return + if self.Gen is None: return self.Gen.CallGenBase.TempDir = temp_dir if temp_dir is not None: self.Gen.CallGenBase.TempDirLen = string.strlen(temp_dir) @@ -830,10 +806,10 @@ class CallGenBase: # _ParseLLVMRetTyStr:把 LLVM IR 返回类型字符串(define 与 @ 之间)转为 LLVMType——void / iN / double / float,含 * 者返回通用 Ptr(Int8);无法解析返回 None # ============================================================ - def _ParseLLVMRetTyStr(self, pool: rawptr[memhub.MemBuddy], + def _ParseLLVMRetTyStr(self, pool: memhub.MemBuddy*, buf: bytes, start: sizet, - end: sizet) -> rawptr[llvmlite.LLVMType]: + end: sizet) -> llvmlite.LLVMType*: """将 LLVM IR 返回类型字符串转换为 llvmlite.LLVMType""" if pool is None or buf is None or start >= end: return None @@ -860,8 +836,8 @@ class CallGenBase: # struct 字面量 {T1, T2, ...}(tuple 打包返回类型)必须在 * 检查之前,否则内含 * 会被误判为 i8*(破坏 tuple 解包) if s < e and buf[s] == '{': - th_st: rawptr[llvmlite.Function] = None - tt_st: rawptr[llvmlite.Function] = None + th_st: llvmlite.Function* = None + tt_st: llvmlite.Function* = None tc_st: int = 0 ps_st: sizet = s + 1 while ps_st < e and buf[ps_st] != '}': @@ -874,14 +850,10 @@ class CallGenBase: ps_st += 1 ee_st: sizet = ps_st if ee_st > es_st: - et_st: rawptr[llvmlite.LLVMType] = self._ParseLLVMRetTyStr( - pool, buf, es_st, ee_st) - if et_st is None: - return None - en_st: rawptr[llvmlite.Function] = llvmlite.new_param_node( - pool, et_st) - if en_st is None: - return None + et_st: llvmlite.LLVMType* = self._ParseLLVMRetTyStr(pool, buf, es_st, ee_st) + if et_st is None: return None + en_st: llvmlite.Function* = llvmlite.new_param_node(pool, et_st) + if en_st is None: return None if th_st is None: th_st = en_st else: @@ -890,7 +862,7 @@ class CallGenBase: tc_st += 1 if th_st is None or tc_st == 0: return None - st_ty_st: rawptr[llvmlite.LLVMType] = llvmlite.Struct(pool, th_st, tc_st, None) + st_ty_st: llvmlite.LLVMType* = llvmlite.Struct(pool, th_st, tc_st, None) # 指针到 struct({i32, i8}*):返回 Ptr(Struct);纯 tuple 打包 # ({i8*, i16})无尾部 *,返回 Struct 本身。 if ps_st < e and buf[ps_st] == '*': @@ -949,7 +921,7 @@ class CallGenBase: """查返回类型文本缓存:命中返回文本,未命中返回 None""" if self.Gen is None or class_sha1 is None or method_name is None: return None - ht: rawptr[hashtable.HashTable] = self.Gen.CallGenBase.MethodRetTyMap + ht: hashtable.HashTable* = self.Gen.CallGenBase.MethodRetTyMap if ht is None: return None sha1_len: sizet = string.strlen(class_sha1) @@ -981,10 +953,10 @@ class CallGenBase: """登记 text.ll 全部 define 行到持久缓存(建表/分配失败即不缓存,回退原扫描)""" if self.Gen is None or class_sha1 is None or text_buf is None or text_len == 0: return - perm: rawptr[memhub.MemBuddy] = CompilerFactory.factory.PermPool + perm: memhub.MemBuddy* = CompilerFactory.factory.PermPool if perm is None: return - ht: rawptr[hashtable.HashTable] = self.Gen.CallGenBase.MethodRetTyMap + ht: hashtable.HashTable* = self.Gen.CallGenBase.MethodRetTyMap if ht is None: ht = hashtable.HashTable(perm) if ht is None: @@ -1051,11 +1023,11 @@ class CallGenBase: # _LookupMethodRetTyFromTextLL:读取 {temp_dir}/{sha1[0:2]}/{sha1}.text.ll (level=1),按 "{sha1}.{class_name}.{method_name}" 搜索 define 行并解析返回类型;未找到/文件不存在返回 None # ============================================================ - def _LookupMethodRetTyFromTextLL(self, pool: rawptr[memhub.MemBuddy], + def _LookupMethodRetTyFromTextLL(self, pool: memhub.MemBuddy*, class_sha1: str, class_name: str, method_name: str, - use_bare: int = 0) -> rawptr[llvmlite.LLVMType]: + use_bare: int = 0) -> llvmlite.LLVMType*: """从依赖模块的 text.ll 中查找方法返回类型 use_bare: 1=按模块级函数查找(搜索 "{sha1}.{method_name}" define, @@ -1071,8 +1043,7 @@ class CallGenBase: return None # 缓存命中:O(1) 取回返回类型文本并用调用方 pool 重建类型直接返回;未命中走下方原实现 - cached_text: str = self._LookupCachedRetTyText( - class_sha1, class_name, method_name, use_bare) + cached_text: str = self._LookupCachedRetTyText(class_sha1, class_name, method_name, use_bare) if cached_text is not None: return self._ParseLLVMRetTyStr(pool, cached_text, 0, string.strlen(cached_text)) @@ -1080,8 +1051,7 @@ class CallGenBase: # 使用 subdir 缓冲区避免 %c 格式化问题(与 StubMerger._sliced_path 一致) path_len: sizet = self.Gen.CallGenBase.TempDirLen + sha1_len + 14 path_buf: bytes = stdlib.malloc(path_len) - if path_buf is None: - return None + if path_buf is None: return None subdir_buf: bytes = stdlib.malloc(3) if subdir_buf is None: stdlib.free(path_buf) @@ -1145,7 +1115,7 @@ class CallGenBase: self._CacheModuleRetTyTexts(class_sha1, read_buf, buf_len) pos: sizet = 0 - result_ty: rawptr[llvmlite.LLVMType] = None + result_ty: llvmlite.LLVMType* = None while pos < buf_len and result_ty is None: ls: sizet = pos @@ -1191,7 +1161,7 @@ class CallGenBase: # _dep_text_ll_exists:探测 {temp_dir}/{sha1[0:2]}/{sha1}.text.ll 是否存在(1=存在),用于区分「依赖已编译但函数缺失」与「依赖模块尚未翻译」 # ============================================================ - def _dep_text_ll_exists(self, pool: rawptr[memhub.MemBuddy], + def _dep_text_ll_exists(self, pool: memhub.MemBuddy*, sha1: str) -> int: """探测 {temp_dir}/{sha1[0:2]}/{sha1}.text.ll 是否存在,1=存在""" if self.Gen.CallGenBase.TempDir is None or self.Gen.CallGenBase.TempDirLen == 0 or sha1 is None: diff --git a/App/lib/core/Gen/Call/CallGenCBuiltin.vp b/App/lib/core/Gen/Call/CallGenCBuiltin.vp index 8285e7b..1c31350 100644 --- a/App/lib/core/Gen/Call/CallGenCBuiltin.vp +++ b/App/lib/core/Gen/Call/CallGenCBuiltin.vp @@ -46,35 +46,27 @@ class CallGenCBuiltin(CallGenBase.CallGenBase): """c.* 内建 + 内联汇编 + LLVMIR 翻译(继承 Base)""" - def translate_c_deref(self, pool: rawptr[memhub.MemBuddy], - builder: rawptr[llvmlite.IRBuilder], - mod: rawptr[llvmlite.LLVMModule], - cl: rawptr[ast.Call], - trans: rawptr[HT.Translator] = None) -> rawptr[llvmlite.Value]: - """c.Deref(ptr) → load,宽度只由 ptr 的 pointee 类型决定 - - pointee 是 i8(t.CPtr / void* / str / bytes)恒读 1 字节;不再按赋值 - 目标注解(CurAssignAnnot)反推宽度——那会让同一处 c.Deref(i8*) 的读取 - 宽度取决于它是否恰好出现在带注解赋值的 RHS 里。需要按更宽类型读时, - 由调用点显式给出元素类型指针后再解引用(见下方读取分支注释)。 + def translate_c_deref(self, pool: memhub.MemBuddy*, + builder: llvmlite.IRBuilder*, + mod: llvmlite.LLVMModule*, + cl: ast.Call*, + trans: HT.Translator* = None) -> llvmlite.Value*: + """c.Deref(ptr) → load,宽度只由 ptr 的 pointee 类型决定 + + pointee 是 i8(t.CPtr / void* / str / bytes)恒读 1 字节;不再按赋值 + 目标注解(CurAssignAnnot)反推宽度——那会让同一处 c.Deref(i8*) 的读取 + 宽度取决于它是否恰好出现在带注解赋值的 RHS 里。需要按更宽类型读时, + 由调用点显式给出元素类型指针后再解引用(见下方读取分支注释)。 """ - if cl is None: - return None + if cl is None: return None cargs: list[ast.AST*]* = cl.args - if cargs is None or len(cargs) < 1: - return None - - 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 - + if cargs is None or len(cargs) < 1: return None + ptr_val: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, mod, cargs.get(0), None, 0, trans) + if ptr_val is None: return None # rawptr[t.CVolatile | T] 实参(volatile 指针指向物):c.Deref(p) 的 # 解引用 load 带 volatile。仅当实参可解析到 VarEntry(Name)/ FieldEntry # (Attribute)时为 1;其余(函数返回/调用/复杂表达式)为 0(明确不支持)。 - vol_deref: int = self.Gen.ExprGenAttr.base_pointee_is_volatile( - pool, trans, cargs.get(0)) - + vol_deref: int = self.Gen.ExprGenAttr.base_pointee_is_volatile(pool, trans, cargs.get(0)) # 读取宽度只由指针类型决定:按 pointee 类型 load 一个元素。 # pointee 是 i8(t.CPtr / void* / str / bytes)即恒读 1 字节。 # 需要 4/8 字节等更宽读取时,必须在调用点把指针显式变成有元素类型的 @@ -82,7 +74,7 @@ class CallGenCBuiltin(CallGenBase.CallGenBase): # 不再由赋值目标注解反推——否则同一处 c.Deref(i8*) 的宽度会随上下文 # (是否带注解赋值的 RHS)而变。 if self.Gen.ExprGenBase.is_ptr_type(ptr_val.Ty) != 0: - pointee: rawptr[llvmlite.LLVMType] = ptr_val.Ty.Pointee + pointee: llvmlite.LLVMType* = ptr_val.Ty.Pointee if pointee is not None: return llvmlite.build_load(builder, pointee, ptr_val, vol_deref) # 非指针参数即类型推断退化:fail-fast,绝不按 i8 兜底读取(会读到垃圾宽度) @@ -90,11 +82,11 @@ class CallGenCBuiltin(CallGenBase.CallGenBase): return None - def translate_c_derefas(self, pool: rawptr[memhub.MemBuddy], - builder: rawptr[llvmlite.IRBuilder], - mod: rawptr[llvmlite.LLVMModule], - cl: rawptr[ast.Call], - trans: rawptr[HT.Translator] = None) -> rawptr[llvmlite.Value]: + def translate_c_derefas(self, pool: memhub.MemBuddy*, + builder: llvmlite.IRBuilder*, + mod: llvmlite.LLVMModule*, + cl: ast.Call*, + trans: HT.Translator* = None) -> llvmlite.Value*: """c.DerefAs(ptr, val) → store val to ptr(bitcast 后 store) 单参形式 c.DerefAs(ptr) → 读取 ptr 指向的值(等价 c.Deref(ptr))。 """ @@ -107,17 +99,14 @@ class CallGenCBuiltin(CallGenBase.CallGenBase): # saved = c.DerefAs(save_count)、restore_pt_range L277-278 # c.DerefAs(entry_ptr) 根因——此前 len<2 直接 return None → # 跌落跨模块函数调用生成 call @DerefAs → ld.lld undefined symbol: - # DerefAs。读取宽度与 c.Deref 同口径(只认 pointee 类型), + # DerefAs。读取宽度与 c.Deref 同口径(只认 pointee 类型), # 故直接复用 translate_c_deref。 if len(cargs) < 2: return self.translate_c_deref(pool, builder, mod, cl, trans) - ptr_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( - builder, pool, mod, cargs.get(0), None, 0, trans) - 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 + ptr_val: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, mod, cargs.get(0), None, 0, trans) + val: 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 # 两端均为指向同一结构体类型的指针时执行结构体拷贝(*ptr = *val), # 而非存储指针值。这对 REnum 变体构造(c.DerefAs(ptr, LLVMType.Int(32)))至关重要: @@ -125,61 +114,53 @@ class CallGenCBuiltin(CallGenBase.CallGenBase): # 只写入 8 字节指针(tag 字段仍是 0x0),导致运行时读 tag 错乱。 # 对应 TPC HandlesExprCall.py:3696-3701 的 struct 拷贝逻辑。 if self.Gen.ExprGenBase.is_ptr_type(ptr_val.Ty) != 0 and self.Gen.ExprGenBase.is_ptr_type(val.Ty) != 0: - ptr_pointee: rawptr[llvmlite.LLVMType] = ptr_val.Ty.Pointee - val_pointee: rawptr[llvmlite.LLVMType] = val.Ty.Pointee + ptr_pointee: llvmlite.LLVMType* = ptr_val.Ty.Pointee + val_pointee: llvmlite.LLVMType* = val.Ty.Pointee if ptr_pointee is not None and val_pointee is not None: # ptr_pointee 是已注册结构体类型(用 find_struct_by_type 判断) if self.Gen.StructGen.find_struct_by_type(ptr_pointee) is not None: if ptr_pointee is val_pointee: # 同一结构体类型:load 值再 store(结构体拷贝) - loaded: rawptr[llvmlite.Value] = llvmlite.build_load( - builder, val_pointee, val) + loaded: 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: rawptr[llvmlite.Value] = llvmlite.build_bitcast( - builder, ptr_val, struct_ptr_ty) + struct_ptr_ty: llvmlite.LLVMType* = llvmlite.Ptr(pool, ptr_pointee) + casted_ptr: llvmlite.Value* = llvmlite.build_bitcast(builder, ptr_val, struct_ptr_ty) if casted_ptr is not None: llvmlite.build_store(builder, loaded, casted_ptr) return val # bitcast ptr 到 val.Ty* 再 store - val_ptr_ty: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, val.Ty) - casted_ptr: rawptr[llvmlite.Value] = llvmlite.build_bitcast(builder, ptr_val, val_ptr_ty) + val_ptr_ty: llvmlite.LLVMType* = llvmlite.Ptr(pool, val.Ty) + casted_ptr: 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) return val - def translate_c_set(self, pool: rawptr[memhub.MemBuddy], - builder: rawptr[llvmlite.IRBuilder], - mod: rawptr[llvmlite.LLVMModule], - cl: rawptr[ast.Call], - trans: rawptr[HT.Translator] = None) -> rawptr[llvmlite.Value]: + def translate_c_set(self, pool: memhub.MemBuddy*, + builder: llvmlite.IRBuilder*, + mod: llvmlite.LLVMModule*, + cl: ast.Call*, + trans: HT.Translator* = None) -> llvmlite.Value*: """c.Set(a, b) → a = b(赋值语义,a 为左值)""" - if cl is None: - return None + if cl is None: return None cargs: list[ast.AST*]* = cl.args - if cargs is None or len(cargs) < 2: - return None - a_node: rawptr[ast.AST] = cargs.get(0) - 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 + if cargs is None or len(cargs) < 2: return None + a_node: ast.AST* = cargs.get(0) + b_val: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, mod, cargs.get(1), None, 0, trans) + if b_val is None: return None # 形态 1: c.Set(c.Deref(ptr), b) → *ptr = b if a_node is not None and a_node.kind() == ast.ASTKind.Call: - d_call: rawptr[ast.Call] = rawptr[ast.Call](a_node) + d_call: ast.Call* = ast.Call*(a_node) 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) + d_at: ast.Attribute* = ast.Attribute*(d_call.func) if d_at.attr is not None and string.strcmp(d_at.attr, "Deref") == 0: d_args: list[ast.AST*]* = d_call.args if d_args is not None and len(d_args) >= 1: - ptr_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( - builder, pool, mod, d_args.get(0), None, 0, trans) + ptr_val: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, mod, d_args.get(0), None, 0, trans) if ptr_val is not None: # 写入宽度以「左值指针自身的元素类型」为准: # c.Set(c.Deref((p)), v) 应先把 v 转换到 T,再按 T 宽度写入。 @@ -188,10 +169,10 @@ class CallGenCBuiltin(CallGenBase.CallGenBase): # c.Deref(uint32(p)) 被 0xFFFFFFFF(i64) 写成 8 字节(越界 4 字节)。 # 无类型指针(元素为 i8,如 t.CPtr/i8* 形参)维持原行为: # 按 RHS 类型重解释指针 store(如 paging save_count 写 i32)。 - store_ptr: rawptr[llvmlite.Value] = ptr_val - store_val: rawptr[llvmlite.Value] = b_val + store_ptr: llvmlite.Value* = ptr_val + store_val: llvmlite.Value* = b_val typed_elem: int = 0 - elem_ty: rawptr[llvmlite.LLVMType] = None + elem_ty: llvmlite.LLVMType* = None if ptr_val.Ty is not None: elem_ty = ptr_val.Ty.Pointee if elem_ty is not None: @@ -205,12 +186,10 @@ class CallGenCBuiltin(CallGenBase.CallGenBase): elif self.Gen.ExprGenBase.is_array_type(elem_ty) != 0: typed_elem = 1 if typed_elem != 0: - store_val = self.Gen.ExprGenBase.coerce_to_type( - builder, b_val, elem_ty, a_node) + store_val = self.Gen.ExprGenBase.coerce_to_type(builder, b_val, elem_ty, a_node) else: - val_ptr_ty: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, b_val.Ty) - casted_ptr: rawptr[llvmlite.Value] = llvmlite.build_bitcast( - builder, ptr_val, val_ptr_ty) + val_ptr_ty: llvmlite.LLVMType* = llvmlite.Ptr(pool, b_val.Ty) + casted_ptr: llvmlite.Value* = llvmlite.build_bitcast(builder, ptr_val, val_ptr_ty) if casted_ptr is not None: store_ptr = casted_ptr if store_ptr is not None and store_val is not None: @@ -221,39 +200,36 @@ class CallGenCBuiltin(CallGenBase.CallGenBase): # 形态 2: Name 变量赋值 if a_node is not None and a_node.kind() == ast.ASTKind.Name and trans is not None: - nm_set: rawptr[ast.Name] = rawptr[ast.Name](a_node) + nm_set: ast.Name* = ast.Name*(a_node) if nm_set.id is not None: if GenApi.is_global_name(trans, nm_set.id) != 0: - mod_alloca: rawptr[llvmlite.Value] = self.Gen.VarGen.lookup_module_var( - trans.SymTab, nm_set.id) + mod_alloca: 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 + tg_ty: llvmlite.LLVMType* = None if mod_alloca.Ty is not None: tg_ty = mod_alloca.Ty.Pointee - sv: rawptr[llvmlite.Value] = b_val + sv: 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: rawptr[llvmlite.Value] = self.Gen.StmtGenDecl.get_nonlocal_var_ptr( - trans, nm_set.id) + nl_ptr: 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 + nl_ty: llvmlite.LLVMType* = None if nl_ptr.Ty is not None: nl_ty = nl_ptr.Ty.Pointee - sv2: rawptr[llvmlite.Value] = b_val + sv2: 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: rawptr[llvmlite.Value] = self.Gen.VarGen.get_or_create_sym( - trans.SymTab, pool, builder, nm_set.id, b_val.Ty) + alloca: 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 + ac_ty: llvmlite.LLVMType* = None if alloca.Ty is not None: ac_ty = alloca.Ty.Pointee - sv3: rawptr[llvmlite.Value] = b_val + sv3: 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) @@ -262,13 +238,12 @@ class CallGenCBuiltin(CallGenBase.CallGenBase): # 形态 3: Attribute 字段赋值 if a_node is not None and a_node.kind() == ast.ASTKind.Attribute: - field_ptr: rawptr[llvmlite.Value] = self.Gen.ExprGenAttr.get_attribute_ptr( - builder, pool, mod, a_node, trans) + field_ptr: 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 + fd_ty: llvmlite.LLVMType* = None if field_ptr.Ty is not None: fd_ty = field_ptr.Ty.Pointee - sv4: rawptr[llvmlite.Value] = b_val + sv4: 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) @@ -277,11 +252,11 @@ class CallGenCBuiltin(CallGenBase.CallGenBase): return b_val - def translate_c_addr(self, pool: rawptr[memhub.MemBuddy], - builder: rawptr[llvmlite.IRBuilder], - mod: rawptr[llvmlite.LLVMModule], - cl: rawptr[ast.Call], - trans: rawptr[HT.Translator] = None) -> rawptr[llvmlite.Value]: + def translate_c_addr(self, pool: memhub.MemBuddy*, + builder: llvmlite.IRBuilder*, + mod: llvmlite.LLVMModule*, + cl: ast.Call*, + trans: HT.Translator* = None) -> llvmlite.Value*: """c.Addr(var) → 返回变量的 alloca 指针(不 load)""" if cl is None: return None @@ -289,27 +264,26 @@ class CallGenCBuiltin(CallGenBase.CallGenBase): if cargs is None or len(cargs) < 1: return None - arg0: rawptr[ast.AST] = cargs.get(0) + arg0: ast.AST* = cargs.get(0) if arg0 is None: return None # Name 形式: c.Addr(var) → 返回变量的 alloca 指针(不 load) if arg0.kind() == ast.ASTKind.Name: - nm: rawptr[ast.Name] = rawptr[ast.Name](arg0) + nm: ast.Name* = ast.Name*(arg0) if nm.id is None: return None if trans is not None: # 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: rawptr[GenTypes.VarEntry] = self.Gen.VarGen.lookup_var_entry( - trans.SymTab, nm.id) + self_entry: 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: case llvmlite.LLVMType.Ptr(inner1): match inner1: case llvmlite.LLVMType.Ptr(inner2): - obj_ty: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, inner2) + obj_ty: llvmlite.LLVMType* = llvmlite.Ptr(pool, inner2) return llvmlite.build_load(builder, obj_ty, self_entry.Alloca) case _: pass @@ -320,22 +294,20 @@ class CallGenCBuiltin(CallGenBase.CallGenBase): # 与普通局部 c.Addr(obj) 返回对象指针(load 一次)语义一致。 if trans is not None: if GenApi.is_nonlocal_name(trans, nm.id) != 0: - nl_addr: rawptr[llvmlite.Value] = self.Gen.StmtGenDecl.load_nonlocal_var( - trans, nm.id) + nl_addr: llvmlite.Value* = self.Gen.StmtGenDecl.load_nonlocal_var(trans, nm.id) if nl_addr is not None: return nl_addr - return_var: rawptr[llvmlite.Value] = self.Gen.VarGen.lookup_var(trans.SymTab, nm.id) + return_var: llvmlite.Value* = self.Gen.VarGen.lookup_var(trans.SymTab, nm.id) # REPL 模式(M2)会话变量取址:c.Addr(x) → ctx 内该槽的地址(地址同一性)。 # 位置在局部查找之后(片段自己声明的局部名优先,与读路径同序)、 # 模块全局/函数引用之前。守卫 trans.ReplCtx:非 REPL 恒 None ⇒ 不变。 if return_var is None and trans is not None and trans.ReplCtx is not None: - sess_addr: rawptr[llvmlite.Value] = self.Gen.VarGen.repl_try_addr( - trans, nm.id, arg0) + sess_addr: llvmlite.Value* = self.Gen.VarGen.repl_try_addr(trans, nm.id, arg0) if sess_addr is not None: return sess_addr 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: rawptr[llvmlite.GlobalVariable] = self.Gen.ExprGenAttr.find_global_in_module(mod, nm.id) + gv_ref_nm: 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)。 @@ -344,18 +316,17 @@ class CallGenCBuiltin(CallGenBase.CallGenBase): # Addr(uhci.vp L130、coroutine.vp L133 c.Addr(_coro_entry)、 # sched.vp L209 c.Addr(_thread_entry) 根因)。 if return_var is None and mod is not None: - f_addr_ref: rawptr[llvmlite.Function] = self.Gen.CallGenBase.find_func_in_module(mod, nm.id) + f_addr_ref: llvmlite.Function* = self.Gen.CallGenBase.find_func_in_module(mod, nm.id) 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: rawptr[llvmlite.Param] = llvmlite.function_get_param_head(f_addr_ref) + p_head_ca: llvmlite.Param* = llvmlite.function_get_param_head(f_addr_ref) p_cnt_ca: sizet = 0 - p_cur_ca: rawptr[llvmlite.Param] = p_head_ca + p_cur_ca: 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) - fn_ty_ca: rawptr[llvmlite.LLVMType] = llvmlite.Func( - pool, f_addr_ref.RetTy, p_head_ca, p_cnt_ca) + fn_ty_ca: llvmlite.LLVMType* = llvmlite.Func(pool, f_addr_ref.RetTy, p_head_ca, p_cnt_ca) # 函数引用名需按需加引号(数字开头/含 '.' 的 sha1 前缀名 # 必须 @\"...\",否则 llc "expected 'to' after cast value", # uhci.vp c.Addr(_on_int_complete) 根因)。 @@ -367,8 +338,7 @@ class CallGenCBuiltin(CallGenBase.CallGenBase): viperlib.snprintf(faddr_buf_ca, fnlen_ca + 4, "@\"%s\"", f_addr_name) else: viperlib.snprintf(faddr_buf_ca, fnlen_ca + 4, "@%s", f_addr_name) - return_var = llvmlite.SSAValue( - pool, llvmlite.Ptr(pool, fn_ty_ca), faddr_buf_ca) + return_var = llvmlite.SSAValue(pool, llvmlite.Ptr(pool, fn_ty_ca), faddr_buf_ca) # 闭包变量:c.Addr(闭包名) → 返回闭包对象指针(load 一次)。 # 闭包 alloca 是 i8**(存 {fn_ptr, env_ptr} 结构地址);不 load 的话 # 会把 &闭包指针变量(i8**)当对象地址传,回调侧按闭包结构读 @@ -376,8 +346,8 @@ class CallGenCBuiltin(CallGenBase.CallGenBase): # 变量 c.Addr(obj) load 一次的语义一致)。 if return_var is not None and return_var.Ty is not None: if self.Gen.CallGenLeafKit.is_closure_name(nm.id) != 0: - i8_ty_cb: rawptr[llvmlite.LLVMType] = llvmlite.Int8(pool) - i8_ptr_ty_cb: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, i8_ty_cb) + i8_ty_cb: llvmlite.LLVMType* = llvmlite.Int8(pool) + i8_ptr_ty_cb: llvmlite.LLVMType* = llvmlite.Ptr(pool, i8_ty_cb) return llvmlite.build_load(builder, i8_ptr_ty_cb, return_var) if return_var is not None and return_var.Ty is not None: # 对象指针变量(如 lit_tree = zhuff.zhuff_tree(),alloca 是 @@ -393,7 +363,7 @@ class CallGenCBuiltin(CallGenBase.CallGenBase): case llvmlite.LLVMType.Ptr(addr_inner2): match addr_inner2: case llvmlite.LLVMType.Struct(_, _, _): - addr_obj_ty: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, addr_inner2) + addr_obj_ty: llvmlite.LLVMType* = llvmlite.Ptr(pool, addr_inner2) return llvmlite.build_load(builder, addr_obj_ty, return_var) case _: pass @@ -408,30 +378,27 @@ class CallGenCBuiltin(CallGenBase.CallGenBase): if arg0.kind() == ast.ASTKind.Attribute: if trans is None: return None - at_addr: rawptr[ast.Attribute] = rawptr[ast.Attribute](arg0) + at_addr: ast.Attribute* = ast.Attribute*(arg0) if at_addr is None or at_addr.attr is None or at_addr.value is None: return None # 跨模块函数地址 c.Addr(serial.puts) → 函数符号本身(@sha1.puts):不可回退 ExprGenAttr 当全局变量处理,否则与 vpi 注入的 puts 函数 declare 同名冲突(llc "redefinition of function") if at_addr.value.kind() == ast.ASTKind.Name and trans is not None \ and trans._imported_modules is not None: - mod_nm2: rawptr[ast.Name] = rawptr[ast.Name](at_addr.value) + mod_nm2: ast.Name* = ast.Name*(at_addr.value) if mod_nm2.id is not None: - if self.Gen.ImportsGen.is_module_imported( - trans._imported_modules, mod_nm2.id) != 0: - f_ref2: rawptr[llvmlite.Function] = self.Gen.CallGenBase.find_func_in_module( - mod, at_addr.attr) + if self.Gen.ImportsGen.is_module_imported(trans._imported_modules, mod_nm2.id) != 0: + f_ref2: llvmlite.Function* = self.Gen.CallGenBase.find_func_in_module(mod, at_addr.attr) if f_ref2 is not None: 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: rawptr[llvmlite.Param] = llvmlite.function_get_param_head(f_ref2) + p_head2: llvmlite.Param* = llvmlite.function_get_param_head(f_ref2) p_cnt2: sizet = 0 - p_cur2: rawptr[llvmlite.Param] = p_head2 + p_cur2: llvmlite.Param* = p_head2 while p_cur2 is not None: p_cnt2 += 1 p_cur2 = llvmlite.param_get_next(p_cur2) - fn_ty2: rawptr[llvmlite.LLVMType] = llvmlite.Func( - pool, f_ref2.RetTy, p_head2, p_cnt2) + fn_ty2: llvmlite.LLVMType* = llvmlite.Func(pool, f_ref2.RetTy, p_head2, p_cnt2) # 函数引用名按需加引号(数字开头/含 '.' 的 # sha1 前缀名必须 @\"...\")。 fnlen2: sizet = string.strlen(fname2) @@ -442,51 +409,45 @@ class CallGenCBuiltin(CallGenBase.CallGenBase): viperlib.snprintf(faddr_buf2, fnlen2 + 4, "@\"%s\"", fname2) else: viperlib.snprintf(faddr_buf2, fnlen2 + 4, "@%s", fname2) - return llvmlite.SSAValue( - pool, llvmlite.Ptr(pool, fn_ty2), faddr_buf2) + return llvmlite.SSAValue(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: rawptr[llvmlite.GlobalVariable] = self.Gen.ExprGenAttr.find_global_in_module( - mod, at_addr.attr) + g_ref2: 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: rawptr[llvmlite.Value] = None - struct_ty: rawptr[llvmlite.LLVMType] = None + obj_ptr: llvmlite.Value* = None + struct_ty: llvmlite.LLVMType* = None if at_addr.value.kind() == ast.ASTKind.Subscript: # c.Addr(s.threads[0].rsp):base 是数组元素(Subscript)→ 先取 # 元素指针(GEP 数组),再 GEP 到字段。此前仅支持 Name base, # Subscript 落到下方 return None → 跌落跨模块函数调用生成 # call @Addr(sched.vp L90/L182/L188/L196、coroutine.vp # L99/L106/L112/L120 根因)。 - sub_base: rawptr[ast.Subscript] = rawptr[ast.Subscript](at_addr.value) + sub_base: ast.Subscript* = ast.Subscript*(at_addr.value) if sub_base.value is None or sub_base.slice is None: return None - bval: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( - builder, pool, mod, sub_base.value, None, 0, trans) - bidx: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( - builder, pool, mod, sub_base.slice, None, 0, trans) + bval: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, mod, sub_base.value, None, 0, trans) + bidx: 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 - bpointee: rawptr[llvmlite.LLVMType] = None + bpointee: llvmlite.LLVMType* = None if self.Gen.ExprGenBase.is_ptr_type(bval.Ty) != 0: bpointee = bval.Ty.Pointee if bpointee is not None: match bpointee: case llvmlite.LLVMType.Array(bet, _): - obj_ptr = llvmlite.build_gep_array( - builder, bpointee, bet, bval, bidx) + obj_ptr = llvmlite.build_gep_array(builder, bpointee, bet, bval, bidx) struct_ty = bet case _: return None else: return None elif at_addr.value.kind() == ast.ASTKind.Name: - self_nm: rawptr[ast.Name] = rawptr[ast.Name](at_addr.value) + self_nm: ast.Name* = ast.Name*(at_addr.value) if self_nm.id is None: return None - self_alloca: rawptr[llvmlite.Value] = self.Gen.VarGen.lookup_var( - trans.SymTab, self_nm.id) + self_alloca: 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 # 从 self 类型提取结构体类型(Ptr(Struct) 或 Ptr(Ptr(Struct))) @@ -504,20 +465,18 @@ class CallGenCBuiltin(CallGenBase.CallGenBase): # self_alloca 是 Ptr(Ptr(Struct)) 时先 load 成 Ptr(Struct) 对象指针 obj_ptr = self_alloca if self_is_ptr_ptr == 1: - self_obj_ty: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, struct_ty) + self_obj_ty: llvmlite.LLVMType* = llvmlite.Ptr(pool, struct_ty) obj_ptr = llvmlite.build_load(builder, self_obj_ty, self_alloca) else: return None if obj_ptr is None or struct_ty is None: return None # 查找字段 - fe_addr: rawptr[GenTypes.FieldEntry] = self.Gen.StructGen.lookup_field( - struct_ty, at_addr.attr) + fe_addr: GenTypes.FieldEntry* = self.Gen.StructGen.lookup_field(struct_ty, at_addr.attr) if fe_addr is None: return None # GEP 到字段地址 - return llvmlite.build_gep_struct( - builder, struct_ty, fe_addr.Ty, obj_ptr, fe_addr.Index) + return llvmlite.build_gep_struct(builder, struct_ty, fe_addr.Ty, obj_ptr, fe_addr.Index) # Subscript 形式: c.Addr(arr[i]) / c.Addr(a.b[i][j]) → 元素地址(GEP,不 load) # 统一走 get_subscript_ptr(递归处理嵌套下标、数组/指针/str|t.CPtr 形态)。 @@ -526,53 +485,39 @@ class CallGenCBuiltin(CallGenBase.CallGenBase): # 数组值([80 x i8])→ 非 Ptr → return None → 跌落跨模块函数调用生成 # call @Addr(ld.lld undefined symbol: Addr 根因)。 if arg0.kind() == ast.ASTKind.Subscript: - if trans is None: - return None - 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 + if trans is None: return None + elem_ptr_ca: llvmlite.Value* = self.Gen.ExprGenName.get_subscript_ptr(builder, pool, mod, arg0, trans) + if elem_ptr_ca is not None: return elem_ptr_ca # 兜底:单层数组基址 GEP(get_subscript_ptr 未命中的形态) - 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: 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: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( - builder, pool, mod, sub_addr.slice, None, 0, trans) - if idx_val is None: - return None - arr_pointee_ca: rawptr[llvmlite.LLVMType] = None + sub_addr: ast.Subscript* = 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* = 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* = self.Gen.ExprGen.translate_value(builder, pool, mod, sub_addr.slice, None, 0, trans) + if idx_val is None: return None + arr_pointee_ca: llvmlite.LLVMType* = None if self.Gen.ExprGenBase.is_ptr_type(arr_val.Ty) != 0: arr_pointee_ca = arr_val.Ty.Pointee if arr_pointee_ca is not None: match arr_pointee_ca: case llvmlite.LLVMType.Array(arr_et_ca, _): - return llvmlite.build_gep_array( - builder, arr_pointee_ca, arr_et_ca, arr_val, idx_val) + return llvmlite.build_gep_array(builder, arr_pointee_ca, arr_et_ca, arr_val, idx_val) case _: # 标量/指针元素(如字符串 a[4])→ 简单 GEP 元素地址。 # 此前仅 Array 走 GEP,标量 pointee 落 return None → # 跌落跨模块函数调用生成 call @Addr(main.vp L272 # c.Addr(a[4]) 根因)。 - return llvmlite.build_gep( - builder, arr_pointee_ca, arr_val, idx_val) + return llvmlite.build_gep(builder, arr_pointee_ca, arr_val, idx_val) return None # Call 形式: c.Addr(expr) → 求值 expr 存临时槽(entry alloca),返回槽地址 # 供就地解读使用:tt: Coroutine = c.Addr(task()) —— coerce 指针→结构体时 # 从槽地址 load(target 是 NoVTable 结构体,如 Coroutine={__ptr__} 8 字节)。 if arg0.kind() == ast.ASTKind.Call: - 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: rawptr[llvmlite.Value] = llvmlite.build_alloca_at_entry( - builder, call_val.Ty) - if tmp_slot is None: - return None + call_val: 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* = llvmlite.build_alloca_at_entry(builder, call_val.Ty) + if tmp_slot is None: return None llvmlite.build_store(builder, call_val, tmp_slot) return tmp_slot @@ -580,53 +525,38 @@ class CallGenCBuiltin(CallGenBase.CallGenBase): # c.Addr 是编译期指令,绝不跌落成运行时 call @Addr(ld.lld undefined # symbol: Addr 根因——未识别形态 return None 会被 translate_call 当作 # 普通函数调用处理)。 - self.Gen.TypeGenErr.fatal_error( - cl, f"c.Addr 不支持的操作数形式(kind={arg0.kind()})," - f"c.Addr 仅支持 变量/全局/函数/数组元素/字段", "TypeError") + self.Gen.TypeGenErr.fatal_error(cl, f"c.Addr 不支持的操作数形式(kind={arg0.kind()}),c.Addr 仅支持 变量/全局/函数/数组元素/字段", "TypeError") return None - def translate_c_load(self, pool: rawptr[memhub.MemBuddy], - builder: rawptr[llvmlite.IRBuilder], - mod: rawptr[llvmlite.LLVMModule], - cl: rawptr[ast.Call], - trans: rawptr[HT.Translator] = None) -> rawptr[llvmlite.Value]: + def translate_c_load(self, pool: memhub.MemBuddy*, + builder: llvmlite.IRBuilder*, + mod: llvmlite.LLVMModule*, + cl: ast.Call*, + trans: HT.Translator* = None) -> llvmlite.Value*: """c.Load(a, b) → *a = *b(加载 b 的值,存储到 a)""" - if cl is None: - return None + if cl is None: return None cargs: list[ast.AST*]* = cl.args - if cargs is None or len(cargs) < 2: - return None - - dst_ptr: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( - builder, pool, mod, cargs.get(0), None, 0, trans) - 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 - + if cargs is None or len(cargs) < 2: return None + dst_ptr: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, mod, cargs.get(0), None, 0, trans) + src_ptr: 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 # 确定 pointee 类型(优先用 src 的 pointee,回退到 dst 的 pointee) - pointee: rawptr[llvmlite.LLVMType] = None + pointee: llvmlite.LLVMType* = None if src_ptr.Ty is not None: pointee = src_ptr.Ty.Pointee if pointee is None and dst_ptr.Ty is not None: pointee = dst_ptr.Ty.Pointee - if pointee is None: - return None - + if pointee is None: return None # bitcast src 到 pointee* 并 load - target_ptr_ty: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, pointee) - src_cast: rawptr[llvmlite.Value] = llvmlite.build_bitcast(builder, src_ptr, target_ptr_ty) - if src_cast is None: - return None - loaded: rawptr[llvmlite.Value] = llvmlite.build_load(builder, pointee, src_cast) - if loaded is None: - return None - + target_ptr_ty: llvmlite.LLVMType* = llvmlite.Ptr(pool, pointee) + src_cast: llvmlite.Value* = llvmlite.build_bitcast(builder, src_ptr, target_ptr_ty) + if src_cast is None: return None + loaded: llvmlite.Value* = llvmlite.build_load(builder, pointee, src_cast) + if loaded is None: return None # bitcast dst 到 pointee* 并 store - dst_cast: rawptr[llvmlite.Value] = llvmlite.build_bitcast(builder, dst_ptr, target_ptr_ty) - if dst_cast is None: - return None + dst_cast: 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) return loaded @@ -648,9 +578,9 @@ class CallGenCBuiltin(CallGenBase.CallGenBase): dst[dlen + i] = '\0' - def _asm_mangle_global_symbols(self, pool: rawptr[memhub.MemBuddy], + def _asm_mangle_global_symbols(self, pool: memhub.MemBuddy*, asm_text: str, asm_size: sizet, - mod: rawptr[llvmlite.LLVMModule]) -> str: + mod: llvmlite.LLVMModule*) -> str: """asm 模板中裸符号引用模块全局的检查(fail-fast) 内联汇编 `lea rax, [rip + gdt]` 的 gdt 是汇编器符号,若对应模块全局 @@ -673,7 +603,7 @@ class CallGenCBuiltin(CallGenBase.CallGenBase): i: sizet = 0 while i < src_len: matched: int = 0 - cur: rawptr[llvmlite.GlobalVariable] = mod.GlobalHead + cur: 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: @@ -704,11 +634,7 @@ class CallGenCBuiltin(CallGenBase.CallGenBase): # 不可在 LLVM MC 内联汇编中使用(数字开头的符号名 # 会被解析成数字而报 "Unexpected offset"),必须 # 标记 t.CExport 使用裸名(如 gdt → @gdt)。 - self.Gen.TypeGenErr.fatal_error( - None, - f"asm 模板引用的全局符号 '{bare_g}' 带 SHA1 混淆头" - f"({gname}),内联汇编必须引用裸名符号,请将该" - f"全局定义标记为 t.CExport", "TypeError") + self.Gen.TypeGenErr.fatal_error(None, f"asm 模板引用的全局符号 '{bare_g}' 带 SHA1 混淆头({gname}),内联汇编必须引用裸名符号,请将该全局定义标记为 t.CExport", "TypeError") return asm_text cur = cur.Next if matched == 0: @@ -720,7 +646,7 @@ class CallGenCBuiltin(CallGenBase.CallGenBase): return out - def _asm_escape_for_ir(self, pool: rawptr[memhub.MemBuddy], + def _asm_escape_for_ir(self, pool: memhub.MemBuddy*, src: str) -> str: """转义汇编文本用于 LLVM IR 字符串字面量""" if src is None: @@ -855,8 +781,8 @@ class CallGenCBuiltin(CallGenBase.CallGenBase): return "" - def _resolve_asm_descr(self, pool: rawptr[memhub.MemBuddy], - node: rawptr[ast.AST]) -> str: + def _resolve_asm_descr(self, pool: memhub.MemBuddy*, + node: ast.AST*) -> str: """递归解析约束表达式,返回约束字符串""" if node is None: return "" @@ -865,7 +791,7 @@ class CallGenCBuiltin(CallGenBase.CallGenBase): # BinOp with BitOr: 拼接左右 if k == ast.ASTKind.BinOp: - bop: rawptr[ast.BinOp] = rawptr[ast.BinOp](node) + bop: ast.BinOp* = ast.BinOp*(node) if bop.op == ast.OpKind.BitOr: left_str: str = self._resolve_asm_descr(pool, bop.left) right_str: str = self._resolve_asm_descr(pool, bop.right) @@ -883,25 +809,25 @@ class CallGenCBuiltin(CallGenBase.CallGenBase): # Attribute: t.ASM_DESCR.XXX 或 t.XXX if k == ast.ASTKind.Attribute: - at: rawptr[ast.Attribute] = rawptr[ast.Attribute](node) + at: ast.Attribute* = ast.Attribute*(node) # t.ASM_DESCR.XXX if at.value is not None and at.value.kind() == ast.ASTKind.Attribute: - inner: rawptr[ast.Attribute] = rawptr[ast.Attribute](at.value) + inner: ast.Attribute* = ast.Attribute*(at.value) if inner.value is not None and inner.value.kind() == ast.ASTKind.Name: - mod_nm: rawptr[ast.Name] = rawptr[ast.Name](inner.value) + mod_nm: ast.Name* = ast.Name*(inner.value) if mod_nm.id is not None and string.strcmp(mod_nm.id, "t") == 0: if inner.attr is not None and string.strcmp(inner.attr, "ASM_DESCR") == 0: return self._resolve_register(at.attr) # t.XXX 简化形式 if at.value is not None and at.value.kind() == ast.ASTKind.Name: - mod_nm2: rawptr[ast.Name] = rawptr[ast.Name](at.value) + mod_nm2: ast.Name* = ast.Name*(at.value) if mod_nm2.id is not None and string.strcmp(mod_nm2.id, "t") == 0: return self._resolve_register(at.attr) return "" # Constant: 字符串常量 if k == ast.ASTKind.Constant: - cn: rawptr[ast.Constant] = rawptr[ast.Constant](node) + cn: ast.Constant* = ast.Constant*(node) if cn.const_kind == ast.CONST_STR: return cn.str_val return "" @@ -917,16 +843,16 @@ class CallGenCBuiltin(CallGenBase.CallGenBase): return rawptr[GenTypes.AsmOperand](entry_addr) - def _asm_is_c_call(self, node: rawptr[ast.Call]) -> str: + def _asm_is_c_call(self, node: ast.Call*) -> str: """检查 Call 节点是否是 c.XXX 调用,返回属性名或 None""" if node is None or node.func is None: return None if node.func.kind() != ast.ASTKind.Attribute: return None - at: rawptr[ast.Attribute] = rawptr[ast.Attribute](node.func) + at: ast.Attribute* = ast.Attribute*(node.func) if at.value is None or at.value.kind() != ast.ASTKind.Name: return None - mod_nm: rawptr[ast.Name] = rawptr[ast.Name](at.value) + mod_nm: ast.Name* = ast.Name*(at.value) if mod_nm.id is None or string.strcmp(mod_nm.id, "c") != 0: return None return at.attr @@ -956,7 +882,7 @@ class CallGenCBuiltin(CallGenBase.CallGenBase): def _asm_add_operand(self, operands: rawptr[GenTypes.AsmOperand], count: int, - val: rawptr[llvmlite.Value], + val: llvmlite.Value*, constraint: str, is_output: int) -> int: """添加操作数到数组,返回新计数(失败返回原计数) @@ -973,11 +899,7 @@ class CallGenCBuiltin(CallGenBase.CallGenBase): # 且裸机链接要求裸名 —— 必须将对应定义标记为 t.CExport。 if val is not None and val.Name is not None: if self._asm_name_is_mangled(val.Name) != 0: - self.Gen.TypeGenErr.fatal_error( - None, - f"c.Asm 操作数(AsmInp/AsmOut)不允许带 SHA1 混淆头的符号 " - f"'{val.Name}',请将对应函数/全局定义标记为 t.CExport(裸名)", - "TypeError") + self.Gen.TypeGenErr.fatal_error(None, f"c.Asm 操作数(AsmInp/AsmOut)不允许带 SHA1 混淆头的符号 '{val.Name}',请将对应函数/全局定义标记为 t.CExport(裸名)", "TypeError") if val is not None: for ei in range(count): eop: rawptr[GenTypes.AsmOperand] = self._asm_get_operand(operands, ei) @@ -1000,11 +922,11 @@ class CallGenCBuiltin(CallGenBase.CallGenBase): return count + 1 - def translate_c_asm(self, pool: rawptr[memhub.MemBuddy], - builder: rawptr[llvmlite.IRBuilder], - mod: rawptr[llvmlite.LLVMModule], - cl: rawptr[ast.Call], - trans: rawptr[HT.Translator] = None) -> rawptr[llvmlite.Value]: + def translate_c_asm(self, pool: memhub.MemBuddy*, + builder: llvmlite.IRBuilder*, + mod: llvmlite.LLVMModule*, + cl: ast.Call*, + trans: HT.Translator* = None) -> llvmlite.Value*: """翻译 c.Asm 内联汇编,返回结果 Value(无输出时返回 None)""" if cl is None: return None @@ -1041,10 +963,10 @@ class CallGenCBuiltin(CallGenBase.CallGenBase): # 首个输出操作数的元素类型缓存(对齐 python 参考 HandlesExprAsm 的 # "收集时即定 ret 类型":不依赖事后从 pool 槽二次读回 Value.Ty.Pointee, # 避免读回不稳定 → ret 静默 Void → 带名 void asm(atom.vp 根因)。 - out_ret_ty_first: rawptr[llvmlite.LLVMType] = None + out_ret_ty_first: llvmlite.LLVMType* = None # 全量输出元素类型按序缓存(多输出如 vrandom rdrand*_step 的 val+ok): # 同样在收集时直接从 alloca 取 Pointee,绕开 AsmOperand 槽读不稳定。 - out_ptys: sizet | t.CPtr = pool.alloc(8 * ASM_MAX_OPERANDS) + out_ptys: sizet* = pool.alloc(8 * ASM_MAX_OPERANDS) out_pty_n: int = 0 if out_ptys is not None: string.memset(out_ptys, 0, 8 * ASM_MAX_OPERANDS) @@ -1059,7 +981,7 @@ class CallGenCBuiltin(CallGenBase.CallGenBase): # 1. 解析汇编模板(JoinedStr 或 Constant)— 第一遍:收集操作数 # 不生成 asm 文本(占位符 $N 需在重排后才能确定编号) # ============================================================ - tmpl_node: rawptr[ast.AST] = cargs.get(0) + tmpl_node: ast.AST* = cargs.get(0) if tmpl_node is not None: tk: int = tmpl_node.kind() @@ -1069,17 +991,17 @@ class CallGenCBuiltin(CallGenBase.CallGenBase): if jvalues is not None: jvlen: sizet = len(jvalues) for vi in range(jvlen): - part: rawptr[ast.AST] = jvalues.get(vi) + part: ast.AST* = jvalues.get(vi) if part is None: continue pk: int = part.kind() if pk == ast.ASTKind.FormattedValue: fv: rawptr[ast.FormattedValue] = rawptr[ast.FormattedValue](part) - fexpr: rawptr[ast.AST] = fv.value + fexpr: ast.AST* = fv.value if fexpr is None or fexpr.kind() != ast.ASTKind.Call: continue - fcall: rawptr[ast.Call] = rawptr[ast.Call](fexpr) + fcall: ast.Call* = ast.Call*(fexpr) attr_nm: str = self._asm_is_c_call(fcall) if attr_nm is None: continue @@ -1096,7 +1018,7 @@ class CallGenCBuiltin(CallGenBase.CallGenBase): if fargs is None or len(fargs) < 1: continue - val_node: rawptr[ast.AST] = fargs.get(0) + val_node: ast.AST* = fargs.get(0) cons_str: str = "" if len(fargs) >= 2: cons_str = self._resolve_asm_descr(pool, fargs.get(1)) @@ -1106,9 +1028,9 @@ class CallGenCBuiltin(CallGenBase.CallGenBase): # Attribute 字段地址) if val_node is None: continue - alloca: rawptr[llvmlite.Value] = None + alloca: llvmlite.Value* = None if val_node.kind() == ast.ASTKind.Name: - nm: rawptr[ast.Name] = rawptr[ast.Name](val_node) + nm: ast.Name* = ast.Name*(val_node) if nm.id is None: continue alloca = self.Gen.VarGen.lookup_var(trans.SymTab, nm.id) @@ -1125,15 +1047,14 @@ class CallGenCBuiltin(CallGenBase.CallGenBase): # GEP 到字段地址(对齐 translate_c_addr Attribute # 分支)。仅 Name 检查时 Attribute 被跳过 → # 空操作数 "mov , cr3"(process.vp L127/L208 根因)。 - at_a: rawptr[ast.Attribute] = rawptr[ast.Attribute](val_node) + at_a: ast.Attribute* = ast.Attribute*(val_node) if at_a.attr is not None and at_a.value is not None \ and at_a.value.kind() == ast.ASTKind.Name: - base_nm_a: rawptr[ast.Name] = rawptr[ast.Name](at_a.value) + base_nm_a: ast.Name* = ast.Name*(at_a.value) if base_nm_a.id is not None: - base_alloca_a: rawptr[llvmlite.Value] = self.Gen.VarGen.lookup_var( - trans.SymTab, base_nm_a.id) + base_alloca_a: 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 + struct_ty_a: llvmlite.LLVMType* = None self_is_ptr_ptr_a: int = 0 match base_alloca_a.Ty: case llvmlite.LLVMType.Ptr(inner1): @@ -1146,36 +1067,27 @@ class CallGenCBuiltin(CallGenBase.CallGenBase): case _: pass if struct_ty_a is not None: - fe_a: rawptr[GenTypes.FieldEntry] = self.Gen.StructGen.lookup_field( - struct_ty_a, at_a.attr) + fe_a: GenTypes.FieldEntry* = self.Gen.StructGen.lookup_field(struct_ty_a, at_a.attr) if fe_a is not None: - obj_ptr_a: rawptr[llvmlite.Value] = base_alloca_a + obj_ptr_a: 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) + obj_ptr_a = llvmlite.build_load(builder, llvmlite.Ptr(pool, struct_ty_a), base_alloca_a) if obj_ptr_a is not None: - alloca = llvmlite.build_gep_struct( - builder, struct_ty_a, fe_a.Ty, obj_ptr_a, fe_a.Index) + alloca = llvmlite.build_gep_struct(builder, struct_ty_a, fe_a.Ty, obj_ptr_a, fe_a.Index) if alloca is None: continue - operand_count = self._asm_add_operand( - operands, operand_count, alloca, cons_str, 1) - if out_ret_ty_first is None and alloca is not None \ - and alloca.Ty is not None and alloca.Ty.Pointee is not None: + operand_count = self._asm_add_operand(operands, operand_count, alloca, cons_str, 1) + if out_ret_ty_first is None and alloca is not None and alloca.Ty is not None and alloca.Ty.Pointee != 0: out_ret_ty_first = alloca.Ty.Pointee - if out_ptys is not None and out_pty_n < ASM_MAX_OPERANDS \ - and alloca is not None and alloca.Ty is not None \ - and alloca.Ty.Pointee is not None: + if out_ptys is not None and out_pty_n < ASM_MAX_OPERANDS and alloca is not None and alloca.Ty is not None and alloca.Ty.Pointee != 0: out_ptys[out_pty_n] = uint64(alloca.Ty.Pointee) out_pty_n += 1 else: # 输入:翻译值 - ival: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( - builder, pool, mod, val_node, None, 0, trans) + ival: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, mod, val_node, None, 0, trans) if ival is None: continue - operand_count = self._asm_add_operand( - operands, operand_count, ival, cons_str, 0) + operand_count = self._asm_add_operand(operands, operand_count, ival, cons_str, 0) # 记录 fv 的原始操作数索引 if fv_count < ASM_MAX_OPERANDS: @@ -1196,94 +1108,70 @@ class CallGenCBuiltin(CallGenBase.CallGenBase): if string.strcmp(kw.arg, "out") == 0: # 输出操作数列表 - if kwk != ast.ASTKind.List: - continue - out_lst: rawptr[ast.List] = rawptr[ast.List](kw.value) + if kwk != ast.ASTKind.List: continue + out_lst: ast.List* = ast.List*(kw.value) out_elts: list[ast.AST*]* = out_lst.elts - if out_elts is None: - continue + if out_elts is None: continue oelen: sizet = len(out_elts) for oi in range(oelen): - oelt: rawptr[ast.AST] = out_elts.get(oi) - if oelt is None or oelt.kind() != ast.ASTKind.Call: - continue - ocall: rawptr[ast.Call] = rawptr[ast.Call](oelt) + oelt: ast.AST* = out_elts.get(oi) + if oelt is None or oelt.kind() != ast.ASTKind.Call: continue + ocall: ast.Call* = ast.Call*(oelt) oattr: str = self._asm_is_c_call(ocall) - if oattr is None or string.strcmp(oattr, "AsmOut") != 0: - continue + if oattr is None or string.strcmp(oattr, "AsmOut") != 0: continue oargs: list[ast.AST*]* = ocall.args - if oargs is None or len(oargs) < 1: - continue - oval_node: rawptr[ast.AST] = oargs.get(0) + if oargs is None or len(oargs) < 1: continue + oval_node: ast.AST* = oargs.get(0) ocons: str = "" if len(oargs) >= 2: ocons = self._resolve_asm_descr(pool, oargs.get(1)) - if oval_node is None or oval_node.kind() != ast.ASTKind.Name: - continue - onm: rawptr[ast.Name] = rawptr[ast.Name](oval_node) - if onm.id is None: - continue - oalloca: rawptr[llvmlite.Value] = self.Gen.VarGen.lookup_var(trans.SymTab, onm.id) - if oalloca is None: - continue - operand_count = self._asm_add_operand( - operands, operand_count, oalloca, ocons, 1) - if out_ret_ty_first is None and oalloca is not None \ - and oalloca.Ty is not None and oalloca.Ty.Pointee is not None: + if oval_node is None or oval_node.kind() != ast.ASTKind.Name: continue + onm: ast.Name* = ast.Name*(oval_node) + if onm.id is None: continue + oalloca: llvmlite.Value* = self.Gen.VarGen.lookup_var(trans.SymTab, onm.id) + if oalloca is None: continue + operand_count = self._asm_add_operand(operands, operand_count, oalloca, ocons, 1) + if out_ret_ty_first is None and oalloca is not None and oalloca.Ty is not None and oalloca.Ty.Pointee != 0: out_ret_ty_first = oalloca.Ty.Pointee - if out_ptys is not None and out_pty_n < ASM_MAX_OPERANDS \ - and oalloca is not None and oalloca.Ty is not None \ - and oalloca.Ty.Pointee is not None: + if out_ptys is not None and out_pty_n < ASM_MAX_OPERANDS and oalloca is not None and oalloca.Ty is not None and oalloca.Ty.Pointee != 0: out_ptys[out_pty_n] = uint64(oalloca.Ty.Pointee) out_pty_n += 1 elif string.strcmp(kw.arg, "inp") == 0 or string.strcmp(kw.arg, "inputs") == 0: # 输入操作数列表 - if kwk != ast.ASTKind.List: - continue - in_lst: rawptr[ast.List] = rawptr[ast.List](kw.value) + if kwk != ast.ASTKind.List: continue + in_lst: ast.List* = ast.List*(kw.value) in_elts: list[ast.AST*]* = in_lst.elts - if in_elts is None: - continue + if in_elts is None: continue ielen: sizet = len(in_elts) for ii in range(ielen): - ielt: rawptr[ast.AST] = in_elts.get(ii) - if ielt is None or ielt.kind() != ast.ASTKind.Call: - continue - icall: rawptr[ast.Call] = rawptr[ast.Call](ielt) + ielt: ast.AST* = in_elts.get(ii) + if ielt is None or ielt.kind() != ast.ASTKind.Call: continue + icall: ast.Call* = ast.Call*(ielt) iattr: str = self._asm_is_c_call(icall) - if iattr is None or string.strcmp(iattr, "AsmInp") != 0: - continue + if iattr is None or string.strcmp(iattr, "AsmInp") != 0: continue iargs: list[ast.AST*]* = icall.args - if iargs is None or len(iargs) < 1: - continue - ival_node: rawptr[ast.AST] = iargs.get(0) + if iargs is None or len(iargs) < 1: continue + ival_node: ast.AST* = iargs.get(0) icons: str = "" if len(iargs) >= 2: icons = self._resolve_asm_descr(pool, iargs.get(1)) - ival2: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( - builder, pool, mod, ival_node, None, 0, trans) - if ival2 is None: - continue - operand_count = self._asm_add_operand( - operands, operand_count, ival2, icons, 0) + ival2: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, mod, ival_node, None, 0, trans) + if ival2 is None: continue + operand_count = self._asm_add_operand(operands, operand_count, ival2, icons, 0) elif string.strcmp(kw.arg, "op") == 0 or string.strcmp(kw.arg, "clobber") == 0: # 破坏列表 - if kwk != ast.ASTKind.List: - continue - cl_lst: rawptr[ast.List] = rawptr[ast.List](kw.value) + if kwk != ast.ASTKind.List: continue + cl_lst: ast.List* = ast.List*(kw.value) cl_elts: list[ast.AST*]* = cl_lst.elts - if cl_elts is None: - continue + if cl_elts is None: continue clen: sizet = len(cl_elts) for ci in range(clen): - celt: rawptr[ast.AST] = cl_elts.get(ci) - if celt is None: - continue + celt: ast.AST* = cl_elts.get(ci) + if celt is None: continue cstr: str = self._resolve_asm_descr(pool, celt) - if cstr is None or cstr[0] == '\0': - continue + if cstr is None or cstr[0] == '\0': continue if clobber_count < ASM_MAX_CLOBBERS: cl_addr: uint64 = uint64(clobbers) + clobber_count * 8 cl_ptr: str | t.CPtr = (str | t.CPtr)(cl_addr) @@ -1294,19 +1182,17 @@ class CallGenCBuiltin(CallGenBase.CallGenBase): # 3. 解析第二个位置参数作为破坏列表 # ============================================================ if len(cargs) >= 2: - pos_node: rawptr[ast.AST] = cargs.get(1) + pos_node: ast.AST* = cargs.get(1) if pos_node is not None and pos_node.kind() == ast.ASTKind.List: - pos_lst: rawptr[ast.List] = rawptr[ast.List](pos_node) + pos_lst: ast.List* = ast.List*(pos_node) pos_elts: list[ast.AST*]* = pos_lst.elts if pos_elts is not None: plen: sizet = len(pos_elts) for pi in range(plen): - pelt: rawptr[ast.AST] = pos_elts.get(pi) - if pelt is None: - continue + pelt: ast.AST* = pos_elts.get(pi) + if pelt is None: continue pstr: str = self._resolve_asm_descr(pool, pelt) - if pstr is None or pstr[0] == '\0': - continue + if pstr is None or pstr[0] == '\0': continue if clobber_count < ASM_MAX_CLOBBERS: pcl_addr: uint64 = uint64(clobbers) + clobber_count * 8 pcl_ptr: str | t.CPtr = (str | t.CPtr)(pcl_addr) @@ -1332,28 +1218,28 @@ class CallGenCBuiltin(CallGenBase.CallGenBase): # 多输出(如 vrandom rdrand*_step 的 val+ok 两个 AsmOut)返回 # 匿名 struct {ty1, ty2, ...},元素数 = 输出操作数(LLVM asm # 要求输出约束数 = 返回 struct 元素数)。 - ret_ty: rawptr[llvmlite.LLVMType] = llvmlite.Void(pool) + ret_ty: llvmlite.LLVMType* = llvmlite.Void(pool) if output_count > 0 and first_output_idx >= 0: if output_count > 1: - out_pn_head: rawptr[llvmlite.Function] = None - out_pn_last: rawptr[llvmlite.Function] = None + out_pn_head: llvmlite.Function* = None + out_pn_last: llvmlite.Function* = None out_pn_n: int = 0 out_seq: int = 0 for oi5 in range(operand_count): op5: rawptr[GenTypes.AsmOperand] = self._asm_get_operand(operands, oi5) if op5 is None or op5.IsOutput == 0: continue - pty5: rawptr[llvmlite.LLVMType] = None + pty5: llvmlite.LLVMType* = None # 优先收集时按序缓存的直接类型,再回退从槽读回 if out_ptys is not None and out_seq < out_pty_n: - pty5 = (rawptr[llvmlite.LLVMType])(out_ptys[out_seq]) + pty5 = (llvmlite.LLVMType*)(out_ptys[out_seq]) elif op5.Value is not None and op5.Value.Ty is not None \ - and op5.Value.Ty.Pointee is not None: + and op5.Value.Ty.Pointee != 0: pty5 = op5.Value.Ty.Pointee out_seq += 1 if pty5 is None: continue - pn5: rawptr[llvmlite.Function] = llvmlite.new_param_node(pool, pty5) + pn5: llvmlite.Function* = llvmlite.new_param_node(pool, pty5) if pn5 is not None: if out_pn_head is None: out_pn_head = pn5 @@ -1364,23 +1250,21 @@ class CallGenCBuiltin(CallGenBase.CallGenBase): if out_pn_head is not None and out_pn_n > 0: ret_ty = llvmlite.Struct(pool, out_pn_head, out_pn_n, None) else: - self.Gen.TypeGenErr.fatal_error( - cl, "c.Asm 输出操作数类型缺失(变量 alloca 类型退化)", "TypeError") + self.Gen.TypeGenErr.fatal_error(cl, "c.Asm 输出操作数类型缺失(变量 alloca 类型退化)", "TypeError") ret_ty = llvmlite.Int32(pool) else: out_op: rawptr[GenTypes.AsmOperand] = self._asm_get_operand(operands, first_output_idx) - out_pt: rawptr[llvmlite.LLVMType] = None + out_pt: llvmlite.LLVMType* = None # 优先用收集时缓存的元素类型(对齐 python 参考),再回退从槽读回 if out_ret_ty_first is not None: out_pt = out_ret_ty_first elif out_op is not None and out_op.Value is not None \ - and out_op.Value.Ty is not None and out_op.Value.Ty.Pointee is not None: + and out_op.Value.Ty is not None and out_op.Value.Ty.Pointee != 0: out_pt = out_op.Value.Ty.Pointee if out_pt is not None: ret_ty = out_pt else: - self.Gen.TypeGenErr.fatal_error( - cl, "c.Asm 输出操作数类型缺失(变量 alloca 类型退化)", "TypeError") + self.Gen.TypeGenErr.fatal_error(cl, "c.Asm 输出操作数类型缺失(变量 alloca 类型退化)", "TypeError") ret_ty = llvmlite.Int32(pool) # 判断 void — 直接基于 output_count 判断,避免 match 类型匹配问题 @@ -1396,19 +1280,15 @@ class CallGenCBuiltin(CallGenBase.CallGenBase): if is_void == 0: match ret_ty: case llvmlite.LLVMType.Void(): - ret_re: rawptr[llvmlite.LLVMType] = None + ret_re: llvmlite.LLVMType* = None for re_i in range(operand_count): - re_op: rawptr[GenTypes.AsmOperand] = self._asm_get_operand( - operands, re_i) - if re_op is None or re_op.IsOutput == 0: - continue - if re_op.Value is not None and re_op.Value.Ty is not None \ - and re_op.Value.Ty.Pointee is not None: + re_op: rawptr[GenTypes.AsmOperand] = self._asm_get_operand(operands, re_i) + if re_op is None or re_op.IsOutput == 0: continue + if re_op.Value is not None and re_op.Value.Ty is not None and re_op.Value.Ty.Pointee != 0: ret_re = re_op.Value.Ty.Pointee break if ret_re is None: - self.Gen.TypeGenErr.fatal_error( - cl, "c.Asm 输出操作数类型缺失(变量 alloca 类型退化)", "TypeError") + self.Gen.TypeGenErr.fatal_error(cl, "c.Asm 输出操作数类型缺失(变量 alloca 类型退化)", "TypeError") ret_ty = ret_re case _: pass @@ -1454,12 +1334,12 @@ class CallGenCBuiltin(CallGenBase.CallGenBase): jvlen2: sizet = len(jvalues2) fv_fi: int = 0 for vi2 in range(jvlen2): - part2: rawptr[ast.AST] = jvalues2.get(vi2) + part2: ast.AST* = jvalues2.get(vi2) if part2 is None: continue pk2: int = part2.kind() if pk2 == ast.ASTKind.Constant: - cn3: rawptr[ast.Constant] = rawptr[ast.Constant](part2) + cn3: ast.Constant* = ast.Constant*(part2) if cn3.const_kind == ast.CONST_STR and cn3.str_val is not None: self._asm_append_cstr(asm_text, ASM_TEXT_BUF_SIZE, cn3.str_val) elif pk2 == ast.ASTKind.FormattedValue: @@ -1472,7 +1352,7 @@ class CallGenCBuiltin(CallGenBase.CallGenBase): self._asm_append_cstr(asm_text, ASM_TEXT_BUF_SIZE, ph_buf2) fv_fi += 1 elif tk2 == ast.ASTKind.Constant: - cn4: rawptr[ast.Constant] = rawptr[ast.Constant](tmpl_node) + cn4: ast.Constant* = ast.Constant*(tmpl_node) if cn4.const_kind == ast.CONST_STR and cn4.str_val is not None: self._asm_append_cstr(asm_text, ASM_TEXT_BUF_SIZE, cn4.str_val) @@ -1529,11 +1409,9 @@ class CallGenCBuiltin(CallGenBase.CallGenBase): for ai3 in range(operand_count): orig_i2: int = new_order[ai3] aop: rawptr[GenTypes.AsmOperand] = self._asm_get_operand(operands, orig_i2) - if aop.IsOutput != 0: - continue - aval: rawptr[llvmlite.Value] = aop.Value - if aval is None or aval.Ty is None or aval.Name is None: - continue + if aop.IsOutput != 0: continue + aval: llvmlite.Value* = aop.Value + if aval is None or aval.Ty is None or aval.Name is None: continue if first_arg == 0: self._asm_append_cstr(args_buf, ASM_ARGS_BUF_SIZE, ", ") @@ -1551,20 +1429,17 @@ class CallGenCBuiltin(CallGenBase.CallGenBase): # ============================================================ # 7. 转义汇编文本 # 7.0 先做裸符号→混淆名替换(lea rax, [rip + gdt] → [rip + 054f5e56cbefcaa4.gdt]) - mangled_asm: str = self._asm_mangle_global_symbols( - pool, asm_text, ASM_TEXT_BUF_SIZE, mod) + mangled_asm: str = self._asm_mangle_global_symbols(pool, asm_text, ASM_TEXT_BUF_SIZE, mod) if mangled_asm is None: mangled_asm = asm_text escaped_asm: str = self._asm_escape_for_ir(pool, mangled_asm) - if escaped_asm is None: - return None + if escaped_asm is None: return None # ============================================================ # 8. 生成 IR 行并发射 # ============================================================ line: str = pool.alloc(ASM_LINE_BUF_SIZE) - if line is None: - return None + if line is None: return None line[0] = '\0' ssa_name: str = None @@ -1596,7 +1471,7 @@ class CallGenCBuiltin(CallGenBase.CallGenBase): # 9. 处理输出:存储结果到输出变量 # ============================================================ if is_void == 0 and first_output_idx >= 0: - result_val: rawptr[llvmlite.Value] = llvmlite.SSAValue(pool, ret_ty, ssa_name) + result_val: 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] @@ -1606,7 +1481,7 @@ class CallGenCBuiltin(CallGenBase.CallGenBase): if output_count > 1: # 多输出:extractvalue 取第 out_emit_idx 个元素后 store if oo.Value is not None and oo.Value.Ty is not None \ - and oo.Value.Ty.Pointee is not None: + and oo.Value.Ty.Pointee != 0: ev_name: str = pool.alloc(32) ev_line: str = pool.alloc(ASM_LINE_BUF_SIZE) if ev_name is not None and ev_line is not None: @@ -1618,8 +1493,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: rawptr[llvmlite.Value] = llvmlite.SSAValue( - pool, oo.Value.Ty.Pointee, ev_name) + ev_val: llvmlite.Value* = llvmlite.SSAValue(pool, oo.Value.Ty.Pointee, ev_name) llvmlite.build_store(builder, ev_val, oo.Value) else: if oo.Value is not None: @@ -1630,11 +1504,11 @@ class CallGenCBuiltin(CallGenBase.CallGenBase): return None - def translate_c_llvmir(self, pool: rawptr[memhub.MemBuddy], - builder: rawptr[llvmlite.IRBuilder], - mod: rawptr[llvmlite.LLVMModule], - cl: rawptr[ast.Call], - trans: rawptr[HT.Translator] = None) -> rawptr[llvmlite.Value]: + def translate_c_llvmir(self, pool: memhub.MemBuddy*, + builder: llvmlite.IRBuilder*, + mod: llvmlite.LLVMModule*, + cl: ast.Call*, + trans: HT.Translator* = None) -> llvmlite.Value*: """c.LLVMIR 内联 LLVM IR:无返回值,直接嵌入原始 IR 文本 不做指令解析,模板文本(c.LInp/c.LOut 替换后)用 block_append_text @@ -1649,8 +1523,8 @@ class CallGenCBuiltin(CallGenBase.CallGenBase): self.Gen.TypeGenErr.fatal_error(cl, "c.LLVMIR 缺少模板参数", "TypeError") # LOut 写回记录(alloca 指针 + 寄存器名),最多 LLVMIR_MAX_OPS 个 - out_alloca: sizet | t.CPtr = pool.alloc(8 * LLVMIR_MAX_OPS) - out_regname: sizet | t.CPtr = pool.alloc(8 * LLVMIR_MAX_OPS) + out_alloca: sizet* = pool.alloc(8 * LLVMIR_MAX_OPS) + out_regname: sizet* = pool.alloc(8 * LLVMIR_MAX_OPS) if out_alloca is None or out_regname is None: return None string.memset(out_alloca, 0, 8 * LLVMIR_MAX_OPS) @@ -1666,7 +1540,7 @@ class CallGenCBuiltin(CallGenBase.CallGenBase): # ============================================================ # 1. 解析 IR 模板(JoinedStr 或 Constant)— 替换 LInp/LOut/表达式为值文本 # ============================================================ - first_arg: rawptr[ast.AST] = cargs.get(0) + first_arg: ast.AST* = cargs.get(0) if first_arg is None: return None @@ -1678,36 +1552,35 @@ class CallGenCBuiltin(CallGenBase.CallGenBase): if jvalues is not None: jvlen: sizet = len(jvalues) for vi in range(jvlen): - part: rawptr[ast.AST] = jvalues.get(vi) + part: ast.AST* = jvalues.get(vi) if part is None: continue pk: int = part.kind() if pk == ast.ASTKind.Constant: # 字符串字面量片段 - cn: rawptr[ast.Constant] = rawptr[ast.Constant](part) + cn: ast.Constant* = ast.Constant*(part) if cn.str_val is not None: self._asm_append_cstr(text, LLVMIR_TEMPLATE_BUF, cn.str_val) elif pk == ast.ASTKind.FormattedValue: fv: rawptr[ast.FormattedValue] = rawptr[ast.FormattedValue](part) - fexpr: rawptr[ast.AST] = fv.value + fexpr: ast.AST* = fv.value if fexpr is None: continue # 检测 c.LInp / c.LOut if fexpr.kind() == ast.ASTKind.Call: - fcall: rawptr[ast.Call] = rawptr[ast.Call](fexpr) + fcall: ast.Call* = ast.Call*(fexpr) attr_nm: str = self._asm_is_c_call(fcall) if attr_nm is not None: fargs: list[ast.AST*]* = fcall.args if fargs is None or len(fargs) < 1: continue - val_node: rawptr[ast.AST] = fargs.get(0) + val_node: ast.AST* = fargs.get(0) if string.strcmp(attr_nm, "LInp") == 0: # 输入操作数:翻译值,替换为 LLVM 值引用文本(%x 或常量文本) - inp_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( - builder, pool, mod, val_node, None, 0, trans) + inp_val: 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) @@ -1715,15 +1588,11 @@ class CallGenCBuiltin(CallGenBase.CallGenBase): # 输出操作数:为变量分配唯一 SSA 寄存器 %llvmirN, # 记录写回(模板嵌入后 store 到变量 alloca) if val_node is not None and val_node.kind() == ast.ASTKind.Name: - nm: rawptr[ast.Name] = rawptr[ast.Name](val_node) + nm: ast.Name* = ast.Name*(val_node) if nm.id is not None: - alloca: rawptr[llvmlite.Value] = self.Gen.VarGen.lookup_var( - trans.SymTab, nm.id) + alloca: 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( - fcall, - f"c.LOut 变量 '{nm.id}' 未定义或输出数超过 {LLVMIR_MAX_OPS}", - "TypeError") + self.Gen.TypeGenErr.fatal_error(fcall, f"c.LOut 变量 '{nm.id}' 未定义或输出数超过 {LLVMIR_MAX_OPS}", "TypeError") self.Gen.CallGenBase.LLVMIRRegSeq += 1 reg_buf: str = pool.alloc(32) if reg_buf is not None: @@ -1734,13 +1603,12 @@ class CallGenCBuiltin(CallGenBase.CallGenBase): out_count += 1 continue # 非 c.LInp/c.LOut 的 f-string 表达式:翻译值并嵌入值文本 - ival: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( - builder, pool, mod, fexpr, None, 0, trans) + ival: 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) elif tk == ast.ASTKind.Constant: - cn2: rawptr[ast.Constant] = rawptr[ast.Constant](first_arg) + cn2: ast.Constant* = ast.Constant*(first_arg) if cn2.str_val is not None: # 裸 strcpy 无界:模板常量串 ≥ LLVMIR_TEMPLATE_BUF 会越界写 pool 块, # 改用与 JoinedStr 分支一致的有界追加 @@ -1754,11 +1622,11 @@ class CallGenCBuiltin(CallGenBase.CallGenBase): # LOut 写回: store %llvmirN, * %var oi: int for oi in range(out_count): - oa: rawptr[llvmlite.Value] = rawptr[llvmlite.Value](out_alloca[oi]) + oa: llvmlite.Value* = 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: + if oa is None or oa.Ty is None or oa.Ty.Pointee == 0 or rn is None: continue - reg_val: rawptr[llvmlite.Value] = llvmlite.new_value(pool) + reg_val: llvmlite.Value* = llvmlite.new_value(pool) if reg_val is None: continue reg_val.Ty = oa.Ty.Pointee diff --git a/App/lib/core/Gen/Call/CallGenCall.vp b/App/lib/core/Gen/Call/CallGenCall.vp index 5d62206..807af8b 100644 --- a/App/lib/core/Gen/Call/CallGenCall.vp +++ b/App/lib/core/Gen/Call/CallGenCall.vp @@ -15,8 +15,7 @@ from . import CallGenBase # ============================================================ # CallGenCall - CallGenMixin 拆分(阶段 B):方法调用分派(含 super / 虚调用 / kwargs 名匹配) # ============================================================ -@t.NoVTable -class CallGenCall(CallGenBase.CallGenBase): +novirtual class CallGenCall(CallGenBase.CallGenBase): """方法调用分派(含 super / 虚调用 / kwargs 名匹配)""" # ============================================================ @@ -39,17 +38,17 @@ class CallGenCall(CallGenBase.CallGenBase): # ============================================================ # ============================================================ - def _do_virtual_call(self, pool: rawptr[memhub.MemBuddy], - builder: rawptr[llvmlite.IRBuilder], - mod: rawptr[llvmlite.LLVMModule], + def _do_virtual_call(self, pool: memhub.MemBuddy*, + builder: llvmlite.IRBuilder*, + mod: llvmlite.LLVMModule*, class_name: str, method_name: str, - self_ptr: rawptr[llvmlite.Value], - args_head: rawptr[llvmlite.Value], + self_ptr: llvmlite.Value*, + args_head: llvmlite.Value*, args_count: int, - found_func: rawptr[llvmlite.Function], - ret_ty: rawptr[llvmlite.LLVMType], - vtable_base: rawptr[llvmlite.Value] = None) -> rawptr[llvmlite.Value]: + found_func: llvmlite.Function*, + ret_ty: llvmlite.LLVMType*, + vtable_base: llvmlite.Value* = None) -> llvmlite.Value*: """通过虚表间接调用虚方法,返回 call 结果(void 方法返回 None) vtable_base: 对象头指针(vtable 所在位置,即未调整的 obj_ptr)。 @@ -57,10 +56,8 @@ class CallGenCall(CallGenBase.CallGenBase): 从调整后位置读 vtable 会读到字段值 → 垃圾指针崩溃。默认 None 时 vtable_base = self_ptr(未调整场景,读对象头)。 """ - if pool is None or builder is None or class_name is None or method_name is None: - return None - if self_ptr is None or args_head is None: - return None + if pool is None or builder is None or class_name is None or method_name is None: return None + if self_ptr is None or args_head is None: return None if vtable_base is None: vtable_base = self_ptr @@ -71,8 +68,8 @@ class CallGenCall(CallGenBase.CallGenBase): # GEP 槽位错位读到别的函数(MultiInheritTest color_code 虚调用读到 # area FAILED 根因)。vtable_base 是接收者静态类型指针(vtable 所在 # 位置),其 VTableMethods 才是最终对象实际存储的完整 vtable 布局。 - vc_entry: rawptr[GenTypes.StructEntry] = None - struct_ty: rawptr[llvmlite.LLVMType] = None + vc_entry: GenTypes.StructEntry* = None + struct_ty: 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) if vc_entry is not None: @@ -89,45 +86,39 @@ class CallGenCall(CallGenBase.CallGenBase): struct_ty = vc_entry.Ty if struct_ty is None: struct_ty = self.Gen.StructGen.get_struct_type(class_name) - if struct_ty is None: - return None + if struct_ty is None: return None # 2. 获取方法在虚表中的索引(用 entry 直接查找) method_index: int = -1 if vc_entry is not None and vc_entry.VTableMethods is not None: - methods_arr: sizet | t.CPtr = (sizet | t.CPtr)(vc_entry.VTableMethods) + methods_arr: sizet* = (sizet*)(vc_entry.VTableMethods) for mi in range(vc_entry.VTableMethodCount): mname_addr: sizet = methods_arr[mi] - if mname_addr == 0: - continue + if mname_addr == 0: continue mname: str = (str | t.CPtr)(mname_addr) if mname is not None and string.strcmp(mname, method_name) == 0: method_index = mi break else: method_index = self.Gen.StructGen.get_vtable_method_index(class_name, method_name) - if method_index < 0: - return None + if method_index < 0: return None # 3. 基础类型 - 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) + i8_ty: llvmlite.LLVMType* = llvmlite.Int8(pool) + i8_ptr_ty: llvmlite.LLVMType* = llvmlite.Ptr(pool, i8_ty) + i8_ptr_ptr_ty: llvmlite.LLVMType* = llvmlite.Ptr(pool, i8_ptr_ty) # 4. bitcast 到 i8** 访问 __vtable__ 字段(索引 0) # vtable 指针总是在对象第一个字段,无需 GEP,直接 bitcast 到 i8** 即可。 # 这样即使 struct_ty 是 opaque(跨模块未加载完整定义)也能正常工作。 # 注意用 vtable_base(对象头)而非 self_ptr:多继承 this 调整后 # self_ptr 已前移,其头部不是 vtable 而是父类字段值。 - vtable_slot: rawptr[llvmlite.Value] = llvmlite.build_bitcast( - builder, vtable_base, i8_ptr_ptr_ty) - if vtable_slot is None: - return None + vtable_slot: 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: rawptr[llvmlite.Value] = llvmlite.build_load(builder, i8_ptr_ty, vtable_slot) - if vtable_ptr is None: - return None + vtable_ptr: llvmlite.Value* = llvmlite.build_load(builder, i8_ptr_ty, vtable_slot) + if vtable_ptr is None: return None # 6. 构造 vtable 类型 {i8*, i8*, ...} method_count: int = 0 @@ -135,54 +126,48 @@ class CallGenCall(CallGenBase.CallGenBase): method_count = vc_entry.VTableMethodCount else: method_count = self.Gen.StructGen.get_vtable_method_count(class_name) - if method_count <= 0: - return None + if method_count <= 0: return None - vt_first: rawptr[llvmlite.Function] = None - vt_prev: rawptr[llvmlite.Function] = None + vt_first: llvmlite.Function* = None + vt_prev: llvmlite.Function* = None for vi in range(method_count): - pn: rawptr[llvmlite.Function] = llvmlite.new_param_node(pool, i8_ptr_ty) - if pn is None: - continue + pn: llvmlite.Function* = llvmlite.new_param_node(pool, i8_ptr_ty) + if pn is None: continue if vt_first is None: vt_first = pn if vt_prev is not None: llvmlite.paramnode_set_next(vt_prev, pn) vt_prev = pn - vtable_ty: rawptr[llvmlite.LLVMType] = llvmlite.Struct(pool, vt_first, method_count, None) - if vtable_ty is None: - return None - vtable_ptr_ty: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, vtable_ty) + vtable_ty: llvmlite.LLVMType* = llvmlite.Struct(pool, vt_first, method_count, None) + if vtable_ty is None: return None + vtable_ptr_ty: llvmlite.LLVMType* = llvmlite.Ptr(pool, vtable_ty) # 7. bitcast i8* 到 vtable 类型指针 - vtable_typed: rawptr[llvmlite.Value] = llvmlite.build_bitcast( - builder, vtable_ptr, vtable_ptr_ty) - if vtable_typed is None: - return None + vtable_typed: llvmlite.Value* = llvmlite.build_bitcast(builder, vtable_ptr, vtable_ptr_ty) + if vtable_typed is None: return None # 8. GEP 到方法槽位 - func_slot: rawptr[llvmlite.Value] = llvmlite.build_gep_struct( - builder, vtable_ty, i8_ptr_ty, vtable_typed, method_index) + func_slot: 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: rawptr[llvmlite.Value] = llvmlite.build_load(builder, i8_ptr_ty, func_slot) + func_i8: llvmlite.Value* = llvmlite.build_load(builder, i8_ptr_ty, func_slot) if func_i8 is None: return None # 10. 从 args_head 构造函数类型 RetTy(Param1, Param2, ...) # 直接遍历 Value 链表提取参数类型,避免跨模块访问 found_func(stub 字段偏移问题) - fp_first: rawptr[llvmlite.Function] = None - fp_prev: rawptr[llvmlite.Function] = None + fp_first: llvmlite.Function* = None + fp_prev: llvmlite.Function* = None fp_count: int = 0 - cur_val: rawptr[llvmlite.Value] = args_head + cur_val: llvmlite.Value* = args_head for vi in range(args_count): if cur_val is None: break - cur_ty: rawptr[llvmlite.LLVMType] = llvmlite.value_get_ty(cur_val) - fpn: rawptr[llvmlite.Function] = llvmlite.new_param_node(pool, cur_ty) + cur_ty: llvmlite.LLVMType* = llvmlite.value_get_ty(cur_val) + fpn: llvmlite.Function* = llvmlite.new_param_node(pool, cur_ty) if fpn is not None: if fp_first is None: fp_first = fpn @@ -192,13 +177,13 @@ class CallGenCall(CallGenBase.CallGenBase): cur_val = llvmlite.value_get_next(cur_val) fp_count += 1 - func_ty: rawptr[llvmlite.LLVMType] = llvmlite.Func(pool, ret_ty, fp_first, fp_count) + func_ty: llvmlite.LLVMType* = llvmlite.Func(pool, ret_ty, fp_first, fp_count) if func_ty is None: return None - func_ptr_ty: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, func_ty) + func_ptr_ty: llvmlite.LLVMType* = llvmlite.Ptr(pool, func_ty) # 11. bitcast i8* 到函数指针类型 - func_ptr: rawptr[llvmlite.Value] = llvmlite.build_bitcast(builder, func_i8, func_ptr_ty) + func_ptr: llvmlite.Value* = llvmlite.build_bitcast(builder, func_i8, func_ptr_ty) if func_ptr is None: return None @@ -212,16 +197,16 @@ class CallGenCall(CallGenBase.CallGenBase): # ============================================================ # ============================================================ - def _call_method_on_ptr(self, pool: rawptr[memhub.MemBuddy], - builder: rawptr[llvmlite.IRBuilder], - mod: rawptr[llvmlite.LLVMModule], + def _call_method_on_ptr(self, pool: memhub.MemBuddy*, + builder: llvmlite.IRBuilder*, + mod: llvmlite.LLVMModule*, class_name: str, method_name: str, - self_ptr: rawptr[llvmlite.Value], - extra_args: sizet | t.CPtr, + self_ptr: llvmlite.Value*, + extra_args: sizet*, extra_count: int, - trans: rawptr[HT.Translator], - node: rawptr[ast.AST] = None) -> rawptr[llvmlite.Value]: + trans: HT.Translator*, + node: ast.AST* = None) -> llvmlite.Value*: """在结构体指针上调用方法,返回 call 结果(void 方法返回 None) node: 触发本次调用的 AST 节点(如 Subscript 下标节点),用于 fatal_error @@ -233,8 +218,8 @@ class CallGenCall(CallGenBase.CallGenBase): # 提前获取结构体 entry(用 find_struct_by_type 规避跨模块同名 find_struct 找错) # 用于 SHA1 查找和虚表分派 - cmop_entry: rawptr[GenTypes.StructEntry] = None - cmop_struct_ty: rawptr[llvmlite.LLVMType] = self.Gen.StructGen.get_struct_type_from_value(self_ptr) + cmop_entry: GenTypes.StructEntry* = None + cmop_struct_ty: 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) if cmop_entry is None: @@ -251,7 +236,7 @@ class CallGenCall(CallGenBase.CallGenBase): viperlib.snprintf(lookup_name, 128, "%s.%s", class_name, method_name) # 查找函数(支持 SHA1 后缀匹配) - found_func: rawptr[llvmlite.Function] = self.find_func_in_module(mod, lookup_name) + found_func: llvmlite.Function* = self.find_func_in_module(mod, lookup_name) # 确定调用名 call_name: str = lookup_name @@ -290,10 +275,10 @@ class CallGenCall(CallGenBase.CallGenBase): call_name = mangled2 # 确定返回类型(__before_init__ 和 __init__ 返回 void) - void_ty: rawptr[llvmlite.LLVMType] = llvmlite.Void(pool) - call_ret_ty: rawptr[llvmlite.LLVMType] = void_ty + void_ty: llvmlite.LLVMType* = llvmlite.Void(pool) + call_ret_ty: llvmlite.LLVMType* = void_ty if found_func is not None: - frt: rawptr[llvmlite.LLVMType] = llvmlite.function_get_ret_ty(found_func) + frt: llvmlite.LLVMType* = llvmlite.function_get_ret_ty(found_func) if frt is not None: call_ret_ty = frt elif string.strcmp(method_name, "__getitem__") == 0 or string.strcmp(method_name, "__new__") == 0: @@ -351,7 +336,7 @@ class CallGenCall(CallGenBase.CallGenBase): # operand type for instruction(NumpyTest a+b 根因)。用 text.ll # → vpi 精确解析返回类型(对齐 _translate_method_call L4641); # 都失败则 fail-fast,绝不静默 void。 - ret_cm: rawptr[llvmlite.LLVMType] = None + ret_cm: llvmlite.LLVMType* = None # is_local_mod 豁免(对齐 _translate_method_call mro_ret 段): # 目标模块 sha1 == 当前正在翻译的模块 sha1 时,自己的 text.ll # 尚未生成 → _dep_text_ll_exists 恒 0 → 误判 pending 死锁。 @@ -359,55 +344,48 @@ class CallGenCall(CallGenBase.CallGenBase): if cls_sha1 is not None and trans is not None \ and trans.ModuleSha1 is not None \ and string.strncmp(cls_sha1, trans.ModuleSha1, 16) == 0: - local_lk_cm2: str = pool.alloc( - string.strlen(class_name) + string.strlen(method_name) + 2) + local_lk_cm2: str = pool.alloc(string.strlen(class_name) + string.strlen(method_name) + 2) if local_lk_cm2 is not None: viperlib.snprintf(local_lk_cm2, string.strlen(class_name) + string.strlen(method_name) + 2, "%s.%s", class_name, method_name) - local_fn_cm2: rawptr[llvmlite.Function] = self.find_func_in_module(mod, local_lk_cm2) + local_fn_cm2: llvmlite.Function* = self.find_func_in_module(mod, local_lk_cm2) if local_fn_cm2 is not None: - lrt_cm2: rawptr[llvmlite.LLVMType] = llvmlite.function_get_ret_ty(local_fn_cm2) + lrt_cm2: llvmlite.LLVMType* = llvmlite.function_get_ret_ty(local_fn_cm2) if lrt_cm2 is not None: ret_cm = lrt_cm2 if cls_sha1 is not None: - ret_cm = self._LookupMethodRetTyFromTextLL( - pool, cls_sha1, class_name, method_name) + ret_cm = self._LookupMethodRetTyFromTextLL(pool, cls_sha1, class_name, method_name) if ret_cm is None and cls_sha1 is not None: - ret_cm = self._lookup_method_ret_ty_via_vpi( - pool, cls_sha1, class_name, method_name) + ret_cm = self._lookup_method_ret_ty_via_vpi(pool, cls_sha1, class_name, method_name) if ret_cm is not None: call_ret_ty = ret_cm else: # Phase A 依赖 text.ll 未生成(方法定义模块尚未翻译):保持默认 # 类型继续(本函数同样服务 Mixin 跨模块方法调用,如 BuildPipeline # gen.extract_module_docstrings)。cls_sha1 为 None 同样视为依赖未就绪。 - if cls_sha1 is None \ - or (cls_sha1 is not None - and self._dep_text_ll_exists(pool, cls_sha1) == 0): + if cls_sha1 is None or (cls_sha1 is not None and self._dep_text_ll_exists(pool, cls_sha1) == 0): # 依赖未就绪:保持默认 i32(build_call(Void) 返回 None 会 # 破坏表达式翻译) call_ret_ty = llvmlite.Int32(pool) else: err_cm4: str = pool.alloc(256) if err_cm4 is not None: - viperlib.snprintf(err_cm4, 256, - "方法 '%s.%s' 返回类型无法确定(text.ll/vpi 均未命中,跨模块 stub 未注入)", - class_name, method_name) + viperlib.snprintf(err_cm4, 256, "方法 '%s.%s' 返回类型无法确定(text.ll/vpi 均未命中,跨模块 stub 未注入)", class_name, method_name) self.Gen.TypeGenErr.fatal_error(node, err_cm4) self.Gen.TypeGenErr.fatal_error(node, "方法返回类型无法确定") # 构建参数链表: self_ptr → extra_args... llvmlite.value_set_next(self_ptr, None) - head: rawptr[llvmlite.Value] = self_ptr - tail: rawptr[llvmlite.Value] = self_ptr + head: llvmlite.Value* = self_ptr + tail: 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: rawptr[llvmlite.Value] = rawptr[llvmlite.Value](arg_addr) + av: llvmlite.Value* = llvmlite.Value*(arg_addr) if av is not None: llvmlite.value_set_next(av, None) llvmlite.value_set_next(tail, av) @@ -422,8 +400,7 @@ class CallGenCall(CallGenBase.CallGenBase): mdf_default_count: int = 0 mdf_param_count: int = 0 if trans is not None and trans._funcs is not None: - mdf_entry: rawptr[GenTypes.FuncEntry] = self.Gen.CallGenLeafKit.find_func_entry_in_table( - trans._funcs, trans._func_count, lookup_name) + mdf_entry: GenTypes.FuncEntry* = self.Gen.CallGenLeafKit.find_func_entry_in_table(trans._funcs, trans._func_count, lookup_name) if mdf_entry is not None: mdf_defaults = mdf_entry.Defaults mdf_default_count = mdf_entry.DefaultCount @@ -432,7 +409,7 @@ class CallGenCall(CallGenBase.CallGenBase): # 调用方函数表)Defaults 非 None 会短路跳过,但下方"用快照重建默认值" # 分支依赖 mdf_gd(唯一持有 stdlib 常量快照处)——缺它必 fatal_error # (ListTest list[int].__new__ 根因) - mdf_gd: rawptr[GenTypes.FuncDefaultsEntry] = self.Gen.CallGenLeafKit.find_func_defaults(lookup_name) + mdf_gd: 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 @@ -449,8 +426,7 @@ class CallGenCall(CallGenBase.CallGenBase): else: vpi_sha1_p = self.Gen.StructGen.get_struct_sha1(class_name) if vpi_sha1_p is not None: - vpi_pa = self.Gen.CallGenBase._vpi_method_param_annot( - pool, vpi_sha1_p, class_name, method_name) + vpi_pa = self.Gen.CallGenBase._vpi_method_param_annot(pool, vpi_sha1_p, class_name, method_name) if vpi_pa is not None and vpi_pa[0] != '\0': vpi_pc2: int = 1 vi2: sizet = 0 @@ -470,7 +446,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: rawptr[llvmlite.Param] = llvmlite.function_get_param_head(found_func) + ppn_f2: 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,18 +469,14 @@ 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: rawptr[llvmlite.Value] = None + mdf_val: 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) + mdf_val = self.Gen.CallGenLeafKit._build_const_from_snapshot(pool, mod, mdf_gd, mdf_di, trans, builder) if mdf_val is None: # 用 node(本函数报错行号节点,如构造实参/源码 Call)而非 cl—— # cl 在本函数未定义(无该参数),读取垃圾指针导致 fatal_error # 显示 "line 0"(FileIoTest File.__init__ 报错行号丢失根因) - self.Gen.TypeGenErr.fatal_error( - node, - f"跨模块默认参数无法重建(快照缺失,默认值需为简单常量): {lookup_name}", - "TypeError") + self.Gen.TypeGenErr.fatal_error(node, f"跨模块默认参数无法重建(快照缺失,默认值需为简单常量): {lookup_name}", "TypeError") continue llvmlite.value_set_next(mdf_val, None) llvmlite.value_set_next(tail, mdf_val) @@ -517,14 +489,14 @@ class CallGenCall(CallGenBase.CallGenBase): # 查找常查不到——查不到 ≠ 无默认值(如 Buf.__init__(data, capacity) # 缺的 length=0/owned=False 恰为零值),零值兜底语义一致。 if found_func is not None: - param_node_z: rawptr[llvmlite.Param] = llvmlite.function_get_param_head(found_func) + param_node_z: 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: rawptr[llvmlite.Value] = llvmlite.ConstZero(pool, zero_ty) + zero_ty: llvmlite.LLVMType* = llvmlite.param_get_ty(param_node_z) + zero_val: 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) @@ -547,18 +519,17 @@ class CallGenCall(CallGenBase.CallGenBase): and vpi_pa[seg_start_v + seg_len_v] != '@': seg_len_v += 1 if seg_no_v == seg_idx_v: - pty_v: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, llvmlite.Int8(pool)) + pty_v: llvmlite.LLVMType* = llvmlite.Ptr(pool, llvmlite.Int8(pool)) if seg_len_v > 0: seg_buf_v: bytes = stdlib.malloc(seg_len_v + 1) if seg_buf_v is not None: string.strncpy(seg_buf_v, vpi_pa + seg_start_v, seg_len_v) seg_buf_v[seg_len_v] = '\0' - rty_v: rawptr[llvmlite.LLVMType] = self.Gen.CallGenBase._vpi_resolve_param_annot_ty( - pool, seg_buf_v) + rty_v: llvmlite.LLVMType* = self.Gen.CallGenBase._vpi_resolve_param_annot_ty(pool, seg_buf_v) if rty_v is not None: pty_v = rty_v stdlib.free(seg_buf_v) - zero_val_v: rawptr[llvmlite.Value] = llvmlite.ConstZero(pool, pty_v) + zero_val_v: 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 +539,14 @@ class CallGenCall(CallGenBase.CallGenBase): elif found_func is not None: # 无默认参数信息但有 found_func:用零值兜底填充缺失参数 # (原逻辑;禁止 fail-fast 误杀——同上,查不到默认参数表 ≠ 无默认值) - param_node: rawptr[llvmlite.Param] = llvmlite.function_get_param_head(found_func) + param_node: 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: rawptr[llvmlite.Value] = llvmlite.ConstZero(pool, missing_ty) + missing_ty: llvmlite.LLVMType* = llvmlite.param_get_ty(param_node) + zero_val2: 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,18 +562,17 @@ class CallGenCall(CallGenBase.CallGenBase): # 与形参 Vec3* 不匹配,需 bitcast(coerce 指针→指针生成 bitcast), # 否则 call 参数类型与声明不一致 llc 报错。 if found_func is not None and head is not 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 + pc_param: llvmlite.Param* = llvmlite.function_get_param_head(found_func) + pc_node: llvmlite.Value* = head + new_head_pc: llvmlite.Value* = head + prev_pc: llvmlite.Value* = None while pc_node is not None: - pc_next_save: rawptr[llvmlite.Value] = pc_node.Next - coerced_pc: rawptr[llvmlite.Value] = pc_node + pc_next_save: llvmlite.Value* = pc_node.Next + coerced_pc: llvmlite.Value* = pc_node if pc_param is not None: - pty_pc: rawptr[llvmlite.LLVMType] = llvmlite.param_get_ty(pc_param) + pty_pc: llvmlite.LLVMType* = llvmlite.param_get_ty(pc_param) if pty_pc is not None: - c_pc: rawptr[llvmlite.Value] = self.Gen.ExprGenBase.coerce_to_type( - builder, pc_node, pty_pc, None) + c_pc: llvmlite.Value* = self.Gen.ExprGenBase.coerce_to_type(builder, pc_node, pty_pc, None) if c_pc is not None: coerced_pc = c_pc pc_param = llvmlite.param_get_next(pc_param) @@ -623,7 +593,7 @@ class CallGenCall(CallGenBase.CallGenBase): if cmop_entry is not None: cmop_has_vt = cmop_entry.HasVTable if cmop_has_vt == 1 and cmop_entry.VTableMethods is not None: - cmop_methods_arr: sizet | t.CPtr = (sizet | t.CPtr)(cmop_entry.VTableMethods) + cmop_methods_arr: sizet* = (sizet*)(cmop_entry.VTableMethods) for cmop_mi in range(cmop_entry.VTableMethodCount): cmop_mname_addr: sizet = cmop_methods_arr[cmop_mi] if cmop_mname_addr == 0: @@ -659,8 +629,7 @@ class CallGenCall(CallGenBase.CallGenBase): # MemManager* 口径不一致 → 跨模块 declare/define 不一致并经 .stub.ll # 传播到未调用该函数的消费方模块。泛型特化名({sha}.list[str].__new__) # 的定义侧注解在模板类上,由 _coerce_args_to_def_params 的模板退查解析。 - head = self.Gen.CallGenLib._coerce_args_to_def_params( - pool, builder, call_name, head, total_count, None, 1, trans) + head = self.Gen.CallGenLib._coerce_args_to_def_params(pool, builder, call_name, head, total_count, None, 1, trans) self._ensure_method_declare(pool, mod, call_name, call_ret_ty, head, total_count) return llvmlite.build_call(builder, call_name, head, total_count, call_ret_ty, 0) @@ -673,14 +642,14 @@ class CallGenCall(CallGenBase.CallGenBase): # ============================================================ # ============================================================ - def _translate_method_call(self, pool: rawptr[memhub.MemBuddy], - builder: rawptr[llvmlite.IRBuilder], - mod: rawptr[llvmlite.LLVMModule], + def _translate_method_call(self, pool: memhub.MemBuddy*, + builder: llvmlite.IRBuilder*, + mod: llvmlite.LLVMModule*, class_name: str, method_name: str, - obj_ptr: rawptr[llvmlite.Value], - cl: rawptr[ast.Call], - trans: rawptr[HT.Translator]) -> rawptr[llvmlite.Value]: + obj_ptr: llvmlite.Value*, + cl: ast.Call*, + trans: HT.Translator*) -> llvmlite.Value*: """翻译方法调用,返回 call 结果 Value""" if pool is None or builder is None or class_name is None or method_name is None: return None @@ -691,7 +660,7 @@ class CallGenCall(CallGenBase.CallGenBase): # [D25 分派修复] class_name 可能因注解在 Handle 阶段退化而为空串,使 list 内建拦截(_is_list_builtin_method)与 D25 泛型基类 fail-fast 双双失效 ⇒ 误绑到无关特化。接收者的**实际 struct 名**比退化注解可靠,用它补全判定来源(提升到分支外声明,D25 fail-fast 同样使用) lb_src: str = class_name if lb_src is None or lb_src[0] == '\0': - lb_sty_s: rawptr[llvmlite.LLVMType] = \ + lb_sty_s: llvmlite.LLVMType* = \ self.Gen.StructGen.get_struct_type_from_value(obj_ptr) if lb_sty_s is not None: lb_nm_s: str = llvmlite.get_struct_name(lb_sty_s) @@ -707,12 +676,11 @@ class CallGenCall(CallGenBase.CallGenBase): lb_cls = lb_cls + lb_pfx_d # 触发判据同样以接收者实际类型为准(_is_list_builtin_receiver): # 真实 list 命中不变;非容器不命中;实际类型不可得回退 lb_cls。 - if self.Gen.CallGenProp._is_list_builtin_receiver( - pool, obj_ptr, lb_cls, method_name, cl) != 0: + if self.Gen.CallGenProp._is_list_builtin_receiver(pool, obj_ptr, lb_cls, method_name, cl) != 0: # 双指针槽形态(rawptr[list[...]] 局部变量 alloca Ptr(Ptr(Struct)) # 直接传入时先 load 一层得到对象指针 Ptr(Struct),与分派方 # _translate_method_call 调用点的 obj_ptr 语义一致)。 - lb_obj: rawptr[llvmlite.Value] = obj_ptr + lb_obj: 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): @@ -728,9 +696,7 @@ class CallGenCall(CallGenBase.CallGenBase): lb_can: sizet = 0 if lb_cargs is not None: lb_can = len(lb_cargs) - return self._translate_list_builtin_call( - pool, builder, mod, cl, method_name, lb_obj, - lb_cargs, lb_can, trans) + return self._translate_list_builtin_call(pool, builder, mod, cl, method_name, lb_obj, lb_cargs, lb_can, trans) # [D25 fail-fast] 泛型模板**基类**(剥 sha1 前缀后不含 '[',如裸 "list")上的 # 非 list 内建方法调用:接收者元素类型未知(list 内建方法已在上面走内联路径, @@ -744,20 +710,19 @@ class CallGenCall(CallGenBase.CallGenBase): cm_pfx: int = GenApi.sha1_prefix_len(lb_src) cm_bare = lb_src + cm_pfx if cm_pfx != 0 else lb_src if cm_bare is not None and string.strchr(cm_bare, '[') is None: - cm_tpl: rawptr[ast.ClassDef] = self.Gen.ClassGenGeneric._find_generic_template(cm_bare) + cm_tpl: ast.ClassDef* = self.Gen.ClassGenGeneric._find_generic_template(cm_bare) if cm_tpl is not None: - self.Gen.TypeGenErr.fatal_error( - cl, + self.Gen.TypeGenErr.fatal_error(cl, f"泛型类 '{cm_bare}' 的方法 '{method_name}' 调用缺少类型实参" f"(接收者静态类型是裸泛型基类,元素类型未知);" f"禁止静默按默认 list[int] 特化(元素按 i32 处理会截断指针)," - f"请让该变量的注解/类型带上实参(如 list[rawptr[ast.AST]])", + f"请让该变量的注解/类型带上实参(如 list[ast.AST*])", "TypeError") # 提前获取结构体 entry(用 find_struct_by_type 规避跨模块同名 find_struct 找错) # 用于继承链遍历、SHA1 查找和虚表分派 - mc_entry: rawptr[GenTypes.StructEntry] = None - mc_struct_ty: rawptr[llvmlite.LLVMType] = self.Gen.StructGen.get_struct_type_from_value(obj_ptr) + mc_entry: GenTypes.StructEntry* = None + mc_struct_ty: 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) if mc_entry is None: @@ -765,8 +730,7 @@ class CallGenCall(CallGenBase.CallGenBase): # [D25 分派根治] 泛型容器接收者以**实际结构体名**为准:obj_ptr 的 LLVM 结构体类型名是 IR 层真值,class_name 可能因同名变量重复声明而退化到无关特化。判定仅作用于泛型容器接收者(普通类名不含方括号,既有路径不受影响) # 共用口径收敛到 CallGenProp._resolve_generic_receiver_name(唯一实现):去 sha1 前缀 → 基名是已注册泛型模板且含 '[' ⇒ 覆盖 class_name;裸泛型基类 ⇒ fail-fast;非泛型模板 ⇒ None - mc_act_d: str = self.Gen.CallGenProp._resolve_generic_receiver_name( - pool, mc_struct_ty, method_name, cl) + mc_act_d: str = self.Gen.CallGenProp._resolve_generic_receiver_name(pool, mc_struct_ty, method_name, cl) if mc_act_d is not None: class_name = mc_act_d @@ -780,7 +744,7 @@ class CallGenCall(CallGenBase.CallGenBase): viperlib.snprintf(lookup_name, lk_cap, "%s.%s", class_name, method_name) # 查找函数(支持 SHA1 后缀匹配) - found_func: rawptr[llvmlite.Function] = self.find_func_in_module(mod, lookup_name) + found_func: llvmlite.Function* = self.find_func_in_module(mod, lookup_name) # 泛型模板类方法:特化函数名带类型参数({sha1}.list[int].get), # "ClassName.method" 短名匹配不到。特化由触发方(通常即调用方)模块完成, @@ -795,7 +759,7 @@ class CallGenCall(CallGenBase.CallGenBase): # 沿 MRO 祖先链查找父类方法(子类未覆盖时回退到父类,先声明父类优先) mc_anc: str = None # 方法实际定义类(多继承 this 调整用) if found_func is None: - mro_ptr: sizet | t.CPtr = self.Gen.StructGen.get_mro_chain(pool, class_name) + mro_ptr: sizet* = self.Gen.StructGen.get_mro_chain(pool, class_name) mi: int = 1 while mro_ptr is not None and mro_ptr[mi] != 0: anc: str = (str | t.CPtr)(mro_ptr[mi]) @@ -803,7 +767,7 @@ class CallGenCall(CallGenBase.CallGenBase): parent_lookup: str = pool.alloc(128) if parent_lookup is not None: viperlib.snprintf(parent_lookup, 128, "%s.%s", anc, method_name) - parent_func: rawptr[llvmlite.Function] = self.find_func_in_module(mod, parent_lookup) + parent_func: llvmlite.Function* = self.find_func_in_module(mod, parent_lookup) if parent_func is not None: found_func = parent_func mc_anc = anc @@ -813,7 +777,7 @@ class CallGenCall(CallGenBase.CallGenBase): # 兄弟 Mixin 兜底(与 TPC HandlesExprCall 一致):方法不在本类 MRO 链时遍历已注册 struct 表找定义类方法,this 由下方 _adjust_this_for_inherited_method 按组合布局前移 sizeof(定义类)。仅对普通类名兜底——泛型特化类名(list[X]/dict[K,V])必须过滤,否则普通方法在 found_func 未命中时会误绑到 list 特化函数,this 前移错位导致运行期崩溃 # 跨模块兄弟 Mixin 兜底命中(定义类在另一文件、本地 IR 无 define)需经候选类模块 sha1 查 text.ll 返回类型。 mixin_hit: int = 0 - mixin_ret_ty: rawptr[llvmlite.LLVMType] = None + mixin_ret_ty: llvmlite.LLVMType* = None mixin_anc_name: str = None mixin_anc_sha1: str = None if found_func is None: @@ -843,7 +807,7 @@ class CallGenCall(CallGenBase.CallGenBase): # 且本模块存在同名方法"的任意条目,需逐条枚举探测,不可改为按名 # find_struct(会退化为单条精确查找、漏掉全部兄弟候选)。 while sc_i < sc_n and found_func is None and mixin_hit == 0: - cand_entry: rawptr[GenTypes.StructEntry] = self.Gen.StructGen._get_struct_entry(sc_i) + cand_entry: 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: @@ -855,8 +819,7 @@ class CallGenCall(CallGenBase.CallGenBase): cand_lookup: str = pool.alloc(128) if cand_lookup is not None: viperlib.snprintf(cand_lookup, 128, "%s.%s", cand_name, method_name) - cand_func: rawptr[llvmlite.Function] = self.find_func_in_module( - mod, cand_lookup) + cand_func: llvmlite.Function* = self.find_func_in_module(mod, cand_lookup) if cand_func is not None: found_func = cand_func mc_anc = cand_name @@ -869,10 +832,8 @@ class CallGenCall(CallGenBase.CallGenBase): # (ClassGenVTable._mangle_name → 7871cc1aabebfc33 根因)。 if mixin_hit == 0: cand_sha1_cx: str = self.Gen.StructGen.get_struct_sha1(cand_name) - if cand_sha1_cx is not None \ - and self._dep_text_ll_exists(pool, cand_sha1_cx) != 0: - cand_ret_cx: rawptr[llvmlite.LLVMType] = self._LookupMethodRetTyFromTextLL( - pool, cand_sha1_cx, cand_name, method_name) + if cand_sha1_cx is not None and self._dep_text_ll_exists(pool, cand_sha1_cx) != 0: + cand_ret_cx: llvmlite.LLVMType* = self._LookupMethodRetTyFromTextLL(pool, cand_sha1_cx, cand_name, method_name) if cand_ret_cx is not None: mixin_hit = 1 mixin_ret_ty = cand_ret_cx @@ -890,15 +851,15 @@ class CallGenCall(CallGenBase.CallGenBase): call_name = found_name # 确定返回类型 - i32_ty: rawptr[llvmlite.LLVMType] = llvmlite.Int32(pool) - call_ret_ty: rawptr[llvmlite.LLVMType] = i32_ty + i32_ty: llvmlite.LLVMType* = llvmlite.Int32(pool) + call_ret_ty: llvmlite.LLVMType* = i32_ty if found_func is not None: - frt: rawptr[llvmlite.LLVMType] = llvmlite.function_get_ret_ty(found_func) + frt: llvmlite.LLVMType* = llvmlite.function_get_ret_ty(found_func) if frt is not None: call_ret_ty = frt else: # found_func 为 None(stub 未注入):先处理编译器内置特殊方法 - sp_ty2: rawptr[llvmlite.LLVMType] = self._special_method_ret_ty(pool, class_name, method_name) + sp_ty2: llvmlite.LLVMType* = self._special_method_ret_ty(pool, class_name, method_name) if sp_ty2 is not None: call_ret_ty = sp_ty2 # 特殊方法(__before_init__ 等)跨模块调用同样需带 sha1 前缀: @@ -953,7 +914,7 @@ class CallGenCall(CallGenBase.CallGenBase): call_ret_ty = mixin_ret_ty if ret_anc_sha1 is None: # 沿 MRO 找第一个有 SHA1 的类 - mro_s0: sizet | t.CPtr = self.Gen.StructGen.get_mro_chain(pool, class_name) + mro_s0: sizet* = self.Gen.StructGen.get_mro_chain(pool, class_name) mi_s0: int = 1 while mro_s0 is not None and mro_s0[mi_s0] != 0 and ret_anc_sha1 is None: anc_s0: str = (str | t.CPtr)(mro_s0[mi_s0]) @@ -969,7 +930,7 @@ class CallGenCall(CallGenBase.CallGenBase): # 下方回退段不执行,若在此声明则读到未初始化的池内存垃圾(非 NULL), # 把已正确解析的 call_ret_ty(特化 define 的 i32)覆盖成垃圾零值 # LLVMType → build_call 输出 call i0(llc bitwidth out of range)。 - looked_up_ty: rawptr[llvmlite.LLVMType] = None + looked_up_ty: llvmlite.LLVMType* = None if class_name is not None: lbkt_g: str = string.strchr(class_name, '[') if lbkt_g is not None: @@ -985,7 +946,7 @@ class CallGenCall(CallGenBase.CallGenBase): base_buf_g[base_len_g] = '\0' string.strncpy(arg_buf_g, lbkt_g + 1, arg_len_g) arg_buf_g[arg_len_g] = '\0' - ta_list_g: list[str] | t.CPtr = list[str](pool, 8) + ta_list_g: list[str]* = list[str](pool, 8) if ta_list_g is not None: # 逗号分隔多类型实参(list[X] / dict[K, V]) cur_arg_g: str = arg_buf_g @@ -1010,8 +971,7 @@ class CallGenCall(CallGenBase.CallGenBase): base_pfx_g: int = GenApi.sha1_prefix_len(base_buf_g) if base_pfx_g != 0: base_clean_g = base_buf_g + sizet(base_pfx_g) - spec_name_g: str = self.Gen.ClassGenGeneric._specialize_generic_class( - trans, base_clean_g, ta_list_g) + spec_name_g: str = self.Gen.ClassGenGeneric._specialize_generic_class(trans, base_clean_g, ta_list_g) if spec_name_g is not None: # 特化后重新查找特化函数(特化名 = 调用点类名)。 # find_func_in_module 后缀匹配:定义符号名 @@ -1019,15 +979,12 @@ class CallGenCall(CallGenBase.CallGenBase): # 同时以裸名(spec.method)和带模板前缀名 # ({tpl}.spec.method)结尾,两种 class_name 形式 # 都能命中本地 define。 - spec_lk_g: str = pool.alloc( - string.strlen(class_name) + string.strlen(method_name) + 2) + spec_lk_g: str = pool.alloc(string.strlen(class_name) + string.strlen(method_name) + 2) if spec_lk_g is not None: - viperlib.snprintf(spec_lk_g, - string.strlen(class_name) + string.strlen(method_name) + 2, - "%s.%s", class_name, method_name) - spec_found_g: rawptr[llvmlite.Function] = self.find_func_in_module(mod, spec_lk_g) + viperlib.snprintf(spec_lk_g, string.strlen(class_name) + string.strlen(method_name) + 2, "%s.%s", class_name, method_name) + spec_found_g: llvmlite.Function* = self.find_func_in_module(mod, spec_lk_g) if spec_found_g is not None: - frt_g: rawptr[llvmlite.LLVMType] = llvmlite.function_get_ret_ty(spec_found_g) + frt_g: llvmlite.LLVMType* = llvmlite.function_get_ret_ty(spec_found_g) if frt_g is not None: call_ret_ty = frt_g found_func = spec_found_g @@ -1046,39 +1003,32 @@ class CallGenCall(CallGenBase.CallGenBase): # 类型(本模块方法已发射,find_func_in_module 后缀匹配优先本 # 模块 define),不走跨模块 text.ll/vpi 查找。 # ============================================================ - if trans is not None and ret_anc_sha1 is not None \ - and trans.ModuleSha1 is not None \ - and string.strncmp(ret_anc_sha1, trans.ModuleSha1, 16) == 0: - local_lk_lm: str = pool.alloc( - string.strlen(ret_anc_name) + string.strlen(method_name) + 2) + if trans is not None and ret_anc_sha1 is not None and trans.ModuleSha1 is not None and string.strncmp(ret_anc_sha1, trans.ModuleSha1, 16) == 0: + local_lk_lm: str = pool.alloc(string.strlen(ret_anc_name) + string.strlen(method_name) + 2) if local_lk_lm is not None: - viperlib.snprintf(local_lk_lm, - string.strlen(ret_anc_name) + string.strlen(method_name) + 2, - "%s.%s", ret_anc_name, method_name) - local_fn_lm: rawptr[llvmlite.Function] = self.find_func_in_module(mod, local_lk_lm) + viperlib.snprintf(local_lk_lm, string.strlen(ret_anc_name) + string.strlen(method_name) + 2, "%s.%s", ret_anc_name, method_name) + local_fn_lm: llvmlite.Function* = self.find_func_in_module(mod, local_lk_lm) if local_fn_lm is not None: - lrt_lm: rawptr[llvmlite.LLVMType] = llvmlite.function_get_ret_ty(local_fn_lm) + lrt_lm: llvmlite.LLVMType* = llvmlite.function_get_ret_ty(local_fn_lm) if lrt_lm is not None: call_ret_ty = lrt_lm gen_done = 1 # 尝试从 text.ll 查找实际返回类型 # 避免指针返回值被默认 i32 导致 inttoptr 截断 - looked_up_ty = self._LookupMethodRetTyFromTextLL( - pool, ret_anc_sha1, ret_anc_name, method_name) + looked_up_ty = self._LookupMethodRetTyFromTextLL(pool, ret_anc_sha1, ret_anc_name, method_name) # 沿 MRO 祖先链重试:方法可能定义在基类(如 Module.append → # AST.append,函数名 {ast_sha1}.AST.append,且基类在另一模块文件 # 如 ast/stmts.vp 的 Module vs ast/base.vp 的 AST),按调用类名 # 及其 sha1 查不到,需用每个祖先类的类名 + 祖先类所属模块 sha1 # 查 text.ll(NewAstTest mod.append 根因) if looked_up_ty is None: - mro_t2: sizet | t.CPtr = self.Gen.StructGen.get_mro_chain(pool, class_name) + mro_t2: sizet* = self.Gen.StructGen.get_mro_chain(pool, class_name) mi_t2: int = 1 while mro_t2 is not None and mro_t2[mi_t2] != 0 and looked_up_ty is None: anc_t2: str = (str | t.CPtr)(mro_t2[mi_t2]) if anc_t2 is not None and string.strcmp(anc_t2, class_name) != 0: anc_sha1_t2: str = self.Gen.StructGen.get_struct_sha1(anc_t2) - looked_up_ty = self._LookupMethodRetTyFromTextLL( - pool, anc_sha1_t2, anc_t2, method_name) + looked_up_ty = self._LookupMethodRetTyFromTextLL(pool, anc_sha1_t2, anc_t2, method_name) if looked_up_ty is not None: ret_anc_name = anc_t2 ret_anc_sha1 = anc_sha1_t2 @@ -1087,18 +1037,16 @@ class CallGenCall(CallGenBase.CallGenBase): call_ret_ty = looked_up_ty elif gen_done == 0: # 精确查找:vpi stub 返回注解缓存(方法定义处,不硬编码白名单) - vpi_ret_ty: rawptr[llvmlite.LLVMType] = self._lookup_method_ret_ty_via_vpi( - pool, ret_anc_sha1, ret_anc_name, method_name) + vpi_ret_ty: llvmlite.LLVMType* = self._lookup_method_ret_ty_via_vpi(pool, ret_anc_sha1, ret_anc_name, method_name) # vpi 同样沿 MRO 祖先链重试(基类方法注解,用祖先类自身 sha1) if vpi_ret_ty is None: - mro_v2: sizet | t.CPtr = self.Gen.StructGen.get_mro_chain(pool, class_name) + mro_v2: sizet* = self.Gen.StructGen.get_mro_chain(pool, class_name) mi_v2: int = 1 while mro_v2 is not None and mro_v2[mi_v2] != 0 and vpi_ret_ty is None: anc_v2: str = (str | t.CPtr)(mro_v2[mi_v2]) if anc_v2 is not None and string.strcmp(anc_v2, class_name) != 0: anc_sha1_v2: str = self.Gen.StructGen.get_struct_sha1(anc_v2) - vpi_ret_ty = self._lookup_method_ret_ty_via_vpi( - pool, anc_sha1_v2, anc_v2, method_name) + vpi_ret_ty = self._lookup_method_ret_ty_via_vpi(pool, anc_sha1_v2, anc_v2, method_name) if vpi_ret_ty is not None: ret_anc_name = anc_v2 ret_anc_sha1 = anc_sha1_v2 @@ -1128,7 +1076,7 @@ class CallGenCall(CallGenBase.CallGenBase): # text.ll 未生成),属依赖未就绪而非方法不存在。遍历祖先链: # 任一祖先的 sha1 取不到或其 text.ll 未生成 → 结果不确定, # 本遍保持默认类型;全部祖先就绪仍查不到才是真错误。 - mro_p2: sizet | t.CPtr = self.Gen.StructGen.get_mro_chain(pool, class_name) + mro_p2: sizet* = self.Gen.StructGen.get_mro_chain(pool, class_name) mi_p2: int = 1 anc_missing_p2: int = 0 while mro_p2 is not None and mro_p2[mi_p2] != 0: @@ -1184,11 +1132,7 @@ class CallGenCall(CallGenBase.CallGenBase): elif ret_anc_name is not None and ret_anc_sha1 is None: # fail-fast:方法所属类既查不到 SHA1 又从类型名提取失败, # 禁止静默裸名(否则链接期 undefined symbol 难以定位) - self.Gen.TypeGenErr.fatal_error( - cl, - f"方法 '{method_name}' 所属类 '{ret_anc_name}' 无法解析模块 SHA1" - f"(text.ll/vpi/类型名均未命中),跨模块调用名构造失败", - "TypeError") + self.Gen.TypeGenErr.fatal_error(cl, f"方法 '{method_name}' 所属类 '{ret_anc_name}' 无法解析模块 SHA1(text.ll/vpi/类型名均未命中),跨模块调用名构造失败", "TypeError") # 翻译调用参数 cargs: list[ast.AST*]* = cl.args @@ -1201,19 +1145,19 @@ class CallGenCall(CallGenBase.CallGenBase): kwc = len(kw_calls) # 多继承 this 调整(字节偏移法,与 TPC HandlesExprCall._adjust_this_for_inherited_method 一致):继承方法体按"定义类自身布局"读 self 字段,父类字段区在子类中字节偏移可能不同,故 delta = 字段在子类中字节偏移 − 字段在父类自身布局中字节偏移;delta==0(第一父类,字段区前缀对齐)无需调整,delta>0 时按字节 GEP 到父类字段区在子类中的等效基址再 bitcast 成父类指针 - self_arg: rawptr[llvmlite.Value] = obj_ptr + self_arg: 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,任何一步失败都 # fail-fast——绝不静默用未调整的 obj_ptr 当 self,否则方法按自身 # 布局读字段读到垃圾(lookup_reexport strcmp 概率崩溃根因候选)。 is_first_parent_th: int = 0 - mro_fp_th: sizet | t.CPtr = self.Gen.StructGen.get_mro_chain(pool, class_name) + mro_fp_th: sizet* = self.Gen.StructGen.get_mro_chain(pool, class_name) if mro_fp_th is not None and mro_fp_th[1] != 0: first_parent_th: str = (str | t.CPtr)(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: rawptr[GenTypes.StructEntry] = self.Gen.StructGen.find_struct(mc_anc) + anc_entry_th: GenTypes.StructEntry* = self.Gen.StructGen.find_struct(mc_anc) # 无字段父类(FieldCount==0,如多继承中的纯方法类 Vec2Extra): # 继承方法体按"定义类字段"读 self,定义类无字段则方法体不读 # self 布局 → this 无需字节调整,原样传入即可(对齐 TPC @@ -1222,8 +1166,7 @@ class CallGenCall(CallGenBase.CallGenBase): anc_first_name_th: str = None afi_th: int = 0 while afi_th < anc_entry_th.FieldCount: - afe_th: rawptr[GenTypes.FieldEntry] = self.Gen.StructGen._get_field_entry( - anc_entry_th, afi_th) + afe_th: 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) if afn_th is not None and string.strcmp(afn_th, "__vtable__") != 0: @@ -1231,29 +1174,22 @@ class CallGenCall(CallGenBase.CallGenBase): break afi_th += 1 if anc_first_name_th is not None: - sub_entry_th: rawptr[GenTypes.StructEntry] = self.Gen.StructGen.find_struct( - class_name) + sub_entry_th: GenTypes.StructEntry* = self.Gen.StructGen.find_struct(class_name) if sub_entry_th is not None: - anc_field_th: rawptr[GenTypes.FieldEntry] = self.Gen.StructGen.lookup_field( - anc_entry_th.Ty, anc_first_name_th) - sub_field_th: rawptr[GenTypes.FieldEntry] = self.Gen.StructGen.lookup_field( - sub_entry_th.Ty, anc_first_name_th) + anc_field_th: GenTypes.FieldEntry* = self.Gen.StructGen.lookup_field(anc_entry_th.Ty, anc_first_name_th) + sub_field_th: 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( - pool, anc_entry_th, anc_field_th.Index) - sub_off_th: int = self._field_byte_offset( - pool, sub_entry_th, sub_field_th.Index) + anc_off_th: int = self._field_byte_offset(pool, anc_entry_th, anc_field_th.Index) + sub_off_th: int = self._field_byte_offset(pool, sub_entry_th, sub_field_th.Index) delta_th: int = sub_off_th - anc_off_th 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: rawptr[llvmlite.Value] = llvmlite.build_bitcast( - builder, obj_ptr, i8_ptr_th) - 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) + i8_ty_th: llvmlite.LLVMType* = llvmlite.Int8(pool) + i8_ptr_th: llvmlite.LLVMType* = llvmlite.Ptr(pool, i8_ty_th) + obj_i8_th: llvmlite.Value* = llvmlite.build_bitcast(builder, obj_ptr, i8_ptr_th) + delta_val_th: llvmlite.Value* = llvmlite.const_int32(pool, delta_th) + adj_th: 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) + anc_ptr_ty_th: llvmlite.LLVMType* = llvmlite.Ptr(pool, anc_entry_th.Ty) # 跨模块基类(如 Generator → ClassGenBase)的完整定义不在本模块, # bitcast 引用 %"sha1.ClassGenBase" 前必须确保 opaque 声明存在, # 否则 llc 报 "use of undefined type"(PrintModule 只扫函数签名, @@ -1270,40 +1206,22 @@ class CallGenCall(CallGenBase.CallGenBase): # 调用永远编译不过(NoVTableCrossMixinTest BaseB.caller 根因)。 anc_size_th: int = self.Gen.ClassGenEnum._get_type_size(anc_entry_th.Ty) 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: rawptr[llvmlite.Value] = llvmlite.build_bitcast( - builder, obj_ptr, i8_ptr_th2) - sib_delta_th: rawptr[llvmlite.Value] = llvmlite.const_int32( - pool, 0 - anc_size_th) - adj_th2: rawptr[llvmlite.Value] = llvmlite.build_gep( - builder, i8_ty_th2, obj_i8_th2, sib_delta_th) + i8_ty_th2: llvmlite.LLVMType* = llvmlite.Int8(pool) + i8_ptr_th2: llvmlite.LLVMType* = llvmlite.Ptr(pool, i8_ty_th2) + obj_i8_th2: llvmlite.Value* = llvmlite.build_bitcast(builder, obj_ptr, i8_ptr_th2) + sib_delta_th: llvmlite.Value* = llvmlite.const_int32(pool, 0 - anc_size_th) + adj_th2: 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( - pool, anc_entry_th.Ty) - llvmlite.module_ensure_opaque_for_type( - mod, pool, anc_ptr_ty_th2) - self_arg = llvmlite.build_bitcast( - builder, adj_th2, anc_ptr_ty_th2) + anc_ptr_ty_th2: llvmlite.LLVMType* = llvmlite.Ptr(pool, anc_entry_th.Ty) + llvmlite.module_ensure_opaque_for_type(mod, pool, anc_ptr_ty_th2) + self_arg = llvmlite.build_bitcast(builder, adj_th2, anc_ptr_ty_th2) else: # 定义类 struct 大小不可得(opaque/未加载):fail-fast - self.Gen.TypeGenErr.fatal_error( - cl, - f"this-adjust 兄弟 Mixin 定义类大小未知: 方法'{method_name}'" - f"定义类'{mc_anc}'的 struct 大小计算失败", - "InternalCompilerError") + self.Gen.TypeGenErr.fatal_error(cl, f"this-adjust 兄弟 Mixin 定义类大小未知: 方法'{method_name}'定义类'{mc_anc}'的 struct 大小计算失败", "InternalCompilerError") elif is_first_parent_th == 0: - self.Gen.TypeGenErr.fatal_error( - cl, - f"this-adjust 字段查找失败: 方法'{method_name}'定义类'{mc_anc}'" - f"首字段'{anc_first_name_th}'在类'{class_name}'/'{mc_anc}'布局中未找到", - "InternalCompilerError") + self.Gen.TypeGenErr.fatal_error(cl, f"this-adjust 字段查找失败: 方法'{method_name}'定义类'{mc_anc}'首字段'{anc_first_name_th}'在类'{class_name}'/'{mc_anc}'布局中未找到", "InternalCompilerError") elif is_first_parent_th == 0: - self.Gen.TypeGenErr.fatal_error( - cl, - f"this-adjust 子类结构体未注册: 方法'{method_name}'定义类'{mc_anc}'," - f"接收类'{class_name}'的 struct 未找到", - "InternalCompilerError") + self.Gen.TypeGenErr.fatal_error(cl, f"this-adjust 子类结构体未注册: 方法'{method_name}'定义类'{mc_anc}',接收类'{class_name}'的 struct 未找到", "InternalCompilerError") else: # 父类仅 __vtable__ 字段(无字段 CVTable 类):方法体不读 # 布局字段,无需调整(对齐 TPC:first_field_name None → ObjVal) @@ -1314,40 +1232,36 @@ class CallGenCall(CallGenBase.CallGenBase): elif is_first_parent_th == 0: # 父类 struct 未注册:fail-fast,绝不静默用未调整的 obj_ptr # 当 self(否则方法按自身布局读字段读到垃圾) - self.Gen.TypeGenErr.fatal_error( - cl, - f"this-adjust 父类结构体未注册: 方法'{method_name}'定义类'{mc_anc}'的 struct 未找到", - "InternalCompilerError") + self.Gen.TypeGenErr.fatal_error(cl, f"this-adjust 父类结构体未注册: 方法'{method_name}'定义类'{mc_anc}'的 struct 未找到", "InternalCompilerError") # self 参数按声明首参类型 coerce:跨模块 declare self 是类指针 # (%"sha1.Class"*,见 VpiReader._inject_method_declare),而对象指针 # 可能是 i8*(X|t.CPtr 联合简化)或 this-adjust 后的祖先指针,需 # bitcast 匹配声明签名(对齐 _call_method_on_ptr 的 coerce 块), # 否则 llc 报 call 参数类型与 declare 不一致。 if found_func is not None: - pp_self: rawptr[llvmlite.Param] = llvmlite.function_get_param_head(found_func) + pp_self: 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) + pty_self: llvmlite.LLVMType* = llvmlite.param_get_ty(pp_self) if pty_self is not None: - cself_tm: rawptr[llvmlite.Value] = self.Gen.ExprGenBase.coerce_to_type( - builder, self_arg, pty_self, None) + cself_tm: 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: rawptr[llvmlite.Value] = self_arg - tail: rawptr[llvmlite.Value] = self_arg + head: llvmlite.Value* = self_arg + tail: 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: rawptr[llvmlite.Param] = llvmlite.function_get_param_head(found_func) + cur_param_k: 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 while cur_param_k is not None: - arg_node_k: rawptr[ast.AST] = None + arg_node_k: ast.AST* = None if pi_k < can: arg_node_k = cargs.get(pi_k) else: @@ -1361,34 +1275,28 @@ class CallGenCall(CallGenBase.CallGenBase): if self._kwarg_name_matches(kw_k.arg, pname_k) == 1: arg_node_k = kw_k.value break - arg_val_k: rawptr[llvmlite.Value] = None + arg_val_k: 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) - arg_val_k = self.Gen.ExprGen.translate_value( - builder, pool, mod, arg_node_k, None, 0, trans, pty_k0) + pty_k0: llvmlite.LLVMType* = llvmlite.param_get_ty(cur_param_k) + arg_val_k = self.Gen.ExprGen.translate_value(builder, pool, mod, arg_node_k, None, 0, trans, pty_k0) if arg_val_k is None: if arg_node_k is not None: # (a) 实参节点存在但表达式翻译失败(返回 None)→ fail-fast。 # 禁止静默零值替换:那会把未解析实参(如跨模块同名冲突的 # Phase1.SHA1_LEN)伪造成合法实参。 - self.Gen.TypeGenErr.fatal_error( - arg_node_k, - f"方法调用 '{class_name}.{method_name}' 第 {pi_k + 1} 个形参" - f"的实参表达式翻译失败(返回 None,禁止按类型零值兜底)", - "TypeError") + self.Gen.TypeGenErr.fatal_error(arg_node_k, f"方法调用 '{class_name}.{method_name}' 第 {pi_k + 1} 个形参的实参表达式翻译失败(返回 None,禁止按类型零值兜底)","TypeError") continue # (b)/(c) 关键字/位置都未提供该形参:按形参类型补占位零值以保持 # 参数序列位置(避免后续实参左移错位)。此占位不是"表达式翻译 # 失败"的兜底(那条通路已在上方 fail-fast)。 - pty_k: rawptr[llvmlite.LLVMType] = llvmlite.param_get_ty(cur_param_k) + pty_k: llvmlite.LLVMType* = llvmlite.param_get_ty(cur_param_k) if pty_k is not None: arg_val_k = llvmlite.ConstZero(pool, pty_k) if arg_val_k is not None: - pty_k2: rawptr[llvmlite.LLVMType] = llvmlite.param_get_ty(cur_param_k) + pty_k2: llvmlite.LLVMType* = llvmlite.param_get_ty(cur_param_k) if pty_k2 is not None: - arg_val_k = self.Gen.ExprGenBase.coerce_to_type( - builder, arg_val_k, pty_k2, arg_node_k) + arg_val_k = self.Gen.ExprGenBase.coerce_to_type(builder, arg_val_k, pty_k2, arg_node_k) llvmlite.value_set_next(arg_val_k, None) llvmlite.value_set_next(tail, arg_val_k) tail = arg_val_k @@ -1398,21 +1306,17 @@ class CallGenCall(CallGenBase.CallGenBase): else: # 位置参数(原逻辑) for ai in range(can): - arg_node: rawptr[ast.AST] = cargs.get(ai) + arg_node: ast.AST* = cargs.get(ai) if arg_node is None: # (a) 实参节点缺失(AST 参数列表空洞)→ fail-fast,禁止静默跳过 # (跳过会减少 arg_count_eff,随后被"缺参默认填充"用零值补齐)。 - self.Gen.TypeGenErr.fatal_error( - cl, - f"方法调用 '{class_name}.{method_name}' 第 {ai + 1} 个实参" - f"节点缺失(AST 参数列表空洞,无法翻译)", - "TypeError") + self.Gen.TypeGenErr.fatal_error(cl, f"方法调用 '{class_name}.{method_name}' 第 {ai + 1} 个实参节点缺失(AST 参数列表空洞,无法翻译)", "TypeError") continue # 先取形参类型:单引号单字符字面量(CONST_CHAR)传给 str/指针 # 形参时需物化 1 字符字符串(translate_constant 依据 target_ty 判定), # 否则 coerce inttoptr 把字符值当指针 → strlen 访问低地址崩溃。 - pp: rawptr[llvmlite.Param] = None - pty: rawptr[llvmlite.LLVMType] = None + pp: llvmlite.Param* = None + pty: llvmlite.LLVMType* = None if found_func is not None: pp = llvmlite.function_get_param_head(found_func) pi: int = 0 @@ -1423,40 +1327,32 @@ class CallGenCall(CallGenBase.CallGenBase): pi += 1 if pp is not None: pty = llvmlite.param_get_ty(pp) - arg_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( - builder, pool, mod, arg_node, None, 0, trans, pty) + arg_val: 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。 # 禁止 continue 跳过:跳过会减少 arg_count_eff,随后"缺参默认 # 填充"用类型零值补齐该形参 —— 正是把未解析实参(如跨模块同名 # 冲突的 Phase1.SHA1_LEN)静默变成 alloc(..., 0) 的兜底通路。 # 用实参节点带出行号,报出被调用者与实参序号。 - self.Gen.TypeGenErr.fatal_error( - arg_node, - f"方法调用 '{class_name}.{method_name}' 第 {ai + 1} 个实参" - f"表达式翻译失败(返回 None,禁止按类型零值兜底)", - "TypeError") + self.Gen.TypeGenErr.fatal_error(arg_node, f"方法调用 '{class_name}.{method_name}' 第 {ai + 1} 个实参表达式翻译失败(返回 None,禁止按类型零值兜底)", "TypeError") continue # 按形参类型 coerce(self 是形参 0,第 ai 个实参对应形参 ai+1) # 修复: CDefine/i32 常量传给 i64 形参(如 MemBuddy.__init__ 的 size: sizet) # 未提升导致 call(i32) 与 define(i64) 不匹配,运行时读到垃圾高 32 位崩溃 if found_func is not None: if pty is not None: - arg_val = self.Gen.ExprGenBase.coerce_to_type( - builder, arg_val, pty, arg_node) + arg_val = self.Gen.ExprGenBase.coerce_to_type(builder, arg_val, pty, arg_node) else: # found_func=None(跨模块 stub 未注入):数组实参按 C 语义 # 衰减为元素指针(对齐 TPC _decay_array_to_ptr)。否则 # _ensure_method_declare 用 [N x ty]* 实参类型建 declare, # 与定义侧元素指针(如 md5.final 的 i8*)类型不匹配。 if arg_val.Ty is not None and self.Gen.ExprGenBase.is_ptr_type(arg_val.Ty) != 0: - arr_pointee_ma: rawptr[llvmlite.LLVMType] = arg_val.Ty.Pointee + arr_pointee_ma: llvmlite.LLVMType* = arg_val.Ty.Pointee if arr_pointee_ma is not None: match arr_pointee_ma: case llvmlite.LLVMType.Array(arr_et_ma, _): - decayed_ma: rawptr[llvmlite.Value] = llvmlite.build_gep_array( - builder, arr_pointee_ma, arr_et_ma, arg_val, - llvmlite.const_int32(pool, 0)) + decayed_ma: 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: arg_val = decayed_ma case _: @@ -1474,8 +1370,7 @@ class CallGenCall(CallGenBase.CallGenBase): mdf_default_count: int = 0 mdf_param_count: int = 0 if trans is not None and trans._funcs is not None: - mdf_entry: rawptr[GenTypes.FuncEntry] = self.Gen.CallGenLeafKit.find_func_entry_in_table( - trans._funcs, trans._func_count, lookup_name) + mdf_entry: GenTypes.FuncEntry* = self.Gen.CallGenLeafKit.find_func_entry_in_table(trans._funcs, trans._func_count, lookup_name) if mdf_entry is not None: mdf_defaults = mdf_entry.Defaults mdf_default_count = mdf_entry.DefaultCount @@ -1484,7 +1379,7 @@ class CallGenCall(CallGenBase.CallGenBase): # 调用方函数表)Defaults 非 None 会短路跳过,但下方"用快照重建默认值" # 分支依赖 mdf_gd(唯一持有 stdlib 常量快照处)——缺它必 fatal_error # (ListTest list[int].__new__ 根因) - mdf_gd: rawptr[GenTypes.FuncDefaultsEntry] = self.Gen.CallGenLeafKit.find_func_defaults(lookup_name) + mdf_gd: 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 @@ -1504,8 +1399,7 @@ class CallGenCall(CallGenBase.CallGenBase): else: vpi_sha1_p = self.Gen.StructGen.get_struct_sha1(class_name) if vpi_sha1_p is not None: - vpi_pa = self.Gen.CallGenBase._vpi_method_param_annot( - pool, vpi_sha1_p, class_name, method_name) + vpi_pa = self.Gen.CallGenBase._vpi_method_param_annot(pool, vpi_sha1_p, class_name, method_name) if vpi_pa is not None and vpi_pa[0] != '\0': vpi_pc2: int = 1 vi2: sizet = 0 @@ -1527,7 +1421,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: rawptr[llvmlite.Param] = llvmlite.function_get_param_head(found_func) + ppn_f: 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,15 +1444,11 @@ 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: rawptr[llvmlite.Value] = None + mdf_val: 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) + mdf_val = self.Gen.CallGenLeafKit._build_const_from_snapshot(pool, mod, mdf_gd, mdf_di, trans, builder) if mdf_val is None: - self.Gen.TypeGenErr.fatal_error( - cl, - f"跨模块默认参数无法重建(快照缺失,默认值需为简单常量): {lookup_name}", - "TypeError") + self.Gen.TypeGenErr.fatal_error(cl, f"跨模块默认参数无法重建(快照缺失,默认值需为简单常量): {lookup_name}", "TypeError") continue llvmlite.value_set_next(mdf_val, None) llvmlite.value_set_next(tail, mdf_val) @@ -1570,12 +1460,7 @@ class CallGenCall(CallGenBase.CallGenBase): # ⇒ 该形参确无默认值 ⇒ 调用点漏传必需实参。禁止零值兜底(历史 # 兜底会把漏传实参静默变成 0),fail-fast 报出被调用者与形参序号。 if mdf_default_count > 0 and mdf_pi < mdf_offset: - self.Gen.TypeGenErr.fatal_error( - cl, - f"方法调用 '{lookup_name}' 漏传必需实参:第 {mdf_pi + 1} 个形参" - f"无默认值(调用点仅提供 {arg_count_eff} 个实参," - f"该函数前 {mdf_offset} 个形参为必需)", - "TypeError") + self.Gen.TypeGenErr.fatal_error(cl, f"方法调用 '{lookup_name}' 漏传必需实参:第 {mdf_pi + 1} 个形参无默认值(调用点仅提供 {arg_count_eff} 个实参,该函数前 {mdf_offset} 个形参为必需)", "TypeError") mdf_pi += 1 continue # (b) 其余缺参只能来自"默认值信息缺失"(默认参数表按裸名注册、 @@ -1584,14 +1469,14 @@ class CallGenCall(CallGenBase.CallGenBase): # call/declare 的形参数量、填补尾随的声明可选参数;这**不是** # "表达式翻译失败"的兜底 —— 那条通路已在实参装配处 fail-fast。 if found_func is not None: - param_node_z: rawptr[llvmlite.Param] = llvmlite.function_get_param_head(found_func) + param_node_z: 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: rawptr[llvmlite.Value] = llvmlite.ConstZero(pool, zero_ty) + zero_ty: llvmlite.LLVMType* = llvmlite.param_get_ty(param_node_z) + zero_val: 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) @@ -1614,18 +1499,17 @@ class CallGenCall(CallGenBase.CallGenBase): and vpi_pa[seg_start_v + seg_len_v] != '@': seg_len_v += 1 if seg_no_v == seg_idx_v: - pty_v: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, llvmlite.Int8(pool)) + pty_v: llvmlite.LLVMType* = llvmlite.Ptr(pool, llvmlite.Int8(pool)) if seg_len_v > 0: seg_buf_v: bytes = stdlib.malloc(seg_len_v + 1) if seg_buf_v is not None: string.strncpy(seg_buf_v, vpi_pa + seg_start_v, seg_len_v) seg_buf_v[seg_len_v] = '\0' - rty_v: rawptr[llvmlite.LLVMType] = self.Gen.CallGenBase._vpi_resolve_param_annot_ty( - pool, seg_buf_v) + rty_v: llvmlite.LLVMType* = self.Gen.CallGenBase._vpi_resolve_param_annot_ty(pool, seg_buf_v) if rty_v is not None: pty_v = rty_v stdlib.free(seg_buf_v) - zero_val_v: rawptr[llvmlite.Value] = llvmlite.ConstZero(pool, pty_v) + zero_val_v: 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) @@ -1641,7 +1525,7 @@ class CallGenCall(CallGenBase.CallGenBase): if mc_entry is not None: mc_has_vt = mc_entry.HasVTable if mc_has_vt == 1 and mc_entry.VTableMethods is not None: - mc_methods_arr: sizet | t.CPtr = (sizet | t.CPtr)(mc_entry.VTableMethods) + mc_methods_arr: sizet* = (sizet*)(mc_entry.VTableMethods) for mc_mi in range(mc_entry.VTableMethodCount): mc_mname_addr: sizet = mc_methods_arr[mc_mi] if mc_mname_addr == 0: @@ -1660,16 +1544,12 @@ class CallGenCall(CallGenBase.CallGenBase): # 跨模块调用:创建 declare 声明,避免 llc 报 undefined value # 先按 vpi 定义侧形参 coerce 实参(宽度对齐),再建 declare(ABI 通用化) - head = self.Gen.CallGenLib._coerce_args_to_def_params( - pool, builder, call_name, head, total_count, cargs, 1, trans) + head = self.Gen.CallGenLib._coerce_args_to_def_params(pool, builder, call_name, head, total_count, cargs, 1, trans) self._ensure_method_declare(pool, mod, call_name, call_ret_ty, head, total_count) # 检查变长函数 + C ABI 提升(cargs 是实参 AST,self_offset=1 跳过 self) - is_variadic_3441: int = self.Gen.CallGenVa._check_and_promote_variadic_call( - pool, builder, mod, call_name, head, total_count, cargs, 1, trans) + is_variadic_3441: int = self.Gen.CallGenVa._check_and_promote_variadic_call(pool, builder, mod, call_name, head, total_count, cargs, 1, trans) # try-except:方法含 raise(EH 输出参数)时追加输出实参 + 调用后检测 - return self.Gen.CallGenLeafKit._emit_eh_guarded_call( - builder, pool, mod, trans, found_func, call_name, head, total_count, - call_ret_ty, is_variadic_3441) + return self.Gen.CallGenLeafKit._emit_eh_guarded_call(builder, pool, mod, trans, found_func, call_name, head, total_count, call_ret_ty, is_variadic_3441) # ============================================================ # _translate_list_builtin_call — list 内置方法内联翻译(兜底共享实现) @@ -1683,32 +1563,31 @@ class CallGenCall(CallGenBase.CallGenBase): # 翻译,绝不生成对 list 方法函数的跨模块调用(list 方法无对应 C 函数)。 # lm_obj 必须是已 load 的 list 对象指针 Ptr(list-struct)。 # ============================================================ - def _translate_list_builtin_call(self, pool: rawptr[memhub.MemBuddy], - builder: rawptr[llvmlite.IRBuilder], - mod: rawptr[llvmlite.LLVMModule], - cl: rawptr[ast.Call], + def _translate_list_builtin_call(self, pool: memhub.MemBuddy*, + builder: llvmlite.IRBuilder*, + mod: llvmlite.LLVMModule*, + cl: ast.Call*, lm_name: str, - lm_obj: rawptr[llvmlite.Value], + lm_obj: llvmlite.Value*, cargs: list[ast.AST*]*, can: sizet, - trans: rawptr[HT.Translator]) -> rawptr[llvmlite.Value]: + trans: HT.Translator*) -> 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 - i64_ty: rawptr[llvmlite.LLVMType] = llvmlite.Int64(pool) - i8_ty: rawptr[llvmlite.LLVMType] = llvmlite.Int8(pool) - i8_ptr_ty: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, i8_ty) + i64_ty: llvmlite.LLVMType* = llvmlite.Int64(pool) + i8_ty: llvmlite.LLVMType* = llvmlite.Int8(pool) + i8_ptr_ty: llvmlite.LLVMType* = llvmlite.Ptr(pool, i8_ty) # 元素类型 T:从 list 特化类型名解析(list[int]→i32、list[str]→i8*、 # 未知/指针元素→i8*),与 CallGenDispatch 尾部 list 分支一致 - lm_esty: rawptr[llvmlite.LLVMType] = \ + lm_esty: llvmlite.LLVMType* = \ self.Gen.StructGen.get_struct_type_from_value(lm_obj) lm_ename: str = None if lm_esty is not None: lm_ename = llvmlite.get_struct_name(lm_esty) - lm_elem_ty: rawptr[llvmlite.LLVMType] = None + lm_elem_ty: llvmlite.LLVMType* = None if lm_ename is not None: - lm_elem_ty = self.Gen.ExprGenName._list_elem_type_from_name( - pool, lm_ename) + lm_elem_ty = self.Gen.ExprGenName._list_elem_type_from_name(pool, lm_ename) if lm_elem_ty is None: lm_elem_ty = i8_ptr_ty @@ -1716,98 +1595,88 @@ 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: 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) + g_idx0: llvmlite.Value* = llvmlite.const_int64(pool, 0) + g_dpp: llvmlite.Value* = llvmlite.build_gep(builder, i64_ty, lm_obj, g_idx0) + g_data: llvmlite.Value* = llvmlite.build_load(builder, i8_ptr_ty, g_dpp) # 加载 __elem_size__ (偏移 32, index 4) - 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) + g_idx4: llvmlite.Value* = llvmlite.const_int64(pool, 4) + g_epp: llvmlite.Value* = llvmlite.build_gep(builder, i64_ty, lm_obj, g_idx4) + g_esize: llvmlite.Value* = llvmlite.build_load(builder, i64_ty, g_epp) # 翻译 index - g_idx_node: rawptr[ast.AST] = cargs.get(0) - g_idx_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( - builder, pool, mod, g_idx_node, None, 0, trans) + g_idx_node: ast.AST* = cargs.get(0) + g_idx_val: 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: rawptr[llvmlite.Value] = self.Gen.ExprGenBase.coerce_to_type( - builder, g_idx_val, i64_ty, g_idx_node) - 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) + g_idx_i64: llvmlite.Value* = self.Gen.ExprGenBase.coerce_to_type(builder, g_idx_val, i64_ty, g_idx_node) + g_offset: llvmlite.Value* = llvmlite.build_mul(builder, g_idx_i64, g_esize) + g_addr: llvmlite.Value* = llvmlite.build_gep(builder, i8_ty, g_data, g_offset) if g_addr is not None: - g_ep: rawptr[llvmlite.Value] = llvmlite.build_bitcast( - builder, g_addr, llvmlite.Ptr(pool, lm_elem_ty)) + g_ep: 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) # 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: 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: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( - builder, pool, mod, s_idx_node, None, 0, trans) - s_val_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( - builder, pool, mod, s_val_node, None, 0, trans) + s_idx0: llvmlite.Value* = llvmlite.const_int64(pool, 0) + s_dpp: llvmlite.Value* = llvmlite.build_gep(builder, i64_ty, lm_obj, s_idx0) + s_data: llvmlite.Value* = llvmlite.build_load(builder, i8_ptr_ty, s_dpp) + s_idx4: llvmlite.Value* = llvmlite.const_int64(pool, 4) + s_epp: llvmlite.Value* = llvmlite.build_gep(builder, i64_ty, lm_obj, s_idx4) + s_esize: llvmlite.Value* = llvmlite.build_load(builder, i64_ty, s_epp) + s_idx_node: ast.AST* = cargs.get(0) + s_val_node: ast.AST* = cargs.get(1) + s_idx_val: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, mod, s_idx_node, None, 0, trans) + s_val_val: 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: rawptr[llvmlite.Value] = self.Gen.ExprGenBase.coerce_to_type( - builder, s_idx_val, i64_ty, s_idx_node) - 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) + s_idx_i64: llvmlite.Value* = self.Gen.ExprGenBase.coerce_to_type(builder, s_idx_val, i64_ty, s_idx_node) + s_offset: llvmlite.Value* = llvmlite.build_mul(builder, s_idx_i64, s_esize) + s_addr: llvmlite.Value* = llvmlite.build_gep(builder, i8_ty, s_data, s_offset) if s_addr is not None: - s_val_elem: rawptr[llvmlite.Value] = self.Gen.ExprGenBase.coerce_to_type( - builder, s_val_val, lm_elem_ty, s_val_node) - s_ep: rawptr[llvmlite.Value] = llvmlite.build_bitcast( - builder, s_addr, llvmlite.Ptr(pool, lm_elem_ty)) + s_val_elem: llvmlite.Value* = self.Gen.ExprGenBase.coerce_to_type(builder, s_val_val, lm_elem_ty, s_val_node) + s_ep: 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) return None # pop: 返回最后一个元素,count-- elif string.strcmp(lm_name, "pop") == 0: - 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)) + p_idx1: llvmlite.Value* = llvmlite.const_int64(pool, 1) + p_cpp: llvmlite.Value* = llvmlite.build_gep(builder, i64_ty, lm_obj, p_idx1) + p_count: llvmlite.Value* = llvmlite.build_load(builder, i64_ty, p_cpp) + p_nc: llvmlite.Value* = llvmlite.build_sub(builder, p_count, llvmlite.const_int64(pool, 1)) llvmlite.build_store(builder, p_nc, p_cpp) - 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) + p_idx0: llvmlite.Value* = llvmlite.const_int64(pool, 0) + p_dpp: llvmlite.Value* = llvmlite.build_gep(builder, i64_ty, lm_obj, p_idx0) + p_data: llvmlite.Value* = llvmlite.build_load(builder, i8_ptr_ty, p_dpp) + p_idx4: llvmlite.Value* = llvmlite.const_int64(pool, 4) + p_epp: llvmlite.Value* = llvmlite.build_gep(builder, i64_ty, lm_obj, p_idx4) + p_esize: 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: 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) + p_offset: llvmlite.Value* = llvmlite.build_mul(builder, p_nc, p_esize) + p_addr: llvmlite.Value* = llvmlite.build_gep(builder, i8_ty, p_data, p_offset) if p_addr is not None: - p_ep: rawptr[llvmlite.Value] = llvmlite.build_bitcast( - builder, p_addr, llvmlite.Ptr(pool, lm_elem_ty)) + p_ep: 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: rawptr[llvmlite.Value] = llvmlite.const_int64(pool, 1) - c_cpp: rawptr[llvmlite.Value] = llvmlite.build_gep(builder, i64_ty, lm_obj, c_idx1) + c_idx1: llvmlite.Value* = llvmlite.const_int64(pool, 1) + c_cpp: 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: rawptr[llvmlite.Value] = llvmlite.const_int64(pool, 5) - it_ipp: rawptr[llvmlite.Value] = llvmlite.build_gep(builder, i64_ty, lm_obj, it_idx5) + it_idx5: llvmlite.Value* = llvmlite.const_int64(pool, 5) + it_ipp: 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: rawptr[llvmlite.Value] = llvmlite.const_int64(pool, 1) - l_cpp: rawptr[llvmlite.Value] = llvmlite.build_gep(builder, i64_ty, lm_obj, l_idx1) + l_idx1: llvmlite.Value* = llvmlite.const_int64(pool, 1) + l_cpp: 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) @@ -1819,20 +1688,17 @@ class CallGenCall(CallGenBase.CallGenBase): if ap_sha1 is None: # 依赖模块未编译(_list 未预加入编译链):fail-fast, # 绝不静默跳过 append(元素永远不会被加入列表) - self.Gen.TypeGenErr.fatal_error( - cl, "list.append: 找不到 _list 模块 SHA1(依赖模块未编译)", - "InternalCompilerError") + self.Gen.TypeGenErr.fatal_error(cl, "list.append: 找不到 _list 模块 SHA1(依赖模块未编译)", "InternalCompilerError") if ap_sha1 is not None: # 特化类名提取:list.append 的符号名是 # {sha1}.list[AST|CPtr].append(带类型参数特化名),而非 # {sha1}.list.append。lm_obj 类型即特化结构体 Ptr(list[...]), # 从类型解析特化类名拼接调用名,否则 ld.lld undefined symbol ap_spec_nm: str = None - ap_struct_ty: rawptr[llvmlite.LLVMType] = \ + ap_struct_ty: llvmlite.LLVMType* = \ self.Gen.StructGen.get_struct_type_from_value(lm_obj) if ap_struct_ty is not None: - ap_spec_nm = self.Gen.StructGen.get_class_name_by_type( - pool, ap_struct_ty) + ap_spec_nm = self.Gen.StructGen.get_class_name_by_type(pool, ap_struct_ty) if ap_spec_nm is None: ap_spec_nm = "list" # 触发泛型特化翻译(幂等,MethodsEmitted 防重入) @@ -1851,7 +1717,7 @@ class CallGenCall(CallGenBase.CallGenBase): base_buf_ap[base_len_ap] = '\0' string.strncpy(arg_buf_ap, lbkt_ap + 1, arg_len_ap) arg_buf_ap[arg_len_ap] = '\0' - args_ap: list[str] | t.CPtr = list[str](pool, 8) + args_ap: list[str]* = list[str](pool, 8) if args_ap is not None: # 逗号分隔多类型实参(list[X] / dict[K, V]) cur_ap: str = arg_buf_ap @@ -1867,24 +1733,21 @@ class CallGenCall(CallGenBase.CallGenBase): seg_buf_ap[seg_len_ap] = '\0' args_ap.append(seg_buf_ap) cur_ap = comma_ap + 1 - self.Gen.ClassGenGeneric._specialize_generic_class( - trans, base_buf_ap, args_ap) + self.Gen.ClassGenGeneric._specialize_generic_class(trans, base_buf_ap, args_ap) # 调用名 "{sha1}.{spec}.append": # sha1(16) + '.'(1) + spec + '.append'(7) + NUL(1) = spec + 25 ap_mlen: sizet = string.strlen(ap_sha1) + \ string.strlen(ap_spec_nm) + 26 ap_mangled: str = pool.alloc(ap_mlen) if ap_mangled is not None: - 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: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( - builder, pool, mod, ap_item_node, None, 0, trans) + viperlib.snprintf(ap_mangled, ap_mlen, "%s.%s.append", ap_sha1, ap_spec_nm) + ap_item_node: ast.AST* = cargs.get(0) + ap_item_val: 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) llvmlite.value_set_next(ap_item_val, None) llvmlite.value_set_next(lm_obj, ap_item_val) - ap_ret_ty: rawptr[llvmlite.LLVMType] = llvmlite.Int32(pool) + ap_ret_ty: llvmlite.LLVMType* = llvmlite.Int32(pool) self._ensure_method_declare(pool, mod, ap_mangled, ap_ret_ty, lm_obj, 2) return llvmlite.build_call(builder, ap_mangled, lm_obj, 2, ap_ret_ty, 0) @@ -1903,12 +1766,12 @@ class CallGenCall(CallGenBase.CallGenBase): # ============================================================ # ============================================================ - def _translate_super_call(self, pool: rawptr[memhub.MemBuddy], - builder: rawptr[llvmlite.IRBuilder], - mod: rawptr[llvmlite.LLVMModule], - cl: rawptr[ast.Call], + def _translate_super_call(self, pool: memhub.MemBuddy*, + builder: llvmlite.IRBuilder*, + mod: llvmlite.LLVMModule*, + cl: ast.Call*, method_name: str, - trans: rawptr[HT.Translator]) -> rawptr[llvmlite.Value]: + trans: HT.Translator*) -> 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,8 +1782,7 @@ class CallGenCall(CallGenBase.CallGenBase): # 不用 Mixin 字段:TPV Mixin 字段按声明类独立布局(Generator 多继承 # 去重只保留首个声明),ClassGenMixin 写的 CurClassName 与 CallGenMixin # 读的位置偏移不一致 → 运行时读到空 → super() 误报"只能在类方法内使用"。 - self_entry: rawptr[GenTypes.VarEntry] = self.Gen.VarGen.lookup_var_entry( - trans.SymTab, "self") + self_entry: 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") if self_entry is None: @@ -1932,7 +1794,7 @@ class CallGenCall(CallGenBase.CallGenBase): return None # 2. 沿 MRO 跳过自身,找第一个定义 method 的祖先类 anc: str = None - mro_sp: sizet | t.CPtr = self.Gen.StructGen.get_mro_chain(pool, cur_class) + mro_sp: sizet* = self.Gen.StructGen.get_mro_chain(pool, cur_class) mi_sp: int = 1 while mro_sp is not None and mro_sp[mi_sp] != 0: anc_sp: str = (str | t.CPtr)(mro_sp[mi_sp]) @@ -1956,12 +1818,12 @@ 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: rawptr[llvmlite.Value] = None + self_ptr: llvmlite.Value* = None match self_entry.Alloca.Ty: case llvmlite.LLVMType.Ptr(inner1): match inner1: case llvmlite.LLVMType.Ptr(inner2): - obj_ty_sp: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, inner2) + obj_ty_sp: llvmlite.LLVMType* = llvmlite.Ptr(pool, inner2) self_ptr = llvmlite.build_load(builder, obj_ty_sp, self_entry.Alloca) case _: self_ptr = llvmlite.build_load(builder, self_entry.Alloca.Ty, self_entry.Alloca) @@ -1970,15 +1832,14 @@ class CallGenCall(CallGenBase.CallGenBase): if self_ptr is None: return None # 3. this_adjust(字节偏移法:父类字段区在子类中的偏移差) - self_arg: rawptr[llvmlite.Value] = self_ptr + self_arg: llvmlite.Value* = self_ptr if string.strcmp(anc, cur_class) != 0: - anc_entry_sp: rawptr[GenTypes.StructEntry] = self.Gen.StructGen.find_struct(anc) + anc_entry_sp: 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: rawptr[GenTypes.FieldEntry] = self.Gen.StructGen._get_field_entry( - anc_entry_sp, afi_sp) + afe_sp: 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) if afn_sp is not None and string.strcmp(afn_sp, "__vtable__") != 0: @@ -1986,29 +1847,22 @@ class CallGenCall(CallGenBase.CallGenBase): break afi_sp += 1 if first_name_sp is not None: - sub_entry_sp: rawptr[GenTypes.StructEntry] = self.Gen.StructGen.find_struct( - cur_class) + sub_entry_sp: GenTypes.StructEntry* = self.Gen.StructGen.find_struct(cur_class) if sub_entry_sp is not None: - anc_field_sp: rawptr[GenTypes.FieldEntry] = self.Gen.StructGen.lookup_field( - anc_entry_sp.Ty, first_name_sp) - sub_field_sp: rawptr[GenTypes.FieldEntry] = self.Gen.StructGen.lookup_field( - sub_entry_sp.Ty, first_name_sp) + anc_field_sp: GenTypes.FieldEntry* = self.Gen.StructGen.lookup_field(anc_entry_sp.Ty, first_name_sp) + sub_field_sp: 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( - pool, anc_entry_sp, anc_field_sp.Index) - sub_off_sp: int = self._field_byte_offset( - pool, sub_entry_sp, sub_field_sp.Index) + anc_off_sp: int = self._field_byte_offset(pool, anc_entry_sp, anc_field_sp.Index) + sub_off_sp: int = self._field_byte_offset(pool, sub_entry_sp, sub_field_sp.Index) delta_sp: int = sub_off_sp - anc_off_sp 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: rawptr[llvmlite.Value] = llvmlite.build_bitcast( - builder, self_ptr, i8_ptr_sp) - 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) + i8_ty_sp: llvmlite.LLVMType* = llvmlite.Int8(pool) + i8_ptr_sp: llvmlite.LLVMType* = llvmlite.Ptr(pool, i8_ty_sp) + obj_i8_sp: llvmlite.Value* = llvmlite.build_bitcast(builder, self_ptr, i8_ptr_sp) + dval_sp: llvmlite.Value* = llvmlite.const_int32(pool, delta_sp) + adj_sp: 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) + anc_ptr_sp: llvmlite.LLVMType* = llvmlite.Ptr(pool, anc_entry_sp.Ty) # 同上:跨模块祖先类型 bitcast 前确保 opaque 声明, # 否则 llc 报 "use of undefined type" llvmlite.module_ensure_opaque_for_type(mod, pool, anc_ptr_sp) @@ -2018,7 +1872,7 @@ class CallGenCall(CallGenBase.CallGenBase): if anc_lookup is None: return None viperlib.snprintf(anc_lookup, 160, "%s.%s", anc, method_name) - found_func: rawptr[llvmlite.Function] = self.find_func_in_module(mod, anc_lookup) + found_func: llvmlite.Function* = self.find_func_in_module(mod, anc_lookup) call_name: str = anc_lookup anc_sha1_sp: str = self.Gen.StructGen.get_struct_sha1(anc) if anc_sha1_sp is None: @@ -2038,16 +1892,16 @@ class CallGenCall(CallGenBase.CallGenBase): if cargs_sp is not None: can_sp = len(cargs_sp) llvmlite.value_set_next(self_arg, None) - head: rawptr[llvmlite.Value] = self_arg - tail: rawptr[llvmlite.Value] = self_arg + head: llvmlite.Value* = self_arg + tail: 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) + arg_node_sp: ast.AST* = cargs_sp.get(ai_sp) if arg_node_sp is None: continue # 先取形参类型(char 字面量 → str 形参需物化字符串,见 translate_constant) - pp_sp: rawptr[llvmlite.Param] = None - pty_sp: rawptr[llvmlite.LLVMType] = None + pp_sp: llvmlite.Param* = None + pty_sp: llvmlite.LLVMType* = None if found_func is not None: pp_sp = llvmlite.function_get_param_head(found_func) pi_sp: int = 0 @@ -2058,24 +1912,20 @@ class CallGenCall(CallGenBase.CallGenBase): pi_sp += 1 if pp_sp is not None: pty_sp = llvmlite.param_get_ty(pp_sp) - arg_val_sp: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( - builder, pool, mod, arg_node_sp, None, 0, trans, pty_sp) + arg_val_sp: 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 if pty_sp is not None: - arg_val_sp = self.Gen.ExprGenBase.coerce_to_type( - builder, arg_val_sp, pty_sp, arg_node_sp) + arg_val_sp = self.Gen.ExprGenBase.coerce_to_type(builder, arg_val_sp, pty_sp, arg_node_sp) else: # found_func=None:数组实参按 C 语义衰减为元素指针 # (与 _translate_method_call 一致,避免 declare 类型不匹配) if arg_val_sp.Ty is not None and self.Gen.ExprGenBase.is_ptr_type(arg_val_sp.Ty) != 0: - arr_pointee_sp: rawptr[llvmlite.LLVMType] = arg_val_sp.Ty.Pointee + arr_pointee_sp: llvmlite.LLVMType* = arg_val_sp.Ty.Pointee if arr_pointee_sp is not None: match arr_pointee_sp: case llvmlite.LLVMType.Array(arr_et_sp, _): - decayed_sp: rawptr[llvmlite.Value] = llvmlite.build_gep_array( - builder, arr_pointee_sp, arr_et_sp, arg_val_sp, - llvmlite.const_int32(pool, 0)) + decayed_sp: 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: arg_val_sp = decayed_sp case _: @@ -2085,23 +1935,21 @@ class CallGenCall(CallGenBase.CallGenBase): tail = arg_val_sp arg_count_sp += 1 # 6. 返回类型:found_func → 特殊方法 → text.ll/vpi - ret_ty_sp: rawptr[llvmlite.LLVMType] = llvmlite.Int32(pool) + ret_ty_sp: llvmlite.LLVMType* = llvmlite.Int32(pool) if found_func is not None: - frt_sp: rawptr[llvmlite.LLVMType] = llvmlite.function_get_ret_ty(found_func) + frt_sp: llvmlite.LLVMType* = llvmlite.function_get_ret_ty(found_func) if frt_sp is not None: ret_ty_sp = frt_sp else: - sp_ty_sp: rawptr[llvmlite.LLVMType] = self._special_method_ret_ty(pool, anc, method_name) + sp_ty_sp: llvmlite.LLVMType* = self._special_method_ret_ty(pool, anc, method_name) if sp_ty_sp is not None: ret_ty_sp = sp_ty_sp else: - looked_sp: rawptr[llvmlite.LLVMType] = self._LookupMethodRetTyFromTextLL( - pool, anc_sha1_sp, anc, method_name) + looked_sp: llvmlite.LLVMType* = self._LookupMethodRetTyFromTextLL(pool, anc_sha1_sp, anc, method_name) if looked_sp is not None: ret_ty_sp = looked_sp else: - vpi_ret_sp: rawptr[llvmlite.LLVMType] = self._lookup_method_ret_ty_via_vpi( - pool, anc_sha1_sp, anc, method_name) + vpi_ret_sp: llvmlite.LLVMType* = self._lookup_method_ret_ty_via_vpi(pool, anc_sha1_sp, anc, method_name) if vpi_ret_sp is not None: ret_ty_sp = vpi_ret_sp else: @@ -2115,8 +1963,7 @@ class CallGenCall(CallGenBase.CallGenBase): # 7. 跨模块:创建 declare;生成 call if found_func is None: self._ensure_method_declare(pool, mod, call_name, ret_ty_sp, head, arg_count_sp) - is_variadic_sp: int = self.Gen.CallGenVa._check_and_promote_variadic_call( - pool, builder, mod, call_name, head, arg_count_sp, cargs_sp, 1, trans) + is_variadic_sp: int = self.Gen.CallGenVa._check_and_promote_variadic_call(pool, builder, mod, call_name, head, arg_count_sp, cargs_sp, 1, trans) return llvmlite.build_call(builder, call_name, head, arg_count_sp, ret_ty_sp, is_variadic_sp) # ============================================================ # _field_byte_offset — 计算字段在结构体布局中的字节偏移 @@ -2127,8 +1974,8 @@ class CallGenCall(CallGenBase.CallGenBase): # ============================================================ # ============================================================ - def _field_byte_offset(self, pool: rawptr[memhub.MemBuddy], - entry: rawptr[GenTypes.StructEntry], + def _field_byte_offset(self, pool: memhub.MemBuddy*, + entry: GenTypes.StructEntry*, field_index: int) -> int: """计算字段在结构体中的字节偏移(含对齐 padding),无法计算返回 0""" if pool is None or entry is None or entry.Ty is None or field_index < 0: @@ -2143,7 +1990,7 @@ class CallGenCall(CallGenBase.CallGenBase): i_fb: int = 0 while cur_fb is not None and i_fb < field_index: if cur_fb.Ty is not None: - fty_fb: rawptr[llvmlite.LLVMType] = (rawptr[llvmlite.LLVMType])(cur_fb.Ty) + fty_fb: llvmlite.LLVMType* = (llvmlite.LLVMType*)(cur_fb.Ty) fsize_fb: int = self.Gen.ClassGenEnum._get_type_size(fty_fb) falign_fb: int = self.Gen.ClassGenEnum._get_type_align(fty_fb) if is_packed_fb == 0 and falign_fb > 1: @@ -2155,7 +2002,7 @@ class CallGenCall(CallGenBase.CallGenBase): i_fb += 1 # 字段自身对齐 if cur_fb is not None and cur_fb.Ty is not None: - fty2_fb: rawptr[llvmlite.LLVMType] = (rawptr[llvmlite.LLVMType])(cur_fb.Ty) + fty2_fb: llvmlite.LLVMType* = (llvmlite.LLVMType*)(cur_fb.Ty) falign2_fb: int = self.Gen.ClassGenEnum._get_type_align(fty2_fb) if is_packed_fb == 0 and falign2_fb > 1: rem2_fb: int = offset_fb % falign2_fb diff --git a/App/lib/core/Gen/Call/CallGenCtor.vp b/App/lib/core/Gen/Call/CallGenCtor.vp index 1c79888..c7ab31c 100644 --- a/App/lib/core/Gen/Call/CallGenCtor.vp +++ b/App/lib/core/Gen/Call/CallGenCtor.vp @@ -16,13 +16,8 @@ from . import CallGenBase # ============================================================ # CallGenCtor - CallGenMixin 拆分(阶段 B):结构体构造 / 枚举构造 / 泛型构造 / 类型转换 -# -# 继承 CallGenBase(1 级,TPV self 调用仅支持 1 级父类)。 -# 跨 Mixin 调用统一走 HandlesExprCall 委托(经 _g_gen)。 -# @t.NoVTable:静态绑定。 # ============================================================ -@t.NoVTable -class CallGenCtor(CallGenBase.CallGenBase): +novirtual class CallGenCtor(CallGenBase.CallGenBase): """结构体构造 / 枚举构造 / 泛型构造 / 类型转换""" # ============================================================ @@ -32,63 +27,56 @@ class CallGenCtor(CallGenBase.CallGenBase): # 遍历所有字段,对有默认值的字段翻译并 store # 显式参数(位置/关键字)后续会覆盖默认值 # ============================================================ - def _apply_struct_defaults(self, pool: rawptr[memhub.MemBuddy], - builder: rawptr[llvmlite.IRBuilder], - mod: rawptr[llvmlite.LLVMModule], - struct_ty: rawptr[llvmlite.LLVMType], + def _apply_struct_defaults(self, pool: memhub.MemBuddy*, + builder: llvmlite.IRBuilder*, + mod: llvmlite.LLVMModule*, + struct_ty: llvmlite.LLVMType*, class_name: str, - tmp: rawptr[llvmlite.Value], - trans: rawptr[HT.Translator]): + tmp: llvmlite.Value*, + trans: HT.Translator*): """应用结构体字段的默认值""" # 用类型指针定位 entry,规避跨模块同名 find_struct 找错 - entry: rawptr[GenTypes.StructEntry] = self.Gen.StructGen.find_struct_by_type(struct_ty) + entry: GenTypes.StructEntry* = self.Gen.StructGen.find_struct_by_type(struct_ty) if entry is None: # fast-fail: 结构体类型未注册,静默 return 会导致字段未初始化 - VLogger.error( - f"结构体类型未注册,无法应用默认值: {class_name}", - "HandlesExprCall") + VLogger.error(f"结构体类型未注册,无法应用默认值: {class_name}", "HandlesExprCall") return for fi in range(entry.FieldCount): - fe: rawptr[GenTypes.FieldEntry] = self.Gen.StructGen._get_field_entry( - entry, fi) + fe: GenTypes.FieldEntry* = self.Gen.StructGen._get_field_entry(entry, fi) if fe is None: # fast-fail: 字段索引越界(entry.FieldCount 与实际不一致) - VLogger.error( - f"字段索引越界,无法获取字段 entry: {class_name}", - "HandlesExprCall") + VLogger.error(f"字段索引越界,无法获取字段 entry: {class_name}", "HandlesExprCall") continue - if fe.DefaultVal is None: - continue # 合理跳过:无默认值的字段 + if fe.DefaultVal is None: continue # 合理跳过:无默认值的字段 # 静态数组字段 + 列表字面量默认值 → 整体置零 + 逐元素 GEP+store # (与 _generate_before_init 一致;translate_value 会把列表字面量 # 误译成动态 list 对象指针,coerce 到 [N x elem] 会失败)。 # 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: rawptr[llvmlite.Value] = llvmlite.build_gep_struct( - builder, struct_ty, fe.Ty, tmp, fe.Index) + field_ptr_arr2: llvmlite.Value* = llvmlite.build_gep_struct(builder, struct_ty, fe.Ty, tmp, fe.Index) if field_ptr_arr2 is not None: - zero_arr2: rawptr[llvmlite.Value] = llvmlite.ConstZero(pool, fe.Ty) + zero_arr2: 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) + # owner_ctx 只服务空元素 fail-fast 报文(类名 + 字段名 + 下标) + sd_ctx: str = pool.alloc(192) + if sd_ctx is not None: + fname_sd: str = fe.Name + if fname_sd is None: + fname_sd = "?" + viperlib.snprintf(sd_ctx, 192, "类 %s 字段 %s(结构体构造默认值):", class_name, fname_sd) + self.Gen.AssignGen._init_global_array_from_list(builder, pool, mod, field_ptr_arr2, fe.DefaultVal, trans, sd_ctx) continue - default_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( - builder, pool, mod, fe.DefaultVal, None, 0, trans, fe.Ty) + default_val: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, mod, fe.DefaultVal, None, 0, trans, fe.Ty) if default_val is None: # fast-fail: 默认值翻译失败(如引用了未定义符号) - VLogger.error( - f"字段默认值翻译失败: {class_name}", - "HandlesExprCall") + VLogger.error(f"字段默认值翻译失败: {class_name}", "HandlesExprCall") continue - field_ptr: rawptr[llvmlite.Value] = llvmlite.build_gep_struct( - builder, struct_ty, fe.Ty, tmp, fe.Index) + field_ptr: 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 不匹配) - VLogger.error( - f"字段 GEP 失败,类型不匹配: {class_name}", - "HandlesExprCall") + VLogger.error(f"字段 GEP 失败,类型不匹配: {class_name}", "HandlesExprCall") continue default_val = self.Gen.ExprGenBase.coerce_to_type(builder, default_val, fe.Ty, fe.DefaultVal) llvmlite.build_store(builder, default_val, field_ptr) @@ -106,14 +94,14 @@ class CallGenCtor(CallGenBase.CallGenBase): # ============================================================ # ============================================================ - def _translate_struct_ctor(self, pool: rawptr[memhub.MemBuddy], - builder: rawptr[llvmlite.IRBuilder], - mod: rawptr[llvmlite.LLVMModule], - struct_ty: rawptr[llvmlite.LLVMType], + def _translate_struct_ctor(self, pool: memhub.MemBuddy*, + builder: llvmlite.IRBuilder*, + mod: llvmlite.LLVMModule*, + struct_ty: llvmlite.LLVMType*, class_name: str, cargs: list[ast.AST*]*, can: sizet, - trans: rawptr[HT.Translator]) -> rawptr[llvmlite.Value]: + trans: HT.Translator*) -> llvmlite.Value*: """结构体构造函数:按字段顺序 store 参数值,返回结构体值 OOP 结构体:alloca → call __before_init__(ptr) → call __init__(ptr, args) 或 store 参数 → load @@ -122,17 +110,17 @@ class CallGenCtor(CallGenBase.CallGenBase): # 创建临时 alloca # 确保跨模块结构体的完整定义在当前模块中可用(供 alloca 分配空间) self.Gen.StructGen.ensure_struct_def_in_module(pool, mod, struct_ty) - tmp: rawptr[llvmlite.Value] = self.Gen.VarGen._alloca_at_entry(builder, struct_ty) + tmp: 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 的 # fatal_error 显示构造调用行号(本函数无 cl 参数,实参节点最接近调用点) - diag_node_ct: rawptr[ast.AST] = None + diag_node_ct: ast.AST* = None if cargs is not None and len(cargs) > 0: diag_node_ct = cargs.get(0) # 检查是否为 OOP 结构体(用类型指针定位 entry,规避跨模块同名 find_struct 找错) - ctor_entry: rawptr[GenTypes.StructEntry] = self.Gen.StructGen.find_struct_by_type(struct_ty) + ctor_entry: 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 @@ -145,7 +133,7 @@ class CallGenCtor(CallGenBase.CallGenBase): if init_lookup_name is not None: viperlib.snprintf(init_lookup_name, 128, "%s.__init__", class_name) # 方案1: 检查当前模块的函数声明 - init_found_func: rawptr[llvmlite.Function] = self.find_func_in_module(mod, init_lookup_name) + init_found_func: llvmlite.Function* = self.find_func_in_module(mod, init_lookup_name) if init_found_func is not None: is_oop = 1 if ctor_entry is not None: @@ -153,7 +141,7 @@ class CallGenCtor(CallGenBase.CallGenBase): ctor_entry.HasInit = 1 else: # 方案2: 检查全局默认参数表(翻译时填充,不依赖 stub 注入) - init_defaults_entry: rawptr[GenTypes.FuncDefaultsEntry] = self.Gen.CallGenLeafKit.find_func_defaults(init_lookup_name) + init_defaults_entry: 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 +150,7 @@ class CallGenCtor(CallGenBase.CallGenBase): if is_oop != 0: # 存储指针:默认用 alloca,如果有 __new__ 则用 __new__ 返回的指针 - storage_ptr: rawptr[llvmlite.Value] = tmp + storage_ptr: llvmlite.Value* = tmp # 如果有 __new__,调用 __new__(tmp, args...) 获取实际存储指针 # __new__ 签名与 __init__ 一样(self + args),返回 Ptr(struct_ty) @@ -171,24 +159,21 @@ class CallGenCtor(CallGenBase.CallGenBase): has_new_flag = ctor_entry.HasNew # 注意: __new__ 是可选的,不推断 HasNew(仅 __init__ 是 OOP 类标准方法) if has_new_flag != 0: - new_arg_vals: sizet | t.CPtr = pool.alloc(8 * 32) + new_arg_vals: sizet* = pool.alloc(8 * 32) if new_arg_vals is not None: string.memset(new_arg_vals, 0, 8 * 32) new_arg_count: int = 0 for nai in range(can): - new_arg_node: rawptr[ast.AST] = cargs.get(nai) + new_arg_node: ast.AST* = cargs.get(nai) if new_arg_node is None: continue - new_av: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( - builder, pool, mod, new_arg_node, None, 0, trans) + new_av: 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: 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) + new_ptr: 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: storage_ptr = new_ptr # __new__ 只保证返回"实例存储指针",声明类型通常是 @@ -198,15 +183,14 @@ class CallGenCtor(CallGenBase.CallGenBase): # 查不到类名,误报"跨模块调用 'parser.add_argument' 找不到模块 SHA1"。 # bitcast 只改类型层视图,运行时零开销(指针位不变)。 if new_ptr.Ty is not None: - nw_ty: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, struct_ty) + nw_ty: llvmlite.LLVMType* = llvmlite.Ptr(pool, struct_ty) if uint64(new_ptr.Ty) != uint64(nw_ty): - nw_bc: rawptr[llvmlite.Value] = llvmlite.build_bitcast(builder, new_ptr, nw_ty) + nw_bc: llvmlite.Value* = llvmlite.build_bitcast(builder, new_ptr, nw_ty) if nw_bc is not None: storage_ptr = nw_bc # OOP 结构体:调用 __before_init__ 进行零值填充和默认值赋值 - self.Gen.CallGenCall._call_method_on_ptr(pool, builder, mod, class_name, - "__before_init__", storage_ptr, None, 0, trans, diag_node_ct) + self.Gen.CallGenCall._call_method_on_ptr(pool, builder, mod, class_name,"__before_init__", storage_ptr, None, 0, trans, diag_node_ct) # 如果有 __init__,调用 __init__(ptr, args...) # 注意: 仅依据 ctor_entry.HasInit 判断,不强制推断 @@ -216,44 +200,38 @@ class CallGenCtor(CallGenBase.CallGenBase): has_init_flag = ctor_entry.HasInit if has_init_flag != 0: # 翻译构造函数参数 - arg_vals: sizet | t.CPtr = pool.alloc(8 * 32) + arg_vals: sizet* = pool.alloc(8 * 32) if arg_vals is not None: string.memset(arg_vals, 0, 8 * 32) real_arg_count: int = 0 for ai in range(can): - arg_node: rawptr[ast.AST] = cargs.get(ai) + arg_node: ast.AST* = cargs.get(ai) if arg_node is None: continue - av: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( - builder, pool, mod, arg_node, None, 0, trans) + av: 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: arg_vals[real_arg_count] = sizet(av) real_arg_count += 1 - self.Gen.CallGenCall._call_method_on_ptr(pool, builder, mod, class_name, - "__init__", storage_ptr, arg_vals, real_arg_count, trans, diag_node_ct) + self.Gen.CallGenCall._call_method_on_ptr(pool, builder, mod, class_name, "__init__", storage_ptr, arg_vals, real_arg_count, trans, diag_node_ct) elif has_new_flag == 0: # 无 __init__ 且无 __new__:逐字段 store 参数值 # (有 __new__ 时参数已由 __new__ 消费,不应存入字段) for ai in range(can): - arg: rawptr[ast.AST] = cargs.get(ai) - if arg is None: - continue + arg: ast.AST* = cargs.get(ai) + if arg is None: continue # 先取字段(fe.Ty 用于 char 字面量 → str 字段的物化判定, # 见 translate_constant;否则 coerce inttoptr 字符值当指针崩溃) - fe: rawptr[GenTypes.FieldEntry] = None + fe: 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: rawptr[GenTypes.FieldEntry] = self.Gen.StructGen._get_field_entry( - ctor_entry, fi) - if cand_fe is None: - continue + cand_fe: GenTypes.FieldEntry* = self.Gen.StructGen._get_field_entry(ctor_entry, fi) + if cand_fe is None: continue cand_name: str = self.Gen.StructGen.get_field_name_ptr(cand_fe) - if cand_name is not None and string.strcmp(cand_name, "__vtable__") == 0: - continue + if cand_name is not None and string.strcmp(cand_name, "__vtable__") == 0: continue if target_idx == ai: fe = cand_fe break @@ -262,25 +240,17 @@ class CallGenCtor(CallGenBase.CallGenBase): fe = self.Gen.StructGen.get_field_by_index(class_name, ai) if fe is None: # fast-fail: 字段索引越界(用户传了多余参数) - VLogger.error( - f"构造函数参数过多,字段索引越界: {class_name}", - "HandlesExprCall") + VLogger.error(f"构造函数参数过多,字段索引越界: {class_name}", "HandlesExprCall") continue - arg_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( - builder, pool, mod, arg, None, 0, trans, fe.Ty) + arg_val: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, mod, arg, None, 0, trans, fe.Ty) if arg_val is None: # fast-fail: 参数翻译失败 - VLogger.error( - f"构造函数参数翻译失败: {class_name}", - "HandlesExprCall") + VLogger.error(f"构造函数参数翻译失败: {class_name}", "HandlesExprCall") continue - field_ptr: rawptr[llvmlite.Value] = llvmlite.build_gep_struct( - builder, struct_ty, fe.Ty, storage_ptr, fe.Index) + field_ptr: 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 不匹配) - VLogger.error( - f"构造函数字段 GEP 失败: {class_name}", - "HandlesExprCall") + VLogger.error(f"构造函数字段 GEP 失败: {class_name}", "HandlesExprCall") continue arg_val = self.Gen.ExprGenBase.coerce_to_type(builder, arg_val, fe.Ty, arg) llvmlite.build_store(builder, arg_val, field_ptr) @@ -289,7 +259,7 @@ class CallGenCtor(CallGenBase.CallGenBase): return storage_ptr # 普通结构体:先 store zeroinitializer 清零(确保未赋值字段为零) - zero: rawptr[llvmlite.Value] = llvmlite.ConstZero(pool, struct_ty) + zero: llvmlite.Value* = llvmlite.ConstZero(pool, struct_ty) llvmlite.build_store(builder, zero, tmp) # 应用默认值(显式参数会覆盖默认值) @@ -297,37 +267,29 @@ class CallGenCtor(CallGenBase.CallGenBase): # 逐字段 store 参数值(覆盖默认值) for ai in range(can): - arg: rawptr[ast.AST] = cargs.get(ai) + arg: ast.AST* = cargs.get(ai) if arg is None: continue # 先取字段(fe.Ty 用于 char 字面量 → str 字段的物化判定,见 translate_constant) - fe: rawptr[GenTypes.FieldEntry] = None + fe: GenTypes.FieldEntry* = None if ctor_entry is not None: fe = self.Gen.StructGen._get_field_entry(ctor_entry, ai) else: fe = self.Gen.StructGen.get_field_by_index(class_name, ai) if fe is None: # fast-fail: 字段索引越界(用户传了多余参数) - VLogger.error( - f"构造函数参数过多,字段索引越界: {class_name}", - "HandlesExprCall") + VLogger.error(f"构造函数参数过多,字段索引越界: {class_name}", "HandlesExprCall") continue - arg_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( - builder, pool, mod, arg, None, 0, trans, fe.Ty) + arg_val: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, mod, arg, None, 0, trans, fe.Ty) if arg_val is None: # fast-fail: 参数翻译失败 - VLogger.error( - f"构造函数参数翻译失败: {class_name}", - "HandlesExprCall") + VLogger.error(f"构造函数参数翻译失败: {class_name}", "HandlesExprCall") continue # GEP 到字段 ai - field_ptr: rawptr[llvmlite.Value] = llvmlite.build_gep_struct( - builder, struct_ty, fe.Ty, tmp, fe.Index) + field_ptr: 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 不匹配) - VLogger.error( - f"构造函数字段 GEP 失败: {class_name}", - "HandlesExprCall") + VLogger.error(f"构造函数字段 GEP 失败: {class_name}", "HandlesExprCall") continue # 类型转换并 store arg_val = self.Gen.ExprGenBase.coerce_to_type(builder, arg_val, fe.Ty, arg) @@ -355,15 +317,15 @@ class CallGenCtor(CallGenBase.CallGenBase): # ============================================================ # ============================================================ - def _translate_renum_construct(self, pool: rawptr[memhub.MemBuddy], - builder: rawptr[llvmlite.IRBuilder], - mod: rawptr[llvmlite.LLVMModule], + def _translate_renum_construct(self, pool: memhub.MemBuddy*, + builder: llvmlite.IRBuilder*, + mod: llvmlite.LLVMModule*, class_name: str, variant_name: str, tag_value: int, cargs: list[ast.AST*]*, can: sizet, - trans: rawptr[HT.Translator]) -> rawptr[llvmlite.Value]: + trans: HT.Translator*) -> llvmlite.Value*: """构造 REnum 变体实例,返回指向 alloca 的指针 class_name: REnum 类名(如 "LLVMType") @@ -376,7 +338,7 @@ class CallGenCtor(CallGenBase.CallGenBase): return None # 查找 REnum 结构体类型(用 find_struct_by_module 规避跨模块同名) - renum_entry: rawptr[GenTypes.StructEntry] = None + renum_entry: 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: @@ -385,61 +347,51 @@ class CallGenCtor(CallGenBase.CallGenBase): VLogger.error(f"REnum construct: type {class_name} not registered", "RENUM") return None - renum_ty: rawptr[llvmlite.LLVMType] = renum_entry.Ty + renum_ty: llvmlite.LLVMType* = renum_entry.Ty if renum_ty is None: return None # alloca REnum 类型 # 确保跨模块结构体的完整定义在当前模块中可用(供 alloca 分配空间) self.Gen.StructGen.ensure_struct_def_in_module(pool, mod, renum_ty) - tmp: rawptr[llvmlite.Value] = self.Gen.VarGen._alloca_at_entry(builder, renum_ty) + tmp: llvmlite.Value* = self.Gen.VarGen._alloca_at_entry(builder, renum_ty) if tmp is None: return llvmlite.ConstZero(pool, renum_ty) # 清零(确保未赋值的 payload 位置为零) - zero: rawptr[llvmlite.Value] = llvmlite.ConstZero(pool, renum_ty) + zero: llvmlite.Value* = llvmlite.ConstZero(pool, renum_ty) llvmlite.build_store(builder, zero, tmp) # 写入 __tag 字段(索引 0) - i32_ty: rawptr[llvmlite.LLVMType] = llvmlite.Int32(pool) + i32_ty: llvmlite.LLVMType* = llvmlite.Int32(pool) 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: rawptr[llvmlite.Value] = llvmlite.ConstInt( - pool, i32_ty, tag_value, + tag_const: llvmlite.Value* = llvmlite.ConstInt(pool, i32_ty, tag_value, tag_name_buf if tag_name_buf is not None else "0") - tag_field: rawptr[GenTypes.FieldEntry] = self.Gen.StructGen._get_field_entry(renum_entry, 0) - tag_field_ty: rawptr[llvmlite.LLVMType] = i32_ty + tag_field: GenTypes.FieldEntry* = self.Gen.StructGen._get_field_entry(renum_entry, 0) + tag_field_ty: 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: rawptr[llvmlite.Value] = llvmlite.build_gep_struct( - builder, renum_ty, tag_field_ty, tmp, 0) + tag_ptr: 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) # 写入 payload 字段(索引 1, 2, ... 对应 _p1, _p2, ...) # 参数按位置顺序填充 payload,跳过 __tag(索引 0) for ai in range(can): - arg: rawptr[ast.AST] = cargs.get(ai) - if arg is None: - continue + arg: ast.AST* = cargs.get(ai) + if arg is None: continue # payload 字段索引 = ai + 1(跳过 __tag);先取字段(pfe.Ty 用于 # char 字面量 → str 字段的物化判定,见 translate_constant) payload_idx: int = ai + 1 - if payload_idx >= renum_entry.FieldCount: - break - pfe: rawptr[GenTypes.FieldEntry] = self.Gen.StructGen._get_field_entry( - renum_entry, payload_idx) - if pfe is None: - continue - 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: rawptr[llvmlite.Value] = llvmlite.build_gep_struct( - builder, renum_ty, pfe.Ty, tmp, payload_idx) - if payload_ptr is None: - continue + if payload_idx >= renum_entry.FieldCount: break + pfe: GenTypes.FieldEntry* = self.Gen.StructGen._get_field_entry(renum_entry, payload_idx) + if pfe is None: continue + arg_val: 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* = llvmlite.build_gep_struct(builder, renum_ty, pfe.Ty, tmp, payload_idx) + if payload_ptr is None: continue # 类型转换并 store(payload 位置可能是 i32 或 i64,按字段类型 coerce) arg_val = self.Gen.ExprGenBase.coerce_to_type(builder, arg_val, pfe.Ty, arg) llvmlite.build_store(builder, arg_val, payload_ptr) @@ -457,32 +409,32 @@ class CallGenCtor(CallGenBase.CallGenBase): # ============================================================ # ============================================================ - def _translate_struct_ctor_kw(self, pool: rawptr[memhub.MemBuddy], - builder: rawptr[llvmlite.IRBuilder], - mod: rawptr[llvmlite.LLVMModule], - struct_ty: rawptr[llvmlite.LLVMType], + def _translate_struct_ctor_kw(self, pool: memhub.MemBuddy*, + builder: llvmlite.IRBuilder*, + mod: llvmlite.LLVMModule*, + struct_ty: llvmlite.LLVMType*, class_name: str, cargs: list[ast.AST*]*, can: sizet, keywords: list[ast.AST*]*, kw_count: sizet, - trans: rawptr[HT.Translator]) -> rawptr[llvmlite.Value]: + trans: HT.Translator*) -> llvmlite.Value*: """结构体构造函数(关键字参数版本)""" # 创建临时 alloca # 确保跨模块结构体的完整定义在当前模块中可用(供 alloca 分配空间) self.Gen.StructGen.ensure_struct_def_in_module(pool, mod, struct_ty) - tmp: rawptr[llvmlite.Value] = self.Gen.VarGen._alloca_at_entry(builder, struct_ty) + tmp: 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 的 # fatal_error 显示构造调用行号(本函数无 cl 参数,实参节点最接近调用点) - diag_node_ct: rawptr[ast.AST] = None + diag_node_ct: ast.AST* = None if cargs is not None and len(cargs) > 0: diag_node_ct = cargs.get(0) # OOP 结构体:调用 __before_init__ 进行零值填充和默认值赋值 # 用 find_struct_by_type 规避跨模块同名 find_struct 找错 - kw_entry: rawptr[GenTypes.StructEntry] = self.Gen.StructGen.find_struct_by_type(struct_ty) + kw_entry: 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 @@ -495,7 +447,7 @@ class CallGenCtor(CallGenBase.CallGenBase): if kw_init_lookup is not None: viperlib.snprintf(kw_init_lookup, 128, "%s.__init__", class_name) # 方案1: 检查当前模块的函数声明 - kw_init_found: rawptr[llvmlite.Function] = self.find_func_in_module(mod, kw_init_lookup) + kw_init_found: llvmlite.Function* = self.find_func_in_module(mod, kw_init_lookup) if kw_init_found is not None: is_oop = 1 if kw_entry is not None: @@ -503,7 +455,7 @@ class CallGenCtor(CallGenBase.CallGenBase): kw_entry.HasInit = 1 else: # 方案2: 检查全局默认参数表(翻译时填充,不依赖 stub 注入) - kw_init_defaults: rawptr[GenTypes.FuncDefaultsEntry] = self.Gen.CallGenLeafKit.find_func_defaults(kw_init_lookup) + kw_init_defaults: 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 +467,7 @@ class CallGenCtor(CallGenBase.CallGenBase): "__before_init__", tmp, None, 0, trans) else: # 普通结构体:store zeroinitializer + 应用默认值 - zero: rawptr[llvmlite.Value] = llvmlite.ConstZero(pool, struct_ty) + zero: 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,20 +488,18 @@ class CallGenCtor(CallGenBase.CallGenBase): if is_oop != 0 and has_init_flag != 0: # 有 __init__:构建参数数组并调用 __init__ - storage_ptr: rawptr[llvmlite.Value] = tmp + storage_ptr: llvmlite.Value* = tmp # 如果有 __new__,调用 __new__ 获取实际存储指针 if has_new_flag != 0: - new_arg_vals: sizet | t.CPtr = pool.alloc(8 * 32) + new_arg_vals: sizet* = pool.alloc(8 * 32) if new_arg_vals is not None: string.memset(new_arg_vals, 0, 8 * 32) new_arg_count: int = 0 for nai in range(can): - new_arg_node: rawptr[ast.AST] = cargs.get(nai) - if new_arg_node is None: - continue - new_av: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( - builder, pool, mod, new_arg_node, None, 0, trans) + new_arg_node: ast.AST* = cargs.get(nai) + if new_arg_node is None: continue + new_av: 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) @@ -557,17 +507,13 @@ class CallGenCtor(CallGenBase.CallGenBase): # 关键字参数也传递给 __new__ for nki in range(kw_count): nkw: rawptr[ast.Keyword] = rawptr[ast.Keyword](keywords.get(nki)) - if nkw is None or nkw.value is None: - continue - nkw_av: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( - builder, pool, mod, nkw.value, None, 0, trans) + if nkw is None or nkw.value is None: continue + nkw_av: 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: 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) + new_ptr: 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: storage_ptr = new_ptr # __new__ 只保证返回"实例存储指针",声明类型通常是 @@ -577,24 +523,22 @@ class CallGenCtor(CallGenBase.CallGenBase): # 查不到类名,误报"跨模块调用 'parser.add_argument' 找不到模块 SHA1"。 # bitcast 只改类型层视图,运行时零开销(指针位不变)。 if new_ptr.Ty is not None: - nw_ty: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, struct_ty) + nw_ty: llvmlite.LLVMType* = llvmlite.Ptr(pool, struct_ty) if uint64(new_ptr.Ty) != uint64(nw_ty): - nw_bc: rawptr[llvmlite.Value] = llvmlite.build_bitcast(builder, new_ptr, nw_ty) + nw_bc: llvmlite.Value* = llvmlite.build_bitcast(builder, new_ptr, nw_ty) if nw_bc is not None: storage_ptr = nw_bc # 构建 __init__ 参数数组:位置参数按顺序 + 关键字参数追加 - init_arg_vals: sizet | t.CPtr = pool.alloc(8 * 32) + init_arg_vals: sizet* = pool.alloc(8 * 32) if init_arg_vals is not None: string.memset(init_arg_vals, 0, 8 * 32) init_arg_count: int = 0 # 位置参数 for ai_init in range(can): - arg_node_init: rawptr[ast.AST] = cargs.get(ai_init) - if arg_node_init is None: - continue - av_init: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( - builder, pool, mod, arg_node_init, None, 0, trans) + arg_node_init: ast.AST* = cargs.get(ai_init) + if arg_node_init is None: continue + av_init: 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: init_arg_vals[init_arg_count] = sizet(av_init) @@ -602,18 +546,15 @@ class CallGenCtor(CallGenBase.CallGenBase): # 关键字参数(追加到末尾,按出现顺序) for ki_init in range(kw_count): 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: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( - builder, pool, mod, kw_init.value, None, 0, trans) + if kw_init is None or kw_init.value is None: continue + kw_av_init: 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: init_arg_vals[init_arg_count] = sizet(kw_av_init) init_arg_count += 1 # 调用 __init__(storage_ptr, *args) - self.Gen.CallGenCall._call_method_on_ptr(pool, builder, mod, class_name, - "__init__", storage_ptr, init_arg_vals, init_arg_count, trans, diag_node_ct) + self.Gen.CallGenCall._call_method_on_ptr(pool, builder, mod, class_name, "__init__", storage_ptr, init_arg_vals, init_arg_count, trans, diag_node_ct) # 返回指针 return storage_ptr @@ -621,28 +562,22 @@ class CallGenCtor(CallGenBase.CallGenBase): # 无 __init__(或非 OOP):逐字段 store 参数值 # 先处理位置参数(按字段索引,覆盖默认值) for ai in range(can): - arg: rawptr[ast.AST] = cargs.get(ai) - if arg is None: - continue + arg: ast.AST* = cargs.get(ai) + if arg is None: continue # 先取字段(fe.Ty 用于 char 字面量 → str 字段的物化判定,见 translate_constant) - fe: rawptr[GenTypes.FieldEntry] = None + fe: GenTypes.FieldEntry* = None if kw_entry is not None: fe = self.Gen.StructGen._get_field_entry(kw_entry, ai) else: fe = self.Gen.StructGen.get_field_by_index(class_name, ai) if fe is None: # 位置参数越界(字段表无对应项):fail-fast,绝不静默跳过 - self.Gen.TypeGenErr.fatal_error( - arg, f"结构体 '{class_name}' 位置参数越界(无对应字段)", "TypeError") - continue - 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: rawptr[llvmlite.Value] = llvmlite.build_gep_struct( - builder, struct_ty, fe.Ty, tmp, fe.Index) - if field_ptr is None: + self.Gen.TypeGenErr.fatal_error(arg, f"结构体 '{class_name}' 位置参数越界(无对应字段)", "TypeError") continue + arg_val: 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* = llvmlite.build_gep_struct(builder, struct_ty, fe.Ty, tmp, fe.Index) + if field_ptr is None: continue arg_val = self.Gen.ExprGenBase.coerce_to_type(builder, arg_val, fe.Ty, arg) llvmlite.build_store(builder, arg_val, field_ptr) @@ -653,23 +588,16 @@ class CallGenCtor(CallGenBase.CallGenBase): kw_sha1 = kw_entry.ModuleSha1 for ki in range(kw_count): 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: rawptr[GenTypes.FieldEntry] = self.Gen.StructGen.lookup_field_by_class( - class_name, kw.arg, kw_sha1, kw, trans._from_imports) + if kw is None or kw.arg is None or kw.value is None: continue + fe: 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: 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: rawptr[llvmlite.Value] = llvmlite.build_gep_struct( - builder, struct_ty, fe.Ty, tmp, fe.Index) - if field_ptr is None: + self.Gen.TypeGenErr.fatal_error(kw, f"结构体 '{class_name}' 无字段 '{kw.arg}'", "AttributeError") continue + kw_val: 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* = llvmlite.build_gep_struct(builder, struct_ty, fe.Ty, tmp, fe.Index) + if field_ptr is None: continue kw_val = self.Gen.ExprGenBase.coerce_to_type(builder, kw_val, fe.Ty, kw.value) llvmlite.build_store(builder, kw_val, field_ptr) @@ -690,12 +618,12 @@ class CallGenCtor(CallGenBase.CallGenBase): # ============================================================ # ============================================================ - def _translate_t_type_cast(self, pool: rawptr[memhub.MemBuddy], - builder: rawptr[llvmlite.IRBuilder], - val: rawptr[llvmlite.Value], - target_ty: rawptr[llvmlite.LLVMType], - src_node: rawptr[ast.AST] = None, - trans: rawptr[HT.Translator] = None) -> rawptr[llvmlite.Value]: + def _translate_t_type_cast(self, pool: memhub.MemBuddy*, + builder: llvmlite.IRBuilder*, + val: llvmlite.Value*, + target_ty: llvmlite.LLVMType*, + src_node: ast.AST* = None, + trans: HT.Translator* = None) -> llvmlite.Value*: """类型转换:根据参数类型和目标类型选择转换方式 整数 → 整数拓宽:拓宽方向由**源**的符号性决定(与 coerce_to_type 的 @@ -768,9 +696,9 @@ class CallGenCtor(CallGenBase.CallGenBase): # _get_type_name_from_annotation 已移至 HandlesType.py(支持 BinOp/Attribute) # HandlesExprCall 通过 HandlesType._get_type_name_from_annotation 调用 - def _extract_type_args_from_slice(self, pool: rawptr[memhub.MemBuddy], - slice_node: rawptr[ast.AST], - from_imports: str = None) -> list[str] | t.CPtr: + def _extract_type_args_from_slice(self, pool: memhub.MemBuddy*, + slice_node: ast.AST*, + from_imports: str = None) -> list[str]*: """从 Subscript.slice 提取类型实参名列表 list[int] -> ["int"] @@ -785,18 +713,18 @@ class CallGenCtor(CallGenBase.CallGenBase): return None # elem_size=8:str 是 i8* 指针(8 字节),若用 4 则双元素时 append 写 8 字节 # 但步长按 4 计算,第 2 个元素覆盖第 1 个元素高 4 字节 → get 读出垃圾指针崩溃 - result: list[str] | t.CPtr = list[str](pool, 8) + result: list[str]* = list[str](pool, 8) k: int = slice_node.kind() tn_raw: str = None tn: str = None if k == ast.ASTKind.Tuple: - tp: rawptr[ast.Tuple] = rawptr[ast.Tuple](slice_node) + tp: ast.Tuple* = ast.Tuple*(slice_node) elts: list[ast.AST*]* = tp.elts if elts is not None: n: sizet = len(elts) i: sizet for i in range(n): - elt: rawptr[ast.AST] = elts.get(i) + elt: ast.AST* = elts.get(i) tn_raw = self.Gen.TypeGenResolve._get_type_name_from_annotation(pool, elt) tn = self.Gen.TypeGenResolve._norm_type_arg_name(pool, tn_raw, from_imports) if tn is not None: @@ -810,10 +738,10 @@ class CallGenCtor(CallGenBase.CallGenBase): # 泛型类构造调用辅助 list[str](pool, 8):复用 translate_list_literal 的构造逻辑——alloca tmp → 翻译 cl.args 为参数指针数组 → __new__(tmp,*args) → __before_init__ → __init__ → 返回 storage_ptr。必须独立于 translate_call 普通函数路径:spec_name 是类名不是函数名,走裸名会被 _lookup_mod_sha1 的 star import 回退误导 # ============================================================ - def _infer_generic_ctor_type_arg(self, pool: rawptr[memhub.MemBuddy], - arg_node: rawptr[ast.AST], + def _infer_generic_ctor_type_arg(self, pool: memhub.MemBuddy*, + arg_node: ast.AST*, class_name: str, - trans: rawptr[HT.Translator]) -> str: + trans: HT.Translator*) -> str: """从构造实参 AST 推断泛型类型实参名 裸名泛型类构造(Box(42) → Box[int])需要从实参推断类型实参。 @@ -823,29 +751,22 @@ class CallGenCtor(CallGenBase.CallGenBase): 注意:本函数仅做 AST 静态推断与查表,不发射 IR(避免重复翻译实参)。 """ if pool is None or arg_node is None: - self.Gen.TypeGenErr.fatal_error( - None, - f"无法从实参推断泛型类 '{class_name}' 的类型实参,请显式标注如 {class_name}[类型](...)", - "TypeError") + self.Gen.TypeGenErr.fatal_error(None, f"无法从实参推断泛型类 '{class_name}' 的类型实参,请显式标注如 {class_name}[类型](...)", "TypeError") return None k: int = arg_node.kind() # 常量: 42→int, 3.14→double, "abc"→str, 'x'→char if k == ast.ASTKind.Constant: - cn: rawptr[ast.Constant] = rawptr[ast.Constant](arg_node) - if cn.const_kind == ast.CONST_FLOAT: - return "double" - if cn.const_kind == ast.CONST_CHAR: - # 单字符字面量 'x' 是 char(i8),与 int/float/double 并列 - return "char" - if cn.const_kind == ast.CONST_STR: - return "str" + cn: ast.Constant* = ast.Constant*(arg_node) + if cn.const_kind == ast.CONST_FLOAT: return "double" + if cn.const_kind == ast.CONST_CHAR: return "char" + if cn.const_kind == ast.CONST_STR: return "str" return "int" # 类型转换调用: int(...)/float(...)/int(...)/t.CDouble(...) if k == ast.ASTKind.Call: - cl_f: rawptr[ast.Call] = rawptr[ast.Call](arg_node) + cl_f: ast.Call* = ast.Call*(arg_node) if cl_f.func is not None: if cl_f.func.kind() == ast.ASTKind.Name: - fn_nm: rawptr[ast.Name] = rawptr[ast.Name](cl_f.func) + fn_nm: ast.Name* = ast.Name*(cl_f.func) if fn_nm.id is not None: # 与下方 Attribute 分支的 strstr 匹配一致:from t import CInt # 后 `CInt(0)` 的 func 是 Name("CInt"),仅精确匹配 int/float @@ -864,7 +785,7 @@ class CallGenCtor(CallGenBase.CallGenBase): or string.strstr(fn_nm.id, "Long") is not None: return "int" elif cl_f.func.kind() == ast.ASTKind.Attribute: - fn_at: rawptr[ast.Attribute] = rawptr[ast.Attribute](cl_f.func) + fn_at: ast.Attribute* = ast.Attribute*(cl_f.func) if fn_at.attr is not None: if string.strstr(fn_at.attr, "Float") is not None or string.strstr(fn_at.attr, "Double") is not None: return "double" @@ -875,10 +796,7 @@ class CallGenCtor(CallGenBase.CallGenBase): return "int" # 类型转换调用(Call)但函数名无法识别:明确的类型意图却无法解析, # fail-fast(返回 None ⇒ 调用方 fail-fast)。 - self.Gen.TypeGenErr.fatal_error( - arg_node, - f"无法从实参推断泛型类 '{class_name}' 的类型实参,请显式标注如 {class_name}[类型](...)", - "TypeError") + self.Gen.TypeGenErr.fatal_error(arg_node, f"无法从实参推断泛型类 '{class_name}' 的类型实参,请显式标注如 {class_name}[类型](...)", "TypeError") return None # 普通变量(Name)实参:取变量条目的注解类名(与形参定义/AnnAssign 经 # VarGen.set_var_annot_class_name 写入同源)。此前对 Name/Attribute 一律 @@ -886,10 +804,9 @@ class CallGenCtor(CallGenBase.CallGenBase): # 静默特化成 Box[int](元素按 4 字节/i32 处理)。 # 仅查表(Spec.SourceName),不发 IR、无副作用 ⇒ 构造特化阶段可安全调用。 if k == ast.ASTKind.Name: - nm_i: rawptr[ast.Name] = rawptr[ast.Name](arg_node) + nm_i: ast.Name* = ast.Name*(arg_node) if nm_i.id is not None and trans is not None: - ve_i: rawptr[GenTypes.VarEntry] = self.Gen.VarGen.lookup_var_entry( - trans.SymTab, nm_i.id) + ve_i: 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) return None @@ -899,7 +816,7 @@ class CallGenCtor(CallGenBase.CallGenBase): return self.Gen.ExprGenAttr._resolve_attr_field_class(pool, trans, arg_node) return None - def _annotation_refers_type_param(self, node: rawptr[ast.AST], + def _annotation_refers_type_param(self, node: ast.AST*, tp_name: str) -> int: """注解是否引用类型形参 tp_name(1=是 / 0=否) @@ -911,12 +828,12 @@ class CallGenCtor(CallGenBase.CallGenBase): return 0 k: int = node.kind() if k == ast.ASTKind.Name: - nm_a: rawptr[ast.Name] = rawptr[ast.Name](node) + nm_a: ast.Name* = ast.Name*(node) if nm_a.id is not None and string.strcmp(nm_a.id, tp_name) == 0: return 1 return 0 if k == ast.ASTKind.BinOp: - bop_a: rawptr[ast.BinOp] = rawptr[ast.BinOp](node) + bop_a: ast.BinOp* = ast.BinOp*(node) if self._annotation_refers_type_param(bop_a.left, tp_name) != 0: return 1 return self._annotation_refers_type_param(bop_a.right, tp_name) @@ -934,22 +851,22 @@ class CallGenCtor(CallGenBase.CallGenBase): """ if class_name is None: return None - template_cd: rawptr[ast.ClassDef] = self.Gen.ClassGenGeneric._find_generic_template(class_name) + template_cd: 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[ast.AST*]* = template_cd.children cn: sizet = len(children) ci: sizet for ci in range(cn): - child: rawptr[ast.AST] = children.get(ci) + child: ast.AST* = children.get(ci) if child is None or child.kind() != ast.ASTKind.FunctionDef: continue - fd: rawptr[ast.FunctionDef] = rawptr[ast.FunctionDef](child) + fd: ast.FunctionDef* = ast.FunctionDef*(child) if fd.name is None or string.strcmp(fd.name, "__init__") != 0: continue if fd.args is None or fd.args.kind() != ast.ASTKind.Arguments: return None - fargs: rawptr[ast.Arguments] = rawptr[ast.Arguments](fd.args) + fargs: ast.Arguments* = ast.Arguments*(fd.args) if fargs.args is None: return None return fargs.args @@ -960,9 +877,8 @@ class CallGenCtor(CallGenBase.CallGenBase): """泛型类模板 __init__ 中注解为类型形参 tp_name 的形参序号(含 self,0 起) 找不到返回 -1。位置实参下标 = 本返回值 - 1(形参 0 是 self)。 - 用途:类型形参 i 的推断来源不是第 i 个实参(Vector[T].__init__( - self, pool, capacity, _hint: T) 的 T 在第 3 个位置实参,pool/capacity - 是非 T 参数),须按签名对齐——位置实参对齐(_find_ctor_type_param_arg_index) + 用途:类型形参 i 的推断来源不是第 i 个实参(Vector[T].__init__(self, pool, capacity, _hint: T) + 的 T 在第 3 个位置实参,pool/capacity 是非 T 参数),须按签名对齐——位置实参对齐(_find_ctor_type_param_arg_index) 与关键字实参对齐(_find_ctor_type_param_kw_arg_index)共用本函数。 """ if class_name is None or tp_name is None: @@ -975,10 +891,10 @@ class CallGenCtor(CallGenBase.CallGenBase): for pi in range(pn): if pi == 0: continue # self:位置实参下标 = 形参序号 - 1 - pa: rawptr[ast.AST] = plist.get(pi) + pa: ast.AST* = plist.get(pi) if pa is None or pa.kind() != ast.ASTKind.Arg: continue - ag: rawptr[ast.Arg] = rawptr[ast.Arg](pa) + ag: ast.Arg* = ast.Arg*(pa) if self._annotation_refers_type_param(ag.annotation, tp_name) != 0: return int(pi) return -1 @@ -989,9 +905,8 @@ class CallGenCtor(CallGenBase.CallGenBase): 返回「位置实参下标」(0 = 第 1 个位置实参;形参 0 是 self,故等于形参 序号 - 1);找不到返回 -1(调用方退化为「同一序号」对齐)。 - 用途:类型形参 i 的推断来源不是第 i 个实参(Vector[T].__init__( - self, pool, capacity, _hint: T) 的 T 在第 3 个位置实参,pool/capacity - 是非 T 参数),须按签名对齐。 + 用途:类型形参 i 的推断来源不是第 i 个实参(Vector[T].__init__(self, pool, capacity, _hint: T) + 的 T 在第 3 个位置实参,pool/capacity 是非 T 参数),须按签名对齐。 遍历(形参序号定位)委托 _find_ctor_type_param_param_index。 """ pi_arg: int = self._find_ctor_type_param_param_index(class_name, tp_name) @@ -1019,10 +934,10 @@ class CallGenCtor(CallGenBase.CallGenBase): for pi_sb in range(pn_sb): if pi_sb == 0: continue # self 不是实参槽位 - pa_sb: rawptr[ast.AST] = plist_sb.get(pi_sb) + pa_sb: ast.AST* = plist_sb.get(pi_sb) if pa_sb is None or pa_sb.kind() != ast.ASTKind.Arg: continue - ag_sb: rawptr[ast.Arg] = rawptr[ast.Arg](pa_sb) + ag_sb: ast.Arg* = ast.Arg*(pa_sb) if ag_sb.arg is not None and string.strcmp(ag_sb.arg, kw_name) == 0: return int(pi_sb) - 1 return -1 @@ -1054,10 +969,10 @@ class CallGenCtor(CallGenBase.CallGenBase): plist_kw: list[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)) + pa_kw: ast.AST* = plist_kw.get(sizet(pi_kw)) if pa_kw is None or pa_kw.kind() != ast.ASTKind.Arg: return -1 - ag_kw: rawptr[ast.Arg] = rawptr[ast.Arg](pa_kw) + ag_kw: ast.Arg* = ast.Arg*(pa_kw) if ag_kw.arg is None: return -1 ki_kw: sizet @@ -1069,11 +984,11 @@ class CallGenCtor(CallGenBase.CallGenBase): return int(ki_kw) return -1 - def _infer_ctor_type_args_from_ctx(self, pool: rawptr[memhub.MemBuddy], - trans: rawptr[HT.Translator], + def _infer_ctor_type_args_from_ctx(self, pool: memhub.MemBuddy*, + trans: HT.Translator*, class_name: str, tp_count: int, - cl: rawptr[ast.Call]) -> list[str] | t.CPtr: + cl: ast.Call*) -> list[str]*: """从「赋值目标注解 / 函数返回注解」上下文取泛型构造的类型实参 场景:`s: Stack[int] = Stack()`(__init__ 无参 ⇒ 实参推断不到 T)、 @@ -1092,75 +1007,62 @@ class CallGenCtor(CallGenBase.CallGenBase): 完全相同 ⇒ _specialize_generic_class 幂等,特化名一致。 返回 None = 上下文不适用(调用方维持 fail-fast)。 """ - if pool is None or trans is None or class_name is None or cl is None: - return None - if tp_count <= 0: - return None - ctx_annot: rawptr[ast.AST] = None + if pool is None or trans is None or class_name is None or cl is None: return None + if tp_count <= 0: return None + ctx_annot: ast.AST* = None if trans.CurAssignNode is not None and uint64(cl) == uint64(trans.CurAssignNode): ctx_annot = trans.CurAssignAnnot - if ctx_annot is None and trans.CurRetNode is not None \ - and uint64(cl) == uint64(trans.CurRetNode): + if ctx_annot is None and trans.CurRetNode is not None and uint64(cl) == uint64(trans.CurRetNode): ctx_annot = trans.CurFuncRetAnnot - if ctx_annot is None: - return None + if ctx_annot is None: return None # 取注解里的泛型 Subscript 一侧(与 _prespecialize_generic_annotation 同构: # 支持 `X[T]` 与 `X[T] | t.CPtr` 两种形态) - spec_annot: rawptr[ast.Subscript] = None + spec_annot: ast.Subscript* = None if ctx_annot.kind() == ast.ASTKind.Subscript: - spec_annot = rawptr[ast.Subscript](ctx_annot) + spec_annot = ast.Subscript*(ctx_annot) elif ctx_annot.kind() == ast.ASTKind.BinOp: - bop_ctx: rawptr[ast.BinOp] = rawptr[ast.BinOp](ctx_annot) + bop_ctx: ast.BinOp* = ast.BinOp*(ctx_annot) if bop_ctx.op == ast.OpKind.BitOr: if bop_ctx.left is not None and bop_ctx.left.kind() == ast.ASTKind.Subscript: - spec_annot = rawptr[ast.Subscript](bop_ctx.left) + spec_annot = ast.Subscript*(bop_ctx.left) elif bop_ctx.right is not None and bop_ctx.right.kind() == ast.ASTKind.Subscript: - spec_annot = rawptr[ast.Subscript](bop_ctx.right) - if spec_annot is None: - return None + spec_annot = ast.Subscript*(bop_ctx.right) + if spec_annot is None: return None # 注解必须与本次构造是同一个泛型类(不同类 ⇒ 上下文与本次构造无关) - sv_ctx: rawptr[ast.AST] = spec_annot.value - if sv_ctx is None or sv_ctx.kind() != ast.ASTKind.Name: - return None - sn_ctx: rawptr[ast.Name] = rawptr[ast.Name](sv_ctx) - if sn_ctx.id is None or string.strcmp(sn_ctx.id, class_name) != 0: - return None - type_args_ctx: list[str] | t.CPtr = self._extract_type_args_from_slice( - pool, spec_annot.slice, trans._from_imports) - if type_args_ctx is None: - return None + sv_ctx: ast.AST* = spec_annot.value + if sv_ctx is None or sv_ctx.kind() != ast.ASTKind.Name: return None + sn_ctx: ast.Name* = ast.Name*(sv_ctx) + if sn_ctx.id is None or string.strcmp(sn_ctx.id, class_name) != 0: return None + type_args_ctx: list[str]* = self._extract_type_args_from_slice(pool, spec_annot.slice, trans._from_imports) + if type_args_ctx is None: return None # 类型实参个数必须与类型形参个数一致:不做补齐/截断(否则会用错特化) - if len(type_args_ctx) != sizet(tp_count): - return None + if len(type_args_ctx) != sizet(tp_count): return None return type_args_ctx - def _translate_generic_ctor_call(self, pool: rawptr[memhub.MemBuddy], - builder: rawptr[llvmlite.IRBuilder], - mod: rawptr[llvmlite.LLVMModule], + def _translate_generic_ctor_call(self, pool: memhub.MemBuddy*, + builder: llvmlite.IRBuilder*, + mod: llvmlite.LLVMModule*, spec_name: str, - cl: rawptr[ast.Call], - trans: rawptr[HT.Translator], - tmpl_name: str = None) -> rawptr[llvmlite.Value]: + cl: ast.Call*, + trans: HT.Translator*, + tmpl_name: str = None) -> 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 + 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: rawptr[GenTypes.StructEntry] = self.Gen.StructGen.find_struct(spec_name) + struct_entry: GenTypes.StructEntry* = self.Gen.StructGen.find_struct(spec_name) if struct_entry is None: self.Gen.TypeGenErr.fatal_error(cl, "泛型类构造调用: 特化类未注册") return None - struct_ty: rawptr[llvmlite.LLVMType] = struct_entry.Ty - if struct_ty is None: - return None + struct_ty: llvmlite.LLVMType* = struct_entry.Ty + if struct_ty is None: return None # 确保结构体定义在当前模块中可用(供 alloca 分配空间) self.Gen.StructGen.ensure_struct_def_in_module(pool, mod, struct_ty) # alloca tmp(self 指针) - tmp: rawptr[llvmlite.Value] = self.Gen.VarGen._alloca_at_entry(builder, struct_ty) - if tmp is None: - return None + tmp: 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[ast.AST*]* = cl.args @@ -1172,26 +1074,29 @@ class CallGenCtor(CallGenBase.CallGenBase): if keywords is not None: kw_count = len(keywords) - extra_args: sizet | t.CPtr = pool.alloc(8 * 32) + extra_args: sizet* = pool.alloc_tagged(8 * 32, memhub.DETSITE_CALLGENCTOR_1175) if extra_args is None: return None string.memset(extra_args, 0, 8 * 32) - # 槽占用标志(1 字节/槽:0=空 1=已填),用于关键字定位后的连续性校验 - arg_filled: sizet | t.CPtr = pool.alloc(32) - if arg_filled is None: - return None - string.memset(arg_filled, 0, 32) + # 槽占用标志(0=空 1=已填),用于关键字定位后的连续性校验。 + # 尺寸口径 = extra_args 同源:槽位数固定 32(下标 0..31,由下方 + # `ai >= 32` / `slot_kw >= 32` 守卫界定),元素类型 = sizet|t.CPtr ⇒ 步长 + # 8 字节 ⇒ 必须 32 * 8 = 256 字节。原写 alloc(32) 是"按 1 字节/槽"的 + # 第二份真相源,与 `arg_filled[i] = 1` 的 8 字节步长写自相矛盾:只要实参 + # 数/关键字槽位 ≥ 4(下标 4 落在偏移 32)即越界写穿本块尾 canary 与右邻 + # 空闲块首字([FREEFRAME] 现场族)。改后申请尺寸与实际写入范围同源。 + arg_filled: sizet* = pool.alloc_tagged(8 * 32, memhub.DETSITE_CALLGENCTOR_1186) + if arg_filled is None: return None + string.memset(arg_filled, 0, 8 * 32) for ai in range(can): if ai >= 32: # 定长 8*32 槽:超过 32 个实参继续写会越界污染 pool 相邻块,fail-fast - self.Gen.TypeGenErr.fatal_error( - cl, "泛型构造实参超过 32 个上限", "TypeError") + self.Gen.TypeGenErr.fatal_error(cl, "泛型构造实参超过 32 个上限", "TypeError") break - arg_node: rawptr[ast.AST] = cargs.get(ai) + arg_node: ast.AST* = cargs.get(ai) if arg_node is not None: - arg_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( - builder, pool, mod, arg_node, None, 0, trans) + arg_val: 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) arg_filled[ai] = 1 @@ -1201,30 +1106,23 @@ class CallGenCtor(CallGenBase.CallGenBase): ki_slot: sizet for ki_slot in range(kw_count): 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 + 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) if slot_kw >= 32: - self.Gen.TypeGenErr.fatal_error( - kw_slot, "泛型构造实参超过 32 个上限", "TypeError") + self.Gen.TypeGenErr.fatal_error(kw_slot, "泛型构造实参超过 32 个上限", "TypeError") continue if slot_kw < 0: # fail-fast:关键字名在 __init__ 形参中查无(含模板无 __init__/ # 模板名缺失)——静默丢弃会少传实参,__init__ 收到错位实参。 # 对齐 _translate_struct_ctor_kw 的"结构体 'X' 无字段 'kw'"。 - self.Gen.TypeGenErr.fatal_error( - kw_slot, - f"泛型类 '{tmpl_name}' 的关键字实参 '{kw_slot.arg}' 无法定位到 __init__ 形参", - "TypeError") + self.Gen.TypeGenErr.fatal_error(kw_slot, f"泛型类 '{tmpl_name}' 的关键字实参 '{kw_slot.arg}' 无法定位到 __init__ 形参", "TypeError") continue if arg_filled[sizet(slot_kw)] != 0: # 该形参位已被位置实参/先前关键字占用:位置优先,本次跳过 # (先例 same as 上方:_translate_method_call 名匹配) continue - 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 + kw_val: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, mod, kw_slot.value, None, 0, trans) + if kw_val is None: continue extra_args[sizet(slot_kw)] = sizet(kw_val) arg_filled[sizet(slot_kw)] = 1 if slot_kw > arg_max_filled: @@ -1235,10 +1133,7 @@ class CallGenCtor(CallGenBase.CallGenBase): ci_hole: int = 0 while ci_hole <= arg_max_filled: if arg_filled[sizet(ci_hole)] == 0: - self.Gen.TypeGenErr.fatal_error( - cl, - f"泛型类 '{tmpl_name}' 的关键字构造缺少前置形参(第 {ci_hole + 1} 个实参位置既无位置实参也无关键字实参)", - "TypeError") + self.Gen.TypeGenErr.fatal_error(cl, f"泛型类 '{tmpl_name}' 的关键字构造缺少前置形参(第 {ci_hole + 1} 个实参位置既无位置实参也无关键字实参)", "TypeError") break ci_hole += 1 arg_count: int = 0 @@ -1248,13 +1143,12 @@ class CallGenCtor(CallGenBase.CallGenBase): # 存储指针:默认用 alloca,如果有 __new__ 则用 __new__ 返回的指针 # __new__ 是可选的,仅当泛型类模板定义了 __new__ 方法时才调用 # (与 _translate_struct_ctor 保持一致,避免为无 __new__ 的类生成过度声明) - storage_ptr: rawptr[llvmlite.Value] = tmp + storage_ptr: 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: rawptr[llvmlite.Value] = self.Gen.CallGenCall._call_method_on_ptr( - pool, builder, mod, spec_name, "__new__", tmp, extra_args, arg_count, trans) + new_ptr: 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 # __new__ 只保证返回"实例存储指针",声明类型通常是 @@ -1264,18 +1158,16 @@ class CallGenCtor(CallGenBase.CallGenBase): # 查不到类名,误报"跨模块调用 'parser.add_argument' 找不到模块 SHA1"。 # bitcast 只改类型层视图,运行时零开销(指针位不变)。 if new_ptr.Ty is not None: - nw_ty: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, struct_ty) + nw_ty: llvmlite.LLVMType* = llvmlite.Ptr(pool, struct_ty) if uint64(new_ptr.Ty) != uint64(nw_ty): - nw_bc: rawptr[llvmlite.Value] = llvmlite.build_bitcast(builder, new_ptr, nw_ty) + nw_bc: llvmlite.Value* = llvmlite.build_bitcast(builder, new_ptr, nw_ty) if nw_bc is not None: storage_ptr = nw_bc # call __before_init__(storage_ptr)(TransPyV 自动生成,零值填充) - self.Gen.CallGenCall._call_method_on_ptr( - pool, builder, mod, spec_name, "__before_init__", storage_ptr, None, 0, trans) + self.Gen.CallGenCall._call_method_on_ptr(pool, builder, mod, spec_name, "__before_init__", storage_ptr, None, 0, trans) # call __init__(storage_ptr, *args)(arg_count = 槽位 0..已填最高槽) - self.Gen.CallGenCall._call_method_on_ptr( - pool, builder, mod, spec_name, "__init__", storage_ptr, extra_args, arg_count, trans) + self.Gen.CallGenCall._call_method_on_ptr(pool, builder, mod, spec_name, "__init__", storage_ptr, extra_args, arg_count, trans) return storage_ptr \ No newline at end of file diff --git a/App/lib/core/Gen/Call/CallGenDispatch.vp b/App/lib/core/Gen/Call/CallGenDispatch.vp index 8132eb2..18d5f97 100644 --- a/App/lib/core/Gen/Call/CallGenDispatch.vp +++ b/App/lib/core/Gen/Call/CallGenDispatch.vp @@ -29,21 +29,20 @@ import lib.core.Gen.GenApi as GenApi # 每个 helper 返回 Value|CPtr,None = 未命中(translate_call 继续)。 # @t.NoVTable:静态绑定。 # ============================================================ -@t.NoVTable -class CallGenDispatch(CallGenBase.CallGenBase): +novirtual class CallGenDispatch(CallGenBase.CallGenBase): """translate_call 前置检测 helper(继承 Base)""" - def _tc_h1_super_ctraits(self, pool: rawptr[memhub.MemBuddy], - builder: rawptr[llvmlite.IRBuilder], - mod: rawptr[llvmlite.LLVMModule], - cl: rawptr[ast.Call], + def _tc_h1_super_ctraits(self, pool: memhub.MemBuddy*, + builder: llvmlite.IRBuilder*, + mod: llvmlite.LLVMModule*, + cl: ast.Call*, funcs_ptr: t.CPtr, func_count: int, - trans: rawptr[HT.Translator], + trans: HT.Translator*, func_name: str, cargs: list[ast.AST*]*, can: sizet, - hit_box: t.CPtr = None) -> rawptr[llvmlite.Value]: + hit_box: t.CPtr = None) -> llvmlite.Value*: """super()/ctraits 编译期检测(未命中返回 None) hit_box: 命中标志字节([0]=1 表示被本 helper 拦截处理)。 @@ -57,31 +56,29 @@ class CallGenDispatch(CallGenBase.CallGenBase): # 必须在 Attribute 分派前拦截——否则 value 的 Call(super) 被 translate_value # 当作普通函数调用报错,且走普通属性调用会命中自身/虚分派而非父类实现。 if func_name is not None and cl.func is not None and cl.func.kind() == ast.ASTKind.Attribute: - sup_at: rawptr[ast.Attribute] = rawptr[ast.Attribute](cl.func) + sup_at: ast.Attribute* = ast.Attribute*(cl.func) if sup_at.value is not None and sup_at.value.kind() == ast.ASTKind.Call: - sup_cl: rawptr[ast.Call] = rawptr[ast.Call](sup_at.value) + sup_cl: ast.Call* = ast.Call*(sup_at.value) if sup_cl.func is not None and sup_cl.func.kind() == ast.ASTKind.Name: - sup_nm: rawptr[ast.Name] = rawptr[ast.Name](sup_cl.func) + sup_nm: ast.Name* = ast.Name*(sup_cl.func) if sup_nm.id is not None and string.strcmp(sup_nm.id, "super") == 0: if hit_box is not None: hit_box[0] = 1 - return self.Gen.CallGenCall._translate_super_call( - pool, builder, mod, cl, func_name, trans) + return self.Gen.CallGenCall._translate_super_call(pool, builder, mod, cl, func_name, trans) # ctraits 宏库编译期谓词:ctraits.isptr(x) 不生成运行时调用, # 直接按变量存储类型返回编译期常量(CIf 求值失败回退或非 CIf 上下文时兜底, # 避免生成跨模块调用 ctraits.isptr 触发"模块未注册 SHA1"误导性报错) if func_name is not None and cl.func is not None and cl.func.kind() == ast.ASTKind.Attribute: - ct_at: rawptr[ast.Attribute] = rawptr[ast.Attribute](cl.func) + ct_at: ast.Attribute* = ast.Attribute*(cl.func) if ct_at.value is not None and ct_at.value.kind() == ast.ASTKind.Name: - 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_nm: ast.Name* = 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[ast.AST*]* = cl.args if ct_args is not None and len(ct_args) >= 1: - ct_arg0: rawptr[ast.AST] = ct_args.get(0) + ct_arg0: ast.AST* = ct_args.get(0) if ct_arg0 is not None and ct_arg0.kind() == ast.ASTKind.Name: - ct_nm0: rawptr[ast.Name] = rawptr[ast.Name](ct_arg0) + ct_nm0: ast.Name* = ast.Name*(ct_arg0) if ct_nm0.id is not None and trans is not None: ct_r: int = self.Gen.StmtGenCif._eval_ctraits_isptr(trans.SymTab, ct_nm0.id) if ct_r > 0: @@ -89,17 +86,17 @@ class CallGenDispatch(CallGenBase.CallGenBase): return llvmlite.const_int32(pool, 0) return None - def _tc_h2_c_special(self, pool: rawptr[memhub.MemBuddy], - builder: rawptr[llvmlite.IRBuilder], - mod: rawptr[llvmlite.LLVMModule], - cl: rawptr[ast.Call], + def _tc_h2_c_special(self, pool: memhub.MemBuddy*, + builder: llvmlite.IRBuilder*, + mod: llvmlite.LLVMModule*, + cl: ast.Call*, funcs_ptr: t.CPtr, func_count: int, - trans: rawptr[HT.Translator], + trans: HT.Translator*, func_name: str, cargs: list[ast.AST*]*, can: sizet, - hit_box: t.CPtr = None) -> rawptr[llvmlite.Value]: + hit_box: t.CPtr = None) -> llvmlite.Value*: """c.Deref/Asm/LLVMIR 等特殊调用(未命中返回 None) hit_box: 命中标记(t.CPtr,[0]=1 表示已识别为 c.* 特殊调用)。 @@ -110,9 +107,9 @@ class CallGenDispatch(CallGenBase.CallGenBase): # 检测 c.Deref / c.DerefAs / c.Addr 等特殊调用(内联 IR,不生成 call) # 及 coro.* 协程库拦截(coro.coro_run 内联翻译,TPV-M1) if cl.func is not None and cl.func.kind() == ast.ASTKind.Attribute: - at_node: rawptr[ast.Attribute] = rawptr[ast.Attribute](cl.func) + at_node: ast.Attribute* = ast.Attribute*(cl.func) if at_node.value is not None and at_node.value.kind() == ast.ASTKind.Name: - mod_nm: rawptr[ast.Name] = rawptr[ast.Name](at_node.value) + mod_nm: ast.Name* = ast.Name*(at_node.value) is_coro_mod: int = 0 if mod_nm.id is not None and string.strcmp(mod_nm.id, "coro") == 0: is_coro_mod = 1 @@ -148,20 +145,16 @@ class CallGenDispatch(CallGenBase.CallGenBase): # 对齐 TPC HandlesExprCall.py L2434-2444 cif_args: list[ast.AST*]* = cl.args if cif_args is not None and len(cif_args) >= 1: - cif_arg_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( - builder, pool, mod, cif_args.get(0), funcs_ptr, func_count, trans) + cif_arg_val: 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: 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: rawptr[llvmlite.Value] = llvmlite.const_int32(pool, 0) - return llvmlite.build_icmp( - builder, llvmlite.ICMP_NE, cif_arg_val, cif_zero) + cif_null: 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* = 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") elif string.strcmp(func_name, "CIfdef") == 0 or string.strcmp(func_name, "CIfndef") == 0: # 运行时 c.CIfdef/c.CIfndef(编译期求值失败回退):恒真 @@ -173,36 +166,31 @@ class CallGenDispatch(CallGenBase.CallGenBase): # 注意:coro.* 系列 translate_coro_* 签名统一是 # (builder, pool, mod, cl, trans),与本文件其它 c.* 分支的 # (pool, builder, ...) 顺序不同,勿混用。 - return self.Gen.AsyncGen.translate_coro_run( - builder, pool, mod, cl, trans) + return self.Gen.AsyncGen.translate_coro_run(builder, pool, mod, cl, trans) elif is_coro_mod != 0 and string.strcmp(func_name, "coro_destroy") == 0: # coro.coro_destroy(帧):帧回池(M7 free-list) - return self.Gen.AsyncGen.translate_coro_destroy( - builder, pool, mod, cl, trans) + return self.Gen.AsyncGen.translate_coro_destroy(builder, pool, mod, cl, trans) elif is_coro_mod != 0 and string.strcmp(func_name, "coro_exception") == 0: # coro.coro_exception(帧):返回帧 exc 槽(M4) - return self.Gen.AsyncGen.translate_coro_exception( - builder, pool, mod, cl, trans) + return self.Gen.AsyncGen.translate_coro_exception(builder, pool, mod, cl, trans) elif is_coro_mod != 0 and string.strcmp(func_name, "coro_exception_msg") == 0: # coro.coro_exception_msg(帧):返回帧 msg 槽(M7) - return self.Gen.AsyncGen.translate_coro_exception_msg( - builder, pool, mod, cl, trans) + return self.Gen.AsyncGen.translate_coro_exception_msg(builder, pool, mod, cl, trans) elif is_coro_mod != 0 and string.strcmp(func_name, "coro_gather") == 0: # coro.coro_gather(帧...):并发推进全部协程(M4) - return self.Gen.AsyncGen.translate_coro_gather( - builder, pool, mod, cl, trans) + return self.Gen.AsyncGen.translate_coro_gather(builder, pool, mod, cl, trans) return None - def _tc_h3_stdarg_cast(self, pool: rawptr[memhub.MemBuddy], - builder: rawptr[llvmlite.IRBuilder], - mod: rawptr[llvmlite.LLVMModule], - cl: rawptr[ast.Call], + def _tc_h3_stdarg_cast(self, pool: memhub.MemBuddy*, + builder: llvmlite.IRBuilder*, + mod: llvmlite.LLVMModule*, + cl: ast.Call*, funcs_ptr: t.CPtr, func_count: int, - trans: rawptr[HT.Translator], + trans: HT.Translator*, func_name: str, cargs: list[ast.AST*]*, - can: sizet) -> rawptr[llvmlite.Value]: + can: sizet) -> llvmlite.Value*: """stdarg 糖 + str/int/bool 内置强转(未命中返回 None)""" # stdarg 糖函数处理: va_arg / arg / va_start / va_end # 这些函数在 stdarg.vp 中声明为 pass 体,由编译器在翻译期处理: @@ -237,18 +225,16 @@ 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: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( - builder, pool, mod, cargs.get(0), funcs_ptr, func_count, trans) + cast_arg: 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)) + i8_ptr_ty_builtin: llvmlite.LLVMType* = llvmlite.Ptr(pool, llvmlite.Int8(pool)) return self.Gen.CallGenCtor._translate_t_type_cast(pool, builder, cast_arg, i8_ptr_ty_builtin) return None elif string.strcmp(cast_fn_name, "int") == 0: # int(x) → i32 - cast_arg_int: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( - builder, pool, mod, cargs.get(0), funcs_ptr, func_count, trans) + cast_arg_int: 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) + i32_ty_builtin: llvmlite.LLVMType* = llvmlite.Int32(pool) return self.Gen.CallGenCtor._translate_t_type_cast(pool, builder, cast_arg_int, i32_ty_builtin) return None elif string.strcmp(cast_fn_name, "bool") == 0: @@ -256,42 +242,41 @@ class CallGenDispatch(CallGenBase.CallGenBase): # 整数: icmp ne x, 0 → i1 # 浮点: fcmp one x, 0.0 → i1 # 指针: icmp ne x, null → i1 - cast_arg_bool: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( - builder, pool, mod, cargs.get(0), funcs_ptr, func_count, trans) + cast_arg_bool: 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: rawptr[llvmlite.Value] = llvmlite.const_int(pool, arg_bits, 0) + zero_int: 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: rawptr[llvmlite.Value] = llvmlite.ConstFloat(pool, zero_ty, 0.0) + zero_ty: llvmlite.LLVMType* = cast_arg_bool.Ty + zero_flt: 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: rawptr[llvmlite.Value] = llvmlite.ConstNull(pool, cast_arg_bool.Ty, "null") + ptr_null: 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 return None return None - def _tc_h4_type_casts(self, pool: rawptr[memhub.MemBuddy], - builder: rawptr[llvmlite.IRBuilder], - mod: rawptr[llvmlite.LLVMModule], - cl: rawptr[ast.Call], + def _tc_h4_type_casts(self, pool: memhub.MemBuddy*, + builder: llvmlite.IRBuilder*, + mod: llvmlite.LLVMModule*, + cl: ast.Call*, funcs_ptr: t.CPtr, func_count: int, - trans: rawptr[HT.Translator], + trans: HT.Translator*, func_name: str, cargs: list[ast.AST*]*, - can: sizet) -> rawptr[llvmlite.Value]: + can: sizet) -> llvmlite.Value*: """t.XXX / typedef 类型转换(未命中返回 None)""" # 检测 t.XXX 类型转换: uint64(ptr), t.CPtr(val), int(val) 等 # 当 func 是 t.XXX 形式且 XXX 是已知类型名时,当作类型转换处理(而非函数调用) @@ -300,9 +285,9 @@ class CallGenDispatch(CallGenBase.CallGenBase): # 双参数: int(val, t.CPtr) → 目标类型 = Ptr(map_t_type(func_name)) # t 是内部库,一旦确认为类型转换,绝不跌落到跨模块调用 FATAL 路径 if cl.func is not None and cl.func.kind() == ast.ASTKind.Attribute: - tc_at: rawptr[ast.Attribute] = rawptr[ast.Attribute](cl.func) + tc_at: ast.Attribute* = ast.Attribute*(cl.func) if tc_at.value is not None and tc_at.value.kind() == ast.ASTKind.Name: - tc_mod_nm: rawptr[ast.Name] = rawptr[ast.Name](tc_at.value) + tc_mod_nm: ast.Name* = ast.Name*(tc_at.value) if tc_mod_nm.id is not None and string.strcmp(tc_mod_nm.id, "t") == 0: # t.CType 特殊形式:t.CType(value, TypeName, t.CPtr) → # 把 value 转为 TypeName|t.CPtr(TypeName* 指针)。TypeName @@ -311,32 +296,31 @@ class CallGenDispatch(CallGenBase.CallGenBase): # (VKernel mm.vp merge_blocks 根因)。CType 不是 map_t_type # 的具名类型,须在此显式处理,否则跌落到跨模块 FATAL。 if string.strcmp(func_name, "CType") == 0 and can >= 2: - cty_node: rawptr[ast.AST] = cargs.get(1) - ctype_target: rawptr[llvmlite.LLVMType] = None + cty_node: ast.AST* = cargs.get(1) + ctype_target: llvmlite.LLVMType* = None if cty_node is not None: cti_imp: str = None cti_fi: str = None if trans is not None: cti_imp = trans._imported_modules cti_fi = trans._from_imports - ctype_target = self.Gen.TypeGenResolve.resolve_annotation_type( - pool, cty_node, cti_imp, cti_fi, trans, 0) + ctype_target = self.Gen.TypeGenResolve.resolve_annotation_type(pool, cty_node, cti_imp, cti_fi, trans, 0) if ctype_target is not None: if can == 3: - cty_arg3: rawptr[ast.AST] = cargs.get(2) + cty_arg3: ast.AST* = cargs.get(2) cty_is_cptr: int = 0 if cty_arg3 is not None: # 形式 1: t.CPtr(Attribute) if cty_arg3.kind() == ast.ASTKind.Attribute: - cty_at3: rawptr[ast.Attribute] = rawptr[ast.Attribute](cty_arg3) + cty_at3: ast.Attribute* = ast.Attribute*(cty_arg3) if cty_at3.attr is not None and string.strcmp(cty_at3.attr, "CPtr") == 0: if cty_at3.value is not None and cty_at3.value.kind() == ast.ASTKind.Name: - cty_nm3: rawptr[ast.Name] = rawptr[ast.Name](cty_at3.value) + cty_nm3: ast.Name* = ast.Name*(cty_at3.value) if cty_nm3.id is not None and string.strcmp(cty_nm3.id, "t") == 0: cty_is_cptr = 1 # 形式 2: 裸名 CPtr elif cty_arg3.kind() == ast.ASTKind.Name: - cty_bn3: rawptr[ast.Name] = rawptr[ast.Name](cty_arg3) + cty_bn3: ast.Name* = ast.Name*(cty_arg3) if cty_bn3.id is not None and string.strcmp(cty_bn3.id, "CPtr") == 0: cty_is_cptr = 1 if cty_is_cptr != 0: @@ -347,14 +331,11 @@ class CallGenDispatch(CallGenBase.CallGenBase): case _: pass ctype_target = llvmlite.Ptr(pool, ctype_target) - cty_arg0: rawptr[ast.AST] = cargs.get(0) + cty_arg0: ast.AST* = cargs.get(0) if cty_arg0 is not None: - cty_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( - builder, pool, mod, cty_arg0, funcs_ptr, func_count, trans) + cty_val: 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( - pool, builder, cty_val, ctype_target, - cty_arg0, trans) + return self.Gen.CallGenCtor._translate_t_type_cast(pool, builder, cty_val, ctype_target, cty_arg0, trans) # t.CType 语法已确认:即使类型解析失败也不跌落到跨模块 FATAL return None # CConst const 标记:CConst(val, t.CPtr) → Ptr(i8)(const void*)。 @@ -367,38 +348,33 @@ class CallGenDispatch(CallGenBase.CallGenBase): # 直接返回原值。 if string.strcmp(func_name, "CConst") == 0: if can >= 2: - cconst_ptr_ty: rawptr[llvmlite.LLVMType] = llvmlite.Ptr( - pool, llvmlite.Int8(pool)) - cconst_arg: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( - builder, pool, mod, cargs.get(0), funcs_ptr, func_count, trans) + cconst_ptr_ty: llvmlite.LLVMType* = llvmlite.Ptr(pool, llvmlite.Int8(pool)) + cconst_arg: 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( - pool, builder, cconst_arg, cconst_ptr_ty, - cargs.get(0), trans) + return self.Gen.CallGenCtor._translate_t_type_cast(pool, builder, cconst_arg, cconst_ptr_ty, cargs.get(0), trans) elif can == 1: - return self.Gen.ExprGen.translate_value( - builder, pool, mod, cargs.get(0), funcs_ptr, func_count, trans) + return self.Gen.ExprGen.translate_value(builder, pool, mod, cargs.get(0), funcs_ptr, func_count, trans) return None - target_ty: rawptr[llvmlite.LLVMType] = self.Gen.TypeGenResolve.map_t_type(pool, func_name) + target_ty: llvmlite.LLVMType* = self.Gen.TypeGenResolve.map_t_type(pool, func_name) if target_ty is not None: tc_effective_can: sizet = can # 双参数形式: int(val, t.CPtr) → Ptr(target_ty) # 注意: void* 在 LLVM 中非法,CVoid* 应表示为 i8* if can == 2: - tc_arg2_node: rawptr[ast.AST] = cargs.get(1) + tc_arg2_node: ast.AST* = cargs.get(1) tc_arg2_is_cptr: int = 0 if tc_arg2_node is not None: # 形式 1: t.CPtr(Attribute 形式) if tc_arg2_node.kind() == ast.ASTKind.Attribute: - tc_arg2_at: rawptr[ast.Attribute] = rawptr[ast.Attribute](tc_arg2_node) + tc_arg2_at: ast.Attribute* = ast.Attribute*(tc_arg2_node) if tc_arg2_at.attr is not None and string.strcmp(tc_arg2_at.attr, "CPtr") == 0: if tc_arg2_at.value is not None and tc_arg2_at.value.kind() == ast.ASTKind.Name: - tc_arg2_nm: rawptr[ast.Name] = rawptr[ast.Name](tc_arg2_at.value) + tc_arg2_nm: ast.Name* = ast.Name*(tc_arg2_at.value) if tc_arg2_nm.id is not None and string.strcmp(tc_arg2_nm.id, "t") == 0: tc_arg2_is_cptr = 1 # 形式 2: 裸名 CPtr(from t import CPtr 后直接使用,如 t.CXXX(x, CPtr)) elif tc_arg2_node.kind() == ast.ASTKind.Name: - tc_arg2_bn: rawptr[ast.Name] = rawptr[ast.Name](tc_arg2_node) + tc_arg2_bn: ast.Name* = ast.Name*(tc_arg2_node) if tc_arg2_bn.id is not None and string.strcmp(tc_arg2_bn.id, "CPtr") == 0: tc_arg2_is_cptr = 1 if tc_arg2_is_cptr != 0: @@ -411,18 +387,15 @@ class CallGenDispatch(CallGenBase.CallGenBase): target_ty = llvmlite.Ptr(pool, target_ty) tc_effective_can = 1 if tc_effective_can == 1: - tc_arg_node: rawptr[ast.AST] = cargs.get(0) + tc_arg_node: ast.AST* = cargs.get(0) if tc_arg_node is not None: # 第 8 参 target_ty 必须下传:否则常量在 # translate_constant 里按「是否超出 i32 范围」选位宽, # `uint64(0xFFFFFFFFFFFFFFFF)`(词法回绕为 -1)被 # 物化成 i32 -1 再 zext → 0x00000000FFFFFFFF(N1)。 - tc_arg_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( - builder, pool, mod, tc_arg_node, None, 0, trans, target_ty) + tc_arg_val: 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( - pool, builder, tc_arg_val, target_ty, - tc_arg_node, trans) + return self.Gen.CallGenCtor._translate_t_type_cast(pool, builder, tc_arg_val, target_ty, tc_arg_node, trans) # t.XXX 类型转换已确认但不满足参数条件:返回 None,不跌落到跨模块 FATAL return None @@ -432,33 +405,26 @@ class CallGenDispatch(CallGenBase.CallGenBase): # L130 posix.mode_t(mode) 根因)。typedef 名做类型转换(与裸名 BYTEPTR(x) # 对齐);非 typedef 名继续走模块函数调用。 if cl.func is not None and cl.func.kind() == ast.ASTKind.Attribute: - mt_at: rawptr[ast.Attribute] = rawptr[ast.Attribute](cl.func) + mt_at: ast.Attribute* = ast.Attribute*(cl.func) if mt_at.value is not None and mt_at.value.kind() == ast.ASTKind.Name: - mt_mod_nm: rawptr[ast.Name] = rawptr[ast.Name](mt_at.value) - if mt_mod_nm.id is not None and string.strcmp(mt_mod_nm.id, "t") != 0 \ - and string.strcmp(mt_mod_nm.id, "c") != 0: - mod_td_ty: rawptr[llvmlite.LLVMType] = self.Gen.TypeGenResolve.map_t_type( - pool, func_name) + mt_mod_nm: ast.Name* = ast.Name*(mt_at.value) + if mt_mod_nm.id is not None and string.strcmp(mt_mod_nm.id, "t") != 0 and string.strcmp(mt_mod_nm.id, "c") != 0: + mod_td_ty: llvmlite.LLVMType* = self.Gen.TypeGenResolve.map_t_type(pool, func_name) if mod_td_ty is None: mod_td_str: str = self.Gen.TypeGenCType.lookup_ctypedef(func_name) if mod_td_str is not None and self.Gen.TypeGenCType.is_ctypedef_found() != 0: - mod_td_ast: rawptr[ast.AST] = self.Gen.TypeGenResolve._parse_type_string( - pool, mod_td_str, 0) + mod_td_ast: ast.AST* = self.Gen.TypeGenResolve._parse_type_string(pool, mod_td_str, 0) if mod_td_ast is not None: mod_imp_td: str = None mod_fi_td: str = None if trans is not None: mod_imp_td = trans._imported_modules mod_fi_td = trans._from_imports - mod_td_ty = self.Gen.TypeGenResolve.resolve_annotation_type( - pool, mod_td_ast, mod_imp_td, mod_fi_td, trans, 0) + 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: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( - builder, pool, mod, cargs.get(0), funcs_ptr, func_count, trans, mod_td_ty) + mt_arg_val: 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( - pool, builder, mt_arg_val, mod_td_ty, - cargs.get(0), trans) + return self.Gen.CallGenCtor._translate_t_type_cast(pool, builder, mt_arg_val, mod_td_ty, cargs.get(0), trans) # 裸名 typedef 调用: BYTEPTR(ptr1), HANDLE(val), CHARPTR(str) 等 # 用户通过 `from stdint import *` 导入 typedef 后,可直接用裸名做类型转换 @@ -469,7 +435,7 @@ class CallGenDispatch(CallGenBase.CallGenBase): # self.value = T(v)、combine[T1,T2] 的 T1(b) 依赖此路径) if cl.func is not None and cl.func.kind() == ast.ASTKind.Name: bare_fn_name: str = self.Gen.TypeGenBase.resolve_generic_type_name(func_name) - bare_ty: rawptr[llvmlite.LLVMType] = None + bare_ty: llvmlite.LLVMType* = None # 泛型上下文解析出的内建名(如 T→"double"/"float"):map_t_type 只认 t.CDouble, # 且 float 必须映射 t.CFloat(f32)而非 f64(与注解语义一致) if string.strcmp(bare_fn_name, "double") == 0: @@ -490,34 +456,33 @@ class CallGenDispatch(CallGenBase.CallGenBase): # 回退用 resolve_annotation_type 解析(支持 t.CXxx / 结构体类名 / 别名等)。 # GenericTest4 Box[int].__init__ 的 self.value = T(v) 依赖此路径。 if bare_ty is None and string.strcmp(bare_fn_name, func_name) != 0: - gp_ast: rawptr[ast.AST] = self.Gen.TypeGenResolve._parse_type_string(pool, bare_fn_name, 0) + gp_ast: ast.AST* = self.Gen.TypeGenResolve._parse_type_string(pool, bare_fn_name, 0) if gp_ast is not None: imp_gp: str = None fi_gp: str = None if trans is not None: imp_gp = trans._imported_modules fi_gp = trans._from_imports - bare_ty = self.Gen.TypeGenResolve.resolve_annotation_type( - pool, gp_ast, imp_gp, fi_gp, trans, 0) + bare_ty = self.Gen.TypeGenResolve.resolve_annotation_type(pool, gp_ast, imp_gp, fi_gp, trans, 0) # 泛型类型参数双参数形式: T(val, t.CPtr) → Ptr(T) # (与 int(val, t.CPtr) → Ptr(i32) 对齐;vector.vp get() 的 # typed_ptr = T(offset, t.CPtr) 依赖此路径,否则双参数不进 # can==1 单参数分支 → 跌落到"裸名调用未定义"误报) if bare_ty is not None and can == 2: - bare_arg2_node: rawptr[ast.AST] = cargs.get(1) + bare_arg2_node: ast.AST* = cargs.get(1) bare_arg2_is_cptr: int = 0 if bare_arg2_node is not None: # 形式 1: t.CPtr(Attribute 形式) if bare_arg2_node.kind() == ast.ASTKind.Attribute: - bare_arg2_at: rawptr[ast.Attribute] = rawptr[ast.Attribute](bare_arg2_node) + bare_arg2_at: ast.Attribute* = ast.Attribute*(bare_arg2_node) if bare_arg2_at.attr is not None and string.strcmp(bare_arg2_at.attr, "CPtr") == 0: if bare_arg2_at.value is not None and bare_arg2_at.value.kind() == ast.ASTKind.Name: - bare_arg2_nm: rawptr[ast.Name] = rawptr[ast.Name](bare_arg2_at.value) + bare_arg2_nm: ast.Name* = ast.Name*(bare_arg2_at.value) if bare_arg2_nm.id is not None and string.strcmp(bare_arg2_nm.id, "t") == 0: bare_arg2_is_cptr = 1 # 形式 2: 裸名 CPtr(from t import CPtr 后直接使用) elif bare_arg2_node.kind() == ast.ASTKind.Name: - bare_arg2_bn: rawptr[ast.Name] = rawptr[ast.Name](bare_arg2_node) + bare_arg2_bn: ast.Name* = ast.Name*(bare_arg2_node) if bare_arg2_bn.id is not None and string.strcmp(bare_arg2_bn.id, "CPtr") == 0: bare_arg2_is_cptr = 1 if bare_arg2_is_cptr != 0: @@ -528,60 +493,54 @@ class CallGenDispatch(CallGenBase.CallGenBase): case _: pass bare_ty = llvmlite.Ptr(pool, bare_ty) - bare_arg_node: rawptr[ast.AST] = cargs.get(0) + bare_arg_node: ast.AST* = cargs.get(0) if bare_arg_node is not None: - bare_arg_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( - builder, pool, mod, bare_arg_node, None, 0, trans, bare_ty) + bare_arg_val: 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( - pool, builder, bare_arg_val, bare_ty, - bare_arg_node, trans) + return self.Gen.CallGenCtor._translate_t_type_cast(pool, builder, bare_arg_val, bare_ty, bare_arg_node, trans) if bare_ty is not None and can == 1: - bare_arg_node: rawptr[ast.AST] = cargs.get(0) + bare_arg_node: ast.AST* = cargs.get(0) if bare_arg_node is not None: # 第 8 参 target_ty 下传:裸名 typedef 强转(如 uint64(x))的 # 目标位宽必须参与常量物化(N1)。 - bare_arg_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( - builder, pool, mod, bare_arg_node, None, 0, trans, bare_ty) + bare_arg_val: 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( - pool, builder, bare_arg_val, bare_ty, - bare_arg_node, trans) + return self.Gen.CallGenCtor._translate_t_type_cast(pool, builder, bare_arg_val, bare_ty, bare_arg_node, trans) return None - def _tc_h5_sizeof_len_isinst(self, pool: rawptr[memhub.MemBuddy], - builder: rawptr[llvmlite.IRBuilder], - mod: rawptr[llvmlite.LLVMModule], - cl: rawptr[ast.Call], + def _tc_h5_sizeof_len_isinst(self, pool: memhub.MemBuddy*, + builder: llvmlite.IRBuilder*, + mod: llvmlite.LLVMModule*, + cl: ast.Call*, funcs_ptr: t.CPtr, func_count: int, - trans: rawptr[HT.Translator], + trans: HT.Translator*, func_name: str, cargs: list[ast.AST*]*, - can: sizet) -> rawptr[llvmlite.Value]: + can: sizet) -> llvmlite.Value*: """__sizeof__/len/isinstance 内置(未命中返回 None)""" # 检测 ClassName.__sizeof__() — 返回结构体大小常量(i64) # __sizeof__ 是内置方法,不走跨模块调用路径 # 支持: Argument.__sizeof__() 和 w32.win32file.WIN32_FIND_DATAA.__sizeof__() if cl.func is not None and cl.func.kind() == ast.ASTKind.Attribute: - sz_at: rawptr[ast.Attribute] = rawptr[ast.Attribute](cl.func) + sz_at: ast.Attribute* = ast.Attribute*(cl.func) if sz_at.attr is not None and string.strcmp(sz_at.attr, "__sizeof__") == 0: if sz_at.value is not None and can == 0: sz_cls_name: str = None sz_vk: int = sz_at.value.kind() if sz_vk == ast.ASTKind.Name: - sz_cls_nm2: rawptr[ast.Name] = rawptr[ast.Name](sz_at.value) + sz_cls_nm2: ast.Name* = ast.Name*(sz_at.value) sz_cls_name = sz_cls_nm2.id elif sz_vk == ast.ASTKind.Attribute: - sz_inner_at: rawptr[ast.Attribute] = rawptr[ast.Attribute](sz_at.value) + sz_inner_at: ast.Attribute* = ast.Attribute*(sz_at.value) sz_cls_name = sz_inner_at.attr # 保留完整模块路径(w32.win32base.SECURITY_ATTRIBUTES): # 仅取 attr 会在后续 get_struct_type 裸名全局匹配时误命中 # 跨模块同名类(SECURITY_ATTRIBUTES FieldCount=0 根因)。 if sz_inner_at.value is not None and sz_inner_at.attr is not None: if sz_inner_at.value.kind() == ast.ASTKind.Name: - sz_inner_nm: rawptr[ast.Name] = rawptr[ast.Name](sz_inner_at.value) + sz_inner_nm: ast.Name* = ast.Name*(sz_inner_at.value) if sz_inner_nm.id is not None: sz_full_len: sizet = string.strlen(sz_inner_nm.id) + 1 + string.strlen(sz_inner_at.attr) + 1 sz_full_buf: str = pool.alloc(sz_full_len) @@ -603,7 +562,7 @@ class CallGenDispatch(CallGenBase.CallGenBase): string.strcat(sz_full_buf2, sz_inner_at.attr) sz_cls_name = sz_full_buf2 # 最终解析出的结构体类型:类型名命中 → 泛型特化(Stack[T])→ 实例接收者类型(self/obj) - sz_resolved_ty: rawptr[llvmlite.LLVMType] = None + sz_resolved_ty: llvmlite.LLVMType* = None sz_resolved_name: str = sz_cls_name if sz_cls_name is not None: # 泛型类型参数 T 替换: T.__sizeof__() → int.__sizeof__() @@ -652,54 +611,35 @@ class CallGenDispatch(CallGenBase.CallGenBase): # MyInt 来自 from t import CInt as MyInt),不传则别名链解析失败 # → get_type_size_bytes 返回 0 → 落到"回退 2"把 Name 当值翻译 # → NameError: 未定义名称 'MyWord'(T8 根因)。 - dyn_sz_c: int = self.Gen.TypeGenResolve.get_type_size_bytes( - pool, sz_cls_name, - trans._imported_modules if trans is not None else None, - trans._from_imports if trans is not None else None) + dyn_sz_c: int = self.Gen.TypeGenResolve.get_type_size_bytes(pool, sz_cls_name, + trans._imported_modules if trans is not None else None, + trans._from_imports if trans is not None else None) if dyn_sz_c > 0: return llvmlite.const_int64(pool, dyn_sz_c) # 内置类型 sizeof(int=4, str/bytes=8 指针, double=8 等) sz_builtin: int = -1 - if string.strcmp(sz_cls_name, "int") == 0: - sz_builtin = 4 - elif string.strcmp(sz_cls_name, "str") == 0: - sz_builtin = 8 - elif string.strcmp(sz_cls_name, "bytes") == 0: - sz_builtin = 8 - elif string.strcmp(sz_cls_name, "CInt") == 0: - sz_builtin = 4 - elif string.strcmp(sz_cls_name, "CInt8T") == 0: - sz_builtin = 1 - elif string.strcmp(sz_cls_name, "CInt16T") == 0: - sz_builtin = 2 - elif string.strcmp(sz_cls_name, "CInt32T") == 0: - sz_builtin = 4 - elif string.strcmp(sz_cls_name, "CInt64T") == 0: - sz_builtin = 8 - elif string.strcmp(sz_cls_name, "CChar") == 0: - sz_builtin = 1 - elif string.strcmp(sz_cls_name, "CDouble") == 0: - sz_builtin = 8 - elif string.strcmp(sz_cls_name, "CFloat") == 0: - sz_builtin = 4 - elif string.strcmp(sz_cls_name, "CPtr") == 0: - sz_builtin = 8 - elif string.strcmp(sz_cls_name, "CSizeT") == 0: - sz_builtin = 8 - elif string.strcmp(sz_cls_name, "CBool") == 0: - sz_builtin = 1 - elif string.strcmp(sz_cls_name, "bool") == 0: - sz_builtin = 1 + if string.strcmp(sz_cls_name, "int") == 0: sz_builtin = 4 + elif string.strcmp(sz_cls_name, "str") == 0: sz_builtin = 8 + elif string.strcmp(sz_cls_name, "bytes") == 0: sz_builtin = 8 + elif string.strcmp(sz_cls_name, "CInt") == 0: sz_builtin = 4 + elif string.strcmp(sz_cls_name, "CInt8T") == 0: sz_builtin = 1 + elif string.strcmp(sz_cls_name, "CInt16T") == 0: sz_builtin = 2 + elif string.strcmp(sz_cls_name, "CInt32T") == 0: sz_builtin = 4 + elif string.strcmp(sz_cls_name, "CInt64T") == 0: sz_builtin = 8 + elif string.strcmp(sz_cls_name, "CChar") == 0: sz_builtin = 1 + elif string.strcmp(sz_cls_name, "CDouble") == 0: sz_builtin = 8 + elif string.strcmp(sz_cls_name, "CFloat") == 0: sz_builtin = 4 + elif string.strcmp(sz_cls_name, "CPtr") == 0: sz_builtin = 8 + elif string.strcmp(sz_cls_name, "CSizeT") == 0: sz_builtin = 8 + elif string.strcmp(sz_cls_name, "CBool") == 0: sz_builtin = 1 + elif string.strcmp(sz_cls_name, "bool") == 0: sz_builtin = 1 # 泛型 T 解析出的裸内建名(resolve_generic_type_name 返回 # _infer_generic_ctor_type_arg 的输出,如 T→"double"/"float"): # 缺省会让 sz_builtin=-1 → 落到"回退 2"把 Name(T) 当值翻译 → # NameError(VectorGenericTest Vector[double].__init__ 回归根因) - elif string.strcmp(sz_cls_name, "double") == 0: - sz_builtin = 8 - elif string.strcmp(sz_cls_name, "float") == 0: - sz_builtin = 4 - elif string.strcmp(sz_cls_name, "char") == 0: - sz_builtin = 1 + elif string.strcmp(sz_cls_name, "double") == 0: sz_builtin = 8 + elif string.strcmp(sz_cls_name, "float") == 0: sz_builtin = 4 + elif string.strcmp(sz_cls_name, "char") == 0: sz_builtin = 1 if sz_builtin >= 0: # 注意: 必须用 const_int64 而非 ConstInt(...,"0") # ConstInt 的 name 参数是 IR 文本表示,ValuePrint 输出时使用 Name 而非 IntVal @@ -719,10 +659,9 @@ class CallGenDispatch(CallGenBase.CallGenBase): szf_mod[szf_mod_len] = '\0' # t/c 内置库豁免(int 等已由内建/尺寸表处理) if string.strcmp(szf_mod, "t") != 0 and string.strcmp(szf_mod, "c") != 0: - szf_sha1: str = self.Gen.StructGen._resolve_module_sha1( - szf_mod, trans._from_imports if trans is not None else None) + 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: rawptr[GenTypes.StructEntry] = self.Gen.StructGen.find_struct_by_module(sz_cls_name, szf_sha1) + szf_entry: 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: @@ -730,22 +669,20 @@ class CallGenDispatch(CallGenBase.CallGenBase): # 回退 1: 泛型类引用接收者 Stack[T].__sizeof__() — Subscript → 特化后计算大小 # (GenericTest2 Stack.type_size 依赖此路径) if sz_resolved_ty is None and trans is not None and sz_vk == ast.ASTKind.Subscript: - sub_sz: rawptr[ast.Subscript] = rawptr[ast.Subscript](sz_at.value) + sub_sz: ast.Subscript* = ast.Subscript*(sz_at.value) if sub_sz.value is not None and sub_sz.value.kind() == ast.ASTKind.Name: - gen_nm_sz: rawptr[ast.Name] = rawptr[ast.Name](sub_sz.value) + gen_nm_sz: ast.Name* = ast.Name*(sub_sz.value) if gen_nm_sz.id is not None: - gen_args_sz: list[str] | t.CPtr = self.Gen.CallGenCtor._extract_type_args_from_slice(pool, sub_sz.slice, trans._from_imports) + gen_args_sz: list[str]* = self.Gen.CallGenCtor._extract_type_args_from_slice(pool, sub_sz.slice, trans._from_imports) if gen_args_sz is not None and len(gen_args_sz) > 0: - gargs_resolved: list[str] | t.CPtr = list[str](pool, 8) + gargs_resolved: list[str]* = list[str](pool, 8) if gargs_resolved is not None: gai_sz: sizet = len(gen_args_sz) gai2_sz: sizet = 0 for gai2_sz in range(gai_sz): - gres_sz: str = self.Gen.TypeGenBase.resolve_generic_type_name( - gen_args_sz.get(gai2_sz)) + gres_sz: str = self.Gen.TypeGenBase.resolve_generic_type_name(gen_args_sz.get(gai2_sz)) gargs_resolved.append(gres_sz) - spec_sz: str = self.Gen.ClassGenGeneric._specialize_generic_class( - trans, gen_nm_sz.id, gargs_resolved) + spec_sz: str = self.Gen.ClassGenGeneric._specialize_generic_class(trans, gen_nm_sz.id, gargs_resolved) if spec_sz is not None: sz_resolved_name = spec_sz sz_resolved_ty = self.Gen.StructGen.get_struct_type(spec_sz) @@ -755,8 +692,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: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( - builder, pool, mod, sz_at.value, None, 0, trans) + inst_sz_val: 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: case llvmlite.LLVMType.Ptr(inst_inner_sz): @@ -782,15 +718,11 @@ class CallGenDispatch(CallGenBase.CallGenBase): if sz_val > 0: return llvmlite.const_int64(pool, sz_val) # 类型已注册但大小为 0(opaque struct 或字段链表未填充):Python 风格报错终止 - self.Gen.TypeGenErr.fatal_error( - sz_at, f"类型 '{sz_resolved_name}' 已注册但大小为 0(字段链表未填充),无法计算大小", - "TypeError") + self.Gen.TypeGenErr.fatal_error(sz_at, f"类型 '{sz_resolved_name}' 已注册但大小为 0(字段链表未填充),无法计算大小", "TypeError") # 类型未注册:Python 风格报错终止,不静默返回 0(会导致 malloc(0)/alloc(0) 堆溢出) if sz_resolved_name is None: sz_resolved_name = "(unknown)" - self.Gen.TypeGenErr.fatal_error( - sz_at, f"类型 '{sz_resolved_name}' 未在结构体表中注册,无法计算大小", - "TypeError") + self.Gen.TypeGenErr.fatal_error(sz_at, f"类型 '{sz_resolved_name}' 未在结构体表中注册,无法计算大小", "TypeError") # 检测 len(obj) — 返回 list 对象的 __count__ 字段(偏移 8,i64) # __len__ 是 list[T] 的内置方法,list 是泛型类不注册 struct @@ -798,11 +730,10 @@ class CallGenDispatch(CallGenBase.CallGenBase): # 可能是 Attribute 节点(如 md_ags.args),translate_name_value 只处理 Name 节点, # 对 Attribute 会错误返回 i32 0,导致 GEP base 不是指针(base of getelementptr must be a pointer) if cl.func is not None and cl.func.kind() == ast.ASTKind.Attribute: - len_at: rawptr[ast.Attribute] = rawptr[ast.Attribute](cl.func) + len_at: ast.Attribute* = 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: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( - builder, pool, mod, len_at.value, funcs_ptr, func_count, trans) + obj_val: 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 # 如果 translate_value 返回 i32 (如 CDefine 常量被误解析、 @@ -810,15 +741,13 @@ class CallGenDispatch(CallGenBase.CallGenBase): # 导致 llc 报错 "base of getelementptr must be a pointer" if self.Gen.ExprGenBase.is_ptr_type(obj_val.Ty) == 0: # 类型推断失败(非指针/结构体):fail-fast,绝不返回 0 掩盖错误 - self.Gen.TypeGenErr.fatal_error( - len_at.value, "len() 参数类型推断失败(非指针/结构体)", "TypeError") - i64_ty_len: rawptr[llvmlite.LLVMType] = llvmlite.Int64(pool) + self.Gen.TypeGenErr.fatal_error(len_at.value, "len() 参数类型推断失败(非指针/结构体)", "TypeError") + i64_ty_len: llvmlite.LLVMType* = llvmlite.Int64(pool) # 注意: 必须用 const_int64 而非 ConstInt(...,"0") # ConstInt 的 name 参数 "0" 会被当作 IR 文本值输出 i64 0 # 导致 GEP 索引为 0(访问 __data__)而非 1(访问 __count__) - 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) + idx_one: llvmlite.Value* = llvmlite.const_int64(pool, 1) + count_ptr: 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) @@ -827,10 +756,9 @@ 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, "len") == 0: if can == 1: - len_arg_node: rawptr[ast.AST] = cargs.get(0) + len_arg_node: ast.AST* = cargs.get(0) if len_arg_node is not None: - len_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( - builder, pool, mod, len_arg_node, None, 0, trans) + len_val: 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 # _HandleLenLlvm 的 ArrayType.count 分支)。数组变量 @@ -841,7 +769,7 @@ class CallGenDispatch(CallGenBase.CallGenBase): len_arr_n: int = 0 if len_val.Ty is not None: if self.Gen.ExprGenBase.is_ptr_type(len_val.Ty) != 0: - len_ap: rawptr[llvmlite.LLVMType] = len_val.Ty.Pointee + len_ap: llvmlite.LLVMType* = len_val.Ty.Pointee if len_ap is not None: match len_ap: case llvmlite.LLVMType.Array(_, len_arr_cnt): @@ -866,50 +794,37 @@ class CallGenDispatch(CallGenBase.CallGenBase): # - 普通类:调用 {Class}.__len__ 函数 # - 都没有:fatal_error # str(Ptr(Int8))保持 strlen(内建语义)。 - len_struct_ty: rawptr[llvmlite.LLVMType] = \ + len_struct_ty: llvmlite.LLVMType* = \ self.Gen.StructGen.get_struct_type_from_value(len_val) if len_struct_ty is not None: - len_cls_nm: str = self.Gen.StructGen.get_class_name_by_type( - pool, len_struct_ty) + len_cls_nm: str = self.Gen.StructGen.get_class_name_by_type(pool, len_struct_ty) if len_cls_nm is None: - self.Gen.TypeGenErr.fatal_error( - len_arg_node, "len() 参数类型推断失败(结构体类名未知)", - "TypeError") + self.Gen.TypeGenErr.fatal_error(len_arg_node, "len() 参数类型推断失败(结构体类名未知)", "TypeError") # list 内置 __len__:读 __count__(GEP 偏移 1,i64) # 判据优先取接收者实际类型(_is_list_builtin_receiver) - 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: 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 self.Gen.CallGenProp._is_list_builtin_receiver(pool, len_val, len_cls_nm, "__len__", len_arg_node) != 0: + i64_ty_lb: llvmlite.LLVMType* = llvmlite.Int64(pool) + idx_one_lb: llvmlite.Value* = llvmlite.const_int64(pool, 1) + cnt_ptr_lb: 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) len_lookup: str = pool.alloc(128) if len_lookup is not None: viperlib.snprintf(len_lookup, 128, "%s.__len__", len_cls_nm) - len_fn2: rawptr[llvmlite.Function] = self.find_func_in_module( - mod, len_lookup) + len_fn2: llvmlite.Function* = self.find_func_in_module(mod, len_lookup) if len_fn2 is not None: - len_ret_ty2: rawptr[llvmlite.LLVMType] = \ - llvmlite.function_get_ret_ty(len_fn2) - len_fn_name2: str = \ - llvmlite.function_get_name(len_fn2) + len_ret_ty2: llvmlite.LLVMType* = llvmlite.function_get_ret_ty(len_fn2) + len_fn_name2: str = 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: rawptr[llvmlite.Value] = len_val - len_first_param2: rawptr[llvmlite.Param] = \ - llvmlite.function_get_param_head(len_fn2) + len_self_arg2: llvmlite.Value* = len_val + len_first_param2: llvmlite.Param* = llvmlite.function_get_param_head(len_fn2) if len_first_param2 is not None: - len_self_ty2: rawptr[llvmlite.LLVMType] = \ - llvmlite.param_get_ty(len_first_param2) + len_self_ty2: llvmlite.LLVMType* = llvmlite.param_get_ty(len_first_param2) if len_self_ty2 is not None and len_val.Ty is not None: - len_self_arg2 = llvmlite.build_bitcast( - builder, len_val, len_self_ty2) + len_self_arg2 = llvmlite.build_bitcast(builder, len_val, len_self_ty2) len_self_arg2.Next = None - return llvmlite.build_call( - builder, len_fn_name2, len_self_arg2, - 1, len_ret_ty2, 0) + return llvmlite.build_call(builder, len_fn_name2, len_self_arg2, 1, len_ret_ty2, 0) # len_fn2 未命中(跨模块方法):如 ndarray[t.CDouble].__len__ # 定义在 numpy——泛型特化方法无 stub declare,find_func_in_module # 后缀匹配查不到。用结构体所属模块 sha1 构造 @@ -922,37 +837,25 @@ class CallGenDispatch(CallGenBase.CallGenBase): # 2 个点 + "__len__"(7) + NUL = 10;+8 会截断 # 末两位 → 符号变 ".__len" 链接 undefined # (NumpyTest test_len 链接错误根因) - len_ml_x: sizet = string.strlen(len_cls_sha1_x) \ - + string.strlen(len_cls_nm) + 10 + len_ml_x: sizet = string.strlen(len_cls_sha1_x) + string.strlen(len_cls_nm) + 10 len_mangled_x: str = pool.alloc(len_ml_x) if len_mangled_x is not None: - viperlib.snprintf(len_mangled_x, len_ml_x, - "%s.%s.__len__", len_cls_sha1_x, len_cls_nm) - len_ret_x: rawptr[llvmlite.LLVMType] = \ - self._LookupMethodRetTyFromTextLL( - pool, len_cls_sha1_x, len_cls_nm, "__len__") + viperlib.snprintf(len_mangled_x, len_ml_x, "%s.%s.__len__", len_cls_sha1_x, len_cls_nm) + len_ret_x: llvmlite.LLVMType* = self._LookupMethodRetTyFromTextLL(pool, len_cls_sha1_x, len_cls_nm, "__len__") if len_ret_x is None: - len_ret_x = self._lookup_method_ret_ty_via_vpi( - pool, len_cls_sha1_x, len_cls_nm, "__len__") + len_ret_x = self._lookup_method_ret_ty_via_vpi(pool, len_cls_sha1_x, len_cls_nm, "__len__") if len_ret_x is not None: # self 参数按对象实际类型 Ptr(len_struct_ty)(与定义侧 # 同名类型链接匹配);len_val 已是 load 后的对象指针。 # Value 链直接作 param_head(同跨模块调用模式)。 - len_self_x: rawptr[llvmlite.Value] = len_val + len_self_x: llvmlite.Value* = len_val len_self_x.Next = None - self._ensure_method_declare( - pool, mod, len_mangled_x, len_ret_x, - len_self_x, 1) - return llvmlite.build_call( - builder, len_mangled_x, len_self_x, - 1, len_ret_x, 0) + self._ensure_method_declare(pool, mod, len_mangled_x, len_ret_x, len_self_x, 1) + return llvmlite.build_call(builder, len_mangled_x, len_self_x, 1, len_ret_x, 0) # fail-fast:类没有 __len__(用户要求编译期报错) - self.Gen.TypeGenErr.fatal_error( - len_arg_node, - f"len() 参数类型 '{len_cls_nm}' 没有 __len__ 方法", - "TypeError") + self.Gen.TypeGenErr.fatal_error(len_arg_node, f"len() 参数类型 '{len_cls_nm}' 没有 __len__ 方法", "TypeError") # 非结构体:str(Ptr(Int8))走 strlen;其它类型 fail-fast - len_arg_ty: rawptr[llvmlite.LLVMType] = llvmlite.value_get_ty(len_val) + len_arg_ty: llvmlite.LLVMType* = llvmlite.value_get_ty(len_val) len_is_str: int = 0 if len_arg_ty is not None and self.Gen.ExprGenBase.is_ptr_type(len_arg_ty) != 0: match len_arg_ty: @@ -968,26 +871,24 @@ class CallGenDispatch(CallGenBase.CallGenBase): pass if len_is_str != 0: # 确保 strlen 在模块中有声明 - strlen_fn: rawptr[llvmlite.Function] = self.find_func_in_module(mod, "strlen") + strlen_fn: llvmlite.Function* = self.find_func_in_module(mod, "strlen") if strlen_fn is None: - i64_ty_ln: rawptr[llvmlite.LLVMType] = llvmlite.Int64(pool) - i8_ptr_ty_ln: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, llvmlite.Int8(pool)) + i64_ty_ln: llvmlite.LLVMType* = llvmlite.Int64(pool) + i8_ptr_ty_ln: llvmlite.LLVMType* = llvmlite.Ptr(pool, llvmlite.Int8(pool)) strlen_fn = llvmlite.create_declare(pool, mod, "strlen", i64_ty_ln) if strlen_fn is not None: 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: rawptr[llvmlite.Value] = len_val + i8_ptr_ty_ln2: llvmlite.LLVMType* = llvmlite.Ptr(pool, llvmlite.Int8(pool)) + len_coerced: 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 len_coerced.Next = None - i64_ty_ln2: rawptr[llvmlite.LLVMType] = llvmlite.Int64(pool) + i64_ty_ln2: llvmlite.LLVMType* = llvmlite.Int64(pool) return llvmlite.build_call(builder, "strlen", len_coerced, 1, i64_ty_ln2, 0) # fail-fast:非字符串/数组/对象,无法求长度 - self.Gen.TypeGenErr.fatal_error( - len_arg_node, "len() 参数类型不支持(非字符串/数组/对象)", - "TypeError") + self.Gen.TypeGenErr.fatal_error(len_arg_node, "len() 参数类型不支持(非字符串/数组/对象)", "TypeError") # 检测 isinstance() 内置函数调用 — 运行时 vtable 子类集合比较 # isinstance(obj, Cls):obj 头部 vtable 指针 ∈ {Cls 及全部子类 vtable}; @@ -995,24 +896,23 @@ 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: rawptr[llvmlite.Value] = self.Gen.CallGenLeafKit._translate_isinstance( - pool, builder, mod, cargs.get(0), cargs.get(1), trans) + is_res: 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 return None - def _tc_h6_method_dispatch(self, pool: rawptr[memhub.MemBuddy], - builder: rawptr[llvmlite.IRBuilder], - mod: rawptr[llvmlite.LLVMModule], - cl: rawptr[ast.Call], + def _tc_h6_method_dispatch(self, pool: memhub.MemBuddy*, + builder: llvmlite.IRBuilder*, + mod: llvmlite.LLVMModule*, + cl: ast.Call*, funcs_ptr: t.CPtr, func_count: int, - trans: rawptr[HT.Translator], + trans: HT.Translator*, func_name: str, cargs: list[ast.AST*]*, can: sizet, - hit_box: t.CPtr = None) -> rawptr[llvmlite.Value]: + hit_box: t.CPtr = None) -> llvmlite.Value*: """静态类/方法调用/表达式接收者/self.field/list 内置(未命中返回 None) hit_box: 命中标记(t.CPtr,[0]=1 表示已识别为方法调用路径)。 @@ -1026,42 +926,35 @@ class CallGenDispatch(CallGenBase.CallGenBase): # 兜底误绑到 ast.AST.kind(this 偏移,语义错误)。此处直接翻译为 # bitcast obj 到 i32* + load —— 零函数调用,返回变体 tag。 if cl.func is not None and cl.func.kind() == ast.ASTKind.Attribute: - 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: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( - builder, pool, mod, rk_at.value, None, 0, trans) + rk_at: ast.Attribute* = 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* = 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 + rk_ty: llvmlite.LLVMType* = rk_obj.Ty rk_load: int = 0 rk_cls: str = None if self.Gen.ExprGenBase.is_ptr_type(rk_ty) != 0: - rk_pointee: rawptr[llvmlite.LLVMType] = rk_ty.Pointee + rk_pointee: llvmlite.LLVMType* = rk_ty.Pointee # 联合简化双指针(Ptr(Ptr(Struct)))→ 解一层 + load - if rk_pointee is not None \ - and self.Gen.ExprGenBase.is_ptr_type(rk_pointee) != 0: + if rk_pointee is not None and self.Gen.ExprGenBase.is_ptr_type(rk_pointee) != 0: rk_pointee = rk_pointee.Pointee rk_load = 1 rk_cls = self.Gen.StructGen.get_class_name_by_type(pool, rk_pointee) - if rk_cls is not None \ - and self.Gen.ClassGenEnum._is_renum_class_name(rk_cls) == 0: + if rk_cls is not None and self.Gen.ClassGenEnum._is_renum_class_name(rk_cls) == 0: rk_cls = None # 注解兜底:联合简化/退化后运行时类型丢失(如 - # resolved: rawptr[llvmlite.LLVMType] 存 i8*,pointee 非 + # resolved: llvmlite.LLVMType* 存 i8*,pointee 非 # 结构体),用变量注解类名识别 REnum 类(kind() 语义: # 读 __tag,bitcast 对象到 i32* + load)。 - if rk_cls is None and rk_at.value is not None \ - 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_cls is None and rk_at.value is not None and rk_at.value.kind() == ast.ASTKind.Name and trans is not None: + rk_nm: ast.Name* = ast.Name*(rk_at.value) if rk_nm.id is not None: - rk_ve: rawptr[GenTypes.VarEntry] = self.Gen.VarGen.lookup_var_entry( - trans.SymTab, rk_nm.id) + rk_ve: 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: # 截断联合/泛型后缀(" | t.CPtr" / "[...]") rk_ae: sizet = 0 - while rk_annot_raw[rk_ae] != '\0' and rk_annot_raw[rk_ae] != ' ' \ - and rk_annot_raw[rk_ae] != '|' and rk_annot_raw[rk_ae] != '[': + while rk_annot_raw[rk_ae] != '\0' and rk_annot_raw[rk_ae] != ' ' and rk_annot_raw[rk_ae] != '|' and rk_annot_raw[rk_ae] != '[': rk_ae += 1 rk_ab: str = pool.alloc(rk_ae + 1) if rk_ab is not None: @@ -1076,62 +969,49 @@ 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: rawptr[llvmlite.Value] = rk_obj + rk_val: llvmlite.Value* = rk_obj if rk_load != 0: rk_val = llvmlite.build_load(builder, rk_ty, rk_obj) if rk_val is not None: if hit_box is not None: hit_box[0] = 1 - rk_i32p: rawptr[llvmlite.LLVMType] = llvmlite.Ptr( - pool, llvmlite.Int32(pool)) - rk_cast: rawptr[llvmlite.Value] = llvmlite.build_bitcast( - builder, rk_val, rk_i32p) + rk_i32p: llvmlite.LLVMType* = llvmlite.Ptr(pool, llvmlite.Int32(pool)) + rk_cast: llvmlite.Value* = llvmlite.build_bitcast(builder, rk_val, rk_i32p) return llvmlite.build_load(builder, rk_i32p, rk_cast) # 检测类名静态/类方法调用: ClassName.method(args) # 当 cl.func 是 Attribute、value 是已注册结构体类名(非普通变量)时, # 且方法带 @staticmethod/@classmethod 元数据,走静态调用路径 if cl.func is not None and cl.func.kind() == ast.ASTKind.Attribute: - st_at: rawptr[ast.Attribute] = rawptr[ast.Attribute](cl.func) + st_at: ast.Attribute* = ast.Attribute*(cl.func) if st_at is not None and st_at.value is not None and trans is not None: if st_at.value.kind() == ast.ASTKind.Name: - st_nm: rawptr[ast.Name] = rawptr[ast.Name](st_at.value) + st_nm: ast.Name* = ast.Name*(st_at.value) if st_nm.id is not None: - st_var: rawptr[llvmlite.Value] = self.Gen.VarGen.lookup_var( - trans.SymTab, st_nm.id) + st_var: 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( - trans._imported_modules, st_nm.id) == 0: + and self.Gen.ImportsGen.is_module_imported(trans._imported_modules, st_nm.id) == 0: # REnum 变体构造优先于静态/类方法调用: if self.Gen.ClassGenEnum._is_renum_class_name(st_nm.id) != 0: - rc_tag_sc: int = self.Gen.ClassGenEnum._lookup_renum_variant_in_class( - st_nm.id, func_name) + rc_tag_sc: int = self.Gen.ClassGenEnum._lookup_renum_variant_in_class(st_nm.id, func_name) if rc_tag_sc >= 0: - return self.Gen.CallGenCtor._translate_renum_construct( - pool, builder, mod, st_nm.id, func_name, - rc_tag_sc, cargs, can, trans) - st_res: rawptr[llvmlite.Value] = self.Gen.CallGenProp._translate_static_class_call( - pool, builder, mod, st_nm.id, func_name, cl, trans) + 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* = 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: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( - builder, pool, mod, cargs.get(0), None, 0, trans) + if can >= 1 and cargs is not None and string.strcmp(st_nm.id, func_name) != 0: + im_self: 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 + im_rem: sizet* = None if can >= 2: im_rem = pool.alloc(sizet(can - 1) * 8) if im_rem is not None: ri_im: sizet for ri_im in range(can - 1): - im_rv: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( - builder, pool, mod, cargs.get(ri_im + 1), None, 0, trans) + im_rv: 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: 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) + im_res: 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: return im_res elif st_at.value.kind() == ast.ASTKind.Attribute: @@ -1141,13 +1021,12 @@ class CallGenDispatch(CallGenBase.CallGenBase): # 此前未检测 → 走通用路径把 method_name 当裸函数解析, # 生成 call i32 @from_long(无类名/SHA1 前缀)→ 链接 # undefined reference(CPythonTest PyLongObj.from_long 根因) - st_at2: rawptr[ast.Attribute] = rawptr[ast.Attribute](st_at.value) + st_at2: ast.Attribute* = ast.Attribute*(st_at.value) if st_at2 is not None and st_at2.attr is not None and st_at2.value is not None: if st_at2.value.kind() == ast.ASTKind.Name: # ClassName 是已注册结构体类名时尝试静态/类方法 if self.Gen.StructGen.get_struct_type(st_at2.attr) is not None: - st_res2: rawptr[llvmlite.Value] = self.Gen.CallGenProp._translate_static_class_call( - pool, builder, mod, st_at2.attr, func_name, cl, trans) + st_res2: 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 @@ -1158,17 +1037,15 @@ class CallGenDispatch(CallGenBase.CallGenBase): # = 对象自身地址,正是 self 需要的形态),再用接收者类型的类名走同一条 # `_translate_method_call`(符号 .<类>.<方法>、返回类型经 text.ll/vpi)。 # 守卫 trans.ReplCtx is not None ⇒ 非 REPL 编译路径一行不经过(逐字不变)。 - if cl.func is not None and cl.func.kind() == ast.ASTKind.Attribute \ - and trans is not None and trans.ReplCtx is not None and pool is not None: - rp_at: rawptr[ast.Attribute] = rawptr[ast.Attribute](cl.func) + if cl.func is not None and cl.func.kind() == ast.ASTKind.Attribute and trans is not None and trans.ReplCtx is not None and pool is not None: + rp_at: ast.Attribute* = ast.Attribute*(cl.func) if rp_at is not None and rp_at.value is not None and rp_at.attr is not None: if rp_at.value.kind() == ast.ASTKind.Name: - rp_nm: rawptr[ast.Name] = rawptr[ast.Name](rp_at.value) + rp_nm: ast.Name* = ast.Name*(rp_at.value) if rp_nm.id is not None: - rp_ent: rawptr[GenTypes.ReplVarEntry] = \ - self.Gen.VarGen.repl_find_entry(trans.ReplCtx, rp_nm.id) + rp_ent: rawptr[GenTypes.ReplVarEntry] = self.Gen.VarGen.repl_find_entry(trans.ReplCtx, rp_nm.id) if rp_ent is not None: - rp_val: rawptr[llvmlite.Value] = None + rp_val: llvmlite.Value* = None if rp_ent.TyTag == GenTypes.REPL_TY_STRUCT: # 结构体值内联在槽里:槽地址即对象地址(self) rp_val = self.Gen.VarGen.repl_try_addr(trans, rp_nm.id, cl) @@ -1176,63 +1053,50 @@ class CallGenDispatch(CallGenBase.CallGenBase): rp_val = self.Gen.VarGen.repl_try_read(trans, rp_nm.id, cl) rp_cls: str = None if rp_val is not None and rp_val.Ty is not None: - rp_sty: rawptr[llvmlite.LLVMType] = \ - self.Gen.StructGen.get_struct_type_from_value(rp_val) + rp_sty: llvmlite.LLVMType* = self.Gen.StructGen.get_struct_type_from_value(rp_val) if rp_sty is not None: - rp_cls = self.Gen.StructGen.get_class_name_by_type( - pool, rp_sty) + rp_cls = self.Gen.StructGen.get_class_name_by_type(pool, rp_sty) if rp_cls is not None: - rp_obj: rawptr[llvmlite.Value] = rp_val - if self.Gen.ExprGenBase.is_ptr_type(rp_val.Ty) != 0 \ - and rp_val.Ty.Pointee is not None \ - and self.Gen.ExprGenBase.is_ptr_type(rp_val.Ty.Pointee) != 0: + rp_obj: llvmlite.Value* = rp_val + if self.Gen.ExprGenBase.is_ptr_type(rp_val.Ty) != 0 and rp_val.Ty.Pointee != 0 and self.Gen.ExprGenBase.is_ptr_type(rp_val.Ty.Pointee) != 0: rp_obj = llvmlite.build_load(builder, rp_val.Ty, rp_val) if rp_obj is not None: if hit_box is not None: hit_box[0] = 1 - return self.Gen.CallGenCall._translate_method_call( - pool, builder, mod, rp_cls, rp_at.attr, rp_obj, cl, trans) + return self.Gen.CallGenCall._translate_method_call(pool, builder, mod, rp_cls, rp_at.attr, rp_obj, cl, trans) # 会话变量命中但接收者不是结构体类(如 int/str/其它指针): # 不拦截、不置 hit,交给下方既有分支(list 内置/FakeDuck 等) # 检测方法调用: obj.method(args) # 当 cl.func 是 Attribute 且 obj 是已注册的结构体变量时,翻译为方法调用 if cl.func is not None and cl.func.kind() == ast.ASTKind.Attribute: - method_at: rawptr[ast.Attribute] = rawptr[ast.Attribute](cl.func) + method_at: ast.Attribute* = ast.Attribute*(cl.func) if method_at is not None and method_at.value is not None: # 链式方法调用: a.b().c() —— value 是内层 Call(如 gfx.vp 的 # eye.Sub(target).Norm())。此前未处理 → 外层 .Norm() 的 value # 非 Name 跳过方法分支 → 通用路径把 eye.Sub 当属性解析 → # "属性写入失败: .Sub"。先翻译内层调用得接收者,再方法调用。 if method_at.value.kind() == ast.ASTKind.Call and trans is not None: - recv_val_c: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( - builder, pool, mod, method_at.value, None, 0, trans) + recv_val_c: 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 + recv_ty_c: llvmlite.LLVMType* = recv_val_c.Ty if self.Gen.ExprGenBase.is_ptr_type(recv_ty_c) != 0: recv_ty_c = recv_ty_c.Pointee # 堆对象(@t.Object)双指针 → 再解一层取 struct if self.Gen.ExprGenBase.is_ptr_type(recv_ty_c) != 0: recv_ty_c = recv_ty_c.Pointee - recv_cls_c: str = self.Gen.StructGen.get_class_name_by_type( - pool, recv_ty_c) + recv_cls_c: str = self.Gen.StructGen.get_class_name_by_type(pool, recv_ty_c) 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: 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: - obj_ptr_c = llvmlite.build_load( - builder, recv_val_c.Ty, recv_val_c) + 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* = recv_val_c + if self.Gen.ExprGenBase.is_ptr_type(recv_val_c.Ty) != 0 and recv_val_c.Ty.Pointee != 0 and self.Gen.ExprGenBase.is_ptr_type(recv_val_c.Ty.Pointee) != 0: + obj_ptr_c = llvmlite.build_load(builder, recv_val_c.Ty, recv_val_c) if obj_ptr_c is not None: if hit_box is not None: hit_box[0] = 1 - return self.Gen.CallGenCall._translate_method_call( - pool, builder, mod, recv_cls_c, method_at.attr, - obj_ptr_c, cl, trans) + return self.Gen.CallGenCall._translate_method_call(pool, builder, mod, recv_cls_c, method_at.attr, obj_ptr_c, cl, trans) if method_at.value.kind() == ast.ASTKind.Name and trans is not None: - method_obj_nm: rawptr[ast.Name] = rawptr[ast.Name](method_at.value) + method_obj_nm: ast.Name* = ast.Name*(method_at.value) if method_obj_nm.id is not None: # nonlocal 对象:提升函数内从 env 读对象指针(load_nonlocal_var), # 不能 lookup_var 跨函数命中父函数 alloca(SSA 编号错乱 → @@ -1242,37 +1106,28 @@ 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: rawptr[llvmlite.Value] = self.Gen.StmtGenDecl.load_nonlocal_var( - trans, method_obj_nm.id) + nl_obj: 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: rawptr[llvmlite.Value] = self.Gen.ExprGenBase._deref_if_ptr_ptr( - builder, nl_obj) + nl_deref: llvmlite.Value* = self.Gen.ExprGenBase._deref_if_ptr_ptr(builder, nl_obj) if nl_deref is None: nl_deref = nl_obj - nl_struct: rawptr[llvmlite.LLVMType] = \ - self.Gen.StructGen.get_struct_type_from_value(nl_deref) + nl_struct: llvmlite.LLVMType* = self.Gen.StructGen.get_struct_type_from_value(nl_deref) if nl_struct is not None: - nl_cls: str = self.Gen.StructGen.get_class_name_by_type( - pool, nl_struct) + nl_cls: str = self.Gen.StructGen.get_class_name_by_type(pool, nl_struct) if nl_cls is not None: - if self.Gen.CallGenProp._is_list_builtin_receiver( - pool, nl_deref, nl_cls, func_name, cl) == 0: + if self.Gen.CallGenProp._is_list_builtin_receiver(pool, nl_deref, nl_cls, func_name, cl) == 0: if hit_box is not None: hit_box[0] = 1 - return self.Gen.CallGenCall._translate_method_call( - pool, builder, mod, nl_cls, func_name, - nl_deref, cl, trans) + return self.Gen.CallGenCall._translate_method_call(pool, builder, mod, nl_cls, func_name, nl_deref, cl, trans) # 非 local 对象但分派未成功:绝不回退 lookup_var # (其 Alloca 是父函数存储,跨函数引用 → SSA 错乱), # 返回 None 让上层 fast-fail 暴露类型解析问题。 return None # 查找对象变量 - obj_var: rawptr[llvmlite.Value] = self.Gen.VarGen.lookup_var( - trans.SymTab, method_obj_nm.id) + obj_var: 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: rawptr[GenTypes.VarEntry] = self.Gen.VarGen.lookup_var_entry( - trans.SymTab, method_obj_nm.id) + var_entry: 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) if la_buf is not None: @@ -1280,13 +1135,11 @@ class CallGenDispatch(CallGenBase.CallGenBase): if string.strncmp(la_buf, "rawptr[", 7) == 0: la_tail = la_buf + 7 if string.strncmp(la_tail, "list", 4) == 0: - if self.Gen.CallGenProp._is_list_builtin_receiver( - pool, obj_var, la_tail, func_name, cl) != 0: + if self.Gen.CallGenProp._is_list_builtin_receiver(pool, obj_var, la_tail, func_name, cl) != 0: is_list_annot_builtin = 1 match obj_var.Ty: case llvmlite.LLVMType.Ptr(obj_struct_ty): - class_nm: str = self.Gen.StructGen.get_class_name_by_type( - pool, obj_struct_ty) + class_nm: str = self.Gen.StructGen.get_class_name_by_type(pool, obj_struct_ty) if class_nm is not None: # list 泛型内置容器方法(append/get/set/pop/clear/__iter__/ # __len__/__getitem__/__setitem__)由下方 list 内置分支 @@ -1297,35 +1150,25 @@ class CallGenDispatch(CallGenBase.CallGenBase): # 注解兜底(is_list_annot_builtin=1)同跳过:class_nm # 可能被类型名后缀匹配错解为内层元素类,非 'list' 前缀 # 拦截会漏放 → 走 method_call/MRO fatal。 - if self.Gen.CallGenProp._is_list_builtin_receiver( - pool, obj_var, class_nm, func_name, cl) == 0 \ - and is_list_annot_builtin == 0: + if self.Gen.CallGenProp._is_list_builtin_receiver(pool, obj_var, class_nm, func_name, cl) == 0 and is_list_annot_builtin == 0: if hit_box is not None: hit_box[0] = 1 - return self.Gen.CallGenCall._translate_method_call( - pool, builder, mod, class_nm, func_name, - obj_var, cl, trans) + return self.Gen.CallGenCall._translate_method_call(pool, builder, mod, class_nm, func_name, obj_var, cl, trans) # 指针变量: alloca 类型是 Ptr(Ptr(Struct)) # load 获取实际指针 Ptr(Struct) 后再查找 match obj_struct_ty: case llvmlite.LLVMType.Ptr(inner_struct_ty): - inner_nm: str = self.Gen.StructGen.get_class_name_by_type( - pool, inner_struct_ty) + inner_nm: str = self.Gen.StructGen.get_class_name_by_type(pool, inner_struct_ty) if inner_nm is not None: # list 内置方法同样跳过(同 Ptr(Struct) 分支); # 注解兜底(is_list_annot_builtin=1)同跳过: # inner_nm 也可能被后缀匹配错解为内层元素类。 - 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: rawptr[llvmlite.Value] = llvmlite.build_load( - builder, obj_struct_ty, obj_var) + 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* = llvmlite.build_load(builder, obj_struct_ty, obj_var) if obj_ptr is not None: if hit_box is not None: hit_box[0] = 1 - return self.Gen.CallGenCall._translate_method_call( - pool, builder, mod, inner_nm, func_name, - obj_ptr, cl, trans) + return self.Gen.CallGenCall._translate_method_call(pool, builder, mod, inner_nm, func_name,obj_ptr, cl, trans) # FakeDuck: str/bytes 变量(Ptr(i8),AnnotClassName 为空) # 方法调用 → 扩展类 _Type/_str(a.type_id() / a.upper())。 # 前置拦截:常规结构体方法分支全落空时,尝试扩展类方法 @@ -1333,8 +1176,7 @@ class CallGenDispatch(CallGenBase.CallGenBase): # list 容器注解命中(is_list_annot_builtin=1)时跳过 FakeDuck: # 接收者非 str/bytes,此调用必须由尾部 list 内置分支翻译。 if is_list_annot_builtin == 0: - fd_name_res: rawptr[llvmlite.Value] = self.Gen.CallGenFd._translate_fakeduck_call( - pool, builder, mod, None, func_name, cl, trans) + fd_name_res: 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 # AnnotClassName 回退:联合类型简化为 Ptr(i8) 时, @@ -1365,30 +1207,23 @@ class CallGenDispatch(CallGenBase.CallGenBase): if self.Gen.StructGen.get_struct_type(cls_nm2) is not None: # list 内置方法跳过 method_call(同 Ptr(Struct) 分支), # 落到下方 list 内置分支 - if self.Gen.CallGenProp._is_list_builtin_receiver( - pool, obj_var, cls_nm2, func_name, cl) == 0: + if self.Gen.CallGenProp._is_list_builtin_receiver(pool, obj_var, cls_nm2, func_name, cl) == 0: # 结构体已注册:load obj_ptr 走方法调用 - i8_ptr_ty2: rawptr[llvmlite.LLVMType] = llvmlite.Ptr( - pool, llvmlite.Int8(pool)) - obj_ptr2: rawptr[llvmlite.Value] = llvmlite.build_load( - builder, i8_ptr_ty2, obj_var) + i8_ptr_ty2: llvmlite.LLVMType* = llvmlite.Ptr(pool, llvmlite.Int8(pool)) + obj_ptr2: llvmlite.Value* = llvmlite.build_load(builder, i8_ptr_ty2, obj_var) if obj_ptr2 is not None: if hit_box is not None: hit_box[0] = 1 - return self.Gen.CallGenCall._translate_method_call( - pool, builder, mod, cls_nm2, func_name, - obj_ptr2, cl, trans) + return self.Gen.CallGenCall._translate_method_call(pool, builder, mod, cls_nm2, func_name,obj_ptr2, cl, trans) else: # list 内置方法跳过(结构体未注册路径同样不能 # 构造 {sha1}.{cls}.append 调用名——list 方法无此函数) - if self.Gen.CallGenProp._is_list_builtin_receiver( - pool, obj_var, cls_nm2, func_name, cl) == 0: + if self.Gen.CallGenProp._is_list_builtin_receiver(pool, obj_var, cls_nm2, func_name, cl) == 0: # FakeDuck: str 变量方法调用 → 扩展类 _Type/_str # a.type_id() / a.upper() / " ".isspace() 等 # AnnotClassName=="str" 且对象是 char* 时触发, # self 用影子结构体 {a}__meta__(或临时影子)。 - fd_res: rawptr[llvmlite.Value] = self.Gen.CallGenFd._translate_fakeduck_call( - pool, builder, mod, cls_nm2, func_name, cl, trans) + fd_res: 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 # 结构体未注册(跨模块依赖未翻译): @@ -1403,34 +1238,28 @@ class CallGenDispatch(CallGenBase.CallGenBase): if mangled3 is not None: viperlib.snprintf(mangled3, mlen3, "%s.%s.%s", sha1_fc, cls_nm2, func_name) # load obj_ptr (self) - i8_ptr_ty3: rawptr[llvmlite.LLVMType] = llvmlite.Ptr( - pool, llvmlite.Int8(pool)) - obj_ptr3: rawptr[llvmlite.Value] = llvmlite.build_load( - builder, i8_ptr_ty3, obj_var) + i8_ptr_ty3: llvmlite.LLVMType* = llvmlite.Ptr(pool, llvmlite.Int8(pool)) + obj_ptr3: 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: rawptr[llvmlite.Value] = obj_ptr3 - tail3: rawptr[llvmlite.Value] = obj_ptr3 + head3: llvmlite.Value* = obj_ptr3 + tail3: llvmlite.Value* = obj_ptr3 for ai3 in range(can): - arg3: rawptr[ast.AST] = cargs.get(ai3) + arg3: ast.AST* = cargs.get(ai3) if arg3 is not None: - arg_val3: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( - builder, pool, mod, arg3, None, 0, trans) + arg_val3: 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) llvmlite.value_set_next(tail3, arg_val3) tail3 = arg_val3 total3: int = 1 + can - ret_ty3: rawptr[llvmlite.LLVMType] = self._special_method_ret_ty( - pool, cls_nm2, func_name) + ret_ty3: llvmlite.LLVMType* = self._special_method_ret_ty(pool, cls_nm2, func_name) if ret_ty3 is None: - ret_ty3 = self._LookupMethodRetTyFromTextLL( - pool, sha1_fc, cls_nm2, func_name) + ret_ty3 = self._LookupMethodRetTyFromTextLL(pool, sha1_fc, cls_nm2, func_name) if ret_ty3 is None: # 精确查找:vpi stub 返回注解缓存(方法定义处,不硬编码白名单) - ret_ty3 = self._lookup_method_ret_ty_via_vpi( - pool, sha1_fc, cls_nm2, func_name) + ret_ty3 = self._lookup_method_ret_ty_via_vpi(pool, sha1_fc, cls_nm2, func_name) if ret_ty3 is None: # 本分支仅在"注解类结构体未注册"时到达(L6932 else): # 类未注册 → 无法沿 MRO 解析 Mixin 方法定义模块。 @@ -1444,9 +1273,7 @@ class CallGenDispatch(CallGenBase.CallGenBase): # 返回 None 破坏表达式翻译) ret_ty3 = llvmlite.Int32(pool) # 先按 vpi 定义侧形参 coerce 实参(宽度对齐),再建 declare - head3 = self.Gen.CallGenLib._coerce_args_to_def_params( - pool, builder, mangled3, head3, total3, - cargs, 1, trans) + head3 = self.Gen.CallGenLib._coerce_args_to_def_params(pool, builder, mangled3, head3, total3, cargs, 1, trans) self._ensure_method_declare(pool, mod, mangled3, ret_ty3, head3, total3) return llvmlite.build_call(builder, mangled3, head3, total3, ret_ty3, 0) else: @@ -1458,19 +1285,14 @@ class CallGenDispatch(CallGenBase.CallGenBase): # 绝不掉出返回 None 让 translate_call 把对象名当模块名 # 报"跨模块调用 'buf.__before_init__' 找不到模块 SHA1" # (memhub.alloc_buf buf.__before_init__() 根因)。 - sp_ty4: rawptr[llvmlite.LLVMType] = self._special_method_ret_ty( - pool, cls_nm2, func_name) + sp_ty4: llvmlite.LLVMType* = self._special_method_ret_ty(pool, cls_nm2, func_name) if sp_ty4 is not None: - i8_ptr_ty4: rawptr[llvmlite.LLVMType] = llvmlite.Ptr( - pool, llvmlite.Int8(pool)) - obj_ptr4: rawptr[llvmlite.Value] = llvmlite.build_load( - builder, i8_ptr_ty4, obj_var) + i8_ptr_ty4: llvmlite.LLVMType* = llvmlite.Ptr(pool, llvmlite.Int8(pool)) + obj_ptr4: llvmlite.Value* = llvmlite.build_load(builder, i8_ptr_ty4, obj_var) if obj_ptr4 is not None: if hit_box is not None: hit_box[0] = 1 - return self.Gen.CallGenCall._translate_method_call( - pool, builder, mod, cls_nm2, func_name, - obj_ptr4, cl, trans) + return self.Gen.CallGenCall._translate_method_call(pool, builder, mod, cls_nm2, func_name, obj_ptr4, cl, trans) # ============================================================ # 检测表达式接收者方法调用: (expr).method(args) @@ -1480,7 +1302,7 @@ class CallGenDispatch(CallGenBase.CallGenBase): # 再从值的 LLVM 类型(Ptr(Struct))解析类名,走方法调用路径。 # ============================================================ if cl.func is not None and cl.func.kind() == ast.ASTKind.Attribute: - expr_method_at: rawptr[ast.Attribute] = rawptr[ast.Attribute](cl.func) + expr_method_at: ast.Attribute* = ast.Attribute*(cl.func) if expr_method_at is not None and expr_method_at.value is not None and trans is not None: evk: int = expr_method_at.value.kind() # Attribute 接收者区分两种形态: @@ -1492,40 +1314,36 @@ class CallGenDispatch(CallGenBase.CallGenBase): # SHA1"(zdeflate.vp write_fixed_block 根因) is_mod_path_expr: int = 0 if evk == ast.ASTKind.Attribute: - expr_root: rawptr[ast.AST] = expr_method_at.value + expr_root: ast.AST* = expr_method_at.value while expr_root is not None and expr_root.kind() == ast.ASTKind.Attribute: - expr_root = rawptr[ast.Attribute](expr_root).value + expr_root = ast.Attribute*(expr_root).value if expr_root is not None and expr_root.kind() == ast.ASTKind.Name: - expr_root_nm: str = rawptr[ast.Name](expr_root).id + expr_root_nm: str = ast.Name*(expr_root).id if expr_root_nm is not None: if string.strcmp(expr_root_nm, "t") == 0 or \ string.strcmp(expr_root_nm, "c") == 0: is_mod_path_expr = 1 elif trans._imported_modules is not None: - if self.Gen.ImportsGen.is_module_imported( - trans._imported_modules, expr_root_nm) != 0: + if self.Gen.ImportsGen.is_module_imported(trans._imported_modules, expr_root_nm) != 0: is_mod_path_expr = 1 if evk != ast.ASTKind.Name and is_mod_path_expr == 0: # 翻译接收者表达式(求值结果应为 Ptr(Struct)) - expr_obj: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( - builder, pool, mod, expr_method_at.value, funcs_ptr, func_count, trans) + expr_obj: 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 # 递归解 Ptr:识别 X|t.CPtr 联合简化的 Ptr(Ptr(Struct)) # (如 (a*2.0 - b) 中 __mul__ 返回 Vec3**),否则方法 # 调用被当裸函数 @dot 解析 → 链接 undefined symbol - expr_struct_ty: rawptr[llvmlite.LLVMType] = \ + expr_struct_ty: llvmlite.LLVMType* = \ self.Gen.StructGen.get_struct_type_from_value(expr_obj) if expr_struct_ty is not None: - expr_cls_nm = self.Gen.StructGen.get_class_name_by_type( - pool, expr_struct_ty) + expr_cls_nm = self.Gen.StructGen.get_class_name_by_type(pool, expr_struct_ty) # 回退:LLVM 类型为 Ptr(i8)(方法返回 X|t.CPtr 无类型信息)时, # 从接收者表达式结构推断类名(链式调用 c2.scale(2.0).move(...) # 的 scale 返回 Ptr(i8),经 infer_expr_class → vpi 返回注解) # 跨 Mixin 不能 self 调用 ExprGenMixin 方法,经全局单例 if expr_cls_nm is None: - expr_cls_nm = self.Gen.ExprGenCls.infer_expr_class( - pool, mod, expr_method_at.value, trans) + expr_cls_nm = self.Gen.ExprGenCls.infer_expr_class(pool, mod, expr_method_at.value, trans) if expr_cls_nm is not None: # 值类型接收者(内嵌 struct 字段,如 zdeflate s.writer 值字段): # 方法调用 self 必须传字段地址(GEP)而非 load 出的结构体值, @@ -1540,20 +1358,16 @@ class CallGenDispatch(CallGenBase.CallGenBase): case _: expr_is_ptr = 0 if expr_is_ptr == 0: - expr_addr: rawptr[llvmlite.Value] = self.Gen.ExprGenAttr.get_attribute_ptr( - builder, pool, mod, expr_method_at.value, trans) + expr_addr: 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 if hit_box is not None: hit_box[0] = 1 - return self.Gen.CallGenCall._translate_method_call( - pool, builder, mod, expr_cls_nm, func_name, - expr_obj, cl, trans) + return self.Gen.CallGenCall._translate_method_call(pool, builder, mod, expr_cls_nm, func_name, expr_obj, cl, trans) # FakeDuck: 表达式接收者解析失败且对象是 char* 时 # (如 " ".isspace()),尝试扩展类 _Type/_str 方法 # (self 用临时影子,对齐 TPC L2858-2873) - fd_expr_res: rawptr[llvmlite.Value] = self.Gen.CallGenFd._translate_fakeduck_call( - pool, builder, mod, None, func_name, cl, trans) + fd_expr_res: 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 @@ -1567,33 +1381,29 @@ class CallGenDispatch(CallGenBase.CallGenBase): # 路径2: 从字段的 AnnotClassName 回退查找(字段类型被简化为 Ptr(i8) 时) # ============================================================ if cl.func is not None and cl.func.kind() == ast.ASTKind.Attribute: - attr_method_at: rawptr[ast.Attribute] = rawptr[ast.Attribute](cl.func) + attr_method_at: ast.Attribute* = ast.Attribute*(cl.func) if attr_method_at is not None and attr_method_at.value is not None: if attr_method_at.value.kind() == ast.ASTKind.Attribute and trans is not None: - inner_attr: rawptr[ast.Attribute] = rawptr[ast.Attribute](attr_method_at.value) + inner_attr: ast.Attribute* = ast.Attribute*(attr_method_at.value) if inner_attr is not None and inner_attr.attr is not None: # 翻译 self.__pool__ 获取字段值(已 load 的对象指针) - field_obj: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( - builder, pool, mod, attr_method_at.value, funcs_ptr, func_count, trans) + field_obj: 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 # 路径1: 从字段值的 LLVM 类型获取类名 match field_obj.Ty: case llvmlite.LLVMType.Ptr(field_struct_ty): - field_cls_nm = self.Gen.StructGen.get_class_name_by_type( - pool, field_struct_ty) + field_cls_nm = self.Gen.StructGen.get_class_name_by_type(pool, field_struct_ty) # 路径2: 从字段注解类名回退查找 if field_cls_nm is None: 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) + inner_name_node: ast.Name* = ast.Name*(inner_attr.value) if inner_name_node is not None and inner_name_node.id is not None: - inner_var: rawptr[llvmlite.Value] = self.Gen.VarGen.lookup_var( - trans.SymTab, inner_name_node.id) + inner_var: 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: rawptr[GenTypes.FieldEntry] = self.Gen.StructGen.lookup_field( - field_owner_struct_ty, inner_attr.attr) + field_info: 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) if field_annot is not None: @@ -1615,15 +1425,12 @@ class CallGenDispatch(CallGenBase.CallGenBase): case _: is_val_field = 1 if is_val_field != 0: - field_addr: rawptr[llvmlite.Value] = self.Gen.ExprGenAttr.get_attribute_ptr( - builder, pool, mod, attr_method_at.value, trans) + field_addr: 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 if hit_box is not None: hit_box[0] = 1 - return self.Gen.CallGenCall._translate_method_call( - pool, builder, mod, field_cls_nm, func_name, - field_obj, cl, trans) + return self.Gen.CallGenCall._translate_method_call(pool, builder, mod, field_cls_nm, func_name, field_obj, cl, trans) # ============================================================ # 检测 list 内置方法调用: lst.get(i), lst.set(i,v), lst.pop(), lst.clear(), lst.__iter__() @@ -1633,7 +1440,7 @@ class CallGenDispatch(CallGenBase.CallGenBase): # __data__(0) __count__(8) __capacity__(16) __pool__(24) __elem_size__(32) __iter_index__(40) # ============================================================ if cl.func is not None and cl.func.kind() == ast.ASTKind.Attribute: - lm_at: rawptr[ast.Attribute] = rawptr[ast.Attribute](cl.func) + lm_at: ast.Attribute* = ast.Attribute*(cl.func) if lm_at is not None and lm_at.attr is not None and lm_at.value is not None: lm_name: str = lm_at.attr # 判断是否是 list 方法名 @@ -1649,8 +1456,7 @@ class CallGenDispatch(CallGenBase.CallGenBase): if lm_is_list == 1 and trans is not None: # 翻译 list 对象 - lm_obj: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( - builder, pool, mod, lm_at.value, funcs_ptr, func_count, trans) + lm_obj: 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 # translate_value 对某些 Attribute 节点(如 ast.Arguments 的属性) @@ -1659,15 +1465,14 @@ class CallGenDispatch(CallGenBase.CallGenBase): if lm_obj.Ty is None or self.Gen.ExprGenBase.is_ptr_type(lm_obj.Ty) == 0: # translate_value 类型推断失败(目标对象非指针): # fail-fast,绝不 VLogger.critical 后 return None 静默吞掉 - self.Gen.TypeGenErr.fatal_error( - lm_at.value, f"list 方法 '{lm_name}' 目标对象非指针", "TypeError") + self.Gen.TypeGenErr.fatal_error(lm_at.value, f"list 方法 '{lm_name}' 目标对象非指针", "TypeError") # list 对象类型确认(额外搜索路径):list 内置分支仅按方法名 # 判断(get/set/__getitem__ 等非 list 专有),须确认对象确实 # 是 list——从对象结构体名匹配 "list"。明确非 list(如 dict / # 普通类未注册场景)跳过本分支,避免按 list 布局 GEP 生成 # 错误 IR(dict 的 get 被当 list.get 按 __data__/__elem_size__ # 偏移读写垃圾)。 - lm_conf_ty: rawptr[llvmlite.LLVMType] = \ + lm_conf_ty: llvmlite.LLVMType* = \ self.Gen.StructGen.get_struct_type_from_value(lm_obj) lm_conf_nm: str = None if lm_conf_ty is not None: @@ -1687,9 +1492,9 @@ class CallGenDispatch(CallGenBase.CallGenBase): # 调用点的 hit_box 置位模式)。 if hit_box is not None: hit_box[0] = 1 - i64_ty: rawptr[llvmlite.LLVMType] = llvmlite.Int64(pool) - i8_ty: rawptr[llvmlite.LLVMType] = llvmlite.Int8(pool) - i8_ptr_ty: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, i8_ty) + i64_ty: llvmlite.LLVMType* = llvmlite.Int64(pool) + i8_ty: llvmlite.LLVMType* = llvmlite.Int8(pool) + i8_ptr_ty: llvmlite.LLVMType* = llvmlite.Ptr(pool, i8_ty) # 元素类型 T:从 list 特化类型名解析(list[int]→i32、 # list[str]→i8*、未知/指针元素→i8*)。此前 get/set/pop # 固定 i8*(8 字节)读写:set 的 8 字节 store 覆盖相邻元素 @@ -1697,15 +1502,14 @@ class CallGenDispatch(CallGenBase.CallGenBase): # pop 读回 0 → ListTest "pop FAILED expect 30" 根因。 # subscript 路径(list_getitem_inline 调用方)已用 # _list_elem_type_from_name 修正,方法调用路径漏改。 - lm_esty: rawptr[llvmlite.LLVMType] = \ + lm_esty: llvmlite.LLVMType* = \ self.Gen.StructGen.get_struct_type_from_value(lm_obj) lm_ename: str = None if lm_esty is not None: lm_ename = llvmlite.get_struct_name(lm_esty) - lm_elem_ty: rawptr[llvmlite.LLVMType] = None + lm_elem_ty: llvmlite.LLVMType* = None if lm_ename is not None: - lm_elem_ty = self.Gen.ExprGenName._list_elem_type_from_name( - pool, lm_ename) + lm_elem_ty = self.Gen.ExprGenName._list_elem_type_from_name(pool, lm_ename) if lm_elem_ty is None: lm_elem_ty = i8_ptr_ty @@ -1713,91 +1517,81 @@ 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: 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) + g_idx0: llvmlite.Value* = llvmlite.const_int64(pool, 0) + g_dpp: llvmlite.Value* = llvmlite.build_gep(builder, i64_ty, lm_obj, g_idx0) + g_data: llvmlite.Value* = llvmlite.build_load(builder, i8_ptr_ty, g_dpp) # 加载 __elem_size__ (偏移 32, index 4) - 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) + g_idx4: llvmlite.Value* = llvmlite.const_int64(pool, 4) + g_epp: llvmlite.Value* = llvmlite.build_gep(builder, i64_ty, lm_obj, g_idx4) + g_esize: llvmlite.Value* = llvmlite.build_load(builder, i64_ty, g_epp) # 翻译 index - g_idx_node: rawptr[ast.AST] = cargs.get(0) - g_idx_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( - builder, pool, mod, g_idx_node, None, 0, trans) + g_idx_node: ast.AST* = cargs.get(0) + g_idx_val: 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: rawptr[llvmlite.Value] = self.Gen.ExprGenBase.coerce_to_type( - builder, g_idx_val, i64_ty, g_idx_node) - 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) + g_idx_i64: llvmlite.Value* = self.Gen.ExprGenBase.coerce_to_type(builder, g_idx_val, i64_ty, g_idx_node) + g_offset: llvmlite.Value* = llvmlite.build_mul(builder, g_idx_i64, g_esize) + g_addr: llvmlite.Value* = llvmlite.build_gep(builder, i8_ty, g_data, g_offset) if g_addr is not None: - g_ep: rawptr[llvmlite.Value] = llvmlite.build_bitcast( - builder, g_addr, llvmlite.Ptr(pool, lm_elem_ty)) + g_ep: 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) # set / __setitem__: 设置 index 处的元素 elif string.strcmp(lm_name, "set") == 0 or string.strcmp(lm_name, "__setitem__") == 0: if can >= 2: - 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: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( - builder, pool, mod, s_idx_node, None, 0, trans) - s_val_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( - builder, pool, mod, s_val_node, None, 0, trans) + s_idx0: llvmlite.Value* = llvmlite.const_int64(pool, 0) + s_dpp: llvmlite.Value* = llvmlite.build_gep(builder, i64_ty, lm_obj, s_idx0) + s_data: llvmlite.Value* = llvmlite.build_load(builder, i8_ptr_ty, s_dpp) + s_idx4: llvmlite.Value* = llvmlite.const_int64(pool, 4) + s_epp: llvmlite.Value* = llvmlite.build_gep(builder, i64_ty, lm_obj, s_idx4) + s_esize: llvmlite.Value* = llvmlite.build_load(builder, i64_ty, s_epp) + s_idx_node: ast.AST* = cargs.get(0) + s_val_node: ast.AST* = cargs.get(1) + s_idx_val: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, mod, s_idx_node, None, 0, trans) + s_val_val: 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: rawptr[llvmlite.Value] = self.Gen.ExprGenBase.coerce_to_type( - builder, s_idx_val, i64_ty, s_idx_node) - 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) + s_idx_i64: llvmlite.Value* = self.Gen.ExprGenBase.coerce_to_type(builder, s_idx_val, i64_ty, s_idx_node) + s_offset: llvmlite.Value* = llvmlite.build_mul(builder, s_idx_i64, s_esize) + s_addr: llvmlite.Value* = llvmlite.build_gep(builder, i8_ty, s_data, s_offset) if s_addr is not None: - s_val_elem: rawptr[llvmlite.Value] = self.Gen.ExprGenBase.coerce_to_type( - builder, s_val_val, lm_elem_ty, s_val_node) - s_ep: rawptr[llvmlite.Value] = llvmlite.build_bitcast( - builder, s_addr, llvmlite.Ptr(pool, lm_elem_ty)) + s_val_elem: llvmlite.Value* = self.Gen.ExprGenBase.coerce_to_type(builder, s_val_val, lm_elem_ty, s_val_node) + s_ep: 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) return None # pop: 返回最后一个元素,count-- elif string.strcmp(lm_name, "pop") == 0: - 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)) + p_idx1: llvmlite.Value* = llvmlite.const_int64(pool, 1) + p_cpp: llvmlite.Value* = llvmlite.build_gep(builder, i64_ty, lm_obj, p_idx1) + p_count: llvmlite.Value* = llvmlite.build_load(builder, i64_ty, p_cpp) + p_nc: llvmlite.Value* = llvmlite.build_sub(builder, p_count, llvmlite.const_int64(pool, 1)) llvmlite.build_store(builder, p_nc, p_cpp) - 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) + p_idx0: llvmlite.Value* = llvmlite.const_int64(pool, 0) + p_dpp: llvmlite.Value* = llvmlite.build_gep(builder, i64_ty, lm_obj, p_idx0) + p_data: llvmlite.Value* = llvmlite.build_load(builder, i8_ptr_ty, p_dpp) + p_idx4: llvmlite.Value* = llvmlite.const_int64(pool, 4) + p_epp: llvmlite.Value* = llvmlite.build_gep(builder, i64_ty, lm_obj, p_idx4) + p_esize: 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: 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) + p_offset: llvmlite.Value* = llvmlite.build_mul(builder, p_nc, p_esize) + p_addr: llvmlite.Value* = llvmlite.build_gep(builder, i8_ty, p_data, p_offset) if p_addr is not None: - p_ep: rawptr[llvmlite.Value] = llvmlite.build_bitcast( - builder, p_addr, llvmlite.Ptr(pool, lm_elem_ty)) + p_ep: 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: rawptr[llvmlite.Value] = llvmlite.const_int64(pool, 1) - c_cpp: rawptr[llvmlite.Value] = llvmlite.build_gep(builder, i64_ty, lm_obj, c_idx1) + c_idx1: llvmlite.Value* = llvmlite.const_int64(pool, 1) + c_cpp: 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: rawptr[llvmlite.Value] = llvmlite.const_int64(pool, 5) - it_ipp: rawptr[llvmlite.Value] = llvmlite.build_gep(builder, i64_ty, lm_obj, it_idx5) + it_idx5: llvmlite.Value* = llvmlite.const_int64(pool, 5) + it_ipp: 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 @@ -1809,9 +1603,7 @@ class CallGenDispatch(CallGenBase.CallGenBase): if ap_sha1 is None: # 依赖模块未编译(_list 未预加入编译链):fail-fast, # 绝不静默跳过 append(元素永远不会被加入列表) - self.Gen.TypeGenErr.fatal_error( - cl, "list.append: 找不到 _list 模块 SHA1(依赖模块未编译)", - "InternalCompilerError") + self.Gen.TypeGenErr.fatal_error(cl, "list.append: 找不到 _list 模块 SHA1(依赖模块未编译)", "InternalCompilerError") if ap_sha1 is not None: # 特化类名提取:list.append 的符号名是 # {sha1}.list[AST|CPtr].append(带类型参数特化名), @@ -1819,11 +1611,9 @@ class CallGenDispatch(CallGenBase.CallGenBase): # Ptr(list[AST|CPtr]),从类型解析特化类名拼接调用名, # 否则 ld.lld undefined symbol(定义端是特化名)。 ap_spec_nm: str = None - ap_struct_ty: rawptr[llvmlite.LLVMType] = \ - self.Gen.StructGen.get_struct_type_from_value(lm_obj) + ap_struct_ty: llvmlite.LLVMType* = self.Gen.StructGen.get_struct_type_from_value(lm_obj) if ap_struct_ty is not None: - ap_spec_nm = self.Gen.StructGen.get_class_name_by_type( - pool, ap_struct_ty) + ap_spec_nm = self.Gen.StructGen.get_class_name_by_type(pool, ap_struct_ty) if ap_spec_nm is None: ap_spec_nm = "list" # 触发泛型特化翻译(幂等,MethodsEmitted 防重入): @@ -1845,7 +1635,7 @@ class CallGenDispatch(CallGenBase.CallGenBase): base_buf_ap[base_len_ap] = '\0' string.strncpy(arg_buf_ap, lbkt_ap + 1, arg_len_ap) arg_buf_ap[arg_len_ap] = '\0' - args_ap: list[str] | t.CPtr = list[str](pool, 8) + args_ap: list[str]* = list[str](pool, 8) if args_ap is not None: # 逗号分隔多类型实参(list[X] / dict[K, V]) cur_ap: str = arg_buf_ap @@ -1861,26 +1651,22 @@ class CallGenDispatch(CallGenBase.CallGenBase): seg_buf_ap[seg_len_ap] = '\0' args_ap.append(seg_buf_ap) cur_ap = comma_ap + 1 - self.Gen.ClassGenGeneric._specialize_generic_class( - trans, base_buf_ap, args_ap) + self.Gen.ClassGenGeneric._specialize_generic_class(trans, base_buf_ap, args_ap) # 调用名 "{sha1}.{spec}.append": # sha1(16) + '.'(1) + spec + '.append'(7) + NUL(1) = spec + 25。 # 此前 +8 少 1 字节,snprintf 截断末尾 'd' → # undefined symbol: ...list[AST|CPtr].appen(缺 d)。 - ap_mlen: sizet = string.strlen(ap_sha1) + \ - string.strlen(ap_spec_nm) + 26 + ap_mlen: sizet = string.strlen(ap_sha1) + string.strlen(ap_spec_nm) + 26 ap_mangled: str = pool.alloc(ap_mlen) if ap_mangled is not None: - 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: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( - builder, pool, mod, ap_item_node, None, 0, trans) + viperlib.snprintf(ap_mangled, ap_mlen, "%s.%s.append", ap_sha1, ap_spec_nm) + ap_item_node: ast.AST* = cargs.get(0) + ap_item_val: 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) llvmlite.value_set_next(ap_item_val, None) llvmlite.value_set_next(lm_obj, ap_item_val) - ap_ret_ty: rawptr[llvmlite.LLVMType] = llvmlite.Int32(pool) + ap_ret_ty: llvmlite.LLVMType* = llvmlite.Int32(pool) self._ensure_method_declare(pool, mod, ap_mangled, ap_ret_ty, lm_obj, 2) return llvmlite.build_call(builder, ap_mangled, lm_obj, 2, ap_ret_ty, 0) diff --git a/App/lib/core/Gen/Call/CallGenFd.vp b/App/lib/core/Gen/Call/CallGenFd.vp index 7834a5b..1866469 100644 --- a/App/lib/core/Gen/Call/CallGenFd.vp +++ b/App/lib/core/Gen/Call/CallGenFd.vp @@ -26,13 +26,13 @@ class CallGenFd(CallGenBase.CallGenBase): # _translate_fakeduck_call:FakeDuck str 变量方法调用 → 扩展类 _Type/_str(对齐 TPC HandlesExprCall.py L2841-2880)。对象是 Name 且有影子({var}__meta__)时 self=影子;否则在入口创建临时影子(__data__=obj 值、__mbuddy__=NULL)后作 self,避免 bitcast i8* → _str* 读垃圾指针 # ============================================================ - def _translate_fakeduck_call(self, pool: rawptr[memhub.MemBuddy], - builder: rawptr[llvmlite.IRBuilder], - mod: rawptr[llvmlite.LLVMModule], + def _translate_fakeduck_call(self, pool: memhub.MemBuddy*, + builder: llvmlite.IRBuilder*, + mod: llvmlite.LLVMModule*, cls_name: str, method_name: str, - cl: rawptr[ast.Call], - trans: rawptr[HT.Translator]) -> rawptr[llvmlite.Value]: + cl: ast.Call*, + trans: HT.Translator*) -> 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 @@ -44,13 +44,13 @@ class CallGenFd(CallGenBase.CallGenBase): return None if cl.func is None or cl.func.kind() != ast.ASTKind.Attribute: return None - fd_at: rawptr[ast.Attribute] = rawptr[ast.Attribute](cl.func) + fd_at: ast.Attribute* = ast.Attribute*(cl.func) if fd_at is None or fd_at.value is None or fd_at.attr is None: return None if string.strcmp(fd_at.attr, method_name) != 0: return None # 候选扩展类:先 _Type(a.type_id())后 _str(a.upper() 等) - fd_func: rawptr[llvmlite.Function] = None + fd_func: llvmlite.Function* = None fd_cls: str = None fd_key: str = pool.alloc(160) if fd_key is not None: @@ -66,26 +66,25 @@ class CallGenFd(CallGenBase.CallGenBase): if fd_func is None or fd_cls is None: return None # 扩展类结构体必须已注册(GEP/临时影子需要类型) - fd_sty: rawptr[llvmlite.LLVMType] = self.Gen.StructGen.get_struct_type(fd_cls) + fd_sty: llvmlite.LLVMType* = self.Gen.StructGen.get_struct_type(fd_cls) if fd_sty is None: return None # 扩展类字段数:有字段(_str)时 self 用影子结构体指针; # 无字段(_Type)时 self 用对象值 bitcast 到扩展类指针(对齐 TPC L2856-2876) - fd_entry_fd: rawptr[GenTypes.StructEntry] = self.Gen.StructGen.find_struct_by_type(fd_sty) + fd_entry_fd: 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: rawptr[llvmlite.Value] = None + fd_self: llvmlite.Value* = None if fd_at.value.kind() == ast.ASTKind.Name: - fd_onm: rawptr[ast.Name] = rawptr[ast.Name](fd_at.value) + fd_onm: ast.Name* = ast.Name*(fd_at.value) if fd_onm.id is not None: # pool 持久缓冲(f-string 栈缓冲在函数返回后失效) fd_mn: str = pool.alloc(256) if fd_mn is not None: viperlib.snprintf(fd_mn, 256, "%s__meta__", fd_onm.id) - fd_meta: rawptr[llvmlite.Value] = self.Gen.VarGen.lookup_current( - trans.SymTab, fd_mn) + fd_meta: 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 if fd_self is None: @@ -96,69 +95,57 @@ 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: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( - builder, pool, mod, fd_at.value, None, 0, trans) + fd_obj_val: 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: rawptr[GenTypes.FieldEntry] = \ - self.Gen.StructGen.lookup_field(fd_sty, "__data__") + fd_dfe: 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: rawptr[llvmlite.Value] = llvmlite.build_gep_struct( - builder, fd_sty, fd_dfe.Ty, fd_self, fd_dfe.Index) + fd_dp: 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: rawptr[GenTypes.FieldEntry] = \ + fd_bfe: 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: rawptr[llvmlite.Value] = llvmlite.build_gep_struct( - builder, fd_sty, fd_bfe.Ty, fd_self, fd_bfe.Index) - fd_null: rawptr[llvmlite.Value] = llvmlite.ConstNull( - pool, fd_bfe.Ty, "null") + fd_bp: llvmlite.Value* = llvmlite.build_gep_struct(builder, fd_sty, fd_bfe.Ty, fd_self, fd_bfe.Index) + fd_null: 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) # FakeDuck: with 上下文自动注入 requires 字段(如 __mbuddy__) - self._inject_requires_fields( - trans, pool, builder, mod, fd_self, fd_cls) + self._inject_requires_fields(trans, pool, builder, mod, fd_self, fd_cls) else: # 无字段扩展类(_Type):对象值 bitcast 到扩展类指针 - 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 - fd_self = llvmlite.build_bitcast( - builder, fd_obj_v, llvmlite.Ptr(pool, fd_sty)) - if fd_self is None: - return None + fd_obj_v: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, mod, fd_at.value, None, 0, trans) + if fd_obj_v is None: return None + fd_self = llvmlite.build_bitcast(builder, fd_obj_v, llvmlite.Ptr(pool, fd_sty)) + if fd_self is None: return None # 构建参数链表: self → 其余参数 llvmlite.value_set_next(fd_self, None) - fd_head: rawptr[llvmlite.Value] = fd_self - fd_tail: rawptr[llvmlite.Value] = fd_self + fd_head: llvmlite.Value* = fd_self + fd_tail: llvmlite.Value* = fd_self fd_args: list[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) + fd_arg: ast.AST* = fd_args.get(fd_ai) if fd_arg is not None: - fd_av: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( - builder, pool, mod, fd_arg, None, 0, trans) + fd_av: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, mod, fd_arg, None, 0, trans) # char 常量参数 → 单字符字符串(char 隐式转 str, # 如 s1.split(','):',' 是 i32 值 44,传给 str 参数须先字符串化, # 否则运行时 strlen/strncmp 解引用 44 崩溃) if fd_arg.kind() == ast.ASTKind.Constant: - fd_ac: rawptr[ast.Constant] = rawptr[ast.Constant](fd_arg) + fd_ac: ast.Constant* = ast.Constant*(fd_arg) if fd_ac.const_kind == ast.CONST_CHAR: ch_buf: str = pool.alloc(2) if ch_buf is not None: ch_buf[0] = char(fd_ac.int_val) ch_buf[1] = '\0' - fd_av = self.Gen.ExprGenConst.create_global_string( - builder, pool, mod, ch_buf, trans) + fd_av = self.Gen.ExprGenConst.create_global_string(builder, pool, mod, ch_buf, trans) if fd_av is not None: llvmlite.value_set_next(fd_av, None) llvmlite.value_set_next(fd_tail, fd_av) fd_tail = fd_av # 返回类型与调用名(来自 find_func_in_module 命中的函数定义) - fd_ret_ty: rawptr[llvmlite.LLVMType] = llvmlite.function_get_ret_ty(fd_func) + fd_ret_ty: llvmlite.LLVMType* = llvmlite.function_get_ret_ty(fd_func) if fd_ret_ty is None: fd_ret_ty = llvmlite.Int32(pool) fd_fname: str = llvmlite.function_get_name(fd_func) @@ -170,8 +157,7 @@ class CallGenFd(CallGenBase.CallGenBase): if fd_sha1 is not None: string.strncpy(fd_sha1, fd_fname, 16) fd_sha1[16] = '\0' - fd_exact: rawptr[llvmlite.LLVMType] = self._LookupMethodRetTyFromTextLL( - pool, fd_sha1, fd_cls, method_name) + fd_exact: llvmlite.LLVMType* = self._LookupMethodRetTyFromTextLL(pool, fd_sha1, fd_cls, method_name) if fd_exact is not None: fd_ret_ty = fd_exact fd_total: int = 1 + fd_can @@ -188,11 +174,11 @@ class CallGenFd(CallGenBase.CallGenBase): # ============================================================ # ============================================================ - def _inject_requires_fields(self, trans: rawptr[HT.Translator], - pool: rawptr[memhub.MemBuddy], - builder: rawptr[llvmlite.IRBuilder], - mod: rawptr[llvmlite.LLVMModule], - meta_ptr: rawptr[llvmlite.Value], + def _inject_requires_fields(self, trans: HT.Translator*, + pool: memhub.MemBuddy*, + builder: llvmlite.IRBuilder*, + mod: llvmlite.LLVMModule*, + meta_ptr: llvmlite.Value*, class_name: str) -> int: """在 with 上下文注入 requires 字段,返回注入字段数""" if trans is None or pool is None or builder is None or mod is None: @@ -204,85 +190,56 @@ class CallGenFd(CallGenBase.CallGenBase): # (Gen.functions.get('_find_provider') 不存在则跳过)——否则非 with # 项目(如 HashTableTest 未 import _withcontent)也会为每个 _str(...) # 构造发射 {sha1}._find_provider 调用 → ld.lld undefined symbol。 - fd_fn_probe: rawptr[llvmlite.Function] = self.find_func_in_module( - mod, "_find_provider") - if fd_fn_probe is None: - return 0 + fd_fn_probe: llvmlite.Function* = self.find_func_in_module(mod, "_find_provider") + if fd_fn_probe is None: return 0 fd_fname: str = llvmlite.function_get_name(fd_fn_probe) - if fd_fname is None: - return 0 - cnt: int = self.Gen.ClassGenBase.class_meta_count( - GenTypes.CLASS_META_REQUIRES, class_name) - if cnt <= 0: - return 0 - sty: rawptr[llvmlite.LLVMType] = self.Gen.StructGen.get_struct_type(class_name) - if sty is None: - return 0 - i8_ty_j: rawptr[llvmlite.LLVMType] = llvmlite.Int8(pool) - if i8_ty_j is None: - return 0 - i8_ptr_ty_j: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, i8_ty_j) - if i8_ptr_ty_j is None: - return 0 - cur_func: rawptr[llvmlite.Function] = trans._cur_func - if cur_func is None: - return 0 + if fd_fname is None: return 0 + cnt: int = self.Gen.ClassGenBase.class_meta_count(GenTypes.CLASS_META_REQUIRES, class_name) + if cnt <= 0: return 0 + sty: llvmlite.LLVMType* = self.Gen.StructGen.get_struct_type(class_name) + if sty is None: return 0 + i8_ty_j: llvmlite.LLVMType* = llvmlite.Int8(pool) + if i8_ty_j is None: return 0 + i8_ptr_ty_j: llvmlite.LLVMType* = llvmlite.Ptr(pool, i8_ty_j) + if i8_ptr_ty_j is None: return 0 + cur_func: llvmlite.Function* = trans._cur_func + if cur_func is None: return 0 injected: int = 0 for ji in range(cnt): - fname: str = self.Gen.ClassGenBase.class_meta_field_at( - GenTypes.CLASS_META_REQUIRES, class_name, ji) - if fname is None: - continue - fe: rawptr[GenTypes.FieldEntry] = self.Gen.StructGen.lookup_field( - sty, fname) - if fe is None or fe.Ty is None: - continue + fname: str = self.Gen.ClassGenBase.class_meta_field_at(GenTypes.CLASS_META_REQUIRES, class_name, ji) + if fname is None: continue + fe: GenTypes.FieldEntry* = self.Gen.StructGen.lookup_field(sty, fname) + if fe is None or fe.Ty is None: continue # 参数:字段名字符串(i8*) - fd_fstr: rawptr[llvmlite.Value] = self.Gen.ExprGenConst.create_global_string( - builder, pool, mod, fname, trans) - if fd_fstr is None: - continue + fd_fstr: 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: rawptr[llvmlite.Value] = llvmlite.build_call( - builder, fd_fname, fd_fstr, 1, i8_ptr_ty_j, 0) - if fd_ptr is None: - continue + self._ensure_method_declare(pool, mod, fd_fname, i8_ptr_ty_j, fd_fstr, 1) + fd_ptr: 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: rawptr[llvmlite.Value] = llvmlite.ConstNull( - pool, i8_ptr_ty_j, "null") - if fd_null is None: - continue - fd_cmp: rawptr[llvmlite.Value] = llvmlite.build_icmp( - builder, llvmlite.ICMP_NE, fd_ptr, fd_null) - if fd_cmp is None: - continue + fd_null: llvmlite.Value* = llvmlite.ConstNull(pool, i8_ptr_ty_j, "null") + if fd_null is None: continue + fd_cmp: llvmlite.Value* = llvmlite.build_icmp(builder, llvmlite.ICMP_NE, fd_ptr, fd_null) + if fd_cmp is None: continue # 块名唯一化(create_block 不自动编号,同名 label 在文本 IR 中 # 冲突 → llc "Terminator found in the middle of a basic block") vtc2: int = trans._label_counter trans._label_counter = vtc2 + 1 fd_bb_buf2: str = pool.alloc(64) - if fd_bb_buf2 is None: - continue + if fd_bb_buf2 is None: continue viperlib.snprintf(fd_bb_buf2, 64, "fd.skip.%d", vtc2) - fd_skip_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block( - pool, cur_func, fd_bb_buf2) + 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: 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 + 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: rawptr[llvmlite.Value] = llvmlite.build_bitcast( - builder, fd_ptr, fe.Ty) + fd_cast: llvmlite.Value* = llvmlite.build_bitcast(builder, fd_ptr, fe.Ty) if fd_cast is not None: - 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) + fd_fp: 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) llvmlite.build_br(builder, fd_skip_bb) # skip 块:恢复 CurBlock,继续后续代码生成 llvmlite.position_at_end(builder, fd_skip_bb) @@ -299,85 +256,60 @@ class CallGenFd(CallGenBase.CallGenBase): # ============================================================ # ============================================================ - def _emit_provider_push(self, trans: rawptr[HT.Translator], - pool: rawptr[memhub.MemBuddy], - builder: rawptr[llvmlite.IRBuilder], - mod: rawptr[llvmlite.LLVMModule], + def _emit_provider_push(self, trans: HT.Translator*, + pool: memhub.MemBuddy*, + builder: llvmlite.IRBuilder*, + mod: llvmlite.LLVMModule*, cls_name: str, - ctx_val: rawptr[llvmlite.Value]) -> int: + ctx_val: 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 - if cls_name is None or ctx_val is None: - return 0 - fd_pc: int = self.Gen.ClassGenBase.class_meta_count( - GenTypes.CLASS_META_PROVIDES, cls_name) - if fd_pc <= 0: - return 0 + if trans is None or pool is None or builder is None or mod is None: return 0 + if cls_name is None or ctx_val is None: return 0 + fd_pc: int = self.Gen.ClassGenBase.class_meta_count(GenTypes.CLASS_META_PROVIDES, cls_name) + if fd_pc <= 0: return 0 # _withcontent._push_provider(跨模块,同 _find_provider 的可见性守卫: # 本模块未 import _withcontent 时跳过,避免 undefined symbol) - fd_pfn_probe: rawptr[llvmlite.Function] = self.find_func_in_module( - mod, "_push_provider") - if fd_pfn_probe is None: - return 0 + fd_pfn_probe: llvmlite.Function* = self.find_func_in_module(mod, "_push_provider") + if fd_pfn_probe is None: return 0 fd_pfn: str = llvmlite.function_get_name(fd_pfn_probe) - if fd_pfn is None: - return 0 - i8_ty_p: rawptr[llvmlite.LLVMType] = llvmlite.Int8(pool) - if i8_ty_p is None: - return 0 - i8_ptr_ty_p: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, i8_ty_p) - if i8_ptr_ty_p is None: - return 0 - ret_i32_p: rawptr[llvmlite.LLVMType] = llvmlite.Int32(pool) - if ret_i32_p is None: - return 0 + if fd_pfn is None: return 0 + i8_ty_p: llvmlite.LLVMType* = llvmlite.Int8(pool) + if i8_ty_p is None: return 0 + i8_ptr_ty_p: llvmlite.LLVMType* = llvmlite.Ptr(pool, i8_ty_p) + if i8_ptr_ty_p is None: return 0 + ret_i32_p: llvmlite.LLVMType* = llvmlite.Int32(pool) + if ret_i32_p is None: return 0 # ctx 值 bitcast 到 i8*(provider 栈存 void*) - fd_ctx_i8: rawptr[llvmlite.Value] = llvmlite.build_bitcast( - builder, ctx_val, i8_ptr_ty_p) - if fd_ctx_i8 is None: - return 0 + fd_ctx_i8: llvmlite.Value* = llvmlite.build_bitcast(builder, ctx_val, i8_ptr_ty_p) + if fd_ctx_i8 is None: return 0 for pi in range(fd_pc): - fname: str = self.Gen.ClassGenBase.class_meta_field_at( - GenTypes.CLASS_META_PROVIDES, cls_name, pi) - if fname is None: - continue - fd_fstr: rawptr[llvmlite.Value] = self.Gen.ExprGenConst.create_global_string( - builder, pool, mod, fname, trans) - if fd_fstr is None: - continue + fname: str = self.Gen.ClassGenBase.class_meta_field_at(GenTypes.CLASS_META_PROVIDES, cls_name, pi) + if fname is None: continue + fd_fstr: 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, fd_ctx_i8) llvmlite.value_set_next(fd_ctx_i8, None) - self._ensure_method_declare( - pool, mod, fd_pfn, ret_i32_p, fd_fstr, 2) + self._ensure_method_declare(pool, mod, fd_pfn, ret_i32_p, fd_fstr, 2) llvmlite.build_call(builder, fd_pfn, fd_fstr, 2, ret_i32_p, 0) return fd_pc - def _emit_provider_pop(self, trans: rawptr[HT.Translator], - pool: rawptr[memhub.MemBuddy], - builder: rawptr[llvmlite.IRBuilder], - mod: rawptr[llvmlite.LLVMModule], + def _emit_provider_pop(self, trans: HT.Translator*, + pool: memhub.MemBuddy*, + builder: llvmlite.IRBuilder*, + mod: llvmlite.LLVMModule*, cls_name: str) -> int: """生成 _pop_provider() 调用(每提供字段一次),返回字段数""" - if trans is None or pool is None or builder is None or mod is None: - return 0 - if cls_name is None: - return 0 - fd_pc: int = self.Gen.ClassGenBase.class_meta_count( - GenTypes.CLASS_META_PROVIDES, cls_name) - if fd_pc <= 0: - return 0 + if trans is None or pool is None or builder is None or mod is None: return 0 + if cls_name is None: return 0 + fd_pc: int = self.Gen.ClassGenBase.class_meta_count(GenTypes.CLASS_META_PROVIDES, cls_name) + if fd_pc <= 0: return 0 # _withcontent._pop_provider(跨模块,同 _find_provider 的可见性守卫: # 本模块未 import _withcontent 时跳过,避免 undefined symbol) - fd_pon_probe: rawptr[llvmlite.Function] = self.find_func_in_module( - mod, "_pop_provider") - if fd_pon_probe is None: - return 0 + fd_pon_probe: llvmlite.Function* = self.find_func_in_module(mod, "_pop_provider") + if fd_pon_probe is None: return 0 fd_pon: str = llvmlite.function_get_name(fd_pon_probe) - if fd_pon is None: - return 0 - ret_i32_q: rawptr[llvmlite.LLVMType] = llvmlite.Int32(pool) - if ret_i32_q is None: - return 0 + if fd_pon is None: return 0 + ret_i32_q: llvmlite.LLVMType* = llvmlite.Int32(pool) + if ret_i32_q is None: return 0 self._ensure_method_declare(pool, mod, fd_pon, ret_i32_q, None, 0) for _pi in range(fd_pc): llvmlite.build_call(builder, fd_pon, None, 0, ret_i32_q, 0) diff --git a/App/lib/core/Gen/Call/CallGenLeafKit.vp b/App/lib/core/Gen/Call/CallGenLeafKit.vp index eb68c61..9d2d900 100644 --- a/App/lib/core/Gen/Call/CallGenLeafKit.vp +++ b/App/lib/core/Gen/Call/CallGenLeafKit.vp @@ -19,30 +19,20 @@ from . import CallGenBase # ============================================================ # CallGenLeafKit - CallGenMixin 拆分 3/9:EH/isinstance/闭包/print/函数表 -# -# 按功能域从 CallGenMixin.vp 拆出(500~1500 行/文件架构重构): -# EH 防护 + isinstance + 闭包/函数指针 + printf/print + 全局函数表/默认参数表。 -# 继承 CallGenCBuiltin。 -# -# @t.NoVTable:静态绑定(方法沿 MRO 直接调用 + this 调整)。 # ============================================================ # ============================================================ -# 常量(与 TPC 侧 HandlesExprCall 保持一致) -# -# GLOBAL_FUNC_MAX / GLOBAL_DEFAULTS_MAX / MAX_CLOSURE_NAMES / -# MAX_FUNC_PTR_SIGS / ISINSTANCE_CLASS_MAX:唯一来源在 CallGenBase.vp -# (本文件是唯一消费方,经 CallGenBase. 取值,本地不再保留副本)。 +# 常量 # ============================================================ -_CEXPORT_MAX: t.CDefine = 256 -ASM_MAX_OPERANDS: t.CDefine = 16 -ASM_TEXT_BUF_SIZE: t.CDefine = 2048 -ASM_CONST_BUF_SIZE: t.CDefine = 512 -ASM_ARGS_BUF_SIZE: t.CDefine = 512 -ASM_LINE_BUF_SIZE: t.CDefine = 4096 -LLVMIR_MAX_OPS: t.CDefine = 16 -LLVMIR_TEMPLATE_BUF: t.CDefine = 512 +define _CEXPORT_MAX = 256 +define ASM_MAX_OPERANDS = 16 +define ASM_TEXT_BUF_SIZE = 2048 +define ASM_CONST_BUF_SIZE = 512 +define ASM_ARGS_BUF_SIZE = 512 +define ASM_LINE_BUF_SIZE = 4096 +define LLVMIR_MAX_OPS = 16 +define LLVMIR_TEMPLATE_BUF = 512 # ============================================================ # 全局函数表名索引(名 → 槽下标,开放寻址 | 线性探测) @@ -53,18 +43,17 @@ LLVMIR_TEMPLATE_BUF: t.CDefine = 512 # 槽存槽下标 + 1(0=空槽)。GlobalFuncs 在 PermPool 定长分配、只追加不重排、 # 从不 reset ⇒ 槽下标稳定;Built == GlobalFuncCount 才可信。 # ============================================================ -GLOBAL_FUNC_IDX_CAP: t.CDefine = 16384 +define GLOBAL_FUNC_IDX_CAP = 16384 # 索引哈希常量(32 位 FNV-1a,与 StructGenMixin 范式一致) -GFN_FNV_OFFSET: t.CDefine = 2166136261 -GFN_FNV_PRIME: t.CDefine = 16777619 -GFN_FNV_MASK: t.CDefine = 4294967295 +define GFN_FNV_OFFSET = 2166136261 +define GFN_FNV_PRIME = 16777619 +define GFN_FNV_MASK = 4294967295 def _gfn_hash(name: str) -> uint64: """函数名 → 64 位哈希(32 位 FNV-1a,逐字节到 NUL 结束)""" h: uint64 = uint64(GFN_FNV_OFFSET) - if name is None: - return h + if name is None: return h i: sizet = 0 while name[i] != '\0': h = (h ^ uint64(int(name[i]))) * uint64(GFN_FNV_PRIME) @@ -73,13 +62,13 @@ def _gfn_hash(name: str) -> uint64: return h -def _gfn_idx_slot(idx_base: sizet | t.CPtr, si: sizet) -> sizet | t.CPtr: +def _gfn_idx_slot(idx_base: sizet*, si: sizet) -> sizet*: """取索引第 si 个槽(8 字节,存槽下标+1;0=空槽)""" - return (sizet | t.CPtr)(uint64(idx_base) + uint64(si) * 8) + return (sizet*)(uint64(idx_base) + uint64(si) * 8) -def _gfn_idx_find(funcs: rawptr[GenTypes.FuncEntry], - idx_base: sizet | t.CPtr, cap: int, name: str) -> int: +def _gfn_idx_find(funcs: GenTypes.FuncEntry*, + idx_base: sizet*, cap: int, name: str) -> int: """在全局函数表名索引中探测 name,返回命中槽下标(>=0);未命中/不可用返回 -1""" if funcs is None or idx_base is None or cap <= 0 or name is None: return -1 @@ -89,22 +78,20 @@ def _gfn_idx_find(funcs: rawptr[GenTypes.FuncEntry], entry_size: sizet = GenTypes.FuncEntry.__sizeof__() i: int = 0 while i < cap: - slot: sizet | t.CPtr = _gfn_idx_slot(idx_base, si) + slot: sizet* = _gfn_idx_slot(idx_base, si) sv: sizet = slot[0] - if sv == 0: - return -1 + if sv == 0: return -1 se: int = int(sv) - 1 entry_addr: uint64 = uint64(funcs) + se * entry_size - entry: rawptr[GenTypes.FuncEntry] = rawptr[GenTypes.FuncEntry](entry_addr) + entry: GenTypes.FuncEntry* = GenTypes.FuncEntry*(entry_addr) if entry is not None and entry.Name is not None: - if string.strcmp(entry.Name, name) == 0: - return se + if string.strcmp(entry.Name, name) == 0: return se si = (si + 1) & mask i += 1 return -1 -def _gfn_idx_insert(idx_base: sizet | t.CPtr, cap: int, slot_index: int, name: str) -> int: +def _gfn_idx_insert(idx_base: sizet*, cap: int, slot_index: int, name: str) -> int: """把 (name → slot_index) 记入索引;0=成功 / 1=失败""" if idx_base is None or cap <= 0 or name is None: return 1 @@ -113,7 +100,7 @@ def _gfn_idx_insert(idx_base: sizet | t.CPtr, cap: int, slot_index: int, name: s si: sizet = sizet(h) & mask i: int = 0 while i < cap: - slot: sizet | t.CPtr = _gfn_idx_slot(idx_base, si) + slot: sizet* = _gfn_idx_slot(idx_base, si) if slot[0] == 0: slot[0] = sizet(slot_index + 1) return 0 @@ -125,8 +112,7 @@ def _gfn_idx_insert(idx_base: sizet | t.CPtr, cap: int, slot_index: int, name: s # ============================================================ # CallGenLeafKit - EH/isinstance/闭包/print/函数表 # ============================================================ -@t.NoVTable -class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin): +novirtual class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin): """EH 防护 + isinstance + 闭包 + print + 全局函数表(继承 CBuiltin)""" @@ -136,11 +122,11 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin): # EH 参数(%__eh_msg_out__/__eh_code_out__)由 translate_function_def/ # _translate_method 在含 raise 的函数签名末尾注入(main 除外)。 # ============================================================ - def _func_has_eh_params(self, func: rawptr[llvmlite.Function]) -> int: + def _func_has_eh_params(self, func: llvmlite.Function*) -> int: """返回 1=函数带 EH 输出参数 / 0=不带""" if func is None: return 0 - cur_p: rawptr[llvmlite.Param] = llvmlite.function_get_param_head(func) + cur_p: 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: @@ -167,27 +153,27 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin): # ============================================================ # ============================================================ - 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], + def _emit_eh_guarded_call(self, builder: llvmlite.IRBuilder*, + pool: memhub.MemBuddy*, + mod: llvmlite.LLVMModule*, + trans: HT.Translator*, + func: llvmlite.Function*, call_name: str, - head: rawptr[llvmlite.Value], + head: llvmlite.Value*, count: int, - ret_ty: rawptr[llvmlite.LLVMType], - is_variadic: int) -> rawptr[llvmlite.Value]: + ret_ty: llvmlite.LLVMType*, + is_variadic: int) -> 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) # ---- 1. 确定输出指针 ---- - i8_ty_g: rawptr[llvmlite.LLVMType] = llvmlite.Int8(pool) - i8_ptr_ty_g: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, i8_ty_g) - i32_ty_g: rawptr[llvmlite.LLVMType] = llvmlite.Int32(pool) + i8_ty_g: llvmlite.LLVMType* = llvmlite.Int8(pool) + i8_ptr_ty_g: llvmlite.LLVMType* = llvmlite.Ptr(pool, i8_ty_g) + i32_ty_g: 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: rawptr[llvmlite.Value] = None - code_ptr: rawptr[llvmlite.Value] = None + msg_ptr: llvmlite.Value* = None + code_ptr: 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 @@ -199,8 +185,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: rawptr[llvmlite.Value] = llvmlite.ConstNull(pool, i8_ptr_ty_g, "null") - zero_code_g: rawptr[llvmlite.Value] = llvmlite.const_int32(pool, 0) + null_msg_g: llvmlite.Value* = llvmlite.ConstNull(pool, i8_ptr_ty_g, "null") + zero_code_g: 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: @@ -211,38 +197,28 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin): if head is None: head = msg_ptr else: - tail_g: rawptr[llvmlite.Value] = head + tail_g: 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: 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: rawptr[llvmlite.Value] = llvmlite.build_load( - builder, i8_ptr_ty_g, msg_ptr) - if msg_val_g is None: - return result - 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 + result: llvmlite.Value* = llvmlite.build_call(builder, call_name, head, count, ret_ty, is_variadic) + cur_func_g: llvmlite.Function* = trans._cur_func + if cur_func_g is None or null_msg_g is None: return result + msg_val_g: 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* = llvmlite.build_icmp(builder, llvmlite.ICMP_NE, msg_val_g, null_msg_g) + if is_err_g is None: return result lc_g: int = trans._label_counter trans._label_counter = lc_g + 1 bb_buf_g: str = pool.alloc(64) - if bb_buf_g is None: - return result + if bb_buf_g is None: return result viperlib.snprintf(bb_buf_g, 64, "eh.err.%d", lc_g) - err_bb_g: rawptr[llvmlite.BasicBlock] = llvmlite.create_block( - pool, cur_func_g, bb_buf_g) + 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: 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 + 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 llvmlite.build_cond_br(builder, is_err_g, err_bb_g, ok_bb_g) # err 块 llvmlite.position_at_end(builder, err_bb_g) @@ -254,25 +230,21 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin): # 非 try:异常已写入本函数 out 参数(复用)或局部 alloca(吞掉), # 仅返回默认值,由调用方检测本函数 out 参数 if llvmlite.builder_cur_block_is_terminated(builder) == 0: - ret_ty_g2: rawptr[llvmlite.LLVMType] = llvmlite.function_get_ret_ty( - cur_func_g) + ret_ty_g2: llvmlite.LLVMType* = llvmlite.function_get_ret_ty(cur_func_g) if ret_ty_g2 is not None: match ret_ty_g2: case llvmlite.LLVMType.Void(): llvmlite.build_ret_void(builder) case llvmlite.LLVMType.Ptr(_pg): - nv_g: rawptr[llvmlite.Value] = llvmlite.ConstNull( - pool, ret_ty_g2, "null") + nv_g: 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: rawptr[llvmlite.Value] = llvmlite.ConstFloat( - pool, ret_ty_g2, 0.0) + zf_g: 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: rawptr[llvmlite.Value] = llvmlite.ConstZero( - pool, ret_ty_g2) + zv_g: llvmlite.Value* = llvmlite.ConstZero(pool, ret_ty_g2) if zv_g is not None: llvmlite.build_ret(builder, zv_g) # ok 块:继续 @@ -292,42 +264,40 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin): - def _translate_isinstance(self, pool: rawptr[memhub.MemBuddy], - builder: rawptr[llvmlite.IRBuilder], - mod: rawptr[llvmlite.LLVMModule], - obj_node: rawptr[ast.AST], - cls_node: rawptr[ast.AST], - trans: rawptr[HT.Translator] = None) -> rawptr[llvmlite.Value]: + def _translate_isinstance(self, pool: memhub.MemBuddy*, + builder: llvmlite.IRBuilder*, + mod: llvmlite.LLVMModule*, + obj_node: ast.AST*, + cls_node: ast.AST*, + trans: HT.Translator* = None) -> 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: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( - builder, pool, mod, obj_node, None, 0, trans) + obj_val: 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: rawptr[llvmlite.Value] = obj_val + obj_ptr: llvmlite.Value* = obj_val match obj_val.Ty: case llvmlite.LLVMType.Ptr(inner_ty): match inner_ty: case llvmlite.LLVMType.Ptr(_): - loaded: rawptr[llvmlite.Value] = llvmlite.build_load( - builder, inner_ty, obj_val) + loaded: llvmlite.Value* = llvmlite.build_load(builder, inner_ty, obj_val) if loaded is not None: obj_ptr = loaded case _: pass obj_is_ptr: int = self.Gen.ExprGenBase.is_ptr_type(obj_ptr.Ty) - 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) + i8_ty: llvmlite.LLVMType* = llvmlite.Int8(pool) + i8_ptr_ty: llvmlite.LLVMType* = llvmlite.Ptr(pool, i8_ty) + i8_ptr_ptr_ty: llvmlite.LLVMType* = llvmlite.Ptr(pool, i8_ptr_ty) # 对象 vtable 指针惰性读取(首个 CVTable 类比较时执行一次) - vtable_ptr: rawptr[llvmlite.Value] = None + vtable_ptr: llvmlite.Value* = None vtable_ready: int = 0 - res: rawptr[llvmlite.Value] = None - cls_names: sizet | t.CPtr = self._extract_isinstance_class_names(pool, cls_node) + res: llvmlite.Value* = None + cls_names: sizet* = self._extract_isinstance_class_names(pool, cls_node) if cls_names is None: # 类名提取失败:fail-fast,绝不返回 True 掩盖 self.Gen.TypeGenErr.fatal_error(cls_node, "isinstance() 参数类型推断失败", "TypeError") @@ -339,7 +309,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: rawptr[llvmlite.Value] = llvmlite.const_int(pool, 1, 1 if st > 0 else 0) + c1: llvmlite.Value* = llvmlite.const_int(pool, 1, 1 if st > 0 else 0) if res is None: res = c1 else: @@ -347,23 +317,20 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin): elif obj_is_ptr != 0: # CVTable → 运行时 vtable 比较(读对象头部 vtable 指针) if vtable_ready == 0: - vtable_slot: rawptr[llvmlite.Value] = llvmlite.build_bitcast( - builder, obj_ptr, i8_ptr_ptr_ty) + vtable_slot: 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) vtable_ready = 1 if vtable_ptr is not None: - subs: sizet | t.CPtr = self._collect_subclass_vtable_classes(pool, cn) + subs: sizet* = self._collect_subclass_vtable_classes(pool, cn) if subs is not None: k: int = 0 while subs[k] != 0: scn: str = (str | t.CPtr)(subs[k]) if scn is not None: - sub_i8: rawptr[llvmlite.Value] = self._make_vtable_ref_i8( - pool, builder, mod, scn, trans) + sub_i8: llvmlite.Value* = self._make_vtable_ref_i8(pool, builder, mod, scn, trans) if sub_i8 is not None: - cmp: rawptr[llvmlite.Value] = llvmlite.build_icmp( - builder, llvmlite.ICMP_EQ, vtable_ptr, sub_i8) + cmp: llvmlite.Value* = llvmlite.build_icmp(builder, llvmlite.ICMP_EQ, vtable_ptr, sub_i8) if cmp is not None: if res is None: res = cmp @@ -377,10 +344,10 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin): return res - def _extract_isinstance_class_names(self, pool: rawptr[memhub.MemBuddy], - node: rawptr[ast.AST]) -> sizet | t.CPtr: + def _extract_isinstance_class_names(self, pool: memhub.MemBuddy*, + node: ast.AST*) -> sizet*: """从 isinstance 第二参数提取类名数组(Name→id / Attribute→attr / Tuple→遍历)""" - arr: sizet | t.CPtr = pool.alloc(8 * 16) + arr: sizet* = pool.alloc(8 * 16) if arr is None: return None # 全数组清零:pool 分配内存非零时,未初始化槽位会被 while cls_names[ci]!=0 @@ -392,32 +359,32 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin): count: int = 0 k: int = node.kind() if k == ast.ASTKind.Name: - nm: rawptr[ast.Name] = rawptr[ast.Name](node) + nm: ast.Name* = ast.Name*(node) if nm.id is not None: arr[0] = sizet(nm.id) elif k == ast.ASTKind.Attribute: - at: rawptr[ast.Attribute] = rawptr[ast.Attribute](node) + at: ast.Attribute* = ast.Attribute*(node) if at.attr is not None: arr[0] = sizet(at.attr) elif k == ast.ASTKind.Tuple: - tp: rawptr[ast.Tuple] = rawptr[ast.Tuple](node) + tp: ast.Tuple* = ast.Tuple*(node) elts: list[ast.AST*]* = tp.elts if elts is not None: n: sizet = len(elts) for i in range(n): if count >= 15: break - elt: rawptr[ast.AST] = elts.get(i) + elt: ast.AST* = elts.get(i) if elt is None: continue ek: int = elt.kind() if ek == ast.ASTKind.Name: - enm: rawptr[ast.Name] = rawptr[ast.Name](elt) + enm: ast.Name* = ast.Name*(elt) if enm.id is not None: arr[count] = sizet(enm.id) count += 1 elif ek == ast.ASTKind.Attribute: - eat: rawptr[ast.Attribute] = rawptr[ast.Attribute](elt) + eat: ast.Attribute* = ast.Attribute*(elt) if eat.attr is not None: arr[count] = sizet(eat.attr) count += 1 @@ -425,14 +392,14 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin): return arr - def _collect_subclass_vtable_classes(self, pool: rawptr[memhub.MemBuddy], - class_name: str) -> sizet | t.CPtr: + def _collect_subclass_vtable_classes(self, pool: memhub.MemBuddy*, + class_name: str) -> sizet*: """反向 BFS 收集目标类及全部子类(含自身,仅 HasVTable==1),返回 0 结尾数组""" if class_name is None: return None - names: sizet | t.CPtr = pool.alloc(8 * (CallGenBase.ISINSTANCE_CLASS_MAX + 1)) - queue: sizet | t.CPtr = pool.alloc(8 * CallGenBase.ISINSTANCE_CLASS_MAX) - visited: sizet | t.CPtr = pool.alloc(8 * CallGenBase.ISINSTANCE_CLASS_MAX) + names: sizet* = pool.alloc(8 * (CallGenBase.ISINSTANCE_CLASS_MAX + 1)) + queue: sizet* = pool.alloc(8 * CallGenBase.ISINSTANCE_CLASS_MAX) + visited: sizet* = pool.alloc(8 * CallGenBase.ISINSTANCE_CLASS_MAX) if names is None or queue is None or visited is None: return None string.memset(names, 0, 8 * (CallGenBase.ISINSTANCE_CLASS_MAX + 1)) @@ -461,7 +428,7 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin): if vcount < CallGenBase.ISINSTANCE_CLASS_MAX: visited[vcount] = sizet(cur) vcount += 1 - centry: rawptr[GenTypes.StructEntry] = self.Gen.StructGen.find_struct(cur) + centry: GenTypes.StructEntry* = self.Gen.StructGen.find_struct(cur) if centry is not None and centry.HasVTable != 0: if outcount < CallGenBase.ISINSTANCE_CLASS_MAX: names[outcount] = sizet(cur) @@ -472,11 +439,11 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin): # 取条目,语义等价于"扫描全表收集子类",不可改为 find_struct。 scnt: int = self.Gen.StructGen.get_struct_count() for i in range(scnt): - e2: rawptr[GenTypes.StructEntry] = self.Gen.StructGen._get_struct_entry(i) + e2: 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: - parr: sizet | t.CPtr = (sizet | t.CPtr)(e2.ParentNames) + parr: sizet* = (sizet*)(e2.ParentNames) for j in range(e2.ParentCount): pa: sizet = parr[j] if pa != 0: @@ -490,16 +457,16 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin): return names - def _make_vtable_ref_i8(self, pool: rawptr[memhub.MemBuddy], - builder: rawptr[llvmlite.IRBuilder], - mod: rawptr[llvmlite.LLVMModule], + def _make_vtable_ref_i8(self, pool: memhub.MemBuddy*, + builder: llvmlite.IRBuilder*, + mod: llvmlite.LLVMModule*, class_name: str, - trans: rawptr[HT.Translator] = None) -> rawptr[llvmlite.Value]: + trans: HT.Translator* = None) -> llvmlite.Value*: """构造类 vtable 地址引用(i8*):本模块已定义直接引用,跨模块声明 external""" if class_name is None: return None - i8_ty: rawptr[llvmlite.LLVMType] = llvmlite.Int8(pool) - i8_ptr_ty: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, i8_ty) + i8_ty: llvmlite.LLVMType* = llvmlite.Int8(pool) + i8_ptr_ty: llvmlite.LLVMType* = llvmlite.Ptr(pool, i8_ty) buf: str = pool.alloc(256) if buf is None: return None @@ -518,27 +485,26 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin): return None # vtable 名含 sha1 点号前缀,一律 @"..." 引号形式 viperlib.snprintf(ref_name, 256, "@\"%s\"", mangled) - gv: rawptr[llvmlite.GlobalVariable] = self.Gen.ExprGenAttr.find_global_in_module(mod, mangled) - ref_ty: rawptr[llvmlite.LLVMType] = None + gv: llvmlite.GlobalVariable* = self.Gen.ExprGenAttr.find_global_in_module(mod, mangled) + ref_ty: 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: rawptr[llvmlite.GlobalVariable] = llvmlite.new_global_variable( - pool, mangled, i8_ptr_ty) + gv2: 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: rawptr[llvmlite.Value] = llvmlite.SSAValue(pool, ref_ty, ref_name) + ref: 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: rawptr[llvmlite.Value], + def _isinstance_compile_time(self, pool: memhub.MemBuddy*, + obj_ptr: 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: @@ -549,7 +515,7 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin): if sname is not None: if string.strcmp(sname, class_name) == 0: return 1 - mro: sizet | t.CPtr = self.Gen.StructGen.get_mro_chain(pool, sname) + mro: sizet* = self.Gen.StructGen.get_mro_chain(pool, sname) if mro is not None: k: int = 0 while mro[k] != 0: @@ -569,63 +535,60 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin): - def translate_closure_call(self, pool: rawptr[memhub.MemBuddy], - builder: rawptr[llvmlite.IRBuilder], - mod: rawptr[llvmlite.LLVMModule], - closure_alloca: rawptr[llvmlite.Value], + def translate_closure_call(self, pool: memhub.MemBuddy*, + builder: llvmlite.IRBuilder*, + mod: llvmlite.LLVMModule*, + closure_alloca: llvmlite.Value*, cargs: list[ast.AST*]*, can: sizet, - trans: rawptr[HT.Translator] = None) -> rawptr[llvmlite.Value]: + trans: HT.Translator* = None) -> llvmlite.Value*: """通过闭包指针间接调用(支持带参 lambda:i32(i8*, args...))""" if builder is None or closure_alloca is None: return None - i8_ty: rawptr[llvmlite.LLVMType] = llvmlite.Int8(pool) - i8_ptr_ty: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, i8_ty) - i32_ty: rawptr[llvmlite.LLVMType] = llvmlite.Int32(pool) + i8_ty: llvmlite.LLVMType* = llvmlite.Int8(pool) + i8_ptr_ty: llvmlite.LLVMType* = llvmlite.Ptr(pool, i8_ty) + i32_ty: llvmlite.LLVMType* = llvmlite.Int32(pool) # 1. 加载闭包指针 (i8*) - closure_ptr: rawptr[llvmlite.Value] = llvmlite.build_load(builder, i8_ptr_ty, closure_alloca) + closure_ptr: 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: rawptr[llvmlite.Value] = llvmlite.build_bitcast(builder, closure_ptr, llvmlite.Ptr(pool, i8_ptr_ty)) + fn_ptr_addr: llvmlite.Value* = llvmlite.build_bitcast(builder, closure_ptr, llvmlite.Ptr(pool, i8_ptr_ty)) if fn_ptr_addr is None: return None - fn_raw: rawptr[llvmlite.Value] = llvmlite.build_load(builder, i8_ptr_ty, fn_ptr_addr) + fn_raw: 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: rawptr[llvmlite.Value] = llvmlite.const_int32(pool, 8) - env_addr: rawptr[llvmlite.Value] = llvmlite.build_gep(builder, i8_ty, closure_ptr, eight_val) + eight_val: llvmlite.Value* = llvmlite.const_int32(pool, 8) + env_addr: llvmlite.Value* = llvmlite.build_gep(builder, i8_ty, closure_ptr, eight_val) if env_addr is None: return None - env_ptr: rawptr[llvmlite.Value] = llvmlite.build_load(builder, i8_ptr_ty, env_addr) + env_ptr: 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: 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 + arg_head: llvmlite.Value* = env_ptr + arg_tail: llvmlite.Value* = env_ptr + param_node: llvmlite.Function* = llvmlite.new_param_node(pool, i8_ptr_ty) + pn_tail: llvmlite.Function* = param_node if can > 0 and cargs is not None and trans is not None: for ai in range(can): - arg: rawptr[ast.AST] = cargs.get(ai) - if arg is None: - continue - 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 + arg: ast.AST* = cargs.get(ai) + if arg is None: continue + arg_val: 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 arg_val.Next = None if arg_tail is not None: arg_tail.Next = arg_val arg_tail = arg_val - pn_new: rawptr[llvmlite.Function] = llvmlite.new_param_node(pool, arg_val.Ty) + pn_new: llvmlite.Function* = llvmlite.new_param_node(pool, arg_val.Ty) if pn_new is not None: pn_tail.Next = pn_new pn_tail = pn_new @@ -634,9 +597,9 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin): env_ptr.Next = None # 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: rawptr[llvmlite.Value] = llvmlite.build_bitcast(builder, fn_raw, func_ptr_ty) + func_ty: llvmlite.LLVMType* = llvmlite.Func(pool, i32_ty, param_node, total_args) + func_ptr_ty: llvmlite.LLVMType* = llvmlite.Ptr(pool, func_ty) + fn_typed: llvmlite.Value* = llvmlite.build_bitcast(builder, fn_raw, func_ptr_ty) if fn_typed is None: return None @@ -644,16 +607,16 @@ 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: rawptr[llvmlite.Value]) -> int: + def _is_func_ptr_alloca(self, alloca: llvmlite.Value*) -> int: """判断 alloca 是否为函数指针变量(类型 Ptr(Ptr(i8))),1=是 / 0=否""" if alloca is None or alloca.Ty is None: return 0 if self.Gen.ExprGenBase.is_ptr_type(alloca.Ty) == 0: return 0 - pointee: rawptr[llvmlite.LLVMType] = alloca.Ty.Pointee + pointee: llvmlite.LLVMType* = alloca.Ty.Pointee if pointee is None or self.Gen.ExprGenBase.is_ptr_type(pointee) == 0: return 0 - inner: rawptr[llvmlite.LLVMType] = pointee.Pointee + inner: llvmlite.LLVMType* = pointee.Pointee if inner is None or self.Gen.ExprGenBase.is_ptr_type(inner) != 0: return 0 return 1 @@ -702,9 +665,9 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin): return 1 - def _func_ptr_sig_fatal(self, pool: rawptr[memhub.MemBuddy], - node: rawptr[ast.AST], name: str, - ret_ty: rawptr[llvmlite.LLVMType], + def _func_ptr_sig_fatal(self, pool: memhub.MemBuddy*, + node: ast.AST*, name: str, + ret_ty: llvmlite.LLVMType*, reason: str) -> None: """函数指针签名登记失败 → 编译期报错(文案含变量名/返回类型/上限/处置建议) @@ -734,12 +697,11 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin): name, ret_str, reason, cap, self.FuncptrCount) self.Gen.TypeGenErr.fatal_error(node, msg_buf, "TypeError") return - self.Gen.TypeGenErr.fatal_error( - node, "函数指针签名表登记失败(签名表已满或变量名冲突)", "TypeError") + self.Gen.TypeGenErr.fatal_error(node, "函数指针签名表登记失败(签名表已满或变量名冲突)", "TypeError") - def register_func_ptr_sig(self, pool: rawptr[memhub.MemBuddy], name: str, - ret_ty: rawptr[llvmlite.LLVMType], - node: rawptr[ast.AST] = None) -> int: + def register_func_ptr_sig(self, pool: memhub.MemBuddy*, name: str, + ret_ty: llvmlite.LLVMType*, + node: ast.AST* = None) -> int: """注册函数指针变量的返回类型签名,0=成功(含幂等命中)/ 1=失败(已报错终止) 表按**裸变量名**全局共享(PermPool,跨文件/跨阶段存活),同一变量可能被 @@ -762,13 +724,10 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin): for i in range(self.FuncptrCount): idx_hit: sizet = sizet(i) * 64 if string.strcmp(self.FuncptrNames + idx_hit, name) == 0: - prev_ret: rawptr[llvmlite.LLVMType] = ( - rawptr[llvmlite.LLVMType])(self.FuncptrRets[i]) - if prev_ret is not None \ - and self.Gen.AssignGen._stg_ty_equal(pool, prev_ret, ret_ty) != 0: + prev_ret: llvmlite.LLVMType* = (llvmlite.LLVMType*)(self.FuncptrRets[i]) + if prev_ret is not None and self.Gen.AssignGen._stg_ty_equal(pool, prev_ret, ret_ty) != 0: return 0 - self._func_ptr_sig_fatal(pool, node, name, ret_ty, - "该名字已按另一种返回类型登记过") + self._func_ptr_sig_fatal(pool, node, name, ret_ty, "该名字已按另一种返回类型登记过") return 1 if self.FuncptrCount >= CallGenBase.MAX_FUNC_PTR_SIGS: self._func_ptr_sig_fatal(pool, node, name, ret_ty, "签名表已满") @@ -778,8 +737,7 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin): string.strncpy(self.FuncptrNames + idx, name, 63) # ret_ty 是调用方 pool 分配的裸 LLVMType,1a 每文件 reset 后悬空; # 深拷贝到 perm_pool(lookup_func_ptr_ret 跨文件读取) - ret_copy_fp: rawptr[llvmlite.LLVMType] = llvmlite.DeepCopyType( - CompilerFactory.factory.PermPool, ret_ty) + ret_copy_fp: llvmlite.LLVMType* = llvmlite.DeepCopyType(CompilerFactory.factory.PermPool, ret_ty) if ret_copy_fp is not None: self.FuncptrRets[self.FuncptrCount] = uint64(ret_copy_fp) else: @@ -788,47 +746,45 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin): return 0 - def lookup_func_ptr_ret(self, name: str) -> rawptr[llvmlite.LLVMType]: + def lookup_func_ptr_ret(self, name: str) -> llvmlite.LLVMType*: """查函数指针变量的返回类型,None=未注册(调用时默认 i32)""" if name is None or self.FuncptrNames is None: return None for i in range(self.FuncptrCount): idx: sizet = sizet(i) * 64 if string.strcmp(self.FuncptrNames + idx, name) == 0: - return (rawptr[llvmlite.LLVMType])(self.FuncptrRets[i]) + return (llvmlite.LLVMType*)(self.FuncptrRets[i]) return None - def _translate_func_ptr_call(self, pool: rawptr[memhub.MemBuddy], - builder: rawptr[llvmlite.IRBuilder], - mod: rawptr[llvmlite.LLVMModule], - fp_alloca: rawptr[llvmlite.Value], + def _translate_func_ptr_call(self, pool: memhub.MemBuddy*, + builder: llvmlite.IRBuilder*, + mod: llvmlite.LLVMModule*, + fp_alloca: llvmlite.Value*, func_name: str, cargs: list[ast.AST*]*, can: sizet, - trans: rawptr[HT.Translator]) -> rawptr[llvmlite.Value]: + trans: HT.Translator*) -> llvmlite.Value*: """函数指针变量间接调用,返回结果 Value""" if builder is None or fp_alloca is None: return None - i8_ty: rawptr[llvmlite.LLVMType] = llvmlite.Int8(pool) - i8_ptr_ty: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, i8_ty) - i32_ty: rawptr[llvmlite.LLVMType] = llvmlite.Int32(pool) + i8_ty: llvmlite.LLVMType* = llvmlite.Int8(pool) + i8_ptr_ty: llvmlite.LLVMType* = llvmlite.Ptr(pool, i8_ty) + i32_ty: llvmlite.LLVMType* = llvmlite.Int32(pool) # 1. load 函数地址 (i8*) - fn_i8: rawptr[llvmlite.Value] = llvmlite.build_load(builder, i8_ptr_ty, fp_alloca) - if fn_i8 is None: - return None + fn_i8: llvmlite.Value* = llvmlite.build_load(builder, i8_ptr_ty, fp_alloca) + if fn_i8 is None: return None # 2. 翻译实参并链接为 Value 链表 - head: rawptr[llvmlite.Value] = None - tail: rawptr[llvmlite.Value] = None + head: llvmlite.Value* = None + tail: llvmlite.Value* = None arg_count: int = 0 ai: sizet for ai in range(can): - arg: rawptr[ast.AST] = cargs.get(ai) + arg: ast.AST* = cargs.get(ai) if arg is not None: - arg_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( - builder, pool, mod, arg, None, 0, trans) + arg_val: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, mod, arg, None, 0, trans) if arg_val is not None: arg_val.Next = None if head is None: @@ -839,21 +795,18 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin): arg_count += 1 # 3. 按实参类型 + 注册的返回类型构造签名(未注册即 t.Callable 注解缺失,fail-fast) - ret_ty: rawptr[llvmlite.LLVMType] = self.lookup_func_ptr_ret(func_name) + ret_ty: llvmlite.LLVMType* = self.lookup_func_ptr_ret(func_name) if ret_ty is None: - self.Gen.TypeGenErr.fatal_error( - None, - f"函数指针变量 '{func_name}' 的返回类型未注册(t.Callable 注解缺失)", - "TypeError") + self.Gen.TypeGenErr.fatal_error(None, f"函数指针变量 '{func_name}' 的返回类型未注册(t.Callable 注解缺失)", "TypeError") ret_ty = i32_ty - fp_first: rawptr[llvmlite.Function] = None - fp_prev: rawptr[llvmlite.Function] = None - cur_v: rawptr[llvmlite.Value] = head + fp_first: llvmlite.Function* = None + fp_prev: llvmlite.Function* = None + cur_v: llvmlite.Value* = head for pi in range(arg_count): if cur_v is None: break - cur_ty: rawptr[llvmlite.LLVMType] = llvmlite.value_get_ty(cur_v) - pn2: rawptr[llvmlite.Function] = llvmlite.new_param_node(pool, cur_ty) + cur_ty: llvmlite.LLVMType* = llvmlite.value_get_ty(cur_v) + pn2: llvmlite.Function* = llvmlite.new_param_node(pool, cur_ty) if pn2 is not None: if fp_first is None: fp_first = pn2 @@ -862,59 +815,52 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin): fp_prev = pn2 cur_v = llvmlite.value_get_next(cur_v) - func_ty: rawptr[llvmlite.LLVMType] = llvmlite.Func(pool, ret_ty, fp_first, arg_count) + func_ty: llvmlite.LLVMType* = llvmlite.Func(pool, ret_ty, fp_first, arg_count) if func_ty is None: return None - func_ptr_ty: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, func_ty) + func_ptr_ty: llvmlite.LLVMType* = llvmlite.Ptr(pool, func_ty) # 4. bitcast i8* → 函数指针类型,间接调用 - fn_typed: rawptr[llvmlite.Value] = llvmlite.build_bitcast(builder, fn_i8, func_ptr_ty) + fn_typed: 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: rawptr[llvmlite.IRBuilder], - mod: rawptr[llvmlite.LLVMModule], - cl: rawptr[ast.Call], - trans: rawptr[HT.Translator] = None) -> None: + def translate_printf_call(self, pool: memhub.MemBuddy*, + builder: llvmlite.IRBuilder*, + mod: llvmlite.LLVMModule*, + cl: ast.Call*, + trans: HT.Translator* = None) -> None: """翻译 printf 调用(特殊处理格式字符串)""" cargs: list[ast.AST*]* = cl.args - if cargs is None: - return + if cargs is None: return can: sizet = len(cargs) - if can == 0: - return + if can == 0: return - arg0: rawptr[ast.AST] = cargs.get(0) - if arg0 is None: - return + arg0: ast.AST* = cargs.get(0) + if arg0 is None: return fmt_str: str = None arg0_kind: int = arg0.kind() if arg0_kind == ast.ASTKind.Constant: - cn: rawptr[ast.Constant] = rawptr[ast.Constant](arg0) + cn: ast.Constant* = ast.Constant*(arg0) if cn.const_kind == ast.CONST_STR: fmt_str = cn.str_val - if fmt_str is None: - return + if fmt_str is None: return - fmt_ptr: rawptr[llvmlite.Value] = self.Gen.ExprGenConst.create_global_string( - builder, pool, mod, fmt_str, trans) - if fmt_ptr is None: - return + fmt_ptr: llvmlite.Value* = self.Gen.ExprGenConst.create_global_string(builder, pool, mod, fmt_str, trans) + if fmt_ptr is None: return - i32_ty: rawptr[llvmlite.LLVMType] = llvmlite.Int32(pool) + i32_ty: llvmlite.LLVMType* = llvmlite.Int32(pool) # 翻译额外参数并链接 - prev: rawptr[llvmlite.Value] = fmt_ptr + prev: llvmlite.Value* = fmt_ptr for ai in range(1, can): - arg: rawptr[ast.AST] = cargs.get(ai) + arg: ast.AST* = cargs.get(ai) if arg is not None: - arg_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( - builder, pool, mod, arg, None, 0, trans) + arg_val: 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 变参函数要求) arg_bits: int = self.Gen.ExprGenBase.get_llvm_type_bits(arg_val.Ty) @@ -923,7 +869,7 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin): # C ABI float promotion: float → double(printf 变参函数要求) arg_fbits: int = self.Gen.ExprGenBase.get_llvm_float_bits(arg_val.Ty) if arg_fbits != 0 and arg_fbits < 64: - double_ty: rawptr[llvmlite.LLVMType] = llvmlite.Double(pool) + double_ty: llvmlite.LLVMType* = llvmlite.Double(pool) arg_val = self.Gen.ExprGenBase.coerce_to_type(builder, arg_val, double_ty, arg) arg_val.Next = None prev.Next = arg_val @@ -935,11 +881,11 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin): llvmlite.build_call(builder, "printf", fmt_ptr, can, i32_ty, 1) - def translate_print_call(self, pool: rawptr[memhub.MemBuddy], - builder: rawptr[llvmlite.IRBuilder], - mod: rawptr[llvmlite.LLVMModule], - cl: rawptr[ast.Call], - trans: rawptr[HT.Translator] = None) -> None: + def translate_print_call(self, pool: memhub.MemBuddy*, + builder: llvmlite.IRBuilder*, + mod: llvmlite.LLVMModule*, + cl: ast.Call*, + trans: HT.Translator* = None) -> None: """翻译 print 调用(类型感知格式化 + 默认换行)""" cargs: list[ast.AST*]* = cl.args if cargs is None: @@ -951,21 +897,19 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin): return fmt_buf[0] = '\0' - i32_ty: rawptr[llvmlite.LLVMType] = llvmlite.Int32(pool) - i64_ty: rawptr[llvmlite.LLVMType] = llvmlite.Int64(pool) - dbl_ty: rawptr[llvmlite.LLVMType] = llvmlite.Double(pool) + i32_ty: llvmlite.LLVMType* = llvmlite.Int32(pool) + i64_ty: llvmlite.LLVMType* = llvmlite.Int64(pool) + dbl_ty: llvmlite.LLVMType* = llvmlite.Double(pool) can: sizet = len(cargs) - arg_head: rawptr[llvmlite.Value] = None - arg_tail: rawptr[llvmlite.Value] = None + arg_head: llvmlite.Value* = None + arg_tail: 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: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( - builder, pool, mod, arg, None, 0, trans) + arg: ast.AST* = cargs.get(ai) + if arg is None: continue + arg_val: 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 参数翻译失败必须终止编译,绝不在格式串写 # 误导为数据问题而非编译器 bug。 @@ -977,16 +921,14 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin): # translate_value 会 load 出数组值([N x T]),print 无法格式化; # 按数组退化语义取数组 alloca 地址——字符数组 → %s(打印字符串内容), # 其他元素类型 → 0x%llx(打印数组地址)。 - array_ptr: rawptr[llvmlite.Value] = None + array_ptr: 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) + anm: ast.Name* = ast.Name*(arg) if anm.id is not None: - 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: - arr_pointee: rawptr[llvmlite.LLVMType] = arr_alloca.Ty.Pointee + arr_alloca: 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: + arr_pointee: llvmlite.LLVMType* = arr_alloca.Ty.Pointee if arr_pointee is not None: match arr_pointee: case llvmlite.LLVMType.Array(arr_et, arr_n): @@ -1003,8 +945,7 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin): if array_ptr is not None: # 数组退化:字符数组 → %s(bitcast [N x i8]* 到 i8*);其他 → 0x%llx if array_elem_bits == 8: - i8_ptr_ty: rawptr[llvmlite.LLVMType] = llvmlite.Ptr( - pool, llvmlite.Int8(pool)) + i8_ptr_ty: llvmlite.LLVMType* = llvmlite.Ptr(pool, llvmlite.Int8(pool)) token = "%s" arg_val = llvmlite.build_bitcast(builder, array_ptr, i8_ptr_ty) else: @@ -1012,7 +953,7 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin): arg_val = llvmlite.build_ptrtoint(builder, array_ptr, i64_ty) elif self.Gen.ExprGenBase.is_ptr_type(arg_val.Ty) != 0: # i8*(str/bytes)→ %s;其他指针 → 0x%llx - pointee: rawptr[llvmlite.LLVMType] = arg_val.Ty.Pointee + pointee: llvmlite.LLVMType* = arg_val.Ty.Pointee if pointee is not None and self.Gen.ExprGenBase.get_llvm_type_bits(pointee) == 8: token = "%s" else: @@ -1058,30 +999,27 @@ 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: rawptr[llvmlite.Value] = self.Gen.ExprGenConst.create_global_string( - builder, pool, mod, fmt_buf, trans) + fmt_ptr: llvmlite.Value* = self.Gen.ExprGenConst.create_global_string(builder, pool, mod, fmt_buf, trans) stdlib.free(fmt_buf) - if fmt_ptr is None: - return + if fmt_ptr is None: return fmt_ptr.Next = arg_head # is_variadic=1: 带显式函数类型签名(C ABI 变参调用) llvmlite.build_call(builder, "printf", fmt_ptr, arg_count, i32_ty, 1) - def init_func_table(self, pool: rawptr[memhub.MemBuddy], - max_count: int) -> rawptr[GenTypes.FuncEntry]: + def init_func_table(self, pool: memhub.MemBuddy*, max_count: int) -> GenTypes.FuncEntry*: """分配并清零函数表数组""" size: sizet = max_count * GenTypes.FuncEntry.__sizeof__() - funcs_ptr: rawptr[GenTypes.FuncEntry] = pool.alloc(size) + funcs_ptr: GenTypes.FuncEntry* = pool.alloc(size) if funcs_ptr is not None: string.memset(funcs_ptr, 0, size) return funcs_ptr - def find_func_in_table(self, funcs: rawptr[GenTypes.FuncEntry], + def find_func_in_table(self, funcs: GenTypes.FuncEntry*, func_count: int, name: str, - owner_sha1: str = None) -> rawptr[llvmlite.Function]: + owner_sha1: str = None) -> llvmlite.Function*: """在函数表中按名称查找,返回 Function 指针或 None owner_sha1: 当前模块 SHA1。非 None 时"本模块函数优先"——表里同名条目 @@ -1107,7 +1045,7 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin): fi_t: int = _gfn_idx_find(self.GlobalFuncs, self.GlobalFuncNameIdx, self.GlobalFuncNameIdxCap, name) if fi_t >= 0: - fe_t: rawptr[GenTypes.FuncEntry] = rawptr[GenTypes.FuncEntry]((uint64(self.GlobalFuncs) + fi_t * entry_size)) + fe_t: GenTypes.FuncEntry* = GenTypes.FuncEntry*((uint64(self.GlobalFuncs) + fi_t * entry_size)) if fe_t is not None: return fe_t.Func # 索引可信(Built==GlobalFuncCount | 查询名非空)⇒ 未命中即"确无同名条目": @@ -1116,10 +1054,10 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin): # "首个同名条目的 Func",未命中必为 None。索引不可信时回退下方线性扫描。 return None # 单遍扫描(合并原 owner 优先遍 + 通用遍,语义完全一致但省一半遍历):扫描中同时记录"首个同裸名条目"作通用兜底;一旦发现本模块条目(mangled 名以 "{owner_sha1}." 开头,16 位前缀 + '.')立即返回 - fallback_entry: rawptr[GenTypes.FuncEntry] = None + fallback_entry: GenTypes.FuncEntry* = None for i in range(func_count): entry_addr: uint64 = uint64(funcs) + i * entry_size - entry: rawptr[GenTypes.FuncEntry] = rawptr[GenTypes.FuncEntry](entry_addr) + entry: GenTypes.FuncEntry* = GenTypes.FuncEntry*(entry_addr) if entry is not None and entry.Name is not None: # 快速路径:同名要求首字符相等(strcmp 判等蕴含首字符相等), # 首字符不同者直接跳过 strcmp,避免全表每槽一次函数调用。 @@ -1136,15 +1074,15 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin): return None - def add_func_to_table(self, funcs: rawptr[GenTypes.FuncEntry], + def add_func_to_table(self, funcs: GenTypes.FuncEntry*, func_count: int, name: str, - func: rawptr[llvmlite.Function], + func: llvmlite.Function*, max_count: int, defaults: t.CPtr = None, default_count: int = 0, param_count: int = 0, - pool: rawptr[memhub.MemBuddy] = None, + pool: memhub.MemBuddy* = None, def_sha1: str = None) -> int: """添加函数到函数表,返回 0 成功 @@ -1160,7 +1098,7 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin): return 1 entry_size: sizet = GenTypes.FuncEntry.__sizeof__() entry_addr: uint64 = uint64(funcs) + func_count * entry_size - entry: rawptr[GenTypes.FuncEntry] = rawptr[GenTypes.FuncEntry](entry_addr) + entry: GenTypes.FuncEntry* = GenTypes.FuncEntry*(entry_addr) entry.Name = name entry.Func = func entry.Defaults = defaults @@ -1189,7 +1127,7 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin): # 名索引(PermPool,与表同生命周期)。分配失败 → 保持不可信(Built=-1), # 查找/去重一律回退线性扫描(语义完全一致,不因此使初始化失败)。 idx_bytes: sizet = sizet(GLOBAL_FUNC_IDX_CAP) * 8 - idx_buf: sizet | t.CPtr = CompilerFactory.factory.PermPool.alloc(idx_bytes) + idx_buf: sizet* = CompilerFactory.factory.PermPool.alloc(idx_bytes) if idx_buf is None: self.GlobalFuncNameIdx = None self.GlobalFuncNameIdxCap = 0 @@ -1202,8 +1140,8 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin): return 1 - def _register_global_func(self, name: str, func: rawptr[llvmlite.Function], - pool: rawptr[memhub.MemBuddy] = None) -> int: + def _register_global_func(self, name: str, func: llvmlite.Function*, + pool: memhub.MemBuddy* = None) -> int: """注册函数到全局表(已存在则跳过),返回 0 成功 直接操作全局表,不调用 add_func_to_table,避免递归。 @@ -1220,7 +1158,7 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin): # 直接写入全局表(不调用 add_func_to_table,避免递归) entry_size: sizet = GenTypes.FuncEntry.__sizeof__() entry_addr: uint64 = uint64(self.GlobalFuncs) + self.GlobalFuncCount * entry_size - entry: rawptr[GenTypes.FuncEntry] = rawptr[GenTypes.FuncEntry](entry_addr) + entry: GenTypes.FuncEntry* = GenTypes.FuncEntry*(entry_addr) # Name 深拷贝到 stdlib 区:全局表跨文件永久存活,pool 内名字会被 1b 每文件 # reset_to(mark1) 回收导致悬空(vtable 生成 find_func_global 后 strcmp 崩溃) name_len: sizet = string.strlen(name) @@ -1247,7 +1185,7 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin): def update_global_func_spec(self, name: str, - func: rawptr[llvmlite.Function]) -> int: + func: llvmlite.Function*) -> int: """更新全局函数表的 Spec(在函数参数全部添加完成后调用) 调用时机:add_func_to_table 注册后、llvmlite.add_param 全部执行完。 @@ -1256,7 +1194,7 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin): """ if name is None or func is None: return 1 - entry: rawptr[GenTypes.FuncEntry] = self.find_func_entry_global(name) + entry: GenTypes.FuncEntry* = self.find_func_entry_global(name) if entry is None: return 1 entry.Spec = self._build_func_spec(func) @@ -1264,72 +1202,60 @@ 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]) -> rawptr[TSpec.TypeSpec]: + def _build_func_spec(self, func: llvmlite.Function*) -> TSpec.TypeSpec*: """由函数对象构造整签名 TypeSpec,失败返回 None""" - if func is None: - return None - arena: rawptr[TSpec.TypeSpecArena] = self.Gen.TypeGenBase.ensure_spec_arena() - if arena is None: - return None - ret_s: rawptr[TSpec.TypeSpec] = TSpec.SpecFromLLVMType( - arena, llvmlite.function_get_ret_ty(func)) - if ret_s is None: - return None + if func is None: return None + arena: TSpec.TypeSpecArena* = self.Gen.TypeGenBase.ensure_spec_arena() + if arena is None: return None + ret_s: TSpec.TypeSpec* = TSpec.SpecFromLLVMType(arena, llvmlite.function_get_ret_ty(func)) + if ret_s is None: return None # 第一遍:计数 cnt: int = 0 - cur: rawptr[llvmlite.Param] = llvmlite.function_get_param_head(func) + cur: llvmlite.Param* = llvmlite.function_get_param_head(func) while cur is not None and cnt < 256: cnt += 1 cur = llvmlite.param_get_next(cur) # 第二遍:逐个构造并写入连续参数数组 - params_arr: sizet | t.CPtr = None + params_arr: sizet* = None if cnt > 0: params_arr = CompilerFactory.factory.PermPool.alloc(8 * cnt) - if params_arr is None: - return None + if params_arr is None: return None cur = llvmlite.function_get_param_head(func) i: int = 0 while cur is not None and i < cnt: - ps: rawptr[TSpec.TypeSpec] = TSpec.SpecFromLLVMType( - arena, llvmlite.param_get_ty(cur)) - if ps is None: - return None - slot: sizet | t.CPtr = (sizet | t.CPtr)(uint64(params_arr) + uint64(i * 8)) - if slot is None: - return None + ps: TSpec.TypeSpec* = TSpec.SpecFromLLVMType(arena, llvmlite.param_get_ty(cur)) + if ps is None: return None + slot: sizet* = (sizet*)(uint64(params_arr) + uint64(i * 8)) + if slot is None: return None slot[0] = sizet(ps) cur = llvmlite.param_get_next(cur) i += 1 return TSpec.NewTypeFunc(arena, ret_s, params_arr, cnt, func.IsVarArg) - def find_func_global(self, name: str) -> rawptr[llvmlite.Function]: + def find_func_global(self, name: str) -> llvmlite.Function*: """在全局函数表中按名称查找,返回 Function 指针或 None""" - if name is None or self.GlobalFuncs is None: - return None + if name is None or self.GlobalFuncs is None: return None return self.find_func_in_table(self.GlobalFuncs, self.GlobalFuncCount, name) - def find_func_entry_global(self, name: str) -> rawptr[GenTypes.FuncEntry]: + def find_func_entry_global(self, name: str) -> GenTypes.FuncEntry*: """在全局函数表中按名称查找,返回完整 FuncEntry(含 Spec)或 None""" - if name is None or self.GlobalFuncs is None: - return None + if name is None or self.GlobalFuncs is None: return None entry_size: sizet = GenTypes.FuncEntry.__sizeof__() # 名索引快速路径:可信(Built==Count)时一次探测返回首个同名条目 # (= 原线性扫描首个命中);可信且查询名非空时未命中即"确无同名条目" # (全局表只经 _register_global_func 追加并同步索引,名注册后不再改写), # 直接返回 None;索引不可信 → 回退下方原线性扫描。 - if self.GlobalFuncNameIdxBuilt == self.GlobalFuncCount \ - and self.GlobalFuncNameIdx is not None and self.GlobalFuncNameIdxCap > 0: - gi: int = _gfn_idx_find(self.GlobalFuncs, self.GlobalFuncNameIdx, - self.GlobalFuncNameIdxCap, name) + if self.GlobalFuncNameIdxBuilt == self.GlobalFuncCount and self.GlobalFuncNameIdx is not None and self.GlobalFuncNameIdxCap > 0: + gi: int = _gfn_idx_find(self.GlobalFuncs, self.GlobalFuncNameIdx, self.GlobalFuncNameIdxCap, name) if gi >= 0: - entry_g: rawptr[GenTypes.FuncEntry] = rawptr[GenTypes.FuncEntry](uint64(self.GlobalFuncs) + gi * entry_size) + entry_g: GenTypes.FuncEntry* = GenTypes.FuncEntry*(uint64(self.GlobalFuncs) + gi * entry_size) return entry_g return None for i in range(self.GlobalFuncCount): entry_addr: uint64 = uint64(self.GlobalFuncs) + i * entry_size - entry: rawptr[GenTypes.FuncEntry] = rawptr[GenTypes.FuncEntry](entry_addr) + entry: GenTypes.FuncEntry* = GenTypes.FuncEntry*(entry_addr) if entry.Name is not None: # 快速路径:同名要求首字符相等(strcmp 判等蕴含首字符相等), # 首字符不同者直接跳过 strcmp。 @@ -1340,12 +1266,10 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin): def _init_global_defaults_table(self) -> int: """初始化全局默认参数表""" - if self.GlobalDefaults is not None: - return 1 + if self.GlobalDefaults is not None: return 1 size: sizet = CallGenBase.GLOBAL_DEFAULTS_MAX * GenTypes.FuncDefaultsEntry.__sizeof__() self.GlobalDefaults = CompilerFactory.factory.PermPool.alloc(size) - if self.GlobalDefaults is None: - return 0 + if self.GlobalDefaults is None: return 0 string.memset(self.GlobalDefaults, 0, size) self.GlobalDefaultsCount = 0 return 1 @@ -1368,10 +1292,8 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin): 而被补 2 个 i32 0(N17 真因;模块函数表的"按定义模块限定查找"救不了这条 全局表路径,因为该处 found_func 仍为 None、交叉校验被整体跳过)。 """ - if name is None or defaults is None: - return 1 - if self._init_global_defaults_table() == 0: - return 1 + if name is None or defaults is None: return 1 + if self._init_global_defaults_table() == 0: return 1 # 限定键 = **定义该函数的模块 SHA1**:同一函数名在不同模块各存一条,查询时 # 按「名 + 定义模块」精确匹配,消除跨模块同名串味。def_sha1 由依赖注入 # 路径显式传入被依赖模块自身 sha1;非注入路径(本模块真实定义)取 @@ -1380,18 +1302,15 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin): if cur_sha is None and self.Gen is not None and self.Gen.TypeGenBase is not None: cur_sha = self.Gen.TypeGenBase.CurrentModuleSha1 # 同模块同名已存在则跳过 - if self.find_func_defaults(name, cur_sha) is not None: - return 0 - if self.GlobalDefaultsCount >= CallGenBase.GLOBAL_DEFAULTS_MAX: - return 1 + if self.find_func_defaults(name, cur_sha) is not None: return 0 + if self.GlobalDefaultsCount >= CallGenBase.GLOBAL_DEFAULTS_MAX: return 1 entry_size: sizet = GenTypes.FuncDefaultsEntry.__sizeof__() entry_addr: uint64 = uint64(self.GlobalDefaults) + self.GlobalDefaultsCount * entry_size - entry: rawptr[GenTypes.FuncDefaultsEntry] = rawptr[GenTypes.FuncDefaultsEntry](entry_addr) + entry: GenTypes.FuncDefaultsEntry* = GenTypes.FuncDefaultsEntry*(entry_addr) # Name 深拷贝到 stdlib(全局表跨文件永久存活) nm_len: sizet = string.strlen(name) nm_copy: str = CompilerFactory.factory.PermPool.alloc(nm_len + 1) - if nm_copy is None: - return 1 + if nm_copy is None: return 1 string.strcpy(nm_copy, name) entry.Name = nm_copy entry.ModuleSha1 = None @@ -1415,7 +1334,7 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin): if default_count > 0: kinds: int | t.CPtr = CompilerFactory.factory.PermPool.alloc(default_count * 4) ints: int64 | t.CPtr = CompilerFactory.factory.PermPool.alloc(default_count * 8) - strs: sizet | t.CPtr = CompilerFactory.factory.PermPool.alloc(default_count * 8) + strs: sizet* = CompilerFactory.factory.PermPool.alloc(default_count * 8) if kinds is not None and ints is not None and strs is not None: string.memset(kinds, 0, default_count * 4) string.memset(ints, 0, default_count * 8) @@ -1423,9 +1342,9 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin): dl: list[ast.AST*]* = (list[ast.AST*] | t.CPtr)(uint64(defaults)) di: int for di in range(default_count): - dnode: rawptr[ast.AST] = dl.get(di) + dnode: ast.AST* = dl.get(di) if dnode is not None and dnode.kind() == ast.ASTKind.Constant: - dcn: rawptr[ast.Constant] = rawptr[ast.Constant](dnode) + dcn: ast.Constant* = ast.Constant*(dnode) kinds[di] = dcn.const_kind ints[di] = dcn.int_val if dcn.const_kind == ast.CONST_STR and dcn.str_val is not None: @@ -1440,7 +1359,7 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin): # → "跨模块默认参数无法重建"(FileIoTest File.__init__ 根因)。 # 仅支持已注册的整型 CDefine;未注册保持 kinds=0(重建时 # 仍 fail-fast,绝不静默回退)。 - dnm: rawptr[ast.Name] = rawptr[ast.Name](dnode) + dnm: ast.Name* = ast.Name*(dnode) if dnm.id is not None: cdef_v: int = self.Gen.TypeGenCDef.lookup_cdefine_constant(dnm.id) if self.Gen.TypeGenCDef.is_cdefine_found() != 0: @@ -1453,9 +1372,9 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin): # 重建(快照缺失,默认值需为简单常量)"(AppGui.top_index # 的 ex3 = -1 根因)。只对"操作数是整型 Constant"求值, # 其它(浮点取负 / 取负变量)保持 kinds=0 → 重建时 fail-fast。 - du: rawptr[ast.UnaryOp] = rawptr[ast.UnaryOp](dnode) + du: ast.UnaryOp* = ast.UnaryOp*(dnode) if du.operand is not None and du.operand.kind() == ast.ASTKind.Constant: - doc: rawptr[ast.Constant] = rawptr[ast.Constant](du.operand) + doc: ast.Constant* = ast.Constant*(du.operand) if doc.const_kind == ast.CONST_INT: if du.op == ast.OpKind.USub: kinds[di] = ast.CONST_INT @@ -1474,7 +1393,7 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin): def find_func_defaults(self, name: str, - module_sha1: str = None) -> rawptr[GenTypes.FuncDefaultsEntry]: + module_sha1: str = None) -> GenTypes.FuncDefaultsEntry*: """按函数名(可选按定义模块 SHA1)查找默认参数信息,返回 FuncDefaultsEntry 或 None module_sha1 非 None 时要求条目定义模块完全一致(限定名匹配,消除跨模块同名串味); @@ -1485,7 +1404,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: rawptr[GenTypes.FuncDefaultsEntry] = rawptr[GenTypes.FuncDefaultsEntry](entry_addr) + entry: GenTypes.FuncDefaultsEntry* = GenTypes.FuncDefaultsEntry*(entry_addr) if entry.Name is None: continue if string.strcmp(entry.Name, name) != 0: @@ -1499,12 +1418,12 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin): return None - def _build_const_from_snapshot(self, pool: rawptr[memhub.MemBuddy], - mod: rawptr[llvmlite.LLVMModule], - gd_entry: rawptr[GenTypes.FuncDefaultsEntry], + def _build_const_from_snapshot(self, pool: memhub.MemBuddy*, + mod: llvmlite.LLVMModule*, + gd_entry: GenTypes.FuncDefaultsEntry*, di: int, - trans: rawptr[HT.Translator], - builder: rawptr[llvmlite.IRBuilder]) -> rawptr[llvmlite.Value]: + trans: HT.Translator*, + builder: llvmlite.IRBuilder*) -> llvmlite.Value*: """从快照重建第 di 个默认值常量 IR""" if gd_entry is None or gd_entry.ConstKinds is None or gd_entry.ConstInts is None: return None @@ -1521,8 +1440,8 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin): return llvmlite.const_int32(pool, 1) return llvmlite.const_int32(pool, 0) elif kind == ast.CONST_NONE: - i8_ty: rawptr[llvmlite.LLVMType] = llvmlite.Int8(pool) - i8_ptr_ty: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, i8_ty) + i8_ty: llvmlite.LLVMType* = llvmlite.Int8(pool) + i8_ptr_ty: llvmlite.LLVMType* = llvmlite.Ptr(pool, i8_ty) return llvmlite.ConstNull(pool, i8_ptr_ty, "null") elif kind == ast.CONST_STR: if gd_entry.ConstStrs is not None and gd_entry.ConstStrs[di] != 0: @@ -1532,26 +1451,26 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin): return None - def find_func_entry_in_table(self, funcs: rawptr[GenTypes.FuncEntry], + def find_func_entry_in_table(self, funcs: GenTypes.FuncEntry*, func_count: int, - name: str) -> rawptr[GenTypes.FuncEntry]: + name: str) -> GenTypes.FuncEntry*: """在函数表中按名称查找,返回完整 FuncEntry 或 None""" if name is None or funcs is None: return None entry_size: sizet = GenTypes.FuncEntry.__sizeof__() for i in range(func_count): entry_addr: uint64 = uint64(funcs) + i * entry_size - entry: rawptr[GenTypes.FuncEntry] = rawptr[GenTypes.FuncEntry](entry_addr) + entry: GenTypes.FuncEntry* = GenTypes.FuncEntry*(entry_addr) if entry.Name is not None: # 快速路径:strcmp 判等蕴含首字符相等,首字符不同者跳过 strcmp if entry.Name[0] == name[0] and string.strcmp(entry.Name, name) == 0: return entry return None - def find_func_entry_in_table_owned(self, funcs: rawptr[GenTypes.FuncEntry], + def find_func_entry_in_table_owned(self, funcs: GenTypes.FuncEntry*, func_count: int, name: str, - owner_sha1: str) -> rawptr[GenTypes.FuncEntry]: + owner_sha1: str) -> GenTypes.FuncEntry*: """按「裸名 + 定义模块 SHA1」查找函数表条目,返回 FuncEntry 或 None 函数表以**裸名**登记,且 LoadDepVpiIntoModule 会把依赖模块的同名函数 @@ -1567,7 +1486,7 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin): entry_size: sizet = GenTypes.FuncEntry.__sizeof__() for i in range(func_count): entry_addr: uint64 = uint64(funcs) + i * entry_size - entry: rawptr[GenTypes.FuncEntry] = rawptr[GenTypes.FuncEntry](entry_addr) + entry: GenTypes.FuncEntry* = GenTypes.FuncEntry*(entry_addr) if entry is None or entry.Name is None: continue # 快速路径:strcmp 判等要求首字符相等,首字符不同者跳过 strcmp @@ -1584,11 +1503,9 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin): return None - def NewExprCallHandle(self, pool: rawptr[memhub.MemBuddy], - trans: rawptr[HT.Translator]) -> ExprCallHandle | t.CPtr: - h: ExprCallHandle | t.CPtr = pool.alloc(ExprCallHandle.__sizeof__()) - if h is None: - return None + def NewExprCallHandle(self, pool: memhub.MemBuddy*, trans: HT.Translator*) -> ExprCallHandle*: + h: ExprCallHandle* = pool.alloc(ExprCallHandle.__sizeof__()) + if h is None: return None string.memset(h, 0, ExprCallHandle.__sizeof__()) h.Trans = trans return h @@ -1600,38 +1517,30 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin): # HandleCall / HandlePrintfCall / HandlePrintCall 提供 trans 接口, # 内部委托 GenApi.translate_call 等。 # ============================================================ -@t.NoVTable -class ExprCallHandle(HT.Mixin): +novirtual class ExprCallHandle(HT.Mixin): """函数调用处理器:继承 Mixin 获得 Trans 回指针""" - def __init__(self, trans: rawptr[HT.Translator]): + def __init__(self, trans: HT.Translator*): self.Trans = trans # ============================================================ # HandleCall - 翻译函数调用,返回 call 结果 Value # ============================================================ - def HandleCall(self, node: rawptr[ast.AST]) -> rawptr[llvmlite.Value]: + def HandleCall(self, node: ast.AST*) -> llvmlite.Value*: """翻译函数调用,从 self.Trans 获取共享状态""" - return GenApi.translate_call( - self.Trans.Pool, self.Trans._cur_builder, self.Trans.Module, - node, - self.Trans._funcs, self.Trans._func_count, self.Trans) + return GenApi.translate_call(self.Trans.Pool, self.Trans._cur_builder, self.Trans.Module, node, self.Trans._funcs, self.Trans._func_count, self.Trans) # ============================================================ # HandlePrintfCall - 翻译 printf 调用 # ============================================================ - def HandlePrintfCall(self, cl: rawptr[ast.Call]): + def HandlePrintfCall(self, cl: ast.Call*): """翻译 printf 调用,从 self.Trans 获取共享状态""" - GenApi.translate_printf_call( - self.Trans.Pool, self.Trans._cur_builder, self.Trans.Module, - cl, self.Trans) + GenApi.translate_printf_call(self.Trans.Pool, self.Trans._cur_builder, self.Trans.Module, cl, self.Trans) # ============================================================ # HandlePrintCall - 翻译 print 调用 # ============================================================ - def HandlePrintCall(self, cl: rawptr[ast.Call]): + def HandlePrintCall(self, cl: ast.Call*): """翻译 print 调用(类型感知格式化 + 默认换行)""" - GenApi.translate_print_call( - self.Trans.Pool, self.Trans._cur_builder, self.Trans.Module, - cl, self.Trans) + GenApi.translate_print_call(self.Trans.Pool, self.Trans._cur_builder, self.Trans.Module, cl, self.Trans) diff --git a/App/lib/core/Gen/Call/CallGenLib.vp b/App/lib/core/Gen/Call/CallGenLib.vp index dc4d207..2c86cdf 100644 --- a/App/lib/core/Gen/Call/CallGenLib.vp +++ b/App/lib/core/Gen/Call/CallGenLib.vp @@ -14,29 +14,22 @@ from . import CallGenBase # ============================================================ # CallGenLib - CallGenMixin 拆分(阶段 C):C 库声明 / 返回类型推断 / -# 变长参数 / memcpy / kwargs 调用辅助方法 -# -# 继承 CallGenBase(1 级,TPV self 调用仅支持 1 级父类)。 -# 跨 Mixin 调用统一走 HandlesExprCall 委托(经 _g_gen)。 -# @t.NoVTable:静态绑定。 # ============================================================ -@t.NoVTable -class CallGenLib(CallGenBase.CallGenBase): +novirtual class CallGenLib(CallGenBase.CallGenBase): """C 库声明 / 返回类型推断 / kwargs 调用辅助(继承 Base)""" - def _ensure_c_lib_declare(self, pool: rawptr[memhub.MemBuddy], - mod: rawptr[llvmlite.LLVMModule], - name: str) -> rawptr[llvmlite.Function]: + def _ensure_c_lib_declare(self, pool: memhub.MemBuddy*, + mod: llvmlite.LLVMModule*, + name: str) -> llvmlite.Function*: """为已知的 C 库函数创建 declare 声明""" - if pool is None or mod is None or name is None: - return None + if pool is None or mod is None or name is None: return None - i8_ty: rawptr[llvmlite.LLVMType] = llvmlite.Int8(pool) - i32_ty: rawptr[llvmlite.LLVMType] = llvmlite.Int32(pool) - i64_ty: rawptr[llvmlite.LLVMType] = llvmlite.Int64(pool) - i8_ptr_ty: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, i8_ty) + i8_ty: llvmlite.LLVMType* = llvmlite.Int8(pool) + i32_ty: llvmlite.LLVMType* = llvmlite.Int32(pool) + i64_ty: llvmlite.LLVMType* = llvmlite.Int64(pool) + i8_ptr_ty: llvmlite.LLVMType* = llvmlite.Ptr(pool, i8_ty) - ret_ty: rawptr[llvmlite.LLVMType] = None + ret_ty: llvmlite.LLVMType* = None params: int = 0 # 参数数量 if string.strcmp(name, "strlen") == 0 or string.strcmp(name, "strlength") == 0: @@ -88,7 +81,7 @@ class CallGenLib(CallGenBase.CallGenBase): return None # 创建 declare - fn: rawptr[llvmlite.Function] = llvmlite.create_declare(pool, mod, name, ret_ty) + fn: llvmlite.Function* = llvmlite.create_declare(pool, mod, name, ret_ty) if fn is None: return None # 添加参数 @@ -113,12 +106,12 @@ class CallGenLib(CallGenBase.CallGenBase): llvmlite.add_param(pool, fn, i64_ty, "n") return fn - def _promote_clib_call_args(self, pool: rawptr[memhub.MemBuddy], - builder: rawptr[llvmlite.IRBuilder], - mod: rawptr[llvmlite.LLVMModule], + def _promote_clib_call_args(self, pool: memhub.MemBuddy*, + builder: llvmlite.IRBuilder*, + mod: llvmlite.LLVMModule*, call_name: str, - head: rawptr[llvmlite.Value], - count: int) -> rawptr[llvmlite.Value]: + head: llvmlite.Value*, + count: int) -> llvmlite.Value*: """裸名 C 库函数实参按标准签名提升(B3)。 跨模块裸名调用(string.memset → @memset)时 _ensure_method_declare 用 @@ -146,15 +139,15 @@ class CallGenLib(CallGenBase.CallGenBase): if size_idx < 0 or count <= size_idx: return head # 定位长度参数(index size_idx) - cur: rawptr[llvmlite.Value] = head + cur: llvmlite.Value* = head idx: int = 0 while cur is not None and idx < size_idx: cur = cur.Next idx += 1 if cur is None or cur.Ty is None: return head - i64_ty: rawptr[llvmlite.LLVMType] = llvmlite.Int64(pool) - promoted: rawptr[llvmlite.Value] = None + i64_ty: llvmlite.LLVMType* = llvmlite.Int64(pool) + promoted: llvmlite.Value* = None match cur.Ty: case llvmlite.LLVMType.Int(bits): if bits >= 64: @@ -170,12 +163,12 @@ class CallGenLib(CallGenBase.CallGenBase): if promoted is None: return head # 重建实参链表:index size_idx 替换为提升后的值 - new_head: rawptr[llvmlite.Value] = None - new_tail: rawptr[llvmlite.Value] = None - cur2: rawptr[llvmlite.Value] = head + new_head: llvmlite.Value* = None + new_tail: llvmlite.Value* = None + cur2: llvmlite.Value* = head i2: int = 0 while cur2 is not None: - node_v: rawptr[llvmlite.Value] = cur2 + node_v: llvmlite.Value* = cur2 if i2 == size_idx: node_v = promoted if new_head is None: @@ -188,14 +181,14 @@ class CallGenLib(CallGenBase.CallGenBase): return new_head # _coerce_args_to_def_params:按 vpi 定义侧形参注解把跨模块调用实参 coerce 到目标类型并重建实参链,使 call/declare/define 宽度一致;支持 {sha1}.{func} 与 {sha1}.{cls}.{method} 两形态(段下标与实参下标一一对应),裸名 C 库走 _promote_clib_call_args/_ensure_c_lib_declare,未命中原样保留 - def _coerce_args_to_def_params(self, pool: rawptr[memhub.MemBuddy], - builder: rawptr[llvmlite.IRBuilder], + def _coerce_args_to_def_params(self, pool: memhub.MemBuddy*, + builder: llvmlite.IRBuilder*, call_name: str, - head: rawptr[llvmlite.Value], + head: llvmlite.Value*, count: int, cargs: list[ast.AST*]* = None, self_off: int = 0, - trans: rawptr[HT.Translator] = None) -> rawptr[llvmlite.Value]: + trans: HT.Translator* = None) -> llvmlite.Value*: """把跨模块调用实参 coerce 到 vpi 定义侧形参类型,返回重建的实参链 cargs/self_off/trans:实参 AST 列表与其在实参链中的偏移(模块级函数 0、 @@ -249,29 +242,26 @@ class CallGenLib(CallGenBase.CallGenBase): if cls_nm is not None: stdlib.free(cls_nm) return head - i32_ty: rawptr[llvmlite.LLVMType] = llvmlite.Int32(pool) - i8_ptr_ty: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, llvmlite.Int8(pool)) - new_head: rawptr[llvmlite.Value] = None - new_tail: rawptr[llvmlite.Value] = None - cur: rawptr[llvmlite.Value] = head + i32_ty: llvmlite.LLVMType* = llvmlite.Int32(pool) + i8_ptr_ty: llvmlite.LLVMType* = llvmlite.Ptr(pool, llvmlite.Int8(pool)) + new_head: llvmlite.Value* = None + new_tail: llvmlite.Value* = None + cur: llvmlite.Value* = head idx: int = 0 while cur is not None and idx < count: - node_v: rawptr[llvmlite.Value] = cur - tgt_ty: rawptr[llvmlite.LLVMType] = None + node_v: llvmlite.Value* = cur + tgt_ty: llvmlite.LLVMType* = None if tpl_src != 0: - tgt_ty = VpiReader._resolve_vpi_param_annot_seg_template( - pool, sha1_buf, cls_nm, meth_nm, idx, i32_ty, i8_ptr_ty) + tgt_ty = VpiReader._resolve_vpi_param_annot_seg_template(pool, sha1_buf, cls_nm, meth_nm, idx, i32_ty, i8_ptr_ty) else: - tgt_ty = VpiReader._resolve_vpi_param_annot_seg( - pool, sha1_buf, cls_nm, meth_nm, idx, i32_ty, i8_ptr_ty) + tgt_ty = VpiReader._resolve_vpi_param_annot_seg(pool, sha1_buf, cls_nm, meth_nm, idx, i32_ty, i8_ptr_ty) if tgt_ty is not None and cur.Ty is not None: # 实参 AST(源符号性判定用):链下标 idx 减 self 偏移即 AST 下标 arg_idx: int = idx - self_off - arg_node: rawptr[ast.AST] = None + arg_node: ast.AST* = None if cargs is not None and arg_idx >= 0 and arg_idx < len(cargs): arg_node = cargs.get(arg_idx) - node_v = self._coerce_arg_value_to_ty( - pool, builder, cur, tgt_ty, arg_node, trans, tpl_src) + node_v = self._coerce_arg_value_to_ty(pool, builder, cur, tgt_ty, arg_node, trans, tpl_src) if new_head is None: new_head = node_v else: @@ -285,13 +275,13 @@ class CallGenLib(CallGenBase.CallGenBase): return new_head # _coerce_arg_value_to_ty:单个实参 Value 转换到目标形参类型——整型同宽原样、窄化 trunc/按宽度重建常量、扩宽按源符号性 zext/sext;指针 i8* 性不同则 bitcast;其余原样返回(不可转换亦不改型) - def _coerce_arg_value_to_ty(self, pool: rawptr[memhub.MemBuddy], - 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) -> rawptr[llvmlite.Value]: + def _coerce_arg_value_to_ty(self, pool: memhub.MemBuddy*, + builder: llvmlite.IRBuilder*, + val: llvmlite.Value*, + tgt_ty: llvmlite.LLVMType*, + node: ast.AST* = None, + trans: HT.Translator* = None, + tpl_src: int = 0) -> llvmlite.Value*: """把单个实参 Value 转换到目标形参类型,无法安全转换时原样返回 node/trans:实参 AST 与其翻译器(仅 SSA 整型扩宽的源符号性判定用, @@ -310,35 +300,25 @@ class CallGenLib(CallGenBase.CallGenBase): return val if bits_b < bits_a: if val.IsConst != 0: - nv_c: rawptr[llvmlite.Value] = llvmlite.const_int( - pool, bits_b, val.IntVal) - if nv_c is not None: - return nv_c + nv_c: llvmlite.Value* = llvmlite.const_int(pool, bits_b, val.IntVal) + if nv_c is not None: return nv_c else: - nv_t: rawptr[llvmlite.Value] = llvmlite.build_trunc( - builder, val, tgt_ty) - if nv_t is not None: - return nv_t + nv_t: 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: rawptr[llvmlite.Value] = llvmlite.const_int( - pool, bits_b, val.IntVal) + nv_w: llvmlite.Value* = llvmlite.const_int(pool, bits_b, val.IntVal) if nv_w is not None: return nv_w return val # 非常量(SSA)扩宽:扩宽方向由源符号性决定(i1/i8、无符号源 → zext,否则 sext),使 declare/call/define 三者同宽 if bits_b > bits_a: - if self.Gen.ExprGenBase._zext_or_sext_val( - pool, val, node, trans) != 0: - nv_zw: rawptr[llvmlite.Value] = llvmlite.build_zext( - builder, val, tgt_ty) - if nv_zw is not None: - return nv_zw + if self.Gen.ExprGenBase._zext_or_sext_val(pool, val, node, trans) != 0: + nv_zw: llvmlite.Value* = llvmlite.build_zext(builder, val, tgt_ty) + if nv_zw is not None: return nv_zw else: - nv_sw: rawptr[llvmlite.Value] = llvmlite.build_sext( - builder, val, tgt_ty) - if nv_sw is not None: - return nv_sw + nv_sw: llvmlite.Value* = llvmlite.build_sext(builder, val, tgt_ty) + if nv_sw is not None: return nv_sw return val case _: pass @@ -360,16 +340,12 @@ class CallGenLib(CallGenBase.CallGenBase): case _: pass if ia != ib: - nv_p: rawptr[llvmlite.Value] = llvmlite.build_bitcast( - builder, val, tgt_ty) - if nv_p is not None: - return nv_p + nv_p: 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: rawptr[llvmlite.Value] = llvmlite.build_bitcast( - builder, val, tgt_ty) - if nv_p2 is not None: - return nv_p2 + nv_p2: llvmlite.Value* = llvmlite.build_bitcast(builder, val, tgt_ty) + if nv_p2 is not None: return nv_p2 case _: pass case _: @@ -378,8 +354,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: rawptr[llvmlite.Value] = self.Gen.VarGen._alloca_at_entry( - builder, val.Ty) + tmp_a: llvmlite.Value* = self.Gen.VarGen._alloca_at_entry(builder, val.Ty) if tmp_a is not None: llvmlite.build_store(builder, val, tmp_a) return tmp_a @@ -387,10 +362,10 @@ class CallGenLib(CallGenBase.CallGenBase): pass return val - def _infer_external_func_ret_ty(self, pool: rawptr[memhub.MemBuddy], + def _infer_external_func_ret_ty(self, pool: memhub.MemBuddy*, func_name: str, - node: rawptr[ast.AST], - fatal_if_unknown: int) -> rawptr[llvmlite.LLVMType]: + node: ast.AST*, + fatal_if_unknown: int) -> llvmlite.LLVMType*: """根据函数名推断外部 includes 函数的返回类型 支持三种函数名形式: @@ -415,7 +390,7 @@ class CallGenLib(CallGenBase.CallGenBase): # '.' 后的部分是裸函数名 bare_name = dot_pos + 1 - i8_ptr_ty: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, llvmlite.Int8(pool)) + i8_ptr_ty: llvmlite.LLVMType* = llvmlite.Ptr(pool, llvmlite.Int8(pool)) # 返回 i8* 的函数(指针返回值,截断会导致错误) if string.strcmp(bare_name, "strchr") == 0 or string.strcmp(func_name, "strchr") == 0: @@ -489,7 +464,7 @@ class CallGenLib(CallGenBase.CallGenBase): # Win32 API 返回指针(VOIDPTR/HANDLE)的函数 # stubs 翻译时未注入,需推断返回 i8* 避免指针被截断为 i32 导致解引用崩溃 - i8_ptr_ty: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, llvmlite.Int8(pool)) + i8_ptr_ty: llvmlite.LLVMType* = llvmlite.Ptr(pool, llvmlite.Int8(pool)) if string.strcmp(func_name, "VirtualAlloc") == 0: return i8_ptr_ty if string.strcmp(func_name, "HeapAlloc") == 0: @@ -579,14 +554,11 @@ class CallGenLib(CallGenBase.CallGenBase): # 默认 i32 占位:fatal_if_unknown=1 → fail-fast 报错;=0(Phase A 中间遍)保持占位,不输出 WARN if fatal_if_unknown != 0: - self.Gen.TypeGenErr.fatal_error( - node, - f"外部函数返回类型未登记且无法收敛推断(默认 i32 会截断指针/i64,需提供 stub 声明或加入白名单): {func_name}", - "TypeError") + self.Gen.TypeGenErr.fatal_error(node, f"外部函数返回类型未登记且无法收敛推断(默认 i32 会截断指针/i64,需提供 stub 声明或加入白名单): {func_name}", "TypeError") return llvmlite.Int32(pool) - def _get_external_func_param_ty(self, pool: rawptr[memhub.MemBuddy], + def _get_external_func_param_ty(self, pool: memhub.MemBuddy*, func_name: str, - param_idx: int) -> rawptr[llvmlite.LLVMType]: + param_idx: int) -> llvmlite.LLVMType*: """获取外部函数第 param_idx 个参数的期望类型,None 表示用字面量原类型 对 Win32 API 函数的所有非指针参数返回 i64,匹配 declare 中 @@ -595,11 +567,11 @@ class CallGenLib(CallGenBase.CallGenBase): if pool is None or func_name is None: return None - i64_ty: rawptr[llvmlite.LLVMType] = llvmlite.Int64(pool) + i64_ty: llvmlite.LLVMType* = llvmlite.Int64(pool) # Win32 API 函数列表:所有非指针参数在 declare 中都是 i64 # (因为 ULONG/DWORD/SIZE_T 在 LLVM stubs 翻译时都被映射为 i64) - win32_apis: list[str] | t.CPtr = [ + win32_apis: list[str]* = [ "VirtualAlloc", "VirtualFree", "VirtualProtect", "VirtualQuery", "VirtualLock", "VirtualUnlock", "HeapCreate", "HeapDestroy", "HeapAlloc", "HeapReAlloc", @@ -644,12 +616,12 @@ class CallGenLib(CallGenBase.CallGenBase): if GenApi.sha1_prefix_len(call_name) != 0: return 1 return 0 - def _emit_llvm_memcpy_intrinsic(self, pool: rawptr[memhub.MemBuddy], - builder: rawptr[llvmlite.IRBuilder], - mod: rawptr[llvmlite.LLVMModule], - dst_val: rawptr[llvmlite.Value], - src_val: rawptr[llvmlite.Value], - num_val: rawptr[llvmlite.Value]) -> rawptr[llvmlite.Value]: + def _emit_llvm_memcpy_intrinsic(self, pool: memhub.MemBuddy*, + builder: llvmlite.IRBuilder*, + mod: llvmlite.LLVMModule*, + dst_val: llvmlite.Value*, + src_val: llvmlite.Value*, + num_val: llvmlite.Value*) -> llvmlite.Value*: """将 memcpy 调用映射到 @llvm.memcpy 内联函数 直接接收三个 Value 参数,避免通过 Next 链表遍历(共享 alloca 对象的 @@ -661,16 +633,16 @@ class CallGenLib(CallGenBase.CallGenBase): return None # 在函数顶部声明 void_ty,避免后续遮蔽 - void_ty: rawptr[llvmlite.LLVMType] = llvmlite.Void(pool) + void_ty: llvmlite.LLVMType* = llvmlite.Void(pool) # 声明 @llvm.memcpy(如未声明) - memcpy_func: rawptr[llvmlite.Function] = self.find_func_in_module(mod, "llvm.memcpy") + memcpy_func: llvmlite.Function* = self.find_func_in_module(mod, "llvm.memcpy") if memcpy_func is None: memcpy_func = llvmlite.create_declare(pool, mod, "llvm.memcpy", void_ty) if memcpy_func is not None: - i8_ptr_ty_d: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, llvmlite.Int8(pool)) - i64_ty_d: rawptr[llvmlite.LLVMType] = llvmlite.Int64(pool) - i1_ty_d: rawptr[llvmlite.LLVMType] = llvmlite.Int1(pool) + i8_ptr_ty_d: llvmlite.LLVMType* = llvmlite.Ptr(pool, llvmlite.Int8(pool)) + i64_ty_d: llvmlite.LLVMType* = llvmlite.Int64(pool) + i1_ty_d: llvmlite.LLVMType* = llvmlite.Int1(pool) llvmlite.add_param(pool, memcpy_func, i8_ptr_ty_d, "dst") llvmlite.add_param(pool, memcpy_func, i8_ptr_ty_d, "src") llvmlite.add_param(pool, memcpy_func, i64_ty_d, "len") @@ -678,12 +650,12 @@ class CallGenLib(CallGenBase.CallGenBase): # 类型转换: dst, src → i8*; num → i64 # 注意: 使用 value_get_ty 访问器获取 Ty,避免本地 Value 类型字段索引偏移 - i8_ptr_ty: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, llvmlite.Int8(pool)) - i64_ty: rawptr[llvmlite.LLVMType] = llvmlite.Int64(pool) + i8_ptr_ty: llvmlite.LLVMType* = llvmlite.Ptr(pool, llvmlite.Int8(pool)) + i64_ty: llvmlite.LLVMType* = llvmlite.Int64(pool) # dst → i8* - dst_coerced: rawptr[llvmlite.Value] = dst_val - dst_ty: rawptr[llvmlite.LLVMType] = llvmlite.value_get_ty(dst_val) + dst_coerced: llvmlite.Value* = dst_val + dst_ty: 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) else: @@ -694,8 +666,8 @@ class CallGenLib(CallGenBase.CallGenBase): dst_coerced = llvmlite.build_inttoptr(builder, dst_coerced, i8_ptr_ty) # src → i8* - src_coerced: rawptr[llvmlite.Value] = src_val - src_ty: rawptr[llvmlite.LLVMType] = llvmlite.value_get_ty(src_val) + src_coerced: llvmlite.Value* = src_val + src_ty: 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) else: @@ -706,13 +678,13 @@ class CallGenLib(CallGenBase.CallGenBase): src_coerced = llvmlite.build_inttoptr(builder, src_coerced, i8_ptr_ty) # num → i64 - num_coerced: rawptr[llvmlite.Value] = self.Gen.ExprGenBase.coerce_to_type(builder, num_val, i64_ty) + num_coerced: 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: rawptr[llvmlite.Value] = llvmlite.ConstInt(pool, llvmlite.Int1(pool), 0, "false") + false_val: llvmlite.Value* = llvmlite.ConstInt(pool, llvmlite.Int1(pool), 0, "false") # 使用 includes 中的访问器函数构建参数链表,避免本地 Value 类型字段索引偏移 # (f26cd4c78b4d554c.Value 缺少 GSListNode 的 Next 字段,直接访问 .Next 会修改 .Ty) @@ -726,62 +698,59 @@ class CallGenLib(CallGenBase.CallGenBase): # 使用 build_call 发射 call 指令(内部用 includes Value 类型访问字段,索引正确) # _ll_name_needs_quote 已对 llvm. 前缀豁免引号 - result: rawptr[llvmlite.Value] = llvmlite.build_call(builder, "llvm.memcpy", dst_coerced, 4, void_ty, 0) + result: llvmlite.Value* = llvmlite.build_call(builder, "llvm.memcpy", dst_coerced, 4, void_ty, 0) # 返回 dst(匹配 C memcpy 语义: 返回 dest 指针) return dst_coerced # _translate_call_with_kwargs:带关键字参数的函数调用,按 found_func.Params 顺序构建实参链表(位置参数优先,否则按参数名匹配关键字) # ============================================================ - def _translate_call_with_kwargs(self, pool: rawptr[memhub.MemBuddy], - builder: rawptr[llvmlite.IRBuilder], - mod: rawptr[llvmlite.LLVMModule], + def _translate_call_with_kwargs(self, pool: memhub.MemBuddy*, + builder: llvmlite.IRBuilder*, + mod: llvmlite.LLVMModule*, func_name: str, - found_func: rawptr[llvmlite.Function], + found_func: llvmlite.Function*, cargs: list[ast.AST*]*, can: sizet, keywords: list[ast.AST*]*, kw_count: sizet, - trans: rawptr[HT.Translator]) -> rawptr[llvmlite.Value]: + trans: HT.Translator*) -> llvmlite.Value*: """带关键字参数的函数调用,按参数顺序构建调用链表 使用 llvmlite 访问器函数绕过 stub 类型限制: found_func.Params/RetTy/Name 和 cur_param.Name/Ty/Next 在 stub 类型中字段不足,直接访问会被 TransPyC 静默跳过。 """ - head: rawptr[llvmlite.Value] = None - tail: rawptr[llvmlite.Value] = None + head: llvmlite.Value* = None + tail: llvmlite.Value* = None actual_count: sizet = 0 # memcpy 专用: 收集前三个 Value 的独立引用(避免共享 alloca 对象的 Next 被污染) - mc_dst1: rawptr[llvmlite.Value] = None - mc_src1: rawptr[llvmlite.Value] = None - mc_num1: rawptr[llvmlite.Value] = None + mc_dst1: llvmlite.Value* = None + mc_src1: llvmlite.Value* = None + mc_num1: llvmlite.Value* = None # 遍历函数参数链表(使用访问器获取 Head) param_idx: sizet = 0 - cur_param: rawptr[llvmlite.Param] = llvmlite.function_get_param_head(found_func) + cur_param: llvmlite.Param* = llvmlite.function_get_param_head(found_func) while cur_param is not None: - arg_val: rawptr[llvmlite.Value] = None - param_ty: rawptr[llvmlite.LLVMType] = llvmlite.param_get_ty(cur_param) + arg_val: llvmlite.Value* = None + param_ty: llvmlite.LLVMType* = llvmlite.param_get_ty(cur_param) if param_idx < can: # 优先使用位置参数 - arg: rawptr[ast.AST] = cargs.get(param_idx) + arg: ast.AST* = cargs.get(param_idx) if arg is not None: # 传形参类型(char 字面量 → str 形参需物化字符串,见 translate_constant) - arg_val = self.Gen.ExprGen.translate_value( - builder, pool, mod, arg, None, 0, trans, param_ty) + arg_val = self.Gen.ExprGen.translate_value(builder, pool, mod, arg, None, 0, trans, param_ty) else: # 查找匹配的关键字参数 param_name: str = llvmlite.param_get_name(cur_param) if param_name is not None: for ki in range(kw_count): 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 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: - arg_val = self.Gen.ExprGen.translate_value( - builder, pool, mod, kw.value, None, 0, trans, param_ty) + arg_val = self.Gen.ExprGen.translate_value(builder, pool, mod, kw.value, None, 0, trans, param_ty) break if arg_val is not None: @@ -813,7 +782,7 @@ class CallGenLib(CallGenBase.CallGenBase): call_name = found_name # 返回类型(使用访问器) - call_ret_ty: rawptr[llvmlite.LLVMType] = llvmlite.function_get_ret_ty(found_func) + call_ret_ty: llvmlite.LLVMType* = llvmlite.function_get_ret_ty(found_func) if call_ret_ty is None: # found_func 已有 declare 却读不到返回类型(访问器异常,罕见防御): # 白名单未命中也不 fail-fast,保持默认 i32(有声明即有类型来源)。 diff --git a/App/lib/core/Gen/Call/CallGenMixin.vp b/App/lib/core/Gen/Call/CallGenMixin.vp index 44f447a..e85f98f 100644 --- a/App/lib/core/Gen/Call/CallGenMixin.vp +++ b/App/lib/core/Gen/Call/CallGenMixin.vp @@ -19,55 +19,41 @@ import lib.core.Gen.GenApi as GenApi # ============================================================ # CallGenMixin - 调用分派 Mixin(拆分后顶层,阶段 A:底层已拆至 -# CallGenBase/CallGenCBuiltin/CallGenLeafKit) -# -# 500~1500 行/文件架构重构阶段 A:底层自包含组(模块查找/返回类型解析/ -# c.*/asm/llvmir/EH/isinstance/闭包/print/函数表)已拆出,本文件保留 -# 调用分派中枢(translate_call 等)。继承链 CallGenMixin → LeafKit → -# CBuiltin → Base,@t.NoVTable 静态绑定沿 MRO 解析 self 调用。 -# -# @t.NoVTable:静态绑定(方法沿 MRO 直接调用 + this 调整)。 # ============================================================ # ============================================================ # 常量(与 TPC 侧 HandlesExprCall 保持一致) -# -# GLOBAL_FUNC_MAX / GLOBAL_DEFAULTS_MAX / MAX_CLOSURE_NAMES / -# MAX_FUNC_PTR_SIGS / ISINSTANCE_CLASS_MAX:唯一来源在 CallGenBase.vp -# (本文件不使用,故不留副本;消费方 CallGenLeafKit.vp 经 CallGenBase. 引用)。 # ============================================================ -_CEXPORT_MAX: t.CDefine = 256 -ASM_MAX_OPERANDS: t.CDefine = 16 -ASM_TEXT_BUF_SIZE: t.CDefine = 2048 -ASM_CONST_BUF_SIZE: t.CDefine = 512 -ASM_ARGS_BUF_SIZE: t.CDefine = 512 -ASM_LINE_BUF_SIZE: t.CDefine = 4096 -LLVMIR_MAX_OPS: t.CDefine = 16 -LLVMIR_TEMPLATE_BUF: t.CDefine = 512 +define _CEXPORT_MAX = 256 +define ASM_MAX_OPERANDS = 16 +define ASM_TEXT_BUF_SIZE = 2048 +define ASM_CONST_BUF_SIZE = 512 +define ASM_ARGS_BUF_SIZE = 512 +define ASM_LINE_BUF_SIZE = 4096 +define LLVMIR_MAX_OPS = 16 +define LLVMIR_TEMPLATE_BUF = 512 # ============================================================ # CallGenMixin - 调用分派中枢(顶层,继承 LeafKit) # ============================================================ -@t.NoVTable -class CallGenMixin(CallGenBase.CallGenBase): +novirtual class CallGenMixin(CallGenBase.CallGenBase): """调用分派 Mixin(拆分后顶层,直接继承 CallGenBase——TPV self 调用仅支持 1 级父类)""" # ============================================================ # 翻译函数调用 Call(func, args) — 模块级版本 # ============================================================ - def translate_call(self, pool: rawptr[memhub.MemBuddy], - builder: rawptr[llvmlite.IRBuilder], - mod: rawptr[llvmlite.LLVMModule], - node: rawptr[ast.AST], + def translate_call(self, pool: memhub.MemBuddy*, + builder: llvmlite.IRBuilder*, + mod: llvmlite.LLVMModule*, + node: ast.AST*, funcs_ptr: t.CPtr, func_count: int, - trans: rawptr[HT.Translator] = None) -> rawptr[llvmlite.Value]: + trans: HT.Translator* = None) -> llvmlite.Value*: """翻译函数调用,返回 call 结果 Value""" - cl: rawptr[ast.Call] = rawptr[ast.Call](node) - if cl is None: - return None + cl: ast.Call* = ast.Call*(node) + if cl is None: return None func_name: str = self.Gen.ExprGenBase.get_func_name(cl.func) @@ -82,8 +68,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: 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) + _tc_h1_super_ctraits_res: 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: h1_hit_val = h1_hit[0] @@ -99,26 +84,24 @@ class CallGenMixin(CallGenBase.CallGenBase): # 检查是否是 list[int](pool) 形式的泛型实例化调用 # Subscript 节点作为 Call func: 泛型类构造函数 if cl.func is not None and cl.func.kind() == ast.ASTKind.Subscript and trans is not None: - sub_node: rawptr[ast.Subscript] = rawptr[ast.Subscript](cl.func) + sub_node: ast.Subscript* = ast.Subscript*(cl.func) if sub_node.value is not None and sub_node.value.kind() == ast.ASTKind.Name: - gen_nm_node: rawptr[ast.Name] = rawptr[ast.Name](sub_node.value) + gen_nm_node: ast.Name* = ast.Name*(sub_node.value) gen_class_name: str = gen_nm_node.id # 检查是否是泛型类模板 - template_cd: rawptr[ast.ClassDef] = self.Gen.ClassGenGeneric._find_generic_template(gen_class_name) + template_cd: ast.ClassDef* = self.Gen.ClassGenGeneric._find_generic_template(gen_class_name) if template_cd is not None: # 提取类型实参 - gen_type_args: list[str] | t.CPtr = self.Gen.CallGenCtor._extract_type_args_from_slice(pool, sub_node.slice, trans._from_imports) + gen_type_args: list[str]* = self.Gen.CallGenCtor._extract_type_args_from_slice(pool, sub_node.slice, trans._from_imports) if gen_type_args is not None and len(gen_type_args) > 0: # 特化泛型类,返回特化类名 - spec_name: str = self.Gen.ClassGenGeneric._specialize_generic_class( - trans, gen_class_name, gen_type_args) + spec_name: str = self.Gen.ClassGenGeneric._specialize_generic_class(trans, gen_class_name, gen_type_args) if spec_name is not None: # 泛型类构造调用: list[str](pool, 8) → __new__ + __before_init__ + __init__ # 不能直接用 spec_name 作为 func_name(会走裸名调用路径, # 被 star import 回退误导用错误的 SHA1,且缺少 __new__ 方法名后缀) # 末参传模板名:关键字实参需按 __init__ 形参名定位槽位 - return self.Gen.CallGenCtor._translate_generic_ctor_call( - pool, builder, mod, spec_name, cl, trans, gen_class_name) + return self.Gen.CallGenCtor._translate_generic_ctor_call(pool, builder, mod, spec_name, cl, trans, gen_class_name) else: # 泛型类模板未找到:可能是泛型函数手动传类型参数调用 xxx[T](x) # (对应 TPC _HandleGenericCallExplicitLlvm;TPV 无泛型函数特化, @@ -133,14 +116,11 @@ class CallGenMixin(CallGenBase.CallGenBase): # CArray 不是泛型类模板,是类型注解下标。先按注解解析出 # 类型再单参转换(ast/base.vp L392 ops_list 行根因)。 if cl.args is not None and len(cl.args) == 1: - sub_cast_ty: rawptr[llvmlite.LLVMType] = self.Gen.TypeGenResolve.resolve_annotation_type( - pool, cl.func, trans._imported_modules, trans._from_imports, trans, 0) + sub_cast_ty: 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: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( - builder, pool, mod, cl.args.get(0), funcs_ptr, func_count, trans) + sub_cast_arg: 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( - pool, builder, sub_cast_arg, sub_cast_ty, + return self.Gen.CallGenCtor._translate_t_type_cast(pool, builder, sub_cast_arg, sub_cast_ty, cl.args.get(0), trans) # 泛型类模板未找到:可能未 import 定义模块 gt_err: str = pool.alloc(256) @@ -152,13 +132,11 @@ class CallGenMixin(CallGenBase.CallGenBase): # 检查是否是 (A | t.CPtr)(value) 形式的类型转换 # BinOp 节点作为 Call func: 联合类型注解用作类型转换 if cl.func is not None and cl.func.kind() == ast.ASTKind.BinOp and trans is not None: - binop_ty: rawptr[llvmlite.LLVMType] = self.Gen.TypeGenResolve.resolve_annotation_type( - pool, cl.func, trans._imported_modules, trans._from_imports, trans, 0) + binop_ty: 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[ast.AST*]* = cl.args if binop_args is not None and len(binop_args) == 1: - binop_arg_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( - builder, pool, mod, binop_args.get(0), funcs_ptr, func_count, trans) + binop_arg_val: 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) return None @@ -170,8 +148,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: 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) + _tc_h2_c_special_res: 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: h2_hit_val = h2_hit[0] @@ -182,18 +159,15 @@ class CallGenMixin(CallGenBase.CallGenBase): # 命中 c.Asm/c.LLVMIR 但无返回值(void):视为已处理 return None - _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) + _tc_h3_stdarg_cast_res: 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: rawptr[llvmlite.Value] = self.Gen.CallGenDispatch._tc_h4_type_casts( - pool, builder, mod, cl, funcs_ptr, func_count, trans, func_name, cargs, can) + _tc_h4_type_casts_res: 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: rawptr[llvmlite.Value] = self.Gen.CallGenDispatch._tc_h5_sizeof_len_isinst( - pool, builder, mod, cl, funcs_ptr, func_count, trans, func_name, cargs, can) + _tc_h5_sizeof_len_isinst_res: 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 @@ -206,8 +180,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: 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) + _tc_h6_method_dispatch_res: 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: h6_hit_val = h6_hit[0] @@ -229,8 +202,8 @@ class CallGenMixin(CallGenBase.CallGenBase): # - 裸名 Class(): 需要 from X import Class 或本地定义 # - 模块限定 Module.Class(): 需要 import Module # 用 find_struct_by_module 规避跨模块同名 find_struct 找错 - struct_ty: rawptr[llvmlite.LLVMType] = None - gen_ctor_entry: rawptr[GenTypes.StructEntry] = None + struct_ty: llvmlite.LLVMType* = None + gen_ctor_entry: GenTypes.StructEntry* = None # 模块限定构造 Module.Class(...) 优先:按模块名解析 SHA1 精确命中类。 # 必须在裸名可见性分支之前——跨模块同名类(VKernel gfx 与 App gfx 都 # 定义 Scene3D)存在时,裸名 find_struct 返回先注册的错误 entry @@ -238,10 +211,10 @@ class CallGenMixin(CallGenBase.CallGenBase): # symbol,Scene3D 根因)。模块解析成功即锁定,跳过下方裸名回退。 mod_qual_done: int = 0 if trans is not None and cl.func is not None and cl.func.kind() == ast.ASTKind.Attribute: - at_qc0: rawptr[ast.Attribute] = rawptr[ast.Attribute](cl.func) + at_qc0: ast.Attribute* = ast.Attribute*(cl.func) mod_path0: str = None if at_qc0.value is not None and at_qc0.value.kind() == ast.ASTKind.Name: - mod_nm0: rawptr[ast.Name] = rawptr[ast.Name](at_qc0.value) + mod_nm0: ast.Name* = ast.Name*(at_qc0.value) if mod_nm0.id is not None: mod_path0 = mod_nm0.id elif at_qc0.value is not None and at_qc0.value.kind() == ast.ASTKind.Attribute: @@ -250,8 +223,7 @@ class CallGenMixin(CallGenBase.CallGenBase): if self.Gen.ImportsGen.is_module_imported_or_known(trans._imported_modules, mod_path0) != 0: mod_sha1_0: str = self._lookup_module_sha1(mod_path0) if mod_sha1_0 is not None: - gen_ctor_entry = self.Gen.StructGen.find_struct_by_module( - func_name, mod_sha1_0) + gen_ctor_entry = self.Gen.StructGen.find_struct_by_module(func_name, mod_sha1_0) mod_qual_done = 1 vis: int = self.Gen.StructGen.is_struct_visible(func_name) if mod_qual_done == 0 and vis != 0: @@ -262,9 +234,9 @@ class CallGenMixin(CallGenBase.CallGenBase): if gen_ctor_entry is not None: struct_ty = gen_ctor_entry.Ty elif trans is not None and cl.func is not None and cl.func.kind() == ast.ASTKind.Attribute: - at_qc: rawptr[ast.Attribute] = rawptr[ast.Attribute](cl.func) + at_qc: ast.Attribute* = ast.Attribute*(cl.func) if at_qc.value is not None and at_qc.value.kind() == ast.ASTKind.Name: - mod_nm_qc: rawptr[ast.Name] = rawptr[ast.Name](at_qc.value) + mod_nm_qc: ast.Name* = ast.Name*(at_qc.value) imp_ok: int = self.Gen.ImportsGen.is_module_imported_or_known(trans._imported_modules, mod_nm_qc.id) if imp_ok != 0: # 模块限定构造 Module.Class(...):按模块名解析 SHA1 精确命中类。 @@ -277,8 +249,7 @@ class CallGenMixin(CallGenBase.CallGenBase): if mod_nm_qc.id is not None: mod_sha1_qc2 = self._lookup_module_sha1(mod_nm_qc.id) if mod_sha1_qc2 is not None: - gen_ctor_entry = self.Gen.StructGen.find_struct_by_module( - func_name, mod_sha1_qc2) + gen_ctor_entry = self.Gen.StructGen.find_struct_by_module(func_name, mod_sha1_qc2) if gen_ctor_entry is None: gen_ctor_entry = self.Gen.StructGen.find_struct(func_name) if gen_ctor_entry is not None: @@ -294,13 +265,11 @@ class CallGenMixin(CallGenBase.CallGenBase): # @t.NoVTable 静态绑定会 mangle 成 CallGenMixin. 前缀 → undefined reference)。 mod_path_qc: str = self.Gen.ExprGenAttr._attr_module_path_str(pool, at_qc.value) if mod_path_qc is not None: - imp_ok_qc: int = self.Gen.ImportsGen.is_module_imported( - trans._imported_modules, mod_path_qc) + imp_ok_qc: int = self.Gen.ImportsGen.is_module_imported(trans._imported_modules, mod_path_qc) if imp_ok_qc != 0: mod_sha1_qc: str = self._lookup_module_sha1(mod_path_qc) if mod_sha1_qc is not None: - gen_ctor_entry = self.Gen.StructGen.find_struct_by_module( - func_name, mod_sha1_qc) + gen_ctor_entry = self.Gen.StructGen.find_struct_by_module(func_name, mod_sha1_qc) if gen_ctor_entry is None: gen_ctor_entry = self.Gen.StructGen.find_struct(func_name) if gen_ctor_entry is not None: @@ -314,8 +283,7 @@ class CallGenMixin(CallGenBase.CallGenBase): if trans._from_imports is not None: ctor_sha1: str = self._lookup_mod_sha1(pool, trans._from_imports, func_name, 0) if ctor_sha1 is not None: - ctor_orig: str = self.Gen.ImportsGen.lookup_from_import_original( - trans._from_imports, func_name) + ctor_orig: str = self.Gen.ImportsGen.lookup_from_import_original(trans._from_imports, func_name) if ctor_orig is not None: # 复制到独立 null 终止缓冲区(from_imports 内部缓冲未终止) co_len: sizet = 0 @@ -341,8 +309,7 @@ class CallGenMixin(CallGenBase.CallGenBase): if gen_ctor_entry is not None: ctor_is_oop = gen_ctor_entry.IsOOP if ctor_is_oop != 0: - return self.Gen.CallGenCtor._translate_struct_ctor( - pool, builder, mod, struct_ty, func_name, cargs, sizet(0), trans) + return self.Gen.CallGenCtor._translate_struct_ctor(pool, builder, mod, struct_ty, func_name, cargs, sizet(0), trans) # @t.NoVTable 类(无方法、类语义/指针对象):无参构造也应分配内存 # 返回指针。否则按值结构体返回 ConstZero(struct_ty),LHS 联合注解 # (如 Plain|CPtr)存 0 指针 → p.v 解引用 NULL 段错误 @@ -351,14 +318,12 @@ class CallGenMixin(CallGenBase.CallGenBase): if gen_ctor_entry is not None: ctor_is_novt = gen_ctor_entry.IsNoVTable if ctor_is_novt != 0: - return self.Gen.CallGenCtor._translate_struct_ctor( - pool, builder, mod, struct_ty, func_name, cargs, sizet(0), trans) + return self.Gen.CallGenCtor._translate_struct_ctor(pool, builder, mod, struct_ty, func_name, cargs, sizet(0), trans) # 普通结构体:检查是否有默认值(用 entry 直接访问) gen_has_defaults: int = 0 if gen_ctor_entry is not None: for gdi in range(gen_ctor_entry.FieldCount): - gdf: rawptr[GenTypes.FieldEntry] = self.Gen.StructGen._get_field_entry( - gen_ctor_entry, gdi) + gdf: 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 break @@ -366,18 +331,14 @@ class CallGenMixin(CallGenBase.CallGenBase): gen_has_defaults = self.Gen.StructGen.struct_has_defaults(func_name) if gen_has_defaults == 1: # 有默认值:走构造函数路径应用默认值 - return self.Gen.CallGenCtor._translate_struct_ctor( - pool, builder, mod, struct_ty, func_name, cargs, sizet(0), trans) + return self.Gen.CallGenCtor._translate_struct_ctor(pool, builder, mod, struct_ty, func_name, cargs, sizet(0), trans) # 无默认值:返回 zeroinitializer - ret: rawptr[llvmlite.Value] = llvmlite.ConstZero(pool, struct_ty) + ret: llvmlite.Value* = llvmlite.ConstZero(pool, struct_ty) return ret if kw_count > 0: # 有关键字参数:按字段名赋值 - return self.Gen.CallGenCtor._translate_struct_ctor_kw( - pool, builder, mod, struct_ty, func_name, cargs, can, - keywords, kw_count, trans) - return self.Gen.CallGenCtor._translate_struct_ctor( - pool, builder, mod, struct_ty, func_name, cargs, can, trans) + return self.Gen.CallGenCtor._translate_struct_ctor_kw(pool, builder, mod, struct_ty, func_name, cargs, can, keywords, kw_count, trans) + return self.Gen.CallGenCtor._translate_struct_ctor(pool, builder, mod, struct_ty, func_name, cargs, can, trans) # 裸名泛型类模板构造: Box(42) → 从实参推断类型实参 → 特化 → 构造 # (TPC 参考: _HandleGenericClassNewLlvm;GenericTest Test4 Box(42)/Test5 @@ -391,27 +352,25 @@ class CallGenMixin(CallGenBase.CallGenBase): if cl.func is not None and cl.func.kind() == ast.ASTKind.Name: is_gen_bare = 1 elif cl.func is not None and cl.func.kind() == ast.ASTKind.Attribute: - at_gb: rawptr[ast.Attribute] = rawptr[ast.Attribute](cl.func) + at_gb: ast.Attribute* = ast.Attribute*(cl.func) if at_gb.value is not None and at_gb.value.kind() == ast.ASTKind.Name: - am_gb: rawptr[ast.Name] = rawptr[ast.Name](at_gb.value) + am_gb: ast.Name* = ast.Name*(at_gb.value) if am_gb.id is not None: if self.Gen.ImportsGen.is_module_imported(trans._imported_modules, am_gb.id) != 0: is_gen_bare = 1 if is_gen_bare != 0: - template_cd_bare: rawptr[ast.ClassDef] = self.Gen.ClassGenGeneric._find_generic_template(func_name) + template_cd_bare: ast.ClassDef* = self.Gen.ClassGenGeneric._find_generic_template(func_name) if template_cd_bare is not None and template_cd_bare.type_params is not None: - tp_bare: list[str] | t.CPtr = template_cd_bare.type_params + tp_bare: list[str]* = template_cd_bare.type_params tp_count_bare: sizet = len(tp_bare) if tp_count_bare > 0: - inferred_args_bare: list[str] | t.CPtr = list[str](pool, 8) + inferred_args_bare: list[str]* = list[str](pool, 8) if inferred_args_bare is not None: # 类型形参 → 位置实参对齐:取 __init__ 签名中注解为该类型形参的形参位次(Vector[T].__init__(self, pool, capacity, _hint: T) ⇒ T 对齐第 3 个位置实参)。不能按「类型形参序号 = 实参序号」硬对齐(第 1 个实参常是 pool/size 等非 T 参数);签名不可得(无 __init__/无 T 注解形参)时退化为同一序号。[C①] 注解上下文提供的类型实参优先级:显式 [...] > 位置/关键字实参推断 > 注解上下文 > fail-fast,仅当本次构造就是注解赋值/return 的直接值(identity 判定)时才返回非 None - ctx_args_bare: list[str] | t.CPtr = self.Gen.CallGenCtor._infer_ctor_type_args_from_ctx( - pool, trans, func_name, int(tp_count_bare), cl) + ctx_args_bare: list[str]* = self.Gen.CallGenCtor._infer_ctor_type_args_from_ctx(pool, trans, func_name, int(tp_count_bare), cl) tpi_bare: sizet = 0 for tpi_bare in range(tp_count_bare): - aip_bare: int = self.Gen.CallGenCtor._find_ctor_type_param_arg_index( - func_name, tp_bare.get(tpi_bare)) + aip_bare: int = self.Gen.CallGenCtor._find_ctor_type_param_arg_index(func_name, tp_bare.get(tpi_bare)) if aip_bare < 0: aip_bare = int(tpi_bare) ais_bare: sizet = sizet(aip_bare) @@ -423,21 +382,16 @@ class CallGenMixin(CallGenBase.CallGenBase): # 改为 fail-fast 并指明显式标注写法。 ta_bare: str = None if ais_bare < can: - ta_bare = self.Gen.CallGenCtor._infer_generic_ctor_type_arg( - pool, cargs.get(ais_bare), func_name, trans) + ta_bare = self.Gen.CallGenCtor._infer_generic_ctor_type_arg(pool, cargs.get(ais_bare), func_name, trans) if ta_bare is None: # [C②] 仅关键字实参(Box(v=42)):按 __init__ 形参名 # 把该类型形参对应的关键字实参找出来再推断(关键字乱序 # 也能对齐;该形参位已被位置实参占用时返回 -1)。 - kwi_bare: int = self.Gen.CallGenCtor._find_ctor_type_param_kw_arg_index( - func_name, tp_bare.get(tpi_bare), - keywords, kw_count, int(can)) + kwi_bare: int = self.Gen.CallGenCtor._find_ctor_type_param_kw_arg_index(func_name, tp_bare.get(tpi_bare), keywords, kw_count, int(can)) if kwi_bare >= 0: - kwn_bare: rawptr[ast.Keyword] = rawptr[ast.Keyword]( - keywords.get(sizet(kwi_bare))) + 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( - pool, kwn_bare.value, func_name, trans) + ta_bare = self.Gen.CallGenCtor._infer_generic_ctor_type_arg(pool, kwn_bare.value, func_name, trans) if ta_bare is None and ctx_args_bare is not None: # [C①] 注解已显式给出类型实参(如 # s: Stack[int] = Stack())⇒ 用它特化,而非 fail-fast @@ -450,20 +404,18 @@ class CallGenMixin(CallGenBase.CallGenBase): f"请为该实参标注类型或显式标注如 {func_name}[类型](...)", "TypeError") inferred_args_bare.append(ta_bare) - spec_name_bare: str = self.Gen.ClassGenGeneric._specialize_generic_class( - trans, func_name, inferred_args_bare) + spec_name_bare: str = self.Gen.ClassGenGeneric._specialize_generic_class(trans, func_name, inferred_args_bare) if spec_name_bare is not None: - return self.Gen.CallGenCtor._translate_generic_ctor_call( - pool, builder, mod, spec_name_bare, cl, trans, func_name) + return self.Gen.CallGenCtor._translate_generic_ctor_call(pool, builder, mod, spec_name_bare, cl, trans, func_name) # REnum 变体构造检测: ClassName.VariantName(args...) # 如 LLVMType.Int(1) → 构造 LLVMType 的 Int 变体 # 必须在跨模块调用查找之前,否则 ClassName 会被误判为模块名 # 对应 TPC HandlesExprCall.py:585-644 的三条检测路径之一 if cl.func is not None and cl.func.kind() == ast.ASTKind.Attribute: - rc_at: rawptr[ast.Attribute] = rawptr[ast.Attribute](cl.func) + rc_at: ast.Attribute* = ast.Attribute*(cl.func) if rc_at.value is not None and rc_at.value.kind() == ast.ASTKind.Name: - rc_cls_node: rawptr[ast.Name] = rawptr[ast.Name](rc_at.value) + rc_cls_node: ast.Name* = ast.Name*(rc_at.value) if rc_cls_node.id is not None: rc_cls_name: str = rc_cls_node.id # 检查 ClassName 是否是已注册的 REnum 类 @@ -474,8 +426,7 @@ class CallGenMixin(CallGenBase.CallGenBase): if self.Gen.ClassGenEnum._is_renum_class_name(rc_cls_name) != 0 \ or self.Gen.ClassGenEnum._is_renum_by_entry(rc_cls_name) != 0: # 在该 REnum 类中查找变体名 func_name - rc_tag: int = self.Gen.ClassGenEnum._lookup_renum_variant_in_class( - rc_cls_name, func_name) + rc_tag: int = self.Gen.ClassGenEnum._lookup_renum_variant_in_class(rc_cls_name, func_name) if rc_tag < 0: # [D32 fail-fast] 是 REnum 却查不到变体名 ⇒ 变体表不完整, # 继续走外部函数路径会报无关的 "外部函数返回类型未登记"。 @@ -486,9 +437,7 @@ class CallGenMixin(CallGenBase.CallGenBase): f"变体表未注册或变体名不匹配", "NameError") if rc_tag >= 0: - return self.Gen.CallGenCtor._translate_renum_construct( - pool, builder, mod, rc_cls_name, func_name, - rc_tag, cargs, can, trans) + return self.Gen.CallGenCtor._translate_renum_construct(pool, builder, mod, rc_cls_name, func_name, rc_tag, cargs, can, trans) elif rc_at.value is not None and rc_at.value.kind() == ast.ASTKind.Attribute: # 模块限定 REnum 变体构造: mod.Class.Variant(args...) # 如 llvmlite.LLVMType.Struct(...) → 构造 llvmlite 模块 LLVMType 的 Struct 变体。 @@ -511,18 +460,14 @@ class CallGenMixin(CallGenBase.CallGenBase): rc_mq_mod[rc_mq_len] = '\0' rc_mq_imp: int = 1 if trans is not None and trans._imported_modules is not None: - rc_mq_imp = self.Gen.ImportsGen.is_module_imported( - trans._imported_modules, rc_mq_mod) + rc_mq_imp = self.Gen.ImportsGen.is_module_imported(trans._imported_modules, rc_mq_mod) if rc_mq_imp != 0: rc_mq_cls: str = rc_mq_dot + 1 # 检查类名是否是已注册的 REnum 类 if self.Gen.ClassGenEnum._is_renum_class_name(rc_mq_cls) != 0: - rc_mq_tag: int = self.Gen.ClassGenEnum._lookup_renum_variant_in_class( - rc_mq_cls, func_name) + rc_mq_tag: int = self.Gen.ClassGenEnum._lookup_renum_variant_in_class(rc_mq_cls, func_name) if rc_mq_tag >= 0: - return self.Gen.CallGenCtor._translate_renum_construct( - pool, builder, mod, rc_mq_cls, func_name, - rc_mq_tag, cargs, can, trans) + return self.Gen.CallGenCtor._translate_renum_construct(pool, builder, mod, rc_mq_cls, func_name, rc_mq_tag, cargs, can, trans) # async 裸名调用(TPV-M1/M2):普通函数调用 async 函数(如 task(5, 6))→ # 生成 create_(args...) 调用(返回 Ptr(帧),bitcast 成 i8* 供变量存储)。 @@ -535,29 +480,22 @@ class CallGenMixin(CallGenBase.CallGenBase): can_buf: str = pool.alloc(64) if can_buf is not None: viperlib.snprintf(can_buf, 64, "create_%s", func_name) - create_an: str = self.Gen.FuncGenBase._mangle_func_name( - trans, can_buf, 0) - create_fn_an: rawptr[llvmlite.Function] = self.find_func_in_module( - mod, create_an) + create_an: str = self.Gen.FuncGenBase._mangle_func_name(trans, can_buf, 0) + create_fn_an: llvmlite.Function* = self.find_func_in_module(mod, create_an) if create_fn_an is not None: - frame_ty_an: rawptr[llvmlite.LLVMType] = self.Gen.AsyncGen._lookup_coro_frame( - trans, func_name) + frame_ty_an: llvmlite.LLVMType* = self.Gen.AsyncGen._lookup_coro_frame(trans, func_name) if frame_ty_an is not None: - ret_ptr_ty_an: rawptr[llvmlite.LLVMType] = llvmlite.Ptr( - pool, frame_ty_an) - i8_ptr_ty_an: rawptr[llvmlite.LLVMType] = llvmlite.Ptr( - pool, llvmlite.Int8(pool)) + ret_ptr_ty_an: llvmlite.LLVMType* = llvmlite.Ptr(pool, frame_ty_an) + i8_ptr_ty_an: llvmlite.LLVMType* = llvmlite.Ptr(pool, llvmlite.Int8(pool)) # M2:async 调用参数(task(5, 6) → create_task(5, 6)) - arg_head_an: rawptr[llvmlite.Value] = None - arg_tail_an: rawptr[llvmlite.Value] = None + arg_head_an: llvmlite.Value* = None + arg_tail_an: 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: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( - builder, pool, mod, cl.args.get(j_an), - None, 0, trans) + av_an: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, mod, cl.args.get(j_an), None, 0, trans) if av_an is None: av_an = llvmlite.const_int32(pool, 0) av_an.Next = None @@ -568,9 +506,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: rawptr[llvmlite.Value] = llvmlite.build_call( - builder, create_an, arg_head_an, arg_cnt_an, - ret_ptr_ty_an, 0) + child_an: 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: return llvmlite.build_bitcast(builder, child_an, i8_ptr_ty_an) return llvmlite.const_int32(pool, 0) @@ -585,12 +521,12 @@ class CallGenMixin(CallGenBase.CallGenBase): # stubs 在翻译后才注入,翻译时跨模块函数 found_func 通常为 None, # 此时根据函数名推断 includes 库函数的返回类型(如 strchr 返回 i8*) # 如果调用方未传 funcs_ptr/func_count(如 AnnAssign 路径),从 trans 获取 - actual_funcs: rawptr[GenTypes.FuncEntry] = funcs_ptr + actual_funcs: GenTypes.FuncEntry* = funcs_ptr actual_func_count: int = func_count if actual_funcs is None and trans is not None: actual_funcs = trans._funcs actual_func_count = trans._func_count - found_func: rawptr[llvmlite.Function] = None + found_func: llvmlite.Function* = None if cl.func is not None and cl.func.kind() == ast.ASTKind.Name: # 裸名调用:允许精确 + 后缀匹配 # 自定义装饰器 wrapper 重写:原函数名 → __decor_wrap_{name} @@ -601,7 +537,7 @@ class CallGenMixin(CallGenBase.CallGenBase): found_func = self.find_func_in_module(mod, decor_wrap_nm) else: # 本模块已定义函数名的裸名调用:先按裸名在模块函数表(FuncEntry 数组,forward_declare_functions 已把所有模块级函数以 Name=裸名、Func=其 declare/define 登记进 trans._funcs)精确命中,再回落 find_func_in_module 的 LLVM 模块链表扫描。函数表才是同模块函数名的权威注册表(链表扫描漏掉本模块定义时会误走 C 库自动 declare / from_imports 回退)。模块表只含模块级函数(无方法),CExport 条目 Func 名即裸名,复用不改变既有符号语义 - mod_fn_tb: rawptr[llvmlite.Function] = None + mod_fn_tb: llvmlite.Function* = None if actual_funcs is not None: # 同模块函数优先:_funcs 表在 forward_declare_functions 之前 # 已被 LoadDepVpiIntoModule 注入的依赖模块 stub 污染——外来 @@ -613,8 +549,7 @@ class CallGenMixin(CallGenBase.CallGenBase): tbl_owner_sha1: str = None if trans is not None: tbl_owner_sha1 = trans.ModuleSha1 - mod_fn_tb = self.Gen.CallGenLeafKit.find_func_in_table( - actual_funcs, actual_func_count, func_name, tbl_owner_sha1) + mod_fn_tb = self.Gen.CallGenLeafKit.find_func_in_table(actual_funcs, actual_func_count, func_name, tbl_owner_sha1) if mod_fn_tb is not None: found_func = mod_fn_tb else: @@ -665,8 +600,7 @@ class CallGenMixin(CallGenBase.CallGenBase): bn_seg2_cls = 1 bn_seg2_mod: int = 0 if trans is not None and trans._imported_modules is not None: - if self.Gen.ImportsGen.is_module_imported_or_known( - trans._imported_modules, bn_seg2) != 0: + if self.Gen.ImportsGen.is_module_imported_or_known(trans._imported_modules, bn_seg2) != 0: bn_seg2_mod = 1 if bn_seg2_cls != 0 or bn_seg2_mod == 0: found_func = None @@ -687,7 +621,7 @@ class CallGenMixin(CallGenBase.CallGenBase): # 误命中 subprocess.run → call 到错误符号 → 参数错位解引用崩溃, # SysLibTest 0xC0000005 根因)。误命中时拒绝(found_func=None), # 落到下方跨模块模块限定解析用模块自身 SHA1 构造正确符号。 - xm_at: rawptr[ast.Attribute] = rawptr[ast.Attribute](cl.func) + xm_at: ast.Attribute* = ast.Attribute*(cl.func) if xm_at is not None and xm_at.value is not None and trans is not None \ and trans._imported_modules is not None: # 模块路径:单层 Name(syslibtest_impl.run)或嵌套 Attribute @@ -696,15 +630,13 @@ class CallGenMixin(CallGenBase.CallGenBase): # 无限递归栈溢出(SysLibTest 0xC00000FD 根因)。 xm_mod_path: str = None if xm_at.value.kind() == ast.ASTKind.Name: - xm_nm: rawptr[ast.Name] = rawptr[ast.Name](xm_at.value) + xm_nm: ast.Name* = ast.Name*(xm_at.value) if xm_nm.id is not None: xm_mod_path = xm_nm.id elif xm_at.value.kind() == ast.ASTKind.Attribute: - xm_mod_path = self.Gen.ExprGenAttr._attr_module_path_str( - pool, xm_at.value) + xm_mod_path = self.Gen.ExprGenAttr._attr_module_path_str(pool, xm_at.value) if xm_mod_path is not None: - if self.Gen.ImportsGen.is_module_imported_or_known( - trans._imported_modules, xm_mod_path) != 0: + if self.Gen.ImportsGen.is_module_imported_or_known(trans._imported_modules, xm_mod_path) != 0: mod_sha1_chk: str = self._lookup_module_sha1(xm_mod_path) if mod_sha1_chk is None and trans._from_imports is not None: # import X as Y(如 import fat32_diskio as diskio): @@ -714,8 +646,7 @@ class CallGenMixin(CallGenBase.CallGenBase): # (diskio.read 命中 fat32 自身 read)→ call 到错误 # 符号 + 参数错位 + define 被 4 参调用污染(VKernel # llc "instruction expected to be numbered" 根因)。 - mod_sha1_chk = self.Gen.StructGen._resolve_module_sha1( - xm_mod_path, trans._from_imports) + mod_sha1_chk = self.Gen.StructGen._resolve_module_sha1(xm_mod_path, trans._from_imports) if mod_sha1_chk is not None: ff_nm2: str = llvmlite.function_get_name(found_func) if ff_nm2 is not None: @@ -758,8 +689,7 @@ class CallGenMixin(CallGenBase.CallGenBase): is_seg2_cls = 1 is_seg2_mod: int = 0 if trans is not None and trans._imported_modules is not None: - if self.Gen.ImportsGen.is_module_imported_or_known( - trans._imported_modules, seg2) != 0: + if self.Gen.ImportsGen.is_module_imported_or_known(trans._imported_modules, seg2) != 0: is_seg2_mod = 1 if is_seg2_cls != 0 or is_seg2_mod == 0: found_func = None @@ -774,9 +704,9 @@ class CallGenMixin(CallGenBase.CallGenBase): if found_func is None: bi_sha1: str = self._lookup_module_sha1("builtins") if bi_sha1 is not None: - bi_ret: rawptr[llvmlite.LLVMType] = None - bi_p1: rawptr[llvmlite.LLVMType] = None - bi_p2: rawptr[llvmlite.LLVMType] = None + bi_ret: llvmlite.LLVMType* = None + bi_p1: llvmlite.LLVMType* = None + bi_p2: llvmlite.LLVMType* = None if string.strcmp(func_name, "ord") == 0: bi_ret = llvmlite.Int32(pool) bi_p1 = llvmlite.Int8(pool) @@ -797,21 +727,20 @@ class CallGenMixin(CallGenBase.CallGenBase): if bi_sym_buf is not None: viperlib.snprintf(bi_sym_buf, bi_sym_len, "%s.%s", bi_sha1, func_name) bi_sym = bi_sym_buf - bi_decl: rawptr[llvmlite.Function] = llvmlite.create_declare( - pool, mod, bi_sym, bi_ret) + bi_decl: llvmlite.Function* = llvmlite.create_declare(pool, mod, bi_sym, bi_ret) if bi_decl is not None: llvmlite.add_param(pool, bi_decl, bi_p1, "v") if bi_p2 is not None: llvmlite.add_param(pool, bi_decl, bi_p2, "w") found_func = bi_decl # 使用访问器绕过 stub 类型限制 - found_ret_ty: rawptr[llvmlite.LLVMType] = None + found_ret_ty: llvmlite.LLVMType* = None found_params: t.CPtr = None if found_func is not None: found_ret_ty = llvmlite.function_get_ret_ty(found_func) found_params = llvmlite.function_get_params(found_func) if found_ret_ty is not None: - call_ret_ty: rawptr[llvmlite.LLVMType] = found_ret_ty + call_ret_ty: llvmlite.LLVMType* = found_ret_ty else: # found_func=None(跨模块 stub 未注入):先从 vpi stub 返回注解 # 缓存精确获取返回类型(含 tuple[T1,T2] → 匿名结构体,如 @@ -822,7 +751,7 @@ class CallGenMixin(CallGenBase.CallGenBase): # 与定义侧 {i8*, i16} 不匹配 → HandlesAssign 的 tuple 解包 # (依赖 rhs_val.Ty 是 Struct)静默跳过 → 目标变量从未赋值 → # free 未初始化栈垃圾指针崩溃(HashLibTest hqx 段)。 - vpi_ret_ty: rawptr[llvmlite.LLVMType] = None + vpi_ret_ty: llvmlite.LLVMType* = None # 跨模块返回类型解析的来源模块 SHA1:仅在下方 cl.func 是 # Attribute(模块.函数) 分支赋值。必须显式初始化 None——此前声明在 # if 块内、elif mod_ret_sha1 is not None 在外层读取,裸名调用 @@ -832,14 +761,14 @@ class CallGenMixin(CallGenBase.CallGenBase): # (llvmlite/__init__.vp CreateGlobalInt 翻译时 0xC0000005 根因)。 mod_ret_sha1: str = None if cl.func is not None and cl.func.kind() == ast.ASTKind.Attribute: - at_ret: rawptr[ast.Attribute] = rawptr[ast.Attribute](cl.func) + at_ret: ast.Attribute* = ast.Attribute*(cl.func) # 解析调用模块路径:单层(stdlib.free,value 是 Name)与多层 # (w32.win32file.CreatePipe,value 是嵌套 Attribute)都支持。 # 缺失多层路径 → mod_ret_sha1=None → 误走裸名外部函数路径, # fail-fast 误杀可收敛的模块限定调用(CreatePipe 根因)。 mod_path_ret: str = None if at_ret.value is not None and at_ret.value.kind() == ast.ASTKind.Name: - mod_ret_nm: rawptr[ast.Name] = rawptr[ast.Name](at_ret.value) + mod_ret_nm: ast.Name* = ast.Name*(at_ret.value) mod_path_ret = mod_ret_nm.id elif at_ret.value is not None and at_ret.value.kind() == ast.ASTKind.Attribute: mod_path_ret = self.Gen.ExprGenAttr._attr_module_path_str(pool, at_ret.value) @@ -853,14 +782,12 @@ class CallGenMixin(CallGenBase.CallGenBase): fi_from_rt: str = None if trans is not None: fi_from_rt = trans._from_imports - mod_ret_sha1 = self.Gen.StructGen._resolve_module_sha1( - mod_path_ret, fi_from_rt) + mod_ret_sha1 = self.Gen.StructGen._resolve_module_sha1(mod_path_ret, fi_from_rt) if mod_ret_sha1 is not None: # 函数内懒 import:VpiReader imports HandlesExprCall, # 顶层 import 会成环(与 _lookup_method_ret_ty_via_vpi 一致) VpiReader._ensure_vpi_ret_annot_loaded(mod_ret_sha1, self.Gen.CallGenBase.TempDir) - ret_annot_fc: str = VpiReader._lookup_vpi_ret_annot( - mod_ret_sha1, None, func_name) + ret_annot_fc: str = VpiReader._lookup_vpi_ret_annot(mod_ret_sha1, None, func_name) if ret_annot_fc is None: # 包模块 vpi 未命中(函数定义在子模块,如 # fltk.Fl_Input_value 实际在 fltk._cfl_input): @@ -887,15 +814,10 @@ class CallGenMixin(CallGenBase.CallGenBase): rr_buf[rr_len] = '\0' rr_sha1: str = self._lookup_module_sha1(rr_buf) if rr_sha1 is not None: - VpiReader._ensure_vpi_ret_annot_loaded( - rr_sha1, self.Gen.CallGenBase.TempDir) - ret_annot_fc = VpiReader._lookup_vpi_ret_annot( - rr_sha1, None, func_name) + VpiReader._ensure_vpi_ret_annot_loaded(rr_sha1, self.Gen.CallGenBase.TempDir) + ret_annot_fc = VpiReader._lookup_vpi_ret_annot(rr_sha1, None, func_name) if ret_annot_fc is not None: - vpi_ret_ty = VpiReader._resolve_vpi_ret_annot_str( - pool, ret_annot_fc, - llvmlite.Int32(pool), - llvmlite.Ptr(pool, llvmlite.Int8(pool))) + vpi_ret_ty = VpiReader._resolve_vpi_ret_annot_str(pool, ret_annot_fc, llvmlite.Int32(pool), llvmlite.Ptr(pool, llvmlite.Int8(pool))) if vpi_ret_ty is not None: call_ret_ty = vpi_ret_ty elif mod_ret_sha1 is not None: @@ -903,13 +825,11 @@ class CallGenMixin(CallGenBase.CallGenBase): # 且 vpi 返回注解缓存未命中时,仍从依赖模块 text.ll/vpi 精确解析 # 返回类型(对齐 mangled 路径),避免静默默认 i32 截断指针/i64 # (uhci.vp mm.malloc 根因:call i32 @malloc 截断 0xbb69000 → null)。 - cross_ret: rawptr[llvmlite.LLVMType] = None + cross_ret: llvmlite.LLVMType* = None if trans is not None and trans._declare_only == 0: - cross_ret = self._LookupMethodRetTyFromTextLL( - pool, mod_ret_sha1, None, func_name, 1) + cross_ret = self._LookupMethodRetTyFromTextLL(pool, mod_ret_sha1, None, func_name, 1) if cross_ret is None: - cross_ret = self._lookup_method_ret_ty_via_vpi( - pool, mod_ret_sha1, None, func_name) + cross_ret = self._lookup_method_ret_ty_via_vpi(pool, mod_ret_sha1, None, func_name) if cross_ret is not None: call_ret_ty = cross_ret else: @@ -938,11 +858,10 @@ class CallGenMixin(CallGenBase.CallGenBase): and cl.func is not None and cl.func.kind() == ast.ASTKind.Name \ and self.Gen.VarGen.repl_find_func_entry(trans.ReplCtx, func_name) is not None: bare_resolvable = 1 - call_ret_ty = self.Gen.CallGenLib._infer_external_func_ret_ty( - pool, func_name, node, 1 - bare_resolvable) + call_ret_ty = self.Gen.CallGenLib._infer_external_func_ret_ty(pool, func_name, node, 1 - bare_resolvable) if found_func is None: - fp_alloca: rawptr[llvmlite.Value] = None + fp_alloca: llvmlite.Value* = None if cl.func is None or cl.func.kind() == ast.ASTKind.Name: # 闭包内调用捕获的闭包变量(如 _cmd_cd 调 _build_path): # 从 env 读闭包对象指针,不能 lookup_var 跨函数命中父函数 @@ -954,10 +873,9 @@ class CallGenMixin(CallGenBase.CallGenBase): # translate_closure_call 期望 i8** 存储(load 一次得闭包 # 对象指针);load_nonlocal_var 已返回对象指针 → 临时 # 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: rawptr[llvmlite.Value] = self.Gen.VarGen._alloca_at_entry( - builder, i8_ptr_ty_nl) + i8_ty_nl: llvmlite.LLVMType* = llvmlite.Int8(pool) + i8_ptr_ty_nl: llvmlite.LLVMType* = llvmlite.Ptr(pool, i8_ty_nl) + tmp_alloca_nl: 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) fp_alloca = tmp_alloca_nl @@ -974,8 +892,7 @@ class CallGenMixin(CallGenBase.CallGenBase): # t.CPtr 变量(如 f: t.CPtr = make_counter())存的是闭包结构 # {fn_ptr, env_ptr},调用必须提取 env 传参;若按函数指针直接 # call,跳转到闭包结构数据地址崩溃(ClosureCallTest 运行时崩溃)。 - ve_fp: rawptr[GenTypes.VarEntry] = self.Gen.VarGen.lookup_var_entry( - trans.SymTab, func_name) + ve_fp: 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) if fp_annot is not None: @@ -1014,9 +931,7 @@ class CallGenMixin(CallGenBase.CallGenBase): sfn_box = stdlib.malloc(4) if sfn_box is not None: sfn_box[0] = 0 - sfn_val: rawptr[llvmlite.Value] = self.Gen.VarGen.repl_try_session_func_call( - trans, pool, builder, mod, func_name, cargs, int(can), - int(kw_count), node, sfn_box) + sfn_val: llvmlite.Value* = self.Gen.VarGen.repl_try_session_func_call(trans, pool, builder, mod, func_name, cargs, int(can), int(kw_count), node, sfn_box) sfn_handled: int = int(sfn_box[0]) stdlib.free(sfn_box) if sfn_handled != 0: @@ -1027,25 +942,23 @@ class CallGenMixin(CallGenBase.CallGenBase): # 翻译参数并链接 # 有关键字参数且找到函数定义时,按参数名匹配 if kw_count > 0 and found_func is not None and found_params is not None: - return self.Gen.CallGenLib._translate_call_with_kwargs( - pool, builder, mod, func_name, found_func, - cargs, can, keywords, kw_count, trans) + return self.Gen.CallGenLib._translate_call_with_kwargs(pool, builder, mod, func_name, found_func, cargs, can, keywords, kw_count, trans) - head: rawptr[llvmlite.Value] = None - tail: rawptr[llvmlite.Value] = None + head: llvmlite.Value* = None + tail: llvmlite.Value* = None # memcpy 专用: 收集前三个 Value 的独立引用(避免共享 alloca 对象的 Next 被污染) - mc_dst2: rawptr[llvmlite.Value] = None - mc_src2: rawptr[llvmlite.Value] = None - mc_num2: rawptr[llvmlite.Value] = None + mc_dst2: llvmlite.Value* = None + mc_src2: llvmlite.Value* = None + mc_num2: llvmlite.Value* = None for ai in range(can): - arg: rawptr[ast.AST] = cargs.get(ai) + arg: ast.AST* = cargs.get(ai) if arg is not None: # 先取形参类型:单引号单字符字面量(CONST_CHAR)传给 str/指针 # 形参时需物化 1 字符字符串(translate_constant 依据 target_ty # 判定),否则 coerce inttoptr 把字符值当指针(如 '"'=0x22)→ # strlen 访问低地址 ASan 崩溃(二代编 StringTest PyI 生成根因)。 - fp: rawptr[llvmlite.Param] = None - fpty: rawptr[llvmlite.LLVMType] = None + fp: llvmlite.Param* = None + fpty: llvmlite.LLVMType* = None if found_func is not None: fp = llvmlite.function_get_param_head(found_func) fpi: int = 0 @@ -1054,8 +967,7 @@ class CallGenMixin(CallGenBase.CallGenBase): fpi += 1 if fp is not None: fpty = llvmlite.param_get_ty(fp) - arg_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( - builder, pool, mod, arg, None, 0, trans, fpty) + arg_val: 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 未注入)时, # 根据外部函数签名推断期望类型,提升字面量(如 i32→i64) @@ -1064,13 +976,11 @@ class CallGenMixin(CallGenBase.CallGenBase): # 数组实参按 C 语义衰减为元素指针(对齐 TPC # _decay_array_to_ptr),与 _translate_method_call 一致。 if self.Gen.ExprGenBase.is_ptr_type(arg_val.Ty) != 0: - arr_pointee_fc: rawptr[llvmlite.LLVMType] = arg_val.Ty.Pointee + arr_pointee_fc: llvmlite.LLVMType* = arg_val.Ty.Pointee if arr_pointee_fc is not None: match arr_pointee_fc: case llvmlite.LLVMType.Array(arr_et_fc, _): - decayed_fc: rawptr[llvmlite.Value] = llvmlite.build_gep_array( - builder, arr_pointee_fc, arr_et_fc, arg_val, - llvmlite.const_int32(pool, 0)) + decayed_fc: 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: arg_val = decayed_fc case _: @@ -1080,12 +990,10 @@ class CallGenMixin(CallGenBase.CallGenBase): # 参数类型是 C ABI 硬约束(snprintf size 为 i64),不提升 # 则 call(i32 1024) 与 declare(i64 size) 不匹配,且 Win64 # 变参槽高 4 字节残留栈垃圾(clean 日志 0x7ff700000052 根因)。 - kvc_ty: rawptr[llvmlite.LLVMType] = self.Gen.CallGenVa._get_known_vararg_cfunc_param_ty( - pool, func_name, ai) + kvc_ty: llvmlite.LLVMType* = self.Gen.CallGenVa._get_known_vararg_cfunc_param_ty(pool, func_name, ai) if kvc_ty is not None: arg_val = self.Gen.ExprGenBase.coerce_to_type(builder, arg_val, kvc_ty, arg) - ext_param_ty: rawptr[llvmlite.LLVMType] = self.Gen.CallGenLib._get_external_func_param_ty( - pool, func_name, ai) + ext_param_ty: llvmlite.LLVMType* = self.Gen.CallGenLib._get_external_func_param_ty(pool, func_name, ai) if ext_param_ty is not None: val_bits_ap: int = self.Gen.ExprGenBase.get_llvm_type_bits(arg_val.Ty) tgt_bits_ap: int = self.Gen.ExprGenBase.get_llvm_type_bits(ext_param_ty) @@ -1099,8 +1007,7 @@ class CallGenMixin(CallGenBase.CallGenBase): # 修复: CDefine/i32 常量传给 i64 形参未提升,导致 call(i32) 与 define(i64) 不匹配 if fp is not None: if fpty is not None: - arg_val = self.Gen.ExprGenBase.coerce_to_type( - builder, arg_val, fpty, arg, trans) + arg_val = self.Gen.ExprGenBase.coerce_to_type(builder, arg_val, fpty, arg, trans) elif found_func.IsVarArg == 1: # Win64 变参 8 字节槽位:<64 位整数按 i64 传(sext 符号扩展), # f32 提升为 f64。若按原窄类型传,调用点只写 4 字节进 8 字节槽, @@ -1109,12 +1016,11 @@ class CallGenMixin(CallGenBase.CallGenBase): # 对齐 TPC FuncGen/Python-llvmlite 的 ABI 自动提升。 ab_va: int = self.Gen.ExprGenBase.get_llvm_type_bits(arg_val.Ty) af_va: int = self.Gen.ExprGenBase.get_llvm_float_bits(arg_val.Ty) - i64_va: rawptr[llvmlite.LLVMType] = llvmlite.Int64(pool) + i64_va: llvmlite.LLVMType* = llvmlite.Int64(pool) if ab_va != 0 and ab_va < 64: arg_val = llvmlite.build_sext(builder, arg_val, i64_va) elif af_va == 32: - arg_val = llvmlite.build_fpext( - builder, arg_val, llvmlite.Double(pool)) + arg_val = llvmlite.build_fpext(builder, arg_val, llvmlite.Double(pool)) arg_val.Next = None if head is None: head = arg_val @@ -1142,9 +1048,9 @@ class CallGenMixin(CallGenBase.CallGenBase): # 必须先算(模块表查找也要用它限定定义模块 → 见下)。 dfx_callee_sha: str = None if cl.func is not None and cl.func.kind() == ast.ASTKind.Attribute: - dfx_at: rawptr[ast.Attribute] = rawptr[ast.Attribute](cl.func) + dfx_at: ast.Attribute* = ast.Attribute*(cl.func) if dfx_at.value is not None and dfx_at.value.kind() == ast.ASTKind.Name: - dfx_mn: rawptr[ast.Name] = rawptr[ast.Name](dfx_at.value) + dfx_mn: ast.Name* = ast.Name*(dfx_at.value) if dfx_mn.id is not None: dfx_callee_sha = self._lookup_module_sha1(dfx_mn.id) if dfx_callee_sha is None and self.Gen.TypeGenBase is not None: @@ -1159,8 +1065,7 @@ class CallGenMixin(CallGenBase.CallGenBase): # 且本项改动已足以修掉 N17(受限查找命中本模块/同定义模块条目, # Defaults 为 None 或本模块池内 AST)。 if trans is not None and trans._funcs is not None: - df_entry: rawptr[GenTypes.FuncEntry] = self.Gen.CallGenLeafKit.find_func_entry_in_table_owned( - trans._funcs, trans._func_count, func_name, dfx_callee_sha) + df_entry: GenTypes.FuncEntry* = self.Gen.CallGenLeafKit.find_func_entry_in_table_owned(trans._funcs, trans._func_count, func_name, dfx_callee_sha) if df_entry is not None: df_defaults = df_entry.Defaults df_default_count = df_entry.DefaultCount @@ -1170,7 +1075,7 @@ class CallGenMixin(CallGenBase.CallGenBase): # 快照才是跨文件永久存活。同模块命中时 gd_entry 也必须已赋值, # 否则下方 _build_const_from_snapshot 读到未初始化栈垃圾指针崩溃。 # 与 _translate_method_call 的 mdf_gd 无条件查询(L2677)保持一致。 - gd_entry: rawptr[GenTypes.FuncDefaultsEntry] = self.Gen.CallGenLeafKit.find_func_defaults(func_name, dfx_callee_sha) + gd_entry: GenTypes.FuncDefaultsEntry* = self.Gen.CallGenLeafKit.find_func_defaults(func_name, dfx_callee_sha) # 包重导出补查(如 json.write 实际定义在 includes/json/__writer.vp): # AST 侧模块名 'json' 只能解析到包 __init__ 的 SHA1,而默认参数表按 # **定义该函数的模块 SHA1** 登记(_register_global_defaults),于是直接 @@ -1201,7 +1106,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: rawptr[llvmlite.Param] = llvmlite.function_get_param_head(found_func) + dfx_p: 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 @@ -1219,16 +1124,14 @@ 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: rawptr[llvmlite.Value] = None + df_arg_val: 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) + df_arg_val = self.Gen.CallGenLeafKit._build_const_from_snapshot(pool, mod, gd_entry, df_di, trans, builder) if df_arg_val is None and df_defaults is not None: df_defaults_list: list[ast.AST*]* = (list[ast.AST*] | t.CPtr)(uint64(df_defaults)) - df_default_node: rawptr[ast.AST] = df_defaults_list.get(df_di) + df_default_node: ast.AST* = df_defaults_list.get(df_di) if df_default_node is not None: - df_arg_val = self.Gen.ExprGen.translate_value( - builder, pool, mod, df_default_node, None, 0, trans) + df_arg_val = self.Gen.ExprGen.translate_value(builder, pool, mod, df_default_node, None, 0, trans) if df_arg_val is not None: df_arg_val.Next = None if head is None: @@ -1245,7 +1148,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: rawptr[llvmlite.Param] = llvmlite.function_get_param_head(found_func) + fc_p: 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 @@ -1255,14 +1158,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: rawptr[llvmlite.Param] = llvmlite.function_get_param_head(found_func) + fp_z: 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: rawptr[llvmlite.Value] = llvmlite.ConstZero(pool, zero_ty_z) + zero_ty_z: llvmlite.LLVMType* = llvmlite.param_get_ty(fp_z) + zero_val_z: llvmlite.Value* = llvmlite.ConstZero(pool, zero_ty_z) if zero_val_z is not None: zero_val_z.Next = None if head is None: @@ -1310,7 +1213,7 @@ class CallGenMixin(CallGenBase.CallGenBase): # 跨模块函数调用:found_func 为 None 时,检查是否是模块限定调用 # 如 string.strchr(...) → @{sha1_of_string}.strchr if cl.func is not None and cl.func.kind() == ast.ASTKind.Attribute: - xmod_at: rawptr[ast.Attribute] = rawptr[ast.Attribute](cl.func) + xmod_at: ast.Attribute* = ast.Attribute*(cl.func) if xmod_at.value is not None and (xmod_at.value.kind() == ast.ASTKind.Name or xmod_at.value.kind() == ast.ASTKind.Attribute): # 模块路径:单层 Name(string.strchr)或嵌套 Attribute @@ -1321,7 +1224,7 @@ class CallGenMixin(CallGenBase.CallGenBase): # L7344 对齐,SysLibTest 0xC00000FD 根因)。 xmod_path: str = None if xmod_at.value.kind() == ast.ASTKind.Name: - xmod_nm: rawptr[ast.Name] = rawptr[ast.Name](xmod_at.value) + xmod_nm: ast.Name* = ast.Name*(xmod_at.value) if xmod_nm.id is not None: xmod_path = xmod_nm.id else: @@ -1335,8 +1238,7 @@ class CallGenMixin(CallGenBase.CallGenBase): # 静默生成 @{sha1}.func 调用而非报错——违反"找不到 fast-fail"原则。 is_xmod_imported: int = 1 if trans is not None and trans._imported_modules is not None: - is_xmod_imported = self.Gen.ImportsGen.is_module_imported_or_known( - trans._imported_modules, xmod_path) + is_xmod_imported = self.Gen.ImportsGen.is_module_imported_or_known(trans._imported_modules, xmod_path) if is_xmod_imported == 0: err_ni: str = pool.alloc(256) if err_ni is not None: @@ -1399,10 +1301,8 @@ class CallGenMixin(CallGenBase.CallGenBase): orig_has_def: int = 0 if self.Gen.CallGenBase.TempDir is not None \ and self.Gen.CallGenBase.TempDirLen > 0: - VpiReader._ensure_vpi_ret_annot_loaded( - mod_sha1, self.Gen.CallGenBase.TempDir) - if VpiReader._lookup_vpi_ret_annot( - mod_sha1, None, func_name) is not None: + VpiReader._ensure_vpi_ret_annot_loaded(mod_sha1, self.Gen.CallGenBase.TempDir) + if VpiReader._lookup_vpi_ret_annot(mod_sha1, None, func_name) is not None: orig_has_def = 1 if orig_has_def == 0: # 原模块未定义:回退首个候选(旧行为,普通跨模块 @@ -1436,8 +1336,7 @@ class CallGenMixin(CallGenBase.CallGenBase): # 应该立即报错,而不是错误地走 from_imports 查找(会被 star import 回退误导) is_imported_mod: int = 0 if trans is not None and trans._imported_modules is not None: - is_imported_mod = self.Gen.ImportsGen.is_module_imported( - trans._imported_modules, xmod_path) + is_imported_mod = self.Gen.ImportsGen.is_module_imported(trans._imported_modules, xmod_path) if is_imported_mod != 0: # 别名导入(import X as Y):Y 在 _imported_modules 中, # 但 _lookup_module_sha1("Y") 精确匹配失败(mod_arr 只存文件名)。 @@ -1502,8 +1401,7 @@ class CallGenMixin(CallGenBase.CallGenBase): if bare_sha1 is not None: # 别名处理: from X import Y as Z → 调用 Z 时需用 Y 作为源模块函数名 # 例如 from json.__parser import parse as json_parse → 修饰为 SHA1.parse 而非 SHA1.json_parse - bare_orig: str = self.Gen.ImportsGen.lookup_from_import_original( - trans._from_imports, func_name) + bare_orig: str = self.Gen.ImportsGen.lookup_from_import_original(trans._from_imports, func_name) bare_func_name: str = func_name if bare_orig is not None: # bare_orig 指向 from_imports 内部缓冲区,未 null 终止 @@ -1569,7 +1467,7 @@ class CallGenMixin(CallGenBase.CallGenBase): # 别名附加尝试:仅作为 mangled 精确解析前的临时推断(fatal_if_unknown=0)。 # 若 call_name 是 mangled,L1272 起的 text.ll/vpi 精确解析会覆盖并 fail-fast; # 未命中时保持白名单/默认 i32 由后续路径兜底。 - re_inferred_ty: rawptr[llvmlite.LLVMType] = self.Gen.CallGenLib._infer_external_func_ret_ty(pool, orig_func_name, node, 0) + re_inferred_ty: llvmlite.LLVMType* = self.Gen.CallGenLib._infer_external_func_ret_ty(pool, orig_func_name, node, 0) if re_inferred_ty is not None: call_ret_ty = re_inferred_ty # ============================================================ @@ -1606,17 +1504,15 @@ class CallGenMixin(CallGenBase.CallGenBase): if string.strncmp(cf_sha1, trans.ModuleSha1, 16) == 0: is_local_mod = 1 if is_local_mod != 0: - local_fn: rawptr[llvmlite.Function] = self.find_func_in_module(mod, call_name) + local_fn: llvmlite.Function* = self.find_func_in_module(mod, call_name) if local_fn is not None and local_fn.RetTy is not None: call_ret_ty = local_fn.RetTy else: - cf_ret: rawptr[llvmlite.LLVMType] = self._LookupMethodRetTyFromTextLL( - pool, cf_sha1, None, cf_bare, 1) + cf_ret: llvmlite.LLVMType* = self._LookupMethodRetTyFromTextLL(pool, cf_sha1, None, cf_bare, 1) if cf_ret is not None: call_ret_ty = cf_ret else: - cf_vpi: rawptr[llvmlite.LLVMType] = self._lookup_method_ret_ty_via_vpi( - pool, cf_sha1, None, cf_bare) + cf_vpi: llvmlite.LLVMType* = self._lookup_method_ret_ty_via_vpi(pool, cf_sha1, None, cf_bare) if cf_vpi is not None: call_ret_ty = cf_vpi else: @@ -1624,43 +1520,22 @@ class CallGenMixin(CallGenBase.CallGenBase): # 顺序翻译,main.vp 先于其 import 的 mbuddytest.vp(同项目 # 多源文件):本遍保持默认类型,不 fail-fast。 if self._dep_text_ll_exists(pool, cf_sha1) != 0: - self.Gen.TypeGenErr.fatal_error( - node, - f"跨模块函数返回类型无法精确获取(text.ll/vpi 均未命中),默认 i32 会截断指针: {call_name}", - "TypeError") + self.Gen.TypeGenErr.fatal_error(node, f"跨模块函数返回类型无法精确获取(text.ll/vpi 均未命中),默认 i32 会截断指针: {call_name}", "TypeError") stdlib.free(cf_sha1) stdlib.free(cf_bare) # 裸名 C 库函数(string.memset → @memset):实参按标准签名提升 # (第三参 i32 字面量 → i64),再建 declare,保证 call 实参与 # declare/定义宽度一致(B3:process 固化 i32 vs 定义 sizet=i64)。 - head = self.Gen.CallGenLib._promote_clib_call_args( - pool, builder, mod, call_name, head, can) + head = self.Gen.CallGenLib._promote_clib_call_args(pool, builder, mod, call_name, head, can) # 跨模块模块级调用({sha1}.{func}):实参按 vpi 定义侧形参类型 coerce # (整型宽度精确对齐,i32 字面量 → 定义侧 i8/i16),再建 declare → # call 实参 / declare / define 三者宽度一致(B3 同族通用化;反例: # su8250.putchar 定义 (i16,i8) 而调用点字面量 1016=i32 固化宽)。 - head = self.Gen.CallGenLib._coerce_args_to_def_params( - pool, builder, call_name, head, can, cargs, 0, trans) + head = self.Gen.CallGenLib._coerce_args_to_def_params(pool, builder, call_name, head, can, cargs, 0, trans) # 跨模块调用:创建 declare 声明,避免 llc 报 undefined value self._ensure_method_declare(pool, mod, call_name, call_ret_ty, head, can) # 检查被调用函数是否为变长函数(*args),若是则对变长参数进行 C ABI 提升 # (cargs 为本函数参数 AST 链表,self_offset=0 普通函数调用) - is_variadic_call: int = self.Gen.CallGenVa._check_and_promote_variadic_call( - pool, builder, mod, call_name, head, can, cargs, sizet(0), trans) + is_variadic_call: int = self.Gen.CallGenVa._check_and_promote_variadic_call(pool, builder, mod, call_name, head, can, cargs, sizet(0), trans) # try-except:被调函数带 EH 输出参数时,追加输出实参 + 调用后检测异常 - return self.Gen.CallGenLeafKit._emit_eh_guarded_call( - builder, pool, mod, trans, found_func, call_name, head, can, - call_ret_ty, is_variadic_call) - - - - - - - - - - - - - + return self.Gen.CallGenLeafKit._emit_eh_guarded_call(builder, pool, mod, trans, found_func, call_name, head, can, call_ret_ty, is_variadic_call) diff --git a/App/lib/core/Gen/Call/CallGenProp.vp b/App/lib/core/Gen/Call/CallGenProp.vp index 5ea8264..84880cf 100644 --- a/App/lib/core/Gen/Call/CallGenProp.vp +++ b/App/lib/core/Gen/Call/CallGenProp.vp @@ -15,22 +15,10 @@ from . import CallGenBase # ============================================================ # CallGenProp - CallGenMixin 拆分(阶段 B):属性访问(getter/setter/deleter / 静态类调用 / list 内置方法) -# -# 继承 CallGenBase(1 级,TPV self 调用仅支持 1 级父类)。 -# 跨 Mixin 调用统一走 HandlesExprCall 委托(经 _g_gen)。 -# @t.NoVTable:静态绑定。 # ============================================================ -@t.NoVTable -class CallGenProp(CallGenBase.CallGenBase): +novirtual class CallGenProp(CallGenBase.CallGenBase): """属性访问(getter/setter/deleter / 静态类调用 / list 内置方法)""" - # ============================================================ - # _ensure_method_declare - 为跨模块方法调用创建 declare 声明 - # - # 当 found_func 为 None(stub 未注入或跨模块调用)时, - # 在当前模块中创建函数声明,避免 llc 报 undefined value。 - # ============================================================ - # ============================================================ # 属性方法(@property/@x.setter/@x.deleter)与静态/类方法调用辅助 # @@ -49,26 +37,24 @@ class CallGenProp(CallGenBase.CallGenBase): # # call_head/call_count: 已构建好的参数链表(如 getter 只有 obj 一个参数) # ============================================================ - def _translate_property_call(self, pool: rawptr[memhub.MemBuddy], - builder: rawptr[llvmlite.IRBuilder], - mod: rawptr[llvmlite.LLVMModule], + def _translate_property_call(self, pool: memhub.MemBuddy*, + builder: llvmlite.IRBuilder*, + mod: llvmlite.LLVMModule*, class_name: str, method_name: str, - call_head: rawptr[llvmlite.Value], + call_head: llvmlite.Value*, call_count: int, - trans: rawptr[HT.Translator]) -> rawptr[llvmlite.Value]: + trans: HT.Translator*) -> llvmlite.Value*: """翻译属性/静态方法调用,返回 call 结果 Value""" - if pool is None or builder is None or class_name is None or method_name is None: - return None + if pool is None or builder is None or class_name is None or method_name is None: return None # 构造查找名: ClassName.method_name lookup_name: str = pool.alloc(128) - if lookup_name is None: - return None + if lookup_name is None: return None viperlib.snprintf(lookup_name, 128, "%s.%s", class_name, method_name) # 查找函数(精确/后缀匹配) - found_func: rawptr[llvmlite.Function] = self.find_func_in_module(mod, lookup_name) + found_func: llvmlite.Function* = self.find_func_in_module(mod, lookup_name) # 确定调用名 call_name: str = lookup_name @@ -87,26 +73,24 @@ class CallGenProp(CallGenBase.CallGenBase): call_name = mangled_pc # 确定返回类型 - i32_ty: rawptr[llvmlite.LLVMType] = llvmlite.Int32(pool) - call_ret_ty: rawptr[llvmlite.LLVMType] = i32_ty + i32_ty: llvmlite.LLVMType* = llvmlite.Int32(pool) + call_ret_ty: llvmlite.LLVMType* = i32_ty if found_func is not None: - frt: rawptr[llvmlite.LLVMType] = llvmlite.function_get_ret_ty(found_func) + frt: llvmlite.LLVMType* = llvmlite.function_get_ret_ty(found_func) if frt is not None: call_ret_ty = frt else: - sp_ty1: rawptr[llvmlite.LLVMType] = self._special_method_ret_ty(pool, class_name, method_name) + sp_ty1: llvmlite.LLVMType* = self._special_method_ret_ty(pool, class_name, method_name) if sp_ty1 is not None: call_ret_ty = sp_ty1 else: cls_sha1_rt: str = self.Gen.StructGen.get_struct_sha1(class_name) - looked_up_ty: rawptr[llvmlite.LLVMType] = self._LookupMethodRetTyFromTextLL( - pool, cls_sha1_rt, class_name, method_name) + looked_up_ty: llvmlite.LLVMType* = self._LookupMethodRetTyFromTextLL(pool, cls_sha1_rt, class_name, method_name) if looked_up_ty is not None: call_ret_ty = looked_up_ty else: # 精确查找:vpi stub 返回注解缓存(方法定义处,不硬编码白名单) - vpi_ret_ty: rawptr[llvmlite.LLVMType] = self._lookup_method_ret_ty_via_vpi( - pool, cls_sha1_rt, class_name, method_name) + vpi_ret_ty: llvmlite.LLVMType* = self._lookup_method_ret_ty_via_vpi(pool, cls_sha1_rt, class_name, method_name) if vpi_ret_ty is not None: call_ret_ty = vpi_ret_ty else: @@ -122,18 +106,17 @@ class CallGenProp(CallGenBase.CallGenBase): # 一致)。例如 from_long(10) 的 i32 字面量 → i64 形参(v: t.CLong), # 不转换则 call(i32) 与 declare(i64) 不匹配,llc 报参数类型错误。 # 目标函数优先用已找到的 found_func,否则按 mangled 调用名查模块 declare。 - tgt_func_pc: rawptr[llvmlite.Function] = found_func + tgt_func_pc: llvmlite.Function* = found_func 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: 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) + prev_pc: llvmlite.Value* = None + cur_arg_pc: llvmlite.Value* = call_head + cur_param_pc: 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) + param_ty_pc: 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: rawptr[llvmlite.Value] = self.Gen.ExprGenBase.coerce_to_type( - builder, cur_arg_pc, param_ty_pc) + coerced_pc: 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,前驱指向新节点 llvmlite.value_set_next(coerced_pc, cur_arg_pc.Next) @@ -158,17 +141,16 @@ class CallGenProp(CallGenBase.CallGenBase): # ============================================================ # ============================================================ - def _resolve_obj_class_name(self, pool: rawptr[memhub.MemBuddy], - trans: rawptr[HT.Translator], - obj_node: rawptr[ast.AST]) -> str: + def _resolve_obj_class_name(self, pool: memhub.MemBuddy*, + trans: HT.Translator*, + obj_node: ast.AST*) -> str: """解析对象表达式的类名(短名),失败返回 None""" if pool is None or trans is None or obj_node is None: return None if obj_node.kind() == ast.ASTKind.Name: - obj_nm: rawptr[ast.Name] = rawptr[ast.Name](obj_node) + obj_nm: ast.Name* = ast.Name*(obj_node) if obj_nm.id is not None: - var_entry: rawptr[GenTypes.VarEntry] = self.Gen.VarGen.lookup_var_entry( - trans.SymTab, obj_nm.id) + var_entry: 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: # [D32] 取「模块限定名」末段时只按**括号外**的 '.' 切分。 @@ -201,13 +183,13 @@ class CallGenProp(CallGenBase.CallGenBase): # ============================================================ # ============================================================ - def _try_property_getter_attr(self, pool: rawptr[memhub.MemBuddy], - builder: rawptr[llvmlite.IRBuilder], - mod: rawptr[llvmlite.LLVMModule], - at_node: rawptr[ast.Attribute], - obj_ptr: rawptr[llvmlite.Value], - trans: rawptr[HT.Translator], - fallback_class_name: str = None) -> rawptr[llvmlite.Value]: + def _try_property_getter_attr(self, pool: memhub.MemBuddy*, + builder: llvmlite.IRBuilder*, + mod: llvmlite.LLVMModule*, + at_node: ast.Attribute*, + obj_ptr: llvmlite.Value*, + trans: HT.Translator*, + fallback_class_name: str = None) -> llvmlite.Value*: """尝试 property getter 属性访问,返回调用结果 Value;非 getter 返回 None fallback_class_name: 对象表达式非 Name 时从 LLVM 类型解析出的类名兜底。 @@ -224,8 +206,7 @@ class CallGenProp(CallGenBase.CallGenBase): return None # 单参数调用: obj → getter llvmlite.value_set_next(obj_ptr, None) - return self._translate_property_call( - pool, builder, mod, class_name, at_node.attr, obj_ptr, 1, trans) + return self._translate_property_call(pool, builder, mod, class_name, at_node.attr, obj_ptr, 1, trans) # ============================================================ # _try_property_setter — 尝试将 obj.attr = v 翻译为 property setter 调用 # @@ -234,36 +215,29 @@ class CallGenProp(CallGenBase.CallGenBase): # ============================================================ # ============================================================ - def _try_property_setter(self, pool: rawptr[memhub.MemBuddy], - builder: rawptr[llvmlite.IRBuilder], - mod: rawptr[llvmlite.LLVMModule], - target_attr: rawptr[ast.Attribute], - rhs_val: rawptr[llvmlite.Value], - trans: rawptr[HT.Translator]) -> int: + def _try_property_setter(self, pool: memhub.MemBuddy*, + builder: llvmlite.IRBuilder*, + mod: llvmlite.LLVMModule*, + target_attr: ast.Attribute*, + rhs_val: llvmlite.Value*, + trans: HT.Translator*) -> int: """尝试 property setter 赋值,返回 1=已处理(生成调用)""" - if pool is None or builder is None or mod is None or trans is None: - return 0 - if target_attr is None or target_attr.attr is None or rhs_val is None: - return 0 + if pool is None or builder is None or mod is None or trans is None: return 0 + if target_attr is None or target_attr.attr is None or rhs_val is None: return 0 class_name: str = self._resolve_obj_class_name(pool, trans, target_attr.value) - if class_name is None: - return 0 + if class_name is None: return 0 meta: int = self.Gen.ClassGenBase.lookup_method_meta(class_name, target_attr.attr) - if meta & GenTypes.META_PROP_SETTER == 0: - return 0 + if meta & GenTypes.META_PROP_SETTER == 0: return 0 # 翻译对象值(self 参数) - 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 + obj_val: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, mod, target_attr.value, None, 0, trans) + if obj_val is None: return 0 # 构建参数链表: obj → rhs llvmlite.value_set_next(obj_val, None) llvmlite.value_set_next(rhs_val, None) llvmlite.value_set_next(obj_val, rhs_val) # setter 函数名带 $set 后缀 setter_name_buf: str = pool.alloc(128) - if setter_name_buf is None: - return 0 + if setter_name_buf is None: return 0 viperlib.snprintf(setter_name_buf, 128, "%s$set", target_attr.attr) self._translate_property_call(pool, builder, mod, class_name, setter_name_buf, obj_val, 2, trans) @@ -276,32 +250,25 @@ class CallGenProp(CallGenBase.CallGenBase): # ============================================================ # ============================================================ - def _try_property_deleter(self, pool: rawptr[memhub.MemBuddy], - builder: rawptr[llvmlite.IRBuilder], - mod: rawptr[llvmlite.LLVMModule], - target_attr: rawptr[ast.Attribute], - trans: rawptr[HT.Translator]) -> int: + def _try_property_deleter(self, pool: memhub.MemBuddy*, + builder: llvmlite.IRBuilder*, + mod: llvmlite.LLVMModule*, + target_attr: ast.Attribute*, + trans: HT.Translator*) -> int: """尝试 property deleter 删除,返回 1=已处理(生成调用)""" - if pool is None or builder is None or mod is None or trans is None: - return 0 - if target_attr is None or target_attr.attr is None: - return 0 + if pool is None or builder is None or mod is None or trans is None: return 0 + if target_attr is None or target_attr.attr is None: return 0 class_name: str = self._resolve_obj_class_name(pool, trans, target_attr.value) - if class_name is None: - return 0 + if class_name is None: return 0 meta: int = self.Gen.ClassGenBase.lookup_method_meta(class_name, target_attr.attr) - if meta & GenTypes.META_PROP_DELETER == 0: - return 0 + if meta & GenTypes.META_PROP_DELETER == 0: return 0 # 翻译对象值(self 参数) - 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 + obj_val: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, mod, target_attr.value, None, 0, trans) + if obj_val is None: return 0 llvmlite.value_set_next(obj_val, None) # deleter 函数名带 $del 后缀 del_name_buf: str = pool.alloc(128) - if del_name_buf is None: - return 0 + if del_name_buf is None: return 0 viperlib.snprintf(del_name_buf, 128, "%s$del", target_attr.attr) self._translate_property_call(pool, builder, mod, class_name, del_name_buf, obj_val, 1, trans) @@ -314,40 +281,33 @@ class CallGenProp(CallGenBase.CallGenBase): # ============================================================ # ============================================================ - def _translate_static_class_call(self, pool: rawptr[memhub.MemBuddy], - builder: rawptr[llvmlite.IRBuilder], - mod: rawptr[llvmlite.LLVMModule], + def _translate_static_class_call(self, pool: memhub.MemBuddy*, + builder: llvmlite.IRBuilder*, + mod: llvmlite.LLVMModule*, class_name: str, method_name: str, - cl: rawptr[ast.Call], - trans: rawptr[HT.Translator]) -> rawptr[llvmlite.Value]: + cl: ast.Call*, + trans: HT.Translator*) -> llvmlite.Value*: """翻译类名静态/类方法调用,返回 call 结果 Value;非静态/类方法返回 None""" - if pool is None or builder is None or mod is None or trans is None: - return None - if class_name is None or method_name is None or cl is None: - return None + if pool is None or builder is None or mod is None or trans is None: return None + if class_name is None or method_name is None or cl is None: return None meta: int = self.Gen.ClassGenBase.lookup_method_meta(class_name, method_name) is_static: int = 0 is_class: int = 0 - if meta & GenTypes.META_STATIC != 0: - is_static = 1 - if meta & GenTypes.META_CLASS != 0: - is_class = 1 - if is_static == 0 and is_class == 0: - return None + if meta & GenTypes.META_STATIC != 0: is_static = 1 + if meta & GenTypes.META_CLASS != 0: is_class = 1 + if is_static == 0 and is_class == 0: return None # 构建参数链表 - head: rawptr[llvmlite.Value] = None + head: llvmlite.Value* = None total_count: int = 0 # @classmethod: 插入栈上分配的类实例指针作为 cls 参数 if is_class != 0: - struct_ty_cc: rawptr[llvmlite.LLVMType] = self.Gen.StructGen.get_struct_type(class_name) - if struct_ty_cc is None: - return None - cls_ptr: rawptr[llvmlite.Value] = self.Gen.VarGen._alloca_at_entry(builder, struct_ty_cc) - if cls_ptr is None: - return None + struct_ty_cc: llvmlite.LLVMType* = self.Gen.StructGen.get_struct_type(class_name) + if struct_ty_cc is None: return None + cls_ptr: 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) head = cls_ptr total_count = 1 @@ -357,15 +317,12 @@ class CallGenProp(CallGenBase.CallGenBase): can: sizet = 0 if cargs is not None: can = len(cargs) - tail: rawptr[llvmlite.Value] = head + tail: llvmlite.Value* = head for ai in range(can): - arg_node: rawptr[ast.AST] = cargs.get(ai) - if arg_node is None: - continue - arg_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( - builder, pool, mod, arg_node, None, 0, trans) - if arg_val is None: - continue + arg_node: ast.AST* = cargs.get(ai) + if arg_node is None: continue + arg_val: llvmlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, mod, arg_node, None, 0, trans) + if arg_val is None: continue llvmlite.value_set_next(arg_val, None) if head is None: head = arg_val @@ -380,8 +337,7 @@ class CallGenProp(CallGenBase.CallGenBase): # 若此处 return None,调用方回退通用路径把方法名当裸函数解析,生成 # call i32 @new() → 链接 undefined reference(CPythonTest 根因)。 # @classmethod 恒有 cls_ptr(head 非 None),不受影响。 - return self._translate_property_call(pool, builder, mod, class_name, - method_name, head, total_count, trans) + return self._translate_property_call(pool, builder, mod, class_name, method_name, head, total_count, trans) # ============================================================ # _is_list_builtin_method - 判断是否是 list 泛型内置容器方法 # @@ -399,11 +355,9 @@ class CallGenProp(CallGenBase.CallGenBase): def _is_list_builtin_method(self, class_name: str, method_name: str) -> int: """判断 (class_name, method_name) 是否是 list 泛型内置方法""" - if class_name is None or method_name is None: - return 0 + if class_name is None or method_name is None: return 0 # 类名必须以 "list" 开头(list / list[AST | CPtr] 特化名) - if string.strncmp(class_name, "list", 4) != 0: - return 0 + if string.strncmp(class_name, "list", 4) != 0: return 0 # 方法名必须是 list 内置方法集合 if string.strcmp(method_name, "append") == 0: return 1 if string.strcmp(method_name, "get") == 0: return 1 @@ -431,10 +385,10 @@ class CallGenProp(CallGenBase.CallGenBase): return name + pfx if pfx != 0 else name # _resolve_generic_receiver_name:解析接收者实际泛型特化名(IR 真值)——接收者实际 LLVM 结构体类型名比可能退化的注解/注册名可靠,故泛型判定以此为准:去 sha1 前缀取 '[' 前基名,基名是已注册泛型模板时含类型实参 ⇒ 返回实际特化名,无类型实参 ⇒ fail-fast(D25);基名非泛型模板或实际类型不可得 ⇒ 返回 None(调用方各自回退)。与 CallGenCall._translate_method_call 的 D25 分派修复共用本函数(唯一口径) - def _resolve_generic_receiver_name(self, pool: rawptr[memhub.MemBuddy], - struct_ty: rawptr[llvmlite.LLVMType], + def _resolve_generic_receiver_name(self, pool: memhub.MemBuddy*, + struct_ty: llvmlite.LLVMType*, method_name: str, - cl: rawptr[ast.Call]) -> str: + cl: ast.Call*) -> str: """返回实际泛型特化名(去 sha1)或 None;裸泛型基类 fail-fast""" if struct_ty is None: return None @@ -466,29 +420,27 @@ class CallGenProp(CallGenBase.CallGenBase): f"方法 '{method_name}' 的接收者实际结构体类型是裸泛型基类 " f"'{short_nm}*'(丢失类型实参),元素类型未知;" f"禁止静默按默认元素类型处理(元素按 i32 处理会截断指针)," - f"请让该变量的注解/类型带上实参(如 list[rawptr[ast.AST]])", + f"请让该变量的注解/类型带上实参(如 list[ast.AST*])", "TypeError") return None # _is_list_builtin_receiver:基于接收者实际类型判定 list 内建方法,判据与 _resolve_generic_receiver_name 同源——优先采用接收者实际 LLVM 结构体类型名(去 sha1 判基名),不可得时回退注解名/注册名判定。返回 1=list 内置方法 / 0=非 - def _is_list_builtin_receiver(self, pool: rawptr[memhub.MemBuddy], - recv_val: rawptr[llvmlite.Value], + def _is_list_builtin_receiver(self, pool: memhub.MemBuddy*, + recv_val: llvmlite.Value*, fallback_name: str, method_name: str, - cl: rawptr[ast.Call]) -> int: + cl: ast.Call*) -> int: """基于接收者实际类型判定 list 内建方法(实际类型不可得回退注解名)""" - sty: rawptr[llvmlite.LLVMType] = \ + sty: llvmlite.LLVMType* = \ self.Gen.StructGen.get_struct_type_from_value(recv_val) if sty is not None: ty_nm: str = llvmlite.get_struct_name(sty) if ty_nm is not None and ty_nm[0] != '\0': # 泛型模板接收者:裸基类 fail-fast;含实参用实际特化名 - act_nm: str = self._resolve_generic_receiver_name( - pool, sty, method_name, cl) + act_nm: str = self._resolve_generic_receiver_name(pool, sty, method_name, cl) if act_nm is not None: return self._is_list_builtin_method(act_nm, method_name) # 非泛型模板接收者:用去 sha1 后的实际短名判定(不复用退化注解名) - return self._is_list_builtin_method( - self._strip_module_sha1_prefix(ty_nm), method_name) + return self._is_list_builtin_method(self._strip_module_sha1_prefix(ty_nm), method_name) # 实际类型不可得 → 回退注解名/注册名判定(信息缺失下的既有行为) return self._is_list_builtin_method(fallback_name, method_name) \ No newline at end of file diff --git a/App/lib/core/Gen/Call/CallGenVa.vp b/App/lib/core/Gen/Call/CallGenVa.vp index 640786d..bfb6d32 100644 --- a/App/lib/core/Gen/Call/CallGenVa.vp +++ b/App/lib/core/Gen/Call/CallGenVa.vp @@ -11,13 +11,8 @@ from . import CallGenBase # ============================================================ # CallGenVa - CallGenMixin 拆分(阶段 B):va_arg 变长参数(start/arg/end / 变长调用提升) -# -# 继承 CallGenBase(1 级,TPV self 调用仅支持 1 级父类)。 -# 跨 Mixin 调用统一走 HandlesExprCall 委托(经 _g_gen)。 -# @t.NoVTable:静态绑定。 # ============================================================ -@t.NoVTable -class CallGenVa(CallGenBase.CallGenBase): +novirtual class CallGenVa(CallGenBase.CallGenBase): """va_arg 变长参数(start/arg/end / 变长调用提升)""" # ============================================================ @@ -27,33 +22,32 @@ class CallGenVa(CallGenBase.CallGenBase): # _translate_method 在含 raise 的函数签名末尾注入(main 除外)。 # ============================================================ - def _va_arg_get_alloca_ptr(self, pool: rawptr[memhub.MemBuddy], - builder: rawptr[llvmlite.IRBuilder], - mod: rawptr[llvmlite.LLVMModule], - arg_node: rawptr[ast.AST], + def _va_arg_get_alloca_ptr(self, pool: memhub.MemBuddy*, + builder: llvmlite.IRBuilder*, + mod: llvmlite.LLVMModule*, + arg_node: ast.AST*, funcs_ptr: t.CPtr, func_count: int, - trans: rawptr[HT.Translator]) -> rawptr[llvmlite.Value]: + trans: HT.Translator*) -> llvmlite.Value*: """获取 va_list 变量的 alloca 指针(不 load) va_arg/va_start/va_end 需要的是 va_list 对象的地址(alloca 指针), 而非 va_list 的值。若 arg_node 是 Name,查符号表获取 alloca; 否则用 translate_value 翻译(调用者负责确保传入的是指针)。 """ - if arg_node is None: - return None + if arg_node is None: return None # Name 节点:直接查符号表获取 alloca 指针(不 load) if arg_node.kind() == ast.ASTKind.Name: - nm: rawptr[ast.Name] = rawptr[ast.Name](arg_node) + nm: ast.Name* = ast.Name*(arg_node) if nm.id is not None: - alloca: rawptr[llvmlite.Value] = self.Gen.VarGen.lookup_var(trans.SymTab, nm.id) + alloca: llvmlite.Value* = self.Gen.VarGen.lookup_var(trans.SymTab, nm.id) if alloca is not None: return alloca # 回退:translate_value(可能返回 load 后的值,仅适用于已是指针的情况) return self.Gen.ExprGen.translate_value(builder, pool, mod, arg_node, funcs_ptr, func_count, trans) - def _resolve_va_arg_type(self, pool: rawptr[memhub.MemBuddy], - type_node: rawptr[ast.AST], - trans: rawptr[HT.Translator]) -> rawptr[llvmlite.LLVMType]: + def _resolve_va_arg_type(self, pool: memhub.MemBuddy*, + type_node: ast.AST*, + trans: HT.Translator*) -> llvmlite.LLVMType*: """解析 va_arg/arg 的类型参数为 LLVMType 支持的类型表达式: @@ -67,22 +61,21 @@ class CallGenVa(CallGenBase.CallGenBase): if type_node is None: return llvmlite.Int32(pool) # 使用 HandlesType.resolve_annotation_type 解析类型表达式 - resolved: rawptr[llvmlite.LLVMType] = self.Gen.TypeGenResolve.resolve_annotation_type( - pool, type_node, trans._imported_modules, trans._from_imports, trans, 0) + resolved: llvmlite.LLVMType* = self.Gen.TypeGenResolve.resolve_annotation_type(pool, type_node, trans._imported_modules, trans._from_imports, trans, 0) if resolved is not None: return resolved # 类型节点存在但解析失败:fail-fast,绝不回退 i32(会按错宽度读变参槽位) 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: rawptr[llvmlite.IRBuilder], - mod: rawptr[llvmlite.LLVMModule], - cl: rawptr[ast.Call], + def _translate_va_arg_sugar(self, pool: memhub.MemBuddy*, + builder: llvmlite.IRBuilder*, + mod: llvmlite.LLVMModule*, + cl: ast.Call*, cargs: list[ast.AST*]*, can: sizet, funcs_ptr: t.CPtr, func_count: int, - trans: rawptr[HT.Translator]) -> rawptr[llvmlite.Value]: + trans: HT.Translator*) -> llvmlite.Value*: """va_arg(ap, type) / va_arg(ap) → %N = va_arg , 生成 LLVM va_arg 指令,从 va_list 读取下一个变长参数。 @@ -93,28 +86,27 @@ class CallGenVa(CallGenBase.CallGenBase): # 第一个参数:va_list(求值为 i8* 地址值,对齐 TPC _HandleVaArgLlvm) # 当前函数 *args:translate_value 经 vararg 名映射直接返回 va_list 缓冲区地址; # 转发场景(sprintf → vsnprintf 的 ap 参数):translate_value load 参数得到地址值。 - ap_node: rawptr[ast.AST] = cargs.get(0) - ap_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( - builder, pool, mod, ap_node, None, 0, trans) + ap_node: ast.AST* = cargs.get(0) + ap_val: 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: rawptr[llvmlite.Value] = ap_val + ap_ptr: llvmlite.Value* = ap_val # 第二个参数:目标类型(可选,默认 i32) - arg_ty: rawptr[llvmlite.LLVMType] = llvmlite.Int32(pool) + arg_ty: llvmlite.LLVMType* = llvmlite.Int32(pool) if can >= 2: - type_node: rawptr[ast.AST] = cargs.get(1) + type_node: ast.AST* = cargs.get(1) arg_ty = self._resolve_va_arg_type(pool, type_node, trans) # Win64 变参槽位为 8 字节:<64 位整数按 i64 读取(对齐 TPC emit_va_arg L72-73), # 再 trunc 回目标宽度——否则返回 8 字节含高位垃圾,%d/%i 语义错误 # (viperlib vsnprintf %d 非 long 分支 `int64(va_arg(ap, int))` # 编译成直接 va_arg i64,高 32 位未定义 → 负数当大正数 A6 根因)。 - read_ty: rawptr[llvmlite.LLVMType] = arg_ty + read_ty: llvmlite.LLVMType* = arg_ty 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: rawptr[llvmlite.Value] = llvmlite.build_va_arg(builder, ap_ptr, read_ty) + va_raw: 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 @@ -122,15 +114,15 @@ 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: rawptr[llvmlite.IRBuilder], - mod: rawptr[llvmlite.LLVMModule], - cl: rawptr[ast.Call], + def _translate_arg_sugar(self, pool: memhub.MemBuddy*, + builder: llvmlite.IRBuilder*, + mod: llvmlite.LLVMModule*, + cl: ast.Call*, cargs: list[ast.AST*]*, can: sizet, funcs_ptr: t.CPtr, func_count: int, - trans: rawptr[HT.Translator]) -> rawptr[llvmlite.Value]: + trans: HT.Translator*) -> llvmlite.Value*: """arg(type) → %N = va_arg , 使用当前函数的隐式 va_list(trans._va_list_ptr), @@ -140,32 +132,32 @@ class CallGenVa(CallGenBase.CallGenBase): return llvmlite.const_int32(pool, 0) # 第一个参数:目标类型(可选,默认 i32) - arg_ty: rawptr[llvmlite.LLVMType] = llvmlite.Int32(pool) + arg_ty: llvmlite.LLVMType* = llvmlite.Int32(pool) if can >= 1 and cargs is not None: - type_node: rawptr[ast.AST] = cargs.get(0) + type_node: ast.AST* = cargs.get(0) arg_ty = self._resolve_va_arg_type(pool, type_node, trans) # Win64 变参槽位为 8 字节:<64 位整数按 i64 读取(与 _translate_va_arg_sugar 一致), # 再 trunc 回目标宽度(%d/%i 高位垃圾 A6 修复,见 _translate_va_arg_sugar) - read_ty: rawptr[llvmlite.LLVMType] = arg_ty + read_ty: llvmlite.LLVMType* = arg_ty 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: rawptr[llvmlite.Value] = llvmlite.build_va_arg(builder, trans._va_list_ptr, read_ty) + arg_raw: 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) # 生成 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: rawptr[llvmlite.IRBuilder], - mod: rawptr[llvmlite.LLVMModule], + def _translate_va_start_sugar(self, pool: memhub.MemBuddy*, + builder: llvmlite.IRBuilder*, + mod: llvmlite.LLVMModule*, cargs: list[ast.AST*]*, can: sizet, funcs_ptr: t.CPtr, func_count: int, - trans: rawptr[HT.Translator]) -> rawptr[llvmlite.Value]: + trans: HT.Translator*) -> llvmlite.Value*: """va_start(ap, last_arg) → call void @llvm.va_start(i8* %ap) 初始化 va_list。第二个参数 last_arg 在 LLVM intrinsic 中不使用(C 宏兼容)。 @@ -174,30 +166,29 @@ class CallGenVa(CallGenBase.CallGenBase): return llvmlite.const_int32(pool, 0) # 第一个参数:va_list 指针(获取 alloca,不 load) - ap_node: rawptr[ast.AST] = cargs.get(0) - ap_ptr: rawptr[llvmlite.Value] = self._va_arg_get_alloca_ptr( - pool, builder, mod, ap_node, funcs_ptr, func_count, trans) + ap_node: ast.AST* = cargs.get(0) + ap_ptr: 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) # 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: rawptr[llvmlite.Value] = llvmlite.build_bitcast(builder, ap_ptr, i8_ptr_ty_vs) + i8_ty_vs: llvmlite.LLVMType* = llvmlite.Int8(pool) + i8_ptr_ty_vs: llvmlite.LLVMType* = llvmlite.Ptr(pool, i8_ty_vs) + ap_i8: llvmlite.Value* = llvmlite.build_bitcast(builder, ap_ptr, i8_ptr_ty_vs) if ap_i8 is None: return llvmlite.const_int32(pool, 0) - void_ty_vs: rawptr[llvmlite.LLVMType] = llvmlite.Void(pool) + void_ty_vs: llvmlite.LLVMType* = llvmlite.Void(pool) 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: rawptr[llvmlite.IRBuilder], - mod: rawptr[llvmlite.LLVMModule], + def _translate_va_end_sugar(self, pool: memhub.MemBuddy*, + builder: llvmlite.IRBuilder*, + mod: llvmlite.LLVMModule*, cargs: list[ast.AST*]*, can: sizet, funcs_ptr: t.CPtr, func_count: int, - trans: rawptr[HT.Translator]) -> rawptr[llvmlite.Value]: + trans: HT.Translator*) -> llvmlite.Value*: """va_end(ap) → call void @llvm.va_end(i8* %ap) 清理 va_list。在大多数平台上是 no-op,但调用它是良好的 C ABI 习惯。 @@ -206,28 +197,27 @@ class CallGenVa(CallGenBase.CallGenBase): return llvmlite.const_int32(pool, 0) # 第一个参数:va_list 指针(获取 alloca,不 load) - ap_node: rawptr[ast.AST] = cargs.get(0) - ap_ptr: rawptr[llvmlite.Value] = self._va_arg_get_alloca_ptr( - pool, builder, mod, ap_node, funcs_ptr, func_count, trans) + ap_node: ast.AST* = cargs.get(0) + ap_ptr: 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) # 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: rawptr[llvmlite.Value] = llvmlite.build_bitcast(builder, ap_ptr, i8_ptr_ty_ve) + i8_ty_ve: llvmlite.LLVMType* = llvmlite.Int8(pool) + i8_ptr_ty_ve: llvmlite.LLVMType* = llvmlite.Ptr(pool, i8_ty_ve) + ap_i8: llvmlite.Value* = llvmlite.build_bitcast(builder, ap_ptr, i8_ptr_ty_ve) if ap_i8 is None: return llvmlite.const_int32(pool, 0) - void_ty_ve: rawptr[llvmlite.LLVMType] = llvmlite.Void(pool) + void_ty_ve: llvmlite.LLVMType* = llvmlite.Void(pool) llvmlite.build_call(builder, "llvm.va_end", ap_i8, 1, void_ty_ve, 0) return llvmlite.const_int32(pool, 0) - def _get_func_fixed_param_count(self, func: rawptr[llvmlite.Function]) -> int: + def _get_func_fixed_param_count(self, func: llvmlite.Function*) -> int: """获取函数的固定参数数量(遍历 Params 链表)""" if func is None: return 0 count: int = 0 - param: rawptr[llvmlite.Param] = llvmlite.function_get_param_head(func) + param: llvmlite.Param* = llvmlite.function_get_param_head(func) while param is not None: count += 1 param = llvmlite.param_get_next(param) @@ -250,8 +240,8 @@ class CallGenVa(CallGenBase.CallGenBase): return 2 return -1 - def _get_known_vararg_cfunc_param_ty(self, pool: rawptr[memhub.MemBuddy], - name: str, idx: int) -> rawptr[llvmlite.LLVMType]: + def _get_known_vararg_cfunc_param_ty(self, pool: memhub.MemBuddy*, + name: str, idx: int) -> llvmlite.LLVMType*: """已知变参 C 库函数第 idx 个固定参数类型(变参位置/未知返回 None) 固定参数类型是 C ABI 硬约束(snprintf 的 size 为 i64),stub 未注入 @@ -259,8 +249,8 @@ class CallGenVa(CallGenBase.CallGenBase): """ if pool is None or name is None or idx < 0: return None - i8_ptr_kv: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, llvmlite.Int8(pool)) - i64_kv: rawptr[llvmlite.LLVMType] = llvmlite.Int64(pool) + i8_ptr_kv: llvmlite.LLVMType* = llvmlite.Ptr(pool, llvmlite.Int8(pool)) + i64_kv: llvmlite.LLVMType* = llvmlite.Int64(pool) if string.strcmp(name, "snprintf") == 0: if idx == 0: return i8_ptr_kv @@ -276,15 +266,15 @@ class CallGenVa(CallGenBase.CallGenBase): return i8_ptr_kv return None return None - def _check_and_promote_variadic_call(self, pool: rawptr[memhub.MemBuddy], - builder: rawptr[llvmlite.IRBuilder], - mod: rawptr[llvmlite.LLVMModule], + def _check_and_promote_variadic_call(self, pool: memhub.MemBuddy*, + builder: llvmlite.IRBuilder*, + mod: llvmlite.LLVMModule*, call_name: str, - head: rawptr[llvmlite.Value], + head: llvmlite.Value*, can: sizet, arg_nodes: list[ast.AST*]* = None, self_offset: int = 0, - trans: rawptr[HT.Translator] = None) -> int: + trans: HT.Translator* = None) -> int: """检查被调用函数是否为变长函数,若是则对变长参数进行 C ABI 提升 返回: is_variadic (1=变长调用, 0=普通调用) @@ -297,7 +287,7 @@ class CallGenVa(CallGenBase.CallGenBase): if mod is None or call_name is None or head is None: return 0 # 查找函数对象 - func: rawptr[llvmlite.Function] = self.find_func_in_module(mod, call_name) + func: llvmlite.Function* = self.find_func_in_module(mod, call_name) fixed_count: int = -1 if func is not None and func.IsVarArg == 1: fixed_count = self._get_func_fixed_param_count(func) @@ -312,8 +302,8 @@ class CallGenVa(CallGenBase.CallGenBase): return 1 # 遍历到第 fixed_count 个节点(固定参数的最后一个) - cur: rawptr[llvmlite.Value] = head - prev: rawptr[llvmlite.Value] = None + cur: llvmlite.Value* = head + prev: llvmlite.Value* = None idx: int = 0 while cur is not None and idx < fixed_count: prev = cur @@ -322,12 +312,12 @@ class CallGenVa(CallGenBase.CallGenBase): # cur 指向第 fixed_count+1 个节点(第一个变长参数) # 对变长参数进行 C ABI 提升 - i32_ty_promote: rawptr[llvmlite.LLVMType] = llvmlite.Int32(pool) - double_ty_promote: rawptr[llvmlite.LLVMType] = llvmlite.Double(pool) + i32_ty_promote: llvmlite.LLVMType* = llvmlite.Int32(pool) + double_ty_promote: llvmlite.LLVMType* = llvmlite.Double(pool) v_idx: int = fixed_count while cur is not None: - next_node: rawptr[llvmlite.Value] = cur.Next - promoted: rawptr[llvmlite.Value] = cur + next_node: llvmlite.Value* = cur.Next + promoted: 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: @@ -338,7 +328,7 @@ class CallGenVa(CallGenBase.CallGenBase): if arg_nodes is not None and trans is not None: ast_idx_va: int = v_idx - self_offset if ast_idx_va >= 0 and ast_idx_va < len(arg_nodes): - an_va: rawptr[ast.AST] = arg_nodes.get(ast_idx_va) + an_va: ast.AST* = arg_nodes.get(ast_idx_va) if an_va is not None: if self.Gen.ExprGenOps._node_type_unsigned(pool, an_va, trans) != 0: is_u_va = 1 @@ -371,15 +361,15 @@ class CallGenVa(CallGenBase.CallGenBase): # 调用方必须写满 8 字节槽,否则高 4 字节残留旧栈数据,%d 读到 # 0x7ff700000052 类垃圾(clean 日志根因;对齐 CallGenMixin # L798-811 的 found_func.IsVarArg 提升)。 - i64_ty_promote: rawptr[llvmlite.LLVMType] = llvmlite.Int64(pool) + i64_ty_promote: 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: rawptr[llvmlite.Value] = None + promoted_va2: 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 if ast_idx_va2 >= 0 and ast_idx_va2 < len(arg_nodes): - an_va2: rawptr[ast.AST] = arg_nodes.get(ast_idx_va2) + an_va2: ast.AST* = arg_nodes.get(ast_idx_va2) if an_va2 is not None: if self.Gen.ExprGenOps._node_type_unsigned(pool, an_va2, trans) != 0: is_u_va2 = 1 diff --git a/App/lib/core/Gen/Call/CallGenVt.vp b/App/lib/core/Gen/Call/CallGenVt.vp index fda94ab..7d0cfe0 100644 --- a/App/lib/core/Gen/Call/CallGenVt.vp +++ b/App/lib/core/Gen/Call/CallGenVt.vp @@ -13,93 +13,68 @@ from . import CallGenBase # ============================================================ # CallGenVt - CallGenMixin 拆分(阶段 B):vtable 槽位写入 -# -# 继承 CallGenBase(1 级,TPV self 调用仅支持 1 级父类)。 -# 跨 Mixin 调用统一走 HandlesExprCall 委托(经 _g_gen)。 -# @t.NoVTable:静态绑定。 # ============================================================ -@t.NoVTable -class CallGenVt(CallGenBase.CallGenBase): +novirtual class CallGenVt(CallGenBase.CallGenBase): """vtable 槽位写入""" # _write_vtable_slot / _write_vtable_attr:把模块级函数指针写入对象 vtable 的方法槽位(devfs 驱动注册模式,对齐 TPC HandlesAssign.py L905-949 写时复制)——vtable 方法不是数据字段,get_attribute_ptr 查不到;对象 vtable 仍指向类默认 vtable 时先复制一份(internal 全局 + llvm.memcpy)并让对象指向副本,再 GEP method_index 槽位 store i8*。多次写入互不覆盖 # ============================================================ - def _write_vtable_slot(self, pool: rawptr[memhub.MemBuddy], - builder: rawptr[llvmlite.IRBuilder], - mod: rawptr[llvmlite.LLVMModule], - obj_ptr: rawptr[llvmlite.Value], + def _write_vtable_slot(self, pool: memhub.MemBuddy*, + builder: llvmlite.IRBuilder*, + mod: llvmlite.LLVMModule*, + obj_ptr: llvmlite.Value*, class_name: str, method_index: int, - func_val: rawptr[llvmlite.Value], - trans: rawptr[HT.Translator]) -> int: + func_val: llvmlite.Value*, + trans: HT.Translator*) -> int: """生成 vtable 槽位写入(写时复制),成功返回 1""" - if pool is None or builder is None or mod is None or trans is None: - return 0 - if obj_ptr is None or class_name is None or func_val is None: - return 0 - if method_index < 0 or trans._cur_func is None: - return 0 - i8_ty: rawptr[llvmlite.LLVMType] = llvmlite.Int8(pool) - if i8_ty is None: - return 0 - i8_ptr_ty: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, i8_ty) - if i8_ptr_ty is None: - return 0 - i8_ptr_ptr_ty: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, i8_ptr_ty) - if i8_ptr_ptr_ty is None: - return 0 + if pool is None or builder is None or mod is None or trans is None: return 0 + if obj_ptr is None or class_name is None or func_val is None: return 0 + if method_index < 0 or trans._cur_func is None: return 0 + i8_ty: llvmlite.LLVMType* = llvmlite.Int8(pool) + if i8_ty is None: return 0 + i8_ptr_ty: llvmlite.LLVMType* = llvmlite.Ptr(pool, i8_ty) + if i8_ptr_ty is None: return 0 + i8_ptr_ptr_ty: llvmlite.LLVMType* = llvmlite.Ptr(pool, i8_ptr_ty) + if i8_ptr_ptr_ty is None: return 0 method_count: int = self.Gen.StructGen.get_vtable_method_count(class_name) - if method_count <= 0: - return 0 + if method_count <= 0: return 0 # 构造 vtable 类型 { i8*, i8*, ... } - vt_first: rawptr[llvmlite.Function] = None - vt_prev: rawptr[llvmlite.Function] = None + vt_first: llvmlite.Function* = None + vt_prev: llvmlite.Function* = None for vi in range(method_count): - pn: rawptr[llvmlite.Function] = llvmlite.new_param_node(pool, i8_ptr_ty) - if pn is None: - continue + pn: llvmlite.Function* = llvmlite.new_param_node(pool, i8_ptr_ty) + if pn is None: continue if vt_first is None: vt_first = pn if vt_prev is not None: llvmlite.paramnode_set_next(vt_prev, pn) vt_prev = pn - vtable_ty: rawptr[llvmlite.LLVMType] = llvmlite.Struct(pool, vt_first, method_count, None) + vtable_ty: llvmlite.LLVMType* = llvmlite.Struct(pool, vt_first, method_count, None) if vtable_ty is None: return 0 # 对象 vtable 槽位(对象头 → i8**,vtable 指针总是第一个字段) - vtable_slot: rawptr[llvmlite.Value] = llvmlite.build_bitcast( - builder, obj_ptr, i8_ptr_ptr_ty) - if vtable_slot is None: - return 0 - vtable_ptr: rawptr[llvmlite.Value] = llvmlite.build_load( - builder, i8_ptr_ty, vtable_slot) - if vtable_ptr is None: - return 0 + vtable_slot: llvmlite.Value* = llvmlite.build_bitcast(builder, obj_ptr, i8_ptr_ptr_ty) + if vtable_slot is None: return 0 + vtable_ptr: llvmlite.Value* = llvmlite.build_load(builder, i8_ptr_ty, vtable_slot) + if vtable_ptr is None: return 0 # 类默认 vtable 地址(比较用) - 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: rawptr[llvmlite.Value] = llvmlite.build_icmp( - builder, llvmlite.ICMP_EQ, vtable_ptr, class_vt) - if cmp_vt is None: - return 0 + class_vt: 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* = llvmlite.build_icmp(builder, llvmlite.ICMP_EQ, vtable_ptr, class_vt) + if cmp_vt is None: return 0 # 块名唯一化(create_block 不自动编号;同函数多次 vtable 写入(如 # devfs open/close/read/write 连续赋值)同名 label 冲突) vtc3: int = trans._label_counter trans._label_counter = vtc3 + 1 vt_bb_buf3: str = pool.alloc(64) - if vt_bb_buf3 is None: - return 0 + if vt_bb_buf3 is None: return 0 viperlib.snprintf(vt_bb_buf3, 64, "vt.copy.%d", vtc3) - vt_copy_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block( - pool, trans._cur_func, vt_bb_buf3) + 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: 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 + 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 llvmlite.build_cond_br(builder, cmp_vt, vt_copy_bb, vt_skip_bb) # copy 块:创建 internal 副本全局(zeroinit)+ memcpy + 对象指向副本 llvmlite.position_at_end(builder, vt_copy_bb) @@ -108,8 +83,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: rawptr[llvmlite.GlobalVariable] = llvmlite.new_global_variable( - pool, vcopy_buf, vtable_ty) + vcopy_gv: llvmlite.GlobalVariable* = llvmlite.new_global_variable(pool, vcopy_buf, vtable_ty) if vcopy_gv is not None: llvmlite.module_add_global(mod, vcopy_gv) vcopy_gv.Linkage = None @@ -123,11 +97,9 @@ class CallGenVt(CallGenBase.CallGenBase): vcopy_ref_nm = vcopy_buf else: viperlib.snprintf(vcopy_ref_nm, 272, "@%s", vcopy_buf) - vcopy_ref: rawptr[llvmlite.Value] = llvmlite.SSAValue( - pool, llvmlite.Ptr(pool, vtable_ty), vcopy_ref_nm) + vcopy_ref: llvmlite.Value* = llvmlite.SSAValue(pool, llvmlite.Ptr(pool, vtable_ty), vcopy_ref_nm) if vcopy_ref is not None: - vcopy_i8: rawptr[llvmlite.Value] = llvmlite.build_bitcast( - builder, vcopy_ref, i8_ptr_ty) + vcopy_i8: llvmlite.Value* = llvmlite.build_bitcast(builder, vcopy_ref, i8_ptr_ty) if vcopy_i8 is not None: # ConstInt 的 name 必须是数字文本(如 "56"),不能是 # 标识符 "vtsz"——参数经 Name 原样输出,裸名 vtsz 无 % @@ -135,78 +107,59 @@ 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: rawptr[llvmlite.Value] = llvmlite.ConstInt( - pool, llvmlite.Int64(pool), method_count * 8, vtsz_buf) + vt_size: 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( - pool, builder, mod, vcopy_i8, class_vt, vt_size) + self.Gen.CallGenLib._emit_llvm_memcpy_intrinsic(pool, builder, mod, vcopy_i8, class_vt, vt_size) llvmlite.build_store(builder, vcopy_i8, vtable_slot) llvmlite.build_br(builder, vt_skip_bb) # skip 块:reload vtable → GEP 槽位 → store 函数指针(i8*) llvmlite.position_at_end(builder, vt_skip_bb) - vt_ptr2: rawptr[llvmlite.Value] = llvmlite.build_load( - builder, i8_ptr_ty, vtable_slot) - if vt_ptr2 is None: - return 0 - 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: 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: rawptr[llvmlite.Value] = llvmlite.build_bitcast( - builder, func_val, i8_ptr_ty) + vt_ptr2: llvmlite.Value* = llvmlite.build_load(builder, i8_ptr_ty, vtable_slot) + if vt_ptr2 is None: return 0 + vt_typed: llvmlite.Value* = llvmlite.build_bitcast(builder, vt_ptr2, llvmlite.Ptr(pool, vtable_ty)) + if vt_typed is None: return 0 + vt_slotp: 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* = 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: rawptr[llvmlite.IRBuilder], - pool: rawptr[memhub.MemBuddy], - mod: rawptr[llvmlite.LLVMModule], - node: rawptr[ast.AST], - rhs_val: rawptr[llvmlite.Value], - trans: rawptr[HT.Translator]) -> int: + def _write_vtable_attr(self, builder: llvmlite.IRBuilder*, + pool: memhub.MemBuddy*, + mod: llvmlite.LLVMModule*, + node: ast.AST*, + rhs_val: llvmlite.Value*, + trans: HT.Translator*) -> int: """属性写入 obj.method = func:检测 vtable 方法并生成槽位写入(成功返回 1)""" - if node is None or builder is None or pool is None or mod is None: - return 0 - if rhs_val is None or trans is None: - return 0 - at: rawptr[ast.Attribute] = rawptr[ast.Attribute](node) - if at is None or at.value is None or at.attr is None: - return 0 + if node is None or builder is None or pool is None or mod is None: return 0 + if rhs_val is None or trans is None: return 0 + at: ast.Attribute* = ast.Attribute*(node) + if at is None or at.value is None or at.attr is None: return 0 # 解析类名(AnnotClassName;去模块前缀) class_nm_v: str = None if at.value.kind() == ast.ASTKind.Name: - nm_v: rawptr[ast.Name] = rawptr[ast.Name](at.value) + nm_v: ast.Name* = ast.Name*(at.value) if nm_v.id is not None: - ve_v: rawptr[GenTypes.VarEntry] = self.Gen.VarGen.lookup_var_entry( - trans.SymTab, nm_v.id) + ve_v: 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) elif at.value.kind() == ast.ASTKind.Attribute: # 跨 Mixin:_resolve_attr_field_class 定义在 ExprGenAttr,经 self.Gen 调用 class_nm_v = self.Gen.ExprGenAttr._resolve_attr_field_class(pool, trans, at.value) - if class_nm_v is None: - return 0 + if class_nm_v is None: return 0 fd_dot_v: str = string.strrchr(class_nm_v, '.') if fd_dot_v is not None: class_nm_v = fd_dot_v + 1 - if self.Gen.StructGen.get_struct_type(class_nm_v) is None: - return 0 + if self.Gen.StructGen.get_struct_type(class_nm_v) is None: return 0 vm_idx_v: int = self.Gen.StructGen.get_vtable_method_index(class_nm_v, at.attr) - if vm_idx_v < 0: - return 0 + if vm_idx_v < 0: return 0 # 解析 obj_ptr(对齐 get_attribute_ptr 前半段:Name 直接查 alloca) - obj_ptr_v: rawptr[llvmlite.Value] = None + obj_ptr_v: 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) + obj_ptr_v = self.Gen.VarGen.lookup_var(trans.SymTab, (ast.Name*(at.value)).id) else: - obj_ptr_v = self.Gen.ExprGen.translate_value( - builder, pool, mod, at.value, None, 0, trans) - if obj_ptr_v is None or obj_ptr_v.Ty is None: - return 0 + obj_ptr_v = self.Gen.ExprGen.translate_value(builder, pool, mod, at.value, None, 0, trans) + if obj_ptr_v is None or obj_ptr_v.Ty is None: return 0 # X|t.CPtr 变量(Ptr(Ptr))load 解引用取对象指针 match obj_ptr_v.Ty: case llvmlite.LLVMType.Ptr(inner_v): @@ -219,5 +172,4 @@ class CallGenVt(CallGenBase.CallGenBase): pass if obj_ptr_v is None: return 0 - return self._write_vtable_slot( - pool, builder, mod, obj_ptr_v, class_nm_v, vm_idx_v, rhs_val, trans) \ No newline at end of file + return self._write_vtable_slot(pool, builder, mod, obj_ptr_v, class_nm_v, vm_idx_v, rhs_val, trans) \ No newline at end of file diff --git a/App/lib/core/Gen/Class/ClassGenBase.vp b/App/lib/core/Gen/Class/ClassGenBase.vp index 3ac74ed..67dbae3 100644 --- a/App/lib/core/Gen/Class/ClassGenBase.vp +++ b/App/lib/core/Gen/Class/ClassGenBase.vp @@ -50,37 +50,37 @@ class ClassGenBase: """字段 + 方法元数据/异常/继承检测/装饰器(Meta)""" # --- 方法元数据表(原 _g_method_meta_keys/_g_method_meta_flags/_g_method_meta_count) --- - Gen: rawptr[Generator.Generator] + Gen: Generator.Generator* MethodMetaKeys: bytes MethodMetaFlags: bytes MethodMetaCount: int # --- REnum 变体表(原 _renum_class_names/_renum_class_variant_counts/ # _renum_variant_names/_renum_variant_tags/_renum_class_count) --- - RenumClassNames: sizet | t.CPtr - RenumClassVariantCounts: sizet | t.CPtr - RenumVariantNames: sizet | t.CPtr - RenumVariantTags: sizet | t.CPtr + RenumClassNames: sizet* + RenumClassVariantCounts: sizet* + RenumVariantNames: sizet* + RenumVariantTags: sizet* RenumClassCount: int # --- REnum 字段别名表(原 _renum_alias_class/_renum_alias_field/ # _renum_alias_index/_renum_alias_count) --- - RenumAliasClass: sizet | t.CPtr - RenumAliasField: sizet | t.CPtr - RenumAliasIndex: sizet | t.CPtr + RenumAliasClass: sizet* + RenumAliasField: sizet* + RenumAliasIndex: sizet* # 变体成员实际 LLVM 类型(对齐 TPC class_members):注册时按注解解析, # perm_pool 深拷贝持久化。match 绑定用真实成员类型 bitcast 槽位地址 # (Struct.Name: i8*,否则按槽位 i64 读 → is/subscript/strlen 失败)。 - RenumAliasTy: sizet | t.CPtr + RenumAliasTy: sizet* # 别名所属变体名(perm_pool 拷贝):同一 payload 位置跨变体类型不同 # (Int.Bits=i32 vs Struct.Fields=Ptr),match 绑定按 (class, 变体, 位置) # 唯一定位成员类型。 - RenumAliasVariant: sizet | t.CPtr + RenumAliasVariant: sizet* RenumAliasCount: int # --- 泛型特化缓存(原 _spec_keys/_spec_names/_spec_count) --- - SpecKeys: sizet | t.CPtr - SpecNames: sizet | t.CPtr + SpecKeys: sizet* + SpecNames: sizet* SpecCount: int # --- 类编译期元数据表(__provides__/__requires__/__require_must__) --- @@ -124,40 +124,40 @@ class ClassGenBase: # --- 泛型模板表(原 HandlesClassDef._generic_class_names/ # _generic_class_nodes/_generic_class_sha1s) --- - GenericClassNames: list[str] | t.CPtr - GenericClassNodes: list[rawptr[ast.ClassDef]] | t.CPtr - GenericClassSha1s: list[str] | t.CPtr + GenericClassNames: list[str]* + GenericClassNodes: list[ast.ClassDef*] | t.CPtr + GenericClassSha1s: list[str]* # 泛型模板来源文件路径(与上面三表同序)。特化翻译模板方法体时 node.lineno 是模板 # 文件行号,若 CurrentFile 仍是调用方文件,fatal_error 会把模板行号套到调用方文件上 # 显示错位。此表用于特化期间临时切换 CurrentFile 到模板文件,翻译完恢复。 - GenericClassFiles: list[str] | t.CPtr + GenericClassFiles: list[str]* # 泛型模板类型参数名表(与 GenericClassNames 同序,stdlib 深拷贝)。 # 模板节点 type_params 是 Phase 1 pool 分配的 list,跨 Phase 引用时内容 # 可能失效(VectorGenericTest 特化 Vector[int].__init__ 的 T.__sizeof__() # NameError 根因方向);注册时展平深拷贝到 stdlib,特化时从本表恢复。 # 每槽指向一个空格分隔、NUL 结尾的 stdlib 缓冲区(如 "T" 或 "T K")。 - GenericClassTpParams: sizet | t.CPtr + GenericClassTpParams: sizet* # --- vtable 方法收集表(原 _g_vt_full_names/_g_vt_method_names/ # _g_vt_parent_sha1s/_g_vt_method_count) --- - VtFullNames: sizet | t.CPtr - VtMethodNames: sizet | t.CPtr - VtParentSha1s: sizet | t.CPtr + VtFullNames: sizet* + VtMethodNames: sizet* + VtParentSha1s: sizet* VtMethodCount: int # ============================================================ # 以下方法由 P5-2 分簇迁移填充(函数体来自 HandlesClassDef.vp, # 本模块函数调用改 self.,外部模块调用保留模块前缀) # ============================================================ - def _is_cenum_base(self, base_node: rawptr[ast.AST], - trans: rawptr[HT.Translator] = None) -> int: + def _is_cenum_base(self, base_node: ast.AST*, + trans: HT.Translator* = None) -> int: """检查 base 节点是否为 t.CEnum,返回 1=是 / 0=否""" if base_node is None: return 0 k: int = base_node.kind() # Name('CEnum') 形式(from t import CEnum) if k == ast.ASTKind.Name: - nm: rawptr[ast.Name] = rawptr[ast.Name](base_node) + nm: ast.Name* = ast.Name*(base_node) if nm.id is None: return 0 if string.strcmp(nm.id, "CEnum") == 0: @@ -176,13 +176,13 @@ class ClassGenBase: return 0 # Attribute(t.CEnum) 形式 if k == ast.ASTKind.Attribute: - at: rawptr[ast.Attribute] = rawptr[ast.Attribute](base_node) + at: ast.Attribute* = ast.Attribute*(base_node) if at.attr is not None and string.strcmp(at.attr, "CEnum") == 0: return 1 return 0 return 0 - def _is_enum_class(self, cd: rawptr[ast.ClassDef], - trans: rawptr[HT.Translator] = None) -> int: + def _is_enum_class(self, cd: ast.ClassDef*, + trans: HT.Translator* = None) -> int: """检查 ClassDef 是否为 CEnum:继承自 t.CEnum 或 @t.CEnum 装饰器形式""" if cd is None: return 0 @@ -197,21 +197,21 @@ class ClassGenBase: if bn == 0: return 0 for bi in range(bn): - base_node: rawptr[ast.AST] = bases.get(bi) + base_node: ast.AST* = bases.get(bi) if base_node is None: continue if self._is_cenum_base(base_node, trans) == 1: return 1 return 0 - def _is_cunion_base(self, base_node: rawptr[ast.AST], - trans: rawptr[HT.Translator] = None) -> int: + def _is_cunion_base(self, base_node: ast.AST*, + trans: HT.Translator* = None) -> int: """检查 base 节点是否为 t.CUnion,返回 1=是 / 0=否""" if base_node is None: return 0 k: int = base_node.kind() # Name('CUnion') 形式(from t import CUnion) if k == ast.ASTKind.Name: - nm: rawptr[ast.Name] = rawptr[ast.Name](base_node) + nm: ast.Name* = ast.Name*(base_node) if nm.id is None: return 0 if string.strcmp(nm.id, "CUnion") == 0: @@ -229,13 +229,13 @@ class ClassGenBase: return 0 # Attribute(t.CUnion) 形式 if k == ast.ASTKind.Attribute: - at: rawptr[ast.Attribute] = rawptr[ast.Attribute](base_node) + at: ast.Attribute* = ast.Attribute*(base_node) if at.attr is not None and string.strcmp(at.attr, "CUnion") == 0: return 1 return 0 return 0 - def _is_union_class(self, cd: rawptr[ast.ClassDef], - trans: rawptr[HT.Translator] = None) -> int: + def _is_union_class(self, cd: ast.ClassDef*, + trans: HT.Translator* = None) -> int: """检查 ClassDef 是否为 CUnion:继承自 t.CUnion 或 @t.CUnion 装饰器形式""" if cd is None: return 0 @@ -250,21 +250,21 @@ class ClassGenBase: if bn == 0: return 0 for bi in range(bn): - base_node: rawptr[ast.AST] = bases.get(bi) + base_node: ast.AST* = bases.get(bi) if base_node is None: continue if self._is_cunion_base(base_node, trans) == 1: return 1 return 0 - def _is_crenum_base(self, base_node: rawptr[ast.AST], - trans: rawptr[HT.Translator] = None) -> int: + def _is_crenum_base(self, base_node: ast.AST*, + trans: HT.Translator* = None) -> int: """检查 base 节点是否为 t.REnum,返回 1=是 / 0=否""" if base_node is None: return 0 k: int = base_node.kind() # Name('REnum') 形式(from t import REnum) if k == ast.ASTKind.Name: - nm: rawptr[ast.Name] = rawptr[ast.Name](base_node) + nm: ast.Name* = ast.Name*(base_node) if nm.id is None: return 0 if string.strcmp(nm.id, "REnum") == 0: @@ -282,13 +282,13 @@ class ClassGenBase: return 0 # Attribute(t.REnum) 形式 if k == ast.ASTKind.Attribute: - at: rawptr[ast.Attribute] = rawptr[ast.Attribute](base_node) + at: ast.Attribute* = ast.Attribute*(base_node) if at.attr is not None and string.strcmp(at.attr, "REnum") == 0: return 1 return 0 return 0 - def _is_renum_class(self, cd: rawptr[ast.ClassDef], - trans: rawptr[HT.Translator] = None) -> int: + def _is_renum_class(self, cd: ast.ClassDef*, + trans: HT.Translator* = None) -> int: """检查 ClassDef 是否为 REnum:继承自 t.REnum 或 @t.REnum 装饰器形式""" if cd is None: return 0 @@ -303,7 +303,7 @@ class ClassGenBase: if bn == 0: return 0 for bi in range(bn): - base_node: rawptr[ast.AST] = bases.get(bi) + base_node: ast.AST* = bases.get(bi) if base_node is None: continue if self._is_crenum_base(base_node, trans) == 1: @@ -318,27 +318,27 @@ class ClassGenBase: if dn == 0: return 0 for di in range(dn): - deco: rawptr[ast.AST] = decorator_list.get(di) + deco: ast.AST* = decorator_list.get(di) if deco is None: continue k: int = deco.kind() # @t.NoVTable 形式(Attribute) if k == ast.ASTKind.Attribute: - at: rawptr[ast.Attribute] = rawptr[ast.Attribute](deco) + at: ast.Attribute* = ast.Attribute*(deco) if at.attr is not None and string.strcmp(at.attr, deco_name) == 0: # 检查 value 是 Name('t') if at.value is not None and at.value.kind() == ast.ASTKind.Name: - vn: rawptr[ast.Name] = rawptr[ast.Name](at.value) + vn: ast.Name* = ast.Name*(at.value) if vn.id is not None and string.strcmp(vn.id, "t") == 0: return 1 return 0 # @NoVTable 形式(Name,from t import NoVTable) if k == ast.ASTKind.Name: - nm: rawptr[ast.Name] = rawptr[ast.Name](deco) + nm: ast.Name* = ast.Name*(deco) if nm.id is not None and string.strcmp(nm.id, deco_name) == 0: return 1 return 0 - def _tattr_name(self, node: rawptr[ast.AST], attr_name: str) -> int: + def _tattr_name(self, node: ast.AST*, attr_name: str) -> int: """从 t.attr. / t.attr.(args) 节点提取最外层属性名并比较。 Call(t.attr.aligned(16))→ 递归取 func;Attribute(t.attr.packed)→ 取 attr。 @@ -346,12 +346,12 @@ class ClassGenBase: if node is None: return 0 if node.kind() == ast.ASTKind.Call: - cl2: rawptr[ast.Call] = rawptr[ast.Call](node) + cl2: ast.Call* = ast.Call*(node) if cl2.func is None: return 0 return self._tattr_name(cl2.func, attr_name) if node.kind() == ast.ASTKind.Attribute: - at2: rawptr[ast.Attribute] = rawptr[ast.Attribute](node) + at2: ast.Attribute* = ast.Attribute*(node) if at2.attr is None: return 0 return 1 if string.strcmp(at2.attr, attr_name) == 0 else 0 @@ -368,23 +368,23 @@ class ClassGenBase: if dn == 0: return 0 for di in range(dn): - deco: rawptr[ast.AST] = decorator_list.get(di) + deco: ast.AST* = decorator_list.get(di) if deco is None: continue k: int = deco.kind() if k == ast.ASTKind.Call: - cl: rawptr[ast.Call] = rawptr[ast.Call](deco) + cl: ast.Call* = ast.Call*(deco) # @c.Attribute(t.attr.xxx) 形式:func 是 Attribute(c, "Attribute") if cl.func is None or cl.func.kind() != ast.ASTKind.Attribute: continue - at0: rawptr[ast.Attribute] = rawptr[ast.Attribute](cl.func) + at0: ast.Attribute* = ast.Attribute*(cl.func) if at0.attr is None or string.strcmp(at0.attr, "Attribute") != 0: continue if cl.args is None: continue an: sizet = len(cl.args) for ai in range(an): - ag: rawptr[ast.AST] = cl.args.get(ai) + ag: ast.AST* = cl.args.get(ai) if ag is not None and self._tattr_name(ag, attr_name) != 0: return 1 else: @@ -392,23 +392,23 @@ class ClassGenBase: if self._tattr_name(deco, attr_name) != 0: return 1 return 0 - def _tattr_aligned_int(self, node: rawptr[ast.AST]) -> int: + def _tattr_aligned_int(self, node: ast.AST*) -> int: """t.attr.aligned(N) → N(整数参数),非 aligned 或无参返回 0""" if node is None: return 0 if node.kind() == ast.ASTKind.Call: - cl2: rawptr[ast.Call] = rawptr[ast.Call](node) + cl2: ast.Call* = ast.Call*(node) if cl2.func is None or cl2.func.kind() != ast.ASTKind.Attribute: return 0 - at2: rawptr[ast.Attribute] = rawptr[ast.Attribute](cl2.func) + at2: ast.Attribute* = ast.Attribute*(cl2.func) if at2.attr is None or string.strcmp(at2.attr, "aligned") != 0: return 0 if cl2.args is None or len(cl2.args) == 0: return 0 - a0: rawptr[ast.AST] = cl2.args.get(0) + a0: ast.AST* = cl2.args.get(0) if a0 is None or a0.kind() != ast.ASTKind.Constant: return 0 - cn: rawptr[ast.Constant] = rawptr[ast.Constant](a0) + cn: ast.Constant* = ast.Constant*(a0) if cn.const_kind != ast.CONST_INT: return 0 return int(cn.int_val) @@ -421,21 +421,21 @@ class ClassGenBase: if dn == 0: return 0 for di in range(dn): - deco: rawptr[ast.AST] = decorator_list.get(di) + deco: ast.AST* = decorator_list.get(di) if deco is None: continue if deco.kind() == ast.ASTKind.Call: - cl: rawptr[ast.Call] = rawptr[ast.Call](deco) + cl: ast.Call* = ast.Call*(deco) if cl.func is None or cl.func.kind() != ast.ASTKind.Attribute: continue - at0: rawptr[ast.Attribute] = rawptr[ast.Attribute](cl.func) + at0: ast.Attribute* = ast.Attribute*(cl.func) if at0.attr is None or string.strcmp(at0.attr, "Attribute") != 0: continue if cl.args is None: continue an: sizet = len(cl.args) for ai in range(an): - ag: rawptr[ast.AST] = cl.args.get(ai) + ag: ast.AST* = cl.args.get(ai) if ag is not None: av: int = self._tattr_aligned_int(ag) if av > 0: @@ -454,12 +454,12 @@ class ClassGenBase: if dn == 0: return meta for di in range(dn): - deco: rawptr[ast.AST] = decorator_list.get(di) + deco: ast.AST* = decorator_list.get(di) if deco is None: continue k: int = deco.kind() if k == ast.ASTKind.Name: - nm: rawptr[ast.Name] = rawptr[ast.Name](deco) + nm: ast.Name* = ast.Name*(deco) if nm.id is not None: if string.strcmp(nm.id, "staticmethod") == 0: meta |= GenTypes.META_STATIC @@ -470,10 +470,10 @@ class ClassGenBase: elif string.strcmp(nm.id, "TLS") == 0: meta |= META_TLS elif k == ast.ASTKind.Attribute: - at: rawptr[ast.Attribute] = rawptr[ast.Attribute](deco) + at: ast.Attribute* = ast.Attribute*(deco) if at.attr is not None and at.value is not None: if at.value.kind() == ast.ASTKind.Name: - vn: rawptr[ast.Name] = rawptr[ast.Name](at.value) + vn: ast.Name* = ast.Name*(at.value) is_prop_name: int = 0 if vn.id is not None and string.strcmp(vn.id, "property") == 0: is_prop_name = 1 @@ -492,7 +492,7 @@ class ClassGenBase: elif string.strcmp(at.attr, "deleter") == 0: meta |= GenTypes.META_PROP_DELETER return meta - def register_class_meta(self, pool: rawptr[memhub.MemBuddy], + def register_class_meta(self, pool: memhub.MemBuddy*, kind: int, cls: str, field: str) -> int: """注册类编译期元数据字段(__provides__/__requires__/__require_must__,幂等)""" if pool is None or cls is None or field is None: @@ -545,7 +545,7 @@ class ClassGenBase: return self.ClassMetaFields + i * 64 n_cm2 += 1 return None - def register_decorator(self, pool: rawptr[memhub.MemBuddy], + def register_decorator(self, pool: memhub.MemBuddy*, func_name: str, wrapper_name: str, arg0: int64) -> int: """注册自定义装饰器函数(@log/@skip/@repeat(3) → __decor_wrap_{name}) @@ -606,7 +606,7 @@ class ClassGenBase: """懒初始化异常表(perm_pool),返回 0 成功""" if self.ExceptionNames is not None: return 0 - pp_e: rawptr[memhub.MemBuddy] = CompilerFactory.factory.PermPool + pp_e: memhub.MemBuddy* = CompilerFactory.factory.PermPool if pp_e is None: return -1 self.ExceptionNames = pp_e.alloc(EXCEPTION_MAX * EXCEPTION_NAME_LEN) @@ -730,21 +730,21 @@ class ClassGenBase: if pname_e is not None and pname_e[0] != '\0': if string.strcmp(pname_e, name) == 0: self._collect_desc_codes_rec(cname_e, out_codes, max_codes, depth + 1) - def _is_exception_class_def(self, cd: rawptr[ast.ClassDef]) -> int: + def _is_exception_class_def(self, cd: ast.ClassDef*) -> int: """类定义是否是异常类:基类是 Exception 或已注册异常类(1=是)""" if cd is None or cd.bases is None: return 0 bases_e: list[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) + base_e: ast.AST* = bases_e.get(bi_e) if base_e is None: continue base_name_e: str = None if base_e.kind() == ast.ASTKind.Name: - base_name_e = (rawptr[ast.Name](base_e)).id + base_name_e = (ast.Name*(base_e)).id elif base_e.kind() == ast.ASTKind.Attribute: - base_at_e: rawptr[ast.Attribute] = rawptr[ast.Attribute](base_e) + base_at_e: ast.Attribute* = ast.Attribute*(base_e) if base_at_e.attr is not None: base_name_e = base_at_e.attr if base_name_e is None: @@ -754,21 +754,21 @@ class ClassGenBase: if self.is_exception_name(base_name_e) != 0: return 1 return 0 - def _get_exception_parent_name(self, cd: rawptr[ast.ClassDef]) -> str: + def _get_exception_parent_name(self, cd: ast.ClassDef*) -> str: """返回异常类定义的真实父类名(第一个非 Exception 的已注册异常类),无则 None""" if cd is None or cd.bases is None: return None bases_e2: list[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) + base_e2: ast.AST* = bases_e2.get(bi_e2) if base_e2 is None: continue base_name_e2: str = None if base_e2.kind() == ast.ASTKind.Name: - base_name_e2 = (rawptr[ast.Name](base_e2)).id + base_name_e2 = (ast.Name*(base_e2)).id elif base_e2.kind() == ast.ASTKind.Attribute: - base_at_e2: rawptr[ast.Attribute] = rawptr[ast.Attribute](base_e2) + base_at_e2: ast.Attribute* = ast.Attribute*(base_e2) if base_at_e2.attr is not None: base_name_e2 = base_at_e2.attr if base_name_e2 is None: @@ -777,31 +777,31 @@ class ClassGenBase: and self.is_exception_name(base_name_e2) != 0: return base_name_e2 return None - def _register_exception_class_def(self, trans: rawptr[HT.Translator], - cd: rawptr[ast.ClassDef]) -> int: + def _register_exception_class_def(self, trans: HT.Translator*, + cd: ast.ClassDef*) -> int: """注册异常类(分配编码 + 记录父类),不生成 struct,返回 0""" if cd is None or cd.name is None: return 0 parent_e: str = self._get_exception_parent_name(cd) self.register_exception(cd.name, parent_e) return 0 - def _register_class_meta_list(self, pool: rawptr[memhub.MemBuddy], - kind: int, cls: str, value_node: rawptr[ast.AST]) -> None: + def _register_class_meta_list(self, pool: memhub.MemBuddy*, + kind: int, cls: str, value_node: ast.AST*) -> None: """解析类体 __provides__/__requires__ 的 list[str] 字面量并注册""" if value_node is None or cls is None: return if value_node.kind() != ast.ASTKind.List: return - lst_rcm: rawptr[ast.List] = rawptr[ast.List](value_node) + lst_rcm: ast.List* = ast.List*(value_node) if lst_rcm.elts is None: return elts_rcm: list[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) + el_rcm: ast.AST* = elts_rcm.get(ei_rcm) if el_rcm is None or el_rcm.kind() != ast.ASTKind.Constant: continue - ec_rcm: rawptr[ast.Constant] = rawptr[ast.Constant](el_rcm) + ec_rcm: ast.Constant* = ast.Constant*(el_rcm) if ec_rcm.str_val is not None: self.register_class_meta(pool, kind, cls, ec_rcm.str_val) def register_method_meta(self, class_name: str, method_name: str, @@ -899,8 +899,8 @@ class ClassGenBase: if string.strcmp(base_name, "REnum") == 0: return 1 return 0 - def _get_base_name(self, base_node: rawptr[ast.AST], - pool: rawptr[memhub.MemBuddy] = None) -> str: + def _get_base_name(self, base_node: ast.AST*, + pool: memhub.MemBuddy* = None) -> str: """从 base AST 节点提取基类名,返回 None=失败 对于 Subscript 节点,需要 pool 分配内存拼接特化名; @@ -911,15 +911,15 @@ class ClassGenBase: k: int = base_node.kind() # Name(id) 形式 if k == ast.ASTKind.Name: - nm: rawptr[ast.Name] = rawptr[ast.Name](base_node) + nm: ast.Name* = ast.Name*(base_node) return nm.id # Attribute(attr) 形式 if k == ast.ASTKind.Attribute: - at: rawptr[ast.Attribute] = rawptr[ast.Attribute](base_node) + at: ast.Attribute* = ast.Attribute*(base_node) return at.attr # Subscript(value, slice) 形式 — 如 GSListNode[Value] if k == ast.ASTKind.Subscript: - sub: rawptr[ast.Subscript] = rawptr[ast.Subscript](base_node) + sub: ast.Subscript* = ast.Subscript*(base_node) if sub is None or sub.value is None or sub.slice is None: return None # 提取基类名(如 "GSListNode") @@ -930,7 +930,7 @@ class ClassGenBase: slice_k: int = sub.slice.kind() arg_nm: str = None if slice_k == ast.ASTKind.Name: - sl_nm: rawptr[ast.Name] = rawptr[ast.Name](sub.slice) + sl_nm: ast.Name* = ast.Name*(sub.slice) arg_nm = sl_nm.id # 如果无法提取类型实参,返回基类名(降级) if arg_nm is None: @@ -952,12 +952,12 @@ class ClassGenBase: string.strcat(mangled, "]") return mangled return None - def _get_parent_class(self, cd: rawptr[ast.ClassDef], - trans: rawptr[HT.Translator] = None) -> str: + def _get_parent_class(self, cd: ast.ClassDef*, + trans: HT.Translator* = None) -> str: """获取 ClassDef 的真实父类名,返回 None=无真实父类""" if cd is None or cd.bases is None: return None - pool: rawptr[memhub.MemBuddy] = None + pool: memhub.MemBuddy* = None if trans is not None: pool = trans.Pool bases: list[ast.AST*]* = cd.bases @@ -965,7 +965,7 @@ class ClassGenBase: if bn == 0: return None for bi in range(bn): - base_node: rawptr[ast.AST] = bases.get(bi) + base_node: ast.AST* = bases.get(bi) if base_node is None: continue bname: str = self._get_base_name(base_node, pool) @@ -977,7 +977,7 @@ class ClassGenBase: return bname return None def _resolve_base_alias(self, base_name: str, - trans: rawptr[HT.Translator] = None) -> str: + trans: HT.Translator* = None) -> str: """解析基类别名:from t import CStruct as cs → 基类 cs 实际是 CStruct。 别名不解析时 "cs" 会被当作真实父类名 → find_struct("cs") 失败 → @@ -1004,11 +1004,11 @@ class ClassGenBase: og_buf[og_len] = '\0' return og_buf return base_name - def _collect_parents(self, pool: rawptr[memhub.MemBuddy], - cd: rawptr[ast.ClassDef], - parents_buf: sizet | t.CPtr, + def _collect_parents(self, pool: memhub.MemBuddy*, + cd: ast.ClassDef*, + parents_buf: sizet*, max_parents: int, - trans: rawptr[HT.Translator] = None) -> int: + trans: HT.Translator* = None) -> int: """收集所有非 marker 父类名到 parents_buf,返回数量""" if pool is None or cd is None or cd.bases is None or parents_buf is None: return 0 @@ -1018,7 +1018,7 @@ class ClassGenBase: for bi in range(bn): if count >= max_parents: break - base_node: rawptr[ast.AST] = bases.get(bi) + base_node: ast.AST* = bases.get(bi) if base_node is None: continue bname: str = self._get_base_name(base_node, pool) @@ -1029,7 +1029,7 @@ class ClassGenBase: parents_buf[count] = sizet(bname) count += 1 return count - def _field_name_exists(self, names_buf: sizet | t.CPtr, + def _field_name_exists(self, names_buf: sizet*, count: int, name: str) -> int: """检查字段名是否已在 names_buf 中(先声明父类优先,重复跳过)""" if names_buf is None or name is None: @@ -1041,36 +1041,36 @@ class ClassGenBase: if existing is not None and string.strcmp(existing, name) == 0: return 1 return 0 - def _class_body_has_field(self, cd: rawptr[ast.ClassDef]) -> int: + def _class_body_has_field(self, cd: ast.ClassDef*) -> int: """检查类体是否声明了字段(AnnAssign),0=纯方法/无字段类""" if cd is None or cd.children is None: return 0 cn: sizet = len(cd.children) for ci in range(cn): - stmt: rawptr[ast.AST] = cd.children.get(ci) + stmt: ast.AST* = cd.children.get(ci) if stmt is None: continue if stmt.kind() == ast.ASTKind.AnnAssign: return 1 return 0 - def _trigger_base_specialization(self, trans: rawptr[HT.Translator], - cd: rawptr[ast.ClassDef]): + def _trigger_base_specialization(self, trans: HT.Translator*, + cd: ast.ClassDef*): """触发 base 中 Subscript 的泛型特化(如 GSListNode[Value])""" if trans is None or cd is None or cd.bases is None: return - pool: rawptr[memhub.MemBuddy] = trans.Pool + pool: memhub.MemBuddy* = trans.Pool bases: list[ast.AST*]* = cd.bases bn: sizet = len(bases) if bn == 0: return for bi in range(bn): - base_node: rawptr[ast.AST] = bases.get(bi) + base_node: ast.AST* = bases.get(bi) if base_node is None: continue bk: int = base_node.kind() if bk != ast.ASTKind.Subscript: continue - sub: rawptr[ast.Subscript] = rawptr[ast.Subscript](base_node) + sub: ast.Subscript* = ast.Subscript*(base_node) if sub is None or sub.value is None or sub.slice is None: continue # 提取泛型类名(如 "GSListNode") @@ -1084,30 +1084,30 @@ class ClassGenBase: slice_k: int = sub.slice.kind() arg_nm: str = None if slice_k == ast.ASTKind.Name: - sl_nm: rawptr[ast.Name] = rawptr[ast.Name](sub.slice) + sl_nm: ast.Name* = ast.Name*(sub.slice) arg_nm = sl_nm.id if arg_nm is None: continue # 构建 type_args 列表(elem_size=8:str 是指针,1 会导致双元素重叠损坏) - type_args: list[str] | t.CPtr = list[str](pool, 8) + type_args: list[str]* = list[str](pool, 8) if type_args is None: continue type_args.append(arg_nm) # 触发特化(_specialize_generic_class 有缓存,重复调用安全) self.Gen.ClassGenGeneric._specialize_generic_class(trans, gen_class_name, type_args) - def _has_any_func_cvtable(self, cd: rawptr[ast.ClassDef]) -> int: + def _has_any_func_cvtable(self, cd: ast.ClassDef*) -> int: """检查类中是否有任何函数标记了 @t.CVTable,返回 1=有 / 0=无""" if cd is None or cd.children is None: return 0 children: list[ast.AST*]* = cd.children cn: sizet = len(children) for ci in range(cn): - stmt: rawptr[ast.AST] = children.get(ci) + stmt: ast.AST* = children.get(ci) if stmt is None: continue if stmt.kind() != ast.ASTKind.FunctionDef: continue - fd: rawptr[ast.FunctionDef] = rawptr[ast.FunctionDef](stmt) + fd: ast.FunctionDef* = ast.FunctionDef*(stmt) if fd is None or fd.name is None: continue # 跳过构造函数 @@ -1121,9 +1121,9 @@ class ClassGenBase: if self._has_decorator(fd.decorator_list, "CVTable") == 1: return 1 return 0 - def _should_method_be_virtual(self, cd: rawptr[ast.ClassDef], - fd: rawptr[ast.FunctionDef], - trans: rawptr[HT.Translator] = None) -> int: + def _should_method_be_virtual(self, cd: ast.ClassDef*, + fd: ast.FunctionDef*, + trans: HT.Translator* = None) -> int: """判断方法是否应该进入虚表,返回 1=包含 / 0=排除""" if fd is None: return 0 @@ -1146,7 +1146,7 @@ class ClassGenBase: # 用 SHA1 感知查找父类,规避跨模块同名找错 is_nvt: int = 0 if trans is not None: - p_entry: rawptr[GenTypes.StructEntry] = self.Gen.StructGen.find_struct_by_module( + p_entry: GenTypes.StructEntry* = self.Gen.StructGen.find_struct_by_module( parent_name, trans.ModuleSha1) if p_entry is None: # 跨模块父类回退全局查找(父类注册在父模块 SHA1 下,如 linkedlist.LinkedNode), @@ -1168,8 +1168,8 @@ class ClassGenBase: # 5. 默认排除 return 0 - def _detect_vtable_status(self, cd: rawptr[ast.ClassDef], - trans: rawptr[HT.Translator] = None) -> int: + def _detect_vtable_status(self, cd: ast.ClassDef*, + trans: HT.Translator* = None) -> int: """检测类是否应该启用虚表""" if cd is None: return 0 @@ -1189,7 +1189,7 @@ class ClassGenBase: # 用 SHA1 感知查找父类,规避跨模块同名找错 is_nvt: int = 0 if trans is not None: - p_entry: rawptr[GenTypes.StructEntry] = self.Gen.StructGen.find_struct_by_module( + p_entry: GenTypes.StructEntry* = self.Gen.StructGen.find_struct_by_module( parent_name, trans.ModuleSha1) if p_entry is None: # 跨模块父类回退全局查找(同 _detect_vtable_status 的回退) diff --git a/App/lib/core/Gen/Class/ClassGenDef.vp b/App/lib/core/Gen/Class/ClassGenDef.vp index 40914b8..98618e2 100644 --- a/App/lib/core/Gen/Class/ClassGenDef.vp +++ b/App/lib/core/Gen/Class/ClassGenDef.vp @@ -28,17 +28,17 @@ class ClassGenDef(ClassGenBase.ClassGenBase): # ============================================================ # translate_class_def — 翻译 class 定义(簇 D) # ============================================================ - def translate_class_def(self, trans: rawptr[HT.Translator], - node: rawptr[ast.AST]) -> int: + def translate_class_def(self, trans: HT.Translator*, + node: ast.AST*) -> int: """翻译 class 定义,返回 0""" if node is None or trans is None: return 0 - cd: rawptr[ast.ClassDef] = rawptr[ast.ClassDef](node) + cd: ast.ClassDef* = ast.ClassDef*(node) if cd is None or cd.name is None: return 0 - pool: rawptr[memhub.MemBuddy] = trans.Pool + pool: memhub.MemBuddy* = trans.Pool class_name: str = cd.name if trans.ModuleSha1 is None: @@ -73,7 +73,7 @@ class ClassGenDef(ClassGenBase.ClassGenBase): # 泛型类:存储为模板,不发射 IR(等实例化时特化) # 用局部变量接收 cd.type_params,触发类型推断 - tp_val: list[str] | t.CPtr = cd.type_params + tp_val: list[str]* = cd.type_params if self.Gen.ClassGenGeneric._is_generic_class(tp_val) == 1: self.Gen.ClassGenGeneric._register_generic_template(pool, cd, trans.ModuleSha1) return 0 @@ -85,7 +85,7 @@ class ClassGenDef(ClassGenBase.ClassGenBase): return self.Gen.ClassGenBase._register_exception_class_def(trans, cd) # 检查是否已注册(用 SHA1 区分跨模块同名类) - existing: rawptr[GenTypes.StructEntry] = self.Gen.StructGen.find_struct_by_module( + existing: GenTypes.StructEntry* = self.Gen.StructGen.find_struct_by_module( class_name, trans.ModuleSha1) # 空类注册不完整检测:existing FieldCount==0 但源类体声明了字段(vpi 注入/注册缺陷)。 # 标记 _deps_pending 延迟会让空 entry 持久存在、多遍死锁不收敛 ⇒ 改为中和旧 entry @@ -112,7 +112,7 @@ class ClassGenDef(ClassGenBase.ClassGenBase): # _ensure_field_types_in_module 遍历悬空字段 ParamNode 链表 # 读悬空挂起(G3 LinkedNode.prepend 挂起根因)。DeepCopyType # 递归深拷贝字段链表/子类型/Name 到 stdlib(深度上限+链守卫)。 - ty_deep: rawptr[llvmlite.LLVMType] = llvmlite.DeepCopyType( + ty_deep: llvmlite.LLVMType* = llvmlite.DeepCopyType( CompilerFactory.factory.PermPool, existing.Ty) if ty_deep is not None: existing.Ty = ty_deep @@ -162,7 +162,7 @@ class ClassGenDef(ClassGenBase.ClassGenBase): has_vtable: int = self.Gen.ClassGenBase._detect_vtable_status(cd, trans) parent_name: str = self.Gen.ClassGenBase._get_parent_class(cd, trans) # 多继承:收集所有真实父类名(跳过 marker base),供字段展平/vtable/MRO 使用 - parents_buf: sizet | t.CPtr = pool.alloc(8 * GenTypes.PARENT_MAX) + parents_buf: sizet* = pool.alloc(8 * GenTypes.PARENT_MAX) parents_count: int = 0 if parents_buf is not None: parents_count = self.Gen.ClassGenBase._collect_parents(pool, cd, parents_buf, GenTypes.PARENT_MAX, trans) @@ -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: rawptr[GenTypes.StructEntry] = self.Gen.StructGen.find_struct_by_module( + parent_check: 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) @@ -196,21 +196,24 @@ class ClassGenDef(ClassGenBase.ClassGenBase): # 1. 遍历 class body,收集字段信息 # ============================================================ # 用 CSizeT 数组存储指针值(64 位系统上 8 字节) - field_names_buf: sizet | t.CPtr = pool.alloc(8 * GenTypes.FIELD_MAX) - field_types_buf: sizet | t.CPtr = pool.alloc(8 * GenTypes.FIELD_MAX) - field_defaults_buf: sizet | t.CPtr = pool.alloc(8 * GenTypes.FIELD_MAX) - field_annot_buf: sizet | t.CPtr = pool.alloc(8 * GenTypes.FIELD_MAX) + field_names_buf: sizet* = pool.alloc(8 * GenTypes.FIELD_MAX) + field_types_buf: sizet* = pool.alloc(8 * GenTypes.FIELD_MAX) + field_defaults_buf: sizet* = pool.alloc(8 * GenTypes.FIELD_MAX) + field_annot_buf: sizet* = pool.alloc(8 * GenTypes.FIELD_MAX) # 字段 volatile 标记缓冲(1=字段注解联合含 t.CVolatile);与 field_annot_buf # 并行,取值 0/1(sizet 数组复用,避免另设类型)。 - field_volatile_buf: sizet | t.CPtr = pool.alloc(8 * GenTypes.FIELD_MAX) + field_volatile_buf: sizet* = pool.alloc(8 * GenTypes.FIELD_MAX) # 字段「所指物 volatile」标记缓冲(1=字段注解为 rawptr[t.CVolatile | T], # 等价 C 的 volatile T*);与 field_volatile_buf 并行,取值 0/1。 - field_pointee_volatile_buf: sizet | t.CPtr = pool.alloc(8 * GenTypes.FIELD_MAX) + field_pointee_volatile_buf: sizet* = pool.alloc(8 * GenTypes.FIELD_MAX) + # 字段 const 对象标记缓冲(1=字段注解含 t.CConst 且字段类型非指针); + # 与 field_volatile_buf 并行,取值 0/1。 + field_const_buf: sizet* = pool.alloc(8 * GenTypes.FIELD_MAX) if field_names_buf is None or field_types_buf is None or field_defaults_buf is None: return 0 if field_annot_buf is None or field_volatile_buf is None: return 0 - if field_pointee_volatile_buf is None: + if field_pointee_volatile_buf is None or field_const_buf is None: return 0 string.memset(field_names_buf, 0, 8 * GenTypes.FIELD_MAX) string.memset(field_types_buf, 0, 8 * GenTypes.FIELD_MAX) @@ -218,6 +221,7 @@ class ClassGenDef(ClassGenBase.ClassGenBase): string.memset(field_annot_buf, 0, 8 * GenTypes.FIELD_MAX) string.memset(field_volatile_buf, 0, 8 * GenTypes.FIELD_MAX) string.memset(field_pointee_volatile_buf, 0, 8 * GenTypes.FIELD_MAX) + string.memset(field_const_buf, 0, 8 * GenTypes.FIELD_MAX) field_count: int = 0 @@ -239,7 +243,7 @@ class ClassGenDef(ClassGenBase.ClassGenBase): if pname is None: continue # 用 SHA1 感知查找父类,规避跨模块同名找错 - parent_entry: rawptr[GenTypes.StructEntry] = self.Gen.StructGen.find_struct_by_module( + parent_entry: GenTypes.StructEntry* = self.Gen.StructGen.find_struct_by_module( pname, trans.ModuleSha1) if parent_entry is None: # 父类可能定义在另一个模块(不同 SHA1,如 HandlesBase.Mixin), @@ -255,7 +259,7 @@ class ClassGenDef(ClassGenBase.ClassGenBase): return 0 pfc: int = parent_entry.FieldCount for pfi in range(pfc): - pfe: rawptr[GenTypes.FieldEntry] = self.Gen.StructGen._get_field_entry( + pfe: GenTypes.FieldEntry* = self.Gen.StructGen._get_field_entry( parent_entry, pfi) if pfe is None: continue @@ -269,8 +273,8 @@ class ClassGenDef(ClassGenBase.ClassGenBase): if self.Gen.ClassGenBase._field_name_exists(field_names_buf, field_count, pfn) != 0: continue if field_count < GenTypes.FIELD_MAX: - pft: rawptr[llvmlite.LLVMType] = self.Gen.StructGen.get_field_type_ptr(pfe) - pfd: rawptr[ast.AST] = self.Gen.StructGen.get_field_default_ptr(pfe) + pft: llvmlite.LLVMType* = self.Gen.StructGen.get_field_type_ptr(pfe) + pfd: ast.AST* = self.Gen.StructGen.get_field_default_ptr(pfe) pfa: str = self.Gen.StructGen.get_field_annot_class_name(pfe) field_names_buf[field_count] = sizet(pfn) field_types_buf[field_count] = sizet(pft) @@ -287,6 +291,8 @@ class ClassGenDef(ClassGenBase.ClassGenBase): field_volatile_buf[field_count] = sizet(pfe.IsVolatile) # 继承父类字段的「所指物 volatile」标记(展平后语义不变) field_pointee_volatile_buf[field_count] = sizet(pfe.PointeeVolatile) + # 继承父类字段的 const 对象标记(展平后语义不变) + field_const_buf[field_count] = sizet(pfe.IsConst) field_count += 1 children: list[ast.AST*]* = cd.children @@ -295,7 +301,7 @@ class ClassGenDef(ClassGenBase.ClassGenBase): cn: sizet = len(children) for ci in range(cn): - stmt: rawptr[ast.AST] = children.get(ci) + stmt: ast.AST* = children.get(ci) if stmt is None: continue sk: int = stmt.kind() @@ -303,14 +309,14 @@ class ClassGenDef(ClassGenBase.ClassGenBase): if sk != ast.ASTKind.AnnAssign: continue # AnnAssign(target=Name(id), annotation=type, value=...) - aa: rawptr[ast.AnnAssign] = rawptr[ast.AnnAssign](stmt) + aa: ast.AnnAssign* = ast.AnnAssign*(stmt) if aa is None or aa.target is None: continue # 获取字段名 if aa.target.kind() != ast.ASTKind.Name: continue - tgt: rawptr[ast.Name] = rawptr[ast.Name](aa.target) + tgt: ast.Name* = ast.Name*(aa.target) if tgt.id is None: continue @@ -320,14 +326,14 @@ class ClassGenDef(ClassGenBase.ClassGenBase): # 路径注册,但方法之后的 AnnAssign 不经过那些路径 → 此处统一兜底注册。 if self.Gen.AssignGen.is_cdefine_annotation(aa.annotation) != 0: if aa.value is not None: - self.Gen.AssignGen._register_cdefine_from_value(pool, tgt.id, aa.value) + self.Gen.AssignGen._register_cdefine_from_value(pool, tgt.id, aa.value, aa.annotation) # CDefine 字段类型固定 i32,直接收集后跳过通用注解解析: # resolve_annotation_type 不识别 "CDefine"(map_t_type/CTypedef # 表均无此名),类体尾部常量(ISINSTANCE_CLASS_MAX 是首个触发 # 该路径的实例)Phase B 会 NameError: 't.CDefine' is not defined。 # 与类头常量(MRO_MAX 等)的 i32 字段语义保持一致。 if field_count < GenTypes.FIELD_MAX: - cdef_ty_l: rawptr[llvmlite.LLVMType] = llvmlite.Int32(pool) + cdef_ty_l: llvmlite.LLVMType* = llvmlite.Int32(pool) if cdef_ty_l is not None: field_names_buf[field_count] = sizet(tgt.id) field_types_buf[field_count] = sizet(cdef_ty_l) @@ -353,7 +359,7 @@ class ClassGenDef(ClassGenBase.ClassGenBase): continue # 解析字段类型 - field_ty: rawptr[llvmlite.LLVMType] = self.Gen.TypeGenResolve.resolve_annotation_type( + field_ty: llvmlite.LLVMType* = self.Gen.TypeGenResolve.resolve_annotation_type( pool, aa.annotation, trans._imported_modules, trans._from_imports, trans, 0) # 单参 t.CArray[elem] + 列表字面量 → 静态数组 [N x elem] # (与局部 AnnAssign 路径一致,对齐 TPC ParseListAnnotation 语义): @@ -377,16 +383,16 @@ class ClassGenDef(ClassGenBase.ClassGenBase): # 元素类型未就绪时若回退 Ptr(i8) 会注册成退化字段布局,Phase B 复用该 entry # 后 GEP 元素成 i8、字段访问/赋值全部失效。仅真正的泛型类(list[T]/Vector[T] # 等堆对象)未特化才回退 Ptr(i8)(AnnotClassName 携带 mangled name 供后续恢复)。 - sub_g: rawptr[ast.Subscript] = rawptr[ast.Subscript](aa.annotation) + sub_g: ast.Subscript* = ast.Subscript*(aa.annotation) is_carray_sub_g: int = 0 if sub_g is not None and sub_g.value is not None: if sub_g.value.kind() == ast.ASTKind.Attribute: - svg_at: rawptr[ast.Attribute] = rawptr[ast.Attribute](sub_g.value) + svg_at: ast.Attribute* = ast.Attribute*(sub_g.value) if svg_at.attr is not None and string.strcmp(svg_at.attr, "CArray") == 0: is_carray_sub_g = 1 elif sub_g.value.kind() == ast.ASTKind.Name: - svg_nm: rawptr[ast.Name] = rawptr[ast.Name](sub_g.value) - if svg_nm.id is not None and (string.strcmp(svg_nm.id, "CArray") == 0 or string.strcmp(svg_nm.id, "rawarray") == 0): + svg_nm: ast.Name* = ast.Name*(sub_g.value) + if svg_nm.id is not None and (string.strcmp(svg_nm.id, "CArray") == 0 or string.strcmp(svg_nm.id, "rawarray") == 0 or string.strcmp(svg_nm.id, "array") == 0): is_carray_sub_g = 1 if is_carray_sub_g == 0: is_generic_sub = 1 @@ -441,10 +447,18 @@ class ClassGenDef(ClassGenBase.ClassGenBase): field_pointee_volatile_buf[field_count] = 1 else: field_pointee_volatile_buf[field_count] = 0 + # const 对象字段(注解含 t.CConst 且字段类型非指针)→ 经对象给该 + # 字段赋值 fail-fast。判据与 TPC 的 Gen.field_const_flags 一致。 + if self.Gen.TypeGenErr.is_const_object_marker( + aa.annotation, field_ty) != 0: + field_const_buf[field_count] = 1 + else: + field_const_buf[field_count] = 0 else: field_annot_buf[field_count] = 0 field_volatile_buf[field_count] = 0 field_pointee_volatile_buf[field_count] = 0 + field_const_buf[field_count] = 0 field_count += 1 if field_count == 0: @@ -467,7 +481,7 @@ class ClassGenDef(ClassGenBase.ClassGenBase): # 如果有虚表,首字段添加 i8* vtable 指针 if has_vtable == 1: - i8_ptr_ty: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, llvmlite.Int8(pool)) + i8_ptr_ty: llvmlite.LLVMType* = llvmlite.Ptr(pool, llvmlite.Int8(pool)) 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") @@ -482,7 +496,7 @@ class ClassGenDef(ClassGenBase.ClassGenBase): fty_addr: sizet = field_types_buf[fi] if fty_addr == 0: continue - fty: rawptr[llvmlite.LLVMType] = (rawptr[llvmlite.LLVMType])(fty_addr) + fty: llvmlite.LLVMType* = (llvmlite.LLVMType*)(fty_addr) # 创建 ParamNode pnode: rawptr[llvmlite.ParamNode] = pool.alloc(llvmlite.ParamNode.__sizeof__()) @@ -515,7 +529,7 @@ class ClassGenDef(ClassGenBase.ClassGenBase): type_name = tn_copy # 创建 StructType(命名结构体) - struct_ty: rawptr[llvmlite.LLVMType] = llvmlite.Struct(pool, first_node, total_field_count, type_name) + struct_ty: llvmlite.LLVMType* = llvmlite.Struct(pool, first_node, total_field_count, type_name) if struct_ty is None: VLogger.error(f"failed to create StructType for {class_name}", "CLASS") return 0 @@ -530,7 +544,7 @@ class ClassGenDef(ClassGenBase.ClassGenBase): # 后续文件字段类型引用(resolve → Ptr(entry.Ty))→ opaque 扫描遍历悬空 fields # 崩溃(LoopTest _scan_type_for_cross_module_refs 0xFFFF 根因)。 if trans._declare_only == 0 or self.Gen.StructGen.get_stdlib_alloc() != 0: - st_copy: rawptr[llvmlite.LLVMType] = llvmlite.DeepCopyType( + st_copy: llvmlite.LLVMType* = llvmlite.DeepCopyType( CompilerFactory.factory.PermPool, struct_ty) if st_copy is not None: struct_ty = st_copy @@ -553,13 +567,13 @@ class ClassGenDef(ClassGenBase.ClassGenBase): fty_addr_op: sizet = field_types_buf[fi] if fty_addr_op == 0: continue - fty_op: rawptr[llvmlite.LLVMType] = (rawptr[llvmlite.LLVMType])(fty_addr_op) + fty_op: llvmlite.LLVMType* = (llvmlite.LLVMType*)(fty_addr_op) llvmlite.module_ensure_opaque_for_type(trans.Module, pool, fty_op) # ============================================================ # 3. 注册到 HandlesStruct # ============================================================ - entry: rawptr[GenTypes.StructEntry] = self.Gen.StructGen.register_struct( + entry: 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") @@ -598,7 +612,7 @@ class ClassGenDef(ClassGenBase.ClassGenBase): # 添加字段信息 # 如果有虚表,先添加 __vtable__ 字段占位(索引 0),用户字段从索引 1 开始 if has_vtable == 1: - i8_ptr_ty2: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, llvmlite.Int8(pool)) + i8_ptr_ty2: llvmlite.LLVMType* = llvmlite.Ptr(pool, llvmlite.Int8(pool)) self.Gen.StructGen.add_field(pool, entry, "__vtable__", i8_ptr_ty2, None, None) for fi in range(field_count): @@ -609,12 +623,12 @@ class ClassGenDef(ClassGenBase.ClassGenBase): fty_addr2: sizet = field_types_buf[fi] if fty_addr2 == 0: continue - fty2: rawptr[llvmlite.LLVMType] = (rawptr[llvmlite.LLVMType])(fty_addr2) + fty2: llvmlite.LLVMType* = (llvmlite.LLVMType*)(fty_addr2) # 恢复默认值 AST 指针 fdef_addr: sizet = field_defaults_buf[fi] - fdef: rawptr[ast.AST] = None + fdef: ast.AST* = None if fdef_addr != 0: - fdef = (rawptr[ast.AST])(fdef_addr) + fdef = (ast.AST*)(fdef_addr) # 恢复注解类名指针 fannot_addr: sizet = field_annot_buf[fi] fannot: str = None @@ -624,17 +638,23 @@ class ClassGenDef(ClassGenBase.ClassGenBase): fidx_add: int = self.Gen.StructGen.add_field(pool, entry, fname, fty2, fdef, fannot) # t.CVolatile 字段标记(field_volatile_buf[fi] 与 add_field 顺序一一对应) if fidx_add >= 0 and field_volatile_buf[fi] != 0: - fe_vol: rawptr[GenTypes.FieldEntry] = \ + fe_vol: GenTypes.FieldEntry* = \ self.Gen.StructGen._get_field_entry(entry, fidx_add) if fe_vol is not None: fe_vol.IsVolatile = 1 # rawptr[t.CVolatile | T] 字段标记(field_pointee_volatile_buf[fi] 与 # add_field 顺序一一对应):经该字段解引用时 load/store 带 volatile。 if fidx_add >= 0 and field_pointee_volatile_buf[fi] != 0: - fe_pv: rawptr[GenTypes.FieldEntry] = \ + fe_pv: GenTypes.FieldEntry* = \ self.Gen.StructGen._get_field_entry(entry, fidx_add) if fe_pv is not None: fe_pv.PointeeVolatile = 1 + # const 对象字段标记(field_const_buf[fi] 与 add_field 顺序一一对应) + if fidx_add >= 0 and field_const_buf[fi] != 0: + fe_c: GenTypes.FieldEntry* = \ + self.Gen.StructGen._get_field_entry(entry, fidx_add) + if fe_c is not None: + fe_c.IsConst = 1 # Phase 1a 声明模式:只注册 struct + 设置 OOP 标志,不翻译方法体 if trans._declare_only == 1: diff --git a/App/lib/core/Gen/Class/ClassGenEnum.vp b/App/lib/core/Gen/Class/ClassGenEnum.vp index 7d07070..1f1d24a 100644 --- a/App/lib/core/Gen/Class/ClassGenEnum.vp +++ b/App/lib/core/Gen/Class/ClassGenEnum.vp @@ -34,10 +34,10 @@ RENUM_ALIAS_MAX: t.CDefine = 512 class ClassGenEnum(ClassGenBase.ClassGenBase): """enum/union/renum 定义与变体表""" - def _resolve_enum_member_type(self, pool: rawptr[memhub.MemBuddy], - ann_node: rawptr[ast.AST], + def _resolve_enum_member_type(self, pool: memhub.MemBuddy*, + ann_node: ast.AST*, imported_modules: str, - from_imports: str) -> rawptr[llvmlite.LLVMType]: + from_imports: str) -> llvmlite.LLVMType*: """解析枚举成员的类型注解为 LLVM 整数类型""" if ann_node is None: return llvmlite.Int32(pool) @@ -46,7 +46,7 @@ class ClassGenEnum(ClassGenBase.ClassGenBase): # Attribute 节点: t.State / int / int8 等 if k == ast.ASTKind.Attribute: - at: rawptr[ast.Attribute] = rawptr[ast.Attribute](ann_node) + at: ast.Attribute* = ast.Attribute*(ann_node) if at.attr is None: # [S4 fail-fast] Attribute 缺失成员名(AST 损坏),不再静默回退 i32 self.Gen.TypeGenErr.fatal_error( @@ -55,8 +55,14 @@ class ClassGenEnum(ClassGenBase.ClassGenBase): # t.State → 默认 i32 if string.strcmp(at.attr, "State") == 0: return llvmlite.Int32(pool) + # [枚举侧 bool 口径] `t.CBool` 与裸名 `bool` 同宽(8 位),否则同一 + # 枚举成员两种写法会分裂出 i1 / i8 两种宽度。全局 `t.CBool` = i1 + # (map_t_type L1447-1449)保持不变,仅在**枚举成员注解**这一处按 + # 8 位物化(枚举存储须可按字节寻址;TPC 侧 t.CBool.Size = 8 同口径)。 + if string.strcmp(at.attr, "CBool") == 0: + return llvmlite.Int8(pool) # 其他 t.CXxx 类型:统一口径(CTypedef 动态表优先,miss 回退 map_t_type) - ty: rawptr[llvmlite.LLVMType] = self.Gen.TypeGenResolve.resolve_typedef_or_map( + ty: llvmlite.LLVMType* = self.Gen.TypeGenResolve.resolve_typedef_or_map( pool, at.attr, imported_modules, from_imports) if ty is not None: return ty @@ -67,7 +73,7 @@ class ClassGenEnum(ClassGenBase.ClassGenBase): # Name 节点: from-import 形式(State / CInt) if k == ast.ASTKind.Name: - nm: rawptr[ast.Name] = rawptr[ast.Name](ann_node) + nm: ast.Name* = ast.Name*(ann_node) if nm.id is None: # [S4 fail-fast] Name 缺失标识符(AST 损坏),不再静默回退 i32 self.Gen.TypeGenErr.fatal_error( @@ -75,7 +81,23 @@ class ClassGenEnum(ClassGenBase.ClassGenBase): return llvmlite.Int32(pool) # 不可达(fatal_error 已退出) if string.strcmp(nm.id, "State") == 0: return llvmlite.Int32(pool) - ty2: rawptr[llvmlite.LLVMType] = self.Gen.TypeGenResolve.resolve_typedef_or_map( + # 内建裸名整数类型(与 resolve_annotation_type 的 Name 分支同口径, + # TypeGenResolve.vp L2189-2203):枚举成员是整数常量,`int` / `char` / + # `bool` 裸名直通。其余裸名(含 str/bytes 指针形态与未知名)仍走 + # typedef / builtins 表,miss 即下方 fail-fast(不静默当 int); + # 指针与非整数成员的统一拦截见 _translate_enum_def。 + if string.strcmp(nm.id, "int") == 0: + return llvmlite.Int32(pool) + if string.strcmp(nm.id, "char") == 0: + return llvmlite.Int8(pool) + if string.strcmp(nm.id, "bool") == 0: + # [枚举侧 bool 口径] 枚举存储必须是可按字节寻址的整数类型, + # i1 不能作为独立枚举宽度 ⇒ 枚举成员注解的 bool 一律 8 位。 + # **不改**全局 bool = i1(TypeGenResolve.vp L2201-2203 与 + # map_t_type 的 CBool,用于普通变量/形参/字段)。 + # 两侧一致:TPC 侧枚举成员 bool 经 t.CBool.Size 亦为 8。 + return llvmlite.Int8(pool) + ty2: llvmlite.LLVMType* = self.Gen.TypeGenResolve.resolve_typedef_or_map( pool, nm.id, imported_modules, from_imports) if ty2 is not None: return ty2 @@ -86,15 +108,15 @@ class ClassGenEnum(ClassGenBase.ClassGenBase): # BinOp 节点: t.State | int8(递归查找实际类型) if k == ast.ASTKind.BinOp: - bop: rawptr[ast.BinOp] = rawptr[ast.BinOp](ann_node) + bop: ast.BinOp* = ast.BinOp*(ann_node) if bop.op == ast.OpKind.BitOr: - left_ty: rawptr[llvmlite.LLVMType] = self._resolve_enum_member_type( + left_ty: llvmlite.LLVMType* = self._resolve_enum_member_type( pool, bop.left, imported_modules, from_imports) # 跳过 t.State(i32 默认),优先返回具体类型 left_bits: int = self.Gen.TypeGenErr.get_llvm_type_bits(left_ty) if left_bits != 0 and not self._is_state_annotation(bop.left): return left_ty - right_ty: rawptr[llvmlite.LLVMType] = self._resolve_enum_member_type( + right_ty: llvmlite.LLVMType* = self._resolve_enum_member_type( pool, bop.right, imported_modules, from_imports) if right_ty is not None and not self._is_state_annotation(bop.right): return right_ty @@ -112,46 +134,206 @@ class ClassGenEnum(ClassGenBase.ClassGenBase): self.Gen.TypeGenErr.fatal_error( ann_node, f"枚举成员类型注解解析失败: {self.Gen.TypeGenResolve.annotation_to_str(ann_node)}", "TypeError") return llvmlite.Int32(pool) # 不可达(fatal_error 已退出) - def _is_state_annotation(self, node: rawptr[ast.AST]) -> int: + def _is_state_annotation(self, node: ast.AST*) -> int: """检查注解节点是否为 t.State,返回 1=是 / 0=否""" if node is None: return 0 k: int = node.kind() if k == ast.ASTKind.Attribute: - at: rawptr[ast.Attribute] = rawptr[ast.Attribute](node) + at: ast.Attribute* = ast.Attribute*(node) if at.attr is not None and string.strcmp(at.attr, "State") == 0: return 1 return 0 if k == ast.ASTKind.Name: - nm: rawptr[ast.Name] = rawptr[ast.Name](node) + nm: ast.Name* = ast.Name*(node) if nm.id is not None and string.strcmp(nm.id, "State") == 0: return 1 return 0 return 0 - def _extract_int_value(self, node: rawptr[ast.AST]) -> int64: + def _enum_annotation_name_is_ptr(self, node: ast.AST*) -> int: + """注解节点本身(Name/Attribute/Subscript 顶名)是否指针形态,1=是 / 0=否 + + 指针标记名集合与 resolve_annotation_type / map_t_type 的指针产出点同源: + CPtr(= rawptr/str/bytes 的底层,map_t_type L1407)、CNeedPtr / CAutoPtr + (map_t_type L1421-1424 均为 i8*)、rawptr(内建指针,_lookup_builtins_typedef + L921-923 恒返回 t.CPtr)、str / bytes(resolve_annotation_type L2190-2200 → i8*)。 + """ + if node is None: + return 0 + k: int = node.kind() + if k == ast.ASTKind.Attribute: + at: ast.Attribute* = ast.Attribute*(node) + if at.attr is not None: + if string.strcmp(at.attr, "CPtr") == 0: + return 1 + if string.strcmp(at.attr, "CNeedPtr") == 0: + return 1 + if string.strcmp(at.attr, "CAutoPtr") == 0: + return 1 + if string.strcmp(at.attr, "rawptr") == 0: + return 1 + if string.strcmp(at.attr, "str") == 0: + return 1 + if string.strcmp(at.attr, "bytes") == 0: + return 1 + return 0 + if k == ast.ASTKind.Name: + nm: ast.Name* = ast.Name*(node) + if nm.id is not None: + if string.strcmp(nm.id, "CPtr") == 0: + return 1 + if string.strcmp(nm.id, "CNeedPtr") == 0: + return 1 + if string.strcmp(nm.id, "CAutoPtr") == 0: + return 1 + if string.strcmp(nm.id, "rawptr") == 0: + return 1 + if string.strcmp(nm.id, "str") == 0: + return 1 + if string.strcmp(nm.id, "bytes") == 0: + return 1 + return 0 + if k == ast.ASTKind.Subscript: + sub: ast.Subscript* = ast.Subscript*(node) + if sub.value is not None: + return self._enum_annotation_name_is_ptr(sub.value) + return 0 + return 0 + def _enum_member_annotation_is_ptr(self, ann_node: ast.AST*) -> int: + """枚举成员注解(**含联合类型逐边**)是否含指针类型,1=是 / 0=否 + + 联合形态必须逐边检查:`t.CInt | t.CPtr` 在 _resolve_enum_member_type 的 + BinOp 分支会"优先返回具体整数类型"(源码 L94-105)——只看解析结果会把 + 含指针的联合静默当整数,故在解析前按注解树拦。 + """ + if ann_node is None: + return 0 + if ann_node.kind() == ast.ASTKind.BinOp: + bop: ast.BinOp* = ast.BinOp*(ann_node) + if bop.op != ast.OpKind.BitOr: + return 0 + if self._enum_member_annotation_is_ptr(bop.left) == 1: + return 1 + return self._enum_member_annotation_is_ptr(bop.right) + return self._enum_annotation_name_is_ptr(ann_node) + def _extract_int_value(self, node: ast.AST*) -> int64: """从 AST 节点提取整数值,失败返回 0""" if node is None: return 0 k: int = node.kind() if k == ast.ASTKind.Constant: - cn: rawptr[ast.Constant] = rawptr[ast.Constant](node) + cn: ast.Constant* = ast.Constant*(node) if cn.const_kind == ast.CONST_INT: return cn.int_val return 0 if k == ast.ASTKind.UnaryOp: - uo: rawptr[ast.UnaryOp] = rawptr[ast.UnaryOp](node) + uo: ast.UnaryOp* = ast.UnaryOp*(node) if uo.op == ast.OpKind.USub: inner: int64 = self._extract_int_value(uo.operand) return -inner return 0 return 0 - def _translate_enum_def(self, trans: rawptr[HT.Translator], - cd: rawptr[ast.ClassDef]) -> int: + + # ======================================================== + # 枚举成员"可见名 vs 登记名"兜底判据(与 TPC 侧 + # SymbolUtils.EnumBodyMemberNames 同口径、同规则源) + # + # 背景:`enum` 成员行一旦出现"注册器不认的写法",成员会被**静默丢弃** + # (ASTKind 71→3、OpKind 32→2;与 Debugger/enum-semantics.md §15、 + # rawptr-migration-and-fastfail.md §27 同族,这是第三次复发)。取全口径而非 + # 逐个白名单化"已知可展开形态":成员名必然落在 Assign 的 targets / AnnAssign + # 的 target / Expr 语句的表达式这三类"名字位置"之一,把它们**全部**数进来, + # 任何漏登记的写法都会表现为"可见名数 > 登记数" ⇒ 注册处 fail-fast。 + # ======================================================== + def _enum_elts_visible_names(self, elts: list[ast.AST*]*) -> int: + """元素表里的"可见名"计数(Tuple/List 共用)。""" + if elts is None: + return 0 + n: int = 0 + for i in range(len(elts)): + n += self._enum_target_visible_names(elts.get(i)) + return n + def _enum_target_visible_names(self, node: ast.AST*) -> int: + """成员名位置的"可见名"计数(Name / Tuple / List 逐项、Starred 解引用递归)。 + + 与 TPC 侧 SymbolUtils._EnumMemberNameNodes 同口径:把"注册器不认的成员 + 写法"(逗号组 Tuple、元组目标、Starred)里的成员名照样数进来。 + """ + if node is None: + return 0 + k: int = node.kind() + if k == ast.ASTKind.Name: + return 1 + if k == ast.ASTKind.Tuple: + tup: ast.Tuple* = ast.Tuple*(node) + return self._enum_elts_visible_names(tup.elts) + if k == ast.ASTKind.List: + lst: ast.List* = ast.List*(node) + return self._enum_elts_visible_names(lst.elts) + if k == ast.ASTKind.Starred: + st: rawptr[ast.Starred] = rawptr[ast.Starred](node) + return self._enum_target_visible_names(st.value) + return 0 + def _enum_body_visible_names(self, children: list[ast.AST*]*) -> int: + """枚举类体内"源码可见的成员名"总数(含注册器不认的写法)。 + + Assign 的每个 target / AnnAssign 的 target / Expr 语句的表达式; + 不含成员名的语句(docstring / pass / 方法定义 / 嵌套类)计 0,不误报。 + """ + if children is None: + return 0 + n: int = 0 + for ci in range(len(children)): + stmt: ast.AST* = children.get(ci) + if stmt is None: + continue + sk: int = stmt.kind() + if sk == ast.ASTKind.Assign: + ag: ast.Assign* = ast.Assign*(stmt) + if ag.targets is not None: + for ti in range(len(ag.targets)): + n += self._enum_target_visible_names(ag.targets.get(ti)) + elif sk == ast.ASTKind.AnnAssign: + aa: ast.AnnAssign* = ast.AnnAssign*(stmt) + n += self._enum_target_visible_names(aa.target) + elif sk == ast.ASTKind.Expr: + ex: rawptr[ast.Expr] = rawptr[ast.Expr](stmt) + n += self._enum_target_visible_names(ex.value) + return n + def _enum_first_unregistered_node(self, children: list[ast.AST*]*) -> ast.AST*: + """第一个"含可见成员名但注册器不认"的语句(供 fail-fast 定位真行号);无则 None。""" + if children is None: + return None + for ci in range(len(children)): + stmt: ast.AST* = children.get(ci) + if stmt is None: + continue + sk: int = stmt.kind() + if sk == ast.ASTKind.Expr: + ex: rawptr[ast.Expr] = rawptr[ast.Expr](stmt) + if self._enum_target_visible_names(ex.value) > 0: + return stmt + elif sk == ast.ASTKind.AnnAssign: + aa: ast.AnnAssign* = ast.AnnAssign*(stmt) + if aa.target is not None and aa.target.kind() != ast.ASTKind.Name \ + and self._enum_target_visible_names(aa.target) > 0: + return stmt + elif sk == ast.ASTKind.Assign: + ag: ast.Assign* = ast.Assign*(stmt) + if ag.targets is not None: + for ti in range(len(ag.targets)): + tgt: ast.AST* = ag.targets.get(ti) + if tgt is not None and tgt.kind() != ast.ASTKind.Name \ + and self._enum_target_visible_names(tgt) > 0: + return stmt + return None + def _translate_enum_def(self, trans: HT.Translator*, + cd: ast.ClassDef*) -> int: """翻译枚举类定义,返回 0""" if cd is None or cd.name is None or trans is None: return 0 - pool: rawptr[memhub.MemBuddy] = trans.Pool + pool: memhub.MemBuddy* = trans.Pool class_name: str = cd.name # 不按全局同名跳过:跨模块可能同名枚举(includes/w32/fileio.vp 的 @@ -167,8 +349,8 @@ class ClassGenEnum(ClassGenBase.ClassGenBase): cn: sizet = len(children) # 临时数组存储成员信息 - member_names_buf: sizet | t.CPtr = pool.alloc(8 * ENUM_MEMBER_MAX_LOCAL) - member_types_buf: sizet | t.CPtr = pool.alloc(8 * ENUM_MEMBER_MAX_LOCAL) + member_names_buf: sizet* = pool.alloc(8 * ENUM_MEMBER_MAX_LOCAL) + member_types_buf: sizet* = pool.alloc(8 * ENUM_MEMBER_MAX_LOCAL) member_values_buf: int64 | t.CPtr = pool.alloc(8 * ENUM_MEMBER_MAX_LOCAL) if member_names_buf is None or member_types_buf is None or member_values_buf is None: return 0 @@ -180,27 +362,50 @@ class ClassGenEnum(ClassGenBase.ClassGenBase): next_val: int64 = 0 for ci in range(cn): - stmt: rawptr[ast.AST] = children.get(ci) + stmt: ast.AST* = children.get(ci) if stmt is None: continue sk: int = stmt.kind() if sk == ast.ASTKind.AnnAssign: - aa: rawptr[ast.AnnAssign] = rawptr[ast.AnnAssign](stmt) + aa: ast.AnnAssign* = ast.AnnAssign*(stmt) if aa is None or aa.target is None: continue # 获取成员名 if aa.target.kind() != ast.ASTKind.Name: continue - tgt: rawptr[ast.Name] = rawptr[ast.Name](aa.target) + tgt: ast.Name* = ast.Name*(aa.target) if tgt.id is None: continue + # [枚举规格 fail-fast] 成员不允许指针类型:t.CPtr / CNeedPtr / + # CAutoPtr / rawptr[...] / str / bytes,以及**联合类型里夹带指针** + # 的形态(t.CInt | t.CPtr)。必须先于类型解析——联合分支会优先返回 + # 具体整数类型、rawptr[...] 又是 Subscript(非 Name/Attribute/BinOp) + # 会在解析里报笼统的"注解解析失败",两者都盖不住"指针成员"这个真因。 + if self._enum_member_annotation_is_ptr(aa.annotation) == 1: + self.Gen.TypeGenErr.fatal_error( + aa, + f"枚举成员 '{tgt.id}' 不能是指针类型(枚举值只支持整数成员类型)", + "TypeError") + return 0 # 不可达(fatal_error 已退出) + # 解析成员类型 - member_ty: rawptr[llvmlite.LLVMType] = self._resolve_enum_member_type( + member_ty: llvmlite.LLVMType* = self._resolve_enum_member_type( pool, aa.annotation, trans._imported_modules, trans._from_imports) + # [枚举规格 fail-fast] 成员类型必须是整数类型:浮点/void/结构体/ + # 数组的位宽均为 0,无法参与"枚举宽度 = 最宽成员类型"的推导, + # 静默接受会让寄存器宽度与访问侧常量类型不一致。禁止静默降级。 + member_bits: int = self.Gen.TypeGenErr.get_llvm_type_bits(member_ty) + if member_bits <= 0: + self.Gen.TypeGenErr.fatal_error( + aa, + f"枚举成员 '{tgt.id}' 的类型必须为整数类型(不允许指针/浮点/void/结构体/数组),无法推导枚举宽度", + "TypeError") + return 0 # 不可达(fatal_error 已退出) + # 解析成员值 has_value: int = 0 cur_val: int64 = 0 @@ -222,54 +427,83 @@ class ClassGenEnum(ClassGenBase.ClassGenBase): elif sk == ast.ASTKind.Assign: # 处理 Assign 形式的枚举成员: DEBUG = 0, INFO = 1 等 - # CEnum 子类中无类型注释的赋值也视为枚举成员 - ag: rawptr[ast.Assign] = rawptr[ast.Assign](stmt) + # CEnum 子类中无类型注释的赋值也视为枚举成员。 + # 每个 Name target 都是成员(`A = B = 1` 两个名字都登记——与 TPC + # HandlesClassDef._RegisterEnumMembers 的逐 target 口径一致;此前 + # 只取 targets[0] 会让后续 target 静默漏成员)。 + ag: ast.Assign* = ast.Assign*(stmt) if ag is None or ag.targets is None: continue tgts: list[ast.AST*]* = ag.targets tn: sizet = len(tgts) if tn == 0: continue - # 取第一个 target 作为成员名 - t0: rawptr[ast.AST] = tgts.get(0) - if t0 is None or t0.kind() != ast.ASTKind.Name: - continue - tgt_a: rawptr[ast.Name] = rawptr[ast.Name](t0) - if tgt_a.id is None: - continue # Assign 无类型注释,默认使用 i32 - member_ty_a: rawptr[llvmlite.LLVMType] = llvmlite.Int32(pool) + member_ty_a: llvmlite.LLVMType* = llvmlite.Int32(pool) - # 解析成员值 + # 解析成员值(同一语句的所有 target 共享该值,next_val 只推进一次) cur_val_a: int64 = 0 if ag.value is not None: cur_val_a = self._extract_int_value(ag.value) else: cur_val_a = next_val - - # 下一个自动值 next_val = cur_val_a + 1 - # 存储 - if member_count < ENUM_MEMBER_MAX_LOCAL: - member_names_buf[member_count] = sizet(tgt_a.id) - member_types_buf[member_count] = sizet(member_ty_a) - member_values_buf[member_count] = cur_val_a - member_count += 1 + # 存储(逐 target;非 Name target 由注册处兜底判据拦住) + for ti in range(tn): + t0: ast.AST* = tgts.get(ti) + if t0 is None or t0.kind() != ast.ASTKind.Name: + continue + tgt_a: ast.Name* = ast.Name*(t0) + if tgt_a.id is None: + continue + if member_count < ENUM_MEMBER_MAX_LOCAL: + member_names_buf[member_count] = sizet(tgt_a.id) + member_types_buf[member_count] = sizet(member_ty_a) + member_values_buf[member_count] = cur_val_a + member_count += 1 + + # [兜底判据 fail-fast] "源码里可见的成员名字数" vs "实际登记成员数"。 + # 任何注册器不认的成员写法(逗号组带值 `A, B = 1`、逗号组带注解 + # `A, B: T`、单名尾随逗号 `A,`、元组目标,以及未来出现的新形态)都会让 + # 可见名数 > 登记数——此前是**静默丢成员**(ASTKind 71→3、OpKind 32→2; + # 与 Debugger/enum-semantics.md §15、rawptr-migration-and-fastfail.md §27 + # 同族,这是第三次复发),此处一律 fail-fast,不再静默跳过。 + # 判据口径与 TPC HandlesClassDef._RegisterEnumMembers 完全一致(同规则源)。 + visible_count: int = self._enum_body_visible_names(children) + if visible_count != member_count: + diff_count: int = visible_count - member_count + bad: ast.AST* = self._enum_first_unregistered_node(children) + bad_desc: str = "(无法定位到具体语句,请检查枚举体)" + if bad is not None: + bad_desc = bad.type_name() + self.Gen.TypeGenErr.fatal_error( + bad if bad is not None else cd, + f"枚举 '{class_name}' 成员登记数不一致:源码里可见的成员名 {visible_count} 个," + f"实际只登记 {member_count} 个(差额 {diff_count} 个会被静默丢弃)。" + f"未识别的成员写法(首个): {bad_desc} 形态的语句——如逗号组带值 `A, B = 1`、" + f"逗号组带注解 `A, B: T`、单名尾随逗号 `A,`。" + f"期望形态: 每行一个 `Name` / `Name: T` / `Name = 值`," + f"或多个简单标识符用逗号分隔(`A, B, C`,可带尾随逗号)。" + f"修法: 把该行改写为逐个成员一行,或改写为纯标识符逗号组(去掉 `= 值` / `: T`)。" + f"(本判据在注册处比对『可见名数 vs 登记数』,任何未识别形态都会命中," + f"不再静默丢成员)", + "TypeError") + return 0 if member_count == 0: VLogger.warning(f"{class_name} has no members", "ENUM") return 0 # 确定基准类型:所有成员类型中 Bits 最大的 - base_ty: rawptr[llvmlite.LLVMType] = llvmlite.Int32(pool) + base_ty: llvmlite.LLVMType* = llvmlite.Int32(pool) max_bits: int = 0 for mi in range(member_count): ty_addr: sizet = member_types_buf[mi] if ty_addr == 0: continue - mty: rawptr[llvmlite.LLVMType] = (rawptr[llvmlite.LLVMType])(ty_addr) + mty: llvmlite.LLVMType* = (llvmlite.LLVMType*)(ty_addr) bits: int = self.Gen.TypeGenErr.get_llvm_type_bits(mty) if bits > max_bits: max_bits = bits @@ -291,7 +525,7 @@ class ClassGenEnum(ClassGenBase.ClassGenBase): fty_addr2: sizet = member_types_buf[mi] if fty_addr2 == 0: continue - mty2: rawptr[llvmlite.LLVMType] = (rawptr[llvmlite.LLVMType])(fty_addr2) + mty2: llvmlite.LLVMType* = (llvmlite.LLVMType*)(fty_addr2) mval: int64 = member_values_buf[mi] if mname is not None and mty2 is not None: self.Gen.StmtGenDecl.add_enum_member(pool, entry, mname, mval, mty2) @@ -299,7 +533,7 @@ class ClassGenEnum(ClassGenBase.ClassGenBase): VLogger.info(f"registered {class_name} with {member_count} members, base_bits={max_bits}", "ENUM") return 0 - def _get_type_size(self, ty: rawptr[llvmlite.LLVMType]) -> int: + def _get_type_size(self, ty: llvmlite.LLVMType*) -> int: """计算 LLVM 类型的字节大小(含对齐 padding)""" if ty is None: return 0 @@ -326,7 +560,7 @@ class ClassGenEnum(ClassGenBase.ClassGenBase): i: int = 0 while cur is not None and i < fcount: if cur.Ty is not None: - fty: rawptr[llvmlite.LLVMType] = (rawptr[llvmlite.LLVMType])(cur.Ty) + fty: llvmlite.LLVMType* = (llvmlite.LLVMType*)(cur.Ty) fsize: int = self._get_type_size(fty) falign: int = self._get_type_align(fty) # 对齐当前偏移到字段对齐边界(packed 不插填充) @@ -348,7 +582,7 @@ class ClassGenEnum(ClassGenBase.ClassGenBase): return total case _: return 8 - def _get_type_align(self, ty: rawptr[llvmlite.LLVMType]) -> int: + def _get_type_align(self, ty: llvmlite.LLVMType*) -> int: """返回类型的自然对齐(字节)""" if ty is None: return 1 @@ -381,7 +615,7 @@ class ClassGenEnum(ClassGenBase.ClassGenBase): i: int = 0 while cur is not None and i < fcount: if cur.Ty is not None: - fty: rawptr[llvmlite.LLVMType] = (rawptr[llvmlite.LLVMType])(cur.Ty) + fty: llvmlite.LLVMType* = (llvmlite.LLVMType*)(cur.Ty) fa: int = self._get_type_align(fty) if fa > max_align: max_align = fa @@ -390,20 +624,20 @@ class ClassGenEnum(ClassGenBase.ClassGenBase): return max_align case _: return 8 - def _translate_union_def(self, trans: rawptr[HT.Translator], - cd: rawptr[ast.ClassDef]) -> int: + def _translate_union_def(self, trans: HT.Translator*, + cd: ast.ClassDef*) -> int: """翻译联合体定义,返回 0""" if cd is None or cd.name is None or trans is None: return 0 - pool: rawptr[memhub.MemBuddy] = trans.Pool + pool: memhub.MemBuddy* = trans.Pool class_name: str = cd.name # 命名空间隔离:标记为当前文件可见(必须在 existing 检查之前) self.Gen.StructGen.add_visible_struct(pool, class_name) # 检查是否已注册(用 SHA1 区分跨模块同名类) - existing: rawptr[GenTypes.StructEntry] = self.Gen.StructGen.find_struct_by_module( + existing: GenTypes.StructEntry* = self.Gen.StructGen.find_struct_by_module( class_name, trans.ModuleSha1) if existing is not None: # Phase B: 将已存在的命名结构体注册到当前模块 @@ -420,8 +654,8 @@ class ClassGenEnum(ClassGenBase.ClassGenBase): cn: sizet = len(children) # 临时数组存储字段信息 - field_names_buf: sizet | t.CPtr = pool.alloc(8 * GenTypes.FIELD_MAX) - field_types_buf: sizet | t.CPtr = pool.alloc(8 * GenTypes.FIELD_MAX) + field_names_buf: sizet* = pool.alloc(8 * GenTypes.FIELD_MAX) + field_types_buf: sizet* = pool.alloc(8 * GenTypes.FIELD_MAX) if field_names_buf is None or field_types_buf is None: return 0 string.memset(field_names_buf, 0, 8 * GenTypes.FIELD_MAX) @@ -431,25 +665,25 @@ class ClassGenEnum(ClassGenBase.ClassGenBase): max_size: int = 0 for ci in range(cn): - stmt: rawptr[ast.AST] = children.get(ci) + stmt: ast.AST* = children.get(ci) if stmt is None: continue sk: int = stmt.kind() if sk == ast.ASTKind.AnnAssign: - aa: rawptr[ast.AnnAssign] = rawptr[ast.AnnAssign](stmt) + aa: ast.AnnAssign* = ast.AnnAssign*(stmt) if aa is None or aa.target is None: continue # 获取字段名 if aa.target.kind() != ast.ASTKind.Name: continue - tgt: rawptr[ast.Name] = rawptr[ast.Name](aa.target) + tgt: ast.Name* = ast.Name*(aa.target) if tgt.id is None: continue # 解析字段类型 - field_ty: rawptr[llvmlite.LLVMType] = self.Gen.TypeGenResolve.resolve_annotation_type( + field_ty: llvmlite.LLVMType* = self.Gen.TypeGenResolve.resolve_annotation_type( pool, aa.annotation, trans._imported_modules, trans._from_imports, trans, 0) if field_ty is None: # Phase A-pre(declare_only=1):依赖的类可能尚未注册, @@ -484,8 +718,8 @@ class ClassGenEnum(ClassGenBase.ClassGenBase): # 创建联合体的 LLVM 类型: Struct([Array(Int8, max_size)]) # 即 { [max_size x i8] } - i8_ty: rawptr[llvmlite.LLVMType] = llvmlite.Int8(pool) - array_ty: rawptr[llvmlite.LLVMType] = llvmlite.Array(pool, i8_ty, max_size) + i8_ty: llvmlite.LLVMType* = llvmlite.Int8(pool) + array_ty: llvmlite.LLVMType* = llvmlite.Array(pool, i8_ty, max_size) # 构建 ParamNode 链表(单字段:字节数组) pnode: rawptr[llvmlite.ParamNode] = pool.alloc(llvmlite.ParamNode.__sizeof__()) @@ -502,7 +736,7 @@ class ClassGenEnum(ClassGenBase.ClassGenBase): viperlib.snprintf(union_name_buf, 64, "%s.%s", trans.ModuleSha1, class_name) union_type_name = union_name_buf - union_ty: rawptr[llvmlite.LLVMType] = llvmlite.Struct(pool, pnode, 1, union_type_name) + union_ty: llvmlite.LLVMType* = llvmlite.Struct(pool, pnode, 1, union_type_name) if union_ty is None: VLogger.error(f"failed to create type for {class_name}", "UNION") return 0 @@ -513,7 +747,7 @@ class ClassGenEnum(ClassGenBase.ClassGenBase): # entry.Ty 悬空 → 后续文件 opaque 扫描跨模块引用遍历悬空 fields 崩溃 # (LoopTest _scan_type_for_cross_module_refs 0xFFFF 根因)。 if trans._declare_only == 0 or self.Gen.StructGen.get_stdlib_alloc() != 0: - union_copy: rawptr[llvmlite.LLVMType] = llvmlite.DeepCopyType( + union_copy: llvmlite.LLVMType* = llvmlite.DeepCopyType( CompilerFactory.factory.PermPool, union_ty) if union_copy is not None: union_ty = union_copy @@ -522,7 +756,7 @@ class ClassGenEnum(ClassGenBase.ClassGenBase): llvmlite.module_add_named_type(trans.Module, pool, union_ty) # 注册到 HandlesStruct(传递 SHA1 在注册时直接设置,避免跨模块同名找错 entry) - entry: rawptr[GenTypes.StructEntry] = self.Gen.StructGen.register_struct( + entry: 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") @@ -543,14 +777,14 @@ class ClassGenEnum(ClassGenBase.ClassGenBase): fty_addr2: sizet = field_types_buf[fi] if fty_addr2 == 0: continue - fty2: rawptr[llvmlite.LLVMType] = (rawptr[llvmlite.LLVMType])(fty_addr2) + fty2: llvmlite.LLVMType* = (llvmlite.LLVMType*)(fty_addr2) if fname is not None and fty2 is not None: self.Gen.StructGen.add_field(pool, entry, fname, fty2, None, None) VLogger.info(f"registered {class_name} with {field_count} fields, max_size={max_size}", "UNION") return 0 - def _get_annotation_field_size(self, pool: rawptr[memhub.MemBuddy], - annotation: rawptr[ast.AST]) -> int: + def _get_annotation_field_size(self, pool: memhub.MemBuddy*, + annotation: ast.AST*) -> int: """计算注解类型的字节大小,用于 REnum 布局计算""" if annotation is None: return 8 @@ -561,11 +795,11 @@ class ClassGenEnum(ClassGenBase.ClassGenBase): # Name(id) 或 Attribute(attr) → 解析类型名 type_name: str = None if k == ast.ASTKind.Name: - nm: rawptr[ast.Name] = rawptr[ast.Name](annotation) + nm: ast.Name* = ast.Name*(annotation) if nm is not None: type_name = nm.id elif k == ast.ASTKind.Attribute: - at: rawptr[ast.Attribute] = rawptr[ast.Attribute](annotation) + at: ast.Attribute* = ast.Attribute*(annotation) if at is not None: type_name = at.attr if type_name is None: @@ -606,27 +840,27 @@ class ClassGenEnum(ClassGenBase.ClassGenBase): # bool = t.CBool = i8(1 字节) return 1 # 已注册的结构体类型 - struct_ty: rawptr[llvmlite.LLVMType] = self.Gen.StructGen.get_struct_type(type_name) + struct_ty: llvmlite.LLVMType* = self.Gen.StructGen.get_struct_type(type_name) if struct_ty is not None: sz: int = self._get_type_size(struct_ty) if sz > 0: return sz # 未注册类型 → 默认指针大小 8(可能是自引用或前向引用) return 8 - def _translate_renum_def(self, trans: rawptr[HT.Translator], - cd: rawptr[ast.ClassDef]) -> int: + def _translate_renum_def(self, trans: HT.Translator*, + cd: ast.ClassDef*) -> int: """翻译 REnum 类定义,返回 0""" if cd is None or cd.name is None or trans is None: return 0 - pool: rawptr[memhub.MemBuddy] = trans.Pool + pool: memhub.MemBuddy* = trans.Pool class_name: str = cd.name # 命名空间隔离:标记为当前文件可见 self.Gen.StructGen.add_visible_struct(pool, class_name) # 检查是否已注册(用 SHA1 区分跨模块同名类) - existing: rawptr[GenTypes.StructEntry] = self.Gen.StructGen.find_struct_by_module( + existing: GenTypes.StructEntry* = self.Gen.StructGen.find_struct_by_module( class_name, trans.ModuleSha1) if existing is not None: # existing 只保证 struct entry 在,不保证 REnum 语义(变体表)在:struct entry @@ -660,7 +894,7 @@ class ClassGenEnum(ClassGenBase.ClassGenBase): # 变体最多 32 个,每个变体最多 16 个字段 # variant_field_sizes[i][j] = 变体 i 的第 j 个字段大小 - variant_field_sizes: sizet | t.CPtr = pool.alloc(8 * 64 * 16) + variant_field_sizes: sizet* = pool.alloc(8 * 64 * 16) if variant_field_sizes is None: return 0 string.memset(variant_field_sizes, 0, 8 * 64 * 16) @@ -669,14 +903,14 @@ class ClassGenEnum(ClassGenBase.ClassGenBase): max_field_count: int = 0 # 所有变体中最大字段数 for ci in range(cn): - stmt: rawptr[ast.AST] = children.get(ci) + stmt: ast.AST* = children.get(ci) if stmt is None: continue sk: int = stmt.kind() if sk == ast.ASTKind.ClassDef: # 嵌套变体类 - variant_cd: rawptr[ast.ClassDef] = rawptr[ast.ClassDef](stmt) + variant_cd: ast.ClassDef* = ast.ClassDef*(stmt) if variant_cd is None or variant_cd.children is None: variant_count += 1 continue @@ -684,19 +918,19 @@ class ClassGenEnum(ClassGenBase.ClassGenBase): vcn: sizet = len(variant_children) field_idx: int = 0 for vi in range(vcn): - vstmt: rawptr[ast.AST] = variant_children.get(vi) + vstmt: ast.AST* = variant_children.get(vi) if vstmt is None: continue vk: int = vstmt.kind() if vk != ast.ASTKind.AnnAssign: continue - vaa: rawptr[ast.AnnAssign] = rawptr[ast.AnnAssign](vstmt) + vaa: ast.AnnAssign* = ast.AnnAssign*(vstmt) if vaa is None or vaa.target is None or vaa.annotation is None: continue if vaa.target.kind() != ast.ASTKind.Name: continue # 提取字段名 - vnm: rawptr[ast.Name] = rawptr[ast.Name](vaa.target) + vnm: ast.Name* = ast.Name*(vaa.target) # 计算字段大小 fsize: int = self._get_annotation_field_size(pool, vaa.annotation) if variant_count < 32 and field_idx < 16: @@ -710,7 +944,7 @@ class ClassGenEnum(ClassGenBase.ClassGenBase): # 不存类型,绑定回退槽位类型。variant_cd.name 在 1a reset # 后悬空,注册内部会 strcpy 到 perm_pool。 if vnm is not None and vnm.id is not None: - mem_ty_l: rawptr[llvmlite.LLVMType] = None + mem_ty_l: llvmlite.LLVMType* = None if trans is not None: mem_ty_l = self.Gen.TypeGenResolve.resolve_annotation_type( pool, vaa.annotation, @@ -729,16 +963,16 @@ class ClassGenEnum(ClassGenBase.ClassGenBase): # 只是无字段。不认则 variant_count 与变体表都漏掉该变体 ⇒ match 的 # `case Option.Empty():` 查表失配 tag=-1 → 硬校验 fail-fast。 # tag 值由 _register_renum_variants 按同一口径分配(显式值优先)。 - ag_v: rawptr[ast.Assign] = rawptr[ast.Assign](stmt) + ag_v: ast.Assign* = ast.Assign*(stmt) if ag_v is None or ag_v.targets is None: continue tgts_v: list[ast.AST*]* = ag_v.targets if len(tgts_v) == 0: continue - t0_v: rawptr[ast.AST] = tgts_v.get(0) + t0_v: ast.AST* = tgts_v.get(0) if t0_v is None or t0_v.kind() != ast.ASTKind.Name: continue - tgt_v: rawptr[ast.Name] = rawptr[ast.Name](t0_v) + tgt_v: ast.Name* = ast.Name*(t0_v) if tgt_v.id is None: continue variant_count += 1 @@ -758,7 +992,7 @@ class ClassGenEnum(ClassGenBase.ClassGenBase): if total_positions < 2: total_positions = 2 # 至少 {i32, i32} - position_max_sizes: sizet | t.CPtr = pool.alloc(8 * total_positions) + position_max_sizes: sizet* = pool.alloc(8 * total_positions) if position_max_sizes is None: return 0 string.memset(position_max_sizes, 0, 8 * total_positions) @@ -782,18 +1016,18 @@ class ClassGenEnum(ClassGenBase.ClassGenBase): position_max_sizes[pos] = sizet(pos_max) # 构建 ParamNode 链表 - i32_ty: rawptr[llvmlite.LLVMType] = llvmlite.Int32(pool) - i64_ty: rawptr[llvmlite.LLVMType] = llvmlite.Int64(pool) + i32_ty: llvmlite.LLVMType* = llvmlite.Int32(pool) + i64_ty: llvmlite.LLVMType* = llvmlite.Int64(pool) - first_node: rawptr[llvmlite.Function] = None - tail_node: rawptr[llvmlite.Function] = None + first_node: llvmlite.Function* = None + tail_node: llvmlite.Function* = None for pos in range(total_positions): psize: int = position_max_sizes[pos] - field_ty: rawptr[llvmlite.LLVMType] = i32_ty + field_ty: llvmlite.LLVMType* = i32_ty if psize > 4: field_ty = i64_ty - pnode: rawptr[llvmlite.Function] = llvmlite.new_param_node(pool, field_ty) + pnode: llvmlite.Function* = llvmlite.new_param_node(pool, field_ty) if pnode is None: continue tail_node = llvmlite.param_list_append(first_node, tail_node, pnode) @@ -812,7 +1046,7 @@ class ClassGenEnum(ClassGenBase.ClassGenBase): viperlib.snprintf(renum_name_buf, 64, "%s.%s", trans.ModuleSha1, class_name) renum_type_name = renum_name_buf - renum_ty: rawptr[llvmlite.LLVMType] = llvmlite.Struct( + renum_ty: llvmlite.LLVMType* = llvmlite.Struct( pool, first_node, total_positions, renum_type_name) if renum_ty is None: VLogger.error(f"failed to create type for {class_name}", "RENUM") @@ -822,7 +1056,7 @@ class ClassGenEnum(ClassGenBase.ClassGenBase): # 与 entry.Ty 保持同一指针,find_struct_by_type 匹配不失效) # StdlibAlloc=1(Phase2 mark2 后)也必须深拷贝:同 union 的悬空根因。 if trans._declare_only == 0 or self.Gen.StructGen.get_stdlib_alloc() != 0: - renum_copy: rawptr[llvmlite.LLVMType] = llvmlite.DeepCopyType( + renum_copy: llvmlite.LLVMType* = llvmlite.DeepCopyType( CompilerFactory.factory.PermPool, renum_ty) if renum_copy is not None: renum_ty = renum_copy @@ -831,7 +1065,7 @@ class ClassGenEnum(ClassGenBase.ClassGenBase): llvmlite.module_add_named_type(trans.Module, pool, renum_ty) # 注册到 HandlesStruct - entry: rawptr[GenTypes.StructEntry] = self.Gen.StructGen.register_struct( + entry: 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") @@ -843,7 +1077,7 @@ class ClassGenEnum(ClassGenBase.ClassGenBase): # 添加 payload 字段(位置 1+,i32 或 i64) for pos in range(1, total_positions): psize2: int = position_max_sizes[pos] - payload_ty: rawptr[llvmlite.LLVMType] = i32_ty + payload_ty: llvmlite.LLVMType* = i32_ty if psize2 > 4: payload_ty = i64_ty field_name_buf: str = pool.alloc(16) @@ -863,10 +1097,10 @@ class ClassGenEnum(ClassGenBase.ClassGenBase): VLogger.info(f"registered {class_name} with {variant_count} variants, {total_positions} positions", "RENUM") return 0 - def _refill_renum_field_types(self, trans: rawptr[HT.Translator], - pool: rawptr[memhub.MemBuddy], + def _refill_renum_field_types(self, trans: HT.Translator*, + pool: memhub.MemBuddy*, class_name: str, - cd: rawptr[ast.ClassDef]): + cd: ast.ClassDef*): """REnum 注册完成后补解析变体字段类型(仅回填类型槽为 0 的别名记录) 第一遍变体字段遍历发生在 register_struct 之前:字段注解引用本 REnum 类 @@ -891,10 +1125,10 @@ class ClassGenEnum(ClassGenBase.ClassGenBase): return cn: sizet = len(children) for ci in range(cn): - stmt: rawptr[ast.AST] = children.get(ci) + stmt: ast.AST* = children.get(ci) if stmt is None or stmt.kind() != ast.ASTKind.ClassDef: continue - variant_cd: rawptr[ast.ClassDef] = rawptr[ast.ClassDef](stmt) + variant_cd: ast.ClassDef* = ast.ClassDef*(stmt) if variant_cd is None or variant_cd.name is None \ or variant_cd.children is None: continue @@ -902,23 +1136,23 @@ class ClassGenEnum(ClassGenBase.ClassGenBase): vcn: sizet = len(vchildren) field_idx: int = 0 for vi in range(vcn): - vstmt: rawptr[ast.AST] = vchildren.get(vi) + vstmt: ast.AST* = vchildren.get(vi) if vstmt is None: continue if vstmt.kind() != ast.ASTKind.AnnAssign: continue - vaa: rawptr[ast.AnnAssign] = rawptr[ast.AnnAssign](vstmt) + vaa: ast.AnnAssign* = ast.AnnAssign*(vstmt) if vaa is None or vaa.target is None or vaa.annotation is None: # 与第一遍同规则:无效 AnnAssign 不占用 payload 槽位 continue if vaa.target.kind() != ast.ASTKind.Name: continue - vnm: rawptr[ast.Name] = rawptr[ast.Name](vaa.target) + vnm: ast.Name* = ast.Name*(vaa.target) if vnm.id is None: # 与第一遍同规则:有效 AnnAssign 仍占用 payload 槽位 field_idx += 1 continue - mem_ty_l: rawptr[llvmlite.LLVMType] = \ + mem_ty_l: llvmlite.LLVMType* = \ self.Gen.TypeGenResolve.resolve_annotation_type( pool, vaa.annotation, trans._imported_modules, @@ -929,9 +1163,9 @@ class ClassGenEnum(ClassGenBase.ClassGenBase): pool, class_name, vnm.id, field_idx + 1, mem_ty_l, variant_cd.name) field_idx += 1 - def _register_renum_variants(self, pool: rawptr[memhub.MemBuddy], + def _register_renum_variants(self, pool: memhub.MemBuddy*, class_name: str, - cd: rawptr[ast.ClassDef], + cd: ast.ClassDef*, variant_count: int): """注册 REnum 类的变体名和 tag 值到全局变体表""" if pool is None or class_name is None or cd is None: @@ -1005,16 +1239,16 @@ class ClassGenEnum(ClassGenBase.ClassGenBase): # 第一遍:扫出 Assign 变体的显式整数值上界(无显式值时保持 -1) max_explicit: int = -1 for ci in range(cn): - stmt_p: rawptr[ast.AST] = children.get(ci) + stmt_p: ast.AST* = children.get(ci) if stmt_p is None or stmt_p.kind() != ast.ASTKind.Assign: continue - ag_p: rawptr[ast.Assign] = rawptr[ast.Assign](stmt_p) + ag_p: ast.Assign* = 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[ast.AST*]* = ag_p.targets if len(tgts_p) == 0: continue - t0_p: rawptr[ast.AST] = tgts_p.get(0) + t0_p: ast.AST* = tgts_p.get(0) if t0_p is None or t0_p.kind() != ast.ASTKind.Name: continue if ag_p.value.kind() != ast.ASTKind.Constant: @@ -1036,14 +1270,14 @@ class ClassGenEnum(ClassGenBase.ClassGenBase): # 每类固定 32 槽:变体超过上限继续写会越界污染相邻类槽,fail-fast 报错 VLogger.error(f"REnum 变体数超过上限 {RENUM_VARIANT_PER_CLASS}: {class_name}", "RENUM") break - stmt: rawptr[ast.AST] = children.get(ci) + stmt: ast.AST* = children.get(ci) if stmt is None: continue sk_rv: int = stmt.kind() vname_ptr: sizet = 0 tag_val: int = 0 if sk_rv == ast.ASTKind.ClassDef: - vcd: rawptr[ast.ClassDef] = rawptr[ast.ClassDef](stmt) + vcd: ast.ClassDef* = ast.ClassDef*(stmt) if vcd is None or vcd.name is None: continue vname_ptr = sizet(vcd.name) @@ -1051,16 +1285,16 @@ class ClassGenEnum(ClassGenBase.ClassGenBase): next_class_tag += 1 elif sk_rv == ast.ASTKind.Assign: # Assign 形式无载荷变体(与 _translate_renum_def 首遍同过滤口径) - ag_rv: rawptr[ast.Assign] = rawptr[ast.Assign](stmt) + ag_rv: ast.Assign* = ast.Assign*(stmt) if ag_rv is None or ag_rv.targets is None: continue tgts_rv: list[ast.AST*]* = ag_rv.targets if len(tgts_rv) == 0: continue - t0_rv: rawptr[ast.AST] = tgts_rv.get(0) + t0_rv: ast.AST* = tgts_rv.get(0) if t0_rv is None or t0_rv.kind() != ast.ASTKind.Name: continue - tgt_rv: rawptr[ast.Name] = rawptr[ast.Name](t0_rv) + tgt_rv: ast.Name* = ast.Name*(t0_rv) if tgt_rv.id is None: continue vname_ptr = sizet(tgt_rv.id) @@ -1140,7 +1374,7 @@ class ClassGenEnum(ClassGenBase.ClassGenBase): """ if class_name is None: return 0 - st: rawptr[llvmlite.LLVMType] = self.Gen.StructGen.get_struct_type(class_name) + st: llvmlite.LLVMType* = self.Gen.StructGen.get_struct_type(class_name) if st is None: return 0 if self.Gen.StructGen.lookup_field(st, "__tag") is None: @@ -1172,11 +1406,11 @@ class ClassGenEnum(ClassGenBase.ClassGenBase): return self.RenumVariantTags[name_offset] return -1 return -1 - def _register_renum_field_alias(self, pool: rawptr[memhub.MemBuddy], + def _register_renum_field_alias(self, pool: memhub.MemBuddy*, class_name: str, field_name: str, payload_idx: int, - field_ty: rawptr[llvmlite.LLVMType] = None, + field_ty: llvmlite.LLVMType* = None, variant_name: str = None): """注册 REnum 变体字段名别名到全局表 @@ -1191,7 +1425,7 @@ class ClassGenEnum(ClassGenBase.ClassGenBase): # 懒初始化表(perm_pool:1a 每文件 reset 后表本体不被回收) if self.RenumAliasClass is None: - alias_pool_rfa: rawptr[memhub.MemBuddy] = CompilerFactory.factory.PermPool + alias_pool_rfa: memhub.MemBuddy* = CompilerFactory.factory.PermPool self.RenumAliasClass = alias_pool_rfa.alloc(8 * RENUM_ALIAS_MAX) self.RenumAliasField = alias_pool_rfa.alloc(8 * RENUM_ALIAS_MAX) self.RenumAliasIndex = alias_pool_rfa.alloc(8 * RENUM_ALIAS_MAX) @@ -1230,7 +1464,7 @@ class ClassGenEnum(ClassGenBase.ClassGenBase): # _refill_renum_field_types)类型槽为 0 时,本次解析成功则 # 回填真实类型;非 0 槽保持原样(避免重复 DeepCopy 覆盖抖动)。 if self.RenumAliasTy[i] == 0 and field_ty is not None: - ty_copy_rf2: rawptr[llvmlite.LLVMType] = llvmlite.DeepCopyType( + ty_copy_rf2: llvmlite.LLVMType* = llvmlite.DeepCopyType( CompilerFactory.factory.PermPool, field_ty) if ty_copy_rf2 is not None: self.RenumAliasTy[i] = sizet(ty_copy_rf2) @@ -1258,7 +1492,7 @@ class ClassGenEnum(ClassGenBase.ClassGenBase): # 未解析成功(自引用等)存 0,绑定回退槽位类型) self.RenumAliasTy[idx] = 0 if field_ty is not None: - ty_copy_rfa: rawptr[llvmlite.LLVMType] = llvmlite.DeepCopyType( + ty_copy_rfa: llvmlite.LLVMType* = llvmlite.DeepCopyType( CompilerFactory.factory.PermPool, field_ty) if ty_copy_rfa is not None: self.RenumAliasTy[idx] = sizet(ty_copy_rfa) @@ -1290,7 +1524,7 @@ class ClassGenEnum(ClassGenBase.ClassGenBase): return self.RenumAliasIndex[i] return -1 def _lookup_renum_field_alias_ty(self, class_name: str, - field_name: str) -> rawptr[llvmlite.LLVMType]: + field_name: str) -> llvmlite.LLVMType*: """查找 REnum 变体成员的实际 LLVM 类型,返回类型或 None 与 _lookup_renum_field_alias 同表同键(class/field 均 strcmp 内容比较)。 @@ -1305,11 +1539,11 @@ class ClassGenEnum(ClassGenBase.ClassGenBase): if fld_existing_ptr is not None and string.strcmp(fld_existing_ptr, field_name) == 0: if self.RenumAliasTy[i] == 0: return None - return (rawptr[llvmlite.LLVMType])(self.RenumAliasTy[i]) + return (llvmlite.LLVMType*)(self.RenumAliasTy[i]) return None def _lookup_renum_member_ty(self, class_name: str, variant_name: str, - payload_idx: int) -> rawptr[llvmlite.LLVMType]: + payload_idx: int) -> llvmlite.LLVMType*: """按 (class, 变体名, payload 位置) 查找变体成员的实际 LLVM 类型 match 绑定用:同一 payload 位置跨变体类型不同(Int.Bits=i32 vs @@ -1333,5 +1567,5 @@ class ClassGenEnum(ClassGenBase.ClassGenBase): continue if self.RenumAliasTy[i] == 0: return None - return (rawptr[llvmlite.LLVMType])(self.RenumAliasTy[i]) + return (llvmlite.LLVMType*)(self.RenumAliasTy[i]) return None \ No newline at end of file diff --git a/App/lib/core/Gen/Class/ClassGenGeneric.vp b/App/lib/core/Gen/Class/ClassGenGeneric.vp index 5b32894..5c4322b 100644 --- a/App/lib/core/Gen/Class/ClassGenGeneric.vp +++ b/App/lib/core/Gen/Class/ClassGenGeneric.vp @@ -43,7 +43,7 @@ class ClassGenGeneric(ClassGenBase.ClassGenBase): # - _spec_* 全局缓存迁移为 self.SpecKeys/SpecNames/SpecCount # ============================================================ - def _is_generic_class(self, tp: list[str] | t.CPtr) -> int: + def _is_generic_class(self, tp: list[str]*) -> int: """检查 ClassDef 是否有类型参数(泛型类),返回 1=是 / 0=否 接收 type_params 而非 cd,避免 cd.type_params 属性访问 @@ -56,7 +56,7 @@ class ClassGenGeneric(ClassGenBase.ClassGenBase): """深拷贝字符串到永久池(无永久池/分配失败时原样返回入参)""" if s is None: return None - perm: rawptr[memhub.MemBuddy] = CompilerFactory.factory.PermPool + perm: memhub.MemBuddy* = CompilerFactory.factory.PermPool if perm is None: return s n: sizet = string.strlen(s) @@ -65,8 +65,8 @@ class ClassGenGeneric(ClassGenBase.ClassGenBase): return s string.strcpy(b, s) return b - def _register_generic_template(self, pool: rawptr[memhub.MemBuddy], - cd: rawptr[ast.ClassDef], + def _register_generic_template(self, pool: memhub.MemBuddy*, + cd: ast.ClassDef*, module_sha1: str) -> None: """注册泛型类模板(类名 + ClassDef 节点 + 来源模块 SHA1) @@ -94,13 +94,13 @@ class ClassGenGeneric(ClassGenBase.ClassGenBase): """ if cd is None or cd.name is None: return - perm: rawptr[memhub.MemBuddy] = CompilerFactory.factory.PermPool - table_pool: rawptr[memhub.MemBuddy] = perm + perm: memhub.MemBuddy* = CompilerFactory.factory.PermPool + table_pool: memhub.MemBuddy* = perm if table_pool is None: table_pool = pool if self.GenericClassNames is None: self.GenericClassNames = list[str](table_pool, 8) - self.GenericClassNodes = list[rawptr[ast.ClassDef]](table_pool, 8) + self.GenericClassNodes = list[ast.ClassDef*](table_pool, 8) self.GenericClassSha1s = list[str](table_pool, 8) self.GenericClassFiles = list[str](table_pool, 8) if self.GenericClassTpParams is None: @@ -111,7 +111,7 @@ class ClassGenGeneric(ClassGenBase.ClassGenBase): return string.memset(self.GenericClassTpParams, 0, GENERIC_TEMPLATE_MAX * 8) # 用局部变量接收 list,触发类型推断(避免字段 __len__ 失败) - names_local: list[str] | t.CPtr = self.GenericClassNames + names_local: list[str]* = self.GenericClassNames cn: sizet = len(names_local) i: sizet for i in range(cn): @@ -128,7 +128,7 @@ class ClassGenGeneric(ClassGenBase.ClassGenBase): self._dup_perm_str(self.Gen.TypeGenResolve.get_current_file())) if tp_names_buf is not None and cn < GENERIC_TEMPLATE_MAX: self.GenericClassTpParams[cn] = sizet(tp_names_buf) - def _copy_type_params_stdlib(self, tp: list[str] | t.CPtr) -> str: + def _copy_type_params_stdlib(self, tp: list[str]*) -> str: """将模板 type_params 深拷贝为空格分隔、NUL 结尾的 stdlib 缓冲区 TPC Python 参考实现:type_params = [tp.name for tp in Node.type_params] @@ -160,8 +160,8 @@ class ClassGenGeneric(ClassGenBase.ClassGenBase): string.strcat(buf, " ") string.strcat(buf, tp_name) return buf - def _find_generic_template_tp_params(self, pool: rawptr[memhub.MemBuddy], - class_name: str) -> list[str] | t.CPtr: + def _find_generic_template_tp_params(self, pool: memhub.MemBuddy*, + class_name: str) -> list[str]*: """查找泛型类模板的类型参数名列表,未找到返回 None 从注册时深拷贝的 stdlib 缓冲区重建当前 pool 的 list[str] @@ -170,7 +170,7 @@ class ClassGenGeneric(ClassGenBase.ClassGenBase): if self.GenericClassNames is None or class_name is None \ or self.GenericClassTpParams is None: return None - names_local: list[str] | t.CPtr = self.GenericClassNames + names_local: list[str]* = self.GenericClassNames cn: sizet = len(names_local) i: sizet for i in range(cn): @@ -187,7 +187,7 @@ class ClassGenGeneric(ClassGenBase.ClassGenBase): # 不是容量!传 4 会导致 get(i) 偏移算错、append 相互覆盖 # (Pair[T1,T2] 的 seg1 写 data+4 覆盖 seg0 高 4 字节 → strcmp # 收到 0x15B78D5015B78CB0 混合垃圾崩溃,GenericTest 回归根因) - tp_list: list[str] | t.CPtr = list[str](pool, 8) + tp_list: list[str]* = list[str](pool, 8) if tp_list is None: return None seg_start: sizet = 0 @@ -206,19 +206,19 @@ class ClassGenGeneric(ClassGenBase.ClassGenBase): pos += 1 return tp_list return None - def _find_generic_template(self, class_name: str) -> rawptr[ast.ClassDef]: + def _find_generic_template(self, class_name: str) -> ast.ClassDef*: """查找泛型类模板,返回 ClassDef 节点或 None""" if self.GenericClassNames is None or class_name is None: return None # 用局部变量接收 list,触发类型推断(避免字段 __len__ 失败) - names_local: list[str] | t.CPtr = self.GenericClassNames - nodes_local: list[rawptr[ast.ClassDef]] | t.CPtr = self.GenericClassNodes + names_local: list[str]* = self.GenericClassNames + nodes_local: list[ast.ClassDef*] | t.CPtr = self.GenericClassNodes cn: sizet = len(names_local) i: sizet for i in range(cn): nm: str = names_local.get(i) if nm is not None and string.strcmp(nm, class_name) == 0: - node: rawptr[ast.ClassDef] = nodes_local.get(i) + node: ast.ClassDef* = nodes_local.get(i) return node return None def _find_generic_template_sha1(self, class_name: str) -> str: @@ -226,8 +226,8 @@ class ClassGenGeneric(ClassGenBase.ClassGenBase): if self.GenericClassNames is None or class_name is None: return None # 用局部变量接收 list,触发类型推断 - names_local: list[str] | t.CPtr = self.GenericClassNames - sha1s_local: list[str] | t.CPtr = self.GenericClassSha1s + names_local: list[str]* = self.GenericClassNames + sha1s_local: list[str]* = self.GenericClassSha1s cn: sizet = len(names_local) i: sizet for i in range(cn): @@ -244,8 +244,8 @@ class ClassGenGeneric(ClassGenBase.ClassGenBase): """ if self.GenericClassNames is None or class_name is None: return None - names_local: list[str] | t.CPtr = self.GenericClassNames - files_local: list[str] | t.CPtr = self.GenericClassFiles + names_local: list[str]* = self.GenericClassNames + files_local: list[str]* = self.GenericClassFiles cn: sizet = len(names_local) i: sizet for i in range(cn): @@ -254,9 +254,9 @@ class ClassGenGeneric(ClassGenBase.ClassGenBase): f_val: str = files_local.get(i) return f_val return None - def _mangle_generic_class_name(self, pool: rawptr[memhub.MemBuddy], + def _mangle_generic_class_name(self, pool: memhub.MemBuddy*, class_name: str, - type_args: list[str] | t.CPtr) -> str: + type_args: list[str]*) -> str: """生成特化类名: list + [int] -> list[int] 分配新缓冲区拼接,避免原地 strcat 导致缓冲区溢出 @@ -291,10 +291,10 @@ class ClassGenGeneric(ClassGenBase.ClassGenBase): string.strcat(mangled, ta) string.strcat(mangled, "]") return mangled - def _clone_annotation(self, pool: rawptr[memhub.MemBuddy], - node: rawptr[ast.AST], - tp_names: list[str] | t.CPtr, - type_args: list[str] | t.CPtr) -> rawptr[ast.AST]: + def _clone_annotation(self, pool: memhub.MemBuddy*, + node: ast.AST*, + tp_names: list[str]*, + type_args: list[str]*) -> ast.AST*: """拷贝类型注解表达式,替换类型参数 T 为具体类型名 tp_names: 类型参数名列表 ['T'] @@ -306,7 +306,7 @@ class ClassGenGeneric(ClassGenBase.ClassGenBase): # Name: 可能是类型参数 T if k == ast.ASTKind.Name: - nm: rawptr[ast.Name] = rawptr[ast.Name](node) + nm: ast.Name* = ast.Name*(node) if nm.id is not None: n: sizet = len(tp_names) if tp_names is not None else 0 i: sizet @@ -315,88 +315,88 @@ class ClassGenGeneric(ClassGenBase.ClassGenBase): if tpn is not None and string.strcmp(nm.id, tpn) == 0: ta: str = type_args.get(i) # 类型实参可能是复合类型(如 "AST|t.CPtr"),用 _parse_type_string 解析 - parsed_node: rawptr[ast.AST] = self.Gen.TypeGenResolve._parse_type_string(pool, ta, nm.ctx) + parsed_node: ast.AST* = self.Gen.TypeGenResolve._parse_type_string(pool, ta, nm.ctx) return parsed_node return ast.Name(pool, nm.id, nm.ctx) return None # Attribute: t.CPtr 等 if k == ast.ASTKind.Attribute: - at: rawptr[ast.Attribute] = rawptr[ast.Attribute](node) - new_value: rawptr[ast.AST] = self._clone_annotation(pool, at.value, tp_names, type_args) + at: ast.Attribute* = ast.Attribute*(node) + new_value: ast.AST* = self._clone_annotation(pool, at.value, tp_names, type_args) return ast.Attribute(pool, new_value, at.attr, at.ctx) # BinOp: T | t.CPtr 等 if k == ast.ASTKind.BinOp: - bop: rawptr[ast.BinOp] = rawptr[ast.BinOp](node) - new_left: rawptr[ast.AST] = self._clone_annotation(pool, bop.left, tp_names, type_args) - new_right: rawptr[ast.AST] = self._clone_annotation(pool, bop.right, tp_names, type_args) + bop: ast.BinOp* = ast.BinOp*(node) + new_left: ast.AST* = self._clone_annotation(pool, bop.left, tp_names, type_args) + new_right: ast.AST* = self._clone_annotation(pool, bop.right, tp_names, type_args) return ast.BinOp(pool, new_left, bop.op, new_right) # Subscript: list[int] 等 if k == ast.ASTKind.Subscript: - sub: rawptr[ast.Subscript] = rawptr[ast.Subscript](node) - new_value2: rawptr[ast.AST] = self._clone_annotation(pool, sub.value, tp_names, type_args) - new_slice: rawptr[ast.AST] = self._clone_annotation(pool, sub.slice, tp_names, type_args) + sub: ast.Subscript* = ast.Subscript*(node) + new_value2: ast.AST* = self._clone_annotation(pool, sub.value, tp_names, type_args) + new_slice: ast.AST* = self._clone_annotation(pool, sub.slice, tp_names, type_args) return ast.Subscript(pool, new_value2, new_slice, sub.ctx) # Tuple: (T, int) 等 if k == ast.ASTKind.Tuple: - tup: rawptr[ast.Tuple] = rawptr[ast.Tuple](node) - new_elts: list[ast.AST*]* = list[rawptr[ast.AST]](pool, 8) + tup: ast.Tuple* = ast.Tuple*(node) + new_elts: list[ast.AST*]* = list[ast.AST*](pool, 8) if tup.elts is not None: tup_elts: list[ast.AST*]* = tup.elts en: sizet = len(tup_elts) ei: sizet for ei in range(en): - el: rawptr[ast.AST] = tup_elts.get(ei) - new_el: rawptr[ast.AST] = self._clone_annotation(pool, el, tp_names, type_args) + el: ast.AST* = tup_elts.get(ei) + new_el: ast.AST* = self._clone_annotation(pool, el, tp_names, type_args) if new_el is not None: new_elts.append(new_el) return ast.Tuple(pool, new_elts, tup.ctx) # Constant: 默认值等 if k == ast.ASTKind.Constant: - cnst: rawptr[ast.Constant] = rawptr[ast.Constant](node) + cnst: ast.Constant* = ast.Constant*(node) return ast.Constant(pool, cnst.const_kind, cnst.int_val, cnst.float_val, cnst.str_val, cnst.lineno, cnst.col_offset) # 其他: 直接引用(不拷贝) return node - def _clone_arguments(self, pool: rawptr[memhub.MemBuddy], - args: rawptr[ast.AST], - tp_names: list[str] | t.CPtr, - type_args: list[str] | t.CPtr) -> rawptr[ast.AST]: + def _clone_arguments(self, pool: memhub.MemBuddy*, + args: ast.AST*, + tp_names: list[str]*, + type_args: list[str]*) -> ast.AST*: """拷贝 Arguments 节点,替换 arg annotation 中的 T""" if args is None: return None if args.kind() != ast.ASTKind.Arguments: return args - old_args: rawptr[ast.Arguments] = rawptr[ast.Arguments](args) + old_args: ast.Arguments* = ast.Arguments*(args) # 拷贝 args 列表,替换每个 Arg 的 annotation - new_arg_list: list[ast.AST*]* = list[rawptr[ast.AST]](pool, 8) + new_arg_list: list[ast.AST*]* = list[ast.AST*](pool, 8) if old_args.args is not None: old_arg_list: list[ast.AST*]* = old_args.args an: sizet = len(old_arg_list) ai: sizet for ai in range(an): - arg_node: rawptr[ast.AST] = old_arg_list.get(ai) + arg_node: ast.AST* = old_arg_list.get(ai) if arg_node is None: continue if arg_node.kind() == ast.ASTKind.Arg: - ag: rawptr[ast.Arg] = rawptr[ast.Arg](arg_node) - new_anno: rawptr[ast.AST] = self._clone_annotation(pool, ag.annotation, tp_names, type_args) - new_arg: rawptr[ast.Arg] = ast.Arg(pool, ag.arg, new_anno) + ag: ast.Arg* = ast.Arg*(arg_node) + new_anno: ast.AST* = self._clone_annotation(pool, ag.annotation, tp_names, type_args) + new_arg: ast.Arg* = ast.Arg(pool, ag.arg, new_anno) new_arg_list.append(new_arg) else: new_arg_list.append(arg_node) return ast.Arguments(pool, new_arg_list, old_args.vararg, old_args.kwarg, old_args.defaults, old_args.kw_defaults) - def _clone_classdef_for_spec(self, pool: rawptr[memhub.MemBuddy], - cd: rawptr[ast.ClassDef], + def _clone_classdef_for_spec(self, pool: memhub.MemBuddy*, + cd: ast.ClassDef*, spec_name: str, - tp_names: list[str] | t.CPtr, - type_args: list[str] | t.CPtr) -> rawptr[ast.ClassDef]: + tp_names: list[str]*, + type_args: list[str]*) -> ast.ClassDef*: """拷贝 ClassDef 节点用于泛型特化 - 替换类名为 spec_name @@ -405,7 +405,7 @@ class ClassGenGeneric(ClassGenBase.ClassGenBase): - 方法体直接引用原始节点(通过 type_map 上下文处理 T) """ # 创建新 ClassDef(type_params=None 表示非泛型) - new_cd: rawptr[ast.ClassDef] = ast.ClassDef(pool, spec_name, cd.bases, cd.keywords, + new_cd: ast.ClassDef* = ast.ClassDef(pool, spec_name, cd.bases, cd.keywords, cd.decorator_list, None) # 拷贝 children if cd.children is not None: @@ -413,24 +413,24 @@ class ClassGenGeneric(ClassGenBase.ClassGenBase): cn: sizet = len(cd_children) ci: sizet for ci in range(cn): - child: rawptr[ast.AST] = cd_children.get(ci) + child: ast.AST* = cd_children.get(ci) if child is None: continue ck: int = child.kind() if ck == ast.ASTKind.AnnAssign: - aa: rawptr[ast.AnnAssign] = rawptr[ast.AnnAssign](child) - new_target: rawptr[ast.AST] = aa.target - new_anno2: rawptr[ast.AST] = self._clone_annotation(pool, aa.annotation, tp_names, type_args) - new_value3: rawptr[ast.AST] = aa.value - new_aa: rawptr[ast.AnnAssign] = ast.AnnAssign(pool, new_target, new_anno2, new_value3, aa.simple) + aa: ast.AnnAssign* = ast.AnnAssign*(child) + new_target: ast.AST* = aa.target + new_anno2: ast.AST* = self._clone_annotation(pool, aa.annotation, tp_names, type_args) + new_value3: ast.AST* = aa.value + new_aa: ast.AnnAssign* = ast.AnnAssign(pool, new_target, new_anno2, new_value3, aa.simple) new_cd.append(new_aa) elif ck == ast.ASTKind.FunctionDef: - fd: rawptr[ast.FunctionDef] = rawptr[ast.FunctionDef](child) - new_args2: rawptr[ast.AST] = self._clone_arguments(pool, fd.args, tp_names, type_args) - new_returns2: rawptr[ast.AST] = self._clone_annotation(pool, fd.returns, tp_names, type_args) - new_fd: rawptr[ast.FunctionDef] = ast.FunctionDef(pool, fd.name, new_args2, + fd: ast.FunctionDef* = ast.FunctionDef*(child) + new_args2: ast.AST* = self._clone_arguments(pool, fd.args, tp_names, type_args) + new_returns2: ast.AST* = self._clone_annotation(pool, fd.returns, tp_names, type_args) + new_fd: ast.FunctionDef* = ast.FunctionDef(pool, fd.name, new_args2, fd.decorator_list, new_returns2, 0) # 方法体直接引用原始节点 if fd.children is not None: @@ -438,7 +438,7 @@ class ClassGenGeneric(ClassGenBase.ClassGenBase): bcn: sizet = len(fd_children) bci: sizet for bci in range(bcn): - body_stmt: rawptr[ast.AST] = fd_children.get(bci) + body_stmt: ast.AST* = fd_children.get(bci) if body_stmt is not None: new_fd.append(body_stmt) new_cd.append(new_fd) @@ -461,7 +461,7 @@ class ClassGenGeneric(ClassGenBase.ClassGenBase): if name_addr != 0: return (str | t.CPtr)(name_addr) return None - def _cache_spec(self, pool: rawptr[memhub.MemBuddy], spec_key: str, spec_name: str): + def _cache_spec(self, pool: memhub.MemBuddy*, spec_key: str, spec_name: str): """缓存特化结果(stdlib 深拷贝存储,跨文件安全)""" if spec_key is None or spec_name is None: return @@ -487,7 +487,7 @@ class ClassGenGeneric(ClassGenBase.ClassGenBase): self.SpecKeys[self.SpecCount] = sizet(key_copy) self.SpecNames[self.SpecCount] = sizet(name_copy) self.SpecCount += 1 - def _merge_template_imports(self, trans: rawptr[HT.Translator], + def _merge_template_imports(self, trans: HT.Translator*, template_sha1: str) -> None: """将模板模块的 imports 并入 trans._imported_modules(空格分隔)""" if trans is None or template_sha1 is None: @@ -508,7 +508,7 @@ class ClassGenGeneric(ClassGenBase.ClassGenBase): merged[cur_len] = ' ' string.strcpy(merged + cur_len + 1, tdeps) trans._imported_modules = merged - def _record_spec_trigger(self, pool: rawptr[memhub.MemBuddy], + def _record_spec_trigger(self, pool: memhub.MemBuddy*, spec_name: str, trigger_sha1: str) -> int: """记录泛型特化类的触发文件 sha1(StructEntry.SpecTriggerSha1) @@ -519,7 +519,7 @@ class ClassGenGeneric(ClassGenBase.ClassGenBase): """ if spec_name is None or trigger_sha1 is None: return 0 - entry_rt: rawptr[GenTypes.StructEntry] = self.Gen.StructGen.find_struct(spec_name) + entry_rt: 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: @@ -531,9 +531,9 @@ class ClassGenGeneric(ClassGenBase.ClassGenBase): string.strcpy(ts_buf_r, trigger_sha1) entry_rt.SpecTriggerSha1 = ts_buf_r return 1 - def _specialize_generic_class(self, trans: rawptr[HT.Translator], + def _specialize_generic_class(self, trans: HT.Translator*, class_name: str, - type_args: list[str] | t.CPtr) -> str: + type_args: list[str]*) -> str: """特化泛型类,返回特化类名 1. 查找泛型模板 @@ -573,10 +573,10 @@ class ClassGenGeneric(ClassGenBase.ClassGenBase): if ta_rsv_g is not None and string.strcmp(ta_raw_g, ta_rsv_g) != 0: type_args.set(ta_i_g, ta_rsv_g) - pool: rawptr[memhub.MemBuddy] = trans.Pool + pool: memhub.MemBuddy* = trans.Pool # 1. 查找泛型模板 - template_cd: rawptr[ast.ClassDef] = self._find_generic_template(class_name) + template_cd: ast.ClassDef* = self._find_generic_template(class_name) if template_cd is None: self.GenericSpecDepth -= 1 return None @@ -592,7 +592,7 @@ class ClassGenGeneric(ClassGenBase.ClassGenBase): # define,避免符号只有 declare 无 define → 链接失败。 # 首次 Phase B 特化(Phase 1a 未特化)find_struct 返回 None,不补译,走下方正常全量翻译。 if trans._declare_only == 0: - pre_existing: rawptr[GenTypes.StructEntry] = self.Gen.StructGen.find_struct(spec_name) + pre_existing: 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) @@ -602,11 +602,11 @@ class ClassGenGeneric(ClassGenBase.ClassGenBase): # 方法体永不发射 → 特化方法只有 call 无 define → 链接 undefined symbol。 pre_existing.MethodsEmitted = 1 # 从 stdlib 深拷贝表取 type_params(模板节点 pool list 跨 Phase 可能失效) - tp_names_pre: list[str] | t.CPtr = self._find_generic_template_tp_params( + tp_names_pre: list[str]* = self._find_generic_template_tp_params( pool, class_name) if tp_names_pre is None: tp_names_pre = template_cd.type_params - spec_cd_pre: rawptr[ast.ClassDef] = self._clone_classdef_for_spec( + spec_cd_pre: ast.ClassDef* = self._clone_classdef_for_spec( pool, template_cd, spec_name, tp_names_pre, type_args) if spec_cd_pre is not None: trans.GenericTypeParamNames = tp_names_pre @@ -669,7 +669,7 @@ class ClassGenGeneric(ClassGenBase.ClassGenBase): return cached # 4. 检查是否已注册(Phase B 重复特化) - existing: rawptr[GenTypes.StructEntry] = self.Gen.StructGen.find_struct(spec_name) + existing: 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) @@ -681,11 +681,11 @@ class ClassGenGeneric(ClassGenBase.ClassGenBase): # 5. 拷贝 ClassDef 节点 # 从 stdlib 深拷贝表取 type_params(模板节点 pool list 跨 Phase 可能失效) - tp_names: list[str] | t.CPtr = self._find_generic_template_tp_params( + tp_names: list[str]* = self._find_generic_template_tp_params( pool, class_name) if tp_names is None: tp_names = template_cd.type_params - spec_cd: rawptr[ast.ClassDef] = self._clone_classdef_for_spec( + spec_cd: ast.ClassDef* = self._clone_classdef_for_spec( pool, template_cd, spec_name, tp_names, type_args) if spec_cd is None: self.GenericSpecDepth -= 1 @@ -732,11 +732,11 @@ class ClassGenGeneric(ClassGenBase.ClassGenBase): # 特化结果字段名完整性检查(fail-fast:字段名缺失 = 字段表损坏, # 静默继续会让后续 GEP 按错索引访问) if string.strcmp(class_name, "GSListNode") == 0: - result_entry: rawptr[GenTypes.StructEntry] = self.Gen.StructGen.find_struct(spec_name) + result_entry: 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: rawptr[GenTypes.FieldEntry] = self.Gen.StructGen._get_field_entry( + rfe: 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) diff --git a/App/lib/core/Gen/Class/ClassGenVTable.vp b/App/lib/core/Gen/Class/ClassGenVTable.vp index ae9a602..3c7a1b6 100644 --- a/App/lib/core/Gen/Class/ClassGenVTable.vp +++ b/App/lib/core/Gen/Class/ClassGenVTable.vp @@ -77,15 +77,15 @@ class ClassGenVTable(ClassGenBase.ClassGenBase): # # 返回 1=有虚方法 / 0=无方法或失败 # ============================================================ - def _collect_vtable_methods(self, trans: rawptr[HT.Translator], - cd: rawptr[ast.ClassDef], + def _collect_vtable_methods(self, trans: HT.Translator*, + cd: ast.ClassDef*, class_name: str) -> int: """收集虚方法信息,设置 entry.VTableMethods/VTableMethodCount""" if trans is None or cd is None or class_name is None: return 0 - pool: rawptr[memhub.MemBuddy] = trans.Pool - mod: rawptr[llvmlite.LLVMModule] = trans.Module + pool: memhub.MemBuddy* = trans.Pool + mod: llvmlite.LLVMModule* = trans.Module children: list[ast.AST*]* = cd.children if children is None: @@ -95,10 +95,10 @@ class ClassGenVTable(ClassGenBase.ClassGenBase): # 1. 收集虚方法信息 # stdlib 分配:method_names_buf 存到 StructEntry.VTableMethods(跨文件永久存活), # 必须迁出 mb 池 reset 区间,否则 1b 每文件 reset_to(mark1) 会回收导致悬空。 - full_names_buf: sizet | t.CPtr = CompilerFactory.factory.PermPool.alloc(8 * VTBL_METHOD_MAX) - method_names_buf: sizet | t.CPtr = CompilerFactory.factory.PermPool.alloc(8 * VTBL_METHOD_MAX) + full_names_buf: sizet* = CompilerFactory.factory.PermPool.alloc(8 * VTBL_METHOD_MAX) + method_names_buf: sizet* = CompilerFactory.factory.PermPool.alloc(8 * VTBL_METHOD_MAX) # 记录每个方法的父类 SHA1(非 0=继承方法用父模块 SHA1 mangling,0=当前类方法) - method_parent_sha1s: sizet | t.CPtr = CompilerFactory.factory.PermPool.alloc(8 * VTBL_METHOD_MAX) + method_parent_sha1s: sizet* = CompilerFactory.factory.PermPool.alloc(8 * VTBL_METHOD_MAX) if full_names_buf is None or method_names_buf is None or method_parent_sha1s is None: return 0 string.memset(full_names_buf, 0, 8 * VTBL_METHOD_MAX) @@ -114,7 +114,7 @@ class ClassGenVTable(ClassGenBase.ClassGenBase): # 如果子类覆盖了方法,full_name 用子类的;否则用父类的。 # 用 SHA1 感知查找,规避跨模块同名 find_struct 找错 # ============================================================ - vt_self_entry: rawptr[GenTypes.StructEntry] = self.Gen.StructGen.find_struct_by_module( + vt_self_entry: 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: rawptr[GenTypes.StructEntry] = self.Gen.StructGen.find_struct_by_module( + vt_parent_entry: GenTypes.StructEntry* = self.Gen.StructGen.find_struct_by_module( pname, trans.ModuleSha1) if vt_parent_entry is None: # 跨模块继承: 父类在不同模块定义(SHA1 不同),回退到按类名查找 @@ -148,12 +148,12 @@ class ClassGenVTable(ClassGenBase.ClassGenBase): child_overrides: int = 0 child_nvt: int = 0 for ci2 in range(cn): - stmt2: rawptr[ast.AST] = children.get(ci2) + stmt2: ast.AST* = children.get(ci2) if stmt2 is None: continue if stmt2.kind() != ast.ASTKind.FunctionDef: continue - fd2: rawptr[ast.FunctionDef] = rawptr[ast.FunctionDef](stmt2) + fd2: ast.FunctionDef* = ast.FunctionDef*(stmt2) if fd2 is not None and fd2.name is not None: if string.strcmp(fd2.name, pmethod_name) == 0: child_overrides = 1 @@ -176,7 +176,7 @@ class ClassGenVTable(ClassGenBase.ClassGenBase): else: def_class = pname # 多继承:沿 pname 的 MRO 祖先链探测实际定义类(跳过自身,先声明父类优先) - mro_ptr: sizet | t.CPtr = self.Gen.StructGen.get_mro_chain(pool, pname) + mro_ptr: sizet* = self.Gen.StructGen.get_mro_chain(pool, pname) mro_i: int = 1 while mro_ptr is not None and mro_ptr[mro_i] != 0: anc: str = (str | t.CPtr)(mro_ptr[mro_i]) @@ -204,7 +204,7 @@ class ClassGenVTable(ClassGenBase.ClassGenBase): method_parent_sha1s[method_count] = 0 else: # 继承未覆盖: 用实际定义类的模块 SHA1(跨模块继承时 mangling 正确) - def_entry2: rawptr[GenTypes.StructEntry] = self.Gen.StructGen.find_struct( + def_entry2: 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) @@ -214,12 +214,12 @@ class ClassGenVTable(ClassGenBase.ClassGenBase): # 2. 收集当前类的虚方法(跳过已从父类继承的) for ci in range(cn): - stmt: rawptr[ast.AST] = children.get(ci) + stmt: ast.AST* = children.get(ci) if stmt is None: continue if stmt.kind() != ast.ASTKind.FunctionDef: continue - fd: rawptr[ast.FunctionDef] = rawptr[ast.FunctionDef](stmt) + fd: ast.FunctionDef* = ast.FunctionDef*(stmt) if fd is None or fd.name is None: continue if method_count >= VTBL_METHOD_MAX: @@ -288,44 +288,44 @@ class ClassGenVTable(ClassGenBase.ClassGenBase): # 4. 创建全局变量 @"SHA1.ClassName.vtable" # 5. 存储虚方法名列表到 StructEntry # ============================================================ - def _generate_vtable(self, trans: rawptr[HT.Translator], - cd: rawptr[ast.ClassDef], + def _generate_vtable(self, trans: HT.Translator*, + cd: ast.ClassDef*, class_name: str) -> int: """生成 VTable 全局变量""" if trans is None or cd is None or class_name is None: return 0 - pool: rawptr[memhub.MemBuddy] = trans.Pool - mod: rawptr[llvmlite.LLVMModule] = trans.Module + pool: memhub.MemBuddy* = trans.Pool + mod: llvmlite.LLVMModule* = trans.Module # 收集虚方法信息(继承父类 + 自身,结果存 self.VtFullNames 等暂存区) # 同时设置 entry.VTableMethodCount/VTableMethods(虚分派查询用) if self._collect_vtable_methods(trans, cd, class_name) == 0: return 0 - full_names_buf: sizet | t.CPtr = self.VtFullNames - method_names_buf: sizet | t.CPtr = self.VtMethodNames - method_parent_sha1s: sizet | t.CPtr = self.VtParentSha1s + full_names_buf: sizet* = self.VtFullNames + method_names_buf: sizet* = self.VtMethodNames + method_parent_sha1s: sizet* = self.VtParentSha1s method_count: int = self.VtMethodCount # 重新获取 entry(后续存储 VTableMethods 用) - vt_self_entry: rawptr[GenTypes.StructEntry] = self.Gen.StructGen.find_struct_by_module( + vt_self_entry: GenTypes.StructEntry* = self.Gen.StructGen.find_struct_by_module( class_name, trans.ModuleSha1) # 2. 构造 VTable 类型: { i8*, i8*, ..., i8* } - i8_ty: rawptr[llvmlite.LLVMType] = llvmlite.Int8(pool) - i8_ptr_ty: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, i8_ty) + i8_ty: llvmlite.LLVMType* = llvmlite.Int8(pool) + i8_ptr_ty: llvmlite.LLVMType* = llvmlite.Ptr(pool, i8_ty) - first_node: rawptr[llvmlite.Function] = None - tail_node: rawptr[llvmlite.Function] = None + first_node: llvmlite.Function* = None + tail_node: llvmlite.Function* = None for i in range(method_count): - pnode: rawptr[llvmlite.Function] = llvmlite.new_param_node(pool, i8_ptr_ty) + pnode: llvmlite.Function* = llvmlite.new_param_node(pool, i8_ptr_ty) if pnode is None: continue tail_node = llvmlite.param_list_append(first_node, tail_node, pnode) if first_node is None: first_node = tail_node - vtable_ty: rawptr[llvmlite.LLVMType] = llvmlite.Struct(pool, first_node, method_count, None) + vtable_ty: llvmlite.LLVMType* = llvmlite.Struct(pool, first_node, method_count, None) if vtable_ty is None: return 0 @@ -363,7 +363,7 @@ class ClassGenVTable(ClassGenBase.ClassGenBase): # 全局表 entry.Spec 在方法 add_param 完成后由 update_global_func_spec 填 # (PermPool 驻留,跨 1b reset 安全),故不再解引用 func(func 可能已被 # reset_to(mark1) 回收悬空)。 - ge: rawptr[GenTypes.FuncEntry] = self.Gen.CallGenLeafKit.find_func_entry_global(full_name) + ge: GenTypes.FuncEntry* = self.Gen.CallGenLeafKit.find_func_entry_global(full_name) func_ty_buf: str = pool.alloc(1024) if func_ty_buf is None: self._vtable_strcat(init_buf, 16384, "i8* null") @@ -397,7 +397,7 @@ class ClassGenVTable(ClassGenBase.ClassGenBase): vtable_mangled: str = self.Gen.FuncGenBase._mangle_name(trans, vtable_name_buf) # 5. 创建全局变量 - gv: rawptr[llvmlite.GlobalVariable] = llvmlite.new_global_variable( + gv: llvmlite.GlobalVariable* = llvmlite.new_global_variable( pool, vtable_mangled, vtable_ty) if gv is None: return 0 @@ -427,9 +427,9 @@ class ClassGenVTable(ClassGenBase.ClassGenBase): # - 翻译方法(生成 SHA1.ClassName.method_name 函数) # 翻译完所有方法后,生成 __before_init__ 函数 # ============================================================ - def _translate_oop_methods(self, trans: rawptr[HT.Translator], - cd: rawptr[ast.ClassDef], - struct_ty: rawptr[llvmlite.LLVMType], + def _translate_oop_methods(self, trans: HT.Translator*, + cd: ast.ClassDef*, + struct_ty: llvmlite.LLVMType*, class_name: str, mark_only: int = 0, reemit: int = 0) -> int: @@ -454,16 +454,16 @@ class ClassGenVTable(ClassGenBase.ClassGenBase): has_new: int = 0 # 提前用类型指针定位 entry(规避跨模块同名类 find_struct 找错) - oop_entry: rawptr[GenTypes.StructEntry] = self.Gen.StructGen.find_struct_by_type(struct_ty) + oop_entry: GenTypes.StructEntry* = self.Gen.StructGen.find_struct_by_type(struct_ty) # 第一遍:检测是否有方法,标记 OOP,并注册装饰器元数据 for ci in range(cn): - stmt: rawptr[ast.AST] = children.get(ci) + stmt: ast.AST* = children.get(ci) if stmt is None: continue if stmt.kind() == ast.ASTKind.FunctionDef: has_method = 1 - fd_check: rawptr[ast.FunctionDef] = rawptr[ast.FunctionDef](stmt) + fd_check: ast.FunctionDef* = ast.FunctionDef*(stmt) if fd_check is not None and fd_check.name is not None: if string.strcmp(fd_check.name, "__init__") == 0: has_init = 1 @@ -540,11 +540,11 @@ class ClassGenVTable(ClassGenBase.ClassGenBase): if oop_has_vt_pre == 1: self._collect_vtable_methods(trans, cd, class_name) for ci in range(cn): - stmt: rawptr[ast.AST] = children.get(ci) + stmt: ast.AST* = children.get(ci) if stmt is None: continue if stmt.kind() == ast.ASTKind.FunctionDef: - fd: rawptr[ast.FunctionDef] = rawptr[ast.FunctionDef](stmt) + fd: ast.FunctionDef* = ast.FunctionDef*(stmt) if fd is not None and fd.name is not None: self._translate_method(trans, fd, struct_ty, class_name) @@ -570,24 +570,24 @@ class ClassGenVTable(ClassGenBase.ClassGenBase): # - 类型 Ptr(struct_ty),直接注册为 SSA 值(不创建 alloca) # - 使 self.field 能通过 GEP 直接访问原始结构体 # ============================================================ - def _translate_method(self, trans: rawptr[HT.Translator], - fd: rawptr[ast.FunctionDef], - struct_ty: rawptr[llvmlite.LLVMType], + def _translate_method(self, trans: HT.Translator*, + fd: ast.FunctionDef*, + struct_ty: llvmlite.LLVMType*, class_name: str) -> int: """翻译单个方法,返回 0""" if trans is None or fd is None or struct_ty is None or class_name is None: return 0 - pool: rawptr[memhub.MemBuddy] = trans.Pool - mod: rawptr[llvmlite.LLVMModule] = trans.Module + pool: memhub.MemBuddy* = trans.Pool + mod: llvmlite.LLVMModule* = trans.Module imported_modules: str = trans._imported_modules from_imports: str = trans._from_imports - funcs_ptr: rawptr[GenTypes.FuncEntry] = trans._funcs + funcs_ptr: GenTypes.FuncEntry* = trans._funcs func_count: int = trans._func_count - i32_ty: rawptr[llvmlite.LLVMType] = llvmlite.Int32(pool) - self_ptr_ty: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, struct_ty) + i32_ty: llvmlite.LLVMType* = llvmlite.Int32(pool) + self_ptr_ty: llvmlite.LLVMType* = llvmlite.Ptr(pool, struct_ty) method_name: str = fd.name if method_name is None: @@ -634,7 +634,7 @@ class ClassGenVTable(ClassGenBase.ClassGenBase): mangled_name: str = self.Gen.FuncGenBase._mangle_name(trans, full_name) # 推断返回类型 - ret_ty: rawptr[llvmlite.LLVMType] = None + ret_ty: llvmlite.LLVMType* = None if fd.returns is not None: ret_ty = self.Gen.TypeGenResolve.resolve_annotation_type( pool, fd.returns, imported_modules, from_imports, trans, 0) @@ -665,7 +665,7 @@ class ClassGenVTable(ClassGenBase.ClassGenBase): pool, fd.children, param_types_str) # 创建 LLVM 函数 - func: rawptr[llvmlite.Function] = llvmlite.create_function( + func: llvmlite.Function* = llvmlite.create_function( pool, mod, mangled_name, ret_ty) if func is None: return 0 @@ -677,9 +677,9 @@ class ClassGenVTable(ClassGenBase.ClassGenBase): md_defaults: t.CPtr = None md_default_count: int = 0 md_param_count: int = 0 - md_args_node: rawptr[ast.Arguments] = fd.args + md_args_node: ast.Arguments* = fd.args if md_args_node is not None: - md_ags: rawptr[ast.Arguments] = rawptr[ast.Arguments](md_args_node) + md_ags: ast.Arguments* = ast.Arguments*(md_args_node) if md_ags.args is not None: md_alist: list[ast.AST*]* = md_ags.args if is_static_m != 0: @@ -703,9 +703,9 @@ class ClassGenVTable(ClassGenBase.ClassGenBase): if is_static_m == 0: first_pname: str = "self" if is_class_m != 0 and fd.args is not None: - fd_ags: rawptr[ast.Arguments] = rawptr[ast.Arguments](fd.args) + fd_ags: ast.Arguments* = ast.Arguments*(fd.args) if fd_ags.args is not None and len(fd_ags.args) > 0: - fd_first_arg: rawptr[ast.Arg] = rawptr[ast.Arg](fd_ags.args.get(0)) + fd_first_arg: ast.Arg* = ast.Arg*(fd_ags.args.get(0)) if fd_first_arg is not None and fd_first_arg.arg is not None: first_pname = fd_first_arg.arg first_pname_buf: str = pool.alloc(32) @@ -714,9 +714,9 @@ class ClassGenVTable(ClassGenBase.ClassGenBase): llvmlite.add_param(pool, func, self_ptr_ty, first_pname_buf) # 添加其他参数(支持类型注解;@staticmethod 从索引 0 开始,其余跳过索引 0 的 self/cls) - args_node: rawptr[ast.Arguments] = fd.args + args_node: ast.Arguments* = fd.args if args_node is not None: - ags: rawptr[ast.Arguments] = rawptr[ast.Arguments](args_node) + ags: ast.Arguments* = ast.Arguments*(args_node) if ags.args is not None: alist: list[ast.AST*]* = ags.args an: sizet = len(alist) @@ -724,11 +724,11 @@ class ClassGenVTable(ClassGenBase.ClassGenBase): if is_static_m == 0: start_idx = 1 for ai in range(start_idx, an): - arg: rawptr[ast.Arg] = rawptr[ast.Arg](alist.get(ai)) + arg: ast.Arg* = ast.Arg*(alist.get(ai)) if arg is not None and arg.arg is not None: - param_ty: rawptr[llvmlite.LLVMType] = i32_ty + param_ty: llvmlite.LLVMType* = i32_ty if arg.annotation is not None: - resolved: rawptr[llvmlite.LLVMType] = self.Gen.TypeGenResolve.resolve_annotation_type( + resolved: llvmlite.LLVMType* = self.Gen.TypeGenResolve.resolve_annotation_type( pool, arg.annotation, imported_modules, from_imports, trans, 0) if resolved is None: # [S4 fail-fast] 有注解但解析失败:不再静默用 i32 @@ -757,9 +757,9 @@ class ClassGenVTable(ClassGenBase.ClassGenBase): # raise StopIteration 时置 1(对齐 TPC HandlesFunctions.py L703-705)。 # 该参数不计入 md_param_count(逻辑参数),调用侧(for 循环)显式传。 if string.strcmp(method_name, "__next__") == 0: - i1_ty_si: rawptr[llvmlite.LLVMType] = llvmlite.Int1(pool) + i1_ty_si: llvmlite.LLVMType* = llvmlite.Int1(pool) if i1_ty_si is not None: - i1_ptr_ty_si: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, i1_ty_si) + i1_ptr_ty_si: llvmlite.LLVMType* = llvmlite.Ptr(pool, i1_ty_si) if i1_ptr_ty_si is not None: llvmlite.add_param(pool, func, i1_ptr_ty_si, "%__stop_iter_flag__") @@ -772,7 +772,7 @@ class ClassGenVTable(ClassGenBase.ClassGenBase): return 0 # 创建方法专属 builder - func_builder: rawptr[llvmlite.IRBuilder] = llvmlite.new_builder(pool, func) + func_builder: llvmlite.IRBuilder* = llvmlite.new_builder(pool, func) if func_builder is None: return 0 llvmlite.position_at_end(func_builder, entry_blk) @@ -783,20 +783,20 @@ 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: rawptr[llvmlite.GlobalVariable] = llvmlite.create_global_int( + tls_m_gv: 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) + i1_ty_m: llvmlite.LLVMType* = llvmlite.Int1(pool) if i1_ty_m is not None: # GlobalVariable 非 Value 子类:构造 Value 视图后再 load/store - tls_m_ptr_ty: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, i1_ty_m) + tls_m_ptr_ty: llvmlite.LLVMType* = llvmlite.Ptr(pool, i1_ty_m) 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: rawptr[llvmlite.Value] = llvmlite.SSAValue( + tls_m_ref: llvmlite.Value* = llvmlite.SSAValue( pool, tls_m_ptr_ty, tls_m_rn) if tls_m_ref is not None: - tls_m_ld: rawptr[llvmlite.Value] = llvmlite.build_load( + tls_m_ld: 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 @@ -816,22 +816,22 @@ class ClassGenVTable(ClassGenBase.ClassGenBase): case llvmlite.LLVMType.Void(): llvmlite.build_ret_void(func_builder) case llvmlite.LLVMType.Int(_): - tlm0: rawptr[llvmlite.Value] = llvmlite.ConstInt( + tlm0: 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: rawptr[llvmlite.Value] = llvmlite.ConstFloat( + tlmf: llvmlite.Value* = llvmlite.ConstFloat( pool, ret_ty, 0.0) if tlmf is not None: llvmlite.build_ret(func_builder, tlmf) case _: - tlmn: rawptr[llvmlite.Value] = llvmlite.ConstNull( + tlmn: 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: rawptr[llvmlite.Value] = llvmlite.ConstInt( + tlmo: 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,14 +843,14 @@ class ClassGenVTable(ClassGenBase.ClassGenBase): # self 必须走 alloca:注册为 SSA 值会让 translate_name_value 多 load 一次, # 把 Ptr(struct_ty) 变成 struct 值 → 变参函数 ABI 不匹配崩溃。 if is_static_m == 0: - self_alloca: rawptr[llvmlite.Value] = llvmlite.build_alloca(func_builder, self_ptr_ty) + self_alloca: 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" if is_class_m != 0 and args_node is not None: - cags: rawptr[ast.Arguments] = rawptr[ast.Arguments](args_node) + cags: ast.Arguments* = ast.Arguments*(args_node) if cags.args is not None and len(cags.args) > 0: - cfirst: rawptr[ast.Arg] = rawptr[ast.Arg](cags.args.get(0)) + cfirst: ast.Arg* = ast.Arg*(cags.args.get(0)) if cfirst is not None and cfirst.arg is not None: self_var_name = cfirst.arg self_ssa_name_buf: str = pool.alloc(32) @@ -860,13 +860,13 @@ 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: rawptr[llvmlite.Value] = llvmlite.SSAValue(pool, self_ptr_ty, self_ssa_name) + self_val: llvmlite.Value* = llvmlite.SSAValue(pool, self_ptr_ty, self_ssa_name) llvmlite.build_store(func_builder, self_val, self_alloca) # 为其他参数创建 alloca 并 store(与普通函数一致; # @staticmethod 从索引 0 开始,其余跳过索引 0 的 self/cls 参数) if args_node is not None: - ags2: rawptr[ast.Arguments] = rawptr[ast.Arguments](args_node) + ags2: ast.Arguments* = ast.Arguments*(args_node) if ags2.args is not None: alist2: list[ast.AST*]* = ags2.args an2: sizet = len(alist2) @@ -874,11 +874,11 @@ class ClassGenVTable(ClassGenBase.ClassGenBase): if is_static_m == 0: start_idx2 = 1 for ai2 in range(start_idx2, an2): - arg2: rawptr[ast.Arg] = rawptr[ast.Arg](alist2.get(ai2)) + arg2: ast.Arg* = ast.Arg*(alist2.get(ai2)) if arg2 is not None and arg2.arg is not None: - param_ty2: rawptr[llvmlite.LLVMType] = i32_ty + param_ty2: llvmlite.LLVMType* = i32_ty if arg2.annotation is not None: - resolved2: rawptr[llvmlite.LLVMType] = self.Gen.TypeGenResolve.resolve_annotation_type( + resolved2: llvmlite.LLVMType* = self.Gen.TypeGenResolve.resolve_annotation_type( pool, arg2.annotation, imported_modules, from_imports, trans, 0) if resolved2 is None: # fail-fast:参数有注解但类型解析失败,不再静默保持 i32 @@ -896,7 +896,7 @@ class ClassGenVTable(ClassGenBase.ClassGenBase): param_ty2 = llvmlite.Ptr(pool, aelem_ty2) case _: param_ty2 = resolved2 - alloca: rawptr[llvmlite.Value] = llvmlite.build_alloca(func_builder, param_ty2) + alloca: 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: rawptr[llvmlite.Value] = llvmlite.SSAValue( + param_val: llvmlite.Value* = llvmlite.SSAValue( pool, param_ty2, pname2) llvmlite.build_store(func_builder, param_val, alloca) @@ -918,26 +918,26 @@ class ClassGenVTable(ClassGenBase.ClassGenBase): # 指针到 trans,供 translate_raise 的 raise StopIteration 写 1。 # 参数名必须与上面 add_param 的 "%__stop_iter_flag__" 一致。 if string.strcmp(method_name, "__next__") == 0: - i1_ty_sf: rawptr[llvmlite.LLVMType] = llvmlite.Int1(pool) + i1_ty_sf: llvmlite.LLVMType* = llvmlite.Int1(pool) if i1_ty_sf is not None: - i1_ptr_ty_sf: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, i1_ty_sf) + i1_ptr_ty_sf: llvmlite.LLVMType* = llvmlite.Ptr(pool, i1_ty_sf) if i1_ptr_ty_sf is not None: - flag_ref_sf: rawptr[llvmlite.Value] = llvmlite.SSAValue( + flag_ref_sf: 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: rawptr[llvmlite.Value] = llvmlite.ConstInt( + zero_i1_sf: 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: rawptr[llvmlite.IRBuilder] = trans._cur_builder + old_func: llvmlite.Function* = trans._cur_func + old_builder: 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: rawptr[llvmlite.Value] = trans._stop_iter_flag_ptr + old_stop_iter_flag: llvmlite.Value* = trans._stop_iter_flag_ptr trans._cur_func = func trans._cur_builder = func_builder @@ -952,11 +952,11 @@ class ClassGenVTable(ClassGenBase.ClassGenBase): if body is not None: bn: sizet = len(body) for bi in range(bn): - stmt: rawptr[ast.AST] = body.get(bi) + stmt: ast.AST* = body.get(bi) if stmt is not None: self.Gen.StmtGenDecl.pre_scan_scope_decls(trans, stmt) for bi in range(bn): - stmt: rawptr[ast.AST] = body.get(bi) + stmt: ast.AST* = body.get(bi) if stmt is not None: self.Gen.StmtGenDecl.pre_scan_allocas(trans, stmt) @@ -964,7 +964,7 @@ class ClassGenVTable(ClassGenBase.ClassGenBase): if body is not None: bn2: sizet = len(body) for bi2 in range(bn2): - stmt2: rawptr[ast.AST] = body.get(bi2) + stmt2: ast.AST* = body.get(bi2) if stmt2 is not None: self.Gen.StmtGen.translate_stmt(trans, stmt2) @@ -983,14 +983,14 @@ class ClassGenVTable(ClassGenBase.ClassGenBase): if body is not None: bn3 = len(body) if bn3 > 0: - last_stmt_m: rawptr[ast.AST] = body.get(bn3 - 1) + last_stmt_m: ast.AST* = body.get(bn3 - 1) if last_stmt_m is not None and last_stmt_m.kind() == ast.ASTKind.Return: last_is_return = 1 if last_is_return == 0: if llvmlite.builder_cur_block_is_terminated(func_builder) == 0: last_is_ctrl: int = 0 if bn3 > 0: - last_stmt3_m: rawptr[ast.AST] = body.get(bn3 - 1) + last_stmt3_m: ast.AST* = body.get(bn3 - 1) if last_stmt3_m is not None: k3m: int = last_stmt3_m.kind() if k3m == ast.ASTKind.If or k3m == ast.ASTKind.While or \ @@ -1017,8 +1017,8 @@ class ClassGenVTable(ClassGenBase.ClassGenBase): fd.returns, imported_modules) != 0: _is_void = 1 elif fd.returns.kind() == ast.ASTKind.Constant: - ret_none_cn_m: rawptr[ast.Constant] = ( - rawptr[ast.Constant])(fd.returns) + ret_none_cn_m: ast.Constant* = ( + ast.Constant*)(fd.returns) if ret_none_cn_m.const_kind == ast.CONST_NONE: _is_void = 1 if _is_void != 0: @@ -1032,7 +1032,7 @@ class ClassGenVTable(ClassGenBase.ClassGenBase): elif fd.returns is None: # 无返回类型注解 → 无返回值过程方法,默认零值返回 if ret_ty is not None: - _m_zero_val: rawptr[llvmlite.Value] = llvmlite.ConstZero(pool, ret_ty) + _m_zero_val: llvmlite.Value* = llvmlite.ConstZero(pool, ret_ty) if _m_zero_val is not None: llvmlite.build_ret(func_builder, _m_zero_val) else: @@ -1078,21 +1078,21 @@ class ClassGenVTable(ClassGenBase.ClassGenBase): # 2. 逐字段 store 默认值(如有) # 3. ret void # ============================================================ - def _generate_before_init(self, trans: rawptr[HT.Translator], - struct_ty: rawptr[llvmlite.LLVMType], + def _generate_before_init(self, trans: HT.Translator*, + struct_ty: llvmlite.LLVMType*, class_name: str) -> int: """生成 __before_init__ 函数,返回 0""" if trans is None or struct_ty is None or class_name is None: return 0 - pool: rawptr[memhub.MemBuddy] = trans.Pool - mod: rawptr[llvmlite.LLVMModule] = trans.Module - funcs_ptr: rawptr[GenTypes.FuncEntry] = trans._funcs + pool: memhub.MemBuddy* = trans.Pool + mod: llvmlite.LLVMModule* = trans.Module + funcs_ptr: GenTypes.FuncEntry* = trans._funcs func_count: int = trans._func_count - self_ptr_ty: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, struct_ty) - void_ty: rawptr[llvmlite.LLVMType] = llvmlite.Void(pool) + self_ptr_ty: llvmlite.LLVMType* = llvmlite.Ptr(pool, struct_ty) + void_ty: llvmlite.LLVMType* = llvmlite.Void(pool) # 构建函数名: ClassName.__before_init__ full_name_buf: str = pool.alloc(128) @@ -1104,7 +1104,7 @@ class ClassGenVTable(ClassGenBase.ClassGenBase): mangled_name: str = self.Gen.FuncGenBase._mangle_name(trans, full_name) # 创建函数 - func: rawptr[llvmlite.Function] = llvmlite.create_function( + func: llvmlite.Function* = llvmlite.create_function( pool, mod, mangled_name, void_ty) if func is None: return 0 @@ -1125,13 +1125,13 @@ class ClassGenVTable(ClassGenBase.ClassGenBase): entry_blk: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(pool, func, "entry") if entry_blk is None: return 0 - func_builder: rawptr[llvmlite.IRBuilder] = llvmlite.new_builder(pool, func) + func_builder: 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: rawptr[llvmlite.Value] = llvmlite.SSAValue(pool, self_ptr_ty, "%self") + self_val: 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: rawptr[llvmlite.Value] = llvmlite.ConstZero(pool, struct_ty) + zero: 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: rawptr[GenTypes.StructEntry] = self.Gen.StructGen.find_struct_by_type(struct_ty) + bi_entry: 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 @@ -1155,13 +1155,13 @@ class ClassGenVTable(ClassGenBase.ClassGenBase): vt_method_count = bi_entry.VTableMethodCount if vt_method_count > 0: # 构造 vtable 类型 { i8*, i8*, ..., i8* } - vt_i8_ty: rawptr[llvmlite.LLVMType] = llvmlite.Int8(pool) - vt_i8_ptr_ty: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, vt_i8_ty) + vt_i8_ty: llvmlite.LLVMType* = llvmlite.Int8(pool) + vt_i8_ptr_ty: llvmlite.LLVMType* = llvmlite.Ptr(pool, vt_i8_ty) - vt_first_node: rawptr[llvmlite.Function] = None - vt_prev_node: rawptr[llvmlite.Function] = None + vt_first_node: llvmlite.Function* = None + vt_prev_node: llvmlite.Function* = None for vti in range(vt_method_count): - vtnode: rawptr[llvmlite.Function] = llvmlite.new_param_node(pool, vt_i8_ptr_ty) + vtnode: llvmlite.Function* = llvmlite.new_param_node(pool, vt_i8_ptr_ty) if vtnode is None: continue if vt_first_node is None: @@ -1170,8 +1170,8 @@ class ClassGenVTable(ClassGenBase.ClassGenBase): llvmlite.paramnode_set_next(vt_prev_node, vtnode) vt_prev_node = vtnode - vt_ty: rawptr[llvmlite.LLVMType] = llvmlite.Struct(pool, vt_first_node, vt_method_count, None) - vt_ptr_ty: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, vt_ty) + vt_ty: llvmlite.LLVMType* = llvmlite.Struct(pool, vt_first_node, vt_method_count, None) + vt_ptr_ty: llvmlite.LLVMType* = llvmlite.Ptr(pool, vt_ty) # 构造 vtable 全局变量名 vt_name_buf: str = pool.alloc(128) @@ -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: rawptr[llvmlite.Value] = llvmlite.build_gep_struct( + vt_slot: 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: rawptr[llvmlite.Value] = llvmlite.new_value(pool) + vt_ref: 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: rawptr[llvmlite.Value] = llvmlite.build_bitcast( + vt_as_i8: 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: rawptr[GenTypes.FieldEntry] = self.Gen.StructGen._get_field_entry( + fe: GenTypes.FieldEntry* = self.Gen.StructGen._get_field_entry( bi_entry, fi) if fe is None or fe.DefaultVal is None: continue @@ -1219,25 +1219,32 @@ 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: rawptr[llvmlite.Value] = llvmlite.build_gep_struct( + field_ptr_arr: 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: rawptr[llvmlite.Value] = llvmlite.ConstZero(pool, fe.Ty) + zero_arr_f: 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 方法 # (AssignGenMixin._init_global_array_from_list)会生成不存在 # 符号 → 必须走 HandlesAnnAssign 模块级委托(延迟 import Gen)。 + # owner_ctx 只服务空元素 fail-fast 报文(类名 + 字段名 + 下标)。 + arr_ctx: str = pool.alloc(192) + if arr_ctx is not None: + fname_dbg_v: str = fe.Name + if fname_dbg_v is None: + fname_dbg_v = "?" + viperlib.snprintf(arr_ctx, 192, "类 %s 字段 %s:", class_name, fname_dbg_v) self.Gen.AssignGen._init_global_array_from_list( - func_builder, pool, mod, field_ptr_arr, fe.DefaultVal, trans) + func_builder, pool, mod, field_ptr_arr, fe.DefaultVal, trans, arr_ctx) continue # 翻译默认值表达式 - default_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( + default_val: 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: rawptr[llvmlite.Value] = llvmlite.build_gep_struct( + field_ptr: llvmlite.Value* = llvmlite.build_gep_struct( func_builder, struct_ty, fe.Ty, self_val, fe.Index) if field_ptr is None: continue diff --git a/App/lib/core/Gen/Expr/ExprGenAttr.vp b/App/lib/core/Gen/Expr/ExprGenAttr.vp index 83b0cbb..2626713 100644 --- a/App/lib/core/Gen/Expr/ExprGenAttr.vp +++ b/App/lib/core/Gen/Expr/ExprGenAttr.vp @@ -18,30 +18,24 @@ import lib.core.Gen.Expr.ExprGenBase as ExprGenBase import lib.core.Gen.GenApi as GenApi # ============================================================ -# ExprGenAttr - ExprGenMixin 拆分(阶段 D):Attribute/属性访问/全局引用 -# -# 继承 ExprGenBase(1 级,TPV self 调用仅支持 1 级父类)。 -# 跨 Mixin 调用统一走 HandlesExpr 委托(经 _g_gen)。 -# @t.NoVTable:静态绑定。 +# ExprGenAttr - Attribute/属性访问/全局引用 # ============================================================ -@t.NoVTable -class ExprGenAttr(ExprGenBase.ExprGenBase): +novirtual class ExprGenAttr(ExprGenBase.ExprGenBase): """Attribute/属性访问/全局引用""" - - # ============================================================ + # ============================================================ # find_global_in_module - 在模块全局变量链表中按名称查找 # # 查找策略: # 1. 精确匹配 (如 "_mbuddy" 匹配 @_mbuddy) # 2. 后缀匹配 (如 "_mbuddy" 匹配 @"sha1._mbuddy") # ============================================================ - def find_global_in_module(self, mod: rawptr[llvmlite.LLVMModule], - name: str) -> rawptr[llvmlite.GlobalVariable]: + def find_global_in_module(self, mod: llvmlite.LLVMModule*, + name: str) -> llvmlite.GlobalVariable*: """在模块全局变量链表中按名称查找全局变量""" if mod is None or name is None: return None name_len: sizet = string.strlen(name) - cur: rawptr[llvmlite.GlobalVariable] = mod.GlobalHead + cur: llvmlite.GlobalVariable* = mod.GlobalHead # 第一遍: 精确匹配 while cur is not None: if cur.Name is not None: @@ -71,13 +65,13 @@ class ExprGenAttr(ExprGenBase.ExprGenBase): # 用于跨模块全局变量访问: stub 未注入时,翻译阶段生成 @name 引用, # 链接时由 stub 提供 external global 声明。 # ============================================================ - def make_global_ref(self, pool: rawptr[memhub.MemBuddy], + def make_global_ref(self, pool: memhub.MemBuddy*, name: str, - ty: rawptr[llvmlite.LLVMType]) -> rawptr[llvmlite.Value]: + ty: llvmlite.LLVMType*) -> llvmlite.Value*: """创建全局变量引用 (类型为 ty*,名称为 @name)""" if name is None or ty is None: return None - ptr_ty: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, ty) + ptr_ty: llvmlite.LLVMType* = llvmlite.Ptr(pool, ty) ref_name: str = pool.alloc(96) if ref_name is None: return None @@ -110,83 +104,46 @@ class ExprGenAttr(ExprGenBase.ExprGenBase): if name is None: return 0 # t.py 中的类型对象名(PascalCase,首字母大写) - if string.strcmp(name, "CPtr") == 0: - return 1 - if string.strcmp(name, "CInt") == 0: - return 1 - if string.strcmp(name, "CChar") == 0: - return 1 - if string.strcmp(name, "CShort") == 0: - return 1 - if string.strcmp(name, "CLong") == 0: - return 1 - if string.strcmp(name, "CLongLong") == 0: - return 1 - if string.strcmp(name, "CDouble") == 0: - return 1 - if string.strcmp(name, "CFloat") == 0: - return 1 - if string.strcmp(name, "CBool") == 0: - return 1 - if string.strcmp(name, "CVoid") == 0: - return 1 - if string.strcmp(name, "CInt8T") == 0: - return 1 - if string.strcmp(name, "CInt16T") == 0: - return 1 - if string.strcmp(name, "CInt32T") == 0: - return 1 - if string.strcmp(name, "CInt64T") == 0: - return 1 - if string.strcmp(name, "CUInt8T") == 0: - return 1 - if string.strcmp(name, "CUInt16T") == 0: - return 1 - if string.strcmp(name, "CUInt32T") == 0: - return 1 - if string.strcmp(name, "CUInt64T") == 0: - return 1 - if string.strcmp(name, "CUnsigned") == 0: - return 1 - if string.strcmp(name, "CUnsignedInt") == 0: - return 1 - if string.strcmp(name, "CUnsignedChar") == 0: - return 1 - if string.strcmp(name, "CUnsignedShort") == 0: - return 1 - if string.strcmp(name, "CUnsignedLong") == 0: - return 1 - if string.strcmp(name, "CUnsignedLongLong") == 0: - return 1 - if string.strcmp(name, "CSizeT") == 0: - return 1 - if string.strcmp(name, "CIntPtrT") == 0: - return 1 - if string.strcmp(name, "CUIntPtrT") == 0: - return 1 - if string.strcmp(name, "CPtrDiffT") == 0: - return 1 - if string.strcmp(name, "CType") == 0: - return 1 - if string.strcmp(name, "CDefine") == 0: - return 1 - if string.strcmp(name, "CStatic") == 0: - return 1 - if string.strcmp(name, "CExport") == 0: - return 1 - if string.strcmp(name, "CArray") == 0: - return 1 - if string.strcmp(name, "CTypedef") == 0: - return 1 - if string.strcmp(name, "CNoVTable") == 0: - return 1 - if string.strcmp(name, "CNeedPtr") == 0: - return 1 - if string.strcmp(name, "CAutoPtr") == 0: - return 1 + if string.strcmp(name, "CPtr") == 0: return 1 + if string.strcmp(name, "CInt") == 0: return 1 + if string.strcmp(name, "CChar") == 0: return 1 + if string.strcmp(name, "CShort") == 0: return 1 + if string.strcmp(name, "CLong") == 0: return 1 + if string.strcmp(name, "CLongLong") == 0: return 1 + if string.strcmp(name, "CDouble") == 0: return 1 + if string.strcmp(name, "CFloat") == 0: return 1 + if string.strcmp(name, "CBool") == 0: return 1 + if string.strcmp(name, "CVoid") == 0: return 1 + if string.strcmp(name, "CInt8T") == 0: return 1 + if string.strcmp(name, "CInt16T") == 0: return 1 + if string.strcmp(name, "CInt32T") == 0: return 1 + if string.strcmp(name, "CInt64T") == 0: return 1 + if string.strcmp(name, "CUInt8T") == 0: return 1 + if string.strcmp(name, "CUInt16T") == 0: return 1 + if string.strcmp(name, "CUInt32T") == 0: return 1 + if string.strcmp(name, "CUInt64T") == 0: return 1 + if string.strcmp(name, "CUnsigned") == 0: return 1 + if string.strcmp(name, "CUnsignedInt") == 0: return 1 + if string.strcmp(name, "CUnsignedChar") == 0: return 1 + if string.strcmp(name, "CUnsignedShort") == 0: return 1 + if string.strcmp(name, "CUnsignedLong") == 0: return 1 + if string.strcmp(name, "CUnsignedLongLong") == 0: return 1 + if string.strcmp(name, "CSizeT") == 0: return 1 + if string.strcmp(name, "CIntPtrT") == 0: return 1 + if string.strcmp(name, "CUIntPtrT") == 0: return 1 + if string.strcmp(name, "CPtrDiffT") == 0: return 1 + if string.strcmp(name, "CType") == 0: return 1 + if string.strcmp(name, "CDefine") == 0: return 1 + if string.strcmp(name, "CStatic") == 0: return 1 + if string.strcmp(name, "CExport") == 0: return 1 + if string.strcmp(name, "CArray") == 0: return 1 + if string.strcmp(name, "CTypedef") == 0: return 1 + if string.strcmp(name, "CNoVTable") == 0: return 1 + if string.strcmp(name, "CNeedPtr") == 0: return 1 + if string.strcmp(name, "CAutoPtr") == 0: return 1 return 0 - def _attr_module_path_str(self, pool: rawptr[memhub.MemBuddy], - node: rawptr[ast.AST]) -> str: + def _attr_module_path_str(self, pool: memhub.MemBuddy*, + node: ast.AST*) -> str: """把模块引用 AST 转成模块路径字符串(递归拼接 Attribute 链): Name('sys') → "sys";Attribute(Attribute(Name('os'),'_win32')) → "os._win32"。 非模块引用形态(Call/Subscript 等)返回 None。""" @@ -194,30 +151,26 @@ class ExprGenAttr(ExprGenBase.ExprGenBase): return None k: int = node.kind() if k == ast.ASTKind.Name: - nm_m: rawptr[ast.Name] = rawptr[ast.Name](node) - if nm_m.id is not None: - return nm_m.id + nm_m: ast.Name* = ast.Name*(node) + if nm_m.id is not None: return nm_m.id return None if k == ast.ASTKind.Attribute: - at_m: rawptr[ast.Attribute] = rawptr[ast.Attribute](node) - if at_m.attr is None: - return None + at_m: ast.Attribute* = ast.Attribute*(node) + if at_m.attr is None: return None base_m: str = self._attr_module_path_str(pool, at_m.value) - if base_m is None: - return None + if base_m is None: return None blen: sizet = string.strlen(base_m) alen: sizet = string.strlen(at_m.attr) buf_m: str = pool.alloc(blen + alen + 2) - if buf_m is None: - return None + if buf_m is None: return None viperlib.snprintf(buf_m, blen + alen + 2, "%s.%s", base_m, at_m.attr) return buf_m return None - def _resolve_module_attribute_global(self, pool: rawptr[memhub.MemBuddy], - mod: rawptr[llvmlite.LLVMModule], - trans: rawptr[HT.Translator], - at: rawptr[ast.Attribute], - ty_hint: rawptr[llvmlite.LLVMType]) -> rawptr[llvmlite.Value]: + def _resolve_module_attribute_global(self, pool: memhub.MemBuddy*, + mod: llvmlite.LLVMModule*, + trans: HT.Translator*, + at: ast.Attribute*, + ty_hint: llvmlite.LLVMType*) -> llvmlite.Value*: """解析模块属性访问,返回全局变量引用 (用于跨模块 global 访问)""" if at is None or at.value is None or at.attr is None: return None @@ -227,8 +180,7 @@ class ExprGenAttr(ExprGenBase.ExprGenBase): # (此前只支持 Name 模块;SysLibTest main.vp L32 `os._win32._mbuddy = v` # 的 at.value 是 Attribute → 被跳过 → "属性写入失败" 根因) mod_path_w: str = self._attr_module_path_str(pool, at.value) - if mod_path_w is None: - return None + if mod_path_w is None: return None # 别名解析:import lib.core.Gen.Generator as GenGenerator → 查 from_imports # 得原始模块名。否则 _lookup_module_sha1("GenGenerator") 查不到(Sha1Store # 用原始模块名)→ 退化裸名 → 全局带 SHA1 前缀后 undefined symbol。 @@ -236,8 +188,7 @@ class ExprGenAttr(ExprGenBase.ExprGenBase): # 注意:lookup_from_import 返回指针非 NUL 结尾,须截断到空格/冒号/NUL # 再查 SHA1(否则整串 "lib.core.Gen.Generator Config:lib... " 查不到)。 if trans._from_imports is not None: - orig_mw: str = self.Gen.ImportsGen.lookup_from_import( - trans._from_imports, mod_path_w, 0) + orig_mw: str = self.Gen.ImportsGen.lookup_from_import(trans._from_imports, mod_path_w, 0) if orig_mw is not None: oml_a: sizet = 0 while orig_mw[oml_a] != ' ' and orig_mw[oml_a] != '\0' and orig_mw[oml_a] != ':': @@ -254,9 +205,8 @@ class ExprGenAttr(ExprGenBase.ExprGenBase): # 在当前模块查找全局变量:优先按"目标模块 SHA1 前缀 + 属性名"精确匹配, # 避免多模块同名全局(@._mbuddy / @._mbuddy 同时注入)时裸名后缀 # 匹配返回错误模块的全局(串扰)。目标 sha1 未知时退化裸名(后缀匹配兜底) - gv_q: str = self.Gen.FuncGenBase._mangle_name_with_sha1( - self._lookup_module_sha1(mod_path_w), at.attr) - gv: rawptr[llvmlite.GlobalVariable] = self.find_global_in_module(mod, gv_q) + gv_q: str = self.Gen.FuncGenBase._mangle_name_with_sha1(self._lookup_module_sha1(mod_path_w), at.attr) + gv: llvmlite.GlobalVariable* = self.find_global_in_module(mod, gv_q) # CExport 全局(定义端裸名 @_sched_ptr):mangled 名查不到时回退裸名精确 # 查找。此前只查 mangled 名 → 找不到 → 新建 mangled external global 声明 # (@"ef5b0ba0dc895058._sched_ptr")→ 与定义端裸名不匹配 → ld.lld @@ -270,7 +220,7 @@ class ExprGenAttr(ExprGenBase.ExprGenBase): return self.make_global_ref(pool, gv.Name, gv.Ty) # 未找到: 创建 external global 声明并添加到模块 # 否则只生成 @_argc 引用而无声明,LLVM 报 "use of undefined value '@_argc'" - use_ty: rawptr[llvmlite.LLVMType] = ty_hint + use_ty: llvmlite.LLVMType* = ty_hint if use_ty is None: use_ty = llvmlite.Int8(pool) # 确保 use_ty 中的跨模块结构体类型有 opaque 声明 @@ -290,9 +240,8 @@ class ExprGenAttr(ExprGenBase.ExprGenBase): # 全局独立命名,消除 duplicate symbol / 串扰) gv_name_ba: str = at.attr 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: rawptr[llvmlite.GlobalVariable] = llvmlite.new_global_variable(pool, gv_name_ba, use_ty) + gv_name_ba = self.Gen.FuncGenBase._mangle_name_with_sha1(self._lookup_module_sha1(mod_path_w), at.attr) + ext_gv: 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,41 +291,40 @@ class ExprGenAttr(ExprGenBase.ExprGenBase): # ptr 指针值(Ptr(Struct) 或 Ptr(Ptr(Struct)),交由 _deref_if_ptr_ptr 解层级) # 非 c.Deref 模式返回 None # ============================================================ - 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) -> rawptr[llvmlite.Value]: + def _get_cderef_attr_base(self, builder: llvmlite.IRBuilder*, + pool: memhub.MemBuddy*, + mod: llvmlite.LLVMModule*, + at_value: ast.AST*, + trans: HT.Translator* = None) -> llvmlite.Value*: """检测 at.value 是否为 c.Deref(ptr) 调用,返回 ptr 指针(不做 load)""" if at_value is None or at_value.kind() != ast.ASTKind.Call: return None - cl_cd: rawptr[ast.Call] = rawptr[ast.Call](at_value) + cl_cd: ast.Call* = ast.Call*(at_value) if cl_cd.func is None or cl_cd.func.kind() != ast.ASTKind.Attribute: return None - f_cd: rawptr[ast.Attribute] = rawptr[ast.Attribute](cl_cd.func) + f_cd: ast.Attribute* = ast.Attribute*(cl_cd.func) if f_cd.attr is None or string.strcmp(f_cd.attr, "Deref") != 0: return None if f_cd.value is None or f_cd.value.kind() != ast.ASTKind.Name: return None - nm_cd: rawptr[ast.Name] = rawptr[ast.Name](f_cd.value) + nm_cd: ast.Name* = ast.Name*(f_cd.value) if nm_cd.id is None or string.strcmp(nm_cd.id, "c") != 0: return None if cl_cd.args is None or len(cl_cd.args) < 1: return None - inner_cd: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( - builder, pool, mod, cl_cd.args.get(0), None, 0, trans) + inner_cd: 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: rawptr[llvmlite.IRBuilder], - pool: rawptr[memhub.MemBuddy], - mod: rawptr[llvmlite.LLVMModule], - node: rawptr[ast.AST], - trans: rawptr[HT.Translator] = None) -> rawptr[llvmlite.Value]: + def translate_attribute(self, builder: llvmlite.IRBuilder*, + pool: memhub.MemBuddy*, + mod: llvmlite.LLVMModule*, + node: ast.AST*, + trans: HT.Translator* = None) -> llvmlite.Value*: """翻译属性访问,返回加载的字段值""" if node is None or builder is None: return None - at: rawptr[ast.Attribute] = rawptr[ast.Attribute](node) + at: ast.Attribute* = ast.Attribute*(node) if at is None or at.value is None or at.attr is None: # fast-fail: AST 节点字段缺失属解析器 bug,应报告具体缺失字段 diag_buf_an: bytes = stdlib.malloc(256) @@ -408,19 +356,19 @@ class ExprGenAttr(ExprGenBase.ExprGenBase): doc_mod_buf[0] = '\0' doc_sym_buf[0] = '\0' if at.value is not None and at.value.kind() == ast.ASTKind.Name: - nm_doc: rawptr[ast.Name] = rawptr[ast.Name](at.value) + nm_doc: ast.Name* = ast.Name*(at.value) if nm_doc.id is not None: self.Gen.ExprGenCls._resolve_doc_symbol_name(trans, nm_doc.id, doc_mod_buf, doc_sym_buf) elif at.value is not None and at.value.kind() == ast.ASTKind.Attribute: - self.Gen.ExprGenCls._resolve_doc_symbol_attr(trans, rawptr[ast.Attribute](at.value), doc_mod_buf, doc_sym_buf) + self.Gen.ExprGenCls._resolve_doc_symbol_attr(trans, ast.Attribute*(at.value), doc_mod_buf, doc_sym_buf) doc_val: str = None if doc_mod_buf[0] != '\0' and doc_sym_buf[0] != '\0': doc_val = self.Gen.ExprGenCls.lookup_docstring(doc_mod_buf, doc_sym_buf) if doc_val is None: - i8_ty_doc: rawptr[llvmlite.LLVMType] = llvmlite.Int8(pool) + i8_ty_doc: llvmlite.LLVMType* = llvmlite.Int8(pool) if i8_ty_doc is None: return None - i8_ptr_ty_doc: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, i8_ty_doc) + i8_ptr_ty_doc: llvmlite.LLVMType* = llvmlite.Ptr(pool, i8_ty_doc) if i8_ptr_ty_doc is None: return None return llvmlite.ConstNull(pool, i8_ptr_ty_doc, "null") @@ -429,14 +377,12 @@ class ExprGenAttr(ExprGenBase.ExprGenBase): # 枚举成员访问: EnumName.MemberName → 常量值 # 当 value 是 Name 且 Name.id 是已注册枚举时,查找成员并返回常量 if at.value.kind() == ast.ASTKind.Name: - enum_nm: rawptr[ast.Name] = rawptr[ast.Name](at.value) + enum_nm: ast.Name* = ast.Name*(at.value) if enum_nm.id is not None: if self.Gen.StmtGenDecl.is_enum_class(enum_nm.id) == 1: - member: rawptr[GenTypes.EnumMember] = self.Gen.StmtGenDecl.lookup_enum_member( - enum_nm.id, at.attr) + 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( - enum_nm.id) + base_ty: llvmlite.LLVMType* = self.Gen.StmtGenDecl.get_enum_base_type(enum_nm.id) if base_ty is not None: # 生成数字字符串作为常量名(LLVM IR 要求常量输出数字值) name_buf: str = pool.alloc(32) @@ -445,9 +391,7 @@ class ExprGenAttr(ExprGenBase.ExprGenBase): return llvmlite.ConstInt(pool, base_ty, member.Value, name_buf) return llvmlite.const_int32(pool, member.Value) # fast-fail: 枚举成员未找到 - VLogger.error( - f"枚举成员未找到: {enum_nm.id}.{at.attr}", - "ATTR") + VLogger.error(f"枚举成员未找到: {enum_nm.id}.{at.attr}", "ATTR") return None # 嵌套枚举成员访问: Module.EnumName.MemberName → 常量值 @@ -457,14 +401,12 @@ class ExprGenAttr(ExprGenBase.ExprGenBase): # Attribute)被跳过 → "属性访问失败: .W"(SysLibTest L190 根因)。 # 枚举类名只取最内层 attr(MODE),模块路径形态不影响。 if at.value.kind() == ast.ASTKind.Attribute: - inner_at_e: rawptr[ast.Attribute] = rawptr[ast.Attribute](at.value) + inner_at_e: ast.Attribute* = 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: rawptr[GenTypes.EnumMember] = self.Gen.StmtGenDecl.lookup_enum_member( - inner_at_e.attr, at.attr) + 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( - inner_at_e.attr) + base_ty_e: llvmlite.LLVMType* = self.Gen.StmtGenDecl.get_enum_base_type(inner_at_e.attr) if base_ty_e is not None: name_buf_e: str = pool.alloc(32) if name_buf_e is not None: @@ -472,14 +414,11 @@ 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: rawptr[GenTypes.EnumEntry] = self.Gen.StmtGenDecl.find_enum( - inner_at_e.attr) + dbg_ee: rawptr[GenTypes.EnumEntry] = self.Gen.StmtGenDecl.find_enum(inner_at_e.attr) dbg_mc: int = -1 if dbg_ee is not None: dbg_mc = dbg_ee.MemberCount - VLogger.error( - f"嵌套枚举成员未找到: {inner_at_e.attr}.{at.attr} " - f"(enum_members={dbg_mc})", "ATTR") + VLogger.error(f"嵌套枚举成员未找到: {inner_at_e.attr}.{at.attr} (enum_members={dbg_mc})", "ATTR") return None # REnum 变体引用作为值: ClassName.Variant / Module.ClassName.Variant → 变体 tag 常量 @@ -489,17 +428,16 @@ class ExprGenAttr(ExprGenBase.ExprGenBase): # 见 __types.vp)查变体返回 -1 → 自然落空不拦截。 renum_cls_rv: str = None if at.value.kind() == ast.ASTKind.Name: - rn_nm_rv: rawptr[ast.Name] = rawptr[ast.Name](at.value) + rn_nm_rv: ast.Name* = ast.Name*(at.value) if rn_nm_rv.id is not None: renum_cls_rv = rn_nm_rv.id elif at.value.kind() == ast.ASTKind.Attribute: - rn_at_rv: rawptr[ast.Attribute] = rawptr[ast.Attribute](at.value) + rn_at_rv: ast.Attribute* = ast.Attribute*(at.value) if rn_at_rv.attr is not None: renum_cls_rv = rn_at_rv.attr if renum_cls_rv is not None \ and self.Gen.ClassGenEnum._is_renum_class_name(renum_cls_rv) != 0: - rv_tag: int = self.Gen.ClassGenEnum._lookup_renum_variant_in_class( - renum_cls_rv, at.attr) + rv_tag: int = self.Gen.ClassGenEnum._lookup_renum_variant_in_class(renum_cls_rv, at.attr) if rv_tag >= 0: name_buf_rv: str = pool.alloc(32) if name_buf_rv is not None: @@ -512,34 +450,30 @@ class ExprGenAttr(ExprGenBase.ExprGenBase): # 对齐 TPC HandlesExprAttr.py L433-442:对象是 Name 变量且存在 # {var}__meta__ 影子(fd2 创建)时,属性访问改走影子结构体。 if at.value.kind() == ast.ASTKind.Name and trans is not None: - fd_nm: rawptr[ast.Name] = rawptr[ast.Name](at.value) + fd_nm: ast.Name* = ast.Name*(at.value) if fd_nm.id is not None: # pool 持久缓冲(f-string 栈缓冲在函数返回后失效) 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: rawptr[llvmlite.Value] = self.Gen.VarGen.lookup_current( - trans.SymTab, fd_meta_buf) + fd_meta_v: 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") + fd_sty: llvmlite.LLVMType* = self.Gen.StructGen.get_struct_type("_str") if fd_sty is not None: - fd_fe: rawptr[GenTypes.FieldEntry] = \ + fd_fe: 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: rawptr[llvmlite.Value] = llvmlite.build_gep_struct( - builder, fd_sty, fd_fe.Ty, fd_meta_v, fd_fe.Index) + fd_fp: 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) # 模块属性访问 (读路径): sys._mbuddy → 加载全局变量 @_mbuddy # 当 obj 是已导入模块名且不是普通变量时,查找/创建全局变量引用并加载 if at.value.kind() == ast.ASTKind.Name and trans is not None: - nm_ma: rawptr[ast.Name] = rawptr[ast.Name](at.value) + nm_ma: ast.Name* = ast.Name*(at.value) if nm_ma.id is not None: # 先检查是否是普通变量 (优先级高于模块属性) - ma_is_var: rawptr[llvmlite.Value] = self.Gen.VarGen.lookup_var( - trans.SymTab, nm_ma.id) + ma_is_var: 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) # 模块属性访问的 CDefine 常量需要跨模块查找源 .vp / .vpi 文件 @@ -551,8 +485,7 @@ class ExprGenAttr(ExprGenBase.ExprGenBase): # 如 win32base:w32.win32base → 别名 win32base 真实模块 w32.win32base real_mod_name: str = nm_ma.id if trans._from_imports is not None: - resolved_mod: str = self.Gen.ImportsGen.lookup_from_import( - trans._from_imports, nm_ma.id, 0) + resolved_mod: str = self.Gen.ImportsGen.lookup_from_import(trans._from_imports, nm_ma.id, 0) if resolved_mod is not None: # 复制模块名到新缓冲区(截断于空格、null、或 ':') rm_len: sizet = 0 @@ -580,8 +513,7 @@ class ExprGenAttr(ExprGenBase.ExprGenBase): if self.Gen.TypeGenCDef.is_cdefine_str() != 0: cdef_str_v: str = self.Gen.TypeGenCDef.lookup_cdefine_string(at.attr) if cdef_str_v is not None: - return self.Gen.ExprGenConst.create_global_string( - builder, pool, mod, cdef_str_v, trans) + return self.Gen.ExprGenConst.create_global_string(builder, pool, mod, cdef_str_v, trans) # 跨模块浮点 CDefine(如 vipermath.U_M_PI)→ 浮点常量 dchk_ma: double = self.Gen.TypeGenCDef.lookup_cdefine_double(at.attr) if self.Gen.TypeGenCDef.is_cdefine_double() != 0: @@ -599,8 +531,7 @@ class ExprGenAttr(ExprGenBase.ExprGenBase): is_submod = 1 # also check from_imports: at.attr 别名对应真实模块 w32.win32file if is_submod == 0 and trans._from_imports is not None: - fi_mod_raw: str = self.Gen.ImportsGen.lookup_from_import( - trans._from_imports, at.attr, 0) + fi_mod_raw: str = self.Gen.ImportsGen.lookup_from_import(trans._from_imports, at.attr, 0) if fi_mod_raw is not None: # 复制模块名到新缓冲区(截断于空格、null、或 ':') fm_len: sizet = 0 @@ -636,17 +567,13 @@ class ExprGenAttr(ExprGenBase.ExprGenBase): # "use of undefined value")。 if self.Gen.ExprGenCdef._is_cdefine_name_pattern(at.attr) != 0: if self.find_global_in_module(mod, at.attr) is None: - self.Gen.TypeGenErr.fatal_error( - at, - f"跨模块 CDefine 未找到: '{nm_ma.id}.{at.attr}'(CDefine cross-module lookup failed)", - "TypeError") + self.Gen.TypeGenErr.fatal_error(at, f"跨模块 CDefine 未找到: '{nm_ma.id}.{at.attr}'(CDefine cross-module lookup failed)", "TypeError") # 命中跨模块全局 → 落到下方跨模块全局加载路径 # 非 CDefine: 使用 i8* 作为类型提示 (模块级变量通常存储指针) - i8_ptr_hint: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, llvmlite.Int8(pool)) - mod_gv_ref: rawptr[llvmlite.Value] = self._resolve_module_attribute_global( - pool, mod, trans, at, i8_ptr_hint) + i8_ptr_hint: llvmlite.LLVMType* = llvmlite.Ptr(pool, llvmlite.Int8(pool)) + mod_gv_ref: 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 + load_ty_mod: llvmlite.LLVMType* = mod_gv_ref.Ty.Pointee if load_ty_mod is not None: # 模块级全局数组(如 zdef.zdeflate_len_base: CArray[T, N]): # 按 C 语义衰减为基址返回(对齐 translate_name_value 局部 @@ -661,9 +588,9 @@ class ExprGenAttr(ExprGenBase.ExprGenBase): # 嵌套模块属性访问 (w32.win32file.GENERIC_READ → 查找全局 @GENERIC_READ) # 当 at.value 是 Attribute 且解析为已导入子模块时,查找 at.attr 作为全局常量 if at.value.kind() == ast.ASTKind.Attribute and trans is not None: - inner_at: rawptr[ast.Attribute] = rawptr[ast.Attribute](at.value) + inner_at: ast.Attribute* = ast.Attribute*(at.value) if inner_at.value is not None and inner_at.value.kind() == ast.ASTKind.Name: - inner_nm: rawptr[ast.Name] = rawptr[ast.Name](inner_at.value) + inner_nm: ast.Name* = ast.Name*(inner_at.value) if inner_nm.id is not None and inner_at.attr is not None: if self.Gen.VarGen.lookup_var(trans.SymTab, inner_nm.id) is None: # 构建限定模块名: "w32.win32file" @@ -673,31 +600,26 @@ class ExprGenAttr(ExprGenBase.ExprGenBase): viperlib.snprintf(qual_buf, qual_len, "%s.%s", inner_nm.id, inner_at.attr) # 模块已知性:显式 import(w32.win32file)或全局模块注册表登记 #(包 __init__.vp 内 from . import X 注册的 pkg.X,如 intr.idt) - mod_known_n: int = self.Gen.ImportsGen.is_module_imported( - trans._imported_modules, qual_buf) + mod_known_n: int = self.Gen.ImportsGen.is_module_imported(trans._imported_modules, qual_buf) if mod_known_n == 0 and self._lookup_module_sha1(qual_buf) is not None: # 未显式 import 的已知子模块:先注入其 .vpi 声明到当前模块, # 否则 find_global_in_module 找不到该模块的 CExport 全局(@idt) #(main.vp intr.idt.idt[32] 根因) - StubMergerBuild.LoadDepVpiIntoModule( - pool, mod, qual_buf, trans._from_imports, - self.Gen.TypeGenBase.get_temp_dir(), trans) + StubMergerBuild.LoadDepVpiIntoModule(pool, mod, qual_buf, trans._from_imports, self.Gen.TypeGenBase.get_temp_dir(), trans) mod_known_n = 1 if mod_known_n != 0: # 查找全局变量 at.attr(带限定模块 SHA1 前缀精确匹配, # 避免多模块同名全局后缀匹配串扰;sha1 未知退化裸名) - gv_nested_q: str = self.Gen.FuncGenBase._mangle_name_with_sha1( - self._lookup_module_sha1(qual_buf), at.attr) - gv_nested: rawptr[llvmlite.GlobalVariable] = self.find_global_in_module(mod, gv_nested_q) + gv_nested_q: str = self.Gen.FuncGenBase._mangle_name_with_sha1(self._lookup_module_sha1(qual_buf), at.attr) + gv_nested: 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: rawptr[llvmlite.Value] = self.make_global_ref( - pool, gv_nested.Name, gv_nested.Ty) + gv_ref_nested: 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 + load_ty_nested: llvmlite.LLVMType* = gv_ref_nested.Ty.Pointee if load_ty_nested is not None: # 模块级全局数组(如 idt.idt: CArray[T, N])按 C 语义 # 返回基址指针(对齐读路径 L629-634),下标/取址继续 GEP @@ -729,43 +651,34 @@ class ExprGenAttr(ExprGenBase.ExprGenBase): # 导致 llc 报 "use of undefined value" 错误。 # 正确做法是报错终止,让开发者修复跨模块 CDefine 查找失败的根本原因。 if self.Gen.ExprGenCdef._is_cdefine_name_pattern(at.attr) != 0: - self.Gen.TypeGenErr.fatal_error( - at, - f"嵌套属性跨模块 CDefine 未找到: '{qual_buf}.{at.attr}'(CDefine cross-module lookup failed)", - "TypeError") + self.Gen.TypeGenErr.fatal_error(at, f"嵌套属性跨模块 CDefine 未找到: '{qual_buf}.{at.attr}'(CDefine cross-module lookup failed)", "TypeError") return None # 对于 Name 类型的 obj,直接查找 alloca(不 load 结构体); # nonlocal 变量(提升函数内)从 env 读共享堆值,避免 lookup_var # 跨函数引用外层 alloca(SSA 编号跨函数错乱崩溃) - obj_ptr: rawptr[llvmlite.Value] = None + obj_ptr: llvmlite.Value* = None if at.value.kind() == ast.ASTKind.Name and trans is not None: - nm: rawptr[ast.Name] = rawptr[ast.Name](at.value) + nm: ast.Name* = ast.Name*(at.value) if nm.id is not None: if GenApi.is_nonlocal_name(trans, nm.id) != 0: - raw_nl_a: rawptr[llvmlite.Value] = self.Gen.StmtGenDecl._load_raw_var_ptr( - trans, nm.id) + raw_nl_a: 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( - trans, nm.id) + nl_ty_a: llvmlite.LLVMType* = GenApi.get_nonlocal_type(trans, nm.id) if nl_ty_a is not None: # 对象即指针:Struct/Array 类型直接用堆地址(bitcast 后 # 作为对象指针,不 load);指针类型(如 Ptr(Point))堆里 # 存对象指针,需 load 出对象指针 match nl_ty_a: case llvmlite.LLVMType.Struct(_, _, _): - obj_ptr = llvmlite.build_bitcast( - builder, raw_nl_a, llvmlite.Ptr(pool, nl_ty_a)) + obj_ptr = llvmlite.build_bitcast(builder, raw_nl_a, llvmlite.Ptr(pool, nl_ty_a)) case llvmlite.LLVMType.Array(_, _): - obj_ptr = llvmlite.build_bitcast( - builder, raw_nl_a, llvmlite.Ptr(pool, nl_ty_a)) + obj_ptr = llvmlite.build_bitcast(builder, raw_nl_a, llvmlite.Ptr(pool, nl_ty_a)) case _: - nl_val_ptr_a: rawptr[llvmlite.Value] = \ - llvmlite.build_bitcast( - builder, raw_nl_a, llvmlite.Ptr(pool, nl_ty_a)) + nl_val_ptr_a: llvmlite.Value* = \ + llvmlite.build_bitcast(builder, raw_nl_a, llvmlite.Ptr(pool, nl_ty_a)) if nl_val_ptr_a is not None: - obj_ptr = llvmlite.build_load( - builder, nl_ty_a, nl_val_ptr_a) + obj_ptr = llvmlite.build_load(builder, nl_ty_a, nl_val_ptr_a) else: obj_ptr = self.Gen.VarGen.lookup_var(trans.SymTab, nm.id) @@ -773,8 +686,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: rawptr[llvmlite.Value] = self._get_cderef_attr_base( - builder, pool, mod, at.value, trans) + cd_base_rd: 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 elif at.value.kind() == ast.ASTKind.Subscript: @@ -813,35 +725,26 @@ class ExprGenAttr(ExprGenBase.ExprGenBase): # 确保跨模块结构体的完整定义在当前模块中可用(供 getelementptr 访问字段) self.Gen.StructGen.ensure_struct_def_in_module(pool, mod, struct_ty) # 查找字段索引和类型 - field_info: rawptr[GenTypes.FieldEntry] = self.Gen.StructGen.lookup_field( - struct_ty, at.attr) + field_info: 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: rawptr[GenTypes.StructEntry] = self.Gen.StructGen.find_struct_by_type( - struct_ty) + renum_se: 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) if is_rn == 1: - alias_idx: int = self.Gen.ClassGenEnum._lookup_renum_field_alias( - renum_se.Name, at.attr) + alias_idx: int = self.Gen.ClassGenEnum._lookup_renum_field_alias(renum_se.Name, at.attr) if alias_idx >= 1: - alias_fe: rawptr[GenTypes.FieldEntry] = \ - self.Gen.StructGen._get_field_entry(renum_se, alias_idx) + alias_fe: 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: rawptr[llvmlite.Value] = llvmlite.build_gep_struct( - builder, struct_ty, alias_fe.Ty, obj_ptr, alias_idx) + alias_ptr: 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——同宽无信息丢失,指针字段读出真正的指针值 - decl_ty_rn: rawptr[llvmlite.LLVMType] = \ - self.Gen.ClassGenEnum._lookup_renum_field_alias_ty( - renum_se.Name, at.attr) + decl_ty_rn: llvmlite.LLVMType* = self.Gen.ClassGenEnum._lookup_renum_field_alias_ty(renum_se.Name, at.attr) if decl_ty_rn is not None: - decl_ptr_rn: rawptr[llvmlite.LLVMType] = \ - llvmlite.Ptr(pool, decl_ty_rn) + decl_ptr_rn: llvmlite.LLVMType* = llvmlite.Ptr(pool, decl_ty_rn) if decl_ptr_rn is not None: - cast_ptr_rn: rawptr[llvmlite.Value] = \ - llvmlite.build_bitcast(builder, alias_ptr, decl_ptr_rn) + cast_ptr_rn: 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) return llvmlite.build_load(builder, alias_fe.Ty, alias_ptr, vol_ba_rd) @@ -849,8 +752,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: rawptr[llvmlite.Value] = self.Gen.CallGenProp._try_property_getter_attr( - pool, builder, mod, at, obj_ptr, trans, prop_cls_fb) + prop_val: 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 # 按需过滤: struct_ty 为 i8(简化联合类型)时,通过 AnnotClassName 按类名查找 @@ -859,56 +761,49 @@ class ExprGenAttr(ExprGenBase.ExprGenBase): if field_info is None: base_class: str = None if at.value.kind() == ast.ASTKind.Name and trans is not None: - nm_fb: rawptr[ast.Name] = rawptr[ast.Name](at.value) + nm_fb: ast.Name* = ast.Name*(at.value) if nm_fb.id is not None: - var_entry: rawptr[GenTypes.VarEntry] = self.Gen.VarGen.lookup_var_entry( - trans.SymTab, nm_fb.id) + var_entry: 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) elif at.value.kind() == ast.ASTKind.Attribute: - base_class = self._resolve_attr_field_class(pool, trans, at.value) + # allow_module_global=1:基座可为「模块名.全局变量」(通用形态 + # Mod.g,如 GenApi._g_gen)——缺此则 Mod.g.Field[.Field] 的 + # 接收者类解析不出(末跳 lookup_field 必然失败)。 + base_class = self._resolve_attr_field_class(pool, trans, at.value, 1) if base_class is not None: cur_sha1: str = trans.ModuleSha1 - field_info = self.Gen.StructGen.lookup_field_by_class( - base_class, at.attr, cur_sha1, at, trans._from_imports) + field_info = self.Gen.StructGen.lookup_field_by_class(base_class, at.attr, cur_sha1, at, trans._from_imports) # REnum 变体字段别名回退:base_class 是 REnum 类时,变体 # 字段名(如 LLVMType.Pointee → _p2 槽位)不是普通字段, # lookup_field_by_class 查不到(LLVMType"字段 Pointee 未找到" # 根因;主路径 L4989-5004 的 REnum 别名查找因 struct_ty 简化 # 为 i8、find_struct_by_type 失败被跳过) - if field_info is None \ - and self.Gen.ClassGenEnum._is_renum_class_name(base_class) != 0: - rn_alias: int = self.Gen.ClassGenEnum._lookup_renum_field_alias( - base_class, at.attr) + if field_info is None and self.Gen.ClassGenEnum._is_renum_class_name(base_class) != 0: + rn_alias: int = self.Gen.ClassGenEnum._lookup_renum_field_alias(base_class, at.attr) if rn_alias >= 1: - rn_se: rawptr[GenTypes.StructEntry] = \ - self.Gen.StructGen.find_struct(base_class) + rn_se: GenTypes.StructEntry* = self.Gen.StructGen.find_struct(base_class) if rn_se is not None: - rn_fe: rawptr[GenTypes.FieldEntry] = \ - self.Gen.StructGen._get_field_entry(rn_se, rn_alias) + rn_fe: 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 # 按需过滤成功:bitcast obj_ptr 到 AnnotClassName 对应的结构体类型 # 原始 struct_ty 可能是 i8(X|t.CPtr 简化为 Ptr(i8)), # 需用实际结构体类型做 GEP,否则 GEP i8 失败 if field_info is not None: - annot_se: rawptr[GenTypes.StructEntry] = \ - self.Gen.StructGen.find_struct(base_class) + annot_se: 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: rawptr[llvmlite.Value] = \ - llvmlite.build_bitcast(builder, obj_ptr, annot_ptr_ty) + annot_ptr_ty: llvmlite.LLVMType* = llvmlite.Ptr(pool, annot_se.Ty) + casted_ptr: llvmlite.Value* = llvmlite.build_bitcast(builder, obj_ptr, annot_ptr_ty) if casted_ptr is not None: obj_ptr = casted_ptr struct_ty = annot_se.Ty # 按需过滤更新 struct_ty 后,需重新确保 # 注解类型结构体定义在当前模块可用 # (原始 struct_ty 可能是 i8,ensure 无效) - self.Gen.StructGen.ensure_struct_def_in_module( - pool, mod, annot_se.Ty) + self.Gen.StructGen.ensure_struct_def_in_module(pool, mod, annot_se.Ty) if field_info is not None: - field_ty: rawptr[llvmlite.LLVMType] = field_info.Ty + field_ty: llvmlite.LLVMType* = field_info.Ty # t.CVolatile 字段:经对象访问的 load 带 volatile 限定符 field_vol_rd: int = self.Gen.StructGen.field_is_volatile(field_info) # 合并"字段所指物 volatile"(基址是 rawptr[t.CVolatile|T] 时, @@ -917,41 +812,36 @@ class ExprGenAttr(ExprGenBase.ExprGenBase): field_vol_rd = 1 # 联合体: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: rawptr[llvmlite.Value] = llvmlite.build_bitcast( - builder, obj_ptr, field_ptr_ty) + field_ptr_ty: llvmlite.LLVMType* = llvmlite.Ptr(pool, field_ty) + casted: llvmlite.Value* = llvmlite.build_bitcast(builder, obj_ptr, field_ptr_ty) if casted is not None: return llvmlite.build_load(builder, field_ty, casted, field_vol_rd) return None # 普通结构体:GEP + load field_idx: int = field_info.Index - field_ptr: rawptr[llvmlite.Value] = llvmlite.build_gep_struct( - builder, struct_ty, field_ty, obj_ptr, field_idx) + field_ptr: 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: rawptr[GenTypes.StructEntry] = \ + rn_rd_se: 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: - decl_ty_rd: rawptr[llvmlite.LLVMType] = \ - self.Gen.ClassGenEnum._lookup_renum_field_alias_ty( - rn_rd_se.Name, at.attr) + decl_ty_rd: llvmlite.LLVMType* = \ + self.Gen.ClassGenEnum._lookup_renum_field_alias_ty(rn_rd_se.Name, at.attr) if decl_ty_rd is not None and self.is_array_type(decl_ty_rd) == 0: - decl_ptr_rd: rawptr[llvmlite.LLVMType] = llvmlite.Ptr( - pool, decl_ty_rd) + decl_ptr_rd: llvmlite.LLVMType* = llvmlite.Ptr(pool, decl_ty_rd) if decl_ptr_rd is not None: - cast_ptr_rd: rawptr[llvmlite.Value] = llvmlite.build_bitcast( - builder, field_ptr, decl_ptr_rd) + cast_ptr_rd: 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, field_vol_rd) # 数组类型字段不能 load 为 SSA value,直接返回字段指针 # 用于后续下标访问: self.state[0] → GEP state 字段 → GEP 数组元素 if self.is_array_type(field_ty) != 0: return field_ptr - loaded_val: rawptr[llvmlite.Value] = llvmlite.build_load(builder, field_ty, field_ptr, field_vol_rd) + loaded_val: llvmlite.Value* = llvmlite.build_load(builder, field_ty, field_ptr, field_vol_rd) # 联合类型字段(如 Token | t.CPtr)被编译为 i8*, # 若 AnnotClassName 指示了具体结构体类型,bitcast 为正确的结构体指针。 # 注意:仅当字段类型本身是指针时才 bitcast(指针→指针); @@ -960,8 +850,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: rawptr[GenTypes.StructEntry] = self.Gen.StructGen.find_struct( - fc_annot) + annot_struct: GenTypes.StructEntry* = self.Gen.StructGen.find_struct(fc_annot) if annot_struct is not None and annot_struct.Ty is not None: # 确保目标结构体类型在当前模块有声明(可能未定义/未 opaque): # 联合字段 AnnotClassName 可能解析到本模块未 import 的类 @@ -970,9 +859,8 @@ class ExprGenAttr(ExprGenBase.ExprGenBase): # _scan_type_for_cross_module_refs 只扫 Ptr(Struct) 模式, # 因此传 Ptr(Ty) 让结构体名本身被 opaque 声明。 # opaque 声明足以支撑指针 bitcast(不访问字段),行为不变。 - llvmlite.module_ensure_opaque_for_type( - mod, pool, llvmlite.Ptr(pool, annot_struct.Ty)) - annot_ptr_ty: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, annot_struct.Ty) + llvmlite.module_ensure_opaque_for_type(mod, pool, llvmlite.Ptr(pool, annot_struct.Ty)) + annot_ptr_ty: llvmlite.LLVMType* = llvmlite.Ptr(pool, annot_struct.Ty) return llvmlite.build_bitcast(builder, loaded_val, annot_ptr_ty) return loaded_val # 字段未找到:可能是 Phase A 依赖未就绪(定义侧模块未编译,vpi @@ -982,11 +870,10 @@ class ExprGenAttr(ExprGenBase.ExprGenBase): diag_annot: str = None diag_var_nm: str = None if at.value is not None and at.value.kind() == ast.ASTKind.Name: - dnm: rawptr[ast.Name] = rawptr[ast.Name](at.value) + dnm: ast.Name* = ast.Name*(at.value) diag_var_nm = dnm.id if dnm.id is not None: - dve: rawptr[GenTypes.VarEntry] = self.Gen.VarGen.lookup_var_entry( - trans.SymTab, dnm.id) + dve: 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) diag_var_txt: str = "?" @@ -995,13 +882,19 @@ class ExprGenAttr(ExprGenBase.ExprGenBase): diag_annot_txt: str = "None" if diag_annot is not None: diag_annot_txt = diag_annot + # 接收者链路径(Name/Attribute 链逐段拼接,如 + # "GenApi._g_gen.TypeGenCDef"):`var=?` 说明接收者不是本模块 + # 变量,此处补出完整拼写形态,供直接定位是模块限定全局链 + # (Mod.g.F[.F])还是字段链;Call/Subscript 等形态给 "?"。 + diag_base_txt: str = "?" + if at.value is not None: + dbg_bp: str = self._attr_module_path_str(pool, at.value) + if dbg_bp is not None: + diag_base_txt = dbg_bp sha1_attr: str = "?" if trans.ModuleSha1 is not None: sha1_attr = trans.ModuleSha1 - self.Gen.TypeGenErr.fatal_error( - at, - f"属性访问失败: .{at.attr} (var={diag_var_txt} annot={diag_annot_txt} sha1={sha1_attr})", - "TypeError") + self.Gen.TypeGenErr.fatal_error(at, f"属性访问失败: .{at.attr} (var={diag_var_txt} annot={diag_annot_txt} base={diag_base_txt} sha1={sha1_attr})", "TypeError") return None case _: # fast-fail: 对非指针类型做属性访问(如 i32.x), @@ -1015,10 +908,7 @@ class ExprGenAttr(ExprGenBase.ExprGenBase): ln_ap: int = 0 if at is not None and at.lineno is not None: ln_ap = at.lineno - self.Gen.TypeGenErr.fatal_error( - at, - f"属性访问失败: .{attr_nm_ap} (base=非指针类型,无法做属性访问 sha1={sha1_ap}:{ln_ap})", - "TypeError") + self.Gen.TypeGenErr.fatal_error(at, f"属性访问失败: .{attr_nm_ap} (base=非指针类型,无法做属性访问 sha1={sha1_ap}:{ln_ap})", "TypeError") # fatal_error 后补显式 return 样板:match 末 arm 块必须 terminated, # 否则掉出末尾被函数收尾 fail-fast 误判(块设计约定) return None @@ -1026,9 +916,10 @@ class ExprGenAttr(ExprGenBase.ExprGenBase): # 获取属性访问的字段指针(不加载值,用于赋值) # 对于 Name 类型的 obj,直接使用 alloca 指针(不 load 结构体) # ============================================================ - def _resolve_attr_field_class(self, pool: rawptr[memhub.MemBuddy], - trans: rawptr[HT.Translator], - attr_node: rawptr[ast.AST]) -> str: + def _resolve_attr_field_class(self, pool: memhub.MemBuddy*, + trans: HT.Translator*, + attr_node: ast.AST*, + allow_module_global: int = 0) -> str: """解析属性链(a.b.c)中 c 字段的注解类名。 联合类型字段(X | t.CPtr)被简化为 Ptr(i8),属性链写入时 @@ -1036,48 +927,109 @@ class ExprGenAttr(ExprGenBase.ExprGenBase): lookup_field(i8, ...) 必然失败。此函数沿属性链递归解析 最终字段的 AnnotClassName(如 tokens_tail → 'Token'), 供按需过滤分支 bitcast 回真实结构体类型后 GEP。 + + allow_module_global: 1=基座为「模块名.全局变量」(Mod.g,如 + GenApi._g_gen)时按该全局的元素类型取类名(属性访问的接收者解析需要: + 该形态基座不是本模块变量,无 VarEntry 可取类名;缺此分支则 + Mod.g.Field[.Field] 全链解析不出接收者类,末跳必然 lookup_field 失败); + 0=严格按变量注解/字段注解解析——其余调用方(虚拟分派/注解推断/volatile + 判定等)口径逐字不变。 """ if attr_node is None or trans is None: return None k: int = attr_node.kind() if k != ast.ASTKind.Attribute: return None - at: rawptr[ast.Attribute] = rawptr[ast.Attribute](attr_node) + at: ast.Attribute* = ast.Attribute*(attr_node) if at is None or at.attr is None or at.value is None: return None # 递归解析基座的注解类名(Name → 变量注解;Attribute → 字段注解) parent_class: str = None if at.value.kind() == ast.ASTKind.Name: - nm: rawptr[ast.Name] = rawptr[ast.Name](at.value) - if nm.id is None: - return None - var_entry: rawptr[GenTypes.VarEntry] = self.Gen.VarGen.lookup_var_entry( - trans.SymTab, nm.id) + nm: ast.Name* = ast.Name*(at.value) + if nm.id is None: return None + var_entry: GenTypes.VarEntry* = self.Gen.VarGen.lookup_var_entry(trans.SymTab, nm.id) if var_entry is None: + if allow_module_global != 0: + # 基座即「模块名.全局变量」本身(Mod.g,如 GenApi._g_gen): + # 本节点表达式的值就是该全局的对象指针,类名直接取自目标模块 + # 全局变量的元素类型(非该形态返回 None,调用方保持原语义)。 + return self._resolve_module_global_class_name(pool, trans, nm.id, at.attr) return None parent_class = self.Gen.VarGen.var_annot_class_name(var_entry) elif at.value.kind() == ast.ASTKind.Attribute: - parent_class = self._resolve_attr_field_class(pool, trans, at.value) - else: - return None - if parent_class is None: - return None + parent_class = self._resolve_attr_field_class(pool, trans, at.value, allow_module_global) + else: return None + if parent_class is None: return None # 在父类中查 at.attr 字段,返回其注解类名 cur_sha1: str = None - if trans is not None: - cur_sha1 = trans.ModuleSha1 + if trans is not None: cur_sha1 = trans.ModuleSha1 lfi_pc: str = None - if trans is not None: - lfi_pc = trans._from_imports - 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 + if trans is not None: lfi_pc = trans._from_imports + fe: 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 attr_field_is_volatile(self, pool: rawptr[memhub.MemBuddy], - trans: rawptr[HT.Translator], - attr_node: rawptr[ast.AST]) -> int: + # ============================================================ + # _resolve_module_global_class_name - 「模块名.全局变量」Mod.g 的结构体类名 + # + # 供 _resolve_attr_field_class 的模块根分支调用:属性链基座是「模块名.全局 + # 变量」(如 GenApi._g_gen)时,基座不是本模块变量(lookup_var_entry 恒 None), + # 其类名只能取自目标模块全局变量的元素类型(如 @"._g_gen" : %Generator* + # → "Generator")。取到类名后,紧随的 .Field 才能按该类查字段(按需过滤分支 + # bitcast 回真实结构体类型),Mod.g.Field[.Field] 全链方可解析。 + # + # 模块/全局定位口径与 _resolve_module_attribute_global 一致(import 别名还原 + # → 模块已知性 → SHA1 前缀名精确匹配 → 裸名回退)。未识别为模块限定全局时 + # 返回 None,调用方保持原语义(不新增报错、不改变既有可编译路径)。 + # ============================================================ + def _resolve_module_global_class_name(self, pool: memhub.MemBuddy*, + trans: HT.Translator*, + mod_name: str, + global_name: str) -> str: + """解析模块限定全局 Mod.g 的元素类型类名;非该形态返回 None""" + if pool is None or trans is None or mod_name is None or global_name is None: + return None + mod: llvmlite.LLVMModule* = trans.Module + if mod is None or trans._imported_modules is None: + return None + # 模块路径:import 别名还原(对齐 _resolve_module_attribute_global 的同款截断) + mod_path: str = mod_name + if trans._from_imports is not None: + orig_mw: str = self.Gen.ImportsGen.lookup_from_import(trans._from_imports, mod_name, 0) + if orig_mw is not None: + oml_mg: sizet = 0 + while orig_mw[oml_mg] != ' ' and orig_mw[oml_mg] != '\0' and orig_mw[oml_mg] != ':': + oml_mg += 1 + if oml_mg > 0: + om_buf_mg: str = pool.alloc(oml_mg + 1) + if om_buf_mg is not None: + string.strncpy(om_buf_mg, orig_mw, oml_mg) + om_buf_mg[oml_mg] = '\0' + mod_path = om_buf_mg + if self.Gen.ImportsGen.is_module_imported(trans._imported_modules, mod_path) == 0: + return None + # 全局定位:SHA1 前缀名(对齐定义端 mangling)→ 裸名回退(CExport 全局) + gv: llvmlite.GlobalVariable* = self.find_global_in_module(mod, self.Gen.FuncGenBase._mangle_name_with_sha1(self._lookup_module_sha1(mod_path), global_name)) + if gv is None: + gv = self.find_global_in_module(mod, global_name) + if gv is None or gv.Ty is None: return None + if self.is_ptr_type(gv.Ty) == 0: return None + # 全局变量类型是「元素类型的指针」(@"._g_gen" : %Generator*)⇒ 类名 + # 取其元素类型;元素类型仍可能是指针("多一层"形态 %Generator**)⇒ 逐层内推。 + elem_ty: llvmlite.LLVMType* = gv.Ty.Pointee + level_mg: int = 0 + while elem_ty is not None and level_mg < 3: + cls_mg: str = self.Gen.StructGen.get_class_name_by_type(pool, elem_ty) + if cls_mg is not None: return cls_mg + if self.is_ptr_type(elem_ty) == 0: return None + elem_ty = elem_ty.Pointee + level_mg += 1 + return None + + def attr_field_is_volatile(self, pool: memhub.MemBuddy*, + trans: HT.Translator*, + attr_node: ast.AST*) -> int: """obj.field 访问的字段是否 volatile(1=是 / 0=否) 仅解析一层属性:先定基座(Name 变量注解名 / 属性链字段注解名)得到父类, @@ -1088,25 +1040,20 @@ class ExprGenAttr(ExprGenBase.ExprGenBase): return 0 if attr_node.kind() != ast.ASTKind.Attribute: return 0 - at: rawptr[ast.Attribute] = rawptr[ast.Attribute](attr_node) + at: ast.Attribute* = ast.Attribute*(attr_node) if at is None or at.attr is None or at.value is None: return 0 parent_class: str = None if at.value.kind() == ast.ASTKind.Name: - nm: rawptr[ast.Name] = rawptr[ast.Name](at.value) - if nm.id is None: - return 0 - ve: rawptr[GenTypes.VarEntry] = self.Gen.VarGen.lookup_var_entry( - trans.SymTab, nm.id) - if ve is None: - return 0 + nm: ast.Name* = ast.Name*(at.value) + if nm.id is None: return 0 + ve: GenTypes.VarEntry* = self.Gen.VarGen.lookup_var_entry(trans.SymTab, nm.id) + if ve is None: return 0 parent_class = self.Gen.VarGen.var_annot_class_name(ve) elif at.value.kind() == ast.ASTKind.Attribute: parent_class = self._resolve_attr_field_class(pool, trans, at.value) - if parent_class is None: - return 0 - fe: rawptr[GenTypes.FieldEntry] = self.Gen.StructGen.lookup_field_by_class( - parent_class, at.attr, trans.ModuleSha1, at, trans._from_imports) + if parent_class is None: return 0 + fe: GenTypes.FieldEntry* = self.Gen.StructGen.lookup_field_by_class(parent_class, at.attr, trans.ModuleSha1, at, trans._from_imports) return self.Gen.StructGen.field_is_volatile(fe) # ============================================================ @@ -1114,9 +1061,9 @@ class ExprGenAttr(ExprGenBase.ExprGenBase): # 基址→VarEntry/FieldEntry 解析与消费点。仅在基址能解析到具体条目时生效, # 其余(函数返回/复杂表达式等)返回 0(明确不支持,见限制清单)。 # ============================================================ - def _resolve_attr_field_entry(self, pool: rawptr[memhub.MemBuddy], - trans: rawptr[HT.Translator], - attr_node: rawptr[ast.AST]) -> rawptr[GenTypes.FieldEntry]: + def _resolve_attr_field_entry(self, pool: memhub.MemBuddy*, + trans: HT.Translator*, + attr_node: ast.AST*) -> GenTypes.FieldEntry*: """obj.field 访问的 FieldEntry(**非 fatal 只读解析**,失败返回 None) 与 attr_field_is_volatile 的区别:后者走 lookup_field_by_class(模块限定名 @@ -1125,61 +1072,67 @@ class ExprGenAttr(ExprGenBase.ExprGenBase): 取裸结构体、自遍历字段,未命中一律返回 None,绝不 fatal,不改变既有报错行为。 仅支持单层基座(基座是 Name,如 self.ptr);基座是属性链/调用/下标等返回 None。 """ - if attr_node is None or trans is None: - return None - if attr_node.kind() != ast.ASTKind.Attribute: - return None - at: rawptr[ast.Attribute] = rawptr[ast.Attribute](attr_node) - if at is None or at.attr is None or at.value is None: - return None - if at.value.kind() != ast.ASTKind.Name: - return None - nm: rawptr[ast.Name] = rawptr[ast.Name](at.value) - if nm.id is None: - return None - ve: rawptr[GenTypes.VarEntry] = self.Gen.VarGen.lookup_var_entry( - trans.SymTab, nm.id) - if ve is None: - return None + if attr_node is None or trans is None: return None + if attr_node.kind() != ast.ASTKind.Attribute: return None + at: ast.Attribute* = ast.Attribute*(attr_node) + if at is None or at.attr is None or at.value is None: return None + if at.value.kind() != ast.ASTKind.Name: return None + nm: ast.Name* = ast.Name*(at.value) + if nm.id is None: return None + ve: GenTypes.VarEntry* = self.Gen.VarGen.lookup_var_entry(trans.SymTab, nm.id) + if ve is None: return None cls_nm: str = self.Gen.VarGen.var_annot_class_name(ve) - if cls_nm is None: - return None + if cls_nm is None: return None # 取裸类名(点前部分):只做裸名结构体查找,避免模块限定名解析 fatal bare: str = cls_nm dot: str = self.Gen.StructGen._last_dot_outside_brackets(cls_nm) - if dot is not None: - bare = dot + 1 - if bare is None: - return None - st: rawptr[GenTypes.StructEntry] = self.Gen.StructGen.find_struct(bare) - if st is None: - return None + if dot is not None: bare = dot + 1 + if bare is None: return None + st: GenTypes.StructEntry* = self.Gen.StructGen.find_struct(bare) + if st is None: return None fi: int = 0 while fi < st.FieldCount: - fe_u: rawptr[GenTypes.FieldEntry] = \ - self.Gen.StructGen._get_field_entry(st, fi) - if fe_u is not None and fe_u.Name is not None \ - and string.strcmp(fe_u.Name, at.attr) == 0: + fe_u: GenTypes.FieldEntry* = self.Gen.StructGen._get_field_entry(st, fi) + if fe_u is not None and fe_u.Name is not None and string.strcmp(fe_u.Name, at.attr) == 0: return fe_u fi += 1 return None - def attr_field_pointee_is_volatile(self, pool: rawptr[memhub.MemBuddy], - trans: rawptr[HT.Translator], - attr_node: rawptr[ast.AST]) -> int: + def attr_field_pointee_is_volatile(self, pool: memhub.MemBuddy*, + trans: HT.Translator*, + attr_node: ast.AST*) -> int: """obj.field 字段的**所指物**是否 volatile(1=是 / 0=否) 即该字段注解是否为 rawptr[t.CVolatile | T](等价 C 的 volatile T*)。 消费点:经该字段解引用(self.ptr[i] / self.ptr.field)的 load/store 据此加 LLVM volatile 限定符。 """ - fe: rawptr[GenTypes.FieldEntry] = self._resolve_attr_field_entry( - pool, trans, attr_node) + fe: GenTypes.FieldEntry* = self._resolve_attr_field_entry(pool, trans, attr_node) return self.Gen.StructGen.field_pointee_is_volatile(fe) - def base_pointee_is_volatile(self, pool: rawptr[memhub.MemBuddy], - trans: rawptr[HT.Translator], - base_node: rawptr[ast.AST]) -> int: + def attr_field_is_const(self, pool: memhub.MemBuddy*, + trans: HT.Translator*, + attr_node: ast.AST*) -> int: + """obj.field 字段**自身**是否 const 对象(1=是 / 0=否) + + 即该字段注解含 t.CConst 且字段类型非指针(FieldEntry.IsConst 承载)。 + 消费点:obj.f = ... / self.f = ... / obj.f += ... 的字段写,据此 fail-fast。 + 与 TPC 的 Gen._IsFieldConst(键 `类名.字段名`)同判据,见 + Debugger/type-descriptors.md。 + """ + fe: GenTypes.FieldEntry* = self._resolve_attr_field_entry(pool, trans, attr_node) + return self.Gen.StructGen.field_is_const(fe) + + def attr_field_decl_src(self, pool: memhub.MemBuddy*, + trans: HT.Translator*, + attr_node: ast.AST*) -> str: + """字段注解来源名(供 const 报文的『声明处类型(含 const)』),无则 None。""" + fe: GenTypes.FieldEntry* = self._resolve_attr_field_entry(pool, trans, attr_node) + return self.Gen.StructGen.get_field_annot_class_name(fe) + + def base_pointee_is_volatile(self, pool: memhub.MemBuddy*, + trans: HT.Translator*, + base_node: ast.AST*) -> int: """指针基址的所指物是否 volatile(rawptr[t.CVolatile|T] 变量/字段) 仅当基址可解析到具体 VarEntry(Name)/ FieldEntry(Attribute)时生效; @@ -1189,59 +1142,50 @@ class ExprGenAttr(ExprGenBase.ExprGenBase): if base_node is None or trans is None: return 0 if base_node.kind() == ast.ASTKind.Name: - nm: rawptr[ast.Name] = rawptr[ast.Name](base_node) - if nm.id is None: - return 0 - ve: rawptr[GenTypes.VarEntry] = self.Gen.VarGen.lookup_var_entry( - trans.SymTab, nm.id) + nm: ast.Name* = ast.Name*(base_node) + if nm.id is None: return 0 + ve: GenTypes.VarEntry* = self.Gen.VarGen.lookup_var_entry(trans.SymTab, nm.id) return self.Gen.VarGen.var_pointee_is_volatile(ve) if base_node.kind() == ast.ASTKind.Attribute: return self.attr_field_pointee_is_volatile(pool, trans, base_node) return 0 - def get_attribute_ptr(self, builder: rawptr[llvmlite.IRBuilder], - pool: rawptr[memhub.MemBuddy], - mod: rawptr[llvmlite.LLVMModule], - node: rawptr[ast.AST], - trans: rawptr[HT.Translator] = None) -> rawptr[llvmlite.Value]: + def get_attribute_ptr(self, builder: llvmlite.IRBuilder*, + pool: memhub.MemBuddy*, + mod: llvmlite.LLVMModule*, + node: ast.AST*, + trans: HT.Translator* = None) -> llvmlite.Value*: """获取属性访问的字段指针(用于赋值 lhs)""" if node is None or builder is None: return None - at: rawptr[ast.Attribute] = rawptr[ast.Attribute](node) + at: ast.Attribute* = ast.Attribute*(node) if at is None or at.value is None or at.attr is None: return None # 对于 Name 类型的 obj,直接查找 alloca(不 load 结构体); # nonlocal 变量(提升函数内)从 env 读共享堆值,避免 lookup_var # 跨函数引用外层 alloca(SSA 编号跨函数错乱崩溃) - obj_ptr: rawptr[llvmlite.Value] = None + obj_ptr: llvmlite.Value* = None if at.value.kind() == ast.ASTKind.Name and trans is not None: - nm: rawptr[ast.Name] = rawptr[ast.Name](at.value) + nm: ast.Name* = ast.Name*(at.value) if nm.id is not None: if GenApi.is_nonlocal_name(trans, nm.id) != 0: - raw_nl_a: rawptr[llvmlite.Value] = self.Gen.StmtGenDecl._load_raw_var_ptr( - trans, nm.id) + raw_nl_a: 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( - trans, nm.id) + nl_ty_a: llvmlite.LLVMType* = GenApi.get_nonlocal_type(trans, nm.id) if nl_ty_a is not None: # 对象即指针:Struct/Array 类型直接用堆地址(bitcast 后 # 作为对象指针,不 load);指针类型(如 Ptr(Point))堆里 # 存对象指针,需 load 出对象指针 match nl_ty_a: case llvmlite.LLVMType.Struct(_, _, _): - obj_ptr = llvmlite.build_bitcast( - builder, raw_nl_a, llvmlite.Ptr(pool, nl_ty_a)) + obj_ptr = llvmlite.build_bitcast(builder, raw_nl_a, llvmlite.Ptr(pool, nl_ty_a)) case llvmlite.LLVMType.Array(_, _): - obj_ptr = llvmlite.build_bitcast( - builder, raw_nl_a, llvmlite.Ptr(pool, nl_ty_a)) + obj_ptr = llvmlite.build_bitcast(builder, raw_nl_a, llvmlite.Ptr(pool, nl_ty_a)) case _: - nl_val_ptr_a: rawptr[llvmlite.Value] = \ - llvmlite.build_bitcast( - builder, raw_nl_a, llvmlite.Ptr(pool, nl_ty_a)) + nl_val_ptr_a: llvmlite.Value* = llvmlite.build_bitcast(builder, raw_nl_a, llvmlite.Ptr(pool, nl_ty_a)) if nl_val_ptr_a is not None: - obj_ptr = llvmlite.build_load( - builder, nl_ty_a, nl_val_ptr_a) + obj_ptr = llvmlite.build_load(builder, nl_ty_a, nl_val_ptr_a) else: obj_ptr = self.Gen.VarGen.lookup_var(trans.SymTab, nm.id) @@ -1254,7 +1198,7 @@ class ExprGenAttr(ExprGenBase.ExprGenBase): # CDefine 常量不可写: 报 FATAL 错误,不创建未定义全局 # (仅单层 Name 模块可精确判 CDefine) if at.value.kind() == ast.ASTKind.Name: - nm_wma: rawptr[ast.Name] = rawptr[ast.Name](at.value) + nm_wma: ast.Name* = ast.Name*(at.value) if nm_wma.id is not None: if self.Gen.ExprGenCdef._is_cdefine_name_pattern(at.attr) != 0: err_buf_wma: str = pool.alloc(256) @@ -1265,9 +1209,8 @@ class ExprGenAttr(ExprGenBase.ExprGenBase): VLogger.error(err_buf_wma, "CD") return None # 使用 i8* 作为类型提示 (模块级变量通常存储指针) - i8_ptr_w: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, llvmlite.Int8(pool)) - wma_ref: rawptr[llvmlite.Value] = self._resolve_module_attribute_global( - pool, mod, trans, at, i8_ptr_w) + i8_ptr_w: llvmlite.LLVMType* = llvmlite.Ptr(pool, llvmlite.Int8(pool)) + wma_ref: llvmlite.Value* = self._resolve_module_attribute_global(pool, mod, trans, at, i8_ptr_w) if wma_ref is not None: return wma_ref @@ -1275,8 +1218,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: rawptr[llvmlite.Value] = self._get_cderef_attr_base( - builder, pool, mod, at.value, trans) + cd_base_wr: 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 elif at.value.kind() == ast.ASTKind.Subscript: @@ -1308,8 +1250,7 @@ class ExprGenAttr(ExprGenBase.ExprGenBase): # 确保跨模块结构体的完整定义在当前模块中可用(供 getelementptr 访问字段) # 与 translate_attribute 一致,避免 opaque 类型导致 GEP 报错 self.Gen.StructGen.ensure_struct_def_in_module(pool, mod, struct_ty) - field_info: rawptr[GenTypes.FieldEntry] = self.Gen.StructGen.lookup_field( - struct_ty, at.attr) + field_info: GenTypes.FieldEntry* = self.Gen.StructGen.lookup_field(struct_ty, at.attr) # 按需过滤: struct_ty 为 i8(简化联合类型)时,通过 AnnotClassName 按类名查找 # 传递 SHA1 以区分跨模块同名类 # base 注解类名提取:Name → 变量注解类名;Attribute → 属性链递归字段注解类名 @@ -1317,63 +1258,54 @@ class ExprGenAttr(ExprGenBase.ExprGenBase): if field_info is None: base_class: str = None if at.value.kind() == ast.ASTKind.Name and trans is not None: - nm_fb: rawptr[ast.Name] = rawptr[ast.Name](at.value) + nm_fb: ast.Name* = ast.Name*(at.value) if nm_fb.id is not None: - var_entry: rawptr[GenTypes.VarEntry] = self.Gen.VarGen.lookup_var_entry( - trans.SymTab, nm_fb.id) + var_entry: 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) elif at.value.kind() == ast.ASTKind.Attribute: - base_class = self._resolve_attr_field_class(pool, trans, at.value) + # allow_module_global=1:同 translate_attribute(基座可为 + # 「模块名.全局变量」,如 GenApi._g_gen.TypeGenCDef) + base_class = self._resolve_attr_field_class(pool, trans, at.value, 1) if base_class is not None: cur_sha1: str = None lfi_gp: str = None if trans is not None: cur_sha1 = trans.ModuleSha1 lfi_gp = trans._from_imports - field_info = self.Gen.StructGen.lookup_field_by_class( - base_class, at.attr, cur_sha1, at, lfi_gp) + field_info = self.Gen.StructGen.lookup_field_by_class(base_class, at.attr, cur_sha1, at, lfi_gp) # REnum 变体字段别名回退(同 translate_attribute L5046-5062): # get_attribute_ptr 赋值路径的按需过滤同样需要——struct_ty 简化 # i8 时主路径 REnum 别名查找被跳过(LLVMType.Pointee 报错根因) - if field_info is None \ - and self.Gen.ClassGenEnum._is_renum_class_name(base_class) != 0: - rn_alias_g: int = self.Gen.ClassGenEnum._lookup_renum_field_alias( - base_class, at.attr) + if field_info is None and self.Gen.ClassGenEnum._is_renum_class_name(base_class) != 0: + rn_alias_g: int = self.Gen.ClassGenEnum._lookup_renum_field_alias(base_class, at.attr) if rn_alias_g >= 1: - rn_se_g: rawptr[GenTypes.StructEntry] = \ - self.Gen.StructGen.find_struct(base_class) + rn_se_g: GenTypes.StructEntry* = self.Gen.StructGen.find_struct(base_class) if rn_se_g is not None: - rn_fe_g: rawptr[GenTypes.FieldEntry] = \ - self.Gen.StructGen._get_field_entry(rn_se_g, rn_alias_g) + rn_fe_g: 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 # 按需过滤成功:bitcast obj_ptr 到 AnnotClassName 对应的结构体类型 # 原始 struct_ty 可能是 i8(X|t.CPtr 简化为 Ptr(i8)), # 需用实际结构体类型做 GEP,否则 GEP i8 失败 if field_info is not None: - annot_se: rawptr[GenTypes.StructEntry] = \ - self.Gen.StructGen.find_struct(base_class) + annot_se: 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: rawptr[llvmlite.Value] = \ - llvmlite.build_bitcast(builder, obj_ptr, annot_ptr_ty) + annot_ptr_ty: llvmlite.LLVMType* = llvmlite.Ptr(pool, annot_se.Ty) + casted_ptr: llvmlite.Value* = llvmlite.build_bitcast(builder, obj_ptr, annot_ptr_ty) if casted_ptr is not None: obj_ptr = casted_ptr struct_ty = annot_se.Ty # 按需过滤更新 struct_ty 后,需重新确保 # 注解类型结构体定义在当前模块可用 - self.Gen.StructGen.ensure_struct_def_in_module( - pool, mod, annot_se.Ty) + self.Gen.StructGen.ensure_struct_def_in_module(pool, mod, annot_se.Ty) if field_info is not None: # 联合体:bitcast obj_ptr 到 field_ty*(字段指针用于 store) if self.Gen.StructGen.is_union_by_type(struct_ty) == 1: - field_ptr_ty: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, field_info.Ty) + field_ptr_ty: llvmlite.LLVMType* = llvmlite.Ptr(pool, field_info.Ty) return llvmlite.build_bitcast(builder, obj_ptr, field_ptr_ty) # 普通结构体:GEP 获取字段指针 - return llvmlite.build_gep_struct( - builder, struct_ty, field_info.Ty, obj_ptr, field_info.Index) + return llvmlite.build_gep_struct(builder, struct_ty, field_info.Ty, obj_ptr, field_info.Index) # 字段未找到:可能是 Phase A 依赖未就绪(定义侧模块未编译,vpi # stub 空类 FieldCount=0,如 SECURITY_ATTRIBUTES)→ 走下方真实报错 # (lookup_field_by_class 已对空 stub 返回 None 而非 fatal)。 @@ -1381,11 +1313,10 @@ class ExprGenAttr(ExprGenBase.ExprGenBase): diag_annot_g: str = None diag_var_nm_g: str = None if at.value is not None and at.value.kind() == ast.ASTKind.Name: - dnm_g: rawptr[ast.Name] = rawptr[ast.Name](at.value) + dnm_g: ast.Name* = ast.Name*(at.value) diag_var_nm_g = dnm_g.id if dnm_g.id is not None: - dve_g: rawptr[GenTypes.VarEntry] = self.Gen.VarGen.lookup_var_entry( - trans.SymTab, dnm_g.id) + dve_g: 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) diag_var_txt_g: str = "?" @@ -1394,13 +1325,17 @@ class ExprGenAttr(ExprGenBase.ExprGenBase): diag_annot_txt_g: str = "None" if diag_annot_g is not None: diag_annot_txt_g = diag_annot_g + # 接收者链路径(同 translate_attribute 的读取侧补全):`var=?` + # 说明接收者不是本模块变量,补出完整拼写形态(Mod.g.F[.F])。 + diag_base_txt_g: str = "?" + if at.value is not None: + dbg_bp_g: str = self._attr_module_path_str(pool, at.value) + if dbg_bp_g is not None: + diag_base_txt_g = dbg_bp_g sha1_attr_g: str = "?" if trans.ModuleSha1 is not None: sha1_attr_g = trans.ModuleSha1 - self.Gen.TypeGenErr.fatal_error( - at, - f"属性写入失败: .{at.attr} (var={diag_var_txt_g} annot={diag_annot_txt_g} sha1={sha1_attr_g})", - "TypeError") + self.Gen.TypeGenErr.fatal_error(at, f"属性写入失败: .{at.attr} (var={diag_var_txt_g} annot={diag_annot_txt_g} base={diag_base_txt_g} sha1={sha1_attr_g})", "TypeError") return None case _: # fast-fail: 对非指针类型做属性写入(如 i32.x = ...), @@ -1414,9 +1349,6 @@ class ExprGenAttr(ExprGenBase.ExprGenBase): ln_gp: int = 0 if at is not None and at.lineno is not None: ln_gp = at.lineno - self.Gen.TypeGenErr.fatal_error( - at, - f"属性写入失败: .{attr_nm_gp} (base=非指针类型,无法做属性写入 sha1={sha1_gp}:{ln_gp})", - "TypeError") + self.Gen.TypeGenErr.fatal_error(at, f"属性写入失败: .{attr_nm_gp} (base=非指针类型,无法做属性写入 sha1={sha1_gp}:{ln_gp})", "TypeError") # fatal_error 后补显式 return 样板:match 末 arm 块必须 terminated return None \ No newline at end of file diff --git a/App/lib/core/Gen/Expr/ExprGenBase.vp b/App/lib/core/Gen/Expr/ExprGenBase.vp index 8c6df85..5ac98c3 100644 --- a/App/lib/core/Gen/Expr/ExprGenBase.vp +++ b/App/lib/core/Gen/Expr/ExprGenBase.vp @@ -23,7 +23,7 @@ class ExprGenBase: """表达式基础工具(类型判断/指针层级/coerce)""" # --- docstring 登记表字段(__doc__ 魔法属性支持)--- - Gen: rawptr[Generator.Generator] + Gen: Generator.Generator* DocKeys: bytes DocValues: bytes DocCount: int @@ -42,22 +42,22 @@ class ExprGenBase: # ============================================================ # 从 AST 节点提取函数名 # ============================================================ - def get_func_name(self, func_node: rawptr[ast.AST]) -> str: + def get_func_name(self, func_node: ast.AST*) -> str: """从函数节点提取函数名""" if func_node is None: return None k: int = func_node.kind() if k == ast.ASTKind.Name: - nm: rawptr[ast.Name] = rawptr[ast.Name](func_node) + nm: ast.Name* = ast.Name*(func_node) return nm.id elif k == ast.ASTKind.Attribute: - at: rawptr[ast.Attribute] = rawptr[ast.Attribute](func_node) + at: ast.Attribute* = ast.Attribute*(func_node) return at.attr return None # ============================================================ # 转义 LLVM IR 字符串字面量 # ============================================================ - def escape_llvm_string(self, pool: rawptr[memhub.MemBuddy], + def escape_llvm_string(self, pool: memhub.MemBuddy*, src: str) -> str: """将字符串转换为 LLVM IR 字符串字面量 c"...\\00" """ if src is None: @@ -106,13 +106,13 @@ class ExprGenBase: # 同样委托到它)。两份副本一旦分叉,会出现「同一类型在两处算出不同位宽」的 # 隐蔽不一致。私有调用点(self.get_llvm_type_bits)保持原样不受影响。 # ============================================================ - def get_llvm_type_bits(self, ty: rawptr[llvmlite.LLVMType]) -> int: + def get_llvm_type_bits(self, ty: llvmlite.LLVMType*) -> int: """获取 LLVM 整数类型的位宽,非整数类型返回 0(委托 SpecTypeBits)""" return TSpec.SpecTypeBits(ty) # ============================================================ # 获取 LLVM 浮点类型的位宽 # ============================================================ - def get_llvm_float_bits(self, ty: rawptr[llvmlite.LLVMType]) -> int: + def get_llvm_float_bits(self, ty: llvmlite.LLVMType*) -> int: """获取 LLVM 浮点类型的位宽,非浮点类型返回 0""" if ty is None: return 0 @@ -126,7 +126,7 @@ class ExprGenBase: # # 返回 1=是, 0=否。作为类型检查工具函数被广泛使用(50+ 处调用)。 # ============================================================ - def is_ptr_type(self, ty: rawptr[llvmlite.LLVMType]) -> int: + def is_ptr_type(self, ty: llvmlite.LLVMType*) -> int: """检查 ty 是否是 Ptr 类型,返回 1=是, 0=否""" if ty is None: return 0 @@ -150,7 +150,7 @@ class ExprGenBase: # - 数值(0) vs 指针(1+) → 禁止(fast-fail) # - 不同级指针(1 vs 2) → 禁止(fast-fail) # ============================================================ - def get_ptr_level(self, ty: rawptr[llvmlite.LLVMType]) -> int: + def get_ptr_level(self, ty: llvmlite.LLVMType*) -> int: """计算指针层级,0=非指针, 1=一级指针, 2=二级指针... [S3 切读·指针层级块] 实现已收拢到 `TSpec.SpecTypePtrLevel` @@ -164,13 +164,13 @@ class ExprGenBase: # 用于指针判空比较(ptr != 0 / ptr == 0):指针与字面量 0 比较时 # 0 视为 NULL,允许并转成 null 指针(比较类型检查的例外)。 # ============================================================ - def _is_zero_int_literal(self, node: rawptr[ast.AST]) -> int: + def _is_zero_int_literal(self, node: ast.AST*) -> int: """判断节点是否为整数字面量 0,返回 1=是 / 0=否""" if node is None: return 0 if node.kind() != ast.ASTKind.Constant: return 0 - cn: rawptr[ast.Constant] = rawptr[ast.Constant](node) + cn: ast.Constant* = ast.Constant*(node) if cn is None or cn.const_kind != ast.CONST_INT: return 0 if cn.int_val == 0: @@ -181,7 +181,7 @@ class ExprGenBase: # # 返回 1=是, 0=否。类型检查工具函数。 # ============================================================ - def is_array_type(self, ty: rawptr[llvmlite.LLVMType]) -> int: + def is_array_type(self, ty: llvmlite.LLVMType*) -> int: """检查 ty 是否是 Array 类型,返回 1=是, 0=否""" if ty is None: return 0 @@ -198,14 +198,14 @@ class ExprGenBase: # 数组下标语义为非负,<32 位整数索引一律 zext 到 i32。 # 仅用于数组 GEP;指针负偏移(p[-1])不经过此路径,不受影响。 # ============================================================ - def _zext_index_to_i32(self, builder: rawptr[llvmlite.IRBuilder], - idx_val: rawptr[llvmlite.Value]) -> rawptr[llvmlite.Value]: + def _zext_index_to_i32(self, builder: llvmlite.IRBuilder*, + idx_val: llvmlite.Value*) -> llvmlite.Value*: """将 <32 位整数下标零扩展到 i32(数组下标非负语义)""" if idx_val is None or idx_val.Ty is None or builder is None: return idx_val idx_bits: int = self.get_llvm_type_bits(idx_val.Ty) if idx_bits != 0 and idx_bits < 32: - i32_ty: rawptr[llvmlite.LLVMType] = llvmlite.Int32(builder.Pool) + i32_ty: llvmlite.LLVMType* = llvmlite.Int32(builder.Pool) return llvmlite.build_zext(builder, idx_val, i32_ty) return idx_val # ============================================================ @@ -218,8 +218,8 @@ class ExprGenBase: # 返回类名字符串或 None。用于 subscript 操作中判断是否需要 # 转发到 __getitem__/__setitem__ 而非生成 GEP。 # ============================================================ - def _get_custom_struct_cls_nm(self, pool: rawptr[memhub.MemBuddy], - ty: rawptr[llvmlite.LLVMType]) -> str: + def _get_custom_struct_cls_nm(self, pool: memhub.MemBuddy*, + ty: llvmlite.LLVMType*) -> str: """检查 ty 或 ty 的 pointee 是否是已注册的自定义结构体,返回类名或 None""" if ty is None: return None @@ -229,7 +229,7 @@ class ExprGenBase: return cls_nm_direct # 如果 ty 是 Ptr,检查 pointee if self.is_ptr_type(ty) != 0: - pointee_cs: rawptr[llvmlite.LLVMType] = ty.Pointee + pointee_cs: llvmlite.LLVMType* = ty.Pointee if pointee_cs is not None: return self.Gen.StructGen.get_class_name_by_type(pool, pointee_cs) return None @@ -241,24 +241,24 @@ class ExprGenBase: # - 普通结构体指针数组(如 pts: Point | t.CPtr):get_subscript_ptr 返回元素地址 # 路由错误会让 list[T] 被当作结构体数组 GEP,访问错位崩溃。 # ============================================================ - def _is_list_subscript_base(self, pool: rawptr[memhub.MemBuddy], - trans: rawptr[HT.Translator], - sub_node: rawptr[ast.AST]) -> int: + def _is_list_subscript_base(self, pool: memhub.MemBuddy*, + trans: HT.Translator*, + sub_node: ast.AST*) -> int: """判断下标基座是否为 list[T] 变量(1=是)""" if sub_node is None or trans is None: return 0 - sub: rawptr[ast.Subscript] = rawptr[ast.Subscript](sub_node) + sub: ast.Subscript* = ast.Subscript*(sub_node) if sub is None or sub.value is None or sub.value.kind() != ast.ASTKind.Name: return 0 - nm: rawptr[ast.Name] = rawptr[ast.Name](sub.value) + nm: ast.Name* = ast.Name*(sub.value) if nm.id is None: return 0 - alloca: rawptr[llvmlite.Value] = self.Gen.VarGen.lookup_var(trans.SymTab, nm.id) + alloca: 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: return 0 - pointee: rawptr[llvmlite.LLVMType] = alloca.Ty.Pointee + pointee: llvmlite.LLVMType* = alloca.Ty.Pointee if pointee is None: return 0 match pointee: @@ -277,28 +277,28 @@ class ExprGenBase: # ============================================================ # _sub_base_class_name - 解析下标基座变量的结构体类名 # ============================================================ - def _sub_base_class_name(self, pool: rawptr[memhub.MemBuddy], - trans: rawptr[HT.Translator], - sub_node: rawptr[ast.AST]) -> str: + def _sub_base_class_name(self, pool: memhub.MemBuddy*, + trans: HT.Translator*, + sub_node: ast.AST*) -> str: """解析下标基座变量的结构体类名(无则 None)""" if sub_node is None or trans is None: return None - sub: rawptr[ast.Subscript] = rawptr[ast.Subscript](sub_node) + sub: ast.Subscript* = ast.Subscript*(sub_node) if sub is None or sub.value is None or sub.value.kind() != ast.ASTKind.Name: return None - nm: rawptr[ast.Name] = rawptr[ast.Name](sub.value) + nm: ast.Name* = ast.Name*(sub.value) if nm.id is None: return None - alloca: rawptr[llvmlite.Value] = self.Gen.VarGen.lookup_var(trans.SymTab, nm.id) + alloca: 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: return None - pointee: rawptr[llvmlite.LLVMType] = alloca.Ty.Pointee + pointee: llvmlite.LLVMType* = alloca.Ty.Pointee if pointee is None: return None if self.is_ptr_type(pointee) != 0: - inner: rawptr[llvmlite.LLVMType] = pointee.Pointee + inner: llvmlite.LLVMType* = pointee.Pointee if inner is not None: return self.Gen.StructGen.get_class_name_by_type(pool, inner) return self.Gen.StructGen.get_class_name_by_type(pool, pointee) @@ -311,10 +311,10 @@ class ExprGenBase: # - 普通结构体指针数组(如 pts: Point | t.CPtr)→ get_subscript_ptr # (GEP 元素地址,避免结构体值 base=非指针 报错) # ============================================================ - def _sub_base_uses_getitem(self, pool: rawptr[memhub.MemBuddy], - mod: rawptr[llvmlite.LLVMModule], - trans: rawptr[HT.Translator], - sub_node: rawptr[ast.AST]) -> int: + def _sub_base_uses_getitem(self, pool: memhub.MemBuddy*, + mod: llvmlite.LLVMModule*, + trans: HT.Translator*, + sub_node: ast.AST*) -> int: """下标基座应走 __getitem__ 语义时返回 1,否则 0(应走 GEP 地址语义)""" if self._is_list_subscript_base(pool, trans, sub_node) != 0: return 1 @@ -335,31 +335,31 @@ class ExprGenBase: # - 值类型变量 (cnt: Counter): alloca 类型是 Ptr(Struct) → 不解引用 # - 指针类型变量 (r: Vec2|t.CPtr): alloca 类型是 Ptr(Ptr(Struct)) → load 解引用 # ============================================================ - def _deref_if_ptr_ptr(self, builder: rawptr[llvmlite.IRBuilder], - obj_ptr: rawptr[llvmlite.Value]) -> rawptr[llvmlite.Value]: + def _deref_if_ptr_ptr(self, builder: llvmlite.IRBuilder*, + obj_ptr: llvmlite.Value*) -> llvmlite.Value*: """如果 obj_ptr 是 Ptr(Ptr(...)),load 解引用获取内层指针""" if obj_ptr is None or obj_ptr.Ty is None: return obj_ptr if self.is_ptr_type(obj_ptr.Ty) == 0: return obj_ptr - pointee: rawptr[llvmlite.LLVMType] = obj_ptr.Ty.Pointee + pointee: llvmlite.LLVMType* = obj_ptr.Ty.Pointee if pointee is None: return obj_ptr if self.is_ptr_type(pointee) == 0: return obj_ptr # obj_ptr 是 Ptr(Ptr(...)),load 解引用 - loaded: rawptr[llvmlite.Value] = llvmlite.build_load(builder, pointee, obj_ptr) + loaded: 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: rawptr[llvmlite.IRBuilder], - val: rawptr[llvmlite.Value], - target_ty: rawptr[llvmlite.LLVMType], - node: rawptr[ast.AST] = None, - trans: rawptr[HT.Translator] = None) -> rawptr[llvmlite.Value]: + def coerce_to_type(self, builder: llvmlite.IRBuilder*, + val: llvmlite.Value*, + target_ty: llvmlite.LLVMType*, + node: ast.AST* = None, + trans: HT.Translator* = None) -> 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: rawptr[llvmlite.Value] = self.Gen.VarGen._alloca_at_entry( + tmp_agg: 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: rawptr[llvmlite.Value] = llvmlite.build_bitcast( + bc_agg: llvmlite.Value* = llvmlite.build_bitcast( builder, tmp_agg, target_ty) if bc_agg is not None: return bc_agg @@ -489,10 +489,10 @@ class ExprGenBase: return llvmlite.build_bitcast(builder, val, target_ty) return val - def _zext_or_sext_val(self, pool: rawptr[memhub.MemBuddy], - val: rawptr[llvmlite.Value], - node: rawptr[ast.AST] = None, - trans: rawptr[HT.Translator] = None) -> int: + def _zext_or_sext_val(self, pool: memhub.MemBuddy*, + val: llvmlite.Value*, + node: ast.AST* = None, + trans: HT.Translator* = None) -> int: """统一整数拓宽方向:1=zext(无符号语义),0=sext 委托到 ExprGenOps.should_zext_widen(拓宽方向的**单一真源**),避免两套 @@ -509,16 +509,16 @@ class ExprGenBase: return self.Gen.ExprGenOps.should_zext_widen(pool, val, None, node, trans) # translate_ptr_arith:指针算术 ptr±int,用 getelementptr(按 pointee 元素大小缩放索引,对齐 TPC ExprGen.emit_binary_op / HandlesAugAssign.py);数组 pointee([N x ty]*)先 decay 为元素指针(GEP 0,0),避免以整个数组为步长 - def translate_ptr_arith(self, pool: rawptr[memhub.MemBuddy], - builder: rawptr[llvmlite.IRBuilder], - ptr_val: rawptr[llvmlite.Value], - int_val: rawptr[llvmlite.Value], - op: int) -> rawptr[llvmlite.Value]: + def translate_ptr_arith(self, pool: memhub.MemBuddy*, + builder: llvmlite.IRBuilder*, + ptr_val: llvmlite.Value*, + int_val: llvmlite.Value*, + op: int) -> 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 # 提取 pointee 类型(非指针 → 不处理返回 None) - elem_ty: rawptr[llvmlite.LLVMType] = None + elem_ty: llvmlite.LLVMType* = None match ptr_val.Ty: case llvmlite.LLVMType.Ptr(pointee): elem_ty = pointee @@ -527,20 +527,20 @@ class ExprGenBase: if elem_ty is None: return None # 索引统一到 i64(对齐 TPC zext 到 i64) - i64_ty: rawptr[llvmlite.LLVMType] = llvmlite.Int64(pool) - idx: rawptr[llvmlite.Value] = self.coerce_to_type(builder, int_val, i64_ty, None) + i64_ty: llvmlite.LLVMType* = llvmlite.Int64(pool) + idx: 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: rawptr[llvmlite.Value] = llvmlite.build_sub( + neg_idx: llvmlite.Value* = llvmlite.build_sub( builder, llvmlite.const_int64(pool, 0), idx) if neg_idx is None: return None idx = neg_idx # 数组 pointee → 先 decay 为元素指针(getelementptr [N x ty], [N x ty]* %p, i32 0, i32 0) if self.is_array_type(elem_ty) != 0: - inner_ty: rawptr[llvmlite.LLVMType] = None + inner_ty: llvmlite.LLVMType* = None match elem_ty: case llvmlite.LLVMType.Array(inner, _): inner_ty = inner @@ -548,7 +548,7 @@ class ExprGenBase: return None if inner_ty is None: return None - decayed: rawptr[llvmlite.Value] = llvmlite.build_gep_array( + decayed: llvmlite.Value* = llvmlite.build_gep_array( builder, elem_ty, inner_ty, ptr_val, llvmlite.const_int64(pool, 0)) if decayed is None: return None diff --git a/App/lib/core/Gen/Expr/ExprGenCdef.vp b/App/lib/core/Gen/Expr/ExprGenCdef.vp index 5896026..6ca4087 100644 --- a/App/lib/core/Gen/Expr/ExprGenCdef.vp +++ b/App/lib/core/Gen/Expr/ExprGenCdef.vp @@ -125,12 +125,12 @@ class ExprGenCdef(ExprGenBase.ExprGenBase): # # pyi 文件格式: "NAME: t.CDefine = value" # ============================================================ - def _lookup_cross_module_cdefine(self, pool: rawptr[memhub.MemBuddy], + def _lookup_cross_module_cdefine(self, pool: memhub.MemBuddy*, name: str, from_imports: str, imported_modules: str = None, depth: int = 0, - node: rawptr[ast.AST] = None) -> int64: + node: ast.AST* = None) -> int64: """跨模块查找 CDefine 常量,返回值(64 位)或 -1(未找到) 查找顺序: @@ -1069,10 +1069,24 @@ class ExprGenCdef(ExprGenBase.ExprGenBase): # ============================================================ # 翻译变量引用(Name 节点)→ load # ============================================================ - def _const_int_for_cdefine(self, pool: rawptr[memhub.MemBuddy], - value: int64) -> rawptr[llvmlite.Value]: + def _const_int_for_cdefine(self, pool: memhub.MemBuddy*, + value: int64) -> llvmlite.Value*: """CDefine 整数常量 → LLVM 常量(对齐 TPC TypeConvert 的 64 位升级) + **使用处宽度("W_min + 使用处宽度"规则)与物化宽度的关系**(与 TPC 同口径, + 对照表见 Debugger/define-constants.md): + · 本函数是"取不到使用处宽度"的物化点(调用方 ExprGenName/ExprGenAttr 只有 + 常量名与值,没有目标类型)⇒ 按语言默认整型宽度物化:能落进 32 位 ⇒ i32, + 否则 i64。**不**降到 W_min——降到 i8/i16 会把窄立即数喂进 i32 上下文与 + C 默认实参提升(printf 变参),属静默降级/ABI 破坏。 + · "使用处更宽 ⇒ 以该宽度物化"由**消费端**实现:translate_binop 按较宽侧 + zext/sext/coerce_to_type 对齐,赋值/形参按目标存储类型 coerce。 + · "使用处更窄 ⇒ fail-fast"在**注册处与声明处**实现: + AssignGenMixin.require_cdefine_storable(显式类型 T 的位宽)与 + require_cdefine_use_width(`a: T = C`);超 64 位字面量由 + _int_text_exceeds_64 以**源码文本**判定(lexer 的 atoll 会在字面量层 + 回绕,回绕后的 int64 不可信,故本函数不承担溢出判定)。 + 规则(与 translate_constant 的 i32 溢出升级一致,但保留 0xFFFFFFFF 语义): 值超 32 位无符号范围(> 0xFFFFFFFF)→ i64 全精度常量 (如 sys.maxsize = 9223372036854775807); @@ -1100,4 +1114,90 @@ class ExprGenCdef(ExprGenBase.ExprGenBase): """ if (value >= 0 and uint64(uint32(value)) != value) or value < -2147483648: return llvmlite.const_int64(pool, value) - return llvmlite.const_int32(pool, int(value)) \ No newline at end of file + return llvmlite.const_int32(pool, int(value)) + + # ============================================================ + # cdefine_use_width_value - "使用处宽度"下的 CDefine 常量物化 + # (与 TPC HandlesExpr._HandleNameLlvm + ConstWidthHint 同口径) + # ============================================================ + def _cdefine_bits_value(self, value: int64, bits: int) -> int64: + """把 CDefine 值归一到 bits 位的**有符号表示**(LLVM 整数字面量口径)。 + + 前提:调用方已用 W_min 判据保证 value 落在 + [-(2^(bits-1)), 2^bits-1](两解释口径)。非负但最高位为 1 的值 + (如 0xFFFFFFFF)转成同一位模式的负数(i32 4294967295 → i32 -1), + 与 _const_int_for_cdefine 既有的 i32 截断口径一致,避免生成非法 IR 文本。 + """ + if bits == 8: + if value > 127: + return value - 256 + return value + if bits == 16: + if value > 32767: + return value - 65536 + return value + if bits == 32: + if value > 2147483647: + return value - 4294967296 + return value + return value + + def cdefine_use_width_value(self, pool: memhub.MemBuddy*, + node: ast.AST*, name: str, + value: int64, + target_ty: llvmlite.LLVMType*, + use_ctx: str = None) -> llvmlite.Value*: + """CDefine 整数常量在**已知使用处类型**时的物化(与 TPC 同口径)。 + + 返回 None ⇒ "取不到使用处宽度"(调用方沿用 _const_int_for_cdefine 的 + 语言默认整型宽度 32/64)。只当 target_ty 是 i8/i16/i32/i64 时启用 + (i1 是比较/逻辑结果、指针不是整数使用处 ⇒ 落回默认,否则 `C == 0` + 之类会拿到位宽 1 而误报"使用处宽度不足"): + 使用处更宽(bits >= W_min)⇒ 按 bits 就地物化(立即数升宽无损); + 使用处更窄(bits < W_min)⇒ fail-fast(替换静默截断)。 + 只被 CDefine 整数物化点调用 ⇒ 不改变非常量实参/返回值的既有 IR。 + + use_ctx:**真实站点种类**标签(如 "局部变量注解" / "模块级全局" / "形参" / + "返回注解"),由 `translate_value` 的调用方按站点下传;None ⇒ 报文不写 + 括注(**不得**再写死"形参 / 返回类型"——AnnAssign 的 `a: T = C` 现场也被 + 本函数拦到时,硬编码标签会给出错误站点)。 + """ + bits: int = self.Gen.ExprGenBase.get_llvm_type_bits(target_ty) + if bits != 8 and bits != 16 and bits != 32 and bits != 64: + return None + wmin: int = self.Gen.AssignGen.define_min_width(value) + if bits < wmin: + # "该使用处可表示的范围"与判据同一口径 = TPC `DefineWidthLoHi` + # = [-(2^(bits-1)), 2^bits - 1](有符号/无符号两种解释的并集; + # 判据本身只按**位宽**比较,故报文必须报"位宽 w 的可接受值域")。 + # 字面量纪律见 AssignGenMixin.define_min_width:2147483648 / + # 4294967295 会被 TPC 压成 i32 并在提升时 sext,故用安全字面量 + # 2147483647 的算术等价式构造。 + m31: int64 = 2147483647 + lo: int64 = -m31 - 1 + hi: int64 = m31 * 2 + 1 + if bits == 8: + lo = -128 + hi = 255 + elif bits == 16: + lo = -32768 + hi = 65535 + ctx: str = "" + if use_ctx is not None: + # 本语言的 str 是 i8*,**没有** `str + str` 的拼接语义(`+` 会退化 + # 成裸指针 add → "invalid operand type for instruction")。 + # 构建字符串一律用本仓库惯用法:f-string 插值 / string.strcat / + # viperlib.snprintf。 + ctx = f"({use_ctx})" + self.Gen.TypeGenErr.fatal_error( + node, + f"[TPV] define 常量使用处宽度不足: 常量 '{name}' 的实际值 {value} " + f"需要至少 {wmin} 位(最小可容纳宽度 W_min)," + f"但使用处{ctx}只提供 {bits} 位" + f"(该位宽按有符号/无符号两种解释可接受的范围: {lo}..{hi})。" + f"禁止静默截断/降级,已终止编译。" + f"修法: 把使用处{ctx}的类型加宽到至少 {wmin} 位" + f"(如 t.CInt{wmin}T / CUInt{wmin}T 及更宽类型),或改用更小的常量值。", + "TypeError") + return None + return llvmlite.const_int(pool, bits, self._cdefine_bits_value(value, bits)) \ No newline at end of file diff --git a/App/lib/core/Gen/Expr/ExprGenCls.vp b/App/lib/core/Gen/Expr/ExprGenCls.vp index e8afff5..48bf1c6 100644 --- a/App/lib/core/Gen/Expr/ExprGenCls.vp +++ b/App/lib/core/Gen/Expr/ExprGenCls.vp @@ -50,13 +50,13 @@ class ExprGenCls(ExprGenBase.ExprGenBase): """从函数/类体提取 docstring:body[0] 为 Expr(Constant str) 时返回内容""" if body is None or len(body) == 0: return None - first: rawptr[ast.AST] = body.get(0) + first: ast.AST* = body.get(0) if first is None or first.kind() != ast.ASTKind.Expr: return None 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) + cn: ast.Constant* = ast.Constant*(ex.value) if cn is None or cn.const_kind != ast.CONST_STR: return None return cn.str_val @@ -107,7 +107,7 @@ class ExprGenCls(ExprGenBase.ExprGenBase): return self.DocValues + i * DOC_VAL_SZ stdlib.free(key_buf) return None - def extract_module_docstrings(self, tree: rawptr[ast.AST], module_sha1: str) -> None: + def extract_module_docstrings(self, tree: ast.AST*, module_sha1: str) -> None: """扫描模块 AST:登记模块级函数/类/方法的 docstring(幂等)""" if tree is None or module_sha1 is None: return @@ -116,19 +116,19 @@ class ExprGenCls(ExprGenBase.ExprGenBase): return cn: sizet = len(ch) for ci in range(cn): - child: rawptr[ast.AST] = ch.get(ci) + child: ast.AST* = ch.get(ci) if child is None: continue kd: int = child.kind() if kd == ast.ASTKind.FunctionDef: - fd: rawptr[ast.FunctionDef] = rawptr[ast.FunctionDef](child) + fd: ast.FunctionDef* = ast.FunctionDef*(child) if fd is not None and fd.name is not None: fd_body: list[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) elif kd == ast.ASTKind.ClassDef: - cd: rawptr[ast.ClassDef] = rawptr[ast.ClassDef](child) + cd: ast.ClassDef* = ast.ClassDef*(child) if cd is None or cd.name is None: continue cd_body0: list[ast.AST*]* = cd.children @@ -140,10 +140,10 @@ class ExprGenCls(ExprGenBase.ExprGenBase): if cd_body is not None: cbn: sizet = len(cd_body) for mi in range(cbn): - m: rawptr[ast.AST] = cd_body.get(mi) + m: ast.AST* = cd_body.get(mi) if m is None or m.kind() != ast.ASTKind.FunctionDef: continue - mfd: rawptr[ast.FunctionDef] = rawptr[ast.FunctionDef](m) + mfd: ast.FunctionDef* = ast.FunctionDef*(m) if mfd is None or mfd.name is None: continue mdoc: str = self._extract_docstring_from_body(mfd.children) @@ -155,7 +155,7 @@ class ExprGenCls(ExprGenBase.ExprGenBase): viperlib.snprintf(sym_buf, cl_nl + mt_nl + 2, "%s.%s", cd.name, mfd.name) self.register_docstring(module_sha1, sym_buf, mdoc) stdlib.free(sym_buf) - def _resolve_doc_symbol_name(self, trans: rawptr[HT.Translator], name_id: str, + def _resolve_doc_symbol_name(self, trans: HT.Translator*, name_id: str, out_mod: str, out_sym: str) -> int: """解析 Name 符号的 docstring 归属,写入 out_mod/out_sym,成功返回 1 @@ -171,7 +171,7 @@ class ExprGenCls(ExprGenBase.ExprGenBase): string.strcpy(out_sym, name_id) return 1 # 2. 结构体类(entry.ModuleSha1 区分跨模块预注册的类) - se: rawptr[GenTypes.StructEntry] = self.Gen.StructGen.find_struct(name_id) + se: 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) @@ -192,8 +192,8 @@ class ExprGenCls(ExprGenBase.ExprGenBase): string.strcpy(out_mod, trans.ModuleSha1) string.strcpy(out_sym, name_id) return 1 - def _resolve_doc_symbol_attr(self, trans: rawptr[HT.Translator], - at: rawptr[ast.Attribute], + def _resolve_doc_symbol_attr(self, trans: HT.Translator*, + at: ast.Attribute*, out_mod: str, out_sym: str) -> int: """解析嵌套 Attribute 链的 docstring 归属,写入 out_mod/out_sym @@ -211,9 +211,9 @@ class ExprGenCls(ExprGenBase.ExprGenBase): if items is None: return 0 n_items: int = 0 - cur: rawptr[ast.AST] = (rawptr[ast.AST])(at) + cur: ast.AST* = (ast.AST*)(at) while cur is not None and cur.kind() == ast.ASTKind.Attribute and n_items < DOC_CHAIN_MAX: - cat: rawptr[ast.Attribute] = rawptr[ast.Attribute](cur) + cat: ast.Attribute* = ast.Attribute*(cur) if cat.attr is None: break string.strcpy(items + n_items * 128, cat.attr) @@ -222,7 +222,7 @@ class ExprGenCls(ExprGenBase.ExprGenBase): # 最左应为 Name head_id: str = None if cur is not None and cur.kind() == ast.ASTKind.Name: - hnm: rawptr[ast.Name] = rawptr[ast.Name](cur) + hnm: ast.Name* = ast.Name*(cur) head_id = hnm.id if head_id is None: stdlib.free(items) @@ -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: rawptr[GenTypes.StructEntry] = self.Gen.StructGen.find_struct(head_id) + se2: 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: @@ -299,21 +299,21 @@ class ExprGenCls(ExprGenBase.ExprGenBase): # Attribute → 字段注解类名(_resolve_attr_field_class) # 仅采用已注册结构体;无法精确推断返回 None(fail-fast 由调用方暴露)。 # ============================================================ - def infer_expr_class(self, pool: rawptr[memhub.MemBuddy], - mod: rawptr[llvmlite.LLVMModule], - node: rawptr[ast.AST], - trans: rawptr[HT.Translator]) -> str: + def infer_expr_class(self, pool: memhub.MemBuddy*, + mod: llvmlite.LLVMModule*, + node: ast.AST*, + trans: HT.Translator*) -> str: """从表达式推断结构体类名,无法推断返回 None""" if node is None or trans is None: return None k: int = node.kind() # Call: 类实例化 / 方法调用 if k == ast.ASTKind.Call: - cl: rawptr[ast.Call] = rawptr[ast.Call](node) + cl: ast.Call* = ast.Call*(node) if cl is None or cl.func is None: return None if cl.func.kind() == ast.ASTKind.Name: - cand: str = (rawptr[ast.Name](cl.func)).id + cand: str = (ast.Name*(cl.func)).id if cand is None: return None if self.Gen.StructGen.find_struct(cand) is not None: @@ -322,12 +322,12 @@ class ExprGenCls(ExprGenBase.ExprGenBase): if cl.func.kind() == ast.ASTKind.Attribute: # 方法调用 a.cross(b):vpi 返回注解缓存精确解析返回类名 # (方法可返回非同类对象,如 Transform.world_position → 'Vec3')。 - ca: rawptr[ast.Attribute] = rawptr[ast.Attribute](cl.func) + ca: ast.Attribute* = ast.Attribute*(cl.func) if ca is None or ca.attr is None or ca.value is None: return None # 模块级函数调用(Module.func()):接收者是已导入模块名而非类对象 if ca.value.kind() == ast.ASTKind.Name: - mod_nm2: str = (rawptr[ast.Name](ca.value)).id + mod_nm2: str = (ast.Name*(ca.value)).id if mod_nm2 is not None and trans._from_imports is not None: mod_sha1_2: str = self.Gen.CallGenBase._lookup_mod_sha1( pool, trans._from_imports, mod_nm2) @@ -367,10 +367,10 @@ class ExprGenCls(ExprGenBase.ExprGenBase): return None # Name: 源变量注解 if k == ast.ASTKind.Name: - nm: rawptr[ast.Name] = rawptr[ast.Name](node) + nm: ast.Name* = ast.Name*(node) if nm is None or nm.id is None: return None - ve: rawptr[GenTypes.VarEntry] = self.Gen.VarGen.lookup_var_entry( + ve: GenTypes.VarEntry* = self.Gen.VarGen.lookup_var_entry( trans.SymTab, nm.id) if ve is None: return None @@ -388,7 +388,7 @@ class ExprGenCls(ExprGenBase.ExprGenBase): return acn_n # BinOp/UnaryOp: 运算符重载返回同类对象 if k == ast.ASTKind.BinOp: - bop: rawptr[ast.BinOp] = rawptr[ast.BinOp](node) + bop: ast.BinOp* = ast.BinOp*(node) if bop is None or bop.left is None: return None dunder: str = self.Gen.ExprGenOps._binop_to_dunder(bop.op) @@ -399,7 +399,7 @@ class ExprGenCls(ExprGenBase.ExprGenBase): return None return lhs_cls if k == ast.ASTKind.UnaryOp: - uop: rawptr[ast.UnaryOp] = rawptr[ast.UnaryOp](node) + uop: ast.UnaryOp* = ast.UnaryOp*(node) if uop is None or uop.operand is None: return None dunder: str = self.Gen.ExprGenOps._unaryop_to_dunder(uop.op) @@ -420,8 +420,8 @@ class ExprGenCls(ExprGenBase.ExprGenBase): # SHA1(stub 中声明)即视为存在。仅在确实存在时采用推断类名, # 避免把原生运算误标为类类型。 # ============================================================ - def _cls_has_dunder(self, pool: rawptr[memhub.MemBuddy], - mod: rawptr[llvmlite.LLVMModule], + def _cls_has_dunder(self, pool: memhub.MemBuddy*, + mod: llvmlite.LLVMModule*, class_name: str, dunder: str) -> int: """类及其 MRO 祖先链中是否存在 dunder 方法,存在返回 1""" if class_name is None or dunder is None or mod is None: @@ -433,7 +433,7 @@ class ExprGenCls(ExprGenBase.ExprGenBase): if self.Gen.CallGenBase.find_func_in_module(mod, lookup_name) is not None: return 1 # 继承链祖先查找 - mro_ptr: sizet | t.CPtr = self.Gen.StructGen.get_mro_chain(pool, class_name) + mro_ptr: sizet* = self.Gen.StructGen.get_mro_chain(pool, class_name) mi: int = 1 while mro_ptr is not None and mro_ptr[mi] != 0: anc: str = (str | t.CPtr)(mro_ptr[mi]) @@ -456,7 +456,7 @@ class ExprGenCls(ExprGenBase.ExprGenBase): # CFloat64T/t.CPtr 等均不注册 struct,天然过滤)。"A | B" 联合 # 多候选时取首个命中段。 # ============================================================ - def _extract_annot_class_name(self, pool: rawptr[memhub.MemBuddy], + def _extract_annot_class_name(self, pool: memhub.MemBuddy*, annot: str) -> str: """从返回注解文本提取已注册结构体类名,无命中返回 None""" if pool is None or annot is None: diff --git a/App/lib/core/Gen/Expr/ExprGenConst.vp b/App/lib/core/Gen/Expr/ExprGenConst.vp index 12c9c99..b4ed314 100644 --- a/App/lib/core/Gen/Expr/ExprGenConst.vp +++ b/App/lib/core/Gen/Expr/ExprGenConst.vp @@ -27,11 +27,11 @@ class ExprGenConst(ExprGenBase.ExprGenBase): # ============================================================ # 创建全局字符串常量 # ============================================================ - def create_global_string(self, builder: rawptr[llvmlite.IRBuilder], - pool: rawptr[memhub.MemBuddy], - mod: rawptr[llvmlite.LLVMModule], + def create_global_string(self, builder: llvmlite.IRBuilder*, + pool: memhub.MemBuddy*, + mod: llvmlite.LLVMModule*, str_val: str, - trans: rawptr[HT.Translator]) -> rawptr[llvmlite.Value]: + trans: HT.Translator*) -> llvmlite.Value*: """创建全局字符串常量并返回 i8* bitcast""" escaped: str = self.escape_llvm_string(pool, str_val) if escaped is None: @@ -40,8 +40,8 @@ class ExprGenConst(ExprGenBase.ExprGenBase): slen: sizet = string.strlen(str_val) count: int = slen + 1 - i8_ty: rawptr[llvmlite.LLVMType] = llvmlite.Int8(pool) - arr_ty: rawptr[llvmlite.LLVMType] = llvmlite.Array(pool, i8_ty, count) + i8_ty: llvmlite.LLVMType* = llvmlite.Int8(pool) + arr_ty: llvmlite.LLVMType* = llvmlite.Array(pool, i8_ty, count) # 使用模块级计数器(trans._label_counter)避免跨函数命名冲突 str_idx: int = trans._label_counter @@ -56,7 +56,7 @@ class ExprGenConst(ExprGenBase.ExprGenBase): else: viperlib.snprintf(gv_name, 48, ".str.%d", str_idx) - gv: rawptr[llvmlite.GlobalVariable] = llvmlite.new_global_variable(pool, gv_name, arr_ty) + gv: llvmlite.GlobalVariable* = llvmlite.new_global_variable(pool, gv_name, arr_ty) if gv is None: return None llvmlite.module_add_global(mod, gv) @@ -68,28 +68,28 @@ class ExprGenConst(ExprGenBase.ExprGenBase): gv.Linkage = "internal" gv.Initializer = escaped - arr_ptr_ty: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, arr_ty) + arr_ptr_ty: llvmlite.LLVMType* = llvmlite.Ptr(pool, arr_ty) gv_ref_name: str = pool.alloc(64) if gv_ref_name is None: return None viperlib.snprintf(gv_ref_name, 64, "@%s", gv.Name) - gv_ref: rawptr[llvmlite.Value] = llvmlite.SSAValue(pool, arr_ptr_ty, gv_ref_name) + gv_ref: llvmlite.Value* = llvmlite.SSAValue(pool, arr_ptr_ty, gv_ref_name) - i8_ptr_ty: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, i8_ty) + i8_ptr_ty: llvmlite.LLVMType* = llvmlite.Ptr(pool, i8_ty) - bc: rawptr[llvmlite.Value] = llvmlite.build_bitcast(builder, gv_ref, i8_ptr_ty) + bc: llvmlite.Value* = llvmlite.build_bitcast(builder, gv_ref, i8_ptr_ty) return bc # ============================================================ # 翻译常量表达式 # ============================================================ - 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) -> rawptr[llvmlite.Value]: + def translate_constant(self, builder: llvmlite.IRBuilder*, + pool: memhub.MemBuddy*, + mod: llvmlite.LLVMModule*, + node: ast.AST*, + trans: HT.Translator* = None, + target_ty: llvmlite.LLVMType* = None) -> llvmlite.Value*: """翻译常量(int/str/bool)""" - cn: rawptr[ast.Constant] = rawptr[ast.Constant](node) + cn: ast.Constant* = ast.Constant*(node) if cn is None: return None ck: int = cn.const_kind @@ -110,7 +110,7 @@ class ExprGenConst(ExprGenBase.ExprGenBase): return llvmlite.const_int32(pool, iv) elif cn.const_kind == ast.CONST_FLOAT: # 浮点常量默认创建为 double(64 位),赋值时由 coerce_to_type 自动 fptrunc - double_ty: rawptr[llvmlite.LLVMType] = llvmlite.Double(pool) + double_ty: llvmlite.LLVMType* = llvmlite.Double(pool) return llvmlite.ConstFloat(pool, double_ty, cn.float_val) elif cn.const_kind == ast.CONST_CHAR: # 单引号单字符字面量(CONST_CHAR):默认按字符值(i32,coerce 截断为 i8);但当目标类型是指针(str/bytes/t.CPtr)时须物化为 1 字符字符串,否则 coerce inttoptr 把字符值当指针(如 '"'=0x22)→ 运行期 strlen 访问低地址崩溃。1a 阶段(declare_only=1)依赖函数 found_func=None,target_ty 未对齐即视为垃圾跳过,避免 is_ptr_type 解引用崩溃 @@ -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: rawptr[llvmlite.Value] = self.create_global_string(builder, pool, mod, cbuf, trans) + r_cs: 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: rawptr[llvmlite.Value] = self.create_global_string(builder, pool, mod, sv, trans) + r: 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: @@ -138,13 +138,13 @@ class ExprGenConst(ExprGenBase.ExprGenBase): return llvmlite.const_int32(pool, 0) elif cn.const_kind == ast.CONST_NONE: # None → i8* null(空指针常量),用于 `p is None` / `p is not None` 比较 - i8_ty: rawptr[llvmlite.LLVMType] = llvmlite.Int8(pool) + i8_ty: llvmlite.LLVMType* = llvmlite.Int8(pool) if i8_ty is None: return None - i8_ptr_ty: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, i8_ty) + i8_ptr_ty: llvmlite.LLVMType* = llvmlite.Ptr(pool, i8_ty) if i8_ptr_ty is None: return None - rv_none: rawptr[llvmlite.Value] = llvmlite.ConstNull(pool, i8_ptr_ty, "null") + rv_none: llvmlite.Value* = llvmlite.ConstNull(pool, i8_ptr_ty, "null") return rv_none return None # ============================================================ @@ -152,8 +152,8 @@ class ExprGenConst(ExprGenBase.ExprGenBase): # # 用于 list 字面量 [a, b, c] 的元素类型推断 # ============================================================ - def _infer_elem_type_from_value(self, pool: rawptr[memhub.MemBuddy], - value: rawptr[llvmlite.Value]) -> str: + def _infer_elem_type_from_value(self, pool: memhub.MemBuddy*, + value: llvmlite.Value*) -> str: """从 LLVM Value 的类型推断 list 元素类型名 fail-fast:值类型缺失/无法映射时返回 None(调用方携带节点报错终止), @@ -161,7 +161,7 @@ class ExprGenConst(ExprGenBase.ExprGenBase): """ if value is None or value.Ty is None: return None - ty: rawptr[llvmlite.LLVMType] = value.Ty + ty: llvmlite.LLVMType* = value.Ty bits: int = self.get_llvm_type_bits(ty) if bits != 0: if bits == 32: @@ -187,7 +187,7 @@ class ExprGenConst(ExprGenBase.ExprGenBase): # # 依次尝试 "pool", "_mbuddy", "mbuddy", "mb" # ============================================================ - def _find_pool_var(self, trans: rawptr[HT.Translator]) -> rawptr[llvmlite.Value]: + def _find_pool_var(self, trans: HT.Translator*) -> llvmlite.Value*: """查找上下文中的 pool 变量,返回 alloca 或 None 查找顺序: pool → _mbuddy → mbuddy → mb @@ -198,7 +198,7 @@ class ExprGenConst(ExprGenBase.ExprGenBase): """ if trans is None: return None - alloca: rawptr[llvmlite.Value] = self.Gen.VarGen.lookup_var(trans.SymTab, "pool") + alloca: 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") @@ -216,26 +216,26 @@ class ExprGenConst(ExprGenBase.ExprGenBase): # 链接器合并同模板重复特化定义,zeroinitializer 保证编译链接通过。 # 运行时若该模块未在入口 main 赋值 _mbuddy(null pool 上动态建 list), # 由真实崩溃暴露(fail-fast 哲学,不掩盖上游未初始化)。 - pool: rawptr[memhub.MemBuddy] = trans.Pool + pool: memhub.MemBuddy* = trans.Pool if pool is None or trans.Module is None or trans.SymTab is None: return None # 先检查是否已注册到模块作用域(避免重复创建全局变量) - existing: rawptr[llvmlite.Value] = self.Gen.VarGen.lookup_module_var(trans.SymTab, "_mbuddy") + existing: llvmlite.Value* = self.Gen.VarGen.lookup_module_var(trans.SymTab, "_mbuddy") if existing is not None: return existing # 创建 i8* 类型(t.CPtr = i8*) - i8_ty_fb: rawptr[llvmlite.LLVMType] = llvmlite.Int8(pool) - i8_ptr_ty_fb: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, i8_ty_fb) + i8_ty_fb: llvmlite.LLVMType* = llvmlite.Int8(pool) + i8_ptr_ty_fb: llvmlite.LLVMType* = llvmlite.Ptr(pool, i8_ty_fb) # 当前模块 mangled 名(@<模块sha1>._mbuddy) mb_name_fb: str = self.Gen.FuncGenBase._mangle_name(trans, "_mbuddy") # 创建 linkonce_odr 定义(可被链接器合并,自给自足保证链接通过) - gv_ext: rawptr[llvmlite.GlobalVariable] = llvmlite.new_global_variable(pool, mb_name_fb, i8_ptr_ty_fb) + gv_ext: 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" llvmlite.module_add_global(trans.Module, gv_ext) # 创建 Value 引用(@<模块sha1>._mbuddy, 类型为 i8**) - i8_ptr_ptr_ty_fb: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, i8_ptr_ty_fb) + i8_ptr_ptr_ty_fb: llvmlite.LLVMType* = llvmlite.Ptr(pool, i8_ptr_ty_fb) ref_name_fb: str = pool.alloc(96) if ref_name_fb is not None: # mangled 名带 SHA1 前缀(数字开头),引用必须加引号(见 make_global_ref) @@ -243,22 +243,22 @@ 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: rawptr[llvmlite.Value] = llvmlite.SSAValue(pool, i8_ptr_ptr_ty_fb, ref_name_fb) + gv_ref_fb: 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: rawptr[llvmlite.IRBuilder], - pool: rawptr[memhub.MemBuddy], - mod: rawptr[llvmlite.LLVMModule], - node: rawptr[ast.AST], + def translate_list_literal(self, builder: llvmlite.IRBuilder*, + pool: memhub.MemBuddy*, + mod: llvmlite.LLVMModule*, + node: ast.AST*, elem_type_name: str, - trans: rawptr[HT.Translator]) -> rawptr[llvmlite.Value]: + trans: HT.Translator*) -> llvmlite.Value*: """翻译 list 字面量 [a, b, c] → list[T](pool) + append 序列""" if node is None or trans is None: return None - list_node: rawptr[ast.List] = rawptr[ast.List](node) + list_node: ast.List* = ast.List*(node) if list_node is None: return None @@ -269,10 +269,10 @@ class ExprGenConst(ExprGenBase.ExprGenBase): # 推断元素类型 inferred_type_name: str = elem_type_name - first_elem_val: rawptr[llvmlite.Value] = None + first_elem_val: llvmlite.Value* = None if inferred_type_name is None: if elts_count > 0: - first_elem_node: rawptr[ast.AST] = elts.get(0) + first_elem_node: ast.AST* = elts.get(0) first_elem_val = self.Gen.ExprGen.translate_value(builder, pool, mod, first_elem_node, None, 0, trans) if first_elem_val is None or first_elem_val.Ty is None: # fail-fast:首元素翻译失败/Value 类型缺失,立即终止编译(暴露上游根因) @@ -288,20 +288,20 @@ class ExprGenConst(ExprGenBase.ExprGenBase): inferred_type_name = "str" # 查找 pool 变量 - pool_alloca: rawptr[llvmlite.Value] = self._find_pool_var(trans) + pool_alloca: 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 # load pool 变量值(i8*) - i8_ty: rawptr[llvmlite.LLVMType] = llvmlite.Int8(pool) - i8_ptr_ty: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, i8_ty) - pool_val: rawptr[llvmlite.Value] = llvmlite.build_load(builder, i8_ptr_ty, pool_alloca) + i8_ty: llvmlite.LLVMType* = llvmlite.Int8(pool) + i8_ptr_ty: llvmlite.LLVMType* = llvmlite.Ptr(pool, i8_ty) + pool_val: llvmlite.Value* = llvmlite.build_load(builder, i8_ptr_ty, pool_alloca) if pool_val is None: return None # 特化 list[T] 类(elem_size=8:str 是指针,4 会导致双元素重叠损坏) - type_args: list[str] | t.CPtr = list[str](pool, 8) + type_args: list[str]* = list[str](pool, 8) type_args.append(inferred_type_name) spec_name: str = self.Gen.ClassGenGeneric._specialize_generic_class(trans, "list", type_args) if spec_name is None: @@ -309,18 +309,18 @@ class ExprGenConst(ExprGenBase.ExprGenBase): return None # 查找 struct entry - struct_entry: rawptr[GenTypes.StructEntry] = self.Gen.StructGen.find_struct(spec_name) + struct_entry: 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 - struct_ty: rawptr[llvmlite.LLVMType] = struct_entry.Ty + struct_ty: llvmlite.LLVMType* = struct_entry.Ty if struct_ty is None: return None # alloca 临时 list 空间 # 确保跨模块结构体的完整定义在当前模块中可用(供 alloca 分配空间) self.Gen.StructGen.ensure_struct_def_in_module(pool, mod, struct_ty) - tmp: rawptr[llvmlite.Value] = self.Gen.VarGen._alloca_at_entry(builder, struct_ty) + tmp: llvmlite.Value* = self.Gen.VarGen._alloca_at_entry(builder, struct_ty) if tmp is None: return None @@ -328,17 +328,17 @@ class ExprGenConst(ExprGenBase.ExprGenBase): # __new__ 是可选的,仅当泛型类模板定义了 __new__ 方法时才调用 # (与 _translate_struct_ctor/_translate_generic_ctor_call 保持一致, # 避免为无 __new__ 的类生成过度声明) - storage_ptr: rawptr[llvmlite.Value] = tmp + storage_ptr: 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_args: sizet | t.CPtr = pool.alloc(8 * 32) + new_args: sizet* = pool.alloc(8 * 32) if new_args is None: return None string.memset(new_args, 0, 8 * 32) new_args[0] = sizet(pool_val) - new_ptr: rawptr[llvmlite.Value] = self.Gen.CallGenCall._call_method_on_ptr( + new_ptr: 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 @@ -348,12 +348,12 @@ class ExprGenConst(ExprGenBase.ExprGenBase): pool, builder, mod, spec_name, "__before_init__", storage_ptr, None, 0, trans) # 调用 __init__(storage_ptr, pool_val, elem_size=0) - init_args: sizet | t.CPtr = pool.alloc(8 * 32) + init_args: sizet* = pool.alloc(8 * 32) if init_args is None: return None string.memset(init_args, 0, 8 * 32) init_args[0] = sizet(pool_val) - elem_size_val: rawptr[llvmlite.Value] = llvmlite.const_int64(pool, 0) + elem_size_val: 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) @@ -362,7 +362,7 @@ class ExprGenConst(ExprGenBase.ExprGenBase): if elts_count > 0: # 第一个元素可能已经翻译过 if first_elem_val is not None: - append_args: sizet | t.CPtr = pool.alloc(8 * 32) + append_args: sizet* = pool.alloc(8 * 32) if append_args is not None: string.memset(append_args, 0, 8 * 32) append_args[0] = sizet(first_elem_val) @@ -372,10 +372,10 @@ class ExprGenConst(ExprGenBase.ExprGenBase): # 翻译剩余元素 i: sizet = 1 while i < elts_count: - elem_node_i: rawptr[ast.AST] = elts.get(i) - elem_val_i: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value(builder, pool, mod, elem_node_i, None, 0, trans) + elem_node_i: ast.AST* = elts.get(i) + elem_val_i: 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) + ap_args: sizet* = pool.alloc(8 * 32) if ap_args is not None: string.memset(ap_args, 0, 8 * 32) ap_args[0] = sizet(elem_val_i) diff --git a/App/lib/core/Gen/Expr/ExprGenFstr.vp b/App/lib/core/Gen/Expr/ExprGenFstr.vp index 4515089..c3dce3b 100644 --- a/App/lib/core/Gen/Expr/ExprGenFstr.vp +++ b/App/lib/core/Gen/Expr/ExprGenFstr.vp @@ -35,11 +35,11 @@ class ExprGenFstr(ExprGenBase.ExprGenBase): # 栈缓冲。之前 f-string 未翻译导致 print/赋值拿到 NULL 指针 # ("(null)"输出 + printf("%s", 垃圾) 崩溃 0xC0000005)。 # ============================================================ - 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) -> rawptr[llvmlite.Value]: + def translate_joined_str(self, builder: llvmlite.IRBuilder*, + pool: memhub.MemBuddy*, + mod: llvmlite.LLVMModule*, + node: ast.AST*, + trans: HT.Translator* = None) -> llvmlite.Value*: """f-string → snprintf 生成 i8* 栈缓冲""" if node is None or builder is None or trans is None: return None @@ -54,18 +54,18 @@ class ExprGenFstr(ExprGenBase.ExprGenBase): fmt_buf[0] = '\0' # 运行时参数链表(Value.Next 链接,与 printf 调用一致) - arg_head: rawptr[llvmlite.Value] = None - arg_tail: rawptr[llvmlite.Value] = None + arg_head: llvmlite.Value* = None + arg_tail: llvmlite.Value* = None arg_count: int = 0 parts: list[ast.AST*]* = js.values pn: sizet = len(parts) for pi in range(pn): - part: rawptr[ast.AST] = parts.get(pi) + part: ast.AST* = parts.get(pi) if part is None: continue if part.kind() == ast.ASTKind.Constant: - pcn: rawptr[ast.Constant] = rawptr[ast.Constant](part) + pcn: ast.Constant* = ast.Constant*(part) if pcn.const_kind == ast.CONST_STR and pcn.str_val is not None: self._fstr_append_literal(fmt_buf, pcn.str_val) continue @@ -74,7 +74,7 @@ class ExprGenFstr(ExprGenBase.ExprGenBase): fv: rawptr[ast.FormattedValue] = rawptr[ast.FormattedValue](part) if fv.value is None: continue - val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( + val: 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: rawptr[llvmlite.Value] = self._fstr_cast_value( + cast_val: llvmlite.Value* = self._fstr_cast_value( builder, pool, val, c_fmt, fv.value, trans) if cast_val is None: cast_val = val @@ -107,11 +107,11 @@ 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: rawptr[llvmlite.IRBuilder], - pool: rawptr[memhub.MemBuddy], - mod: rawptr[llvmlite.LLVMModule], - node: rawptr[ast.AST], - trans: rawptr[HT.Translator] = None) -> rawptr[llvmlite.Value]: + def translate_formatted_value(self, builder: llvmlite.IRBuilder*, + pool: memhub.MemBuddy*, + mod: llvmlite.LLVMModule*, + node: ast.AST*, + trans: HT.Translator* = None) -> llvmlite.Value*: """翻译裸 FormattedValue(f"{expr:spec}" 无字面量时解析器返回 FormattedValue 而非 JoinedStr)""" if node is None or builder is None or trans is None: return None @@ -122,10 +122,10 @@ class ExprGenFstr(ExprGenBase.ExprGenBase): if fmt_buf is None: return None fmt_buf[0] = '\0' - arg_head: rawptr[llvmlite.Value] = None - arg_tail: rawptr[llvmlite.Value] = None + arg_head: llvmlite.Value* = None + arg_tail: llvmlite.Value* = None arg_count: int = 0 - val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( + val: 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: rawptr[llvmlite.Value] = self._fstr_cast_value( + cast_val: llvmlite.Value* = self._fstr_cast_value( builder, pool, val, c_fmt, fv.value, trans) if cast_val is None: cast_val = val @@ -151,37 +151,37 @@ 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: rawptr[llvmlite.IRBuilder], - pool: rawptr[memhub.MemBuddy], - mod: rawptr[llvmlite.LLVMModule], + def _fstr_finalize(self, builder: llvmlite.IRBuilder*, + pool: memhub.MemBuddy*, + mod: llvmlite.LLVMModule*, fmt_buf: str, - arg_head: rawptr[llvmlite.Value], - arg_tail: rawptr[llvmlite.Value], + arg_head: llvmlite.Value*, + arg_tail: llvmlite.Value*, arg_count: int, - trans: rawptr[HT.Translator]) -> rawptr[llvmlite.Value]: + trans: HT.Translator*) -> llvmlite.Value*: """f-string 尾部:全局格式串 + 固定栈缓冲 + snprintf,返回 i8*""" - i32_ty: rawptr[llvmlite.LLVMType] = llvmlite.Int32(pool) - i8_ty: rawptr[llvmlite.LLVMType] = llvmlite.Int8(pool) + i32_ty: llvmlite.LLVMType* = llvmlite.Int32(pool) + i8_ty: llvmlite.LLVMType* = llvmlite.Int8(pool) if fmt_buf is None or fmt_buf[0] == '\0': # 空 f-string(f"")→ 空字符串常量 return self.Gen.ExprGenConst.create_global_string(builder, pool, mod, "", trans) # 格式串 → 全局字符串常量(i8*) - fmt_ptr: rawptr[llvmlite.Value] = self.Gen.ExprGenConst.create_global_string( + fmt_ptr: 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: rawptr[llvmlite.Value] = self.Gen.VarGen._alloca_at_entry(builder, buf_ty) + buf_ty: llvmlite.LLVMType* = llvmlite.Array(pool, i8_ty, FSTR_BUF_SIZE) + buf_alloca: llvmlite.Value* = self.Gen.VarGen._alloca_at_entry(builder, buf_ty) if buf_alloca is None: return None - zero_i32: rawptr[llvmlite.Value] = llvmlite.const_int32(pool, 0) - buf_ptr: rawptr[llvmlite.Value] = llvmlite.build_gep_array( + zero_i32: llvmlite.Value* = llvmlite.const_int32(pool, 0) + buf_ptr: 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: rawptr[llvmlite.Value] = llvmlite.const_int64(pool, FSTR_BUF_SIZE) + size_val: llvmlite.Value* = llvmlite.const_int64(pool, FSTR_BUF_SIZE) buf_ptr.Next = size_val size_val.Next = fmt_ptr fmt_ptr.Next = arg_head @@ -223,10 +223,10 @@ class ExprGenFstr(ExprGenBase.ExprGenBase): src_len: sizet = string.strlen(s) if cur_len + src_len < FSTR_BUF_SIZE: string.strcpy(fmt_buf + cur_len, s) - def _fstr_parse_format_spec(self, pool: rawptr[memhub.MemBuddy], - spec_node: rawptr[ast.AST], - val: rawptr[llvmlite.Value], - arg_node: rawptr[ast.AST]) -> str: + def _fstr_parse_format_spec(self, pool: memhub.MemBuddy*, + spec_node: ast.AST*, + val: llvmlite.Value*, + arg_node: ast.AST*) -> str: """Python format_spec → C printf 格式串(pool 分配),无法解析返回 None""" if spec_node is None or pool is None or val is None: return None @@ -242,18 +242,18 @@ class ExprGenFstr(ExprGenBase.ExprGenBase): return None vn: sizet = len(jss.values) for vi in range(vn): - vpart: rawptr[ast.AST] = jss.values.get(vi) + vpart: ast.AST* = jss.values.get(vi) if vpart is None: continue if vpart.kind() != ast.ASTKind.Constant: return None - vcn: rawptr[ast.Constant] = rawptr[ast.Constant](vpart) + vcn: ast.Constant* = ast.Constant*(vpart) if vcn.const_kind != ast.CONST_STR or vcn.str_val is None: return None if string.strlen(spec) + string.strlen(vcn.str_val) < FSTR_SPEC_MAX - 1: string.strcat(spec, vcn.str_val) elif sk == ast.ASTKind.Constant: - cn: rawptr[ast.Constant] = rawptr[ast.Constant](spec_node) + cn: ast.Constant* = ast.Constant*(spec_node) if cn.const_kind != ast.CONST_STR or cn.str_val is None: return None string.strncpy(spec, cn.str_val, FSTR_SPEC_MAX - 1) @@ -406,10 +406,10 @@ class ExprGenFstr(ExprGenBase.ExprGenBase): else: return None return out - def _fstr_infer_c_fmt(self, pool: rawptr[memhub.MemBuddy], - val: rawptr[llvmlite.Value], - arg_node: rawptr[ast.AST], - trans: rawptr[HT.Translator]) -> str: + def _fstr_infer_c_fmt(self, pool: memhub.MemBuddy*, + val: llvmlite.Value*, + arg_node: ast.AST*, + trans: HT.Translator*) -> str: """无 format_spec 时按值类型推断 C printf 格式(对齐 TPC 无 spec 分支,带 % 前缀)""" if val is None or pool is None: return None @@ -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: rawptr[llvmlite.IRBuilder], - pool: rawptr[memhub.MemBuddy], - val: rawptr[llvmlite.Value], + def _fstr_cast_value(self, builder: llvmlite.IRBuilder*, + pool: memhub.MemBuddy*, + val: llvmlite.Value*, c_fmt: str, - arg_node: rawptr[ast.AST], - trans: rawptr[HT.Translator]) -> rawptr[llvmlite.Value]: + arg_node: ast.AST*, + trans: HT.Translator*) -> llvmlite.Value*: """按 C 格式转换值类型(i8/i16→i32、bool→i32、f32→f64)""" if val is None or c_fmt is None: return None @@ -464,7 +464,7 @@ class ExprGenFstr(ExprGenBase.ExprGenBase): if ch != 'l' and ch != 'h': fmt_char = ch break - i32_ty: rawptr[llvmlite.LLVMType] = llvmlite.Int32(pool) + i32_ty: llvmlite.LLVMType* = llvmlite.Int32(pool) if fmt_char == 's': return val if fmt_char == 'c': diff --git a/App/lib/core/Gen/Expr/ExprGenMixin.vp b/App/lib/core/Gen/Expr/ExprGenMixin.vp index 0544941..c02dcf1 100644 --- a/App/lib/core/Gen/Expr/ExprGenMixin.vp +++ b/App/lib/core/Gen/Expr/ExprGenMixin.vp @@ -60,59 +60,65 @@ class ExprGenMixin(ExprGenBase.ExprGenBase): # ============================================================ # 翻译值表达式(RHS 分派)— 模块级版本 # ============================================================ - def translate_value(self, builder: rawptr[llvmlite.IRBuilder], - pool: rawptr[memhub.MemBuddy], - mod: rawptr[llvmlite.LLVMModule], - node: rawptr[ast.AST], + def translate_value(self, builder: llvmlite.IRBuilder*, + pool: memhub.MemBuddy*, + mod: llvmlite.LLVMModule*, + node: ast.AST*, funcs_ptr: t.CPtr = None, func_count: int = 0, - trans: rawptr[HT.Translator] = None, - target_ty: rawptr[llvmlite.LLVMType] = None) -> rawptr[llvmlite.Value]: + trans: HT.Translator* = None, + target_ty: llvmlite.LLVMType* = None, + use_ctx: str = None) -> llvmlite.Value*: """翻译值表达式为 LLVM Value(深度守卫包装器,原逻辑见 _translate_value_impl) target_ty: 目标类型上下文(如调用形参类型/赋值目标类型),用于单引号 单字符字面量(CONST_CHAR)在字符串目标下物化为 1 字符字符串(对齐 TPC)。 + use_ctx: 使用处**真实站点种类**标签("局部变量注解" / "模块级全局" / + "形参" / "返回注解" …),只被 CDefine 使用处宽度不足报文读取;不参与判定。 """ if trans is not None: if trans.TranslateDepth >= HT.TRANSLATE_MAX_DEPTH: self.Gen.TypeGenErr.fatal_error( node, "表达式翻译嵌套过深(疑似 AST 自引用环或翻译 bug)", "RecursionError") trans.TranslateDepth += 1 - rv: rawptr[llvmlite.Value] = self._translate_value_impl( - builder, pool, mod, node, funcs_ptr, func_count, trans, target_ty) + rv: llvmlite.Value* = self._translate_value_impl( + builder, pool, mod, node, funcs_ptr, func_count, trans, target_ty, use_ctx) if trans is not None: trans.TranslateDepth -= 1 return rv - def _translate_value_impl(self, builder: rawptr[llvmlite.IRBuilder], - pool: rawptr[memhub.MemBuddy], - mod: rawptr[llvmlite.LLVMModule], - node: rawptr[ast.AST], + def _translate_value_impl(self, builder: llvmlite.IRBuilder*, + pool: memhub.MemBuddy*, + mod: llvmlite.LLVMModule*, + node: ast.AST*, funcs_ptr: t.CPtr = None, func_count: int = 0, - trans: rawptr[HT.Translator] = None, - target_ty: rawptr[llvmlite.LLVMType] = None) -> rawptr[llvmlite.Value]: + trans: HT.Translator* = None, + target_ty: llvmlite.LLVMType* = None, + use_ctx: str = None) -> llvmlite.Value*: """翻译值表达式为 LLVM Value""" if node is None: return None k: int = node.kind() if k == ast.ASTKind.Constant: - rv: rawptr[llvmlite.Value] = self.Gen.ExprGenConst.translate_constant(builder, pool, mod, node, trans, target_ty) + rv: 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) + # target_ty(使用处类型:赋值目标 / 形参 / 返回)与 use_ctx(真实站点 + # 种类,仅供报文)下传给裸名翻译,供 CDefine 常量按使用处宽度物化; + # 非常量名不受影响(见 translate_name_value)。 + return self.Gen.ExprGenName.translate_name_value( + builder, pool, node, trans, target_ty, use_ctx) elif k == ast.ASTKind.BinOp: return self.Gen.ExprGenOps.translate_binop(pool, builder, mod, node, trans) elif k == ast.ASTKind.Call: - return self.Gen.CallGen.translate_call(pool, builder, mod, node, - funcs_ptr, func_count, trans) + return self.Gen.CallGen.translate_call(pool, builder, mod, node, funcs_ptr, func_count, trans) elif k == ast.ASTKind.Compare: return self.Gen.ExprGenOps.translate_compare(builder, pool, mod, node, trans) elif k == ast.ASTKind.UnaryOp: return self.Gen.ExprGenOps.translate_unaryop(builder, pool, mod, node, trans) elif k == ast.ASTKind.BoolOp: - return self.Gen.ExprGenOps.translate_boolop(builder, pool, mod, node, - funcs_ptr, func_count, trans) + return self.Gen.ExprGenOps.translate_boolop(builder, pool, mod, node, funcs_ptr, func_count, trans) elif k == ast.ASTKind.Subscript: return self.Gen.ExprGenName.translate_subscript(builder, pool, mod, node, trans) elif k == ast.ASTKind.Attribute: @@ -139,13 +145,12 @@ class ExprGenMixin(ExprGenBase.ExprGenBase): # await(M1 覆盖有限场景,详见 AsyncGenMixin._emit_await)。 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) + aw_cl: ast.Call* = ast.Call*(aw.value) if aw_cl.func is not None and aw_cl.func.kind() == ast.ASTKind.Name: - aw_nm: rawptr[ast.Name] = rawptr[ast.Name](aw_cl.func) + aw_nm: ast.Name* = ast.Name*(aw_cl.func) if aw_nm.id is not None and trans is not None: if self.Gen.AsyncGen.is_async_func(trans, aw_nm.id) != 0: - return self.Gen.AsyncGen._emit_await( - builder, pool, mod, trans, aw, aw_nm.id) + return self.Gen.AsyncGen._emit_await(builder, pool, mod, trans, aw, aw_nm.id) return None elif k == ast.ASTKind.Starred: # *x 在值上下文(如 printf("%d", *k) 实参):解析器把调用参数位的 @@ -155,7 +160,7 @@ class ExprGenMixin(ExprGenBase.ExprGenBase): 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) + deref_node: ast.AST* = ast.UnaryOp(pool, ast.OpKind.Deref, st.value) if deref_node is None: return None return self.Gen.ExprGenOps.translate_unaryop(builder, pool, mod, deref_node, trans) diff --git a/App/lib/core/Gen/Expr/ExprGenName.vp b/App/lib/core/Gen/Expr/ExprGenName.vp index 29d5497..8c55767 100644 --- a/App/lib/core/Gen/Expr/ExprGenName.vp +++ b/App/lib/core/Gen/Expr/ExprGenName.vp @@ -25,7 +25,7 @@ import lib.core.Gen.GenApi as GenApi class ExprGenName(ExprGenBase.ExprGenBase): """Name/Subscript/下标访问""" - def _cut_from_import_mod(self, pool: rawptr[memhub.MemBuddy], + def _cut_from_import_mod(self, pool: memhub.MemBuddy*, raw: str) -> str: """截断 lookup_from_import 返回的模块名到独立缓冲 @@ -50,18 +50,27 @@ class ExprGenName(ExprGenBase.ExprGenBase): buf_c[mbl_c] = '\0' return buf_c - def translate_name_value(self, builder: rawptr[llvmlite.IRBuilder], - pool: rawptr[memhub.MemBuddy], - node: rawptr[ast.AST], - trans: rawptr[HT.Translator] = None) -> rawptr[llvmlite.Value]: - """翻译变量引用(Name 节点)→ load""" + def translate_name_value(self, builder: llvmlite.IRBuilder*, + pool: memhub.MemBuddy*, + node: ast.AST*, + trans: HT.Translator* = None, + target_ty: llvmlite.LLVMType* = None, + use_ctx: str = None) -> llvmlite.Value*: + """翻译变量引用(Name 节点)→ load + + target_ty:调用方(translate_value)下传的**使用处类型**(赋值目标 / + 形参类型 / 返回类型)。它只被下方 CDefine 整数常量物化点读取(决定 + 物化宽度);普通变量 load 逐字沿用原有逻辑 ⇒ 非常量路径的既有 IR 不变。 + use_ctx:使用处**真实站点种类**标签,仅透传给宽度不足报文(见 + cdefine_use_width_value),不参与任何判定。 + """ # mod 必须取自 trans.Module:函数签名无 mod 参数,若用裸名 mod 会被 # 解析为 None → create_global_string 的 module_add_global(None, gv) 被 # add_global 的 `if self is None: return` 静默丢弃 → 字符串 CDefine 的 # global 定义丢失但 _label_counter/IR 引用已生成 → llc 报 # "use of undefined value '@.str.{sha1}.N'(SysLibTest _cleanup 根因)" - mod: rawptr[llvmlite.LLVMModule] = trans.Module - nm: rawptr[ast.Name] = rawptr[ast.Name](node) + mod: llvmlite.LLVMModule* = trans.Module + nm: ast.Name* = ast.Name*(node) if nm is None: return None nm_id: str = nm.id @@ -83,6 +92,13 @@ class ExprGenName(ExprGenBase.ExprGenBase): # 整数 CDefine:重新查表取 64 位全精度值(double 往返会丢精度, # 9223372036854775807 → 9.223372036854776e18 舍入错位,生成错常量) cdef_val_c: int64 = self.Gen.TypeGenCDef.lookup_cdefine_constant(nm_id) + # 使用处宽度(经 translate_value 的 target_ty 下传;站点种类由 + # use_ctx 携带,仅供报文使用): + # 更宽 ⇒ 就地升宽物化;更窄 ⇒ fail-fast;取不到 ⇒ 既有默认 32/64。 + uw_val: llvmlite.Value* = self.Gen.ExprGenCdef.cdefine_use_width_value( + pool, node, nm_id, cdef_val_c, target_ty, use_ctx) + if uw_val is not None: + return uw_val return self.Gen.ExprGenCdef._const_int_for_cdefine(pool, cdef_val_c) # 本地表未找到:尝试跨模块 .vpi 查找(保证多模块查表存表一致) @@ -111,6 +127,11 @@ class ExprGenName(ExprGenBase.ExprGenBase): dchk_nm: double = self.Gen.TypeGenCDef.lookup_cdefine_double(nm_id) if self.Gen.TypeGenCDef.is_cdefine_double() != 0: return llvmlite.ConstFloat(pool, llvmlite.Double(pool), dchk_nm) + # 使用处宽度同口径(跨模块 CDefine) + uw_x: llvmlite.Value* = self.Gen.ExprGenCdef.cdefine_use_width_value( + pool, node, nm_id, cdef_val, target_ty, use_ctx) + if uw_x is not None: + return uw_x return self.Gen.ExprGenCdef._const_int_for_cdefine(pool, cdef_val) # CDefine 查找失败:from-import 的模块级全局变量(如 @@ -128,13 +149,13 @@ 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: rawptr[llvmlite.GlobalVariable] = self.Gen.ExprGenAttr.find_global_in_module( + fi_gv: 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: rawptr[llvmlite.Value] = self.Gen.ExprGenAttr.make_global_ref( + fi_ref: 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 + fi_pty: llvmlite.LLVMType* = fi_ref.Ty.Pointee if fi_pty is not None: match fi_pty: case llvmlite.LLVMType.Array(_, _): @@ -147,10 +168,10 @@ class ExprGenName(ExprGenBase.ExprGenBase): # global 变量:从模块作用域查找(global 声明优先级最高) if trans is not None: if GenApi.is_global_name(trans, nm_id) != 0: - mod_alloca: rawptr[llvmlite.Value] = self.Gen.VarGen.lookup_module_var( + mod_alloca: llvmlite.Value* = self.Gen.VarGen.lookup_module_var( trans.SymTab, nm_id) if mod_alloca is not None: - load_ty: rawptr[llvmlite.LLVMType] = None + load_ty: llvmlite.LLVMType* = None if mod_alloca.Ty is not None: load_ty = mod_alloca.Ty.Pointee if load_ty is None: @@ -170,7 +191,7 @@ class ExprGenName(ExprGenBase.ExprGenBase): # t.CVolatile 全局:load 带 volatile 限定符(禁优化器消除重复读) vol_g: int = 0 if trans is not None: - ve_g: rawptr[GenTypes.VarEntry] = self.Gen.VarGen.lookup_var_entry( + ve_g: GenTypes.VarEntry* = self.Gen.VarGen.lookup_var_entry( trans.SymTab, nm_id) vol_g = self.Gen.VarGen.var_is_volatile(ve_g) return llvmlite.build_load(builder, load_ty, mod_alloca, vol_g) @@ -190,9 +211,9 @@ class ExprGenName(ExprGenBase.ExprGenBase): # 局部变量查找(必须先于模块别名检查) # 否则与模块同名的局部变量(如 `import t, c` 后的局部变量 c)会被误判为模块别名, # 导致 SymTab 已注册的局部变量查找不到(rhs_val is None bug 根因) - alloca: rawptr[llvmlite.Value] = self.Gen.VarGen.lookup_var(trans.SymTab, nm_id) + alloca: llvmlite.Value* = self.Gen.VarGen.lookup_var(trans.SymTab, nm_id) if alloca is not None: - load_ty: rawptr[llvmlite.LLVMType] = None + load_ty: llvmlite.LLVMType* = None if alloca.Ty is not None: load_ty = alloca.Ty.Pointee if load_ty is None: @@ -215,7 +236,7 @@ class ExprGenName(ExprGenBase.ExprGenBase): # t.CVolatile 局部变量:load 带 volatile 限定符 vol_l: int = 0 if trans is not None: - ve_l: rawptr[GenTypes.VarEntry] = self.Gen.VarGen.lookup_var_entry( + ve_l: GenTypes.VarEntry* = self.Gen.VarGen.lookup_var_entry( trans.SymTab, nm_id) vol_l = self.Gen.VarGen.var_is_volatile(ve_l) return llvmlite.build_load(builder, load_ty, alloca, vol_l) @@ -225,7 +246,7 @@ class ExprGenName(ExprGenBase.ExprGenBase): # ② 模块别名/模块函数引用之前(会话名不得被 printf 等本模块 declare 抢走)。 # 非 REPL(trans.ReplCtx is None)时 repl_try_read 立即返回 None ⇒ 原路径逐字不变。 if trans is not None and trans.ReplCtx is not None: - sess_val: rawptr[llvmlite.Value] = self.Gen.VarGen.repl_try_read( + sess_val: llvmlite.Value* = self.Gen.VarGen.repl_try_read( trans, nm_id, node) if sess_val is not None: return sess_val @@ -247,25 +268,25 @@ class ExprGenName(ExprGenBase.ExprGenBase): # 最终打印出 `declare void @()` 空名函数。正确做法:按 Function 的 # RetTy/Params 构造真实函数类型,用 new_value 包装成普通 Value 再 bitcast。 if trans is not None and trans.Module is not None: - fn_ref: rawptr[llvmlite.Function] = self.Gen.CallGenBase.find_func_in_module( + fn_ref: llvmlite.Function* = self.Gen.CallGenBase.find_func_in_module( trans.Module, nm_id) if fn_ref is not None: fn_name: str = llvmlite.function_get_name(fn_ref) if fn_name is None: return None # 构造函数类型:ret_ty + 参数 ParamNode 链表 - fn_ret_ty: rawptr[llvmlite.LLVMType] = llvmlite.function_get_ret_ty(fn_ref) + fn_ret_ty: llvmlite.LLVMType* = llvmlite.function_get_ret_ty(fn_ref) if fn_ret_ty is None: # fail-fast:函数返回类型缺失,无法构造函数指针(暴露上游根因) self.Gen.TypeGenErr.fatal_error( node, f"函数 '{nm_id}' 返回类型缺失,无法构造函数指针", "TypeError") - 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_pp: llvmlite.Param* = llvmlite.function_get_param_head(fn_ref) + fn_first_node: llvmlite.Function* = None + fn_prev_node: llvmlite.Function* = None fn_pcount: int = 0 while fn_pp is not None: - fn_pty: rawptr[llvmlite.LLVMType] = llvmlite.param_get_ty(fn_pp) - fn_pn: rawptr[llvmlite.Function] = llvmlite.new_param_node(pool, fn_pty) + fn_pty: llvmlite.LLVMType* = llvmlite.param_get_ty(fn_pp) + fn_pn: llvmlite.Function* = llvmlite.new_param_node(pool, fn_pty) if fn_pn is not None: if fn_first_node is None: fn_first_node = fn_pn @@ -274,12 +295,12 @@ class ExprGenName(ExprGenBase.ExprGenBase): fn_prev_node = fn_pn fn_pcount += 1 fn_pp = llvmlite.param_get_next(fn_pp) - fn_ty: rawptr[llvmlite.LLVMType] = llvmlite.Func( + fn_ty: llvmlite.LLVMType* = llvmlite.Func( pool, fn_ret_ty, fn_first_node, fn_pcount) if fn_ty is None: return None # 构造函数指针 Value(new_value 包装,避免触碰 Function.Next) - fn_ref_v: rawptr[llvmlite.Value] = llvmlite.new_value(pool) + fn_ref_v: 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)) @@ -292,7 +313,7 @@ class ExprGenName(ExprGenBase.ExprGenBase): else: viperlib.snprintf(fn_ref_name, 256, "@%s", fn_name) llvmlite.value_set_name(fn_ref_v, fn_ref_name) - fn_i8ptr_ty: rawptr[llvmlite.LLVMType] = llvmlite.Ptr( + fn_i8ptr_ty: llvmlite.LLVMType* = llvmlite.Ptr( pool, llvmlite.Int8(pool)) return llvmlite.build_bitcast(builder, fn_ref_v, fn_i8ptr_ty) @@ -342,9 +363,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: rawptr[llvmlite.GlobalVariable] = self.Gen.ExprGenAttr.find_global_in_module( + gv_fi: llvmlite.GlobalVariable* = self.Gen.ExprGenAttr.find_global_in_module( trans.Module, gv_fi_q) - ref_fi: rawptr[llvmlite.Value] = None + ref_fi: 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: @@ -355,7 +376,7 @@ class ExprGenName(ExprGenBase.ExprGenBase): # "stub 未注入"。 return None if ref_fi is not None and ref_fi.Ty is not None: - lty_fi: rawptr[llvmlite.LLVMType] = ref_fi.Ty.Pointee + lty_fi: llvmlite.LLVMType* = ref_fi.Ty.Pointee if lty_fi is not None: return llvmlite.build_load(builder, lty_fi, ref_fi) return ref_fi @@ -384,35 +405,35 @@ 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: rawptr[llvmlite.IRBuilder], - pool: rawptr[memhub.MemBuddy], - lm_obj: rawptr[llvmlite.Value], - idx_val: rawptr[llvmlite.Value], - node: rawptr[ast.AST] = None) -> rawptr[llvmlite.Value]: + def list_getitem_inline(self, builder: llvmlite.IRBuilder*, + pool: memhub.MemBuddy*, + lm_obj: llvmlite.Value*, + idx_val: llvmlite.Value*, + node: ast.AST* = None) -> 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 - i64_ty: rawptr[llvmlite.LLVMType] = llvmlite.Int64(pool) - i8_ty: rawptr[llvmlite.LLVMType] = llvmlite.Int8(pool) - i8_ptr_ty: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, i8_ty) + i64_ty: llvmlite.LLVMType* = llvmlite.Int64(pool) + i8_ty: llvmlite.LLVMType* = llvmlite.Int8(pool) + i8_ptr_ty: llvmlite.LLVMType* = llvmlite.Ptr(pool, i8_ty) # 加载 __data__ (偏移 0, index 0) - 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_idx0: llvmlite.Value* = llvmlite.const_int64(pool, 0) + g_dpp: llvmlite.Value* = llvmlite.build_gep(builder, i64_ty, lm_obj, g_idx0) if g_dpp is None: return None - g_data: rawptr[llvmlite.Value] = llvmlite.build_load(builder, i8_ptr_ty, g_dpp) + g_data: llvmlite.Value* = llvmlite.build_load(builder, i8_ptr_ty, g_dpp) # 加载 __elem_size__ (偏移 32, index 4) - 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_idx4: llvmlite.Value* = llvmlite.const_int64(pool, 4) + g_epp: llvmlite.Value* = llvmlite.build_gep(builder, i64_ty, lm_obj, g_idx4) if g_epp is None: return None - g_esize: rawptr[llvmlite.Value] = llvmlite.build_load(builder, i64_ty, g_epp) + g_esize: 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: rawptr[llvmlite.Value] = self.coerce_to_type(builder, idx_val, i64_ty, node) + g_idx_i64: llvmlite.Value* = self.coerce_to_type(builder, idx_val, i64_ty, node) if g_idx_i64 is None: return None - g_offset: rawptr[llvmlite.Value] = llvmlite.build_mul(builder, g_idx_i64, g_esize) + g_offset: llvmlite.Value* = llvmlite.build_mul(builder, g_idx_i64, g_esize) if g_offset is None: return None # 返回元素地址 (i8*),不 load @@ -425,8 +446,8 @@ class ExprGenName(ExprGenBase.ExprGenBase): # 支持: list[int]→i32, list[str]/list[bytes]→i8*, list[CInt]→i32 等 # 默认: i32 # ============================================================ - def _list_elem_type_from_name(self, pool: rawptr[memhub.MemBuddy], - struct_name: str) -> rawptr[llvmlite.LLVMType]: + def _list_elem_type_from_name(self, pool: memhub.MemBuddy*, + struct_name: str) -> llvmlite.LLVMType*: """从 list 类型名提取元素 LLVM 类型""" if pool is None or struct_name is None: return None @@ -452,7 +473,7 @@ class ExprGenName(ExprGenBase.ExprGenBase): if string.strstr(struct_name, "list[CChar]") is not None: return llvmlite.Int8(pool) # str/bytes/CPtr 等已知指针元素类型 → i8*(元素存储为 8 字节地址) - i8_ty_d: rawptr[llvmlite.LLVMType] = llvmlite.Int8(pool) + i8_ty_d: llvmlite.LLVMType* = llvmlite.Int8(pool) if string.strstr(struct_name, "list[str]") is not None: return llvmlite.Ptr(pool, i8_ty_d) if string.strstr(struct_name, "list[bytes]") is not None: @@ -467,7 +488,7 @@ class ExprGenName(ExprGenBase.ExprGenBase): # 才能经 LLVM 类型解析出类名 AST(T29 修复);否则统一 Ptr(i8) 丢失 # 类名,.kind() 被当未绑定外部函数(AstTest NewAstTest fatal: 'kind' # 根因:list 元素类名没有沿 get(0) 调用结果值类型传播到后续分派)。 - elem_obj_ty_l: rawptr[llvmlite.LLVMType] = \ + elem_obj_ty_l: llvmlite.LLVMType* = \ self._list_elem_obj_ty_from_struct_name(pool, struct_name) if elem_obj_ty_l is not None: return elem_obj_ty_l @@ -486,8 +507,8 @@ class ExprGenName(ExprGenBase.ExprGenBase): # llvmlite.Ptr(entry.Ty)(list 元素槽 8 字节存对象指针)。全部未命中 # 返回 None(调用方回退 Ptr(i8) 旧行为,不影响已支持的内置元素)。 # ============================================================ - def _list_elem_obj_ty_from_struct_name(self, pool: rawptr[memhub.MemBuddy], - struct_name: str) -> rawptr[llvmlite.LLVMType]: + def _list_elem_obj_ty_from_struct_name(self, pool: memhub.MemBuddy*, + struct_name: str) -> llvmlite.LLVMType*: """从 list 特化类型名还原元素对象指针 LLVM 类型,失败返回 None""" if pool is None or struct_name is None: return None @@ -539,7 +560,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: rawptr[GenTypes.StructEntry] = \ + s_entry_e: 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) @@ -553,57 +574,57 @@ class ExprGenName(ExprGenBase.ExprGenBase): # # 直接存储 rhs_val 到元素地址 (coerce 为 i8* 后 store) # ============================================================ - def list_setitem_inline(self, builder: rawptr[llvmlite.IRBuilder], - pool: rawptr[memhub.MemBuddy], - lm_obj: rawptr[llvmlite.Value], - idx_val: rawptr[llvmlite.Value], - rhs_val: rawptr[llvmlite.Value], - node: rawptr[ast.AST] = None) -> int: + def list_setitem_inline(self, builder: llvmlite.IRBuilder*, + pool: memhub.MemBuddy*, + lm_obj: llvmlite.Value*, + idx_val: llvmlite.Value*, + rhs_val: llvmlite.Value*, + node: ast.AST* = None) -> int: """内联生成 list __setitem__ 逻辑,返回 0""" if builder is None or pool is None or lm_obj is None or idx_val is None or rhs_val is None: return 0 - i64_ty: rawptr[llvmlite.LLVMType] = llvmlite.Int64(pool) - i8_ty: rawptr[llvmlite.LLVMType] = llvmlite.Int8(pool) - i8_ptr_ty: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, i8_ty) + i64_ty: llvmlite.LLVMType* = llvmlite.Int64(pool) + i8_ty: llvmlite.LLVMType* = llvmlite.Int8(pool) + i8_ptr_ty: llvmlite.LLVMType* = llvmlite.Ptr(pool, i8_ty) # 加载 __data__ (偏移 0, index 0) - 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_idx0: llvmlite.Value* = llvmlite.const_int64(pool, 0) + s_dpp: llvmlite.Value* = llvmlite.build_gep(builder, i64_ty, lm_obj, s_idx0) if s_dpp is None: return 0 - s_data: rawptr[llvmlite.Value] = llvmlite.build_load(builder, i8_ptr_ty, s_dpp) + s_data: llvmlite.Value* = llvmlite.build_load(builder, i8_ptr_ty, s_dpp) # 加载 __elem_size__ (偏移 32, index 4) - 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_idx4: llvmlite.Value* = llvmlite.const_int64(pool, 4) + s_epp: llvmlite.Value* = llvmlite.build_gep(builder, i64_ty, lm_obj, s_idx4) if s_epp is None: return 0 - s_esize: rawptr[llvmlite.Value] = llvmlite.build_load(builder, i64_ty, s_epp) + s_esize: 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: rawptr[llvmlite.Value] = self.coerce_to_type(builder, idx_val, i64_ty, node) + s_idx_i64: llvmlite.Value* = self.coerce_to_type(builder, idx_val, i64_ty, node) if s_idx_i64 is None: return 0 - s_offset: rawptr[llvmlite.Value] = llvmlite.build_mul(builder, s_idx_i64, s_esize) + s_offset: llvmlite.Value* = llvmlite.build_mul(builder, s_idx_i64, s_esize) if s_offset is None: return 0 - s_addr: rawptr[llvmlite.Value] = llvmlite.build_gep(builder, i8_ty, s_data, s_offset) + s_addr: 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*)。 # 此前固定 i8*(8 字节)store(inttoptr 值)覆盖相邻元素——与 # CallGenMixin list 内置分支同根因(ListTest pop FAILED expect 30)。 - s_sty: rawptr[llvmlite.LLVMType] = self.Gen.StructGen.get_struct_type_from_value(lm_obj) + s_sty: llvmlite.LLVMType* = self.Gen.StructGen.get_struct_type_from_value(lm_obj) s_name: str = None if s_sty is not None: s_name = llvmlite.get_struct_name(s_sty) - s_elem_ty: rawptr[llvmlite.LLVMType] = None + s_elem_ty: llvmlite.LLVMType* = None if s_name is not None: 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: rawptr[llvmlite.Value] = self.coerce_to_type(builder, rhs_val, s_elem_ty, node) + s_val_ptr: llvmlite.Value* = self.coerce_to_type(builder, rhs_val, s_elem_ty, node) if s_val_ptr is None: return 0 - s_ep: rawptr[llvmlite.Value] = llvmlite.build_bitcast( + s_ep: 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) @@ -613,29 +634,29 @@ class ExprGenName(ExprGenBase.ExprGenBase): # # 返回 list 对象指针 (Ptr(list[T])) 或 None # ============================================================ - def is_list_subscript(self, node: rawptr[ast.AST], - trans: rawptr[HT.Translator]) -> rawptr[llvmlite.Value]: + def is_list_subscript(self, node: ast.AST*, + trans: HT.Translator*) -> llvmlite.Value*: """检查 Subscript 节点是否是 list[T] 类型,返回 list 对象指针或 None""" if node is None or trans is None: return None - sub: rawptr[ast.Subscript] = rawptr[ast.Subscript](node) + sub: ast.Subscript* = ast.Subscript*(node) if sub is None or sub.value is None: return None if sub.value.kind() != ast.ASTKind.Name: return None - nm: rawptr[ast.Name] = rawptr[ast.Name](sub.value) + nm: ast.Name* = ast.Name*(sub.value) if nm is None or nm.id is None: return None - alloca: rawptr[llvmlite.Value] = self.Gen.VarGen.lookup_var(trans.SymTab, nm.id) + alloca: 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: return None - pointee: rawptr[llvmlite.LLVMType] = alloca.Ty.Pointee + pointee: llvmlite.LLVMType* = alloca.Ty.Pointee if pointee is None: return None # 检查 pointee 是否是 Ptr(Struct) - inner_ty: rawptr[llvmlite.LLVMType] = None + inner_ty: llvmlite.LLVMType* = None match pointee: case llvmlite.LLVMType.Ptr(it): inner_ty = it @@ -655,26 +676,26 @@ class ExprGenName(ExprGenBase.ExprGenBase): if string.strstr(struct_name, "list[") is None: return None # 是 list 类型: load 出 list 对象指针 - builder: rawptr[llvmlite.IRBuilder] = trans._cur_builder + builder: 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: rawptr[llvmlite.IRBuilder], - pool: rawptr[memhub.MemBuddy], - trans: rawptr[HT.Translator], + def _nonlocal_subscript_ptr(self, builder: llvmlite.IRBuilder*, + pool: memhub.MemBuddy*, + trans: HT.Translator*, nm_id: str, - idx_val: rawptr[llvmlite.Value]) -> rawptr[llvmlite.Value]: + idx_val: llvmlite.Value*) -> 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) + nl_ty: llvmlite.LLVMType* = GenApi.get_nonlocal_type(trans, nm_id) if nl_ty is None: return None - raw_nl: rawptr[llvmlite.Value] = self.Gen.StmtGenDecl._load_raw_var_ptr(trans, nm_id) + raw_nl: 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: rawptr[llvmlite.Value] = llvmlite.build_bitcast( + arr_ptr_nl: llvmlite.Value* = llvmlite.build_bitcast( builder, raw_nl, llvmlite.Ptr(pool, nl_ty)) if arr_ptr_nl is None: return None @@ -682,13 +703,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: rawptr[llvmlite.Value] = llvmlite.build_bitcast( + arr_ptr_nl2: 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: rawptr[llvmlite.Value] = llvmlite.build_bitcast( + arr_ptr_nl3: llvmlite.Value* = llvmlite.build_bitcast( builder, raw_nl, llvmlite.Ptr(pool, nl_ty)) if arr_ptr_nl3 is None: return None @@ -701,15 +722,15 @@ class ExprGenName(ExprGenBase.ExprGenBase): # 数组遍历: arr 是数组变量,用 alloca 指针做双索引 GEP [0, i] + load # list[T]: 泛型类不注册 struct,subscript 走 __getitem__ 内联路径 # ============================================================ - 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) -> rawptr[llvmlite.Value]: + def translate_subscript(self, builder: llvmlite.IRBuilder*, + pool: memhub.MemBuddy*, + mod: llvmlite.LLVMModule*, + node: ast.AST*, + trans: HT.Translator* = None) -> llvmlite.Value*: """翻译下标表达式,返回加载的元素值""" if node is None or builder is None: return None - sub: rawptr[ast.Subscript] = rawptr[ast.Subscript](node) + sub: ast.Subscript* = ast.Subscript*(node) if sub is None: return None @@ -720,29 +741,29 @@ class ExprGenName(ExprGenBase.ExprGenBase): # p.entry 垃圾 → 用户进程 iretq 到垃圾地址 → PF)。 if sub.slice is not None and sub.slice.kind() == ast.ASTKind.Slice: slc: rawptr[ast.Slice] = rawptr[ast.Slice](sub.slice) - base_v: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( + base_v: 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: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( + start_v: 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: rawptr[llvmlite.Value] = start_v + i64_sc: llvmlite.LLVMType* = llvmlite.Int64(pool) + start_w: 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: start_w = llvmlite.build_sext(builder, start_v, i64_sc) if start_w is None: return None - i8_sc: rawptr[llvmlite.LLVMType] = llvmlite.Int8(pool) + i8_sc: llvmlite.LLVMType* = llvmlite.Int8(pool) return llvmlite.build_gep(builder, i8_sc, base_v, start_w) # 翻译索引 - idx_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( + idx_val: llvmlite.Value* = self.Gen.ExprGen.translate_value( builder, pool, mod, sub.slice, None, 0, trans) if idx_val is None: return None @@ -752,23 +773,23 @@ 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: rawptr[llvmlite.Value] = self.get_subscript_ptr( + inner_ptr_r: 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 - inner_elem_r: rawptr[llvmlite.LLVMType] = inner_ptr_r.Ty.Pointee + inner_elem_r: llvmlite.LLVMType* = inner_ptr_r.Ty.Pointee if inner_elem_r is None: return None match inner_elem_r: case llvmlite.LLVMType.Array(arr_ie_r, _): - elem_ptr_r: rawptr[llvmlite.Value] = llvmlite.build_gep_array( + elem_ptr_r: 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: rawptr[llvmlite.Value] = llvmlite.build_gep( + elem_ptr_r2: 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) @@ -776,7 +797,7 @@ class ExprGenName(ExprGenBase.ExprGenBase): # 如果 value 是 Name,尝试从 alloca 类型推断 if sub.value is not None and sub.value.kind() == ast.ASTKind.Name: - nm: rawptr[ast.Name] = rawptr[ast.Name](sub.value) + nm: ast.Name* = ast.Name*(sub.value) if nm.id is not None and trans is not None: # rawptr[t.CVolatile | T] 变量(volatile 指针指向物):本分支内 # 的**元素 load**(p[i] 解引用)带 volatile;仅读取指针值自身的 @@ -787,24 +808,24 @@ class ExprGenName(ExprGenBase.ExprGenBase): # lookup_var 外层 alloca——SSA 编号跨函数错乱崩溃) # 读路径:元素指针 load 出元素值 if GenApi.is_nonlocal_name(trans, nm.id) != 0: - nl_ptr_r: rawptr[llvmlite.Value] = self._nonlocal_subscript_ptr( + nl_ptr_r: 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 + nl_elem_ty: 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: rawptr[llvmlite.Value] = self.Gen.VarGen.lookup_var(trans.SymTab, nm.id) + alloca: 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 + pointee: llvmlite.LLVMType* = alloca.Ty.Pointee if pointee is not None: # 不调用 pointee.kind() 避免跨模块引用 LLVMType.kind 符号 # 用 match 检查 pointee 类型 match pointee: case llvmlite.LLVMType.Array(elem_ty, count): # 数组遍历: getelementptr [N x elem_ty], ... , i32 0, i32 %idx - elem_ptr: rawptr[llvmlite.Value] = llvmlite.build_gep_array( + elem_ptr: 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: @@ -818,16 +839,16 @@ 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: rawptr[llvmlite.Value] = \ + elem_addr_v: llvmlite.Value* = \ self.list_getitem_inline( builder, pool, alloca, idx_val, node) if elem_addr_v is not None: - elem_ty_v: rawptr[llvmlite.LLVMType] = \ + elem_ty_v: llvmlite.LLVMType* = \ self._list_elem_type_from_name(pool, lsn_v) if elem_ty_v is not None: - elem_ptr_ty_v: rawptr[llvmlite.LLVMType] = \ + elem_ptr_ty_v: llvmlite.LLVMType* = \ llvmlite.Ptr(pool, elem_ty_v) - casted_v: rawptr[llvmlite.Value] = \ + casted_v: llvmlite.Value* = \ llvmlite.build_bitcast( builder, elem_addr_v, elem_ptr_ty_v) if casted_v is not None: @@ -846,19 +867,19 @@ 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: rawptr[llvmlite.Value] = llvmlite.build_load( + ptr_val_list: llvmlite.Value* = llvmlite.build_load( builder, pointee, alloca) if ptr_val_list is not None: - elem_addr_list: rawptr[llvmlite.Value] = self.list_getitem_inline( + elem_addr_list: llvmlite.Value* = self.list_getitem_inline( builder, pool, ptr_val_list, idx_val, node) if elem_addr_list is not None: # 根据类型名提取元素类型,bitcast 后 load - elem_ty_list: rawptr[llvmlite.LLVMType] = self._list_elem_type_from_name( + elem_ty_list: llvmlite.LLVMType* = self._list_elem_type_from_name( pool, list_struct_name) if elem_ty_list is not None: - elem_ptr_ty_list: rawptr[llvmlite.LLVMType] = llvmlite.Ptr( + elem_ptr_ty_list: llvmlite.LLVMType* = llvmlite.Ptr( pool, elem_ty_list) - casted_addr_list: rawptr[llvmlite.Value] = llvmlite.build_bitcast( + casted_addr_list: llvmlite.Value* = llvmlite.build_bitcast( builder, elem_addr_list, elem_ptr_ty_list) if casted_addr_list is not None: return llvmlite.build_load( @@ -871,10 +892,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: rawptr[llvmlite.Value] = llvmlite.build_load( + ptr_val_pp: llvmlite.Value* = llvmlite.build_load( builder, pointee, alloca) if ptr_val_pp is not None: - elem_ptr_pp: rawptr[llvmlite.Value] = llvmlite.build_gep( + elem_ptr_pp: llvmlite.Value* = llvmlite.build_gep( builder, inner_ty, ptr_val_pp, idx_val) if elem_ptr_pp is not None: # volatile 指针指向物:解引用 load 带 volatile @@ -890,22 +911,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: rawptr[llvmlite.Value] = llvmlite.build_load( + obj_ptr_rd: 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) + arg_vals_rd_p: sizet* = pool.alloc(8) if not (arg_vals_rd_p is None): arg_vals_rd_p[0] = sizet(idx_val) - ret_rd_p: rawptr[llvmlite.Value] = self.Gen.CallGenCall._call_method_on_ptr( + ret_rd_p: 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: rawptr[llvmlite.Value] = llvmlite.build_load( + ptr_val_rd_g: llvmlite.Value* = llvmlite.build_load( builder, pointee, alloca) if ptr_val_rd_g is not None: - elem_rd_g: rawptr[llvmlite.Value] = llvmlite.build_gep( + elem_rd_g: llvmlite.Value* = llvmlite.build_gep( builder, inner_ty, ptr_val_rd_g, idx_val) if elem_rd_g is not None: # volatile 指针指向物:解引用 load 带 volatile @@ -915,7 +936,7 @@ class ExprGenName(ExprGenBase.ExprGenBase): # 直接 GEP 按 i8* 步长(8 字节),load i8* # 仅当 inner_ty 不是自定义结构体时才走指针遍历 if trans is not None: - ve_pe_ts: rawptr[GenTypes.VarEntry] = \ + ve_pe_ts: 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*), @@ -923,20 +944,20 @@ class ExprGenName(ExprGenBase.ExprGenBase): # 必须先 load alloca 得指针值,再 GEP i8*(步长 8)—— # 否则 GEP base 用 alloca(&elem_ptr)读到栈变量而非数据区, # list.get 返回"元素地址"而非"元素值"(dump 虚调用读错 vtable)。 - ptr_val_pe_ts: rawptr[llvmlite.Value] = llvmlite.build_load( + ptr_val_pe_ts: llvmlite.Value* = llvmlite.build_load( builder, pointee, alloca) if ptr_val_pe_ts is not None: - elem_ptr_ts: rawptr[llvmlite.Value] = llvmlite.build_gep( + elem_ptr_ts: llvmlite.Value* = llvmlite.build_gep( builder, pointee, ptr_val_pe_ts, idx_val) if elem_ptr_ts is not None: # volatile 指针指向物:解引用 load 带 volatile return llvmlite.build_load(builder, pointee, elem_ptr_ts, vol_sub_rd) return None # 普通指针遍历: 先 load 指针值,再 GEP - ptr_val: rawptr[llvmlite.Value] = llvmlite.build_load( + ptr_val: llvmlite.Value* = llvmlite.build_load( builder, pointee, alloca) if ptr_val is not None: - elem_ptr2: rawptr[llvmlite.Value] = llvmlite.build_gep( + elem_ptr2: llvmlite.Value* = llvmlite.build_gep( builder, inner_ty, ptr_val, idx_val) if elem_ptr2 is not None: # volatile 指针指向物:解引用 load 带 volatile @@ -948,15 +969,15 @@ class ExprGenName(ExprGenBase.ExprGenBase): # 元素是 8 字节指针,须按 i8* 步长 GEP + load i8*—— # 否则 list.get 只读 1 字节,指针截断 inttoptr 崩溃。 if trans is not None: - ve_pe_rd: rawptr[GenTypes.VarEntry] = \ + ve_pe_rd: 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: case llvmlite.LLVMType.Int(bits_rd): if bits_rd == 8: - i8_ptr_rd: rawptr[llvmlite.LLVMType] = llvmlite.Ptr( + i8_ptr_rd: llvmlite.LLVMType* = llvmlite.Ptr( pool, llvmlite.Int8(pool)) - elem_ptr_rd: rawptr[llvmlite.Value] = llvmlite.build_gep( + elem_ptr_rd: llvmlite.Value* = llvmlite.build_gep( builder, i8_ptr_rd, alloca, idx_val) if elem_ptr_rd is not None: return llvmlite.build_load( @@ -972,22 +993,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: rawptr[llvmlite.Value] = llvmlite.build_load( + obj_val_sub: llvmlite.Value* = llvmlite.build_load( builder, pointee, alloca) if not (obj_val_sub is None): - arg_vals_sub: sizet | t.CPtr = pool.alloc(8) + arg_vals_sub: sizet* = pool.alloc(8) if not (arg_vals_sub is None): arg_vals_sub[0] = sizet(idx_val) - ret_sub: rawptr[llvmlite.Value] = self.Gen.CallGenCall._call_method_on_ptr( + ret_sub: 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: rawptr[llvmlite.Value] = llvmlite.build_load( + ptr_val_sub_g: llvmlite.Value* = llvmlite.build_load( builder, pointee, alloca) if ptr_val_sub_g is not None: - elem_sub_g: rawptr[llvmlite.Value] = llvmlite.build_gep( + elem_sub_g: llvmlite.Value* = llvmlite.build_gep( builder, pointee, ptr_val_sub_g, idx_val) if elem_sub_g is not None: # volatile 指针指向物:解引用 load 带 volatile @@ -996,7 +1017,7 @@ class ExprGenName(ExprGenBase.ExprGenBase): pass # 通用路径:翻译 value 获取指针 - ptr_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( + ptr_val: 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 @@ -1008,12 +1029,12 @@ class ExprGenName(ExprGenBase.ExprGenBase): # 其余基址解析返回 0(明确不支持,见限制清单)。守卫为 0 时文本不变。 vol_sub_gen: int = self.Gen.ExprGenAttr.base_pointee_is_volatile( pool, trans, sub.value) - elem_ty2: rawptr[llvmlite.LLVMType] = ptr_val.Ty.Pointee + elem_ty2: llvmlite.LLVMType* = ptr_val.Ty.Pointee if elem_ty2 is not None: # 数组类型: 双索引 GEP + load 元素 match elem_ty2: case llvmlite.LLVMType.Array(arr_elem_ty2, arr_count2): - elem_ptr3: rawptr[llvmlite.Value] = llvmlite.build_gep_array( + elem_ptr3: 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: @@ -1022,7 +1043,7 @@ class ExprGenName(ExprGenBase.ExprGenBase): case _: pass # [FIX 2026-08-31] 64 位标量 | t.CPtr 联合字段下标读回 - # (如 RenumClassNames: sizet | t.CPtr,联合解析为 i64* 8 字节 + # (如 RenumClassNames: sizet*,联合解析为 i64* 8 字节 # 槽数组):槽位按 Int64 load 得位模式,赋给 str(i8*)触发 int→ptr # 禁令误报(ClassGenEnum.vp existing: str = self.RenumClassNames[i] # 根因)。槽里实际存的是 perm_pool 字符串指针——联合声明即"槽位可能 @@ -1037,16 +1058,16 @@ class ExprGenName(ExprGenBase.ExprGenBase): match elem_ty2: case llvmlite.LLVMType.Int(eb_u64): if eb_u64 == 64: - cell_p_u64: rawptr[llvmlite.Value] = \ + cell_p_u64: 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] = \ + i8_ty_u64: llvmlite.LLVMType* = \ llvmlite.Int8(pool) - i8p_ty_u64: rawptr[llvmlite.LLVMType] = \ + i8p_ty_u64: llvmlite.LLVMType* = \ llvmlite.Ptr(pool, i8_ty_u64) - i8pp_ty_u64: rawptr[llvmlite.LLVMType] = \ + i8pp_ty_u64: llvmlite.LLVMType* = \ llvmlite.Ptr(pool, i8p_ty_u64) - cast_cell_u64: rawptr[llvmlite.Value] = \ + cast_cell_u64: llvmlite.Value* = \ llvmlite.build_bitcast( builder, cell_p_u64, i8pp_ty_u64) if cast_cell_u64 is not None: @@ -1062,22 +1083,22 @@ class ExprGenName(ExprGenBase.ExprGenBase): if gi_lookup_gen is not None: viperlib.snprintf(gi_lookup_gen, 128, "%s.__getitem__", cls_nm_rd_gen) if self.Gen.CallGenBase.find_func_in_module(mod, gi_lookup_gen) is not None: - arg_vals_rd_g: sizet | t.CPtr = pool.alloc(8) + arg_vals_rd_g: sizet* = pool.alloc(8) if not (arg_vals_rd_g is None): arg_vals_rd_g[0] = sizet(idx_val) - ret_rd_g: rawptr[llvmlite.Value] = self.Gen.CallGenCall._call_method_on_ptr( + ret_rd_g: 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: rawptr[llvmlite.Value] = llvmlite.build_gep( + elem_ptr_gen: 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, vol_sub_gen) return None # 指针类型: 单索引 GEP + load - elem_ptr4: rawptr[llvmlite.Value] = llvmlite.build_gep( + elem_ptr4: 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, vol_sub_gen) @@ -1099,20 +1120,85 @@ class ExprGenName(ExprGenBase.ExprGenBase): return 1 return 0 - 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) -> rawptr[llvmlite.Value]: + # ============================================================ + # subscript_base_store_kind - 下标基座的**存储形态**(只读,不生成 IR) + # + # 用于区分「数组槽」与「指针所指对象」,只有前者才允许"整对象赋值": + # 1 = 数组存储:t.CArray[T,N] / 内建 Array 形态。元素槽按 sizeof(T) 布局, + # `v[i] = <指向 T 的指针>`(如构造函数返回的临时对象地址)是合法的 + # 整对象复制,不拦。 + # 0 = 指针存储:rawptr[T] 形态(基座元素类型是 Ptr(T),T 为对象)。 + # 元素即所指对象,`p[i] = <指向 T 的指针>` 会静默整对象拷贝 + # (写 sizeof(T) 字节而非 8 字节指针)——可能写穿按 8 字节排布的 + # 缓冲/空闲链表,由调用方 fail-fast。 + # -1 = 无法判定(基座不是可静态定型的 Name / 单层 Attribute):不作为判据, + # 调用方保持既有行为(不误伤,也不新增静默降级)。 + # 分派与 get_subscript_ptr 同源:Name 取变量/全局存储的元素类型, + # Attribute 取字段类型。 + # ============================================================ + def subscript_base_store_kind(self, pool: memhub.MemBuddy*, + trans: HT.Translator*, + node: ast.AST*) -> int: + """下标基座存储形态:1=数组 / 0=指针 / -1=无法判定""" + if node is None or trans is None: + return -1 + sub_bk: ast.Subscript* = ast.Subscript*(node) + if sub_bk is None or sub_bk.value is None: + return -1 + base_ty_bk: llvmlite.LLVMType* = None + if sub_bk.value.kind() == ast.ASTKind.Name: + nm_bk: ast.Name* = ast.Name*(sub_bk.value) + if nm_bk.id is None: + return -1 + alloca_bk: llvmlite.Value* = self.Gen.VarGen.lookup_var( + trans.SymTab, nm_bk.id) + if alloca_bk is None: + alloca_bk = self.Gen.VarGen.lookup_module_var(trans.SymTab, nm_bk.id) + if alloca_bk is None or alloca_bk.Ty is None: + return -1 + if self.is_ptr_type(alloca_bk.Ty) == 0: + return -1 + base_ty_bk = alloca_bk.Ty.Pointee + elif sub_bk.value.kind() == ast.ASTKind.Attribute: + # 单层 obj.field(如 self.arr):非 fatal 只读解析字段类型 + fe_bk: GenTypes.FieldEntry* = \ + self.Gen.ExprGenAttr._resolve_attr_field_entry(pool, trans, sub_bk.value) + if fe_bk is None or fe_bk.Ty is None: + return -1 + base_ty_bk = fe_bk.Ty + else: + return -1 + if base_ty_bk is None: + return -1 + # 基座自身是数组值 → 数组存储 + if self.is_array_type(base_ty_bk) != 0: + return 1 + if self.is_ptr_type(base_ty_bk) != 0: + inner_bk: llvmlite.LLVMType* = base_ty_bk.Pointee + if inner_bk is None: + return -1 + # Ptr(Array) → t.CArray[T,N] 局部/字段(数组存储) + if self.is_array_type(inner_bk) != 0: + return 1 + # Ptr(Struct) → rawptr[T](指针存储) + if inner_bk.kind() == llvmlite.LLVMType.Struct: + return 0 + return -1 + + def get_subscript_ptr(self, builder: llvmlite.IRBuilder*, + pool: memhub.MemBuddy*, + mod: llvmlite.LLVMModule*, + node: ast.AST*, + trans: HT.Translator* = None) -> llvmlite.Value*: """获取下标表达式的元素指针(用于赋值 lhs)""" if node is None or builder is None: return None - sub: rawptr[ast.Subscript] = rawptr[ast.Subscript](node) + sub: ast.Subscript* = ast.Subscript*(node) if sub is None: return None # 翻译索引 - idx_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( + idx_val: llvmlite.Value* = self.Gen.ExprGen.translate_value( builder, pool, mod, sub.slice, None, 0, trans) if idx_val is None: return None @@ -1123,11 +1209,11 @@ 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: rawptr[llvmlite.Value] = self.get_subscript_ptr( + inner_ptr: 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 - inner_elem: rawptr[llvmlite.LLVMType] = inner_ptr.Ty.Pointee + inner_elem: llvmlite.LLVMType* = inner_ptr.Ty.Pointee if inner_elem is None: return None match inner_elem: @@ -1140,17 +1226,17 @@ class ExprGenName(ExprGenBase.ExprGenBase): # 如果 value 是 Name,尝试从 alloca 类型推断 if sub.value is not None and sub.value.kind() == ast.ASTKind.Name: - nm: rawptr[ast.Name] = rawptr[ast.Name](sub.value) + nm: ast.Name* = ast.Name*(sub.value) if nm.id is not None and trans is not None: # nonlocal 数组/指针:从 env 读共享堆地址(提升函数内不能 # lookup_var 外层 alloca——SSA 编号跨函数错乱崩溃) if GenApi.is_nonlocal_name(trans, nm.id) != 0: return self._nonlocal_subscript_ptr( builder, pool, trans, nm.id, idx_val) - alloca: rawptr[llvmlite.Value] = self.Gen.VarGen.lookup_var(trans.SymTab, nm.id) + alloca: 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 + pointee: llvmlite.LLVMType* = alloca.Ty.Pointee if pointee is not None: # 用 match 检查 pointee 类型 match pointee: @@ -1164,7 +1250,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: rawptr[llvmlite.Value] = llvmlite.build_load( + ptr_val_gsp: llvmlite.Value* = llvmlite.build_load( builder, pointee, alloca) if ptr_val_gsp is not None: return llvmlite.build_gep( @@ -1185,7 +1271,7 @@ class ExprGenName(ExprGenBase.ExprGenBase): # 直接 GEP 按 i8* 步长(8 字节),不 load # 仅当 inner_ty 不是自定义结构体时才走指针遍历 if trans is not None: - ve_pe: rawptr[GenTypes.VarEntry] = \ + ve_pe: 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:变量存指针值, @@ -1193,7 +1279,7 @@ class ExprGenName(ExprGenBase.ExprGenBase): # alloca 得指针值,再 GEP——否则 GEP base 用 alloca(&elem_ptr) # 读到栈变量而非数据区,赋值写不进 list 数据 # (data 全 0xbaadf00d,dump 虚调用读错 vtable 崩溃)。 - ptr_val_pe: rawptr[llvmlite.Value] = llvmlite.build_load( + ptr_val_pe: llvmlite.Value* = llvmlite.build_load( builder, pointee, alloca) if ptr_val_pe is not None: # [FIX 2026-08-30] 64 位标量联合(int64|t.CPtr / @@ -1210,7 +1296,7 @@ class ExprGenName(ExprGenBase.ExprGenBase): match pointee: case llvmlite.LLVMType.Int(bits_pe): if bits_pe == 8: - i8_ptr_pe: rawptr[llvmlite.LLVMType] = llvmlite.Ptr( + i8_ptr_pe: llvmlite.LLVMType* = llvmlite.Ptr( pool, llvmlite.Int8(pool)) return llvmlite.build_gep( builder, i8_ptr_pe, ptr_val_pe, idx_val) @@ -1220,11 +1306,11 @@ class ExprGenName(ExprGenBase.ExprGenBase): builder, pointee, ptr_val_pe, idx_val) return None # 普通指针遍历: 先 load 指针值,再 GEP - ptr_val: rawptr[llvmlite.Value] = llvmlite.build_load( + ptr_val: llvmlite.Value* = llvmlite.build_load( builder, pointee, alloca) if ptr_val is None: return None - gep_r: rawptr[llvmlite.Value] = llvmlite.build_gep( + gep_r: llvmlite.Value* = llvmlite.build_gep( builder, inner_ty, ptr_val, idx_val) return gep_r case _: @@ -1235,7 +1321,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: rawptr[GenTypes.VarEntry] = \ + ve_pe_cs: 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)变量 @@ -1243,13 +1329,13 @@ class ExprGenName(ExprGenBase.ExprGenBase): # 得指针值,再按 i8* 步长 GEP——否则 GEP base 用 alloca # (&elem_ptr)算到栈地址,赋值写不进 list 数据区 # (append 只增 count、data 全 0xbaadf00d)。 - ptr_val_cs: rawptr[llvmlite.Value] = llvmlite.build_load( + ptr_val_cs: llvmlite.Value* = llvmlite.build_load( builder, pointee, alloca) if ptr_val_cs is not None: match pointee: case llvmlite.LLVMType.Int(bits_cs): if bits_cs == 8: - i8_ptr_cs: rawptr[llvmlite.LLVMType] = llvmlite.Ptr( + i8_ptr_cs: llvmlite.LLVMType* = llvmlite.Ptr( pool, llvmlite.Int8(pool)) return llvmlite.build_gep( builder, i8_ptr_cs, ptr_val_cs, idx_val) @@ -1261,12 +1347,12 @@ class ExprGenName(ExprGenBase.ExprGenBase): return llvmlite.build_gep(builder, pointee, alloca, idx_val) # 通用路径 - ptr_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( + ptr_val: 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 if self.is_ptr_type(ptr_val.Ty) != 0: - elem_ty2: rawptr[llvmlite.LLVMType] = ptr_val.Ty.Pointee + elem_ty2: llvmlite.LLVMType* = ptr_val.Ty.Pointee if elem_ty2 is not None: # 数组类型: 双索引 GEP (getelementptr [N x ty], ptr, i32 0, i32 idx) match elem_ty2: diff --git a/App/lib/core/Gen/Expr/ExprGenOps.vp b/App/lib/core/Gen/Expr/ExprGenOps.vp index 2ff4eb7..9ec51e4 100644 --- a/App/lib/core/Gen/Expr/ExprGenOps.vp +++ b/App/lib/core/Gen/Expr/ExprGenOps.vp @@ -31,11 +31,11 @@ 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: rawptr[llvmlite.IRBuilder], - pool: rawptr[memhub.MemBuddy], - mod: rawptr[llvmlite.LLVMModule], - node: rawptr[ast.AST], - trans: rawptr[HT.Translator] = None) -> rawptr[llvmlite.Value]: + def translate_ifexp(self, builder: llvmlite.IRBuilder*, + pool: memhub.MemBuddy*, + mod: llvmlite.LLVMModule*, + node: ast.AST*, + trans: HT.Translator* = None) -> llvmlite.Value*: """翻译三元表达式 (body if test else orelse),返回 phi 结果 Value""" if node is None or builder is None or trans is None: return None @@ -43,26 +43,26 @@ class ExprGenOps(ExprGenBase.ExprGenBase): if ie is None: return None - func: rawptr[llvmlite.Function] = trans._cur_func + func: llvmlite.Function* = trans._cur_func if func is None: return None # 1. 求值条件 - cond_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( + cond_val: 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: rawptr[llvmlite.Value] = cond_val + cond_i1: llvmlite.Value* = cond_val else: if self.is_ptr_type(cond_val.Ty) != 0: # 指针类型:与 null 比较 - null_cond: rawptr[llvmlite.Value] = llvmlite.ConstNull(pool, cond_val.Ty, "null") + null_cond: llvmlite.Value* = llvmlite.ConstNull(pool, cond_val.Ty, "null") cond_i1 = llvmlite.build_icmp(builder, llvmlite.ICMP_NE, cond_val, null_cond) else: - zero: rawptr[llvmlite.Value] = llvmlite.const_int32(pool, 0) + zero: llvmlite.Value* = llvmlite.const_int32(pool, 0) cond_i1 = llvmlite.build_icmp(builder, llvmlite.ICMP_NE, cond_val, zero) # 2. 创建三个基本块 @@ -86,7 +86,7 @@ class ExprGenOps(ExprGenBase.ExprGenBase): # 4. then 分支 llvmlite.position_at_end(builder, then_bb) - body_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( + body_val: llvmlite.Value* = self.Gen.ExprGen.translate_value( builder, pool, mod, ie.body, None, 0, trans) then_blk_for_phi: rawptr[llvmlite.BasicBlock] = trans._cur_builder.CurBlock if body_val is None: @@ -102,11 +102,11 @@ class ExprGenOps(ExprGenBase.ExprGenBase): # (VpiReader.vp `rel_path_rt if rel_path_rt is not None else '?'` 根因:then 是 # str(i8*)、else '?' 恒 i32 → CastError)。非指针 then 分支不下传,既有 # 常量物化与位宽行为保持不变。 - orelse_target_ty: rawptr[llvmlite.LLVMType] = None + orelse_target_ty: llvmlite.LLVMType* = None if self.is_ptr_type(body_val.Ty) != 0: orelse_target_ty = body_val.Ty llvmlite.position_at_end(builder, else_bb) - orelse_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( + orelse_val: llvmlite.Value* = self.Gen.ExprGen.translate_value( builder, pool, mod, ie.orelse, None, 0, trans, orelse_target_ty) else_blk_for_phi: rawptr[llvmlite.BasicBlock] = trans._cur_builder.CurBlock if orelse_val is None: @@ -152,7 +152,7 @@ class ExprGenOps(ExprGenBase.ExprGenBase): # 6. merge 块: phi(PHI 是 merge 块的第一条指令) llvmlite.position_at_end(builder, merge_bb) - phi_ty: rawptr[llvmlite.LLVMType] = body_val.Ty + phi_ty: llvmlite.LLVMType* = body_val.Ty if phi_ty is None: # fail-fast:三元表达式分支类型缺失,立即终止编译(暴露上游根因) self.Gen.TypeGenErr.fatal_error(node, "三元表达式分支类型缺失", "TypeError") @@ -172,11 +172,11 @@ class ExprGenOps(ExprGenBase.ExprGenBase): # ============================================================ # 翻译比较表达式 Compare(left, ops, comparators) # ============================================================ - def should_zext_widen(self, pool: rawptr[memhub.MemBuddy], - narrow_val: rawptr[llvmlite.Value], - wide_val: rawptr[llvmlite.Value], - narrow_node: rawptr[ast.AST] = None, - trans: rawptr[HT.Translator] = None) -> int: + def should_zext_widen(self, pool: memhub.MemBuddy*, + narrow_val: llvmlite.Value*, + wide_val: llvmlite.Value*, + narrow_node: ast.AST* = None, + trans: HT.Translator* = None) -> int: """判断整数拓宽方向:1=zext(无符号语义),0=sext **拓宽方向的单一真源**:ExprGenBase._zext_or_sext_val(coerce 路径)委托到此。 @@ -233,16 +233,16 @@ class ExprGenOps(ExprGenBase.ExprGenBase): # 全 FAIL 根因)。负值 CDefine(如 -1)不在此区间(-1 > 0x7FFFFFFF 为假), # 保持 sext 语义不变。 if narrow_node is not None and narrow_node.kind() == ast.ASTKind.Name: - cdef_nm_zw: rawptr[ast.Name] = rawptr[ast.Name](narrow_node) + cdef_nm_zw: ast.Name* = ast.Name*(narrow_node) if cdef_nm_zw.id is not None: cdv_zw: int64 = self.Gen.TypeGenCDef.lookup_cdefine_constant(cdef_nm_zw.id) if self.Gen.TypeGenCDef.is_cdefine_found() != 0: if cdv_zw > 0x7FFFFFFF: return 1 return 0 - def _node_type_unsigned(self, pool: rawptr[memhub.MemBuddy], - node: rawptr[ast.AST], - trans: rawptr[HT.Translator] = None) -> int: + def _node_type_unsigned(self, pool: memhub.MemBuddy*, + node: ast.AST*, + trans: HT.Translator* = None) -> int: """轻量判断 AST 节点是否解析为无符号整数类型(1=是,0=否/未知) 覆盖常见形态(对齐 TPC _check_node_unsigned 的 Call/Subscript 分支): @@ -254,25 +254,25 @@ class ExprGenOps(ExprGenBase.ExprGenBase): return 0 k: int = node.kind() if k == ast.ASTKind.Call: - cl: rawptr[ast.Call] = rawptr[ast.Call](node) + cl: ast.Call* = ast.Call*(node) if cl.func is not None and cl.func.kind() == ast.ASTKind.Attribute: - at: rawptr[ast.Attribute] = rawptr[ast.Attribute](cl.func) + at: ast.Attribute* = ast.Attribute*(cl.func) if at.value is not None and at.value.kind() == ast.ASTKind.Name: - mod_nm: rawptr[ast.Name] = rawptr[ast.Name](at.value) + mod_nm: ast.Name* = ast.Name*(at.value) if mod_nm.id is not None and string.strcmp(mod_nm.id, "t") == 0 \ and at.attr is not None: if self._type_name_unsigned(at.attr) != 0: return 1 return 0 if k == ast.ASTKind.Name: - nm: rawptr[ast.Name] = rawptr[ast.Name](node) + nm: ast.Name* = ast.Name*(node) if nm.id is not None: # 1) 名字本身是无符号类型名(如 UInt32T 别名) if self._type_name_unsigned(nm.id) != 0: return 1 # 2) 变量注解类型为无符号类型(trans 可用时查 SymTab) if trans is not None: - ve: rawptr[GenTypes.VarEntry] = self.Gen.VarGen.lookup_var_entry( + ve: GenTypes.VarEntry* = self.Gen.VarGen.lookup_var_entry( trans.SymTab, nm.id) if ve is not None: # [S4 切读] Spec 明确无符号(TS_UINT)优先于字符串判定 @@ -284,25 +284,25 @@ class ExprGenOps(ExprGenBase.ExprGenBase): return 1 return 0 if k == ast.ASTKind.BinOp: - bop: rawptr[ast.BinOp] = rawptr[ast.BinOp](node) + bop: ast.BinOp* = ast.BinOp*(node) if self._node_type_unsigned(pool, bop.left, trans) != 0: return 1 if self._node_type_unsigned(pool, bop.right, trans) != 0: return 1 return 0 if k == ast.ASTKind.UnaryOp: - uop: rawptr[ast.UnaryOp] = rawptr[ast.UnaryOp](node) + uop: ast.UnaryOp* = ast.UnaryOp*(node) if self._node_type_unsigned(pool, uop.operand, trans) != 0: return 1 return 0 if k == ast.ASTKind.Subscript: # 数组/指针下标: md5_buf[i](t.CArray[uint8, N])或 buf[i] # (形参 uint8 | t.CPtr)元素是无符号整型 → printf("%02x", ...) zext。 - sub_su: rawptr[ast.Subscript] = rawptr[ast.Subscript](node) + sub_su: ast.Subscript* = ast.Subscript*(node) 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) + snm_su: ast.Name* = ast.Name*(sub_su.value) if snm_su.id is not None and trans is not None: - ve_su: rawptr[GenTypes.VarEntry] = self.Gen.VarGen.lookup_var_entry( + ve_su: GenTypes.VarEntry* = self.Gen.VarGen.lookup_var_entry( trans.SymTab, snm_su.id) if ve_su is not None: # [S4 切读] Spec 明确无符号优先(数组元素为无符号的联合注解场景 @@ -316,13 +316,13 @@ class ExprGenOps(ExprGenBase.ExprGenBase): return 0 if k == ast.ASTKind.Attribute: # 结构体字段(如 viperio.Buf 的 self.capacity/length: sizet):经接收者变量的 AnnotClassName 取类名,再按类名+字段名查字段注解,判定无符号(CSizeT/uint*)。本函数在 translate_binop 对每个操作数调用,必须只读、失败返回 0——故不走 lookup_field_by_class(其模块限定名分支会 fatal_error),改用 find_struct + 自遍历字段(未命中一律返回 0) - at_u: rawptr[ast.Attribute] = rawptr[ast.Attribute](node) + at_u: ast.Attribute* = ast.Attribute*(node) if at_u.value is not None and at_u.attr is not None and trans is not None: cls_nm_u: str = None if at_u.value.kind() == ast.ASTKind.Name: - vn_u: rawptr[ast.Name] = rawptr[ast.Name](at_u.value) + vn_u: ast.Name* = ast.Name*(at_u.value) if vn_u.id is not None: - ve_u: rawptr[GenTypes.VarEntry] = self.Gen.VarGen.lookup_var_entry( + ve_u: 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: rawptr[GenTypes.StructEntry] = self.Gen.StructGen.find_struct(bare_u) + st_u: 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: rawptr[GenTypes.FieldEntry] = \ + fe_u: 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: @@ -352,9 +352,9 @@ class ExprGenOps(ExprGenBase.ExprGenBase): fi_u += 1 return 0 return 0 - def _node_type_signed(self, pool: rawptr[memhub.MemBuddy], - node: rawptr[ast.AST], - trans: rawptr[HT.Translator] = None) -> int: + def _node_type_signed(self, pool: memhub.MemBuddy*, + node: ast.AST*, + trans: HT.Translator* = None) -> int: """源节点是否**明确有符号**整数(独立真源的 SIGNED 分支;未知返回 0) 只服务 should_zext_widen 的 i8 分支:i8 默认按「无符号字节」zext, @@ -367,23 +367,23 @@ class ExprGenOps(ExprGenBase.ExprGenBase): return 0 k: int = node.kind() if k == ast.ASTKind.Call: - cl: rawptr[ast.Call] = rawptr[ast.Call](node) + cl: ast.Call* = ast.Call*(node) if cl.func is not None and cl.func.kind() == ast.ASTKind.Attribute: - at: rawptr[ast.Attribute] = rawptr[ast.Attribute](cl.func) + at: ast.Attribute* = ast.Attribute*(cl.func) if at.value is not None and at.value.kind() == ast.ASTKind.Name: - mod_nm: rawptr[ast.Name] = rawptr[ast.Name](at.value) + mod_nm: ast.Name* = ast.Name*(at.value) if mod_nm.id is not None and string.strcmp(mod_nm.id, "t") == 0 \ and at.attr is not None: if self._spec_sign_from_annot(at.attr) == TSpec.TS_SIGN_SIGNED: return 1 return 0 if k == ast.ASTKind.Name: - nm: rawptr[ast.Name] = rawptr[ast.Name](node) + nm: ast.Name* = ast.Name*(node) if nm.id is not None: if self._spec_sign_from_annot(nm.id) == TSpec.TS_SIGN_SIGNED: return 1 if trans is not None: - ve: rawptr[GenTypes.VarEntry] = self.Gen.VarGen.lookup_var_entry( + ve: 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) @@ -392,11 +392,11 @@ class ExprGenOps(ExprGenBase.ExprGenBase): return 1 return 0 if k == ast.ASTKind.Subscript: - sub_s: rawptr[ast.Subscript] = rawptr[ast.Subscript](node) + sub_s: ast.Subscript* = ast.Subscript*(node) 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) + snm: ast.Name* = ast.Name*(sub_s.value) if snm.id is not None and trans is not None: - ve_s: rawptr[GenTypes.VarEntry] = self.Gen.VarGen.lookup_var_entry( + ve_s: 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: rawptr[TSpec.TypeSpec]) -> int: + def _entry_spec_unsigned(self, sp: TSpec.TypeSpec*) -> int: """Spec 是否明确无符号整数(TS_UINT);其它一律 0(未表态/不适用)""" if sp is None: return 0 @@ -464,11 +464,11 @@ class ExprGenOps(ExprGenBase.ExprGenBase): if self._spec_sign_from_annot(annot) == TSpec.TS_SIGN_UNSIGNED: return 1 return 0 - 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) -> rawptr[llvmlite.Value]: + def translate_compare(self, builder: llvmlite.IRBuilder*, + pool: memhub.MemBuddy*, + mod: llvmlite.LLVMModule*, + node: ast.AST*, + trans: HT.Translator* = None) -> llvmlite.Value*: """翻译比较表达式,返回 i1 结果""" cmp: rawptr[ast.Compare] = rawptr[ast.Compare](node) if cmp is None: @@ -482,8 +482,8 @@ class ExprGenOps(ExprGenBase.ExprGenBase): comparators: list[ast.AST*]* = cmp.comparators if comparators is None or len(comparators) == 0: return None - rhs_node: rawptr[ast.AST] = comparators.get(0) - rhs: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( + rhs_node: ast.AST* = comparators.get(0) + rhs: llvmlite.Value* = self.Gen.ExprGen.translate_value( builder, pool, mod, rhs_node, None, 0, trans) if rhs is None: return None @@ -492,15 +492,15 @@ class ExprGenOps(ExprGenBase.ExprGenBase): # 避免对结构体指针生成无效的 __eq__/__ne__ 调用(方法未定义但类有 SHA1 时 # try_operator_overload 会误生成 call void @...__eq__(...) 导致链接错误) # 语义依据: Python 中 == None / != None 默认走身份比较,不调用 __eq__/__ne__ - lhs_node: rawptr[ast.AST] = cmp.left + lhs_node: ast.AST* = cmp.left cmp_with_none: int = 0 if op == ast.OpKind.Eq or op == ast.OpKind.Ne or op == ast.OpKind.Is or op == ast.OpKind.IsNot: if rhs_node is not None and rhs_node.kind() == ast.ASTKind.Constant: - rhs_cn: rawptr[ast.Constant] = rawptr[ast.Constant](rhs_node) + rhs_cn: ast.Constant* = ast.Constant*(rhs_node) if rhs_cn is not None and rhs_cn.const_kind == ast.CONST_NONE: cmp_with_none = 1 if cmp_with_none == 0 and lhs_node is not None and lhs_node.kind() == ast.ASTKind.Constant: - lhs_cn: rawptr[ast.Constant] = rawptr[ast.Constant](lhs_node) + lhs_cn: ast.Constant* = ast.Constant*(lhs_node) if lhs_cn is not None and lhs_cn.const_kind == ast.CONST_NONE: cmp_with_none = 1 @@ -521,28 +521,28 @@ class ExprGenOps(ExprGenBase.ExprGenBase): # 对于值类型变量(如 cnt: Counter),用 alloca 指针尝试重载 # None 比较跳过重载(走身份比较) 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) + nm: ast.Name* = ast.Name*(lhs_node) if nm is not None and nm.id is not None: - lhs_alloca: rawptr[llvmlite.Value] = self.Gen.VarGen.lookup_var( + lhs_alloca: 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: rawptr[llvmlite.Value] = lhs_alloca + ovl_self1: 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 \ + if lhs_alloca.Ty is not None and lhs_alloca.Ty.Pointee != 0 \ and self.Gen.ExprGenBase.is_ptr_type(lhs_alloca.Ty.Pointee) != 0: - load_self1: rawptr[llvmlite.Value] = llvmlite.build_load( + load_self1: llvmlite.Value* = llvmlite.build_load( builder, lhs_alloca.Ty.Pointee, lhs_alloca) if load_self1 is not None: ovl_self1 = load_self1 - ovl_result: rawptr[llvmlite.Value] = self.try_operator_overload( + ovl_result: 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: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( + lhs: llvmlite.Value* = self.Gen.ExprGen.translate_value( builder, pool, mod, cmp.left, None, 0, trans) if lhs is None: return None @@ -552,39 +552,39 @@ class ExprGenOps(ExprGenBase.ExprGenBase): # x not in y → !y.__contains__(x)。容器无 __contains__ → # 返回 i1 0(TPC 同:恒 False)。 if op == ast.OpKind.In or op == ast.OpKind.NotIn: - cn_st: rawptr[llvmlite.LLVMType] = self.Gen.StructGen.get_struct_type_from_value(rhs) + cn_st: llvmlite.LLVMType* = self.Gen.StructGen.get_struct_type_from_value(rhs) if cn_st is not None: cn_cls: str = self.Gen.StructGen.get_class_name_by_type(pool, cn_st) if cn_cls is not None: cn_lookup: str = pool.alloc(128) if cn_lookup is not None: viperlib.snprintf(cn_lookup, 128, "%s.__contains__", cn_cls) - cn_fn: rawptr[llvmlite.Function] = self.Gen.CallGenBase.find_func_in_module( + cn_fn: llvmlite.Function* = self.Gen.CallGenBase.find_func_in_module( mod, cn_lookup) if cn_fn is not None: - cn_ret: rawptr[llvmlite.LLVMType] = llvmlite.function_get_ret_ty(cn_fn) + cn_ret: llvmlite.LLVMType* = llvmlite.function_get_ret_ty(cn_fn) 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: rawptr[llvmlite.Value] = rhs - cn_first: rawptr[llvmlite.Param] = llvmlite.function_get_param_head(cn_fn) + cn_self: llvmlite.Value* = rhs + cn_first: 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) + cn_self_ty: llvmlite.LLVMType* = llvmlite.param_get_ty(cn_first) if cn_self_ty is not None: cn_self = llvmlite.build_bitcast(builder, rhs, cn_self_ty) if cn_self is not None: # 参数链表: self → key(独立 null 结尾) cn_self.Next = lhs lhs.Next = None - cn_res: rawptr[llvmlite.Value] = llvmlite.build_call( + cn_res: 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: rawptr[llvmlite.Value] = cn_res + cn_i1: llvmlite.Value* = cn_res match cn_ret: case llvmlite.LLVMType.Int(cn_bits): if cn_bits > 1: - cn_zero: rawptr[llvmlite.Value] = llvmlite.ConstInt( + cn_zero: llvmlite.Value* = llvmlite.ConstInt( pool, cn_ret, 0, "0") if cn_zero is not None: cn_i1 = llvmlite.build_icmp( @@ -592,16 +592,16 @@ class ExprGenOps(ExprGenBase.ExprGenBase): case _: pass if op == ast.OpKind.NotIn: - i1_ty_ni: rawptr[llvmlite.LLVMType] = llvmlite.Int1(pool) + i1_ty_ni: llvmlite.LLVMType* = llvmlite.Int1(pool) if i1_ty_ni is not None and cn_i1 is not None: - one_i1_ni: rawptr[llvmlite.Value] = llvmlite.ConstInt( + one_i1_ni: 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) if cn_i1 is not None: return cn_i1 # 容器无 __contains__:TPC 语义恒 False(i1 0) - i1_ty_in: rawptr[llvmlite.LLVMType] = llvmlite.Int1(pool) + i1_ty_in: llvmlite.LLVMType* = llvmlite.Int1(pool) if i1_ty_in is not None: return llvmlite.ConstInt(pool, i1_ty_in, 0, "0") return None @@ -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: rawptr[llvmlite.Value] = self.try_operator_overload( + ovl_result2: 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: rawptr[llvmlite.IRBuilder], - pool: rawptr[memhub.MemBuddy], - mod: rawptr[llvmlite.LLVMModule], - node: rawptr[ast.AST], - trans: rawptr[HT.Translator] = None) -> rawptr[llvmlite.Value]: + def translate_unaryop(self, builder: llvmlite.IRBuilder*, + pool: memhub.MemBuddy*, + mod: llvmlite.LLVMModule*, + node: ast.AST*, + trans: HT.Translator* = None) -> llvmlite.Value*: """翻译一元运算(-x, +x, not x, ~x)""" - uo: rawptr[ast.UnaryOp] = rawptr[ast.UnaryOp](node) + uo: ast.UnaryOp* = ast.UnaryOp*(node) if uo is None: return None - operand: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( + operand: 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: rawptr[llvmlite.Value] = self.try_unary_operator_overload( + ovl_u: 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: rawptr[llvmlite.Value] = llvmlite.const_int32(pool, 0) + zero: 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: rawptr[llvmlite.Value] = llvmlite.ConstNull(pool, operand.Ty, "null") + null_op: 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,14 +843,14 @@ 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: rawptr[llvmlite.Value] = llvmlite.const_int32(pool, -1) + neg1: 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) elif uo.op == ast.OpKind.Deref: # *p → load 按 pointee 类型读取(对齐 translate_c_deref) if self.Gen.ExprGenBase.is_ptr_type(operand.Ty) != 0: - d_pointee: rawptr[llvmlite.LLVMType] = operand.Ty.Pointee + d_pointee: llvmlite.LLVMType* = operand.Ty.Pointee if d_pointee is not None: return llvmlite.build_load(builder, d_pointee, operand) # 非指针即类型推断退化:fail-fast,绝不按 i8 兜底读取 @@ -863,28 +863,28 @@ class ExprGenOps(ExprGenBase.ExprGenBase): if trans is None: return None if uo.operand.kind() == ast.ASTKind.Name: - nm_ao: rawptr[ast.Name] = rawptr[ast.Name](uo.operand) + nm_ao: ast.Name* = ast.Name*(uo.operand) if nm_ao.id is not None: # 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: rawptr[GenTypes.VarEntry] = self.Gen.VarGen.lookup_var_entry( + se_ao: 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: case llvmlite.LLVMType.Ptr(sa1): match sa1: case llvmlite.LLVMType.Ptr(sa2): - obj_ty_sa: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, sa2) + obj_ty_sa: llvmlite.LLVMType* = llvmlite.Ptr(pool, sa2) return llvmlite.build_load(builder, obj_ty_sa, se_ao.Alloca) case _: pass case _: pass - v_ao: rawptr[llvmlite.Value] = self.Gen.VarGen.lookup_var(trans.SymTab, nm_ao.id) + v_ao: 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: rawptr[llvmlite.GlobalVariable] = self.Gen.ExprGenAttr.find_global_in_module(mod, nm_ao.id) + gv_ao: 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: @@ -896,7 +896,7 @@ class ExprGenOps(ExprGenBase.ExprGenBase): case llvmlite.LLVMType.Ptr(ao2): match ao2: case llvmlite.LLVMType.Struct(_, _, _): - obj_ty_ao: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, ao2) + obj_ty_ao: llvmlite.LLVMType* = llvmlite.Ptr(pool, ao2) return llvmlite.build_load(builder, obj_ty_ao, v_ao) case _: pass @@ -907,17 +907,17 @@ class ExprGenOps(ExprGenBase.ExprGenBase): return v_ao # 模块函数地址:函数符号本身 if v_ao is None and mod is not None: - f_ao: rawptr[llvmlite.Function] = self.Gen.CallGenBase.find_func_in_module(mod, nm_ao.id) + f_ao: llvmlite.Function* = self.Gen.CallGenBase.find_func_in_module(mod, nm_ao.id) if f_ao is not None: fname_ao: str = llvmlite.function_get_name(f_ao) if fname_ao is not None: - p_head_ao: rawptr[llvmlite.Param] = llvmlite.function_get_param_head(f_ao) + p_head_ao: llvmlite.Param* = llvmlite.function_get_param_head(f_ao) p_cnt_ao: sizet = 0 - p_cur_ao: rawptr[llvmlite.Param] = p_head_ao + p_cur_ao: 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) - fn_ty_ao: rawptr[llvmlite.LLVMType] = llvmlite.Func(pool, f_ao.RetTy, p_head_ao, p_cnt_ao) + fn_ty_ao: llvmlite.LLVMType* = llvmlite.Func(pool, f_ao.RetTy, p_head_ao, p_cnt_ao) # 函数引用名按需加引号(数字开头/含 '.' 的 sha1 前缀名) fnlen_ao: sizet = string.strlen(fname_ao) needs_q_ao: int = self.Gen.ClassGenVTable._vtable_name_needs_quote(fname_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: rawptr[llvmlite.Value] = self.Gen.ExprGenAttr.get_attribute_ptr( + fptr_ao: 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: rawptr[llvmlite.Value] = self.Gen.ExprGenName.get_subscript_ptr( + sptr_ao: llvmlite.Value* = self.Gen.ExprGenName.get_subscript_ptr( builder, pool, mod, uo.operand, trans) if sptr_ao is not None: return sptr_ao @@ -953,13 +953,13 @@ class ExprGenOps(ExprGenBase.ExprGenBase): # 最后一个值直接求值并跳 merge # merge 块用 phi 合并所有入边的 i1 # ============================================================ - def translate_boolop(self, builder: rawptr[llvmlite.IRBuilder], - pool: rawptr[memhub.MemBuddy], - mod: rawptr[llvmlite.LLVMModule], - node: rawptr[ast.AST], + def translate_boolop(self, builder: llvmlite.IRBuilder*, + pool: memhub.MemBuddy*, + mod: llvmlite.LLVMModule*, + node: ast.AST*, funcs_ptr: t.CPtr = None, func_count: int = 0, - trans: rawptr[HT.Translator] = None) -> rawptr[llvmlite.Value]: + trans: HT.Translator* = None) -> llvmlite.Value*: """翻译布尔运算(and/or)的短路求值,返回 i1""" bo: rawptr[ast.BoolOp] = rawptr[ast.BoolOp](node) if bo is None: @@ -976,7 +976,7 @@ class ExprGenOps(ExprGenBase.ExprGenBase): return self.Gen.ExprGen.translate_value(builder, pool, mod, values.get(0), funcs_ptr, func_count, trans) - func: rawptr[llvmlite.Function] = builder.Func + func: llvmlite.Function* = builder.Func if func is None: return None @@ -997,8 +997,8 @@ class ExprGenOps(ExprGenBase.ExprGenBase): # 对每个值(除最后一个)求值并短路 for i in range(count - 1): - val_node: rawptr[ast.AST] = values.get(i) - val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( + val_node: ast.AST* = values.get(i) + val: llvmlite.Value* = self.Gen.ExprGen.translate_value( builder, pool, mod, val_node, funcs_ptr, func_count, trans) if val is None: @@ -1006,14 +1006,14 @@ class ExprGenOps(ExprGenBase.ExprGenBase): # 转为 i1(已经是 i1 的直接用,否则与 0/null 比较) val_bits: int = self.get_llvm_type_bits(val.Ty) - val_i1: rawptr[llvmlite.Value] = val + val_i1: llvmlite.Value* = val if val_bits != 1: if self.is_ptr_type(val.Ty) != 0: # 指针类型:与 null 比较(避免 i8* 与 i32 类型不匹配) - null_val: rawptr[llvmlite.Value] = llvmlite.ConstNull(pool, val.Ty, "null") + null_val: llvmlite.Value* = llvmlite.ConstNull(pool, val.Ty, "null") val_i1 = llvmlite.build_icmp(builder, llvmlite.ICMP_NE, val, null_val) else: - zero: rawptr[llvmlite.Value] = llvmlite.const_int32(pool, 0) + zero: llvmlite.Value* = llvmlite.const_int32(pool, 0) val_i1 = llvmlite.build_icmp(builder, llvmlite.ICMP_NE, val, zero) # 创建 next BB(求值下一个值) @@ -1042,18 +1042,18 @@ class ExprGenOps(ExprGenBase.ExprGenBase): llvmlite.position_at_end(builder, next_bb) # 最后一个值:求值后直接跳 merge - last_node: rawptr[ast.AST] = values.get(count - 1) - last_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( + last_node: ast.AST* = values.get(count - 1) + last_val: 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: rawptr[llvmlite.Value] = last_val + last_i1: llvmlite.Value* = last_val if last_bits != 1: if self.is_ptr_type(last_val.Ty) != 0: # 指针类型:与 null 比较(避免 i8* 与 i32 类型不匹配) - null_val2: rawptr[llvmlite.Value] = llvmlite.ConstNull(pool, last_val.Ty, "null") + null_val2: 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) @@ -1071,7 +1071,7 @@ class ExprGenOps(ExprGenBase.ExprGenBase): # 定位到 merge,创建 phi 合并所有入边 llvmlite.position_at_end(builder, merge_bb) - i1_ty: rawptr[llvmlite.LLVMType] = llvmlite.Int1(pool) + i1_ty: llvmlite.LLVMType* = llvmlite.Int1(pool) return llvmlite.build_phi(builder, i1_ty, phi_head, phi_count) # ============================================================ # BinOp 运算符 → dunder 方法名 @@ -1121,14 +1121,14 @@ class ExprGenOps(ExprGenBase.ExprGenBase): # dunder 方法。找到则生成方法调用 lhs.__dunder__(rhs),返回 # 调用结果;未找到返回 None,调用方回退到原生运算。 # ============================================================ - def try_operator_overload(self, pool: rawptr[memhub.MemBuddy], - builder: rawptr[llvmlite.IRBuilder], - mod: rawptr[llvmlite.LLVMModule], - lhs: rawptr[llvmlite.Value], - rhs: rawptr[llvmlite.Value], + def try_operator_overload(self, pool: memhub.MemBuddy*, + builder: llvmlite.IRBuilder*, + mod: llvmlite.LLVMModule*, + lhs: llvmlite.Value*, + rhs: llvmlite.Value*, op: int, - trans: rawptr[HT.Translator], - is_compare: int) -> rawptr[llvmlite.Value]: + trans: HT.Translator*, + is_compare: int) -> llvmlite.Value*: """尝试运算符重载:lhs 是结构体指针时调用 dunder 方法,否则返回 None""" if lhs is None or rhs is None: return None @@ -1142,7 +1142,7 @@ class ExprGenOps(ExprGenBase.ExprGenBase): return None # 检查 lhs 是否为结构体指针 - struct_ty: rawptr[llvmlite.LLVMType] = self.Gen.StructGen.get_struct_type_from_value(lhs) + struct_ty: llvmlite.LLVMType* = self.Gen.StructGen.get_struct_type_from_value(lhs) if struct_ty is None: return None @@ -1156,12 +1156,12 @@ class ExprGenOps(ExprGenBase.ExprGenBase): if lookup_name is None: return None viperlib.snprintf(lookup_name, 128, "%s.%s", class_name, dunder) - found_func: rawptr[llvmlite.Function] = self.Gen.CallGenBase.find_func_in_module(mod, lookup_name) + found_func: llvmlite.Function* = self.Gen.CallGenBase.find_func_in_module(mod, lookup_name) search_class: str = class_name if found_func is None: # 多继承:沿 MRO 祖先链查找(先声明父类优先) - mro_ptr: sizet | t.CPtr = self.Gen.StructGen.get_mro_chain(pool, class_name) + mro_ptr: sizet* = self.Gen.StructGen.get_mro_chain(pool, class_name) mi: int = 1 while mro_ptr is not None and mro_ptr[mi] != 0: anc: str = (str | t.CPtr)(mro_ptr[mi]) @@ -1169,7 +1169,7 @@ class ExprGenOps(ExprGenBase.ExprGenBase): parent_lookup: str = pool.alloc(128) if parent_lookup is not None: viperlib.snprintf(parent_lookup, 128, "%s.%s", anc, dunder) - parent_func: rawptr[llvmlite.Function] = self.Gen.CallGenBase.find_func_in_module(mod, parent_lookup) + parent_func: llvmlite.Function* = self.Gen.CallGenBase.find_func_in_module(mod, parent_lookup) if parent_func is not None: found_func = parent_func search_class = anc @@ -1179,13 +1179,13 @@ class ExprGenOps(ExprGenBase.ExprGenBase): # 方法不在当前模块中时,检查类(含父类)是否有 SHA1(stub 可能未注入) # 优先用类型指针定位 entry 获取 SHA1(规避跨模块同名 find_struct 找错) cls_sha1: str = None - op_entry: rawptr[GenTypes.StructEntry] = self.Gen.StructGen.find_struct_by_type(struct_ty) + op_entry: 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: cls_sha1 = self.Gen.StructGen.get_struct_sha1(search_class) if cls_sha1 is None: - mro_p: sizet | t.CPtr = self.Gen.StructGen.get_mro_chain(pool, search_class) + mro_p: sizet* = self.Gen.StructGen.get_mro_chain(pool, search_class) mj: int = 1 while mro_p is not None and mro_p[mj] != 0 and cls_sha1 is None: anc_p: str = (str | t.CPtr)(mro_p[mj]) @@ -1208,13 +1208,13 @@ class ExprGenOps(ExprGenBase.ExprGenBase): # vpi 未命中(依赖模块确实无此 dunder)→ 回退原生比较(icmp), # 绝不发幽灵 call——`call @{cls_sha1}.{Class}.{dunder}` 链接 undefined # (MemBuddy 无 __eq__ 时 os._mbuddy == sys._mbuddy,SysLibTest 根因)。 - vpi_dup: rawptr[llvmlite.LLVMType] = self.Gen.CallGenBase._lookup_method_ret_ty_via_vpi( + vpi_dup: llvmlite.LLVMType* = self.Gen.CallGenBase._lookup_method_ret_ty_via_vpi( pool, cls_sha1, search_class, dunder) if vpi_dup is None: return None # 构建 extra_args 数组(仅含 rhs 一个参数) - extra_args: sizet | t.CPtr = pool.alloc(8) + extra_args: sizet* = pool.alloc(8) if extra_args is None: return None extra_args[0] = sizet(rhs) @@ -1230,12 +1230,12 @@ class ExprGenOps(ExprGenBase.ExprGenBase): # dunder 方法(__neg__/__pos__/__invert__)。找到则生成方法调用 # operand.__dunder__(),返回调用结果;未找到返回 None,调用方回退到原生运算。 # ============================================================ - def try_unary_operator_overload(self, pool: rawptr[memhub.MemBuddy], - builder: rawptr[llvmlite.IRBuilder], - mod: rawptr[llvmlite.LLVMModule], - operand: rawptr[llvmlite.Value], + def try_unary_operator_overload(self, pool: memhub.MemBuddy*, + builder: llvmlite.IRBuilder*, + mod: llvmlite.LLVMModule*, + operand: llvmlite.Value*, op: int, - trans: rawptr[HT.Translator]) -> rawptr[llvmlite.Value]: + trans: HT.Translator*) -> llvmlite.Value*: """尝试一元运算符重载:operand 是结构体指针时调用 dunder 方法,否则返回 None""" if operand is None: return None @@ -1244,7 +1244,7 @@ class ExprGenOps(ExprGenBase.ExprGenBase): return None # 检查 operand 是否为结构体指针 - struct_ty: rawptr[llvmlite.LLVMType] = self.Gen.StructGen.get_struct_type_from_value(operand) + struct_ty: llvmlite.LLVMType* = self.Gen.StructGen.get_struct_type_from_value(operand) if struct_ty is None: return None @@ -1258,12 +1258,12 @@ class ExprGenOps(ExprGenBase.ExprGenBase): if lookup_name is None: return None viperlib.snprintf(lookup_name, 128, "%s.%s", class_name, dunder) - found_func: rawptr[llvmlite.Function] = self.Gen.CallGenBase.find_func_in_module(mod, lookup_name) + found_func: llvmlite.Function* = self.Gen.CallGenBase.find_func_in_module(mod, lookup_name) search_class: str = class_name if found_func is None: # 多继承:沿 MRO 祖先链查找(先声明父类优先) - mro_ptr: sizet | t.CPtr = self.Gen.StructGen.get_mro_chain(pool, class_name) + mro_ptr: sizet* = self.Gen.StructGen.get_mro_chain(pool, class_name) mi: int = 1 while mro_ptr is not None and mro_ptr[mi] != 0: anc: str = (str | t.CPtr)(mro_ptr[mi]) @@ -1271,7 +1271,7 @@ class ExprGenOps(ExprGenBase.ExprGenBase): parent_lookup: str = pool.alloc(128) if parent_lookup is not None: viperlib.snprintf(parent_lookup, 128, "%s.%s", anc, dunder) - parent_func: rawptr[llvmlite.Function] = self.Gen.CallGenBase.find_func_in_module(mod, parent_lookup) + parent_func: llvmlite.Function* = self.Gen.CallGenBase.find_func_in_module(mod, parent_lookup) if parent_func is not None: found_func = parent_func search_class = anc @@ -1280,13 +1280,13 @@ class ExprGenOps(ExprGenBase.ExprGenBase): # 方法不在当前模块中时,检查类(含父类)是否有 SHA1(stub 可能未注入) cls_sha1: str = None - uop_entry: rawptr[GenTypes.StructEntry] = self.Gen.StructGen.find_struct_by_type(struct_ty) + uop_entry: 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: cls_sha1 = self.Gen.StructGen.get_struct_sha1(search_class) if cls_sha1 is None: - mro_p: sizet | t.CPtr = self.Gen.StructGen.get_mro_chain(pool, search_class) + mro_p: sizet* = self.Gen.StructGen.get_mro_chain(pool, search_class) mj: int = 1 while mro_p is not None and mro_p[mj] != 0 and cls_sha1 is None: anc_p: str = (str | t.CPtr)(mro_p[mj]) @@ -1309,24 +1309,102 @@ class ExprGenOps(ExprGenBase.ExprGenBase): pool, builder, mod, search_class, dunder, operand, None, 0, trans) # ============================================================ + # fail_if_double_ptr_binop - 双指针算术 fail-fast(**唯一实现**) + # + # BinOp(translate_binop)与 AugAssign(AssignGenMixin._apply_aug_op)共用此 + # 判据与报文,避免两处各写一份导致分叉(此前只有 translate_binop 有一份, + # 且只覆盖 Add/Sub,AugAssign 与 Mult/Div/Mod/Shift 均未受保护)。 + # + # 判据:运算符属二元算术/位运算/移位集合 **且** 两操作数都是 LLVM 指针。 + # 本语言的 str 是 i8*,没有 `+` 拼接语义;指针 ± 指针也不是 GEP 语义 + # (GEP 只接受「一指针一整数」,由调用方在此之前用 translate_ptr_arith 分流)。 + # 落到 build_add/build_sub/… 会直出非法 IR(`add i8*, i8*` ⇒ opt 报 + # invalid operand type for instruction),故在 IR 生成前 fail-fast。 + # + # is_aug != 0 表示增量赋值(+=、-=、…):报文把符号补成 "+=" 形态并标注 + # 「(增量赋值)」,避免只报裸 "+",便于定位。 + # 命中即 fatal_error 终止编译;未命中返回 0。 + # ============================================================ + def fail_if_double_ptr_binop(self, pool: memhub.MemBuddy*, + op: int, + lhs: llvmlite.Value*, + rhs: llvmlite.Value*, + node: ast.AST* = None, + is_aug: int = 0) -> int: + """双指针算术 fail-fast;命中即终止编译,未命中返回 0""" + if lhs is None or rhs is None: + return 0 + if self.is_ptr_type(lhs.Ty) == 0 or self.is_ptr_type(rhs.Ty) == 0: + return 0 + op_ch: str = None + if op == ast.OpKind.Add: op_ch = "+" + elif op == ast.OpKind.Sub: op_ch = "-" + elif op == ast.OpKind.Mult: op_ch = "*" + elif op == ast.OpKind.Div: op_ch = "/" + elif op == ast.OpKind.FloorDiv: op_ch = "//" + elif op == ast.OpKind.Mod: op_ch = "%" + elif op == ast.OpKind.Pow: op_ch = "**" + elif op == ast.OpKind.BitAnd: op_ch = "&" + elif op == ast.OpKind.BitOr: op_ch = "|" + elif op == ast.OpKind.BitXor: op_ch = "^" + elif op == ast.OpKind.LShift: op_ch = "<<" + elif op == ast.OpKind.RShift: op_ch = ">>" + else: + return 0 + op_lbl: str = op_ch + aug_note: str = "" + if is_aug != 0: + # 增量赋值:用 f-string 拼 "+=" 形态(本语言 str 无 `+` 拼接语义, + # 禁止 op_ch + "=" 这种裸字符串加法) + op_lbl = f"{op_ch}=" + aug_note = "(增量赋值)" + lty_buf: str = pool.alloc(64) + rty_buf: str = pool.alloc(64) + lty_lbl: str = "?" + rty_lbl: str = "?" + if lty_buf is not None: + llvmlite.TypePrint(lty_buf, 64, lhs.Ty, pool) + lty_lbl = lty_buf + if string.strcmp(lty_buf, "i8*") == 0: + lty_lbl = "str(i8*)" + if rty_buf is not None: + llvmlite.TypePrint(rty_buf, 64, rhs.Ty, pool) + rty_lbl = rty_buf + if string.strcmp(rty_buf, "i8*") == 0: + rty_lbl = "str(i8*)" + col_s: int = 0 + if node is not None: + col_s = node.col_offset + 1 + self.Gen.TypeGenErr.fatal_error( + node, + f"[TPV] 双指针运算类型非法: op = '{op_lbl}'{aug_note}," + f"左操作数类型 = {lty_lbl},右操作数类型 = {rty_lbl}。" + f"本语言的 str 是 i8*,没有 `+` 拼接语义(`str + str` 与指针 ± 指针" + f"都会退化成裸指针 add/sub ⇒ 非法 IR: opt 报 " + f"invalid operand type for instruction)。" + f"禁止静默降级,已终止编译。" + f"修法: 用 f-string 插值、string.strcat 或 viperlib.snprintf 构建字符串。", + "TypeError", col_s, col_s) + return 1 + # ============================================================ # 翻译二元运算(自动类型提升) # ============================================================ - def translate_binop(self, pool: rawptr[memhub.MemBuddy], - builder: rawptr[llvmlite.IRBuilder], - mod: rawptr[llvmlite.LLVMModule], - node: rawptr[ast.AST], - trans: rawptr[HT.Translator] = None) -> rawptr[llvmlite.Value]: + def translate_binop(self, pool: memhub.MemBuddy*, + builder: llvmlite.IRBuilder*, + mod: llvmlite.LLVMModule*, + node: ast.AST*, + trans: HT.Translator* = None) -> llvmlite.Value*: """翻译二元运算(自动类型提升)""" - binop: rawptr[ast.BinOp] = rawptr[ast.BinOp](node) + binop: ast.BinOp* = ast.BinOp*(node) if binop is None: return None - lhs_node: rawptr[ast.AST] = binop.left - rhs_node: rawptr[ast.AST] = binop.right + lhs_node: ast.AST* = binop.left + rhs_node: ast.AST* = binop.right op: int = binop.op # 先翻译 rhs(只翻译一次,避免副作用重复) - rhs: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( + rhs: llvmlite.Value* = self.Gen.ExprGen.translate_value( builder, pool, mod, rhs_node, None, 0, trans) if rhs is None: return None @@ -1335,36 +1413,36 @@ class ExprGenOps(ExprGenBase.ExprGenBase): # 对于值类型变量(如 cnt: Counter),translate_value 会 load 返回 Struct 值, # 但 dunder 方法需要 Ptr(Struct) 作为 self。直接用 alloca 指针尝试重载。 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) + nm: ast.Name* = ast.Name*(lhs_node) if nm is not None and nm.id is not None: - lhs_alloca: rawptr[llvmlite.Value] = self.Gen.VarGen.lookup_var( + lhs_alloca: llvmlite.Value* = self.Gen.VarGen.lookup_var( trans.SymTab, nm.id) if lhs_alloca is not None: - ovl_self1: rawptr[llvmlite.Value] = lhs_alloca + ovl_self1: llvmlite.Value* = lhs_alloca # alloca 是 Ptr(Ptr(Struct))(X|t.CPtr 对象存储槽)时, # load 出对象指针作为 self——若把槽地址当 self,dunder 内 # load 槽内容(对象指针值)当字段读 → 垃圾(MultiInheritTest # Vec2Both __add__ 输出 (1.0,2.0) 根因;get_struct_type_from_value # 递归解指针后路径 1 能识别 alloca,需同步修正 self 语义) - if lhs_alloca.Ty is not None and lhs_alloca.Ty.Pointee is not None \ + if lhs_alloca.Ty is not None and lhs_alloca.Ty.Pointee != 0 \ and self.Gen.ExprGenBase.is_ptr_type(lhs_alloca.Ty.Pointee) != 0: - load_self1: rawptr[llvmlite.Value] = llvmlite.build_load( + load_self1: llvmlite.Value* = llvmlite.build_load( builder, lhs_alloca.Ty.Pointee, lhs_alloca) if load_self1 is not None: ovl_self1 = load_self1 - ovl_result: rawptr[llvmlite.Value] = self.try_operator_overload( + ovl_result: 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: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( + lhs: 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: rawptr[llvmlite.Value] = self.try_operator_overload( + ovl_result2: llvmlite.Value* = self.try_operator_overload( pool, builder, mod, lhs, rhs, op, trans, 0) if ovl_result2 is not None: return ovl_result2 @@ -1382,7 +1460,7 @@ class ExprGenOps(ExprGenBase.ExprGenBase): target_fbits: int = lhs_fbits if rhs_fbits > target_fbits: target_fbits = rhs_fbits - target_float_ty: rawptr[llvmlite.LLVMType] = llvmlite.Double(pool) + target_float_ty: llvmlite.LLVMType* = llvmlite.Double(pool) if target_fbits == 32: target_float_ty = llvmlite.Float(pool) # 将两个操作数转换为目标浮点类型(int→float via si2fp, float→float via fpext/fptrunc) @@ -1411,6 +1489,13 @@ class ExprGenOps(ExprGenBase.ExprGenBase): if op == ast.OpKind.Sub and lhs_bits == 0: return self.translate_ptr_arith(pool, builder, lhs, rhs, op) + # 双指针算术(含 AugAssign)fail-fast:判据/报文唯一实现见 + # fail_if_double_ptr_binop(本文件;BinOp 与 AssignGenMixin._apply_aug_op 共用)。 + # 指针 ± 整数(GEP 语义)已在上方 translate_ptr_arith 分流;此处的双指针 + # Add/Sub/Mult/Div/Mod/Shift/位运算在本语言非法(str 是 i8*,无 `+` 拼接语义), + # 落到 build_add/build_sub/… 会直出非法 IR(`add i8*, i8*`)。 + self.fail_if_double_ptr_binop(pool, op, lhs, rhs, node, 0) + # 拓宽方向(zext/sext)与后续除/模谓词都需要"操作数是否无符号", # 统一在此求值一次并下沉 trans(Name/Subscript 靠 SymTab 注解判定)。 binop_unsigned: int = 0 diff --git a/App/lib/core/Gen/Func/FuncGenBase.vp b/App/lib/core/Gen/Func/FuncGenBase.vp index 8604f57..1a325a6 100644 --- a/App/lib/core/Gen/Func/FuncGenBase.vp +++ b/App/lib/core/Gen/Func/FuncGenBase.vp @@ -31,7 +31,7 @@ class FuncGenBase(CallGenBase.CallGenBase): # # 返回 LLVM IR 属性字符串(如 "alwaysinline nounwind"),无属性返回 None # ============================================================ - def extract_func_attrs(self, pool: rawptr[memhub.MemBuddy], + def extract_func_attrs(self, pool: memhub.MemBuddy*, decorator_list: list[ast.AST*]*, imported_modules: str) -> str: """从 decorator_list 提取 c.Attribute 属性,返回 LLVM IR 属性字符串""" @@ -48,13 +48,13 @@ class FuncGenBase(CallGenBase.CallGenBase): found_any: int = 0 for di in range(dn): - deco: rawptr[ast.AST] = decorator_list.get(di) + deco: ast.AST* = decorator_list.get(di) if deco is None: continue dk: int = deco.kind() if dk != ast.ASTKind.Call: continue - call_node: rawptr[ast.Call] = rawptr[ast.Call](deco) + call_node: ast.Call* = ast.Call*(deco) if call_node.func is None: continue cfk: int = call_node.func.kind() @@ -62,7 +62,7 @@ class FuncGenBase(CallGenBase.CallGenBase): continue # 检测 c.Attribute - func_attr: rawptr[ast.Attribute] = rawptr[ast.Attribute](call_node.func) + func_attr: ast.Attribute* = ast.Attribute*(call_node.func) if func_attr.attr is None: continue if string.strcmp(func_attr.attr, "Attribute") != 0: @@ -72,7 +72,7 @@ class FuncGenBase(CallGenBase.CallGenBase): fvk: int = func_attr.value.kind() if fvk != ast.ASTKind.Name: continue - c_name: rawptr[ast.Name] = rawptr[ast.Name](func_attr.value) + c_name: ast.Name* = ast.Name*(func_attr.value) if c_name.id is None: continue if string.strcmp(c_name.id, "c") != 0: @@ -87,7 +87,7 @@ class FuncGenBase(CallGenBase.CallGenBase): args_list: list[ast.AST*]* = call_node.args an: sizet = len(args_list) for ai in range(an): - arg_node: rawptr[ast.AST] = args_list.get(ai) + arg_node: ast.AST* = args_list.get(ai) if arg_node is None: continue # 提取属性名(t.attr.xxx / t.attr.xxx() / t.attr.llvm.xxx) @@ -107,7 +107,7 @@ class FuncGenBase(CallGenBase.CallGenBase): if found_any == 0: return None return attrs_buf - def extract_func_section(self, pool: rawptr[memhub.MemBuddy], + def extract_func_section(self, pool: memhub.MemBuddy*, decorator_list: list[ast.AST*]*, imported_modules: str) -> str: """提取 @c.Attribute(t.attr.section("xxx")) 为属性组文本 '"section"="xxx"'。 @@ -122,13 +122,13 @@ class FuncGenBase(CallGenBase.CallGenBase): if dn == 0: return None for di in range(dn): - deco: rawptr[ast.AST] = decorator_list.get(di) + deco: ast.AST* = decorator_list.get(di) if deco is None or deco.kind() != ast.ASTKind.Call: continue - call_node: rawptr[ast.Call] = rawptr[ast.Call](deco) + call_node: ast.Call* = ast.Call*(deco) if call_node.func is None or call_node.func.kind() != ast.ASTKind.Attribute: continue - func_attr: rawptr[ast.Attribute] = rawptr[ast.Attribute](call_node.func) + func_attr: ast.Attribute* = ast.Attribute*(call_node.func) if func_attr.attr is None or string.strcmp(func_attr.attr, "Attribute") != 0: continue if call_node.args is None: @@ -136,7 +136,7 @@ class FuncGenBase(CallGenBase.CallGenBase): args_list: list[ast.AST*]* = call_node.args an: sizet = len(args_list) for ai in range(an): - arg_node: rawptr[ast.AST] = args_list.get(ai) + arg_node: ast.AST* = args_list.get(ai) if arg_node is None: continue attr_name: str = self._get_attr_name_from_node(arg_node) @@ -151,7 +151,7 @@ class FuncGenBase(CallGenBase.CallGenBase): viperlib.snprintf(sec_buf, 128, "\"section\"=\"%s\"", sec_val) return sec_buf return None - def _get_attr_name_from_node(self, node: rawptr[ast.AST]) -> str: + def _get_attr_name_from_node(self, node: ast.AST*) -> str: """从 AST 节点提取属性名 支持: @@ -165,29 +165,29 @@ class FuncGenBase(CallGenBase.CallGenBase): # Call 节点: t.attr.always_inline() if k == ast.ASTKind.Call: - call: rawptr[ast.Call] = rawptr[ast.Call](node) + call: ast.Call* = ast.Call*(node) if call.func is None or call.func.kind() != ast.ASTKind.Attribute: return None - at: rawptr[ast.Attribute] = rawptr[ast.Attribute](call.func) + at: ast.Attribute* = ast.Attribute*(call.func) return at.attr # Attribute 节点: t.attr.packed 或 t.attr.llvm.nounwind if k == ast.ASTKind.Attribute: - at2: rawptr[ast.Attribute] = rawptr[ast.Attribute](node) + at2: ast.Attribute* = ast.Attribute*(node) return at2.attr return None - def _get_attr_call_arg_str(self, node: rawptr[ast.AST]) -> str: + def _get_attr_call_arg_str(self, node: ast.AST*) -> str: """取 t.attr.xxx("val") 调用的首参字符串常量(如 section(".text.startup"))""" if node is None or node.kind() != ast.ASTKind.Call: return None - cl: rawptr[ast.Call] = rawptr[ast.Call](node) + cl: ast.Call* = ast.Call*(node) if cl.args is None or len(cl.args) == 0: return None - a0: rawptr[ast.AST] = cl.args.get(0) + a0: ast.AST* = cl.args.get(0) if a0 is None or a0.kind() != ast.ASTKind.Constant: return None - cn: rawptr[ast.Constant] = rawptr[ast.Constant](a0) + cn: ast.Constant* = ast.Constant*(a0) if cn.const_kind != ast.CONST_STR: return None return cn.str_val @@ -257,7 +257,7 @@ class FuncGenBase(CallGenBase.CallGenBase): # 返回 "sha1.name" 格式的混淆名。若 ModuleSha1 为 None 或名称已带 # SHA1 前缀(16 hex + '.'),则原样返回。 # ============================================================ - def _mangle_name(self, trans: rawptr[HT.Translator], name: str) -> str: + def _mangle_name(self, trans: HT.Translator*, name: str) -> str: """为任意名称添加 SHA1 前缀(不做 main/export 检查)""" if trans is None or name is None: return name @@ -310,7 +310,7 @@ class FuncGenBase(CallGenBase.CallGenBase): # - 已带 SHA1 前缀的不再加 # - ModuleSha1 为 None 时不加前缀 # ============================================================ - def _mangle_func_name(self, trans: rawptr[HT.Translator], name: str, + def _mangle_func_name(self, trans: HT.Translator*, name: str, has_export: int) -> str: """为函数名添加 SHA1 前缀(检查 main/export)""" if trans is None or name is None: @@ -327,14 +327,14 @@ class FuncGenBase(CallGenBase.CallGenBase): # 追加 __eh_msg_out__/__eh_code_out__ 输出参数的条件。v1 只扫函数体 # 顶层 raise(嵌套 if/for/try 内的 raise 未覆盖,后续扩展)。 # ============================================================ - def _body_has_raise(self, fd: rawptr[ast.FunctionDef]) -> int: + def _body_has_raise(self, fd: ast.FunctionDef*) -> int: """函数体顶层是否含 raise(非 StopIteration),1=是 / 0=否""" if fd is None or fd.children is None: return 0 body_f: list[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) + stmt_f: ast.AST* = body_f.get(bi_f) if stmt_f is None: continue if stmt_f.kind() != ast.ASTKind.Raise: @@ -345,13 +345,13 @@ class FuncGenBase(CallGenBase.CallGenBase): ek_f: int = rn_f.exc.kind() is_stop_f: int = 0 if ek_f == ast.ASTKind.Name: - enm_f: rawptr[ast.Name] = rawptr[ast.Name](rn_f.exc) + enm_f: ast.Name* = ast.Name*(rn_f.exc) if enm_f.id is not None and string.strcmp(enm_f.id, "StopIteration") == 0: is_stop_f = 1 elif ek_f == ast.ASTKind.Call: - ecl_f: rawptr[ast.Call] = rawptr[ast.Call](rn_f.exc) + ecl_f: ast.Call* = ast.Call*(rn_f.exc) if ecl_f.func is not None and ecl_f.func.kind() == ast.ASTKind.Name: - ecn_f: rawptr[ast.Name] = rawptr[ast.Name](ecl_f.func) + ecn_f: ast.Name* = ast.Name*(ecl_f.func) if ecn_f.id is not None and string.strcmp(ecn_f.id, "StopIteration") == 0: is_stop_f = 1 if is_stop_f == 0: @@ -366,26 +366,26 @@ class FuncGenBase(CallGenBase.CallGenBase): # 两阶段必须一致,否则 declare i32 + define {i64,i64,i64} → llc # "ret doesn't match function result type"。 # ============================================================ - def _resolve_creturn_ret_ty(self, pool: rawptr[memhub.MemBuddy], - fd: rawptr[ast.FunctionDef], + def _resolve_creturn_ret_ty(self, pool: memhub.MemBuddy*, + fd: ast.FunctionDef*, imported_modules: str, from_imports: str, - trans: rawptr[HT.Translator]) -> rawptr[llvmlite.LLVMType]: + trans: HT.Translator*) -> llvmlite.LLVMType*: """解析 @c.CReturn 装饰器为 struct 返回类型;无 CReturn 返回 None""" if fd is None or fd.decorator_list is None: return None - cr_head: rawptr[llvmlite.Function] = None - cr_last: rawptr[llvmlite.Function] = None + cr_head: llvmlite.Function* = None + cr_last: llvmlite.Function* = None cr_count: int = 0 cr_dn: sizet = len(fd.decorator_list) for cdi in range(cr_dn): - deco_cr: rawptr[ast.AST] = fd.decorator_list.get(cdi) + deco_cr: ast.AST* = fd.decorator_list.get(cdi) if deco_cr is None or deco_cr.kind() != ast.ASTKind.Call: continue - deco_call_cr: rawptr[ast.Call] = rawptr[ast.Call](deco_cr) + deco_call_cr: ast.Call* = ast.Call*(deco_cr) if deco_call_cr.func is None or deco_call_cr.func.kind() != ast.ASTKind.Attribute: continue - deco_fa_cr: rawptr[ast.Attribute] = rawptr[ast.Attribute](deco_call_cr.func) + deco_fa_cr: ast.Attribute* = 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[ast.AST*]* = deco_call_cr.args @@ -393,11 +393,11 @@ class FuncGenBase(CallGenBase.CallGenBase): continue cr_an: sizet = len(cr_args) for cai in range(cr_an): - cr_aty: rawptr[llvmlite.LLVMType] = self.Gen.TypeGenResolve.resolve_annotation_type( + cr_aty: llvmlite.LLVMType* = self.Gen.TypeGenResolve.resolve_annotation_type( pool, cr_args.get(cai), imported_modules, from_imports, trans, 0) if cr_aty is None: continue - cr_pn: rawptr[llvmlite.Function] = llvmlite.new_param_node(pool, cr_aty) + cr_pn: llvmlite.Function* = llvmlite.new_param_node(pool, cr_aty) if cr_pn is not None: if cr_head is None: cr_head = cr_pn @@ -411,37 +411,37 @@ class FuncGenBase(CallGenBase.CallGenBase): # ============================================================ # 创建 LLVM 函数(简单版本,仅声明) # ============================================================ - def create_function(self, pool: rawptr[memhub.MemBuddy], - mod: rawptr[llvmlite.LLVMModule], + def create_function(self, pool: memhub.MemBuddy*, + mod: llvmlite.LLVMModule*, name: str, - args_node: rawptr[ast.AST], - ret_ty: rawptr[llvmlite.LLVMType]) -> rawptr[llvmlite.Function]: + args_node: ast.AST*, + ret_ty: llvmlite.LLVMType*) -> llvmlite.Function*: """创建 LLVM 函数并添加参数""" if name is None or mod is None: return None - func: rawptr[llvmlite.Function] = llvmlite.create_function(pool, mod, name, ret_ty) + func: llvmlite.Function* = llvmlite.create_function(pool, mod, name, ret_ty) if func is None: return None if args_node is not None: - ags: rawptr[ast.Arguments] = rawptr[ast.Arguments](args_node) + ags: ast.Arguments* = ast.Arguments*(args_node) if ags.args is not None: alist: list[ast.AST*]* = ags.args an: sizet = len(alist) - i32_ty: rawptr[llvmlite.LLVMType] = llvmlite.Int32(pool) + i32_ty: llvmlite.LLVMType* = llvmlite.Int32(pool) for ai in range(an): - arg: rawptr[ast.Arg] = rawptr[ast.Arg](alist.get(ai)) + arg: ast.Arg* = ast.Arg*(alist.get(ai)) if arg is not None and arg.arg is not None: # t\.CVoid 表示空参:跳过 if arg.annotation is not None: if arg.annotation.kind() == ast.ASTKind.Attribute: - at_cf: rawptr[ast.Attribute] = rawptr[ast.Attribute](arg.annotation) + at_cf: ast.Attribute* = ast.Attribute*(arg.annotation) if at_cf.attr is not None and string.strcmp(at_cf.attr, "CVoid") == 0: continue - param_ty: rawptr[llvmlite.LLVMType] = i32_ty + param_ty: llvmlite.LLVMType* = i32_ty if arg.annotation is not None: - resolved: rawptr[llvmlite.LLVMType] = self.Gen.TypeGenResolve.resolve_annotation_type( + resolved: llvmlite.LLVMType* = self.Gen.TypeGenResolve.resolve_annotation_type( pool, arg.annotation, None, None, None, 0) if resolved is None: # [S4 fail-fast] 有注解但解析失败:不再静默用 i32。 diff --git a/App/lib/core/Gen/Func/FuncGenDef.vp b/App/lib/core/Gen/Func/FuncGenDef.vp index 77271ce..856998d 100644 --- a/App/lib/core/Gen/Func/FuncGenDef.vp +++ b/App/lib/core/Gen/Func/FuncGenDef.vp @@ -31,23 +31,23 @@ class FuncGenDef(CallGenBase.CallGenBase): # 3) 创建 declare(IsDeclared=1) 4) 添加参数 5) 注册到函数表。 # 后续 translate_function_def 经 find_func_in_module 复用该 declare(清除 IsDeclared, # 跳过参数创建,直接添加函数体)。 - def forward_declare_functions(self, trans: rawptr[HT.Translator], - tree: rawptr[ast.AST]) -> int: + def forward_declare_functions(self, trans: HT.Translator*, + tree: ast.AST*) -> int: """预扫描所有顶层 FunctionDef,创建前向声明""" if trans is None or tree is None: return 0 - pool: rawptr[memhub.MemBuddy] = trans.Pool - mod: rawptr[llvmlite.LLVMModule] = trans.Module + pool: memhub.MemBuddy* = trans.Pool + mod: llvmlite.LLVMModule* = trans.Module if pool is None or mod is None: return 0 imported_modules: str = trans._imported_modules from_imports: str = trans._from_imports - funcs_ptr: rawptr[GenTypes.FuncEntry] = trans._funcs + funcs_ptr: GenTypes.FuncEntry* = trans._funcs - i32_ty: rawptr[llvmlite.LLVMType] = llvmlite.Int32(pool) - i8_ty: rawptr[llvmlite.LLVMType] = llvmlite.Int8(pool) - i8_ptr_ty: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, i8_ty) + i32_ty: llvmlite.LLVMType* = llvmlite.Int32(pool) + i8_ty: llvmlite.LLVMType* = llvmlite.Int8(pool) + i8_ptr_ty: llvmlite.LLVMType* = llvmlite.Ptr(pool, i8_ty) ch: list[ast.AST*]* = tree.children if ch is None: @@ -77,27 +77,27 @@ class FuncGenDef(CallGenBase.CallGenBase): # 交由 translate_children 走 existing 路径,无重复处理副作用。 pre_i: sizet for pre_i in range(cn_count): - pre_child: rawptr[ast.AST] = ch.get(pre_i) + pre_child: ast.AST* = ch.get(pre_i) if pre_child is None: continue if pre_child.kind() != ast.ASTKind.ClassDef: continue - pre_cd: rawptr[ast.ClassDef] = rawptr[ast.ClassDef](pre_child) + pre_cd: ast.ClassDef* = ast.ClassDef*(pre_child) if pre_cd is None or pre_cd.name is None: continue - pre_ex: rawptr[GenTypes.StructEntry] = self.Gen.StructGen.find_struct_by_module( + pre_ex: 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 self.Gen.ClassGenDef.translate_class_def(trans, pre_child) for ci in range(cn_count): - child: rawptr[ast.AST] = ch.get(ci) + child: ast.AST* = ch.get(ci) if child is None: continue if child.kind() != ast.ASTKind.FunctionDef: continue - fd: rawptr[ast.FunctionDef] = rawptr[ast.FunctionDef](child) + fd: ast.FunctionDef* = ast.FunctionDef*(child) if fd is None or fd.name is None: continue @@ -107,10 +107,10 @@ class FuncGenDef(CallGenBase.CallGenBase): # forward_declare 阶段 "函数返回类型解析失败:注解不可解析" # (ExpandKeywordsTest fn ident[T] 根因)。所有退出路径(continue / # 循环末尾)必须 clear_generic_context,避免污染后续函数注解解析。 - tp_names_fd: list[str] | t.CPtr = None + tp_names_fd: list[str]* = None if fd.type_params is not None: tp_names_fd = fd.type_params - tp_args_fd: list[str] | t.CPtr = list[str](pool, 8) + tp_args_fd: list[str]* = list[str](pool, 8) if tp_args_fd is not None: tpn_fd: sizet = len(fd.type_params) tpi_fd: sizet = 0 @@ -119,7 +119,7 @@ class FuncGenDef(CallGenBase.CallGenBase): self.Gen.TypeGenBase.set_generic_context(tp_names_fd, tp_args_fd) # 推断返回类型 - ret_ty: rawptr[llvmlite.LLVMType] = None + ret_ty: llvmlite.LLVMType* = None if fd.returns is not None: ret_ty = self.Gen.TypeGenResolve.resolve_annotation_type( pool, fd.returns, imported_modules, from_imports, trans, 0) @@ -128,10 +128,10 @@ class FuncGenDef(CallGenBase.CallGenBase): # 回退为 i32 → 掉尾检查强制 return i32,mm.vp free 根因)。 # CExport 混用实际类型(-> t.CExport | int)时保持解析结果。 if fd.returns.kind() == ast.ASTKind.Attribute: - ce_at: rawptr[ast.Attribute] = rawptr[ast.Attribute](fd.returns) + ce_at: ast.Attribute* = ast.Attribute*(fd.returns) if ce_at.attr is not None and string.strcmp(ce_at.attr, "CExport") == 0: if ce_at.value is not None and ce_at.value.kind() == ast.ASTKind.Name: - ce_nm: rawptr[ast.Name] = rawptr[ast.Name](ce_at.value) + ce_nm: ast.Name* = ast.Name*(ce_at.value) if ce_nm.id is not None and string.strcmp(ce_nm.id, "t") == 0: ret_ty = llvmlite.Void(pool) if ret_ty is None and fd.returns is not None: @@ -186,14 +186,14 @@ class FuncGenDef(CallGenBase.CallGenBase): mangled_name = self.Gen.FuncGenBase._mangle_func_name(trans, fd.name, 0) # 如果函数已存在(如重复定义),跳过 - existing: rawptr[llvmlite.Function] = self.Gen.CallGenBase.find_func_in_module(mod, mangled_name) + existing: llvmlite.Function* = self.Gen.CallGenBase.find_func_in_module(mod, mangled_name) if existing is not None: if tp_names_fd is not None: self.Gen.TypeGenBase.clear_generic_context() continue # 创建 declare - func: rawptr[llvmlite.Function] = llvmlite.create_declare( + func: llvmlite.Function* = llvmlite.create_declare( pool, mod, mangled_name, ret_ty) if func is None: if tp_names_fd is not None: @@ -203,12 +203,12 @@ class FuncGenDef(CallGenBase.CallGenBase): # 提取默认参数信息 # 注意: 必须先把属性赋给显式类型为 list[...] | t.CPtr 的局部变量再调用 __len__(), # 否则编译器无法识别属性返回的 list 类型,GEP base 会变成 i32 0 导致 llc 报错 - fd_args_node: rawptr[ast.Arguments] = fd.args + fd_args_node: ast.Arguments* = fd.args fd_defaults: t.CPtr = None fd_default_count: int = 0 fd_param_count: int = 0 if fd_args_node is not None: - fd_ags: rawptr[ast.Arguments] = rawptr[ast.Arguments](fd_args_node) + fd_ags: ast.Arguments* = ast.Arguments*(fd_args_node) if fd_ags.args is not None: fd_alist: list[ast.AST*]* = fd_ags.args fd_param_count = len(fd_alist) @@ -230,23 +230,23 @@ class FuncGenDef(CallGenBase.CallGenBase): self.Gen.CallGenBase.register_cexport_func(trans.ModuleSha1, fd.name) # 添加参数 - args_node: rawptr[ast.Arguments] = fd.args + args_node: ast.Arguments* = fd.args if args_node is not None: - ags: rawptr[ast.Arguments] = rawptr[ast.Arguments](args_node) + ags: ast.Arguments* = ast.Arguments*(args_node) if ags.args is not None: alist: list[ast.AST*]* = ags.args an: sizet = len(alist) for ai in range(an): - arg: rawptr[ast.Arg] = rawptr[ast.Arg](alist.get(ai)) + arg: ast.Arg* = ast.Arg*(alist.get(ai)) if arg is None or arg.arg is None: continue # CVoid 表示空参:跳过 if arg.annotation is not None: if self.Gen.TypeGenResolve._is_t_attr(arg.annotation, "CVoid", imported_modules) != 0: continue - param_ty: rawptr[llvmlite.LLVMType] = i32_ty + param_ty: llvmlite.LLVMType* = i32_ty if arg.annotation is not None: - resolved: rawptr[llvmlite.LLVMType] = self.Gen.TypeGenResolve.resolve_annotation_type( + resolved: llvmlite.LLVMType* = self.Gen.TypeGenResolve.resolve_annotation_type( pool, arg.annotation, imported_modules, from_imports, trans, 0) if resolved is None: # [S4 fail-fast] 有注解但解析失败:不再静默用 i32 @@ -305,10 +305,10 @@ class FuncGenDef(CallGenBase.CallGenBase): # trans 单参模式:所有共享状态从 trans 获取 # 函数局部作用域通过 enter_scope/exit_scope 管理 # ============================================================ - def translate_function_def(self, trans: rawptr[HT.Translator], - node: rawptr[ast.AST]) -> int: + def translate_function_def(self, trans: HT.Translator*, + node: ast.AST*) -> int: """翻译函数定义,返回新增的变量数(通常为 0,函数定义不增加当前作用域变量)""" - fd: rawptr[ast.FunctionDef] = rawptr[ast.FunctionDef](node) + fd: ast.FunctionDef* = ast.FunctionDef*(node) if fd is None or fd.name is None: return 0 @@ -319,17 +319,17 @@ class FuncGenDef(CallGenBase.CallGenBase): if fd.flags is not None and (fd.flags & 1) != 0: return self.Gen.AsyncGen.translate_async_function(trans, node) - pool: rawptr[memhub.MemBuddy] = trans.Pool - mod: rawptr[llvmlite.LLVMModule] = trans.Module + pool: memhub.MemBuddy* = trans.Pool + mod: llvmlite.LLVMModule* = trans.Module imported_modules: str = trans._imported_modules from_imports: str = trans._from_imports - funcs_ptr: rawptr[GenTypes.FuncEntry] = trans._funcs + funcs_ptr: GenTypes.FuncEntry* = trans._funcs func_count: int = trans._func_count - i32_ty: rawptr[llvmlite.LLVMType] = llvmlite.Int32(pool) + i32_ty: llvmlite.LLVMType* = llvmlite.Int32(pool) # 推断返回类型:优先使用返回类型注解 - ret_ty: rawptr[llvmlite.LLVMType] = None + ret_ty: llvmlite.LLVMType* = None if fd.returns is not None: ret_ty = self.Gen.TypeGenResolve.resolve_annotation_type( pool, fd.returns, imported_modules, from_imports, trans, 0) @@ -338,10 +338,10 @@ class FuncGenDef(CallGenBase.CallGenBase): # 为 i32 → 掉尾检查强制 return i32,mm.vp free 根因)。 # 混合实际类型(-> t.CExport | int)时保持解析结果。 if fd.returns.kind() == ast.ASTKind.Attribute: - ce_at2: rawptr[ast.Attribute] = rawptr[ast.Attribute](fd.returns) + ce_at2: ast.Attribute* = ast.Attribute*(fd.returns) if ce_at2.attr is not None and string.strcmp(ce_at2.attr, "CExport") == 0: if ce_at2.value is not None and ce_at2.value.kind() == ast.ASTKind.Name: - ce_nm2: rawptr[ast.Name] = rawptr[ast.Name](ce_at2.value) + ce_nm2: ast.Name* = ast.Name*(ce_at2.value) if ce_nm2.id is not None and string.strcmp(ce_nm2.id, "t") == 0: ret_ty = llvmlite.Void(pool) @@ -427,24 +427,24 @@ class FuncGenDef(CallGenBase.CallGenBase): if fd.decorator_list is not None: ddn: sizet = len(fd.decorator_list) for ddi in range(ddn): - deco: rawptr[ast.AST] = fd.decorator_list.get(ddi) + deco: ast.AST* = fd.decorator_list.get(ddi) if deco is None: continue dk: int = deco.kind() dname: str = None if dk == ast.ASTKind.Name: - dnm: rawptr[ast.Name] = rawptr[ast.Name](deco) + dnm: ast.Name* = ast.Name*(deco) dname = dnm.id elif dk == ast.ASTKind.Call: - dcl: rawptr[ast.Call] = rawptr[ast.Call](deco) + dcl: ast.Call* = ast.Call*(deco) if dcl.func is not None and dcl.func.kind() == ast.ASTKind.Name: - dnm2: rawptr[ast.Name] = rawptr[ast.Name](dcl.func) + dnm2: ast.Name* = ast.Name*(dcl.func) dname = dnm2.id # @repeat(3):取首个常量 int 参数(对齐 TPC L1182-1184) if dcl.args is not None and len(dcl.args) >= 1: - da0: rawptr[ast.AST] = dcl.args.get(0) + da0: ast.AST* = dcl.args.get(0) if da0 is not None and da0.kind() == ast.ASTKind.Constant: - dc0: rawptr[ast.Constant] = rawptr[ast.Constant](da0) + dc0: ast.Constant* = ast.Constant*(da0) if dc0.const_kind == ast.CONST_INT: decor_arg0 = dc0.int_val if dname is None: @@ -492,12 +492,12 @@ class FuncGenDef(CallGenBase.CallGenBase): if is_extern_decl != 0: # 外部声明函数:生成 declare(仅声明,不定义) # 先检查是否已由 forward_declare_functions 创建,避免重复 declare - existing_extern: rawptr[llvmlite.Function] = self.Gen.CallGenBase.find_func_in_module(mod, mangled_name) + existing_extern: llvmlite.Function* = self.Gen.CallGenBase.find_func_in_module(mod, mangled_name) if existing_extern is not None: # 已存在前向声明,复用之,不再重复创建 return 0 - func: rawptr[llvmlite.Function] = llvmlite.create_declare( + func: llvmlite.Function* = llvmlite.create_declare( pool, mod, mangled_name, ret_ty) if func is None: return 0 @@ -508,22 +508,22 @@ class FuncGenDef(CallGenBase.CallGenBase): trans._func_count = func_count + 1 # 添加参数(支持类型注解) - args_node_extern: rawptr[ast.Arguments] = fd.args + args_node_extern: ast.Arguments* = fd.args if args_node_extern is not None: - ags_e: rawptr[ast.Arguments] = rawptr[ast.Arguments](args_node_extern) + ags_e: ast.Arguments* = ast.Arguments*(args_node_extern) if ags_e.args is not None: alist_e: list[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)) + arg_e: ast.Arg* = ast.Arg*(alist_e.get(ai_e)) if arg_e is not None and arg_e.arg is not None: # CVoid 表示空参:跳过,不添加到函数签名 if arg_e.annotation is not None \ and self.Gen.TypeGenResolve._is_t_attr(arg_e.annotation, "CVoid", imported_modules) != 0: continue - param_ty_e: rawptr[llvmlite.LLVMType] = i32_ty + param_ty_e: llvmlite.LLVMType* = i32_ty if arg_e.annotation is not None: - resolved_e: rawptr[llvmlite.LLVMType] = self.Gen.TypeGenResolve.resolve_annotation_type( + resolved_e: llvmlite.LLVMType* = self.Gen.TypeGenResolve.resolve_annotation_type( pool, arg_e.annotation, imported_modules, from_imports, trans, 0) if resolved_e is None: # fail-fast:外部声明函数参数有注解但类型解析失败, @@ -571,10 +571,10 @@ class FuncGenDef(CallGenBase.CallGenBase): return 0 # args_node 用于后续 alloca 创建,提前赋值 - args_node: rawptr[ast.Arguments] = fd.args + args_node: ast.Arguments* = fd.args # 检查是否已有前向声明(由 forward_declare_functions 创建) - func: rawptr[llvmlite.Function] = self.Gen.CallGenBase.find_func_in_module(mod, mangled_name) + func: llvmlite.Function* = self.Gen.CallGenBase.find_func_in_module(mod, mangled_name) if func is not None and llvmlite.function_is_declared(func) != 0: # 复用前向声明:清除 IsDeclared 标记,转为 define func.IsDeclared = 0 @@ -609,7 +609,7 @@ class FuncGenDef(CallGenBase.CallGenBase): tfd_default_count: int = 0 tfd_param_count: int = 0 if args_node is not None: - tfd_ags: rawptr[ast.Arguments] = rawptr[ast.Arguments](args_node) + tfd_ags: ast.Arguments* = ast.Arguments*(args_node) if tfd_ags.args is not None: tfd_alist: list[ast.AST*]* = tfd_ags.args tfd_param_count = len(tfd_alist) @@ -627,20 +627,20 @@ class FuncGenDef(CallGenBase.CallGenBase): # 添加参数(支持类型注解) if args_node is not None: - ags: rawptr[ast.Arguments] = rawptr[ast.Arguments](args_node) + ags: ast.Arguments* = ast.Arguments*(args_node) if ags.args is not None: alist: list[ast.AST*]* = ags.args an: sizet = len(alist) for ai in range(an): - arg: rawptr[ast.Arg] = rawptr[ast.Arg](alist.get(ai)) + arg: ast.Arg* = ast.Arg*(alist.get(ai)) if arg is not None and arg.arg is not None: # CVoid 表示空参:跳过,不添加到函数签名 if arg.annotation is not None \ and self.Gen.TypeGenResolve._is_t_attr(arg.annotation, "CVoid", imported_modules) != 0: continue - param_ty: rawptr[llvmlite.LLVMType] = i32_ty + param_ty: llvmlite.LLVMType* = i32_ty if arg.annotation is not None: - resolved: rawptr[llvmlite.LLVMType] = self.Gen.TypeGenResolve.resolve_annotation_type( + resolved: llvmlite.LLVMType* = self.Gen.TypeGenResolve.resolve_annotation_type( pool, arg.annotation, imported_modules, from_imports, trans, 0) if resolved is None: # [S4 fail-fast] 有注解但解析失败:不再静默用 i32 @@ -677,11 +677,11 @@ class FuncGenDef(CallGenBase.CallGenBase): # store %__eh_code_out__ 但签名无此参数(llc: use of undefined value)。 if string.strcmp(fd.name, "main") != 0: if self.Gen.FuncGenBase._body_has_raise(fd) != 0: - i8_ty_eh: rawptr[llvmlite.LLVMType] = llvmlite.Int8(pool) - i8_ptr_ty_eh: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, i8_ty_eh) - i8_ptr_ptr_ty_eh: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, i8_ptr_ty_eh) - i32_ty_eh: rawptr[llvmlite.LLVMType] = llvmlite.Int32(pool) - i32_ptr_ty_eh: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, i32_ty_eh) + i8_ty_eh: llvmlite.LLVMType* = llvmlite.Int8(pool) + i8_ptr_ty_eh: llvmlite.LLVMType* = llvmlite.Ptr(pool, i8_ty_eh) + i8_ptr_ptr_ty_eh: llvmlite.LLVMType* = llvmlite.Ptr(pool, i8_ptr_ty_eh) + i32_ty_eh: llvmlite.LLVMType* = llvmlite.Int32(pool) + i32_ptr_ty_eh: llvmlite.LLVMType* = llvmlite.Ptr(pool, i32_ty_eh) if i8_ptr_ptr_ty_eh is not None and i32_ptr_ty_eh is not None: llvmlite.add_param(pool, func, i8_ptr_ptr_ty_eh, "%__eh_msg_out__") llvmlite.add_param(pool, func, i32_ptr_ty_eh, "%__eh_code_out__") @@ -695,7 +695,7 @@ class FuncGenDef(CallGenBase.CallGenBase): return 0 # 创建函数专属 builder - func_builder: rawptr[llvmlite.IRBuilder] = llvmlite.new_builder(pool, func) + func_builder: llvmlite.IRBuilder* = llvmlite.new_builder(pool, func) if func_builder is None: return 0 llvmlite.position_at_end(func_builder, entry_blk) @@ -707,22 +707,22 @@ 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: rawptr[llvmlite.GlobalVariable] = llvmlite.create_global_int( + tls_flag_gv: 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) + i1_ty_t: llvmlite.LLVMType* = llvmlite.Int1(pool) if i1_ty_t is not None: # GlobalVariable 不是 Value 子类(字段布局不同),build_load/store # 按 Value 读 ptr.Ty/ptr.Name 会错位(Ty 读到 Name → void,Name 为空)。 # 与 create_global_string 一致:构造 Value 视图(Ty=Ptr(i1), Name="@name")。 - tls_gv_ptr_ty: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, i1_ty_t) + tls_gv_ptr_ty: llvmlite.LLVMType* = llvmlite.Ptr(pool, i1_ty_t) 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: rawptr[llvmlite.Value] = llvmlite.SSAValue( + tls_flag_ref: llvmlite.Value* = llvmlite.SSAValue( pool, tls_gv_ptr_ty, tls_ref_name) if tls_flag_ref is not None: - tls_flag_ld: rawptr[llvmlite.Value] = llvmlite.build_load( + tls_flag_ld: llvmlite.Value* = llvmlite.build_load( func_builder, i1_ty_t, tls_flag_ref) # 块名唯一化(create_block 不自动编号,同函数同名 label 冲突) lc_t: int = trans._label_counter @@ -744,23 +744,23 @@ class FuncGenDef(CallGenBase.CallGenBase): case llvmlite.LLVMType.Void(): llvmlite.build_ret_void(func_builder) case llvmlite.LLVMType.Int(_): - tlz0: rawptr[llvmlite.Value] = llvmlite.ConstInt( + tlz0: 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: rawptr[llvmlite.Value] = llvmlite.ConstFloat( + tlf0: llvmlite.Value* = llvmlite.ConstFloat( pool, ret_ty, 0.0) if tlf0 is not None: llvmlite.build_ret(func_builder, tlf0) case _: - tln0: rawptr[llvmlite.Value] = llvmlite.ConstNull( + tln0: 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: rawptr[llvmlite.Value] = llvmlite.ConstInt( + tlone: llvmlite.Value* = llvmlite.ConstInt( pool, i1_ty_t, 1, "1") if tlone is not None: llvmlite.build_store(func_builder, tlone, tls_flag_ref) @@ -772,10 +772,10 @@ class FuncGenDef(CallGenBase.CallGenBase): # TPV 无泛型函数特化机制(类泛型走 _specialize_generic_class),泛型函数按普通 # 函数编译;设置上下文使参数注解 T / 方法体中的 T(x) 转换可解析为 int。 # (注意与类特化的 set_generic_context 一样是全局状态,需在退出作用域前清除。) - tp_names_fn: list[str] | t.CPtr = None + tp_names_fn: list[str]* = None if fd.type_params is not None: tp_names_fn = fd.type_params - tp_args_fn: list[str] | t.CPtr = list[str](pool, 8) + tp_args_fn: list[str]* = list[str](pool, 8) if tp_args_fn is not None: tpn_fn: sizet = len(fd.type_params) tpi_fn: sizet = 0 @@ -785,20 +785,20 @@ class FuncGenDef(CallGenBase.CallGenBase): # 为参数创建 alloca if args_node is not None: - ags2: rawptr[ast.Arguments] = rawptr[ast.Arguments](args_node) + ags2: ast.Arguments* = ast.Arguments*(args_node) if ags2.args is not None: alist2: list[ast.AST*]* = ags2.args an2: sizet = len(alist2) for ai2 in range(an2): - arg2: rawptr[ast.Arg] = rawptr[ast.Arg](alist2.get(ai2)) + arg2: ast.Arg* = ast.Arg*(alist2.get(ai2)) if arg2 is not None and arg2.arg is not None: # CVoid 表示空参:跳过,不创建 alloca if arg2.annotation is not None: if self.Gen.TypeGenResolve._is_t_attr(arg2.annotation, "CVoid", imported_modules) != 0: continue - param_ty2: rawptr[llvmlite.LLVMType] = i32_ty + param_ty2: llvmlite.LLVMType* = i32_ty if arg2.annotation is not None: - resolved2: rawptr[llvmlite.LLVMType] = self.Gen.TypeGenResolve.resolve_annotation_type( + resolved2: llvmlite.LLVMType* = self.Gen.TypeGenResolve.resolve_annotation_type( pool, arg2.annotation, imported_modules, from_imports, trans, 0) if resolved2 is None: # fail-fast:参数有注解但类型解析失败,不再静默保持 i32 @@ -817,7 +817,7 @@ class FuncGenDef(CallGenBase.CallGenBase): param_ty2 = llvmlite.Ptr(pool, aelem_ty2) case _: param_ty2 = resolved2 - alloca: rawptr[llvmlite.Value] = llvmlite.build_alloca(func_builder, param_ty2) + alloca: 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) 回退到类名查找结构体) @@ -833,6 +833,14 @@ class FuncGenDef(CallGenBase.CallGenBase): # load/store 带 volatile(volatile 参数对象的读改写不得 # 被优化器提升/合并,如自旋等待入参)。 if arg2.annotation is not None: + # const 形参:**沿用 TPC 形参的历史判据**(只看注解 + # 是否含 t.CConst,不看指针层数)——TPC 形参登记点 + # HandlesFunctions 的 IsParam=True 用同一条件,两侧逐条 + # 对齐(见 Debugger/type-descriptors.md 已知差异)。 + if self.Gen.TypeGenErr.has_decorator_marker( + arg2.annotation, "CConst", 0) != 0: + self.Gen.VarGen.set_var_const( + trans.SymTab, arg2.arg) if self.Gen.TypeGenErr.has_decorator_marker( arg2.annotation, "CVolatile", 0) != 0: self.Gen.VarGen.set_var_volatile( @@ -846,7 +854,7 @@ class FuncGenDef(CallGenBase.CallGenBase): pname2: str = pool.alloc(32) if pname2 is not None: viperlib.snprintf(pname2, 32, "%%%s", arg2.arg) - param_val: rawptr[llvmlite.Value] = llvmlite.SSAValue( + param_val: llvmlite.Value* = llvmlite.SSAValue( pool, param_ty2, pname2) vol_p2: int = self.Gen.VarGen.var_is_volatile( self.Gen.VarGen.lookup_var_entry( @@ -863,25 +871,25 @@ class FuncGenDef(CallGenBase.CallGenBase): # 无 raise 的函数(viperlib.sprintf 等)同样有 *args,若放在 EH 块内 # 会被跳过,args 未注册到符号表 → NameError: 未定义名称 'args'。 if ags2.vararg is not None: - vararg_node: rawptr[ast.Arg] = rawptr[ast.Arg](ags2.vararg) + vararg_node: ast.Arg* = ast.Arg*(ags2.vararg) if vararg_node is not None and vararg_node.arg is not None: vararg_name_str: str = vararg_node.arg # va_list 缓冲区 24 字节(Win64 的 __va_list_tag = {i32,i32,i8*,i8*})+ 16 对齐 # (对齐 TPC HandlesFunctions.py:1739-1741) - 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: rawptr[llvmlite.Value] = llvmlite.build_alloca_aligned( + i8_ty_va: llvmlite.LLVMType* = llvmlite.Int8(pool) + i8_ptr_ty_va: llvmlite.LLVMType* = llvmlite.Ptr(pool, i8_ty_va) + va_buf_ty: llvmlite.LLVMType* = llvmlite.Array(pool, i8_ty_va, 24) + va_list_alloca: 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: rawptr[llvmlite.Value] = llvmlite.build_bitcast( + va_list_addr: 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 名特殊处理返回地址) self.Gen.VarGen.define_var(trans.SymTab, vararg_name_str, va_list_alloca) # 调用 @llvm.va_start(i8* %va_list_addr) - void_ty_va: rawptr[llvmlite.LLVMType] = llvmlite.Void(pool) + void_ty_va: llvmlite.LLVMType* = llvmlite.Void(pool) llvmlite.build_call(func_builder, "llvm.va_start", va_list_addr, 1, void_ty_va, 0) # 保存到 trans 供 arg(type) 糖函数与 vararg 名翻译使用 @@ -892,8 +900,8 @@ class FuncGenDef(CallGenBase.CallGenBase): # (调用方/包围函数)的 EH 输出参数,翻译完本函数后再恢复——否则 # 下方设置本函数 EH 参数会覆盖外层值,恢复时 old_eh_* 拿到的是 # 本函数自身参数(嵌套函数/多函数链 EH 状态错乱)。 - 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_eh_msg_out: llvmlite.Value* = trans._eh_msg_out_param + old_eh_code_out: 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 @@ -902,31 +910,31 @@ class FuncGenDef(CallGenBase.CallGenBase): # try-except:保存当前函数的 EH 输出参数(__eh_msg_out__/__eh_code_out__) # 供 translate_raise / UnhandledBB 写入并向上传播。无 EH 参数的函数置空。 if string.strcmp(fd.name, "main") != 0 and self.Gen.FuncGenBase._body_has_raise(fd) != 0: - i8_ty_eh2: rawptr[llvmlite.LLVMType] = llvmlite.Int8(pool) - i8_ptr_ty_eh2: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, i8_ty_eh2) - i8_ptr_ptr_ty_eh2: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, i8_ptr_ty_eh2) - i32_ty_eh2: rawptr[llvmlite.LLVMType] = llvmlite.Int32(pool) - i32_ptr_ty_eh2: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, i32_ty_eh2) + i8_ty_eh2: llvmlite.LLVMType* = llvmlite.Int8(pool) + i8_ptr_ty_eh2: llvmlite.LLVMType* = llvmlite.Ptr(pool, i8_ty_eh2) + i8_ptr_ptr_ty_eh2: llvmlite.LLVMType* = llvmlite.Ptr(pool, i8_ptr_ty_eh2) + i32_ty_eh2: llvmlite.LLVMType* = llvmlite.Int32(pool) + i32_ptr_ty_eh2: 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: rawptr[llvmlite.Value] = llvmlite.SSAValue( + msg_out_ref: llvmlite.Value* = llvmlite.SSAValue( pool, i8_ptr_ptr_ty_eh2, "%__eh_msg_out__") - code_out_ref: rawptr[llvmlite.Value] = llvmlite.SSAValue( + code_out_ref: 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 trans._cur_func_has_eh = 1 # 保存模块级作用域状态(仅非变量表相关) - old_func: rawptr[llvmlite.Function] = trans._cur_func - old_builder: rawptr[llvmlite.IRBuilder] = trans._cur_builder + old_func: llvmlite.Function* = trans._cur_func + old_builder: 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: rawptr[llvmlite.Value] = trans._va_list_ptr + old_va_list_ptr: llvmlite.Value* = trans._va_list_ptr old_vararg_name: str = trans._vararg_name # 返回注解上下文([C①] 裸名泛型构造的类型实参回退来源之一): # 进入函数体前记录本函数返回注解,退出时恢复外层函数的值 - old_ret_annot: rawptr[ast.AST] = trans.CurFuncRetAnnot + old_ret_annot: ast.AST* = trans.CurFuncRetAnnot trans._cur_func = func trans._cur_builder = func_builder @@ -945,11 +953,11 @@ class FuncGenDef(CallGenBase.CallGenBase): if body is not None: bn: sizet = len(body) for bi in range(bn): - stmt: rawptr[ast.AST] = body.get(bi) + stmt: ast.AST* = body.get(bi) if stmt is not None: self.Gen.StmtGenDecl.pre_scan_scope_decls(trans, stmt) for bi in range(bn): - stmt: rawptr[ast.AST] = body.get(bi) + stmt: ast.AST* = body.get(bi) if stmt is not None: self.Gen.StmtGenDecl.pre_scan_allocas(trans, stmt) @@ -957,7 +965,7 @@ class FuncGenDef(CallGenBase.CallGenBase): if body is not None: bn2: sizet = len(body) for bi2 in range(bn2): - stmt2: rawptr[ast.AST] = body.get(bi2) + stmt2: ast.AST* = body.get(bi2) if stmt2 is not None: # 嵌套函数定义前:预扫描其链内 nonlocal 并建堆 # (不同层捕获不同变量的场景,见 _prepare_chain_nonlocals) @@ -975,7 +983,7 @@ class FuncGenDef(CallGenBase.CallGenBase): if body is not None: bn3 = len(body) if bn3 > 0: - last_stmt: rawptr[ast.AST] = body.get(bn3 - 1) + last_stmt: ast.AST* = body.get(bn3 - 1) if last_stmt is not None and last_stmt.kind() == ast.ASTKind.Return: last_is_return = 1 if last_is_return == 0: @@ -994,7 +1002,7 @@ class FuncGenDef(CallGenBase.CallGenBase): # 生成 unreachable 而非 fail-fast(GCC/Clang 对 fall-through 视为 UB 同语义)。 last_is_ctrl: int = 0 if bn3 > 0: - last_stmt3: rawptr[ast.AST] = body.get(bn3 - 1) + last_stmt3: ast.AST* = body.get(bn3 - 1) if last_stmt3 is not None: k3: int = last_stmt3.kind() if k3 == ast.ASTKind.If or k3 == ast.ASTKind.While or \ @@ -1022,8 +1030,8 @@ class FuncGenDef(CallGenBase.CallGenBase): fd.returns, imported_modules) != 0: _is_void = 1 elif fd.returns.kind() == ast.ASTKind.Constant: - ret_none_cn: rawptr[ast.Constant] = ( - rawptr[ast.Constant])(fd.returns) + ret_none_cn: ast.Constant* = ( + ast.Constant*)(fd.returns) if ret_none_cn.const_kind == ast.CONST_NONE: _is_void = 1 if _is_void != 0: @@ -1040,7 +1048,7 @@ class FuncGenDef(CallGenBase.CallGenBase): elif fd.returns is None: # 无返回类型注解 → 无返回值过程函数,默认零值返回 if ret_ty is not None: - zero_val: rawptr[llvmlite.Value] = llvmlite.ConstZero(pool, ret_ty) + zero_val: llvmlite.Value* = llvmlite.ConstZero(pool, ret_ty) if zero_val is not None: llvmlite.build_ret(func_builder, zero_val) else: @@ -1118,46 +1126,46 @@ class FuncGenDef(CallGenBase.CallGenBase): # i8* args_ptr, i8* ret_ptr, i8* decor_args_ptr) # 前置返回:0=跳过原函数,1=调用一次,N=循环 N 次 # ============================================================ - def _gen_decor_wrapper(self, trans: rawptr[HT.Translator], - pool: rawptr[memhub.MemBuddy], - mod: rawptr[llvmlite.LLVMModule], - func: rawptr[llvmlite.Function], + def _gen_decor_wrapper(self, trans: HT.Translator*, + pool: memhub.MemBuddy*, + mod: llvmlite.LLVMModule*, + func: llvmlite.Function*, func_name: str, wrapper_name: str, handler_name: str, - decor_arg0: int64) -> rawptr[llvmlite.Function]: + decor_arg0: int64) -> llvmlite.Function*: """生成装饰器 wrapper 函数,返回 wrapper 或 None""" if trans is None or pool is None or mod is None or func is None: return None if func_name is None or wrapper_name is None or handler_name is None: return None - ret_ty: rawptr[llvmlite.LLVMType] = llvmlite.function_get_ret_ty(func) + ret_ty: llvmlite.LLVMType* = llvmlite.function_get_ret_ty(func) if ret_ty is None: return None orig_call_name: str = llvmlite.function_get_name(func) if orig_call_name is None: return None - i32_ty: rawptr[llvmlite.LLVMType] = llvmlite.Int32(pool) - i8_ty: rawptr[llvmlite.LLVMType] = llvmlite.Int8(pool) - i8_ptr_ty: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, i8_ty) + i32_ty: llvmlite.LLVMType* = llvmlite.Int32(pool) + i8_ty: llvmlite.LLVMType* = llvmlite.Int8(pool) + i8_ptr_ty: llvmlite.LLVMType* = llvmlite.Ptr(pool, i8_ty) # ---- 收集原函数参数类型(按位置,最多 16 个)---- n_params: int = 0 - param_tys: sizet | t.CPtr = pool.alloc(16 * 8) + param_tys: sizet* = pool.alloc(16 * 8) if param_tys is None: return None string.memset(param_tys, 0, 16 * 8) - pp: rawptr[llvmlite.Param] = llvmlite.function_get_param_head(func) + pp: llvmlite.Param* = llvmlite.function_get_param_head(func) while pp is not None: - pty: rawptr[llvmlite.LLVMType] = llvmlite.param_get_ty(pp) + pty: llvmlite.LLVMType* = llvmlite.param_get_ty(pp) if pty is not None and n_params < 16: param_tys[n_params] = sizet(pty) n_params += 1 pp = llvmlite.param_get_next(pp) # ---- 创建 wrapper 函数并添加参数(名字 %a0..%aN)---- - wrapper: rawptr[llvmlite.Function] = llvmlite.create_function( + wrapper: llvmlite.Function* = llvmlite.create_function( pool, mod, wrapper_name, ret_ty) if wrapper is None: return None @@ -1166,7 +1174,7 @@ class FuncGenDef(CallGenBase.CallGenBase): pname_w: str = pool.alloc(16) if pname_w is not None: viperlib.snprintf(pname_w, 16, "%%a%d", pi) - llvmlite.add_param(pool, wrapper, (rawptr[llvmlite.LLVMType])(param_tys[pi]), pname_w) + llvmlite.add_param(pool, wrapper, (llvmlite.LLVMType*)(param_tys[pi]), pname_w) # ---- 创建块 ---- entry_bb: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(pool, wrapper, "entry") @@ -1177,7 +1185,7 @@ class FuncGenDef(CallGenBase.CallGenBase): return None # 递归保护标志(最外层):@__decor_rec_{wrapper} = global i8 0 - rec_flag_ref: rawptr[llvmlite.Value] = None + rec_flag_ref: 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) @@ -1187,7 +1195,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: rawptr[llvmlite.IRBuilder] = llvmlite.new_builder(pool, wrapper) + wb: llvmlite.IRBuilder* = llvmlite.new_builder(pool, wrapper) if wb is None: return None @@ -1207,29 +1215,29 @@ class FuncGenDef(CallGenBase.CallGenBase): 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: 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( + rec_val: llvmlite.Value* = llvmlite.build_load(wb, i8_ty, rec_flag_ref) + rec_zero: llvmlite.Value* = llvmlite.ConstInt(pool, i8_ty, 0, "0") + rec_is: 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: rawptr[llvmlite.Value] = None + rec_args: 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: rawptr[llvmlite.Value] = llvmlite.SSAValue( - pool, (rawptr[llvmlite.LLVMType])(param_tys[ri]), an_r) + av_r: llvmlite.Value* = llvmlite.SSAValue( + pool, (llvmlite.LLVMType*)(param_tys[ri]), an_r) if av_r is not None: llvmlite.value_set_next(av_r, None) if rec_args is None: rec_args = av_r else: # 链尾追加 - rt: rawptr[llvmlite.Value] = rec_args + rt: llvmlite.Value* = rec_args while rt.Next is not None: rt = rt.Next llvmlite.value_set_next(rt, av_r) @@ -1237,7 +1245,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: rawptr[llvmlite.Value] = llvmlite.build_call( + rc_res: 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) @@ -1245,43 +1253,43 @@ class FuncGenDef(CallGenBase.CallGenBase): llvmlite.build_ret_void(wb) # decorated_entry:置递归标志,继续装饰路径 llvmlite.position_at_end(wb, dec_bb) - rec_one: rawptr[llvmlite.Value] = llvmlite.ConstInt(pool, i8_ty, 1, "1") + rec_one: 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 # ---- 公共装饰路径(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: rawptr[llvmlite.Value] = llvmlite.build_alloca(wb, ctx_ty) - ctx_ptr: rawptr[llvmlite.Value] = llvmlite.build_bitcast(wb, ctx_alloca, i8_ptr_ty) + ctx_ty: llvmlite.LLVMType* = llvmlite.Array(pool, i8_ty, 32) + ctx_alloca: llvmlite.Value* = llvmlite.build_alloca(wb, ctx_ty) + ctx_ptr: llvmlite.Value* = llvmlite.build_bitcast(wb, ctx_alloca, i8_ptr_ty) # 2. 打包函数参数到结构体 {param_types}(装饰器可读写 args_ptr) - args_alloca: rawptr[llvmlite.Value] = None - args_ptr: rawptr[llvmlite.Value] = None + args_alloca: llvmlite.Value* = None + args_ptr: llvmlite.Value* = None if n_params > 0: - fields_head: rawptr[llvmlite.Function] = None + fields_head: llvmlite.Function* = None fk: int = 0 for fk in range(n_params - 1, -1, -1): - pn_n: rawptr[llvmlite.Function] = llvmlite.new_param_node( - pool, (rawptr[llvmlite.LLVMType])(param_tys[fk])) + pn_n: llvmlite.Function* = llvmlite.new_param_node( + pool, (llvmlite.LLVMType*)(param_tys[fk])) if pn_n is not None: pn_n.Next = fields_head fields_head = pn_n - args_ty: rawptr[llvmlite.LLVMType] = llvmlite.Struct( + args_ty: llvmlite.LLVMType* = llvmlite.Struct( pool, fields_head, n_params, None) if args_ty is not None: args_alloca = llvmlite.build_alloca(wb, args_ty) fi2: int = 0 for fi2 in range(n_params): - fld_ty: rawptr[llvmlite.LLVMType] = (rawptr[llvmlite.LLVMType])(param_tys[fi2]) - fld_ptr: rawptr[llvmlite.Value] = llvmlite.build_gep_struct( + fld_ty: llvmlite.LLVMType* = (llvmlite.LLVMType*)(param_tys[fi2]) + fld_ptr: 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: rawptr[llvmlite.Value] = llvmlite.SSAValue( + fld_v: llvmlite.Value* = llvmlite.SSAValue( pool, fld_ty, fld_nm) if fld_v is not None: llvmlite.build_store(wb, fld_v, fld_ptr) @@ -1290,10 +1298,10 @@ class FuncGenDef(CallGenBase.CallGenBase): args_ptr = llvmlite.ConstNull(pool, i8_ptr_ty, "null") # 3. 返回值存储(零初始化;跳过原函数时返回安全默认值) - ret_alloca: rawptr[llvmlite.Value] = None + ret_alloca: llvmlite.Value* = None if ret_is_void == 0: ret_alloca = llvmlite.build_alloca(wb, ret_ty) - ret_zero: rawptr[llvmlite.Value] = None + ret_zero: llvmlite.Value* = None match ret_ty: case llvmlite.LLVMType.Int(_): ret_zero = llvmlite.ConstInt(pool, ret_ty, 0, "0") @@ -1305,14 +1313,14 @@ class FuncGenDef(CallGenBase.CallGenBase): llvmlite.build_store(wb, ret_zero, ret_alloca) # 4. 函数名字符串常量 - fn_str: rawptr[llvmlite.Value] = self.Gen.ExprGenConst.create_global_string( + fn_str: 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") # 5. handler 声明(未翻译时 declare,固定签名 i32 (i8*,i8*,i32,i8*,i8*,i8*)) if self.Gen.CallGenBase.find_func_in_module(mod, handler_name) is None: - handler_d: rawptr[llvmlite.Function] = llvmlite.create_declare( + handler_d: llvmlite.Function* = llvmlite.create_declare( pool, mod, handler_name, i32_ty) if handler_d is not None: llvmlite.add_param(pool, handler_d, i8_ptr_ty, "ctx") @@ -1323,9 +1331,9 @@ class FuncGenDef(CallGenBase.CallGenBase): llvmlite.add_param(pool, handler_d, i8_ptr_ty, "decor_args_ptr") # 6. 前置阶段:handler 返回调用次数 n_calls - 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") + ph0: llvmlite.Value* = llvmlite.ConstInt(pool, i32_ty, 0, "0") + null_ret: llvmlite.Value* = llvmlite.ConstNull(pool, i8_ptr_ty, "null") + null_dec: 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: @@ -1338,49 +1346,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: rawptr[llvmlite.Value] = llvmlite.build_call( + n_calls: llvmlite.Value* = llvmlite.build_call( wb, handler_name, ctx_ptr, 6, i32_ty, 0) # 7. 计数器 alloca(TPV 用 alloca 计数器替代 phi) - cnt_alloca: rawptr[llvmlite.Value] = llvmlite.build_alloca(wb, i32_ty) - cnt_zero: rawptr[llvmlite.Value] = llvmlite.ConstInt(pool, i32_ty, 0, "0") + cnt_alloca: llvmlite.Value* = llvmlite.build_alloca(wb, i32_ty) + cnt_zero: 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: rawptr[llvmlite.Value] = llvmlite.build_load(wb, i32_ty, cnt_alloca) - loop_cond: rawptr[llvmlite.Value] = llvmlite.build_icmp( + cur_i: llvmlite.Value* = llvmlite.build_load(wb, i32_ty, cnt_alloca) + loop_cond: 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: rawptr[llvmlite.Value] = None + call_args: 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: rawptr[llvmlite.Value] = llvmlite.build_gep_struct( + fld_ty_k: llvmlite.LLVMType* = (llvmlite.LLVMType*)(param_tys[k]) + fld_pk: llvmlite.Value* = llvmlite.build_gep_struct( wb, args_ty, fld_ty_k, args_alloca, k) if fld_pk is None: continue - fld_vk: rawptr[llvmlite.Value] = llvmlite.build_load(wb, fld_ty_k, fld_pk) + fld_vk: 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: rawptr[llvmlite.Value] = call_args + ct: llvmlite.Value* = call_args while ct.Next is not None: ct = ct.Next llvmlite.value_set_next(ct, fld_vk) - res_v: rawptr[llvmlite.Value] = llvmlite.build_call( + res_v: 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: rawptr[llvmlite.Value] = llvmlite.build_add( + nxt_i: 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) @@ -1388,10 +1396,10 @@ class FuncGenDef(CallGenBase.CallGenBase): # 10. post:handler 后置 → 清递归标志 → 返回结果 llvmlite.position_at_end(wb, post_bb) - ret_ptr: rawptr[llvmlite.Value] = null_ret + ret_ptr: llvmlite.Value* = null_ret if ret_alloca is not None: ret_ptr = llvmlite.build_bitcast(wb, ret_alloca, i8_ptr_ty) - ph1: rawptr[llvmlite.Value] = llvmlite.ConstInt(pool, i32_ty, 1, "1") + ph1: 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) @@ -1405,13 +1413,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: rawptr[llvmlite.Value] = llvmlite.ConstInt(pool, i8_ty, 0, "0") + rec_zero2: 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: rawptr[llvmlite.Value] = llvmlite.build_load(wb, ret_ty, ret_alloca) + final_v: llvmlite.Value* = llvmlite.build_load(wb, ret_ty, ret_alloca) if final_v is not None: llvmlite.build_ret(wb, final_v) else: diff --git a/App/lib/core/Gen/Func/FuncGenMixin.vp b/App/lib/core/Gen/Func/FuncGenMixin.vp index 3bcec90..4661cef 100644 --- a/App/lib/core/Gen/Func/FuncGenMixin.vp +++ b/App/lib/core/Gen/Func/FuncGenMixin.vp @@ -74,20 +74,20 @@ class FuncGenMixin(CallGenBase.CallGenBase): # 闭包结构: {i8* fn_ptr, i8* env_ptr} (16 字节, malloc 分配) # Env 结构: {i8* ptr0, i8* ptr1, ...} (每个 nonlocal 变量 8 字节,指向父函数 alloca) # ============================================================ - def translate_nested_function_def(self, trans: rawptr[HT.Translator], - node: rawptr[ast.AST]) -> int: + def translate_nested_function_def(self, trans: HT.Translator*, + node: ast.AST*) -> int: """翻译嵌套函数定义:提升为顶层函数 + 创建闭包""" - fd: rawptr[ast.FunctionDef] = rawptr[ast.FunctionDef](node) + fd: ast.FunctionDef* = ast.FunctionDef*(node) if fd is None or fd.name is None: return 0 - pool: rawptr[memhub.MemBuddy] = trans.Pool - mod: rawptr[llvmlite.LLVMModule] = trans.Module + pool: memhub.MemBuddy* = trans.Pool + mod: llvmlite.LLVMModule* = trans.Module func_name: str = fd.name - i32_ty: rawptr[llvmlite.LLVMType] = llvmlite.Int32(pool) - i8_ty: rawptr[llvmlite.LLVMType] = llvmlite.Int8(pool) - i8_ptr_ty: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, i8_ty) + i32_ty: llvmlite.LLVMType* = llvmlite.Int32(pool) + i8_ty: llvmlite.LLVMType* = llvmlite.Int8(pool) + i8_ptr_ty: llvmlite.LLVMType* = llvmlite.Ptr(pool, i8_ty) # 1. 构建提升后的函数名: __closure_{name}(加 SHA1 前缀避免跨模块冲突) promoted_name: str = pool.alloc(64) @@ -96,7 +96,7 @@ class FuncGenMixin(CallGenBase.CallGenBase): mangled_promoted: str = self.Gen.FuncGenBase._mangle_name(trans, promoted_name) # 2. 创建提升后的函数: define i32 @__closure_{name}(i8* %env, args...) - func: rawptr[llvmlite.Function] = llvmlite.create_function( + func: llvmlite.Function* = llvmlite.create_function( pool, mod, mangled_promoted, i32_ty) if func is None: return 0 @@ -111,20 +111,20 @@ class FuncGenMixin(CallGenBase.CallGenBase): string.memset(param_tys, 0, 8 * 64) param_count: int = 0 if fd.args is not None: - ags_n: rawptr[ast.Arguments] = rawptr[ast.Arguments](fd.args) + ags_n: ast.Arguments* = ast.Arguments*(fd.args) if ags_n.args is not None: alist_n: list[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)) + arg_n: ast.Arg* = ast.Arg*(alist_n.get(ai_n)) if arg_n is None or arg_n.arg is None: continue if arg_n.annotation is not None: if self.Gen.TypeGenResolve._is_t_attr(arg_n.annotation, "CVoid", imported_modules) != 0: continue - pty_n: rawptr[llvmlite.LLVMType] = i32_ty + pty_n: llvmlite.LLVMType* = i32_ty if arg_n.annotation is not None: - resolved_n: rawptr[llvmlite.LLVMType] = self.Gen.TypeGenResolve.resolve_annotation_type( + resolved_n: llvmlite.LLVMType* = self.Gen.TypeGenResolve.resolve_annotation_type( pool, arg_n.annotation, imported_modules, from_imports, trans, 0) if resolved_n is not None: match resolved_n: @@ -148,7 +148,7 @@ class FuncGenMixin(CallGenBase.CallGenBase): entry_blk: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(pool, func, "entry") if entry_blk is None: return 0 - func_builder: rawptr[llvmlite.IRBuilder] = llvmlite.new_builder(pool, func) + func_builder: llvmlite.IRBuilder* = llvmlite.new_builder(pool, func) if func_builder is None: return 0 llvmlite.position_at_end(func_builder, entry_blk) @@ -157,22 +157,22 @@ class FuncGenMixin(CallGenBase.CallGenBase): self.Gen.VarGen.enter_scope(trans.SymTab, SCOPE_FUNCTION) # 5. 创建 _env_ptr alloca 并存储 %env 参数 - env_alloca: rawptr[llvmlite.Value] = llvmlite.build_alloca(func_builder, i8_ptr_ty) + env_alloca: 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: rawptr[llvmlite.Value] = llvmlite.SSAValue(pool, i8_ptr_ty, "%env") + env_param_val: llvmlite.Value* = llvmlite.SSAValue(pool, i8_ptr_ty, "%env") llvmlite.build_store(func_builder, env_param_val, env_alloca) # 5a. 创建嵌套函数参数 alloca(函数体内参数名可引用,如 # accumulate(n) 内 for i in range(n)、set_result(val) 内 result = val) if fd.args is not None: - ags_p: rawptr[ast.Arguments] = rawptr[ast.Arguments](fd.args) + ags_p: ast.Arguments* = ast.Arguments*(fd.args) if ags_p.args is not None: alist_p: list[ast.AST*]* = ags_p.args idx_p: int = 0 apn: sizet = len(alist_p) for api in range(apn): - arg_p: rawptr[ast.Arg] = rawptr[ast.Arg](alist_p.get(api)) + arg_p: ast.Arg* = ast.Arg*(alist_p.get(api)) if arg_p is None or arg_p.arg is None: continue if arg_p.annotation is not None: @@ -180,14 +180,14 @@ class FuncGenMixin(CallGenBase.CallGenBase): continue if idx_p >= param_count: break - pty2_n: rawptr[llvmlite.LLVMType] = i32_ty + pty2_n: llvmlite.LLVMType* = i32_ty if param_tys is not None: ty_addr_n: uint64 = uint64(param_tys) + idx_p * 8 ty_slot_n: str | t.CPtr = (t.CPtr)(ty_addr_n) - pty2_n = (rawptr[llvmlite.LLVMType])(ty_slot_n[0]) + pty2_n = (llvmlite.LLVMType*)(ty_slot_n[0]) if pty2_n is None: pty2_n = i32_ty - p_alloca: rawptr[llvmlite.Value] = llvmlite.build_alloca(func_builder, pty2_n) + p_alloca: 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: @@ -196,6 +196,13 @@ class FuncGenMixin(CallGenBase.CallGenBase): if cls_nm_p is not None: self.Gen.VarGen.set_var_annot_class_name( trans.SymTab, arg_p.arg, cls_nm_p) + # const 形参:沿用 TPC 形参的历史判据(只看注解是否含 + # t.CConst,不看指针层数),两侧逐条对齐(见 + # Debugger/type-descriptors.md 已知差异)。 + if self.Gen.TypeGenErr.has_decorator_marker( + arg_p.annotation, "CConst", 0) != 0: + self.Gen.VarGen.set_var_const( + trans.SymTab, arg_p.arg) # t.CVolatile 形参:声明期标记(与 FuncGenDef 主路径同款), # 函数体内该参数名的 load/store 带 volatile。 if self.Gen.TypeGenErr.has_decorator_marker( @@ -211,15 +218,15 @@ 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: rawptr[llvmlite.Value] = llvmlite.SSAValue(pool, pty2_n, pname2_n) + p_val: llvmlite.Value* = llvmlite.SSAValue(pool, pty2_n, pname2_n) vol_pn: int = self.Gen.VarGen.var_is_volatile( self.Gen.VarGen.lookup_var_entry(trans.SymTab, arg_p.arg)) llvmlite.build_store(func_builder, p_val, p_alloca, vol_pn) idx_p += 1 # 6. 保存父函数作用域状态(仅非变量表相关) - old_func: rawptr[llvmlite.Function] = trans._cur_func - old_builder: rawptr[llvmlite.IRBuilder] = trans._cur_builder + old_func: llvmlite.Function* = trans._cur_func + old_builder: 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 @@ -250,11 +257,11 @@ class FuncGenMixin(CallGenBase.CallGenBase): if body is not None: bn: sizet = len(body) for bi in range(bn): - stmt: rawptr[ast.AST] = body.get(bi) + stmt: ast.AST* = body.get(bi) if stmt is not None: self.Gen.StmtGenDecl.pre_scan_scope_decls(trans, stmt) for bi in range(bn): - stmt: rawptr[ast.AST] = body.get(bi) + stmt: ast.AST* = body.get(bi) if stmt is not None: self.Gen.StmtGenDecl.pre_scan_allocas(trans, stmt) @@ -266,7 +273,7 @@ class FuncGenMixin(CallGenBase.CallGenBase): if body is not None: bnc: sizet = len(body) for bic in range(bnc): - stmtc: rawptr[ast.AST] = body.get(bic) + stmtc: ast.AST* = body.get(bic) if stmtc is not None: self._closure_scan_captures(trans, stmtc) @@ -274,7 +281,7 @@ class FuncGenMixin(CallGenBase.CallGenBase): if body is not None: bn2: sizet = len(body) for bi2 in range(bn2): - stmt2: rawptr[ast.AST] = body.get(bi2) + stmt2: ast.AST* = body.get(bi2) if stmt2 is not None: self.Gen.StmtGen.translate_stmt(trans, stmt2) @@ -283,11 +290,11 @@ class FuncGenMixin(CallGenBase.CallGenBase): if body is not None: bn3: sizet = len(body) if bn3 > 0: - last_stmt: rawptr[ast.AST] = body.get(bn3 - 1) + last_stmt: ast.AST* = body.get(bn3 - 1) if last_stmt is not None and last_stmt.kind() == ast.ASTKind.Return: last_is_return = 1 if last_is_return == 0: - zero_val: rawptr[llvmlite.Value] = llvmlite.const_int32(pool, 0) + zero_val: llvmlite.Value* = llvmlite.const_int32(pool, 0) llvmlite.build_ret(func_builder, zero_val) # 11. 保存嵌套函数的 nonlocal 信息 @@ -300,7 +307,7 @@ class FuncGenMixin(CallGenBase.CallGenBase): # NOTE: _nonlocal_names 和 _nonlocal_name_count 仍为嵌套函数的值 # 13. 在父函数中创建闭包对象 - parent_builder: rawptr[llvmlite.IRBuilder] = old_builder + parent_builder: llvmlite.IRBuilder* = old_builder if parent_builder is None: # 无 builder(模块级嵌套函数?)→ 无法创建闭包,仅恢复状态 trans._cur_func_name = old_func_name @@ -313,10 +320,10 @@ class FuncGenMixin(CallGenBase.CallGenBase): # 13a. 创建 env: malloc(8 * nested_nonlocal_count) — env 存储指针数组 # 每个 nonlocal 变量占 8 字节(i8*),指向父函数的 alloca(共享存储) - env_ptr: rawptr[llvmlite.Value] = None + env_ptr: llvmlite.Value* = None if nested_nonlocal_count > 0: env_size: int64 = nested_nonlocal_count * 8 - env_size_val: rawptr[llvmlite.Value] = llvmlite.const_int64(pool, env_size) + env_size_val: 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( @@ -333,7 +340,7 @@ class FuncGenMixin(CallGenBase.CallGenBase): # → 从父函数 env 读该变量的堆地址(_load_raw_var_ptr), # env[ni] = 同一堆地址(运行时链式共享,各层写同一堆) if env_ptr is not None: - i8_ptr_ptr_ty: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, i8_ptr_ty) + i8_ptr_ptr_ty: llvmlite.LLVMType* = llvmlite.Ptr(pool, i8_ptr_ty) for ni in range(nested_nonlocal_count): # 从 _nonlocal_names 缓冲区读取名称 name_addr: uint64 = uint64(trans._nonlocal_names) + ni * 8 @@ -341,7 +348,7 @@ class FuncGenMixin(CallGenBase.CallGenBase): nl_name: str = nl_slot[0] if nl_name is None: continue - heap_store: rawptr[llvmlite.Value] = None + heap_store: llvmlite.Value* = None # 1. 优先查全局堆地址映射(_prepare_chain_nonlocals 已为 # 链内 nonlocal 建堆并 store 到 @nlheap.*;不同层捕获 # 不同变量时(ClosureTest2 Test 7)level2 的 b 经此共享) @@ -349,47 +356,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: rawptr[llvmlite.Value] = self._nl_heap_global_ref( + gv_ref0: 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: rawptr[llvmlite.Value] = self.Gen.VarGen.lookup_current( + local_alloca: 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 + nl_load_ty: llvmlite.LLVMType* = local_alloca.Ty.Pointee if nl_load_ty is not None: - cur_val_nl: rawptr[llvmlite.Value] = llvmlite.build_load( + cur_val_nl: 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: rawptr[llvmlite.Value] = llvmlite.const_int64( + st_size_val: llvmlite.Value* = llvmlite.const_int64( pool, st_size) if st_size_val is not None: st_size_val.Next = None - var_storage: rawptr[llvmlite.Value] = llvmlite.build_call( + var_storage: 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: rawptr[llvmlite.Value] = llvmlite.build_bitcast( + st_slot_nl: 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: rawptr[GenTypes.VarEntry] = self.Gen.VarGen.lookup_var_entry( + ve_nl: GenTypes.VarEntry* = self.Gen.VarGen.lookup_var_entry( trans.SymTab, nl_name) - heap_typed: rawptr[llvmlite.Value] = llvmlite.build_bitcast( + heap_typed: 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: rawptr[llvmlite.Value] = None + gv_ref_new: llvmlite.Value* = None if gname_ck is not None \ and self._nl_heap_global_exists(mod, gname_ck) == 0: - gv_new: rawptr[llvmlite.GlobalVariable] = \ + gv_new: llvmlite.GlobalVariable* = \ llvmlite.new_global_variable(pool, gname_ck, i8_ptr_ty) if gv_new is not None: # 清除 external linkage + 零初始化(防 undefined reference) @@ -408,20 +415,20 @@ class FuncGenMixin(CallGenBase.CallGenBase): if heap_store is None: continue # env[ni] = 堆存储地址(共享) - offset_val: rawptr[llvmlite.Value] = llvmlite.const_int32(pool, ni * 8) - slot: rawptr[llvmlite.Value] = llvmlite.build_gep( + offset_val: llvmlite.Value* = llvmlite.const_int32(pool, ni * 8) + slot: llvmlite.Value* = llvmlite.build_gep( parent_builder, i8_ty, env_ptr, offset_val) if slot is not None: - slot_typed: rawptr[llvmlite.Value] = llvmlite.build_bitcast( + slot_typed: 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: rawptr[llvmlite.Value] = llvmlite.const_int64(pool, 16) + closure_size_val: llvmlite.Value* = llvmlite.const_int64(pool, 16) if closure_size_val is not None: closure_size_val.Next = None - closure_ptr: rawptr[llvmlite.Value] = llvmlite.build_call( + closure_ptr: llvmlite.Value* = llvmlite.build_call( parent_builder, "malloc", closure_size_val, 1, i8_ptr_ty, 0) if closure_ptr is None: # malloc 失败,恢复状态 @@ -435,9 +442,9 @@ class FuncGenMixin(CallGenBase.CallGenBase): # 13c. 存储 fn_ptr 到 offset 0 # 创建函数指针类型 i32(i8*)* - fn_param_node: rawptr[llvmlite.Function] = llvmlite.new_param_node(pool, i8_ptr_ty) - fn_func_ty: rawptr[llvmlite.LLVMType] = llvmlite.Func(pool, i32_ty, fn_param_node, 1) - fn_func_ptr_ty: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, fn_func_ty) + fn_param_node: llvmlite.Function* = llvmlite.new_param_node(pool, i8_ptr_ty) + fn_func_ty: llvmlite.LLVMType* = llvmlite.Func(pool, i32_ty, fn_param_node, 1) + fn_func_ptr_ty: llvmlite.LLVMType* = llvmlite.Ptr(pool, fn_func_ty) # 创建函数引用 Value(类型为 i32(i8*)*,使用 SHA1 混淆名) fn_ptr_name: str = pool.alloc(64) @@ -447,33 +454,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: rawptr[llvmlite.Value] = llvmlite.SSAValue(pool, fn_func_ptr_ty, fn_ptr_name) + fn_ptr_val: llvmlite.Value* = llvmlite.SSAValue(pool, fn_func_ptr_ty, fn_ptr_name) # bitcast 函数指针到 i8*(闭包存储 i8* 类型) - fn_as_i8ptr: rawptr[llvmlite.Value] = llvmlite.build_bitcast( + fn_as_i8ptr: llvmlite.Value* = llvmlite.build_bitcast( parent_builder, fn_ptr_val, i8_ptr_ty) - fn_slot: rawptr[llvmlite.Value] = llvmlite.build_bitcast( + fn_slot: 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: rawptr[llvmlite.Value] = llvmlite.const_int32(pool, 8) - env_slot_addr: rawptr[llvmlite.Value] = llvmlite.build_gep( + eight_val: llvmlite.Value* = llvmlite.const_int32(pool, 8) + env_slot_addr: llvmlite.Value* = llvmlite.build_gep( parent_builder, i8_ty, closure_ptr, eight_val) if env_slot_addr is not None: - env_slot: rawptr[llvmlite.Value] = llvmlite.build_bitcast( + env_slot: 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: rawptr[llvmlite.Value] = llvmlite.SSAValue(pool, i8_ptr_ty, "null") + null_val: llvmlite.Value* = llvmlite.SSAValue(pool, i8_ptr_ty, "null") llvmlite.build_store(parent_builder, null_val, env_slot) # 13e. 将闭包指针存储到父函数的局部变量 {func_name} - closure_alloca: rawptr[llvmlite.Value] = self.Gen.VarGen._alloca_at_entry(parent_builder, i8_ptr_ty) + closure_alloca: 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) @@ -497,14 +504,14 @@ class FuncGenMixin(CallGenBase.CallGenBase): # 属于父函数 → llc "use of undefined value")。故对嵌套 def 做等价预扫描:把"读取的外层 # 函数局部变量"注册为 nonlocal(复用 env 共享堆机制),使 read 走 _load_raw_var_ptr 从堆读。 # 注意:注册顺序必须与 step 13 的 env 构建一致(本扫描在 body 翻译前执行,顺序稳定)。 - def _closure_scan_captures(self, trans: rawptr[HT.Translator], - node: rawptr[ast.AST]) -> int: + def _closure_scan_captures(self, trans: HT.Translator*, + node: ast.AST*) -> int: """递归扫描节点中的隐式捕获并注册为 nonlocal""" if node is None or trans is None: return 1 k: int = node.kind() if k == ast.ASTKind.Name: - nm: rawptr[ast.Name] = rawptr[ast.Name](node) + nm: ast.Name* = ast.Name*(node) if nm.id is None: return 1 # 当前作用域已定义(参数 / AnnAssign 局部,含分支内)→ 非捕获 @@ -513,15 +520,15 @@ class FuncGenMixin(CallGenBase.CallGenBase): # 已注册 nonlocal(显式 nonlocal 语句 / 已捕获)→ 跳过 if GenApi.is_nonlocal_name(trans, nm.id) != 0: return 1 - ve: rawptr[GenTypes.VarEntry] = self.Gen.VarGen.lookup_var_entry( + ve: 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 - nl_ty: rawptr[llvmlite.LLVMType] = ve.Alloca.Ty.Pointee + nl_ty: llvmlite.LLVMType* = ve.Alloca.Ty.Pointee if nl_ty is None: return 1 # 模块级全局直接解析,无需 env 捕获 - mod_gv: rawptr[llvmlite.Value] = self.Gen.VarGen.lookup_module_var( + mod_gv: 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): @@ -531,12 +538,12 @@ class FuncGenMixin(CallGenBase.CallGenBase): return 1 # ---- 语句 ---- if k == ast.ASTKind.Assign: - asn: rawptr[ast.Assign] = rawptr[ast.Assign](node) + asn: ast.Assign* = ast.Assign*(node) if asn.value is not None: self._closure_scan_captures(trans, asn.value) return 1 if k == ast.ASTKind.AnnAssign: - aan: rawptr[ast.AnnAssign] = rawptr[ast.AnnAssign](node) + aan: ast.AnnAssign* = ast.AnnAssign*(node) if aan.value is not None: self._closure_scan_captures(trans, aan.value) return 1 @@ -599,11 +606,11 @@ class FuncGenMixin(CallGenBase.CallGenBase): self._closure_scan_captures(trans, ex_n.value) return 1 if k == ast.ASTKind.With: - wth: rawptr[ast.With] = rawptr[ast.With](node) + wth: ast.With* = ast.With*(node) if wth.items is not None: bn_wi: sizet = len(wth.items) for bi_wi in range(bn_wi): - wi_n: rawptr[ast.AST] = wth.items.get(bi_wi) + wi_n: ast.AST* = wth.items.get(bi_wi) if wi_n is not None and wi_n.kind() == ast.ASTKind.WithItem: wi_c: rawptr[ast.WithItem] = rawptr[ast.WithItem](wi_n) if wi_c.context_expr is not None: @@ -628,7 +635,7 @@ class FuncGenMixin(CallGenBase.CallGenBase): self._closure_scan_captures(trans, as_n.msg) return 1 if k == ast.ASTKind.Try: - tr_n: rawptr[ast.Try] = rawptr[ast.Try](node) + tr_n: ast.Try* = ast.Try*(node) if tr_n.children is not None: bn_t: sizet = len(tr_n.children) for bi_t in range(bn_t): @@ -636,9 +643,9 @@ class FuncGenMixin(CallGenBase.CallGenBase): if tr_n.handlers is not None: bn_th: sizet = len(tr_n.handlers) for bi_th in range(bn_th): - eh_n: rawptr[ast.AST] = tr_n.handlers.get(bi_th) + eh_n: ast.AST* = tr_n.handlers.get(bi_th) if eh_n is not None and eh_n.kind() == ast.ASTKind.ExceptHandler: - eh_c: rawptr[ast.ExceptHandler] = rawptr[ast.ExceptHandler](eh_n) + eh_c: ast.ExceptHandler* = ast.ExceptHandler*(eh_n) if eh_c.children is not None: bn_ehb: sizet = len(eh_c.children) for bi_ehb in range(bn_ehb): @@ -653,13 +660,13 @@ class FuncGenMixin(CallGenBase.CallGenBase): self._closure_scan_captures(trans, tr_n.finalbody.get(bi_tf)) return 1 if k == ast.ASTKind.Match: - mt_n: rawptr[ast.Match] = rawptr[ast.Match](node) + mt_n: ast.Match* = ast.Match*(node) if mt_n.subject is not None: self._closure_scan_captures(trans, mt_n.subject) if mt_n.cases is not None: bn_mc: sizet = len(mt_n.cases) for bi_mc in range(bn_mc): - mc_n: rawptr[ast.AST] = mt_n.cases.get(bi_mc) + mc_n: ast.AST* = mt_n.cases.get(bi_mc) if mc_n is not None and mc_n.kind() == ast.ASTKind.MatchCase: mc_c: rawptr[ast.MatchCase] = rawptr[ast.MatchCase](mc_n) if mc_c.guard is not None: @@ -671,14 +678,14 @@ class FuncGenMixin(CallGenBase.CallGenBase): return 1 # ---- 表达式 ---- if k == ast.ASTKind.BinOp: - bop: rawptr[ast.BinOp] = rawptr[ast.BinOp](node) + bop: ast.BinOp* = ast.BinOp*(node) if bop.left is not None: self._closure_scan_captures(trans, bop.left) if bop.right is not None: self._closure_scan_captures(trans, bop.right) return 1 if k == ast.ASTKind.UnaryOp: - uop: rawptr[ast.UnaryOp] = rawptr[ast.UnaryOp](node) + uop: ast.UnaryOp* = ast.UnaryOp*(node) if uop.operand is not None: self._closure_scan_captures(trans, uop.operand) return 1 @@ -699,7 +706,7 @@ class FuncGenMixin(CallGenBase.CallGenBase): self._closure_scan_captures(trans, cmp.comparators.get(bi_cmp)) return 1 if k == ast.ASTKind.Call: - cal: rawptr[ast.Call] = rawptr[ast.Call](node) + cal: ast.Call* = ast.Call*(node) if cal.func is not None: self._closure_scan_captures(trans, cal.func) if cal.args is not None: @@ -709,21 +716,21 @@ class FuncGenMixin(CallGenBase.CallGenBase): if cal.keywords is not None: bn_ck: sizet = len(cal.keywords) for bi_ck in range(bn_ck): - kw_n: rawptr[ast.AST] = cal.keywords.get(bi_ck) + kw_n: ast.AST* = cal.keywords.get(bi_ck) if kw_n is not None and kw_n.kind() == ast.ASTKind.Keyword: 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 if k == ast.ASTKind.Subscript: - sub: rawptr[ast.Subscript] = rawptr[ast.Subscript](node) + sub: ast.Subscript* = ast.Subscript*(node) if sub.value is not None: self._closure_scan_captures(trans, sub.value) if sub.slice is not None: self._closure_scan_captures(trans, sub.slice) return 1 if k == ast.ASTKind.Attribute: - at_n: rawptr[ast.Attribute] = rawptr[ast.Attribute](node) + at_n: ast.Attribute* = ast.Attribute*(node) if at_n.value is not None: self._closure_scan_captures(trans, at_n.value) return 1 @@ -755,14 +762,14 @@ class FuncGenMixin(CallGenBase.CallGenBase): self._closure_scan_captures(trans, st_n.elts.get(bi_set)) return 1 if k == ast.ASTKind.List: - ls_n: rawptr[ast.List] = rawptr[ast.List](node) + ls_n: ast.List* = ast.List*(node) if ls_n.elts is not None: bn_ls: sizet = len(ls_n.elts) for bi_ls in range(bn_ls): self._closure_scan_captures(trans, ls_n.elts.get(bi_ls)) return 1 if k == ast.ASTKind.Tuple: - tp_n: rawptr[ast.Tuple] = rawptr[ast.Tuple](node) + tp_n: ast.Tuple* = ast.Tuple*(node) if tp_n.elts is not None: bn_tp: sizet = len(tp_n.elts) for bi_tp in range(bn_tp): @@ -830,7 +837,7 @@ class FuncGenMixin(CallGenBase.CallGenBase): if lc_n.generators is not None: bn_gen: sizet = len(lc_n.generators) for bi_gen in range(bn_gen): - cp_n: rawptr[ast.AST] = lc_n.generators.get(bi_gen) + cp_n: ast.AST* = lc_n.generators.get(bi_gen) if cp_n is not None and cp_n.kind() == ast.ASTKind.Comprehension: cp_c: rawptr[ast.Comprehension] = rawptr[ast.Comprehension](cp_n) if cp_c.iter is not None: @@ -849,7 +856,7 @@ class FuncGenMixin(CallGenBase.CallGenBase): if dcn.generators is not None: bn_dgen: sizet = len(dcn.generators) for bi_dgen in range(bn_dgen): - cp_dn: rawptr[ast.AST] = dcn.generators.get(bi_dgen) + cp_dn: ast.AST* = dcn.generators.get(bi_dgen) if cp_dn is not None and cp_dn.kind() == ast.ASTKind.Comprehension: cp_dc: rawptr[ast.Comprehension] = rawptr[ast.Comprehension](cp_dn) if cp_dc.iter is not None: @@ -868,8 +875,8 @@ class FuncGenMixin(CallGenBase.CallGenBase): # 注:`case _`(Void/Struct/Func 等)仍返回 8——不是静默兜底,而是**算不出** # (结构体尺寸需查布局表,本函数只做 LLVMType 递归);改 fatal 会拒绝 # "nonlocal 结构体"这一合法用法,需先补布局查询能力。 - def _type_byte_size(self, pool: rawptr[memhub.MemBuddy], - ty: rawptr[llvmlite.LLVMType]) -> int: + def _type_byte_size(self, pool: memhub.MemBuddy*, + ty: llvmlite.LLVMType*) -> int: """计算 LLVM 类型占用的字节大小(递归)""" if ty is None: # [S4 fail-fast] 类型缺失 → 不再保守 8 字节(分配不足会越界写邻块) @@ -902,8 +909,8 @@ class FuncGenMixin(CallGenBase.CallGenBase): # 变量名: nlheap_{sha1}.{name}(全局变量,跨函数可见;SSA 编号是函数 # 局部的,跨函数传递堆地址只能经全局变量/模块级映射)。 # ============================================================ - def _nl_heap_global_name(self, pool: rawptr[memhub.MemBuddy], - trans: rawptr[HT.Translator], + def _nl_heap_global_name(self, pool: memhub.MemBuddy*, + trans: HT.Translator*, name: str) -> str: """构造 nonlocal 堆地址全局映射变量名 nlheap_{sha1}.{name}""" if pool is None or trans is None or name is None: @@ -917,17 +924,17 @@ class FuncGenMixin(CallGenBase.CallGenBase): # ============================================================ # _nl_heap_global_ref - 全局映射变量引用 Value(i8**) # ============================================================ - def _nl_heap_global_ref(self, pool: rawptr[memhub.MemBuddy], - trans: rawptr[HT.Translator], - name: str) -> rawptr[llvmlite.Value]: + def _nl_heap_global_ref(self, pool: memhub.MemBuddy*, + trans: HT.Translator*, + name: str) -> llvmlite.Value*: """获取 nonlocal 堆地址全局映射变量的引用(@"..." 引号包裹)""" if pool is None or trans is None or name is None: return None gname: str = self._nl_heap_global_name(pool, trans, name) if gname is None: return None - i8_ty: rawptr[llvmlite.LLVMType] = llvmlite.Int8(pool) - i8_ptr_ty: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, i8_ty) + i8_ty: llvmlite.LLVMType* = llvmlite.Int8(pool) + i8_ptr_ty: llvmlite.LLVMType* = llvmlite.Ptr(pool, i8_ty) ref_buf: str = pool.alloc(176) if ref_buf is None: return None @@ -937,12 +944,12 @@ class FuncGenMixin(CallGenBase.CallGenBase): # ============================================================ # _nl_heap_global_exists - 检查 nonlocal 堆地址全局映射变量是否存在 # ============================================================ - def _nl_heap_global_exists(self, mod: rawptr[llvmlite.LLVMModule], + def _nl_heap_global_exists(self, mod: llvmlite.LLVMModule*, gname: str) -> int: """检查全局映射变量 gname 是否已在模块中,1=存在""" if mod is None or gname is None: return 0 - gcur: rawptr[llvmlite.GlobalVariable] = mod.GlobalHead + gcur: llvmlite.GlobalVariable* = mod.GlobalHead while gcur is not None: if gcur.Name is not None and string.strcmp(gcur.Name, gname) == 0: return 1 @@ -955,20 +962,20 @@ class FuncGenMixin(CallGenBase.CallGenBase): # 遍历 node(FunctionDef)的 children:遇嵌套 FunctionDef 递归, # 遇 Nonlocal 语句收集变量名(去重)。返回更新后的计数。 # ============================================================ - def _collect_chain_nonlocals(self, trans: rawptr[HT.Translator], - node: rawptr[ast.AST], + def _collect_chain_nonlocals(self, trans: HT.Translator*, + node: ast.AST*, names: t.CPtr, count: int) -> int: """递归收集 node(FunctionDef)链内所有 nonlocal 声明名(去重)""" if node is None or names is None: return count - fd: rawptr[ast.FunctionDef] = rawptr[ast.FunctionDef](node) + fd: ast.FunctionDef* = ast.FunctionDef*(node) if fd is None or fd.children is None: return count ch: list[ast.AST*]* = fd.children cn: sizet = len(ch) for ci in range(cn): - st: rawptr[ast.AST] = ch.get(ci) + st: ast.AST* = ch.get(ci) if st is None: continue k: int = st.kind() @@ -980,10 +987,10 @@ class FuncGenMixin(CallGenBase.CallGenBase): nl_list: list[ast.AST*]* = nl_node.names nn: sizet = len(nl_list) for ni in range(nn): - nm_node: rawptr[ast.AST] = nl_list.get(ni) + nm_node: ast.AST* = nl_list.get(ni) if nm_node is None: continue - nm_x: rawptr[ast.Name] = rawptr[ast.Name](nm_node) + nm_x: ast.Name* = ast.Name*(nm_node) if nm_x is None or nm_x.id is None: continue dup: int = 0 @@ -1009,13 +1016,13 @@ class FuncGenMixin(CallGenBase.CallGenBase): # 建堆 + 重定向 VarEntry + 把堆地址 store 到模块级映射 # @nlheap.{sha1}.{name}(全局变量跨函数可见),内层闭包创建时从映射 load。 # ============================================================ - def _prepare_chain_nonlocals(self, trans: rawptr[HT.Translator], - node: rawptr[ast.AST], - pool: rawptr[memhub.MemBuddy], - builder: rawptr[llvmlite.IRBuilder], - mod: rawptr[llvmlite.LLVMModule], - i8_ty: rawptr[llvmlite.LLVMType], - i8_ptr_ty: rawptr[llvmlite.LLVMType]) -> int: + def _prepare_chain_nonlocals(self, trans: HT.Translator*, + node: ast.AST*, + pool: memhub.MemBuddy*, + builder: llvmlite.IRBuilder*, + mod: llvmlite.LLVMModule*, + i8_ty: llvmlite.LLVMType*, + i8_ptr_ty: llvmlite.LLVMType*) -> int: """预收集嵌套函数链内 nonlocal 并建堆,1 成功""" if node is None or trans is None or builder is None or mod is None: return 0 @@ -1039,11 +1046,11 @@ class FuncGenMixin(CallGenBase.CallGenBase): if nl_name is None: continue # 只在"定义它的函数"(当前顶层作用域有 alloca)中建堆 - local_alloca: rawptr[llvmlite.Value] = self.Gen.VarGen.lookup_current( + local_alloca: llvmlite.Value* = self.Gen.VarGen.lookup_current( trans.SymTab, nl_name) if local_alloca is None or local_alloca.Ty is None: continue - nl_ty: rawptr[llvmlite.LLVMType] = local_alloca.Ty.Pointee + nl_ty: llvmlite.LLVMType* = local_alloca.Ty.Pointee if nl_ty is None: continue gname: str = self._nl_heap_global_name(pool, trans, nl_name) @@ -1054,30 +1061,30 @@ class FuncGenMixin(CallGenBase.CallGenBase): # @nlheap.* 保持上一函数的堆地址,env 读到错堆。映射变量仅首次 add(模块去重), # store 指令每次照发。 st_size: int = self._type_byte_size(pool, nl_ty) - st_size_val: rawptr[llvmlite.Value] = llvmlite.const_int64(pool, st_size) + st_size_val: llvmlite.Value* = llvmlite.const_int64(pool, st_size) if st_size_val is not None: st_size_val.Next = None - var_storage: rawptr[llvmlite.Value] = llvmlite.build_call( + var_storage: llvmlite.Value* = llvmlite.build_call( builder, "malloc", st_size_val, 1, i8_ptr_ty, 0) if var_storage is None: continue - cur_val: rawptr[llvmlite.Value] = llvmlite.build_load( + cur_val: llvmlite.Value* = llvmlite.build_load( builder, nl_ty, local_alloca) - st_slot: rawptr[llvmlite.Value] = llvmlite.build_bitcast( + st_slot: 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: rawptr[GenTypes.VarEntry] = self.Gen.VarGen.lookup_var_entry( + ve: GenTypes.VarEntry* = self.Gen.VarGen.lookup_var_entry( trans.SymTab, nl_name) if ve is not None: - heap_typed: rawptr[llvmlite.Value] = llvmlite.build_bitcast( + heap_typed: 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: rawptr[llvmlite.GlobalVariable] = None - gcur: rawptr[llvmlite.GlobalVariable] = mod.GlobalHead + gv_found: llvmlite.GlobalVariable* = None + gcur: 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 @@ -1092,7 +1099,7 @@ class FuncGenMixin(CallGenBase.CallGenBase): gv_found.Initializer = "null" llvmlite.module_add_global(mod, gv_found) if gv_found is not None: - gv_ref: rawptr[llvmlite.Value] = self._nl_heap_global_ref( + gv_ref: 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) @@ -1109,11 +1116,11 @@ class FuncGenMixin(CallGenBase.CallGenBase): # 3. 创建闭包 {fn_ptr, env_ptr},返回 i8* 闭包指针 # 赋值语句据此创建 i8** alloca,调用走 translate_closure_call # ============================================================ - 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) -> rawptr[llvmlite.Value]: + def translate_lambda(self, builder: llvmlite.IRBuilder*, + pool: memhub.MemBuddy*, + mod: llvmlite.LLVMModule*, + node: ast.AST*, + trans: HT.Translator* = None) -> llvmlite.Value*: """翻译 lambda 表达式,返回闭包指针(i8*)""" if node is None or trans is None or builder is None: return None @@ -1121,10 +1128,10 @@ class FuncGenMixin(CallGenBase.CallGenBase): if lam is None: return None - i32_ty: rawptr[llvmlite.LLVMType] = llvmlite.Int32(pool) - 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) + i32_ty: llvmlite.LLVMType* = llvmlite.Int32(pool) + i8_ty: llvmlite.LLVMType* = llvmlite.Int8(pool) + i8_ptr_ty: llvmlite.LLVMType* = llvmlite.Ptr(pool, i8_ty) + i8_ptr_ptr_ty: llvmlite.LLVMType* = llvmlite.Ptr(pool, i8_ptr_ty) # 1. lambda id + 提升函数名 # 注意:计数器放 trans(_lambda_count)而非 self——Mixin 类自身无字段, @@ -1149,20 +1156,20 @@ class FuncGenMixin(CallGenBase.CallGenBase): string.memset(param_tys, 0, 8 * 64) param_count: int = 0 if lam.args is not None: - ags: rawptr[ast.Arguments] = rawptr[ast.Arguments](lam.args) + ags: ast.Arguments* = ast.Arguments*(lam.args) if ags.args is not None: alist: list[ast.AST*]* = ags.args pn: sizet = len(alist) for pi in range(pn): if param_count >= 64: break - arg_n: rawptr[ast.Arg] = rawptr[ast.Arg](alist.get(pi)) + arg_n: ast.Arg* = ast.Arg*(alist.get(pi)) if arg_n is None or arg_n.arg is None: continue string.strncpy(param_names + param_count * 32, arg_n.arg, 31) - p_ty: rawptr[llvmlite.LLVMType] = i32_ty + p_ty: llvmlite.LLVMType* = i32_ty if arg_n.annotation is not None: - resolved: rawptr[llvmlite.LLVMType] = self.Gen.TypeGenResolve.resolve_annotation_type( + resolved: llvmlite.LLVMType* = self.Gen.TypeGenResolve.resolve_annotation_type( pool, arg_n.annotation, trans._imported_modules, trans._from_imports, trans, 0) if resolved is None: # fail-fast:lambda 参数有注解但类型解析失败,不再静默保持 i32 @@ -1201,7 +1208,7 @@ class FuncGenMixin(CallGenBase.CallGenBase): cap_names, cap_allocas, cap_tys, 0) # 4. 创建提升函数 __lambda_{id}(i8* %env, [args...]) - func: rawptr[llvmlite.Function] = llvmlite.create_function( + func: llvmlite.Function* = llvmlite.create_function( pool, mod, mangled_promoted, i32_ty) if func is None: return None @@ -1209,7 +1216,7 @@ class FuncGenMixin(CallGenBase.CallGenBase): for pi2 in range(param_count): ty_addr2: uint64 = uint64(param_tys) + pi2 * 8 ty_slot2: str | t.CPtr = (t.CPtr)(ty_addr2) - p_ty2: rawptr[llvmlite.LLVMType] = (rawptr[llvmlite.LLVMType])(ty_slot2[0]) + p_ty2: llvmlite.LLVMType* = (llvmlite.LLVMType*)(ty_slot2[0]) if p_ty2 is None: p_ty2 = i32_ty pname_l: str = pool.alloc(32) @@ -1221,7 +1228,7 @@ class FuncGenMixin(CallGenBase.CallGenBase): entry_blk: rawptr[llvmlite.BasicBlock] = llvmlite.create_block(pool, func, "entry") if entry_blk is None: return None - func_builder: rawptr[llvmlite.IRBuilder] = llvmlite.new_builder(pool, func) + func_builder: llvmlite.IRBuilder* = llvmlite.new_builder(pool, func) if func_builder is None: return None llvmlite.position_at_end(func_builder, entry_blk) @@ -1230,15 +1237,15 @@ class FuncGenMixin(CallGenBase.CallGenBase): self.Gen.VarGen.enter_scope(trans.SymTab, SCOPE_FUNCTION) # 7. _env_ptr alloca(存储 %env 参数) - env_alloca: rawptr[llvmlite.Value] = llvmlite.build_alloca(func_builder, i8_ptr_ty) + env_alloca: 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: rawptr[llvmlite.Value] = llvmlite.SSAValue(pool, i8_ptr_ty, "%env") + env_param_val: 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: rawptr[llvmlite.IRBuilder] = trans._cur_builder + old_func: llvmlite.Function* = trans._cur_func + old_builder: 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 @@ -1258,27 +1265,27 @@ class FuncGenMixin(CallGenBase.CallGenBase): continue ty_addr3: uint64 = uint64(cap_tys) + ci * 8 ty_slot3: str | t.CPtr = (t.CPtr)(ty_addr3) - cap_ty: rawptr[llvmlite.LLVMType] = (rawptr[llvmlite.LLVMType])(ty_slot3[0]) + cap_ty: llvmlite.LLVMType* = (llvmlite.LLVMType*)(ty_slot3[0]) if cap_ty is None: continue - off_val: rawptr[llvmlite.Value] = llvmlite.const_int32(pool, ci * 8) - slot_addr: rawptr[llvmlite.Value] = llvmlite.build_gep( + off_val: llvmlite.Value* = llvmlite.const_int32(pool, ci * 8) + slot_addr: llvmlite.Value* = llvmlite.build_gep( func_builder, i8_ty, env_param_val, off_val) if slot_addr is None: continue - storage_addr: rawptr[llvmlite.Value] = llvmlite.build_load( + storage_addr: llvmlite.Value* = llvmlite.build_load( func_builder, i8_ptr_ty, slot_addr) if storage_addr is None: continue - st_typed: rawptr[llvmlite.Value] = llvmlite.build_bitcast( + st_typed: llvmlite.Value* = llvmlite.build_bitcast( func_builder, storage_addr, llvmlite.Ptr(pool, cap_ty)) if st_typed is None: continue - cap_val: rawptr[llvmlite.Value] = llvmlite.build_load( + cap_val: llvmlite.Value* = llvmlite.build_load( func_builder, cap_ty, st_typed) if cap_val is None: continue - var_alloca: rawptr[llvmlite.Value] = llvmlite.build_alloca(func_builder, cap_ty) + var_alloca: 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) @@ -1287,7 +1294,7 @@ class FuncGenMixin(CallGenBase.CallGenBase): for pi3 in range(param_count): ty_addr4: uint64 = uint64(param_tys) + pi3 * 8 ty_slot4: str | t.CPtr = (t.CPtr)(ty_addr4) - p_ty3: rawptr[llvmlite.LLVMType] = (rawptr[llvmlite.LLVMType])(ty_slot4[0]) + p_ty3: llvmlite.LLVMType* = (llvmlite.LLVMType*)(ty_slot4[0]) if p_ty3 is None: # fail-fast:lambda 参数类型槽缺失(内部状态不一致),不再静默保持 i32 self.Gen.TypeGenErr.fatal_error( @@ -1296,21 +1303,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: rawptr[llvmlite.Value] = llvmlite.SSAValue(pool, p_ty3, pname_ref) - arg_alloca: rawptr[llvmlite.Value] = llvmlite.build_alloca(func_builder, p_ty3) + param_ref: llvmlite.Value* = llvmlite.SSAValue(pool, p_ty3, pname_ref) + arg_alloca: 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: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( + body_val: 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: rawptr[llvmlite.Value] = self.Gen.ExprGenBase.coerce_to_type( + ret_val: 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) @@ -1331,10 +1338,10 @@ class FuncGenMixin(CallGenBase.CallGenBase): trans._closure_env_count = old_env_count # 13. 在父函数中创建 env(每个捕获变量 8 字节堆存储,env[i] = 堆地址) - env_ptr: rawptr[llvmlite.Value] = None + env_ptr: llvmlite.Value* = None if cap_count > 0: env_size: int64 = cap_count * 8 - env_size_val: rawptr[llvmlite.Value] = llvmlite.const_int64(pool, env_size) + env_size_val: 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( @@ -1347,14 +1354,14 @@ class FuncGenMixin(CallGenBase.CallGenBase): continue al_addr: uint64 = uint64(cap_allocas) + ci3 * 8 al_slot: str | t.CPtr = (t.CPtr)(al_addr) - var_alloca2: rawptr[llvmlite.Value] = ( - rawptr[llvmlite.Value])(al_slot[0]) + var_alloca2: llvmlite.Value* = ( + llvmlite.Value*)(al_slot[0]) if var_alloca2 is None: continue ty_addr5: uint64 = uint64(cap_tys) + ci3 * 8 ty_slot5: str | t.CPtr = (t.CPtr)(ty_addr5) - cap_ty2: rawptr[llvmlite.LLVMType] = ( - rawptr[llvmlite.LLVMType])(ty_slot5[0]) + cap_ty2: llvmlite.LLVMType* = ( + llvmlite.LLVMType*)(ty_slot5[0]) if cap_ty2 is None: continue # 堆存储大小:位宽/8,至少 8 字节(容纳指针/标量) @@ -1362,67 +1369,67 @@ class FuncGenMixin(CallGenBase.CallGenBase): st_size: int = 8 if ty_bits > 64: st_size = ty_bits // 8 - st_size_val: rawptr[llvmlite.Value] = llvmlite.const_int64(pool, st_size) + st_size_val: llvmlite.Value* = llvmlite.const_int64(pool, st_size) if st_size_val is not None: st_size_val.Next = None - var_storage: rawptr[llvmlite.Value] = llvmlite.build_call( + var_storage: llvmlite.Value* = llvmlite.build_call( builder, "malloc", st_size_val, 1, i8_ptr_ty, 0) if var_storage is not None: - cur_val: rawptr[llvmlite.Value] = llvmlite.build_load( + cur_val: llvmlite.Value* = llvmlite.build_load( builder, cap_ty2, var_alloca2) if cur_val is not None: - st_slot5: rawptr[llvmlite.Value] = llvmlite.build_bitcast( + st_slot5: 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: rawptr[llvmlite.Value] = llvmlite.const_int32(pool, ci3 * 8) - slot2: rawptr[llvmlite.Value] = llvmlite.build_gep( + off_val2: llvmlite.Value* = llvmlite.const_int32(pool, ci3 * 8) + slot2: llvmlite.Value* = llvmlite.build_gep( builder, i8_ty, env_ptr, off_val2) if slot2 is not None: - slot_typed2: rawptr[llvmlite.Value] = llvmlite.build_bitcast( + slot_typed2: 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: rawptr[llvmlite.Value] = llvmlite.const_int64(pool, 16) + closure_size_val: llvmlite.Value* = llvmlite.const_int64(pool, 16) if closure_size_val is not None: closure_size_val.Next = None - closure_ptr: rawptr[llvmlite.Value] = llvmlite.build_call( + closure_ptr: llvmlite.Value* = llvmlite.build_call( builder, "malloc", closure_size_val, 1, i8_ptr_ty, 0) if closure_ptr is None: return None # 15. [0] = fn_ptr(函数引用 bitcast 到 i8*) - fn_param_node: rawptr[llvmlite.Function] = llvmlite.new_param_node(pool, i8_ptr_ty) - fn_func_ty: rawptr[llvmlite.LLVMType] = llvmlite.Func(pool, i32_ty, fn_param_node, 1) - fn_func_ptr_ty: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, fn_func_ty) + fn_param_node: llvmlite.Function* = llvmlite.new_param_node(pool, i8_ptr_ty) + fn_func_ty: llvmlite.LLVMType* = llvmlite.Func(pool, i32_ty, fn_param_node, 1) + fn_func_ptr_ty: llvmlite.LLVMType* = llvmlite.Ptr(pool, fn_func_ty) fn_ptr_name: str = pool.alloc(64) if fn_ptr_name is not None: if string.strchr(mangled_promoted, '.') is not None: viperlib.snprintf(fn_ptr_name, 64, "@\"%s\"", mangled_promoted) else: viperlib.snprintf(fn_ptr_name, 64, "@%s", mangled_promoted) - 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( + fn_ptr_val: llvmlite.Value* = llvmlite.SSAValue(pool, fn_func_ptr_ty, fn_ptr_name) + fn_as_i8ptr: llvmlite.Value* = llvmlite.build_bitcast( builder, fn_ptr_val, i8_ptr_ty) - fn_slot: rawptr[llvmlite.Value] = llvmlite.build_bitcast( + fn_slot: 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: rawptr[llvmlite.Value] = llvmlite.const_int32(pool, 8) - env_slot_addr: rawptr[llvmlite.Value] = llvmlite.build_gep( + eight_val: llvmlite.Value* = llvmlite.const_int32(pool, 8) + env_slot_addr: llvmlite.Value* = llvmlite.build_gep( builder, i8_ty, closure_ptr, eight_val) if env_slot_addr is not None: - env_slot: rawptr[llvmlite.Value] = llvmlite.build_bitcast( + env_slot: 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: rawptr[llvmlite.Value] = llvmlite.SSAValue(pool, i8_ptr_ty, "null") + null_val: llvmlite.Value* = llvmlite.SSAValue(pool, i8_ptr_ty, "null") llvmlite.build_store(builder, null_val, env_slot) # 17. 返回闭包指针(i8*) @@ -1435,8 +1442,8 @@ class FuncGenMixin(CallGenBase.CallGenBase): # 记录到 cap_names/cap_allocas/cap_tys 三个并行缓冲。 # 返回更新后的捕获数量(递归调用逐层累加)。 # ============================================================ - def _lambda_scan_body(self, trans: rawptr[HT.Translator], - node: rawptr[ast.AST], + def _lambda_scan_body(self, trans: HT.Translator*, + node: ast.AST*, param_names: str, param_count: int, cap_names: str, @@ -1448,7 +1455,7 @@ class FuncGenMixin(CallGenBase.CallGenBase): return cap_count k: int = node.kind() if k == ast.ASTKind.Name: - nm: rawptr[ast.Name] = rawptr[ast.Name](node) + nm: ast.Name* = ast.Name*(node) if nm.id is None: return cap_count # 排除 lambda 参数 @@ -1460,14 +1467,14 @@ class FuncGenMixin(CallGenBase.CallGenBase): if string.strcmp(cap_names + ci * 64, nm.id) == 0: return cap_count # 查当前作用域链 - alloca: rawptr[llvmlite.Value] = self.Gen.VarGen.lookup_var(trans.SymTab, nm.id) + alloca: 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 + pointee: llvmlite.LLVMType* = alloca.Ty.Pointee if pointee is None: return cap_count # 跳过模块级全局(body 直接解析全局,无需 env 捕获) - mod_gv: rawptr[llvmlite.Value] = self.Gen.VarGen.lookup_module_var(trans.SymTab, nm.id) + mod_gv: 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 @@ -1483,13 +1490,13 @@ class FuncGenMixin(CallGenBase.CallGenBase): return cap_count + 1 # 递归遍历常见表达式子节点 if k == ast.ASTKind.BinOp: - bop: rawptr[ast.BinOp] = rawptr[ast.BinOp](node) + bop: ast.BinOp* = ast.BinOp*(node) cc1: int = self._lambda_scan_body(trans, bop.left, param_names, param_count, cap_names, cap_allocas, cap_tys, cap_count) return self._lambda_scan_body(trans, bop.right, param_names, param_count, cap_names, cap_allocas, cap_tys, cc1) if k == ast.ASTKind.UnaryOp: - uop: rawptr[ast.UnaryOp] = rawptr[ast.UnaryOp](node) + uop: ast.UnaryOp* = ast.UnaryOp*(node) return self._lambda_scan_body(trans, uop.operand, param_names, param_count, cap_names, cap_allocas, cap_tys, cap_count) if k == ast.ASTKind.BoolOp: @@ -1514,7 +1521,7 @@ class FuncGenMixin(CallGenBase.CallGenBase): cap_names, cap_allocas, cap_tys, cc3) return cc3 if k == ast.ASTKind.Call: - cal: rawptr[ast.Call] = rawptr[ast.Call](node) + cal: ast.Call* = ast.Call*(node) cc4: int = self._lambda_scan_body(trans, cal.func, param_names, param_count, cap_names, cap_allocas, cap_tys, cap_count) if cal.args is not None: @@ -1533,7 +1540,7 @@ class FuncGenMixin(CallGenBase.CallGenBase): cap_names, cap_allocas, cap_tys, cc4) return cc4 if k == ast.ASTKind.Subscript: - sub: rawptr[ast.Subscript] = rawptr[ast.Subscript](node) + sub: ast.Subscript* = ast.Subscript*(node) cc5: int = self._lambda_scan_body(trans, sub.value, param_names, param_count, cap_names, cap_allocas, cap_tys, cap_count) if sub.slice is not None: @@ -1541,7 +1548,7 @@ class FuncGenMixin(CallGenBase.CallGenBase): cap_names, cap_allocas, cap_tys, cc5) return cc5 if k == ast.ASTKind.Attribute: - at: rawptr[ast.Attribute] = rawptr[ast.Attribute](node) + at: ast.Attribute* = ast.Attribute*(node) return self._lambda_scan_body(trans, at.value, param_names, param_count, cap_names, cap_allocas, cap_tys, cap_count) if k == ast.ASTKind.IfExp: @@ -1553,7 +1560,7 @@ 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: rawptr[ast.List] = rawptr[ast.List](node) + ls: ast.List* = ast.List*(node) cc7: int = cap_count if ls.elts is not None: es: list[ast.AST*]* = ls.elts diff --git a/App/lib/core/Gen/GenApi.vp b/App/lib/core/Gen/GenApi.vp index a5666d7..e905d33 100644 --- a/App/lib/core/Gen/GenApi.vp +++ b/App/lib/core/Gen/GenApi.vp @@ -18,7 +18,7 @@ import lib.core.Gen.Generator as Generator # 全局 gen 单例(main/BuildPipeline 创建 gen 后注入) -_g_gen: rawptr[Generator.Generator] = None +_g_gen: Generator.Generator* = None # ---------------- set_temp_dir(委托 TypeGenBase.set_temp_dir) ---------------- @@ -48,7 +48,7 @@ def set_current_file_type(file_path: str) -> None: if _g_gen is not None: _g_gen.TypeGenResolve.set_current_file(file_path) return - gg: rawptr[Generator.Generator] = Generator._g_gen + gg: Generator.Generator* = Generator._g_gen if gg is not None: gg.TypeGenResolve.set_current_file(file_path) @@ -82,7 +82,7 @@ def clear_ctypedefs() -> None: # ---------------- RegisterCTypedefFromSource(委托 TypeGenCType.register_ctypedef_from_source) ---------------- -def RegisterCTypedefFromSource(pool: rawptr[memhub.MemBuddy], src: str) -> int: +def RegisterCTypedefFromSource(pool: memhub.MemBuddy*, src: str) -> int: """委托到 gen.register_ctypedef_from_source(原 Handles 壳)""" if _g_gen is not None: _g_gen.TypeGenCType.register_ctypedef_from_source(pool, src) @@ -97,7 +97,7 @@ def dump_parse_traceback(file_path: str) -> None: # ---------------- fatal_error(委托 TypeGenErr.fatal_error) ---------------- -def fatal_error(node: rawptr[ast.AST], msg: str, +def fatal_error(node: ast.AST*, msg: str, err_type: str = "SyntaxError") -> None: """委托到 gen.TypeGenErr.fatal_error —— 模块级函数的报错通道 @@ -111,13 +111,13 @@ def fatal_error(node: rawptr[ast.AST], msg: str, if _g_gen is not None: _g_gen.TypeGenErr.fatal_error(node, msg, err_type) return - gg: rawptr[Generator.Generator] = Generator._g_gen + gg: Generator.Generator* = Generator._g_gen if gg is not None: gg.TypeGenErr.fatal_error(node, msg, err_type) # ---------------- map_t_type(委托 TypeGenResolve.map_t_type) ---------------- -def map_t_type(pool: rawptr[memhub.MemBuddy], type_name: str) -> rawptr[llvmlite.LLVMType]: +def map_t_type(pool: memhub.MemBuddy*, type_name: str) -> llvmlite.LLVMType*: """委托到 gen.map_t_type(原 Handles 壳)""" if _g_gen is not None: _g_gen.TypeGenResolve.map_t_type(pool, type_name) @@ -125,11 +125,11 @@ def map_t_type(pool: rawptr[memhub.MemBuddy], type_name: str) -> rawptr[llvmlite # ---------------- resolve_typedef_or_map(委托 TypeGenResolve.resolve_typedef_or_map) ---------------- -def resolve_typedef_or_map(pool: rawptr[memhub.MemBuddy], +def resolve_typedef_or_map(pool: memhub.MemBuddy*, name: str, imported_modules: str, from_imports: str, - trans: rawptr[HT.Translator] = None) -> rawptr[llvmlite.LLVMType]: + trans: HT.Translator* = None) -> llvmlite.LLVMType*: """委托到 gen.resolve_typedef_or_map(CTypedef 动态表优先,miss 回退 map_t_type)""" if _g_gen is not None: return _g_gen.TypeGenResolve.resolve_typedef_or_map(pool, name, imported_modules, from_imports, trans) @@ -137,8 +137,8 @@ def resolve_typedef_or_map(pool: rawptr[memhub.MemBuddy], # ---------------- infer_external_func_ret_ty(委托 CallGenLib._infer_external_func_ret_ty) ---------------- -def infer_external_func_ret_ty(pool: rawptr[memhub.MemBuddy], - func_name: str) -> rawptr[llvmlite.LLVMType]: +def infer_external_func_ret_ty(pool: memhub.MemBuddy*, + func_name: str) -> llvmlite.LLVMType*: """委托到 gen.CallGenLib._infer_external_func_ret_ty(外部函数返回类型白名单) vpi 注入 extern declare 时返回类型解析 miss 的兜底:FindFirstFileA/ @@ -161,7 +161,7 @@ def get_current_file() -> str: # ---------------- _is_ctypedef_annotation(委托 TypeGenCType._is_ctypedef_annotation) ---------------- -def _is_ctypedef_annotation(annotation: rawptr[ast.AST]) -> int: +def _is_ctypedef_annotation(annotation: ast.AST*) -> int: """委托到 gen._is_ctypedef_annotation(原 Handles 壳)""" if _g_gen is not None: return _g_gen.TypeGenCType._is_ctypedef_annotation(annotation) @@ -169,7 +169,7 @@ def _is_ctypedef_annotation(annotation: rawptr[ast.AST]) -> int: # ---------------- resolve_annotation_type(委托 TypeGenResolve.resolve_annotation_type) ---------------- -def resolve_annotation_type(pool: rawptr[memhub.MemBuddy], node: rawptr[ast.AST], imported_modules: str, from_imports: str, trans: rawptr[HT.Translator] = None, depth: int = 0) -> rawptr[llvmlite.LLVMType]: +def resolve_annotation_type(pool: memhub.MemBuddy*, node: ast.AST*, imported_modules: str, from_imports: str, trans: HT.Translator* = None, depth: int = 0) -> llvmlite.LLVMType*: """委托到 gen.resolve_annotation_type(原 Handles 壳)""" if _g_gen is not None: return _g_gen.TypeGenResolve.resolve_annotation_type(pool, node, imported_modules, from_imports, trans, depth) @@ -177,7 +177,7 @@ def resolve_annotation_type(pool: rawptr[memhub.MemBuddy], node: rawptr[ast.AST] # ---------------- has_decorator_marker(委托 TypeGenErr.has_decorator_marker) ---------------- -def has_decorator_marker(node: rawptr[ast.AST], marker_name: str, +def has_decorator_marker(node: ast.AST*, marker_name: str, depth: int = 0) -> int: """委托到 gen.has_decorator_marker(原 Handles 壳)""" if _g_gen is not None: @@ -186,7 +186,7 @@ def has_decorator_marker(node: rawptr[ast.AST], marker_name: str, # ---------------- _get_type_name_from_annotation(委托 TypeGenResolve._get_type_name_from_annotation) ---------------- -def _get_type_name_from_annotation(pool: rawptr[memhub.MemBuddy], node: rawptr[ast.AST]) -> str: +def _get_type_name_from_annotation(pool: memhub.MemBuddy*, node: ast.AST*) -> str: """委托到 gen._get_type_name_from_annotation(原 Handles 壳)""" if _g_gen is not None: return _g_gen.TypeGenResolve._get_type_name_from_annotation(pool, node) @@ -194,7 +194,7 @@ def _get_type_name_from_annotation(pool: rawptr[memhub.MemBuddy], node: rawptr[a # ---------------- register_ctypedef(委托 TypeGenCType.register_ctypedef) ---------------- -def register_ctypedef(pool: rawptr[memhub.MemBuddy], name: str, type_str: str): +def register_ctypedef(pool: memhub.MemBuddy*, name: str, type_str: str): """委托到 gen.register_ctypedef(原 Handles 壳)""" if _g_gen is not None: _g_gen.TypeGenCType.register_ctypedef(pool, name, type_str) @@ -217,7 +217,7 @@ def is_cdefine_found() -> int: # ---------------- register_cdefine_constant(委托 TypeGenCDef.register_cdefine_constant) ---------------- -def register_cdefine_constant(pool: rawptr[memhub.MemBuddy], +def register_cdefine_constant(pool: memhub.MemBuddy*, name: str, value: int64): """委托到 gen.register_cdefine_constant(原 Handles 壳)""" if _g_gen is not None: @@ -225,7 +225,7 @@ def register_cdefine_constant(pool: rawptr[memhub.MemBuddy], # ---------------- register_cdefine_double(委托 TypeGenCDef.register_cdefine_double) ---------------- -def register_cdefine_double(pool: rawptr[memhub.MemBuddy], +def register_cdefine_double(pool: memhub.MemBuddy*, name: str, value: double): """委托到 gen.register_cdefine_double(原 Handles 壳)""" if _g_gen is not None: @@ -233,7 +233,7 @@ def register_cdefine_double(pool: rawptr[memhub.MemBuddy], # ---------------- is_cdefine_annotation(委托 AssignGenMixin.is_cdefine_annotation) ---------------- -def is_cdefine_annotation(annot: rawptr[ast.AST]) -> int: +def is_cdefine_annotation(annot: ast.AST*) -> int: """委托到 gen.is_cdefine_annotation(原 Handles 壳)""" if _g_gen is not None: return _g_gen.AssignGen.is_cdefine_annotation(annot) @@ -241,7 +241,7 @@ def is_cdefine_annotation(annot: rawptr[ast.AST]) -> int: # ---------------- extract_cdefine_int_value(委托 AssignGenMixin.extract_cdefine_int_value) ---------------- -def extract_cdefine_int_value(val_node: rawptr[ast.AST]) -> int64: +def extract_cdefine_int_value(val_node: ast.AST*) -> int64: """委托到 gen.extract_cdefine_int_value(原 Handles 壳)""" if _g_gen is not None: return _g_gen.AssignGen.extract_cdefine_int_value(val_node) @@ -271,7 +271,7 @@ def get_temp_dir() -> str: # ---------------- reset_visible_structs(委托 StructGenMixin.reset_visible_structs) ---------------- -def reset_visible_structs(pool: rawptr[memhub.MemBuddy], strict: int): +def reset_visible_structs(pool: memhub.MemBuddy*, strict: int): """委托到 gen.reset_visible_structs(原 Handles 壳)""" if _g_gen is not None: _g_gen.StructGen.reset_visible_structs(pool, strict) @@ -301,7 +301,7 @@ def reset_module_methods_emitted(sha1: str) -> int: # ---------------- get_struct_type(委托 StructGenMixin.get_struct_type) ---------------- -def get_struct_type(class_name: str) -> rawptr[llvmlite.LLVMType]: +def get_struct_type(class_name: str) -> llvmlite.LLVMType*: """委托到 gen.get_struct_type(原 Handles 壳)""" if _g_gen is not None: return _g_gen.StructGen.get_struct_type(class_name) @@ -309,7 +309,7 @@ def get_struct_type(class_name: str) -> rawptr[llvmlite.LLVMType]: # ---------------- get_enum_base_type(委托 StmtGenDeclMixin.get_enum_base_type) ---------------- -def get_enum_base_type(enum_name: str) -> rawptr[llvmlite.LLVMType]: +def get_enum_base_type(enum_name: str) -> llvmlite.LLVMType*: """委托到 gen.get_enum_base_type(原 Handles 壳) 枚举(t.CEnum)注册在独立的 EnumTable(EnumEntry),不进 StructTable, @@ -323,14 +323,14 @@ def get_enum_base_type(enum_name: str) -> rawptr[llvmlite.LLVMType]: # ---------------- add_visible_struct(委托 StructGenMixin.add_visible_struct) ---------------- -def add_visible_struct(pool: rawptr[memhub.MemBuddy], name: str): +def add_visible_struct(pool: memhub.MemBuddy*, name: str): """委托到 gen.add_visible_struct(原 Handles 壳)""" if _g_gen is not None: _g_gen.StructGen.add_visible_struct(pool, name) # ---------------- find_struct_by_module(委托 StructGenMixin.find_struct_by_module) ---------------- -def find_struct_by_module(name: str, sha1: str) -> rawptr[GenTypes.StructEntry]: +def find_struct_by_module(name: str, sha1: str) -> GenTypes.StructEntry*: """委托到 gen.find_struct_by_module(原 Handles 壳)""" if _g_gen is not None: return _g_gen.StructGen.find_struct_by_module(name, sha1) @@ -338,7 +338,7 @@ def find_struct_by_module(name: str, sha1: str) -> rawptr[GenTypes.StructEntry]: # ---------------- find_struct_by_type(委托 StructGenMixin.find_struct_by_type) ---------------- -def find_struct_by_type(struct_ty: rawptr[llvmlite.LLVMType]) -> rawptr[GenTypes.StructEntry]: +def find_struct_by_type(struct_ty: llvmlite.LLVMType*) -> GenTypes.StructEntry*: """委托到 gen.find_struct_by_type(原 Handles 壳)""" if _g_gen is not None: return _g_gen.StructGen.find_struct_by_type(struct_ty) @@ -346,10 +346,10 @@ def find_struct_by_type(struct_ty: rawptr[llvmlite.LLVMType]) -> rawptr[GenTypes # ---------------- register_struct(委托 StructGenMixin.register_struct) ---------------- -def register_struct(pool: rawptr[memhub.MemBuddy], +def register_struct(pool: memhub.MemBuddy*, name: str, - struct_ty: rawptr[llvmlite.LLVMType], - sha1: str = None) -> rawptr[GenTypes.StructEntry]: + struct_ty: llvmlite.LLVMType*, + sha1: str = None) -> GenTypes.StructEntry*: """委托到 gen.register_struct(原 Handles 壳)""" if _g_gen is not None: return _g_gen.StructGen.register_struct(pool, name, struct_ty, sha1) @@ -357,10 +357,10 @@ def register_struct(pool: rawptr[memhub.MemBuddy], # ---------------- add_field(委托 StructGenMixin.add_field) ---------------- -def add_field(pool: rawptr[memhub.MemBuddy], - struct_entry: rawptr[GenTypes.StructEntry], +def add_field(pool: memhub.MemBuddy*, + struct_entry: GenTypes.StructEntry*, field_name: str, - field_ty: rawptr[llvmlite.LLVMType]) -> int: + field_ty: llvmlite.LLVMType*) -> int: """委托到 gen.add_field(原 Handles 壳)""" if _g_gen is not None: return _g_gen.StructGen.add_field(pool, struct_entry, field_name, field_ty) @@ -368,10 +368,10 @@ def add_field(pool: rawptr[memhub.MemBuddy], # ---------------- register_struct_alias(委托 StructGenMixin.register_struct_alias) ---------------- -def register_struct_alias(pool: rawptr[memhub.MemBuddy], +def register_struct_alias(pool: memhub.MemBuddy*, name: str, sha1: str, - src_entry: rawptr[GenTypes.StructEntry]) -> rawptr[GenTypes.StructEntry]: + src_entry: GenTypes.StructEntry*) -> GenTypes.StructEntry*: """委托到 gen.StructGen.register_struct_alias(包重导出类别名注册,原 Handles 壳)""" if _g_gen is not None: return _g_gen.StructGen.register_struct_alias(pool, name, sha1, src_entry) @@ -388,7 +388,7 @@ def get_stdlib_alloc() -> int: # ---------------- compute_package_from_relpath(委托 ImportsGenMixin.compute_package_from_relpath) ---------------- -def compute_package_from_relpath(pool: rawptr[memhub.MemBuddy], rel_path: str) -> str: +def compute_package_from_relpath(pool: memhub.MemBuddy*, rel_path: str) -> str: """委托到 gen.compute_package_from_relpath(原 Handles 壳)""" if _g_gen is not None: return _g_gen.ImportsGen.compute_package_from_relpath(pool, rel_path) @@ -446,7 +446,7 @@ def is_sha1_hex16(seg: str) -> int: # ---------------- add_imported_module(委托 ImportsGenMixin.add_imported_module) ---------------- -def add_imported_module(pool: rawptr[memhub.MemBuddy], imported_modules: str, name: str) -> str: +def add_imported_module(pool: memhub.MemBuddy*, imported_modules: str, name: str) -> str: """委托到 gen.add_imported_module(原 Handles 壳)""" if _g_gen is not None: return _g_gen.ImportsGen.add_imported_module(pool, imported_modules, name) @@ -454,7 +454,7 @@ def add_imported_module(pool: rawptr[memhub.MemBuddy], imported_modules: str, na # ---------------- translate_import(委托 ImportsGenMixin.translate_import) ---------------- -def translate_import(trans: rawptr[HT.Translator], node: rawptr[ast.AST]) -> int: +def translate_import(trans: HT.Translator*, node: ast.AST*) -> int: """委托到 gen.translate_import(原 Handles 壳)""" if _g_gen is not None: return _g_gen.ImportsGen.translate_import(trans, node) @@ -462,7 +462,7 @@ def translate_import(trans: rawptr[HT.Translator], node: rawptr[ast.AST]) -> int # ---------------- translate_import_from_module(委托 ImportsGenMixin.translate_import_from_module) ---------------- -def translate_import_from_module(trans: rawptr[HT.Translator], node: rawptr[ast.AST]) -> int: +def translate_import_from_module(trans: HT.Translator*, node: ast.AST*) -> int: """委托到 gen.translate_import_from_module(原 Handles 壳)""" if _g_gen is not None: return _g_gen.ImportsGen.translate_import_from_module(trans, node) @@ -470,7 +470,7 @@ def translate_import_from_module(trans: rawptr[HT.Translator], node: rawptr[ast. # ---------------- translate_import_from_names(委托 ImportsGenMixin.translate_import_from_names) ---------------- -def translate_import_from_names(trans: rawptr[HT.Translator], node: rawptr[ast.AST]) -> int: +def translate_import_from_names(trans: HT.Translator*, node: ast.AST*) -> int: """委托到 gen.translate_import_from_names(原 Handles 壳)""" if _g_gen is not None: return _g_gen.ImportsGen.translate_import_from_names(trans, node) @@ -478,7 +478,7 @@ def translate_import_from_names(trans: rawptr[HT.Translator], node: rawptr[ast.A # ---------------- _get_parent_class(委托 ClassGenBase._get_parent_class) ---------------- -def _get_parent_class(cd: rawptr[ast.ClassDef], trans: rawptr[HT.Translator] = None) -> str: +def _get_parent_class(cd: ast.ClassDef*, trans: HT.Translator* = None) -> str: """委托到 gen._get_parent_class(原 Handles 壳)""" if _g_gen is not None: return _g_gen.ClassGenBase._get_parent_class(cd, trans) @@ -486,7 +486,7 @@ def _get_parent_class(cd: rawptr[ast.ClassDef], trans: rawptr[HT.Translator] = N # ---------------- _register_generic_template(委托 ClassGenGeneric._register_generic_template) ---------------- -def _register_generic_template(pool: rawptr[memhub.MemBuddy], cd: rawptr[ast.ClassDef], module_sha1: str): +def _register_generic_template(pool: memhub.MemBuddy*, cd: ast.ClassDef*, module_sha1: str): """委托到 gen._register_generic_template(原 Handles 壳)""" if _g_gen is not None: _g_gen.ClassGenGeneric._register_generic_template(pool, cd, module_sha1) @@ -501,7 +501,7 @@ def _mangle_name_with_sha1(sha1: str, name: str) -> str: # ---------------- forward_declare_functions(委托 FuncGenDef.forward_declare_functions) ---------------- -def forward_declare_functions(trans: rawptr[HT.Translator], tree: rawptr[ast.AST]) -> int: +def forward_declare_functions(trans: HT.Translator*, tree: ast.AST*) -> int: """委托到 gen.forward_declare_functions(原 Handles 壳)""" if _g_gen is not None: return _g_gen.FuncGenDef.forward_declare_functions(trans, tree) @@ -509,7 +509,7 @@ def forward_declare_functions(trans: rawptr[HT.Translator], tree: rawptr[ast.AST # ---------------- create_wrapper_main(委托 TranslatorGenMixin.create_wrapper_main) ---------------- -def create_wrapper_main(trans: rawptr[HT.Translator], tree: rawptr[ast.AST], i32_ty: rawptr[llvmlite.LLVMType]) -> int: +def create_wrapper_main(trans: HT.Translator*, tree: ast.AST*, i32_ty: llvmlite.LLVMType*) -> int: """委托到 gen.create_wrapper_main(原 Handles 壳)""" if _g_gen is not None: return _g_gen.TranslatorGen.create_wrapper_main(trans, tree, i32_ty) @@ -517,7 +517,7 @@ def create_wrapper_main(trans: rawptr[HT.Translator], tree: rawptr[ast.AST], i32 # ---------------- handle_module_level_var(委托 TranslatorGenMixin.handle_module_level_var) ---------------- -def handle_module_level_var(trans: rawptr[HT.Translator], node: rawptr[ast.AST]) -> int: +def handle_module_level_var(trans: HT.Translator*, node: ast.AST*) -> int: """委托到 gen.handle_module_level_var(原 Handles 壳)""" if _g_gen is not None: return _g_gen.TranslatorGen.handle_module_level_var(trans, node) @@ -525,7 +525,7 @@ def handle_module_level_var(trans: rawptr[HT.Translator], node: rawptr[ast.AST]) # ---------------- translate_children(委托 TranslatorGenMixin.translate_children) ---------------- -def translate_children(trans: rawptr[HT.Translator], tree: rawptr[ast.AST]) -> int: +def translate_children(trans: HT.Translator*, tree: ast.AST*) -> int: """委托到 gen.translate_children(原 Handles 壳)""" if _g_gen is not None: return _g_gen.TranslatorGen.translate_children(trans, tree) @@ -533,7 +533,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]) -> rawptr[GenTypes.SymbolTable]: +def init_symbol_table(pool: memhub.MemBuddy*) -> rawptr[GenTypes.SymbolTable]: """委托到 gen.init_symbol_table(原 Handles 壳)""" if _g_gen is not None: return _g_gen.VarGen.init_symbol_table(pool) @@ -548,7 +548,7 @@ def SetTempDir(temp_dir: str): # ---------------- find_func_in_module(委托 CallGenBase.find_func_in_module) ---------------- -def find_func_in_module(mod: rawptr[llvmlite.LLVMModule], name: str) -> rawptr[llvmlite.Function]: +def find_func_in_module(mod: llvmlite.LLVMModule*, name: str) -> llvmlite.Function*: """委托到 gen.find_func_in_module(原 Handles 壳)""" if _g_gen is not None: return _g_gen.CallGenBase.find_func_in_module(mod, name) @@ -556,7 +556,7 @@ def find_func_in_module(mod: rawptr[llvmlite.LLVMModule], name: str) -> rawptr[l # ---------------- add_func_to_table(委托 CallGenLeafKit.add_func_to_table) ---------------- -def add_func_to_table(funcs: rawptr[GenTypes.FuncEntry], func_count: int, name: str, func: rawptr[llvmlite.Function], max_count: int, defaults: t.CPtr = None, default_count: int = 0, param_count: int = 0, pool: rawptr[memhub.MemBuddy] = None, def_sha1: str = None) -> int: +def add_func_to_table(funcs: GenTypes.FuncEntry*, func_count: int, name: str, func: llvmlite.Function*, max_count: int, defaults: t.CPtr = None, default_count: int = 0, param_count: int = 0, pool: memhub.MemBuddy* = None, def_sha1: str = None) -> int: """委托到 gen.add_func_to_table(原 Handles 壳) def_sha1:定义该函数的模块 SHA1(依赖注入路径必须传,避免默认值被挂到导入方名下) @@ -567,7 +567,7 @@ def add_func_to_table(funcs: rawptr[GenTypes.FuncEntry], func_count: int, name: # ---------------- init_func_table(委托 CallGenLeafKit.init_func_table) ---------------- -def init_func_table(pool: rawptr[memhub.MemBuddy], max_count: int) -> rawptr[GenTypes.FuncEntry]: +def init_func_table(pool: memhub.MemBuddy*, max_count: int) -> GenTypes.FuncEntry*: """委托到 gen.init_func_table(原 Handles 壳)""" if _g_gen is not None: return _g_gen.CallGenLeafKit.init_func_table(pool, max_count) @@ -575,7 +575,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: 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]: +def translate_call(pool: memhub.MemBuddy*, builder: llvmlite.IRBuilder*, mod: llvmlite.LLVMModule*, node: ast.AST*, funcs_ptr: t.CPtr, func_count: int, trans: HT.Translator* = None) -> 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) @@ -583,28 +583,28 @@ def translate_call(pool: rawptr[memhub.MemBuddy], builder: rawptr[llvmlite.IRBui # ---------------- translate_printf_call(委托 CallGenLeafKit.translate_printf_call) ---------------- -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): +def translate_printf_call(pool: memhub.MemBuddy*, builder: llvmlite.IRBuilder*, mod: llvmlite.LLVMModule*, cl: ast.Call*, trans: 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: rawptr[llvmlite.IRBuilder], mod: rawptr[llvmlite.LLVMModule], cl: rawptr[ast.Call], trans: rawptr[HT.Translator] = None): +def translate_print_call(pool: memhub.MemBuddy*, builder: llvmlite.IRBuilder*, mod: llvmlite.LLVMModule*, cl: ast.Call*, trans: 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) # ---------------- add_global_name(委托 TranslatorGenMixin.add_global_name) ---------------- -def add_global_name(trans: rawptr[HT.Translator], name: str): +def add_global_name(trans: HT.Translator*, name: str): """委托到 gen.TranslatorGen.add_global_name(原 Handles 壳)""" if _g_gen is not None: _g_gen.TranslatorGen.add_global_name(trans, name) # ---------------- is_global_name(委托 TranslatorGenMixin.is_global_name) ---------------- -def is_global_name(trans: rawptr[HT.Translator], name: str) -> int: +def is_global_name(trans: HT.Translator*, name: str) -> int: """委托到 gen.TranslatorGen.is_global_name(原 Handles 壳)""" if _g_gen is not None: return _g_gen.TranslatorGen.is_global_name(trans, name) @@ -612,16 +612,16 @@ def is_global_name(trans: rawptr[HT.Translator], name: str) -> int: # ---------------- add_nonlocal_name(委托 TranslatorGenMixin.add_nonlocal_name) ---------------- -def add_nonlocal_name(trans: rawptr[HT.Translator], name: str, - var_ty: rawptr[llvmlite.LLVMType] = None): +def add_nonlocal_name(trans: HT.Translator*, name: str, + var_ty: llvmlite.LLVMType* = None): """委托到 gen.TranslatorGen.add_nonlocal_name(原 Handles 壳)""" if _g_gen is not None: _g_gen.TranslatorGen.add_nonlocal_name(trans, name, var_ty) # ---------------- get_nonlocal_type(委托 TranslatorGenMixin.get_nonlocal_type) ---------------- -def get_nonlocal_type(trans: rawptr[HT.Translator], - name: str) -> rawptr[llvmlite.LLVMType]: +def get_nonlocal_type(trans: HT.Translator*, + name: str) -> llvmlite.LLVMType*: """委托到 gen.TranslatorGen.get_nonlocal_type(原 Handles 壳)""" if _g_gen is not None: return _g_gen.TranslatorGen.get_nonlocal_type(trans, name) @@ -629,7 +629,7 @@ def get_nonlocal_type(trans: rawptr[HT.Translator], # ---------------- is_nonlocal_name(委托 TranslatorGenMixin.is_nonlocal_name) ---------------- -def is_nonlocal_name(trans: rawptr[HT.Translator], name: str) -> int: +def is_nonlocal_name(trans: HT.Translator*, name: str) -> int: """委托到 gen.TranslatorGen.is_nonlocal_name(原 Handles 壳)""" if _g_gen is not None: return _g_gen.TranslatorGen.is_nonlocal_name(trans, name) @@ -637,7 +637,7 @@ def is_nonlocal_name(trans: rawptr[HT.Translator], name: str) -> int: # ---------------- get_nonlocal_index(委托 TranslatorGenMixin.get_nonlocal_index) ---------------- -def get_nonlocal_index(trans: rawptr[HT.Translator], name: str) -> int: +def get_nonlocal_index(trans: HT.Translator*, name: str) -> int: """委托到 gen.TranslatorGen.get_nonlocal_index(原 Handles 壳)""" if _g_gen is not None: return _g_gen.TranslatorGen.get_nonlocal_index(trans, name) @@ -645,7 +645,7 @@ def get_nonlocal_index(trans: rawptr[HT.Translator], name: str) -> int: # ---------------- clear_scope_names(委托 TranslatorGenMixin.clear_scope_names) ---------------- -def clear_scope_names(trans: rawptr[HT.Translator]): +def clear_scope_names(trans: HT.Translator*): """委托到 gen.TranslatorGen.clear_scope_names(原 Handles 壳)""" if _g_gen is not None: _g_gen.TranslatorGen.clear_scope_names(trans) @@ -653,7 +653,7 @@ def clear_scope_names(trans: rawptr[HT.Translator]): # ---------------- update_global_func_spec(委托 CallGenLeafKit.update_global_func_spec) ---------------- def update_global_func_spec(name: str, - func: rawptr[llvmlite.Function]) -> int: + func: llvmlite.Function*) -> int: """委托到 gen.CallGenLeafKit.update_global_func_spec(原 ExprCallTable 壳)""" if _g_gen is not None: return _g_gen.CallGenLeafKit.update_global_func_spec(name, func) diff --git a/App/lib/core/Gen/GenTypes.vp b/App/lib/core/Gen/GenTypes.vp index 6450f13..3660f31 100644 --- a/App/lib/core/Gen/GenTypes.vp +++ b/App/lib/core/Gen/GenTypes.vp @@ -63,7 +63,7 @@ class TraceFrame: class VarEntry: """变量表条目""" Name: str - Alloca: rawptr[llvmlite.Value] + Alloca: 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: rawptr[TSpec.TypeSpec] + Spec: TSpec.TypeSpec* # 1=该变量的 load/store 带 LLVM volatile 限定符(注解联合含 t.CVolatile)。 # 追加在末尾:既有字段偏移不变,__sizeof__() 自动纳入,条目数组步长同步。 IsVolatile: int @@ -81,13 +81,19 @@ class VarEntry: # 的区别:IsVolatile 限定"指针变量自身"的读写,本字段限定"指针所指物"。 # 追加在末尾:既有字段偏移不变,__sizeof__() 自动纳入,条目数组步长同步。 PointeeVolatile: int + # 1=该变量是 **const 对象**(注解含 t.CConst 且声明类型**不是指针**): + # 整个作用域内禁止对该变量名赋值 / 增量赋值 / 元素赋值(fail-fast)。 + # 与 TPC 的 Gen.var_const_flags / global_const_flags 同判据、同报文,见 + # Debugger/type-descriptors.md。指针类型(如 `p: t.CConst | T | t.CPtr`)的 + # CConst 只约束 pointee,不使指针变量自身不可写,故不置 1。 + # 追加在末尾:既有字段偏移不变,__sizeof__() 自动纳入,条目数组步长同步。 + IsConst: int # ============================================================ # Scope - 作用域节点(原 HandlesVar.Scope) # ============================================================ -@t.NoVTable -class Scope: +novirtual class Scope: """作用域节点""" Parent: Scope | t.CPtr Vars: VarEntry | t.CPtr @@ -98,10 +104,9 @@ class Scope: # ============================================================ # SymbolTable - 嵌套作用域符号表(原 HandlesVar.SymbolTable) # ============================================================ -@t.NoVTable -class SymbolTable: +novirtual class SymbolTable: """嵌套作用域符号表""" - Pool: rawptr[memhub.MemBuddy] + Pool: memhub.MemBuddy* Root: Scope | t.CPtr Current: Scope | t.CPtr @@ -112,13 +117,13 @@ class SymbolTable: class FieldEntry: Name: str # 字段名(字符串) Index: int # 字段在结构体中的索引 - Ty: rawptr[llvmlite.LLVMType] # 字段的 LLVM 类型 - DefaultVal: rawptr[ast.AST] # 默认值 AST 节点(None=无默认值) + Ty: llvmlite.LLVMType* # 字段的 LLVM 类型 + DefaultVal: ast.AST* # 默认值 AST 节点(None=无默认值) # TypeSpec(S3 起为**唯一类型承载**):由 add_field 用 SpecFromLLVMType 从 # field_ty 填充(PermPool 分配 ⇒ 跨 1b reset 安全,无需 DeepCopyType), # 注解侧再经 SpecWithSign / SpecWithSource 补符号性与注解来源名 # (Spec.SourceName,原 AnnotClassName 字段已并入)。 - Spec: rawptr[TSpec.TypeSpec] + Spec: TSpec.TypeSpec* # 1=该字段经对象访问的 load/store 带 LLVM volatile 限定符 # (字段注解联合含 t.CVolatile,如 Spinlock.locked: t.CVolatile | t.CInt)。 # 追加在末尾:既有字段偏移不变,__sizeof__() 自动纳入,字段数组步长同步。 @@ -128,15 +133,19 @@ class FieldEntry: # 带 LLVM volatile。与 IsVolatile 的区别同 VarEntry.PointeeVolatile。 # 追加在末尾:既有字段偏移不变,__sizeof__() 自动纳入,字段数组步长同步。 PointeeVolatile: int + # 1=该字段是 **const 对象**(注解含 t.CConst 且字段类型**不是指针**): + # 经对象给该字段赋值(obj.f = ... / self.f = ...)即 fail-fast,与 + # VarEntry.IsConst 同判据、同报文(TPC 侧对应 Gen.field_const_flags)。 + # 追加在末尾:既有字段偏移不变,__sizeof__() 自动纳入,字段数组步长同步。 + IsConst: int # ============================================================ # StructEntry - 结构体注册条目(原 HandlesStruct.StructEntry) # ============================================================ -@t.NoVTable -class StructEntry: +novirtual class StructEntry: Name: str # 类名 - Ty: rawptr[llvmlite.LLVMType] # LLVM StructType + Ty: llvmlite.LLVMType* # LLVM StructType FieldCount: int # 字段数量 Fields: FieldEntry | t.CPtr # 字段数组(FIELD_MAX 个槽位) IsUnion: int # 1=联合体 / 0=普通结构体 @@ -148,7 +157,7 @@ class StructEntry: HasVTable: int # 1=有虚表 / 0=无虚表 IsNoVTable: int # 1=明确标记 @t.NoVTable / 0=未标记 ParentName: str # 父类名(None=无父类,多继承时为第一个父类,兼容旧调用) - ParentNames: sizet | t.CPtr # 多继承父类名数组(每元素 str 指针,ParentCount 个;stdlib 深拷贝) + ParentNames: sizet* # 多继承父类名数组(每元素 str 指针,ParentCount 个;stdlib 深拷贝) ParentCount: int # 父类数量(0=无父类,1=单继承,>1=多继承) VTableMethodCount: int # 虚表中的方法数量 VTableMethods: str # 虚表方法名数组(每个方法名 str,VTableMethodCount 个) @@ -166,16 +175,15 @@ class StructEntry: class EnumMember: Name: str # 成员名(字符串) Value: int64 # 成员的整数值 - Ty: rawptr[llvmlite.LLVMType] # 成员的 LLVM 类型(用于混用类型场景) + Ty: llvmlite.LLVMType* # 成员的 LLVM 类型(用于混用类型场景) # ============================================================ # EnumEntry - 枚举类型条目(原 HandlesEnum.EnumEntry) # ============================================================ -@t.NoVTable -class EnumEntry: +novirtual class EnumEntry: Name: str # 枚举类名 - BaseTy: rawptr[llvmlite.LLVMType] # 基准类型(所有成员类型中最大的) + BaseTy: llvmlite.LLVMType* # 基准类型(所有成员类型中最大的) MemberCount: int # 成员数量 Members: EnumMember | t.CPtr # 成员数组(ENUM_MEMBER_MAX 个槽位) @@ -185,7 +193,7 @@ class EnumEntry: # ============================================================ class AsmOperand: """内联汇编操作数条目""" - Value: rawptr[llvmlite.Value] # 输入值或输出 alloca + Value: llvmlite.Value* # 输入值或输出 alloca Constraint: str # 约束字符串 (如 "r", "=r") IsOutput: int # 1=输出, 0=输入 @@ -193,11 +201,10 @@ class AsmOperand: # ============================================================ # FuncEntry - 函数表条目(原 HandlesExprCall.FuncEntry) # ============================================================ -@t.NoVTable -class FuncEntry: +novirtual class FuncEntry: """函数表条目""" Name: str - Func: rawptr[llvmlite.Function] + Func: llvmlite.Function* Defaults: t.CPtr # defaults 列表节点指针 (list[AST | CPtr]),None=无默认值 DefaultCount: int # 默认值数量 ParamCount: int # 形参数量(不含 self) @@ -205,14 +212,13 @@ class FuncEntry: # 都在其内),由 update_global_func_spec 在形参 add_param 完成后用 NewTypeFunc 构造。 # PermPool 驻留 ⇒ 跨 1b reset 安全。单字段即可完整表达签名,与 VarEntry/FieldEntry # 的 Spec 命名一致,避免参数数组重复。 - Spec: rawptr[TSpec.TypeSpec] + Spec: TSpec.TypeSpec* # ============================================================ # FuncDefaultsEntry - 默认参数表条目(原 HandlesExprCall.FuncDefaultsEntry) # ============================================================ -@t.NoVTable -class FuncDefaultsEntry: +novirtual class FuncDefaultsEntry: """默认参数表条目""" Name: str ModuleSha1: str # 定义该函数的模块 SHA1(限定名去重,避免跨模块同名串味) @@ -224,7 +230,7 @@ class FuncDefaultsEntry: # 避免读取已被 1b reset_to(mark1) 回收的 pool 内 AST。 ConstKinds: int | t.CPtr # const_kind 数组(DefaultCount 个 i32) ConstInts: int64 | t.CPtr # int_val 数组(DefaultCount 个 i64) - ConstStrs: sizet | t.CPtr # str_val 指针数组(DefaultCount 个 i8*) + ConstStrs: sizet* # str_val 指针数组(DefaultCount 个 i8*) # ============================================================ @@ -335,8 +341,7 @@ REPL_TY_VOID: t.CDefine = 0 # 无返回值(void;不作为 # ============================================================ # ReplVarEntry - REPL 会话变量条目(跨片段存活,表本体在 PermPool) # ============================================================ -@t.NoVTable -class ReplVarEntry: +novirtual class ReplVarEntry: """REPL 会话变量条目:名字 + ctx 槽偏移 + 定型信息 Name/TyName 必须是 PermPool 深拷贝——宿主的 AST 名字串属于片段 pool, @@ -365,8 +370,7 @@ class ReplVarEntry: # REPL_TY_INT(bits=1/8/16/32/64) / REPL_TY_FLOAT(bits=32/64) / REPL_TY_STR(i8*) # 其余类型(结构体值、数组、多级指针等)⇒ 注册期明确报错,绝不静默按 i32 兜底。 # ============================================================ -@t.NoVTable -class ReplFuncEntry: +novirtual class ReplFuncEntry: """REPL 会话函数条目:名字 + 导出符号名 + ctx 函数指针槽 + 签名 token""" Name: str # 会话函数名(= 用户写的裸名;PermPool 深拷贝,NUL 结尾) SymName: str # 片段 DLL 里的导出符号名(PermPool 深拷贝;M3 = 裸名) @@ -386,8 +390,7 @@ class ReplFuncEntry: # 翻译后清空)。Gen 侧全部拦截点都以此字段为唯一守卫——普通编译路径下该字段 # 恒为 None,逐字走原路径。 # ============================================================ -@t.NoVTable -class ReplCtx: +novirtual class ReplCtx: """REPL 模式上下文(宿主持有;翻译器只读)""" Marker: int # REPL_CTX_MARKER(防误传非 ReplCtx 对象) Table: rawptr[ReplVarEntry] # 会话表数组(PermPool,容量 Cap) @@ -400,7 +403,7 @@ class ReplCtx: Scratch: rawptr[ReplVarEntry] # 宿主提供的永久池:会话表条目名/结构体名等**跨片段存活**的数据必须在此池 # 深拷贝(片段的 trans.Pool 行末 reset_to 即回收,直接存其指针会悬垂)。 - Perm: rawptr[memhub.MemBuddy] + Perm: memhub.MemBuddy* # 会话函数表(M3;宿主写、Gen 只读):数组容量 FuncCap,已登记 FuncCount 条。 # 条目只在"定义片段 DLL 加载成功且 GetProcAddress 命中"后由宿主追加 ⇒ 片段 # 翻译期看到的表恒为"先前片段的已就绪函数"(本片段新定义的同名函数走直接调用)。 @@ -416,8 +419,7 @@ class ReplCtx: # Reserved0(+12,i32) A(+16,i64) B(+24,i64) VarCount(+32,i32) LastFrag(+36,i32)。 # 宿主另有"同一头的浮点视图"(把 +16 的 8 字节按 double 读回,见 Repl.vp)。 # ============================================================ -@t.NoVTable -class ReplResult: +novirtual class ReplResult: """ctx 固定头(前 64 字节中的前 40 字节;+40..63 为保留)""" Magic: int # REPL_CTX_MAGIC('REPL') Version: int # REPL_CTX_VERSION diff --git a/App/lib/core/Gen/Generator.vp b/App/lib/core/Gen/Generator.vp index dd4b18e..50cc473 100644 --- a/App/lib/core/Gen/Generator.vp +++ b/App/lib/core/Gen/Generator.vp @@ -57,14 +57,8 @@ import lib.core.Gen.TranslatorGenMixin as TranslatorGenMixin # ============================================================ # Generator - 生成器(双向引用组合架构) -# -# 不再 46 路多继承 Mixin;改为组合:Generator 持所有 GenMixin -# 子对象指针(永久池分配,全生命周期),每个 Mixin 持 Gen 回指。 -# 跨子对象访问 = self.Gen..<字段/方法>(链式有风险, -# 统一用中间变量取子对象再访问)。高亮可推导(显式类型注解)。 # ============================================================ -@t.NoVTable -class Generator: +novirtual class Generator: """生成器:持所有 GenMixin 子对象指针(双向引用组合)""" # ---- 子对象指针(46 个,永久池) ---- @@ -116,7 +110,7 @@ class Generator: VarGen: rawptr[VarGenMixin.VarGenMixin] TranslatorGen: rawptr[TranslatorGenMixin.TranslatorGenMixin] - def __init__(self, pool: rawptr[memhub.MemBuddy]): + def __init__(self, pool: memhub.MemBuddy*): if self is None: return # ---- alloc 46 个子对象 + 回指(永久池,fail-fast) ---- diff --git a/App/lib/core/Gen/ImportsGenMixin.vp b/App/lib/core/Gen/ImportsGenMixin.vp index 55f86c3..a1821c7 100644 --- a/App/lib/core/Gen/ImportsGenMixin.vp +++ b/App/lib/core/Gen/ImportsGenMixin.vp @@ -13,7 +13,7 @@ import w32.fileio as fileio import lib.Stub.StubMerger as StubMerger import lib.core.CompilerFactory as CompilerFactory import lib.core.Gen.Translator as HT -import lib.Stub.StubMerger.StubMergerStore as StubMergerStore +import lib.Stub.StubMerger.StubMergerStore as StubMergerStore import lib.core.VLogger as VLogger @@ -34,13 +34,12 @@ MAX_REEXPORT: t.CDefine = 512 # ============================================================ # ImportsGenMixin - 导入处理 # ============================================================ -@t.NoVTable -class ImportsGenMixin: +novirtual class ImportsGenMixin: """导入处理 Mixin(P6 方法化)""" # --- 全局 re-export 映射表(原 _g_reexport_sha1s/_g_reexport_funcs/ # _g_reexport_srcs/_g_reexport_count) --- - Gen: rawptr[Generator.Generator] + Gen: Generator.Generator* ReexportSha1s: bytes ReexportFuncs: bytes ReexportSrcs: bytes @@ -54,10 +53,10 @@ class ImportsGenMixin: # 索引表用 PermPool 分配(跨文件/Phase 存活),由对应 add_* 增量维护;key/value # 均为指向该扁平串内部的指针,串在文件级 reset 前始终有效。 CurImportedModulesPtr: str - CurImportedModulesNames: rawptr[hashtable.HashTable] + CurImportedModulesNames: hashtable.HashTable* CurFromImportsPtr: str - CurFromImportsMods: rawptr[hashtable.HashTable] - CurFromImportsOrigs: rawptr[hashtable.HashTable] + CurFromImportsMods: hashtable.HashTable* + CurFromImportsOrigs: hashtable.HashTable* # 注意:不声明 CurrentFile 字段——TypeGenMixin 已声明(Generator 展平块 # 只有一份,跨父类不去重规则下重复声明会导致字段错位)。本 Mixin 的 @@ -74,10 +73,10 @@ class ImportsGenMixin: """增量更新 imported_modules 索引(复用旧索引或新建,失败则解除绑定)""" if new_ptr is None or name_ptr is None: return - perm: rawptr[memhub.MemBuddy] = CompilerFactory.factory.PermPool + perm: memhub.MemBuddy* = CompilerFactory.factory.PermPool if perm is None: return - idx: rawptr[hashtable.HashTable] = None + idx: hashtable.HashTable* = None if old_ptr is None: # 新文件/新链首:建全新索引(旧索引随旧串一起废弃) idx = hashtable.HashTable(perm) @@ -110,11 +109,11 @@ class ImportsGenMixin: """增量更新 from_imports 索引(复用旧索引或新建,失败则解除绑定)""" if new_ptr is None or local_name is None or module_name is None: return - perm: rawptr[memhub.MemBuddy] = CompilerFactory.factory.PermPool + perm: memhub.MemBuddy* = CompilerFactory.factory.PermPool if perm is None: return - idx_m: rawptr[hashtable.HashTable] = None - idx_o: rawptr[hashtable.HashTable] = None + idx_m: hashtable.HashTable* = None + idx_o: hashtable.HashTable* = None if old_ptr is None: idx_m = hashtable.HashTable(perm) idx_o = hashtable.HashTable(perm) @@ -168,7 +167,7 @@ class ImportsGenMixin: # ============================================================ # 添加已导入模块名 # ============================================================ - def add_imported_module(self, pool: rawptr[memhub.MemBuddy], + def add_imported_module(self, pool: memhub.MemBuddy*, imported_modules: str, name: str) -> str: """记录已导入的模块名,返回新的 imported_modules 字符串指针""" @@ -277,7 +276,7 @@ class ImportsGenMixin: # ============================================================ # 添加 from-import 名称映射 # ============================================================ - def add_from_import(self, pool: rawptr[memhub.MemBuddy], + def add_from_import(self, pool: memhub.MemBuddy*, from_imports: str, local_name: str, module_name: str, @@ -564,7 +563,7 @@ class ImportsGenMixin: # 解析后的完整模块名;绝对导入(level<=0)直接返回 module; # 无法解析时返回 module(回退到原始值) # ============================================================ - def _resolve_relative_module(self, pool: rawptr[memhub.MemBuddy], + def _resolve_relative_module(self, pool: memhub.MemBuddy*, current_package: str, level: int, module: str) -> str: @@ -637,7 +636,7 @@ class ImportsGenMixin: # "ast/parser.vp" → "ast" # "ast.vp" → None(顶级文件) # ============================================================ - def compute_package_from_relpath(self, pool: rawptr[memhub.MemBuddy], + def compute_package_from_relpath(self, pool: memhub.MemBuddy*, rel_path: str) -> str: """从相对路径计算包名(目录部分,分隔符替换为 .)""" if rel_path is None: @@ -700,7 +699,7 @@ class ImportsGenMixin: # File "<当前文件>", line # ImportError: # ============================================================ - def _report_import_error(self, node: rawptr[ast.AST], msg: str) -> None: + def _report_import_error(self, node: ast.AST*, msg: str) -> None: """以 Python 风格报错并退出(本地实现,避免循环依赖)""" stdio.printf("Traceback (most recent call last):\n") lineno: int = 0 @@ -778,7 +777,7 @@ class ImportsGenMixin: # includes 路径配置错误时扫描结果为 0、模块不注册 SHA1,若延迟到实际跨模块调用才报错 # 会误导("跨模块调用 'bd.alloc' 找不到模块 SHA1"),故在 import 语句处立即检测。 # t/c 是内部库,不参与 includes 扫描,豁免检查。 - def _check_import_sha1(self, node: rawptr[ast.AST], mod_name: str) -> int: + def _check_import_sha1(self, node: ast.AST*, mod_name: str) -> int: """导入时校验模块 SHA1 是否已注册,未注册则立即报错退出 Args: @@ -815,10 +814,10 @@ class ImportsGenMixin: # translate_import - 处理 import 语句,更新 trans._imported_modules # (迁移自 HandlesImports.ImportsHandle.HandleImport) # ============================================================ - def translate_import(self, trans: rawptr[HT.Translator], - node: rawptr[ast.AST]) -> int: + def translate_import(self, trans: HT.Translator*, + node: ast.AST*) -> int: """处理 import 语句,返回 0""" - imp: rawptr[ast.Import] = rawptr[ast.Import](node) + imp: ast.Import* = ast.Import*(node) if imp is None: return 0 names: list[ast.AST*]* = imp.names @@ -826,14 +825,14 @@ class ImportsGenMixin: return 0 nn: sizet = len(names) for ni in range(nn): - alias: rawptr[ast.Alias] = rawptr[ast.Alias](names.get(ni)) + alias: ast.Alias* = ast.Alias*(names.get(ni)) if alias is not None and alias.name is not None: # 导入时立即校验模块 SHA1 是否注册(fast-fail,仅全量翻译时检查) # declare_only=1/2 是 struct 预注册/import 扫描阶段:此时 SHA1 表 # 尚未包含后续才追加的模块(如 App 源文件),检查会造成误报。 if trans._declare_only == 0: self._check_import_sha1(node, alias.name) - pool_val: rawptr[memhub.MemBuddy] = trans.Pool + pool_val: memhub.MemBuddy* = trans.Pool im_val: str = trans._imported_modules trans._imported_modules = self.add_imported_module( pool_val, im_val, alias.name) @@ -869,10 +868,10 @@ class ImportsGenMixin: # 完整模块名(如 __types → llvmlite.__types),确保 .deps.txt # 记录的模块名与 SHA1 映射表一致。 # ============================================================ - def translate_import_from_module(self, trans: rawptr[HT.Translator], - node: rawptr[ast.AST]) -> int: + def translate_import_from_module(self, trans: HT.Translator*, + node: ast.AST*) -> int: """处理 from X import Y 的模块部分,更新 trans._imported_modules""" - impf: rawptr[ast.ImportFrom] = rawptr[ast.ImportFrom](node) + impf: ast.ImportFrom* = ast.ImportFrom*(node) if impf is None: return 0 # 解析模块名:相对导入需补充包前缀 @@ -899,7 +898,7 @@ class ImportsGenMixin: if names_m is not None: nn_m: sizet = len(names_m) for ni_m in range(nn_m): - alias_m: rawptr[ast.Alias] = rawptr[ast.Alias](names_m.get(ni_m)) + alias_m: ast.Alias* = ast.Alias*(names_m.get(ni_m)) if alias_m is not None and alias_m.name is not None: rl_m: sizet = string.strlen(resolved) rn_m: sizet = string.strlen(alias_m.name) @@ -928,10 +927,10 @@ class ImportsGenMixin: # 同样使用解析后的完整模块名,确保 from-import 映射 # (如 LLVMType:llvmlite.__types)能正确查到 SHA1。 # ============================================================ - def translate_import_from_names(self, trans: rawptr[HT.Translator], - node: rawptr[ast.AST]) -> int: + def translate_import_from_names(self, trans: HT.Translator*, + node: ast.AST*) -> int: """处理 from X import Y 的名称部分,更新 trans._from_imports""" - impf: rawptr[ast.ImportFrom] = rawptr[ast.ImportFrom](node) + impf: ast.ImportFrom* = ast.ImportFrom*(node) if impf is None: return 0 # 解析模块名:相对导入需补充包前缀 @@ -943,7 +942,7 @@ class ImportsGenMixin: if names is not None: nn: sizet = len(names) for ni in range(nn): - alias: rawptr[ast.Alias] = rawptr[ast.Alias](names.get(ni)) + alias: ast.Alias* = ast.Alias*(names.get(ni)) if alias is not None and alias.name is not None: local_name: str = alias.name orig_name: str = None diff --git a/App/lib/core/Gen/MatchGenMixin.vp b/App/lib/core/Gen/MatchGenMixin.vp index 6de5d58..dba3340 100644 --- a/App/lib/core/Gen/MatchGenMixin.vp +++ b/App/lib/core/Gen/MatchGenMixin.vp @@ -26,8 +26,7 @@ SCOPE_MATCH: t.CDefine = 6 MATCH_TRANSLATE_MAX_DEPTH: t.CDefine = 64 -@t.NoVTable -class MatchGenMixin: +novirtual class MatchGenMixin: """match 语句翻译 Mixin(P6 方法化)""" # _case_tail_unreachable - case 体末尾结构性不可达判定 @@ -36,9 +35,9 @@ class MatchGenMixin: # 与 HandlesIf L309-315 / ClassGenVTable L1084 同语义补 unreachable。 # 返回 1=已补 unreachable(调用方不应 br end_bb);0=正常收尾(应 br end_bb)。 # 不含 Try/With:其处理器不维护 _ctrl_merge_reachable,避免残留值误判。 - Gen: rawptr[Generator.Generator] - def _case_tail_unreachable(self, trans: rawptr[HT.Translator], - builder: rawptr[llvmlite.IRBuilder], + Gen: Generator.Generator* + def _case_tail_unreachable(self, trans: HT.Translator*, + builder: llvmlite.IRBuilder*, body_list: list[ast.AST*]*) -> int: if trans is None or builder is None: return 0 @@ -46,7 +45,7 @@ class MatchGenMixin: return 0 if body_list is None or len(body_list) == 0: return 0 - lst: rawptr[ast.AST] = body_list.get(len(body_list) - 1) + lst: ast.AST* = body_list.get(len(body_list) - 1) if lst is None: return 0 lk: int = lst.kind() @@ -62,8 +61,8 @@ class MatchGenMixin: # translate_match - match 语句主入口,返回 0 # (迁移自 HandlesMatch.MatchHandle.Handle) # ============================================================ - def translate_match(self, trans: rawptr[HT.Translator], - node: rawptr[ast.AST]) -> int: + def translate_match(self, trans: HT.Translator*, + node: ast.AST*) -> int: """match 语句翻译主入口(深度守卫包装器,原逻辑见 _translate_match_impl)""" if trans is not None: if trans.MatchTranslateDepth >= MATCH_TRANSLATE_MAX_DEPTH: @@ -75,13 +74,13 @@ class MatchGenMixin: trans.MatchTranslateDepth -= 1 return mret - def _translate_match_impl(self, trans: rawptr[HT.Translator], - node: rawptr[ast.AST]) -> int: + def _translate_match_impl(self, trans: HT.Translator*, + node: ast.AST*) -> int: if node is None: return 0 - pool: rawptr[memhub.MemBuddy] = trans.Pool - builder: rawptr[llvmlite.IRBuilder] = trans._cur_builder - func: rawptr[llvmlite.Function] = trans._cur_func + pool: memhub.MemBuddy* = trans.Pool + builder: llvmlite.IRBuilder* = trans._cur_builder + func: llvmlite.Function* = trans._cur_func if builder is None or func is None: return 0 @@ -90,10 +89,10 @@ class MatchGenMixin: # 内部声明并收尾覆盖:声明在 Handle 这里会退化为隐式全局,跨 match 污染。 trans._ctrl_merge_reachable = 0 - m_node: rawptr[ast.Match] = rawptr[ast.Match](node) + m_node: ast.Match* = ast.Match*(node) # 1. 求值 subject - subject_node: rawptr[ast.AST] = m_node.subject + subject_node: ast.AST* = m_node.subject if subject_node is None: return 0 # 序列匹配(match (a, b): case (x, y): ...)走独立路径: @@ -102,7 +101,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: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( + subject_val: 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 +111,13 @@ class MatchGenMixin: # 2. 检测是否 REnum match is_renum: int = 0 renum_name: str = None - subject_ptr: rawptr[llvmlite.Value] = None + subject_ptr: llvmlite.Value* = None # 2a. 若 subject 是 Name,查变量注解类名 if subject_node.kind() == ast.ASTKind.Name: - nm: rawptr[ast.Name] = rawptr[ast.Name](subject_node) + nm: ast.Name* = ast.Name*(subject_node) if nm.id is not None: - entry: rawptr[GenTypes.VarEntry] = self.Gen.VarGen.lookup_var_entry( + entry: GenTypes.VarEntry* = self.Gen.VarGen.lookup_var_entry( trans.SymTab, nm.id) entry_annot: str = self.Gen.VarGen.var_annot_class_name(entry) if entry_annot is not None \ @@ -137,12 +136,12 @@ class MatchGenMixin: cn: sizet = len(cases_list) ci: int = 0 while ci < cn and is_renum == 0: - case_node: rawptr[ast.AST] = cases_list.get(ci) + case_node: ast.AST* = cases_list.get(ci) if case_node is not None \ and case_node.kind() == ast.ASTKind.MatchCase: mc: rawptr[ast.MatchCase] = ( rawptr[ast.MatchCase])(case_node) - pat: rawptr[ast.AST] = mc.pattern + pat: ast.AST* = mc.pattern if pat is not None \ and pat.kind() == ast.ASTKind.MatchClass: rnm: str = self._extract_renum_name_from_cls(pat) @@ -168,27 +167,27 @@ class MatchGenMixin: # Ptr -> Name('Ptr') -> 遍历查找 # ============================================================ def _extract_renum_name_from_cls(self, - pattern: rawptr[ast.AST]) -> str: + pattern: ast.AST*) -> str: if pattern is None: return None mc: rawptr[ast.MatchClass] = rawptr[ast.MatchClass](pattern) - cls_node: rawptr[ast.AST] = mc.cls + cls_node: ast.AST* = mc.cls if cls_node is None: return None # Attribute 形式 if cls_node.kind() == ast.ASTKind.Attribute: - at: rawptr[ast.Attribute] = rawptr[ast.Attribute](cls_node) + at: ast.Attribute* = ast.Attribute*(cls_node) if at.value is not None: if at.value.kind() == ast.ASTKind.Name: - inner_nm: rawptr[ast.Name] = rawptr[ast.Name](at.value) + inner_nm: ast.Name* = ast.Name*(at.value) return inner_nm.id if at.value.kind() == ast.ASTKind.Attribute: - inner_at: rawptr[ast.Attribute] = ( - rawptr[ast.Attribute])(at.value) + inner_at: ast.Attribute* = ( + ast.Attribute*)(at.value) return inner_at.attr # Name 形式:遍历所有 REnum 类反查 if cls_node.kind() == ast.ASTKind.Name: - nm: rawptr[ast.Name] = rawptr[ast.Name](cls_node) + nm: ast.Name* = ast.Name*(cls_node) return self._find_renum_class_for_variant(nm.id) return None @@ -196,18 +195,18 @@ class MatchGenMixin: # _extract_variant_name_from_cls - 从 MatchClass.cls 提取变体名 # ============================================================ def _extract_variant_name_from_cls(self, - pattern: rawptr[ast.AST]) -> str: + pattern: ast.AST*) -> str: if pattern is None: return None mc: rawptr[ast.MatchClass] = rawptr[ast.MatchClass](pattern) - cls_node: rawptr[ast.AST] = mc.cls + cls_node: ast.AST* = mc.cls if cls_node is None: return None if cls_node.kind() == ast.ASTKind.Attribute: - at: rawptr[ast.Attribute] = rawptr[ast.Attribute](cls_node) + at: ast.Attribute* = ast.Attribute*(cls_node) return at.attr if cls_node.kind() == ast.ASTKind.Name: - nm: rawptr[ast.Name] = rawptr[ast.Name](cls_node) + nm: ast.Name* = ast.Name*(cls_node) return nm.id return None @@ -233,20 +232,20 @@ class MatchGenMixin: n: sizet = len(body_list) i: int = 0 while i < n: - stmt: rawptr[ast.AST] = body_list.get(i) + stmt: ast.AST* = body_list.get(i) if stmt is not None and stmt.kind() == ast.ASTKind.Expr: expr_node: rawptr[ast.Expr] = rawptr[ast.Expr](stmt) - val: rawptr[ast.AST] = expr_node.value + val: 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) - fn: rawptr[ast.AST] = call_node.func + call_node: ast.Call* = ast.Call*(val) + fn: ast.AST* = call_node.func if fn is not None and fn.kind() == ast.ASTKind.Attribute: - at: rawptr[ast.Attribute] = ( - rawptr[ast.Attribute])(fn) + at: ast.Attribute* = ( + ast.Attribute*)(fn) if at.value is not None \ and at.value.kind() == ast.ASTKind.Name: - base_nm: rawptr[ast.Name] = ( - rawptr[ast.Name])(at.value) + base_nm: ast.Name* = ( + ast.Name*)(at.value) if base_nm.id is not None \ and string.strcmp(base_nm.id, "c") == 0 \ and at.attr is not None \ @@ -263,13 +262,13 @@ class MatchGenMixin: # 3. 发射 build_switch # 4. 翻译每个 case body(含作用域隔离 + 变体字段绑定) # ============================================================ - def _handle_renum_match(self, trans: rawptr[HT.Translator], - node: rawptr[ast.Match], + def _handle_renum_match(self, trans: HT.Translator*, + node: ast.Match*, renum_name: str, - subject_ptr: rawptr[llvmlite.Value]) -> int: - pool: rawptr[memhub.MemBuddy] = trans.Pool - builder: rawptr[llvmlite.IRBuilder] = trans._cur_builder - func: rawptr[llvmlite.Function] = trans._cur_func + subject_ptr: llvmlite.Value*) -> int: + pool: memhub.MemBuddy* = trans.Pool + builder: llvmlite.IRBuilder* = trans._cur_builder + func: llvmlite.Function* = trans._cur_func # 局部记录本 renum match 是否有 br 进入 end_bb,收尾时覆盖 # _ctrl_merge_reachable(case 体内嵌套 If 无 else + return 会把全局 # 标志置 1,全 case return 的 match 被误判 merge 可达 → 函数收尾 @@ -283,12 +282,12 @@ class MatchGenMixin: # 情况2: subject_ptr 不是指针(值型,如 REnum payload 槽位 load 出的 i64) # → alloca REnum 结构体 + store 值 + 用 alloca 指针 # 情况3: 指针但 pointee 不是结构体 → bitcast 到 REnum 结构体指针 - subj_ty: rawptr[llvmlite.LLVMType] = subject_ptr.Ty + subj_ty: llvmlite.LLVMType* = subject_ptr.Ty if subj_ty is not None and self.Gen.ExprGenBase.is_ptr_type(subj_ty) != 0 \ - and subj_ty.Pointee is not None \ + and subj_ty.Pointee != 0 \ and self.Gen.ExprGenBase.is_ptr_type(subj_ty.Pointee) != 0: # 情况1: T** → load 一次得 T* - loaded_sub: rawptr[llvmlite.Value] = llvmlite.build_load( + loaded_sub: llvmlite.Value* = llvmlite.build_load( builder, subj_ty.Pointee, subject_ptr) if loaded_sub is not None: subject_ptr = loaded_sub @@ -296,9 +295,9 @@ 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: rawptr[GenTypes.StructEntry] = self.Gen.StructGen.find_struct( + renum_se: GenTypes.StructEntry* = self.Gen.StructGen.find_struct( renum_name) - renum_sty: rawptr[llvmlite.LLVMType] = None + renum_sty: llvmlite.LLVMType* = None if renum_se is not None: renum_sty = renum_se.Ty if renum_sty is None: @@ -307,8 +306,8 @@ class MatchGenMixin: node, f"REnum 结构体 '{renum_name}' 未注册", "NameError") - i64_ty0: rawptr[llvmlite.LLVMType] = llvmlite.Int64(pool) - int_val: rawptr[llvmlite.Value] = subject_ptr + i64_ty0: llvmlite.LLVMType* = llvmlite.Int64(pool) + int_val: 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 \ @@ -317,21 +316,21 @@ class MatchGenMixin: int_val = llvmlite.build_trunc(builder, subject_ptr, i64_ty0) else: int_val = llvmlite.build_zext(builder, subject_ptr, i64_ty0) - renum_ptr_ty0: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, renum_sty) - subj_ptr0: rawptr[llvmlite.Value] = llvmlite.build_inttoptr( + renum_ptr_ty0: llvmlite.LLVMType* = llvmlite.Ptr(pool, renum_sty) + subj_ptr0: llvmlite.Value* = llvmlite.build_inttoptr( builder, int_val, renum_ptr_ty0) if subj_ptr0 is not None: subject_ptr = subj_ptr0 # 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: rawptr[llvmlite.Value] = llvmlite.build_bitcast( + i32_ty: llvmlite.LLVMType* = llvmlite.Int32(pool) + i32_ptr_ty: llvmlite.LLVMType* = llvmlite.Ptr(pool, i32_ty) + tag_ptr: 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: rawptr[llvmlite.Value] = llvmlite.build_load( + tag_val: llvmlite.Value* = llvmlite.build_load( builder, i32_ty, tag_ptr) if tag_val is None: # fail-fast: REnum tag 读取失败 @@ -359,12 +358,12 @@ class MatchGenMixin: case_count: sizet = len(cases_list) # BB 指针数组、case 值指针数组、default 标记数组、nobreak 标记数组 - bb_arr: sizet | t.CPtr = pool.alloc(8 * MAX_MATCH_CASES) - cv_arr: sizet | t.CPtr = pool.alloc(8 * MAX_MATCH_CASES) + bb_arr: sizet* = pool.alloc(8 * MAX_MATCH_CASES) + cv_arr: sizet* = pool.alloc(8 * MAX_MATCH_CASES) def_arr: int | t.CPtr = pool.alloc(4 * MAX_MATCH_CASES) nb_arr: int | t.CPtr = pool.alloc(4 * MAX_MATCH_CASES) # pass1 缓存的 mc 指针数组(pass2 复用,避免重索引) - mc_arr: sizet | t.CPtr = pool.alloc(8 * MAX_MATCH_CASES) + mc_arr: sizet* = pool.alloc(8 * MAX_MATCH_CASES) if bb_arr is None or cv_arr is None or def_arr is None or nb_arr is None \ or mc_arr is None: # fail-fast: match 分派数组分配失败 @@ -403,7 +402,7 @@ class MatchGenMixin: # 4. 第一遍:收集 case 信息 + 创建 BB + 构建链表 i: int = 0 while i < case_count: - case_node: rawptr[ast.AST] = cases_list.get(i) + case_node: ast.AST* = cases_list.get(i) if case_node is None: i = i + 1 continue @@ -411,10 +410,10 @@ class MatchGenMixin: i = i + 1 continue mc: rawptr[ast.MatchCase] = rawptr[ast.MatchCase](case_node) - pat: rawptr[ast.AST] = mc.pattern + pat: ast.AST* = mc.pattern is_def: int = 0 - cv: rawptr[llvmlite.Value] = None + cv: llvmlite.Value* = None # 修复: 提升到臂作用域(原先声明在 MatchClass 分支内),供下方 # "未取到 case 值"诊断打印变体名/tag vnm: str = None @@ -454,7 +453,7 @@ class MatchGenMixin: mo: rawptr[ast.MatchOr] = rawptr[ast.MatchOr](pat) pats: list[ast.AST*]* = mo.patterns if pats is not None and len(pats) > 0: - first_pat: rawptr[ast.AST] = pats.get(0) + first_pat: ast.AST* = pats.get(0) if first_pat is not None \ and first_pat.kind() == ast.ASTKind.MatchValue: mv2: rawptr[ast.MatchValue] = ( @@ -533,9 +532,9 @@ class MatchGenMixin: llvmlite.build_switch(builder, tag_val, default_bb, sw_head, sw_count) # 6. 查找 REnum 结构体类型(用于变体字段绑定的 GEP) - renum_entry: rawptr[GenTypes.StructEntry] = None - renum_ty: rawptr[llvmlite.LLVMType] = None - se: rawptr[GenTypes.StructEntry] = self.Gen.StructGen.find_struct(renum_name) + renum_entry: GenTypes.StructEntry* = None + renum_ty: llvmlite.LLVMType* = None + se: GenTypes.StructEntry* = self.Gen.StructGen.find_struct(renum_name) if se is not None: renum_entry = se renum_ty = se.Ty @@ -548,7 +547,7 @@ class MatchGenMixin: if mc is None: i = i + 1 continue - pat: rawptr[ast.AST] = mc.pattern + pat: ast.AST* = mc.pattern # 取 BB bb_addr: sizet = bb_arr[i] @@ -585,7 +584,7 @@ class MatchGenMixin: # pass1 的 cases_list.get(i) 同型同码)。切勿改为 # `bl_data + bi*8` 裸地址:那会把数组槽地址当节点传入 # translate_stmt,虚调用跳进 vtable 表 → DEP 崩溃。 - stmt: rawptr[ast.AST] = body_list.get(bi) + stmt: ast.AST* = body_list.get(bi) if stmt is not None: self.Gen.StmtGen.translate_stmt(trans, stmt) bi = bi + 1 @@ -618,7 +617,7 @@ class MatchGenMixin: di: int = 0 while di < collected: if def_arr[di] == 1: - dcase: rawptr[ast.AST] = cases_list.get(di) + dcase: ast.AST* = cases_list.get(di) if dcase is not None: dmc: rawptr[ast.MatchCase] = ( rawptr[ast.MatchCase])(dcase) @@ -633,7 +632,7 @@ class MatchGenMixin: dn: sizet = len(dbody2) dj: int = 0 while dj < dn: - stmt: rawptr[ast.AST] = dbody2.get(dj) + stmt: ast.AST* = dbody2.get(dj) if stmt is not None: self.Gen.StmtGen.translate_stmt(trans, stmt) dj = dj + 1 @@ -659,14 +658,14 @@ class MatchGenMixin: # # case LLVMType.Ptr(pointee) 中的 pointee 绑定到 subject 的 payload 字段 # ============================================================ - def _bind_variant_fields(self, pat: rawptr[ast.AST], + def _bind_variant_fields(self, pat: ast.AST*, renum_name: str, - renum_entry: rawptr[GenTypes.StructEntry], - renum_ty: rawptr[llvmlite.LLVMType], - subject_ptr: rawptr[llvmlite.Value], - trans: rawptr[HT.Translator], - pool: rawptr[memhub.MemBuddy], - builder: rawptr[llvmlite.IRBuilder]): + renum_entry: GenTypes.StructEntry*, + renum_ty: llvmlite.LLVMType*, + subject_ptr: llvmlite.Value*, + trans: HT.Translator*, + pool: memhub.MemBuddy*, + builder: llvmlite.IRBuilder*): if pat is None or renum_entry is None or renum_ty is None: return mc: rawptr[ast.MatchClass] = rawptr[ast.MatchClass](pat) @@ -674,15 +673,15 @@ class MatchGenMixin: 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: rawptr[llvmlite.Value] = llvmlite.build_bitcast( + renum_ptr_ty: llvmlite.LLVMType* = llvmlite.Ptr(pool, renum_ty) + casted_ptr: llvmlite.Value* = llvmlite.build_bitcast( builder, subject_ptr, renum_ptr_ty) if casted_ptr is None: casted_ptr = subject_ptr pn: sizet = len(pats) j: int = 0 while j < pn: - sub_pat: rawptr[ast.AST] = pats.get(j) + sub_pat: ast.AST* = pats.get(j) if sub_pat is not None and sub_pat.kind() == ast.ASTKind.MatchAs: ma: rawptr[ast.MatchAs] = rawptr[ast.MatchAs](sub_pat) bind_name: str = ma.name @@ -709,10 +708,10 @@ class MatchGenMixin: f"REnum 变体字段 '{bind_name}' 在结构体 '{renum_name}' 中越界且别名查找失败", "TypeError") # 获取字段类型 - fe: rawptr[GenTypes.FieldEntry] = ( + fe: GenTypes.FieldEntry* = ( self.Gen.StructGen._get_field_entry( renum_entry, payload_idx)) - field_ty: rawptr[llvmlite.LLVMType] = None + field_ty: llvmlite.LLVMType* = None if fe is not None: field_ty = fe.Ty if field_ty is None: @@ -722,7 +721,7 @@ class MatchGenMixin: f"REnum 变体字段类型缺失: {bind_name}", "TypeError") # GEP 取字段地址 - elem_ptr: rawptr[llvmlite.Value] = ( + elem_ptr: llvmlite.Value* = ( llvmlite.build_gep_struct( builder, renum_ty, field_ty, casted_ptr, payload_idx)) @@ -739,17 +738,17 @@ class MatchGenMixin: # 必须按 (class, 变体名, 位置) 定位:MatchAs 名是局部变量名而非字段名, # 按字段名查恒不匹配;同一 payload 位置跨变体类型也不同。 # 自引用类型注册期解析失败 → 查不到类型时回退槽位类型。 - mem_ty_m: rawptr[llvmlite.LLVMType] = None + mem_ty_m: llvmlite.LLVMType* = None vnt_m: str = self._extract_variant_name_from_cls(pat) if vnt_m is not None and renum_entry is not None \ and renum_entry.Name is not None: mem_ty_m = self.Gen.ClassGenEnum._lookup_renum_member_ty( renum_entry.Name, vnt_m, payload_idx) if mem_ty_m is not None: - mem_ptr_m: rawptr[llvmlite.LLVMType] = llvmlite.Ptr( + mem_ptr_m: llvmlite.LLVMType* = llvmlite.Ptr( pool, mem_ty_m) if mem_ptr_m is not None: - cast_m: rawptr[llvmlite.Value] = llvmlite.build_bitcast( + cast_m: llvmlite.Value* = llvmlite.build_bitcast( builder, elem_ptr, mem_ptr_m) if cast_m is not None: elem_ptr = cast_m @@ -763,17 +762,17 @@ class MatchGenMixin: # 对齐 lhs/rhs(指针统一 ptrtoint i64,整数位宽统一到较宽者)后 # 生成 icmp eq,返回 i1 条件。 # ============================================================ - def _seq_cmp_eq(self, trans: rawptr[HT.Translator], - builder: rawptr[llvmlite.IRBuilder], - lhs: rawptr[llvmlite.Value], - rhs: rawptr[llvmlite.Value]) -> rawptr[llvmlite.Value]: + def _seq_cmp_eq(self, trans: HT.Translator*, + builder: llvmlite.IRBuilder*, + lhs: llvmlite.Value*, + rhs: llvmlite.Value*) -> llvmlite.Value*: """对齐 lhs/rhs 后生成 icmp eq(指针统一 ptrtoint i64)""" if lhs is None or rhs is None or builder is None: return None - pool: rawptr[memhub.MemBuddy] = trans.Pool + pool: memhub.MemBuddy* = trans.Pool if self.Gen.ExprGenBase.is_ptr_type(lhs.Ty) != 0 \ or self.Gen.ExprGenBase.is_ptr_type(rhs.Ty) != 0: - i64_ty: rawptr[llvmlite.LLVMType] = llvmlite.Int64(pool) + i64_ty: llvmlite.LLVMType* = llvmlite.Int64(pool) if self.Gen.ExprGenBase.is_ptr_type(lhs.Ty) != 0: lhs = llvmlite.build_ptrtoint(builder, lhs, i64_ty) if self.Gen.ExprGenBase.is_ptr_type(rhs.Ty) != 0: @@ -808,12 +807,12 @@ class MatchGenMixin: # body_i: → end(c.NoBreak 时 fallthrough 到下一 case body) # 全不匹配 → default → end # ============================================================ - def _handle_sequence_match(self, trans: rawptr[HT.Translator], - node: rawptr[ast.Match], - subject_node: rawptr[ast.AST]) -> int: - pool: rawptr[memhub.MemBuddy] = trans.Pool - builder: rawptr[llvmlite.IRBuilder] = trans._cur_builder - func: rawptr[llvmlite.Function] = trans._cur_func + def _handle_sequence_match(self, trans: HT.Translator*, + node: ast.Match*, + subject_node: ast.AST*) -> int: + pool: memhub.MemBuddy* = trans.Pool + builder: llvmlite.IRBuilder* = trans._cur_builder + func: llvmlite.Function* = trans._cur_func if builder is None or func is None: return 0 # 同主路径:局部记录本 sequence match 的 br end_bb,收尾覆盖 @@ -823,11 +822,11 @@ class MatchGenMixin: # 1. 求值 subject 各元素 elts: list[ast.AST*]* = None if subject_node.kind() == ast.ASTKind.Tuple: - st: rawptr[ast.Tuple] = rawptr[ast.Tuple](subject_node) + st: ast.Tuple* = ast.Tuple*(subject_node) if st is not None: elts = st.elts elif subject_node.kind() == ast.ASTKind.List: - sl2: rawptr[ast.List] = rawptr[ast.List](subject_node) + sl2: ast.List* = ast.List*(subject_node) if sl2 is not None: elts = sl2.elts if elts is None: @@ -835,15 +834,15 @@ class MatchGenMixin: ecount: sizet = len(elts) if ecount == 0: return 0 - subj_vals: sizet | t.CPtr = pool.alloc(8 * ecount) + subj_vals: sizet* = pool.alloc(8 * ecount) if subj_vals is None: return 0 for ei in range(ecount): # elts 预声明+重赋值会把 .get 误分派成 list[int].get(i32 截断); # 用内联别名接收者规避(对齐 Converter arg_defaults 内联模式) elts_inl: list[ast.AST*]* = elts - elt: rawptr[ast.AST] = elts_inl.get(ei) - sv: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( + elt: ast.AST* = elts_inl.get(ei) + sv: llvmlite.Value* = self.Gen.ExprGen.translate_value( builder, pool, trans.Module, elt, trans._funcs, trans._func_count, trans) if sv is None: @@ -869,11 +868,11 @@ class MatchGenMixin: if cases_list is None: return 0 case_count: sizet = len(cases_list) - check_arr: sizet | t.CPtr = pool.alloc(8 * MAX_MATCH_CASES) - body_arr: sizet | t.CPtr = pool.alloc(8 * MAX_MATCH_CASES) + check_arr: sizet* = pool.alloc(8 * MAX_MATCH_CASES) + body_arr: sizet* = pool.alloc(8 * MAX_MATCH_CASES) def_arr: int | t.CPtr = pool.alloc(4 * MAX_MATCH_CASES) nb_arr: int | t.CPtr = pool.alloc(4 * MAX_MATCH_CASES) - guard_arr: sizet | t.CPtr = pool.alloc(8 * MAX_MATCH_CASES) + guard_arr: sizet* = pool.alloc(8 * MAX_MATCH_CASES) if check_arr is None or body_arr is None or def_arr is None \ or nb_arr is None or guard_arr is None: return 0 @@ -893,12 +892,12 @@ class MatchGenMixin: f"match case 数量超过上限 MAX_MATCH_CASES={MAX_MATCH_CASES}", "OverflowError") break - case_node: rawptr[ast.AST] = cases_list.get(i) + case_node: ast.AST* = cases_list.get(i) if case_node is None or case_node.kind() != ast.ASTKind.MatchCase: i = i + 1 continue mc: rawptr[ast.MatchCase] = rawptr[ast.MatchCase](case_node) - pat: rawptr[ast.AST] = mc.pattern + pat: ast.AST* = mc.pattern is_def: int = 0 if pat is not None: pk: int = pat.kind() @@ -955,8 +954,8 @@ class MatchGenMixin: llvmlite.position_at_end(builder, cbb2) # 计算匹配条件(元素比较 && guard) - cond: rawptr[llvmlite.Value] = None - cnode: rawptr[ast.AST] = cases_list.get(ci) + cond: llvmlite.Value* = None + cnode: ast.AST* = cases_list.get(ci) mc2: rawptr[ast.MatchCase] = rawptr[ast.MatchCase](cnode) ms: rawptr[ast.MatchSequence] = ( rawptr[ast.MatchSequence])(mc2.pattern) @@ -974,21 +973,21 @@ class MatchGenMixin: # pats 预声明+重赋值会把 .get 误分派成 list[int].get(i32 截断); # 用内联别名接收者规避(对齐 Converter arg_defaults 内联模式) pats_inl: list[ast.AST*]* = pats - pat1: rawptr[ast.AST] = pats_inl.get(pi) + pat1: ast.AST* = pats_inl.get(pi) if pat1 is None: continue pk1: int = pat1.kind() if pk1 == ast.ASTKind.MatchValue: mv: rawptr[ast.MatchValue] = ( rawptr[ast.MatchValue])(pat1) - pv: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( + pv: 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: rawptr[llvmlite.Value] = rawptr[llvmlite.Value](subj_vals[pi]) - c1: rawptr[llvmlite.Value] = self._seq_cmp_eq(trans, builder, sv1, pv) + sv1: llvmlite.Value* = llvmlite.Value*(subj_vals[pi]) + c1: 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: @@ -1011,8 +1010,8 @@ class MatchGenMixin: # guard(若有):匹配成立且 guard 非零 g_addr: sizet = guard_arr[ci] if g_addr != 0: - gnode: rawptr[ast.AST] = (rawptr[ast.AST])(g_addr) - gv: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( + gnode: ast.AST* = (ast.AST*)(g_addr) + gv: llvmlite.Value* = self.Gen.ExprGen.translate_value( builder, pool, trans.Module, gnode, trans._funcs, trans._func_count, trans) if gv is None: @@ -1020,9 +1019,9 @@ class MatchGenMixin: gnode, "match guard 翻译失败", "TypeError") gbits: int = self.Gen.ExprGenBase.get_llvm_type_bits(gv.Ty) if gbits == 1: - g1: rawptr[llvmlite.Value] = gv + g1: llvmlite.Value* = gv else: - gzero: rawptr[llvmlite.Value] = llvmlite.const_int( + gzero: llvmlite.Value* = llvmlite.const_int( pool, gbits if gbits > 0 else 32, 0) g1 = llvmlite.build_icmp( builder, llvmlite.ICMP_NE, gv, gzero) @@ -1055,7 +1054,7 @@ class MatchGenMixin: continue bbb3: rawptr[llvmlite.BasicBlock] = rawptr[llvmlite.BasicBlock](body_arr[ci]) llvmlite.position_at_end(builder, bbb3) - cnode2: rawptr[ast.AST] = cases_list.get(ci) + cnode2: ast.AST* = cases_list.get(ci) mc3: rawptr[ast.MatchCase] = ( rawptr[ast.MatchCase])(cnode2) self.Gen.VarGen.enter_scope(trans.SymTab, SCOPE_MATCH) @@ -1064,7 +1063,7 @@ class MatchGenMixin: bc: sizet = len(body_list2) bi: int = 0 while bi < bc: - stmt: rawptr[ast.AST] = body_list2.get(bi) + stmt: ast.AST* = body_list2.get(bi) if stmt is not None: self.Gen.StmtGen.translate_stmt(trans, stmt) bi = bi + 1 @@ -1097,7 +1096,7 @@ class MatchGenMixin: di: int = 0 while di < collected: if def_arr[di] == 1: - dnode: rawptr[ast.AST] = cases_list.get(di) + dnode: ast.AST* = cases_list.get(di) if dnode is not None: dmc: rawptr[ast.MatchCase] = ( rawptr[ast.MatchCase])(dnode) @@ -1112,7 +1111,7 @@ class MatchGenMixin: dn: sizet = len(dbody2) dj: int = 0 while dj < dn: - stmt: rawptr[ast.AST] = dbody2.get(dj) + stmt: ast.AST* = dbody2.get(dj) if stmt is not None: self.Gen.StmtGen.translate_stmt(trans, stmt) dj = dj + 1 @@ -1136,20 +1135,20 @@ class MatchGenMixin: # # subject ptrtoint 到 i32 + switch 分派 # ============================================================ - def _handle_simple_match(self, trans: rawptr[HT.Translator], - node: rawptr[ast.Match], - subject_val: rawptr[llvmlite.Value]) -> int: - pool: rawptr[memhub.MemBuddy] = trans.Pool - builder: rawptr[llvmlite.IRBuilder] = trans._cur_builder - func: rawptr[llvmlite.Function] = trans._cur_func + def _handle_simple_match(self, trans: HT.Translator*, + node: ast.Match*, + subject_val: llvmlite.Value*) -> int: + pool: memhub.MemBuddy* = trans.Pool + builder: llvmlite.IRBuilder* = trans._cur_builder + func: llvmlite.Function* = trans._cur_func # 同主路径:局部记录本 simple match 的 br end_bb,收尾覆盖 # _ctrl_merge_reachable,消除 case 体内嵌套控制流污染 sm_merge_reach: int = 0 # 1. subject 转 i32(若已 i32 直接用,否则 ptrtoint) - i32_ty: rawptr[llvmlite.LLVMType] = llvmlite.Int32(pool) + i32_ty: llvmlite.LLVMType* = llvmlite.Int32(pool) subj_bits: int = self.Gen.ExprGenBase.get_llvm_type_bits(subject_val.Ty) - subj_val: rawptr[llvmlite.Value] = subject_val + subj_val: 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) @@ -1184,8 +1183,8 @@ class MatchGenMixin: self.Gen.TypeGenErr.fatal_error(node, "match cases 缺失", "TypeError") case_count: sizet = len(cases_list) - bb_arr: sizet | t.CPtr = pool.alloc(8 * MAX_MATCH_CASES) - cv_arr: sizet | t.CPtr = pool.alloc(8 * MAX_MATCH_CASES) + bb_arr: sizet* = pool.alloc(8 * MAX_MATCH_CASES) + cv_arr: sizet* = pool.alloc(8 * MAX_MATCH_CASES) def_arr: int | t.CPtr = pool.alloc(4 * MAX_MATCH_CASES) nb_arr: int | t.CPtr = pool.alloc(4 * MAX_MATCH_CASES) if bb_arr is None or cv_arr is None or def_arr is None or nb_arr is None: @@ -1201,7 +1200,7 @@ class MatchGenMixin: # 4. 第一遍:收集 + 创建 BB + 构建链表 i: int = 0 while i < case_count: - case_node: rawptr[ast.AST] = cases_list.get(i) + case_node: ast.AST* = cases_list.get(i) if case_node is None: i = i + 1 continue @@ -1209,10 +1208,10 @@ class MatchGenMixin: i = i + 1 continue mc: rawptr[ast.MatchCase] = rawptr[ast.MatchCase](case_node) - pat: rawptr[ast.AST] = mc.pattern + pat: ast.AST* = mc.pattern is_def: int = 0 - cv: rawptr[llvmlite.Value] = None + cv: llvmlite.Value* = None if pat is not None: pk: int = pat.kind() @@ -1235,7 +1234,7 @@ class MatchGenMixin: mo: rawptr[ast.MatchOr] = rawptr[ast.MatchOr](pat) pats: list[ast.AST*]* = mo.patterns if pats is not None and len(pats) > 0: - first_pat: rawptr[ast.AST] = pats.get(0) + first_pat: ast.AST* = pats.get(0) if first_pat is not None \ and first_pat.kind() == ast.ASTKind.MatchValue: mv2: rawptr[ast.MatchValue] = ( @@ -1296,7 +1295,7 @@ class MatchGenMixin: # 6. 第二遍:翻译 case body i = 0 while i < collected: - case_node: rawptr[ast.AST] = cases_list.get(i) + case_node: ast.AST* = cases_list.get(i) if case_node is None: i = i + 1 continue @@ -1321,7 +1320,7 @@ class MatchGenMixin: bc: sizet = len(body_list) bi: int = 0 while bi < bc: - stmt: rawptr[ast.AST] = body_list.get(bi) + stmt: ast.AST* = body_list.get(bi) if stmt is not None: self.Gen.StmtGen.translate_stmt(trans, stmt) bi = bi + 1 @@ -1350,7 +1349,7 @@ class MatchGenMixin: di: int = 0 while di < collected: if def_arr[di] == 1: - dcase: rawptr[ast.AST] = cases_list.get(di) + dcase: ast.AST* = cases_list.get(di) if dcase is not None: dmc: rawptr[ast.MatchCase] = ( rawptr[ast.MatchCase])(dcase) @@ -1365,7 +1364,7 @@ class MatchGenMixin: dn: sizet = len(dbody2) dj: int = 0 while dj < dn: - stmt: rawptr[ast.AST] = dbody2.get(dj) + stmt: ast.AST* = dbody2.get(dj) if stmt is not None: self.Gen.StmtGen.translate_stmt(trans, stmt) dj = dj + 1 diff --git a/App/lib/core/Gen/Stmt/StmtGenCifMixin.vp b/App/lib/core/Gen/Stmt/StmtGenCifMixin.vp index fe708fb..48447d5 100644 --- a/App/lib/core/Gen/Stmt/StmtGenCifMixin.vp +++ b/App/lib/core/Gen/Stmt/StmtGenCifMixin.vp @@ -38,7 +38,7 @@ class StmtGenCifMixin: # 用 8 字节类型:Mixin 独立布局与 Generator 组合布局的字段对齐必须一致 # (i32 首字段在组合布局中导致 EnumTable 相对偏移 4 vs 独立布局 8 的错位, # this_adjust 无法同时修正,枚举表错位到相邻字段被覆盖——ASTCtx 丢失根因)。 - Gen: rawptr[Generator.Generator] + Gen: Generator.Generator* CifEvalOk: sizet # --- 枚举注册表(原 HandlesEnum._enum_table/_enum_count) --- @@ -61,25 +61,25 @@ class StmtGenCifMixin: if string.strcmp(attr, "CIfndef") == 0: return 1 return 0 - def _is_cif_call(self, node: rawptr[ast.AST]) -> int: + def _is_cif_call(self, node: ast.AST*) -> int: """检查 test 是否为 c.CIf(...)/c.CIfdef(...)/c.CIfndef(...)(或裸 CIf 系)调用""" if node is None or node.kind() != ast.ASTKind.Call: return 0 - cl: rawptr[ast.Call] = rawptr[ast.Call](node) + cl: ast.Call* = ast.Call*(node) if cl.func is None: return 0 fk: int = cl.func.kind() if fk == ast.ASTKind.Attribute: - at: rawptr[ast.Attribute] = rawptr[ast.Attribute](cl.func) + at: ast.Attribute* = ast.Attribute*(cl.func) if at.attr is None: return 0 if at.value is not None and at.value.kind() == ast.ASTKind.Name: - vn: rawptr[ast.Name] = rawptr[ast.Name](at.value) + vn: ast.Name* = ast.Name*(at.value) if vn.id is not None and string.strcmp(vn.id, "c") == 0: return self._is_cif_attr(at.attr) return 0 if fk == ast.ASTKind.Name: - nm: rawptr[ast.Name] = rawptr[ast.Name](cl.func) + nm: ast.Name* = ast.Name*(cl.func) if nm.id is not None and self._is_cif_attr(nm.id) != 0: return 1 return 0 @@ -121,8 +121,8 @@ class StmtGenCifMixin: if string.strcmp(name, "NDEBUG") == 0: self.CifEvalOk = 1; return 0 return 0 - def _cif_name_value(self, pool: rawptr[memhub.MemBuddy], - trans: rawptr[HT.Translator], + def _cif_name_value(self, pool: memhub.MemBuddy*, + trans: HT.Translator*, name: str) -> int: """查宏名值: 本地 CDefine → 跨模块 CDefine → 平台宏。 @@ -145,9 +145,9 @@ class StmtGenCifMixin: return pv return 0 - def _cif_attr_value(self, pool: rawptr[memhub.MemBuddy], - trans: rawptr[HT.Translator], - at: rawptr[ast.Attribute]) -> int: + def _cif_attr_value(self, pool: memhub.MemBuddy*, + trans: HT.Translator*, + at: ast.Attribute*) -> int: """Attribute 宏值: platmacro.IS_WINDOWS → 本地 CDefine(attr) → 跨模块 CDefine。 命中置 self.CifEvalOk=1;未命中置 0。 @@ -157,7 +157,7 @@ class StmtGenCifMixin: return 0 if at.value.kind() != ast.ASTKind.Name: return 0 - vn: rawptr[ast.Name] = rawptr[ast.Name](at.value) + vn: ast.Name* = ast.Name*(at.value) if vn.id is None: return 0 v: int = self.Gen.TypeGenCDef.lookup_cdefine_constant(at.attr) @@ -190,9 +190,9 @@ class StmtGenCifMixin: return v2 return 0 - def _cif_eval_node(self, pool: rawptr[memhub.MemBuddy], - trans: rawptr[HT.Translator], - node: rawptr[ast.AST]) -> int: + def _cif_eval_node(self, pool: memhub.MemBuddy*, + trans: HT.Translator*, + node: ast.AST*) -> int: """递归常量求值 CIf 表达式。 支持: Constant(int) / Name(CDefine/跨模块/平台宏) / Attribute(跨模块 CDefine) @@ -205,7 +205,7 @@ class StmtGenCifMixin: return 0 k: int = node.kind() if k == ast.ASTKind.Constant: - cn: rawptr[ast.Constant] = rawptr[ast.Constant](node) + cn: ast.Constant* = ast.Constant*(node) if cn.const_kind == ast.CONST_INT: self.CifEvalOk = 1 return cn.int_val @@ -214,16 +214,16 @@ class StmtGenCifMixin: if k == ast.ASTKind.Call: return self._cif_eval_call(pool, trans, node) if k == ast.ASTKind.Name: - nm: rawptr[ast.Name] = rawptr[ast.Name](node) + nm: ast.Name* = ast.Name*(node) if nm.id is None: self.CifEvalOk = 0 return 0 return self._cif_name_value(pool, trans, nm.id) if k == ast.ASTKind.Attribute: - at: rawptr[ast.Attribute] = rawptr[ast.Attribute](node) + at: ast.Attribute* = ast.Attribute*(node) return self._cif_attr_value(pool, trans, at) if k == ast.ASTKind.UnaryOp: - uop: rawptr[ast.UnaryOp] = rawptr[ast.UnaryOp](node) + uop: ast.UnaryOp* = ast.UnaryOp*(node) if uop.operand is None: self.CifEvalOk = 0 return 0 @@ -293,7 +293,7 @@ class StmtGenCifMixin: lv = rv return 1 if k == ast.ASTKind.BinOp: - bop: rawptr[ast.BinOp] = rawptr[ast.BinOp](node) + bop: ast.BinOp* = ast.BinOp*(node) lv: int = self._cif_eval_node(pool, trans, bop.left) if self.CifEvalOk == 0: return 0 @@ -339,17 +339,17 @@ class StmtGenCifMixin: """ if name is None or symtab is None: return -1 - v: rawptr[llvmlite.Value] = self.Gen.VarGen.lookup_var(symtab, name) + v: llvmlite.Value* = self.Gen.VarGen.lookup_var(symtab, name) if v is None or v.Ty is None: return -1 - pointee: rawptr[llvmlite.LLVMType] = v.Ty.Pointee + pointee: llvmlite.LLVMType* = v.Ty.Pointee if pointee is not None and self.Gen.ExprGenBase.is_ptr_type(pointee) != 0: return 1 return 0 - def _cif_eval_call(self, pool: rawptr[memhub.MemBuddy], - trans: rawptr[HT.Translator], - node: rawptr[ast.AST]) -> int: + def _cif_eval_call(self, pool: memhub.MemBuddy*, + trans: HT.Translator*, + node: ast.AST*) -> int: """编译期函数调用求值:ctraits.isptr(x)。 命中置 self.CifEvalOk=1 返回 1/0;未识别调用置 0 返回 0。 @@ -357,18 +357,18 @@ class StmtGenCifMixin: self.CifEvalOk = 0 if node is None or trans is None: return 0 - cl: rawptr[ast.Call] = rawptr[ast.Call](node) + cl: ast.Call* = ast.Call*(node) if cl is None or cl.func is None: return 0 fk: int = cl.func.kind() if fk != ast.ASTKind.Attribute: return 0 - at: rawptr[ast.Attribute] = rawptr[ast.Attribute](cl.func) + at: ast.Attribute* = ast.Attribute*(cl.func) if at.value is None or at.attr is None: return 0 if at.value.kind() != ast.ASTKind.Name: return 0 - vn: rawptr[ast.Name] = rawptr[ast.Name](at.value) + vn: ast.Name* = ast.Name*(at.value) if vn.id is None: return 0 if string.strcmp(vn.id, "ctraits") != 0 or string.strcmp(at.attr, "isptr") != 0: @@ -377,11 +377,11 @@ class StmtGenCifMixin: if cargs is None or len(cargs) < 1: self.CifEvalOk = 0 return 0 - arg0: rawptr[ast.AST] = cargs.get(0) + arg0: ast.AST* = cargs.get(0) if arg0 is None or arg0.kind() != ast.ASTKind.Name: self.CifEvalOk = 0 return 0 - nm0: rawptr[ast.Name] = rawptr[ast.Name](arg0) + nm0: ast.Name* = ast.Name*(arg0) if nm0.id is None: self.CifEvalOk = 0 return 0 @@ -392,32 +392,32 @@ class StmtGenCifMixin: self.CifEvalOk = 1 return r - def _evaluate_cif_test(self, pool: rawptr[memhub.MemBuddy], - trans: rawptr[HT.Translator], - test: rawptr[ast.AST]) -> int: + def _evaluate_cif_test(self, pool: memhub.MemBuddy*, + trans: HT.Translator*, + test: ast.AST*) -> int: """求值 CIf 调用(test 必须是 c.CIf 系调用)。 成功: 置 self.CifEvalOk=1,返回条件值(0/1) 失败(运行时变量/未知结构): 置 self.CifEvalOk=0,返回 0 """ self.CifEvalOk = 0 - cl: rawptr[ast.Call] = rawptr[ast.Call](test) + cl: ast.Call* = ast.Call*(test) if cl is None or cl.func is None: return 0 kind: str = None fk: int = cl.func.kind() if fk == ast.ASTKind.Attribute: - at: rawptr[ast.Attribute] = rawptr[ast.Attribute](cl.func) + at: ast.Attribute* = ast.Attribute*(cl.func) kind = at.attr elif fk == ast.ASTKind.Name: - nm: rawptr[ast.Name] = rawptr[ast.Name](cl.func) + nm: ast.Name* = ast.Name*(cl.func) kind = nm.id if kind is None: return 0 cargs: list[ast.AST*]* = cl.args if cargs is None or len(cargs) < 1: return 0 - arg0: rawptr[ast.AST] = cargs.get(0) + arg0: ast.AST* = cargs.get(0) if string.strcmp(kind, "CIf") == 0: v: int = self._cif_eval_node(pool, trans, arg0) if self.CifEvalOk == 0: @@ -426,20 +426,20 @@ class StmtGenCifMixin: # CIfdef / CIfndef: 判定宏名是否已定义 defined: int = 0 if arg0 is not None and arg0.kind() == ast.ASTKind.Name: - nm0: rawptr[ast.Name] = rawptr[ast.Name](arg0) + nm0: ast.Name* = ast.Name*(arg0) if nm0.id is None: return 0 self._cif_name_value(pool, trans, nm0.id) defined = self.CifEvalOk elif arg0 is not None and arg0.kind() == ast.ASTKind.Constant: - cn0: rawptr[ast.Constant] = rawptr[ast.Constant](arg0) + cn0: ast.Constant* = ast.Constant*(arg0) if cn0.const_kind == ast.CONST_STR and cn0.str_val is not None: self._cif_name_value(pool, trans, cn0.str_val) defined = self.CifEvalOk else: return 0 elif arg0 is not None and arg0.kind() == ast.ASTKind.Attribute: - at0: rawptr[ast.Attribute] = rawptr[ast.Attribute](arg0) + at0: ast.Attribute* = ast.Attribute*(arg0) self._cif_attr_value(pool, trans, at0) defined = self.CifEvalOk else: @@ -457,35 +457,35 @@ class StmtGenCifMixin: # 翻译返回值(若有)并生成 ret 指令;裸 return 按函数返回类型生成 # 默认零值(void→ret void,ptr→null,float→0.0,其余→零值)。 # ============================================================ - def translate_return(self, trans: rawptr[HT.Translator], - node: rawptr[ast.AST]) -> int: + def translate_return(self, trans: HT.Translator*, + node: ast.AST*) -> int: """翻译 Return 语句""" rt: rawptr[ast.Return] = rawptr[ast.Return](node) if rt is None: return 0 - pool: rawptr[memhub.MemBuddy] = trans.Pool - builder: rawptr[llvmlite.IRBuilder] = trans._cur_builder - mod: rawptr[llvmlite.LLVMModule] = trans.Module + pool: memhub.MemBuddy* = trans.Pool + builder: llvmlite.IRBuilder* = trans._cur_builder + mod: llvmlite.LLVMModule* = trans.Module - val: rawptr[llvmlite.Value] = None + val: llvmlite.Value* = None if rt.value is not None: # return a, b → 打包匿名 struct 值(多返回值,函数返回类型 tuple[T1,T2]) if rt.value.kind() == ast.ASTKind.Tuple: - rtp: rawptr[ast.Tuple] = rawptr[ast.Tuple](rt.value) + rtp: ast.Tuple* = ast.Tuple*(rt.value) rtp_elts: list[ast.AST*]* = rtp.elts rt_n: sizet = 0 if rtp_elts is not None: rt_n = len(rtp_elts) if rt_n > 0 and rt_n <= 16: - rt_vals: sizet | t.CPtr = pool.alloc(8 * 16) + rt_vals: sizet* = pool.alloc(8 * 16) if rt_vals is not None: rt_val_ok: int = 1 - rt_head: rawptr[llvmlite.Function] = None - rt_tail: rawptr[llvmlite.Function] = None + rt_head: llvmlite.Function* = None + rt_tail: llvmlite.Function* = None rvi: sizet for rvi in range(rt_n): - ev_i: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( + ev_i: llvmlite.Value* = self.Gen.ExprGen.translate_value( builder, pool, mod, rtp_elts.get(rvi), trans._funcs, trans._func_count, trans) if ev_i is None: @@ -496,11 +496,11 @@ class StmtGenCifMixin: # 构建匿名 struct 类型(字段类型 = 元素值类型) rvi2: sizet for rvi2 in range(rt_n): - rv_i: rawptr[llvmlite.Value] = rawptr[llvmlite.Value]((rt_vals[rvi2])) + rv_i: llvmlite.Value* = llvmlite.Value*((rt_vals[rvi2])) if rv_i is None or rv_i.Ty is None: rt_val_ok = 0 break - rn: rawptr[llvmlite.Function] = llvmlite.new_param_node(pool, rv_i.Ty) + rn: llvmlite.Function* = llvmlite.new_param_node(pool, rv_i.Ty) if rn is None: rt_val_ok = 0 break @@ -509,17 +509,17 @@ class StmtGenCifMixin: else: llvmlite.paramnode_set_next(rt_tail, rn) rt_tail = rn - rt_struct_ty: rawptr[llvmlite.LLVMType] = None + rt_struct_ty: llvmlite.LLVMType* = None if rt_val_ok != 0 and rt_head is not None: rt_struct_ty = llvmlite.Struct(pool, rt_head, rt_n, None) - rt_tmp: rawptr[llvmlite.Value] = None + rt_tmp: llvmlite.Value* = None if rt_struct_ty is not None: rt_tmp = llvmlite.build_alloca(builder, rt_struct_ty) if rt_tmp is not None: rvi3: sizet for rvi3 in range(rt_n): - rv3: rawptr[llvmlite.Value] = rawptr[llvmlite.Value](rt_vals[rvi3]) - rfp: rawptr[llvmlite.Value] = llvmlite.build_gep_struct( + rv3: llvmlite.Value* = llvmlite.Value*(rt_vals[rvi3]) + rfp: llvmlite.Value* = llvmlite.build_gep_struct( builder, rt_struct_ty, rv3.Ty, rt_tmp, rvi3) if rfp is None: rt_val_ok = 0 @@ -532,14 +532,14 @@ class StmtGenCifMixin: # 注意: lookup_var 返回的是存储 self 的 alloca (Ptr(Ptr(StructTy))) # 需要 load 得到实际的 self 指针 (Ptr(StructTy)) if rt.value.kind() == ast.ASTKind.Name: - ret_nm: rawptr[ast.Name] = rawptr[ast.Name](rt.value) + ret_nm: ast.Name* = ast.Name*(rt.value) if ret_nm is not None and ret_nm.id is not None \ and string.strcmp(ret_nm.id, "self") == 0: - self_ptr: rawptr[llvmlite.Value] = self.Gen.VarGen.lookup_var( + self_ptr: llvmlite.Value* = self.Gen.VarGen.lookup_var( trans.SymTab, "self") if self_ptr is not None: # 检查 self_ptr 是否是 Ptr(Ptr(...))(alloca 存储指针) - self_pointee_ty: rawptr[llvmlite.LLVMType] = None + self_pointee_ty: llvmlite.LLVMType* = None match self_ptr.Ty: case llvmlite.LLVMType.Ptr(inner_ty): self_pointee_ty = inner_ty @@ -552,8 +552,8 @@ class StmtGenCifMixin: # P1-A(上下文位宽传播):把当前函数的返回类型作为 target_ty 传入, # 使 `return 12345`(-> uint64)直接物化 i64 常量,与 `return u64(12345)` # 一致,并省去下方返回类型对齐生成的 zext。 - ret_val_ty: rawptr[llvmlite.LLVMType] = None - cur_func_rv: rawptr[llvmlite.Function] = trans._cur_func + ret_val_ty: llvmlite.LLVMType* = None + cur_func_rv: llvmlite.Function* = trans._cur_func if cur_func_rv is not None: ret_val_ty = llvmlite.function_get_ret_ty(cur_func_rv) # [C①] 返回注解上下文:记录本次 return 的直接值节点,供裸名泛型 @@ -562,7 +562,7 @@ class StmtGenCifMixin: trans.CurRetNode = rt.value val = self.Gen.ExprGen.translate_value( builder, pool, mod, rt.value, - trans._funcs, trans._func_count, trans, ret_val_ty) + trans._funcs, trans._func_count, trans, ret_val_ty, "返回注解") trans.CurRetNode = None # val 为 None 时(裸 return):检查当前函数返回类型 @@ -570,11 +570,11 @@ class StmtGenCifMixin: # ptr 函数生成 ret ptr null,浮点函数生成 ConstFloat(0.0), # 否则 ret i32 0(浮点漏处理会报 llc: value doesn't match function result type) if val is None: - cur_func: rawptr[llvmlite.Function] = trans._cur_func + cur_func: llvmlite.Function* = trans._cur_func is_void_ret: int = 0 is_ptr_ret: int = 0 is_float_ret: int = 0 - ret_ty: rawptr[llvmlite.LLVMType] = None + ret_ty: llvmlite.LLVMType* = None if cur_func is not None: ret_ty = llvmlite.function_get_ret_ty(cur_func) if ret_ty is not None: @@ -589,11 +589,11 @@ class StmtGenCifMixin: llvmlite.build_ret_void(builder) return 0 if is_ptr_ret != 0: - null_val: rawptr[llvmlite.Value] = llvmlite.ConstNull(pool, ret_ty, "null") + null_val: llvmlite.Value* = llvmlite.ConstNull(pool, ret_ty, "null") llvmlite.build_ret(builder, null_val) return 0 if is_float_ret != 0: - zero_f: rawptr[llvmlite.Value] = llvmlite.ConstFloat(pool, ret_ty, 0.0) + zero_f: llvmlite.Value* = llvmlite.ConstFloat(pool, ret_ty, 0.0) llvmlite.build_ret(builder, zero_f) return 0 if ret_ty is None: @@ -609,8 +609,8 @@ class StmtGenCifMixin: # i1 → 更宽整数用 zext(bool 语义:1 保持 1,而非 sext 的 0xFF) # 注意:当 val 是整数而 ret_ty 是 ptr 时(即使 bits 相同,如 i64 vs ptr), # 也必须 inttoptr 转换,否则 llc 报 "value doesn't match function result type" - cur_func_rt: rawptr[llvmlite.Function] = trans._cur_func - ret_ty_rt: rawptr[llvmlite.LLVMType] = None + cur_func_rt: llvmlite.Function* = trans._cur_func + ret_ty_rt: llvmlite.LLVMType* = None if cur_func_rt is not None and val is not None and val.Ty is not None: ret_ty_rt = llvmlite.function_get_ret_ty(cur_func_rt) # void 函数 return :丢弃值 + ret void(Python 语义合法;此前 @@ -655,8 +655,8 @@ class StmtGenCifMixin: # 指针 → 指针且元素类型不同(如 t\.CVoid(x, CPtr) 得到 i8*, # 函数返回类型是类指针 Circle* 时)需 bitcast 回, # 否则 llc 报 "value doesn't match function result type"。 - val_pointee: rawptr[llvmlite.LLVMType] = None - ret_pointee: rawptr[llvmlite.LLVMType] = None + val_pointee: llvmlite.LLVMType* = None + ret_pointee: llvmlite.LLVMType* = None match val.Ty: case llvmlite.LLVMType.Ptr(v_inner): val_pointee = v_inner @@ -692,15 +692,15 @@ class StmtGenCifMixin: # br label %end # end: # ============================================================ - def translate_if(self, trans: rawptr[HT.Translator], - node: rawptr[ast.AST]) -> int: + def translate_if(self, trans: HT.Translator*, + node: ast.AST*) -> int: """翻译 if/elif/else 语句""" if node is None: return 0 - pool: rawptr[memhub.MemBuddy] = trans.Pool - builder: rawptr[llvmlite.IRBuilder] = trans._cur_builder - func: rawptr[llvmlite.Function] = trans._cur_func + pool: memhub.MemBuddy* = trans.Pool + builder: llvmlite.IRBuilder* = trans._cur_builder + func: llvmlite.Function* = trans._cur_func if builder is None or func is None: return 0 @@ -719,13 +719,13 @@ class StmtGenCifMixin: bc_cif: sizet = len(body_cif) bi_cif: sizet for bi_cif in range(bc_cif): - stmt_cif: rawptr[ast.AST] = body_cif.get(bi_cif) + stmt_cif: ast.AST* = body_cif.get(bi_cif) if stmt_cif is not None: self.Gen.StmtGen.translate_stmt(trans, stmt_cif) else: orelse_cif: list[ast.AST*]* = if_node.orelse if orelse_cif is not None and len(orelse_cif) == 1: - sub_cif: rawptr[ast.AST] = orelse_cif.get(0) + sub_cif: ast.AST* = orelse_cif.get(0) if sub_cif is not None and sub_cif.kind() == ast.ASTKind.If: # elif: 递归(子 If 的 test 仍会走 CIf 判定或运行时翻译) self.translate_if(trans, sub_cif) @@ -735,13 +735,13 @@ class StmtGenCifMixin: oc_cif: sizet = len(orelse_cif) oi_cif: sizet for oi_cif in range(oc_cif): - stmt_cif2: rawptr[ast.AST] = orelse_cif.get(oi_cif) + stmt_cif2: ast.AST* = orelse_cif.get(oi_cif) if stmt_cif2 is not None: self.Gen.StmtGen.translate_stmt(trans, stmt_cif2) return 0 # 1. 求值条件表达式 - cond_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( + cond_val: llvmlite.Value* = self.Gen.ExprGen.translate_value( builder, pool, trans.Module, if_node.test, trans._funcs, trans._func_count, trans) @@ -752,14 +752,14 @@ class StmtGenCifMixin: self.Gen.TypeGenErr.fatal_error(if_node.test, "if 条件表达式翻译失败", "TypeError") cond_bits: int = self.Gen.ExprGenBase.get_llvm_type_bits(cond_val.Ty) if cond_bits == 1: - cond_i1: rawptr[llvmlite.Value] = cond_val + cond_i1: llvmlite.Value* = cond_val elif self.Gen.ExprGenBase.is_ptr_type(cond_val.Ty) != 0: # 指针类型:与 null 比较(不能用整数 0,否则 llc 报 "integer constant must have integer type") - null_cond: rawptr[llvmlite.Value] = llvmlite.ConstNull(pool, cond_val.Ty, "null") + null_cond: llvmlite.Value* = llvmlite.ConstNull(pool, cond_val.Ty, "null") cond_i1 = llvmlite.build_icmp( builder, llvmlite.ICMP_NE, cond_val, null_cond) else: - zero: rawptr[llvmlite.Value] = llvmlite.const_int32(pool, 0) + zero: llvmlite.Value* = llvmlite.const_int32(pool, 0) cond_i1 = llvmlite.build_icmp( builder, llvmlite.ICMP_NE, cond_val, zero) @@ -802,7 +802,7 @@ class StmtGenCifMixin: if body is not None: body_count: sizet = len(body) for bi in range(body_count): - stmt: rawptr[ast.AST] = body.get(bi) + stmt: ast.AST* = body.get(bi) if stmt is not None: self.Gen.StmtGen.translate_stmt(trans, stmt) @@ -828,7 +828,7 @@ class StmtGenCifMixin: llvmlite.position_at_end(builder, else_bb) else_count: sizet = len(orelse_list) for ei in range(else_count): - stmt: rawptr[ast.AST] = orelse_list.get(ei) + stmt: ast.AST* = orelse_list.get(ei) if stmt is not None: self.Gen.StmtGen.translate_stmt(trans, stmt) if llvmlite.builder_cur_block_is_terminated(builder) == 0: @@ -864,15 +864,15 @@ class StmtGenCifMixin: # br label %cond # end: # ============================================================ - def translate_while(self, trans: rawptr[HT.Translator], - node: rawptr[ast.AST]) -> int: + def translate_while(self, trans: HT.Translator*, + node: ast.AST*) -> int: """翻译 while 循环语句""" if node is None: return 0 - pool: rawptr[memhub.MemBuddy] = trans.Pool - builder: rawptr[llvmlite.IRBuilder] = trans._cur_builder - func: rawptr[llvmlite.Function] = trans._cur_func + pool: memhub.MemBuddy* = trans.Pool + builder: llvmlite.IRBuilder* = trans._cur_builder + func: llvmlite.Function* = trans._cur_func if builder is None or func is None: return 0 @@ -898,7 +898,7 @@ class StmtGenCifMixin: # 3. cond 块: 求值条件,条件分支 llvmlite.position_at_end(builder, cond_bb) - cond_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( + cond_val: llvmlite.Value* = self.Gen.ExprGen.translate_value( builder, pool, trans.Module, while_node.test, trans._funcs, trans._func_count, trans) if cond_val is None: @@ -908,14 +908,14 @@ class StmtGenCifMixin: # Compare/Not 表达式已返回 i1,直接使用;指针类型与 null 比较;其他类型与 0 比较 cond_bits: int = self.Gen.ExprGenBase.get_llvm_type_bits(cond_val.Ty) if cond_bits == 1: - cond_i1: rawptr[llvmlite.Value] = cond_val + cond_i1: llvmlite.Value* = cond_val elif self.Gen.ExprGenBase.is_ptr_type(cond_val.Ty) != 0: # 指针类型:与 null 比较(不能用整数 0,否则 llc 报 "integer constant must have integer type") - null_cond: rawptr[llvmlite.Value] = llvmlite.ConstNull(pool, cond_val.Ty, "null") + null_cond: llvmlite.Value* = llvmlite.ConstNull(pool, cond_val.Ty, "null") cond_i1 = llvmlite.build_icmp( builder, llvmlite.ICMP_NE, cond_val, null_cond) else: - zero: rawptr[llvmlite.Value] = llvmlite.const_int32(pool, 0) + zero: llvmlite.Value* = llvmlite.const_int32(pool, 0) cond_i1 = llvmlite.build_icmp( builder, llvmlite.ICMP_NE, cond_val, zero) llvmlite.build_cond_br(builder, cond_i1, body_bb, end_bb) @@ -933,7 +933,7 @@ class StmtGenCifMixin: if body is not None: body_count: sizet = len(body) for bi in range(body_count): - stmt: rawptr[ast.AST] = body.get(bi) + stmt: ast.AST* = body.get(bi) if stmt is not None: self.Gen.StmtGen.translate_stmt(trans, stmt) @@ -964,19 +964,19 @@ class StmtGenCifMixin: # _NodeHasBreak / _StmtHasBreak: 扫描本层 break(跳过嵌套 While/For # 子树——嵌套循环的 break 归内层,不影响外层 merge 可达性) # ============================================================ - def _IsConstTrue(self, test: rawptr[ast.AST]) -> int: + def _IsConstTrue(self, test: ast.AST*) -> int: """while 条件为常量真(1 / True)返回 1""" if test is None: return 0 if test.kind() == ast.ASTKind.Constant: - cn: rawptr[ast.Constant] = rawptr[ast.Constant](test) + cn: ast.Constant* = ast.Constant*(test) if cn.const_kind == ast.CONST_INT and cn.int_val != 0: return 1 if cn.const_kind == ast.CONST_BOOL and cn.int_val != 0: return 1 return 0 - def _NodeHasBreak(self, node: rawptr[ast.AST]) -> int: + def _NodeHasBreak(self, node: ast.AST*) -> int: """递归扫描节点子树(跳过嵌套 While/For 子树),含 Break 返回 1""" if node is None: return 0 @@ -984,7 +984,7 @@ class StmtGenCifMixin: if ch is not None: n: sizet = len(ch) for bi in range(n): - c: rawptr[ast.AST] = ch.get(bi) + c: ast.AST* = ch.get(bi) if c is None: continue k: int = c.kind() @@ -1002,7 +1002,7 @@ class StmtGenCifMixin: return 0 n: sizet = len(body) for bi in range(n): - s: rawptr[ast.AST] = body.get(bi) + s: ast.AST* = body.get(bi) if s is None: continue k: int = s.kind() @@ -1035,15 +1035,15 @@ class StmtGenCifMixin: # br label %cond # end: # ============================================================ - def translate_for(self, trans: rawptr[HT.Translator], - node: rawptr[ast.AST]) -> int: + def translate_for(self, trans: HT.Translator*, + node: ast.AST*) -> int: """翻译 for i in range(...) 循环语句""" if node is None: return 0 - pool: rawptr[memhub.MemBuddy] = trans.Pool - builder: rawptr[llvmlite.IRBuilder] = trans._cur_builder - func: rawptr[llvmlite.Function] = trans._cur_func + pool: memhub.MemBuddy* = trans.Pool + builder: llvmlite.IRBuilder* = trans._cur_builder + func: llvmlite.Function* = trans._cur_func if builder is None or func is None: return 0 @@ -1051,7 +1051,7 @@ class StmtGenCifMixin: for_node: rawptr[ast.For] = rawptr[ast.For](node) # 1. 获取循环变量(Name 单变量 / Tuple 多变量) - target: rawptr[ast.AST] = for_node.target + target: ast.AST* = for_node.target if target is None: return 0 tk: int = target.kind() @@ -1059,20 +1059,20 @@ class StmtGenCifMixin: return 0 var_name: str = None if tk == ast.ASTKind.Name: - target_nm: rawptr[ast.Name] = rawptr[ast.Name](target) + target_nm: ast.Name* = ast.Name*(target) var_name = target_nm.id if var_name is None: return 0 # 2. 解析迭代器:支持 range() 和指针迭代 - iter_node: rawptr[ast.AST] = for_node.iter + iter_node: ast.AST* = for_node.iter if iter_node is None: return 0 # 检查是否是 range() 调用 is_range_iter: int = 0 if iter_node.kind() == ast.ASTKind.Call: - call_pre: rawptr[ast.Call] = rawptr[ast.Call](iter_node) + call_pre: ast.Call* = ast.Call*(iter_node) fn_pre: str = self.Gen.ExprGenBase.get_func_name(call_pre.func) if fn_pre is not None: if string.strcmp(fn_pre, "range") == 0: @@ -1093,12 +1093,12 @@ class StmtGenCifMixin: return self._handle_list_literal_iter(trans, for_node, var_name, iter_node) # enumerate(x):for i, v in enumerate(x)(多变量迭代) if iter_node.kind() == ast.ASTKind.Call: - call_mi: rawptr[ast.Call] = rawptr[ast.Call](iter_node) + call_mi: ast.Call* = ast.Call*(iter_node) fn_mi: str = self.Gen.ExprGenBase.get_func_name(call_mi.func) if fn_mi is not None and string.strcmp(fn_mi, "enumerate") == 0: if tk != ast.ASTKind.Tuple: self.Gen.TypeGenErr.fatal_error(iter_node, "enumerate 迭代需要两个循环变量 (for i, v in enumerate(x))") - tup_ie: rawptr[ast.Tuple] = rawptr[ast.Tuple](target) + tup_ie: ast.Tuple* = ast.Tuple*(target) t1_buf_ie: bytes = pool.alloc(128) t2_buf_ie: bytes = pool.alloc(128) if t1_buf_ie is None or t2_buf_ie is None: @@ -1111,7 +1111,7 @@ class StmtGenCifMixin: if fn_mi is not None and string.strcmp(fn_mi, "zip") == 0: if tk != ast.ASTKind.Tuple: self.Gen.TypeGenErr.fatal_error(iter_node, "zip 迭代需要两个循环变量 (for a, b in zip(...))") - tup_iz: rawptr[ast.Tuple] = rawptr[ast.Tuple](target) + tup_iz: ast.Tuple* = ast.Tuple*(target) t1_buf_iz: bytes = pool.alloc(128) t2_buf_iz: bytes = pool.alloc(128) if t1_buf_iz is None or t2_buf_iz is None: @@ -1123,9 +1123,9 @@ class StmtGenCifMixin: return self._handle_zip_iter(trans, for_node, t1_buf_iz, t2_buf_iz, call_mi) # list[T] 容器变量:按 __count__ 动态长度迭代 if iter_node.kind() == ast.ASTKind.Name and trans is not None: - nm_lst: rawptr[ast.Name] = rawptr[ast.Name](iter_node) + nm_lst: ast.Name* = ast.Name*(iter_node) if nm_lst.id is not None: - ve_lst: rawptr[GenTypes.VarEntry] = self.Gen.VarGen.lookup_var_entry( + ve_lst: GenTypes.VarEntry* = self.Gen.VarGen.lookup_var_entry( trans.SymTab, nm_lst.id) lst_annot: str = self.Gen.VarGen.var_annot_class_name(ve_lst) if lst_annot is not None: @@ -1133,7 +1133,7 @@ class StmtGenCifMixin: # [S4] 容器基名精确比较(SpecTypeNameBaseIs):原 strstr("dict") 子串匹配 # 会误命中任何含 "dict" 的类名(如 MyDictHelper)。 if TSpec.SpecTypeNameBaseIs(lst_annot, "dict") != 0: - lst_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( + lst_val: llvmlite.Value* = self.Gen.ExprGen.translate_value( builder, pool, trans.Module, iter_node, trans._funcs, trans._func_count, trans) if lst_val is not None and lst_val.Ty is not None \ @@ -1142,7 +1142,7 @@ class StmtGenCifMixin: # [S4] 同上:原 strstr("list") 会误命中 playlist / GSList 等; # 非 list 基名的用户类改由下方 OOP __iter__/__next__ 路径处理(更正确)。 if TSpec.SpecTypeNameBaseIs(lst_annot, "list") != 0: - lst_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( + lst_val: llvmlite.Value* = self.Gen.ExprGen.translate_value( builder, pool, trans.Module, iter_node, trans._funcs, trans._func_count, trans) if lst_val is not None and lst_val.Ty is not None \ @@ -1151,12 +1151,12 @@ class StmtGenCifMixin: # OOP iter 协议:迭代源是类对象且类有 __iter__/__next__ 方法 → # 走 __iter__/__next__ 调用迭代(对齐 TPC HandlesFor.py L142-166 # _HandleForIterLlvm)。dict/list 是内置泛型容器已在上方内联处理。 - ov_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( + ov_val: llvmlite.Value* = self.Gen.ExprGen.translate_value( builder, pool, trans.Module, iter_node, trans._funcs, trans._func_count, trans) if ov_val is not None and ov_val.Ty is not None \ and self.Gen.ExprGenBase.is_ptr_type(ov_val.Ty) != 0: - ov_st: rawptr[llvmlite.LLVMType] = self.Gen.StructGen.get_struct_type_from_value( + ov_st: llvmlite.LLVMType* = self.Gen.StructGen.get_struct_type_from_value( ov_val) if ov_st is not None: ov_cn: str = self.Gen.StructGen.get_class_name_by_type(pool, ov_st) @@ -1164,13 +1164,13 @@ class StmtGenCifMixin: oi_lookup: str = pool.alloc(128) if oi_lookup is not None: viperlib.snprintf(oi_lookup, 128, "%s.__iter__", ov_cn) - oi_fn: rawptr[llvmlite.Function] = self.Gen.CallGenBase.find_func_in_module( + oi_fn: llvmlite.Function* = self.Gen.CallGenBase.find_func_in_module( trans.Module, oi_lookup) if oi_fn is not None: on_lookup: str = pool.alloc(128) if on_lookup is not None: viperlib.snprintf(on_lookup, 128, "%s.__next__", ov_cn) - on_fn: rawptr[llvmlite.Function] = self.Gen.CallGenBase.find_func_in_module( + on_fn: llvmlite.Function* = self.Gen.CallGenBase.find_func_in_module( trans.Module, on_lookup) if on_fn is not None: return self._handle_oop_iter( @@ -1179,7 +1179,7 @@ class StmtGenCifMixin: # 避免 translate_value 触发 list[T] 特化崩溃或语义歧义。 ik: int = iter_node.kind() if ik == ast.ASTKind.Constant: - cn_ik: rawptr[ast.Constant] = rawptr[ast.Constant](iter_node) + cn_ik: ast.Constant* = ast.Constant*(iter_node) if cn_ik.const_kind != ast.CONST_STR: self.Gen.TypeGenErr.fatal_error( iter_node, @@ -1191,7 +1191,7 @@ class StmtGenCifMixin: "for 迭代不支持字典/集合/元组字面量,请使用 range()、t.CArray 数组或列表字面量") return self._handle_ptr_iter(trans, for_node, var_name) - call: rawptr[ast.Call] = rawptr[ast.Call](iter_node) + call: ast.Call* = ast.Call*(iter_node) # 3. 解析 range 参数: range(stop) / range(start, stop) / range(start, stop, step) args: list[ast.AST*]* = call.args @@ -1199,10 +1199,10 @@ class StmtGenCifMixin: return 0 arg_count: sizet = len(args) - i32_ty: rawptr[llvmlite.LLVMType] = llvmlite.Int32(pool) - start_val: rawptr[llvmlite.Value] = llvmlite.const_int32(pool, 0) - stop_val: rawptr[llvmlite.Value] = None - step_val: rawptr[llvmlite.Value] = llvmlite.const_int32(pool, 1) + i32_ty: llvmlite.LLVMType* = llvmlite.Int32(pool) + start_val: llvmlite.Value* = llvmlite.const_int32(pool, 0) + stop_val: llvmlite.Value* = None + step_val: llvmlite.Value* = llvmlite.const_int32(pool, 1) if arg_count == 0: # fail-fast: range 无参数,立即终止 @@ -1240,18 +1240,18 @@ class StmtGenCifMixin: # 修复 _find_provider 的 range(top-1, -1, -1) 循环体不执行(i < -1 恒假)。 step_neg_const: int = 0 if arg_count >= 3: - step_arg_node: rawptr[ast.AST] = args.get(2) + step_arg_node: ast.AST* = args.get(2) if step_arg_node is not None: skn: int = step_arg_node.kind() if skn == ast.ASTKind.UnaryOp: - uop_r: rawptr[ast.UnaryOp] = rawptr[ast.UnaryOp](step_arg_node) + uop_r: ast.UnaryOp* = ast.UnaryOp*(step_arg_node) if uop_r.op == ast.OpKind.USub and uop_r.operand is not None: if uop_r.operand.kind() == ast.ASTKind.Constant: - uoc_r: rawptr[ast.Constant] = rawptr[ast.Constant](uop_r.operand) + uoc_r: ast.Constant* = ast.Constant*(uop_r.operand) if uoc_r.int_val > 0: step_neg_const = 1 elif skn == ast.ASTKind.Constant: - skc_r: rawptr[ast.Constant] = rawptr[ast.Constant](step_arg_node) + skc_r: ast.Constant* = ast.Constant*(step_arg_node) if skc_r.int_val < 0: step_neg_const = 1 @@ -1259,7 +1259,7 @@ class StmtGenCifMixin: # 不固定 i32:固定 i32 alloca 会截断 uint64 上界(range(heap_end, new_end, 4096) # 生成 trunc i64→i32 → 高 32 位丢失 → 映射地址错误)。仅当循环变量尚未声明时生效; # 已声明变量沿用其 alloca 元素类型(见下方 loop_var_ty 解引用)。 - loop_store_ty: rawptr[llvmlite.LLVMType] = i32_ty + loop_store_ty: llvmlite.LLVMType* = i32_ty range_arg_bits: int = 0 if arg_count == 1: if stop_val is not None and stop_val.Ty is not None: @@ -1308,18 +1308,18 @@ class StmtGenCifMixin: # 此处无条件退回有符号谓词(slt/sgt),与 3.6 的无符号优化不冲突。 stop_neg_const: int = 0 if arg_count >= 2: - stop_arg_node: rawptr[ast.AST] = args.get(1) + stop_arg_node: ast.AST* = args.get(1) if stop_arg_node is not None: stn_k: int = stop_arg_node.kind() if stn_k == ast.ASTKind.UnaryOp: - stop_uop: rawptr[ast.UnaryOp] = rawptr[ast.UnaryOp](stop_arg_node) + stop_uop: ast.UnaryOp* = ast.UnaryOp*(stop_arg_node) if stop_uop.op == ast.OpKind.USub and stop_uop.operand is not None: if stop_uop.operand.kind() == ast.ASTKind.Constant: - stop_uc: rawptr[ast.Constant] = rawptr[ast.Constant](stop_uop.operand) + stop_uc: ast.Constant* = ast.Constant*(stop_uop.operand) if stop_uc.int_val > 0: stop_neg_const = 1 elif stn_k == ast.ASTKind.Constant: - stop_c: rawptr[ast.Constant] = rawptr[ast.Constant](stop_arg_node) + stop_c: ast.Constant* = ast.Constant*(stop_arg_node) if stop_c.int_val < 0: stop_neg_const = 1 if stop_neg_const != 0: @@ -1330,7 +1330,7 @@ class StmtGenCifMixin: # 命中父函数同名变量(如父函数自己的循环计数器 i)→ 循环计数写到 # 父函数存储 → 跨函数 SSA 错乱(llc "instruction expected to be # numbered",Terminal _cmd_cd 的 for i in range(1,64) 根因)。 - var_alloca: rawptr[llvmlite.Value] = self.Gen.VarGen.lookup_current( + var_alloca: llvmlite.Value* = self.Gen.VarGen.lookup_current( trans.SymTab, var_name) new_vars: int = 0 if var_alloca is None: @@ -1350,7 +1350,7 @@ class StmtGenCifMixin: # 获取循环变量的实际元素类型(alloca 是指针类型,需解引用 Pointee) # 当循环变量已声明为 i64(如 sizet),使用 i64 而非硬编码 i32 # 避免 load i32, i64* / store i32, i64* 类型不匹配 - loop_var_ty: rawptr[llvmlite.LLVMType] = i32_ty + loop_var_ty: llvmlite.LLVMType* = i32_ty if var_alloca is not None and var_alloca.Ty is not None: match var_alloca.Ty: case llvmlite.LLVMType.Ptr(pointee_ty): @@ -1359,7 +1359,7 @@ class StmtGenCifMixin: loop_var_bits: int = self.Gen.ExprGenBase.get_llvm_type_bits(loop_var_ty) # 5. 存储初始值 (类型对齐: start_val 可能是 i32/i64,需对齐到 loop_var_ty) - init_val: rawptr[llvmlite.Value] = start_val + init_val: llvmlite.Value* = start_val if start_val is not None and start_val.Ty is not None: start_bits: int = self.Gen.ExprGenBase.get_llvm_type_bits(start_val.Ty) if start_bits != 0 and start_bits != loop_var_bits: @@ -1391,10 +1391,10 @@ class StmtGenCifMixin: # 8. cond 块: load i, icmp slt i, stop, cond_br body/end llvmlite.position_at_end(builder, cond_bb) - cur_i: rawptr[llvmlite.Value] = llvmlite.build_load(builder, loop_var_ty, var_alloca) + cur_i: llvmlite.Value* = llvmlite.build_load(builder, loop_var_ty, var_alloca) # 类型对齐: stop_val 可能是 i64 (如 range(strlen(s))),需将 cur_i 提升到 stop_val 类型 - cmp_lhs: rawptr[llvmlite.Value] = cur_i - cmp_rhs: rawptr[llvmlite.Value] = stop_val + cmp_lhs: llvmlite.Value* = cur_i + cmp_rhs: llvmlite.Value* = stop_val if stop_val is not None and stop_val.Ty is not None: stop_bits: int = self.Gen.ExprGenBase.get_llvm_type_bits(stop_val.Ty) cur_bits: int = self.Gen.ExprGenBase.get_llvm_type_bits(cur_i.Ty) @@ -1416,7 +1416,7 @@ class StmtGenCifMixin: range_cmp_op = llvmlite.ICMP_UGT else: range_cmp_op = llvmlite.ICMP_ULT - cond_i1: rawptr[llvmlite.Value] = llvmlite.build_icmp( + cond_i1: llvmlite.Value* = llvmlite.build_icmp( builder, range_cmp_op, cmp_lhs, cmp_rhs) llvmlite.build_cond_br(builder, cond_i1, body_bb, end_bb) @@ -1433,7 +1433,7 @@ class StmtGenCifMixin: if body is not None: body_count: sizet = len(body) for bi in range(body_count): - stmt: rawptr[ast.AST] = body.get(bi) + stmt: ast.AST* = body.get(bi) if stmt is not None: self.Gen.StmtGen.translate_stmt(trans, stmt) @@ -1446,9 +1446,9 @@ class StmtGenCifMixin: # 10. incr 块: i = i + step, 跳回 cond llvmlite.position_at_end(builder, incr_bb) - cur_i2: rawptr[llvmlite.Value] = llvmlite.build_load(builder, loop_var_ty, var_alloca) + cur_i2: llvmlite.Value* = llvmlite.build_load(builder, loop_var_ty, var_alloca) # 类型对齐: step_val 可能是 i32/i64,需对齐到 loop_var_ty 与 cur_i2 类型一致 - incr_step: rawptr[llvmlite.Value] = step_val + incr_step: llvmlite.Value* = step_val if step_val is not None and step_val.Ty is not None: step_bits: int = self.Gen.ExprGenBase.get_llvm_type_bits(step_val.Ty) cur2_bits: int = self.Gen.ExprGenBase.get_llvm_type_bits(cur_i2.Ty) @@ -1457,7 +1457,7 @@ class StmtGenCifMixin: incr_step = llvmlite.build_trunc(builder, step_val, loop_var_ty) else: incr_step = llvmlite.build_sext(builder, step_val, loop_var_ty) - next_i: rawptr[llvmlite.Value] = llvmlite.build_add(builder, cur_i2, incr_step) + next_i: llvmlite.Value* = llvmlite.build_add(builder, cur_i2, incr_step) llvmlite.build_store(builder, next_i, var_alloca) llvmlite.build_br(builder, cond_bb) @@ -1474,7 +1474,7 @@ class StmtGenCifMixin: # enumerate(x) → for i, v in enumerate(x):i 为序号,v 为元素 # zip(a, b) → for x, y in zip(a, b):任一源耗尽即终止 # ============================================================ - def _extract_tuple_names(self, tup: rawptr[ast.Tuple], + def _extract_tuple_names(self, tup: ast.Tuple*, out1: str, out2: str) -> int: """从 Tuple target 提取前两个 Name 变量名,写入 out1/out2,成功返回 1""" if tup is None or tup.elts is None or out1 is None or out2 is None: @@ -1483,41 +1483,41 @@ class StmtGenCifMixin: n: sizet = len(elts) if n < 2: return 0 - e0: rawptr[ast.AST] = elts.get(0) - e1: rawptr[ast.AST] = elts.get(1) + e0: ast.AST* = elts.get(0) + e1: ast.AST* = elts.get(1) if e0 is None or e1 is None: return 0 if e0.kind() != ast.ASTKind.Name or e1.kind() != ast.ASTKind.Name: return 0 - n0: rawptr[ast.Name] = rawptr[ast.Name](e0) - n1: rawptr[ast.Name] = rawptr[ast.Name](e1) + n0: ast.Name* = ast.Name*(e0) + n1: ast.Name* = ast.Name*(e1) if n0.id is None or n1.id is None: return 0 string.strcpy(out1, n0.id) string.strcpy(out2, n1.id) return 1 - def _seq_kind(self, trans: rawptr[HT.Translator], - src: rawptr[ast.AST]) -> int: + def _seq_kind(self, trans: HT.Translator*, + src: ast.AST*) -> int: """判断迭代源类型: SEQ_KIND_RANGE / STR / LIST,不支持返回 0""" if src is None: return 0 k: int = src.kind() if k == ast.ASTKind.Call: - cl_s: rawptr[ast.Call] = rawptr[ast.Call](src) + cl_s: ast.Call* = ast.Call*(src) fn_s: str = self.Gen.ExprGenBase.get_func_name(cl_s.func) if fn_s is not None and string.strcmp(fn_s, "range") == 0: return GenTypes.SEQ_KIND_RANGE return 0 if k == ast.ASTKind.Constant: - cn_s: rawptr[ast.Constant] = rawptr[ast.Constant](src) + cn_s: ast.Constant* = ast.Constant*(src) if cn_s is not None and cn_s.const_kind == ast.CONST_STR: return GenTypes.SEQ_KIND_STR return 0 if k == ast.ASTKind.Name: - nm_s: rawptr[ast.Name] = rawptr[ast.Name](src) + nm_s: ast.Name* = ast.Name*(src) if nm_s.id is not None and trans is not None: - ve_s: rawptr[GenTypes.VarEntry] = self.Gen.VarGen.lookup_var_entry( + ve_s: GenTypes.VarEntry* = self.Gen.VarGen.lookup_var_entry( trans.SymTab, nm_s.id) sq_annot: str = self.Gen.VarGen.var_annot_class_name(ve_s) if sq_annot is not None: @@ -1527,50 +1527,50 @@ class StmtGenCifMixin: return GenTypes.SEQ_KIND_STR return 0 - def _build_seq_loop(self, trans: rawptr[HT.Translator], + def _build_seq_loop(self, trans: HT.Translator*, for_node: rawptr[ast.For], t1: str, t2: str, - src1: rawptr[ast.AST], - src2: rawptr[ast.AST], + src1: ast.AST*, + src2: ast.AST*, n_srcs: int) -> int: """生成序列迭代循环(enumerate: n_srcs=1 / zip: n_srcs=2) 循环变量 alloca 自动创建或复用;元素类型由源类型决定 (RANGE→i32, STR→i8, LIST→i8*)。索引内部统一 i64。 """ - pool: rawptr[memhub.MemBuddy] = trans.Pool - builder: rawptr[llvmlite.IRBuilder] = trans._cur_builder - func: rawptr[llvmlite.Function] = trans._cur_func + pool: memhub.MemBuddy* = trans.Pool + builder: llvmlite.IRBuilder* = trans._cur_builder + func: llvmlite.Function* = trans._cur_func - i32_ty: rawptr[llvmlite.LLVMType] = llvmlite.Int32(pool) - i64_ty: rawptr[llvmlite.LLVMType] = llvmlite.Int64(pool) - i8_ty: rawptr[llvmlite.LLVMType] = llvmlite.Int8(pool) - i8_ptr_ty: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, i8_ty) + i32_ty: llvmlite.LLVMType* = llvmlite.Int32(pool) + i64_ty: llvmlite.LLVMType* = llvmlite.Int64(pool) + i8_ty: llvmlite.LLVMType* = llvmlite.Int8(pool) + i8_ptr_ty: llvmlite.LLVMType* = llvmlite.Ptr(pool, i8_ty) # ---- 源 1 准备 ---- kind1: int = self._seq_kind(trans, src1) if kind1 == 0: self.Gen.TypeGenErr.fatal_error(for_node, "序列迭代: 源 1 类型不支持") - r1_start: rawptr[llvmlite.Value] = None - r1_stop: rawptr[llvmlite.Value] = None - r1_step: rawptr[llvmlite.Value] = None - s1_ptr: rawptr[llvmlite.Value] = None - l1_count: rawptr[llvmlite.Value] = None - l1_data: rawptr[llvmlite.Value] = None - l1_esize: rawptr[llvmlite.Value] = None - elem1_ty: rawptr[llvmlite.LLVMType] = i8_ptr_ty + r1_start: llvmlite.Value* = None + r1_stop: llvmlite.Value* = None + r1_step: llvmlite.Value* = None + s1_ptr: llvmlite.Value* = None + l1_count: llvmlite.Value* = None + l1_data: llvmlite.Value* = None + l1_esize: llvmlite.Value* = None + elem1_ty: llvmlite.LLVMType* = i8_ptr_ty if kind1 == GenTypes.SEQ_KIND_RANGE: elem1_ty = i32_ty r1_start = llvmlite.const_int64(pool, 0) r1_step = llvmlite.const_int64(pool, 1) r1_stop = llvmlite.const_int64(pool, 0) # 先赋中间变量再取 args(cast 链式属性访问会推断错字段偏移) - call_src1: rawptr[ast.Call] = rawptr[ast.Call](src1) + call_src1: ast.Call* = ast.Call*(src1) cargs1: list[ast.AST*]* = call_src1.args if cargs1 is not None: n1: sizet = len(cargs1) if n1 >= 1: - sv: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( + sv: llvmlite.Value* = self.Gen.ExprGen.translate_value( builder, pool, trans.Module, cargs1.get(0), trans._funcs, trans._func_count, trans) if sv is None: @@ -1578,7 +1578,7 @@ class StmtGenCifMixin: self.Gen.TypeGenErr.fatal_error(cargs1.get(0), "range 参数翻译失败", "TypeError") r1_stop = self.Gen.ExprGenBase.coerce_to_type(builder, sv, i64_ty, cargs1.get(0)) if n1 >= 2: - sv2: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( + sv2: llvmlite.Value* = self.Gen.ExprGen.translate_value( builder, pool, trans.Module, cargs1.get(1), trans._funcs, trans._func_count, trans) if sv2 is None: @@ -1586,7 +1586,7 @@ class StmtGenCifMixin: self.Gen.TypeGenErr.fatal_error(cargs1.get(1), "range 参数翻译失败", "TypeError") r1_start = self.Gen.ExprGenBase.coerce_to_type(builder, sv2, i64_ty, cargs1.get(1)) if n1 >= 3: - sv3: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( + sv3: llvmlite.Value* = self.Gen.ExprGen.translate_value( builder, pool, trans.Module, cargs1.get(2), trans._funcs, trans._func_count, trans) if sv3 is None: @@ -1602,7 +1602,7 @@ class StmtGenCifMixin: self.Gen.TypeGenErr.fatal_error(for_node, "序列迭代: 字符串源翻译失败") elif kind1 == GenTypes.SEQ_KIND_LIST: elem1_ty = i8_ptr_ty - l1_obj: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( + l1_obj: llvmlite.Value* = self.Gen.ExprGen.translate_value( builder, pool, trans.Module, src1, trans._funcs, trans._func_count, trans) if l1_obj is None or l1_obj.Ty is None \ @@ -1617,14 +1617,14 @@ class StmtGenCifMixin: # ---- 源 2 准备(zip)---- kind2: int = 0 - elem2_ty: rawptr[llvmlite.LLVMType] = elem1_ty - s2_ptr: rawptr[llvmlite.Value] = None - l2_count: rawptr[llvmlite.Value] = None - l2_data: rawptr[llvmlite.Value] = None - l2_esize: rawptr[llvmlite.Value] = None - r2_start: rawptr[llvmlite.Value] = None - r2_stop: rawptr[llvmlite.Value] = None - r2_step: rawptr[llvmlite.Value] = None + elem2_ty: llvmlite.LLVMType* = elem1_ty + s2_ptr: llvmlite.Value* = None + l2_count: llvmlite.Value* = None + l2_data: llvmlite.Value* = None + l2_esize: llvmlite.Value* = None + r2_start: llvmlite.Value* = None + r2_stop: llvmlite.Value* = None + r2_step: llvmlite.Value* = None if n_srcs >= 2: kind2 = self._seq_kind(trans, src2) if kind2 == 0: @@ -1635,12 +1635,12 @@ class StmtGenCifMixin: r2_step = llvmlite.const_int64(pool, 1) r2_stop = llvmlite.const_int64(pool, 0) # 先赋中间变量再取 args(cast 链式属性访问会推断错字段偏移) - call_src2: rawptr[ast.Call] = rawptr[ast.Call](src2) + call_src2: ast.Call* = ast.Call*(src2) cargs2: list[ast.AST*]* = call_src2.args if cargs2 is not None: n2: sizet = len(cargs2) if n2 >= 1: - svz: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( + svz: llvmlite.Value* = self.Gen.ExprGen.translate_value( builder, pool, trans.Module, cargs2.get(0), trans._funcs, trans._func_count, trans) if svz is None: @@ -1648,7 +1648,7 @@ class StmtGenCifMixin: self.Gen.TypeGenErr.fatal_error(cargs2.get(0), "range 参数翻译失败", "TypeError") r2_stop = self.Gen.ExprGenBase.coerce_to_type(builder, svz, i64_ty, cargs2.get(0)) if n2 >= 2: - svz2: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( + svz2: llvmlite.Value* = self.Gen.ExprGen.translate_value( builder, pool, trans.Module, cargs2.get(1), trans._funcs, trans._func_count, trans) if svz2 is None: @@ -1656,7 +1656,7 @@ class StmtGenCifMixin: self.Gen.TypeGenErr.fatal_error(cargs2.get(1), "range 参数翻译失败", "TypeError") r2_start = self.Gen.ExprGenBase.coerce_to_type(builder, svz2, i64_ty, cargs2.get(1)) if n2 >= 3: - svz3: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( + svz3: llvmlite.Value* = self.Gen.ExprGen.translate_value( builder, pool, trans.Module, cargs2.get(2), trans._funcs, trans._func_count, trans) if svz3 is None: @@ -1672,7 +1672,7 @@ class StmtGenCifMixin: self.Gen.TypeGenErr.fatal_error(for_node, "序列迭代: 字符串源 2 翻译失败") elif kind2 == GenTypes.SEQ_KIND_LIST: elem2_ty = i8_ptr_ty - l2_obj: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( + l2_obj: llvmlite.Value* = self.Gen.ExprGen.translate_value( builder, pool, trans.Module, src2, trans._funcs, trans._func_count, trans) if l2_obj is None or l2_obj.Ty is None \ @@ -1687,7 +1687,7 @@ class StmtGenCifMixin: # ---- 循环变量 alloca ---- # t1: enumerate → 序号 (i32);zip → 源 1 元素 - t1_alloca: rawptr[llvmlite.Value] = self.Gen.VarGen.lookup_var(trans.SymTab, t1) + t1_alloca: llvmlite.Value* = self.Gen.VarGen.lookup_var(trans.SymTab, t1) new_vars: int = 0 if t1_alloca is None: if n_srcs == 1: @@ -1698,7 +1698,7 @@ class StmtGenCifMixin: if self.Gen.VarGen.define_var(trans.SymTab, t1, t1_alloca) == 0: new_vars += 1 # t2: 源 2 元素(enumerate 时 = 源 1 元素) - t2_alloca: rawptr[llvmlite.Value] = self.Gen.VarGen.lookup_var(trans.SymTab, t2) + t2_alloca: llvmlite.Value* = self.Gen.VarGen.lookup_var(trans.SymTab, t2) if t2_alloca is None: t2_alloca = self.Gen.VarGen._alloca_at_entry(builder, elem2_ty) if t2_alloca is not None: @@ -1706,7 +1706,7 @@ class StmtGenCifMixin: new_vars += 1 # 隐式 index 变量 (i64) - idx_alloca: rawptr[llvmlite.Value] = self.Gen.VarGen._alloca_at_entry(builder, i64_ty) + idx_alloca: llvmlite.Value* = self.Gen.VarGen._alloca_at_entry(builder, i64_ty) llvmlite.build_store(builder, llvmlite.const_int64(pool, 0), idx_alloca) # 基本块: cond / body / incr / end @@ -1730,26 +1730,26 @@ class StmtGenCifMixin: # cond 块: 源 1 done 检查(zip 需源 2 也 done) llvmlite.position_at_end(builder, cond_bb) - cur_idx: rawptr[llvmlite.Value] = llvmlite.build_load(builder, i64_ty, idx_alloca) - done1: rawptr[llvmlite.Value] = None + cur_idx: llvmlite.Value* = llvmlite.build_load(builder, i64_ty, idx_alloca) + done1: llvmlite.Value* = None if kind1 == GenTypes.SEQ_KIND_RANGE: done1 = llvmlite.build_icmp(builder, llvmlite.ICMP_SLT, cur_idx, r1_stop) elif kind1 == GenTypes.SEQ_KIND_STR: - ch_ptr1: rawptr[llvmlite.Value] = llvmlite.build_gep(builder, i8_ty, s1_ptr, cur_idx) - ch1: rawptr[llvmlite.Value] = llvmlite.build_load(builder, i8_ty, ch_ptr1) - zero1: rawptr[llvmlite.Value] = llvmlite.const_int(pool, 8, 0) + ch_ptr1: llvmlite.Value* = llvmlite.build_gep(builder, i8_ty, s1_ptr, cur_idx) + ch1: llvmlite.Value* = llvmlite.build_load(builder, i8_ty, ch_ptr1) + zero1: llvmlite.Value* = llvmlite.const_int(pool, 8, 0) done1 = llvmlite.build_icmp(builder, llvmlite.ICMP_NE, ch1, zero1) elif kind1 == GenTypes.SEQ_KIND_LIST: done1 = llvmlite.build_icmp(builder, llvmlite.ICMP_SLT, cur_idx, l1_count) - cont: rawptr[llvmlite.Value] = done1 + cont: llvmlite.Value* = done1 if n_srcs >= 2: - done2: rawptr[llvmlite.Value] = None + done2: llvmlite.Value* = None if kind2 == GenTypes.SEQ_KIND_RANGE: done2 = llvmlite.build_icmp(builder, llvmlite.ICMP_SLT, cur_idx, r2_stop) elif kind2 == GenTypes.SEQ_KIND_STR: - ch_ptr2: rawptr[llvmlite.Value] = llvmlite.build_gep(builder, i8_ty, s2_ptr, cur_idx) - ch2: rawptr[llvmlite.Value] = llvmlite.build_load(builder, i8_ty, ch_ptr2) - zero2: rawptr[llvmlite.Value] = llvmlite.const_int(pool, 8, 0) + ch_ptr2: llvmlite.Value* = llvmlite.build_gep(builder, i8_ty, s2_ptr, cur_idx) + ch2: llvmlite.Value* = llvmlite.build_load(builder, i8_ty, ch_ptr2) + zero2: llvmlite.Value* = llvmlite.const_int(pool, 8, 0) done2 = llvmlite.build_icmp(builder, llvmlite.ICMP_NE, ch2, zero2) elif kind2 == GenTypes.SEQ_KIND_LIST: done2 = llvmlite.build_icmp(builder, llvmlite.ICMP_SLT, cur_idx, l2_count) @@ -1759,47 +1759,47 @@ class StmtGenCifMixin: # body 块: 获取元素 → store → 循环体 llvmlite.position_at_end(builder, body_bb) # 源 1 元素 - v1: rawptr[llvmlite.Value] = None + v1: llvmlite.Value* = None if kind1 == GenTypes.SEQ_KIND_RANGE: - step1: rawptr[llvmlite.Value] = llvmlite.build_mul(builder, cur_idx, r1_step) + step1: llvmlite.Value* = llvmlite.build_mul(builder, cur_idx, r1_step) v1 = llvmlite.build_add(builder, r1_start, step1) elif kind1 == GenTypes.SEQ_KIND_STR: - ch_ptr1b: rawptr[llvmlite.Value] = llvmlite.build_gep(builder, i8_ty, s1_ptr, cur_idx) + ch_ptr1b: llvmlite.Value* = llvmlite.build_gep(builder, i8_ty, s1_ptr, cur_idx) v1 = llvmlite.build_load(builder, i8_ty, ch_ptr1b) elif kind1 == GenTypes.SEQ_KIND_LIST: - off1: rawptr[llvmlite.Value] = llvmlite.build_mul(builder, cur_idx, l1_esize) - addr1: rawptr[llvmlite.Value] = llvmlite.build_gep(builder, i8_ty, l1_data, off1) + off1: llvmlite.Value* = llvmlite.build_mul(builder, cur_idx, l1_esize) + addr1: llvmlite.Value* = llvmlite.build_gep(builder, i8_ty, l1_data, off1) v1 = llvmlite.build_load(builder, i8_ptr_ty, addr1) # store t1 / t2 if t1_alloca is not None and t1_alloca.Ty is not None: - t1_ty: rawptr[llvmlite.LLVMType] = t1_alloca.Ty.Pointee + t1_ty: llvmlite.LLVMType* = t1_alloca.Ty.Pointee if n_srcs == 1: # enumerate: t1 = 序号(trunc i64 → i32) - idx32: rawptr[llvmlite.Value] = llvmlite.build_trunc(builder, cur_idx, i32_ty) + idx32: llvmlite.Value* = llvmlite.build_trunc(builder, cur_idx, i32_ty) llvmlite.build_store(builder, idx32, t1_alloca) if t2_alloca is not None and t2_alloca.Ty is not None and v1 is not None: - t2_ty: rawptr[llvmlite.LLVMType] = t2_alloca.Ty.Pointee - v1c: rawptr[llvmlite.Value] = self.Gen.ExprGenBase.coerce_to_type(builder, v1, t2_ty, src1) + t2_ty: llvmlite.LLVMType* = t2_alloca.Ty.Pointee + v1c: llvmlite.Value* = self.Gen.ExprGenBase.coerce_to_type(builder, v1, t2_ty, src1) llvmlite.build_store(builder, v1c, t2_alloca) else: if v1 is not None: - v1c: rawptr[llvmlite.Value] = self.Gen.ExprGenBase.coerce_to_type(builder, v1, t1_ty, src1) + v1c: llvmlite.Value* = self.Gen.ExprGenBase.coerce_to_type(builder, v1, t1_ty, src1) llvmlite.build_store(builder, v1c, t1_alloca) # 源 2 元素 → t2 - v2: rawptr[llvmlite.Value] = None + v2: llvmlite.Value* = None if kind2 == GenTypes.SEQ_KIND_RANGE: - step2: rawptr[llvmlite.Value] = llvmlite.build_mul(builder, cur_idx, r2_step) + step2: llvmlite.Value* = llvmlite.build_mul(builder, cur_idx, r2_step) v2 = llvmlite.build_add(builder, r2_start, step2) elif kind2 == GenTypes.SEQ_KIND_STR: - ch_ptr2b: rawptr[llvmlite.Value] = llvmlite.build_gep(builder, i8_ty, s2_ptr, cur_idx) + ch_ptr2b: llvmlite.Value* = llvmlite.build_gep(builder, i8_ty, s2_ptr, cur_idx) v2 = llvmlite.build_load(builder, i8_ty, ch_ptr2b) elif kind2 == GenTypes.SEQ_KIND_LIST: - off2: rawptr[llvmlite.Value] = llvmlite.build_mul(builder, cur_idx, l2_esize) - addr2: rawptr[llvmlite.Value] = llvmlite.build_gep(builder, i8_ty, l2_data, off2) + off2: llvmlite.Value* = llvmlite.build_mul(builder, cur_idx, l2_esize) + addr2: llvmlite.Value* = llvmlite.build_gep(builder, i8_ty, l2_data, off2) v2 = llvmlite.build_load(builder, i8_ptr_ty, addr2) if t2_alloca is not None and t2_alloca.Ty is not None and v2 is not None: - t2_ty2: rawptr[llvmlite.LLVMType] = t2_alloca.Ty.Pointee - v2c: rawptr[llvmlite.Value] = self.Gen.ExprGenBase.coerce_to_type(builder, v2, t2_ty2, src2) + t2_ty2: llvmlite.LLVMType* = t2_alloca.Ty.Pointee + v2c: llvmlite.Value* = self.Gen.ExprGenBase.coerce_to_type(builder, v2, t2_ty2, src2) llvmlite.build_store(builder, v2c, t2_alloca) # 保存旧循环上下文,设置 break/continue 目标 @@ -1812,7 +1812,7 @@ class StmtGenCifMixin: if body is not None: body_count: sizet = len(body) for bi in range(body_count): - stmt: rawptr[ast.AST] = body.get(bi) + stmt: ast.AST* = body.get(bi) if stmt is not None: self.Gen.StmtGen.translate_stmt(trans, stmt) @@ -1824,8 +1824,8 @@ class StmtGenCifMixin: # incr 块: index++ llvmlite.position_at_end(builder, incr_bb) - one_val: rawptr[llvmlite.Value] = llvmlite.const_int64(pool, 1) - next_idx: rawptr[llvmlite.Value] = llvmlite.build_add(builder, cur_idx, one_val) + one_val: llvmlite.Value* = llvmlite.const_int64(pool, 1) + next_idx: llvmlite.Value* = llvmlite.build_add(builder, cur_idx, one_val) llvmlite.build_store(builder, next_idx, idx_alloca) llvmlite.build_br(builder, cond_bb) @@ -1859,16 +1859,16 @@ class StmtGenCifMixin: # br label %cond # end: # ============================================================ - def _handle_ptr_iter(self, trans: rawptr[HT.Translator], + def _handle_ptr_iter(self, trans: HT.Translator*, for_node: rawptr[ast.For], var_name: str) -> int: """指针迭代: for x in ptr: 直到解引用为空""" - pool: rawptr[memhub.MemBuddy] = trans.Pool - builder: rawptr[llvmlite.IRBuilder] = trans._cur_builder - func: rawptr[llvmlite.Function] = trans._cur_func + pool: memhub.MemBuddy* = trans.Pool + builder: llvmlite.IRBuilder* = trans._cur_builder + func: llvmlite.Function* = trans._cur_func # 翻译迭代器表达式,获取指针值 - ptr_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( + ptr_val: llvmlite.Value* = self.Gen.ExprGen.translate_value( builder, pool, trans.Module, for_node.iter, trans._funcs, trans._func_count, trans) if ptr_val is None: @@ -1882,14 +1882,14 @@ class StmtGenCifMixin: self.Gen.TypeGenErr.fatal_error(for_node, "指针迭代: 迭代器不是指针类型") # 获取元素类型 - elem_ty: rawptr[llvmlite.LLVMType] = ptr_val.Ty.Pointee + elem_ty: llvmlite.LLVMType* = ptr_val.Ty.Pointee if elem_ty is None: self.Gen.TypeGenErr.fatal_error(for_node, "指针迭代: 无法获取元素类型") # 元素类型是数组(Ptr([N x T]),如 t.CArray 变量退化指针): # load 出数组值后走数组迭代(按长度,非 null 终止) if self.Gen.ExprGenBase.is_array_type(elem_ty) != 0: - arr_v2: rawptr[llvmlite.Value] = llvmlite.build_load(builder, elem_ty, ptr_val) + arr_v2: llvmlite.Value* = llvmlite.build_load(builder, elem_ty, ptr_val) if arr_v2 is not None: return self._handle_array_iter(trans, for_node, var_name, arr_v2) @@ -1901,10 +1901,10 @@ class StmtGenCifMixin: if elem_bits == 0 and elem_is_ptr2 == 0 and elem_fbits2 == 0: self.Gen.TypeGenErr.fatal_error(for_node, "指针迭代: 元素类型不是整数/指针/浮点,无法检查空终止符") - i32_ty: rawptr[llvmlite.LLVMType] = llvmlite.Int32(pool) + i32_ty: llvmlite.LLVMType* = llvmlite.Int32(pool) # 创建循环变量 alloca(存储元素值) - var_alloca: rawptr[llvmlite.Value] = self.Gen.VarGen.lookup_var( + var_alloca: llvmlite.Value* = self.Gen.VarGen.lookup_var( trans.SymTab, var_name) new_vars: int = 0 if var_alloca is None: @@ -1914,7 +1914,7 @@ class StmtGenCifMixin: new_vars = 1 # 创建隐式 index 变量,初始为 0 - idx_alloca: rawptr[llvmlite.Value] = self.Gen.VarGen._alloca_at_entry(builder, i32_ty) + idx_alloca: llvmlite.Value* = self.Gen.VarGen._alloca_at_entry(builder, i32_ty) llvmlite.build_store(builder, llvmlite.const_int32(pool, 0), idx_alloca) # 创建基本块: cond / body / incr / end @@ -1939,21 +1939,21 @@ class StmtGenCifMixin: # cond 块: load index, GEP, load elem, 空值判定(整数==0 / 指针==null / 浮点==0.0) llvmlite.position_at_end(builder, cond_bb) - cur_idx: rawptr[llvmlite.Value] = llvmlite.build_load(builder, i32_ty, idx_alloca) - elem_ptr: rawptr[llvmlite.Value] = llvmlite.build_gep( + cur_idx: llvmlite.Value* = llvmlite.build_load(builder, i32_ty, idx_alloca) + elem_ptr: llvmlite.Value* = llvmlite.build_gep( builder, elem_ty, ptr_val, cur_idx) - cur_elem: rawptr[llvmlite.Value] = llvmlite.build_load(builder, elem_ty, elem_ptr) - is_null: rawptr[llvmlite.Value] = None + cur_elem: llvmlite.Value* = llvmlite.build_load(builder, elem_ty, elem_ptr) + is_null: llvmlite.Value* = None if elem_is_ptr2 != 0: - null_p: rawptr[llvmlite.Value] = llvmlite.ConstNull(pool, elem_ty, "null") + null_p: llvmlite.Value* = llvmlite.ConstNull(pool, elem_ty, "null") if null_p is not None: is_null = llvmlite.build_icmp(builder, llvmlite.ICMP_EQ, cur_elem, null_p) elif elem_fbits2 != 0: - zero_f2: rawptr[llvmlite.Value] = llvmlite.ConstFloat(pool, elem_ty, 0.0) + zero_f2: llvmlite.Value* = llvmlite.ConstFloat(pool, elem_ty, 0.0) if zero_f2 is not None: is_null = llvmlite.build_fcmp(builder, llvmlite.FCMP_OEQ, cur_elem, zero_f2) else: - null_val: rawptr[llvmlite.Value] = llvmlite.const_int(pool, elem_bits, 0) + null_val: llvmlite.Value* = llvmlite.const_int(pool, elem_bits, 0) is_null = llvmlite.build_icmp(builder, llvmlite.ICMP_EQ, cur_elem, null_val) if is_null is None: is_null = llvmlite.const_int(pool, 1, 0) @@ -1973,7 +1973,7 @@ class StmtGenCifMixin: if body is not None: body_count: sizet = len(body) for bi in range(body_count): - stmt: rawptr[ast.AST] = body.get(bi) + stmt: ast.AST* = body.get(bi) if stmt is not None: self.Gen.StmtGen.translate_stmt(trans, stmt) @@ -1986,8 +1986,8 @@ class StmtGenCifMixin: # incr 块: index++, br cond llvmlite.position_at_end(builder, incr_bb) - one_val: rawptr[llvmlite.Value] = llvmlite.const_int32(pool, 1) - next_idx: rawptr[llvmlite.Value] = llvmlite.build_add(builder, cur_idx, one_val) + one_val: llvmlite.Value* = llvmlite.const_int32(pool, 1) + next_idx: llvmlite.Value* = llvmlite.build_add(builder, cur_idx, one_val) llvmlite.build_store(builder, next_idx, idx_alloca) llvmlite.build_br(builder, cond_bb) @@ -2023,18 +2023,18 @@ class StmtGenCifMixin: # %n = add i32 %i, 1 ; store %n ; br %cond # end: # ============================================================ - def _handle_array_iter(self, trans: rawptr[HT.Translator], + def _handle_array_iter(self, trans: HT.Translator*, for_node: rawptr[ast.For], var_name: str, - array_val: rawptr[llvmlite.Value]) -> int: + array_val: llvmlite.Value*) -> int: """数组迭代: for x in arr: 按数组长度迭代""" - pool: rawptr[memhub.MemBuddy] = trans.Pool - builder: rawptr[llvmlite.IRBuilder] = trans._cur_builder - func: rawptr[llvmlite.Function] = trans._cur_func + pool: memhub.MemBuddy* = trans.Pool + builder: llvmlite.IRBuilder* = trans._cur_builder + func: llvmlite.Function* = trans._cur_func # 解析数组类型 [N x elem_ty] - arr_ty: rawptr[llvmlite.LLVMType] = array_val.Ty - elem_ty: rawptr[llvmlite.LLVMType] = None + arr_ty: llvmlite.LLVMType* = array_val.Ty + elem_ty: llvmlite.LLVMType* = None elem_count: int = 0 match arr_ty: case llvmlite.LLVMType.Array(et, n): @@ -2046,15 +2046,15 @@ class StmtGenCifMixin: # 数组值 → 临时 alloca(数组值不是指针,需拷贝后 GEP 迭代) # 必须在 entry 块创建:非 entry alloca 会被 LLVM 当动态 alloca → 运行时 sub rsp 大数组, # 调用栈深时 rsp 骤降踩未映射页 → 概率性 #PF。 - arr_tmp: rawptr[llvmlite.Value] = self.Gen.VarGen._alloca_at_entry(builder, arr_ty) + arr_tmp: llvmlite.Value* = self.Gen.VarGen._alloca_at_entry(builder, arr_ty) if arr_tmp is None: self.Gen.TypeGenErr.fatal_error(for_node, "数组迭代: 临时存储分配失败") llvmlite.build_store(builder, array_val, arr_tmp) - i32_ty: rawptr[llvmlite.LLVMType] = llvmlite.Int32(pool) + i32_ty: llvmlite.LLVMType* = llvmlite.Int32(pool) # 循环变量 alloca(存储元素值) - var_alloca: rawptr[llvmlite.Value] = self.Gen.VarGen.lookup_var( + var_alloca: llvmlite.Value* = self.Gen.VarGen.lookup_var( trans.SymTab, var_name) new_vars: int = 0 if var_alloca is None: @@ -2064,7 +2064,7 @@ class StmtGenCifMixin: new_vars = 1 # 隐式 index 变量,初始为 0 - idx_alloca: rawptr[llvmlite.Value] = self.Gen.VarGen._alloca_at_entry(builder, i32_ty) + idx_alloca: llvmlite.Value* = self.Gen.VarGen._alloca_at_entry(builder, i32_ty) llvmlite.build_store(builder, llvmlite.const_int32(pool, 0), idx_alloca) # 基本块: cond / body / incr / end @@ -2091,9 +2091,9 @@ class StmtGenCifMixin: # cond 块: 先查越界(idx < count,越界时不能 GEP+load 判空) llvmlite.position_at_end(builder, cond_bb) - cur_idx: rawptr[llvmlite.Value] = llvmlite.build_load(builder, i32_ty, idx_alloca) - count_val: rawptr[llvmlite.Value] = llvmlite.const_int32(pool, elem_count) - in_bounds: rawptr[llvmlite.Value] = llvmlite.build_icmp( + cur_idx: llvmlite.Value* = llvmlite.build_load(builder, i32_ty, idx_alloca) + count_val: llvmlite.Value* = llvmlite.const_int32(pool, elem_count) + in_bounds: llvmlite.Value* = llvmlite.build_icmp( builder, llvmlite.ICMP_SLT, cur_idx, count_val) llvmlite.build_cond_br(builder, in_bounds, elem_check_bb, end_bb) @@ -2101,24 +2101,24 @@ class StmtGenCifMixin: # 用户语义:整数/指针/浮点元素按"解引用为空"提前终止(如 split 尾哨兵 # 的 str 数组),同时保留长度上限防越界读;聚合元素只按长度迭代。 llvmlite.position_at_end(builder, elem_check_bb) - elem_ptr: rawptr[llvmlite.Value] = llvmlite.build_gep_array( + elem_ptr: llvmlite.Value* = llvmlite.build_gep_array( builder, arr_ty, elem_ty, arr_tmp, cur_idx) - cur_elem: rawptr[llvmlite.Value] = llvmlite.build_load(builder, elem_ty, elem_ptr) + cur_elem: llvmlite.Value* = llvmlite.build_load(builder, elem_ty, elem_ptr) elem_bits_a: int = self.Gen.ExprGenBase.get_llvm_type_bits(elem_ty) elem_ptr_a: int = self.Gen.ExprGenBase.is_ptr_type(elem_ty) elem_fbits_a: int = self.Gen.ExprGenBase.get_llvm_float_bits(elem_ty) if elem_bits_a != 0 or elem_ptr_a != 0 or elem_fbits_a != 0: - is_empty_a: rawptr[llvmlite.Value] = None + is_empty_a: llvmlite.Value* = None if elem_ptr_a != 0: - null_ap: rawptr[llvmlite.Value] = llvmlite.ConstNull(pool, elem_ty, "null") + null_ap: llvmlite.Value* = llvmlite.ConstNull(pool, elem_ty, "null") if null_ap is not None: is_empty_a = llvmlite.build_icmp(builder, llvmlite.ICMP_EQ, cur_elem, null_ap) elif elem_fbits_a != 0: - zero_af: rawptr[llvmlite.Value] = llvmlite.ConstFloat(pool, elem_ty, 0.0) + zero_af: llvmlite.Value* = llvmlite.ConstFloat(pool, elem_ty, 0.0) if zero_af is not None: is_empty_a = llvmlite.build_fcmp(builder, llvmlite.FCMP_OEQ, cur_elem, zero_af) else: - zero_ai: rawptr[llvmlite.Value] = llvmlite.const_int(pool, elem_bits_a, 0) + zero_ai: llvmlite.Value* = llvmlite.const_int(pool, elem_bits_a, 0) is_empty_a = llvmlite.build_icmp(builder, llvmlite.ICMP_EQ, cur_elem, zero_ai) if is_empty_a is not None: llvmlite.build_cond_br(builder, is_empty_a, end_bb, body_bb) @@ -2140,7 +2140,7 @@ class StmtGenCifMixin: if body is not None: body_count: sizet = len(body) for bi in range(body_count): - stmt: rawptr[ast.AST] = body.get(bi) + stmt: ast.AST* = body.get(bi) if stmt is not None: self.Gen.StmtGen.translate_stmt(trans, stmt) @@ -2152,8 +2152,8 @@ class StmtGenCifMixin: # incr 块: index++ llvmlite.position_at_end(builder, incr_bb) - one_val: rawptr[llvmlite.Value] = llvmlite.const_int32(pool, 1) - next_idx: rawptr[llvmlite.Value] = llvmlite.build_add(builder, cur_idx, one_val) + one_val: llvmlite.Value* = llvmlite.const_int32(pool, 1) + next_idx: llvmlite.Value* = llvmlite.build_add(builder, cur_idx, one_val) llvmlite.build_store(builder, next_idx, idx_alloca) llvmlite.build_br(builder, cond_bb) @@ -2169,15 +2169,15 @@ class StmtGenCifMixin: # # 元素类型取第一个元素的值类型,其余元素 coerce 到该类型。 # ============================================================ - def _handle_list_literal_iter(self, trans: rawptr[HT.Translator], + def _handle_list_literal_iter(self, trans: HT.Translator*, for_node: rawptr[ast.For], var_name: str, - list_node: rawptr[ast.AST]) -> int: + list_node: ast.AST*) -> int: """列表字面量迭代: for x in [a, b, c]: 按元素顺序迭代""" - pool: rawptr[memhub.MemBuddy] = trans.Pool - builder: rawptr[llvmlite.IRBuilder] = trans._cur_builder + pool: memhub.MemBuddy* = trans.Pool + builder: llvmlite.IRBuilder* = trans._cur_builder - lst: rawptr[ast.List] = rawptr[ast.List](list_node) + lst: ast.List* = ast.List*(list_node) if lst is None or lst.elts is None: self.Gen.TypeGenErr.fatal_error(for_node, "列表字面量迭代: 空列表") elts: list[ast.AST*]* = lst.elts @@ -2186,41 +2186,77 @@ class StmtGenCifMixin: self.Gen.TypeGenErr.fatal_error(for_node, "列表字面量迭代: 空列表") # 翻译第一个元素,确定元素类型 - first_el: rawptr[ast.AST] = elts.get(0) - first_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( + first_el: ast.AST* = elts.get(0) + # 显式判空(本仓硬约定:指针判空一律 `is None`;整型字面量 0 比较不是本仓判空写法 + # ——`x == 0` 实测同样编译为 `icmp eq , null`,逐字证据见 + # AssignGenMixin.vp:1126-1145 记录的反例现场): + # 列表元素计数 > 实际填充 ⇒ 该槽为裸 0 ⇒ 上层某处产生了空 AST 元素。 + # 不给下游 translate_value 的守卫吞掉(那会静默跳过 store、产出错值),此处响亮失败。 + if first_el is None: + self.Gen.TypeGenErr.fatal_error( + for_node, + f"列表字面量迭代遇到空 AST 元素:第 0 个元素为裸空指针(0)," + f"但元素计数为 {elts_count}(元素与计数不一致);上层某处产生了空 AST 元素,已终止编译。", + "ValueError") + # 对象有效性校验(vptr 非 0,硬约定与证据见 AssignGenMixin.vp:1174-1183): + # @t.CVTable 类对象首字即 vptr,为 0 时下游任意虚调用(kind()/dump())都会 + # `load [0+slot]` ⇒ ASan READ at 0x0。读首字的唯一可用写法是 c.Deref((uint64*)(p))。 + if c.Deref((uint64*)(first_el)) == 0: + self.Gen.TypeGenErr.fatal_error( + for_node, + f"列表字面量迭代遇到【对象无效】的 AST 元素(vptr 为 0):第 0 个元素指针非 0" + f"(地址 {uint64(first_el)})但其对象首字(vtable 指针)为 0,元素计数 {elts_count};" + f"上层某处产生了「未初始化 vptr 的 AST 节点」(典型源:深拷贝只搬字段未搬 vptr),已终止编译。", + "ValueError") + first_val: llvmlite.Value* = self.Gen.ExprGen.translate_value( builder, pool, trans.Module, first_el, trans._funcs, trans._func_count, trans) if first_val is None or first_val.Ty is None: self.Gen.TypeGenErr.fatal_error(first_el, "列表字面量迭代: 无法确定元素类型") - elem_ty: rawptr[llvmlite.LLVMType] = first_val.Ty + elem_ty: llvmlite.LLVMType* = first_val.Ty # 构建 [N x elem_ty] 数组值:临时 alloca 逐元素写入后 load # 同样必须在 entry 块创建,避免非 entry alloca 被降为动态 alloca(见 _handle_array_iter) - arr_ty: rawptr[llvmlite.LLVMType] = llvmlite.Array(pool, elem_ty, elts_count) - tmp_alloca: rawptr[llvmlite.Value] = self.Gen.VarGen._alloca_at_entry(builder, arr_ty) + arr_ty: llvmlite.LLVMType* = llvmlite.Array(pool, elem_ty, elts_count) + tmp_alloca: llvmlite.Value* = self.Gen.VarGen._alloca_at_entry(builder, arr_ty) if tmp_alloca is None: self.Gen.TypeGenErr.fatal_error(for_node, "列表字面量迭代: 临时数组分配失败") - first_ptr: rawptr[llvmlite.Value] = llvmlite.build_gep_array( + first_ptr: llvmlite.Value* = llvmlite.build_gep_array( builder, arr_ty, elem_ty, tmp_alloca, llvmlite.const_int32(pool, 0)) if first_ptr is not None: llvmlite.build_store(builder, first_val, first_ptr) # 写其余元素(coerce 到 elem_ty) i: sizet = 1 while i < elts_count: - el_node: rawptr[ast.AST] = elts.get(i) - el_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( + el_node: ast.AST* = elts.get(i) + # 显式判空(同上,用 `is None`):不得让空元素被 translate_value 的 None 守卫静默吞掉。 + if el_node is None: + self.Gen.TypeGenErr.fatal_error( + for_node, + f"列表字面量迭代遇到空 AST 元素:第 {i} 个元素为裸空指针(0)," + f"但元素计数为 {elts_count}(元素与计数不一致);上层某处产生了空 AST 元素,已终止编译。", + "ValueError") + # 对象有效性校验(vptr 非 0),同第 0 元素处:同族"取元素后即用"路径。 + if c.Deref((uint64*)(el_node)) == 0: + self.Gen.TypeGenErr.fatal_error( + for_node, + f"列表字面量迭代遇到【对象无效】的 AST 元素(vptr 为 0):第 {i} 个元素指针非 0" + f"(地址 {uint64(el_node)})但其对象首字(vtable 指针)为 0,元素计数 {elts_count};" + f"上层某处产生了「未初始化 vptr 的 AST 节点」(典型源:深拷贝只搬字段未搬 vptr),已终止编译。", + "ValueError") + el_val: llvmlite.Value* = self.Gen.ExprGen.translate_value( builder, pool, trans.Module, el_node, trans._funcs, trans._func_count, trans) if el_val is not None: el_val = self.Gen.ExprGenBase.coerce_to_type(builder, el_val, elem_ty, el_node) - el_ptr: rawptr[llvmlite.Value] = llvmlite.build_gep_array( + el_ptr: llvmlite.Value* = llvmlite.build_gep_array( builder, arr_ty, elem_ty, tmp_alloca, llvmlite.const_int32(pool, i)) if el_ptr is not None: llvmlite.build_store(builder, el_val, el_ptr) i += 1 # load 回数组值,复用数组迭代 - arr_val: rawptr[llvmlite.Value] = llvmlite.build_load(builder, arr_ty, tmp_alloca) + arr_val: llvmlite.Value* = llvmlite.build_load(builder, arr_ty, tmp_alloca) if arr_val is None: self.Gen.TypeGenErr.fatal_error(for_node, "列表字面量迭代: 数组加载失败") return self._handle_array_iter(trans, for_node, var_name, arr_val) @@ -2254,28 +2290,28 @@ class StmtGenCifMixin: # %n = add i64 %i, 1 ; store ; br %cond # end: # ============================================================ - def _handle_list_iter(self, trans: rawptr[HT.Translator], + def _handle_list_iter(self, trans: HT.Translator*, for_node: rawptr[ast.For], var_name: str, - list_val: rawptr[llvmlite.Value]) -> int: + list_val: llvmlite.Value*) -> int: """list[T] 容器迭代: for v in lst: 按 __count__ 动态长度迭代""" - pool: rawptr[memhub.MemBuddy] = trans.Pool - builder: rawptr[llvmlite.IRBuilder] = trans._cur_builder - func: rawptr[llvmlite.Function] = trans._cur_func + pool: memhub.MemBuddy* = trans.Pool + builder: llvmlite.IRBuilder* = trans._cur_builder + func: llvmlite.Function* = trans._cur_func - i64_ty: rawptr[llvmlite.LLVMType] = llvmlite.Int64(pool) - i8_ty: rawptr[llvmlite.LLVMType] = llvmlite.Int8(pool) - i8_ptr_ty: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, i8_ty) + i64_ty: llvmlite.LLVMType* = llvmlite.Int64(pool) + i8_ty: llvmlite.LLVMType* = llvmlite.Int8(pool) + i8_ptr_ty: llvmlite.LLVMType* = llvmlite.Ptr(pool, i8_ty) # 读取 __count__ (偏移 8, GEP index 1) - cnt_ptr: rawptr[llvmlite.Value] = llvmlite.build_gep( + cnt_ptr: llvmlite.Value* = llvmlite.build_gep( builder, i64_ty, list_val, llvmlite.const_int64(pool, 1)) if cnt_ptr is None: self.Gen.TypeGenErr.fatal_error(for_node, "list 迭代: 无法定位 __count__") - count_val: rawptr[llvmlite.Value] = llvmlite.build_load(builder, i64_ty, cnt_ptr) + count_val: llvmlite.Value* = llvmlite.build_load(builder, i64_ty, cnt_ptr) # 循环变量 alloca(元素类型 i8*,与 list.get 内联一致) - var_alloca: rawptr[llvmlite.Value] = self.Gen.VarGen.lookup_var( + var_alloca: llvmlite.Value* = self.Gen.VarGen.lookup_var( trans.SymTab, var_name) new_vars: int = 0 if var_alloca is None: @@ -2285,7 +2321,7 @@ class StmtGenCifMixin: new_vars = 1 # 隐式 index 变量 (i64,与 __count__ 类型对齐) - idx_alloca: rawptr[llvmlite.Value] = self.Gen.VarGen._alloca_at_entry(builder, i64_ty) + idx_alloca: llvmlite.Value* = self.Gen.VarGen._alloca_at_entry(builder, i64_ty) llvmlite.build_store(builder, llvmlite.const_int64(pool, 0), idx_alloca) # 基本块: cond / body / incr / end @@ -2309,23 +2345,23 @@ class StmtGenCifMixin: # cond 块: load index, icmp slt idx, count llvmlite.position_at_end(builder, cond_bb) - cur_idx: rawptr[llvmlite.Value] = llvmlite.build_load(builder, i64_ty, idx_alloca) - in_bounds: rawptr[llvmlite.Value] = llvmlite.build_icmp( + cur_idx: llvmlite.Value* = llvmlite.build_load(builder, i64_ty, idx_alloca) + in_bounds: llvmlite.Value* = llvmlite.build_icmp( builder, llvmlite.ICMP_SLT, cur_idx, count_val) llvmlite.build_cond_br(builder, in_bounds, body_bb, end_bb) # body 块: __data__ + idx*__elem_size__ → load 元素 → store to var llvmlite.position_at_end(builder, body_bb) - dpp: rawptr[llvmlite.Value] = llvmlite.build_gep( + dpp: llvmlite.Value* = llvmlite.build_gep( builder, i64_ty, list_val, llvmlite.const_int64(pool, 0)) - data_ptr: rawptr[llvmlite.Value] = llvmlite.build_load(builder, i8_ptr_ty, dpp) - epp: rawptr[llvmlite.Value] = llvmlite.build_gep( + data_ptr: llvmlite.Value* = llvmlite.build_load(builder, i8_ptr_ty, dpp) + epp: llvmlite.Value* = llvmlite.build_gep( builder, i64_ty, list_val, llvmlite.const_int64(pool, 4)) - esize: rawptr[llvmlite.Value] = llvmlite.build_load(builder, i64_ty, epp) - offset: rawptr[llvmlite.Value] = llvmlite.build_mul(builder, cur_idx, esize) - elem_addr: rawptr[llvmlite.Value] = llvmlite.build_gep( + esize: llvmlite.Value* = llvmlite.build_load(builder, i64_ty, epp) + offset: llvmlite.Value* = llvmlite.build_mul(builder, cur_idx, esize) + elem_addr: llvmlite.Value* = llvmlite.build_gep( builder, i8_ty, data_ptr, offset) - cur_elem: rawptr[llvmlite.Value] = llvmlite.build_load(builder, i8_ptr_ty, elem_addr) + cur_elem: llvmlite.Value* = llvmlite.build_load(builder, i8_ptr_ty, elem_addr) llvmlite.build_store(builder, cur_elem, var_alloca) # 保存旧循环上下文,设置 break/continue 目标 @@ -2338,7 +2374,7 @@ class StmtGenCifMixin: if body is not None: body_count: sizet = len(body) for bi in range(body_count): - stmt: rawptr[ast.AST] = body.get(bi) + stmt: ast.AST* = body.get(bi) if stmt is not None: self.Gen.StmtGen.translate_stmt(trans, stmt) @@ -2350,8 +2386,8 @@ class StmtGenCifMixin: # incr 块: index++ llvmlite.position_at_end(builder, incr_bb) - one_val: rawptr[llvmlite.Value] = llvmlite.const_int64(pool, 1) - next_idx: rawptr[llvmlite.Value] = llvmlite.build_add(builder, cur_idx, one_val) + one_val: llvmlite.Value* = llvmlite.const_int64(pool, 1) + next_idx: llvmlite.Value* = llvmlite.build_add(builder, cur_idx, one_val) llvmlite.build_store(builder, next_idx, idx_alloca) llvmlite.build_br(builder, cond_bb) @@ -2361,10 +2397,10 @@ class StmtGenCifMixin: trans._ctrl_merge_reachable = 1 return new_vars - def _handle_dict_iter(self, trans: rawptr[HT.Translator], + def _handle_dict_iter(self, trans: HT.Translator*, for_node: rawptr[ast.For], var_name: str, - dict_val: rawptr[llvmlite.Value]) -> int: + dict_val: llvmlite.Value*) -> int: """dict 容器迭代: for key in d: 按 __count__/__keys__ 布局迭代 _dict.vp 布局(8 字节槽):__keys__@0, __values__@1, __count__@2, @@ -2372,23 +2408,23 @@ class StmtGenCifMixin: __iter__ 协议(__iter__ 重置 iter_index + __next__ 取 key)内联为 循环:iter_idx < __count__ → key = __keys__[iter_idx]。 """ - pool: rawptr[memhub.MemBuddy] = trans.Pool - builder: rawptr[llvmlite.IRBuilder] = trans._cur_builder - func: rawptr[llvmlite.Function] = trans._cur_func + pool: memhub.MemBuddy* = trans.Pool + builder: llvmlite.IRBuilder* = trans._cur_builder + func: llvmlite.Function* = trans._cur_func - i64_ty: rawptr[llvmlite.LLVMType] = llvmlite.Int64(pool) - i8_ty: rawptr[llvmlite.LLVMType] = llvmlite.Int8(pool) - i8_ptr_ty: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, i8_ty) + i64_ty: llvmlite.LLVMType* = llvmlite.Int64(pool) + i8_ty: llvmlite.LLVMType* = llvmlite.Int8(pool) + i8_ptr_ty: llvmlite.LLVMType* = llvmlite.Ptr(pool, i8_ty) # 读取 __count__(槽 2,字节偏移 16) - cnt_ptr: rawptr[llvmlite.Value] = llvmlite.build_gep( + cnt_ptr: llvmlite.Value* = llvmlite.build_gep( builder, i64_ty, dict_val, llvmlite.const_int64(pool, 2)) if cnt_ptr is None: self.Gen.TypeGenErr.fatal_error(for_node, "dict 迭代: 无法定位 __count__") - count_val: rawptr[llvmlite.Value] = llvmlite.build_load(builder, i64_ty, cnt_ptr) + count_val: llvmlite.Value* = llvmlite.build_load(builder, i64_ty, cnt_ptr) # 循环变量 alloca(元素类型 i8*,与 dict.__next__ 返回 str 一致) - var_alloca: rawptr[llvmlite.Value] = self.Gen.VarGen.lookup_var( + var_alloca: llvmlite.Value* = self.Gen.VarGen.lookup_var( trans.SymTab, var_name) new_vars: int = 0 if var_alloca is None: @@ -2398,7 +2434,7 @@ class StmtGenCifMixin: new_vars = 1 # 隐式 index 变量 (i64,与 __count__ 类型对齐) - idx_alloca: rawptr[llvmlite.Value] = self.Gen.VarGen._alloca_at_entry(builder, i64_ty) + idx_alloca: llvmlite.Value* = self.Gen.VarGen._alloca_at_entry(builder, i64_ty) llvmlite.build_store(builder, llvmlite.const_int64(pool, 0), idx_alloca) # 基本块: cond / body / incr / end @@ -2422,21 +2458,21 @@ class StmtGenCifMixin: # cond 块: load index, icmp slt idx, count llvmlite.position_at_end(builder, cond_bb) - cur_idx: rawptr[llvmlite.Value] = llvmlite.build_load(builder, i64_ty, idx_alloca) - in_bounds: rawptr[llvmlite.Value] = llvmlite.build_icmp( + cur_idx: llvmlite.Value* = llvmlite.build_load(builder, i64_ty, idx_alloca) + in_bounds: llvmlite.Value* = llvmlite.build_icmp( builder, llvmlite.ICMP_SLT, cur_idx, count_val) llvmlite.build_cond_br(builder, in_bounds, body_bb, end_bb) # body 块: __keys__ + idx*8 → load key (i8*) → store to var llvmlite.position_at_end(builder, body_bb) - kpp: rawptr[llvmlite.Value] = llvmlite.build_gep( + kpp: llvmlite.Value* = llvmlite.build_gep( builder, i64_ty, dict_val, llvmlite.const_int64(pool, 0)) - keys_ptr: rawptr[llvmlite.Value] = llvmlite.build_load(builder, i8_ptr_ty, kpp) - eight_val: rawptr[llvmlite.Value] = llvmlite.const_int64(pool, 8) - key_offset: rawptr[llvmlite.Value] = llvmlite.build_mul(builder, cur_idx, eight_val) - key_addr: rawptr[llvmlite.Value] = llvmlite.build_gep( + keys_ptr: llvmlite.Value* = llvmlite.build_load(builder, i8_ptr_ty, kpp) + eight_val: llvmlite.Value* = llvmlite.const_int64(pool, 8) + key_offset: llvmlite.Value* = llvmlite.build_mul(builder, cur_idx, eight_val) + key_addr: llvmlite.Value* = llvmlite.build_gep( builder, i8_ty, keys_ptr, key_offset) - cur_key: rawptr[llvmlite.Value] = llvmlite.build_load(builder, i8_ptr_ty, key_addr) + cur_key: llvmlite.Value* = llvmlite.build_load(builder, i8_ptr_ty, key_addr) llvmlite.build_store(builder, cur_key, var_alloca) # 保存旧循环上下文,设置 break/continue 目标 @@ -2449,7 +2485,7 @@ class StmtGenCifMixin: if body is not None: body_count: sizet = len(body) for bi in range(body_count): - stmt: rawptr[ast.AST] = body.get(bi) + stmt: ast.AST* = body.get(bi) if stmt is not None: self.Gen.StmtGen.translate_stmt(trans, stmt) @@ -2461,8 +2497,8 @@ class StmtGenCifMixin: # incr 块: index++ llvmlite.position_at_end(builder, incr_bb) - one_val: rawptr[llvmlite.Value] = llvmlite.const_int64(pool, 1) - next_idx: rawptr[llvmlite.Value] = llvmlite.build_add(builder, cur_idx, one_val) + one_val: llvmlite.Value* = llvmlite.const_int64(pool, 1) + next_idx: llvmlite.Value* = llvmlite.build_add(builder, cur_idx, one_val) llvmlite.build_store(builder, next_idx, idx_alloca) llvmlite.build_br(builder, cond_bb) @@ -2498,16 +2534,16 @@ class StmtGenCifMixin: # _translate_method 注入,raise StopIteration 时置 1(translate_raise); # VpiReader stub 声明同步该参数(_inject_method_declare)。 # ============================================================ - def _handle_oop_iter(self, trans: rawptr[HT.Translator], + def _handle_oop_iter(self, trans: HT.Translator*, for_node: rawptr[ast.For], var_name: str, class_name: str, - obj_val: rawptr[llvmlite.Value]) -> int: + obj_val: llvmlite.Value*) -> int: """OOP iter 协议: for x in obj: 调用 __iter__/__next__ 迭代""" - pool: rawptr[memhub.MemBuddy] = trans.Pool - builder: rawptr[llvmlite.IRBuilder] = trans._cur_builder - func: rawptr[llvmlite.Function] = trans._cur_func - mod: rawptr[llvmlite.LLVMModule] = trans.Module + pool: memhub.MemBuddy* = trans.Pool + builder: llvmlite.IRBuilder* = trans._cur_builder + func: llvmlite.Function* = trans._cur_func + mod: llvmlite.LLVMModule* = trans.Module if builder is None or func is None or mod is None: return 0 @@ -2521,26 +2557,26 @@ class StmtGenCifMixin: if iter_lookup is None: return 0 viperlib.snprintf(iter_lookup, 128, "%s.__iter__", class_name) - iter_fn: rawptr[llvmlite.Function] = self.Gen.CallGenBase.find_func_in_module( + iter_fn: llvmlite.Function* = self.Gen.CallGenBase.find_func_in_module( mod, iter_lookup) if iter_fn is None: self.Gen.TypeGenErr.fatal_error( for_node, f"OOP 迭代: 类 '{class_name}' 没有 __iter__ 方法") - iter_ret_ty: rawptr[llvmlite.LLVMType] = llvmlite.function_get_ret_ty(iter_fn) + iter_ret_ty: llvmlite.LLVMType* = llvmlite.function_get_ret_ty(iter_fn) iter_fn_name: str = llvmlite.function_get_name(iter_fn) if iter_ret_ty is None or iter_fn_name is None: return 0 # self 参数按 __iter__ 首参类型对齐(stub 声明 self 可能是 i8*) - iter_self: rawptr[llvmlite.Value] = obj_val - iter_first: rawptr[llvmlite.Param] = llvmlite.function_get_param_head(iter_fn) + iter_self: llvmlite.Value* = obj_val + iter_first: llvmlite.Param* = llvmlite.function_get_param_head(iter_fn) if iter_first is not None: - iter_self_ty: rawptr[llvmlite.LLVMType] = llvmlite.param_get_ty(iter_first) + iter_self_ty: llvmlite.LLVMType* = llvmlite.param_get_ty(iter_first) if iter_self_ty is not None: iter_self = llvmlite.build_bitcast(builder, obj_val, iter_self_ty) if iter_self is None: return 0 iter_self.Next = None - iter_result: rawptr[llvmlite.Value] = llvmlite.build_call( + iter_result: llvmlite.Value* = llvmlite.build_call( builder, iter_fn_name, iter_self, 1, iter_ret_ty, 0) if iter_result is None: return 0 @@ -2550,18 +2586,18 @@ class StmtGenCifMixin: if next_lookup is None: return 0 viperlib.snprintf(next_lookup, 128, "%s.__next__", class_name) - next_fn: rawptr[llvmlite.Function] = self.Gen.CallGenBase.find_func_in_module( + next_fn: llvmlite.Function* = self.Gen.CallGenBase.find_func_in_module( mod, next_lookup) if next_fn is None: self.Gen.TypeGenErr.fatal_error( for_node, f"OOP 迭代: 类 '{class_name}' 没有 __next__ 方法") - next_ret_ty: rawptr[llvmlite.LLVMType] = llvmlite.function_get_ret_ty(next_fn) + next_ret_ty: llvmlite.LLVMType* = llvmlite.function_get_ret_ty(next_fn) next_fn_name: str = llvmlite.function_get_name(next_fn) if next_ret_ty is None or next_fn_name is None: return 0 # 3. 循环变量 alloca(元素类型 = __next__ 返回类型) - var_alloca: rawptr[llvmlite.Value] = self.Gen.VarGen.lookup_var( + var_alloca: llvmlite.Value* = self.Gen.VarGen.lookup_var( trans.SymTab, var_name) new_vars: int = 0 if var_alloca is None: @@ -2572,11 +2608,11 @@ class StmtGenCifMixin: new_vars = 1 # 4. stop flag alloca(i1,初始 0) - i1_ty: rawptr[llvmlite.LLVMType] = llvmlite.Int1(pool) - flag_alloca: rawptr[llvmlite.Value] = llvmlite.build_alloca(builder, i1_ty) + i1_ty: llvmlite.LLVMType* = llvmlite.Int1(pool) + flag_alloca: llvmlite.Value* = llvmlite.build_alloca(builder, i1_ty) if flag_alloca is None: return 0 - flag_zero: rawptr[llvmlite.Value] = llvmlite.ConstInt(pool, i1_ty, 0, "0") + flag_zero: llvmlite.Value* = llvmlite.ConstInt(pool, i1_ty, 0, "0") if flag_zero is not None: llvmlite.build_store(builder, flag_zero, flag_alloca) @@ -2602,10 +2638,10 @@ class StmtGenCifMixin: if flag_zero is not None: llvmlite.build_store(builder, flag_zero, flag_alloca) # __next__ 参数 1:迭代器(按首参类型 bitcast) - next_self: rawptr[llvmlite.Value] = iter_result - next_first: rawptr[llvmlite.Param] = llvmlite.function_get_param_head(next_fn) + next_self: llvmlite.Value* = iter_result + next_first: llvmlite.Param* = llvmlite.function_get_param_head(next_fn) if next_first is not None: - next_self_ty: rawptr[llvmlite.LLVMType] = llvmlite.param_get_ty(next_first) + next_self_ty: llvmlite.LLVMType* = llvmlite.param_get_ty(next_first) if next_self_ty is not None and iter_result.Ty is not None: next_self = llvmlite.build_bitcast(builder, iter_result, next_self_ty) if next_self is None: @@ -2613,15 +2649,15 @@ class StmtGenCifMixin: # 参数链表: arg1(iter).Next = arg2(flag);flag 独立 null 结尾防自链接 next_self.Next = flag_alloca flag_alloca.Next = None - next_val: rawptr[llvmlite.Value] = llvmlite.build_call( + next_val: llvmlite.Value* = llvmlite.build_call( builder, next_fn_name, next_self, 2, next_ret_ty, 0) if next_val is None: return 0 - stop_val: rawptr[llvmlite.Value] = llvmlite.build_load(builder, i1_ty, flag_alloca) + stop_val: llvmlite.Value* = llvmlite.build_load(builder, i1_ty, flag_alloca) if stop_val is None: return 0 - flag_zero2: rawptr[llvmlite.Value] = llvmlite.ConstInt(pool, i1_ty, 0, "0") - continue_i1: rawptr[llvmlite.Value] = None + flag_zero2: llvmlite.Value* = llvmlite.ConstInt(pool, i1_ty, 0, "0") + continue_i1: llvmlite.Value* = None if flag_zero2 is not None: continue_i1 = llvmlite.build_icmp( builder, llvmlite.ICMP_EQ, stop_val, flag_zero2) @@ -2641,7 +2677,7 @@ class StmtGenCifMixin: if body is not None: body_count: sizet = len(body) for bi in range(body_count): - stmt: rawptr[ast.AST] = body.get(bi) + stmt: ast.AST* = body.get(bi) if stmt is not None: self.Gen.StmtGen.translate_stmt(trans, stmt) trans._break_bb = old_break @@ -2657,10 +2693,10 @@ class StmtGenCifMixin: trans._ctrl_merge_reachable = 1 return new_vars - def _handle_enumerate_iter(self, trans: rawptr[HT.Translator], + def _handle_enumerate_iter(self, trans: HT.Translator*, for_node: rawptr[ast.For], t1: str, t2: str, - call: rawptr[ast.Call]) -> int: + call: ast.Call*) -> int: """enumerate 迭代: for i, v in enumerate(x)""" if call is None or call.args is None: return 0 @@ -2669,10 +2705,10 @@ class StmtGenCifMixin: self.Gen.TypeGenErr.fatal_error(for_node, "enumerate 需要至少一个参数") return self._build_seq_loop(trans, for_node, t1, t2, cargs.get(0), None, 1) - def _handle_zip_iter(self, trans: rawptr[HT.Translator], + def _handle_zip_iter(self, trans: HT.Translator*, for_node: rawptr[ast.For], t1: str, t2: str, - call: rawptr[ast.Call]) -> int: + call: ast.Call*) -> int: """zip 迭代: for a, b in zip(x, y)""" if call is None or call.args is None: # fail-fast: zip 参数缺失 diff --git a/App/lib/core/Gen/Stmt/StmtGenDeclMixin.vp b/App/lib/core/Gen/Stmt/StmtGenDeclMixin.vp index fddd96c..9b3517b 100644 --- a/App/lib/core/Gen/Stmt/StmtGenDeclMixin.vp +++ b/App/lib/core/Gen/Stmt/StmtGenDeclMixin.vp @@ -40,8 +40,8 @@ ENUM_MEMBER_MAX: t.CDefine = 128 class StmtGenDeclMixin(StmtGenCifMixin.StmtGenCifMixin): """声明/枚举/nonlocal 访问(StmtGen 拆分 2/3,继承 Cif)""" - def translate_global(self, trans: rawptr[HT.Translator], - node: rawptr[ast.AST]) -> int: + def translate_global(self, trans: HT.Translator*, + node: ast.AST*) -> int: """翻译 global 语句:记录 global 变量名""" gn: rawptr[ast.Global] = rawptr[ast.Global](node) if gn is None: @@ -51,15 +51,15 @@ class StmtGenDeclMixin(StmtGenCifMixin.StmtGenCifMixin): return 0 n: sizet = len(names) for i in range(n): - nm_node: rawptr[ast.AST] = names.get(i) + nm_node: ast.AST* = names.get(i) if nm_node is not None and nm_node.kind() == ast.ASTKind.Name: - nm: rawptr[ast.Name] = rawptr[ast.Name](nm_node) + nm: ast.Name* = ast.Name*(nm_node) if nm.id is not None: GenApi.add_global_name(trans, nm.id) return 0 - def translate_nonlocal(self, trans: rawptr[HT.Translator], - node: rawptr[ast.AST]) -> int: + def translate_nonlocal(self, trans: HT.Translator*, + node: ast.AST*) -> int: """翻译 nonlocal 语句:记录 nonlocal 变量名及其类型 类型信息通过查找父作用域的 alloca 获取(用于 env 指针数组方案的类型恢复)。 @@ -72,13 +72,13 @@ class StmtGenDeclMixin(StmtGenCifMixin.StmtGenCifMixin): return 0 n: sizet = len(names) for i in range(n): - nm_node: rawptr[ast.AST] = names.get(i) + nm_node: ast.AST* = names.get(i) if nm_node is not None and nm_node.kind() == ast.ASTKind.Name: - nm: rawptr[ast.Name] = rawptr[ast.Name](nm_node) + nm: ast.Name* = ast.Name*(nm_node) if nm.id is not None: # 查找父作用域中的变量 alloca,获取类型信息 - var_ty: rawptr[llvmlite.LLVMType] = None - var_alloca: rawptr[llvmlite.Value] = self.Gen.VarGen.lookup_var( + var_ty: llvmlite.LLVMType* = None + var_alloca: 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 @@ -94,13 +94,13 @@ class StmtGenDeclMixin(StmtGenCifMixin.StmtGenCifMixin): GenApi.add_nonlocal_name(trans, nm.id, var_ty) return 0 - def translate_expr_stmt(self, trans: rawptr[HT.Translator], - node: rawptr[ast.AST]) -> int: + def translate_expr_stmt(self, trans: HT.Translator*, + node: ast.AST*) -> int: """翻译表达式语句(printf 调用等)""" ex: rawptr[ast.Expr] = rawptr[ast.Expr](node) if ex is None: return 0 - call_node: rawptr[ast.AST] = ex.value + call_node: ast.AST* = ex.value if call_node is None: return 0 ck: int = call_node.kind() @@ -115,8 +115,8 @@ class StmtGenDeclMixin(StmtGenCifMixin.StmtGenCifMixin): self.Gen.VarGen.repl_expr_result(trans, call_node) return 0 - cl: rawptr[ast.Call] = rawptr[ast.Call](call_node) - func_node: rawptr[ast.AST] = cl.func + cl: ast.Call* = ast.Call*(call_node) + func_node: ast.AST* = cl.func if func_node is None: return 0 @@ -147,11 +147,11 @@ class StmtGenDeclMixin(StmtGenCifMixin.StmtGenCifMixin): sfn_ent: rawptr[GenTypes.ReplFuncEntry] = \ self.Gen.VarGen.repl_find_func_entry(trans.ReplCtx, func_name) if sfn_ent is not None and sfn_ent.RetTag != GenTypes.REPL_TY_VOID: - sfn_v: rawptr[llvmlite.Value] = self.Gen.CallGen.translate_call( + sfn_v: llvmlite.Value* = self.Gen.CallGen.translate_call( trans.Pool, trans._cur_builder, trans.Module, call_node, trans._funcs, trans._func_count, trans) if sfn_v is not None: - ctx_v: rawptr[llvmlite.Value] = self.Gen.VarGen.repl_ctx_ptr( + ctx_v: llvmlite.Value* = self.Gen.VarGen.repl_ctx_ptr( trans, trans.ReplCtx, call_node) if ctx_v is not None: self.Gen.VarGen.repl_emit_result( @@ -163,8 +163,8 @@ class StmtGenDeclMixin(StmtGenCifMixin.StmtGenCifMixin): trans._funcs, trans._func_count, trans) return 0 - def pre_scan_allocas(self, trans: rawptr[HT.Translator], - node: rawptr[ast.AST]) -> int: + def pre_scan_allocas(self, trans: HT.Translator*, + node: ast.AST*) -> int: """预扫描语句中的 AnnAssign,提前创建 alloca 递归分支/循环/异常体:if/else/for/while/try 分支内的 AnnAssign 局部 @@ -214,7 +214,7 @@ class StmtGenDeclMixin(StmtGenCifMixin.StmtGenCifMixin): self.pre_scan_allocas(trans, wh_n.orelse.get(bi_pre_we)) return 0 if k == ast.ASTKind.Try: - tr_n: rawptr[ast.Try] = rawptr[ast.Try](node) + tr_n: ast.Try* = ast.Try*(node) if tr_n.children is not None: bn_pre_t: sizet = len(tr_n.children) for bi_pre_t in range(bn_pre_t): @@ -222,9 +222,9 @@ class StmtGenDeclMixin(StmtGenCifMixin.StmtGenCifMixin): if tr_n.handlers is not None: bn_pre_th: sizet = len(tr_n.handlers) for bi_pre_th in range(bn_pre_th): - eh_pre: rawptr[ast.AST] = tr_n.handlers.get(bi_pre_th) + eh_pre: ast.AST* = tr_n.handlers.get(bi_pre_th) if eh_pre is not None and eh_pre.kind() == ast.ASTKind.ExceptHandler: - ehc_pre: rawptr[ast.ExceptHandler] = rawptr[ast.ExceptHandler](eh_pre) + ehc_pre: ast.ExceptHandler* = ast.ExceptHandler*(eh_pre) if ehc_pre.children is not None: bn_pre_ehb: sizet = len(ehc_pre.children) for bi_pre_ehb in range(bn_pre_ehb): @@ -239,18 +239,18 @@ class StmtGenDeclMixin(StmtGenCifMixin.StmtGenCifMixin): self.pre_scan_allocas(trans, tr_n.finalbody.get(bi_pre_tf)) return 0 if k == ast.ASTKind.With: - wth: rawptr[ast.With] = rawptr[ast.With](node) + wth: ast.With* = ast.With*(node) if wth.children is not None: bn_pre_wb: sizet = len(wth.children) for bi_pre_wb in range(bn_pre_wb): self.pre_scan_allocas(trans, wth.children.get(bi_pre_wb)) return 0 if k == ast.ASTKind.Match: - mt_n: rawptr[ast.Match] = rawptr[ast.Match](node) + mt_n: ast.Match* = ast.Match*(node) if mt_n.cases is not None: bn_pre_mc: sizet = len(mt_n.cases) for bi_pre_mc in range(bn_pre_mc): - mc_pre: rawptr[ast.AST] = mt_n.cases.get(bi_pre_mc) + mc_pre: ast.AST* = mt_n.cases.get(bi_pre_mc) if mc_pre is not None and mc_pre.kind() == ast.ASTKind.MatchCase: mcc_pre: rawptr[ast.MatchCase] = rawptr[ast.MatchCase](mc_pre) if mcc_pre.children is not None: @@ -260,8 +260,8 @@ class StmtGenDeclMixin(StmtGenCifMixin.StmtGenCifMixin): return 0 return 0 - def pre_scan_scope_decls(self, trans: rawptr[HT.Translator], - node: rawptr[ast.AST]) -> int: + def pre_scan_scope_decls(self, trans: HT.Translator*, + node: ast.AST*) -> int: """预扫描 Global/Nonlocal 声明,提前注册作用域名称""" if node is None: return 0 @@ -272,11 +272,11 @@ class StmtGenDeclMixin(StmtGenCifMixin.StmtGenCifMixin): return self.translate_nonlocal(trans, node) return 0 - def translate_break(self, trans: rawptr[HT.Translator]) -> int: + def translate_break(self, trans: HT.Translator*) -> int: """翻译 break 语句:跳转到循环 end 块""" - builder: rawptr[llvmlite.IRBuilder] = trans._cur_builder - func: rawptr[llvmlite.Function] = trans._cur_func - pool: rawptr[memhub.MemBuddy] = trans.Pool + builder: llvmlite.IRBuilder* = trans._cur_builder + func: llvmlite.Function* = trans._cur_func + pool: memhub.MemBuddy* = trans.Pool if builder is None or func is None: return 0 @@ -295,11 +295,11 @@ class StmtGenDeclMixin(StmtGenCifMixin.StmtGenCifMixin): llvmlite.position_at_end(builder, dead_bb) return 0 - def translate_continue(self, trans: rawptr[HT.Translator]) -> int: + def translate_continue(self, trans: HT.Translator*) -> int: """翻译 continue 语句:跳转到循环 cond/incr 块""" - builder: rawptr[llvmlite.IRBuilder] = trans._cur_builder - func: rawptr[llvmlite.Function] = trans._cur_func - pool: rawptr[memhub.MemBuddy] = trans.Pool + builder: llvmlite.IRBuilder* = trans._cur_builder + func: llvmlite.Function* = trans._cur_func + pool: memhub.MemBuddy* = trans.Pool if builder is None or func is None: return 0 @@ -318,7 +318,7 @@ class StmtGenDeclMixin(StmtGenCifMixin.StmtGenCifMixin): llvmlite.position_at_end(builder, dead_bb) return 0 - def get_stmt_kind_name(self, node: rawptr[ast.AST]) -> str: + def get_stmt_kind_name(self, node: ast.AST*) -> str: """获取语句类型名""" if node is None: return None @@ -328,7 +328,7 @@ class StmtGenDeclMixin(StmtGenCifMixin.StmtGenCifMixin): # 簇 D:nonlocal/闭包 env 访问(迁移自 HandlesNonlocal.vp) # ============================================================ - def _is_void_type(self, ty: rawptr[llvmlite.LLVMType]) -> int: + def _is_void_type(self, ty: llvmlite.LLVMType*) -> int: """判断是否为 Void 类型,是则返回 1,否则 0""" if ty is None: return 0 @@ -338,25 +338,25 @@ class StmtGenDeclMixin(StmtGenCifMixin.StmtGenCifMixin): case _: return 0 - def get_env_ptr_var(self, trans: rawptr[HT.Translator]) -> rawptr[llvmlite.Value]: + def get_env_ptr_var(self, trans: HT.Translator*) -> llvmlite.Value*: """获取或创建 _env_ptr 变量(存储闭包 env 指针)""" - env_var: rawptr[llvmlite.Value] = self.Gen.VarGen.lookup_var( + env_var: 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: 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: rawptr[llvmlite.Value] = llvmlite.build_alloca(builder, i8_ptr_ty) + pool: memhub.MemBuddy* = trans.Pool + builder: llvmlite.IRBuilder* = trans._cur_builder + i8_ty: llvmlite.LLVMType* = llvmlite.Int8(pool) + i8_ptr_ty: llvmlite.LLVMType* = llvmlite.Ptr(pool, i8_ty) + alloca: 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) -> rawptr[llvmlite.Value]: + def _load_raw_var_ptr(self, trans: HT.Translator*, + name: str) -> llvmlite.Value*: """从闭包 env 加载 nonlocal 变量的原始指针(i8*) 返回 i8* 类型的 Value,调用方需 bitcast 为具体类型指针后 load/store。 @@ -365,86 +365,86 @@ class StmtGenDeclMixin(StmtGenCifMixin.StmtGenCifMixin): if idx < 0: return None - pool: rawptr[memhub.MemBuddy] = trans.Pool - 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) + pool: memhub.MemBuddy* = trans.Pool + builder: llvmlite.IRBuilder* = trans._cur_builder + i8_ty: llvmlite.LLVMType* = llvmlite.Int8(pool) + i8_ptr_ty: llvmlite.LLVMType* = llvmlite.Ptr(pool, i8_ty) + i8_ptr_ptr_ty: llvmlite.LLVMType* = llvmlite.Ptr(pool, i8_ptr_ty) # 1. 加载 env_ptr - env_alloca: rawptr[llvmlite.Value] = self.get_env_ptr_var(trans) + env_alloca: llvmlite.Value* = self.get_env_ptr_var(trans) if env_alloca is None: return None - env_ptr: rawptr[llvmlite.Value] = llvmlite.build_load(builder, i8_ptr_ty, env_alloca) + env_ptr: 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: rawptr[llvmlite.Value] = llvmlite.const_int32(pool, idx * 8) - addr: rawptr[llvmlite.Value] = llvmlite.build_gep(builder, i8_ty, env_ptr, offset_val) + offset_val: llvmlite.Value* = llvmlite.const_int32(pool, idx * 8) + addr: 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: rawptr[llvmlite.Value] = llvmlite.build_bitcast(builder, addr, i8_ptr_ptr_ty) + ptr_addr: 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) -> rawptr[llvmlite.Value]: + def load_nonlocal_var(self, trans: HT.Translator*, + name: str) -> llvmlite.Value*: """从闭包 env 加载 nonlocal 变量值 通过 HT.get_nonlocal_type 获取变量类型,bitcast 原始指针后 load。 """ - raw_ptr: rawptr[llvmlite.Value] = self._load_raw_var_ptr(trans, name) + raw_ptr: llvmlite.Value* = self._load_raw_var_ptr(trans, name) if raw_ptr is None: return None - pool: rawptr[memhub.MemBuddy] = trans.Pool - builder: rawptr[llvmlite.IRBuilder] = trans._cur_builder + pool: memhub.MemBuddy* = trans.Pool + builder: llvmlite.IRBuilder* = trans._cur_builder # 获取变量类型(从注册时存储的类型信息) - var_ty: rawptr[llvmlite.LLVMType] = GenApi.get_nonlocal_type(trans, name) + var_ty: llvmlite.LLVMType* = GenApi.get_nonlocal_type(trans, name) if var_ty is None or self._is_void_type(var_ty) != 0: # 类型缺失/无效直接报错终止(fail-fast),避免生成 "load void, void*" 非法 IR self.Gen.TypeGenErr.fatal_error(None, f"nonlocal 变量 '{name}' 类型缺失,无法 load", "TypeError") # bitcast raw i8* to var_ty* - var_ptr_ty: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, var_ty) - var_ptr: rawptr[llvmlite.Value] = llvmlite.build_bitcast(builder, raw_ptr, var_ptr_ty) + var_ptr_ty: llvmlite.LLVMType* = llvmlite.Ptr(pool, var_ty) + var_ptr: 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) -> rawptr[llvmlite.Value]: + def get_nonlocal_var_ptr(self, trans: HT.Translator*, + name: str) -> llvmlite.Value*: """获取 nonlocal 变量的存储指针(var_ty*),用于 store 操作 返回的指针指向父函数的 alloca,store 操作对父函数可见。 """ - raw_ptr: rawptr[llvmlite.Value] = self._load_raw_var_ptr(trans, name) + raw_ptr: llvmlite.Value* = self._load_raw_var_ptr(trans, name) if raw_ptr is None: return None - pool: rawptr[memhub.MemBuddy] = trans.Pool - builder: rawptr[llvmlite.IRBuilder] = trans._cur_builder + pool: memhub.MemBuddy* = trans.Pool + builder: llvmlite.IRBuilder* = trans._cur_builder # 获取变量类型 - var_ty: rawptr[llvmlite.LLVMType] = GenApi.get_nonlocal_type(trans, name) + var_ty: llvmlite.LLVMType* = GenApi.get_nonlocal_type(trans, name) if var_ty is None or self._is_void_type(var_ty) != 0: # 类型缺失/无效直接报错终止(fail-fast),避免生成 "bitcast ... to void*" 非法 IR self.Gen.TypeGenErr.fatal_error(None, f"nonlocal 变量 '{name}' 类型缺失,无法 load", "TypeError") # bitcast raw i8* to var_ty* - var_ptr_ty: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, var_ty) + var_ptr_ty: llvmlite.LLVMType* = llvmlite.Ptr(pool, var_ty) return llvmlite.build_bitcast(builder, raw_ptr, var_ptr_ty) # ============================================================ # 簇 E:枚举注册表(迁移自 HandlesEnum.vp) # ============================================================ - def init_enum_table(self, pool: rawptr[memhub.MemBuddy]) -> int: + def init_enum_table(self, pool: memhub.MemBuddy*) -> int: """初始化枚举注册表,返回 1 成功 表用 stdlib 分配(跨 Phase1 1b 的 mark/reset_to 存活——枚举表是 @@ -479,9 +479,9 @@ class StmtGenDeclMixin(StmtGenCifMixin.StmtGenCifMixin): addr: uint64 = uint64(enum_entry.Members) + i * member_size return rawptr[GenTypes.EnumMember](addr) - def register_enum(self, pool: rawptr[memhub.MemBuddy], + def register_enum(self, pool: memhub.MemBuddy*, name: str, - base_ty: rawptr[llvmlite.LLVMType]) -> rawptr[GenTypes.EnumEntry]: + base_ty: llvmlite.LLVMType*) -> rawptr[GenTypes.EnumEntry]: """注册枚举类型,返回 EnumEntry 指针""" if self.init_enum_table(pool) == 0: return None @@ -519,7 +519,7 @@ class StmtGenDeclMixin(StmtGenCifMixin.StmtGenCifMixin): # 注意:StdlibAlloc 是 StructGenMixin 字段,本 Mixin 方法体不能直接 self.StdlibAlloc # (NoVTable 按本 Mixin 字段布局编译),走模块级委托。 if self.Gen.StructGen.get_stdlib_alloc() != 0: - base_ty_copy: rawptr[llvmlite.LLVMType] = llvmlite.DeepCopyType( + base_ty_copy: llvmlite.LLVMType* = llvmlite.DeepCopyType( CompilerFactory.factory.PermPool, base_ty) if base_ty_copy is not None: entry.BaseTy = base_ty_copy @@ -532,11 +532,11 @@ class StmtGenDeclMixin(StmtGenCifMixin.StmtGenCifMixin): self.EnumCount += 1 return entry - def add_enum_member(self, pool: rawptr[memhub.MemBuddy], + def add_enum_member(self, pool: memhub.MemBuddy*, enum_entry: rawptr[GenTypes.EnumEntry], member_name: str, member_val: int64, - member_ty: rawptr[llvmlite.LLVMType]) -> int: + member_ty: llvmlite.LLVMType*) -> int: """向枚举添加成员,返回成员索引(-1 失败)""" if enum_entry is None or member_name is None or member_ty is None: return -1 @@ -606,7 +606,7 @@ class StmtGenDeclMixin(StmtGenCifMixin.StmtGenCifMixin): return 1 return 0 - def get_enum_base_type(self, enum_name: str) -> rawptr[llvmlite.LLVMType]: + def get_enum_base_type(self, enum_name: str) -> llvmlite.LLVMType*: """按枚举类名获取基准类型""" entry: rawptr[GenTypes.EnumEntry] = self.find_enum(enum_name) if entry is not None: diff --git a/App/lib/core/Gen/Stmt/StmtGenMixin.vp b/App/lib/core/Gen/Stmt/StmtGenMixin.vp index bd03e34..346c615 100644 --- a/App/lib/core/Gen/Stmt/StmtGenMixin.vp +++ b/App/lib/core/Gen/Stmt/StmtGenMixin.vp @@ -37,8 +37,8 @@ import lib.core.Gen.Stmt.StmtGenDeclMixin as StmtGenDeclMixin class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin): """语句/流程翻译 Mixin(拆分后顶层,继承 Decl)""" - def translate_stmt(self, trans: rawptr[HT.Translator], - node: rawptr[ast.AST]) -> int: + def translate_stmt(self, trans: HT.Translator*, + node: ast.AST*) -> int: """翻译单条语句,返回新增的变量数(深度守卫包装器,原逻辑见 _translate_stmt_impl)""" if trans is not None: if trans.TranslateDepth >= HT.TRANSLATE_MAX_DEPTH: @@ -50,8 +50,8 @@ class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin): trans.TranslateDepth -= 1 return mret - def _translate_stmt_impl(self, trans: rawptr[HT.Translator], - node: rawptr[ast.AST]) -> int: + def _translate_stmt_impl(self, trans: HT.Translator*, + node: ast.AST*) -> int: """翻译单条语句,返回新增的变量数""" if node is None: return 0 @@ -107,41 +107,41 @@ class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin): self.Gen.TypeGenErr.fatal_error(node, f"未知语句类型 kind={k}", "SyntaxError") return 0 - def translate_delete(self, trans: rawptr[HT.Translator], - node: rawptr[ast.AST]) -> int: + def translate_delete(self, trans: HT.Translator*, + node: ast.AST*) -> int: """翻译 del 语句,返回 0""" if trans is None or node is None: return 0 dnode: rawptr[ast.Delete] = rawptr[ast.Delete](node) if dnode is None or dnode.targets is None: return 0 - pool: rawptr[memhub.MemBuddy] = trans.Pool - mod: rawptr[llvmlite.LLVMModule] = trans.Module - builder: rawptr[llvmlite.IRBuilder] = trans._cur_builder + pool: memhub.MemBuddy* = trans.Pool + mod: llvmlite.LLVMModule* = trans.Module + builder: llvmlite.IRBuilder* = trans._cur_builder if pool is None or mod is None or builder is None: return 0 tn: sizet = len(dnode.targets) for ti in range(tn): - tgt: rawptr[ast.AST] = dnode.targets.get(ti) + tgt: ast.AST* = dnode.targets.get(ti) if tgt is None: continue # del obj.attr → property deleter if tgt.kind() == ast.ASTKind.Attribute: - del_at: rawptr[ast.Attribute] = rawptr[ast.Attribute](tgt) + del_at: ast.Attribute* = ast.Attribute*(tgt) if del_at is not None: self.Gen.CallGenProp._try_property_deleter( pool, builder, mod, del_at, trans) # del obj[key] → __delitem__(obj, key)(对齐 TPC HandlesDelete.py)。 # 不能静默忽略 Subscript 目标——否则 del 不生效(len 不变)。 elif tgt.kind() == ast.ASTKind.Subscript: - dl_sub: rawptr[ast.Subscript] = rawptr[ast.Subscript](tgt) + dl_sub: ast.Subscript* = 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: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( + dl_obj: llvmlite.Value* = self.Gen.ExprGen.translate_value( builder, pool, mod, dl_sub.value, None, 0, trans) - dl_idx: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( + dl_idx: 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( + dl_st: llvmlite.LLVMType* = self.Gen.StructGen.get_struct_type_from_value( dl_obj) if dl_st is not None: dl_cls: str = self.Gen.StructGen.get_class_name_by_type(pool, dl_st) @@ -149,17 +149,17 @@ class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin): dl_lookup: str = pool.alloc(128) if dl_lookup is not None: viperlib.snprintf(dl_lookup, 128, "%s.__delitem__", dl_cls) - dl_fn: rawptr[llvmlite.Function] = self.Gen.CallGenBase.find_func_in_module( + dl_fn: llvmlite.Function* = self.Gen.CallGenBase.find_func_in_module( mod, dl_lookup) if dl_fn is not None: - dl_ret: rawptr[llvmlite.LLVMType] = llvmlite.function_get_ret_ty(dl_fn) + dl_ret: llvmlite.LLVMType* = llvmlite.function_get_ret_ty(dl_fn) 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: rawptr[llvmlite.Value] = dl_obj - dl_first: rawptr[llvmlite.Param] = llvmlite.function_get_param_head(dl_fn) + dl_self: llvmlite.Value* = dl_obj + dl_first: 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) + dl_self_ty: llvmlite.LLVMType* = llvmlite.param_get_ty(dl_first) if dl_self_ty is not None: dl_self = llvmlite.build_bitcast(builder, dl_obj, dl_self_ty) if dl_self is not None: @@ -185,34 +185,34 @@ class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin): # v1 未实现 finalbody(TestFBProject 未使用;finally+return 交互复杂, # 后续按 TPC HandlesTry.py L188-214 的 pending_ret 方案扩展)。 # ============================================================ - def translate_try(self, trans: rawptr[HT.Translator], - node: rawptr[ast.AST]) -> int: + def translate_try(self, trans: HT.Translator*, + node: ast.AST*) -> int: """翻译 try/except 语句,返回 0""" if trans is None or node is None: return 0 - tr: rawptr[ast.Try] = rawptr[ast.Try](node) + tr: ast.Try* = ast.Try*(node) if tr is None: return 0 - pool: rawptr[memhub.MemBuddy] = trans.Pool - builder: rawptr[llvmlite.IRBuilder] = trans._cur_builder - func: rawptr[llvmlite.Function] = trans._cur_func + pool: memhub.MemBuddy* = trans.Pool + builder: llvmlite.IRBuilder* = trans._cur_builder + func: llvmlite.Function* = trans._cur_func if pool is None or builder is None or func is None: return 0 if llvmlite.builder_cur_block_is_terminated(builder) != 0: return 0 # ---- 1. 异常编码/消息 alloca(当前 try 上下文)---- - i32_ty_t: rawptr[llvmlite.LLVMType] = llvmlite.Int32(pool) - i8_ty_t: rawptr[llvmlite.LLVMType] = llvmlite.Int8(pool) - i8_ptr_ty_t: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, i8_ty_t) + i32_ty_t: llvmlite.LLVMType* = llvmlite.Int32(pool) + i8_ty_t: llvmlite.LLVMType* = llvmlite.Int8(pool) + i8_ptr_ty_t: 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: rawptr[llvmlite.Value] = llvmlite.build_alloca(builder, i32_ty_t) - eh_message: rawptr[llvmlite.Value] = llvmlite.build_alloca(builder, i8_ptr_ty_t) + exception_code: llvmlite.Value* = llvmlite.build_alloca(builder, i32_ty_t) + eh_message: 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: rawptr[llvmlite.Value] = llvmlite.const_int32(pool, 0) - init_msg_t: rawptr[llvmlite.Value] = llvmlite.ConstNull(pool, i8_ptr_ty_t, "null") + init_code_t: llvmlite.Value* = llvmlite.const_int32(pool, 0) + init_msg_t: 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: @@ -260,8 +260,8 @@ class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin): # ---- 3. 保存外层 try 上下文,设置本 try 上下文 ---- 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 + old_code_t: llvmlite.Value* = trans._eh_code_ptr + old_msg_t: llvmlite.Value* = trans._eh_msg_ptr trans._eh_dispatch_bb = dispatch_bb trans._eh_code_ptr = exception_code trans._eh_msg_ptr = eh_message @@ -272,7 +272,7 @@ class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin): if tr.children is not None: tb_n: sizet = len(tr.children) for tbi in range(tb_n): - stmt_t: rawptr[ast.AST] = tr.children.get(tbi) + stmt_t: ast.AST* = tr.children.get(tbi) if stmt_t is not None: self.translate_stmt(trans, stmt_t) # 正常走完 try 体:清异常码,进 else(若有)或 After @@ -290,11 +290,11 @@ class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin): # 无 except(非法 try,防御):直接吞掉 llvmlite.build_br(builder, unhandled_bb) else: - eh_code_val: rawptr[llvmlite.Value] = llvmlite.build_load( + eh_code_val: llvmlite.Value* = llvmlite.build_load( builder, i32_ty_t, exception_code) next_check_t: rawptr[llvmlite.BasicBlock] = None for i_t in range(n_handlers_t): - hdr_t: rawptr[ast.ExceptHandler] = rawptr[ast.ExceptHandler]( + hdr_t: ast.ExceptHandler* = ast.ExceptHandler*( tr.handlers.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: @@ -307,11 +307,11 @@ class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin): else: # 展开匹配编码集(handler.type 自身 + 全部子孙异常类) hname_t: str = None - htype_t: rawptr[ast.AST] = hdr_t.type + htype_t: ast.AST* = hdr_t.type if htype_t.kind() == ast.ASTKind.Name: - hname_t = (rawptr[ast.Name](htype_t)).id + hname_t = (ast.Name*(htype_t)).id elif htype_t.kind() == ast.ASTKind.Attribute: - hname_t = (rawptr[ast.Attribute](htype_t)).attr + hname_t = (ast.Attribute*(htype_t)).attr # 匹配编码缓冲:必须是 int*(i32 步长)——collect_descendant_codes 按 # out_codes[i](4 字节)写入;用 sizet*(8 字节)读会读出 64 位拼接垃圾 # (多码时 code[i+1]<<32|code[i];单码时高位恰为 0 掩盖)。 @@ -330,11 +330,11 @@ class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin): c0_t = 1 codes_buf_t[0] = c0_t n_codes_t = 1 - match_cond_t: rawptr[llvmlite.Value] = None + match_cond_t: llvmlite.Value* = None for ci_t in range(n_codes_t): - code_val_t: rawptr[llvmlite.Value] = llvmlite.const_int32( + code_val_t: llvmlite.Value* = llvmlite.const_int32( pool, codes_buf_t[ci_t]) - is_match_t: rawptr[llvmlite.Value] = llvmlite.build_icmp( + is_match_t: 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,16 +355,16 @@ class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin): # 重复 define_var 不 shadow——多 try 共用 `as e` 时各 MatchBB # 各自 store 消息,各 ExceptBB 读同一入口 alloca,避免 # 非支配 alloca 触发 "does not dominate all uses")。 - h_ent_t: rawptr[GenTypes.VarEntry] = self.Gen.VarGen.lookup_var_entry( + h_ent_t: 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: rawptr[llvmlite.Value] = h_ent_t.Alloca + h_alloca_t: 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: rawptr[llvmlite.Value] = llvmlite.build_load( + h_msg_t: 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) @@ -375,9 +375,9 @@ class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin): 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: rawptr[llvmlite.Value] = llvmlite.build_load( + un_msg_t: llvmlite.Value* = llvmlite.build_load( builder, i8_ptr_ty_t, eh_message) - un_code_t: rawptr[llvmlite.Value] = llvmlite.build_load( + un_code_t: 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) @@ -391,14 +391,14 @@ class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin): # ---- 7. Except 体 ---- for i_t in range(n_handlers_t): - hdr2_t: rawptr[ast.ExceptHandler] = rawptr[ast.ExceptHandler]( + hdr2_t: ast.ExceptHandler* = ast.ExceptHandler*( tr.handlers.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) for hi2 in range(hn2_t): - stmt2_t: rawptr[ast.AST] = hdr2_t.children.get(hi2) + stmt2_t: ast.AST* = hdr2_t.children.get(hi2) if stmt2_t is not None: self.translate_stmt(trans, stmt2_t) if llvmlite.builder_cur_block_is_terminated(builder) == 0: @@ -410,7 +410,7 @@ class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin): if tr.orelse is not None: en_t: sizet = len(tr.orelse) for ei in range(en_t): - stmt3_t: rawptr[ast.AST] = tr.orelse.get(ei) + stmt3_t: ast.AST* = tr.orelse.get(ei) if stmt3_t is not None: self.translate_stmt(trans, stmt3_t) if llvmlite.builder_cur_block_is_terminated(builder) == 0: @@ -423,8 +423,8 @@ class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin): trans._eh_msg_ptr = old_msg_t return 0 - def translate_raise(self, trans: rawptr[HT.Translator], - node: rawptr[ast.AST]) -> int: + def translate_raise(self, trans: HT.Translator*, + node: ast.AST*) -> int: """翻译 raise 语句,返回 0 对齐 TPC HandlesRaise.py 的 try-except 语义(v1 迁移): @@ -438,9 +438,9 @@ class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin): """ if trans is None or node is None: return 0 - pool: rawptr[memhub.MemBuddy] = trans.Pool - builder: rawptr[llvmlite.IRBuilder] = trans._cur_builder - mod: rawptr[llvmlite.LLVMModule] = trans.Module + pool: memhub.MemBuddy* = trans.Pool + builder: llvmlite.IRBuilder* = trans._cur_builder + mod: llvmlite.LLVMModule* = trans.Module if pool is None or builder is None or mod is None: return 0 rn: rawptr[ast.Raise] = rawptr[ast.Raise](node) @@ -454,20 +454,20 @@ class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin): ek: int = rn.exc.kind() is_stop_iter: int = 0 if ek == ast.ASTKind.Name: - enm: rawptr[ast.Name] = rawptr[ast.Name](rn.exc) + enm: ast.Name* = ast.Name*(rn.exc) if enm.id is not None and string.strcmp(enm.id, "StopIteration") == 0: is_stop_iter = 1 elif ek == ast.ASTKind.Call: - ecl: rawptr[ast.Call] = rawptr[ast.Call](rn.exc) + ecl: ast.Call* = ast.Call*(rn.exc) if ecl.func is not None and ecl.func.kind() == ast.ASTKind.Name: - ecn: rawptr[ast.Name] = rawptr[ast.Name](ecl.func) + ecn: ast.Name* = ast.Name*(ecl.func) if ecn.id is not None and string.strcmp(ecn.id, "StopIteration") == 0: is_stop_iter = 1 if is_stop_iter != 0: if trans._stop_iter_flag_ptr is not None: - i1_ty_r: rawptr[llvmlite.LLVMType] = llvmlite.Int1(pool) + i1_ty_r: llvmlite.LLVMType* = llvmlite.Int1(pool) if i1_ty_r is not None: - one_i1_r: rawptr[llvmlite.Value] = llvmlite.ConstInt( + one_i1_r: llvmlite.Value* = llvmlite.ConstInt( pool, i1_ty_r, 1, "1") if one_i1_r is not None: llvmlite.build_store( @@ -477,21 +477,21 @@ class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin): # ---- 非 StopIteration:计算异常编码与消息 ---- exc_code: int = 1 - exc_msg: rawptr[llvmlite.Value] = None + exc_msg: llvmlite.Value* = None if ek == ast.ASTKind.Constant: - cst_r: rawptr[ast.Constant] = rawptr[ast.Constant](rn.exc) + cst_r: ast.Constant* = ast.Constant*(rn.exc) if cst_r is not None and cst_r.const_kind == ast.CONST_INT: exc_code = cst_r.int_val elif ek == ast.ASTKind.Name: - enm2: rawptr[ast.Name] = rawptr[ast.Name](rn.exc) + enm2: ast.Name* = ast.Name*(rn.exc) if enm2.id is not None: exc_code = self.Gen.ClassGenBase.lookup_exception_code(enm2.id) if exc_code == 0: exc_code = 1 elif ek == ast.ASTKind.Call: - ecl2: rawptr[ast.Call] = rawptr[ast.Call](rn.exc) + ecl2: ast.Call* = ast.Call*(rn.exc) if ecl2.func is not None and ecl2.func.kind() == ast.ASTKind.Name: - ecn2: rawptr[ast.Name] = rawptr[ast.Name](ecl2.func) + ecn2: ast.Name* = ast.Name*(ecl2.func) if ecn2.id is not None: exc_code = self.Gen.ClassGenBase.lookup_exception_code(ecn2.id) if exc_code == 0: @@ -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: rawptr[llvmlite.Value] = llvmlite.const_int32(pool, exc_code) + code_val_r: 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: rawptr[llvmlite.Value] = llvmlite.const_int32(pool, exc_code) + code_val_r2: 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: @@ -537,33 +537,33 @@ class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin): # (void→ret_void,ptr→null,float→0.0,其余→零值)。当前块已 # 终结(前一条是 raise/return)时跳过,避免在终止块后插指令。 # ============================================================ - def _eh_ret_default(self, trans: rawptr[HT.Translator], - pool: rawptr[memhub.MemBuddy], - builder: rawptr[llvmlite.IRBuilder]) -> int: + def _eh_ret_default(self, trans: HT.Translator*, + pool: memhub.MemBuddy*, + builder: llvmlite.IRBuilder*) -> int: """异常路径返回当前函数默认零值,返回 0""" if trans is None or builder is None: return 0 if llvmlite.builder_cur_block_is_terminated(builder) != 0: return 0 - cur_func: rawptr[llvmlite.Function] = trans._cur_func + cur_func: llvmlite.Function* = trans._cur_func if cur_func is None: return 0 - ret_ty: rawptr[llvmlite.LLVMType] = llvmlite.function_get_ret_ty(cur_func) + ret_ty: llvmlite.LLVMType* = llvmlite.function_get_ret_ty(cur_func) if ret_ty is None: return 0 match ret_ty: case llvmlite.LLVMType.Void(): llvmlite.build_ret_void(builder) case llvmlite.LLVMType.Ptr(_pe): - null_v: rawptr[llvmlite.Value] = llvmlite.ConstNull(pool, ret_ty, "null") + null_v: 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: rawptr[llvmlite.Value] = llvmlite.ConstFloat(pool, ret_ty, 0.0) + zero_f: llvmlite.Value* = llvmlite.ConstFloat(pool, ret_ty, 0.0) if zero_f is not None: llvmlite.build_ret(builder, zero_f) case _: - zero_v: rawptr[llvmlite.Value] = llvmlite.ConstZero(pool, ret_ty) + zero_v: llvmlite.Value* = llvmlite.ConstZero(pool, ret_ty) if zero_v is not None: llvmlite.build_ret(builder, zero_v) return 0 @@ -584,17 +584,17 @@ class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin): # 退出后恢复,避免内层覆盖导致外层 __exit__ 解析到错误对象。 # 对齐 TPC HandlesWith 语义(不含 __provides__ provider 机制)。 # ============================================================ - def translate_with(self, trans: rawptr[HT.Translator], - node: rawptr[ast.AST]) -> int: + def translate_with(self, trans: HT.Translator*, + node: ast.AST*) -> int: """翻译 with 语句,返回 0""" if trans is None or node is None: return 0 - wt: rawptr[ast.With] = rawptr[ast.With](node) + wt: ast.With* = ast.With*(node) if wt is None: return 0 - pool: rawptr[memhub.MemBuddy] = trans.Pool - builder: rawptr[llvmlite.IRBuilder] = trans._cur_builder - mod: rawptr[llvmlite.LLVMModule] = trans.Module + pool: memhub.MemBuddy* = trans.Pool + builder: llvmlite.IRBuilder* = trans._cur_builder + mod: llvmlite.LLVMModule* = trans.Module if pool is None or builder is None or mod is None: return 0 items: list[ast.AST*]* = wt.items @@ -603,18 +603,18 @@ class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin): n: sizet = len(items) # 保存外层 __with_ctx(嵌套 with 时退出后恢复) - old_ctx_alloca: rawptr[llvmlite.Value] = self.Gen.VarGen.lookup_var( + old_ctx_alloca: llvmlite.Value* = self.Gen.VarGen.lookup_var( trans.SymTab, "__with_ctx") # 记录每个 item 的类名(__exit__ 调用时设置 __with_ctx 类型用) - ctx_class_buf: sizet | t.CPtr = pool.alloc(8 * n) + ctx_class_buf: sizet* = pool.alloc(8 * n) if ctx_class_buf is None: return 0 string.memset(ctx_class_buf, 0, 8 * n) # 1. 全部 item:构造 context 对象 + 调用 __enter__ + asname 绑定 for i in range(n): - item_node: rawptr[ast.AST] = items.get(i) + item_node: ast.AST* = items.get(i) if item_node is None: continue if item_node.kind() != ast.ASTKind.WithItem: @@ -623,7 +623,7 @@ class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin): if item is None or item.context_expr is None: continue # 翻译 context_expr(对象构造,如 MemPool(arena, 4096)) - ctx_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( + ctx_val: llvmlite.Value* = self.Gen.ExprGen.translate_value( builder, pool, mod, item.context_expr, trans._funcs, trans._func_count, trans) if ctx_val is None: @@ -632,14 +632,14 @@ class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin): # 与 AnnAssign 的 extract_class_name_from_annotation 一致,跨模块 # 方法调用靠 AnnotClassName 回退按模块名查 SHA1) cls_name: str = None - ce: rawptr[ast.AST] = item.context_expr + ce: ast.AST* = item.context_expr if ce.kind() == ast.ASTKind.Call: - cfn: rawptr[ast.AST] = (rawptr[ast.Call](ce)).func + cfn: ast.AST* = (ast.Call*(ce)).func if cfn is not None: if cfn.kind() == ast.ASTKind.Attribute: - ca: rawptr[ast.Attribute] = rawptr[ast.Attribute](cfn) + ca: ast.Attribute* = ast.Attribute*(cfn) if ca.value is not None and ca.value.kind() == ast.ASTKind.Name: - cmn: rawptr[ast.Name] = rawptr[ast.Name](ca.value) + cmn: ast.Name* = ast.Name*(ca.value) if cmn.id is not None: ml2: sizet = string.strlen(cmn.id) + string.strlen(ca.attr) + 2 mbuf: str = pool.alloc(ml2) @@ -649,9 +649,9 @@ class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin): if cls_name is None: cls_name = ca.attr elif cfn.kind() == ast.ASTKind.Name: - cls_name = (rawptr[ast.Name](cfn)).id + cls_name = (ast.Name*(cfn)).id # context 对象存入 __with_ctx(方法调用解析 self 用) - ctx_alloca: rawptr[llvmlite.Value] = llvmlite.build_alloca( + ctx_alloca: llvmlite.Value* = llvmlite.build_alloca( builder, ctx_val.Ty) if ctx_alloca is None: continue @@ -662,19 +662,19 @@ class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin): trans.SymTab, "__with_ctx", cls_name) ctx_class_buf[i] = sizet(cls_name) # 调用 __enter__() - enter_val: rawptr[llvmlite.Value] = self._with_ctx_call( + enter_val: llvmlite.Value* = self._with_ctx_call( trans, pool, builder, mod, "__enter__") # asname 绑定(__enter__ 返回值,缺失时退回 context 对象) if item.optional_vars is not None: - ov: rawptr[ast.AST] = item.optional_vars + ov: ast.AST* = item.optional_vars if ov.kind() == ast.ASTKind.Name: - asname: str = (rawptr[ast.Name](ov)).id + asname: str = (ast.Name*(ov)).id if asname is not None: - bind_val: rawptr[llvmlite.Value] = enter_val + bind_val: llvmlite.Value* = enter_val if bind_val is None: bind_val = ctx_val if bind_val is not None: - asn_alloca: rawptr[llvmlite.Value] = llvmlite.build_alloca( + asn_alloca: llvmlite.Value* = llvmlite.build_alloca( builder, bind_val.Ty) if asn_alloca is not None: llvmlite.build_store(builder, bind_val, asn_alloca) @@ -699,7 +699,7 @@ class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin): if body is not None: bn: sizet = len(body) for bi in range(bn): - st: rawptr[ast.AST] = body.get(bi) + st: ast.AST* = body.get(bi) if st is not None: self.translate_stmt(trans, st) @@ -731,22 +731,22 @@ class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin): self.Gen.VarGen.define_var(trans.SymTab, "__with_ctx", old_ctx_alloca) return 0 - def _with_ctx_call(self, trans: rawptr[HT.Translator], - pool: rawptr[memhub.MemBuddy], - builder: rawptr[llvmlite.IRBuilder], - mod: rawptr[llvmlite.LLVMModule], - method_name: str) -> rawptr[llvmlite.Value]: + def _with_ctx_call(self, trans: HT.Translator*, + pool: memhub.MemBuddy*, + builder: llvmlite.IRBuilder*, + mod: llvmlite.LLVMModule*, + method_name: str) -> llvmlite.Value*: """构造并翻译 __with_ctx.() 调用(__enter__/__exit__)""" if pool is None or method_name is None: return None - name_node: rawptr[ast.AST] = ast.Name(pool, "__with_ctx", ast.ASTCtx.Load) + name_node: ast.AST* = ast.Name(pool, "__with_ctx", ast.ASTCtx.Load) if name_node is None: return None - attr_node: rawptr[ast.AST] = ast.Attribute( + attr_node: ast.AST* = ast.Attribute( pool, name_node, method_name, ast.ASTCtx.Load) if attr_node is None: return None - call_node: rawptr[ast.AST] = ast.Call(pool, attr_node, None, None) + call_node: ast.AST* = ast.Call(pool, attr_node, None, None) if call_node is None: return None return self.Gen.ExprGen.translate_value( diff --git a/App/lib/core/Gen/StructGenMixin.vp b/App/lib/core/Gen/StructGenMixin.vp index c01ac90..48d26d3 100644 --- a/App/lib/core/Gen/StructGenMixin.vp +++ b/App/lib/core/Gen/StructGenMixin.vp @@ -80,32 +80,30 @@ def _struct_ty_hash(tyval: uint64) -> uint64: # ============================================================ # StructGenMixin - 结构体注册表/字段查找/可见性 # ============================================================ -@t.NoVTable -class StructGenMixin: +novirtual class StructGenMixin: """结构体注册与查找 Mixin(状态从 HandlesStruct 全局变量迁入)""" # --- 全局注册表(原 _struct_table/_struct_count) --- - Gen: rawptr[Generator.Generator] - StructTable: rawptr[GenTypes.StructEntry] # STRUCT_MAX 槽位数组 + Gen: Generator.Generator* + StructTable: GenTypes.StructEntry* # STRUCT_MAX 槽位数组 StructCount: int # --- OOM 回收分配模式(原 _g_stdlib_alloc) --- StdlibAlloc: int # --- 跨模块命名空间隔离(原 _visible_structs/_strict_visibility) --- - VisibleStructs: rawptr[hashtable.HashTable] + VisibleStructs: hashtable.HashTable* StrictVisibility: int # --- 名 | 类型 下标索引(查找快速路径;索引不可信时回退原线性扫描) --- - StructNameIdx: sizet | t.CPtr # 名 → 首注册下标(槽 u64:0=空槽,否则 index+1) - StructTypeIdx: sizet | t.CPtr # Ty 指针值 → 首注册下标(同布局) + StructNameIdx: sizet* # 名 → 首注册下标(槽 u64:0=空槽,否则 index+1) + StructTypeIdx: sizet* # Ty 指针值 → 首注册下标(同布局) StructIdxCap: int # 索引槽数(2 的幂,> 2*STRUCT_MAX) StructIdxBuilt: int # 已同步建索引条目数(-1=不可信;= StructCount 才可信) def InitStructGen(self) -> int: """初始化结构体 Mixin 字段(子类构造时内联调用,规避 NoVTable 继承符号不转发)""" - if self is None: - return 1 + if self is None: return 1 self.StructTable = None self.StructCount = 0 self.StdlibAlloc = 0 @@ -131,7 +129,7 @@ class StructGenMixin: 避免跨 Mixin 直接读 self.StdlibAlloc——Mixin 方法体按自身块内索引编译)""" return self.StdlibAlloc - def reset_visible_structs(self, pool: rawptr[memhub.MemBuddy], strict: int) -> None: + def reset_visible_structs(self, pool: memhub.MemBuddy*, strict: int) -> None: """重置可见性状态(每个文件翻译前调用) pool: 内存分配器(严格模式下创建 HashTable) @@ -145,55 +143,46 @@ class StructGenMixin: # 宽松模式:全部可见,不需要 HashTable self.VisibleStructs = None - def add_visible_struct(self, pool: rawptr[memhub.MemBuddy], name: str) -> None: + def add_visible_struct(self, pool: memhub.MemBuddy*, name: str) -> None: """添加可见结构体名(类定义时和 from-import 时调用)""" - if name is None: - return + if name is None: return # 宽松模式:全部可见,无需记录 - if self.StrictVisibility == 0: - return - if self.VisibleStructs is None: - return + if self.StrictVisibility == 0: return + if self.VisibleStructs is None: return # 已存在则跳过(HashTable.__setitem__ 会覆盖,此处提前检查避免重复分配) - if self.VisibleStructs.__contains__(name) != 0: - return + if self.VisibleStructs.__contains__(name) != 0: return self.VisibleStructs.set_int(name, 1) def is_struct_visible(self, name: str) -> int: """检查结构体是否可见,返回 1=可见 / 0=不可见""" - if self.StrictVisibility == 0: - return 1 - if name is None or self.VisibleStructs is None: - return 0 + if self.StrictVisibility == 0: return 1 + if name is None or self.VisibleStructs is None: return 0 return self.VisibleStructs.__contains__(name) - def init_struct_table(self, pool: rawptr[memhub.MemBuddy]) -> int: + def init_struct_table(self, pool: memhub.MemBuddy*) -> int: """初始化结构体注册表,返回 1 成功 StdlibAlloc=1 时表体分配在 perm_pool:1a 每文件 reset 后表本体 不被回收(否则首次 register_struct 若发生在文件级 mark 之后, reset 会把 StructTable 连根回收,全局 find_struct 悬空)。 """ - if self.StructTable is not None: - return 1 + if self.StructTable is not None: return 1 entry_size: sizet = GenTypes.StructEntry.__sizeof__() - table_pool: rawptr[memhub.MemBuddy] = pool + table_pool: memhub.MemBuddy* = pool if self.StdlibAlloc != 0: table_pool = CompilerFactory.factory.PermPool - if table_pool is None: - table_pool = pool + if table_pool is None: table_pool = pool self.StructTable = table_pool.alloc(entry_size * STRUCT_MAX) - if self.StructTable is None: - return 0 + if self.StructTable is None: return 0 string.memset(self.StructTable, 0, entry_size * STRUCT_MAX) self.StructCount = 0 # 建 名 | 类型 索引(与表同池分配:表存活则索引存活,生命周期一致)。 # 索引是可选加速层:分配失败则保持 None 且 StructIdxBuilt=-1,查找自动 # 回退原线性扫描(语义完全一致),故不因此使初始化失败。 idx_bytes: sizet = sizet(STRUCT_IDX_CAP) * 8 - name_idx: sizet | t.CPtr = table_pool.alloc(idx_bytes) - type_idx: sizet | t.CPtr = table_pool.alloc(idx_bytes) + name_idx: sizet* = table_pool.alloc(idx_bytes) + type_idx: sizet* = table_pool.alloc(idx_bytes) if name_idx is None or type_idx is None: self.StructNameIdx = None self.StructTypeIdx = None @@ -208,13 +197,13 @@ class StructGenMixin: self.StructIdxBuilt = 0 return 1 - def _get_struct_entry(self, i: int) -> rawptr[GenTypes.StructEntry]: + def _get_struct_entry(self, i: int) -> 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 rawptr[GenTypes.StructEntry](addr) + return GenTypes.StructEntry*(addr) # 名 | 类型 索引(开放寻址 | 线性探测;槽存 index+1,0=空槽) # 目的:把 find_struct/find_struct_by_module(名)与 find_struct_by_type(类型指针) @@ -224,14 +213,14 @@ class StructGenMixin: # 条目被中和(Name[0]=0 / Ty=None)后索引槽成失效键,探测时键不等即判定未命中。 def _struct_entry_name(self, i: int) -> str: """取第 i 个条目的 Name(供索引探测比较),越界/空返回 None""" - e: rawptr[GenTypes.StructEntry] = self._get_struct_entry(i) + e: 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: rawptr[GenTypes.StructEntry] = self._get_struct_entry(i) + e: GenTypes.StructEntry* = self._get_struct_entry(i) if e is None or e.Ty is None: return 0 return uint64(e.Ty) @@ -243,7 +232,7 @@ class StructGenMixin: 递增排列,查找取链上首个"当前键相等"者即 = 原扫描的首个命中。若按键去重, 则最早的重复项被中和(Name[0]=0)后,被丢弃的后续重复项将无法找回。 """ - base: sizet | t.CPtr = self.StructNameIdx + base: sizet* = self.StructNameIdx if base is None or self.StructIdxCap <= 0: return 1 h: uint64 = _struct_name_hash(name) @@ -251,7 +240,7 @@ class StructGenMixin: idx: sizet = sizet(h) & mask i: int = 0 while i < self.StructIdxCap: - slot: sizet | t.CPtr = (sizet | t.CPtr)(uint64(base) + uint64(idx * 8)) + slot: sizet* = (sizet*)(uint64(base) + uint64(idx * 8)) if slot[0] == 0: slot[0] = sizet(ei + 1) return 0 @@ -265,7 +254,7 @@ class StructGenMixin: 与名索引同策略:每次注册都占槽(不去重),保证探测链上同键条目按注册 顺序排列,查找首个"当前 Ty 相等"者 = 原扫描首个命中。 """ - base: sizet | t.CPtr = self.StructTypeIdx + base: sizet* = self.StructTypeIdx if base is None or self.StructIdxCap <= 0 or tyval == 0: return 1 h: uint64 = _struct_ty_hash(tyval) @@ -273,7 +262,7 @@ class StructGenMixin: idx: sizet = sizet(h) & mask i: int = 0 while i < self.StructIdxCap: - slot: sizet | t.CPtr = (sizet | t.CPtr)(uint64(base) + uint64(idx * 8)) + slot: sizet* = (sizet*)(uint64(base) + uint64(idx * 8)) if slot[0] == 0: slot[0] = sizet(ei + 1) return 0 @@ -281,7 +270,7 @@ class StructGenMixin: i += 1 return 1 - def _struct_idx_add(self, ei: int, entry: rawptr[GenTypes.StructEntry]) -> None: + def _struct_idx_add(self, ei: int, entry: GenTypes.StructEntry*) -> None: """新增条目后同步两张索引;任一写入失败 → 标记索引不可信(查找回退扫描)""" if self.StructNameIdx is None or self.StructTypeIdx is None or self.StructIdxCap <= 0: self.StructIdxBuilt = -1 @@ -303,7 +292,7 @@ class StructGenMixin: -1 表示"未命中或索引不可用",调用方须回退原线性扫描(保证正确性)。 探测链上同键条目按注册顺序排列,故首个"当前键相等"者即原扫描首个命中。 """ - base: sizet | t.CPtr = self.StructNameIdx + base: sizet* = self.StructNameIdx if base is None or self.StructIdxCap <= 0 or self.StructIdxBuilt != self.StructCount: return -1 # 空名("")特例:被中和的条目 Name 恰为 ""(Name[0]=0),原扫描会命中首个 @@ -314,18 +303,14 @@ class StructGenMixin: h: uint64 = _struct_name_hash(name) mask: sizet = sizet(self.StructIdxCap - 1) idx: sizet = sizet(h) & mask - i: int = 0 - while i < self.StructIdxCap: - slot: sizet | t.CPtr = (sizet | t.CPtr)(uint64(base) + uint64(idx * 8)) + for i in range(self.StructIdxCap): + slot: sizet* = (sizet*)(uint64(base) + uint64(idx * 8)) sv: sizet = slot[0] - if sv == 0: - return -1 + if sv == 0: return -1 se: int = int(sv) - 1 ek: str = self._struct_entry_name(se) - if ek is not None and string.strcmp(ek, name) == 0: - return se + if ek is not None and string.strcmp(ek, name) == 0: return se idx = (idx + 1) & mask - i += 1 return -1 def _struct_type_idx_find(self, tyval: uint64) -> int: @@ -334,93 +319,74 @@ class StructGenMixin: 类型索引不保证覆盖全部 Ty 值(如 ClassGenDef 深拷贝后 existing.Ty 被 改写为新指针,未入索引)⇒ 未命中不能断言"确无",一律回退线性扫描。 """ - base: sizet | t.CPtr = self.StructTypeIdx - if base is None or self.StructIdxCap <= 0 or tyval == 0: - return -1 - if self.StructIdxBuilt != self.StructCount: - return -1 + base: sizet* = self.StructTypeIdx + if base is None or self.StructIdxCap <= 0 or tyval == 0: return -1 + if self.StructIdxBuilt != self.StructCount: return -1 h: uint64 = _struct_ty_hash(tyval) mask: sizet = sizet(self.StructIdxCap - 1) idx: sizet = sizet(h) & mask - i: int = 0 - while i < self.StructIdxCap: - slot: sizet | t.CPtr = (sizet | t.CPtr)(uint64(base) + uint64(idx * 8)) + for i in range(self.StructIdxCap): + slot: sizet* = (sizet*)(uint64(base) + uint64(idx * 8)) sv: sizet = slot[0] if sv == 0: return -1 se: int = int(sv) - 1 - if self._struct_entry_tyval(se) == tyval: - return se + if self._struct_entry_tyval(se) == tyval: return se idx = (idx + 1) & mask - i += 1 return -1 - def _get_field_entry(self, struct_entry: rawptr[GenTypes.StructEntry], i: int) -> rawptr[GenTypes.FieldEntry]: + def _get_field_entry(self, struct_entry: GenTypes.StructEntry*, i: int) -> GenTypes.FieldEntry*: """获取结构体中第 i 个字段条目""" - if struct_entry is None or i < 0 or i >= FIELD_MAX: - return None + 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 rawptr[GenTypes.FieldEntry](addr) + return GenTypes.FieldEntry*(addr) - def register_struct(self, pool: rawptr[memhub.MemBuddy], + def register_struct(self, pool: memhub.MemBuddy*, name: str, - struct_ty: rawptr[llvmlite.LLVMType], - sha1: str = None) -> rawptr[GenTypes.StructEntry]: + struct_ty: llvmlite.LLVMType*, + sha1: str = None) -> GenTypes.StructEntry*: """注册结构体类型,返回 StructEntry 指针 用类型指针去重(is 比较),不用类名去重。 这样跨模块同名类可以共存,各自有独立的字段定义。 sha1 参数在注册时直接设置 ModuleSha1(避免 set_struct_sha1 找错 entry)。 """ - if self.init_struct_table(pool) == 0: - return None - + if self.init_struct_table(pool) == 0: return None # 用类型指针去重(同一类型不重复注册,支持跨模块同名类) # 用 uint64 指针值比较(is 比较会触发类型安全检查解引用悬空 Ty) # 走 find_struct_by_type(其 Ty 索引判定已整体停用、恢复原线性扫描), # 去重语义 = 原去重扫描"首个 Ty 指针相等条目"(首注册优先),逐字节一致。 - existing: rawptr[GenTypes.StructEntry] = self.find_struct_by_type(struct_ty) - if existing is not None: - return existing - + existing: GenTypes.StructEntry* = self.find_struct_by_type(struct_ty) + if existing is not None: return existing if self.StructCount >= STRUCT_MAX: VLogger.error(f"table full, cannot register {name}", "STRUCT") return None - - entry: rawptr[GenTypes.StructEntry] = self._get_struct_entry(self.StructCount) - if entry is None: - return None - + entry: GenTypes.StructEntry* = self._get_struct_entry(self.StructCount) + if entry is None: return None # 分配字段数组(1b 阶段用永久池,避免 reset 回收后 Fields 悬空) field_size: sizet = GenTypes.FieldEntry.__sizeof__() if self.StdlibAlloc != 0: - perm_sg: rawptr[memhub.MemBuddy] = CompilerFactory.factory.PermPool - if perm_sg is None: - perm_sg = pool + perm_sg: memhub.MemBuddy* = CompilerFactory.factory.PermPool + if perm_sg is None: perm_sg = pool entry.Fields = perm_sg.alloc(field_size * FIELD_MAX) else: entry.Fields = pool.alloc(field_size * FIELD_MAX) - if entry.Fields is None: - return None + if entry.Fields is None: return None string.memset(entry.Fields, 0, field_size * FIELD_MAX) - # 复制类名(1b/Phase2(StdlibAlloc=1)用永久池跨 reset 存活;1a 用主 pool, # mark1 前不回收同样存活)。不复制则 find_struct_by_module 的 strcmp 读悬空 Name。 - name_pool: rawptr[memhub.MemBuddy] = pool + name_pool: memhub.MemBuddy* = pool if self.StdlibAlloc != 0: name_pool = CompilerFactory.factory.PermPool - if name_pool is None: - name_pool = pool + if name_pool is None: name_pool = pool name_len: sizet = string.strlen(name) name_buf: str = name_pool.alloc(name_len + 1) if name_buf is not None: string.strcpy(name_buf, name) entry.Name = name_buf - entry.Ty = struct_ty entry.FieldCount = 0 - # 注册时直接设置 SHA1(避免 set_struct_sha1 跨模块同名时找错 entry) # SHA1 同样按 StdlibAlloc 选分配源(跨 1a/1b 存活,防 strcmp 悬空) if sha1 is not None: @@ -435,10 +401,10 @@ class StructGenMixin: self._struct_idx_add(self.StructCount - 1, entry) return entry - def register_struct_alias(self, pool: rawptr[memhub.MemBuddy], + def register_struct_alias(self, pool: memhub.MemBuddy*, name: str, sha1: str, - src_entry: rawptr[GenTypes.StructEntry]) -> rawptr[GenTypes.StructEntry]: + src_entry: GenTypes.StructEntry*) -> GenTypes.StructEntry*: """为已注册类追加包重导出别名 entry(方案A:ast.Attribute 归属 ast 包) 子模块类从包 __init__ 重导出时,查找端 _resolve_module_sha1 按 @@ -450,36 +416,28 @@ class StructGenMixin: 幂等:目标 (name, sha1) 已注册则返回现有 entry。返回 None 失败。 """ - if name is None or sha1 is None or src_entry is None: - return None - if self.init_struct_table(pool) == 0: - return None + if name is None or sha1 is None or src_entry is None: return None + if self.init_struct_table(pool) == 0: return None # 幂等:目标 (name, sha1) 已注册则跳过(find_struct_by_module 不回退裸名) if sha1[0] != '\0': - 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: rawptr[GenTypes.StructEntry] = self._get_struct_entry(self.StructCount) - if entry is None: - return None + existing: 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* = self._get_struct_entry(self.StructCount) + if entry is None: return None # 复制类名与 SHA1(别名注册同样按 StdlibAlloc 选分配源,跨 1a/1b reset 存活) - alias_pool: rawptr[memhub.MemBuddy] = pool + alias_pool: memhub.MemBuddy* = pool if self.StdlibAlloc != 0: alias_pool = CompilerFactory.factory.PermPool - if alias_pool is None: - alias_pool = pool + if alias_pool is None: alias_pool = pool name_len: sizet = string.strlen(name) name_buf: str = alias_pool.alloc(name_len + 1) - if name_buf is None: - return None + if name_buf is None: return None string.strcpy(name_buf, name) entry.Name = name_buf sha1_len: sizet = string.strlen(sha1) sha1_buf: str = alias_pool.alloc(sha1_len + 1) - if sha1_buf is None: - return None + if sha1_buf is None: return None string.strcpy(sha1_buf, sha1) entry.ModuleSha1 = sha1_buf # 复用源 entry 的类型、字段与类属性(同一类,仅归属模块不同) @@ -505,24 +463,22 @@ class StructGenMixin: self._struct_idx_add(self.StructCount - 1, entry) return entry - def set_struct_sha1(self, pool: rawptr[memhub.MemBuddy], - class_name: str, sha1: str) -> int: + def set_struct_sha1(self, pool: memhub.MemBuddy*, class_name: str, sha1: str) -> int: """设置结构体所属模块的 SHA1,返回 1=成功 / 0=失败""" if class_name is None or sha1 is None: return 0 - entry: rawptr[GenTypes.StructEntry] = self.find_struct(class_name) + entry: GenTypes.StructEntry* = self.find_struct(class_name) if entry is None: return 0 # 复制 SHA1 字符串(StdlibAlloc=1 用永久池,跨 1a/1b 存活防 strcmp 悬空) sha1_len: sizet = string.strlen(sha1) - sha1_pool: rawptr[memhub.MemBuddy] = pool + sha1_pool: memhub.MemBuddy* = pool if self.StdlibAlloc != 0: sha1_pool = CompilerFactory.factory.PermPool if sha1_pool is None: sha1_pool = pool sha1_buf: str = sha1_pool.alloc(sha1_len + 1) - if sha1_buf is None: - return 0 + if sha1_buf is None: return 0 string.strcpy(sha1_buf, sha1) entry.ModuleSha1 = sha1_buf return 1 @@ -531,47 +487,41 @@ class StructGenMixin: """获取结构体所属模块的 SHA1,返回 None=无 SHA1""" if class_name is None or self.StructTable is None: return None - entry: rawptr[GenTypes.StructEntry] = self.find_struct(class_name) + entry: 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: rawptr[GenTypes.StructEntry], + def add_field(self, pool: memhub.MemBuddy*, + struct_entry: GenTypes.StructEntry*, field_name: str, - field_ty: rawptr[llvmlite.LLVMType], - default_val: rawptr[ast.AST] = None, + field_ty: llvmlite.LLVMType*, + default_val: ast.AST* = None, annot_class_name: str = None) -> int: """向结构体添加字段,返回字段索引(-1 失败) default_val: 字段默认值 AST 节点(可选,None=无默认值) annot_class_name: 原始类型注解的类名(可选,用于联合类型字段的方法调用解析) """ - if struct_entry is None or field_name is None or field_ty is None: - return -1 - + if struct_entry is None or field_name is None or field_ty is None: return -1 if struct_entry.FieldCount >= FIELD_MAX: VLogger.error(f"field table full for {struct_entry.Name}", "STRUCT") return -1 - idx: int = struct_entry.FieldCount - fe: rawptr[GenTypes.FieldEntry] = self._get_field_entry(struct_entry, idx) - if fe is None: - return -1 - + fe: GenTypes.FieldEntry* = self._get_field_entry(struct_entry, idx) + if fe is None: return -1 # 复制字段名(StdlibAlloc=1 用永久池跨 reset 存活);否则 lookup_field 的 # strcmp(fe.Name, ...) 读悬空越界。 - fname_pool: rawptr[memhub.MemBuddy] = pool + fname_pool: memhub.MemBuddy* = pool if self.StdlibAlloc != 0: fname_pool = CompilerFactory.factory.PermPool - if fname_pool is None: - fname_pool = pool + if fname_pool is None: fname_pool = pool name_len: sizet = string.strlen(field_name) - name_buf: str = fname_pool.alloc(name_len + 1) + # 带调用点 tag:写入者若为该 32B 附近的字段名缓冲,报文直接指名本处。 + name_buf: str = fname_pool.alloc_tagged(name_len + 1, memhub.DETSITE_STRUCTGENMIXIN_570) if name_buf is not None: string.strcpy(name_buf, field_name) fe.Name = name_buf - fe.Index = idx # 1b 阶段(StdlibAlloc=1)字段类型必须深拷贝到 stdlib:字段级 Ty 若仍存 pool # 指针,本文件 reset_to(mark1) 回收后跨文件读取(字段展平、多继承 this 调整、 @@ -579,14 +529,11 @@ class StructGenMixin: # 悬空内存。 # 注:注解类名已并入 Spec.SourceName,Spec 一律 PermPool 分配 ⇒ 天然跨 reset 存活。 if self.StdlibAlloc != 0: - dp_pool_sg: rawptr[memhub.MemBuddy] = CompilerFactory.factory.PermPool - if dp_pool_sg is None: - dp_pool_sg = pool - ty_copy: rawptr[llvmlite.LLVMType] = llvmlite.DeepCopyType(dp_pool_sg, field_ty) - if ty_copy is not None: - fe.Ty = ty_copy - else: - fe.Ty = field_ty + dp_pool_sg: memhub.MemBuddy* = CompilerFactory.factory.PermPool + if dp_pool_sg is None: dp_pool_sg = pool + ty_copy: llvmlite.LLVMType* = llvmlite.DeepCopyType(dp_pool_sg, field_ty) + if ty_copy is not None: fe.Ty = ty_copy + else: fe.Ty = field_ty # DefaultVal:跨文件结构体构造(_translate_struct_ctor→_apply_struct_defaults) # 在调用方文件翻译时读取字段默认值,原 pool AST 已 reset 回收 → 常量深拷贝 # 到 perm_pool(1a 每文件 reset 后 DefaultVal 同样必须跨文件存活) @@ -594,10 +541,8 @@ class StructGenMixin: else: fe.Ty = field_ty fe.DefaultVal = default_val - - # [S3 条目双写] 字段类型 Spec(唯一类型承载,含注解来源名)。TypeSpec # 实例一律 PermPool 分配(驻留或独立副本)⇒ 天然跨 1b reset 存活。 - arena_f: rawptr[TSpec.TypeSpecArena] = self.Gen.TypeGenBase.ensure_spec_arena() + arena_f: 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 @@ -605,19 +550,20 @@ class StructGenMixin: # 类型信息缺失(Spec 为 None)时建 TS_UNKNOWN 承载注解名(不表态具体类型)。 if annot_class_name is not None: if fe.Spec is None: - fe.Spec = TSpec.NewTypeSpec(arena_f, TSpec.TS_UNKNOWN, 0, - TSpec.TS_SIGN_UNKNOWN) + fe.Spec = TSpec.NewTypeSpec(arena_f, TSpec.TS_UNKNOWN, 0, TSpec.TS_SIGN_UNKNOWN) if fe.Spec is not None: sign_f: int = self.Gen.TypeGenCType.spec_sign_of_annot(annot_class_name) if sign_f != TSpec.TS_SIGN_UNKNOWN: fe.Spec = TSpec.SpecWithSign(arena_f, fe.Spec, sign_f) fe.Spec = TSpec.SpecWithSource(fe.Spec, annot_class_name) + # const 标记显式置 0(不依赖条目内存的零初值约定):本字段由 ClassGenDef + # 在确认为 const 对象时才置 1,显式清零杜绝"未初始化即被读成 1"的误报。 + fe.IsConst = 0 struct_entry.FieldCount = idx + 1 return idx - def _deep_copy_default_ast(self, pool: rawptr[memhub.MemBuddy], - default_val: rawptr[ast.AST]) -> rawptr[ast.AST]: + def _deep_copy_default_ast(self, pool: memhub.MemBuddy*, default_val: ast.AST*) -> ast.AST*: """深拷贝字段默认值 AST 到永久池(仅常量节点),跨 1b reset 存活。 字段默认值(fe.DefaultVal)除定义文件内 _generate_before_init 使用外, @@ -628,21 +574,30 @@ class StructGenMixin: (调用方 fe.DefaultVal 保持 None,仅定义文件内 _generate_before_init 仍持有原始 pool 指针,不受影响)。 """ - if default_val is None: - return None - if default_val.kind() == ast.ASTKind.List: - return self._deep_copy_list_ast(pool, default_val) - if default_val.kind() != ast.ASTKind.Constant: - return None - src_c: rawptr[ast.Constant] = rawptr[ast.Constant](default_val) - dst_c: rawptr[ast.Constant] = rawptr[ast.Constant]( - pool.alloc(ast.Constant.__sizeof__())) + if default_val is None: return None + if default_val.kind() == ast.ASTKind.List: return self._deep_copy_list_ast(pool, default_val) + if default_val.kind() != ast.ASTKind.Constant: return None + src_c: ast.Constant* = ast.Constant*(default_val) + dst_c: ast.Constant* = ast.Constant*( + pool.alloc_tagged(ast.Constant.__sizeof__(), memhub.DETSITE_STRUCTGENMIXIN_641)) if dst_c is None: return None string.memset(dst_c, 0, ast.Constant.__sizeof__()) # 拷贝 vtable 指针(AST 是 @t.CVTable,kind() 虚调用依赖首字段 vptr) - vt_ptr: t.CPtr = t.CPtr(c.Deref((uint64 | t.CPtr)(default_val))) - c.DerefAs(dst_c, vt_ptr) + # 【必须与 _deep_copy_list_ast 同款:c.Deref 读首字 + c.DerefAs 写首字】 + # 旧写法(本行 + 下一行)在 TPC 下**静默失效**,是 vptr=0 AST 节点的产生源: + # ① `vt_ptr: rawptr = rawptr(*(uint64*)(default_val))` 被折成裸 0 + # ——IR 实证 `inttoptr i32 0 to i8*`(**没有 load vptr 的指令**); + # ② `*dst_c = vt_ptr`(目标 LHS 是结构体类型的解引用)**根本不发射任何 + # 指令**——全模块无任何指令带 `!dbg !425`。 + # ⇒ dst_c 的前 8 字节保持 memset 的 0(vptr = 0),随后对它的 + # `node.kind()` 虚调用生成 `load i8*, i8** [0 + 0]` ⇒ ASan READ at 0x0。 + # 逐字 IR 证据:`TransPyV\output\b5883dc9c114a604.ll:10382-10384` + # (!424 = 本函数 :587 行;!426 = :590 行;两者之间无任何指令)。 + # 对照可用写法(List 分支,同文件 :10611-10615):`bitcast AST* → i64*` + + # `load i64` + `inttoptr i64 → i8*` + `bitcast List* → i8**` + `store i8*`。 + vt_ptr_c: t.CPtr = t.CPtr(c.Deref((uint64*)(default_val))) + c.DerefAs(dst_c, vt_ptr_c) # 拷贝位置字段(报错定位用) dst_c.lineno = src_c.lineno dst_c.col_offset = src_c.col_offset @@ -654,28 +609,25 @@ class StructGenMixin: dst_c.float_val = src_c.float_val if src_c.str_val is not None: s_len: sizet = string.strlen(src_c.str_val) - s_copy: str = pool.alloc(s_len + 1) + s_copy: str = pool.alloc_tagged(s_len + 1, memhub.DETSITE_STRUCTGENMIXIN_659) if s_copy is not None: string.strcpy(s_copy, src_c.str_val) dst_c.str_val = s_copy - return (rawptr[ast.AST])(dst_c) + return (ast.AST*)(dst_c) - def _deep_copy_list_ast(self, pool: rawptr[memhub.MemBuddy], - default_val: rawptr[ast.AST]) -> rawptr[ast.AST]: + def _deep_copy_list_ast(self, pool: memhub.MemBuddy*, default_val: ast.AST*) -> ast.AST*: """深拷贝 List 节点(列表字面量默认值)到永久池,跨 1b reset 存活。 elts 容器手动在永久池构造(list 的 __pool__ 置 None:深拷贝的 elts 只被只读访问 get/__len__/迭代,不 append,不会触发 pool 扩容)。 元素递归调用 _deep_copy_default_ast(支持 Constant 与嵌套 List)。 """ - 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 + src_l: ast.List* = ast.List*(default_val) + dst_l: ast.List* = ast.List*(pool.alloc(ast.List.__sizeof__())) + if dst_l is None: return None string.memset(dst_l, 0, ast.List.__sizeof__()) # 拷贝 vtable 指针(AST 是 @t.CVTable,kind() 虚调用依赖首字段 vptr) - vt_l: t.CPtr = t.CPtr(c.Deref((uint64 | t.CPtr)(default_val))) + vt_l: t.CPtr = t.CPtr(c.Deref((uint64*)(default_val))) c.DerefAs(dst_l, vt_l) # 拷贝位置字段与 ctx dst_l.lineno = src_l.lineno @@ -688,27 +640,70 @@ class StructGenMixin: if src_elts_l is not None: cnt_l: sizet = len(src_elts_l) lst_copy_l: list[ast.AST*]* = (list[ast.AST*] | t.CPtr)( - pool.alloc(list[rawptr[ast.AST]].__sizeof__())) + pool.alloc_tagged(list[ast.AST*].__sizeof__(), memhub.DETSITE_STRUCTGENMIXIN_693)) if lst_copy_l is not None: - string.memset(lst_copy_l, 0, list[rawptr[ast.AST]].__sizeof__()) - lst_copy_l.__count__ = cnt_l + string.memset(lst_copy_l, 0, list[ast.AST*].__sizeof__()) + # 计数**绝不先按源计数写死**:必须在填充循环里按"实际写入槽数"落定 + # (下方 written_l)。否则源元素为空指针 / 不可深拷贝而被静默跳过时, + # 会留下 __count__ > 实际填充数 的零槽 ⇒ 后续 _init_global_array_from_list + # 的 elts.get(i) 读到裸 0 ⇒ 空 AST 元素崩溃(ASan access-violation 0x0)。 + # 本处只先定容量。 lst_copy_l.__capacity__ = cnt_l - lst_copy_l.__elem_size__ = 8 + # 元素尺寸的唯一真相源:申请(cnt_l * elem_sz_l)、清零(同式)与 + # 写入(槽基址按 elem_sz_l 步进)必须同源;写成两处字面量 8 会让 + # "申请 n*8 却按别的宽度写"重新变得可能。 + elem_sz_l: sizet = 8 + lst_copy_l.__elem_size__ = elem_sz_l lst_copy_l.__pool__ = None - data_l: t.CPtr = pool.alloc(cnt_l * 8) + data_l: t.CPtr = pool.alloc_tagged(cnt_l * elem_sz_l, + memhub.DETSITE_STRUCTGENMIXIN_698) if data_l is not None: - string.memset(data_l, 0, cnt_l * 8) + string.memset(data_l, 0, cnt_l * elem_sz_l) lst_copy_l.__data__ = data_l + written_l: sizet = 0 li_l: sizet for li_l in range(cnt_l): - elem_src_l: rawptr[ast.AST] = src_elts_l.get(li_l) - if elem_src_l is not None: - elem_dst_l: rawptr[ast.AST] = self._deep_copy_default_ast(pool, elem_src_l) - if elem_dst_l is not None: - slot_l: rawptr[ast.AST] = (rawptr[ast.AST])(uint64(data_l) + li_l * 8) - slot_l[0] = elem_dst_l + elem_src_l: ast.AST* = src_elts_l.get(li_l) + # 显式判空(本仓硬约定:指针判空一律 `is None`)。上一轮曾写作 + # 整型字面量比较 `elem_src_l == 0` 并附注"与 `is None` 同义": + # 该注的 IR 事实对(`x == 0` 同样编译为 `icmp eq , null`, + # 逐字证据见 AssignGenMixin.vp:1126-1145 记录的反例现场), + # 但结论表述误导——`== 0` 并非无效判据,只是不该作为本仓判空写法。 + # 源列表自身存在空元素,说明产生源已损坏(计数 > 实际填充) + # ——响亮失败,绝不静默补 0。 + if elem_src_l is None: + self.Gen.TypeGenErr.fatal_error( + default_val, + f"字段默认值深拷贝:列表字面量第 {li_l} 个元素为空 AST 元素(指针为 0)。" + f"上层某处产生了空 AST 元素(元素计数与实际填充不一致)," + f"拒绝静默补 0 生成残缺的默认值;已终止编译。", + "ValueError") + return None + elem_dst_l: ast.AST* = self._deep_copy_default_ast(pool, elem_src_l) + if elem_dst_l is None: + self.Gen.TypeGenErr.fatal_error( + elem_src_l, + f"字段默认值深拷贝:列表字面量第 {li_l} 个元素(kind={elem_src_l.kind()})" + f"既非 Constant 也非 List,无法深拷贝到永久池。若在此静默跳过该槽," + f"会形成【计数 > 实际填充数】的空槽(后续 elts.get 读到裸 0 崩溃);" + f"若静默截短计数则会改变数组初始化长度。两者都是静默降级,故响亮失败。", + "TypeError") + return None + # 槽元素类型必须是**指针**:`ast.AST*` 的 `[0]` 是 + # 对象 `ast.AST`(48 字节)⇒ `slot[0] = <指针>` 被静默按 + # "结构体赋值"编译成 48 字节 load + 48 字节 store,而本 + # 缓冲只申请 cnt_l*elem_sz_l ⇒ 每槽越界 40 字节,写穿本块 + # canary 与右邻空闲块首字(三代 [FREEFRAME] 现场根因)。 + # 按本仓既有合并规则(hashtable.vp:82-85):`X | t.CPtr` + # = Ptr(resolve(X)) ⇒ 取下标得到**指针元素** ⇒ 8 字节 + # 指针 store,与申请宽度同源。 + slot_l: ast.AST** = (ast.AST**)(uint64(data_l) + li_l * elem_sz_l) + slot_l[0] = elem_dst_l + written_l += 1 + # 计数 == 实际填充数(成功时 == cnt_l;任何不一致都已在上面终止)。 + lst_copy_l.__count__ = written_l dst_l.elts = lst_copy_l - return (rawptr[ast.AST])(dst_l) + return (ast.AST*)(dst_l) def get_struct_count(self) -> int: """返回当前已注册的结构体数量""" @@ -730,8 +725,7 @@ class StructGenMixin: 3. LookupSha1ByModNameSuffix:后缀匹配(store 键是全路径模块名, 如 "Kernel.drivers.fs.fat32.fat32_types"),非别名裸名兜底 """ - if mod_name is None: - return None + if mod_name is None: return None s_rm: str = StubMergerStore.LookupSha1ByModName(mod_name) if s_rm is None and from_imports is not None: real_rm: str = StubMergerStore.LookupModNameByAlias(from_imports, mod_name) @@ -743,7 +737,7 @@ class StructGenMixin: s_rm = StubMergerStore.LookupSha1ByModNameSuffix(mod_name) return s_rm - def find_struct(self, name: str) -> rawptr[GenTypes.StructEntry]: + def find_struct(self, name: str) -> GenTypes.StructEntry*: """按类名查找结构体,返回 StructEntry 或 None 支持模块限定名(如 "HT.Translator"): @@ -761,8 +755,7 @@ class StructGenMixin: stdlib.exit(1) # 名索引快速路径:命中即首注册下标(语义 = 原精确匹配扫描首个命中)。 fi: int = self._struct_name_idx_find(name) - if fi >= 0: - return self._get_struct_entry(fi) + if fi >= 0: return self._get_struct_entry(fi) # 名索引可信(Built==StructCount | 索引存在 | 查询名非空)时,索引未命中即 # "确无同名条目":条目在注册时即命名并同步入索引,之后名至多被中和为 "" # (ClassGenDef/ClassGenEnum 置 Name[0]=0),故任何非空查询名的命中项必在 @@ -770,12 +763,11 @@ class StructGenMixin: # 全部 strcmp)。索引不可信 / 无索引 / 空名查询时仍回退原线性扫描 # (正确性保证,非兜底);精确匹配确无时继续走模块限定名/裸名回退逻辑。 name_idx_trusted: int = 0 - if self.StructNameIdx is not None and self.StructIdxCap > 0 \ - and self.StructIdxBuilt == self.StructCount: + if self.StructNameIdx is not None and self.StructIdxCap > 0 and self.StructIdxBuilt == self.StructCount: name_idx_trusted = 1 if name_idx_trusted == 0 or name[0] == '\0': for i in range(self.StructCount): - entry: rawptr[GenTypes.StructEntry] = self._get_struct_entry(i) + entry: 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 +797,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: rawptr[GenTypes.StructEntry] = \ + me_h: 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: rawptr[GenTypes.StructEntry] = \ + me_f: 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: rawptr[GenTypes.StructEntry] = None + same_entry_f: GenTypes.StructEntry* = None for i2 in range(self.StructCount): - e2: rawptr[GenTypes.StructEntry] = self._get_struct_entry(i2) + e2: 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 +832,9 @@ class StructGenMixin: # 与 App gfx 都定义 Scene3D)存在时不得返回先注册的错误 entry——否则 # 模块段无法解析的限定名被劫持到错误模块 → 返回类型解析查错 text.ll。 same_cnt_b: int = 0 - same_entry_b: rawptr[GenTypes.StructEntry] = None + same_entry_b: GenTypes.StructEntry* = None for i in range(self.StructCount): - entry: rawptr[GenTypes.StructEntry] = self._get_struct_entry(i) + entry: 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 +843,7 @@ class StructGenMixin: return same_entry_b return None - def find_struct_by_module(self, name: str, sha1: str) -> rawptr[GenTypes.StructEntry]: + def find_struct_by_module(self, name: str, sha1: str) -> GenTypes.StructEntry*: """按类名 + SHA1 查找结构体,返回 StructEntry 或 None SHA1 非 None 时:精确匹配 name+sha1,未找到返回 None(不回退,避免跨模块同名找错) @@ -872,7 +864,7 @@ class StructGenMixin: if fri >= 0: start = fri for i in range(start, self.StructCount): - entry: rawptr[GenTypes.StructEntry] = self._get_struct_entry(i) + entry: 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 +898,7 @@ class StructGenMixin: return 0 reset_count: int = 0 for i in range(self.StructCount): - entry: rawptr[GenTypes.StructEntry] = self._get_struct_entry(i) + entry: GenTypes.StructEntry* = self._get_struct_entry(i) if entry is not None: # 普通类按 ModuleSha1 匹配 if entry.ModuleSha1 is not None: @@ -923,7 +915,7 @@ class StructGenMixin: reset_count += 1 return reset_count - def find_struct_by_type(self, struct_ty: rawptr[llvmlite.LLVMType]) -> rawptr[GenTypes.StructEntry]: + def find_struct_by_type(self, struct_ty: llvmlite.LLVMType*) -> GenTypes.StructEntry*: """按类型指针查找结构体(指针值比较),返回 StructEntry 或 None 注意: 不能用 `entry.Ty is struct_ty` 的 is 比较——TPV 编译 is 时会触发 @@ -944,13 +936,13 @@ class StructGenMixin: # 首个 Ty 相等条目",命中路径与原语义不等价、且无法低成本保证等价。故此处 # 恢复原线性精确扫描(未命中/命中行为均与未加索引前逐字节一致)。 for i in range(self.StructCount): - entry: rawptr[GenTypes.StructEntry] = self._get_struct_entry(i) + entry: 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 return None - def struct_type_is_packed(self, struct_ty: rawptr[llvmlite.LLVMType]) -> int: + def struct_type_is_packed(self, struct_ty: llvmlite.LLVMType*) -> int: """判断命名结构体是否 packed(@c.Attribute(t.attr.packed)),返回 1/0 先按类型指针身份匹配(find_struct_by_type,跨模块 deep copy 后仍 @@ -963,15 +955,15 @@ class StructGenMixin: sname: str = llvmlite.get_struct_name(struct_ty) if sname is None: return 0 - entry: rawptr[GenTypes.StructEntry] = self.find_struct_by_type(struct_ty) + entry: GenTypes.StructEntry* = self.find_struct_by_type(struct_ty) if entry is None: entry = self.find_struct(sname) if entry is None: return 0 return entry.IsPacked - def lookup_field(self, struct_ty: rawptr[llvmlite.LLVMType], - field_name: str) -> rawptr[GenTypes.FieldEntry]: + def lookup_field(self, struct_ty: llvmlite.LLVMType*, + field_name: str) -> GenTypes.FieldEntry*: """按结构体类型和字段名查找字段信息 两遍查找策略(跨模块同名类冲突的根本修复): @@ -997,10 +989,10 @@ class StructGenMixin: # find_struct_by_type 的语义 = 原扫描"首个 Ty 指针相等条目"(首注册优先); # 其 Ty 索引判定已整体停用、恢复原线性扫描 ⇒ 选中的 entry 与原 is 身份扫描 # 完全一致。类型唯一确定 entry:命中后查字段,字段未找到直接返回 None。 - lk_entry: rawptr[GenTypes.StructEntry] = self.find_struct_by_type(struct_ty) + lk_entry: GenTypes.StructEntry* = self.find_struct_by_type(struct_ty) if lk_entry is not None: for fi in range(lk_entry.FieldCount): - fe: rawptr[GenTypes.FieldEntry] = self._get_field_entry(lk_entry, fi) + fe: 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 +1010,7 @@ class StructGenMixin: if GenApi.sha1_prefix_len(ty_name) != 0: ty_has_sha1_lf = 1 for i in range(self.StructCount): - entry: rawptr[GenTypes.StructEntry] = self._get_struct_entry(i) + entry: GenTypes.StructEntry* = self._get_struct_entry(i) if entry is not None and entry.Name is not None: # 类型名带 SHA1 前缀:必须与 entry.ModuleSha1 前 16 字符 # 精确一致,否则跳过(跨模块同名类命名空间隔离) @@ -1035,7 +1027,7 @@ class StructGenMixin: if matched != 0: # 查找字段 for fi in range(entry.FieldCount): - fe: rawptr[GenTypes.FieldEntry] = self._get_field_entry(entry, fi) + fe: 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 @@ -1062,20 +1054,16 @@ class StructGenMixin: while i > 0: i -= 1 ch: char = s[i] - if ch == ']': - depth += 1 - elif ch == '[': - if depth > 0: - depth -= 1 - elif ch == '.' and depth == 0: - return s + i + if ch == ']': depth += 1 + elif ch == '[' and depth > 0: depth -= 1 + elif ch == '.' and depth == 0: return s + i return None def lookup_field_by_class(self, class_name: str, field_name: str, sha1: str = None, - node: rawptr[ast.AST] = None, - from_imports: str = None) -> rawptr[GenTypes.FieldEntry]: + node: ast.AST* = None, + from_imports: str = None) -> GenTypes.FieldEntry*: """按类名和字段名查找字段信息 优先用 SHA1 匹配(跨模块同名类区分),无 SHA1 时按类名查找第一个。 @@ -1084,9 +1072,7 @@ class StructGenMixin: from_imports: from-import 映射("local:module" 格式),供模块限定名 的 import 别名(import X as Y → Y.Class)解析为模块 sha1 """ - if class_name is None or field_name is None: - return None - + if class_name is None or field_name is None: return None # 优先用 SHA1 匹配(跨模块同名类区分) # 支持模块限定名:class_name 可能是 "HT.Translator",entry.Name 是 "Translator" # 先精确匹配,失败后用 strrchr 提取类名部分回退匹配 @@ -1101,7 +1087,7 @@ class StructGenMixin: if bare_name is None or bare_name[0] == '\0': bare_name = class_name for i in range(self.StructCount): - entry: rawptr[GenTypes.StructEntry] = self._get_struct_entry(i) + entry: GenTypes.StructEntry* = self._get_struct_entry(i) if entry is not None and entry.Name is not None: # 精确匹配或类名回退匹配 name_match: int = 0 @@ -1115,7 +1101,7 @@ class StructGenMixin: sha1_matched = 1 # SHA1 + 类名匹配,查找字段 for fi in range(entry.FieldCount): - fe: rawptr[GenTypes.FieldEntry] = self._get_field_entry(entry, fi) + fe: 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 +1145,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: rawptr[GenTypes.StructEntry] = \ + mod_entry_q: GenTypes.StructEntry* = \ self.find_struct_by_module(bare_q, mod_sha1_q) if mod_entry_q is not None: # 依赖未就绪容忍(对齐裸名路径):FieldCount==0 的空类 @@ -1169,7 +1155,7 @@ class StructGenMixin: stdlib.free(mod_buf_q) return None for fi_q in range(mod_entry_q.FieldCount): - fe_q: rawptr[GenTypes.FieldEntry] = \ + fe_q: 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 +1181,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: rawptr[GenTypes.FieldEntry] = \ + rn_fe_q: 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 +1215,7 @@ class StructGenMixin: return None # 先查找字段(诊断/error 之前返回,否则 error 立即退出导致查找永远失败) for fi in range(entry.FieldCount): - fe: rawptr[GenTypes.FieldEntry] = self._get_field_entry(entry, fi) + fe: 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 +1241,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: rawptr[GenTypes.FieldEntry] = \ + rn_fe_l: 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 +1251,7 @@ class StructGenMixin: if fb_flds_lst is not None: fb_flds_lst[0] = '\0' for fi in range(entry.FieldCount): - fe: rawptr[GenTypes.FieldEntry] = self._get_field_entry(entry, fi) + fe: 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, ", ") @@ -1302,19 +1288,19 @@ class StructGenMixin: # 诊断:找到结构体但字段未找到 return None - def get_struct_type(self, class_name: str) -> rawptr[llvmlite.LLVMType]: + def get_struct_type(self, class_name: str) -> llvmlite.LLVMType*: """按类名获取结构体的 LLVM 类型""" - entry: rawptr[GenTypes.StructEntry] = self.find_struct(class_name) + entry: 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) -> rawptr[GenTypes.FieldEntry]: + idx: int) -> GenTypes.FieldEntry*: """按类名和字段索引获取字段信息""" if class_name is None: return None - entry: rawptr[GenTypes.StructEntry] = self.find_struct(class_name) + entry: GenTypes.StructEntry* = self.find_struct(class_name) if entry is None: return None if idx < 0 or idx >= entry.FieldCount: @@ -1325,16 +1311,16 @@ class StructGenMixin: """检查结构体是否有任何带默认值的字段,返回 1=有 / 0=无""" if class_name is None: return 0 - entry: rawptr[GenTypes.StructEntry] = self.find_struct(class_name) + entry: GenTypes.StructEntry* = self.find_struct(class_name) if entry is None: return 0 for fi in range(entry.FieldCount): - fe: rawptr[GenTypes.FieldEntry] = self._get_field_entry(entry, fi) + fe: 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: rawptr[llvmlite.Value]) -> rawptr[llvmlite.LLVMType]: + def get_struct_type_from_value(self, val: llvmlite.Value*) -> llvmlite.LLVMType*: """从 Value 的类型推断结构体类型 递归解 Ptr:支持 X|t.CPtr 联合简化产生的 Ptr(Ptr(Struct)) 对象指针 @@ -1344,13 +1330,13 @@ class StructGenMixin: """ if val is None or val.Ty is None: return None - ty: rawptr[llvmlite.LLVMType] = val.Ty + ty: llvmlite.LLVMType* = val.Ty while ty is not None: # 同类编译 bug(见 TypeGenResolve L1463 注释):case body 直接 # 更新 while 条件变量(ty = pointee)时自举编译出的 match 把赋值 # 写到 subject 快照槽,while 条件读旧槽 → 死循环。改法:case # 绑定到局部变量,match 外更新循环变量。 - nxt_ty: rawptr[llvmlite.LLVMType] = None + nxt_ty: llvmlite.LLVMType* = None match ty: case llvmlite.LLVMType.Ptr(pointee): nxt_ty = pointee @@ -1365,7 +1351,7 @@ class StructGenMixin: """标记已注册的结构体为联合体,返回 1=成功 / 0=失败""" if name is None: return 0 - entry: rawptr[GenTypes.StructEntry] = self.find_struct(name) + entry: GenTypes.StructEntry* = self.find_struct(name) if entry is None: return 0 entry.IsUnion = 1 @@ -1375,12 +1361,12 @@ class StructGenMixin: """按类名检查是否为联合体,返回 1=是 / 0=否""" if name is None: return 0 - entry: rawptr[GenTypes.StructEntry] = self.find_struct(name) + entry: GenTypes.StructEntry* = self.find_struct(name) if entry is None: return 0 return entry.IsUnion - def is_union_by_type(self, struct_ty: rawptr[llvmlite.LLVMType]) -> int: + def is_union_by_type(self, struct_ty: llvmlite.LLVMType*) -> int: """按类型指针检查是否为联合体,返回 1=是 / 0=否 先尝试类型指针 == 比较,失败时回退到名称匹配 @@ -1390,7 +1376,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: rawptr[GenTypes.StructEntry] = self._get_struct_entry(i) + entry: 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 +1394,7 @@ class StructGenMixin: """标记已注册的结构体为 OOP,返回 1=成功 / 0=失败""" if name is None: return 0 - entry: rawptr[GenTypes.StructEntry] = self.find_struct(name) + entry: GenTypes.StructEntry* = self.find_struct(name) if entry is None: return 0 entry.IsOOP = 1 @@ -1418,7 +1404,7 @@ class StructGenMixin: """按类名检查是否为 OOP 结构体,返回 1=是 / 0=否""" if name is None: return 0 - entry: rawptr[GenTypes.StructEntry] = self.find_struct(name) + entry: GenTypes.StructEntry* = self.find_struct(name) if entry is None: return 0 return entry.IsOOP @@ -1427,7 +1413,7 @@ class StructGenMixin: """标记结构体拥有 __init__ 方法,返回 1=成功 / 0=失败""" if name is None: return 0 - entry: rawptr[GenTypes.StructEntry] = self.find_struct(name) + entry: GenTypes.StructEntry* = self.find_struct(name) if entry is None: return 0 entry.HasInit = 1 @@ -1437,7 +1423,7 @@ class StructGenMixin: """按类名检查是否有 __init__ 方法,返回 1=有 / 0=无""" if name is None: return 0 - entry: rawptr[GenTypes.StructEntry] = self.find_struct(name) + entry: GenTypes.StructEntry* = self.find_struct(name) if entry is None: return 0 return entry.HasInit @@ -1446,7 +1432,7 @@ class StructGenMixin: """标记结构体拥有 __new__ 方法,返回 1=成功 / 0=失败""" if name is None: return 0 - entry: rawptr[GenTypes.StructEntry] = self.find_struct(name) + entry: GenTypes.StructEntry* = self.find_struct(name) if entry is None: return 0 entry.HasNew = 1 @@ -1456,19 +1442,19 @@ class StructGenMixin: """按类名检查是否有 __new__ 方法,返回 1=有 / 0=无""" if name is None: return 0 - entry: rawptr[GenTypes.StructEntry] = self.find_struct(name) + entry: GenTypes.StructEntry* = self.find_struct(name) if entry is None: return 0 return entry.HasNew - def get_class_name_by_type(self, pool: rawptr[memhub.MemBuddy], - struct_ty: rawptr[llvmlite.LLVMType]) -> str: + def get_class_name_by_type(self, pool: memhub.MemBuddy*, + struct_ty: llvmlite.LLVMType*) -> str: """按类型指针查找类名,返回类名字符串或 None""" if struct_ty is None or self.StructTable is None: return None # find_struct_by_type 的语义 = 原扫描"首个 Ty 指针相等条目"(首注册优先), # 返回其 Name;其 Ty 索引判定已整体停用、恢复原线性扫描 ⇒ 逐字节一致。 - fast_cn: rawptr[GenTypes.StructEntry] = self.find_struct_by_type(struct_ty) + fast_cn: GenTypes.StructEntry* = self.find_struct_by_type(struct_ty) if fast_cn is not None: return fast_cn.Name # 回退: 类型指针比较失败时,遍历所有注册的结构体按名称匹配 @@ -1476,7 +1462,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: rawptr[GenTypes.StructEntry] = self._get_struct_entry(j) + entry2: 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 @@ -1509,7 +1495,7 @@ class StructGenMixin: return entry2.Name return None - def _extract_struct_name(self, ty: rawptr[llvmlite.LLVMType]) -> str: + def _extract_struct_name(self, ty: llvmlite.LLVMType*) -> str: """从 LLVMType 提取 Struct 变体的 Name 字段,返回 None 非 Struct""" if ty is None: return None @@ -1523,7 +1509,7 @@ class StructGenMixin: """标记结构体拥有虚表,返回 1=成功 / 0=失败""" if name is None: return 0 - entry: rawptr[GenTypes.StructEntry] = self.find_struct(name) + entry: GenTypes.StructEntry* = self.find_struct(name) if entry is None: return 0 entry.HasVTable = 1 @@ -1533,7 +1519,7 @@ class StructGenMixin: """按类名检查是否有虚表,返回 1=有 / 0=无""" if name is None: return 0 - entry: rawptr[GenTypes.StructEntry] = self.find_struct(name) + entry: GenTypes.StructEntry* = self.find_struct(name) if entry is None: return 0 return entry.HasVTable @@ -1542,7 +1528,7 @@ class StructGenMixin: """标记结构体为 NoVTable,返回 1=成功 / 0=失败""" if name is None: return 0 - entry: rawptr[GenTypes.StructEntry] = self.find_struct(name) + entry: GenTypes.StructEntry* = self.find_struct(name) if entry is None: return 0 entry.IsNoVTable = 1 @@ -1552,7 +1538,7 @@ class StructGenMixin: """按类名检查是否为 NoVTable,返回 1=是 / 0=否""" if name is None: return 0 - entry: rawptr[GenTypes.StructEntry] = self.find_struct(name) + entry: GenTypes.StructEntry* = self.find_struct(name) if entry is None: return 0 return entry.IsNoVTable @@ -1561,19 +1547,19 @@ class StructGenMixin: """设置结构体的父类名,返回 1=成功 / 0=失败""" if name is None: return 0 - entry: rawptr[GenTypes.StructEntry] = self.find_struct(name) + entry: GenTypes.StructEntry* = self.find_struct(name) if entry is None: return 0 entry.ParentName = parent_name return 1 - def set_parent_names(self, pool: rawptr[memhub.MemBuddy], - name: str, names_ptr: sizet | t.CPtr, + def set_parent_names(self, pool: memhub.MemBuddy*, + name: str, names_ptr: sizet*, count: int) -> int: """设置结构体的父类名数组(永久池深拷贝,跨文件永久存活)""" if name is None: return 0 - entry: rawptr[GenTypes.StructEntry] = self.find_struct(name) + entry: GenTypes.StructEntry* = self.find_struct(name) if entry is None: return 0 if names_ptr is None or count <= 0: @@ -1582,12 +1568,12 @@ class StructGenMixin: return 1 if count > PARENT_MAX: count = PARENT_MAX - pn_pool: rawptr[memhub.MemBuddy] = pool + pn_pool: memhub.MemBuddy* = pool if self.StdlibAlloc != 0: pn_pool = CompilerFactory.factory.PermPool if pn_pool is None: pn_pool = pool - arr: sizet | t.CPtr = pn_pool.alloc(8 * count) + arr: sizet* = pn_pool.alloc(8 * count) if arr is None: return 0 for i in range(count): @@ -1609,7 +1595,7 @@ class StructGenMixin: """获取父类数量(0=无父类,1=单继承,>1=多继承)""" if name is None: return 0 - entry: rawptr[GenTypes.StructEntry] = self.find_struct(name) + entry: GenTypes.StructEntry* = self.find_struct(name) if entry is None: return 0 return entry.ParentCount @@ -1618,29 +1604,29 @@ class StructGenMixin: """获取第 idx 个父类名,越界返回 None""" if name is None or idx < 0: return None - entry: rawptr[GenTypes.StructEntry] = self.find_struct(name) + entry: GenTypes.StructEntry* = self.find_struct(name) if entry is None or entry.ParentNames is None: return None if idx >= entry.ParentCount: return None - parr: sizet | t.CPtr = (sizet | t.CPtr)(entry.ParentNames) + parr: sizet* = (sizet*)(entry.ParentNames) addr: sizet = parr[idx] if addr == 0: return None return (str | t.CPtr)(addr) - def get_mro_chain(self, pool: rawptr[memhub.MemBuddy], - name: str) -> sizet | t.CPtr: + def get_mro_chain(self, pool: memhub.MemBuddy*, + name: str) -> sizet*: """MRO 线性化类名数组(深度优先 + 声明顺序 + 去重,含自身)""" if pool is None or name is None: return None - arr: sizet | t.CPtr = pool.alloc(8 * (MRO_MAX + 1)) + arr: sizet* = pool.alloc(8 * (MRO_MAX + 1)) if arr is None: return None - stack: sizet | t.CPtr = pool.alloc(8 * MRO_MAX) + stack: sizet* = pool.alloc(8 * MRO_MAX) if stack is None: return None - visited: sizet | t.CPtr = pool.alloc(8 * MRO_MAX) + visited: sizet* = pool.alloc(8 * MRO_MAX) if visited is None: return None stack_count: int = 0 @@ -1674,10 +1660,10 @@ class StructGenMixin: visited[visit_count] = sizet(cur) visit_count += 1 # 父类逆序压栈(正向 range 计算逆序索引,保证声明顺序弹出) - entry: rawptr[GenTypes.StructEntry] = self.find_struct(cur) + entry: 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) + parr: sizet* = (sizet*)(entry.ParentNames) for pi2 in range(pc): pi: int = pc - 1 - pi2 if stack_count < MRO_MAX: @@ -1691,7 +1677,7 @@ class StructGenMixin: """获取结构体的父类名,返回 None=无父类""" if name is None: return None - entry: rawptr[GenTypes.StructEntry] = self.find_struct(name) + entry: GenTypes.StructEntry* = self.find_struct(name) if entry is None: return None return entry.ParentName @@ -1700,7 +1686,7 @@ class StructGenMixin: """设置虚表方法名数组,返回 1=成功 / 0=失败""" if name is None: return 0 - entry: rawptr[GenTypes.StructEntry] = self.find_struct(name) + entry: GenTypes.StructEntry* = self.find_struct(name) if entry is None: return 0 entry.VTableMethods = methods @@ -1711,12 +1697,12 @@ class StructGenMixin: """获取方法在虚表中的索引,返回 -1=未找到""" if name is None or method_name is None: return -1 - entry: rawptr[GenTypes.StructEntry] = self.find_struct(name) + entry: GenTypes.StructEntry* = self.find_struct(name) if entry is None or entry.VTableMethods is None: return -1 # VTableMethods 字段声明为 char*,但实际存储的是 sizet 数组 # 必须转换为 sizet* 才能正确读取 8 字节指针值 - methods_arr: sizet | t.CPtr = (sizet | t.CPtr)(entry.VTableMethods) + methods_arr: sizet* = (sizet*)(entry.VTableMethods) for i in range(entry.VTableMethodCount): mname_addr: sizet = methods_arr[i] if mname_addr == 0: @@ -1730,7 +1716,7 @@ class StructGenMixin: """获取虚表方法数量""" if name is None: return 0 - entry: rawptr[GenTypes.StructEntry] = self.find_struct(name) + entry: GenTypes.StructEntry* = self.find_struct(name) if entry is None: return 0 return entry.VTableMethodCount @@ -1739,12 +1725,12 @@ class StructGenMixin: """获取虚表中第 idx 个方法名,返回 None=越界""" if name is None or idx < 0: return None - entry: rawptr[GenTypes.StructEntry] = self.find_struct(name) + entry: GenTypes.StructEntry* = self.find_struct(name) if entry is None or entry.VTableMethods is None: return None if idx >= entry.VTableMethodCount: return None - methods_arr: sizet | t.CPtr = (sizet | t.CPtr)(entry.VTableMethods) + methods_arr: sizet* = (sizet*)(entry.VTableMethods) mname_addr: sizet = methods_arr[idx] if mname_addr == 0: return None @@ -1754,14 +1740,14 @@ class StructGenMixin: """获取结构体字段数量,返回 -1=未找到""" if name is None: return -1 - entry: rawptr[GenTypes.StructEntry] = self.find_struct(name) + entry: GenTypes.StructEntry* = self.find_struct(name) if entry is None: return -1 return entry.FieldCount - def ensure_struct_def_in_module(self, pool: rawptr[memhub.MemBuddy], - mod: rawptr[llvmlite.LLVMModule], - ty: rawptr[llvmlite.LLVMType]): + def ensure_struct_def_in_module(self, pool: memhub.MemBuddy*, + mod: llvmlite.LLVMModule*, + ty: llvmlite.LLVMType*): """确保跨模块结构体的完整定义在当前模块中可用(供 alloca 使用) 处理两种情况: @@ -1801,7 +1787,8 @@ class StructGenMixin: total_len: sizet = string.strlen(sname) class_name_len: sizet = string.strlen(class_name) sha1_len: sizet = total_len - class_name_len - 1 - sha1_buf: str = pool.alloc(32) + sha1_buf: str = pool.alloc_tagged(32, + memhub.DETSITE_STRUCTGENMIXIN_1804) if sha1_buf is None: return # 32 字节缓冲:strncpy 不截断,前缀超过 31 字符会越界写 + 手动 NUL 再越界 @@ -1811,7 +1798,7 @@ class StructGenMixin: string.strncpy(sha1_buf, sname, sha1_cp) sha1_buf[sha1_cp] = '\0' # 按类名 + SHA1 查找结构体定义 - entry: rawptr[GenTypes.StructEntry] = self.find_struct_by_module(class_name, sha1_buf) + entry: GenTypes.StructEntry* = self.find_struct_by_module(class_name, sha1_buf) if entry is None: # 回退到按类名查找(可能找到不同模块的同名类,但总比没有好) entry = self.find_struct(class_name) @@ -1830,9 +1817,9 @@ class StructGenMixin: # 也有完整定义。指针类型字段只需 opaque 声明(已由 module_ensure_opaque_for_type 处理)。 self._ensure_field_types_in_module(pool, mod, entry.Ty) - def _ensure_field_types_in_module(self, pool: rawptr[memhub.MemBuddy], - mod: rawptr[llvmlite.LLVMModule], - ty: rawptr[llvmlite.LLVMType]): + def _ensure_field_types_in_module(self, pool: memhub.MemBuddy*, + mod: llvmlite.LLVMModule*, + ty: llvmlite.LLVMType*): """递归扫描类型树,确保值类型子结构体有完整定义""" if ty is None or mod is None or pool is None: return @@ -1879,25 +1866,25 @@ class StructGenMixin: case _: pass - def get_field_name_ptr(self, fe: rawptr[GenTypes.FieldEntry]) -> str: + def get_field_name_ptr(self, fe: GenTypes.FieldEntry*) -> str: """获取 FieldEntry 的字段名,返回 None=未设置""" if fe is None: return None return fe.Name - def get_field_type_ptr(self, fe: rawptr[GenTypes.FieldEntry]) -> rawptr[llvmlite.LLVMType]: + def get_field_type_ptr(self, fe: GenTypes.FieldEntry*) -> llvmlite.LLVMType*: """获取 FieldEntry 的字段类型,返回 None=未设置""" if fe is None: return None return fe.Ty - def get_field_default_ptr(self, fe: rawptr[GenTypes.FieldEntry]) -> rawptr[ast.AST]: + def get_field_default_ptr(self, fe: GenTypes.FieldEntry*) -> ast.AST*: """获取 FieldEntry 的默认值 AST 节点,返回 None=无默认值""" if fe is None: return None return fe.DefaultVal - def get_field_annot_class_name(self, fe: rawptr[GenTypes.FieldEntry]) -> str: + def get_field_annot_class_name(self, fe: GenTypes.FieldEntry*) -> str: """获取 FieldEntry 的原始类型注解类名(Spec.SourceName),返回 None=未设置 [S4] 原 FieldEntry.AnnotClassName 字段已删除,注解名承载在 Spec.SourceName @@ -1907,7 +1894,7 @@ class StructGenMixin: return None return TSpec.SpecSourceName(fe.Spec) - def field_is_volatile(self, fe: rawptr[GenTypes.FieldEntry]) -> int: + def field_is_volatile(self, fe: GenTypes.FieldEntry*) -> int: """字段是否 volatile(FieldEntry.IsVolatile 承载),1=是 / 0=否 由 ClassGenDef 收集字段注解时检测 t.CVolatile 写入;消费点(成员读写的 @@ -1917,7 +1904,7 @@ class StructGenMixin: return 0 return fe.IsVolatile - def field_pointee_is_volatile(self, fe: rawptr[GenTypes.FieldEntry]) -> int: + def field_pointee_is_volatile(self, fe: GenTypes.FieldEntry*) -> int: """字段所指物是否 volatile(FieldEntry.PointeeVolatile 承载),1=是 / 0=否 字段注解为 rawptr[t.CVolatile | T](等价 C 的 volatile T*)时由 ClassGenDef @@ -1927,3 +1914,13 @@ class StructGenMixin: if fe is None: return 0 return fe.PointeeVolatile + + def field_is_const(self, fe: GenTypes.FieldEntry*) -> int: + """字段是否 const 对象(FieldEntry.IsConst 承载),1=是 / 0=否 + + 字段注解含 t.CConst 且字段类型非指针时由 ClassGenDef 写入;消费点 + (obj.f = ... / self.f = ... 的字段赋值)据此 fail-fast。 + """ + if fe is None: + return 0 + return fe.IsConst diff --git a/App/lib/core/Gen/Translator.vp b/App/lib/core/Gen/Translator.vp index 098a779..7f5c8f1 100644 --- a/App/lib/core/Gen/Translator.vp +++ b/App/lib/core/Gen/Translator.vp @@ -47,9 +47,23 @@ import lib.core.Gen.Generator as Generator # ============================================================ # 常量 +# 作用域变量表容量上限(唯一真源)。分配点 VarGenMixin.init_vars +# (HT.MAX_VARS * VarEntry.__sizeof__())与守卫 VarGenMixin.add_var +# (var_count >= HT.MAX_VARS)都取本常量,两者结构上不可能各自漂移。 MAX_VARS: t.CDefine = 1024 +# 函数表容量上限(唯一真源)。分配点在本模块 _init_state +# (GenApi.init_func_table(pool, MAX_FUNCS));注册侧守卫上限由 +# FuncGenDef/ClassGenVTable/AsyncGenMixin/VpiReader 传给 +# CallGenLeafKit.add_func_to_table 的 max_count 给出,必须 <= 本容量。 MAX_FUNCS: t.CDefine = 1024 -MAX_GLOBAL_NAMES: t.CDefine = 32 +# 引用口径(同 CallGenBase.vp 常量段):跨模块 t.CDefine 只能在函数体内读, +# 故引用方一律写限定名 HT.MAX_VARS / HT.MAX_FUNCS,且不得用于模块级 +# CDefine 初始化式。 +# global/nonlocal 名称表容量上限(唯一真源)。TranslatorGenMixin 的 +# add_global_name/add_nonlocal_name 越界守卫与 FuncGenMixin 的嵌套 nonlocal +# 缓冲分配均经 HT.MAX_GLOBAL_NAMES 引用本常量;缓冲分配(Translator._init_state) +# 与守卫必须同值,单改任一侧都会造成堆越界写或有效容量缩水。 +MAX_GLOBAL_NAMES: t.CDefine = 128 # 协程表容量(TPV-M1):async 函数数 / 协程变量·局部名数 MAX_CORO_FUNCS: t.CDefine = 256 MAX_CORO_VARS: t.CDefine = 256 @@ -66,16 +80,15 @@ TRANSLATE_MAX_DEPTH: t.CDefine = 256 # 全局 gen 单例(模块级镜像,同 HandlesType/HandlesStruct 模式) # ============================================================ -@t.NoVTable -class Translator: +novirtual class Translator: """翻译器:管理编译状态,委托 Handles 模块执行翻译""" # LLVM 上下文(共享状态) - Module: rawptr[llvmlite.LLVMModule] - Pool: rawptr[memhub.MemBuddy] + Module: llvmlite.LLVMModule* + Pool: memhub.MemBuddy* # 函数表 - _funcs: rawptr[GenTypes.FuncEntry] + _funcs: GenTypes.FuncEntry* _func_count: int # 协程(TPV-M1 async def / await / coro.coro_run) @@ -92,12 +105,12 @@ class Translator: _coro_frames: str _coro_frame_count: int # resume_ 翻译上下文(AsyncGenMixin 段翻译共享) - _coro_state_ptr: rawptr[llvmlite.Value] - _coro_done_ptr: rawptr[llvmlite.Value] - _coro_ret_ptr: rawptr[llvmlite.Value] + _coro_state_ptr: llvmlite.Value* + _coro_done_ptr: llvmlite.Value* + _coro_ret_ptr: llvmlite.Value* _coro_exit_bb: rawptr[llvmlite.BasicBlock] - _coro_await_slot: rawptr[llvmlite.Value] - _coro_frame: rawptr[llvmlite.Value] + _coro_await_slot: llvmlite.Value* + _coro_frame: llvmlite.Value* _coro_next_state: int _coro_nseg: int # M2:async 参数表(char* 数组,8 字节/项)+ 预扫描计数 @@ -109,12 +122,12 @@ class Translator: _coro_extra_base: int # 额外槽(__await_N)起始 index _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 恢复块定位) + _coro_state_bbs: sizet* # 预建 state 块数组(await 恢复块定位) # M3-M7 协程扩展 - _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_exc_ptr: llvmlite.Value* # 帧 exc 槽(i32,M4) + _coro_msg_ptr: llvmlite.Value* # 帧 msg 槽(i8*,M7) + _coro_wake_ptr: llvmlite.Value* # 帧 wake 槽(i64,M3 coro_sleep) + _coro_try_stack: sizet* # try 栈:except/finally 块指针数组(8B/项) _coro_try_stack_count: int _coro_for_counter: int # range-For 编号(M3,翻译期递增) _coro_scan_for_count: int # 预扫描期 For 计数 @@ -133,28 +146,28 @@ class Translator: _from_imports: str # 当前翻译上下文 - _cur_func: rawptr[llvmlite.Function] - _cur_builder: rawptr[llvmlite.IRBuilder] + _cur_func: llvmlite.Function* + _cur_builder: llvmlite.IRBuilder* # 当前赋值语句的注解节点(AnnAssign 翻译 rhs 前设置,Assign 翻译前清空)。 # 供裸名泛型构造从注解推断类型实参:`s: Stack[int] = Stack()` 用注解里的 # int 特化(消费者见 CallGenCtor.vp 的 CurAssignNode/CurAssignAnnot 判定)。 - CurAssignAnnot: rawptr[ast.AST] + CurAssignAnnot: ast.AST* # 当前赋值语句的 RHS 节点(AnnAssign 翻译 rhs 前设置,rhs 翻译后清除)。 # 供裸名泛型构造判定"构造调用是否为赋值直接 RHS":仅该 identity 命中时才用 # CurAssignAnnot 推断类型实参(对齐 TPC 的直接 RHS 检查)。 - CurAssignNode: rawptr[ast.AST] + CurAssignNode: ast.AST* # 当前函数的返回注解节点(translate_function_def 进入函数体前设置,退出时 # 恢复外层函数的值)。供裸名泛型构造回退推断类型实参:`-> Stack[int]` 里 # `return Stack()` 用注解里的 int 特化(与 CurAssignAnnot 同类的上下文通道)。 - CurFuncRetAnnot: rawptr[ast.AST] + CurFuncRetAnnot: ast.AST* # 当前 Return 语句的直接值节点(translate_return 翻译返回值前设置,翻译后 # 清除)。与 CurAssignNode 同款的 identity 判定:仅「裸名泛型构造就是 return # 的直接值」时才用 CurFuncRetAnnot(嵌套调用如 return f(Stack()) 不推断)。 - CurRetNode: rawptr[ast.AST] + CurRetNode: ast.AST* # 循环控制流目标(break/continue) _break_bb: rawptr[llvmlite.BasicBlock] @@ -192,7 +205,7 @@ class Translator: # *args 变长参数支持:当前函数的 va_list 指针(i8* alloca) # 仅当函数声明了 *args 时设置,供 arg(type) 糖函数使用 - _va_list_ptr: rawptr[llvmlite.Value] + _va_list_ptr: llvmlite.Value* # *args 参数名(如 "args"),用于符号表注册 _vararg_name: str @@ -200,19 +213,19 @@ class Translator: # _translate_method 注入 __stop_iter_flag__ 参数时设置;translate_raise # 检测 raise StopIteration 时对该指针 store 1(对齐 TPC HandlesRaise.py)。 # 非 __next__ 函数中为 None。 - _stop_iter_flag_ptr: rawptr[llvmlite.Value] + _stop_iter_flag_ptr: llvmlite.Value* # try-except 机制(对齐 TPC HandlesTry.py):当前最内层 try 的 # 分发块 + 异常编码/消息 alloca。translate_try 设置,translate_raise # 与调用侧 EH 检测写入/跳转。try 外为 None。 _eh_dispatch_bb: rawptr[llvmlite.BasicBlock] - _eh_code_ptr: rawptr[llvmlite.Value] - _eh_msg_ptr: rawptr[llvmlite.Value] + _eh_code_ptr: llvmlite.Value* + _eh_msg_ptr: 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: rawptr[llvmlite.Value] - _eh_code_out_param: rawptr[llvmlite.Value] + _eh_msg_out_param: llvmlite.Value* + _eh_code_out_param: llvmlite.Value* _cur_func_has_eh: int # 模块 SHA1 前缀(16 字符),用于函数名混淆(SHA1 命名空间) @@ -242,8 +255,8 @@ class Translator: # 泛型特化上下文:当前正在特化的类型参数名/实参名列表 # 由 _specialize_generic_class 设置,方法体翻译时用于将 T 替换为具体类型 # None 表示不在泛型特化上下文中 - GenericTypeParamNames: list[str] | t.CPtr - GenericTypeArgs: list[str] | t.CPtr + GenericTypeParamNames: list[str]* + GenericTypeArgs: list[str]* # Phase 1a 声明模式标志:1=只注册 struct/enum/union 不翻译代码体,0=全量翻译 _declare_only: int @@ -341,7 +354,7 @@ class Translator: # ============================================================ # 状态初始化 # ============================================================ - def _init_state(self, pool: rawptr[memhub.MemBuddy]): + def _init_state(self, pool: memhub.MemBuddy*): """初始化变量表、函数表和子 Handle""" self.Pool = pool if self._funcs is None: @@ -349,7 +362,7 @@ class Translator: # 嵌套作用域符号表(新版) if self.SymTab is None: self.SymTab = GenApi.init_symbol_table(pool) - # global/nonlocal 名称集合缓冲区(32 个 char* 指针 = 256 字节) + # global/nonlocal 名称集合缓冲区(MAX_GLOBAL_NAMES 个 char* 指针 = 128*8 字节) if self._global_names is None: self._global_names = stdlib.malloc(MAX_GLOBAL_NAMES * 8) if self._global_names is not None: @@ -419,20 +432,20 @@ class Translator: # ============================================================ # 主翻译入口 # ============================================================ - def translate(self, tree: rawptr[ast.AST]) -> int: + def translate(self, tree: ast.AST*) -> int: """将 AST 翻译为 LLVM IR""" if tree is None: return 1 if _mbuddy is None: return 1 - pool: rawptr[memhub.MemBuddy] = _mbuddy + pool: memhub.MemBuddy* = _mbuddy # 初始化状态 self._init_state(pool) # 创建 LLVM 模块 - mod: rawptr[llvmlite.LLVMModule] = llvmlite.new_module(pool, "main") + mod: llvmlite.LLVMModule* = llvmlite.new_module(pool, "main") if mod is None: VLogger.error("NewModule returned NULL", "TR") return 1 @@ -445,12 +458,12 @@ class Translator: llvmlite.module_set_target(mod, triple) # 类型 - i32_ty: rawptr[llvmlite.LLVMType] = llvmlite.Int32(pool) - i8_ty: rawptr[llvmlite.LLVMType] = llvmlite.Int8(pool) - i8_ptr_ty: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, i8_ty) + i32_ty: llvmlite.LLVMType* = llvmlite.Int32(pool) + i8_ty: llvmlite.LLVMType* = llvmlite.Int8(pool) + i8_ptr_ty: llvmlite.LLVMType* = llvmlite.Ptr(pool, i8_ty) # 声明 printf - printf_func: rawptr[llvmlite.Function] = llvmlite.create_declare( + printf_func: llvmlite.Function* = llvmlite.create_declare( pool, mod, "printf", i32_ty) if printf_func is None: VLogger.error("CreateDeclare printf returned NULL", "TR") @@ -460,21 +473,21 @@ class Translator: # 声明 LLVM va_start/va_end intrinsic(供 *args 函数体内使用) # declare void @llvm.va_start(i8*) # declare void @llvm.va_end(i8*) - void_ty_decl: rawptr[llvmlite.LLVMType] = llvmlite.Void(pool) - va_start_func: rawptr[llvmlite.Function] = llvmlite.create_declare( + void_ty_decl: llvmlite.LLVMType* = llvmlite.Void(pool) + va_start_func: llvmlite.Function* = llvmlite.create_declare( pool, mod, "llvm.va_start", void_ty_decl) if va_start_func is not None: llvmlite.add_param(pool, va_start_func, i8_ptr_ty, "ap") - va_end_func: rawptr[llvmlite.Function] = llvmlite.create_declare( + va_end_func: llvmlite.Function* = llvmlite.create_declare( pool, mod, "llvm.va_end", void_ty_decl) if va_end_func is not None: llvmlite.add_param(pool, va_end_func, i8_ptr_ty, "ap") # 声明 malloc(闭包分配用) - malloc_func: rawptr[llvmlite.Function] = llvmlite.create_declare( + malloc_func: llvmlite.Function* = llvmlite.create_declare( pool, mod, "malloc", i8_ptr_ty) if malloc_func is not None: - i64_ty: rawptr[llvmlite.LLVMType] = llvmlite.Int64(pool) + i64_ty: llvmlite.LLVMType* = llvmlite.Int64(pool) llvmlite.add_param(pool, malloc_func, i64_ty, "size") # 检查用户是否定义了 main 函数 @@ -483,9 +496,9 @@ class Translator: if ch is not None: cn_count: sizet = len(ch) for ci in range(cn_count): - child: rawptr[ast.AST] = ch.get(ci) + child: ast.AST* = ch.get(ci) if child is not None and child.kind() == ast.ASTKind.FunctionDef: - fd: rawptr[ast.FunctionDef] = rawptr[ast.FunctionDef](child) + fd: ast.FunctionDef* = ast.FunctionDef*(child) if fd is not None and fd.name is not None: if string.strcmp(fd.name, "main") == 0: has_user_main = 1 @@ -507,19 +520,19 @@ class Translator: # ============================================================ # 包装 main 函数(无用户 main 时)→ 委托 HandlesMain # ============================================================ - def _translate_wrapper_main(self, pool: rawptr[memhub.MemBuddy], - mod: rawptr[llvmlite.LLVMModule], - tree: rawptr[ast.AST], - i32_ty: rawptr[llvmlite.LLVMType]): + def _translate_wrapper_main(self, pool: memhub.MemBuddy*, + mod: llvmlite.LLVMModule*, + tree: ast.AST*, + i32_ty: llvmlite.LLVMType*): """委托 GenApi.create_wrapper_main() 创建包装 main(trans 单参)""" added: int = GenApi.create_wrapper_main(self, tree, i32_ty) # ============================================================ # 模块级翻译(用户已定义 main)→ 委托 HandlesMain # ============================================================ - def _translate_module_level(self, pool: rawptr[memhub.MemBuddy], - mod: rawptr[llvmlite.LLVMModule], - tree: rawptr[ast.AST]): + def _translate_module_level(self, pool: memhub.MemBuddy*, + mod: llvmlite.LLVMModule*, + tree: ast.AST*): """委托 GenApi.translate_children() 翻译模块级语句(trans 单参)""" # 全量翻译模式下,先处理导入语句,再创建前向声明,解决前向引用问题 if self._declare_only == 0: @@ -531,7 +544,7 @@ class Translator: if ch is not None: cn_count: sizet = len(ch) for ci in range(cn_count): - child: rawptr[ast.AST] = ch.get(ci) + child: ast.AST* = ch.get(ci) if child is None: continue kd: int = child.kind() @@ -571,7 +584,7 @@ class Translator: # 通过 lookup_module_var 检测已存在并跳过(HandlesMain.py:206-209) if ch is not None: for ci in range(cn_count): - child: rawptr[ast.AST] = ch.get(ci) + child: ast.AST* = ch.get(ci) if child is None: continue kd_mv: int = child.kind() @@ -589,8 +602,8 @@ class Translator: # - AnnAssign 注解裸名 Name(list/dict):d: dict # - 构造调用 func 裸名 Name(list/dict):dict(bd) # - Subscript 的 value 裸名 Name(list/dict):list[int] - def _inject_auto_container_visibility(self, pool: rawptr[memhub.MemBuddy], - tree: rawptr[ast.AST]): + def _inject_auto_container_visibility(self, pool: memhub.MemBuddy*, + tree: ast.AST*): """检测 list/dict 容器使用,注入容器类可见性""" if tree is None or tree.children is None: return @@ -689,7 +702,7 @@ class Translator: stdlib.free(nm_buf) return 0 - def _scan_container_usage(self, node: rawptr[ast.AST], + def _scan_container_usage(self, node: ast.AST*, need_list_box: t.CPtr, need_dict_box: t.CPtr): """递归扫描 AST 语句结构,检测 list/dict 容器使用""" @@ -697,31 +710,31 @@ class Translator: return k: int = node.kind() if k == ast.ASTKind.AnnAssign: - aa_s: rawptr[ast.AnnAssign] = rawptr[ast.AnnAssign](node) + aa_s: ast.AnnAssign* = ast.AnnAssign*(node) if aa_s.annotation is not None: self._check_container_type_node(aa_s.annotation, need_list_box, need_dict_box) elif k == ast.ASTKind.Call: - cl_s: rawptr[ast.Call] = rawptr[ast.Call](node) + cl_s: ast.Call* = ast.Call*(node) if cl_s.func is not None: self._check_container_type_node(cl_s.func, need_list_box, need_dict_box) elif k == ast.ASTKind.Subscript: - sub_s: rawptr[ast.Subscript] = rawptr[ast.Subscript](node) + sub_s: ast.Subscript* = ast.Subscript*(node) if sub_s.value is not None: self._check_container_type_node(sub_s.value, need_list_box, need_dict_box) elif k == ast.ASTKind.FunctionDef: - fd_s: rawptr[ast.FunctionDef] = rawptr[ast.FunctionDef](node) + fd_s: ast.FunctionDef* = ast.FunctionDef*(node) if fd_s.returns is not None: self._check_container_type_node(fd_s.returns, need_list_box, need_dict_box) if fd_s.args is not None: - args_s: rawptr[ast.Arguments] = rawptr[ast.Arguments](fd_s.args) + args_s: ast.Arguments* = ast.Arguments*(fd_s.args) if args_s.args is not None: args_list_s: list[ast.AST*]* = args_s.args an_s: sizet = len(args_list_s) ai_s: sizet for ai_s in range(an_s): - arg_s: rawptr[ast.AST] = args_list_s.get(ai_s) + arg_s: ast.AST* = args_list_s.get(ai_s) if arg_s is not None: - ag_s: rawptr[ast.Arg] = rawptr[ast.Arg](arg_s) + ag_s: ast.Arg* = ast.Arg*(arg_s) if ag_s.annotation is not None: self._check_container_type_node( ag_s.annotation, need_list_box, need_dict_box) @@ -738,7 +751,7 @@ class Translator: for ci_s in range(n_s): self._scan_container_usage(ch_s.get(ci_s), need_list_box, need_dict_box) - def _check_container_type_node(self, node: rawptr[ast.AST], + def _check_container_type_node(self, node: ast.AST*, need_list_box: t.CPtr, need_dict_box: t.CPtr): """检测类型位置节点是否为 list/dict(支持 Name / Subscript / BinOp 递归)""" @@ -746,25 +759,25 @@ class Translator: return k: int = node.kind() if k == ast.ASTKind.Name: - nm_s: rawptr[ast.Name] = rawptr[ast.Name](node) + nm_s: ast.Name* = ast.Name*(node) if nm_s.id is not None: if string.strcmp(nm_s.id, "dict") == 0: need_dict_box[0] = 1 elif string.strcmp(nm_s.id, "list") == 0: need_list_box[0] = 1 elif k == ast.ASTKind.Subscript: - sub_s: rawptr[ast.Subscript] = rawptr[ast.Subscript](node) + sub_s: ast.Subscript* = ast.Subscript*(node) if sub_s.value is not None: self._check_container_type_node(sub_s.value, need_list_box, need_dict_box) # rawptr[list[int]] / list[AST] 等:slice 里可能含 list,需下钻 if sub_s.slice is not None: self._check_container_type_node(sub_s.slice, need_list_box, need_dict_box) elif k == ast.ASTKind.BinOp: - bop_s: rawptr[ast.BinOp] = rawptr[ast.BinOp](node) + bop_s: ast.BinOp* = ast.BinOp*(node) self._check_container_type_node(ast.binop_get_left(bop_s), need_list_box, need_dict_box) self._check_container_type_node(ast.binop_get_right(bop_s), need_list_box, need_dict_box) - def _annotation_is_container(self, ann: rawptr[ast.AST]) -> int: + def _annotation_is_container(self, ann: ast.AST*) -> int: """注解是否为 list/dict 容器(Name 裸名或 Subscript list[...]/dict[...]) 数组初始化(t.CArray[...] / 裸数组注解)返回 0,避免 _scan_container_usage @@ -773,7 +786,7 @@ class Translator: while ann is not None: ak: int = ann.kind() if ak == ast.ASTKind.Name: - nm_c: rawptr[ast.Name] = rawptr[ast.Name](ann) + nm_c: ast.Name* = ast.Name*(ann) if nm_c.id is not None: if string.strcmp(nm_c.id, "list") == 0: return 1 @@ -781,7 +794,7 @@ class Translator: return 1 return 0 elif ak == ast.ASTKind.Subscript: - sub_c: rawptr[ast.Subscript] = rawptr[ast.Subscript](ann) + sub_c: ast.Subscript* = ast.Subscript*(ann) ann = sub_c.value else: return 0 @@ -810,8 +823,7 @@ class Translator: # 持有 Translator 回指针。ExprCallHandle 等跨模块 handler 类经 # `class X(Translator.Mixin)` 继承(TPV 支持模块限定基类继承)。 # ============================================================ -@t.NoVTable -class Mixin: +novirtual class Mixin: """所有 Handle 的非多态基类:持有 Translator 回指针 + 共享委托方法""" Trans: Translator | t.CPtr @@ -824,5 +836,5 @@ class Mixin: # ============================================================ # 全局 mbuddy 指针 -_mbuddy: rawptr[memhub.MemBuddy] +_mbuddy: memhub.MemBuddy* diff --git a/App/lib/core/Gen/TranslatorGenMixin.vp b/App/lib/core/Gen/TranslatorGenMixin.vp index 3dfe573..4195099 100644 --- a/App/lib/core/Gen/TranslatorGenMixin.vp +++ b/App/lib/core/Gen/TranslatorGenMixin.vp @@ -17,25 +17,17 @@ import lib.core.Gen.GenTypes as GenTypes # # 职责:模块级翻译入口(translate_children/create_wrapper_main/ # handle_module_level_var 等)与 global/nonlocal 名称管理辅助。 -# 常量 MAX_VARS/MAX_FUNCS/MAX_GLOBAL_NAMES 与 Handles 侧一致。 +# 容量常量 MAX_VARS/MAX_FUNCS/MAX_GLOBAL_NAMES 不在此定义(本文件无使用点), +# 统一经 HT. 引用 Translator.vp 的唯一真源(与 FuncGenMixin 同一引用路径)。 # @t.NoVTable:静态绑定(方法沿 MRO 直接调用 + this 调整)。 # ============================================================ -# ============================================================ -# 常量(与 HandlesTranslator 保持一致) -# ============================================================ -MAX_VARS: t.CDefine = 1024 -MAX_FUNCS: t.CDefine = 1024 -MAX_GLOBAL_NAMES: t.CDefine = 32 - - # ============================================================ # TranslatorGenMixin - 翻译驱动(模块级翻译入口 + 作用域名称管理) # ============================================================ -@t.NoVTable -class TranslatorGenMixin: - """翻译驱动 Mixin(P6 方法化)""" +novirtual class TranslatorGenMixin: + """翻译驱动 Mixin""" # ============================================================ # _register_cexport_from_funcdef - Phase 1a 预注册 CExport/State 函数 @@ -44,15 +36,12 @@ class TranslatorGenMixin: # CExport 函数无法被先翻译的模块正确识别为裸名调用。 # Phase 1a 预注册所有 CExport/State 函数名到全局表。 # ============================================================ - Gen: rawptr[Generator.Generator] - def _register_cexport_from_funcdef(self, trans: rawptr[HT.Translator], - node: rawptr[ast.AST]) -> int: + Gen: Generator.Generator* + def _register_cexport_from_funcdef(self, trans: HT.Translator*, node: ast.AST*) -> int: """预注册 CExport/State 函数到全局表(仅注册,不生成 IR)""" - fd: rawptr[ast.FunctionDef] = rawptr[ast.FunctionDef](node) - if fd is None or fd.name is None: - return 0 - if trans is None or trans.ModuleSha1 is None: - return 0 + fd: ast.FunctionDef* = ast.FunctionDef*(node) + if fd is None or fd.name is None: return 0 + if trans is None or trans.ModuleSha1 is None: return 0 # 检查返回类型是否有 CExport 或 State 标记 has_export: int = 0 @@ -72,8 +61,7 @@ class TranslatorGenMixin: # 对应 TransPyC translator._translate_children() # 共享状态从 trans 获取,imported_modules/from_imports 更新到 trans # ============================================================ - def translate_children(self, trans: rawptr[HT.Translator], - tree: rawptr[ast.AST]) -> int: + def translate_children(self, trans: HT.Translator*, tree: ast.AST*) -> int: """遍历 tree.children 并翻译每个子节点 Args: @@ -84,21 +72,16 @@ class TranslatorGenMixin: int: 新增的变量数 """ ch: list[ast.AST*]* = tree.children - if ch is None: - return 0 - + if ch is None: return 0 cn_count: sizet = len(ch) added_total: int = 0 - for ci in range(cn_count): - child: rawptr[ast.AST] = ch.get(ci) + child: ast.AST* = ch.get(ci) if child is None: continue kd: int = child.kind() - # _declare_only == 0 时,_translate_module_level 已预处理导入语句, # 此处跳过避免重复处理(from_imports 条目重复) - if trans._declare_only == 0 and (kd == ast.ASTKind.Import or kd == ast.ASTKind.ImportFrom): - continue + if trans._declare_only == 0 and (kd == ast.ASTKind.Import or kd == ast.ASTKind.ImportFrom): continue if kd == ast.ASTKind.Import: self.Gen.ImportsGen.translate_import(trans, child) elif kd == ast.ASTKind.ImportFrom: @@ -149,12 +132,11 @@ class TranslatorGenMixin: # 避免 Phase2 翻译 App 文件时访问悬空结构体(UAF)。 # 仅解析类型触发特化,不验证结果(1b 全量翻译时重新解析)。 # ============================================================ - def _prescan_funcdef_signatures(self, trans: rawptr[HT.Translator], - fd: rawptr[ast.FunctionDef]) -> None: + def _prescan_funcdef_signatures(self, trans: HT.Translator*, fd: ast.FunctionDef*) -> None: """预解析模块级函数签名的返回/参数类型,触发泛型类特化""" if trans is None or fd is None: return - pool: rawptr[memhub.MemBuddy] = trans.Pool + pool: memhub.MemBuddy* = trans.Pool if pool is None: return imp: str = trans._imported_modules @@ -162,13 +144,13 @@ class TranslatorGenMixin: if fd.returns is not None: self.Gen.TypeGenResolve.resolve_annotation_type(pool, fd.returns, imp, fi, trans, 0) if fd.args is not None: - ags: rawptr[ast.Arguments] = rawptr[ast.Arguments](fd.args) + ags: ast.Arguments* = ast.Arguments*(fd.args) if ags.args is not None: al: list[ast.AST*]* = ags.args an: sizet = len(al) ai: sizet for ai in range(an): - ag: rawptr[ast.Arg] = rawptr[ast.Arg](al.get(ai)) + ag: ast.Arg* = ast.Arg*(al.get(ai)) if ag is not None and ag.annotation is not None: self.Gen.TypeGenResolve.resolve_annotation_type(pool, ag.annotation, imp, fi, trans, 0) @@ -178,21 +160,21 @@ class TranslatorGenMixin: # 生成格式: [N x elem_ty] [elem_ty val0, elem_ty val1, ...] # 用于模块级 t.CArray 列表字面量初始化(不依赖 builder,直接生成常量初始化器) # ============================================================ - def _build_array_initializer_text(self, pool: rawptr[memhub.MemBuddy], - var_ty: rawptr[llvmlite.LLVMType], - list_node: rawptr[ast.List]) -> str: + def _build_array_initializer_text(self, pool: memhub.MemBuddy*, + var_ty: llvmlite.LLVMType*, + list_node: 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: rawptr[ast.List] = rawptr[ast.List](list_node) + ln: ast.List* = ast.List*(list_node) if ln is None: return None # 从 var_ty 提取数组元素类型和数量 - elem_ty: rawptr[llvmlite.LLVMType] = None + elem_ty: llvmlite.LLVMType* = None arr_count: int = 0 match var_ty: case llvmlite.LLVMType.Array(et, cnt): @@ -266,12 +248,12 @@ class TranslatorGenMixin: while i_n < cnt_total_n: sub_n: str = None if i_n < elts_count: - en_n: rawptr[ast.AST] = elts.get(i_n) + en_n: ast.AST* = elts.get(i_n) if en_n is not None: ek_n: int = en_n.kind() if ek_n == ast.ASTKind.List: sub_n = self._build_array_initializer_text( - pool, elem_ty, rawptr[ast.List](en_n)) + pool, elem_ty, ast.List*(en_n)) elif ek_n == ast.ASTKind.Set: # 花括号行字面量(如点阵字库 {0x00, ...}):Set.elts # 与 List 同构,包装为临时 List 递归生成子数组文本 @@ -292,12 +274,12 @@ class TranslatorGenMixin: viperlib.snprintf(buf_n + pos_n, buf_size_n - pos_n, "]") return buf_n for zi in range(elts_count): - ze: rawptr[ast.AST] = elts.get(zi) + ze: ast.AST* = elts.get(zi) if ze is None: continue zk: int = ze.kind() if zk == ast.ASTKind.Constant: - zc: rawptr[ast.Constant] = rawptr[ast.Constant](ze) + zc: ast.Constant* = ast.Constant*(ze) if zc is None: continue # None(CONST_NONE)视为零:函数指针数组 @@ -335,12 +317,12 @@ class TranslatorGenMixin: while i < cnt_total: elem_val: int64 = 0 if i < elts_count: - elem_node: rawptr[ast.AST] = elts.get(i) + elem_node: ast.AST* = elts.get(i) # 直接从 Constant 节点提取 int_val(避免 extract_cdefine_int_value 的 int 截断) if elem_node is not None: ek: int = elem_node.kind() if ek == ast.ASTKind.Constant: - ec: rawptr[ast.Constant] = rawptr[ast.Constant](elem_node) + ec: ast.Constant* = ast.Constant*(elem_node) # CONST_CHAR 字符字面量(如 `_ps2_set1 = ['\x1b', '1', ...]`): # int_val 即字符码(不识别则字符元素全编成 0)。 if ec is not None and (ec.const_kind == ast.CONST_INT or ec.const_kind == ast.CONST_CHAR): @@ -369,8 +351,8 @@ class TranslatorGenMixin: # t.CArray[char, N] = "..." → [i8 b0, i8 b1, ..., i8 0, ...](字符串字节 + # 零填充到数组长度;空串返回 zeroinitializer)。 # 不能用字符串指针 GEP 初始化器:会导致 @g = global [N x i8] 类型不匹配。 - def _build_string_array_initializer_text(self, pool: rawptr[memhub.MemBuddy], - var_ty: rawptr[llvmlite.LLVMType], + def _build_string_array_initializer_text(self, pool: memhub.MemBuddy*, + var_ty: llvmlite.LLVMType*, str_val: str) -> str: """字符串字面量初始化数组全局,返回初始化器文本或 None""" if var_ty is None or str_val is None: @@ -411,8 +393,8 @@ class TranslatorGenMixin: # 返回 GEP 初始化器文本: getelementptr inbounds ([len+1 x i8], [len+1 x i8]* @.str.{var_name}, i32 0, i32 0) # 用于 b64_tab: t.CArray[char, None] = "ABC..." 等字符串初始化指针类型 # ============================================================ - def _build_string_ptr_initializer(self, pool: rawptr[memhub.MemBuddy], - mod: rawptr[llvmlite.LLVMModule], + def _build_string_ptr_initializer(self, pool: memhub.MemBuddy*, + mod: llvmlite.LLVMModule*, var_name: str, str_val: str) -> str: """为字符串字面量创建内部常量全局并返回 GEP 初始化器文本,None 失败""" @@ -426,7 +408,7 @@ class TranslatorGenMixin: viperlib.snprintf(str_name_buf, 64, ".str.%s", var_name) # 调用 llvmlite.create_global_string 创建字符串常量全局 - str_gv: rawptr[llvmlite.GlobalVariable] = llvmlite.create_global_string( + str_gv: llvmlite.GlobalVariable* = llvmlite.create_global_string( pool, mod, str_name_buf, str_val) if str_gv is None: return None @@ -441,8 +423,8 @@ class TranslatorGenMixin: str_len + 1, str_len + 1, str_name_buf) return init_buf - def _stg_field_zero_text(self, pool: rawptr[memhub.MemBuddy], - fty: rawptr[llvmlite.LLVMType], + def _stg_field_zero_text(self, pool: memhub.MemBuddy*, + fty: llvmlite.LLVMType*, ty_str: str) -> str: """按 LLVM 类型生成 storage struct 字段的零值初始化器文本 @@ -473,17 +455,17 @@ class TranslatorGenMixin: # 仅处理可常量折叠的整型默认值(CONST_INT/CONST_CHAR 及负号字面量); # 其余(浮点/字符串/None/名字/表达式)返回 None,由调用方按零值兜底。 # ============================================================ - def _default_val_const_text(self, pool: rawptr[memhub.MemBuddy], - fty: rawptr[llvmlite.LLVMType], + def _default_val_const_text(self, pool: memhub.MemBuddy*, + fty: llvmlite.LLVMType*, ty_str: str, - dval: rawptr[ast.AST]) -> str: + dval: ast.AST*) -> str: """字段默认值 → "ty 值" 文本;不可折叠返回 None""" if dval is None or fty is None or ty_str is None: return None is_int: int = 0 dv_int: int64 = 0 if dval.kind() == ast.ASTKind.Constant: - dc: rawptr[ast.Constant] = rawptr[ast.Constant](dval) + dc: ast.Constant* = ast.Constant*(dval) if dc is not None: if dc.const_kind == ast.CONST_INT or dc.const_kind == ast.CONST_CHAR: dv_int = dc.int_val @@ -511,8 +493,8 @@ class TranslatorGenMixin: # - _build_stg_struct_init_text:外包 "{ ... }" 作为完整初始化器; # - vtable 对象 storage:首元素为 vtable 指针,其后追加本函数结果(start_idx=1 跳过字段 0)。 # 无任何非零默认值时返回 None,调用方据此保持原零值路径(避免无谓文本)。 - def _build_stg_struct_body_text(self, pool: rawptr[memhub.MemBuddy], - se: rawptr[GenTypes.StructEntry], + def _build_stg_struct_body_text(self, pool: memhub.MemBuddy*, + se: GenTypes.StructEntry*, start_idx: int) -> str: """按字段默认值生成 "e0, e1, ..." 元素文本;无非零默认值返回 None""" if se is None or se.Fields is None: @@ -529,7 +511,7 @@ class TranslatorGenMixin: has_nonzero: int = 0 i: int = start_idx while i < fc: - fe: rawptr[GenTypes.FieldEntry] = self.Gen.StructGen._get_field_entry(se, i) + fe: GenTypes.FieldEntry* = self.Gen.StructGen._get_field_entry(se, i) i += 1 if fe is None or fe.Ty is None: continue @@ -561,8 +543,8 @@ class TranslatorGenMixin: # 用于模块级对象全局 `X: T = T()`:按字段默认值生成完整 struct 常量 # (LLVM 要求列全每个字段);不生成则字段默认值全丢。 # 无任何非零默认值时返回 None,由调用方保持 zeroinitializer(避免无谓文本)。 - def _build_stg_struct_init_text(self, pool: rawptr[memhub.MemBuddy], - se: rawptr[GenTypes.StructEntry], + def _build_stg_struct_init_text(self, pool: memhub.MemBuddy*, + se: GenTypes.StructEntry*, start_idx: int) -> str: """按字段默认值生成完整 struct 初始化器;无非零默认值返回 None""" body: str = self._build_stg_struct_body_text(pool, se, start_idx) @@ -587,8 +569,8 @@ class TranslatorGenMixin: # 字段,打印时由 includes/llvmlite/__module.vp 的 _print_global 补引号 # (`, section "xxx"` / `, align N`),故此处 Section 值不带引号。 # ============================================================ - def _scan_global_tattr(self, node: rawptr[ast.AST], - want_name: str) -> rawptr[ast.AST]: + def _scan_global_tattr(self, node: ast.AST*, + want_name: str) -> ast.AST*: """在全局变量类型注解中查找 t.attr. 节点。 注解形态是 BinOp(BitOr) 左深链(`A | B | C` = BinOp(BinOp(A,B),C)), @@ -599,9 +581,9 @@ class TranslatorGenMixin: if node is None: return None if node.kind() == ast.ASTKind.BinOp: - bop: rawptr[ast.BinOp] = rawptr[ast.BinOp](node) + bop: ast.BinOp* = ast.BinOp*(node) if bop.op == ast.OpKind.BitOr: - hit_l: rawptr[ast.AST] = self._scan_global_tattr(bop.left, want_name) + hit_l: ast.AST* = self._scan_global_tattr(bop.left, want_name) if hit_l is not None: return hit_l return self._scan_global_tattr(bop.right, want_name) @@ -609,7 +591,7 @@ class TranslatorGenMixin: if self.Gen.ClassGenBase._tattr_name(node, want_name) != 0: return node return None - def _extract_global_attr_section(self, node: rawptr[ast.AST], + def _extract_global_attr_section(self, node: ast.AST*, var_name: str) -> str: """取 `T | t.attr.section("xxx")` 的段名(不含引号)。 @@ -617,7 +599,7 @@ class TranslatorGenMixin: TypeGenErr.fatal_error 风格一致):空段名会生成 `section ""` 这种 无意义/非法的 IR,静默忽略只会掩盖拼写错误。 """ - hit: rawptr[ast.AST] = self._scan_global_tattr(node, "section") + hit: ast.AST* = self._scan_global_tattr(node, "section") if hit is None: return None sec_val: str = self.Gen.FuncGenBase._get_attr_call_arg_str(hit) @@ -627,14 +609,14 @@ class TranslatorGenMixin: "ValueError") return None return sec_val - def _extract_global_attr_aligned(self, node: rawptr[ast.AST], + def _extract_global_attr_aligned(self, node: ast.AST*, var_name: str) -> int: """取 `T | t.attr.aligned(N)` 的对齐字节数(无该属性返回 0)。 N 必须是正整数字面量:aligned(0)/aligned(-4)/aligned("x") 均属非法值 → fail-fast(llc 亦拒绝 `align 0`,静默忽略会掩盖参数错误)。 """ - hit: rawptr[ast.AST] = self._scan_global_tattr(node, "aligned") + hit: ast.AST* = self._scan_global_tattr(node, "aligned") if hit is None: return 0 al_val: int = self.Gen.ClassGenBase._tattr_aligned_int(hit) @@ -644,7 +626,7 @@ class TranslatorGenMixin: "ValueError") return 0 return al_val - def _extract_global_attr_weak(self, node: rawptr[ast.AST]) -> int: + def _extract_global_attr_weak(self, node: ast.AST*) -> int: """检测 `T | t.attr.weak` / `t.attr.weak()`(1=有,0=无)""" if self._scan_global_tattr(node, "weak") is not None: return 1 @@ -657,25 +639,25 @@ class TranslatorGenMixin: # AnnAssign/Assign 创建全局变量 @var_name 并注册到 SymTab 模块作用域 # 支持整数、列表字面量、字符串字面量初始值 # ============================================================ - def handle_module_level_var(self, trans: rawptr[HT.Translator], - node: rawptr[ast.AST]) -> int: + def handle_module_level_var(self, trans: HT.Translator*, + node: ast.AST*) -> int: """处理模块级变量声明,创建全局变量""" - pool: rawptr[memhub.MemBuddy] = trans.Pool - mod: rawptr[llvmlite.LLVMModule] = trans.Module + pool: memhub.MemBuddy* = trans.Pool + mod: llvmlite.LLVMModule* = trans.Module # CDefine 注解: 编译期常量,不创建全局变量 # 注册到全局 CDefine 表供 t.CArray[elem_ty, NAME] 解析 k: int = node.kind() if k == ast.ASTKind.AnnAssign: - aa_cd: rawptr[ast.AnnAssign] = rawptr[ast.AnnAssign](node) + aa_cd: ast.AnnAssign* = ast.AnnAssign*(node) if aa_cd is not None and aa_cd.target is not None: if aa_cd.target.kind() == ast.ASTKind.Name: - nm_cd: rawptr[ast.Name] = rawptr[ast.Name](aa_cd.target) + nm_cd: ast.Name* = ast.Name*(aa_cd.target) if nm_cd.id is not None: if self.Gen.AssignGen.is_cdefine_annotation(aa_cd.annotation) != 0: # 浮点/整数自动识别注册(浮点 CDefine 如 vipermath U_M_PI) self.Gen.AssignGen._register_cdefine_from_value( - pool, nm_cd.id, aa_cd.value) + pool, nm_cd.id, aa_cd.value, aa_cd.annotation) return 0 # CTypedef 注解(如 posix.vp mode_t: t.CTypedef = uint32): # 不创建全局变量(否则生成 @mode_t 符号 → 链接 duplicate symbol)。 @@ -694,28 +676,28 @@ class TranslatorGenMixin: return 0 var_name: str = None - var_ty: rawptr[llvmlite.LLVMType] = llvmlite.Int32(pool) - resolved_stg_ty: rawptr[llvmlite.LLVMType] = None # 对象类全局:静态 storage 类型(BSS 实例) - resolved_stg_entry: rawptr[GenTypes.StructEntry] = None # 对象类全局:对应 StructEntry(vtable 初始化用) + var_ty: llvmlite.LLVMType* = llvmlite.Int32(pool) + resolved_stg_ty: llvmlite.LLVMType* = None # 对象类全局:静态 storage 类型(BSS 实例) + resolved_stg_entry: 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: rawptr[ast.List] = None + init_list_node: ast.List* = None # = None 显式初始化(如 tokens.vp `_kw_head: KwEntry | t.CPtr = None`): # 对象类全局的懒初始化指针语义——必须保持 NULL,不能创建 BSS storage # (storage 会让 @g = &g.stg 恒非 NULL,破坏 `if _kw_head != None` 守卫, # 懒初始化代码永不执行)。 is_none_init: int = 0 - annot_node: rawptr[ast.AST] = None # 类型注解节点(检测 t.CExport 标记) + annot_node: ast.AST* = None # 类型注解节点(检测 t.CExport 标记) if k == ast.ASTKind.AnnAssign: - aa: rawptr[ast.AnnAssign] = rawptr[ast.AnnAssign](node) + aa: ast.AnnAssign* = ast.AnnAssign*(node) if aa is None or aa.target is None: return 0 if aa.target.kind() != ast.ASTKind.Name: return 0 - nm: rawptr[ast.Name] = rawptr[ast.Name](aa.target) + nm: ast.Name* = ast.Name*(aa.target) var_name = nm.id annot_node = aa.annotation # t.Callable 模块级函数指针:登记 (变量名 → 返回类型) 签名。此路径原先 @@ -730,7 +712,7 @@ class TranslatorGenMixin: # (CallGenLeafKit.vp:698-699、:783-788),跨文件查找可见。 # t.CDefine/t.CTypedef 等分支已在 :675-689 提前返回,行为不变。 if annot_node is not None: - ml_callable_ret: rawptr[llvmlite.LLVMType] = ( + ml_callable_ret: llvmlite.LLVMType* = ( self.Gen.TypeGenErr.try_extract_callable_ret( pool, annot_node, trans._imported_modules, trans._from_imports, trans)) @@ -742,7 +724,7 @@ class TranslatorGenMixin: return 0 # 解析类型 if aa.annotation is not None: - resolved: rawptr[llvmlite.LLVMType] = self.Gen.TypeGenResolve.resolve_annotation_type( + resolved: llvmlite.LLVMType* = self.Gen.TypeGenResolve.resolve_annotation_type( pool, aa.annotation, trans._imported_modules, trans._from_imports, trans, 0) if resolved is not None: # 对象类模块级变量(@t.Object/@t.CVTable:对象即指针)→ Ptr(struct): @@ -750,7 +732,7 @@ class TranslatorGenMixin: # 值实例,跨模块字段访问/虚表调用会按指针处理读首 8 字节当 vtable → 崩溃。 # 纯 t.CStruct(无方法无虚表无 __new__)保持值实例。 if resolved.kind() == llvmlite.LLVMType.Struct: - gv_entry: rawptr[GenTypes.StructEntry] = self.Gen.StructGen.find_struct_by_type(resolved) + gv_entry: 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 值类型, @@ -763,9 +745,9 @@ class TranslatorGenMixin: # 对象类联合注解(T | t.CPtr → T*):同样创建 storage;否则入口/方法 # 虚调用 load @g 得 NULL → 读 [NULL] 拿 vtable → #PF。 # var_ty 保持 Ptr(联合注解语义:指针全局),storage 承载对象实例。 - pointee_uv: rawptr[llvmlite.LLVMType] = resolved.Pointee + pointee_uv: llvmlite.LLVMType* = resolved.Pointee if pointee_uv is not None and pointee_uv.kind() == llvmlite.LLVMType.Struct: - gv_entry_u: rawptr[GenTypes.StructEntry] = self.Gen.StructGen.find_struct_by_type(pointee_uv) + gv_entry_u: 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 @@ -782,7 +764,7 @@ class TranslatorGenMixin: if aa.value is not None: val_kind: int = aa.value.kind() if val_kind == ast.ASTKind.Constant: - cn: rawptr[ast.Constant] = rawptr[ast.Constant](aa.value) + cn: ast.Constant* = ast.Constant*(aa.value) if cn.const_kind == ast.CONST_NONE: is_none_init = 1 elif cn.const_kind == ast.CONST_INT: @@ -802,24 +784,24 @@ 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 = rawptr[ast.List](aa.value) + init_list_node = ast.List*(aa.value) init_kind = 2 elif k == ast.ASTKind.Assign: - asgn: rawptr[ast.Assign] = rawptr[ast.Assign](node) + asgn: ast.Assign* = ast.Assign*(node) if asgn is None or asgn.targets is None: return 0 targets: list[ast.AST*]* = asgn.targets if len(targets) < 1: return 0 - t0: rawptr[ast.AST] = targets.get(0) + t0: ast.AST* = targets.get(0) if t0 is None or t0.kind() != ast.ASTKind.Name: return 0 - nm2: rawptr[ast.Name] = rawptr[ast.Name](t0) + nm2: ast.Name* = ast.Name*(t0) var_name = nm2.id if asgn.value is not None: val_kind2: int = asgn.value.kind() if val_kind2 == ast.ASTKind.Constant: - cn2: rawptr[ast.Constant] = rawptr[ast.Constant](asgn.value) + cn2: ast.Constant* = ast.Constant*(asgn.value) if cn2.const_kind == ast.CONST_NONE: is_none_init = 1 elif cn2.const_kind == ast.CONST_INT: @@ -838,7 +820,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 = rawptr[ast.List](asgn.value) + init_list_node = ast.List*(asgn.value) init_kind = 2 elif val_kind2 == ast.ASTKind.Attribute: # 模块级 re-export 别名(如 fat32_core.vp `_read32 = types._read32`): @@ -883,7 +865,7 @@ class TranslatorGenMixin: return 0 # 检查是否已注册 - existing: rawptr[llvmlite.Value] = self.Gen.VarGen.lookup_module_var( + existing: llvmlite.Value* = self.Gen.VarGen.lookup_module_var( trans.SymTab, var_name) if existing is not None: return 0 @@ -917,7 +899,7 @@ class TranslatorGenMixin: mangled_name: str = var_name if is_global_cexport == 0: mangled_name = self.Gen.FuncGenBase._mangle_name(trans, var_name) - gv: rawptr[llvmlite.GlobalVariable] = llvmlite.new_global_variable(pool, mangled_name, var_ty) + gv: llvmlite.GlobalVariable* = llvmlite.new_global_variable(pool, mangled_name, var_ty) if gv is None: return 0 llvmlite.module_add_global(mod, gv) @@ -930,13 +912,13 @@ class TranslatorGenMixin: # FXSAVE 区域要求 16 字节对齐,否则 fxsave/fxrstor #GP)。 # 优先级:变量级显式 `T | t.attr.aligned(N)` 比类级(struct entry Align)更具体, # 显式值胜出;无显式属性时沿用类级对齐(既有行为不变)。 - al_ty: rawptr[llvmlite.LLVMType] = var_ty + al_ty: llvmlite.LLVMType* = var_ty match var_ty: case llvmlite.LLVMType.Ptr(pointee_al): al_ty = pointee_al case _: pass - al_entry: rawptr[GenTypes.StructEntry] = None + al_entry: 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 gv_attr_align > 0: @@ -994,7 +976,7 @@ class TranslatorGenMixin: # 浮点初始值:LLVM IR 的浮点常量必须写成位模式文本(0x%016llx / 0x%08x)—— # 十进制文本经 llc 解析对部分值有 ±1 ulp 误差(见 llvmlite.ConstFloat 注释)。 # 浮点分支缺失时模块级 t.CDouble 全局会退化成 zeroinitializer(值全变 0)。 - fc_g: rawptr[llvmlite.Value] = llvmlite.ConstFloat(pool, var_ty, init_fval) + fc_g: 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: @@ -1064,7 +1046,7 @@ class TranslatorGenMixin: else: fc_v: int = resolved_stg_entry.FieldCount for fi_v in range(1, fc_v): - fe_v: rawptr[GenTypes.FieldEntry] = self.Gen.StructGen._get_field_entry( + fe_v: 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 @@ -1091,7 +1073,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: rawptr[llvmlite.GlobalVariable] = llvmlite.new_global_variable( + stg_gv: 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) @@ -1111,7 +1093,7 @@ class TranslatorGenMixin: gv.Initializer = stg_init_buf # 注册 storage 引用(key: var_name.__stg),供 AssignGenMixin # 全局赋值分支检测对象类全局并复制对象到 storage。 - stg_ref: rawptr[llvmlite.Value] = self.Gen.ExprGenAttr.make_global_ref( + stg_ref: 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 @@ -1121,7 +1103,7 @@ class TranslatorGenMixin: self.Gen.VarGen.define_module_var(trans.SymTab, stg_key, stg_ref) # 创建 Value 引用(@mangled_name, 类型为 var_ty*) - var_ptr_ty: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, var_ty) + var_ptr_ty: llvmlite.LLVMType* = llvmlite.Ptr(pool, var_ty) ref_name: str = pool.alloc(96) if ref_name is not None: # mangled 名带 SHA1 前缀(数字开头),引用必须加引号(对齐 make_global_ref) @@ -1129,7 +1111,7 @@ class TranslatorGenMixin: viperlib.snprintf(ref_name, 96, "@\"%s\"", mangled_name) else: viperlib.snprintf(ref_name, 96, "@%s", mangled_name) - gv_ref: rawptr[llvmlite.Value] = llvmlite.SSAValue(pool, var_ptr_ty, ref_name) + gv_ref: llvmlite.Value* = llvmlite.SSAValue(pool, var_ptr_ty, ref_name) # 注册到模块作用域 if self.Gen.VarGen.define_module_var(trans.SymTab, var_name, gv_ref) == 0: @@ -1137,6 +1119,12 @@ class TranslatorGenMixin: # volatile:所有 load/store 带 LLVM volatile,禁止优化器把忙等循环 # 的重复 load 提升/消除(如 `locked: t.CVolatile | t.CInt`)。 if annot_node is not None: + # const 对象全局:注解含 t.CConst 且类型非指针 ⇒ 登记 IsConst, + # 之后对该全局名的赋值/增量赋值/元素赋值 fail-fast(判据同 TPC + # 的 Gen.global_const_flags,见 Debugger/type-descriptors.md)。 + if self.Gen.TypeGenErr.is_const_object_marker( + annot_node, var_ty) != 0: + self.Gen.VarGen.set_var_const(trans.SymTab, var_name) if self.Gen.TypeGenErr.has_decorator_marker(annot_node, "CVolatile", 0) != 0: self.Gen.VarGen.set_var_volatile(trans.SymTab, var_name) # rawptr[t.CVolatile | T](volatile 指针指向物):解引用(p[i]/ @@ -1147,7 +1135,7 @@ class TranslatorGenMixin: # 设置 AnnotClassName(联合类型如 Logger|t.CPtr 简化为 Ptr(i8) 时, # 属性访问需要通过 AnnotClassName 回退到类名查找结构体) if k == ast.ASTKind.AnnAssign: - aa_ml: rawptr[ast.AnnAssign] = rawptr[ast.AnnAssign](node) + aa_ml: ast.AnnAssign* = ast.AnnAssign*(node) if aa_ml is not None and aa_ml.annotation is not None: cls_nm_ml: str = self.Gen.TypeGenResolve.extract_class_name_from_annotation( aa_ml.annotation, trans._imported_modules, pool, trans._from_imports) @@ -1159,7 +1147,7 @@ class TranslatorGenMixin: # global_var_ptr_element(_argv 等字符串指针数组)。否则 # var[i] 退化为 1 字节字符步长 GEP + load i8 截断指针。 if aa_ml.annotation.kind() == ast.ASTKind.BinOp: - bop_ml: rawptr[ast.BinOp] = rawptr[ast.BinOp](aa_ml.annotation) + bop_ml: ast.BinOp* = ast.BinOp*(aa_ml.annotation) if bop_ml.op == ast.OpKind.BitOr: if self.Gen.AssignGen._annotation_contains_name( aa_ml.annotation, "str") != 0 \ @@ -1177,9 +1165,9 @@ class TranslatorGenMixin: # 创建 main() -> i32 函数 → 设置 trans._cur_func/_cur_builder → # 预扫描 alloca → 翻译子节点 → ret 0 # ============================================================ - def create_wrapper_main(self, trans: rawptr[HT.Translator], - tree: rawptr[ast.AST], - i32_ty: rawptr[llvmlite.LLVMType]) -> int: + def create_wrapper_main(self, trans: HT.Translator*, + tree: ast.AST*, + i32_ty: llvmlite.LLVMType*) -> int: """创建包装 main 函数并翻译所有顶层语句 Args: @@ -1190,10 +1178,10 @@ class TranslatorGenMixin: Returns: int: 新增的变量数 """ - pool: rawptr[memhub.MemBuddy] = trans.Pool - mod: rawptr[llvmlite.LLVMModule] = trans.Module + pool: memhub.MemBuddy* = trans.Pool + mod: llvmlite.LLVMModule* = trans.Module - main_func: rawptr[llvmlite.Function] = llvmlite.create_function( + main_func: llvmlite.Function* = llvmlite.create_function( pool, mod, "main", i32_ty) if main_func is None: VLogger.error("CreateFunction main returned NULL", "TR") @@ -1205,7 +1193,7 @@ class TranslatorGenMixin: VLogger.error("CreateBlock returned NULL", "TR") return 0 - builder: rawptr[llvmlite.IRBuilder] = llvmlite.new_builder(pool, main_func) + builder: llvmlite.IRBuilder* = llvmlite.new_builder(pool, main_func) if builder is None: VLogger.error("NewBuilder returned NULL", "TR") return 0 @@ -1222,7 +1210,7 @@ class TranslatorGenMixin: if ch is not None: cn_count: sizet = len(ch) for ci in range(cn_count): - child: rawptr[ast.AST] = ch.get(ci) + child: ast.AST* = ch.get(ci) if child is not None: kd: int = child.kind() if kd == ast.ASTKind.AnnAssign or kd == ast.ASTKind.Assign: @@ -1232,7 +1220,7 @@ class TranslatorGenMixin: # (模块级变量已在上面注册到模块作用域,PreScan 的 lookup_current 会跳过它们) if ch is not None: for ci in range(cn_count): - child: rawptr[ast.AST] = ch.get(ci) + child: ast.AST* = ch.get(ci) if child is not None: self.Gen.StmtGenDecl.pre_scan_allocas(trans, child) @@ -1240,7 +1228,7 @@ class TranslatorGenMixin: added_total: int = self.translate_children(trans, tree) # 返回 0 - zero_val: rawptr[llvmlite.Value] = llvmlite.const_int32(pool, 0) + zero_val: llvmlite.Value* = llvmlite.const_int32(pool, 0) llvmlite.build_ret(builder, zero_val) return added_total @@ -1248,7 +1236,7 @@ class TranslatorGenMixin: # ============================================================ # global/nonlocal 名称管理(迁移自 HandlesTranslator.vp 模块级函数) # ============================================================ - def add_global_name(self, trans: rawptr[HT.Translator], name: str): + def add_global_name(self, trans: HT.Translator*, name: str): """添加一个 global 变量名""" if trans is None or name is None: return @@ -1257,13 +1245,13 @@ class TranslatorGenMixin: # 检查是否已存在 if self.is_global_name(trans, name) != 0: return - if trans._global_name_count >= MAX_GLOBAL_NAMES: - pool_err: rawptr[memhub.MemBuddy] = trans.Pool + if trans._global_name_count >= HT.MAX_GLOBAL_NAMES: + pool_err: memhub.MemBuddy* = trans.Pool err_buf: str = None if pool_err is not None: err_buf = pool_err.alloc(256) if err_buf is not None: - viperlib.snprintf(err_buf, 256, "global 变量数量超过上限 MAX_GLOBAL_NAMES=%d,请减少 global 声明或增大 MAX_GLOBAL_NAMES", MAX_GLOBAL_NAMES) + viperlib.snprintf(err_buf, 256, "global 变量数量超过上限 MAX_GLOBAL_NAMES=%d,请减少 global 声明或增大 MAX_GLOBAL_NAMES", HT.MAX_GLOBAL_NAMES) VLogger.error(err_buf, "ScopeDecl") else: VLogger.error("global 变量数量超过上限,请减少 global 声明或增大 MAX_GLOBAL_NAMES", "ScopeDecl") @@ -1273,7 +1261,7 @@ class TranslatorGenMixin: slot_ptr[0] = name trans._global_name_count += 1 - def is_global_name(self, trans: rawptr[HT.Translator], name: str) -> int: + def is_global_name(self, trans: HT.Translator*, name: str) -> int: """检查 name 是否在当前函数的 global 集合中""" if trans is None or name is None or trans._global_names is None: return 0 @@ -1286,8 +1274,8 @@ class TranslatorGenMixin: return 1 return 0 - def add_nonlocal_name(self, trans: rawptr[HT.Translator], name: str, - var_ty: rawptr[llvmlite.LLVMType] = None): + def add_nonlocal_name(self, trans: HT.Translator*, name: str, + var_ty: llvmlite.LLVMType* = None): """添加一个 nonlocal 变量名 Args: @@ -1311,13 +1299,13 @@ class TranslatorGenMixin: ty_slot: str | t.CPtr = (t.CPtr)(ty_addr) ty_slot[0] = var_ty return - if trans._nonlocal_name_count >= MAX_GLOBAL_NAMES: - pool_err_nl: rawptr[memhub.MemBuddy] = trans.Pool + if trans._nonlocal_name_count >= HT.MAX_GLOBAL_NAMES: + pool_err_nl: memhub.MemBuddy* = trans.Pool err_buf_nl: str = None if pool_err_nl is not None: err_buf_nl = pool_err_nl.alloc(256) if err_buf_nl is not None: - viperlib.snprintf(err_buf_nl, 256, "nonlocal 变量数量超过上限 MAX_GLOBAL_NAMES=%d,请减少 nonlocal 声明或增大 MAX_GLOBAL_NAMES", MAX_GLOBAL_NAMES) + viperlib.snprintf(err_buf_nl, 256, "nonlocal 变量数量超过上限 MAX_GLOBAL_NAMES=%d,请减少 nonlocal 声明或增大 MAX_GLOBAL_NAMES", HT.MAX_GLOBAL_NAMES) VLogger.error(err_buf_nl, "ScopeDecl") else: VLogger.error("nonlocal 变量数量超过上限,请减少 nonlocal 声明或增大 MAX_GLOBAL_NAMES", "ScopeDecl") @@ -1330,7 +1318,7 @@ class TranslatorGenMixin: ty_addr2: uint64 = uint64(trans._nonlocal_types) + trans._nonlocal_name_count * 8 ty_slot2: str | t.CPtr = (t.CPtr)(ty_addr2) # var_ty 为 None 时直接报错终止(fail-fast),不再默认 i32 - stored_ty: rawptr[llvmlite.LLVMType] = var_ty + stored_ty: llvmlite.LLVMType* = var_ty if stored_ty is None: self.Gen.TypeGenErr.fatal_error(None, f"nonlocal 变量 '{name}' 类型缺失,无法注册", "TypeError") return @@ -1338,8 +1326,8 @@ class TranslatorGenMixin: trans._nonlocal_name_count += 1 trans._closure_env_count += 1 - def get_nonlocal_type(self, trans: rawptr[HT.Translator], - name: str) -> rawptr[llvmlite.LLVMType]: + def get_nonlocal_type(self, trans: HT.Translator*, + name: str) -> llvmlite.LLVMType*: """获取 nonlocal 变量的 LLVM 类型 Returns: 找到的类型指针,找不到返回 None @@ -1351,9 +1339,9 @@ class TranslatorGenMixin: return None ty_addr: uint64 = uint64(trans._nonlocal_types) + idx * 8 ty_slot: str | t.CPtr = (t.CPtr)(ty_addr) - return (rawptr[llvmlite.LLVMType])(ty_slot[0]) + return (llvmlite.LLVMType*)(ty_slot[0]) - def is_nonlocal_name(self, trans: rawptr[HT.Translator], name: str) -> int: + def is_nonlocal_name(self, trans: HT.Translator*, name: str) -> int: """检查 name 是否在当前函数的 nonlocal 集合中""" if trans is None or name is None or trans._nonlocal_names is None: return 0 @@ -1366,7 +1354,7 @@ class TranslatorGenMixin: return 1 return 0 - def get_nonlocal_index(self, trans: rawptr[HT.Translator], name: str) -> int: + def get_nonlocal_index(self, trans: HT.Translator*, name: str) -> int: """获取 nonlocal 变量在 env 中的索引(0-based),找不到返回 -1""" if trans is None or name is None or trans._nonlocal_names is None: return -1 @@ -1379,7 +1367,7 @@ class TranslatorGenMixin: return i return -1 - def clear_scope_names(self, trans: rawptr[HT.Translator]): + def clear_scope_names(self, trans: HT.Translator*): """清空当前函数的 global/nonlocal 名称集合(进入新函数时调用)""" if trans is None: return diff --git a/App/lib/core/Gen/Type/TypeGenBase.vp b/App/lib/core/Gen/Type/TypeGenBase.vp index 57f1a1a..27bf86a 100644 --- a/App/lib/core/Gen/Type/TypeGenBase.vp +++ b/App/lib/core/Gen/Type/TypeGenBase.vp @@ -32,23 +32,23 @@ class TypeGenBase: """字段 + InitTypeGen + trace/临时目录/generic 上下文""" # --- 仿 Python Traceback 调用栈(原 _g_trace_frames/_g_trace_count) --- - Gen: rawptr[Generator.Generator] + Gen: Generator.Generator* TraceFrames: rawptr[GenTypes.TraceFrame] # malloc 数组(TypeGenMixin.TRACE_MAX 槽) TraceCount: int # --- 全局泛型特化上下文(原 _g_generic_tp_names/_g_generic_type_args) --- - GenericTpNames: list[str] | t.CPtr - GenericTypeArgs: list[str] | t.CPtr + GenericTpNames: list[str]* + GenericTypeArgs: list[str]* # 嵌套安全栈:set_generic_context 压入外层值,clear_generic_context 弹出 # 恢复(原单槽赋值:嵌套特化/泛型函数翻译退出时把外层上下文清成 None → # 外层方法体后续的 T 替换丢失 → T.__sizeof__() NameError,VectorGenericTest # 特化 Vector[int].__init__ 回归根因)。 - GenericCtxStack: sizet | t.CPtr # i64* 固定数组:每层 2 个槽(tp_names, type_args 指针) + GenericCtxStack: sizet* # i64* 固定数组:每层 2 个槽(tp_names, type_args 指针) GenericCtxDepth: int # --- 全局 CDefine 编译期常量表(原 _g_cdefine_*) --- - CDefineNames: list[str] | t.CPtr - CDefineValues: list[str] | t.CPtr + CDefineNames: list[str]* + CDefineValues: list[str]* CDefineDoubleFlags: list[int] | t.CPtr CDefineStrFlags: list[int] | t.CPtr # 1=字符串值(如 ZLIB_VERSION: t.CDefine = "1.3.2") CDefineIsDouble: int @@ -58,15 +58,15 @@ class TypeGenBase: # 与 CDefineNames 同池分配、同 clear_cdefine_constants 复位;CDefineNames 只 # 追加不重排 ⇒ 存槽下标稳定;Built == len(CDefineNames) 才可信,不可信/未命中 # 一律回退线性扫描(正确性保证)。 - CDefineNameIdx: sizet | t.CPtr + CDefineNameIdx: sizet* CDefineNameIdxCap: int CDefineNameIdxBuilt: int # --- 跨模块 CDefine 查找缓存(perm_pool 永久分配,跨文件复用) --- # 缓存 reset_to(mark2)/clear_cdefine_constants 不清除 → 跨文件复用, # CONST_INT 递归查找只做一次。 - XmodCdefNames: list[str] | t.CPtr - XmodCdefValues: list[str] | t.CPtr + XmodCdefNames: list[str]* + XmodCdefValues: list[str]* XmodCdefDoubleFlags: list[int] | t.CPtr XmodCdefStrFlags: list[int] | t.CPtr @@ -74,18 +74,18 @@ class TypeGenBase: CurrentModuleSha1: str # --- 全局 CTypedef 表(原 _g_ctypedef_*) --- - CTypedefNames: list[str] | t.CPtr - CTypedefTypeStrs: list[str] | t.CPtr + CTypedefNames: list[str]* + CTypedefTypeStrs: list[str]* CTypedefFound: int # CTypedef 名 → 槽下标 索引(开放寻址 | 线性探测;槽存 index+1,0=空槽)。 # 与 CTypedefNames 同池分配、同 clear_ctypedefs 复位;CTypedefNames 只追加 # 不重排(同名注册原地更新类型串)⇒ 存槽下标稳定;Built == len(CTypedefNames) # 才可信,不可信/未命中一律回退线性扫描(正确性保证)。 - CTypedefNameIdx: sizet | t.CPtr + CTypedefNameIdx: sizet* CTypedefNameIdxCap: int CTypedefNameIdxBuilt: int CTypedefResolveDepth: int - CTypedefVisiting: list[str] | t.CPtr + CTypedefVisiting: list[str]* # builtins 源扫描标记:注解解析"最后匹配"兜底(_lookup_builtins_typedef) # 每文件最多读一次 includes/builtins.vp;随 clear_ctypedefs 复位 BuiltinsTypedefScanned: int @@ -113,8 +113,8 @@ class TypeGenBase: # LibTypedefTypeMap: key="模块名|typedef 名" → 源中原始类型表达式。 # 每次查询都读 64KB 库源全文扫描会使单文件 translate 耗时 7–12s;库源单次编译内 # 不变,故缓存命中结果与逐次读源等价。 - LibTypedefScannedMods: rawptr[hashtable.HashTable] - LibTypedefTypeMap: rawptr[hashtable.HashTable] + LibTypedefScannedMods: hashtable.HashTable* + LibTypedefTypeMap: 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: rawptr[TSpec.TypeSpecArena] + Specs: 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) -> rawptr[TSpec.TypeSpecArena]: + def ensure_spec_arena(self) -> TSpec.TypeSpecArena*: """确保 TypeSpec 驻留表已创建,返回 arena;失败返回 None""" if self.Specs is not None: return self.Specs size: sizet = TSpec.TypeSpecArena.__sizeof__() - arena: rawptr[TSpec.TypeSpecArena] = rawptr[TSpec.TypeSpecArena](CompilerFactory.factory.PermPool.alloc(size)) + arena: TSpec.TypeSpecArena* = TSpec.TypeSpecArena*(CompilerFactory.factory.PermPool.alloc(size)) if arena is None: return None string.memset(arena, 0, size) @@ -259,12 +259,12 @@ class TypeGenBase: def set_current_module_sha1(self, sha1: str) -> None: """设置当前正在编译的模块 SHA1(Phase1 在模块开始翻译前调用)""" self.CurrentModuleSha1 = sha1 - def _dbg_check_ast_floats(self, mb: rawptr[memhub.MemBuddy], - tree: rawptr[ast.AST], tag: str): + def _dbg_check_ast_floats(self, mb: memhub.MemBuddy*, + tree: ast.AST*, tag: str): """已移除调试插桩(占位保留签名,避免外部调用引用失败)""" pass - def set_generic_context(self, tp_names: list[str] | t.CPtr, - type_args: list[str] | t.CPtr): + def set_generic_context(self, tp_names: list[str]*, + type_args: list[str]*): """设置泛型特化上下文(进入泛型类方法体翻译时调用),嵌套安全 先压栈当前(外层)上下文,再设置新值。clear_generic_context 弹出恢复, @@ -288,8 +288,8 @@ class TypeGenBase: """清除泛型特化上下文(离开泛型类方法体翻译时调用),恢复外层而非置 None""" if self.GenericCtxDepth > 0: self.GenericCtxDepth -= 1 - self.GenericTpNames = (list[str] | t.CPtr)(self.GenericCtxStack[self.GenericCtxDepth * 2]) - self.GenericTypeArgs = (list[str] | t.CPtr)(self.GenericCtxStack[self.GenericCtxDepth * 2 + 1]) + self.GenericTpNames = (list[str]*)(self.GenericCtxStack[self.GenericCtxDepth * 2]) + self.GenericTypeArgs = (list[str]*)(self.GenericCtxStack[self.GenericCtxDepth * 2 + 1]) else: self.GenericTpNames = None self.GenericTypeArgs = None diff --git a/App/lib/core/Gen/Type/TypeGenCDef.vp b/App/lib/core/Gen/Type/TypeGenCDef.vp index 727823f..388c1d3 100644 --- a/App/lib/core/Gen/Type/TypeGenCDef.vp +++ b/App/lib/core/Gen/Type/TypeGenCDef.vp @@ -55,13 +55,13 @@ class TypeGenCDef(TypeGenBase.TypeGenBase): i += 1 return h - def _cdef_idx_slot(self, si: sizet) -> sizet | t.CPtr: + def _cdef_idx_slot(self, si: sizet) -> sizet*: """取索引第 si 个槽(8 字节,存槽下标+1;0=空槽)""" - return (sizet | t.CPtr)(uint64(self.CDefineNameIdx) + uint64(si) * 8) + return (sizet*)(uint64(self.CDefineNameIdx) + uint64(si) * 8) - def _cdef_idx_init(self, pool: rawptr[memhub.MemBuddy]) -> None: + def _cdef_idx_init(self, pool: memhub.MemBuddy*) -> None: """创建/清零名索引(与 CDefineNames 同池);失败则标记不可信""" - idx: sizet | t.CPtr = pool.alloc(sizet(CDEFINE_IDX_CAP) * 8) + idx: sizet* = pool.alloc(sizet(CDEFINE_IDX_CAP) * 8) if idx is None: self.CDefineNameIdx = None self.CDefineNameIdxCap = 0 @@ -83,7 +83,7 @@ class TypeGenCDef(TypeGenBase.TypeGenBase): si: sizet = sizet(h) & mask i: int = 0 while i < self.CDefineNameIdxCap: - slot: sizet | t.CPtr = self._cdef_idx_slot(si) + slot: sizet* = self._cdef_idx_slot(si) sv: sizet = slot[0] if sv == 0: return -1 @@ -104,7 +104,7 @@ class TypeGenCDef(TypeGenBase.TypeGenBase): si: sizet = sizet(h) & mask i: int = 0 while i < self.CDefineNameIdxCap: - slot: sizet | t.CPtr = self._cdef_idx_slot(si) + slot: sizet* = self._cdef_idx_slot(si) if slot[0] == 0: slot[0] = sizet(slot_index + 1) return 0 @@ -135,14 +135,14 @@ class TypeGenCDef(TypeGenBase.TypeGenBase): # pool —— 与既有语义一致,只是不再有"表本体跨 reset 存活"的隐式假设。 # ============================================================ def _cdefine_table_pool(self, - pool: rawptr[memhub.MemBuddy]) -> rawptr[memhub.MemBuddy]: + pool: memhub.MemBuddy*) -> memhub.MemBuddy*: """CDefine 表本体的池:恒取 PermPool(不可用则退回入参 pool)""" if CompilerFactory.factory is not None \ and CompilerFactory.factory.PermPool is not None: return CompilerFactory.factory.PermPool return pool - def register_cdefine_constant(self, pool: rawptr[memhub.MemBuddy], + def register_cdefine_constant(self, pool: memhub.MemBuddy*, name: str, value: int64) -> None: """注册 CDefine 编译期常量到本地表 @@ -161,9 +161,9 @@ class TypeGenCDef(TypeGenBase.TypeGenBase): if name is None: return if self.CDefineNames is None: - tp: rawptr[memhub.MemBuddy] = self._cdefine_table_pool(pool) - tn: list[str] | t.CPtr = list[str](tp, 64) - tv: list[str] | t.CPtr = list[str](tp, 64) + tp: memhub.MemBuddy* = self._cdefine_table_pool(pool) + tn: list[str]* = list[str](tp, 64) + tv: list[str]* = list[str](tp, 64) td: list[int] | t.CPtr = list[int](tp, 64) tsf: list[int] | t.CPtr = list[int](tp, 64) # 建表失败(池不可用/耗尽)⇒ 明确报错并返回,绝不让下面的 append @@ -205,7 +205,7 @@ class TypeGenCDef(TypeGenBase.TypeGenBase): self.CDefineDoubleFlags.append(0) if self.CDefineStrFlags is not None: self.CDefineStrFlags.append(0) - def register_cdefine_double(self, pool: rawptr[memhub.MemBuddy], + def register_cdefine_double(self, pool: memhub.MemBuddy*, name: str, value: double) -> None: """注册浮点 CDefine 编译期常量(如 U_M_PI: t.CDefine = 3.14159...) @@ -217,9 +217,9 @@ class TypeGenCDef(TypeGenBase.TypeGenBase): if name is None: return if self.CDefineNames is None: - tp: rawptr[memhub.MemBuddy] = self._cdefine_table_pool(pool) - tn: list[str] | t.CPtr = list[str](tp, 64) - tv: list[str] | t.CPtr = list[str](tp, 64) + tp: memhub.MemBuddy* = self._cdefine_table_pool(pool) + tn: list[str]* = list[str](tp, 64) + tv: list[str]* = list[str](tp, 64) td: list[int] | t.CPtr = list[int](tp, 64) tsf: list[int] | t.CPtr = list[int](tp, 64) if tn is None or tv is None or td is None or tsf is None: @@ -261,7 +261,7 @@ class TypeGenCDef(TypeGenBase.TypeGenBase): if val_buf is None: VLogger.error("CDefine 浮点值缓冲区分配失败", "CDEF-DBG") self.Gen.TypeGenErr.fatal_error(None, "CDefine 浮点值缓冲区分配失败", "MemoryError") - def register_cdefine_string(self, pool: rawptr[memhub.MemBuddy], + def register_cdefine_string(self, pool: memhub.MemBuddy*, name: str, value: str) -> None: """注册字符串 CDefine 编译期常量(如 ZLIB_VERSION: t.CDefine = "1.3.2") @@ -275,9 +275,9 @@ class TypeGenCDef(TypeGenBase.TypeGenBase): self.Gen.TypeGenErr.fatal_error(None, f"CDefine 字符串值缺失: {name}", "InternalCompilerError") return if self.CDefineNames is None: - tp: rawptr[memhub.MemBuddy] = self._cdefine_table_pool(pool) - tn: list[str] | t.CPtr = list[str](tp, 64) - tv: list[str] | t.CPtr = list[str](tp, 64) + tp: memhub.MemBuddy* = self._cdefine_table_pool(pool) + tn: list[str]* = list[str](tp, 64) + tv: list[str]* = list[str](tp, 64) td: list[int] | t.CPtr = list[int](tp, 64) tsf: list[int] | t.CPtr = list[int](tp, 64) if tn is None or tv is None or td is None or tsf is None: @@ -342,7 +342,7 @@ class TypeGenCDef(TypeGenBase.TypeGenBase): x_nm: str = self.XmodCdefNames.get(x_i) if x_nm is not None and string.strcmp(x_nm, name) == 0: return - perm: rawptr[memhub.MemBuddy] = CompilerFactory.factory.PermPool + perm: memhub.MemBuddy* = CompilerFactory.factory.PermPool if self.XmodCdefNames is None: self.XmodCdefNames = list[str](perm, 64) self.XmodCdefValues = list[str](perm, 64) diff --git a/App/lib/core/Gen/Type/TypeGenCType.vp b/App/lib/core/Gen/Type/TypeGenCType.vp index 9c8bcfb..a48fc94 100644 --- a/App/lib/core/Gen/Type/TypeGenCType.vp +++ b/App/lib/core/Gen/Type/TypeGenCType.vp @@ -56,13 +56,13 @@ class TypeGenCType(TypeGenBase.TypeGenBase): # ============================================================ # CTypedef 名索引(开放寻址;槽存 index+1,0=空槽) # ============================================================ - def _ctypedef_idx_slot(self, si: sizet) -> sizet | t.CPtr: + def _ctypedef_idx_slot(self, si: sizet) -> sizet*: """取索引第 si 个槽(8 字节,存槽下标+1;0=空槽)""" - return (sizet | t.CPtr)(uint64(self.CTypedefNameIdx) + uint64(si) * 8) + return (sizet*)(uint64(self.CTypedefNameIdx) + uint64(si) * 8) - def _ctypedef_idx_init(self, pool: rawptr[memhub.MemBuddy]) -> None: + def _ctypedef_idx_init(self, pool: memhub.MemBuddy*) -> None: """创建/清零名索引(与 CTypedefNames 同池);失败则标记不可信""" - idx: sizet | t.CPtr = pool.alloc(sizet(CTYPEDEF_IDX_CAP) * 8) + idx: sizet* = pool.alloc(sizet(CTYPEDEF_IDX_CAP) * 8) if idx is None: self.CTypedefNameIdx = None self.CTypedefNameIdxCap = 0 @@ -84,7 +84,7 @@ class TypeGenCType(TypeGenBase.TypeGenBase): si: sizet = sizet(h) & mask i: int = 0 while i < self.CTypedefNameIdxCap: - slot: sizet | t.CPtr = self._ctypedef_idx_slot(si) + slot: sizet* = self._ctypedef_idx_slot(si) sv: sizet = slot[0] if sv == 0: return -1 @@ -105,7 +105,7 @@ class TypeGenCType(TypeGenBase.TypeGenBase): si: sizet = sizet(h) & mask i: int = 0 while i < self.CTypedefNameIdxCap: - slot: sizet | t.CPtr = self._ctypedef_idx_slot(si) + slot: sizet* = self._ctypedef_idx_slot(si) if slot[0] == 0: slot[0] = sizet(slot_index + 1) return 0 @@ -136,14 +136,14 @@ class TypeGenCType(TypeGenBase.TypeGenBase): # pool —— 与既有语义一致,只是不再有"表本体跨 reset 存活"的隐式假设。 # ============================================================ def _ctypedef_table_pool(self, - pool: rawptr[memhub.MemBuddy]) -> rawptr[memhub.MemBuddy]: + pool: memhub.MemBuddy*) -> memhub.MemBuddy*: """CTypedef 表本体的池:恒取 PermPool(不可用则退回入参 pool)""" if CompilerFactory.factory is not None \ and CompilerFactory.factory.PermPool is not None: return CompilerFactory.factory.PermPool return pool - def register_ctypedef(self, pool: rawptr[memhub.MemBuddy], + def register_ctypedef(self, pool: memhub.MemBuddy*, name: str, type_str: str) -> None: """注册 CTypedef 到本地表 @@ -174,9 +174,9 @@ class TypeGenCType(TypeGenBase.TypeGenBase): return string.strcpy(type_copy, type_str) if self.CTypedefNames is None: - tp: rawptr[memhub.MemBuddy] = self._ctypedef_table_pool(pool) - tn: list[str] | t.CPtr = list[str](tp, 64) - ts: list[str] | t.CPtr = list[str](tp, 64) + tp: memhub.MemBuddy* = self._ctypedef_table_pool(pool) + tn: list[str]* = list[str](tp, 64) + ts: list[str]* = list[str](tp, 64) # 建表失败(池不可用/耗尽)⇒ 明确报错并返回,绝不让下面的 append # 落到 None 或未初始化地址(原实现无检查 ⇒ 写进 0xCDCD 区崩) if tn is None or ts is None: @@ -464,7 +464,7 @@ class TypeGenCType(TypeGenBase.TypeGenBase): if self.ImportAliasBuf is not None: stdlib.free(self.ImportAliasBuf) self.ImportAliasBuf = None - def _ctypedef_push_visiting(self, pool: rawptr[memhub.MemBuddy], name: str) -> int: + def _ctypedef_push_visiting(self, pool: memhub.MemBuddy*, name: str) -> int: """将 CTypedef 名加入正在解析列表(循环检测) Returns: @@ -475,7 +475,7 @@ class TypeGenCType(TypeGenBase.TypeGenBase): if self.CTypedefVisiting is None: # 与 CTypedef 表同池(PermPool):clear_ctypedefs 只清空、指针不丢, # 避免这张表也落在会被 reset_to 回收的调用方池上 - vp: rawptr[memhub.MemBuddy] = self._ctypedef_table_pool(pool) + vp: memhub.MemBuddy* = self._ctypedef_table_pool(pool) self.CTypedefVisiting = list[str](vp, 32) if self.CTypedefVisiting is None: return 0 @@ -494,7 +494,7 @@ class TypeGenCType(TypeGenBase.TypeGenBase): vn: sizet = len(self.CTypedefVisiting) if vn > 0: self.CTypedefVisiting.pop() - def _is_ctypedef_annotation(self, annotation: rawptr[ast.AST]) -> int: + def _is_ctypedef_annotation(self, annotation: ast.AST*) -> int: """检测类型注解是否为 t.CTypedef Args: @@ -508,7 +508,7 @@ class TypeGenCType(TypeGenBase.TypeGenBase): k_v: int = annotation.kind() if k_v != ast.ASTKind.Attribute: return 0 - at: rawptr[ast.Attribute] = rawptr[ast.Attribute](annotation) + at: ast.Attribute* = ast.Attribute*(annotation) # 字段访问改用 ast 模块访问器(直接访问 at.attr 可能按 stub 类型生成错误 GEP, # 读垃圾地址 → strcmp 崩溃)。 at_attr_v: str = ast.attribute_get_attr(at) @@ -523,10 +523,10 @@ class TypeGenCType(TypeGenBase.TypeGenBase): if sep_ch_d != '\0' and sep_ch_d != ' ' and sep_ch_d != '\n' \ and sep_ch_d != '\r' and sep_ch_d != '\t' and sep_ch_d != '|': return 0 - at_val_v: rawptr[ast.AST] = ast.attribute_get_value(at) + at_val_v: ast.AST* = ast.attribute_get_value(at) if at_val_v is None or at_val_v.kind() != ast.ASTKind.Name: return 0 - mod_nm: rawptr[ast.Name] = rawptr[ast.Name](at_val_v) + mod_nm: ast.Name* = ast.Name*(at_val_v) mod_id_v: str = ast.name_get_id(mod_nm) if mod_id_v is None: return 0 @@ -538,8 +538,8 @@ class TypeGenCType(TypeGenBase.TypeGenBase): and sep_ch_m != '\r' and sep_ch_m != '\t' and sep_ch_m != '|': return 0 return 1 - def ScanCTypedefDeclarations(self, pool: rawptr[memhub.MemBuddy], - tree: rawptr[ast.AST]) -> int: + def ScanCTypedefDeclarations(self, pool: memhub.MemBuddy*, + tree: ast.AST*) -> int: """扫描 AST 顶层节点,注册所有 NAME: t.CTypedef = Type 声明 在 _translate_module_level 中、模块级变量预注册之前调用, @@ -561,12 +561,12 @@ class TypeGenCType(TypeGenBase.TypeGenBase): count: int = 0 i: sizet for i in range(n): - child: rawptr[ast.AST] = ch.get(i) + child: ast.AST* = ch.get(i) if child is None: continue if child.kind() != ast.ASTKind.AnnAssign: continue - aa: rawptr[ast.AnnAssign] = rawptr[ast.AnnAssign](child) + aa: ast.AnnAssign* = ast.AnnAssign*(child) if aa.annotation is None: continue # 检测注解是否为 t.CTypedef @@ -575,7 +575,7 @@ class TypeGenCType(TypeGenBase.TypeGenBase): # 提取目标名称(必须是 Name 节点) if aa.target is None or aa.target.kind() != ast.ASTKind.Name: continue - tgt: rawptr[ast.Name] = rawptr[ast.Name](aa.target) + tgt: ast.Name* = ast.Name*(aa.target) tgt_id_v: str = ast.name_get_id(tgt) if tgt_id_v is None: continue @@ -589,7 +589,7 @@ class TypeGenCType(TypeGenBase.TypeGenBase): self.register_ctypedef(pool, tgt_id_v, type_str) count += 1 return count - def register_ctypedef_from_source(self, pool: rawptr[memhub.MemBuddy], + def register_ctypedef_from_source(self, pool: memhub.MemBuddy*, src: str) -> int: """从源码文本逐行扫描注册 CTypedef(NAME: t.CTypedef = TYPE) @@ -662,8 +662,8 @@ class TypeGenCType(TypeGenBase.TypeGenBase): line_start = i + 1 i += 1 return count - def _eval_const_int_expr(self, node: rawptr[ast.AST], - pool: rawptr[memhub.MemBuddy] = None, + def _eval_const_int_expr(self, node: ast.AST*, + pool: memhub.MemBuddy* = None, from_imports: str = None, imported_modules: str = None, depth: int = 0) -> int: @@ -687,7 +687,7 @@ class TypeGenCType(TypeGenBase.TypeGenBase): # Constant: 整数字面量 if k == ast.ASTKind.Constant: - cn: rawptr[ast.Constant] = rawptr[ast.Constant](node) + cn: ast.Constant* = ast.Constant*(node) if cn.const_kind == ast.CONST_INT: self.ConstEvalOk = 1 return cn.int_val @@ -696,7 +696,7 @@ class TypeGenCType(TypeGenBase.TypeGenBase): # Name: CDefine 常量名(本地表优先,未命中走跨模块查找) if k == ast.ASTKind.Name: - nm: rawptr[ast.Name] = rawptr[ast.Name](node) + nm: ast.Name* = ast.Name*(node) if nm.id is None: self.ConstEvalOk = 0 return 0 @@ -722,12 +722,12 @@ class TypeGenCType(TypeGenBase.TypeGenBase): # 复用跨模块 CDefine 查找:*:模块 → 源文件提取;re-export 常量由 # _lookup_cross_module_cdefine 的 from-import 递归子模块兜底) if k == ast.ASTKind.Attribute: - at: rawptr[ast.Attribute] = rawptr[ast.Attribute](node) + at: ast.Attribute* = ast.Attribute*(node) if at.attr is None: self.ConstEvalOk = 0 return 0 if at.value is not None and at.value.kind() == ast.ASTKind.Name: - at_mod: rawptr[ast.Name] = rawptr[ast.Name](at.value) + at_mod: ast.Name* = ast.Name*(at.value) if at_mod.id is not None: if (from_imports is not None or imported_modules is not None) \ and pool is not None: @@ -749,7 +749,7 @@ class TypeGenCType(TypeGenBase.TypeGenBase): # BinOp: 算术/位运算 if k == ast.ASTKind.BinOp: - bop: rawptr[ast.BinOp] = rawptr[ast.BinOp](node) + bop: ast.BinOp* = ast.BinOp*(node) # 递归计算左操作数 lv: int = self._eval_const_int_expr(bop.left, pool, from_imports, imported_modules, depth + 1) if self.ConstEvalOk == 0: diff --git a/App/lib/core/Gen/Type/TypeGenErr.vp b/App/lib/core/Gen/Type/TypeGenErr.vp index 84b95ca..9fee6a6 100644 --- a/App/lib/core/Gen/Type/TypeGenErr.vp +++ b/App/lib/core/Gen/Type/TypeGenErr.vp @@ -104,7 +104,7 @@ class TypeGenErr(TypeGenBase.TypeGenBase): if err_msg is None or err_msg[0] == 0: err_msg = "语法错误" stdio.printf("SyntaxError: %s\n", err_msg) - def fatal_error(self, node: rawptr[ast.AST], msg: str, + def fatal_error(self, node: ast.AST*, msg: str, err_type: str = "SyntaxError", col_start: int = 0, col_end: int = 0): """以 Python 风格报错并退出(支持多帧、错误类型、列范围) @@ -181,35 +181,35 @@ class TypeGenErr(TypeGenBase.TypeGenBase): # (Traceback 已打印,进程存活);批处理下该出口即 sys.exit(1),逐字不变。 VLogger.repl_abort() - def fatal_type_error(self, node: rawptr[ast.AST], msg: str, + def fatal_type_error(self, node: ast.AST*, msg: str, col_start: int = 0, col_end: int = 0): """以 Python 风格报错并退出(TypeError 版本)""" self.fatal_error(node, msg, "TypeError", col_start, col_end) - def try_extract_callable_ret(self, pool: rawptr[memhub.MemBuddy], - annot: rawptr[ast.AST], + def try_extract_callable_ret(self, pool: memhub.MemBuddy*, + annot: ast.AST*, imported_modules: str, from_imports: str, - trans: rawptr[HT.Translator]) -> rawptr[llvmlite.LLVMType]: + trans: HT.Translator*) -> llvmlite.LLVMType*: """提取 t.Callable 注解的返回类型 LLVMType;非 Callable 注解返回 None""" if annot is None or annot.kind() != ast.ASTKind.Subscript: return None - sub_cr: rawptr[ast.Subscript] = rawptr[ast.Subscript](annot) + sub_cr: ast.Subscript* = ast.Subscript*(annot) if sub_cr.value is None or sub_cr.value.kind() != ast.ASTKind.Attribute: return None - at_cr: rawptr[ast.Attribute] = rawptr[ast.Attribute](sub_cr.value) + at_cr: ast.Attribute* = ast.Attribute*(sub_cr.value) if at_cr.attr is None or string.strcmp(at_cr.attr, "Callable") != 0: return None # slice 必须是 Tuple(elts=[args_list, ret_node]) if sub_cr.slice is None or sub_cr.slice.kind() != ast.ASTKind.Tuple: return None - tp_cr: rawptr[ast.Tuple] = rawptr[ast.Tuple](sub_cr.slice) + tp_cr: ast.Tuple* = ast.Tuple*(sub_cr.slice) if tp_cr.elts is None or len(tp_cr.elts) != 2: return None - ret_node_cr: rawptr[ast.AST] = tp_cr.elts.get(1) + ret_node_cr: ast.AST* = tp_cr.elts.get(1) if ret_node_cr is None: return None return self.Gen.TypeGenResolve.resolve_annotation_type(pool, ret_node_cr, imported_modules, from_imports, trans, 0) - def has_decorator_marker(self, node: rawptr[ast.AST], + def has_decorator_marker(self, node: ast.AST*, marker_name: str, depth: int = 0) -> int: """检测类型注解中是否包含指定的装饰器标记""" @@ -225,7 +225,7 @@ class TypeGenErr(TypeGenBase.TypeGenBase): # Attribute 节点: t.CExtern, t.State, t.CExport, t.CInline if k == ast.ASTKind.Attribute: - at: rawptr[ast.Attribute] = rawptr[ast.Attribute](node) + at: ast.Attribute* = ast.Attribute*(node) if at.attr is not None: if string.strcmp(at.attr, marker_name) == 0: return 1 @@ -233,7 +233,7 @@ class TypeGenErr(TypeGenBase.TypeGenBase): # BinOp 节点: int | t.CExtern(递归检测左右子节点) if k == ast.ASTKind.BinOp: - bop: rawptr[ast.BinOp] = rawptr[ast.BinOp](node) + bop: ast.BinOp* = ast.BinOp*(node) if self.has_decorator_marker(bop.left, marker_name, depth + 1) != 0: return 1 if self.has_decorator_marker(bop.right, marker_name, depth + 1) != 0: @@ -242,7 +242,7 @@ class TypeGenErr(TypeGenBase.TypeGenBase): return 0 - def has_pointee_volatile_marker(self, node: rawptr[ast.AST]) -> int: + def has_pointee_volatile_marker(self, node: ast.AST*) -> int: """检测指针注解 rawptr[...] 的下标实参是否含 t.CVolatile 标记,1=是 / 0=否 语义:rawptr[t.CVolatile | T] 等价 C 的 volatile T*,即"指针所指对象按 @@ -259,16 +259,36 @@ class TypeGenErr(TypeGenBase.TypeGenBase): """ if node is None or node.kind() != ast.ASTKind.Subscript: return 0 - sub: rawptr[ast.Subscript] = rawptr[ast.Subscript](node) + sub: ast.Subscript* = ast.Subscript*(node) if sub.value is None or sub.value.kind() != ast.ASTKind.Name: return 0 - rp_nm: rawptr[ast.Name] = rawptr[ast.Name](sub.value) + rp_nm: ast.Name* = ast.Name*(sub.value) if rp_nm.id is None or string.strcmp(rp_nm.id, "rawptr") != 0: return 0 if sub.slice is None: return 0 return self.has_decorator_marker(sub.slice, "CVolatile", 0) + def is_const_object_marker(self, node: ast.AST*, + var_ty: llvmlite.LLVMType*) -> int: + """变量/字段本身是否 **const 对象**(1=是 / 0=否)。 + + 判据与 TPC 的 BaseGen._IsConstObject **逐条一致**(见 Debugger/type-descriptors.md): + ① 注解子树含 t.CConst(has_decorator_marker,与 TPC 的 _AnnotationHasQualifier 同口径); + ② 声明类型的 LLVM 形态**不是指针**(TPC 用 PtrCount==0 表达同一件事)。 + `t.CConst` 在本语言里承载「指向的数据 const」(对齐 TPC 的 DataConst 语义), + 对非指针类型该限定退化为「该对象自身 const」⇒ 登记为 const 变量/字段; + 对指针类型(`p: t.CConst | T | t.CPtr`)限定只作用于 pointee ⇒ 指针变量自身 + 仍可重新赋值,不登记。 + """ + if self.has_decorator_marker(node, "CConst", 0) == 0: + return 0 + if var_ty is None: + return 0 + if var_ty.kind() == llvmlite.LLVMType.Ptr: + return 0 + return 1 + def is_pass_body(self, body: list[ast.AST*]*) -> int: """检测函数体是否为 pass(空体或仅含 pass 语句)""" if body is None: @@ -277,19 +297,19 @@ class TypeGenErr(TypeGenBase.TypeGenBase): if bn == 0: return 1 if bn == 1: - stmt: rawptr[ast.AST] = body.get(0) + stmt: ast.AST* = body.get(0) if stmt is not None and stmt.kind() == ast.ASTKind.Pass: return 1 return 0 # 获取 LLVM 整数类型的位宽 # 实现已收拢到 TSpec.SpecTypeBits(该块在 TypeSpec 模块中的唯一实现),此处只做委托。 # 私有调用点(self.get_llvm_type_bits)保持原样不受影响。 - def get_llvm_type_bits(self, ty: rawptr[llvmlite.LLVMType]) -> int: + def get_llvm_type_bits(self, ty: llvmlite.LLVMType*) -> int: """获取 LLVM 整数类型的位宽,非整数类型返回 0(委托 SpecTypeBits)""" return TSpec.SpecTypeBits(ty) - def infer_expr_type(self, pool: rawptr[memhub.MemBuddy], - node: rawptr[ast.AST], - param_types: str) -> rawptr[llvmlite.LLVMType]: + def infer_expr_type(self, pool: memhub.MemBuddy*, + node: ast.AST*, + param_types: str) -> llvmlite.LLVMType*: """推断表达式的 LLVM 类型 param_types 格式: "name:bits,name:bits,..." @@ -303,7 +323,7 @@ class TypeGenErr(TypeGenBase.TypeGenBase): return llvmlite.Int32(pool) elif k == ast.ASTKind.Name: - nm: rawptr[ast.Name] = rawptr[ast.Name](node) + nm: ast.Name* = ast.Name*(node) if nm.id is not None and param_types is not None: # 在 param_types 中查找: "name:bits" 格式 # 键按精确长度分配:固定 64 缓冲 + snprintf("%s:") 会静默截断超长参数名, @@ -334,10 +354,10 @@ class TypeGenErr(TypeGenBase.TypeGenBase): return llvmlite.Int32(pool) elif k == ast.ASTKind.BinOp: - binop: rawptr[ast.BinOp] = rawptr[ast.BinOp](node) - lhs_ty: rawptr[llvmlite.LLVMType] = self.infer_expr_type( + binop: ast.BinOp* = ast.BinOp*(node) + lhs_ty: llvmlite.LLVMType* = self.infer_expr_type( pool, binop.left, param_types) - rhs_ty: rawptr[llvmlite.LLVMType] = self.infer_expr_type( + rhs_ty: llvmlite.LLVMType* = self.infer_expr_type( pool, binop.right, param_types) lhs_bits: int = self.get_llvm_type_bits(lhs_ty) rhs_bits: int = self.get_llvm_type_bits(rhs_ty) @@ -346,21 +366,21 @@ class TypeGenErr(TypeGenBase.TypeGenBase): return rhs_ty return llvmlite.Int32(pool) - def infer_return_type(self, pool: rawptr[memhub.MemBuddy], + def infer_return_type(self, pool: memhub.MemBuddy*, body: list[ast.AST*]*, - param_types: str) -> rawptr[llvmlite.LLVMType]: + param_types: str) -> llvmlite.LLVMType*: """扫描函数体中的 return 语句,推断返回类型""" if body is None: return llvmlite.Int32(pool) - ret_ty: rawptr[llvmlite.LLVMType] = llvmlite.Int32(pool) + ret_ty: llvmlite.LLVMType* = llvmlite.Int32(pool) bn: sizet = len(body) for bi in range(bn): - stmt: rawptr[ast.AST] = body.get(bi) + stmt: ast.AST* = body.get(bi) if stmt is not None and stmt.kind() == ast.ASTKind.Return: rt: rawptr[ast.Return] = rawptr[ast.Return](stmt) if rt.value is not None: - expr_ty: rawptr[llvmlite.LLVMType] = self.infer_expr_type( + expr_ty: llvmlite.LLVMType* = self.infer_expr_type( pool, rt.value, param_types) if expr_ty is not None: cur_bits: int = self.get_llvm_type_bits(ret_ty) @@ -368,7 +388,7 @@ class TypeGenErr(TypeGenBase.TypeGenBase): if new_bits > cur_bits: ret_ty = expr_ty return ret_ty - def body_has_value_return(self, pool: rawptr[memhub.MemBuddy], + def body_has_value_return(self, pool: memhub.MemBuddy*, body: list[ast.AST*]*) -> int: """扫描函数体,判断是否存在返回非 None 值的 return @@ -383,7 +403,7 @@ class TypeGenErr(TypeGenBase.TypeGenBase): return 0 bn: sizet = len(body) for bi in range(bn): - stmt: rawptr[ast.AST] = body.get(bi) + stmt: ast.AST* = body.get(bi) if stmt is None: continue k: int = stmt.kind() @@ -392,7 +412,7 @@ class TypeGenErr(TypeGenBase.TypeGenBase): if rt.value is not None: # return None(CONST_NONE)不算返回非 None 值 if rt.value.kind() == ast.ASTKind.Constant: - cn: rawptr[ast.Constant] = rawptr[ast.Constant](rt.value) + cn: ast.Constant* = ast.Constant*(rt.value) if cn.const_kind == ast.CONST_NONE: continue return 1 @@ -406,8 +426,8 @@ class TypeGenErr(TypeGenBase.TypeGenBase): if self.body_has_value_return(pool, sub) != 0: return 1 return 0 - def build_param_types_str(self, pool: rawptr[memhub.MemBuddy], - args_node: rawptr[ast.AST]) -> str: + def build_param_types_str(self, pool: memhub.MemBuddy*, + args_node: ast.AST*) -> str: """构建参数类型编码字符串 "name:bits,name:bits,..." [D5·截断纪律] 旧实现按 `an * 32 + 1` 预估缓冲,再用 `_strappend` 以 @@ -420,7 +440,7 @@ class TypeGenErr(TypeGenBase.TypeGenBase): """ if args_node is None: return None - ags: rawptr[ast.Arguments] = rawptr[ast.Arguments](args_node) + ags: ast.Arguments* = ast.Arguments*(args_node) if ags.args is None: return None alist: list[ast.AST*]* = ags.args @@ -435,7 +455,7 @@ class TypeGenErr(TypeGenBase.TypeGenBase): bound: sizet = 1 # 末尾 NUL pre_i: sizet for pre_i in range(an): - pre_arg: rawptr[ast.Arg] = rawptr[ast.Arg](alist.get(pre_i)) + pre_arg: ast.Arg* = ast.Arg*(alist.get(pre_i)) if pre_arg is None or pre_arg.arg is None: continue bound += string.strlen(pre_arg.arg) + 1 + 12 + 1 @@ -446,19 +466,19 @@ class TypeGenErr(TypeGenBase.TypeGenBase): # 2) 单遍:解析类型 → 就地格式化条目 → 立即拼接(缓冲为上界,不会截断) cnt: sizet = 0 - i32_ty: rawptr[llvmlite.LLVMType] = llvmlite.Int32(pool) + i32_ty: llvmlite.LLVMType* = llvmlite.Int32(pool) for ai in range(an): - arg: rawptr[ast.Arg] = rawptr[ast.Arg](alist.get(ai)) + arg: ast.Arg* = ast.Arg*(alist.get(ai)) if arg is None or arg.arg is None: continue - param_ty: rawptr[llvmlite.LLVMType] = i32_ty + param_ty: llvmlite.LLVMType* = i32_ty if arg.annotation is not None: # 统一口径:CTypedef 动态表优先,miss 回退 map_t_type # (阶段 2:删除 map_t_type 硬编码别名后,BYTE 等靠库 typedef) if arg.annotation.kind() == ast.ASTKind.Attribute: - at: rawptr[ast.Attribute] = rawptr[ast.Attribute](arg.annotation) + at: ast.Attribute* = ast.Attribute*(arg.annotation) if at.attr is not None: - resolved: rawptr[llvmlite.LLVMType] = self.Gen.TypeGenResolve.resolve_typedef_or_map(pool, at.attr, None, None) + resolved: llvmlite.LLVMType* = self.Gen.TypeGenResolve.resolve_typedef_or_map(pool, at.attr, None, None) if resolved is not None: param_ty = resolved bits: int = self.get_llvm_type_bits(param_ty) diff --git a/App/lib/core/Gen/Type/TypeGenResolve.vp b/App/lib/core/Gen/Type/TypeGenResolve.vp index 29c95dd..c553c18 100644 --- a/App/lib/core/Gen/Type/TypeGenResolve.vp +++ b/App/lib/core/Gen/Type/TypeGenResolve.vp @@ -36,15 +36,15 @@ import w32.fileio as fileio class TypeGenResolve(TypeGenBase.TypeGenBase): """类型映射/注解解析(map_t_type/resolve_annotation_type 等)""" - def _get_type_name_from_annotation(self, pool: rawptr[memhub.MemBuddy], - node: rawptr[ast.AST]) -> str: + def _get_type_name_from_annotation(self, pool: memhub.MemBuddy*, + node: ast.AST*) -> str: """从类型注解节点提取类型名(支持 Name/Attribute/BinOp)""" if node is None: return None k: int = node.kind() # Constant: 字符串注解,直接返回字符串值 if k == ast.ASTKind.Constant: - cn: rawptr[ast.Constant] = rawptr[ast.Constant](node) + cn: ast.Constant* = ast.Constant*(node) cn_val_v: str = ast.constant_get_str_val(cn) if cn.const_kind == ast.CONST_STR and cn_val_v is not None: return cn_val_v @@ -52,7 +52,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): # Name: 直接返回 id(泛型特化上下文内先做 T 替换,避免 ndarray[T] 中 T 未解析 # 导致 _specialize_generic_class("ndarray", ["T"]) 二次递归崩溃) if k == ast.ASTKind.Name: - nm: rawptr[ast.Name] = rawptr[ast.Name](node) + nm: ast.Name* = ast.Name*(node) # 直接用字段:ast.name_get_id 是跨模块访问器,Phase A 阶段 exprs.vp # text.ll 未生成时该访问器是 stub(declare 无体)返回 None,导致 # 泛型类型实参提取失败(list[int] 的 int 被误判未提取)。 @@ -62,11 +62,11 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): # Phase A 阶段对应 text.ll 未生成时是 stub 无体返回 None → tn_raw 为空 → # Box[int](v) 泛型实参提取失败,与 Name 分支 L53-55 同源)。 if k == ast.ASTKind.Attribute: - at: rawptr[ast.Attribute] = rawptr[ast.Attribute](node) + at: ast.Attribute* = ast.Attribute*(node) if at.attr is None: return None if at.value is not None and at.value.kind() == ast.ASTKind.Name: - mod_nm: rawptr[ast.Name] = rawptr[ast.Name](at.value) + mod_nm: ast.Name* = ast.Name*(at.value) if mod_nm.id is not None: total: sizet = string.strlen(mod_nm.id) + 1 + string.strlen(at.attr) + 1 buf: str = pool.alloc(total) @@ -84,7 +84,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): # None → 注册失败 → 同 vpi 后续裸类名 lookup_ctypedef 失败 fail-fast, # VKernel idt.vp irq_handler_t 根因)。 if k == ast.ASTKind.Subscript: - sub_s: rawptr[ast.Subscript] = rawptr[ast.Subscript](node) + sub_s: ast.Subscript* = ast.Subscript*(node) val_s: str = self._get_type_name_from_annotation(pool, sub_s.value) if val_s is None: return None @@ -103,7 +103,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): return None # BinOp (BitOr): 构造 "left|right" 格式 if k == ast.ASTKind.BinOp: - bop: rawptr[ast.BinOp] = rawptr[ast.BinOp](node) + bop: ast.BinOp* = ast.BinOp*(node) if bop.op == ast.OpKind.BitOr: left_str: str = self._get_type_name_from_annotation(pool, ast.binop_get_left(bop)) right_str: str = self._get_type_name_from_annotation(pool, ast.binop_get_right(bop)) @@ -118,8 +118,8 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): return buf2 return None return None - def _subscript_slice_to_str(self, pool: rawptr[memhub.MemBuddy], - node: rawptr[ast.AST]) -> str: + def _subscript_slice_to_str(self, pool: memhub.MemBuddy*, + node: ast.AST*) -> str: """Subscript slice 节点转类型字符串(递归,支持 Name/Attribute/BinOp/Constant/List/Tuple/Subscript)""" if node is None: return None @@ -130,7 +130,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): return self._get_type_name_from_annotation(pool, node) # Constant:数值/字符串字面量(t.CArray[elem, 104] 的 count 等) if k2 == ast.ASTKind.Constant: - cn2: rawptr[ast.Constant] = rawptr[ast.Constant](node) + cn2: ast.Constant* = ast.Constant*(node) if cn2.const_kind == ast.CONST_INT: buf2: str = pool.alloc(24) if buf2 is not None: @@ -141,17 +141,17 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): return None # List:Callable 参数列表([[A], B]),元素递归,逗号连接 if k2 == ast.ASTKind.List: - lst: rawptr[ast.List] = rawptr[ast.List](node) + lst: ast.List* = 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 # 内**不带括号**输出("x, y"),否则 "t.Callable[([int], int)]" # 的显式括号 Tuple slice 会让 ast.parse_expression 解析失败。 if k2 == ast.ASTKind.Tuple: - tup: rawptr[ast.Tuple] = rawptr[ast.Tuple](node) + tup: ast.Tuple* = ast.Tuple*(node) return self._list_elts_to_type_str(pool, tup.elts, "", "") return None - def _list_elts_to_type_str(self, pool: rawptr[memhub.MemBuddy], + def _list_elts_to_type_str(self, pool: memhub.MemBuddy*, elts: list[ast.AST*]*, open_ch: str, close_ch: str) -> str: """元素列表转逗号分隔字符串(List/Tuple 共用),包上 open/close 括号 @@ -173,7 +173,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): total3: sizet = 2 # open + close(各按 1 字节算;实参为空串时多算无害) cnt3: sizet = 0 for i3 in range(n3): - e3: rawptr[ast.AST] = elts.get(i3) + e3: ast.AST* = elts.get(i3) if e3 is None: continue es3: str = self._subscript_slice_to_str(pool, e3) @@ -194,7 +194,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): string.strcat(buf4, open_ch) wrote3: sizet = 0 for i4 in range(n3): - e4: rawptr[ast.AST] = elts.get(i4) + e4: ast.AST* = elts.get(i4) if e4 is None: continue es4: str = self._subscript_slice_to_str(pool, e4) @@ -217,7 +217,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): 此处只做委托:保留本方法是因 `@t.NoVTable` 静态绑定下大量调用点依赖它存在。 """ return GenApi.sha1_prefix_len(s) - def _concat_sha1_class(self, pool: rawptr[memhub.MemBuddy], + def _concat_sha1_class(self, pool: memhub.MemBuddy*, sha1: str, cls_name: str) -> str: """拼接 "{sha1}.{cls_name}"(pool 分配),失败返回 None""" if pool is None or sha1 is None or cls_name is None: @@ -231,9 +231,9 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): string.strcat(buf, ".") string.strcat(buf, cls_name) return buf - def _repl_opaque_class_ty(self, pool: rawptr[memhub.MemBuddy], + def _repl_opaque_class_ty(self, pool: memhub.MemBuddy*, mod_sha1: str, - cls_name: str) -> rawptr[llvmlite.LLVMType]: + cls_name: str) -> llvmlite.LLVMType*: """(REPL 会话专用)未登记类别的"仅类型"占位:`%"{sha1}.{类名}"` opaque 具名结构体 背景:REPL 的 includes 类注册(M4.2)只登记**布局可信**的类;缺 `.stub.ll` @@ -261,20 +261,20 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): full: str = self._concat_sha1_class(pool, mod_sha1, cls_name) if full is None: return None - ex: rawptr[llvmlite.LLVMType] = self.Gen.StructGen.get_struct_type(full) + ex: llvmlite.LLVMType* = self.Gen.StructGen.get_struct_type(full) if ex is not None: return ex # fcount=-1 = opaque 哨兵(区别于空结构体 {}:后者 fcount==0 是"完整定义、 # 可 alloca");与 llvmlite 的跨模块 opaque 声明同一表示。 return llvmlite.Struct(pool, None, -1, full) - def _norm_type_arg_name(self, pool: rawptr[memhub.MemBuddy], + def _norm_type_arg_name(self, pool: memhub.MemBuddy*, type_name: str, from_imports: str) -> str: """泛型类型参数名 SHA1 规范化:统一为 "{定义模块SHA1}.{Class}" 形式 收敛同一类型的不同书写(ast.AST / AST → f467978339422f32.AST), 消除跨模块特化名分裂(undefined symbol: 7cadfe07e983fd90.list[AST].set 根因: - 一侧注解写 "list[rawptr[ast.AST]]"、另一侧写 "list[AST | t.CPtr]", + 一侧注解写 "list[ast.AST*]"、另一侧写 "list[AST | t.CPtr]", 生成两个不同特化名 → 结构体/方法注册与调用不一致)。 规则(自顶向下): @@ -398,7 +398,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): # 数据)→ _norm_type_arg_name 递归 strlen 崩(ViperOS Mat4.m # t.CArray[t.CArray[float, 4], 4] 崩溃根因:strlen 参数三次 # 均为低 16 位 0x2850、高 48 位漂移)。 - arg_list_g: list[str] | t.CPtr = list[str](pool, 8) + arg_list_g: list[str]* = list[str](pool, 8) if arg_list_g is not None: arg_start_g: sizet = 0 cur_dep_g = 0 @@ -530,9 +530,9 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): return 1 return 0 - def _parse_type_string(self, pool: rawptr[memhub.MemBuddy], + def _parse_type_string(self, pool: memhub.MemBuddy*, type_str: str, - ctx: int) -> rawptr[ast.AST]: + ctx: int) -> ast.AST*: """将类型名字符串解析为 AST 节点 正确处理 '|' 与 '.' 周围的空格(如 "ParsedArgs | t.CPtr"): @@ -570,9 +570,9 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): return None string.strncpy(left_buf, type_str, left_len) left_buf[left_len] = '\0' - left_node: rawptr[ast.AST] = self._parse_type_string(pool, left_buf, ctx) + left_node: ast.AST* = self._parse_type_string(pool, left_buf, ctx) # 右段前导空格由递归入口跳过 - right_node: rawptr[ast.AST] = self._parse_type_string( + right_node: ast.AST* = self._parse_type_string( pool, type_str + pipe_idx + 1, ctx) stdlib.free(left_buf) if left_node is not None and right_node is not None: @@ -624,8 +624,8 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): base_buf_m[base_len_m] = '\0' string.strncpy(inner_buf_m, type_str + bracket_idx + 1, inner_len_m) inner_buf_m[inner_len_m] = '\0' - base_node_m: rawptr[ast.AST] = self._parse_type_string(pool, base_buf_m, ctx) - slice_node_m: rawptr[ast.AST] = self._parse_type_string(pool, inner_buf_m, ctx) + base_node_m: ast.AST* = self._parse_type_string(pool, base_buf_m, ctx) + slice_node_m: ast.AST* = self._parse_type_string(pool, inner_buf_m, ctx) stdlib.free(base_buf_m) stdlib.free(inner_buf_m) if base_node_m is not None and slice_node_m is not None: @@ -638,18 +638,18 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): # 优先 ast.parse_expression(单表达式入口,返回 Expression 包装节点) 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 + expr_body: ast.AST* = expr_node.body if expr_body is not None: return expr_body # 备选:ast.parse 文件级(TPV parser 的 _parse_test 单表达式入口对 # 复杂 slice 如 "t.Callable[[int], int]" 解析失败,但文件级 # _parse_expr_stmt 可解析裸表达式语句——vpi 同语法已验证 # parse_tokens 成功,故此处用文件级 parse 兜底) - tree_s: rawptr[ast.AST] = ast.parse(type_str, pool) + tree_s: ast.AST* = ast.parse(type_str, pool) if tree_s is not None: ch_s: list[ast.AST*]* = tree_s.children if ch_s is not None and len(ch_s) > 0: - st0: rawptr[ast.AST] = ch_s.get(0) + st0: ast.AST* = ch_s.get(0) if st0 is not None and st0.kind() == ast.ASTKind.Expr: ex0: rawptr[ast.Expr] = rawptr[ast.Expr](st0) if ex0.value is not None: @@ -674,7 +674,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): return None string.strncpy(mod_buf, type_str, mod_len) mod_buf[mod_len] = '\0' - module_node: rawptr[ast.AST] = ast.Name(pool, mod_buf, ctx) + module_node: ast.AST* = ast.Name(pool, mod_buf, ctx) # attr 段 trim 尾随空格 attr_str: str = type_str + dot_idx + 1 attr_len: sizet = string.strlen(attr_str) @@ -686,7 +686,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): return None string.strncpy(attr_buf, attr_str, attr_len) attr_buf[attr_len] = '\0' - attr_node: rawptr[ast.AST] = ast.Attribute(pool, module_node, attr_buf, ctx) + attr_node: ast.AST* = ast.Attribute(pool, module_node, attr_buf, ctx) stdlib.free(mod_buf) stdlib.free(attr_buf) return attr_node @@ -697,7 +697,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): return None string.strncpy(name_buf, type_str, seg_len) name_buf[seg_len] = '\0' - name_node: rawptr[ast.AST] = ast.Name(pool, name_buf, ctx) + name_node: ast.AST* = ast.Name(pool, name_buf, ctx) stdlib.free(name_buf) return name_node def set_current_file(self, file_path: str) -> None: @@ -706,11 +706,11 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): def get_current_file(self) -> str: """获取当前编译的文件名(供报错归因使用)""" return self.CurrentFile - def resolve_typedef_or_map(self, pool: rawptr[memhub.MemBuddy], + def resolve_typedef_or_map(self, pool: memhub.MemBuddy*, name: str, imported_modules: str, from_imports: str, - trans: rawptr[HT.Translator] = None) -> rawptr[llvmlite.LLVMType]: + trans: HT.Translator* = None) -> llvmlite.LLVMType*: """统一口径:CTypedef 动态表优先展开,miss 回退 map_t_type 硬编码 供 resolve_annotation_type 之外的旁路调用点(TypeGenErr/ClassGenEnum/ @@ -723,10 +723,10 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): ts_rt: str = self.Gen.TypeGenCType.lookup_ctypedef(name) if ts_rt is not None and self.Gen.TypeGenCType.CTypedefFound != 0: if self.Gen.TypeGenCType._ctypedef_push_visiting(pool, name) == 0: - inner_rt: rawptr[ast.AST] = self._parse_type_string(pool, ts_rt, ast.ASTCtx.Load) + inner_rt: ast.AST* = self._parse_type_string(pool, ts_rt, ast.ASTCtx.Load) if inner_rt is not None: self.Gen.TypeGenCType.CTypedefResolveDepth += 1 - ity_rt: rawptr[llvmlite.LLVMType] = self.resolve_annotation_type( + ity_rt: llvmlite.LLVMType* = self.resolve_annotation_type( pool, inner_rt, imported_modules, from_imports, trans, 1) self.Gen.TypeGenCType.CTypedefResolveDepth -= 1 self.Gen.TypeGenCType._ctypedef_pop_visiting() @@ -738,11 +738,11 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): # __sizeof__/REnum 等旁路查表(get_type_size_bytes 等)也能命中 builtins。 btd_r: str = self._lookup_builtins_typedef(pool, name) if btd_r is not None: - btd_node_r: rawptr[ast.AST] = self._parse_type_string(pool, btd_r, ast.ASTCtx.Load) + btd_node_r: ast.AST* = self._parse_type_string(pool, btd_r, ast.ASTCtx.Load) if btd_node_r is not None: if self.Gen.TypeGenCType.CTypedefResolveDepth < TypeGenMixin.MAX_CTYPEDEF_DEPTH: self.Gen.TypeGenCType.CTypedefResolveDepth += 1 - btd_ty_r: rawptr[llvmlite.LLVMType] = self.resolve_annotation_type( + btd_ty_r: llvmlite.LLVMType* = self.resolve_annotation_type( pool, btd_node_r, imported_modules, from_imports, trans, 1) self.Gen.TypeGenCType.CTypedefResolveDepth -= 1 if btd_ty_r is not None: @@ -755,17 +755,17 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): if lib_ts is None: lib_ts = self._lookup_library_typedef(pool, "w32.win32base", name) if lib_ts is not None: - lib_node: rawptr[ast.AST] = self._parse_type_string(pool, lib_ts, ast.ASTCtx.Load) + lib_node: ast.AST* = self._parse_type_string(pool, lib_ts, ast.ASTCtx.Load) if lib_node is not None: if self.Gen.TypeGenCType.CTypedefResolveDepth < TypeGenMixin.MAX_CTYPEDEF_DEPTH: self.Gen.TypeGenCType.CTypedefResolveDepth += 1 - lib_ty: rawptr[llvmlite.LLVMType] = self.resolve_annotation_type( + lib_ty: llvmlite.LLVMType* = self.resolve_annotation_type( pool, lib_node, imported_modules, from_imports, trans, 1) self.Gen.TypeGenCType.CTypedefResolveDepth -= 1 if lib_ty is not None: return lib_ty return self.map_t_type(pool, name) - def get_type_size_bytes(self, pool: rawptr[memhub.MemBuddy], + def get_type_size_bytes(self, pool: memhub.MemBuddy*, name: str, imported_modules: str, from_imports: str) -> int: @@ -776,7 +776,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): """ if name is None: return 0 - ty_sz: rawptr[llvmlite.LLVMType] = self.resolve_typedef_or_map(pool, name, imported_modules, from_imports) + ty_sz: llvmlite.LLVMType* = self.resolve_typedef_or_map(pool, name, imported_modules, from_imports) if ty_sz is None: return 0 bits_sz: int = self.Gen.TypeGenErr.get_llvm_type_bits(ty_sz) @@ -894,7 +894,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): if string.strncmp(buf + al_start, mod, mod_len) == 0: return buf + tg_start return None - def _lookup_builtins_typedef(self, pool: rawptr[memhub.MemBuddy], + def _lookup_builtins_typedef(self, pool: memhub.MemBuddy*, name: str) -> str: """builtins 最后匹配:查 includes/builtins.vp 的 CTypedef 声明 @@ -1103,7 +1103,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): """ if mod is None or name_src is None or type_str is None or name_len == 0: return - perm: rawptr[memhub.MemBuddy] = CompilerFactory.factory.PermPool + perm: memhub.MemBuddy* = CompilerFactory.factory.PermPool if perm is None: return if self.LibTypedefTypeMap is None: @@ -1136,7 +1136,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): # 会误返回 None(改变语义);此时不标记、留待下次重试读源。 if self.LibTypedefTypeMap is None: return - perm: rawptr[memhub.MemBuddy] = CompilerFactory.factory.PermPool + perm: memhub.MemBuddy* = CompilerFactory.factory.PermPool if perm is None: return if self.LibTypedefScannedMods is None: @@ -1170,7 +1170,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): if v is None: return None return (str | t.CPtr)(v) - def _lookup_library_typedef(self, pool: rawptr[memhub.MemBuddy], + def _lookup_library_typedef(self, pool: memhub.MemBuddy*, mod: str, attr: str) -> str: """查库模块源文件中 "attr: t.CTypedef = TYPE" 并注册,返回 TYPE 或 None @@ -1288,7 +1288,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): self.Gen.TypeGenCType.register_ctypedef(pool, attr, m_res) stdlib.free(m_buf) return m_res - def _expand_typedef_ref(self, pool: rawptr[memhub.MemBuddy], + def _expand_typedef_ref(self, pool: memhub.MemBuddy*, type_str: str, depth: int = 0) -> str: """展开类型表达式中的模块限定 typedef 引用(stdint.size_t → sizet) @@ -1328,7 +1328,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): and string.strcmp(ts_x, type_str) != 0: return self._expand_typedef_ref(pool, ts_x, depth + 1) return type_str - def _long_llvm_ty(self, pool: rawptr[memhub.MemBuddy]) -> rawptr[llvmlite.LLVMType]: + def _long_llvm_ty(self, pool: memhub.MemBuddy*) -> llvmlite.LLVMType*: """C 的 long / unsigned long 的目标平台 LLVM 类型 Windows 目标(LLP64)下 long = 32 位——对齐 TPC @@ -1348,8 +1348,8 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): or string.strstr(triple, "msvc") is not None: return llvmlite.Int32(pool) return llvmlite.Int64(pool) - def map_t_type(self, pool: rawptr[memhub.MemBuddy], - type_name: str) -> rawptr[llvmlite.LLVMType]: + def map_t_type(self, pool: memhub.MemBuddy*, + type_name: str) -> llvmlite.LLVMType*: """将 t.CXxx / c.CXxx 类型名映射到 LLVMType 注意: str = i8* = str = bytes @@ -1468,7 +1468,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): elif string.strcmp(type_name, "double") == 0: return llvmlite.Double(pool) return None - def _is_t_attr(self, node: rawptr[ast.AST], + def _is_t_attr(self, node: ast.AST*, attr_name: str, imported_modules: str) -> int: """检测节点是否是 t.attr_name 形式(含 from t import attr_name 的裸名) @@ -1482,14 +1482,14 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): if node is None or attr_name is None: return 0 if node.kind() == ast.ASTKind.Attribute: - at: rawptr[ast.Attribute] = rawptr[ast.Attribute](node) + at: ast.Attribute* = ast.Attribute*(node) if at.attr is None: return 0 if string.strcmp(at.attr, attr_name) != 0: return 0 if at.value is None or at.value.kind() != ast.ASTKind.Name: return 0 - val_nm: rawptr[ast.Name] = rawptr[ast.Name](at.value) + val_nm: ast.Name* = ast.Name*(at.value) if val_nm.id is None: return 0 if string.strcmp(val_nm.id, "t") == 0: @@ -1499,7 +1499,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): return 0 # 裸名形式: from t import attr_name → Name(id == attr_name) if node.kind() == ast.ASTKind.Name: - nm: rawptr[ast.Name] = rawptr[ast.Name](node) + nm: ast.Name* = ast.Name*(node) if nm.id is None: return 0 if string.strcmp(nm.id, attr_name) != 0: @@ -1509,17 +1509,17 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): return 0 return 1 return 0 - def _is_cptr_marker(self, node: rawptr[ast.AST], + def _is_cptr_marker(self, node: ast.AST*, imported_modules: str) -> int: """检测节点是否为 CPtr 指针标记,返回 1=是 / 0=否""" if self._is_t_attr(node, "CPtr", imported_modules) != 0: return 1 if node is not None and node.kind() == ast.ASTKind.Name: - nm: rawptr[ast.Name] = rawptr[ast.Name](node) + nm: ast.Name* = ast.Name*(node) if nm.id is not None and string.strcmp(nm.id, "CPtr") == 0: return 1 return 0 - def _is_cptr_subscript(self, node: rawptr[ast.AST]) -> int: + def _is_cptr_subscript(self, node: ast.AST*) -> int: """检测节点是否为 t.CPtr[T] 下标指针类型(t.CPtr[t.CPtr] / t.CPtr[int] 等) 用于联合类型 X | t.CPtr[T] 的指针层级合并(TPC 联合合并规则: @@ -1528,29 +1528,29 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): """ if node is None or node.kind() != ast.ASTKind.Subscript: return 0 - sub: rawptr[ast.Subscript] = rawptr[ast.Subscript](node) + sub: ast.Subscript* = ast.Subscript*(node) if sub.value is None or sub.value.kind() != ast.ASTKind.Attribute: return 0 - at: rawptr[ast.Attribute] = rawptr[ast.Attribute](sub.value) + at: ast.Attribute* = ast.Attribute*(sub.value) if at.attr is None or string.strcmp(at.attr, "CPtr") != 0: return 0 if at.value is None or at.value.kind() != ast.ASTKind.Name: return 0 - nm: rawptr[ast.Name] = rawptr[ast.Name](at.value) + nm: ast.Name* = ast.Name*(at.value) if nm.id is None or string.strcmp(nm.id, "t") != 0: return 0 return 1 - def _is_cvoid_marker(self, node: rawptr[ast.AST], + def _is_cvoid_marker(self, node: ast.AST*, imported_modules: str) -> int: """检测节点是否为 CVoid 指针标记,返回 1=是 / 0=否""" if self._is_t_attr(node, "CVoid", imported_modules) != 0: return 1 if node is not None and node.kind() == ast.ASTKind.Name: - nm: rawptr[ast.Name] = rawptr[ast.Name](node) + nm: ast.Name* = ast.Name*(node) if nm.id is not None and string.strcmp(nm.id, "CVoid") == 0: return 1 return 0 - def annotation_to_str(self, annot: rawptr[ast.AST]) -> str: + def annotation_to_str(self, annot: ast.AST*) -> str: """将类型注解 AST 转换为可读字符串,返回 None=无法提取 注意:返回的字符串可能由 malloc 分配,调用方无需释放(错误路径用)。 @@ -1561,21 +1561,21 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): # Constant 节点: 字符串注解 if k == ast.ASTKind.Constant: - cn: rawptr[ast.Constant] = rawptr[ast.Constant](annot) + cn: ast.Constant* = ast.Constant*(annot) if cn.const_kind == ast.CONST_STR and cn.str_val is not None: return cn.str_val return "" # Name 节点: bool, int, MemBuddy if k == ast.ASTKind.Name: - nm: rawptr[ast.Name] = rawptr[ast.Name](annot) + nm: ast.Name* = ast.Name*(annot) if nm.id is not None: return nm.id return "" # Attribute 节点: t.CBool, memhub.MemBuddy if k == ast.ASTKind.Attribute: - at: rawptr[ast.Attribute] = rawptr[ast.Attribute](annot) + at: ast.Attribute* = ast.Attribute*(annot) if at.attr is None: return "" if at.value is not None: @@ -1592,7 +1592,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): # Subscript 节点: list[...], t.CArray[...] if k == ast.ASTKind.Subscript: - sub: rawptr[ast.Subscript] = rawptr[ast.Subscript](annot) + sub: ast.Subscript* = ast.Subscript*(annot) base: str = self.annotation_to_str(sub.value) if base is not None: buf2: str = stdlib.malloc(string.strlen(base) + 5) @@ -1604,7 +1604,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): # BinOp 节点: A | B (联合类型) if k == ast.ASTKind.BinOp: - bo: rawptr[ast.BinOp] = rawptr[ast.BinOp](annot) + bo: ast.BinOp* = ast.BinOp*(annot) left_s: str = self.annotation_to_str(bo.left) right_s: str = self.annotation_to_str(bo.right) if left_s is not None and right_s is not None: @@ -1636,9 +1636,9 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): if string.strcmp(name, "CInline") == 0: return 1 return 0 - def extract_class_name_from_annotation(self, node: rawptr[ast.AST], + def extract_class_name_from_annotation(self, node: ast.AST*, imported_modules: str, - pool: rawptr[memhub.MemBuddy] = None, + pool: memhub.MemBuddy* = None, from_imports: str = None) -> str: """从类型注解 AST 中提取类名,返回 None=无法提取 @@ -1656,7 +1656,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): # Constant 节点: 字符串注解(如 'MemManager'),简单类名直接返回 if k == ast.ASTKind.Constant: - cn: rawptr[ast.Constant] = rawptr[ast.Constant](node) + cn: ast.Constant* = ast.Constant*(node) if cn.const_kind == ast.CONST_STR and cn.str_val is not None: # 仅处理简单类名(不含 . 和 |),复杂形式返回 None if string.strchr(cn.str_val, 46) is None and string.strchr(cn.str_val, 124) is None: @@ -1679,7 +1679,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): # Name 节点: MemBuddy → "MemBuddy" if k == ast.ASTKind.Name: - nm: rawptr[ast.Name] = rawptr[ast.Name](node) + nm: ast.Name* = ast.Name*(node) if nm.id is None: return None # 泛型特化上下文:T → 具体类型(特化方法体内局部变量注解 @@ -1706,14 +1706,14 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): # Attribute 节点: memhub.MemBuddy → "memhub.MemBuddy"(模块限定名) if k == ast.ASTKind.Attribute: - at: rawptr[ast.Attribute] = rawptr[ast.Attribute](node) + at: ast.Attribute* = ast.Attribute*(node) if at.attr is None: return None # t.XXX 内置类型:返回 XXX(如 uint32 → "CUInt32T"), # 供 AnnotClassName 记录变量类型名(_type_name_unsigned 判断无符号性时使用)。 # 消费方(find_struct/lookup_field_by_class)对非结构体名返回 None 优雅降级。 if at.value is not None and at.value.kind() == ast.ASTKind.Name: - val_nm2: rawptr[ast.Name] = rawptr[ast.Name](at.value) + val_nm2: ast.Name* = ast.Name*(at.value) if val_nm2.id is not None and string.strcmp(val_nm2.id, "t") == 0: return at.attr # import 别名还原:val_nm2.id 可能是 "import X as Y" 的别名 Y @@ -1742,7 +1742,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): # BinOp 节点: 联合类型 A | B if k == ast.ASTKind.BinOp: - bop: rawptr[ast.BinOp] = rawptr[ast.BinOp](node) + bop: ast.BinOp* = ast.BinOp*(node) if bop.op == ast.OpKind.BitOr: left_is_cptr: int = self._is_cptr_marker(bop.left, imported_modules) right_is_cptr: int = self._is_cptr_marker(bop.right, imported_modules) @@ -1771,7 +1771,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): # list[AST | t.CPtr] → "list[ast.AST|t.CPtr]"(pool 可用时) # 与 resolve_annotation_type 的 mangled name 格式一致,使 find_struct 能找到特化结构体 if k == ast.ASTKind.Subscript: - sub: rawptr[ast.Subscript] = rawptr[ast.Subscript](node) + sub: ast.Subscript* = ast.Subscript*(node) if sub.value is None: return None # rawptr[T] 是内建裸指针(等价 t.CPtr[T]),AnnotClassName 应取 pointee @@ -1779,14 +1779,14 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): # lookup_field_by_class 报"类 'rawptr' 未注册"(json.__parser _peek # 参数 s: rawptr[ParseState] 根因)。 if sub.value.kind() == ast.ASTKind.Name: - rp_nm: rawptr[ast.Name] = rawptr[ast.Name](sub.value) + rp_nm: ast.Name* = ast.Name*(sub.value) if rp_nm.id is not None and string.strcmp(rp_nm.id, "rawptr") == 0: if sub.slice is not None: return self.extract_class_name_from_annotation( sub.slice, imported_modules, pool, from_imports) return None # 递归取 base 时必须把 from_imports 一并下传:否则同一份注解在派发名/查表键/ - # 注册键三处算出的 mangled 名不一致(如 list[rawptr[ast.AST]] 的元素段), + # 注册键三处算出的 mangled 名不一致(如 list[ast.AST*] 的元素段), # 出现「alloca 裸 list* / pass1 按 list[ast.ASTptr] / pass2 按 list[ast.ClassDefptr]」 # 的分裂崩溃。其余调用点均已传。 base_name: str = self.extract_class_name_from_annotation( @@ -1801,7 +1801,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): slice_name: str = None if sub.slice.kind() == ast.ASTKind.Tuple: # Tuple slice: dict[str, int] → "str,int" - sub_tup: rawptr[ast.Tuple] = rawptr[ast.Tuple](sub.slice) + sub_tup: ast.Tuple* = ast.Tuple*(sub.slice) if sub_tup.elts is not None: tup_elts_sn: list[ast.AST*]* = sub_tup.elts tn_sn: sizet = len(tup_elts_sn) @@ -1811,7 +1811,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): for ti_sn in range(tn_sn): if ti_sn > 0: tup_total += 1 - elt_node: rawptr[ast.AST] = tup_elts_sn.get(ti_sn) + elt_node: ast.AST* = tup_elts_sn.get(ti_sn) elt_name_raw: str = self._get_type_name_from_annotation(pool, elt_node) elt_name: str = self._norm_type_arg_name(pool, elt_name_raw, from_imports) if elt_name is not None: @@ -1822,7 +1822,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): for ti_sn in range(tn_sn): if ti_sn > 0: string.strcat(tup_buf, ",") - elt_node2: rawptr[ast.AST] = tup_elts_sn.get(ti_sn) + elt_node2: ast.AST* = tup_elts_sn.get(ti_sn) elt_name2_raw: str = self._get_type_name_from_annotation(pool, elt_node2) elt_name2: str = self._norm_type_arg_name(pool, elt_name2_raw, from_imports) if elt_name2 is not None: @@ -1849,13 +1849,13 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): return mangled_buf return None - def _resolve_generic_subscript_ty(self, pool: rawptr[memhub.MemBuddy], - sub: rawptr[ast.Subscript], + def _resolve_generic_subscript_ty(self, pool: memhub.MemBuddy*, + sub: ast.Subscript*, gen_cls_name: str, - trans: rawptr[HT.Translator], + trans: HT.Translator*, imported_modules: str, from_imports: str, - depth: int = 0) -> rawptr[llvmlite.LLVMType]: + depth: int = 0) -> llvmlite.LLVMType*: """解析泛型类类型注解(特化或查找已注册结构体),失败返回 None""" if pool is None or sub is None or gen_cls_name is None: return None @@ -1867,32 +1867,32 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): tp_elts: list[ast.AST*]* = None tp_count: sizet = 0 if sub.slice.kind() == ast.ASTKind.Tuple: - tp_tup: rawptr[ast.Tuple] = rawptr[ast.Tuple](sub.slice) + tp_tup: ast.Tuple* = ast.Tuple*(sub.slice) if tp_tup.elts is not None: tp_elts = tp_tup.elts tp_count = len(tp_elts) else: - # [FIX] elem_size=8(rawptr[ast.AST] 指针 8 字节),原传 1 → get 只读 + # [FIX] elem_size=8(ast.AST* 指针 8 字节),原传 1 → get 只读 # 1 字节拼指针(高 56 位残留)→ tuple 元素解析垃圾 - tp_single: list[ast.AST*]* = list[rawptr[ast.AST]](pool, 8) + tp_single: list[ast.AST*]* = list[ast.AST*](pool, 8) if tp_single is not None: tp_single.append(sub.slice) tp_elts = tp_single tp_count = 1 if tp_count == 0 or tp_elts is None: return None - tup_head: rawptr[llvmlite.Function] = None - tup_tail: rawptr[llvmlite.Function] = None + tup_head: llvmlite.Function* = None + tup_tail: llvmlite.Function* = None tui: sizet for tui in range(tp_count): - tup_elt: rawptr[ast.AST] = tp_elts.get(tui) + tup_elt: ast.AST* = tp_elts.get(tui) if tup_elt is None: continue - tup_ety: rawptr[llvmlite.LLVMType] = self.resolve_annotation_type( + tup_ety: llvmlite.LLVMType* = self.resolve_annotation_type( pool, tup_elt, imported_modules, from_imports, trans, depth + 1) if tup_ety is None: return None - tup_node: rawptr[llvmlite.Function] = llvmlite.new_param_node(pool, tup_ety) + tup_node: llvmlite.Function* = llvmlite.new_param_node(pool, tup_ety) if tup_node is None: return None if tup_head is None: @@ -1904,15 +1904,15 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): return None return llvmlite.Struct(pool, tup_head, tp_count, None) # 先收集类型实参名,再分配缓冲区拼接 mangled name(elem_size=8:str 是指针) - gen_arg_names: list[str] | t.CPtr = list[str](pool, 8) + gen_arg_names: list[str]* = list[str](pool, 8) if sub.slice.kind() == ast.ASTKind.Tuple: - gen_tp: rawptr[ast.Tuple] = rawptr[ast.Tuple](sub.slice) + gen_tp: ast.Tuple* = ast.Tuple*(sub.slice) gen_elts: list[ast.AST*]* = gen_tp.elts if gen_elts is not None: gen_en: sizet = len(gen_elts) gen_ei: sizet for gen_ei in range(gen_en): - gen_elt: rawptr[ast.AST] = gen_elts.get(gen_ei) + gen_elt: ast.AST* = gen_elts.get(gen_ei) gen_tn_raw: str = self._get_type_name_from_annotation(pool, gen_elt) # 类型参数 SHA1 规范化(ast.AST/AST → f467978339422f32.AST), # 与特化注册名一致,消除跨模块特化名分裂 @@ -1968,7 +1968,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): if trans is not None and trans.ReplCtx is not None \ and VpiReader.ReplStubLayoutMode != 0: # 已登记的特化结构体(会话期先前注册)直接复用:本分支只读、不翻译 - spec_ty_inj: rawptr[llvmlite.LLVMType] = self.Gen.StructGen.get_struct_type(gen_mangled) + spec_ty_inj: llvmlite.LLVMType* = self.Gen.StructGen.get_struct_type(gen_mangled) if spec_ty_inj is not None: return spec_ty_inj # 归属模块 sha1:优先取**全局模板表**(步骤③'' 已按 includes 全量注册, @@ -1978,7 +1978,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): if inj_owner is None: inj_owner = StubMergerStore.LookupGenericOwnerSha1(gen_cls_name) if inj_owner is not None: - ty_inj: rawptr[llvmlite.LLVMType] = self._repl_opaque_class_ty( + ty_inj: llvmlite.LLVMType* = self._repl_opaque_class_ty( pool, inj_owner, gen_mangled) if ty_inj is not None: return ty_inj @@ -1986,13 +1986,13 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): # "注解解析失败"明确报错(不伪造无模块前缀的类名) return None # 查找已特化的 struct(特化由实例化调用 list[int](pool) 触发) - gen_spec_ty: rawptr[llvmlite.LLVMType] = self.Gen.StructGen.get_struct_type(gen_mangled) + gen_spec_ty: llvmlite.LLVMType* = self.Gen.StructGen.get_struct_type(gen_mangled) if gen_spec_ty is not None: # Phase B 补译泛型特化类方法体:Phase 1a 特化时只注册结构体不译方法体, # Phase B 解析字段类型命中已注册结构体时本会早返回 → 方法体永不生成 # → 符号只有 declare 无 define → 链接失败。故这里走补译分支。 if trans is not None and trans._declare_only == 0: - gen_spec_entry: rawptr[GenTypes.StructEntry] = self.Gen.StructGen.find_struct(gen_mangled) + gen_spec_entry: GenTypes.StructEntry* = self.Gen.StructGen.find_struct(gen_mangled) if gen_spec_entry is not None and gen_spec_entry.MethodsEmitted == 0: # 错误定位:压入触发特化的调用方帧(注解所在文件+行号), # 使特化方法体报错(如参数类型解析失败)能追溯到用户代码 @@ -2005,9 +2005,9 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): # 未特化:尝试主动触发泛型特化(与 TPC _HandleSubscript 对齐) # 当 trans 可用时,检查是否是泛型模板并触发特化 if trans is not None: - template_cd_chk: rawptr[ast.ClassDef] = self.Gen.ClassGenGeneric._find_generic_template(gen_cls_name) + template_cd_chk: ast.ClassDef* = self.Gen.ClassGenGeneric._find_generic_template(gen_cls_name) if template_cd_chk is not None: - type_args_chk: list[str] | t.CPtr = self.Gen.CallGenCtor._extract_type_args_from_slice( + type_args_chk: list[str]* = self.Gen.CallGenCtor._extract_type_args_from_slice( pool, sub.slice, from_imports) if type_args_chk is not None and len(type_args_chk) > 0: # 错误定位:压入触发特化的调用方帧(注解所在文件+行号) @@ -2019,7 +2019,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): if spec_name_chk is not None: gen_spec_ty = self.Gen.StructGen.get_struct_type(gen_mangled) # gen_mangled 由本函数自行拼接,而 _specialize_generic_class 内部还会对 - # 每个实参再规范化一次,两处命名可能不一致(如元素注解 `rawptr[ast.AST]` + # 每个实参再规范化一次,两处命名可能不一致(如元素注解 `ast.AST*` # 本函数拼 "list[.AST|t.CPtr]",特化侧规范化 "list[.ASTptr]") # → 按 gen_mangled 重查恒 miss → 静默退化为裸 list* → .get() 误分派截断。 # spec_name_chk 是特化侧返回的权威特化名,必须按它重查。 @@ -2063,18 +2063,18 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): if trans is not None and trans.ReplCtx is not None: gowner_sha1: str = StubMergerStore.LookupGenericOwnerSha1(gen_cls_name) if gowner_sha1 is not None: - ty_repl_g: rawptr[llvmlite.LLVMType] = self._repl_opaque_class_ty( + ty_repl_g: llvmlite.LLVMType* = self._repl_opaque_class_ty( pool, gowner_sha1, gen_mangled) if ty_repl_g is not None: return ty_repl_g # 未特化:返回 None(不报错,让后续流程处理) return None - def resolve_annotation_type(self, pool: rawptr[memhub.MemBuddy], - node: rawptr[ast.AST], + def resolve_annotation_type(self, pool: memhub.MemBuddy*, + node: ast.AST*, imported_modules: str, from_imports: str, - trans: rawptr[HT.Translator] = None, - depth: int = 0) -> rawptr[llvmlite.LLVMType]: + trans: HT.Translator* = None, + depth: int = 0) -> llvmlite.LLVMType*: """解析类型注解节点为 LLVMType Args: @@ -2098,23 +2098,28 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): # Constant 节点: 字符串注解(如 'MemManager'),当作无引号的 Name/Attribute/BinOp 处理 if k == ast.ASTKind.Constant: - cn: rawptr[ast.Constant] = rawptr[ast.Constant](node) + cn: ast.Constant* = ast.Constant*(node) if cn.const_kind == ast.CONST_NONE: return llvmlite.Void(pool) if cn.const_kind == ast.CONST_STR and cn.str_val is not None: - sub_node: rawptr[ast.AST] = self._parse_type_string(pool, cn.str_val, ast.ASTCtx.Load) + sub_node: ast.AST* = self._parse_type_string(pool, cn.str_val, ast.ASTCtx.Load) if sub_node is not None: return self.resolve_annotation_type(pool, sub_node, imported_modules, from_imports, trans, depth + 1) return None # Name 节点: str, int, bytes, from-import 名称, class 名称等 if k == ast.ASTKind.Name: - nm: rawptr[ast.Name] = rawptr[ast.Name](node) + nm: ast.Name* = ast.Name*(node) if nm.id is None: return None + # 内建定长数组构造子 array 是**软关键字**:只在类型/注解位置作为 + # array[E, N] 生效;裸用(缺少下标与参数)在类型位置属误用 → fail-fast。 + # 非类型位置(如 json.array(pool) 调用、from json import array)不受影响。 + if string.strcmp(nm.id, "array") == 0: + self.Gen.TypeGenErr.fatal_type_error(nm, "裸用内建定长数组构造子 'array'(缺少下标与参数):'array' 只在类型/注解位置生效,必须写成 array[E, N](元素类型在前、长度在后)。正确示例:state: array[uint32, 4]") # 泛型类型参数 T 替换:在泛型特化上下文中,将 T 替换为具体类型 - tpn_g: list[str] | t.CPtr = self.Gen.TypeGenBase.GenericTpNames - tpa_g: list[str] | t.CPtr = self.Gen.TypeGenBase.GenericTypeArgs + tpn_g: list[str]* = self.Gen.TypeGenBase.GenericTpNames + tpa_g: list[str]* = self.Gen.TypeGenBase.GenericTypeArgs if tpn_g is not None and tpa_g is not None: gp_n: sizet = len(tpn_g) gp_i: sizet @@ -2157,7 +2162,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): self.Gen.TypeGenErr.fatal_error( nm, f"泛型类型实参污染:实参 '{gp_ta}' 包含类型参数名,无法特化", "TypeError") # 用具体类型名递归解析(支持 BinOp/Attribute 类型实参) - gp_sub_node: rawptr[ast.AST] = self._parse_type_string(pool, gp_ta, nm.ctx) + gp_sub_node: ast.AST* = self._parse_type_string(pool, gp_ta, nm.ctx) if gp_sub_node is not None: return self.resolve_annotation_type(pool, gp_sub_node, imported_modules, from_imports, trans, depth + 1) # 已规范化 sha1 前缀名 "{16hex}.Class"(_norm_type_arg_name 产物,如泛型 @@ -2175,14 +2180,14 @@ 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: rawptr[GenTypes.StructEntry] = self.Gen.StructGen.find_struct_by_module( + sp_entry2: 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: return llvmlite.Ptr(pool, sp_entry2.Ty) return sp_entry2.Ty # 兜底:按完整前缀名直接查(部分注册键即全名) - sp_full2: rawptr[llvmlite.LLVMType] = self.Gen.StructGen.get_struct_type(nm.id) + sp_full2: llvmlite.LLVMType* = self.Gen.StructGen.get_struct_type(nm.id) if sp_full2 is not None: return sp_full2 return None @@ -2214,7 +2219,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): # G5Node 顶掉,避免 alloca 用本模块类型、load 用他模块类型的混用)。 # 本模块未定义时回退按裸名全局查找(import 来的类走此路径)。 if trans is not None and trans.ModuleSha1 is not None: - own_entry: rawptr[GenTypes.StructEntry] = self.Gen.StructGen.find_struct_by_module(nm.id, trans.ModuleSha1) + own_entry: 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 值语义: @@ -2240,15 +2245,15 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): fi_sha1_rn = fi_sha1 stdlib.free(fi_mod) if fi_sha1 is not None: - fi_entry: rawptr[GenTypes.StructEntry] = self.Gen.StructGen.find_struct_by_module(nm.id, fi_sha1) + fi_entry: 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) return fi_entry.Ty if self.Gen.StructGen.is_struct_visible(nm.id) != 0: - struct_ty: rawptr[llvmlite.LLVMType] = self.Gen.StructGen.get_struct_type(nm.id) + struct_ty: llvmlite.LLVMType* = self.Gen.StructGen.get_struct_type(nm.id) if struct_ty is not None: - nm_entry_s: rawptr[GenTypes.StructEntry] = self.Gen.StructGen.find_struct_by_type(struct_ty) + nm_entry_s: 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 @@ -2268,10 +2273,10 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): # 循环检测:将当前 CTypedef 名加入正在解析列表 if self.Gen.TypeGenCType._ctypedef_push_visiting(pool, nm.id) == 0: # 用 _parse_type_string 把类型字符串转回 AST,递归解析 - inner_node: rawptr[ast.AST] = self._parse_type_string(pool, ctypedef_str, nm.ctx) + inner_node: ast.AST* = self._parse_type_string(pool, ctypedef_str, nm.ctx) if inner_node is not None: self.Gen.TypeGenCType.CTypedefResolveDepth += 1 - inner_ty: rawptr[llvmlite.LLVMType] = self.resolve_annotation_type( + inner_ty: llvmlite.LLVMType* = self.resolve_annotation_type( pool, inner_node, imported_modules, from_imports, trans, depth + 1) self.Gen.TypeGenCType.CTypedefResolveDepth -= 1 self.Gen.TypeGenCType._ctypedef_pop_visiting() @@ -2283,7 +2288,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): # 这些是跨模块通用的 C typedef 名,即使 from-import 查找失败也能解析 # 注意:from-import 的结构体名若未注册,get_struct_type 已返回 None, # 此处 map_t_type 对结构体名也返回 None,由上层 declare_only 机制延迟到下一遍 - mapped_ty_fallback: rawptr[llvmlite.LLVMType] = self.map_t_type(pool, nm.id) + mapped_ty_fallback: llvmlite.LLVMType* = self.map_t_type(pool, nm.id) if mapped_ty_fallback is not None: return mapped_ty_fallback # [阶段1a] from-import 别名反查(正常库分析):from t import CInt as XXX @@ -2304,9 +2309,9 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): oa_buf[oa_i] = orig_alias[oa_i] oa_buf[oa_len] = '\0' # 用原始名重建节点递归解析(depth 守卫复用 resolve 上限) - orig_node_a: rawptr[ast.AST] = self._parse_type_string(pool, oa_buf, nm.ctx) + orig_node_a: ast.AST* = self._parse_type_string(pool, oa_buf, nm.ctx) if orig_node_a is not None: - alias_ty: rawptr[llvmlite.LLVMType] = self.resolve_annotation_type( + alias_ty: llvmlite.LLVMType* = self.resolve_annotation_type( pool, orig_node_a, imported_modules, from_imports, trans, depth + 1) if alias_ty is not None: return alias_ty @@ -2315,9 +2320,9 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): # t.CPtr)。命中展开类型表达式后递归解析,仍失败才由调用方报错。 btd_n: str = self._lookup_builtins_typedef(pool, nm.id) if btd_n is not None: - btd_node_n: rawptr[ast.AST] = self._parse_type_string(pool, btd_n, nm.ctx) + btd_node_n: ast.AST* = self._parse_type_string(pool, btd_n, nm.ctx) if btd_node_n is not None: - btd_ty_n: rawptr[llvmlite.LLVMType] = self.resolve_annotation_type( + btd_ty_n: llvmlite.LLVMType* = self.resolve_annotation_type( pool, btd_node_n, imported_modules, from_imports, trans, depth + 1) if btd_ty_n is not None: return btd_ty_n @@ -2329,9 +2334,9 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): if lib_ts_n is None: lib_ts_n = self._lookup_library_typedef(pool, "w32.win32base", nm.id) if lib_ts_n is not None: - lib_node_n: rawptr[ast.AST] = self._parse_type_string(pool, lib_ts_n, nm.ctx) + lib_node_n: ast.AST* = self._parse_type_string(pool, lib_ts_n, nm.ctx) if lib_node_n is not None: - lib_ty_n: rawptr[llvmlite.LLVMType] = self.resolve_annotation_type( + lib_ty_n: llvmlite.LLVMType* = self.resolve_annotation_type( pool, lib_node_n, imported_modules, from_imports, trans, depth + 1) if lib_ty_n is not None: return lib_ty_n @@ -2354,7 +2359,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): and string.strcmp(trans.ModuleSha1, GenTypes.REPL_SESSION_SHA1) != 0: own_sha_rn = trans.ModuleSha1 if own_sha_rn is not None: - ty_repl_n: rawptr[llvmlite.LLVMType] = self._repl_opaque_class_ty( + ty_repl_n: llvmlite.LLVMType* = self._repl_opaque_class_ty( pool, own_sha_rn, nm.id) if ty_repl_n is not None: return ty_repl_n @@ -2362,12 +2367,12 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): # Attribute 节点: int, uint64, namespace_defs.PlainStruct 等 if k == ast.ASTKind.Attribute: - at: rawptr[ast.Attribute] = rawptr[ast.Attribute](node) + at: ast.Attribute* = ast.Attribute*(node) if at.attr is None: return None # 检查 value 是否是 Name('t') 或 Name('c') if at.value is not None and at.value.kind() == ast.ASTKind.Name: - val_name: rawptr[ast.Name] = rawptr[ast.Name](at.value) + val_name: ast.Name* = ast.Name*(at.value) if val_name.id is not None: # t/c 是内建库(SHA1 豁免),显式写 t.XXX 即确指内建库, # 不依赖 imported_modules(t 可能不在其中,如 vpi 注入上下文) @@ -2410,23 +2415,23 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): ctypedef_attr: str = self.Gen.TypeGenCType.lookup_ctypedef(at.attr) if ctypedef_attr is not None and self.Gen.TypeGenCType.CTypedefFound != 0: if self.Gen.TypeGenCType._ctypedef_push_visiting(pool, at.attr) == 0: - inner_attr: rawptr[ast.AST] = self._parse_type_string(pool, ctypedef_attr, ast.ASTCtx.Load) + inner_attr: ast.AST* = self._parse_type_string(pool, ctypedef_attr, ast.ASTCtx.Load) if inner_attr is not None: self.Gen.TypeGenCType.CTypedefResolveDepth += 1 - inner_ty_attr: rawptr[llvmlite.LLVMType] = self.resolve_annotation_type( + inner_ty_attr: llvmlite.LLVMType* = self.resolve_annotation_type( pool, inner_attr, imported_modules, from_imports, trans, depth + 1) self.Gen.TypeGenCType.CTypedefResolveDepth -= 1 self.Gen.TypeGenCType._ctypedef_pop_visiting() if inner_ty_attr is not None: return inner_ty_attr # 先尝试内置类型映射(int 等) - mapped_ty: rawptr[llvmlite.LLVMType] = self.map_t_type(pool, at.attr) + mapped_ty: llvmlite.LLVMType* = self.map_t_type(pool, at.attr) if mapped_ty is not None: return mapped_ty # 模块限定类类型:Module.ClassName(命名空间隔离) # SHA1 前缀形态优先用完整名 "{sha1}.{Class}" 精确命中定义侧 # struct(get_struct_type 类名回退可能命中跨模块同名类) - full_attr_ty: rawptr[llvmlite.LLVMType] = None + full_attr_ty: llvmlite.LLVMType* = None # mod_sha1_rv:把本分支解析出的"模块段 sha1"带到末尾(REPL 会话的 # "仅类型"占位兜底要用它;声明在此以覆盖下方 SHA1 前缀形态与枚举/ # typedef 尝试都在同一作用域)。 @@ -2454,10 +2459,10 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): if mod_sha1_v is not None: full_q_v: str = self._concat_sha1_class(pool, mod_sha1_v, at.attr) if full_q_v is not None: - full_ty_v: rawptr[llvmlite.LLVMType] = self.Gen.StructGen.get_struct_type(full_q_v) + full_ty_v: 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: rawptr[GenTypes.StructEntry] = self.Gen.StructGen.find_struct_by_module(at.attr, mod_sha1_v) + mod_entry_v: 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) @@ -2467,7 +2472,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): # 模块名未登记(未编译/未扫描):同样不裸名回退 else: # t/c 内置库限定:裸名回退合法(内置类名无跨模块冲突) - mod_struct_ty: rawptr[llvmlite.LLVMType] = self.Gen.StructGen.get_struct_type(at.attr) + mod_struct_ty: llvmlite.LLVMType* = self.Gen.StructGen.get_struct_type(at.attr) if mod_struct_ty is not None: return mod_struct_ty # 模块限定枚举类型:Module.EnumClass(如 fat32_types.FRESULT, @@ -2481,11 +2486,11 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): mod_td_str: str = self.Gen.TypeGenCType.lookup_ctypedef(at.attr) if mod_td_str is not None and self.Gen.TypeGenCType.CTypedefFound != 0: if self.Gen.TypeGenCType._ctypedef_push_visiting(pool, at.attr) == 0: - mod_td_inner: rawptr[ast.AST] = self._parse_type_string( + mod_td_inner: ast.AST* = self._parse_type_string( pool, mod_td_str, at.ctx) if mod_td_inner is not None: self.Gen.TypeGenCType.CTypedefResolveDepth += 1 - mod_td_ty: rawptr[llvmlite.LLVMType] = self.resolve_annotation_type( + mod_td_ty: llvmlite.LLVMType* = self.resolve_annotation_type( pool, mod_td_inner, imported_modules, from_imports, trans, depth + 1) self.Gen.TypeGenCType.CTypedefResolveDepth -= 1 self.Gen.TypeGenCType._ctypedef_pop_visiting() @@ -2498,7 +2503,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): # 不可解析被跳过)⇒ 用 opaque 具名类型占位(不写 StructTable ⇒ # 字段访问仍按"类未注册"明确报错)。批处理 trans.ReplCtx 恒 None。 if trans is not None and trans.ReplCtx is not None and mod_sha1_rv is not None: - ty_repl_a: rawptr[llvmlite.LLVMType] = self._repl_opaque_class_ty( + ty_repl_a: llvmlite.LLVMType* = self._repl_opaque_class_ty( pool, mod_sha1_rv, at.attr) if ty_repl_a is not None: return ty_repl_a @@ -2507,7 +2512,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): # at.value 是 Attribute 而非 Name,递归提取最终类名(at.attr)查结构体表 # find_struct 支持模块限定名回退,此处用最外层 attr(简单类名)即可 if at.value is not None and at.value.kind() == ast.ASTKind.Attribute: - nested_struct_ty: rawptr[llvmlite.LLVMType] = self.Gen.StructGen.get_struct_type(at.attr) + nested_struct_ty: llvmlite.LLVMType* = self.Gen.StructGen.get_struct_type(at.attr) if nested_struct_ty is not None: return nested_struct_ty # 嵌套模块限定的枚举类(fat32_types.FRESULT 三级名):查枚举基类型 @@ -2520,11 +2525,11 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): nested_td_str: str = self.Gen.TypeGenCType.lookup_ctypedef(at.attr) if nested_td_str is not None and self.Gen.TypeGenCType.CTypedefFound != 0: if self.Gen.TypeGenCType._ctypedef_push_visiting(pool, at.attr) == 0: - nested_inner: rawptr[ast.AST] = self._parse_type_string( + nested_inner: ast.AST* = self._parse_type_string( pool, nested_td_str, at.ctx) if nested_inner is not None: self.Gen.TypeGenCType.CTypedefResolveDepth += 1 - nested_ty: rawptr[llvmlite.LLVMType] = self.resolve_annotation_type( + nested_ty: llvmlite.LLVMType* = self.resolve_annotation_type( pool, nested_inner, imported_modules, from_imports, trans, depth + 1) self.Gen.TypeGenCType.CTypedefResolveDepth -= 1 self.Gen.TypeGenCType._ctypedef_pop_visiting() @@ -2532,7 +2537,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): return nested_ty else: self.Gen.TypeGenCType._ctypedef_pop_visiting() - mapped_ty_na: rawptr[llvmlite.LLVMType] = self.map_t_type(pool, at.attr) + mapped_ty_na: llvmlite.LLVMType* = self.map_t_type(pool, at.attr) if mapped_ty_na is not None: return mapped_ty_na # 嵌套模块限定 typedef 兜底(w32.win32base.HANDLE = t.CTypedef = @@ -2544,9 +2549,9 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): if mod_path_na is not None: lib_td_na: str = self._lookup_library_typedef(pool, mod_path_na, at.attr) if lib_td_na is not None: - td_node_na: rawptr[ast.AST] = self._parse_type_string(pool, lib_td_na, at.ctx) + td_node_na: ast.AST* = self._parse_type_string(pool, lib_td_na, at.ctx) if td_node_na is not None: - td_ty_na: rawptr[llvmlite.LLVMType] = self.resolve_annotation_type( + td_ty_na: llvmlite.LLVMType* = self.resolve_annotation_type( pool, td_node_na, imported_modules, from_imports, trans, depth + 1) if td_ty_na is not None: return td_ty_na @@ -2558,7 +2563,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): # 2. t.CPtr → i8* (void* 等价于 i8*) # 3. ActualType | DecoratorMarker → ActualType(忽略装饰器标记如 CExport/CExtern) if k == ast.ASTKind.BinOp: - bop: rawptr[ast.BinOp] = rawptr[ast.BinOp](node) + bop: ast.BinOp* = ast.BinOp*(node) if bop.op == ast.OpKind.BitOr: # 检测 t.CPtr 标记(指针包装标记,支持 t.CPtr 与 from t import CPtr 裸名) left_is_cptr: int = self._is_cptr_marker(bop.left, imported_modules) @@ -2566,7 +2571,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): if left_is_cptr != 0 or right_is_cptr != 0: # 有 CPtr 标记:解析非 CPtr 一边的实际类型,包装为 Ptr # left 是 CPtr → other 是 right;right 是 CPtr → other 是 left - other_node: rawptr[ast.AST] = bop.left + other_node: ast.AST* = bop.left if left_is_cptr != 0: other_node = bop.right # 检测另一边是否是 t\.CVoid (void* = i8*) @@ -2575,20 +2580,20 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): other_is_cvoid: int = 0 if other_node is not None: if other_node.kind() == ast.ASTKind.Attribute: - oat2: rawptr[ast.Attribute] = rawptr[ast.Attribute](other_node) + oat2: ast.Attribute* = ast.Attribute*(other_node) if oat2.attr is not None and string.strcmp(oat2.attr, "CVoid") == 0: if oat2.value is not None and oat2.value.kind() == ast.ASTKind.Name: - ov2: rawptr[ast.Name] = rawptr[ast.Name](oat2.value) + ov2: ast.Name* = ast.Name*(oat2.value) if ov2.id is not None and string.strcmp(ov2.id, "t") == 0: other_is_cvoid = 1 elif other_node.kind() == ast.ASTKind.Name: - onm2: rawptr[ast.Name] = rawptr[ast.Name](other_node) + onm2: ast.Name* = ast.Name*(other_node) if onm2.id is not None and string.strcmp(onm2.id, "CVoid") == 0: if self.Gen.ImportsGen.is_module_imported(imported_modules, "t") != 0: other_is_cvoid = 1 if other_is_cvoid != 0: return llvmlite.Ptr(pool, llvmlite.Int8(pool)) - other_ty: rawptr[llvmlite.LLVMType] = self.resolve_annotation_type( + other_ty: llvmlite.LLVMType* = self.resolve_annotation_type( pool, other_node, imported_modules, from_imports, trans, depth + 1) # 仅裸名(Name)场景验证解析结果必须是已注册 struct: # 损坏节点可能解析出基础类型垃圾(如 Int8 → Ptr(i8))。 @@ -2609,9 +2614,9 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): # 按 8 字节槽写、elem_size=4 步长读 → 元素互相覆盖, # pop 读到 0(ListTest 根因)。泛型参数名放行。 keep_other_ty: int = 0 - tpn_g2: list[str] | t.CPtr = self.Gen.TypeGenBase.GenericTpNames + tpn_g2: list[str]* = self.Gen.TypeGenBase.GenericTpNames if tpn_g2 is not None: - other_nm_x: rawptr[ast.Name] = rawptr[ast.Name](other_node) + other_nm_x: ast.Name* = ast.Name*(other_node) gtn_nx: sizet = len(tpn_g2) gtn_ix: sizet for gtn_ix in range(gtn_nx): @@ -2626,7 +2631,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): # int → 联合退化为 i8* → int_ptr[0]=val 写 1 字节截断、 # 读回符号扩展(DictTest key5=500 读出 -12 根因)。 if keep_other_ty == 0 and other_node is not None and other_node.kind() == ast.ASTKind.Name: - other_nm_b: rawptr[ast.Name] = rawptr[ast.Name](other_node) + other_nm_b: ast.Name* = ast.Name*(other_node) if other_nm_b.id is not None: if string.strcmp(other_nm_b.id, "int") == 0 or \ string.strcmp(other_nm_b.id, "char") == 0 or \ @@ -2647,7 +2652,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): # 恒为"追加 1 层指针",唯一例外是 struct 引用语义时吸收这 1 层 # (判据 = Ptr 的 pointee 是否为已注册 struct,find_struct_by_type 命中即吸收)。 if keep_other_ty == 0 and other_node is not None and other_node.kind() == ast.ASTKind.Name: - other_nm_td: rawptr[ast.Name] = rawptr[ast.Name](other_node) + other_nm_td: ast.Name* = ast.Name*(other_node) if other_nm_td.id is not None: td_res_is_ptr: int = 0 match other_ty: @@ -2659,7 +2664,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): case _: td_res_is_ptr = 0 if td_res_is_ptr == 0: - td_alias_ty: rawptr[llvmlite.LLVMType] = self.resolve_typedef_or_map( + td_alias_ty: llvmlite.LLVMType* = self.resolve_typedef_or_map( pool, other_nm_td.id, imported_modules, from_imports, trans) if td_alias_ty is not None: keep_other_ty = 1 @@ -2676,11 +2681,11 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): # 仅裸名(Name)场景回退:Attribute 场景 resolve 已成功。 other_cls_nm: str = None if other_node is not None and other_node.kind() == ast.ASTKind.Name: - other_nm: rawptr[ast.Name] = rawptr[ast.Name](other_node) + other_nm: ast.Name* = ast.Name*(other_node) if other_nm.id is not None: other_cls_nm = other_nm.id if other_cls_nm is not None: - other_cls_ty: rawptr[llvmlite.LLVMType] = self.Gen.StructGen.get_struct_type(other_cls_nm) + other_cls_ty: llvmlite.LLVMType* = self.Gen.StructGen.get_struct_type(other_cls_nm) if other_cls_ty is not None: return llvmlite.Ptr(pool, other_cls_ty) # 类名未注册:可能是前向自我引用(如 json 的 @@ -2695,8 +2700,8 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): # X | t.CPtr[T] → 指针层级合并(对齐 TPC HandlesTypeMerge.py L864-884: # CPtr 侧贡献 PtrCount,另一侧提供 BaseType),如 uint8 | t.CPtr[t.CPtr] → u8**。 # 不处理会落到"无 CPtr 标记"分支返回左值 i8 → c.Deref 报"参数不是指针类型"。 - cptr_sub_side: rawptr[ast.AST] = None - cptr_other: rawptr[ast.AST] = None + cptr_sub_side: ast.AST* = None + cptr_other: ast.AST* = None if self._is_cptr_subscript(bop.left) != 0: cptr_sub_side = bop.left cptr_other = bop.right @@ -2704,21 +2709,21 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): cptr_sub_side = bop.right cptr_other = bop.left if cptr_sub_side is not None and cptr_other is not None: - cptr_sub_ty: rawptr[llvmlite.LLVMType] = self.resolve_annotation_type( + cptr_sub_ty: llvmlite.LLVMType* = self.resolve_annotation_type( pool, cptr_sub_side, imported_modules, from_imports, trans, depth + 1) - cptr_other_ty: rawptr[llvmlite.LLVMType] = self.resolve_annotation_type( + cptr_other_ty: llvmlite.LLVMType* = self.resolve_annotation_type( pool, cptr_other, imported_modules, from_imports, trans, depth + 1) if cptr_sub_ty is not None and cptr_other_ty is not None: # 计算 CPtr 侧外层 Ptr 嵌套数(如 t.CPtr[t.CPtr]=i8** → 2 层) cptr_level: int = 0 - cur_lvl: rawptr[llvmlite.LLVMType] = cptr_sub_ty + cur_lvl: llvmlite.LLVMType* = cptr_sub_ty while cur_lvl is not None: # 注意:不能在 case body 内直接更新 while 条件变量 # (cur_lvl = cur_lvl.Pointee)——自举编译出的 match 会把 # 赋值写到 subject 快照槽,while 条件仍读旧槽 → 死循环 # (gen2 编 FuncTest 卡死根因,gdb 反汇编 +3770-3819 确认)。 # 改法:case 绑定 pointee 到局部变量,match 外更新循环变量。 - nxt_lvl: rawptr[llvmlite.LLVMType] = None + nxt_lvl: llvmlite.LLVMType* = None match cur_lvl: case llvmlite.LLVMType.Ptr(pointee): cptr_level += 1 @@ -2727,7 +2732,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): break cur_lvl = nxt_lvl # 结果 = 另一侧类型外包 N 层 Ptr - res_ty: rawptr[llvmlite.LLVMType] = cptr_other_ty + res_ty: llvmlite.LLVMType* = cptr_other_ty li2: int = 0 while li2 < cptr_level: res_ty = llvmlite.Ptr(pool, res_ty) @@ -2735,11 +2740,11 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): return res_ty # 无 CPtr 标记:返回第一个非 None(装饰器标记如 CExport/CExtern 被忽略) - left_ty: rawptr[llvmlite.LLVMType] = self.resolve_annotation_type( + left_ty: llvmlite.LLVMType* = self.resolve_annotation_type( pool, bop.left, imported_modules, from_imports, trans, depth + 1) if left_ty is not None: return left_ty - right_ty: rawptr[llvmlite.LLVMType] = self.resolve_annotation_type( + right_ty: llvmlite.LLVMType* = self.resolve_annotation_type( pool, bop.right, imported_modules, from_imports, trans, depth + 1) if right_ty is not None: return right_ty @@ -2751,39 +2756,69 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): # value 是 Attribute(Name('t'), 'CArray') 或 Name('list')(泛型类) # slice 是 Tuple(elts=[elem_ty_node, count_node]) 或单 elem_ty_node if k == ast.ASTKind.Subscript: - sub: rawptr[ast.Subscript] = rawptr[ast.Subscript](node) + sub: ast.Subscript* = ast.Subscript*(node) if sub.value is None or sub.slice is None: self.Gen.TypeGenErr.fatal_type_error(node, "Subscript 节点缺少 value 或 slice") # 泛型类类型注解: list[int] → 查找已特化的 struct(value 是 Name 泛型类名) if sub.value.kind() == ast.ASTKind.Name: - gen_nm: rawptr[ast.Name] = rawptr[ast.Name](sub.value) + gen_nm: ast.Name* = ast.Name*(sub.value) if gen_nm.id is not None: + # 内建定长数组构造子 array[E, N](软关键字,与 t.CArray[E, N] 逐点等价): + # 只在类型/注解位置生效;非类型位置仍是普通标识符(如 json.array(...) 函数)。 + # 只接受恰好两个参数;缺参/多参/长度 None 或非正整型常量表达式 → fail-fast + # (不静默降级为 Ptr/长度 1)。t.CArray/rawarray 的既有(含单参自动推导) + # 写法完全不受影响。 + if string.strcmp(gen_nm.id, "array") == 0: + if sub.slice.kind() != ast.ASTKind.Tuple: + self.Gen.TypeGenErr.fatal_type_error(node, "内建定长数组构造子 'array' 缺少长度参数(当前仅 1 个参数):必须写成 array[E, N](E=元素类型,N=长度)。正确示例:state: array[uint32, 4]") + tup_arr: ast.Tuple* = ast.Tuple*(sub.slice) + if tup_arr.elts is None or len(tup_arr.elts) != 2: + self.Gen.TypeGenErr.fatal_type_error(node, "内建定长数组构造子 'array' 参数个数错误(期望 2 个):只接受 array[E, N]。正确示例:state: array[uint32, 4]") + elem_node_arr: ast.AST* = tup_arr.elts.get(0) + count_node_arr: ast.AST* = tup_arr.elts.get(1) + if elem_node_arr is None or count_node_arr is None: + self.Gen.TypeGenErr.fatal_type_error(node, "内建定长数组构造子 'array' 的元素类型或长度为空:只接受 array[E, N]。正确示例:state: array[uint32, 4]") + if count_node_arr.kind() == ast.ASTKind.Constant: + cnt_arr0: ast.Constant* = ast.Constant*(count_node_arr) + if cnt_arr0.const_kind == ast.CONST_NONE: + self.Gen.TypeGenErr.fatal_type_error(count_node_arr, "内建定长数组构造子 'array' 的长度必须是正整型常量(>0),不允许 None(长度自动推导请改用 t.CArray[E])。正确示例:state: array[uint32, 4]") + elem_ty_arr: llvmlite.LLVMType* = self.resolve_annotation_type( + pool, elem_node_arr, imported_modules, from_imports, trans, depth + 1) + if elem_ty_arr is None: + return None + count_arr: int = self.Gen.TypeGenCType._eval_const_int_expr( + count_node_arr, pool, from_imports, imported_modules) + if self.Gen.TypeGenCType.ConstEvalOk == 0: + self.Gen.TypeGenErr.fatal_type_error(count_node_arr, "内建定长数组构造子 'array' 的长度必须是整型常量表达式(字面量 / CDefine 常量名 / 常量算术表达式)。正确示例:state: array[uint8, MAX_LEN]") + if count_arr <= 0: + self.Gen.TypeGenErr.fatal_type_error(count_node_arr, "内建定长数组构造子 'array' 的长度必须为正数。正确示例:state: array[uint32, 4]") + return llvmlite.Array(pool, elem_ty_arr, count_arr) # 裸名 CArray(from t import * 场景):与 t.CArray 语义等价——否则走泛型 # 模板查找失败 → 字段类型退化 Ptr(i8) → 默认值 List 字面量误走动态 list # 构造(符号未生成 → 链接 undefined reference)。 if string.strcmp(gen_nm.id, "CArray") == 0 or string.strcmp(gen_nm.id, "rawarray") == 0: # 单参数: CArray[elem_ty] → Ptr(elem_ty)(静态推导长度数组) if sub.slice.kind() != ast.ASTKind.Tuple: - elem_n: rawptr[llvmlite.LLVMType] = self.resolve_annotation_type( + elem_n: llvmlite.LLVMType* = self.resolve_annotation_type( pool, sub.slice, imported_modules, from_imports, trans, depth + 1) if elem_n is None: return None return llvmlite.Ptr(pool, elem_n) # 双参数: CArray[elem_ty, count] → [count x elem_ty] - tup_n: rawptr[ast.Tuple] = rawptr[ast.Tuple](sub.slice) + tup_n: ast.Tuple* = ast.Tuple*(sub.slice) if tup_n.elts is None or len(tup_n.elts) < 2: return None - elem_node_n: rawptr[ast.AST] = tup_n.elts.get(0) - count_node_n: rawptr[ast.AST] = tup_n.elts.get(1) + elem_node_n: ast.AST* = tup_n.elts.get(0) + count_node_n: ast.AST* = tup_n.elts.get(1) if elem_node_n is None or count_node_n is None: return None - elem_ty_n: rawptr[llvmlite.LLVMType] = self.resolve_annotation_type( + elem_ty_n: llvmlite.LLVMType* = self.resolve_annotation_type( pool, elem_node_n, imported_modules, from_imports, trans, depth + 1) if elem_ty_n is None: return None # count=None → Ptr(elem)(等价单参) if count_node_n.kind() == ast.ASTKind.Constant: - cnt_n: rawptr[ast.Constant] = rawptr[ast.Constant](count_node_n) + cnt_n: ast.Constant* = ast.Constant*(count_node_n) if cnt_n.const_kind == ast.CONST_NONE: return llvmlite.Ptr(pool, elem_ty_n) count_n: int = self.Gen.TypeGenCType._eval_const_int_expr( @@ -2796,13 +2831,13 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): # "函数返回类型解析失败:注解不可解析"。 if string.strcmp(gen_nm.id, "rawptr") == 0: if sub.slice.kind() != ast.ASTKind.Tuple: - rp_elem: rawptr[llvmlite.LLVMType] = self.resolve_annotation_type( + rp_elem: llvmlite.LLVMType* = self.resolve_annotation_type( pool, sub.slice, imported_modules, from_imports, trans, depth + 1) if rp_elem is None: return None return llvmlite.Ptr(pool, rp_elem) return None - gen_ty_nm: rawptr[llvmlite.LLVMType] = self._resolve_generic_subscript_ty( + gen_ty_nm: llvmlite.LLVMType* = self._resolve_generic_subscript_ty( pool, sub, gen_nm.id, trans, imported_modules, from_imports, depth + 1) if gen_ty_nm is not None: @@ -2812,7 +2847,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): # 下方 builtins 兜底若也未命中,仍按旧行为返回 None(多遍 # 收敛/上层报错),不落到"仅支持 t.CArray/t.Callable"fatal。 if sub.value.kind() == ast.ASTKind.Name: - gen_nm_fb: rawptr[ast.Name] = rawptr[ast.Name](sub.value) + gen_nm_fb: ast.Name* = ast.Name*(sub.value) if gen_nm_fb.id is not None: fb_td: str = self._lookup_builtins_typedef(pool, gen_nm_fb.id) if fb_td is not None: @@ -2826,9 +2861,9 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): string.strcat(fb_str, "[") string.strcat(fb_str, fb_slice) string.strcat(fb_str, "]") - fb_node: rawptr[ast.AST] = self._parse_type_string(pool, fb_str, ast.ASTCtx.Load) + fb_node: ast.AST* = self._parse_type_string(pool, fb_str, ast.ASTCtx.Load) if fb_node is not None: - fb_ty: rawptr[llvmlite.LLVMType] = self.resolve_annotation_type( + fb_ty: llvmlite.LLVMType* = self.resolve_annotation_type( pool, fb_node, imported_modules, from_imports, trans, depth + 1) if fb_ty is not None: return fb_ty @@ -2836,7 +2871,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): # 检查 value 是否是 Attribute(t.CArray / t.Callable / 模块限定泛型类如 numpy.ndarray[T]) if sub.value.kind() != ast.ASTKind.Attribute: self.Gen.TypeGenErr.fatal_type_error(node, "不支持的 Subscript 类型注解(仅支持 t.CArray / t.Callable)") - arr_at: rawptr[ast.Attribute] = rawptr[ast.Attribute](sub.value) + arr_at: ast.Attribute* = ast.Attribute*(sub.value) if arr_at.attr is None: self.Gen.TypeGenErr.fatal_type_error(node, "Subscript Attribute 缺少 attr") # 模块限定泛型类: numpy.ndarray[t.CDouble] → 裸类名 ndarray 走泛型特化 @@ -2847,7 +2882,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): imported_modules, from_imports, depth + 1) if arr_at.value is None or arr_at.value.kind() != ast.ASTKind.Name: self.Gen.TypeGenErr.fatal_type_error(node, "t.CArray / t.Callable 必须通过模块名限定") - arr_val_name: rawptr[ast.Name] = rawptr[ast.Name](arr_at.value) + arr_val_name: ast.Name* = ast.Name*(arr_at.value) if arr_val_name.id is None: self.Gen.TypeGenErr.fatal_type_error(node, "Subscript 模块名为 None") # 函数指针类型: t.Callable[[A, B], Ret] → i8* @@ -2864,7 +2899,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): if string.strcmp(arr_val_name.id, "t") != 0 and string.strcmp(arr_val_name.id, "c") != 0 \ and self.Gen.ImportsGen.is_module_imported(imported_modules, arr_val_name.id) == 0: self.Gen.TypeGenErr.fatal_type_error(node, "t.CPtr 模块未导入") - inner_cptr_ty: rawptr[llvmlite.LLVMType] = self.resolve_annotation_type( + inner_cptr_ty: llvmlite.LLVMType* = self.resolve_annotation_type( pool, sub.slice, imported_modules, from_imports, trans, depth + 1) if inner_cptr_ty is None: # 元素类型依赖未就绪(如 t.CPtr[类] 中类尚未注册):返回 None 交上层多遍 @@ -2881,26 +2916,26 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): # 单参数形式: t.CArray[elem_ty] → Ptr(elem_ty) # 相当于 t.CArray[elem_ty, None],表示静态推导长度数组 if sub.slice.kind() != ast.ASTKind.Tuple: - elem_ty_single: rawptr[llvmlite.LLVMType] = self.resolve_annotation_type( + elem_ty_single: llvmlite.LLVMType* = self.resolve_annotation_type( pool, sub.slice, imported_modules, from_imports, trans, depth + 1) if elem_ty_single is None: # 元素类型依赖未就绪(同 L1807 注释):返回 None 交多遍收敛 return None return llvmlite.Ptr(pool, elem_ty_single) # 双参数形式: t.CArray[elem_ty, count] → [count x elem_ty] - tup: rawptr[ast.Tuple] = rawptr[ast.Tuple](sub.slice) + tup: ast.Tuple* = ast.Tuple*(sub.slice) if tup.elts is None: self.Gen.TypeGenErr.fatal_type_error(node, "t.CArray Tuple 缺少 elts") elts_list: list[ast.AST*]* = tup.elts elts_n: sizet = len(elts_list) if elts_n < 2: self.Gen.TypeGenErr.fatal_type_error(node, "t.CArray Tuple 元素不足") - elem_node: rawptr[ast.AST] = elts_list.get(0) - count_node: rawptr[ast.AST] = elts_list.get(1) + elem_node: ast.AST* = elts_list.get(0) + count_node: ast.AST* = elts_list.get(1) if elem_node is None or count_node is None: self.Gen.TypeGenErr.fatal_type_error(node, "t.CArray Tuple 元素为 None") # 递归解析元素类型 - elem_ty: rawptr[llvmlite.LLVMType] = self.resolve_annotation_type( + elem_ty: llvmlite.LLVMType* = self.resolve_annotation_type( pool, elem_node, imported_modules, from_imports, trans, depth + 1) if elem_ty is None: # 元素类型依赖未就绪(如 t.CArray[类, N] 中类尚未注册):返回 None 交上层多遍 @@ -2914,7 +2949,7 @@ class TypeGenResolve(TypeGenBase.TypeGenBase): # t.CArray[elem_ty, 2 * MAX] 常量表达式静态计算 → [2*MAX x elem_ty] count_val: int = 0 if count_node.kind() == ast.ASTKind.Constant: - cnt_cn: rawptr[ast.Constant] = rawptr[ast.Constant](count_node) + cnt_cn: ast.Constant* = ast.Constant*(count_node) if cnt_cn.const_kind == ast.CONST_NONE: return llvmlite.Ptr(pool, elem_ty) # 统一用 _eval_const_int_expr 计算常量整数表达式 diff --git a/App/lib/core/Gen/Type/TypeSpec.vp b/App/lib/core/Gen/Type/TypeSpec.vp index 8f1e182..e9a01f5 100644 --- a/App/lib/core/Gen/Type/TypeSpec.vp +++ b/App/lib/core/Gen/Type/TypeSpec.vp @@ -93,7 +93,7 @@ def _spec_name_eq(text: str, start: sizet, end: sizet, lit: str) -> int: # 基名 = 先截断第一个 '[' 起的泛型实参,再取**最后一个 '.' 之后**的部分 # (去模块名 / LLVM 注册名的模块 sha1 前缀)。例: # "e94ef9e139461915.list[ast.ASTptr]" → "list" -# "list[rawptr[ast.AST]]" → "list" +# "list[ast.AST*]" → "list" # "memhub.MemBuddy" → "MemBuddy"(≠ list/dict) # # 用途:替换容器种类判断里的 strstr 子串匹配(Debugger/_Type.md D20)—— @@ -230,14 +230,14 @@ class TypeSpec: # 而 PermPool 分配天然满足 ⇒ SpecWithSource 返回独立副本、不进表。 SourceName: str Ret: TypeSpec | t.CPtr # Func:返回类型 - Params: sizet | t.CPtr # Func:参数数组(连续 TypeSpec* 指针,ParamCount 个) + Params: sizet* # Func:参数数组(连续 TypeSpec* 指针,ParamCount 个) ParamCount: int # Func:参数个数 IsVarArg: int # Func:1=变参(...) Storage: int # 限定宏位标志(0=无) ElemBits: int # 元素槽位宽(元素语义三元组 1/3) IsElemPtr: int # 元素是否为指针(1=是)(2/3) DerefBase: int # 基址是否需二次解引用(1=是)(3/3) - Ty: rawptr[llvmlite.LLVMType] # 解析结果缓存(可空) + Ty: llvmlite.LLVMType* # 解析结果缓存(可空) # ============================================================ @@ -251,12 +251,12 @@ class TypeSpec: class TypeSpecArena: """TypeSpec 驻留表(按规范文本键去重,同型只存一份)""" Keys: bytes - Specs: sizet | t.CPtr + Specs: sizet* Count: int Cap: int # 规范文本键 → 驻留下标 的开放寻址哈希索引(槽为 u64:0=空槽,否则 index+1)。 # 可选加速层:为 None 时 InternSpec 回退原线性扫描(语义完全一致)。 - Index: sizet | t.CPtr + Index: sizet* # 索引槽数(2 的幂,> 2*Cap;仅 Index 非 None 时有效) IndexCap: int @@ -301,7 +301,7 @@ def _spec_index_find(arena: TypeSpecArena | t.CPtr, key: str, h: uint64) -> int: idx: sizet = sizet(h) & mask i: int = 0 while i < arena.IndexCap: - slot: sizet | t.CPtr = (sizet | t.CPtr)(uint64(arena.Index) + uint64(idx * 8)) + slot: sizet* = (sizet*)(uint64(arena.Index) + uint64(idx * 8)) sv: sizet = slot[0] if sv == 0: return -1 @@ -327,7 +327,7 @@ def _spec_index_insert(arena: TypeSpecArena | t.CPtr, key: str, h: uint64, ei: i idx: sizet = sizet(h) & mask i: int = 0 while i < arena.IndexCap: - slot: sizet | t.CPtr = (sizet | t.CPtr)(uint64(arena.Index) + uint64(idx * 8)) + slot: sizet* = (sizet*)(uint64(arena.Index) + uint64(idx * 8)) if slot[0] == 0: slot[0] = sizet(ei + 1) return 0 @@ -349,11 +349,11 @@ def SpecArenaInit(arena: TypeSpecArena | t.CPtr, cap: int) -> int: use_cap: int = cap if use_cap <= 0: use_cap = SPEC_INTERN_MAX - pp: rawptr[memhub.MemBuddy] = CompilerFactory.factory.PermPool + pp: memhub.MemBuddy* = CompilerFactory.factory.PermPool keys: bytes = pp.alloc(use_cap * SPEC_TEXT_MAX) if keys is None: return 1 - specs: sizet | t.CPtr = pp.alloc(use_cap * 8) + specs: sizet* = pp.alloc(use_cap * 8) if specs is None: return 1 string.memset(keys, 0, use_cap * SPEC_TEXT_MAX) @@ -368,7 +368,7 @@ def SpecArenaInit(arena: TypeSpecArena | t.CPtr, cap: int) -> int: icap: int = 1 while icap < use_cap * 2: icap = icap * 2 - idx_buf: sizet | t.CPtr = pp.alloc(icap * 8) + idx_buf: sizet* = pp.alloc(icap * 8) if idx_buf is not None: string.memset(idx_buf, 0, icap * 8) arena.Index = idx_buf @@ -384,7 +384,7 @@ def SpecArenaInit(arena: TypeSpecArena | t.CPtr, cap: int) -> int: # ============================================================ def _spec_alloc() -> TypeSpec | t.CPtr: """分配并清零一个 TypeSpec(PermPool)""" - pp: rawptr[memhub.MemBuddy] = CompilerFactory.factory.PermPool + pp: memhub.MemBuddy* = CompilerFactory.factory.PermPool size: sizet = TypeSpec.__sizeof__() sp: TypeSpec | t.CPtr = (TypeSpec | t.CPtr)(pp.alloc(size)) if sp is None: @@ -502,7 +502,7 @@ def NewTypeArray(arena: TypeSpecArena | t.CPtr, elem: TypeSpec | t.CPtr, # params:TypeSpec* 连续数组(由调用方预先构造并保证存活);count 个 # ============================================================ def NewTypeFunc(arena: TypeSpecArena | t.CPtr, ret: TypeSpec | t.CPtr, - params: sizet | t.CPtr, count: int, + params: sizet*, count: int, is_vararg: int) -> TypeSpec | t.CPtr: """构造函数签名类型,失败返回 None""" if ret is None or count < 0: @@ -691,7 +691,7 @@ def _spec_param_at(sp: TypeSpec | t.CPtr, index: int) -> TypeSpec | t.CPtr: if sp is None or sp.Params is None or index < 0 or index >= sp.ParamCount: return None addr: uint64 = uint64(sp.Params) + uint64(index * 8) - slot: sizet | t.CPtr = (sizet | t.CPtr)(addr) + slot: sizet* = (sizet*)(addr) if slot is None: return None return (TypeSpec | t.CPtr)(uint64(slot[0])) @@ -815,7 +815,7 @@ def _text_to_func(text: str, depth: int) -> TypeSpec | t.CPtr: if string.strstr(params_buf, "...") is not None: is_vararg = 1 # 逐段解析参数(按顶层 ',' 分割;变参段 "..." 跳过) - param_specs: sizet | t.CPtr = CompilerFactory.factory.PermPool.alloc(8 * 64) + param_specs: sizet* = CompilerFactory.factory.PermPool.alloc(8 * 64) if param_specs is None: return None pcount: int = 0 @@ -842,7 +842,7 @@ def _text_to_func(text: str, depth: int) -> TypeSpec | t.CPtr: psp: TypeSpec | t.CPtr = _text_to_spec(seg, depth + 1) if psp is None: return None - slot_p: sizet | t.CPtr = (sizet | t.CPtr)(uint64(param_specs) + uint64(pcount * 8)) + slot_p: sizet* = (sizet*)(uint64(param_specs) + uint64(pcount * 8)) if slot_p is None: return None slot_p[0] = sizet(psp) @@ -888,7 +888,7 @@ def InternSpec(arena: TypeSpecArena | t.CPtr, key_hash: uint64 = _spec_key_hash(key_buf) found: int = _spec_index_find(arena, key_buf, key_hash) if found >= 0: - slot_e: sizet | t.CPtr = (sizet | t.CPtr)(uint64(arena.Specs) + uint64(found * 8)) + slot_e: sizet* = (sizet*)(uint64(arena.Specs) + uint64(found * 8)) if slot_e is None: return None return (TypeSpec | t.CPtr)(uint64(slot_e[0])) @@ -898,7 +898,7 @@ def InternSpec(arena: TypeSpecArena | t.CPtr, while i < arena.Count: exist_key: str = _spec_key_at(arena.Keys, i) if exist_key is not None and string.strcmp(exist_key, key_buf) == 0: - slot_e2: sizet | t.CPtr = (sizet | t.CPtr)(uint64(arena.Specs) + uint64(i * 8)) + slot_e2: sizet* = (sizet*)(uint64(arena.Specs) + uint64(i * 8)) if slot_e2 is None: return None return (TypeSpec | t.CPtr)(uint64(slot_e2[0])) @@ -918,7 +918,7 @@ def InternSpec(arena: TypeSpecArena | t.CPtr, if dst_key is None: return None string.strcpy(dst_key, key_buf) - slot_n: sizet | t.CPtr = (sizet | t.CPtr)(uint64(arena.Specs) + uint64(arena.Count * 8)) + slot_n: sizet* = (sizet*)(uint64(arena.Specs) + uint64(arena.Count * 8)) if slot_n is None: return None slot_n[0] = sizet(sp) @@ -1122,14 +1122,14 @@ def SpecBitWidth(sp: TypeSpec | t.CPtr) -> int: # ⚠️ 规避自举 match codegen 缺陷:`case` 体内直接更新外层 while 条件变量会把赋值 # 写进 subject 快照槽,while 条件读旧槽 ⇒ 死循环。故此处 `case` 只绑定局部 `nxt`, # 循环变量在 match **外**更新。 -def SpecTypePtrLevel(ty: rawptr[llvmlite.LLVMType]) -> int: +def SpecTypePtrLevel(ty: llvmlite.LLVMType*) -> int: """计算指针层级,0=非指针,1=一级指针,2=二级指针…""" if ty is None: return 0 level: int = 0 - cur: rawptr[llvmlite.LLVMType] = ty + cur: llvmlite.LLVMType* = ty while cur is not None: - nxt: rawptr[llvmlite.LLVMType] = None + nxt: llvmlite.LLVMType* = None match cur: case llvmlite.LLVMType.Ptr(pointee): level += 1 @@ -1149,7 +1149,7 @@ def SpecTypePtrLevel(ty: rawptr[llvmlite.LLVMType]) -> int: # 副本一旦分叉会出现「同一类型在两处算出不同位宽」的隐蔽不一致。 # 非整数类型(指针/浮点/结构体等)返回 0 —— 0 是"非整数"的表态,不是兜底位宽。 # ============================================================ -def SpecTypeBits(ty: rawptr[llvmlite.LLVMType]) -> int: +def SpecTypeBits(ty: llvmlite.LLVMType*) -> int: """获取 LLVM 整数类型的位宽,非整数类型返回 0""" if ty is None: return 0 @@ -1315,7 +1315,7 @@ def _spec_llvm_text(sp: TypeSpec | t.CPtr, buf: str, buf_size: sizet, # 本函数当前**无调用点**(S2 只入库;接线在后续步骤)。 # ============================================================ def SpecFromLLVMType(arena: TypeSpecArena | t.CPtr, - ty: rawptr[llvmlite.LLVMType]) -> TypeSpec | t.CPtr: + ty: llvmlite.LLVMType*) -> TypeSpec | t.CPtr: """把已解析的 LLVM 类型翻译成 TypeSpec;不支持或为 None 时返回 None""" if arena is None or ty is None: return None @@ -1341,7 +1341,7 @@ def SpecFromLLVMType(arena: TypeSpecArena | t.CPtr, def _spec_from_ptr(arena: TypeSpecArena | t.CPtr, - pointee: rawptr[llvmlite.LLVMType]) -> TypeSpec | t.CPtr: + pointee: llvmlite.LLVMType*) -> TypeSpec | t.CPtr: """Ptr(pointee) → TypeSpec(PtrLevel/ElemBits/IsElemPtr 由 NewTypePtr 填)""" inner: TypeSpec | t.CPtr = SpecFromLLVMType(arena, pointee) if inner is None: @@ -1350,7 +1350,7 @@ def _spec_from_ptr(arena: TypeSpecArena | t.CPtr, def _spec_from_array(arena: TypeSpecArena | t.CPtr, - elem_ty: rawptr[llvmlite.LLVMType], + elem_ty: llvmlite.LLVMType*, count: int) -> TypeSpec | t.CPtr: """[count x elem] → TypeSpec(ArrayCount/ElemBits/IsElemPtr 由 NewTypeArray 填)""" inner: TypeSpec | t.CPtr = SpecFromLLVMType(arena, elem_ty) @@ -1360,27 +1360,27 @@ def _spec_from_array(arena: TypeSpecArena | t.CPtr, def _spec_from_func(arena: TypeSpecArena | t.CPtr, - ret: rawptr[llvmlite.LLVMType], - params: rawptr[llvmlite.Function], + ret: llvmlite.LLVMType*, + params: llvmlite.Function*, pcount: int) -> TypeSpec | t.CPtr: """函数类型 → TypeSpec(形参沿 ParamNode 链表遍历;IsVarArg 恒 0,见上)""" ret_s: TypeSpec | t.CPtr = SpecFromLLVMType(arena, ret) if ret_s is None: return None if pcount <= 0: - no_params: sizet | t.CPtr = None + no_params: sizet* = None return NewTypeFunc(arena, ret_s, no_params, 0, 0) - params_arr: sizet | t.CPtr = CompilerFactory.factory.PermPool.alloc(8 * pcount) + params_arr: sizet* = CompilerFactory.factory.PermPool.alloc(8 * pcount) if params_arr is None: return None - node: rawptr[llvmlite.Function] = params + node: llvmlite.Function* = params i: int = 0 while node is not None and i < pcount: - pty: rawptr[llvmlite.LLVMType] = llvmlite.paramnode_get_ty(node) + pty: llvmlite.LLVMType* = llvmlite.paramnode_get_ty(node) ps: TypeSpec | t.CPtr = SpecFromLLVMType(arena, pty) if ps is None: return None - slot: sizet | t.CPtr = (sizet | t.CPtr)(uint64(params_arr) + uint64(i * 8)) + slot: sizet* = (sizet*)(uint64(params_arr) + uint64(i * 8)) if slot is None: return None slot[0] = sizet(ps) @@ -1441,14 +1441,14 @@ def SpecSelfCheck() -> int: return 4 # 5) fn(i32,u64)->i32(变参) - params: sizet | t.CPtr = CompilerFactory.factory.PermPool.alloc(8 * 2) + params: sizet* = CompilerFactory.factory.PermPool.alloc(8 * 2) if params is None: return 5 - slot0: sizet | t.CPtr = (sizet | t.CPtr)(uint64(params)) + slot0: sizet* = (sizet*)(uint64(params)) if slot0 is None: return 5 slot0[0] = sizet(s_i32) - slot1: sizet | t.CPtr = (sizet | t.CPtr)(uint64(params) + 8) + slot1: sizet* = (sizet*)(uint64(params) + 8) if slot1 is None: return 5 slot1[0] = sizet(s_u64) diff --git a/App/lib/core/Gen/VarGenMixin.vp b/App/lib/core/Gen/VarGenMixin.vp index daa490c..2058228 100644 --- a/App/lib/core/Gen/VarGenMixin.vp +++ b/App/lib/core/Gen/VarGenMixin.vp @@ -1,6 +1,7 @@ import lib.core.Gen.GenTypes as GenTypes import lib.core.Gen.Generator as Generator import lib.core.Gen.Type.TypeSpec as TSpec +from MatchGenMixin import SCOPE_MATCH import lib.core.Gen.Translator as HT import t, c from stdint import * @@ -13,63 +14,48 @@ import stdlib # ============================================================ # VarGenMixin - 变量/作用域符号表 Mixin -# -# 职责:变量注册/查找、作用域进出(模块/函数/match)与 alloca 创建。 -# @t.NoVTable:静态绑定(方法沿 MRO 直接调用 + this 调整,无 vtable 开销)。 # ============================================================ # ============================================================ -# 常量(与 HandlesVar 保持一致) +# 常量(作用域类型;容量常量经 HT. 引用,见下) # ============================================================ # 作用域类型常量 -SCOPE_MODULE: t.CDefine = 0 -SCOPE_FUNCTION: t.CDefine = 1 -SCOPE_BLOCK: t.CDefine = 2 -# match case 作用域(对齐 MatchGenMixin.SCOPE_MATCH;本地定义避免循环依赖)。 -# 该作用域仅用于"变体字段绑定隔离",普通赋值语义上属于外层函数作用域, -# get_or_create_sym/_lookup_through_match_scope 会"看穿"它写回外层变量。 -SCOPE_MATCH: t.CDefine = 6 - -# 每个作用域最大变量数 -# 256 太小:NewAstTest main() 有 289 个局部变量(几十个测试用例), -# add_var 超限静默失败导致变量未注册,后续使用报"未定义名称"(NameError)。 -MAX_VARS: t.CDefine = 1024 +define SCOPE_MODULE = 0 +define SCOPE_FUNCTION = 1 +define SCOPE_BLOCK = 2 +# 每个作用域最大变量数:唯一真源在 Translator.vp,本文件一律写 HT.MAX_VARS # ============================================================ # VarGenMixin - 变量/作用域符号表 Mixin # ============================================================ -@t.NoVTable -class VarGenMixin: - """变量/作用域 Mixin(P6 方法化)""" - # 迁移自 HandlesVar 的模块级函数 - +novirtual class VarGenMixin: + """变量/作用域 Mixin""" # ============================================================ # init_vars — 分配并清零 VarEntry 数组 # ============================================================ - Gen: rawptr[Generator.Generator] - def init_vars(self, pool: rawptr[memhub.MemBuddy]) -> rawptr[GenTypes.VarEntry]: + Gen: Generator.Generator* + def init_vars(self, pool: memhub.MemBuddy*) -> GenTypes.VarEntry*: """分配并清零变量表数组""" - size: sizet = MAX_VARS * GenTypes.VarEntry.__sizeof__() - vars_ptr: rawptr[GenTypes.VarEntry] = pool.alloc(size) - if vars_ptr is not None: - string.memset(vars_ptr, 0, size) + size: sizet = HT.MAX_VARS * GenTypes.VarEntry.__sizeof__() + vars_ptr: GenTypes.VarEntry* = pool.alloc(size) + if vars_ptr is not None: string.memset(vars_ptr, 0, size) return vars_ptr # ============================================================ # find_var — 在变量表中按名称查找 # ============================================================ - def find_var(self, vars_ptr: rawptr[GenTypes.VarEntry], + def find_var(self, vars_ptr: GenTypes.VarEntry*, var_count: int, - name: str) -> rawptr[llvmlite.Value]: + name: str) -> 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: rawptr[GenTypes.VarEntry] = rawptr[GenTypes.VarEntry](entry_addr) + entry: GenTypes.VarEntry* = 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: @@ -79,16 +65,16 @@ class VarGenMixin: # ============================================================ # find_var_entry — 在变量表中按名称查找,返回 VarEntry(含 AnnotTy) # ============================================================ - def find_var_entry(self, vars_ptr: rawptr[GenTypes.VarEntry], + def find_var_entry(self, vars_ptr: GenTypes.VarEntry*, var_count: int, - name: str) -> rawptr[GenTypes.VarEntry]: + name: str) -> 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: rawptr[GenTypes.VarEntry] = rawptr[GenTypes.VarEntry](entry_addr) + entry: GenTypes.VarEntry* = GenTypes.VarEntry*(entry_addr) if entry.Name is not None and entry.Used != 0: if string.strcmp(entry.Name, name) == 0: return entry @@ -98,13 +84,13 @@ class VarGenMixin: # lookup_var_entry — 从当前作用域逐级向上查找变量,返回 VarEntry # ============================================================ def lookup_var_entry(self, symtab: rawptr[GenTypes.SymbolTable], - name: str) -> rawptr[GenTypes.VarEntry]: + name: str) -> GenTypes.VarEntry*: """从当前作用域逐级向上查找变量,返回 VarEntry 或 None""" if symtab is None or name is None: return None scope: rawptr[GenTypes.Scope] = symtab.Current while scope is not None: - result: rawptr[GenTypes.VarEntry] = self.find_var_entry(scope.Vars, scope.VarCount, name) + result: GenTypes.VarEntry* = self.find_var_entry(scope.Vars, scope.VarCount, name) if result is not None: return result scope = scope.Parent @@ -132,13 +118,13 @@ class VarGenMixin: """ if symtab is None or name is None: return 1 - entry: rawptr[GenTypes.VarEntry] = self.lookup_var_entry(symtab, name) + entry: 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: rawptr[TSpec.TypeSpecArena] = self.Gen.TypeGenBase.ensure_spec_arena() + arena_sn: TSpec.TypeSpecArena* = self.Gen.TypeGenBase.ensure_spec_arena() if arena_sn is None: return 1 if entry.Spec is None: @@ -158,7 +144,7 @@ class VarGenMixin: # 注解侧由 set_var_annot_class_name 经 SpecWithSource 写入 Spec.SourceName。 # 变量侧类名恢复读取点统一走此入口。 # ============================================================ - def var_annot_class_name(self, entry: rawptr[GenTypes.VarEntry]) -> str: + def var_annot_class_name(self, entry: GenTypes.VarEntry*) -> str: """变量条目注解类名(Spec.SourceName);未设置返回 None""" if entry is None: return None @@ -176,7 +162,7 @@ class VarGenMixin: """标记变量为 ptr-element(Spec.ElemBits=64),返回 0=成功 / 1=失败""" if symtab is None or name is None: return 1 - entry: rawptr[GenTypes.VarEntry] = self.lookup_var_entry(symtab, name) + entry: GenTypes.VarEntry* = self.lookup_var_entry(symtab, name) if entry is None: return 1 # ptr-element 变量的 alloca 是 Ptr(Ptr(Int8)),其值类型 Ptr(Int8) ⇒ Spec 必为 @@ -194,11 +180,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: rawptr[GenTypes.VarEntry]) -> int: + def var_is_ptr_element(self, entry: GenTypes.VarEntry*) -> int: """变量是否为 ptr-element 语义(1=是 / 0=否)""" if entry is None or entry.Spec is None: return 0 - sp: rawptr[TSpec.TypeSpec] = entry.Spec + sp: TSpec.TypeSpec* = entry.Spec if sp.PtrLevel < 1 or sp.Elem is None: return 0 if sp.Elem.Bits != 8: @@ -216,14 +202,14 @@ class VarGenMixin: """标记变量为 volatile(VarEntry.IsVolatile=1),返回 0=成功 / 1=失败""" if symtab is None or name is None: return 1 - entry: rawptr[GenTypes.VarEntry] = self.lookup_var_entry(symtab, name) + entry: GenTypes.VarEntry* = self.lookup_var_entry(symtab, name) if entry is None: return 1 entry.IsVolatile = 1 return 0 # var_is_volatile — 变量是否 volatile(读路径/写路径统一入口) - def var_is_volatile(self, entry: rawptr[GenTypes.VarEntry]) -> int: + def var_is_volatile(self, entry: GenTypes.VarEntry*) -> int: """变量条目是否 volatile(1=是 / 0=否;entry 为 None 时 0)""" if entry is None: return 0 @@ -239,34 +225,57 @@ class VarGenMixin: """标记变量所指物为 volatile(VarEntry.PointeeVolatile=1),返回 0=成功 / 1=失败""" if symtab is None or name is None: return 1 - entry: rawptr[GenTypes.VarEntry] = self.lookup_var_entry(symtab, name) + entry: GenTypes.VarEntry* = self.lookup_var_entry(symtab, name) if entry is None: return 1 entry.PointeeVolatile = 1 return 0 # var_pointee_is_volatile — 变量所指物是否 volatile(解引用读写统一入口) - def var_pointee_is_volatile(self, entry: rawptr[GenTypes.VarEntry]) -> int: + def var_pointee_is_volatile(self, entry: GenTypes.VarEntry*) -> int: """变量条目所指物是否 volatile(1=是 / 0=否;entry 为 None 时 0)""" if entry is None: return 0 return entry.PointeeVolatile + # set_var_const — 标记变量为 const 对象(注解含 t.CConst 且类型非指针) + # 语义:与 TPC 的 Gen.var_const_flags / global_const_flags 同判据、同报文 + # (见 Debugger/type-descriptors.md「两侧语义对照表」)。整个作用域内禁止对 + # 该变量名赋值 / 增量赋值 / 元素赋值;由注解侧(模块级已注册后 / 局部声明时 / + # 形参声明时)调用。 + def set_var_const(self, symtab: rawptr[GenTypes.SymbolTable], + name: str) -> int: + """标记变量为 const 对象(VarEntry.IsConst=1),返回 0=成功 / 1=失败""" + if symtab is None or name is None: + return 1 + entry: GenTypes.VarEntry* = self.lookup_var_entry(symtab, name) + if entry is None: + return 1 + entry.IsConst = 1 + return 0 + + # var_is_const — 变量是否 const 对象(赋值/增量赋值/元素赋值拦截面统一入口) + def var_is_const(self, entry: GenTypes.VarEntry*) -> int: + """变量条目是否 const 对象(1=是 / 0=否;entry 为 None 时 0)""" + if entry is None: + return 0 + return entry.IsConst + # ============================================================ # add_var — 添加变量到变量表 # ============================================================ - def add_var(self, vars_ptr: rawptr[GenTypes.VarEntry], + def add_var(self, vars_ptr: GenTypes.VarEntry*, var_count: int, name: str, - alloca: rawptr[llvmlite.Value]) -> int: + alloca: llvmlite.Value*) -> int: """添加变量到变量表""" if name is None or alloca is None or vars_ptr is None: return 1 - if var_count >= MAX_VARS: + if var_count >= HT.MAX_VARS: return 1 entry_size: sizet = GenTypes.VarEntry.__sizeof__() entry_addr: uint64 = uint64(vars_ptr) + var_count * entry_size - entry: rawptr[GenTypes.VarEntry] = rawptr[GenTypes.VarEntry](entry_addr) + entry: GenTypes.VarEntry* = GenTypes.VarEntry*(entry_addr) # 变量名必须深拷贝到 stdlib(跨 pool reset 存活):entry.Name 直接存 AST # 节点 Name.id 指针时,该段内存被后续分配覆盖会使 find_var 的 strcmp 静默 # 失配 → Handle 阶段找不到 PreScan 已建的同名 alloca → 另建类型退化的 @@ -280,6 +289,9 @@ class VarGenMixin: entry.Name = name_copy entry.Alloca = alloca entry.Used = 1 + # const 标记显式置 0(不依赖条目内存的零初值约定):由注解侧 + # set_var_const 在确认为 const 对象时才置 1,显式清零杜绝误报。 + entry.IsConst = 0 # [S3 条目双写] 值类型 Spec(alloca.Ty 是 Ptr(值类型) ⇒ 取其 pointee) entry.Spec = self._spec_of_var_alloca(alloca) return 0 @@ -292,14 +304,14 @@ class VarGenMixin: # SpecFromLLVMType 不支持者)返回 None —— 后者是设计内的「不适用」,非兜底。 # 分配一律 PermPool 驻留 ⇒ 跨文件/跨 1b reset 安全。 # ============================================================ - def _spec_of_var_alloca(self, alloca: rawptr[llvmlite.Value]) -> rawptr[TSpec.TypeSpec]: + def _spec_of_var_alloca(self, alloca: llvmlite.Value*) -> TSpec.TypeSpec*: """由 alloca 的值类型构造 TypeSpec,不适用/失败返回 None""" if alloca is None or alloca.Ty is None: return None - ty: rawptr[llvmlite.LLVMType] = alloca.Ty + ty: llvmlite.LLVMType* = alloca.Ty if self.Gen.ExprGenBase.is_ptr_type(ty) != 0: ty = ty.Pointee - arena: rawptr[TSpec.TypeSpecArena] = self.Gen.TypeGenBase.ensure_spec_arena() + arena: TSpec.TypeSpecArena* = self.Gen.TypeGenBase.ensure_spec_arena() if arena is None: return None return TSpec.SpecFromLLVMType(arena, ty) @@ -307,8 +319,8 @@ class VarGenMixin: # _alloca_at_entry - 在函数入口块生成 alloca(确保支配性) # LLVM IR 要求指令支配所有使用点,故所有 alloca 须在函数入口块生成。 # 实现:临时切换 builder.CurBlock 到入口块,生成 alloca 后恢复。 - def _alloca_at_entry(self, builder: rawptr[llvmlite.IRBuilder], - ty: rawptr[llvmlite.LLVMType]) -> rawptr[llvmlite.Value]: + def _alloca_at_entry(self, builder: llvmlite.IRBuilder*, + ty: llvmlite.LLVMType*) -> llvmlite.Value*: """在函数入口块生成 alloca,返回 alloca 值 使用 llvmlite.build_alloca_at_entry 在入口块终止指令之前插入 alloca, @@ -319,17 +331,17 @@ class VarGenMixin: return llvmlite.build_alloca_at_entry(builder, ty) # get_or_create_var — 查找或创建变量 alloca(旧版兼容) - def get_or_create_var(self, pool: rawptr[memhub.MemBuddy], - builder: rawptr[llvmlite.IRBuilder], - vars_ptr: rawptr[GenTypes.VarEntry], + def get_or_create_var(self, pool: memhub.MemBuddy*, + builder: llvmlite.IRBuilder*, + vars_ptr: GenTypes.VarEntry*, var_count: int, name: str, - ty: rawptr[llvmlite.LLVMType]) -> rawptr[llvmlite.Value]: + ty: llvmlite.LLVMType*) -> llvmlite.Value*: """查找或创建变量 alloca""" - existing: rawptr[llvmlite.Value] = self.find_var(vars_ptr, var_count, name) + existing: llvmlite.Value* = self.find_var(vars_ptr, var_count, name) if existing is not None: return existing - alloca: rawptr[llvmlite.Value] = self._alloca_at_entry(builder, ty) + alloca: 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: @@ -339,7 +351,7 @@ class VarGenMixin: # ============================================================ # _create_scope — 创建新作用域节点(内部辅助函数) # ============================================================ - def _create_scope(self, pool: rawptr[memhub.MemBuddy], + def _create_scope(self, pool: memhub.MemBuddy*, parent: rawptr[GenTypes.Scope], kind: int) -> rawptr[GenTypes.Scope]: """创建并初始化作用域节点""" @@ -358,7 +370,7 @@ class VarGenMixin: # ============================================================ # init_symbol_table — 创建符号表(含模块级根作用域) # ============================================================ - def init_symbol_table(self, pool: rawptr[memhub.MemBuddy]) -> rawptr[GenTypes.SymbolTable]: + def init_symbol_table(self, pool: memhub.MemBuddy*) -> rawptr[GenTypes.SymbolTable]: """创建并初始化符号表,包含模块级根作用域""" if pool is None: return None @@ -385,7 +397,7 @@ class VarGenMixin: """进入新作用域,返回新创建的作用域""" if symtab is None: return None - pool: rawptr[memhub.MemBuddy] = symtab.Pool + pool: memhub.MemBuddy* = symtab.Pool scope: rawptr[GenTypes.Scope] = self._create_scope(pool, symtab.Current, kind) if scope is None: return None @@ -405,7 +417,7 @@ class VarGenMixin: # ============================================================ def define_var(self, symtab: rawptr[GenTypes.SymbolTable], name: str, - alloca: rawptr[llvmlite.Value]) -> int: + alloca: llvmlite.Value*) -> int: """在当前作用域定义变量,返回 0 成功""" if symtab is None or name is None or alloca is None: return 1 @@ -422,7 +434,7 @@ class VarGenMixin: # ============================================================ def define_module_var(self, symtab: rawptr[GenTypes.SymbolTable], name: str, - alloca: rawptr[llvmlite.Value]) -> int: + alloca: llvmlite.Value*) -> int: """在模块作用域定义变量,返回 0 成功""" if symtab is None or name is None or alloca is None: return 1 @@ -438,13 +450,13 @@ class VarGenMixin: # lookup_var — 从当前作用域逐级向上查找变量 # ============================================================ def lookup_var(self, symtab: rawptr[GenTypes.SymbolTable], - name: str) -> rawptr[llvmlite.Value]: + name: str) -> llvmlite.Value*: """从当前作用域逐级向上查找变量,返回 alloca 或 None""" if symtab is None or name is None: return None scope: rawptr[GenTypes.Scope] = symtab.Current while scope is not None: - result: rawptr[llvmlite.Value] = self.find_var( + result: llvmlite.Value* = self.find_var( scope.Vars, scope.VarCount, name) if result is not None: return result @@ -455,7 +467,7 @@ class VarGenMixin: # lookup_current — 仅在当前作用域查找变量 # ============================================================ def lookup_current(self, symtab: rawptr[GenTypes.SymbolTable], - name: str) -> rawptr[llvmlite.Value]: + name: str) -> llvmlite.Value*: """仅在当前作用域查找变量""" if symtab is None or name is None: return None @@ -468,7 +480,7 @@ class VarGenMixin: # lookup_module_var — 在模块作用域查找变量 # ============================================================ def lookup_module_var(self, symtab: rawptr[GenTypes.SymbolTable], - name: str) -> rawptr[llvmlite.Value]: + name: str) -> llvmlite.Value*: """在模块作用域查找变量""" if symtab is None or name is None: return None @@ -499,20 +511,14 @@ class VarGenMixin: return 0 # _lookup_through_match_scope — 穿越 match case 作用域查找变量 - # match case 作用域(SCOPE_MATCH)仅用于"变体字段绑定隔离"(case 绑定的模式 - # 变量互不泄漏);case 体内对"外层普通变量"的赋值语义上应写回外层 alloca, - # 而非新建 case 局部槽——否则外层变量恒为初始值。 - # 遍历规则:逐级向上查找;SCOPE_MATCH 边界可穿越(可命中外层 case 声明的变量), - # 遇到第一个非 match 作用域(函数/模块)后停止——不跨函数边界(闭包 nonlocal - # 语义由 is_nonlocal_name 单独处理)。 def _lookup_through_match_scope(self, symtab: rawptr[GenTypes.SymbolTable], - name: str) -> rawptr[llvmlite.Value]: + name: str) -> llvmlite.Value*: """从当前作用域向上,仅穿越 SCOPE_MATCH 作用域查找变量 alloca""" if symtab is None or name is None: return None scope: rawptr[GenTypes.Scope] = symtab.Current while scope is not None: - result: rawptr[llvmlite.Value] = self.find_var( + result: llvmlite.Value* = self.find_var( scope.Vars, scope.VarCount, name) if result is not None: return result @@ -526,30 +532,23 @@ class VarGenMixin: # get_or_create_sym — 查找或创建变量(在当前作用域) # ============================================================ def get_or_create_sym(self, symtab: rawptr[GenTypes.SymbolTable], - pool: rawptr[memhub.MemBuddy], - builder: rawptr[llvmlite.IRBuilder], + pool: memhub.MemBuddy*, + builder: llvmlite.IRBuilder*, name: str, - ty: rawptr[llvmlite.LLVMType]) -> rawptr[llvmlite.Value]: + ty: llvmlite.LLVMType*) -> llvmlite.Value*: """查找或创建变量 alloca(在当前作用域)""" - existing: rawptr[llvmlite.Value] = self.lookup_current(symtab, name) + existing: llvmlite.Value* = self.lookup_current(symtab, name) if existing is not None: return existing - # SCOPE_MATCH 隔离作用域对"赋值"必须透明(详见 _lookup_through_match_scope): - # case 体内对外层变量的赋值要写回外层 alloca。仅穿越 match 边界, - # 不跨函数/模块作用域(global/nonlocal 在 AssignGenMixin 提前拦截)。 + # SCOPE_MATCH 隔离作用域对"赋值"必须透明: existing = self._lookup_through_match_scope(symtab, name) if existing is not None: return existing - alloca: rawptr[llvmlite.Value] = self._alloca_at_entry(builder, ty) + alloca: llvmlite.Value* = self._alloca_at_entry(builder, ty) if alloca is None: return None if self.define_var(symtab, name, alloca) != 0: - # fail-fast: 变量注册失败(如超过 MAX_VARS)必须立即终止。 - # 静默忽略返回值会使 alloca 已建但未入符号表,后续读取报"未定义名称"。 - self.Gen.TypeGenErr.fatal_error( - None, - f"变量 '{name}' 注册失败(作用域变量数超过上限 MAX_VARS)", - "InternalCompilerError") + self.Gen.TypeGenErr.fatal_error(None, f"变量 '{name}' 注册失败(作用域变量数超过上限 MAX_VARS)", "InternalCompilerError") return alloca # ============================================================ @@ -563,10 +562,8 @@ class VarGenMixin: # 槽内存放的是**值本身**(标量/指针/≤16B 结构体值内联)⇒ 宿主不需要知道类型, # 且槽地址即值地址(c.Addr 的地址同一性)。 # ============================================================ - # ---- repl_find_entry — 会话表按名查找 ---- - def repl_find_entry(self, ctx: rawptr[GenTypes.ReplCtx], - name: str) -> rawptr[GenTypes.ReplVarEntry]: + def repl_find_entry(self, ctx: rawptr[GenTypes.ReplCtx], name: str) -> rawptr[GenTypes.ReplVarEntry]: """在会话表中按名查找条目;ctx 无效或未登记返回 None""" if ctx is None or name is None: return None @@ -603,15 +600,15 @@ class VarGenMixin: return 0 # ---- repl_ctx_ptr — 取片段函数 ctx 形参的值(i8*) ---- - def repl_ctx_ptr(self, trans: rawptr[HT.Translator], + def repl_ctx_ptr(self, trans: HT.Translator*, ctx: rawptr[GenTypes.ReplCtx], - node: rawptr[ast.AST]) -> rawptr[llvmlite.Value]: + node: ast.AST*) -> llvmlite.Value*: """load 片段函数 ctx 形参(形参 alloca 由 FuncGenDef 建);失败 fail-fast""" if trans is None or ctx is None or ctx.CtxParam is None: return None symtab: rawptr[GenTypes.SymbolTable] = trans.SymTab - param_alloca: rawptr[llvmlite.Value] = self.lookup_var(symtab, ctx.CtxParam) - if param_alloca is None or param_alloca.Ty is None or param_alloca.Ty.Pointee is None: + param_alloca: llvmlite.Value* = self.lookup_var(symtab, ctx.CtxParam) + if param_alloca is None or param_alloca.Ty is None or param_alloca.Ty.Pointee == 0: self.Gen.TypeGenErr.fatal_error( node, f"REPL: 片段函数缺少 ctx 形参 '{ctx.CtxParam}'(包裹模板与 M2 调用约定不一致)", @@ -619,246 +616,246 @@ class VarGenMixin: return None return llvmlite.build_load(trans._cur_builder, param_alloca.Ty.Pointee, param_alloca) - # ---- repl_in_frag_entry_scope — 当前最近函数作用域是否就是**片段入口**函数 ---- - # - # 与 repl_in_frag_scope 的差别(M3 引入):被提升的会话函数(片段里顶层 def 提升 - # 到模块级的 export def)在作用域上同样是"父为模块根的函数作用域",故 - # repl_in_frag_scope 对其返回 1;但它**不是**片段入口函数。 - # - 读路径(会话变量取值/取址/会话函数调用):两者都允许 ⇒ 用 repl_in_frag_scope - # (会话函数体里能读到会话变量,这是 M3 的核心能力); - # - 写路径(会话槽位分配/赋值/增强赋值/注解赋值):只允许片段入口函数 ⇒ 用本 - # 谓词。理由(正确性,不是风格): - # ① 会话函数体里的 `y = 1` 应是**局部**变量(Python 语义),若走会话槽 - # 会把局部名泄漏成全局、并使递归/重入共享同一槽; - # ② 形参同名遮蔽最危险:`x = 1` 建立会话变量 x 后,`def f(x: int): x = x + 1` - # 若走会话槽会把实参写进**会话变量 x**(静默数据串味); - # ③ 片段入口函数是唯一"用户一整行/一整块"的语义载体 ⇒ 与 M2 行为一致。 - # 判定:片段入口函数名由宿主生成,恒以 GenTypes.REPL_ENTRY_PREFIX 开头 - # (Repl.vp 的 "__repl_frag_%d")。非 REPL 路径 _cur_func 无该前缀 ⇒ 恒 0。 - def repl_in_frag_entry_scope(self, trans: rawptr[HT.Translator]) -> int: - """1=当前正在翻译片段入口函数本体;0=其他(含被提升的会话函数本体)""" - if trans is None or trans._cur_func is None: - return 0 - if self.repl_in_frag_scope(trans.SymTab) == 0: - return 0 - cur_nm: str = llvmlite.function_get_name(trans._cur_func) - if cur_nm is None: - return 0 - pfx: str = GenTypes.REPL_ENTRY_PREFIX - pl: sizet = string.strlen(pfx) - if string.strncmp(cur_nm, pfx, pl) != 0: - return 0 - return 1 - - # ---- repl_find_func_entry — 会话函数表按名查找(M3) ---- - def repl_find_func_entry(self, ctx: rawptr[GenTypes.ReplCtx], - name: str) -> rawptr[GenTypes.ReplFuncEntry]: - """在会话函数表中按名查找;ctx 无效/未登记返回 None(只读,不改表)""" - if ctx is None or name is None: - return None - if ctx.Marker != GenTypes.REPL_CTX_MARKER: - return None - if ctx.FuncTable is None or ctx.FuncCount <= 0: - return None - entry_size: sizet = GenTypes.ReplFuncEntry.__sizeof__() - for i in range(ctx.FuncCount): - entry_addr: uint64 = uint64(ctx.FuncTable) + i * entry_size - entry: rawptr[GenTypes.ReplFuncEntry] = rawptr[GenTypes.ReplFuncEntry](entry_addr) - if entry.Name is not None and string.strcmp(entry.Name, name) == 0: - return entry - return None - - # ---- repl_func_ty — 签名 token → LLVM 类型(M3) ---- - # - # token 由宿主在注册期从定义片段的 IR define 行解析而来(唯一 ABI 真相), - # 只允许可往返重建的集合:iN(N=1/8/16/32/64) / float / double / i8*。 - # 其余 token(含 REPL_TY_PTR / REPL_TY_STRUCT)返回 None ⇒ 调用点明确报错。 - def repl_func_ty(self, pool: rawptr[memhub.MemBuddy], - tag: int, bits: int) -> rawptr[llvmlite.LLVMType]: - """签名 token → LLVM 类型;不支持的 token 返回 None""" - if pool is None: - return None - if tag == GenTypes.REPL_TY_INT: - return self.repl_scalar_ty(pool, bits, 0) - if tag == GenTypes.REPL_TY_FLOAT: - return self.repl_scalar_ty(pool, bits, 1) - if tag == GenTypes.REPL_TY_STR: - return llvmlite.Ptr(pool, llvmlite.Int8(pool)) - return None - - # ---- repl_func_sig_label — 签名 token → 人类可读类型名(错误消息用) ---- - def repl_func_sig_label(self, tag: int, bits: int) -> str: - """签名 token → 显示名;未识别返回 "?"(VOID 显示为 void)""" - if tag == GenTypes.REPL_TY_VOID: - return "void" - return self.repl_tag_label(tag, bits) - - # ---- repl_try_session_func_call — 会话函数间接调用(M3 核心) ---- - # - # 命中(名字在会话函数表且当前在片段函数作用域内)时: - # ① 从 ctx 的函数指针槽(ctx + SlotOff,i8**)load 出函数地址(i8*); - # ② 首实参恒为本片段的 ctx(i8*)——被提升的会话函数首形参即 ctx, - # 其体内经该指针读写会话变量槽(与片段入口函数同一套寻址); - # ③ 其余实参与定义端签名逐个对齐(translate_value 带 target_ty + coerce_to_type); - # ④ 按表内签名(ret + (i8*, P1..Pn))bitcast 后 build_call_indirect。 - # 语义要点:函数**代码**只在定义片段的 DLL 里存在一份,调用点不复制/不重编译; - # 表内签名即定义端 ABI(宿主从 define 行解析)⇒ 调用点签名与定义端恒一致。 - # - # hit 是宿主调用方提供的 int 盒子(stdlib.malloc(4) 风格,与 translate_call 里 - # h1_hit 同款):命中后(含命中但报错)置 1,使调用方"已处理"而不是继续走 - # "裸名调用未定义且未导入"的 fail-fast 或搭上别的解析路径。 - # 守卫:调用方只在 trans.ReplCtx is not None 时调用;非 REPL 恒不进入。 - def repl_try_session_func_call(self, trans: rawptr[HT.Translator], - pool: rawptr[memhub.MemBuddy], - builder: rawptr[llvmlite.IRBuilder], - mod: rawptr[llvmlite.LLVMModule], - func_name: str, - cargs: list[ast.AST*]*, - can: int, - kw_count: int, - node: rawptr[ast.AST], - hit: t.CPtr) -> rawptr[llvmlite.Value]: - """会话函数调用:命中返回 call 结果(void 函数返回 None 但 hit 已置 1)""" - if trans is None or trans.ReplCtx is None or pool is None or builder is None: - return None - if func_name is None or hit is None: - return None - ctx: rawptr[GenTypes.ReplCtx] = trans.ReplCtx - entry: rawptr[GenTypes.ReplFuncEntry] = self.repl_find_func_entry(ctx, func_name) - if entry is None: - return None - # 本判定与 M2 的读路径同口径:片段入口函数**或被提升的会话函数**体内允许 - # 调用别的会话函数;片段内的嵌套闭包体(无 ctx 形参)不允许 ⇒ 返回未命中, - # 由既有路径给出明确报错(不生成非法 IR)。 - if self.repl_in_frag_scope(trans.SymTab) == 0: - return None - hit[0] = 1 - if kw_count != 0: - self.Gen.TypeGenErr.fatal_error( - node, - f"REPL: 会话函数 '{func_name}' 不支持关键字实参(M3 仅支持位置实参)", - "TypeError") - return None - if can != entry.ParamCount: - self.Gen.TypeGenErr.fatal_error( - node, - f"REPL: 会话函数 '{func_name}' 期待 {entry.ParamCount} 个位置实参," - f"调用处给了 {can} 个(M3 不支持默认参数/缺省补全)", - "TypeError") - return None - ctx_val: rawptr[llvmlite.Value] = self.repl_ctx_ptr(trans, ctx, node) - if ctx_val is None: - return None - i8_ty: rawptr[llvmlite.LLVMType] = llvmlite.Int8(pool) - i8_ptr_ty: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, i8_ty) - # ① 槽内取函数地址:槽地址是 i8**(Ptr(i8*)),load 得 i8* - slot: rawptr[llvmlite.Value] = self.repl_slot_ptr( - pool, builder, ctx_val, entry.SlotOff, i8_ptr_ty) - if slot is None: - self.Gen.TypeGenErr.fatal_error( - node, "REPL: 会话函数指针槽地址生成失败", "InternalCompilerError") - return None - fn_i8: rawptr[llvmlite.Value] = llvmlite.build_load(builder, i8_ptr_ty, slot) - if fn_i8 is None: - self.Gen.TypeGenErr.fatal_error( - node, f"REPL: 会话函数 '{func_name}' 的地址读取失败", "InternalCompilerError") - return None - # ② 签名构造前先取形参类型(token → LLVM 类型;不支持 ⇒ 明确报错) - ptypes: t.CPtr = pool.alloc(8 * GenTypes.REPL_FUNC_PARAM_MAX) - if ptypes is None: - return None - string.memset(ptypes, 0, 8 * GenTypes.REPL_FUNC_PARAM_MAX) - ai_chk: int - for ai_chk in range(entry.ParamCount): - pty_chk: rawptr[llvmlite.LLVMType] = self.repl_func_ty( - pool, int(entry.ParamTags[ai_chk]), int(entry.ParamBits[ai_chk])) - if pty_chk is None: - self.Gen.TypeGenErr.fatal_error( - node, - f"REPL: 会话函数 '{func_name}' 第 {ai_chk + 1} 个形参的类型 token " - f"不受支持(M3 支持 iN/float/double/i8*)", - "TypeError") - return None - pty_slot: str | t.CPtr = (t.CPtr)(uint64(ptypes) + ai_chk * 8) - pty_slot[0] = pty_chk - # ③ 实参:首实参 = 本片段 ctx,其后按签名类型逐个翻译并 coerce - head: rawptr[llvmlite.Value] = ctx_val - head.Next = None - tail: rawptr[llvmlite.Value] = head - arg_count: int = 1 - ai: int - for ai in range(entry.ParamCount): - arg: rawptr[ast.AST] = cargs.get(ai) - if arg is None: - self.Gen.TypeGenErr.fatal_error( - node, f"REPL: 会话函数 '{func_name}' 的第 {ai + 1} 个实参缺失", - "SyntaxError") - return None - pty_slot2: str | t.CPtr = (t.CPtr)(uint64(ptypes) + ai * 8) - pty: rawptr[llvmlite.LLVMType] = (rawptr[llvmlite.LLVMType])(pty_slot2[0]) - arg_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( - builder, pool, mod, arg, None, 0, trans, pty) - if arg_val is None: - self.Gen.TypeGenErr.fatal_error( - node, f"REPL: 会话函数 '{func_name}' 的第 {ai + 1} 个实参翻译失败", - "TypeError") - return None - coerced: rawptr[llvmlite.Value] = self.Gen.ExprGenBase.coerce_to_type( - builder, arg_val, pty, arg, trans) - if coerced is None: - self.Gen.TypeGenErr.fatal_error( - node, - f"REPL: 会话函数 '{func_name}' 的第 {ai + 1} 个实参与签名类型不兼容", - "TypeError") - return None - coerced.Next = None - tail.Next = coerced - tail = coerced - arg_count += 1 - # ④ 函数类型:ret + (i8*, P1..Pn)(ret=void 时用 llvmlite.Void, - # build_call_indirect 返回 None ⇒ 宿主调用方按"void 调用"处理) - ret_ty: rawptr[llvmlite.LLVMType] = llvmlite.Void(pool) - if entry.RetTag != GenTypes.REPL_TY_VOID: - ret_ty = self.repl_func_ty(pool, entry.RetTag, entry.RetBits) - if ret_ty is None: - self.Gen.TypeGenErr.fatal_error( - node, - f"REPL: 会话函数 '{func_name}' 的返回类型 token 不受支持" - f"(M3 支持 void/iN/float/double/i8*)", - "TypeError") - return None - fp_first: rawptr[llvmlite.Function] = None - fp_prev: rawptr[llvmlite.Function] = None - pi: int - for pi in range(arg_count): - cur_ty: rawptr[llvmlite.LLVMType] = i8_ptr_ty - if pi > 0: - pty_slot3: str | t.CPtr = (t.CPtr)(uint64(ptypes) + (pi - 1) * 8) - cur_ty = (rawptr[llvmlite.LLVMType])(pty_slot3[0]) - pn: rawptr[llvmlite.Function] = llvmlite.new_param_node(pool, cur_ty) - if pn is not None: - if fp_first is None: - fp_first = pn - if fp_prev is not None: - llvmlite.paramnode_set_next(fp_prev, pn) - fp_prev = pn - func_ty: rawptr[llvmlite.LLVMType] = llvmlite.Func(pool, ret_ty, fp_first, arg_count) - if func_ty is None: - return None - func_ptr_ty: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, func_ty) - fn_typed: rawptr[llvmlite.Value] = llvmlite.build_bitcast(builder, fn_i8, func_ptr_ty) - if fn_typed is None: - self.Gen.TypeGenErr.fatal_error( - node, f"REPL: 会话函数 '{func_name}' 的地址转换失败", "InternalCompilerError") - return None - return llvmlite.build_call_indirect(builder, fn_typed, head, arg_count, ret_ty) - + # ---- repl_in_frag_entry_scope — 当前最近函数作用域是否就是**片段入口**函数 ---- + # + # 与 repl_in_frag_scope 的差别(M3 引入):被提升的会话函数(片段里顶层 def 提升 + # 到模块级的 export def)在作用域上同样是"父为模块根的函数作用域",故 + # repl_in_frag_scope 对其返回 1;但它**不是**片段入口函数。 + # - 读路径(会话变量取值/取址/会话函数调用):两者都允许 ⇒ 用 repl_in_frag_scope + # (会话函数体里能读到会话变量,这是 M3 的核心能力); + # - 写路径(会话槽位分配/赋值/增强赋值/注解赋值):只允许片段入口函数 ⇒ 用本 + # 谓词。理由(正确性,不是风格): + # ① 会话函数体里的 `y = 1` 应是**局部**变量(Python 语义),若走会话槽 + # 会把局部名泄漏成全局、并使递归/重入共享同一槽; + # ② 形参同名遮蔽最危险:`x = 1` 建立会话变量 x 后,`def f(x: int): x = x + 1` + # 若走会话槽会把实参写进**会话变量 x**(静默数据串味); + # ③ 片段入口函数是唯一"用户一整行/一整块"的语义载体 ⇒ 与 M2 行为一致。 + # 判定:片段入口函数名由宿主生成,恒以 GenTypes.REPL_ENTRY_PREFIX 开头 + # (Repl.vp 的 "__repl_frag_%d")。非 REPL 路径 _cur_func 无该前缀 ⇒ 恒 0。 + def repl_in_frag_entry_scope(self, trans: HT.Translator*) -> int: + """1=当前正在翻译片段入口函数本体;0=其他(含被提升的会话函数本体)""" + if trans is None or trans._cur_func is None: + return 0 + if self.repl_in_frag_scope(trans.SymTab) == 0: + return 0 + cur_nm: str = llvmlite.function_get_name(trans._cur_func) + if cur_nm is None: + return 0 + pfx: str = GenTypes.REPL_ENTRY_PREFIX + pl: sizet = string.strlen(pfx) + if string.strncmp(cur_nm, pfx, pl) != 0: + return 0 + return 1 + + # ---- repl_find_func_entry — 会话函数表按名查找(M3) ---- + def repl_find_func_entry(self, ctx: rawptr[GenTypes.ReplCtx], + name: str) -> rawptr[GenTypes.ReplFuncEntry]: + """在会话函数表中按名查找;ctx 无效/未登记返回 None(只读,不改表)""" + if ctx is None or name is None: + return None + if ctx.Marker != GenTypes.REPL_CTX_MARKER: + return None + if ctx.FuncTable is None or ctx.FuncCount <= 0: + return None + entry_size: sizet = GenTypes.ReplFuncEntry.__sizeof__() + for i in range(ctx.FuncCount): + entry_addr: uint64 = uint64(ctx.FuncTable) + i * entry_size + entry: rawptr[GenTypes.ReplFuncEntry] = rawptr[GenTypes.ReplFuncEntry](entry_addr) + if entry.Name is not None and string.strcmp(entry.Name, name) == 0: + return entry + return None + + # ---- repl_func_ty — 签名 token → LLVM 类型(M3) ---- + # + # token 由宿主在注册期从定义片段的 IR define 行解析而来(唯一 ABI 真相), + # 只允许可往返重建的集合:iN(N=1/8/16/32/64) / float / double / i8*。 + # 其余 token(含 REPL_TY_PTR / REPL_TY_STRUCT)返回 None ⇒ 调用点明确报错。 + def repl_func_ty(self, pool: memhub.MemBuddy*, + tag: int, bits: int) -> llvmlite.LLVMType*: + """签名 token → LLVM 类型;不支持的 token 返回 None""" + if pool is None: + return None + if tag == GenTypes.REPL_TY_INT: + return self.repl_scalar_ty(pool, bits, 0) + if tag == GenTypes.REPL_TY_FLOAT: + return self.repl_scalar_ty(pool, bits, 1) + if tag == GenTypes.REPL_TY_STR: + return llvmlite.Ptr(pool, llvmlite.Int8(pool)) + return None + + # ---- repl_func_sig_label — 签名 token → 人类可读类型名(错误消息用) ---- + def repl_func_sig_label(self, tag: int, bits: int) -> str: + """签名 token → 显示名;未识别返回 "?"(VOID 显示为 void)""" + if tag == GenTypes.REPL_TY_VOID: + return "void" + return self.repl_tag_label(tag, bits) + + # ---- repl_try_session_func_call — 会话函数间接调用(M3 核心) ---- + # + # 命中(名字在会话函数表且当前在片段函数作用域内)时: + # ① 从 ctx 的函数指针槽(ctx + SlotOff,i8**)load 出函数地址(i8*); + # ② 首实参恒为本片段的 ctx(i8*)——被提升的会话函数首形参即 ctx, + # 其体内经该指针读写会话变量槽(与片段入口函数同一套寻址); + # ③ 其余实参与定义端签名逐个对齐(translate_value 带 target_ty + coerce_to_type); + # ④ 按表内签名(ret + (i8*, P1..Pn))bitcast 后 build_call_indirect。 + # 语义要点:函数**代码**只在定义片段的 DLL 里存在一份,调用点不复制/不重编译; + # 表内签名即定义端 ABI(宿主从 define 行解析)⇒ 调用点签名与定义端恒一致。 + # + # hit 是宿主调用方提供的 int 盒子(stdlib.malloc(4) 风格,与 translate_call 里 + # h1_hit 同款):命中后(含命中但报错)置 1,使调用方"已处理"而不是继续走 + # "裸名调用未定义且未导入"的 fail-fast 或搭上别的解析路径。 + # 守卫:调用方只在 trans.ReplCtx is not None 时调用;非 REPL 恒不进入。 + def repl_try_session_func_call(self, trans: HT.Translator*, + pool: memhub.MemBuddy*, + builder: llvmlite.IRBuilder*, + mod: llvmlite.LLVMModule*, + func_name: str, + cargs: list[ast.AST*]*, + can: int, + kw_count: int, + node: ast.AST*, + hit: t.CPtr) -> llvmlite.Value*: + """会话函数调用:命中返回 call 结果(void 函数返回 None 但 hit 已置 1)""" + if trans is None or trans.ReplCtx is None or pool is None or builder is None: + return None + if func_name is None or hit is None: + return None + ctx: rawptr[GenTypes.ReplCtx] = trans.ReplCtx + entry: rawptr[GenTypes.ReplFuncEntry] = self.repl_find_func_entry(ctx, func_name) + if entry is None: + return None + # 本判定与 M2 的读路径同口径:片段入口函数**或被提升的会话函数**体内允许 + # 调用别的会话函数;片段内的嵌套闭包体(无 ctx 形参)不允许 ⇒ 返回未命中, + # 由既有路径给出明确报错(不生成非法 IR)。 + if self.repl_in_frag_scope(trans.SymTab) == 0: + return None + hit[0] = 1 + if kw_count != 0: + self.Gen.TypeGenErr.fatal_error( + node, + f"REPL: 会话函数 '{func_name}' 不支持关键字实参(M3 仅支持位置实参)", + "TypeError") + return None + if can != entry.ParamCount: + self.Gen.TypeGenErr.fatal_error( + node, + f"REPL: 会话函数 '{func_name}' 期待 {entry.ParamCount} 个位置实参," + f"调用处给了 {can} 个(M3 不支持默认参数/缺省补全)", + "TypeError") + return None + ctx_val: llvmlite.Value* = self.repl_ctx_ptr(trans, ctx, node) + if ctx_val is None: + return None + i8_ty: llvmlite.LLVMType* = llvmlite.Int8(pool) + i8_ptr_ty: llvmlite.LLVMType* = llvmlite.Ptr(pool, i8_ty) + # ① 槽内取函数地址:槽地址是 i8**(Ptr(i8*)),load 得 i8* + slot: llvmlite.Value* = self.repl_slot_ptr( + pool, builder, ctx_val, entry.SlotOff, i8_ptr_ty) + if slot is None: + self.Gen.TypeGenErr.fatal_error( + node, "REPL: 会话函数指针槽地址生成失败", "InternalCompilerError") + return None + fn_i8: llvmlite.Value* = llvmlite.build_load(builder, i8_ptr_ty, slot) + if fn_i8 is None: + self.Gen.TypeGenErr.fatal_error( + node, f"REPL: 会话函数 '{func_name}' 的地址读取失败", "InternalCompilerError") + return None + # ② 签名构造前先取形参类型(token → LLVM 类型;不支持 ⇒ 明确报错) + ptypes: t.CPtr = pool.alloc(8 * GenTypes.REPL_FUNC_PARAM_MAX) + if ptypes is None: + return None + string.memset(ptypes, 0, 8 * GenTypes.REPL_FUNC_PARAM_MAX) + ai_chk: int + for ai_chk in range(entry.ParamCount): + pty_chk: llvmlite.LLVMType* = self.repl_func_ty( + pool, int(entry.ParamTags[ai_chk]), int(entry.ParamBits[ai_chk])) + if pty_chk is None: + self.Gen.TypeGenErr.fatal_error( + node, + f"REPL: 会话函数 '{func_name}' 第 {ai_chk + 1} 个形参的类型 token " + f"不受支持(M3 支持 iN/float/double/i8*)", + "TypeError") + return None + pty_slot: str | t.CPtr = (t.CPtr)(uint64(ptypes) + ai_chk * 8) + pty_slot[0] = pty_chk + # ③ 实参:首实参 = 本片段 ctx,其后按签名类型逐个翻译并 coerce + head: llvmlite.Value* = ctx_val + head.Next = None + tail: llvmlite.Value* = head + arg_count: int = 1 + ai: int + for ai in range(entry.ParamCount): + arg: ast.AST* = cargs.get(ai) + if arg is None: + self.Gen.TypeGenErr.fatal_error( + node, f"REPL: 会话函数 '{func_name}' 的第 {ai + 1} 个实参缺失", + "SyntaxError") + return None + pty_slot2: str | t.CPtr = (t.CPtr)(uint64(ptypes) + ai * 8) + pty: llvmlite.LLVMType* = (llvmlite.LLVMType*)(pty_slot2[0]) + arg_val: llvmlite.Value* = self.Gen.ExprGen.translate_value( + builder, pool, mod, arg, None, 0, trans, pty) + if arg_val is None: + self.Gen.TypeGenErr.fatal_error( + node, f"REPL: 会话函数 '{func_name}' 的第 {ai + 1} 个实参翻译失败", + "TypeError") + return None + coerced: llvmlite.Value* = self.Gen.ExprGenBase.coerce_to_type( + builder, arg_val, pty, arg, trans) + if coerced is None: + self.Gen.TypeGenErr.fatal_error( + node, + f"REPL: 会话函数 '{func_name}' 的第 {ai + 1} 个实参与签名类型不兼容", + "TypeError") + return None + coerced.Next = None + tail.Next = coerced + tail = coerced + arg_count += 1 + # ④ 函数类型:ret + (i8*, P1..Pn)(ret=void 时用 llvmlite.Void, + # build_call_indirect 返回 None ⇒ 宿主调用方按"void 调用"处理) + ret_ty: llvmlite.LLVMType* = llvmlite.Void(pool) + if entry.RetTag != GenTypes.REPL_TY_VOID: + ret_ty = self.repl_func_ty(pool, entry.RetTag, entry.RetBits) + if ret_ty is None: + self.Gen.TypeGenErr.fatal_error( + node, + f"REPL: 会话函数 '{func_name}' 的返回类型 token 不受支持" + f"(M3 支持 void/iN/float/double/i8*)", + "TypeError") + return None + fp_first: llvmlite.Function* = None + fp_prev: llvmlite.Function* = None + pi: int + for pi in range(arg_count): + cur_ty: llvmlite.LLVMType* = i8_ptr_ty + if pi > 0: + pty_slot3: str | t.CPtr = (t.CPtr)(uint64(ptypes) + (pi - 1) * 8) + cur_ty = (llvmlite.LLVMType*)(pty_slot3[0]) + pn: llvmlite.Function* = llvmlite.new_param_node(pool, cur_ty) + if pn is not None: + if fp_first is None: + fp_first = pn + if fp_prev is not None: + llvmlite.paramnode_set_next(fp_prev, pn) + fp_prev = pn + func_ty: llvmlite.LLVMType* = llvmlite.Func(pool, ret_ty, fp_first, arg_count) + if func_ty is None: + return None + func_ptr_ty: llvmlite.LLVMType* = llvmlite.Ptr(pool, func_ty) + fn_typed: llvmlite.Value* = llvmlite.build_bitcast(builder, fn_i8, func_ptr_ty) + if fn_typed is None: + self.Gen.TypeGenErr.fatal_error( + node, f"REPL: 会话函数 '{func_name}' 的地址转换失败", "InternalCompilerError") + return None + return llvmlite.build_call_indirect(builder, fn_typed, head, arg_count, ret_ty) + # ---- repl_slot_ptr — 槽地址(ctx + off 的字节 GEP 后 bitcast 成 Ptr(val_ty)) ---- - def repl_slot_ptr(self, pool: rawptr[memhub.MemBuddy], - builder: rawptr[llvmlite.IRBuilder], - ctx_val: rawptr[llvmlite.Value], + def repl_slot_ptr(self, pool: memhub.MemBuddy*, + builder: llvmlite.IRBuilder*, + ctx_val: llvmlite.Value*, off: int, - val_ty: rawptr[llvmlite.LLVMType]) -> rawptr[llvmlite.Value]: + val_ty: llvmlite.LLVMType*) -> llvmlite.Value*: """返回槽指针(Ptr(val_ty));参数不完整返回 None 用 i8 步长 GEP 做纯字节偏移(同 list_getitem_inline 的既有做法), @@ -866,12 +863,12 @@ class VarGenMixin: """ if pool is None or builder is None or ctx_val is None or val_ty is None: return None - i8_ty: rawptr[llvmlite.LLVMType] = llvmlite.Int8(pool) - target_ptr_ty: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, val_ty) - off_val: rawptr[llvmlite.Value] = llvmlite.const_int64(pool, t.CInt64T(off)) + i8_ty: llvmlite.LLVMType* = llvmlite.Int8(pool) + target_ptr_ty: llvmlite.LLVMType* = llvmlite.Ptr(pool, val_ty) + off_val: llvmlite.Value* = llvmlite.const_int64(pool, t.CInt64T(off)) if off_val is None: return None - base: rawptr[llvmlite.Value] = llvmlite.build_gep(builder, i8_ty, ctx_val, off_val) + base: llvmlite.Value* = llvmlite.build_gep(builder, i8_ty, ctx_val, off_val) if base is None: return None # 同型时不发 bitcast:llvmlite 类型非 canonical(同类型不同实例地址不同), @@ -883,8 +880,8 @@ class VarGenMixin: return llvmlite.build_bitcast(builder, base, target_ptr_ty) # ---- repl_scalar_ty — 位宽 → LLVM 标量类型 ---- - def repl_scalar_ty(self, pool: rawptr[memhub.MemBuddy], - bits: int, is_float: int) -> rawptr[llvmlite.LLVMType]: + def repl_scalar_ty(self, pool: memhub.MemBuddy*, + bits: int, is_float: int) -> llvmlite.LLVMType*: """按位宽还原 LLVM 标量类型;不支持的位宽返回 None""" if is_float != 0: if bits == 32: @@ -905,8 +902,8 @@ class VarGenMixin: return None # ---- repl_llvm_ty — 条目 → LLVM 值类型(结构体按名重解析) ---- - def repl_llvm_ty(self, pool: rawptr[memhub.MemBuddy], - entry: rawptr[GenTypes.ReplVarEntry]) -> rawptr[llvmlite.LLVMType]: + def repl_llvm_ty(self, pool: memhub.MemBuddy*, + entry: rawptr[GenTypes.ReplVarEntry]) -> llvmlite.LLVMType*: """条目反推 LLVM 值类型;未定型/结构体类型不可解析返回 None TyTag=STRUCT 时返回结构体**值**类型(内联存槽,槽类型即它本身)。 @@ -926,11 +923,11 @@ class VarGenMixin: return llvmlite.Ptr(pool, llvmlite.Int8(pool)) if entry.TyTag == GenTypes.REPL_TY_PTR: if entry.TyName is not None: - st: rawptr[llvmlite.LLVMType] = self.Gen.StructGen.get_struct_type(entry.TyName) + st: llvmlite.LLVMType* = self.Gen.StructGen.get_struct_type(entry.TyName) if st is None: return None return llvmlite.Ptr(pool, st) - ptee: rawptr[llvmlite.LLVMType] = self.repl_scalar_ty(pool, entry.Bits, 0) + ptee: llvmlite.LLVMType* = self.repl_scalar_ty(pool, entry.Bits, 0) if ptee is None: ptee = llvmlite.Int8(pool) return llvmlite.Ptr(pool, ptee) @@ -941,8 +938,8 @@ class VarGenMixin: return None # ---- repl_slot_ty — 槽内存放的值类型 ---- - def repl_slot_ty(self, pool: rawptr[memhub.MemBuddy], - entry: rawptr[GenTypes.ReplVarEntry]) -> rawptr[llvmlite.LLVMType]: + def repl_slot_ty(self, pool: memhub.MemBuddy*, + entry: rawptr[GenTypes.ReplVarEntry]) -> llvmlite.LLVMType*: """槽内存放的值类型 = 条目的值类型本身(标量/指针/结构体值都内联在槽里) 结构体值另有体积约束:尺寸 > REPL_SLOT_SIZE 或对齐 > REPL_SLOT_SIZE 时 @@ -950,7 +947,7 @@ class VarGenMixin: """ if entry is None or pool is None: return None - vt: rawptr[llvmlite.LLVMType] = self.repl_llvm_ty(pool, entry) + vt: llvmlite.LLVMType* = self.repl_llvm_ty(pool, entry) if vt is None: return None if entry.TyTag == GenTypes.REPL_TY_STRUCT: @@ -962,7 +959,7 @@ class VarGenMixin: return vt # ---- repl_type_align / repl_type_size — 结构体值的尺寸/对齐(LLVM 标准布局) ---- - def repl_type_align(self, ty: rawptr[llvmlite.LLVMType], depth: int = 0) -> int: + def repl_type_align(self, ty: llvmlite.LLVMType*, depth: int = 0) -> int: """类型自然对齐字节;未知类型返回 0(deep=守卫递归深度)""" if ty is None or depth > 64: return 0 @@ -984,7 +981,7 @@ class VarGenMixin: return 8 if self.Gen.ExprGenBase.is_ptr_type(ty) != 0: return 8 - elem_ty: rawptr[llvmlite.LLVMType] = None + elem_ty: llvmlite.LLVMType* = None match ty: case llvmlite.LLVMType.Array(elem_a, _cnt_a): elem_ty = elem_a @@ -998,7 +995,7 @@ class VarGenMixin: cur: rawptr[llvmlite.ParamNode] = fields best: int = 1 while cur is not None: - fty: rawptr[llvmlite.LLVMType] = llvmlite.paramnode_get_ty(cur) + fty: llvmlite.LLVMType* = llvmlite.paramnode_get_ty(cur) fa: int = self.repl_type_align(fty, depth + 1) if fa <= 0: return 0 @@ -1007,7 +1004,7 @@ class VarGenMixin: cur = llvmlite.paramnode_get_next(cur) return best - def repl_type_size(self, ty: rawptr[llvmlite.LLVMType], depth: int = 0) -> int: + def repl_type_size(self, ty: llvmlite.LLVMType*, depth: int = 0) -> int: """类型字节尺寸(LLVM 标准布局:字段按自然对齐排布 + 尾填充);未知返回 0 用于结构体值的"能否放入槽"判定(标量/指针见 repl_scalar_ty)。 @@ -1022,7 +1019,7 @@ class VarGenMixin: return fb // 8 if self.Gen.ExprGenBase.is_ptr_type(ty) != 0: return 8 - elem_ty: rawptr[llvmlite.LLVMType] = None + elem_ty: llvmlite.LLVMType* = None cnt: int = 0 match ty: case llvmlite.LLVMType.Array(elem_s, cnt_s): @@ -1045,7 +1042,7 @@ class VarGenMixin: off: int = 0 counted: int = 0 while cur is not None: - fty2: rawptr[llvmlite.LLVMType] = llvmlite.paramnode_get_ty(cur) + fty2: llvmlite.LLVMType* = llvmlite.paramnode_get_ty(cur) fsz: int = self.repl_type_size(fty2, depth + 1) fa2: int = self.repl_type_align(fty2, depth + 1) if fsz <= 0 or fa2 <= 0: @@ -1064,10 +1061,10 @@ class VarGenMixin: return off # ---- repl_seal — 首次定型(已定型则校验类型标签一致) ---- - def repl_seal(self, trans: rawptr[HT.Translator], + def repl_seal(self, trans: HT.Translator*, entry: rawptr[GenTypes.ReplVarEntry], - val_ty: rawptr[llvmlite.LLVMType], - node: rawptr[ast.AST]) -> int: + val_ty: llvmlite.LLVMType*, + node: ast.AST*) -> int: """按 val_ty 给条目定型;返回 0=成功(含幂等命中)/ 1=不支持或冲突(已 fail-fast) 规则: @@ -1077,7 +1074,7 @@ class VarGenMixin: """ if trans is None or entry is None or val_ty is None: return 1 - perm: rawptr[memhub.MemBuddy] = self.repl_perm_pool(trans) + perm: memhub.MemBuddy* = self.repl_perm_pool(trans) if perm is None: self.Gen.TypeGenErr.fatal_error( node, "REPL: 会话永久池不可用(宿主未注入)", "InternalCompilerError") @@ -1095,7 +1092,7 @@ class VarGenMixin: tag = GenTypes.REPL_TY_FLOAT bits = fb elif self.Gen.ExprGenBase.is_ptr_type(val_ty) != 0: - ptee: rawptr[llvmlite.LLVMType] = val_ty.Pointee + ptee: llvmlite.LLVMType* = val_ty.Pointee pname: str = None if ptee is not None: pname = llvmlite.get_struct_name(ptee) @@ -1174,7 +1171,7 @@ class VarGenMixin: return 0 # ---- repl_perm_strdup — 深拷贝到 PermPool(跨片段存活) ---- - def repl_perm_strdup(self, pool: rawptr[memhub.MemBuddy], + def repl_perm_strdup(self, pool: memhub.MemBuddy*, s: str) -> str: """把 s 深拷贝进 pool(调用方传 PermPool)供会话表长期持有;失败返回 None""" if s is None or pool is None: @@ -1220,9 +1217,9 @@ class VarGenMixin: # 分配时机:片段翻译期(translate_assign / translate_annassign 的 Name 目标 # 在局部表未命中时)。表满 ⇒ 明确报错(fail-fast,经 M0 setjmp 恢复点继续 # 下一行),不静默丢弃。 - def repl_ensure_entry(self, trans: rawptr[HT.Translator], + def repl_ensure_entry(self, trans: HT.Translator*, name: str, - node: rawptr[ast.AST]) -> rawptr[GenTypes.ReplVarEntry]: + node: ast.AST*) -> rawptr[GenTypes.ReplVarEntry]: """按名取条目,未登记则分配槽位并登记;失败返回 None(已 fail-fast)""" if trans is None or name is None: return None @@ -1243,7 +1240,7 @@ class VarGenMixin: f"无法为 '{name}' 再分配槽位;请重启会话", "ResourceError") return None - perm: rawptr[memhub.MemBuddy] = self.repl_perm_pool(trans) + perm: memhub.MemBuddy* = self.repl_perm_pool(trans) if perm is None: self.Gen.TypeGenErr.fatal_error( node, "REPL: 会话永久池不可用(宿主未注入)", "InternalCompilerError") @@ -1268,18 +1265,18 @@ class VarGenMixin: return entry # ---- repl_perm_pool — 会话数据的永久池(跨片段存活) ---- - def repl_perm_pool(self, trans: rawptr[HT.Translator]) -> rawptr[memhub.MemBuddy]: + def repl_perm_pool(self, trans: HT.Translator*) -> memhub.MemBuddy*: """宿主注入的 PermPool(ctx.Perm);无 ctx/未注入返回 None""" if trans is None or trans.ReplCtx is None: return None return trans.ReplCtx.Perm # ---- repl_emit_result — 把本片段结果写入 ctx 结果区 ---- - def repl_emit_result(self, trans: rawptr[HT.Translator], - ctx_val: rawptr[llvmlite.Value], - val: rawptr[llvmlite.Value], + def repl_emit_result(self, trans: HT.Translator*, + ctx_val: llvmlite.Value*, + val: llvmlite.Value*, tag: int, bits: int, - node: rawptr[ast.AST] = None) -> int: + node: ast.AST* = None) -> int: """按 tag 把 val 写入 ctx 结果区(见 GenTypes 的 result_kind 表);0=成功 tag: REPL_TY_INT/FLOAT/STR/PTR/STRUCT。 @@ -1292,14 +1289,14 @@ class VarGenMixin: """ if trans is None or ctx_val is None or val is None: return 1 - pool: rawptr[memhub.MemBuddy] = trans.Pool - builder: rawptr[llvmlite.IRBuilder] = trans._cur_builder + pool: memhub.MemBuddy* = trans.Pool + builder: llvmlite.IRBuilder* = trans._cur_builder if pool is None or builder is None: return 1 - i64_ty: rawptr[llvmlite.LLVMType] = llvmlite.Int64(pool) - zero64: rawptr[llvmlite.Value] = llvmlite.const_int64(pool, 0) + i64_ty: llvmlite.LLVMType* = llvmlite.Int64(pool) + zero64: llvmlite.Value* = llvmlite.const_int64(pool, 0) if tag == GenTypes.REPL_TY_INT: - iv: rawptr[llvmlite.Value] = self.Gen.ExprGenBase.coerce_to_type( + iv: llvmlite.Value* = self.Gen.ExprGenBase.coerce_to_type( builder, val, i64_ty, node, trans) if iv is None: return 1 @@ -1310,12 +1307,12 @@ class VarGenMixin: return 1 return self._repl_store_res_i64(trans, ctx_val, GenTypes.REPL_RES_B_OFF, zero64) if tag == GenTypes.REPL_TY_FLOAT: - dv: rawptr[llvmlite.Value] = self.Gen.ExprGenBase.coerce_to_type( + dv: llvmlite.Value* = self.Gen.ExprGenBase.coerce_to_type( builder, val, llvmlite.Double(pool), node, trans) if dv is None: return 1 # double → i64 位模式(bitcast,不做数值转换):宿主按位重解释回 double - dbits: rawptr[llvmlite.Value] = llvmlite.build_bitcast(builder, dv, i64_ty) + dbits: llvmlite.Value* = llvmlite.build_bitcast(builder, dv, i64_ty) if dbits is None: return 1 if self._repl_store_res_i32(trans, ctx_val, GenTypes.REPL_RES_KIND_OFF, @@ -1325,8 +1322,8 @@ class VarGenMixin: return 1 return self._repl_store_res_i64(trans, ctx_val, GenTypes.REPL_RES_B_OFF, zero64) if tag == GenTypes.REPL_TY_STR or tag == GenTypes.REPL_TY_PTR: - i8_ptr_ty: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(pool, llvmlite.Int8(pool)) - pv: rawptr[llvmlite.Value] = val + i8_ptr_ty: llvmlite.LLVMType* = llvmlite.Ptr(pool, llvmlite.Int8(pool)) + pv: llvmlite.Value* = val if val.Ty is not None and self.Gen.ExprGenBase.is_ptr_type(val.Ty) != 0 \ and self.Gen.AssignGen._stg_ty_equal(pool, val.Ty, i8_ptr_ty) == 0: # 已是指向 i8 的指针(str/bytes/t.CPtr)时跳过——LLVM 拒绝同型 bitcast @@ -1334,7 +1331,7 @@ class VarGenMixin: if pv is None: return 1 # 指针 → i64(ptrtoint):宿主按整数读回后再 inttoptr 成地址 - pbits: rawptr[llvmlite.Value] = self.Gen.ExprGenBase.coerce_to_type( + pbits: llvmlite.Value* = self.Gen.ExprGenBase.coerce_to_type( builder, pv, i64_ty, node, trans) if pbits is None: return 1 @@ -1359,47 +1356,47 @@ class VarGenMixin: return 1 # ---- _repl_store_res_i64 / _repl_store_res_i32 — 结果区某偏移写定宽常量/值 ---- - def _repl_store_res_i64(self, trans: rawptr[HT.Translator], - ctx_val: rawptr[llvmlite.Value], + def _repl_store_res_i64(self, trans: HT.Translator*, + ctx_val: llvmlite.Value*, off: int, - val: rawptr[llvmlite.Value]) -> int: + val: llvmlite.Value*) -> int: """把 i64 值写到 ctx 结果区的 off 偏移(0=成功)""" if trans is None or ctx_val is None or val is None: return 1 - pool: rawptr[memhub.MemBuddy] = trans.Pool - builder: rawptr[llvmlite.IRBuilder] = trans._cur_builder - slot: rawptr[llvmlite.Value] = self.repl_slot_ptr( + pool: memhub.MemBuddy* = trans.Pool + builder: llvmlite.IRBuilder* = trans._cur_builder + slot: llvmlite.Value* = self.repl_slot_ptr( pool, builder, ctx_val, off, llvmlite.Int64(pool)) if slot is None: return 1 llvmlite.build_store(builder, val, slot) return 0 - def _repl_store_res_i32(self, trans: rawptr[HT.Translator], - ctx_val: rawptr[llvmlite.Value], + def _repl_store_res_i32(self, trans: HT.Translator*, + ctx_val: llvmlite.Value*, off: int, val: int) -> int: """把 i32 常量写到 ctx 结果区的 off 偏移(kind / var_count 等,0=成功)""" if trans is None or ctx_val is None: return 1 - pool: rawptr[memhub.MemBuddy] = trans.Pool - builder: rawptr[llvmlite.IRBuilder] = trans._cur_builder + pool: memhub.MemBuddy* = trans.Pool + builder: llvmlite.IRBuilder* = trans._cur_builder if pool is None or builder is None: return 1 - slot: rawptr[llvmlite.Value] = self.repl_slot_ptr( + slot: llvmlite.Value* = self.repl_slot_ptr( pool, builder, ctx_val, off, llvmlite.Int32(pool)) if slot is None: return 1 - cv: rawptr[llvmlite.Value] = llvmlite.const_int32(pool, val) + cv: llvmlite.Value* = llvmlite.const_int32(pool, val) if cv is None: return 1 llvmlite.build_store(builder, cv, slot) return 0 # ---- repl_try_read — 会话变量读取(命中返回 load 值,未命中返回 None) ---- - def repl_try_read(self, trans: rawptr[HT.Translator], + def repl_try_read(self, trans: HT.Translator*, name: str, - node: rawptr[ast.AST]) -> rawptr[llvmlite.Value]: + node: ast.AST*) -> llvmlite.Value*: """REPL 会话变量读:命中返回槽内值(结构体返回盒子地址);否则 None 返回 None 表示"不是会话变量",调用方继续原有查找/报错路径。 @@ -1417,8 +1414,8 @@ class VarGenMixin: f"REPL: 会话变量 '{name}' 尚未赋值(未定型,先执行一条 'x = ...' 或 'x: int = ...')", "NameError") return None - pool: rawptr[memhub.MemBuddy] = trans.Pool - slot_ty: rawptr[llvmlite.LLVMType] = self.repl_slot_ty(pool, entry) + pool: memhub.MemBuddy* = trans.Pool + slot_ty: llvmlite.LLVMType* = self.repl_slot_ty(pool, entry) if slot_ty is None: self.Gen.TypeGenErr.fatal_error( node, @@ -1427,10 +1424,10 @@ class VarGenMixin: f"(跨片段类型可见性属 M4)", "NameError") return None - ctx_val: rawptr[llvmlite.Value] = self.repl_ctx_ptr(trans, trans.ReplCtx, node) + ctx_val: llvmlite.Value* = self.repl_ctx_ptr(trans, trans.ReplCtx, node) if ctx_val is None: return None - slot: rawptr[llvmlite.Value] = self.repl_slot_ptr( + slot: llvmlite.Value* = self.repl_slot_ptr( pool, trans._cur_builder, ctx_val, entry.Offset, slot_ty) if slot is None: self.Gen.TypeGenErr.fatal_error(node, "REPL: 会话槽地址生成失败", "InternalCompilerError") @@ -1438,9 +1435,9 @@ class VarGenMixin: return llvmlite.build_load(trans._cur_builder, slot_ty, slot) # ---- repl_try_addr — 会话变量取址(c.Addr(x) → ctx 槽地址) ---- - def repl_try_addr(self, trans: rawptr[HT.Translator], + def repl_try_addr(self, trans: HT.Translator*, name: str, - node: rawptr[ast.AST]) -> rawptr[llvmlite.Value]: + node: ast.AST*) -> llvmlite.Value*: """会话变量取址:返回槽地址(Ptr(值类型)) 值只存一份(宿主持有的 ctx arena)且内联在槽里,故 c.Addr(x) 得到的 @@ -1460,18 +1457,18 @@ class VarGenMixin: f"REPL: 会话变量 '{name}' 尚未赋值(未定型),无法取址(c.Addr)", "NameError") return None - pool: rawptr[memhub.MemBuddy] = trans.Pool - slot_ty: rawptr[llvmlite.LLVMType] = self.repl_slot_ty(pool, entry) + pool: memhub.MemBuddy* = trans.Pool + slot_ty: llvmlite.LLVMType* = self.repl_slot_ty(pool, entry) if slot_ty is None: self.Gen.TypeGenErr.fatal_error( node, f"REPL: 会话变量 '{name}' 的类型在当前片段不可用(跨片段类型可见性属 M4)", "NameError") return None - ctx_val: rawptr[llvmlite.Value] = self.repl_ctx_ptr(trans, trans.ReplCtx, node) + ctx_val: llvmlite.Value* = self.repl_ctx_ptr(trans, trans.ReplCtx, node) if ctx_val is None: return None - slot: rawptr[llvmlite.Value] = self.repl_slot_ptr( + slot: llvmlite.Value* = self.repl_slot_ptr( pool, trans._cur_builder, ctx_val, entry.Offset, slot_ty) if slot is None: self.Gen.TypeGenErr.fatal_error( @@ -1481,11 +1478,11 @@ class VarGenMixin: return slot # ---- repl_store_slot — 定型后的值写槽(并把该值写入结果区) ---- - def repl_store_slot(self, trans: rawptr[HT.Translator], + def repl_store_slot(self, trans: HT.Translator*, entry: rawptr[GenTypes.ReplVarEntry], - ctx_val: rawptr[llvmlite.Value], - rhs_val: rawptr[llvmlite.Value], - node: rawptr[ast.AST]) -> int: + ctx_val: llvmlite.Value*, + rhs_val: llvmlite.Value*, + node: ast.AST*) -> int: """coerce 到槽类型 → 写槽 → 写结果区;0=成功(失败已 fail-fast) 槽内一律"值本身"(标量/指针/≤16B 结构体值内联),无装箱间接层 ⇒ @@ -1493,9 +1490,9 @@ class VarGenMixin: """ if trans is None or entry is None or ctx_val is None or rhs_val is None: return 1 - pool: rawptr[memhub.MemBuddy] = trans.Pool - builder: rawptr[llvmlite.IRBuilder] = trans._cur_builder - slot_ty: rawptr[llvmlite.LLVMType] = self.repl_slot_ty(pool, entry) + pool: memhub.MemBuddy* = trans.Pool + builder: llvmlite.IRBuilder* = trans._cur_builder + slot_ty: llvmlite.LLVMType* = self.repl_slot_ty(pool, entry) if slot_ty is None: self.Gen.TypeGenErr.fatal_error( node, @@ -1503,7 +1500,7 @@ class VarGenMixin: f"(类型在当前片段不可解析,或结构体值体积超出槽容量)", "TypeError") return 1 - store_val: rawptr[llvmlite.Value] = self.Gen.ExprGenBase.coerce_to_type( + store_val: llvmlite.Value* = self.Gen.ExprGenBase.coerce_to_type( builder, rhs_val, slot_ty, node, trans) if store_val is None: self.Gen.TypeGenErr.fatal_error( @@ -1522,7 +1519,7 @@ class VarGenMixin: if store_val is None: self.Gen.TypeGenErr.fatal_error(node, "REPL: 会话槽指针同型化失败", "CastError") return 1 - slot: rawptr[llvmlite.Value] = self.repl_slot_ptr( + slot: llvmlite.Value* = self.repl_slot_ptr( pool, builder, ctx_val, entry.Offset, slot_ty) if slot is None: self.Gen.TypeGenErr.fatal_error(node, "REPL: 会话槽写入失败", "InternalCompilerError") @@ -1532,11 +1529,11 @@ class VarGenMixin: return 0 # ---- repl_try_assign — 会话变量赋值(命中返回 1) ---- - def repl_try_assign(self, trans: rawptr[HT.Translator], + def repl_try_assign(self, trans: HT.Translator*, name: str, - rhs_val: rawptr[llvmlite.Value], - rhs_node: rawptr[ast.AST], - node: rawptr[ast.AST]) -> int: + rhs_val: llvmlite.Value*, + rhs_node: ast.AST*, + node: ast.AST*) -> int: """REPL 会话变量赋值:命中(已登记 + 在**片段入口函数**本体)返回 1,否则 0 命中路径:定型 → coerce 到条目类型 → 写槽 → 写结果区。 @@ -1557,18 +1554,18 @@ class VarGenMixin: return 1 if self.repl_seal(trans, entry, rhs_val.Ty, rhs_node) != 0: return 1 - ctx_val: rawptr[llvmlite.Value] = self.repl_ctx_ptr(trans, trans.ReplCtx, node) + ctx_val: llvmlite.Value* = self.repl_ctx_ptr(trans, trans.ReplCtx, node) if ctx_val is None: return 1 self.repl_store_slot(trans, entry, ctx_val, rhs_val, node) return 1 # ---- repl_try_annassign — 会话变量带注解声明/赋值(命中返回 1) ---- - def repl_try_annassign(self, trans: rawptr[HT.Translator], + def repl_try_annassign(self, trans: HT.Translator*, name: str, - annot_node: rawptr[ast.AST], - value_node: rawptr[ast.AST], - node: rawptr[ast.AST]) -> int: + annot_node: ast.AST*, + value_node: ast.AST*, + node: ast.AST*) -> int: """REPL 会话变量注解路径:x: int = 1 / x: int(仅定型) 注解先解析并定型条目,再用定型后的类型作为 RHS 的 target_ty(与普通 @@ -1583,8 +1580,8 @@ class VarGenMixin: return 0 if self.repl_in_frag_entry_scope(trans) == 0: return 0 - pool: rawptr[memhub.MemBuddy] = trans.Pool - builder: rawptr[llvmlite.IRBuilder] = trans._cur_builder + pool: memhub.MemBuddy* = trans.Pool + builder: llvmlite.IRBuilder* = trans._cur_builder if annot_node is None: self.Gen.TypeGenErr.fatal_error( node, f"REPL: 会话变量 '{name}' 的注解缺失", "SyntaxError") @@ -1592,7 +1589,7 @@ class VarGenMixin: # 与普通 AnnAssign 同口径:先注册泛型特化,避免 list[X] 退化为裸基类 # (裸 list* 会让后续 .get() 误分派并截断指针) self.Gen.AssignGen._prespecialize_generic_annotation(trans, pool, annot_node) - annot_ty: rawptr[llvmlite.LLVMType] = self.Gen.TypeGenResolve.resolve_annotation_type( + annot_ty: llvmlite.LLVMType* = self.Gen.TypeGenResolve.resolve_annotation_type( pool, annot_node, trans._imported_modules, trans._from_imports, trans, 0) if annot_ty is None: self.Gen.TypeGenErr.fatal_error( @@ -1606,11 +1603,11 @@ class VarGenMixin: if value_node is None: # 仅定型(x: int):不产生值;结果区本行由宿主清零 ⇒ 无结果 return 1 - slot_ty: rawptr[llvmlite.LLVMType] = self.repl_slot_ty(pool, entry) + slot_ty: llvmlite.LLVMType* = self.repl_slot_ty(pool, entry) # 与普通 AnnAssign 四处同口径:翻译 RHS 前设置上下文(裸名泛型构造推断用) trans.CurAssignAnnot = annot_node trans.CurAssignNode = value_node - rhs_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( + rhs_val: llvmlite.Value* = self.Gen.ExprGen.translate_value( builder, pool, trans.Module, value_node, None, 0, trans, slot_ty) trans.CurAssignAnnot = None trans.CurAssignNode = None @@ -1618,18 +1615,18 @@ class VarGenMixin: self.Gen.TypeGenErr.fatal_error( node, f"REPL: 会话变量 '{name}' 的初值翻译失败", "TypeError") return 1 - ctx_val: rawptr[llvmlite.Value] = self.repl_ctx_ptr(trans, trans.ReplCtx, node) + ctx_val: llvmlite.Value* = self.repl_ctx_ptr(trans, trans.ReplCtx, node) if ctx_val is None: return 1 self.repl_store_slot(trans, entry, ctx_val, rhs_val, node) return 1 # ---- repl_try_augassign — 会话变量增强赋值(命中返回 1) ---- - def repl_try_augassign(self, trans: rawptr[HT.Translator], + def repl_try_augassign(self, trans: HT.Translator*, name: str, op: int, - rhs_node: rawptr[ast.AST], - node: rawptr[ast.AST]) -> int: + rhs_node: ast.AST*, + node: ast.AST*) -> int: """REPL 会话变量 x += v:读槽 → 二元运算 → 写槽 → 写结果(命中返回 1) 作用域判据用 repl_in_frag_entry_scope(M3):被提升的会话函数体内 @@ -1642,23 +1639,23 @@ class VarGenMixin: return 0 if self.repl_in_frag_entry_scope(trans) == 0: return 0 - pool: rawptr[memhub.MemBuddy] = trans.Pool - builder: rawptr[llvmlite.IRBuilder] = trans._cur_builder + pool: memhub.MemBuddy* = trans.Pool + builder: llvmlite.IRBuilder* = trans._cur_builder if entry.TyTag == GenTypes.REPL_TY_STRUCT: self.Gen.TypeGenErr.fatal_error( node, f"REPL: 会话变量 '{name}' 是结构体值,不支持增强赋值", "TypeError") return 1 - cur_val: rawptr[llvmlite.Value] = self.repl_try_read(trans, name, node) + cur_val: llvmlite.Value* = self.repl_try_read(trans, name, node) if cur_val is None: return 1 - rhs_val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( + rhs_val: llvmlite.Value* = self.Gen.ExprGen.translate_value( builder, pool, trans.Module, rhs_node, None, 0, trans) if rhs_val is None: self.Gen.TypeGenErr.fatal_error(node, "REPL: 增强赋值右侧翻译失败", "TypeError") return 1 - result: rawptr[llvmlite.Value] = self.Gen.AssignGen._apply_aug_op( + result: llvmlite.Value* = self.Gen.AssignGen._apply_aug_op( pool, builder, op, cur_val, rhs_val, node, trans, node) if result is None: self.Gen.TypeGenErr.fatal_error( @@ -1668,8 +1665,8 @@ class VarGenMixin: return self.repl_try_assign(trans, name, result, node, node) # ---- repl_expr_result — 片段内裸表达式语句的结果回传 ---- - def repl_expr_result(self, trans: rawptr[HT.Translator], - value_node: rawptr[ast.AST]) -> int: + def repl_expr_result(self, trans: HT.Translator*, + value_node: ast.AST*) -> int: """REPL 模式下把裸表达式语句(如 x + 1)求值并写入结果区;0=成功 非 REPL 模式不调用本函数(translate_expr_stmt 只在 REPL 分支调用), @@ -1677,15 +1674,15 @@ class VarGenMixin: """ if trans is None or trans.ReplCtx is None or value_node is None: return 1 - pool: rawptr[memhub.MemBuddy] = trans.Pool - builder: rawptr[llvmlite.IRBuilder] = trans._cur_builder - val: rawptr[llvmlite.Value] = self.Gen.ExprGen.translate_value( + pool: memhub.MemBuddy* = trans.Pool + builder: llvmlite.IRBuilder* = trans._cur_builder + val: llvmlite.Value* = self.Gen.ExprGen.translate_value( builder, pool, trans.Module, value_node, None, 0, trans) if val is None or val.Ty is None: self.Gen.TypeGenErr.fatal_error( value_node, "REPL: 表达式片段求值失败", "TypeError") return 1 - ctx_val: rawptr[llvmlite.Value] = self.repl_ctx_ptr(trans, trans.ReplCtx, value_node) + ctx_val: llvmlite.Value* = self.repl_ctx_ptr(trans, trans.ReplCtx, value_node) if ctx_val is None: return 1 # 类型分类用宿主的影子条目(不占会话槽、不进表):每次先复位为未定型 diff --git a/App/lib/core/IncludesScanner.vp b/App/lib/core/IncludesScanner.vp index f1a1fe3..2feb0dc 100644 --- a/App/lib/core/IncludesScanner.vp +++ b/App/lib/core/IncludesScanner.vp @@ -18,7 +18,7 @@ import lib.core.VLogger as VLogger # ============================================================ # 全局 mbuddy 指针 -_mbuddy: rawptr[memhub.MemBuddy] +_mbuddy: memhub.MemBuddy* # 文件路径最大长度 MAX_PATH_LEN: t.CDefine = 512 @@ -53,7 +53,7 @@ class ScanResult: # ============================================================ # create_scan_result - 创建扫描结果容器 # ============================================================ -def create_scan_result(pool: rawptr[memhub.MemBuddy]) -> ScanResult | t.CPtr: +def create_scan_result(pool: memhub.MemBuddy*) -> ScanResult | t.CPtr: """创建扫描结果容器,预分配 MAX_FILES 个槽位""" if pool is None: return None @@ -78,7 +78,7 @@ def create_scan_result(pool: rawptr[memhub.MemBuddy]) -> ScanResult | t.CPtr: # add_file_entry - 向扫描结果添加文件条目 # ============================================================ def add_file_entry(result: ScanResult | t.CPtr, - pool: rawptr[memhub.MemBuddy], + pool: memhub.MemBuddy*, abs_path: str, rel_path: str, sha1: str, inc_dir: str) -> int: """添加文件条目到扫描结果,返回 0 成功(inc_dir 为所属 includes 根目录)""" @@ -140,7 +140,7 @@ def add_file_entry(result: ScanResult | t.CPtr, # ============================================================ # compute_file_sha1 - 读取文件内容并计算 SHA1(CRLF→LF 后计算,与 Projectrans.py 一致) # ============================================================ -def compute_file_sha1(pool: rawptr[memhub.MemBuddy], +def compute_file_sha1(pool: memhub.MemBuddy*, file_path: str) -> str: """读取文件内容并计算 SHA1 前16字符(CRLF→LF 后计算,与 Projectrans.py 一致)""" if pool is None or file_path is None: @@ -186,7 +186,7 @@ def compute_file_sha1(pool: rawptr[memhub.MemBuddy], # ============================================================ # scan_directory_recursive - 递归扫描目录(FindFirstFileA/FindNextFileA 遍历目录树) # ============================================================ -def scan_directory_recursive(pool: rawptr[memhub.MemBuddy], +def scan_directory_recursive(pool: memhub.MemBuddy*, root_dir: str, rel_prefix: str, result: ScanResult | t.CPtr, @@ -300,7 +300,7 @@ def scan_directory_recursive(pool: rawptr[memhub.MemBuddy], # ============================================================ # scan_includes - 扫描 includes 目录入口(返回所有 .vp 文件路径与 SHA1) # ============================================================ -def scan_includes(pool: rawptr[memhub.MemBuddy], +def scan_includes(pool: memhub.MemBuddy*, includes_dirs: str) -> ScanResult | t.CPtr: """扫描 includes 目录(支持空格分隔的多目录),返回所有 .vp/.py 文件的扫描结果""" if pool is None or includes_dirs is None: @@ -425,22 +425,22 @@ def _TryResolveModuleFile(inc_dir: str, rel_seg: bytes, rel_len: sizet, return 0 string.strcpy(inc_buf, inc_dir) # 写输出槽(stdlib 深拷贝,调用方负责 free) - # 槽联合必须用 (sizet | t.CPtr):t.CPtr|t.CPtr 会被折叠成 t.CPtr, + # 槽联合必须用 (sizet*):t.CPtr|t.CPtr 会被折叠成 t.CPtr, # [0] 变成 1 字节访问 → 指针被截断(0x2e 崩溃根因)。CSizeT 成员为 # 8 字节,写入用 sizet(ptr) 直接转换;读取用 t\.CVoid(u64, t.CPtr) # 转回指针(t\.CVoid 仅配合 t.CPtr 表示 void* 强转)。 if out_abs_path is not None: - abs_slot: sizet | t.CPtr = (sizet | t.CPtr)(out_abs_path) + abs_slot: sizet* = (sizet*)(out_abs_path) abs_slot[0] = sizet(cand) else: stdlib.free(cand) if out_rel_path is not None: - rel_slot: sizet | t.CPtr = (sizet | t.CPtr)(out_rel_path) + rel_slot: sizet* = (sizet*)(out_rel_path) rel_slot[0] = sizet(rel_path) else: stdlib.free(rel_path) if out_inc_dir is not None and inc_buf is not None: - inc_slot: sizet | t.CPtr = (sizet | t.CPtr)(out_inc_dir) + inc_slot: sizet* = (sizet*)(out_inc_dir) inc_slot[0] = sizet(inc_buf) return 1 diff --git a/App/lib/core/Repl.vp b/App/lib/core/Repl.vp index a6c14eb..381268c 100644 --- a/App/lib/core/Repl.vp +++ b/App/lib/core/Repl.vp @@ -76,7 +76,7 @@ extern def _setjmp(buf: t.CPtr, frame: t.CPtr) -> int extern def longjmp(buf: t.CPtr, val: int) # PermPool(由 main 注入):jmp_buf 生命周期须覆盖整个会话,不能被 mb.reset_to 回收 -_perm_pool: rawptr[memhub.MemBuddy] +_perm_pool: memhub.MemBuddy* # ============================================================ @@ -404,7 +404,7 @@ ReplSessionSha1: bytes = None # `p = Point(1, 2)`(Point 定义在片段 M.Point.__init__ # 的引用,该符号只存在于片段 M 的 DLL 里 ⇒ 必须把 M 的 import lib 加进 N 的链接 # 命令行。数组槽内是 PermPool 里的路径串指针(8 字节/槽)。 -ReplFragImplibs: sizet | t.CPtr = None +ReplFragImplibs: sizet* = None ReplFragImplibCount: int = 0 # ==== M4:会话基线(CDefine / CTypedef 的跨片段存活)==== @@ -416,12 +416,12 @@ ReplFragImplibCount: int = 0 # - 每片段清空表后按基线回灌(条目分配在本片段池,随片段回收); # - 失败片段用 ReplSavedCDefineCount/ReplSavedCTypedefCount 截断(防御性, # 与 ReplSavedVarCount/ReplSavedFuncCount 同思路)。 -ReplBaseCDefineNames: sizet | t.CPtr = None -ReplBaseCDefineValues: sizet | t.CPtr = None -ReplBaseCDefineKinds: sizet | t.CPtr = None # 每条目 8 字节:0=int / 1=double / 2=str +ReplBaseCDefineNames: sizet* = None +ReplBaseCDefineValues: sizet* = None +ReplBaseCDefineKinds: sizet* = None # 每条目 8 字节:0=int / 1=double / 2=str ReplBaseCDefineCount: int = 0 -ReplBaseCTypedefNames: sizet | t.CPtr = None -ReplBaseCTypedefTypeStrs: sizet | t.CPtr = None +ReplBaseCTypedefNames: sizet* = None +ReplBaseCTypedefTypeStrs: sizet* = None ReplBaseCTypedefCount: int = 0 # 片段开始时的基线水位(失败/回滚时截断回它) ReplSavedCDefineCount: int = 0 @@ -548,7 +548,7 @@ def _read_line(h: win32base.HANDLE, buf: bytes, cap: int) -> int: # 统计顶层语句数(Module.children) -def _count_top_stmts(tree: rawptr[ast.AST]) -> int: +def _count_top_stmts(tree: ast.AST*) -> int: """返回 Module 的顶层语句数(children 为空时为 0)。""" if tree is None or tree.children is None: return 0 @@ -614,7 +614,7 @@ def _block_append(line: str, n: int) -> int: if ReplBlockLen > 0: ReplBlockBuf[ReplBlockLen] = '\n' ReplBlockLen += 1 - string.memcpy(ReplBlockBuf + ReplBlockLen, line, t.CSizeT(n)) + string.memcpy(ReplBlockBuf + ReplBlockLen, line, sizet(n)) ReplBlockLen += n ReplBlockBuf[ReplBlockLen] = 0 return 0 @@ -685,7 +685,7 @@ def _repl_echo_result(frag_name: str, res: rawptr[GenTypes.ReplResult]) -> int: # ============================================================ # 串深拷贝进 pool(调用方给池;池/串无效或分配失败返回 None) -def _repl_str_dup(pool: rawptr[memhub.MemBuddy], s: str) -> str: +def _repl_str_dup(pool: memhub.MemBuddy*, s: str) -> str: """深拷贝 s 到 pool;失败返回 None""" if pool is None or s is None: return None @@ -693,7 +693,7 @@ def _repl_str_dup(pool: rawptr[memhub.MemBuddy], s: str) -> str: b: str = pool.alloc(n + 1) if b is None: return None - string.memcpy(b, s, t.CSizeT(n)) + string.memcpy(b, s, sizet(n)) b[n] = 0 return b @@ -724,7 +724,7 @@ def _repl_base_cdefine_find(name: str) -> int: return -1 -def ReplBaselineRestore(pool: rawptr[memhub.MemBuddy]) -> int: +def ReplBaselineRestore(pool: memhub.MemBuddy*) -> int: """把会话基线(CDefine + CTypedef)回灌进刚被 clear_* 清空的表;0=成功 条目分配在 pool(= 本片段池):表每片段被清空,条目只需活到本片段结束。 @@ -768,9 +768,9 @@ def ReplBaselineCapture() -> int: global ReplBaseCDefineCount, ReplBaseCTypedefCount if _perm_pool is None or GenApi._g_gen is None: return 1 - cdef_names: list[str] | t.CPtr = GenApi._g_gen.TypeGenCDef.CDefineNames + cdef_names: list[str]* = GenApi._g_gen.TypeGenCDef.CDefineNames if cdef_names is not None: - cdef_vals: list[str] | t.CPtr = GenApi._g_gen.TypeGenCDef.CDefineValues + cdef_vals: list[str]* = GenApi._g_gen.TypeGenCDef.CDefineValues cdef_dbl: list[int] | t.CPtr = GenApi._g_gen.TypeGenCDef.CDefineDoubleFlags cdef_str: list[int] | t.CPtr = GenApi._g_gen.TypeGenCDef.CDefineStrFlags n: sizet = len(cdef_names) @@ -802,9 +802,9 @@ def ReplBaselineCapture() -> int: ReplBaseCDefineValues[j] = sizet(vc) ReplBaseCDefineKinds[j] = sizet(kind) ReplBaseCDefineCount = j + 1 - ct_names: list[str] | t.CPtr = GenApi._g_gen.TypeGenCType.CTypedefNames + ct_names: list[str]* = GenApi._g_gen.TypeGenCType.CTypedefNames if ct_names is not None: - ct_vals: list[str] | t.CPtr = GenApi._g_gen.TypeGenCType.CTypedefTypeStrs + ct_vals: list[str]* = GenApi._g_gen.TypeGenCType.CTypedefTypeStrs cn2: sizet = len(ct_names) i2: sizet for i2 in range(cn2): @@ -885,7 +885,7 @@ def _repl_cmd_append_implibs(cmd: bytes, cap: int, pos: int) -> int: # ---- includes 类注册(会话初始化一次;逐模块隔离,失败只告警)---- -def ReplInitIncludesClasses(mb: rawptr[memhub.MemBuddy], +def ReplInitIncludesClasses(mb: memhub.MemBuddy*, sr: rawptr[IncludesScanner.ScanResult], vpi_dir: str) -> int: """把各 includes 模块的 .vpi 注入临时模块 ⇒ 其类进入会话 StructTable;0=完成 @@ -921,7 +921,7 @@ def ReplInitIncludesClasses(mb: rawptr[memhub.MemBuddy], if n_mod > _REPL_INC_CLS_MOD_MAX: n_mod = _REPL_INC_CLS_MOD_MAX # 每模块状态(8 字节/槽,PermPool):0=未尝试/待重试、1=已完成(成功或确认不可用) - st: sizet | t.CPtr = _perm_pool.alloc(_REPL_INC_CLS_MOD_MAX * 8) + st: sizet* = _perm_pool.alloc(_REPL_INC_CLS_MOD_MAX * 8) if st is None: return 1 string.memset(st, 0, _REPL_INC_CLS_MOD_MAX * 8) @@ -932,7 +932,7 @@ def ReplInitIncludesClasses(mb: rawptr[memhub.MemBuddy], GenApi.set_temp_dir(vpi_dir) GenApi.SetTempDir(vpi_dir) GenApi.set_current_file_type(vpi_dir) - tmp_mod: rawptr[llvmlite.LLVMModule] = llvmlite.new_module(_perm_pool, _REPL_INC_MOD_NAME) + tmp_mod: llvmlite.LLVMModule* = llvmlite.new_module(_perm_pool, _REPL_INC_MOD_NAME) tr_inc: rawptr[HandlesTranslator.Translator] = _perm_pool.alloc( HandlesTranslator.Translator.__sizeof__()) if tmp_mod is None or tr_inc is None: @@ -984,7 +984,7 @@ def ReplInitIncludesClasses(mb: rawptr[memhub.MemBuddy], st[i] = sizet(1) ReplIncClsFail += 1 continue - vm: t.CSizeT = mb.mark() + vm: sizet = mb.mark() vpi_path: str = StubMergerCollect._sliced_path(vpi_dir, dl, ent.Sha1, "vpi") if vpi_path is None: st[i] = sizet(1) @@ -1278,7 +1278,7 @@ def ReplInitSession() -> int: # 失败口径(宽容,与 M0 的恢复点一致):includes 目录缺失/扫描为 0/存根生成失败 # 都只告警,**不终止会话**——"不带 import 的片段"仍照常可用。 # ============================================================ -def _repl_gen_includes_vpi(mb: rawptr[memhub.MemBuddy], +def _repl_gen_includes_vpi(mb: memhub.MemBuddy*, sr: rawptr[IncludesScanner.ScanResult], vpi_dir: str) -> int: """为 includes 扫描结果预生成 .vpi 存根;返回新生成个数(-1=参数错误) @@ -1301,7 +1301,7 @@ def _repl_gen_includes_vpi(mb: rawptr[memhub.MemBuddy], if ent is None or ent.Sha1 is None or ent.Path is None: ReplIncVpiFail += 1 continue - fm: t.CSizeT = mb.mark() + fm: sizet = mb.mark() vpi_path: str = StubMergerCollect._sliced_path(vpi_dir, dl, ent.Sha1, "vpi") if vpi_path is None: ReplIncVpiFail += 1 @@ -1346,11 +1346,11 @@ def _repl_gen_includes_vpi(mb: rawptr[memhub.MemBuddy], if bytes_read < _REPL_SRC_BUF_CAP: src_buf[bytes_read] = 0 # 解析(AST 全部分配在本文件的 mb 窗口内) - lx: rawptr[ast.Lexer] = ast.new_lexer(mb) - tree: rawptr[ast.AST] = None + lx: ast.Lexer* = ast.new_lexer(mb) + tree: ast.AST* = None if lx is not None: ast._lexer_init(lx, src_buf, mb) - tokens: rawptr[ast.Token] = ast.tokenize(lx) + tokens: ast.Token* = ast.tokenize(lx) tree = ast.parse_tokens(mb, tokens) if tree is None: stdlib.free(src_buf) @@ -1385,7 +1385,7 @@ def _repl_gen_includes_vpi(mb: rawptr[memhub.MemBuddy], return ReplIncVpiNew -def ReplInitIncludes(mb: rawptr[memhub.MemBuddy]) -> int: +def ReplInitIncludes(mb: memhub.MemBuddy*) -> int: """会话级 includes 初始化:扫描 → 注册 SHA1 → 预生成 .vpi → 注册泛型模板 → 逐模块类注册;0=成功,非 0=降级跳过 @@ -1525,7 +1525,7 @@ def _repl_show_line(p: bytes, n: int) -> str: m = 118 if m < 0: m = 0 - string.memcpy(ReplLineShow, p, t.CSizeT(m)) + string.memcpy(ReplLineShow, p, sizet(m)) ReplLineShow[m] = 0 return ReplLineShow @@ -1551,7 +1551,7 @@ def _repl_line_has_kw(p: bytes, n: int, ind: int, kw: str) -> int: k: int = int(string.strlen(kw)) if ind + k + 1 > n: return 0 - if string.strncmp(p + ind, kw, t.CSizeT(k)) != 0: + if string.strncmp(p + ind, kw, sizet(k)) != 0: return 0 c: char = p[ind + k] if c != ' ' and c != '\t': @@ -1565,7 +1565,7 @@ def _repl_cat(dst: bytes, cap: int, pos: int, src: bytes, n: int) -> int: return -1 if pos + n + 1 > cap: return -1 - string.memcpy(dst + pos, src, t.CSizeT(n)) + string.memcpy(dst + pos, src, sizet(n)) pos += n dst[pos] = 0 return pos @@ -1587,7 +1587,7 @@ def _repl_lift_add_name(name: str) -> int: # 依据(会话变量的写路径只在该作用域生效),用户不得占用该前缀 pfx: str = GenTypes.REPL_ENTRY_PREFIX pl: int = int(string.strlen(pfx)) - if string.strncmp(name, pfx, t.CSizeT(pl)) == 0: + if string.strncmp(name, pfx, sizet(pl)) == 0: stdio.printf("M3: 会话函数名不能以保留前缀 '%s' 开头:%s\n", pfx, name) return 1 i: int @@ -1632,7 +1632,7 @@ def _repl_lift_def_header(line: bytes, n: int, name_out: bytes, name_cap: int) - stdio.printf("M3: 会话函数名过长(上限 %d 字节):%s\n", name_cap - 1, _repl_show_line(line, n)) return 1 - string.memcpy(name_out, line + ns, t.CSizeT(nlen)) + string.memcpy(name_out, line + ns, sizet(nlen)) name_out[nlen] = 0 # PEP 695 泛型参数 [T]:跳过平衡的方括号(翻译侧把 T 映射为 int) if p < n and line[p] == '[': @@ -1695,7 +1695,7 @@ def _repl_lift_def_header(line: bytes, n: int, name_out: bytes, name_cap: int) - seg: int = lp + 1 while seg + 12 <= rp: if line[seg] == '_' and string.strncmp(line + seg, GenTypes.REPL_CTX_PARAM, - t.CSizeT(12)) == 0: + sizet(12)) == 0: stdio.printf("M3: 会话函数 '%s' 不能自定义 %s 形参" "(提升时自动注入为第一个形参)\n", name_out, GenTypes.REPL_CTX_PARAM) return 1 @@ -2056,8 +2056,8 @@ def _repl_register_session_funcs(h_lib: win32base.HANDLE, frag_no: int) -> int: return 1 string.memset(tags_b, 0, GenTypes.REPL_FUNC_PARAM_MAX) string.memset(bits_b, 0, GenTypes.REPL_FUNC_PARAM_MAX) - string.memcpy(tags_b, ReplSigTags, t.CSizeT(ReplSigResult.ParamCount)) - string.memcpy(bits_b, ReplSigBits, t.CSizeT(ReplSigResult.ParamCount)) + string.memcpy(tags_b, ReplSigTags, sizet(ReplSigResult.ParamCount)) + string.memcpy(bits_b, ReplSigBits, sizet(ReplSigResult.ParamCount)) ent.Name = nm_c ent.SymName = nm_s ent.FragNo = frag_no @@ -2101,7 +2101,7 @@ def _repl_span_str(src: bytes, n: int) -> str: m = _REPL_FN_TY_CAP - 1 if m < 0: m = 0 - string.memcpy(ReplTySpan, src, t.CSizeT(m)) + string.memcpy(ReplTySpan, src, sizet(m)) ReplTySpan[m] = 0 return ReplTySpan @@ -2385,11 +2385,11 @@ def _build_frag_src(name: str, body: str) -> int: # 执行一份片段源码(单行与整块同一入口):先按**未包裹**源码解析一次(诊断行号 # 对用户可读、且与单行路径同款消息),再交给 ReplExecFragment 包裹/翻译/执行。 # 行为与改动前 run 里的单行逻辑逐语句一致(moved,非新增)。 -def _exec_repl_src(mb: rawptr[memhub.MemBuddy], src: str) -> int: +def _exec_repl_src(mb: memhub.MemBuddy*, src: str) -> int: """解析 + 执行一份片段源码;0=已处理(含各类诊断已打印)""" if src is None: return 1 - tree: rawptr[ast.AST] = ast.parse(src, mb) + tree: ast.AST* = ast.parse(src, mb) if tree is None: el: int = ast.get_parse_err_line() ec: int = ast.get_parse_err_col() @@ -2423,7 +2423,7 @@ def _exec_repl_src(mb: rawptr[memhub.MemBuddy], src: str) -> int: # 返回 0=成功(已按 result_kind 回显);非 0=失败(已打印原因,未崩)。 # 注意:翻译期 fatal_error / llc 失败会经 VLogger.error → longjmp 回到 run 的恢复点, # 此时本函数不返回;失败片段占用的符号序号已提前递增(名字/文件名不复用)。 -def ReplExecFragment(mb: rawptr[memhub.MemBuddy], src: str) -> int: +def ReplExecFragment(mb: memhub.MemBuddy*, src: str) -> int: """片段 → DLL → 调用 → ctx 回显;0=成功""" global ReplFragFn, ReplFragNo, ReplSavedVarCount, ReplSavedFuncCount global ReplSavedCDefineCount, ReplSavedCTypedefCount @@ -2532,11 +2532,11 @@ def ReplExecFragment(mb: rawptr[memhub.MemBuddy], src: str) -> int: # 供后续片段特化时重读模板;若节点在本片段池,后续片段特化即读已回收内存。 # 永久池解析让"模板节点"与"模板表"同寿命(代价:含 class 的片段 AST 常驻, # 量级 KB/片段)。不含 class 的片段仍用 mb,行为与 M2/M3 逐字一致。 - parse_pool: rawptr[memhub.MemBuddy] = mb + parse_pool: memhub.MemBuddy* = mb if _perm_pool is not None: if string.strstr(ReplSrcBuf, "class ") is not None: parse_pool = _perm_pool - tree: rawptr[ast.AST] = ast.parse(ReplSrcBuf, parse_pool) + tree: ast.AST* = ast.parse(ReplSrcBuf, parse_pool) if tree is None: el: int = ast.get_parse_err_line() ec: int = ast.get_parse_err_col() @@ -2754,7 +2754,7 @@ def ReplExecFragment(mb: rawptr[memhub.MemBuddy], src: str) -> int: # ============================================================ # run - M2 REPL 主循环 # ============================================================ -def run(mb: rawptr[memhub.MemBuddy]) -> int: +def run(mb: memhub.MemBuddy*) -> int: """M2/M3 REPL:读一行/一整块 → 解析 → 编译为 DLL 并调用(会话变量经 ctx 槽)→ 回显; 行尾 ':' 进入块级续行(提示符 "... "),空行或 EOF 结束并整块执行一次;错误不终止进程。""" global ReplJmpBuf, ReplSavedVarCount, ReplSavedFuncCount, ReplInBlock, ReplBlockLen @@ -2836,7 +2836,7 @@ def run(mb: rawptr[memhub.MemBuddy]) -> int: # jmp_buf 是未定义行为。恢复后按宽容口径继续进入读行循环。 # 【硬保证】提示符必现:includes 的任何失败(含"类注册整体失败")都只影响 # includes 类的可用性,绝不阻止进入读行循环 —— 本段所有出口都不 return。 - inc_mark: t.CSizeT = mb.mark() + inc_mark: sizet = mb.mark() rc_inc: int = _setjmp(jb, None) if rc_inc != 0: stdio.printf("REPL: includes 初始化中断(已注册 %d 个模块、存根 %d 个):" @@ -2910,7 +2910,7 @@ def run(mb: rawptr[memhub.MemBuddy]) -> int: n = 0 # 每行独立:先取水位,再 _setjmp(武装本片段/本块的恢复点,覆盖整条流水线); # 解析/翻译/llc/加载/调用期的任何 longjmp 都回收到 mark 并继续。 - mark: t.CSizeT = mb.mark() + mark: sizet = mb.mark() rc: int = _setjmp(jb, None) if rc != 0: # longjmp 返回:诊断已由 VLogger.error / fatal_error 等打印(均以换行 diff --git a/App/lib/core/VLogger.vp b/App/lib/core/VLogger.vp index f39ec21..791177e 100644 --- a/App/lib/core/VLogger.vp +++ b/App/lib/core/VLogger.vp @@ -95,7 +95,7 @@ class Logger: _console_handle: win32base.HANDLE _use_color: int jit_flag: bool - __mbuddy__: rawptr[memhub.MemBuddy] + __mbuddy__: memhub.MemBuddy* def __init__(self, level: int = 1): self._level = level @@ -229,7 +229,7 @@ class Logger: # 全局 mbuddy 指针(由 lib.InitLib 注入) -_mbuddy: rawptr[memhub.MemBuddy] +_mbuddy: memhub.MemBuddy* # 全局 logger 指针 logger: Logger | t.CPtr diff --git a/App/main.vp b/App/main.vp index d1eef87..e5c19c4 100644 --- a/App/main.vp +++ b/App/main.vp @@ -81,12 +81,12 @@ def main() -> int: stdio.printf("FAIL: malloc for perm_pool arena failed\n") return 1 - mb: rawptr[memhub.MemBuddy] = memhub.MemBuddy(arena, POOL_SIZE, detect_flag, deep_detect_flag) + mb: memhub.MemBuddy* = memhub.MemBuddy(arena, POOL_SIZE, detect_flag, deep_detect_flag) if mb is None: stdio.printf("FAIL: MemBuddy init failed\n") return 1 - perm_pool: rawptr[memhub.MemBuddy] = memhub.MemBuddy(perm_arena, PERM_POOL_SIZE, detect_flag, deep_detect_flag) + perm_pool: memhub.MemBuddy* = memhub.MemBuddy(perm_arena, PERM_POOL_SIZE, detect_flag, deep_detect_flag) if perm_pool is None: stdio.printf("FAIL: perm_pool init failed\n") @@ -502,10 +502,10 @@ Target: %s src_buf[bytes_read] = 0 # 解析 AST(拆分为词法+语法两阶段,便于调试) ast._init_tables(mb) - lx: rawptr[ast.Lexer] = ast.new_lexer(mb) + lx: ast.Lexer* = ast.new_lexer(mb) ast._lexer_init(lx, src_buf, mb) - tokens: rawptr[ast.Token] = ast.tokenize(lx) - tree: rawptr[ast.AST] = ast.parse_tokens(mb, tokens) + tokens: ast.Token* = ast.tokenize(lx) + tree: ast.AST* = ast.parse_tokens(mb, tokens) if tree is None: log.error("AST 解析失败", "ast") argparse.release(args)