Files
TransPyC/Test/PointerTest/App/main.py
2026-06-16 16:09:42 +08:00

268 lines
8.6 KiB
Python
Raw 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.
from stdint import *
import t, c
import stdio
import string
import w32.win32console
import w32.win32memory
# ============================================================
# PointerTest - 测试指针操作、global声明、数组退化、指针算术
# ============================================================
# --- Test 1: global 声明对模块级变量的影响 ---
_g_val: t.CInt = 0
_g_ptr: t.CUInt32T | t.CPtr = None
def test_global_write():
"""测试:缺少 global 声明时,赋值是否修改模块级变量"""
global _g_val
_g_val = 42
def test_global_write_no_decl():
"""测试:没有 global 声明时,赋值是否创建局部变量"""
# 注意:这里故意不声明 global测试编译器行为
# 如果 _g_val 在此函数之前被读取过,赋值会修改全局变量
# 如果 _g_val 在此函数中首次被赋值,会创建局部变量
_g_val = 99 # 这应该创建一个局部变量
def test_global_ptr():
global _g_ptr
buf: t.CUInt32T | t.CPtr = w32.win32memory.VirtualAlloc(None, 256, 0x3000, 0x04)
if buf:
string.memset(buf, 0, 256)
_g_ptr = buf
p: t.CUInt32T | t.CPtr = _g_ptr
p[0] = 0xAABBCCDD
p[1] = 0x11223344
def test_global_ptr_no_decl():
"""测试:没有 global 声明时,指针赋值是否创建局部变量"""
# _g_ptr 在 test_global_ptr 中已被赋值(有 global
# 这里读取 _g_ptr 然后赋值 — 读取会将全局变量加入 Gen.variables
# 所以后续赋值应该修改全局变量
old: t.CUInt32T | t.CPtr = _g_ptr # 读取 -> 加入 Gen.variables
_g_ptr = None # 因为之前读取过,这应该修改全局变量
# --- Test 2: 指针算术和数组索引 ---
def test_pointer_arithmetic():
"""测试指针算术:偏移计算是否正确"""
buf: t.CUInt32T | t.CPtr = w32.win32memory.VirtualAlloc(None, 256, 0x3000, 0x04)
if not buf:
stdio.printf("FAIL: VirtualAlloc returned NULL\n")
return
string.memset(buf, 0, 256)
# 写入值
for i in range(8):
buf[i] = t.CUInt32T(i * 100)
# 读取并验证
ok: t.CInt = 1
for i in range(8):
v: t.CUInt32T = buf[i]
expected: t.CUInt32T = t.CUInt32T(i * 100)
if v != expected:
stdio.printf("FAIL: buf[%d] = 0x%x, expected 0x%x\n", i, v, expected)
ok = 0
if ok:
stdio.printf("PASS: pointer arithmetic (buf[i] = i*100)\n")
# --- Test 3: 数组退化为指针 ---
def test_array_decay():
"""测试 list[t.CChar, N] 传递给 t.CConst | str 参数"""
arr: list[t.CChar, 32]
string.memset(c.Addr(arr), 0, 32)
# 手动写入字符串
src: str = "Hello"
for i in range(5):
arr[i] = t.CChar(ord(src[i]))
arr[5] = 0
# 传递给 print (接受 t.CConst | str)
stdio.printf("PASS: array decay -> %s\n", c.Addr(arr))
# --- Test 4: 指针类型转换 (CVoid/CPtr) ---
def test_pointer_cast():
"""测试指针与整数之间的类型转换"""
buf: t.CUInt32T | t.CPtr = w32.win32memory.VirtualAlloc(None, 256, 0x3000, 0x04)
if not buf:
stdio.printf("FAIL: VirtualAlloc returned NULL\n")
return
string.memset(buf, 0, 256)
# 通过 CVoid 指针写入
raw: t.CVoid | t.CPtr = t.CVoid(t.CUInt64T(buf), t.CPtr)
# 将 CVoid 指针转回 CUInt32T 指针
p32: t.CUInt32T | t.CPtr = (t.CUInt32T | t.CPtr)(raw)
p32[0] = 0xDEADBEEF
# 通过原始指针读取
if buf[0] == 0xDEADBEEF:
stdio.printf("PASS: pointer cast CVoid -> CUInt32T*\n")
else:
stdio.printf("FAIL: pointer cast, got 0x%x\n", buf[0])
# --- Test 5: 指针偏移计算 (byte offset vs element offset) ---
def test_pointer_offset():
"""测试指针偏移CUInt8T* + N 应该偏移 N 字节CUInt32T* + N 应该偏移 N*4 字节"""
buf: t.CUInt8T | t.CPtr = w32.win32memory.VirtualAlloc(None, 256, 0x3000, 0x04)
if not buf:
stdio.printf("FAIL: VirtualAlloc returned NULL\n")
return
string.memset(buf, 0, 256)
# 写入 4 字节
buf[0] = 0x41 # 'A'
buf[1] = 0x42 # 'B'
buf[2] = 0x43 # 'C'
buf[3] = 0x44 # 'D'
# 通过 CUInt32T* 读取(应该读到 0x44434241 on little-endian
p32: t.CUInt32T | t.CPtr = (t.CUInt32T | t.CPtr)(t.CVoid(t.CUInt64T(buf), t.CPtr))
val: t.CUInt32T = p32[0]
# little-endian: 0x44434241
if val == 0x44434241:
stdio.printf("PASS: byte offset vs element offset (0x%x)\n", val)
else:
stdio.printf("FAIL: expected 0x44434241, got 0x%x\n", val)
# --- Test 6: 结构体指针访问 ---
class TestStruct():
a: t.CInt
b: t.CInt
c: t.CUInt64T
def test_struct_pointer():
"""测试结构体指针的成员访问"""
s: TestStruct
s.a = 10
s.b = 20
s.c = 0x123456789ABCDEF0
p: TestStruct | t.CPtr = c.Addr(s)
if p.a == 10 and p.b == 20 and p.c == 0x123456789ABCDEF0:
stdio.printf("PASS: struct pointer access (a=%d b=%d c=0x%llx)\n", p.a, p.b, p.c)
else:
stdio.printf("FAIL: struct pointer access (a=%d b=%d c=0x%llx)\n", p.a, p.b, p.c)
# --- Test 7: memcpy/memset 通过指针 ---
def test_memcpy_pointers():
"""测试 memcpy 在指针之间的数据复制"""
src_buf: t.CUInt32T | t.CPtr = w32.win32memory.VirtualAlloc(None, 64, 0x3000, 0x04)
dst_buf: t.CUInt32T | t.CPtr = w32.win32memory.VirtualAlloc(None, 64, 0x3000, 0x04)
if not src_buf or not dst_buf:
stdio.printf("FAIL: VirtualAlloc returned NULL\n")
return
# 初始化 src
for i in range(8):
src_buf[i] = t.CUInt32T(i + 1000)
# 复制
string.memcpy(t.CVoid(t.CUInt64T(dst_buf), t.CPtr), t.CVoid(t.CUInt64T(src_buf), t.CPtr), 32)
# 验证
ok: t.CInt = 1
for i in range(8):
if dst_buf[i] != t.CUInt32T(i + 1000):
stdio.printf("FAIL: dst[%d] = %u, expected %u\n", i, dst_buf[i], i + 1000)
ok = 0
if ok:
stdio.printf("PASS: memcpy between pointers\n")
# --- Test 8: 指针作为函数参数 ---
def fill_array(arr: t.CUInt32T | t.CPtr, count: t.CInt, val: t.CUInt32T):
for i in range(count):
arr[i] = val
def test_pointer_param():
"""测试指针作为函数参数传递"""
buf: t.CUInt32T | t.CPtr = w32.win32memory.VirtualAlloc(None, 64, 0x3000, 0x04)
if not buf:
stdio.printf("FAIL: VirtualAlloc returned NULL\n")
return
fill_array(buf, 8, 0xCAFEBABE)
ok: t.CInt = 1
for i in range(8):
if buf[i] != 0xCAFEBABE:
ok = 0
if ok:
stdio.printf("PASS: pointer as function parameter\n")
else:
stdio.printf("FAIL: pointer as function parameter\n")
def main() -> t.CInt | t.CExport:
w32.win32console.SetConsoleCP(65001)
w32.win32console.SetConsoleOutputCP(65001)
stdio.printf("=== PointerTest: 指针操作基准测试 ===\n\n")
# Test 1: global 声明
stdio.printf("--- Test 1: global declaration ---\n")
_g_val = 0
test_global_write()
stdio.printf("After test_global_write(): _g_val = %d (expect 42)\n", _g_val)
test_global_write_no_decl()
stdio.printf("After test_global_write_no_decl(): _g_val = %d (expect 42, not 99)\n", _g_val)
stdio.printf("\n")
# Test 1b: global pointer
stdio.printf("--- Test 1b: global pointer ---\n")
test_global_ptr()
if _g_ptr:
p: t.CUInt32T | t.CPtr = _g_ptr
stdio.printf("_g_ptr[0] = 0x%x (expect 0xAABBCCDD)\n", p[0])
stdio.printf("_g_ptr[1] = 0x%x (expect 0x11223344)\n", p[1])
test_global_ptr_no_decl()
stdio.printf("After test_global_ptr_no_decl(): _g_ptr = %p (expect NULL/0)\n", t.CVoid(t.CUInt64T(_g_ptr), t.CPtr))
stdio.printf("\n")
# Test 2: pointer arithmetic
stdio.printf("--- Test 2: pointer arithmetic ---\n")
test_pointer_arithmetic()
stdio.printf("\n")
# Test 3: array decay
stdio.printf("--- Test 3: array decay ---\n")
test_array_decay()
stdio.printf("\n")
# Test 4: pointer cast
stdio.printf("--- Test 4: pointer cast ---\n")
test_pointer_cast()
stdio.printf("\n")
# Test 5: pointer offset
stdio.printf("--- Test 5: pointer offset (byte vs element) ---\n")
test_pointer_offset()
stdio.printf("\n")
# Test 6: struct pointer
stdio.printf("--- Test 6: struct pointer access ---\n")
test_struct_pointer()
stdio.printf("\n")
# Test 7: memcpy pointers
stdio.printf("--- Test 7: memcpy between pointers ---\n")
test_memcpy_pointers()
stdio.printf("\n")
# Test 8: pointer as param
stdio.printf("--- Test 8: pointer as function parameter ---\n")
test_pointer_param()
stdio.printf("\n")
stdio.printf("=== PointerTest Complete ===\n")
return 0