Files
TransPyC/Test/G5/includes/g5container.py

174 lines
5.3 KiB
Python
Raw Permalink 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
import string
from linkedlist import GSListNode, GSList
import memhub
# ============================================================
# G5Node: 继承 GSListNode[G5Node] 的测试节点
#
# 与 __function.py 中的 Line(GSListNode[Line]) 模式相同。
# 这个类在 includes 目录中,走 Phase1 路径。
# Phase1 的 _specialize_member_types 会将 Next 字段类型 T 降级为 i8*
# 而不是 G5Node*(与 TPV 中 Value/Line 类的情况相同)
# ============================================================
@t.NoVTable
class G5Node(GSListNode[G5Node]):
Value: t.CInt
# ============================================================
# G5Container: 持有 GSList[G5Node] 字段的容器
#
# 这是 G5 测试的核心GSList[T] 在 Phase1 中被降级为 opaque
# 导致 List.Head / List.Tail / List.Count 字段访问无法生成 GEP。
#
# 与 __function.py 中的 Function(GSListNode[Function]):
# Params: GSList[Param] | t.CPtr
# Blocks: GSList[BasicBlock] | t.CPtr
# 模式完全相同。
# ============================================================
@t.NoVTable
class G5Container:
List: GSList[G5Node] | t.CPtr
# ============================================================
# 工厂函数(与 __function.py 的 new_line/new_function 模式相同)
# ============================================================
# G5Node 硬编码大小: Next(8) + Value(4) + padding(4) = 16 字节
G5NODE_SIZE: t.CDefine = 16
def new_g5node(pool: memhub.MemBuddy | t.CPtr) -> G5Node | t.CPtr:
"""从 pool 分配并零初始化一个 G5Node"""
ptr: G5Node | t.CPtr = pool.alloc(G5NODE_SIZE)
if ptr is None: return None
string.memset(ptr, 0, G5NODE_SIZE)
return ptr
# GSList 硬编码大小: Head(8) + Tail(8) + Count(8) = 24 字节
G5LIST_SIZE: t.CDefine = 24
def new_g5list(pool: memhub.MemBuddy | t.CPtr) -> GSList | t.CPtr:
"""从 pool 分配并零初始化一个 GSList 容器Head/Tail/Count 全零)"""
gsl: t.CPtr = pool.alloc(G5LIST_SIZE)
if gsl is None: return None
string.memset(gsl, 0, G5LIST_SIZE)
return gsl
# G5Container 硬编码大小: List(8) = 8 字节
G5CONTAINER_SIZE: t.CDefine = 8
def new_g5container(pool: memhub.MemBuddy | t.CPtr) -> G5Container | t.CPtr:
"""从 pool 分配并零初始化一个 G5Container"""
ptr: G5Container | t.CPtr = pool.alloc(G5CONTAINER_SIZE)
if ptr is None: return None
string.memset(ptr, 0, G5CONTAINER_SIZE)
return ptr
# ============================================================
# 字段访问器(供其他模块绕过 stub 类型限制使用)
#
# 跨模块编译时,使用方模块只有 GSList 的 stub 类型opaque
# 导致 TransPyC 静默跳过字段访问(不生成 GEP不报错
# 字段值永远为 null。
#
# 这些访问器在拥有完整类型定义的本模块内执行,能正确访问
# 所有字段。其他模块通过函数调用获取字段值,绕过 stub 限制。
# ============================================================
def g5list_get_head(lst: GSList | t.CPtr) -> G5Node | t.CPtr:
"""获取链表头节点"""
if lst is None: return None
return lst.Head
def g5list_get_tail(lst: GSList | t.CPtr) -> G5Node | t.CPtr:
"""获取链表尾节点"""
if lst is None: return None
return lst.Tail
def g5list_get_count(lst: GSList | t.CPtr) -> t.CSizeT:
"""获取链表节点数"""
if lst is None: return 0
return lst.Count
def g5list_set_head(lst: GSList | t.CPtr, node: G5Node | t.CPtr):
"""设置链表头节点"""
if lst is None: return
lst.Head = node
def g5list_set_tail(lst: GSList | t.CPtr, node: G5Node | t.CPtr):
"""设置链表尾节点"""
if lst is None: return
lst.Tail = node
def g5list_set_count(lst: GSList | t.CPtr, count: t.CSizeT):
"""设置链表节点数"""
if lst is None: return
lst.Count = count
def g5list_append(lst: GSList | t.CPtr, node: G5Node | t.CPtr):
"""将 node 追加到链表末尾O(1)
直接操作 Head/Tail/Count 字段,不依赖 GSList.append 方法
(因为跨模块时方法实现可能缺失)
"""
if lst is None or node is None: return
node.Next = None
if lst.Head is None:
lst.Head = node
else:
lst.Tail.Next = node
lst.Tail = node
lst.Count += 1
# ============================================================
# G5Node 访问器
# ============================================================
def g5node_get_value(node: G5Node | t.CPtr) -> t.CInt:
if node is None: return 0
return node.Value
def g5node_set_value(node: G5Node | t.CPtr, value: t.CInt):
if node is None: return
node.Value = value
def g5node_get_next(node: G5Node | t.CPtr) -> G5Node | t.CPtr:
if node is None: return None
return node.Next
def g5node_set_next(node: G5Node | t.CPtr, next_node: G5Node | t.CPtr):
if node is None: return
node.Next = next_node
# ============================================================
# G5Container 访问器
# ============================================================
def g5container_get_list(container: G5Container | t.CPtr) -> GSList | t.CPtr:
if container is None: return None
return container.List
def g5container_set_list(container: G5Container | t.CPtr, lst: GSList | t.CPtr):
if container is None: return
container.List = lst