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