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