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// This file contains implementations of a few macros that are defined
6// as external in Torque, so that generated debug code can work.
7
8#ifndef V8_TORQUE_DEBUG_MACRO_SHIMS_H_
9#define V8_TORQUE_DEBUG_MACRO_SHIMS_H_
10
11#include "src/numbers/integer-literal.h"
12#include "src/objects/smi.h"
13#include "tools/debug_helper/debug-helper-internal.h"
14
15// For Object::ReadField<T>.
16#define READ_FIELD_OR_FAIL(Type, destination, accessor, object, offset) \
17  do {                                                                  \
18    Type value{};                                                       \
19    d::MemoryAccessResult validity =                                    \
20        accessor(object - kHeapObjectTag + offset,                      \
21                 reinterpret_cast<Type*>(&value), sizeof(value));       \
22    if (validity != d::MemoryAccessResult::kOk) return {validity, {}};  \
23    destination = value;                                                \
24  } while (false)
25
26// For TaggedField<T>::load.
27#define READ_TAGGED_FIELD_OR_FAIL(destination, accessor, object, offset) \
28  do {                                                                   \
29    Tagged_t value{};                                                    \
30    d::MemoryAccessResult validity =                                     \
31        accessor(object - kHeapObjectTag + offset,                       \
32                 reinterpret_cast<uint8_t*>(&value), sizeof(value));     \
33    if (validity != d::MemoryAccessResult::kOk) return {validity, {}};   \
34    destination = EnsureDecompressed(value, object);                     \
35  } while (false)
36
37// Process Value struct.
38#define ASSIGN_OR_RETURN(dest, val)                   \
39  do {                                                \
40    if ((val).validity != d::MemoryAccessResult::kOk) \
41      return {(val).validity, {}};                    \
42    dest = (val).value;                               \
43  } while (false)
44
45namespace v8 {
46namespace internal {
47namespace debug_helper_internal {
48namespace TorqueDebugMacroShims {
49namespace CodeStubAssembler {
50
51inline Value<bool> BoolConstant(d::MemoryAccessor accessor, bool b) {
52  return {d::MemoryAccessResult::kOk, b};
53}
54inline Value<intptr_t> ChangeInt32ToIntPtr(d::MemoryAccessor accessor,
55                                           int32_t i) {
56  return {d::MemoryAccessResult::kOk, i};
57}
58inline Value<uintptr_t> ChangeUint32ToWord(d::MemoryAccessor accessor,
59                                           uint32_t u) {
60  return {d::MemoryAccessResult::kOk, u};
61}
62inline Value<intptr_t> IntPtrAdd(d::MemoryAccessor accessor, intptr_t a,
63                                 intptr_t b) {
64  return {d::MemoryAccessResult::kOk, a + b};
65}
66inline Value<intptr_t> IntPtrMul(d::MemoryAccessor accessor, intptr_t a,
67                                 intptr_t b) {
68  return {d::MemoryAccessResult::kOk, a * b};
69}
70inline Value<bool> IntPtrLessThan(d::MemoryAccessor accessor, intptr_t a,
71                                  intptr_t b) {
72  return {d::MemoryAccessResult::kOk, a < b};
73}
74inline Value<bool> IntPtrLessThanOrEqual(d::MemoryAccessor accessor, intptr_t a,
75                                         intptr_t b) {
76  return {d::MemoryAccessResult::kOk, a <= b};
77}
78inline Value<intptr_t> Signed(d::MemoryAccessor accessor, uintptr_t u) {
79  return {d::MemoryAccessResult::kOk, static_cast<intptr_t>(u)};
80}
81inline Value<int32_t> SmiUntag(d::MemoryAccessor accessor, uintptr_t s_t) {
82  Smi s(s_t);
83  return {d::MemoryAccessResult::kOk, s.value()};
84}
85inline Value<uintptr_t> SmiFromInt32(d::MemoryAccessor accessor, int32_t i) {
86  return {d::MemoryAccessResult::kOk, Smi::FromInt(i).ptr()};
87}
88inline Value<bool> UintPtrLessThan(d::MemoryAccessor accessor, uintptr_t a,
89                                   uintptr_t b) {
90  return {d::MemoryAccessResult::kOk, a < b};
91}
92inline Value<uint32_t> Unsigned(d::MemoryAccessor accessor, int32_t s) {
93  return {d::MemoryAccessResult::kOk, static_cast<uint32_t>(s)};
94}
95#if V8_HOST_ARCH_64_BIT
96inline Value<uintptr_t> Unsigned(d::MemoryAccessor accessor, intptr_t s) {
97  return {d::MemoryAccessResult::kOk, static_cast<uintptr_t>(s)};
98}
99#endif
100inline Value<bool> Word32Equal(d::MemoryAccessor accessor, uint32_t a,
101                               uint32_t b) {
102  return {d::MemoryAccessResult::kOk, a == b};
103}
104inline Value<bool> Word32NotEqual(d::MemoryAccessor accessor, uint32_t a,
105                                  uint32_t b) {
106  return {d::MemoryAccessResult::kOk, a != b};
107}
108// This is used in a nested call where we cannot pass Value<int32_t>.
109inline int31_t ConstexprIntegerLiteralToInt31(d::MemoryAccessor accessor,
110                                              const IntegerLiteral& i) {
111  return i.To<int32_t>();
112}
113inline int32_t ConstexprIntegerLiteralToInt32(d::MemoryAccessor accessor,
114                                              const IntegerLiteral& i) {
115  return i.To<int32_t>();
116}
117inline intptr_t ConstexprIntegerLiteralToIntptr(d::MemoryAccessor accessor,
118                                                const IntegerLiteral& i) {
119  return i.To<intptr_t>();
120}
121
122}  // namespace CodeStubAssembler
123}  // namespace TorqueDebugMacroShims
124}  // namespace debug_helper_internal
125}  // namespace internal
126}  // namespace v8
127
128#endif  // V8_TORQUE_DEBUG_MACRO_SHIMS_H_
129