修复了 TPV 的一些错误,包括闭包等
This commit is contained in:
102
App/lib/core/Handles/HandlesDelete.py
Normal file
102
App/lib/core/Handles/HandlesDelete.py
Normal file
@@ -0,0 +1,102 @@
|
||||
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: ast.Delete) -> None:
|
||||
Gen: "Translator.LlvmGen" = self.Trans.LlvmGen
|
||||
for target in Node.targets:
|
||||
if isinstance(target, ast.Subscript):
|
||||
ClassName: str | None = self.Trans.ExprHandler._get_var_class(target.value, Gen)
|
||||
if ClassName and Gen._has_function(f'{ClassName}.__delitem__'):
|
||||
obj_val: ir.Value | None = self.Trans.ExprHandler.HandleExprLlvm(target.value)
|
||||
idx_val: ir.Value | None = self.Trans.ExprHandler.HandleExprLlvm(target.slice)
|
||||
if obj_val and idx_val:
|
||||
# 处理 obj_val 为 i8(整数)的情况:联合类型 | t.CPtr 降级后可能被 load 为 i8
|
||||
if isinstance(obj_val.type, ir.IntType) and obj_val.type.width == 8:
|
||||
obj_val = Gen.builder.inttoptr(obj_val, ir.PointerType(ir.IntType(8)), name=f"i8_to_ptr_{ClassName}")
|
||||
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: str | None = Gen.var_struct_class.get(target.id)
|
||||
if ClassName and Gen._has_function(f'{ClassName}.__delete__'):
|
||||
obj_val: ir.Value | None = self.Trans.ExprHandler.HandleExprLlvm(target)
|
||||
if obj_val:
|
||||
# 处理 obj_val 为 i8(整数)的情况:联合类型 | t.CPtr 降级后可能被 load 为 i8
|
||||
if isinstance(obj_val.type, ir.IntType) and obj_val.type.width == 8:
|
||||
obj_val = Gen.builder.inttoptr(obj_val, ir.PointerType(ir.IntType(8)), name=f"i8_to_ptr_{ClassName}")
|
||||
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: str = target.attr
|
||||
ClassName: str | None = None
|
||||
obj_val_for_prop: ir.Value | None = None
|
||||
|
||||
if isinstance(target.value, ast.Name) and target.value.id == 'self':
|
||||
# del self.attr — 检查当前类的 property deleter
|
||||
ClassName = self.Trans._CurrentCpythonObjectClass
|
||||
if ClassName:
|
||||
PropKey: str = f'{ClassName}.{AttrName}'
|
||||
PropInfo: "SymbolTable.SymbolInfo | None" = self.Trans.SymbolTable.lookup(PropKey)
|
||||
if PropInfo and PropInfo.MetaList and FuncMeta.PROPERTY_DELETER in PropInfo.MetaList:
|
||||
SelfVar: ir.Value | None = Gen._get_var_ptr('self')
|
||||
if SelfVar:
|
||||
SelfPtr: ir.Value = Gen._load(SelfVar, name="self")
|
||||
DeleterFunc: ir.Function | None = 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: str = f'{ClassName}.{AttrName}'
|
||||
PropInfo: "SymbolTable.SymbolInfo | None" = self.Trans.SymbolTable.lookup(PropKey)
|
||||
if PropInfo and PropInfo.MetaList and FuncMeta.PROPERTY_DELETER in PropInfo.MetaList:
|
||||
obj_val: ir.Value | None = self.Trans.ExprHandler.HandleExprLlvm(target.value)
|
||||
if obj_val:
|
||||
DeleterFunc: ir.Function | None = Gen._get_function(PropKey + '$del')
|
||||
if DeleterFunc:
|
||||
Gen.builder.call(DeleterFunc, [obj_val], name=f"prop_del_{PropKey}")
|
||||
continue
|
||||
|
||||
# 原有的 __del__ 处理逻辑
|
||||
obj_val: ir.Value | None = 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: str | None = 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__")
|
||||
Reference in New Issue
Block a user