Chromium Code Reviews| 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); | |
|
Igor Sheludko
2016/07/14 09:53:47
Same here: STATIC_ASSERT(FIRST_PRIMITIVE_TYPE == F
Benedikt Meurer
2016/07/14 09:56:09
Hm, that would have to materialize a bit because o
| |
| 6167 assembler->GotoIf(assembler->Int32LessThanOrEqual( | |
| 6168 result_instance_type, | |
| 6169 assembler->Int32Constant(LAST_PRIMITIVE_TYPE)), | |
| 6170 &return_result); | |
| 6171 } | |
| 6172 | |
| 6173 // Just continue with the next {name} if the {method} is not callable. | |
| 6174 assembler->Goto(&if_methodisnotcallable); | |
| 6175 assembler->Bind(&if_methodisnotcallable); | |
| 6176 } | |
| 6177 | |
| 6178 assembler->TailCallRuntime(Runtime::kThrowCannotConvertToPrimitive, context); | |
| 6179 | |
| 6180 assembler->Bind(&return_result); | |
| 6181 assembler->Return(var_result.value()); | |
| 6182 } | |
| 6183 | |
| 6184 void Generate_OrdinaryToPrimitive_Number(CodeStubAssembler* assembler) { | |
| 6185 Generate_OrdinaryToPrimitive(assembler, OrdinaryToPrimitiveHint::kNumber); | |
| 6186 } | |
| 6187 | |
| 6188 void Generate_OrdinaryToPrimitive_String(CodeStubAssembler* assembler) { | |
| 6189 Generate_OrdinaryToPrimitive(assembler, OrdinaryToPrimitiveHint::kString); | |
| 6190 } | |
| 6191 | |
| 6192 // ES6 section 7.1.1 ToPrimitive ( input [ , PreferredType ] ) | |
| 6193 void Generate_NonPrimitiveToPrimitive(CodeStubAssembler* assembler, | |
| 6194 ToPrimitiveHint hint) { | |
| 6195 typedef CodeStubAssembler::Label Label; | |
| 6196 typedef compiler::Node Node; | |
| 6197 | |
| 6198 Node* input = assembler->Parameter(0); | |
| 6199 Node* context = assembler->Parameter(1); | |
| 6200 | |
| 6201 // Lookup the @@toPrimitive property on the {input}. | |
| 6202 Callable callable = CodeFactory::GetProperty(assembler->isolate()); | |
| 6203 Node* to_primitive_symbol = | |
| 6204 assembler->HeapConstant(assembler->factory()->to_primitive_symbol()); | |
| 6205 Node* exotic_to_prim = | |
| 6206 assembler->CallStub(callable, context, input, to_primitive_symbol); | |
| 6207 | |
| 6208 // Check if {exotic_to_prim} is neither null nor undefined. | |
| 6209 Label ordinary_to_primitive(assembler); | |
| 6210 assembler->GotoIf( | |
| 6211 assembler->WordEqual(exotic_to_prim, assembler->NullConstant()), | |
| 6212 &ordinary_to_primitive); | |
| 6213 assembler->GotoIf( | |
| 6214 assembler->WordEqual(exotic_to_prim, assembler->UndefinedConstant()), | |
| 6215 &ordinary_to_primitive); | |
| 6216 { | |
| 6217 // Invoke the {exotic_to_prim} method on the {input} with a string | |
| 6218 // representation of the {hint}. | |
| 6219 Callable callable = CodeFactory::Call(assembler->isolate()); | |
| 6220 Node* hint_string = assembler->HeapConstant( | |
| 6221 assembler->factory()->ToPrimitiveHintString(hint)); | |
| 6222 Node* result = assembler->CallJS(callable, context, exotic_to_prim, input, | |
| 6223 hint_string); | |
| 6224 | |
| 6225 // Verify that the {result} is actually a primitive. | |
| 6226 Label if_resultisprimitive(assembler), | |
| 6227 if_resultisnotprimitive(assembler, Label::kDeferred); | |
| 6228 assembler->GotoIf(assembler->WordIsSmi(result), &if_resultisprimitive); | |
| 6229 Node* result_instance_type = assembler->LoadInstanceType(result); | |
|
Igor Sheludko
2016/07/14 09:41:25
STATIC_ASSERT(FIRST_PRIMITIVE_TYPE == FIRST_TYPE);
Benedikt Meurer
2016/07/14 09:56:09
Done.
| |
| 6230 assembler->Branch(assembler->Int32LessThanOrEqual( | |
| 6231 result_instance_type, | |
| 6232 assembler->Int32Constant(LAST_PRIMITIVE_TYPE)), | |
| 6233 &if_resultisprimitive, &if_resultisnotprimitive); | |
| 6234 | |
| 6235 assembler->Bind(&if_resultisprimitive); | |
| 6236 { | |
| 6237 // Just return the {result}. | |
| 6238 assembler->Return(result); | |
| 6239 } | |
| 6240 | |
| 6241 assembler->Bind(&if_resultisnotprimitive); | |
| 6242 { | |
| 6243 // Somehow the @@toPrimitive method on {input} didn't yield a primitive. | |
| 6244 assembler->TailCallRuntime(Runtime::kThrowCannotConvertToPrimitive, | |
| 6245 context); | |
| 6246 } | |
| 6247 } | |
| 6248 | |
| 6249 // Convert using the OrdinaryToPrimitive algorithm instead. | |
| 6250 assembler->Bind(&ordinary_to_primitive); | |
| 6251 { | |
| 6252 Callable callable = CodeFactory::OrdinaryToPrimitive( | |
| 6253 assembler->isolate(), (hint == ToPrimitiveHint::kString) | |
| 6254 ? OrdinaryToPrimitiveHint::kString | |
| 6255 : OrdinaryToPrimitiveHint::kNumber); | |
| 6256 assembler->TailCallStub(callable, context, input); | |
| 6257 } | |
| 6258 } | |
| 6259 | |
| 6260 void Generate_NonPrimitiveToPrimitive_Default(CodeStubAssembler* assembler) { | |
| 6261 Generate_NonPrimitiveToPrimitive(assembler, ToPrimitiveHint::kDefault); | |
| 6262 } | |
| 6263 | |
| 6264 void Generate_NonPrimitiveToPrimitive_Number(CodeStubAssembler* assembler) { | |
| 6265 Generate_NonPrimitiveToPrimitive(assembler, ToPrimitiveHint::kNumber); | |
| 6266 } | |
| 6267 | |
| 6268 void Generate_NonPrimitiveToPrimitive_String(CodeStubAssembler* assembler) { | |
| 6269 Generate_NonPrimitiveToPrimitive(assembler, ToPrimitiveHint::kString); | |
| 6270 } | |
| 6271 | |
| 6090 void Generate_KeyedStoreIC_Slow(MacroAssembler* masm) { | 6272 void Generate_KeyedStoreIC_Slow(MacroAssembler* masm) { |
| 6091 ElementHandlerCompiler::GenerateStoreSlow(masm); | 6273 ElementHandlerCompiler::GenerateStoreSlow(masm); |
| 6092 } | 6274 } |
| 6093 | 6275 |
| 6094 void Generate_StoreIC_Setter_ForDeopt(MacroAssembler* masm) { | 6276 void Generate_StoreIC_Setter_ForDeopt(MacroAssembler* masm) { |
| 6095 NamedStoreHandlerCompiler::GenerateStoreViaSetterForDeopt(masm); | 6277 NamedStoreHandlerCompiler::GenerateStoreViaSetterForDeopt(masm); |
| 6096 } | 6278 } |
| 6097 | 6279 |
| 6098 void Generate_KeyedStoreIC_Megamorphic(MacroAssembler* masm) { | 6280 void Generate_KeyedStoreIC_Megamorphic(MacroAssembler* masm) { |
| 6099 KeyedStoreIC::GenerateMegamorphic(masm, SLOPPY); | 6281 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) | 6844 BUILTIN_LIST_H(DEFINE_BUILTIN_ACCESSOR_H) |
| 6663 BUILTIN_LIST_DEBUG_A(DEFINE_BUILTIN_ACCESSOR_A) | 6845 BUILTIN_LIST_DEBUG_A(DEFINE_BUILTIN_ACCESSOR_A) |
| 6664 #undef DEFINE_BUILTIN_ACCESSOR_C | 6846 #undef DEFINE_BUILTIN_ACCESSOR_C |
| 6665 #undef DEFINE_BUILTIN_ACCESSOR_A | 6847 #undef DEFINE_BUILTIN_ACCESSOR_A |
| 6666 #undef DEFINE_BUILTIN_ACCESSOR_T | 6848 #undef DEFINE_BUILTIN_ACCESSOR_T |
| 6667 #undef DEFINE_BUILTIN_ACCESSOR_S | 6849 #undef DEFINE_BUILTIN_ACCESSOR_S |
| 6668 #undef DEFINE_BUILTIN_ACCESSOR_H | 6850 #undef DEFINE_BUILTIN_ACCESSOR_H |
| 6669 | 6851 |
| 6670 } // namespace internal | 6852 } // namespace internal |
| 6671 } // namespace v8 | 6853 } // namespace v8 |
| OLD | NEW |