OLD | NEW |
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 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 2601 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2612 __ mov(r2, Operand(r0)); | 2612 __ mov(r2, Operand(r0)); |
2613 | 2613 |
2614 done.Bind(); | 2614 done.Bind(); |
2615 // Push the literal. | 2615 // Push the literal. |
2616 frame_->EmitPush(r2); | 2616 frame_->EmitPush(r2); |
2617 ASSERT(frame_->height() == original_height + 1); | 2617 ASSERT(frame_->height() == original_height + 1); |
2618 } | 2618 } |
2619 | 2619 |
2620 | 2620 |
2621 // This deferred code stub will be used for creating the boilerplate | 2621 // This deferred code stub will be used for creating the boilerplate |
2622 // by calling Runtime_CreateObjectLiteral. | 2622 // by calling Runtime_CreateObjectLiteralBoilerplate. |
2623 // Each created boilerplate is stored in the JSFunction and they are | 2623 // Each created boilerplate is stored in the JSFunction and they are |
2624 // therefore context dependent. | 2624 // therefore context dependent. |
2625 class DeferredObjectLiteral: public DeferredCode { | 2625 class DeferredObjectLiteral: public DeferredCode { |
2626 public: | 2626 public: |
2627 DeferredObjectLiteral(CodeGenerator* generator, ObjectLiteral* node) | 2627 DeferredObjectLiteral(CodeGenerator* generator, ObjectLiteral* node) |
2628 : DeferredCode(generator), node_(node) { | 2628 : DeferredCode(generator), node_(node) { |
2629 set_comment("[ DeferredObjectLiteral"); | 2629 set_comment("[ DeferredObjectLiteral"); |
2630 } | 2630 } |
2631 | 2631 |
2632 virtual void Generate(); | 2632 virtual void Generate(); |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2686 // Check whether we need to materialize the object literal boilerplate. | 2686 // Check whether we need to materialize the object literal boilerplate. |
2687 // If so, jump to the deferred code. | 2687 // If so, jump to the deferred code. |
2688 __ cmp(r2, Operand(Factory::undefined_value())); | 2688 __ cmp(r2, Operand(Factory::undefined_value())); |
2689 deferred->enter()->Branch(eq); | 2689 deferred->enter()->Branch(eq); |
2690 deferred->BindExit(); | 2690 deferred->BindExit(); |
2691 | 2691 |
2692 // Push the object literal boilerplate. | 2692 // Push the object literal boilerplate. |
2693 frame_->EmitPush(r2); | 2693 frame_->EmitPush(r2); |
2694 | 2694 |
2695 // Clone the boilerplate object. | 2695 // Clone the boilerplate object. |
2696 frame_->CallRuntime(Runtime::kCloneObjectLiteralBoilerplate, 1); | 2696 frame_->CallRuntime(Runtime::kCloneLiteralBoilerplate, 1); |
2697 frame_->EmitPush(r0); // save the result | 2697 frame_->EmitPush(r0); // save the result |
2698 // r0: cloned object literal | 2698 // r0: cloned object literal |
2699 | 2699 |
2700 for (int i = 0; i < node->properties()->length(); i++) { | 2700 for (int i = 0; i < node->properties()->length(); i++) { |
2701 ObjectLiteral::Property* property = node->properties()->at(i); | 2701 ObjectLiteral::Property* property = node->properties()->at(i); |
2702 Literal* key = property->key(); | 2702 Literal* key = property->key(); |
2703 Expression* value = property->value(); | 2703 Expression* value = property->value(); |
2704 switch (property->kind()) { | 2704 switch (property->kind()) { |
2705 case ObjectLiteral::Property::CONSTANT: break; | 2705 case ObjectLiteral::Property::CONSTANT: |
2706 case ObjectLiteral::Property::OBJECT_LITERAL: | 2706 break; |
2707 if (property->value()->AsObjectLiteral()->is_simple()) break; | 2707 case ObjectLiteral::Property::MATERIALIZED_LITERAL: |
| 2708 if (property->value()->AsMaterializedLiteral()->is_simple()) break; |
| 2709 // else fall through |
2708 case ObjectLiteral::Property::COMPUTED: // fall through | 2710 case ObjectLiteral::Property::COMPUTED: // fall through |
2709 case ObjectLiteral::Property::PROTOTYPE: { | 2711 case ObjectLiteral::Property::PROTOTYPE: { |
2710 frame_->EmitPush(r0); // dup the result | 2712 frame_->EmitPush(r0); // dup the result |
2711 LoadAndSpill(key); | 2713 LoadAndSpill(key); |
2712 LoadAndSpill(value); | 2714 LoadAndSpill(value); |
2713 frame_->CallRuntime(Runtime::kSetProperty, 3); | 2715 frame_->CallRuntime(Runtime::kSetProperty, 3); |
2714 // restore r0 | 2716 // restore r0 |
2715 __ ldr(r0, frame_->Top()); | 2717 __ ldr(r0, frame_->Top()); |
2716 break; | 2718 break; |
2717 } | 2719 } |
(...skipping 16 matching lines...) Expand all Loading... |
2734 frame_->CallRuntime(Runtime::kDefineAccessor, 4); | 2736 frame_->CallRuntime(Runtime::kDefineAccessor, 4); |
2735 __ ldr(r0, frame_->Top()); | 2737 __ ldr(r0, frame_->Top()); |
2736 break; | 2738 break; |
2737 } | 2739 } |
2738 } | 2740 } |
2739 } | 2741 } |
2740 ASSERT(frame_->height() == original_height + 1); | 2742 ASSERT(frame_->height() == original_height + 1); |
2741 } | 2743 } |
2742 | 2744 |
2743 | 2745 |
| 2746 // This deferred code stub will be used for creating the boilerplate |
| 2747 // by calling Runtime_CreateArrayLiteralBoilerplate. |
| 2748 // Each created boilerplate is stored in the JSFunction and they are |
| 2749 // therefore context dependent. |
| 2750 class DeferredArrayLiteral: public DeferredCode { |
| 2751 public: |
| 2752 DeferredArrayLiteral(CodeGenerator* generator, ArrayLiteral* node) |
| 2753 : DeferredCode(generator), node_(node) { |
| 2754 set_comment("[ DeferredArrayLiteral"); |
| 2755 } |
| 2756 |
| 2757 virtual void Generate(); |
| 2758 |
| 2759 private: |
| 2760 ArrayLiteral* node_; |
| 2761 }; |
| 2762 |
| 2763 |
| 2764 void DeferredArrayLiteral::Generate() { |
| 2765 // Argument is passed in r1. |
| 2766 enter()->Bind(); |
| 2767 VirtualFrame::SpilledScope spilled_scope(generator()); |
| 2768 |
| 2769 // If the entry is undefined we call the runtime system to computed |
| 2770 // the literal. |
| 2771 |
| 2772 VirtualFrame* frame = generator()->frame(); |
| 2773 // Literal array (0). |
| 2774 frame->EmitPush(r1); |
| 2775 // Literal index (1). |
| 2776 __ mov(r0, Operand(Smi::FromInt(node_->literal_index()))); |
| 2777 frame->EmitPush(r0); |
| 2778 // Constant properties (2). |
| 2779 __ mov(r0, Operand(node_->literals())); |
| 2780 frame->EmitPush(r0); |
| 2781 Result boilerplate = |
| 2782 frame->CallRuntime(Runtime::kCreateArrayLiteralBoilerplate, 3); |
| 2783 __ mov(r2, Operand(boilerplate.reg())); |
| 2784 // Result is returned in r2. |
| 2785 exit_.Jump(); |
| 2786 } |
| 2787 |
| 2788 |
2744 void CodeGenerator::VisitArrayLiteral(ArrayLiteral* node) { | 2789 void CodeGenerator::VisitArrayLiteral(ArrayLiteral* node) { |
2745 #ifdef DEBUG | 2790 #ifdef DEBUG |
2746 int original_height = frame_->height(); | 2791 int original_height = frame_->height(); |
2747 #endif | 2792 #endif |
2748 VirtualFrame::SpilledScope spilled_scope(this); | 2793 VirtualFrame::SpilledScope spilled_scope(this); |
2749 Comment cmnt(masm_, "[ ArrayLiteral"); | 2794 Comment cmnt(masm_, "[ ArrayLiteral"); |
2750 | 2795 |
2751 // Call runtime to create the array literal. | 2796 DeferredArrayLiteral* deferred = new DeferredArrayLiteral(this, node); |
2752 __ mov(r0, Operand(node->literals())); | |
2753 frame_->EmitPush(r0); | |
2754 // Load the function of this frame. | |
2755 __ ldr(r0, frame_->Function()); | |
2756 __ ldr(r0, FieldMemOperand(r0, JSFunction::kLiteralsOffset)); | |
2757 frame_->EmitPush(r0); | |
2758 frame_->CallRuntime(Runtime::kCreateArrayLiteral, 2); | |
2759 | 2797 |
2760 // Push the resulting array literal on the stack. | 2798 // Retrieve the literal array and check the allocated entry. |
2761 frame_->EmitPush(r0); | 2799 |
| 2800 // Load the function of this activation. |
| 2801 __ ldr(r1, frame_->Function()); |
| 2802 |
| 2803 // Load the literals array of the function. |
| 2804 __ ldr(r1, FieldMemOperand(r1, JSFunction::kLiteralsOffset)); |
| 2805 |
| 2806 // Load the literal at the ast saved index. |
| 2807 int literal_offset = |
| 2808 FixedArray::kHeaderSize + node->literal_index() * kPointerSize; |
| 2809 __ ldr(r2, FieldMemOperand(r1, literal_offset)); |
| 2810 |
| 2811 // Check whether we need to materialize the object literal boilerplate. |
| 2812 // If so, jump to the deferred code. |
| 2813 __ cmp(r2, Operand(Factory::undefined_value())); |
| 2814 deferred->enter()->Branch(eq); |
| 2815 deferred->BindExit(); |
| 2816 |
| 2817 // Push the object literal boilerplate. |
| 2818 frame_->EmitPush(r2); |
| 2819 |
| 2820 // Clone the boilerplate object. |
| 2821 frame_->CallRuntime(Runtime::kCloneLiteralBoilerplate, 1); |
| 2822 frame_->EmitPush(r0); // save the result |
| 2823 // r0: cloned object literal |
2762 | 2824 |
2763 // Generate code to set the elements in the array that are not | 2825 // Generate code to set the elements in the array that are not |
2764 // literals. | 2826 // literals. |
2765 for (int i = 0; i < node->values()->length(); i++) { | 2827 for (int i = 0; i < node->values()->length(); i++) { |
2766 Expression* value = node->values()->at(i); | 2828 Expression* value = node->values()->at(i); |
2767 | 2829 |
2768 // If value is literal the property value is already | 2830 // If value is literal the property value is already |
2769 // set in the boilerplate object. | 2831 // set in the boilerplate object. |
2770 if (value->AsLiteral() == NULL) { | 2832 if (value->AsLiteral() == NULL) { |
2771 // The property must be set by generated code. | 2833 // The property must be set by generated code. |
(...skipping 2323 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5095 __ mov(r2, Operand(0)); | 5157 __ mov(r2, Operand(0)); |
5096 __ GetBuiltinEntry(r3, Builtins::CALL_NON_FUNCTION); | 5158 __ GetBuiltinEntry(r3, Builtins::CALL_NON_FUNCTION); |
5097 __ Jump(Handle<Code>(Builtins::builtin(Builtins::ArgumentsAdaptorTrampoline)), | 5159 __ Jump(Handle<Code>(Builtins::builtin(Builtins::ArgumentsAdaptorTrampoline)), |
5098 RelocInfo::CODE_TARGET); | 5160 RelocInfo::CODE_TARGET); |
5099 } | 5161 } |
5100 | 5162 |
5101 | 5163 |
5102 #undef __ | 5164 #undef __ |
5103 | 5165 |
5104 } } // namespace v8::internal | 5166 } } // namespace v8::internal |
OLD | NEW |