修复了大量存在的问题,增加了假鸭子类型等等机制
This commit is contained in:
@@ -106,20 +106,24 @@ v4 增强版特性:
|
||||
"""
|
||||
from __future__ import annotations
|
||||
import llvmlite.ir as ir
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from lib.core.LlvmCodeGenerator import LlvmCodeGenerator
|
||||
|
||||
|
||||
# 栈帧局部上下文缓冲区大小(字节)
|
||||
_CTX_SIZE = 32
|
||||
_CTX_SIZE: int = 32
|
||||
|
||||
# 装饰器处理函数的 LLVM 签名:i32 (i8*, i8*, i32, i8*, i8*, i8*)
|
||||
_DECOR_HANDLER_PARAM_TYPES = None # 延迟初始化
|
||||
_DECOR_HANDLER_PARAM_TYPES: ir.FunctionType | None = None # 延迟初始化
|
||||
|
||||
|
||||
def _get_decor_handler_func_type():
|
||||
def _get_decor_handler_func_type() -> ir.FunctionType:
|
||||
"""获取装饰器处理函数的 LLVM FunctionType: i32 (i8*, i8*, i32, i8*, i8*, i8*)"""
|
||||
global _DECOR_HANDLER_PARAM_TYPES
|
||||
if _DECOR_HANDLER_PARAM_TYPES is None:
|
||||
i8_ptr = ir.IntType(8).as_pointer()
|
||||
i8_ptr: ir.PointerType = ir.IntType(8).as_pointer()
|
||||
_DECOR_HANDLER_PARAM_TYPES = ir.FunctionType(
|
||||
ir.IntType(32),
|
||||
[i8_ptr, i8_ptr, ir.IntType(32), i8_ptr, i8_ptr, i8_ptr]
|
||||
@@ -127,27 +131,28 @@ def _get_decor_handler_func_type():
|
||||
return _DECOR_HANDLER_PARAM_TYPES
|
||||
|
||||
|
||||
def _find_or_declare_handler(module, handler_name):
|
||||
def _find_or_declare_handler(module: ir.Module, handler_name: str) -> ir.Function:
|
||||
"""在 module 中查找或声明装饰器处理函数"""
|
||||
f: ir.Function
|
||||
for f in module.functions:
|
||||
if f.name == handler_name:
|
||||
return f
|
||||
func_type = _get_decor_handler_func_type()
|
||||
handler = ir.Function(module, func_type, name=handler_name)
|
||||
func_type: ir.FunctionType = _get_decor_handler_func_type()
|
||||
handler: ir.Function = ir.Function(module, func_type, name=handler_name)
|
||||
return handler
|
||||
|
||||
|
||||
def _make_string_constant(module, text, name_prefix="decor.str"):
|
||||
def _make_string_constant(module: ir.Module, text: str, name_prefix: str = "decor.str") -> ir.Constant:
|
||||
"""在 module 中创建一个全局字符串常量,返回 i8* 指针"""
|
||||
counter = getattr(_make_string_constant, '_counter', 0) + 1
|
||||
counter: int = getattr(_make_string_constant, '_counter', 0) + 1
|
||||
_make_string_constant._counter = counter
|
||||
const_name = f"{name_prefix}.{counter}"
|
||||
const_name: str = f"{name_prefix}.{counter}"
|
||||
|
||||
encoded = text.encode('utf-8') + b'\x00'
|
||||
const_type = ir.ArrayType(ir.IntType(8), len(encoded))
|
||||
const_val = ir.Constant(const_type, bytearray(encoded))
|
||||
encoded: bytes = text.encode('utf-8') + b'\x00'
|
||||
const_type: ir.ArrayType = ir.ArrayType(ir.IntType(8), len(encoded))
|
||||
const_val: ir.Constant = ir.Constant(const_type, bytearray(encoded))
|
||||
|
||||
global_var = ir.GlobalVariable(module, const_type, name=const_name)
|
||||
global_var: ir.GlobalVariable = ir.GlobalVariable(module, const_type, name=const_name)
|
||||
global_var.global_constant = True
|
||||
global_var.linkage = 'private'
|
||||
global_var.initializer = const_val
|
||||
@@ -155,7 +160,7 @@ def _make_string_constant(module, text, name_prefix="decor.str"):
|
||||
return global_var.bitcast(ir.IntType(8).as_pointer())
|
||||
|
||||
|
||||
def _make_decor_args_constant(module, decorator_info):
|
||||
def _make_decor_args_constant(module: ir.Module, decorator_info: dict) -> ir.Constant:
|
||||
"""
|
||||
为带参数的装饰器生成全局常量结构体,返回 i8* 指针。
|
||||
无参数装饰器返回 null。
|
||||
@@ -166,37 +171,43 @@ def _make_decor_args_constant(module, decorator_info):
|
||||
- bool → i1
|
||||
- str → i8*(全局字符串常量)
|
||||
"""
|
||||
deco_args = decorator_info.get('args', [])
|
||||
deco_kwargs = decorator_info.get('kwargs', {})
|
||||
deco_args: list = decorator_info.get('args', [])
|
||||
deco_kwargs: dict = decorator_info.get('kwargs', {})
|
||||
|
||||
if not deco_args and not deco_kwargs:
|
||||
return ir.Constant(ir.IntType(8).as_pointer(), None)
|
||||
|
||||
field_types = []
|
||||
field_values = []
|
||||
field_types: list = []
|
||||
field_values: list = []
|
||||
|
||||
arg: int | str | float | bool
|
||||
for arg in deco_args:
|
||||
llvm_type: ir.Type | None
|
||||
llvm_val: ir.Constant | None
|
||||
llvm_type, llvm_val = _python_value_to_llvm(module, arg)
|
||||
if llvm_type is None:
|
||||
return ir.Constant(ir.IntType(8).as_pointer(), None)
|
||||
field_types.append(llvm_type)
|
||||
field_values.append(llvm_val)
|
||||
|
||||
kw: str
|
||||
for kw in sorted(deco_kwargs.keys()):
|
||||
llvm_type: ir.Type | None
|
||||
llvm_val: ir.Constant | None
|
||||
llvm_type, llvm_val = _python_value_to_llvm(module, deco_kwargs[kw])
|
||||
if llvm_type is None:
|
||||
return ir.Constant(ir.IntType(8).as_pointer(), None)
|
||||
field_types.append(llvm_type)
|
||||
field_values.append(llvm_val)
|
||||
|
||||
struct_type = ir.LiteralStructType(field_types)
|
||||
struct_const = ir.Constant(struct_type, field_values)
|
||||
struct_type: ir.LiteralStructType = ir.LiteralStructType(field_types)
|
||||
struct_const: ir.Constant = ir.Constant(struct_type, field_values)
|
||||
|
||||
counter = getattr(_make_decor_args_constant, '_counter', 0) + 1
|
||||
counter: int = getattr(_make_decor_args_constant, '_counter', 0) + 1
|
||||
_make_decor_args_constant._counter = counter
|
||||
global_name = f"__decor_args.{counter}"
|
||||
global_name: str = f"__decor_args.{counter}"
|
||||
|
||||
global_var = ir.GlobalVariable(module, struct_type, name=global_name)
|
||||
global_var: ir.GlobalVariable = ir.GlobalVariable(module, struct_type, name=global_name)
|
||||
global_var.global_constant = True
|
||||
global_var.linkage = 'private'
|
||||
global_var.initializer = struct_const
|
||||
@@ -204,7 +215,7 @@ def _make_decor_args_constant(module, decorator_info):
|
||||
return global_var.bitcast(ir.IntType(8).as_pointer())
|
||||
|
||||
|
||||
def _python_value_to_llvm(module, value):
|
||||
def _python_value_to_llvm(module: ir.Module, value: int | str | float | bool) -> tuple[ir.Type | None, ir.Constant | None]:
|
||||
"""将 Python 值转换为 (LLVM类型, LLVM常量) 元组。"""
|
||||
if isinstance(value, bool):
|
||||
return ir.IntType(1), ir.Constant(ir.IntType(1), int(value))
|
||||
@@ -222,7 +233,7 @@ def _python_value_to_llvm(module, value):
|
||||
return None, None
|
||||
|
||||
|
||||
def _ZeroConstant(llvm_type):
|
||||
def _ZeroConstant(llvm_type: ir.Type) -> ir.Constant | None:
|
||||
"""为给定 LLVM 类型创建零值常量"""
|
||||
if isinstance(llvm_type, ir.IntType):
|
||||
return ir.Constant(llvm_type, 0)
|
||||
@@ -231,7 +242,7 @@ def _ZeroConstant(llvm_type):
|
||||
elif isinstance(llvm_type, ir.PointerType):
|
||||
return ir.Constant(llvm_type, None)
|
||||
elif isinstance(llvm_type, ir.ArrayType):
|
||||
elem_zero = _ZeroConstant(llvm_type.element)
|
||||
elem_zero: ir.Constant | None = _ZeroConstant(llvm_type.element)
|
||||
if elem_zero is None:
|
||||
return None
|
||||
return ir.Constant(llvm_type, [elem_zero] * llvm_type.count)
|
||||
@@ -239,9 +250,9 @@ def _ZeroConstant(llvm_type):
|
||||
return None
|
||||
|
||||
|
||||
def _generate_single_wrapper(module, original_func, wrapper_name, func_name_str,
|
||||
decorator_info, is_export=False,
|
||||
is_outermost=False, true_original_func=None):
|
||||
def _generate_single_wrapper(module: ir.Module, original_func: ir.Function, wrapper_name: str, func_name_str: str,
|
||||
decorator_info: dict, is_export: bool = False,
|
||||
is_outermost: bool = False, true_original_func: ir.Function | None = None) -> ir.Function:
|
||||
"""
|
||||
为单个装饰器生成一层 wrapper 函数。
|
||||
|
||||
@@ -253,38 +264,39 @@ def _generate_single_wrapper(module, original_func, wrapper_name, func_name_str,
|
||||
loop.body → 从 args_struct 读回参数(支持修改),调用原函数
|
||||
post → 调用 handler 后置,清除递归标志,返回结果
|
||||
"""
|
||||
decor_name = decorator_info['name']
|
||||
handler = _find_or_declare_handler(module, decor_name)
|
||||
func_name_const = _make_string_constant(module, func_name_str, name_prefix="decor.fn")
|
||||
decor_name: str = decorator_info['name']
|
||||
handler: ir.Function = _find_or_declare_handler(module, decor_name)
|
||||
func_name_const: ir.Constant = _make_string_constant(module, func_name_str, name_prefix="decor.fn")
|
||||
|
||||
func_type = original_func.ftype
|
||||
return_type = func_type.return_type
|
||||
param_types = [p.type for p in original_func.args]
|
||||
is_void = isinstance(return_type, ir.VoidType)
|
||||
func_type: ir.FunctionType = original_func.ftype
|
||||
return_type: ir.Type = func_type.return_type
|
||||
param_types: list[ir.Type] = [p.type for p in original_func.args]
|
||||
is_void: bool = isinstance(return_type, ir.VoidType)
|
||||
|
||||
wrapper_type = ir.FunctionType(return_type, param_types)
|
||||
wrapper = ir.Function(module, wrapper_type, name=wrapper_name)
|
||||
wrapper_type: ir.FunctionType = ir.FunctionType(return_type, param_types)
|
||||
wrapper: ir.Function = ir.Function(module, wrapper_type, name=wrapper_name)
|
||||
|
||||
# 添加 alwaysinline 属性,优化器完全内联消除调用开销
|
||||
wrapper.attributes.add('alwaysinline')
|
||||
|
||||
i32 = ir.IntType(32)
|
||||
i8 = ir.IntType(8)
|
||||
i8_ptr = ir.IntType(8).as_pointer()
|
||||
phase_pre = ir.Constant(i32, 0)
|
||||
phase_post = ir.Constant(i32, 1)
|
||||
null_ptr = ir.Constant(i8_ptr, None)
|
||||
zero_i32 = ir.Constant(i32, 0)
|
||||
one_i32 = ir.Constant(i32, 1)
|
||||
one_i8 = ir.Constant(i8, 1)
|
||||
zero_i8 = ir.Constant(i8, 0)
|
||||
i32: ir.IntType = ir.IntType(32)
|
||||
i8: ir.IntType = ir.IntType(8)
|
||||
i8_ptr: ir.PointerType = ir.IntType(8).as_pointer()
|
||||
phase_pre: ir.Constant = ir.Constant(i32, 0)
|
||||
phase_post: ir.Constant = ir.Constant(i32, 1)
|
||||
null_ptr: ir.Constant = ir.Constant(i8_ptr, None)
|
||||
zero_i32: ir.Constant = ir.Constant(i32, 0)
|
||||
one_i32: ir.Constant = ir.Constant(i32, 1)
|
||||
one_i8: ir.Constant = ir.Constant(i8, 1)
|
||||
zero_i8: ir.Constant = ir.Constant(i8, 0)
|
||||
|
||||
# 递归保护:仅最外层 wrapper 生成
|
||||
rec_flag = None
|
||||
rec_flag: ir.GlobalVariable | None = None
|
||||
if is_outermost and true_original_func is not None:
|
||||
rec_flag_name = f"__decor_rec_{wrapper_name}"
|
||||
rec_flag_name: str = f"__decor_rec_{wrapper_name}"
|
||||
# 检查是否已存在
|
||||
rec_flag = None
|
||||
g: ir.GlobalValue
|
||||
for g in module.global_values:
|
||||
if g.name == rec_flag_name:
|
||||
rec_flag = g
|
||||
@@ -296,8 +308,10 @@ def _generate_single_wrapper(module, original_func, wrapper_name, func_name_str,
|
||||
rec_flag.initializer = zero_i8
|
||||
|
||||
# 创建基本块
|
||||
entry_block = wrapper.append_basic_block("entry")
|
||||
entry_block: ir.Block = wrapper.append_basic_block("entry")
|
||||
|
||||
recursive_call_block: ir.Block | None
|
||||
decorated_entry_block: ir.Block | None
|
||||
if rec_flag is not None:
|
||||
recursive_call_block = wrapper.append_basic_block("recursive_call")
|
||||
decorated_entry_block = wrapper.append_basic_block("decorated_entry")
|
||||
@@ -305,24 +319,25 @@ def _generate_single_wrapper(module, original_func, wrapper_name, func_name_str,
|
||||
recursive_call_block = None
|
||||
decorated_entry_block = None
|
||||
|
||||
loop_header_block = wrapper.append_basic_block("loop.header")
|
||||
loop_body_block = wrapper.append_basic_block("loop.body")
|
||||
post_block = wrapper.append_basic_block("post")
|
||||
loop_header_block: ir.Block = wrapper.append_basic_block("loop.header")
|
||||
loop_body_block: ir.Block = wrapper.append_basic_block("loop.body")
|
||||
post_block: ir.Block = wrapper.append_basic_block("post")
|
||||
|
||||
# ==== Entry block ====
|
||||
builder = ir.IRBuilder(entry_block)
|
||||
builder: ir.IRBuilder = ir.IRBuilder(entry_block)
|
||||
|
||||
loop_predecessor: ir.Block
|
||||
if rec_flag is not None:
|
||||
# 递归保护:检查标志位
|
||||
rec_val = builder.load(rec_flag, name="rec_val")
|
||||
is_recursive = builder.icmp_signed('!=', rec_val, zero_i8)
|
||||
rec_val: ir.LoadInstr = builder.load(rec_flag, name="rec_val")
|
||||
is_recursive: ir.ICMPInstr = builder.icmp_signed('!=', rec_val, zero_i8)
|
||||
builder.cbranch(is_recursive, recursive_call_block, decorated_entry_block)
|
||||
|
||||
# ==== Recursive call block ====
|
||||
builder = ir.IRBuilder(recursive_call_block)
|
||||
# 递归调用:直接调用真正的原函数,跳过所有装饰逻辑
|
||||
rec_call_args = [arg for arg in wrapper.args]
|
||||
rec_ret_val = builder.call(true_original_func, rec_call_args)
|
||||
rec_call_args: list[ir.Argument] = [arg for arg in wrapper.args]
|
||||
rec_ret_val: ir.CallInstr = builder.call(true_original_func, rec_call_args)
|
||||
if is_void:
|
||||
builder.ret_void()
|
||||
else:
|
||||
@@ -339,39 +354,42 @@ def _generate_single_wrapper(module, original_func, wrapper_name, func_name_str,
|
||||
loop_predecessor = entry_block
|
||||
|
||||
# 1. 分配栈帧局部上下文(每次调用独立,线程安全,递归安全)
|
||||
ctx_type = ir.ArrayType(ir.IntType(8), _CTX_SIZE)
|
||||
ctx_alloca = builder.alloca(ctx_type, name="ctx")
|
||||
ctx_ptr = builder.bitcast(ctx_alloca, i8_ptr)
|
||||
ctx_type: ir.ArrayType = ir.ArrayType(ir.IntType(8), _CTX_SIZE)
|
||||
ctx_alloca: ir.AllocaInstr = builder.alloca(ctx_type, name="ctx")
|
||||
ctx_ptr: ir.BitCastInstr = builder.bitcast(ctx_alloca, i8_ptr)
|
||||
|
||||
# 2. 打包函数参数到结构体(装饰器可通过 args_ptr 读写修改)
|
||||
args_alloca = None
|
||||
args_struct_type = None
|
||||
args_alloca: ir.AllocaInstr | None = None
|
||||
args_struct_type: ir.LiteralStructType | None = None
|
||||
if param_types:
|
||||
args_struct_type = ir.LiteralStructType(param_types)
|
||||
args_alloca = builder.alloca(args_struct_type, name="args")
|
||||
zero = ir.Constant(i32, 0)
|
||||
zero: ir.Constant = ir.Constant(i32, 0)
|
||||
i: int
|
||||
arg: ir.Argument
|
||||
for i, arg in enumerate(wrapper.args):
|
||||
field_idx = ir.Constant(i32, i)
|
||||
gep = builder.gep(args_alloca, [zero, field_idx], inbounds=True)
|
||||
field_idx: ir.Constant = ir.Constant(i32, i)
|
||||
gep: ir.GEPInstr = builder.gep(args_alloca, [zero, field_idx], inbounds=True)
|
||||
builder.store(arg, gep)
|
||||
args_ptr = builder.bitcast(args_alloca, i8_ptr)
|
||||
args_ptr: ir.BitCastInstr | ir.Constant = builder.bitcast(args_alloca, i8_ptr)
|
||||
else:
|
||||
args_ptr = null_ptr
|
||||
|
||||
# 3. 分配返回值存储(零初始化,确保跳过原函数时返回安全默认值)
|
||||
ret_alloca: ir.AllocaInstr | None
|
||||
if not is_void:
|
||||
ret_alloca = builder.alloca(return_type, name="ret")
|
||||
zero_val = _ZeroConstant(return_type)
|
||||
zero_val: ir.Constant | None = _ZeroConstant(return_type)
|
||||
if zero_val is not None:
|
||||
builder.store(zero_val, ret_alloca)
|
||||
else:
|
||||
ret_alloca = None
|
||||
|
||||
# 4. 获取装饰器参数指针
|
||||
decor_args_ptr = _make_decor_args_constant(module, decorator_info)
|
||||
decor_args_ptr: ir.Constant = _make_decor_args_constant(module, decorator_info)
|
||||
|
||||
# 5. 前置阶段:handler 返回调用次数
|
||||
n_calls = builder.call(handler, [ctx_ptr, func_name_const, phase_pre,
|
||||
n_calls: ir.CallInstr = builder.call(handler, [ctx_ptr, func_name_const, phase_pre,
|
||||
args_ptr, null_ptr, decor_args_ptr])
|
||||
|
||||
# 6. 跳转到循环头
|
||||
@@ -379,30 +397,28 @@ def _generate_single_wrapper(module, original_func, wrapper_name, func_name_str,
|
||||
|
||||
# ==== Loop header block ====
|
||||
builder = ir.IRBuilder(loop_header_block)
|
||||
i_phi = builder.phi(i32, "i")
|
||||
i_phi: ir.PhiInstr = builder.phi(i32, "i")
|
||||
i_phi.add_incoming(zero_i32, loop_predecessor)
|
||||
cond = builder.icmp_signed('<', i_phi, n_calls)
|
||||
cond: ir.ICMPInstr = builder.icmp_signed('<', i_phi, n_calls)
|
||||
builder.cbranch(cond, loop_body_block, post_block)
|
||||
|
||||
# ==== Loop body block ====
|
||||
builder = ir.IRBuilder(loop_body_block)
|
||||
|
||||
# v4: 从 args_struct 读回参数(装饰器可能在 pre-phase 中修改了参数)
|
||||
call_args: list[ir.LoadInstr | ir.Argument] = []
|
||||
if args_alloca is not None and args_struct_type is not None:
|
||||
zero = ir.Constant(i32, 0)
|
||||
call_args = []
|
||||
for i in range(len(param_types)):
|
||||
field_idx = ir.Constant(i32, i)
|
||||
gep = builder.gep(args_alloca, [zero, field_idx], inbounds=True)
|
||||
Loaded_arg = builder.load(gep, name=f"arg.{i}")
|
||||
field_idx: ir.Constant = ir.Constant(i32, i)
|
||||
gep: ir.GEPInstr = builder.gep(args_alloca, [zero, field_idx], inbounds=True)
|
||||
Loaded_arg: ir.LoadInstr = builder.load(gep, name=f"arg.{i}")
|
||||
call_args.append(Loaded_arg)
|
||||
else:
|
||||
call_args = []
|
||||
|
||||
ret_val = builder.call(original_func, call_args)
|
||||
ret_val: ir.CallInstr = builder.call(original_func, call_args)
|
||||
if ret_alloca is not None:
|
||||
builder.store(ret_val, ret_alloca)
|
||||
i_next = builder.add(i_phi, one_i32)
|
||||
i_next: ir.AddInstr = builder.add(i_phi, one_i32)
|
||||
i_phi.add_incoming(i_next, loop_body_block)
|
||||
builder.branch(loop_header_block)
|
||||
|
||||
@@ -410,6 +426,7 @@ def _generate_single_wrapper(module, original_func, wrapper_name, func_name_str,
|
||||
builder = ir.IRBuilder(post_block)
|
||||
|
||||
# 后置阶段
|
||||
ret_ptr: ir.BitCastInstr | ir.Constant
|
||||
if ret_alloca is not None:
|
||||
ret_ptr = builder.bitcast(ret_alloca, i8_ptr)
|
||||
else:
|
||||
@@ -425,13 +442,13 @@ def _generate_single_wrapper(module, original_func, wrapper_name, func_name_str,
|
||||
if is_void:
|
||||
builder.ret_void()
|
||||
else:
|
||||
final_ret = builder.load(ret_alloca, name="final_ret")
|
||||
final_ret: ir.LoadInstr = builder.load(ret_alloca, name="final_ret")
|
||||
builder.ret(final_ret)
|
||||
|
||||
return wrapper
|
||||
|
||||
|
||||
def _redirect_calls(module, old_func, new_func, skip_func_names=None):
|
||||
def _redirect_calls(module: ir.Module, old_func: ir.Function, new_func: ir.Function, skip_func_names: set[str] | None = None) -> None:
|
||||
"""
|
||||
替换 module 中所有对 old_func 的调用指令为对 new_func 的调用。
|
||||
跳过 skip_func_names 中的函数(wrapper 函数内部不应被重定向)。
|
||||
@@ -439,21 +456,24 @@ def _redirect_calls(module, old_func, new_func, skip_func_names=None):
|
||||
if skip_func_names is None:
|
||||
skip_func_names = set()
|
||||
|
||||
func: ir.Function
|
||||
for func in module.functions:
|
||||
if func.name in skip_func_names:
|
||||
continue
|
||||
if func.name == new_func.name:
|
||||
continue
|
||||
block: ir.Block
|
||||
for block in func.blocks:
|
||||
instr: ir.Instruction
|
||||
for instr in list(block.instructions):
|
||||
if not isinstance(instr, ir.CallInstr):
|
||||
continue
|
||||
callee = instr.callee
|
||||
callee: ir.Function = instr.callee
|
||||
if isinstance(callee, ir.Function) and callee is old_func:
|
||||
instr.callee = new_func
|
||||
|
||||
|
||||
def run(Gen):
|
||||
def run(Gen: LlvmCodeGenerator) -> None:
|
||||
"""
|
||||
执行 DecoratorPass。
|
||||
|
||||
@@ -466,16 +486,19 @@ def run(Gen):
|
||||
if not hasattr(Gen, '_decorated_funcs') or not Gen._decorated_funcs:
|
||||
return
|
||||
|
||||
module = Gen.module
|
||||
decorated = Gen._decorated_funcs.copy()
|
||||
module: ir.Module = Gen.module
|
||||
decorated: dict = Gen._decorated_funcs.copy()
|
||||
|
||||
mangled_name: str
|
||||
info: dict
|
||||
for mangled_name, info in decorated.items():
|
||||
decorators = info['decorators']
|
||||
func_name = info['func_name']
|
||||
is_export = info['is_export']
|
||||
decorators: list = info['decorators']
|
||||
func_name: str = info['func_name']
|
||||
is_export: bool = info['is_export']
|
||||
|
||||
# 查找原始函数
|
||||
original_func = None
|
||||
original_func: ir.Function | None = None
|
||||
f: ir.Function
|
||||
for f in module.functions:
|
||||
if f.name == mangled_name:
|
||||
original_func = f
|
||||
@@ -490,14 +513,16 @@ def run(Gen):
|
||||
# Python 装饰器顺序:@a @b def f() => a(b(f))
|
||||
# 执行顺序:先应用最靠近函数的 @b,再应用 @a
|
||||
|
||||
current_func = original_func
|
||||
all_wrapper_names = set()
|
||||
current_func: ir.Function = original_func
|
||||
all_wrapper_names: set[str] = set()
|
||||
|
||||
i: int
|
||||
for i in range(len(decorators) - 1, -1, -1):
|
||||
deco = decorators[i]
|
||||
is_outermost = (i == 0)
|
||||
deco_name = deco['name']
|
||||
deco: dict = decorators[i]
|
||||
is_outermost: bool = (i == 0)
|
||||
deco_name: str = deco['name']
|
||||
|
||||
wrapper_name: str
|
||||
if is_outermost:
|
||||
wrapper_name = f"__decor_wrap_{mangled_name}"
|
||||
else:
|
||||
@@ -505,7 +530,7 @@ def run(Gen):
|
||||
|
||||
all_wrapper_names.add(wrapper_name)
|
||||
|
||||
wrapper = _generate_single_wrapper(
|
||||
wrapper: ir.Function = _generate_single_wrapper(
|
||||
module, current_func, wrapper_name,
|
||||
func_name, deco, is_export=is_export,
|
||||
is_outermost=is_outermost,
|
||||
|
||||
Reference in New Issue
Block a user