Bug 1622184 - Add a public method to mark a settled Promise as handled; r=arai
authorBrian Birtles <birtles@gmail.com>
Wed, 18 Mar 2020 02:22:00 +0000
changeset 519285 14521d59a4cf7d51fc0ea61372db91299920d753
parent 519284 7c1a4d74cc7a29510ad95403d001e57c2ba78119
child 519286 bd0f43a21b36f57ff72c3c2f5402310343900be8
push id37225
push userdvarga@mozilla.com
push dateWed, 18 Mar 2020 16:05:52 +0000
treeherdermozilla-central@5bfecf5aff6d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersarai
bugs1622184
milestone76.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1622184 - Add a public method to mark a settled Promise as handled; r=arai Differential Revision: https://phabricator.services.mozilla.com/D67103
dom/promise/Promise.h
js/public/Promise.h
js/src/builtin/Promise-inl.h
js/src/builtin/streams/MiscellaneousOperations-inl.h
js/src/builtin/streams/ReadableStreamInternals.cpp
js/src/builtin/streams/ReadableStreamReader.cpp
js/src/builtin/streams/WritableStreamDefaultWriter.cpp
js/src/builtin/streams/WritableStreamOperations.cpp
js/src/builtin/streams/WritableStreamWriterOperations.cpp
js/src/jsapi.cpp
--- a/dom/promise/Promise.h
+++ b/dom/promise/Promise.h
@@ -4,16 +4,17 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_dom_Promise_h
 #define mozilla_dom_Promise_h
 
 #include <utility>
 
+#include "js/Promise.h"
 #include "js/TypeDecls.h"
 #include "jspubtd.h"
 #include "mozilla/Attributes.h"
 #include "mozilla/ErrorResult.h"
 #include "mozilla/TimeStamp.h"
 #include "mozilla/TypeTraits.h"
 #include "mozilla/WeakPtr.h"
 #include "mozilla/dom/BindingDeclarations.h"
@@ -175,16 +176,25 @@ class Promise : public nsISupports, publ
   // every translation unit that includes this header, because that would
   // require use to include DOMException.h either here or in all those
   // translation units.
   template <typename T>
   void MaybeRejectBrokenly(const T& aArg);  // Not implemented by default; see
                                             // specializations in the .cpp for
                                             // the T values we support.
 
+  // Mark a settled promise as already handled so that rejections will not
+  // be reported as unhandled.
+  void SetSettledPromiseIsHandled() {
+    AutoEntryScript aes(mGlobal, "Set settled promise handled");
+    JSContext* cx = aes.cx();
+    JS::RootedObject promiseObj(cx, mPromiseObj);
+    JS::SetSettledPromiseIsHandled(cx, promiseObj);
+  }
+
   // WebIDL
 
   nsIGlobalObject* GetParentObject() const { return GetGlobalObject(); }
 
   // Do the equivalent of Promise.resolve in the compartment of aGlobal.  The
   // compartment of aCx is ignored.  Errors are reported on the ErrorResult; if
   // aRv comes back !Failed(), this function MUST return a non-null value.
   // Pass ePropagateUserInteraction for aPropagateUserInteraction if you want
--- a/js/public/Promise.h
+++ b/js/public/Promise.h
@@ -350,16 +350,24 @@ extern JS_PUBLIC_API JS::Value GetPromis
 /**
  * Returns whether the given promise's rejection is already handled or not.
  *
  * The caller must check the given promise is rejected before checking it's
  * handled or not.
  */
 extern JS_PUBLIC_API bool GetPromiseIsHandled(JS::HandleObject promise);
 
