Tests for TLA module evaluation

This commit is contained in:
Leo Balter 2019-09-25 12:00:25 -04:00 committed by Rick Waldron
parent 0213936e95
commit 32bb36f5e4
17 changed files with 927 additions and 0 deletions

View File

@ -0,0 +1,53 @@
// Copyright (C) 2019 Leo Balter. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-moduleevaluation
description: >
Top Level Await on a Dynamic import
info: |
InnerModuleEvaluation( module, stack, index )
...
14. If module.[[PendingAsyncDependencies]] is > 0, set module.[[AsyncEvaluating]] to true.
15. Otherwise, if module.[[Async]] is true, perform ! ExecuteAsyncModule(module).
16. Otherwise, perform ? module.ExecuteModule().
ExecuteAsyncModule ( module )
1. Assert: module.[[Status]] is "evaluating" or "evaluated".
2. Assert: module.[[Async]] is true.
3. Set module.[[AsyncEvaluating]] to true.
4. Let capability be ! NewPromiseCapability(%Promise%).
5. Let stepsFulfilled be the steps of a CallAsyncModuleFulfilled function as specified below.
...
8. Let stepsRejected be the steps of a CallAsyncModuleRejected function as specified below.
...
11. Perform ! PerformPromiseThen(capability.[[Promise]], onFulfilled, onRejected).
12. Perform ! module.ExecuteModule(capability).
13. Return.
ExecuteModule ( [ capability ] )
...
11. If module.[[Async]] is false, then
a. Assert: capability was not provided.
b. Push moduleCxt on to the execution context stack; moduleCxt is now the running execution context.
c. Let result be the result of evaluating module.[[ECMAScriptCode]].
d. Suspend moduleCxt and remove it from the execution context stack.
e. Resume the context that is now on the top of the execution context stack as the running execution context.
f. Return Completion(result).
12. Otherwise,
a. Assert: capability is a PromiseCapability Record.
b. Perform ! AsyncBlockStart(capability, module.[[ECMAScriptCode]], moduleCxt).
c. Return.
flags: [module]
features: [top-level-await, dynamic-import]
negative:
phase: runtime
type: TypeError
---*/
await import('./module-import-rejection-body_FIXTURE.js');
throw new Test262Error('this should be unreachable');

View File

@ -0,0 +1,54 @@
// Copyright (C) 2019 Leo Balter. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-moduleevaluation
description: >
Top Level Await on a Dynamic import
info: |
InnerModuleEvaluation( module, stack, index )
...
14. If module.[[PendingAsyncDependencies]] is > 0, set module.[[AsyncEvaluating]] to true.
15. Otherwise, if module.[[Async]] is true, perform ! ExecuteAsyncModule(module).
16. Otherwise, perform ? module.ExecuteModule().
ExecuteAsyncModule ( module )
1. Assert: module.[[Status]] is "evaluating" or "evaluated".
2. Assert: module.[[Async]] is true.
3. Set module.[[AsyncEvaluating]] to true.
4. Let capability be ! NewPromiseCapability(%Promise%).
5. Let stepsFulfilled be the steps of a CallAsyncModuleFulfilled function as specified below.
...
8. Let stepsRejected be the steps of a CallAsyncModuleRejected function as specified below.
...
11. Perform ! PerformPromiseThen(capability.[[Promise]], onFulfilled, onRejected).
12. Perform ! module.ExecuteModule(capability).
13. Return.
ExecuteModule ( [ capability ] )
...
11. If module.[[Async]] is false, then
a. Assert: capability was not provided.
b. Push moduleCxt on to the execution context stack; moduleCxt is now the running execution context.
c. Let result be the result of evaluating module.[[ECMAScriptCode]].
d. Suspend moduleCxt and remove it from the execution context stack.
e. Resume the context that is now on the top of the execution context stack as the running execution context.
f. Return Completion(result).
12. Otherwise,
a. Assert: capability is a PromiseCapability Record.
b. Perform ! AsyncBlockStart(capability, module.[[ECMAScriptCode]], moduleCxt).
c. Return.
flags: [module, async]
features: [top-level-await, dynamic-import]
---*/
var ns = await import('./module-import-resolution_FIXTURE.js');
assert.sameValue(ns.default, 42);
assert.sameValue(ns.x, 'named');
assert.sameValue(ns.y, 39);
$DONE();

