eval() support + co-locate SharpTS.dll only when needed (#107)#115
Merged
Conversation
added 2 commits
June 5, 2026 22:34
Register `eval` as a global typed `(s: string) => any` (identifier + call
paths), removing the categorical TypeCheckError floor that blocked any
program referencing eval.
Interpreted: direct eval — Interpreter.Eval() lexes/parses/interprets the
source against the caller's scope chain and returns the completion value.
Not type-checked (matches tsc); non-string args returned unchanged
(ECMA-262 19.2.1); parse failures throw SyntaxError.
Compiled: indirect eval via EvalBridge in the SharpTS runtime, invoked
through the Type.GetType("...,SharpTS") reflection pattern so the output
DLL keeps no hard SharpTS reference. Global builtins resolve; compiled
locals are not visible. Degrades to a deterministic "eval not supported"
throw when SharpTS.dll is absent. GlobalFunctionHandler added to the
standalone-DLL late-binding allowlist.
Tests: EvalTests covers both modes (whitespace tolerance, completion
values, non-string passthrough, var decls, builtin calls) plus an
interpreter-only direct-eval local-capture case.
Add a semantic "needs-SharpTS-at-runtime" signal so compiled output gains
the SharpTS.dll soft dependency only when it actually uses a feature whose
normal execution late-binds into the runtime — and stays fully standalone
otherwise. A byte-scan for "...,SharpTS" is too coarse: the unconditional
`process` helper bakes that string into every DLL, yet a trivial program
runs fine without SharpTS present.
Mechanism:
- EmittedRuntime.RequiredSharpTSRuntimeReasons + RequireSharpTSRuntime(reason),
surfaced via ILCompiler.RequiredSharpTSRuntimeReasons (one set per compile).
- Recorded at the gates/call sites that emit a reachable Type.GetType("...,
SharpTS"): eval (call site), Proxy / Intl / vm / dns (orchestrator gates),
@DotNetType dynamic-event reflected path.
- Deliberately NOT recorded for pure-BCL features (zlib, child_process, JSON)
or unconditional graceful-fallback plumbing (process).
- Program.cs CopySharpTSRuntimeIfNeeded copies SharpTS.dll next to the output
after Save when the reason set is non-empty, printing the reasons.
- New `--compile --standalone` flag suppresses the copy (those features then
throw their clear "not supported" error at runtime).
Known gaps (follow-ups): AbortSignal.any late-binds but is gated only at the
coarse UsesAbortController level, so it is left unflagged to avoid penalizing
common AbortController+fetch use; the -t exe and NuGet packaging paths do not
yet consume this signal.
Tests: RuntimeDependencySignalTests asserts trivial=empty, eval/Proxy/Intl
flagged, and eval does not false-positive other features. Docs updated in
CLAUDE.md (standalone-DLL section) and STATUS.md (eval entry).
This was referenced Jun 6, 2026
Test262 #8: eval(...) rejected in property-accessors and elsewhere (~10+ tests, broader impact)
#107
Closed
Owner
Author
|
Follow-ups for the runtime-copy mechanism (out of scope for this PR), now tracked:
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Two related changes:
eval()support (closes Test262 #8: eval(...) rejected in property-accessors and elsewhere (~10+ tests, broader impact) #107) — real eval in both execution modes.SharpTS.dllwith compiled output only when a feature actually needs it at runtime.1. eval() (#107)
evalis now registered as a global typed(s: string) => any(identifier + call paths), removing the categoricalTypeCheckErrorfloor that blocked any program referencing eval.Interpreter.Eval()lexes/parses/interprets the source against the caller's scope chain and returns the completion value. Not type-checked (matches tsc); non-string args returned unchanged (ECMA-262 §19.2.1); parse failures throwSyntaxError.EvalBridgein the SharpTS runtime, invoked through theType.GetType("…,SharpTS")reflection pattern so the output DLL keeps no hard SharpTS reference. Global builtins resolve; compiled locals are not visible (no live interpreter behind native IL). Degrades to a deterministic "eval not supported" throw when SharpTS.dll is absent.Acceptance verified
The issue's criterion — the property-accessor eval tests move off
TypeCheckError— is confirmed:test/language/expressions/property-accessors/S11.2.1_A1.1.jsnow passes all 9 Unicode-whitespace checks (TAB, VT, FF, SP, NBSP, LF, CR, LS, PS) in both interpreted and compiled modes (TypeCheckError → Pass).2. Co-locate SharpTS.dll only when needed
Some features (eval, Proxy, Intl, vm, dns,
@DotNetTypedynamic events) emit aType.GetType("…,SharpTS")path whose normal execution needs SharpTS.dll present. A byte-scan for,SharpTSis too coarse — the unconditionalprocesshelper bakes that string into every DLL, yet a trivial program runs fine standalone. So this adds a semantic signal:EmittedRuntime.RequiredSharpTSRuntimeReasons+RequireSharpTSRuntime(reason), surfaced viaILCompiler.RequiredSharpTSRuntimeReasons(one set per compilation).process).Program.cscopiesSharpTS.dllnext to the output afterSaveonly when the reason set is non-empty — programs using none of these stay fully standalone.--compile … --standaloneflag suppresses the copy (those features then throw their clear "not supported" error at runtime).Verified end-to-end
evalprogram →Copied SharpTS.dll … required at runtime by: eval(); co-located DLL runs.Proxyprogram → copy with reasonProxy; runs.--standalone→ note printed, no copy.Tests
EvalTests— both modes (whitespace tolerance, completion values, non-string passthrough, var decls, builtin calls) + an interpreter-only direct-eval local-capture case.RuntimeDependencySignalTests— trivial = empty reasons; eval/Proxy/Intl flagged; eval does not false-positive other features.PackagingTests.Pack_WithoutPackageJson_*failures remain (confirmed failing at baselinemain, unrelated). Standalone-DLL guard green.Known limitations / follow-ups (not in scope here)
AbortSignal.anylate-binds but is gated only at the coarseUsesAbortControllerlevel, so it's left unflagged to avoid penalizing common AbortController + fetch use.-t exeand NuGet packaging paths don't yet consume the runtime-dependency signal.Closes #107.