1// Copyright 2020 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_SANDBOX_EXTERNAL_POINTER_INL_H_ 6#define V8_SANDBOX_EXTERNAL_POINTER_INL_H_ 7 8#include "include/v8-internal.h" 9#include "src/execution/isolate.h" 10#include "src/sandbox/external-pointer-table-inl.h" 11#include "src/sandbox/external-pointer.h" 12 13namespace v8 { 14namespace internal { 15 16V8_INLINE Address DecodeExternalPointer(const Isolate* isolate, 17 ExternalPointer_t encoded_pointer, 18 ExternalPointerTag tag) { 19#ifdef V8_SANDBOXED_EXTERNAL_POINTERS 20 STATIC_ASSERT(kExternalPointerSize == kInt32Size); 21 uint32_t index = encoded_pointer >> kExternalPointerIndexShift; 22 return isolate->external_pointer_table().Get(index, tag); 23#else 24 STATIC_ASSERT(kExternalPointerSize == kSystemPointerSize); 25 return encoded_pointer; 26#endif 27} 28 29V8_INLINE void InitExternalPointerField(Address field_address, Isolate* isolate, 30 ExternalPointerTag tag) { 31 InitExternalPointerField(field_address, isolate, kNullExternalPointer, tag); 32} 33 34V8_INLINE void InitExternalPointerField(Address field_address, Isolate* isolate, 35 Address value, ExternalPointerTag tag) { 36#ifdef V8_SANDBOXED_EXTERNAL_POINTERS 37 ExternalPointer_t index = isolate->external_pointer_table().Allocate(); 38 isolate->external_pointer_table().Set(index, value, tag); 39 index <<= kExternalPointerIndexShift; 40 base::Memory<ExternalPointer_t>(field_address) = index; 41#else 42 // Pointer compression causes types larger than kTaggedSize to be unaligned. 43 constexpr bool v8_pointer_compression_unaligned = 44 kExternalPointerSize > kTaggedSize; 45 ExternalPointer_t encoded_value = static_cast<ExternalPointer_t>(value); 46 if (v8_pointer_compression_unaligned) { 47 base::WriteUnalignedValue<ExternalPointer_t>(field_address, encoded_value); 48 } else { 49 base::Memory<ExternalPointer_t>(field_address) = encoded_value; 50 } 51#endif // V8_SANDBOXED_EXTERNAL_POINTERS 52} 53 54V8_INLINE ExternalPointer_t ReadRawExternalPointerField(Address field_address) { 55 // Pointer compression causes types larger than kTaggedSize to be unaligned. 56 constexpr bool v8_pointer_compression_unaligned = 57 kExternalPointerSize > kTaggedSize; 58 if (v8_pointer_compression_unaligned) { 59 return base::ReadUnalignedValue<ExternalPointer_t>(field_address); 60 } else { 61 return base::Memory<ExternalPointer_t>(field_address); 62 } 63} 64 65V8_INLINE Address ReadExternalPointerField(Address field_address, 66 const Isolate* isolate, 67 ExternalPointerTag tag) { 68 ExternalPointer_t encoded_value = ReadRawExternalPointerField(field_address); 69 return DecodeExternalPointer(isolate, encoded_value, tag); 70} 71 72V8_INLINE void WriteExternalPointerField(Address field_address, 73 Isolate* isolate, Address value, 74 ExternalPointerTag tag) { 75#ifdef V8_SANDBOXED_EXTERNAL_POINTERS 76 ExternalPointer_t index = base::Memory<ExternalPointer_t>(field_address); 77 index >>= kExternalPointerIndexShift; 78 isolate->external_pointer_table().Set(index, value, tag); 79#else 80 // Pointer compression causes types larger than kTaggedSize to be unaligned. 81 constexpr bool v8_pointer_compression_unaligned = 82 kExternalPointerSize > kTaggedSize; 83 ExternalPointer_t encoded_value = static_cast<ExternalPointer_t>(value); 84 if (v8_pointer_compression_unaligned) { 85 base::WriteUnalignedValue<ExternalPointer_t>(field_address, encoded_value); 86 } else { 87 base::Memory<ExternalPointer_t>(field_address) = encoded_value; 88 } 89#endif // V8_SANDBOXED_EXTERNAL_POINTERS 90} 91 92} // namespace internal 93} // namespace v8 94 95#endif // V8_SANDBOX_EXTERNAL_POINTER_INL_H_ 96