@masknet/compartment
Advanced tools
Comparing version 0.3.11 to 0.3.13
@@ -72,4 +72,4 @@ class ModuleSource { | ||
} | ||
/** @internal */ function assert(val) { | ||
if (!val) throw new TypeError('Internal error.'); | ||
/** @internal */ function assertFailed() { | ||
throw new TypeError('Assertion failed.'); | ||
} | ||
@@ -211,3 +211,3 @@ /** @internal */ function unreachable(val) { | ||
if (isExportAllBinding(binding2)) { | ||
assert(binding2.as !== undefined); | ||
if (!(binding2.as !== undefined)) assertFailed(); | ||
indirectExportEntries.push({ | ||
@@ -244,2 +244,14 @@ ExportName: binding2.as, | ||
let asyncTaskPolyfill; | ||
function getAsyncTaskAPI() { | ||
if (typeof console === 'object' && typeof console.createTask === 'function') return console.createTask; | ||
return (_name)=>asyncTaskPolyfill ||= { | ||
run: Function.prototype.call.bind(Function.call) | ||
}; | ||
} | ||
/** | ||
* @internal | ||
* @see https://developer.chrome.com/docs/devtools/console/api/#createtask | ||
*/ const createTask = /*#__PURE__*/ getAsyncTaskAPI(); | ||
let imports; | ||
@@ -317,14 +329,14 @@ /** @internal */ let setGlobalThis; | ||
for (const e of module.#LocalExportEntries){ | ||
assert(e.ExportName !== null); | ||
if (!(e.ExportName !== null)) assertFailed(); | ||
exportedNames.push(e.ExportName); | ||
} | ||
for (const e1 of module.#IndirectExportEntries){ | ||
assert(e1.ExportName !== null); | ||
if (!(e1.ExportName !== null)) assertFailed(); | ||
exportedNames.push(e1.ExportName); | ||
} | ||
for (const e2 of module.#StarExportEntries){ | ||
assert(e2.ModuleRequest !== null); | ||
if (!(e2.ModuleRequest !== null)) assertFailed(); | ||
const requestedModule = Module.#GetImportedModule(module, e2.ModuleRequest); | ||
// TODO: https://github.com/tc39/ecma262/pull/2905/files#r973044508 | ||
assert(requestedModule); | ||
if (!requestedModule) assertFailed(); | ||
const starNames = requestedModule.#GetExportedNames(exportStarSet); | ||
@@ -354,3 +366,3 @@ for (const n of starNames){ | ||
if (exportName === e3.ExportName) { | ||
// assert(e.LocalName !== null) | ||
// if (!(e.LocalName !== null)) assertFailed() | ||
// return { module, bindingName: e.LocalName } | ||
@@ -365,6 +377,6 @@ return { | ||
if (exportName === e4.ExportName) { | ||
assert(e4.ModuleRequest !== null); | ||
if (!(e4.ModuleRequest !== null)) assertFailed(); | ||
const importedModule = Module.#GetImportedModule(module1, e4.ModuleRequest); | ||
// TODO: https://github.com/tc39/ecma262/pull/2905/files#r973044508 | ||
assert(importedModule); | ||
if (!importedModule) assertFailed(); | ||
if (e4.ImportName === all) { | ||
@@ -377,3 +389,3 @@ // Assert: module does not provide the direct binding for this export. | ||
} else { | ||
assert(typeof e4.ImportName === 'string'); | ||
if (!(typeof e4.ImportName === 'string')) assertFailed(); | ||
return importedModule.#ResolveExport(e4.ImportName, resolveSet); | ||
@@ -390,6 +402,6 @@ } | ||
for (const e5 of module1.#StarExportEntries){ | ||
assert(e5.ModuleRequest !== null); | ||
if (!(e5.ModuleRequest !== null)) assertFailed(); | ||
const importedModule1 = Module.#GetImportedModule(module1, e5.ModuleRequest); | ||
// TODO: https://github.com/tc39/ecma262/pull/2905/files#r973044508 | ||
assert(importedModule1); | ||
if (!importedModule1) assertFailed(); | ||
let resolution = importedModule1.#ResolveExport(exportName, resolveSet); | ||
@@ -411,3 +423,3 @@ if (resolution === ambiguous) return ambiguous; | ||
} | ||
#LoadRequestedModules(HostDefined = undefined) { | ||
#LoadRequestedModules(HostDefined) { | ||
const module2 = this; | ||
@@ -427,3 +439,3 @@ const pc = PromiseCapability(); | ||
static #InnerModuleLoading(state1, module3) { | ||
assert(state1.Action === 'graph-loading' && state1.IsLoading); | ||
if (!state1.IsLoading) assertFailed(); | ||
if (module3.#Status === 0 && !state1.Visited.includes(module3)) { | ||
@@ -434,11 +446,14 @@ state1.Visited.push(module3); | ||
for (const required of module3.#RequestedModules){ | ||
const record = module3.#LoadedModules.get(required); | ||
if (record) { | ||
Module.#ContinueModuleLoading(state1, NormalCompletion(record)); | ||
} else { | ||
Module.#HostLoadImportedModule(module3, required, state1.HostDefined, state1); | ||
if (state1.IsLoading) { | ||
const record = module3.#LoadedModules.get(required); | ||
if (record) { | ||
Module.#InnerModuleLoading(state1, record); | ||
} else { | ||
Module.#HostLoadImportedModule(module3, required, state1.HostDefined, state1); | ||
} | ||
} | ||
} | ||
} | ||
assert(state1.PendingModules >= 1); | ||
if (!state1.IsLoading) return; | ||
if (!(state1.PendingModules >= 1)) assertFailed(); | ||
state1.PendingModules = state1.PendingModules - 1; | ||
@@ -453,9 +468,8 @@ if (state1.PendingModules === 0) { | ||
} | ||
static #ContinueModuleLoading(state2, result) { | ||
assert(state2.Action === 'graph-loading'); | ||
static #ContinueModuleLoading(state2, moduleCompletion) { | ||
if (!state2.IsLoading) return; | ||
if (result.Type === 'normal') Module.#InnerModuleLoading(state2, result.Value); | ||
if (moduleCompletion.Type === 'normal') Module.#InnerModuleLoading(state2, moduleCompletion.Value); | ||
else { | ||
state2.IsLoading = false; | ||
state2.PromiseCapability.Reject(result.Value); | ||
state2.PromiseCapability.Reject(moduleCompletion.Value); | ||
} | ||
@@ -484,3 +498,3 @@ } | ||
for (const e6 of module4.#IndirectExportEntries){ | ||
assert(e6.ExportName !== null); | ||
if (!(e6.ExportName !== null)) assertFailed(); | ||
const resolution1 = module4.#ResolveExport(e6.ExportName); | ||
@@ -502,3 +516,3 @@ if (resolution1 === null || resolution1 === ambiguous) { | ||
const importedModule2 = Module.#GetImportedModule(module4, i.ModuleRequest); | ||
assert(importedModule2); | ||
if (!importedModule2) assertFailed(); | ||
// import * as ns from '..' | ||
@@ -549,3 +563,3 @@ if (i.ImportName === namespace) { | ||
for (const { ModuleRequest , ExportName , ImportName } of module4.#LocalExportEntries){ | ||
assert(ModuleRequest === null && typeof ExportName === 'string' && ImportName === null); | ||
if (!(ModuleRequest === null && typeof ExportName === 'string' && ImportName === null)) assertFailed(); | ||
propertiesToBeDefined[ExportName] = { | ||
@@ -573,3 +587,3 @@ get: ()=>this.#LocalExportedValues.get(ExportName), | ||
} | ||
#ExecuteModule(promise) { | ||
/** All call to ExecuteModule must use Task.run to keep the call stack continue */ #ExecuteModule(promise) { | ||
// prepare context | ||
@@ -585,3 +599,4 @@ this.#ContextObject.globalThis = this.#GlobalThis; | ||
Action: 'dynamic-import', | ||
PromiseCapability: PromiseCapability() | ||
PromiseCapability: PromiseCapability(), | ||
HostDefined: createTask(`import("${specifier}")`) | ||
}; | ||
@@ -592,6 +607,6 @@ Module.#HostLoadImportedModule(this, specifier, status.HostDefined, status); | ||
} | ||
assert(this.#Environment); | ||
if (!this.#Environment) assertFailed(); | ||
const env1 = new Proxy(this.#Environment, moduleEnvExoticMethods); | ||
if (!this.#HasTLA) { | ||
assert(!promise); | ||
if (!!promise) assertFailed(); | ||
if (this.#Execute) { | ||
@@ -604,3 +619,3 @@ Reflect.apply(this.#Execute, this.#Source, [ | ||
} else { | ||
assert(promise); | ||
if (!promise) assertFailed(); | ||
if (this.#Execute) { | ||
@@ -618,3 +633,3 @@ Promise.resolve(Reflect.apply(this.#Execute, this.#Source, [ | ||
const module5 = this; | ||
assert([ | ||
if (![ | ||
1, | ||
@@ -624,3 +639,3 @@ 3, | ||
6 | ||
].includes(module5.#Status)); | ||
].includes(module5.#Status)) assertFailed(); | ||
const stack = []; | ||
@@ -631,24 +646,24 @@ try { | ||
for (const mod of stack){ | ||
assert(mod.#Status === 2); | ||
if (!(mod.#Status === 2)) assertFailed(); | ||
mod.#Status = 1; | ||
} | ||
assert(module5.#Status === 1); | ||
if (!(module5.#Status === 1)) assertFailed(); | ||
throw err; | ||
} | ||
assert([ | ||
if (![ | ||
3, | ||
5, | ||
6 | ||
].includes(module5.#Status)); | ||
assert(stack.length === 0); | ||
].includes(module5.#Status)) assertFailed(); | ||
if (!(stack.length === 0)) assertFailed(); | ||
} | ||
// https://tc39.es/ecma262/#sec-moduleevaluation | ||
#Evaluate() { | ||
#Evaluate(HostDefined1) { | ||
let module6 = this; | ||
// TODO: Assert: This call to Evaluate is not happening at the same time as another call to Evaluate within the surrounding agent. | ||
assert([ | ||
if (![ | ||
3, | ||
5, | ||
6 | ||
].includes(module6.#Status)); | ||
].includes(module6.#Status)) assertFailed(); | ||
if ([ | ||
@@ -659,3 +674,3 @@ 5, | ||
module6 = module6.#CycleRoot; | ||
assert(module6) // TODO: https://github.com/tc39/ecma262/issues/2823 | ||
if (!module6) assertFailed() // TODO: https://github.com/tc39/ecma262/issues/2823 | ||
; | ||
@@ -668,24 +683,24 @@ } | ||
try { | ||
Module.#InnerModuleEvaluation(module6, stack1, 0); | ||
Module.#InnerModuleEvaluation(module6, stack1, 0, HostDefined1); | ||
} catch (err1) { | ||
for (const m of stack1){ | ||
assert(m.#Status === 4); | ||
if (!(m.#Status === 4)) assertFailed(); | ||
m.#Status = 6; | ||
m.#EvaluationError = err1; | ||
} | ||
assert(module6.#Status === 6); | ||
assert(module6.#EvaluationError === err1); | ||
if (!(module6.#Status === 6)) assertFailed(); | ||
if (!(module6.#EvaluationError === err1)) assertFailed(); | ||
capability.Reject(err1); | ||
return capability.Promise; | ||
} | ||
assert([ | ||
if (![ | ||
5, | ||
6 | ||
].includes(module6.#Status)); | ||
assert(module6.#EvaluationError === empty); | ||
].includes(module6.#Status)) assertFailed(); | ||
if (!(module6.#EvaluationError === empty)) assertFailed(); | ||
if (module6.#AsyncEvaluation === false) { | ||
assert(module6.#Status === 6); | ||
if (!(module6.#Status === 6)) assertFailed(); | ||
capability.Resolve(); | ||
} | ||
assert(stack1.length === 0); | ||
if (!(stack1.length === 0)) assertFailed(); | ||
return capability.Promise; | ||
@@ -703,3 +718,3 @@ } | ||
} | ||
assert(module7.#Status === 1); | ||
if (!(module7.#Status === 1)) assertFailed(); | ||
module7.#Status = 2; | ||
@@ -712,5 +727,5 @@ module7.#DFSIndex = index; | ||
const requiredModule = this.#GetImportedModule(module7, required1); | ||
assert(requiredModule); | ||
if (!requiredModule) assertFailed(); | ||
index = this.#InnerModuleLinking(requiredModule, stack2, index); | ||
assert([ | ||
if (![ | ||
2, | ||
@@ -720,7 +735,7 @@ 3, | ||
6 | ||
].includes(requiredModule.#Status)); | ||
].includes(requiredModule.#Status)) assertFailed(); | ||
if (stack2.includes(requiredModule)) { | ||
assert(requiredModule.#Status === 2); | ||
if (!(requiredModule.#Status === 2)) assertFailed(); | ||
} else { | ||
assert(requiredModule.#Status !== 2); | ||
if (!(requiredModule.#Status !== 2)) assertFailed(); | ||
} | ||
@@ -732,4 +747,4 @@ if (requiredModule.#Status === 2) { | ||
module7.#InitializeEnvironment(); | ||
assert(stack2.filter((x)=>x === module7).length === 1); | ||
assert(module7.#DFSAncestorIndex <= module7.#DFSIndex); | ||
if (!(stack2.filter((x)=>x === module7).length === 1)) assertFailed(); | ||
if (!(module7.#DFSAncestorIndex <= module7.#DFSIndex)) assertFailed(); | ||
if (module7.#DFSAncestorIndex === module7.#DFSIndex) { | ||
@@ -746,3 +761,3 @@ let done = false; | ||
// https://tc39.es/ecma262/#sec-InnerModuleEvaluation | ||
static #InnerModuleEvaluation(module8, stack3, index1) { | ||
static #InnerModuleEvaluation(module8, stack3, index1, HostDefined2) { | ||
if ([ | ||
@@ -756,3 +771,3 @@ 5, | ||
if (module8.#Status === 4) return index1; | ||
assert(module8.#Status === 3); | ||
if (!(module8.#Status === 3)) assertFailed(); | ||
module8.#Status = 4; | ||
@@ -766,13 +781,13 @@ module8.#DFSIndex = index1; | ||
let requiredModule2 = this.#GetImportedModule(module8, required2); | ||
assert(requiredModule2); | ||
index1 = this.#InnerModuleEvaluation(requiredModule2, stack3, index1); | ||
assert([ | ||
if (!requiredModule2) assertFailed(); | ||
index1 = this.#InnerModuleEvaluation(requiredModule2, stack3, index1, HostDefined2); | ||
if (![ | ||
4, | ||
5, | ||
6 | ||
].includes(requiredModule2.#Status)); | ||
].includes(requiredModule2.#Status)) assertFailed(); | ||
if (stack3.includes(requiredModule2)) { | ||
assert(requiredModule2.#Status === 4); | ||
if (!(requiredModule2.#Status === 4)) assertFailed(); | ||
} else { | ||
assert(requiredModule2.#Status !== 4); | ||
if (!(requiredModule2.#Status !== 4)) assertFailed(); | ||
} | ||
@@ -783,6 +798,6 @@ if (requiredModule2.#Status === 4) { | ||
requiredModule2 = requiredModule2.#CycleRoot; | ||
assert([ | ||
if (![ | ||
5, | ||
6 | ||
].includes(requiredModule2.#Status)); | ||
].includes(requiredModule2.#Status)) assertFailed(); | ||
if (requiredModule2.#EvaluationError !== empty) throw requiredModule2.#EvaluationError; | ||
@@ -796,4 +811,4 @@ } | ||
if (module8.#PendingAsyncDependencies > 0 || module8.#HasTLA) { | ||
assert(module8.#AsyncEvaluation === false); | ||
assert(module8.#__AsyncEvaluationPreviouslyTrue === false); | ||
if (!(module8.#AsyncEvaluation === false)) assertFailed(); | ||
if (!(module8.#__AsyncEvaluationPreviouslyTrue === false)) assertFailed(); | ||
module8.#AsyncEvaluation = true; | ||
@@ -803,9 +818,9 @@ module8.#__AsyncEvaluationPreviouslyTrue = true; | ||
if (module8.#PendingAsyncDependencies === 0) { | ||
this.#ExecuteAsyncModule(module8); | ||
this.#ExecuteAsyncModule(module8, HostDefined2); | ||
} | ||
} else { | ||
module8.#ExecuteModule(); | ||
HostDefined2.run(()=>module8.#ExecuteModule()); | ||
} | ||
assert(stack3.filter((x)=>x === module8).length === 1); | ||
assert(module8.#DFSAncestorIndex <= module8.#DFSIndex); | ||
if (!(stack3.filter((x)=>x === module8).length === 1)) assertFailed(); | ||
if (!(module8.#DFSAncestorIndex <= module8.#DFSIndex)) assertFailed(); | ||
if (module8.#DFSAncestorIndex === module8.#DFSIndex) { | ||
@@ -827,15 +842,15 @@ let done1 = false; | ||
// https://tc39.es/ecma262/#sec-execute-async-module | ||
static #ExecuteAsyncModule(module9) { | ||
assert([ | ||
static #ExecuteAsyncModule(module9, HostDefined3) { | ||
if (![ | ||
4, | ||
5 | ||
].includes(module9.#Status)); | ||
assert(module9.#HasTLA); | ||
].includes(module9.#Status)) assertFailed(); | ||
if (!module9.#HasTLA) assertFailed(); | ||
const capability1 = PromiseCapability(); | ||
capability1.Promise.then(()=>{ | ||
this.#AsyncModuleExecutionFulfilled(module9); | ||
this.#AsyncModuleExecutionFulfilled(module9, HostDefined3); | ||
}, (error)=>{ | ||
this.#AsyncModuleExecutionRejected(module9, error); | ||
}); | ||
module9.#ExecuteModule(capability1); | ||
HostDefined3.run(()=>module9.#ExecuteModule(capability1)); | ||
} | ||
@@ -846,6 +861,6 @@ // https://tc39.es/ecma262/#sec-gather-available-ancestors | ||
if (!execList.includes(m1) && m1.#CycleRoot.#EvaluationError === empty) { | ||
assert(m1.#Status === 5); | ||
assert(m1.#EvaluationError === empty); | ||
assert(m1.#AsyncEvaluation === true); | ||
assert(m1.#PendingAsyncDependencies > 0); | ||
if (!(m1.#Status === 5)) assertFailed(); | ||
if (!(m1.#EvaluationError === empty)) assertFailed(); | ||
if (!(m1.#AsyncEvaluation === true)) assertFailed(); | ||
if (!(m1.#PendingAsyncDependencies > 0)) assertFailed(); | ||
m1.#PendingAsyncDependencies--; | ||
@@ -860,14 +875,14 @@ if (m1.#PendingAsyncDependencies === 0) { | ||
// https://tc39.es/ecma262/#sec-async-module-execution-fulfilled | ||
static #AsyncModuleExecutionFulfilled(module11) { | ||
static #AsyncModuleExecutionFulfilled(module11, HostDefined4) { | ||
if (module11.#Status === 6) { | ||
assert(module11.#EvaluationError !== empty); | ||
if (!(module11.#EvaluationError !== empty)) assertFailed(); | ||
return; | ||
} | ||
assert(module11.#Status === 5); | ||
assert(module11.#AsyncEvaluation === true); | ||
assert(module11.#EvaluationError === empty); | ||
if (!(module11.#Status === 5)) assertFailed(); | ||
if (!(module11.#AsyncEvaluation === true)) assertFailed(); | ||
if (!(module11.#EvaluationError === empty)) assertFailed(); | ||
module11.#AsyncEvaluation = false; | ||
module11.#Status = 6; | ||
if (module11.#TopLevelCapability) { | ||
assert(module11.#CycleRoot === module11); | ||
if (!(module11.#CycleRoot === module11)) assertFailed(); | ||
module11.#TopLevelCapability.Resolve(); | ||
@@ -879,11 +894,11 @@ } | ||
const sortedExecList = execList1; | ||
assert(sortedExecList.every((x)=>x.#AsyncEvaluation && x.#PendingAsyncDependencies === 0 && x.#EvaluationError === empty)); | ||
if (!sortedExecList.every((x)=>x.#AsyncEvaluation && x.#PendingAsyncDependencies === 0 && x.#EvaluationError === empty)) assertFailed(); | ||
for (const m2 of sortedExecList){ | ||
if (m2.#Status === 6) { | ||
assert(m2.#EvaluationError !== empty); | ||
if (!(m2.#EvaluationError !== empty)) assertFailed(); | ||
} else if (m2.#HasTLA) { | ||
this.#ExecuteAsyncModule(m2); | ||
this.#ExecuteAsyncModule(m2, HostDefined4); | ||
} else { | ||
try { | ||
m2.#ExecuteModule(); | ||
HostDefined4.run(()=>m2.#ExecuteModule()); | ||
} catch (err2) { | ||
@@ -895,3 +910,3 @@ this.#AsyncModuleExecutionRejected(m2, err2); | ||
if (m2.#TopLevelCapability) { | ||
assert(m2.#CycleRoot === m2); | ||
if (!(m2.#CycleRoot === m2)) assertFailed(); | ||
m2.#TopLevelCapability.Resolve(); | ||
@@ -905,8 +920,8 @@ } | ||
if (module.#Status === 6) { | ||
assert(module.#EvaluationError !== empty); | ||
if (!(module.#EvaluationError !== empty)) assertFailed(); | ||
return; | ||
} | ||
assert(module.#Status === 5); | ||
assert(module.#AsyncEvaluation === true); | ||
assert(module.#EvaluationError === empty); | ||
if (!(module.#Status === 5)) assertFailed(); | ||
if (!(module.#AsyncEvaluation === true)) assertFailed(); | ||
if (!(module.#EvaluationError === empty)) assertFailed(); | ||
module.#EvaluationError = error; | ||
@@ -918,3 +933,3 @@ module.#Status = 6; | ||
if (module.#TopLevelCapability) { | ||
assert(module.#CycleRoot === module); | ||
if (!(module.#CycleRoot === module)) assertFailed(); | ||
module.#TopLevelCapability.Reject(error); | ||
@@ -925,3 +940,3 @@ } | ||
if (module12.#Namespace) return module12.#Namespace; | ||
assert(module12.#Status !== 1); | ||
if (!(module12.#Status !== 1)) assertFailed(); | ||
const exportedNames1 = module12.#GetExportedNames(); | ||
@@ -988,7 +1003,7 @@ const namespaceObject2 = { | ||
promiseCapability?.Resolve(module); | ||
Module.#FinishLoadImportedModule(referrer, specifier, payload, NormalCompletion(module)); | ||
Module.#FinishLoadingImportedModule(referrer, specifier, payload, NormalCompletion(module)); | ||
} | ||
function onRejected(reason) { | ||
promiseCapability?.Reject(reason); | ||
Module.#FinishLoadImportedModule(referrer, specifier, payload, ThrowCompletion(reason)); | ||
Module.#FinishLoadingImportedModule(referrer, specifier, payload, ThrowCompletion(reason)); | ||
} | ||
@@ -1008,6 +1023,6 @@ if (promiseCapability) { | ||
try { | ||
const result1 = referrer.#ImportHook(specifier, referrer.#Referral); | ||
if (result1 === null) throw new SyntaxError(`Failed to load module ${specifier}.`); | ||
const result = referrer.#ImportHook(specifier, referrer.#Referral); | ||
if (result === null) throw new SyntaxError(`Failed to load module ${specifier}.`); | ||
try { | ||
const module14 = result1; | ||
const module14 = result; | ||
module14.#Referral; | ||
@@ -1018,3 +1033,3 @@ onFulfilled(module14); | ||
// treat it as a Promise | ||
Promise.resolve(result1).then((result)=>{ | ||
Promise.resolve(result).then((result)=>{ | ||
if (result === null) onRejected(new SyntaxError(`Failed to load module ${specifier}.`)); | ||
@@ -1033,32 +1048,32 @@ try { | ||
} | ||
static #FinishLoadImportedModule(referrer1, specifier1, state3, result2) { | ||
if (result2.Type === 'normal') { | ||
static #FinishLoadingImportedModule(referrer1, specifier1, state3, result1) { | ||
if (result1.Type === 'normal') { | ||
const record1 = referrer1.#LoadedModules.get(specifier1); | ||
if (record1) { | ||
assert(record1 === result2.Value); | ||
if (!(record1 === result1.Value)) assertFailed(); | ||
} else { | ||
referrer1.#LoadedModules.set(specifier1, result2.Value); | ||
referrer1.#LoadedModules.set(specifier1, result1.Value); | ||
} | ||
} | ||
if (state3.Action === 'graph-loading') { | ||
Module.#ContinueModuleLoading(state3, result2); | ||
Module.#ContinueModuleLoading(state3, result1); | ||
} else { | ||
Module.#ContinueDynamicImport(state3, result2); | ||
Module.#ContinueDynamicImport(state3, result1); | ||
} | ||
} | ||
static #ContinueDynamicImport(state4, result3) { | ||
assert(state4.Action === 'dynamic-import'); | ||
static #ContinueDynamicImport(state4, moduleCompletion1) { | ||
const promiseCapability1 = state4.PromiseCapability; | ||
if (result3.Type === 'throw') { | ||
promiseCapability1.Reject(result3.Value); | ||
if (moduleCompletion1.Type === 'throw') { | ||
promiseCapability1.Reject(moduleCompletion1.Value); | ||
return; | ||
} | ||
const module15 = result3.Value; | ||
const onRejected1 = (reason)=>{ | ||
const module15 = moduleCompletion1.Value; | ||
const loadPromise = module15.#LoadRequestedModules(state4.HostDefined); | ||
function onRejected1(reason) { | ||
promiseCapability1.Reject(reason); | ||
}; | ||
} | ||
function linkAndEvaluate() { | ||
try { | ||
module15.#Link(); | ||
const evaluatePromise = module15.#Evaluate(); | ||
const evaluatePromise = module15.#Evaluate(state4.HostDefined); | ||
function onFulfilled() { | ||
@@ -1077,3 +1092,2 @@ try { | ||
} | ||
const loadPromise = module15.#LoadRequestedModules(); | ||
loadPromise.then(linkAndEvaluate, onRejected1); | ||
@@ -1085,5 +1099,9 @@ } | ||
const promiseCapability = PromiseCapability(); | ||
let HostDefinedName = 'Module<...>'; | ||
if (typeof module.#Referral === 'symbol') HostDefinedName = `Module<@${module.#Referral.description}>`; | ||
else if (typeof module.#Referral === 'string') HostDefinedName = `"${module.#Referral}"`; | ||
const state = { | ||
Action: 'dynamic-import', | ||
PromiseCapability: promiseCapability | ||
PromiseCapability: promiseCapability, | ||
HostDefined: createTask(`import(${HostDefinedName})`) | ||
}; | ||
@@ -1090,0 +1108,0 @@ Module.#ContinueDynamicImport(state, NormalCompletion(module)); |
import { ModuleSource } from './ModuleSource.js'; | ||
import { all, ambiguous, empty, namespace, NormalCompletion, PromiseCapability, ThrowCompletion, } from './utils/spec.js'; | ||
import { normalizeBindingsToSpecRecord, normalizeVirtualModuleRecord } from './utils/normalize.js'; | ||
import { assert, internalError, opaqueProxy } from './utils/assert.js'; | ||
import { assertFailed, internalError, opaqueProxy } from './utils/assert.js'; | ||
import { defaultImportHook } from './Evaluators.js'; | ||
import { createTask } from './utils/async-task.js'; | ||
export let imports; | ||
@@ -95,14 +96,18 @@ /** @internal */ | ||
for (const e of module.#LocalExportEntries) { | ||
assert(e.ExportName !== null); | ||
if (!(e.ExportName !== null)) | ||
assertFailed(); | ||
exportedNames.push(e.ExportName); | ||
} | ||
for (const e of module.#IndirectExportEntries) { | ||
assert(e.ExportName !== null); | ||
if (!(e.ExportName !== null)) | ||
assertFailed(); | ||
exportedNames.push(e.ExportName); | ||
} | ||
for (const e of module.#StarExportEntries) { | ||
assert(e.ModuleRequest !== null); | ||
if (!(e.ModuleRequest !== null)) | ||
assertFailed(); | ||
const requestedModule = Module.#GetImportedModule(module, e.ModuleRequest); | ||
// TODO: https://github.com/tc39/ecma262/pull/2905/files#r973044508 | ||
assert(requestedModule); | ||
if (!requestedModule) | ||
assertFailed(); | ||
const starNames = requestedModule.#GetExportedNames(exportStarSet); | ||
@@ -131,3 +136,3 @@ for (const n of starNames) { | ||
if (exportName === e.ExportName) { | ||
// assert(e.LocalName !== null) | ||
// if (!(e.LocalName !== null)) assertFailed() | ||
// return { module, bindingName: e.LocalName } | ||
@@ -139,6 +144,8 @@ return { module, bindingName: e.ExportName }; | ||
if (exportName === e.ExportName) { | ||
assert(e.ModuleRequest !== null); | ||
if (!(e.ModuleRequest !== null)) | ||
assertFailed(); | ||
const importedModule = Module.#GetImportedModule(module, e.ModuleRequest); | ||
// TODO: https://github.com/tc39/ecma262/pull/2905/files#r973044508 | ||
assert(importedModule); | ||
if (!importedModule) | ||
assertFailed(); | ||
if (e.ImportName === all) { | ||
@@ -149,3 +156,4 @@ // Assert: module does not provide the direct binding for this export. | ||
else { | ||
assert(typeof e.ImportName === 'string'); | ||
if (!(typeof e.ImportName === 'string')) | ||
assertFailed(); | ||
return importedModule.#ResolveExport(e.ImportName, resolveSet); | ||
@@ -162,6 +170,8 @@ } | ||
for (const e of module.#StarExportEntries) { | ||
assert(e.ModuleRequest !== null); | ||
if (!(e.ModuleRequest !== null)) | ||
assertFailed(); | ||
const importedModule = Module.#GetImportedModule(module, e.ModuleRequest); | ||
// TODO: https://github.com/tc39/ecma262/pull/2905/files#r973044508 | ||
assert(importedModule); | ||
if (!importedModule) | ||
assertFailed(); | ||
let resolution = importedModule.#ResolveExport(exportName, resolveSet); | ||
@@ -190,3 +200,3 @@ if (resolution === ambiguous) | ||
} | ||
#LoadRequestedModules(HostDefined = undefined) { | ||
#LoadRequestedModules(HostDefined) { | ||
const module = this; | ||
@@ -206,3 +216,4 @@ const pc = PromiseCapability(); | ||
static #InnerModuleLoading(state, module) { | ||
assert(state.Action === 'graph-loading' && state.IsLoading); | ||
if (!state.IsLoading) | ||
assertFailed(); | ||
if (module.#Status === ModuleStatus.new && !state.Visited.includes(module)) { | ||
@@ -213,12 +224,17 @@ state.Visited.push(module); | ||
for (const required of module.#RequestedModules) { | ||
const record = module.#LoadedModules.get(required); | ||
if (record) { | ||
Module.#ContinueModuleLoading(state, NormalCompletion(record)); | ||
if (state.IsLoading) { | ||
const record = module.#LoadedModules.get(required); | ||
if (record) { | ||
Module.#InnerModuleLoading(state, record); | ||
} | ||
else { | ||
Module.#HostLoadImportedModule(module, required, state.HostDefined, state); | ||
} | ||
} | ||
else { | ||
Module.#HostLoadImportedModule(module, required, state.HostDefined, state); | ||
} | ||
} | ||
} | ||
assert(state.PendingModules >= 1); | ||
if (!state.IsLoading) | ||
return; | ||
if (!(state.PendingModules >= 1)) | ||
assertFailed(); | ||
state.PendingModules = state.PendingModules - 1; | ||
@@ -234,11 +250,10 @@ if (state.PendingModules === 0) { | ||
} | ||
static #ContinueModuleLoading(state, result) { | ||
assert(state.Action === 'graph-loading'); | ||
static #ContinueModuleLoading(state, moduleCompletion) { | ||
if (!state.IsLoading) | ||
return; | ||
if (result.Type === 'normal') | ||
Module.#InnerModuleLoading(state, result.Value); | ||
if (moduleCompletion.Type === 'normal') | ||
Module.#InnerModuleLoading(state, moduleCompletion.Value); | ||
else { | ||
state.IsLoading = false; | ||
state.PromiseCapability.Reject(result.Value); | ||
state.PromiseCapability.Reject(moduleCompletion.Value); | ||
} | ||
@@ -267,3 +282,4 @@ } | ||
for (const e of module.#IndirectExportEntries) { | ||
assert(e.ExportName !== null); | ||
if (!(e.ExportName !== null)) | ||
assertFailed(); | ||
const resolution = module.#ResolveExport(e.ExportName); | ||
@@ -283,3 +299,4 @@ if (resolution === null || resolution === ambiguous) { | ||
const importedModule = Module.#GetImportedModule(module, i.ModuleRequest); | ||
assert(importedModule); | ||
if (!importedModule) | ||
assertFailed(); | ||
// import * as ns from '..' | ||
@@ -329,3 +346,4 @@ if (i.ImportName === namespace) { | ||
for (const { ModuleRequest, ExportName, ImportName } of module.#LocalExportEntries) { | ||
assert(ModuleRequest === null && typeof ExportName === 'string' && ImportName === null); | ||
if (!(ModuleRequest === null && typeof ExportName === 'string' && ImportName === null)) | ||
assertFailed(); | ||
propertiesToBeDefined[ExportName] = { | ||
@@ -353,2 +371,3 @@ get: () => this.#LocalExportedValues.get(ExportName), | ||
} | ||
/** All call to ExecuteModule must use Task.run to keep the call stack continue */ | ||
#ExecuteModule(promise) { | ||
@@ -366,2 +385,3 @@ // prepare context | ||
PromiseCapability: PromiseCapability(), | ||
HostDefined: createTask(`import("${specifier}")`), | ||
}; | ||
@@ -372,6 +392,8 @@ Module.#HostLoadImportedModule(this, specifier, status.HostDefined, status); | ||
} | ||
assert(this.#Environment); | ||
if (!this.#Environment) | ||
assertFailed(); | ||
const env = new Proxy(this.#Environment, moduleEnvExoticMethods); | ||
if (!this.#HasTLA) { | ||
assert(!promise); | ||
if (!!promise) | ||
assertFailed(); | ||
if (this.#Execute) { | ||
@@ -382,3 +404,4 @@ Reflect.apply(this.#Execute, this.#Source, [env, this.#ContextObject]); | ||
else { | ||
assert(promise); | ||
if (!promise) | ||
assertFailed(); | ||
if (this.#Execute) { | ||
@@ -393,3 +416,9 @@ Promise.resolve(Reflect.apply(this.#Execute, this.#Source, [env, this.#ContextObject])).then(promise.Resolve, promise.Reject); | ||
const module = this; | ||
assert([ModuleStatus.unlinked, ModuleStatus.linked, ModuleStatus.evaluatingAsync, ModuleStatus.evaluated].includes(module.#Status)); | ||
if (![ | ||
ModuleStatus.unlinked, | ||
ModuleStatus.linked, | ||
ModuleStatus.evaluatingAsync, | ||
ModuleStatus.evaluated, | ||
].includes(module.#Status)) | ||
assertFailed(); | ||
const stack = []; | ||
@@ -401,19 +430,25 @@ try { | ||
for (const mod of stack) { | ||
assert(mod.#Status === ModuleStatus.linking); | ||
if (!(mod.#Status === ModuleStatus.linking)) | ||
assertFailed(); | ||
mod.#Status = ModuleStatus.unlinked; | ||
} | ||
assert(module.#Status === ModuleStatus.unlinked); | ||
if (!(module.#Status === ModuleStatus.unlinked)) | ||
assertFailed(); | ||
throw err; | ||
} | ||
assert([ModuleStatus.linked, ModuleStatus.evaluatingAsync, ModuleStatus.evaluated].includes(module.#Status)); | ||
assert(stack.length === 0); | ||
if (![ModuleStatus.linked, ModuleStatus.evaluatingAsync, ModuleStatus.evaluated].includes(module.#Status)) | ||
assertFailed(); | ||
if (!(stack.length === 0)) | ||
assertFailed(); | ||
} | ||
// https://tc39.es/ecma262/#sec-moduleevaluation | ||
#Evaluate() { | ||
#Evaluate(HostDefined) { | ||
let module = this; | ||
// TODO: Assert: This call to Evaluate is not happening at the same time as another call to Evaluate within the surrounding agent. | ||
assert([ModuleStatus.linked, ModuleStatus.evaluatingAsync, ModuleStatus.evaluated].includes(module.#Status)); | ||
if (![ModuleStatus.linked, ModuleStatus.evaluatingAsync, ModuleStatus.evaluated].includes(module.#Status)) | ||
assertFailed(); | ||
if ([ModuleStatus.evaluatingAsync, ModuleStatus.evaluated].includes(module.#Status)) { | ||
module = module.#CycleRoot; | ||
assert(module); // TODO: https://github.com/tc39/ecma262/issues/2823 | ||
if (!module) | ||
assertFailed(); // TODO: https://github.com/tc39/ecma262/issues/2823 | ||
} | ||
@@ -426,22 +461,29 @@ if (module.#TopLevelCapability) | ||
try { | ||
Module.#InnerModuleEvaluation(module, stack, 0); | ||
Module.#InnerModuleEvaluation(module, stack, 0, HostDefined); | ||
} | ||
catch (err) { | ||
for (const m of stack) { | ||
assert(m.#Status === ModuleStatus.evaluating); | ||
if (!(m.#Status === ModuleStatus.evaluating)) | ||
assertFailed(); | ||
m.#Status = ModuleStatus.evaluated; | ||
m.#EvaluationError = err; | ||
} | ||
assert(module.#Status === ModuleStatus.evaluated); | ||
assert(module.#EvaluationError === err); | ||
if (!(module.#Status === ModuleStatus.evaluated)) | ||
assertFailed(); | ||
if (!(module.#EvaluationError === err)) | ||
assertFailed(); | ||
capability.Reject(err); | ||
return capability.Promise; | ||
} | ||
assert([ModuleStatus.evaluatingAsync, ModuleStatus.evaluated].includes(module.#Status)); | ||
assert(module.#EvaluationError === empty); | ||
if (![ModuleStatus.evaluatingAsync, ModuleStatus.evaluated].includes(module.#Status)) | ||
assertFailed(); | ||
if (!(module.#EvaluationError === empty)) | ||
assertFailed(); | ||
if (module.#AsyncEvaluation === false) { | ||
assert(module.#Status === ModuleStatus.evaluated); | ||
if (!(module.#Status === ModuleStatus.evaluated)) | ||
assertFailed(); | ||
capability.Resolve(); | ||
} | ||
assert(stack.length === 0); | ||
if (!(stack.length === 0)) | ||
assertFailed(); | ||
return capability.Promise; | ||
@@ -454,3 +496,4 @@ } | ||
} | ||
assert(module.#Status === ModuleStatus.unlinked); | ||
if (!(module.#Status === ModuleStatus.unlinked)) | ||
assertFailed(); | ||
module.#Status = ModuleStatus.linking; | ||
@@ -463,5 +506,6 @@ module.#DFSIndex = index; | ||
const requiredModule = this.#GetImportedModule(module, required); | ||
assert(requiredModule); | ||
if (!requiredModule) | ||
assertFailed(); | ||
index = this.#InnerModuleLinking(requiredModule, stack, index); | ||
assert([ | ||
if (![ | ||
ModuleStatus.linking, | ||
@@ -471,8 +515,11 @@ ModuleStatus.linked, | ||
ModuleStatus.evaluated, | ||
].includes(requiredModule.#Status)); | ||
].includes(requiredModule.#Status)) | ||
assertFailed(); | ||
if (stack.includes(requiredModule)) { | ||
assert(requiredModule.#Status === ModuleStatus.linking); | ||
if (!(requiredModule.#Status === ModuleStatus.linking)) | ||
assertFailed(); | ||
} | ||
else { | ||
assert(requiredModule.#Status !== ModuleStatus.linking); | ||
if (!(requiredModule.#Status !== ModuleStatus.linking)) | ||
assertFailed(); | ||
} | ||
@@ -484,4 +531,6 @@ if (requiredModule.#Status === ModuleStatus.linking) { | ||
module.#InitializeEnvironment(); | ||
assert(stack.filter((x) => x === module).length === 1); | ||
assert(module.#DFSAncestorIndex <= module.#DFSIndex); | ||
if (!(stack.filter((x) => x === module).length === 1)) | ||
assertFailed(); | ||
if (!(module.#DFSAncestorIndex <= module.#DFSIndex)) | ||
assertFailed(); | ||
if (module.#DFSAncestorIndex === module.#DFSIndex) { | ||
@@ -499,3 +548,3 @@ let done = false; | ||
// https://tc39.es/ecma262/#sec-InnerModuleEvaluation | ||
static #InnerModuleEvaluation(module, stack, index) { | ||
static #InnerModuleEvaluation(module, stack, index, HostDefined) { | ||
if ([ModuleStatus.evaluatingAsync, ModuleStatus.evaluated].includes(module.#Status)) { | ||
@@ -508,3 +557,4 @@ if (module.#EvaluationError === empty) | ||
return index; | ||
assert(module.#Status === ModuleStatus.linked); | ||
if (!(module.#Status === ModuleStatus.linked)) | ||
assertFailed(); | ||
module.#Status = ModuleStatus.evaluating; | ||
@@ -518,10 +568,14 @@ module.#DFSIndex = index; | ||
let requiredModule = this.#GetImportedModule(module, required); | ||
assert(requiredModule); | ||
index = this.#InnerModuleEvaluation(requiredModule, stack, index); | ||
assert([ModuleStatus.evaluating, ModuleStatus.evaluatingAsync, ModuleStatus.evaluated].includes(requiredModule.#Status)); | ||
if (!requiredModule) | ||
assertFailed(); | ||
index = this.#InnerModuleEvaluation(requiredModule, stack, index, HostDefined); | ||
if (![ModuleStatus.evaluating, ModuleStatus.evaluatingAsync, ModuleStatus.evaluated].includes(requiredModule.#Status)) | ||
assertFailed(); | ||
if (stack.includes(requiredModule)) { | ||
assert(requiredModule.#Status === ModuleStatus.evaluating); | ||
if (!(requiredModule.#Status === ModuleStatus.evaluating)) | ||
assertFailed(); | ||
} | ||
else { | ||
assert(requiredModule.#Status !== ModuleStatus.evaluating); | ||
if (!(requiredModule.#Status !== ModuleStatus.evaluating)) | ||
assertFailed(); | ||
} | ||
@@ -533,3 +587,4 @@ if (requiredModule.#Status === ModuleStatus.evaluating) { | ||
requiredModule = requiredModule.#CycleRoot; | ||
assert([ModuleStatus.evaluatingAsync, ModuleStatus.evaluated].includes(requiredModule.#Status)); | ||
if (![ModuleStatus.evaluatingAsync, ModuleStatus.evaluated].includes(requiredModule.#Status)) | ||
assertFailed(); | ||
if (requiredModule.#EvaluationError !== empty) | ||
@@ -544,4 +599,6 @@ throw requiredModule.#EvaluationError; | ||
if (module.#PendingAsyncDependencies > 0 || module.#HasTLA) { | ||
assert(module.#AsyncEvaluation === false); | ||
assert(module.#__AsyncEvaluationPreviouslyTrue === false); | ||
if (!(module.#AsyncEvaluation === false)) | ||
assertFailed(); | ||
if (!(module.#__AsyncEvaluationPreviouslyTrue === false)) | ||
assertFailed(); | ||
module.#AsyncEvaluation = true; | ||
@@ -551,10 +608,12 @@ module.#__AsyncEvaluationPreviouslyTrue = true; | ||
if (module.#PendingAsyncDependencies === 0) { | ||
this.#ExecuteAsyncModule(module); | ||
this.#ExecuteAsyncModule(module, HostDefined); | ||
} | ||
} | ||
else { | ||
module.#ExecuteModule(); | ||
HostDefined.run(() => module.#ExecuteModule()); | ||
} | ||
assert(stack.filter((x) => x === module).length === 1); | ||
assert(module.#DFSAncestorIndex <= module.#DFSIndex); | ||
if (!(stack.filter((x) => x === module).length === 1)) | ||
assertFailed(); | ||
if (!(module.#DFSAncestorIndex <= module.#DFSIndex)) | ||
assertFailed(); | ||
if (module.#DFSAncestorIndex === module.#DFSIndex) { | ||
@@ -578,12 +637,14 @@ let done = false; | ||
// https://tc39.es/ecma262/#sec-execute-async-module | ||
static #ExecuteAsyncModule(module) { | ||
assert([ModuleStatus.evaluating, ModuleStatus.evaluatingAsync].includes(module.#Status)); | ||
assert(module.#HasTLA); | ||
static #ExecuteAsyncModule(module, HostDefined) { | ||
if (![ModuleStatus.evaluating, ModuleStatus.evaluatingAsync].includes(module.#Status)) | ||
assertFailed(); | ||
if (!module.#HasTLA) | ||
assertFailed(); | ||
const capability = PromiseCapability(); | ||
capability.Promise.then(() => { | ||
this.#AsyncModuleExecutionFulfilled(module); | ||
this.#AsyncModuleExecutionFulfilled(module, HostDefined); | ||
}, (error) => { | ||
this.#AsyncModuleExecutionRejected(module, error); | ||
}); | ||
module.#ExecuteModule(capability); | ||
HostDefined.run(() => module.#ExecuteModule(capability)); | ||
} | ||
@@ -594,6 +655,10 @@ // https://tc39.es/ecma262/#sec-gather-available-ancestors | ||
if (!execList.includes(m) && m.#CycleRoot.#EvaluationError === empty) { | ||
assert(m.#Status === ModuleStatus.evaluatingAsync); | ||
assert(m.#EvaluationError === empty); | ||
assert(m.#AsyncEvaluation === true); | ||
assert(m.#PendingAsyncDependencies > 0); | ||
if (!(m.#Status === ModuleStatus.evaluatingAsync)) | ||
assertFailed(); | ||
if (!(m.#EvaluationError === empty)) | ||
assertFailed(); | ||
if (!(m.#AsyncEvaluation === true)) | ||
assertFailed(); | ||
if (!(m.#PendingAsyncDependencies > 0)) | ||
assertFailed(); | ||
m.#PendingAsyncDependencies--; | ||
@@ -609,14 +674,19 @@ if (m.#PendingAsyncDependencies === 0) { | ||
// https://tc39.es/ecma262/#sec-async-module-execution-fulfilled | ||
static #AsyncModuleExecutionFulfilled(module) { | ||
static #AsyncModuleExecutionFulfilled(module, HostDefined) { | ||
if (module.#Status === ModuleStatus.evaluated) { | ||
assert(module.#EvaluationError !== empty); | ||
if (!(module.#EvaluationError !== empty)) | ||
assertFailed(); | ||
return; | ||
} | ||
assert(module.#Status === ModuleStatus.evaluatingAsync); | ||
assert(module.#AsyncEvaluation === true); | ||
assert(module.#EvaluationError === empty); | ||
if (!(module.#Status === ModuleStatus.evaluatingAsync)) | ||
assertFailed(); | ||
if (!(module.#AsyncEvaluation === true)) | ||
assertFailed(); | ||
if (!(module.#EvaluationError === empty)) | ||
assertFailed(); | ||
module.#AsyncEvaluation = false; | ||
module.#Status = ModuleStatus.evaluated; | ||
if (module.#TopLevelCapability) { | ||
assert(module.#CycleRoot === module); | ||
if (!(module.#CycleRoot === module)) | ||
assertFailed(); | ||
module.#TopLevelCapability.Resolve(); | ||
@@ -628,13 +698,15 @@ } | ||
const sortedExecList = execList; | ||
assert(sortedExecList.every((x) => x.#AsyncEvaluation && x.#PendingAsyncDependencies === 0 && x.#EvaluationError === empty)); | ||
if (!sortedExecList.every((x) => x.#AsyncEvaluation && x.#PendingAsyncDependencies === 0 && x.#EvaluationError === empty)) | ||
assertFailed(); | ||
for (const m of sortedExecList) { | ||
if (m.#Status === ModuleStatus.evaluated) { | ||
assert(m.#EvaluationError !== empty); | ||
if (!(m.#EvaluationError !== empty)) | ||
assertFailed(); | ||
} | ||
else if (m.#HasTLA) { | ||
this.#ExecuteAsyncModule(m); | ||
this.#ExecuteAsyncModule(m, HostDefined); | ||
} | ||
else { | ||
try { | ||
m.#ExecuteModule(); | ||
HostDefined.run(() => m.#ExecuteModule()); | ||
} | ||
@@ -647,3 +719,4 @@ catch (err) { | ||
if (m.#TopLevelCapability) { | ||
assert(m.#CycleRoot === m); | ||
if (!(m.#CycleRoot === m)) | ||
assertFailed(); | ||
m.#TopLevelCapability.Resolve(); | ||
@@ -657,8 +730,12 @@ } | ||
if (module.#Status === ModuleStatus.evaluated) { | ||
assert(module.#EvaluationError !== empty); | ||
if (!(module.#EvaluationError !== empty)) | ||
assertFailed(); | ||
return; | ||
} | ||
assert(module.#Status === ModuleStatus.evaluatingAsync); | ||
assert(module.#AsyncEvaluation === true); | ||
assert(module.#EvaluationError === empty); | ||
if (!(module.#Status === ModuleStatus.evaluatingAsync)) | ||
assertFailed(); | ||
if (!(module.#AsyncEvaluation === true)) | ||
assertFailed(); | ||
if (!(module.#EvaluationError === empty)) | ||
assertFailed(); | ||
module.#EvaluationError = error; | ||
@@ -670,3 +747,4 @@ module.#Status = ModuleStatus.evaluated; | ||
if (module.#TopLevelCapability) { | ||
assert(module.#CycleRoot === module); | ||
if (!(module.#CycleRoot === module)) | ||
assertFailed(); | ||
module.#TopLevelCapability.Reject(error); | ||
@@ -678,3 +756,4 @@ } | ||
return module.#Namespace; | ||
assert(module.#Status !== ModuleStatus.unlinked); | ||
if (!(module.#Status !== ModuleStatus.unlinked)) | ||
assertFailed(); | ||
const exportedNames = module.#GetExportedNames(); | ||
@@ -737,7 +816,7 @@ const namespaceObject = { __proto__: null }; | ||
promiseCapability?.Resolve(module); | ||
Module.#FinishLoadImportedModule(referrer, specifier, payload, NormalCompletion(module)); | ||
Module.#FinishLoadingImportedModule(referrer, specifier, payload, NormalCompletion(module)); | ||
} | ||
function onRejected(reason) { | ||
promiseCapability?.Reject(reason); | ||
Module.#FinishLoadImportedModule(referrer, specifier, payload, ThrowCompletion(reason)); | ||
Module.#FinishLoadingImportedModule(referrer, specifier, payload, ThrowCompletion(reason)); | ||
} | ||
@@ -786,7 +865,8 @@ if (promiseCapability) { | ||
} | ||
static #FinishLoadImportedModule(referrer, specifier, state, result) { | ||
static #FinishLoadingImportedModule(referrer, specifier, state, result) { | ||
if (result.Type === 'normal') { | ||
const record = referrer.#LoadedModules.get(specifier); | ||
if (record) { | ||
assert(record === result.Value); | ||
if (!(record === result.Value)) | ||
assertFailed(); | ||
} | ||
@@ -804,17 +884,17 @@ else { | ||
} | ||
static #ContinueDynamicImport(state, result) { | ||
assert(state.Action === 'dynamic-import'); | ||
static #ContinueDynamicImport(state, moduleCompletion) { | ||
const promiseCapability = state.PromiseCapability; | ||
if (result.Type === 'throw') { | ||
promiseCapability.Reject(result.Value); | ||
if (moduleCompletion.Type === 'throw') { | ||
promiseCapability.Reject(moduleCompletion.Value); | ||
return; | ||
} | ||
const module = result.Value; | ||
const onRejected = (reason) => { | ||
const module = moduleCompletion.Value; | ||
const loadPromise = module.#LoadRequestedModules(state.HostDefined); | ||
function onRejected(reason) { | ||
promiseCapability.Reject(reason); | ||
}; | ||
} | ||
function linkAndEvaluate() { | ||
try { | ||
module.#Link(); | ||
const evaluatePromise = module.#Evaluate(); | ||
const evaluatePromise = module.#Evaluate(state.HostDefined); | ||
function onFulfilled() { | ||
@@ -835,3 +915,2 @@ try { | ||
} | ||
const loadPromise = module.#LoadRequestedModules(); | ||
loadPromise.then(linkAndEvaluate, onRejected); | ||
@@ -844,5 +923,11 @@ } | ||
const promiseCapability = PromiseCapability(); | ||
let HostDefinedName = 'Module<...>'; | ||
if (typeof module.#Referral === 'symbol') | ||
HostDefinedName = `Module<@${module.#Referral.description}>`; | ||
else if (typeof module.#Referral === 'string') | ||
HostDefinedName = `"${module.#Referral}"`; | ||
const state = { | ||
Action: 'dynamic-import', | ||
PromiseCapability: promiseCapability, | ||
HostDefined: createTask(`import(${HostDefinedName})`), | ||
}; | ||
@@ -849,0 +934,0 @@ Module.#ContinueDynamicImport(state, NormalCompletion(module)); |
@@ -13,5 +13,4 @@ function getOpaqueProxy() { | ||
/** @internal */ | ||
export function assert(val) { | ||
if (!val) | ||
throw new TypeError('Internal error.'); | ||
export function assertFailed() { | ||
throw new TypeError('Assertion failed.'); | ||
} | ||
@@ -18,0 +17,0 @@ /** @internal */ |
@@ -1,2 +0,2 @@ | ||
import { assert, unreachable } from './assert.js'; | ||
import { assertFailed, unreachable } from './assert.js'; | ||
import { hasFromField, isExportAllBinding, isExportBinding, isImportAllBinding, isImportBinding } from './shapeCheck.js'; | ||
@@ -162,3 +162,4 @@ import { all, allButDefault, namespace } from './spec.js'; | ||
if (isExportAllBinding(binding)) { | ||
assert(binding.as !== undefined); | ||
if (!(binding.as !== undefined)) | ||
assertFailed(); | ||
indirectExportEntries.push({ | ||
@@ -165,0 +166,0 @@ ExportName: binding.as, |
{ | ||
"name": "@masknet/compartment", | ||
"version": "0.3.11", | ||
"version": "0.3.13", | ||
"type": "module", | ||
@@ -5,0 +5,0 @@ "main": "./dist/index.js", |
@@ -22,4 +22,5 @@ import { ModuleSource } from './ModuleSource.js' | ||
import { normalizeBindingsToSpecRecord, normalizeVirtualModuleRecord } from './utils/normalize.js' | ||
import { assert, internalError, opaqueProxy } from './utils/assert.js' | ||
import { assertFailed, internalError, opaqueProxy } from './utils/assert.js' | ||
import { defaultImportHook } from './Evaluators.js' | ||
import { createTask, type Task } from './utils/async-task.js' | ||
@@ -120,14 +121,14 @@ export let imports: <T extends object = any>(specifier: Module<T>, options?: ImportCallOptions) => Promise<T> | ||
for (const e of module.#LocalExportEntries) { | ||
assert(e.ExportName !== null) | ||
if (!(e.ExportName !== null)) assertFailed() | ||
exportedNames.push(e.ExportName) | ||
} | ||
for (const e of module.#IndirectExportEntries) { | ||
assert(e.ExportName !== null) | ||
if (!(e.ExportName !== null)) assertFailed() | ||
exportedNames.push(e.ExportName) | ||
} | ||
for (const e of module.#StarExportEntries) { | ||
assert(e.ModuleRequest !== null) | ||
if (!(e.ModuleRequest !== null)) assertFailed() | ||
const requestedModule = Module.#GetImportedModule(module, e.ModuleRequest) | ||
// TODO: https://github.com/tc39/ecma262/pull/2905/files#r973044508 | ||
assert(requestedModule) | ||
if (!requestedModule) assertFailed() | ||
const starNames = requestedModule.#GetExportedNames(exportStarSet) | ||
@@ -157,3 +158,3 @@ for (const n of starNames) { | ||
if (exportName === e.ExportName) { | ||
// assert(e.LocalName !== null) | ||
// if (!(e.LocalName !== null)) assertFailed() | ||
// return { module, bindingName: e.LocalName } | ||
@@ -165,6 +166,6 @@ return { module, bindingName: e.ExportName } | ||
if (exportName === e.ExportName) { | ||
assert(e.ModuleRequest !== null) | ||
if (!(e.ModuleRequest !== null)) assertFailed() | ||
const importedModule = Module.#GetImportedModule(module, e.ModuleRequest) | ||
// TODO: https://github.com/tc39/ecma262/pull/2905/files#r973044508 | ||
assert(importedModule) | ||
if (!importedModule) assertFailed() | ||
if (e.ImportName === all) { | ||
@@ -174,3 +175,3 @@ // Assert: module does not provide the direct binding for this export. | ||
} else { | ||
assert(typeof e.ImportName === 'string') | ||
if (!(typeof e.ImportName === 'string')) assertFailed() | ||
return importedModule.#ResolveExport(e.ImportName, resolveSet) | ||
@@ -187,6 +188,6 @@ } | ||
for (const e of module.#StarExportEntries) { | ||
assert(e.ModuleRequest !== null) | ||
if (!(e.ModuleRequest !== null)) assertFailed() | ||
const importedModule = Module.#GetImportedModule(module, e.ModuleRequest) | ||
// TODO: https://github.com/tc39/ecma262/pull/2905/files#r973044508 | ||
assert(importedModule) | ||
if (!importedModule) assertFailed() | ||
let resolution = importedModule.#ResolveExport(exportName, resolveSet) | ||
@@ -216,6 +217,6 @@ if (resolution === ambiguous) return ambiguous | ||
} | ||
#LoadRequestedModules(HostDefined = undefined) { | ||
#LoadRequestedModules(HostDefined: Task) { | ||
const module = this | ||
const pc = PromiseCapability<void>() | ||
const state: ModuleLoadState = { | ||
const state: ModuleLoadState_GraphLoading = { | ||
Action: 'graph-loading', | ||
@@ -231,4 +232,4 @@ IsLoading: true, | ||
} | ||
static #InnerModuleLoading(state: ModuleLoadState, module: Module) { | ||
assert(state.Action === 'graph-loading' && state.IsLoading) | ||
static #InnerModuleLoading(state: ModuleLoadState_GraphLoading, module: Module) { | ||
if (!state.IsLoading) assertFailed() | ||
if (module.#Status === ModuleStatus.new && !state.Visited.includes(module)) { | ||
@@ -239,11 +240,14 @@ state.Visited.push(module) | ||
for (const required of module.#RequestedModules) { | ||
const record = module.#LoadedModules.get(required) | ||
if (record) { | ||
Module.#ContinueModuleLoading(state, NormalCompletion(record)) | ||
} else { | ||
Module.#HostLoadImportedModule(module, required, state.HostDefined, state) | ||
if (state.IsLoading) { | ||
const record = module.#LoadedModules.get(required) | ||
if (record) { | ||
Module.#InnerModuleLoading(state, record) | ||
} else { | ||
Module.#HostLoadImportedModule(module, required, state.HostDefined, state) | ||
} | ||
} | ||
} | ||
} | ||
assert(state.PendingModules >= 1) | ||
if (!state.IsLoading) return | ||
if (!(state.PendingModules >= 1)) assertFailed() | ||
state.PendingModules = state.PendingModules - 1 | ||
@@ -258,9 +262,8 @@ if (state.PendingModules === 0) { | ||
} | ||
static #ContinueModuleLoading(state: ModuleLoadState, result: Completion<Module>) { | ||
assert(state.Action === 'graph-loading') | ||
static #ContinueModuleLoading(state: ModuleLoadState_GraphLoading, moduleCompletion: Completion<Module>) { | ||
if (!state.IsLoading) return | ||
if (result.Type === 'normal') Module.#InnerModuleLoading(state, result.Value) | ||
if (moduleCompletion.Type === 'normal') Module.#InnerModuleLoading(state, moduleCompletion.Value) | ||
else { | ||
state.IsLoading = false | ||
state.PromiseCapability.Reject(result.Value) | ||
state.PromiseCapability.Reject(moduleCompletion.Value) | ||
} | ||
@@ -291,3 +294,3 @@ } | ||
for (const e of module.#IndirectExportEntries) { | ||
assert(e.ExportName !== null) | ||
if (!(e.ExportName !== null)) assertFailed() | ||
const resolution = module.#ResolveExport(e.ExportName) | ||
@@ -310,3 +313,3 @@ if (resolution === null || resolution === ambiguous) { | ||
const importedModule = Module.#GetImportedModule(module, i.ModuleRequest) | ||
assert(importedModule) | ||
if (!importedModule) assertFailed() | ||
// import * as ns from '..' | ||
@@ -355,3 +358,3 @@ if (i.ImportName === namespace) { | ||
for (const { ModuleRequest, ExportName, ImportName } of module.#LocalExportEntries) { | ||
assert(ModuleRequest === null && typeof ExportName === 'string' && ImportName === null) | ||
if (!(ModuleRequest === null && typeof ExportName === 'string' && ImportName === null)) assertFailed() | ||
propertiesToBeDefined[ExportName] = { | ||
@@ -382,2 +385,3 @@ get: () => this.#LocalExportedValues.get(ExportName), | ||
} | ||
/** All call to ExecuteModule must use Task.run to keep the call stack continue */ | ||
#ExecuteModule(promise?: PromiseCapability<void>) { | ||
@@ -392,5 +396,6 @@ // prepare context | ||
specifier = String(specifier) | ||
const status: ModuleLoadState = { | ||
const status: ModuleLoadState_DynamicImport = { | ||
Action: 'dynamic-import', | ||
PromiseCapability: PromiseCapability(), | ||
HostDefined: createTask(`import("${specifier}")`), | ||
} | ||
@@ -402,7 +407,7 @@ Module.#HostLoadImportedModule(this, specifier, status.HostDefined, status) | ||
assert(this.#Environment) | ||
if (!this.#Environment) assertFailed() | ||
const env = new Proxy(this.#Environment, moduleEnvExoticMethods) | ||
if (!this.#HasTLA) { | ||
assert(!promise) | ||
if (!!promise) assertFailed() | ||
if (this.#Execute) { | ||
@@ -412,3 +417,3 @@ Reflect.apply(this.#Execute, this.#Source, [env, this.#ContextObject]) | ||
} else { | ||
assert(promise) | ||
if (!promise) assertFailed() | ||
if (this.#Execute) { | ||
@@ -426,7 +431,11 @@ Promise.resolve(Reflect.apply(this.#Execute, this.#Source, [env, this.#ContextObject])).then( | ||
const module = this | ||
assert( | ||
[ModuleStatus.unlinked, ModuleStatus.linked, ModuleStatus.evaluatingAsync, ModuleStatus.evaluated].includes( | ||
module.#Status, | ||
), | ||
if ( | ||
![ | ||
ModuleStatus.unlinked, | ||
ModuleStatus.linked, | ||
ModuleStatus.evaluatingAsync, | ||
ModuleStatus.evaluated, | ||
].includes(module.#Status) | ||
) | ||
assertFailed() | ||
const stack: Module[] = [] | ||
@@ -437,20 +446,22 @@ try { | ||
for (const mod of stack) { | ||
assert(mod.#Status === ModuleStatus.linking) | ||
if (!(mod.#Status === ModuleStatus.linking)) assertFailed() | ||
mod.#Status = ModuleStatus.unlinked | ||
} | ||
assert(module.#Status === ModuleStatus.unlinked) | ||
if (!(module.#Status === ModuleStatus.unlinked)) assertFailed() | ||
throw err | ||
} | ||
assert([ModuleStatus.linked, ModuleStatus.evaluatingAsync, ModuleStatus.evaluated].includes(module.#Status)) | ||
assert(stack.length === 0) | ||
if (![ModuleStatus.linked, ModuleStatus.evaluatingAsync, ModuleStatus.evaluated].includes(module.#Status)) | ||
assertFailed() | ||
if (!(stack.length === 0)) assertFailed() | ||
} | ||
// https://tc39.es/ecma262/#sec-moduleevaluation | ||
#Evaluate() { | ||
#Evaluate(HostDefined: Task) { | ||
let module: Module = this | ||
// TODO: Assert: This call to Evaluate is not happening at the same time as another call to Evaluate within the surrounding agent. | ||
assert([ModuleStatus.linked, ModuleStatus.evaluatingAsync, ModuleStatus.evaluated].includes(module.#Status)) | ||
if (![ModuleStatus.linked, ModuleStatus.evaluatingAsync, ModuleStatus.evaluated].includes(module.#Status)) | ||
assertFailed() | ||
if ([ModuleStatus.evaluatingAsync, ModuleStatus.evaluated].includes(module.#Status)) { | ||
module = module.#CycleRoot! | ||
assert(module) // TODO: https://github.com/tc39/ecma262/issues/2823 | ||
if (!module) assertFailed() // TODO: https://github.com/tc39/ecma262/issues/2823 | ||
} | ||
@@ -462,21 +473,21 @@ if (module.#TopLevelCapability) return module.#TopLevelCapability.Promise | ||
try { | ||
Module.#InnerModuleEvaluation(module, stack, 0) | ||
Module.#InnerModuleEvaluation(module, stack, 0, HostDefined) | ||
} catch (err) { | ||
for (const m of stack) { | ||
assert(m.#Status === ModuleStatus.evaluating) | ||
if (!(m.#Status === ModuleStatus.evaluating)) assertFailed() | ||
m.#Status = ModuleStatus.evaluated | ||
m.#EvaluationError = err | ||
} | ||
assert(module.#Status === ModuleStatus.evaluated) | ||
assert(module.#EvaluationError === err) | ||
if (!(module.#Status === ModuleStatus.evaluated)) assertFailed() | ||
if (!(module.#EvaluationError === err)) assertFailed() | ||
capability.Reject(err) | ||
return capability.Promise | ||
} | ||
assert([ModuleStatus.evaluatingAsync, ModuleStatus.evaluated].includes(module.#Status)) | ||
assert(module.#EvaluationError === empty) | ||
if (![ModuleStatus.evaluatingAsync, ModuleStatus.evaluated].includes(module.#Status)) assertFailed() | ||
if (!(module.#EvaluationError === empty)) assertFailed() | ||
if (module.#AsyncEvaluation === false) { | ||
assert(module.#Status === ModuleStatus.evaluated) | ||
if (!(module.#Status === ModuleStatus.evaluated)) assertFailed() | ||
capability.Resolve() | ||
} | ||
assert(stack.length === 0) | ||
if (!(stack.length === 0)) assertFailed() | ||
return capability.Promise | ||
@@ -494,3 +505,3 @@ } | ||
} | ||
assert(module.#Status === ModuleStatus.unlinked) | ||
if (!(module.#Status === ModuleStatus.unlinked)) assertFailed() | ||
module.#Status = ModuleStatus.linking | ||
@@ -503,6 +514,6 @@ module.#DFSIndex = index | ||
const requiredModule = this.#GetImportedModule(module, required) | ||
assert(requiredModule) | ||
if (!requiredModule) assertFailed() | ||
index = this.#InnerModuleLinking(requiredModule, stack, index) | ||
assert( | ||
[ | ||
if ( | ||
![ | ||
ModuleStatus.linking, | ||
@@ -512,8 +523,9 @@ ModuleStatus.linked, | ||
ModuleStatus.evaluated, | ||
].includes(requiredModule.#Status), | ||
].includes(requiredModule.#Status) | ||
) | ||
assertFailed() | ||
if (stack.includes(requiredModule)) { | ||
assert(requiredModule.#Status === ModuleStatus.linking) | ||
if (!(requiredModule.#Status === ModuleStatus.linking)) assertFailed() | ||
} else { | ||
assert(requiredModule.#Status !== ModuleStatus.linking) | ||
if (!(requiredModule.#Status !== ModuleStatus.linking)) assertFailed() | ||
} | ||
@@ -528,4 +540,4 @@ if (requiredModule.#Status === ModuleStatus.linking) { | ||
module.#InitializeEnvironment() | ||
assert(stack.filter((x) => x === module).length === 1) | ||
assert(module.#DFSAncestorIndex <= module.#DFSIndex) | ||
if (!(stack.filter((x) => x === module).length === 1)) assertFailed() | ||
if (!(module.#DFSAncestorIndex <= module.#DFSIndex)) assertFailed() | ||
if (module.#DFSAncestorIndex === module.#DFSIndex) { | ||
@@ -543,3 +555,3 @@ let done = false | ||
// https://tc39.es/ecma262/#sec-InnerModuleEvaluation | ||
static #InnerModuleEvaluation(module: Module, stack: Module[], index: number) { | ||
static #InnerModuleEvaluation(module: Module, stack: Module[], index: number, HostDefined: Task) { | ||
if ([ModuleStatus.evaluatingAsync, ModuleStatus.evaluated].includes(module.#Status)) { | ||
@@ -550,3 +562,3 @@ if (module.#EvaluationError === empty) return index | ||
if (module.#Status === ModuleStatus.evaluating) return index | ||
assert(module.#Status === ModuleStatus.linked) | ||
if (!(module.#Status === ModuleStatus.linked)) assertFailed() | ||
module.#Status = ModuleStatus.evaluating | ||
@@ -560,13 +572,14 @@ module.#DFSIndex = index | ||
let requiredModule = this.#GetImportedModule(module, required) | ||
assert(requiredModule) | ||
index = this.#InnerModuleEvaluation(requiredModule, stack, index) | ||
assert( | ||
[ModuleStatus.evaluating, ModuleStatus.evaluatingAsync, ModuleStatus.evaluated].includes( | ||
if (!requiredModule) assertFailed() | ||
index = this.#InnerModuleEvaluation(requiredModule, stack, index, HostDefined) | ||
if ( | ||
![ModuleStatus.evaluating, ModuleStatus.evaluatingAsync, ModuleStatus.evaluated].includes( | ||
requiredModule.#Status, | ||
), | ||
) | ||
) | ||
assertFailed() | ||
if (stack.includes(requiredModule)) { | ||
assert(requiredModule.#Status === ModuleStatus.evaluating) | ||
if (!(requiredModule.#Status === ModuleStatus.evaluating)) assertFailed() | ||
} else { | ||
assert(requiredModule.#Status !== ModuleStatus.evaluating) | ||
if (!(requiredModule.#Status !== ModuleStatus.evaluating)) assertFailed() | ||
} | ||
@@ -580,3 +593,4 @@ if (requiredModule.#Status === ModuleStatus.evaluating) { | ||
requiredModule = requiredModule.#CycleRoot! | ||
assert([ModuleStatus.evaluatingAsync, ModuleStatus.evaluated].includes(requiredModule.#Status)) | ||
if (![ModuleStatus.evaluatingAsync, ModuleStatus.evaluated].includes(requiredModule.#Status)) | ||
assertFailed() | ||
if (requiredModule.#EvaluationError !== empty) throw requiredModule.#EvaluationError | ||
@@ -590,4 +604,4 @@ } | ||
if (module.#PendingAsyncDependencies > 0 || module.#HasTLA) { | ||
assert(module.#AsyncEvaluation === false) | ||
assert(module.#__AsyncEvaluationPreviouslyTrue === false) | ||
if (!(module.#AsyncEvaluation === false)) assertFailed() | ||
if (!(module.#__AsyncEvaluationPreviouslyTrue === false)) assertFailed() | ||
module.#AsyncEvaluation = true | ||
@@ -597,9 +611,9 @@ module.#__AsyncEvaluationPreviouslyTrue = true | ||
if (module.#PendingAsyncDependencies === 0) { | ||
this.#ExecuteAsyncModule(module) | ||
this.#ExecuteAsyncModule(module, HostDefined) | ||
} | ||
} else { | ||
module.#ExecuteModule() | ||
HostDefined.run(() => module.#ExecuteModule()) | ||
} | ||
assert(stack.filter((x) => x === module).length === 1) | ||
assert(module.#DFSAncestorIndex <= module.#DFSIndex) | ||
if (!(stack.filter((x) => x === module).length === 1)) assertFailed() | ||
if (!(module.#DFSAncestorIndex <= module.#DFSIndex)) assertFailed() | ||
if (module.#DFSAncestorIndex === module.#DFSIndex) { | ||
@@ -622,9 +636,9 @@ let done = false | ||
// https://tc39.es/ecma262/#sec-execute-async-module | ||
static #ExecuteAsyncModule(module: Module) { | ||
assert([ModuleStatus.evaluating, ModuleStatus.evaluatingAsync].includes(module.#Status)) | ||
assert(module.#HasTLA) | ||
static #ExecuteAsyncModule(module: Module, HostDefined: Task) { | ||
if (![ModuleStatus.evaluating, ModuleStatus.evaluatingAsync].includes(module.#Status)) assertFailed() | ||
if (!module.#HasTLA) assertFailed() | ||
const capability = PromiseCapability<void>() | ||
capability.Promise.then( | ||
() => { | ||
this.#AsyncModuleExecutionFulfilled(module) | ||
this.#AsyncModuleExecutionFulfilled(module, HostDefined) | ||
}, | ||
@@ -635,3 +649,3 @@ (error) => { | ||
) | ||
module.#ExecuteModule(capability) | ||
HostDefined.run(() => module.#ExecuteModule(capability)) | ||
} | ||
@@ -643,6 +657,6 @@ | ||
if (!execList.includes(m) && m.#CycleRoot!.#EvaluationError === empty) { | ||
assert(m.#Status === ModuleStatus.evaluatingAsync) | ||
assert(m.#EvaluationError === empty) | ||
assert(m.#AsyncEvaluation === true) | ||
assert((m.#PendingAsyncDependencies as number) > 0) | ||
if (!(m.#Status === ModuleStatus.evaluatingAsync)) assertFailed() | ||
if (!(m.#EvaluationError === empty)) assertFailed() | ||
if (!(m.#AsyncEvaluation === true)) assertFailed() | ||
if (!((m.#PendingAsyncDependencies as number) > 0)) assertFailed() | ||
;(m.#PendingAsyncDependencies as number)-- | ||
@@ -658,14 +672,14 @@ if (m.#PendingAsyncDependencies === 0) { | ||
// https://tc39.es/ecma262/#sec-async-module-execution-fulfilled | ||
static #AsyncModuleExecutionFulfilled(module: Module) { | ||
static #AsyncModuleExecutionFulfilled(module: Module, HostDefined: Task) { | ||
if (module.#Status === ModuleStatus.evaluated) { | ||
assert(module.#EvaluationError !== empty) | ||
if (!(module.#EvaluationError !== empty)) assertFailed() | ||
return | ||
} | ||
assert(module.#Status === ModuleStatus.evaluatingAsync) | ||
assert(module.#AsyncEvaluation === true) | ||
assert(module.#EvaluationError === empty) | ||
if (!(module.#Status === ModuleStatus.evaluatingAsync)) assertFailed() | ||
if (!(module.#AsyncEvaluation === true)) assertFailed() | ||
if (!(module.#EvaluationError === empty)) assertFailed() | ||
module.#AsyncEvaluation = false | ||
module.#Status = ModuleStatus.evaluated | ||
if (module.#TopLevelCapability) { | ||
assert(module.#CycleRoot === module) | ||
if (!(module.#CycleRoot === module)) assertFailed() | ||
module.#TopLevelCapability.Resolve() | ||
@@ -677,15 +691,16 @@ } | ||
const sortedExecList = execList | ||
assert( | ||
sortedExecList.every( | ||
if ( | ||
!sortedExecList.every( | ||
(x) => x.#AsyncEvaluation && x.#PendingAsyncDependencies === 0 && x.#EvaluationError === empty, | ||
), | ||
) | ||
) | ||
assertFailed() | ||
for (const m of sortedExecList) { | ||
if (m.#Status === ModuleStatus.evaluated) { | ||
assert(m.#EvaluationError !== empty) | ||
if (!(m.#EvaluationError !== empty)) assertFailed() | ||
} else if (m.#HasTLA) { | ||
this.#ExecuteAsyncModule(m) | ||
this.#ExecuteAsyncModule(m, HostDefined) | ||
} else { | ||
try { | ||
m.#ExecuteModule() | ||
HostDefined.run(() => m.#ExecuteModule()) | ||
} catch (err) { | ||
@@ -697,3 +712,3 @@ this.#AsyncModuleExecutionRejected(m, err) | ||
if (m.#TopLevelCapability) { | ||
assert(m.#CycleRoot === m) | ||
if (!(m.#CycleRoot === m)) assertFailed() | ||
m.#TopLevelCapability.Resolve() | ||
@@ -708,8 +723,8 @@ } | ||
if (module.#Status === ModuleStatus.evaluated) { | ||
assert(module.#EvaluationError !== empty) | ||
if (!(module.#EvaluationError !== empty)) assertFailed() | ||
return | ||
} | ||
assert(module.#Status === ModuleStatus.evaluatingAsync) | ||
assert(module.#AsyncEvaluation === true) | ||
assert(module.#EvaluationError === empty) | ||
if (!(module.#Status === ModuleStatus.evaluatingAsync)) assertFailed() | ||
if (!(module.#AsyncEvaluation === true)) assertFailed() | ||
if (!(module.#EvaluationError === empty)) assertFailed() | ||
module.#EvaluationError = error | ||
@@ -721,3 +736,3 @@ module.#Status = ModuleStatus.evaluated | ||
if (module.#TopLevelCapability) { | ||
assert(module.#CycleRoot === module) | ||
if (!(module.#CycleRoot === module)) assertFailed() | ||
module.#TopLevelCapability.Reject(error) | ||
@@ -728,3 +743,3 @@ } | ||
if (module.#Namespace) return module.#Namespace | ||
assert(module.#Status !== ModuleStatus.unlinked) | ||
if (!(module.#Status !== ModuleStatus.unlinked)) assertFailed() | ||
const exportedNames = module.#GetExportedNames() | ||
@@ -785,16 +800,11 @@ | ||
} | ||
static #HostLoadImportedModule( | ||
referrer: Module, | ||
specifier: string, | ||
hostDefined: undefined, | ||
payload: ModuleLoadState, | ||
) { | ||
static #HostLoadImportedModule(referrer: Module, specifier: string, hostDefined: Task, payload: ModuleLoadState) { | ||
let promiseCapability = referrer.#ImportHookCache.get(specifier) | ||
function onFulfilled(module: Module) { | ||
promiseCapability?.Resolve(module) | ||
Module.#FinishLoadImportedModule(referrer, specifier, payload, NormalCompletion(module)) | ||
Module.#FinishLoadingImportedModule(referrer, specifier, payload, NormalCompletion(module)) | ||
} | ||
function onRejected(reason: unknown) { | ||
promiseCapability?.Reject(reason) | ||
Module.#FinishLoadImportedModule(referrer, specifier, payload, ThrowCompletion(reason)) | ||
Module.#FinishLoadingImportedModule(referrer, specifier, payload, ThrowCompletion(reason)) | ||
} | ||
@@ -839,3 +849,3 @@ if (promiseCapability) { | ||
static #FinishLoadImportedModule( | ||
static #FinishLoadingImportedModule( | ||
referrer: Module, | ||
@@ -849,3 +859,3 @@ specifier: string, | ||
if (record) { | ||
assert(record === result.Value) | ||
if (!(record === result.Value)) assertFailed() | ||
} else { | ||
@@ -862,11 +872,11 @@ referrer.#LoadedModules.set(specifier, result.Value) | ||
static #ContinueDynamicImport(state: ModuleLoadState, result: Completion<Module>) { | ||
assert(state.Action === 'dynamic-import') | ||
static #ContinueDynamicImport(state: ModuleLoadState_DynamicImport, moduleCompletion: Completion<Module>) { | ||
const promiseCapability = state.PromiseCapability | ||
if (result.Type === 'throw') { | ||
promiseCapability.Reject(result.Value) | ||
if (moduleCompletion.Type === 'throw') { | ||
promiseCapability.Reject(moduleCompletion.Value) | ||
return | ||
} | ||
const module = result.Value | ||
const onRejected = (reason: unknown) => { | ||
const module = moduleCompletion.Value | ||
const loadPromise = module.#LoadRequestedModules(state.HostDefined) | ||
function onRejected(reason: unknown) { | ||
promiseCapability.Reject(reason) | ||
@@ -877,3 +887,3 @@ } | ||
module.#Link() | ||
const evaluatePromise = module.#Evaluate() | ||
const evaluatePromise = module.#Evaluate(state.HostDefined) | ||
function onFulfilled() { | ||
@@ -892,3 +902,2 @@ try { | ||
} | ||
const loadPromise = module.#LoadRequestedModules() | ||
loadPromise.then(linkAndEvaluate, onRejected) | ||
@@ -901,5 +910,11 @@ } | ||
const promiseCapability = PromiseCapability<ModuleNamespace>() | ||
const state: ModuleLoadState = { | ||
let HostDefinedName = 'Module<...>' | ||
if (typeof module.#Referral === 'symbol') HostDefinedName = `Module<@${module.#Referral.description}>` | ||
else if (typeof module.#Referral === 'string') HostDefinedName = `"${module.#Referral}"` | ||
const state: ModuleLoadState_DynamicImport = { | ||
Action: 'dynamic-import', | ||
PromiseCapability: promiseCapability, | ||
HostDefined: createTask(`import(${HostDefinedName})`), | ||
} | ||
@@ -923,3 +938,3 @@ Module.#ContinueDynamicImport(state, NormalCompletion(module)) | ||
Visited: Module[] | ||
HostDefined?: undefined | ||
HostDefined: Task | ||
} | ||
@@ -929,3 +944,3 @@ interface ModuleLoadState_DynamicImport { | ||
PromiseCapability: PromiseCapability<ModuleNamespace> | ||
HostDefined?: undefined | ||
HostDefined: Task | ||
} | ||
@@ -932,0 +947,0 @@ type ModuleLoadState = ModuleLoadState_DynamicImport | ModuleLoadState_GraphLoading |
@@ -14,4 +14,4 @@ function getOpaqueProxy() { | ||
/** @internal */ | ||
export function assert(val: any): asserts val { | ||
if (!val) throw new TypeError('Internal error.') | ||
export function assertFailed(): never { | ||
throw new TypeError('Assertion failed.') | ||
} | ||
@@ -18,0 +18,0 @@ /** @internal */ |
import type { VirtualModuleRecord, Binding, ExportAllBinding, ImportBinding } from '../types.js' | ||
import { assert, unreachable } from './assert.js' | ||
import { assertFailed, unreachable } from './assert.js' | ||
import { hasFromField, isExportAllBinding, isExportBinding, isImportAllBinding, isImportBinding } from './shapeCheck.js' | ||
@@ -154,3 +154,3 @@ import { all, allButDefault, namespace, type ModuleExportEntry, type ModuleImportEntry } from './spec.js' | ||
if (isExportAllBinding(binding)) { | ||
assert(binding.as !== undefined) | ||
if (!(binding.as !== undefined)) assertFailed() | ||
indirectExportEntries.push({ | ||
@@ -157,0 +157,0 @@ ExportName: binding.as, |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
222962
58
4260