OLD | NEW |
1 // Copyright 2009 the V8 project authors. All rights reserved. | 1 // Copyright 2009 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 541 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
552 // Create a new closure. | 552 // Create a new closure. |
553 __ push(rsi); | 553 __ push(rsi); |
554 __ Push(boilerplate); | 554 __ Push(boilerplate); |
555 __ CallRuntime(Runtime::kNewClosure, 2); | 555 __ CallRuntime(Runtime::kNewClosure, 2); |
556 Move(expr->context(), rax); | 556 Move(expr->context(), rax); |
557 } | 557 } |
558 | 558 |
559 | 559 |
560 void FastCodeGenerator::VisitVariableProxy(VariableProxy* expr) { | 560 void FastCodeGenerator::VisitVariableProxy(VariableProxy* expr) { |
561 Comment cmnt(masm_, "[ VariableProxy"); | 561 Comment cmnt(masm_, "[ VariableProxy"); |
562 Expression* rewrite = expr->var()->rewrite(); | 562 EmitVariableLoad(expr->var(), expr->context()); |
| 563 } |
| 564 |
| 565 |
| 566 void FastCodeGenerator::EmitVariableLoad(Variable* var, |
| 567 Expression::Context context) { |
| 568 Expression* rewrite = var->rewrite(); |
563 if (rewrite == NULL) { | 569 if (rewrite == NULL) { |
564 ASSERT(expr->var()->is_global()); | 570 ASSERT(var->is_global()); |
565 Comment cmnt(masm_, "Global variable"); | 571 Comment cmnt(masm_, "Global variable"); |
566 // Use inline caching. Variable name is passed in rcx and the global | 572 // Use inline caching. Variable name is passed in rcx and the global |
567 // object on the stack. | 573 // object on the stack. |
568 __ push(CodeGenerator::GlobalObject()); | 574 __ push(CodeGenerator::GlobalObject()); |
569 __ Move(rcx, expr->name()); | 575 __ Move(rcx, var->name()); |
570 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); | 576 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); |
571 __ Call(ic, RelocInfo::CODE_TARGET_CONTEXT); | 577 __ Call(ic, RelocInfo::CODE_TARGET_CONTEXT); |
572 // A test rax instruction following the call is used by the IC to | 578 // A test rax instruction following the call is used by the IC to |
573 // indicate that the inobject property case was inlined. Ensure there | 579 // indicate that the inobject property case was inlined. Ensure there |
574 // is no test rax instruction here. | 580 // is no test rax instruction here. |
575 __ nop(); | 581 __ nop(); |
576 | 582 |
577 DropAndMove(expr->context(), rax); | 583 DropAndMove(context, rax); |
578 } else if (rewrite->AsSlot() != NULL) { | 584 } else if (rewrite->AsSlot() != NULL) { |
579 Slot* slot = rewrite->AsSlot(); | 585 Slot* slot = rewrite->AsSlot(); |
580 if (FLAG_debug_code) { | 586 if (FLAG_debug_code) { |
581 switch (slot->type()) { | 587 switch (slot->type()) { |
582 case Slot::LOCAL: | 588 case Slot::LOCAL: |
583 case Slot::PARAMETER: { | 589 case Slot::PARAMETER: { |
584 Comment cmnt(masm_, "Stack slot"); | 590 Comment cmnt(masm_, "Stack slot"); |
585 break; | 591 break; |
586 } | 592 } |
587 case Slot::CONTEXT: { | 593 case Slot::CONTEXT: { |
588 Comment cmnt(masm_, "Context slot"); | 594 Comment cmnt(masm_, "Context slot"); |
589 break; | 595 break; |
590 } | 596 } |
591 case Slot::LOOKUP: | 597 case Slot::LOOKUP: |
592 UNIMPLEMENTED(); | 598 UNIMPLEMENTED(); |
593 break; | 599 break; |
594 default: | 600 default: |
595 UNREACHABLE(); | 601 UNREACHABLE(); |
596 } | 602 } |
597 } | 603 } |
598 Move(expr->context(), slot, rax); | 604 Move(context, slot, rax); |
599 } else { | 605 } else { |
600 // A variable has been rewritten into an explicit access to | 606 // A variable has been rewritten into an explicit access to |
601 // an object property. | 607 // an object property. |
602 Property* property = rewrite->AsProperty(); | 608 Property* property = rewrite->AsProperty(); |
603 ASSERT_NOT_NULL(property); | 609 ASSERT_NOT_NULL(property); |
604 | 610 |
605 // Currently the only parameter expressions that can occur are | 611 // Currently the only parameter expressions that can occur are |
606 // on the form "slot[literal]". | 612 // on the form "slot[literal]". |
607 | 613 |
608 // Check that the object is in a slot. | 614 // Check that the object is in a slot. |
(...skipping 13 matching lines...) Expand all Loading... |
622 // Load the key. | 628 // Load the key. |
623 Move(Expression::kValue, key_literal); | 629 Move(Expression::kValue, key_literal); |
624 | 630 |
625 // Do a KEYED property load. | 631 // Do a KEYED property load. |
626 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); | 632 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); |
627 __ call(ic, RelocInfo::CODE_TARGET); | 633 __ call(ic, RelocInfo::CODE_TARGET); |
628 // Notice: We must not have a "test rax, ..." instruction after | 634 // Notice: We must not have a "test rax, ..." instruction after |
629 // the call. It is treated specially by the LoadIC code. | 635 // the call. It is treated specially by the LoadIC code. |
630 | 636 |
631 // Drop key and object left on the stack by IC, and push the result. | 637 // Drop key and object left on the stack by IC, and push the result. |
632 DropAndMove(expr->context(), rax, 2); | 638 DropAndMove(context, rax, 2); |
633 } | 639 } |
634 } | 640 } |
635 | 641 |
636 | 642 |
637 void FastCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) { | 643 void FastCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) { |
638 Comment cmnt(masm_, "[ RegExpLiteral"); | 644 Comment cmnt(masm_, "[ RegExpLiteral"); |
639 Label done; | 645 Label done; |
640 // Registers will be used as follows: | 646 // Registers will be used as follows: |
641 // rdi = JS function. | 647 // rdi = JS function. |
642 // rbx = literals array. | 648 // rbx = literals array. |
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
836 TestAndBranch(rax, &discard, false_label_); | 842 TestAndBranch(rax, &discard, false_label_); |
837 __ bind(&discard); | 843 __ bind(&discard); |
838 __ addq(rsp, Immediate(kPointerSize)); | 844 __ addq(rsp, Immediate(kPointerSize)); |
839 __ jmp(true_label_); | 845 __ jmp(true_label_); |
840 break; | 846 break; |
841 } | 847 } |
842 } | 848 } |
843 } | 849 } |
844 | 850 |
845 | 851 |
| 852 void FastCodeGenerator::EmitNamedPropertyLoad(Property* prop, |
| 853 Expression::Context context) { |
| 854 Literal* key = prop->key()->AsLiteral(); |
| 855 __ Move(rcx, key->handle()); |
| 856 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); |
| 857 __ Call(ic, RelocInfo::CODE_TARGET); |
| 858 Move(context, rax); |
| 859 } |
| 860 |
| 861 |
| 862 void FastCodeGenerator::EmitKeyedPropertyLoad(Expression::Context context) { |
| 863 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); |
| 864 __ Call(ic, RelocInfo::CODE_TARGET); |
| 865 Move(context, rax); |
| 866 } |
| 867 |
| 868 |
| 869 void FastCodeGenerator::EmitCompoundAssignmentOp(Token::Value op, |
| 870 Expression::Context context) { |
| 871 GenericBinaryOpStub stub(op, |
| 872 NO_OVERWRITE, |
| 873 NO_GENERIC_BINARY_FLAGS); |
| 874 __ CallStub(&stub); |
| 875 Move(context, rax); |
| 876 } |
| 877 |
| 878 |
846 void FastCodeGenerator::EmitVariableAssignment(Assignment* expr) { | 879 void FastCodeGenerator::EmitVariableAssignment(Assignment* expr) { |
847 Variable* var = expr->target()->AsVariableProxy()->AsVariable(); | 880 Variable* var = expr->target()->AsVariableProxy()->AsVariable(); |
848 ASSERT(var != NULL); | 881 ASSERT(var != NULL); |
849 ASSERT(var->is_global() || var->slot() != NULL); | 882 ASSERT(var->is_global() || var->slot() != NULL); |
850 if (var->is_global()) { | 883 if (var->is_global()) { |
851 // Assignment to a global variable. Use inline caching for the | 884 // Assignment to a global variable. Use inline caching for the |
852 // assignment. Right-hand-side value is passed in rax, variable name in | 885 // assignment. Right-hand-side value is passed in rax, variable name in |
853 // rcx, and the global object on the stack. | 886 // rcx, and the global object on the stack. |
854 __ pop(rax); | 887 __ pop(rax); |
855 __ Move(rcx, var->name()); | 888 __ Move(rcx, var->name()); |
(...skipping 791 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1647 void FastCodeGenerator::VisitThisFunction(ThisFunction* expr) { | 1680 void FastCodeGenerator::VisitThisFunction(ThisFunction* expr) { |
1648 __ movq(rax, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset)); | 1681 __ movq(rax, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset)); |
1649 Move(expr->context(), rax); | 1682 Move(expr->context(), rax); |
1650 } | 1683 } |
1651 | 1684 |
1652 | 1685 |
1653 #undef __ | 1686 #undef __ |
1654 | 1687 |
1655 | 1688 |
1656 } } // namespace v8::internal | 1689 } } // namespace v8::internal |
OLD | NEW |