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 6254 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6265 } | 6265 } |
6266 | 6266 |
6267 void Generate_NonPrimitiveToPrimitive_Number(CodeStubAssembler* assembler) { | 6267 void Generate_NonPrimitiveToPrimitive_Number(CodeStubAssembler* assembler) { |
6268 Generate_NonPrimitiveToPrimitive(assembler, ToPrimitiveHint::kNumber); | 6268 Generate_NonPrimitiveToPrimitive(assembler, ToPrimitiveHint::kNumber); |
6269 } | 6269 } |
6270 | 6270 |
6271 void Generate_NonPrimitiveToPrimitive_String(CodeStubAssembler* assembler) { | 6271 void Generate_NonPrimitiveToPrimitive_String(CodeStubAssembler* assembler) { |
6272 Generate_NonPrimitiveToPrimitive(assembler, ToPrimitiveHint::kString); | 6272 Generate_NonPrimitiveToPrimitive(assembler, ToPrimitiveHint::kString); |
6273 } | 6273 } |
6274 | 6274 |
| 6275 // ES6 section 7.1.3 ToNumber ( argument ) |
| 6276 void Generate_NonNumberToNumber(CodeStubAssembler* assembler) { |
| 6277 typedef CodeStubAssembler::Label Label; |
| 6278 typedef compiler::Node Node; |
| 6279 typedef CodeStubAssembler::Variable Variable; |
| 6280 |
| 6281 Node* input = assembler->Parameter(0); |
| 6282 Node* context = assembler->Parameter(1); |
| 6283 |
| 6284 // We might need to loop once here due to ToPrimitive conversions. |
| 6285 Variable var_input(assembler, MachineRepresentation::kTagged); |
| 6286 Label loop(assembler, &var_input); |
| 6287 var_input.Bind(input); |
| 6288 assembler->Goto(&loop); |
| 6289 assembler->Bind(&loop); |
| 6290 { |
| 6291 // Load the current {input} value (known to be a HeapObject). |
| 6292 Node* input = var_input.value(); |
| 6293 |
| 6294 // Dispatch on the {input} instance type. |
| 6295 Node* input_instance_type = assembler->LoadInstanceType(input); |
| 6296 Label if_inputisstring(assembler), if_inputisoddball(assembler), |
| 6297 if_inputisreceiver(assembler, Label::kDeferred), |
| 6298 if_inputisother(assembler, Label::kDeferred); |
| 6299 assembler->GotoIf(assembler->Int32LessThan( |
| 6300 input_instance_type, |
| 6301 assembler->Int32Constant(FIRST_NONSTRING_TYPE)), |
| 6302 &if_inputisstring); |
| 6303 assembler->GotoIf( |
| 6304 assembler->Word32Equal(input_instance_type, |
| 6305 assembler->Int32Constant(ODDBALL_TYPE)), |
| 6306 &if_inputisoddball); |
| 6307 STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE); |
| 6308 assembler->Branch(assembler->Int32GreaterThanOrEqual( |
| 6309 input_instance_type, |
| 6310 assembler->Int32Constant(FIRST_JS_RECEIVER_TYPE)), |
| 6311 &if_inputisreceiver, &if_inputisother); |
| 6312 |
| 6313 assembler->Bind(&if_inputisstring); |
| 6314 { |
| 6315 // The {input} is a String, use the fast stub to convert it to a Number. |
| 6316 // TODO(bmeurer): Consider inlining the StringToNumber logic here. |
| 6317 Callable callable = CodeFactory::StringToNumber(assembler->isolate()); |
| 6318 assembler->TailCallStub(callable, context, input); |
| 6319 } |
| 6320 |
| 6321 assembler->Bind(&if_inputisoddball); |
| 6322 { |
| 6323 // The {input} is an Oddball, we just need to the Number value of it. |
| 6324 Node* result = |
| 6325 assembler->LoadObjectField(input, Oddball::kToNumberOffset); |
| 6326 assembler->Return(result); |
| 6327 } |
| 6328 |
| 6329 assembler->Bind(&if_inputisreceiver); |
| 6330 { |
| 6331 // The {input} is a JSReceiver, we need to convert it to a Primitive first |
| 6332 // using the ToPrimitive type conversion, preferably yielding a Number. |
| 6333 Callable callable = CodeFactory::NonPrimitiveToPrimitive( |
| 6334 assembler->isolate(), ToPrimitiveHint::kNumber); |
| 6335 Node* result = assembler->CallStub(callable, context, input); |
| 6336 |
| 6337 // Check if the {result} is already a Number. |
| 6338 Label if_resultisnumber(assembler), if_resultisnotnumber(assembler); |
| 6339 assembler->GotoIf(assembler->WordIsSmi(result), &if_resultisnumber); |
| 6340 Node* result_map = assembler->LoadMap(result); |
| 6341 assembler->Branch( |
| 6342 assembler->WordEqual(result_map, assembler->HeapNumberMapConstant()), |
| 6343 &if_resultisnumber, &if_resultisnotnumber); |
| 6344 |
| 6345 assembler->Bind(&if_resultisnumber); |
| 6346 { |
| 6347 // The ToPrimitive conversion already gave us a Number, so we're done. |
| 6348 assembler->Return(result); |
| 6349 } |
| 6350 |
| 6351 assembler->Bind(&if_resultisnotnumber); |
| 6352 { |
| 6353 // We now have a Primitive {result}, but it's not yet a Number. |
| 6354 var_input.Bind(result); |
| 6355 assembler->Goto(&loop); |
| 6356 } |
| 6357 } |
| 6358 |
| 6359 assembler->Bind(&if_inputisother); |
| 6360 { |
| 6361 // The {input} is something else (i.e. Symbol or Simd128Value), let the |
| 6362 // runtime figure out the correct exception. |
| 6363 // Note: We cannot tail call to the runtime here, as js-to-wasm |
| 6364 // trampolines also use this code currently, and they declare all |
| 6365 // outgoing parameters as untagged, while we would push a tagged |
| 6366 // object here. |
| 6367 Node* result = assembler->CallRuntime(Runtime::kToNumber, context, input); |
| 6368 assembler->Return(result); |
| 6369 } |
| 6370 } |
| 6371 } |
| 6372 |
6275 void Generate_KeyedStoreIC_Slow(MacroAssembler* masm) { | 6373 void Generate_KeyedStoreIC_Slow(MacroAssembler* masm) { |
6276 ElementHandlerCompiler::GenerateStoreSlow(masm); | 6374 ElementHandlerCompiler::GenerateStoreSlow(masm); |
6277 } | 6375 } |
6278 | 6376 |
6279 void Generate_StoreIC_Setter_ForDeopt(MacroAssembler* masm) { | 6377 void Generate_StoreIC_Setter_ForDeopt(MacroAssembler* masm) { |
6280 NamedStoreHandlerCompiler::GenerateStoreViaSetterForDeopt(masm); | 6378 NamedStoreHandlerCompiler::GenerateStoreViaSetterForDeopt(masm); |
6281 } | 6379 } |
6282 | 6380 |
6283 void Generate_KeyedStoreIC_Megamorphic(MacroAssembler* masm) { | 6381 void Generate_KeyedStoreIC_Megamorphic(MacroAssembler* masm) { |
6284 KeyedStoreIC::GenerateMegamorphic(masm, SLOPPY); | 6382 KeyedStoreIC::GenerateMegamorphic(masm, SLOPPY); |
(...skipping 540 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6825 #define DEFINE_BUILTIN_ACCESSOR(Name, ...) \ | 6923 #define DEFINE_BUILTIN_ACCESSOR(Name, ...) \ |
6826 Handle<Code> Builtins::Name() { \ | 6924 Handle<Code> Builtins::Name() { \ |
6827 Code** code_address = reinterpret_cast<Code**>(builtin_address(k##Name)); \ | 6925 Code** code_address = reinterpret_cast<Code**>(builtin_address(k##Name)); \ |
6828 return Handle<Code>(code_address); \ | 6926 return Handle<Code>(code_address); \ |
6829 } | 6927 } |
6830 BUILTIN_LIST_ALL(DEFINE_BUILTIN_ACCESSOR) | 6928 BUILTIN_LIST_ALL(DEFINE_BUILTIN_ACCESSOR) |
6831 #undef DEFINE_BUILTIN_ACCESSOR | 6929 #undef DEFINE_BUILTIN_ACCESSOR |
6832 | 6930 |
6833 } // namespace internal | 6931 } // namespace internal |
6834 } // namespace v8 | 6932 } // namespace v8 |
OLD | NEW |