1 // Copyright 2019 the V8 project authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef V8_EXECUTION_PROTECTORS_H_ 6 #define V8_EXECUTION_PROTECTORS_H_ 7 8 #include "src/handles/handles.h" 9 10 namespace v8 { 11 namespace internal { 12 13 class Protectors : public AllStatic { 14 public: 15 static const int kProtectorValid = 1; 16 static const int kProtectorInvalid = 0; 17 18 #define DECLARED_PROTECTORS_ON_ISOLATE(V) \ 19 V(ArrayBufferDetaching, ArrayBufferDetachingProtector, \ 20 array_buffer_detaching_protector) \ 21 V(ArrayConstructor, ArrayConstructorProtector, array_constructor_protector) \ 22 V(ArrayIteratorLookupChain, ArrayIteratorProtector, \ 23 array_iterator_protector) \ 24 V(ArraySpeciesLookupChain, ArraySpeciesProtector, array_species_protector) \ 25 V(IsConcatSpreadableLookupChain, IsConcatSpreadableProtector, \ 26 is_concat_spreadable_protector) \ 27 V(NoElements, NoElementsProtector, no_elements_protector) \ 28 \ 29 /* The MapIterator protector protects the original iteration behaviors */ \ 30 /* of Map.prototype.keys(), Map.prototype.values(), and */ \ 31 /* Set.prototype.entries(). It does not protect the original iteration */ \ 32 /* behavior of Map.prototype[Symbol.iterator](). */ \ 33 /* The protector is invalidated when: */ \ 34 /* * The 'next' property is set on an object where the property holder */ \ 35 /* is the %MapIteratorPrototype% (e.g. because the object is that very */ \ 36 /* prototype). */ \ 37 /* * The 'Symbol.iterator' property is set on an object where the */ \ 38 /* property holder is the %IteratorPrototype%. Note that this also */ \ 39 /* invalidates the SetIterator protector (see below). */ \ 40 V(MapIteratorLookupChain, MapIteratorProtector, map_iterator_protector) \ 41 V(RegExpSpeciesLookupChain, RegExpSpeciesProtector, \ 42 regexp_species_protector) \ 43 V(PromiseHook, PromiseHookProtector, promise_hook_protector) \ 44 V(PromiseThenLookupChain, PromiseThenProtector, promise_then_protector) \ 45 V(PromiseResolveLookupChain, PromiseResolveProtector, \ 46 promise_resolve_protector) \ 47 V(PromiseSpeciesLookupChain, PromiseSpeciesProtector, \ 48 promise_species_protector) \ 49 \ 50 /* The SetIterator protector protects the original iteration behavior of */ \ 51 /* Set.prototype.keys(), Set.prototype.values(), */ \ 52 /* Set.prototype.entries(), and Set.prototype[Symbol.iterator](). The */ \ 53 /* protector is invalidated when: */ \ 54 /* * The 'next' property is set on an object where the property holder */ \ 55 /* is the %SetIteratorPrototype% (e.g. because the object is that very */ \ 56 /* prototype). */ \ 57 /* * The 'Symbol.iterator' property is set on an object where the */ \ 58 /* property holder is the %SetPrototype% OR %IteratorPrototype%. This */ \ 59 /* means that setting Symbol.iterator on a MapIterator object can also */ \ 60 /* invalidate the SetIterator protector, and vice versa, setting */ \ 61 /* Symbol.iterator on a SetIterator object can also invalidate the */ \ 62 /* MapIterator. This is an over-approximation for the sake of */ \ 63 /* simplicity. */ \ 64 V(SetIteratorLookupChain, SetIteratorProtector, set_iterator_protector) \ 65 \ 66 /* The StringIteratorProtector protects the original string iteration */ \ 67 /* behavior for primitive strings. As long as the */ \ 68 /* StringIteratorProtector is valid, iterating over a primitive string */ \ 69 /* is guaranteed to be unobservable from user code and can thus be cut */ \ 70 /* short. More specifically, the protector gets invalidated as soon as */ \ 71 /* either String.prototype[Symbol.iterator] or */ \ 72 /* String.prototype[Symbol.iterator]().next is modified. This guarantee */ \ 73 /* does not apply to string objects (as opposed to primitives), since */ \ 74 /* they could define their own Symbol.iterator. */ \ 75 /* String.prototype itself does not need to be protected, since it is */ \ 76 /* non-configurable and non-writable. */ \ 77 V(StringIteratorLookupChain, StringIteratorProtector, \ 78 string_iterator_protector) \ 79 V(StringLengthOverflowLookupChain, StringLengthProtector, \ 80 string_length_protector) \ 81 V(TypedArraySpeciesLookupChain, TypedArraySpeciesProtector, \ 82 typed_array_species_protector) 83 84 #define DECLARE_PROTECTOR_ON_ISOLATE(name, unused_root_index, unused_cell) \ 85 V8_EXPORT_PRIVATE static inline bool Is##name##Intact(Isolate* isolate); \ 86 V8_EXPORT_PRIVATE static void Invalidate##name(Isolate* isolate); 87 DECLARED_PROTECTORS_ON_ISOLATE(DECLARE_PROTECTOR_ON_ISOLATE) 88 #undef DECLARE_PROTECTOR_ON_ISOLATE 89 }; 90 91 } // namespace internal 92 } // namespace v8 93 94 #endif // V8_EXECUTION_PROTECTORS_H_ 95