重置上传,新增了多个标准库,开始 TransPyV 自举实验
This commit is contained in:
5
includes/hello.py
Normal file
5
includes/hello.py
Normal file
@@ -0,0 +1,5 @@
|
||||
import stdio
|
||||
|
||||
|
||||
def helloworld():
|
||||
stdio.printf("Hello, world!\n")
|
||||
@@ -22,7 +22,11 @@ from .__function import Function, BasicBlock, block_append_text, function_move_b
|
||||
# builder.build_store(ConstInt(42), a)
|
||||
# r = builder.build_load(i32_ty, a)
|
||||
# builder.build_ret(r)
|
||||
#
|
||||
# 注意: 加 @t.NoVTable 以与硬编码 BUILDER_SIZE=32 保持一致
|
||||
# (所有方法均为顶层函数,无需 vtable)。
|
||||
# ============================================================
|
||||
@t.NoVTable
|
||||
class IRBuilder:
|
||||
Pool: memhub.MemBuddy | t.CPtr # 内存池
|
||||
Func: Function | t.CPtr # 所属函数
|
||||
@@ -897,7 +901,10 @@ def build_gep_struct(builder: IRBuilder | t.CPtr, struct_ty: LLVMType | t.CPtr,
|
||||
# ============================================================
|
||||
# PhiIncoming: phi 节点的入边 (value, block) 对
|
||||
# 继承 GSListNode[PhiIncoming] 获取强类型 Next
|
||||
#
|
||||
# 注意: 必须加 @t.NoVTable(理由见 __function.py 的 Line 注释)。
|
||||
# ============================================================
|
||||
@t.NoVTable
|
||||
class PhiIncoming(GSListNode[PhiIncoming]):
|
||||
Val: Value | t.CPtr
|
||||
Block: BasicBlock | t.CPtr
|
||||
@@ -965,7 +972,10 @@ def build_phi(builder: IRBuilder | t.CPtr, ty: LLVMType | t.CPtr,
|
||||
|
||||
# ============================================================
|
||||
# SwitchCase: switch 指令的 case 分支
|
||||
#
|
||||
# 注意: 必须加 @t.NoVTable(理由见 __function.py 的 Line 注释)。
|
||||
# ============================================================
|
||||
@t.NoVTable
|
||||
class SwitchCase(GSListNode[SwitchCase]):
|
||||
CaseVal: Value | t.CPtr
|
||||
Block: BasicBlock | t.CPtr
|
||||
|
||||
@@ -13,7 +13,12 @@ from .__types import LLVMType, ParamNode, TypePrint
|
||||
#
|
||||
# 每条 LLVM IR 指令序列化为一行文本,通过链表组织。
|
||||
# 继承 GSListNode[Line] 获取强类型 Next: Line|CPtr
|
||||
#
|
||||
# 注意: 必须加 @t.NoVTable。否则 TransPyC 为子类添加 vtable 指针(T*),
|
||||
# 但完全丢失父类 GSListNode[T] 的 Next 字段,导致 struct 布局错位,
|
||||
# 所有字段访问读取垃圾值(见续 XV 会话根因分析)。
|
||||
# ============================================================
|
||||
@t.NoVTable
|
||||
class Line(GSListNode[Line]):
|
||||
Buf: t.CChar | t.CPtr # 行文本(NUL 结尾)
|
||||
Len: t.CSizeT # 文本长度(不含 NUL)
|
||||
@@ -25,7 +30,10 @@ class Line(GSListNode[Line]):
|
||||
# 持有名称 + 指令行链表 + 终止指令标志。
|
||||
# 继承 GSListNode[BasicBlock] 获取强类型 Next: BasicBlock|CPtr
|
||||
# Lines 为 GSList[Line] 指针,提供 O(1) 追加。
|
||||
#
|
||||
# 注意: 必须加 @t.NoVTable(理由同 Line)。
|
||||
# ============================================================
|
||||
@t.NoVTable
|
||||
class BasicBlock(GSListNode[BasicBlock]):
|
||||
Name: t.CChar | t.CPtr # 块名(如 "entry"/"if.then")
|
||||
Lines: GSList[Line] | t.CPtr # 指令行链表容器(Head/Tail/Count)
|
||||
@@ -37,7 +45,10 @@ class BasicBlock(GSListNode[BasicBlock]):
|
||||
#
|
||||
# 继承 GSListNode[Param] 获取强类型 Next: Param|CPtr
|
||||
# Attrs 存储参数属性文本(如 "noundef"/"nocapture"/"readonly"),None=无属性
|
||||
#
|
||||
# 注意: 必须加 @t.NoVTable(理由同 Line)。
|
||||
# ============================================================
|
||||
@t.NoVTable
|
||||
class Param(GSListNode[Param]):
|
||||
Ty: LLVMType | t.CPtr # 参数类型
|
||||
Name: t.CChar | t.CPtr # 参数名(如 "%0"/"%a")
|
||||
@@ -51,7 +62,10 @@ class Param(GSListNode[Param]):
|
||||
# 继承 GSListNode[Function] 获取强类型 Next: Function|CPtr
|
||||
# Params/Blocks 为 GSList 指针,提供 O(1) 追加。
|
||||
# Attrs 存储函数级属性文本(如 "nounwind"/"noinline"),None=无属性
|
||||
#
|
||||
# 注意: 必须加 @t.NoVTable(理由同 Line)。
|
||||
# ============================================================
|
||||
@t.NoVTable
|
||||
class Function(GSListNode[Function]):
|
||||
Name: t.CChar | t.CPtr # 函数名
|
||||
RetTy: LLVMType | t.CPtr # 返回类型
|
||||
@@ -161,9 +175,12 @@ def function_move_block_to_end(func: Function | t.CPtr, block: BasicBlock | t.CP
|
||||
用于解决 SSA 名非单调问题:BB 按创建顺序排列,但指令按控制流顺序生成,
|
||||
导致 SSA 编号在文本输出时非单调递增,llc 报错。
|
||||
在 position_at_end 时调用此函数,使 BB 顺序与 position 顺序一致。
|
||||
|
||||
注意:必须使用 GSList[BasicBlock] 带类型参数,否则 TransPyC 创建不完整
|
||||
struct 类型,导致 blocks.Head/Tail/Count 字段访问读取垃圾值。
|
||||
"""
|
||||
if func is None or block is None: return
|
||||
blocks: GSList | t.CPtr = func.Blocks
|
||||
blocks: GSList[BasicBlock] | t.CPtr = func.Blocks
|
||||
if blocks is None: return
|
||||
|
||||
# 已经是 Tail,无需移动
|
||||
|
||||
@@ -10,7 +10,10 @@ from linkedlist import GSListNode
|
||||
# ParamNode: 函数参数类型链表节点
|
||||
# 继承 GSListNode[ParamNode] 获取强类型 Next: ParamNode|CPtr
|
||||
# Ty 用 t.CVoid | t.CPtr 前向引用,使用时转型为 (LLVMType | t.CPtr)
|
||||
#
|
||||
# 注意: 必须加 @t.NoVTable(理由见 __function.py 的 Line 注释)。
|
||||
# ============================================================
|
||||
@t.NoVTable
|
||||
class ParamNode(GSListNode[ParamNode]):
|
||||
Ty: t.CVoid | t.CPtr # LLVMType*(前向引用,使用时转型)
|
||||
|
||||
|
||||
@@ -13,7 +13,10 @@ from .__types import LLVMType, TypePrint
|
||||
# 表示一个 LLVM IR 值:SSA 临时值(%0/%result)或常量字面量(42/0)。
|
||||
# 每个值有类型指针、名字、是否常量标志。
|
||||
# 继承 GSListNode[Value] 获取强类型 Next: Value|CPtr(值池链表)
|
||||
#
|
||||
# 注意: 必须加 @t.NoVTable(理由见 __function.py 的 Line 注释)。
|
||||
# ============================================================
|
||||
@t.NoVTable
|
||||
class Value(GSListNode[Value]):
|
||||
Ty: LLVMType | t.CPtr # 值的类型
|
||||
Name: t.CChar | t.CPtr # SSA 名("%0"/"%result")或常量文本("42"/"1.5e+00")
|
||||
|
||||
@@ -28,7 +28,10 @@ VERIFY_ERR_PHI_NOT_FIRST: t.CDefine = 4
|
||||
|
||||
# ============================================================
|
||||
# NameEntry: 已定义 SSA 名条目(链表节点)
|
||||
#
|
||||
# 注意: 必须加 @t.NoVTable(理由见 __function.py 的 Line 注释)。
|
||||
# ============================================================
|
||||
@t.NoVTable
|
||||
class NameEntry(GSListNode[NameEntry]):
|
||||
Name: t.CChar | t.CPtr # SSA 名(如 "%0"/"%result")
|
||||
|
||||
|
||||
@@ -84,7 +84,7 @@ class MemManager:
|
||||
string.memset(ptr, 0, total)
|
||||
return ptr
|
||||
|
||||
def realloc(self, ptr: t.CVoid | t.CPtr, old_size: t.CSizeT, new_size: t.CSizeT) -> t.CVoid | t.CPtr:
|
||||
def realloc(self, ptr: t.CVoid | t.CPtr, new_size: t.CSizeT) -> t.CVoid | t.CPtr:
|
||||
if ptr is None:
|
||||
return self.alloc(new_size)
|
||||
if new_size == 0:
|
||||
@@ -93,10 +93,7 @@ class MemManager:
|
||||
new_ptr: t.CVoid | t.CPtr = self.alloc(new_size)
|
||||
if new_ptr is None:
|
||||
return ptr
|
||||
copy_size: t.CSizeT = old_size
|
||||
if new_size < old_size:
|
||||
copy_size = new_size
|
||||
string.memcpy(new_ptr, ptr, copy_size)
|
||||
# 基类无法追踪旧分配大小, 不复制数据; 子类可覆盖以保留数据
|
||||
self.free(ptr)
|
||||
return new_ptr
|
||||
|
||||
@@ -453,7 +450,7 @@ class MemBuddy(MemManager):
|
||||
return 1
|
||||
|
||||
# realloc 覆盖: 伙伴系统从块头读取旧阶数, 无需 old_size
|
||||
def realloc(self, ptr: t.CVoid | t.CPtr, old_size: t.CSizeT, new_size: t.CSizeT) -> t.CVoid | t.CPtr:
|
||||
def realloc(self, ptr: t.CVoid | t.CPtr, new_size: t.CSizeT) -> t.CVoid | t.CPtr:
|
||||
if ptr is None:
|
||||
return self.alloc(new_size)
|
||||
if new_size == 0:
|
||||
@@ -477,3 +474,48 @@ class MemBuddy(MemManager):
|
||||
string.memcpy(new_ptr, ptr, old_data_size)
|
||||
self.free(ptr)
|
||||
return new_ptr
|
||||
|
||||
# === 状态查询 ===
|
||||
|
||||
@property
|
||||
def mem_size(self) -> t.CSizeT:
|
||||
# 可用区总大小(2 的幂),分配上限为 mem_size - MEMBUDDY_HEADER_SIZE
|
||||
return self.usable_size
|
||||
|
||||
def stats(self) -> t.CSizeT:
|
||||
# 返回可用区总大小,用于状态统计
|
||||
return self.usable_size
|
||||
|
||||
def free_count(self) -> t.CSizeT:
|
||||
# 统计所有阶数空闲链中的块总数
|
||||
count: t.CSizeT = 0
|
||||
i: t.CInt
|
||||
for i in range(MEMBUDDY_MAX_ORDERS + 1):
|
||||
head_val: t.CUInt64T = self.free_lists[i]
|
||||
cur: t.CVoid | t.CPtr = t.CVoid(head_val, t.CPtr)
|
||||
while cur is not None:
|
||||
count += 1
|
||||
cur = t.CVoid(c.Deref(t.CUInt64T(cur, t.CPtr)), t.CPtr)
|
||||
return count
|
||||
|
||||
def self_check(self) -> t.CInt:
|
||||
# 验证伙伴分配器内部一致性,返回 0=OK,非 0=损坏
|
||||
if self.usable is None:
|
||||
return 0
|
||||
i: t.CInt
|
||||
for i in range(MEMBUDDY_MAX_ORDERS + 1):
|
||||
head_val: t.CUInt64T = self.free_lists[i]
|
||||
cur: t.CVoid | t.CPtr = t.CVoid(head_val, t.CPtr)
|
||||
while cur is not None:
|
||||
# 检查指针在可用区内
|
||||
if t.CUInt64T(cur) < t.CUInt64T(self.usable):
|
||||
return 1
|
||||
if t.CUInt64T(cur) >= t.CUInt64T(self.usable) + self.usable_size:
|
||||
return 2
|
||||
# 检查对齐:order i 的块必须按 _block_size_at_order(i) 对齐
|
||||
offset: t.CSizeT = t.CUInt64T(cur) - t.CUInt64T(self.usable)
|
||||
bs: t.CSizeT = _block_size_at_order(i)
|
||||
if offset % bs != 0:
|
||||
return 3
|
||||
cur = t.CVoid(c.Deref(t.CUInt64T(cur, t.CPtr)), t.CPtr)
|
||||
return 0
|
||||
|
||||
@@ -39,10 +39,9 @@ def strncpy(dest: str, src: str, n: t.CSizeT) -> str:
|
||||
dest += 1
|
||||
i += 1
|
||||
# 填充剩余空间为 '\0'
|
||||
while i < n:
|
||||
for i in range(n):
|
||||
dest[0] = 0
|
||||
dest += 1
|
||||
i += 1
|
||||
return original_dest
|
||||
|
||||
|
||||
@@ -351,4 +350,16 @@ def split(s: str, delim: str, result: t.CArray[str]) -> int:
|
||||
start[0] = '\0'
|
||||
start += 1
|
||||
result[count] = None # 结尾标记
|
||||
return count
|
||||
return count
|
||||
|
||||
|
||||
ascii_lowercase: str = "abcdefghijklmnopqrstuvwxyz"
|
||||
ascii_uppercase: str = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
ascii_letters: str = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
|
||||
digits: str = "0123456789"
|
||||
hexdigits: str = "0123456789abcdefABCDEF"
|
||||
octdigits: str = "01234567"
|
||||
punctuation: str = "!\"#$%&'()*+,-./:;<=>?@[]^_`{|}~"
|
||||
whitespace: str = " \t\n\r\f\v"
|
||||
printable: str = "01234567890123456789abcdefABCDEF01234567!\"#$%&'()*+,-./:;<=>?@[]^_`{|}~ \t\n\r\f\v"
|
||||
|
||||
@@ -20,11 +20,13 @@ def begin(name: str):
|
||||
SetConsoleOutputCP(CP_UTF8)
|
||||
SetConsoleCP(CP_UTF8)
|
||||
stdio.printf("=== %s ===\n\n", name)
|
||||
stdio.fflush(None)
|
||||
|
||||
|
||||
def section(name: str):
|
||||
"""打印分节标题"""
|
||||
stdio.printf("--- %s ---\n", name)
|
||||
stdio.fflush(None)
|
||||
|
||||
|
||||
def ok(msg: str):
|
||||
@@ -32,6 +34,7 @@ def ok(msg: str):
|
||||
global _pass_count
|
||||
_pass_count += 1
|
||||
stdio.printf("PASS: %s\n", msg)
|
||||
stdio.fflush(None)
|
||||
|
||||
|
||||
def fail(msg: str):
|
||||
@@ -39,6 +42,7 @@ def fail(msg: str):
|
||||
global _fail_count
|
||||
_fail_count += 1
|
||||
stdio.printf("FAIL: %s\n", msg)
|
||||
stdio.fflush(None)
|
||||
|
||||
|
||||
def check(cond: t.CInt, ok_msg: str, fail_msg: str):
|
||||
@@ -52,6 +56,7 @@ def check(cond: t.CInt, ok_msg: str, fail_msg: str):
|
||||
def info(msg: str):
|
||||
"""打印信息消息(不计入 PASS/FAIL)"""
|
||||
stdio.printf("%s\n", msg)
|
||||
stdio.fflush(None)
|
||||
|
||||
|
||||
def end() -> t.CInt:
|
||||
@@ -61,6 +66,7 @@ def end() -> t.CInt:
|
||||
_total_fail += _fail_count
|
||||
stdio.printf("\n--- Summary ---\n")
|
||||
stdio.printf("PASS: %d, FAIL: %d\n", _pass_count, _fail_count)
|
||||
stdio.fflush(None)
|
||||
return _fail_count
|
||||
|
||||
|
||||
@@ -68,4 +74,5 @@ def summary() -> t.CInt:
|
||||
"""打印所有套件的总计汇总,返回总失败数"""
|
||||
stdio.printf("\n=== Total Summary ===\n")
|
||||
stdio.printf("Total PASS: %d, Total FAIL: %d\n", _total_pass, _total_fail)
|
||||
stdio.fflush(None)
|
||||
return _total_fail
|
||||
|
||||
@@ -31,9 +31,8 @@ class Vector[T]():
|
||||
if self.pool == None: return
|
||||
new_capacity: t.CSizeT = self.capacity * 2
|
||||
if new_capacity == 0: new_capacity = 4
|
||||
old_size: t.CSizeT = self.capacity * self.elem_size
|
||||
new_size: t.CSizeT = new_capacity * self.elem_size
|
||||
new_data: t.CVoid | t.CPtr = self.pool.realloc(self.data, old_size, new_size)
|
||||
new_data: t.CVoid | t.CPtr = self.pool.realloc(self.data, new_size)
|
||||
if new_data == None: return
|
||||
self.data = new_data
|
||||
self.capacity = new_capacity
|
||||
|
||||
Reference in New Issue
Block a user