Skip to content

Commit f1135ff

Browse files
committed
feat(module): implement dynamic import
1 parent 3a9fdd2 commit f1135ff

26 files changed

Lines changed: 3792 additions & 293 deletions

.github/workflows/ci.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ jobs:
6868
./scripts/check-no-test262-special-casing.sh
6969
node scripts/check-test262-artifact-inventory.mjs
7070
node --check scripts/test-negative-diagnostic-generator.mjs
71+
node --check scripts/generate-test262-dynamic-import-a.mjs
7172
node --check scripts/generate-test262-module-import-attributes-a.mjs
7273
node --check scripts/test-generate-test262-module-import-attributes-a.mjs
7374
node --check scripts/generate-test262-module-json-a.mjs
@@ -151,6 +152,8 @@ jobs:
151152
QJS_ORACLE_ARCHIVE="$QJS_ORACLE_CACHE/quickjs-2026-06-04.tar.xz" \
152153
./scripts/test-quickjs-dynamic-import-trace.sh
153154
suite=$(./scripts/prepare-test262.sh)
155+
node scripts/generate-test262-dynamic-import-a.mjs \
156+
--suite "$suite" --check-current
154157
node scripts/audit-negative-diagnostics.mjs \
155158
--contracts dev-support/test262/negative-diagnostics.tsv \
156159
--rules dev-support/test262/negative-diagnostic-rules.tsv \

README.md

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,11 @@ include binary data and Atomics, collections and weak references, Promise jobs,
88
Unicode behavior, public/private class fields and private callable elements,
99
and synchronous static-module graphs with default exports, live namespace
1010
objects, static import attributes, JSON synthetic modules, and core
11-
`import.meta` semantics. Dynamic import, top-level await, JSON5/byte-oriented
12-
host loading, and QuickJS host-populated `import.meta` properties remain parity
13-
work.
11+
`import.meta` semantics. Script-goal dynamic `import()` includes FIFO-job host
12+
loading, import attributes, namespace reuse, and cycle-root evaluation
13+
Promises. Top-level await, JavaScript-valued module-host errors,
14+
JSON5/byte-oriented loading, and host-populated `import.meta` properties remain
15+
parity work.
1416

1517
<!-- current-test262-metrics:start -->
1618
The authoritative R3ep Test262 baseline records **79,462 full-corpus passes

dev-support/test262/README.md

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,23 @@ by a shell.
1111
The focused manifest is a sorted set of source paths. Its receipt remains a
1212
full `(path, variant)` vector, so one path may produce multiple metadata-driven
1313
variants. The current R3ep vector includes the source-authenticated static JSON
14-
module graph; dynamic import and text modules remain excluded by generator
15-
canaries.
14+
module graph. A staged dynamic-import Script-goal cohort is authenticated
15+
separately and enters the frozen result vector only after a full-run promotion;
16+
text modules remain excluded by generator canaries.
1617

1718
`admissions.tsv` is the hash-pinned source of exact Module-goal graphs,
18-
dependency-free module roots, `$262.agent` host paths, and supplemental feature
19-
contracts. Its strict 16-column TSV schema records source hashes, complete
20-
metadata shapes, graph edges and closure sizes, lookup priority, and host
21-
cohort policy. Both coordinator and isolated worker parse and authenticate the
22-
same file; malformed, unsorted, duplicate, open-graph, or checksum-drifted data
23-
fails closed. The six cohort generators emit `--admissions` rows and compare
24-
their owned group against this file in normal check mode.
19+
dynamic-import Script-goal graphs, dependency-free module roots, `$262.agent`
20+
host paths, and supplemental feature contracts. Its strict 16-column TSV
21+
schema records source hashes, complete metadata shapes, graph edges and closure
22+
sizes, lookup priority, execution goal, and host cohort policy. Every
23+
`dynamic-import-root` also declares its initial bytecode expectation: an
24+
`initial-import-tree` must already contain the authenticated import opcode,
25+
while `runtime-compiled-import` authorizes a later runtime compilation and
26+
requires the initial tree not to contain it. A missing or unknown policy fails
27+
closed. Both coordinator and isolated worker parse and authenticate the same
28+
file; malformed, unsorted, duplicate, open-graph, mixed-goal, or
29+
checksum-drifted data fails closed. The cohort generators emit `--admissions`
30+
rows and compare their owned group against this file in normal check mode.
2531

2632
`negative-diagnostics.tsv` is a strict, source-authenticated overlay for
2733
negative variants whose QuickJS failure reason and location are part of the

