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/builtins/builtins.h" | 5 #include "src/builtins/builtins.h" |
6 | 6 |
7 #include "src/api-arguments.h" | 7 #include "src/api-arguments.h" |
8 #include "src/api-natives.h" | 8 #include "src/api-natives.h" |
9 #include "src/api.h" | 9 #include "src/api.h" |
10 #include "src/base/ieee754.h" | 10 #include "src/base/ieee754.h" |
(...skipping 5783 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5794 switch (tail_call_mode) { | 5794 switch (tail_call_mode) { |
5795 case TailCallMode::kDisallow: | 5795 case TailCallMode::kDisallow: |
5796 return CallBoundFunction(); | 5796 return CallBoundFunction(); |
5797 case TailCallMode::kAllow: | 5797 case TailCallMode::kAllow: |
5798 return TailCallBoundFunction(); | 5798 return TailCallBoundFunction(); |
5799 } | 5799 } |
5800 UNREACHABLE(); | 5800 UNREACHABLE(); |
5801 return Handle<Code>::null(); | 5801 return Handle<Code>::null(); |
5802 } | 5802 } |
5803 | 5803 |
| 5804 Handle<Code> Builtins::NonPrimitiveToPrimitive(ToPrimitiveHint hint) { |
| 5805 switch (hint) { |
| 5806 case ToPrimitiveHint::kDefault: |
| 5807 return NonPrimitiveToPrimitive_Default(); |
| 5808 case ToPrimitiveHint::kNumber: |
| 5809 return NonPrimitiveToPrimitive_Number(); |
| 5810 case ToPrimitiveHint::kString: |
| 5811 return NonPrimitiveToPrimitive_String(); |
| 5812 } |
| 5813 UNREACHABLE(); |
| 5814 return Handle<Code>::null(); |
| 5815 } |
| 5816 |
| 5817 Handle<Code> Builtins::OrdinaryToPrimitive(OrdinaryToPrimitiveHint hint) { |
| 5818 switch (hint) { |
| 5819 case OrdinaryToPrimitiveHint::kNumber: |
| 5820 return OrdinaryToPrimitive_Number(); |
| 5821 case OrdinaryToPrimitiveHint::kString: |
| 5822 return OrdinaryToPrimitive_String(); |
| 5823 } |
| 5824 UNREACHABLE(); |
| 5825 return Handle<Code>::null(); |
| 5826 } |
| 5827 |
5804 Handle<Code> Builtins::InterpreterPushArgsAndCall(TailCallMode tail_call_mode, | 5828 Handle<Code> Builtins::InterpreterPushArgsAndCall(TailCallMode tail_call_mode, |
5805 CallableType function_type) { | 5829 CallableType function_type) { |
5806 switch (tail_call_mode) { | 5830 switch (tail_call_mode) { |
5807 case TailCallMode::kDisallow: | 5831 case TailCallMode::kDisallow: |
5808 if (function_type == CallableType::kJSFunction) { | 5832 if (function_type == CallableType::kJSFunction) { |
5809 return InterpreterPushArgsAndCallFunction(); | 5833 return InterpreterPushArgsAndCallFunction(); |
5810 } else { | 5834 } else { |
5811 return InterpreterPushArgsAndCall(); | 5835 return InterpreterPushArgsAndCall(); |
5812 } | 5836 } |
5813 case TailCallMode::kAllow: | 5837 case TailCallMode::kAllow: |
(...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6080 } | 6104 } |
6081 | 6105 |
6082 void Generate_StoreIC_SlowSloppy(CodeStubAssembler* assembler) { | 6106 void Generate_StoreIC_SlowSloppy(CodeStubAssembler* assembler) { |
6083 Generate_StoreIC_Slow(assembler, SLOPPY); | 6107 Generate_StoreIC_Slow(assembler, SLOPPY); |
6084 } | 6108 } |
6085 | 6109 |
6086 void Generate_StoreIC_SlowStrict(CodeStubAssembler* assembler) { | 6110 void Generate_StoreIC_SlowStrict(CodeStubAssembler* assembler) { |
6087 Generate_StoreIC_Slow(assembler, STRICT); | 6111 Generate_StoreIC_Slow(assembler, STRICT); |
6088 } | 6112 } |
6089 | 6113 |
| 6114 // 7.1.1.1 OrdinaryToPrimitive ( O, hint ) |
| 6115 void Generate_OrdinaryToPrimitive(CodeStubAssembler* assembler, |
| 6116 OrdinaryToPrimitiveHint hint) { |
| 6117 typedef CodeStubAssembler::Label Label; |
| 6118 typedef compiler::Node Node; |
| 6119 typedef CodeStubAssembler::Variable Variable; |
| 6120 |
| 6121 Node* input = assembler->Parameter(0); |
| 6122 Node* context = assembler->Parameter(1); |
| 6123 |
| 6124 Variable var_result(assembler, MachineRepresentation::kTagged); |
| 6125 Label return_result(assembler, &var_result); |
| 6126 |
| 6127 Handle<String> method_names[2]; |
| 6128 switch (hint) { |
| 6129 case OrdinaryToPrimitiveHint::kNumber: |
| 6130 method_names[0] = assembler->factory()->valueOf_string(); |
| 6131 method_names[1] = assembler->factory()->toString_string(); |
| 6132 break; |
| 6133 case OrdinaryToPrimitiveHint::kString: |
| 6134 method_names[0] = assembler->factory()->toString_string(); |
| 6135 method_names[1] = assembler->factory()->valueOf_string(); |
| 6136 break; |
| 6137 } |
| 6138 for (Handle<String> name : method_names) { |
| 6139 // Lookup the {name} on the {input}. |
| 6140 Callable callable = CodeFactory::GetProperty(assembler->isolate()); |
| 6141 Node* name_string = assembler->HeapConstant(name); |
| 6142 Node* method = assembler->CallStub(callable, context, input, name_string); |
| 6143 |
| 6144 // Check if the {method} is callable. |
| 6145 Label if_methodiscallable(assembler), |
| 6146 if_methodisnotcallable(assembler, Label::kDeferred); |
| 6147 assembler->GotoIf(assembler->WordIsSmi(method), &if_methodisnotcallable); |
| 6148 Node* method_map = assembler->LoadMap(method); |
| 6149 Node* method_bit_field = assembler->LoadMapBitField(method_map); |
| 6150 assembler->Branch( |
| 6151 assembler->Word32Equal( |
| 6152 assembler->Word32And(method_bit_field, assembler->Int32Constant( |
| 6153 1 << Map::kIsCallable)), |
| 6154 assembler->Int32Constant(0)), |
| 6155 &if_methodisnotcallable, &if_methodiscallable); |
| 6156 |
| 6157 assembler->Bind(&if_methodiscallable); |
| 6158 { |
| 6159 // Call the {method} on the {input}. |
| 6160 Callable callable = CodeFactory::Call(assembler->isolate()); |
| 6161 Node* result = assembler->CallJS(callable, context, method, input); |
| 6162 var_result.Bind(result); |
| 6163 |
| 6164 // Return the {result} if it is a primitive. |
| 6165 assembler->GotoIf(assembler->WordIsSmi(result), &return_result); |
| 6166 Node* result_instance_type = assembler->LoadInstanceType(result); |
| 6167 STATIC_ASSERT(FIRST_PRIMITIVE_TYPE == FIRST_TYPE); |
| 6168 assembler->GotoIf(assembler->Int32LessThanOrEqual( |
| 6169 result_instance_type, |
| 6170 assembler->Int32Constant(LAST_PRIMITIVE_TYPE)), |
| 6171 &return_result); |
| 6172 } |
| 6173 |
| 6174 // Just continue with the next {name} if the {method} is not callable. |
| 6175 assembler->Goto(&if_methodisnotcallable); |
| 6176 assembler->Bind(&if_methodisnotcallable); |
| 6177 } |
| 6178 |
| 6179 assembler->TailCallRuntime(Runtime::kThrowCannotConvertToPrimitive, context); |
| 6180 |
| 6181 assembler->Bind(&return_result); |
| 6182 assembler->Return(var_result.value()); |
| 6183 } |
| 6184 |
| 6185 void Generate_OrdinaryToPrimitive_Number(CodeStubAssembler* assembler) { |
| 6186 Generate_OrdinaryToPrimitive(assembler, OrdinaryToPrimitiveHint::kNumber); |
| 6187 } |
| 6188 |
| 6189 void Generate_OrdinaryToPrimitive_String(CodeStubAssembler* assembler) { |
| 6190 Generate_OrdinaryToPrimitive(assembler, OrdinaryToPrimitiveHint::kString); |
| 6191 } |
| 6192 |
| 6193 // ES6 section 7.1.1 ToPrimitive ( input [ , PreferredType ] ) |
| 6194 void Generate_NonPrimitiveToPrimitive(CodeStubAssembler* assembler, |
| 6195 ToPrimitiveHint hint) { |
| 6196 typedef CodeStubAssembler::Label Label; |
| 6197 typedef compiler::Node Node; |
| 6198 |
| 6199 Node* input = assembler->Parameter(0); |
| 6200 Node* context = assembler->Parameter(1); |
| 6201 |
| 6202 // Lookup the @@toPrimitive property on the {input}. |
| 6203 Callable callable = CodeFactory::GetProperty(assembler->isolate()); |
| 6204 Node* to_primitive_symbol = |
| 6205 assembler->HeapConstant(assembler->factory()->to_primitive_symbol()); |
| 6206 Node* exotic_to_prim = |
| 6207 assembler->CallStub(callable, context, input, to_primitive_symbol); |
| 6208 |
| 6209 // Check if {exotic_to_prim} is neither null nor undefined. |
| 6210 Label ordinary_to_primitive(assembler); |
| 6211 assembler->GotoIf( |
| 6212 assembler->WordEqual(exotic_to_prim, assembler->NullConstant()), |
| 6213 &ordinary_to_primitive); |
| 6214 assembler->GotoIf( |
| 6215 assembler->WordEqual(exotic_to_prim, assembler->UndefinedConstant()), |
| 6216 &ordinary_to_primitive); |
| 6217 { |
| 6218 // Invoke the {exotic_to_prim} method on the {input} with a string |
| 6219 // representation of the {hint}. |
| 6220 Callable callable = CodeFactory::Call(assembler->isolate()); |
| 6221 Node* hint_string = assembler->HeapConstant( |
| 6222 assembler->factory()->ToPrimitiveHintString(hint)); |
| 6223 Node* result = assembler->CallJS(callable, context, exotic_to_prim, input, |
| 6224 hint_string); |
| 6225 |
| 6226 // Verify that the {result} is actually a primitive. |
| 6227 Label if_resultisprimitive(assembler), |
| 6228 if_resultisnotprimitive(assembler, Label::kDeferred); |
| 6229 assembler->GotoIf(assembler->WordIsSmi(result), &if_resultisprimitive); |
| 6230 Node* result_instance_type = assembler->LoadInstanceType(result); |
| 6231 STATIC_ASSERT(FIRST_PRIMITIVE_TYPE == FIRST_TYPE); |
| 6232 assembler->Branch(assembler->Int32LessThanOrEqual( |
| 6233 result_instance_type, |
| 6234 assembler->Int32Constant(LAST_PRIMITIVE_TYPE)), |
| 6235 &if_resultisprimitive, &if_resultisnotprimitive); |
| 6236 |
| 6237 assembler->Bind(&if_resultisprimitive); |
| 6238 { |
| 6239 // Just return the {result}. |
| 6240 assembler->Return(result); |
| 6241 } |
| 6242 |
| 6243 assembler->Bind(&if_resultisnotprimitive); |
| 6244 { |
| 6245 // Somehow the @@toPrimitive method on {input} didn't yield a primitive. |
| 6246 assembler->TailCallRuntime(Runtime::kThrowCannotConvertToPrimitive, |
| 6247 context); |
| 6248 } |
| 6249 } |
| 6250 |
| 6251 // Convert using the OrdinaryToPrimitive algorithm instead. |
| 6252 assembler->Bind(&ordinary_to_primitive); |
| 6253 { |
| 6254 Callable callable = CodeFactory::OrdinaryToPrimitive( |
| 6255 assembler->isolate(), (hint == ToPrimitiveHint::kString) |
| 6256 ? OrdinaryToPrimitiveHint::kString |
| 6257 : OrdinaryToPrimitiveHint::kNumber); |
| 6258 assembler->TailCallStub(callable, context, input); |
| 6259 } |
| 6260 } |
| 6261 |
| 6262 void Generate_NonPrimitiveToPrimitive_Default(CodeStubAssembler* assembler) { |
| 6263 Generate_NonPrimitiveToPrimitive(assembler, ToPrimitiveHint::kDefault); |
| 6264 } |
| 6265 |
| 6266 void Generate_NonPrimitiveToPrimitive_Number(CodeStubAssembler* assembler) { |
| 6267 Generate_NonPrimitiveToPrimitive(assembler, ToPrimitiveHint::kNumber); |
| 6268 } |
| 6269 |
| 6270 void Generate_NonPrimitiveToPrimitive_String(CodeStubAssembler* assembler) { |
| 6271 Generate_NonPrimitiveToPrimitive(assembler, ToPrimitiveHint::kString); |
| 6272 } |
| 6273 |
6090 void Generate_KeyedStoreIC_Slow(MacroAssembler* masm) { | 6274 void Generate_KeyedStoreIC_Slow(MacroAssembler* masm) { |
6091 ElementHandlerCompiler::GenerateStoreSlow(masm); | 6275 ElementHandlerCompiler::GenerateStoreSlow(masm); |
6092 } | 6276 } |
6093 | 6277 |
6094 void Generate_StoreIC_Setter_ForDeopt(MacroAssembler* masm) { | 6278 void Generate_StoreIC_Setter_ForDeopt(MacroAssembler* masm) { |
6095 NamedStoreHandlerCompiler::GenerateStoreViaSetterForDeopt(masm); | 6279 NamedStoreHandlerCompiler::GenerateStoreViaSetterForDeopt(masm); |
6096 } | 6280 } |
6097 | 6281 |
6098 void Generate_KeyedStoreIC_Megamorphic(MacroAssembler* masm) { | 6282 void Generate_KeyedStoreIC_Megamorphic(MacroAssembler* masm) { |
6099 KeyedStoreIC::GenerateMegamorphic(masm, SLOPPY); | 6283 KeyedStoreIC::GenerateMegamorphic(masm, SLOPPY); |
(...skipping 562 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6662 BUILTIN_LIST_H(DEFINE_BUILTIN_ACCESSOR_H) | 6846 BUILTIN_LIST_H(DEFINE_BUILTIN_ACCESSOR_H) |
6663 BUILTIN_LIST_DEBUG_A(DEFINE_BUILTIN_ACCESSOR_A) | 6847 BUILTIN_LIST_DEBUG_A(DEFINE_BUILTIN_ACCESSOR_A) |
6664 #undef DEFINE_BUILTIN_ACCESSOR_C | 6848 #undef DEFINE_BUILTIN_ACCESSOR_C |
6665 #undef DEFINE_BUILTIN_ACCESSOR_A | 6849 #undef DEFINE_BUILTIN_ACCESSOR_A |
6666 #undef DEFINE_BUILTIN_ACCESSOR_T | 6850 #undef DEFINE_BUILTIN_ACCESSOR_T |
6667 #undef DEFINE_BUILTIN_ACCESSOR_S | 6851 #undef DEFINE_BUILTIN_ACCESSOR_S |
6668 #undef DEFINE_BUILTIN_ACCESSOR_H | 6852 #undef DEFINE_BUILTIN_ACCESSOR_H |
6669 | 6853 |
6670 } // namespace internal | 6854 } // namespace internal |
6671 } // namespace v8 | 6855 } // namespace v8 |
OLD | NEW |