mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-10-03 22:07:30 +09:00
Issue #1691 - Part 1: Provide a way of associating a private value with a script or module.
This is a prerequisite for dynamic import (cherry picked from commit 2e2972647ee29340df51a804f05e40fc1da2c89b)
This commit is contained in:
parent
d75c6c1815
commit
1a6b3a822c
10 changed files with 129 additions and 43 deletions
|
|
@ -58,9 +58,9 @@ ModuleScript::UnlinkModuleRecord()
|
||||||
{
|
{
|
||||||
// Remove module's back reference to this object request if present.
|
// Remove module's back reference to this object request if present.
|
||||||
if (mModuleRecord) {
|
if (mModuleRecord) {
|
||||||
MOZ_ASSERT(JS::GetModuleHostDefinedField(mModuleRecord).toPrivate() ==
|
MOZ_ASSERT(JS::GetModulePrivate(mModuleRecord).toPrivate() ==
|
||||||
this);
|
this);
|
||||||
JS::SetModuleHostDefinedField(mModuleRecord, JS::UndefinedValue());
|
JS::SetModulePrivate(mModuleRecord, JS::UndefinedValue());
|
||||||
mModuleRecord = nullptr;
|
mModuleRecord = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -83,7 +83,7 @@ ModuleScript::SetModuleRecord(JS::Handle<JSObject*> aModuleRecord)
|
||||||
|
|
||||||
// Make module's host defined field point to this module script object.
|
// Make module's host defined field point to this module script object.
|
||||||
// This is cleared in the UnlinkModuleRecord().
|
// This is cleared in the UnlinkModuleRecord().
|
||||||
JS::SetModuleHostDefinedField(mModuleRecord, JS::PrivateValue(this));
|
JS::SetModulePrivate(mModuleRecord, JS::PrivateValue(this));
|
||||||
HoldJSObjects(this);
|
HoldJSObjects(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -798,13 +798,13 @@ ScriptLoader::StartFetchingModuleAndDependencies(ModuleLoadRequest* aParent,
|
||||||
|
|
||||||
// 8.1.3.8.1 HostResolveImportedModule(referencingModule, specifier)
|
// 8.1.3.8.1 HostResolveImportedModule(referencingModule, specifier)
|
||||||
JSObject*
|
JSObject*
|
||||||
HostResolveImportedModule(JSContext* aCx, JS::Handle<JSObject*> aModule,
|
HostResolveImportedModule(JSContext* aCx,
|
||||||
|
JS::Handle<JS::Value> aReferencingPrivate,
|
||||||
JS::Handle<JSString*> aSpecifier)
|
JS::Handle<JSString*> aSpecifier)
|
||||||
{
|
{
|
||||||
// Let referencing module script be referencingModule.[[HostDefined]].
|
// Let referencing module script be referencingModule.[[HostDefined]].
|
||||||
JS::Value value = JS::GetModuleHostDefinedField(aModule);
|
auto script = static_cast<ModuleScript*>(aReferencingPrivate.toPrivate());
|
||||||
auto script = static_cast<ModuleScript*>(value.toPrivate());
|
MOZ_ASSERT(JS::GetModulePrivate(script->ModuleRecord()) == aReferencingPrivate);
|
||||||
MOZ_ASSERT(script->ModuleRecord() == aModule);
|
|
||||||
|
|
||||||
// Let url be the result of resolving a module specifier given referencing
|
// Let url be the result of resolving a module specifier given referencing
|
||||||
// module script and specifier.
|
// module script and specifier.
|
||||||
|
|
|
||||||
|
|
@ -630,8 +630,9 @@ private:
|
||||||
ModuleScript* GetFetchedModule(nsIURI* aURL) const;
|
ModuleScript* GetFetchedModule(nsIURI* aURL) const;
|
||||||
|
|
||||||
friend JSObject*
|
friend JSObject*
|
||||||
HostResolveImportedModule(JSContext* aCx, JS::Handle<JSObject*> aModule,
|
HostResolveImportedModule(JSContext* aCx,
|
||||||
JS::Handle<JSString*> aSpecifier);
|
JS::Handle<JS::Value> aReferencingPrivate,
|
||||||
|
JS::Handle<JSString*> aSpecifier);
|
||||||
|
|
||||||
nsresult CreateModuleScript(ModuleLoadRequest* aRequest);
|
nsresult CreateModuleScript(ModuleLoadRequest* aRequest);
|
||||||
nsresult ProcessFetchedModuleSource(ModuleLoadRequest* aRequest);
|
nsresult ProcessFetchedModuleSource(ModuleLoadRequest* aRequest);
|
||||||
|
|
|
||||||
|
|
@ -725,6 +725,12 @@ ModuleObject::namespace_()
|
||||||
return &value.toObject().as<ModuleNamespaceObject>();
|
return &value.toObject().as<ModuleNamespaceObject>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ScriptSourceObject*
|
||||||
|
ModuleObject::scriptSourceObject() const
|
||||||
|
{
|
||||||
|
return &getReservedSlot(ScriptSourceObjectSlot).toObject().as<ScriptSourceObject>();
|
||||||
|
}
|
||||||
|
|
||||||
FunctionDeclarationVector*
|
FunctionDeclarationVector*
|
||||||
ModuleObject::functionDeclarations()
|
ModuleObject::functionDeclarations()
|
||||||
{
|
{
|
||||||
|
|
@ -738,8 +744,10 @@ ModuleObject::functionDeclarations()
|
||||||
void
|
void
|
||||||
ModuleObject::init(HandleScript script)
|
ModuleObject::init(HandleScript script)
|
||||||
{
|
{
|
||||||
|
MOZ_ASSERT(script);
|
||||||
initReservedSlot(ScriptSlot, PrivateValue(script));
|
initReservedSlot(ScriptSlot, PrivateValue(script));
|
||||||
initReservedSlot(StatusSlot, Int32Value(MODULE_STATUS_UNINSTANTIATED));
|
initReservedSlot(StatusSlot, Int32Value(MODULE_STATUS_UNINSTANTIATED));
|
||||||
|
initReservedSlot(ScriptSourceObjectSlot, ObjectValue(script->scriptSourceUnwrap()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -868,18 +876,6 @@ ModuleObject::evaluationError() const
|
||||||
return getReservedSlot(EvaluationErrorSlot);
|
return getReservedSlot(EvaluationErrorSlot);
|
||||||
}
|
}
|
||||||
|
|
||||||
Value
|
|
||||||
ModuleObject::hostDefinedField() const
|
|
||||||
{
|
|
||||||
return getReservedSlot(HostDefinedSlot);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
ModuleObject::setHostDefinedField(const JS::Value& value)
|
|
||||||
{
|
|
||||||
setReservedSlot(HostDefinedSlot, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
Scope*
|
Scope*
|
||||||
ModuleObject::enclosingScope() const
|
ModuleObject::enclosingScope() const
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -221,7 +221,7 @@ class ModuleObject : public NativeObject
|
||||||
NamespaceSlot,
|
NamespaceSlot,
|
||||||
StatusSlot,
|
StatusSlot,
|
||||||
EvaluationErrorSlot,
|
EvaluationErrorSlot,
|
||||||
HostDefinedSlot,
|
ScriptSourceObjectSlot,
|
||||||
RequestedModulesSlot,
|
RequestedModulesSlot,
|
||||||
ImportEntriesSlot,
|
ImportEntriesSlot,
|
||||||
LocalExportEntriesSlot,
|
LocalExportEntriesSlot,
|
||||||
|
|
@ -273,7 +273,7 @@ class ModuleObject : public NativeObject
|
||||||
ModuleStatus status() const;
|
ModuleStatus status() const;
|
||||||
bool hadEvaluationError() const;
|
bool hadEvaluationError() const;
|
||||||
Value evaluationError() const;
|
Value evaluationError() const;
|
||||||
Value hostDefinedField() const;
|
ScriptSourceObject* scriptSourceObject() const;
|
||||||
ArrayObject& requestedModules() const;
|
ArrayObject& requestedModules() const;
|
||||||
ArrayObject& importEntries() const;
|
ArrayObject& importEntries() const;
|
||||||
ArrayObject& localExportEntries() const;
|
ArrayObject& localExportEntries() const;
|
||||||
|
|
@ -286,8 +286,6 @@ class ModuleObject : public NativeObject
|
||||||
static bool Instantiate(JSContext* cx, HandleModuleObject self);
|
static bool Instantiate(JSContext* cx, HandleModuleObject self);
|
||||||
static bool Evaluate(JSContext* cx, HandleModuleObject self);
|
static bool Evaluate(JSContext* cx, HandleModuleObject self);
|
||||||
|
|
||||||
void setHostDefinedField(const JS::Value& value);
|
|
||||||
|
|
||||||
// For BytecodeEmitter.
|
// For BytecodeEmitter.
|
||||||
bool noteFunctionDeclaration(ExclusiveContext* cx, HandleAtom name, HandleFunction fun);
|
bool noteFunctionDeclaration(ExclusiveContext* cx, HandleAtom name, HandleFunction fun);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4710,15 +4710,27 @@ JS::CompileModule(JSContext* cx, const ReadOnlyCompileOptions& options,
|
||||||
}
|
}
|
||||||
|
|
||||||
JS_PUBLIC_API(void)
|
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_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)
|
JS_PUBLIC_API(bool)
|
||||||
|
|
|
||||||
|
|
@ -4324,7 +4324,7 @@ extern JS_PUBLIC_API(bool)
|
||||||
Evaluate(JSContext* cx, const ReadOnlyCompileOptions& options,
|
Evaluate(JSContext* cx, const ReadOnlyCompileOptions& options,
|
||||||
const char* filename, JS::MutableHandleValue rval);
|
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.
|
* Get the HostResolveImportedModule hook for the runtime.
|
||||||
|
|
@ -4347,17 +4347,30 @@ CompileModule(JSContext* cx, const ReadOnlyCompileOptions& options,
|
||||||
SourceBufferHolder& srcBuf, JS::MutableHandleObject moduleRecord);
|
SourceBufferHolder& srcBuf, JS::MutableHandleObject moduleRecord);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the [[HostDefined]] field of a source text module record to the given
|
* Set a private value associated with a source text module record.
|
||||||
* value.
|
|
||||||
*/
|
*/
|
||||||
extern JS_PUBLIC_API(void)
|
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)
|
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
|
* Perform the ModuleInstantiate operation on the given source text module
|
||||||
|
|
|
||||||
|
|
@ -638,12 +638,22 @@ class ScriptSourceObject : public NativeObject
|
||||||
return static_cast<JSScript*>(untyped);
|
return static_cast<JSScript*>(untyped);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setPrivate(const Value& value) {
|
||||||
|
setReservedSlot(PRIVATE_SLOT, value);
|
||||||
|
}
|
||||||
|
Value getPrivate() const {
|
||||||
|
return getReservedSlot(PRIVATE_SLOT);
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static const uint32_t SOURCE_SLOT = 0;
|
enum {
|
||||||
static const uint32_t ELEMENT_SLOT = 1;
|
SOURCE_SLOT = 0,
|
||||||
static const uint32_t ELEMENT_PROPERTY_SLOT = 2;
|
ELEMENT_SLOT,
|
||||||
static const uint32_t INTRODUCTION_SCRIPT_SLOT = 3;
|
ELEMENT_PROPERTY_SLOT,
|
||||||
static const uint32_t RESERVED_SLOTS = 4;
|
INTRODUCTION_SCRIPT_SLOT,
|
||||||
|
PRIVATE_SLOT,
|
||||||
|
RESERVED_SLOTS
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
enum GeneratorKind { NotGenerator, LegacyGenerator, StarGenerator };
|
enum GeneratorKind { NotGenerator, LegacyGenerator, StarGenerator };
|
||||||
|
|
|
||||||
|
|
@ -4035,12 +4035,12 @@ SetModuleResolveHook(JSContext* cx, unsigned argc, Value* vp)
|
||||||
}
|
}
|
||||||
|
|
||||||
static JSObject*
|
static JSObject*
|
||||||
CallModuleResolveHook(JSContext* cx, HandleObject module, HandleString specifier)
|
CallModuleResolveHook(JSContext* cx, HandleValue referencingPrivate, HandleString specifier)
|
||||||
{
|
{
|
||||||
ShellContext* sc = GetShellContext(cx);
|
ShellContext* sc = GetShellContext(cx);
|
||||||
|
|
||||||
JS::AutoValueArray<2> args(cx);
|
JS::AutoValueArray<2> args(cx);
|
||||||
args[0].setObject(*module);
|
args[0].set(referencingPrivate);
|
||||||
args[1].setString(specifier);
|
args[1].setString(specifier);
|
||||||
|
|
||||||
RootedValue result(cx);
|
RootedValue result(cx);
|
||||||
|
|
@ -4055,6 +4055,53 @@ CallModuleResolveHook(JSContext* cx, HandleObject module, HandleString specifier
|
||||||
return &result.toObject();
|
return &result.toObject();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
static bool
|
||||||
GetModuleLoadPath(JSContext* cx, unsigned argc, Value* vp)
|
GetModuleLoadPath(JSContext* cx, unsigned argc, Value* vp)
|
||||||
{
|
{
|
||||||
|
|
@ -5923,6 +5970,14 @@ static const JSFunctionSpecWithHelp shell_functions[] = {
|
||||||
" This hook is used to look up a previously loaded module object. It should\n"
|
" This hook is used to look up a previously loaded module object. It should\n"
|
||||||
" be implemented by the module loader."),
|
" 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,
|
JS_FN_HELP("getModuleLoadPath", GetModuleLoadPath, 0, 0,
|
||||||
"getModuleLoadPath()",
|
"getModuleLoadPath()",
|
||||||
" Return any --module-load-path argument passed to the shell. Used by the\n"
|
" Return any --module-load-path argument passed to the shell. Used by the\n"
|
||||||
|
|
|
||||||
|
|
@ -2006,7 +2006,8 @@ intrinsic_HostResolveImportedModule(JSContext* cx, unsigned argc, Value* vp)
|
||||||
}
|
}
|
||||||
|
|
||||||
RootedObject result(cx);
|
RootedObject result(cx);
|
||||||
result = moduleResolveHook(cx, module, specifier);
|
RootedValue referencingPrivate(cx, JS::GetModulePrivate(module));
|
||||||
|
result = moduleResolveHook(cx, referencingPrivate, specifier);
|
||||||
if (!result)
|
if (!result)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue