diff --git a/App/lib/core/Gen/Call/CallGenCBuiltin.vp b/App/lib/core/Gen/Call/CallGenCBuiltin.vp index ba0d8b8..55e02f0 100644 --- a/App/lib/core/Gen/Call/CallGenCBuiltin.vp +++ b/App/lib/core/Gen/Call/CallGenCBuiltin.vp @@ -18,41 +18,34 @@ from . import CallGenBase # ============================================================ # 常量(与 TPC 侧 HandlesExprCall 保持一致) -# -# GLOBAL_FUNC_MAX / GLOBAL_DEFAULTS_MAX / MAX_CLOSURE_NAMES / -# MAX_FUNC_PTR_SIGS / ISINSTANCE_CLASS_MAX:唯一来源在 CallGenBase.vp -# (本文件不使用,故不留副本;消费方 CallGenLeafKit.vp 经 CallGenBase. 引用)。 # ============================================================ -_CEXPORT_MAX: t.CDefine = 256 -ASM_MAX_OPERANDS: t.CDefine = 16 +define _CEXPORT_MAX = 256 +define ASM_MAX_OPERANDS = 16 # clobber(~{...})容量独立于操作数上限:vipersimd ×8 内核单条 c.Asm # 需 21 项(memory + ymm0-15 + rcx/r8-r11)。此前复用 ASM_MAX_OPERANDS=16 # 导致 21 项静默截断为 16,靠后的 GPR clobber(rcx/r8-r11)丢失 → llc 把 # "r" 输入分进 asm 硬编码寄存器 → 现场 r8/r10=4、vmovupd [r8] 读 0x4 崩溃。 -ASM_MAX_CLOBBERS: t.CDefine = 32 -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 -LLVMIR_MAX_OPS: t.CDefine = 16 -LLVMIR_TEMPLATE_BUF: t.CDefine = 512 +define ASM_MAX_CLOBBERS = 32 +define ASM_TEXT_BUF_SIZE = 2048 +define ASM_CONST_BUF_SIZE = 512 +define ASM_ARGS_BUF_SIZE = 512 +define ASM_LINE_BUF_SIZE = 4096 +define LLVMIR_MAX_OPS = 16 +define LLVMIR_TEMPLATE_BUF = 512 # ============================================================ # CallGenCBuiltin - c.*/asm/llvmir 内建 # ============================================================ -@t.NoVTable -class CallGenCBuiltin(CallGenBase.CallGenBase): +novirtual class CallGenCBuiltin(CallGenBase.CallGenBase): """c.* 内建 + 内联汇编 + LLVMIR 翻译(继承 Base)""" - def translate_c_deref(self, pool: memhub.MemBuddy*, builder: llvmlite.IRBuilder*, mod: llvmlite.LLVMModule*, cl: ast.Call*, trans: HT.Translator* = None) -> llvmlite.Value*: """c.Deref(ptr) → load,宽度只由 ptr 的 pointee 类型决定 - pointee 是 i8(t.CPtr / void* / str / bytes)恒读 1 字节;不再按赋值 目标注解(CurAssignAnnot)反推宽度——那会让同一处 c.Deref(i8*) 的读取 宽度取决于它是否恰好出现在带注解赋值的 RHS 里。需要按更宽类型读时, @@ -958,7 +951,13 @@ class CallGenCBuiltin(CallGenBase.CallGenBase): # 与操作数上限解耦——长 clobber 集如 vipersimd ×8 的 21 项不得截断, # 否则硬编码 GPR(rcx/r8-r11)声明丢失 → 输入被 llc 错分配进被 clobber # 的寄存器 → 寄存器错乱/零页崩溃) - clobbers: str | t.CPtr = pool.alloc(8 * ASM_MAX_CLOBBERS) + # 类型必须是**单级**裸缓冲(t.CPtr = i8*):pool.alloc 返回 t.CPtr、 + # string.memset 首参也是 t.CPtr;每槽按 8 字节字符串指针写入由下方的 + # `cl_ptr: str | t.CPtr = (str | t.CPtr)(cl_addr)` 显式 cast 完成 + # (与 includes/_dict.vp 的一致模式:缓冲单级、槽视图 str | t.CPtr)。 + # 此前声明成 str | t.CPtr(=i8**) 与 alloc/memset 层数不符,隐式指针转换 + # 禁止"层数不同",首行即报错。 + clobbers: t.CPtr = pool.alloc(8 * ASM_MAX_CLOBBERS) if clobbers is None: return None string.memset(clobbers, 0, 8 * ASM_MAX_CLOBBERS)