OLD | NEW |
| (Empty) |
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 #include "src/v8.h" | |
6 | |
7 #include "src/interpreter/bytecode-array-builder.h" | |
8 #include "src/interpreter/bytecode-array-reverse-iterator.h" | |
9 #include "test/unittests/test-utils.h" | |
10 | |
11 namespace v8 { | |
12 namespace internal { | |
13 namespace interpreter { | |
14 | |
15 class BytecodeArrayReverseIteratorTest : public TestWithIsolateAndZone { | |
16 public: | |
17 BytecodeArrayReverseIteratorTest() {} | |
18 ~BytecodeArrayReverseIteratorTest() override {} | |
19 }; | |
20 | |
21 TEST_F(BytecodeArrayReverseIteratorTest, IteratesBytecodeArray) { | |
22 // Use a builder to create an array with containing multiple bytecodes | |
23 // with 0, 1 and 2 operands. | |
24 BytecodeArrayBuilder builder(isolate(), zone(), 3, 3, 0); | |
25 Factory* factory = isolate()->factory(); | |
26 Handle<HeapObject> heap_num_0 = factory->NewHeapNumber(2.718); | |
27 Handle<HeapObject> heap_num_1 = factory->NewHeapNumber(2147483647); | |
28 Smi* zero = Smi::kZero; | |
29 Smi* smi_0 = Smi::FromInt(64); | |
30 Smi* smi_1 = Smi::FromInt(-65536); | |
31 Register reg_0(0); | |
32 Register reg_1(1); | |
33 RegisterList pair(0, 2); | |
34 RegisterList triple(0, 3); | |
35 Register param = Register::FromParameterIndex(2, builder.parameter_count()); | |
36 Handle<String> name = factory->NewStringFromStaticChars("abc"); | |
37 uint32_t name_index = 2; | |
38 uint32_t feedback_slot = 97; | |
39 | |
40 builder.LoadLiteral(heap_num_0) | |
41 .StoreAccumulatorInRegister(reg_0) | |
42 .LoadLiteral(heap_num_1) | |
43 .StoreAccumulatorInRegister(reg_0) | |
44 .LoadLiteral(zero) | |
45 .StoreAccumulatorInRegister(reg_0) | |
46 .LoadLiteral(smi_0) | |
47 .StackCheck(0) | |
48 .StoreAccumulatorInRegister(reg_0) | |
49 .LoadLiteral(smi_1) | |
50 .StackCheck(1) | |
51 .StoreAccumulatorInRegister(reg_1) | |
52 .LoadAccumulatorWithRegister(reg_0) | |
53 .BinaryOperation(Token::Value::ADD, reg_0, 2) | |
54 .StoreAccumulatorInRegister(reg_1) | |
55 .LoadNamedProperty(reg_1, name, feedback_slot) | |
56 .BinaryOperation(Token::Value::ADD, reg_0, 3) | |
57 .StoreAccumulatorInRegister(param) | |
58 .CallRuntimeForPair(Runtime::kLoadLookupSlotForCall, param, pair) | |
59 .ForInPrepare(reg_0, triple) | |
60 .CallRuntime(Runtime::kLoadIC_Miss, reg_0) | |
61 .Debugger() | |
62 .LoadGlobal(name, 0x10000000, TypeofMode::NOT_INSIDE_TYPEOF) | |
63 .Return(); | |
64 | |
65 // Test iterator sees the expected output from the builder. | |
66 Handle<BytecodeArray> bytecodeArray = builder.ToBytecodeArray(isolate()); | |
67 BytecodeArrayReverseIterator iterator(bytecodeArray, zone()); | |
68 const int kPrefixByteSize = 1; | |
69 int offset = bytecodeArray->length(); | |
70 | |
71 offset -= Bytecodes::Size(Bytecode::kReturn, OperandScale::kSingle); | |
72 CHECK_EQ(iterator.current_bytecode(), Bytecode::kReturn); | |
73 CHECK_EQ(iterator.current_offset(), offset); | |
74 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kSingle); | |
75 CHECK(!iterator.done()); | |
76 iterator.Advance(); | |
77 | |
78 offset -= Bytecodes::Size(Bytecode::kLdaGlobal, OperandScale::kQuadruple) + | |
79 kPrefixByteSize; | |
80 CHECK_EQ(iterator.current_bytecode(), Bytecode::kLdaGlobal); | |
81 CHECK_EQ(iterator.current_offset(), offset); | |
82 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kQuadruple); | |
83 CHECK_EQ(iterator.current_bytecode_size(), 10); | |
84 CHECK_EQ(iterator.GetIndexOperand(1), 0x10000000u); | |
85 iterator.Advance(); | |
86 | |
87 offset -= Bytecodes::Size(Bytecode::kDebugger, OperandScale::kSingle); | |
88 CHECK_EQ(iterator.current_bytecode(), Bytecode::kDebugger); | |
89 CHECK_EQ(iterator.current_offset(), offset); | |
90 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kSingle); | |
91 CHECK(!iterator.done()); | |
92 iterator.Advance(); | |
93 | |
94 offset -= Bytecodes::Size(Bytecode::kCallRuntime, OperandScale::kSingle); | |
95 CHECK_EQ(iterator.current_bytecode(), Bytecode::kCallRuntime); | |
96 CHECK_EQ(iterator.current_offset(), offset); | |
97 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kSingle); | |
98 CHECK_EQ(iterator.GetRuntimeIdOperand(0), Runtime::kLoadIC_Miss); | |
99 CHECK_EQ(iterator.GetRegisterOperand(1).index(), reg_0.index()); | |
100 CHECK_EQ(iterator.GetRegisterCountOperand(2), 1u); | |
101 CHECK(!iterator.done()); | |
102 iterator.Advance(); | |
103 | |
104 offset -= Bytecodes::Size(Bytecode::kForInPrepare, OperandScale::kSingle); | |
105 CHECK_EQ(iterator.current_bytecode(), Bytecode::kForInPrepare); | |
106 CHECK_EQ(iterator.current_offset(), offset); | |
107 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kSingle); | |
108 CHECK_EQ(iterator.GetRegisterOperand(0).index(), reg_0.index()); | |
109 CHECK_EQ(iterator.GetRegisterOperandRange(0), 1); | |
110 CHECK_EQ(iterator.GetRegisterOperand(1).index(), reg_0.index()); | |
111 CHECK_EQ(iterator.GetRegisterOperandRange(1), 3); | |
112 CHECK(!iterator.done()); | |
113 iterator.Advance(); | |
114 | |
115 offset -= | |
116 Bytecodes::Size(Bytecode::kCallRuntimeForPair, OperandScale::kSingle); | |
117 CHECK_EQ(iterator.current_bytecode(), Bytecode::kCallRuntimeForPair); | |
118 CHECK_EQ(iterator.current_offset(), offset); | |
119 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kSingle); | |
120 CHECK_EQ(iterator.GetRuntimeIdOperand(0), Runtime::kLoadLookupSlotForCall); | |
121 CHECK_EQ(iterator.GetRegisterOperand(1).index(), param.index()); | |
122 CHECK_EQ(iterator.GetRegisterOperandRange(1), 1); | |
123 CHECK_EQ(iterator.GetRegisterCountOperand(2), 1u); | |
124 CHECK_EQ(iterator.GetRegisterOperand(3).index(), reg_0.index()); | |
125 CHECK_EQ(iterator.GetRegisterOperandRange(3), 2); | |
126 CHECK(!iterator.done()); | |
127 iterator.Advance(); | |
128 | |
129 offset -= Bytecodes::Size(Bytecode::kStar, OperandScale::kSingle); | |
130 CHECK_EQ(iterator.current_bytecode(), Bytecode::kStar); | |
131 CHECK_EQ(iterator.current_offset(), offset); | |
132 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kSingle); | |
133 CHECK_EQ(iterator.GetRegisterOperand(0).index(), param.index()); | |
134 CHECK_EQ(iterator.GetRegisterOperandRange(0), 1); | |
135 CHECK(!iterator.done()); | |
136 iterator.Advance(); | |
137 | |
138 offset -= Bytecodes::Size(Bytecode::kAdd, OperandScale::kSingle); | |
139 CHECK_EQ(iterator.current_bytecode(), Bytecode::kAdd); | |
140 CHECK_EQ(iterator.current_offset(), offset); | |
141 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kSingle); | |
142 CHECK_EQ(iterator.GetRegisterOperand(0).index(), reg_0.index()); | |
143 CHECK_EQ(iterator.GetRegisterOperandRange(0), 1); | |
144 CHECK(!iterator.done()); | |
145 iterator.Advance(); | |
146 | |
147 offset -= Bytecodes::Size(Bytecode::kLdaNamedProperty, OperandScale::kSingle); | |
148 CHECK_EQ(iterator.current_bytecode(), Bytecode::kLdaNamedProperty); | |
149 CHECK_EQ(iterator.current_offset(), offset); | |
150 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kSingle); | |
151 CHECK_EQ(iterator.GetRegisterOperand(0).index(), reg_1.index()); | |
152 CHECK_EQ(iterator.GetIndexOperand(1), name_index); | |
153 CHECK_EQ(iterator.GetIndexOperand(2), feedback_slot); | |
154 CHECK(!iterator.done()); | |
155 iterator.Advance(); | |
156 | |
157 offset -= Bytecodes::Size(Bytecode::kStar, OperandScale::kSingle); | |
158 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 iterator.Advance(); | |
165 | |
166 offset -= Bytecodes::Size(Bytecode::kAdd, OperandScale::kSingle); | |
167 CHECK_EQ(iterator.current_bytecode(), Bytecode::kAdd); | |
168 CHECK_EQ(iterator.current_offset(), offset); | |
169 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kSingle); | |
170 CHECK_EQ(iterator.GetRegisterOperand(0).index(), reg_0.index()); | |
171 CHECK_EQ(iterator.GetRegisterOperandRange(0), 1); | |
172 CHECK(!iterator.done()); | |
173 iterator.Advance(); | |
174 | |
175 offset -= Bytecodes::Size(Bytecode::kLdar, OperandScale::kSingle); | |
176 CHECK_EQ(iterator.current_bytecode(), Bytecode::kLdar); | |
177 CHECK_EQ(iterator.current_offset(), offset); | |
178 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kSingle); | |
179 CHECK_EQ(iterator.GetRegisterOperand(0).index(), reg_0.index()); | |
180 CHECK(!iterator.done()); | |
181 iterator.Advance(); | |
182 | |
183 offset -= Bytecodes::Size(Bytecode::kStar, OperandScale::kSingle); | |
184 CHECK_EQ(iterator.current_bytecode(), Bytecode::kStar); | |
185 CHECK_EQ(iterator.current_offset(), offset); | |
186 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kSingle); | |
187 CHECK_EQ(iterator.GetRegisterOperand(0).index(), reg_1.index()); | |
188 CHECK_EQ(iterator.GetRegisterOperandRange(0), 1); | |
189 CHECK(!iterator.done()); | |
190 iterator.Advance(); | |
191 | |
192 offset -= Bytecodes::Size(Bytecode::kStackCheck, OperandScale::kSingle); | |
193 CHECK_EQ(iterator.current_bytecode(), Bytecode::kStackCheck); | |
194 CHECK_EQ(iterator.current_offset(), offset); | |
195 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kSingle); | |
196 CHECK_EQ(Bytecodes::NumberOfOperands(iterator.current_bytecode()), 0); | |
197 CHECK(!iterator.done()); | |
198 iterator.Advance(); | |
199 | |
200 offset -= Bytecodes::Size(Bytecode::kLdaSmi, OperandScale::kQuadruple) + | |
201 kPrefixByteSize; | |
202 CHECK_EQ(iterator.current_bytecode(), Bytecode::kLdaSmi); | |
203 CHECK_EQ(iterator.current_offset(), offset); | |
204 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kQuadruple); | |
205 CHECK_EQ(Smi::FromInt(iterator.GetImmediateOperand(0)), smi_1); | |
206 CHECK(!iterator.done()); | |
207 iterator.Advance(); | |
208 | |
209 offset -= Bytecodes::Size(Bytecode::kStar, OperandScale::kSingle); | |
210 CHECK_EQ(iterator.current_bytecode(), Bytecode::kStar); | |
211 CHECK_EQ(iterator.current_offset(), offset); | |
212 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kSingle); | |
213 CHECK_EQ(iterator.GetRegisterOperand(0).index(), reg_0.index()); | |
214 CHECK_EQ(iterator.GetRegisterOperandRange(0), 1); | |
215 CHECK(!iterator.done()); | |
216 iterator.Advance(); | |
217 | |
218 offset -= Bytecodes::Size(Bytecode::kStackCheck, OperandScale::kSingle); | |
219 CHECK_EQ(iterator.current_bytecode(), Bytecode::kStackCheck); | |
220 CHECK_EQ(iterator.current_offset(), offset); | |
221 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kSingle); | |
222 CHECK_EQ(Bytecodes::NumberOfOperands(iterator.current_bytecode()), 0); | |
223 CHECK(!iterator.done()); | |
224 iterator.Advance(); | |
225 | |
226 offset -= Bytecodes::Size(Bytecode::kLdaSmi, OperandScale::kSingle); | |
227 CHECK_EQ(iterator.current_bytecode(), Bytecode::kLdaSmi); | |
228 CHECK_EQ(iterator.current_offset(), offset); | |
229 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kSingle); | |
230 CHECK_EQ(Smi::FromInt(iterator.GetImmediateOperand(0)), smi_0); | |
231 CHECK(!iterator.done()); | |
232 iterator.Advance(); | |
233 | |
234 offset -= Bytecodes::Size(Bytecode::kStar, OperandScale::kSingle); | |
235 CHECK_EQ(iterator.current_bytecode(), Bytecode::kStar); | |
236 CHECK_EQ(iterator.current_offset(), offset); | |
237 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kSingle); | |
238 CHECK_EQ(iterator.GetRegisterOperand(0).index(), reg_0.index()); | |
239 CHECK_EQ(iterator.GetRegisterOperandRange(0), 1); | |
240 CHECK(!iterator.done()); | |
241 iterator.Advance(); | |
242 | |
243 offset -= Bytecodes::Size(Bytecode::kLdaZero, OperandScale::kSingle); | |
244 CHECK_EQ(iterator.current_bytecode(), Bytecode::kLdaZero); | |
245 CHECK_EQ(iterator.current_offset(), offset); | |
246 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kSingle); | |
247 CHECK(!iterator.done()); | |
248 iterator.Advance(); | |
249 | |
250 offset -= Bytecodes::Size(Bytecode::kStar, OperandScale::kSingle); | |
251 CHECK_EQ(iterator.current_bytecode(), Bytecode::kStar); | |
252 CHECK_EQ(iterator.current_offset(), offset); | |
253 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kSingle); | |
254 CHECK_EQ(iterator.GetRegisterOperand(0).index(), reg_0.index()); | |
255 CHECK_EQ(iterator.GetRegisterOperandRange(0), 1); | |
256 CHECK(!iterator.done()); | |
257 iterator.Advance(); | |
258 | |
259 offset -= Bytecodes::Size(Bytecode::kLdaConstant, OperandScale::kSingle); | |
260 CHECK_EQ(iterator.current_bytecode(), Bytecode::kLdaConstant); | |
261 CHECK_EQ(iterator.current_offset(), offset); | |
262 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kSingle); | |
263 CHECK(iterator.GetConstantForIndexOperand(0).is_identical_to(heap_num_1)); | |
264 CHECK(!iterator.done()); | |
265 iterator.Advance(); | |
266 | |
267 offset -= Bytecodes::Size(Bytecode::kStar, OperandScale::kSingle); | |
268 CHECK_EQ(iterator.current_bytecode(), Bytecode::kStar); | |
269 CHECK_EQ(iterator.current_offset(), offset); | |
270 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kSingle); | |
271 CHECK_EQ(iterator.GetRegisterOperand(0).index(), reg_0.index()); | |
272 CHECK_EQ(iterator.GetRegisterOperandRange(0), 1); | |
273 CHECK(!iterator.done()); | |
274 iterator.Advance(); | |
275 | |
276 offset -= Bytecodes::Size(Bytecode::kLdaConstant, OperandScale::kSingle); | |
277 CHECK_EQ(iterator.current_bytecode(), Bytecode::kLdaConstant); | |
278 CHECK_EQ(iterator.current_offset(), offset); | |
279 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kSingle); | |
280 CHECK(iterator.GetConstantForIndexOperand(0).is_identical_to(heap_num_0)); | |
281 CHECK(!iterator.done()); | |
282 iterator.Advance(); | |
283 CHECK(iterator.done()); | |
284 } | |
285 | |
286 } // namespace interpreter | |
287 } // namespace internal | |
288 } // namespace v8 | |
OLD | NEW |