• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // 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!
12 #include "src/utils.h"
13 
14 namespace v8 {
15 namespace internal {
16 namespace interpreter {
17 
18 // The list of operand types used by bytecodes.
19 #define OPERAND_TYPE_LIST(V)       \
20                                    \
21   /* None operand. */              \
22   V(None, OperandSize::kNone)      \
23                                    \
24   /* Byte operands. */             \
25   V(Count8, OperandSize::kByte)    \
26   V(Imm8, OperandSize::kByte)      \
27   V(Idx8, OperandSize::kByte)      \
28   V(MaybeReg8, OperandSize::kByte) \
29   V(Reg8, OperandSize::kByte)      \
30   V(RegPair8, OperandSize::kByte)  \
31                                    \
32   /* Short operands. */            \
33   V(Count16, OperandSize::kShort)  \
34   V(Idx16, OperandSize::kShort)    \
35   V(Reg16, OperandSize::kShort)
36 
37 // The list of bytecodes which are interpreted by the interpreter.
38 #define BYTECODE_LIST(V)                                                       \
39                                                                                \
40   /* Loading the accumulator */                                                \
41   V(LdaZero, OperandType::kNone)                                               \
42   V(LdaSmi8, OperandType::kImm8)                                               \
43   V(LdaUndefined, OperandType::kNone)                                          \
44   V(LdaNull, OperandType::kNone)                                               \
45   V(LdaTheHole, OperandType::kNone)                                            \
46   V(LdaTrue, OperandType::kNone)                                               \
47   V(LdaFalse, OperandType::kNone)                                              \
48   V(LdaConstant, OperandType::kIdx8)                                           \
49   V(LdaConstantWide, OperandType::kIdx16)                                      \
50                                                                                \
51   /* Globals */                                                                \
52   V(LdaGlobalSloppy, OperandType::kIdx8, OperandType::kIdx8)                   \
53   V(LdaGlobalStrict, OperandType::kIdx8, OperandType::kIdx8)                   \
54   V(LdaGlobalInsideTypeofSloppy, OperandType::kIdx8, OperandType::kIdx8)       \
55   V(LdaGlobalInsideTypeofStrict, OperandType::kIdx8, OperandType::kIdx8)       \
56   V(LdaGlobalSloppyWide, OperandType::kIdx16, OperandType::kIdx16)             \
57   V(LdaGlobalStrictWide, OperandType::kIdx16, OperandType::kIdx16)             \
58   V(LdaGlobalInsideTypeofSloppyWide, OperandType::kIdx16, OperandType::kIdx16) \
59   V(LdaGlobalInsideTypeofStrictWide, OperandType::kIdx16, OperandType::kIdx16) \
60   V(StaGlobalSloppy, OperandType::kIdx8, OperandType::kIdx8)                   \
61   V(StaGlobalStrict, OperandType::kIdx8, OperandType::kIdx8)                   \
62   V(StaGlobalSloppyWide, OperandType::kIdx16, OperandType::kIdx16)             \
63   V(StaGlobalStrictWide, OperandType::kIdx16, OperandType::kIdx16)             \
64                                                                                \
65   /* Context operations */                                                     \
66   V(PushContext, OperandType::kReg8)                                           \
67   V(PopContext, OperandType::kReg8)                                            \
68   V(LdaContextSlot, OperandType::kReg8, OperandType::kIdx8)                    \
69   V(StaContextSlot, OperandType::kReg8, OperandType::kIdx8)                    \
70   V(LdaContextSlotWide, OperandType::kReg8, OperandType::kIdx16)               \
71   V(StaContextSlotWide, OperandType::kReg8, OperandType::kIdx16)               \
72                                                                                \
73   /* Load-Store lookup slots */                                                \
74   V(LdaLookupSlot, OperandType::kIdx8)                                         \
75   V(LdaLookupSlotInsideTypeof, OperandType::kIdx8)                             \
76   V(LdaLookupSlotWide, OperandType::kIdx16)                                    \
77   V(LdaLookupSlotInsideTypeofWide, OperandType::kIdx16)                        \
78   V(StaLookupSlotSloppy, OperandType::kIdx8)                                   \
79   V(StaLookupSlotStrict, OperandType::kIdx8)                                   \
80   V(StaLookupSlotSloppyWide, OperandType::kIdx16)                              \
81   V(StaLookupSlotStrictWide, OperandType::kIdx16)                              \
82                                                                                \
83   /* Register-accumulator transfers */                                         \
84   V(Ldar, OperandType::kReg8)                                                  \
85   V(Star, OperandType::kReg8)                                                  \
86                                                                                \
87   /* Register-register transfers */                                            \
88   V(Mov, OperandType::kReg8, OperandType::kReg8)                               \
89   V(Exchange, OperandType::kReg8, OperandType::kReg16)                         \
90   V(ExchangeWide, OperandType::kReg16, OperandType::kReg16)                    \
91                                                                                \
92   /* LoadIC operations */                                                      \
93   V(LoadICSloppy, OperandType::kReg8, OperandType::kIdx8, OperandType::kIdx8)  \
94   V(LoadICStrict, OperandType::kReg8, OperandType::kIdx8, OperandType::kIdx8)  \
95   V(KeyedLoadICSloppy, OperandType::kReg8, OperandType::kIdx8)                 \
96   V(KeyedLoadICStrict, OperandType::kReg8, OperandType::kIdx8)                 \
97   /* TODO(rmcilroy): Wide register operands too? */                            \
98   V(LoadICSloppyWide, OperandType::kReg8, OperandType::kIdx16,                 \
99     OperandType::kIdx16)                                                       \
100   V(LoadICStrictWide, OperandType::kReg8, OperandType::kIdx16,                 \
101     OperandType::kIdx16)                                                       \
102   V(KeyedLoadICSloppyWide, OperandType::kReg8, OperandType::kIdx16)            \
103   V(KeyedLoadICStrictWide, OperandType::kReg8, OperandType::kIdx16)            \
104                                                                                \
105   /* StoreIC operations */                                                     \
106   V(StoreICSloppy, OperandType::kReg8, OperandType::kIdx8, OperandType::kIdx8) \
107   V(StoreICStrict, OperandType::kReg8, OperandType::kIdx8, OperandType::kIdx8) \
108   V(KeyedStoreICSloppy, OperandType::kReg8, OperandType::kReg8,                \
109     OperandType::kIdx8)                                                        \
110   V(KeyedStoreICStrict, OperandType::kReg8, OperandType::kReg8,                \
111     OperandType::kIdx8)                                                        \
112   /* TODO(rmcilroy): Wide register operands too? */                            \
113   V(StoreICSloppyWide, OperandType::kReg8, OperandType::kIdx16,                \
114     OperandType::kIdx16)                                                       \
115   V(StoreICStrictWide, OperandType::kReg8, OperandType::kIdx16,                \
116     OperandType::kIdx16)                                                       \
117   V(KeyedStoreICSloppyWide, OperandType::kReg8, OperandType::kReg8,            \
118     OperandType::kIdx16)                                                       \
119   V(KeyedStoreICStrictWide, OperandType::kReg8, OperandType::kReg8,            \
120     OperandType::kIdx16)                                                       \
121                                                                                \
122   /* Binary Operators */                                                       \
123   V(Add, OperandType::kReg8)                                                   \
124   V(Sub, OperandType::kReg8)                                                   \
125   V(Mul, OperandType::kReg8)                                                   \
126   V(Div, OperandType::kReg8)                                                   \
127   V(Mod, OperandType::kReg8)                                                   \
128   V(BitwiseOr, OperandType::kReg8)                                             \
129   V(BitwiseXor, OperandType::kReg8)                                            \
130   V(BitwiseAnd, OperandType::kReg8)                                            \
131   V(ShiftLeft, OperandType::kReg8)                                             \
132   V(ShiftRight, OperandType::kReg8)                                            \
133   V(ShiftRightLogical, OperandType::kReg8)                                     \
134                                                                                \
135   /* Unary Operators */                                                        \
136   V(Inc, OperandType::kNone)                                                   \
137   V(Dec, OperandType::kNone)                                                   \
138   V(LogicalNot, OperandType::kNone)                                            \
139   V(TypeOf, OperandType::kNone)                                                \
140   V(DeletePropertyStrict, OperandType::kReg8)                                  \
141   V(DeletePropertySloppy, OperandType::kReg8)                                  \
142   V(DeleteLookupSlot, OperandType::kNone)                                      \
143                                                                                \
144   /* Call operations */                                                        \
145   V(Call, OperandType::kReg8, OperandType::kReg8, OperandType::kCount8,        \
146     OperandType::kIdx8)                                                        \
147   V(CallWide, OperandType::kReg8, OperandType::kReg8, OperandType::kCount16,   \
148     OperandType::kIdx16)                                                       \
149   V(CallRuntime, OperandType::kIdx16, OperandType::kMaybeReg8,                 \
150     OperandType::kCount8)                                                      \
151   V(CallRuntimeForPair, OperandType::kIdx16, OperandType::kMaybeReg8,          \
152     OperandType::kCount8, OperandType::kRegPair8)                              \
153   V(CallJSRuntime, OperandType::kIdx16, OperandType::kReg8,                    \
154     OperandType::kCount8)                                                      \
155                                                                                \
156   /* New operator */                                                           \
157   V(New, OperandType::kReg8, OperandType::kMaybeReg8, OperandType::kCount8)    \
158                                                                                \
159   /* Test Operators */                                                         \
160   V(TestEqual, OperandType::kReg8)                                             \
161   V(TestNotEqual, OperandType::kReg8)                                          \
162   V(TestEqualStrict, OperandType::kReg8)                                       \
163   V(TestNotEqualStrict, OperandType::kReg8)                                    \
164   V(TestLessThan, OperandType::kReg8)                                          \
165   V(TestGreaterThan, OperandType::kReg8)                                       \
166   V(TestLessThanOrEqual, OperandType::kReg8)                                   \
167   V(TestGreaterThanOrEqual, OperandType::kReg8)                                \
168   V(TestInstanceOf, OperandType::kReg8)                                        \
169   V(TestIn, OperandType::kReg8)                                                \
170                                                                                \
171   /* Cast operators */                                                         \
172   V(ToName, OperandType::kNone)                                                \
173   V(ToNumber, OperandType::kNone)                                              \
174   V(ToObject, OperandType::kNone)                                              \
175                                                                                \
176   /* Literals */                                                               \
177   V(CreateRegExpLiteral, OperandType::kIdx8, OperandType::kIdx8,               \
178     OperandType::kImm8)                                                        \
179   V(CreateArrayLiteral, OperandType::kIdx8, OperandType::kIdx8,                \
180     OperandType::kImm8)                                                        \
181   V(CreateObjectLiteral, OperandType::kIdx8, OperandType::kIdx8,               \
182     OperandType::kImm8)                                                        \
183   V(CreateRegExpLiteralWide, OperandType::kIdx16, OperandType::kIdx16,         \
184     OperandType::kImm8)                                                        \
185   V(CreateArrayLiteralWide, OperandType::kIdx16, OperandType::kIdx16,          \
186     OperandType::kImm8)                                                        \
187   V(CreateObjectLiteralWide, OperandType::kIdx16, OperandType::kIdx16,         \
188     OperandType::kImm8)                                                        \
189                                                                                \
190   /* Closure allocation */                                                     \
191   V(CreateClosure, OperandType::kIdx8, OperandType::kImm8)                     \
192   V(CreateClosureWide, OperandType::kIdx16, OperandType::kImm8)                \
193                                                                                \
194   /* Arguments allocation */                                                   \
195   V(CreateMappedArguments, OperandType::kNone)                                 \
196   V(CreateUnmappedArguments, OperandType::kNone)                               \
197                                                                                \
198   /* Control Flow */                                                           \
199   V(Jump, OperandType::kImm8)                                                  \
200   V(JumpConstant, OperandType::kIdx8)                                          \
201   V(JumpConstantWide, OperandType::kIdx16)                                     \
202   V(JumpIfTrue, OperandType::kImm8)                                            \
203   V(JumpIfTrueConstant, OperandType::kIdx8)                                    \
204   V(JumpIfTrueConstantWide, OperandType::kIdx16)                               \
205   V(JumpIfFalse, OperandType::kImm8)                                           \
206   V(JumpIfFalseConstant, OperandType::kIdx8)                                   \
207   V(JumpIfFalseConstantWide, OperandType::kIdx16)                              \
208   V(JumpIfToBooleanTrue, OperandType::kImm8)                                   \
209   V(JumpIfToBooleanTrueConstant, OperandType::kIdx8)                           \
210   V(JumpIfToBooleanTrueConstantWide, OperandType::kIdx16)                      \
211   V(JumpIfToBooleanFalse, OperandType::kImm8)                                  \
212   V(JumpIfToBooleanFalseConstant, OperandType::kIdx8)                          \
213   V(JumpIfToBooleanFalseConstantWide, OperandType::kIdx16)                     \
214   V(JumpIfNull, OperandType::kImm8)                                            \
215   V(JumpIfNullConstant, OperandType::kIdx8)                                    \
216   V(JumpIfNullConstantWide, OperandType::kIdx16)                               \
217   V(JumpIfUndefined, OperandType::kImm8)                                       \
218   V(JumpIfUndefinedConstant, OperandType::kIdx8)                               \
219   V(JumpIfUndefinedConstantWide, OperandType::kIdx16)                          \
220                                                                                \
221   /* Complex flow control For..in */                                           \
222   V(ForInPrepare, OperandType::kReg8, OperandType::kReg8, OperandType::kReg8)  \
223   V(ForInDone, OperandType::kReg8, OperandType::kReg8)                         \
224   V(ForInNext, OperandType::kReg8, OperandType::kReg8, OperandType::kReg8,     \
225     OperandType::kReg8)                                                        \
226   V(ForInStep, OperandType::kReg8)                                             \
227                                                                                \
228   /* Non-local flow control */                                                 \
229   V(Throw, OperandType::kNone)                                                 \
230   V(Return, OperandType::kNone)
231 
232 
233 // Enumeration of the size classes of operand types used by bytecodes.
234 enum class OperandSize : uint8_t {
235   kNone = 0,
236   kByte = 1,
237   kShort = 2,
238 };
239 
240 
241 // Enumeration of operand types used by bytecodes.
242 enum class OperandType : uint8_t {
243 #define DECLARE_OPERAND_TYPE(Name, _) k##Name,
244   OPERAND_TYPE_LIST(DECLARE_OPERAND_TYPE)
245 #undef DECLARE_OPERAND_TYPE
246 #define COUNT_OPERAND_TYPES(x, _) +1
247   // The COUNT_OPERAND macro will turn this into kLast = -1 +1 +1... which will
248   // evaluate to the same value as the last operand.
249   kLast = -1 OPERAND_TYPE_LIST(COUNT_OPERAND_TYPES)
250 #undef COUNT_OPERAND_TYPES
251 };
252 
253 
254 // Enumeration of interpreter bytecodes.
255 enum class Bytecode : uint8_t {
256 #define DECLARE_BYTECODE(Name, ...) k##Name,
257   BYTECODE_LIST(DECLARE_BYTECODE)
258 #undef DECLARE_BYTECODE
259 #define COUNT_BYTECODE(x, ...) +1
260   // The COUNT_BYTECODE macro will turn this into kLast = -1 +1 +1... which will
261   // evaluate to the same value as the last real bytecode.
262   kLast = -1 BYTECODE_LIST(COUNT_BYTECODE)
263 #undef COUNT_BYTECODE
264 };
265 
266 
267 // An interpreter Register which is located in the function's Register file
268 // in its stack-frame. Register hold parameters, this, and expression values.
269 class Register {
270  public:
Register()271   Register() : index_(kIllegalIndex) {}
272 
Register(int index)273   explicit Register(int index) : index_(index) {}
274 
index()275   int index() const {
276     DCHECK(index_ != kIllegalIndex);
277     return index_;
278   }
is_parameter()279   bool is_parameter() const { return index() < 0; }
is_valid()280   bool is_valid() const { return index_ != kIllegalIndex; }
281 
282   static Register FromParameterIndex(int index, int parameter_count);
283   int ToParameterIndex(int parameter_count) const;
284   static int MaxParameterIndex();
285 
286   // Returns the register for the function's closure object.
287   static Register function_closure();
288   bool is_function_closure() const;
289 
290   // Returns the register for the function's outer context.
291   static Register function_context();
292   bool is_function_context() const;
293 
294   // Returns the register for the incoming new target value.
295   static Register new_target();
296   bool is_new_target() const;
297 
298   static Register FromOperand(uint8_t operand);
299   uint8_t ToOperand() const;
300 
301   static Register FromWideOperand(uint16_t operand);
302   uint16_t ToWideOperand() const;
303 
304   static bool AreContiguous(Register reg1, Register reg2,
305                             Register reg3 = Register(),
306                             Register reg4 = Register(),
307                             Register reg5 = Register());
308 
309   bool operator==(const Register& other) const {
310     return index() == other.index();
311   }
312   bool operator!=(const Register& other) const {
313     return index() != other.index();
314   }
315   bool operator<(const Register& other) const {
316     return index() < other.index();
317   }
318   bool operator<=(const Register& other) const {
319     return index() <= other.index();
320   }
321 
322  private:
323   static const int kIllegalIndex = kMaxInt;
324 
325   void* operator new(size_t size);
326   void operator delete(void* p);
327 
328   int index_;
329 };
330 
331 
332 class Bytecodes {
333  public:
334   // Returns string representation of |bytecode|.
335   static const char* ToString(Bytecode bytecode);
336 
337   // Returns string representation of |operand_type|.
338   static const char* OperandTypeToString(OperandType operand_type);
339 
340   // Returns string representation of |operand_size|.
341   static const char* OperandSizeToString(OperandSize operand_size);
342 
343   // Returns byte value of bytecode.
344   static uint8_t ToByte(Bytecode bytecode);
345 
346   // Returns bytecode for |value|.
347   static Bytecode FromByte(uint8_t value);
348 
349   // Returns the number of operands expected by |bytecode|.
350   static int NumberOfOperands(Bytecode bytecode);
351 
352   // Return the i-th operand of |bytecode|.
353   static OperandType GetOperandType(Bytecode bytecode, int i);
354 
355   // Return the size of the i-th operand of |bytecode|.
356   static OperandSize GetOperandSize(Bytecode bytecode, int i);
357 
358   // Returns the offset of the i-th operand of |bytecode| relative to the start
359   // of the bytecode.
360   static int GetOperandOffset(Bytecode bytecode, int i);
361 
362   // Returns the size of the bytecode including its operands.
363   static int Size(Bytecode bytecode);
364 
365   // Returns the size of |operand|.
366   static OperandSize SizeOfOperand(OperandType operand);
367 
368   // Return true if the bytecode is a conditional jump taking
369   // an immediate byte operand (OperandType::kImm8).
370   static bool IsConditionalJumpImmediate(Bytecode bytecode);
371 
372   // Return true if the bytecode is a conditional jump taking
373   // a constant pool entry (OperandType::kIdx8).
374   static bool IsConditionalJumpConstant(Bytecode bytecode);
375 
376   // Return true if the bytecode is a conditional jump taking
377   // a constant pool entry (OperandType::kIdx16).
378   static bool IsConditionalJumpConstantWide(Bytecode bytecode);
379 
380   // Return true if the bytecode is a conditional jump taking
381   // any kind of operand.
382   static bool IsConditionalJump(Bytecode bytecode);
383 
384   // Return true if the bytecode is a jump or a conditional jump taking
385   // an immediate byte operand (OperandType::kImm8).
386   static bool IsJumpImmediate(Bytecode bytecode);
387 
388   // Return true if the bytecode is a jump or conditional jump taking a
389   // constant pool entry (OperandType::kIdx8).
390   static bool IsJumpConstant(Bytecode bytecode);
391 
392   // Return true if the bytecode is a jump or conditional jump taking a
393   // constant pool entry (OperandType::kIdx16).
394   static bool IsJumpConstantWide(Bytecode bytecode);
395 
396   // Return true if the bytecode is a jump or conditional jump taking
397   // any kind of operand.
398   static bool IsJump(Bytecode bytecode);
399 
400   // Return true if the bytecode is a conditional jump, a jump, or a return.
401   static bool IsJumpOrReturn(Bytecode bytecode);
402 
403   // Decode a single bytecode and operands to |os|.
404   static std::ostream& Decode(std::ostream& os, const uint8_t* bytecode_start,
405                               int number_of_parameters);
406 
407  private:
408   DISALLOW_IMPLICIT_CONSTRUCTORS(Bytecodes);
409 };
410 
411 std::ostream& operator<<(std::ostream& os, const Bytecode& bytecode);
412 std::ostream& operator<<(std::ostream& os, const OperandType& operand_type);
413 std::ostream& operator<<(std::ostream& os, const OperandSize& operand_type);
414 
415 }  // namespace interpreter
416 }  // namespace internal
417 }  // namespace v8
418 
419 #endif  // V8_INTERPRETER_BYTECODES_H_
420