View File

@ -0,0 +1,54 @@
// Copyright (C) 2019 Leo Balter. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-moduleevaluation
description: >
Dynamic imported module with async exports
info: |
InnerModuleEvaluation( module, stack, index )
...
14. If module.[[PendingAsyncDependencies]] is > 0, set module.[[AsyncEvaluating]] to true.
15. Otherwise, if module.[[Async]] is true, perform ! ExecuteAsyncModule(module).
16. Otherwise, perform ? module.ExecuteModule().
ExecuteAsyncModule ( module )
1. Assert: module.[[Status]] is "evaluating" or "evaluated".
2. Assert: module.[[Async]] is true.
3. Set module.[[AsyncEvaluating]] to true.
4. Let capability be ! NewPromiseCapability(%Promise%).
5. Let stepsFulfilled be the steps of a CallAsyncModuleFulfilled function as specified below.
...
8. Let stepsRejected be the steps of a CallAsyncModuleRejected function as specified below.
...
11. Perform ! PerformPromiseThen(capability.[[Promise]], onFulfilled, onRejected).
12. Perform ! module.ExecuteModule(capability).
13. Return.
ExecuteModule ( [ capability ] )
...
11. If module.[[Async]] is false, then
a. Assert: capability was not provided.
b. Push moduleCxt on to the execution context stack; moduleCxt is now the running execution context.
c. Let result be the result of evaluating module.[[ECMAScriptCode]].
d. Suspend moduleCxt and remove it from the execution context stack.
e. Resume the context that is now on the top of the execution context stack as the running execution context.
f. Return Completion(result).
12. Otherwise,
a. Assert: capability is a PromiseCapability Record.
b. Perform ! AsyncBlockStart(capability, module.[[ECMAScriptCode]], moduleCxt).
c. Return.
flags: [module, async]
features: [top-level-await, dynamic-import]
---*/
import('./module-import-rejection_FIXTURE.js').then(() => {
throw new Test262Error('Should not be fulfilled');
}, (err) => {
assert(err instanceof TypeError);
assert.sameValue(err.constructor, TypeError);
assert.sameValue(err.message, 'error in the default export line');
}).then($DONE, $DONE);

View File

@ -0,0 +1,52 @@
// Copyright (C) 2019 Leo Balter. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-moduleevaluation
description: >
Dynamic imported module with async exports
info: |
InnerModuleEvaluation( module, stack, index )
...
14. If module.[[PendingAsyncDependencies]] is > 0, set module.[[AsyncEvaluating]] to true.
15. Otherwise, if module.[[Async]] is true, perform ! ExecuteAsyncModule(module).
16. Otherwise, perform ? module.ExecuteModule().
ExecuteAsyncModule ( module )
1. Assert: module.[[Status]] is "evaluating" or "evaluated".
2. Assert: module.[[Async]] is true.
3. Set module.[[AsyncEvaluating]] to true.
4. Let capability be ! NewPromiseCapability(%Promise%).
5. Let stepsFulfilled be the steps of a CallAsyncModuleFulfilled function as specified below.
...
8. Let stepsRejected be the steps of a CallAsyncModuleRejected function as specified below.
...
11. Perform ! PerformPromiseThen(capability.[[Promise]], onFulfilled, onRejected).
12. Perform ! module.ExecuteModule(capability).
13. Return.
ExecuteModule ( [ capability ] )
...
11. If module.[[Async]] is false, then
a. Assert: capability was not provided.
b. Push moduleCxt on to the execution context stack; moduleCxt is now the running execution context.
c. Let result be the result of evaluating module.[[ECMAScriptCode]].
d. Suspend moduleCxt and remove it from the execution context stack.
e. Resume the context that is now on the top of the execution context stack as the running execution context.
f. Return Completion(result).
12. Otherwise,
a. Assert: capability is a PromiseCapability Record.
b. Perform ! AsyncBlockStart(capability, module.[[ECMAScriptCode]], moduleCxt).
c. Return.
flags: [module, async]
features: [top-level-await, dynamic-import]
---*/
import('./module-import-resolution_FIXTURE.js').then(ns => {
assert.sameValue(ns.default, 42);
assert.sameValue(ns.x, 'named');
assert.sameValue(ns.y, 39);
}).then($DONE, $DONE);