+/*
+ * Given a settled (i.e. fulfilled or rejected, not pending) promise, sets
+ * |promise.[[PromiseIsHandled]]| to true and removes it from the list of
+ * unhandled rejected promises.
+ */
+extern JS_PUBLIC_API void SetSettledPromiseIsHandled(JSContext* cx,
+                                                     JS::HandleObject promise);
+
 /**
  * Returns a js::SavedFrame linked list of the stack that lead to the given
  * Promise's allocation.
  */
 extern JS_PUBLIC_API JSObject* GetPromiseAllocationSite(
     JS::HandleObject promise);
 
 extern JS_PUBLIC_API JSObject* GetPromiseResolutionSite(
new file mode 100644
--- /dev/null
+++ b/js/src/builtin/Promise-inl.h
@@ -0,0 +1,37 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * vim: set ts=8 sts=2 et sw=2 tw=80:
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef builtin_Promise_inl_h
+#define builtin_Promise_inl_h
+
+#include "js/Promise.h"          // JS::PromiseState
+
+#include "mozilla/Assertions.h"  // MOZ_ASSERT
+
+#include "js/RootingAPI.h"       // JS::Handle
+#include "vm/JSContext.h"        // JSContext
+#include "vm/PromiseObject.h"    // js::PromiseObject
+
+namespace js {
+
+/**
+ * Given a settled (i.e. fulfilled or rejected, not pending) promise, sets
+ * |promise.[[PromiseIsHandled]]| to true and removes it from the list of
+ * unhandled rejected promises.
+ *
+ * NOTE: If you need to set |promise.[[PromiseIsHandled]]| on a pending promise,
+ *       use |PromiseObject::setHandled()| directly.
+ */
+inline void SetSettledPromiseIsHandled(
+    JSContext* cx, JS::Handle<PromiseObject*> unwrappedPromise) {
+  MOZ_ASSERT(unwrappedPromise->state() != JS::PromiseState::Pending);
+  unwrappedPromise->setHandled();
+  cx->runtime()->removeUnhandledRejectedPromise(cx, unwrappedPromise);
+}
+
+}  // namespace js
+
+#endif  // builtin_Promise_inl_h
--- a/js/src/builtin/streams/MiscellaneousOperations-inl.h
+++ b/js/src/builtin/streams/MiscellaneousOperations-inl.h
@@ -9,17 +9,17 @@
 #ifndef builtin_streams_MiscellaneousOperations_inl_h
 #define builtin_streams_MiscellaneousOperations_inl_h
 
 #include "builtin/streams/MiscellaneousOperations.h"
 
 #include "mozilla/Assertions.h"  // MOZ_ASSERT
 #include "mozilla/Attributes.h"  // MOZ_MUST_USE
 
-#include "js/Promise.h"        // JS::{Resolve,Reject}Promise, JS::PromiseState
+#include "js/Promise.h"        // JS::{Resolve,Reject}Promise
 #include "js/RootingAPI.h"     // JS::Rooted, JS::{,Mutable}Handle
 #include "js/Value.h"          // JS::UndefinedHandleValue, JS::Value
 #include "vm/Compartment.h"    // JS::Compartment
 #include "vm/Interpreter.h"    // js::Call
 #include "vm/JSContext.h"      // JSContext
 #include "vm/JSObject.h"       // JSObject
 #include "vm/PromiseObject.h"  // js::PromiseObject
 
@@ -105,26 +105,11 @@ inline MOZ_MUST_USE bool RejectUnwrapped
  * Reject the unwrapped promise |unwrappedPromise| with |error|.
  */
 inline MOZ_MUST_USE bool RejectUnwrappedPromiseWithError(
     JSContext* cx, JSObject* unwrappedPromise, JS::Handle<JS::Value> error) {
   JS::Rooted<JSObject*> promise(cx, unwrappedPromise);
   return RejectUnwrappedPromiseWithError(cx, &promise, error);
 }
 
-/**
- * Given a settled (i.e. fulfilled or rejected, not pending) promise, sets
- * |promise.[[PromiseIsHandled]]| to true and removes it from the list of
- * unhandled rejected promises.
- *
- * NOTE: If you need to set |promise.[[PromiseIsHandled]]| on a pending promise,
- *       use |PromiseObject::setHandled()| directly.
- */
-inline void SetSettledPromiseIsHandled(
-    JSContext* cx, JS::Handle<PromiseObject*> unwrappedPromise) {
-  MOZ_ASSERT(unwrappedPromise->state() != JS::PromiseState::Pending);
-  unwrappedPromise->setHandled();
-  cx->runtime()->removeUnhandledRejectedPromise(cx, unwrappedPromise);
-}
-
 }  // namespace js
 
 #endif  // builtin_streams_MiscellaneousOperations_inl_h
