blob: d67a390d121021173bcfd22c29ac2b4621a96917 [file] [log] [blame]
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001// Copyright 2015 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_BYTECODES_H_
6#define V8_INTERPRETER_BYTECODES_H_
7
8#include <iosfwd>
9
10// Clients of this interface shouldn't depend on lots of interpreter internals.
11// Do not include anything from src/interpreter here!
Ben Murdochc5610432016-08-08 18:44:38 +010012#include "src/frames.h"
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000013#include "src/utils.h"
14
15namespace v8 {
16namespace internal {
17namespace interpreter {
18
Ben Murdochda12d292016-06-02 14:46:10 +010019#define INVALID_OPERAND_TYPE_LIST(V) V(None, OperandTypeInfo::kNone)
Ben Murdoch097c5b22016-05-18 11:27:45 +010020
Ben Murdochda12d292016-06-02 14:46:10 +010021#define REGISTER_INPUT_OPERAND_TYPE_LIST(V) \
22 V(MaybeReg, OperandTypeInfo::kScalableSignedByte) \
23 V(Reg, OperandTypeInfo::kScalableSignedByte) \
24 V(RegPair, OperandTypeInfo::kScalableSignedByte)
Ben Murdoch097c5b22016-05-18 11:27:45 +010025
Ben Murdochda12d292016-06-02 14:46:10 +010026#define REGISTER_OUTPUT_OPERAND_TYPE_LIST(V) \
27 V(RegOut, OperandTypeInfo::kScalableSignedByte) \
28 V(RegOutPair, OperandTypeInfo::kScalableSignedByte) \
29 V(RegOutTriple, OperandTypeInfo::kScalableSignedByte)
Ben Murdoch097c5b22016-05-18 11:27:45 +010030
Ben Murdochda12d292016-06-02 14:46:10 +010031#define SCALAR_OPERAND_TYPE_LIST(V) \
32 V(Flag8, OperandTypeInfo::kFixedUnsignedByte) \
33 V(Idx, OperandTypeInfo::kScalableUnsignedByte) \
34 V(Imm, OperandTypeInfo::kScalableSignedByte) \
35 V(RegCount, OperandTypeInfo::kScalableUnsignedByte) \
36 V(RuntimeId, OperandTypeInfo::kFixedUnsignedShort)
Ben Murdoch097c5b22016-05-18 11:27:45 +010037
38#define REGISTER_OPERAND_TYPE_LIST(V) \
39 REGISTER_INPUT_OPERAND_TYPE_LIST(V) \
40 REGISTER_OUTPUT_OPERAND_TYPE_LIST(V)
41
42#define NON_REGISTER_OPERAND_TYPE_LIST(V) \
43 INVALID_OPERAND_TYPE_LIST(V) \
44 SCALAR_OPERAND_TYPE_LIST(V)
45
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000046// The list of operand types used by bytecodes.
Ben Murdoch097c5b22016-05-18 11:27:45 +010047#define OPERAND_TYPE_LIST(V) \
48 NON_REGISTER_OPERAND_TYPE_LIST(V) \
49 REGISTER_OPERAND_TYPE_LIST(V)
50
Ben Murdochda12d292016-06-02 14:46:10 +010051// Define one debug break bytecode for each possible size of unscaled
52// bytecodes. Format is V(<bytecode>, <accumulator_use>, <operands>).
53#define DEBUG_BREAK_PLAIN_BYTECODE_LIST(V) \
54 V(DebugBreak0, AccumulatorUse::kRead) \
55 V(DebugBreak1, AccumulatorUse::kRead, OperandType::kReg) \
56 V(DebugBreak2, AccumulatorUse::kRead, OperandType::kReg, OperandType::kReg) \
57 V(DebugBreak3, AccumulatorUse::kRead, OperandType::kReg, OperandType::kReg, \
58 OperandType::kReg) \
59 V(DebugBreak4, AccumulatorUse::kRead, OperandType::kReg, OperandType::kReg, \
60 OperandType::kReg, OperandType::kReg) \
61 V(DebugBreak5, AccumulatorUse::kRead, OperandType::kRuntimeId, \
62 OperandType::kReg, OperandType::kReg) \
63 V(DebugBreak6, AccumulatorUse::kRead, OperandType::kRuntimeId, \
64 OperandType::kReg, OperandType::kReg, OperandType::kReg)
65
66// Define one debug break for each widening prefix.
67#define DEBUG_BREAK_PREFIX_BYTECODE_LIST(V) \
68 V(DebugBreakWide, AccumulatorUse::kRead) \
69 V(DebugBreakExtraWide, AccumulatorUse::kRead)
70
71#define DEBUG_BREAK_BYTECODE_LIST(V) \
72 DEBUG_BREAK_PLAIN_BYTECODE_LIST(V) \
73 DEBUG_BREAK_PREFIX_BYTECODE_LIST(V)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000074
75// The list of bytecodes which are interpreted by the interpreter.
Ben Murdochda12d292016-06-02 14:46:10 +010076#define BYTECODE_LIST(V) \
77 /* Extended width operands */ \
78 V(Wide, AccumulatorUse::kNone) \
79 V(ExtraWide, AccumulatorUse::kNone) \
80 \
81 /* Loading the accumulator */ \
82 V(LdaZero, AccumulatorUse::kWrite) \
83 V(LdaSmi, AccumulatorUse::kWrite, OperandType::kImm) \
84 V(LdaUndefined, AccumulatorUse::kWrite) \
85 V(LdaNull, AccumulatorUse::kWrite) \
86 V(LdaTheHole, AccumulatorUse::kWrite) \
87 V(LdaTrue, AccumulatorUse::kWrite) \
88 V(LdaFalse, AccumulatorUse::kWrite) \
89 V(LdaConstant, AccumulatorUse::kWrite, OperandType::kIdx) \
90 \
91 /* Globals */ \
92 V(LdaGlobal, AccumulatorUse::kWrite, OperandType::kIdx, OperandType::kIdx) \
93 V(LdaGlobalInsideTypeof, AccumulatorUse::kWrite, OperandType::kIdx, \
94 OperandType::kIdx) \
95 V(StaGlobalSloppy, AccumulatorUse::kRead, OperandType::kIdx, \
96 OperandType::kIdx) \
97 V(StaGlobalStrict, AccumulatorUse::kRead, OperandType::kIdx, \
98 OperandType::kIdx) \
99 \
100 /* Context operations */ \
Ben Murdochc5610432016-08-08 18:44:38 +0100101 V(PushContext, AccumulatorUse::kRead, OperandType::kRegOut) \
Ben Murdochda12d292016-06-02 14:46:10 +0100102 V(PopContext, AccumulatorUse::kNone, OperandType::kReg) \
103 V(LdaContextSlot, AccumulatorUse::kWrite, OperandType::kReg, \
104 OperandType::kIdx) \
105 V(StaContextSlot, AccumulatorUse::kRead, OperandType::kReg, \
106 OperandType::kIdx) \
107 \
108 /* Load-Store lookup slots */ \
109 V(LdaLookupSlot, AccumulatorUse::kWrite, OperandType::kIdx) \
110 V(LdaLookupSlotInsideTypeof, AccumulatorUse::kWrite, OperandType::kIdx) \
111 V(StaLookupSlotSloppy, AccumulatorUse::kReadWrite, OperandType::kIdx) \
112 V(StaLookupSlotStrict, AccumulatorUse::kReadWrite, OperandType::kIdx) \
113 \
114 /* Register-accumulator transfers */ \
115 V(Ldar, AccumulatorUse::kWrite, OperandType::kReg) \
116 V(Star, AccumulatorUse::kRead, OperandType::kRegOut) \
117 \
118 /* Register-register transfers */ \
119 V(Mov, AccumulatorUse::kNone, OperandType::kReg, OperandType::kRegOut) \
120 \
121 /* LoadIC operations */ \
122 V(LoadIC, AccumulatorUse::kWrite, OperandType::kReg, OperandType::kIdx, \
123 OperandType::kIdx) \
124 V(KeyedLoadIC, AccumulatorUse::kReadWrite, OperandType::kReg, \
125 OperandType::kIdx) \
126 \
127 /* StoreIC operations */ \
128 V(StoreICSloppy, AccumulatorUse::kRead, OperandType::kReg, \
129 OperandType::kIdx, OperandType::kIdx) \
130 V(StoreICStrict, AccumulatorUse::kRead, OperandType::kReg, \
131 OperandType::kIdx, OperandType::kIdx) \
132 V(KeyedStoreICSloppy, AccumulatorUse::kRead, OperandType::kReg, \
133 OperandType::kReg, OperandType::kIdx) \
134 V(KeyedStoreICStrict, AccumulatorUse::kRead, OperandType::kReg, \
135 OperandType::kReg, OperandType::kIdx) \
136 \
137 /* Binary Operators */ \
138 V(Add, AccumulatorUse::kReadWrite, OperandType::kReg) \
139 V(Sub, AccumulatorUse::kReadWrite, OperandType::kReg) \
140 V(Mul, AccumulatorUse::kReadWrite, OperandType::kReg) \
141 V(Div, AccumulatorUse::kReadWrite, OperandType::kReg) \
142 V(Mod, AccumulatorUse::kReadWrite, OperandType::kReg) \
143 V(BitwiseOr, AccumulatorUse::kReadWrite, OperandType::kReg) \
144 V(BitwiseXor, AccumulatorUse::kReadWrite, OperandType::kReg) \
145 V(BitwiseAnd, AccumulatorUse::kReadWrite, OperandType::kReg) \
146 V(ShiftLeft, AccumulatorUse::kReadWrite, OperandType::kReg) \
147 V(ShiftRight, AccumulatorUse::kReadWrite, OperandType::kReg) \
148 V(ShiftRightLogical, AccumulatorUse::kReadWrite, OperandType::kReg) \
149 \
150 /* Unary Operators */ \
151 V(Inc, AccumulatorUse::kReadWrite) \
152 V(Dec, AccumulatorUse::kReadWrite) \
Ben Murdochc5610432016-08-08 18:44:38 +0100153 V(ToBooleanLogicalNot, AccumulatorUse::kReadWrite) \
Ben Murdochda12d292016-06-02 14:46:10 +0100154 V(LogicalNot, AccumulatorUse::kReadWrite) \
155 V(TypeOf, AccumulatorUse::kReadWrite) \
156 V(DeletePropertyStrict, AccumulatorUse::kReadWrite, OperandType::kReg) \
157 V(DeletePropertySloppy, AccumulatorUse::kReadWrite, OperandType::kReg) \
158 \
159 /* Call operations */ \
160 V(Call, AccumulatorUse::kWrite, OperandType::kReg, OperandType::kReg, \
161 OperandType::kRegCount, OperandType::kIdx) \
162 V(TailCall, AccumulatorUse::kWrite, OperandType::kReg, OperandType::kReg, \
163 OperandType::kRegCount, OperandType::kIdx) \
164 V(CallRuntime, AccumulatorUse::kWrite, OperandType::kRuntimeId, \
165 OperandType::kMaybeReg, OperandType::kRegCount) \
166 V(CallRuntimeForPair, AccumulatorUse::kNone, OperandType::kRuntimeId, \
167 OperandType::kMaybeReg, OperandType::kRegCount, OperandType::kRegOutPair) \
168 V(CallJSRuntime, AccumulatorUse::kWrite, OperandType::kIdx, \
169 OperandType::kReg, OperandType::kRegCount) \
170 \
171 /* Intrinsics */ \
172 V(InvokeIntrinsic, AccumulatorUse::kWrite, OperandType::kRuntimeId, \
173 OperandType::kMaybeReg, OperandType::kRegCount) \
174 \
175 /* New operator */ \
176 V(New, AccumulatorUse::kReadWrite, OperandType::kReg, \
177 OperandType::kMaybeReg, OperandType::kRegCount) \
178 \
179 /* Test Operators */ \
180 V(TestEqual, AccumulatorUse::kReadWrite, OperandType::kReg) \
181 V(TestNotEqual, AccumulatorUse::kReadWrite, OperandType::kReg) \
182 V(TestEqualStrict, AccumulatorUse::kReadWrite, OperandType::kReg) \
183 V(TestLessThan, AccumulatorUse::kReadWrite, OperandType::kReg) \
184 V(TestGreaterThan, AccumulatorUse::kReadWrite, OperandType::kReg) \
185 V(TestLessThanOrEqual, AccumulatorUse::kReadWrite, OperandType::kReg) \
186 V(TestGreaterThanOrEqual, AccumulatorUse::kReadWrite, OperandType::kReg) \
187 V(TestInstanceOf, AccumulatorUse::kReadWrite, OperandType::kReg) \
188 V(TestIn, AccumulatorUse::kReadWrite, OperandType::kReg) \
189 \
190 /* Cast operators */ \
191 V(ToName, AccumulatorUse::kReadWrite) \
192 V(ToNumber, AccumulatorUse::kReadWrite) \
193 V(ToObject, AccumulatorUse::kReadWrite) \
194 \
195 /* Literals */ \
196 V(CreateRegExpLiteral, AccumulatorUse::kWrite, OperandType::kIdx, \
197 OperandType::kIdx, OperandType::kFlag8) \
198 V(CreateArrayLiteral, AccumulatorUse::kWrite, OperandType::kIdx, \
199 OperandType::kIdx, OperandType::kFlag8) \
200 V(CreateObjectLiteral, AccumulatorUse::kWrite, OperandType::kIdx, \
201 OperandType::kIdx, OperandType::kFlag8) \
202 \
203 /* Closure allocation */ \
204 V(CreateClosure, AccumulatorUse::kWrite, OperandType::kIdx, \
205 OperandType::kFlag8) \
206 \
207 /* Arguments allocation */ \
208 V(CreateMappedArguments, AccumulatorUse::kWrite) \
209 V(CreateUnmappedArguments, AccumulatorUse::kWrite) \
210 V(CreateRestParameter, AccumulatorUse::kWrite) \
211 \
212 /* Control Flow */ \
213 V(Jump, AccumulatorUse::kNone, OperandType::kImm) \
214 V(JumpConstant, AccumulatorUse::kNone, OperandType::kIdx) \
215 V(JumpIfTrue, AccumulatorUse::kRead, OperandType::kImm) \
216 V(JumpIfTrueConstant, AccumulatorUse::kRead, OperandType::kIdx) \
217 V(JumpIfFalse, AccumulatorUse::kRead, OperandType::kImm) \
218 V(JumpIfFalseConstant, AccumulatorUse::kRead, OperandType::kIdx) \
219 V(JumpIfToBooleanTrue, AccumulatorUse::kRead, OperandType::kImm) \
220 V(JumpIfToBooleanTrueConstant, AccumulatorUse::kRead, OperandType::kIdx) \
221 V(JumpIfToBooleanFalse, AccumulatorUse::kRead, OperandType::kImm) \
222 V(JumpIfToBooleanFalseConstant, AccumulatorUse::kRead, OperandType::kIdx) \
223 V(JumpIfNull, AccumulatorUse::kRead, OperandType::kImm) \
224 V(JumpIfNullConstant, AccumulatorUse::kRead, OperandType::kIdx) \
225 V(JumpIfUndefined, AccumulatorUse::kRead, OperandType::kImm) \
226 V(JumpIfUndefinedConstant, AccumulatorUse::kRead, OperandType::kIdx) \
227 V(JumpIfNotHole, AccumulatorUse::kRead, OperandType::kImm) \
228 V(JumpIfNotHoleConstant, AccumulatorUse::kRead, OperandType::kIdx) \
229 \
230 /* Complex flow control For..in */ \
231 V(ForInPrepare, AccumulatorUse::kRead, OperandType::kRegOutTriple) \
232 V(ForInDone, AccumulatorUse::kWrite, OperandType::kReg, OperandType::kReg) \
233 V(ForInNext, AccumulatorUse::kWrite, OperandType::kReg, OperandType::kReg, \
234 OperandType::kRegPair, OperandType::kIdx) \
235 V(ForInStep, AccumulatorUse::kWrite, OperandType::kReg) \
236 \
237 /* Perform a stack guard check */ \
238 V(StackCheck, AccumulatorUse::kNone) \
239 \
240 /* Non-local flow control */ \
241 V(Throw, AccumulatorUse::kRead) \
242 V(ReThrow, AccumulatorUse::kRead) \
Ben Murdochc5610432016-08-08 18:44:38 +0100243 V(Return, AccumulatorUse::kRead) \
244 \
245 /* Generators */ \
246 V(SuspendGenerator, AccumulatorUse::kRead, OperandType::kReg) \
247 V(ResumeGenerator, AccumulatorUse::kWrite, OperandType::kReg) \
Ben Murdochda12d292016-06-02 14:46:10 +0100248 \
249 /* Debugger */ \
250 V(Debugger, AccumulatorUse::kNone) \
251 DEBUG_BREAK_BYTECODE_LIST(V) \
252 \
253 /* Illegal bytecode (terminates execution) */ \
Ben Murdochc5610432016-08-08 18:44:38 +0100254 V(Illegal, AccumulatorUse::kNone) \
255 \
256 /* No operation (used to maintain source positions for peephole */ \
257 /* eliminated bytecodes). */ \
258 V(Nop, AccumulatorUse::kNone)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000259
Ben Murdochda12d292016-06-02 14:46:10 +0100260enum class AccumulatorUse : uint8_t {
261 kNone = 0,
262 kRead = 1 << 0,
263 kWrite = 1 << 1,
264 kReadWrite = kRead | kWrite
265};
266
267V8_INLINE AccumulatorUse operator&(AccumulatorUse lhs, AccumulatorUse rhs) {
268 int result = static_cast<int>(lhs) & static_cast<int>(rhs);
269 return static_cast<AccumulatorUse>(result);
270}
271
272V8_INLINE AccumulatorUse operator|(AccumulatorUse lhs, AccumulatorUse rhs) {
273 int result = static_cast<int>(lhs) | static_cast<int>(rhs);
274 return static_cast<AccumulatorUse>(result);
275}
276
277// Enumeration of scaling factors applicable to scalable operands. Code
278// relies on being able to cast values to integer scaling values.
Ben Murdochc5610432016-08-08 18:44:38 +0100279#define OPERAND_SCALE_LIST(V) \
280 V(Single, 1) \
281 V(Double, 2) \
282 V(Quadruple, 4)
283
Ben Murdochda12d292016-06-02 14:46:10 +0100284enum class OperandScale : uint8_t {
Ben Murdochc5610432016-08-08 18:44:38 +0100285#define DECLARE_OPERAND_SCALE(Name, Scale) k##Name = Scale,
286 OPERAND_SCALE_LIST(DECLARE_OPERAND_SCALE)
287#undef DECLARE_OPERAND_SCALE
288 kLast = kQuadruple
Ben Murdochda12d292016-06-02 14:46:10 +0100289};
290
291// Enumeration of the size classes of operand types used by
292// bytecodes. Code relies on being able to cast values to integer
293// types to get the size in bytes.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000294enum class OperandSize : uint8_t {
295 kNone = 0,
296 kByte = 1,
297 kShort = 2,
Ben Murdochda12d292016-06-02 14:46:10 +0100298 kQuad = 4,
299 kLast = kQuad
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000300};
301
Ben Murdochda12d292016-06-02 14:46:10 +0100302// Primitive operand info used that summarize properties of operands.
303// Columns are Name, IsScalable, IsUnsigned, UnscaledSize.
304#define OPERAND_TYPE_INFO_LIST(V) \
305 V(None, false, false, OperandSize::kNone) \
306 V(ScalableSignedByte, true, false, OperandSize::kByte) \
307 V(ScalableUnsignedByte, true, true, OperandSize::kByte) \
308 V(FixedUnsignedByte, false, true, OperandSize::kByte) \
309 V(FixedUnsignedShort, false, true, OperandSize::kShort)
310
311enum class OperandTypeInfo : uint8_t {
312#define DECLARE_OPERAND_TYPE_INFO(Name, ...) k##Name,
313 OPERAND_TYPE_INFO_LIST(DECLARE_OPERAND_TYPE_INFO)
314#undef DECLARE_OPERAND_TYPE_INFO
315};
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000316
317// Enumeration of operand types used by bytecodes.
318enum class OperandType : uint8_t {
319#define DECLARE_OPERAND_TYPE(Name, _) k##Name,
320 OPERAND_TYPE_LIST(DECLARE_OPERAND_TYPE)
321#undef DECLARE_OPERAND_TYPE
322#define COUNT_OPERAND_TYPES(x, _) +1
323 // The COUNT_OPERAND macro will turn this into kLast = -1 +1 +1... which will
324 // evaluate to the same value as the last operand.
325 kLast = -1 OPERAND_TYPE_LIST(COUNT_OPERAND_TYPES)
326#undef COUNT_OPERAND_TYPES
327};
328
329
330// Enumeration of interpreter bytecodes.
331enum class Bytecode : uint8_t {
332#define DECLARE_BYTECODE(Name, ...) k##Name,
333 BYTECODE_LIST(DECLARE_BYTECODE)
334#undef DECLARE_BYTECODE
335#define COUNT_BYTECODE(x, ...) +1
336 // The COUNT_BYTECODE macro will turn this into kLast = -1 +1 +1... which will
337 // evaluate to the same value as the last real bytecode.
338 kLast = -1 BYTECODE_LIST(COUNT_BYTECODE)
339#undef COUNT_BYTECODE
340};
341
342
343// An interpreter Register which is located in the function's Register file
344// in its stack-frame. Register hold parameters, this, and expression values.
Ben Murdochc5610432016-08-08 18:44:38 +0100345class Register final {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000346 public:
Ben Murdoch097c5b22016-05-18 11:27:45 +0100347 explicit Register(int index = kInvalidIndex) : index_(index) {}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000348
Ben Murdoch097c5b22016-05-18 11:27:45 +0100349 int index() const { return index_; }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000350 bool is_parameter() const { return index() < 0; }
Ben Murdoch097c5b22016-05-18 11:27:45 +0100351 bool is_valid() const { return index_ != kInvalidIndex; }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000352
353 static Register FromParameterIndex(int index, int parameter_count);
354 int ToParameterIndex(int parameter_count) const;
Ben Murdoch097c5b22016-05-18 11:27:45 +0100355
356 // Returns an invalid register.
357 static Register invalid_value() { return Register(); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000358
359 // Returns the register for the function's closure object.
360 static Register function_closure();
361 bool is_function_closure() const;
362
Ben Murdoch097c5b22016-05-18 11:27:45 +0100363 // Returns the register which holds the current context object.
364 static Register current_context();
365 bool is_current_context() const;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000366
367 // Returns the register for the incoming new target value.
368 static Register new_target();
369 bool is_new_target() const;
370
Ben Murdochc5610432016-08-08 18:44:38 +0100371 // Returns the register for the bytecode array.
372 static Register bytecode_array();
373 bool is_bytecode_array() const;
374
375 // Returns the register for the saved bytecode offset.
376 static Register bytecode_offset();
377 bool is_bytecode_offset() const;
378
379 OperandSize SizeOfOperand() const;
380
381 int32_t ToOperand() const { return kRegisterFileStartOffset - index_; }
382 static Register FromOperand(int32_t operand) {
383 return Register(kRegisterFileStartOffset - operand);
384 }
Ben Murdoch097c5b22016-05-18 11:27:45 +0100385
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000386 static bool AreContiguous(Register reg1, Register reg2,
387 Register reg3 = Register(),
388 Register reg4 = Register(),
389 Register reg5 = Register());
390
Ben Murdoch097c5b22016-05-18 11:27:45 +0100391 std::string ToString(int parameter_count);
392
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000393 bool operator==(const Register& other) const {
394 return index() == other.index();
395 }
396 bool operator!=(const Register& other) const {
397 return index() != other.index();
398 }
399 bool operator<(const Register& other) const {
400 return index() < other.index();
401 }
402 bool operator<=(const Register& other) const {
403 return index() <= other.index();
404 }
Ben Murdoch097c5b22016-05-18 11:27:45 +0100405 bool operator>(const Register& other) const {
406 return index() > other.index();
407 }
408 bool operator>=(const Register& other) const {
409 return index() >= other.index();
410 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000411
412 private:
Ben Murdoch097c5b22016-05-18 11:27:45 +0100413 static const int kInvalidIndex = kMaxInt;
Ben Murdochc5610432016-08-08 18:44:38 +0100414 static const int kRegisterFileStartOffset =
415 InterpreterFrameConstants::kRegisterFileFromFp / kPointerSize;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000416
417 void* operator new(size_t size);
418 void operator delete(void* p);
419
420 int index_;
421};
422
423
424class Bytecodes {
425 public:
426 // Returns string representation of |bytecode|.
427 static const char* ToString(Bytecode bytecode);
428
Ben Murdochda12d292016-06-02 14:46:10 +0100429 // Returns string representation of |bytecode|.
430 static std::string ToString(Bytecode bytecode, OperandScale operand_scale);
431
432 // Returns string representation of |accumulator_use|.
433 static const char* AccumulatorUseToString(AccumulatorUse accumulator_use);
434
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000435 // Returns string representation of |operand_type|.
436 static const char* OperandTypeToString(OperandType operand_type);
437
Ben Murdochda12d292016-06-02 14:46:10 +0100438 // Returns string representation of |operand_scale|.
439 static const char* OperandScaleToString(OperandScale operand_scale);
440
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000441 // Returns string representation of |operand_size|.
442 static const char* OperandSizeToString(OperandSize operand_size);
443
444 // Returns byte value of bytecode.
445 static uint8_t ToByte(Bytecode bytecode);
446
447 // Returns bytecode for |value|.
448 static Bytecode FromByte(uint8_t value);
449
450 // Returns the number of operands expected by |bytecode|.
451 static int NumberOfOperands(Bytecode bytecode);
452
Ben Murdoch097c5b22016-05-18 11:27:45 +0100453 // Returns the number of register operands expected by |bytecode|.
454 static int NumberOfRegisterOperands(Bytecode bytecode);
455
Ben Murdochda12d292016-06-02 14:46:10 +0100456 // Returns the prefix bytecode representing an operand scale to be
457 // applied to a a bytecode.
458 static Bytecode OperandScaleToPrefixBytecode(OperandScale operand_scale);
459
460 // Returns true if the operand scale requires a prefix bytecode.
461 static bool OperandScaleRequiresPrefixBytecode(OperandScale operand_scale);
462
463 // Returns the scaling applied to scalable operands if bytecode is
464 // is a scaling prefix.
465 static OperandScale PrefixBytecodeToOperandScale(Bytecode bytecode);
466
467 // Returns how accumulator is used by |bytecode|.
468 static AccumulatorUse GetAccumulatorUse(Bytecode bytecode);
469
470 // Returns true if |bytecode| reads the accumulator.
471 static bool ReadsAccumulator(Bytecode bytecode);
472
473 // Returns true if |bytecode| writes the accumulator.
474 static bool WritesAccumulator(Bytecode bytecode);
475
Ben Murdochc5610432016-08-08 18:44:38 +0100476 // Return true if |bytecode| writes the accumulator with a boolean value.
477 static bool WritesBooleanToAccumulator(Bytecode bytecode);
478
479 // Return true if |bytecode| is an accumulator load bytecode,
480 // e.g. LdaConstant, LdaTrue, Ldar.
481 static bool IsAccumulatorLoadWithoutEffects(Bytecode bytecode);
482
Ben Murdoch097c5b22016-05-18 11:27:45 +0100483 // Returns the i-th operand of |bytecode|.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000484 static OperandType GetOperandType(Bytecode bytecode, int i);
485
Ben Murdochc5610432016-08-08 18:44:38 +0100486 // Returns a pointer to an array of operand types terminated in
487 // OperandType::kNone.
488 static const OperandType* GetOperandTypes(Bytecode bytecode);
489
Ben Murdoch097c5b22016-05-18 11:27:45 +0100490 // Returns the size of the i-th operand of |bytecode|.
Ben Murdochda12d292016-06-02 14:46:10 +0100491 static OperandSize GetOperandSize(Bytecode bytecode, int i,
492 OperandScale operand_scale);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000493
494 // Returns the offset of the i-th operand of |bytecode| relative to the start
495 // of the bytecode.
Ben Murdochda12d292016-06-02 14:46:10 +0100496 static int GetOperandOffset(Bytecode bytecode, int i,
497 OperandScale operand_scale);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000498
Ben Murdoch097c5b22016-05-18 11:27:45 +0100499 // Returns a zero-based bitmap of the register operand positions of
500 // |bytecode|.
501 static int GetRegisterOperandBitmap(Bytecode bytecode);
502
Ben Murdochda12d292016-06-02 14:46:10 +0100503 // Returns a debug break bytecode to replace |bytecode|.
Ben Murdoch097c5b22016-05-18 11:27:45 +0100504 static Bytecode GetDebugBreak(Bytecode bytecode);
505
Ben Murdochda12d292016-06-02 14:46:10 +0100506 // Returns the size of the bytecode including its operands for the
507 // given |operand_scale|.
508 static int Size(Bytecode bytecode, OperandScale operand_scale);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000509
510 // Returns the size of |operand|.
Ben Murdochda12d292016-06-02 14:46:10 +0100511 static OperandSize SizeOfOperand(OperandType operand, OperandScale scale);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000512
Ben Murdochc5610432016-08-08 18:44:38 +0100513 // Returns the number of values which |bytecode| returns.
514 static size_t ReturnCount(Bytecode bytecode);
515
Ben Murdoch097c5b22016-05-18 11:27:45 +0100516 // Returns true if the bytecode is a conditional jump taking
Ben Murdochda12d292016-06-02 14:46:10 +0100517 // an immediate byte operand (OperandType::kImm).
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000518 static bool IsConditionalJumpImmediate(Bytecode bytecode);
519
Ben Murdoch097c5b22016-05-18 11:27:45 +0100520 // Returns true if the bytecode is a conditional jump taking
Ben Murdochda12d292016-06-02 14:46:10 +0100521 // a constant pool entry (OperandType::kIdx).
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000522 static bool IsConditionalJumpConstant(Bytecode bytecode);
523
Ben Murdoch097c5b22016-05-18 11:27:45 +0100524 // Returns true if the bytecode is a conditional jump taking
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000525 // any kind of operand.
526 static bool IsConditionalJump(Bytecode bytecode);
527
Ben Murdoch097c5b22016-05-18 11:27:45 +0100528 // Returns true if the bytecode is a jump or a conditional jump taking
Ben Murdochda12d292016-06-02 14:46:10 +0100529 // an immediate byte operand (OperandType::kImm).
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000530 static bool IsJumpImmediate(Bytecode bytecode);
531
Ben Murdoch097c5b22016-05-18 11:27:45 +0100532 // Returns true if the bytecode is a jump or conditional jump taking a
Ben Murdochda12d292016-06-02 14:46:10 +0100533 // constant pool entry (OperandType::kIdx).
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000534 static bool IsJumpConstant(Bytecode bytecode);
535
Ben Murdoch097c5b22016-05-18 11:27:45 +0100536 // Returns true if the bytecode is a jump or conditional jump taking
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000537 // any kind of operand.
538 static bool IsJump(Bytecode bytecode);
539
Ben Murdochc5610432016-08-08 18:44:38 +0100540 // Returns true if the bytecode is a jump that internally coerces the
541 // accumulator to a boolean.
542 static bool IsJumpIfToBoolean(Bytecode bytecode);
543
544 // Returns the equivalent jump bytecode without the accumulator coercion.
545 static Bytecode GetJumpWithoutToBoolean(Bytecode bytecode);
546
Ben Murdoch097c5b22016-05-18 11:27:45 +0100547 // Returns true if the bytecode is a conditional jump, a jump, or a return.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000548 static bool IsJumpOrReturn(Bytecode bytecode);
549
Ben Murdoch097c5b22016-05-18 11:27:45 +0100550 // Returns true if the bytecode is a call or a constructor call.
551 static bool IsCallOrNew(Bytecode bytecode);
552
Ben Murdochda12d292016-06-02 14:46:10 +0100553 // Returns true if the bytecode is a call to the runtime.
554 static bool IsCallRuntime(Bytecode bytecode);
555
Ben Murdoch097c5b22016-05-18 11:27:45 +0100556 // Returns true if the bytecode is a debug break.
557 static bool IsDebugBreak(Bytecode bytecode);
558
Ben Murdochc5610432016-08-08 18:44:38 +0100559 // Returns true if the bytecode is Ldar or Star.
560 static bool IsLdarOrStar(Bytecode bytecode);
561
Ben Murdochda12d292016-06-02 14:46:10 +0100562 // Returns true if the bytecode has wider operand forms.
563 static bool IsBytecodeWithScalableOperands(Bytecode bytecode);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100564
Ben Murdochda12d292016-06-02 14:46:10 +0100565 // Returns true if the bytecode is a scaling prefix bytecode.
566 static bool IsPrefixScalingBytecode(Bytecode bytecode);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100567
568 // Returns true if |operand_type| is any type of register operand.
569 static bool IsRegisterOperandType(OperandType operand_type);
570
571 // Returns true if |operand_type| represents a register used as an input.
572 static bool IsRegisterInputOperandType(OperandType operand_type);
573
574 // Returns true if |operand_type| represents a register used as an output.
575 static bool IsRegisterOutputOperandType(OperandType operand_type);
576
Ben Murdochc5610432016-08-08 18:44:38 +0100577 // Returns the number of registers represented by a register operand. For
578 // instance, a RegPair represents two registers.
579 static int GetNumberOfRegistersRepresentedBy(OperandType operand_type);
580
Ben Murdoch097c5b22016-05-18 11:27:45 +0100581 // Returns true if |operand_type| is a maybe register operand
Ben Murdochda12d292016-06-02 14:46:10 +0100582 // (kMaybeReg).
Ben Murdoch097c5b22016-05-18 11:27:45 +0100583 static bool IsMaybeRegisterOperandType(OperandType operand_type);
584
Ben Murdochda12d292016-06-02 14:46:10 +0100585 // Returns true if |operand_type| is a runtime-id operand (kRuntimeId).
586 static bool IsRuntimeIdOperandType(OperandType operand_type);
587
588 // Returns true if |operand_type| is unsigned, false if signed.
589 static bool IsUnsignedOperandType(OperandType operand_type);
590
591 // Decodes a register operand in a byte array.
592 static Register DecodeRegisterOperand(const uint8_t* operand_start,
593 OperandType operand_type,
594 OperandScale operand_scale);
595
596 // Decodes a signed operand in a byte array.
597 static int32_t DecodeSignedOperand(const uint8_t* operand_start,
598 OperandType operand_type,
599 OperandScale operand_scale);
600
601 // Decodes an unsigned operand in a byte array.
602 static uint32_t DecodeUnsignedOperand(const uint8_t* operand_start,
603 OperandType operand_type,
604 OperandScale operand_scale);
605
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000606 // Decode a single bytecode and operands to |os|.
607 static std::ostream& Decode(std::ostream& os, const uint8_t* bytecode_start,
608 int number_of_parameters);
609
Ben Murdochda12d292016-06-02 14:46:10 +0100610 // Returns true if a handler is generated for a bytecode at a given
611 // operand scale. All bytecodes have handlers at OperandScale::kSingle,
612 // but only bytecodes with scalable operands have handlers with larger
613 // OperandScale values.
614 static bool BytecodeHasHandler(Bytecode bytecode, OperandScale operand_scale);
615
Ben Murdochc5610432016-08-08 18:44:38 +0100616 // Return the operand size required to hold a signed operand.
617 static OperandSize SizeForSignedOperand(int value);
618
619 // Return the operand size required to hold an unsigned operand.
620 static OperandSize SizeForUnsignedOperand(int value);
621
622 // Return the operand size required to hold an unsigned operand.
623 static OperandSize SizeForUnsignedOperand(size_t value);
624
625 // Return the OperandScale required for bytecode emission of
626 // operand sizes.
627 static OperandScale OperandSizesToScale(
628 OperandSize size0, OperandSize size1 = OperandSize::kByte,
629 OperandSize size2 = OperandSize::kByte,
630 OperandSize size3 = OperandSize::kByte);
Ben Murdochda12d292016-06-02 14:46:10 +0100631
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000632 private:
633 DISALLOW_IMPLICIT_CONSTRUCTORS(Bytecodes);
634};
635
Ben Murdochc5610432016-08-08 18:44:38 +0100636class CreateObjectLiteralFlags {
637 public:
638 class FlagsBits : public BitField8<int, 0, 3> {};
639 class FastClonePropertiesCountBits
640 : public BitField8<int, FlagsBits::kNext, 3> {};
641 STATIC_ASSERT((FlagsBits::kMask & FastClonePropertiesCountBits::kMask) == 0);
642};
643
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000644std::ostream& operator<<(std::ostream& os, const Bytecode& bytecode);
Ben Murdochda12d292016-06-02 14:46:10 +0100645std::ostream& operator<<(std::ostream& os, const AccumulatorUse& use);
646std::ostream& operator<<(std::ostream& os, const OperandScale& operand_scale);
647std::ostream& operator<<(std::ostream& os, const OperandSize& operand_size);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000648std::ostream& operator<<(std::ostream& os, const OperandType& operand_type);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000649
650} // namespace interpreter
651} // namespace internal
652} // namespace v8
653
654#endif // V8_INTERPRETER_BYTECODES_H_