fix(compiler): 跨模块调用补全 int→ptr 转换与别名默认参数;类型文本缓冲 512→4096
1) CallGenMixin.vp(跨模块 extern 实参提升):指针目标形参改为无条件走 coerce_to_type——原守卫按整数位宽比较,而指针类型的 bits 恒为 0,整段提升被跳过,致 VirtualAlloc(0,...) 以 i32 传入指针形参、mlir-opt 报 operand type mismatch(ViperAIChat 失败)。 2) CallGenMixin.vp(默认参数限定键):改用 StructGen._resolve_module_sha1 解析模块 SHA——原只精确匹配模块名,import x as y 这类别名取不到真实 SHA,默认值表落空、跨模块调用实参数目不符(ViperRequestsTest 失败)。 3) 11 个文件的 TypePrint 类型文本缓冲 512→4096(分配与传入 size 成对修改):48 字段类(如 MNIST 的 Net)的 MLIR 结构体类型文本超过 512 被截断并 fail-fast。
This commit is contained in:
1 parent
7a9bc5ae75
commit
848dc0ab38
12 files changed
+57
-38
No files matched your search
@@ -553,11 +553,11 @@ novirtual class AssignGenMixin:
|
||||
if ta is None or tb is None: return 0
|
||||
# Fast path: identical instance is equal
|
||||
if uint64(ta) == uint64(tb): return 1
|
||||
buf_a: str = pool.alloc(512)
|
||||
buf_b: str = pool.alloc(512)
|
||||
buf_a: str = pool.alloc(4096)
|
||||
buf_b: str = pool.alloc(4096)
|
||||
if buf_a is None or buf_b is None: return 0
|
||||
mlirlite.TypePrint(buf_a, 512, ta, pool)
|
||||
mlirlite.TypePrint(buf_b, 512, tb, pool)
|
||||
mlirlite.TypePrint(buf_a, 4096, ta, pool)
|
||||
mlirlite.TypePrint(buf_b, 4096, tb, pool)
|
||||
if buf_a[0] == 0 or buf_b[0] == 0: return 0
|
||||
return 1 if string.strcmp(buf_a, buf_b) == 0 else 0
|
||||
|
||||
|
||||
@@ -1147,10 +1147,10 @@ novirtual class CallGenCBuiltin(CallGenBase.CallGenBase):
|
||||
first_arg = 0
|
||||
|
||||
# Type text
|
||||
ty_buf: str = pool.alloc(512)
|
||||
ty_buf: str = pool.alloc(4096)
|
||||
if ty_buf is not None:
|
||||
ty_buf[0] = '\0'
|
||||
mlirlite.TypePrint(ty_buf, 512, aval.Ty, pool)
|
||||
mlirlite.TypePrint(ty_buf, 4096, aval.Ty, pool)
|
||||
self._asm_append_cstr(args_buf, asm_arg_cap, ty_buf)
|
||||
self._asm_append_cstr(args_buf, asm_arg_cap, " ")
|
||||
self._asm_append_cstr(args_buf, asm_arg_cap, aval.Name)
|
||||
@@ -1173,10 +1173,10 @@ novirtual class CallGenCBuiltin(CallGenBase.CallGenBase):
|
||||
builder.Counter += 1
|
||||
|
||||
# Get the return type text
|
||||
ret_ty_buf: str = pool.alloc(512)
|
||||
ret_ty_buf: str = pool.alloc(4096)
|
||||
if ret_ty_buf is not None:
|
||||
ret_ty_buf[0] = '\0'
|
||||
mlirlite.TypePrint(ret_ty_buf, 512, ret_ty, pool)
|
||||
mlirlite.TypePrint(ret_ty_buf, 4096, ret_ty, pool)
|
||||
|
||||
# Size the line buffer by actual content (type text can be 512 bytes; asm/constraints may be long)
|
||||
line_cap: sizet = 512 + string.strlen(escaped_asm) + string.strlen(args_buf)
|
||||
|
||||
@@ -536,9 +536,9 @@ novirtual class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin):
|
||||
cap: int = CallGenBase.MAX_FUNC_PTR_SIGS
|
||||
ret_str: str = "?"
|
||||
if ret_ty is not None:
|
||||
typed_buf: str = pool.alloc(512)
|
||||
typed_buf: str = pool.alloc(4096)
|
||||
if typed_buf is not None:
|
||||
mlirlite.TypePrint(typed_buf, 512, ret_ty, pool)
|
||||
mlirlite.TypePrint(typed_buf, 4096, ret_ty, pool)
|
||||
if typed_buf[0] != '\0': ret_str = typed_buf
|
||||
msg_buf: str = pool.alloc(1024)
|
||||
if msg_buf is not None:
|
||||
|
||||
@@ -799,7 +799,14 @@ novirtual class CallGenMixin(CallGenBase.CallGenBase):
|
||||
if ext_param_ty is not None:
|
||||
val_bits_ap: int = self.Gen.ExprGenBase.get_llvm_type_bits(arg_val.Ty)
|
||||
tgt_bits_ap: int = self.Gen.ExprGenBase.get_llvm_type_bits(ext_param_ty)
|
||||
if val_bits_ap != 0 and tgt_bits_ap != 0 and val_bits_ap != tgt_bits_ap:
|
||||
# A pointer target reports bit width 0, so the integer-width guard alone skips it and
|
||||
# the arg stays an integer (e.g. the null-pointer constant 0 stays i32) in the call,
|
||||
# mismatching the declared pointer param (llvm.call operand type mismatch). Coerce
|
||||
# pointer targets through coerce_to_type too: it materializes the compile-time constant
|
||||
# 0 as a null pointer and fails fast on any other implicit int<->ptr conversion.
|
||||
if self.Gen.ExprGenBase.is_ptr_type(ext_param_ty) != 0:
|
||||
arg_val = self.Gen.ExprGenBase.coerce_to_type(builder, arg_val, ext_param_ty, arg)
|
||||
elif val_bits_ap != 0 and tgt_bits_ap != 0 and val_bits_ap != tgt_bits_ap:
|
||||
if val_bits_ap == 1 and val_bits_ap < tgt_bits_ap: arg_val = mlirlite.build_zext(builder, arg_val, ext_param_ty)
|
||||
else: arg_val = self.Gen.ExprGenBase.coerce_to_type(builder, arg_val, ext_param_ty, arg)
|
||||
elif found_func is not None:
|
||||
@@ -843,9 +850,21 @@ novirtual class CallGenMixin(CallGenBase.CallGenBase):
|
||||
dfx_callee_sha: str = None
|
||||
if cl.func is not None and cl.func.kind() == ast.ASTKind.Attribute:
|
||||
dfx_at: ast.Attribute* = ast.Attribute*(cl.func)
|
||||
dfx_mod_path: str = None
|
||||
if dfx_at.value is not None and dfx_at.value.kind() == ast.ASTKind.Name:
|
||||
dfx_mn: ast.Name* = ast.Name*(dfx_at.value)
|
||||
if dfx_mn.id is not None: dfx_callee_sha = self._lookup_module_sha1(dfx_mn.id)
|
||||
if dfx_mn.id is not None: dfx_mod_path = dfx_mn.id
|
||||
elif dfx_at.value is not None and dfx_at.value.kind() == ast.ASTKind.Attribute:
|
||||
# Nested module path (os._win32.exists): resolve the full path, like the call-name path below.
|
||||
dfx_mod_path = self.Gen.ExprGenAttr._attr_module_path_str(pool, dfx_at.value)
|
||||
if dfx_mod_path is not None:
|
||||
# Resolve the alias before the SHA1 lookup: _lookup_module_sha1 is an exact module-name lookup
|
||||
# and returns None for `import X.Y as Z` (Z is not a module name). Without the alias restore the
|
||||
# qualifier degrades to the current module SHA1, so find_func_defaults misses the defining module
|
||||
# and the defaults are never filled (rhttps.get(url, verify) emits 2 operands for a 3-param callee).
|
||||
dfx_fi: str = None
|
||||
if trans is not None: dfx_fi = trans._from_imports
|
||||
dfx_callee_sha = self.Gen.StructGen._resolve_module_sha1(dfx_mod_path, dfx_fi)
|
||||
if dfx_callee_sha is None and self.Gen.TypeGenBase is not None: dfx_callee_sha = self.Gen.TypeGenBase.CurrentModuleSha1
|
||||
# Look up the FuncEntry in the module table qualified by the defining module SHA1: the table
|
||||
# contains bare-name dependency stubs, so an unqualified hit would pick mm.init for usb.uhci.init (N17).
|
||||
|
||||
@@ -816,9 +816,9 @@ novirtual class ClassGenVTable(ClassGenBase.ClassGenBase):
|
||||
else:
|
||||
# fail-fast: has a -> annotation but control truly falls off the end (traceback-style).
|
||||
if ret_ty is not None:
|
||||
rt_name_m: str = pool.alloc(512)
|
||||
rt_name_m: str = pool.alloc(4096)
|
||||
if rt_name_m is not None:
|
||||
mlirlite.TypePrint(rt_name_m, 512, ret_ty, pool)
|
||||
mlirlite.TypePrint(rt_name_m, 4096, ret_ty, pool)
|
||||
if rt_name_m[0] == '\0': rt_name_m = "?"
|
||||
err_fn_m: str = pool.alloc(256)
|
||||
if err_fn_m is not None:
|
||||
|
||||
@@ -412,9 +412,9 @@ novirtual class ExprGenBase:
|
||||
def _type_text(self, pool: memhub.MemBuddy*, ty: mlirlite.LLVMType*) -> str:
|
||||
"""Readable LLVM type text via TypePrint; "?" on failure."""
|
||||
if ty is None: return "?"
|
||||
buf: str = pool.alloc(512)
|
||||
buf: str = pool.alloc(4096)
|
||||
if buf is None: return "?"
|
||||
mlirlite.TypePrint(buf, 512, ty, pool)
|
||||
mlirlite.TypePrint(buf, 4096, ty, pool)
|
||||
if buf[0] == 0: return "?"
|
||||
return buf
|
||||
# _ptr_cast_reason_text - human-readable text for a forbidden ptr -> ptr cast.
|
||||
|
||||
@@ -260,7 +260,7 @@ novirtual class ExprGenCdef(ExprGenBase.ExprGenBase):
|
||||
if src_path is None:
|
||||
# SHA1 absent from the store = compiler bug (Phase1/Phase2 not populated):
|
||||
# report and abort instead of silently returning -1 (avoids bad @UNDEFINED refs).
|
||||
err_buf: str = pool.alloc(512)
|
||||
err_buf: str = pool.alloc(4096)
|
||||
if err_buf is not None:
|
||||
viperlib.snprintf(err_buf, 512, "cross-module CDefine lookup failed: SHA1 %s is not in the store (base_mod=%s name=%s). " "Phase1/Phase2 did not correctly populate PopulateSha1MapStore/AppendToSha1MapStore", sha1, base_mod, name)
|
||||
VLogger.error(err_buf, "XMOD-CD")
|
||||
|
||||
@@ -497,11 +497,11 @@ novirtual class ExprGenOps(ExprGenBase.ExprGenBase):
|
||||
rhs_is_ptr_now: int = self.is_ptr_type(rhs.Ty)
|
||||
if lhs_is_ptr_now != 0 and rhs_is_ptr_now != 0:
|
||||
# Both are pointers; compare type strings via TypePrint
|
||||
lhs_ty_buf: str = pool.alloc(512)
|
||||
rhs_ty_buf: str = pool.alloc(512)
|
||||
lhs_ty_buf: str = pool.alloc(4096)
|
||||
rhs_ty_buf: str = pool.alloc(4096)
|
||||
if lhs_ty_buf is not None and rhs_ty_buf is not None:
|
||||
mlirlite.TypePrint(lhs_ty_buf, 512, lhs.Ty, pool)
|
||||
mlirlite.TypePrint(rhs_ty_buf, 512, rhs.Ty, pool)
|
||||
mlirlite.TypePrint(lhs_ty_buf, 4096, lhs.Ty, pool)
|
||||
mlirlite.TypePrint(rhs_ty_buf, 4096, rhs.Ty, pool)
|
||||
if string.strcmp(lhs_ty_buf, rhs_ty_buf) != 0: rhs = mlirlite.build_bitcast(builder, rhs, lhs.Ty)
|
||||
|
||||
# Float comparison: use fcmp instead of icmp when either operand is floating point
|
||||
@@ -1056,16 +1056,16 @@ novirtual class ExprGenOps(ExprGenBase.ExprGenBase):
|
||||
# Augmented assignment: build the "+=" form with an f-string (this language's str has no `+` concatenation).
|
||||
op_lbl = f"{op_ch}="
|
||||
aug_note = "(augmented assignment)"
|
||||
lty_buf: str = pool.alloc(512)
|
||||
rty_buf: str = pool.alloc(512)
|
||||
lty_buf: str = pool.alloc(4096)
|
||||
rty_buf: str = pool.alloc(4096)
|
||||
lty_lbl: str = "?"
|
||||
rty_lbl: str = "?"
|
||||
if lty_buf is not None:
|
||||
mlirlite.TypePrint(lty_buf, 512, lhs.Ty, pool)
|
||||
mlirlite.TypePrint(lty_buf, 4096, lhs.Ty, pool)
|
||||
lty_lbl = lty_buf
|
||||
if string.strcmp(lty_buf, "i8*") == 0: lty_lbl = "str(i8*)"
|
||||
if rty_buf is not None:
|
||||
mlirlite.TypePrint(rty_buf, 512, rhs.Ty, pool)
|
||||
mlirlite.TypePrint(rty_buf, 4096, rhs.Ty, pool)
|
||||
rty_lbl = rty_buf
|
||||
if string.strcmp(rty_buf, "i8*") == 0: rty_lbl = "str(i8*)"
|
||||
col_s: int = 0
|
||||
|
||||
@@ -789,9 +789,9 @@ novirtual class FuncGenDef(CallGenBase.CallGenBase):
|
||||
if ret_ty is not None:
|
||||
# mlirlite has no type_get_name API; serialize the type with the real interface
|
||||
# TypePrint(buf, size, ty, pool).
|
||||
rt_name: str = pool.alloc(512)
|
||||
rt_name: str = pool.alloc(4096)
|
||||
if rt_name is not None:
|
||||
mlirlite.TypePrint(rt_name, 512, ret_ty, pool)
|
||||
mlirlite.TypePrint(rt_name, 4096, ret_ty, pool)
|
||||
if rt_name[0] == '\0': rt_name = "?"
|
||||
err_fn: str = pool.alloc(256)
|
||||
if err_fn is not None:
|
||||
|
||||
@@ -182,9 +182,9 @@ novirtual class TranslatorGenMixin:
|
||||
pos_n: sizet = sizet(written_n)
|
||||
# Sub-array type prefix (e.g. "[16 x i8]"): nested initializers must spell out the
|
||||
# inner type, so serialize elem_ty via TypePrint for the [[16 x i8][...]] form.
|
||||
elem_ty_str_n: str = pool.alloc(512)
|
||||
elem_ty_str_n: str = pool.alloc(4096)
|
||||
if elem_ty_str_n is None: return None
|
||||
mlirlite.TypePrint(elem_ty_str_n, 512, elem_ty, pool)
|
||||
mlirlite.TypePrint(elem_ty_str_n, 4096, elem_ty, pool)
|
||||
for i_n in range(cnt_total_n):
|
||||
sub_n: str = None
|
||||
if i_n < elts_count:
|
||||
@@ -381,9 +381,9 @@ novirtual class TranslatorGenMixin:
|
||||
fe: GenTypes.FieldEntry* = self.Gen.StructGen._get_field_entry(se, i)
|
||||
i += 1
|
||||
if fe is None or fe.Ty is None: continue
|
||||
ty_str: str = pool.alloc(512)
|
||||
ty_str: str = pool.alloc(4096)
|
||||
if ty_str is None: continue
|
||||
mlirlite.TypePrint(ty_str, 512, fe.Ty, pool)
|
||||
mlirlite.TypePrint(ty_str, 4096, fe.Ty, pool)
|
||||
elem: str = self._default_val_const_text(pool, fe.Ty, ty_str, fe.DefaultVal)
|
||||
is_zero: int = 0
|
||||
if elem is None:
|
||||
@@ -784,9 +784,9 @@ novirtual class TranslatorGenMixin:
|
||||
for fi_v in range(1, fc_v):
|
||||
fe_v: GenTypes.FieldEntry* = self.Gen.StructGen._get_field_entry(resolved_stg_entry, fi_v)
|
||||
if fe_v is None or fe_v.Ty is None: continue
|
||||
ty_buf_v: str = pool.alloc(512)
|
||||
ty_buf_v: str = pool.alloc(4096)
|
||||
if ty_buf_v is None: continue
|
||||
mlirlite.TypePrint(ty_buf_v, 512, fe_v.Ty, pool)
|
||||
mlirlite.TypePrint(ty_buf_v, 4096, fe_v.Ty, pool)
|
||||
zero_v: str = self._stg_field_zero_text(pool, fe_v.Ty, ty_buf_v)
|
||||
if zero_v is None: continue
|
||||
written_v = viperlib.snprintf(init_full + pos_v, init_full_len - pos_v, ", %s", zero_v)
|
||||
|
||||
@@ -422,7 +422,7 @@ class TypeGenCType(TypeGenBase.TypeGenBase):
|
||||
# line parse buffer ("NAME\0VALUE\0"), reused per file (register_ctypedef copies).
|
||||
# 512 (not 320): _parse_typedef_line normalizes a C-style RHS (`const T` / `T*`) into
|
||||
# the longer canonical `|` union text, so the VALUE area must hold the expanded form.
|
||||
td_buf: str = pool.alloc(512)
|
||||
td_buf: str = pool.alloc(4096)
|
||||
for i in range(src_len + 1):
|
||||
if i == src_len or src[i] == '\n':
|
||||
line_len: sizet = i - line_start
|
||||
|
||||
@@ -557,10 +557,10 @@ novirtual class TypeGenResolve(TypeGenBase.TypeGenBase):
|
||||
# 4) Symbol-name truth: the struct's own IR name is "{module SHA1}.{Class}"
|
||||
# (same mangling as everywhere), so recover the SHA1 from the type name.
|
||||
if _def_sha1 is None and _bare_entry is not None and _bare_entry.Ty is not None:
|
||||
_tp_buf: str = pool.alloc(512)
|
||||
_tp_buf: str = pool.alloc(4096)
|
||||
if _tp_buf is not None:
|
||||
_tp_buf[0] = '\0'
|
||||
mlirlite.TypePrint(_tp_buf, 512, _bare_entry.Ty, pool)
|
||||
mlirlite.TypePrint(_tp_buf, 4096, _bare_entry.Ty, pool)
|
||||
_tp_nm: str = _tp_buf
|
||||
if _tp_nm[0] == '%' and _tp_nm[1] == '"': _tp_nm += 2
|
||||
_sp_l: sizet = sizet(self._is_sha1_prefixed(_tp_nm))
|
||||
@@ -607,10 +607,10 @@ novirtual class TypeGenResolve(TypeGenBase.TypeGenBase):
|
||||
if _bare_entry is not None: _w_ep = 1
|
||||
_w_ty: str = "None"
|
||||
if _bare_entry is not None and _bare_entry.Ty is not None:
|
||||
_w_buf: str = pool.alloc(512)
|
||||
_w_buf: str = pool.alloc(4096)
|
||||
if _w_buf is not None:
|
||||
_w_buf[0] = '\0'
|
||||
mlirlite.TypePrint(_w_buf, 512, _bare_entry.Ty, pool)
|
||||
mlirlite.TypePrint(_w_buf, 4096, _bare_entry.Ty, pool)
|
||||
if _w_buf[0] != '\0': _w_ty = _w_buf
|
||||
VLogger.error(f"[TypeArgOwnership] bare class name '{type_name}' keeps the bare name this time (may split from the prefixed form):" f"entry_present={_w_ep} entry.Ty={_w_ty} cur_def_mod={_w_mod} cur_def_cls={_w_cls} " f"is_module_class={_w_imc} find_struct_by_module={_w_fbm} " f"from_imports={_w_fi} file={_w_file}", "TypeGen")
|
||||
# ---- 6. not found: keep as-is (builtin type names etc.) ----
|
||||
|
||||
Reference in new issue
Block a user