--- a/js/src/builtin/streams/ReadableStreamInternals.cpp
+++ b/js/src/builtin/streams/ReadableStreamInternals.cpp
@@ -28,17 +28,18 @@
 #include "vm/JSContext.h"      // JSContext
 #include "vm/JSFunction.h"     // JSFunction, js::NewNativeFunction
 #include "vm/NativeObject.h"   // js::NativeObject
 #include "vm/ObjectGroup.h"    // js::GenericObject
 #include "vm/PromiseObject.h"  // js::PromiseObject
 #include "vm/Realm.h"          // JS::Realm
 #include "vm/StringType.h"     // js::PropertyName
 
-#include "builtin/streams/MiscellaneousOperations-inl.h"  // js::{Reject,Resolve}UnwrappedPromiseWithUndefined, js::SetSettledPromiseIsHandled
+#include "builtin/Promise-inl.h"  // js::SetSettledPromiseIsHandled
+#include "builtin/streams/MiscellaneousOperations-inl.h"  // js::{Reject,Resolve}UnwrappedPromiseWithUndefined
 #include "builtin/streams/ReadableStreamReader-inl.h"  // js::js::UnwrapReaderFromStream{,NoThrow}
 #include "vm/Compartment-inl.h"                        // JS::Compartment::wrap
 #include "vm/JSContext-inl.h"                          // JSContext::check
 #include "vm/List-inl.h"  // js::ListObject, js::AppendToListInFixedSlot, js::StoreNewListInFixedSlot
 #include "vm/Realm-inl.h"  // JS::Realm
 
 using js::ReadableStream;
 
@@ -349,17 +350,17 @@ MOZ_MUST_USE bool js::ReadableStreamErro
   // Step 10: Set reader.[[closedPromise]].[[PromiseIsHandled]] to true.
   //
   // `closedPromise` can return a CCW, but that case is filtered out by step 6,
   // given the only place that can set [[closedPromise]] to a CCW is
   // 3.8.5 ReadableStreamReaderGenericRelease step 4, and
   // 3.8.5 ReadableStreamReaderGenericRelease step 6 sets
   // stream.[[reader]] to undefined.
   Rooted<JSObject*> closedPromise(cx, unwrappedReader->closedPromise());
-  SetSettledPromiseIsHandled(cx, closedPromise.as<PromiseObject>());
+  js::SetSettledPromiseIsHandled(cx, closedPromise.as<PromiseObject>());
 
   if (unwrappedStream->mode() == JS::ReadableStreamMode::ExternalSource) {
     // Make sure we're in the stream's compartment.
     AutoRealm ar(cx, unwrappedStream);
     JS::ReadableStreamUnderlyingSource* source =
         unwrappedStream->controller()->externalSource();
 
     // Ensure that the embedding doesn't have to deal with
--- a/js/src/builtin/streams/ReadableStreamReader.cpp
+++ b/js/src/builtin/streams/ReadableStreamReader.cpp
@@ -19,17 +19,17 @@
 #include "builtin/streams/ReadableStreamInternals.h"  // js::ReadableStream{Cancel,CreateReadResult}
 #include "js/RootingAPI.h"                            // JS::Handle, JS::Rooted
 #include "js/Value.h"          // JS::Value, JS::UndefinedHandleValue
 #include "vm/Interpreter.h"    // js::GetAndClearException
 #include "vm/JSContext.h"      // JSContext
 #include "vm/PromiseObject.h"  // js::PromiseObject
 #include "vm/Runtime.h"        // JSRuntime
 
-#include "builtin/streams/MiscellaneousOperations-inl.h"  // js::SetSettledPromiseIsHandled
+#include "builtin/Promise-inl.h" // js::SetSettledPromiseIsHandled
 #include "vm/Compartment-inl.h"  // JS::Compartment::wrap, js::UnwrapInternalSlot
 #include "vm/List-inl.h"         // js::StoreNewListInFixedSlot
 #include "vm/Realm-inl.h"        // js::AutoRealm
 
 using js::ReadableStreamController;
 using js::UnwrapStreamFromReader;
 
 using JS::Handle;
@@ -108,17 +108,17 @@ MOZ_MUST_USE bool js::ReadableStreamRead
       return false;
     }
     promise = PromiseObject::unforgeableReject(cx, storedError);
     if (!promise) {
       return false;
     }
 
     // Step c. Set reader.[[closedPromise]].[[PromiseIsHandled]] to true.
-    SetSettledPromiseIsHandled(cx, promise);
+    js::SetSettledPromiseIsHandled(cx, promise);
   }
 
   if (!promise) {
     return false;
   }
 
   reader->setClosedPromise(promise);
 
@@ -206,17 +206,17 @@ MOZ_MUST_USE bool js::ReadableStreamRead
     AutoRealm ar(cx, unwrappedReader);
     if (!cx->compartment()->wrap(cx, &closedPromise)) {
       return false;
     }
     unwrappedReader->setClosedPromise(closedPromise);
   }
 
   // Step 5: Set reader.[[closedPromise]].[[PromiseIsHandled]] to true.
-  SetSettledPromiseIsHandled(cx, unwrappedClosedPromise);
+  js::SetSettledPromiseIsHandled(cx, unwrappedClosedPromise);
 
   // Step 6: Set reader.[[ownerReadableStream]].[[reader]] to undefined.
   unwrappedStream->clearReader();
 
   // Step 7: Set reader.[[ownerReadableStream]] to undefined.
   unwrappedReader->clearStream();
 
   return true;
--- a/js/src/builtin/streams/WritableStreamDefaultWriter.cpp
+++ b/js/src/builtin/streams/WritableStreamDefaultWriter.cpp
@@ -23,17 +23,17 @@
 #include "js/Class.h"     // js::ClassSpec, JS_NULL_CLASS_OPS
 #include "js/PropertySpec.h"  // JS{Function,Property}Spec, JS_{FS,PS}_END, JS_{FN,PSG}
 #include "js/RootingAPI.h"     // JS::Handle
 #include "js/Value.h"          // JS::Value
 #include "vm/Compartment.h"    // JS::Compartment
 #include "vm/JSContext.h"      // JSContext
 #include "vm/PromiseObject.h"  // js::PromiseObject
 
-#include "builtin/streams/MiscellaneousOperations-inl.h"  // js::SetSettledPromiseIsHandled
+#include "builtin/Promise-inl.h" // js::SetSettledPromiseIsHandled
 #include "vm/Compartment-inl.h"  // JS::Compartment::wrap, js::UnwrapAndTypeCheck{Argument,This}
 #include "vm/JSObject-inl.h"      // js::NewObjectWithClassProto
 #include "vm/NativeObject-inl.h"  // js::ThrowIfNotConstructing
 #include "vm/Realm-inl.h"         // js::AutoRealm
 
 using JS::CallArgs;
 using JS::CallArgsFromVp;
 using JS::Handle;
@@ -142,17 +142,17 @@ MOZ_MUST_USE WritableStreamDefaultWriter
           cx, PromiseObject::unforgeableReject(cx, storedError));
       if (!promise) {
         return nullptr;
       }
 
       writer->setReadyPromise(promise);
 
       // Step 7.b: Set this.[[readyPromise]].[[PromiseIsHandled]] to true.
-      SetSettledPromiseIsHandled(cx, promise.as<PromiseObject>());
+      js::SetSettledPromiseIsHandled(cx, promise.as<PromiseObject>());
 
       // Step 7.c: Set this.[[closedPromise]] to a new promise.
       JSObject* closedPromise = PromiseObject::createSkippingExecutor(cx);
       if (!closedPromise) {
         return nullptr;
       }
 
       writer->setClosedPromise(closedPromise);
@@ -170,29 +170,29 @@ MOZ_MUST_USE WritableStreamDefaultWriter
       promise = PromiseObject::unforgeableReject(cx, storedError);
       if (!promise) {
         return nullptr;
       }
 
       writer->setReadyPromise(promise);
 
       // Step 9.d: Set this.[[readyPromise]].[[PromiseIsHandled]] to true.
-      SetSettledPromiseIsHandled(cx, promise.as<PromiseObject>());
+      js::SetSettledPromiseIsHandled(cx, promise.as<PromiseObject>());
 
       // Step 9.e: Set this.[[closedPromise]] to a promise rejected with
       //           storedError.
       promise = PromiseObject::unforgeableReject(cx, storedError);
       if (!promise) {
         return nullptr;
       }
 
       writer->setClosedPromise(promise);
 
       // Step 9.f: Set this.[[closedPromise]].[[PromiseIsHandled]] to true.
