| Index: src/builtins/builtins-number.cc
|
| diff --git a/src/builtins/builtins-number.cc b/src/builtins/builtins-number.cc
|
| index 6b894d3e47e3269220f09a48619f1d6e99cc10ab..0d2f5e0cf49e5e3c24a303533b764393486dbb36 100644
|
| --- a/src/builtins/builtins-number.cc
|
| +++ b/src/builtins/builtins-number.cc
|
| @@ -150,6 +150,112 @@ void Builtins::Generate_NumberIsSafeInteger(CodeStubAssembler* assembler) {
|
| assembler->Return(assembler->BooleanConstant(false));
|
| }
|
|
|
| +// ES6 section 20.1.2.12 Number.parseFloat ( string )
|
| +void Builtins::Generate_NumberParseFloat(CodeStubAssembler* assembler) {
|
| + typedef CodeStubAssembler::Label Label;
|
| + typedef compiler::Node Node;
|
| + typedef CodeStubAssembler::Variable Variable;
|
| +
|
| + Node* context = assembler->Parameter(4);
|
| +
|
| + // We might need to loop once for ToString conversion.
|
| + Variable var_input(assembler, MachineRepresentation::kTagged);
|
| + Label loop(assembler, &var_input);
|
| + var_input.Bind(assembler->Parameter(1));
|
| + assembler->Goto(&loop);
|
| + assembler->Bind(&loop);
|
| + {
|
| + // Load the current {input} value.
|
| + Node* input = var_input.value();
|
| +
|
| + // Check if the {input} is a HeapObject or a Smi.
|
| + Label if_inputissmi(assembler), if_inputisnotsmi(assembler);
|
| + assembler->Branch(assembler->WordIsSmi(input), &if_inputissmi,
|
| + &if_inputisnotsmi);
|
| +
|
| + assembler->Bind(&if_inputissmi);
|
| + {
|
| + // The {input} is already a Number, no need to do anything.
|
| + assembler->Return(input);
|
| + }
|
| +
|
| + assembler->Bind(&if_inputisnotsmi);
|
| + {
|
| + // The {input} is a HeapObject, check if it's already a String.
|
| + Label if_inputisstring(assembler), if_inputisnotstring(assembler);
|
| + Node* input_map = assembler->LoadMap(input);
|
| + Node* input_instance_type = assembler->LoadMapInstanceType(input_map);
|
| + assembler->Branch(assembler->IsStringInstanceType(input_instance_type),
|
| + &if_inputisstring, &if_inputisnotstring);
|
| +
|
| + assembler->Bind(&if_inputisstring);
|
| + {
|
| + // The {input} is already a String, check if {input} contains
|
| + // a cached array index.
|
| + Label if_inputcached(assembler), if_inputnotcached(assembler);
|
| + Node* input_hash = assembler->LoadNameHashField(input);
|
| + Node* input_bit = assembler->Word32And(
|
| + input_hash,
|
| + assembler->Int32Constant(String::kContainsCachedArrayIndexMask));
|
| + assembler->Branch(
|
| + assembler->Word32Equal(input_bit, assembler->Int32Constant(0)),
|
| + &if_inputcached, &if_inputnotcached);
|
| +
|
| + assembler->Bind(&if_inputcached);
|
| + {
|
| + // Just return the {input}s cached array index.
|
| + Node* input_array_index =
|
| + assembler->BitFieldDecodeWord<String::ArrayIndexValueBits>(
|
| + input_hash);
|
| + assembler->Return(assembler->SmiTag(input_array_index));
|
| + }
|
| +
|
| + assembler->Bind(&if_inputnotcached);
|
| + {
|
| + // Need to fall back to the runtime to convert {input} to double.
|
| + assembler->Return(assembler->CallRuntime(Runtime::kStringParseFloat,
|
| + context, input));
|
| + }
|
| + }
|
| +
|
| + assembler->Bind(&if_inputisnotstring);
|
| + {
|
| + // The {input} is neither a String nor a Smi, check for HeapNumber.
|
| + Label if_inputisnumber(assembler),
|
| + if_inputisnotnumber(assembler, Label::kDeferred);
|
| + assembler->Branch(
|
| + assembler->WordEqual(input_map, assembler->HeapNumberMapConstant()),
|
| + &if_inputisnumber, &if_inputisnotnumber);
|
| +
|
| + assembler->Bind(&if_inputisnumber);
|
| + {
|
| + // The {input} is already a Number, take care of -0.
|
| + Label if_inputiszero(assembler), if_inputisnotzero(assembler);
|
| + Node* input_value = assembler->LoadHeapNumberValue(input);
|
| + assembler->Branch(assembler->Float64Equal(
|
| + input_value, assembler->Float64Constant(0.0)),
|
| + &if_inputiszero, &if_inputisnotzero);
|
| +
|
| + assembler->Bind(&if_inputiszero);
|
| + assembler->Return(assembler->SmiConstant(0));
|
| +
|
| + assembler->Bind(&if_inputisnotzero);
|
| + assembler->Return(input);
|
| + }
|
| +
|
| + assembler->Bind(&if_inputisnotnumber);
|
| + {
|
| + // Need to convert the {input} to String first.
|
| + // TODO(bmeurer): This could be more efficient if necessary.
|
| + Callable callable = CodeFactory::ToString(assembler->isolate());
|
| + var_input.Bind(assembler->CallStub(callable, context, input));
|
| + assembler->Goto(&loop);
|
| + }
|
| + }
|
| + }
|
| + }
|
| +}
|
| +
|
| // ES6 section 20.1.3.2 Number.prototype.toExponential ( fractionDigits )
|
| BUILTIN(NumberPrototypeToExponential) {
|
| HandleScope scope(isolate);
|
|
|