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 3723 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3734 assembler->Return(var_len.value()); | 3734 assembler->Return(var_len.value()); |
3735 | 3735 |
3736 assembler->Bind(&return_two53minus1); | 3736 assembler->Bind(&return_two53minus1); |
3737 assembler->Return(assembler->NumberConstant(kMaxSafeInteger)); | 3737 assembler->Return(assembler->NumberConstant(kMaxSafeInteger)); |
3738 | 3738 |
3739 assembler->Bind(&return_zero); | 3739 assembler->Bind(&return_zero); |
3740 assembler->Return(assembler->SmiConstant(Smi::FromInt(0))); | 3740 assembler->Return(assembler->SmiConstant(Smi::FromInt(0))); |
3741 } | 3741 } |
3742 } | 3742 } |
3743 | 3743 |
3744 // static | |
3745 compiler::Node* ToBooleanStub::Generate(CodeStubAssembler* assembler, | |
3746 compiler::Node* value, | |
3747 compiler::Node* context) { | |
3748 typedef compiler::Node Node; | |
3749 typedef CodeStubAssembler::Label Label; | |
3750 typedef CodeStubAssembler::Variable Variable; | |
3751 | |
3752 Variable result(assembler, MachineRepresentation::kTagged); | |
3753 Label if_valueissmi(assembler), if_valueisnotsmi(assembler), | |
3754 return_true(assembler), return_false(assembler), end(assembler); | |
3755 | |
3756 // Check if {value} is a Smi or a HeapObject. | |
3757 assembler->Branch(assembler->WordIsSmi(value), &if_valueissmi, | |
3758 &if_valueisnotsmi); | |
3759 | |
3760 assembler->Bind(&if_valueissmi); | |
3761 { | |
3762 // The {value} is a Smi, only need to check against zero. | |
3763 assembler->Branch(assembler->SmiEqual(value, assembler->SmiConstant(0)), | |
3764 &return_false, &return_true); | |
3765 } | |
3766 | |
3767 assembler->Bind(&if_valueisnotsmi); | |
3768 { | |
3769 Label if_valueisstring(assembler), if_valueisnotstring(assembler), | |
3770 if_valueisheapnumber(assembler), if_valueisoddball(assembler), | |
3771 if_valueisother(assembler); | |
3772 | |
3773 // The {value} is a HeapObject, load its map. | |
3774 Node* value_map = assembler->LoadMap(value); | |
3775 | |
3776 // Load the {value}s instance type. | |
3777 Node* value_instance_type = assembler->Load( | |
3778 MachineType::Uint8(), value_map, | |
3779 assembler->IntPtrConstant(Map::kInstanceTypeOffset - kHeapObjectTag)); | |
3780 | |
3781 // Dispatch based on the instance type; we distinguish all String instance | |
3782 // types, the HeapNumber type and the Oddball type. | |
3783 assembler->Branch(assembler->Int32LessThan( | |
3784 value_instance_type, | |
3785 assembler->Int32Constant(FIRST_NONSTRING_TYPE)), | |
3786 &if_valueisstring, &if_valueisnotstring); | |
3787 assembler->Bind(&if_valueisnotstring); | |
3788 size_t const kNumCases = 2; | |
3789 Label* case_labels[kNumCases]; | |
3790 int32_t case_values[kNumCases]; | |
3791 case_labels[0] = &if_valueisheapnumber; | |
3792 case_values[0] = HEAP_NUMBER_TYPE; | |
3793 case_labels[1] = &if_valueisoddball; | |
3794 case_values[1] = ODDBALL_TYPE; | |
3795 assembler->Switch(value_instance_type, &if_valueisother, case_values, | |
3796 case_labels, arraysize(case_values)); | |
3797 | |
3798 assembler->Bind(&if_valueisstring); | |
3799 { | |
3800 // Load the string length field of the {value}. | |
3801 Node* value_length = | |
3802 assembler->LoadObjectField(value, String::kLengthOffset); | |
3803 | |
3804 // Check if the {value} is the empty string. | |
3805 assembler->Branch( | |
3806 assembler->SmiEqual(value_length, assembler->SmiConstant(0)), | |
3807 &return_false, &return_true); | |
3808 } | |
3809 | |
3810 assembler->Bind(&if_valueisheapnumber); | |
3811 { | |
3812 Node* value_value = assembler->Load( | |
3813 MachineType::Float64(), value, | |
3814 assembler->IntPtrConstant(HeapNumber::kValueOffset - kHeapObjectTag)); | |
3815 | |
3816 Label if_valueisnotpositive(assembler); | |
3817 assembler->Branch(assembler->Float64LessThan( | |
3818 assembler->Float64Constant(0.0), value_value), | |
3819 &return_true, &if_valueisnotpositive); | |
3820 | |
3821 assembler->Bind(&if_valueisnotpositive); | |
3822 assembler->Branch(assembler->Float64LessThan( | |
3823 value_value, assembler->Float64Constant(0.0)), | |
3824 &return_true, &return_false); | |
3825 } | |
3826 | |
3827 assembler->Bind(&if_valueisoddball); | |
3828 { | |
3829 // The {value} is an Oddball, and every Oddball knows its boolean value. | |
3830 Node* value_toboolean = | |
3831 assembler->LoadObjectField(value, Oddball::kToBooleanOffset); | |
3832 result.Bind(value_toboolean); | |
3833 assembler->Goto(&end); | |
3834 } | |
3835 | |
3836 assembler->Bind(&if_valueisother); | |
3837 { | |
3838 Node* value_map_bitfield = assembler->Load( | |
3839 MachineType::Uint8(), value_map, | |
3840 assembler->IntPtrConstant(Map::kBitFieldOffset - kHeapObjectTag)); | |
3841 Node* value_map_undetectable = assembler->Word32And( | |
3842 value_map_bitfield, | |
3843 assembler->Int32Constant(1 << Map::kIsUndetectable)); | |
3844 | |
3845 // Check if the {value} is undetectable. | |
3846 assembler->Branch(assembler->Word32Equal(value_map_undetectable, | |
3847 assembler->Int32Constant(0)), | |
3848 &return_true, &return_false); | |
3849 } | |
3850 } | |
3851 | |
3852 assembler->Bind(&return_false); | |
3853 { | |
3854 result.Bind(assembler->BooleanConstant(false)); | |
3855 assembler->Goto(&end); | |
3856 } | |
3857 | |
3858 assembler->Bind(&return_true); | |
3859 { | |
3860 result.Bind(assembler->BooleanConstant(true)); | |
3861 assembler->Goto(&end); | |
3862 } | |
3863 | |
3864 assembler->Bind(&end); | |
3865 return result.value(); | |
3866 } | |
3867 | |
3868 void ToIntegerStub::GenerateAssembly(CodeStubAssembler* assembler) const { | 3744 void ToIntegerStub::GenerateAssembly(CodeStubAssembler* assembler) const { |
3869 typedef CodeStubAssembler::Label Label; | 3745 typedef CodeStubAssembler::Label Label; |
3870 typedef compiler::Node Node; | 3746 typedef compiler::Node Node; |
3871 typedef CodeStubAssembler::Variable Variable; | 3747 typedef CodeStubAssembler::Variable Variable; |
3872 | 3748 |
3873 Node* context = assembler->Parameter(1); | 3749 Node* context = assembler->Parameter(1); |
3874 | 3750 |
3875 // We might need to loop once for ToNumber conversion. | 3751 // We might need to loop once for ToNumber conversion. |
3876 Variable var_arg(assembler, MachineRepresentation::kTagged); | 3752 Variable var_arg(assembler, MachineRepresentation::kTagged); |
3877 Label loop(assembler, &var_arg); | 3753 Label loop(assembler, &var_arg); |
(...skipping 1058 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4936 if (type->Is(Type::UntaggedPointer())) { | 4812 if (type->Is(Type::UntaggedPointer())) { |
4937 return Representation::External(); | 4813 return Representation::External(); |
4938 } | 4814 } |
4939 | 4815 |
4940 DCHECK(!type->Is(Type::Untagged())); | 4816 DCHECK(!type->Is(Type::Untagged())); |
4941 return Representation::Tagged(); | 4817 return Representation::Tagged(); |
4942 } | 4818 } |
4943 | 4819 |
4944 } // namespace internal | 4820 } // namespace internal |
4945 } // namespace v8 | 4821 } // namespace v8 |
OLD | NEW |