From 67f5e5d20c99c909b2272ad55a363a17bc489a4c Mon Sep 17 00:00:00 2001 From: janekptacijarabaci Date: Sat, 14 Apr 2018 09:02:03 +0200 Subject: [PATCH] Bug 1341298 - Relax expected module state when resolving modules and circular module dependencies are present --- js/src/builtin/Module.js | 10 ++++++---- .../modules/export-circular-nonexisting-binding-1.js | 4 ++++ .../modules/export-circular-nonexisting-binding-2.js | 1 + .../modules/export-circular-nonexisting-binding.js | 3 +++ js/src/vm/EnvironmentObject.cpp | 2 +- 5 files changed, 15 insertions(+), 5 deletions(-) create mode 100644 js/src/jit-test/modules/export-circular-nonexisting-binding-1.js create mode 100644 js/src/jit-test/modules/export-circular-nonexisting-binding-2.js create mode 100644 js/src/jit-test/tests/modules/export-circular-nonexisting-binding.js diff --git a/js/src/builtin/Module.js b/js/src/builtin/Module.js index 95f97495db..5c3d5e1479 100644 --- a/js/src/builtin/Module.js +++ b/js/src/builtin/Module.js @@ -100,7 +100,7 @@ function ModuleResolveExport(exportName, resolveSet = []) let e = indirectExportEntries[i]; if (exportName === e.exportName) { let importedModule = CallModuleResolveHook(module, e.moduleRequest, - MODULE_STATE_INSTANTIATED); + MODULE_STATE_PARSED); return callFunction(importedModule.resolveExport, importedModule, e.importName, resolveSet); } @@ -120,7 +120,7 @@ function ModuleResolveExport(exportName, resolveSet = []) for (let i = 0; i < starExportEntries.length; i++) { let e = starExportEntries[i]; let importedModule = CallModuleResolveHook(module, e.moduleRequest, - MODULE_STATE_INSTANTIATED); + MODULE_STATE_PARSED); let resolution = callFunction(importedModule.resolveExport, importedModule, exportName, resolveSet); if (resolution === "ambiguous") @@ -205,8 +205,8 @@ function GetModuleEnvironment(module) function RecordInstantationFailure(module) { - // Set the module's environment slot to 'null' to indicate a failed module - // instantiation. + // Set the module's state to 'failed' to indicate a failed module + // instantiation and reset the environment slot to 'undefined'. assert(IsModule(module), "Non-module passed to RecordInstantationFailure"); SetModuleState(module, MODULE_STATE_FAILED); UnsafeSetReservedSlot(module, MODULE_OBJECT_ENVIRONMENT_SLOT, undefined); @@ -267,6 +267,8 @@ function ModuleDeclarationInstantiation() ThrowSyntaxError(JSMSG_MISSING_IMPORT, imp.importName); if (resolution === "ambiguous") ThrowSyntaxError(JSMSG_AMBIGUOUS_IMPORT, imp.importName); + if (resolution.module.state < MODULE_STATE_INSTANTIATED) + ThrowInternalError(JSMSG_BAD_MODULE_STATE); CreateImportBinding(env, imp.localName, resolution.module, resolution.bindingName); } } diff --git a/js/src/jit-test/modules/export-circular-nonexisting-binding-1.js b/js/src/jit-test/modules/export-circular-nonexisting-binding-1.js new file mode 100644 index 0000000000..2b91b6a284 --- /dev/null +++ b/js/src/jit-test/modules/export-circular-nonexisting-binding-1.js @@ -0,0 +1,4 @@ +import "export-circular-nonexisting-binding-2.js"; + +export* from "empty.js"; +export {x} from "empty.js"; diff --git a/js/src/jit-test/modules/export-circular-nonexisting-binding-2.js b/js/src/jit-test/modules/export-circular-nonexisting-binding-2.js new file mode 100644 index 0000000000..ba7dcc1b48 --- /dev/null +++ b/js/src/jit-test/modules/export-circular-nonexisting-binding-2.js @@ -0,0 +1 @@ +export {x} from "export-circular-nonexisting-binding-1.js"; diff --git a/js/src/jit-test/tests/modules/export-circular-nonexisting-binding.js b/js/src/jit-test/tests/modules/export-circular-nonexisting-binding.js new file mode 100644 index 0000000000..387c7c369a --- /dev/null +++ b/js/src/jit-test/tests/modules/export-circular-nonexisting-binding.js @@ -0,0 +1,3 @@ +// |jit-test| module; error:SyntaxError + +import "export-circular-nonexisting-binding-1.js"; diff --git a/js/src/vm/EnvironmentObject.cpp b/js/src/vm/EnvironmentObject.cpp index 3680c5b7b4..c95bb0597a 100644 --- a/js/src/vm/EnvironmentObject.cpp +++ b/js/src/vm/EnvironmentObject.cpp @@ -490,7 +490,7 @@ ModuleEnvironmentObject::createImportBinding(JSContext* cx, HandleAtom importNam { RootedId importNameId(cx, AtomToId(importName)); RootedId localNameId(cx, AtomToId(localName)); - RootedModuleEnvironmentObject env(cx, module->environment()); + RootedModuleEnvironmentObject env(cx, &module->initialEnvironment()); if (!importBindings().putNew(cx, importNameId, env, localNameId)) { ReportOutOfMemory(cx); return false;