| OLD | NEW |
| 1 // Copyright 2015 the V8 project authors. All rights reserved. | 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 | 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/interpreter/interpreter.h" | 5 #include "src/interpreter/interpreter.h" |
| 6 | 6 |
| 7 #include <fstream> | 7 #include <fstream> |
| 8 | 8 |
| 9 #include "src/ast/prettyprinter.h" | 9 #include "src/ast/prettyprinter.h" |
| 10 #include "src/code-factory.h" | 10 #include "src/code-factory.h" |
| (...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 286 __ Dispatch(); | 286 __ Dispatch(); |
| 287 } | 287 } |
| 288 | 288 |
| 289 void Interpreter::DoLoadConstant(InterpreterAssembler* assembler) { | 289 void Interpreter::DoLoadConstant(InterpreterAssembler* assembler) { |
| 290 Node* index = __ BytecodeOperandIdx(0); | 290 Node* index = __ BytecodeOperandIdx(0); |
| 291 Node* constant = __ LoadConstantPoolEntry(index); | 291 Node* constant = __ LoadConstantPoolEntry(index); |
| 292 __ SetAccumulator(constant); | 292 __ SetAccumulator(constant); |
| 293 __ Dispatch(); | 293 __ Dispatch(); |
| 294 } | 294 } |
| 295 | 295 |
| 296 | |
| 297 // LdaConstant <idx> | 296 // LdaConstant <idx> |
| 298 // | 297 // |
| 299 // Load constant literal at |idx| in the constant pool into the accumulator. | 298 // Load constant literal at |idx| in the constant pool into the accumulator. |
| 300 void Interpreter::DoLdaConstant(InterpreterAssembler* assembler) { | 299 void Interpreter::DoLdaConstant(InterpreterAssembler* assembler) { |
| 301 DoLoadConstant(assembler); | 300 DoLoadConstant(assembler); |
| 302 } | 301 } |
| 303 | 302 |
| 304 // LdaUndefined | 303 // LdaUndefined |
| 305 // | 304 // |
| 306 // Load Undefined into the accumulator. | 305 // Load Undefined into the accumulator. |
| 307 void Interpreter::DoLdaUndefined(InterpreterAssembler* assembler) { | 306 void Interpreter::DoLdaUndefined(InterpreterAssembler* assembler) { |
| 308 Node* undefined_value = | 307 Node* undefined_value = |
| 309 __ HeapConstant(isolate_->factory()->undefined_value()); | 308 __ HeapConstant(isolate_->factory()->undefined_value()); |
| 310 __ SetAccumulator(undefined_value); | 309 __ SetAccumulator(undefined_value); |
| 311 __ Dispatch(); | 310 __ Dispatch(); |
| 312 } | 311 } |
| 313 | 312 |
| 314 | |
| 315 // LdaNull | 313 // LdaNull |
| 316 // | 314 // |
| 317 // Load Null into the accumulator. | 315 // Load Null into the accumulator. |
| 318 void Interpreter::DoLdaNull(InterpreterAssembler* assembler) { | 316 void Interpreter::DoLdaNull(InterpreterAssembler* assembler) { |
| 319 Node* null_value = __ HeapConstant(isolate_->factory()->null_value()); | 317 Node* null_value = __ HeapConstant(isolate_->factory()->null_value()); |
| 320 __ SetAccumulator(null_value); | 318 __ SetAccumulator(null_value); |
| 321 __ Dispatch(); | 319 __ Dispatch(); |
| 322 } | 320 } |
| 323 | 321 |
| 324 | |
| 325 // LdaTheHole | 322 // LdaTheHole |
| 326 // | 323 // |
| 327 // Load TheHole into the accumulator. | 324 // Load TheHole into the accumulator. |
| 328 void Interpreter::DoLdaTheHole(InterpreterAssembler* assembler) { | 325 void Interpreter::DoLdaTheHole(InterpreterAssembler* assembler) { |
| 329 Node* the_hole_value = __ HeapConstant(isolate_->factory()->the_hole_value()); | 326 Node* the_hole_value = __ HeapConstant(isolate_->factory()->the_hole_value()); |
| 330 __ SetAccumulator(the_hole_value); | 327 __ SetAccumulator(the_hole_value); |
| 331 __ Dispatch(); | 328 __ Dispatch(); |
| 332 } | 329 } |
| 333 | 330 |
| 334 | |
| 335 // LdaTrue | 331 // LdaTrue |
| 336 // | 332 // |
| 337 // Load True into the accumulator. | 333 // Load True into the accumulator. |
| 338 void Interpreter::DoLdaTrue(InterpreterAssembler* assembler) { | 334 void Interpreter::DoLdaTrue(InterpreterAssembler* assembler) { |
| 339 Node* true_value = __ HeapConstant(isolate_->factory()->true_value()); | 335 Node* true_value = __ HeapConstant(isolate_->factory()->true_value()); |
| 340 __ SetAccumulator(true_value); | 336 __ SetAccumulator(true_value); |
| 341 __ Dispatch(); | 337 __ Dispatch(); |
| 342 } | 338 } |
| 343 | 339 |
| 344 | |
| 345 // LdaFalse | 340 // LdaFalse |
| 346 // | 341 // |
| 347 // Load False into the accumulator. | 342 // Load False into the accumulator. |
| 348 void Interpreter::DoLdaFalse(InterpreterAssembler* assembler) { | 343 void Interpreter::DoLdaFalse(InterpreterAssembler* assembler) { |
| 349 Node* false_value = __ HeapConstant(isolate_->factory()->false_value()); | 344 Node* false_value = __ HeapConstant(isolate_->factory()->false_value()); |
| 350 __ SetAccumulator(false_value); | 345 __ SetAccumulator(false_value); |
| 351 __ Dispatch(); | 346 __ Dispatch(); |
| 352 } | 347 } |
| 353 | 348 |
| 354 | |
| 355 // Ldar <src> | 349 // Ldar <src> |
| 356 // | 350 // |
| 357 // Load accumulator with value from register <src>. | 351 // Load accumulator with value from register <src>. |
| 358 void Interpreter::DoLdar(InterpreterAssembler* assembler) { | 352 void Interpreter::DoLdar(InterpreterAssembler* assembler) { |
| 359 Node* reg_index = __ BytecodeOperandReg(0); | 353 Node* reg_index = __ BytecodeOperandReg(0); |
| 360 Node* value = __ LoadRegister(reg_index); | 354 Node* value = __ LoadRegister(reg_index); |
| 361 __ SetAccumulator(value); | 355 __ SetAccumulator(value); |
| 362 __ Dispatch(); | 356 __ Dispatch(); |
| 363 } | 357 } |
| 364 | 358 |
| 365 | |
| 366 // Star <dst> | 359 // Star <dst> |
| 367 // | 360 // |
| 368 // Store accumulator to register <dst>. | 361 // Store accumulator to register <dst>. |
| 369 void Interpreter::DoStar(InterpreterAssembler* assembler) { | 362 void Interpreter::DoStar(InterpreterAssembler* assembler) { |
| 370 Node* reg_index = __ BytecodeOperandReg(0); | 363 Node* reg_index = __ BytecodeOperandReg(0); |
| 371 Node* accumulator = __ GetAccumulator(); | 364 Node* accumulator = __ GetAccumulator(); |
| 372 __ StoreRegister(accumulator, reg_index); | 365 __ StoreRegister(accumulator, reg_index); |
| 373 __ Dispatch(); | 366 __ Dispatch(); |
| 374 } | 367 } |
| 375 | 368 |
| 376 | |
| 377 // Mov <src> <dst> | 369 // Mov <src> <dst> |
| 378 // | 370 // |
| 379 // Stores the value of register <src> to register <dst>. | 371 // Stores the value of register <src> to register <dst>. |
| 380 void Interpreter::DoMov(InterpreterAssembler* assembler) { | 372 void Interpreter::DoMov(InterpreterAssembler* assembler) { |
| 381 Node* src_index = __ BytecodeOperandReg(0); | 373 Node* src_index = __ BytecodeOperandReg(0); |
| 382 Node* src_value = __ LoadRegister(src_index); | 374 Node* src_value = __ LoadRegister(src_index); |
| 383 Node* dst_index = __ BytecodeOperandReg(1); | 375 Node* dst_index = __ BytecodeOperandReg(1); |
| 384 __ StoreRegister(src_value, dst_index); | 376 __ StoreRegister(src_value, dst_index); |
| 385 __ Dispatch(); | 377 __ Dispatch(); |
| 386 } | 378 } |
| 387 | 379 |
| 388 | |
| 389 void Interpreter::DoLoadGlobal(Callable ic, InterpreterAssembler* assembler) { | 380 void Interpreter::DoLoadGlobal(Callable ic, InterpreterAssembler* assembler) { |
| 390 // Get the global object. | 381 // Get the global object. |
| 391 Node* context = __ GetContext(); | 382 Node* context = __ GetContext(); |
| 392 Node* native_context = | 383 Node* native_context = |
| 393 __ LoadContextSlot(context, Context::NATIVE_CONTEXT_INDEX); | 384 __ LoadContextSlot(context, Context::NATIVE_CONTEXT_INDEX); |
| 394 Node* global = __ LoadContextSlot(native_context, Context::EXTENSION_INDEX); | 385 Node* global = __ LoadContextSlot(native_context, Context::EXTENSION_INDEX); |
| 395 | 386 |
| 396 // Load the global via the LoadIC. | 387 // Load the global via the LoadIC. |
| 397 Node* code_target = __ HeapConstant(ic.code()); | 388 Node* code_target = __ HeapConstant(ic.code()); |
| 398 Node* constant_index = __ BytecodeOperandIdx(0); | 389 Node* constant_index = __ BytecodeOperandIdx(0); |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 439 Node* name = __ LoadConstantPoolEntry(constant_index); | 430 Node* name = __ LoadConstantPoolEntry(constant_index); |
| 440 Node* value = __ GetAccumulator(); | 431 Node* value = __ GetAccumulator(); |
| 441 Node* raw_slot = __ BytecodeOperandIdx(1); | 432 Node* raw_slot = __ BytecodeOperandIdx(1); |
| 442 Node* smi_slot = __ SmiTag(raw_slot); | 433 Node* smi_slot = __ SmiTag(raw_slot); |
| 443 Node* type_feedback_vector = __ LoadTypeFeedbackVector(); | 434 Node* type_feedback_vector = __ LoadTypeFeedbackVector(); |
| 444 __ CallStub(ic.descriptor(), code_target, context, global, name, value, | 435 __ CallStub(ic.descriptor(), code_target, context, global, name, value, |
| 445 smi_slot, type_feedback_vector); | 436 smi_slot, type_feedback_vector); |
| 446 __ Dispatch(); | 437 __ Dispatch(); |
| 447 } | 438 } |
| 448 | 439 |
| 449 | |
| 450 // StaGlobalSloppy <name_index> <slot> | 440 // StaGlobalSloppy <name_index> <slot> |
| 451 // | 441 // |
| 452 // Store the value in the accumulator into the global with name in constant pool | 442 // Store the value in the accumulator into the global with name in constant pool |
| 453 // entry <name_index> using FeedBackVector slot <slot> in sloppy mode. | 443 // entry <name_index> using FeedBackVector slot <slot> in sloppy mode. |
| 454 void Interpreter::DoStaGlobalSloppy(InterpreterAssembler* assembler) { | 444 void Interpreter::DoStaGlobalSloppy(InterpreterAssembler* assembler) { |
| 455 Callable ic = | 445 Callable ic = |
| 456 CodeFactory::StoreICInOptimizedCode(isolate_, SLOPPY, UNINITIALIZED); | 446 CodeFactory::StoreICInOptimizedCode(isolate_, SLOPPY, UNINITIALIZED); |
| 457 DoStoreGlobal(ic, assembler); | 447 DoStoreGlobal(ic, assembler); |
| 458 } | 448 } |
| 459 | 449 |
| 460 | |
| 461 // StaGlobalStrict <name_index> <slot> | 450 // StaGlobalStrict <name_index> <slot> |
| 462 // | 451 // |
| 463 // Store the value in the accumulator into the global with name in constant pool | 452 // Store the value in the accumulator into the global with name in constant pool |
| 464 // entry <name_index> using FeedBackVector slot <slot> in strict mode. | 453 // entry <name_index> using FeedBackVector slot <slot> in strict mode. |
| 465 void Interpreter::DoStaGlobalStrict(InterpreterAssembler* assembler) { | 454 void Interpreter::DoStaGlobalStrict(InterpreterAssembler* assembler) { |
| 466 Callable ic = | 455 Callable ic = |
| 467 CodeFactory::StoreICInOptimizedCode(isolate_, STRICT, UNINITIALIZED); | 456 CodeFactory::StoreICInOptimizedCode(isolate_, STRICT, UNINITIALIZED); |
| 468 DoStoreGlobal(ic, assembler); | 457 DoStoreGlobal(ic, assembler); |
| 469 } | 458 } |
| 470 | 459 |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 533 } | 522 } |
| 534 | 523 |
| 535 // StaLookupSlotSloppy <name_index> | 524 // StaLookupSlotSloppy <name_index> |
| 536 // | 525 // |
| 537 // Store the object in accumulator to the object with the name in constant | 526 // Store the object in accumulator to the object with the name in constant |
| 538 // pool entry |name_index| in sloppy mode. | 527 // pool entry |name_index| in sloppy mode. |
| 539 void Interpreter::DoStaLookupSlotSloppy(InterpreterAssembler* assembler) { | 528 void Interpreter::DoStaLookupSlotSloppy(InterpreterAssembler* assembler) { |
| 540 DoStoreLookupSlot(LanguageMode::SLOPPY, assembler); | 529 DoStoreLookupSlot(LanguageMode::SLOPPY, assembler); |
| 541 } | 530 } |
| 542 | 531 |
| 543 | |
| 544 // StaLookupSlotStrict <name_index> | 532 // StaLookupSlotStrict <name_index> |
| 545 // | 533 // |
| 546 // Store the object in accumulator to the object with the name in constant | 534 // Store the object in accumulator to the object with the name in constant |
| 547 // pool entry |name_index| in strict mode. | 535 // pool entry |name_index| in strict mode. |
| 548 void Interpreter::DoStaLookupSlotStrict(InterpreterAssembler* assembler) { | 536 void Interpreter::DoStaLookupSlotStrict(InterpreterAssembler* assembler) { |
| 549 DoStoreLookupSlot(LanguageMode::STRICT, assembler); | 537 DoStoreLookupSlot(LanguageMode::STRICT, assembler); |
| 550 } | 538 } |
| 551 | 539 |
| 552 void Interpreter::DoLoadIC(Callable ic, InterpreterAssembler* assembler) { | 540 void Interpreter::DoLoadIC(Callable ic, InterpreterAssembler* assembler) { |
| 553 Node* code_target = __ HeapConstant(ic.code()); | 541 Node* code_target = __ HeapConstant(ic.code()); |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 609 Node* value = __ GetAccumulator(); | 597 Node* value = __ GetAccumulator(); |
| 610 Node* raw_slot = __ BytecodeOperandIdx(2); | 598 Node* raw_slot = __ BytecodeOperandIdx(2); |
| 611 Node* smi_slot = __ SmiTag(raw_slot); | 599 Node* smi_slot = __ SmiTag(raw_slot); |
| 612 Node* type_feedback_vector = __ LoadTypeFeedbackVector(); | 600 Node* type_feedback_vector = __ LoadTypeFeedbackVector(); |
| 613 Node* context = __ GetContext(); | 601 Node* context = __ GetContext(); |
| 614 __ CallStub(ic.descriptor(), code_target, context, object, name, value, | 602 __ CallStub(ic.descriptor(), code_target, context, object, name, value, |
| 615 smi_slot, type_feedback_vector); | 603 smi_slot, type_feedback_vector); |
| 616 __ Dispatch(); | 604 __ Dispatch(); |
| 617 } | 605 } |
| 618 | 606 |
| 619 | |
| 620 // StoreICSloppy <object> <name_index> <slot> | 607 // StoreICSloppy <object> <name_index> <slot> |
| 621 // | 608 // |
| 622 // Calls the sloppy mode StoreIC at FeedBackVector slot <slot> for <object> and | 609 // Calls the sloppy mode StoreIC at FeedBackVector slot <slot> for <object> and |
| 623 // the name in constant pool entry <name_index> with the value in the | 610 // the name in constant pool entry <name_index> with the value in the |
| 624 // accumulator. | 611 // accumulator. |
| 625 void Interpreter::DoStoreICSloppy(InterpreterAssembler* assembler) { | 612 void Interpreter::DoStoreICSloppy(InterpreterAssembler* assembler) { |
| 626 Callable ic = | 613 Callable ic = |
| 627 CodeFactory::StoreICInOptimizedCode(isolate_, SLOPPY, UNINITIALIZED); | 614 CodeFactory::StoreICInOptimizedCode(isolate_, SLOPPY, UNINITIALIZED); |
| 628 DoStoreIC(ic, assembler); | 615 DoStoreIC(ic, assembler); |
| 629 } | 616 } |
| 630 | 617 |
| 631 | |
| 632 // StoreICStrict <object> <name_index> <slot> | 618 // StoreICStrict <object> <name_index> <slot> |
| 633 // | 619 // |
| 634 // Calls the strict mode StoreIC at FeedBackVector slot <slot> for <object> and | 620 // Calls the strict mode StoreIC at FeedBackVector slot <slot> for <object> and |
| 635 // the name in constant pool entry <name_index> with the value in the | 621 // the name in constant pool entry <name_index> with the value in the |
| 636 // accumulator. | 622 // accumulator. |
| 637 void Interpreter::DoStoreICStrict(InterpreterAssembler* assembler) { | 623 void Interpreter::DoStoreICStrict(InterpreterAssembler* assembler) { |
| 638 Callable ic = | 624 Callable ic = |
| 639 CodeFactory::StoreICInOptimizedCode(isolate_, STRICT, UNINITIALIZED); | 625 CodeFactory::StoreICInOptimizedCode(isolate_, STRICT, UNINITIALIZED); |
| 640 DoStoreIC(ic, assembler); | 626 DoStoreIC(ic, assembler); |
| 641 } | 627 } |
| 642 | 628 |
| 643 void Interpreter::DoKeyedStoreIC(Callable ic, InterpreterAssembler* assembler) { | 629 void Interpreter::DoKeyedStoreIC(Callable ic, InterpreterAssembler* assembler) { |
| 644 Node* code_target = __ HeapConstant(ic.code()); | 630 Node* code_target = __ HeapConstant(ic.code()); |
| 645 Node* object_reg_index = __ BytecodeOperandReg(0); | 631 Node* object_reg_index = __ BytecodeOperandReg(0); |
| 646 Node* object = __ LoadRegister(object_reg_index); | 632 Node* object = __ LoadRegister(object_reg_index); |
| 647 Node* name_reg_index = __ BytecodeOperandReg(1); | 633 Node* name_reg_index = __ BytecodeOperandReg(1); |
| 648 Node* name = __ LoadRegister(name_reg_index); | 634 Node* name = __ LoadRegister(name_reg_index); |
| 649 Node* value = __ GetAccumulator(); | 635 Node* value = __ GetAccumulator(); |
| 650 Node* raw_slot = __ BytecodeOperandIdx(2); | 636 Node* raw_slot = __ BytecodeOperandIdx(2); |
| 651 Node* smi_slot = __ SmiTag(raw_slot); | 637 Node* smi_slot = __ SmiTag(raw_slot); |
| 652 Node* type_feedback_vector = __ LoadTypeFeedbackVector(); | 638 Node* type_feedback_vector = __ LoadTypeFeedbackVector(); |
| 653 Node* context = __ GetContext(); | 639 Node* context = __ GetContext(); |
| 654 __ CallStub(ic.descriptor(), code_target, context, object, name, value, | 640 __ CallStub(ic.descriptor(), code_target, context, object, name, value, |
| 655 smi_slot, type_feedback_vector); | 641 smi_slot, type_feedback_vector); |
| 656 __ Dispatch(); | 642 __ Dispatch(); |
| 657 } | 643 } |
| 658 | 644 |
| 659 | |
| 660 // KeyedStoreICSloppy <object> <key> <slot> | 645 // KeyedStoreICSloppy <object> <key> <slot> |
| 661 // | 646 // |
| 662 // Calls the sloppy mode KeyStoreIC at FeedBackVector slot <slot> for <object> | 647 // Calls the sloppy mode KeyStoreIC at FeedBackVector slot <slot> for <object> |
| 663 // and the key <key> with the value in the accumulator. | 648 // and the key <key> with the value in the accumulator. |
| 664 void Interpreter::DoKeyedStoreICSloppy(InterpreterAssembler* assembler) { | 649 void Interpreter::DoKeyedStoreICSloppy(InterpreterAssembler* assembler) { |
| 665 Callable ic = | 650 Callable ic = |
| 666 CodeFactory::KeyedStoreICInOptimizedCode(isolate_, SLOPPY, UNINITIALIZED); | 651 CodeFactory::KeyedStoreICInOptimizedCode(isolate_, SLOPPY, UNINITIALIZED); |
| 667 DoKeyedStoreIC(ic, assembler); | 652 DoKeyedStoreIC(ic, assembler); |
| 668 } | 653 } |
| 669 | 654 |
| 670 | |
| 671 // KeyedStoreICStore <object> <key> <slot> | 655 // KeyedStoreICStore <object> <key> <slot> |
| 672 // | 656 // |
| 673 // Calls the strict mode KeyStoreIC at FeedBackVector slot <slot> for <object> | 657 // Calls the strict mode KeyStoreIC at FeedBackVector slot <slot> for <object> |
| 674 // and the key <key> with the value in the accumulator. | 658 // and the key <key> with the value in the accumulator. |
| 675 void Interpreter::DoKeyedStoreICStrict(InterpreterAssembler* assembler) { | 659 void Interpreter::DoKeyedStoreICStrict(InterpreterAssembler* assembler) { |
| 676 Callable ic = | 660 Callable ic = |
| 677 CodeFactory::KeyedStoreICInOptimizedCode(isolate_, STRICT, UNINITIALIZED); | 661 CodeFactory::KeyedStoreICInOptimizedCode(isolate_, STRICT, UNINITIALIZED); |
| 678 DoKeyedStoreIC(ic, assembler); | 662 DoKeyedStoreIC(ic, assembler); |
| 679 } | 663 } |
| 680 | 664 |
| 681 // PushContext <context> | 665 // PushContext <context> |
| 682 // | 666 // |
| 683 // Saves the current context in <context>, and pushes the accumulator as the | 667 // Saves the current context in <context>, and pushes the accumulator as the |
| 684 // new current context. | 668 // new current context. |
| 685 void Interpreter::DoPushContext(InterpreterAssembler* assembler) { | 669 void Interpreter::DoPushContext(InterpreterAssembler* assembler) { |
| 686 Node* reg_index = __ BytecodeOperandReg(0); | 670 Node* reg_index = __ BytecodeOperandReg(0); |
| 687 Node* new_context = __ GetAccumulator(); | 671 Node* new_context = __ GetAccumulator(); |
| 688 Node* old_context = __ GetContext(); | 672 Node* old_context = __ GetContext(); |
| 689 __ StoreRegister(old_context, reg_index); | 673 __ StoreRegister(old_context, reg_index); |
| 690 __ SetContext(new_context); | 674 __ SetContext(new_context); |
| 691 __ Dispatch(); | 675 __ Dispatch(); |
| 692 } | 676 } |
| 693 | 677 |
| 694 | |
| 695 // PopContext <context> | 678 // PopContext <context> |
| 696 // | 679 // |
| 697 // Pops the current context and sets <context> as the new context. | 680 // Pops the current context and sets <context> as the new context. |
| 698 void Interpreter::DoPopContext(InterpreterAssembler* assembler) { | 681 void Interpreter::DoPopContext(InterpreterAssembler* assembler) { |
| 699 Node* reg_index = __ BytecodeOperandReg(0); | 682 Node* reg_index = __ BytecodeOperandReg(0); |
| 700 Node* context = __ LoadRegister(reg_index); | 683 Node* context = __ LoadRegister(reg_index); |
| 701 __ SetContext(context); | 684 __ SetContext(context); |
| 702 __ Dispatch(); | 685 __ Dispatch(); |
| 703 } | 686 } |
| 704 | 687 |
| 705 void Interpreter::DoBinaryOp(Callable callable, | 688 void Interpreter::DoBinaryOp(Callable callable, |
| 706 InterpreterAssembler* assembler) { | 689 InterpreterAssembler* assembler) { |
| 707 // TODO(bmeurer): Collect definition side type feedback for various | 690 // TODO(bmeurer): Collect definition side type feedback for various |
| 708 // binary operations. | 691 // binary operations. |
| 709 Node* target = __ HeapConstant(callable.code()); | 692 Node* target = __ HeapConstant(callable.code()); |
| 710 Node* reg_index = __ BytecodeOperandReg(0); | 693 Node* reg_index = __ BytecodeOperandReg(0); |
| 711 Node* lhs = __ LoadRegister(reg_index); | 694 Node* lhs = __ LoadRegister(reg_index); |
| 712 Node* rhs = __ GetAccumulator(); | 695 Node* rhs = __ GetAccumulator(); |
| 713 Node* context = __ GetContext(); | 696 Node* context = __ GetContext(); |
| 714 Node* result = __ CallStub(callable.descriptor(), target, context, lhs, rhs); | 697 Node* result = __ CallStub(callable.descriptor(), target, context, lhs, rhs); |
| 715 __ SetAccumulator(result); | 698 __ SetAccumulator(result); |
| 716 __ Dispatch(); | 699 __ Dispatch(); |
| 717 } | 700 } |
| 718 | 701 |
| 719 void Interpreter::DoBinaryOp(Runtime::FunctionId function_id, | |
| 720 InterpreterAssembler* assembler) { | |
| 721 // TODO(rmcilroy): Call ICs which back-patch bytecode with type specialized | |
| 722 // operations, instead of calling builtins directly. | |
| 723 Node* reg_index = __ BytecodeOperandReg(0); | |
| 724 Node* lhs = __ LoadRegister(reg_index); | |
| 725 Node* rhs = __ GetAccumulator(); | |
| 726 Node* context = __ GetContext(); | |
| 727 Node* result = __ CallRuntime(function_id, context, lhs, rhs); | |
| 728 __ SetAccumulator(result); | |
| 729 __ Dispatch(); | |
| 730 } | |
| 731 | |
| 732 template <class Generator> | 702 template <class Generator> |
| 733 void Interpreter::DoBinaryOp(InterpreterAssembler* assembler) { | 703 void Interpreter::DoBinaryOp(InterpreterAssembler* assembler) { |
| 734 Node* reg_index = __ BytecodeOperandReg(0); | 704 Node* reg_index = __ BytecodeOperandReg(0); |
| 735 Node* lhs = __ LoadRegister(reg_index); | 705 Node* lhs = __ LoadRegister(reg_index); |
| 736 Node* rhs = __ GetAccumulator(); | 706 Node* rhs = __ GetAccumulator(); |
| 737 Node* context = __ GetContext(); | 707 Node* context = __ GetContext(); |
| 738 Node* result = Generator::Generate(assembler, lhs, rhs, context); | 708 Node* result = Generator::Generate(assembler, lhs, rhs, context); |
| 739 __ SetAccumulator(result); | 709 __ SetAccumulator(result); |
| 740 __ Dispatch(); | 710 __ Dispatch(); |
| 741 } | 711 } |
| 742 | 712 |
| 743 // Add <src> | 713 // Add <src> |
| 744 // | 714 // |
| 745 // Add register <src> to accumulator. | 715 // Add register <src> to accumulator. |
| 746 void Interpreter::DoAdd(InterpreterAssembler* assembler) { | 716 void Interpreter::DoAdd(InterpreterAssembler* assembler) { |
| 747 DoBinaryOp<AddStub>(assembler); | 717 DoBinaryOp<AddStub>(assembler); |
| 748 } | 718 } |
| 749 | 719 |
| 750 | |
| 751 // Sub <src> | 720 // Sub <src> |
| 752 // | 721 // |
| 753 // Subtract register <src> from accumulator. | 722 // Subtract register <src> from accumulator. |
| 754 void Interpreter::DoSub(InterpreterAssembler* assembler) { | 723 void Interpreter::DoSub(InterpreterAssembler* assembler) { |
| 755 DoBinaryOp<SubtractStub>(assembler); | 724 DoBinaryOp<SubtractStub>(assembler); |
| 756 } | 725 } |
| 757 | 726 |
| 758 | |
| 759 // Mul <src> | 727 // Mul <src> |
| 760 // | 728 // |
| 761 // Multiply accumulator by register <src>. | 729 // Multiply accumulator by register <src>. |
| 762 void Interpreter::DoMul(InterpreterAssembler* assembler) { | 730 void Interpreter::DoMul(InterpreterAssembler* assembler) { |
| 763 DoBinaryOp<MultiplyStub>(assembler); | 731 DoBinaryOp<MultiplyStub>(assembler); |
| 764 } | 732 } |
| 765 | 733 |
| 766 | |
| 767 // Div <src> | 734 // Div <src> |
| 768 // | 735 // |
| 769 // Divide register <src> by accumulator. | 736 // Divide register <src> by accumulator. |
| 770 void Interpreter::DoDiv(InterpreterAssembler* assembler) { | 737 void Interpreter::DoDiv(InterpreterAssembler* assembler) { |
| 771 DoBinaryOp<DivideStub>(assembler); | 738 DoBinaryOp<DivideStub>(assembler); |
| 772 } | 739 } |
| 773 | 740 |
| 774 | |
| 775 // Mod <src> | 741 // Mod <src> |
| 776 // | 742 // |
| 777 // Modulo register <src> by accumulator. | 743 // Modulo register <src> by accumulator. |
| 778 void Interpreter::DoMod(InterpreterAssembler* assembler) { | 744 void Interpreter::DoMod(InterpreterAssembler* assembler) { |
| 779 DoBinaryOp<ModulusStub>(assembler); | 745 DoBinaryOp<ModulusStub>(assembler); |
| 780 } | 746 } |
| 781 | 747 |
| 782 | |
| 783 // BitwiseOr <src> | 748 // BitwiseOr <src> |
| 784 // | 749 // |
| 785 // BitwiseOr register <src> to accumulator. | 750 // BitwiseOr register <src> to accumulator. |
| 786 void Interpreter::DoBitwiseOr(InterpreterAssembler* assembler) { | 751 void Interpreter::DoBitwiseOr(InterpreterAssembler* assembler) { |
| 787 DoBinaryOp<BitwiseOrStub>(assembler); | 752 DoBinaryOp<BitwiseOrStub>(assembler); |
| 788 } | 753 } |
| 789 | 754 |
| 790 | |
| 791 // BitwiseXor <src> | 755 // BitwiseXor <src> |
| 792 // | 756 // |
| 793 // BitwiseXor register <src> to accumulator. | 757 // BitwiseXor register <src> to accumulator. |
| 794 void Interpreter::DoBitwiseXor(InterpreterAssembler* assembler) { | 758 void Interpreter::DoBitwiseXor(InterpreterAssembler* assembler) { |
| 795 DoBinaryOp<BitwiseXorStub>(assembler); | 759 DoBinaryOp<BitwiseXorStub>(assembler); |
| 796 } | 760 } |
| 797 | 761 |
| 798 | |
| 799 // BitwiseAnd <src> | 762 // BitwiseAnd <src> |
| 800 // | 763 // |
| 801 // BitwiseAnd register <src> to accumulator. | 764 // BitwiseAnd register <src> to accumulator. |
| 802 void Interpreter::DoBitwiseAnd(InterpreterAssembler* assembler) { | 765 void Interpreter::DoBitwiseAnd(InterpreterAssembler* assembler) { |
| 803 DoBinaryOp<BitwiseAndStub>(assembler); | 766 DoBinaryOp<BitwiseAndStub>(assembler); |
| 804 } | 767 } |
| 805 | 768 |
| 806 | |
| 807 // ShiftLeft <src> | 769 // ShiftLeft <src> |
| 808 // | 770 // |
| 809 // Left shifts register <src> by the count specified in the accumulator. | 771 // Left shifts register <src> by the count specified in the accumulator. |
| 810 // Register <src> is converted to an int32 and the accumulator to uint32 | 772 // Register <src> is converted to an int32 and the accumulator to uint32 |
| 811 // before the operation. 5 lsb bits from the accumulator are used as count | 773 // before the operation. 5 lsb bits from the accumulator are used as count |
| 812 // i.e. <src> << (accumulator & 0x1F). | 774 // i.e. <src> << (accumulator & 0x1F). |
| 813 void Interpreter::DoShiftLeft(InterpreterAssembler* assembler) { | 775 void Interpreter::DoShiftLeft(InterpreterAssembler* assembler) { |
| 814 DoBinaryOp<ShiftLeftStub>(assembler); | 776 DoBinaryOp<ShiftLeftStub>(assembler); |
| 815 } | 777 } |
| 816 | 778 |
| 817 | |
| 818 // ShiftRight <src> | 779 // ShiftRight <src> |
| 819 // | 780 // |
| 820 // Right shifts register <src> by the count specified in the accumulator. | 781 // Right shifts register <src> by the count specified in the accumulator. |
| 821 // Result is sign extended. Register <src> is converted to an int32 and the | 782 // Result is sign extended. Register <src> is converted to an int32 and the |
| 822 // accumulator to uint32 before the operation. 5 lsb bits from the accumulator | 783 // accumulator to uint32 before the operation. 5 lsb bits from the accumulator |
| 823 // are used as count i.e. <src> >> (accumulator & 0x1F). | 784 // are used as count i.e. <src> >> (accumulator & 0x1F). |
| 824 void Interpreter::DoShiftRight(InterpreterAssembler* assembler) { | 785 void Interpreter::DoShiftRight(InterpreterAssembler* assembler) { |
| 825 DoBinaryOp<ShiftRightStub>(assembler); | 786 DoBinaryOp<ShiftRightStub>(assembler); |
| 826 } | 787 } |
| 827 | 788 |
| 828 | |
| 829 // ShiftRightLogical <src> | 789 // ShiftRightLogical <src> |
| 830 // | 790 // |
| 831 // Right Shifts register <src> by the count specified in the accumulator. | 791 // Right Shifts register <src> by the count specified in the accumulator. |
| 832 // Result is zero-filled. The accumulator and register <src> are converted to | 792 // Result is zero-filled. The accumulator and register <src> are converted to |
| 833 // uint32 before the operation 5 lsb bits from the accumulator are used as | 793 // uint32 before the operation 5 lsb bits from the accumulator are used as |
| 834 // count i.e. <src> << (accumulator & 0x1F). | 794 // count i.e. <src> << (accumulator & 0x1F). |
| 835 void Interpreter::DoShiftRightLogical(InterpreterAssembler* assembler) { | 795 void Interpreter::DoShiftRightLogical(InterpreterAssembler* assembler) { |
| 836 DoBinaryOp<ShiftRightLogicalStub>(assembler); | 796 DoBinaryOp<ShiftRightLogicalStub>(assembler); |
| 837 } | 797 } |
| 838 | 798 |
| 799 void Interpreter::DoUnaryOp(Callable callable, |
| 800 InterpreterAssembler* assembler) { |
| 801 Node* target = __ HeapConstant(callable.code()); |
| 802 Node* accumulator = __ GetAccumulator(); |
| 803 Node* context = __ GetContext(); |
| 804 Node* result = |
| 805 __ CallStub(callable.descriptor(), target, context, accumulator); |
| 806 __ SetAccumulator(result); |
| 807 __ Dispatch(); |
| 808 } |
| 809 |
| 839 template <class Generator> | 810 template <class Generator> |
| 840 void Interpreter::DoUnaryOp(InterpreterAssembler* assembler) { | 811 void Interpreter::DoUnaryOp(InterpreterAssembler* assembler) { |
| 841 Node* value = __ GetAccumulator(); | 812 Node* value = __ GetAccumulator(); |
| 842 Node* context = __ GetContext(); | 813 Node* context = __ GetContext(); |
| 843 Node* result = Generator::Generate(assembler, value, context); | 814 Node* result = Generator::Generate(assembler, value, context); |
| 844 __ SetAccumulator(result); | 815 __ SetAccumulator(result); |
| 845 __ Dispatch(); | 816 __ Dispatch(); |
| 846 } | 817 } |
| 847 | 818 |
| 819 // ToName |
| 820 // |
| 821 // Cast the object referenced by the accumulator to a name. |
| 822 void Interpreter::DoToName(InterpreterAssembler* assembler) { |
| 823 DoUnaryOp(CodeFactory::ToName(isolate_), assembler); |
| 824 } |
| 825 |
| 826 // ToNumber |
| 827 // |
| 828 // Cast the object referenced by the accumulator to a number. |
| 829 void Interpreter::DoToNumber(InterpreterAssembler* assembler) { |
| 830 DoUnaryOp(CodeFactory::ToNumber(isolate_), assembler); |
| 831 } |
| 832 |
| 833 // ToObject |
| 834 // |
| 835 // Cast the object referenced by the accumulator to a JSObject. |
| 836 void Interpreter::DoToObject(InterpreterAssembler* assembler) { |
| 837 DoUnaryOp(CodeFactory::ToObject(isolate_), assembler); |
| 838 } |
| 839 |
| 848 // Inc | 840 // Inc |
| 849 // | 841 // |
| 850 // Increments value in the accumulator by one. | 842 // Increments value in the accumulator by one. |
| 851 void Interpreter::DoInc(InterpreterAssembler* assembler) { | 843 void Interpreter::DoInc(InterpreterAssembler* assembler) { |
| 852 DoUnaryOp<IncStub>(assembler); | 844 DoUnaryOp<IncStub>(assembler); |
| 853 } | 845 } |
| 854 | 846 |
| 855 // Dec | 847 // Dec |
| 856 // | 848 // |
| 857 // Decrements value in the accumulator by one. | 849 // Decrements value in the accumulator by one. |
| 858 void Interpreter::DoDec(InterpreterAssembler* assembler) { | 850 void Interpreter::DoDec(InterpreterAssembler* assembler) { |
| 859 DoUnaryOp<DecStub>(assembler); | 851 DoUnaryOp<DecStub>(assembler); |
| 860 } | 852 } |
| 861 | 853 |
| 862 void Interpreter::DoLogicalNotOp(Node* value, InterpreterAssembler* assembler) { | 854 Node* Interpreter::BuildToBoolean(Node* value, |
| 855 InterpreterAssembler* assembler) { |
| 856 Node* context = __ GetContext(); |
| 857 return ToBooleanStub::Generate(assembler, value, context); |
| 858 } |
| 859 |
| 860 Node* Interpreter::BuildLogicalNot(Node* value, |
| 861 InterpreterAssembler* assembler) { |
| 862 Variable result(assembler, MachineRepresentation::kTagged); |
| 863 Label if_true(assembler), if_false(assembler), end(assembler); | 863 Label if_true(assembler), if_false(assembler), end(assembler); |
| 864 Node* true_value = __ BooleanConstant(true); | 864 Node* true_value = __ BooleanConstant(true); |
| 865 Node* false_value = __ BooleanConstant(false); | 865 Node* false_value = __ BooleanConstant(false); |
| 866 __ BranchIfWordEqual(value, true_value, &if_true, &if_false); | 866 __ BranchIfWordEqual(value, true_value, &if_true, &if_false); |
| 867 __ Bind(&if_true); | 867 __ Bind(&if_true); |
| 868 { | 868 { |
| 869 __ SetAccumulator(false_value); | 869 result.Bind(false_value); |
| 870 __ Goto(&end); | 870 __ Goto(&end); |
| 871 } | 871 } |
| 872 __ Bind(&if_false); | 872 __ Bind(&if_false); |
| 873 { | 873 { |
| 874 if (FLAG_debug_code) { | 874 if (FLAG_debug_code) { |
| 875 __ AbortIfWordNotEqual(value, false_value, | 875 __ AbortIfWordNotEqual(value, false_value, |
| 876 BailoutReason::kExpectedBooleanValue); | 876 BailoutReason::kExpectedBooleanValue); |
| 877 } | 877 } |
| 878 __ SetAccumulator(true_value); | 878 result.Bind(true_value); |
| 879 __ Goto(&end); | 879 __ Goto(&end); |
| 880 } | 880 } |
| 881 __ Bind(&end); | 881 __ Bind(&end); |
| 882 return result.value(); |
| 882 } | 883 } |
| 883 | 884 |
| 884 // ToBooleanLogicalNot | 885 // LogicalNot |
| 885 // | 886 // |
| 886 // Perform logical-not on the accumulator, first casting the | 887 // Perform logical-not on the accumulator, first casting the |
| 887 // accumulator to a boolean value if required. | 888 // accumulator to a boolean value if required. |
| 889 // ToBooleanLogicalNot |
| 888 void Interpreter::DoToBooleanLogicalNot(InterpreterAssembler* assembler) { | 890 void Interpreter::DoToBooleanLogicalNot(InterpreterAssembler* assembler) { |
| 889 Callable callable = CodeFactory::ToBoolean(isolate_); | 891 Node* value = __ GetAccumulator(); |
| 890 Node* target = __ HeapConstant(callable.code()); | 892 Node* to_boolean_value = BuildToBoolean(value, assembler); |
| 891 Node* accumulator = __ GetAccumulator(); | 893 Node* result = BuildLogicalNot(to_boolean_value, assembler); |
| 892 Node* context = __ GetContext(); | 894 __ SetAccumulator(result); |
| 893 Node* to_boolean_value = | |
| 894 __ CallStub(callable.descriptor(), target, context, accumulator); | |
| 895 DoLogicalNotOp(to_boolean_value, assembler); | |
| 896 __ Dispatch(); | 895 __ Dispatch(); |
| 897 } | 896 } |
| 898 | 897 |
| 899 // LogicalNot | 898 // LogicalNot |
| 900 // | 899 // |
| 901 // Perform logical-not on the accumulator, which must already be a boolean | 900 // Perform logical-not on the accumulator, which must already be a boolean |
| 902 // value. | 901 // value. |
| 903 void Interpreter::DoLogicalNot(InterpreterAssembler* assembler) { | 902 void Interpreter::DoLogicalNot(InterpreterAssembler* assembler) { |
| 904 Node* value = __ GetAccumulator(); | 903 Node* value = __ GetAccumulator(); |
| 905 DoLogicalNotOp(value, assembler); | 904 Node* result = BuildLogicalNot(value, assembler); |
| 905 __ SetAccumulator(result); |
| 906 __ Dispatch(); | 906 __ Dispatch(); |
| 907 } | 907 } |
| 908 | 908 |
| 909 // TypeOf | 909 // TypeOf |
| 910 // | 910 // |
| 911 // Load the accumulator with the string representating type of the | 911 // Load the accumulator with the string representating type of the |
| 912 // object in the accumulator. | 912 // object in the accumulator. |
| 913 void Interpreter::DoTypeOf(InterpreterAssembler* assembler) { | 913 void Interpreter::DoTypeOf(InterpreterAssembler* assembler) { |
| 914 Callable callable = CodeFactory::Typeof(isolate_); | 914 DoUnaryOp(CodeFactory::Typeof(isolate_), assembler); |
| 915 Node* target = __ HeapConstant(callable.code()); | |
| 916 Node* accumulator = __ GetAccumulator(); | |
| 917 Node* context = __ GetContext(); | |
| 918 Node* result = | |
| 919 __ CallStub(callable.descriptor(), target, context, accumulator); | |
| 920 __ SetAccumulator(result); | |
| 921 __ Dispatch(); | |
| 922 } | 915 } |
| 923 | 916 |
| 924 void Interpreter::DoDelete(Runtime::FunctionId function_id, | 917 void Interpreter::DoDelete(Runtime::FunctionId function_id, |
| 925 InterpreterAssembler* assembler) { | 918 InterpreterAssembler* assembler) { |
| 926 Node* reg_index = __ BytecodeOperandReg(0); | 919 Node* reg_index = __ BytecodeOperandReg(0); |
| 927 Node* object = __ LoadRegister(reg_index); | 920 Node* object = __ LoadRegister(reg_index); |
| 928 Node* key = __ GetAccumulator(); | 921 Node* key = __ GetAccumulator(); |
| 929 Node* context = __ GetContext(); | 922 Node* context = __ GetContext(); |
| 930 Node* result = __ CallRuntime(function_id, context, object, key); | 923 Node* result = __ CallRuntime(function_id, context, object, key); |
| 931 __ SetAccumulator(result); | 924 __ SetAccumulator(result); |
| 932 __ Dispatch(); | 925 __ Dispatch(); |
| 933 } | 926 } |
| 934 | 927 |
| 935 | |
| 936 // DeletePropertyStrict | 928 // DeletePropertyStrict |
| 937 // | 929 // |
| 938 // Delete the property specified in the accumulator from the object | 930 // Delete the property specified in the accumulator from the object |
| 939 // referenced by the register operand following strict mode semantics. | 931 // referenced by the register operand following strict mode semantics. |
| 940 void Interpreter::DoDeletePropertyStrict(InterpreterAssembler* assembler) { | 932 void Interpreter::DoDeletePropertyStrict(InterpreterAssembler* assembler) { |
| 941 DoDelete(Runtime::kDeleteProperty_Strict, assembler); | 933 DoDelete(Runtime::kDeleteProperty_Strict, assembler); |
| 942 } | 934 } |
| 943 | 935 |
| 944 | |
| 945 // DeletePropertySloppy | 936 // DeletePropertySloppy |
| 946 // | 937 // |
| 947 // Delete the property specified in the accumulator from the object | 938 // Delete the property specified in the accumulator from the object |
| 948 // referenced by the register operand following sloppy mode semantics. | 939 // referenced by the register operand following sloppy mode semantics. |
| 949 void Interpreter::DoDeletePropertySloppy(InterpreterAssembler* assembler) { | 940 void Interpreter::DoDeletePropertySloppy(InterpreterAssembler* assembler) { |
| 950 DoDelete(Runtime::kDeleteProperty_Sloppy, assembler); | 941 DoDelete(Runtime::kDeleteProperty_Sloppy, assembler); |
| 951 } | 942 } |
| 952 | 943 |
| 953 void Interpreter::DoJSCall(InterpreterAssembler* assembler, | 944 void Interpreter::DoJSCall(InterpreterAssembler* assembler, |
| 954 TailCallMode tail_call_mode) { | 945 TailCallMode tail_call_mode) { |
| 955 Node* function_reg = __ BytecodeOperandReg(0); | 946 Node* function_reg = __ BytecodeOperandReg(0); |
| 956 Node* function = __ LoadRegister(function_reg); | 947 Node* function = __ LoadRegister(function_reg); |
| 957 Node* receiver_reg = __ BytecodeOperandReg(1); | 948 Node* receiver_reg = __ BytecodeOperandReg(1); |
| 958 Node* receiver_arg = __ RegisterLocation(receiver_reg); | 949 Node* receiver_arg = __ RegisterLocation(receiver_reg); |
| 959 Node* receiver_args_count = __ BytecodeOperandCount(2); | 950 Node* receiver_args_count = __ BytecodeOperandCount(2); |
| 960 Node* receiver_count = __ Int32Constant(1); | 951 Node* receiver_count = __ Int32Constant(1); |
| 961 Node* args_count = __ Int32Sub(receiver_args_count, receiver_count); | 952 Node* args_count = __ Int32Sub(receiver_args_count, receiver_count); |
| 962 Node* context = __ GetContext(); | 953 Node* context = __ GetContext(); |
| 963 // TODO(rmcilroy): Use the call type feedback slot to call via CallStub. | 954 // TODO(rmcilroy): Use the call type feedback slot to call via CallStub. |
| 964 Node* result = | 955 Node* result = |
| 965 __ CallJS(function, context, receiver_arg, args_count, tail_call_mode); | 956 __ CallJS(function, context, receiver_arg, args_count, tail_call_mode); |
| 966 __ SetAccumulator(result); | 957 __ SetAccumulator(result); |
| 967 __ Dispatch(); | 958 __ Dispatch(); |
| 968 } | 959 } |
| 969 | 960 |
| 970 | |
| 971 // Call <callable> <receiver> <arg_count> | 961 // Call <callable> <receiver> <arg_count> |
| 972 // | 962 // |
| 973 // Call a JSfunction or Callable in |callable| with the |receiver| and | 963 // Call a JSfunction or Callable in |callable| with the |receiver| and |
| 974 // |arg_count| arguments in subsequent registers. | 964 // |arg_count| arguments in subsequent registers. |
| 975 void Interpreter::DoCall(InterpreterAssembler* assembler) { | 965 void Interpreter::DoCall(InterpreterAssembler* assembler) { |
| 976 DoJSCall(assembler, TailCallMode::kDisallow); | 966 DoJSCall(assembler, TailCallMode::kDisallow); |
| 977 } | 967 } |
| 978 | 968 |
| 979 // TailCall <callable> <receiver> <arg_count> | 969 // TailCall <callable> <receiver> <arg_count> |
| 980 // | 970 // |
| 981 // Tail call a JSfunction or Callable in |callable| with the |receiver| and | 971 // Tail call a JSfunction or Callable in |callable| with the |receiver| and |
| 982 // |arg_count| arguments in subsequent registers. | 972 // |arg_count| arguments in subsequent registers. |
| 983 void Interpreter::DoTailCall(InterpreterAssembler* assembler) { | 973 void Interpreter::DoTailCall(InterpreterAssembler* assembler) { |
| 984 DoJSCall(assembler, TailCallMode::kAllow); | 974 DoJSCall(assembler, TailCallMode::kAllow); |
| 985 } | 975 } |
| 986 | 976 |
| 987 void Interpreter::DoCallRuntimeCommon(InterpreterAssembler* assembler) { | 977 void Interpreter::DoCallRuntimeCommon(InterpreterAssembler* assembler) { |
| 988 Node* function_id = __ BytecodeOperandRuntimeId(0); | 978 Node* function_id = __ BytecodeOperandRuntimeId(0); |
| 989 Node* first_arg_reg = __ BytecodeOperandReg(1); | 979 Node* first_arg_reg = __ BytecodeOperandReg(1); |
| 990 Node* first_arg = __ RegisterLocation(first_arg_reg); | 980 Node* first_arg = __ RegisterLocation(first_arg_reg); |
| 991 Node* args_count = __ BytecodeOperandCount(2); | 981 Node* args_count = __ BytecodeOperandCount(2); |
| 992 Node* context = __ GetContext(); | 982 Node* context = __ GetContext(); |
| 993 Node* result = __ CallRuntimeN(function_id, context, first_arg, args_count); | 983 Node* result = __ CallRuntimeN(function_id, context, first_arg, args_count); |
| 994 __ SetAccumulator(result); | 984 __ SetAccumulator(result); |
| 995 __ Dispatch(); | 985 __ Dispatch(); |
| 996 } | 986 } |
| 997 | 987 |
| 998 | |
| 999 // CallRuntime <function_id> <first_arg> <arg_count> | 988 // CallRuntime <function_id> <first_arg> <arg_count> |
| 1000 // | 989 // |
| 1001 // Call the runtime function |function_id| with the first argument in | 990 // Call the runtime function |function_id| with the first argument in |
| 1002 // register |first_arg| and |arg_count| arguments in subsequent | 991 // register |first_arg| and |arg_count| arguments in subsequent |
| 1003 // registers. | 992 // registers. |
| 1004 void Interpreter::DoCallRuntime(InterpreterAssembler* assembler) { | 993 void Interpreter::DoCallRuntime(InterpreterAssembler* assembler) { |
| 1005 DoCallRuntimeCommon(assembler); | 994 DoCallRuntimeCommon(assembler); |
| 1006 } | 995 } |
| 1007 | 996 |
| 1008 // InvokeIntrinsic <function_id> <first_arg> <arg_count> | 997 // InvokeIntrinsic <function_id> <first_arg> <arg_count> |
| (...skipping 26 matching lines...) Expand all Loading... |
| 1035 // Store the results in <first_return> and <first_return + 1> | 1024 // Store the results in <first_return> and <first_return + 1> |
| 1036 Node* first_return_reg = __ BytecodeOperandReg(3); | 1025 Node* first_return_reg = __ BytecodeOperandReg(3); |
| 1037 Node* second_return_reg = __ NextRegister(first_return_reg); | 1026 Node* second_return_reg = __ NextRegister(first_return_reg); |
| 1038 Node* result0 = __ Projection(0, result_pair); | 1027 Node* result0 = __ Projection(0, result_pair); |
| 1039 Node* result1 = __ Projection(1, result_pair); | 1028 Node* result1 = __ Projection(1, result_pair); |
| 1040 __ StoreRegister(result0, first_return_reg); | 1029 __ StoreRegister(result0, first_return_reg); |
| 1041 __ StoreRegister(result1, second_return_reg); | 1030 __ StoreRegister(result1, second_return_reg); |
| 1042 __ Dispatch(); | 1031 __ Dispatch(); |
| 1043 } | 1032 } |
| 1044 | 1033 |
| 1045 | |
| 1046 // CallRuntimeForPair <function_id> <first_arg> <arg_count> <first_return> | 1034 // CallRuntimeForPair <function_id> <first_arg> <arg_count> <first_return> |
| 1047 // | 1035 // |
| 1048 // Call the runtime function |function_id| which returns a pair, with the | 1036 // Call the runtime function |function_id| which returns a pair, with the |
| 1049 // first argument in register |first_arg| and |arg_count| arguments in | 1037 // first argument in register |first_arg| and |arg_count| arguments in |
| 1050 // subsequent registers. Returns the result in <first_return> and | 1038 // subsequent registers. Returns the result in <first_return> and |
| 1051 // <first_return + 1> | 1039 // <first_return + 1> |
| 1052 void Interpreter::DoCallRuntimeForPair(InterpreterAssembler* assembler) { | 1040 void Interpreter::DoCallRuntimeForPair(InterpreterAssembler* assembler) { |
| 1053 DoCallRuntimeForPairCommon(assembler); | 1041 DoCallRuntimeForPairCommon(assembler); |
| 1054 } | 1042 } |
| 1055 | 1043 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1067 __ LoadContextSlot(context, Context::NATIVE_CONTEXT_INDEX); | 1055 __ LoadContextSlot(context, Context::NATIVE_CONTEXT_INDEX); |
| 1068 Node* function = __ LoadContextSlot(native_context, context_index); | 1056 Node* function = __ LoadContextSlot(native_context, context_index); |
| 1069 | 1057 |
| 1070 // Call the function. | 1058 // Call the function. |
| 1071 Node* result = __ CallJS(function, context, first_arg, args_count, | 1059 Node* result = __ CallJS(function, context, first_arg, args_count, |
| 1072 TailCallMode::kDisallow); | 1060 TailCallMode::kDisallow); |
| 1073 __ SetAccumulator(result); | 1061 __ SetAccumulator(result); |
| 1074 __ Dispatch(); | 1062 __ Dispatch(); |
| 1075 } | 1063 } |
| 1076 | 1064 |
| 1077 | |
| 1078 // CallJSRuntime <context_index> <receiver> <arg_count> | 1065 // CallJSRuntime <context_index> <receiver> <arg_count> |
| 1079 // | 1066 // |
| 1080 // Call the JS runtime function that has the |context_index| with the receiver | 1067 // Call the JS runtime function that has the |context_index| with the receiver |
| 1081 // in register |receiver| and |arg_count| arguments in subsequent registers. | 1068 // in register |receiver| and |arg_count| arguments in subsequent registers. |
| 1082 void Interpreter::DoCallJSRuntime(InterpreterAssembler* assembler) { | 1069 void Interpreter::DoCallJSRuntime(InterpreterAssembler* assembler) { |
| 1083 DoCallJSRuntimeCommon(assembler); | 1070 DoCallJSRuntimeCommon(assembler); |
| 1084 } | 1071 } |
| 1085 | 1072 |
| 1086 void Interpreter::DoCallConstruct(InterpreterAssembler* assembler) { | 1073 void Interpreter::DoCallConstruct(InterpreterAssembler* assembler) { |
| 1087 Callable ic = CodeFactory::InterpreterPushArgsAndConstruct(isolate_); | 1074 Callable ic = CodeFactory::InterpreterPushArgsAndConstruct(isolate_); |
| 1088 Node* new_target = __ GetAccumulator(); | 1075 Node* new_target = __ GetAccumulator(); |
| 1089 Node* constructor_reg = __ BytecodeOperandReg(0); | 1076 Node* constructor_reg = __ BytecodeOperandReg(0); |
| 1090 Node* constructor = __ LoadRegister(constructor_reg); | 1077 Node* constructor = __ LoadRegister(constructor_reg); |
| 1091 Node* first_arg_reg = __ BytecodeOperandReg(1); | 1078 Node* first_arg_reg = __ BytecodeOperandReg(1); |
| 1092 Node* first_arg = __ RegisterLocation(first_arg_reg); | 1079 Node* first_arg = __ RegisterLocation(first_arg_reg); |
| 1093 Node* args_count = __ BytecodeOperandCount(2); | 1080 Node* args_count = __ BytecodeOperandCount(2); |
| 1094 Node* context = __ GetContext(); | 1081 Node* context = __ GetContext(); |
| 1095 Node* result = | 1082 Node* result = |
| 1096 __ CallConstruct(constructor, context, new_target, first_arg, args_count); | 1083 __ CallConstruct(constructor, context, new_target, first_arg, args_count); |
| 1097 __ SetAccumulator(result); | 1084 __ SetAccumulator(result); |
| 1098 __ Dispatch(); | 1085 __ Dispatch(); |
| 1099 } | 1086 } |
| 1100 | 1087 |
| 1101 | |
| 1102 // New <constructor> <first_arg> <arg_count> | 1088 // New <constructor> <first_arg> <arg_count> |
| 1103 // | 1089 // |
| 1104 // Call operator new with |constructor| and the first argument in | 1090 // Call operator new with |constructor| and the first argument in |
| 1105 // register |first_arg| and |arg_count| arguments in subsequent | 1091 // register |first_arg| and |arg_count| arguments in subsequent |
| 1106 // registers. The new.target is in the accumulator. | 1092 // registers. The new.target is in the accumulator. |
| 1107 // | 1093 // |
| 1108 void Interpreter::DoNew(InterpreterAssembler* assembler) { | 1094 void Interpreter::DoNew(InterpreterAssembler* assembler) { |
| 1109 DoCallConstruct(assembler); | 1095 DoCallConstruct(assembler); |
| 1110 } | 1096 } |
| 1111 | 1097 |
| 1112 // TestEqual <src> | 1098 // TestEqual <src> |
| 1113 // | 1099 // |
| 1114 // Test if the value in the <src> register equals the accumulator. | 1100 // Test if the value in the <src> register equals the accumulator. |
| 1115 void Interpreter::DoTestEqual(InterpreterAssembler* assembler) { | 1101 void Interpreter::DoTestEqual(InterpreterAssembler* assembler) { |
| 1116 DoBinaryOp(CodeFactory::Equal(isolate_), assembler); | 1102 DoBinaryOp(CodeFactory::Equal(isolate_), assembler); |
| 1117 } | 1103 } |
| 1118 | 1104 |
| 1119 | |
| 1120 // TestNotEqual <src> | 1105 // TestNotEqual <src> |
| 1121 // | 1106 // |
| 1122 // Test if the value in the <src> register is not equal to the accumulator. | 1107 // Test if the value in the <src> register is not equal to the accumulator. |
| 1123 void Interpreter::DoTestNotEqual(InterpreterAssembler* assembler) { | 1108 void Interpreter::DoTestNotEqual(InterpreterAssembler* assembler) { |
| 1124 DoBinaryOp(CodeFactory::NotEqual(isolate_), assembler); | 1109 DoBinaryOp(CodeFactory::NotEqual(isolate_), assembler); |
| 1125 } | 1110 } |
| 1126 | 1111 |
| 1127 | |
| 1128 // TestEqualStrict <src> | 1112 // TestEqualStrict <src> |
| 1129 // | 1113 // |
| 1130 // Test if the value in the <src> register is strictly equal to the accumulator. | 1114 // Test if the value in the <src> register is strictly equal to the accumulator. |
| 1131 void Interpreter::DoTestEqualStrict(InterpreterAssembler* assembler) { | 1115 void Interpreter::DoTestEqualStrict(InterpreterAssembler* assembler) { |
| 1132 DoBinaryOp(CodeFactory::StrictEqual(isolate_), assembler); | 1116 DoBinaryOp(CodeFactory::StrictEqual(isolate_), assembler); |
| 1133 } | 1117 } |
| 1134 | 1118 |
| 1135 | |
| 1136 // TestLessThan <src> | 1119 // TestLessThan <src> |
| 1137 // | 1120 // |
| 1138 // Test if the value in the <src> register is less than the accumulator. | 1121 // Test if the value in the <src> register is less than the accumulator. |
| 1139 void Interpreter::DoTestLessThan(InterpreterAssembler* assembler) { | 1122 void Interpreter::DoTestLessThan(InterpreterAssembler* assembler) { |
| 1140 DoBinaryOp(CodeFactory::LessThan(isolate_), assembler); | 1123 DoBinaryOp(CodeFactory::LessThan(isolate_), assembler); |
| 1141 } | 1124 } |
| 1142 | 1125 |
| 1143 | |
| 1144 // TestGreaterThan <src> | 1126 // TestGreaterThan <src> |
| 1145 // | 1127 // |
| 1146 // Test if the value in the <src> register is greater than the accumulator. | 1128 // Test if the value in the <src> register is greater than the accumulator. |
| 1147 void Interpreter::DoTestGreaterThan(InterpreterAssembler* assembler) { | 1129 void Interpreter::DoTestGreaterThan(InterpreterAssembler* assembler) { |
| 1148 DoBinaryOp(CodeFactory::GreaterThan(isolate_), assembler); | 1130 DoBinaryOp(CodeFactory::GreaterThan(isolate_), assembler); |
| 1149 } | 1131 } |
| 1150 | 1132 |
| 1151 | |
| 1152 // TestLessThanOrEqual <src> | 1133 // TestLessThanOrEqual <src> |
| 1153 // | 1134 // |
| 1154 // Test if the value in the <src> register is less than or equal to the | 1135 // Test if the value in the <src> register is less than or equal to the |
| 1155 // accumulator. | 1136 // accumulator. |
| 1156 void Interpreter::DoTestLessThanOrEqual(InterpreterAssembler* assembler) { | 1137 void Interpreter::DoTestLessThanOrEqual(InterpreterAssembler* assembler) { |
| 1157 DoBinaryOp(CodeFactory::LessThanOrEqual(isolate_), assembler); | 1138 DoBinaryOp(CodeFactory::LessThanOrEqual(isolate_), assembler); |
| 1158 } | 1139 } |
| 1159 | 1140 |
| 1160 | |
| 1161 // TestGreaterThanOrEqual <src> | 1141 // TestGreaterThanOrEqual <src> |
| 1162 // | 1142 // |
| 1163 // Test if the value in the <src> register is greater than or equal to the | 1143 // Test if the value in the <src> register is greater than or equal to the |
| 1164 // accumulator. | 1144 // accumulator. |
| 1165 void Interpreter::DoTestGreaterThanOrEqual(InterpreterAssembler* assembler) { | 1145 void Interpreter::DoTestGreaterThanOrEqual(InterpreterAssembler* assembler) { |
| 1166 DoBinaryOp(CodeFactory::GreaterThanOrEqual(isolate_), assembler); | 1146 DoBinaryOp(CodeFactory::GreaterThanOrEqual(isolate_), assembler); |
| 1167 } | 1147 } |
| 1168 | 1148 |
| 1169 | |
| 1170 // TestIn <src> | 1149 // TestIn <src> |
| 1171 // | 1150 // |
| 1172 // Test if the object referenced by the register operand is a property of the | 1151 // Test if the object referenced by the register operand is a property of the |
| 1173 // object referenced by the accumulator. | 1152 // object referenced by the accumulator. |
| 1174 void Interpreter::DoTestIn(InterpreterAssembler* assembler) { | 1153 void Interpreter::DoTestIn(InterpreterAssembler* assembler) { |
| 1175 DoBinaryOp(CodeFactory::HasProperty(isolate_), assembler); | 1154 DoBinaryOp(CodeFactory::HasProperty(isolate_), assembler); |
| 1176 } | 1155 } |
| 1177 | 1156 |
| 1178 | |
| 1179 // TestInstanceOf <src> | 1157 // TestInstanceOf <src> |
| 1180 // | 1158 // |
| 1181 // Test if the object referenced by the <src> register is an an instance of type | 1159 // Test if the object referenced by the <src> register is an an instance of type |
| 1182 // referenced by the accumulator. | 1160 // referenced by the accumulator. |
| 1183 void Interpreter::DoTestInstanceOf(InterpreterAssembler* assembler) { | 1161 void Interpreter::DoTestInstanceOf(InterpreterAssembler* assembler) { |
| 1184 DoBinaryOp(CodeFactory::InstanceOf(isolate_), assembler); | 1162 DoBinaryOp(CodeFactory::InstanceOf(isolate_), assembler); |
| 1185 } | 1163 } |
| 1186 | 1164 |
| 1187 void Interpreter::DoTypeConversionOp(Callable callable, | |
| 1188 InterpreterAssembler* assembler) { | |
| 1189 Node* target = __ HeapConstant(callable.code()); | |
| 1190 Node* accumulator = __ GetAccumulator(); | |
| 1191 Node* context = __ GetContext(); | |
| 1192 Node* result = | |
| 1193 __ CallStub(callable.descriptor(), target, context, accumulator); | |
| 1194 __ SetAccumulator(result); | |
| 1195 __ Dispatch(); | |
| 1196 } | |
| 1197 | |
| 1198 // ToName | |
| 1199 // | |
| 1200 // Cast the object referenced by the accumulator to a name. | |
| 1201 void Interpreter::DoToName(InterpreterAssembler* assembler) { | |
| 1202 DoTypeConversionOp(CodeFactory::ToName(isolate_), assembler); | |
| 1203 } | |
| 1204 | |
| 1205 | |
| 1206 // ToNumber | |
| 1207 // | |
| 1208 // Cast the object referenced by the accumulator to a number. | |
| 1209 void Interpreter::DoToNumber(InterpreterAssembler* assembler) { | |
| 1210 DoTypeConversionOp(CodeFactory::ToNumber(isolate_), assembler); | |
| 1211 } | |
| 1212 | |
| 1213 | |
| 1214 // ToObject | |
| 1215 // | |
| 1216 // Cast the object referenced by the accumulator to a JSObject. | |
| 1217 void Interpreter::DoToObject(InterpreterAssembler* assembler) { | |
| 1218 DoTypeConversionOp(CodeFactory::ToObject(isolate_), assembler); | |
| 1219 } | |
| 1220 | |
| 1221 // Jump <imm> | 1165 // Jump <imm> |
| 1222 // | 1166 // |
| 1223 // Jump by number of bytes represented by the immediate operand |imm|. | 1167 // Jump by number of bytes represented by the immediate operand |imm|. |
| 1224 void Interpreter::DoJump(InterpreterAssembler* assembler) { | 1168 void Interpreter::DoJump(InterpreterAssembler* assembler) { |
| 1225 Node* relative_jump = __ BytecodeOperandImm(0); | 1169 Node* relative_jump = __ BytecodeOperandImm(0); |
| 1226 __ Jump(relative_jump); | 1170 __ Jump(relative_jump); |
| 1227 } | 1171 } |
| 1228 | 1172 |
| 1229 // JumpConstant <idx> | 1173 // JumpConstant <idx> |
| 1230 // | 1174 // |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1282 Node* relative_jump = __ SmiUntag(constant); | 1226 Node* relative_jump = __ SmiUntag(constant); |
| 1283 Node* false_value = __ BooleanConstant(false); | 1227 Node* false_value = __ BooleanConstant(false); |
| 1284 __ JumpIfWordEqual(accumulator, false_value, relative_jump); | 1228 __ JumpIfWordEqual(accumulator, false_value, relative_jump); |
| 1285 } | 1229 } |
| 1286 | 1230 |
| 1287 // JumpIfToBooleanTrue <imm> | 1231 // JumpIfToBooleanTrue <imm> |
| 1288 // | 1232 // |
| 1289 // Jump by number of bytes represented by an immediate operand if the object | 1233 // Jump by number of bytes represented by an immediate operand if the object |
| 1290 // referenced by the accumulator is true when the object is cast to boolean. | 1234 // referenced by the accumulator is true when the object is cast to boolean. |
| 1291 void Interpreter::DoJumpIfToBooleanTrue(InterpreterAssembler* assembler) { | 1235 void Interpreter::DoJumpIfToBooleanTrue(InterpreterAssembler* assembler) { |
| 1292 Callable callable = CodeFactory::ToBoolean(isolate_); | |
| 1293 Node* target = __ HeapConstant(callable.code()); | |
| 1294 Node* accumulator = __ GetAccumulator(); | 1236 Node* accumulator = __ GetAccumulator(); |
| 1295 Node* context = __ GetContext(); | 1237 Node* to_boolean_value = BuildToBoolean(accumulator, assembler); |
| 1296 Node* to_boolean_value = | |
| 1297 __ CallStub(callable.descriptor(), target, context, accumulator); | |
| 1298 Node* relative_jump = __ BytecodeOperandImm(0); | 1238 Node* relative_jump = __ BytecodeOperandImm(0); |
| 1299 Node* true_value = __ BooleanConstant(true); | 1239 Node* true_value = __ BooleanConstant(true); |
| 1300 __ JumpIfWordEqual(to_boolean_value, true_value, relative_jump); | 1240 __ JumpIfWordEqual(to_boolean_value, true_value, relative_jump); |
| 1301 } | 1241 } |
| 1302 | 1242 |
| 1303 // JumpIfToBooleanTrueConstant <idx> | 1243 // JumpIfToBooleanTrueConstant <idx> |
| 1304 // | 1244 // |
| 1305 // Jump by number of bytes in the Smi in the |idx| entry in the constant pool | 1245 // Jump by number of bytes in the Smi in the |idx| entry in the constant pool |
| 1306 // if the object referenced by the accumulator is true when the object is cast | 1246 // if the object referenced by the accumulator is true when the object is cast |
| 1307 // to boolean. | 1247 // to boolean. |
| 1308 void Interpreter::DoJumpIfToBooleanTrueConstant( | 1248 void Interpreter::DoJumpIfToBooleanTrueConstant( |
| 1309 InterpreterAssembler* assembler) { | 1249 InterpreterAssembler* assembler) { |
| 1310 Callable callable = CodeFactory::ToBoolean(isolate_); | |
| 1311 Node* target = __ HeapConstant(callable.code()); | |
| 1312 Node* accumulator = __ GetAccumulator(); | 1250 Node* accumulator = __ GetAccumulator(); |
| 1313 Node* context = __ GetContext(); | 1251 Node* to_boolean_value = BuildToBoolean(accumulator, assembler); |
| 1314 Node* to_boolean_value = | |
| 1315 __ CallStub(callable.descriptor(), target, context, accumulator); | |
| 1316 Node* index = __ BytecodeOperandIdx(0); | 1252 Node* index = __ BytecodeOperandIdx(0); |
| 1317 Node* constant = __ LoadConstantPoolEntry(index); | 1253 Node* constant = __ LoadConstantPoolEntry(index); |
| 1318 Node* relative_jump = __ SmiUntag(constant); | 1254 Node* relative_jump = __ SmiUntag(constant); |
| 1319 Node* true_value = __ BooleanConstant(true); | 1255 Node* true_value = __ BooleanConstant(true); |
| 1320 __ JumpIfWordEqual(to_boolean_value, true_value, relative_jump); | 1256 __ JumpIfWordEqual(to_boolean_value, true_value, relative_jump); |
| 1321 } | 1257 } |
| 1322 | 1258 |
| 1323 // JumpIfToBooleanFalse <imm> | 1259 // JumpIfToBooleanFalse <imm> |
| 1324 // | 1260 // |
| 1325 // Jump by number of bytes represented by an immediate operand if the object | 1261 // Jump by number of bytes represented by an immediate operand if the object |
| 1326 // referenced by the accumulator is false when the object is cast to boolean. | 1262 // referenced by the accumulator is false when the object is cast to boolean. |
| 1327 void Interpreter::DoJumpIfToBooleanFalse(InterpreterAssembler* assembler) { | 1263 void Interpreter::DoJumpIfToBooleanFalse(InterpreterAssembler* assembler) { |
| 1328 Callable callable = CodeFactory::ToBoolean(isolate_); | |
| 1329 Node* target = __ HeapConstant(callable.code()); | |
| 1330 Node* accumulator = __ GetAccumulator(); | 1264 Node* accumulator = __ GetAccumulator(); |
| 1331 Node* context = __ GetContext(); | 1265 Node* to_boolean_value = BuildToBoolean(accumulator, assembler); |
| 1332 Node* to_boolean_value = | |
| 1333 __ CallStub(callable.descriptor(), target, context, accumulator); | |
| 1334 Node* relative_jump = __ BytecodeOperandImm(0); | 1266 Node* relative_jump = __ BytecodeOperandImm(0); |
| 1335 Node* false_value = __ BooleanConstant(false); | 1267 Node* false_value = __ BooleanConstant(false); |
| 1336 __ JumpIfWordEqual(to_boolean_value, false_value, relative_jump); | 1268 __ JumpIfWordEqual(to_boolean_value, false_value, relative_jump); |
| 1337 } | 1269 } |
| 1338 | 1270 |
| 1339 // JumpIfToBooleanFalseConstant <idx> | 1271 // JumpIfToBooleanFalseConstant <idx> |
| 1340 // | 1272 // |
| 1341 // Jump by number of bytes in the Smi in the |idx| entry in the constant pool | 1273 // Jump by number of bytes in the Smi in the |idx| entry in the constant pool |
| 1342 // if the object referenced by the accumulator is false when the object is cast | 1274 // if the object referenced by the accumulator is false when the object is cast |
| 1343 // to boolean. | 1275 // to boolean. |
| 1344 void Interpreter::DoJumpIfToBooleanFalseConstant( | 1276 void Interpreter::DoJumpIfToBooleanFalseConstant( |
| 1345 InterpreterAssembler* assembler) { | 1277 InterpreterAssembler* assembler) { |
| 1346 Callable callable = CodeFactory::ToBoolean(isolate_); | |
| 1347 Node* target = __ HeapConstant(callable.code()); | |
| 1348 Node* accumulator = __ GetAccumulator(); | 1278 Node* accumulator = __ GetAccumulator(); |
| 1349 Node* context = __ GetContext(); | 1279 Node* to_boolean_value = BuildToBoolean(accumulator, assembler); |
| 1350 Node* to_boolean_value = | |
| 1351 __ CallStub(callable.descriptor(), target, context, accumulator); | |
| 1352 Node* index = __ BytecodeOperandIdx(0); | 1280 Node* index = __ BytecodeOperandIdx(0); |
| 1353 Node* constant = __ LoadConstantPoolEntry(index); | 1281 Node* constant = __ LoadConstantPoolEntry(index); |
| 1354 Node* relative_jump = __ SmiUntag(constant); | 1282 Node* relative_jump = __ SmiUntag(constant); |
| 1355 Node* false_value = __ BooleanConstant(false); | 1283 Node* false_value = __ BooleanConstant(false); |
| 1356 __ JumpIfWordEqual(to_boolean_value, false_value, relative_jump); | 1284 __ JumpIfWordEqual(to_boolean_value, false_value, relative_jump); |
| 1357 } | 1285 } |
| 1358 | 1286 |
| 1359 // JumpIfNull <imm> | 1287 // JumpIfNull <imm> |
| 1360 // | 1288 // |
| 1361 // Jump by number of bytes represented by an immediate operand if the object | 1289 // Jump by number of bytes represented by an immediate operand if the object |
| (...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1572 | 1500 |
| 1573 __ Bind(&if_duplicate_parameters); | 1501 __ Bind(&if_duplicate_parameters); |
| 1574 { | 1502 { |
| 1575 Node* result = | 1503 Node* result = |
| 1576 __ CallRuntime(Runtime::kNewSloppyArguments_Generic, context, closure); | 1504 __ CallRuntime(Runtime::kNewSloppyArguments_Generic, context, closure); |
| 1577 __ SetAccumulator(result); | 1505 __ SetAccumulator(result); |
| 1578 __ Dispatch(); | 1506 __ Dispatch(); |
| 1579 } | 1507 } |
| 1580 } | 1508 } |
| 1581 | 1509 |
| 1582 | |
| 1583 // CreateUnmappedArguments | 1510 // CreateUnmappedArguments |
| 1584 // | 1511 // |
| 1585 // Creates a new unmapped arguments object. | 1512 // Creates a new unmapped arguments object. |
| 1586 void Interpreter::DoCreateUnmappedArguments(InterpreterAssembler* assembler) { | 1513 void Interpreter::DoCreateUnmappedArguments(InterpreterAssembler* assembler) { |
| 1587 // TODO(rmcilroy): Inline FastNewStrictArguments when it is a TurboFan stub. | 1514 // TODO(rmcilroy): Inline FastNewStrictArguments when it is a TurboFan stub. |
| 1588 Callable callable = CodeFactory::FastNewStrictArguments(isolate_, true); | 1515 Callable callable = CodeFactory::FastNewStrictArguments(isolate_, true); |
| 1589 Node* target = __ HeapConstant(callable.code()); | 1516 Node* target = __ HeapConstant(callable.code()); |
| 1590 Node* context = __ GetContext(); | 1517 Node* context = __ GetContext(); |
| 1591 Node* closure = __ LoadRegister(Register::function_closure()); | 1518 Node* closure = __ LoadRegister(Register::function_closure()); |
| 1592 Node* result = __ CallStub(callable.descriptor(), target, context, closure); | 1519 Node* result = __ CallStub(callable.descriptor(), target, context, closure); |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1632 // | 1559 // |
| 1633 // Throws the exception in the accumulator. | 1560 // Throws the exception in the accumulator. |
| 1634 void Interpreter::DoThrow(InterpreterAssembler* assembler) { | 1561 void Interpreter::DoThrow(InterpreterAssembler* assembler) { |
| 1635 Node* exception = __ GetAccumulator(); | 1562 Node* exception = __ GetAccumulator(); |
| 1636 Node* context = __ GetContext(); | 1563 Node* context = __ GetContext(); |
| 1637 __ CallRuntime(Runtime::kThrow, context, exception); | 1564 __ CallRuntime(Runtime::kThrow, context, exception); |
| 1638 // We shouldn't ever return from a throw. | 1565 // We shouldn't ever return from a throw. |
| 1639 __ Abort(kUnexpectedReturnFromThrow); | 1566 __ Abort(kUnexpectedReturnFromThrow); |
| 1640 } | 1567 } |
| 1641 | 1568 |
| 1642 | |
| 1643 // ReThrow | 1569 // ReThrow |
| 1644 // | 1570 // |
| 1645 // Re-throws the exception in the accumulator. | 1571 // Re-throws the exception in the accumulator. |
| 1646 void Interpreter::DoReThrow(InterpreterAssembler* assembler) { | 1572 void Interpreter::DoReThrow(InterpreterAssembler* assembler) { |
| 1647 Node* exception = __ GetAccumulator(); | 1573 Node* exception = __ GetAccumulator(); |
| 1648 Node* context = __ GetContext(); | 1574 Node* context = __ GetContext(); |
| 1649 __ CallRuntime(Runtime::kReThrow, context, exception); | 1575 __ CallRuntime(Runtime::kReThrow, context, exception); |
| 1650 // We shouldn't ever return from a throw. | 1576 // We shouldn't ever return from a throw. |
| 1651 __ Abort(kUnexpectedReturnFromThrow); | 1577 __ Abort(kUnexpectedReturnFromThrow); |
| 1652 } | 1578 } |
| 1653 | 1579 |
| 1654 | |
| 1655 // Return | 1580 // Return |
| 1656 // | 1581 // |
| 1657 // Return the value in the accumulator. | 1582 // Return the value in the accumulator. |
| 1658 void Interpreter::DoReturn(InterpreterAssembler* assembler) { | 1583 void Interpreter::DoReturn(InterpreterAssembler* assembler) { |
| 1659 __ UpdateInterruptBudgetOnReturn(); | 1584 __ UpdateInterruptBudgetOnReturn(); |
| 1660 Node* accumulator = __ GetAccumulator(); | 1585 Node* accumulator = __ GetAccumulator(); |
| 1661 __ Return(accumulator); | 1586 __ Return(accumulator); |
| 1662 } | 1587 } |
| 1663 | 1588 |
| 1664 // Debugger | 1589 // Debugger |
| (...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1855 __ StoreObjectField(generator, JSGeneratorObject::kContinuationOffset, | 1780 __ StoreObjectField(generator, JSGeneratorObject::kContinuationOffset, |
| 1856 __ SmiTag(new_state)); | 1781 __ SmiTag(new_state)); |
| 1857 __ SetAccumulator(old_state); | 1782 __ SetAccumulator(old_state); |
| 1858 | 1783 |
| 1859 __ Dispatch(); | 1784 __ Dispatch(); |
| 1860 } | 1785 } |
| 1861 | 1786 |
| 1862 } // namespace interpreter | 1787 } // namespace interpreter |
| 1863 } // namespace internal | 1788 } // namespace internal |
| 1864 } // namespace v8 | 1789 } // namespace v8 |
| OLD | NEW |