Skip to content

Support re-exporting source-phase imports#2490

Merged
lahma merged 1 commit into
sebastienros:mainfrom
lahma:source-phase-import-reexport
Jun 1, 2026
Merged

Support re-exporting source-phase imports#2490
lahma merged 1 commit into
sebastienros:mainfrom
lahma:source-phase-import-reexport

Conversation

@lahma

@lahma lahma commented Jun 1, 2026

Copy link
Copy Markdown
Collaborator

Follow-up to #2489. Implements the module-system plumbing for re-exporting a source-phase import (import source x from "..."; export { x };) so the three test files that #2489 had to exclude now pass, leaving only one (upstream-buggy) exclusion from that update.

Note: this branch is stacked on #2489 (the test262 bump), so until that merges the diff here also shows its commit. Review the Support re-exporting source-phase imports commit.

What this enables

Per test262's INTERPRETING.md, the host is expected to resolve the <module source> specifier to a module exposing a [[ModuleSource]] (WebAssembly being the canonical example). Jint has no WebAssembly support, so the test harness supplies a synthetic module source — the sanctioned approach — and the engine gains the general source-phase re-export semantics.

Engine changes (all internal, one new protected virtual hook)

  • Module gains an internal [[ModuleSource]] slot (null for ordinary modules).
  • ModuleLoader exposes protected virtual ObjectInstance? GetModuleSource(engine, resolved) (default null); LoadModule attaches its result. With the default, a source-phase import of an ordinary JS module still rejects (so import-source.js keeps passing).
  • SourceTextModule.InitializeEnvironment binds a direct import source x to the imported module's [[ModuleSource]] (TypeError if absent — the host-defined non-SyntaxError rejection import-source.js asserts).
  • Re-export: HoistingScope reclassifies export { x } of a source-phase import as an indirect export with a "*source*" import name; ResolveExport returns a "*source*" binding; InitializeEnvironment binds it to [[ModuleSource]] (SyntaxError if absent); ModuleNamespace.[[Get]] returns [[ModuleSource]] (ReferenceError if absent).

Test harness

Test262ModuleLoader resolves <module source> to a trivial module and overrides GetModuleSource to return an object whose prototype is $262.AbstractModuleSource.prototype, satisfying x instanceof $262.AbstractModuleSource. The three exclusions are removed from Test262Harness.settings.json.

Verification

Full test262 suite: 0 failures, 99208 passed (+3 vs #2489), no module/defer/namespace regressions; import-source.js still passes. Jint.Tests module suite and Jint.Tests.PublicInterface are green.

Not addressed here

built-ins/TypedArray/prototype/slice/speciesctor-return-same-buffer-with-offset.js stays excluded — it is an upstream test262 bug (commit 21513be91f): it runs the immutable-buffer arg factory while expecting a write into an immutable buffer to succeed, contradicting %TypedArray%.prototype.slice step 13/14 of proposal-immutable-arraybuffer (the species destination is created with ~write~ and must be non-immutable). The exclusion comment documents this; it will be reported upstream.

🤖 Generated with Claude Code

Implements the spec plumbing for `import source x from "..."; export { x };`
so the three previously-excluded module tests pass:
- language/module-code/source-phase-import/reexport-source-binding-named-import.js
- language/module-code/source-phase-import/reexport-source-binding-namespace-get.js
- language/module-code/ambiguous-export-bindings/namespace-unambiguous-if-import-source-and-export.js

A module record now carries an internal [[ModuleSource]] slot (Module.cs).
ModuleLoader exposes a `protected virtual GetModuleSource` hook (default null,
so an ordinary JS module still rejects a source-phase import); LoadModule
attaches its result. SourceTextModule.InitializeEnvironment binds a direct
`import source x` to the imported module's [[ModuleSource]] (TypeError when
absent, preserving import-source.js). Re-export is reclassified in
HoistingScope as an indirect export with a "*source*" import name; ResolveExport
returns a "*source*" binding, InitializeEnvironment binds it to [[ModuleSource]]
(SyntaxError when absent), and ModuleNamespace.[[Get]] returns [[ModuleSource]]
(ReferenceError when absent).

The test harness (Test262ModuleLoader) resolves the test262 `<module source>`
specifier to a trivial module and overrides GetModuleSource to return an object
whose prototype is $262.AbstractModuleSource.prototype, matching INTERPRETING.md's
guidance that the host supplies a module source (Jint has no WebAssembly).

The slice/speciesctor-return-same-buffer-with-offset.js exclusion remains: it is
an upstream test262 bug (commit 21513be91f) that runs the immutable-buffer factory
while expecting a write to succeed, which a spec-correct slice rejects. The
exclusion comment documents this for an upstream report.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@lahma
lahma force-pushed the source-phase-import-reexport branch from 5e5756a to 93c1704 Compare June 1, 2026 19:05
@lahma
lahma enabled auto-merge (squash) June 1, 2026 19:07
@lahma
lahma merged commit 82d0cf4 into sebastienros:main Jun 1, 2026
4 checks passed
@lahma
lahma deleted the source-phase-import-reexport branch June 7, 2026 07:22
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