Files
TransPyV/Test/App/virtual_dispatch_test.py
2026-07-19 13:18:46 +08:00

84 lines
3.2 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 stdio
import t, c
import string
from inherit_test import Animal, Dog
# ============================================================
# 虚分派测试:通过虚表指针验证虚分派机制
#
# 本测试验证:方法调用通过对象的 __vtable__ 字段进行虚分派,
# 而非通过变量声明类型直接调用。
#
# 测试方法:
# 1. 创建 Animal 对象 aAnimal 虚表Speak 返回 0
# 2. 创建 Dog 对象 d
# 3. 用内联汇编将 d 的虚表指针复制到 a
# 4. 调用 a.Speak() — 应返回 1Dog.Speak证明虚分派生效
#
# 如果是直接调用非虚分派a.Speak() 会调用 Animal.Speak 返回 0
#
# 注意Animal 和 Dog 类从 inherit_test.py 导入(命名空间隔离)
# ============================================================
def virtual_dispatch_test() -> int:
stdio.printf("vdispatch: === Test Start ===\n")
# 创建对象
a: Animal = Animal(42)
d: Dog = Dog(100, 7)
# ============================================================
# 测试 1: 直接分派(基线验证)
# ============================================================
stdio.printf("vdispatch: === Test 1: Direct Dispatch ===\n")
a_speak: int = a.Speak()
stdio.printf("vdispatch: a.Speak()=%d (expected 0)\n", a_speak)
if a_speak != 0:
stdio.printf("[FAIL] a.Speak()=%d expected 0\n", a_speak)
return 1
d_speak: int = d.Speak()
stdio.printf("vdispatch: d.Speak()=%d (expected 1)\n", d_speak)
if d_speak != 1:
stdio.printf("[FAIL] d.Speak()=%d expected 1\n", d_speak)
return 1
# ============================================================
# 测试 2: 虚分派验证(复制虚表指针)
#
# 将 Dog 的虚表指针复制到 Animal 对象 a
# 虚表指针位于结构体偏移 0__vtable__ 字段)
# 复制后 a.Speak() 应通过虚表分发到 Dog.Speak返回 1
# ============================================================
stdio.printf("vdispatch: === Test 2: Virtual Dispatch ===\n")
# 使用 string.memcpy 复制虚表指针8字节结构体偏移0
# 将 d 的虚表指针复制到 a使 a.Speak() 分发到 Dog.Speak
string.memcpy(c.Addr(a), c.Addr(d), 8)
a_speak2: int = a.Speak()
stdio.printf("vdispatch: a.Speak()=%d (expected 1 after vtable copy)\n", a_speak2)
if a_speak2 != 1:
stdio.printf("[FAIL] a.Speak()=%d expected 1 after vtable copy\n", a_speak2)
return 1
# ============================================================
# 测试 3: GetName 验证(未被覆盖的虚方法)
#
# Dog 没有覆盖 GetNameDog 虚表中 GetName 槽位指向 Animal.GetName
# a.GetName() 应返回 a.name (42),证明虚表槽位一致性
# ============================================================
stdio.printf("vdispatch: === Test 3: GetName After VTable Copy ===\n")
a_name: int = a.GetName()
stdio.printf("vdispatch: a.GetName()=%d (expected 42)\n", a_name)
if a_name != 42:
stdio.printf("[FAIL] a.GetName()=%d expected 42\n", a_name)
return 1
stdio.printf("vdispatch: === All Tests Passed ===\n")
return 0