OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/code-stubs.h" | 5 #include "src/code-stubs.h" |
6 | 6 |
7 #include <sstream> | 7 #include <sstream> |
8 | 8 |
9 #include "src/bootstrapper.h" | 9 #include "src/bootstrapper.h" |
10 #include "src/code-factory.h" | 10 #include "src/code-factory.h" |
(...skipping 2749 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2760 void StringGreaterThanStub::GenerateAssembly( | 2760 void StringGreaterThanStub::GenerateAssembly( |
2761 compiler::CodeStubAssembler* assembler) const { | 2761 compiler::CodeStubAssembler* assembler) const { |
2762 GenerateStringRelationalComparison(assembler, kGreaterThan); | 2762 GenerateStringRelationalComparison(assembler, kGreaterThan); |
2763 } | 2763 } |
2764 | 2764 |
2765 void StringGreaterThanOrEqualStub::GenerateAssembly( | 2765 void StringGreaterThanOrEqualStub::GenerateAssembly( |
2766 compiler::CodeStubAssembler* assembler) const { | 2766 compiler::CodeStubAssembler* assembler) const { |
2767 GenerateStringRelationalComparison(assembler, kGreaterThanOrEqual); | 2767 GenerateStringRelationalComparison(assembler, kGreaterThanOrEqual); |
2768 } | 2768 } |
2769 | 2769 |
| 2770 void ToLengthStub::GenerateAssembly( |
| 2771 compiler::CodeStubAssembler* assembler) const { |
| 2772 typedef compiler::CodeStubAssembler::Label Label; |
| 2773 typedef compiler::Node Node; |
| 2774 typedef compiler::CodeStubAssembler::Variable Variable; |
| 2775 |
| 2776 Node* context = assembler->Parameter(1); |
| 2777 |
| 2778 // We might need to loop once for ToNumber conversion. |
| 2779 Variable var_len(assembler, MachineRepresentation::kTagged); |
| 2780 Label loop(assembler, &var_len); |
| 2781 var_len.Bind(assembler->Parameter(0)); |
| 2782 assembler->Goto(&loop); |
| 2783 assembler->Bind(&loop); |
| 2784 { |
| 2785 // Shared entry points. |
| 2786 Label return_len(assembler), |
| 2787 return_two53minus1(assembler, Label::kDeferred), |
| 2788 return_zero(assembler, Label::kDeferred); |
| 2789 |
| 2790 // Load the current {len} value. |
| 2791 Node* len = var_len.value(); |
| 2792 |
| 2793 // Check if {len} is a positive Smi. |
| 2794 assembler->GotoIf(assembler->WordIsPositiveSmi(len), &return_len); |
| 2795 |
| 2796 // Check if {len} is a (negative) Smi. |
| 2797 assembler->GotoIf(assembler->WordIsSmi(len), &return_zero); |
| 2798 |
| 2799 // Check if {len} is a HeapNumber. |
| 2800 Label if_lenisheapnumber(assembler), |
| 2801 if_lenisnotheapnumber(assembler, Label::kDeferred); |
| 2802 assembler->Branch(assembler->WordEqual(assembler->LoadMap(len), |
| 2803 assembler->HeapNumberMapConstant()), |
| 2804 &if_lenisheapnumber, &if_lenisnotheapnumber); |
| 2805 |
| 2806 assembler->Bind(&if_lenisheapnumber); |
| 2807 { |
| 2808 // Load the floating-point value of {len}. |
| 2809 Node* len_value = assembler->LoadHeapNumberValue(len); |
| 2810 |
| 2811 // Check if {len} is not greater than zero. |
| 2812 assembler->GotoUnless(assembler->Float64GreaterThan( |
| 2813 len_value, assembler->Float64Constant(0.0)), |
| 2814 &return_zero); |
| 2815 |
| 2816 // Check if {len} is greater than or equal to 2^53-1. |
| 2817 assembler->GotoIf( |
| 2818 assembler->Float64GreaterThanOrEqual( |
| 2819 len_value, assembler->Float64Constant(kMaxSafeInteger)), |
| 2820 &return_two53minus1); |
| 2821 |
| 2822 // Round the {len} towards -Infinity. |
| 2823 Node* value = assembler->Float64Floor(len_value); |
| 2824 Node* result = assembler->ChangeFloat64ToTagged(value); |
| 2825 assembler->Return(result); |
| 2826 } |
| 2827 |
| 2828 assembler->Bind(&if_lenisnotheapnumber); |
| 2829 { |
| 2830 // Need to convert {len} to a Number first. |
| 2831 Callable callable = CodeFactory::NonNumberToNumber(assembler->isolate()); |
| 2832 var_len.Bind(assembler->CallStub(callable, context, len)); |
| 2833 assembler->Goto(&loop); |
| 2834 } |
| 2835 |
| 2836 assembler->Bind(&return_len); |
| 2837 assembler->Return(var_len.value()); |
| 2838 |
| 2839 assembler->Bind(&return_two53minus1); |
| 2840 assembler->Return(assembler->NumberConstant(kMaxSafeInteger)); |
| 2841 |
| 2842 assembler->Bind(&return_zero); |
| 2843 assembler->Return(assembler->SmiConstant(Smi::FromInt(0))); |
| 2844 } |
| 2845 } |
| 2846 |
2770 void ToBooleanStub::GenerateAssembly( | 2847 void ToBooleanStub::GenerateAssembly( |
2771 compiler::CodeStubAssembler* assembler) const { | 2848 compiler::CodeStubAssembler* assembler) const { |
2772 typedef compiler::Node Node; | 2849 typedef compiler::Node Node; |
2773 typedef compiler::CodeStubAssembler::Label Label; | 2850 typedef compiler::CodeStubAssembler::Label Label; |
2774 | 2851 |
2775 Node* value = assembler->Parameter(0); | 2852 Node* value = assembler->Parameter(0); |
2776 Label if_valueissmi(assembler), if_valueisnotsmi(assembler); | 2853 Label if_valueissmi(assembler), if_valueisnotsmi(assembler); |
2777 | 2854 |
2778 // Check if {value} is a Smi or a HeapObject. | 2855 // Check if {value} is a Smi or a HeapObject. |
2779 assembler->Branch(assembler->WordIsSmi(value), &if_valueissmi, | 2856 assembler->Branch(assembler->WordIsSmi(value), &if_valueissmi, |
(...skipping 595 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3375 if (type->Is(Type::UntaggedPointer())) { | 3452 if (type->Is(Type::UntaggedPointer())) { |
3376 return Representation::External(); | 3453 return Representation::External(); |
3377 } | 3454 } |
3378 | 3455 |
3379 DCHECK(!type->Is(Type::Untagged())); | 3456 DCHECK(!type->Is(Type::Untagged())); |
3380 return Representation::Tagged(); | 3457 return Representation::Tagged(); |
3381 } | 3458 } |
3382 | 3459 |
3383 } // namespace internal | 3460 } // namespace internal |
3384 } // namespace v8 | 3461 } // namespace v8 |
OLD | NEW |