View File

@ -0,0 +1,86 @@
// Copyright (C) 2019 Leo Balter. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-moduleevaluation
description: >
Ticks from async module (w/ TLA) won't change loading async module
info: |
Table 3: Additional Fields of Cyclic Module Records
[[Async]]
...
Having an asynchronous dependency does not make the module asynchronous. This field must not change after the module is parsed.
Evaluate ( ) Concrete Method
...
6. Let capability be ! NewPromiseCapability(%Promise%).
7. Set module.[[TopLevelCapability]] to capability.
8. Let result be InnerModuleEvaluation(module, stack, 0).
9. If result is an abrupt completion, then
...
d. Perform ! Call(capability.[[Reject]], undefined, «result.[[Value]]»).
10. Otherwise,
...
b. If module.[[AsyncEvaluating]] is false, then
i. Perform ! Call(capability.[[Resolve]], undefined, «undefined»).
...
11. Return undefinedcapability.[[Promise]].
InnerModuleEvaluation( module, stack, index )
...
14. If module.[[PendingAsyncDependencies]] is > 0, set module.[[AsyncEvaluating]] to true.
15. Otherwise, if module.[[Async]] is true, perform ! ExecuteAsyncModule(module).
16. Otherwise, perform ? module.ExecuteModule().
ExecuteAsyncModule ( module )
1. Assert: module.[[Status]] is "evaluating" or "evaluated".
2. Assert: module.[[Async]] is true.
3. Set module.[[AsyncEvaluating]] to true.
4. Let capability be ! NewPromiseCapability(%Promise%).
5. Let stepsFulfilled be the steps of a CallAsyncModuleFulfilled function as specified below.
...
8. Let stepsRejected be the steps of a CallAsyncModuleRejected function as specified below.
...
11. Perform ! PerformPromiseThen(capability.[[Promise]], onFulfilled, onRejected).
12. Perform ! module.ExecuteModule(capability).
13. Return.
ExecuteModule ( [ capability ] )
...
11. If module.[[Async]] is false, then
a. Assert: capability was not provided.
b. Push moduleCxt on to the execution context stack; moduleCxt is now the running execution context.
c. Let result be the result of evaluating module.[[ECMAScriptCode]].
d. Suspend moduleCxt and remove it from the execution context stack.
e. Resume the context that is now on the top of the execution context stack as the running execution context.
f. Return Completion(result).
12. Otherwise,
a. Assert: capability is a PromiseCapability Record.
b. Perform ! AsyncBlockStart(capability, module.[[ECMAScriptCode]], moduleCxt).
c. Return.
flags: [module, async]
features: [top-level-await]
---*/
var x = 'synchronous evaluation';
Promise.resolve().then(() => x = 'tick in the async evaluation');
// module 'foo' won't tick here
import foo from './module-import-resolution_FIXTURE.js';
assert.sameValue(foo, 42);
assert.sameValue(x, 'synchronous evaluation');
// Enforce [[Async]] to true, and tick
await 1;
assert.sameValue(x, 'tick in the async evaluation');
$DONE();

View File

