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

Side by Side 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 unified diff | Download patch
« no previous file with comments | « src/builtins/builtins.h ('k') | src/compiler/typer.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/builtins/builtins-utils.h" 5 #include "src/builtins/builtins-utils.h"
6 #include "src/builtins/builtins.h" 6 #include "src/builtins/builtins.h"
7 #include "src/code-factory.h" 7 #include "src/code-factory.h"
8 8
9 namespace v8 { 9 namespace v8 {
10 namespace internal { 10 namespace internal {
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
143 assembler->Float64Abs(integer), 143 assembler->Float64Abs(integer),
144 assembler->Float64Constant(kMaxSafeInteger), &return_true, &return_false); 144 assembler->Float64Constant(kMaxSafeInteger), &return_true, &return_false);
145 145
146 assembler->Bind(&return_true); 146 assembler->Bind(&return_true);
147 assembler->Return(assembler->BooleanConstant(true)); 147 assembler->Return(assembler->BooleanConstant(true));
148 148
149 assembler->Bind(&return_false); 149 assembler->Bind(&return_false);
150 assembler->Return(assembler->BooleanConstant(false)); 150 assembler->Return(assembler->BooleanConstant(false));
151 } 151 }
152 152
153 // ES6 section 20.1.2.12 Number.parseFloat ( string )
154 void Builtins::Generate_NumberParseFloat(CodeStubAssembler* assembler) {
155 typedef CodeStubAssembler::Label Label;
156 typedef compiler::Node Node;
157 typedef CodeStubAssembler::Variable Variable;
158
159 Node* context = assembler->Parameter(4);
160
161 // We might need to loop once for ToString conversion.
162 Variable var_input(assembler, MachineRepresentation::kTagged);
163 Label loop(assembler, &var_input);
164 var_input.Bind(assembler->Parameter(1));
165 assembler->Goto(&loop);
166 assembler->Bind(&loop);
167 {
168 // Load the current {input} value.
169 Node* input = var_input.value();
170
171 // Check if the {input} is a HeapObject or a Smi.
172 Label if_inputissmi(assembler), if_inputisnotsmi(assembler);
173 assembler->Branch(assembler->WordIsSmi(input), &if_inputissmi,
174 &if_inputisnotsmi);
175
176 assembler->Bind(&if_inputissmi);
177 {
178 // The {input} is already a Number, no need to do anything.
179 assembler->Return(input);
180 }
181
182 assembler->Bind(&if_inputisnotsmi);
183 {
184 // The {input} is a HeapObject, check if it's already a String.
185 Label if_inputisstring(assembler), if_inputisnotstring(assembler);
186 Node* input_map = assembler->LoadMap(input);
187 Node* input_instance_type = assembler->LoadMapInstanceType(input_map);
188 assembler->Branch(assembler->IsStringInstanceType(input_instance_type),
189 &if_inputisstring, &if_inputisnotstring);
190
191 assembler->Bind(&if_inputisstring);
192 {
193 // The {input} is already a String, check if {input} contains
194 // a cached array index.
195 Label if_inputcached(assembler), if_inputnotcached(assembler);
196 Node* input_hash = assembler->LoadNameHashField(input);
197 Node* input_bit = assembler->Word32And(
198 input_hash,
199 assembler->Int32Constant(String::kContainsCachedArrayIndexMask));
200 assembler->Branch(
201 assembler->Word32Equal(input_bit, assembler->Int32Constant(0)),
202 &if_inputcached, &if_inputnotcached);
203
204 assembler->Bind(&if_inputcached);
205 {
206 // Just return the {input}s cached array index.
207 Node* input_array_index =
208 assembler->BitFieldDecodeWord<String::ArrayIndexValueBits>(
209 input_hash);
210 assembler->Return(assembler->SmiTag(input_array_index));
211 }
212
213 assembler->Bind(&if_inputnotcached);
214 {
215 // Need to fall back to the runtime to convert {input} to double.
216 assembler->Return(assembler->CallRuntime(Runtime::kStringParseFloat,
217 context, input));
218 }
219 }
220
221 assembler->Bind(&if_inputisnotstring);
222 {
223 // The {input} is neither a String nor a Smi, check for HeapNumber.
224 Label if_inputisnumber(assembler),
225 if_inputisnotnumber(assembler, Label::kDeferred);
226 assembler->Branch(
227 assembler->WordEqual(input_map, assembler->HeapNumberMapConstant()),
228 &if_inputisnumber, &if_inputisnotnumber);
229
230 assembler->Bind(&if_inputisnumber);
231 {
232 // The {input} is already a Number, take care of -0.
233 Label if_inputiszero(assembler), if_inputisnotzero(assembler);
234 Node* input_value = assembler->LoadHeapNumberValue(input);
235 assembler->Branch(assembler->Float64Equal(
236 input_value, assembler->Float64Constant(0.0)),
237 &if_inputiszero, &if_inputisnotzero);
238
239 assembler->Bind(&if_inputiszero);
240 assembler->Return(assembler->SmiConstant(0));
241
242 assembler->Bind(&if_inputisnotzero);
243 assembler->Return(input);
244 }
245
246 assembler->Bind(&if_inputisnotnumber);
247 {
248 // Need to convert the {input} to String first.
249 // TODO(bmeurer): This could be more efficient if necessary.
250 Callable callable = CodeFactory::ToString(assembler->isolate());
251 var_input.Bind(assembler->CallStub(callable, context, input));
252 assembler->Goto(&loop);
253 }
254 }
255 }
256 }
257 }
258
153 // ES6 section 20.1.3.2 Number.prototype.toExponential ( fractionDigits ) 259 // ES6 section 20.1.3.2 Number.prototype.toExponential ( fractionDigits )
154 BUILTIN(NumberPrototypeToExponential) { 260 BUILTIN(NumberPrototypeToExponential) {
155 HandleScope scope(isolate); 261 HandleScope scope(isolate);
156 Handle<Object> value = args.at<Object>(0); 262 Handle<Object> value = args.at<Object>(0);
157 Handle<Object> fraction_digits = args.atOrUndefined(isolate, 1); 263 Handle<Object> fraction_digits = args.atOrUndefined(isolate, 1);
158 264
159 // Unwrap the receiver {value}. 265 // Unwrap the receiver {value}.
160 if (value->IsJSValue()) { 266 if (value->IsJSValue()) {
161 value = handle(Handle<JSValue>::cast(value)->value(), isolate); 267 value = handle(Handle<JSValue>::cast(value)->value(), isolate);
162 } 268 }
(...skipping 1432 matching lines...) Expand 10 before | Expand all | Expand 10 after
1595 compiler::Node* lhs = assembler->Parameter(0); 1701 compiler::Node* lhs = assembler->Parameter(0);
1596 compiler::Node* rhs = assembler->Parameter(1); 1702 compiler::Node* rhs = assembler->Parameter(1);
1597 compiler::Node* context = assembler->Parameter(2); 1703 compiler::Node* context = assembler->Parameter(2);
1598 1704
1599 assembler->Return(assembler->StrictEqual(CodeStubAssembler::kNegateResult, 1705 assembler->Return(assembler->StrictEqual(CodeStubAssembler::kNegateResult,
1600 lhs, rhs, context)); 1706 lhs, rhs, context));
1601 } 1707 }
1602 1708
1603 } // namespace internal 1709 } // namespace internal
1604 } // namespace v8 1710 } // namespace v8
OLDNEW
« 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