fix(viperc): 闭包变量取址返回闭包指针,并让方法/构造实参转换报错定位到具体实参
- ExprGenOps 取址:嵌套 def 提升出的闭包变量在父函数里是 i8** 槽,&f 原来返回槽地址(二级),传给 callback: t.CPtr 会因级数不符报 CastError(source level 2 -> target level 1);现按闭包名表判定,返回其值 i8*(一级),与“函数名即地址(同 C)”一致 - CallGenCall._call_method_on_ptr:实参逐个转换原来统一传 node=None,失败时只能退回函数定义行(只剩一帧);现按 arg_nodes 带上每个实参自身的 AST 节点(slot 0 是 self),报错可定位到具体实参表达式并显示完整两帧 - TypeGenErr:移除定位用的 [TEMP-DIAG] 临时打印
This commit is contained in:
1 parent
3c6041c97c
commit
a060e1d76e
3 files changed
+17
-10
No files matched your search
@@ -485,19 +485,27 @@ novirtual class CallGenCall(CallGenBase.CallGenBase):
|
||||
pc_node: mlirlite.Value* = head
|
||||
new_head_pc: mlirlite.Value* = head
|
||||
prev_pc: mlirlite.Value* = None
|
||||
pc_idx: int = 0
|
||||
while pc_node is not None:
|
||||
pc_next_save: mlirlite.Value* = pc_node.Next
|
||||
coerced_pc: mlirlite.Value* = pc_node
|
||||
# 每个实参带上**它自己的 AST 节点**(arg_nodes 与链上 slot 1.. 对应,slot 0 是
|
||||
# self):转换失败时报错才能定位到这个实参表达式(如 `&_on_submit`),而不是
|
||||
# 因 node=None 退回"函数定义行"、只剩一帧。
|
||||
pc_arg_node: ast.AST* = node
|
||||
if pc_idx >= 1 and arg_nodes is not None and (pc_idx - 1) < len(arg_nodes):
|
||||
pc_arg_node = arg_nodes.get(pc_idx - 1)
|
||||
if pc_param is not None:
|
||||
pty_pc: mlirlite.LLVMType* = mlirlite.param_get_ty(pc_param)
|
||||
if pty_pc is not None:
|
||||
c_pc: mlirlite.Value* = self.Gen.ExprGenBase.coerce_to_type(builder, pc_node, pty_pc, None)
|
||||
c_pc: mlirlite.Value* = self.Gen.ExprGenBase.coerce_to_type(builder, pc_node, pty_pc, pc_arg_node)
|
||||
if c_pc is not None: coerced_pc = c_pc
|
||||
pc_param = mlirlite.param_get_next(pc_param)
|
||||
coerced_pc.Next = None
|
||||
if prev_pc is None: new_head_pc = coerced_pc
|
||||
else: prev_pc.Next = coerced_pc
|
||||
prev_pc = coerced_pc
|
||||
pc_idx += 1
|
||||
pc_node = pc_next_save
|
||||
head = new_head_pc
|
||||
|
||||
|
||||
@@ -755,6 +755,14 @@ novirtual class ExprGenOps(ExprGenBase.ExprGenBase):
|
||||
gv_ao: mlirlite.GlobalVariable* = self.Gen.ExprGenAttr.find_global_in_module(mod, nm_ao.id)
|
||||
if gv_ao is not None and gv_ao.Name is not None and gv_ao.Ty is not None: v_ao = self.Gen.ExprGenAttr.make_global_ref(pool, gv_ao.Name, gv_ao.Ty)
|
||||
if v_ao is not None and v_ao.Ty is not None:
|
||||
# 闭包变量(嵌套 `def f()` 被提升后在父函数里是一个 **i8\*\*** 槽,见
|
||||
# FuncGenMixin.translate_nested_function_def 第 13e 步):变量自身就是那个
|
||||
# 函数的闭包指针,`&f` 应给出它的**值**(一级 i8*),而不是槽地址 i8**(二级)
|
||||
# ——否则传给 `callback: t.CPtr` 会因级数不符报 CastError(source level 2 ->
|
||||
# target level 1)。与“函数名即地址(同 C)”一致。闭包槽与普通函数指针变量
|
||||
# 同为 i8**、类型上无法区分,故用闭包名表判定(第 13e 步已登记该名字)。
|
||||
if self.Gen.CallGenLeafKit.is_closure_name(nm_ao.id) != 0 and v_ao.Ty.Pointee is not None:
|
||||
return mlirlite.build_load(builder, v_ao.Ty.Pointee, v_ao)
|
||||
# Object-pointer variable (alloca is Ptr(Ptr(Struct))): the variable is the object, return the object pointer (load once), aligned with translate_c_addr.
|
||||
match v_ao.Ty:
|
||||
case mlirlite.LLVMType.Ptr(ao1):
|
||||
|
||||
@@ -47,7 +47,6 @@ novirtual class TypeGenErr(TypeGenBase.TypeGenBase):
|
||||
# 当前帧(错误点)位置:优先 node,其次调用栈最内层有行号的帧,最后 current_file。
|
||||
lineno: int = 0
|
||||
if node is not None: lineno = node.lineno
|
||||
raw_line: int = lineno # [TEMP-DIAG] 兜底前的原始节点行号(定位完删除)
|
||||
file_name: str = self.Gen.TypeGenResolve.get_current_file()
|
||||
if file_name is None: file_name = "<unknown>"
|
||||
# 报错位置兜底(“节点位置不可信”时优先用正在翻译的实参位置,精确定位到
|
||||
@@ -85,14 +84,6 @@ novirtual class TypeGenErr(TypeGenBase.TypeGenBase):
|
||||
Diag.finish()
|
||||
return 0
|
||||
|
||||
# [TEMP-DIAG] 定位“报错位置”问题用(定位完删除):把决策输入打出来
|
||||
# node=节点原始行号(0=合成) curarg=当前实参行号 trace=栈深 top=栈最内层行号
|
||||
ti_top: int = -1
|
||||
if self.Gen.TypeGenBase.TraceCount > 0:
|
||||
tf_d: GenTypes.TraceFrame* = self.Gen.TypeGenBase._get_trace_frame(self.Gen.TypeGenBase.TraceCount - 1)
|
||||
if tf_d is not None: ti_top = tf_d.lineno
|
||||
stdio.printf("[TEMP-DIAG] node=%d curarg=%d trace=%d top=%d -> shown=%d\n",
|
||||
raw_line, self.Gen.TypeGenBase.CurArgLine, self.Gen.TypeGenBase.TraceCount, ti_top, lineno)
|
||||
Diag.begin(ent, err_type, msg)
|
||||
# 调用链帧(按"自外向内"顺序)**由本类遍历**(只有它拿得到 TraceFrame),填入 entry。
|
||||
for i in range(int(self.Gen.TypeGenBase.TraceCount)):
|
||||
|
||||
Reference in new issue
Block a user