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 531 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
542 // Create a new closure. | 542 // Create a new closure. |
543 __ push(esi); | 543 __ push(esi); |
544 __ push(Immediate(boilerplate)); | 544 __ push(Immediate(boilerplate)); |
545 __ CallRuntime(Runtime::kNewClosure, 2); | 545 __ CallRuntime(Runtime::kNewClosure, 2); |
546 Move(expr->context(), eax); | 546 Move(expr->context(), eax); |
547 } | 547 } |
548 | 548 |
549 | 549 |
550 void FastCodeGenerator::VisitVariableProxy(VariableProxy* expr) { | 550 void FastCodeGenerator::VisitVariableProxy(VariableProxy* expr) { |
551 Comment cmnt(masm_, "[ VariableProxy"); | 551 Comment cmnt(masm_, "[ VariableProxy"); |
552 Expression* rewrite = expr->var()->rewrite(); | 552 EmitVariableLoad(expr->var(), expr->context()); |
| 553 } |
| 554 |
| 555 |
| 556 void FastCodeGenerator::EmitVariableLoad(Variable* var, |
| 557 Expression::Context context) { |
| 558 Expression* rewrite = var->rewrite(); |
553 if (rewrite == NULL) { | 559 if (rewrite == NULL) { |
554 ASSERT(expr->var()->is_global()); | 560 ASSERT(var->is_global()); |
555 Comment cmnt(masm_, "Global variable"); | 561 Comment cmnt(masm_, "Global variable"); |
556 // Use inline caching. Variable name is passed in ecx and the global | 562 // Use inline caching. Variable name is passed in ecx and the global |
557 // object on the stack. | 563 // object on the stack. |
558 __ push(CodeGenerator::GlobalObject()); | 564 __ push(CodeGenerator::GlobalObject()); |
559 __ mov(ecx, expr->name()); | 565 __ mov(ecx, var->name()); |
560 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); | 566 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); |
561 __ call(ic, RelocInfo::CODE_TARGET_CONTEXT); | 567 __ call(ic, RelocInfo::CODE_TARGET_CONTEXT); |
562 // By emitting a nop we make sure that we do not have a test eax | 568 // By emitting a nop we make sure that we do not have a test eax |
563 // instruction after the call it is treated specially by the LoadIC code | 569 // instruction after the call it is treated specially by the LoadIC code |
564 // Remember that the assembler may choose to do peephole optimization | 570 // Remember that the assembler may choose to do peephole optimization |
565 // (eg, push/pop elimination). | 571 // (eg, push/pop elimination). |
566 __ nop(); | 572 __ nop(); |
567 | 573 DropAndMove(context, eax); |
568 DropAndMove(expr->context(), eax); | |
569 } else if (rewrite->AsSlot() != NULL) { | 574 } else if (rewrite->AsSlot() != NULL) { |
570 Slot* slot = rewrite->AsSlot(); | 575 Slot* slot = rewrite->AsSlot(); |
571 if (FLAG_debug_code) { | 576 if (FLAG_debug_code) { |
572 switch (slot->type()) { | 577 switch (slot->type()) { |
573 case Slot::LOCAL: | 578 case Slot::LOCAL: |
574 case Slot::PARAMETER: { | 579 case Slot::PARAMETER: { |
575 Comment cmnt(masm_, "Stack slot"); | 580 Comment cmnt(masm_, "Stack slot"); |
576 break; | 581 break; |
577 } | 582 } |
578 case Slot::CONTEXT: { | 583 case Slot::CONTEXT: { |
579 Comment cmnt(masm_, "Context slot"); | 584 Comment cmnt(masm_, "Context slot"); |
580 break; | 585 break; |
581 } | 586 } |
582 case Slot::LOOKUP: | 587 case Slot::LOOKUP: |
583 UNIMPLEMENTED(); | 588 UNIMPLEMENTED(); |
584 break; | 589 break; |
585 default: | 590 default: |
586 UNREACHABLE(); | 591 UNREACHABLE(); |
587 } | 592 } |
588 } | 593 } |
589 Move(expr->context(), slot, eax); | 594 Move(context, slot, eax); |
590 } else { | 595 } else { |
591 Comment cmnt(masm_, "Variable rewritten to Property"); | 596 Comment cmnt(masm_, "Variable rewritten to Property"); |
592 // A variable has been rewritten into an explicit access to | 597 // A variable has been rewritten into an explicit access to |
593 // an object property. | 598 // an object property. |
594 Property* property = rewrite->AsProperty(); | 599 Property* property = rewrite->AsProperty(); |
595 ASSERT_NOT_NULL(property); | 600 ASSERT_NOT_NULL(property); |
596 | 601 |
597 // Currently the only parameter expressions that can occur are | 602 // Currently the only parameter expressions that can occur are |
598 // on the form "slot[literal]". | 603 // on the form "slot[literal]". |
599 | 604 |
(...skipping 13 matching lines...) Expand all Loading... |
613 | 618 |
614 // Load the key. | 619 // Load the key. |
615 Move(Expression::kValue, key_literal); | 620 Move(Expression::kValue, key_literal); |
616 | 621 |
617 // Do a KEYED property load. | 622 // Do a KEYED property load. |
618 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); | 623 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); |
619 __ call(ic, RelocInfo::CODE_TARGET); | 624 __ call(ic, RelocInfo::CODE_TARGET); |
620 // Notice: We must not have a "test eax, ..." instruction after | 625 // Notice: We must not have a "test eax, ..." instruction after |
621 // the call. It is treated specially by the LoadIC code. | 626 // the call. It is treated specially by the LoadIC code. |
622 __ nop(); | 627 __ nop(); |
623 | 628 // Drop key and object left on the stack by IC. |
624 // Drop key and object left on the stack by IC, and push the result. | 629 DropAndMove(context, eax, 2); |
625 DropAndMove(expr->context(), eax, 2); | |
626 } | 630 } |
627 } | 631 } |
628 | 632 |
629 | 633 |
630 void FastCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) { | 634 void FastCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) { |
631 Comment cmnt(masm_, "[ RegExpLiteral"); | 635 Comment cmnt(masm_, "[ RegExpLiteral"); |
632 Label done; | 636 Label done; |
633 // Registers will be used as follows: | 637 // Registers will be used as follows: |
634 // edi = JS function. | 638 // edi = JS function. |
635 // ebx = literals array. | 639 // ebx = literals array. |
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
829 TestAndBranch(eax, &discard, false_label_); | 833 TestAndBranch(eax, &discard, false_label_); |
830 __ bind(&discard); | 834 __ bind(&discard); |
831 __ add(Operand(esp), Immediate(kPointerSize)); | 835 __ add(Operand(esp), Immediate(kPointerSize)); |
832 __ jmp(true_label_); | 836 __ jmp(true_label_); |
833 break; | 837 break; |
834 } | 838 } |
835 } | 839 } |
836 } | 840 } |
837 | 841 |
838 | 842 |
| 843 void FastCodeGenerator::EmitNamedPropertyLoad(Property* prop, Expression::Contex
t context) { |
| 844 Literal* key = prop->key()->AsLiteral(); |
| 845 __ mov(ecx, Immediate(key->handle())); |
| 846 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); |
| 847 __ call(ic, RelocInfo::CODE_TARGET); |
| 848 Move(context, eax); |
| 849 } |
| 850 |
| 851 |
| 852 void FastCodeGenerator::EmitKeyedPropertyLoad(Expression::Context context) { |
| 853 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); |
| 854 __ call(ic, RelocInfo::CODE_TARGET); |
| 855 Move(context, eax); |
| 856 } |
| 857 |
| 858 |
| 859 void FastCodeGenerator::EmitCompoundAssignmentOp(Token::Value op, |
| 860 Expression::Context context) { |
| 861 GenericBinaryOpStub stub(op, |
| 862 NO_OVERWRITE, |
| 863 NO_GENERIC_BINARY_FLAGS); |
| 864 __ CallStub(&stub); |
| 865 Move(context, eax); |
| 866 } |
| 867 |
| 868 |
839 void FastCodeGenerator::EmitVariableAssignment(Assignment* expr) { | 869 void FastCodeGenerator::EmitVariableAssignment(Assignment* expr) { |
840 Variable* var = expr->target()->AsVariableProxy()->AsVariable(); | 870 Variable* var = expr->target()->AsVariableProxy()->AsVariable(); |
841 ASSERT(var != NULL); | 871 ASSERT(var != NULL); |
842 ASSERT(var->is_global() || var->slot() != NULL); | 872 ASSERT(var->is_global() || var->slot() != NULL); |
843 if (var->is_global()) { | 873 if (var->is_global()) { |
844 // Assignment to a global variable. Use inline caching for the | 874 // Assignment to a global variable. Use inline caching for the |
845 // assignment. Right-hand-side value is passed in eax, variable name in | 875 // assignment. Right-hand-side value is passed in eax, variable name in |
846 // ecx, and the global object on the stack. | 876 // ecx, and the global object on the stack. |
847 __ pop(eax); | 877 __ pop(eax); |
848 __ mov(ecx, var->name()); | 878 __ mov(ecx, var->name()); |
(...skipping 793 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1642 | 1672 |
1643 void FastCodeGenerator::VisitThisFunction(ThisFunction* expr) { | 1673 void FastCodeGenerator::VisitThisFunction(ThisFunction* expr) { |
1644 __ mov(eax, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); | 1674 __ mov(eax, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); |
1645 Move(expr->context(), eax); | 1675 Move(expr->context(), eax); |
1646 } | 1676 } |
1647 | 1677 |
1648 #undef __ | 1678 #undef __ |
1649 | 1679 |
1650 | 1680 |
1651 } } // namespace v8::internal | 1681 } } // namespace v8::internal |
OLD | NEW |