fix(len): opaque list 特化按字节偏移读取 __count__

特化结构体尚未展开布局时,先 bitcast 到 i8* 再按偏移 8 读取 __count__,避免 opaque struct 的 getelementptr 失败。
This commit is contained in:
TermiNexus committed 2026-10-18 17:29:44 +08:00
1 parent 4346e3fb27
commit 0f1a2e9fbb
2 files changed
+22 -10

No files matched your search

+11 -5
View File
@@ -738,12 +738,18 @@ class ExprBuiltinHandle(BaseHandle):
if result is not None:
return result
if _matched_cn.startswith('list['):
_count_off: int | None = Gen._get_member_offset('__count__', _matched_cn, pointee)
try:
_count_off: int | None = Gen._get_member_offset('__count__', _matched_cn, pointee)
except Exception:
# 特化结构体尚未展开布局(opaque):_list.vp 的 list 依次为
# __data__(ptr) / __count__ / __capacity__ / __pool__ / ...
_count_off = 8
if _count_off is not None:
_count_ptr = Gen.builder.gep(
val,
[ir.Constant(ir.IntType(32), 0), ir.Constant(ir.IntType(32), _count_off)],
name='list_count_ptr')
_i8p = Gen.builder.bitcast(val, ir.PointerType(ir.IntType(8)), name='list_i8p')
_count_addr = Gen.builder.gep(
_i8p, [ir.Constant(ir.IntType(64), _count_off)], name='list_count_addr')
_count_ptr = Gen.builder.bitcast(
_count_addr, ir.PointerType(ir.IntType(64)), name='list_count_ptr')
return Gen._load(_count_ptr, name='list_count')
self._FailFastLenUnsupported(arg_node, Gen, val, f"len() 参数类型 '{_matched_cn}' 没有 __len__ 方法")
else:
+11 -5
View File
@@ -4121,12 +4121,18 @@ class ExprCallHandle(BaseHandle):
if result is not None:
return result
if _matched_cn.startswith('list['):
_count_off: int | None = Gen._get_member_offset('__count__', _matched_cn, pointee)
try:
_count_off: int | None = Gen._get_member_offset('__count__', _matched_cn, pointee)
except Exception:
# 特化结构体尚未展开布局(opaque):_list.vp 的 list 依次为
# __data__(ptr) / __count__ / __capacity__ / __pool__ / ...
_count_off = 8
if _count_off is not None:
_count_ptr = Gen.builder.gep(
val,
[ir.Constant(ir.IntType(32), 0), ir.Constant(ir.IntType(32), _count_off)],
name='list_count_ptr')
_i8p = Gen.builder.bitcast(val, ir.PointerType(ir.IntType(8)), name='list_i8p')
_count_addr = Gen.builder.gep(
_i8p, [ir.Constant(ir.IntType(64), _count_off)], name='list_count_addr')
_count_ptr = Gen.builder.bitcast(
_count_addr, ir.PointerType(ir.IntType(64)), name='list_count_ptr')
return Gen._load(_count_ptr, name='list_count')
self._FailFastLenUnsupported(arg_node, Gen, val, f"len() 参数类型 '{_matched_cn}' 没有 __len__ 方法")
else: