refactor(tpv): 新语法 R10(反斜杠续行合并)+ 回退 R5(语义不等价)
- 反斜杠续行合并为单行(304 处),呼应"尽可能不换行"。 - 回退 c.DerefAs(p, v) → *p = v 两处(StructGenMixin):原写法是 bitcast 后 store 指针位,新写法按 pointee 值类型赋值,类型不符(i8* → List 值), 语义不等价,保留 c.DerefAs。 种子自举通过。
This commit is contained in:
1 parent
185a2196ca
commit
30a3da4cd4
43 files changed
+305
-707
No files matched your search
@@ -946,9 +946,7 @@ def _CollectObjFilesImpl(base_dir: str, bd_len: sizet,
|
||||
_mbuddy.free(sub_dir)
|
||||
else:
|
||||
# 检查是否是 .obj 文件
|
||||
if fname_len > 4 and fname[fname_len - 4] == '.' \
|
||||
and fname[fname_len - 3] == 'o' and fname[fname_len - 2] == 'b' \
|
||||
and fname[fname_len - 1] == 'j':
|
||||
if fname_len > 4 and fname[fname_len - 4] == '.' and fname[fname_len - 3] == 'o' and fname[fname_len - 2] == 'b' and fname[fname_len - 1] == 'j':
|
||||
need: sizet = bd_len + 1 + fname_len + 2
|
||||
if out_pos + need >= out_size:
|
||||
break
|
||||
@@ -1162,8 +1160,7 @@ def asm_to_obj(asm_path: str, sha1_val: str, output_dir: str,
|
||||
trip: str = triple
|
||||
if trip is None or trip[0] == '\0':
|
||||
trip = "x86_64-none-elf"
|
||||
cmd_len: sizet = len("llvm-mc -triple=") + len(trip) \
|
||||
+ len(" -filetype=obj -o ") + len(obj_path) + len(asm_path) + 64
|
||||
cmd_len: sizet = len("llvm-mc -triple=") + len(trip) + len(" -filetype=obj -o ") + len(obj_path) + len(asm_path) + 64
|
||||
cmd: bytes = _mbuddy.alloc(cmd_len)
|
||||
if cmd is None:
|
||||
return 1
|
||||
@@ -1923,9 +1920,7 @@ def _tb_read_pe_layout(mb: memhub.MemBuddy*, exe_path: str) -> TbPeLayout*:
|
||||
have_sec = 1
|
||||
if va < min_rva:
|
||||
min_rva = va
|
||||
if _tb_cc(head, base) == 46 and _tb_cc(head, base + 1) == 116 \
|
||||
and _tb_cc(head, base + 2) == 101 and _tb_cc(head, base + 3) == 120 \
|
||||
and _tb_cc(head, base + 4) == 116:
|
||||
if _tb_cc(head, base) == 46 and _tb_cc(head, base + 1) == 116 and _tb_cc(head, base + 2) == 101 and _tb_cc(head, base + 3) == 120 and _tb_cc(head, base + 4) == 116:
|
||||
text_rva = va
|
||||
found_text = 1
|
||||
si += 1
|
||||
@@ -2266,8 +2261,7 @@ def _tb_grp_get(grp: bytes, cap: int, caller: str, callee: str, do_insert: int)
|
||||
return slot
|
||||
sc: str = rawptr(_tb_rd_u64(grp, off + TB_GRP_OFF_CALLER))
|
||||
sk: str = rawptr(_tb_rd_u64(grp, off + TB_GRP_OFF_CALLEE))
|
||||
if sc is not None and sk is not None \
|
||||
and string.strcmp(sc, caller) == 0 and string.strcmp(sk, callee) == 0:
|
||||
if sc is not None and sk is not None and string.strcmp(sc, caller) == 0 and string.strcmp(sk, callee) == 0:
|
||||
return slot
|
||||
i += 1
|
||||
return -1
|
||||
@@ -2635,8 +2629,7 @@ def _tb_scan_objdump(mb: memhub.MemBuddy*, dump: str, img_lo: uint64,
|
||||
p += 1
|
||||
tl: sizet = p - ts
|
||||
ishex: int = 0
|
||||
if tl == 2 and _tb_hex_digit(_tb_cc(dump, ts)) >= 0 \
|
||||
and _tb_hex_digit(_tb_cc(dump, ts + 1)) >= 0:
|
||||
if tl == 2 and _tb_hex_digit(_tb_cc(dump, ts)) >= 0 and _tb_hex_digit(_tb_cc(dump, ts + 1)) >= 0:
|
||||
ishex = 1
|
||||
ms = ts
|
||||
if ishex == 0:
|
||||
|
||||
@@ -213,14 +213,12 @@ def _BufHasGenericClassMarker(buf: bytes, blen: sizet) -> int:
|
||||
return 0
|
||||
pos: sizet = 0
|
||||
while pos + 5 < blen:
|
||||
if buf[pos] == 'c' and buf[pos + 1] == 'l' and buf[pos + 2] == 'a' \
|
||||
and buf[pos + 3] == 's' and buf[pos + 4] == 's':
|
||||
if buf[pos] == 'c' and buf[pos + 1] == 'l' and buf[pos + 2] == 'a' and buf[pos + 3] == 's' and buf[pos + 4] == 's':
|
||||
# class 前是词边界(行首或非标识符字符)
|
||||
prev_ok: int = 1
|
||||
if pos > 0:
|
||||
pc: char = buf[pos - 1]
|
||||
if(pc >= 'a' and pc <= 'z') or(pc >= 'A' and pc <= 'Z') \
|
||||
or(pc >= '0' and pc <= '9') or pc == '_':
|
||||
if(pc >= 'a' and pc <= 'z') or(pc >= 'A' and pc <= 'Z') or(pc >= '0' and pc <= '9') or pc == '_':
|
||||
prev_ok = 0
|
||||
if prev_ok != 0:
|
||||
p: sizet = pos + 5
|
||||
@@ -263,8 +261,7 @@ def _BufHasGenericFuncMarker(buf: bytes, blen: sizet) -> int:
|
||||
prev_ok: int = 1
|
||||
if pos > 0:
|
||||
pc: char = buf[pos - 1]
|
||||
if(pc >= 'a' and pc <= 'z') or(pc >= 'A' and pc <= 'Z') \
|
||||
or(pc >= '0' and pc <= '9') or pc == '_':
|
||||
if(pc >= 'a' and pc <= 'z') or(pc >= 'A' and pc <= 'Z') or(pc >= '0' and pc <= '9') or pc == '_':
|
||||
prev_ok = 0
|
||||
if prev_ok != 0:
|
||||
p: sizet = pos + 3
|
||||
@@ -335,8 +332,7 @@ def _PreRegisterAllGenericTemplates(mb: memhub.MemBuddy*,
|
||||
src_buf_pg[bytes_read_pg] = 0
|
||||
# 文本扫描筛选:非泛型文件跳过(不 parse、不驻留,防 OOM)。
|
||||
# 泛型类(class X[)与泛型函数(def f[)任一命中即进入 parse。
|
||||
if _BufHasGenericClassMarker(src_buf_pg, bytes_read_pg) == 0 \
|
||||
and _BufHasGenericFuncMarker(src_buf_pg, bytes_read_pg) == 0:
|
||||
if _BufHasGenericClassMarker(src_buf_pg, bytes_read_pg) == 0 and _BufHasGenericFuncMarker(src_buf_pg, bytes_read_pg) == 0:
|
||||
stdlib.free(src_buf_pg)
|
||||
continue
|
||||
# 泛型文件:永久池解析 → 注册模板(节点/表进 perm_pool,跨 reset 存活)
|
||||
|
||||
@@ -116,8 +116,7 @@ def _ScanDirForPyFiles(mb: memhub.MemBuddy*,
|
||||
break
|
||||
continue
|
||||
# 检查是否是 .vp 源文件(Viper 源仅 .vp,不再识别 .py)
|
||||
if fname_len > 3 and Utils.is_vp_at(fname, 0, fname_len) != 0 \
|
||||
and file_count < max_files:
|
||||
if fname_len > 3 and Utils.is_vp_at(fname, 0, fname_len) != 0 and file_count < max_files:
|
||||
full_path: bytes = Utils.JoinPath(dir_path, fname)
|
||||
if full_path is not None:
|
||||
sbuf: bytes = Utils.read_file_to_buf(full_path, SRC_BUF_SIZE)
|
||||
@@ -891,8 +890,7 @@ def RunMultiFileProject(mb: memhub.MemBuddy*,
|
||||
for i_app_inc in range(file_count):
|
||||
ea_app_inc: uint64 = uint64(entries) + i_app_inc * entry_size
|
||||
ent_app_inc: SrcFileEntry* = (SrcFileEntry*)(ea_app_inc)
|
||||
if ent_app_inc is not None and ent_app_inc.Sha1 is not None \
|
||||
and string.strcmp(ent_app_inc.Sha1, inc_sha1_pre) == 0:
|
||||
if ent_app_inc is not None and ent_app_inc.Sha1 is not None and string.strcmp(ent_app_inc.Sha1, inc_sha1_pre) == 0:
|
||||
is_app_file_inc = 1
|
||||
break
|
||||
if is_app_file_inc != 0 and inc_fail_flags is not None:
|
||||
@@ -921,8 +919,7 @@ def RunMultiFileProject(mb: memhub.MemBuddy*,
|
||||
inc_fail_flags[si_inc] = 0
|
||||
# 依赖填充只在第一遍执行(PopulateIncludesDeps 内部有去重)
|
||||
# 注意:必须在 reset_to(mark2) 之前调用——内部深拷贝到 stdlib
|
||||
if pass_inc_i == 0 and tr_inc_pre._imported_modules is not None \
|
||||
and StubMergerStore.PopulateIncludesDeps(
|
||||
if pass_inc_i == 0 and tr_inc_pre._imported_modules is not None and StubMergerStore.PopulateIncludesDeps(
|
||||
inc_sha1_pre, tr_inc_pre._imported_modules) == 0:
|
||||
deps_filled_pre = deps_filled_pre + 1
|
||||
# OOM 清理:回收本 includes 文件预注册翻译的瞬时数据
|
||||
|
||||
@@ -172,10 +172,7 @@ def PathToModuleName(path: str, strip_includes_prefix: int) -> str:
|
||||
if plen > 9:
|
||||
tail_off: sizet = path_start + plen - 9
|
||||
sep_char: char = path[tail_off]
|
||||
if (sep_char == '/' or sep_char == '\\') \
|
||||
and path[tail_off + 1] == '_' and path[tail_off + 2] == '_' \
|
||||
and path[tail_off + 3] == 'i' and path[tail_off + 4] == 'n' and path[tail_off + 5] == 'i' \
|
||||
and path[tail_off + 6] == 't' and path[tail_off + 7] == '_' and path[tail_off + 8] == '_':
|
||||
if (sep_char == '/' or sep_char == '\\') and path[tail_off + 1] == '_' and path[tail_off + 2] == '_' and path[tail_off + 3] == 'i' and path[tail_off + 4] == 'n' and path[tail_off + 5] == 'i' and path[tail_off + 6] == 't' and path[tail_off + 7] == '_' and path[tail_off + 8] == '_':
|
||||
# 去掉 分隔符+__init__ 后缀,plen 就是包名部分长度
|
||||
plen = tail_off - path_start
|
||||
if plen == 0:
|
||||
|
||||
@@ -818,8 +818,7 @@ def _GeneratePyiFromAst(mb: memhub.MemBuddy*, tree: ast.AST*,
|
||||
stmt_pc0: ast.AST* = pre_children.get(pci0)
|
||||
if stmt_pc0 is not None and stmt_pc0.kind() == ast.ASTKind.AnnAssign:
|
||||
aa_pc0: ast.AnnAssign* = ast.AnnAssign*(stmt_pc0)
|
||||
if aa_pc0.target is not None and aa_pc0.target.kind() == ast.ASTKind.Name \
|
||||
and aa_pc0.annotation is not None:
|
||||
if aa_pc0.target is not None and aa_pc0.target.kind() == ast.ASTKind.Name and aa_pc0.annotation is not None:
|
||||
tgt_pc0: ast.Name* = ast.Name*(aa_pc0.target)
|
||||
if tgt_pc0.id is not None and aa_pc0.annotation.kind() == ast.ASTKind.Attribute:
|
||||
ann_pc0: ast.Attribute* = ast.Attribute*(aa_pc0.annotation)
|
||||
@@ -835,8 +834,7 @@ def _GeneratePyiFromAst(mb: memhub.MemBuddy*, tree: ast.AST*,
|
||||
stmt_pc: ast.AST* = pre_children.get(pci)
|
||||
if stmt_pc is not None and stmt_pc.kind() == ast.ASTKind.AnnAssign:
|
||||
aa_pc: ast.AnnAssign* = ast.AnnAssign*(stmt_pc)
|
||||
if aa_pc.target is not None and aa_pc.target.kind() == ast.ASTKind.Name \
|
||||
and aa_pc.annotation is not None:
|
||||
if aa_pc.target is not None and aa_pc.target.kind() == ast.ASTKind.Name and aa_pc.annotation is not None:
|
||||
tgt_pc: ast.Name* = ast.Name*(aa_pc.target)
|
||||
if tgt_pc.id is not None and aa_pc.annotation.kind() == ast.ASTKind.Attribute:
|
||||
ann_pc: ast.Attribute* = ast.Attribute*(aa_pc.annotation)
|
||||
@@ -1052,8 +1050,7 @@ def _GeneratePyiFromAst(mb: memhub.MemBuddy*, tree: ast.AST*,
|
||||
# UnaryOp(USub, Constant(1)) → -1
|
||||
uop_cv: ast.UnaryOp* = ast.UnaryOp*(aa.value)
|
||||
num_buf_u: bytes = mb.alloc(32)
|
||||
if uop_cv.op == ast.OpKind.USub and uop_cv.operand is not None \
|
||||
and uop_cv.operand.kind() == ast.ASTKind.Constant:
|
||||
if uop_cv.op == ast.OpKind.USub and uop_cv.operand is not None and uop_cv.operand.kind() == ast.ASTKind.Constant:
|
||||
uop_const: ast.Constant* = ast.Constant*(uop_cv.operand)
|
||||
if uop_const.const_kind == ast.CONST_INT and num_buf_u is not None:
|
||||
neg_val: int64 = -uop_const.int_val
|
||||
@@ -1086,8 +1083,7 @@ def _GeneratePyiFromAst(mb: memhub.MemBuddy*, tree: ast.AST*,
|
||||
elif arg_kind == ast.ASTKind.UnaryOp:
|
||||
uop_ca: ast.UnaryOp* = ast.UnaryOp*(first_arg)
|
||||
num_buf_cu: bytes = mb.alloc(32)
|
||||
if uop_ca.op == ast.OpKind.USub and uop_ca.operand is not None \
|
||||
and uop_ca.operand.kind() == ast.ASTKind.Constant:
|
||||
if uop_ca.op == ast.OpKind.USub and uop_ca.operand is not None and uop_ca.operand.kind() == ast.ASTKind.Constant:
|
||||
uoc: ast.Constant* = ast.Constant*(uop_ca.operand)
|
||||
if uoc.const_kind == ast.CONST_INT and num_buf_cu is not None:
|
||||
neg_c_val: int64 = -uoc.int_val
|
||||
@@ -1106,8 +1102,7 @@ def _GeneratePyiFromAst(mb: memhub.MemBuddy*, tree: ast.AST*,
|
||||
# 递归计算 BinOp 值
|
||||
binop_val_bo: int64 = _eval_binop_int(first_arg)
|
||||
num_buf_bo: bytes = mb.alloc(32)
|
||||
if (binop_val_bo != 0 or _eval_binop_valid(first_arg) != 0) \
|
||||
and num_buf_bo is not None:
|
||||
if (binop_val_bo != 0 or _eval_binop_valid(first_arg) != 0) and num_buf_bo is not None:
|
||||
viperlib.snprintf(num_buf_bo, 32, " = %lld", binop_val_bo)
|
||||
pos = _PyiEmit(buf, buf_size, pos, num_buf_bo)
|
||||
elif aa.value is not None and aa.value.kind() == ast.ASTKind.BinOp:
|
||||
|
||||
@@ -409,10 +409,7 @@ def _cache_vpi_return_annots_text(vpi_buf: bytes, src_sha1: str) -> int:
|
||||
# 无注解的特殊方法(构造/析构)跳过:它们有专门调用路径
|
||||
skip_def: int = 0
|
||||
if arrow_pos >= le and (
|
||||
string.strcmp(mname_buf, "__init__") == 0 or \
|
||||
string.strcmp(mname_buf, "__new__") == 0 or \
|
||||
string.strcmp(mname_buf, "__before_init__") == 0 or \
|
||||
string.strcmp(mname_buf, "__after_init__") == 0):
|
||||
string.strcmp(mname_buf, "__init__") == 0 or string.strcmp(mname_buf, "__new__") == 0 or string.strcmp(mname_buf, "__before_init__") == 0 or string.strcmp(mname_buf, "__after_init__") == 0):
|
||||
skip_def = 1
|
||||
if skip_def == 0:
|
||||
key_buf: bytes = stdlib.malloc(key_len + 1)
|
||||
@@ -427,8 +424,7 @@ def _cache_vpi_return_annots_text(vpi_buf: bytes, src_sha1: str) -> int:
|
||||
# 索引快速路径:索引可信(Built==Count)时一次探测判定
|
||||
# 重复(命中即"首个注册优先"= 原线性扫描首个同名);
|
||||
# 未命中 | 索引不可信 → 回退原线性扫描(正确性保证)。
|
||||
if _g_vpi_ret_idx_built == _g_vpi_ret_count \
|
||||
and _g_vpi_ret_idx is not None and _g_vpi_ret_idx_cap > 0:
|
||||
if _g_vpi_ret_idx_built == _g_vpi_ret_count and _g_vpi_ret_idx is not None and _g_vpi_ret_idx_cap > 0:
|
||||
if _vpi_idx_find(_g_vpi_ret_keys, VPI_KEY_LEN,
|
||||
_g_vpi_ret_idx, _g_vpi_ret_idx_cap, key_buf) >= 0:
|
||||
dup_key = 1
|
||||
@@ -452,8 +448,7 @@ def _cache_vpi_return_annots_text(vpi_buf: bytes, src_sha1: str) -> int:
|
||||
_g_vpi_ret_count += 1
|
||||
# 同步索引:仅当插入前可信(Built==Count-1,含扩容
|
||||
# 重建后)且插入成功;否则标记不可信(查找回退扫描)。
|
||||
if _g_vpi_ret_idx_built == _g_vpi_ret_count - 1 \
|
||||
and _vpi_idx_insert(_g_vpi_ret_idx, _g_vpi_ret_idx_cap,
|
||||
if _g_vpi_ret_idx_built == _g_vpi_ret_count - 1 and _vpi_idx_insert(_g_vpi_ret_idx, _g_vpi_ret_idx_cap,
|
||||
_g_vpi_ret_count - 1, key_buf) == 0:
|
||||
_g_vpi_ret_idx_built = _g_vpi_ret_count
|
||||
else:
|
||||
@@ -652,8 +647,7 @@ def _cache_vpi_param_annots_text(vpi_buf: bytes, src_sha1: str) -> int:
|
||||
# 索引快速路径:索引可信(Built==Count)时一次探测判定
|
||||
# 重复(命中即"首个注册优先"= 原线性扫描首个同名);
|
||||
# 未命中 | 索引不可信 → 回退原线性扫描(正确性保证)。
|
||||
if _g_vpi_param_idx_built == _g_vpi_param_count \
|
||||
and _g_vpi_param_idx is not None and _g_vpi_param_idx_cap > 0:
|
||||
if _g_vpi_param_idx_built == _g_vpi_param_count and _g_vpi_param_idx is not None and _g_vpi_param_idx_cap > 0:
|
||||
if _vpi_idx_find(_g_vpi_param_keys, VPI_PARAM_KEY_LEN,
|
||||
_g_vpi_param_idx, _g_vpi_param_idx_cap, key_buf) >= 0:
|
||||
dup_key = 1
|
||||
@@ -677,8 +671,7 @@ def _cache_vpi_param_annots_text(vpi_buf: bytes, src_sha1: str) -> int:
|
||||
_g_vpi_param_count += 1
|
||||
# 同步索引:仅当插入前可信(Built==Count-1,含扩容
|
||||
# 重建后)且插入成功;否则标记不可信(查找回退扫描)。
|
||||
if _g_vpi_param_idx_built == _g_vpi_param_count - 1 \
|
||||
and _vpi_idx_insert(_g_vpi_param_idx, _g_vpi_param_idx_cap,
|
||||
if _g_vpi_param_idx_built == _g_vpi_param_count - 1 and _vpi_idx_insert(_g_vpi_param_idx, _g_vpi_param_idx_cap,
|
||||
_g_vpi_param_count - 1, key_buf) == 0:
|
||||
_g_vpi_param_idx_built = _g_vpi_param_count
|
||||
else:
|
||||
@@ -745,8 +738,7 @@ def _lookup_vpi_param_annots(src_sha1: str, cls_name: str, method_name: str) ->
|
||||
# 扫描首个同名,首注册优先);未命中即"确无"(键表只追加、键文本注册后不改写,
|
||||
# 索引随扩容整体重建且覆盖全表)⇒ 无需再线性扫描;索引不可信 → 回退线性扫描。
|
||||
hit_p: int = -1
|
||||
if _g_vpi_param_idx_built == _g_vpi_param_count \
|
||||
and _g_vpi_param_idx is not None and _g_vpi_param_idx_cap > 0:
|
||||
if _g_vpi_param_idx_built == _g_vpi_param_count and _g_vpi_param_idx is not None and _g_vpi_param_idx_cap > 0:
|
||||
hit_p = _vpi_idx_find(_g_vpi_param_keys, VPI_PARAM_KEY_LEN,
|
||||
_g_vpi_param_idx, _g_vpi_param_idx_cap, key_buf)
|
||||
else:
|
||||
@@ -779,8 +771,7 @@ def _resolve_vpi_param_annot_seg_template(pool: memhub.MemBuddy*,
|
||||
i32_ty: mlirlite.LLVMType*,
|
||||
i8_ptr_ty: mlirlite.LLVMType*) -> mlirlite.LLVMType*:
|
||||
"""特化类 X[arg] 的参数注解段解析(模板 X[T] 注解 + T→arg 替换);未命中 None"""
|
||||
if pool is None or src_sha1 is None or cls_name is None or method_name is None \
|
||||
or _g_vpi_param_keys is None:
|
||||
if pool is None or src_sha1 is None or cls_name is None or method_name is None or _g_vpi_param_keys is None:
|
||||
return None
|
||||
lbkt_t: str = string.strchr(cls_name, 91) # '[' = 91
|
||||
if lbkt_t is None:
|
||||
@@ -835,8 +826,7 @@ def _resolve_vpi_param_annot_seg_template(pool: memhub.MemBuddy*,
|
||||
cur_seg_t += 1
|
||||
seg_start_t: sizet = cur_t
|
||||
seg_len_t: sizet = 0
|
||||
while annots_t[seg_start_t + seg_len_t] != '\0' \
|
||||
and annots_t[seg_start_t + seg_len_t] != '@':
|
||||
while annots_t[seg_start_t + seg_len_t] != '\0' and annots_t[seg_start_t + seg_len_t] != '@':
|
||||
seg_len_t += 1
|
||||
if seg_len_t == 0:
|
||||
break
|
||||
@@ -955,8 +945,7 @@ def _resolve_vpi_param_annot_seg(pool: memhub.MemBuddy*,
|
||||
cur_seg_p += 1
|
||||
seg_start_p: sizet = cur_p
|
||||
seg_len_p: sizet = 0
|
||||
while prm_annots_p[seg_start_p + seg_len_p] != '\0' \
|
||||
and prm_annots_p[seg_start_p + seg_len_p] != '@':
|
||||
while prm_annots_p[seg_start_p + seg_len_p] != '\0' and prm_annots_p[seg_start_p + seg_len_p] != '@':
|
||||
seg_len_p += 1
|
||||
if seg_len_p == 0:
|
||||
return None
|
||||
@@ -1022,8 +1011,7 @@ def _ensure_vpi_ret_annot_loaded(src_sha1: str, temp_dir: str) -> int:
|
||||
s1: int = src_sha1[1]
|
||||
for pre_i in range(_g_vpi_ret_count):
|
||||
pre_key: bytes = _g_vpi_ret_keys + pre_i * VPI_KEY_LEN
|
||||
if pre_key[0] == s0 and pre_key[1] == s1 and \
|
||||
string.strncmp(pre_key, src_sha1, sha1_len) == 0 and pre_key[sha1_len] == '.':
|
||||
if pre_key[0] == s0 and pre_key[1] == s1 and string.strncmp(pre_key, src_sha1, sha1_len) == 0 and pre_key[sha1_len] == '.':
|
||||
return 1
|
||||
# 构造路径 {temp_dir}/{sha1[0:2]}/{sha1}.vpi(逐字符拼接,避免 %c 格式化问题)
|
||||
td_len: sizet = string.strlen(temp_dir)
|
||||
@@ -1122,8 +1110,7 @@ def _ensure_vpi_param_annot_loaded(src_sha1: str, temp_dir: str) -> int:
|
||||
s1: int = src_sha1[1]
|
||||
for pre_i in range(_g_vpi_param_count):
|
||||
pre_key: bytes = _g_vpi_param_keys + pre_i * VPI_PARAM_KEY_LEN
|
||||
if pre_key[0] == s0 and pre_key[1] == s1 and \
|
||||
string.strncmp(pre_key, src_sha1, sha1_len) == 0 and pre_key[sha1_len] == '.':
|
||||
if pre_key[0] == s0 and pre_key[1] == s1 and string.strncmp(pre_key, src_sha1, sha1_len) == 0 and pre_key[sha1_len] == '.':
|
||||
return 1
|
||||
# 构造路径 {temp_dir}/{sha1[0:2]}/{sha1}.vpi(逐字符拼接,避免 %c 格式化问题)
|
||||
td_len: sizet = string.strlen(temp_dir)
|
||||
@@ -1201,12 +1188,10 @@ def _subst_template_arg(annot: str, tparam: str, targ: str) -> str:
|
||||
if p + tplen < alen:
|
||||
next_ch = annot[p + tplen]
|
||||
prev_ok: int = 1
|
||||
if (prev_ch >= 'a' and prev_ch <= 'z') or (prev_ch >= 'A' and prev_ch <= 'Z') or \
|
||||
(prev_ch >= '0' and prev_ch <= '9') or prev_ch == '_':
|
||||
if (prev_ch >= 'a' and prev_ch <= 'z') or (prev_ch >= 'A' and prev_ch <= 'Z') or (prev_ch >= '0' and prev_ch <= '9') or prev_ch == '_':
|
||||
prev_ok = 0
|
||||
next_ok: int = 1
|
||||
if (next_ch >= 'a' and next_ch <= 'z') or (next_ch >= 'A' and next_ch <= 'Z') or \
|
||||
(next_ch >= '0' and next_ch <= '9') or next_ch == '_':
|
||||
if (next_ch >= 'a' and next_ch <= 'z') or (next_ch >= 'A' and next_ch <= 'Z') or (next_ch >= '0' and next_ch <= '9') or next_ch == '_':
|
||||
next_ok = 0
|
||||
if prev_ok != 0 and next_ok != 0:
|
||||
string.strncpy(out + opos, targ, tglen)
|
||||
@@ -1249,8 +1234,7 @@ def _lookup_vpi_ret_annot(src_sha1: str, cls_name: str, method_name: str) -> str
|
||||
# 不改写,索引随扩容整体重建且覆盖全表)⇒ 跳过精确线性扫描(下方泛型特化归一化
|
||||
# 匹配兜底仍保留,其键形态不同、不依赖精确键命中);索引不可信 → 回退线性扫描。
|
||||
hit_r: int = -1
|
||||
if _g_vpi_ret_idx_built == _g_vpi_ret_count \
|
||||
and _g_vpi_ret_idx is not None and _g_vpi_ret_idx_cap > 0:
|
||||
if _g_vpi_ret_idx_built == _g_vpi_ret_count and _g_vpi_ret_idx is not None and _g_vpi_ret_idx_cap > 0:
|
||||
hit_r = _vpi_idx_find(_g_vpi_ret_keys, VPI_KEY_LEN,
|
||||
_g_vpi_ret_idx, _g_vpi_ret_idx_cap, key_buf)
|
||||
else:
|
||||
@@ -1286,10 +1270,7 @@ def _lookup_vpi_ret_annot(src_sha1: str, cls_name: str, method_name: str) -> str
|
||||
gi: int
|
||||
for gi in range(_g_vpi_ret_count):
|
||||
gk: bytes = _g_vpi_ret_keys + gi * VPI_KEY_LEN
|
||||
if string.strncmp(gk, src_sha1, sha1_len) == 0 and \
|
||||
gk[sha1_len] == '.' and \
|
||||
string.strncmp(gk + sha1_len + 1, base_v, base_len_v) == 0 and \
|
||||
gk[sha1_len + 1 + base_len_v] == '[':
|
||||
if string.strncmp(gk, src_sha1, sha1_len) == 0 and gk[sha1_len] == '.' and string.strncmp(gk + sha1_len + 1, base_v, base_len_v) == 0 and gk[sha1_len + 1 + base_len_v] == '[':
|
||||
gklb: str = string.strchr(gk + sha1_len + 1 + base_len_v, ']')
|
||||
if gklb is not None:
|
||||
tparam_len_v: sizet = sizet(
|
||||
@@ -1559,13 +1540,10 @@ def _resolve_vpi_ret_annot_str(pool: memhub.MemBuddy*,
|
||||
while mk_e > mk_s and ret_annot[mk_e - 1] == ' ':
|
||||
mk_e -= 1
|
||||
mk_off_m: sizet = 0
|
||||
if mk_e - mk_s >= 2 and (ret_annot[mk_s] == 't' or ret_annot[mk_s] == 'c') \
|
||||
and ret_annot[mk_s + 1] == '.':
|
||||
if mk_e - mk_s >= 2 and (ret_annot[mk_s] == 't' or ret_annot[mk_s] == 'c') and ret_annot[mk_s + 1] == '.':
|
||||
mk_off_m = 2
|
||||
mk_nlen: sizet = mk_e - mk_s - mk_off_m
|
||||
if (mk_nlen == 5 and string.strncmp(ret_annot + mk_s + mk_off_m, "State", 5) == 0) \
|
||||
or (mk_nlen == 7 and string.strncmp(ret_annot + mk_s + mk_off_m, "CExtern", 7) == 0) \
|
||||
or (mk_nlen == 7 and string.strncmp(ret_annot + mk_s + mk_off_m, "CExport", 7) == 0):
|
||||
if (mk_nlen == 5 and string.strncmp(ret_annot + mk_s + mk_off_m, "State", 5) == 0) or (mk_nlen == 7 and string.strncmp(ret_annot + mk_s + mk_off_m, "CExtern", 7) == 0) or (mk_nlen == 7 and string.strncmp(ret_annot + mk_s + mk_off_m, "CExport", 7) == 0):
|
||||
return mlirlite.Void(pool)
|
||||
|
||||
has_cptr: int = 0
|
||||
@@ -1652,8 +1630,7 @@ def _resolve_vpi_ret_annot_str(pool: memhub.MemBuddy*,
|
||||
cptr_sub_ty = seg_ty_cs
|
||||
elif string.strcmp(seg_buf, "t.CPtr") == 0 or string.strcmp(seg_buf, "CPtr") == 0:
|
||||
has_cptr = 1
|
||||
elif string.strcmp(seg_buf, "void") == 0 or string.strcmp(seg_buf, "CVoid") == 0 \
|
||||
or string.strcmp(seg_buf, "void") == 0:
|
||||
elif string.strcmp(seg_buf, "void") == 0 or string.strcmp(seg_buf, "CVoid") == 0 or string.strcmp(seg_buf, "void") == 0:
|
||||
# 裸名 void 是 t.CVoid 的别名(用户 2026-10-01):必须与 CVoid 同处理,
|
||||
# 否则会走 else 分支取到 first_td=1 → Ptr(Void) 这种非法类型
|
||||
# (void* 应为 i8*,由下方 has_cptr 分支统一给出)。
|
||||
@@ -1668,13 +1645,7 @@ def _resolve_vpi_ret_annot_str(pool: memhub.MemBuddy*,
|
||||
# Ptr(first_ty) → `uint64*` 两侧不一致(定义 i8* vs declare i64*)。
|
||||
if string.strchr(seg_buf, 46) is not None:
|
||||
first_qual = 1
|
||||
if string.strcmp(seg_buf, "int") == 0 or \
|
||||
string.strcmp(seg_buf, "char") == 0 or \
|
||||
string.strcmp(seg_buf, "str") == 0 or \
|
||||
string.strcmp(seg_buf, "bytes") == 0 or \
|
||||
string.strcmp(seg_buf, "bool") == 0 or \
|
||||
string.strcmp(seg_buf, "float") == 0 or \
|
||||
string.strcmp(seg_buf, "double") == 0:
|
||||
if string.strcmp(seg_buf, "int") == 0 or string.strcmp(seg_buf, "char") == 0 or string.strcmp(seg_buf, "str") == 0 or string.strcmp(seg_buf, "bytes") == 0 or string.strcmp(seg_buf, "bool") == 0 or string.strcmp(seg_buf, "float") == 0 or string.strcmp(seg_buf, "double") == 0:
|
||||
first_wl = 1
|
||||
# 裸名 typedef 别名保真(N13,与定义侧同源):sizet/uint64/INT/u32 等别名若被判「非 struct 且不在白名单」会被坍缩成 i8*,
|
||||
# 而定义侧已改为「解析成功即保留」⇒ 跨模块同型收敛被破坏。判据直接用 GenApi.resolve_typedef_or_map(与定义侧同一 API),命中即置位保留;
|
||||
@@ -2279,8 +2250,7 @@ def _ParseVpiIntoModuleImpl(pool: memhub.MemBuddy*,
|
||||
# ast/__init__.vpi 的 `parse_expression -> rawptr[Expression]`,而
|
||||
# Expression 定义在 ast.stmts,真因是子模块 sha1 查找/注入失败)。
|
||||
# 此处直接给出包名与子模块名(含补前缀后的精确名)便于定位。
|
||||
if is_pkg_init_rt != 0 and sub_sha1_rt is None \
|
||||
and sifr_mod is not None and sifr_mod[0] != '\0':
|
||||
if is_pkg_init_rt != 0 and sub_sha1_rt is None and sifr_mod is not None and sifr_mod[0] != '\0':
|
||||
GenApi.fatal_error(
|
||||
sifr,
|
||||
f"包 stub 的 from-import 子模块 sha1 查找失败:"
|
||||
@@ -2485,9 +2455,7 @@ def _ParseVpiIntoModuleImpl(pool: memhub.MemBuddy*,
|
||||
if aa.target is not None and aa.target.kind() == ast.ASTKind.Name:
|
||||
dbg_tn: ast.Name* = ast.Name*(aa.target)
|
||||
if dbg_tn.id is not None and dbg_tn.id[0] != '\0': # 存疑
|
||||
if string.strcmp(dbg_tn.id, "irq_handler_t") == 0 \
|
||||
or string.strcmp(dbg_tn.id, "gdt") == 0 \
|
||||
or string.strcmp(dbg_tn.id, "KBD_BUF_SIZE") == 0:
|
||||
if string.strcmp(dbg_tn.id, "irq_handler_t") == 0 or string.strcmp(dbg_tn.id, "gdt") == 0 or string.strcmp(dbg_tn.id, "KBD_BUF_SIZE") == 0:
|
||||
dbg_ct: int = GenApi._is_ctypedef_annotation(aa.annotation)
|
||||
dbg_cd: int = GenApi.is_cdefine_annotation(aa.annotation)
|
||||
if GenApi._is_ctypedef_annotation(aa.annotation) != 0:
|
||||
@@ -2496,8 +2464,7 @@ def _ParseVpiIntoModuleImpl(pool: memhub.MemBuddy*,
|
||||
# vpi 里 CDefine 定义(如 keyboard.vp 的 KBD_BUF_SIZE: t.CDefine = 1024)
|
||||
# 注册到当前文件 CDefine 表,供同 vpi 后续 t.CArray count 引用解析
|
||||
# (否则跨模块 count 查找 [CDEF-MISS] fail-fast,VKernel PhaseA 根因)
|
||||
if aa.target is not None and aa.target.kind() == ast.ASTKind.Name \
|
||||
and aa.value is not None:
|
||||
if aa.target is not None and aa.target.kind() == ast.ASTKind.Name and aa.value is not None:
|
||||
cdef_tgt: ast.Name* = ast.Name*(aa.target)
|
||||
if cdef_tgt.id is not None:
|
||||
# 字符串 CDefine(版本号等)跳过:extract_cdefine_int_value
|
||||
@@ -3136,8 +3103,7 @@ def _inject_global_variable_declare(pool: memhub.MemBuddy*,
|
||||
# 先制造同名的 external global 声明,随后定义端再发射 global 定义 → llc:
|
||||
# redefinition of global '@<sha1>.<name>'。与 _inject_function_declare /
|
||||
# _inject_method_declare 的自注入守卫同因同构(那两处已修,全局此处此前遗漏)。
|
||||
if trans is not None and trans._declare_only == 0 and trans.ModuleSha1 is not None \
|
||||
and src_sha1 is not None:
|
||||
if trans is not None and trans._declare_only == 0 and trans.ModuleSha1 is not None and src_sha1 is not None:
|
||||
if string.strcmp(src_sha1, trans.ModuleSha1) == 0:
|
||||
return
|
||||
# mangled 名:带源模块 SHA1 前缀(对齐定义端 5f7a873 的 @<sha1>.<name>
|
||||
@@ -3176,8 +3142,7 @@ def _inject_global_variable_declare(pool: memhub.MemBuddy*,
|
||||
# 对象类(@t.Object/@t.CVTable:对象即指针,HasNew/HasVTable/IsOOP)→ Ptr(struct),与定义端 handle_module_level_var 一致;
|
||||
# 纯 t.CStruct 值类(如 pci_device)保持值实例——一律转 Ptr 会把实例前 8 字节当指针解引用(#GP),一律保持值则 @t.Object 类模块级变量按指针访问读错 vtable(#PF)。
|
||||
gv_entry_v: GenTypes.StructEntry* = 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):
|
||||
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 = mlirlite.Ptr(pool, resolved_v)
|
||||
else:
|
||||
gv_ty_v = resolved_v
|
||||
@@ -4035,8 +4000,7 @@ def _repl_stub_deco_flags(deco_list: list[ast.AST*]*) -> int:
|
||||
k: int = deco.kind()
|
||||
if k == ast.ASTKind.Attribute:
|
||||
at: ast.Attribute* = ast.Attribute*(deco)
|
||||
if at.attr is not None and at.value is not None \
|
||||
and at.value.kind() == ast.ASTKind.Name:
|
||||
if at.attr is not None and at.value is not None and at.value.kind() == ast.ASTKind.Name:
|
||||
vn: ast.Name* = ast.Name*(at.value)
|
||||
if vn.id is not None and string.strcmp(vn.id, "t") == 0:
|
||||
nm = at.attr
|
||||
@@ -4397,9 +4361,7 @@ def _repl_stub_add_class(pool: memhub.MemBuddy*,
|
||||
e.Names = pool.alloc(8 * _REPL_STUB_FIELD_MAX)
|
||||
e.Types = pool.alloc(8 * _REPL_STUB_FIELD_MAX)
|
||||
e.VtNames = pool.alloc(8 * _REPL_STUB_VT_MAX)
|
||||
if e.OwnNames is None or e.OwnTypes is None or e.MethodNames is None \
|
||||
or e.MethodFlags is None or e.Bases is None or e.Names is None \
|
||||
or e.Types is None or e.VtNames is None:
|
||||
if e.OwnNames is None or e.OwnTypes is None or e.MethodNames is None or e.MethodFlags is None or e.Bases is None or e.Names is None or e.Types is None or e.VtNames is None:
|
||||
return 0
|
||||
string.memset(e.OwnNames, 0, 8 * _REPL_STUB_FIELD_MAX)
|
||||
string.memset(e.OwnTypes, 0, 8 * _REPL_STUB_FIELD_MAX)
|
||||
|
||||
@@ -352,8 +352,7 @@ novirtual class AssignGenMixin:
|
||||
while eq < line_start + line_len and buf[eq] == ' ':
|
||||
eq += 1
|
||||
vstart: sizet = eq
|
||||
while eq < line_start + line_len and buf[eq] != ' ' and buf[eq] != '\t' \
|
||||
and buf[eq] != '#' and buf[eq] != '\r':
|
||||
while eq < line_start + line_len and buf[eq] != ' ' and buf[eq] != '\t' and buf[eq] != '#' and buf[eq] != '\r':
|
||||
eq += 1
|
||||
if eq == vstart:
|
||||
continue
|
||||
@@ -674,8 +673,7 @@ novirtual class AssignGenMixin:
|
||||
ns: sizet = line_start
|
||||
is_define_line: int = 0
|
||||
if line_len >= 8:
|
||||
if buf[ns] == 'd' and buf[ns + 1] == 'e' and buf[ns + 2] == 'f' \
|
||||
and buf[ns + 3] == 'i' and buf[ns + 4] == 'n' and buf[ns + 5] == 'e':
|
||||
if buf[ns] == 'd' and buf[ns + 1] == 'e' and buf[ns + 2] == 'f' and buf[ns + 3] == 'i' and buf[ns + 4] == 'n' and buf[ns + 5] == 'e':
|
||||
nb: sizet = ns + 6
|
||||
while nb < line_start + line_len and (buf[nb] == ' ' or buf[nb] == '\t'):
|
||||
nb += 1
|
||||
@@ -743,8 +741,7 @@ novirtual class AssignGenMixin:
|
||||
break
|
||||
pfx_rf += 1
|
||||
val_start: sizet = eq
|
||||
while eq < line_start + line_len and buf[eq] != ' ' and buf[eq] != '\t' \
|
||||
and buf[eq] != '#' and buf[eq] != '\r' and buf[eq] != '\n':
|
||||
while eq < line_start + line_len and buf[eq] != ' ' and buf[eq] != '\t' and buf[eq] != '#' and buf[eq] != '\r' and buf[eq] != '\n':
|
||||
eq += 1
|
||||
if eq == val_start:
|
||||
continue
|
||||
@@ -1382,11 +1379,7 @@ novirtual class AssignGenMixin:
|
||||
decl: str = "(注解含 t.CConst,声明处来源名未记录)"
|
||||
if src_name is not None:
|
||||
decl = f"t.CConst | {src_name}"
|
||||
return GenApi.escape_fstring_copy(f"不能对 const 变量 '{name}' {kind}" \
|
||||
f"(声明处类型(含 const):{decl}" \
|
||||
f";修法:删掉该声明里的 const 描述符 / t.CConst,或改为声明时一次赋值、" \
|
||||
f"之后只用非 const 的副本/中间量;const 对象在其作用域内禁止赋值、" \
|
||||
f"增量赋值与元素赋值,且不会降级为警告)")
|
||||
return GenApi.escape_fstring_copy(f"不能对 const 变量 '{name}' {kind}" f"(声明处类型(含 const):{decl}" f";修法:删掉该声明里的 const 描述符 / t.CConst,或改为声明时一次赋值、" f"之后只用非 const 的副本/中间量;const 对象在其作用域内禁止赋值、" f"增量赋值与元素赋值,且不会降级为警告)")
|
||||
|
||||
def const_assign_fail(self, node: ast.AST*, kind: str,
|
||||
name: str, src_name: str) -> int:
|
||||
@@ -1484,8 +1477,7 @@ novirtual class AssignGenMixin:
|
||||
if sub_ca.value.kind() == ast.ASTKind.Name:
|
||||
nm_ca: ast.Name* = ast.Name*(sub_ca.value)
|
||||
if nm_ca.id is not None:
|
||||
ve_ca: GenTypes.VarEntry* = \
|
||||
self.Gen.VarGen.lookup_var_entry(trans.SymTab, nm_ca.id)
|
||||
ve_ca: GenTypes.VarEntry* = self.Gen.VarGen.lookup_var_entry(trans.SymTab, nm_ca.id)
|
||||
if self.Gen.VarGen.var_is_const(ve_ca) != 0:
|
||||
self.const_assign_fail(target, "的元素赋值", nm_ca.id,
|
||||
self.Gen.VarGen.var_annot_class_name(ve_ca))
|
||||
@@ -1555,8 +1547,7 @@ novirtual class AssignGenMixin:
|
||||
builder: mlirlite.IRBuilder* = trans._cur_builder
|
||||
mod: mlirlite.LLVMModule* = trans.Module
|
||||
ptr_ag: mlirlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, mod, uo_ag.operand, None, 0, trans)
|
||||
if ptr_ag is None or ptr_ag.Ty is None \
|
||||
or self.Gen.ExprGenBase.is_ptr_type(ptr_ag.Ty) == 0:
|
||||
if ptr_ag is None or ptr_ag.Ty is None or self.Gen.ExprGenBase.is_ptr_type(ptr_ag.Ty) == 0:
|
||||
self.Gen.TypeGenErr.fatal_error(target,
|
||||
"增量赋值 '*' 的操作数必须是指针类型(类型推断退化)", "TypeError")
|
||||
ty_ag: mlirlite.LLVMType* = ptr_ag.Ty.Pointee
|
||||
@@ -1597,8 +1588,7 @@ novirtual class AssignGenMixin:
|
||||
# 守卫 trans.ReplCtx:非 REPL 恒 None ⇒ 本分支整体不经过。
|
||||
# 作用域用 repl_in_frag_entry_scope(M3):被提升的会话函数体内 `x += 1`
|
||||
# 按普通局部变量路径处理(不写会话槽)。
|
||||
if trans.ReplCtx is not None \
|
||||
and self.Gen.VarGen.repl_in_frag_entry_scope(trans) != 0:
|
||||
if trans.ReplCtx is not None and self.Gen.VarGen.repl_in_frag_entry_scope(trans) != 0:
|
||||
if self.Gen.VarGen.repl_try_augassign(trans, nm.id, aug.op, aug.value, node) != 0:
|
||||
return 0
|
||||
|
||||
@@ -1663,8 +1653,7 @@ novirtual class AssignGenMixin:
|
||||
if aug_dup is not None:
|
||||
ovl_self_aug: mlirlite.Value* = target_alloca
|
||||
# 指针存储槽(Ptr(Ptr(Struct))):load 出对象指针作为 self
|
||||
if target_alloca.Ty is not None and target_alloca.Ty.Pointee != 0 \
|
||||
and self.Gen.ExprGenBase.is_ptr_type(target_alloca.Ty.Pointee) != 0:
|
||||
if target_alloca.Ty is not None and target_alloca.Ty.Pointee != 0 and self.Gen.ExprGenBase.is_ptr_type(target_alloca.Ty.Pointee) != 0:
|
||||
load_self_aug: mlirlite.Value* = mlirlite.build_load(builder, target_alloca.Ty.Pointee, target_alloca)
|
||||
if load_self_aug is not None:
|
||||
ovl_self_aug = load_self_aug
|
||||
@@ -1680,19 +1669,15 @@ novirtual class AssignGenMixin:
|
||||
aug_ovl = self.Gen.ExprGenOps._try_named_dunder(pool, builder, mod, ovl_self_aug, aug_fb, trans, aug_extra, 1)
|
||||
if aug_ovl is not None:
|
||||
aug_res: mlirlite.Value* = aug_ovl
|
||||
if target_ty is not None and aug_res.Ty is not None \
|
||||
and self.Gen.ExprGenBase._same_agg_ty(pool, aug_res.Ty, target_ty) == 0:
|
||||
if target_ty is not None and aug_res.Ty is not None and self.Gen.ExprGenBase._same_agg_ty(pool, aug_res.Ty, target_ty) == 0:
|
||||
# 目标为结构体值、返回为指针 → load 出结构体值(按值存储语义)
|
||||
if self.Gen.ExprGenBase.is_ptr_type(target_ty) == 0 \
|
||||
and self.Gen.ExprGenBase.is_ptr_type(aug_res.Ty) != 0 \
|
||||
and aug_res.Ty.Pointee != 0:
|
||||
if self.Gen.ExprGenBase.is_ptr_type(target_ty) == 0 and self.Gen.ExprGenBase.is_ptr_type(aug_res.Ty) != 0 and aug_res.Ty.Pointee != 0:
|
||||
aug_res = mlirlite.build_load(builder, aug_res.Ty.Pointee, aug_res)
|
||||
else:
|
||||
coerced_aug: mlirlite.Value* = self.Gen.ExprGenBase.coerce_to_type(builder, aug_res, target_ty, node, trans)
|
||||
if coerced_aug is not None:
|
||||
aug_res = coerced_aug
|
||||
if aug_res is None or target_ty is None \
|
||||
or self.Gen.ExprGenBase._same_agg_ty(pool, aug_res.Ty, target_ty) == 0:
|
||||
if aug_res is None or target_ty is None or self.Gen.ExprGenBase._same_agg_ty(pool, aug_res.Ty, target_ty) == 0:
|
||||
# fail-fast:重载返回值与目标变量类型不匹配,禁止静默写坏内存
|
||||
self.Gen.TypeGenErr.fatal_error(node, "增量赋值运算符重载返回值类型与目标变量不匹配", "TypeError")
|
||||
mlirlite.build_store(builder, aug_res, target_alloca, vol_aa)
|
||||
@@ -1900,8 +1885,7 @@ novirtual class AssignGenMixin:
|
||||
# 会遮蔽同名会话变量(此后读 `x` 命中空局部槽,槽值丢失)。
|
||||
# 被提升的会话函数体内不走该分支(那里按普通局部声明预建 alloca)。
|
||||
# CDefine/CTypedef 两个分支在本次返回之前,其行为不变。
|
||||
if trans.ReplCtx is not None \
|
||||
and self.Gen.VarGen.repl_in_frag_entry_scope(trans) != 0:
|
||||
if trans.ReplCtx is not None and self.Gen.VarGen.repl_in_frag_entry_scope(trans) != 0:
|
||||
return 0
|
||||
|
||||
# global/nonlocal 变量不需要局部 alloca
|
||||
@@ -2068,8 +2052,7 @@ novirtual class AssignGenMixin:
|
||||
ann_sub = ast.Subscript*(bop_ff.left)
|
||||
elif bop_ff.right is not None and bop_ff.right.kind() == ast.ASTKind.Subscript:
|
||||
ann_sub = ast.Subscript*(bop_ff.right)
|
||||
if ann_sub is None or ann_sub.value is None \
|
||||
or ann_sub.value.kind() != ast.ASTKind.Name:
|
||||
if ann_sub is None or ann_sub.value is None or ann_sub.value.kind() != ast.ASTKind.Name:
|
||||
return 0
|
||||
base_nm_ff: ast.Name* = ast.Name*(ann_sub.value)
|
||||
if base_nm_ff.id is None:
|
||||
@@ -2141,10 +2124,8 @@ novirtual class AssignGenMixin:
|
||||
# 定型后的槽类型再作为 RHS 的 target_ty(与普通 AnnAssign 的 P1-A 同口径)。
|
||||
# 守卫 trans.ReplCtx:非 REPL 恒 None ⇒ 本分支整体不经过。
|
||||
# 被提升的会话函数体内不走该分支(`x: int = 5` 是局部声明,Python 语义)。
|
||||
if trans.ReplCtx is not None \
|
||||
and self.Gen.VarGen.repl_in_frag_entry_scope(trans) != 0:
|
||||
rp_e: rawptr[GenTypes.ReplVarEntry] = \
|
||||
self.Gen.VarGen.repl_ensure_entry(trans, nm.id, aa)
|
||||
if trans.ReplCtx is not None and self.Gen.VarGen.repl_in_frag_entry_scope(trans) != 0:
|
||||
rp_e: rawptr[GenTypes.ReplVarEntry] = self.Gen.VarGen.repl_ensure_entry(trans, nm.id, aa)
|
||||
if rp_e is not None:
|
||||
self.Gen.VarGen.repl_try_annassign(trans, nm.id, aa.annotation, aa.value, aa)
|
||||
return 0
|
||||
@@ -2161,12 +2142,9 @@ novirtual class AssignGenMixin:
|
||||
# 「指针隐式转整数」(如 PointerTest/App/main.vp:46 `_g_ptr: int = None`:
|
||||
# 全局已是 t.CUInt32T*)。范围仅函数内——模块级自身的重复注解
|
||||
# 不归本检查(模块级由 handle_module_level_var 登记,本就不构成"遮蔽")。
|
||||
if nm.id is not None and trans is not None \
|
||||
and self.Gen.VarGen.is_module_scope(trans.SymTab) == 0 \
|
||||
and self.Gen.VarGen.lookup_module_var(trans.SymTab, nm.id) is not None:
|
||||
if nm.id is not None and trans is not None and self.Gen.VarGen.is_module_scope(trans.SymTab) == 0 and self.Gen.VarGen.lookup_module_var(trans.SymTab, nm.id) is not None:
|
||||
dup_decl: int = 0
|
||||
if GenApi.is_global_name(trans, nm.id) != 0 \
|
||||
or GenApi.is_nonlocal_name(trans, nm.id) != 0:
|
||||
if GenApi.is_global_name(trans, nm.id) != 0 or GenApi.is_nonlocal_name(trans, nm.id) != 0:
|
||||
dup_decl = 1
|
||||
if dup_decl != 0:
|
||||
self.Gen.TypeGenErr.fatal_error(aa,
|
||||
@@ -2229,8 +2207,7 @@ novirtual class AssignGenMixin:
|
||||
# LLVM 的 call 无 volatile 限定符,故语义落在内存存取上:本次 store 带
|
||||
# volatile,且此后该变量的 load/store 亦带,避免这次调用/构造的往返访问
|
||||
# 被优化器消除或提升。
|
||||
if aa.value is not None and aa.value.kind() == ast.ASTKind.Call \
|
||||
and (ast.Call*(aa.value)).IsVolatile != 0 and nm.id is not None:
|
||||
if aa.value is not None and aa.value.kind() == ast.ASTKind.Call and (ast.Call*(aa.value)).IsVolatile != 0 and nm.id is not None:
|
||||
if self.Gen.VarGen.lookup_var_entry(trans.SymTab, nm.id) is not None:
|
||||
self.Gen.VarGen.set_var_volatile(trans.SymTab, nm.id)
|
||||
|
||||
@@ -2262,9 +2239,7 @@ novirtual class AssignGenMixin:
|
||||
if stg_key_aa is not None:
|
||||
viperlib.snprintf(stg_key_aa, sizet(string.strlen(nm.id)) + 8, "%s.__stg", nm.id)
|
||||
stg_ref_aa = self.Gen.VarGen.lookup_module_var(trans.SymTab, stg_key_aa)
|
||||
if self._is_addrlike_call(aa.value) == 0 \
|
||||
and stg_ref_aa is not None and rhs_val.Ty is not None \
|
||||
and stg_ref_aa.Ty is not None and stg_ref_aa.Ty.Pointee != 0:
|
||||
if self._is_addrlike_call(aa.value) == 0 and stg_ref_aa is not None and rhs_val.Ty is not None and stg_ref_aa.Ty is not None and stg_ref_aa.Ty.Pointee != 0:
|
||||
stg_ty_aa: mlirlite.LLVMType* = stg_ref_aa.Ty.Pointee
|
||||
rhs_inner_aa: mlirlite.LLVMType* = None
|
||||
match rhs_val.Ty:
|
||||
@@ -2272,8 +2247,7 @@ novirtual class AssignGenMixin:
|
||||
rhs_inner_aa = pointee_aa
|
||||
case _:
|
||||
pass
|
||||
if rhs_inner_aa is not None and rhs_inner_aa.kind() == mlirlite.LLVMType.Struct \
|
||||
and self._stg_ty_equal(pool, stg_ty_aa, rhs_inner_aa) != 0:
|
||||
if rhs_inner_aa is not None and rhs_inner_aa.kind() == mlirlite.LLVMType.Struct and self._stg_ty_equal(pool, stg_ty_aa, rhs_inner_aa) != 0:
|
||||
mlirlite.build_store(builder, stg_ref_aa, mod_alloca)
|
||||
stg_obj_val_aa: mlirlite.Value* = mlirlite.build_load(builder, stg_ty_aa, rhs_val)
|
||||
if stg_obj_val_aa is not None:
|
||||
@@ -2374,9 +2348,7 @@ novirtual class AssignGenMixin:
|
||||
if stg_key_mg is not None:
|
||||
viperlib.snprintf(stg_key_mg, sizet(string.strlen(nm.id)) + 8, "%s.__stg", nm.id)
|
||||
stg_ref_mg = self.Gen.VarGen.lookup_module_var(trans.SymTab, stg_key_mg)
|
||||
if self._is_addrlike_call(aa.value) == 0 \
|
||||
and stg_ref_mg is not None and rhs_val_mg.Ty is not None \
|
||||
and stg_ref_mg.Ty is not None and stg_ref_mg.Ty.Pointee != 0:
|
||||
if self._is_addrlike_call(aa.value) == 0 and stg_ref_mg is not None and rhs_val_mg.Ty is not None and stg_ref_mg.Ty is not None and stg_ref_mg.Ty.Pointee != 0:
|
||||
stg_ty_mg: mlirlite.LLVMType* = stg_ref_mg.Ty.Pointee
|
||||
rhs_inner_mg: mlirlite.LLVMType* = None
|
||||
match rhs_val_mg.Ty:
|
||||
@@ -2384,8 +2356,7 @@ novirtual class AssignGenMixin:
|
||||
rhs_inner_mg = pointee_mg
|
||||
case _:
|
||||
pass
|
||||
if rhs_inner_mg is not None and rhs_inner_mg.kind() == mlirlite.LLVMType.Struct \
|
||||
and self._stg_ty_equal(pool, stg_ty_mg, rhs_inner_mg) != 0:
|
||||
if rhs_inner_mg is not None and rhs_inner_mg.kind() == mlirlite.LLVMType.Struct and self._stg_ty_equal(pool, stg_ty_mg, rhs_inner_mg) != 0:
|
||||
mlirlite.build_store(builder, stg_ref_mg, mod_glob)
|
||||
stg_obj_val_mg: mlirlite.Value* = mlirlite.build_load(builder, stg_ty_mg, rhs_val_mg)
|
||||
if stg_obj_val_mg is not None:
|
||||
@@ -2432,15 +2403,13 @@ novirtual class AssignGenMixin:
|
||||
# 只比较「双方都是指针且 pointee 都是结构体」:结构体名不同即 fail-fast(不兜底)。
|
||||
if alloca is not None and alloca.Ty is not None and var_ty is not None:
|
||||
av_pt_d: mlirlite.LLVMType* = alloca.Ty.Pointee
|
||||
if av_pt_d is not None and self.Gen.ExprGenBase.is_ptr_type(av_pt_d) != 0 \
|
||||
and self.Gen.ExprGenBase.is_ptr_type(var_ty) != 0:
|
||||
if av_pt_d is not None and self.Gen.ExprGenBase.is_ptr_type(av_pt_d) != 0 and self.Gen.ExprGenBase.is_ptr_type(var_ty) != 0:
|
||||
av_in: mlirlite.LLVMType* = av_pt_d.Pointee
|
||||
vt_in: mlirlite.LLVMType* = var_ty.Pointee
|
||||
if av_in is not None and vt_in is not None:
|
||||
av_nm_d: str = mlirlite.get_struct_name(av_in)
|
||||
vt_nm_d: str = mlirlite.get_struct_name(vt_in)
|
||||
if av_nm_d is not None and vt_nm_d is not None \
|
||||
and string.strcmp(av_nm_d, vt_nm_d) != 0:
|
||||
if av_nm_d is not None and vt_nm_d is not None and string.strcmp(av_nm_d, vt_nm_d) != 0:
|
||||
# 仅当旧 alloca 的 pointee 是裸泛型模板基类(丢类型实参,如裸
|
||||
# list / 裸 GSList)而注解是另一个类型时 fail-fast(后续方法调用
|
||||
# 会按错误元素类型特化 → 截断);不同具体类(如 Tuple* vs AST*)
|
||||
@@ -2512,8 +2481,7 @@ novirtual class AssignGenMixin:
|
||||
# c.Addr(async_call):tt: Coroutine = c.Addr(task()) 就地解读
|
||||
elif val_cl.func is not None and val_cl.func.kind() == ast.ASTKind.Attribute:
|
||||
val_at: ast.Attribute* = ast.Attribute*(val_cl.func)
|
||||
if val_at.attr is not None and string.strcmp(val_at.attr, "Addr") == 0 \
|
||||
and val_cl.args is not None and len(val_cl.args) >= 1:
|
||||
if val_at.attr is not None and string.strcmp(val_at.attr, "Addr") == 0 and val_cl.args is not None and len(val_cl.args) >= 1:
|
||||
icall: ast.AST* = val_cl.args.get(0)
|
||||
if icall is not None and icall.kind() == ast.ASTKind.Call:
|
||||
icl2: ast.Call* = ast.Call*(icall)
|
||||
@@ -2590,8 +2558,7 @@ novirtual class AssignGenMixin:
|
||||
if ag_nm.id is not None:
|
||||
ann_gen_base = ag_nm.id
|
||||
rb_is_bare_generic: int = 0
|
||||
if alloca_pt is not None \
|
||||
and uint64(alloca_pt) != uint64(precise_rhs_ty):
|
||||
if alloca_pt is not None and uint64(alloca_pt) != uint64(precise_rhs_ty):
|
||||
rhs_pt_rb: mlirlite.LLVMType* = precise_rhs_ty.Pointee
|
||||
if rhs_pt_rb is not None:
|
||||
rb_nm: str = mlirlite.get_struct_name(rhs_pt_rb)
|
||||
@@ -2606,8 +2573,7 @@ novirtual class AssignGenMixin:
|
||||
# 已比 RHS 的裸 Base 精确)⇒ 本次重建方向是**降级**,
|
||||
# 必须禁止。此判定不依赖泛型模板注册表(list/dict 等
|
||||
# 内建容器未登记时①会漏判,②仍能命中)。
|
||||
elif ann_gen_base is not None \
|
||||
and string.strcmp(rb_short, ann_gen_base) == 0:
|
||||
elif ann_gen_base is not None and string.strcmp(rb_short, ann_gen_base) == 0:
|
||||
rb_is_bare_generic = 1
|
||||
# 禁止「上转被窄化」重建(方向判定其三):注解写明的被指类是
|
||||
# RHS 被指类的**基类**时(如 `node: rawptr[AST] = Name(...)`,
|
||||
@@ -2621,17 +2587,13 @@ novirtual class AssignGenMixin:
|
||||
# 判据只拦「上转被窄化」这一个确定的方向错误:注解退化为
|
||||
# i8*/裸占位(两侧类名不构成继承关系)时不受影响。
|
||||
rb_is_upcast: int = 0
|
||||
if alloca_pt is not None and uint64(alloca_pt) != uint64(precise_rhs_ty) \
|
||||
and self.Gen.ExprGenBase.is_ptr_type(alloca_pt) != 0:
|
||||
if alloca_pt is not None and uint64(alloca_pt) != uint64(precise_rhs_ty) and self.Gen.ExprGenBase.is_ptr_type(alloca_pt) != 0:
|
||||
ann_pt_rb: mlirlite.LLVMType* = alloca_pt.Pointee
|
||||
rhs_pt_up: mlirlite.LLVMType* = precise_rhs_ty.Pointee
|
||||
if ann_pt_rb is not None and rhs_pt_up is not None \
|
||||
and uint64(ann_pt_rb) != uint64(rhs_pt_up):
|
||||
if ann_pt_rb is not None and rhs_pt_up is not None and uint64(ann_pt_rb) != uint64(rhs_pt_up):
|
||||
if self.Gen.ExprGenBase._is_inheritance_upcast(pool, rhs_pt_up, ann_pt_rb) != 0:
|
||||
rb_is_upcast = 1
|
||||
if alloca_pt is not None and \
|
||||
uint64(alloca_pt) != uint64(precise_rhs_ty) \
|
||||
and rb_is_bare_generic == 0 and rb_is_upcast == 0:
|
||||
if alloca_pt is not None and uint64(alloca_pt) != uint64(precise_rhs_ty) and rb_is_bare_generic == 0 and rb_is_upcast == 0:
|
||||
new_alloca: mlirlite.Value* = self.Gen.VarGen._alloca_at_entry(builder, precise_rhs_ty)
|
||||
if new_alloca is not None:
|
||||
v_entry_rb: GenTypes.VarEntry* = self.Gen.VarGen.lookup_var_entry(trans.SymTab, nm.id)
|
||||
@@ -2667,19 +2629,16 @@ novirtual class AssignGenMixin:
|
||||
# 限定符,故语义落在内存存取上:结果槽按 volatile 存取
|
||||
# (本次 store 立即带 volatile,且此后该变量的 load/store 也带),
|
||||
# 使"这次调用/构造的往返内存访问"不会被优化器消除或提升。
|
||||
if aa.value is not None and aa.value.kind() == ast.ASTKind.Call \
|
||||
and (ast.Call*(aa.value)).IsVolatile != 0:
|
||||
if aa.value is not None and aa.value.kind() == ast.ASTKind.Call and (ast.Call*(aa.value)).IsVolatile != 0:
|
||||
self.Gen.VarGen.set_var_volatile(trans.SymTab, nm.id)
|
||||
vol_laa = 1
|
||||
mlirlite.build_store(builder, rhs_val, alloca, vol_laa)
|
||||
# FakeDuck: 初始化影子结构体 __data__ 字段 = 初始字符串指针
|
||||
# (对齐 TPC HandlesAnnAssign.py: 仅当有初值时写入 __data__)
|
||||
if fd_str_ty is not None and fd_meta_alloca is not None:
|
||||
fd_data_fe: GenTypes.FieldEntry* = \
|
||||
self.Gen.StructGen.lookup_field(fd_str_ty, "__data__")
|
||||
fd_data_fe: GenTypes.FieldEntry* = self.Gen.StructGen.lookup_field(fd_str_ty, "__data__")
|
||||
if fd_data_fe is not None:
|
||||
fd_data_ptr: mlirlite.Value* = \
|
||||
mlirlite.build_gep_struct(builder, fd_str_ty, fd_data_fe.Ty, fd_meta_alloca, fd_data_fe.Index)
|
||||
fd_data_ptr: mlirlite.Value* = mlirlite.build_gep_struct(builder, fd_str_ty, fd_data_fe.Ty, fd_meta_alloca, fd_data_fe.Index)
|
||||
if fd_data_ptr is not None:
|
||||
mlirlite.build_store(builder, rhs_val, fd_data_ptr)
|
||||
# 清除赋值上下文(防残留):CurAssignAnnot/CurAssignNode 只在该
|
||||
@@ -2693,12 +2652,10 @@ novirtual class AssignGenMixin:
|
||||
# with 上下文提供的 __mbuddy__ 注入由 _inject_requires_fields(fd4)完成,
|
||||
# 此处仅确保影子结构体初始为空指针(对齐 TPC HandlesAnnAssign.py L667-670)。
|
||||
if fd_str_ty is not None and fd_meta_alloca is not None:
|
||||
fd_buddy_fe: GenTypes.FieldEntry* = \
|
||||
self.Gen.StructGen.lookup_field(fd_str_ty, "__mbuddy__")
|
||||
fd_buddy_fe: GenTypes.FieldEntry* = self.Gen.StructGen.lookup_field(fd_str_ty, "__mbuddy__")
|
||||
if fd_buddy_fe is not None and fd_buddy_fe.Ty is not None:
|
||||
fd_null: mlirlite.Value* = mlirlite.ConstNull(pool, fd_buddy_fe.Ty, "null")
|
||||
fd_buddy_ptr: mlirlite.Value* = \
|
||||
mlirlite.build_gep_struct(builder, fd_str_ty, fd_buddy_fe.Ty,
|
||||
fd_buddy_ptr: mlirlite.Value* = mlirlite.build_gep_struct(builder, fd_str_ty, fd_buddy_fe.Ty,
|
||||
fd_meta_alloca, fd_buddy_fe.Index)
|
||||
if fd_buddy_ptr is not None and fd_null is not None:
|
||||
mlirlite.build_store(builder, fd_null, fd_buddy_ptr)
|
||||
@@ -2814,15 +2771,12 @@ novirtual class AssignGenMixin:
|
||||
asg_slot = self.Gen.VarGen.lookup_module_var(trans.SymTab, asg_nm0.id)
|
||||
if asg_slot is not None and asg_slot.Ty is not None:
|
||||
asg_target_ty = asg_slot.Ty.Pointee
|
||||
elif trans.ReplCtx is not None \
|
||||
and self.Gen.VarGen.repl_in_frag_entry_scope(trans) != 0:
|
||||
elif trans.ReplCtx is not None and self.Gen.VarGen.repl_in_frag_entry_scope(trans) != 0:
|
||||
# REPL 模式(M2/M3):已定型的会话变量也用槽类型做 target_ty
|
||||
# (与 P1-A 同口径;未定型则维持 None,由 RHS 类型定型)。
|
||||
# 只在片段入口函数生效(被提升的会话函数体内同名赋值是局部变量)
|
||||
asg_re: rawptr[GenTypes.ReplVarEntry] = \
|
||||
self.Gen.VarGen.repl_find_entry(trans.ReplCtx, asg_nm0.id)
|
||||
if asg_re is not None \
|
||||
and asg_re.Kind != GenTypes.REPL_KIND_UNTYPED:
|
||||
asg_re: rawptr[GenTypes.ReplVarEntry] = self.Gen.VarGen.repl_find_entry(trans.ReplCtx, asg_nm0.id)
|
||||
if asg_re is not None and asg_re.Kind != GenTypes.REPL_KIND_UNTYPED:
|
||||
asg_target_ty = self.Gen.VarGen.repl_slot_ty(pool, asg_re)
|
||||
rhs_val: mlirlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, mod, asgn.value, None, 0, trans, asg_target_ty)
|
||||
if rhs_val is None:
|
||||
@@ -2989,17 +2943,13 @@ novirtual class AssignGenMixin:
|
||||
sub_nm: ast.Name* = ast.Name*(sub_asgn.value)
|
||||
if sub_nm.id is not None:
|
||||
sub_alloca: mlirlite.Value* = self.Gen.VarGen.lookup_var(trans.SymTab, sub_nm.id)
|
||||
if sub_alloca is not None and sub_alloca.Ty is not None \
|
||||
and sub_alloca.Ty.Pointee != 0 \
|
||||
and self.Gen.ExprGenBase.is_ptr_type(sub_alloca.Ty) != 0:
|
||||
if sub_alloca is not None and sub_alloca.Ty is not None and sub_alloca.Ty.Pointee != 0 and self.Gen.ExprGenBase.is_ptr_type(sub_alloca.Ty) != 0:
|
||||
sub_pointee: mlirlite.LLVMType* = sub_alloca.Ty.Pointee
|
||||
cls_nm_set: str = self.Gen.StructGen.get_class_name_by_type(pool, sub_pointee)
|
||||
obj_val_set: mlirlite.Value* = mlirlite.build_load(builder, sub_pointee, sub_alloca)
|
||||
# 指针类型变量 (X*): sub_pointee 是 Ptr(Struct),
|
||||
# 需 load 获取 Ptr(Struct) 再检查 inner struct
|
||||
if cls_nm_set is None and obj_val_set is not None \
|
||||
and self.Gen.ExprGenBase.is_ptr_type(sub_pointee) != 0 \
|
||||
and sub_pointee.Pointee != 0:
|
||||
if cls_nm_set is None and obj_val_set is not None and self.Gen.ExprGenBase.is_ptr_type(sub_pointee) != 0 and sub_pointee.Pointee != 0:
|
||||
cls_nm_set = self.Gen.StructGen.get_class_name_by_type(pool, sub_pointee.Pointee)
|
||||
if cls_nm_set is not None and obj_val_set is not None:
|
||||
key_val_set: mlirlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, mod, sub_asgn.slice, None, 0, trans)
|
||||
@@ -3015,17 +2965,13 @@ novirtual class AssignGenMixin:
|
||||
# self._ht[key] = val → self._ht.__setitem__(key, val)
|
||||
# 通过 get_attribute_ptr 获取字段指针,再调用 __setitem__
|
||||
field_ptr_set: mlirlite.Value* = self.Gen.ExprGenAttr.get_attribute_ptr(builder, pool, mod, sub_asgn.value, trans)
|
||||
if field_ptr_set is not None and field_ptr_set.Ty is not None \
|
||||
and field_ptr_set.Ty.Pointee != 0 \
|
||||
and self.Gen.ExprGenBase.is_ptr_type(field_ptr_set.Ty) != 0:
|
||||
if field_ptr_set is not None and field_ptr_set.Ty is not None and field_ptr_set.Ty.Pointee != 0 and self.Gen.ExprGenBase.is_ptr_type(field_ptr_set.Ty) != 0:
|
||||
field_pointee_set: mlirlite.LLVMType* = field_ptr_set.Ty.Pointee
|
||||
cls_nm_attr: str = self.Gen.StructGen.get_class_name_by_type(pool, field_pointee_set)
|
||||
obj_val_attr: mlirlite.Value* = field_ptr_set
|
||||
# field_ptr 是 Ptr(Ptr(Struct)) (X* 字段):
|
||||
# load 解引用获取 Ptr(Struct)
|
||||
if cls_nm_attr is None \
|
||||
and self.Gen.ExprGenBase.is_ptr_type(field_pointee_set) != 0 \
|
||||
and field_pointee_set.Pointee != 0:
|
||||
if cls_nm_attr is None and self.Gen.ExprGenBase.is_ptr_type(field_pointee_set) != 0 and field_pointee_set.Pointee != 0:
|
||||
cls_nm_attr = self.Gen.StructGen.get_class_name_by_type(pool, field_pointee_set.Pointee)
|
||||
if cls_nm_attr is not None:
|
||||
obj_val_attr = mlirlite.build_load(builder, field_pointee_set, field_ptr_set)
|
||||
@@ -3045,12 +2991,10 @@ novirtual class AssignGenMixin:
|
||||
if sub_asgn is not None and sub_asgn.value is not None:
|
||||
obj_val_gen: mlirlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, mod, sub_asgn.value, None, 0, trans)
|
||||
key_val_gen: mlirlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, mod, sub_asgn.slice, None, 0, trans)
|
||||
if obj_val_gen is not None and key_val_gen is not None \
|
||||
and obj_val_gen.Ty is not None:
|
||||
if obj_val_gen is not None and key_val_gen is not None and obj_val_gen.Ty is not None:
|
||||
# 内联 _get_custom_struct_cls_nm 逻辑(避免依赖新函数)
|
||||
cls_nm_gen: str = self.Gen.StructGen.get_class_name_by_type(pool, obj_val_gen.Ty)
|
||||
if cls_nm_gen is None and self.Gen.ExprGenBase.is_ptr_type(obj_val_gen.Ty) != 0 \
|
||||
and obj_val_gen.Ty.Pointee != 0:
|
||||
if cls_nm_gen is None and self.Gen.ExprGenBase.is_ptr_type(obj_val_gen.Ty) != 0 and obj_val_gen.Ty.Pointee != 0:
|
||||
cls_nm_gen = self.Gen.StructGen.get_class_name_by_type(pool, obj_val_gen.Ty.Pointee)
|
||||
if cls_nm_gen is not None:
|
||||
# 自定义结构体: 调用 __setitem__
|
||||
@@ -3061,8 +3005,7 @@ novirtual class AssignGenMixin:
|
||||
self.Gen.CallGenCall._call_method_on_ptr(pool, builder, mod, cls_nm_gen, "__setitem__",
|
||||
obj_val_gen, arg_vals_gen, 2, trans)
|
||||
setitem_done = 1
|
||||
elif self.Gen.ExprGenBase.is_ptr_type(obj_val_gen.Ty) != 0 \
|
||||
and obj_val_gen.Ty.Pointee != 0:
|
||||
elif self.Gen.ExprGenBase.is_ptr_type(obj_val_gen.Ty) != 0 and obj_val_gen.Ty.Pointee != 0:
|
||||
# 非自定义结构体: 直接 GEP + store
|
||||
# 处理 get_subscript_ptr 因边界情况返回 None 的指针下标
|
||||
elem_gen: mlirlite.LLVMType* = obj_val_gen.Ty.Pointee
|
||||
@@ -3102,8 +3045,7 @@ novirtual class AssignGenMixin:
|
||||
self.Gen.TypeGenErr.fatal_error(target,
|
||||
"赋值目标只支持单目 '*' 解引用(&x / -x / ~x 不是合法左值)", "SyntaxError")
|
||||
ptr_w: mlirlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, mod, uo_w.operand, None, 0, trans)
|
||||
if ptr_w is None or ptr_w.Ty is None \
|
||||
or self.Gen.ExprGenBase.is_ptr_type(ptr_w.Ty) == 0:
|
||||
if ptr_w is None or ptr_w.Ty is None or self.Gen.ExprGenBase.is_ptr_type(ptr_w.Ty) == 0:
|
||||
self.Gen.TypeGenErr.fatal_error(target,
|
||||
"单目 '*' 赋值的操作数必须是指针类型(类型推断退化)", "TypeError")
|
||||
pointee_w: mlirlite.LLVMType* = ptr_w.Ty.Pointee
|
||||
@@ -3140,18 +3082,14 @@ novirtual class AssignGenMixin:
|
||||
viperlib.snprintf(fd_meta_w, 256, "%s__meta__", fd_obj_nm.id)
|
||||
fd_meta_vw: mlirlite.Value* = self.Gen.VarGen.lookup_current(trans.SymTab, fd_meta_w)
|
||||
if fd_meta_vw is not None:
|
||||
fd_sty_w: mlirlite.LLVMType* = \
|
||||
self.Gen.StructGen.get_struct_type("_str")
|
||||
fd_sty_w: mlirlite.LLVMType* = self.Gen.StructGen.get_struct_type("_str")
|
||||
if fd_sty_w is not None:
|
||||
fd_fe_w: GenTypes.FieldEntry* = \
|
||||
self.Gen.StructGen.lookup_field(fd_sty_w, fd_an.attr)
|
||||
fd_fe_w: GenTypes.FieldEntry* = self.Gen.StructGen.lookup_field(fd_sty_w, fd_an.attr)
|
||||
if fd_fe_w is not None and fd_fe_w.Ty is not None:
|
||||
fd_fp_w: mlirlite.Value* = \
|
||||
mlirlite.build_gep_struct(builder, fd_sty_w, fd_fe_w.Ty,
|
||||
fd_fp_w: mlirlite.Value* = mlirlite.build_gep_struct(builder, fd_sty_w, fd_fe_w.Ty,
|
||||
fd_meta_vw, fd_fe_w.Index)
|
||||
if fd_fp_w is not None:
|
||||
sv_fd: mlirlite.Value* = \
|
||||
self.Gen.ExprGenBase.coerce_to_type(builder, rhs_val, fd_fe_w.Ty, node)
|
||||
sv_fd: mlirlite.Value* = self.Gen.ExprGenBase.coerce_to_type(builder, rhs_val, fd_fe_w.Ty, node)
|
||||
mlirlite.build_store(builder, sv_fd, fd_fp_w)
|
||||
continue
|
||||
# VTABLE 直接写入:obj.method = func(serial0_file.open = serial0_open)
|
||||
@@ -3216,9 +3154,7 @@ novirtual class AssignGenMixin:
|
||||
if stg_key_as is not None:
|
||||
viperlib.snprintf(stg_key_as, sizet(string.strlen(nm.id)) + 8, "%s.__stg", nm.id)
|
||||
stg_ref_as = self.Gen.VarGen.lookup_module_var(trans.SymTab, stg_key_as)
|
||||
if self._is_addrlike_call(asgn.value) == 0 \
|
||||
and stg_ref_as is not None and rhs_val is not None and rhs_val.Ty is not None \
|
||||
and stg_ref_as.Ty is not None and stg_ref_as.Ty.Pointee != 0:
|
||||
if self._is_addrlike_call(asgn.value) == 0 and stg_ref_as is not None and rhs_val is not None and rhs_val.Ty is not None and stg_ref_as.Ty is not None and stg_ref_as.Ty.Pointee != 0:
|
||||
stg_ty_as: mlirlite.LLVMType* = stg_ref_as.Ty.Pointee
|
||||
rhs_inner_as: mlirlite.LLVMType* = None
|
||||
match rhs_val.Ty:
|
||||
@@ -3226,8 +3162,7 @@ novirtual class AssignGenMixin:
|
||||
rhs_inner_as = pointee_as
|
||||
case _:
|
||||
pass
|
||||
if rhs_inner_as is not None and rhs_inner_as.kind() == mlirlite.LLVMType.Struct \
|
||||
and self._stg_ty_equal(pool, stg_ty_as, rhs_inner_as) != 0:
|
||||
if rhs_inner_as is not None and rhs_inner_as.kind() == mlirlite.LLVMType.Struct and self._stg_ty_equal(pool, stg_ty_as, rhs_inner_as) != 0:
|
||||
# 1) @g 引用绑定到 storage(丢弃临时 alloca,避免悬垂)
|
||||
mlirlite.build_store(builder, stg_ref_as, mod_alloca)
|
||||
# 2) 复制构造结果(临时对象)到 storage(函数内复制,alloca 仍有效)
|
||||
@@ -3270,10 +3205,8 @@ novirtual class AssignGenMixin:
|
||||
# 守卫 trans.ReplCtx(非 REPL 恒 None ⇒ 本分支整体不经过);
|
||||
# repl_in_frag_entry_scope 排除被提升的会话函数体与片段内嵌套函数体
|
||||
# (那些仍用普通局部 alloca:Python 局部语义 + 防形参同名串味)。
|
||||
if trans.ReplCtx is not None \
|
||||
and self.Gen.VarGen.repl_in_frag_entry_scope(trans) != 0:
|
||||
rp_entry: rawptr[GenTypes.ReplVarEntry] = \
|
||||
self.Gen.VarGen.repl_ensure_entry(trans, nm.id, target)
|
||||
if trans.ReplCtx is not None and self.Gen.VarGen.repl_in_frag_entry_scope(trans) != 0:
|
||||
rp_entry: rawptr[GenTypes.ReplVarEntry] = self.Gen.VarGen.repl_ensure_entry(trans, nm.id, target)
|
||||
if rp_entry is not None:
|
||||
self.Gen.VarGen.repl_try_assign(trans, nm.id, rhs_val, asgn.value, node)
|
||||
continue
|
||||
@@ -3306,8 +3239,7 @@ novirtual class AssignGenMixin:
|
||||
# 调用分派(is_closure_name)才走闭包间接调用路径;
|
||||
# 否则 i8** alloca 被 _is_func_ptr_alloca 误判为
|
||||
# 函数指针,无参 call 直接跳闭包数据崩溃
|
||||
if asgn.value is not None \
|
||||
and asgn.value.kind() == ast.ASTKind.Lambda:
|
||||
if asgn.value is not None and asgn.value.kind() == ast.ASTKind.Lambda:
|
||||
self.Gen.CallGenLeafKit.register_closure_name(nm.id)
|
||||
existing: mlirlite.Value* = self.Gen.VarGen.lookup_current(trans.SymTab, nm.id)
|
||||
if existing is None:
|
||||
|
||||
@@ -2230,8 +2230,7 @@ novirtual class AsyncGenMixin(CallGenBase.CallGenBase):
|
||||
if rc_buf is not None:
|
||||
viperlib.snprintf(rc_buf, 64, "resume_%s", call_name)
|
||||
resume_mangled: str = self.Gen.FuncGenBase._mangle_func_name(trans, rc_buf, 0)
|
||||
if self.Gen.CallGenBase.find_func_in_module(mod, create_mangled) is None \
|
||||
or self.Gen.CallGenBase.find_func_in_module(mod, resume_mangled) is None:
|
||||
if self.Gen.CallGenBase.find_func_in_module(mod, create_mangled) is None or self.Gen.CallGenBase.find_func_in_module(mod, resume_mangled) is None:
|
||||
# async 函数必须定义在前(前向引用未支持),静默返回 0
|
||||
return mlirlite.const_int32(pool, 0)
|
||||
|
||||
|
||||
@@ -602,17 +602,11 @@ novirtual class CallGenCBuiltin(CallGenBase.CallGenBase):
|
||||
next_ok: int = 1
|
||||
if i > 0:
|
||||
prev_ch: char = asm_text[i - 1]
|
||||
if (prev_ch >= 'a' and prev_ch <= 'z') \
|
||||
or (prev_ch >= 'A' and prev_ch <= 'Z') \
|
||||
or (prev_ch >= '0' and prev_ch <= '9') \
|
||||
or prev_ch == '_':
|
||||
if (prev_ch >= 'a' and prev_ch <= 'z') or (prev_ch >= 'A' and prev_ch <= 'Z') or (prev_ch >= '0' and prev_ch <= '9') or prev_ch == '_':
|
||||
prev_ok = 0
|
||||
if i + bare_len < src_len:
|
||||
next_ch: char = asm_text[i + bare_len]
|
||||
if (next_ch >= 'a' and next_ch <= 'z') \
|
||||
or (next_ch >= 'A' and next_ch <= 'Z') \
|
||||
or (next_ch >= '0' and next_ch <= '9') \
|
||||
or next_ch == '_':
|
||||
if (next_ch >= 'a' and next_ch <= 'z') or (next_ch >= 'A' and next_ch <= 'Z') or (next_ch >= '0' and next_ch <= '9') or next_ch == '_':
|
||||
next_ok = 0
|
||||
if prev_ok != 0 and next_ok != 0:
|
||||
# fail-fast:asm 模板引用的模块全局带 SHA1 混淆头
|
||||
|
||||
@@ -304,8 +304,7 @@ novirtual class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin):
|
||||
while cls_names[ci] != 0:
|
||||
cn: str = rawptr(cls_names[ci])
|
||||
if cn is not None:
|
||||
if self.Gen.StructGen.is_novtable_by_name(cn) != 0 \
|
||||
or self.Gen.StructGen.has_vtable_by_name(cn) == 0:
|
||||
if self.Gen.StructGen.is_novtable_by_name(cn) != 0 or self.Gen.StructGen.has_vtable_by_name(cn) == 0:
|
||||
# NoVTable / 未知类 → 编译时静态判断(obj 静态类型 MRO)
|
||||
st: int = self._isinstance_compile_time(pool, obj_ptr, cn)
|
||||
c1: mlirlite.Value* = mlirlite.const_int(pool, 1, 1 if st > 0 else 0)
|
||||
@@ -1044,8 +1043,7 @@ novirtual class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin):
|
||||
if owner_sha1 is None and self.GlobalFuncs is not None:
|
||||
if uint64(funcs) == uint64(self.GlobalFuncs) and func_count == self.GlobalFuncCount:
|
||||
gfuncs_match = 1
|
||||
if gfuncs_match != 0 and self.GlobalFuncNameIdxBuilt == self.GlobalFuncCount \
|
||||
and self.GlobalFuncNameIdx is not None and self.GlobalFuncNameIdxCap > 0:
|
||||
if gfuncs_match != 0 and self.GlobalFuncNameIdxBuilt == self.GlobalFuncCount and self.GlobalFuncNameIdx is not None and self.GlobalFuncNameIdxCap > 0:
|
||||
fi_t: int = _gfn_idx_find(self.GlobalFuncs, self.GlobalFuncNameIdx,
|
||||
self.GlobalFuncNameIdxCap, name)
|
||||
if fi_t >= 0:
|
||||
@@ -1179,8 +1177,7 @@ novirtual class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin):
|
||||
self.GlobalFuncCount += 1
|
||||
# 同步名索引(槽下标 = 新条目下标):仅当插入前可信(Built==Count-1)
|
||||
# 且插入成功;否则标记不可信(查找回退线性扫描)。
|
||||
if self.GlobalFuncNameIdxBuilt == self.GlobalFuncCount - 1 \
|
||||
and _gfn_idx_insert(self.GlobalFuncNameIdx, self.GlobalFuncNameIdxCap,
|
||||
if self.GlobalFuncNameIdxBuilt == self.GlobalFuncCount - 1 and _gfn_idx_insert(self.GlobalFuncNameIdx, self.GlobalFuncNameIdxCap,
|
||||
self.GlobalFuncCount - 1, name_copy) == 0:
|
||||
self.GlobalFuncNameIdxBuilt = self.GlobalFuncCount
|
||||
else:
|
||||
|
||||
@@ -273,8 +273,7 @@ novirtual class CallGenLib(CallGenBase.CallGenBase):
|
||||
# ExprGenBase._str_rejects_ptr_kind / fail_if_str_annot_agg_ptr(单一
|
||||
# 真源,字符数组 [N x i8] 衰减与其在同模块路径同口径豁免)。
|
||||
if self.Gen.ExprGenBase._str_rejects_ptr_kind(cur) != 0:
|
||||
if VpiReader._vpi_param_annot_seg_is(sha1_buf, cls_nm, meth_nm, idx, "str") != 0 \
|
||||
or VpiReader._vpi_param_annot_seg_is(sha1_buf, cls_nm, meth_nm, idx, "bytes") != 0:
|
||||
if VpiReader._vpi_param_annot_seg_is(sha1_buf, cls_nm, meth_nm, idx, "str") != 0 or VpiReader._vpi_param_annot_seg_is(sha1_buf, cls_nm, meth_nm, idx, "bytes") != 0:
|
||||
self.Gen.ExprGenBase.fail_if_str_annot_agg_ptr(cur, 1, arg_node)
|
||||
node_v = self._coerce_arg_value_to_ty(pool, builder, cur, tgt_ty, arg_node, trans, tpl_src)
|
||||
if new_head is None:
|
||||
@@ -454,8 +453,7 @@ novirtual class CallGenLib(CallGenBase.CallGenBase):
|
||||
if string.strcmp(func_name, "atoll") == 0:
|
||||
return mlirlite.Int64(pool)
|
||||
# mlirlite 函数名长度访问器返回 sizet(i64):默认 i32 与 declare 的 i64 签名不一致,须登记
|
||||
if string.strcmp(bare_name, "function_get_name_len") == 0 or \
|
||||
string.strcmp(func_name, "function_get_name_len") == 0:
|
||||
if string.strcmp(bare_name, "function_get_name_len") == 0 or string.strcmp(func_name, "function_get_name_len") == 0:
|
||||
return mlirlite.Int64(pool)
|
||||
|
||||
# 返回 double 的函数
|
||||
@@ -532,28 +530,13 @@ novirtual class CallGenLib(CallGenBase.CallGenBase):
|
||||
# mlirlite build_* 返回类型推断:多数返回 Value*,少数终止指令返回 void(stubs 未注入时防指针截断)
|
||||
if string.strncmp(func_name, "build_", 6) == 0:
|
||||
# 返回 void 的 build_* 函数(终止指令和无返回值指令)
|
||||
if string.strcmp(func_name, "build_ret") == 0 or string.strcmp(func_name, "build_ret_void") == 0 or \
|
||||
string.strcmp(func_name, "build_store") == 0 or string.strcmp(func_name, "build_br") == 0 or \
|
||||
string.strcmp(func_name, "build_cond_br") == 0 or string.strcmp(func_name, "build_unreachable") == 0 or \
|
||||
string.strcmp(func_name, "build_switch") == 0:
|
||||
if string.strcmp(func_name, "build_ret") == 0 or string.strcmp(func_name, "build_ret_void") == 0 or string.strcmp(func_name, "build_store") == 0 or string.strcmp(func_name, "build_br") == 0 or string.strcmp(func_name, "build_cond_br") == 0 or string.strcmp(func_name, "build_unreachable") == 0 or string.strcmp(func_name, "build_switch") == 0:
|
||||
return mlirlite.Void(pool)
|
||||
# 其他 build_* 函数返回 Value*(指针)
|
||||
return mlirlite.Ptr(pool, mlirlite.Int8(pool))
|
||||
|
||||
# mlirlite 类型工厂 / 常量构造 / 访问器函数返回指针(LLVMType*/Value*):Int*/Ptr/Func/Array/Struct/Void 等、const_*/Const*、function_get_*/param_get_*
|
||||
if string.strcmp(func_name, "Int1") == 0 or string.strcmp(func_name, "Int8") == 0 or string.strcmp(func_name, "Int16") == 0 or \
|
||||
string.strcmp(func_name, "Int32") == 0 or string.strcmp(func_name, "Int64") == 0 or string.strcmp(func_name, "Ptr") == 0 or \
|
||||
string.strcmp(func_name, "Func") == 0 or string.strcmp(func_name, "Array") == 0 or string.strcmp(func_name, "Struct") == 0 or \
|
||||
string.strcmp(func_name, "Void") == 0 or string.strcmp(func_name, "Half") == 0 or string.strcmp(func_name, "Float") == 0 or \
|
||||
string.strcmp(func_name, "Double") == 0 or string.strcmp(func_name, "FP128") == 0 or string.strcmp(func_name, "Label") == 0 or \
|
||||
string.strcmp(func_name, "new_param_node") == 0 or string.strcmp(func_name, "new_phi_incoming") == 0 or \
|
||||
string.strcmp(func_name, "const_int32") == 0 or string.strcmp(func_name, "const_int64") == 0 or \
|
||||
string.strcmp(func_name, "ConstFloat") == 0 or string.strcmp(func_name, "ConstZero") == 0 or \
|
||||
string.strcmp(func_name, "ConstNull") == 0 or string.strcmp(func_name, "ConstInt") == 0 or \
|
||||
string.strcmp(func_name, "function_get_name") == 0 or string.strcmp(func_name, "param_get_ty") == 0 or \
|
||||
string.strcmp(func_name, "value_get_ty") == 0 or string.strcmp(func_name, "value_get_next") == 0 or \
|
||||
string.strcmp(func_name, "function_get_ret_ty") == 0 or string.strcmp(func_name, "function_get_params") == 0 or \
|
||||
string.strcmp(func_name, "function_get_param_head") == 0 or string.strcmp(func_name, "param_get_next") == 0:
|
||||
if string.strcmp(func_name, "Int1") == 0 or string.strcmp(func_name, "Int8") == 0 or string.strcmp(func_name, "Int16") == 0 or string.strcmp(func_name, "Int32") == 0 or string.strcmp(func_name, "Int64") == 0 or string.strcmp(func_name, "Ptr") == 0 or string.strcmp(func_name, "Func") == 0 or string.strcmp(func_name, "Array") == 0 or string.strcmp(func_name, "Struct") == 0 or string.strcmp(func_name, "Void") == 0 or string.strcmp(func_name, "Half") == 0 or string.strcmp(func_name, "Float") == 0 or string.strcmp(func_name, "Double") == 0 or string.strcmp(func_name, "FP128") == 0 or string.strcmp(func_name, "Label") == 0 or string.strcmp(func_name, "new_param_node") == 0 or string.strcmp(func_name, "new_phi_incoming") == 0 or string.strcmp(func_name, "const_int32") == 0 or string.strcmp(func_name, "const_int64") == 0 or string.strcmp(func_name, "ConstFloat") == 0 or string.strcmp(func_name, "ConstZero") == 0 or string.strcmp(func_name, "ConstNull") == 0 or string.strcmp(func_name, "ConstInt") == 0 or string.strcmp(func_name, "function_get_name") == 0 or string.strcmp(func_name, "param_get_ty") == 0 or string.strcmp(func_name, "value_get_ty") == 0 or string.strcmp(func_name, "value_get_next") == 0 or string.strcmp(func_name, "function_get_ret_ty") == 0 or string.strcmp(func_name, "function_get_params") == 0 or string.strcmp(func_name, "function_get_param_head") == 0 or string.strcmp(func_name, "param_get_next") == 0:
|
||||
return mlirlite.Ptr(pool, mlirlite.Int8(pool))
|
||||
|
||||
# 默认 i32 占位:fatal_if_unknown=1 → fail-fast 报错;=0(Phase A 中间遍)保持占位,不输出 WARN
|
||||
@@ -602,9 +585,7 @@ novirtual class CallGenLib(CallGenBase.CallGenBase):
|
||||
return i64_ty
|
||||
|
||||
# 内存分配函数:size 参数声明为 i64(size_t),裸名回退时不提升则 call 与 define 宽度不匹配;calloc/realloc 的 size 在 idx 1
|
||||
if string.strcmp(func_name, "malloc") == 0 \
|
||||
or string.strcmp(func_name, "alloc") == 0 \
|
||||
or string.strcmp(func_name, "alloc_buf") == 0:
|
||||
if string.strcmp(func_name, "malloc") == 0 or string.strcmp(func_name, "alloc") == 0 or string.strcmp(func_name, "alloc_buf") == 0:
|
||||
if param_idx == 0:
|
||||
return i64_ty
|
||||
if string.strcmp(func_name, "calloc") == 0:
|
||||
|
||||
@@ -301,8 +301,7 @@ novirtual class CallGenMixin(CallGenBase.CallGenBase):
|
||||
# 前向声明占位(裸泛型模板注解 `Class` 无实参时由 TypeGenResolve 登记)
|
||||
# 不是真实结构体定义:不作为裸名构造的 struct_ty,交由下方泛型推断按实参
|
||||
# 特化(与模块限定分支同口径)。
|
||||
if gen_ctor_entry is not None and gen_ctor_entry.IsForwardDecl != 0 \
|
||||
and self.Gen.ClassGenGeneric._find_generic_template(func_name) is not None:
|
||||
if gen_ctor_entry is not None and gen_ctor_entry.IsForwardDecl != 0 and self.Gen.ClassGenGeneric._find_generic_template(func_name) is not None:
|
||||
gen_ctor_entry = None
|
||||
if gen_ctor_entry is not None:
|
||||
struct_ty = gen_ctor_entry.Ty
|
||||
@@ -505,8 +504,7 @@ novirtual class CallGenMixin(CallGenBase.CallGenBase):
|
||||
# 变体表因任何原因缺失时,入口至少不被表的空状态挡住;
|
||||
# 若 tag 仍查不到则下方 fail-fast 报出表状态(不再落到
|
||||
# "外部函数返回类型未登记 ... Metadata" 这种误导报错)。
|
||||
if self.Gen.ClassGenEnum._is_renum_class_name(rc_cls_name) != 0 \
|
||||
or self.Gen.ClassGenEnum._is_renum_by_entry(rc_cls_name) != 0:
|
||||
if self.Gen.ClassGenEnum._is_renum_class_name(rc_cls_name) != 0 or self.Gen.ClassGenEnum._is_renum_by_entry(rc_cls_name) != 0:
|
||||
# 在该 REnum 类中查找变体名 func_name
|
||||
rc_tag: int = self.Gen.ClassGenEnum._lookup_renum_variant_in_class(rc_cls_name, func_name)
|
||||
if rc_tag < 0:
|
||||
@@ -704,8 +702,7 @@ novirtual class CallGenMixin(CallGenBase.CallGenBase):
|
||||
# SysLibTest 0xC0000005 根因)。误命中时拒绝(found_func=None),
|
||||
# 落到下方跨模块模块限定解析用模块自身 SHA1 构造正确符号。
|
||||
xm_at: ast.Attribute* = ast.Attribute*(cl.func)
|
||||
if xm_at is not None and xm_at.value is not None and trans is not None \
|
||||
and trans._imported_modules is not None:
|
||||
if xm_at is not None and xm_at.value is not None and trans is not None and trans._imported_modules is not None:
|
||||
# 模块路径:单层 Name(syslibtest_impl.run)或嵌套 Attribute
|
||||
# (os._win32.exists)。后者此前不校验 → os/__init__.vp 内部
|
||||
# 调 os._win32.exists 后缀匹配命中本模块同名 define →
|
||||
@@ -778,8 +775,7 @@ novirtual class CallGenMixin(CallGenBase.CallGenBase):
|
||||
# ---- abs(obj):对象定义了 __abs__ 时优先调度(对齐 TPC _HandleAbsLlvm)----
|
||||
# 仅当实参是类实例(注解类名可解析)且该类(含 MRO 祖先)定义了 __abs__ 时
|
||||
# 命中;否则保持既有内建/整数/浮点 abs 路径不变。
|
||||
if found_func is None and cl.func is not None and cl.func.kind() == ast.ASTKind.Name \
|
||||
and string.strcmp(func_name, "abs") == 0 and can == 1:
|
||||
if found_func is None and cl.func is not None and cl.func.kind() == ast.ASTKind.Name and string.strcmp(func_name, "abs") == 0 and can == 1:
|
||||
abs_arg: ast.AST* = cargs.get(0)
|
||||
if abs_arg is not None:
|
||||
abs_cls: str = self.Gen.CallGenProp._resolve_obj_class_name(pool, trans, abs_arg)
|
||||
@@ -951,9 +947,7 @@ novirtual class CallGenMixin(CallGenBase.CallGenBase):
|
||||
# 占位(命中后立即 return,不会用到)。
|
||||
# 守卫 trans.ReplCtx:非 REPL 恒 None ⇒ 不经过;且限定裸名(Name)——
|
||||
# 会话函数只以裸名导出,模块限定调用(mod.f)不走本表。
|
||||
if trans is not None and trans.ReplCtx is not None \
|
||||
and cl.func is not None and cl.func.kind() == ast.ASTKind.Name \
|
||||
and self.Gen.VarGen.repl_find_func_entry(trans.ReplCtx, func_name) is not None:
|
||||
if trans is not None and trans.ReplCtx is not None and cl.func is not None and cl.func.kind() == ast.ASTKind.Name and self.Gen.VarGen.repl_find_func_entry(trans.ReplCtx, func_name) is not None:
|
||||
bare_resolvable = 1
|
||||
call_ret_ty = self.Gen.CallGenLib._infer_external_func_ret_ty(pool, func_name, node, 1 - bare_resolvable)
|
||||
|
||||
@@ -983,9 +977,7 @@ novirtual class CallGenMixin(CallGenBase.CallGenBase):
|
||||
# obj(args) → obj.__call__(args)。仅当变量非闭包、非函数指针且其值
|
||||
# 指向结构体、该类(含 MRO 祖先)定义了 __call__ 时命中;其余情况
|
||||
# (get_struct_type_from_value 返回 None)保持既有闭包/函数指针路径。
|
||||
if trans is not None \
|
||||
and self.Gen.CallGenLeafKit.is_closure_name(func_name) == 0 \
|
||||
and self.Gen.CallGenLeafKit._is_func_ptr_alloca(fp_alloca) == 0:
|
||||
if trans is not None and self.Gen.CallGenLeafKit.is_closure_name(func_name) == 0 and self.Gen.CallGenLeafKit._is_func_ptr_alloca(fp_alloca) == 0:
|
||||
c_obj: mlirlite.Value* = self.Gen.ExprGenBase._deref_if_ptr_ptr(builder, fp_alloca)
|
||||
if c_obj is None:
|
||||
c_obj = fp_alloca
|
||||
@@ -1042,8 +1034,7 @@ novirtual class CallGenMixin(CallGenBase.CallGenBase):
|
||||
# 命中后从 ctx 的函数指针槽 load 地址、按表内签名间接调用:函数代码只在
|
||||
# 定义片段里一份(不复制/不重编译),调用点只持指针。
|
||||
sfn_box: t.CPtr = None
|
||||
if trans is not None and trans.ReplCtx is not None \
|
||||
and (cl.func is None or cl.func.kind() == ast.ASTKind.Name):
|
||||
if trans is not None and trans.ReplCtx is not None and (cl.func is None or cl.func.kind() == ast.ASTKind.Name):
|
||||
sfn_box = stdlib.malloc(4)
|
||||
if sfn_box is not None:
|
||||
sfn_box[0] = 0
|
||||
@@ -1072,8 +1063,7 @@ novirtual class CallGenMixin(CallGenBase.CallGenBase):
|
||||
# 本模块 vpi 参数注解缓存就绪,循环内每参只做一次 O(1) 段等值判定。
|
||||
# 仅裸名(cl.func 是 Name):模块限定调用走 _coerce_args_to_def_params 已覆盖。
|
||||
same_mod_vpi: int = 0
|
||||
if trans is not None and trans.ModuleSha1 is not None \
|
||||
and cl.func is not None and cl.func.kind() == ast.ASTKind.Name:
|
||||
if trans is not None and trans.ModuleSha1 is not None and cl.func is not None and cl.func.kind() == ast.ASTKind.Name:
|
||||
if self.Gen.CallGenBase.TempDir is not None and self.Gen.CallGenBase.TempDirLen > 0:
|
||||
VpiReader._ensure_vpi_param_annot_loaded(trans.ModuleSha1, self.Gen.CallGenBase.TempDir)
|
||||
same_mod_vpi = 1
|
||||
@@ -1171,8 +1161,7 @@ novirtual class CallGenMixin(CallGenBase.CallGenBase):
|
||||
# 的同名检查同规则、同判据(段等值判定只做逐字节比较)。
|
||||
sm_is_str: int = 0
|
||||
if same_mod_vpi != 0:
|
||||
if VpiReader._vpi_param_annot_seg_is(trans.ModuleSha1, None, func_name, ai, "str") != 0 \
|
||||
or VpiReader._vpi_param_annot_seg_is(trans.ModuleSha1, None, func_name, ai, "bytes") != 0:
|
||||
if VpiReader._vpi_param_annot_seg_is(trans.ModuleSha1, None, func_name, ai, "str") != 0 or VpiReader._vpi_param_annot_seg_is(trans.ModuleSha1, None, func_name, ai, "bytes") != 0:
|
||||
sm_is_str = 1
|
||||
if sm_is_str != 0:
|
||||
self.Gen.ExprGenBase.fail_if_str_annot_agg_ptr(arg_val, 1, arg)
|
||||
@@ -1446,8 +1435,7 @@ novirtual class CallGenMixin(CallGenBase.CallGenBase):
|
||||
cs_buf[cs_seg] = '\0'
|
||||
cand_sha1: str = self._lookup_module_sha1(cs_buf)
|
||||
if cand_sha1 is not None:
|
||||
if self.Gen.CallGenBase.is_cexport_func(cand_sha1, func_name) != 0 or \
|
||||
self._is_state_func_from_vpi(pool, cand_sha1, func_name) != 0:
|
||||
if self.Gen.CallGenBase.is_cexport_func(cand_sha1, func_name) != 0 or self._is_state_func_from_vpi(pool, cand_sha1, func_name) != 0:
|
||||
mod_sha1 = cand_sha1
|
||||
call_name = func_name
|
||||
rs_found = 1
|
||||
@@ -1457,8 +1445,7 @@ novirtual class CallGenMixin(CallGenBase.CallGenBase):
|
||||
# 原模块自身(extern def 如 stdlib.malloc 定义在 stdlib,
|
||||
# 而 stdlib 又 `from stdint import *` 产生误候选 stdint)。
|
||||
# 先验证原模块:extern/State → 裸名(rs_found=1 下方置裸名)。
|
||||
if self.Gen.CallGenBase.is_cexport_func(mod_sha1, func_name) != 0 or \
|
||||
self._is_state_func_from_vpi(pool, mod_sha1, func_name) != 0:
|
||||
if self.Gen.CallGenBase.is_cexport_func(mod_sha1, func_name) != 0 or self._is_state_func_from_vpi(pool, mod_sha1, func_name) != 0:
|
||||
rs_found = 1
|
||||
call_name = func_name
|
||||
else:
|
||||
@@ -1468,8 +1455,7 @@ novirtual class CallGenMixin(CallGenBase.CallGenBase):
|
||||
# vpi 命中 → 保持原模块 sha(生成 @{mod_sha1}.func,
|
||||
# 普通跨模块函数带 sha1 前缀),不走候选回退。
|
||||
orig_has_def: int = 0
|
||||
if self.Gen.CallGenBase.TempDir is not None \
|
||||
and self.Gen.CallGenBase.TempDirLen > 0:
|
||||
if self.Gen.CallGenBase.TempDir is not None and self.Gen.CallGenBase.TempDirLen > 0:
|
||||
VpiReader._ensure_vpi_ret_annot_loaded(mod_sha1, self.Gen.CallGenBase.TempDir)
|
||||
if VpiReader._lookup_vpi_ret_annot(mod_sha1, None, func_name) is not None:
|
||||
orig_has_def = 1
|
||||
@@ -1656,8 +1642,7 @@ novirtual class CallGenMixin(CallGenBase.CallGenBase):
|
||||
cf_last: str = string.strrchr(call_name, '.')
|
||||
if cf_dot is not None and cf_last is not None:
|
||||
cf_sha1: str = stdlib.malloc(17)
|
||||
cf_bare_len: sizet = string.strlen(call_name) - \
|
||||
(sizet(uint64(cf_last) - uint64(call_name))) - 1
|
||||
cf_bare_len: sizet = string.strlen(call_name) - (sizet(uint64(cf_last) - uint64(call_name))) - 1
|
||||
cf_bare: str = stdlib.malloc(cf_bare_len + 1)
|
||||
if cf_sha1 is not None and cf_bare is not None:
|
||||
string.strncpy(cf_sha1, call_name, 16)
|
||||
|
||||
@@ -97,8 +97,7 @@ novirtual class CallGenProp(CallGenBase.CallGenBase):
|
||||
else:
|
||||
# Phase A 依赖未就绪(cls_sha1_rt None / 定义模块 text.ll 未生成):
|
||||
# 保持默认 i32(build_call(Void) 返回 None 会破坏表达式翻译)。
|
||||
if cls_sha1_rt is None \
|
||||
or self._dep_text_ll_exists(pool, cls_sha1_rt) == 0:
|
||||
if cls_sha1_rt is None or self._dep_text_ll_exists(pool, cls_sha1_rt) == 0:
|
||||
call_ret_ty = mlirlite.Int32(pool)
|
||||
else:
|
||||
call_ret_ty = self._fail_method_ret_ty(method_name)
|
||||
|
||||
@@ -483,12 +483,10 @@ novirtual class ClassGenBase:
|
||||
is_prop_name = 1
|
||||
# @t.TLS 一次性初始化标记(对齐 TPC HandlesFunctions.py
|
||||
# L1223-1231:value 必须为 Name('t');@TLS 裸名走上面 Name 分支)
|
||||
if vn.id is not None and string.strcmp(vn.id, "t") == 0 \
|
||||
and string.strcmp(at.attr, "TLS") == 0:
|
||||
if vn.id is not None and string.strcmp(vn.id, "t") == 0 and string.strcmp(at.attr, "TLS") == 0:
|
||||
meta |= META_TLS
|
||||
# @property.setter 或 @x.setter/getter/deleter 都识别
|
||||
if is_prop_name != 0 or string.strcmp(at.attr, "setter") == 0 \
|
||||
or string.strcmp(at.attr, "getter") == 0 or string.strcmp(at.attr, "deleter") == 0:
|
||||
if is_prop_name != 0 or string.strcmp(at.attr, "setter") == 0 or string.strcmp(at.attr, "getter") == 0 or string.strcmp(at.attr, "deleter") == 0:
|
||||
if string.strcmp(at.attr, "setter") == 0:
|
||||
meta |= GenTypes.META_PROP_SETTER
|
||||
elif string.strcmp(at.attr, "getter") == 0:
|
||||
@@ -612,8 +610,7 @@ novirtual class ClassGenBase:
|
||||
self.ExceptionNames = pp_e.alloc(EXCEPTION_MAX * EXCEPTION_NAME_LEN)
|
||||
self.ExceptionParents = pp_e.alloc(EXCEPTION_MAX * EXCEPTION_NAME_LEN)
|
||||
self.ExceptionCodes = pp_e.alloc(EXCEPTION_MAX * 4)
|
||||
if self.ExceptionNames is None or self.ExceptionParents is None \
|
||||
or self.ExceptionCodes is None:
|
||||
if self.ExceptionNames is None or self.ExceptionParents is None or self.ExceptionCodes is None:
|
||||
return -1
|
||||
string.memset(self.ExceptionNames, 0, EXCEPTION_MAX * EXCEPTION_NAME_LEN)
|
||||
string.memset(self.ExceptionParents, 0, EXCEPTION_MAX * EXCEPTION_NAME_LEN)
|
||||
@@ -773,8 +770,7 @@ novirtual class ClassGenBase:
|
||||
base_name_e2 = base_at_e2.attr
|
||||
if base_name_e2 is None:
|
||||
continue
|
||||
if string.strcmp(base_name_e2, "Exception") != 0 \
|
||||
and self.is_exception_name(base_name_e2) != 0:
|
||||
if string.strcmp(base_name_e2, "Exception") != 0 and self.is_exception_name(base_name_e2) != 0:
|
||||
return base_name_e2
|
||||
return None
|
||||
def _register_exception_class_def(self, trans: HT.Translator*,
|
||||
|
||||
@@ -682,21 +682,18 @@ novirtual class ClassGenDef(ClassGenBase.ClassGenBase):
|
||||
fidx_add: int = self.Gen.StructGen.add_field(pool, entry, fname, fty2, fdef, fannot)
|
||||
# t.CVolatile 字段标记(field_volatile_buf[fi] 与 add_field 顺序一一对应)
|
||||
if fidx_add >= 0 and field_volatile_buf[fi] != 0:
|
||||
fe_vol: GenTypes.FieldEntry* = \
|
||||
self.Gen.StructGen._get_field_entry(entry, fidx_add)
|
||||
fe_vol: GenTypes.FieldEntry* = self.Gen.StructGen._get_field_entry(entry, fidx_add)
|
||||
if fe_vol is not None:
|
||||
fe_vol.IsVolatile = 1
|
||||
# rawptr[t.CVolatile | T] 字段标记(field_pointee_volatile_buf[fi] 与
|
||||
# add_field 顺序一一对应):经该字段解引用时 load/store 带 volatile。
|
||||
if fidx_add >= 0 and field_pointee_volatile_buf[fi] != 0:
|
||||
fe_pv: GenTypes.FieldEntry* = \
|
||||
self.Gen.StructGen._get_field_entry(entry, fidx_add)
|
||||
fe_pv: GenTypes.FieldEntry* = self.Gen.StructGen._get_field_entry(entry, fidx_add)
|
||||
if fe_pv is not None:
|
||||
fe_pv.PointeeVolatile = 1
|
||||
# const 对象字段标记(field_const_buf[fi] 与 add_field 顺序一一对应)
|
||||
if fidx_add >= 0 and field_const_buf[fi] != 0:
|
||||
fe_c: GenTypes.FieldEntry* = \
|
||||
self.Gen.StructGen._get_field_entry(entry, fidx_add)
|
||||
fe_c: GenTypes.FieldEntry* = self.Gen.StructGen._get_field_entry(entry, fidx_add)
|
||||
if fe_c is not None:
|
||||
fe_c.IsConst = 1
|
||||
|
||||
|
||||
@@ -299,16 +299,14 @@ novirtual class ClassGenEnum(ClassGenBase.ClassGenBase):
|
||||
return stmt
|
||||
elif sk == ast.ASTKind.AnnAssign:
|
||||
aa: ast.AnnAssign* = ast.AnnAssign*(stmt)
|
||||
if aa.target is not None and aa.target.kind() != ast.ASTKind.Name \
|
||||
and self._enum_target_visible_names(aa.target) > 0:
|
||||
if aa.target is not None and aa.target.kind() != ast.ASTKind.Name and self._enum_target_visible_names(aa.target) > 0:
|
||||
return stmt
|
||||
elif sk == ast.ASTKind.Assign:
|
||||
ag: ast.Assign* = ast.Assign*(stmt)
|
||||
if ag.targets is not None:
|
||||
for ti in range(len(ag.targets)):
|
||||
tgt: ast.AST* = ag.targets.get(ti)
|
||||
if tgt is not None and tgt.kind() != ast.ASTKind.Name \
|
||||
and self._enum_target_visible_names(tgt) > 0:
|
||||
if tgt is not None and tgt.kind() != ast.ASTKind.Name and self._enum_target_visible_names(tgt) > 0:
|
||||
return stmt
|
||||
return None
|
||||
def _translate_enum_def(self, trans: HT.Translator*,
|
||||
@@ -1063,8 +1061,7 @@ novirtual class ClassGenEnum(ClassGenBase.ClassGenBase):
|
||||
if stmt is None or stmt.kind() != ast.ASTKind.ClassDef:
|
||||
continue
|
||||
variant_cd: ast.ClassDef* = ast.ClassDef*(stmt)
|
||||
if variant_cd is None or variant_cd.name is None \
|
||||
or variant_cd.children is None:
|
||||
if variant_cd is None or variant_cd.name is None or variant_cd.children is None:
|
||||
continue
|
||||
vchildren: list[ast.AST*]* = variant_cd.children
|
||||
vcn: sizet = len(vchildren)
|
||||
@@ -1291,8 +1288,7 @@ novirtual class ClassGenEnum(ClassGenBase.ClassGenBase):
|
||||
n_first_v: int = 0
|
||||
if self.RenumClassNames is not None and self.RenumClassCount > 0:
|
||||
cls_first = str(self.RenumClassNames[0])
|
||||
if self.RenumVariantNames is not None \
|
||||
and self.RenumClassVariantCounts is not None:
|
||||
if self.RenumVariantNames is not None and self.RenumClassVariantCounts is not None:
|
||||
n_first_v = self.RenumClassVariantCounts[0]
|
||||
if n_first_v > 0:
|
||||
v_first = str(self.RenumVariantNames[0])
|
||||
|
||||
@@ -119,8 +119,7 @@ novirtual class ClassGenGeneric(ClassGenBase.ClassGenBase):
|
||||
# `self.elem_size = T.__sizeof__()`)。
|
||||
# 故此处补缺:本次能拿到 tp 名就把空槽填上,并把节点换成信息更全的
|
||||
# 这一个(节点也用于 _find_generic_template 的后续读取)。
|
||||
if self.GenericClassTpParams is not None and i < GENERIC_TEMPLATE_MAX \
|
||||
and self.GenericClassTpParams[i] == 0:
|
||||
if self.GenericClassTpParams is not None and i < GENERIC_TEMPLATE_MAX and self.GenericClassTpParams[i] == 0:
|
||||
back_buf: str = self._copy_type_params_stdlib(cd.type_params)
|
||||
if back_buf is not None:
|
||||
self.GenericClassTpParams[i] = sizet(back_buf)
|
||||
@@ -280,8 +279,7 @@ novirtual class ClassGenGeneric(ClassGenBase.ClassGenBase):
|
||||
pool 有效)。逐字节解析逻辑与 _find_generic_template_tp_params 一致:
|
||||
空格分隔;elem_size 必须传 8(str 指针 8 字节)。
|
||||
"""
|
||||
if self.GenericFuncKeys is None or key is None \
|
||||
or self.GenericFuncTpParams is None:
|
||||
if self.GenericFuncKeys is None or key is None or self.GenericFuncTpParams is None:
|
||||
return None
|
||||
keys_local: list[str]* = self.GenericFuncKeys
|
||||
kn: sizet = len(keys_local)
|
||||
@@ -691,9 +689,7 @@ novirtual class ClassGenGeneric(ClassGenBase.ClassGenBase):
|
||||
return None
|
||||
# CExport/CExtern/State 存储标记的泛型函数不支持(特化名会绕过裸名导出语义)
|
||||
if template_fd.returns is not None:
|
||||
if self.Gen.TypeGenErr.has_decorator_marker(template_fd.returns, "CExport", 0) != 0 \
|
||||
or self.Gen.TypeGenErr.has_decorator_marker(template_fd.returns, "CExtern", 0) != 0 \
|
||||
or self.Gen.TypeGenErr.has_decorator_marker(template_fd.returns, "State", 0) != 0:
|
||||
if self.Gen.TypeGenErr.has_decorator_marker(template_fd.returns, "CExport", 0) != 0 or self.Gen.TypeGenErr.has_decorator_marker(template_fd.returns, "CExtern", 0) != 0 or self.Gen.TypeGenErr.has_decorator_marker(template_fd.returns, "State", 0) != 0:
|
||||
self.Gen.TypeGenErr.fatal_error(template_fd, "泛型函数暂不支持 t.CExport/t.CExtern/t.State 存储标记", "TypeError")
|
||||
# 生成特化名(唯一生成器内部逐实参规范化,裸名/带前缀在此收敛为同一名)
|
||||
spec_base: str = self._mangle_generic_class_name(pool, template_fd.name, type_args, trans._from_imports)
|
||||
@@ -777,8 +773,7 @@ novirtual class ClassGenGeneric(ClassGenBase.ClassGenBase):
|
||||
从注册时深拷贝的 stdlib 缓冲区重建当前 pool 的 list[str]
|
||||
(特化期间 pool 有效,方法与体翻译共用)。与 GenericClassNames 同序。
|
||||
"""
|
||||
if self.GenericClassNames is None or class_name is None \
|
||||
or self.GenericClassTpParams is None:
|
||||
if self.GenericClassNames is None or class_name is None or self.GenericClassTpParams is None:
|
||||
return None
|
||||
names_local: list[str]* = self.GenericClassNames
|
||||
cn: sizet = len(names_local)
|
||||
@@ -1178,8 +1173,7 @@ novirtual class ClassGenGeneric(ClassGenBase.ClassGenBase):
|
||||
tp: list[str]* = self._find_generic_template_tp_params(pool, class_name)
|
||||
if tp is not None and len(tp) > 0:
|
||||
return tp
|
||||
if template_cd is not None and template_cd.type_params is not None \
|
||||
and len(template_cd.type_params) > 0:
|
||||
if template_cd is not None and template_cd.type_params is not None and len(template_cd.type_params) > 0:
|
||||
return template_cd.type_params
|
||||
self.Gen.TypeGenErr.fatal_error(None,
|
||||
f"泛型类模板 '{class_name}' 的类型参数名缺失(GenericClassTpParams 对应槽为空,"
|
||||
|
||||
@@ -657,9 +657,7 @@ novirtual class ClassGenVTable(ClassGenBase.ClassGenBase):
|
||||
# 存储类标记(t.State / t.CExport / t.CExtern)语义为 Void:这类注解
|
||||
# 不携带真实返回类型(extern/export 语法写成 "<原类型> | t.<标记>",
|
||||
# 原类型已解析成功时不会走到这里,此处只处理标记本身/解析后仍为 None)。
|
||||
if self.Gen.TypeGenErr.has_decorator_marker(fd.returns, "State", 0) != 0 \
|
||||
or self.Gen.TypeGenErr.has_decorator_marker(fd.returns, "CExport", 0) != 0 \
|
||||
or self.Gen.TypeGenErr.has_decorator_marker(fd.returns, "CExtern", 0) != 0:
|
||||
if self.Gen.TypeGenErr.has_decorator_marker(fd.returns, "State", 0) != 0 or self.Gen.TypeGenErr.has_decorator_marker(fd.returns, "CExport", 0) != 0 or self.Gen.TypeGenErr.has_decorator_marker(fd.returns, "CExtern", 0) != 0:
|
||||
ret_ty = mlirlite.Void(pool)
|
||||
else:
|
||||
# [S4 fail-fast] 有返回注解但解析失败 → 不再退回 infer_return_type()
|
||||
@@ -1032,9 +1030,7 @@ novirtual class ClassGenVTable(ClassGenBase.ClassGenBase):
|
||||
last_stmt3_m: ast.AST* = body.get(bn3 - 1)
|
||||
if last_stmt3_m is not None:
|
||||
k3m: int = last_stmt3_m.kind()
|
||||
if k3m == ast.ASTKind.If or k3m == ast.ASTKind.While or \
|
||||
k3m == ast.ASTKind.For or k3m == ast.ASTKind.Try or \
|
||||
k3m == ast.ASTKind.With or k3m == ast.ASTKind.Match:
|
||||
if k3m == ast.ASTKind.If or k3m == ast.ASTKind.While or k3m == ast.ASTKind.For or k3m == ast.ASTKind.Try or k3m == ast.ASTKind.With or k3m == ast.ASTKind.Match:
|
||||
last_is_ctrl = 1
|
||||
_is_void: int = 0
|
||||
if ret_ty is not None:
|
||||
@@ -1274,8 +1270,7 @@ novirtual class ClassGenVTable(ClassGenBase.ClassGenBase):
|
||||
# 误译成动态 list 对象指针,coerce 到 [N x elem] 会失败)。
|
||||
# 单参 CArray 字段(如 t.CArray[str] = [...])经类体字段收集
|
||||
# 推断为静态数组,此处保证 __before_init__ 填充真实字符串指针。
|
||||
if fe.Ty is not None and self.Gen.ExprGenBase.is_array_type(fe.Ty) != 0 \
|
||||
and fe.DefaultVal.kind() == ast.ASTKind.List:
|
||||
if fe.Ty is not None and self.Gen.ExprGenBase.is_array_type(fe.Ty) != 0 and fe.DefaultVal.kind() == ast.ASTKind.List:
|
||||
field_ptr_arr: mlirlite.Value* = mlirlite.build_gep_struct(func_builder, struct_ty, fe.Ty, self_val, fe.Index)
|
||||
if field_ptr_arr is not None:
|
||||
zero_arr_f: mlirlite.Value* = mlirlite.ConstZero(pool, fe.Ty)
|
||||
|
||||
@@ -287,8 +287,7 @@ def _EnsureLocation(pool: memhub.MemBuddy*, sp: int, line: int, col: int) -> str
|
||||
if _g_loc_used[slot] == 0:
|
||||
break
|
||||
kbase: int = slot * DBG_LOC_KEY_STRIDE
|
||||
if int(_g_loc_key[kbase]) == sp and int(_g_loc_key[kbase + 1]) == line \
|
||||
and int(_g_loc_key[kbase + 2]) == c:
|
||||
if int(_g_loc_key[kbase]) == sp and int(_g_loc_key[kbase + 1]) == line and int(_g_loc_key[kbase + 2]) == c:
|
||||
return _LocRefAt(slot)
|
||||
pi += 1
|
||||
lbuf: str = pool.alloc(96)
|
||||
|
||||
@@ -496,8 +496,7 @@ novirtual class ExprGenAttr(ExprGenBase.ExprGenBase):
|
||||
rn_at_rv: ast.Attribute* = ast.Attribute*(at.value)
|
||||
if rn_at_rv.attr is not None:
|
||||
renum_cls_rv = rn_at_rv.attr
|
||||
if renum_cls_rv is not None \
|
||||
and self.Gen.ClassGenEnum._is_renum_class_name(renum_cls_rv) != 0:
|
||||
if renum_cls_rv is not None and self.Gen.ClassGenEnum._is_renum_class_name(renum_cls_rv) != 0:
|
||||
rv_tag: int = self.Gen.ClassGenEnum._lookup_renum_variant_in_class(renum_cls_rv, at.attr)
|
||||
if rv_tag >= 0:
|
||||
name_buf_rv: str = pool.alloc(32)
|
||||
@@ -521,8 +520,7 @@ novirtual class ExprGenAttr(ExprGenBase.ExprGenBase):
|
||||
if fd_meta_v is not None:
|
||||
fd_sty: mlirlite.LLVMType* = self.Gen.StructGen.get_struct_type("_str")
|
||||
if fd_sty is not None:
|
||||
fd_fe: GenTypes.FieldEntry* = \
|
||||
self.Gen.StructGen.lookup_field(fd_sty, at.attr)
|
||||
fd_fe: GenTypes.FieldEntry* = self.Gen.StructGen.lookup_field(fd_sty, at.attr)
|
||||
if fd_fe is not None and fd_fe.Ty is not None:
|
||||
fd_fp: mlirlite.Value* = mlirlite.build_gep_struct(builder, fd_sty, fd_fe.Ty, fd_meta_v, fd_fe.Index)
|
||||
if fd_fp is not None:
|
||||
@@ -736,8 +734,7 @@ novirtual class ExprGenAttr(ExprGenBase.ExprGenBase):
|
||||
case mlirlite.LLVMType.Array(_, _):
|
||||
obj_ptr = mlirlite.build_bitcast(builder, raw_nl_a, mlirlite.Ptr(pool, nl_ty_a))
|
||||
case _:
|
||||
nl_val_ptr_a: mlirlite.Value* = \
|
||||
mlirlite.build_bitcast(builder, raw_nl_a, mlirlite.Ptr(pool, nl_ty_a))
|
||||
nl_val_ptr_a: mlirlite.Value* = mlirlite.build_bitcast(builder, raw_nl_a, mlirlite.Ptr(pool, nl_ty_a))
|
||||
if nl_val_ptr_a is not None:
|
||||
obj_ptr = mlirlite.build_load(builder, nl_ty_a, nl_val_ptr_a)
|
||||
else:
|
||||
@@ -891,12 +888,9 @@ novirtual class ExprGenAttr(ExprGenBase.ExprGenBase):
|
||||
# 变体别名回退一致):field_info 是 _pN 槽位(i32/i64),
|
||||
# 直接 load 得整数位模式 → 赋给 X* 指针变量触发 int→ptr
|
||||
# 误报。bitcast 槽位地址后按声明类型 load(同宽无信息丢失)。
|
||||
rn_rd_se: GenTypes.StructEntry* = \
|
||||
self.Gen.StructGen.find_struct_by_type(struct_ty)
|
||||
if rn_rd_se is not None and rn_rd_se.Name is not None \
|
||||
and self.Gen.ClassGenEnum._is_renum_class_name(rn_rd_se.Name) != 0:
|
||||
decl_ty_rd: mlirlite.LLVMType* = \
|
||||
self.Gen.ClassGenEnum._lookup_renum_field_alias_ty(rn_rd_se.Name, at.attr)
|
||||
rn_rd_se: GenTypes.StructEntry* = self.Gen.StructGen.find_struct_by_type(struct_ty)
|
||||
if rn_rd_se is not None and rn_rd_se.Name is not None and self.Gen.ClassGenEnum._is_renum_class_name(rn_rd_se.Name) != 0:
|
||||
decl_ty_rd: mlirlite.LLVMType* = self.Gen.ClassGenEnum._lookup_renum_field_alias_ty(rn_rd_se.Name, at.attr)
|
||||
if decl_ty_rd is not None and self.is_array_type(decl_ty_rd) == 0:
|
||||
decl_ptr_rd: mlirlite.LLVMType* = mlirlite.Ptr(pool, decl_ty_rd)
|
||||
if decl_ptr_rd is not None:
|
||||
@@ -914,8 +908,7 @@ novirtual class ExprGenAttr(ExprGenBase.ExprGenBase):
|
||||
# 内嵌结构体字段(field_ty=Struct)load 出的是结构体值,
|
||||
# bitcast 值→指针是非法 IR(llc: invalid cast opcode)。
|
||||
fc_annot: str = self.Gen.StructGen.get_field_annot_class_name(field_info)
|
||||
if loaded_val is not None and fc_annot is not None \
|
||||
and self.is_ptr_type(field_ty) != 0:
|
||||
if loaded_val is not None and fc_annot is not None and self.is_ptr_type(field_ty) != 0:
|
||||
annot_struct: GenTypes.StructEntry* = self.Gen.StructGen.find_struct(fc_annot)
|
||||
if annot_struct is not None and annot_struct.Ty is not None:
|
||||
# 确保目标结构体类型在当前模块有声明(可能未定义/未 opaque):
|
||||
|
||||
@@ -378,8 +378,7 @@ novirtual class ExprGenBase:
|
||||
if cn_nv is not None and cn_nv.const_kind == ast.CONST_NONE:
|
||||
return 1
|
||||
# 判据②:已生成好的 null 常量(指针类型 + 编译期零)
|
||||
if val is not None and val.IsConst == 1 and val.IntVal == 0 \
|
||||
and self.is_ptr_type(val.Ty) != 0:
|
||||
if val is not None and val.IsConst == 1 and val.IntVal == 0 and self.is_ptr_type(val.Ty) != 0:
|
||||
return 1
|
||||
return 0
|
||||
# ============================================================
|
||||
@@ -918,8 +917,7 @@ novirtual class ExprGenBase:
|
||||
val_fbits: int = self.get_llvm_float_bits(val.Ty)
|
||||
target_fbits: int = self.get_llvm_float_bits(target_ty)
|
||||
# float ↔ ptr: 禁止(无意义的转换,fast-fail 防止误走入 build_load 路径)
|
||||
if (val_fbits != 0 and self.is_ptr_type(target_ty) != 0) or \
|
||||
(self.is_ptr_type(val.Ty) != 0 and target_fbits != 0):
|
||||
if (val_fbits != 0 and self.is_ptr_type(target_ty) != 0) or (self.is_ptr_type(val.Ty) != 0 and target_fbits != 0):
|
||||
self.Gen.TypeGenErr.fatal_error(self._value_node_of(node),
|
||||
"unsupported type conversion: float <-> ptr", "CastError")
|
||||
return val
|
||||
|
||||
@@ -173,8 +173,7 @@ novirtual class ExprGenCdef(ExprGenBase.ExprGenBase):
|
||||
base_mod: str = None
|
||||
if mod_name_raw is not None:
|
||||
mbl: sizet = 0
|
||||
while mod_name_raw[mbl] != ' ' and mod_name_raw[mbl] != '\0' \
|
||||
and mod_name_raw[mbl] != ':':
|
||||
while mod_name_raw[mbl] != ' ' and mod_name_raw[mbl] != '\0' and mod_name_raw[mbl] != ':':
|
||||
mbl += 1
|
||||
mb_buf: str = pool.alloc(mbl + 1)
|
||||
if mb_buf is not None:
|
||||
@@ -484,14 +483,11 @@ novirtual class ExprGenCdef(ExprGenBase.ExprGenBase):
|
||||
is_hex = 1
|
||||
val_str_len = 2
|
||||
eq_pos += 2
|
||||
elif (pyi_buf[eq_pos] >= 'A' and pyi_buf[eq_pos] <= 'Z') or \
|
||||
(pyi_buf[eq_pos] >= 'a' and pyi_buf[eq_pos] <= 'z') or \
|
||||
pyi_buf[eq_pos] == '_':
|
||||
elif (pyi_buf[eq_pos] >= 'A' and pyi_buf[eq_pos] <= 'Z') or (pyi_buf[eq_pos] >= 'a' and pyi_buf[eq_pos] <= 'z') or pyi_buf[eq_pos] == '_':
|
||||
is_name_val = 1
|
||||
while eq_pos < line_start + line_len:
|
||||
c_tk: char = pyi_buf[eq_pos]
|
||||
if (c_tk >= 'A' and c_tk <= 'Z') or (c_tk >= 'a' and c_tk <= 'z') or \
|
||||
(c_tk >= '0' and c_tk <= '9') or c_tk == '_':
|
||||
if (c_tk >= 'A' and c_tk <= 'Z') or (c_tk >= 'a' and c_tk <= 'z') or (c_tk >= '0' and c_tk <= '9') or c_tk == '_':
|
||||
val_str_len += 1
|
||||
eq_pos += 1
|
||||
else:
|
||||
@@ -636,14 +632,11 @@ novirtual class ExprGenCdef(ExprGenBase.ExprGenBase):
|
||||
r_hex = 1
|
||||
r_len = 2
|
||||
eq_pos += 2
|
||||
elif (pyi_buf[eq_pos] >= 'A' and pyi_buf[eq_pos] <= 'Z') or \
|
||||
(pyi_buf[eq_pos] >= 'a' and pyi_buf[eq_pos] <= 'z') or \
|
||||
pyi_buf[eq_pos] == '_':
|
||||
elif (pyi_buf[eq_pos] >= 'A' and pyi_buf[eq_pos] <= 'Z') or (pyi_buf[eq_pos] >= 'a' and pyi_buf[eq_pos] <= 'z') or pyi_buf[eq_pos] == '_':
|
||||
r_name = 1
|
||||
while eq_pos < line_start + line_len:
|
||||
c_r: char = pyi_buf[eq_pos]
|
||||
if (c_r >= 'A' and c_r <= 'Z') or (c_r >= 'a' and c_r <= 'z') or \
|
||||
(c_r >= '0' and c_r <= '9') or c_r == '_':
|
||||
if (c_r >= 'A' and c_r <= 'Z') or (c_r >= 'a' and c_r <= 'z') or (c_r >= '0' and c_r <= '9') or c_r == '_':
|
||||
r_len += 1
|
||||
eq_pos += 1
|
||||
else:
|
||||
@@ -770,9 +763,7 @@ novirtual class ExprGenCdef(ExprGenBase.ExprGenBase):
|
||||
# 检查行是否以 "from " 开头(模块导入)
|
||||
if rc_line_len < 12:
|
||||
continue
|
||||
if pyi_buf[rc_line_start] != 'f' or pyi_buf[rc_line_start+1] != 'r' or \
|
||||
pyi_buf[rc_line_start+2] != 'o' or pyi_buf[rc_line_start+3] != 'm' or \
|
||||
pyi_buf[rc_line_start+4] != ' ':
|
||||
if pyi_buf[rc_line_start] != 'f' or pyi_buf[rc_line_start+1] != 'r' or pyi_buf[rc_line_start+2] != 'o' or pyi_buf[rc_line_start+3] != 'm' or pyi_buf[rc_line_start+4] != ' ':
|
||||
continue
|
||||
|
||||
# 提取模块路径 token(从 rc_line_start+5 到空格/tab 为止,跳过前导点)
|
||||
@@ -785,13 +776,11 @@ novirtual class ExprGenCdef(ExprGenBase.ExprGenBase):
|
||||
# "跨模块 CDefine 未找到: 'vqt6.QT_ALIGN_CENTER'"。
|
||||
rc_is_rel: int = 0
|
||||
rc_sub_start: sizet = rc_line_start + 5
|
||||
while rc_sub_start < rc_line_start + rc_line_len and \
|
||||
pyi_buf[rc_sub_start] == '.':
|
||||
while rc_sub_start < rc_line_start + rc_line_len and pyi_buf[rc_sub_start] == '.':
|
||||
rc_is_rel = 1
|
||||
rc_sub_start += 1
|
||||
rc_sub_end: sizet = rc_sub_start
|
||||
while rc_sub_end < rc_line_start + rc_line_len and \
|
||||
pyi_buf[rc_sub_end] != ' ' and pyi_buf[rc_sub_end] != '\t':
|
||||
while rc_sub_end < rc_line_start + rc_line_len and pyi_buf[rc_sub_end] != ' ' and pyi_buf[rc_sub_end] != '\t':
|
||||
rc_sub_end += 1
|
||||
rc_sub_len: sizet = rc_sub_end - rc_sub_start
|
||||
if rc_sub_len == 0:
|
||||
@@ -801,9 +790,7 @@ novirtual class ExprGenCdef(ExprGenBase.ExprGenBase):
|
||||
rc_has_import: int = 0
|
||||
rc_ipos: sizet = rc_sub_end
|
||||
while rc_ipos + 6 <= rc_line_start + rc_line_len:
|
||||
if pyi_buf[rc_ipos] == 'i' and pyi_buf[rc_ipos+1] == 'm' and \
|
||||
pyi_buf[rc_ipos+2] == 'p' and pyi_buf[rc_ipos+3] == 'o' and \
|
||||
pyi_buf[rc_ipos+4] == 'r' and pyi_buf[rc_ipos+5] == 't':
|
||||
if pyi_buf[rc_ipos] == 'i' and pyi_buf[rc_ipos+1] == 'm' and pyi_buf[rc_ipos+2] == 'p' and pyi_buf[rc_ipos+3] == 'o' and pyi_buf[rc_ipos+4] == 'r' and pyi_buf[rc_ipos+5] == 't':
|
||||
rc_has_import = 1
|
||||
break
|
||||
rc_ipos += 1
|
||||
@@ -863,9 +850,7 @@ novirtual class ExprGenCdef(ExprGenBase.ExprGenBase):
|
||||
rc_before_ok = 1
|
||||
else:
|
||||
rc_before_ch: char = pyi_buf[rc_cpos - 1]
|
||||
if rc_before_ch == ' ' or rc_before_ch == '\t' or \
|
||||
rc_before_ch == '(' or rc_before_ch == ',' or \
|
||||
rc_before_ch == '\n' or rc_before_ch == '\r':
|
||||
if rc_before_ch == ' ' or rc_before_ch == '\t' or rc_before_ch == '(' or rc_before_ch == ',' or rc_before_ch == '\n' or rc_before_ch == '\r':
|
||||
rc_before_ok = 1
|
||||
# 检查后字符是否是非标识符字符
|
||||
rc_after_ok: int = 0
|
||||
@@ -874,9 +859,7 @@ novirtual class ExprGenCdef(ExprGenBase.ExprGenBase):
|
||||
rc_after_ok = 1
|
||||
else:
|
||||
rc_after_ch: char = pyi_buf[rc_after_pos]
|
||||
if rc_after_ch == ' ' or rc_after_ch == '\t' or \
|
||||
rc_after_ch == ')' or rc_after_ch == ',' or \
|
||||
rc_after_ch == '\r' or rc_after_ch == '\n':
|
||||
if rc_after_ch == ' ' or rc_after_ch == '\t' or rc_after_ch == ')' or rc_after_ch == ',' or rc_after_ch == '\r' or rc_after_ch == '\n':
|
||||
rc_after_ok = 1
|
||||
if rc_before_ok == 1 and rc_after_ok == 1:
|
||||
rc_name_match = 1
|
||||
@@ -927,8 +910,7 @@ novirtual class ExprGenCdef(ExprGenBase.ExprGenBase):
|
||||
rc_blen: sizet = string.strlen(base_mod)
|
||||
if rc_blen > rc_sub_len + 1:
|
||||
rc_tail: str = base_mod + (rc_blen - rc_sub_len)
|
||||
if rc_tail[0] == '.' and \
|
||||
string.strncmp(rc_tail + 1, rc_sub_buf, rc_sub_len) == 0:
|
||||
if rc_tail[0] == '.' and string.strncmp(rc_tail + 1, rc_sub_buf, rc_sub_len) == 0:
|
||||
continue
|
||||
|
||||
# 构建临时 from_imports "name:full_mod"
|
||||
|
||||
@@ -96,8 +96,7 @@ novirtual class ExprGenConst(ExprGenBase.ExprGenBase):
|
||||
# const_int 按十进制值打印,故 i64 -1 即全 1,语义正确。
|
||||
# 2) 否则维持旧规则:超出 i32 范围用 i64,其余 i32。
|
||||
iv: int64 = cn.int_val
|
||||
if target_ty is not None and self.is_ptr_type(target_ty) == 0 \
|
||||
and self.get_llvm_type_bits(target_ty) > 32:
|
||||
if target_ty is not None and self.is_ptr_type(target_ty) == 0 and self.get_llvm_type_bits(target_ty) > 32:
|
||||
return mlirlite.const_int64(pool, iv)
|
||||
if iv > 2147483647 or iv < -2147483648:
|
||||
return mlirlite.const_int64(pool, iv)
|
||||
@@ -108,8 +107,7 @@ novirtual class ExprGenConst(ExprGenBase.ExprGenBase):
|
||||
return mlirlite.ConstFloat(pool, double_ty, cn.float_val)
|
||||
elif cn.const_kind == ast.CONST_CHAR:
|
||||
# 单引号单字符字面量(CONST_CHAR):默认按字符值(i32,coerce 截断为 i8);但当目标类型是指针(str/bytes/t.CPtr)时须物化为 1 字符字符串,否则 coerce inttoptr 把字符值当指针(如 '"'=0x22)→ 运行期 strlen 访问低地址崩溃。1a 阶段(declare_only=1)依赖函数 found_func=None,target_ty 未对齐即视为垃圾跳过,避免 is_ptr_type 解引用崩溃
|
||||
if target_ty is not None and (uint64(target_ty) & 7) == 0 \
|
||||
and self.is_ptr_type(target_ty) != 0:
|
||||
if target_ty is not None and (uint64(target_ty) & 7) == 0 and self.is_ptr_type(target_ty) != 0:
|
||||
cbuf: bytes = stdlib.malloc(2)
|
||||
if cbuf is None:
|
||||
return mlirlite.const_int32(pool, 0)
|
||||
|
||||
@@ -473,8 +473,7 @@ novirtual class ExprGenFstr(ExprGenBase.ExprGenBase):
|
||||
if ibits != 0 and ibits < 32:
|
||||
return mlirlite.build_zext(builder, val, i32_ty)
|
||||
return val
|
||||
if fmt_char == 'd' or fmt_char == 'i' or fmt_char == 'x' \
|
||||
or fmt_char == 'X' or fmt_char == 'o' or fmt_char == 'u':
|
||||
if fmt_char == 'd' or fmt_char == 'i' or fmt_char == 'x' or fmt_char == 'X' or fmt_char == 'o' or fmt_char == 'u':
|
||||
ibits = self.Gen.ExprGenBase.get_llvm_type_bits(val.Ty)
|
||||
if ibits == 1:
|
||||
return mlirlite.build_zext(builder, val, i32_ty)
|
||||
@@ -483,8 +482,7 @@ novirtual class ExprGenFstr(ExprGenBase.ExprGenBase):
|
||||
return mlirlite.build_zext(builder, val, i32_ty)
|
||||
return mlirlite.build_sext(builder, val, i32_ty)
|
||||
return val
|
||||
if fmt_char == 'f' or fmt_char == 'e' or fmt_char == 'E' \
|
||||
or fmt_char == 'g' or fmt_char == 'G':
|
||||
if fmt_char == 'f' or fmt_char == 'e' or fmt_char == 'E' or fmt_char == 'g' or fmt_char == 'G':
|
||||
fbits: int = self.Gen.ExprGenBase.get_llvm_float_bits(val.Ty)
|
||||
if fbits == 32:
|
||||
return mlirlite.build_fpext(builder, val, mlirlite.Double(pool))
|
||||
|
||||
@@ -378,12 +378,7 @@ novirtual class ExprGenName(ExprGenBase.ExprGenBase):
|
||||
# 处理路径(如 CIf 未定义名特判走 else),保持返回 None 不报错。
|
||||
if nm_id is None:
|
||||
return None
|
||||
if string.strcmp(nm_id, "self") == 0 or string.strcmp(nm_id, "pool") == 0 \
|
||||
or string.strcmp(nm_id, "true") == 0 or string.strcmp(nm_id, "false") == 0 \
|
||||
or string.strcmp(nm_id, "None") == 0 or string.strcmp(nm_id, "match") == 0 \
|
||||
or string.strcmp(nm_id, "_") == 0 \
|
||||
or string.strcmp(nm_id, "CIf") == 0 or string.strcmp(nm_id, "CIfdef") == 0 \
|
||||
or string.strcmp(nm_id, "CIfndef") == 0:
|
||||
if string.strcmp(nm_id, "self") == 0 or string.strcmp(nm_id, "pool") == 0 or string.strcmp(nm_id, "true") == 0 or string.strcmp(nm_id, "false") == 0 or string.strcmp(nm_id, "None") == 0 or string.strcmp(nm_id, "match") == 0 or string.strcmp(nm_id, "_") == 0 or string.strcmp(nm_id, "CIf") == 0 or string.strcmp(nm_id, "CIfdef") == 0 or string.strcmp(nm_id, "CIfndef") == 0:
|
||||
return None
|
||||
# 诊断:把当前泛型上下文一并报出 —— "未定义名称 'T'" 常与真因(泛型上下文
|
||||
# 为空 / 装不上)严重脱节:形参 0 个 ⇒ 上下文根本没建起来;形参 >0 而实参 0
|
||||
@@ -488,8 +483,7 @@ novirtual class ExprGenName(ExprGenBase.ExprGenBase):
|
||||
# 才能经 LLVM 类型解析出类名 AST(T29 修复);否则统一 Ptr(i8) 丢失
|
||||
# 类名,.kind() 被当未绑定外部函数(AstTest NewAstTest fatal: 'kind'
|
||||
# 根因:list 元素类名没有沿 get(0) 调用结果值类型传播到后续分派)。
|
||||
elem_obj_ty_l: mlirlite.LLVMType* = \
|
||||
self._list_elem_obj_ty_from_struct_name(pool, struct_name)
|
||||
elem_obj_ty_l: mlirlite.LLVMType* = 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 字节槽位宽一致,
|
||||
@@ -551,12 +545,9 @@ novirtual class ExprGenName(ExprGenBase.ExprGenBase):
|
||||
# 见 TypeGenResolve._norm_type_arg_name 的指针书写归一),而
|
||||
# find_struct 只认类名本身;不剥则对象元素还原失败、静默退回 Ptr(i8)
|
||||
# 丢元素类名(链式 .get(0).kind() 分派回退根因)。
|
||||
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] == '"' \
|
||||
or cur_e[b_e - 1] == '*'):
|
||||
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] == '"' 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] == '"'):
|
||||
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: sizet = b_e - a_e
|
||||
@@ -565,8 +556,7 @@ novirtual class ExprGenName(ExprGenBase.ExprGenBase):
|
||||
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* = \
|
||||
self.Gen.StructGen.find_struct(seg_buf_e)
|
||||
s_entry_e: GenTypes.StructEntry* = self.Gen.StructGen.find_struct(seg_buf_e)
|
||||
if s_entry_e is not None and s_entry_e.Ty is not None:
|
||||
return mlirlite.Ptr(pool, s_entry_e.Ty)
|
||||
if i_e == total_e:
|
||||
@@ -827,8 +817,7 @@ novirtual class ExprGenName(ExprGenBase.ExprGenBase):
|
||||
elem_ty_v: mlirlite.LLVMType* = self._list_elem_type_from_name(pool, lsn_v)
|
||||
if elem_ty_v is not None:
|
||||
elem_ptr_ty_v: mlirlite.LLVMType* = mlirlite.Ptr(pool, elem_ty_v)
|
||||
casted_v: mlirlite.Value* = \
|
||||
mlirlite.build_bitcast(builder, elem_addr_v, elem_ptr_ty_v)
|
||||
casted_v: mlirlite.Value* = mlirlite.build_bitcast(builder, elem_addr_v, elem_ptr_ty_v)
|
||||
if casted_v is not None:
|
||||
return mlirlite.build_load(builder, elem_ty_v, casted_v)
|
||||
return None
|
||||
@@ -900,8 +889,7 @@ novirtual class ExprGenName(ExprGenBase.ExprGenBase):
|
||||
# 直接 GEP 按 i8* 步长(8 字节),load i8*
|
||||
# 仅当 inner_ty 不是自定义结构体时才走指针遍历
|
||||
if trans is not None:
|
||||
ve_pe_ts: GenTypes.VarEntry* = \
|
||||
self.Gen.VarGen.lookup_var_entry(trans.SymTab, nm.id)
|
||||
ve_pe_ts: GenTypes.VarEntry* = self.Gen.VarGen.lookup_var_entry(trans.SymTab, nm.id)
|
||||
if self.Gen.VarGen.var_is_ptr_element(ve_pe_ts) != 0:
|
||||
# bytes* / str* / T*:变量存指针值(i8*),
|
||||
# elem[i] 语义 = load [指针值 + i*8](8 字节指针元素)。
|
||||
@@ -929,8 +917,7 @@ novirtual class ExprGenName(ExprGenBase.ExprGenBase):
|
||||
# 元素是 8 字节指针,须按 i8* 步长 GEP + load i8*——
|
||||
# 否则 list.get 只读 1 字节,指针截断 inttoptr 崩溃。
|
||||
if trans is not None:
|
||||
ve_pe_rd: GenTypes.VarEntry* = \
|
||||
self.Gen.VarGen.lookup_var_entry(trans.SymTab, nm.id)
|
||||
ve_pe_rd: GenTypes.VarEntry* = self.Gen.VarGen.lookup_var_entry(trans.SymTab, nm.id)
|
||||
if self.Gen.VarGen.var_is_ptr_element(ve_pe_rd) != 0:
|
||||
match pointee:
|
||||
case mlirlite.LLVMType.Int(bits_rd):
|
||||
@@ -1162,8 +1149,7 @@ novirtual class ExprGenName(ExprGenBase.ExprGenBase):
|
||||
# 直接 GEP 按 i8* 步长(8 字节),不 load
|
||||
# 仅当 inner_ty 不是自定义结构体时才走指针遍历
|
||||
if trans is not None:
|
||||
ve_pe: GenTypes.VarEntry* = \
|
||||
self.Gen.VarGen.lookup_var_entry(trans.SymTab, nm.id)
|
||||
ve_pe: GenTypes.VarEntry* = self.Gen.VarGen.lookup_var_entry(trans.SymTab, nm.id)
|
||||
if self.Gen.VarGen.var_is_ptr_element(ve_pe) != 0:
|
||||
# bytes* / str* / T*:变量存指针值,
|
||||
# 下标语义 = [指针值 + i*8](8 字节指针元素)。必须先 load
|
||||
@@ -1204,8 +1190,7 @@ novirtual class ExprGenName(ExprGenBase.ExprGenBase):
|
||||
# elem_ptr: T* 退化为 i8*):pointee=i8 但
|
||||
# 元素是 8 字节指针,须按 i8* 步长 GEP(防只写 1 字节截断)
|
||||
if trans is not None:
|
||||
ve_pe_cs: GenTypes.VarEntry* = \
|
||||
self.Gen.VarGen.lookup_var_entry(trans.SymTab, nm.id)
|
||||
ve_pe_cs: GenTypes.VarEntry* = self.Gen.VarGen.lookup_var_entry(trans.SymTab, nm.id)
|
||||
if self.Gen.VarGen.var_is_ptr_element(ve_pe_cs) != 0:
|
||||
# T*(退化为 i8*,如 _list.vp 的 elem_ptr)变量
|
||||
# 存数据区指针,元素为 8 字节指针:必须先 load alloca
|
||||
|
||||
@@ -234,8 +234,7 @@ novirtual class ExprGenOps(ExprGenBase.ExprGenBase):
|
||||
at: ast.Attribute* = ast.Attribute*(cl.func)
|
||||
if at.value is not None and at.value.kind() == ast.ASTKind.Name:
|
||||
mod_nm: ast.Name* = ast.Name*(at.value)
|
||||
if mod_nm.id is not None and string.strcmp(mod_nm.id, "t") == 0 \
|
||||
and at.attr is not None:
|
||||
if mod_nm.id is not None and string.strcmp(mod_nm.id, "t") == 0 and at.attr is not None:
|
||||
if self._type_name_unsigned(at.attr) != 0:
|
||||
return 1
|
||||
return 0
|
||||
@@ -309,10 +308,8 @@ novirtual class ExprGenOps(ExprGenBase.ExprGenBase):
|
||||
if st_u is not None:
|
||||
fi_u: int = 0
|
||||
while fi_u < st_u.FieldCount:
|
||||
fe_u: GenTypes.FieldEntry* = \
|
||||
self.Gen.StructGen._get_field_entry(st_u, fi_u)
|
||||
if fe_u is not None and fe_u.Name is not None \
|
||||
and string.strcmp(fe_u.Name, at_u.attr) == 0:
|
||||
fe_u: GenTypes.FieldEntry* = self.Gen.StructGen._get_field_entry(st_u, fi_u)
|
||||
if fe_u is not None and fe_u.Name is not None and string.strcmp(fe_u.Name, at_u.attr) == 0:
|
||||
# [S4 切读] 字段 Spec 明确无符号优先
|
||||
if self._entry_spec_unsigned(fe_u.Spec) != 0:
|
||||
return 1
|
||||
@@ -344,8 +341,7 @@ novirtual class ExprGenOps(ExprGenBase.ExprGenBase):
|
||||
at: ast.Attribute* = ast.Attribute*(cl.func)
|
||||
if at.value is not None and at.value.kind() == ast.ASTKind.Name:
|
||||
mod_nm: ast.Name* = ast.Name*(at.value)
|
||||
if mod_nm.id is not None and string.strcmp(mod_nm.id, "t") == 0 \
|
||||
and at.attr is not None:
|
||||
if mod_nm.id is not None and string.strcmp(mod_nm.id, "t") == 0 and at.attr is not None:
|
||||
if self._spec_sign_from_annot(at.attr) == TSpec.TS_SIGN_SIGNED:
|
||||
return 1
|
||||
return 0
|
||||
|
||||
@@ -431,27 +431,13 @@ novirtual class FuncGenDef(CallGenBase.CallGenBase):
|
||||
if dname is None:
|
||||
continue
|
||||
# 跳过内置装饰器
|
||||
if string.strcmp(dname, "staticmethod") == 0 \
|
||||
or string.strcmp(dname, "property") == 0 \
|
||||
or string.strcmp(dname, "classmethod") == 0:
|
||||
if string.strcmp(dname, "staticmethod") == 0 or string.strcmp(dname, "property") == 0 or string.strcmp(dname, "classmethod") == 0:
|
||||
continue
|
||||
# 跳过 t 模块存储类标记(@t.CExport/@t.CExtern/@t.State/@t.TLS/
|
||||
# @t.CStatic/@t.CInline/@t.CVTable/@t.NoVTable/@t.Object/@t.CEnum
|
||||
# /@t.CUnion/@t.REnum/@t.CDefine 等裸名形式——Attribute 形式
|
||||
# @t.xxx 的 kind 是 Attribute,不进入本检测)
|
||||
if string.strcmp(dname, "CExport") == 0 \
|
||||
or string.strcmp(dname, "CExtern") == 0 \
|
||||
or string.strcmp(dname, "State") == 0 \
|
||||
or string.strcmp(dname, "TLS") == 0 \
|
||||
or string.strcmp(dname, "CStatic") == 0 \
|
||||
or string.strcmp(dname, "CInline") == 0 \
|
||||
or string.strcmp(dname, "CVTable") == 0 \
|
||||
or string.strcmp(dname, "NoVTable") == 0 \
|
||||
or string.strcmp(dname, "Object") == 0 \
|
||||
or string.strcmp(dname, "CEnum") == 0 \
|
||||
or string.strcmp(dname, "CUnion") == 0 \
|
||||
or string.strcmp(dname, "REnum") == 0 \
|
||||
or string.strcmp(dname, "CDefine") == 0:
|
||||
if string.strcmp(dname, "CExport") == 0 or string.strcmp(dname, "CExtern") == 0 or string.strcmp(dname, "State") == 0 or string.strcmp(dname, "TLS") == 0 or string.strcmp(dname, "CStatic") == 0 or string.strcmp(dname, "CInline") == 0 or string.strcmp(dname, "CVTable") == 0 or string.strcmp(dname, "NoVTable") == 0 or string.strcmp(dname, "Object") == 0 or string.strcmp(dname, "CEnum") == 0 or string.strcmp(dname, "CUnion") == 0 or string.strcmp(dname, "REnum") == 0 or string.strcmp(dname, "CDefine") == 0:
|
||||
continue
|
||||
has_custom_decor = 1
|
||||
decor_handler = dname
|
||||
@@ -495,8 +481,7 @@ novirtual class FuncGenDef(CallGenBase.CallGenBase):
|
||||
arg_e: ast.Arg* = ast.Arg*(alist_e.get(ai_e))
|
||||
if arg_e is not None and arg_e.arg is not None:
|
||||
# CVoid 表示空参:跳过,不添加到函数签名
|
||||
if arg_e.annotation is not None \
|
||||
and self.Gen.TypeGenResolve._is_t_attr(arg_e.annotation, "CVoid", imported_modules) != 0:
|
||||
if arg_e.annotation is not None and self.Gen.TypeGenResolve._is_t_attr(arg_e.annotation, "CVoid", imported_modules) != 0:
|
||||
continue
|
||||
param_ty_e: mlirlite.LLVMType* = i32_ty
|
||||
if arg_e.annotation is not None:
|
||||
@@ -609,8 +594,7 @@ novirtual class FuncGenDef(CallGenBase.CallGenBase):
|
||||
arg: ast.Arg* = ast.Arg*(alist.get(ai))
|
||||
if arg is not None and arg.arg is not None:
|
||||
# CVoid 表示空参:跳过,不添加到函数签名
|
||||
if arg.annotation is not None \
|
||||
and self.Gen.TypeGenResolve._is_t_attr(arg.annotation, "CVoid", imported_modules) != 0:
|
||||
if arg.annotation is not None and self.Gen.TypeGenResolve._is_t_attr(arg.annotation, "CVoid", imported_modules) != 0:
|
||||
continue
|
||||
param_ty: mlirlite.LLVMType* = i32_ty
|
||||
if arg.annotation is not None:
|
||||
@@ -958,9 +942,7 @@ novirtual class FuncGenDef(CallGenBase.CallGenBase):
|
||||
last_stmt3: ast.AST* = body.get(bn3 - 1)
|
||||
if last_stmt3 is not None:
|
||||
k3: int = last_stmt3.kind()
|
||||
if k3 == ast.ASTKind.If or k3 == ast.ASTKind.While or \
|
||||
k3 == ast.ASTKind.For or k3 == ast.ASTKind.Try or \
|
||||
k3 == ast.ASTKind.With or k3 == ast.ASTKind.Match:
|
||||
if k3 == ast.ASTKind.If or k3 == ast.ASTKind.While or k3 == ast.ASTKind.For or k3 == ast.ASTKind.Try or k3 == ast.ASTKind.With or k3 == ast.ASTKind.Match:
|
||||
last_is_ctrl = 1
|
||||
_is_void: int = 0
|
||||
if ret_ty is not None:
|
||||
|
||||
@@ -345,10 +345,8 @@ novirtual class FuncGenMixin(CallGenBase.CallGenBase):
|
||||
ve_nl.Alloca = heap_typed
|
||||
# 记录到全局映射(后续层/父函数可见)
|
||||
gv_ref_new: mlirlite.Value* = None
|
||||
if gname_ck is not None \
|
||||
and self._nl_heap_global_exists(mod, gname_ck) == 0:
|
||||
gv_new: mlirlite.GlobalVariable* = \
|
||||
mlirlite.new_global_variable(pool, gname_ck, i8_ptr_ty)
|
||||
if gname_ck is not None and self._nl_heap_global_exists(mod, gname_ck) == 0:
|
||||
gv_new: mlirlite.GlobalVariable* = mlirlite.new_global_variable(pool, gname_ck, i8_ptr_ty)
|
||||
if gv_new is not None:
|
||||
# 清除 external linkage + 零初始化(防 undefined reference)
|
||||
gv_new.Linkage = None
|
||||
|
||||
@@ -117,9 +117,7 @@ novirtual class ImportsGenMixin:
|
||||
if old_ptr is None:
|
||||
idx_m = hashtable.HashTable(perm)
|
||||
idx_o = hashtable.HashTable(perm)
|
||||
elif old_ptr == self.CurFromImportsPtr \
|
||||
and self.CurFromImportsMods is not None \
|
||||
and self.CurFromImportsOrigs is not None:
|
||||
elif old_ptr == self.CurFromImportsPtr and self.CurFromImportsMods is not None and self.CurFromImportsOrigs is not None:
|
||||
idx_m = self.CurFromImportsMods
|
||||
idx_o = self.CurFromImportsOrigs
|
||||
else:
|
||||
@@ -154,8 +152,7 @@ novirtual class ImportsGenMixin:
|
||||
if idx_m.__contains__(key_ptr) == 0:
|
||||
idx_m.set_str(key_ptr, mod_ptr)
|
||||
if idx_o.__contains__(key_ptr) == 0:
|
||||
if original_name is not None and string.strcmp(original_name, local_name) != 0 \
|
||||
and string.strlen(original_name) > 0:
|
||||
if original_name is not None and string.strcmp(original_name, local_name) != 0 and string.strlen(original_name) > 0:
|
||||
idx_o.set_str(key_ptr, mod_ptr + mod_len + 1)
|
||||
else:
|
||||
# 首次出现即无别名(或别名为空)→ 该名查询返回 None(与逐字符扫描一致)
|
||||
@@ -200,8 +197,7 @@ novirtual class ImportsGenMixin:
|
||||
return 0
|
||||
# [索引快路径] 传入串即当前索引绑定的串(trans 字段的常态)→ O(名字长) 哈希查;
|
||||
# 指针不匹配(stub 期 malloc 缓冲等)→ 回退下方逐字符扫描,语义不变。
|
||||
if imported_modules == self.CurImportedModulesPtr \
|
||||
and self.CurImportedModulesNames is not None:
|
||||
if imported_modules == self.CurImportedModulesPtr and self.CurImportedModulesNames is not None:
|
||||
if self.CurImportedModulesNames.__contains__(name) != 0:
|
||||
return 1
|
||||
# 索引未命中:绝不据此返回 0(索引不完整会误判"未导入"),
|
||||
|
||||
@@ -49,8 +49,7 @@ novirtual class MatchGenMixin:
|
||||
if lst is None:
|
||||
return 0
|
||||
lk: int = lst.kind()
|
||||
if lk != ast.ASTKind.If and lk != ast.ASTKind.While \
|
||||
and lk != ast.ASTKind.For and lk != ast.ASTKind.Match:
|
||||
if lk != ast.ASTKind.If and lk != ast.ASTKind.While and lk != ast.ASTKind.For and lk != ast.ASTKind.Match:
|
||||
return 0
|
||||
if trans._ctrl_merge_reachable != 0:
|
||||
return 0
|
||||
@@ -112,8 +111,7 @@ novirtual class MatchGenMixin:
|
||||
if dcase is not None and dcase.kind() == ast.ASTKind.MatchCase:
|
||||
dpat: ast.AST* = rawptr[ast.MatchCase](dcase).pattern
|
||||
if dpat is not None:
|
||||
if dpat.kind() == ast.ASTKind.MatchAs \
|
||||
and rawptr[ast.MatchAs](dpat).pattern is None:
|
||||
if dpat.kind() == ast.ASTKind.MatchAs and rawptr[ast.MatchAs](dpat).pattern is None:
|
||||
# 只统计**无 guard** 的通配臂:带 guard 的 `case _ if ...`
|
||||
# 允许多个(各自 guard 区分),不当 default 计
|
||||
if rawptr[ast.MatchCase](dcase).guard is None:
|
||||
@@ -161,8 +159,7 @@ novirtual class MatchGenMixin:
|
||||
if nm.id is not None:
|
||||
entry: GenTypes.VarEntry* = self.Gen.VarGen.lookup_var_entry(trans.SymTab, nm.id)
|
||||
entry_annot: str = self.Gen.VarGen.var_annot_class_name(entry)
|
||||
if entry_annot is not None \
|
||||
and (self.Gen.ClassGenEnum._is_renum_class_name(entry_annot) != 0
|
||||
if entry_annot is not None and (self.Gen.ClassGenEnum._is_renum_class_name(entry_annot) != 0
|
||||
or self.Gen.ClassGenEnum._is_renum_by_entry(entry_annot) != 0):
|
||||
is_renum = 1
|
||||
renum_name = entry_annot
|
||||
@@ -176,15 +173,12 @@ novirtual class MatchGenMixin:
|
||||
ci: int = 0
|
||||
while ci < cn and is_renum == 0:
|
||||
case_node: ast.AST* = cases_list.get(ci)
|
||||
if case_node is not None \
|
||||
and case_node.kind() == ast.ASTKind.MatchCase:
|
||||
if case_node is not None and case_node.kind() == ast.ASTKind.MatchCase:
|
||||
mc: rawptr[ast.MatchCase] = (rawptr[ast.MatchCase])(case_node)
|
||||
pat: ast.AST* = mc.pattern
|
||||
if pat is not None \
|
||||
and pat.kind() == ast.ASTKind.MatchClass:
|
||||
if pat is not None and pat.kind() == ast.ASTKind.MatchClass:
|
||||
rnm: str = self._extract_renum_name_from_cls(pat)
|
||||
if rnm is not None \
|
||||
and (self.Gen.ClassGenEnum._is_renum_class_name(rnm) != 0
|
||||
if rnm is not None and (self.Gen.ClassGenEnum._is_renum_class_name(rnm) != 0
|
||||
or self.Gen.ClassGenEnum._is_renum_by_entry(rnm) != 0):
|
||||
is_renum = 1
|
||||
renum_name = rnm
|
||||
@@ -279,8 +273,7 @@ novirtual class MatchGenMixin:
|
||||
if ca.const_kind != cb.const_kind:
|
||||
return 0
|
||||
if ca.const_kind == ast.CONST_STR:
|
||||
if ca.str_val is not None and cb.str_val is not None \
|
||||
and string.strcmp(ca.str_val, cb.str_val) == 0:
|
||||
if ca.str_val is not None and cb.str_val is not None and string.strcmp(ca.str_val, cb.str_val) == 0:
|
||||
return 1
|
||||
return 0
|
||||
if ca.const_kind == ast.CONST_FLOAT:
|
||||
@@ -403,9 +396,7 @@ novirtual class MatchGenMixin:
|
||||
# → alloca REnum 结构体 + store 值 + 用 alloca 指针
|
||||
# 情况3: 指针但 pointee 不是结构体 → bitcast 到 REnum 结构体指针
|
||||
subj_ty: mlirlite.LLVMType* = subject_ptr.Ty
|
||||
if subj_ty is not None and self.Gen.ExprGenBase.is_ptr_type(subj_ty) != 0 \
|
||||
and subj_ty.Pointee != 0 \
|
||||
and self.Gen.ExprGenBase.is_ptr_type(subj_ty.Pointee) != 0:
|
||||
if subj_ty is not None and self.Gen.ExprGenBase.is_ptr_type(subj_ty) != 0 and subj_ty.Pointee != 0 and self.Gen.ExprGenBase.is_ptr_type(subj_ty.Pointee) != 0:
|
||||
# 情况1: T** → load 一次得 T*
|
||||
loaded_sub: mlirlite.Value* = mlirlite.build_load(builder, subj_ty.Pointee, subject_ptr)
|
||||
if loaded_sub is not None:
|
||||
@@ -425,8 +416,7 @@ novirtual class MatchGenMixin:
|
||||
int_val: mlirlite.Value* = subject_ptr
|
||||
# 非 i64 整数值先扩展/截断到 i64(inttoptr 要求同宽)
|
||||
# 仅当 subj_ty 是已知整数类型时转换;类型未知时保持原值
|
||||
if subj_ty is not None and self.Gen.ExprGenBase.get_llvm_type_bits(subj_ty) != 64 \
|
||||
and self.Gen.ExprGenBase.is_ptr_type(subj_ty) == 0:
|
||||
if subj_ty is not None and self.Gen.ExprGenBase.get_llvm_type_bits(subj_ty) != 64 and self.Gen.ExprGenBase.is_ptr_type(subj_ty) == 0:
|
||||
if self.Gen.ExprGenBase.get_llvm_type_bits(subj_ty) > 64:
|
||||
int_val = mlirlite.build_trunc(builder, subject_ptr, i64_ty0)
|
||||
else:
|
||||
@@ -484,8 +474,7 @@ novirtual class MatchGenMixin:
|
||||
nb_arr: int* = pool.alloc(4 * MAX_MATCH_CASES)
|
||||
# pass1 缓存的 mc 指针数组(pass2 复用,避免重索引)
|
||||
mc_arr: sizet* = pool.alloc(8 * MAX_MATCH_CASES)
|
||||
if bb_arr is None or cv_arr is None or def_arr is None or nb_arr is None \
|
||||
or mc_arr is None:
|
||||
if bb_arr is None or cv_arr is None or def_arr is None or nb_arr is None or mc_arr is None:
|
||||
# fail-fast: match 分派数组分配失败
|
||||
self.Gen.TypeGenErr.fatal_error(node, "match 分派数组分配失败", "TypeError")
|
||||
|
||||
@@ -573,8 +562,7 @@ novirtual class MatchGenMixin:
|
||||
pats: list[ast.AST*]* = mo.patterns
|
||||
if pats is not None and len(pats) > 0:
|
||||
first_pat: ast.AST* = pats.get(0)
|
||||
if first_pat is not None \
|
||||
and first_pat.kind() == ast.ASTKind.MatchValue:
|
||||
if first_pat is not None and first_pat.kind() == ast.ASTKind.MatchValue:
|
||||
mv2: rawptr[ast.MatchValue] = (rawptr[ast.MatchValue])(first_pat)
|
||||
cv = self.Gen.ExprGen.translate_value(builder, pool, trans.Module, mv2.value, trans._funcs, trans._func_count, trans)
|
||||
|
||||
@@ -761,8 +749,7 @@ novirtual class MatchGenMixin:
|
||||
# 若未终止:默认跳 end;含 fallthrough(`fallthrough` 标记或兼容的
|
||||
# c.NoBreak())则落到下一个 case 的 body(跳过其模式检查)。
|
||||
# 末句控制流全 return(结构性不可达)时补 unreachable,不 br end_bb
|
||||
if mlirlite.builder_cur_block_is_terminated(builder) == 0 \
|
||||
and self._case_tail_unreachable(trans, builder, body_list) == 0:
|
||||
if mlirlite.builder_cur_block_is_terminated(builder) == 0 and self._case_tail_unreachable(trans, builder, body_list) == 0:
|
||||
if nb == 0:
|
||||
mlirlite.build_br(builder, end_bb)
|
||||
else:
|
||||
@@ -816,8 +803,7 @@ novirtual class MatchGenMixin:
|
||||
trans._break_bb = rmd_old_break
|
||||
trans._in_switch_case = rmd_old_inmc
|
||||
# 末句控制流全 return → 补 unreachable(不 br end_bb)
|
||||
if mlirlite.builder_cur_block_is_terminated(builder) == 0 \
|
||||
and self._case_tail_unreachable(trans, builder, dbody3) == 0:
|
||||
if mlirlite.builder_cur_block_is_terminated(builder) == 0 and self._case_tail_unreachable(trans, builder, dbody3) == 0:
|
||||
mlirlite.build_br(builder, end_bb)
|
||||
trans._ctrl_merge_reachable = 1
|
||||
rm_merge_reach = 1
|
||||
@@ -899,8 +885,7 @@ novirtual class MatchGenMixin:
|
||||
# 自引用类型注册期解析失败 → 查不到类型时回退槽位类型。
|
||||
mem_ty_m: mlirlite.LLVMType* = None
|
||||
vnt_m: str = self._extract_variant_name_from_cls(pat)
|
||||
if vnt_m is not None and renum_entry is not None \
|
||||
and renum_entry.Name is not None:
|
||||
if vnt_m is not None and renum_entry is not None and renum_entry.Name is not None:
|
||||
mem_ty_m = self.Gen.ClassGenEnum._lookup_renum_member_ty(renum_entry.Name, vnt_m, payload_idx)
|
||||
if mem_ty_m is not None:
|
||||
mem_ptr_m: mlirlite.LLVMType* = mlirlite.Ptr(pool, mem_ty_m)
|
||||
@@ -924,8 +909,7 @@ novirtual class MatchGenMixin:
|
||||
if lhs is None or rhs is None or builder is None:
|
||||
return None
|
||||
pool: memhub.MemBuddy* = trans.Pool
|
||||
if self.Gen.ExprGenBase.is_ptr_type(lhs.Ty) != 0 \
|
||||
or self.Gen.ExprGenBase.is_ptr_type(rhs.Ty) != 0:
|
||||
if self.Gen.ExprGenBase.is_ptr_type(lhs.Ty) != 0 or self.Gen.ExprGenBase.is_ptr_type(rhs.Ty) != 0:
|
||||
i64_ty: mlirlite.LLVMType* = mlirlite.Int64(pool)
|
||||
if self.Gen.ExprGenBase.is_ptr_type(lhs.Ty) != 0:
|
||||
lhs = mlirlite.build_ptrtoint(builder, lhs, i64_ty)
|
||||
@@ -1023,8 +1007,7 @@ novirtual class MatchGenMixin:
|
||||
def_arr: int* = pool.alloc(4 * MAX_MATCH_CASES)
|
||||
nb_arr: int* = pool.alloc(4 * MAX_MATCH_CASES)
|
||||
guard_arr: sizet* = pool.alloc(8 * MAX_MATCH_CASES)
|
||||
if check_arr is None or body_arr is None or def_arr is None \
|
||||
or nb_arr is None or guard_arr is None:
|
||||
if check_arr is None or body_arr is None or def_arr is None or nb_arr is None or guard_arr is None:
|
||||
return 0
|
||||
collected: int = 0
|
||||
has_default: int = 0
|
||||
@@ -1218,8 +1201,7 @@ novirtual class MatchGenMixin:
|
||||
trans._break_bb = sqb_old_break
|
||||
trans._in_switch_case = sqb_old_inmc
|
||||
# 末句控制流全 return → 补 unreachable(不 br end,无 fallthrough)
|
||||
if mlirlite.builder_cur_block_is_terminated(builder) == 0 \
|
||||
and self._case_tail_unreachable(trans, builder, body_list2) == 0:
|
||||
if mlirlite.builder_cur_block_is_terminated(builder) == 0 and self._case_tail_unreachable(trans, builder, body_list2) == 0:
|
||||
if nb_arr[ci] == 0:
|
||||
mlirlite.build_br(builder, end_bb)
|
||||
else:
|
||||
@@ -1268,8 +1250,7 @@ novirtual class MatchGenMixin:
|
||||
trans._break_bb = sqd_old_break
|
||||
trans._in_switch_case = sqd_old_inmc
|
||||
# 末句控制流全 return → 补 unreachable(不 br end_bb)
|
||||
if mlirlite.builder_cur_block_is_terminated(builder) == 0 \
|
||||
and self._case_tail_unreachable(trans, builder, dbody) == 0:
|
||||
if mlirlite.builder_cur_block_is_terminated(builder) == 0 and self._case_tail_unreachable(trans, builder, dbody) == 0:
|
||||
mlirlite.build_br(builder, end_bb)
|
||||
sq_merge_reach = 1
|
||||
|
||||
@@ -1539,8 +1520,7 @@ novirtual class MatchGenMixin:
|
||||
# 若未终止:默认跳 end;含 fallthrough(`fallthrough` 标记或兼容的
|
||||
# c.NoBreak())则落到下一个 case 的 body(跳过其模式检查)。
|
||||
# 末句控制流全 return → 补 unreachable(不 br end_bb)
|
||||
if mlirlite.builder_cur_block_is_terminated(builder) == 0 \
|
||||
and self._case_tail_unreachable(trans, builder, body_list) == 0:
|
||||
if mlirlite.builder_cur_block_is_terminated(builder) == 0 and self._case_tail_unreachable(trans, builder, body_list) == 0:
|
||||
if nb == 0:
|
||||
mlirlite.build_br(builder, end_bb)
|
||||
else:
|
||||
@@ -1593,8 +1573,7 @@ novirtual class MatchGenMixin:
|
||||
trans._break_bb = smd_old_break
|
||||
trans._in_switch_case = smd_old_inmc
|
||||
# 末句控制流全 return → 补 unreachable(不 br end_bb)
|
||||
if mlirlite.builder_cur_block_is_terminated(builder) == 0 \
|
||||
and self._case_tail_unreachable(trans, builder, dbody3) == 0:
|
||||
if mlirlite.builder_cur_block_is_terminated(builder) == 0 and self._case_tail_unreachable(trans, builder, dbody3) == 0:
|
||||
mlirlite.build_br(builder, end_bb)
|
||||
trans._ctrl_merge_reachable = 1
|
||||
sm_merge_reach = 1
|
||||
@@ -1656,8 +1635,7 @@ novirtual class MatchGenMixin:
|
||||
# `case 1 | 2` 变成各备选 subj_val == cv_i 的 OR,故此处记录节点,
|
||||
# 发射 check 时逐备选展开取 OR。非 MatchOr 恒为 0,走原单 cv 路径不变。
|
||||
or_arr: sizet* = pool.alloc(8 * MAX_MATCH_CASES)
|
||||
if check_arr is None or body_arr is None or def_arr is None \
|
||||
or nb_arr is None or mc_arr is None or cv_arr is None or or_arr is None:
|
||||
if check_arr is None or body_arr is None or def_arr is None or nb_arr is None or mc_arr is None or cv_arr is None or or_arr is None:
|
||||
self.Gen.TypeGenErr.fatal_error(node, "match 分派数组分配失败", "TypeError")
|
||||
collected: int = 0
|
||||
has_default: int = 0
|
||||
@@ -1855,8 +1833,7 @@ novirtual class MatchGenMixin:
|
||||
trans._in_switch_case = gmb_old_inmc
|
||||
# 若未终止:默认跳 end;含 fallthrough 则落到下一个非通配 body。
|
||||
# 末句控制流全 return → 补 unreachable(不 br end_bb)
|
||||
if mlirlite.builder_cur_block_is_terminated(builder) == 0 \
|
||||
and self._case_tail_unreachable(trans, builder, body_list2) == 0:
|
||||
if mlirlite.builder_cur_block_is_terminated(builder) == 0 and self._case_tail_unreachable(trans, builder, body_list2) == 0:
|
||||
if nb_arr[ci] == 0:
|
||||
mlirlite.build_br(builder, end_bb)
|
||||
else:
|
||||
@@ -1904,8 +1881,7 @@ novirtual class MatchGenMixin:
|
||||
trans._break_bb = gmd_old_break
|
||||
trans._in_switch_case = gmd_old_inmc
|
||||
# 末句控制流全 return → 补 unreachable(不 br end_bb)
|
||||
if mlirlite.builder_cur_block_is_terminated(builder) == 0 \
|
||||
and self._case_tail_unreachable(trans, builder, dbody3) == 0:
|
||||
if mlirlite.builder_cur_block_is_terminated(builder) == 0 and self._case_tail_unreachable(trans, builder, dbody3) == 0:
|
||||
mlirlite.build_br(builder, end_bb)
|
||||
trans._ctrl_merge_reachable = 1
|
||||
gm_merge_reach = 1
|
||||
|
||||
@@ -92,10 +92,7 @@ novirtual class StmtGenCifMixin:
|
||||
is_win: int = 0
|
||||
is_linux: int = 0
|
||||
is_x64: int = 0
|
||||
if string.strstr(triple, "windows") is not None \
|
||||
or string.strstr(triple, "win32") is not None \
|
||||
or string.strstr(triple, "mingw") is not None \
|
||||
or string.strstr(triple, "msvc") is not None:
|
||||
if string.strstr(triple, "windows") is not None or string.strstr(triple, "win32") is not None or string.strstr(triple, "mingw") is not None or string.strstr(triple, "msvc") is not None:
|
||||
is_win = 1
|
||||
if string.strstr(triple, "linux") is not None:
|
||||
is_linux = 1
|
||||
@@ -528,8 +525,7 @@ novirtual class StmtGenCifMixin:
|
||||
# 需要 load 得到实际的 self 指针 (Ptr(StructTy))
|
||||
if rt.value.kind() == ast.ASTKind.Name:
|
||||
ret_nm: ast.Name* = ast.Name*(rt.value)
|
||||
if ret_nm is not None and ret_nm.id is not None \
|
||||
and string.strcmp(ret_nm.id, "self") == 0:
|
||||
if ret_nm is not None and ret_nm.id is not None and string.strcmp(ret_nm.id, "self") == 0:
|
||||
self_ptr: mlirlite.Value* = self.Gen.VarGen.lookup_var(trans.SymTab, "self")
|
||||
if self_ptr is not None:
|
||||
# 检查 self_ptr 是否是 Ptr(Ptr(...))(alloca 存储指针)
|
||||
@@ -639,8 +635,7 @@ novirtual class StmtGenCifMixin:
|
||||
fn_nm_ret: str = None
|
||||
if cur_func_rt is not None:
|
||||
fn_nm_ret = mlirlite.function_get_name(cur_func_rt)
|
||||
if fn_nm_ret is not None and string.strstr(fn_nm_ret, "__new__") is not None \
|
||||
and val_is_ptr == 0 and ret_is_ptr != 0:
|
||||
if fn_nm_ret is not None and string.strstr(fn_nm_ret, "__new__") is not None and val_is_ptr == 0 and ret_is_ptr != 0:
|
||||
val = mlirlite.build_inttoptr(builder, val, ret_ty_rt)
|
||||
else:
|
||||
# 传 trans:Phase A 依赖未就绪(_deps_pending)时,跨模块调用
|
||||
@@ -661,8 +656,7 @@ novirtual class StmtGenCifMixin:
|
||||
match ret_ty_rt:
|
||||
case mlirlite.LLVMType.Ptr(r_inner):
|
||||
ret_pointee = r_inner
|
||||
if val_pointee is not None and ret_pointee is not None \
|
||||
and uint64(val_pointee) != uint64(ret_pointee):
|
||||
if val_pointee is not None and ret_pointee is not None and uint64(val_pointee) != uint64(ret_pointee):
|
||||
val = self.Gen.ExprGenBase.coerce_to_type(builder, val, ret_ty_rt, node)
|
||||
elif val_bits != 0 and ret_bits != 0 and val_bits != ret_bits:
|
||||
if val_bits == 1 and val_bits < ret_bits:
|
||||
@@ -671,8 +665,7 @@ novirtual class StmtGenCifMixin:
|
||||
# 传 trans:无符号源类型(uint16/uint32/CSizeT 等)扩展用 zext,
|
||||
# 缺 trans 时 _node_type_unsigned 查不到变量注解 → 误 sext
|
||||
val = self.Gen.ExprGenBase.coerce_to_type(builder, val, ret_ty_rt, node, trans)
|
||||
elif self.Gen.ExprGenBase.get_llvm_float_bits(val.Ty) != 0 \
|
||||
or self.Gen.ExprGenBase.get_llvm_float_bits(ret_ty_rt) != 0:
|
||||
elif self.Gen.ExprGenBase.get_llvm_float_bits(val.Ty) != 0 or self.Gen.ExprGenBase.get_llvm_float_bits(ret_ty_rt) != 0:
|
||||
# Float alignment: SpecTypeBits reports 0 for Float/Double, so the
|
||||
# integer branch above never runs and a double literal returned from a
|
||||
# `-> float` function would emit `ret double` (llc: value doesn't match
|
||||
@@ -1178,23 +1171,20 @@ novirtual class StmtGenCifMixin:
|
||||
if TSpec.SpecTypeNameBaseIs(lst_annot, "dict") != 0:
|
||||
lst_val: mlirlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, trans.Module, iter_node,
|
||||
trans._funcs, trans._func_count, trans)
|
||||
if lst_val is not None and lst_val.Ty is not None \
|
||||
and self.Gen.ExprGenBase.is_ptr_type(lst_val.Ty) != 0:
|
||||
if lst_val is not None and lst_val.Ty is not None and self.Gen.ExprGenBase.is_ptr_type(lst_val.Ty) != 0:
|
||||
return self._handle_dict_iter(trans, for_node, var_name, lst_val)
|
||||
# [S4] 同上:原 strstr("list") 会误命中 playlist / GSList 等;
|
||||
# 非 list 基名的用户类改由下方 OOP __iter__/__next__ 路径处理(更正确)。
|
||||
if TSpec.SpecTypeNameBaseIs(lst_annot, "list") != 0:
|
||||
lst_val: mlirlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, trans.Module, iter_node, trans._funcs, trans._func_count, trans)
|
||||
if lst_val is not None and lst_val.Ty is not None \
|
||||
and self.Gen.ExprGenBase.is_ptr_type(lst_val.Ty) != 0:
|
||||
if lst_val is not None and lst_val.Ty is not None and self.Gen.ExprGenBase.is_ptr_type(lst_val.Ty) != 0:
|
||||
return self._handle_list_iter(trans, for_node, var_name, lst_val)
|
||||
# OOP iter 协议:迭代源是类对象且类有 __iter__/__next__ 方法 →
|
||||
# 走 __iter__/__next__ 调用迭代(对齐 TPC HandlesFor.py L142-166
|
||||
# _HandleForIterLlvm)。dict/list 是内置泛型容器已在上方内联处理。
|
||||
ov_val: mlirlite.Value* = self.Gen.ExprGen.translate_value(builder, pool, trans.Module, iter_node,
|
||||
trans._funcs, trans._func_count, trans)
|
||||
if ov_val is not None and ov_val.Ty is not None \
|
||||
and self.Gen.ExprGenBase.is_ptr_type(ov_val.Ty) != 0:
|
||||
if ov_val is not None and ov_val.Ty is not None and self.Gen.ExprGenBase.is_ptr_type(ov_val.Ty) != 0:
|
||||
ov_st: mlirlite.LLVMType* = self.Gen.StructGen.get_struct_type_from_value(ov_val)
|
||||
if ov_st is not None:
|
||||
ov_cn: str = self.Gen.StructGen.get_class_name_by_type(pool, ov_st)
|
||||
@@ -1217,8 +1207,7 @@ novirtual class StmtGenCifMixin:
|
||||
cn_ik: ast.Constant* = ast.Constant*(iter_node)
|
||||
if cn_ik.const_kind != ast.CONST_STR:
|
||||
self.Gen.TypeGenErr.fatal_error(iter_node, "for 迭代不支持该常量(仅支持字符串、数组、列表字面量、range())")
|
||||
elif ik == ast.ASTKind.Dict or ik == ast.ASTKind.Set or ik == ast.ASTKind.Tuple \
|
||||
or ik == ast.ASTKind.SetComp or ik == ast.ASTKind.DictComp:
|
||||
elif ik == ast.ASTKind.Dict or ik == ast.ASTKind.Set or ik == ast.ASTKind.Tuple or ik == ast.ASTKind.SetComp or ik == ast.ASTKind.DictComp:
|
||||
self.Gen.TypeGenErr.fatal_error(iter_node, "for 迭代不支持字典/集合/元组字面量,请使用 range()、t.CArray 数组或列表字面量")
|
||||
return self._handle_ptr_iter(trans, for_node, var_name)
|
||||
|
||||
|
||||
@@ -102,8 +102,7 @@ novirtual class StmtGenDeclMixin(StmtGenCifMixin.StmtGenCifMixin):
|
||||
# (执行 + 丢弃返回值,同 print/printf 语义)。
|
||||
# 守卫 trans.ReplCtx:非 REPL 恒 None ⇒ "表达式语句除调用外一律忽略"
|
||||
# 的原行为逐字不变。
|
||||
if trans is not None and trans.ReplCtx is not None \
|
||||
and self.Gen.VarGen.repl_in_frag_scope(trans.SymTab) != 0:
|
||||
if trans is not None and trans.ReplCtx is not None and self.Gen.VarGen.repl_in_frag_scope(trans.SymTab) != 0:
|
||||
self.Gen.VarGen.repl_expr_result(trans, call_node)
|
||||
return 0
|
||||
|
||||
@@ -131,11 +130,8 @@ novirtual class StmtGenDeclMixin(StmtGenCifMixin.StmtGenCifMixin):
|
||||
# 不用影子条目推断 ⇒ 与调用点签名同源。
|
||||
# 守卫 trans.ReplCtx:非 REPL 恒 None ⇒ 原"执行 + 丢弃返回值"逐字不变;
|
||||
# 仅裸名(Name)且表中登记的会话函数走本分支(printf/print 等在上方已分流)。
|
||||
if trans is not None and trans.ReplCtx is not None \
|
||||
and func_node.kind() == ast.ASTKind.Name \
|
||||
and self.Gen.VarGen.repl_in_frag_scope(trans.SymTab) != 0:
|
||||
sfn_ent: rawptr[GenTypes.ReplFuncEntry] = \
|
||||
self.Gen.VarGen.repl_find_func_entry(trans.ReplCtx, func_name)
|
||||
if trans is not None and trans.ReplCtx is not None and func_node.kind() == ast.ASTKind.Name and self.Gen.VarGen.repl_in_frag_scope(trans.SymTab) != 0:
|
||||
sfn_ent: rawptr[GenTypes.ReplFuncEntry] = self.Gen.VarGen.repl_find_func_entry(trans.ReplCtx, func_name)
|
||||
if sfn_ent is not None and sfn_ent.RetTag != GenTypes.REPL_TY_VOID:
|
||||
sfn_v: mlirlite.Value* = self.Gen.CallGen.translate_call(trans.Pool, trans._cur_builder, trans.Module, call_node,
|
||||
trans._funcs, trans._func_count, trans)
|
||||
|
||||
@@ -251,10 +251,8 @@ novirtual class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin):
|
||||
# 注意:list[ptr](pool, N) 第二参数是 elem_size 不是容量!
|
||||
# 指针元素必须显式传 8(T.__sizeof__ 对联合类型不可靠),
|
||||
# 否则 append 按 N 字节步长错位存取 → 读出垃圾指针(崩溃)。
|
||||
except_bbs: list[rawptr[mlirlite.BasicBlock]]* = \
|
||||
list[rawptr[mlirlite.BasicBlock]](pool, 8)
|
||||
match_bbs: list[rawptr[mlirlite.BasicBlock]]* = \
|
||||
list[rawptr[mlirlite.BasicBlock]](pool, 8)
|
||||
except_bbs: list[rawptr[mlirlite.BasicBlock]]* = list[rawptr[mlirlite.BasicBlock]](pool, 8)
|
||||
match_bbs: list[rawptr[mlirlite.BasicBlock]]* = list[rawptr[mlirlite.BasicBlock]](pool, 8)
|
||||
if except_bbs is None or match_bbs is None:
|
||||
return 0
|
||||
for i_t in range(n_handlers_t):
|
||||
@@ -370,8 +368,7 @@ novirtual class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin):
|
||||
|
||||
# ---- 6. UnhandledBB:无 except 匹配 → 向上传播或吞掉 ----
|
||||
mlirlite.position_at_end(builder, unhandled_bb)
|
||||
if trans._cur_func_has_eh != 0 and trans._eh_msg_out_param is not None \
|
||||
and trans._eh_code_out_param is not None:
|
||||
if trans._cur_func_has_eh != 0 and trans._eh_msg_out_param is not None and trans._eh_code_out_param is not None:
|
||||
un_msg_t: mlirlite.Value* = mlirlite.build_load(builder, i8_ptr_ty_t, eh_message)
|
||||
un_code_t: mlirlite.Value* = mlirlite.build_load(builder, i32_ty_t, exception_code)
|
||||
if un_msg_t is not None:
|
||||
@@ -504,8 +501,7 @@ novirtual class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin):
|
||||
mlirlite.build_br(builder, trans._eh_dispatch_bb)
|
||||
return 0
|
||||
# 2. 函数有 EH 输出参数:写入 out 参数(异常向调用方传播)
|
||||
if trans._cur_func_has_eh != 0 and trans._eh_msg_out_param is not None \
|
||||
and trans._eh_code_out_param is not None:
|
||||
if trans._cur_func_has_eh != 0 and trans._eh_msg_out_param is not None and trans._eh_code_out_param is not None:
|
||||
code_val_r2: mlirlite.Value* = mlirlite.const_int32(pool, exc_code)
|
||||
if code_val_r2 is not None:
|
||||
mlirlite.build_store(builder, code_val_r2, trans._eh_code_out_param)
|
||||
|
||||
@@ -921,7 +921,7 @@ novirtual class StructGenMixin:
|
||||
string.memset(dst_l, 0, ast.List.__sizeof__())
|
||||
# 拷贝 vtable 指针(AST 是 @t.CVTable,kind() 虚调用依赖首字段 vptr)
|
||||
vt_l: t.CPtr = t.CPtr(*((uint64*)(default_val)))
|
||||
*dst_l = vt_l
|
||||
c.DerefAs(dst_l, vt_l)
|
||||
# 拷贝位置字段与 ctx
|
||||
dst_l.lineno = src_l.lineno
|
||||
dst_l.col_offset = src_l.col_offset
|
||||
@@ -1113,14 +1113,12 @@ novirtual class StructGenMixin:
|
||||
# 统一走 GenApi.is_sha1_hex16(该判定的唯一真源)。
|
||||
mod_hex_ok: int = GenApi.is_sha1_hex16(mod_buf_f)
|
||||
if mod_hex_ok != 0:
|
||||
me_h: GenTypes.StructEntry* = \
|
||||
self.find_struct_by_module(bare_f, mod_buf_f)
|
||||
me_h: GenTypes.StructEntry* = self.find_struct_by_module(bare_f, mod_buf_f)
|
||||
stdlib.free(mod_buf_f)
|
||||
return me_h
|
||||
mod_sha1_f: str = self._resolve_module_sha1(mod_buf_f)
|
||||
if mod_sha1_f is not None:
|
||||
me_f: GenTypes.StructEntry* = \
|
||||
self.find_struct_by_module(bare_f, mod_sha1_f)
|
||||
me_f: GenTypes.StructEntry* = self.find_struct_by_module(bare_f, mod_sha1_f)
|
||||
if me_f is not None:
|
||||
stdlib.free(mod_buf_f)
|
||||
return me_f
|
||||
@@ -1402,9 +1400,7 @@ novirtual class StructGenMixin:
|
||||
# 类型名带 SHA1 前缀:必须与 entry.ModuleSha1 前 16 字符
|
||||
# 精确一致,否则跳过(跨模块同名类命名空间隔离)
|
||||
if ty_has_sha1_lf != 0:
|
||||
if entry.ModuleSha1 is None \
|
||||
or string.strlen(entry.ModuleSha1) < 16 \
|
||||
or string.strncmp(entry.ModuleSha1, ty_name, 16) != 0:
|
||||
if entry.ModuleSha1 is None or string.strlen(entry.ModuleSha1) < 16 or string.strncmp(entry.ModuleSha1, ty_name, 16) != 0:
|
||||
continue
|
||||
matched: int = 0
|
||||
if string.strcmp(entry.Name, ty_name) == 0:
|
||||
@@ -1483,14 +1479,12 @@ novirtual class StructGenMixin:
|
||||
elif bare_name is not class_name and string.strcmp(entry.Name, bare_name) == 0:
|
||||
name_match = 1
|
||||
if name_match != 0:
|
||||
if entry.ModuleSha1 is not None \
|
||||
and string.strcmp(entry.ModuleSha1, sha1) == 0:
|
||||
if entry.ModuleSha1 is not None and string.strcmp(entry.ModuleSha1, sha1) == 0:
|
||||
sha1_matched = 1
|
||||
# SHA1 + 类名匹配,查找字段
|
||||
for fi in range(entry.FieldCount):
|
||||
fe: GenTypes.FieldEntry* = self._get_field_entry(entry, fi)
|
||||
if fe is not None and fe.Name is not None \
|
||||
and string.strcmp(fe.Name, field_name) == 0:
|
||||
if fe is not None and fe.Name is not None and string.strcmp(fe.Name, field_name) == 0:
|
||||
return fe
|
||||
return None
|
||||
|
||||
@@ -1532,8 +1526,7 @@ novirtual class StructGenMixin:
|
||||
else:
|
||||
mod_sha1_q = self._resolve_module_sha1(mod_buf_q, from_imports)
|
||||
if mod_sha1_q is not None:
|
||||
mod_entry_q: GenTypes.StructEntry* = \
|
||||
self.find_struct_by_module(bare_q, mod_sha1_q)
|
||||
mod_entry_q: GenTypes.StructEntry* = self.find_struct_by_module(bare_q, mod_sha1_q)
|
||||
if mod_entry_q is not None:
|
||||
# 依赖未就绪容忍(对齐裸名路径):FieldCount==0 的空类
|
||||
# (注册不完整/源模块未编译)→ 返回 None 让上层标记
|
||||
@@ -1542,8 +1535,7 @@ novirtual class StructGenMixin:
|
||||
stdlib.free(mod_buf_q)
|
||||
return None
|
||||
for fi_q in range(mod_entry_q.FieldCount):
|
||||
fe_q: GenTypes.FieldEntry* = \
|
||||
self._get_field_entry(mod_entry_q, fi_q)
|
||||
fe_q: GenTypes.FieldEntry* = self._get_field_entry(mod_entry_q, fi_q)
|
||||
if fe_q is not None and fe_q.Name is not None:
|
||||
if string.strcmp(fe_q.Name, field_name) == 0:
|
||||
stdlib.free(mod_buf_q)
|
||||
@@ -1555,19 +1547,16 @@ novirtual class StructGenMixin:
|
||||
rn_cls_q: str = mod_entry_q.Name
|
||||
if rn_cls_q is None:
|
||||
rn_cls_q = bare_q
|
||||
rn_is_renum_q: int = \
|
||||
self.Gen.ClassGenEnum._is_renum_class_name(bare_q)
|
||||
rn_is_renum_q: int = self.Gen.ClassGenEnum._is_renum_class_name(bare_q)
|
||||
if rn_is_renum_q == 0 and rn_cls_q is not None:
|
||||
rn_is_renum_q = \
|
||||
self.Gen.ClassGenEnum._is_renum_class_name(rn_cls_q)
|
||||
rn_is_renum_q = self.Gen.ClassGenEnum._is_renum_class_name(rn_cls_q)
|
||||
rn_alias_q: int = -1
|
||||
if rn_is_renum_q != 0:
|
||||
rn_alias_q = self.Gen.ClassGenEnum._lookup_renum_field_alias(rn_cls_q, field_name)
|
||||
if rn_alias_q < 1 and bare_q is not rn_cls_q:
|
||||
rn_alias_q = self.Gen.ClassGenEnum._lookup_renum_field_alias(bare_q, field_name)
|
||||
if rn_alias_q >= 1:
|
||||
rn_fe_q: GenTypes.FieldEntry* = \
|
||||
self._get_field_entry(mod_entry_q, rn_alias_q)
|
||||
rn_fe_q: GenTypes.FieldEntry* = self._get_field_entry(mod_entry_q, rn_alias_q)
|
||||
if rn_fe_q is not None and rn_fe_q.Ty is not None:
|
||||
stdlib.free(mod_buf_q)
|
||||
return rn_fe_q
|
||||
@@ -1624,8 +1613,7 @@ novirtual class StructGenMixin:
|
||||
# 未执行/多模块重复注册场景),用调用方 class_name 再试一次
|
||||
rn_alias_l = self.Gen.ClassGenEnum._lookup_renum_field_alias(class_name, field_name)
|
||||
if rn_alias_l >= 1:
|
||||
rn_fe_l: GenTypes.FieldEntry* = \
|
||||
self.Gen.StructGen._get_field_entry(entry, rn_alias_l)
|
||||
rn_fe_l: GenTypes.FieldEntry* = self.Gen.StructGen._get_field_entry(entry, rn_alias_l)
|
||||
if rn_fe_l is not None and rn_fe_l.Ty is not None:
|
||||
return rn_fe_l
|
||||
# 诊断:找到结构体但字段确实未找到
|
||||
@@ -1659,10 +1647,7 @@ novirtual class StructGenMixin:
|
||||
fld_lst_txt: str = "(无)"
|
||||
if fb_flds_lst is not None and string.strlen(fb_flds_lst) > 0:
|
||||
fld_lst_txt = fb_flds_lst
|
||||
err = f"lookup_field_by_class: 类 '{class_name}' 已注册 (FieldCount={entry.FieldCount}, "\
|
||||
f"entry.Name='{entry.Name}', ModuleSha1={sha1_txt}, 调用方期望 sha1={want_sha1_txt}) "\
|
||||
f"但字段 '{field_name}' 未找到;注册字段: [{fld_lst_txt}]。可能原因: 跨模块同名类"\
|
||||
f"被误匹配 / vpi stub 注入字段不全 / 类定义与访问处不一致"
|
||||
err = f"lookup_field_by_class: 类 '{class_name}' 已注册 (FieldCount={entry.FieldCount}, " f"entry.Name='{entry.Name}', ModuleSha1={sha1_txt}, 调用方期望 sha1={want_sha1_txt}) " f"但字段 '{field_name}' 未找到;注册字段: [{fld_lst_txt}]。可能原因: 跨模块同名类" f"被误匹配 / vpi stub 注入字段不全 / 类定义与访问处不一致"
|
||||
# 仿 Python traceback 格式输出(Traceback 帧 + 文件:行号 + 错误类型),
|
||||
# 立即终止编译(与 VLogger.error 同语义,格式对齐 fatal_error)
|
||||
self.Gen.TypeGenErr.fatal_error(node, err, "AttributeError")
|
||||
|
||||
@@ -900,8 +900,7 @@ novirtual class Translator:
|
||||
if need_dict_box[0] != 0:
|
||||
# dict 类可见 + _dict 模块导入(构造/方法调用的 SHA1 解析)
|
||||
GenApi.add_visible_struct(pool, "dict")
|
||||
if self._imported_modules is None or \
|
||||
GenApi.is_module_imported(self._imported_modules, "_dict") == 0:
|
||||
if self._imported_modules is None or GenApi.is_module_imported(self._imported_modules, "_dict") == 0:
|
||||
# [FIX 2026-08-31] 破环:_dict 自身依赖含当前模块则跳过注入。
|
||||
# 对齐 Phase1Main._InjectedCreatesCycle,覆盖所有 translate 路径
|
||||
# (Phase1 1b / Phase2 pre-inc / PhaseA)——否则 _list/_dict 显式
|
||||
@@ -910,8 +909,7 @@ novirtual class Translator:
|
||||
self._imported_modules = GenApi.add_imported_module(pool, self._imported_modules, "_dict")
|
||||
if need_list_box[0] != 0:
|
||||
GenApi.add_visible_struct(pool, "list")
|
||||
if self._imported_modules is None or \
|
||||
GenApi.is_module_imported(self._imported_modules, "_list") == 0:
|
||||
if self._imported_modules is None or GenApi.is_module_imported(self._imported_modules, "_list") == 0:
|
||||
if self._ContainerInjectionCreatesCycle("_list") == 0:
|
||||
self._imported_modules = GenApi.add_imported_module(pool, self._imported_modules, "_list")
|
||||
stdlib.free(need_list_box)
|
||||
|
||||
@@ -766,8 +766,7 @@ novirtual class TranslatorGenMixin:
|
||||
# 纯 t.CStruct(无方法无虚表无 __new__)保持值实例。
|
||||
if resolved.kind() == mlirlite.LLVMType.Struct:
|
||||
gv_entry: GenTypes.StructEntry* = 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):
|
||||
if gv_entry is not None and (gv_entry.HasNew != 0 or gv_entry.HasVTable != 0 or gv_entry.IsOOP != 0):
|
||||
# 对象类全局(裸类名注解 → 对象即指针):记录原 Struct 值类型,
|
||||
# 用于创建静态 storage 全局承载对象实例(BSS);否则 @g 为 NULL,
|
||||
# 对象字段落在物理页 0。
|
||||
@@ -781,8 +780,7 @@ novirtual class TranslatorGenMixin:
|
||||
pointee_uv: mlirlite.LLVMType* = resolved.Pointee
|
||||
if pointee_uv is not None and pointee_uv.kind() == mlirlite.LLVMType.Struct:
|
||||
gv_entry_u: GenTypes.StructEntry* = self.Gen.StructGen.find_struct_by_type(pointee_uv)
|
||||
if gv_entry_u is not None \
|
||||
and (gv_entry_u.HasNew != 0 or gv_entry_u.HasVTable != 0 or gv_entry_u.IsOOP != 0):
|
||||
if gv_entry_u is not None and (gv_entry_u.HasNew != 0 or gv_entry_u.HasVTable != 0 or gv_entry_u.IsOOP != 0):
|
||||
resolved_stg_ty = pointee_uv
|
||||
resolved_stg_entry = gv_entry_u
|
||||
var_ty = resolved
|
||||
@@ -1042,8 +1040,7 @@ novirtual class TranslatorGenMixin:
|
||||
# 否则 zeroinitializer → 入口虚调用 call [vtable+0x10] → 跳 0x0 #PF。
|
||||
# @t.Object(无 CVTable)/普通对象:保持 zeroinitializer(无 vtable 需求)。
|
||||
stg_init_text: str = "zeroinitializer"
|
||||
if resolved_stg_entry is not None and resolved_stg_entry.Name is not None \
|
||||
and resolved_stg_entry.HasVTable != 0:
|
||||
if resolved_stg_entry is not None and resolved_stg_entry.Name is not None and resolved_stg_entry.HasVTable != 0:
|
||||
vt_name_buf: str = pool.alloc(128)
|
||||
if vt_name_buf is not None:
|
||||
viperlib.snprintf(vt_name_buf, 128, "%s.vtable", resolved_stg_entry.Name)
|
||||
@@ -1068,8 +1065,7 @@ novirtual class TranslatorGenMixin:
|
||||
if resolved_stg_entry.ModuleSha1 is not None and trans.ModuleSha1 is not None:
|
||||
if string.strncmp(resolved_stg_entry.ModuleSha1, trans.ModuleSha1, 16) != 0:
|
||||
vt_cross = 1
|
||||
if vt_cross != 0 \
|
||||
and self.Gen.ExprGenAttr.find_global_in_module(mod, vt_mangled) is None:
|
||||
if vt_cross != 0 and self.Gen.ExprGenAttr.find_global_in_module(mod, vt_mangled) is None:
|
||||
vt_decl_ty: mlirlite.LLVMType* = mlirlite.Ptr(pool, mlirlite.Int8(pool))
|
||||
vt_gv: mlirlite.GlobalVariable* = mlirlite.new_global_variable(pool, vt_mangled, vt_decl_ty)
|
||||
if vt_gv is not None:
|
||||
@@ -1193,8 +1189,7 @@ novirtual class TranslatorGenMixin:
|
||||
if aa_ml.annotation.kind() == ast.ASTKind.BinOp:
|
||||
bop_ml: ast.BinOp* = ast.BinOp*(aa_ml.annotation)
|
||||
if bop_ml.op == ast.OpKind.BitOr:
|
||||
if self.Gen.AssignGen._annotation_contains_name(aa_ml.annotation, "str") != 0 \
|
||||
or self.Gen.AssignGen._annotation_contains_name(aa_ml.annotation, "bytes") != 0:
|
||||
if self.Gen.AssignGen._annotation_contains_name(aa_ml.annotation, "str") != 0 or self.Gen.AssignGen._annotation_contains_name(aa_ml.annotation, "bytes") != 0:
|
||||
self.Gen.VarGen.set_var_ptr_element(trans.SymTab, var_name)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
@@ -132,8 +132,7 @@ novirtual class TypeGenCDef(TypeGenBase.TypeGenBase):
|
||||
def _cdefine_table_pool(self,
|
||||
pool: memhub.MemBuddy*) -> memhub.MemBuddy*:
|
||||
"""CDefine 表本体的池:恒取 PermPool(不可用则退回入参 pool)"""
|
||||
if CompilerFactory.factory is not None \
|
||||
and CompilerFactory.factory.PermPool is not None:
|
||||
if CompilerFactory.factory is not None and CompilerFactory.factory.PermPool is not None:
|
||||
return CompilerFactory.factory.PermPool
|
||||
return pool
|
||||
|
||||
@@ -173,8 +172,7 @@ novirtual class TypeGenCDef(TypeGenBase.TypeGenBase):
|
||||
self._cdef_idx_init(tp)
|
||||
# 表就绪守卫:表本体缺失/半初始化(建表失败或外部置空)⇒ fail-fast,
|
||||
# 不写垃圾(append 之前必有非空断言)
|
||||
if self.CDefineNames is None or self.CDefineValues is None \
|
||||
or self.CDefineDoubleFlags is None or self.CDefineStrFlags is None:
|
||||
if self.CDefineNames is None or self.CDefineValues is None or self.CDefineDoubleFlags is None or self.CDefineStrFlags is None:
|
||||
self.Gen.TypeGenErr.fatal_error(None, "CDefine 表未就绪(CDefineNames/Values/Flags 为空)", "MemoryError")
|
||||
return
|
||||
name_copy: str = pool.alloc(string.strlen(name) + 1)
|
||||
@@ -224,8 +222,7 @@ novirtual class TypeGenCDef(TypeGenBase.TypeGenBase):
|
||||
self.CDefineStrFlags = tsf
|
||||
self._cdef_idx_init(tp)
|
||||
# 表就绪守卫(同 register_cdefine_constant):append 之前必有非空断言
|
||||
if self.CDefineNames is None or self.CDefineValues is None \
|
||||
or self.CDefineDoubleFlags is None or self.CDefineStrFlags is None:
|
||||
if self.CDefineNames is None or self.CDefineValues is None or self.CDefineDoubleFlags is None or self.CDefineStrFlags is None:
|
||||
self.Gen.TypeGenErr.fatal_error(None, "CDefine 浮点表未就绪(CDefineNames/Values/Flags 为空)", "MemoryError")
|
||||
return
|
||||
name_copy_d: str = pool.alloc(string.strlen(name) + 1)
|
||||
@@ -280,8 +277,7 @@ novirtual class TypeGenCDef(TypeGenBase.TypeGenBase):
|
||||
self.CDefineStrFlags = tsf
|
||||
self._cdef_idx_init(tp)
|
||||
# 表就绪守卫(同 register_cdefine_constant):append 之前必有非空断言
|
||||
if self.CDefineNames is None or self.CDefineValues is None \
|
||||
or self.CDefineDoubleFlags is None or self.CDefineStrFlags is None:
|
||||
if self.CDefineNames is None or self.CDefineValues is None or self.CDefineDoubleFlags is None or self.CDefineStrFlags is None:
|
||||
self.Gen.TypeGenErr.fatal_error(None, "CDefine 字符串表未就绪(CDefineNames/Values/Flags 为空)", "MemoryError")
|
||||
return
|
||||
ncopy_s: str = pool.alloc(string.strlen(name) + 1)
|
||||
@@ -402,8 +398,7 @@ novirtual class TypeGenCDef(TypeGenBase.TypeGenBase):
|
||||
# 结果);索引不可用时回退下方原全表线性扫描。
|
||||
cd_start: sizet = 0
|
||||
cd_end: sizet = n
|
||||
if name is not None and self.CDefineNameIdxBuilt == int(n) \
|
||||
and self.CDefineNameIdx is not None and self.CDefineNameIdxCap > 0:
|
||||
if name is not None and self.CDefineNameIdxBuilt == int(n) and self.CDefineNameIdx is not None and self.CDefineNameIdxCap > 0:
|
||||
cd_hit: int = self._cdef_idx_find(name)
|
||||
if cd_hit < 0:
|
||||
return 0
|
||||
@@ -444,8 +439,7 @@ novirtual class TypeGenCDef(TypeGenBase.TypeGenBase):
|
||||
# 结果);索引不可用时回退下方原全表线性扫描。
|
||||
cd_start: sizet = 0
|
||||
cd_end: sizet = n
|
||||
if name is not None and self.CDefineNameIdxBuilt == int(n) \
|
||||
and self.CDefineNameIdx is not None and self.CDefineNameIdxCap > 0:
|
||||
if name is not None and self.CDefineNameIdxBuilt == int(n) and self.CDefineNameIdx is not None and self.CDefineNameIdxCap > 0:
|
||||
cd_hit: int = self._cdef_idx_find(name)
|
||||
if cd_hit < 0:
|
||||
return 0.0
|
||||
@@ -487,8 +481,7 @@ novirtual class TypeGenCDef(TypeGenBase.TypeGenBase):
|
||||
# 结果);索引不可用时回退下方原全表线性扫描。
|
||||
cd_start: sizet = 0
|
||||
cd_end: sizet = n
|
||||
if name is not None and self.CDefineNameIdxBuilt == int(n) \
|
||||
and self.CDefineNameIdx is not None and self.CDefineNameIdxCap > 0:
|
||||
if name is not None and self.CDefineNameIdxBuilt == int(n) and self.CDefineNameIdx is not None and self.CDefineNameIdxCap > 0:
|
||||
cd_hit: int = self._cdef_idx_find(name)
|
||||
if cd_hit < 0:
|
||||
return None
|
||||
|
||||
@@ -147,8 +147,7 @@ class TypeGenCType(TypeGenBase.TypeGenBase):
|
||||
def _ctypedef_table_pool(self,
|
||||
pool: memhub.MemBuddy*) -> memhub.MemBuddy*:
|
||||
"""CTypedef 表本体的池:恒取 PermPool(不可用则退回入参 pool)"""
|
||||
if CompilerFactory.factory is not None \
|
||||
and CompilerFactory.factory.PermPool is not None:
|
||||
if CompilerFactory.factory is not None and CompilerFactory.factory.PermPool is not None:
|
||||
return CompilerFactory.factory.PermPool
|
||||
return pool
|
||||
|
||||
@@ -261,8 +260,7 @@ class TypeGenCType(TypeGenBase.TypeGenBase):
|
||||
# 注册时按名去重(register_ctypedef 已存在则原地更新类型串、不追加)⇒ 名
|
||||
# 唯一且注册后不再改写,索引完整覆盖全表 ⇒ 未命中即"确无",直接返回 None
|
||||
# (= 原全表扫描结果);索引不可用/不可信 → 回退下方原全表扫描。
|
||||
if self.CTypedefNameIdxBuilt == int(n) \
|
||||
and self.CTypedefNameIdx is not None and self.CTypedefNameIdxCap > 0:
|
||||
if self.CTypedefNameIdxBuilt == int(n) and self.CTypedefNameIdx is not None and self.CTypedefNameIdxCap > 0:
|
||||
ti: int = self._ctypedef_idx_find(name)
|
||||
if ti < 0:
|
||||
return None
|
||||
@@ -527,8 +525,7 @@ class TypeGenCType(TypeGenBase.TypeGenBase):
|
||||
if string.strncmp(at_attr_v, "CTypedef", 8) != 0:
|
||||
return 0
|
||||
sep_ch_d: char = at_attr_v[8]
|
||||
if sep_ch_d != '\0' and sep_ch_d != ' ' and sep_ch_d != '\n' \
|
||||
and sep_ch_d != '\r' and sep_ch_d != '\t' and sep_ch_d != '|':
|
||||
if sep_ch_d != '\0' and sep_ch_d != ' ' and sep_ch_d != '\n' and sep_ch_d != '\r' and sep_ch_d != '\t' and sep_ch_d != '|':
|
||||
return 0
|
||||
at_val_v: ast.AST* = ast.attribute_get_value(at)
|
||||
if at_val_v is None or at_val_v.kind() != ast.ASTKind.Name:
|
||||
@@ -541,8 +538,7 @@ class TypeGenCType(TypeGenBase.TypeGenBase):
|
||||
if string.strncmp(mod_id_v, "t", 1) != 0:
|
||||
return 0
|
||||
sep_ch_m: char = mod_id_v[1]
|
||||
if sep_ch_m != '\0' and sep_ch_m != ' ' and sep_ch_m != '\n' \
|
||||
and sep_ch_m != '\r' and sep_ch_m != '\t' and sep_ch_m != '|':
|
||||
if sep_ch_m != '\0' and sep_ch_m != ' ' and sep_ch_m != '\n' and sep_ch_m != '\r' and sep_ch_m != '\t' and sep_ch_m != '|':
|
||||
return 0
|
||||
return 1
|
||||
def ScanCTypedefDeclarations(self, pool: memhub.MemBuddy*,
|
||||
@@ -677,8 +673,7 @@ class TypeGenCType(TypeGenBase.TypeGenBase):
|
||||
# 本地表未命中:跨模块 CDefine 查找
|
||||
# 用 HandlesExpr 模块级委托(self._lookup_cross_module_cdefine 是
|
||||
# ExprGenMixin 方法,TypeGenMixin 直接调用会生成未定义引用)
|
||||
if (from_imports is not None or imported_modules is not None) \
|
||||
and pool is not None:
|
||||
if (from_imports is not None or imported_modules is not None) and pool is not None:
|
||||
x_val: int = self.Gen.ExprGenCdef._lookup_cross_module_cdefine(pool, nm.id, from_imports, imported_modules)
|
||||
if self.Gen.TypeGenCDef.is_cdefine_found() != 0:
|
||||
self.ConstEvalOk = 1
|
||||
@@ -700,8 +695,7 @@ class TypeGenCType(TypeGenBase.TypeGenBase):
|
||||
if at.value is not None and at.value.kind() == ast.ASTKind.Name:
|
||||
at_mod: ast.Name* = ast.Name*(at.value)
|
||||
if at_mod.id is not None:
|
||||
if (from_imports is not None or imported_modules is not None) \
|
||||
and pool is not None:
|
||||
if (from_imports is not None or imported_modules is not None) and pool is not None:
|
||||
mod_len: sizet = string.strlen(at_mod.id)
|
||||
fi_buf: str = pool.alloc(mod_len + 3)
|
||||
if fi_buf is not None:
|
||||
|
||||
@@ -409,9 +409,7 @@ novirtual class TypeGenErr(TypeGenBase.TypeGenBase):
|
||||
return 1
|
||||
elif k == ast.ASTKind.FunctionDef or k == ast.ASTKind.ClassDef:
|
||||
continue
|
||||
elif k == ast.ASTKind.If or k == ast.ASTKind.While or \
|
||||
k == ast.ASTKind.For or k == ast.ASTKind.Try or \
|
||||
k == ast.ASTKind.With or k == ast.ASTKind.Match:
|
||||
elif k == ast.ASTKind.If or k == ast.ASTKind.While or k == ast.ASTKind.For or k == ast.ASTKind.Try or k == ast.ASTKind.With or k == ast.ASTKind.Match:
|
||||
sub: list[ast.AST*]* = stmt.children
|
||||
if sub is not None and len(sub) > 0:
|
||||
if self.body_has_value_return(pool, sub) != 0:
|
||||
|
||||
@@ -121,8 +121,7 @@ novirtual class TypeGenResolve(TypeGenBase.TypeGenBase):
|
||||
return None
|
||||
k2: int = node.kind()
|
||||
# Name / Attribute / BinOp / 嵌套 Subscript:复用类型名提取
|
||||
if k2 == ast.ASTKind.Name or k2 == ast.ASTKind.Attribute \
|
||||
or k2 == ast.ASTKind.BinOp or k2 == ast.ASTKind.Subscript:
|
||||
if k2 == ast.ASTKind.Name or k2 == ast.ASTKind.Attribute or k2 == ast.ASTKind.BinOp or k2 == ast.ASTKind.Subscript:
|
||||
return self._get_type_name_from_annotation(pool, node)
|
||||
# Constant:数值/字符串字面量(t.CArray[elem, 104] 的 count 等)
|
||||
if k2 == ast.ASTKind.Constant:
|
||||
@@ -762,8 +761,7 @@ novirtual class TypeGenResolve(TypeGenBase.TypeGenBase):
|
||||
# `T*` 并存两个特化体(现场 _list.vp:83 return self 的
|
||||
# CastError:list[<sha>.AST*] ↔ list[rawptr[<sha>.AST]])。
|
||||
# 详见 _is_ptr_subscript_container_text 的头注释。
|
||||
if self._is_ptr_subscript_container_text(container_g) != 0 \
|
||||
and len(arg_list_g) == 1:
|
||||
if self._is_ptr_subscript_container_text(container_g) != 0 and len(arg_list_g) == 1:
|
||||
_only_arg_g: str = arg_list_g.get(0)
|
||||
_star_cg: str = self._ptr_star_text(pool, _only_arg_g)
|
||||
if _star_cg is not None:
|
||||
@@ -884,8 +882,7 @@ novirtual class TypeGenResolve(TypeGenBase.TypeGenBase):
|
||||
if from_imports is not None:
|
||||
_bi_mod: str = self.Gen.ImportsGen.lookup_from_import(from_imports, type_name, 0)
|
||||
if _bi_mod is not None:
|
||||
if (string.strcmp(_bi_mod, "t") == 0 or string.strcmp(_bi_mod, "c") == 0) \
|
||||
and self.map_t_type(pool, type_name) is not None:
|
||||
if (string.strcmp(_bi_mod, "t") == 0 or string.strcmp(_bi_mod, "c") == 0) and self.map_t_type(pool, type_name) is not None:
|
||||
_bi_len: sizet = string.strlen(_bi_mod) + 1 + string.strlen(type_name) + 1
|
||||
_bi_buf: str = pool.alloc(_bi_len)
|
||||
if _bi_buf is not None:
|
||||
@@ -925,8 +922,7 @@ novirtual class TypeGenResolve(TypeGenBase.TypeGenBase):
|
||||
# 状态无关,故第一遍(A-pre)就能给出带 SHA1 的实参名,字段
|
||||
# 类型不会被冻结成裸名版本、与后续构造调用处分裂。
|
||||
_def_sha1 = _def_mod
|
||||
elif self.Gen.StructGen.CurDefClassName is not None \
|
||||
and string.strcmp(self.Gen.StructGen.CurDefClassName, type_name) == 0:
|
||||
elif self.Gen.StructGen.CurDefClassName is not None and string.strcmp(self.Gen.StructGen.CurDefClassName, type_name) == 0:
|
||||
# ③ 表无关兜底:正在定义的类名与查询名**逐字相同** ⇒ 就是本类
|
||||
# (自引用)。②的表可能因"登记时表未就绪"或"键随 pool 回收"
|
||||
# 查不到,而类名由类定义入口与 CurDefModuleSha1 同源记录、不经
|
||||
@@ -1000,8 +996,7 @@ novirtual class TypeGenResolve(TypeGenBase.TypeGenBase):
|
||||
# 只对**结构体表里根本没有该名**(_bare_entry is None)的情形豁免:若它确
|
||||
# 是已注册的类(如 .vpi 半条目)只是缺定义模块 SHA1,那是真正的归属缺口,
|
||||
# 照旧报出(不被同名 typedef 掩盖)。
|
||||
if _w_need_log != 0 and _bare_entry is None \
|
||||
and self._is_non_class_type_name(pool, type_name) != 0:
|
||||
if _w_need_log != 0 and _bare_entry is None and self._is_non_class_type_name(pool, type_name) != 0:
|
||||
_w_need_log = 0
|
||||
if _w_need_log != 0:
|
||||
_w_mod: str = "None"
|
||||
@@ -1059,14 +1054,12 @@ novirtual class TypeGenResolve(TypeGenBase.TypeGenBase):
|
||||
left_ok: int = 1
|
||||
if i > 0:
|
||||
lc: char = s[i - 1]
|
||||
if (lc >= 'a' and lc <= 'z') or (lc >= 'A' and lc <= 'Z') \
|
||||
or (lc >= '0' and lc <= '9') or lc == '_':
|
||||
if (lc >= 'a' and lc <= 'z') or (lc >= 'A' and lc <= 'Z') or (lc >= '0' and lc <= '9') or lc == '_':
|
||||
left_ok = 0
|
||||
right_ok: int = 1
|
||||
if i + id_len < s_len:
|
||||
rc: char = s[i + id_len]
|
||||
if (rc >= 'a' and rc <= 'z') or (rc >= 'A' and rc <= 'Z') \
|
||||
or (rc >= '0' and rc <= '9') or rc == '_':
|
||||
if (rc >= 'a' and rc <= 'z') or (rc >= 'A' and rc <= 'Z') or (rc >= '0' and rc <= '9') or rc == '_':
|
||||
right_ok = 0
|
||||
if left_ok != 0 and right_ok != 0:
|
||||
return 1
|
||||
@@ -1487,19 +1480,14 @@ novirtual class TypeGenResolve(TypeGenBase.TypeGenBase):
|
||||
name_l: sizet = 0
|
||||
vs: sizet = 0
|
||||
is_sugar: int = 0
|
||||
if lead + 8 <= line_len and buf[line_start + lead] == 't' \
|
||||
and buf[line_start + lead + 1] == 'y' and buf[line_start + lead + 2] == 'p' \
|
||||
and buf[line_start + lead + 3] == 'e' and buf[line_start + lead + 4] == 'd' \
|
||||
and buf[line_start + lead + 5] == 'e' and buf[line_start + lead + 6] == 'f' \
|
||||
and (buf[line_start + lead + 7] == ' ' or buf[line_start + lead + 7] == '\t'):
|
||||
if lead + 8 <= line_len and buf[line_start + lead] == 't' and buf[line_start + lead + 1] == 'y' and buf[line_start + lead + 2] == 'p' and buf[line_start + lead + 3] == 'e' and buf[line_start + lead + 4] == 'd' and buf[line_start + lead + 5] == 'e' and buf[line_start + lead + 6] == 'f' and (buf[line_start + lead + 7] == ' ' or buf[line_start + lead + 7] == '\t'):
|
||||
is_sugar = 1
|
||||
if is_sugar != 0:
|
||||
k: sizet = lead + 7
|
||||
while k < line_len and (buf[line_start + k] == ' ' or buf[line_start + k] == '\t'):
|
||||
k += 1
|
||||
name_s = k
|
||||
while k < line_len and buf[line_start + k] != ' ' and buf[line_start + k] != '\t' \
|
||||
and buf[line_start + k] != '=' and buf[line_start + k] != '\r':
|
||||
while k < line_len and buf[line_start + k] != ' ' and buf[line_start + k] != '\t' and buf[line_start + k] != '=' and buf[line_start + k] != '\r':
|
||||
k += 1
|
||||
name_l = k - name_s
|
||||
while k < line_len and (buf[line_start + k] == ' ' or buf[line_start + k] == '\t'):
|
||||
@@ -1539,8 +1527,7 @@ novirtual class TypeGenResolve(TypeGenBase.TypeGenBase):
|
||||
while vs < line_len and (buf[line_start + vs] == ' ' or buf[line_start + vs] == '\t'):
|
||||
vs += 1
|
||||
ve: sizet = line_len
|
||||
while ve > vs and (buf[line_start + ve - 1] == ' ' or buf[line_start + ve - 1] == '\t' \
|
||||
or buf[line_start + ve - 1] == '\r'):
|
||||
while ve > vs and (buf[line_start + ve - 1] == ' ' or buf[line_start + ve - 1] == '\t' or buf[line_start + ve - 1] == '\r'):
|
||||
ve -= 1
|
||||
if ve <= vs:
|
||||
return 0
|
||||
@@ -1576,8 +1563,7 @@ novirtual class TypeGenResolve(TypeGenBase.TypeGenBase):
|
||||
# 段缓冲(VpiReader._resolve_single_vpi_type_str 的 seg_buf malloc 后
|
||||
# 立即 free),直接存指针会悬垂,_build_ann_fail_msg 的 snprintf 读已
|
||||
# 释放内存(ASan heap-use-after-free)。
|
||||
self.Gen.TypeGenCType.LastBuiltinsTypedefName = \
|
||||
self.Gen.TypeGenCType.store_builtins_diag(0, name)
|
||||
self.Gen.TypeGenCType.LastBuiltinsTypedefName = self.Gen.TypeGenCType.store_builtins_diag(0, name)
|
||||
self.Gen.TypeGenCType.LastBuiltinsTypedefResult = None
|
||||
# rawptr 已内置于编译器(TPC/TPV 双端语法保留字,不可重定义):
|
||||
# 优先于一切外部声明(builtins.vp 已不再声明,用户自行 typedef 也会被
|
||||
@@ -1589,8 +1575,7 @@ novirtual class TypeGenResolve(TypeGenBase.TypeGenBase):
|
||||
if ts_b is not None and self.Gen.TypeGenCType.CTypedefFound != 0:
|
||||
# 表内值可能仍是模块限定引用(如 size_t → stdint.size_t),展开后返回
|
||||
b_hit_r: str = self._expand_typedef_ref(pool, ts_b)
|
||||
self.Gen.TypeGenCType.LastBuiltinsTypedefResult = \
|
||||
self.Gen.TypeGenCType.store_builtins_diag(1, b_hit_r)
|
||||
self.Gen.TypeGenCType.LastBuiltinsTypedefResult = self.Gen.TypeGenCType.store_builtins_diag(1, b_hit_r)
|
||||
return b_hit_r
|
||||
# 本文件已扫过 builtins 源(表内无 = 非 builtins typedef):不再重复读文件
|
||||
if self.Gen.TypeGenCType.BuiltinsTypedefScanned != 0:
|
||||
@@ -1639,14 +1624,11 @@ novirtual class TypeGenResolve(TypeGenBase.TypeGenBase):
|
||||
b_imp_s += 1
|
||||
# "import" 前缀
|
||||
if b_imp_len - b_imp_s >= 6:
|
||||
if b_buf[b_imp_ls + b_imp_s] == 'i' and b_buf[b_imp_ls + b_imp_s + 1] == 'm' \
|
||||
and b_buf[b_imp_ls + b_imp_s + 2] == 'p' and b_buf[b_imp_ls + b_imp_s + 3] == 'o' \
|
||||
and b_buf[b_imp_ls + b_imp_s + 4] == 'r' and b_buf[b_imp_ls + b_imp_s + 5] == 't':
|
||||
if b_buf[b_imp_ls + b_imp_s] == 'i' and b_buf[b_imp_ls + b_imp_s + 1] == 'm' and b_buf[b_imp_ls + b_imp_s + 2] == 'p' and b_buf[b_imp_ls + b_imp_s + 3] == 'o' and b_buf[b_imp_ls + b_imp_s + 4] == 'r' and b_buf[b_imp_ls + b_imp_s + 5] == 't':
|
||||
# 找 " as " 分隔
|
||||
b_as_i: sizet = b_imp_s + 6
|
||||
while b_as_i < b_imp_len - 3:
|
||||
if b_buf[b_imp_ls + b_as_i] == ' ' and b_buf[b_imp_ls + b_as_i + 1] == 'a' \
|
||||
and b_buf[b_imp_ls + b_as_i + 2] == 's' and b_buf[b_imp_ls + b_as_i + 3] == ' ':
|
||||
if b_buf[b_imp_ls + b_as_i] == ' ' and b_buf[b_imp_ls + b_as_i + 1] == 'a' and b_buf[b_imp_ls + b_as_i + 2] == 's' and b_buf[b_imp_ls + b_as_i + 3] == ' ':
|
||||
break
|
||||
b_as_i += 1
|
||||
if b_as_i < b_imp_len - 3:
|
||||
@@ -1720,8 +1702,7 @@ novirtual class TypeGenResolve(TypeGenBase.TypeGenBase):
|
||||
b_final_r: str = None
|
||||
if b_res is not None:
|
||||
b_final_r = self._expand_typedef_ref(pool, b_res)
|
||||
self.Gen.TypeGenCType.LastBuiltinsTypedefResult = \
|
||||
self.Gen.TypeGenCType.store_builtins_diag(1, b_final_r)
|
||||
self.Gen.TypeGenCType.LastBuiltinsTypedefResult = self.Gen.TypeGenCType.store_builtins_diag(1, b_final_r)
|
||||
stdlib.free(b_buf)
|
||||
if b_final_r is not None:
|
||||
return b_final_r
|
||||
@@ -1902,8 +1883,7 @@ novirtual class TypeGenResolve(TypeGenBase.TypeGenBase):
|
||||
if type_str is None or depth > 16:
|
||||
return type_str
|
||||
# 复合表达式(联合/泛型)不在此展开
|
||||
if string.strchr(type_str, '[') is not None \
|
||||
or string.strchr(type_str, '|') is not None:
|
||||
if string.strchr(type_str, '[') is not None or string.strchr(type_str, '|') is not None:
|
||||
return type_str
|
||||
# 拆分 "mod.attr"(取最后一个 '.',支持 w32.win32base.HANDLE)
|
||||
dot_pos: str = string.strrchr(type_str, '.')
|
||||
@@ -1925,8 +1905,7 @@ novirtual class TypeGenResolve(TypeGenBase.TypeGenBase):
|
||||
if lib_ty is not None:
|
||||
return self._expand_typedef_ref(pool, lib_ty, depth + 1)
|
||||
ts_x: str = self.Gen.TypeGenCType.lookup_ctypedef(attr)
|
||||
if ts_x is not None and self.Gen.TypeGenCType.CTypedefFound != 0 \
|
||||
and string.strcmp(ts_x, type_str) != 0:
|
||||
if ts_x is not None and self.Gen.TypeGenCType.CTypedefFound != 0 and string.strcmp(ts_x, type_str) != 0:
|
||||
return self._expand_typedef_ref(pool, ts_x, depth + 1)
|
||||
return type_str
|
||||
def _long_llvm_ty(self, pool: memhub.MemBuddy*) -> mlirlite.LLVMType*:
|
||||
@@ -1943,10 +1922,7 @@ novirtual class TypeGenResolve(TypeGenBase.TypeGenBase):
|
||||
triple: str = Config.TargetTriple
|
||||
if triple is None:
|
||||
triple = "x86_64-pc-windows-gnu"
|
||||
if string.strstr(triple, "windows") is not None \
|
||||
or string.strstr(triple, "win32") is not None \
|
||||
or string.strstr(triple, "mingw") is not None \
|
||||
or string.strstr(triple, "msvc") is not None:
|
||||
if string.strstr(triple, "windows") is not None or string.strstr(triple, "win32") is not None or string.strstr(triple, "mingw") is not None or string.strstr(triple, "msvc") is not None:
|
||||
return mlirlite.Int32(pool)
|
||||
return mlirlite.Int64(pool)
|
||||
# ============================================================
|
||||
@@ -2767,8 +2743,7 @@ novirtual class TypeGenResolve(TypeGenBase.TypeGenBase):
|
||||
# 仍在但 ReplStubLayoutMode 已归零 ⇒ 本分支不经过,特化照常发生(届时按需
|
||||
# 注册的依赖已就绪;确实缺失则明确报错,落在片段内、不影响启动)。
|
||||
# 批处理 ReplCtx 恒 None 且 ReplStubLayoutMode 恒 0 ⇒ 本分支不经过,逐字不变。
|
||||
if trans is not None and trans.ReplCtx is not None \
|
||||
and VpiReader.ReplStubLayoutMode != 0:
|
||||
if trans is not None and trans.ReplCtx is not None and VpiReader.ReplStubLayoutMode != 0:
|
||||
# 已登记的特化结构体(会话期先前注册)直接复用:本分支只读、不翻译
|
||||
spec_ty_inj: mlirlite.LLVMType* = self.Gen.StructGen.get_struct_type(gen_mangled)
|
||||
if spec_ty_inj is not None:
|
||||
@@ -2839,8 +2814,7 @@ novirtual class TypeGenResolve(TypeGenBase.TypeGenBase):
|
||||
# ⇒ 上游注解必然退化(BinOp 分支落到 Ptr(i8) 丢类型,或退化到裸基类 list*),
|
||||
# 后续 .get() 按错误元素类型分派 → inttoptr 截断崩溃。禁止静默退化:报出查表键
|
||||
# 与实际模板名。仅当基名确为泛型模板时才触发(避免误伤 rawptr/CArray 等 builtin)。
|
||||
if trans is not None and trans._declare_only == 0 \
|
||||
and self.Gen.ClassGenGeneric._find_generic_template(gen_cls_name) is not None:
|
||||
if trans is not None and trans._declare_only == 0 and self.Gen.ClassGenGeneric._find_generic_template(gen_cls_name) is not None:
|
||||
self.Gen.TypeGenErr.fatal_error(sub,
|
||||
f"泛型下标 '{gen_mangled}' 未解析出特化结构体(泛型模板='{gen_cls_name}');"
|
||||
f"该注解将退化为裸基类/i8* → 后续 .get() 按错误元素类型分派并截断指针",
|
||||
@@ -3199,8 +3173,7 @@ novirtual class TypeGenResolve(TypeGenBase.TypeGenBase):
|
||||
# "%{会话sha1}.{类名}" 这种宿主里不存在的类名 → 方法调用符号名误导),
|
||||
# 故排除该情形,保持原 fail-fast。
|
||||
if own_sha_rn is None:
|
||||
if trans.ModuleSha1 is not None \
|
||||
and string.strcmp(trans.ModuleSha1, GenTypes.REPL_SESSION_SHA1) != 0:
|
||||
if trans.ModuleSha1 is not None and string.strcmp(trans.ModuleSha1, GenTypes.REPL_SESSION_SHA1) != 0:
|
||||
own_sha_rn = trans.ModuleSha1
|
||||
if own_sha_rn is not None:
|
||||
ty_repl_n: mlirlite.LLVMType* = self._repl_opaque_class_ty(pool, own_sha_rn, nm.id)
|
||||
@@ -3254,8 +3227,7 @@ novirtual class TypeGenResolve(TypeGenBase.TypeGenBase):
|
||||
# 前缀、非已导入模块、非库 typedef ⇒ 原本必然返回 None,
|
||||
# 故新增"扁平名 `外类_内类` 命中即返回"不会覆盖任何既有
|
||||
# 成功路径(命名口径见 ClassGenDef._translate_nested_classdefs)。
|
||||
nested_ty_q: mlirlite.LLVMType* = \
|
||||
self._resolve_nested_class_type(pool, val_name.id, at.attr, trans)
|
||||
nested_ty_q: mlirlite.LLVMType* = self._resolve_nested_class_type(pool, val_name.id, at.attr, trans)
|
||||
if nested_ty_q is not None:
|
||||
return nested_ty_q
|
||||
return None
|
||||
@@ -3530,13 +3502,7 @@ novirtual class TypeGenResolve(TypeGenBase.TypeGenBase):
|
||||
if keep_other_ty == 0 and other_node is not None and other_node.kind() == ast.ASTKind.Name:
|
||||
other_nm_b: ast.Name* = ast.Name*(other_node)
|
||||
if other_nm_b.id is not None:
|
||||
if string.strcmp(other_nm_b.id, "int") == 0 or \
|
||||
string.strcmp(other_nm_b.id, "char") == 0 or \
|
||||
string.strcmp(other_nm_b.id, "str") == 0 or \
|
||||
string.strcmp(other_nm_b.id, "bytes") == 0 or \
|
||||
string.strcmp(other_nm_b.id, "bool") == 0 or \
|
||||
string.strcmp(other_nm_b.id, "float") == 0 or \
|
||||
string.strcmp(other_nm_b.id, "double") == 0:
|
||||
if string.strcmp(other_nm_b.id, "int") == 0 or string.strcmp(other_nm_b.id, "char") == 0 or string.strcmp(other_nm_b.id, "str") == 0 or string.strcmp(other_nm_b.id, "bytes") == 0 or string.strcmp(other_nm_b.id, "bool") == 0 or string.strcmp(other_nm_b.id, "float") == 0 or string.strcmp(other_nm_b.id, "double") == 0:
|
||||
keep_other_ty = 1
|
||||
# typedef 别名保真(判据=解析是否成功,非白名单扩名):
|
||||
# sizet/uint64/CSizeT 等别名经 resolve_annotation_type 已解析出标量,
|
||||
@@ -3694,8 +3660,7 @@ novirtual class TypeGenResolve(TypeGenBase.TypeGenBase):
|
||||
# 统一 i8*。必须在本分支的 Name 路径(泛型特化 / CArray / builtins
|
||||
# typedef 兜底)之前判定,否则裸名 callable 会被当泛型类名查空。
|
||||
# 完整签名的返回类型注册见 TypeGenErr.try_extract_callable_ret。
|
||||
if sub.value.kind() == ast.ASTKind.Name \
|
||||
and self._IsCallableSubscriptValue(sub.value) != 0:
|
||||
if sub.value.kind() == ast.ASTKind.Name and self._IsCallableSubscriptValue(sub.value) != 0:
|
||||
return mlirlite.Ptr(pool, mlirlite.Int8(pool))
|
||||
# 泛型类类型注解: list[int] → 查找已特化的 struct(value 是 Name 泛型类名)
|
||||
if sub.value.kind() == ast.ASTKind.Name:
|
||||
@@ -3827,8 +3792,7 @@ novirtual class TypeGenResolve(TypeGenBase.TypeGenBase):
|
||||
# 与 TPV 函数传指针惯例一致(函数值 bitcast 为 i8* 存储,调用时按实参重建签名)
|
||||
if string.strcmp(arr_at.attr, "Callable") == 0:
|
||||
# t/c 是内置命名空间(不编译、不入 imported_modules),无需显式导入检查
|
||||
if string.strcmp(arr_val_name.id, "t") != 0 and string.strcmp(arr_val_name.id, "c") != 0 \
|
||||
and self.Gen.ImportsGen.is_module_imported(imported_modules, arr_val_name.id) == 0:
|
||||
if string.strcmp(arr_val_name.id, "t") != 0 and string.strcmp(arr_val_name.id, "c") != 0 and self.Gen.ImportsGen.is_module_imported(imported_modules, arr_val_name.id) == 0:
|
||||
self.Gen.TypeGenErr.fatal_type_error(node, "t.Callable 模块未导入")
|
||||
return mlirlite.Ptr(pool, mlirlite.Int8(pool))
|
||||
# 指针类型: t.CPtr[T] → Ptr(T)(T 自身可含指针层级):t.CPtr[t.CPtr] → i8**,
|
||||
@@ -3838,8 +3802,7 @@ novirtual class TypeGenResolve(TypeGenBase.TypeGenBase):
|
||||
# 分支:裸类名恒为原型后该补偿无对象,且会在 T 实例化为指针类型时吃掉
|
||||
# 真层数(`t.CPtr[T]` 应得 T**)。
|
||||
if string.strcmp(arr_at.attr, "CPtr") == 0:
|
||||
if string.strcmp(arr_val_name.id, "t") != 0 and string.strcmp(arr_val_name.id, "c") != 0 \
|
||||
and self.Gen.ImportsGen.is_module_imported(imported_modules, arr_val_name.id) == 0:
|
||||
if string.strcmp(arr_val_name.id, "t") != 0 and string.strcmp(arr_val_name.id, "c") != 0 and self.Gen.ImportsGen.is_module_imported(imported_modules, arr_val_name.id) == 0:
|
||||
self.Gen.TypeGenErr.fatal_type_error(node, "t.CPtr 模块未导入")
|
||||
inner_cptr_ty: mlirlite.LLVMType* = self.resolve_annotation_type(pool, sub.slice, imported_modules, from_imports, trans, depth + 1)
|
||||
if inner_cptr_ty is None:
|
||||
@@ -3857,8 +3820,7 @@ novirtual class TypeGenResolve(TypeGenBase.TypeGenBase):
|
||||
return mlirlite.Ptr(pool, inner_cptr_ty)
|
||||
if string.strcmp(arr_at.attr, "CArray") != 0:
|
||||
self.Gen.TypeGenErr.fatal_type_error(node, "不支持的 Subscript 类型注解(仅支持 t.CArray / t.Callable)")
|
||||
if string.strcmp(arr_val_name.id, "t") != 0 and string.strcmp(arr_val_name.id, "c") != 0 \
|
||||
and self.Gen.ImportsGen.is_module_imported(imported_modules, arr_val_name.id) == 0:
|
||||
if string.strcmp(arr_val_name.id, "t") != 0 and string.strcmp(arr_val_name.id, "c") != 0 and self.Gen.ImportsGen.is_module_imported(imported_modules, arr_val_name.id) == 0:
|
||||
self.Gen.TypeGenErr.fatal_type_error(node, "t.CArray 模块未导入")
|
||||
# 单参数形式: t.CArray[elem_ty] → Ptr(elem_ty)
|
||||
# 相当于 t.CArray[elem_ty, None],表示静态推导长度数组
|
||||
|
||||
@@ -918,8 +918,7 @@ novirtual class VarGenMixin:
|
||||
if entry.TyTag == GenTypes.REPL_TY_STRUCT:
|
||||
sz: int = self.repl_type_size(vt)
|
||||
al: int = self.repl_type_align(vt)
|
||||
if sz <= 0 or al <= 0 or sz > GenTypes.REPL_SLOT_SIZE \
|
||||
or al > GenTypes.REPL_SLOT_SIZE:
|
||||
if sz <= 0 or al <= 0 or sz > GenTypes.REPL_SLOT_SIZE or al > GenTypes.REPL_SLOT_SIZE:
|
||||
return None
|
||||
return vt
|
||||
|
||||
@@ -1277,8 +1276,7 @@ novirtual class VarGenMixin:
|
||||
if tag == GenTypes.REPL_TY_STR or tag == GenTypes.REPL_TY_PTR:
|
||||
i8_ptr_ty: mlirlite.LLVMType* = mlirlite.Ptr(pool, mlirlite.Int8(pool))
|
||||
pv: mlirlite.Value* = val
|
||||
if val.Ty is not None and self.Gen.ExprGenBase.is_ptr_type(val.Ty) != 0 \
|
||||
and self.Gen.AssignGen._stg_ty_equal(pool, val.Ty, i8_ptr_ty) == 0:
|
||||
if val.Ty is not None and self.Gen.ExprGenBase.is_ptr_type(val.Ty) != 0 and self.Gen.AssignGen._stg_ty_equal(pool, val.Ty, i8_ptr_ty) == 0:
|
||||
# 已是指向 i8 的指针(str/bytes/t.CPtr)时跳过——LLVM 拒绝同型 bitcast
|
||||
pv = mlirlite.build_bitcast(builder, val, i8_ptr_ty)
|
||||
if pv is None:
|
||||
@@ -1449,10 +1447,7 @@ novirtual class VarGenMixin:
|
||||
f" {self.repl_tag_label(entry.TyTag, entry.Bits)}",
|
||||
"CastError")
|
||||
return 1
|
||||
if self.Gen.ExprGenBase.is_ptr_type(slot_ty) != 0 \
|
||||
and store_val.Ty is not None \
|
||||
and self.Gen.ExprGenBase.is_ptr_type(store_val.Ty) != 0 \
|
||||
and self.Gen.AssignGen._stg_ty_equal(pool, store_val.Ty, slot_ty) == 0:
|
||||
if self.Gen.ExprGenBase.is_ptr_type(slot_ty) != 0 and store_val.Ty is not None and self.Gen.ExprGenBase.is_ptr_type(store_val.Ty) != 0 and self.Gen.AssignGen._stg_ty_equal(pool, store_val.Ty, slot_ty) == 0:
|
||||
# 指针同型化(槽类型与右侧指针可能不是同一类型实例;位宽相同)。
|
||||
# 同型(含两侧都是 i8*)时跳过——LLVM 拒绝同型 bitcast。
|
||||
store_val = mlirlite.build_bitcast(builder, store_val, slot_ty)
|
||||
|
||||
+8
-16
@@ -1116,11 +1116,9 @@ def ReplInitSession() -> int:
|
||||
ReplMsgName = _perm_pool.alloc(_REPL_FN_NAME_MAX)
|
||||
ReplSigText = _perm_pool.alloc(_REPL_SIG_TEXT_CAP)
|
||||
ReplSigText2 = _perm_pool.alloc(_REPL_SIG_TEXT_CAP)
|
||||
if ReplLiftBuf is None or ReplLiftNames is None or ReplSigTags is None \
|
||||
or ReplSigBits is None or ReplSigResult is None:
|
||||
if ReplLiftBuf is None or ReplLiftNames is None or ReplSigTags is None or ReplSigBits is None or ReplSigResult is None:
|
||||
return 1
|
||||
if ReplLineShow is None or ReplMsgName is None \
|
||||
or ReplSigText is None or ReplSigText2 is None:
|
||||
if ReplLineShow is None or ReplMsgName is None or ReplSigText is None or ReplSigText2 is None:
|
||||
return 1
|
||||
ReplLiftBuf[0] = 0
|
||||
ReplLiftNames[0] = 0
|
||||
@@ -1202,8 +1200,7 @@ def ReplInitSession() -> int:
|
||||
ReplBaseCDefineKinds = _perm_pool.alloc(8 * _REPL_BASE_CDEFINE_MAX)
|
||||
ReplBaseCTypedefNames = _perm_pool.alloc(8 * _REPL_BASE_CTYPEDEF_MAX)
|
||||
ReplBaseCTypedefTypeStrs = _perm_pool.alloc(8 * _REPL_BASE_CTYPEDEF_MAX)
|
||||
if ReplFragImplibs is None or ReplBaseCDefineNames is None \
|
||||
or ReplBaseCDefineValues is None or ReplBaseCDefineKinds is None:
|
||||
if ReplFragImplibs is None or ReplBaseCDefineNames is None or ReplBaseCDefineValues is None or ReplBaseCDefineKinds is None:
|
||||
return 1
|
||||
if ReplBaseCTypedefNames is None or ReplBaseCTypedefTypeStrs is None:
|
||||
return 1
|
||||
@@ -1600,8 +1597,7 @@ def _repl_lift_def_header(line: bytes, n: int, name_out: bytes, name_cap: int) -
|
||||
while p < n:
|
||||
c: char = line[p]
|
||||
is_id: int = 0
|
||||
if (c >= 'a' and c <= 'z') or (c >= 'A' and c <= 'Z') or (c >= '0' and c <= '9') \
|
||||
or c == '_':
|
||||
if (c >= 'a' and c <= 'z') or (c >= 'A' and c <= 'Z') or (c >= '0' and c <= '9') or c == '_':
|
||||
is_id = 1
|
||||
if is_id == 0:
|
||||
break
|
||||
@@ -1784,8 +1780,7 @@ def _repl_split_body(body: bytes) -> int:
|
||||
in_body = 1
|
||||
i += n + 1
|
||||
continue
|
||||
if _repl_line_has_kw(body + i, n, 0, "async") != 0 \
|
||||
and _repl_line_has_kw(body + i, n, 6, "def") != 0:
|
||||
if _repl_line_has_kw(body + i, n, 0, "async") != 0 and _repl_line_has_kw(body + i, n, 6, "def") != 0:
|
||||
stdio.printf("M3: 不支持 async def 会话函数(协程 ABI 与 M3 签名 token "
|
||||
"不相容,请改写成普通 def):%s\n", _repl_show_line(body + i, n))
|
||||
return 1
|
||||
@@ -1948,14 +1943,12 @@ def _repl_precheck_session_funcs(mod: mlirlite.LLVMModule*) -> int:
|
||||
# 重定义:只允许**同签名**覆盖(换签名会让先前片段里已编好的调用点按旧 ABI
|
||||
# 调新代码 ⇒ 静默 UB)。签名一致时只更新槽内地址(段号随之刷新)。
|
||||
sig_same: int = 1
|
||||
if old.RetTag != ReplSigResult.RetTag or old.RetBits != ReplSigResult.RetBits \
|
||||
or old.ParamCount != ReplSigResult.ParamCount:
|
||||
if old.RetTag != ReplSigResult.RetTag or old.RetBits != ReplSigResult.RetBits or old.ParamCount != ReplSigResult.ParamCount:
|
||||
sig_same = 0
|
||||
if sig_same != 0:
|
||||
pi: int = 0
|
||||
while pi < old.ParamCount:
|
||||
if int(old.ParamTags[pi]) != int(ReplSigTags[pi]) \
|
||||
or int(old.ParamBits[pi]) != int(ReplSigBits[pi]):
|
||||
if int(old.ParamTags[pi]) != int(ReplSigTags[pi]) or int(old.ParamBits[pi]) != int(ReplSigBits[pi]):
|
||||
sig_same = 0
|
||||
break
|
||||
pi += 1
|
||||
@@ -2203,8 +2196,7 @@ def _repl_model_func_sig(mod: mlirlite.LLVMModule*, name: str,
|
||||
else:
|
||||
# EH 出参(raise 语义)
|
||||
if bare_nm is not None:
|
||||
if string.strcmp(bare_nm, "__eh_msg_out__") == 0 \
|
||||
or string.strcmp(bare_nm, "__eh_code_out__") == 0:
|
||||
if string.strcmp(bare_nm, "__eh_msg_out__") == 0 or string.strcmp(bare_nm, "__eh_code_out__") == 0:
|
||||
out.EHTag = 1
|
||||
return 3
|
||||
if out.ParamCount >= GenTypes.REPL_FUNC_PARAM_MAX:
|
||||
|
||||
@@ -1141,8 +1141,7 @@ def _DetectHost() -> int:
|
||||
buf[int(n)] = char(0)
|
||||
# "AMD64\0"(A=65 M=77 D=68 6=54 4=52)
|
||||
is_amd64: int = 0
|
||||
if buf[0] == char(65) and buf[1] == char(77) and buf[2] == char(68) \
|
||||
and buf[3] == char(54) and buf[4] == char(52) and buf[5] == char(0):
|
||||
if buf[0] == char(65) and buf[1] == char(77) and buf[2] == char(68) and buf[3] == char(54) and buf[4] == char(52) and buf[5] == char(0):
|
||||
is_amd64 = 1
|
||||
if is_amd64 != 0:
|
||||
_c_triple = "x86_64-pc-windows-gnu"
|
||||
|
||||
Reference in new issue
Block a user