Files
ViperC/App/lib/core/Handles/ExprCallDeref.vp
T
TermiNexus 2cb974ae5a refactor(handles): HandlesExprCall 拆 6 组(Base/Deref/Ctor/Call/Table/Handle,2041→241 行)
直接移动+改调用方:~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 验证通过
2026-08-17 08:10:55 +08:00

292 lines
15 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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.ExprCallCtor as ExprCallCtor
import lib.core.Handles.ExprCallCall as ExprCallCall
import lib.core.Handles.ExprCallTable as ExprCallTable
import lib.core.Handles.ExprCallHandle as ExprCallHandle
import lib.core.Handles.HandlesExprCall as HandlesExprCall
# ============================================================
# ExprCallDeref - HandlesExprCall 拆分(阶段 E):ExprCallDeref
#
# 直接移动模式:委托函数迁至此模块,原 HandlesExprCall.vp 仅
# 保留 _g_gen/常量/类;调用方经本模块前缀访问。
# ============================================================
# ============================================================
# 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(HandlesExprCall._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(HandlesExprCall._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(HandlesExprCall._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(HandlesExprCall._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(HandlesExprCall._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
# ============================================================
# _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(HandlesExprCall._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(HandlesExprCall._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(HandlesExprCall._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(HandlesExprCall._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: HandlesExprCall.AsmOperand | t.CPtr,
idx: int) -> HandlesExprCall.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(HandlesExprCall._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(HandlesExprCall._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: HandlesExprCall.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(HandlesExprCall._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(HandlesExprCall._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(HandlesExprCall._g_gen, t.CPtr))
if g is not None:
return g.translate_c_llvmir(pool, builder, mod, cl, trans)
return None