blob: c3b17c7b10573f4712d5377258212d381f66dd28 [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#include "src/interpreter/bytecodes.h"
6
7#include "src/frames.h"
8#include "src/interpreter/bytecode-traits.h"
9
10namespace v8 {
11namespace internal {
12namespace interpreter {
13
14
15// static
16const char* Bytecodes::ToString(Bytecode bytecode) {
17 switch (bytecode) {
18#define CASE(Name, ...) \
19 case Bytecode::k##Name: \
20 return #Name;
21 BYTECODE_LIST(CASE)
22#undef CASE
23 }
24 UNREACHABLE();
25 return "";
26}
27
28
29// static
30const char* Bytecodes::OperandTypeToString(OperandType operand_type) {
31 switch (operand_type) {
32#define CASE(Name, _) \
33 case OperandType::k##Name: \
34 return #Name;
35 OPERAND_TYPE_LIST(CASE)
36#undef CASE
37 }
38 UNREACHABLE();
39 return "";
40}
41
42
43// static
44const char* Bytecodes::OperandSizeToString(OperandSize operand_size) {
45 switch (operand_size) {
46 case OperandSize::kNone:
47 return "None";
48 case OperandSize::kByte:
49 return "Byte";
50 case OperandSize::kShort:
51 return "Short";
52 }
53 UNREACHABLE();
54 return "";
55}
56
57
58// static
59uint8_t Bytecodes::ToByte(Bytecode bytecode) {
Ben Murdoch097c5b22016-05-18 11:27:45 +010060 DCHECK(bytecode <= Bytecode::kLast);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000061 return static_cast<uint8_t>(bytecode);
62}
63
64
65// static
66Bytecode Bytecodes::FromByte(uint8_t value) {
67 Bytecode bytecode = static_cast<Bytecode>(value);
68 DCHECK(bytecode <= Bytecode::kLast);
69 return bytecode;
70}
71
72
73// static
Ben Murdoch097c5b22016-05-18 11:27:45 +010074Bytecode Bytecodes::GetDebugBreak(Bytecode bytecode) {
75 switch (Size(bytecode)) {
76#define CASE(Name, ...) \
77 case BytecodeTraits<__VA_ARGS__, OPERAND_TERM>::kSize: \
78 return Bytecode::k##Name;
79 DEBUG_BREAK_BYTECODE_LIST(CASE)
80#undef CASE
81 default:
82 break;
83 }
84 UNREACHABLE();
85 return static_cast<Bytecode>(-1);
86}
87
88// static
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000089int Bytecodes::Size(Bytecode bytecode) {
90 DCHECK(bytecode <= Bytecode::kLast);
91 switch (bytecode) {
92#define CASE(Name, ...) \
93 case Bytecode::k##Name: \
94 return BytecodeTraits<__VA_ARGS__, OPERAND_TERM>::kSize;
95 BYTECODE_LIST(CASE)
96#undef CASE
97 }
98 UNREACHABLE();
99 return 0;
100}
101
102
103// static
104int Bytecodes::NumberOfOperands(Bytecode bytecode) {
105 DCHECK(bytecode <= Bytecode::kLast);
106 switch (bytecode) {
107#define CASE(Name, ...) \
108 case Bytecode::k##Name: \
109 return BytecodeTraits<__VA_ARGS__, OPERAND_TERM>::kOperandCount;
110 BYTECODE_LIST(CASE)
111#undef CASE
112 }
113 UNREACHABLE();
114 return 0;
115}
116
117
118// static
Ben Murdoch097c5b22016-05-18 11:27:45 +0100119int Bytecodes::NumberOfRegisterOperands(Bytecode bytecode) {
120 DCHECK(bytecode <= Bytecode::kLast);
121 switch (bytecode) {
122#define CASE(Name, ...) \
123 case Bytecode::k##Name: \
124 typedef BytecodeTraits<__VA_ARGS__, OPERAND_TERM> Name##Trait; \
125 return Name##Trait::kRegisterOperandCount;
126 BYTECODE_LIST(CASE)
127#undef CASE
128 }
129 UNREACHABLE();
130 return false;
131}
132
133// static
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000134OperandType Bytecodes::GetOperandType(Bytecode bytecode, int i) {
135 DCHECK(bytecode <= Bytecode::kLast);
136 switch (bytecode) {
137#define CASE(Name, ...) \
138 case Bytecode::k##Name: \
139 return BytecodeTraits<__VA_ARGS__, OPERAND_TERM>::GetOperandType(i);
140 BYTECODE_LIST(CASE)
141#undef CASE
142 }
143 UNREACHABLE();
144 return OperandType::kNone;
145}
146
147
148// static
149OperandSize Bytecodes::GetOperandSize(Bytecode bytecode, int i) {
150 DCHECK(bytecode <= Bytecode::kLast);
151 switch (bytecode) {
152#define CASE(Name, ...) \
153 case Bytecode::k##Name: \
154 return BytecodeTraits<__VA_ARGS__, OPERAND_TERM>::GetOperandSize(i);
155 BYTECODE_LIST(CASE)
156#undef CASE
157 }
158 UNREACHABLE();
159 return OperandSize::kNone;
160}
161
162
163// static
Ben Murdoch097c5b22016-05-18 11:27:45 +0100164int Bytecodes::GetRegisterOperandBitmap(Bytecode bytecode) {
165 DCHECK(bytecode <= Bytecode::kLast);
166 switch (bytecode) {
167#define CASE(Name, ...) \
168 case Bytecode::k##Name: \
169 typedef BytecodeTraits<__VA_ARGS__, OPERAND_TERM> Name##Trait; \
170 return Name##Trait::kRegisterOperandBitmap;
171 BYTECODE_LIST(CASE)
172#undef CASE
173 }
174 UNREACHABLE();
175 return false;
176}
177
178// static
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000179int Bytecodes::GetOperandOffset(Bytecode bytecode, int i) {
180 DCHECK(bytecode <= Bytecode::kLast);
181 switch (bytecode) {
182#define CASE(Name, ...) \
183 case Bytecode::k##Name: \
184 return BytecodeTraits<__VA_ARGS__, OPERAND_TERM>::GetOperandOffset(i);
185 BYTECODE_LIST(CASE)
186#undef CASE
187 }
188 UNREACHABLE();
189 return 0;
190}
191
192
193// static
194OperandSize Bytecodes::SizeOfOperand(OperandType operand_type) {
195 switch (operand_type) {
196#define CASE(Name, Size) \
197 case OperandType::k##Name: \
198 return Size;
199 OPERAND_TYPE_LIST(CASE)
200#undef CASE
201 }
202 UNREACHABLE();
203 return OperandSize::kNone;
204}
205
206
207// static
208bool Bytecodes::IsConditionalJumpImmediate(Bytecode bytecode) {
209 return bytecode == Bytecode::kJumpIfTrue ||
210 bytecode == Bytecode::kJumpIfFalse ||
211 bytecode == Bytecode::kJumpIfToBooleanTrue ||
212 bytecode == Bytecode::kJumpIfToBooleanFalse ||
Ben Murdoch097c5b22016-05-18 11:27:45 +0100213 bytecode == Bytecode::kJumpIfNotHole ||
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000214 bytecode == Bytecode::kJumpIfNull ||
215 bytecode == Bytecode::kJumpIfUndefined;
216}
217
218
219// static
220bool Bytecodes::IsConditionalJumpConstant(Bytecode bytecode) {
221 return bytecode == Bytecode::kJumpIfTrueConstant ||
222 bytecode == Bytecode::kJumpIfFalseConstant ||
223 bytecode == Bytecode::kJumpIfToBooleanTrueConstant ||
224 bytecode == Bytecode::kJumpIfToBooleanFalseConstant ||
Ben Murdoch097c5b22016-05-18 11:27:45 +0100225 bytecode == Bytecode::kJumpIfNotHoleConstant ||
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000226 bytecode == Bytecode::kJumpIfNullConstant ||
227 bytecode == Bytecode::kJumpIfUndefinedConstant;
228}
229
230
231// static
232bool Bytecodes::IsConditionalJumpConstantWide(Bytecode bytecode) {
233 return bytecode == Bytecode::kJumpIfTrueConstantWide ||
234 bytecode == Bytecode::kJumpIfFalseConstantWide ||
235 bytecode == Bytecode::kJumpIfToBooleanTrueConstantWide ||
236 bytecode == Bytecode::kJumpIfToBooleanFalseConstantWide ||
Ben Murdoch097c5b22016-05-18 11:27:45 +0100237 bytecode == Bytecode::kJumpIfNotHoleConstantWide ||
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000238 bytecode == Bytecode::kJumpIfNullConstantWide ||
239 bytecode == Bytecode::kJumpIfUndefinedConstantWide;
240}
241
242
243// static
244bool Bytecodes::IsConditionalJump(Bytecode bytecode) {
245 return IsConditionalJumpImmediate(bytecode) ||
246 IsConditionalJumpConstant(bytecode) ||
247 IsConditionalJumpConstantWide(bytecode);
248}
249
250
251// static
252bool Bytecodes::IsJumpImmediate(Bytecode bytecode) {
253 return bytecode == Bytecode::kJump || IsConditionalJumpImmediate(bytecode);
254}
255
256
257// static
258bool Bytecodes::IsJumpConstant(Bytecode bytecode) {
259 return bytecode == Bytecode::kJumpConstant ||
260 IsConditionalJumpConstant(bytecode);
261}
262
263
264// static
265bool Bytecodes::IsJumpConstantWide(Bytecode bytecode) {
266 return bytecode == Bytecode::kJumpConstantWide ||
267 IsConditionalJumpConstantWide(bytecode);
268}
269
270
271// static
272bool Bytecodes::IsJump(Bytecode bytecode) {
273 return IsJumpImmediate(bytecode) || IsJumpConstant(bytecode) ||
274 IsJumpConstantWide(bytecode);
275}
276
277
278// static
Ben Murdoch097c5b22016-05-18 11:27:45 +0100279bool Bytecodes::IsCallOrNew(Bytecode bytecode) {
280 return bytecode == Bytecode::kCall || bytecode == Bytecode::kTailCall ||
281 bytecode == Bytecode::kNew || bytecode == Bytecode::kCallWide ||
282 bytecode == Bytecode::kTailCallWide || bytecode == Bytecode::kNewWide;
283}
284
285// static
286bool Bytecodes::IsDebugBreak(Bytecode bytecode) {
287 switch (bytecode) {
288#define CASE(Name, ...) case Bytecode::k##Name:
289 DEBUG_BREAK_BYTECODE_LIST(CASE);
290#undef CASE
291 return true;
292 default:
293 break;
294 }
295 return false;
296}
297
298// static
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000299bool Bytecodes::IsJumpOrReturn(Bytecode bytecode) {
300 return bytecode == Bytecode::kReturn || IsJump(bytecode);
301}
302
Ben Murdoch097c5b22016-05-18 11:27:45 +0100303// static
304bool Bytecodes::IsIndexOperandType(OperandType operand_type) {
305 return operand_type == OperandType::kIdx8 ||
306 operand_type == OperandType::kIdx16;
307}
308
309// static
310bool Bytecodes::IsImmediateOperandType(OperandType operand_type) {
311 return operand_type == OperandType::kImm8;
312}
313
314// static
315bool Bytecodes::IsRegisterCountOperandType(OperandType operand_type) {
316 return (operand_type == OperandType::kRegCount8 ||
317 operand_type == OperandType::kRegCount16);
318}
319
320// static
321bool Bytecodes::IsMaybeRegisterOperandType(OperandType operand_type) {
322 return (operand_type == OperandType::kMaybeReg8 ||
323 operand_type == OperandType::kMaybeReg16);
324}
325
326// static
327bool Bytecodes::IsRegisterOperandType(OperandType operand_type) {
328 switch (operand_type) {
329#define CASE(Name, _) \
330 case OperandType::k##Name: \
331 return true;
332 REGISTER_OPERAND_TYPE_LIST(CASE)
333#undef CASE
334#define CASE(Name, _) \
335 case OperandType::k##Name: \
336 break;
337 NON_REGISTER_OPERAND_TYPE_LIST(CASE)
338#undef CASE
339 }
340 return false;
341}
342
343// static
344bool Bytecodes::IsRegisterInputOperandType(OperandType operand_type) {
345 switch (operand_type) {
346#define CASE(Name, _) \
347 case OperandType::k##Name: \
348 return true;
349 REGISTER_INPUT_OPERAND_TYPE_LIST(CASE)
350#undef CASE
351#define CASE(Name, _) \
352 case OperandType::k##Name: \
353 break;
354 NON_REGISTER_OPERAND_TYPE_LIST(CASE)
355 REGISTER_OUTPUT_OPERAND_TYPE_LIST(CASE)
356#undef CASE
357 }
358 return false;
359}
360
361// static
362bool Bytecodes::IsRegisterOutputOperandType(OperandType operand_type) {
363 switch (operand_type) {
364#define CASE(Name, _) \
365 case OperandType::k##Name: \
366 return true;
367 REGISTER_OUTPUT_OPERAND_TYPE_LIST(CASE)
368#undef CASE
369#define CASE(Name, _) \
370 case OperandType::k##Name: \
371 break;
372 NON_REGISTER_OPERAND_TYPE_LIST(CASE)
373 REGISTER_INPUT_OPERAND_TYPE_LIST(CASE)
374#undef CASE
375 }
376 return false;
377}
378
379namespace {
380static Register DecodeRegister(const uint8_t* operand_start,
381 OperandType operand_type) {
382 switch (Bytecodes::SizeOfOperand(operand_type)) {
383 case OperandSize::kByte:
384 return Register::FromOperand(*operand_start);
385 case OperandSize::kShort:
386 return Register::FromWideOperand(ReadUnalignedUInt16(operand_start));
387 case OperandSize::kNone: {
388 UNREACHABLE();
389 }
390 }
391 return Register();
392}
393} // namespace
394
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000395
396// static
397std::ostream& Bytecodes::Decode(std::ostream& os, const uint8_t* bytecode_start,
398 int parameter_count) {
399 Vector<char> buf = Vector<char>::New(50);
400
401 Bytecode bytecode = Bytecodes::FromByte(bytecode_start[0]);
402 int bytecode_size = Bytecodes::Size(bytecode);
403
404 for (int i = 0; i < bytecode_size; i++) {
405 SNPrintF(buf, "%02x ", bytecode_start[i]);
406 os << buf.start();
407 }
408 const int kBytecodeColumnSize = 6;
409 for (int i = bytecode_size; i < kBytecodeColumnSize; i++) {
410 os << " ";
411 }
412
413 os << bytecode << " ";
414
Ben Murdoch097c5b22016-05-18 11:27:45 +0100415 // Operands for the debug break are from the original instruction.
416 if (IsDebugBreak(bytecode)) return os;
417
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000418 int number_of_operands = NumberOfOperands(bytecode);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100419 int range = 0;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000420 for (int i = 0; i < number_of_operands; i++) {
421 OperandType op_type = GetOperandType(bytecode, i);
422 const uint8_t* operand_start =
423 &bytecode_start[GetOperandOffset(bytecode, i)];
424 switch (op_type) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100425 case interpreter::OperandType::kRegCount8:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000426 os << "#" << static_cast<unsigned int>(*operand_start);
427 break;
Ben Murdoch097c5b22016-05-18 11:27:45 +0100428 case interpreter::OperandType::kRegCount16:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000429 os << '#' << ReadUnalignedUInt16(operand_start);
430 break;
431 case interpreter::OperandType::kIdx8:
432 os << "[" << static_cast<unsigned int>(*operand_start) << "]";
433 break;
434 case interpreter::OperandType::kIdx16:
435 os << "[" << ReadUnalignedUInt16(operand_start) << "]";
436 break;
437 case interpreter::OperandType::kImm8:
438 os << "#" << static_cast<int>(static_cast<int8_t>(*operand_start));
439 break;
Ben Murdoch097c5b22016-05-18 11:27:45 +0100440 case interpreter::OperandType::kMaybeReg8:
441 case interpreter::OperandType::kMaybeReg16:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000442 case interpreter::OperandType::kReg8:
Ben Murdoch097c5b22016-05-18 11:27:45 +0100443 case interpreter::OperandType::kReg16:
444 case interpreter::OperandType::kRegOut8:
445 case interpreter::OperandType::kRegOut16: {
446 Register reg = DecodeRegister(operand_start, op_type);
447 os << reg.ToString(parameter_count);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000448 break;
449 }
Ben Murdoch097c5b22016-05-18 11:27:45 +0100450 case interpreter::OperandType::kRegOutTriple8:
451 case interpreter::OperandType::kRegOutTriple16:
452 range += 1;
453 case interpreter::OperandType::kRegOutPair8:
454 case interpreter::OperandType::kRegOutPair16:
455 case interpreter::OperandType::kRegPair8:
456 case interpreter::OperandType::kRegPair16: {
457 range += 1;
458 Register first_reg = DecodeRegister(operand_start, op_type);
459 Register last_reg = Register(first_reg.index() + range);
460 os << first_reg.ToString(parameter_count) << "-"
461 << last_reg.ToString(parameter_count);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000462 break;
463 }
464 case interpreter::OperandType::kNone:
465 UNREACHABLE();
466 break;
467 }
468 if (i != number_of_operands - 1) {
469 os << ", ";
470 }
471 }
472 return os;
473}
474
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000475std::ostream& operator<<(std::ostream& os, const Bytecode& bytecode) {
476 return os << Bytecodes::ToString(bytecode);
477}
478
479
480std::ostream& operator<<(std::ostream& os, const OperandType& operand_type) {
481 return os << Bytecodes::OperandTypeToString(operand_type);
482}
483
484
485std::ostream& operator<<(std::ostream& os, const OperandSize& operand_size) {
486 return os << Bytecodes::OperandSizeToString(operand_size);
487}
488
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000489static const int kLastParamRegisterIndex =
490 -InterpreterFrameConstants::kLastParamFromRegisterPointer / kPointerSize;
491static const int kFunctionClosureRegisterIndex =
492 -InterpreterFrameConstants::kFunctionFromRegisterPointer / kPointerSize;
Ben Murdoch097c5b22016-05-18 11:27:45 +0100493static const int kCurrentContextRegisterIndex =
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000494 -InterpreterFrameConstants::kContextFromRegisterPointer / kPointerSize;
495static const int kNewTargetRegisterIndex =
496 -InterpreterFrameConstants::kNewTargetFromRegisterPointer / kPointerSize;
497
Ben Murdoch097c5b22016-05-18 11:27:45 +0100498// The register space is a signed 16-bit space. Register operands
499// occupy range above 0. Parameter indices are biased with the
500// negative value kLastParamRegisterIndex for ease of access in the
501// interpreter.
502static const int kMaxParameterIndex = kMaxInt16 + kLastParamRegisterIndex;
503static const int kMaxRegisterIndex = -kMinInt16;
504static const int kMaxReg8Index = -kMinInt8;
505static const int kMinReg8Index = -kMaxInt8;
506static const int kMaxReg16Index = -kMinInt16;
507static const int kMinReg16Index = -kMaxInt16;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000508
Ben Murdoch097c5b22016-05-18 11:27:45 +0100509bool Register::is_byte_operand() const {
510 return index_ >= kMinReg8Index && index_ <= kMaxReg8Index;
511}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000512
Ben Murdoch097c5b22016-05-18 11:27:45 +0100513bool Register::is_short_operand() const {
514 return index_ >= kMinReg16Index && index_ <= kMaxReg16Index;
515}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000516
517Register Register::FromParameterIndex(int index, int parameter_count) {
518 DCHECK_GE(index, 0);
519 DCHECK_LT(index, parameter_count);
520 DCHECK_LE(parameter_count, kMaxParameterIndex + 1);
521 int register_index = kLastParamRegisterIndex - parameter_count + index + 1;
522 DCHECK_LT(register_index, 0);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000523 return Register(register_index);
524}
525
526
527int Register::ToParameterIndex(int parameter_count) const {
528 DCHECK(is_parameter());
529 return index() - kLastParamRegisterIndex + parameter_count - 1;
530}
531
532
533Register Register::function_closure() {
534 return Register(kFunctionClosureRegisterIndex);
535}
536
537
538bool Register::is_function_closure() const {
539 return index() == kFunctionClosureRegisterIndex;
540}
541
542
Ben Murdoch097c5b22016-05-18 11:27:45 +0100543Register Register::current_context() {
544 return Register(kCurrentContextRegisterIndex);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000545}
546
547
Ben Murdoch097c5b22016-05-18 11:27:45 +0100548bool Register::is_current_context() const {
549 return index() == kCurrentContextRegisterIndex;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000550}
551
552
553Register Register::new_target() { return Register(kNewTargetRegisterIndex); }
554
555
556bool Register::is_new_target() const {
557 return index() == kNewTargetRegisterIndex;
558}
559
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000560int Register::MaxParameterIndex() { return kMaxParameterIndex; }
561
Ben Murdoch097c5b22016-05-18 11:27:45 +0100562int Register::MaxRegisterIndex() { return kMaxRegisterIndex; }
563
564int Register::MaxRegisterIndexForByteOperand() { return kMaxReg8Index; }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000565
566uint8_t Register::ToOperand() const {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100567 DCHECK(is_byte_operand());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000568 return static_cast<uint8_t>(-index_);
569}
570
571
572Register Register::FromOperand(uint8_t operand) {
573 return Register(-static_cast<int8_t>(operand));
574}
575
576
577uint16_t Register::ToWideOperand() const {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100578 DCHECK(is_short_operand());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000579 return static_cast<uint16_t>(-index_);
580}
581
582
583Register Register::FromWideOperand(uint16_t operand) {
584 return Register(-static_cast<int16_t>(operand));
585}
586
587
Ben Murdoch097c5b22016-05-18 11:27:45 +0100588uint32_t Register::ToRawOperand() const {
589 return static_cast<uint32_t>(-index_);
590}
591
592
593Register Register::FromRawOperand(uint32_t operand) {
594 return Register(-static_cast<int32_t>(operand));
595}
596
597
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000598bool Register::AreContiguous(Register reg1, Register reg2, Register reg3,
599 Register reg4, Register reg5) {
600 if (reg1.index() + 1 != reg2.index()) {
601 return false;
602 }
603 if (reg3.is_valid() && reg2.index() + 1 != reg3.index()) {
604 return false;
605 }
606 if (reg4.is_valid() && reg3.index() + 1 != reg4.index()) {
607 return false;
608 }
609 if (reg5.is_valid() && reg4.index() + 1 != reg5.index()) {
610 return false;
611 }
612 return true;
613}
614
Ben Murdoch097c5b22016-05-18 11:27:45 +0100615std::string Register::ToString(int parameter_count) {
616 if (is_current_context()) {
617 return std::string("<context>");
618 } else if (is_function_closure()) {
619 return std::string("<closure>");
620 } else if (is_new_target()) {
621 return std::string("<new.target>");
622 } else if (is_parameter()) {
623 int parameter_index = ToParameterIndex(parameter_count);
624 if (parameter_index == 0) {
625 return std::string("<this>");
626 } else {
627 std::ostringstream s;
628 s << "a" << parameter_index - 1;
629 return s.str();
630 }
631 } else {
632 std::ostringstream s;
633 s << "r" << index();
634 return s.str();
635 }
636}
637
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000638} // namespace interpreter
639} // namespace internal
640} // namespace v8