V8 API Reference, 7.2.502.16 (for Deno 0.2.4)
bytecode-node.h
1 // Copyright 2017 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_INTERPRETER_BYTECODE_NODE_H_
6 #define V8_INTERPRETER_BYTECODE_NODE_H_
7 
8 #include <algorithm>
9 
10 #include "src/globals.h"
11 #include "src/interpreter/bytecode-source-info.h"
12 #include "src/interpreter/bytecodes.h"
13 
14 namespace v8 {
15 namespace internal {
16 namespace interpreter {
17 
18 // A container for a generated bytecode, it's operands, and source information.
19 class V8_EXPORT_PRIVATE BytecodeNode final {
20  public:
21  V8_INLINE BytecodeNode(Bytecode bytecode,
22  BytecodeSourceInfo source_info = BytecodeSourceInfo())
23  : bytecode_(bytecode),
24  operand_count_(0),
25  operand_scale_(OperandScale::kSingle),
26  source_info_(source_info) {
27  DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), operand_count());
28  }
29 
30  V8_INLINE BytecodeNode(Bytecode bytecode, uint32_t operand0,
31  BytecodeSourceInfo source_info = BytecodeSourceInfo())
32  : bytecode_(bytecode),
33  operand_count_(1),
34  operand_scale_(OperandScale::kSingle),
35  source_info_(source_info) {
36  DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), operand_count());
37  SetOperand(0, operand0);
38  }
39 
40  V8_INLINE BytecodeNode(Bytecode bytecode, uint32_t operand0,
41  uint32_t operand1,
42  BytecodeSourceInfo source_info = BytecodeSourceInfo())
43  : bytecode_(bytecode),
44  operand_count_(2),
45  operand_scale_(OperandScale::kSingle),
46  source_info_(source_info) {
47  DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), operand_count());
48  SetOperand(0, operand0);
49  SetOperand(1, operand1);
50  }
51 
52  V8_INLINE BytecodeNode(Bytecode bytecode, uint32_t operand0,
53  uint32_t operand1, uint32_t operand2,
54  BytecodeSourceInfo source_info = BytecodeSourceInfo())
55  : bytecode_(bytecode),
56  operand_count_(3),
57  operand_scale_(OperandScale::kSingle),
58  source_info_(source_info) {
59  DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), operand_count());
60  SetOperand(0, operand0);
61  SetOperand(1, operand1);
62  SetOperand(2, operand2);
63  }
64 
65  V8_INLINE BytecodeNode(Bytecode bytecode, uint32_t operand0,
66  uint32_t operand1, uint32_t operand2,
67  uint32_t operand3,
68  BytecodeSourceInfo source_info = BytecodeSourceInfo())
69  : bytecode_(bytecode),
70  operand_count_(4),
71  operand_scale_(OperandScale::kSingle),
72  source_info_(source_info) {
73  DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), operand_count());
74  SetOperand(0, operand0);
75  SetOperand(1, operand1);
76  SetOperand(2, operand2);
77  SetOperand(3, operand3);
78  }
79 
80  V8_INLINE BytecodeNode(Bytecode bytecode, uint32_t operand0,
81  uint32_t operand1, uint32_t operand2,
82  uint32_t operand3, uint32_t operand4,
83  BytecodeSourceInfo source_info = BytecodeSourceInfo())
84  : bytecode_(bytecode),
85  operand_count_(5),
86  operand_scale_(OperandScale::kSingle),
87  source_info_(source_info) {
88  DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), operand_count());
89  SetOperand(0, operand0);
90  SetOperand(1, operand1);
91  SetOperand(2, operand2);
92  SetOperand(3, operand3);
93  SetOperand(4, operand4);
94  }
95 
96 #define DEFINE_BYTECODE_NODE_CREATOR(Name, ...) \
97  template <typename... Operands> \
98  V8_INLINE static BytecodeNode Name(BytecodeSourceInfo source_info, \
99  Operands... operands) { \
100  return Create<Bytecode::k##Name, __VA_ARGS__>(source_info, operands...); \
101  }
102  BYTECODE_LIST(DEFINE_BYTECODE_NODE_CREATOR)
103 #undef DEFINE_BYTECODE_NODE_CREATOR
104 
105  // Print to stream |os|.
106  void Print(std::ostream& os) const;
107 
108  Bytecode bytecode() const { return bytecode_; }
109 
110  uint32_t operand(int i) const {
111  DCHECK_LT(i, operand_count());
112  return operands_[i];
113  }
114  const uint32_t* operands() const { return operands_; }
115 
116  void update_operand0(uint32_t operand0) { SetOperand(0, operand0); }
117 
118  int operand_count() const { return operand_count_; }
119  OperandScale operand_scale() const { return operand_scale_; }
120 
121  const BytecodeSourceInfo& source_info() const { return source_info_; }
122  void set_source_info(BytecodeSourceInfo source_info) {
123  source_info_ = source_info;
124  }
125 
126  bool operator==(const BytecodeNode& other) const;
127  bool operator!=(const BytecodeNode& other) const { return !(*this == other); }
128 
129  private:
130  template <Bytecode bytecode, AccumulatorUse accumulator_use,
131  OperandType... operand_types>
132  friend class BytecodeNodeBuilder;
133 
134  V8_INLINE BytecodeNode(Bytecode bytecode, int operand_count,
135  OperandScale operand_scale,
136  BytecodeSourceInfo source_info, uint32_t operand0 = 0,
137  uint32_t operand1 = 0, uint32_t operand2 = 0,
138  uint32_t operand3 = 0, uint32_t operand4 = 0)
139  : bytecode_(bytecode),
140  operand_count_(operand_count),
141  operand_scale_(operand_scale),
142  source_info_(source_info) {
143  DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), operand_count);
144  operands_[0] = operand0;
145  operands_[1] = operand1;
146  operands_[2] = operand2;
147  operands_[3] = operand3;
148  operands_[4] = operand4;
149  }
150 
151  template <Bytecode bytecode, AccumulatorUse accum_use>
152  V8_INLINE static BytecodeNode Create(BytecodeSourceInfo source_info) {
153  return BytecodeNode(bytecode, 0, OperandScale::kSingle, source_info);
154  }
155 
156  template <Bytecode bytecode, AccumulatorUse accum_use,
157  OperandType operand0_type>
158  V8_INLINE static BytecodeNode Create(BytecodeSourceInfo source_info,
159  uint32_t operand0) {
160  DCHECK_EQ(Bytecodes::GetOperandType(bytecode, 0), operand0_type);
161  OperandScale scale = OperandScale::kSingle;
162  scale = std::max(scale, ScaleForOperand<operand0_type>(operand0));
163  return BytecodeNode(bytecode, 1, scale, source_info, operand0);
164  }
165 
166  template <Bytecode bytecode, AccumulatorUse accum_use,
167  OperandType operand0_type, OperandType operand1_type>
168  V8_INLINE static BytecodeNode Create(BytecodeSourceInfo source_info,
169  uint32_t operand0, uint32_t operand1) {
170  DCHECK_EQ(Bytecodes::GetOperandType(bytecode, 0), operand0_type);
171  DCHECK_EQ(Bytecodes::GetOperandType(bytecode, 1), operand1_type);
172  OperandScale scale = OperandScale::kSingle;
173  scale = std::max(scale, ScaleForOperand<operand0_type>(operand0));
174  scale = std::max(scale, ScaleForOperand<operand1_type>(operand1));
175  return BytecodeNode(bytecode, 2, scale, source_info, operand0, operand1);
176  }
177 
178  template <Bytecode bytecode, AccumulatorUse accum_use,
179  OperandType operand0_type, OperandType operand1_type,
180  OperandType operand2_type>
181  V8_INLINE static BytecodeNode Create(BytecodeSourceInfo source_info,
182  uint32_t operand0, uint32_t operand1,
183  uint32_t operand2) {
184  DCHECK_EQ(Bytecodes::GetOperandType(bytecode, 0), operand0_type);
185  DCHECK_EQ(Bytecodes::GetOperandType(bytecode, 1), operand1_type);
186  DCHECK_EQ(Bytecodes::GetOperandType(bytecode, 2), operand2_type);
187  OperandScale scale = OperandScale::kSingle;
188  scale = std::max(scale, ScaleForOperand<operand0_type>(operand0));
189  scale = std::max(scale, ScaleForOperand<operand1_type>(operand1));
190  scale = std::max(scale, ScaleForOperand<operand2_type>(operand2));
191  return BytecodeNode(bytecode, 3, scale, source_info, operand0, operand1,
192  operand2);
193  }
194 
195  template <Bytecode bytecode, AccumulatorUse accum_use,
196  OperandType operand0_type, OperandType operand1_type,
197  OperandType operand2_type, OperandType operand3_type>
198  V8_INLINE static BytecodeNode Create(BytecodeSourceInfo source_info,
199  uint32_t operand0, uint32_t operand1,
200  uint32_t operand2, uint32_t operand3) {
201  DCHECK_EQ(Bytecodes::GetOperandType(bytecode, 0), operand0_type);
202  DCHECK_EQ(Bytecodes::GetOperandType(bytecode, 1), operand1_type);
203  DCHECK_EQ(Bytecodes::GetOperandType(bytecode, 2), operand2_type);
204  DCHECK_EQ(Bytecodes::GetOperandType(bytecode, 3), operand3_type);
205  OperandScale scale = OperandScale::kSingle;
206  scale = std::max(scale, ScaleForOperand<operand0_type>(operand0));
207  scale = std::max(scale, ScaleForOperand<operand1_type>(operand1));
208  scale = std::max(scale, ScaleForOperand<operand2_type>(operand2));
209  scale = std::max(scale, ScaleForOperand<operand3_type>(operand3));
210  return BytecodeNode(bytecode, 4, scale, source_info, operand0, operand1,
211  operand2, operand3);
212  }
213 
214  template <Bytecode bytecode, AccumulatorUse accum_use,
215  OperandType operand0_type, OperandType operand1_type,
216  OperandType operand2_type, OperandType operand3_type,
217  OperandType operand4_type>
218  V8_INLINE static BytecodeNode Create(BytecodeSourceInfo source_info,
219  uint32_t operand0, uint32_t operand1,
220  uint32_t operand2, uint32_t operand3,
221  uint32_t operand4) {
222  DCHECK_EQ(Bytecodes::GetOperandType(bytecode, 0), operand0_type);
223  DCHECK_EQ(Bytecodes::GetOperandType(bytecode, 1), operand1_type);
224  DCHECK_EQ(Bytecodes::GetOperandType(bytecode, 2), operand2_type);
225  DCHECK_EQ(Bytecodes::GetOperandType(bytecode, 3), operand3_type);
226  DCHECK_EQ(Bytecodes::GetOperandType(bytecode, 4), operand4_type);
227  OperandScale scale = OperandScale::kSingle;
228  scale = std::max(scale, ScaleForOperand<operand0_type>(operand0));
229  scale = std::max(scale, ScaleForOperand<operand1_type>(operand1));
230  scale = std::max(scale, ScaleForOperand<operand2_type>(operand2));
231  scale = std::max(scale, ScaleForOperand<operand3_type>(operand3));
232  scale = std::max(scale, ScaleForOperand<operand4_type>(operand4));
233  return BytecodeNode(bytecode, 5, scale, source_info, operand0, operand1,
234  operand2, operand3, operand4);
235  }
236 
237  template <OperandType operand_type>
238  V8_INLINE static OperandScale ScaleForOperand(uint32_t operand) {
239  if (BytecodeOperands::IsScalableUnsignedByte(operand_type)) {
240  return Bytecodes::ScaleForUnsignedOperand(operand);
241  } else if (BytecodeOperands::IsScalableSignedByte(operand_type)) {
242  return Bytecodes::ScaleForSignedOperand(operand);
243  } else {
244  return OperandScale::kSingle;
245  }
246  }
247 
248  V8_INLINE void UpdateScaleForOperand(int operand_index, uint32_t operand) {
249  if (Bytecodes::OperandIsScalableSignedByte(bytecode(), operand_index)) {
250  operand_scale_ =
251  std::max(operand_scale_, Bytecodes::ScaleForSignedOperand(operand));
252  } else if (Bytecodes::OperandIsScalableUnsignedByte(bytecode(),
253  operand_index)) {
254  operand_scale_ =
255  std::max(operand_scale_, Bytecodes::ScaleForUnsignedOperand(operand));
256  }
257  }
258 
259  V8_INLINE void SetOperand(int operand_index, uint32_t operand) {
260  operands_[operand_index] = operand;
261  UpdateScaleForOperand(operand_index, operand);
262  }
263 
264  Bytecode bytecode_;
265  uint32_t operands_[Bytecodes::kMaxOperands];
266  int operand_count_;
267  OperandScale operand_scale_;
268  BytecodeSourceInfo source_info_;
269 };
270 
271 V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
272  const BytecodeNode& node);
273 
274 } // namespace interpreter
275 } // namespace internal
276 } // namespace v8
277 
278 #endif // V8_INTERPRETER_BYTECODE_NODE_H_
Definition: libplatform.h:13