fix(tpv-expr): list 内置内联按元素原型类 load,支持链式 get(0).method() 分派
This commit is contained in:
1 parent
709c3570fb
commit
82558bd86b
1 file changed
+88
-4
@@ -461,12 +461,96 @@ class ExprGenName(ExprGenBase.ExprGenBase):
|
||||
return llvmlite.Ptr(pool, i8_ty_d)
|
||||
if string.strstr(struct_name, "list[CPtr]") is not None:
|
||||
return llvmlite.Ptr(pool, i8_ty_d)
|
||||
# 未知 list[T] 元素类型(如 list[Foo]、list[AST|t.CPtr]):元素存储为
|
||||
# 8 字节槽(指针或 8 字节整数),回退 Ptr(i8) 位宽一致(load 8 字节),
|
||||
# 由 AnnotClassName/特化恢复机制保证语义。禁止 fail-fast(误杀合法
|
||||
# 自定义类元素列表的下标访问)。
|
||||
# 未知 list[T] 元素类型(自定义结构体元素,如
|
||||
# list[rowptr[7565e081d88517ac.AST]] / list[sha1.Foo|t.CPtr]):
|
||||
# 元素槽存对象指针(8 字节)。从元素类型文本还原对象指针 LLVM 类型
|
||||
# Ptr(%Struct),使 list.get/__getitem__/pop 内联返回值的 LLVM 类型
|
||||
# 携带元素原型类——链式方法调用(mod.children.get(0).kind())的接收者
|
||||
# 才能经 LLVM 类型解析出类名 AST(T29 修复);否则统一 Ptr(i8) 丢失
|
||||
# 类名,.kind() 被当未绑定外部函数(AstTest NewAstTest fatal: 'kind'
|
||||
# 根因:list 元素类名没有沿 get(0) 调用结果值类型传播到后续分派)。
|
||||
elem_obj_ty_l: llvmlite.LLVMType | t.CPtr = \
|
||||
self._list_elem_obj_ty_from_struct_name(pool, struct_name)
|
||||
if elem_obj_ty_l is not None:
|
||||
return elem_obj_ty_l
|
||||
# 结构体未注册(依赖模块未就绪等):回退 Ptr(i8)(8 字节槽位宽一致,
|
||||
# load 值正确),由 AnnotClassName/方法分派回退机制保证语义。
|
||||
# 禁止 fail-fast(误杀合法自定义类元素列表的访问)。
|
||||
return llvmlite.Ptr(pool, i8_ty_d)
|
||||
# ============================================================
|
||||
# _list_elem_obj_ty_from_struct_name — 从 list 特化类型名还原元素对象指针类型
|
||||
#
|
||||
# struct_name 形如 "{_list_sha1}.list[rowptr[{sha1}.AST]]" 或
|
||||
# "{_list_sha1}.list[{sha1}.AST|t.CPtr]"(联合元素)。取 '[' 与最后 ']'
|
||||
# 之间的元素描述文本:剥 rowptr[...] 包装、按 '|' 联合分段、去首尾空白,
|
||||
# 逐段按已注册结构体还原(元素类带模块 SHA1 前缀时 find_struct 走
|
||||
# find_struct_by_module 精确匹配,规避跨模块同名歧义);命中返回
|
||||
# llvmlite.Ptr(entry.Ty)(list 元素槽 8 字节存对象指针)。全部未命中
|
||||
# 返回 None(调用方回退 Ptr(i8) 旧行为,不影响已支持的内置元素)。
|
||||
# ============================================================
|
||||
def _list_elem_obj_ty_from_struct_name(self, pool: memhub.MemBuddy | t.CPtr,
|
||||
struct_name: str) -> llvmlite.LLVMType | t.CPtr:
|
||||
"""从 list 特化类型名还原元素对象指针 LLVM 类型,失败返回 None"""
|
||||
if pool is None or struct_name is None:
|
||||
return None
|
||||
lb_e: str = string.strchr(struct_name, '[')
|
||||
if lb_e is None:
|
||||
return None
|
||||
rb_e: str = string.strrchr(struct_name, ']')
|
||||
if rb_e is None:
|
||||
return None
|
||||
elen_e: t.CSizeT = t.CSizeT(t.CUInt64T(rb_e) - t.CUInt64T(lb_e)) - 1
|
||||
if elen_e == 0 or elen_e > 512:
|
||||
return None
|
||||
elem_buf_e: str = pool.alloc(elen_e + 1)
|
||||
if elem_buf_e is None:
|
||||
return None
|
||||
string.strncpy(elem_buf_e, lb_e + 1, elen_e)
|
||||
elem_buf_e[elen_e] = '\0'
|
||||
# 剥 rowptr[...] 包装(元素声明为对象指针,如 rowptr[sha1.AST])
|
||||
cur_e: str = elem_buf_e
|
||||
if string.strncmp(cur_e, "rowptr[", 7) == 0:
|
||||
cur_e = cur_e + 7
|
||||
# 按 '|' 联合分段(A|B),段内去首尾空白/尾部 ']'/引号;段文本直接
|
||||
# 交给 find_struct(内置名 CPtr/str/int 等不注册 struct → 天然返回
|
||||
# None 跳过;带 "sha1.Class" 前缀走模块归属精确匹配)
|
||||
total_e: t.CSizeT = string.strlen(cur_e)
|
||||
seg_s_e: t.CSizeT = 0
|
||||
i_e: t.CSizeT = 0
|
||||
while i_e <= total_e:
|
||||
hit_e: int = 0
|
||||
if i_e == total_e:
|
||||
hit_e = 1
|
||||
elif cur_e[i_e] == '|':
|
||||
hit_e = 1
|
||||
if hit_e == 0:
|
||||
i_e += 1
|
||||
continue
|
||||
b_e: t.CSizeT = i_e
|
||||
a_e: t.CSizeT = seg_s_e
|
||||
while b_e > a_e and (cur_e[b_e - 1] == ' ' or cur_e[b_e - 1] == ']' \
|
||||
or cur_e[b_e - 1] == '\'' or cur_e[b_e - 1] == '"'):
|
||||
b_e -= 1
|
||||
while a_e < b_e and (cur_e[a_e] == ' ' or cur_e[a_e] == '\'' \
|
||||
or cur_e[a_e] == '"'):
|
||||
a_e += 1
|
||||
if b_e > a_e:
|
||||
seg_len_e: t.CSizeT = b_e - a_e
|
||||
if seg_len_e < 256:
|
||||
seg_buf_e: str = pool.alloc(seg_len_e + 1)
|
||||
if seg_buf_e is not None:
|
||||
string.strncpy(seg_buf_e, cur_e + a_e, seg_len_e)
|
||||
seg_buf_e[seg_len_e] = '\0'
|
||||
s_entry_e: GenTypes.StructEntry | t.CPtr = \
|
||||
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)
|
||||
if i_e == total_e:
|
||||
break
|
||||
seg_s_e = i_e + 1
|
||||
i_e += 1
|
||||
return None
|
||||
# ============================================================
|
||||
# list_setitem_inline — 内联生成 list[T] __setitem__ 逻辑
|
||||
#
|
||||
# 直接存储 rhs_val 到元素地址 (coerce 为 i8* 后 store)
|
||||
|
||||
Reference in new issue
Block a user