diff options
Diffstat (limited to 'js/src/builtin/ModuleObject.cpp')
-rw-r--r-- | js/src/builtin/ModuleObject.cpp | 102 |
1 files changed, 102 insertions, 0 deletions
diff --git a/js/src/builtin/ModuleObject.cpp b/js/src/builtin/ModuleObject.cpp index 760fb9c04d..e40ba110b8 100644 --- a/js/src/builtin/ModuleObject.cpp +++ b/js/src/builtin/ModuleObject.cpp @@ -5,6 +5,7 @@ #include "builtin/ModuleObject.h" +#include "builtin/Promise.h" #include "builtin/SelfHostingDefines.h" #include "frontend/ParseNode.h" #include "frontend/SharedContext.h" @@ -1030,6 +1031,22 @@ ModuleObject::Evaluate(JSContext* cx, HandleModuleObject self) return InvokeSelfHostedMethod(cx, self, cx->names().ModuleEvaluate); } +/* static */ ModuleNamespaceObject* +ModuleObject::GetOrCreateModuleNamespace(JSContext* cx, HandleModuleObject self) +{ + FixedInvokeArgs<1> args(cx); + args[0].setObject(*self); + + RootedValue result(cx); + if (!CallSelfHostedFunction(cx, cx->names().GetModuleNamespace, UndefinedHandleValue, args, + &result)) + { + return nullptr; + } + + return &result.toObject().as<ModuleNamespaceObject>(); +} + DEFINE_GETTER_FUNCTIONS(ModuleObject, namespace_, NamespaceSlot) DEFINE_GETTER_FUNCTIONS(ModuleObject, status, StatusSlot) DEFINE_GETTER_FUNCTIONS(ModuleObject, evaluationError, EvaluationErrorSlot) @@ -1519,3 +1536,88 @@ js::GetOrCreateModuleMetaObject(JSContext* cx, HandleObject moduleArg) return metaObject; } + +JSObject* +js::CallModuleResolveHook(JSContext* cx, HandleValue referencingPrivate, HandleString specifier) +{ + JS::ModuleResolveHook moduleResolveHook = cx->runtime()->moduleResolveHook; + if (!moduleResolveHook) { + JS_ReportErrorASCII(cx, "Module resolve hook not set"); + return nullptr; + } + + RootedObject result(cx, moduleResolveHook(cx, referencingPrivate, specifier)); + if (!result) { + return nullptr; + } + + if (!result->is<ModuleObject>()) { + JS_ReportErrorASCII(cx, "Module resolve hook did not return Module object"); + return nullptr; + } + + return result; +} + +JSObject* +js::StartDynamicModuleImport(JSContext* cx, HandleValue referencingPrivate, HandleValue specifierArg) +{ + RootedObject promiseConstructor(cx, JS::GetPromiseConstructor(cx)); + if (!promiseConstructor) { + return nullptr; + } + + RootedObject promiseObject(cx, JS::NewPromiseObject(cx, nullptr)); + if (!promiseObject) { + return nullptr; + } + + Handle<PromiseObject*> promise = promiseObject.as<PromiseObject>(); + + RootedString specifier(cx, ToString(cx, specifierArg)); + if (!specifier) { + if (!RejectPromiseWithPendingError(cx, promise)) + return nullptr; + return promise; + } + + JS::ModuleDynamicImportHook importHook = cx->runtime()->moduleDynamicImportHook; + MOZ_ASSERT(importHook); + if (!importHook(cx, referencingPrivate, specifier, promise)) { + if (!RejectPromiseWithPendingError(cx, promise)) + return nullptr; + return promise; + } + + return promise; +} + +bool +js::FinishDynamicModuleImport(JSContext* cx, HandleValue referencingPrivate, HandleString specifier, + HandleObject promiseArg) +{ + Handle<PromiseObject*> promise = promiseArg.as<PromiseObject>(); + + if (cx->isExceptionPending()) { + return RejectPromiseWithPendingError(cx, promise); + } + + RootedObject result(cx, CallModuleResolveHook(cx, referencingPrivate, specifier)); + if (!result) { + return RejectPromiseWithPendingError(cx, promise); + } + + RootedModuleObject module(cx, &result->as<ModuleObject>()); + if (module->status() != MODULE_STATUS_EVALUATED) { + JS_ReportErrorASCII(cx, "Unevaluated or errored module returned by module resolve hook"); + return RejectPromiseWithPendingError(cx, promise); + } + + RootedObject ns(cx, ModuleObject::GetOrCreateModuleNamespace(cx, module)); + if (!ns) { + return RejectPromiseWithPendingError(cx, promise); + } + + RootedValue value(cx, ObjectValue(*ns)); + return PromiseObject::resolve(cx, promise, value); +} |