|
| 1 | +# Top-level `await` status |
| 2 | + |
| 3 | +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`). |
| 4 | + |
| 5 | +## 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. |
| 11 | + |
| 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). |
| 25 | + |
| 26 | +## 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. |
0 commit comments