summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMoonchild <moonchild@palemoon.org>2019-11-10 13:33:18 +0100
committerGitHub <noreply@github.com>2019-11-10 13:33:18 +0100
commitffd99743369997aea555d76867d90b3c601e9ed4 (patch)
tree0a1162b528b0801096d27eeed1e891a29437bd6c
parent736d25cbec4541186ed46c935c117ce4d1c7f3bb (diff)
parent406326715dfb8342617df1e8985a296d0cd1b97c (diff)
downloaduxp-ffd99743369997aea555d76867d90b3c601e9ed4.tar.gz
Merge pull request #1278 from MoonchildProductions/js-modules
Partial solution for JS modules
-rw-r--r--dom/base/nsGkAtomList.h1
-rw-r--r--dom/base/nsScriptLoader.cpp65
-rw-r--r--dom/base/nsScriptLoader.h2
-rw-r--r--dom/html/HTMLScriptElement.cpp12
-rw-r--r--dom/html/HTMLScriptElement.h2
-rw-r--r--dom/html/test/file_script_module.html42
-rw-r--r--dom/html/test/file_script_nomodule.html32
-rw-r--r--dom/html/test/mochitest.ini4
-rw-r--r--dom/html/test/test_script_module.html56
-rw-r--r--dom/webidl/HTMLScriptElement.webidl2
-rw-r--r--js/src/builtin/Iterator.js41
-rw-r--r--js/src/builtin/Module.js46
-rw-r--r--js/src/builtin/ModuleObject.cpp124
-rw-r--r--js/src/builtin/ModuleObject.h7
-rw-r--r--js/src/builtin/SelfHostingDefines.h2
-rw-r--r--js/src/jit-test/modules/empty.js1
-rw-r--r--js/src/jit-test/modules/export-circular-nonexisting-binding-1.js4
-rw-r--r--js/src/jit-test/modules/export-circular-nonexisting-binding-2.js1
-rw-r--r--js/src/jit-test/modules/export-star-circular-1.js1
-rw-r--r--js/src/jit-test/modules/export-star-circular-2.js3
-rw-r--r--js/src/jit-test/tests/basic/bug1220766.js3
-rw-r--r--js/src/jit-test/tests/modules/bug-1320993.js2
-rw-r--r--js/src/jit-test/tests/modules/export-circular-nonexisting-binding.js3
-rw-r--r--js/src/jit-test/tests/modules/export-star-cannot-rescue-missing-export.js4
-rw-r--r--js/src/jit-test/tests/modules/export-star-circular-dependencies.js6
-rw-r--r--js/src/jit-test/tests/modules/import-namespace.js45
-rw-r--r--js/src/jit/InlinableNatives.h1
-rw-r--r--js/src/jit/MCallOptimize.cpp2
-rw-r--r--js/src/jsiter.cpp12
-rw-r--r--js/src/jsiter.h6
-rw-r--r--js/src/vm/EnvironmentObject.cpp2
-rw-r--r--js/src/vm/SelfHosting.cpp40
-rw-r--r--modules/libpref/init/all.js4
-rw-r--r--testing/web-platform/mozilla/meta/html/semantics/scripting-1/the-script-element/create-module-script.html.ini2
-rw-r--r--testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/create-module-script.html25
-rw-r--r--testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/support/module.js2
36 files changed, 353 insertions, 254 deletions
diff --git a/dom/base/nsGkAtomList.h b/dom/base/nsGkAtomList.h
index 8fefa0e02f..73a3a02b1f 100644
--- a/dom/base/nsGkAtomList.h
+++ b/dom/base/nsGkAtomList.h
@@ -665,6 +665,7 @@ GK_ATOM(noembed, "noembed")
GK_ATOM(noframes, "noframes")
GK_ATOM(nohref, "nohref")
GK_ATOM(noisolation, "noisolation")
+GK_ATOM(nomodule, "nomodule")
GK_ATOM(nonce, "nonce")
GK_ATOM(none, "none")
GK_ATOM(noresize, "noresize")
diff --git a/dom/base/nsScriptLoader.cpp b/dom/base/nsScriptLoader.cpp
index 1e23d6c5ff..3ac00142dc 100644
--- a/dom/base/nsScriptLoader.cpp
+++ b/dom/base/nsScriptLoader.cpp
@@ -654,6 +654,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
@@ -1230,15 +1243,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;
@@ -1434,7 +1459,7 @@ nsScriptLoader::ProcessScriptElement(nsIScriptElement *aElement)
nsCOMPtr<nsIContent> scriptContent = do_QueryInterface(aElement);
- // Step 12. Check that the script is not an eventhandler
+ // Step 13. Check that the script is not an eventhandler
if (IsScriptEventHandler(scriptContent)) {
return false;
}
@@ -1448,8 +1473,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);
@@ -1469,7 +1493,18 @@ nsScriptLoader::ProcessScriptElement(nsIScriptElement *aElement)
}
}
- // Step 14. in the HTML5 spec
+ // "In modern user agents that support module scripts, the script element with
+ // the nomodule attribute will be ignored".
+ // "The nomodule attribute must not be specified on module scripts (and will
+ // be ignored if it is)."
+ if (ModuleScriptsEnabled() &&
+ scriptKind == nsScriptKind::Classic &&
+ scriptContent->IsHTMLElement() &&
+ scriptContent->HasAttr(kNameSpaceID_None, nsGkAtoms::nomodule)) {
+ return false;
+ }
+
+ // Step 15. and later in the HTML5 spec
nsresult rv = NS_OK;
RefPtr<nsScriptLoadRequest> request;
if (aElement->GetScriptExternal()) {
@@ -1577,7 +1612,7 @@ nsScriptLoader::ProcessScriptElement(nsIScriptElement *aElement)
}
return false;
}
- if (!aElement->GetParserCreated() && !request->IsModuleRequest()) {
+ if (!aElement->GetParserCreated()) {
// Violate the HTML5 spec in order to make LABjs and the "order" plug-in
// for RequireJS work with their Gecko-sniffed code path. See
// http://lists.w3.org/Archives/Public/public-html/2010Oct/0088.html
@@ -2768,7 +2803,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 d30a58441e..a00239be5f 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/dom/html/HTMLScriptElement.cpp b/dom/html/HTMLScriptElement.cpp
index 94d09c12c1..095b9b77de 100644
--- a/dom/html/HTMLScriptElement.cpp
+++ b/dom/html/HTMLScriptElement.cpp
@@ -218,6 +218,18 @@ HTMLScriptElement::SetAsync(bool aValue, ErrorResult& rv)
SetHTMLBoolAttr(nsGkAtoms::async, aValue, rv);
}
+bool
+HTMLScriptElement::NoModule()
+{
+ return GetBoolAttr(nsGkAtoms::nomodule);
+}
+
+void
+HTMLScriptElement::SetNoModule(bool aValue, ErrorResult& aRv)
+{
+ SetHTMLBoolAttr(nsGkAtoms::nomodule, aValue, aRv);
+}
+
nsresult
HTMLScriptElement::AfterSetAttr(int32_t aNamespaceID, nsIAtom* aName,
const nsAttrValue* aValue, bool aNotify)
diff --git a/dom/html/HTMLScriptElement.h b/dom/html/HTMLScriptElement.h
index 00628bd6d3..19ceb414f9 100644
--- a/dom/html/HTMLScriptElement.h
+++ b/dom/html/HTMLScriptElement.h
@@ -89,6 +89,8 @@ public:
}
bool Async();
void SetAsync(bool aValue, ErrorResult& rv);
+ bool NoModule();
+ void SetNoModule(bool aValue, ErrorResult& rv);
protected:
virtual ~HTMLScriptElement();
diff --git a/dom/html/test/file_script_module.html b/dom/html/test/file_script_module.html
new file mode 100644
index 0000000000..78c4992654
--- /dev/null
+++ b/dom/html/test/file_script_module.html
@@ -0,0 +1,42 @@
+<html>
+<body>
+ <script>
+// Helper methods.
+function ok(a, msg) {
+ parent.postMessage({ check: !!a, msg }, "*")
+}
+
+function is(a, b, msg) {
+ ok(a === b, msg);
+}
+
+function finish() {
+ parent.postMessage({ done: true }, "*");
+}
+ </script>
+
+ <script id="a" nomodule>42</script>
+ <script id="b">42</script>
+ <script>
+// Let's test the behavior of nomodule attribute and noModule getter/setter.
+var a = document.getElementById("a");
+is(a.noModule, true, "HTMLScriptElement with nomodule attribute has noModule set to true");
+a.removeAttribute("nomodule");
+is(a.noModule, false, "HTMLScriptElement without nomodule attribute has noModule set to false");
+a.noModule = true;
+ok(a.hasAttribute('nomodule'), "HTMLScriptElement.noModule = true add the nomodule attribute");
+
+var b = document.getElementById("b");
+is(b.noModule, false, "HTMLScriptElement without nomodule attribute has noModule set to false");
+b.noModule = true;
+ok(b.hasAttribute('nomodule'), "HTMLScriptElement.noModule = true add the nomodule attribute");
+ </script>
+
+ <script>var foo = 42;</script>
+ <script nomodule>foo = 43;</script>
+ <script>
+is(foo, 42, "nomodule HTMLScriptElements should not be executed in modern browsers");
+finish();
+ </script>
+</body>
+</html>
diff --git a/dom/html/test/file_script_nomodule.html b/dom/html/test/file_script_nomodule.html
new file mode 100644
index 0000000000..303edb90bb
--- /dev/null
+++ b/dom/html/test/file_script_nomodule.html
@@ -0,0 +1,32 @@
+<html>
+<body>
+ <script>
+// Helper methods.
+function ok(a, msg) {
+ parent.postMessage({ check: !!a, msg }, "*")
+}
+
+function is(a, b, msg) {
+ ok(a === b, msg);
+}
+
+function finish() {
+ parent.postMessage({ done: true }, "*");
+}
+ </script>
+
+ <script id="a" nomodule>42</script>
+ <script>
+// Let's test the behavior of nomodule attribute and noModule getter/setter.
+var a = document.getElementById("a");
+ok(!("noModule" in a), "When modules are disabled HTMLScriptElement.noModule is not defined");
+ </script>
+
+ <script>var foo = 42;</script>
+ <script nomodule>foo = 43;</script>
+ <script>
+is(foo, 43, "nomodule attribute is ignored when modules are disabled");
+finish();
+ </script>
+</body>
+</html>
diff --git a/dom/html/test/mochitest.ini b/dom/html/test/mochitest.ini
index f619be5df6..b9da7def8e 100644
--- a/dom/html/test/mochitest.ini
+++ b/dom/html/test/mochitest.ini
@@ -605,3 +605,7 @@ skip-if = os == "android" # up/down arrow keys not supported on android
[test_bug1295719_event_sequence_for_number_keys.html]
[test_bug1310865.html]
[test_bug1315146.html]
+[test_script_module.html]
+support-files =
+ file_script_module.html
+ file_script_nomodule.html \ No newline at end of file
diff --git a/dom/html/test/test_script_module.html b/dom/html/test/test_script_module.html
new file mode 100644
index 0000000000..4878bb379f
--- /dev/null
+++ b/dom/html/test/test_script_module.html
@@ -0,0 +1,56 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>Test for HTMLScriptElement with nomodule attribute</title>
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+
+<body>
+ <script>
+onmessage = (e) => {
+ if ("done" in e.data) {
+ next();
+ } else if ("check" in e.data) {
+ ok(e.data.check, e.data.msg);
+ } else {
+ ok(false, "Unknown message");
+ }
+}
+
+var tests = [
+ function() {
+ SpecialPowers.pushPrefEnv({"set":[["dom.moduleScripts.enabled", true]]})
+ .then(() => {
+ var ifr = document.createElement('iframe');
+ ifr.src = "file_script_module.html";
+ document.body.appendChild(ifr);
+ });
+ },
+
+ function() {
+ SpecialPowers.pushPrefEnv({"set":[["dom.moduleScripts.enabled", false]]})
+ .then(() => {
+ var ifr = document.createElement('iframe');
+ ifr.src = "file_script_nomodule.html";
+ document.body.appendChild(ifr);
+ });
+ },
+];
+
+SimpleTest.waitForExplicitFinish();
+next();
+
+function next() {
+ if (!tests.length) {
+ SimpleTest.finish();
+ return;
+ }
+
+ var test = tests.shift();
+ test();
+}
+ </script>
+
+</body>
+</html>
diff --git a/dom/webidl/HTMLScriptElement.webidl b/dom/webidl/HTMLScriptElement.webidl
index 377056366d..5b64c42d7c 100644
--- a/dom/webidl/HTMLScriptElement.webidl
+++ b/dom/webidl/HTMLScriptElement.webidl
@@ -13,6 +13,8 @@ interface HTMLScriptElement : HTMLElement {
attribute DOMString src;
[SetterThrows]
attribute DOMString type;
+ [SetterThrows, Pref="dom.moduleScripts.enabled"]
+ attribute boolean noModule;
[SetterThrows]
attribute DOMString charset;
[SetterThrows]
diff --git a/js/src/builtin/Iterator.js b/js/src/builtin/Iterator.js
index 735eec7a06..e25b761561 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 7b70a7fe8b..5c3d5e1479 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 798ef46e11..575bab0b0c 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 e83520ebe6..22db762ac6 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 b57c172691..d676270a14 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 0000000000..bd9ec079d8
--- /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 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/modules/export-star-circular-1.js b/js/src/jit-test/modules/export-star-circular-1.js
new file mode 100644
index 0000000000..9a0771b024
--- /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 0000000000..b273d9cefa
--- /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 fca11eafe6..0000000000
--- 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 0000000000..bece5731a3
--- /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 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/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 0000000000..f87829d89b
--- /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 0000000000..9aa612f087
--- /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 f44d4568aa..0287f7a60e 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 1d0506f743..9c864515d0 100644
--- a/js/src/jit/InlinableNatives.h
+++ b/js/src/jit/InlinableNatives.h
@@ -119,7 +119,6 @@
_(IntrinsicGuardToArrayIterator) \
_(IntrinsicGuardToMapIterator) \
_(IntrinsicGuardToSetIterator) \
- _(IntrinsicIsListIterator) \
_(IntrinsicGuardToStringIterator) \
\
_(IntrinsicGuardToMapObject) \
diff --git a/js/src/jit/MCallOptimize.cpp b/js/src/jit/MCallOptimize.cpp
index 5eee30e497..2363545300 100644
--- a/js/src/jit/MCallOptimize.cpp
+++ b/js/src/jit/MCallOptimize.cpp
@@ -285,8 +285,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 749e15d27d..3e222ca6fb 100644
--- a/js/src/jsiter.cpp
+++ b/js/src/jsiter.cpp
@@ -1135,18 +1135,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 f11f09b550..a3035ddd0f 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 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;
diff --git a/js/src/vm/SelfHosting.cpp b/js/src/vm/SelfHosting.cpp
index 792a00490c..82d2cde642 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);
@@ -2290,11 +2259,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",
@@ -2309,9 +2273,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,
@@ -2533,7 +2494,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 2e3d2aecfd..61a2ef1b54 100644
--- a/modules/libpref/init/all.js
+++ b/modules/libpref/init/all.js
@@ -5486,3 +5486,7 @@ pref("dom.storageManager.enabled", false);
// >0 = suppress further prompts after the user has canceled the dialog n times
// See application preferences for appropriate defaults.
pref("prompts.authentication_dialog_abuse_limit", 0);
+
+// Whether module scripts (<script type="module">) are enabled for content.
+pref("dom.moduleScripts.enabled", false);
+
diff --git a/testing/web-platform/mozilla/meta/html/semantics/scripting-1/the-script-element/create-module-script.html.ini b/testing/web-platform/mozilla/meta/html/semantics/scripting-1/the-script-element/create-module-script.html.ini
new file mode 100644
index 0000000000..007349f1aa
--- /dev/null
+++ b/testing/web-platform/mozilla/meta/html/semantics/scripting-1/the-script-element/create-module-script.html.ini
@@ -0,0 +1,2 @@
+[create-module-script.html]
+ prefs: [dom.moduleScripts.enabled:true]
diff --git a/testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/create-module-script.html b/testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/create-module-script.html
new file mode 100644
index 0000000000..44337a0217
--- /dev/null
+++ b/testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/create-module-script.html
@@ -0,0 +1,25 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Insert non-async module script</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script>
+ var test = async_test("Create module script")
+ var moduleRan = false;
+ function loadModule() {
+ var script = document.createElement("script");
+ script.onerror = function() {
+ test.step(() => assert_unreached("Should not get an error"));
+ test.done();
+ };
+ script.onload = function() {
+ test.step(() => assert_equals(moduleRan, true));
+ test.done();
+ };
+ script.type = "module";
+ script.src = "support/module.js";
+ script.async = false;
+ document.documentElement.appendChild(script);
+ }
+</script>
+<body onload='loadModule()'></body>
diff --git a/testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/support/module.js b/testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/support/module.js
new file mode 100644
index 0000000000..e4d6289d59
--- /dev/null
+++ b/testing/web-platform/mozilla/tests/html/semantics/scripting-1/the-script-element/support/module.js
@@ -0,0 +1,2 @@
+export default 42;
+moduleRan = true;