96 lines
6.4 KiB
Python
96 lines
6.4 KiB
Python
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 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 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__") |