直接移动+改调用方:~100 个委托函数按功能移至 6 个子模块,主文件 保留 _g_gen/set_global_gen/顶层常量/4 个类(AsmOperand、FuncEntry、 FuncDefaultsEntry、ExprCallHandle——CallGenLeafKit/HandlesTranslator 仍以 HandlesExprCall.类名 引用)。 - 子模块函数体内 _g_gen/常量/类裸引用 → HandlesExprCall.xxx 跨模块访问 - 28 个调用方 HandlesExprCall.func( → 子模块前缀并补 import - 全 App 语法/引用/import 验证通过
339 lines
19 KiB
Plaintext
339 lines
19 KiB
Plaintext
import t, c
|
||
from stdint import *
|
||
import ast
|
||
import llvmlite
|
||
import memhub
|
||
import string
|
||
import stdio
|
||
import stdlib
|
||
import sys
|
||
import viperlib
|
||
import w32.fileio as fileio
|
||
import lib.core.VLogger as VLogger
|
||
import lib.core.Handles.HandlesBase as HandlesBase
|
||
import lib.core.Handles.HandlesTranslator as HT
|
||
import lib.core.Handles.HandlesExpr as HandlesExpr
|
||
import lib.core.Handles.HandlesVar as HandlesVar
|
||
import lib.core.Handles.HandlesType as HandlesType
|
||
import lib.core.Handles.HandlesNonlocal as HandlesNonlocal
|
||
import lib.core.Handles.HandlesStruct as HandlesStruct
|
||
import lib.core.Handles.HandlesImports as HandlesImports
|
||
import lib.core.Handles.HandlesClassDef as HandlesClassDef
|
||
import lib.core.StubMerger as StubMerger
|
||
|
||
|
||
import lib.core.Handles.ExprCallBase as ExprCallBase
|
||
import lib.core.Handles.ExprCallDeref as ExprCallDeref
|
||
import lib.core.Handles.ExprCallCtor as ExprCallCtor
|
||
import lib.core.Handles.ExprCallTable as ExprCallTable
|
||
import lib.core.Handles.ExprCallHandle as ExprCallHandle
|
||
import lib.core.Handles.HandlesExprCall as HandlesExprCall
|
||
|
||
# ============================================================
|
||
# ExprCallCall - HandlesExprCall 拆分(阶段 E):ExprCallCall
|
||
#
|
||
# 直接移动模式:委托函数迁至此模块,原 HandlesExprCall.vp 仅
|
||
# 保留 _g_gen/常量/类;调用方经本模块前缀访问。
|
||
# ============================================================
|
||
|
||
# ============================================================
|
||
# 翻译函数调用 Call(func, args) — 模块级版本
|
||
# ============================================================
|
||
def translate_call(pool: memhub.MemBuddy | t.CPtr,
|
||
builder: llvmlite.IRBuilder | t.CPtr,
|
||
mod: llvmlite.LLVMModule | t.CPtr,
|
||
node: ast.AST | t.CPtr,
|
||
funcs_ptr: t.CPtr,
|
||
func_count: int,
|
||
trans: HT.Translator | t.CPtr = None) -> llvmlite.Value | t.CPtr:
|
||
"""翻译函数调用,返回 call 结果 Value(委托到 gen.translate_call)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g.translate_call(pool, builder, mod, node, funcs_ptr, func_count, trans)
|
||
return None
|
||
# ============================================================
|
||
# 翻译闭包调用 — 通过闭包指针间接调用
|
||
#
|
||
# 闭包结构: {i8* fn_ptr, i8* env_ptr} (16 字节)
|
||
# 调用过程:
|
||
# 1. load closure_ptr 从变量 alloca
|
||
# 2. load fn_ptr 从 offset 0
|
||
# 3. load env_ptr 从 offset 8
|
||
# 4. bitcast fn_ptr to i32(i8*)*
|
||
# 5. call i32 %fn_typed(i8* %env_ptr)
|
||
# ============================================================
|
||
def translate_closure_call(pool: memhub.MemBuddy | t.CPtr,
|
||
builder: llvmlite.IRBuilder | t.CPtr,
|
||
mod: llvmlite.LLVMModule | t.CPtr,
|
||
closure_alloca: llvmlite.Value | t.CPtr,
|
||
cargs: list[ast.AST | t.CPtr] | t.CPtr,
|
||
can: t.CSizeT,
|
||
trans: HT.Translator | t.CPtr = None) -> llvmlite.Value | t.CPtr:
|
||
"""通过闭包指针间接调用(委托到 gen.translate_closure_call)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g.translate_closure_call(pool, builder, mod, closure_alloca, cargs, can, trans)
|
||
return None
|
||
# ============================================================
|
||
# _is_func_ptr_alloca - 判断变量 alloca 是否为函数指针变量
|
||
#
|
||
# 函数指针变量(t.Callable 注解 → i8*)的 alloca 类型是 Ptr(Ptr(i8)) = i8**;
|
||
# 闭包变量 alloca 是 i8*(Ptr(i8))。通过类型层级区分。
|
||
# ============================================================
|
||
def _is_func_ptr_alloca(alloca: llvmlite.Value | t.CPtr) -> int:
|
||
"""判断 alloca 是否为函数指针变量(类型 Ptr(Ptr(i8))),1=是 / 0=否(委托到 gen._is_func_ptr_alloca)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g._is_func_ptr_alloca(alloca)
|
||
return 0
|
||
|
||
|
||
# ============================================================
|
||
# 闭包变量名集合(stdlib 分配,懒初始化)
|
||
#
|
||
# 背景: 嵌套函数提升后闭包变量 alloca 类型是 i8**(alloca i8*),
|
||
# 与函数指针变量(t.Callable → i8** alloca)类型完全相同,_is_func_ptr_alloca
|
||
# 无法区分,导致 inner() 被误判为函数指针调用(直接 bitcast 闭包对象到函数指针、
|
||
# 无 env 参数调用 → 运行时崩溃)。translate_nested_function_def 创建闭包时
|
||
# 注册嵌套函数名,调用时优先按闭包调用处理。
|
||
# ============================================================
|
||
MAX_CLOSURE_NAMES: t.CDefine = 128
|
||
def _ensure_closure_names() -> int:
|
||
"""确保闭包名表已分配,0 失败(委托到 gen._ensure_closure_names)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g._ensure_closure_names()
|
||
return 0
|
||
def register_closure_name(name: str) -> int:
|
||
"""注册嵌套函数(闭包变量)名,0 成功(委托到 gen.register_closure_name)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g.register_closure_name(name)
|
||
return 0
|
||
def is_closure_name(name: str) -> int:
|
||
"""检查 name 是否已注册为闭包变量名,1=是 / 0=否(委托到 gen.is_closure_name)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g.is_closure_name(name)
|
||
return 0
|
||
|
||
# ============================================================
|
||
# 函数指针变量签名表(变量名 → 返回类型)
|
||
#
|
||
# AnnAssign 处理 t.Callable 注解时注册,函数指针间接调用时
|
||
# 按注册的返回类型构造签名(而非默认 i32)。
|
||
# ============================================================
|
||
MAX_FUNC_PTR_SIGS: t.CDefine = 64
|
||
def _ensure_funcptr_sigs() -> int:
|
||
"""确保函数指针签名表已分配(stdlib.malloc,懒初始化)(委托到 gen._ensure_funcptr_sigs)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g._ensure_funcptr_sigs()
|
||
return 0
|
||
def register_func_ptr_sig(name: str,
|
||
ret_ty: llvmlite.LLVMType | t.CPtr) -> int:
|
||
"""注册函数指针变量的返回类型签名,0 成功(委托到 gen.register_func_ptr_sig)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g.register_func_ptr_sig(name, ret_ty)
|
||
return 0
|
||
def lookup_func_ptr_ret(name: str) -> llvmlite.LLVMType | t.CPtr:
|
||
"""查函数指针变量的返回类型,None=未注册(调用时默认 i32)(委托到 gen.lookup_func_ptr_ret)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g.lookup_func_ptr_ret(name)
|
||
return None
|
||
# ============================================================
|
||
# _translate_func_ptr_call - 函数指针变量间接调用
|
||
#
|
||
# func_p: t.Callable[[A, B], Ret] 后调用 func_p(a, b):
|
||
# 1. load 函数地址(i8*)
|
||
# 2. 翻译实参并链接为 Value 链表
|
||
# 3. 按实参类型 + 注册的返回类型构造签名(未注册时默认 i32)
|
||
# 4. bitcast i8* → 函数指针类型,间接调用
|
||
# ============================================================
|
||
def _translate_func_ptr_call(pool: memhub.MemBuddy | t.CPtr,
|
||
builder: llvmlite.IRBuilder | t.CPtr,
|
||
mod: llvmlite.LLVMModule | t.CPtr,
|
||
fp_alloca: llvmlite.Value | t.CPtr,
|
||
func_name: str,
|
||
cargs: list[ast.AST | t.CPtr] | t.CPtr,
|
||
can: t.CSizeT,
|
||
trans: HT.Translator | t.CPtr) -> llvmlite.Value | t.CPtr:
|
||
"""函数指针变量间接调用,返回结果 Value(委托到 gen._translate_func_ptr_call)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g._translate_func_ptr_call(pool, builder, mod, fp_alloca, func_name, cargs, can, trans)
|
||
return None
|
||
# ============================================================
|
||
# 翻译 printf 调用 — 模块级版本
|
||
# ============================================================
|
||
def translate_printf_call(pool: memhub.MemBuddy | t.CPtr,
|
||
builder: llvmlite.IRBuilder | t.CPtr,
|
||
mod: llvmlite.LLVMModule | t.CPtr,
|
||
cl: ast.Call | t.CPtr,
|
||
trans: HT.Translator | t.CPtr = None):
|
||
"""翻译 printf 调用(特殊处理格式字符串)(委托到 gen.translate_printf_call)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr))
|
||
if g is not None:
|
||
g.translate_printf_call(pool, builder, mod, cl, trans)
|
||
# ============================================================
|
||
# 翻译 print 调用 — 类型感知格式化 + 默认换行
|
||
#
|
||
# 与 printf 不同,print 不需要用户提供格式串:每个参数按 LLVM
|
||
# 类型自动选择格式(%s/%d/%f/0x%llx),结尾追加 "\n"(对齐 Python
|
||
# print 默认 end="\n",以及 TPC HandlesExprBuiltin._HandlePrintLlvm)。
|
||
#
|
||
# 类型分派规则:
|
||
# i8*(str/bytes) → %s
|
||
# 其他指针(struct*/int*) → 0x%llx(ptrtoint 到 i64)
|
||
# i1(bool) → %d(zext 到 i32)
|
||
# i8/i16/i32 → %d(sext 到 i32,C ABI 整数提升)
|
||
# i64 → %lld
|
||
# float/double → %f(float fpext 到 double,C ABI 提升)
|
||
# 无法识别的类型 → "(unknown)"(不传参)
|
||
# ============================================================
|
||
def translate_print_call(pool: memhub.MemBuddy | t.CPtr,
|
||
builder: llvmlite.IRBuilder | t.CPtr,
|
||
mod: llvmlite.LLVMModule | t.CPtr,
|
||
cl: ast.Call | t.CPtr,
|
||
trans: HT.Translator | t.CPtr = None):
|
||
"""翻译 print 调用(类型感知格式化 + 默认换行)(委托到 gen.translate_print_call)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr))
|
||
if g is not None:
|
||
g.translate_print_call(pool, builder, mod, cl, trans)
|
||
# ============================================================
|
||
# stdarg 糖函数实现: va_arg / arg / va_start / va_end
|
||
#
|
||
# 这些函数对应 stdarg.vp 中的 pass 体声明,由编译器在翻译期
|
||
# 转换为 LLVM 指令或 intrinsic 调用,不生成函数 call。
|
||
#
|
||
# va_list 在 TPV 中表示为 i8*(与 stdarg.vp 中 va_list = t.CUnsignedChar | t.CPtr 一致)。
|
||
# va_list 对象存储在 alloca 中(i8**),va_arg/va_start/va_end 需要传入 alloca 指针。
|
||
# ============================================================
|
||
|
||
def _va_arg_get_alloca_ptr(pool: memhub.MemBuddy | t.CPtr,
|
||
builder: llvmlite.IRBuilder | t.CPtr,
|
||
mod: llvmlite.LLVMModule | t.CPtr,
|
||
arg_node: ast.AST | t.CPtr,
|
||
funcs_ptr: t.CPtr,
|
||
func_count: int,
|
||
trans: HT.Translator | t.CPtr) -> llvmlite.Value | t.CPtr:
|
||
"""获取 va_list 变量的 alloca 指针(不 load)(委托到 gen._va_arg_get_alloca_ptr)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g._va_arg_get_alloca_ptr(pool, builder, mod, arg_node, funcs_ptr, func_count, trans)
|
||
return None
|
||
def _resolve_va_arg_type(pool: memhub.MemBuddy | t.CPtr,
|
||
type_node: ast.AST | t.CPtr,
|
||
trans: HT.Translator | t.CPtr) -> llvmlite.LLVMType | t.CPtr:
|
||
"""解析 va_arg/arg 的类型参数为 LLVMType(委托到 gen._resolve_va_arg_type)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g._resolve_va_arg_type(pool, type_node, trans)
|
||
return None
|
||
def _translate_va_arg_sugar(pool: memhub.MemBuddy | t.CPtr,
|
||
builder: llvmlite.IRBuilder | t.CPtr,
|
||
mod: llvmlite.LLVMModule | t.CPtr,
|
||
cl: ast.Call | t.CPtr,
|
||
cargs: list[ast.AST | t.CPtr] | t.CPtr,
|
||
can: t.CSizeT,
|
||
funcs_ptr: t.CPtr,
|
||
func_count: int,
|
||
trans: HT.Translator | t.CPtr) -> llvmlite.Value | t.CPtr:
|
||
"""va_arg(ap, type) / va_arg(ap) → %N = va_arg <ap_ty> <ap>, <type>(委托到 gen._translate_va_arg_sugar)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g._translate_va_arg_sugar(pool, builder, mod, cl, cargs, can, funcs_ptr, func_count, trans)
|
||
return None
|
||
def _translate_arg_sugar(pool: memhub.MemBuddy | t.CPtr,
|
||
builder: llvmlite.IRBuilder | t.CPtr,
|
||
mod: llvmlite.LLVMModule | t.CPtr,
|
||
cl: ast.Call | t.CPtr,
|
||
cargs: list[ast.AST | t.CPtr] | t.CPtr,
|
||
can: t.CSizeT,
|
||
funcs_ptr: t.CPtr,
|
||
func_count: int,
|
||
trans: HT.Translator | t.CPtr) -> llvmlite.Value | t.CPtr:
|
||
"""arg(type) → %N = va_arg <va_list_ty> <trans._va_list_ptr>, <type>(委托到 gen._translate_arg_sugar)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g._translate_arg_sugar(pool, builder, mod, cl, cargs, can, funcs_ptr, func_count, trans)
|
||
return None
|
||
def _translate_va_start_sugar(pool: memhub.MemBuddy | t.CPtr,
|
||
builder: llvmlite.IRBuilder | t.CPtr,
|
||
mod: llvmlite.LLVMModule | t.CPtr,
|
||
cargs: list[ast.AST | t.CPtr] | t.CPtr,
|
||
can: t.CSizeT,
|
||
funcs_ptr: t.CPtr,
|
||
func_count: int,
|
||
trans: HT.Translator | t.CPtr) -> llvmlite.Value | t.CPtr:
|
||
"""va_start(ap, last_arg) → call void @llvm.va_start(i8* %ap)(委托到 gen._translate_va_start_sugar)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g._translate_va_start_sugar(pool, builder, mod, cargs, can, funcs_ptr, func_count, trans)
|
||
return None
|
||
def _translate_va_end_sugar(pool: memhub.MemBuddy | t.CPtr,
|
||
builder: llvmlite.IRBuilder | t.CPtr,
|
||
mod: llvmlite.LLVMModule | t.CPtr,
|
||
cargs: list[ast.AST | t.CPtr] | t.CPtr,
|
||
can: t.CSizeT,
|
||
funcs_ptr: t.CPtr,
|
||
func_count: int,
|
||
trans: HT.Translator | t.CPtr) -> llvmlite.Value | t.CPtr:
|
||
"""va_end(ap) → call void @llvm.va_end(i8* %ap)(委托到 gen._translate_va_end_sugar)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g._translate_va_end_sugar(pool, builder, mod, cargs, can, funcs_ptr, func_count, trans)
|
||
return None
|
||
# ============================================================
|
||
# 变长函数调用支持: 检查 IsVarArg + C ABI 参数提升
|
||
#
|
||
# C ABI 要求变长参数(...部分)进行默认提升:
|
||
# 整数提升: i8/i16 → i32(sext/zext)
|
||
# 浮点提升: float → double(fpext)
|
||
# 固定参数不需要提升(有明确类型签名)。
|
||
# ============================================================
|
||
|
||
def _get_func_fixed_param_count(func: llvmlite.Function | t.CPtr) -> int:
|
||
"""获取函数的固定参数数量(遍历 Params 链表)(委托到 gen._get_func_fixed_param_count)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g._get_func_fixed_param_count(func)
|
||
return 0
|
||
def _check_and_promote_variadic_call(pool: memhub.MemBuddy | t.CPtr,
|
||
builder: llvmlite.IRBuilder | t.CPtr,
|
||
mod: llvmlite.LLVMModule | t.CPtr,
|
||
call_name: str,
|
||
head: llvmlite.Value | t.CPtr,
|
||
can: t.CSizeT,
|
||
arg_nodes: list[ast.AST | t.CPtr] | t.CPtr = None,
|
||
self_offset: int = 0,
|
||
trans: HT.Translator | t.CPtr = None) -> int:
|
||
"""检查被调用函数是否为变长函数,若是则对变长参数进行 C ABI 提升(委托到 gen._check_and_promote_variadic_call)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g._check_and_promote_variadic_call(pool, builder, mod, call_name, head, can,
|
||
arg_nodes, self_offset, trans)
|
||
return 0
|