| 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 538 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 549 // Create a new closure. | 549 // Create a new closure. |
| 550 __ mov(r0, Operand(boilerplate)); | 550 __ mov(r0, Operand(boilerplate)); |
| 551 __ stm(db_w, sp, cp.bit() | r0.bit()); | 551 __ stm(db_w, sp, cp.bit() | r0.bit()); |
| 552 __ CallRuntime(Runtime::kNewClosure, 2); | 552 __ CallRuntime(Runtime::kNewClosure, 2); |
| 553 Move(expr->context(), r0); | 553 Move(expr->context(), r0); |
| 554 } | 554 } |
| 555 | 555 |
| 556 | 556 |
| 557 void FastCodeGenerator::VisitVariableProxy(VariableProxy* expr) { | 557 void FastCodeGenerator::VisitVariableProxy(VariableProxy* expr) { |
| 558 Comment cmnt(masm_, "[ VariableProxy"); | 558 Comment cmnt(masm_, "[ VariableProxy"); |
| 559 Expression* rewrite = expr->var()->rewrite(); | 559 EmitVariableLoad(expr->var(), expr->context()); |
| 560 } |
| 561 |
| 562 |
| 563 void FastCodeGenerator::EmitVariableLoad(Variable* var, |
| 564 Expression::Context context) { |
| 565 Expression* rewrite = var->rewrite(); |
| 560 if (rewrite == NULL) { | 566 if (rewrite == NULL) { |
| 561 ASSERT(expr->var()->is_global()); | 567 ASSERT(var->is_global()); |
| 562 Comment cmnt(masm_, "Global variable"); | 568 Comment cmnt(masm_, "Global variable"); |
| 563 // Use inline caching. Variable name is passed in r2 and the global | 569 // Use inline caching. Variable name is passed in r2 and the global |
| 564 // object on the stack. | 570 // object on the stack. |
| 565 __ ldr(ip, CodeGenerator::GlobalObject()); | 571 __ ldr(ip, CodeGenerator::GlobalObject()); |
| 566 __ push(ip); | 572 __ push(ip); |
| 567 __ mov(r2, Operand(expr->name())); | 573 __ mov(r2, Operand(var->name())); |
| 568 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); | 574 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); |
| 569 __ Call(ic, RelocInfo::CODE_TARGET_CONTEXT); | 575 __ Call(ic, RelocInfo::CODE_TARGET_CONTEXT); |
| 570 DropAndMove(expr->context(), r0); | 576 DropAndMove(context, r0); |
| 571 } else if (rewrite->AsSlot() != NULL) { | 577 } else if (rewrite->AsSlot() != NULL) { |
| 572 Slot* slot = rewrite->AsSlot(); | 578 Slot* slot = rewrite->AsSlot(); |
| 573 if (FLAG_debug_code) { | 579 if (FLAG_debug_code) { |
| 574 switch (slot->type()) { | 580 switch (slot->type()) { |
| 575 case Slot::LOCAL: | 581 case Slot::LOCAL: |
| 576 case Slot::PARAMETER: { | 582 case Slot::PARAMETER: { |
| 577 Comment cmnt(masm_, "Stack slot"); | 583 Comment cmnt(masm_, "Stack slot"); |
| 578 break; | 584 break; |
| 579 } | 585 } |
| 580 case Slot::CONTEXT: { | 586 case Slot::CONTEXT: { |
| 581 Comment cmnt(masm_, "Context slot"); | 587 Comment cmnt(masm_, "Context slot"); |
| 582 break; | 588 break; |
| 583 } | 589 } |
| 584 case Slot::LOOKUP: | 590 case Slot::LOOKUP: |
| 585 UNIMPLEMENTED(); | 591 UNIMPLEMENTED(); |
| 586 break; | 592 break; |
| 587 default: | 593 default: |
| 588 UNREACHABLE(); | 594 UNREACHABLE(); |
| 589 } | 595 } |
| 590 } | 596 } |
| 591 Move(expr->context(), slot, r0); | 597 Move(context, slot, r0); |
| 592 } else { | 598 } else { |
| 593 // A variable has been rewritten into an explicit access to | 599 // A variable has been rewritten into an explicit access to |
| 594 // an object property. | 600 // an object property. |
| 595 Property* property = rewrite->AsProperty(); | 601 Property* property = rewrite->AsProperty(); |
| 596 ASSERT_NOT_NULL(property); | 602 ASSERT_NOT_NULL(property); |
| 597 | 603 |
| 598 // Currently the only parameter expressions that can occur are | 604 // Currently the only parameter expressions that can occur are |
| 599 // on the form "slot[literal]". | 605 // on the form "slot[literal]". |
| 600 | 606 |
| 601 // Check that the object is in a slot. | 607 // Check that the object is in a slot. |
| (...skipping 14 matching lines...) Expand all Loading... |
| 616 __ mov(r1, Operand(key_literal->handle())); | 622 __ mov(r1, Operand(key_literal->handle())); |
| 617 | 623 |
| 618 // Push both as arguments to ic. | 624 // Push both as arguments to ic. |
| 619 __ stm(db_w, sp, r2.bit() | r1.bit()); | 625 __ stm(db_w, sp, r2.bit() | r1.bit()); |
| 620 | 626 |
| 621 // Do a KEYED property load. | 627 // Do a KEYED property load. |
| 622 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); | 628 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); |
| 623 __ Call(ic, RelocInfo::CODE_TARGET); | 629 __ Call(ic, RelocInfo::CODE_TARGET); |
| 624 | 630 |
| 625 // Drop key and object left on the stack by IC, and push the result. | 631 // Drop key and object left on the stack by IC, and push the result. |
| 626 DropAndMove(expr->context(), r0, 2); | 632 DropAndMove(context, r0, 2); |
| 627 } | 633 } |
| 628 } | 634 } |
| 629 | 635 |
| 630 | 636 |
| 631 void FastCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) { | 637 void FastCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) { |
| 632 Comment cmnt(masm_, "[ RegExpLiteral"); | 638 Comment cmnt(masm_, "[ RegExpLiteral"); |
| 633 Label done; | 639 Label done; |
| 634 // Registers will be used as follows: | 640 // Registers will be used as follows: |
| 635 // r4 = JS function, literals array | 641 // r4 = JS function, literals array |
| 636 // r3 = literal index | 642 // r3 = literal index |
| (...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 839 TestAndBranch(r0, &discard, false_label_); | 845 TestAndBranch(r0, &discard, false_label_); |
| 840 __ bind(&discard); | 846 __ bind(&discard); |
| 841 __ pop(); | 847 __ pop(); |
| 842 __ jmp(true_label_); | 848 __ jmp(true_label_); |
| 843 break; | 849 break; |
| 844 } | 850 } |
| 845 } | 851 } |
| 846 } | 852 } |
| 847 | 853 |
| 848 | 854 |
| 855 void FastCodeGenerator::EmitNamedPropertyLoad(Property* prop, |
| 856 Expression::Context context) { |
| 857 Literal* key = prop->key()->AsLiteral(); |
| 858 __ mov(r2, Operand(key->handle())); |
| 859 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); |
| 860 __ Call(ic, RelocInfo::CODE_TARGET); |
| 861 Move(context, r0); |
| 862 } |
| 863 |
| 864 |
| 865 void FastCodeGenerator::EmitKeyedPropertyLoad(Expression::Context context) { |
| 866 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); |
| 867 __ Call(ic, RelocInfo::CODE_TARGET); |
| 868 Move(context, r0); |
| 869 } |
| 870 |
| 871 |
| 872 void FastCodeGenerator::EmitCompoundAssignmentOp(Token::Value op, |
| 873 Expression::Context context) { |
| 874 __ pop(r0); |
| 875 __ pop(r1); |
| 876 GenericBinaryOpStub stub(op, |
| 877 NO_OVERWRITE); |
| 878 __ CallStub(&stub); |
| 879 Move(context, r0); |
| 880 } |
| 881 |
| 882 |
| 849 void FastCodeGenerator::EmitVariableAssignment(Assignment* expr) { | 883 void FastCodeGenerator::EmitVariableAssignment(Assignment* expr) { |
| 850 Variable* var = expr->target()->AsVariableProxy()->AsVariable(); | 884 Variable* var = expr->target()->AsVariableProxy()->AsVariable(); |
| 851 ASSERT(var != NULL); | 885 ASSERT(var != NULL); |
| 852 ASSERT(var->is_global() || var->slot() != NULL); | 886 ASSERT(var->is_global() || var->slot() != NULL); |
| 853 if (var->is_global()) { | 887 if (var->is_global()) { |
| 854 // Assignment to a global variable. Use inline caching for the | 888 // Assignment to a global variable. Use inline caching for the |
| 855 // assignment. Right-hand-side value is passed in r0, variable name in | 889 // assignment. Right-hand-side value is passed in r0, variable name in |
| 856 // r2, and the global object on the stack. | 890 // r2, and the global object on the stack. |
| 857 __ pop(r0); | 891 __ pop(r0); |
| 858 __ mov(r2, Operand(var->name())); | 892 __ mov(r2, Operand(var->name())); |
| (...skipping 806 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1665 void FastCodeGenerator::VisitThisFunction(ThisFunction* expr) { | 1699 void FastCodeGenerator::VisitThisFunction(ThisFunction* expr) { |
| 1666 __ ldr(r0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); | 1700 __ ldr(r0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); |
| 1667 Move(expr->context(), r0); | 1701 Move(expr->context(), r0); |
| 1668 } | 1702 } |
| 1669 | 1703 |
| 1670 | 1704 |
| 1671 #undef __ | 1705 #undef __ |
| 1672 | 1706 |
| 1673 | 1707 |
| 1674 } } // namespace v8::internal | 1708 } } // namespace v8::internal |
| OLD | NEW |