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