-      SetSettledPromiseIsHandled(cx, promise.as<PromiseObject>());
+      js::SetSettledPromiseIsHandled(cx, promise.as<PromiseObject>());
     }
   }
 
   // Step 4 (reordered): Set stream.[[writer]] to this.
   // Doing this last prevents a partially-initialized writer from being attached
   // to the stream (and possibly left there on OOM).
   {
     AutoRealm ar(cx, unwrappedStream);
--- a/js/src/builtin/streams/WritableStreamOperations.cpp
+++ b/js/src/builtin/streams/WritableStreamOperations.cpp
@@ -25,18 +25,19 @@
 #include "js/Promise.h"     // JS::{Reject,Resolve}Promise
 #include "js/RootingAPI.h"  // JS::Handle, JS::Rooted
 #include "js/Value.h"  // JS::Value, JS::ObjecValue, JS::UndefinedHandleValue
 #include "vm/Compartment.h"    // JS::Compartment
 #include "vm/JSContext.h"      // JSContext
 #include "vm/List.h"           // js::ListObject
 #include "vm/PromiseObject.h"  // js::PromiseObject
 
+#include "builtin/Promise-inl.h"  // js::SetSettledPromiseIsHandled
 #include "builtin/streams/HandlerFunction-inl.h"  // js::NewHandler, js::TargetFromHandler
-#include "builtin/streams/MiscellaneousOperations-inl.h"  // js::ResolveUnwrappedPromiseWithUndefined, js::RejectUnwrappedPromiseWithError, js::SetSettledPromiseIsHandled
+#include "builtin/streams/MiscellaneousOperations-inl.h"  // js::ResolveUnwrappedPromiseWithUndefined, js::RejectUnwrappedPromiseWithError
 #include "builtin/streams/WritableStream-inl.h"  // js::UnwrapWriterFromStream
 #include "builtin/streams/WritableStreamDefaultWriter-inl.h"  // js::WritableStreamDefaultWriter::closedPromise
 #include "vm/Compartment-inl.h"  // JS::Compartment::wrap, js::UnwrapAndDowncastObject
 #include "vm/JSContext-inl.h"  // JSContext::check
 #include "vm/JSObject-inl.h"   // js::NewObjectWithClassProto
 #include "vm/List-inl.h"       // js::{AppendTo,StoreNew}ListInFixedSlot
 #include "vm/Realm-inl.h"      // js::AutoRealm
 
@@ -857,17 +858,17 @@ MOZ_MUST_USE bool js::WritableStreamReje
     // Step 4.b: Set writer.[[closedPromise]].[[PromiseIsHandled]] to true.
     Rooted<PromiseObject*> unwrappedClosedPromise(
         cx, UnwrapAndDowncastObject<PromiseObject>(
                 cx, unwrappedWriter->closedPromise()));
     if (!unwrappedClosedPromise) {
       return false;
     }
 
-    SetSettledPromiseIsHandled(cx, unwrappedClosedPromise);
+    js::SetSettledPromiseIsHandled(cx, unwrappedClosedPromise);
   }
 
   return true;
 }
 
 /**
  * Streams spec, 4.4.14.
  *      WritableStreamUpdateBackpressure ( stream, backpressure )
--- a/js/src/builtin/streams/WritableStreamWriterOperations.cpp
+++ b/js/src/builtin/streams/WritableStreamWriterOperations.cpp
@@ -22,17 +22,18 @@
 #include "builtin/streams/WritableStreamOperations.h"  // js::WritableStream{Abort,CloseQueuedOrInFlight}
 #include "js/Promise.h"                                // JS::PromiseState
 #include "js/Value.h"          // JS::Value, JS::{Int32,Null}Value
 #include "vm/Compartment.h"    // JS::Compartment
 #include "vm/Interpreter.h"    // js::GetAndClearException
 #include "vm/JSContext.h"      // JSContext
 #include "vm/PromiseObject.h"  // js::PromiseObject
 
-#include "builtin/streams/MiscellaneousOperations-inl.h"  // js::ResolveUnwrappedPromiseWithUndefined, js::SetSettledPromiseIsHandled
+#include "builtin/Promise-inl.h"  // js::SetSettledPromiseIsHandled
+#include "builtin/streams/MiscellaneousOperations-inl.h"  // js::ResolveUnwrappedPromiseWithUndefined
 #include "builtin/streams/WritableStream-inl.h"  // js::WritableStream::setCloseRequest
 #include "builtin/streams/WritableStreamDefaultWriter-inl.h"  // js::UnwrapStreamFromWriter
 #include "vm/Compartment-inl.h"  // js::UnwrapAnd{DowncastObject,TypeCheckThis}
 #include "vm/JSContext-inl.h"    // JSContext::check
 #include "vm/Realm-inl.h"        // js::AutoRealm
 
 using JS::Handle;
 using JS::Int32Value;
@@ -180,17 +181,17 @@ static bool EnsurePromiseRejected(
 
     // Directly-unobservable rejected promises aren't collapsed like resolved
     // promises, and this promise is created in the current realm, so it's
     // always an actual Promise.
     unwrappedPromise = &rejectedWithError->as<PromiseObject>();
   }
 
   // 4.6.{5,6} step 3: Set writer.[[<field>]].[[PromiseIsHandled]] to true.
-  SetSettledPromiseIsHandled(cx, unwrappedPromise);
+  js::SetSettledPromiseIsHandled(cx, unwrappedPromise);
   return true;
 }
 
 /**
  * Streams spec, 4.6.5.
  *  WritableStreamDefaultWriterEnsureClosedPromiseRejected( writer, error )
  */
 MOZ_MUST_USE bool js::WritableStreamDefaultWriterEnsureClosedPromiseRejected(
--- a/js/src/jsapi.cpp
+++ b/js/src/jsapi.cpp
@@ -94,16 +94,17 @@
 #include "vm/StringType.h"
 #include "vm/SymbolType.h"
 #include "vm/ToSource.h"
 #include "vm/WrapperObject.h"
 #include "vm/Xdr.h"
 #include "wasm/WasmModule.h"
 #include "wasm/WasmProcess.h"
 
+#include "builtin/Promise-inl.h"
 #include "debugger/DebugAPI-inl.h"
 #include "vm/Compartment-inl.h"
 #include "vm/Interpreter-inl.h"
 #include "vm/IsGivenTypeObject-inl.h"  // js::IsGivenTypeObject
 #include "vm/JSAtom-inl.h"
 #include "vm/JSFunction-inl.h"
 #include "vm/JSScript-inl.h"
 #include "vm/NativeObject-inl.h"
@@ -3823,16 +3824,38 @@ JS_PUBLIC_API JS::Value JS::GetPromiseRe
                                                          : promise->reason();
 }
 
 JS_PUBLIC_API bool JS::GetPromiseIsHandled(JS::HandleObject promiseObj) {
   PromiseObject* promise = &promiseObj->as<PromiseObject>();
   return !promise->isUnhandled();
 }
 
+JS_PUBLIC_API void JS::SetSettledPromiseIsHandled(JSContext* cx,
+                                                  JS::HandleObject promise) {
+  AssertHeapIsIdle();
+  CHECK_THREAD(cx);
+  cx->check(promise);
+
+  mozilla::Maybe<AutoRealm> ar;
+  Rooted<PromiseObject*> promiseObj(cx);
+  if (IsWrapper(promise)) {
+    promiseObj = promise->maybeUnwrapAs<PromiseObject>();
+    if (!promiseObj) {
+      ReportAccessDenied(cx);
+      return;
+    }
+    ar.emplace(cx, promiseObj);
+  } else {
+    promiseObj = promise.as<PromiseObject>();
+  }
+
+  js::SetSettledPromiseIsHandled(cx, promiseObj);
+}
+
 JS_PUBLIC_API JSObject* JS::GetPromiseAllocationSite(JS::HandleObject promise) {
   return promise->as<PromiseObject>().allocationSite();
 }
 
 JS_PUBLIC_API JSObject* JS::GetPromiseResolutionSite(JS::HandleObject promise) {
   return promise->as<PromiseObject>().resolutionSite();
 }