1819 lines
91 KiB
Plaintext
1819 lines
91 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
|
||
|
||
|
||
# ============================================================
|
||
# 全局 gen 单例(模块级镜像,同 HandlesType/HandlesStruct 模式)
|
||
#
|
||
# 由 BuildPipeline/main 在 gen 创建后调用 set_global_gen 注入。
|
||
# P4 委托函数用本地 _g_gen(cast 成 Generator 类型)调
|
||
# CallGenMixin 方法,避免函数体 import 包模块与类/模块名歧义。
|
||
# ============================================================
|
||
_g_gen: t.CVoid | t.CPtr = None
|
||
|
||
|
||
def set_global_gen(gen: t.CVoid | t.CPtr) -> None:
|
||
"""注入全局 gen 单例(BuildPipeline/main 调用)"""
|
||
global _g_gen
|
||
_g_gen = gen
|
||
|
||
|
||
# ============================================================
|
||
# _lookup_module_sha1 — 按模块名查找 SHA1(委托到 gen._lookup_module_sha1)
|
||
# ============================================================
|
||
|
||
|
||
# ============================================================
|
||
# 模块 SHA1 查询(委托给 StubMerger 全局存储器)
|
||
#
|
||
# 翻译时用于跨模块函数调用名混淆:
|
||
# string.strchr(...) → call @{sha1_of_string}.strchr(...)
|
||
#
|
||
# 数据来源是 StubMerger.PopulateSha1MapStore/AppendToSha1MapStore
|
||
# 填充的全局存储器,不再维护独立的 SHA1 映射表副本。
|
||
# ============================================================
|
||
|
||
def _lookup_module_sha1(mod_name: str) -> str:
|
||
"""查找模块名对应的 SHA1,找不到返回 None(委托到 gen._lookup_module_sha1)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g._lookup_module_sha1(mod_name)
|
||
return None
|
||
|
||
def _lookup_module_sha1_suffix(mod_suffix: str) -> str:
|
||
"""后缀匹配查找模块 SHA1(委托到 gen._lookup_module_sha1_suffix)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g._lookup_module_sha1_suffix(mod_suffix)
|
||
return None
|
||
|
||
# ============================================================
|
||
# 全局 CExport 函数表(module_sha1 + func_name)
|
||
#
|
||
# t.CExport 函数定义时不加 SHA1 前缀(如 @strlen),
|
||
# 跨模块调用时需要查表确认目标函数是否是 CExport 函数。
|
||
# 若是,使用裸名调用(@strlen);否则使用 @{sha1}.func。
|
||
# 必须包含模块 SHA1 记录,避免同名跨模块函数冲突
|
||
# (一个模块有 CExport 的 strlen→@strlen,另一个没有→@{sha1}.strlen)。
|
||
#
|
||
# 注:表数据已迁入 gen 字段(CallGenMixin.CexportSha1Arr/CexportFuncArr/
|
||
# CexportCount),本模块不再持有(P4 簇 1+2)。
|
||
# ============================================================
|
||
_CEXPORT_MAX: t.CDefine = 256
|
||
|
||
def register_cexport_func(sha1: str, func_name: str) -> int:
|
||
"""注册 CExport 函数到全局表(委托到 gen.register_cexport_func)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g.register_cexport_func(sha1, func_name)
|
||
return 0
|
||
|
||
def is_cexport_func(sha1: str, func_name: str) -> int:
|
||
"""检查 (sha1, func_name) 是否是 CExport 函数(委托到 gen.is_cexport_func)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g.is_cexport_func(sha1, func_name)
|
||
return 0
|
||
|
||
# ============================================================
|
||
# _lookup_mod_sha1 - 从 from_imports 查找类所属模块的 SHA1
|
||
#
|
||
# lookup_from_import 返回指向 from_imports 内部的指针,不是 null 终止
|
||
# (如 "namespace_defs Gadget:namespace_defs ...")。此函数手动截断
|
||
# 模块名,复制到新缓冲区,再查找 SHA1(精确+后缀匹配)。
|
||
# ============================================================
|
||
def _lookup_mod_sha1(pool: memhub.MemBuddy | t.CPtr,
|
||
from_imports: str, class_name: str,
|
||
allow_star_fallback: int = 1) -> str:
|
||
"""从 from_imports 查找类所属模块的 SHA1(委托到 gen._lookup_mod_sha1)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g._lookup_mod_sha1(pool, from_imports, class_name, allow_star_fallback)
|
||
return None
|
||
|
||
|
||
# ============================================================
|
||
# _lookup_sha1_from_modname_raw - 原始模块名 → SHA1
|
||
#
|
||
# 截断模块名(lookup_from_import 返回内部指针,空格/冒号/null 分隔),
|
||
# 去掉相对导入前导点,再精确+后缀查找 SHA1。
|
||
# 供 _lookup_mod_sha1 与 HandlesExpr._lookup_cross_module_cdefine 复用。
|
||
# ============================================================
|
||
def _lookup_sha1_from_modname_raw(pool: memhub.MemBuddy | t.CPtr,
|
||
mod_name_raw: str) -> str:
|
||
"""从原始模块名查找 SHA1(委托到 gen._lookup_sha1_from_modname_raw)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g._lookup_sha1_from_modname_raw(pool, mod_name_raw)
|
||
return None
|
||
|
||
# ============================================================
|
||
# HandlesExprCall - 函数调用表达式处理(Mixin 继承模式)
|
||
#
|
||
# 工具函数和 FuncEntry 保留为模块级,ExprCallHandle 提供 trans 接口
|
||
# ============================================================
|
||
|
||
# ============================================================
|
||
# 在模块函数链表中按名称查找函数
|
||
# ============================================================
|
||
def find_func_in_module(mod: llvmlite.LLVMModule | t.CPtr,
|
||
name: str) -> llvmlite.Function | t.CPtr:
|
||
"""在模块的函数链表中按名称查找函数(委托到 gen.find_func_in_module)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g.find_func_in_module(mod, name)
|
||
return None
|
||
|
||
# ============================================================
|
||
# _ensure_c_lib_declare - 为已知的 C 库函数创建 declare 声明
|
||
#
|
||
# 对应 TPC 的 _C_LIB_FUNCS 机制。当裸名调用 memset/memmove/memcmp/
|
||
# strcmp/strlen 等已知 C 库函数时,自动在当前模块创建 declare,
|
||
# 避免报 "裸名调用未定义且未导入" 错误。
|
||
# memcpy 不在此处理(已有 _emit_llvm_memcpy_intrinsic 映射到 @llvm.memcpy)。
|
||
#
|
||
# Args:
|
||
# pool: 内存池
|
||
# mod: LLVM 模块
|
||
# name: 函数名
|
||
#
|
||
# Returns:
|
||
# Function 指针(已创建 declare),或 None 如果不是已知 C 库函数
|
||
# ============================================================
|
||
def _ensure_c_lib_declare(pool: memhub.MemBuddy | t.CPtr,
|
||
mod: llvmlite.LLVMModule | t.CPtr,
|
||
name: str) -> llvmlite.Function | t.CPtr:
|
||
"""为已知的 C 库函数创建 declare 声明(委托到 gen._ensure_c_lib_declare)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g._ensure_c_lib_declare(pool, mod, name)
|
||
return None
|
||
|
||
# ============================================================
|
||
# _infer_external_func_ret_ty - 根据函数名推断外部函数返回类型
|
||
#
|
||
# stubs 在翻译后才注入 IR,翻译时模块中无 stub 函数声明,
|
||
# 因此对 includes 库函数(如 string.strchr 返回 i8*)需根据
|
||
# 函数名推断返回类型,避免指针被截断为 i32。
|
||
#
|
||
# 覆盖 includes/string.py 所有导出函数:
|
||
# i8*: strcpy, strncpy, strchr, strrchr, strstr, memset, memset32, memcpy, memmove
|
||
# i64: strlen, atoll
|
||
# double: atof
|
||
# i8: samestr
|
||
# i32(默认): strcmp, strncmp, memcmp, strspn, atoi, split
|
||
# ============================================================
|
||
def _infer_external_func_ret_ty(pool: memhub.MemBuddy | t.CPtr,
|
||
func_name: str) -> llvmlite.LLVMType | t.CPtr:
|
||
"""根据函数名推断外部 includes 函数的返回类型(委托到 gen._infer_external_func_ret_ty)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g._infer_external_func_ret_ty(pool, func_name)
|
||
return None
|
||
|
||
# ============================================================
|
||
# _get_external_func_param_ty - 获取外部函数第 idx 个参数的期望类型
|
||
#
|
||
# stubs 翻译时未注入,需推断参数类型以提升字面量(如 i32→i64),
|
||
# 避免 declare(i64) 与 call(i32) 类型不匹配。
|
||
#
|
||
# 注意:stubs 翻译时 ULONG(t.CUnsignedLong) 在 LLVM IR 中被翻译为 i64
|
||
# (因为 LLVM 中 long 是 64 位),因此 Win32 API 中所有 ULONG/DWORD/SIZE_T
|
||
# 参数在 declare 中都是 i64。call 时必须匹配,否则类型不匹配。
|
||
#
|
||
# 策略:对 Win32 API 函数的所有非指针参数(字面量)都提升为 i64,
|
||
# 以匹配 declare 中 ULONG 被翻译为 i64 的情况。
|
||
#
|
||
# 指针参数(VOIDPTR/HANDLE)不在此处理,由调用点的 inttoptr 处理。
|
||
# ============================================================
|
||
def _get_external_func_param_ty(pool: memhub.MemBuddy | t.CPtr,
|
||
func_name: str,
|
||
param_idx: int) -> llvmlite.LLVMType | t.CPtr:
|
||
"""获取外部函数第 param_idx 个参数的期望类型(委托到 gen._get_external_func_param_ty)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g._get_external_func_param_ty(pool, func_name, param_idx)
|
||
return None
|
||
|
||
# ============================================================
|
||
# _emit_llvm_memcpy_intrinsic — 将 memcpy 调用映射到 @llvm.memcpy 内联函数
|
||
#
|
||
# 背景: string.memcpy 是 t.CExport 函数,跨模块调用生成 @memcpy 裸名调用。
|
||
# 但在 monomorphization 场景下,目标模块的 deps.txt 可能不含 string,
|
||
# 导致 @memcpy 声明缺失,链接器报 undefined value。
|
||
#
|
||
# 解决: 将 memcpy 调用映射到 LLVM 内联函数 @llvm.memcpy,
|
||
# 该内联函数在当前模块内声明,无需跨模块依赖。
|
||
#
|
||
# @llvm.memcpy 签名: void (i8* dst, i8* src, i64 len, i1 isvolatile)
|
||
# C memcpy 签名: i8* (i8* dst, i8* src, i64 len) — 返回 dst
|
||
#
|
||
# Args:
|
||
# args_head: 参数链表头(dst, src, num),通过 Value.Next 链接
|
||
# arg_count: 参数数量(应为 3)
|
||
#
|
||
# Returns:
|
||
# dst 值(匹配 C memcpy 语义: 返回 dest 指针)
|
||
# ============================================================
|
||
def _emit_llvm_memcpy_intrinsic(pool: memhub.MemBuddy | t.CPtr,
|
||
builder: llvmlite.IRBuilder | t.CPtr,
|
||
mod: llvmlite.LLVMModule | t.CPtr,
|
||
dst_val: llvmlite.Value | t.CPtr,
|
||
src_val: llvmlite.Value | t.CPtr,
|
||
num_val: llvmlite.Value | t.CPtr) -> llvmlite.Value | t.CPtr:
|
||
"""将 memcpy 调用映射到 @llvm.memcpy 内联函数(委托到 gen._emit_llvm_memcpy_intrinsic)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g._emit_llvm_memcpy_intrinsic(pool, builder, mod, dst_val, src_val, num_val)
|
||
return None
|
||
|
||
# ============================================================
|
||
# c.Deref(ptr) — 解引用指针,按指针 pointee 类型读取
|
||
#
|
||
# 生成: %N = load <pointee_ty>, <pointee_ty>* %ptr
|
||
# 返回 pointee 类型的值
|
||
#
|
||
# 注意: 必须按 ptr 的 pointee 类型决定读取宽度。
|
||
# - i8* (str/bytes/字符遍历) → load i8
|
||
# - i64* (t.CUInt64T, 块头部) → load i64(memhub 的 free list 链表读 8 字节头部)
|
||
# 之前固定 load i8 导致 memhub 读块头部只读到低 8 位,
|
||
# free list 的 next 指针被截断成 0x88 等垃圾值,alloc 崩溃。
|
||
# ============================================================
|
||
def translate_c_deref(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) -> llvmlite.Value | t.CPtr:
|
||
"""c.Deref(ptr) → load 按 ptr 的 pointee 类型(委托到 gen.translate_c_deref)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g.translate_c_deref(pool, builder, mod, cl, trans)
|
||
return None
|
||
|
||
# ============================================================
|
||
# c.DerefAs(ptr, val) — 解引用写入,*ptr = val
|
||
#
|
||
# 生成: %pc = bitcast i8* %ptr to <val_ty>*
|
||
# store <val_ty> %val, <val_ty>* %pc
|
||
# ============================================================
|
||
def translate_c_derefas(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) -> llvmlite.Value | t.CPtr:
|
||
"""c.DerefAs(ptr, val) → store val to ptr(bitcast 后 store)(委托到 gen.translate_c_derefas)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g.translate_c_derefas(pool, builder, mod, cl, trans)
|
||
return None
|
||
|
||
# ============================================================
|
||
# c.Set(a, b) — 赋值语义 a = b(与 c.DerefAs 的指针语义不同)
|
||
#
|
||
# c.DerefAs(ptr, val) 是 *ptr = val(指针解引用写);
|
||
# c.Set(a, b) 是 a = b(a 为左值),a 支持三种形态:
|
||
# 1. c.Deref(ptr) → *ptr = b(zlib/vipermath 的 c.Set(c.Deref(p), v) 用法)
|
||
# 2. Name 变量 → 变量赋值(含 global/nonlocal/局部)
|
||
# 3. Attribute → 字段赋值(GEP + store)
|
||
# ============================================================
|
||
def translate_c_set(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) -> llvmlite.Value | t.CPtr:
|
||
"""c.Set(a, b) → a = b(赋值语义,a 为左值)(委托到 gen.translate_c_set)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g.translate_c_set(pool, builder, mod, cl, trans)
|
||
return None
|
||
|
||
|
||
# ============================================================
|
||
# c.Addr(var) — 取变量地址,返回 alloca 指针(不 load)
|
||
#
|
||
# 用于获取栈变量的可写地址,配合 c.DerefAs 使用
|
||
# ============================================================
|
||
def translate_c_addr(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) -> llvmlite.Value | t.CPtr:
|
||
"""c.Addr(var) → 返回变量的 alloca 指针(不 load)(委托到 gen.translate_c_addr)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g.translate_c_addr(pool, builder, mod, cl, trans)
|
||
return None
|
||
|
||
# ============================================================
|
||
# c.Load(a, b) — 指针间复制: *a = *b
|
||
#
|
||
# 加载 b 指向的值,存储到 a 指向的地址。
|
||
# 生成: %pc_src = bitcast i8* %src to <ty>*
|
||
# %loaded = load <ty>, <ty>* %pc_src
|
||
# %pc_dst = bitcast i8* %dst to <ty>*
|
||
# store <ty> %loaded, <ty>* %pc_dst
|
||
# ============================================================
|
||
def translate_c_load(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) -> llvmlite.Value | t.CPtr:
|
||
"""c.Load(a, b) → *a = *b(加载 b 的值,存储到 a)(委托到 gen.translate_c_load)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g.translate_c_load(pool, builder, mod, cl, trans)
|
||
return None
|
||
|
||
# ============================================================
|
||
# c.Asm — 内联汇编支持
|
||
#
|
||
# 生成: %N = call <ret_ty> asm sideeffect "<asm>", "<constraints>"(<args>)
|
||
# 或: call void asm sideeffect "<asm>", "<constraints>"(<args>)
|
||
#
|
||
# 操作数按出现顺序编号 $0, $1, ...(用户需按输出在前写 f-string)
|
||
# ============================================================
|
||
|
||
ASM_MAX_OPERANDS: t.CDefine = 16
|
||
ASM_TEXT_BUF_SIZE: t.CDefine = 2048
|
||
ASM_CONST_BUF_SIZE: t.CDefine = 512
|
||
ASM_ARGS_BUF_SIZE: t.CDefine = 512
|
||
ASM_LINE_BUF_SIZE: t.CDefine = 4096
|
||
|
||
# ============================================================
|
||
# AsmOperand - 内联汇编操作数条目
|
||
# ============================================================
|
||
@t.NoVTable
|
||
class AsmOperand:
|
||
"""内联汇编操作数条目"""
|
||
Value: llvmlite.Value | t.CPtr # 输入值或输出 alloca
|
||
Constraint: str # 约束字符串 (如 "r", "=r")
|
||
IsOutput: int # 1=输出, 0=输入
|
||
|
||
# ============================================================
|
||
# _asm_append_cstr — 将 C 字符串 src 追加到 dst 末尾
|
||
# ============================================================
|
||
def _asm_append_cstr(dst: str, dst_size: t.CSizeT,
|
||
src: str):
|
||
"""将 C 字符串 src 追加到 dst 末尾(委托到 gen._asm_append_cstr)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||
if g is not None:
|
||
g._asm_append_cstr(dst, dst_size, src)
|
||
|
||
# ============================================================
|
||
# _asm_escape_for_ir — 将汇编文本转义为 LLVM IR 字符串内容
|
||
#
|
||
# \n → \0A, " → \22, \ → \5C
|
||
# ============================================================
|
||
def _asm_escape_for_ir(pool: memhub.MemBuddy | t.CPtr,
|
||
src: str) -> str:
|
||
"""转义汇编文本用于 LLVM IR 字符串字面量(委托到 gen._asm_escape_for_ir)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g._asm_escape_for_ir(pool, src)
|
||
return None
|
||
|
||
# ============================================================
|
||
# _resolve_register — 将 ASM_DESCR 属性名映射到约束字符串
|
||
# ============================================================
|
||
def _resolve_register(attr_name: str) -> str:
|
||
"""将 t.ASM_DESCR.XXX 的属性名映射到约束字符串值(委托到 gen._resolve_register)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g._resolve_register(attr_name)
|
||
return ""
|
||
|
||
# ============================================================
|
||
# _resolve_asm_descr — 递归解析约束表达式
|
||
#
|
||
# 支持:
|
||
# t.ASM_DESCR.XXX → _resolve_register(XXX)
|
||
# expr | expr (BinOp BitOr) → 拼接
|
||
# "string" (Constant) → 直接返回
|
||
# ============================================================
|
||
def _resolve_asm_descr(pool: memhub.MemBuddy | t.CPtr,
|
||
node: ast.AST | t.CPtr) -> str:
|
||
"""递归解析约束表达式,返回约束字符串(委托到 gen._resolve_asm_descr)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g._resolve_asm_descr(pool, node)
|
||
return ""
|
||
|
||
# ============================================================
|
||
# _asm_get_operand — 获取操作数数组中第 idx 个元素的指针
|
||
# ============================================================
|
||
def _asm_get_operand(base: AsmOperand | t.CPtr,
|
||
idx: int) -> AsmOperand | t.CPtr:
|
||
"""获取操作数数组中第 idx 个元素的指针(委托到 gen._asm_get_operand)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g._asm_get_operand(base, idx)
|
||
return None
|
||
|
||
# ============================================================
|
||
# _asm_is_c_call — 检查 Call 节点是否是 c.XXX 调用
|
||
#
|
||
# 返回 attr_name(如 "AsmInp"/"AsmOut"),不是则返回 None
|
||
# ============================================================
|
||
def _asm_is_c_call(node: ast.Call | t.CPtr) -> str:
|
||
"""检查 Call 节点是否是 c.XXX 调用,返回属性名或 None(委托到 gen._asm_is_c_call)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g._asm_is_c_call(node)
|
||
return None
|
||
|
||
# ============================================================
|
||
# _asm_add_operand — 添加操作数到数组
|
||
#
|
||
# 返回 1 成功, 0 失败(数组已满)
|
||
# ============================================================
|
||
def _asm_add_operand(operands: AsmOperand | t.CPtr,
|
||
count: int,
|
||
val: llvmlite.Value | t.CPtr,
|
||
constraint: str,
|
||
is_output: int) -> int:
|
||
"""添加操作数到数组,返回新计数(失败返回原计数)(委托到 gen._asm_add_operand)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g._asm_add_operand(operands, count, val, constraint, is_output)
|
||
return 0
|
||
|
||
# ============================================================
|
||
# translate_c_asm — 翻译 c.Asm 内联汇编
|
||
#
|
||
# 语法:
|
||
# c.Asm("nop", [t.ASM_DESCR.CLOBBER_MEMORY])
|
||
# c.Asm(f"mov rax, {c.AsmInp(val, t.ASM_DESCR.REG_ANY)}", op=[...])
|
||
# c.Asm(f"...", out=[c.AsmOut(var, t.ASM_DESCR.OUTPUT_REG)], op=[...])
|
||
# ============================================================
|
||
def translate_c_asm(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) -> llvmlite.Value | t.CPtr:
|
||
"""翻译 c.Asm 内联汇编,返回结果 Value(委托到 gen.translate_c_asm)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g.translate_c_asm(pool, builder, mod, cl, trans)
|
||
return None
|
||
|
||
# ============================================================
|
||
# c.LLVMIR — 内联 LLVM IR(无返回值,直接嵌入原始 IR 文本)
|
||
#
|
||
# 语法:
|
||
# c.LLVMIR(f"add i32 {c.LInp(a)}, {c.LInp(b)}")
|
||
# c.LLVMIR(f"{c.LOut(result)} = add i32 {c.LInp(a)}, {c.LInp(b)}")
|
||
#
|
||
# c.LInp(expr) - 输入操作数,替换为 expr 的 LLVM 值引用文本(SSA 名 "%x" 或常量 "42")
|
||
# c.LOut(expr) - 输出操作数:为 expr 变量分配唯一 SSA 寄存器 %llvmirN,
|
||
# 模板嵌入后自动追加 store <ty> %llvmirN, <ty>* %expr 写回变量
|
||
#
|
||
# 语义(2026-08-08 用户决策):不做指令解析,模板文本直接嵌入当前基本块,
|
||
# 返回 None(无返回值)。ret_ty 第二参数已废弃(兼容忽略)。
|
||
# ============================================================
|
||
|
||
LLVMIR_MAX_OPS: t.CDefine = 16
|
||
LLVMIR_TEMPLATE_BUF: t.CDefine = 512
|
||
|
||
# 注:LOut 唯一 SSA 寄存器名计数器已迁入 gen 字段(CallGenMixin.LLVMIRRegSeq),
|
||
# 本模块不再持有(P4 簇 1+2)。
|
||
|
||
# ============================================================
|
||
# translate_c_llvmir — 翻译 c.LLVMIR 内联 LLVM IR
|
||
# ============================================================
|
||
def translate_c_llvmir(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) -> llvmlite.Value | t.CPtr:
|
||
"""c.LLVMIR 内联 LLVM IR:无返回值,直接嵌入原始 IR 文本(委托到 gen.translate_c_llvmir)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g.translate_c_llvmir(pool, builder, mod, cl, trans)
|
||
return None
|
||
|
||
# ============================================================
|
||
# _apply_struct_defaults — 应用结构体字段的默认值
|
||
#
|
||
# 在 zeroinitializer 之后、显式参数之前调用
|
||
# 遍历所有字段,对有默认值的字段翻译并 store
|
||
# 显式参数(位置/关键字)后续会覆盖默认值
|
||
# ============================================================
|
||
def _apply_struct_defaults(pool: memhub.MemBuddy | t.CPtr,
|
||
builder: llvmlite.IRBuilder | t.CPtr,
|
||
mod: llvmlite.LLVMModule | t.CPtr,
|
||
struct_ty: llvmlite.LLVMType | t.CPtr,
|
||
class_name: str,
|
||
tmp: llvmlite.Value | t.CPtr,
|
||
trans: HT.Translator | t.CPtr):
|
||
"""应用结构体字段的默认值(委托到 gen._apply_struct_defaults)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||
if g is not None:
|
||
g._apply_struct_defaults(pool, builder, mod, struct_ty, class_name, tmp, trans)
|
||
|
||
# ============================================================
|
||
# _translate_struct_ctor — 结构体构造函数 Point(10, 20)
|
||
#
|
||
# 生成:
|
||
# %tmp = alloca {i32, i32}
|
||
# store {i32, i32} zeroinitializer, {i32, i32}* %tmp
|
||
# %f0 = getelementptr {i32, i32}, {i32, i32}* %tmp, i32 0, i32 0
|
||
# store i32 10, i32* %f0
|
||
# %f1 = getelementptr {i32, i32}, {i32, i32}* %tmp, i32 0, i32 1
|
||
# store i32 20, i32* %f1
|
||
# %result = load {i32, i32}, {i32, i32}* %tmp
|
||
# ============================================================
|
||
def _translate_struct_ctor(pool: memhub.MemBuddy | t.CPtr,
|
||
builder: llvmlite.IRBuilder | t.CPtr,
|
||
mod: llvmlite.LLVMModule | t.CPtr,
|
||
struct_ty: llvmlite.LLVMType | t.CPtr,
|
||
class_name: str,
|
||
cargs: list[ast.AST | t.CPtr] | t.CPtr,
|
||
can: t.CSizeT,
|
||
trans: HT.Translator | t.CPtr) -> llvmlite.Value | t.CPtr:
|
||
"""结构体构造函数:按字段顺序 store 参数值,返回结构体值(委托到 gen._translate_struct_ctor)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g._translate_struct_ctor(pool, builder, mod, struct_ty, class_name, cargs, can, trans)
|
||
return None
|
||
|
||
|
||
# ============================================================
|
||
# _translate_renum_construct — REnum 变体构造函数
|
||
#
|
||
# 语法: ClassName.VariantName(args...)
|
||
# 如 LLVMType.Int(1) → 构造 LLVMType 的 Int 变体,__tag=0,_p1=1
|
||
#
|
||
# 生成 IR:
|
||
# %tmp = alloca {i32, i32, ...} ; REnum 类型
|
||
# store zeroinitializer, %tmp ; 清零
|
||
# %tag_ptr = gep %tmp, 0, 0 ; __tag 字段
|
||
# store i32 <tag_value>, %tag_ptr ; 写入 tag
|
||
# %p1_ptr = gep %tmp, 0, 1 ; _p1 字段
|
||
# store <coerced_arg0>, %p1_ptr ; 写入 payload[0]
|
||
# ... (更多 payload 字段)
|
||
# return %tmp ; 返回指针
|
||
#
|
||
# 对应 TPC 的 _HandleREnumConstructLlvm
|
||
# ============================================================
|
||
def _translate_renum_construct(pool: memhub.MemBuddy | t.CPtr,
|
||
builder: llvmlite.IRBuilder | t.CPtr,
|
||
mod: llvmlite.LLVMModule | t.CPtr,
|
||
class_name: str,
|
||
variant_name: str,
|
||
tag_value: int,
|
||
cargs: list[ast.AST | t.CPtr] | t.CPtr,
|
||
can: t.CSizeT,
|
||
trans: HT.Translator | t.CPtr) -> llvmlite.Value | t.CPtr:
|
||
"""构造 REnum 变体实例,返回指向 alloca 的指针(委托到 gen._translate_renum_construct)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g._translate_renum_construct(pool, builder, mod, class_name, variant_name,
|
||
tag_value, cargs, can, trans)
|
||
return None
|
||
|
||
|
||
# ============================================================
|
||
# _do_virtual_call — 通过虚表间接调用虚方法
|
||
#
|
||
# IR 模式:
|
||
# %1 = getelementptr StructTy, StructTy* %self, i32 0, i32 0 ; i8**
|
||
# %2 = load i8*, i8** %1 ; i8* (vtable ptr)
|
||
# %3 = bitcast i8* %2 to {i8*, ...}* ; vtable typed ptr
|
||
# %4 = getelementptr {i8*, ...}, {i8*, ...}* %3, i32 0, i32 N ; i8**
|
||
# %5 = load i8*, i8** %4 ; i8* (func ptr)
|
||
# %6 = bitcast i8* %5 to RetTy(Params)* ; func typed ptr
|
||
# call RetTy %6(Params %self, ...)
|
||
#
|
||
# 参数:
|
||
# args_head — 已构建好的参数链表头(self_ptr 为首节点)
|
||
# args_count — 参数总数(含 self)
|
||
# found_func — 方法对应的 Function 对象(用于推断函数签名)
|
||
# ret_ty — 返回类型
|
||
# ============================================================
|
||
def _do_virtual_call(pool: memhub.MemBuddy | t.CPtr,
|
||
builder: llvmlite.IRBuilder | t.CPtr,
|
||
mod: llvmlite.LLVMModule | t.CPtr,
|
||
class_name: str,
|
||
method_name: str,
|
||
self_ptr: llvmlite.Value | t.CPtr,
|
||
args_head: llvmlite.Value | t.CPtr,
|
||
args_count: int,
|
||
found_func: llvmlite.Function | t.CPtr,
|
||
ret_ty: llvmlite.LLVMType | t.CPtr,
|
||
vtable_base: llvmlite.Value | t.CPtr = None) -> llvmlite.Value | t.CPtr:
|
||
"""通过虚表间接调用虚方法,返回 call 结果(void 方法返回 None)(委托到 gen._do_virtual_call)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g._do_virtual_call(pool, builder, mod, class_name, method_name,
|
||
self_ptr, args_head, args_count, found_func, ret_ty, vtable_base)
|
||
return None
|
||
|
||
# ============================================================
|
||
# _call_method_on_ptr — 在结构体指针上调用方法
|
||
#
|
||
# 辅助函数:构造 ClassName.method_name 调用,self 指针为首个参数
|
||
# 如果该方法在虚表中,则走虚方法分发路径(间接调用)
|
||
# ============================================================
|
||
def _call_method_on_ptr(pool: memhub.MemBuddy | t.CPtr,
|
||
builder: llvmlite.IRBuilder | t.CPtr,
|
||
mod: llvmlite.LLVMModule | t.CPtr,
|
||
class_name: str,
|
||
method_name: str,
|
||
self_ptr: llvmlite.Value | t.CPtr,
|
||
extra_args: t.CSizeT | t.CPtr,
|
||
extra_count: int,
|
||
trans: HT.Translator | t.CPtr,
|
||
node: ast.AST | t.CPtr = None) -> llvmlite.Value | t.CPtr:
|
||
"""在结构体指针上调用方法,返回 call 结果(void 方法返回 None)(委托到 gen._call_method_on_ptr)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g._call_method_on_ptr(pool, builder, mod, class_name, method_name,
|
||
self_ptr, extra_args, extra_count, trans, node)
|
||
return None
|
||
|
||
|
||
# ============================================================
|
||
# _ensure_method_declare - 为跨模块方法调用创建 declare 声明
|
||
#
|
||
# 当 found_func 为 None(stub 未注入或跨模块调用)时,
|
||
# 在当前模块中创建函数声明,避免 llc 报 undefined value。
|
||
# ============================================================
|
||
def _ensure_method_declare(pool: memhub.MemBuddy | t.CPtr,
|
||
mod: llvmlite.LLVMModule | t.CPtr,
|
||
call_name: str,
|
||
ret_ty: llvmlite.LLVMType | t.CPtr,
|
||
param_head: llvmlite.ParamNode | t.CPtr,
|
||
param_count: int):
|
||
"""为跨模块方法调用创建 declare 声明(委托到 gen._ensure_method_declare)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||
if g is not None:
|
||
g._ensure_method_declare(pool, mod, call_name, ret_ty, param_head, param_count)
|
||
|
||
# ============================================================
|
||
# _lookup_method_ret_ty_via_vpi - 从 vpi stub 返回注解缓存精确获取方法返回类型
|
||
#
|
||
# 方法定义处(.vpi stub)的返回注解(如 json.JsonValue._pool_alloc →
|
||
# "str")在 stub 注入时由 VpiReader 缓存(_cache_vpi_return_annots_text)。
|
||
# 此函数按 模块SHA1 + 类名 + 方法名 查缓存并纯字符串解析为 LLVMType。
|
||
# 无需硬编码白名单——返回类型始终来自方法定义处。
|
||
# ============================================================
|
||
def _lookup_method_ret_ty_via_vpi(pool: memhub.MemBuddy | t.CPtr,
|
||
cls_sha1: str,
|
||
cls_name: str,
|
||
method_name: str) -> llvmlite.LLVMType | t.CPtr:
|
||
"""从 vpi stub 返回注解缓存获取方法返回类型,未命中返回 None(委托到 gen._lookup_method_ret_ty_via_vpi)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g._lookup_method_ret_ty_via_vpi(pool, cls_sha1, cls_name, method_name)
|
||
return None
|
||
|
||
|
||
# ============================================================
|
||
# _special_method_ret_ty - 编译器内置特殊方法的固定返回类型
|
||
#
|
||
# __before_init__ / __init__:编译器生成/约定返回 void
|
||
# __new__:返回 Ptr(StructTy)(存储空间指针)
|
||
#
|
||
# 这些方法不存在于源码(vpi stub 无条目),跨模块调用时
|
||
# found_func/text.ll/vpi 缓存必然未命中,但返回类型是编译器
|
||
# 确定性语义(与 HandlesClassDef._translate_method 3543-3548 一致),
|
||
# 在此直接固定,不触发 fail-fast 误报。非特殊方法返回 None。
|
||
# ============================================================
|
||
def _special_method_ret_ty(pool: memhub.MemBuddy | t.CPtr,
|
||
class_name: str,
|
||
method_name: str) -> llvmlite.LLVMType | t.CPtr:
|
||
"""编译器内置特殊方法的固定返回类型;非特殊返回 None(委托到 gen._special_method_ret_ty)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g._special_method_ret_ty(pool, class_name, method_name)
|
||
return None
|
||
|
||
|
||
# ============================================================
|
||
# _fail_method_ret_ty - 方法返回类型无法精确获取时 fail-fast
|
||
#
|
||
# 返回类型来源(按序):当前模块函数 → text.ll define → vpi stub 返回注解缓存。
|
||
# 全部未命中时立即 ERROR + 错误堆栈终止,绝不按名推断白名单/静默默认 i32。
|
||
#
|
||
# node: 调用点 AST 节点(可选,用于 ERROR 堆栈定位)
|
||
# ============================================================
|
||
def _fail_method_ret_ty(method_name: str,
|
||
node: ast.AST | t.CPtr = None) -> llvmlite.LLVMType | t.CPtr:
|
||
"""方法返回类型无法精确获取时 fail-fast(ERROR + 错误堆栈)(委托到 gen._fail_method_ret_ty)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g._fail_method_ret_ty(method_name, node)
|
||
return None
|
||
|
||
|
||
# ============================================================
|
||
# 跨模块方法返回类型查找(从 text.ll)
|
||
#
|
||
# Phase A 翻译每个源文件后生成 text.ll,其中 define 行包含
|
||
# 方法的实际返回类型。当 Phase A 翻译后续文件调用跨模块方法时,
|
||
# 方法调用默认返回 i32,导致指针返回值被截断。
|
||
# _LookupMethodRetTyFromTextLL 读取依赖模块的 text.ll,从 define
|
||
# 行提取实际返回类型,避免指针截断(未命中时回退 vpi stub 缓存)。
|
||
# ============================================================
|
||
|
||
# ============================================================
|
||
# SetTempDir - 设置 temp 目录路径
|
||
#
|
||
# 在 Phase2.py 的 Phase A 翻译前调用,使 CallGenMixin
|
||
# 能够读取依赖模块的 text.ll 文件。
|
||
# ============================================================
|
||
def SetTempDir(temp_dir: str):
|
||
"""设置 temp 目录路径(供跨模块方法返回类型查找使用)(委托到 gen.SetTempDir)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||
if g is not None:
|
||
g.SetTempDir(temp_dir)
|
||
|
||
|
||
# ============================================================
|
||
# _ParseLLVMRetTyStr - 将 LLVM IR 返回类型字符串转换为 llvmlite.LLVMType
|
||
#
|
||
# 从 define 行中提取的返回类型字符串(define 与 @ 之间的内容),
|
||
# 转换为 llvmlite.LLVMType 对象。
|
||
#
|
||
# 支持的类型:
|
||
# void → Void
|
||
# i8/i16/i32/i64 → Int8/Int16/Int32/Int64
|
||
# double → Double, float → Float
|
||
# 任何含 * 的类型 → Ptr(Int8)(通用指针,保留 64 位地址)
|
||
#
|
||
# Args:
|
||
# pool: 内存池
|
||
# buf: 包含类型字符串的缓冲区
|
||
# start: 类型字符串起始位置
|
||
# end: 类型字符串结束位置(不含)
|
||
#
|
||
# Returns:
|
||
# LLVM 类型对象,或 None(无法解析)
|
||
# ============================================================
|
||
def _ParseLLVMRetTyStr(pool: memhub.MemBuddy | t.CPtr,
|
||
buf: bytes,
|
||
start: t.CSizeT,
|
||
end: t.CSizeT) -> llvmlite.LLVMType | t.CPtr:
|
||
"""将 LLVM IR 返回类型字符串转换为 llvmlite.LLVMType(委托到 gen._ParseLLVMRetTyStr)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g._ParseLLVMRetTyStr(pool, buf, start, end)
|
||
return None
|
||
|
||
|
||
# ============================================================
|
||
# _LookupMethodRetTyFromTextLL - 从依赖模块的 text.ll 查找方法返回类型
|
||
#
|
||
# 读取 {temp_dir}/{sha1[0:2]}/{sha1}.text.ll (level=1),搜索
|
||
# define 行中包含 "{sha1}.{class_name}.{method_name}" 的函数,
|
||
# 提取返回类型并转换为 llvmlite.LLVMType。
|
||
#
|
||
# 解决问题: 旧实现 _infer_method_ret_ty(已移除)默认返回 i32,导致指针返回值
|
||
# 被 inttoptr 截断为 32 位(coerce_to_type line 238-239)。
|
||
# 本函数从 text.ll 获取实际返回类型,避免截断。
|
||
#
|
||
# Args:
|
||
# pool: 内存池
|
||
# class_sha1: 类所属模块的 SHA1
|
||
# class_name: 类名
|
||
# method_name: 方法名
|
||
#
|
||
# Returns:
|
||
# LLVM 类型对象,或 None(未找到/text.ll 不存在)
|
||
# ============================================================
|
||
def _LookupMethodRetTyFromTextLL(pool: memhub.MemBuddy | t.CPtr,
|
||
class_sha1: str,
|
||
class_name: str,
|
||
method_name: str) -> llvmlite.LLVMType | t.CPtr:
|
||
"""从依赖模块的 text.ll 中查找方法返回类型(委托到 gen._LookupMethodRetTyFromTextLL)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g._LookupMethodRetTyFromTextLL(pool, class_sha1, class_name, method_name)
|
||
return None
|
||
|
||
|
||
# ============================================================
|
||
# 属性方法(@property/@x.setter/@x.deleter)与静态/类方法调用辅助
|
||
#
|
||
# 元数据表由 HandlesClassDef 在类翻译/预注册阶段填充,
|
||
# 这里负责把 obj.prop / obj.prop=v / del obj.prop / Class.method()
|
||
# 翻译为对应的 {sha1}.ClassName.prop 系列函数调用。
|
||
# ============================================================
|
||
|
||
# ============================================================
|
||
# _translate_property_call — 翻译属性方法调用
|
||
#
|
||
# 与 _translate_method_call 的调用名/返回类型解析逻辑一致:
|
||
# 1. 优先用模块中已有的函数(精确/后缀匹配,来自 stub 注入)
|
||
# 2. 否则用类所属模块的 SHA1 构造 "{sha1}.ClassName.method" 调用名
|
||
# 3. 返回类型:函数实类型 → text.ll 查找 → 按方法名推断(默认 i32)
|
||
#
|
||
# call_head/call_count: 已构建好的参数链表(如 getter 只有 obj 一个参数)
|
||
# ============================================================
|
||
def _translate_property_call(pool: memhub.MemBuddy | t.CPtr,
|
||
builder: llvmlite.IRBuilder | t.CPtr,
|
||
mod: llvmlite.LLVMModule | t.CPtr,
|
||
class_name: str,
|
||
method_name: str,
|
||
call_head: llvmlite.Value | t.CPtr,
|
||
call_count: int,
|
||
trans: HT.Translator | t.CPtr) -> llvmlite.Value | t.CPtr:
|
||
"""翻译属性/静态方法调用,返回 call 结果 Value(委托到 gen._translate_property_call)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g._translate_property_call(pool, builder, mod, class_name, method_name,
|
||
call_head, call_count, trans)
|
||
return None
|
||
|
||
|
||
# ============================================================
|
||
# _resolve_obj_class_name — 解析对象表达式的类名(短名)
|
||
#
|
||
# 优先从变量注解(AnnotClassName)解析(如 "memhub.MemBuddy" → "MemBuddy"),
|
||
# 失败时从 LLVM 类型解析(Ptr(Struct) → 类名)。
|
||
# 供属性访问/赋值/删除识别 property 时使用。
|
||
# ============================================================
|
||
def _resolve_obj_class_name(pool: memhub.MemBuddy | t.CPtr,
|
||
trans: HT.Translator | t.CPtr,
|
||
obj_node: ast.AST | t.CPtr) -> str:
|
||
"""解析对象表达式的类名(短名),失败返回 None(委托到 gen._resolve_obj_class_name)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g._resolve_obj_class_name(pool, trans, obj_node)
|
||
return None
|
||
|
||
|
||
# ============================================================
|
||
# _try_property_getter_attr — 尝试将 obj.attr 翻译为 property getter 调用
|
||
#
|
||
# 检查 obj 的类是否有 @property/@x.getter 的 attr 方法;
|
||
# 若有则生成 call Class.attr(obj) 并返回调用结果 Value;否则返回 None。
|
||
# ============================================================
|
||
def _try_property_getter_attr(pool: memhub.MemBuddy | t.CPtr,
|
||
builder: llvmlite.IRBuilder | t.CPtr,
|
||
mod: llvmlite.LLVMModule | t.CPtr,
|
||
at_node: ast.Attribute | t.CPtr,
|
||
obj_ptr: llvmlite.Value | t.CPtr,
|
||
trans: HT.Translator | t.CPtr,
|
||
fallback_class_name: str = None) -> llvmlite.Value | t.CPtr:
|
||
"""尝试 property getter 属性访问,返回调用结果 Value;非 getter 返回 None(委托到 gen._try_property_getter_attr)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g._try_property_getter_attr(pool, builder, mod, at_node, obj_ptr,
|
||
trans, fallback_class_name)
|
||
return None
|
||
|
||
|
||
# ============================================================
|
||
# _try_property_setter — 尝试将 obj.attr = v 翻译为 property setter 调用
|
||
#
|
||
# 检查 obj 的类是否有 @x.setter 的 attr 方法;
|
||
# 若有则生成 call Class.attr$set(obj, v),返回 1;否则返回 0。
|
||
# ============================================================
|
||
def _try_property_setter(pool: memhub.MemBuddy | t.CPtr,
|
||
builder: llvmlite.IRBuilder | t.CPtr,
|
||
mod: llvmlite.LLVMModule | t.CPtr,
|
||
target_attr: ast.Attribute | t.CPtr,
|
||
rhs_val: llvmlite.Value | t.CPtr,
|
||
trans: HT.Translator | t.CPtr) -> int:
|
||
"""尝试 property setter 赋值,返回 1=已处理(生成调用)(委托到 gen._try_property_setter)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g._try_property_setter(pool, builder, mod, target_attr, rhs_val, trans)
|
||
return 0
|
||
|
||
|
||
# ============================================================
|
||
# _try_property_deleter — 尝试将 del obj.attr 翻译为 property deleter 调用
|
||
#
|
||
# 检查 obj 的类是否有 @x.deleter 的 attr 方法;
|
||
# 若有则生成 call Class.attr$del(obj),返回 1;否则返回 0。
|
||
# ============================================================
|
||
def _try_property_deleter(pool: memhub.MemBuddy | t.CPtr,
|
||
builder: llvmlite.IRBuilder | t.CPtr,
|
||
mod: llvmlite.LLVMModule | t.CPtr,
|
||
target_attr: ast.Attribute | t.CPtr,
|
||
trans: HT.Translator | t.CPtr) -> int:
|
||
"""尝试 property deleter 删除,返回 1=已处理(生成调用)(委托到 gen._try_property_deleter)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g._try_property_deleter(pool, builder, mod, target_attr, trans)
|
||
return 0
|
||
|
||
|
||
# ============================================================
|
||
# _translate_static_class_call — 翻译 ClassName.method(args) 静态/类方法调用
|
||
#
|
||
# @staticmethod: 直接 call Class.method(args...),无 self
|
||
# @classmethod: 在参数前插入栈上分配的类实例指针(与 TPC 一致)
|
||
# ============================================================
|
||
def _translate_static_class_call(pool: memhub.MemBuddy | t.CPtr,
|
||
builder: llvmlite.IRBuilder | t.CPtr,
|
||
mod: llvmlite.LLVMModule | t.CPtr,
|
||
class_name: str,
|
||
method_name: str,
|
||
cl: ast.Call | t.CPtr,
|
||
trans: HT.Translator | t.CPtr) -> llvmlite.Value | t.CPtr:
|
||
"""翻译类名静态/类方法调用,返回 call 结果 Value;非静态/类方法返回 None(委托到 gen._translate_static_class_call)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g._translate_static_class_call(pool, builder, mod, class_name, method_name, cl, trans)
|
||
return None
|
||
|
||
|
||
# ============================================================
|
||
# _translate_method_call - 翻译方法调用 obj.method(args)
|
||
#
|
||
# 生成: call <ret_ty> @SHA1.ClassName.method_name(Ptr(StructTy) %obj, args...)
|
||
#
|
||
# obj_ptr 是对象变量的 alloca(Ptr(StructTy)),作为 self 参数传入
|
||
# ============================================================
|
||
def _translate_method_call(pool: memhub.MemBuddy | t.CPtr,
|
||
builder: llvmlite.IRBuilder | t.CPtr,
|
||
mod: llvmlite.LLVMModule | t.CPtr,
|
||
class_name: str,
|
||
method_name: str,
|
||
obj_ptr: llvmlite.Value | t.CPtr,
|
||
cl: ast.Call | t.CPtr,
|
||
trans: HT.Translator | t.CPtr) -> llvmlite.Value | t.CPtr:
|
||
"""翻译方法调用,返回 call 结果 Value(委托到 gen._translate_method_call)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g._translate_method_call(pool, builder, mod, class_name, method_name,
|
||
obj_ptr, cl, trans)
|
||
return None
|
||
|
||
# ============================================================
|
||
# _kwarg_name_matches — 检查关键字参数名是否匹配函数参数名
|
||
#
|
||
# 函数参数名在 LLVM IR 中带 % 前缀(如 "%a"),关键字参数名无前缀(如 "a")
|
||
# 跳过 % 前缀后逐字符比较
|
||
# ============================================================
|
||
def _kwarg_name_matches(kw_arg: str,
|
||
param_name: str) -> int:
|
||
"""检查关键字参数名 kw_arg 是否匹配参数名 param_name(跳过 % 前缀)(委托到 gen._kwarg_name_matches)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g._kwarg_name_matches(kw_arg, param_name)
|
||
return 0
|
||
|
||
# ============================================================
|
||
# _translate_struct_ctor_kw — 结构体构造函数(关键字参数)
|
||
#
|
||
# 支持两种语法:
|
||
# Point(x=10, y=20) — 全关键字
|
||
# Point(10, y=20) — 混合(位置 + 关键字)
|
||
#
|
||
# 位置参数按字段索引赋值,关键字参数按字段名查找赋值
|
||
# ============================================================
|
||
def _translate_struct_ctor_kw(pool: memhub.MemBuddy | t.CPtr,
|
||
builder: llvmlite.IRBuilder | t.CPtr,
|
||
mod: llvmlite.LLVMModule | t.CPtr,
|
||
struct_ty: llvmlite.LLVMType | t.CPtr,
|
||
class_name: str,
|
||
cargs: list[ast.AST | t.CPtr] | t.CPtr,
|
||
can: t.CSizeT,
|
||
keywords: list[ast.AST | t.CPtr] | t.CPtr,
|
||
kw_count: t.CSizeT,
|
||
trans: HT.Translator | t.CPtr) -> llvmlite.Value | t.CPtr:
|
||
"""结构体构造函数(关键字参数版本)(委托到 gen._translate_struct_ctor_kw)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g._translate_struct_ctor_kw(pool, builder, mod, struct_ty, class_name,
|
||
cargs, can, keywords, kw_count, trans)
|
||
return None
|
||
|
||
# ============================================================
|
||
# _translate_call_with_kwargs — 带关键字参数的函数调用
|
||
#
|
||
# 支持两种语法:
|
||
# add(b=4, a=3) — 全关键字乱序
|
||
# greet("Hello", name="World") — 位置 + 关键字混合
|
||
#
|
||
# 策略: 遍历 found_func.Params 链表,对每个参数:
|
||
# 1. 若位置参数仍有剩余(param_idx < can),取位置参数
|
||
# 2. 否则按参数名匹配关键字参数
|
||
# 3. 按参数顺序构建调用参数链表
|
||
# ============================================================
|
||
def _translate_call_with_kwargs(pool: memhub.MemBuddy | t.CPtr,
|
||
builder: llvmlite.IRBuilder | t.CPtr,
|
||
mod: llvmlite.LLVMModule | t.CPtr,
|
||
func_name: str,
|
||
found_func: llvmlite.Function | t.CPtr,
|
||
cargs: list[ast.AST | t.CPtr] | t.CPtr,
|
||
can: t.CSizeT,
|
||
keywords: list[ast.AST | t.CPtr] | t.CPtr,
|
||
kw_count: t.CSizeT,
|
||
trans: HT.Translator | t.CPtr) -> llvmlite.Value | t.CPtr:
|
||
"""带关键字参数的函数调用,按参数顺序构建调用链表(委托到 gen._translate_call_with_kwargs)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g._translate_call_with_kwargs(pool, builder, mod, func_name, found_func,
|
||
cargs, can, keywords, kw_count, trans)
|
||
return None
|
||
|
||
# ============================================================
|
||
# _translate_t_type_cast - 翻译 t.XXX(value) 类型转换
|
||
#
|
||
# 当 func 是 t.XXX 形式且 XXX 是已知类型名(map_t_type 能映射)时,
|
||
# 将 value 转换为目标类型:
|
||
# - 指针 → 整数: ptrtoint (如 t.CUInt64T(ptr) → i64)
|
||
# - 整数 → 指针: inttoptr (如 t.CPtr(int_val) → i8*)
|
||
# - 整数 → 整数: trunc/zext (如 t.CInt8T(i32_val) → i8)
|
||
# - 指针 → 指针: bitcast (如 t.CPtr(ptr_val) → i8*)
|
||
# - 整数 → 浮点: sitofp (如 t.CDouble(i32_val) → double)
|
||
# - 浮点 → 整数: fptosi (如 t.CInt(double_val) → i32)
|
||
# - 浮点 → 浮点: fpext/fptrunc (如 t.CFloat(double_val) → float)
|
||
# ============================================================
|
||
def _translate_t_type_cast(pool: memhub.MemBuddy | t.CPtr,
|
||
builder: llvmlite.IRBuilder | t.CPtr,
|
||
val: llvmlite.Value | t.CPtr,
|
||
target_ty: llvmlite.LLVMType | t.CPtr,
|
||
target_name: str = None,
|
||
src_node: ast.AST | t.CPtr = None,
|
||
trans: HT.Translator | t.CPtr = None) -> llvmlite.Value | t.CPtr:
|
||
"""类型转换:根据参数类型和目标类型选择转换方式(委托到 gen._translate_t_type_cast)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g._translate_t_type_cast(pool, builder, val, target_ty,
|
||
target_name, src_node, trans)
|
||
return None
|
||
|
||
# ============================================================
|
||
# 泛型实例化辅助:从 Subscript slice 提取类型实参名
|
||
# ============================================================
|
||
# _get_type_name_from_annotation 已移至 HandlesType.py(支持 BinOp/Attribute)
|
||
# HandlesExprCall 通过 HandlesType._get_type_name_from_annotation 调用
|
||
|
||
def _extract_type_args_from_slice(pool: memhub.MemBuddy | t.CPtr,
|
||
slice_node: ast.AST | t.CPtr) -> list[str] | t.CPtr:
|
||
"""从 Subscript.slice 提取类型实参名列表(委托到 gen._extract_type_args_from_slice)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g._extract_type_args_from_slice(pool, slice_node)
|
||
return None
|
||
|
||
# ============================================================
|
||
# 泛型类构造调用辅助: list[str](pool, 8) → __new__ + __before_init__ + __init__
|
||
#
|
||
# 复用 translate_list_literal 的构造逻辑:
|
||
# 1. alloca tmp(特化类临时空间,作为 __new__ 的 self)
|
||
# 2. 翻译 cl.args 为参数指针数组
|
||
# 3. call __new__(tmp, *args) → storage_ptr
|
||
# 4. call __before_init__(storage_ptr)
|
||
# 5. call __init__(storage_ptr, *args)
|
||
# 6. return storage_ptr
|
||
#
|
||
# 必须独立于 translate_call 的普通函数路径:spec_name 是类名不是函数名,
|
||
# 走裸名路径会被 _lookup_mod_sha1 的 star import 回退误导,用错误的 SHA1
|
||
# 且缺少 __new__ 方法名后缀,导致链接报 undefined reference。
|
||
# ============================================================
|
||
def _infer_generic_ctor_type_arg(pool: memhub.MemBuddy | t.CPtr,
|
||
arg_node: ast.AST | t.CPtr) -> str:
|
||
"""从构造实参 AST 推断泛型类型实参名;无法推断时默认 "int"(与 TPC 一致)(委托到 gen._infer_generic_ctor_type_arg)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g._infer_generic_ctor_type_arg(pool, arg_node)
|
||
return "int"
|
||
|
||
|
||
def _translate_generic_ctor_call(pool: memhub.MemBuddy | t.CPtr,
|
||
builder: llvmlite.IRBuilder | t.CPtr,
|
||
mod: llvmlite.LLVMModule | t.CPtr,
|
||
spec_name: str,
|
||
cl: ast.Call | t.CPtr,
|
||
trans: HT.Translator | t.CPtr) -> llvmlite.Value | t.CPtr:
|
||
"""泛型类构造调用: list[str](pool, 8) → __new__ + __before_init__ + __init__(委托到 gen._translate_generic_ctor_call)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g._translate_generic_ctor_call(pool, builder, mod, spec_name, cl, trans)
|
||
return None
|
||
|
||
|
||
# ============================================================
|
||
# 翻译函数调用 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(_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(_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(_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(_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(_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(_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(_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(_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(_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(_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(_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(_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(_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(_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(_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(_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(_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(_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(_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(_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
|
||
|
||
|
||
# ============================================================
|
||
# FuncEntry 结构体(用于函数表)
|
||
# ============================================================
|
||
@t.NoVTable
|
||
class FuncEntry:
|
||
"""函数表条目"""
|
||
Name: str
|
||
Func: llvmlite.Function | t.CPtr
|
||
Defaults: t.CVoid | t.CPtr # defaults 列表节点指针 (list[AST | CPtr]),None=无默认值
|
||
DefaultCount: int # 默认值数量
|
||
ParamCount: int # 形参数量(不含 self)
|
||
# TypeStr: 函数类型文本(stdlib 深拷贝,跨文件安全)
|
||
# 1b 每文件 reset_to(mark1) 回收 pool 内 Function 对象后,
|
||
# vtable 生成 find_func_global 读类型改用此文本,避免悬空。
|
||
TypeStr: str
|
||
|
||
# ============================================================
|
||
# 初始化函数表
|
||
# ============================================================
|
||
def init_func_table(pool: memhub.MemBuddy | t.CPtr,
|
||
max_count: int) -> FuncEntry | t.CPtr:
|
||
"""分配并清零函数表数组(委托到 gen.init_func_table)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g.init_func_table(pool, max_count)
|
||
return None
|
||
|
||
# ============================================================
|
||
# 查找函数
|
||
# ============================================================
|
||
def find_func_in_table(funcs: FuncEntry | t.CPtr,
|
||
func_count: int,
|
||
name: str) -> llvmlite.Function | t.CPtr:
|
||
"""在函数表中按名称查找,返回 Function 指针或 None(委托到 gen.find_func_in_table)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g.find_func_in_table(funcs, func_count, name)
|
||
return None
|
||
|
||
# ============================================================
|
||
# 添加函数到函数表
|
||
# ============================================================
|
||
def add_func_to_table(funcs: FuncEntry | t.CPtr,
|
||
func_count: int,
|
||
name: str,
|
||
func: llvmlite.Function | t.CPtr,
|
||
max_count: int,
|
||
defaults: t.CVoid | t.CPtr = None,
|
||
default_count: int = 0,
|
||
param_count: int = 0,
|
||
pool: memhub.MemBuddy | t.CPtr = None) -> int:
|
||
"""添加函数到函数表,返回 0 成功(委托到 gen.add_func_to_table)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g.add_func_to_table(funcs, func_count, name, func, max_count,
|
||
defaults, default_count, param_count, pool)
|
||
return 0
|
||
|
||
# ============================================================
|
||
# 全局函数注册表(跨模块函数查找)
|
||
#
|
||
# 所有模块翻译的函数都会注册到此表(通过 add_func_to_table 自动注册)。
|
||
# 主要用途: vtable 初始化时查找跨模块继承方法的 Function 对象,
|
||
# 以获取函数类型信息构造 bitcast 字符串。
|
||
# ============================================================
|
||
GLOBAL_FUNC_MAX: t.CDefine = 8192
|
||
|
||
def _init_global_func_table() -> int:
|
||
"""初始化全局函数表(用 stdlib.malloc 分配,生命周期=整个程序)(委托到 gen._init_global_func_table)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g._init_global_func_table()
|
||
return 0
|
||
|
||
|
||
# _build_func_type_str — 从 Function 对象生成函数类型文本(stdlib 存储)
|
||
#
|
||
# 格式: ret_ty (param1_ty, param2_ty, ...),与 vtable bitcast 需要一致。
|
||
# 用 stdlib.malloc 分配返回,跨文件永久存活(1b reset 不回收)。
|
||
# 返回 None 表示失败。
|
||
def _build_func_type_str(pool: memhub.MemBuddy | t.CPtr,
|
||
func: llvmlite.Function | t.CPtr) -> str:
|
||
"""生成函数类型文本(stdlib 分配)(委托到 gen._build_func_type_str)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g._build_func_type_str(pool, func)
|
||
return None
|
||
|
||
|
||
def _register_global_func(name: str, func: llvmlite.Function | t.CPtr,
|
||
pool: memhub.MemBuddy | t.CPtr = None) -> int:
|
||
"""注册函数到全局表(已存在则跳过),返回 0 成功(委托到 gen._register_global_func)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g._register_global_func(name, func, pool)
|
||
return 0
|
||
|
||
|
||
def update_global_func_typestr(pool: memhub.MemBuddy | t.CPtr,
|
||
name: str,
|
||
func: llvmlite.Function | t.CPtr) -> int:
|
||
"""更新全局函数表的 TypeStr(在函数参数全部添加完成后调用)(委托到 gen.update_global_func_typestr)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g.update_global_func_typestr(pool, name, func)
|
||
return 0
|
||
|
||
def find_func_global(name: str) -> llvmlite.Function | t.CPtr:
|
||
"""在全局函数表中按名称查找,返回 Function 指针或 None(委托到 gen.find_func_global)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g.find_func_global(name)
|
||
return None
|
||
|
||
|
||
def find_func_entry_global(name: str) -> FuncEntry | t.CPtr:
|
||
"""在全局函数表中按名称查找,返回完整 FuncEntry(含 TypeStr)或 None(委托到 gen.find_func_entry_global)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g.find_func_entry_global(name)
|
||
return None
|
||
|
||
|
||
# ============================================================
|
||
# 全局默认参数注册表(跨模块默认参数填充)
|
||
#
|
||
# 独立于 _global_funcs,因为 _register_global_func 可能在
|
||
# add_func_to_table 之前被调用(如 stub 注入),此时 defaults 还不可用。
|
||
# ============================================================
|
||
GLOBAL_DEFAULTS_MAX: t.CDefine = 4096
|
||
|
||
@t.NoVTable
|
||
class FuncDefaultsEntry:
|
||
"""默认参数表条目"""
|
||
Name: str
|
||
Defaults: t.CVoid | t.CPtr # defaults 列表节点指针 (list[AST | CPtr])(pool 内,可能被 reset)
|
||
DefaultCount: int
|
||
ParamCount: int # 形参数量(不含 self)
|
||
# 常量快照(stdlib 分配,跨文件永久存活):
|
||
# 注册时提取每个默认值 Constant 的值,跨模块调用时优先用快照重建常量 IR,
|
||
# 避免读取已被 1b reset_to(mark1) 回收的 pool 内 AST。
|
||
ConstKinds: t.CInt | t.CPtr # const_kind 数组(DefaultCount 个 i32)
|
||
ConstInts: t.CInt64T | t.CPtr # int_val 数组(DefaultCount 个 i64)
|
||
ConstStrs: t.CSizeT | t.CPtr # str_val 指针数组(DefaultCount 个 i8*)
|
||
|
||
def _init_global_defaults_table() -> int:
|
||
"""初始化全局默认参数表(委托到 gen._init_global_defaults_table)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g._init_global_defaults_table()
|
||
return 0
|
||
|
||
def _register_global_defaults(name: str,
|
||
defaults: t.CVoid | t.CPtr,
|
||
default_count: int,
|
||
param_count: int) -> int:
|
||
"""注册函数默认参数到全局表,返回 0 成功(委托到 gen._register_global_defaults)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g._register_global_defaults(name, defaults, default_count, param_count)
|
||
return 0
|
||
|
||
def find_func_defaults(name: str) -> FuncDefaultsEntry | t.CPtr:
|
||
"""按函数名查找默认参数信息,返回 FuncDefaultsEntry 或 None(委托到 gen.find_func_defaults)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g.find_func_defaults(name)
|
||
return None
|
||
|
||
|
||
# _build_const_from_snapshot — 从常量快照重建常量 IR 值
|
||
#
|
||
# 用于跨模块默认参数填充:gd_entry.Defaults(pool 内 AST)可能已被 reset 回收,
|
||
# 改用注册时提取的 stdlib 常量快照(ConstKinds/ConstInts/ConstStrs)重建常量 IR。
|
||
# 返回 llvmlite.Value*,失败返回 None。
|
||
def _build_const_from_snapshot(pool: memhub.MemBuddy | t.CPtr,
|
||
mod: llvmlite.LLVMModule | t.CPtr,
|
||
gd_entry: FuncDefaultsEntry | t.CPtr,
|
||
di: int,
|
||
trans: HT.Translator | t.CPtr,
|
||
builder: llvmlite.IRBuilder | t.CPtr) -> llvmlite.Value | t.CPtr:
|
||
"""从快照重建第 di 个默认值常量 IR(委托到 gen._build_const_from_snapshot)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g._build_const_from_snapshot(pool, mod, gd_entry, di, trans, builder)
|
||
return None
|
||
|
||
def find_func_entry_in_table(funcs: FuncEntry | t.CPtr,
|
||
func_count: int,
|
||
name: str) -> FuncEntry | t.CPtr:
|
||
"""在函数表中按名称查找,返回完整 FuncEntry 或 None"""
|
||
if name is None or funcs is None:
|
||
return None
|
||
entry_size: t.CSizeT = FuncEntry.__sizeof__()
|
||
i: int = 0
|
||
while i < func_count:
|
||
entry_addr: t.CUInt64T = t.CUInt64T(funcs) + i * entry_size
|
||
entry: FuncEntry | t.CPtr = (FuncEntry | t.CPtr)(t.CVoid(entry_addr, t.CPtr))
|
||
if entry.Name is not None:
|
||
if string.strcmp(entry.Name, name) == 0:
|
||
return entry
|
||
i += 1
|
||
return None
|
||
|
||
# ============================================================
|
||
# ExprCallHandle - 函数调用处理器(Mixin 继承模式)
|
||
#
|
||
# HandleCall / HandlePrintfCall 提供 trans 接口
|
||
# ============================================================
|
||
@t.NoVTable
|
||
class ExprCallHandle(HandlesBase.Mixin):
|
||
"""函数调用处理器:继承 Mixin 获得 Trans 回指针"""
|
||
|
||
def __init__(self, trans: HT.Translator | t.CPtr):
|
||
self.Trans = trans
|
||
|
||
# ============================================================
|
||
# HandleCall - 翻译函数调用,返回 call 结果 Value
|
||
# ============================================================
|
||
def HandleCall(self, node: ast.AST | t.CPtr) -> llvmlite.Value | t.CPtr:
|
||
"""翻译函数调用,从 self.Trans 获取共享状态"""
|
||
return translate_call(
|
||
self.Trans.Pool, self.Trans._cur_builder, self.Trans.Module,
|
||
node,
|
||
self.Trans._funcs, self.Trans._func_count, self.Trans)
|
||
|
||
# ============================================================
|
||
# HandlePrintfCall - 翻译 printf 调用
|
||
# ============================================================
|
||
def HandlePrintfCall(self, cl: ast.Call | t.CPtr):
|
||
"""翻译 printf 调用,从 self.Trans 获取共享状态"""
|
||
translate_printf_call(
|
||
self.Trans.Pool, self.Trans._cur_builder, self.Trans.Module,
|
||
cl, self.Trans)
|
||
|
||
# ============================================================
|
||
# HandlePrintCall - 翻译 print 调用
|
||
# ============================================================
|
||
def HandlePrintCall(self, cl: ast.Call | t.CPtr):
|
||
"""翻译 print 调用(类型感知格式化 + 默认换行)"""
|
||
translate_print_call(
|
||
self.Trans.Pool, self.Trans._cur_builder, self.Trans.Module,
|
||
cl, self.Trans)
|
||
|
||
# ============================================================
|
||
# NewExprCallHandle - 工厂函数
|
||
# ============================================================
|
||
def NewExprCallHandle(pool: memhub.MemBuddy | t.CPtr,
|
||
trans: HT.Translator | t.CPtr) -> ExprCallHandle | t.CPtr:
|
||
"""新建 ExprCallHandle 工厂(委托到 gen.NewExprCallHandle)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g.NewExprCallHandle(pool, trans)
|
||
return None
|
||
|
||
|
||
# ============================================================
|
||
# _make_vtable_ref_i8 / _emit_eh_guarded_call / _translate_isinstance
|
||
# (追加91:CallGenMixin 拆分后顶层经委托调用 CallGenLeafKit 方法——
|
||
# TPV self 调用仅支持 1 级父类,跨 Mixin 统一走 _g_gen 委托)
|
||
# ============================================================
|
||
def _make_vtable_ref_i8(pool: memhub.MemBuddy | t.CPtr,
|
||
builder: llvmlite.IRBuilder | t.CPtr,
|
||
mod: llvmlite.LLVMModule | t.CPtr,
|
||
class_name: str,
|
||
trans: HT.Translator | t.CPtr = None) -> llvmlite.Value | t.CPtr:
|
||
"""构造类 vtable 地址引用(i8*)(委托到 gen._make_vtable_ref_i8)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g._make_vtable_ref_i8(pool, builder, mod, class_name, trans)
|
||
return None
|
||
|
||
|
||
def _emit_eh_guarded_call(builder: llvmlite.IRBuilder | t.CPtr,
|
||
pool: memhub.MemBuddy | t.CPtr,
|
||
mod: llvmlite.LLVMModule | t.CPtr,
|
||
trans: HT.Translator | t.CPtr,
|
||
func: llvmlite.Function | t.CPtr,
|
||
call_name: str,
|
||
head: llvmlite.Value | t.CPtr,
|
||
count: int,
|
||
ret_ty: llvmlite.LLVMType | t.CPtr,
|
||
is_variadic: int) -> llvmlite.Value | t.CPtr:
|
||
"""带 try-except EH 检测的函数调用(委托到 gen._emit_eh_guarded_call)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g._emit_eh_guarded_call(builder, pool, mod, trans, func, call_name, head, count, ret_ty, is_variadic)
|
||
return None
|
||
|
||
|
||
def _translate_isinstance(pool: memhub.MemBuddy | t.CPtr,
|
||
builder: llvmlite.IRBuilder | t.CPtr,
|
||
mod: llvmlite.LLVMModule | t.CPtr,
|
||
obj_node: ast.AST | t.CPtr,
|
||
cls_node: ast.AST | t.CPtr,
|
||
trans: HT.Translator | t.CPtr = None) -> llvmlite.Value | t.CPtr:
|
||
"""翻译 isinstance()(委托到 gen._translate_isinstance)"""
|
||
import lib.core.Gen.Generator as Generator
|
||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||
if g is not None:
|
||
return g._translate_isinstance(pool, builder, mod, obj_node, cls_node, trans)
|
||
return None
|