@@ -120,6 +120,23 @@ constexpr bool HeapSandboxIsEnabled() {
120120
121121using ExternalPointer_t = Address;
122122
123+ // If the heap sandbox is enabled, these tag values will be XORed with the
124+ // external pointers in the external pointer table to prevent use of pointers of
125+ // the wrong type.
126+ enum ExternalPointerTag : Address {
127+ kExternalPointerNullTag = static_cast <Address>(0ULL ),
128+ kArrayBufferBackingStoreTag = static_cast <Address>(1ULL << 48 ),
129+ kTypedArrayExternalPointerTag = static_cast <Address>(2ULL << 48 ),
130+ kDataViewDataPointerTag = static_cast <Address>(3ULL << 48 ),
131+ kExternalStringResourceTag = static_cast <Address>(4ULL << 48 ),
132+ kExternalStringResourceDataTag = static_cast <Address>(5ULL << 48 ),
133+ kForeignForeignAddressTag = static_cast <Address>(6ULL << 48 ),
134+ kNativeContextMicrotaskQueueTag = static_cast <Address>(7ULL << 48 ),
135+ // TODO(v8:10391, saelo): Currently has to be zero so that raw zero values are
136+ // also nullptr
137+ kEmbedderDataSlotPayloadTag = static_cast <Address>(0ULL << 48 ),
138+ };
139+
123140#ifdef V8_31BIT_SMIS_ON_64BIT_ARCH
124141using PlatformSmiTagging = SmiTagging<kApiInt32Size >;
125142#else
@@ -140,6 +157,20 @@ V8_INLINE static constexpr internal::Address IntToSmi(int value) {
140157 kSmiTag ;
141158}
142159
160+ // Converts encoded external pointer to address.
161+ V8_EXPORT Address DecodeExternalPointerImpl (const Isolate* isolate,
162+ ExternalPointer_t pointer,
163+ ExternalPointerTag tag);
164+
165+ // {obj} must be the raw tagged pointer representation of a HeapObject
166+ // that's guaranteed to never be in ReadOnlySpace.
167+ V8_EXPORT internal::Isolate* IsolateFromNeverReadOnlySpaceObject (Address obj);
168+
169+ // Returns if we need to throw when an error occurs. This infers the language
170+ // mode based on the current context and the closure. This returns true if the
171+ // language mode is strict.
172+ V8_EXPORT bool ShouldThrowOnError (v8::internal::Isolate* isolate);
173+
143174/* *
144175 * This class exports constants and functionality from within v8 that
145176 * is necessary to implement inline functions in the v8 api. Don't
@@ -159,6 +190,9 @@ class Internals {
159190 static const int kFixedArrayHeaderSize = 2 * kApiTaggedSize ;
160191 static const int kEmbedderDataArrayHeaderSize = 2 * kApiTaggedSize ;
161192 static const int kEmbedderDataSlotSize = kApiSystemPointerSize ;
193+ #ifdef V8_HEAP_SANDBOX
194+ static const int kEmbedderDataSlotRawPayloadOffset = kApiTaggedSize ;
195+ #endif
162196 static const int kNativeContextEmbedderDataOffset = 6 * kApiTaggedSize ;
163197 static const int kFullStringRepresentationMask = 0x0f ;
164198 static const int kStringEncodingMask = 0x8 ;
@@ -169,21 +203,21 @@ class Internals {
169203
170204 // IsolateData layout guarantees.
171205 static const int kIsolateEmbedderDataOffset = 0 ;
172- static const int kExternalMemoryOffset =
173- kNumIsolateDataSlots * kApiSystemPointerSize ;
174- static const int kExternalMemoryLimitOffset =
175- kExternalMemoryOffset + kApiInt64Size ;
176- static const int kExternalMemoryLowSinceMarkCompactOffset =
177- kExternalMemoryLimitOffset + kApiInt64Size ;
178206 static const int kIsolateFastCCallCallerFpOffset =
179- kExternalMemoryLowSinceMarkCompactOffset + kApiInt64Size ;
207+ kNumIsolateDataSlots * kApiSystemPointerSize ;
180208 static const int kIsolateFastCCallCallerPcOffset =
181209 kIsolateFastCCallCallerFpOffset + kApiSystemPointerSize ;
182210 static const int kIsolateStackGuardOffset =
183211 kIsolateFastCCallCallerPcOffset + kApiSystemPointerSize ;
184212 static const int kIsolateRootsOffset =
185213 kIsolateStackGuardOffset + 7 * kApiSystemPointerSize ;
186214
215+ static const int kExternalPointerTableBufferOffset = 0 ;
216+ static const int kExternalPointerTableLengthOffset =
217+ kExternalPointerTableBufferOffset + kApiSystemPointerSize ;
218+ static const int kExternalPointerTableCapacityOffset =
219+ kExternalPointerTableLengthOffset + kApiInt32Size ;
220+
187221 static const int kUndefinedValueRootIndex = 4 ;
188222 static const int kTheHoleValueRootIndex = 5 ;
189223 static const int kNullValueRootIndex = 6 ;
@@ -339,16 +373,37 @@ class Internals {
339373#endif
340374 }
341375
376+ V8_INLINE static internal::Isolate* GetIsolateForHeapSandbox (
377+ internal::Address obj) {
378+ #ifdef V8_HEAP_SANDBOX
379+ return internal::IsolateFromNeverReadOnlySpaceObject (obj);
380+ #else
381+ // Not used in non-sandbox mode.
382+ return nullptr ;
383+ #endif
384+ }
385+
386+ V8_INLINE static Address DecodeExternalPointer (
387+ const Isolate* isolate, ExternalPointer_t encoded_pointer,
388+ ExternalPointerTag tag) {
389+ #ifdef V8_HEAP_SANDBOX
390+ return internal::DecodeExternalPointerImpl (isolate, encoded_pointer, tag);
391+ #else
392+ return encoded_pointer;
393+ #endif
394+ }
395+
342396 V8_INLINE static internal::Address ReadExternalPointerField (
343- internal::Isolate* isolate, internal::Address heap_object_ptr,
344- int offset) {
345- #ifdef V8_COMPRESS_POINTERS
346- internal::Address value = ReadRawField<Address>(heap_object_ptr, offset);
397+ internal::Isolate* isolate, internal::Address heap_object_ptr, int offset,
398+ ExternalPointerTag tag) {
399+ #ifdef V8_HEAP_SANDBOX
400+ internal::ExternalPointer_t encoded_value =
401+ ReadRawField<uint32_t >(heap_object_ptr, offset);
347402 // We currently have to treat zero as nullptr in embedder slots.
348- if (value) value = DecodeExternalPointer (isolate, value);
349- return value ;
403+ return encoded_value ? DecodeExternalPointer (isolate, encoded_value, tag)
404+ : 0 ;
350405#else
351- return ReadRawField<internal:: Address>(heap_object_ptr, offset);
406+ return ReadRawField<Address>(heap_object_ptr, offset);
352407#endif
353408 }
354409
@@ -357,10 +412,6 @@ class Internals {
357412 static constexpr size_t kPtrComprHeapReservationSize = size_t {1 } << 32 ;
358413 static constexpr size_t kPtrComprIsolateRootAlignment = size_t {1 } << 32 ;
359414
360- // See v8:10391 for details about V8 heap sandbox.
361- static constexpr uint32_t kExternalPointerSalt =
362- 0x7fffffff & ~static_cast <uint32_t >(kHeapObjectTagMask );
363-
364415 V8_INLINE static internal::Address GetRootFromOnHeapAddress (
365416 internal::Address addr) {
366417 return addr & -static_cast <intptr_t >(kPtrComprIsolateRootAlignment );
@@ -372,14 +423,6 @@ class Internals {
372423 return root + static_cast <internal::Address>(static_cast <uintptr_t >(value));
373424 }
374425
375- V8_INLINE static Address DecodeExternalPointer (
376- const Isolate* isolate, ExternalPointer_t encoded_pointer) {
377- #ifndef V8_HEAP_SANDBOX
378- return encoded_pointer;
379- #else
380- return encoded_pointer ^ kExternalPointerSalt ;
381- #endif
382- }
383426#endif // V8_COMPRESS_POINTERS
384427};
385428
@@ -403,18 +446,10 @@ void CastCheck<false>::Perform(T* data) {}
403446
404447template <class T >
405448V8_INLINE void PerformCastCheck (T* data) {
406- CastCheck<std::is_base_of<Data, T>::value>::Perform (data);
449+ CastCheck<std::is_base_of<Data, T>::value &&
450+ !std::is_same<Data, std::remove_cv_t <T>>::value>::Perform (data);
407451}
408452
409- // {obj} must be the raw tagged pointer representation of a HeapObject
410- // that's guaranteed to never be in ReadOnlySpace.
411- V8_EXPORT internal::Isolate* IsolateFromNeverReadOnlySpaceObject (Address obj);
412-
413- // Returns if we need to throw when an error occurs. This infers the language
414- // mode based on the current context and the closure. This returns true if the
415- // language mode is strict.
416- V8_EXPORT bool ShouldThrowOnError (v8::internal::Isolate* isolate);
417-
418453// A base class for backing stores, which is needed due to vagaries of
419454// how static casts work with std::shared_ptr.
420455class BackingStoreBase {};
0 commit comments