blob: 6b7374ec1b2cf3e1c7a473054e72b174df48ae2c [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 Murdoch61f157c2016-09-16 13:49:30 +010050 .BinaryOperation(Token::Value::ADD, reg_0)
Ben Murdochc5610432016-08-08 18:44:38 +010051 .StoreAccumulatorInRegister(reg_1)
Ben Murdoch097c5b22016-05-18 11:27:45 +010052 .LoadNamedProperty(reg_1, name, feedback_slot)
Ben Murdoch61f157c2016-09-16 13:49:30 +010053 .BinaryOperation(Token::Value::ADD, reg_0)
Ben Murdochda12d292016-06-02 14:46:10 +010054 .StoreAccumulatorInRegister(param)
55 .CallRuntimeForPair(Runtime::kLoadLookupSlotForCall, param, 1, reg_0)
56 .ForInPrepare(reg_0)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000057 .CallRuntime(Runtime::kLoadIC_Miss, reg_0, 1)
Ben Murdoch097c5b22016-05-18 11:27:45 +010058 .Debugger()
Ben Murdoch61f157c2016-09-16 13:49:30 +010059 .LoadGlobal(0x10000000, TypeofMode::NOT_INSIDE_TYPEOF)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000060 .Return();
61
62 // Test iterator sees the expected output from the builder.
63 BytecodeArrayIterator iterator(builder.ToBytecodeArray());
Ben Murdochda12d292016-06-02 14:46:10 +010064 const int kPrefixByteSize = 1;
65 int offset = 0;
66
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000067 CHECK_EQ(iterator.current_bytecode(), Bytecode::kLdaConstant);
Ben Murdochda12d292016-06-02 14:46:10 +010068 CHECK_EQ(iterator.current_offset(), offset);
69 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000070 CHECK(iterator.GetConstantForIndexOperand(0).is_identical_to(heap_num_0));
71 CHECK(!iterator.done());
Ben Murdochda12d292016-06-02 14:46:10 +010072 offset += Bytecodes::Size(Bytecode::kLdaConstant, OperandScale::kSingle);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000073 iterator.Advance();
74
Ben Murdochc5610432016-08-08 18:44:38 +010075 CHECK_EQ(iterator.current_bytecode(), Bytecode::kStar);
76 CHECK_EQ(iterator.current_offset(), offset);
77 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
78 CHECK_EQ(iterator.GetRegisterOperand(0).index(), reg_0.index());
79 CHECK_EQ(iterator.GetRegisterOperandRange(0), 1);
80 CHECK(!iterator.done());
81 offset += Bytecodes::Size(Bytecode::kStar, OperandScale::kSingle);
82 iterator.Advance();
83
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000084 CHECK_EQ(iterator.current_bytecode(), Bytecode::kLdaConstant);
Ben Murdochda12d292016-06-02 14:46:10 +010085 CHECK_EQ(iterator.current_offset(), offset);
86 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000087 CHECK(iterator.GetConstantForIndexOperand(0).is_identical_to(heap_num_1));
88 CHECK(!iterator.done());
Ben Murdochda12d292016-06-02 14:46:10 +010089 offset += Bytecodes::Size(Bytecode::kLdaConstant, OperandScale::kSingle);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000090 iterator.Advance();
91
Ben Murdochc5610432016-08-08 18:44:38 +010092 CHECK_EQ(iterator.current_bytecode(), Bytecode::kStar);
93 CHECK_EQ(iterator.current_offset(), offset);
94 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
95 CHECK_EQ(iterator.GetRegisterOperand(0).index(), reg_0.index());
96 CHECK_EQ(iterator.GetRegisterOperandRange(0), 1);
97 CHECK(!iterator.done());
98 offset += Bytecodes::Size(Bytecode::kStar, OperandScale::kSingle);
99 iterator.Advance();
100
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000101 CHECK_EQ(iterator.current_bytecode(), Bytecode::kLdaZero);
Ben Murdochda12d292016-06-02 14:46:10 +0100102 CHECK_EQ(iterator.current_offset(), offset);
103 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000104 CHECK(!iterator.done());
Ben Murdochda12d292016-06-02 14:46:10 +0100105 offset += Bytecodes::Size(Bytecode::kLdaZero, OperandScale::kSingle);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000106 iterator.Advance();
107
Ben Murdochc5610432016-08-08 18:44:38 +0100108 CHECK_EQ(iterator.current_bytecode(), Bytecode::kStar);
109 CHECK_EQ(iterator.current_offset(), offset);
110 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
111 CHECK_EQ(iterator.GetRegisterOperand(0).index(), reg_0.index());
112 CHECK_EQ(iterator.GetRegisterOperandRange(0), 1);
113 CHECK(!iterator.done());
114 offset += Bytecodes::Size(Bytecode::kStar, OperandScale::kSingle);
115 iterator.Advance();
116
Ben Murdochda12d292016-06-02 14:46:10 +0100117 CHECK_EQ(iterator.current_bytecode(), Bytecode::kLdaSmi);
118 CHECK_EQ(iterator.current_offset(), offset);
119 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000120 CHECK_EQ(Smi::FromInt(iterator.GetImmediateOperand(0)), smi_0);
121 CHECK(!iterator.done());
Ben Murdochda12d292016-06-02 14:46:10 +0100122 offset += Bytecodes::Size(Bytecode::kLdaSmi, OperandScale::kSingle);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000123 iterator.Advance();
124
Ben Murdochc5610432016-08-08 18:44:38 +0100125 CHECK_EQ(iterator.current_bytecode(), Bytecode::kStar);
126 CHECK_EQ(iterator.current_offset(), offset);
127 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
128 CHECK_EQ(iterator.GetRegisterOperand(0).index(), reg_0.index());
129 CHECK_EQ(iterator.GetRegisterOperandRange(0), 1);
130 CHECK(!iterator.done());
131 offset += Bytecodes::Size(Bytecode::kStar, OperandScale::kSingle);
132 iterator.Advance();
133
Ben Murdochda12d292016-06-02 14:46:10 +0100134 CHECK_EQ(iterator.current_bytecode(), Bytecode::kLdaSmi);
135 CHECK_EQ(iterator.current_offset(), offset);
136 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kQuadruple);
137 CHECK_EQ(Smi::FromInt(iterator.GetImmediateOperand(0)), smi_1);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000138 CHECK(!iterator.done());
Ben Murdochda12d292016-06-02 14:46:10 +0100139 offset += Bytecodes::Size(Bytecode::kLdaSmi, OperandScale::kQuadruple) +
140 kPrefixByteSize;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000141 iterator.Advance();
142
Ben Murdochc5610432016-08-08 18:44:38 +0100143 CHECK_EQ(iterator.current_bytecode(), Bytecode::kStar);
144 CHECK_EQ(iterator.current_offset(), offset);
145 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
146 CHECK_EQ(iterator.GetRegisterOperand(0).index(), reg_1.index());
147 CHECK_EQ(iterator.GetRegisterOperandRange(0), 1);
148 CHECK(!iterator.done());
149 offset += Bytecodes::Size(Bytecode::kStar, OperandScale::kSingle);
150 iterator.Advance();
151
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000152 CHECK_EQ(iterator.current_bytecode(), Bytecode::kLdar);
Ben Murdochda12d292016-06-02 14:46:10 +0100153 CHECK_EQ(iterator.current_offset(), offset);
154 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000155 CHECK_EQ(iterator.GetRegisterOperand(0).index(), reg_0.index());
156 CHECK(!iterator.done());
Ben Murdochda12d292016-06-02 14:46:10 +0100157 offset += Bytecodes::Size(Bytecode::kLdar, OperandScale::kSingle);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000158 iterator.Advance();
159
Ben Murdoch61f157c2016-09-16 13:49:30 +0100160 CHECK_EQ(iterator.current_bytecode(), Bytecode::kAdd);
161 CHECK_EQ(iterator.current_offset(), offset);
162 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
163 CHECK_EQ(iterator.GetRegisterOperand(0).index(), reg_0.index());
164 CHECK_EQ(iterator.GetRegisterOperandRange(0), 1);
165 CHECK(!iterator.done());
166 offset += Bytecodes::Size(Bytecode::kStar, OperandScale::kSingle);
167 iterator.Advance();
168
Ben Murdochc5610432016-08-08 18:44:38 +0100169 CHECK_EQ(iterator.current_bytecode(), Bytecode::kStar);
170 CHECK_EQ(iterator.current_offset(), offset);
171 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
172 CHECK_EQ(iterator.GetRegisterOperand(0).index(), reg_1.index());
173 CHECK_EQ(iterator.GetRegisterOperandRange(0), 1);
174 CHECK(!iterator.done());
175 offset += Bytecodes::Size(Bytecode::kStar, OperandScale::kSingle);
176 iterator.Advance();
177
Ben Murdoch61f157c2016-09-16 13:49:30 +0100178 CHECK_EQ(iterator.current_bytecode(), Bytecode::kLdaNamedProperty);
Ben Murdochda12d292016-06-02 14:46:10 +0100179 CHECK_EQ(iterator.current_offset(), offset);
180 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000181 CHECK_EQ(iterator.GetRegisterOperand(0).index(), reg_1.index());
182 CHECK_EQ(iterator.GetIndexOperand(1), name_index);
183 CHECK_EQ(iterator.GetIndexOperand(2), feedback_slot);
184 CHECK(!iterator.done());
Ben Murdoch61f157c2016-09-16 13:49:30 +0100185 offset += Bytecodes::Size(Bytecode::kLdaNamedProperty, OperandScale::kSingle);
186 iterator.Advance();
187
188 CHECK_EQ(iterator.current_bytecode(), Bytecode::kAdd);
189 CHECK_EQ(iterator.current_offset(), offset);
190 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
191 CHECK_EQ(iterator.GetRegisterOperand(0).index(), reg_0.index());
192 CHECK_EQ(iterator.GetRegisterOperandRange(0), 1);
193 CHECK(!iterator.done());
194 offset += Bytecodes::Size(Bytecode::kStar, OperandScale::kSingle);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000195 iterator.Advance();
196
197 CHECK_EQ(iterator.current_bytecode(), Bytecode::kStar);
Ben Murdochda12d292016-06-02 14:46:10 +0100198 CHECK_EQ(iterator.current_offset(), offset);
199 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
200 CHECK_EQ(iterator.GetRegisterOperand(0).index(), param.index());
201 CHECK_EQ(iterator.GetRegisterOperandRange(0), 1);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000202 CHECK(!iterator.done());
Ben Murdochda12d292016-06-02 14:46:10 +0100203 offset += Bytecodes::Size(Bytecode::kStar, OperandScale::kSingle);
204 iterator.Advance();
205
206 CHECK_EQ(iterator.current_bytecode(), Bytecode::kCallRuntimeForPair);
207 CHECK_EQ(iterator.current_offset(), offset);
208 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
209 CHECK_EQ(iterator.GetRuntimeIdOperand(0), Runtime::kLoadLookupSlotForCall);
210 CHECK_EQ(iterator.GetRegisterOperand(1).index(), param.index());
211 CHECK_EQ(iterator.GetRegisterOperandRange(1), 1);
212 CHECK_EQ(iterator.GetRegisterCountOperand(2), 1);
213 CHECK_EQ(iterator.GetRegisterOperand(3).index(), reg_0.index());
214 CHECK_EQ(iterator.GetRegisterOperandRange(3), 2);
215 CHECK(!iterator.done());
216 offset +=
217 Bytecodes::Size(Bytecode::kCallRuntimeForPair, OperandScale::kSingle);
218 iterator.Advance();
219
220 CHECK_EQ(iterator.current_bytecode(), Bytecode::kForInPrepare);
221 CHECK_EQ(iterator.current_offset(), offset);
222 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
223 CHECK_EQ(iterator.GetRegisterOperand(0).index(), reg_0.index());
224 CHECK_EQ(iterator.GetRegisterOperandRange(0), 3);
225 CHECK(!iterator.done());
226 offset += Bytecodes::Size(Bytecode::kForInPrepare, OperandScale::kSingle);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000227 iterator.Advance();
228
229 CHECK_EQ(iterator.current_bytecode(), Bytecode::kCallRuntime);
Ben Murdochda12d292016-06-02 14:46:10 +0100230 CHECK_EQ(iterator.current_offset(), offset);
231 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
Ben Murdoch61f157c2016-09-16 13:49:30 +0100232 CHECK_EQ(iterator.GetRuntimeIdOperand(0), Runtime::kLoadIC_Miss);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000233 CHECK_EQ(iterator.GetRegisterOperand(1).index(), reg_0.index());
Ben Murdoch097c5b22016-05-18 11:27:45 +0100234 CHECK_EQ(iterator.GetRegisterCountOperand(2), 1);
235 CHECK(!iterator.done());
Ben Murdochda12d292016-06-02 14:46:10 +0100236 offset += Bytecodes::Size(Bytecode::kCallRuntime, OperandScale::kSingle);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100237 iterator.Advance();
238
239 CHECK_EQ(iterator.current_bytecode(), Bytecode::kDebugger);
Ben Murdochda12d292016-06-02 14:46:10 +0100240 CHECK_EQ(iterator.current_offset(), offset);
241 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000242 CHECK(!iterator.done());
Ben Murdochda12d292016-06-02 14:46:10 +0100243 offset += Bytecodes::Size(Bytecode::kDebugger, OperandScale::kSingle);
244 iterator.Advance();
245
246 CHECK_EQ(iterator.current_bytecode(), Bytecode::kLdaGlobal);
247 CHECK_EQ(iterator.current_offset(), offset);
248 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kQuadruple);
Ben Murdoch61f157c2016-09-16 13:49:30 +0100249 CHECK_EQ(iterator.current_bytecode_size(), 6);
250 CHECK_EQ(iterator.GetIndexOperand(0), 0x10000000);
Ben Murdochda12d292016-06-02 14:46:10 +0100251 offset += Bytecodes::Size(Bytecode::kLdaGlobal, OperandScale::kQuadruple) +
252 kPrefixByteSize;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000253 iterator.Advance();
254
255 CHECK_EQ(iterator.current_bytecode(), Bytecode::kReturn);
Ben Murdochda12d292016-06-02 14:46:10 +0100256 CHECK_EQ(iterator.current_offset(), offset);
257 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000258 CHECK(!iterator.done());
259 iterator.Advance();
260 CHECK(iterator.done());
261}
262
263} // namespace interpreter
264} // namespace internal
265} // namespace v8