fix(phase1): CTypedef 改源码文本扫描注册,彻底修 stdint.vp 访问违规崩溃

AST 字符串字段(attr/id)token 零拷贝指向 src_buf,跨阶段内容不稳定
(悬空)——ScanCTypedefDeclarations 读 attr 在两次运行间内容不同
(上轮 prefix=1 有效、本轮直接崩),0xC0000005。修复:
1. Phase1 1b translate 前用 RegisterCTypedefFromSource 纯文本逐行匹配
   'NAME: t.CTypedef = TYPE' 注册(src_buf 有效期内),不依赖 AST 内容
2. 移除 translate 内 ScanCTypedefDeclarations 调用(已被文本扫描替代)
This commit is contained in:
TermiNexus committed 2026-08-18 10:22:26 +08:00
1 parent 23945cd168
commit d18f9a7e7f
4 files changed
+88 -4

No files matched your search

+62
View File
@@ -235,6 +235,68 @@ class TypeGenCType(TypeGenBase.TypeGenBase):
self.register_ctypedef(pool, tgt_id_v, type_str)
count += 1
return count
def register_ctypedef_from_source(self, pool: memhub.MemBuddy | t.CPtr,
src: str) -> int:
"""从源码文本逐行扫描注册 CTypedef(NAME: t.CTypedef = TYPE)
stdint.vp 崩溃根因修复:AST 字符串字段(attr/id)token 零拷贝指向
src_buf,跨阶段内容不稳定(悬空),ScanCTypedefDeclarations 读
attr 会 0xC0000005。本函数在 src_buf 有效期内(Phase1 1b translate
前)用纯文本匹配注册,不依赖 AST 节点内容。
"""
if pool is None or src is None:
return 0
src_len: t.CSizeT = string.strlen(src)
count: int = 0
line_start: t.CSizeT = 0
i: t.CSizeT = 0
while i <= src_len:
if i == src_len or src[i] == '\n':
line_len: t.CSizeT = i - line_start
if line_len > 0:
# 找行内第一个 ':'(跳过注释行)
j: t.CSizeT = 0
found_colon: int = 0
while j < line_len:
ch_c: t.CChar = src[line_start + j]
if ch_c == ':':
found_colon = 1
break
if ch_c == '#' or ch_c == '\r':
break
j += 1
if found_colon != 0:
# 左段 NAME(trim 尾随空格)
name_len: t.CSizeT = j
while name_len > 0 and src[line_start + name_len - 1] == ' ':
name_len -= 1
if name_len > 0 and name_len < 128:
# 右段必须含 "t.CTypedef"
rest: str = src + line_start + j + 1
if string.strstr(rest, "t.CTypedef") is not None:
# 提取 "=" 后的类型表达式(trim 空格)
eq_ptr: str = string.strstr(rest, "=")
if eq_ptr is not None:
ty_start: str = eq_ptr + 1
while ty_start[0] == ' ':
ty_start += 1
ty_end: t.CSizeT = string.strlen(ty_start)
while ty_end > 0 and (ty_start[ty_end - 1] == ' '
or ty_start[ty_end - 1] == '\r'):
ty_end -= 1
if ty_end > 0:
name_buf: str = pool.alloc(name_len + 1)
ty_buf: str = pool.alloc(ty_end + 1)
if name_buf is not None and ty_buf is not None:
string.strncpy(name_buf, src + line_start, name_len)
name_buf[name_len] = '\0'
string.strncpy(ty_buf, ty_start, ty_end)
ty_buf[ty_end] = '\0'
self.register_ctypedef(pool, name_buf, ty_buf)
count += 1
line_start = i + 1
i += 1
return count
def _eval_const_int_expr(self, node: ast.AST | t.CPtr,
pool: memhub.MemBuddy | t.CPtr = None,
from_imports: str = None,
+5 -4
View File
@@ -460,10 +460,11 @@ class Translator:
# 解析失败(DictTest 的 "变量类型注解解析失败")。
self._inject_auto_container_visibility(pool, tree)
stdio.printf("[DIAG] 模块级: 容器可见性完成\n")
# 扫描当前模块的 CTypedef 声明(NAME: t.CTypedef = Type),
# 注册到动态 CTypedef 表,供 resolve_annotation_type 查询
HandlesType.ScanCTypedefDeclarations(pool, tree)
stdio.printf("[DIAG] 模块级: CTypedef 扫描完成\n")
# 扫描当前模块的 CTypedef 声明已由 Phase1 1b 文本扫描注册
# (RegisterCTypedefFromSource,见 Phase1Main.vp)——AST 字符串字段
# token 零拷贝指向 src_buf,跨阶段内容不稳定,此处 AST 扫描读 attr
# 会 0xC0000005(stdint.vp 崩溃根因),故移除。
stdio.printf("[DIAG] 模块级: CTypedef 扫描完成(文本扫描替代)\n")
# 跨模块 .vpi 注入:加载依赖模块的 .vpi 文件,
# 将函数 declare 声明注入到当前模块,解决跨模块函数调用找不到函数的问题
# 严格保证 declare_only == 0 时才注入(避免 Phase A-pre-inc 死锁)
+15
View File
@@ -378,6 +378,21 @@ def ScanCTypedefDeclarations(pool: memhub.MemBuddy | t.CPtr,
return 0
def RegisterCTypedefFromSource(pool: memhub.MemBuddy | t.CPtr,
src: str) -> int:
"""从源码文本逐行注册 CTypedef 声明(委托到 gen.register_ctypedef_from_source)
stdint.vp 崩溃根因修复:AST 字符串字段(attr/id)token 零拷贝指向
src_buf,跨阶段内容不稳定(悬空),ScanCTypedefDeclarations 读 attr
会 0xC0000005。改用文本匹配 "NAME: t.CTypedef = TYPE"。
"""
import lib.core.Gen.Generator as Generator
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
if g is not None:
return g.register_ctypedef_from_source(pool, src)
return 0
def _eval_const_int_expr(node: ast.AST | t.CPtr,
pool: memhub.MemBuddy | t.CPtr = None,
from_imports: str = None,
+6
View File
@@ -765,6 +765,12 @@ def RunPhase1(mb: memhub.MemBuddy | t.CPtr, includes_dir: str, temp_dir: str,
failed += 1
continue
# 文本扫描注册 CTypedef(stdint.vp 崩溃根因修复):AST 字符串字段
# (attr/id)token 零拷贝指向 src_buf,跨阶段内容不稳定(悬空),
# ScanCTypedefDeclarations 读 attr 会 0xC0000005。改用源码文本逐行
# 匹配 "NAME: t.CTypedef = TYPE",在 src_buf 有效期内注册。
HandlesType.RegisterCTypedefFromSource(mb, src_buf)
# 生成 .vpi 存根文件(直接遍历 AST,不依赖 PythonToStubConverter)
pyi_buf: bytes = stdlib.malloc(Phase1.PYI_BUF_SIZE)
if pyi_buf is not None: