Bug 1519100 - Adjust jit tests to work with module promises; r=mgaudet

Differential Revision: https://phabricator.services.mozilla.com/D96067
This commit is contained in:
yulia 2020-12-02 12:41:08 +00:00
Родитель 5a92ccc7e6
Коммит 8ca98dd89c
10 изменённых файлов: 238 добавлений и 156 удалений

Просмотреть файл

@ -1,2 +1,2 @@
// |jit-test| module // |jit-test| module --enable-top-level-await;
eval("1"); eval("1");

Просмотреть файл

@ -8,7 +8,11 @@ let c = registerModule("c", parseModule(`import "a";`));
b.declarationInstantiation(); b.declarationInstantiation();
c.declarationInstantiation(); c.declarationInstantiation();
let count = 0; (async () => {
try { b.evaluation() } catch (e) { count++; } let count = 0;
try { c.evaluation() } catch (e) { count++; } try { await b.evaluation() } catch (e) { count++; }
assertEq(count, 2); try { await c.evaluation() } catch (e) { count++; }
assertEq(count, 2);
})();
drainJobQueue();

Просмотреть файл

@ -1,3 +1,4 @@
// |jit-test| --enable-top-level-await;
"use strict"; "use strict";
load(libdir + "asserts.js"); load(libdir + "asserts.js");
@ -13,6 +14,18 @@ let b = registerModule('b', parseModule(`
`)); `));
a.declarationInstantiation(); a.declarationInstantiation();
assertThrowsInstanceOf(() => a.evaluation(), UniqueError); a.evaluation()
.then(r => {
// We should not reach here, as we expect an error to be thrown.
assertEq(false, true);
})
.catch(e => assertEq(e instanceof UniqueError, true));
b.declarationInstantiation(); b.declarationInstantiation();
assertThrowsInstanceOf(() => b.evaluation(), UniqueError); b.evaluation()
.then(r => {
// We should not reach here, as we expect an error to be thrown.
assertEq(false, true);
})
.catch(e => assertEq(e instanceof UniqueError, true));
drainJobQueue();

Просмотреть файл

@ -1,3 +1,4 @@
// |jit-test| --enable-top-level-await;
dbgGlobal = newGlobal({newCompartment: true}); dbgGlobal = newGlobal({newCompartment: true});
dbg = new dbgGlobal.Debugger; dbg = new dbgGlobal.Debugger;
dbg.addDebuggee(this); dbg.addDebuggee(this);
@ -9,16 +10,20 @@ function f() {
function execModule(source) { function execModule(source) {
m = parseModule(source); m = parseModule(source);
m.declarationInstantiation(); m.declarationInstantiation();
m.evaluation(); return m.evaluation();
} }
execModule("f();"); execModule("f();").then(() => {
gc(); gc();
let caught; execModule("throw 'foo'")
try { .then(r => {
execModule("throw 'foo'"); // We should not reach here.
} catch (e) { assertEq(false, true);
caught = e; })
} .catch(e => {
assertEq(caught, 'foo'); assertEq(e, 'foo');
});
})
drainJobQueue();

Просмотреть файл

@ -1,3 +1,3 @@
// |jit-test| --more-compartments // |jit-test| --more-compartments;
fullcompartmentchecks(true); fullcompartmentchecks(true);
newGlobal().eval(`import("javascript:")`).catch(() => {}); newGlobal().eval(`import("javascript:")`).catch(() => {});

Просмотреть файл

@ -2,11 +2,11 @@
class MyError {} class MyError {}
function assertThrowsMyError(f) async function assertThrowsMyError(f)
{ {
let caught = false; let caught = false;
try { try {
f(); await f();
} catch (e) { } catch (e) {
caught = true; caught = true;
assertEq(e.constructor, MyError); assertEq(e.constructor, MyError);
@ -29,3 +29,5 @@ let b = registerModule('b', parseModule(`
`)); `));
b.declarationInstantiation(); b.declarationInstantiation();
assertThrowsMyError(() => b.evaluation(b)); assertThrowsMyError(() => b.evaluation(b));
drainJobQueue();

