基线重置,修复了一些 bug
This commit is contained in:
1 parent
6b368b46a7
commit
ed373a3ef2
8 files changed
+171
-17
No files matched your search
@@ -494,10 +494,16 @@ def RunPhase1(mb: memhub.MemBuddy | t.CPtr, includes_dir: str, temp_dir: str,
|
||||
# 1a-pre-generic 只覆盖"可达"泛型文件;非可达泛型文件(如 FuncTest
|
||||
# 场景的 linkedlist/llvmlite/_list)的模板要等 Phase2 Phase A-pre-inc
|
||||
# (mark2 之后)才注册 → reset 回收表/节点 → _find_generic_template
|
||||
# strcmp 悬空崩溃。此处对全部 includes 轻量预注册,使模板表与节点
|
||||
# 都落在 mark1 之前(mark2 > mark1,reset_to(mark2) 不回收)。
|
||||
# ============================================================
|
||||
Phase1Scan._PreRegisterAllGenericTemplates(mb, result)
|
||||
# 此处对全部 includes 轻量预注册,使模板表与节点都落在 mark1 之前。
|
||||
# result 只是"可达子集",非可达的 _list/_dict/linkedlist/llvmlite 等泛型文件
|
||||
# 模板不会注册 → list[int]/dict[...] 特化失败(ast/base.vp _dump_op_list 根因)。
|
||||
# _PreRegisterAllGenericTemplates 内有 generic marker 文本预筛,全量扫描
|
||||
# 不 parse 全部 AST,仅对含 marker 的文件轻量处理,OOM 风险可控。
|
||||
full_scan_g: IncludesScanner.ScanResult | t.CPtr = IncludesScanner.scan_includes(mb, includes_dir)
|
||||
if full_scan_g is not None:
|
||||
Phase1Scan._PreRegisterAllGenericTemplates(mb, full_scan_g)
|
||||
else:
|
||||
Phase1Scan._PreRegisterAllGenericTemplates(mb, result)
|
||||
|
||||
# ============================================================
|
||||
# Phase 1a: 注册 struct/enum/union(mark1 前,全量 includes)
|
||||
|
||||
@@ -341,6 +341,8 @@ def _PreRegisterAllGenericTemplates(mb: memhub.MemBuddy | t.CPtr,
|
||||
stdlib.free(src_buf_pg)
|
||||
if handled_count > 0:
|
||||
VLogger.info(f"mark1 前永久池预注册 {handled_count} 个 includes 泛型类模板", "Phase1")
|
||||
else:
|
||||
VLogger.info(f"mark1 前永久池预注册 0 个泛型模板(扫描 {result.Count} 个文件,可能 marker 未命中或全量扫描失败)", "Phase1")
|
||||
return handled_count
|
||||
# ============================================================
|
||||
# _FindClassDefSha1 - 在扁平数组中查找类名对应的定义文件 SHA1
|
||||
|
||||
@@ -797,6 +797,8 @@ class CallGenCtor(CallGenBase.CallGenBase):
|
||||
# 但步长按 4 计算,第 2 个元素覆盖第 1 个元素高 4 字节 → get 读出垃圾指针崩溃
|
||||
result: list[str] | t.CPtr = list[str](pool, 8)
|
||||
k: int = slice_node.kind()
|
||||
tn_raw: str = None
|
||||
tn: str = None
|
||||
if k == ast.ASTKind.Tuple:
|
||||
tp: ast.Tuple | t.CPtr = (ast.Tuple | t.CPtr)(slice_node)
|
||||
elts: list[ast.AST | t.CPtr] | t.CPtr = tp.elts
|
||||
@@ -805,15 +807,17 @@ class CallGenCtor(CallGenBase.CallGenBase):
|
||||
i: t.CSizeT
|
||||
for i in range(n):
|
||||
elt: ast.AST | t.CPtr = elts.get(i)
|
||||
tn_raw: str = self.Gen.TypeGenResolve._get_type_name_from_annotation(pool, elt)
|
||||
tn: str = self.Gen.TypeGenResolve._norm_type_arg_name(pool, tn_raw, from_imports)
|
||||
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:
|
||||
result.append(tn)
|
||||
else:
|
||||
tn_raw: str = self.Gen.TypeGenResolve._get_type_name_from_annotation(pool, slice_node)
|
||||
tn: str = self.Gen.TypeGenResolve._norm_type_arg_name(pool, tn_raw, from_imports)
|
||||
tn_raw = self.Gen.TypeGenResolve._get_type_name_from_annotation(pool, slice_node)
|
||||
tn = self.Gen.TypeGenResolve._norm_type_arg_name(pool, tn_raw, from_imports)
|
||||
if tn is not None:
|
||||
result.append(tn)
|
||||
if len(result) == 0:
|
||||
VLogger.info(f"[EXTRACT-DBG] 类型实参提取为空: kind={k} tn_raw={'Y' if tn_raw is not None else 'N'} tn={'Y' if tn is not None else 'N'}", "Phase1")
|
||||
return result
|
||||
# ============================================================
|
||||
# 泛型类构造调用辅助: list[str](pool, 8) → __new__ + __before_init__ + __init__
|
||||
|
||||
@@ -600,7 +600,22 @@ class CallGenDispatch(CallGenBase.CallGenBase):
|
||||
sz_resolved_name: str = sz_cls_name
|
||||
if sz_cls_name is not None:
|
||||
# 泛型类型参数 T 替换: T.__sizeof__() → int.__sizeof__()
|
||||
sz_orig: str = sz_cls_name
|
||||
sz_cls_name = self.Gen.TypeGenBase.resolve_generic_type_name(sz_cls_name)
|
||||
# 兜底:TypeGenBase 上下文为空时(模板 tp_names 跨 phase 失效),
|
||||
# 直接用 trans 的泛型映射替换 T(list[int] 单态化 _list.vp
|
||||
# T.__sizeof__ 根因)。
|
||||
if string.strcmp(sz_cls_name, sz_orig) == 0 and trans is not None \
|
||||
and trans.GenericTypeParamNames is not None and trans.GenericTypeArgs is not None:
|
||||
gp_n: t.CSizeT = len(trans.GenericTypeParamNames)
|
||||
gp_i: t.CSizeT
|
||||
for gp_i in range(gp_n):
|
||||
gpn: str = trans.GenericTypeParamNames.get(gp_i)
|
||||
if gpn is not None and string.strcmp(sz_orig, gpn) == 0:
|
||||
gta: str = trans.GenericTypeArgs.get(gp_i)
|
||||
if gta is not None:
|
||||
sz_cls_name = gta
|
||||
break
|
||||
sz_resolved_name = sz_cls_name
|
||||
# 保存完整名(含模块前缀)供模块归属精确匹配:去前缀后
|
||||
# get_struct_type 裸名全局匹配会误命中跨模块同名类
|
||||
|
||||
@@ -634,7 +634,12 @@ class StmtGenCifMixin:
|
||||
and val_is_ptr == 0 and ret_is_ptr != 0:
|
||||
val = llvmlite.build_inttoptr(builder, val, ret_ty_rt)
|
||||
else:
|
||||
val = self.Gen.ExprGenBase.coerce_to_type(builder, val, ret_ty_rt, node)
|
||||
# 传 trans:Phase A 依赖未就绪(_deps_pending)时,跨模块调用
|
||||
# 返回类型退化为默认 i32,int→ptr 是退化指针重建而非隐式转换
|
||||
# 错误,须跳过 fail-fast(与 AssignGenMixin/ExprGenBase 的
|
||||
# _deps_pending 兜底一致)。否则 return 跨模块指针构造函数
|
||||
# (如 SSAValue)误报"整数隐式转指针已禁止"。
|
||||
val = self.Gen.ExprGenBase.coerce_to_type(builder, val, ret_ty_rt, node, trans)
|
||||
elif val_is_ptr != 0 and ret_is_ptr != 0:
|
||||
# 指针 → 指针且元素类型不同(如 t.CVoid(x, CPtr) 得到 i8*,
|
||||
# 函数返回类型是类指针 Circle* 时)需 bitcast 回,
|
||||
|
||||
@@ -718,6 +718,23 @@ class Translator:
|
||||
sub_s: ast.Subscript | t.CPtr = (ast.Subscript | t.CPtr)(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: ast.FunctionDef | t.CPtr = (ast.FunctionDef | t.CPtr)(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: ast.Arguments | t.CPtr = (ast.Arguments | t.CPtr)(fd_s.args)
|
||||
if args_s.args is not None:
|
||||
args_list_s: list[ast.AST | t.CPtr] | t.CPtr = args_s.args
|
||||
an_s: t.CSizeT = len(args_list_s)
|
||||
ai_s: t.CSizeT
|
||||
for ai_s in range(an_s):
|
||||
arg_s: ast.AST | t.CPtr = args_list_s.get(ai_s)
|
||||
if arg_s is not None:
|
||||
ag_s: ast.Arg | t.CPtr = (ast.Arg | t.CPtr)(arg_s)
|
||||
if ag_s.annotation is not None:
|
||||
self._check_container_type_node(
|
||||
ag_s.annotation, need_list_box, need_dict_box)
|
||||
# [FIX 2026-08-30] `[...]`/`{}` 字面量不再无条件触发 _list/_dict 导入:
|
||||
# 字面量广泛用于编译期常量列表(c.Asm 的 op/inp/out CLOBBER 参数、
|
||||
# 数组数据初始化),并非 list 容器使用。list/dict 容器的真实使用由
|
||||
@@ -735,7 +752,7 @@ class Translator:
|
||||
def _check_container_type_node(self, node: ast.AST | t.CPtr,
|
||||
need_list_box: t.CPtr,
|
||||
need_dict_box: t.CPtr):
|
||||
"""检测类型位置节点是否为 list/dict(支持 Name 与 Subscript 外层)"""
|
||||
"""检测类型位置节点是否为 list/dict(支持 Name / Subscript / BinOp 递归)"""
|
||||
if node is None:
|
||||
return
|
||||
k: int = node.kind()
|
||||
@@ -750,6 +767,13 @@ class Translator:
|
||||
sub_s: ast.Subscript | t.CPtr = (ast.Subscript | t.CPtr)(node)
|
||||
if sub_s.value is not None:
|
||||
self._check_container_type_node(sub_s.value, need_list_box, need_dict_box)
|
||||
# rowptr[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: ast.BinOp | t.CPtr = (ast.BinOp | t.CPtr)(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: ast.AST | t.CPtr) -> int:
|
||||
"""注解是否为 list/dict 容器(Name 裸名或 Subscript list[...]/dict[...])
|
||||
|
||||
@@ -42,6 +42,20 @@ class TypeGenCType(TypeGenBase.TypeGenBase):
|
||||
# (rowptr[T] 固定 = 指向原始类型 T 的裸指针)。
|
||||
if string.strcmp(name, "rowptr") == 0:
|
||||
return
|
||||
# 复制 name/type_str 到 pool:调用方可能传入零拷贝 AST 字符串
|
||||
# (如 .vpi 读取缓冲区),缓冲区随后被 free 会导致表项悬空、
|
||||
# lookup_ctypedef strcmp 失配、typedef 退化为 i8*(testcheck
|
||||
# SetConsoleOutputCP 的 UINT 根因)。表须持有自己的字符串副本。
|
||||
name_len: t.CSizeT = string.strlen(name)
|
||||
name_copy: str = pool.alloc(name_len + 1)
|
||||
if name_copy is None:
|
||||
return
|
||||
string.strcpy(name_copy, name)
|
||||
type_len: t.CSizeT = string.strlen(type_str)
|
||||
type_copy: str = pool.alloc(type_len + 1)
|
||||
if type_copy is None:
|
||||
return
|
||||
string.strcpy(type_copy, type_str)
|
||||
if self.CTypedefNames is None:
|
||||
self.CTypedefNames = list[str](pool, 64)
|
||||
self.CTypedefTypeStrs = list[str](pool, 64)
|
||||
@@ -51,12 +65,12 @@ class TypeGenCType(TypeGenBase.TypeGenBase):
|
||||
ei: t.CSizeT
|
||||
for ei in range(exist_n):
|
||||
en: str = self.CTypedefNames.get(ei)
|
||||
if en is not None and string.strcmp(en, name) == 0:
|
||||
if en is not None and string.strcmp(en, name_copy) == 0:
|
||||
# 已存在,更新类型字符串
|
||||
self.CTypedefTypeStrs.set(ei, type_str)
|
||||
self.CTypedefTypeStrs.set(ei, type_copy)
|
||||
return
|
||||
self.CTypedefNames.append(name) # 存疑
|
||||
self.CTypedefTypeStrs.append(type_str)
|
||||
self.CTypedefNames.append(name_copy)
|
||||
self.CTypedefTypeStrs.append(type_copy)
|
||||
def lookup_ctypedef(self, name: str) -> str:
|
||||
"""查找 CTypedef,返回类型表达式字符串
|
||||
|
||||
|
||||
@@ -50,7 +50,10 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
|
||||
# 导致 _specialize_generic_class("ndarray", ["T"]) 二次递归崩溃)
|
||||
if k == ast.ASTKind.Name:
|
||||
nm: ast.Name | t.CPtr = (ast.Name | t.CPtr)(node)
|
||||
return self.Gen.TypeGenBase.resolve_generic_type_name(ast.name_get_id(nm))
|
||||
# 直接用字段:ast.name_get_id 是跨模块访问器,Phase A 阶段 exprs.vp
|
||||
# text.ll 未生成时该访问器是 stub(declare 无体)返回 None,导致
|
||||
# 泛型类型实参提取失败(list[int] 的 int 被误判未提取)。
|
||||
return self.Gen.TypeGenBase.resolve_generic_type_name(nm.id)
|
||||
# Attribute: 构造 "module.attr" 格式
|
||||
if k == ast.ASTKind.Attribute:
|
||||
at: ast.Attribute | t.CPtr = (ast.Attribute | t.CPtr)(node)
|
||||
@@ -648,6 +651,23 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
|
||||
self.Gen.TypeGenCType.CTypedefResolveDepth -= 1
|
||||
if btd_ty_r is not None:
|
||||
return btd_ty_r
|
||||
# 库 typedef 兜底:stdint 等库模块的裸 typedef(UINT/DWORD/...)定义在
|
||||
# 依赖源中,_vpi_register_typedef_closure 因时序/上下文未成功注入当前
|
||||
# 文件 CTypedef 表时,直接读库源注册并解析(testcheck.SetConsoleOutputCP
|
||||
# 的 UINT 退化为 i8* 根因)。这是按权威源恢复正确类型,非静默降级。
|
||||
lib_ts: str = self._lookup_library_typedef(pool, "stdint", name)
|
||||
if lib_ts is None:
|
||||
lib_ts = self._lookup_library_typedef(pool, "w32.win32base", name)
|
||||
if lib_ts is not None:
|
||||
lib_node: ast.AST | t.CPtr = 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: llvmlite.LLVMType | t.CPtr = 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: memhub.MemBuddy | t.CPtr,
|
||||
name: str,
|
||||
@@ -721,7 +741,10 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
|
||||
self.Gen.TypeGenCType.ImportAliasBuf = stdlib.malloc(256)
|
||||
if self.Gen.TypeGenCType.ImportAliasBuf is None:
|
||||
return
|
||||
self.Gen.TypeGenCType.ImportAliasBuf[0] = '\0'
|
||||
# 整体清零:别名段以空 alias('\0')终结,_resolve_import_alias 靠
|
||||
# 末尾 '\0' 判定结束。只写 buf[0]='\0' 会导致追加后残留垃圾字节,
|
||||
# 遍历读到未写入区域 → 越界读(ASan heap-buffer-overflow)。
|
||||
string.memset(self.Gen.TypeGenCType.ImportAliasBuf, 0, 256)
|
||||
buf: bytes = self.Gen.TypeGenCType.ImportAliasBuf
|
||||
al_len: t.CSizeT = string.strlen(alias)
|
||||
tg_len: t.CSizeT = string.strlen(target)
|
||||
@@ -736,7 +759,8 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
|
||||
while buf[cur] != '\0':
|
||||
cur += 1
|
||||
cur += 1 # 跳过 target 段的 '\0'
|
||||
if cur + al_len + tg_len + 2 > 256:
|
||||
# +3 = alias + '\0' + target + '\0' + 空 alias 终结 '\0'
|
||||
if cur + al_len + tg_len + 3 > 256:
|
||||
return
|
||||
string.strcpy(buf + cur, alias)
|
||||
cur += al_len
|
||||
@@ -1499,6 +1523,17 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
|
||||
sub: ast.Subscript | t.CPtr = (ast.Subscript | t.CPtr)(node)
|
||||
if sub.value is None:
|
||||
return None
|
||||
# rowptr[T] 是内建裸指针(等价 t.CPtr[T]),AnnotClassName 应取 pointee
|
||||
# 类名 T(字段访问按 T 查结构体),而非 "rowptr" / "rowptr[T]"——否则
|
||||
# lookup_field_by_class 报"类 'rowptr' 未注册"(json.__parser _peek
|
||||
# 参数 s: rowptr[ParseState] 根因)。
|
||||
if sub.value.kind() == ast.ASTKind.Name:
|
||||
rp_nm: ast.Name | t.CPtr = (ast.Name | t.CPtr)(sub.value)
|
||||
if rp_nm.id is not None and string.strcmp(rp_nm.id, "rowptr") == 0:
|
||||
if sub.slice is not None:
|
||||
return self.extract_class_name_from_annotation(
|
||||
sub.slice, imported_modules, pool, from_imports)
|
||||
return None
|
||||
base_name: str = self.extract_class_name_from_annotation(sub.value, imported_modules, pool)
|
||||
if base_name is None:
|
||||
return None
|
||||
@@ -1692,6 +1727,14 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
|
||||
gen_spec_ty = self.Gen.StructGen.get_struct_type(gen_mangled)
|
||||
if gen_spec_ty is not None:
|
||||
return gen_spec_ty
|
||||
else:
|
||||
VLogger.info(f"[GENERIC-DBG] 特化失败(返回 None): {gen_cls_name}[{gen_mangled}]", "Phase1")
|
||||
else:
|
||||
VLogger.info(f"[GENERIC-DBG] 类型实参提取失败: {gen_cls_name}", "Phase1")
|
||||
else:
|
||||
VLogger.info(f"[GENERIC-DBG] 模板未注册: {gen_cls_name}", "Phase1")
|
||||
else:
|
||||
VLogger.info(f"[GENERIC-DBG] trans 为 None: {gen_cls_name}", "Phase1")
|
||||
# 未特化:返回 None(不报错,让后续流程处理)
|
||||
return None
|
||||
def resolve_annotation_type(self, pool: memhub.MemBuddy | t.CPtr,
|
||||
@@ -1901,6 +1944,20 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
|
||||
pool, btd_node_n, imported_modules, from_imports, trans, depth + 1)
|
||||
if btd_ty_n is not None:
|
||||
return btd_ty_n
|
||||
# 库 typedef 兜底:stdint / w32.win32base 等库模块的裸 typedef
|
||||
# (BYTEPTR/DWORD/HANDLE/LPCSTR/...)定义在依赖源中,_vpi_register_typedef_closure
|
||||
# 因时序/上下文未注入时,直接读库源注册并解析(string.vp BYTEPTR、
|
||||
# win32process STARTUPINFOA 字段 HANDLE 根因)。与 resolve_typedef_or_map 同口径。
|
||||
lib_ts_n: str = self._lookup_library_typedef(pool, "stdint", nm.id)
|
||||
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: ast.AST | t.CPtr = self._parse_type_string(pool, lib_ts_n, nm.ctx)
|
||||
if lib_node_n is not None:
|
||||
lib_ty_n: llvmlite.LLVMType | t.CPtr = 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
|
||||
return None
|
||||
|
||||
# Attribute 节点: t.CInt, t.CUInt64T, namespace_defs.PlainStruct 等
|
||||
@@ -2073,6 +2130,21 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
|
||||
mapped_ty_na: llvmlite.LLVMType | t.CPtr = self.map_t_type(pool, at.attr)
|
||||
if mapped_ty_na is not None:
|
||||
return mapped_ty_na
|
||||
# 嵌套模块限定 typedef 兜底(w32.win32base.HANDLE = t.CTypedef =
|
||||
# VOIDPTR):与单层 Module.Typedef 分支同口径,但 value 是嵌套
|
||||
# Attribute,需先拼完整模块路径(w32.win32base)再读库源扫描注册。
|
||||
# 缺失则 w32.win32base.HANDLE 字段解析失败 → File 整类 defer →
|
||||
# 裸名 File(...) 构造检测 find_struct 落空 → 外部函数 fail-fast。
|
||||
mod_path_na: str = self.Gen.ExprGenAttr._attr_module_path_str(pool, at.value)
|
||||
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: ast.AST | t.CPtr = self._parse_type_string(pool, lib_td_na, at.ctx)
|
||||
if td_node_na is not None:
|
||||
td_ty_na: llvmlite.LLVMType | t.CPtr = 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
|
||||
return None
|
||||
|
||||
# BinOp 节点: 联合类型注解 A | B
|
||||
@@ -2292,6 +2364,18 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
|
||||
if self.Gen.TypeGenCType.ConstEvalOk == 0 or count_n <= 0:
|
||||
return None
|
||||
return llvmlite.Array(pool, elem_ty_n, count_n)
|
||||
# rowptr[T] 内建裸指针:等价 t.CPtr[T] → Ptr(T)(T 自身可含指针层级)。
|
||||
# 与 t.CPtr[T](下方 L2375 附近)语义一致;此前 rowptr[T] 走泛型特化
|
||||
# / builtins 兜底失败 → "函数返回类型解析失败:注解不可解析"
|
||||
# (ast.__init__.parse -> rowptr[AST] 根因)。
|
||||
if string.strcmp(gen_nm.id, "rowptr") == 0:
|
||||
if sub.slice.kind() != ast.ASTKind.Tuple:
|
||||
rp_elem: llvmlite.LLVMType | t.CPtr = 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: llvmlite.LLVMType | t.CPtr = self._resolve_generic_subscript_ty(
|
||||
pool, sub, gen_nm.id, trans,
|
||||
imported_modules, from_imports, depth + 1)
|
||||
|
||||
Reference in new issue
Block a user