// 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. #ifndef V8_EXECUTION_PROTECTORS_H_ #define V8_EXECUTION_PROTECTORS_H_ #include "src/handles/handles.h" namespace v8 { namespace internal { class Protectors : public AllStatic { public: static const int kProtectorValid = 1; static const int kProtectorInvalid = 0; #define DECLARED_PROTECTORS_ON_ISOLATE(V) \ V(ArrayBufferDetaching, ArrayBufferDetachingProtector, \ array_buffer_detaching_protector) \ V(ArrayConstructor, ArrayConstructorProtector, array_constructor_protector) \ V(ArrayIteratorLookupChain, ArrayIteratorProtector, \ array_iterator_protector) \ V(ArraySpeciesLookupChain, ArraySpeciesProtector, array_species_protector) \ V(IsConcatSpreadableLookupChain, IsConcatSpreadableProtector, \ is_concat_spreadable_protector) \ V(NoElements, NoElementsProtector, no_elements_protector) \ \ /* The MapIterator protector protects the original iteration behaviors */ \ /* of Map.prototype.keys(), Map.prototype.values(), and */ \ /* Set.prototype.entries(). It does not protect the original iteration */ \ /* behavior of Map.prototype[Symbol.iterator](). */ \ /* The protector is invalidated when: */ \ /* * The 'next' property is set on an object where the property holder */ \ /* is the %MapIteratorPrototype% (e.g. because the object is that very */ \ /* prototype). */ \ /* * The 'Symbol.iterator' property is set on an object where the */ \ /* property holder is the %IteratorPrototype%. Note that this also */ \ /* invalidates the SetIterator protector (see below). */ \ V(MapIteratorLookupChain, MapIteratorProtector, map_iterator_protector) \ V(RegExpSpeciesLookupChain, RegExpSpeciesProtector, \ regexp_species_protector) \ V(PromiseHook, PromiseHookProtector, promise_hook_protector) \ V(PromiseThenLookupChain, PromiseThenProtector, promise_then_protector) \ V(PromiseResolveLookupChain, PromiseResolveProtector, \ promise_resolve_protector) \ V(PromiseSpeciesLookupChain, PromiseSpeciesProtector, \ promise_species_protector) \ \ /* The SetIterator protector protects the original iteration behavior of */ \ /* Set.prototype.keys(), Set.prototype.values(), */ \ /* Set.prototype.entries(), and Set.prototype[Symbol.iterator](). The */ \ /* protector is invalidated when: */ \ /* * The 'next' property is set on an object where the property holder */ \ /* is the %SetIteratorPrototype% (e.g. because the object is that very */ \ /* prototype). */ \ /* * The 'Symbol.iterator' property is set on an object where the */ \ /* property holder is the %SetPrototype% OR %IteratorPrototype%. This */ \ /* means that setting Symbol.iterator on a MapIterator object can also */ \ /* invalidate the SetIterator protector, and vice versa, setting */ \ /* Symbol.iterator on a SetIterator object can also invalidate the */ \ /* MapIterator. This is an over-approximation for the sake of */ \ /* simplicity. */ \ V(SetIteratorLookupChain, SetIteratorProtector, set_iterator_protector) \ \ /* The StringIteratorProtector protects the original string iteration */ \ /* behavior for primitive strings. As long as the */ \ /* StringIteratorProtector is valid, iterating over a primitive string */ \ /* is guaranteed to be unobservable from user code and can thus be cut */ \ /* short. More specifically, the protector gets invalidated as soon as */ \ /* either String.prototype[Symbol.iterator] or */ \ /* String.prototype[Symbol.iterator]().next is modified. This guarantee */ \ /* does not apply to string objects (as opposed to primitives), since */ \ /* they could define their own Symbol.iterator. */ \ /* String.prototype itself does not need to be protected, since it is */ \ /* non-configurable and non-writable. */ \ V(StringIteratorLookupChain, StringIteratorProtector, \ string_iterator_protector) \ V(StringLengthOverflowLookupChain, StringLengthProtector, \ string_length_protector) \ V(TypedArraySpeciesLookupChain, TypedArraySpeciesProtector, \ typed_array_species_protector) #define DECLARE_PROTECTOR_ON_ISOLATE(name, unused_root_index, unused_cell) \ V8_EXPORT_PRIVATE static inline bool Is##name##Intact(Isolate* isolate); \ V8_EXPORT_PRIVATE static void Invalidate##name(Isolate* isolate); DECLARED_PROTECTORS_ON_ISOLATE(DECLARE_PROTECTOR_ON_ISOLATE) #undef DECLARE_PROTECTOR_ON_ISOLATE }; } // namespace internal } // namespace v8 #endif // V8_EXECUTION_PROTECTORS_H_