84 lines
3.2 KiB
Python
84 lines
3.2 KiB
Python
import stdio
|
||
import t, c
|
||
import string
|
||
from inherit_test import Animal, Dog
|
||
|
||
|
||
# ============================================================
|
||
# 虚分派测试:通过虚表指针验证虚分派机制
|
||
#
|
||
# 本测试验证:方法调用通过对象的 __vtable__ 字段进行虚分派,
|
||
# 而非通过变量声明类型直接调用。
|
||
#
|
||
# 测试方法:
|
||
# 1. 创建 Animal 对象 a(Animal 虚表,Speak 返回 0)
|
||
# 2. 创建 Dog 对象 d
|
||
# 3. 用内联汇编将 d 的虚表指针复制到 a
|
||
# 4. 调用 a.Speak() — 应返回 1(Dog.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 没有覆盖 GetName,Dog 虚表中 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
|