diff options
author | Brian Smith <brian@dbsoft.org> | 2023-04-09 03:06:39 -0500 |
---|---|---|
committer | Brian Smith <brian@dbsoft.org> | 2023-04-27 13:33:00 -0500 |
commit | 130d9f4d91f666f6bd44a3e227808030225ef56b (patch) | |
tree | 548674f5366dc49ec7f784b82b4ae9861a4fc672 /js/src/builtin | |
parent | 6eecfad57c57c4c305149d1f5634628e80b0cca6 (diff) | |
download | uxp-130d9f4d91f666f6bd44a3e227808030225ef56b.tar.gz |
Issue #1691 - Part 4: Finish implementing call import.
https://bugzilla.mozilla.org/show_bug.cgi?id=1499140
(cherry picked from commit 7bf7d64887944b127a72090dd62eb57f67c5089d)
Diffstat (limited to 'js/src/builtin')
-rw-r--r-- | js/src/builtin/ModuleObject.cpp | 102 | ||||
-rw-r--r-- | js/src/builtin/ModuleObject.h | 13 | ||||
-rw-r--r-- | js/src/builtin/Promise.cpp | 10 | ||||
-rw-r--r-- | js/src/builtin/Promise.h | 3 |
4 files changed, 128 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); +} diff --git a/js/src/builtin/ModuleObject.h b/js/src/builtin/ModuleObject.h index dfd76ee847..aaeeb2faaa 100644 --- a/js/src/builtin/ModuleObject.h +++ b/js/src/builtin/ModuleObject.h @@ -288,6 +288,9 @@ class ModuleObject : public NativeObject static bool Instantiate(JSContext* cx, HandleModuleObject self); static bool Evaluate(JSContext* cx, HandleModuleObject self); + static ModuleNamespaceObject* GetOrCreateModuleNamespace(JSContext* cx, + HandleModuleObject self); + void setMetaObject(JSObject* obj); // For BytecodeEmitter. @@ -374,6 +377,16 @@ class MOZ_STACK_CLASS ModuleBuilder JSObject* GetOrCreateModuleMetaObject(JSContext* cx, HandleObject module); +JSObject* +CallModuleResolveHook(JSContext* cx, HandleValue referencingPrivate, HandleString specifier); + +JSObject* +StartDynamicModuleImport(JSContext* cx, HandleValue referencingPrivate, HandleValue specifier); + +bool +FinishDynamicModuleImport(JSContext* cx, HandleValue referencingPrivate, HandleString specifier, + HandleObject promise); + } // namespace js template<> diff --git a/js/src/builtin/Promise.cpp b/js/src/builtin/Promise.cpp index 0aaf68a00f..4da00a8671 100644 --- a/js/src/builtin/Promise.cpp +++ b/js/src/builtin/Promise.cpp @@ -3863,6 +3863,16 @@ OriginalPromiseThenBuiltin(JSContext* cx, HandleValue promiseVal, HandleValue on return true; } +MOZ_MUST_USE bool +js::RejectPromiseWithPendingError(JSContext* cx, Handle<PromiseObject*> promise) +{ + // Not much we can do about uncatchable exceptions, just bail. + RootedValue exn(cx); + if (!GetAndClearException(cx, &exn)) + return false; + return PromiseObject::reject(cx, promise, exn); +} + static MOZ_MUST_USE bool PerformPromiseThenWithReaction(JSContext* cx, Handle<PromiseObject*> promise, Handle<PromiseReactionRecord*> reaction); diff --git a/js/src/builtin/Promise.h b/js/src/builtin/Promise.h index 3d6dbe0e62..5e5c850d60 100644 --- a/js/src/builtin/Promise.h +++ b/js/src/builtin/Promise.h @@ -146,6 +146,9 @@ OriginalPromiseThen(JSContext* cx, Handle<PromiseObject*> promise, MOZ_MUST_USE JSObject* PromiseResolve(JSContext* cx, HandleObject constructor, HandleValue value); +MOZ_MUST_USE bool +RejectPromiseWithPendingError(JSContext* cx, Handle<PromiseObject*> promise); + MOZ_MUST_USE PromiseObject* CreatePromiseObjectForAsync(JSContext* cx, HandleValue generatorVal); |