This is an automated email from the ASF dual-hosted git repository.

tqchen pushed a commit to branch orcjit-windows-arm64-855
in repository https://gitbox.apache.org/repos/asf/tvm-ffi.git

commit 0d7f39be7d4ca077f9979ae2bc7579060e764ca3
Author: Tianqi Chen <[email protected]>
AuthorDate: Mon Oct 26 03:51:54 2026 +0000

    [TEST] Cover ARM64 CRT recovery after object link failure
---
 addons/tvm_ffi_orcjit/README.md           |  2 +-
 addons/tvm_ffi_orcjit/tests/test_basic.py | 61 +++++++++++++++++++++++++++++++
 2 files changed, 62 insertions(+), 1 deletion(-)

diff --git a/addons/tvm_ffi_orcjit/README.md b/addons/tvm_ffi_orcjit/README.md
index 06c087dc..0a3b491b 100644
--- a/addons/tvm_ffi_orcjit/README.md
+++ b/addons/tvm_ffi_orcjit/README.md
@@ -198,7 +198,7 @@ Compile: `clang -O2 -c -o example.o example.c`
 - **DLL Imports** (Windows): A custom `DefinitionGenerator` resolves host
   process symbols from loaded DLLs. AMD64 uses JITLink pointer and jump stubs;
   ARM64 uses RuntimeDyld's native import slots and branch stubs.
-- **SEH Stripping** (Windows): `ObjectTransformLayer` strips `.pdata`/`.xdata`
+- **SEH Stripping** (Windows AMD64): `ObjectTransformLayer` strips 
`.pdata`/`.xdata`
   relocations from COFF objects. C++ exception handling on Windows remains
   unsupported on both architectures.
 
diff --git a/addons/tvm_ffi_orcjit/tests/test_basic.py 
b/addons/tvm_ffi_orcjit/tests/test_basic.py
index b2f82700..52f8ecc2 100644
--- a/addons/tvm_ffi_orcjit/tests/test_basic.py
+++ b/addons/tvm_ffi_orcjit/tests/test_basic.py
@@ -25,6 +25,8 @@ the module tears the dylib down.
 from __future__ import annotations
 
 import gc
+import platform
+import shutil
 import sys
 import tempfile
 import threading
@@ -487,6 +489,65 @@ def test_ctor_dtor(v: Variant) -> None:
         assert "<dtors>" not in log
 
 
[email protected](
+    sys.platform != "win32" or platform.machine().lower() not in ("arm64", 
"aarch64"),
+    reason="RuntimeDyld COFF lifecycle recovery is specific to Windows ARM64",
+)
+def test_failed_materialization_does_not_retain_crt_callbacks(
+    tmp_path: Path, monkeypatch: pytest.MonkeyPatch
+) -> None:
+    """A failed object cannot leave callbacks in the next module's 
lifecycle."""
+    compiler = shutil.which("clang-cl")
+    if compiler is None:
+        pytest.skip("clang-cl is unavailable")
+    monkeypatch.setenv("CC", compiler)
+    source = Path(__file__).parent / "sources" / "c" / "test_ctor_dtor.c"
+    failing_source = tmp_path / "failed_ctor.c"
+    failing_source.write_text(
+        source.read_text().replace(
+            "static void puts_log(const char* msg) {",
+            "extern void tvm_ffi_test_unresolved_symbol(void);\n"
+            "static void puts_log(const char* msg) {\n"
+            "  tvm_ffi_test_unresolved_symbol();",
+        )
+    )
+    failed_obj = tvm_ffi.cpp.build(
+        name="failed_ctor",
+        sources=[str(failing_source)],
+        output="failed_ctor.o",
+        extra_cflags=["/GS-"],
+        build_directory=str(tmp_path / "build"),
+    )
+    log: list[str] = []
+
+    @tvm_ffi.register_global_func("append_log", override=True)
+    def append_ctor_log(value: str) -> None:
+        log.append(value)
+
+    session = ExecutionSession()
+    failed = None
+    with pytest.raises(Exception, match="Failed to materialize|Symbols not 
found"):
+        failed = session.load_module(failed_obj)
+        failed.get_function("main")
+    del failed
+    gc.collect()
+    assert log == []
+
+    mod = load("c/test_ctor_dtor", session=session)
+    mod.get_function("main")()
+    del mod
+    gc.collect()
+    assert log == [
+        "<crt.XCA>",
+        "<crt.XCB>",
+        "<crt.XCC>",
+        "<crt.XCU>",
+        "<main>",
+        "<crt.XTA>",
+        "<crt.XTZ>",
+    ]
+
+
 @pytest.mark.skipif(
     sys.platform == "linux",
     reason="ELFNixPlatform completes initialization before load_module 
returns",

Reply via email to