修正了 args 传参问题
This commit is contained in:
1 parent
fcd4d8a438
commit
4e17365b76
86 files changed
+417
-208
No files matched your search
@@ -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)
|
||||
# ============================================================
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in new issue
Block a user