diff --git a/App/lib/Stub/StubGen/VpiReader.vp b/App/lib/Stub/StubGen/VpiReader.vp index a3702f7..cfcde75 100644 --- a/App/lib/Stub/StubGen/VpiReader.vp +++ b/App/lib/Stub/StubGen/VpiReader.vp @@ -1672,13 +1672,19 @@ def _inject_global_variable_declare(pool: memhub.MemBuddy | t.CPtr, gv_ty_v: llvmlite.LLVMType | t.CPtr = resolved_v match resolved_v: case llvmlite.LLVMType.Struct(_, _, _): - # t.CStruct 值类(如 pci_device):模块级全局变量定义端是值实例 - # (handle_module_level_var 直接 new_global_variable(pool, name, resolved_v)), - # stub 声明必须保持值类型(%struct),否则跨模块字段访问 mod.var.field - # 生成 load %T**, %T** → 把实例前 8 字节当指针解引用 → 垃圾地址 #GP - # (uhci.vp pci._uhci_dev.irq 根因)。@t.Object 类 resolve 已返回 - # Ptr(struct),不会命中本分支,对象即指针语义不受影响。 - gv_ty_v = resolved_v + # 对象类(@t.Object/@t.CVTable:对象即指针,HasNew/HasVTable/IsOOP) + # → Ptr(struct),与定义端 handle_module_level_var 一致;否则纯 + # t.CStruct 值类(如 pci_device)保持值实例。此前一律转 Ptr 导致 + # 跨模块字段访问把实例前 8 字节当指针解引用 → 垃圾地址 #GP + # (uhci.vp pci._uhci_dev.irq 根因);一律保持值则 @t.Object 类 + # 模块级变量(如 devfs.vp serial0_file.open)按指针访问读错 vtable + # → 调用跳栈 #PF。 + gv_entry_v: GenTypes.StructEntry | t.CPtr = 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) + else: + gv_ty_v = resolved_v case llvmlite.LLVMType.Array(aelem_v, acount_v): # 定长数组(CArray[T, N]):保留完整数组类型 [N x T],与定义端 # handle_module_level_var 生成的 global [N x T] 一致——此前一律 diff --git a/App/lib/core/Gen/GenApi.vp b/App/lib/core/Gen/GenApi.vp index 611d96c..32b43bd 100644 --- a/App/lib/core/Gen/GenApi.vp +++ b/App/lib/core/Gen/GenApi.vp @@ -142,22 +142,23 @@ def _is_ctypedef_annotation(annotation: ast.AST | t.CPtr) -> int: # ---------------- resolve_annotation_type(委托 TypeGenResolve.resolve_annotation_type) ---------------- -def resolve_annotation_type(pool: memhub.MemBuddy | t.CPtr, node: ast.AST | t.CPtr, imported_modules: str, from_imports: str, trans: HT.Translator | t.CPtr = None) -> llvmlite.LLVMType | t.CPtr: +def resolve_annotation_type(pool: memhub.MemBuddy | t.CPtr, node: ast.AST | t.CPtr, imported_modules: str, from_imports: str, trans: HT.Translator | t.CPtr = None, depth: int = 0) -> llvmlite.LLVMType | t.CPtr: """委托到 gen.resolve_annotation_type(原 Handles 壳)""" import lib.core.Gen.Generator as Generator g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr)) if g is not None: - return g.TypeGenResolve.resolve_annotation_type(pool, node, imported_modules, from_imports, trans) + return g.TypeGenResolve.resolve_annotation_type(pool, node, imported_modules, from_imports, trans, depth) return None # ---------------- has_decorator_marker(委托 TypeGenErr.has_decorator_marker) ---------------- -def has_decorator_marker(node: ast.AST | t.CPtr, marker_name: str) -> int: +def has_decorator_marker(node: ast.AST | t.CPtr, marker_name: str, + depth: int = 0) -> int: """委托到 gen.has_decorator_marker(原 Handles 壳)""" import lib.core.Gen.Generator as Generator g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr)) if g is not None: - return g.TypeGenErr.has_decorator_marker(node, marker_name) + return g.TypeGenErr.has_decorator_marker(node, marker_name, depth) return 0 @@ -200,6 +201,46 @@ def is_cdefine_found() -> int: return 0 +# ---------------- register_cdefine_constant(委托 TypeGenCDef.register_cdefine_constant) ---------------- +def register_cdefine_constant(pool: memhub.MemBuddy | t.CPtr, + name: str, value: t.CInt64T) -> None: + """委托到 gen.register_cdefine_constant(原 Handles 壳)""" + import lib.core.Gen.Generator as Generator + g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr)) + if g is not None: + return g.TypeGenCDef.register_cdefine_constant(pool, name, value) + + +# ---------------- register_cdefine_double(委托 TypeGenCDef.register_cdefine_double) ---------------- +def register_cdefine_double(pool: memhub.MemBuddy | t.CPtr, + name: str, value: double) -> None: + """委托到 gen.register_cdefine_double(原 Handles 壳)""" + import lib.core.Gen.Generator as Generator + g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr)) + if g is not None: + return g.TypeGenCDef.register_cdefine_double(pool, name, value) + + +# ---------------- is_cdefine_annotation(委托 AssignGenMixin.is_cdefine_annotation) ---------------- +def is_cdefine_annotation(annot: ast.AST | t.CPtr) -> int: + """委托到 gen.is_cdefine_annotation(原 Handles 壳)""" + import lib.core.Gen.Generator as Generator + g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr)) + if g is not None: + return g.AssignGen.is_cdefine_annotation(annot) + return 0 + + +# ---------------- extract_cdefine_int_value(委托 AssignGenMixin.extract_cdefine_int_value) ---------------- +def extract_cdefine_int_value(val_node: ast.AST | t.CPtr) -> t.CInt64T: + """委托到 gen.extract_cdefine_int_value(原 Handles 壳)""" + import lib.core.Gen.Generator as Generator + g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr)) + if g is not None: + return g.AssignGen.extract_cdefine_int_value(val_node) + return 0 + + # ---------------- push_trace(委托 TypeGenBase.push_trace) ---------------- def push_trace(file_name: str, lineno: int, col_start: int = 0, col_end: int = 0) -> None: """委托到 gen.push_trace(原 Handles 壳)""" @@ -276,6 +317,22 @@ def get_struct_type(class_name: str) -> llvmlite.LLVMType | t.CPtr: return None +# ---------------- get_enum_base_type(委托 StmtGenDeclMixin.get_enum_base_type) ---------------- +def get_enum_base_type(enum_name: str) -> llvmlite.LLVMType | t.CPtr: + """委托到 gen.get_enum_base_type(原 Handles 壳) + + 枚举(t.CEnum)注册在独立的 EnumTable(EnumEntry),不进 StructTable, + get_struct_type 查不到。vpi 返回注解如 "types.FRESULT" 解析时 struct + 落空必须回退枚举表取 BaseTy(通常 i32),否则跨模块函数返回类型 + 无法精确获取 → text.ll 缺失(依赖环)时永久 pending(Phase A 死锁根因)。 + """ + import lib.core.Gen.Generator as Generator + g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr)) + if g is not None: + return g.StmtGenDecl.get_enum_base_type(enum_name) + return None + + # ---------------- add_visible_struct(委托 StructGenMixin.add_visible_struct) ---------------- def add_visible_struct(pool: memhub.MemBuddy | t.CPtr, name: str) -> None: """委托到 gen.add_visible_struct(原 Handles 壳)""" @@ -285,6 +342,50 @@ def add_visible_struct(pool: memhub.MemBuddy | t.CPtr, name: str) -> None: return g.StructGen.add_visible_struct(pool, name) +# ---------------- find_struct_by_module(委托 StructGenMixin.find_struct_by_module) ---------------- +def find_struct_by_module(name: str, sha1: str) -> GenTypes.StructEntry | t.CPtr: + """委托到 gen.find_struct_by_module(原 Handles 壳)""" + import lib.core.Gen.Generator as Generator + g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr)) + if g is not None: + return g.StructGen.find_struct_by_module(name, sha1) + return None + + +# ---------------- find_struct_by_type(委托 StructGenMixin.find_struct_by_type) ---------------- +def find_struct_by_type(struct_ty: llvmlite.LLVMType | t.CPtr) -> GenTypes.StructEntry | t.CPtr: + """委托到 gen.find_struct_by_type(原 Handles 壳)""" + import lib.core.Gen.Generator as Generator + g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr)) + if g is not None: + return g.StructGen.find_struct_by_type(struct_ty) + return None + + +# ---------------- register_struct(委托 StructGenMixin.register_struct) ---------------- +def register_struct(pool: memhub.MemBuddy | t.CPtr, + name: str, + struct_ty: llvmlite.LLVMType | t.CPtr, + sha1: str = None) -> GenTypes.StructEntry | t.CPtr: + """委托到 gen.register_struct(原 Handles 壳)""" + import lib.core.Gen.Generator as Generator + g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr)) + if g is not None: + return g.StructGen.register_struct(pool, name, struct_ty, sha1) + return None + + +# ---------------- get_stdlib_alloc(委托 StructGenMixin.get_stdlib_alloc) ---------------- +def get_stdlib_alloc() -> int: + """委托到 gen.get_stdlib_alloc(原 Handles 壳)""" + import lib.core.Gen.Generator as Generator + g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr)) + if g is not None: + return g.StructGen.get_stdlib_alloc() + return 0 + + + # ---------------- compute_package_from_relpath(委托 ImportsGenMixin.compute_package_from_relpath) ---------------- def compute_package_from_relpath(pool: memhub.MemBuddy | t.CPtr, rel_path: str) -> str: """委托到 gen.compute_package_from_relpath(原 Handles 壳)""" diff --git a/App/lib/core/Gen/TranslatorGenMixin.vp b/App/lib/core/Gen/TranslatorGenMixin.vp index 92f95b0..92abbca 100644 --- a/App/lib/core/Gen/TranslatorGenMixin.vp +++ b/App/lib/core/Gen/TranslatorGenMixin.vp @@ -71,8 +71,8 @@ class TranslatorGenMixin: has_export: int = 0 has_state: int = 0 if fd.returns is not None: - has_export = self.Gen.TypeGenErr.has_decorator_marker(fd.returns, "CExport") - has_state = self.Gen.TypeGenErr.has_decorator_marker(fd.returns, "State") + has_export = self.Gen.TypeGenErr.has_decorator_marker(fd.returns, "CExport", 0) + has_state = self.Gen.TypeGenErr.has_decorator_marker(fd.returns, "State", 0) if has_export != 0 or has_state != 0: self.Gen.CallGenBase.register_cexport_func(trans.ModuleSha1, fd.name) @@ -174,7 +174,7 @@ class TranslatorGenMixin: imp: str = trans._imported_modules fi: str = trans._from_imports if fd.returns is not None: - self.Gen.TypeGenResolve.resolve_annotation_type(pool, fd.returns, imp, fi, trans) + self.Gen.TypeGenResolve.resolve_annotation_type(pool, fd.returns, imp, fi, trans, 0) if fd.args is not None: ags: ast.Arguments | t.CPtr = (ast.Arguments | t.CPtr)(fd.args) if ags.args is not None: @@ -184,7 +184,7 @@ class TranslatorGenMixin: for ai in range(an): ag: ast.Arg | t.CPtr = (ast.Arg | t.CPtr)(al.get(ai)) if ag is not None and ag.annotation is not None: - self.Gen.TypeGenResolve.resolve_annotation_type(pool, ag.annotation, imp, fi, trans) + self.Gen.TypeGenResolve.resolve_annotation_type(pool, ag.annotation, imp, fi, trans, 0) # ============================================================ # _build_array_initializer_text - 从 AST List 生成 LLVM IR 数组初始化器 @@ -218,8 +218,10 @@ class TranslatorGenMixin: # 确定元素类型的 IR 表示 elem_ir_ty: str = "i8" + is_int_elem: int = 1 match elem_ty: case llvmlite.LLVMType.Int(bits): + is_int_elem = 1 if bits == 8: elem_ir_ty = "i8" elif bits == 16: @@ -228,6 +230,8 @@ class TranslatorGenMixin: elem_ir_ty = "i32" elif bits == 64: elem_ir_ty = "i64" + case _: + is_int_elem = 0 # 获取列表元素(通过 ln.elts 而非 list_node.elts,确保类型正确识别) elts: list[ast.AST | t.CPtr] | t.CPtr = ln.elts @@ -235,6 +239,93 @@ class TranslatorGenMixin: return None elts_count: t.CSizeT = len(elts) + # 非整数元素类型(struct/指针等聚合):不存在 "%s %lld" 文本展开。 + # 仅当列表全零(元素缺失按零填充)时返回整体 "zeroinitializer"—— + # 对任意聚合类型合法(devfs.directories: t.CArray[devfs_directory, N] + # = [0] 此前生成 [i8 0, ...] 与 [N x %devfs_directory] 类型不匹配, + # llc "constant expression type mismatch" 根因)。含非零/非整数常量 + # 无法文本表达 → None → 调用方 fail-fast。 + if is_int_elem == 0: + # 嵌套数组元素(t.CArray[t.CArray[t.CUInt8T, 16], 256] = [{...}, ...]): + # elem_ty 是 Array → 递归构建子数组初始化器文本。内层类型省略 + # (由外层全局类型推断),llc 合法。vga.vp font 8x16 点阵字库根因: + # 此前只支持 Int 元素,嵌套数组走 zeroinitializer-only 检查,花括号 + # 行(ast.Set)含非零常量 → None → "初始化器构建失败" fail-fast。 + is_nested_arr: int = 0 + match elem_ty: + case llvmlite.LLVMType.Array(_, _): + is_nested_arr = 1 + case _: + pass + if is_nested_arr != 0: + cnt_total_n: t.CSizeT = t.CSizeT(arr_count) + buf_size_n: t.CSizeT = 128 + cnt_total_n * 192 + buf_n: str = pool.alloc(buf_size_n) + if buf_n is None: + return None + written_n: t.CInt = viperlib.snprintf(buf_n, buf_size_n, "[") + pos_n: t.CSizeT = t.CSizeT(written_n) + # 子数组元素类型前缀(如 "[16 x i8]"):嵌套数组初始化器内层 + # 必须显式类型(llc 对省略内层类型的 [[i8 0,...],...] 报 + # "expected number in address space";用户规范要求 + # [[16 x i8][i8 0, ...], ...] 形式)。TypePrint 序列化 elem_ty。 + elem_ty_str_n: str = pool.alloc(96) + if elem_ty_str_n is None: + return None + llvmlite.TypePrint(elem_ty_str_n, 96, elem_ty, pool) + i_n: t.CSizeT = 0 + while i_n < cnt_total_n: + sub_n: str = None + if i_n < elts_count: + en_n: ast.AST | t.CPtr = 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, (ast.List | t.CPtr)(en_n)) + elif ek_n == ast.ASTKind.Set: + # 花括号行字面量(如点阵字库 {0x00, ...}):Set.elts + # 与 List 同构,包装为临时 List 递归生成子数组文本 + se_n: ast.Set | t.CPtr = (ast.Set | t.CPtr)(en_n) + if se_n is not None and se_n.elts is not None: + sub_n = self._build_array_initializer_text( + pool, elem_ty, ast.List(pool, se_n.elts, ast.ASTCtx.Load)) + if sub_n is None: + # 元素缺失/无法展开:子数组整体零初始化 + sub_n = "zeroinitializer" + if i_n > 0: + written_n = viperlib.snprintf(buf_n + pos_n, buf_size_n - pos_n, ", ") + pos_n += t.CSizeT(written_n) + written_n = viperlib.snprintf( + buf_n + pos_n, buf_size_n - pos_n, "%s%s", elem_ty_str_n, sub_n) + pos_n += t.CSizeT(written_n) + i_n += 1 + viperlib.snprintf(buf_n + pos_n, buf_size_n - pos_n, "]") + return buf_n + for zi in range(elts_count): + ze: ast.AST | t.CPtr = elts.get(zi) + if ze is None: + continue + zk: int = ze.kind() + if zk == ast.ASTKind.Constant: + zc: ast.Constant | t.CPtr = (ast.Constant | t.CPtr)(ze) + if zc is None: + continue + # None(CONST_NONE)视为零:函数指针数组 + # irq_handlers: t.CArray[irq_handler_t, 16] = [None] 表示 + # 全空(idt.vp L387)——CONST_NONE 不是 CONST_INT,此前 + # 被拒 → "初始化器构建失败" fail-fast。None 归一零填充。 + if zc.const_kind == ast.CONST_NONE: + continue + if zc.const_kind != ast.CONST_INT or zc.int_val != 0: + return None + elif zk == ast.ASTKind.UnaryOp: + if self.Gen.AssignGen.extract_cdefine_int_value(ze) != 0: + return None + else: + return None + return "zeroinitializer" + # 计算缓冲区大小: 每个元素最多 "i32 -9223372036854775808, " 约 26 字符 # 按数组声明长度 arr_count 计算(元素不足时补零,可能多于 elts_count) cnt_total: t.CSizeT = t.CSizeT(arr_count) @@ -411,6 +502,7 @@ class TranslatorGenMixin: init_kind: int = 0 # 0=none, 1=int, 2=list, 3=str init_str_val: str = None init_list_node: ast.List | t.CPtr = None + annot_node: ast.AST | t.CPtr = None # 类型注解节点(检测 t.CExport 标记) if k == ast.ASTKind.AnnAssign: aa: ast.AnnAssign | t.CPtr = (ast.AnnAssign | t.CPtr)(node) @@ -420,11 +512,23 @@ class TranslatorGenMixin: return 0 nm: ast.Name | t.CPtr = (ast.Name | t.CPtr)(aa.target) var_name = nm.id + annot_node = aa.annotation # 解析类型 if aa.annotation is not None: resolved: llvmlite.LLVMType | t.CPtr = self.Gen.TypeGenResolve.resolve_annotation_type( - pool, aa.annotation, trans._imported_modules, trans._from_imports, trans) + pool, aa.annotation, trans._imported_modules, trans._from_imports, trans, 0) if resolved is not None: + # 对象类模块级变量(@t.Object/@t.CVTable:对象即指针)→ Ptr(struct)。 + # 裸类名注解 resolve 返回 struct 值(参数层 FuncGenDef 会包装 Ptr, + # 模块级变量此处缺包装)→ 若建成值实例,跨模块字段访问/虚表调用 + # 按指针处理读首 8 字节当 vtable → 垃圾地址 #PF(devfs.vp + # serial0_file.open = serial0_open 根因)。纯 t.CStruct(无方法 + # 无虚表无 __new__,如 pci_device)保持值实例。 + if resolved.kind() == llvmlite.LLVMType.Struct: + gv_entry: GenTypes.StructEntry | t.CPtr = 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): + resolved = llvmlite.Ptr(pool, resolved) var_ty = resolved # 解析初始值(支持整数、列表字面量、字符串字面量) if aa.value is not None: @@ -494,7 +598,16 @@ class TranslatorGenMixin: # 模块级全局命名带 SHA1 前缀(对齐函数名 mangling):多个模块声明同名 # 全局(如 _mbuddy)时各自独立命名,消除 ld.lld duplicate symbol。 # SymTab 注册 key 保持裸名(查找逻辑零改动),LLVM 符号名用 mangled 名。 - mangled_name: str = self.Gen.FuncGenBase._mangle_name(trans, var_name) + # t.CExport 标记的全局用裸名(内联汇编引用 / 外部符号对接,如 + # VKernel gdt/gp/_switch_old_rsp/_coro_* 被 c.Asm 引用,带 SHA1 前缀 + # 无法在 LLVM MC 中解析)。 + is_global_cexport: int = 0 + if annot_node is not None: + is_global_cexport = self.Gen.TypeGenErr.has_decorator_marker( + annot_node, "CExport", 0) + mangled_name: str = var_name + if is_global_cexport == 0: + mangled_name = self.Gen.FuncGenBase._mangle_name(trans, var_name) gv: llvmlite.GlobalVariable | t.CPtr = llvmlite.new_global_variable(pool, mangled_name, var_ty) if gv is None: return 0