Просмотреть файл

@ -1,3 +1,4 @@
// |jit-test| --enable-top-level-await;
// Test importing module namespaces // Test importing module namespaces
"use strict"; "use strict";
@ -90,7 +91,14 @@ let d = registerModule('d',
parseModule("export let d = 2; import * as ns from 'c'; let c = ns.c;")); parseModule("export let d = 2; import * as ns from 'c'; let c = ns.c;"));
c.declarationInstantiation(); c.declarationInstantiation();
d.declarationInstantiation(); d.declarationInstantiation();
assertThrowsInstanceOf(() => c.evaluation(), ReferenceError); c.evaluation()
.then(r => {
// We expect the evaluation to throw, so we should not reach this.
assertEq(false, true)
})
.catch(e => {
assertEq(e instanceof ReferenceError, true)
});
// Test cyclic namespace import. // Test cyclic namespace import.
let e = registerModule('e', let e = registerModule('e',
@ -103,3 +111,4 @@ e.evaluation();
f.evaluation(); f.evaluation();
assertEq(e.namespace.f(), 2); assertEq(e.namespace.f(), 2);
assertEq(f.namespace.e(), 1); assertEq(f.namespace.e(), 1);
drainJobQueue();

Просмотреть файл

@ -1,34 +1,46 @@
// |jit-test| --enable-top-level-await;
// Exercise ModuleEvaluation() concrete method. // Exercise ModuleEvaluation() concrete method.
load(libdir + "asserts.js"); load(libdir + "asserts.js");
function parseAndEvaluate(source) { async function parseAndEvaluate(source) {
let m = parseModule(source); let m = parseModule(source);
m.declarationInstantiation(); m.declarationInstantiation();
m.evaluation(); await m.evaluation();
return m; return m;
} }
// Check the evaluation of an empty module succeeds. // Check the evaluation of an empty module succeeds.
parseAndEvaluate(""); (async () => {
await parseAndEvaluate("");
})();
// Check evaluation returns evaluation result the first time, then undefined. (async () => {
let m = parseModule("1"); // Check that evaluation returns evaluation promise,
m.declarationInstantiation(); // and promise is always the same.
assertEq(m.evaluation(), undefined); let m = parseModule("1");
assertEq(typeof m.evaluation(), "undefined"); m.declarationInstantiation();
assertEq(typeof m.evaluation(), "object");
assertEq(m.evaluation() instanceof Promise, true);
assertEq(m.evaluation(), m.evaluation());
await m.evaluation();
})();
// Check top level variables are initialized by evaluation. (async () => {
m = parseModule("export var x = 2 + 2;"); // Check top level variables are initialized by evaluation.
assertEq(typeof getModuleEnvironmentValue(m, "x"), "undefined"); let m = parseModule("export var x = 2 + 2;");
m.declarationInstantiation(); assertEq(typeof getModuleEnvironmentValue(m, "x"), "undefined");
m.evaluation(); m.declarationInstantiation();
assertEq(getModuleEnvironmentValue(m, "x"), 4); await m.evaluation();
assertEq(getModuleEnvironmentValue(m, "x"), 4);
})();
m = parseModule("export let x = 2 * 3;"); (async () => {
m.declarationInstantiation(); let m = parseModule("export let x = 2 * 3;");
m.evaluation(); m.declarationInstantiation();
assertEq(getModuleEnvironmentValue(m, "x"), 6); await m.evaluation();
assertEq(getModuleEnvironmentValue(m, "x"), 6);
})();
// Set up a module to import from. // Set up a module to import from.
let a = registerModule('a', let a = registerModule('a',
@ -37,62 +49,77 @@ let a = registerModule('a',
export default 2; export default 2;
export function f(x) { return x + 1; }`)); export function f(x) { return x + 1; }`));
// Check we can evaluate top level definitions. (async () => {
parseAndEvaluate("var foo = 1;"); // Check we can evaluate top level definitions.
parseAndEvaluate("let foo = 1;"); await parseAndEvaluate("var foo = 1;");
parseAndEvaluate("const foo = 1"); await parseAndEvaluate("let foo = 1;");
parseAndEvaluate("function foo() {}"); await parseAndEvaluate("const foo = 1");
parseAndEvaluate("class foo { constructor() {} }"); await parseAndEvaluate("function foo() {}");
await parseAndEvaluate("class foo { constructor() {} }");
// Check we can evaluate all module-related syntax. // Check we can evaluate all module-related syntax.
parseAndEvaluate("export var foo = 1;"); await parseAndEvaluate("export var foo = 1;");
parseAndEvaluate("export let foo = 1;"); await parseAndEvaluate("export let foo = 1;");
parseAndEvaluate("export const foo = 1;"); await parseAndEvaluate("export const foo = 1;");
parseAndEvaluate("var x = 1; export { x };"); await parseAndEvaluate("var x = 1; export { x };");
parseAndEvaluate("export default 1"); await parseAndEvaluate("export default 1");
parseAndEvaluate("export default function() {};"); await parseAndEvaluate("export default function() {};");
parseAndEvaluate("export default function foo() {};"); await parseAndEvaluate("export default function foo() {};");
parseAndEvaluate("import a from 'a';"); await parseAndEvaluate("import a from 'a';");
parseAndEvaluate("import { x } from 'a';"); await parseAndEvaluate("import { x } from 'a';");
parseAndEvaluate("import * as ns from 'a';"); await parseAndEvaluate("import * as ns from 'a';");
parseAndEvaluate("export * from 'a'"); await parseAndEvaluate("export * from 'a'");
parseAndEvaluate("export default class { constructor() {} };"); await parseAndEvaluate("export default class { constructor() {} };");
parseAndEvaluate("export default class foo { constructor() {} };"); await parseAndEvaluate("export default class foo { constructor() {} };");
})();
// Test default import (async () => {
m = parseModule("import a from 'a'; export { a };") // Test default import
m.declarationInstantiation(); let m = parseModule("import a from 'a'; export { a };")
m.evaluation() m.declarationInstantiation();
assertEq(getModuleEnvironmentValue(m, "a"), 2); await m.evaluation()
assertEq(getModuleEnvironmentValue(m, "a"), 2);
})();
// Test named import (async () => {
m = parseModule("import { x as y } from 'a'; export { y };") // Test named import
m.declarationInstantiation(); let m = parseModule("import { x as y } from 'a'; export { y };")
m.evaluation(); m.declarationInstantiation();
assertEq(getModuleEnvironmentValue(m, "y"), 1); await m.evaluation();
assertEq(getModuleEnvironmentValue(m, "y"), 1);
})();
// Call exported function (async () => {
m = parseModule("import { f } from 'a'; export let x = f(3);") // Call exported function
m.declarationInstantiation(); let m = parseModule("import { f } from 'a'; export let x = f(3);")
m.evaluation(); m.declarationInstantiation();
assertEq(getModuleEnvironmentValue(m, "x"), 4); await m.evaluation();
assertEq(getModuleEnvironmentValue(m, "x"), 4);
})();
// Test importing an indirect export (async () => {
registerModule('b', parseModule("export { x as z } from 'a';")); // Test importing an indirect export
m = parseAndEvaluate("import { z } from 'b'; export { z }"); registerModule('b', parseModule("export { x as z } from 'a';"));
assertEq(getModuleEnvironmentValue(m, "z"), 1); let m = await parseAndEvaluate("import { z } from 'b'; export { z }");
assertEq(getModuleEnvironmentValue(m, "z"), 1);
})();
// Test cyclic dependencies (async () => {
registerModule('c1', parseModule("export var x = 1; export {y} from 'c2'")); // Test cyclic dependencies
registerModule('c2', parseModule("export var y = 2; export {x} from 'c1'")); registerModule('c1', parseModule("export var x = 1; export {y} from 'c2'"));
m = parseAndEvaluate(`import { x as x1, y as y1 } from 'c1'; registerModule('c2', parseModule("export var y = 2; export {x} from 'c1'"));
import { x as x2, y as y2 } from 'c2'; let m = await parseAndEvaluate(`import { x as x1, y as y1 } from 'c1';
export let z = [x1, y1, x2, y2]`), import { x as x2, y as y2 } from 'c2';
assertDeepEq(getModuleEnvironmentValue(m, "z"), [1, 2, 1, 2]); export let z = [x1, y1, x2, y2]`);
assertDeepEq(getModuleEnvironmentValue(m, "z"), [1, 2, 1, 2]);
})();
// Import access in functions (async () => {
m = parseModule("import { x } from 'a'; function f() { return x; }") // Import access in functions
m.declarationInstantiation(); let m = await parseModule("import { x } from 'a'; function f() { return x; }")
m.evaluation(); m.declarationInstantiation();
let f = getModuleEnvironmentValue(m, "f"); m.evaluation();
assertEq(f(), 1); let f = getModuleEnvironmentValue(m, "f");
assertEq(f(), 1);
})();
drainJobQueue();

