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 |