Index: src/code-stubs.cc |
diff --git a/src/code-stubs.cc b/src/code-stubs.cc |
index 847a645587d2c43eea09939a6273aca6217537a2..7ac1eb30ac0474f8985ffa02ef4102b254c68e12 100644 |
--- a/src/code-stubs.cc |
+++ b/src/code-stubs.cc |
@@ -2767,6 +2767,83 @@ void StringGreaterThanOrEqualStub::GenerateAssembly( |
GenerateStringRelationalComparison(assembler, kGreaterThanOrEqual); |
} |
+void ToLengthStub::GenerateAssembly( |
+ compiler::CodeStubAssembler* assembler) const { |
+ typedef compiler::CodeStubAssembler::Label Label; |
+ typedef compiler::Node Node; |
+ typedef compiler::CodeStubAssembler::Variable Variable; |
+ |
+ Node* context = assembler->Parameter(1); |
+ |
+ // We might need to loop once for ToNumber conversion. |
+ Variable var_len(assembler, MachineRepresentation::kTagged); |
+ Label loop(assembler, &var_len); |
+ var_len.Bind(assembler->Parameter(0)); |
+ assembler->Goto(&loop); |
+ assembler->Bind(&loop); |
+ { |
+ // Shared entry points. |
+ Label return_len(assembler), |
+ return_two53minus1(assembler, Label::kDeferred), |
+ return_zero(assembler, Label::kDeferred); |
+ |
+ // Load the current {len} value. |
+ Node* len = var_len.value(); |
+ |
+ // Check if {len} is a positive Smi. |
+ assembler->GotoIf(assembler->WordIsPositiveSmi(len), &return_len); |
+ |
+ // Check if {len} is a (negative) Smi. |
+ assembler->GotoIf(assembler->WordIsSmi(len), &return_zero); |
+ |
+ // Check if {len} is a HeapNumber. |
+ Label if_lenisheapnumber(assembler), |
+ if_lenisnotheapnumber(assembler, Label::kDeferred); |
+ assembler->Branch(assembler->WordEqual(assembler->LoadMap(len), |
+ assembler->HeapNumberMapConstant()), |
+ &if_lenisheapnumber, &if_lenisnotheapnumber); |
+ |
+ assembler->Bind(&if_lenisheapnumber); |
+ { |
+ // Load the floating-point value of {len}. |
+ Node* len_value = assembler->LoadHeapNumberValue(len); |
+ |
+ // Check if {len} is not greater than zero. |
+ assembler->GotoUnless(assembler->Float64GreaterThan( |
+ len_value, assembler->Float64Constant(0.0)), |
+ &return_zero); |
+ |
+ // Check if {len} is greater than or equal to 2^53-1. |
+ assembler->GotoIf( |
+ assembler->Float64GreaterThanOrEqual( |
+ len_value, assembler->Float64Constant(kMaxSafeInteger)), |
+ &return_two53minus1); |
+ |
+ // Round the {len} towards -Infinity. |
+ Node* value = assembler->Float64Floor(len_value); |
+ Node* result = assembler->ChangeFloat64ToTagged(value); |
+ assembler->Return(result); |
+ } |
+ |
+ assembler->Bind(&if_lenisnotheapnumber); |
+ { |
+ // Need to convert {len} to a Number first. |
+ Callable callable = CodeFactory::NonNumberToNumber(assembler->isolate()); |
+ var_len.Bind(assembler->CallStub(callable, context, len)); |
+ assembler->Goto(&loop); |
+ } |
+ |
+ assembler->Bind(&return_len); |
+ assembler->Return(var_len.value()); |
+ |
+ assembler->Bind(&return_two53minus1); |
+ assembler->Return(assembler->NumberConstant(kMaxSafeInteger)); |
+ |
+ assembler->Bind(&return_zero); |
+ assembler->Return(assembler->SmiConstant(Smi::FromInt(0))); |
+ } |
+} |
+ |
void ToBooleanStub::GenerateAssembly( |
compiler::CodeStubAssembler* assembler) const { |
typedef compiler::Node Node; |