[protectors] Move PromiseThenLookupChain protector to Protectors
Bug: v8:9463 Change-Id: Ife5ea730166e76bdbe8b18eac1eb5688b7aaf150 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1800513 Commit-Queue: Joshua Litt <joshualitt@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Cr-Commit-Position: refs/heads/master@{#63795}
This commit is contained in:
parent
bec49d81df
commit
7c9c1039b4
@ -3929,23 +3929,6 @@ bool Isolate::IsPromiseResolveLookupChainIntact() {
|
||||
return is_promise_resolve_protector_intact;
|
||||
}
|
||||
|
||||
bool Isolate::IsPromiseThenLookupChainIntact() {
|
||||
PropertyCell promise_then_cell = heap()->promise_then_protector();
|
||||
bool is_promise_then_protector_intact =
|
||||
Smi::ToInt(promise_then_cell.value()) == kProtectorValid;
|
||||
return is_promise_then_protector_intact;
|
||||
}
|
||||
|
||||
bool Isolate::IsPromiseThenLookupChainIntact(Handle<JSReceiver> receiver) {
|
||||
DisallowHeapAllocation no_gc;
|
||||
if (!receiver->IsJSPromise()) return false;
|
||||
if (!IsInAnyContext(receiver->map().prototype(),
|
||||
Context::PROMISE_PROTOTYPE_INDEX)) {
|
||||
return false;
|
||||
}
|
||||
return IsPromiseThenLookupChainIntact();
|
||||
}
|
||||
|
||||
void Isolate::UpdateNoElementsProtectorOnSetElement(Handle<JSObject> object) {
|
||||
DisallowHeapAllocation no_gc;
|
||||
if (!object->map().is_prototype_map()) return;
|
||||
@ -4059,15 +4042,6 @@ void Isolate::InvalidatePromiseResolveProtector() {
|
||||
DCHECK(!IsPromiseResolveLookupChainIntact());
|
||||
}
|
||||
|
||||
void Isolate::InvalidatePromiseThenProtector() {
|
||||
DCHECK(factory()->promise_then_protector()->value().IsSmi());
|
||||
DCHECK(IsPromiseThenLookupChainIntact());
|
||||
PropertyCell::SetValueWithInvalidation(
|
||||
this, "promise_then_protector", factory()->promise_then_protector(),
|
||||
handle(Smi::FromInt(kProtectorInvalid), this));
|
||||
DCHECK(!IsPromiseThenLookupChainIntact());
|
||||
}
|
||||
|
||||
bool Isolate::IsAnyInitialArrayPrototype(Handle<JSArray> array) {
|
||||
DisallowHeapAllocation no_gc;
|
||||
return IsInAnyContext(*array, Context::INITIAL_ARRAY_PROTOTYPE_INDEX);
|
||||
|
@ -1226,14 +1226,6 @@ class Isolate final : private HiddenFactory {
|
||||
// yeidls the initial Promise.resolve method.
|
||||
bool IsPromiseResolveLookupChainIntact();
|
||||
|
||||
// Make sure a lookup of "then" on any JSPromise whose [[Prototype]] is the
|
||||
// initial %PromisePrototype% yields the initial method. In addition this
|
||||
// protector also guards the negative lookup of "then" on the intrinsic
|
||||
// %ObjectPrototype%, meaning that such lookups are guaranteed to yield
|
||||
// undefined without triggering any side-effects.
|
||||
bool IsPromiseThenLookupChainIntact();
|
||||
bool IsPromiseThenLookupChainIntact(Handle<JSReceiver> receiver);
|
||||
|
||||
// On intent to set an element in object, make sure that appropriate
|
||||
// notifications occur if the set is on the elements of the array or
|
||||
// object prototype. Also ensure that changes to prototype chain between
|
||||
@ -1252,8 +1244,6 @@ class Isolate final : private HiddenFactory {
|
||||
// The `protector_name` C string must be statically allocated.
|
||||
void TraceProtectorInvalidation(const char* protector_name);
|
||||
|
||||
void InvalidateArrayConstructorProtector();
|
||||
void InvalidateRegExpSpeciesProtector(Handle<NativeContext> native_context);
|
||||
void InvalidateIsConcatSpreadableProtector();
|
||||
void InvalidateStringLengthOverflowProtector();
|
||||
void InvalidateArrayIteratorProtector();
|
||||
@ -1263,7 +1253,6 @@ class Isolate final : private HiddenFactory {
|
||||
void InvalidateArrayBufferDetachingProtector();
|
||||
V8_EXPORT_PRIVATE void InvalidatePromiseHookProtector();
|
||||
void InvalidatePromiseResolveProtector();
|
||||
void InvalidatePromiseThenProtector();
|
||||
|
||||
// Returns true if array is the initial array prototype in any native context.
|
||||
bool IsAnyInitialArrayPrototype(Handle<JSArray> array);
|
||||
|
@ -21,6 +21,7 @@ class Protectors : public AllStatic {
|
||||
#define DECLARED_PROTECTORS_ON_ISOLATE(V) \
|
||||
V(ArraySpeciesLookupChain, ArraySpeciesProtector, array_species_protector) \
|
||||
V(ArrayConstructor, ArrayConstructorProtector, array_constructor_protector) \
|
||||
V(PromiseThenLookupChain, PromiseThenProtector, promise_then_protector) \
|
||||
V(PromiseSpeciesLookupChain, PromiseSpeciesProtector, \
|
||||
promise_species_protector) \
|
||||
V(TypedArraySpeciesLookupChain, TypedArraySpeciesProtector, \
|
||||
|
@ -419,7 +419,7 @@ void LookupIterator::InternalUpdateProtector() {
|
||||
isolate_->InvalidatePromiseResolveProtector();
|
||||
}
|
||||
} else if (*name_ == roots.then_string()) {
|
||||
if (!isolate_->IsPromiseThenLookupChainIntact()) return;
|
||||
if (!Protectors::IsPromiseThenLookupChainIntact(isolate_)) return;
|
||||
// Setting the "then" property on any JSPromise instance or on the
|
||||
// initial %PromisePrototype% invalidates the Promise#then protector.
|
||||
// Also setting the "then" property on the initial %ObjectPrototype%
|
||||
@ -431,7 +431,7 @@ void LookupIterator::InternalUpdateProtector() {
|
||||
isolate_->IsInAnyContext(*receiver,
|
||||
Context::INITIAL_OBJECT_PROTOTYPE_INDEX) ||
|
||||
isolate_->IsInAnyContext(*receiver, Context::PROMISE_PROTOTYPE_INDEX)) {
|
||||
isolate_->InvalidatePromiseThenProtector();
|
||||
Protectors::InvalidatePromiseThenLookupChain(isolate_);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5886,17 +5886,25 @@ MaybeHandle<Object> JSPromise::Resolve(Handle<JSPromise> promise,
|
||||
|
||||
// 8. Let then be Get(resolution, "then").
|
||||
MaybeHandle<Object> then;
|
||||
if (isolate->IsPromiseThenLookupChainIntact(
|
||||
Handle<JSReceiver>::cast(resolution))) {
|
||||
Handle<JSReceiver> receiver(Handle<JSReceiver>::cast(resolution));
|
||||
|
||||
// Make sure a lookup of "then" on any JSPromise whose [[Prototype]] is the
|
||||
// initial %PromisePrototype% yields the initial method. In addition this
|
||||
// protector also guards the negative lookup of "then" on the intrinsic
|
||||
// %ObjectPrototype%, meaning that such lookups are guaranteed to yield
|
||||
// undefined without triggering any side-effects.
|
||||
if (receiver->IsJSPromise() &&
|
||||
isolate->IsInAnyContext(receiver->map().prototype(),
|
||||
Context::PROMISE_PROTOTYPE_INDEX) &&
|
||||
Protectors::IsPromiseThenLookupChainIntact(isolate)) {
|
||||
// We can skip the "then" lookup on {resolution} if its [[Prototype]]
|
||||
// is the (initial) Promise.prototype and the Promise#then protector
|
||||
// is intact, as that guards the lookup path for the "then" property
|
||||
// on JSPromise instances which have the (initial) %PromisePrototype%.
|
||||
then = isolate->promise_then();
|
||||
} else {
|
||||
then =
|
||||
JSReceiver::GetProperty(isolate, Handle<JSReceiver>::cast(resolution),
|
||||
isolate->factory()->then_string());
|
||||
then = JSReceiver::GetProperty(isolate, receiver,
|
||||
isolate->factory()->then_string());
|
||||
}
|
||||
|
||||
// 9. If then is an abrupt completion, then
|
||||
|
Loading…
Reference in New Issue
Block a user