Skip to content

JIT: find the GC runtime next to tslang, and say so when it is missing - #633

Merged
ASDAlexander77 merged 3 commits into
mainfrom
jit-runtime-next-to-tslang
Oct 21, 2026
Merged

ASDAlexander77 merged 3 commits into
mainfrom
jit-runtime-next-to-tslang

Conversation

@ASDAlexander77

Copy link
Copy Markdown
Owner

Problem

Running the alpha105 package's JIT from a project folder on Linux (a VS Code GDB launch with cwd = ${workspaceFolder}) failed mid-run:

tslang: symbol lookup error: .../defaultlib/dll/x86_64/unknown/linux/gnu/debug/gc/libTypeScriptDefaultLib.so: undefined symbol: GC_malloc

The JIT looked for libTypeScriptRuntime only in --tslang-lib-path/TSLANG_LIB_PATH, ../lib relative to the current folder, and the current folder. It never looked in tslang's own folder, which is where the package ships it. When it found nothing it carried on without the runtime and printed nothing (the error was commented out). #632's load-order fix only helps when the runtime is found.

Change (tslang/tslang/jit.cpp)

  • After the existing places, tslang also looks in its own folder (the release package; the Windows build's bin) and in ../lib beside tslang (the Linux build tree).
  • Under -mm=gc, finding no runtime is now an error that names the file and says how to pass it (--tslang-lib-path or --shared-libs). Before, the run failed later on an unresolved GC_* symbol.

Test (defaultlib-collector.cmake, Linux JIT)

A hard-linked tslang in a folder laid out like the package, run from another folder with no --tslang-lib-path:

  • without the runtime next to it, tslang refuses with the new error
  • with the runtime copied next to it, the program runs (bad: 0)

Verified

  • Windows Release: 4859/4859 passed.
  • WSL Ubuntu Release, with DEFAULT_LIB_PATH set to the alpha105 package's default library: 4838/4838 passed, including test-jit-gc-defaultlib-collector and its new runs.
  • The original failure reproduced against the deployed alpha105 package, and --tslang-lib-path fixed it.

Note: under -mm=gc a missing runtime is reported before lowering, so it comes ahead of any lowering error in the program. That is why ../lib beside tslang is searched, so the Linux build tree's own tests find the runtime.

🤖 Generated with Claude Code

ASDAlexander77 and others added 3 commits October 21, 2026 20:08
The JIT looked for TypeScriptRuntime in --tslang-lib-path, ../lib and the
current folder, never in tslang's own folder - where the release package puts
it. Run from a project folder (a VS Code launch with cwd = workspace) it found
none and went on without one, so on Linux the default library failed mid-run
with "symbol lookup error: ... undefined symbol: GC_malloc".

tslang's own folder is now the last place it looks, and -mm=gc with no runtime
anywhere is an error naming the file and the two ways to pass it.

The Linux collector test runs a hard-linked tslang from a package-like folder
with no --tslang-lib-path: refused without the runtime next to it, passing with.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ge folder

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ld layout)

Without it, a JIT run in the Linux build tree with no runtime passed stopped on
the missing-runtime error before lowering could report the program's own error
(test-jit-main-argv-string-array-error).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@ASDAlexander77
ASDAlexander77 merged commit 49b5f6b into main Oct 21, 2026
2 checks passed
@ASDAlexander77
ASDAlexander77 deleted the jit-runtime-next-to-tslang branch October 21, 2026 20:06
ASDAlexander77 added a commit that referenced this pull request Oct 23, 2026
A global, or a global's field, given to a call as a view - an interface,
a base class, an object literal holding it - and given a new value by a
later argument of the same call (`f(G, (G = mk(), x))` with an interface
parameter, `f({ v: G.v }, (G = mk(), x))`) was freed before the call ran.

The view is made at the call, after every argument is evaluated, and
holdGlobalArguments did not see through it: `globalOf` stopped at
`ts.NewInterface`, and an object literal holds what it was given with no
count until it is boxed for the interface, at the call too. Under rc the
hold now keeps the value behind the view - the object a cast or an
interface is made over, or each value stored into the literal's slot -
retained where it is read (#647). The fuzzer (#646) found these as A1's
view variant; they failed on #633 as well.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant