Bug 1287410 - Check state of module returned by HostResolveImportedModule r=shu

This commit is contained in:
Jon Coppeard 2016-08-02 10:38:02 +01:00
parent c9bd13abb0
commit 3f47f7f4b8
4 changed files with 49 additions and 7 deletions

View File

@ -2,6 +2,15 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
function CallModuleResolveHook(module, specifier, expectedMinimumState)
{
let requestedModule = HostResolveImportedModule(module, specifier);
if (requestedModule.state < expectedMinimumState)
ThrowInternalError(JSMSG_BAD_MODULE_STATE);
return requestedModule;
}
// 15.2.1.16.2 GetExportedNames(exportStarSet)
function ModuleGetExportedNames(exportStarSet = [])
{
@ -42,7 +51,8 @@ function ModuleGetExportedNames(exportStarSet = [])
let starExportEntries = module.starExportEntries;
for (let i = 0; i < starExportEntries.length; i++) {
let e = starExportEntries[i];
let requestedModule = HostResolveImportedModule(module, e.moduleRequest);
let requestedModule = CallModuleResolveHook(module, e.moduleRequest,
MODULE_STATE_INSTANTIATED);
let starNames = callFunction(requestedModule.getExportedNames, requestedModule,
exportStarSet);
for (let j = 0; j < starNames.length; j++) {
@ -89,7 +99,8 @@ function ModuleResolveExport(exportName, resolveSet = [], exportStarSet = [])
for (let i = 0; i < indirectExportEntries.length; i++) {
let e = indirectExportEntries[i];
if (exportName === e.exportName) {
let importedModule = HostResolveImportedModule(module, e.moduleRequest);
let importedModule = CallModuleResolveHook(module, e.moduleRequest,
MODULE_STATE_INSTANTIATED);
let indirectResolution = callFunction(importedModule.resolveExport, importedModule,
e.importName, resolveSet, exportStarSet);
if (indirectResolution !== null)
@ -117,7 +128,8 @@ function ModuleResolveExport(exportName, resolveSet = [], exportStarSet = [])
let starExportEntries = module.starExportEntries;
for (let i = 0; i < starExportEntries.length; i++) {
let e = starExportEntries[i];
let importedModule = HostResolveImportedModule(module, e.moduleRequest);
let importedModule = CallModuleResolveHook(module, e.moduleRequest,
MODULE_STATE_INSTANTIATED);
let resolution = callFunction(importedModule.resolveExport, importedModule,
exportName, resolveSet, exportStarSet);
if (resolution === "ambiguous")
@ -225,12 +237,14 @@ function ModuleDeclarationInstantiation()
CreateModuleEnvironment(module);
let env = GetModuleEnvironment(module);
SetModuleState(this, MODULE_STATE_INSTANTIATED);
try {
// Step 8
let requestedModules = module.requestedModules;
for (let i = 0; i < requestedModules.length; i++) {
let required = requestedModules[i];
let requiredModule = HostResolveImportedModule(module, required);
let requiredModule = CallModuleResolveHook(module, required, MODULE_STATE_PARSED);
callFunction(requiredModule.declarationInstantiation, requiredModule);
}
@ -249,7 +263,8 @@ function ModuleDeclarationInstantiation()
let importEntries = module.importEntries;
for (let i = 0; i < importEntries.length; i++) {
let imp = importEntries[i];
let importedModule = HostResolveImportedModule(module, imp.moduleRequest);
let importedModule = CallModuleResolveHook(module, imp.moduleRequest,
MODULE_STATE_INSTANTIATED);
if (imp.importName === "*") {
let namespace = GetModuleNamespace(importedModule);
CreateNamespaceBinding(env, imp.localName, namespace);
@ -282,6 +297,9 @@ function ModuleEvaluation()
// Step 1
let module = this;
if (module.state < MODULE_STATE_INSTANTIATED)
ThrowInternalError(JSMSG_BAD_MODULE_STATE);
// Step 4
if (module.state == MODULE_STATE_EVALUATED)
return undefined;
@ -293,7 +311,7 @@ function ModuleEvaluation()
let requestedModules = module.requestedModules;
for (let i = 0; i < requestedModules.length; i++) {
let required = requestedModules[i];
let requiredModule = HostResolveImportedModule(module, required);
let requiredModule = CallModuleResolveHook(module, required, MODULE_STATE_INSTANTIATED);
callFunction(requiredModule.evaluation, requiredModule);
}

View File

@ -696,7 +696,7 @@ void
ModuleObject::init(HandleScript script)
{
initReservedSlot(ScriptSlot, PrivateValue(script));
initReservedSlot(StateSlot, Int32Value(MODULE_STATE_PARSED));
initReservedSlot(StateSlot, Int32Value(MODULE_STATE_FAILED));
}
void
@ -717,6 +717,7 @@ ModuleObject::initImportExportData(HandleArrayObject requestedModules,
initReservedSlot(LocalExportEntriesSlot, ObjectValue(*localExportEntries));
initReservedSlot(IndirectExportEntriesSlot, ObjectValue(*indirectExportEntries));
initReservedSlot(StarExportEntriesSlot, ObjectValue(*starExportEntries));
setReservedSlot(StateSlot, Int32Value(MODULE_STATE_PARSED));
}
static bool

View File

@ -0,0 +1,22 @@
// |jit-test| error: InternalError
let moduleRepo = {};
setModuleResolveHook(function(module, specifier) {
if (specifier in moduleRepo)
return moduleRepo[specifier];
throw "Module '" + specifier + "' not found";
});
let a = moduleRepo['a'] = parseModule("export var a = 1; export var b = 2;");
let b = moduleRepo['b'] = parseModule("export var b = 3; export var c = 4;");
let c = moduleRepo['c'] = parseModule("export * from 'a'; export * from 'b';");
c.declarationInstantiation();
// Module 'a' is replaced with another module that has not been instantiated.
// This should not happen and would be a bug in the module loader.
a = moduleRepo['a'] = parseModule("export var a = 1; export var b = 2;");
let d = moduleRepo['d'] = parseModule("import { a } from 'c'; a;");
// Attempting to instantiate 'd' throws an error because depdency 'a' of
// instantiated module 'c' is not instantiated.
d.declarationInstantiation();

View File

@ -539,6 +539,7 @@ MSG_DEF(JSMSG_AMBIGUOUS_IMPORT, 1, JSEXN_SYNTAXERR, "ambiguous import '
MSG_DEF(JSMSG_MISSING_NAMESPACE_EXPORT, 0, JSEXN_SYNTAXERR, "export not found for namespace")
MSG_DEF(JSMSG_MISSING_EXPORT, 1, JSEXN_SYNTAXERR, "local binding for export '{0}' not found")
MSG_DEF(JSMSG_MODULE_INSTANTIATE_FAILED, 0, JSEXN_INTERNALERR, "attempt to re-instantiate module after failure")
MSG_DEF(JSMSG_BAD_MODULE_STATE, 0, JSEXN_INTERNALERR, "module record in unexpected state")
// Promise
MSG_DEF(JSMSG_CANNOT_RESOLVE_PROMISE_WITH_ITSELF, 0, JSEXN_TYPEERR, "A promise cannot be resolved with itself.")