Commit b6bcf321 authored by Benedikt Meurer's avatar Benedikt Meurer Committed by Commit Bot

[async] The Promise.all() fast-path must check @@species protector.

We cannot take the fast-path if the user messed with the Symbol.species
property on the Promise.prototype, as that makes the internal promises
observable.

Bug: chromium:917076
Change-Id: I928e0bd17836ca78cf88591610526aa7bc1d293c
Reviewed-on: https://chromium-review.googlesource.com/c/1396426
Commit-Queue: Benedikt Meurer <bmeurer@chromium.org>
Reviewed-by: 's avatarYang Guo <yangguo@chromium.org>
Cr-Commit-Position: refs/heads/master@{#58563}
parent 61f4c225
...@@ -1958,9 +1958,12 @@ Node* PromiseBuiltinsAssembler::PerformPromiseAll( ...@@ -1958,9 +1958,12 @@ Node* PromiseBuiltinsAssembler::PerformPromiseAll(
// (a) The {constructor} is the intrinsic %Promise% function, and // (a) The {constructor} is the intrinsic %Promise% function, and
// looking up "resolve" on {constructor} yields the initial // looking up "resolve" on {constructor} yields the initial
// Promise.resolve() builtin, and // Promise.resolve() builtin, and
// (b) the {next_value} is a JSPromise whose [[Prototype]] field // (b) the promise @@species protector cell is valid, meaning that
// no one messed with the Symbol.species property on any
// intrinsic promise or on the Promise.prototype, and
// (c) the {next_value} is a JSPromise whose [[Prototype]] field
// contains the intrinsic %PromisePrototype%, and // contains the intrinsic %PromisePrototype%, and
// (c) we're not running with async_hooks or DevTools enabled. // (d) we're not running with async_hooks or DevTools enabled.
// //
// In that case we also don't need to allocate a chained promise for // In that case we also don't need to allocate a chained promise for
// the PromiseReaction (aka we can pass undefined to PerformPromiseThen), // the PromiseReaction (aka we can pass undefined to PerformPromiseThen),
...@@ -1970,6 +1973,7 @@ Node* PromiseBuiltinsAssembler::PerformPromiseAll( ...@@ -1970,6 +1973,7 @@ Node* PromiseBuiltinsAssembler::PerformPromiseAll(
&if_slow); &if_slow);
GotoIf(IsPromiseHookEnabledOrDebugIsActiveOrHasAsyncEventDelegate(), GotoIf(IsPromiseHookEnabledOrDebugIsActiveOrHasAsyncEventDelegate(),
&if_slow); &if_slow);
GotoIf(IsPromiseSpeciesProtectorCellInvalid(), &if_slow);
GotoIf(TaggedIsSmi(next_value), &if_slow); GotoIf(TaggedIsSmi(next_value), &if_slow);
Node* const next_value_map = LoadMap(next_value); Node* const next_value_map = LoadMap(next_value);
BranchIfPromiseThenLookupChainIntact(native_context, next_value_map, BranchIfPromiseThenLookupChainIntact(native_context, next_value_map,
......
// Copyright 2019 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --allow-natives-syntax
let speciesCounter = 0;
Object.defineProperty(Promise, Symbol.species, {
value: function(...args) {
speciesCounter++;
return new Promise(...args);
}
});
async function foo() { }
assertPromiseResult(Promise.all([foo()]), () => {
assertEquals(3, speciesCounter);
});
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment