from __future__ import annotations from typing import TYPE_CHECKING if TYPE_CHECKING: from lib.core.translator import Translator from lib.core.Handles.HandlesBase import BaseHandle, FuncMeta import ast import llvmlite.ir as ir class DeleteHandle(BaseHandle): def _HandleDeleteLlvm(self, Node): Gen = self.Trans.LlvmGen for target in Node.targets: if isinstance(target, ast.Subscript): ClassName = self.Trans.ExprHandler._get_var_class(target.value, Gen) if ClassName and Gen._has_function(f'{ClassName}.__delitem__'): obj_val = self.Trans.ExprHandler.HandleExprLlvm(target.value) idx_val = self.Trans.ExprHandler.HandleExprLlvm(target.slice) if obj_val and idx_val: if isinstance(obj_val.type, ir.PointerType) and isinstance(obj_val.type.pointee, ir.IntType) and obj_val.type.pointee.width == 8: obj_val = Gen.builder.bitcast(obj_val, ir.PointerType(Gen.structs[ClassName]), name=f"cast_{ClassName}") Gen.builder.call(Gen._get_function(f'{ClassName}.__delitem__'), [obj_val, idx_val], name=f"call_{ClassName}.__delitem__") elif isinstance(target, ast.Name): ClassName = Gen.var_struct_class.get(target.id) if ClassName and Gen._has_function(f'{ClassName}.__delete__'): obj_val = self.Trans.ExprHandler.HandleExprLlvm(target) if obj_val: if isinstance(obj_val.type, ir.PointerType) and isinstance(obj_val.type.pointee, ir.IntType) and obj_val.type.pointee.width == 8: obj_val = Gen.builder.bitcast(obj_val, ir.PointerType(Gen.structs[ClassName]), name=f"cast_{ClassName}") Gen.builder.call(Gen._get_function(f'{ClassName}.__delete__'), [obj_val], name=f"call_{ClassName}.__delete__") elif isinstance(target, ast.Attribute): # 检查 property deleter AttrName = target.attr ClassName = None obj_val_for_prop = None if isinstance(target.value, ast.Name) and target.value.id == 'self': # del self.attr — 检查当前类的 property deleter ClassName = self.Trans._CurrentCpythonObjectClass if ClassName: PropKey = f'{ClassName}.{AttrName}' PropInfo = self.Trans.SymbolTable.get(PropKey) if PropInfo and hasattr(PropInfo, 'MetaList') and FuncMeta.PROPERTY_DELETER in PropInfo.MetaList: SelfVar = Gen._get_var_ptr('self') if SelfVar: SelfPtr = Gen._load(SelfVar, name="self") DeleterFunc = Gen._get_function(PropKey + '$del') if DeleterFunc and SelfPtr: Gen.builder.call(DeleterFunc, [SelfPtr], name=f"prop_del_{PropKey}") continue else: # del obj.attr — 检查 obj 类的 property deleter ClassName = self.Trans.ExprHandler._get_var_class(target.value, Gen) if ClassName: PropKey = f'{ClassName}.{AttrName}' PropInfo = self.Trans.SymbolTable.get(PropKey) if PropInfo and hasattr(PropInfo, 'MetaList') and FuncMeta.PROPERTY_DELETER in PropInfo.MetaList: obj_val = self.Trans.ExprHandler.HandleExprLlvm(target.value) if obj_val: DeleterFunc = Gen._get_function(PropKey + '$del') if DeleterFunc: Gen.builder.call(DeleterFunc, [obj_val], name=f"prop_del_{PropKey}") continue # 原有的 __del__ 处理逻辑 obj_val = self.Trans.ExprHandler.HandleExprLlvm(target) if obj_val: if isinstance(obj_val.type, ir.PointerType) and isinstance(obj_val.type.pointee, ir.PointerType): obj_val = Gen._load(obj_val, name="Load_del_ptr") ClassName = None if isinstance(obj_val.type, ir.PointerType) and isinstance(obj_val.type.pointee, (ir.LiteralStructType, ir.IdentifiedStructType)): for CN, ST in Gen.structs.items(): if obj_val.type.pointee == ST: ClassName = CN break elif isinstance(obj_val.type, ir.PointerType) and isinstance(obj_val.type.pointee, ir.IntType) and obj_val.type.pointee.width == 8: if isinstance(target.value, ast.Name) and target.value.id == 'self': AttrName = target.attr SelfClassName = self.Trans._CurrentCpythonObjectClass if SelfClassName and SelfClassName in Gen.class_members: for member_name, member_type in Gen.class_members[SelfClassName]: if member_name == AttrName: for CN in Gen.structs: if CN == AttrName or Gen._has_function(f'{CN}.__del__'): ClassName = CN break break if not ClassName: for CN, ST in Gen.structs.items(): if Gen._has_function(f'{CN}.__del__'): ClassName = CN break if ClassName and Gen._has_function(f'{ClassName}.__del__'): if isinstance(obj_val.type, ir.PointerType) and isinstance(obj_val.type.pointee, ir.IntType) and obj_val.type.pointee.width == 8: obj_val = Gen.builder.bitcast(obj_val, ir.PointerType(Gen.structs[ClassName]), name=f"cast_{ClassName}") Gen.builder.call(Gen._get_function(f'{ClassName}.__del__'), [obj_val], name=f"call_{ClassName}.__del__")