summaryrefslogtreecommitdiff
path: root/js/src/builtin
diff options
context:
space:
mode:
authorBrian Smith <brian@dbsoft.org>2023-04-09 03:06:39 -0500
committerBrian Smith <brian@dbsoft.org>2023-04-27 13:33:00 -0500
commit130d9f4d91f666f6bd44a3e227808030225ef56b (patch)
tree548674f5366dc49ec7f784b82b4ae9861a4fc672 /js/src/builtin
parent6eecfad57c57c4c305149d1f5634628e80b0cca6 (diff)
downloaduxp-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.cpp102
-rw-r--r--js/src/builtin/ModuleObject.h13
-rw-r--r--js/src/builtin/Promise.cpp10
-rw-r--r--js/src/builtin/Promise.h3
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);