@ -0,0 +1,76 @@
// Copyright (C) 2019 Leo Balter. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-moduleevaluation
description: >
Evaluate imported rejected module
info: |
Table 3: Additional Fields of Cyclic Module Records
[[Async]]
...
Having an asynchronous dependency does not make the module asynchronous. This field must not change after the module is parsed.
Evaluate ( ) Concrete Method
...
6. Let capability be ! NewPromiseCapability(%Promise%).
7. Set module.[[TopLevelCapability]] to capability.
8. Let result be InnerModuleEvaluation(module, stack, 0).
9. If result is an abrupt completion, then
...
d. Perform ! Call(capability.[[Reject]], undefined, «result.[[Value]]»).
10. Otherwise,
...
b. If module.[[AsyncEvaluating]] is false, then
i. Perform ! Call(capability.[[Resolve]], undefined, «undefined»).
...
11. Return undefinedcapability.[[Promise]].
InnerModuleEvaluation( module, stack, index )
...
14. If module.[[PendingAsyncDependencies]] is > 0, set module.[[AsyncEvaluating]] to true.
15. Otherwise, if module.[[Async]] is true, perform ! ExecuteAsyncModule(module).
16. Otherwise, perform ? module.ExecuteModule().
ExecuteAsyncModule ( module )
1. Assert: module.[[Status]] is "evaluating" or "evaluated".
2. Assert: module.[[Async]] is true.
3. Set module.[[AsyncEvaluating]] to true.
4. Let capability be ! NewPromiseCapability(%Promise%).
5. Let stepsFulfilled be the steps of a CallAsyncModuleFulfilled function as specified below.
...
8. Let stepsRejected be the steps of a CallAsyncModuleRejected function as specified below.
...
11. Perform ! PerformPromiseThen(capability.[[Promise]], onFulfilled, onRejected).
12. Perform ! module.ExecuteModule(capability).
13. Return.
ExecuteModule ( [ capability ] )
...
11. If module.[[Async]] is false, then
a. Assert: capability was not provided.
b. Push moduleCxt on to the execution context stack; moduleCxt is now the running execution context.
c. Let result be the result of evaluating module.[[ECMAScriptCode]].
d. Suspend moduleCxt and remove it from the execution context stack.
e. Resume the context that is now on the top of the execution context stack as the running execution context.
f. Return Completion(result).
12. Otherwise,
a. Assert: capability is a PromiseCapability Record.
b. Perform ! AsyncBlockStart(capability, module.[[ECMAScriptCode]], moduleCxt).
c. Return.
flags: [module]
features: [top-level-await]
negative:
phase: runtime
type: TypeError
---*/
import foo from './module-import-rejection-body_FIXTURE.js';
throw new Test262Error('this should be unreachable');

View File

@ -0,0 +1,9 @@
// Copyright (C) 2019 Leo Balter. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
export default 42;
export const named = 'named';
var rejection = Promise.reject(new TypeError('I reject this!'));
await rejection;

View File

@ -0,0 +1,76 @@
// Copyright (C) 2019 Leo Balter. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-moduleevaluation
description: >
Evaluate imported rejected module
info: |
Table 3: Additional Fields of Cyclic Module Records
[[Async]]
...
Having an asynchronous dependency does not make the module asynchronous. This field must not change after the module is parsed.
Evaluate ( ) Concrete Method
...
6. Let capability be ! NewPromiseCapability(%Promise%).
7. Set module.[[TopLevelCapability]] to capability.
8. Let result be InnerModuleEvaluation(module, stack, 0).
9. If result is an abrupt completion, then
...
d. Perform ! Call(capability.[[Reject]], undefined, «result.[[Value]]»).
10. Otherwise,
...
b. If module.[[AsyncEvaluating]] is false, then
i. Perform ! Call(capability.[[Resolve]], undefined, «undefined»).
...
11. Return undefinedcapability.[[Promise]].
InnerModuleEvaluation( module, stack, index )
...
14. If module.[[PendingAsyncDependencies]] is > 0, set module.[[AsyncEvaluating]] to true.
15. Otherwise, if module.[[Async]] is true, perform ! ExecuteAsyncModule(module).
16. Otherwise, perform ? module.ExecuteModule().
ExecuteAsyncModule ( module )
1. Assert: module.[[Status]] is "evaluating" or "evaluated".
2. Assert: module.[[Async]] is true.
3. Set module.[[AsyncEvaluating]] to true.
4. Let capability be ! NewPromiseCapability(%Promise%).
5. Let stepsFulfilled be the steps of a CallAsyncModuleFulfilled function as specified below.
...
8. Let stepsRejected be the steps of a CallAsyncModuleRejected function as specified below.
...
11. Perform ! PerformPromiseThen(capability.[[Promise]], onFulfilled, onRejected).
12. Perform ! module.ExecuteModule(capability).
13. Return.
ExecuteModule ( [ capability ] )
...
11. If module.[[Async]] is false, then
a. Assert: capability was not provided.
b. Push moduleCxt on to the execution context stack; moduleCxt is now the running execution context.
c. Let result be the result of evaluating module.[[ECMAScriptCode]].
d. Suspend moduleCxt and remove it from the execution context stack.
e. Resume the context that is now on the top of the execution context stack as the running execution context.
f. Return Completion(result).
12. Otherwise,
a. Assert: capability is a PromiseCapability Record.
b. Perform ! AsyncBlockStart(capability, module.[[ECMAScriptCode]], moduleCxt).
c. Return.
flags: [module]
features: [top-level-await]
negative:
phase: runtime
type: RangeError
---*/
import foo from './module-import-rejection-tick_FIXTURE.js';
throw new Test262Error('this should be unreachable');

