diff --git a/runtime/CMakeLists.txt b/runtime/CMakeLists.txt index 46c476a3..9b74e42c 100644 --- a/runtime/CMakeLists.txt +++ b/runtime/CMakeLists.txt @@ -393,6 +393,15 @@ if(BUILD_TESTING) include ../recompiler/lib/toml11) target_link_libraries(mod_runtime_test PRIVATE chdr-static) + # The real disc hasher uses a 1 MiB scratch buffer. Match the runtime's + # stack allowance instead of overflowing MinGW's 1 MiB executable default. + if(WIN32) + if(MSVC) + target_link_options(mod_runtime_test PRIVATE /STACK:16777216) + else() + target_link_options(mod_runtime_test PRIVATE -Wl,--stack,16777216) + endif() + endif() add_test(NAME mod_runtime_test COMMAND mod_runtime_test) if(WIN32) diff --git a/runtime/tests/test_dirty_text_continuation_guards.py b/runtime/tests/test_dirty_text_continuation_guards.py index 56aa21ea..751fef44 100644 --- a/runtime/tests/test_dirty_text_continuation_guards.py +++ b/runtime/tests/test_dirty_text_continuation_guards.py @@ -18,13 +18,15 @@ def main() -> int: required_range_fragments = ( "uint32_t exec_pc", - "if (phys + len <= at) continue;", - "len -= at - phys;", + "(void)exec_pc;", + "memcmp(ram + phys, text_ref_image + (phys - text_ref_lo), len)", "if (!any)", ) for fragment in required_range_fragments: if fragment not in range_guard: raise AssertionError(f"missing continuation range guard: {fragment}") + if "len -= at - phys;" in range_guard or "if (phys + len <= at) continue;" in range_guard: + raise AssertionError("continuation guard clips away code reachable by a backward edge") if "text_diverged_bitmap" in range_guard: raise AssertionError("exact-range mismatch still sticky-poisons a whole page") if "dirty_ram_text_native_ok_ranges_from(lo_len_pairs, count, 0u)" not in memory: diff --git a/runtime/tests/test_launcher_vulkan_option.py b/runtime/tests/test_launcher_vulkan_option.py index ad460ece..06d51d37 100644 --- a/runtime/tests/test_launcher_vulkan_option.py +++ b/runtime/tests/test_launcher_vulkan_option.py @@ -2,10 +2,10 @@ from pathlib import Path root = Path(__file__).resolve().parents[2] -main = (root / "runtime" / "src" / "main.cpp").read_text() -config_h = (root / "recompiler" / "src" / "config_loader.h").read_text() -config_cpp = (root / "recompiler" / "src" / "config_loader.cpp").read_text() -runtime_cmake = (root / "runtime" / "runtime.cmake").read_text() +main = (root / "runtime" / "src" / "main.cpp").read_text(encoding="utf-8") +config_h = (root / "recompiler" / "src" / "config_loader.h").read_text(encoding="utf-8") +config_cpp = (root / "recompiler" / "src" / "config_loader.cpp").read_text(encoding="utf-8") +runtime_cmake = (root / "runtime" / "runtime.cmake").read_text(encoding="utf-8") assert "runtime/" + "launcher" not in runtime_cmake assert "Rml" + "Ui" not in runtime_cmake diff --git a/runtime/tests/test_overlay_pair_dedup_runtime.py b/runtime/tests/test_overlay_pair_dedup_runtime.py index 957dfba8..187d8612 100644 --- a/runtime/tests/test_overlay_pair_dedup_runtime.py +++ b/runtime/tests/test_overlay_pair_dedup_runtime.py @@ -7,10 +7,11 @@ import argparse import os import pathlib import platform -import re import shutil import subprocess +import sys import tempfile +from unittest.mock import patch import zlib @@ -23,21 +24,12 @@ RESIDENT = "psxrecomp bios resident shard v1\n" def codegen_leaf() -> str: - api = (RUNTIME / "include" / "overlay_api.h") - hash_header = (RUNTIME / "include" / "overlay_codegen_hash.h") - version = "0" - code_hash = "00000000" - if api.is_file(): - match = re.search(r"PSX_OVERLAY_CODEGEN_VER\s+(\d+)", - api.read_text(encoding="utf-8")) - if match: - version = match.group(1) - if hash_header.is_file(): - match = re.search(r"PSX_OVERLAY_CODEGEN_HASH\s+0x([0-9A-Fa-f]{8})", - hash_header.read_text(encoding="utf-8")) - if match: - code_hash = match.group(1).lower() - return f"cg{version}_{code_hash}_gc00000000_f0" + sys.path.insert(0, str(ROOT / "tools")) + import compile_overlays + # The synthetic loader uses a zero config hash; serialize its namespace + # with the production owner so new namespace fields cannot go stale here. + with patch.object(compile_overlays, "overlay_config_hash", return_value=0): + return compile_overlays.cache_tag(str(RUNTIME / "include"), "", "") def arch_abi() -> str: diff --git a/runtime/tests/test_release_zip.py b/runtime/tests/test_release_zip.py index 2431963a..73131af2 100644 --- a/runtime/tests/test_release_zip.py +++ b/runtime/tests/test_release_zip.py @@ -16,8 +16,8 @@ with tempfile.TemporaryDirectory() as temporary: stage = base / "stage" (stage / "mods" / "package").mkdir(parents=True) (stage / "Tomba Recompiled.exe").write_bytes(b"exe") - (stage / "mods" / "package" / "manifest.toml").write_text( - 'id = "test"\n', encoding="utf-8" + (stage / "mods" / "package" / "manifest.toml").write_bytes( + b'id = "test"\n' ) output = base / "release.zip" subprocess.run(