Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// Copyright (C) 2026 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

globalThis.evaluations.push("a");
export const a = "a-value";
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// Copyright (C) 2026 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

globalThis.evaluations.push("b");
export const b = "b-value";
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
// Copyright (C) 2026 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-innermoduleevaluation
description: Barrel evaluation order with one eager and one deferred re-export resolves as b -> barrel -> a -> entrypoint
info: |
1. Evaluate ( [ importedNames ] )
1. ...
1. Else,
1. ...
1. Let _result_ be Completion(InnerModuleEvaluation(_module_, _stack_, 0)).
1. ...
1. ...
1. Let _optionalIndirectRequests_ be _module_.GetOptionalIndirectExportsModuleRequests(_importedNames_).
1. Let _promises_ be « _topLevelPromise_ ».
1. For each ModuleRequest Record _request_ of _optionalIndirectRequests_, do
1. ...
1. Let _innerPromise_ be _requiredModule_.Evaluate(_request_.[[ImportedNames]]).
1. ...
1. Append _innerPromise_ to _promises_.
1. If _promises_ contains a Promise _P_ such that _P_.[[PromiseState]] is ~pending~, then
1. ...
1. Return ! SafePerformPromiseAll(...).

1. InnerModuleEvaluation ( _module_, _stack_, _index_ )
1. ...
1. Let _evaluationList_ be « ».
1. Perform BuildEvaluationList(_evaluationList_, _module_, _module_.[[RequestedModules]]).

1. BuildEvaluationList ( _evaluationList_, _referrer_, _moduleRequests_ )
1. For each ModuleRequest Record _request_ of _moduleRequests_, do
1. Let _requiredModule_ be GetImportedModule(_referrer_, _request_.[[Specifier]]).
1. If _request_.[[Phase]] is ~defer~, then
1. Perform ListAppendUnique(_evaluationList_, GatherAsynchronousTransitiveDependencies(_requiredModule_)).
1. Else if _evaluationList_ does not contain _requiredModule_, then
1. Append _requiredModule_ to _evaluationList_.
1. If _requiredModule_ is a Cyclic Module Record, then
1. Let _importedNames_ be _request_.[[ImportedNames]].
1. ...
1. Else,
1. Let _optionalIndirectRequests_ be _requiredModule_.GetOptionalIndirectExportsModuleRequests(_importedNames_).
1. Perform BuildEvaluationList(_evaluationList_, _requiredModule_, _optionalIndirectRequests_).

Modules that are re-exported using "defer" evaluates after the module that is
re-exporting it.
flags: [module]
features: [export-defer]
includes: [compareArray.js]
---*/

import "../setup_FIXTURE.js";
import { a, b } from "./barrel_FIXTURE.js";

assert.sameValue(a, "a-value", "deferred re-export `a` resolves to the source's value");
assert.sameValue(b, "b-value", "eager re-export `b` resolves to the source's value");

globalThis.evaluations.push("entrypoint");

