Skip to content

Commit cbc89a5

Browse files
committed
.
1 parent 2547c9d commit cbc89a5

File tree

3 files changed

+204
-82
lines changed

3 files changed

+204
-82
lines changed

continue.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
- Named generator function expressions now skip the internal const name binding when a function-name environment already exists, so sloppy reassignments of the generator name are ignored instead of throwing (covers the generator `reassign-fn-name` and `scope-name-var-open` tests).
3535
- `yield*` now treats a delegated iterator's `throw` result with `done: true` as a normal completion, propagating the returned `value` and finalizing delegation instead of yielding again (fixes the `star-rhs-iter-thrw-res-*` throw/done cases).
3636
- GlobalDeclarationInstantiation now resolves restricted globals against the root global object (so `let undefined` is rejected even in strict wrappers), deletable direct-eval bindings no longer block later global lexical declarations, and function hoists on non-extensible globals throw a proper TypeError instead of null-refing in DefineFunctionScoped.
37+
- Top-level await dependencies start async imports without stalling siblings, await async parents before executing dependents, and `ModuleCode_topLevelAwait` is green in both strict and sloppy runs.
3738

3839
## Next Iteration Plan
3940
1. When resuming broader work, run a narrow Language filter outside `ArgumentsObject`/`Array_fromAsync` to find the next hot cluster (avoid full 43k sweep).

docs/top-level-await.md

Lines changed: 5 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3,27 +3,11 @@
33
Tracking notes for the current top-level `await` bring-up. Use this as a scratchpad while iterating (similar spirit to `docs/fix-assignment-destructuring-evaluation-order.md`).
44

55
## What changed this round
6-
- Async modules now predeclare exports with `AsyncExportBinding` placeholders. The placeholder wraps a realm-scoped `JsPromise` and swaps to the resolved value once set. Export hoisting (`PredeclareExportNames`) creates these promise-backed bindings so imports observe the eventual value instead of `undefined`.
7-
- Module evaluation for async modules runs asynchronously: `EvaluateModuleBodyWithTopLevelAwait` awaits async dependencies, then executes the body on a background task and records the promise on the module entry.
8-
- Await semantics were aligned with the realm Promise prototype. Await wraps non-promise values via `Promise.resolve` (using the realm constructor/prototype) before driving through the shared scheduler.
9-
- Module path normalization regained “keep it relative” behavior for harness loaders. With a module loader present we normalize relative to the referrer directory without stripping the `/language/...` prefix.
10-
- Import evaluation now temporarily detaches the current microtask queue when waiting on an async dependency and prepends the preserved microtasks afterwards. This prevents caller-queued ticks from running while we synchronously block on the imported module.
6+
- Async dependencies still start evaluation immediately, but async parents are now drained before executing the importing module body so DFS completion ordering and import bindings stay deterministic.
7+
- Blocking waits on async imports detach and restore the caller microtask queue, and microtask enqueue/drain now run under a lock to avoid cross-thread races.
118

12-
## Current failing ModuleCode_topLevelAwait tests
13-
Run: `dotnet test tests/Asynkron.JsEngine.Tests.Test262/Asynkron.JsEngine.Tests.Test262.csproj --filter "ModuleCode_topLevelAwait" --logger "console;verbosity=minimal"`
14-
15-
- `language/module-code/top-level-await/await-dynamic-import-resolution.js` (strict)
16-
- Still throws `Module not found: module-import-resolution_FIXTURE.js`.
17-
- Normalization now yields `language/module-code/top-level-await/module-import-resolution_FIXTURE.js`, but the loader lookup still fails (likely a mismatch between normalized key and Test262Stream lookup).
18-
- `language/module-code/top-level-await/module-graphs-does-not-hang.js` (strict)
19-
- Throws `Module not found: module-graphs-grandparent-tla_FIXTURE.js`.
20-
- Same symptom as above; needs loader path investigation.
21-
- `language/module-code/top-level-await/async-module-does-not-block-sibling-modules.js` (strict)
22-
- Assertion fails: `check` was `false` (the async sibling ticked earlier than expected). Indicates we’re still draining microtasks from the importing module while awaiting an async dependency; the preserved microtask approach didn’t fully isolate the tick ordering.
23-
- `language/module-code/top-level-await/dfs-invariant.js` (strict)
24-
- `globalThis.test262` stayed `undefined`; ordering of async parent completion remains off (likely same microtask/drain ordering issue).
9+
## Current status
10+
- `ModuleCode_topLevelAwait` is green (strict and sloppy).
2511

2612
## Next steps
27-
1) Module loader resolution: confirm the exact specifier strings passed to `SetModuleLoader` for dynamic import and nested TLA graphs. Add temporary logging or reproduce via a tiny harness to see why `Test262Stream.GetTestFile` misses `module-import-resolution_FIXTURE.js` and `module-graphs-grandparent-tla_FIXTURE.js`.
28-
2) Microtask ordering: prevent caller-queued microtasks from running while a sync import waits on an async dependency. The current detach/restore works only for `EvaluateImport`; promise draining elsewhere (e.g., `AwaitScheduler` loops) still runs the caller’s microtasks. Investigate a dedicated “await while preserving existing queue” path or defer draining until after dependency resolution.
29-
3) Re-run `ModuleCode_topLevelAwait` after fixes and update this file.
13+
- Keep an eye on parallel runner behaviour; top-level await still expects deterministic microtask draining while async parents settle.

0 commit comments

Comments
 (0)