OLD | NEW |
1 // Copyright 2016 the V8 project authors. All rights reserved. | 1 // Copyright 2016 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #include "src/api.h" | 7 #include "src/api.h" |
8 #include "src/factory.h" | 8 #include "src/factory.h" |
9 #include "src/interpreter/bytecode-array-writer.h" | 9 #include "src/interpreter/bytecode-array-writer.h" |
10 #include "src/interpreter/bytecode-label.h" | 10 #include "src/interpreter/bytecode-label.h" |
(...skipping 26 matching lines...) Expand all Loading... |
37 | 37 |
38 const BytecodeSourceInfo& info = BytecodeSourceInfo()); | 38 const BytecodeSourceInfo& info = BytecodeSourceInfo()); |
39 void Write(Bytecode bytecode, uint32_t operand0, uint32_t operand1, | 39 void Write(Bytecode bytecode, uint32_t operand0, uint32_t operand1, |
40 uint32_t operand2, | 40 uint32_t operand2, |
41 const BytecodeSourceInfo& info = BytecodeSourceInfo()); | 41 const BytecodeSourceInfo& info = BytecodeSourceInfo()); |
42 void Write(Bytecode bytecode, uint32_t operand0, uint32_t operand1, | 42 void Write(Bytecode bytecode, uint32_t operand0, uint32_t operand1, |
43 uint32_t operand2, uint32_t operand3, | 43 uint32_t operand2, uint32_t operand3, |
44 const BytecodeSourceInfo& info = BytecodeSourceInfo()); | 44 const BytecodeSourceInfo& info = BytecodeSourceInfo()); |
45 | 45 |
46 void WriteJump(Bytecode bytecode, BytecodeLabel* label, | 46 void WriteJump(Bytecode bytecode, BytecodeLabel* label, |
47 | |
48 const BytecodeSourceInfo& info = BytecodeSourceInfo()); | 47 const BytecodeSourceInfo& info = BytecodeSourceInfo()); |
| 48 void WriteJumpLoop(Bytecode bytecode, BytecodeLabel* label, int depth); |
49 | 49 |
50 BytecodeArrayWriter* writer() { return &bytecode_array_writer_; } | 50 BytecodeArrayWriter* writer() { return &bytecode_array_writer_; } |
51 ZoneVector<unsigned char>* bytecodes() { return writer()->bytecodes(); } | 51 ZoneVector<unsigned char>* bytecodes() { return writer()->bytecodes(); } |
52 SourcePositionTableBuilder* source_position_table_builder() { | 52 SourcePositionTableBuilder* source_position_table_builder() { |
53 return writer()->source_position_table_builder(); | 53 return writer()->source_position_table_builder(); |
54 } | 54 } |
55 int max_register_count() { return writer()->max_register_count(); } | 55 int max_register_count() { return writer()->max_register_count(); } |
56 | 56 |
57 private: | 57 private: |
58 ConstantArrayBuilder constant_array_builder_; | 58 ConstantArrayBuilder constant_array_builder_; |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
104 void BytecodeArrayWriterUnittest::WriteJump(Bytecode bytecode, | 104 void BytecodeArrayWriterUnittest::WriteJump(Bytecode bytecode, |
105 BytecodeLabel* label, | 105 BytecodeLabel* label, |
106 const BytecodeSourceInfo& info) { | 106 const BytecodeSourceInfo& info) { |
107 BytecodeNode node(bytecode, 0); | 107 BytecodeNode node(bytecode, 0); |
108 if (info.is_valid()) { | 108 if (info.is_valid()) { |
109 node.source_info().Clone(info); | 109 node.source_info().Clone(info); |
110 } | 110 } |
111 writer()->WriteJump(&node, label); | 111 writer()->WriteJump(&node, label); |
112 } | 112 } |
113 | 113 |
| 114 void BytecodeArrayWriterUnittest::WriteJumpLoop(Bytecode bytecode, |
| 115 BytecodeLabel* label, |
| 116 int depth) { |
| 117 BytecodeNode node(bytecode, 0, depth); |
| 118 writer()->WriteJump(&node, label); |
| 119 } |
| 120 |
114 TEST_F(BytecodeArrayWriterUnittest, SimpleExample) { | 121 TEST_F(BytecodeArrayWriterUnittest, SimpleExample) { |
115 CHECK_EQ(bytecodes()->size(), 0); | 122 CHECK_EQ(bytecodes()->size(), 0); |
116 | 123 |
117 Write(Bytecode::kStackCheck, {10, false}); | 124 Write(Bytecode::kStackCheck, {10, false}); |
118 CHECK_EQ(bytecodes()->size(), 1); | 125 CHECK_EQ(bytecodes()->size(), 1); |
119 CHECK_EQ(max_register_count(), 0); | 126 CHECK_EQ(max_register_count(), 0); |
120 | 127 |
121 Write(Bytecode::kLdaSmi, 127, {55, true}); | 128 Write(Bytecode::kLdaSmi, 127, {55, true}); |
122 CHECK_EQ(bytecodes()->size(), 3); | 129 CHECK_EQ(bytecodes()->size(), 3); |
123 CHECK_EQ(max_register_count(), 0); | 130 CHECK_EQ(max_register_count(), 0); |
(...skipping 30 matching lines...) Expand all Loading... |
154 } | 161 } |
155 CHECK(source_iterator.done()); | 162 CHECK(source_iterator.done()); |
156 } | 163 } |
157 | 164 |
158 TEST_F(BytecodeArrayWriterUnittest, ComplexExample) { | 165 TEST_F(BytecodeArrayWriterUnittest, ComplexExample) { |
159 static const uint8_t expected_bytes[] = { | 166 static const uint8_t expected_bytes[] = { |
160 // clang-format off | 167 // clang-format off |
161 /* 0 30 E> */ B(StackCheck), | 168 /* 0 30 E> */ B(StackCheck), |
162 /* 1 42 S> */ B(LdaConstant), U8(0), | 169 /* 1 42 S> */ B(LdaConstant), U8(0), |
163 /* 3 42 E> */ B(Star), R8(1), | 170 /* 3 42 E> */ B(Star), R8(1), |
164 /* 5 68 S> */ B(JumpIfUndefined), U8(38), | 171 /* 5 68 S> */ B(JumpIfUndefined), U8(39), |
165 /* 7 */ B(JumpIfNull), U8(36), | 172 /* 7 */ B(JumpIfNull), U8(37), |
166 /* 9 */ B(ToObject), R8(3), | 173 /* 9 */ B(ToObject), R8(3), |
167 /* 11 */ B(ForInPrepare), R8(3), R8(4), | 174 /* 11 */ B(ForInPrepare), R8(3), R8(4), |
168 /* 14 */ B(LdaZero), | 175 /* 14 */ B(LdaZero), |
169 /* 15 */ B(Star), R8(7), | 176 /* 15 */ B(Star), R8(7), |
170 /* 17 63 S> */ B(ForInContinue), R8(7), R8(6), | 177 /* 17 63 S> */ B(ForInContinue), R8(7), R8(6), |
171 /* 20 */ B(JumpIfFalse), U8(23), | 178 /* 20 */ B(JumpIfFalse), U8(24), |
172 /* 22 */ B(ForInNext), R8(3), R8(7), R8(4), U8(1), | 179 /* 22 */ B(ForInNext), R8(3), R8(7), R8(4), U8(1), |
173 /* 27 */ B(JumpIfUndefined), U8(10), | 180 /* 27 */ B(JumpIfUndefined), U8(10), |
174 /* 29 */ B(Star), R8(0), | 181 /* 29 */ B(Star), R8(0), |
175 /* 31 54 E> */ B(StackCheck), | 182 /* 31 54 E> */ B(StackCheck), |
176 /* 32 */ B(Ldar), R8(0), | 183 /* 32 */ B(Ldar), R8(0), |
177 /* 34 */ B(Star), R8(2), | 184 /* 34 */ B(Star), R8(2), |
178 /* 36 85 S> */ B(Return), | 185 /* 36 85 S> */ B(Return), |
179 /* 37 */ B(ForInStep), R8(7), | 186 /* 37 */ B(ForInStep), R8(7), |
180 /* 39 */ B(Star), R8(7), | 187 /* 39 */ B(Star), R8(7), |
181 /* 41 */ B(Jump), U8(-24), | 188 /* 41 */ B(JumpLoop), U8(-24), U8(0), |
182 /* 43 */ B(LdaUndefined), | 189 /* 44 */ B(LdaUndefined), |
183 /* 44 85 S> */ B(Return), | 190 /* 45 85 S> */ B(Return), |
184 // clang-format on | 191 // clang-format on |
185 }; | 192 }; |
186 | 193 |
187 static const PositionTableEntry expected_positions[] = { | 194 static const PositionTableEntry expected_positions[] = { |
188 {0, 30, false}, {1, 42, true}, {3, 42, false}, {5, 68, true}, | 195 {0, 30, false}, {1, 42, true}, {3, 42, false}, {5, 68, true}, |
189 {17, 63, true}, {31, 54, false}, {36, 85, true}, {44, 85, true}}; | 196 {17, 63, true}, {31, 54, false}, {36, 85, true}, {45, 85, true}}; |
190 | 197 |
191 BytecodeLabel back_jump, jump_for_in, jump_end_1, jump_end_2, jump_end_3; | 198 BytecodeLabel back_jump, jump_for_in, jump_end_1, jump_end_2, jump_end_3; |
192 | 199 |
193 #define R(i) static_cast<uint32_t>(Register(i).ToOperand()) | 200 #define R(i) static_cast<uint32_t>(Register(i).ToOperand()) |
194 Write(Bytecode::kStackCheck, {30, false}); | 201 Write(Bytecode::kStackCheck, {30, false}); |
195 Write(Bytecode::kLdaConstant, U8(0), {42, true}); | 202 Write(Bytecode::kLdaConstant, U8(0), {42, true}); |
196 CHECK_EQ(max_register_count(), 0); | 203 CHECK_EQ(max_register_count(), 0); |
197 Write(Bytecode::kStar, R(1), {42, false}); | 204 Write(Bytecode::kStar, R(1), {42, false}); |
198 CHECK_EQ(max_register_count(), 2); | 205 CHECK_EQ(max_register_count(), 2); |
199 WriteJump(Bytecode::kJumpIfUndefined, &jump_end_1, {68, true}); | 206 WriteJump(Bytecode::kJumpIfUndefined, &jump_end_1, {68, true}); |
(...skipping 13 matching lines...) Expand all Loading... |
213 Write(Bytecode::kForInNext, R(3), R(7), R(4), U8(1)); | 220 Write(Bytecode::kForInNext, R(3), R(7), R(4), U8(1)); |
214 WriteJump(Bytecode::kJumpIfUndefined, &jump_for_in); | 221 WriteJump(Bytecode::kJumpIfUndefined, &jump_for_in); |
215 Write(Bytecode::kStar, R(0)); | 222 Write(Bytecode::kStar, R(0)); |
216 Write(Bytecode::kStackCheck, {54, false}); | 223 Write(Bytecode::kStackCheck, {54, false}); |
217 Write(Bytecode::kLdar, R(0)); | 224 Write(Bytecode::kLdar, R(0)); |
218 Write(Bytecode::kStar, R(2)); | 225 Write(Bytecode::kStar, R(2)); |
219 Write(Bytecode::kReturn, {85, true}); | 226 Write(Bytecode::kReturn, {85, true}); |
220 writer()->BindLabel(&jump_for_in); | 227 writer()->BindLabel(&jump_for_in); |
221 Write(Bytecode::kForInStep, R(7)); | 228 Write(Bytecode::kForInStep, R(7)); |
222 Write(Bytecode::kStar, R(7)); | 229 Write(Bytecode::kStar, R(7)); |
223 WriteJump(Bytecode::kJump, &back_jump); | 230 WriteJumpLoop(Bytecode::kJumpLoop, &back_jump, 0); |
224 writer()->BindLabel(&jump_end_1); | 231 writer()->BindLabel(&jump_end_1); |
225 writer()->BindLabel(&jump_end_2); | 232 writer()->BindLabel(&jump_end_2); |
226 writer()->BindLabel(&jump_end_3); | 233 writer()->BindLabel(&jump_end_3); |
227 Write(Bytecode::kLdaUndefined); | 234 Write(Bytecode::kLdaUndefined); |
228 Write(Bytecode::kReturn, {85, true}); | 235 Write(Bytecode::kReturn, {85, true}); |
229 CHECK_EQ(max_register_count(), 8); | 236 CHECK_EQ(max_register_count(), 8); |
230 #undef R | 237 #undef R |
231 | 238 |
232 CHECK_EQ(bytecodes()->size(), arraysize(expected_bytes)); | 239 CHECK_EQ(bytecodes()->size(), arraysize(expected_bytes)); |
233 for (size_t i = 0; i < arraysize(expected_bytes); ++i) { | 240 for (size_t i = 0; i < arraysize(expected_bytes); ++i) { |
(...skipping 11 matching lines...) Expand all Loading... |
245 CHECK_EQ(source_iterator.source_position(), expected.source_position); | 252 CHECK_EQ(source_iterator.source_position(), expected.source_position); |
246 CHECK_EQ(source_iterator.is_statement(), expected.is_statement); | 253 CHECK_EQ(source_iterator.is_statement(), expected.is_statement); |
247 source_iterator.Advance(); | 254 source_iterator.Advance(); |
248 } | 255 } |
249 CHECK(source_iterator.done()); | 256 CHECK(source_iterator.done()); |
250 } | 257 } |
251 | 258 |
252 } // namespace interpreter | 259 } // namespace interpreter |
253 } // namespace internal | 260 } // namespace internal |
254 } // namespace v8 | 261 } // namespace v8 |
OLD | NEW |