assert.compareArray(
globalThis.evaluations,
["b", "barrel", "a", "entrypoint"],
"evaluation order matches the bullet's expected b -> barrel -> a -> entrypoint"
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// Copyright (C) 2026 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

export { b } from "./b_FIXTURE.js";
export defer { a } from "./a_FIXTURE.js";
globalThis.evaluations.push("barrel");
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// Copyright (C) 2026 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

globalThis.evaluations.push("b");
export defer { x } from "./c_FIXTURE.js";
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// Copyright (C) 2026 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

import "./d_FIXTURE.js";
globalThis.evaluations.push("c");
export const x = "x-from-c";
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
// Copyright (C) 2026 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-innermoduleevaluation
description: Cycle a -> b -> c -> d -> b where b deferred-re-exports x from c evaluates as b, d, c, a
info: |
1. Evaluate ( [ importedNames ] )
1. ...
1. Else,
1. ...
1. Let _result_ be Completion(InnerModuleEvaluation(_module_, _stack_, 0)).
1. ...
1. ...
1. Let _optionalIndirectRequests_ be _module_.GetOptionalIndirectExportsModuleRequests(_importedNames_).
1. Let _promises_ be « _topLevelPromise_ ».
1. For each ModuleRequest Record _request_ of _optionalIndirectRequests_, do
1. ...
1. Let _innerPromise_ be _requiredModule_.Evaluate(_request_.[[ImportedNames]]).
1. ...
1. Append _innerPromise_ to _promises_.
1. If _promises_ contains a Promise _P_ such that _P_.[[PromiseState]] is ~pending~, then
1. ...
1. Return ! SafePerformPromiseAll(...).

1. InnerModuleEvaluation ( _module_, _stack_, _index_ )
1. ...
1. Let _evaluationList_ be « ».
1. Perform BuildEvaluationList(_evaluationList_, _module_, _module_.[[RequestedModules]]).

1. BuildEvaluationList ( _evaluationList_, _referrer_, _moduleRequests_ )
1. For each ModuleRequest Record _request_ of _moduleRequests_, do
1. Let _requiredModule_ be GetImportedModule(_referrer_, _request_.[[Specifier]]).
1. If _request_.[[Phase]] is ~defer~, then
1. Perform ListAppendUnique(_evaluationList_, GatherAsynchronousTransitiveDependencies(_requiredModule_)).
1. Else if _evaluationList_ does not contain _requiredModule_, then
1. Append _requiredModule_ to _evaluationList_.
1. If _requiredModule_ is a Cyclic Module Record, then
1. Let _importedNames_ be _request_.[[ImportedNames]].
1. ...
1. Else,
1. Let _optionalIndirectRequests_ be _requiredModule_.GetOptionalIndirectExportsModuleRequests(_importedNames_).
1. Perform BuildEvaluationList(_evaluationList_, _requiredModule_, _optionalIndirectRequests_).

Modules that are re-exported using "defer" evaluates after the module that is
re-exporting it.
flags: [module]
features: [export-defer]
includes: [compareArray.js]
---*/

import "../setup_FIXTURE.js";
import { x } from "./b_FIXTURE.js";

assert.sameValue(x, "x-from-c", "deferred re-export `x` resolves through b to c's binding");
globalThis.evaluations.push("a");

assert.compareArray(
globalThis.evaluations,
["b", "d", "c", "a"],
"cycle back to defer source evaluates b -> d -> c -> a"
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// Copyright (C) 2026 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

import "./b_FIXTURE.js";
globalThis.evaluations.push("d");
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// Copyright (C) 2026 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

globalThis.evaluations.push("b");
export defer { x } from "./c_FIXTURE.js";
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// Copyright (C) 2026 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

import "./d_FIXTURE.js";
globalThis.evaluations.push("c");
export const x = "x-from-c";
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
// Copyright (C) 2026 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-innermoduleevaluation
description: Cycle a -> b -> c -> d -> a where b deferred-re-exports x from c evaluates as b, d, c, a
info: |
1. Evaluate ( [ importedNames ] )
1. ...
1. Else,
1. ...
1. Let _result_ be Completion(InnerModuleEvaluation(_module_, _stack_, 0)).
1. ...
1. ...
1. Let _optionalIndirectRequests_ be _module_.GetOptionalIndirectExportsModuleRequests(_importedNames_).
1. Let _promises_ be « _topLevelPromise_ ».
1. For each ModuleRequest Record _request_ of _optionalIndirectRequests_, do
1. ...
1. Let _innerPromise_ be _requiredModule_.Evaluate(_request_.[[ImportedNames]]).
1. ...
1. Append _innerPromise_ to _promises_.
1. If _promises_ contains a Promise _P_ such that _P_.[[PromiseState]] is ~pending~, then
1. ...
1. Return ! SafePerformPromiseAll(...).

1. InnerModuleEvaluation ( _module_, _stack_, _index_ )
1. ...
1. Let _evaluationList_ be « ».
1. Perform BuildEvaluationList(_evaluationList_, _module_, _module_.[[RequestedModules]]).

1. BuildEvaluationList ( _evaluationList_, _referrer_, _moduleRequests_ )
1. For each ModuleRequest Record _request_ of _moduleRequests_, do
1. Let _requiredModule_ be GetImportedModule(_referrer_, _request_.[[Specifier]]).
1. If _request_.[[Phase]] is ~defer~, then
1. Perform ListAppendUnique(_evaluationList_, GatherAsynchronousTransitiveDependencies(_requiredModule_)).
1. Else if _evaluationList_ does not contain _requiredModule_, then
1. Append _requiredModule_ to _evaluationList_.
1. If _requiredModule_ is a Cyclic Module Record, then
1. Let _importedNames_ be _request_.[[ImportedNames]].
1. ...
1. Else,
1. Let _optionalIndirectRequests_ be _requiredModule_.GetOptionalIndirectExportsModuleRequests(_importedNames_).
1. Perform BuildEvaluationList(_evaluationList_, _requiredModule_, _optionalIndirectRequests_).

Sub-trees that are re-exported using "defer" evaluates after the module that is
re-exporting it.
flags: [module]
features: [export-defer]
includes: [compareArray.js]
---*/

import "../setup_FIXTURE.js";
import { x } from "./b_FIXTURE.js";

assert.sameValue(x, "x-from-c", "deferred re-export `x` resolves through b to c's binding");
globalThis.evaluations.push("a");

assert.compareArray(
globalThis.evaluations,
["b", "d", "c", "a"],
"cycle through ancestor evaluates b -> d -> c -> a"
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// Copyright (C) 2026 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

import "./cycle-through-ancestor.js";
globalThis.evaluations.push("d");
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// Copyright (C) 2026 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

export defer { a } from "./dep-1_FIXTURE.js";
export defer { b } from "./dep-2_FIXTURE.js";
export defer { c } from "./dep-3_FIXTURE.js";
globalThis.evaluations.push("barrel");
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
// Copyright (C) 2026 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-innermoduleevaluation
description: Multiple deferred re-exports evaluate in declaration order
info: |
1. Evaluate ( [ importedNames ] )
1. ...
1. Else,
1. ...
1. Let _result_ be Completion(InnerModuleEvaluation(_module_, _stack_, 0)).
1. ...
1. ...
1. Let _optionalIndirectRequests_ be _module_.GetOptionalIndirectExportsModuleRequests(_importedNames_).
1. Let _promises_ be « _topLevelPromise_ ».
1. For each ModuleRequest Record _request_ of _optionalIndirectRequests_, do
1. ...
1. Let _innerPromise_ be _requiredModule_.Evaluate(_request_.[[ImportedNames]]).
1. ...
1. Append _innerPromise_ to _promises_.
1. If _promises_ contains a Promise _P_ such that _P_.[[PromiseState]] is ~pending~, then
1. ...
1. Return ! SafePerformPromiseAll(...).

1. InnerModuleEvaluation ( _module_, _stack_, _index_ )
1. ...
1. Let _evaluationList_ be « ».
1. Perform BuildEvaluationList(_evaluationList_, _module_, _module_.[[RequestedModules]]).

1. BuildEvaluationList ( _evaluationList_, _referrer_, _moduleRequests_ )
1. For each ModuleRequest Record _request_ of _moduleRequests_, do
1. Let _requiredModule_ be GetImportedModule(_referrer_, _request_.[[Specifier]]).
1. If _request_.[[Phase]] is ~defer~, then
1. Perform ListAppendUnique(_evaluationList_, GatherAsynchronousTransitiveDependencies(_requiredModule_)).
1. Else if _evaluationList_ does not contain _requiredModule_, then
1. Append _requiredModule_ to _evaluationList_.
1. If _requiredModule_ is a Cyclic Module Record, then
1. Let _importedNames_ be _request_.[[ImportedNames]].
1. ...
1. Else,
1. Let _optionalIndirectRequests_ be _requiredModule_.GetOptionalIndirectExportsModuleRequests(_importedNames_).
1. Perform BuildEvaluationList(_evaluationList_, _requiredModule_, _optionalIndirectRequests_).

Modules that are re-exported using "defer" evaluates after the module that is
re-exporting it. Per InnerModuleEvaluation, deferred ModuleRequest Records are processed
in the order they appear in [[RequestedModules]], which mirrors the
source-code declaration order of `export defer` statements.
flags: [module]
features: [export-defer]
includes: [compareArray.js]
---*/

import "../setup_FIXTURE.js";
import { a, b, c } from "./barrel_FIXTURE.js";

assert.sameValue(a, 1, "deferred re-export `a` resolves to dep-1's value");
assert.sameValue(b, 2, "deferred re-export `b` resolves to dep-2's value");
assert.sameValue(c, 3, "deferred re-export `c` resolves to dep-3's value");

assert.compareArray(
globalThis.evaluations,
["barrel", "dep-1", "dep-2", "dep-3"],
"deferred re-exports evaluate in declaration order: dep-1, dep-2, dep-3"
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// Copyright (C) 2026 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

globalThis.evaluations.push("dep-1");
export const a = 1;
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// Copyright (C) 2026 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

globalThis.evaluations.push("dep-2");
export const b = 2;
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// Copyright (C) 2026 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

globalThis.evaluations.push("dep-3");
export const c = 3;
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// Copyright (C) 2026 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

export { e1 } from "./eager-1_FIXTURE.js";
export defer { d1 } from "./deferred-1_FIXTURE.js";
export { e2 } from "./eager-2_FIXTURE.js";
export defer { d2 } from "./deferred-2_FIXTURE.js";
globalThis.evaluations.push("barrel");
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// Copyright (C) 2026 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

globalThis.evaluations.push("deferred-1");
export const d1 = "deferred-1-value";
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// Copyright (C) 2026 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

globalThis.evaluations.push("deferred-2");
export const d2 = "deferred-2-value";
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// Copyright (C) 2026 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

globalThis.evaluations.push("eager-1");
export const e1 = "eager-1-value";
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// Copyright (C) 2026 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

globalThis.evaluations.push("eager-2");
export const e2 = "eager-2-value";
Loading
Loading