| 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 |