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

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

Issue 2361363002: [stubs] Add TruncationMode argument to ToInteger (Closed)
Patch Set: Simplify Created 4 years, 3 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 | « no previous file | src/code-stub-assembler.h » ('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.h" 5 #include "src/builtins/builtins.h"
6 #include "src/builtins/builtins-utils.h" 6 #include "src/builtins/builtins-utils.h"
7 7
8 #include "src/code-factory.h" 8 #include "src/code-factory.h"
9 9
10 namespace v8 { 10 namespace v8 {
(...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after
287 CopyChars(result->GetChars() + one_byte_buffer.length(), 287 CopyChars(result->GetChars() + one_byte_buffer.length(),
288 two_byte_buffer.ToConstVector().start(), two_byte_buffer.length()); 288 two_byte_buffer.ToConstVector().start(), two_byte_buffer.length());
289 289
290 return *result; 290 return *result;
291 } 291 }
292 292
293 // ES6 section 21.1.3.1 String.prototype.charAt ( pos ) 293 // ES6 section 21.1.3.1 String.prototype.charAt ( pos )
294 void Builtins::Generate_StringPrototypeCharAt(CodeStubAssembler* assembler) { 294 void Builtins::Generate_StringPrototypeCharAt(CodeStubAssembler* assembler) {
295 typedef CodeStubAssembler::Label Label; 295 typedef CodeStubAssembler::Label Label;
296 typedef compiler::Node Node; 296 typedef compiler::Node Node;
297 typedef CodeStubAssembler::Variable Variable;
298 297
299 Node* receiver = assembler->Parameter(0); 298 Node* receiver = assembler->Parameter(0);
300 Node* position = assembler->Parameter(1); 299 Node* position = assembler->Parameter(1);
301 Node* context = assembler->Parameter(4); 300 Node* context = assembler->Parameter(4);
302 301
303 // Check that {receiver} is coercible to Object and convert it to a String. 302 // Check that {receiver} is coercible to Object and convert it to a String.
304 receiver = 303 receiver =
305 assembler->ToThisString(context, receiver, "String.prototype.charAt"); 304 assembler->ToThisString(context, receiver, "String.prototype.charAt");
306 305
307 // Convert the {position} to a Smi and check that it's in bounds of the 306 // Convert the {position} to a Smi and check that it's in bounds of the
308 // {receiver}. 307 // {receiver}.
309 // TODO(bmeurer): Find an abstraction for this!
310 { 308 {
311 // Check if the {position} is already a Smi. 309 Label return_emptystring(assembler, Label::kDeferred);
312 Variable var_position(assembler, MachineRepresentation::kTagged); 310 position = assembler->ToInteger(context, position,
313 var_position.Bind(position); 311 CodeStubAssembler::kTruncateMinusZero);
314 Label if_positionissmi(assembler), 312 assembler->GotoUnless(assembler->WordIsSmi(position), &return_emptystring);
315 if_positionisnotsmi(assembler, Label::kDeferred);
316 assembler->Branch(assembler->WordIsSmi(position), &if_positionissmi,
317 &if_positionisnotsmi);
318 assembler->Bind(&if_positionisnotsmi);
319 {
320 // Convert the {position} to an Integer via the ToIntegerStub.
321 Node* index = assembler->ToInteger(context, position);
322
323 // Check if the resulting {index} is now a Smi.
324 Label if_indexissmi(assembler, Label::kDeferred),
325 if_indexisnotsmi(assembler, Label::kDeferred);
326 assembler->Branch(assembler->WordIsSmi(index), &if_indexissmi,
327 &if_indexisnotsmi);
328
329 assembler->Bind(&if_indexissmi);
330 {
331 var_position.Bind(index);
332 assembler->Goto(&if_positionissmi);
333 }
334
335 assembler->Bind(&if_indexisnotsmi);
336 {
337 // The ToIntegerStub canonicalizes everything in Smi range to Smi
338 // representation, so any HeapNumber returned is not in Smi range.
339 // The only exception here is -0.0, which we treat as 0.
340 Node* index_value = assembler->LoadHeapNumberValue(index);
341 Label if_indexiszero(assembler, Label::kDeferred),
342 if_indexisnotzero(assembler, Label::kDeferred);
343 assembler->Branch(assembler->Float64Equal(
344 index_value, assembler->Float64Constant(0.0)),
345 &if_indexiszero, &if_indexisnotzero);
346
347 assembler->Bind(&if_indexiszero);
348 {
349 var_position.Bind(assembler->SmiConstant(Smi::FromInt(0)));
350 assembler->Goto(&if_positionissmi);
351 }
352
353 assembler->Bind(&if_indexisnotzero);
354 {
355 // The {index} is some other integral Number, that is definitely
356 // neither -0.0 nor in Smi range.
357 assembler->Return(assembler->EmptyStringConstant());
358 }
359 }
360 }
361 assembler->Bind(&if_positionissmi);
362 position = var_position.value();
363 313
364 // Determine the actual length of the {receiver} String. 314 // Determine the actual length of the {receiver} String.
365 Node* receiver_length = 315 Node* receiver_length =
366 assembler->LoadObjectField(receiver, String::kLengthOffset); 316 assembler->LoadObjectField(receiver, String::kLengthOffset);
367 317
368 // Return "" if the Smi {position} is outside the bounds of the {receiver}. 318 // Return "" if the Smi {position} is outside the bounds of the {receiver}.
369 Label if_positioninbounds(assembler), 319 Label if_positioninbounds(assembler);
370 if_positionnotinbounds(assembler, Label::kDeferred);
371 assembler->Branch(assembler->SmiAboveOrEqual(position, receiver_length), 320 assembler->Branch(assembler->SmiAboveOrEqual(position, receiver_length),
372 &if_positionnotinbounds, &if_positioninbounds); 321 &return_emptystring, &if_positioninbounds);
373 assembler->Bind(&if_positionnotinbounds); 322
323 assembler->Bind(&return_emptystring);
374 assembler->Return(assembler->EmptyStringConstant()); 324 assembler->Return(assembler->EmptyStringConstant());
325
375 assembler->Bind(&if_positioninbounds); 326 assembler->Bind(&if_positioninbounds);
376 } 327 }
377 328
378 // Load the character code at the {position} from the {receiver}. 329 // Load the character code at the {position} from the {receiver}.
379 Node* code = assembler->StringCharCodeAt(receiver, position); 330 Node* code = assembler->StringCharCodeAt(receiver, position);
380 331
381 // And return the single character string with only that {code}. 332 // And return the single character string with only that {code}.
382 Node* result = assembler->StringFromCharCode(code); 333 Node* result = assembler->StringFromCharCode(code);
383 assembler->Return(result); 334 assembler->Return(result);
384 } 335 }
385 336
386 // ES6 section 21.1.3.2 String.prototype.charCodeAt ( pos ) 337 // ES6 section 21.1.3.2 String.prototype.charCodeAt ( pos )
387 void Builtins::Generate_StringPrototypeCharCodeAt( 338 void Builtins::Generate_StringPrototypeCharCodeAt(
388 CodeStubAssembler* assembler) { 339 CodeStubAssembler* assembler) {
389 typedef CodeStubAssembler::Label Label; 340 typedef CodeStubAssembler::Label Label;
390 typedef compiler::Node Node; 341 typedef compiler::Node Node;
391 typedef CodeStubAssembler::Variable Variable;
392 342
393 Node* receiver = assembler->Parameter(0); 343 Node* receiver = assembler->Parameter(0);
394 Node* position = assembler->Parameter(1); 344 Node* position = assembler->Parameter(1);
395 Node* context = assembler->Parameter(4); 345 Node* context = assembler->Parameter(4);
396 346
397 // Check that {receiver} is coercible to Object and convert it to a String. 347 // Check that {receiver} is coercible to Object and convert it to a String.
398 receiver = 348 receiver =
399 assembler->ToThisString(context, receiver, "String.prototype.charCodeAt"); 349 assembler->ToThisString(context, receiver, "String.prototype.charCodeAt");
400 350
401 // Convert the {position} to a Smi and check that it's in bounds of the 351 // Convert the {position} to a Smi and check that it's in bounds of the
402 // {receiver}. 352 // {receiver}.
403 // TODO(bmeurer): Find an abstraction for this!
404 { 353 {
405 // Check if the {position} is already a Smi. 354 Label return_nan(assembler, Label::kDeferred);
406 Variable var_position(assembler, MachineRepresentation::kTagged); 355 position = assembler->ToInteger(context, position,
407 var_position.Bind(position); 356 CodeStubAssembler::kTruncateMinusZero);
408 Label if_positionissmi(assembler), 357 assembler->GotoUnless(assembler->WordIsSmi(position), &return_nan);
409 if_positionisnotsmi(assembler, Label::kDeferred);
410 assembler->Branch(assembler->WordIsSmi(position), &if_positionissmi,
411 &if_positionisnotsmi);
412 assembler->Bind(&if_positionisnotsmi);
413 {
414 // Convert the {position} to an Integer via the ToIntegerStub.
415 Node* index = assembler->ToInteger(context, position);
416
417 // Check if the resulting {index} is now a Smi.
418 Label if_indexissmi(assembler, Label::kDeferred),
419 if_indexisnotsmi(assembler, Label::kDeferred);
420 assembler->Branch(assembler->WordIsSmi(index), &if_indexissmi,
421 &if_indexisnotsmi);
422
423 assembler->Bind(&if_indexissmi);
424 {
425 var_position.Bind(index);
426 assembler->Goto(&if_positionissmi);
427 }
428
429 assembler->Bind(&if_indexisnotsmi);
430 {
431 // The ToIntegerStub canonicalizes everything in Smi range to Smi
432 // representation, so any HeapNumber returned is not in Smi range.
433 // The only exception here is -0.0, which we treat as 0.
434 Node* index_value = assembler->LoadHeapNumberValue(index);
435 Label if_indexiszero(assembler, Label::kDeferred),
436 if_indexisnotzero(assembler, Label::kDeferred);
437 assembler->Branch(assembler->Float64Equal(
438 index_value, assembler->Float64Constant(0.0)),
439 &if_indexiszero, &if_indexisnotzero);
440
441 assembler->Bind(&if_indexiszero);
442 {
443 var_position.Bind(assembler->SmiConstant(Smi::FromInt(0)));
444 assembler->Goto(&if_positionissmi);
445 }
446
447 assembler->Bind(&if_indexisnotzero);
448 {
449 // The {index} is some other integral Number, that is definitely
450 // neither -0.0 nor in Smi range.
451 assembler->Return(assembler->NaNConstant());
452 }
453 }
454 }
455 assembler->Bind(&if_positionissmi);
456 position = var_position.value();
457 358
458 // Determine the actual length of the {receiver} String. 359 // Determine the actual length of the {receiver} String.
459 Node* receiver_length = 360 Node* receiver_length =
460 assembler->LoadObjectField(receiver, String::kLengthOffset); 361 assembler->LoadObjectField(receiver, String::kLengthOffset);
461 362
462 // Return NaN if the Smi {position} is outside the bounds of the {receiver}. 363 // Return NaN if the Smi {position} is outside the bounds of the {receiver}.
463 Label if_positioninbounds(assembler), 364 Label if_positioninbounds(assembler);
464 if_positionnotinbounds(assembler, Label::kDeferred);
465 assembler->Branch(assembler->SmiAboveOrEqual(position, receiver_length), 365 assembler->Branch(assembler->SmiAboveOrEqual(position, receiver_length),
466 &if_positionnotinbounds, &if_positioninbounds); 366 &return_nan, &if_positioninbounds);
467 assembler->Bind(&if_positionnotinbounds); 367
368 assembler->Bind(&return_nan);
468 assembler->Return(assembler->NaNConstant()); 369 assembler->Return(assembler->NaNConstant());
370
469 assembler->Bind(&if_positioninbounds); 371 assembler->Bind(&if_positioninbounds);
470 } 372 }
471 373
472 // Load the character at the {position} from the {receiver}. 374 // Load the character at the {position} from the {receiver}.
473 Node* value = assembler->StringCharCodeAt(receiver, position); 375 Node* value = assembler->StringCharCodeAt(receiver, position);
474 Node* result = assembler->SmiFromWord32(value); 376 Node* result = assembler->SmiFromWord32(value);
475 assembler->Return(result); 377 assembler->Return(result);
476 } 378 }
477 379
478 // ES6 section 21.1.3.9 380 // ES6 section 21.1.3.9
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after
663 } 565 }
664 566
665 iterator->set_string(isolate->heap()->empty_string()); 567 iterator->set_string(isolate->heap()->empty_string());
666 568
667 return *isolate->factory()->NewJSIteratorResult( 569 return *isolate->factory()->NewJSIteratorResult(
668 isolate->factory()->undefined_value(), true); 570 isolate->factory()->undefined_value(), true);
669 } 571 }
670 572
671 } // namespace internal 573 } // namespace internal
672 } // namespace v8 574 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | src/code-stub-assembler.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698