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 |