修正了一些错误

This commit is contained in:
2026-07-26 20:32:26 +08:00
parent ca7c2120b8
commit 1837339f69
203 changed files with 374300 additions and 2638 deletions

View File

@@ -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