| 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 |