View File

@ -0,0 +1,12 @@
// Copyright (C) 2019 Leo Balter. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
export default 42;
await Promise.resolve().then(() => {
// This rejection will tick first unwrapping all the promises first
return Promise.reject(new RangeError());
});
var rejection = Promise.reject(new TypeError());
await rejection;

View File

@ -0,0 +1,76 @@
// Copyright (C) 2019 Leo Balter. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-moduleevaluation
description: >
Evaluate imported rejected module
info: |
Table 3: Additional Fields of Cyclic Module Records
[[Async]]
...
Having an asynchronous dependency does not make the module asynchronous. This field must not change after the module is parsed.
Evaluate ( ) Concrete Method
...
6. Let capability be ! NewPromiseCapability(%Promise%).
7. Set module.[[TopLevelCapability]] to capability.
8. Let result be InnerModuleEvaluation(module, stack, 0).
9. If result is an abrupt completion, then
...
d. Perform ! Call(capability.[[Reject]], undefined, «result.[[Value]]»).
10. Otherwise,
...
b. If module.[[AsyncEvaluating]] is false, then
i. Perform ! Call(capability.[[Resolve]], undefined, «undefined»).
...
11. Return undefinedcapability.[[Promise]].
InnerModuleEvaluation( module, stack, index )
...
14. If module.[[PendingAsyncDependencies]] is > 0, set module.[[AsyncEvaluating]] to true.
15. Otherwise, if module.[[Async]] is true, perform ! ExecuteAsyncModule(module).
16. Otherwise, perform ? module.ExecuteModule().
ExecuteAsyncModule ( module )
1. Assert: module.[[Status]] is "evaluating" or "evaluated".
2. Assert: module.[[Async]] is true.
3. Set module.[[AsyncEvaluating]] to true.
4. Let capability be ! NewPromiseCapability(%Promise%).
5. Let stepsFulfilled be the steps of a CallAsyncModuleFulfilled function as specified below.
...
8. Let stepsRejected be the steps of a CallAsyncModuleRejected function as specified below.
...
11. Perform ! PerformPromiseThen(capability.[[Promise]], onFulfilled, onRejected).
12. Perform ! module.ExecuteModule(capability).
13. Return.
ExecuteModule ( [ capability ] )
...
11. If module.[[Async]] is false, then
a. Assert: capability was not provided.
b. Push moduleCxt on to the execution context stack; moduleCxt is now the running execution context.
c. Let result be the result of evaluating module.[[ECMAScriptCode]].
d. Suspend moduleCxt and remove it from the execution context stack.
e. Resume the context that is now on the top of the execution context stack as the running execution context.
f. Return Completion(result).
12. Otherwise,
a. Assert: capability is a PromiseCapability Record.
b. Perform ! AsyncBlockStart(capability, module.[[ECMAScriptCode]], moduleCxt).
c. Return.
flags: [module]
features: [top-level-await]
negative:
phase: runtime
type: TypeError
---*/
import { resolved } from './module-import-rejection_FIXTURE.js';
throw new Test262Error('this should be unreachable');

View File

@ -0,0 +1,11 @@
// Copyright (C) 2019 Leo Balter. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
export const resolved = await 42;
// Can't use Test262Error in this file because it's not referenced here
export default await Promise.reject(new TypeError('error in the default export line'));
// Use RangeError to differentiate from initial error
export const x = await Promise.reject(new RangeError('named x rejection'));
export const y = await Promise.reject(new RangeError('named y rejection'));

View File

