@@ -120,6 +120,23 @@ constexpr bool HeapSandboxIsEnabled() {
120
120
121
121
using ExternalPointer_t = Address;
122
122
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
+
123
140
#ifdef V8_31BIT_SMIS_ON_64BIT_ARCH
124
141
using PlatformSmiTagging = SmiTagging<kApiInt32Size >;
125
142
#else
@@ -140,6 +157,20 @@ V8_INLINE static constexpr internal::Address IntToSmi(int value) {
140
157
kSmiTag ;
141
158
}
142
159
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
+
143
174
/* *
144
175
* This class exports constants and functionality from within v8 that
145
176
* is necessary to implement inline functions in the v8 api. Don't
@@ -159,6 +190,9 @@ class Internals {
159
190
static const int kFixedArrayHeaderSize = 2 * kApiTaggedSize ;
160
191
static const int kEmbedderDataArrayHeaderSize = 2 * kApiTaggedSize ;
161
192
static const int kEmbedderDataSlotSize = kApiSystemPointerSize ;
193
+ #ifdef V8_HEAP_SANDBOX
194
+ static const int kEmbedderDataSlotRawPayloadOffset = kApiTaggedSize ;
195
+ #endif
162
196
static const int kNativeContextEmbedderDataOffset = 6 * kApiTaggedSize ;
163
197
static const int kFullStringRepresentationMask = 0x0f ;
164
198
static const int kStringEncodingMask = 0x8 ;
@@ -169,21 +203,21 @@ class Internals {
169
203
170
204
// IsolateData layout guarantees.
171
205
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 ;
178
206
static const int kIsolateFastCCallCallerFpOffset =
179
- kExternalMemoryLowSinceMarkCompactOffset + kApiInt64Size ;
207
+ kNumIsolateDataSlots * kApiSystemPointerSize ;
180
208
static const int kIsolateFastCCallCallerPcOffset =
181
209
kIsolateFastCCallCallerFpOffset + kApiSystemPointerSize ;
182
210
static const int kIsolateStackGuardOffset =
183
211
kIsolateFastCCallCallerPcOffset + kApiSystemPointerSize ;
184
212
static const int kIsolateRootsOffset =
185
213
kIsolateStackGuardOffset + 7 * kApiSystemPointerSize ;
186
214
215
+ static const int kExternalPointerTableBufferOffset = 0 ;
216
+ static const int kExternalPointerTableLengthOffset =
217
+ kExternalPointerTableBufferOffset + kApiSystemPointerSize ;
218
+ static const int kExternalPointerTableCapacityOffset =
219
+ kExternalPointerTableLengthOffset + kApiInt32Size ;
220
+
187
221
static const int kUndefinedValueRootIndex = 4 ;
188
222
static const int kTheHoleValueRootIndex = 5 ;
189
223
static const int kNullValueRootIndex = 6 ;
@@ -339,16 +373,37 @@ class Internals {
339
373
#endif
340
374
}
341
375
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
+
342
396
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);
347
402
// 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 ;
350
405
#else
351
- return ReadRawField<internal:: Address>(heap_object_ptr, offset);
406
+ return ReadRawField<Address>(heap_object_ptr, offset);
352
407
#endif
353
408
}
354
409
@@ -357,10 +412,6 @@ class Internals {
357
412
static constexpr size_t kPtrComprHeapReservationSize = size_t {1 } << 32 ;
358
413
static constexpr size_t kPtrComprIsolateRootAlignment = size_t {1 } << 32 ;
359
414
360
- // See v8:10391 for details about V8 heap sandbox.
361
- static constexpr uint32_t kExternalPointerSalt =
362
- 0x7fffffff & ~static_cast <uint32_t >(kHeapObjectTagMask );
363
-
364
415
V8_INLINE static internal::Address GetRootFromOnHeapAddress (
365
416
internal::Address addr) {
366
417
return addr & -static_cast <intptr_t >(kPtrComprIsolateRootAlignment );
@@ -372,14 +423,6 @@ class Internals {
372
423
return root + static_cast <internal::Address>(static_cast <uintptr_t >(value));
373
424
}
374
425
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
- }
383
426
#endif // V8_COMPRESS_POINTERS
384
427
};
385
428
@@ -403,18 +446,10 @@ void CastCheck<false>::Perform(T* data) {}
403
446
404
447
template <class T >
405
448
V8_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);
407
451
}
408
452
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
-
418
453
// A base class for backing stores, which is needed due to vagaries of
419
454
// how static casts work with std::shared_ptr.
420
455
class BackingStoreBase {};
0 commit comments