Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(43)

Unified Diff: src/builtins/builtins-number.cc

Issue 2395373002: [builtins] Migrate Number.parseFloat to a TurboFan builtin. (Closed)
Patch Set: Fix the -0 corner case. Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/builtins/builtins.h ('k') | src/compiler/typer.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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);
« no previous file with comments | « src/builtins/builtins.h ('k') | src/compiler/typer.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698