diff --git a/.github/workflows/test-safe-core-v8.yml b/.github/workflows/test-safe-core-v8.yml index e34c521..942b764 100644 --- a/.github/workflows/test-safe-core-v8.yml +++ b/.github/workflows/test-safe-core-v8.yml @@ -184,6 +184,47 @@ jobs: print("outline.dll machine code: registration and callback ABIs verified") PY + - name: Verify UnitGUID native ECX ABI + shell: bash + run: | + set -euo pipefail + python3 - <<'PY' + from pathlib import Path + src = Path("src/wow.zig").read_text() + for required in ( + 'pub fn unitGUID', + 'callconv(.{ .x86_thiscall = .{} }) u64', + '@call(.never_tail, f_native, .{unit_id})', + ): + if required not in src: + raise SystemExit(f"Missing UnitGUID ABI fix piece: {required}") + print("source: UnitGUID uses native ECX ABI") + PY + + objdump -d -Mintel zig-out/variants/outline.dll > /tmp/outline.disasm + python3 - <<'PY' + import re + from pathlib import Path + + lines = Path("/tmp/outline.disasm").read_text(errors="replace").splitlines() + sites = [] + for i, line in enumerate(lines): + if re.search(r"mov\s+eax,0x0*515970\b", line, re.I): + block = "\n".join(lines[max(0, i - 5):i + 5]) + sites.append(block) + if re.search(r"push\s+0x[0-9a-f]+\s*\n\s*[0-9a-f]+:.*call\s+eax", block, re.I): + raise SystemExit("BAD ABI: UnitGUID argument is still pushed on stack") + if not re.search(r"mov\s+ecx,", block, re.I): + raise SystemExit("BAD ABI: UnitGUID call does not prepare ECX") + + if not sites: + raise SystemExit("Could not find UnitGUID call sites in outline.dll") + + print(f"UnitGUID machine code: {len(sites)} call site(s), ECX ABI verified") + for block in sites: + print(block) + PY + - name: Stage package shell: bash run: | @@ -202,7 +243,7 @@ jobs: cat > package/README_TEST.txt <<'EOF' WeirdUtils Safe Standalone Core Test V8 - This build fixes both x86 ABIs: FrameScript_RegisterFunction gets name in ECX + callback in EDX, and OutlineCommand receives the Lua state in ECX. WoW Lua API calls stay on explicit native register wrappers. + This build fixes the x86 ABIs used by the standalone Outline path: FrameScript_RegisterFunction gets name in ECX + callback in EDX, OutlineCommand receives Lua state in ECX, and UnitGUID receives its unit id in ECX without leaking stack space. WoW Lua API calls stay on explicit native register wrappers. outline.dll - Keeps only the Player_LoadScriptFunctions hook required to register OutlineCommand.