@ -0,0 +1,81 @@
// Copyright (C) 2019 Leo Balter. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-moduleevaluation
description: >
Evaluate imported module with async exports
info: |
Table 3: Additional Fields of Cyclic Module Records
[[Async]]
...
Having an asynchronous dependency does not make the module asynchronous. This field must not change after the module is parsed.
Evaluate ( ) Concrete Method
...
6. Let capability be ! NewPromiseCapability(%Promise%).
7. Set module.[[TopLevelCapability]] to capability.
8. Let result be InnerModuleEvaluation(module, stack, 0).
9. If result is an abrupt completion, then
...
d. Perform ! Call(capability.[[Reject]], undefined, «result.[[Value]]»).
10. Otherwise,
...
b. If module.[[AsyncEvaluating]] is false, then
i. Perform ! Call(capability.[[Resolve]], undefined, «undefined»).
...
11. Return undefinedcapability.[[Promise]].
InnerModuleEvaluation( module, stack, index )
...
14. If module.[[PendingAsyncDependencies]] is > 0, set module.[[AsyncEvaluating]] to true.
15. Otherwise, if module.[[Async]] is true, perform ! ExecuteAsyncModule(module).
16. Otherwise, perform ? module.ExecuteModule().
ExecuteAsyncModule ( module )
1. Assert: module.[[Status]] is "evaluating" or "evaluated".
2. Assert: module.[[Async]] is true.
3. Set module.[[AsyncEvaluating]] to true.
4. Let capability be ! NewPromiseCapability(%Promise%).
5. Let stepsFulfilled be the steps of a CallAsyncModuleFulfilled function as specified below.
...
8. Let stepsRejected be the steps of a CallAsyncModuleRejected function as specified below.
...
11. Perform ! PerformPromiseThen(capability.[[Promise]], onFulfilled, onRejected).
12. Perform ! module.ExecuteModule(capability).
13. Return.
ExecuteModule ( [ capability ] )
...
11. If module.[[Async]] is false, then
a. Assert: capability was not provided.
b. Push moduleCxt on to the execution context stack; moduleCxt is now the running execution context.
c. Let result be the result of evaluating module.[[ECMAScriptCode]].
d. Suspend moduleCxt and remove it from the execution context stack.
e. Resume the context that is now on the top of the execution context stack as the running execution context.
f. Return Completion(result).
12. Otherwise,
a. Assert: capability is a PromiseCapability Record.
b. Perform ! AsyncBlockStart(capability, module.[[ECMAScriptCode]], moduleCxt).
c. Return.
flags: [module, async]
features: [top-level-await]
---*/
import foo from './module-import-resolution_FIXTURE.js';
assert.sameValue(foo, 42);
import { x, y } from './module-import-resolution_FIXTURE.js';
assert.sameValue(x, 'named');
assert.sameValue(y, 39);
// $DONE is set at the end to reflect the async operations from the imported module
$DONE();

View File

@ -0,0 +1,14 @@
// Copyright (C) 2019 Leo Balter. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
await 1;
await 2;
export default await Promise.resolve(42);
export const y = await 39;
export const x = await 'named';
// Bonus: this rejection is not unwrapped
if (false) {
await Promise.reject(42);
}

View File

