diff options
author | Moonchild <mcwerewolf@gmail.com> | 2018-07-07 11:55:43 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-07-07 11:55:43 +0200 |
commit | 1af00389dfb9ea52a1a0ee94a5c4618a647bb6ec (patch) | |
tree | 2eb4027eba5468c0dd0b8cb8bba85182c675a04b | |
parent | e9f79994278968cc86698a7d90e05ca01201c441 (diff) | |
parent | 941e54654eabed0a3568f7fefe424a45aa02eddb (diff) | |
download | UXP-1af00389dfb9ea52a1a0ee94a5c4618a647bb6ec.tar UXP-1af00389dfb9ea52a1a0ee94a5c4618a647bb6ec.tar.gz UXP-1af00389dfb9ea52a1a0ee94a5c4618a647bb6ec.tar.lz UXP-1af00389dfb9ea52a1a0ee94a5c4618a647bb6ec.tar.xz UXP-1af00389dfb9ea52a1a0ee94a5c4618a647bb6ec.zip |
Merge pull request #608 from janekptacijarabaci/_testBranch_js_modules_basic
Merge branch js modules basic
25 files changed, 158 insertions, 251 deletions
diff --git a/dom/base/nsScriptLoader.cpp b/dom/base/nsScriptLoader.cpp index a6d20e363..433f6afa5 100644 --- a/dom/base/nsScriptLoader.cpp +++ b/dom/base/nsScriptLoader.cpp @@ -647,6 +647,19 @@ nsScriptLoader::CheckContentPolicy(nsIDocument* aDocument, } bool +nsScriptLoader::ModuleScriptsEnabled() +{ + static bool sEnabledForContent = false; + static bool sCachedPref = false; + if (!sCachedPref) { + sCachedPref = true; + Preferences::AddBoolVarCache(&sEnabledForContent, "dom.moduleScripts.enabled", false); + } + + return nsContentUtils::IsChromeDoc(mDocument) || sEnabledForContent; +} + +bool nsScriptLoader::ModuleMapContainsModule(nsModuleLoadRequest *aRequest) const { // Returns whether we have fetched, or are currently fetching, a module script @@ -1223,15 +1236,27 @@ nsScriptLoader::StartLoad(nsScriptLoadRequest *aRequest, const nsAString &aType, nsCOMPtr<nsIInterfaceRequestor> prompter(do_QueryInterface(docshell)); nsSecurityFlags securityFlags; - // TODO: the spec currently gives module scripts different CORS behaviour to - // classic scripts. - securityFlags = aRequest->mCORSMode == CORS_NONE - ? nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL - : nsILoadInfo::SEC_REQUIRE_CORS_DATA_INHERITS; - if (aRequest->mCORSMode == CORS_ANONYMOUS) { - securityFlags |= nsILoadInfo::SEC_COOKIES_SAME_ORIGIN; - } else if (aRequest->mCORSMode == CORS_USE_CREDENTIALS) { - securityFlags |= nsILoadInfo::SEC_COOKIES_INCLUDE; + if (aRequest->IsModuleRequest()) { + // According to the spec, module scripts have different behaviour to classic + // scripts and always use CORS. + securityFlags = nsILoadInfo::SEC_REQUIRE_CORS_DATA_INHERITS; + if (aRequest->mCORSMode == CORS_NONE) { + securityFlags |= nsILoadInfo::SEC_COOKIES_OMIT; + } else if (aRequest->mCORSMode == CORS_ANONYMOUS) { + securityFlags |= nsILoadInfo::SEC_COOKIES_SAME_ORIGIN; + } else { + MOZ_ASSERT(aRequest->mCORSMode == CORS_USE_CREDENTIALS); + securityFlags |= nsILoadInfo::SEC_COOKIES_INCLUDE; + } + } else { + securityFlags = aRequest->mCORSMode == CORS_NONE + ? nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL + : nsILoadInfo::SEC_REQUIRE_CORS_DATA_INHERITS; + if (aRequest->mCORSMode == CORS_ANONYMOUS) { + securityFlags |= nsILoadInfo::SEC_COOKIES_SAME_ORIGIN; + } else if (aRequest->mCORSMode == CORS_USE_CREDENTIALS) { + securityFlags |= nsILoadInfo::SEC_COOKIES_INCLUDE; + } } securityFlags |= nsILoadInfo::SEC_ALLOW_CHROME; @@ -1441,8 +1466,7 @@ nsScriptLoader::ProcessScriptElement(nsIScriptElement *aElement) nsScriptKind scriptKind = nsScriptKind::Classic; if (!type.IsEmpty()) { - // Support type="module" only for chrome documents. - if (nsContentUtils::IsChromeDoc(mDocument) && type.LowerCaseEqualsASCII("module")) { + if (ModuleScriptsEnabled() && type.LowerCaseEqualsASCII("module")) { scriptKind = nsScriptKind::Module; } else { NS_ENSURE_TRUE(ParseTypeAttribute(type, &version), false); @@ -2761,7 +2785,7 @@ nsScriptLoader::PreloadURI(nsIURI *aURI, const nsAString &aCharset, } // TODO: Preload module scripts. - if (nsContentUtils::IsChromeDoc(mDocument) && aType.LowerCaseEqualsASCII("module")) { + if (ModuleScriptsEnabled() && aType.LowerCaseEqualsASCII("module")) { return; } diff --git a/dom/base/nsScriptLoader.h b/dom/base/nsScriptLoader.h index d30a58441..a00239be5 100644 --- a/dom/base/nsScriptLoader.h +++ b/dom/base/nsScriptLoader.h @@ -568,6 +568,8 @@ private: JS::SourceBufferHolder GetScriptSource(nsScriptLoadRequest* aRequest, nsAutoString& inlineData); + bool ModuleScriptsEnabled(); + void SetModuleFetchStarted(nsModuleLoadRequest *aRequest); void SetModuleFetchFinishedAndResumeWaitingRequests(nsModuleLoadRequest *aRequest, nsresult aResult); diff --git a/js/src/builtin/Iterator.js b/js/src/builtin/Iterator.js index 735eec7a0..e25b76156 100644 --- a/js/src/builtin/Iterator.js +++ b/js/src/builtin/Iterator.js @@ -84,44 +84,3 @@ function LegacyIteratorShim() { function LegacyGeneratorIteratorShim() { return NewLegacyIterator(ToObject(this), LegacyGeneratorIterator); } - -// 7.4.8 CreateListIterator() -function CreateListIterator(array) { - let iterator = NewListIterator(); - UnsafeSetReservedSlot(iterator, ITERATOR_SLOT_TARGET, array); - UnsafeSetReservedSlot(iterator, ITERATOR_SLOT_NEXT_INDEX, 0); - - // 7.4.8.1 ListIterator next() - // The spec requires that we use a new next function per iterator object. - let next = function() { - if (!IsObject(this) || !IsListIterator(this)) - return callFunction(CallListIteratorMethodIfWrapped, this, "ListIteratorNext"); - - if (ActiveFunction() !== UnsafeGetReservedSlot(this, ITERATOR_SLOT_NEXT_METHOD)) - ThrowTypeError(JSMSG_INCOMPATIBLE_METHOD, "next", "method", ToString(this)); - - let array = UnsafeGetObjectFromReservedSlot(this, ITERATOR_SLOT_TARGET); - let index = UnsafeGetReservedSlot(this, ITERATOR_SLOT_NEXT_INDEX); - - if (index >= ToLength(array.length)) { - UnsafeSetReservedSlot(this, ITERATOR_SLOT_NEXT_INDEX, 1/0); - return { value: undefined, done: true }; - } - - UnsafeSetReservedSlot(this, ITERATOR_SLOT_NEXT_INDEX, index + 1); - return { value: array[index], done: false }; - }; - - UnsafeSetReservedSlot(iterator, ITERATOR_SLOT_NEXT_METHOD, next); - iterator.next = next; - - iterator[std_iterator] = ListIteratorIdentity; - return iterator; -} - -function ListIteratorIdentity() { - if (!IsObject(this) || !IsListIterator(this)) - return callFunction(CallListIteratorMethodIfWrapped, this, "ListIteratorIdentity"); - - return this; -} diff --git a/js/src/builtin/Module.js b/js/src/builtin/Module.js index 7b70a7fe8..5c3d5e147 100644 --- a/js/src/builtin/Module.js +++ b/js/src/builtin/Module.js @@ -65,12 +65,12 @@ function ModuleGetExportedNames(exportStarSet = []) return exportedNames; } -// 15.2.1.16.3 ResolveExport(exportName, resolveSet, exportStarSet) -function ModuleResolveExport(exportName, resolveSet = [], exportStarSet = []) +// 15.2.1.16.3 ResolveExport(exportName, resolveSet) +function ModuleResolveExport(exportName, resolveSet = []) { if (!IsObject(this) || !IsModule(this)) { return callFunction(CallModuleMethodIfWrapped, this, exportName, resolveSet, - exportStarSet, "ModuleResolveExport"); + "ModuleResolveExport"); } // Step 1 @@ -100,38 +100,29 @@ function ModuleResolveExport(exportName, resolveSet = [], exportStarSet = []) let e = indirectExportEntries[i]; if (exportName === e.exportName) { let importedModule = CallModuleResolveHook(module, e.moduleRequest, - MODULE_STATE_INSTANTIATED); - let indirectResolution = callFunction(importedModule.resolveExport, importedModule, - e.importName, resolveSet, exportStarSet); - if (indirectResolution !== null) - return indirectResolution; + MODULE_STATE_PARSED); + return callFunction(importedModule.resolveExport, importedModule, e.importName, + resolveSet); } } // Step 6 if (exportName === "default") { // A default export cannot be provided by an export *. - ThrowSyntaxError(JSMSG_BAD_DEFAULT_EXPORT); + return null; } // Step 7 - if (callFunction(ArrayIncludes, exportStarSet, module)) - return null; - - // Step 8 - _DefineDataProperty(exportStarSet, exportStarSet.length, module); - - // Step 9 let starResolution = null; - // Step 10 + // Step 8 let starExportEntries = module.starExportEntries; 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, exportStarSet); + exportName, resolveSet); if (resolution === "ambiguous") return resolution; @@ -148,6 +139,7 @@ function ModuleResolveExport(exportName, resolveSet = [], exportStarSet = []) } } + // Step 9 return starResolution; } @@ -213,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); @@ -275,11 +267,13 @@ 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); } } - // Step 16.iv + // Step 17.a.iii InstantiateModuleFunctionDeclarations(module); } catch (e) { RecordInstantationFailure(module); @@ -318,11 +312,3 @@ function ModuleEvaluation() return EvaluateModule(module); } _SetCanonicalName(ModuleEvaluation, "ModuleEvaluation"); - -function ModuleNamespaceEnumerate() -{ - if (!IsObject(this) || !IsModuleNamespace(this)) - return callFunction(CallModuleMethodIfWrapped, this, "ModuleNamespaceEnumerate"); - - return CreateListIterator(ModuleNamespaceExports(this)); -} diff --git a/js/src/builtin/ModuleObject.cpp b/js/src/builtin/ModuleObject.cpp index 710c7a76c..333cb3e11 100644 --- a/js/src/builtin/ModuleObject.cpp +++ b/js/src/builtin/ModuleObject.cpp @@ -147,7 +147,7 @@ DEFINE_GETTER_FUNCTIONS(ExportEntryObject, moduleRequest, ModuleRequestSlot) DEFINE_GETTER_FUNCTIONS(ExportEntryObject, importName, ImportNameSlot) DEFINE_GETTER_FUNCTIONS(ExportEntryObject, localName, LocalNameSlot) -DEFINE_ATOM_ACCESSOR_METHOD(ExportEntryObject, exportName) +DEFINE_ATOM_OR_NULL_ACCESSOR_METHOD(ExportEntryObject, exportName) DEFINE_ATOM_OR_NULL_ACCESSOR_METHOD(ExportEntryObject, moduleRequest) DEFINE_ATOM_OR_NULL_ACCESSOR_METHOD(ExportEntryObject, importName) DEFINE_ATOM_OR_NULL_ACCESSOR_METHOD(ExportEntryObject, localName) @@ -289,14 +289,6 @@ ModuleNamespaceObject::create(JSContext* cx, HandleModuleObject module) if (!object) return nullptr; - RootedId funName(cx, INTERNED_STRING_TO_JSID(cx, cx->names().Symbol_iterator_fun)); - RootedFunction enumerateFun(cx); - enumerateFun = JS::GetSelfHostedFunction(cx, "ModuleNamespaceEnumerate", funName, 0); - if (!enumerateFun) - return nullptr; - - SetProxyExtra(object, ProxyHandler::EnumerateFunctionSlot, ObjectValue(*enumerateFun)); - return &object->as<ModuleNamespaceObject>(); } @@ -338,14 +330,9 @@ ModuleNamespaceObject::addBinding(JSContext* cx, HandleAtom exportedName, const char ModuleNamespaceObject::ProxyHandler::family = 0; ModuleNamespaceObject::ProxyHandler::ProxyHandler() - : BaseProxyHandler(&family, true) + : BaseProxyHandler(&family, false) {} -JS::Value ModuleNamespaceObject::ProxyHandler::getEnumerateFunction(HandleObject proxy) const -{ - return GetProxyExtra(proxy, EnumerateFunctionSlot); -} - bool ModuleNamespaceObject::ProxyHandler::getPrototype(JSContext* cx, HandleObject proxy, MutableHandleObject protop) const @@ -358,6 +345,8 @@ bool ModuleNamespaceObject::ProxyHandler::setPrototype(JSContext* cx, HandleObject proxy, HandleObject proto, ObjectOpResult& result) const { + if (!proto) + return result.succeed(); return result.failCantSetProto(); } @@ -402,21 +391,12 @@ ModuleNamespaceObject::ProxyHandler::getOwnPropertyDescriptor(JSContext* cx, Han Rooted<ModuleNamespaceObject*> ns(cx, &proxy->as<ModuleNamespaceObject>()); if (JSID_IS_SYMBOL(id)) { Rooted<JS::Symbol*> symbol(cx, JSID_TO_SYMBOL(id)); - if (symbol == cx->wellKnownSymbols().iterator) { - RootedValue enumerateFun(cx, getEnumerateFunction(proxy)); - desc.object().set(proxy); - desc.setConfigurable(false); - desc.setEnumerable(false); - desc.setValue(enumerateFun); - return true; - } - if (symbol == cx->wellKnownSymbols().toStringTag) { RootedValue value(cx, StringValue(cx->names().Module)); desc.object().set(proxy); desc.setWritable(false); desc.setEnumerable(false); - desc.setConfigurable(true); + desc.setConfigurable(false); desc.setValue(value); return true; } @@ -458,8 +438,8 @@ ModuleNamespaceObject::ProxyHandler::has(JSContext* cx, HandleObject proxy, Hand Rooted<ModuleNamespaceObject*> ns(cx, &proxy->as<ModuleNamespaceObject>()); if (JSID_IS_SYMBOL(id)) { Rooted<JS::Symbol*> symbol(cx, JSID_TO_SYMBOL(id)); - return symbol == cx->wellKnownSymbols().iterator || - symbol == cx->wellKnownSymbols().toStringTag; + *bp = symbol == cx->wellKnownSymbols().toStringTag; + return true; } *bp = ns->bindings().has(id); @@ -473,23 +453,21 @@ ModuleNamespaceObject::ProxyHandler::get(JSContext* cx, HandleObject proxy, Hand Rooted<ModuleNamespaceObject*> ns(cx, &proxy->as<ModuleNamespaceObject>()); if (JSID_IS_SYMBOL(id)) { Rooted<JS::Symbol*> symbol(cx, JSID_TO_SYMBOL(id)); - if (symbol == cx->wellKnownSymbols().iterator) { - vp.set(getEnumerateFunction(proxy)); - return true; - } - if (symbol == cx->wellKnownSymbols().toStringTag) { vp.setString(cx->names().Module); return true; } - return false; + vp.setUndefined(); + return true; } ModuleEnvironmentObject* env; Shape* shape; - if (!ns->bindings().lookup(id, &env, &shape)) - return false; + if (!ns->bindings().lookup(id, &env, &shape)) { + vp.setUndefined(); + return true; + } RootedValue value(cx, env->getSlot(shape->slot())); if (value.isMagic(JS_UNINITIALIZED_LEXICAL)) { @@ -526,7 +504,7 @@ ModuleNamespaceObject::ProxyHandler::ownPropertyKeys(JSContext* cx, HandleObject Rooted<ModuleNamespaceObject*> ns(cx, &proxy->as<ModuleNamespaceObject>()); RootedObject exports(cx, &ns->exports()); uint32_t count; - if (!GetLengthProperty(cx, exports, &count) || !props.reserve(props.length() + count)) + if (!GetLengthProperty(cx, exports, &count) || !props.reserve(props.length() + count + 1)) return false; Rooted<ValueVector> names(cx, ValueVector(cx)); @@ -536,6 +514,8 @@ ModuleNamespaceObject::ProxyHandler::ownPropertyKeys(JSContext* cx, HandleObject for (uint32_t i = 0; i < count; i++) props.infallibleAppend(AtomToId(&names[i].toString()->asAtom())); + props.infallibleAppend(SYMBOL_TO_JSID(cx->wellKnownSymbols().toStringTag)); + return true; } @@ -1014,7 +994,7 @@ GlobalObject::initModuleProto(JSContext* cx, Handle<GlobalObject*> global) static const JSFunctionSpec protoFunctions[] = { JS_SELF_HOSTED_FN("getExportedNames", "ModuleGetExportedNames", 1, 0), - JS_SELF_HOSTED_FN("resolveExport", "ModuleResolveExport", 3, 0), + JS_SELF_HOSTED_FN("resolveExport", "ModuleResolveExport", 2, 0), JS_SELF_HOSTED_FN("declarationInstantiation", "ModuleDeclarationInstantiation", 0, 0), JS_SELF_HOSTED_FN("evaluation", "ModuleEvaluation", 0, 0), JS_FS_END @@ -1164,6 +1144,13 @@ ModuleBuilder::processExport(frontend::ParseNode* pn) bool isDefault = pn->getKind() == PNK_EXPORT_DEFAULT; ParseNode* kid = isDefault ? pn->pn_left : pn->pn_kid; + if (isDefault && pn->pn_right) { + // This is an export default containing an expression. + RootedAtom localName(cx_, cx_->names().starDefaultStar); + RootedAtom exportName(cx_, cx_->names().default_); + return appendExportEntry(exportName, localName); + } + switch (kid->getKind()) { case PNK_EXPORT_SPEC_LIST: MOZ_ASSERT(!isDefault); @@ -1177,53 +1164,46 @@ ModuleBuilder::processExport(frontend::ParseNode* pn) break; case PNK_CLASS: { - const ClassNode& cls = kid->as<ClassNode>(); - MOZ_ASSERT(cls.names()); - RootedAtom localName(cx_, cls.names()->innerBinding()->pn_atom); - RootedAtom exportName(cx_, isDefault ? cx_->names().default_ : localName.get()); - if (!appendExportEntry(exportName, localName)) - return false; - break; + const ClassNode& cls = kid->as<ClassNode>(); + MOZ_ASSERT(cls.names()); + RootedAtom localName(cx_, cls.names()->innerBinding()->pn_atom); + RootedAtom exportName(cx_, isDefault ? cx_->names().default_ : localName.get()); + if (!appendExportEntry(exportName, localName)) + return false; + break; } case PNK_VAR: case PNK_CONST: case PNK_LET: { - MOZ_ASSERT(kid->isArity(PN_LIST)); - for (ParseNode* var = kid->pn_head; var; var = var->pn_next) { - if (var->isKind(PNK_ASSIGN)) - var = var->pn_left; - MOZ_ASSERT(var->isKind(PNK_NAME)); - RootedAtom localName(cx_, var->pn_atom); - RootedAtom exportName(cx_, isDefault ? cx_->names().default_ : localName.get()); - if (!appendExportEntry(exportName, localName)) - return false; - } - break; + MOZ_ASSERT(kid->isArity(PN_LIST)); + for (ParseNode* var = kid->pn_head; var; var = var->pn_next) { + if (var->isKind(PNK_ASSIGN)) + var = var->pn_left; + MOZ_ASSERT(var->isKind(PNK_NAME)); + RootedAtom localName(cx_, var->pn_atom); + RootedAtom exportName(cx_, isDefault ? cx_->names().default_ : localName.get()); + if (!appendExportEntry(exportName, localName)) + return false; + } + break; } case PNK_FUNCTION: { - RootedFunction func(cx_, kid->pn_funbox->function()); - if (!func->isArrow()) { - RootedAtom localName(cx_, func->explicitName()); - RootedAtom exportName(cx_, isDefault ? cx_->names().default_ : localName.get()); - MOZ_ASSERT_IF(isDefault, localName); - if (!appendExportEntry(exportName, localName)) - return false; - break; - } - } - - MOZ_FALLTHROUGH; // Arrow functions are handled below. - - default: - MOZ_ASSERT(isDefault); - RootedAtom localName(cx_, cx_->names().starDefaultStar); - RootedAtom exportName(cx_, cx_->names().default_); + RootedFunction func(cx_, kid->pn_funbox->function()); + MOZ_ASSERT(!func->isArrow()); + RootedAtom localName(cx_, func->explicitName()); + RootedAtom exportName(cx_, isDefault ? cx_->names().default_ : localName.get()); + MOZ_ASSERT_IF(isDefault, localName); if (!appendExportEntry(exportName, localName)) return false; break; + } + + default: + MOZ_CRASH("Unexpected parse node"); } + return true; } diff --git a/js/src/builtin/ModuleObject.h b/js/src/builtin/ModuleObject.h index d0ed8ed08..51a428271 100644 --- a/js/src/builtin/ModuleObject.h +++ b/js/src/builtin/ModuleObject.h @@ -142,15 +142,8 @@ class ModuleNamespaceObject : public ProxyObject private: struct ProxyHandler : public BaseProxyHandler { - enum - { - EnumerateFunctionSlot = 0 - }; - ProxyHandler(); - JS::Value getEnumerateFunction(HandleObject proxy) const; - bool getOwnPropertyDescriptor(JSContext* cx, HandleObject proxy, HandleId id, MutableHandle<PropertyDescriptor> desc) const override; bool defineProperty(JSContext* cx, HandleObject proxy, HandleId id, diff --git a/js/src/builtin/SelfHostingDefines.h b/js/src/builtin/SelfHostingDefines.h index b57c17269..d676270a1 100644 --- a/js/src/builtin/SelfHostingDefines.h +++ b/js/src/builtin/SelfHostingDefines.h @@ -71,8 +71,6 @@ // Used for list, i.e. Array and String, iterators. #define ITERATOR_SLOT_NEXT_INDEX 1 #define ITERATOR_SLOT_ITEM_KIND 2 -// Used for ListIterator. -#define ITERATOR_SLOT_NEXT_METHOD 2 #define ITEM_KIND_KEY 0 #define ITEM_KIND_VALUE 1 diff --git a/js/src/jit-test/modules/empty.js b/js/src/jit-test/modules/empty.js new file mode 100644 index 000000000..bd9ec079d --- /dev/null +++ b/js/src/jit-test/modules/empty.js @@ -0,0 +1 @@ +// Intentionally empty. 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 000000000..2b91b6a28 --- /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 000000000..ba7dcc1b4 --- /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/modules/export-star-circular-1.js b/js/src/jit-test/modules/export-star-circular-1.js new file mode 100644 index 000000000..9a0771b02 --- /dev/null +++ b/js/src/jit-test/modules/export-star-circular-1.js @@ -0,0 +1 @@ +export* from "export-star-circular-2.js"; diff --git a/js/src/jit-test/modules/export-star-circular-2.js b/js/src/jit-test/modules/export-star-circular-2.js new file mode 100644 index 000000000..b273d9cef --- /dev/null +++ b/js/src/jit-test/modules/export-star-circular-2.js @@ -0,0 +1,3 @@ +export {y as x} from "export-star-circular-1.js"; + +export var y = "pass"; diff --git a/js/src/jit-test/tests/basic/bug1220766.js b/js/src/jit-test/tests/basic/bug1220766.js deleted file mode 100644 index fca11eafe..000000000 --- a/js/src/jit-test/tests/basic/bug1220766.js +++ /dev/null @@ -1,3 +0,0 @@ -iter = getSelfHostedValue("CreateListIterator")([]); -iter.next(); -iter.next(); diff --git a/js/src/jit-test/tests/modules/bug-1320993.js b/js/src/jit-test/tests/modules/bug-1320993.js new file mode 100644 index 000000000..bece5731a --- /dev/null +++ b/js/src/jit-test/tests/modules/bug-1320993.js @@ -0,0 +1,2 @@ +parseModule("export default (class {})"); +parseModule("export default (class A {})"); 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 000000000..387c7c369 --- /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/jit-test/tests/modules/export-star-cannot-rescue-missing-export.js b/js/src/jit-test/tests/modules/export-star-cannot-rescue-missing-export.js new file mode 100644 index 000000000..f87829d89 --- /dev/null +++ b/js/src/jit-test/tests/modules/export-star-cannot-rescue-missing-export.js @@ -0,0 +1,4 @@ +// |jit-test| module; error:SyntaxError + +export { a } from "empty.js"; +export* from "module1.js"; diff --git a/js/src/jit-test/tests/modules/export-star-circular-dependencies.js b/js/src/jit-test/tests/modules/export-star-circular-dependencies.js new file mode 100644 index 000000000..9aa612f08 --- /dev/null +++ b/js/src/jit-test/tests/modules/export-star-circular-dependencies.js @@ -0,0 +1,6 @@ +// |jit-test| module + +import { x, y } from "export-star-circular-1.js"; + +assertEq(x, "pass"); +assertEq(y, "pass"); diff --git a/js/src/jit-test/tests/modules/import-namespace.js b/js/src/jit-test/tests/modules/import-namespace.js index f44d4568a..0287f7a60 100644 --- a/js/src/jit-test/tests/modules/import-namespace.js +++ b/js/src/jit-test/tests/modules/import-namespace.js @@ -19,9 +19,19 @@ function testHasNames(names, expected) { }); } +function testEqualArrays(actual, expected) { + assertEq(Array.isArray(actual), true); + assertEq(Array.isArray(expected), true); + assertEq(actual.length, expected.length); + for (let i = 0; i < expected.length; i++) { + assertEq(actual[i], expected[i]); + } +} + let a = moduleRepo['a'] = parseModule( - `export var a = 1; - export var b = 2;` + `// Reflection methods should return these exports alphabetically sorted. + export var b = 2; + export var a = 1;` ); let b = moduleRepo['b'] = parseModule( @@ -35,11 +45,16 @@ b.evaluation(); testHasNames(getModuleEnvironmentNames(b), ["ns", "x"]); let ns = getModuleEnvironmentValue(b, "ns"); testHasNames(Object.keys(ns), ["a", "b"]); +assertEq(ns.a, 1); +assertEq(ns.b, 2); +assertEq(ns.c, undefined); assertEq(getModuleEnvironmentValue(b, "x"), 3); // Test module namespace internal methods as defined in 9.4.6 assertEq(Object.getPrototypeOf(ns), null); -assertThrowsInstanceOf(() => Object.setPrototypeOf(ns, null), TypeError); +assertEq(Reflect.setPrototypeOf(ns, null), true); +assertEq(Reflect.setPrototypeOf(ns, Object.prototype), false); +assertThrowsInstanceOf(() => Object.setPrototypeOf(ns, {}), TypeError); assertThrowsInstanceOf(function() { ns.foo = 1; }, TypeError); assertEq(Object.isExtensible(ns), false); Object.preventExtensions(ns); @@ -59,29 +74,15 @@ desc = Object.getOwnPropertyDescriptor(ns, Symbol.toStringTag); assertEq(desc.value, "Module"); assertEq(desc.writable, false); assertEq(desc.enumerable, false); -assertEq(desc.configurable, true); +assertEq(desc.configurable, false); assertEq(typeof desc.get, "undefined"); assertEq(typeof desc.set, "undefined"); assertEq(Object.prototype.toString.call(ns), "[object Module]"); -// Test @@iterator method. -let iteratorFun = ns[Symbol.iterator]; -assertEq(iteratorFun.name, "[Symbol.iterator]"); - -let iterator = ns[Symbol.iterator](); -assertEq(iterator[Symbol.iterator](), iterator); -assertIteratorNext(iterator, "a"); -assertIteratorNext(iterator, "b"); -assertIteratorDone(iterator); - -// The iterator's next method can only be called on the object it was originally -// associated with. -iterator = ns[Symbol.iterator](); -let iterator2 = ns[Symbol.iterator](); -assertThrowsInstanceOf(() => iterator.next.call({}), TypeError); -assertThrowsInstanceOf(() => iterator.next.call(iterator2), TypeError); -assertEq(iterator.next.call(iterator).value, "a"); -assertEq(iterator2.next.call(iterator2).value, "a"); +// Test [[OwnPropertyKeys]] internal method. +testEqualArrays(Reflect.ownKeys(ns), ["a", "b", Symbol.toStringTag]); +testEqualArrays(Object.getOwnPropertyNames(ns), ["a", "b"]); +testEqualArrays(Object.getOwnPropertySymbols(ns), [Symbol.toStringTag]); // Test cyclic namespace import and access in module evaluation. let c = moduleRepo['c'] = diff --git a/js/src/jit/InlinableNatives.h b/js/src/jit/InlinableNatives.h index 18535389a..23d3143a7 100644 --- a/js/src/jit/InlinableNatives.h +++ b/js/src/jit/InlinableNatives.h @@ -120,7 +120,6 @@ _(IntrinsicGuardToArrayIterator) \ _(IntrinsicGuardToMapIterator) \ _(IntrinsicGuardToSetIterator) \ - _(IntrinsicIsListIterator) \ _(IntrinsicGuardToStringIterator) \ \ _(IntrinsicGuardToMapObject) \ diff --git a/js/src/jit/MCallOptimize.cpp b/js/src/jit/MCallOptimize.cpp index 01755094a..736c6c892 100644 --- a/js/src/jit/MCallOptimize.cpp +++ b/js/src/jit/MCallOptimize.cpp @@ -288,8 +288,6 @@ IonBuilder::inlineNativeCall(CallInfo& callInfo, JSFunction* target) return inlineGuardToClass(callInfo, &SetIteratorObject::class_); case InlinableNative::IntrinsicGuardToStringIterator: return inlineGuardToClass(callInfo, &StringIteratorObject::class_); - case InlinableNative::IntrinsicIsListIterator: - return inlineHasClass(callInfo, &ListIteratorObject::class_); case InlinableNative::IntrinsicDefineDataProperty: return inlineDefineDataProperty(callInfo); case InlinableNative::IntrinsicObjectHasPrototype: diff --git a/js/src/jsiter.cpp b/js/src/jsiter.cpp index c1ae5dc15..59893fa98 100644 --- a/js/src/jsiter.cpp +++ b/js/src/jsiter.cpp @@ -1157,18 +1157,6 @@ static const JSFunctionSpec string_iterator_methods[] = { JS_FS_END }; -enum { - ListIteratorSlotIteratedObject, - ListIteratorSlotNextIndex, - ListIteratorSlotNextMethod, - ListIteratorSlotCount -}; - -const Class ListIteratorObject::class_ = { - "List Iterator", - JSCLASS_HAS_RESERVED_SLOTS(ListIteratorSlotCount) -}; - JSObject* js::ValueToIterator(JSContext* cx, unsigned flags, HandleValue vp) { diff --git a/js/src/jsiter.h b/js/src/jsiter.h index f11f09b55..a3035ddd0 100644 --- a/js/src/jsiter.h +++ b/js/src/jsiter.h @@ -151,12 +151,6 @@ class StringIteratorObject : public JSObject static const Class class_; }; -class ListIteratorObject : public JSObject -{ - public: - static const Class class_; -}; - bool GetIterator(JSContext* cx, HandleObject obj, unsigned flags, MutableHandleObject objp); diff --git a/js/src/vm/EnvironmentObject.cpp b/js/src/vm/EnvironmentObject.cpp index 34c39eabf..9b20c2b9c 100644 --- a/js/src/vm/EnvironmentObject.cpp +++ b/js/src/vm/EnvironmentObject.cpp @@ -491,7 +491,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; diff --git a/js/src/vm/SelfHosting.cpp b/js/src/vm/SelfHosting.cpp index 08670c833..3e7baccad 100644 --- a/js/src/vm/SelfHosting.cpp +++ b/js/src/vm/SelfHosting.cpp @@ -857,37 +857,6 @@ intrinsic_NewStringIterator(JSContext* cx, unsigned argc, Value* vp) } static bool -intrinsic_NewListIterator(JSContext* cx, unsigned argc, Value* vp) -{ - CallArgs args = CallArgsFromVp(argc, vp); - MOZ_ASSERT(args.length() == 0); - - RootedObject proto(cx, GlobalObject::getOrCreateIteratorPrototype(cx, cx->global())); - if (!proto) - return false; - - RootedObject iterator(cx); - iterator = NewObjectWithGivenProto(cx, &ListIteratorObject::class_, proto); - if (!iterator) - return false; - - args.rval().setObject(*iterator); - return true; -} - -static bool -intrinsic_ActiveFunction(JSContext* cx, unsigned argc, Value* vp) -{ - CallArgs args = CallArgsFromVp(argc, vp); - MOZ_ASSERT(args.length() == 0); - - ScriptFrameIter iter(cx); - MOZ_ASSERT(iter.isFunctionFrame()); - args.rval().setObject(*iter.callee(cx)); - return true; -} - -static bool intrinsic_SetCanonicalName(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); @@ -2306,11 +2275,6 @@ static const JSFunctionSpec intrinsic_functions[] = { JS_FN("CallArrayIteratorMethodIfWrapped", CallNonGenericSelfhostedMethod<Is<ArrayIteratorObject>>, 2,0), - JS_FN("NewListIterator", intrinsic_NewListIterator, 0,0), - JS_FN("CallListIteratorMethodIfWrapped", - CallNonGenericSelfhostedMethod<Is<ListIteratorObject>>, 2,0), - JS_FN("ActiveFunction", intrinsic_ActiveFunction, 0,0), - JS_FN("_SetCanonicalName", intrinsic_SetCanonicalName, 2,0), JS_INLINABLE_FN("GuardToArrayIterator", @@ -2325,9 +2289,6 @@ static const JSFunctionSpec intrinsic_functions[] = { JS_INLINABLE_FN("GuardToStringIterator", intrinsic_GuardToBuiltin<StringIteratorObject>, 1,0, IntrinsicGuardToStringIterator), - JS_INLINABLE_FN("IsListIterator", - intrinsic_IsInstanceOfBuiltin<ListIteratorObject>, 1,0, - IntrinsicIsListIterator), JS_FN("_CreateMapIterationResultPair", intrinsic_CreateMapIterationResultPair, 0, 0), JS_INLINABLE_FN("_GetNextMapEntryForIterator", intrinsic_GetNextMapEntryForIterator, 2,0, @@ -2549,7 +2510,6 @@ static const JSFunctionSpec intrinsic_functions[] = { intrinsic_InstantiateModuleFunctionDeclarations, 1, 0), JS_FN("SetModuleState", intrinsic_SetModuleState, 1, 0), JS_FN("EvaluateModule", intrinsic_EvaluateModule, 1, 0), - JS_FN("IsModuleNamespace", intrinsic_IsInstanceOfBuiltin<ModuleNamespaceObject>, 1, 0), JS_FN("NewModuleNamespace", intrinsic_NewModuleNamespace, 2, 0), JS_FN("AddModuleNamespaceBinding", intrinsic_AddModuleNamespaceBinding, 4, 0), JS_FN("ModuleNamespaceExports", intrinsic_ModuleNamespaceExports, 1, 0), diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js index beab06aff..bee38d6c4 100644 --- a/modules/libpref/init/all.js +++ b/modules/libpref/init/all.js @@ -5453,3 +5453,6 @@ pref("dom.storageManager.enabled", false); // be blocked (automatically canceled) for that page. The counter resets // when the page is reloaded. To turn this feature off, just set the limit to 0. pref("prompts.authentication_dialog_abuse_limit", 3); + +// Whether module scripts (<script type="module">) are enabled for content. +pref("dom.moduleScripts.enabled", false); |