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

Side by Side Diff: src/builtins/builtins-number.cc

Issue 2517833005: [cleanup] Refactor builtins-number.cc (Closed)
Patch Set: Created 4 years 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 | « no previous file | src/builtins/builtins-utils.h » ('j') | src/builtins/builtins-utils.h » ('J')
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 #include "src/code-stub-assembler.h"
8 9
9 namespace v8 { 10 namespace v8 {
10 namespace internal { 11 namespace internal {
11 12
13 class NumberBuiltinsAssembler : public CodeStubAssembler {
14 public:
15 explicit NumberBuiltinsAssembler(compiler::CodeAssemblerState* state)
16 : CodeStubAssembler(state) {}
17
18 protected:
19 // TODO(jkummerow): Add useful helpers here, and derive from
20 // NumberBuiltinsAssembler below.
21 };
22
12 // ----------------------------------------------------------------------------- 23 // -----------------------------------------------------------------------------
13 // ES6 section 20.1 Number Objects 24 // ES6 section 20.1 Number Objects
14 25
15 // ES6 section 20.1.2.2 Number.isFinite ( number ) 26 // ES6 section 20.1.2.2 Number.isFinite ( number )
16 void Builtins::Generate_NumberIsFinite(compiler::CodeAssemblerState* state) { 27 TF_BUILTIN(NumberIsFinite, CodeStubAssembler) {
17 typedef CodeStubAssembler::Label Label; 28 Node* number = Parameter(1);
18 typedef compiler::Node Node; 29
19 CodeStubAssembler assembler(state); 30 Label return_true(this), return_false(this);
20 31
21 Node* number = assembler.Parameter(1); 32 // Check if {number} is a Smi.
22 33 GotoIf(TaggedIsSmi(number), &return_true);
23 Label return_true(&assembler), return_false(&assembler); 34
24 35 // Check if {number} is a HeapNumber.
25 // Check if {number} is a Smi. 36 GotoUnless(WordEqual(LoadMap(number), HeapNumberMapConstant()),
26 assembler.GotoIf(assembler.TaggedIsSmi(number), &return_true); 37 &return_false);
27
28 // Check if {number} is a HeapNumber.
29 assembler.GotoUnless(assembler.WordEqual(assembler.LoadMap(number),
30 assembler.HeapNumberMapConstant()),
31 &return_false);
32 38
33 // Check if {number} contains a finite, non-NaN value. 39 // Check if {number} contains a finite, non-NaN value.
34 Node* number_value = assembler.LoadHeapNumberValue(number); 40 Node* number_value = LoadHeapNumberValue(number);
35 assembler.BranchIfFloat64IsNaN( 41 BranchIfFloat64IsNaN(Float64Sub(number_value, number_value), &return_false,
36 assembler.Float64Sub(number_value, number_value), &return_false, 42 &return_true);
37 &return_true); 43
38 44 Bind(&return_true);
39 assembler.Bind(&return_true); 45 Return(BooleanConstant(true));
40 assembler.Return(assembler.BooleanConstant(true)); 46
41 47 Bind(&return_false);
42 assembler.Bind(&return_false); 48 Return(BooleanConstant(false));
43 assembler.Return(assembler.BooleanConstant(false));
44 } 49 }
45 50
46 // ES6 section 20.1.2.3 Number.isInteger ( number ) 51 // ES6 section 20.1.2.3 Number.isInteger ( number )
47 void Builtins::Generate_NumberIsInteger(compiler::CodeAssemblerState* state) { 52 TF_BUILTIN(NumberIsInteger, CodeStubAssembler) {
48 typedef CodeStubAssembler::Label Label; 53 Node* number = Parameter(1);
49 typedef compiler::Node Node; 54
50 CodeStubAssembler assembler(state); 55 Label return_true(this), return_false(this);
51 56
52 Node* number = assembler.Parameter(1); 57 // Check if {number} is a Smi.
53 58 GotoIf(TaggedIsSmi(number), &return_true);
54 Label return_true(&assembler), return_false(&assembler); 59
55 60 // Check if {number} is a HeapNumber.
56 // Check if {number} is a Smi. 61 GotoUnless(WordEqual(LoadMap(number), HeapNumberMapConstant()),
57 assembler.GotoIf(assembler.TaggedIsSmi(number), &return_true); 62 &return_false);
58
59 // Check if {number} is a HeapNumber.
60 assembler.GotoUnless(assembler.WordEqual(assembler.LoadMap(number),
61 assembler.HeapNumberMapConstant()),
62 &return_false);
63 63
64 // Load the actual value of {number}. 64 // Load the actual value of {number}.
65 Node* number_value = assembler.LoadHeapNumberValue(number); 65 Node* number_value = LoadHeapNumberValue(number);
66 66
67 // Truncate the value of {number} to an integer (or an infinity). 67 // Truncate the value of {number} to an integer (or an infinity).
68 Node* integer = assembler.Float64Trunc(number_value); 68 Node* integer = Float64Trunc(number_value);
69 69
70 // Check if {number}s value matches the integer (ruling out the infinities). 70 // Check if {number}s value matches the integer (ruling out the infinities).
71 assembler.Branch( 71 Branch(Float64Equal(Float64Sub(number_value, integer), Float64Constant(0.0)),
72 assembler.Float64Equal(assembler.Float64Sub(number_value, integer), 72 &return_true, &return_false);
73 assembler.Float64Constant(0.0)), 73
74 &return_true, &return_false); 74 Bind(&return_true);
75 75 Return(BooleanConstant(true));
76 assembler.Bind(&return_true); 76
77 assembler.Return(assembler.BooleanConstant(true)); 77 Bind(&return_false);
78 78 Return(BooleanConstant(false));
79 assembler.Bind(&return_false);
80 assembler.Return(assembler.BooleanConstant(false));
81 } 79 }
82 80
83 // ES6 section 20.1.2.4 Number.isNaN ( number ) 81 // ES6 section 20.1.2.4 Number.isNaN ( number )
84 void Builtins::Generate_NumberIsNaN(compiler::CodeAssemblerState* state) { 82 TF_BUILTIN(NumberIsNaN, CodeStubAssembler) {
85 typedef CodeStubAssembler::Label Label; 83 Node* number = Parameter(1);
86 typedef compiler::Node Node; 84
87 CodeStubAssembler assembler(state); 85 Label return_true(this), return_false(this);
88 86
89 Node* number = assembler.Parameter(1); 87 // Check if {number} is a Smi.
90 88 GotoIf(TaggedIsSmi(number), &return_false);
91 Label return_true(&assembler), return_false(&assembler); 89
92 90 // Check if {number} is a HeapNumber.
93 // Check if {number} is a Smi. 91 GotoUnless(WordEqual(LoadMap(number), HeapNumberMapConstant()),
94 assembler.GotoIf(assembler.TaggedIsSmi(number), &return_false); 92 &return_false);
95
96 // Check if {number} is a HeapNumber.
97 assembler.GotoUnless(assembler.WordEqual(assembler.LoadMap(number),
98 assembler.HeapNumberMapConstant()),
99 &return_false);
100 93
101 // Check if {number} contains a NaN value. 94 // Check if {number} contains a NaN value.
102 Node* number_value = assembler.LoadHeapNumberValue(number); 95 Node* number_value = LoadHeapNumberValue(number);
103 assembler.BranchIfFloat64IsNaN(number_value, &return_true, &return_false); 96 BranchIfFloat64IsNaN(number_value, &return_true, &return_false);
104 97
105 assembler.Bind(&return_true); 98 Bind(&return_true);
106 assembler.Return(assembler.BooleanConstant(true)); 99 Return(BooleanConstant(true));
107 100
108 assembler.Bind(&return_false); 101 Bind(&return_false);
109 assembler.Return(assembler.BooleanConstant(false)); 102 Return(BooleanConstant(false));
110 } 103 }
111 104
112 // ES6 section 20.1.2.5 Number.isSafeInteger ( number ) 105 // ES6 section 20.1.2.5 Number.isSafeInteger ( number )
113 void Builtins::Generate_NumberIsSafeInteger( 106 TF_BUILTIN(NumberIsSafeInteger, CodeStubAssembler) {
114 compiler::CodeAssemblerState* state) { 107 Node* number = Parameter(1);
115 typedef CodeStubAssembler::Label Label; 108
116 typedef compiler::Node Node; 109 Label return_true(this), return_false(this);
117 CodeStubAssembler assembler(state); 110
118 111 // Check if {number} is a Smi.
119 Node* number = assembler.Parameter(1); 112 GotoIf(TaggedIsSmi(number), &return_true);
120 113
121 Label return_true(&assembler), return_false(&assembler); 114 // Check if {number} is a HeapNumber.
122 115 GotoUnless(WordEqual(LoadMap(number), HeapNumberMapConstant()),
123 // Check if {number} is a Smi. 116 &return_false);
124 assembler.GotoIf(assembler.TaggedIsSmi(number), &return_true);
125
126 // Check if {number} is a HeapNumber.
127 assembler.GotoUnless(assembler.WordEqual(assembler.LoadMap(number),
128 assembler.HeapNumberMapConstant()),
129 &return_false);
130 117
131 // Load the actual value of {number}. 118 // Load the actual value of {number}.
132 Node* number_value = assembler.LoadHeapNumberValue(number); 119 Node* number_value = LoadHeapNumberValue(number);
133 120
134 // Truncate the value of {number} to an integer (or an infinity). 121 // Truncate the value of {number} to an integer (or an infinity).
135 Node* integer = assembler.Float64Trunc(number_value); 122 Node* integer = Float64Trunc(number_value);
136 123
137 // Check if {number}s value matches the integer (ruling out the infinities). 124 // Check if {number}s value matches the integer (ruling out the infinities).
138 assembler.GotoUnless( 125 GotoUnless(
139 assembler.Float64Equal(assembler.Float64Sub(number_value, integer), 126 Float64Equal(Float64Sub(number_value, integer), Float64Constant(0.0)),
140 assembler.Float64Constant(0.0)),
141 &return_false); 127 &return_false);
142 128
143 // Check if the {integer} value is in safe integer range. 129 // Check if the {integer} value is in safe integer range.
144 assembler.Branch(assembler.Float64LessThanOrEqual( 130 Branch(Float64LessThanOrEqual(Float64Abs(integer),
145 assembler.Float64Abs(integer), 131 Float64Constant(kMaxSafeInteger)),
146 assembler.Float64Constant(kMaxSafeInteger)), 132 &return_true, &return_false);
147 &return_true, &return_false); 133
148 134 Bind(&return_true);
149 assembler.Bind(&return_true); 135 Return(BooleanConstant(true));
150 assembler.Return(assembler.BooleanConstant(true)); 136
151 137 Bind(&return_false);
152 assembler.Bind(&return_false); 138 Return(BooleanConstant(false));
153 assembler.Return(assembler.BooleanConstant(false));
154 } 139 }
155 140
156 // ES6 section 20.1.2.12 Number.parseFloat ( string ) 141 // ES6 section 20.1.2.12 Number.parseFloat ( string )
157 void Builtins::Generate_NumberParseFloat(compiler::CodeAssemblerState* state) { 142 TF_BUILTIN(NumberParseFloat, CodeStubAssembler) {
158 typedef CodeStubAssembler::Label Label; 143 Node* context = Parameter(4);
159 typedef compiler::Node Node;
160 typedef CodeStubAssembler::Variable Variable;
161 CodeStubAssembler assembler(state);
162
163 Node* context = assembler.Parameter(4);
164 144
165 // We might need to loop once for ToString conversion. 145 // We might need to loop once for ToString conversion.
166 Variable var_input(&assembler, MachineRepresentation::kTagged); 146 Variable var_input(this, MachineRepresentation::kTagged);
167 Label loop(&assembler, &var_input); 147 Label loop(this, &var_input);
168 var_input.Bind(assembler.Parameter(1)); 148 var_input.Bind(Parameter(1));
169 assembler.Goto(&loop); 149 Goto(&loop);
170 assembler.Bind(&loop); 150 Bind(&loop);
171 { 151 {
172 // Load the current {input} value. 152 // Load the current {input} value.
173 Node* input = var_input.value(); 153 Node* input = var_input.value();
174 154
175 // Check if the {input} is a HeapObject or a Smi. 155 // Check if the {input} is a HeapObject or a Smi.
176 Label if_inputissmi(&assembler), if_inputisnotsmi(&assembler); 156 Label if_inputissmi(this), if_inputisnotsmi(this);
177 assembler.Branch(assembler.TaggedIsSmi(input), &if_inputissmi, 157 Branch(TaggedIsSmi(input), &if_inputissmi, &if_inputisnotsmi);
178 &if_inputisnotsmi); 158
179 159 Bind(&if_inputissmi);
180 assembler.Bind(&if_inputissmi);
181 { 160 {
182 // The {input} is already a Number, no need to do anything. 161 // The {input} is already a Number, no need to do anything.
183 assembler.Return(input); 162 Return(input);
184 } 163 }
185 164
186 assembler.Bind(&if_inputisnotsmi); 165 Bind(&if_inputisnotsmi);
187 { 166 {
188 // The {input} is a HeapObject, check if it's already a String. 167 // The {input} is a HeapObject, check if it's already a String.
189 Label if_inputisstring(&assembler), if_inputisnotstring(&assembler); 168 Label if_inputisstring(this), if_inputisnotstring(this);
190 Node* input_map = assembler.LoadMap(input); 169 Node* input_map = LoadMap(input);
191 Node* input_instance_type = assembler.LoadMapInstanceType(input_map); 170 Node* input_instance_type = LoadMapInstanceType(input_map);
192 assembler.Branch(assembler.IsStringInstanceType(input_instance_type), 171 Branch(IsStringInstanceType(input_instance_type), &if_inputisstring,
193 &if_inputisstring, &if_inputisnotstring); 172 &if_inputisnotstring);
194 173
195 assembler.Bind(&if_inputisstring); 174 Bind(&if_inputisstring);
196 { 175 {
197 // The {input} is already a String, check if {input} contains 176 // The {input} is already a String, check if {input} contains
198 // a cached array index. 177 // a cached array index.
199 Label if_inputcached(&assembler), if_inputnotcached(&assembler); 178 Label if_inputcached(this), if_inputnotcached(this);
200 Node* input_hash = assembler.LoadNameHashField(input); 179 Node* input_hash = LoadNameHashField(input);
201 Node* input_bit = assembler.Word32And( 180 Node* input_bit = Word32And(
202 input_hash, 181 input_hash, Int32Constant(String::kContainsCachedArrayIndexMask));
203 assembler.Int32Constant(String::kContainsCachedArrayIndexMask)); 182 Branch(Word32Equal(input_bit, Int32Constant(0)), &if_inputcached,
204 assembler.Branch( 183 &if_inputnotcached);
205 assembler.Word32Equal(input_bit, assembler.Int32Constant(0)), 184
206 &if_inputcached, &if_inputnotcached); 185 Bind(&if_inputcached);
207
208 assembler.Bind(&if_inputcached);
209 { 186 {
210 // Just return the {input}s cached array index. 187 // Just return the {input}s cached array index.
211 Node* input_array_index = 188 Node* input_array_index =
212 assembler.DecodeWordFromWord32<String::ArrayIndexValueBits>( 189 DecodeWordFromWord32<String::ArrayIndexValueBits>(input_hash);
213 input_hash); 190 Return(SmiTag(input_array_index));
214 assembler.Return(assembler.SmiTag(input_array_index)); 191 }
215 } 192
216 193 Bind(&if_inputnotcached);
217 assembler.Bind(&if_inputnotcached);
218 { 194 {
219 // Need to fall back to the runtime to convert {input} to double. 195 // Need to fall back to the runtime to convert {input} to double.
220 assembler.Return(assembler.CallRuntime(Runtime::kStringParseFloat, 196 Return(CallRuntime(Runtime::kStringParseFloat, context, input));
221 context, input));
222 } 197 }
223 } 198 }
224 199
225 assembler.Bind(&if_inputisnotstring); 200 Bind(&if_inputisnotstring);
226 { 201 {
227 // The {input} is neither a String nor a Smi, check for HeapNumber. 202 // The {input} is neither a String nor a Smi, check for HeapNumber.
228 Label if_inputisnumber(&assembler), 203 Label if_inputisnumber(this),
229 if_inputisnotnumber(&assembler, Label::kDeferred); 204 if_inputisnotnumber(this, Label::kDeferred);
230 assembler.Branch( 205 Branch(WordEqual(input_map, HeapNumberMapConstant()), &if_inputisnumber,
231 assembler.WordEqual(input_map, assembler.HeapNumberMapConstant()), 206 &if_inputisnotnumber);
232 &if_inputisnumber, &if_inputisnotnumber); 207
233 208 Bind(&if_inputisnumber);
234 assembler.Bind(&if_inputisnumber);
235 { 209 {
236 // The {input} is already a Number, take care of -0. 210 // The {input} is already a Number, take care of -0.
237 Label if_inputiszero(&assembler), if_inputisnotzero(&assembler); 211 Label if_inputiszero(this), if_inputisnotzero(this);
238 Node* input_value = assembler.LoadHeapNumberValue(input); 212 Node* input_value = LoadHeapNumberValue(input);
239 assembler.Branch(assembler.Float64Equal( 213 Branch(Float64Equal(input_value, Float64Constant(0.0)),
240 input_value, assembler.Float64Constant(0.0)), 214 &if_inputiszero, &if_inputisnotzero);
241 &if_inputiszero, &if_inputisnotzero); 215
242 216 Bind(&if_inputiszero);
243 assembler.Bind(&if_inputiszero); 217 Return(SmiConstant(0));
244 assembler.Return(assembler.SmiConstant(0)); 218
245 219 Bind(&if_inputisnotzero);
246 assembler.Bind(&if_inputisnotzero); 220 Return(input);
247 assembler.Return(input); 221 }
248 } 222
249 223 Bind(&if_inputisnotnumber);
250 assembler.Bind(&if_inputisnotnumber);
251 { 224 {
252 // Need to convert the {input} to String first. 225 // Need to convert the {input} to String first.
253 // TODO(bmeurer): This could be more efficient if necessary. 226 // TODO(bmeurer): This could be more efficient if necessary.
254 Callable callable = CodeFactory::ToString(assembler.isolate()); 227 Callable callable = CodeFactory::ToString(isolate());
255 var_input.Bind(assembler.CallStub(callable, context, input)); 228 var_input.Bind(CallStub(callable, context, input));
256 assembler.Goto(&loop); 229 Goto(&loop);
257 } 230 }
258 } 231 }
259 } 232 }
260 } 233 }
261 } 234 }
262 235
263 // ES6 section 20.1.2.13 Number.parseInt ( string, radix ) 236 // ES6 section 20.1.2.13 Number.parseInt ( string, radix )
264 void Builtins::Generate_NumberParseInt(compiler::CodeAssemblerState* state) { 237 TF_BUILTIN(NumberParseInt, CodeStubAssembler) {
265 typedef CodeStubAssembler::Label Label; 238 Node* input = Parameter(1);
266 typedef compiler::Node Node; 239 Node* radix = Parameter(2);
267 CodeStubAssembler assembler(state); 240 Node* context = Parameter(5);
268
269 Node* input = assembler.Parameter(1);
270 Node* radix = assembler.Parameter(2);
271 Node* context = assembler.Parameter(5);
272 241
273 // Check if {radix} is treated as 10 (i.e. undefined, 0 or 10). 242 // Check if {radix} is treated as 10 (i.e. undefined, 0 or 10).
274 Label if_radix10(&assembler), if_generic(&assembler, Label::kDeferred); 243 Label if_radix10(this), if_generic(this, Label::kDeferred);
275 assembler.GotoIf(assembler.WordEqual(radix, assembler.UndefinedConstant()), 244 GotoIf(WordEqual(radix, UndefinedConstant()), &if_radix10);
276 &if_radix10); 245 GotoIf(WordEqual(radix, SmiConstant(Smi::FromInt(10))), &if_radix10);
277 assembler.GotoIf( 246 GotoIf(WordEqual(radix, SmiConstant(Smi::FromInt(0))), &if_radix10);
278 assembler.WordEqual(radix, assembler.SmiConstant(Smi::FromInt(10))), 247 Goto(&if_generic);
279 &if_radix10);
280 assembler.GotoIf(
281 assembler.WordEqual(radix, assembler.SmiConstant(Smi::FromInt(0))),
282 &if_radix10);
283 assembler.Goto(&if_generic);
284 248
285 assembler.Bind(&if_radix10); 249 Bind(&if_radix10);
286 { 250 {
287 // Check if we can avoid the ToString conversion on {input}. 251 // Check if we can avoid the ToString conversion on {input}.
288 Label if_inputissmi(&assembler), if_inputisheapnumber(&assembler), 252 Label if_inputissmi(this), if_inputisheapnumber(this),
289 if_inputisstring(&assembler); 253 if_inputisstring(this);
290 assembler.GotoIf(assembler.TaggedIsSmi(input), &if_inputissmi); 254 GotoIf(TaggedIsSmi(input), &if_inputissmi);
291 Node* input_map = assembler.LoadMap(input); 255 Node* input_map = LoadMap(input);
292 assembler.GotoIf( 256 GotoIf(WordEqual(input_map, HeapNumberMapConstant()),
293 assembler.WordEqual(input_map, assembler.HeapNumberMapConstant()), 257 &if_inputisheapnumber);
294 &if_inputisheapnumber); 258 Node* input_instance_type = LoadMapInstanceType(input_map);
295 Node* input_instance_type = assembler.LoadMapInstanceType(input_map); 259 Branch(IsStringInstanceType(input_instance_type), &if_inputisstring,
296 assembler.Branch(assembler.IsStringInstanceType(input_instance_type), 260 &if_generic);
297 &if_inputisstring, &if_generic);
298 261
299 assembler.Bind(&if_inputissmi); 262 Bind(&if_inputissmi);
300 { 263 {
301 // Just return the {input}. 264 // Just return the {input}.
302 assembler.Return(input); 265 Return(input);
303 } 266 }
304 267
305 assembler.Bind(&if_inputisheapnumber); 268 Bind(&if_inputisheapnumber);
306 { 269 {
307 // Check if the {input} value is in Signed32 range. 270 // Check if the {input} value is in Signed32 range.
308 Label if_inputissigned32(&assembler); 271 Label if_inputissigned32(this);
309 Node* input_value = assembler.LoadHeapNumberValue(input); 272 Node* input_value = LoadHeapNumberValue(input);
310 Node* input_value32 = assembler.TruncateFloat64ToWord32(input_value); 273 Node* input_value32 = TruncateFloat64ToWord32(input_value);
311 assembler.GotoIf( 274 GotoIf(Float64Equal(input_value, ChangeInt32ToFloat64(input_value32)),
312 assembler.Float64Equal(input_value, 275 &if_inputissigned32);
313 assembler.ChangeInt32ToFloat64(input_value32)),
314 &if_inputissigned32);
315 276
316 // Check if the absolute {input} value is in the ]0.01,1e9[ range. 277 // Check if the absolute {input} value is in the ]0.01,1e9[ range.
317 Node* input_value_abs = assembler.Float64Abs(input_value); 278 Node* input_value_abs = Float64Abs(input_value);
318 279
319 assembler.GotoUnless(assembler.Float64LessThan( 280 GotoUnless(Float64LessThan(input_value_abs, Float64Constant(1e9)),
320 input_value_abs, assembler.Float64Constant(1e9)), 281 &if_generic);
321 &if_generic); 282 Branch(Float64LessThan(Float64Constant(0.01), input_value_abs),
322 assembler.Branch(assembler.Float64LessThan( 283 &if_inputissigned32, &if_generic);
323 assembler.Float64Constant(0.01), input_value_abs),
324 &if_inputissigned32, &if_generic);
325 284
326 // Return the truncated int32 value, and return the tagged result. 285 // Return the truncated int32 value, and return the tagged result.
327 assembler.Bind(&if_inputissigned32); 286 Bind(&if_inputissigned32);
328 Node* result = assembler.ChangeInt32ToTagged(input_value32); 287 Node* result = ChangeInt32ToTagged(input_value32);
329 assembler.Return(result); 288 Return(result);
330 } 289 }
331 290
332 assembler.Bind(&if_inputisstring); 291 Bind(&if_inputisstring);
333 { 292 {
334 // Check if the String {input} has a cached array index. 293 // Check if the String {input} has a cached array index.
335 Node* input_hash = assembler.LoadNameHashField(input); 294 Node* input_hash = LoadNameHashField(input);
336 Node* input_bit = assembler.Word32And( 295 Node* input_bit = Word32And(
337 input_hash, 296 input_hash, Int32Constant(String::kContainsCachedArrayIndexMask));
338 assembler.Int32Constant(String::kContainsCachedArrayIndexMask)); 297 GotoIf(Word32NotEqual(input_bit, Int32Constant(0)), &if_generic);
339 assembler.GotoIf(
340 assembler.Word32NotEqual(input_bit, assembler.Int32Constant(0)),
341 &if_generic);
342 298
343 // Return the cached array index as result. 299 // Return the cached array index as result.
344 Node* input_index = 300 Node* input_index =
345 assembler.DecodeWordFromWord32<String::ArrayIndexValueBits>( 301 DecodeWordFromWord32<String::ArrayIndexValueBits>(input_hash);
346 input_hash); 302 Node* result = SmiTag(input_index);
347 Node* result = assembler.SmiTag(input_index); 303 Return(result);
348 assembler.Return(result);
349 } 304 }
350 } 305 }
351 306
352 assembler.Bind(&if_generic); 307 Bind(&if_generic);
353 { 308 {
354 Node* result = 309 Node* result = CallRuntime(Runtime::kStringParseInt, context, input, radix);
355 assembler.CallRuntime(Runtime::kStringParseInt, context, input, radix); 310 Return(result);
356 assembler.Return(result);
357 } 311 }
358 } 312 }
359 313
360 // ES6 section 20.1.3.2 Number.prototype.toExponential ( fractionDigits ) 314 // ES6 section 20.1.3.2 Number.prototype.toExponential ( fractionDigits )
361 BUILTIN(NumberPrototypeToExponential) { 315 BUILTIN(NumberPrototypeToExponential) {
362 HandleScope scope(isolate); 316 HandleScope scope(isolate);
363 Handle<Object> value = args.at<Object>(0); 317 Handle<Object> value = args.at<Object>(0);
364 Handle<Object> fraction_digits = args.atOrUndefined(isolate, 1); 318 Handle<Object> fraction_digits = args.atOrUndefined(isolate, 1);
365 319
366 // Unwrap the receiver {value}. 320 // Unwrap the receiver {value}.
(...skipping 1458 matching lines...) Expand 10 before | Expand all | Expand 10 after
1825 compiler::Node* lhs = assembler.Parameter(0); 1779 compiler::Node* lhs = assembler.Parameter(0);
1826 compiler::Node* rhs = assembler.Parameter(1); 1780 compiler::Node* rhs = assembler.Parameter(1);
1827 compiler::Node* context = assembler.Parameter(2); 1781 compiler::Node* context = assembler.Parameter(2);
1828 1782
1829 assembler.Return(assembler.StrictEqual(CodeStubAssembler::kNegateResult, lhs, 1783 assembler.Return(assembler.StrictEqual(CodeStubAssembler::kNegateResult, lhs,
1830 rhs, context)); 1784 rhs, context));
1831 } 1785 }
1832 1786
1833 } // namespace internal 1787 } // namespace internal
1834 } // namespace v8 1788 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | src/builtins/builtins-utils.h » ('j') | src/builtins/builtins-utils.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698