dev-support/test262/admissions.tsv

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,16 @@ agent agent-host test/built-ins/Atomics/wait/wait-index-value-not-equal.js 0c210
5858
agent agent-host test/built-ins/Atomics/wait/waiterlist-block-indexedposition-wake.js 87e398dbfc8e4022331380d67325a2da98dea734dfed11158ab0e34e0f417ab3 - - Atomics,SharedArrayBuffer,TypedArray - - - - - - - - Test262 agent wake/count/location cohort
5959
agent agent-host test/built-ins/Atomics/wait/waiterlist-order-of-operations-is-fifo.js 6503e1b20e4c55d661c165020ee7b83a3cd35326fed0211358df41b67b2adda1 - - Atomics,SharedArrayBuffer,TypedArray - - - - - - - - Test262 agent FIFO wake-order cohort
6060
agent agent-host test/built-ins/Atomics/wait/was-woken-before-timeout.js d97f474e3fe55e36d6475ef88653ce4e4b203e638d2f28f5547f9c2b30784d2a - - Atomics,SharedArrayBuffer,TypedArray - - - - - - - - Test262 agent wake/count/location cohort
61+
dynamic-import-root dynamic-import-a test/language/expressions/dynamic-import/always-create-new-promise.js - - - - - - 2 0 - - - initial-import-tree -
62+
dynamic-import-root dynamic-import-a test/language/expressions/dynamic-import/assign-expr-get-value-abrupt-throws.js - - - - - - 1 0 - - - initial-import-tree -
63+
dynamic-import-root dynamic-import-a test/language/expressions/dynamic-import/reuse-namespace-object.js - - - - - - 2 0 - - - initial-import-tree -
64+
dynamic-import-root dynamic-import-a test/language/expressions/dynamic-import/usage/top-level-import-then-returns-thenable.js - - - - - - 2 0 - - - initial-import-tree -
65+
graph-file dynamic-import-a test/language/expressions/dynamic-import/always-create-new-promise.js e11f060801c828fbd99052aeb90eb4fa94420eed9ddf5530983decd121420cc1 - - dynamic-import - - - - - - - - -
66+
graph-file dynamic-import-a test/language/expressions/dynamic-import/assign-expr-get-value-abrupt-throws.js e856975950b76ebdd1447bd273f4a7e07485333a6fe1d82e356582577f732b23 - - dynamic-import - - - - - - - - -
67+
graph-file dynamic-import-a test/language/expressions/dynamic-import/dynamic-import-module_FIXTURE.js 08bd41ffb3fbbfe3a33b50b66d0ca03f6266e5a4468cafc266eb109c15d7a261 - - - - - - - - - - - -
68+
graph-file dynamic-import-a test/language/expressions/dynamic-import/reuse-namespace-object.js aa09ffc882f21eabd879596e11e83655c2146b20f5a9031d5202a2960cdfa68b - async dynamic-import - - - - - - - - -
69+
graph-file dynamic-import-a test/language/expressions/dynamic-import/usage/dynamic-import-module_FIXTURE.js 08bd41ffb3fbbfe3a33b50b66d0ca03f6266e5a4468cafc266eb109c15d7a261 - - - - - - - - - - - -
70+
graph-file dynamic-import-a test/language/expressions/dynamic-import/usage/top-level-import-then-returns-thenable.js 3ffdd7ebe4968cdd6abebafb718b855e818a041735120dec4611c045f98ecf3f - async,generated dynamic-import - - - - - - - - -
6171
graph-file fixture-eval-gtbndng-indirect-update test/language/module-code/eval-gtbndng-indirect-update.js 2e382b6cef4a65f3c1b58ed7a21f9311b2627e7980b410805d1018b714d4b5b6 fnGlobalObject.js module - - - - - - - - - -
6272
graph-file fixture-eval-gtbndng-indirect-update test/language/module-code/eval-gtbndng-indirect-update_FIXTURE.js 86f9d73e4f721d046412952d46a9fdeb2864fb6bdc2917d995170945d6f7800b - - - - - - - - - - - -
6373
graph-file fixture-eval-rqstd-abrupt test/language/module-code/eval-rqstd-abrupt-err-type_FIXTURE.js ce3ebfa86081c793bf36a681e6f1e4faca99e529b338bfbfc433b550e1bf27e8 - - - - - - - - - - - -
@@ -228,6 +238,9 @@ graph-file module-namespace-a test/language/module-code/namespace/internals/prev
228238
graph-file module-namespace-a test/language/module-code/namespace/internals/set-prototype-of-null.js 9c63575fc8841e01c02ef30ef47e7c8f713ad8cc4a879cf197f64b7023751e99 - module - - - - - - - - - -
229239
graph-file module-namespace-a test/language/module-code/namespace/internals/set-prototype-of.js 3de9551554eea456e0075fe9dc03daeb5f8641c64d735f448d2c9396eff8e9b8 - module - - - - - - - - - -
230240
graph-file module-namespace-a test/language/module-code/namespace/internals/set.js 4cfe9d8bfa3dfe2ad3c663013855b43b40173b95f32bec06171813b79d56e87e - module Reflect,Symbol,Symbol.toStringTag - - - - - - - - -
241+
graph-request dynamic-import-a test/language/expressions/dynamic-import/always-create-new-promise.js - - - - - - - - 0 ./dynamic-import-module_FIXTURE.js test/language/expressions/dynamic-import/dynamic-import-module_FIXTURE.js - -
242+
graph-request dynamic-import-a test/language/expressions/dynamic-import/reuse-namespace-object.js - - - - - - - - 0 ./dynamic-import-module_FIXTURE.js test/language/expressions/dynamic-import/dynamic-import-module_FIXTURE.js - -
243+
graph-request dynamic-import-a test/language/expressions/dynamic-import/usage/top-level-import-then-returns-thenable.js - - - - - - - - 0 ./dynamic-import-module_FIXTURE.js test/language/expressions/dynamic-import/usage/dynamic-import-module_FIXTURE.js - -
231244
graph-request fixture-eval-gtbndng-indirect-update test/language/module-code/eval-gtbndng-indirect-update.js - - - - - - - - 0 ./eval-gtbndng-indirect-update_FIXTURE.js test/language/module-code/eval-gtbndng-indirect-update_FIXTURE.js - -
232245
graph-request fixture-eval-rqstd-abrupt test/language/module-code/eval-rqstd-abrupt.js - - - - - - - - 0 ./eval-rqstd-abrupt-err-type_FIXTURE.js test/language/module-code/eval-rqstd-abrupt-err-type_FIXTURE.js - -
233246
graph-request fixture-eval-rqstd-abrupt test/language/module-code/eval-rqstd-abrupt.js - - - - - - - - 1 ./eval-rqstd-abrupt-err-uri_FIXTURE.js test/language/module-code/eval-rqstd-abrupt-err-uri_FIXTURE.js - -

