修正了 args 传参问题

This commit is contained in:
TermiNexus committed 2026-07-31 17:15:54 +08:00
1 parent fcd4d8a438
commit 4e17365b76
86 files changed
+417 -208

No files matched your search

+23
View File
@@ -1219,6 +1219,29 @@ def build_cmpxchg(builder: IRBuilder | t.CPtr, ptr: Value | t.CPtr,
return SSAValue(pool, new_val.Ty, name)
# ============================================================
# va_arg 指令: 从 va_list 读取下一个变长参数
# ============================================================
def build_va_arg(builder: IRBuilder | t.CPtr,
va_list_ptr: Value | t.CPtr,
arg_ty: LLVMType | t.CPtr) -> Value | t.CPtr:
"""%N = va_arg <va_list_ty> <va_list_ptr>, <arg_ty>"""
if builder is None or va_list_ptr is None or arg_ty is None:
return None
pool: memhub.MemBuddy | t.CPtr = builder.Pool
name: t.CChar | t.CPtr = _alloc_ssa_name(builder)
va_list_ty_s: t.CChar | t.CPtr = _type_str(builder, va_list_ptr.Ty)
arg_ty_s: t.CChar | t.CPtr = _type_str(builder, arg_ty)
line: t.CChar | t.CPtr = pool.alloc(256)
if line is None: return None
if va_list_ptr.Name is None:
return None
viperlib.snprintf(line, 256, "%s = va_arg %s %s, %s",
name, va_list_ty_s, va_list_ptr.Name, arg_ty_s)
_emit(builder, line)
return SSAValue(pool, arg_ty, name)
# ============================================================
# 内联汇编 (Phase 3)
# ============================================================
+1 -1
View File
@@ -51,7 +51,7 @@ from .__builder import (
build_fpext, build_fptrunc, build_fp2si, build_si2fp, build_fp2ui, build_ui2fp,
build_gep, build_gep_array, build_gep_struct,
build_phi, build_switch, build_select, build_unreachable,
build_atomicrmw, build_cmpxchg, build_inline_asm,
build_atomicrmw, build_cmpxchg, build_inline_asm, build_va_arg,
PhiIncoming, new_phi_incoming, SwitchCase, new_switch_case,
ICMP_EQ, ICMP_NE, ICMP_SGT, ICMP_SGE, ICMP_SLT, ICMP_SLE,
ICMP_UGT, ICMP_UGE, ICMP_ULT, ICMP_ULE,
+41 -3
View File
@@ -120,9 +120,27 @@ def Int64(pool: memhub.MemBuddy | t.CPtr) -> LLVMType | t.CPtr:
def Ptr(pool: memhub.MemBuddy | t.CPtr, pointee: LLVMType | t.CPtr) -> LLVMType | t.CPtr:
"""创建指针类型 Ptr(pointee)
LLVM IR 中 **不允许 void* 指针**("pointers to void are invalid"),
因此:
- 若 pointee == None → 回退 Ptr(Int8)
- 若 pointee 是 LLVMType.Void → 回退 Ptr(Int8)(对应 C 的 void* 语法在 TPV 中写 Ptr(t.CVoid))
其他类型正常构造 Ptr(pointee)。
"""
# ============== 前置校验: 拦截 Void / None pointee(void* 非法)==============
safe_pointee: LLVMType | t.CPtr = pointee
if safe_pointee is None:
safe_pointee = Int8(pool)
else:
match safe_pointee:
case LLVMType.Void():
safe_pointee = Int8(pool)
case _:
pass
ptr: LLVMType | t.CPtr = _new_type(pool)
if ptr is None: return None
c.DerefAs(ptr, LLVMType.Ptr(pointee))
c.DerefAs(ptr, LLVMType.Ptr(safe_pointee))
return ptr
@@ -372,14 +390,34 @@ def TypePrint(buf: t.CChar | t.CPtr, size: t.CSizeT,
case LLVMType.Int(bits):
viperlib.snprintf(buf, size, "i%d", bits)
case LLVMType.Ptr(pointee):
# 快速路径: Ptr(Struct(name)) → %"name"*
# 使用 snprintf 一次性格式化,避免递归 TypePrint + _strappend 导致的截断
# ================================================================
# LLVM IR 不允许 "void*",必须是 "i8*"。
# 兜底处理:
# pointee == None / Void() / Label() / Metadata() → 统一打印 i8*
# ================================================================
# 先判断是否 Struct(name) 的快速路径(需先判断 pointee 非None)
if pointee is not None:
match pointee:
case LLVMType.Struct(sfields, sfcount, sname):
if sname is not None:
viperlib.snprintf(buf, size, "%%\"%s\"*", sname)
return
case LLVMType.Void():
# Ptr(Void) → i8*(LLVM IR void* 非法)
string.strcpy(buf, "i8*")
return
case LLVMType.Label():
string.strcpy(buf, "i8*")
return
case LLVMType.Metadata():
string.strcpy(buf, "i8*")
return
case _:
pass
# pointee == None 时也兜底 Ptr(Int8) 打印 i8*
if pointee is None:
string.strcpy(buf, "i8*")
return
# 通用路径: 递归打印 pointee 后追加 '*'
TypePrint(buf, size, pointee, pool)
pos: t.CSizeT = string.strlen(buf)