@ -0,0 +1,95 @@
// Copyright (C) 2019 Leo Balter. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-moduleevaluation
description: >
Evaluate imported module with unwrapped imported promises
info: |
Table 3: Additional Fields of Cyclic Module Records
[[Async]]
...
Having an asynchronous dependency does not make the module asynchronous. This field must not change after the module is parsed.
Evaluate ( ) Concrete Method
...
6. Let capability be ! NewPromiseCapability(%Promise%).
7. Set module.[[TopLevelCapability]] to capability.
8. Let result be InnerModuleEvaluation(module, stack, 0).
9. If result is an abrupt completion, then
...
d. Perform ! Call(capability.[[Reject]], undefined, «result.[[Value]]»).
10. Otherwise,
...
b. If module.[[AsyncEvaluating]] is false, then
i. Perform ! Call(capability.[[Resolve]], undefined, «undefined»).
...
11. Return undefinedcapability.[[Promise]].
InnerModuleEvaluation( module, stack, index )
...
14. If module.[[PendingAsyncDependencies]] is > 0, set module.[[AsyncEvaluating]] to true.
15. Otherwise, if module.[[Async]] is true, perform ! ExecuteAsyncModule(module).
16. Otherwise, perform ? module.ExecuteModule().
ExecuteAsyncModule ( module )
1. Assert: module.[[Status]] is "evaluating" or "evaluated".
2. Assert: module.[[Async]] is true.
3. Set module.[[AsyncEvaluating]] to true.
4. Let capability be ! NewPromiseCapability(%Promise%).
5. Let stepsFulfilled be the steps of a CallAsyncModuleFulfilled function as specified below.
...
8. Let stepsRejected be the steps of a CallAsyncModuleRejected function as specified below.
...
11. Perform ! PerformPromiseThen(capability.[[Promise]], onFulfilled, onRejected).
12. Perform ! module.ExecuteModule(capability).
13. Return.
ExecuteModule ( [ capability ] )
...
11. If module.[[Async]] is false, then
a. Assert: capability was not provided.
b. Push moduleCxt on to the execution context stack; moduleCxt is now the running execution context.
c. Let result be the result of evaluating module.[[ECMAScriptCode]].
d. Suspend moduleCxt and remove it from the execution context stack.
e. Resume the context that is now on the top of the execution context stack as the running execution context.
f. Return Completion(result).
12. Otherwise,
a. Assert: capability is a PromiseCapability Record.
b. Perform ! AsyncBlockStart(capability, module.[[ECMAScriptCode]], moduleCxt).
c. Return.
flags: [module, async]
features: [top-level-await]
---*/
import mod from './module-import-unwrapped_FIXTURE.js';
import { x, y } from './module-import-unwrapped_FIXTURE.js';
assert(mod instanceof Promise, 'mod is an instance of Promise');
assert(x instanceof Promise, 'x is an instance of Promise');
assert(y instanceof Promise, 'y is an instance of Promise');
assert.sameValue(Object.getPrototypeOf(mod), Promise.prototype, 'Proto of mod');
assert.sameValue(Object.getPrototypeOf(x), Promise.prototype, 'Proto of x');
assert.sameValue(Object.getPrototypeOf(y), Promise.prototype, 'Proto of y');
assert.sameValue(await mod, 'default');
assert.sameValue(await y, 'unwrapped resolution');
var err;
try {
await x;
} catch (e) {
err = e;
}
assert.sameValue(err, 'unwrapped rejection');
// $DONE is set at the end to reflect the async operations from the imported module
$DONE();

View File

@ -0,0 +1,9 @@
// Copyright (C) 2019 Leo Balter. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
await 1;
export default Promise.resolve('default');
export const x = Promise.reject('unwrapped rejection');
export const y = Promise.resolve('unwrapped resolution');

View File

@ -0,0 +1,88 @@
// Copyright (C) 2019 Leo Balter. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-moduleevaluation
description: >
Ticks from async module (w/ TLA) self importing
info: |
Table 3: Additional Fields of Cyclic Module Records
[[Async]]
...
Having an asynchronous dependency does not make the module asynchronous. This field must not change after the module is parsed.
Evaluate ( ) Concrete Method
...
6. Let capability be ! NewPromiseCapability(%Promise%).
7. Set module.[[TopLevelCapability]] to capability.
8. Let result be InnerModuleEvaluation(module, stack, 0).
9. If result is an abrupt completion, then
...
d. Perform ! Call(capability.[[Reject]], undefined, «result.[[Value]]»).
10. Otherwise,
...
b. If module.[[AsyncEvaluating]] is false, then
i. Perform ! Call(capability.[[Resolve]], undefined, «undefined»).
...
11. Return undefinedcapability.[[Promise]].
InnerModuleEvaluation( module, stack, index )
...
14. If module.[[PendingAsyncDependencies]] is > 0, set module.[[AsyncEvaluating]] to true.
15. Otherwise, if module.[[Async]] is true, perform ! ExecuteAsyncModule(module).
16. Otherwise, perform ? module.ExecuteModule().
ExecuteAsyncModule ( module )
1. Assert: module.[[Status]] is "evaluating" or "evaluated".
2. Assert: module.[[Async]] is true.
3. Set module.[[AsyncEvaluating]] to true.
4. Let capability be ! NewPromiseCapability(%Promise%).
5. Let stepsFulfilled be the steps of a CallAsyncModuleFulfilled function as specified below.
...
8. Let stepsRejected be the steps of a CallAsyncModuleRejected function as specified below.
...
11. Perform ! PerformPromiseThen(capability.[[Promise]], onFulfilled, onRejected).
12. Perform ! module.ExecuteModule(capability).
13. Return.
ExecuteModule ( [ capability ] )
...
11. If module.[[Async]] is false, then
a. Assert: capability was not provided.
b. Push moduleCxt on to the execution context stack; moduleCxt is now the running execution context.
c. Let result be the result of evaluating module.[[ECMAScriptCode]].
d. Suspend moduleCxt and remove it from the execution context stack.
e. Resume the context that is now on the top of the execution context stack as the running execution context.
f. Return Completion(result).
12. Otherwise,
a. Assert: capability is a PromiseCapability Record.
b. Perform ! AsyncBlockStart(capability, module.[[ECMAScriptCode]], moduleCxt).
c. Return.
flags: [module, async]
features: [top-level-await]
---*/
var x = 'synchronous evaluation';
Promise.resolve().then(() => x = 'tick in the async evaluation');
import self from './module-self-import-async-resolution-ticks.js';
assert.sameValue(x, 'synchronous evaluation');
assert.throws(ReferenceError, function() {
self;
}, 'self is not initialized yet');
export default await Promise.resolve(42);
assert.sameValue(x, 'tick in the async evaluation');
assert.sameValue(self, 42), 'self is initialized after export';
$DONE();