dev-support/test262/current.conf

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ upstream=compat/upstream.toml
1818
upstream_lines=28
1919
upstream_sha256=6a865d89bbbd21a1265b18eca89b63917976d6b41a365d434906f7bb37601a73
2020
admissions=dev-support/test262/admissions.tsv
21-
admissions_lines=665
22-
admissions_sha256=a2dab95276a3ecaf47477f64fd0198105f5b93b5032ae5f8063f223fb52144b4
21+
admissions_lines=678
22+
admissions_sha256=b67a8aa4e1e7a205c416052026071e4bc232ce3429a2841463b9083f270c2111
2323
profile=compat/test262-oxide.conf
2424
profile_lines=3062
2525
profile_sha256=6c6e4387b719df85aea26b0d9af515312f8d55b97f21e580b60e74f2ffacb8a8

docs/deviations.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,14 @@ initial snapshot. Both paths are pinned in
141141

142142
## Open implementation frontiers
143143

144+
- Dynamic import retries failed acyclic source graphs as pinned QuickJS does.
145+
A failed cycle is intentionally safer while parity work remains open: Rust
146+
rolls back every cached member whose dependency edge would point into the
147+
failed transaction, whereas pinned QuickJS can retain a resolved member with
148+
a dangling dependency pointer. Reproducing that unsafe lifetime is not an
149+
approved target deviation. Vacant Rust module-cache slots are currently not
150+
reused, so repeated failed publications also remain a resource-hygiene
151+
frontier.
144152
- Admitted ordinary async-generator function, object-method, and public
145153
class-method direct-yield/await paths match the pinned driver, including
146154
poisoned Promise constructors, iterator-result resolution reentry, and

docs/status.md

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@ The exact profile, inputs, summary, line counts, and report hashes live in
3939
- synchronous static-module graphs, live namespaces, default exports, static
4040
import attributes with loader validation, JSON synthetic modules, and core
4141
`import.meta` semantics
42+
- Script-goal dynamic `import()` with FIFO load/finish jobs, live host-loader
43+
callback sampling, import attributes, cached cycle-root evaluation Promises,
44+
namespace reuse, and Promise assimilation
4245
- native command-line execution and a Rust/WASM browser playground
4346

4447
The public API and Test262 runner now report the same engine diagnostics.
@@ -49,10 +52,14 @@ host is isolated behind a non-default feature.
4952

5053
## Remaining parity work
5154

52-
Major open frontiers include dynamic import and its import attributes,
53-
top-level await, JSON5/byte-oriented host loading, remaining module-host
54-
behavior, and the unsupported/failed leaves recorded by the current Test262
55-
vector. A Feature Parity claim additionally requires the acceptance contract in
55+
Major open frontiers include top-level await, JSON5/byte-oriented host loading,
56+
arbitrary JavaScript exception values and re-entry at module-host callbacks,
57+
and the unsupported/failed leaves recorded by the current Test262 vector.
58+
Failed acyclic source graphs retry like QuickJS. For a failed cycle, Rust
59+
safely unpublishes every record that still points into the failed transaction;
60+
it does not reproduce pinned QuickJS's dangling dependency pointer. Reclaiming
61+
the resulting vacant module-cache slots remains architecture work. A Feature
62+
Parity claim additionally requires the acceptance contract in
5663
[`parity.md`](parity.md), including QuickJS differential evidence and
5764
non-Test262 behavior.
5865

0 commit comments

Comments
 (0)