修正了一些错误
This commit is contained in:
@@ -6,6 +6,7 @@ import memhub
|
||||
import string
|
||||
import stdio
|
||||
import viperlib
|
||||
import lib.core.VLogger as VLogger
|
||||
import lib.core.Handles.HandlesBase as HandlesBase
|
||||
import lib.core.Handles.HandlesTranslator as HT
|
||||
import lib.core.Handles.HandlesVar as HandlesVar
|
||||
@@ -44,12 +45,12 @@ class AssignHandle(HandlesBase.Mixin):
|
||||
def Handle(self, node: ast.AST | t.CPtr) -> int:
|
||||
asgn: ast.Assign | t.CPtr = (ast.Assign | t.CPtr)(node)
|
||||
if asgn is None:
|
||||
stdio.printf("[ASGN] cast failed\n")
|
||||
VLogger.error("cast failed", "ASGN")
|
||||
return 0
|
||||
|
||||
targets: list[ast.AST | t.CPtr] | t.CPtr = asgn.targets
|
||||
if targets is None:
|
||||
stdio.printf("[ASGN] targets is None\n")
|
||||
VLogger.error("targets is None", "ASGN")
|
||||
return 0
|
||||
|
||||
# 从 self.Trans 取共享状态(替代 11 个参数)
|
||||
@@ -61,7 +62,23 @@ class AssignHandle(HandlesBase.Mixin):
|
||||
rhs_val: llvmlite.Value | t.CPtr = HandlesExpr.translate_value(
|
||||
builder, pool, mod, asgn.value, None, 0, self.Trans)
|
||||
if rhs_val is None:
|
||||
stdio.printf("[ASGN] rhs_val is None\n")
|
||||
# 增强错误信息:包含 sha1 + lineno + AST 节点类型,便于定位
|
||||
fb: t.CChar | t.CPtr = VLogger.fmt_buf()
|
||||
if fb is not None and asgn.value is not None:
|
||||
sha1: str = self.Trans.ModuleSha1
|
||||
val_kind: int = asgn.value.kind()
|
||||
val_line: t.CInt = asgn.value.lineno
|
||||
if sha1 is not None:
|
||||
viperlib.snprintf(fb, 1024,
|
||||
"rhs_val is None [sha1=%s lineno=%d kind=%d]",
|
||||
sha1, val_line, val_kind)
|
||||
else:
|
||||
viperlib.snprintf(fb, 1024,
|
||||
"rhs_val is None [lineno=%d kind=%d]",
|
||||
val_line, val_kind)
|
||||
VLogger.error(fb, "ASGN")
|
||||
else:
|
||||
VLogger.error("rhs_val is None", "ASGN")
|
||||
return 0
|
||||
|
||||
new_vars: int = 0
|
||||
@@ -116,23 +133,115 @@ class AssignHandle(HandlesBase.Mixin):
|
||||
sub_pointee: llvmlite.LLVMType | t.CPtr = sub_alloca.Ty.Pointee
|
||||
if sub_pointee is not None:
|
||||
cls_nm_set: str = HandlesStruct.get_class_name_by_type(pool, sub_pointee)
|
||||
if cls_nm_set is not None:
|
||||
obj_val_set: llvmlite.Value | t.CPtr = llvmlite.build_load(
|
||||
builder, sub_pointee, sub_alloca)
|
||||
if obj_val_set is not None:
|
||||
key_val_set: llvmlite.Value | t.CPtr = HandlesExpr.translate_value(
|
||||
builder, pool, mod, sub_asgn.slice, None, 0, self.Trans)
|
||||
if key_val_set is not None:
|
||||
arg_vals_set: t.CSizeT | t.CPtr = pool.alloc(16)
|
||||
if arg_vals_set is not None:
|
||||
arg_vals_set[0] = t.CSizeT(key_val_set)
|
||||
arg_vals_set[1] = t.CSizeT(rhs_val)
|
||||
HandlesExprCall._call_method_on_ptr(
|
||||
pool, builder, mod, cls_nm_set, "__setitem__",
|
||||
obj_val_set, arg_vals_set, 2, self.Trans)
|
||||
setitem_done = 1
|
||||
obj_val_set: llvmlite.Value | t.CPtr = llvmlite.build_load(
|
||||
builder, sub_pointee, sub_alloca)
|
||||
# 指针类型变量 (X|t.CPtr): sub_pointee 是 Ptr(Struct),
|
||||
# 需 load 获取 Ptr(Struct) 再检查 inner struct
|
||||
if cls_nm_set is None and obj_val_set is not None:
|
||||
if HandlesExpr.is_ptr_type(sub_pointee) != 0:
|
||||
inner_ty_set: llvmlite.LLVMType | t.CPtr = sub_pointee.Pointee
|
||||
if inner_ty_set is not None:
|
||||
cls_nm_set = HandlesStruct.get_class_name_by_type(pool, inner_ty_set)
|
||||
if cls_nm_set is not None and obj_val_set is not None:
|
||||
key_val_set: llvmlite.Value | t.CPtr = HandlesExpr.translate_value(
|
||||
builder, pool, mod, sub_asgn.slice, None, 0, self.Trans)
|
||||
if key_val_set is not None:
|
||||
arg_vals_set: t.CSizeT | t.CPtr = pool.alloc(16)
|
||||
if arg_vals_set is not None:
|
||||
arg_vals_set[0] = t.CSizeT(key_val_set)
|
||||
arg_vals_set[1] = t.CSizeT(rhs_val)
|
||||
HandlesExprCall._call_method_on_ptr(
|
||||
pool, builder, mod, cls_nm_set, "__setitem__",
|
||||
obj_val_set, arg_vals_set, 2, self.Trans)
|
||||
setitem_done = 1
|
||||
elif sub_asgn.value.kind() == ast.ASTKind.Attribute:
|
||||
# self._ht[key] = val → self._ht.__setitem__(key, val)
|
||||
# 通过 get_attribute_ptr 获取字段指针,再调用 __setitem__
|
||||
field_ptr_set: llvmlite.Value | t.CPtr = HandlesExpr.get_attribute_ptr(
|
||||
builder, pool, mod, sub_asgn.value, self.Trans)
|
||||
if field_ptr_set is not None and field_ptr_set.Ty is not None:
|
||||
if HandlesExpr.is_ptr_type(field_ptr_set.Ty) != 0:
|
||||
field_pointee_set: llvmlite.LLVMType | t.CPtr = field_ptr_set.Ty.Pointee
|
||||
if field_pointee_set is not None:
|
||||
cls_nm_attr: str = HandlesStruct.get_class_name_by_type(pool, field_pointee_set)
|
||||
obj_val_attr: llvmlite.Value | t.CPtr = field_ptr_set
|
||||
# field_ptr 是 Ptr(Ptr(Struct)) (X|t.CPtr 字段):
|
||||
# load 解引用获取 Ptr(Struct)
|
||||
if cls_nm_attr is None and HandlesExpr.is_ptr_type(field_pointee_set) != 0:
|
||||
inner_struct_attr: llvmlite.LLVMType | t.CPtr = field_pointee_set.Pointee
|
||||
if inner_struct_attr is not None:
|
||||
cls_nm_attr = HandlesStruct.get_class_name_by_type(pool, inner_struct_attr)
|
||||
if cls_nm_attr is not None:
|
||||
obj_val_attr = llvmlite.build_load(
|
||||
builder, field_pointee_set, field_ptr_set)
|
||||
if cls_nm_attr is not None and obj_val_attr is not None:
|
||||
key_val_attr: llvmlite.Value | t.CPtr = HandlesExpr.translate_value(
|
||||
builder, pool, mod, sub_asgn.slice, None, 0, self.Trans)
|
||||
if key_val_attr is not None:
|
||||
arg_vals_attr: t.CSizeT | t.CPtr = pool.alloc(16)
|
||||
if arg_vals_attr is not None:
|
||||
arg_vals_attr[0] = t.CSizeT(key_val_attr)
|
||||
arg_vals_attr[1] = t.CSizeT(rhs_val)
|
||||
HandlesExprCall._call_method_on_ptr(
|
||||
pool, builder, mod, cls_nm_attr, "__setitem__",
|
||||
obj_val_attr, arg_vals_attr, 2, self.Trans)
|
||||
setitem_done = 1
|
||||
if setitem_done == 0:
|
||||
HandlesType.fatal_error(target, "subscript ptr is None")
|
||||
# 通用 fallback: 翻译 sub.value 并尝试 __setitem__ 或直接 GEP+store
|
||||
# 处理 Name/Attribute 之外的节点以及 SymTab 查找失败的情况
|
||||
if sub_asgn is not None and sub_asgn.value is not None:
|
||||
obj_val_gen: llvmlite.Value | t.CPtr = HandlesExpr.translate_value(
|
||||
builder, pool, mod, sub_asgn.value, None, 0, self.Trans)
|
||||
key_val_gen: llvmlite.Value | t.CPtr = HandlesExpr.translate_value(
|
||||
builder, pool, mod, sub_asgn.slice, None, 0, self.Trans)
|
||||
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 = HandlesStruct.get_class_name_by_type(
|
||||
pool, obj_val_gen.Ty)
|
||||
if cls_nm_gen is None and HandlesExpr.is_ptr_type(obj_val_gen.Ty) != 0:
|
||||
inner_gen: llvmlite.LLVMType | t.CPtr = obj_val_gen.Ty.Pointee
|
||||
if inner_gen is not None:
|
||||
cls_nm_gen = HandlesStruct.get_class_name_by_type(pool, inner_gen)
|
||||
if cls_nm_gen is not None:
|
||||
# 自定义结构体: 调用 __setitem__
|
||||
arg_vals_gen: t.CSizeT | t.CPtr = pool.alloc(16)
|
||||
if arg_vals_gen is not None:
|
||||
arg_vals_gen[0] = t.CSizeT(key_val_gen)
|
||||
arg_vals_gen[1] = t.CSizeT(rhs_val)
|
||||
HandlesExprCall._call_method_on_ptr(
|
||||
pool, builder, mod, cls_nm_gen, "__setitem__",
|
||||
obj_val_gen, arg_vals_gen, 2, self.Trans)
|
||||
setitem_done = 1
|
||||
else:
|
||||
# 非自定义结构体: 直接 GEP + store
|
||||
# 处理 get_subscript_ptr 因边界情况返回 None 的指针下标
|
||||
if HandlesExpr.is_ptr_type(obj_val_gen.Ty) != 0:
|
||||
elem_gen: llvmlite.LLVMType | t.CPtr = obj_val_gen.Ty.Pointee
|
||||
if elem_gen is not None:
|
||||
store_val_gen: llvmlite.Value | t.CPtr = rhs_val
|
||||
elem_ptr_gen: llvmlite.Value | t.CPtr = None
|
||||
match elem_gen:
|
||||
case llvmlite.LLVMType.Array(arr_elem_gen, _):
|
||||
elem_ptr_gen = llvmlite.build_gep_array(
|
||||
builder, elem_gen, arr_elem_gen,
|
||||
obj_val_gen, key_val_gen)
|
||||
case _:
|
||||
elem_ptr_gen = llvmlite.build_gep(
|
||||
builder, elem_gen, obj_val_gen, key_val_gen)
|
||||
if elem_ptr_gen is not None and elem_ptr_gen.Ty is not None:
|
||||
pt_gen: llvmlite.LLVMType | t.CPtr = elem_ptr_gen.Ty.Pointee
|
||||
if pt_gen is not None:
|
||||
store_val_gen = HandlesExpr.coerce_to_type(
|
||||
builder, rhs_val, pt_gen)
|
||||
llvmlite.build_store(builder, store_val_gen, elem_ptr_gen)
|
||||
setitem_done = 1
|
||||
if setitem_done == 0:
|
||||
sub_vk: int = sub_asgn.value.kind()
|
||||
stdio.printf("[ASGN-SUB] fallback failed: val_kind=%d\n", sub_vk)
|
||||
stdio.fflush(0)
|
||||
if setitem_done == 0:
|
||||
HandlesType.fatal_error(target, "subscript ptr is None")
|
||||
continue
|
||||
|
||||
# Attribute 赋值: obj.field = val
|
||||
@@ -140,14 +249,25 @@ class AssignHandle(HandlesBase.Mixin):
|
||||
field_ptr: llvmlite.Value | t.CPtr = HandlesExpr.get_attribute_ptr(
|
||||
builder, pool, mod, target, self.Trans)
|
||||
if field_ptr is not None:
|
||||
stdio.printf("[ASGN-ATTR] field_ptr ok ty_not_null=%d\n",
|
||||
1 if field_ptr.Ty is not None else 0)
|
||||
stdio.fflush(0)
|
||||
# 获取字段类型,对 rhs_val 进行类型转换(如 i32 → i64)
|
||||
store_val: llvmlite.Value | t.CPtr = rhs_val
|
||||
if field_ptr.Ty is not None:
|
||||
field_ty: llvmlite.LLVMType | t.CPtr = field_ptr.Ty.Pointee
|
||||
if field_ty is not None:
|
||||
stdio.printf("[ASGN-ATTR] coerce rhs_ty=%d field_ty=%d\n",
|
||||
HandlesExpr.get_llvm_type_bits(rhs_val.Ty),
|
||||
HandlesExpr.get_llvm_type_bits(field_ty))
|
||||
stdio.fflush(0)
|
||||
store_val = HandlesExpr.coerce_to_type(
|
||||
builder, rhs_val, field_ty)
|
||||
stdio.printf("[ASGN-ATTR] pre_store\n")
|
||||
stdio.fflush(0)
|
||||
llvmlite.build_store(builder, store_val, field_ptr)
|
||||
stdio.printf("[ASGN-ATTR] post_store\n")
|
||||
stdio.fflush(0)
|
||||
else:
|
||||
# 构造详细错误信息
|
||||
attr_node: ast.Attribute | t.CPtr = (ast.Attribute | t.CPtr)(target)
|
||||
@@ -213,7 +333,10 @@ class AssignHandle(HandlesBase.Mixin):
|
||||
if existing is None:
|
||||
new_vars += 1
|
||||
else:
|
||||
stdio.printf("[ASGN] alloca failed for %s\n", nm.id)
|
||||
fb: t.CChar | t.CPtr = VLogger.fmt_buf()
|
||||
if fb is not None:
|
||||
viperlib.snprintf(fb, 1024, "alloca failed for %s", nm.id)
|
||||
VLogger.error(fb, "ASGN")
|
||||
|
||||
return new_vars
|
||||
|
||||
|
||||
Reference in New Issue
Block a user