From 18e303658398ad47b5991c30f31c86e95f2eb467 Mon Sep 17 00:00:00 2001 From: ASDAlexander77 Date: Tue, 20 Oct 2026 23:50:34 +0100 Subject: [PATCH] --jit-native: say why it still links the static default library #630 made --emit=dll read the default library's data through `__imp_`, but that does not carry over to --jit-native. Its DLL links the JIT cache's objects, which are compiled for the JIT's static large code model, and x86 codegen gives a dllimport global no `__imp_` reference under that model (X86Subtarget::classifyGlobalReference). Checked: with the data marked dllimport for JIT objects too, the in-memory JIT still runs, but the objects keep plain `Math.PI` references and the DLL link fails without the static default library. The comment and the design doc said this was the same bug as --emit=dll; they now give the actual reason. Co-Authored-By: Claude Opus 5.5 --- tslang/docs/jit-native-dll-debugging-design.md | 7 +++++-- tslang/tslang/jitnative.cpp | 3 +++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/tslang/docs/jit-native-dll-debugging-design.md b/tslang/docs/jit-native-dll-debugging-design.md index d422c8df3..aae64962c 100644 --- a/tslang/docs/jit-native-dll-debugging-design.md +++ b/tslang/docs/jit-native-dll-debugging-design.md @@ -149,8 +149,11 @@ quality for TS code, which AOT shares, not something this mode adds. With the import library the link fails as soon as the program reads data the default library defines. A `Map` reads `PrimeHelpers.hashCollisionThreshold` by its own name, and only an `__imp_` reference resolves a DLL's data export. The in-memory JIT binds it from the export - table. `--emit=dll` has the same failure today (a separate bug). So in this mode tslang loads - neither the default library's DLL nor `TypeScriptRuntime.dll`. + table. `--emit=dll` had the same failure, and #630 fixed it by marking that data dllimport. + That fix does not carry over here. The DLL links the JIT cache's objects, which are compiled for + the JIT's static large code model, and x86 codegen emits no `__imp_` reference under that model + even for a dllimport global (`X86Subtarget::classifyGlobalReference`). So in this mode tslang + loads neither the default library's DLL nor `TypeScriptRuntime.dll`. - **The DLL and its PDB** are `__jit/..dll` and `.pdb`, linked under a temporary name, `/PDB:` the final name with `/PDBALTPATH:%_PDB%`, then renamed. `.lib` and `.exp` are removed. The DLLs of earlier runs of the same program are removed, and so are temporary files more than an diff --git a/tslang/tslang/jitnative.cpp b/tslang/tslang/jitnative.cpp index e1614b02f..bb4aef58c 100644 --- a/tslang/tslang/jitnative.cpp +++ b/tslang/tslang/jitnative.cpp @@ -301,6 +301,9 @@ int linkJitUnits(const char *argv0, llvm::ArrayRef units, CompileOption // but not for its data: a static field the program reads (a generic's instantiation reading // PrimeHelpers.hashCollisionThreshold, say) is referenced by its own name, which only an // `__imp_` reference resolves to an import. The in-memory JIT binds it from the export table. + // Marking the data dllimport, as --emit=dll does, does not help here: these are the JIT's + // objects, compiled for the static large code model, and x86 codegen gives a dllimport global + // no `__imp_` reference under that model (X86Subtarget::classifyGlobalReference). request.staticDefaultLib = true; request.quiet = true; request.extraArgs.push_back("-Wl,/INCREMENTAL:NO");