OLD | NEW |
1 // Copyright 2006-2009 the V8 project authors. All rights reserved. | 1 // Copyright 2006-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 2583 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2594 frame_->CallRuntime(Runtime::kMaterializeRegExpLiteral, 4); | 2594 frame_->CallRuntime(Runtime::kMaterializeRegExpLiteral, 4); |
2595 __ mov(r2, Operand(r0)); | 2595 __ mov(r2, Operand(r0)); |
2596 | 2596 |
2597 done.Bind(); | 2597 done.Bind(); |
2598 // Push the literal. | 2598 // Push the literal. |
2599 frame_->EmitPush(r2); | 2599 frame_->EmitPush(r2); |
2600 ASSERT(frame_->height() == original_height + 1); | 2600 ASSERT(frame_->height() == original_height + 1); |
2601 } | 2601 } |
2602 | 2602 |
2603 | 2603 |
2604 // This deferred code stub will be used for creating the boilerplate | |
2605 // by calling Runtime_CreateObjectLiteralBoilerplate. | |
2606 // Each created boilerplate is stored in the JSFunction and they are | |
2607 // therefore context dependent. | |
2608 class DeferredObjectLiteral: public DeferredCode { | |
2609 public: | |
2610 explicit DeferredObjectLiteral(ObjectLiteral* node) : node_(node) { | |
2611 set_comment("[ DeferredObjectLiteral"); | |
2612 } | |
2613 | |
2614 virtual void Generate(); | |
2615 | |
2616 private: | |
2617 ObjectLiteral* node_; | |
2618 }; | |
2619 | |
2620 | |
2621 void DeferredObjectLiteral::Generate() { | |
2622 // Argument is passed in r1. | |
2623 | |
2624 // If the entry is undefined we call the runtime system to compute | |
2625 // the literal. | |
2626 // Literal array (0). | |
2627 __ push(r1); | |
2628 // Literal index (1). | |
2629 __ mov(r0, Operand(Smi::FromInt(node_->literal_index()))); | |
2630 __ push(r0); | |
2631 // Constant properties (2). | |
2632 __ mov(r0, Operand(node_->constant_properties())); | |
2633 __ push(r0); | |
2634 __ CallRuntime(Runtime::kCreateObjectLiteralBoilerplate, 3); | |
2635 __ mov(r2, Operand(r0)); | |
2636 // Result is returned in r2. | |
2637 } | |
2638 | |
2639 | |
2640 void CodeGenerator::VisitObjectLiteral(ObjectLiteral* node) { | 2604 void CodeGenerator::VisitObjectLiteral(ObjectLiteral* node) { |
2641 #ifdef DEBUG | 2605 #ifdef DEBUG |
2642 int original_height = frame_->height(); | 2606 int original_height = frame_->height(); |
2643 #endif | 2607 #endif |
2644 VirtualFrame::SpilledScope spilled_scope; | 2608 VirtualFrame::SpilledScope spilled_scope; |
2645 Comment cmnt(masm_, "[ ObjectLiteral"); | 2609 Comment cmnt(masm_, "[ ObjectLiteral"); |
2646 | 2610 |
2647 DeferredObjectLiteral* deferred = new DeferredObjectLiteral(node); | |
2648 | |
2649 // Retrieve the literal array and check the allocated entry. | |
2650 | |
2651 // Load the function of this activation. | 2611 // Load the function of this activation. |
2652 __ ldr(r1, frame_->Function()); | 2612 __ ldr(r2, frame_->Function()); |
2653 | 2613 // Literal array. |
2654 // Load the literals array of the function. | 2614 __ ldr(r2, FieldMemOperand(r2, JSFunction::kLiteralsOffset)); |
2655 __ ldr(r1, FieldMemOperand(r1, JSFunction::kLiteralsOffset)); | 2615 // Literal index. |
2656 | 2616 __ mov(r1, Operand(Smi::FromInt(node->literal_index()))); |
2657 // Load the literal at the ast saved index. | 2617 // Constant properties. |
2658 int literal_offset = | 2618 __ mov(r0, Operand(node->constant_properties())); |
2659 FixedArray::kHeaderSize + node->literal_index() * kPointerSize; | 2619 frame_->EmitPushMultiple(3, r2.bit() | r1.bit() | r0.bit()); |
2660 __ ldr(r2, FieldMemOperand(r1, literal_offset)); | 2620 if (node->depth() > 1) { |
2661 | 2621 frame_->CallRuntime(Runtime::kCreateObjectLiteral, 3); |
2662 // Check whether we need to materialize the object literal boilerplate. | 2622 } else { |
2663 // If so, jump to the deferred code. | 2623 frame_->CallRuntime(Runtime::kCreateObjectLiteralShallow, 3); |
2664 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); | |
2665 __ cmp(r2, Operand(ip)); | |
2666 deferred->Branch(eq); | |
2667 deferred->BindExit(); | |
2668 | |
2669 // Push the object literal boilerplate. | |
2670 frame_->EmitPush(r2); | |
2671 | |
2672 // Clone the boilerplate object. | |
2673 Runtime::FunctionId clone_function_id = Runtime::kCloneLiteralBoilerplate; | |
2674 if (node->depth() == 1) { | |
2675 clone_function_id = Runtime::kCloneShallowLiteralBoilerplate; | |
2676 } | 2624 } |
2677 frame_->CallRuntime(clone_function_id, 1); | |
2678 frame_->EmitPush(r0); // save the result | 2625 frame_->EmitPush(r0); // save the result |
2679 // r0: cloned object literal | 2626 // r0: created object literal |
2680 | 2627 |
2681 for (int i = 0; i < node->properties()->length(); i++) { | 2628 for (int i = 0; i < node->properties()->length(); i++) { |
2682 ObjectLiteral::Property* property = node->properties()->at(i); | 2629 ObjectLiteral::Property* property = node->properties()->at(i); |
2683 Literal* key = property->key(); | 2630 Literal* key = property->key(); |
2684 Expression* value = property->value(); | 2631 Expression* value = property->value(); |
2685 switch (property->kind()) { | 2632 switch (property->kind()) { |
2686 case ObjectLiteral::Property::CONSTANT: | 2633 case ObjectLiteral::Property::CONSTANT: |
2687 break; | 2634 break; |
2688 case ObjectLiteral::Property::MATERIALIZED_LITERAL: | 2635 case ObjectLiteral::Property::MATERIALIZED_LITERAL: |
2689 if (CompileTimeValue::IsCompileTimeValue(property->value())) break; | 2636 if (CompileTimeValue::IsCompileTimeValue(property->value())) break; |
(...skipping 27 matching lines...) Expand all Loading... |
2717 frame_->CallRuntime(Runtime::kDefineAccessor, 4); | 2664 frame_->CallRuntime(Runtime::kDefineAccessor, 4); |
2718 __ ldr(r0, frame_->Top()); | 2665 __ ldr(r0, frame_->Top()); |
2719 break; | 2666 break; |
2720 } | 2667 } |
2721 } | 2668 } |
2722 } | 2669 } |
2723 ASSERT(frame_->height() == original_height + 1); | 2670 ASSERT(frame_->height() == original_height + 1); |
2724 } | 2671 } |
2725 | 2672 |
2726 | 2673 |
2727 // This deferred code stub will be used for creating the boilerplate | |
2728 // by calling Runtime_CreateArrayLiteralBoilerplate. | |
2729 // Each created boilerplate is stored in the JSFunction and they are | |
2730 // therefore context dependent. | |
2731 class DeferredArrayLiteral: public DeferredCode { | |
2732 public: | |
2733 explicit DeferredArrayLiteral(ArrayLiteral* node) : node_(node) { | |
2734 set_comment("[ DeferredArrayLiteral"); | |
2735 } | |
2736 | |
2737 virtual void Generate(); | |
2738 | |
2739 private: | |
2740 ArrayLiteral* node_; | |
2741 }; | |
2742 | |
2743 | |
2744 void DeferredArrayLiteral::Generate() { | |
2745 // Argument is passed in r1. | |
2746 | |
2747 // If the entry is undefined we call the runtime system to computed | |
2748 // the literal. | |
2749 // Literal array (0). | |
2750 __ push(r1); | |
2751 // Literal index (1). | |
2752 __ mov(r0, Operand(Smi::FromInt(node_->literal_index()))); | |
2753 __ push(r0); | |
2754 // Constant properties (2). | |
2755 __ mov(r0, Operand(node_->literals())); | |
2756 __ push(r0); | |
2757 __ CallRuntime(Runtime::kCreateArrayLiteralBoilerplate, 3); | |
2758 __ mov(r2, Operand(r0)); | |
2759 // Result is returned in r2. | |
2760 } | |
2761 | |
2762 | |
2763 void CodeGenerator::VisitArrayLiteral(ArrayLiteral* node) { | 2674 void CodeGenerator::VisitArrayLiteral(ArrayLiteral* node) { |
2764 #ifdef DEBUG | 2675 #ifdef DEBUG |
2765 int original_height = frame_->height(); | 2676 int original_height = frame_->height(); |
2766 #endif | 2677 #endif |
2767 VirtualFrame::SpilledScope spilled_scope; | 2678 VirtualFrame::SpilledScope spilled_scope; |
2768 Comment cmnt(masm_, "[ ArrayLiteral"); | 2679 Comment cmnt(masm_, "[ ArrayLiteral"); |
2769 | 2680 |
2770 DeferredArrayLiteral* deferred = new DeferredArrayLiteral(node); | |
2771 | |
2772 // Retrieve the literal array and check the allocated entry. | |
2773 | |
2774 // Load the function of this activation. | 2681 // Load the function of this activation. |
2775 __ ldr(r1, frame_->Function()); | 2682 __ ldr(r2, frame_->Function()); |
2776 | 2683 // Literals array. |
2777 // Load the literals array of the function. | 2684 __ ldr(r2, FieldMemOperand(r2, JSFunction::kLiteralsOffset)); |
2778 __ ldr(r1, FieldMemOperand(r1, JSFunction::kLiteralsOffset)); | 2685 // Literal index. |
2779 | 2686 __ mov(r1, Operand(Smi::FromInt(node->literal_index()))); |
2780 // Load the literal at the ast saved index. | 2687 // Constant elements. |
2781 int literal_offset = | 2688 __ mov(r0, Operand(node->constant_elements())); |
2782 FixedArray::kHeaderSize + node->literal_index() * kPointerSize; | 2689 frame_->EmitPushMultiple(3, r2.bit() | r1.bit() | r0.bit()); |
2783 __ ldr(r2, FieldMemOperand(r1, literal_offset)); | 2690 if (node->depth() > 1) { |
2784 | 2691 frame_->CallRuntime(Runtime::kCreateArrayLiteral, 3); |
2785 // Check whether we need to materialize the object literal boilerplate. | 2692 } else { |
2786 // If so, jump to the deferred code. | 2693 frame_->CallRuntime(Runtime::kCreateArrayLiteralShallow, 3); |
2787 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); | |
2788 __ cmp(r2, Operand(ip)); | |
2789 deferred->Branch(eq); | |
2790 deferred->BindExit(); | |
2791 | |
2792 // Push the object literal boilerplate. | |
2793 frame_->EmitPush(r2); | |
2794 | |
2795 // Clone the boilerplate object. | |
2796 Runtime::FunctionId clone_function_id = Runtime::kCloneLiteralBoilerplate; | |
2797 if (node->depth() == 1) { | |
2798 clone_function_id = Runtime::kCloneShallowLiteralBoilerplate; | |
2799 } | 2694 } |
2800 frame_->CallRuntime(clone_function_id, 1); | |
2801 frame_->EmitPush(r0); // save the result | 2695 frame_->EmitPush(r0); // save the result |
2802 // r0: cloned object literal | 2696 // r0: created object literal |
2803 | 2697 |
2804 // Generate code to set the elements in the array that are not | 2698 // Generate code to set the elements in the array that are not |
2805 // literals. | 2699 // literals. |
2806 for (int i = 0; i < node->values()->length(); i++) { | 2700 for (int i = 0; i < node->values()->length(); i++) { |
2807 Expression* value = node->values()->at(i); | 2701 Expression* value = node->values()->at(i); |
2808 | 2702 |
2809 // If value is a literal the property value is already set in the | 2703 // If value is a literal the property value is already set in the |
2810 // boilerplate object. | 2704 // boilerplate object. |
2811 if (value->AsLiteral() != NULL) continue; | 2705 if (value->AsLiteral() != NULL) continue; |
2812 // If value is a materialized literal the property value is already set | 2706 // If value is a materialized literal the property value is already set |
(...skipping 3756 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6569 int CompareStub::MinorKey() { | 6463 int CompareStub::MinorKey() { |
6570 // Encode the two parameters in a unique 16 bit value. | 6464 // Encode the two parameters in a unique 16 bit value. |
6571 ASSERT(static_cast<unsigned>(cc_) >> 28 < (1 << 15)); | 6465 ASSERT(static_cast<unsigned>(cc_) >> 28 < (1 << 15)); |
6572 return (static_cast<unsigned>(cc_) >> 27) | (strict_ ? 1 : 0); | 6466 return (static_cast<unsigned>(cc_) >> 27) | (strict_ ? 1 : 0); |
6573 } | 6467 } |
6574 | 6468 |
6575 | 6469 |
6576 #undef __ | 6470 #undef __ |
6577 | 6471 |
6578 } } // namespace v8::internal | 6472 } } // namespace v8::internal |
OLD | NEW |