Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(828)

Unified Diff: src/js/promise.js

Issue 2536463002: Create JSPromise (Closed)
Patch Set: rebase Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/js/async-await.js ('k') | src/objects.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/js/promise.js
diff --git a/src/js/promise.js b/src/js/promise.js
index 25c8beaa9e0aef86dd966faa3af89d8e342c04a3..b78f68c4f71c367365a8a149803c3091a9e55f75 100644
--- a/src/js/promise.js
+++ b/src/js/promise.js
@@ -20,12 +20,6 @@ var promiseForwardingHandlerSymbol =
utils.ImportNow("promise_forwarding_handler_symbol");
var promiseHasHandlerSymbol =
utils.ImportNow("promise_has_handler_symbol");
-var promiseRejectReactionsSymbol =
- utils.ImportNow("promise_reject_reactions_symbol");
-var promiseFulfillReactionsSymbol =
- utils.ImportNow("promise_fulfill_reactions_symbol");
-var promiseDeferredReactionSymbol =
- utils.ImportNow("promise_deferred_reaction_symbol");
var promiseHandledHintSymbol =
utils.ImportNow("promise_handled_hint_symbol");
var promiseRawSymbol = utils.ImportNow("promise_raw_symbol");
@@ -36,6 +30,7 @@ var speciesSymbol = utils.ImportNow("species_symbol");
var toStringTagSymbol = utils.ImportNow("to_string_tag_symbol");
var ObjectHasOwnProperty;
var GlobalPromise = global.Promise;
+var PromiseThen = GlobalPromise.prototype.then;
utils.Import(function(from) {
ObjectHasOwnProperty = from.ObjectHasOwnProperty;
@@ -46,42 +41,6 @@ utils.Import(function(from) {
// Core functionality.
-function PromiseSet(promise, status, value) {
- SET_PRIVATE(promise, promiseStateSymbol, status);
- SET_PRIVATE(promise, promiseResultSymbol, value);
-
- // There are 3 possible states for the resolve, reject symbols when we add
- // a new callback --
- // 1) UNDEFINED -- This is the zero state where there is no callback
- // registered. When we see this state, we directly attach the callbacks to
- // the symbol.
- // 2) !IS_ARRAY -- There is a single callback directly attached to the
- // symbols. We need to create a new array to store additional callbacks.
- // 3) IS_ARRAY -- There are multiple callbacks already registered,
- // therefore we can just push the new callback to the existing array.
- SET_PRIVATE(promise, promiseFulfillReactionsSymbol, UNDEFINED);
- SET_PRIVATE(promise, promiseRejectReactionsSymbol, UNDEFINED);
-
- // This symbol is used only when one deferred needs to be attached. When more
- // than one deferred need to be attached the promise, we attach them directly
- // to the promiseFulfillReactionsSymbol and promiseRejectReactionsSymbol and
- // reset this back to UNDEFINED.
- SET_PRIVATE(promise, promiseDeferredReactionSymbol, UNDEFINED);
-
- return promise;
-}
-
-function PromiseCreateAndSet(status, value) {
- var promise = %promise_internal_constructor();
- // If debug is active, notify about the newly created promise first.
- if (DEBUG_IS_ACTIVE) PromiseSet(promise, kPending, UNDEFINED);
- return PromiseSet(promise, status, value);
-}
-
-function PromiseInit(promise) {
- return PromiseSet(promise, kPending, UNDEFINED);
-}
-
function PromiseHandle(value, handler, deferred) {
var debug_is_active = DEBUG_IS_ACTIVE;
try {
@@ -98,7 +57,6 @@ function PromiseHandle(value, handler, deferred) {
// Pass false for debugEvent so .then chaining or throwaway promises
// in async functions do not trigger redundant ExceptionEvents.
%PromiseReject(deferred.promise, exception, false);
- PromiseSet(deferred.promise, kRejected, exception);
} else {
%_Call(deferred.reject, UNDEFINED, exception);
}
@@ -134,34 +92,6 @@ function PromiseDebugGetInfo(deferreds, status) {
return [id, name];
}
-function PromiseAttachCallbacks(promise, deferred, onResolve, onReject) {
- var maybeResolveCallbacks =
- GET_PRIVATE(promise, promiseFulfillReactionsSymbol);
- if (IS_UNDEFINED(maybeResolveCallbacks)) {
- SET_PRIVATE(promise, promiseFulfillReactionsSymbol, onResolve);
- SET_PRIVATE(promise, promiseRejectReactionsSymbol, onReject);
- SET_PRIVATE(promise, promiseDeferredReactionSymbol, deferred);
- } else if (!IS_ARRAY(maybeResolveCallbacks)) {
- var resolveCallbacks = new InternalArray();
- var rejectCallbacks = new InternalArray();
- var existingDeferred = GET_PRIVATE(promise, promiseDeferredReactionSymbol);
-
- resolveCallbacks.push(
- maybeResolveCallbacks, existingDeferred, onResolve, deferred);
- rejectCallbacks.push(GET_PRIVATE(promise, promiseRejectReactionsSymbol),
- existingDeferred,
- onReject,
- deferred);
-
- SET_PRIVATE(promise, promiseFulfillReactionsSymbol, resolveCallbacks);
- SET_PRIVATE(promise, promiseRejectReactionsSymbol, rejectCallbacks);
- SET_PRIVATE(promise, promiseDeferredReactionSymbol, UNDEFINED);
- } else {
- maybeResolveCallbacks.push(onResolve, deferred);
- GET_PRIVATE(promise, promiseRejectReactionsSymbol).push(onReject, deferred);
- }
-}
-
function PromiseIdResolveHandler(x) { return x; }
function PromiseIdRejectHandler(r) { %_ReThrow(r); }
SET_PRIVATE(PromiseIdRejectHandler, promiseForwardingHandlerSymbol, true);
@@ -171,8 +101,9 @@ SET_PRIVATE(PromiseIdRejectHandler, promiseForwardingHandlerSymbol, true);
// For bootstrapper.
+// This is used by utils and v8-extras.
function PromiseCreate() {
- return PromiseInit(%promise_internal_constructor());
+ return %promise_internal_constructor();
}
// ES#sec-promise-resolve-functions
@@ -181,7 +112,6 @@ function ResolvePromise(promise, resolution) {
if (resolution === promise) {
var exception = %make_type_error(kPromiseCyclic, resolution);
%PromiseReject(promise, exception, true);
- PromiseSet(promise, kRejected, exception);
return;
}
if (IS_RECEIVER(resolution)) {
@@ -190,7 +120,6 @@ function ResolvePromise(promise, resolution) {
var then = resolution.then;
} catch (e) {
%PromiseReject(promise, e, true);
- PromiseSet(promise, kRejected, e);
return;
}
@@ -198,18 +127,16 @@ function ResolvePromise(promise, resolution) {
// rejected, shortcircuit the resolution procedure by directly
// reusing the value from the promise.
if (%is_promise(resolution) && then === PromiseThen) {
- var thenableState = GET_PRIVATE(resolution, promiseStateSymbol);
+ var thenableState = %PromiseStatus(resolution);
if (thenableState === kFulfilled) {
// This goes inside the if-else to save one symbol lookup in
// the slow path.
- var thenableValue = GET_PRIVATE(resolution, promiseResultSymbol);
- %PromiseFulfill(promise, kFulfilled, thenableValue,
- promiseFulfillReactionsSymbol);
- PromiseSet(promise, kFulfilled, thenableValue);
+ var thenableValue = %PromiseResult(resolution);
+ %PromiseFulfill(promise, kFulfilled, thenableValue);
SET_PRIVATE(promise, promiseHasHandlerSymbol, true);
return;
} else if (thenableState === kRejected) {
- var thenableValue = GET_PRIVATE(resolution, promiseResultSymbol);
+ var thenableValue = %PromiseResult(resolution);
if (!HAS_DEFINED_PRIVATE(resolution, promiseHasHandlerSymbol)) {
// Promise has already been rejected, but had no handler.
// Revoke previously triggered reject event.
@@ -217,7 +144,6 @@ function ResolvePromise(promise, resolution) {
}
// Don't cause a debug event as this case is forwarding a rejection
%PromiseReject(promise, thenableValue, false);
- PromiseSet(promise, kRejected, thenableValue);
SET_PRIVATE(resolution, promiseHasHandlerSymbol, true);
return;
}
@@ -232,21 +158,17 @@ function ResolvePromise(promise, resolution) {
return;
}
}
- %PromiseFulfill(promise, kFulfilled, resolution,
- promiseFulfillReactionsSymbol);
- PromiseSet(promise, kFulfilled, resolution);
+ %PromiseFulfill(promise, kFulfilled, resolution);
}
// Only used by async-await.js
function RejectPromise(promise, reason, debugEvent) {
%PromiseReject(promise, reason, debugEvent);
- PromiseSet(promise, kRejected, reason);
}
// Export to bindings
function DoRejectPromise(promise, reason) {
%PromiseReject(promise, reason, true);
- PromiseSet(promise, kRejected, reason);
}
// The resultCapability.promise is only ever fulfilled internally,
@@ -254,7 +176,7 @@ function DoRejectPromise(promise, reason) {
// calling them multiple times.
function CreateInternalPromiseCapability() {
return {
- promise: PromiseCreate(),
+ promise: %promise_internal_constructor(),
resolve: UNDEFINED,
reject: UNDEFINED
};
@@ -265,7 +187,7 @@ function CreateInternalPromiseCapability() {
function NewPromiseCapability(C, debugEvent) {
if (C === GlobalPromise) {
// Optimized case, avoid extra closure.
- var promise = PromiseCreate();
+ var promise = %promise_internal_constructor();
// TODO(gsathya): Remove container for callbacks when this is
// moved to CPP/TF.
var callbacks = %create_resolving_functions(promise, debugEvent);
@@ -298,7 +220,7 @@ function PromiseReject(r) {
}
if (this === GlobalPromise) {
// Optimized case, avoid extra closure.
- var promise = PromiseCreateAndSet(kRejected, r);
+ var promise = %promise_create_and_set(kRejected, r);
// Trigger debug events if the debugger is on, as Promise.reject is
// equivalent to throwing an exception directly.
%PromiseRejectEventFromStack(promise, r);
@@ -310,55 +232,6 @@ function PromiseReject(r) {
}
}
-function PerformPromiseThen(promise, onResolve, onReject, resultCapability) {
- if (!IS_CALLABLE(onResolve)) onResolve = PromiseIdResolveHandler;
- if (!IS_CALLABLE(onReject)) onReject = PromiseIdRejectHandler;
-
- var status = GET_PRIVATE(promise, promiseStateSymbol);
- switch (status) {
- case kPending:
- PromiseAttachCallbacks(promise, resultCapability, onResolve, onReject);
- break;
- case kFulfilled:
- %EnqueuePromiseReactionJob(GET_PRIVATE(promise, promiseResultSymbol),
- onResolve, resultCapability, kFulfilled);
- break;
- case kRejected:
- if (!HAS_DEFINED_PRIVATE(promise, promiseHasHandlerSymbol)) {
- // Promise has already been rejected, but had no handler.
- // Revoke previously triggered reject event.
- %PromiseRevokeReject(promise);
- }
- %EnqueuePromiseReactionJob(GET_PRIVATE(promise, promiseResultSymbol),
- onReject, resultCapability, kRejected);
- break;
- }
-
- // Mark this promise as having handler.
- SET_PRIVATE(promise, promiseHasHandlerSymbol, true);
- return resultCapability.promise;
-}
-
-// ES#sec-promise.prototype.then
-// Promise.prototype.then ( onFulfilled, onRejected )
-// Multi-unwrapped chaining with thenable coercion.
-function PromiseThen(onResolve, onReject) {
- if (!%is_promise(this)) {
- throw %make_type_error(kNotAPromise, this);
- }
-
- var constructor = SpeciesConstructor(this, GlobalPromise);
- var resultCapability;
- if (constructor === GlobalPromise) {
- resultCapability = CreateInternalPromiseCapability();
- } else {
- // Pass false for debugEvent so .then chaining does not trigger
- // redundant ExceptionEvents.
- resultCapability = NewPromiseCapability(constructor, false);
- }
- return PerformPromiseThen(this, onResolve, onReject, resultCapability);
-}
-
// ES#sec-promise.prototype.catch
// Promise.prototype.catch ( onRejected )
function PromiseCatch(onReject) {
@@ -377,7 +250,7 @@ function PromiseResolve(x) {
// Avoid creating resolving functions.
if (this === GlobalPromise) {
- var promise = PromiseCreate();
+ var promise = %promise_internal_constructor();
ResolvePromise(promise, x);
return promise;
}
@@ -520,8 +393,10 @@ function PromiseHasUserDefinedRejectHandlerRecursive(promise) {
return true;
}
- var queue = GET_PRIVATE(promise, promiseRejectReactionsSymbol);
- var deferred = GET_PRIVATE(promise, promiseDeferredReactionSymbol);
+ if (!%is_promise(promise)) return false;
+
+ var queue = %PromiseRejectReactions(promise);
+ var deferred = %PromiseDeferred(promise);
if (IS_UNDEFINED(queue)) return false;
@@ -529,8 +404,8 @@ function PromiseHasUserDefinedRejectHandlerRecursive(promise) {
return PromiseHasUserDefinedRejectHandlerCheck(queue, deferred);
}
- for (var i = 0; i < queue.length; i += 2) {
- if (PromiseHasUserDefinedRejectHandlerCheck(queue[i], queue[i + 1])) {
+ for (var i = 0; i < queue.length; i++) {
+ if (PromiseHasUserDefinedRejectHandlerCheck(queue[i], deferred[i])) {
return true;
}
}
@@ -568,7 +443,6 @@ utils.InstallFunctions(GlobalPromise, DONT_ENUM, [
utils.InstallGetter(GlobalPromise, speciesSymbol, PromiseSpecies);
utils.InstallFunctions(GlobalPromise.prototype, DONT_ENUM, [
- "then", PromiseThen,
"catch", PromiseCatch
]);
@@ -582,7 +456,11 @@ utils.InstallFunctions(GlobalPromise.prototype, DONT_ENUM, [
"promise_resolve", ResolvePromise,
"promise_then", PromiseThen,
"promise_handle", PromiseHandle,
- "promise_debug_get_info", PromiseDebugGetInfo
+ "promise_debug_get_info", PromiseDebugGetInfo,
+ "new_promise_capability", NewPromiseCapability,
+ "internal_promise_capability", CreateInternalPromiseCapability,
+ "promise_id_resolve_handler", PromiseIdResolveHandler,
+ "promise_id_reject_handler", PromiseIdRejectHandler
]);
// This allows extras to create promises quickly without building extra
@@ -600,7 +478,6 @@ utils.Export(function(to) {
to.PromiseThen = PromiseThen;
to.CreateInternalPromiseCapability = CreateInternalPromiseCapability;
- to.PerformPromiseThen = PerformPromiseThen;
to.ResolvePromise = ResolvePromise;
to.RejectPromise = RejectPromise;
});
« no previous file with comments | « src/js/async-await.js ('k') | src/objects.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698