diff --git a/.github/workflows/wp24b2-inplace-gc.yml b/.github/workflows/wp24b2-inplace-gc.yml index 3b4605a..9e1d1dc 100644 --- a/.github/workflows/wp24b2-inplace-gc.yml +++ b/.github/workflows/wp24b2-inplace-gc.yml @@ -62,22 +62,33 @@ jobs: if not re.search(pattern, asm, re.S): raise SystemExit(f"ABI validation failed: {label}") - # Detour callbacks: L must arrive in ECX on WoW 5875 x86. - m = re.search(r"mov\s+edx,\s*0x6f7340.{0,240}?push\s+0x([0-9a-f]+)", asm, re.S) - if not m: - raise SystemExit("ABI validation failed: collector callback address not found") - cb = m.group(1).lstrip("0") or "0" - pos = asm.find(cb + ":") - if pos < 0 or not re.search(r"mov\s+esi,\s*ecx", asm[pos:pos+800]): + def callback_snippet(target, window): + m = re.search(rf"mov\s+edx,\s*0x{target}.{{0,240}}?push\s+0x([0-9a-f]+)", asm, re.S) + if not m: + raise SystemExit(f"ABI validation failed: callback for 0x{target} not found") + cb = m.group(1).lstrip("0") or "0" + pos = asm.find(cb + ":") + if pos < 0: + raise SystemExit(f"ABI validation failed: callback body {cb} not found") + return asm[pos:pos+window] + + # Collector callback: same proven B1 code shape, L copied from ECX. + collector = callback_snippet("6f7340", 900) + if not re.search(r"mov\s+esi,\s*ecx", collector): raise SystemExit("ABI validation failed: collector callback does not consume L from ECX") - m = re.search(r"mov\s+edx,\s*0x6f6ef0.{0,240}?push\s+0x([0-9a-f]+)", asm, re.S) - if not m: - raise SystemExit("ABI validation failed: lua_close callback address not found") - cb = m.group(1).lstrip("0") or "0" - pos = asm.find(cb + ":") - if pos < 0 or not re.search(r"mov\s+esi,\s*ecx", asm[pos:pos+600]): - raise SystemExit("ABI validation failed: lua_close callback does not consume L from ECX") + # lua_close is much smaller in B2 because fragment reconstruction is gone. + # Zig may preserve ECX in any callee-saved register or a stack slot; do + # not require the B1-specific ESI allocation. + close = callback_snippet("6f6ef0", 800) + ecx_preserved = re.search( + r"(?:mov\s+(?:esi|edi|ebx|ebp|eax|edx),\s*ecx|push\s+ecx|mov\s+(?:dword ptr\s*)?\[[^\]]+\],\s*ecx)", + close, + ) + if not ecx_preserved: + print("lua_close callback snippet:") + print(close) + raise SystemExit("ABI validation failed: lua_close callback does not preserve L from ECX") # Native helper ABI observed directly in WoW 5875: # lua_gc_remove_objects: ECX=L, EDX=&list, stack arg all=0. @@ -89,10 +100,9 @@ jobs: "rootudata lua_gc_remove_objects ABI", ) - # B2 also calls lua_gc_remove_objects through a runtime link address; - # require at least one call site with ECX loaded from L and EDX nonzero. + # At least one dynamic-list remove call must load L into ECX. require( - r"mov\s+eax,\s*0x6f7210.{0,220}?mov\s+ecx,\s*e[a-z]{2}.{0,180}?call\s+eax", + r"mov\s+eax,\s*0x6f7210.{0,240}?mov\s+ecx,\s*e[a-z]{2}.{0,200}?call\s+eax", "chunk lua_gc_remove_objects fastcall callsite", ) @@ -118,6 +128,7 @@ jobs: sha256sum "$DLL" | tee SHA256SUMS.txt - uses: actions/upload-artifact@v4 + if: always() with: name: WeirdPerformance-2.4-B2-GC-InPlace-Safe-Sweep path: | @@ -125,4 +136,4 @@ jobs: experiments/wp24b-gc/SHA256SUMS.txt experiments/wp24b-gc/BINARY_INFO.txt experiments/wp24b-gc/ABI_DISASM.txt - if-no-files-found: error + if-no-files-found: warn