summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMoonchild <moonchild@palemoon.org>2020-11-27 15:47:49 +0000
committerMoonchild <moonchild@palemoon.org>2020-11-27 15:47:49 +0000
commit15914ec5780e7867ab508a48a83311c56950f8a9 (patch)
tree80562c8ff9e25d119fde8725fa89d171ef20bb42
parentb863bd2edc94c16498edc3274531f57fbfc30d3f (diff)
downloaduxp-15914ec5780e7867ab508a48a83311c56950f8a9.tar.gz
Issue #1691 - Part 1: Provide a way of associating a private value with a script
or module. This is a prerequisite for dynamic import
-rw-r--r--dom/script/ModuleScript.cpp6
-rw-r--r--dom/script/ScriptLoader.cpp8
-rw-r--r--dom/script/ScriptLoader.h5
-rw-r--r--js/src/builtin/ModuleObject.cpp20
-rw-r--r--js/src/builtin/ModuleObject.h6
-rw-r--r--js/src/jsapi.cpp20
-rw-r--r--js/src/jsapi.h25
-rw-r--r--js/src/jsscript.h20
-rw-r--r--js/src/shell/js.cpp59
-rw-r--r--js/src/vm/SelfHosting.cpp3
10 files changed, 129 insertions, 43 deletions
diff --git a/dom/script/ModuleScript.cpp b/dom/script/ModuleScript.cpp
index 9f7fe9ab92..b2a72e6287 100644
--- a/dom/script/ModuleScript.cpp
+++ b/dom/script/ModuleScript.cpp
@@ -58,9 +58,9 @@ ModuleScript::UnlinkModuleRecord()
{
// Remove module's back reference to this object request if present.
if (mModuleRecord) {
- MOZ_ASSERT(JS::GetModuleHostDefinedField(mModuleRecord).toPrivate() ==
+ MOZ_ASSERT(JS::GetModulePrivate(mModuleRecord).toPrivate() ==
this);
- JS::SetModuleHostDefinedField(mModuleRecord, JS::UndefinedValue());
+ JS::SetModulePrivate(mModuleRecord, JS::UndefinedValue());
mModuleRecord = nullptr;
}
}
@@ -83,7 +83,7 @@ ModuleScript::SetModuleRecord(JS::Handle<JSObject*> aModuleRecord)
// Make module's host defined field point to this module script object.
// This is cleared in the UnlinkModuleRecord().
- JS::SetModuleHostDefinedField(mModuleRecord, JS::PrivateValue(this));
+ JS::SetModulePrivate(mModuleRecord, JS::PrivateValue(this));
HoldJSObjects(this);
}
diff --git a/dom/script/ScriptLoader.cpp b/dom/script/ScriptLoader.cpp
index 5b7bea8d22..8058c8caa7 100644
--- a/dom/script/ScriptLoader.cpp
+++ b/dom/script/ScriptLoader.cpp
@@ -798,13 +798,13 @@ ScriptLoader::StartFetchingModuleAndDependencies(ModuleLoadRequest* aParent,
// 8.1.3.8.1 HostResolveImportedModule(referencingModule, specifier)
JSObject*
-HostResolveImportedModule(JSContext* aCx, JS::Handle<JSObject*> aModule,
+HostResolveImportedModule(JSContext* aCx,
+ JS::Handle<JS::Value> aReferencingPrivate,
JS::Handle<JSString*> aSpecifier)
{
// Let referencing module script be referencingModule.[[HostDefined]].
- JS::Value value = JS::GetModuleHostDefinedField(aModule);
- auto script = static_cast<ModuleScript*>(value.toPrivate());
- MOZ_ASSERT(script->ModuleRecord() == aModule);
+ auto script = static_cast<ModuleScript*>(aReferencingPrivate.toPrivate());
+ MOZ_ASSERT(JS::GetModulePrivate(script->ModuleRecord()) == aReferencingPrivate);
// Let url be the result of resolving a module specifier given referencing
// module script and specifier.
diff --git a/dom/script/ScriptLoader.h b/dom/script/ScriptLoader.h
index ec9524f14a..8cbcf7b966 100644
--- a/dom/script/ScriptLoader.h
+++ b/dom/script/ScriptLoader.h
@@ -630,8 +630,9 @@ private:
ModuleScript* GetFetchedModule(nsIURI* aURL) const;
friend JSObject*
- HostResolveImportedModule(JSContext* aCx, JS::Handle<JSObject*> aModule,
- JS::Handle<JSString*> aSpecifier);
+ HostResolveImportedModule(JSContext* aCx,
+ JS::Handle<JS::Value> aReferencingPrivate,
+ JS::Handle<JSString*> aSpecifier);
nsresult CreateModuleScript(ModuleLoadRequest* aRequest);
nsresult ProcessFetchedModuleSource(ModuleLoadRequest* aRequest);
diff --git a/js/src/builtin/ModuleObject.cpp b/js/src/builtin/ModuleObject.cpp
index 2790b1c444..ae966c89ad 100644
--- a/js/src/builtin/ModuleObject.cpp
+++ b/js/src/builtin/ModuleObject.cpp
@@ -725,6 +725,12 @@ ModuleObject::namespace_()
return &value.toObject().as<ModuleNamespaceObject>();
}
+ScriptSourceObject*
+ModuleObject::scriptSourceObject() const
+{
+ return &getReservedSlot(ScriptSourceObjectSlot).toObject().as<ScriptSourceObject>();
+}
+
FunctionDeclarationVector*
ModuleObject::functionDeclarations()
{
@@ -738,8 +744,10 @@ ModuleObject::functionDeclarations()
void
ModuleObject::init(HandleScript script)
{
+ MOZ_ASSERT(script);
initReservedSlot(ScriptSlot, PrivateValue(script));
initReservedSlot(StatusSlot, Int32Value(MODULE_STATUS_UNINSTANTIATED));
+ initReservedSlot(ScriptSourceObjectSlot, ObjectValue(script->scriptSourceUnwrap()));
}
void
@@ -868,18 +876,6 @@ ModuleObject::evaluationError() const
return getReservedSlot(EvaluationErrorSlot);
}
-Value
-ModuleObject::hostDefinedField() const
-{
- return getReservedSlot(HostDefinedSlot);
-}
-
-void
-ModuleObject::setHostDefinedField(const JS::Value& value)
-{
- setReservedSlot(HostDefinedSlot, value);
-}
-
Scope*
ModuleObject::enclosingScope() const
{
diff --git a/js/src/builtin/ModuleObject.h b/js/src/builtin/ModuleObject.h
index dc078e6b28..c2514e876d 100644
--- a/js/src/builtin/ModuleObject.h
+++ b/js/src/builtin/ModuleObject.h
@@ -219,7 +219,7 @@ class ModuleObject : public NativeObject
NamespaceSlot,
StatusSlot,
EvaluationErrorSlot,
- HostDefinedSlot,
+ ScriptSourceObjectSlot,
RequestedModulesSlot,
ImportEntriesSlot,
LocalExportEntriesSlot,
@@ -271,7 +271,7 @@ class ModuleObject : public NativeObject
ModuleStatus status() const;
bool hadEvaluationError() const;
Value evaluationError() const;
- Value hostDefinedField() const;
+ ScriptSourceObject* scriptSourceObject() const;
ArrayObject& requestedModules() const;
ArrayObject& importEntries() const;
ArrayObject& localExportEntries() const;
@@ -284,8 +284,6 @@ class ModuleObject : public NativeObject
static bool Instantiate(JSContext* cx, HandleModuleObject self);
static bool Evaluate(JSContext* cx, HandleModuleObject self);
- void setHostDefinedField(const JS::Value& value);
-
// For BytecodeEmitter.
bool noteFunctionDeclaration(ExclusiveContext* cx, HandleAtom name, HandleFunction fun);
diff --git a/js/src/jsapi.cpp b/js/src/jsapi.cpp
index dab4c25a43..74d64e312e 100644
--- a/js/src/jsapi.cpp
+++ b/js/src/jsapi.cpp
@@ -4691,15 +4691,27 @@ JS::CompileModule(JSContext* cx, const ReadOnlyCompileOptions& options,
}
JS_PUBLIC_API(void)
-JS::SetModuleHostDefinedField(JSObject* module, const JS::Value& value)
+JS::SetModulePrivate(JSObject* module, const JS::Value& value)
{
- module->as<ModuleObject>().setHostDefinedField(value);
+ module->as<ModuleObject>().scriptSourceObject()->setPrivate(value);
}
JS_PUBLIC_API(JS::Value)
-JS::GetModuleHostDefinedField(JSObject* module)
+JS::GetModulePrivate(JSObject* module)
{
- return module->as<ModuleObject>().hostDefinedField();
+ return module->as<ModuleObject>().scriptSourceObject()->getPrivate();
+}
+
+JS_PUBLIC_API(void)
+JS::SetScriptPrivate(JSScript* script, const JS::Value& value)
+{
+ script->scriptSourceUnwrap().setPrivate(value);
+}
+
+JS_PUBLIC_API(JS::Value)
+JS::GetScriptPrivate(JSScript* script)
+{
+ return script->scriptSourceUnwrap().getPrivate();
}
JS_PUBLIC_API(bool)
diff --git a/js/src/jsapi.h b/js/src/jsapi.h
index f8203ee1fd..82477f9a7e 100644
--- a/js/src/jsapi.h
+++ b/js/src/jsapi.h
@@ -4324,7 +4324,7 @@ extern JS_PUBLIC_API(bool)
Evaluate(JSContext* cx, const ReadOnlyCompileOptions& options,
const char* filename, JS::MutableHandleValue rval);
-using ModuleResolveHook = JSObject* (*)(JSContext*, HandleObject, HandleString);
+using ModuleResolveHook = JSObject* (*)(JSContext*, HandleValue, HandleString);
/**
* Get the HostResolveImportedModule hook for the runtime.
@@ -4347,17 +4347,30 @@ CompileModule(JSContext* cx, const ReadOnlyCompileOptions& options,
SourceBufferHolder& srcBuf, JS::MutableHandleObject moduleRecord);
/**
- * Set the [[HostDefined]] field of a source text module record to the given
- * value.
+ * Set a private value associated with a source text module record.
*/
extern JS_PUBLIC_API(void)
-SetModuleHostDefinedField(JSObject* module, const JS::Value& value);
+SetModulePrivate(JSObject* module, const JS::Value& value);
/**
- * Get the [[HostDefined]] field of a source text module record.
+ * Get the private value associated with a source text module record.
*/
extern JS_PUBLIC_API(JS::Value)
-GetModuleHostDefinedField(JSObject* module);
+GetModulePrivate(JSObject* module);
+
+/**
+ * Set a private value associated with a script. Note that this value is shared
+ * by all nested scripts compiled from a single source file.
+ */
+extern JS_PUBLIC_API(void)
+SetScriptPrivate(JSScript* script, const JS::Value& value);
+
+/**
+ * Get the private value associated with a script. Note that this value is
+ * shared by all nested scripts compiled from a single source file.
+ */
+extern JS_PUBLIC_API(JS::Value)
+GetScriptPrivate(JSScript* script);
/*
* Perform the ModuleInstantiate operation on the given source text module
diff --git a/js/src/jsscript.h b/js/src/jsscript.h
index d8d28ebebe..fd5c96a16d 100644
--- a/js/src/jsscript.h
+++ b/js/src/jsscript.h
@@ -638,12 +638,22 @@ class ScriptSourceObject : public NativeObject
return static_cast<JSScript*>(untyped);
}
+ void setPrivate(const Value& value) {
+ setReservedSlot(PRIVATE_SLOT, value);
+ }
+ Value getPrivate() const {
+ return getReservedSlot(PRIVATE_SLOT);
+ }
+
private:
- static const uint32_t SOURCE_SLOT = 0;
- static const uint32_t ELEMENT_SLOT = 1;
- static const uint32_t ELEMENT_PROPERTY_SLOT = 2;
- static const uint32_t INTRODUCTION_SCRIPT_SLOT = 3;
- static const uint32_t RESERVED_SLOTS = 4;
+ enum {
+ SOURCE_SLOT = 0,
+ ELEMENT_SLOT,
+ ELEMENT_PROPERTY_SLOT,
+ INTRODUCTION_SCRIPT_SLOT,
+ PRIVATE_SLOT,
+ RESERVED_SLOTS
+ };
};
enum GeneratorKind { NotGenerator, LegacyGenerator, StarGenerator };
diff --git a/js/src/shell/js.cpp b/js/src/shell/js.cpp
index 6e155d3ff6..acd2ec207f 100644
--- a/js/src/shell/js.cpp
+++ b/js/src/shell/js.cpp
@@ -4039,12 +4039,12 @@ SetModuleResolveHook(JSContext* cx, unsigned argc, Value* vp)
}
static JSObject*
-CallModuleResolveHook(JSContext* cx, HandleObject module, HandleString specifier)
+CallModuleResolveHook(JSContext* cx, HandleValue referencingPrivate, HandleString specifier)
{
ShellContext* sc = GetShellContext(cx);
JS::AutoValueArray<2> args(cx);
- args[0].setObject(*module);
+ args[0].set(referencingPrivate);
args[1].setString(specifier);
RootedValue result(cx);
@@ -4060,6 +4060,53 @@ CallModuleResolveHook(JSContext* cx, HandleObject module, HandleString specifier
}
static bool
+ReportArgumentTypeError(JSContext* cx, HandleValue value, const char* expected)
+{
+ const char* typeName = InformalValueTypeName(value);
+ JS_ReportErrorASCII(cx, "Expected %s, got %s", expected, typeName);
+ return false;
+}
+
+static bool
+ShellSetModulePrivate(JSContext* cx, unsigned argc, Value* vp)
+{
+ CallArgs args = CallArgsFromVp(argc, vp);
+
+ if (args.length() != 2) {
+ JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_MORE_ARGS_NEEDED,
+ "setModulePrivate", "0", "s");
+ return false;
+ }
+
+ if (!args[0].isObject() || !args[0].toObject().is<ModuleObject>()) {
+ return ReportArgumentTypeError(cx, args[0], "module object");
+ }
+
+ JS::SetModulePrivate(&args[0].toObject(), args[1]);
+ args.rval().setUndefined();
+ return true;
+}
+
+static bool
+ShellGetModulePrivate(JSContext* cx, unsigned argc, Value* vp)
+{
+ CallArgs args = CallArgsFromVp(argc, vp);
+
+ if (args.length() != 1) {
+ JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_MORE_ARGS_NEEDED,
+ "getModulePrivate", "0", "s");
+ return false;
+ }
+
+ if (!args[0].isObject() || !args[0].toObject().is<ModuleObject>()) {
+ return ReportArgumentTypeError(cx, args[0], "module object");
+ }
+
+ args.rval().set(JS::GetModulePrivate(&args[0].toObject()));
+ return true;
+}
+
+static bool
GetModuleLoadPath(JSContext* cx, unsigned argc, Value* vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
@@ -5927,6 +5974,14 @@ static const JSFunctionSpecWithHelp shell_functions[] = {
" This hook is used to look up a previously loaded module object. It should\n"
" be implemented by the module loader."),
+ JS_FN_HELP("setModulePrivate", ShellSetModulePrivate, 2, 0,
+"setModulePrivate(scriptObject, privateValue)",
+" Associate a private value with a module object.\n"),
+
+ JS_FN_HELP("getModulePrivate", ShellGetModulePrivate, 2, 0,
+"getModulePrivate(scriptObject)",
+" Get the private value associated with a module object.\n"),
+
JS_FN_HELP("getModuleLoadPath", GetModuleLoadPath, 0, 0,
"getModuleLoadPath()",
" Return any --module-load-path argument passed to the shell. Used by the\n"
diff --git a/js/src/vm/SelfHosting.cpp b/js/src/vm/SelfHosting.cpp
index dc1dfb9fad..781ddcf16e 100644
--- a/js/src/vm/SelfHosting.cpp
+++ b/js/src/vm/SelfHosting.cpp
@@ -2035,7 +2035,8 @@ intrinsic_HostResolveImportedModule(JSContext* cx, unsigned argc, Value* vp)
}
RootedObject result(cx);
- result = moduleResolveHook(cx, module, specifier);
+ RootedValue referencingPrivate(cx, JS::GetModulePrivate(module));
+ result = moduleResolveHook(cx, referencingPrivate, specifier);
if (!result)
return false;