OLD | NEW |
1 // Copyright 2016 the V8 project authors. All rights reserved. | 1 // Copyright 2016 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-stub-assembler.h" | 5 #include "src/code-stub-assembler.h" |
6 #include "src/code-factory.h" | 6 #include "src/code-factory.h" |
7 #include "src/frames-inl.h" | 7 #include "src/frames-inl.h" |
8 #include "src/frames.h" | 8 #include "src/frames.h" |
9 #include "src/ic/handler-configuration.h" | 9 #include "src/ic/handler-configuration.h" |
10 #include "src/ic/stub-cache.h" | 10 #include "src/ic/stub-cache.h" |
(...skipping 2412 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2423 { | 2423 { |
2424 var_result.Bind(CallRuntime(Runtime::kToName, context, value)); | 2424 var_result.Bind(CallRuntime(Runtime::kToName, context, value)); |
2425 Goto(&end); | 2425 Goto(&end); |
2426 } | 2426 } |
2427 } | 2427 } |
2428 | 2428 |
2429 Bind(&end); | 2429 Bind(&end); |
2430 return var_result.value(); | 2430 return var_result.value(); |
2431 } | 2431 } |
2432 | 2432 |
| 2433 Node* CodeStubAssembler::NonNumberToNumber(Node* context, Node* input) { |
| 2434 // Assert input is a HeapObject (not smi or heap number) |
| 2435 Assert(Word32BinaryNot(WordIsSmi(input))); |
| 2436 Assert(Word32NotEqual(LoadMap(input), HeapNumberMapConstant())); |
| 2437 |
| 2438 // We might need to loop once here due to ToPrimitive conversions. |
| 2439 Variable var_input(this, MachineRepresentation::kTagged); |
| 2440 Variable var_result(this, MachineRepresentation::kTagged); |
| 2441 Label loop(this, &var_input); |
| 2442 Label end(this); |
| 2443 var_input.Bind(input); |
| 2444 Goto(&loop); |
| 2445 Bind(&loop); |
| 2446 { |
| 2447 // Load the current {input} value (known to be a HeapObject). |
| 2448 Node* input = var_input.value(); |
| 2449 |
| 2450 // Dispatch on the {input} instance type. |
| 2451 Node* input_instance_type = LoadInstanceType(input); |
| 2452 Label if_inputisstring(this), if_inputisoddball(this), |
| 2453 if_inputisreceiver(this, Label::kDeferred), |
| 2454 if_inputisother(this, Label::kDeferred); |
| 2455 GotoIf( |
| 2456 Int32LessThan(input_instance_type, Int32Constant(FIRST_NONSTRING_TYPE)), |
| 2457 &if_inputisstring); |
| 2458 GotoIf(Word32Equal(input_instance_type, Int32Constant(ODDBALL_TYPE)), |
| 2459 &if_inputisoddball); |
| 2460 STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE); |
| 2461 Branch(Int32GreaterThanOrEqual(input_instance_type, |
| 2462 Int32Constant(FIRST_JS_RECEIVER_TYPE)), |
| 2463 &if_inputisreceiver, &if_inputisother); |
| 2464 |
| 2465 Bind(&if_inputisstring); |
| 2466 { |
| 2467 // The {input} is a String, use the fast stub to convert it to a Number. |
| 2468 var_result.Bind(StringToNumber(context, input)); |
| 2469 Goto(&end); |
| 2470 } |
| 2471 |
| 2472 Bind(&if_inputisoddball); |
| 2473 { |
| 2474 // The {input} is an Oddball, we just need to load the Number value of it. |
| 2475 var_result.Bind(LoadObjectField(input, Oddball::kToNumberOffset)); |
| 2476 Goto(&end); |
| 2477 } |
| 2478 |
| 2479 Bind(&if_inputisreceiver); |
| 2480 { |
| 2481 // The {input} is a JSReceiver, we need to convert it to a Primitive first |
| 2482 // using the ToPrimitive type conversion, preferably yielding a Number. |
| 2483 Callable callable = CodeFactory::NonPrimitiveToPrimitive( |
| 2484 isolate(), ToPrimitiveHint::kNumber); |
| 2485 Node* result = CallStub(callable, context, input); |
| 2486 |
| 2487 // Check if the {result} is already a Number. |
| 2488 Label if_resultisnumber(this), if_resultisnotnumber(this); |
| 2489 GotoIf(WordIsSmi(result), &if_resultisnumber); |
| 2490 Node* result_map = LoadMap(result); |
| 2491 Branch(WordEqual(result_map, HeapNumberMapConstant()), &if_resultisnumber, |
| 2492 &if_resultisnotnumber); |
| 2493 |
| 2494 Bind(&if_resultisnumber); |
| 2495 { |
| 2496 // The ToPrimitive conversion already gave us a Number, so we're done. |
| 2497 var_result.Bind(result); |
| 2498 Goto(&end); |
| 2499 } |
| 2500 |
| 2501 Bind(&if_resultisnotnumber); |
| 2502 { |
| 2503 // We now have a Primitive {result}, but it's not yet a Number. |
| 2504 var_input.Bind(result); |
| 2505 Goto(&loop); |
| 2506 } |
| 2507 } |
| 2508 |
| 2509 Bind(&if_inputisother); |
| 2510 { |
| 2511 // The {input} is something else (i.e. Symbol or Simd128Value), let the |
| 2512 // runtime figure out the correct exception. |
| 2513 // Note: We cannot tail call to the runtime here, as js-to-wasm |
| 2514 // trampolines also use this code currently, and they declare all |
| 2515 // outgoing parameters as untagged, while we would push a tagged |
| 2516 // object here. |
| 2517 var_result.Bind(CallRuntime(Runtime::kToNumber, context, input)); |
| 2518 Goto(&end); |
| 2519 } |
| 2520 } |
| 2521 |
| 2522 Bind(&end); |
| 2523 return var_result.value(); |
| 2524 } |
| 2525 |
| 2526 Node* CodeStubAssembler::ToNumber(Node* context, Node* input) { |
| 2527 Variable var_result(this, MachineRepresentation::kTagged); |
| 2528 Label end(this); |
| 2529 |
| 2530 Label not_smi(this, Label::kDeferred); |
| 2531 GotoUnless(WordIsSmi(input), ¬_smi); |
| 2532 var_result.Bind(input); |
| 2533 Goto(&end); |
| 2534 |
| 2535 Bind(¬_smi); |
| 2536 { |
| 2537 Label not_heap_number(this, Label::kDeferred); |
| 2538 Node* input_map = LoadMap(input); |
| 2539 GotoIf(Word32NotEqual(input_map, HeapNumberMapConstant()), |
| 2540 ¬_heap_number); |
| 2541 |
| 2542 var_result.Bind(input); |
| 2543 Goto(&end); |
| 2544 |
| 2545 Bind(¬_heap_number); |
| 2546 { |
| 2547 var_result.Bind(NonNumberToNumber(context, input)); |
| 2548 Goto(&end); |
| 2549 } |
| 2550 } |
| 2551 |
| 2552 Bind(&end); |
| 2553 return var_result.value(); |
| 2554 } |
| 2555 |
2433 Node* CodeStubAssembler::BitFieldDecode(Node* word32, uint32_t shift, | 2556 Node* CodeStubAssembler::BitFieldDecode(Node* word32, uint32_t shift, |
2434 uint32_t mask) { | 2557 uint32_t mask) { |
2435 return Word32Shr(Word32And(word32, Int32Constant(mask)), | 2558 return Word32Shr(Word32And(word32, Int32Constant(mask)), |
2436 static_cast<int>(shift)); | 2559 static_cast<int>(shift)); |
2437 } | 2560 } |
2438 | 2561 |
2439 void CodeStubAssembler::SetCounter(StatsCounter* counter, int value) { | 2562 void CodeStubAssembler::SetCounter(StatsCounter* counter, int value) { |
2440 if (FLAG_native_code_counters && counter->Enabled()) { | 2563 if (FLAG_native_code_counters && counter->Enabled()) { |
2441 Node* counter_address = ExternalConstant(ExternalReference(counter)); | 2564 Node* counter_address = ExternalConstant(ExternalReference(counter)); |
2442 StoreNoWriteBarrier(MachineRepresentation::kWord32, counter_address, | 2565 StoreNoWriteBarrier(MachineRepresentation::kWord32, counter_address, |
(...skipping 1948 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4391 Heap::kTheHoleValueRootIndex); | 4514 Heap::kTheHoleValueRootIndex); |
4392 | 4515 |
4393 // Store the WeakCell in the feedback vector. | 4516 // Store the WeakCell in the feedback vector. |
4394 StoreFixedArrayElement(feedback_vector, slot, cell, UPDATE_WRITE_BARRIER, | 4517 StoreFixedArrayElement(feedback_vector, slot, cell, UPDATE_WRITE_BARRIER, |
4395 CodeStubAssembler::SMI_PARAMETERS); | 4518 CodeStubAssembler::SMI_PARAMETERS); |
4396 return cell; | 4519 return cell; |
4397 } | 4520 } |
4398 | 4521 |
4399 } // namespace internal | 4522 } // namespace internal |
4400 } // namespace v8 | 4523 } // namespace v8 |
OLD | NEW |