| OLD | NEW |
| 1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 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/interpreter/bytecode-array-builder.h" | 7 #include "src/interpreter/bytecode-array-builder.h" |
| 8 #include "src/interpreter/bytecode-array-iterator.h" | 8 #include "src/interpreter/bytecode-array-iterator.h" |
| 9 #include "test/unittests/test-utils.h" | 9 #include "test/unittests/test-utils.h" |
| 10 | 10 |
| 11 namespace v8 { | 11 namespace v8 { |
| 12 namespace internal { | 12 namespace internal { |
| 13 namespace interpreter { | 13 namespace interpreter { |
| 14 | 14 |
| 15 class BytecodeArrayBuilderTest : public TestWithIsolateAndZone { | 15 class BytecodeArrayBuilderTest : public TestWithIsolateAndZone { |
| 16 public: | 16 public: |
| 17 BytecodeArrayBuilderTest() {} | 17 BytecodeArrayBuilderTest() {} |
| 18 ~BytecodeArrayBuilderTest() override {} | 18 ~BytecodeArrayBuilderTest() override {} |
| 19 }; | 19 }; |
| 20 | 20 |
| 21 | 21 |
| 22 TEST_F(BytecodeArrayBuilderTest, AllBytecodesGenerated) { | 22 TEST_F(BytecodeArrayBuilderTest, AllBytecodesGenerated) { |
| 23 BytecodeArrayBuilder builder(isolate(), zone()); | 23 BytecodeArrayBuilder builder(isolate(), zone()); |
| 24 | 24 |
| 25 builder.set_locals_count(1); | 25 builder.set_locals_count(1); |
| 26 builder.set_context_count(1); |
| 26 builder.set_parameter_count(0); | 27 builder.set_parameter_count(0); |
| 27 CHECK_EQ(builder.locals_count(), 1); | 28 CHECK_EQ(builder.locals_count(), 1); |
| 29 CHECK_EQ(builder.context_count(), 1); |
| 30 CHECK_EQ(builder.fixed_register_count(), 2); |
| 28 | 31 |
| 29 // Emit constant loads. | 32 // Emit constant loads. |
| 30 builder.LoadLiteral(Smi::FromInt(0)) | 33 builder.LoadLiteral(Smi::FromInt(0)) |
| 31 .LoadLiteral(Smi::FromInt(8)) | 34 .LoadLiteral(Smi::FromInt(8)) |
| 32 .LoadLiteral(Smi::FromInt(10000000)) | 35 .LoadLiteral(Smi::FromInt(10000000)) |
| 33 .LoadUndefined() | 36 .LoadUndefined() |
| 34 .LoadNull() | 37 .LoadNull() |
| 35 .LoadTheHole() | 38 .LoadTheHole() |
| 36 .LoadTrue() | 39 .LoadTrue() |
| 37 .LoadFalse(); | 40 .LoadFalse(); |
| 38 | 41 |
| 39 // Emit accumulator transfers. | 42 // Emit accumulator transfers. |
| 40 Register reg(0); | 43 Register reg(0); |
| 41 builder.LoadAccumulatorWithRegister(reg).StoreAccumulatorInRegister(reg); | 44 builder.LoadAccumulatorWithRegister(reg).StoreAccumulatorInRegister(reg); |
| 42 | 45 |
| 43 // Emit global load / store operations. | 46 // Emit global load / store operations. |
| 44 builder.LoadGlobal(1); | 47 builder.LoadGlobal(1); |
| 45 builder.StoreGlobal(1, LanguageMode::SLOPPY); | 48 builder.StoreGlobal(1, LanguageMode::SLOPPY); |
| 46 | 49 |
| 47 // Emit context operations. | 50 // Emit context operations. |
| 48 builder.PushContext(reg); | 51 builder.PushContext(reg); |
| 49 builder.PopContext(reg); | 52 builder.PopContext(reg); |
| 50 builder.LoadContextSlot(reg, 1); | 53 builder.LoadContextSlot(reg, 1); |
| 54 builder.StoreContextSlot(reg, 1); |
| 51 | 55 |
| 52 // Emit load / store property operations. | 56 // Emit load / store property operations. |
| 53 builder.LoadNamedProperty(reg, 0, LanguageMode::SLOPPY) | 57 builder.LoadNamedProperty(reg, 0, LanguageMode::SLOPPY) |
| 54 .LoadKeyedProperty(reg, 0, LanguageMode::SLOPPY) | 58 .LoadKeyedProperty(reg, 0, LanguageMode::SLOPPY) |
| 55 .StoreNamedProperty(reg, reg, 0, LanguageMode::SLOPPY) | 59 .StoreNamedProperty(reg, reg, 0, LanguageMode::SLOPPY) |
| 56 .StoreKeyedProperty(reg, reg, 0, LanguageMode::SLOPPY) | 60 .StoreKeyedProperty(reg, reg, 0, LanguageMode::SLOPPY) |
| 57 .LoadNamedProperty(reg, 0, LanguageMode::STRICT) | 61 .LoadNamedProperty(reg, 0, LanguageMode::STRICT) |
| 58 .LoadKeyedProperty(reg, 0, LanguageMode::STRICT) | 62 .LoadKeyedProperty(reg, 0, LanguageMode::STRICT) |
| 59 .StoreNamedProperty(reg, reg, 0, LanguageMode::STRICT) | 63 .StoreNamedProperty(reg, reg, 0, LanguageMode::STRICT) |
| 60 .StoreKeyedProperty(reg, reg, 0, LanguageMode::STRICT); | 64 .StoreKeyedProperty(reg, reg, 0, LanguageMode::STRICT); |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 123 // Longer jumps requiring Constant operand | 127 // Longer jumps requiring Constant operand |
| 124 builder.Jump(&start) | 128 builder.Jump(&start) |
| 125 .JumpIfTrue(&start) | 129 .JumpIfTrue(&start) |
| 126 .JumpIfFalse(&start) | 130 .JumpIfFalse(&start) |
| 127 .JumpIfToBooleanTrue(&start) | 131 .JumpIfToBooleanTrue(&start) |
| 128 .JumpIfToBooleanFalse(&start); | 132 .JumpIfToBooleanFalse(&start); |
| 129 builder.Return(); | 133 builder.Return(); |
| 130 | 134 |
| 131 // Generate BytecodeArray. | 135 // Generate BytecodeArray. |
| 132 Handle<BytecodeArray> the_array = builder.ToBytecodeArray(); | 136 Handle<BytecodeArray> the_array = builder.ToBytecodeArray(); |
| 133 CHECK_EQ(the_array->frame_size(), builder.locals_count() * kPointerSize); | 137 CHECK_EQ(the_array->frame_size(), |
| 138 builder.fixed_register_count() * kPointerSize); |
| 134 | 139 |
| 135 // Build scorecard of bytecodes encountered in the BytecodeArray. | 140 // Build scorecard of bytecodes encountered in the BytecodeArray. |
| 136 std::vector<int> scorecard(Bytecodes::ToByte(Bytecode::kLast) + 1); | 141 std::vector<int> scorecard(Bytecodes::ToByte(Bytecode::kLast) + 1); |
| 137 Bytecode final_bytecode = Bytecode::kLdaZero; | 142 Bytecode final_bytecode = Bytecode::kLdaZero; |
| 138 int i = 0; | 143 int i = 0; |
| 139 while (i < the_array->length()) { | 144 while (i < the_array->length()) { |
| 140 uint8_t code = the_array->get(i); | 145 uint8_t code = the_array->get(i); |
| 141 scorecard[code] += 1; | 146 scorecard[code] += 1; |
| 142 final_bytecode = Bytecodes::FromByte(code); | 147 final_bytecode = Bytecodes::FromByte(code); |
| 143 i += Bytecodes::Size(Bytecodes::FromByte(code)); | 148 i += Bytecodes::Size(Bytecodes::FromByte(code)); |
| 144 } | 149 } |
| 145 | 150 |
| 146 // Check return occurs at the end and only once in the BytecodeArray. | 151 // Check return occurs at the end and only once in the BytecodeArray. |
| 147 CHECK_EQ(final_bytecode, Bytecode::kReturn); | 152 CHECK_EQ(final_bytecode, Bytecode::kReturn); |
| 148 CHECK_EQ(scorecard[Bytecodes::ToByte(final_bytecode)], 1); | 153 CHECK_EQ(scorecard[Bytecodes::ToByte(final_bytecode)], 1); |
| 149 | 154 |
| 150 #define CHECK_BYTECODE_PRESENT(Name, ...) \ | 155 #define CHECK_BYTECODE_PRESENT(Name, ...) \ |
| 151 /* Check Bytecode is marked in scorecard */ \ | 156 /* Check Bytecode is marked in scorecard */ \ |
| 152 CHECK_GE(scorecard[Bytecodes::ToByte(Bytecode::k##Name)], 1); | 157 CHECK_GE(scorecard[Bytecodes::ToByte(Bytecode::k##Name)], 1); |
| 153 BYTECODE_LIST(CHECK_BYTECODE_PRESENT) | 158 BYTECODE_LIST(CHECK_BYTECODE_PRESENT) |
| 154 #undef CHECK_BYTECODE_PRESENT | 159 #undef CHECK_BYTECODE_PRESENT |
| 155 } | 160 } |
| 156 | 161 |
| 157 | 162 |
| 158 TEST_F(BytecodeArrayBuilderTest, FrameSizesLookGood) { | 163 TEST_F(BytecodeArrayBuilderTest, FrameSizesLookGood) { |
| 159 for (int locals = 0; locals < 5; locals++) { | 164 for (int locals = 0; locals < 5; locals++) { |
| 160 for (int temps = 0; temps < 3; temps++) { | 165 for (int contexts = 0; contexts < 4; contexts++) { |
| 161 BytecodeArrayBuilder builder(isolate(), zone()); | 166 for (int temps = 0; temps < 3; temps++) { |
| 162 builder.set_parameter_count(0); | 167 BytecodeArrayBuilder builder(isolate(), zone()); |
| 163 builder.set_locals_count(locals); | 168 builder.set_parameter_count(0); |
| 164 builder.Return(); | 169 builder.set_locals_count(locals); |
| 170 builder.set_context_count(contexts); |
| 171 builder.Return(); |
| 165 | 172 |
| 166 TemporaryRegisterScope temporaries(&builder); | 173 TemporaryRegisterScope temporaries(&builder); |
| 167 for (int i = 0; i < temps; i++) { | 174 for (int i = 0; i < temps; i++) { |
| 168 temporaries.NewRegister(); | 175 temporaries.NewRegister(); |
| 176 } |
| 177 |
| 178 Handle<BytecodeArray> the_array = builder.ToBytecodeArray(); |
| 179 int total_registers = locals + contexts + temps; |
| 180 CHECK_EQ(the_array->frame_size(), total_registers * kPointerSize); |
| 169 } | 181 } |
| 170 | |
| 171 Handle<BytecodeArray> the_array = builder.ToBytecodeArray(); | |
| 172 int total_registers = locals + temps; | |
| 173 CHECK_EQ(the_array->frame_size(), total_registers * kPointerSize); | |
| 174 } | 182 } |
| 175 } | 183 } |
| 176 } | 184 } |
| 177 | 185 |
| 178 | 186 |
| 179 TEST_F(BytecodeArrayBuilderTest, TemporariesRecycled) { | 187 TEST_F(BytecodeArrayBuilderTest, TemporariesRecycled) { |
| 180 BytecodeArrayBuilder builder(isolate(), zone()); | 188 BytecodeArrayBuilder builder(isolate(), zone()); |
| 181 builder.set_parameter_count(0); | 189 builder.set_parameter_count(0); |
| 182 builder.set_locals_count(0); | 190 builder.set_locals_count(0); |
| 191 builder.set_context_count(0); |
| 183 builder.Return(); | 192 builder.Return(); |
| 184 | 193 |
| 185 int first; | 194 int first; |
| 186 { | 195 { |
| 187 TemporaryRegisterScope temporaries(&builder); | 196 TemporaryRegisterScope temporaries(&builder); |
| 188 first = temporaries.NewRegister().index(); | 197 first = temporaries.NewRegister().index(); |
| 189 temporaries.NewRegister(); | 198 temporaries.NewRegister(); |
| 190 temporaries.NewRegister(); | 199 temporaries.NewRegister(); |
| 191 temporaries.NewRegister(); | 200 temporaries.NewRegister(); |
| 192 } | 201 } |
| (...skipping 20 matching lines...) Expand all Loading... |
| 213 | 222 |
| 214 int actual_index = Register::FromOperand(actual_operand).index(); | 223 int actual_index = Register::FromOperand(actual_operand).index(); |
| 215 CHECK_EQ(actual_index, index); | 224 CHECK_EQ(actual_index, index); |
| 216 } | 225 } |
| 217 | 226 |
| 218 | 227 |
| 219 TEST_F(BytecodeArrayBuilderTest, Parameters) { | 228 TEST_F(BytecodeArrayBuilderTest, Parameters) { |
| 220 BytecodeArrayBuilder builder(isolate(), zone()); | 229 BytecodeArrayBuilder builder(isolate(), zone()); |
| 221 builder.set_parameter_count(10); | 230 builder.set_parameter_count(10); |
| 222 builder.set_locals_count(0); | 231 builder.set_locals_count(0); |
| 232 builder.set_context_count(0); |
| 223 | 233 |
| 224 Register param0(builder.Parameter(0)); | 234 Register param0(builder.Parameter(0)); |
| 225 Register param9(builder.Parameter(9)); | 235 Register param9(builder.Parameter(9)); |
| 226 CHECK_EQ(param9.index() - param0.index(), 9); | 236 CHECK_EQ(param9.index() - param0.index(), 9); |
| 227 } | 237 } |
| 228 | 238 |
| 229 | 239 |
| 230 TEST_F(BytecodeArrayBuilderTest, Constants) { | 240 TEST_F(BytecodeArrayBuilderTest, Constants) { |
| 231 BytecodeArrayBuilder builder(isolate(), zone()); | 241 BytecodeArrayBuilder builder(isolate(), zone()); |
| 232 builder.set_parameter_count(0); | 242 builder.set_parameter_count(0); |
| 233 builder.set_locals_count(0); | 243 builder.set_locals_count(0); |
| 244 builder.set_context_count(0); |
| 234 | 245 |
| 235 Factory* factory = isolate()->factory(); | 246 Factory* factory = isolate()->factory(); |
| 236 Handle<HeapObject> heap_num_1 = factory->NewHeapNumber(3.14); | 247 Handle<HeapObject> heap_num_1 = factory->NewHeapNumber(3.14); |
| 237 Handle<HeapObject> heap_num_2 = factory->NewHeapNumber(5.2); | 248 Handle<HeapObject> heap_num_2 = factory->NewHeapNumber(5.2); |
| 238 Handle<Object> large_smi(Smi::FromInt(0x12345678), isolate()); | 249 Handle<Object> large_smi(Smi::FromInt(0x12345678), isolate()); |
| 239 Handle<HeapObject> heap_num_2_copy(*heap_num_2); | 250 Handle<HeapObject> heap_num_2_copy(*heap_num_2); |
| 240 builder.LoadLiteral(heap_num_1) | 251 builder.LoadLiteral(heap_num_1) |
| 241 .LoadLiteral(heap_num_2) | 252 .LoadLiteral(heap_num_2) |
| 242 .LoadLiteral(large_smi) | 253 .LoadLiteral(large_smi) |
| 243 .LoadLiteral(heap_num_1) | 254 .LoadLiteral(heap_num_1) |
| 244 .LoadLiteral(heap_num_1) | 255 .LoadLiteral(heap_num_1) |
| 245 .LoadLiteral(heap_num_2_copy); | 256 .LoadLiteral(heap_num_2_copy); |
| 246 | 257 |
| 247 Handle<BytecodeArray> array = builder.ToBytecodeArray(); | 258 Handle<BytecodeArray> array = builder.ToBytecodeArray(); |
| 248 // Should only have one entry for each identical constant. | 259 // Should only have one entry for each identical constant. |
| 249 CHECK_EQ(array->constant_pool()->length(), 3); | 260 CHECK_EQ(array->constant_pool()->length(), 3); |
| 250 } | 261 } |
| 251 | 262 |
| 252 | 263 |
| 253 TEST_F(BytecodeArrayBuilderTest, ForwardJumps) { | 264 TEST_F(BytecodeArrayBuilderTest, ForwardJumps) { |
| 254 static const int kFarJumpDistance = 256; | 265 static const int kFarJumpDistance = 256; |
| 255 | 266 |
| 256 BytecodeArrayBuilder builder(isolate(), zone()); | 267 BytecodeArrayBuilder builder(isolate(), zone()); |
| 257 builder.set_parameter_count(0); | 268 builder.set_parameter_count(0); |
| 258 builder.set_locals_count(0); | 269 builder.set_locals_count(0); |
| 270 builder.set_context_count(0); |
| 259 | 271 |
| 260 BytecodeLabel far0, far1, far2; | 272 BytecodeLabel far0, far1, far2; |
| 261 BytecodeLabel near0, near1, near2; | 273 BytecodeLabel near0, near1, near2; |
| 262 | 274 |
| 263 builder.Jump(&near0) | 275 builder.Jump(&near0) |
| 264 .JumpIfTrue(&near1) | 276 .JumpIfTrue(&near1) |
| 265 .JumpIfFalse(&near2) | 277 .JumpIfFalse(&near2) |
| 266 .Bind(&near0) | 278 .Bind(&near0) |
| 267 .Bind(&near1) | 279 .Bind(&near1) |
| 268 .Bind(&near2) | 280 .Bind(&near2) |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 317 Smi::cast(*iterator.GetConstantForIndexOperand(0))->value()), | 329 Smi::cast(*iterator.GetConstantForIndexOperand(0))->value()), |
| 318 Bytecodes::ToByte(Bytecode::kReturn)); | 330 Bytecodes::ToByte(Bytecode::kReturn)); |
| 319 iterator.Advance(); | 331 iterator.Advance(); |
| 320 } | 332 } |
| 321 | 333 |
| 322 | 334 |
| 323 TEST_F(BytecodeArrayBuilderTest, BackwardJumps) { | 335 TEST_F(BytecodeArrayBuilderTest, BackwardJumps) { |
| 324 BytecodeArrayBuilder builder(isolate(), zone()); | 336 BytecodeArrayBuilder builder(isolate(), zone()); |
| 325 builder.set_parameter_count(0); | 337 builder.set_parameter_count(0); |
| 326 builder.set_locals_count(0); | 338 builder.set_locals_count(0); |
| 339 builder.set_context_count(0); |
| 327 | 340 |
| 328 BytecodeLabel label0, label1, label2; | 341 BytecodeLabel label0, label1, label2; |
| 329 builder.Bind(&label0) | 342 builder.Bind(&label0) |
| 330 .Jump(&label0) | 343 .Jump(&label0) |
| 331 .Bind(&label1) | 344 .Bind(&label1) |
| 332 .JumpIfTrue(&label1) | 345 .JumpIfTrue(&label1) |
| 333 .Bind(&label2) | 346 .Bind(&label2) |
| 334 .JumpIfFalse(&label2); | 347 .JumpIfFalse(&label2); |
| 335 for (int i = 0; i < 64; i++) { | 348 for (int i = 0; i < 64; i++) { |
| 336 builder.Jump(&label2); | 349 builder.Jump(&label2); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 368 CHECK_EQ(iterator.current_bytecode(), Bytecode::kReturn); | 381 CHECK_EQ(iterator.current_bytecode(), Bytecode::kReturn); |
| 369 iterator.Advance(); | 382 iterator.Advance(); |
| 370 CHECK(iterator.done()); | 383 CHECK(iterator.done()); |
| 371 } | 384 } |
| 372 | 385 |
| 373 | 386 |
| 374 TEST_F(BytecodeArrayBuilderTest, LabelReuse) { | 387 TEST_F(BytecodeArrayBuilderTest, LabelReuse) { |
| 375 BytecodeArrayBuilder builder(isolate(), zone()); | 388 BytecodeArrayBuilder builder(isolate(), zone()); |
| 376 builder.set_parameter_count(0); | 389 builder.set_parameter_count(0); |
| 377 builder.set_locals_count(0); | 390 builder.set_locals_count(0); |
| 391 builder.set_context_count(0); |
| 378 | 392 |
| 379 // Labels can only have 1 forward reference, but | 393 // Labels can only have 1 forward reference, but |
| 380 // can be referred to mulitple times once bound. | 394 // can be referred to mulitple times once bound. |
| 381 BytecodeLabel label; | 395 BytecodeLabel label; |
| 382 | 396 |
| 383 builder.Jump(&label).Bind(&label).Jump(&label).Jump(&label).Return(); | 397 builder.Jump(&label).Bind(&label).Jump(&label).Jump(&label).Return(); |
| 384 | 398 |
| 385 Handle<BytecodeArray> array = builder.ToBytecodeArray(); | 399 Handle<BytecodeArray> array = builder.ToBytecodeArray(); |
| 386 BytecodeArrayIterator iterator(array); | 400 BytecodeArrayIterator iterator(array); |
| 387 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJump); | 401 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJump); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 398 CHECK(iterator.done()); | 412 CHECK(iterator.done()); |
| 399 } | 413 } |
| 400 | 414 |
| 401 | 415 |
| 402 TEST_F(BytecodeArrayBuilderTest, LabelAddressReuse) { | 416 TEST_F(BytecodeArrayBuilderTest, LabelAddressReuse) { |
| 403 static const int kRepeats = 3; | 417 static const int kRepeats = 3; |
| 404 | 418 |
| 405 BytecodeArrayBuilder builder(isolate(), zone()); | 419 BytecodeArrayBuilder builder(isolate(), zone()); |
| 406 builder.set_parameter_count(0); | 420 builder.set_parameter_count(0); |
| 407 builder.set_locals_count(0); | 421 builder.set_locals_count(0); |
| 422 builder.set_context_count(0); |
| 408 | 423 |
| 409 for (int i = 0; i < kRepeats; i++) { | 424 for (int i = 0; i < kRepeats; i++) { |
| 410 BytecodeLabel label; | 425 BytecodeLabel label; |
| 411 builder.Jump(&label).Bind(&label).Jump(&label).Jump(&label); | 426 builder.Jump(&label).Bind(&label).Jump(&label).Jump(&label); |
| 412 } | 427 } |
| 413 | 428 |
| 414 builder.Return(); | 429 builder.Return(); |
| 415 | 430 |
| 416 Handle<BytecodeArray> array = builder.ToBytecodeArray(); | 431 Handle<BytecodeArray> array = builder.ToBytecodeArray(); |
| 417 BytecodeArrayIterator iterator(array); | 432 BytecodeArrayIterator iterator(array); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 429 CHECK_EQ(iterator.current_bytecode(), Bytecode::kReturn); | 444 CHECK_EQ(iterator.current_bytecode(), Bytecode::kReturn); |
| 430 iterator.Advance(); | 445 iterator.Advance(); |
| 431 CHECK(iterator.done()); | 446 CHECK(iterator.done()); |
| 432 } | 447 } |
| 433 | 448 |
| 434 | 449 |
| 435 TEST_F(BytecodeArrayBuilderTest, ToBoolean) { | 450 TEST_F(BytecodeArrayBuilderTest, ToBoolean) { |
| 436 BytecodeArrayBuilder builder(isolate(), zone()); | 451 BytecodeArrayBuilder builder(isolate(), zone()); |
| 437 builder.set_parameter_count(0); | 452 builder.set_parameter_count(0); |
| 438 builder.set_locals_count(0); | 453 builder.set_locals_count(0); |
| 454 builder.set_context_count(0); |
| 439 | 455 |
| 440 // Check ToBoolean emitted at start of block. | 456 // Check ToBoolean emitted at start of block. |
| 441 builder.EnterBlock().CastAccumulatorToBoolean(); | 457 builder.EnterBlock().CastAccumulatorToBoolean(); |
| 442 | 458 |
| 443 // Check ToBoolean emitted preceding bytecode is non-boolean. | 459 // Check ToBoolean emitted preceding bytecode is non-boolean. |
| 444 builder.LoadNull().CastAccumulatorToBoolean(); | 460 builder.LoadNull().CastAccumulatorToBoolean(); |
| 445 | 461 |
| 446 // Check ToBoolean omitted if preceding bytecode is boolean. | 462 // Check ToBoolean omitted if preceding bytecode is boolean. |
| 447 builder.LoadFalse().CastAccumulatorToBoolean(); | 463 builder.LoadFalse().CastAccumulatorToBoolean(); |
| 448 | 464 |
| (...skipping 26 matching lines...) Expand all Loading... |
| 475 | 491 |
| 476 CHECK_EQ(iterator.current_bytecode(), Bytecode::kReturn); | 492 CHECK_EQ(iterator.current_bytecode(), Bytecode::kReturn); |
| 477 iterator.Advance(); | 493 iterator.Advance(); |
| 478 CHECK(iterator.done()); | 494 CHECK(iterator.done()); |
| 479 } | 495 } |
| 480 | 496 |
| 481 | 497 |
| 482 } // namespace interpreter | 498 } // namespace interpreter |
| 483 } // namespace internal | 499 } // namespace internal |
| 484 } // namespace v8 | 500 } // namespace v8 |
| OLD | NEW |