blob: 43c6caa8cf4720d6937ac97055af0b3955ed804f [file] [log] [blame]
Ben Murdoch014dc512016-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/v8.h"
6
7#include "src/interpreter/bytecode-array-builder.h"
8#include "src/interpreter/bytecode-array-iterator.h"
9#include "test/unittests/test-utils.h"
10
11namespace v8 {
12namespace internal {
13namespace interpreter {
14
15class BytecodeArrayIteratorTest : public TestWithIsolateAndZone {
16 public:
17 BytecodeArrayIteratorTest() {}
18 ~BytecodeArrayIteratorTest() override {}
19};
20
21
22TEST_F(BytecodeArrayIteratorTest, IteratesBytecodeArray) {
23 // Use a builder to create an array with containing multiple bytecodes
24 // with 0, 1 and 2 operands.
Ben Murdoch3b9bc312016-06-02 14:46:10 +010025 BytecodeArrayBuilder builder(isolate(), zone(), 3, 3, 0);
Ben Murdoch014dc512016-03-22 12:00:34 +000026 Factory* factory = isolate()->factory();
27 Handle<HeapObject> heap_num_0 = factory->NewHeapNumber(2.718);
28 Handle<HeapObject> heap_num_1 = factory->NewHeapNumber(2147483647);
29 Smi* zero = Smi::FromInt(0);
30 Smi* smi_0 = Smi::FromInt(64);
31 Smi* smi_1 = Smi::FromInt(-65536);
32 Register reg_0(0);
33 Register reg_1(1);
Ben Murdoch3b9bc312016-06-02 14:46:10 +010034 Register param = Register::FromParameterIndex(2, builder.parameter_count());
Ben Murdoch014dc512016-03-22 12:00:34 +000035 Handle<String> name = factory->NewStringFromStaticChars("abc");
Ben Murdoch3b9bc312016-06-02 14:46:10 +010036 int name_index = 2;
Ben Murdoch014dc512016-03-22 12:00:34 +000037 int feedback_slot = 97;
38
39 builder.LoadLiteral(heap_num_0)
40 .LoadLiteral(heap_num_1)
41 .LoadLiteral(zero)
42 .LoadLiteral(smi_0)
43 .LoadLiteral(smi_1)
44 .LoadAccumulatorWithRegister(reg_0)
Ben Murdoch109988c2016-05-18 11:27:45 +010045 .LoadNamedProperty(reg_1, name, feedback_slot)
Ben Murdoch3b9bc312016-06-02 14:46:10 +010046 .StoreAccumulatorInRegister(param)
47 .CallRuntimeForPair(Runtime::kLoadLookupSlotForCall, param, 1, reg_0)
48 .ForInPrepare(reg_0)
Ben Murdoch014dc512016-03-22 12:00:34 +000049 .CallRuntime(Runtime::kLoadIC_Miss, reg_0, 1)
Ben Murdoch109988c2016-05-18 11:27:45 +010050 .Debugger()
Ben Murdoch3b9bc312016-06-02 14:46:10 +010051 .LoadGlobal(name, 0x10000000, TypeofMode::NOT_INSIDE_TYPEOF)
Ben Murdoch014dc512016-03-22 12:00:34 +000052 .Return();
53
54 // Test iterator sees the expected output from the builder.
55 BytecodeArrayIterator iterator(builder.ToBytecodeArray());
Ben Murdoch3b9bc312016-06-02 14:46:10 +010056 const int kPrefixByteSize = 1;
57 int offset = 0;
58
Ben Murdoch014dc512016-03-22 12:00:34 +000059 CHECK_EQ(iterator.current_bytecode(), Bytecode::kLdaConstant);
Ben Murdoch3b9bc312016-06-02 14:46:10 +010060 CHECK_EQ(iterator.current_offset(), offset);
61 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
Ben Murdoch014dc512016-03-22 12:00:34 +000062 CHECK(iterator.GetConstantForIndexOperand(0).is_identical_to(heap_num_0));
63 CHECK(!iterator.done());
Ben Murdoch3b9bc312016-06-02 14:46:10 +010064 offset += Bytecodes::Size(Bytecode::kLdaConstant, OperandScale::kSingle);
Ben Murdoch014dc512016-03-22 12:00:34 +000065 iterator.Advance();
66
67 CHECK_EQ(iterator.current_bytecode(), Bytecode::kLdaConstant);
Ben Murdoch3b9bc312016-06-02 14:46:10 +010068 CHECK_EQ(iterator.current_offset(), offset);
69 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
Ben Murdoch014dc512016-03-22 12:00:34 +000070 CHECK(iterator.GetConstantForIndexOperand(0).is_identical_to(heap_num_1));
71 CHECK(!iterator.done());
Ben Murdoch3b9bc312016-06-02 14:46:10 +010072 offset += Bytecodes::Size(Bytecode::kLdaConstant, OperandScale::kSingle);
Ben Murdoch014dc512016-03-22 12:00:34 +000073 iterator.Advance();
74
75 CHECK_EQ(iterator.current_bytecode(), Bytecode::kLdaZero);
Ben Murdoch3b9bc312016-06-02 14:46:10 +010076 CHECK_EQ(iterator.current_offset(), offset);
77 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
Ben Murdoch014dc512016-03-22 12:00:34 +000078 CHECK(!iterator.done());
Ben Murdoch3b9bc312016-06-02 14:46:10 +010079 offset += Bytecodes::Size(Bytecode::kLdaZero, OperandScale::kSingle);
Ben Murdoch014dc512016-03-22 12:00:34 +000080 iterator.Advance();
81
Ben Murdoch3b9bc312016-06-02 14:46:10 +010082 CHECK_EQ(iterator.current_bytecode(), Bytecode::kLdaSmi);
83 CHECK_EQ(iterator.current_offset(), offset);
84 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
Ben Murdoch014dc512016-03-22 12:00:34 +000085 CHECK_EQ(Smi::FromInt(iterator.GetImmediateOperand(0)), smi_0);
86 CHECK(!iterator.done());
Ben Murdoch3b9bc312016-06-02 14:46:10 +010087 offset += Bytecodes::Size(Bytecode::kLdaSmi, OperandScale::kSingle);
Ben Murdoch014dc512016-03-22 12:00:34 +000088 iterator.Advance();
89
Ben Murdoch3b9bc312016-06-02 14:46:10 +010090 CHECK_EQ(iterator.current_bytecode(), Bytecode::kLdaSmi);
91 CHECK_EQ(iterator.current_offset(), offset);
92 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kQuadruple);
93 CHECK_EQ(Smi::FromInt(iterator.GetImmediateOperand(0)), smi_1);
Ben Murdoch014dc512016-03-22 12:00:34 +000094 CHECK(!iterator.done());
Ben Murdoch3b9bc312016-06-02 14:46:10 +010095 offset += Bytecodes::Size(Bytecode::kLdaSmi, OperandScale::kQuadruple) +
96 kPrefixByteSize;
Ben Murdoch014dc512016-03-22 12:00:34 +000097 iterator.Advance();
98
99 CHECK_EQ(iterator.current_bytecode(), Bytecode::kLdar);
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100100 CHECK_EQ(iterator.current_offset(), offset);
101 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
Ben Murdoch014dc512016-03-22 12:00:34 +0000102 CHECK_EQ(iterator.GetRegisterOperand(0).index(), reg_0.index());
103 CHECK(!iterator.done());
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100104 offset += Bytecodes::Size(Bytecode::kLdar, OperandScale::kSingle);
Ben Murdoch014dc512016-03-22 12:00:34 +0000105 iterator.Advance();
106
Ben Murdoch109988c2016-05-18 11:27:45 +0100107 CHECK_EQ(iterator.current_bytecode(), Bytecode::kLoadIC);
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100108 CHECK_EQ(iterator.current_offset(), offset);
109 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
Ben Murdoch014dc512016-03-22 12:00:34 +0000110 CHECK_EQ(iterator.GetRegisterOperand(0).index(), reg_1.index());
111 CHECK_EQ(iterator.GetIndexOperand(1), name_index);
112 CHECK_EQ(iterator.GetIndexOperand(2), feedback_slot);
113 CHECK(!iterator.done());
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100114 offset += Bytecodes::Size(Bytecode::kLoadIC, OperandScale::kSingle);
Ben Murdoch014dc512016-03-22 12:00:34 +0000115 iterator.Advance();
116
117 CHECK_EQ(iterator.current_bytecode(), Bytecode::kStar);
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100118 CHECK_EQ(iterator.current_offset(), offset);
119 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
120 CHECK_EQ(iterator.GetRegisterOperand(0).index(), param.index());
121 CHECK_EQ(iterator.GetRegisterOperandRange(0), 1);
Ben Murdoch014dc512016-03-22 12:00:34 +0000122 CHECK(!iterator.done());
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100123 offset += Bytecodes::Size(Bytecode::kStar, OperandScale::kSingle);
124 iterator.Advance();
125
126 CHECK_EQ(iterator.current_bytecode(), Bytecode::kCallRuntimeForPair);
127 CHECK_EQ(iterator.current_offset(), offset);
128 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
129 CHECK_EQ(iterator.GetRuntimeIdOperand(0), Runtime::kLoadLookupSlotForCall);
130 CHECK_EQ(iterator.GetRegisterOperand(1).index(), param.index());
131 CHECK_EQ(iterator.GetRegisterOperandRange(1), 1);
132 CHECK_EQ(iterator.GetRegisterCountOperand(2), 1);
133 CHECK_EQ(iterator.GetRegisterOperand(3).index(), reg_0.index());
134 CHECK_EQ(iterator.GetRegisterOperandRange(3), 2);
135 CHECK(!iterator.done());
136 offset +=
137 Bytecodes::Size(Bytecode::kCallRuntimeForPair, OperandScale::kSingle);
138 iterator.Advance();
139
140 CHECK_EQ(iterator.current_bytecode(), Bytecode::kForInPrepare);
141 CHECK_EQ(iterator.current_offset(), offset);
142 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
143 CHECK_EQ(iterator.GetRegisterOperand(0).index(), reg_0.index());
144 CHECK_EQ(iterator.GetRegisterOperandRange(0), 3);
145 CHECK(!iterator.done());
146 offset += Bytecodes::Size(Bytecode::kForInPrepare, OperandScale::kSingle);
Ben Murdoch014dc512016-03-22 12:00:34 +0000147 iterator.Advance();
148
149 CHECK_EQ(iterator.current_bytecode(), Bytecode::kCallRuntime);
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100150 CHECK_EQ(iterator.current_offset(), offset);
151 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
152 CHECK_EQ(static_cast<Runtime::FunctionId>(iterator.GetRuntimeIdOperand(0)),
Ben Murdoch014dc512016-03-22 12:00:34 +0000153 Runtime::kLoadIC_Miss);
154 CHECK_EQ(iterator.GetRegisterOperand(1).index(), reg_0.index());
Ben Murdoch109988c2016-05-18 11:27:45 +0100155 CHECK_EQ(iterator.GetRegisterCountOperand(2), 1);
156 CHECK(!iterator.done());
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100157 offset += Bytecodes::Size(Bytecode::kCallRuntime, OperandScale::kSingle);
Ben Murdoch109988c2016-05-18 11:27:45 +0100158 iterator.Advance();
159
160 CHECK_EQ(iterator.current_bytecode(), Bytecode::kDebugger);
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100161 CHECK_EQ(iterator.current_offset(), offset);
162 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
Ben Murdoch014dc512016-03-22 12:00:34 +0000163 CHECK(!iterator.done());
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100164 offset += Bytecodes::Size(Bytecode::kDebugger, OperandScale::kSingle);
165 iterator.Advance();
166
167 CHECK_EQ(iterator.current_bytecode(), Bytecode::kLdaGlobal);
168 CHECK_EQ(iterator.current_offset(), offset);
169 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kQuadruple);
170 CHECK_EQ(iterator.current_bytecode_size(), 10);
171 CHECK_EQ(iterator.GetIndexOperand(1), 0x10000000);
172 offset += Bytecodes::Size(Bytecode::kLdaGlobal, OperandScale::kQuadruple) +
173 kPrefixByteSize;
Ben Murdoch014dc512016-03-22 12:00:34 +0000174 iterator.Advance();
175
176 CHECK_EQ(iterator.current_bytecode(), Bytecode::kReturn);
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100177 CHECK_EQ(iterator.current_offset(), offset);
178 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
Ben Murdoch014dc512016-03-22 12:00:34 +0000179 CHECK(!iterator.done());
180 iterator.Advance();
181 CHECK(iterator.done());
182}
183
184} // namespace interpreter
185} // namespace internal
186} // namespace v8