View File

@ -0,0 +1,81 @@
// Copyright (C) 2019 Leo Balter. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-moduleevaluation
description: >
Ticks from sync module (no TLA) loading async module
info: |
Table 3: Additional Fields of Cyclic Module Records
[[Async]]
...
Having an asynchronous dependency does not make the module asynchronous. This field must not change after the module is parsed.
Evaluate ( ) Concrete Method
...
6. Let capability be ! NewPromiseCapability(%Promise%).
7. Set module.[[TopLevelCapability]] to capability.
8. Let result be InnerModuleEvaluation(module, stack, 0).
9. If result is an abrupt completion, then
...
d. Perform ! Call(capability.[[Reject]], undefined, «result.[[Value]]»).
10. Otherwise,
...
b. If module.[[AsyncEvaluating]] is false, then
i. Perform ! Call(capability.[[Resolve]], undefined, «undefined»).
...
11. Return undefinedcapability.[[Promise]].
InnerModuleEvaluation( module, stack, index )
...
14. If module.[[PendingAsyncDependencies]] is > 0, set module.[[AsyncEvaluating]] to true.
15. Otherwise, if module.[[Async]] is true, perform ! ExecuteAsyncModule(module).
16. Otherwise, perform ? module.ExecuteModule().
ExecuteAsyncModule ( module )
1. Assert: module.[[Status]] is "evaluating" or "evaluated".
2. Assert: module.[[Async]] is true.
3. Set module.[[AsyncEvaluating]] to true.
4. Let capability be ! NewPromiseCapability(%Promise%).
5. Let stepsFulfilled be the steps of a CallAsyncModuleFulfilled function as specified below.
...
8. Let stepsRejected be the steps of a CallAsyncModuleRejected function as specified below.
...
11. Perform ! PerformPromiseThen(capability.[[Promise]], onFulfilled, onRejected).
12. Perform ! module.ExecuteModule(capability).
13. Return.
ExecuteModule ( [ capability ] )
...
11. If module.[[Async]] is false, then
a. Assert: capability was not provided.
b. Push moduleCxt on to the execution context stack; moduleCxt is now the running execution context.
c. Let result be the result of evaluating module.[[ECMAScriptCode]].
d. Suspend moduleCxt and remove it from the execution context stack.
e. Resume the context that is now on the top of the execution context stack as the running execution context.
f. Return Completion(result).
12. Otherwise,
a. Assert: capability is a PromiseCapability Record.
b. Perform ! AsyncBlockStart(capability, module.[[ECMAScriptCode]], moduleCxt).
c. Return.
flags: [module, async]
features: [top-level-await]
---*/
var x = 'synchronous evaluation';
Promise.resolve().then(() => x = 'tick in the async evaluation');
import foo from './module-import-resolution_FIXTURE.js';
assert.sameValue(foo, 42);
assert.sameValue(x, 'synchronous evaluation');
Promise.resolve().then(() => {
assert.sameValue(x, 'tick in the async evaluation');
}).then($DONE, $DONE);