Просмотреть файл

@ -1,3 +1,4 @@
// |jit-test| --enable-top-level-await;
// Test 'this' is undefined in modules. // Test 'this' is undefined in modules.
function parseAndEvaluate(source) { function parseAndEvaluate(source) {
@ -6,10 +7,19 @@ function parseAndEvaluate(source) {
return m.evaluation(); return m.evaluation();
} }
assertEq(typeof(parseAndEvaluate("this")), "undefined"); parseAndEvaluate("this")
.then(value => assertEq(typeof(value), "undefined"))
.catch(error => {
// We shouldn't throw in this case.
assertEq(false, true)
});
let m = parseModule("export function getThis() { return this; }"); let m = parseModule("export function getThis() { return this; }");
m.declarationInstantiation(); m.declarationInstantiation();
m.evaluation(); m.evaluation()
let f = getModuleEnvironmentValue(m, "getThis"); .then(() => {
assertEq(typeof(f()), "undefined"); let f = getModuleEnvironmentValue(m, "getThis");
assertEq(typeof(f()), "undefined");
});
drainJobQueue();

Просмотреть файл

@ -1,81 +1,93 @@
// |jit-test| --enable-top-level-await;
load(libdir + "asserts.js"); load(libdir + "asserts.js");
function parseAndEvaluate(source) { async function parseAndEvaluate(source) {
let og = parseModule(source); let og = parseModule(source);
let bc = codeModule(og); let bc = codeModule(og);
let m = decodeModule(bc); let m = decodeModule(bc);
m.declarationInstantiation(); m.declarationInstantiation();
m.evaluation(); await m.evaluation();
return m; return m;
} }
// Check the evaluation of an empty module succeeds. (async () => {
parseAndEvaluate(""); // Check the evaluation of an empty module succeeds.
await parseAndEvaluate("");
})();
// Check evaluation returns evaluation result the first time, then undefined. (async () => {
let og = parseModule("1"); // Check that evaluation returns evaluation promise,
let bc = codeModule(og); // and promise is always the same.
let m = decodeModule(bc); let og = parseModule("1");
m.declarationInstantiation(); let bc = codeModule(og);
assertEq(m.evaluation(), undefined); let m = decodeModule(bc);
assertEq(typeof m.evaluation(), "undefined"); m.declarationInstantiation();
assertEq(typeof m.evaluation(), "object");
assertEq(m.evaluation() instanceof Promise, true);
assertEq(m.evaluation(), m.evaluation());
})();
// Check top level variables are initialized by evaluation. (async () => {
og = parseModule("export var x = 2 + 2;"); // Check top level variables are initialized by evaluation.
bc = codeModule(og); let og = parseModule("export var x = 2 + 2;");
m = decodeModule(bc); let bc = codeModule(og);
assertEq(typeof getModuleEnvironmentValue(m, "x"), "undefined"); let m = decodeModule(bc);
m.declarationInstantiation(); assertEq(typeof getModuleEnvironmentValue(m, "x"), "undefined");
m.evaluation(); m.declarationInstantiation();
assertEq(getModuleEnvironmentValue(m, "x"), 4); await m.evaluation();
assertEq(getModuleEnvironmentValue(m, "x"), 4);
})();
m = parseAndEvaluate("export let x = 2 * 3;"); (async () => {
assertEq(getModuleEnvironmentValue(m, "x"), 6); let m = await parseAndEvaluate("export let x = 2 * 3;");
assertEq(getModuleEnvironmentValue(m, "x"), 6);
// Set up a module to import from. // Set up a module to import from.
og = parseModule(`var x = 1; let og = parseModule(`var x = 1;
export { x }; export { x };
export default 2; export default 2;
export function f(x) { return x + 1; }`); export function f(x) { return x + 1; }`);
bc = codeModule(og); let bc = codeModule(og);
a = registerModule('a', decodeModule(bc)); let a = registerModule('a', decodeModule(bc));
// Check we can evaluate top level definitions. // Check we can evaluate top level definitions.
parseAndEvaluate("var foo = 1;"); await parseAndEvaluate("var foo = 1;");
parseAndEvaluate("let foo = 1;"); await parseAndEvaluate("let foo = 1;");
parseAndEvaluate("const foo = 1"); await parseAndEvaluate("const foo = 1");
parseAndEvaluate("function foo() {}"); await parseAndEvaluate("function foo() {}");
parseAndEvaluate("class foo { constructor() {} }"); await parseAndEvaluate("class foo { constructor() {} }");
// Check we can evaluate all module-related syntax. // Check we can evaluate all module-related syntax.
parseAndEvaluate("export var foo = 1;"); await parseAndEvaluate("export var foo = 1;");
parseAndEvaluate("export let foo = 1;"); await parseAndEvaluate("export let foo = 1;");
parseAndEvaluate("export const foo = 1;"); await parseAndEvaluate("export const foo = 1;");
parseAndEvaluate("var x = 1; export { x };"); await parseAndEvaluate("var x = 1; export { x };");
parseAndEvaluate("export default 1"); await parseAndEvaluate("export default 1");
parseAndEvaluate("export default function() {};"); await parseAndEvaluate("export default function() {};");
parseAndEvaluate("export default function foo() {};"); await parseAndEvaluate("export default function foo() {};");
parseAndEvaluate("import a from 'a';"); await parseAndEvaluate("import a from 'a';");
parseAndEvaluate("import { x } from 'a';"); await parseAndEvaluate("import { x } from 'a';");
parseAndEvaluate("import * as ns from 'a';"); await parseAndEvaluate("import * as ns from 'a';");
parseAndEvaluate("export * from 'a'"); await parseAndEvaluate("export * from 'a'");
parseAndEvaluate("export default class { constructor() {} };"); await parseAndEvaluate("export default class { constructor() {} };");
parseAndEvaluate("export default class foo { constructor() {} };"); await parseAndEvaluate("export default class foo { constructor() {} };");
// Test default import // Test default import
m = parseAndEvaluate("import a from 'a'; export { a };") m = await parseAndEvaluate("import a from 'a'; export { a };")
assertEq(getModuleEnvironmentValue(m, "a"), 2); assertEq(getModuleEnvironmentValue(m, "a"), 2);
// Test named import // Test named import
m = parseAndEvaluate("import { x as y } from 'a'; export { y };") m = await parseAndEvaluate("import { x as y } from 'a'; export { y };")
assertEq(getModuleEnvironmentValue(m, "y"), 1); assertEq(getModuleEnvironmentValue(m, "y"), 1);
// Call exported function // Call exported function
m = parseAndEvaluate("import { f } from 'a'; export let x = f(3);") m = await parseAndEvaluate("import { f } from 'a'; export let x = f(3);")
assertEq(getModuleEnvironmentValue(m, "x"), 4); assertEq(getModuleEnvironmentValue(m, "x"), 4);
// Import access in functions // Import access in functions
m = parseAndEvaluate("import { x } from 'a'; function f() { return x; }") m = await parseAndEvaluate("import { x } from 'a'; function f() { return x; }")
let f = getModuleEnvironmentValue(m, "f"); let f = getModuleEnvironmentValue(m, "f");
assertEq(f(), 1); assertEq(f(), 1);
})();
drainJobQueue();