blob: aa9effe36c9c8282396f065e8c9653a0ba762155 [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/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 Murdochda12d292016-06-02 14:46:10 +010025 BytecodeArrayBuilder builder(isolate(), zone(), 3, 3, 0);
Ben Murdoch4a90d5f2016-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 Murdochda12d292016-06-02 14:46:10 +010034 Register param = Register::FromParameterIndex(2, builder.parameter_count());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000035 Handle<String> name = factory->NewStringFromStaticChars("abc");
Ben Murdochda12d292016-06-02 14:46:10 +010036 int name_index = 2;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000037 int feedback_slot = 97;
38
39 builder.LoadLiteral(heap_num_0)
Ben Murdochc5610432016-08-08 18:44:38 +010040 .StoreAccumulatorInRegister(reg_0)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000041 .LoadLiteral(heap_num_1)
Ben Murdochc5610432016-08-08 18:44:38 +010042 .StoreAccumulatorInRegister(reg_0)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000043 .LoadLiteral(zero)
Ben Murdochc5610432016-08-08 18:44:38 +010044 .StoreAccumulatorInRegister(reg_0)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000045 .LoadLiteral(smi_0)
Ben Murdochc5610432016-08-08 18:44:38 +010046 .StoreAccumulatorInRegister(reg_0)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000047 .LoadLiteral(smi_1)
Ben Murdochc5610432016-08-08 18:44:38 +010048 .StoreAccumulatorInRegister(reg_1)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000049 .LoadAccumulatorWithRegister(reg_0)
Ben Murdochc5610432016-08-08 18:44:38 +010050 .StoreAccumulatorInRegister(reg_1)
Ben Murdoch097c5b22016-05-18 11:27:45 +010051 .LoadNamedProperty(reg_1, name, feedback_slot)
Ben Murdochda12d292016-06-02 14:46:10 +010052 .StoreAccumulatorInRegister(param)
53 .CallRuntimeForPair(Runtime::kLoadLookupSlotForCall, param, 1, reg_0)
54 .ForInPrepare(reg_0)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000055 .CallRuntime(Runtime::kLoadIC_Miss, reg_0, 1)
Ben Murdoch097c5b22016-05-18 11:27:45 +010056 .Debugger()
Ben Murdochda12d292016-06-02 14:46:10 +010057 .LoadGlobal(name, 0x10000000, TypeofMode::NOT_INSIDE_TYPEOF)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000058 .Return();
59
60 // Test iterator sees the expected output from the builder.
61 BytecodeArrayIterator iterator(builder.ToBytecodeArray());
Ben Murdochda12d292016-06-02 14:46:10 +010062 const int kPrefixByteSize = 1;
63 int offset = 0;
64
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000065 CHECK_EQ(iterator.current_bytecode(), Bytecode::kLdaConstant);
Ben Murdochda12d292016-06-02 14:46:10 +010066 CHECK_EQ(iterator.current_offset(), offset);
67 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000068 CHECK(iterator.GetConstantForIndexOperand(0).is_identical_to(heap_num_0));
69 CHECK(!iterator.done());
Ben Murdochda12d292016-06-02 14:46:10 +010070 offset += Bytecodes::Size(Bytecode::kLdaConstant, OperandScale::kSingle);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000071 iterator.Advance();
72
Ben Murdochc5610432016-08-08 18:44:38 +010073 CHECK_EQ(iterator.current_bytecode(), Bytecode::kStar);
74 CHECK_EQ(iterator.current_offset(), offset);
75 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
76 CHECK_EQ(iterator.GetRegisterOperand(0).index(), reg_0.index());
77 CHECK_EQ(iterator.GetRegisterOperandRange(0), 1);
78 CHECK(!iterator.done());
79 offset += Bytecodes::Size(Bytecode::kStar, OperandScale::kSingle);
80 iterator.Advance();
81
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000082 CHECK_EQ(iterator.current_bytecode(), Bytecode::kLdaConstant);
Ben Murdochda12d292016-06-02 14:46:10 +010083 CHECK_EQ(iterator.current_offset(), offset);
84 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000085 CHECK(iterator.GetConstantForIndexOperand(0).is_identical_to(heap_num_1));
86 CHECK(!iterator.done());
Ben Murdochda12d292016-06-02 14:46:10 +010087 offset += Bytecodes::Size(Bytecode::kLdaConstant, OperandScale::kSingle);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000088 iterator.Advance();
89
Ben Murdochc5610432016-08-08 18:44:38 +010090 CHECK_EQ(iterator.current_bytecode(), Bytecode::kStar);
91 CHECK_EQ(iterator.current_offset(), offset);
92 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
93 CHECK_EQ(iterator.GetRegisterOperand(0).index(), reg_0.index());
94 CHECK_EQ(iterator.GetRegisterOperandRange(0), 1);
95 CHECK(!iterator.done());
96 offset += Bytecodes::Size(Bytecode::kStar, OperandScale::kSingle);
97 iterator.Advance();
98
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000099 CHECK_EQ(iterator.current_bytecode(), Bytecode::kLdaZero);
Ben Murdochda12d292016-06-02 14:46:10 +0100100 CHECK_EQ(iterator.current_offset(), offset);
101 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000102 CHECK(!iterator.done());
Ben Murdochda12d292016-06-02 14:46:10 +0100103 offset += Bytecodes::Size(Bytecode::kLdaZero, OperandScale::kSingle);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000104 iterator.Advance();
105
Ben Murdochc5610432016-08-08 18:44:38 +0100106 CHECK_EQ(iterator.current_bytecode(), Bytecode::kStar);
107 CHECK_EQ(iterator.current_offset(), offset);
108 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
109 CHECK_EQ(iterator.GetRegisterOperand(0).index(), reg_0.index());
110 CHECK_EQ(iterator.GetRegisterOperandRange(0), 1);
111 CHECK(!iterator.done());
112 offset += Bytecodes::Size(Bytecode::kStar, OperandScale::kSingle);
113 iterator.Advance();
114
Ben Murdochda12d292016-06-02 14:46:10 +0100115 CHECK_EQ(iterator.current_bytecode(), Bytecode::kLdaSmi);
116 CHECK_EQ(iterator.current_offset(), offset);
117 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000118 CHECK_EQ(Smi::FromInt(iterator.GetImmediateOperand(0)), smi_0);
119 CHECK(!iterator.done());
Ben Murdochda12d292016-06-02 14:46:10 +0100120 offset += Bytecodes::Size(Bytecode::kLdaSmi, OperandScale::kSingle);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000121 iterator.Advance();
122
Ben Murdochc5610432016-08-08 18:44:38 +0100123 CHECK_EQ(iterator.current_bytecode(), Bytecode::kStar);
124 CHECK_EQ(iterator.current_offset(), offset);
125 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
126 CHECK_EQ(iterator.GetRegisterOperand(0).index(), reg_0.index());
127 CHECK_EQ(iterator.GetRegisterOperandRange(0), 1);
128 CHECK(!iterator.done());
129 offset += Bytecodes::Size(Bytecode::kStar, OperandScale::kSingle);
130 iterator.Advance();
131
Ben Murdochda12d292016-06-02 14:46:10 +0100132 CHECK_EQ(iterator.current_bytecode(), Bytecode::kLdaSmi);
133 CHECK_EQ(iterator.current_offset(), offset);
134 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kQuadruple);
135 CHECK_EQ(Smi::FromInt(iterator.GetImmediateOperand(0)), smi_1);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000136 CHECK(!iterator.done());
Ben Murdochda12d292016-06-02 14:46:10 +0100137 offset += Bytecodes::Size(Bytecode::kLdaSmi, OperandScale::kQuadruple) +
138 kPrefixByteSize;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000139 iterator.Advance();
140
Ben Murdochc5610432016-08-08 18:44:38 +0100141 CHECK_EQ(iterator.current_bytecode(), Bytecode::kStar);
142 CHECK_EQ(iterator.current_offset(), offset);
143 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
144 CHECK_EQ(iterator.GetRegisterOperand(0).index(), reg_1.index());
145 CHECK_EQ(iterator.GetRegisterOperandRange(0), 1);
146 CHECK(!iterator.done());
147 offset += Bytecodes::Size(Bytecode::kStar, OperandScale::kSingle);
148 iterator.Advance();
149
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000150 CHECK_EQ(iterator.current_bytecode(), Bytecode::kLdar);
Ben Murdochda12d292016-06-02 14:46:10 +0100151 CHECK_EQ(iterator.current_offset(), offset);
152 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000153 CHECK_EQ(iterator.GetRegisterOperand(0).index(), reg_0.index());
154 CHECK(!iterator.done());
Ben Murdochda12d292016-06-02 14:46:10 +0100155 offset += Bytecodes::Size(Bytecode::kLdar, OperandScale::kSingle);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000156 iterator.Advance();
157
Ben Murdochc5610432016-08-08 18:44:38 +0100158 CHECK_EQ(iterator.current_bytecode(), Bytecode::kStar);
159 CHECK_EQ(iterator.current_offset(), offset);
160 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
161 CHECK_EQ(iterator.GetRegisterOperand(0).index(), reg_1.index());
162 CHECK_EQ(iterator.GetRegisterOperandRange(0), 1);
163 CHECK(!iterator.done());
164 offset += Bytecodes::Size(Bytecode::kStar, OperandScale::kSingle);
165 iterator.Advance();
166
Ben Murdoch097c5b22016-05-18 11:27:45 +0100167 CHECK_EQ(iterator.current_bytecode(), Bytecode::kLoadIC);
Ben Murdochda12d292016-06-02 14:46:10 +0100168 CHECK_EQ(iterator.current_offset(), offset);
169 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000170 CHECK_EQ(iterator.GetRegisterOperand(0).index(), reg_1.index());
171 CHECK_EQ(iterator.GetIndexOperand(1), name_index);
172 CHECK_EQ(iterator.GetIndexOperand(2), feedback_slot);
173 CHECK(!iterator.done());
Ben Murdochda12d292016-06-02 14:46:10 +0100174 offset += Bytecodes::Size(Bytecode::kLoadIC, OperandScale::kSingle);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000175 iterator.Advance();
176
177 CHECK_EQ(iterator.current_bytecode(), Bytecode::kStar);
Ben Murdochda12d292016-06-02 14:46:10 +0100178 CHECK_EQ(iterator.current_offset(), offset);
179 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
180 CHECK_EQ(iterator.GetRegisterOperand(0).index(), param.index());
181 CHECK_EQ(iterator.GetRegisterOperandRange(0), 1);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000182 CHECK(!iterator.done());
Ben Murdochda12d292016-06-02 14:46:10 +0100183 offset += Bytecodes::Size(Bytecode::kStar, OperandScale::kSingle);
184 iterator.Advance();
185
186 CHECK_EQ(iterator.current_bytecode(), Bytecode::kCallRuntimeForPair);
187 CHECK_EQ(iterator.current_offset(), offset);
188 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
189 CHECK_EQ(iterator.GetRuntimeIdOperand(0), Runtime::kLoadLookupSlotForCall);
190 CHECK_EQ(iterator.GetRegisterOperand(1).index(), param.index());
191 CHECK_EQ(iterator.GetRegisterOperandRange(1), 1);
192 CHECK_EQ(iterator.GetRegisterCountOperand(2), 1);
193 CHECK_EQ(iterator.GetRegisterOperand(3).index(), reg_0.index());
194 CHECK_EQ(iterator.GetRegisterOperandRange(3), 2);
195 CHECK(!iterator.done());
196 offset +=
197 Bytecodes::Size(Bytecode::kCallRuntimeForPair, OperandScale::kSingle);
198 iterator.Advance();
199
200 CHECK_EQ(iterator.current_bytecode(), Bytecode::kForInPrepare);
201 CHECK_EQ(iterator.current_offset(), offset);
202 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
203 CHECK_EQ(iterator.GetRegisterOperand(0).index(), reg_0.index());
204 CHECK_EQ(iterator.GetRegisterOperandRange(0), 3);
205 CHECK(!iterator.done());
206 offset += Bytecodes::Size(Bytecode::kForInPrepare, OperandScale::kSingle);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000207 iterator.Advance();
208
209 CHECK_EQ(iterator.current_bytecode(), Bytecode::kCallRuntime);
Ben Murdochda12d292016-06-02 14:46:10 +0100210 CHECK_EQ(iterator.current_offset(), offset);
211 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
212 CHECK_EQ(static_cast<Runtime::FunctionId>(iterator.GetRuntimeIdOperand(0)),
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000213 Runtime::kLoadIC_Miss);
214 CHECK_EQ(iterator.GetRegisterOperand(1).index(), reg_0.index());
Ben Murdoch097c5b22016-05-18 11:27:45 +0100215 CHECK_EQ(iterator.GetRegisterCountOperand(2), 1);
216 CHECK(!iterator.done());
Ben Murdochda12d292016-06-02 14:46:10 +0100217 offset += Bytecodes::Size(Bytecode::kCallRuntime, OperandScale::kSingle);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100218 iterator.Advance();
219
220 CHECK_EQ(iterator.current_bytecode(), Bytecode::kDebugger);
Ben Murdochda12d292016-06-02 14:46:10 +0100221 CHECK_EQ(iterator.current_offset(), offset);
222 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000223 CHECK(!iterator.done());
Ben Murdochda12d292016-06-02 14:46:10 +0100224 offset += Bytecodes::Size(Bytecode::kDebugger, OperandScale::kSingle);
225 iterator.Advance();
226
227 CHECK_EQ(iterator.current_bytecode(), Bytecode::kLdaGlobal);
228 CHECK_EQ(iterator.current_offset(), offset);
229 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kQuadruple);
230 CHECK_EQ(iterator.current_bytecode_size(), 10);
231 CHECK_EQ(iterator.GetIndexOperand(1), 0x10000000);
232 offset += Bytecodes::Size(Bytecode::kLdaGlobal, OperandScale::kQuadruple) +
233 kPrefixByteSize;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000234 iterator.Advance();
235
236 CHECK_EQ(iterator.current_bytecode(), Bytecode::kReturn);
Ben Murdochda12d292016-06-02 14:46:10 +0100237 CHECK_EQ(iterator.current_offset(), offset);
238 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000239 CHECK(!iterator.done());
240 iterator.Advance();
241 CHECK(iterator.done());
242}
243
244} // namespace interpreter
245} // namespace internal
246} // namespace v8