mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-15 06:15:43 +00:00
Bug 1461751 - Simplify module resolve hook to be a function pointer r=luke r=baku
This commit is contained in:
parent
3ef72562fe
commit
65b2944794
@ -769,25 +769,20 @@ ScriptLoader::StartFetchingModuleAndDependencies(ModuleLoadRequest* aParent,
|
||||
}
|
||||
|
||||
// 8.1.3.8.1 HostResolveImportedModule(referencingModule, specifier)
|
||||
bool
|
||||
HostResolveImportedModule(JSContext* aCx, unsigned argc, JS::Value* vp)
|
||||
JSObject*
|
||||
HostResolveImportedModule(JSContext* aCx, JS::Handle<JSObject*> aModule,
|
||||
JS::Handle<JSString*> aSpecifier)
|
||||
{
|
||||
|
||||
MOZ_ASSERT(argc == 2);
|
||||
JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
|
||||
JS::Rooted<JSObject*> module(aCx, &args[0].toObject());
|
||||
JS::Rooted<JSString*> specifier(aCx, args[1].toString());
|
||||
|
||||
// Let referencing module script be referencingModule.[[HostDefined]].
|
||||
JS::Value value = JS::GetModuleHostDefinedField(module);
|
||||
JS::Value value = JS::GetModuleHostDefinedField(aModule);
|
||||
auto script = static_cast<ModuleScript*>(value.toPrivate());
|
||||
MOZ_ASSERT(script->ModuleRecord() == module);
|
||||
MOZ_ASSERT(script->ModuleRecord() == aModule);
|
||||
|
||||
// Let url be the result of resolving a module specifier given referencing
|
||||
// module script and specifier.
|
||||
nsAutoJSString string;
|
||||
if (!string.init(aCx, specifier)) {
|
||||
return false;
|
||||
if (!string.init(aCx, aSpecifier)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIURI> uri = ResolveModuleSpecifier(script, string);
|
||||
@ -802,27 +797,20 @@ HostResolveImportedModule(JSContext* aCx, unsigned argc, JS::Value* vp)
|
||||
MOZ_ASSERT(ms, "Resolved module not found in module map");
|
||||
|
||||
MOZ_ASSERT(!ms->HasParseError());
|
||||
MOZ_ASSERT(ms->ModuleRecord());
|
||||
|
||||
*vp = JS::ObjectValue(*ms->ModuleRecord());
|
||||
return true;
|
||||
return ms->ModuleRecord();
|
||||
}
|
||||
|
||||
static nsresult
|
||||
static void
|
||||
EnsureModuleResolveHook(JSContext* aCx)
|
||||
{
|
||||
if (JS::GetModuleResolveHook(aCx)) {
|
||||
return NS_OK;
|
||||
JSRuntime* rt = JS_GetRuntime(aCx);
|
||||
if (JS::GetModuleResolveHook(rt)) {
|
||||
return;
|
||||
}
|
||||
|
||||
JS::Rooted<JSFunction*> func(aCx);
|
||||
func = JS_NewFunction(aCx, HostResolveImportedModule, 2, 0,
|
||||
"HostResolveImportedModule");
|
||||
if (!func) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
JS::SetModuleResolveHook(aCx, func);
|
||||
return NS_OK;
|
||||
JS::SetModuleResolveHook(rt, HostResolveImportedModule);
|
||||
}
|
||||
|
||||
void
|
||||
@ -944,8 +932,7 @@ ScriptLoader::InstantiateModuleTree(ModuleLoadRequest* aRequest)
|
||||
return false;
|
||||
}
|
||||
|
||||
nsresult rv = EnsureModuleResolveHook(jsapi.cx());
|
||||
NS_ENSURE_SUCCESS(rv, false);
|
||||
EnsureModuleResolveHook(jsapi.cx());
|
||||
|
||||
JS::Rooted<JSObject*> module(jsapi.cx(), moduleScript->ModuleRecord());
|
||||
bool ok = NS_SUCCEEDED(nsJSUtils::ModuleInstantiate(jsapi.cx(), module));
|
||||
@ -2231,8 +2218,7 @@ ScriptLoader::EvaluateScript(ScriptLoadRequest* aRequest)
|
||||
// currentScript is set to null for modules.
|
||||
AutoCurrentScriptUpdater scriptUpdater(this, nullptr);
|
||||
|
||||
rv = EnsureModuleResolveHook(cx);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
EnsureModuleResolveHook(cx);
|
||||
|
||||
ModuleLoadRequest* request = aRequest->AsModuleRequest();
|
||||
MOZ_ASSERT(request->mModuleScript);
|
||||
|
@ -505,8 +505,9 @@ private:
|
||||
RefPtr<mozilla::GenericPromise> WaitForModuleFetch(nsIURI* aURL);
|
||||
ModuleScript* GetFetchedModule(nsIURI* aURL) const;
|
||||
|
||||
friend bool
|
||||
HostResolveImportedModule(JSContext* aCx, unsigned argc, JS::Value* vp);
|
||||
friend JSObject*
|
||||
HostResolveImportedModule(JSContext* aCx, JS::Handle<JSObject*> aModule,
|
||||
JS::Handle<JSString*> aSpecifier);
|
||||
|
||||
// Returns wether we should save the bytecode of this script after the
|
||||
// execution of the script.
|
||||
|
@ -838,7 +838,7 @@ static const uint32_t JSCLASS_FOREGROUND_FINALIZE = 1 << (JSCLASS_HIGH_FLAGS
|
||||
// application.
|
||||
static const uint32_t JSCLASS_GLOBAL_APPLICATION_SLOTS = 5;
|
||||
static const uint32_t JSCLASS_GLOBAL_SLOT_COUNT =
|
||||
JSCLASS_GLOBAL_APPLICATION_SLOTS + JSProto_LIMIT * 2 + 37;
|
||||
JSCLASS_GLOBAL_APPLICATION_SLOTS + JSProto_LIMIT * 2 + 36;
|
||||
|
||||
#define JSCLASS_GLOBAL_FLAGS_WITH_SLOTS(n) \
|
||||
(JSCLASS_IS_GLOBAL | JSCLASS_HAS_RESERVED_SLOTS(JSCLASS_GLOBAL_SLOT_COUNT + (n)))
|
||||
|
@ -4939,21 +4939,18 @@ JS::Evaluate(JSContext* cx, const ReadOnlyCompileOptions& optionsArg,
|
||||
return ::Evaluate(cx, optionsArg, filename, rval);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSFunction*)
|
||||
JS::GetModuleResolveHook(JSContext* cx)
|
||||
JS_PUBLIC_API(JS::ModuleResolveHook)
|
||||
JS::GetModuleResolveHook(JSRuntime* rt)
|
||||
{
|
||||
AssertHeapIsIdle();
|
||||
CHECK_REQUEST(cx);
|
||||
return cx->global()->moduleResolveHook();
|
||||
return rt->moduleResolveHook;
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(void)
|
||||
JS::SetModuleResolveHook(JSContext* cx, HandleFunction func)
|
||||
JS::SetModuleResolveHook(JSRuntime* rt, JS::ModuleResolveHook func)
|
||||
{
|
||||
AssertHeapIsIdle();
|
||||
CHECK_REQUEST(cx);
|
||||
assertSameCompartment(cx, func);
|
||||
cx->global()->setModuleResolveHook(func);
|
||||
rt->moduleResolveHook = func;
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(bool)
|
||||
|
@ -4141,17 +4141,19 @@ extern JS_PUBLIC_API(bool)
|
||||
Evaluate(JSContext* cx, const ReadOnlyCompileOptions& options,
|
||||
const char* filename, JS::MutableHandleValue rval);
|
||||
|
||||
/**
|
||||
* Get the HostResolveImportedModule hook for a global.
|
||||
*/
|
||||
extern JS_PUBLIC_API(JSFunction*)
|
||||
GetModuleResolveHook(JSContext* cx);
|
||||
using ModuleResolveHook = JSObject* (*)(JSContext*, HandleObject, HandleString);
|
||||
|
||||
/**
|
||||
* Set the HostResolveImportedModule hook for a global to the given function.
|
||||
* Get the HostResolveImportedModule hook for the runtime.
|
||||
*/
|
||||
extern JS_PUBLIC_API(ModuleResolveHook)
|
||||
GetModuleResolveHook(JSRuntime* rt);
|
||||
|
||||
/**
|
||||
* Set the HostResolveImportedModule hook for the runtime to the given function.
|
||||
*/
|
||||
extern JS_PUBLIC_API(void)
|
||||
SetModuleResolveHook(JSContext* cx, JS::HandleFunction func);
|
||||
SetModuleResolveHook(JSRuntime* rt, ModuleResolveHook func);
|
||||
|
||||
/**
|
||||
* Parse the given source buffer as a module in the scope of the current global
|
||||
|
@ -610,7 +610,8 @@ ShellContext::ShellContext(JSContext* cx)
|
||||
readLineBufPos(0),
|
||||
errFilePtr(nullptr),
|
||||
outFilePtr(nullptr),
|
||||
offThreadMonitor(mutexid::ShellOffThreadState)
|
||||
offThreadMonitor(mutexid::ShellOffThreadState),
|
||||
moduleResolveHook(cx)
|
||||
{}
|
||||
|
||||
ShellContext::~ShellContext()
|
||||
@ -868,6 +869,7 @@ RunBinAST(JSContext* cx, const char* filename, FILE* file)
|
||||
static bool
|
||||
InitModuleLoader(JSContext* cx)
|
||||
{
|
||||
|
||||
// Decompress and evaluate the embedded module loader source to initialize
|
||||
// the module loader for the current compartment.
|
||||
|
||||
@ -4280,13 +4282,34 @@ SetModuleResolveHook(JSContext* cx, unsigned argc, Value* vp)
|
||||
return false;
|
||||
}
|
||||
|
||||
RootedFunction hook(cx, &args[0].toObject().as<JSFunction>());
|
||||
Rooted<GlobalObject*> global(cx, cx->global());
|
||||
global->setModuleResolveHook(hook);
|
||||
ShellContext* sc = GetShellContext(cx);
|
||||
sc->moduleResolveHook = &args[0].toObject().as<JSFunction>();
|
||||
|
||||
args.rval().setUndefined();
|
||||
return true;
|
||||
}
|
||||
|
||||
static JSObject*
|
||||
CallModuleResolveHook(JSContext* cx, HandleObject module, HandleString specifier)
|
||||
{
|
||||
ShellContext* sc = GetShellContext(cx);
|
||||
|
||||
JS::AutoValueArray<2> args(cx);
|
||||
args[0].setObject(*module);
|
||||
args[1].setString(specifier);
|
||||
|
||||
RootedValue result(cx);
|
||||
if (!JS_CallFunction(cx, nullptr, sc->moduleResolveHook, args, &result))
|
||||
return nullptr;
|
||||
|
||||
if (!result.isObject() || !result.toObject().is<ModuleObject>()) {
|
||||
JS_ReportErrorASCII(cx, "Module resolve hook did not return Module object");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return &result.toObject();
|
||||
}
|
||||
|
||||
static bool
|
||||
GetModuleLoadPath(JSContext* cx, unsigned argc, Value* vp)
|
||||
{
|
||||
@ -9298,6 +9321,8 @@ main(int argc, char** argv, char** envp)
|
||||
|
||||
js::SetPreserveWrapperCallback(cx, DummyPreserveWrapperCallback);
|
||||
|
||||
JS::SetModuleResolveHook(cx->runtime(), CallModuleResolveHook);
|
||||
|
||||
result = Shell(cx, &op, envp);
|
||||
|
||||
#ifdef DEBUG
|
||||
|
@ -181,6 +181,7 @@ struct ShellContext
|
||||
js::Monitor offThreadMonitor;
|
||||
Vector<OffThreadJob*, 0, SystemAllocPolicy> offThreadJobs;
|
||||
|
||||
JS::PersistentRootedFunction moduleResolveHook;
|
||||
};
|
||||
|
||||
extern ShellContext*
|
||||
|
@ -105,7 +105,6 @@ class GlobalObject : public NativeObject
|
||||
DEBUGGERS,
|
||||
INTRINSICS,
|
||||
FOR_OF_PIC_CHAIN,
|
||||
MODULE_RESOLVE_HOOK,
|
||||
WINDOW_PROXY,
|
||||
|
||||
/* Total reserved-slot count for global objects. */
|
||||
@ -821,19 +820,6 @@ class GlobalObject : public NativeObject
|
||||
setReservedSlot(WINDOW_PROXY, ObjectValue(*windowProxy));
|
||||
}
|
||||
|
||||
void setModuleResolveHook(HandleFunction hook) {
|
||||
MOZ_ASSERT(hook);
|
||||
setSlot(MODULE_RESOLVE_HOOK, ObjectValue(*hook));
|
||||
}
|
||||
|
||||
JSFunction* moduleResolveHook() {
|
||||
Value value = getSlotRef(MODULE_RESOLVE_HOOK);
|
||||
if (value.isUndefined())
|
||||
return nullptr;
|
||||
|
||||
return &value.toObject().as<JSFunction>();
|
||||
}
|
||||
|
||||
// A class used in place of a prototype during off-thread parsing.
|
||||
struct OffThreadPlaceholderObject : public NativeObject
|
||||
{
|
||||
|
@ -174,7 +174,8 @@ JSRuntime::JSRuntime(JSRuntime* parentRuntime)
|
||||
performanceMonitoring_(),
|
||||
stackFormat_(parentRuntime ? js::StackFormat::Default
|
||||
: js::StackFormat::SpiderMonkey),
|
||||
wasmInstances(mutexid::WasmRuntimeInstances)
|
||||
wasmInstances(mutexid::WasmRuntimeInstances),
|
||||
moduleResolveHook()
|
||||
{
|
||||
JS_COUNT_CTOR(JSRuntime);
|
||||
liveRuntimesCount++;
|
||||
|
@ -937,6 +937,9 @@ struct JSRuntime : public js::MallocProvider<JSRuntime>
|
||||
// threads for purposes of wasm::InterruptRunningCode().
|
||||
js::ExclusiveData<js::wasm::InstanceVector> wasmInstances;
|
||||
|
||||
// The implementation-defined abstract operation HostResolveImportedModule.
|
||||
js::MainThreadData<JS::ModuleResolveHook> moduleResolveHook;
|
||||
|
||||
public:
|
||||
#if defined(JS_BUILD_BINAST)
|
||||
js::BinaryASTSupport& binast() {
|
||||
|
@ -2146,25 +2146,26 @@ intrinsic_HostResolveImportedModule(JSContext* cx, unsigned argc, Value* vp)
|
||||
{
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
MOZ_ASSERT(args.length() == 2);
|
||||
MOZ_ASSERT(args[0].toObject().is<ModuleObject>());
|
||||
MOZ_ASSERT(args[1].isString());
|
||||
RootedModuleObject module(cx, &args[0].toObject().as<ModuleObject>());
|
||||
RootedString specifier(cx, args[1].toString());
|
||||
|
||||
RootedFunction moduleResolveHook(cx, cx->global()->moduleResolveHook());
|
||||
JS::ModuleResolveHook moduleResolveHook = cx->runtime()->moduleResolveHook;
|
||||
if (!moduleResolveHook) {
|
||||
JS_ReportErrorASCII(cx, "Module resolve hook not set");
|
||||
return false;
|
||||
}
|
||||
|
||||
RootedValue result(cx);
|
||||
if (!JS_CallFunction(cx, nullptr, moduleResolveHook, args, &result))
|
||||
RootedObject result(cx);
|
||||
result = moduleResolveHook(cx, module, specifier);
|
||||
if (!result)
|
||||
return false;
|
||||
|
||||
if (!result.isObject() || !result.toObject().is<ModuleObject>()) {
|
||||
if (!result->is<ModuleObject>()) {
|
||||
JS_ReportErrorASCII(cx, "Module resolve hook did not return Module object");
|
||||
return false;
|
||||
}
|
||||
|
||||
args.rval().set(result);
|
||||
args.rval().setObject(*result);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user