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

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

Issue 2498073002: [refactoring] Split CodeAssemblerState out of CodeAssembler (Closed)
Patch Set: one more attempt Created 4 years, 1 month 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-sharedarraybuffer.cc ('k') | src/builtins/builtins-symbol.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.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 #include "src/regexp/regexp-utils.h" 9 #include "src/regexp/regexp-utils.h"
10 10
(...skipping 364 matching lines...) Expand 10 before | Expand all | Expand 10 after
375 case RelationalComparisonMode::kGreaterThan: 375 case RelationalComparisonMode::kGreaterThan:
376 case RelationalComparisonMode::kGreaterThanOrEqual: 376 case RelationalComparisonMode::kGreaterThanOrEqual:
377 assembler->Return(assembler->BooleanConstant(true)); 377 assembler->Return(assembler->BooleanConstant(true));
378 break; 378 break;
379 } 379 }
380 } 380 }
381 381
382 } // namespace 382 } // namespace
383 383
384 // static 384 // static
385 void Builtins::Generate_StringEqual(CodeStubAssembler* assembler) { 385 void Builtins::Generate_StringEqual(compiler::CodeAssemblerState* state) {
386 GenerateStringEqual(assembler, ResultMode::kDontNegateResult); 386 CodeStubAssembler assembler(state);
387 GenerateStringEqual(&assembler, ResultMode::kDontNegateResult);
387 } 388 }
388 389
389 // static 390 // static
390 void Builtins::Generate_StringNotEqual(CodeStubAssembler* assembler) { 391 void Builtins::Generate_StringNotEqual(compiler::CodeAssemblerState* state) {
391 GenerateStringEqual(assembler, ResultMode::kNegateResult); 392 CodeStubAssembler assembler(state);
393 GenerateStringEqual(&assembler, ResultMode::kNegateResult);
392 } 394 }
393 395
394 // static 396 // static
395 void Builtins::Generate_StringLessThan(CodeStubAssembler* assembler) { 397 void Builtins::Generate_StringLessThan(compiler::CodeAssemblerState* state) {
396 GenerateStringRelationalComparison(assembler, 398 CodeStubAssembler assembler(state);
399 GenerateStringRelationalComparison(&assembler,
397 RelationalComparisonMode::kLessThan); 400 RelationalComparisonMode::kLessThan);
398 } 401 }
399 402
400 // static 403 // static
401 void Builtins::Generate_StringLessThanOrEqual(CodeStubAssembler* assembler) { 404 void Builtins::Generate_StringLessThanOrEqual(
405 compiler::CodeAssemblerState* state) {
406 CodeStubAssembler assembler(state);
402 GenerateStringRelationalComparison( 407 GenerateStringRelationalComparison(
403 assembler, RelationalComparisonMode::kLessThanOrEqual); 408 &assembler, RelationalComparisonMode::kLessThanOrEqual);
404 } 409 }
405 410
406 // static 411 // static
407 void Builtins::Generate_StringGreaterThan(CodeStubAssembler* assembler) { 412 void Builtins::Generate_StringGreaterThan(compiler::CodeAssemblerState* state) {
408 GenerateStringRelationalComparison(assembler, 413 CodeStubAssembler assembler(state);
414 GenerateStringRelationalComparison(&assembler,
409 RelationalComparisonMode::kGreaterThan); 415 RelationalComparisonMode::kGreaterThan);
410 } 416 }
411 417
412 // static 418 // static
413 void Builtins::Generate_StringGreaterThanOrEqual(CodeStubAssembler* assembler) { 419 void Builtins::Generate_StringGreaterThanOrEqual(
420 compiler::CodeAssemblerState* state) {
421 CodeStubAssembler assembler(state);
414 GenerateStringRelationalComparison( 422 GenerateStringRelationalComparison(
415 assembler, RelationalComparisonMode::kGreaterThanOrEqual); 423 &assembler, RelationalComparisonMode::kGreaterThanOrEqual);
416 } 424 }
417 425
418 // ----------------------------------------------------------------------------- 426 // -----------------------------------------------------------------------------
419 // ES6 section 21.1 String Objects 427 // ES6 section 21.1 String Objects
420 428
421 // ES6 section 21.1.2.1 String.fromCharCode ( ...codeUnits ) 429 // ES6 section 21.1.2.1 String.fromCharCode ( ...codeUnits )
422 void Builtins::Generate_StringFromCharCode(CodeStubAssembler* assembler) { 430 void Builtins::Generate_StringFromCharCode(
431 compiler::CodeAssemblerState* state) {
423 typedef CodeStubAssembler::Label Label; 432 typedef CodeStubAssembler::Label Label;
424 typedef compiler::Node Node; 433 typedef compiler::Node Node;
425 typedef CodeStubAssembler::Variable Variable; 434 typedef CodeStubAssembler::Variable Variable;
435 CodeStubAssembler assembler(state);
426 436
427 Node* argc = assembler->ChangeInt32ToIntPtr( 437 Node* argc = assembler.ChangeInt32ToIntPtr(
428 assembler->Parameter(BuiltinDescriptor::kArgumentsCount)); 438 assembler.Parameter(BuiltinDescriptor::kArgumentsCount));
429 Node* context = assembler->Parameter(BuiltinDescriptor::kContext); 439 Node* context = assembler.Parameter(BuiltinDescriptor::kContext);
430 440
431 CodeStubArguments arguments(assembler, argc); 441 CodeStubArguments arguments(&assembler, argc);
432 442
433 // Check if we have exactly one argument (plus the implicit receiver), i.e. 443 // Check if we have exactly one argument (plus the implicit receiver), i.e.
434 // if the parent frame is not an arguments adaptor frame. 444 // if the parent frame is not an arguments adaptor frame.
435 Label if_oneargument(assembler), if_notoneargument(assembler); 445 Label if_oneargument(&assembler), if_notoneargument(&assembler);
436 assembler->Branch(assembler->WordEqual(argc, assembler->IntPtrConstant(1)), 446 assembler.Branch(assembler.WordEqual(argc, assembler.IntPtrConstant(1)),
437 &if_oneargument, &if_notoneargument); 447 &if_oneargument, &if_notoneargument);
438 448
439 assembler->Bind(&if_oneargument); 449 assembler.Bind(&if_oneargument);
440 { 450 {
441 // Single argument case, perform fast single character string cache lookup 451 // Single argument case, perform fast single character string cache lookup
442 // for one-byte code units, or fall back to creating a single character 452 // for one-byte code units, or fall back to creating a single character
443 // string on the fly otherwise. 453 // string on the fly otherwise.
444 Node* code = arguments.AtIndex(0); 454 Node* code = arguments.AtIndex(0);
445 Node* code32 = assembler->TruncateTaggedToWord32(context, code); 455 Node* code32 = assembler.TruncateTaggedToWord32(context, code);
446 Node* code16 = assembler->Word32And( 456 Node* code16 = assembler.Word32And(
447 code32, assembler->Int32Constant(String::kMaxUtf16CodeUnit)); 457 code32, assembler.Int32Constant(String::kMaxUtf16CodeUnit));
448 Node* result = assembler->StringFromCharCode(code16); 458 Node* result = assembler.StringFromCharCode(code16);
449 arguments.PopAndReturn(result); 459 arguments.PopAndReturn(result);
450 } 460 }
451 461
452 Node* code16 = nullptr; 462 Node* code16 = nullptr;
453 assembler->Bind(&if_notoneargument); 463 assembler.Bind(&if_notoneargument);
454 { 464 {
455 Label two_byte(assembler); 465 Label two_byte(&assembler);
456 // Assume that the resulting string contains only one-byte characters. 466 // Assume that the resulting string contains only one-byte characters.
457 Node* one_byte_result = assembler->AllocateSeqOneByteString(context, argc); 467 Node* one_byte_result = assembler.AllocateSeqOneByteString(context, argc);
458 468
459 Variable max_index(assembler, MachineType::PointerRepresentation()); 469 Variable max_index(&assembler, MachineType::PointerRepresentation());
460 max_index.Bind(assembler->IntPtrConstant(0)); 470 max_index.Bind(assembler.IntPtrConstant(0));
461 471
462 // Iterate over the incoming arguments, converting them to 8-bit character 472 // Iterate over the incoming arguments, converting them to 8-bit character
463 // codes. Stop if any of the conversions generates a code that doesn't fit 473 // codes. Stop if any of the conversions generates a code that doesn't fit
464 // in 8 bits. 474 // in 8 bits.
465 CodeStubAssembler::VariableList vars({&max_index}, assembler->zone()); 475 CodeStubAssembler::VariableList vars({&max_index}, assembler.zone());
466 arguments.ForEach(vars, [context, &two_byte, &max_index, &code16, 476 arguments.ForEach(vars, [context, &two_byte, &max_index, &code16,
467 one_byte_result](CodeStubAssembler* assembler, 477 one_byte_result](CodeStubAssembler* assembler,
468 Node* arg) { 478 Node* arg) {
469 Node* code32 = assembler->TruncateTaggedToWord32(context, arg); 479 Node* code32 = assembler->TruncateTaggedToWord32(context, arg);
470 code16 = assembler->Word32And( 480 code16 = assembler->Word32And(
471 code32, assembler->Int32Constant(String::kMaxUtf16CodeUnit)); 481 code32, assembler->Int32Constant(String::kMaxUtf16CodeUnit));
472 482
473 assembler->GotoIf( 483 assembler->GotoIf(
474 assembler->Int32GreaterThan( 484 assembler->Int32GreaterThan(
475 code16, assembler->Int32Constant(String::kMaxOneByteCharCode)), 485 code16, assembler->Int32Constant(String::kMaxOneByteCharCode)),
476 &two_byte); 486 &two_byte);
477 487
478 // The {code16} fits into the SeqOneByteString {one_byte_result}. 488 // The {code16} fits into the SeqOneByteString {one_byte_result}.
479 Node* offset = assembler->ElementOffsetFromIndex( 489 Node* offset = assembler->ElementOffsetFromIndex(
480 max_index.value(), UINT8_ELEMENTS, 490 max_index.value(), UINT8_ELEMENTS,
481 CodeStubAssembler::INTPTR_PARAMETERS, 491 CodeStubAssembler::INTPTR_PARAMETERS,
482 SeqOneByteString::kHeaderSize - kHeapObjectTag); 492 SeqOneByteString::kHeaderSize - kHeapObjectTag);
483 assembler->StoreNoWriteBarrier(MachineRepresentation::kWord8, 493 assembler->StoreNoWriteBarrier(MachineRepresentation::kWord8,
484 one_byte_result, offset, code16); 494 one_byte_result, offset, code16);
485 max_index.Bind(assembler->IntPtrAdd(max_index.value(), 495 max_index.Bind(assembler->IntPtrAdd(max_index.value(),
486 assembler->IntPtrConstant(1))); 496 assembler->IntPtrConstant(1)));
487 }); 497 });
488 arguments.PopAndReturn(one_byte_result); 498 arguments.PopAndReturn(one_byte_result);
489 499
490 assembler->Bind(&two_byte); 500 assembler.Bind(&two_byte);
491 501
492 // At least one of the characters in the string requires a 16-bit 502 // At least one of the characters in the string requires a 16-bit
493 // representation. Allocate a SeqTwoByteString to hold the resulting 503 // representation. Allocate a SeqTwoByteString to hold the resulting
494 // string. 504 // string.
495 Node* two_byte_result = assembler->AllocateSeqTwoByteString(context, argc); 505 Node* two_byte_result = assembler.AllocateSeqTwoByteString(context, argc);
496 506
497 // Copy the characters that have already been put in the 8-bit string into 507 // Copy the characters that have already been put in the 8-bit string into
498 // their corresponding positions in the new 16-bit string. 508 // their corresponding positions in the new 16-bit string.
499 Node* zero = assembler->IntPtrConstant(0); 509 Node* zero = assembler.IntPtrConstant(0);
500 assembler->CopyStringCharacters( 510 assembler.CopyStringCharacters(one_byte_result, two_byte_result, zero, zero,
501 one_byte_result, two_byte_result, zero, zero, max_index.value(), 511 max_index.value(), String::ONE_BYTE_ENCODING,
502 String::ONE_BYTE_ENCODING, String::TWO_BYTE_ENCODING, 512 String::TWO_BYTE_ENCODING,
503 CodeStubAssembler::INTPTR_PARAMETERS); 513 CodeStubAssembler::INTPTR_PARAMETERS);
504 514
505 // Write the character that caused the 8-bit to 16-bit fault. 515 // Write the character that caused the 8-bit to 16-bit fault.
506 Node* max_index_offset = assembler->ElementOffsetFromIndex( 516 Node* max_index_offset = assembler.ElementOffsetFromIndex(
507 max_index.value(), UINT16_ELEMENTS, 517 max_index.value(), UINT16_ELEMENTS,
508 CodeStubAssembler::INTPTR_PARAMETERS, 518 CodeStubAssembler::INTPTR_PARAMETERS,
509 SeqTwoByteString::kHeaderSize - kHeapObjectTag); 519 SeqTwoByteString::kHeaderSize - kHeapObjectTag);
510 assembler->StoreNoWriteBarrier(MachineRepresentation::kWord16, 520 assembler.StoreNoWriteBarrier(MachineRepresentation::kWord16,
511 two_byte_result, max_index_offset, code16); 521 two_byte_result, max_index_offset, code16);
512 max_index.Bind( 522 max_index.Bind(
513 assembler->IntPtrAdd(max_index.value(), assembler->IntPtrConstant(1))); 523 assembler.IntPtrAdd(max_index.value(), assembler.IntPtrConstant(1)));
514 524
515 // Resume copying the passed-in arguments from the same place where the 525 // Resume copying the passed-in arguments from the same place where the
516 // 8-bit copy stopped, but this time copying over all of the characters 526 // 8-bit copy stopped, but this time copying over all of the characters
517 // using a 16-bit representation. 527 // using a 16-bit representation.
518 arguments.ForEach( 528 arguments.ForEach(
519 vars, 529 vars,
520 [context, two_byte_result, &max_index](CodeStubAssembler* assembler, 530 [context, two_byte_result, &max_index](CodeStubAssembler* assembler,
521 Node* arg) { 531 Node* arg) {
522 Node* code32 = assembler->TruncateTaggedToWord32(context, arg); 532 Node* code32 = assembler->TruncateTaggedToWord32(context, arg);
523 Node* code16 = assembler->Word32And( 533 Node* code16 = assembler->Word32And(
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
625 635
626 CopyChars(result->GetChars(), one_byte_buffer.ToConstVector().start(), 636 CopyChars(result->GetChars(), one_byte_buffer.ToConstVector().start(),
627 one_byte_buffer.length()); 637 one_byte_buffer.length());
628 CopyChars(result->GetChars() + one_byte_buffer.length(), 638 CopyChars(result->GetChars() + one_byte_buffer.length(),
629 two_byte_buffer.ToConstVector().start(), two_byte_buffer.length()); 639 two_byte_buffer.ToConstVector().start(), two_byte_buffer.length());
630 640
631 return *result; 641 return *result;
632 } 642 }
633 643
634 // ES6 section 21.1.3.1 String.prototype.charAt ( pos ) 644 // ES6 section 21.1.3.1 String.prototype.charAt ( pos )
635 void Builtins::Generate_StringPrototypeCharAt(CodeStubAssembler* assembler) { 645 void Builtins::Generate_StringPrototypeCharAt(
646 compiler::CodeAssemblerState* state) {
636 typedef CodeStubAssembler::Label Label; 647 typedef CodeStubAssembler::Label Label;
637 typedef compiler::Node Node; 648 typedef compiler::Node Node;
649 CodeStubAssembler assembler(state);
638 650
639 Node* receiver = assembler->Parameter(0); 651 Node* receiver = assembler.Parameter(0);
640 Node* position = assembler->Parameter(1); 652 Node* position = assembler.Parameter(1);
641 Node* context = assembler->Parameter(4); 653 Node* context = assembler.Parameter(4);
642 654
643 // Check that {receiver} is coercible to Object and convert it to a String. 655 // Check that {receiver} is coercible to Object and convert it to a String.
644 receiver = 656 receiver =
645 assembler->ToThisString(context, receiver, "String.prototype.charAt"); 657 assembler.ToThisString(context, receiver, "String.prototype.charAt");
646 658
647 // Convert the {position} to a Smi and check that it's in bounds of the 659 // Convert the {position} to a Smi and check that it's in bounds of the
648 // {receiver}. 660 // {receiver}.
649 { 661 {
650 Label return_emptystring(assembler, Label::kDeferred); 662 Label return_emptystring(&assembler, Label::kDeferred);
651 position = assembler->ToInteger(context, position, 663 position = assembler.ToInteger(context, position,
652 CodeStubAssembler::kTruncateMinusZero); 664 CodeStubAssembler::kTruncateMinusZero);
653 assembler->GotoUnless(assembler->TaggedIsSmi(position), 665 assembler.GotoUnless(assembler.TaggedIsSmi(position), &return_emptystring);
654 &return_emptystring);
655 666
656 // Determine the actual length of the {receiver} String. 667 // Determine the actual length of the {receiver} String.
657 Node* receiver_length = 668 Node* receiver_length =
658 assembler->LoadObjectField(receiver, String::kLengthOffset); 669 assembler.LoadObjectField(receiver, String::kLengthOffset);
659 670
660 // Return "" if the Smi {position} is outside the bounds of the {receiver}. 671 // Return "" if the Smi {position} is outside the bounds of the {receiver}.
661 Label if_positioninbounds(assembler); 672 Label if_positioninbounds(&assembler);
662 assembler->Branch(assembler->SmiAboveOrEqual(position, receiver_length), 673 assembler.Branch(assembler.SmiAboveOrEqual(position, receiver_length),
663 &return_emptystring, &if_positioninbounds); 674 &return_emptystring, &if_positioninbounds);
664 675
665 assembler->Bind(&return_emptystring); 676 assembler.Bind(&return_emptystring);
666 assembler->Return(assembler->EmptyStringConstant()); 677 assembler.Return(assembler.EmptyStringConstant());
667 678
668 assembler->Bind(&if_positioninbounds); 679 assembler.Bind(&if_positioninbounds);
669 } 680 }
670 681
671 // Load the character code at the {position} from the {receiver}. 682 // Load the character code at the {position} from the {receiver}.
672 Node* code = assembler->StringCharCodeAt(receiver, position); 683 Node* code = assembler.StringCharCodeAt(receiver, position);
673 684
674 // And return the single character string with only that {code}. 685 // And return the single character string with only that {code}.
675 Node* result = assembler->StringFromCharCode(code); 686 Node* result = assembler.StringFromCharCode(code);
676 assembler->Return(result); 687 assembler.Return(result);
677 } 688 }
678 689
679 // ES6 section 21.1.3.2 String.prototype.charCodeAt ( pos ) 690 // ES6 section 21.1.3.2 String.prototype.charCodeAt ( pos )
680 void Builtins::Generate_StringPrototypeCharCodeAt( 691 void Builtins::Generate_StringPrototypeCharCodeAt(
681 CodeStubAssembler* assembler) { 692 compiler::CodeAssemblerState* state) {
682 typedef CodeStubAssembler::Label Label; 693 typedef CodeStubAssembler::Label Label;
683 typedef compiler::Node Node; 694 typedef compiler::Node Node;
695 CodeStubAssembler assembler(state);
684 696
685 Node* receiver = assembler->Parameter(0); 697 Node* receiver = assembler.Parameter(0);
686 Node* position = assembler->Parameter(1); 698 Node* position = assembler.Parameter(1);
687 Node* context = assembler->Parameter(4); 699 Node* context = assembler.Parameter(4);
688 700
689 // Check that {receiver} is coercible to Object and convert it to a String. 701 // Check that {receiver} is coercible to Object and convert it to a String.
690 receiver = 702 receiver =
691 assembler->ToThisString(context, receiver, "String.prototype.charCodeAt"); 703 assembler.ToThisString(context, receiver, "String.prototype.charCodeAt");
692 704
693 // Convert the {position} to a Smi and check that it's in bounds of the 705 // Convert the {position} to a Smi and check that it's in bounds of the
694 // {receiver}. 706 // {receiver}.
695 { 707 {
696 Label return_nan(assembler, Label::kDeferred); 708 Label return_nan(&assembler, Label::kDeferred);
697 position = assembler->ToInteger(context, position, 709 position = assembler.ToInteger(context, position,
698 CodeStubAssembler::kTruncateMinusZero); 710 CodeStubAssembler::kTruncateMinusZero);
699 assembler->GotoUnless(assembler->TaggedIsSmi(position), &return_nan); 711 assembler.GotoUnless(assembler.TaggedIsSmi(position), &return_nan);
700 712
701 // Determine the actual length of the {receiver} String. 713 // Determine the actual length of the {receiver} String.
702 Node* receiver_length = 714 Node* receiver_length =
703 assembler->LoadObjectField(receiver, String::kLengthOffset); 715 assembler.LoadObjectField(receiver, String::kLengthOffset);
704 716
705 // Return NaN if the Smi {position} is outside the bounds of the {receiver}. 717 // Return NaN if the Smi {position} is outside the bounds of the {receiver}.
706 Label if_positioninbounds(assembler); 718 Label if_positioninbounds(&assembler);
707 assembler->Branch(assembler->SmiAboveOrEqual(position, receiver_length), 719 assembler.Branch(assembler.SmiAboveOrEqual(position, receiver_length),
708 &return_nan, &if_positioninbounds); 720 &return_nan, &if_positioninbounds);
709 721
710 assembler->Bind(&return_nan); 722 assembler.Bind(&return_nan);
711 assembler->Return(assembler->NaNConstant()); 723 assembler.Return(assembler.NaNConstant());
712 724
713 assembler->Bind(&if_positioninbounds); 725 assembler.Bind(&if_positioninbounds);
714 } 726 }
715 727
716 // Load the character at the {position} from the {receiver}. 728 // Load the character at the {position} from the {receiver}.
717 Node* value = assembler->StringCharCodeAt(receiver, position); 729 Node* value = assembler.StringCharCodeAt(receiver, position);
718 Node* result = assembler->SmiFromWord32(value); 730 Node* result = assembler.SmiFromWord32(value);
719 assembler->Return(result); 731 assembler.Return(result);
720 } 732 }
721 733
722 // ES6 section 21.1.3.6 734 // ES6 section 21.1.3.6
723 // String.prototype.endsWith ( searchString [ , endPosition ] ) 735 // String.prototype.endsWith ( searchString [ , endPosition ] )
724 BUILTIN(StringPrototypeEndsWith) { 736 BUILTIN(StringPrototypeEndsWith) {
725 HandleScope handle_scope(isolate); 737 HandleScope handle_scope(isolate);
726 TO_THIS_STRING(str, "String.prototype.endsWith"); 738 TO_THIS_STRING(str, "String.prototype.endsWith");
727 739
728 // Check if the search string is a regExp and fail if it is. 740 // Check if the search string is a regExp and fail if it is.
729 Handle<Object> search = args.atOrUndefined(isolate, 1); 741 Handle<Object> search = args.atOrUndefined(isolate, 1);
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
901 isolate->factory()->NewStringFromStaticChars("NFC, NFD, NFKC, NFKD"); 913 isolate->factory()->NewStringFromStaticChars("NFC, NFD, NFKC, NFKD");
902 THROW_NEW_ERROR_RETURN_FAILURE( 914 THROW_NEW_ERROR_RETURN_FAILURE(
903 isolate, 915 isolate,
904 NewRangeError(MessageTemplate::kNormalizationForm, valid_forms)); 916 NewRangeError(MessageTemplate::kNormalizationForm, valid_forms));
905 } 917 }
906 918
907 return *string; 919 return *string;
908 } 920 }
909 921
910 // ES6 section B.2.3.1 String.prototype.substr ( start, length ) 922 // ES6 section B.2.3.1 String.prototype.substr ( start, length )
911 void Builtins::Generate_StringPrototypeSubstr(CodeStubAssembler* a) { 923 void Builtins::Generate_StringPrototypeSubstr(
924 compiler::CodeAssemblerState* state) {
912 typedef CodeStubAssembler::Label Label; 925 typedef CodeStubAssembler::Label Label;
913 typedef compiler::Node Node; 926 typedef compiler::Node Node;
914 typedef CodeStubAssembler::Variable Variable; 927 typedef CodeStubAssembler::Variable Variable;
928 CodeStubAssembler a(state);
915 929
916 Label out(a), handle_length(a); 930 Label out(&a), handle_length(&a);
917 931
918 Variable var_start(a, MachineRepresentation::kTagged); 932 Variable var_start(&a, MachineRepresentation::kTagged);
919 Variable var_length(a, MachineRepresentation::kTagged); 933 Variable var_length(&a, MachineRepresentation::kTagged);
920 934
921 Node* const receiver = a->Parameter(0); 935 Node* const receiver = a.Parameter(0);
922 Node* const start = a->Parameter(1); 936 Node* const start = a.Parameter(1);
923 Node* const length = a->Parameter(2); 937 Node* const length = a.Parameter(2);
924 Node* const context = a->Parameter(5); 938 Node* const context = a.Parameter(5);
925 939
926 Node* const zero = a->SmiConstant(Smi::kZero); 940 Node* const zero = a.SmiConstant(Smi::kZero);
927 941
928 // Check that {receiver} is coercible to Object and convert it to a String. 942 // Check that {receiver} is coercible to Object and convert it to a String.
929 Node* const string = 943 Node* const string =
930 a->ToThisString(context, receiver, "String.prototype.substr"); 944 a.ToThisString(context, receiver, "String.prototype.substr");
931 945
932 Node* const string_length = a->LoadStringLength(string); 946 Node* const string_length = a.LoadStringLength(string);
933 947
934 // Conversions and bounds-checks for {start}. 948 // Conversions and bounds-checks for {start}.
935 { 949 {
936 Node* const start_int = 950 Node* const start_int =
937 a->ToInteger(context, start, CodeStubAssembler::kTruncateMinusZero); 951 a.ToInteger(context, start, CodeStubAssembler::kTruncateMinusZero);
938 952
939 Label if_issmi(a), if_isheapnumber(a, Label::kDeferred); 953 Label if_issmi(&a), if_isheapnumber(&a, Label::kDeferred);
940 a->Branch(a->TaggedIsSmi(start_int), &if_issmi, &if_isheapnumber); 954 a.Branch(a.TaggedIsSmi(start_int), &if_issmi, &if_isheapnumber);
941 955
942 a->Bind(&if_issmi); 956 a.Bind(&if_issmi);
943 { 957 {
944 Node* const length_plus_start = a->SmiAdd(string_length, start_int); 958 Node* const length_plus_start = a.SmiAdd(string_length, start_int);
945 var_start.Bind(a->Select(a->SmiLessThan(start_int, zero), 959 var_start.Bind(a.Select(a.SmiLessThan(start_int, zero),
946 a->SmiMax(length_plus_start, zero), start_int)); 960 a.SmiMax(length_plus_start, zero), start_int));
947 a->Goto(&handle_length); 961 a.Goto(&handle_length);
948 } 962 }
949 963
950 a->Bind(&if_isheapnumber); 964 a.Bind(&if_isheapnumber);
951 { 965 {
952 // If {start} is a heap number, it is definitely out of bounds. If it is 966 // If {start} is a heap number, it is definitely out of bounds. If it is
953 // negative, {start} = max({string_length} + {start}),0) = 0'. If it is 967 // negative, {start} = max({string_length} + {start}),0) = 0'. If it is
954 // positive, set {start} to {string_length} which ultimately results in 968 // positive, set {start} to {string_length} which ultimately results in
955 // returning an empty string. 969 // returning an empty string.
956 Node* const float_zero = a->Float64Constant(0.); 970 Node* const float_zero = a.Float64Constant(0.);
957 Node* const start_float = a->LoadHeapNumberValue(start_int); 971 Node* const start_float = a.LoadHeapNumberValue(start_int);
958 var_start.Bind(a->Select(a->Float64LessThan(start_float, float_zero), 972 var_start.Bind(a.Select(a.Float64LessThan(start_float, float_zero), zero,
959 zero, string_length)); 973 string_length));
960 a->Goto(&handle_length); 974 a.Goto(&handle_length);
961 } 975 }
962 } 976 }
963 977
964 // Conversions and bounds-checks for {length}. 978 // Conversions and bounds-checks for {length}.
965 a->Bind(&handle_length); 979 a.Bind(&handle_length);
966 { 980 {
967 Label if_issmi(a), if_isheapnumber(a, Label::kDeferred); 981 Label if_issmi(&a), if_isheapnumber(&a, Label::kDeferred);
968 982
969 // Default to {string_length} if {length} is undefined. 983 // Default to {string_length} if {length} is undefined.
970 { 984 {
971 Label if_isundefined(a, Label::kDeferred), if_isnotundefined(a); 985 Label if_isundefined(&a, Label::kDeferred), if_isnotundefined(&a);
972 a->Branch(a->WordEqual(length, a->UndefinedConstant()), &if_isundefined, 986 a.Branch(a.WordEqual(length, a.UndefinedConstant()), &if_isundefined,
973 &if_isnotundefined); 987 &if_isnotundefined);
974 988
975 a->Bind(&if_isundefined); 989 a.Bind(&if_isundefined);
976 var_length.Bind(string_length); 990 var_length.Bind(string_length);
977 a->Goto(&if_issmi); 991 a.Goto(&if_issmi);
978 992
979 a->Bind(&if_isnotundefined); 993 a.Bind(&if_isnotundefined);
980 var_length.Bind( 994 var_length.Bind(
981 a->ToInteger(context, length, CodeStubAssembler::kTruncateMinusZero)); 995 a.ToInteger(context, length, CodeStubAssembler::kTruncateMinusZero));
982 } 996 }
983 997
984 a->Branch(a->TaggedIsSmi(var_length.value()), &if_issmi, &if_isheapnumber); 998 a.Branch(a.TaggedIsSmi(var_length.value()), &if_issmi, &if_isheapnumber);
985 999
986 // Set {length} to min(max({length}, 0), {string_length} - {start} 1000 // Set {length} to min(max({length}, 0), {string_length} - {start}
987 a->Bind(&if_issmi); 1001 a.Bind(&if_issmi);
988 { 1002 {
989 Node* const positive_length = a->SmiMax(var_length.value(), zero); 1003 Node* const positive_length = a.SmiMax(var_length.value(), zero);
990 1004
991 Node* const minimal_length = a->SmiSub(string_length, var_start.value()); 1005 Node* const minimal_length = a.SmiSub(string_length, var_start.value());
992 var_length.Bind(a->SmiMin(positive_length, minimal_length)); 1006 var_length.Bind(a.SmiMin(positive_length, minimal_length));
993 1007
994 a->GotoUnless(a->SmiLessThanOrEqual(var_length.value(), zero), &out); 1008 a.GotoUnless(a.SmiLessThanOrEqual(var_length.value(), zero), &out);
995 a->Return(a->EmptyStringConstant()); 1009 a.Return(a.EmptyStringConstant());
996 } 1010 }
997 1011
998 a->Bind(&if_isheapnumber); 1012 a.Bind(&if_isheapnumber);
999 { 1013 {
1000 // If {length} is a heap number, it is definitely out of bounds. There are 1014 // If {length} is a heap number, it is definitely out of bounds. There are
1001 // two cases according to the spec: if it is negative, "" is returned; if 1015 // two cases according to the spec: if it is negative, "" is returned; if
1002 // it is positive, then length is set to {string_length} - {start}. 1016 // it is positive, then length is set to {string_length} - {start}.
1003 1017
1004 CSA_ASSERT(a, a->WordEqual(a->LoadMap(var_length.value()), 1018 CSA_ASSERT(&a, a.WordEqual(a.LoadMap(var_length.value()),
1005 a->HeapNumberMapConstant())); 1019 a.HeapNumberMapConstant()));
1006 1020
1007 Label if_isnegative(a), if_ispositive(a); 1021 Label if_isnegative(&a), if_ispositive(&a);
1008 Node* const float_zero = a->Float64Constant(0.); 1022 Node* const float_zero = a.Float64Constant(0.);
1009 Node* const length_float = a->LoadHeapNumberValue(var_length.value()); 1023 Node* const length_float = a.LoadHeapNumberValue(var_length.value());
1010 a->Branch(a->Float64LessThan(length_float, float_zero), &if_isnegative, 1024 a.Branch(a.Float64LessThan(length_float, float_zero), &if_isnegative,
1011 &if_ispositive); 1025 &if_ispositive);
1012 1026
1013 a->Bind(&if_isnegative); 1027 a.Bind(&if_isnegative);
1014 a->Return(a->EmptyStringConstant()); 1028 a.Return(a.EmptyStringConstant());
1015 1029
1016 a->Bind(&if_ispositive); 1030 a.Bind(&if_ispositive);
1017 { 1031 {
1018 var_length.Bind(a->SmiSub(string_length, var_start.value())); 1032 var_length.Bind(a.SmiSub(string_length, var_start.value()));
1019 a->GotoUnless(a->SmiLessThanOrEqual(var_length.value(), zero), &out); 1033 a.GotoUnless(a.SmiLessThanOrEqual(var_length.value(), zero), &out);
1020 a->Return(a->EmptyStringConstant()); 1034 a.Return(a.EmptyStringConstant());
1021 } 1035 }
1022 } 1036 }
1023 } 1037 }
1024 1038
1025 a->Bind(&out); 1039 a.Bind(&out);
1026 { 1040 {
1027 Node* const end = a->SmiAdd(var_start.value(), var_length.value()); 1041 Node* const end = a.SmiAdd(var_start.value(), var_length.value());
1028 Node* const result = a->SubString(context, string, var_start.value(), end); 1042 Node* const result = a.SubString(context, string, var_start.value(), end);
1029 a->Return(result); 1043 a.Return(result);
1030 } 1044 }
1031 } 1045 }
1032 1046
1033 namespace { 1047 namespace {
1034 1048
1035 compiler::Node* ToSmiBetweenZeroAnd(CodeStubAssembler* a, 1049 compiler::Node* ToSmiBetweenZeroAnd(CodeStubAssembler* a,
1036 compiler::Node* context, 1050 compiler::Node* context,
1037 compiler::Node* value, 1051 compiler::Node* value,
1038 compiler::Node* limit) { 1052 compiler::Node* limit) {
1039 typedef CodeStubAssembler::Label Label; 1053 typedef CodeStubAssembler::Label Label;
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
1082 a->Goto(&out); 1096 a->Goto(&out);
1083 } 1097 }
1084 1098
1085 a->Bind(&out); 1099 a->Bind(&out);
1086 return var_result.value(); 1100 return var_result.value();
1087 } 1101 }
1088 1102
1089 } // namespace 1103 } // namespace
1090 1104
1091 // ES6 section 21.1.3.19 String.prototype.substring ( start, end ) 1105 // ES6 section 21.1.3.19 String.prototype.substring ( start, end )
1092 void Builtins::Generate_StringPrototypeSubstring(CodeStubAssembler* a) { 1106 void Builtins::Generate_StringPrototypeSubstring(
1107 compiler::CodeAssemblerState* state) {
1093 typedef CodeStubAssembler::Label Label; 1108 typedef CodeStubAssembler::Label Label;
1094 typedef compiler::Node Node; 1109 typedef compiler::Node Node;
1095 typedef CodeStubAssembler::Variable Variable; 1110 typedef CodeStubAssembler::Variable Variable;
1111 CodeStubAssembler a(state);
1096 1112
1097 Label out(a); 1113 Label out(&a);
1098 1114
1099 Variable var_start(a, MachineRepresentation::kTagged); 1115 Variable var_start(&a, MachineRepresentation::kTagged);
1100 Variable var_end(a, MachineRepresentation::kTagged); 1116 Variable var_end(&a, MachineRepresentation::kTagged);
1101 1117
1102 Node* const receiver = a->Parameter(0); 1118 Node* const receiver = a.Parameter(0);
1103 Node* const start = a->Parameter(1); 1119 Node* const start = a.Parameter(1);
1104 Node* const end = a->Parameter(2); 1120 Node* const end = a.Parameter(2);
1105 Node* const context = a->Parameter(5); 1121 Node* const context = a.Parameter(5);
1106 1122
1107 // Check that {receiver} is coercible to Object and convert it to a String. 1123 // Check that {receiver} is coercible to Object and convert it to a String.
1108 Node* const string = 1124 Node* const string =
1109 a->ToThisString(context, receiver, "String.prototype.substring"); 1125 a.ToThisString(context, receiver, "String.prototype.substring");
1110 1126
1111 Node* const length = a->LoadStringLength(string); 1127 Node* const length = a.LoadStringLength(string);
1112 1128
1113 // Conversion and bounds-checks for {start}. 1129 // Conversion and bounds-checks for {start}.
1114 var_start.Bind(ToSmiBetweenZeroAnd(a, context, start, length)); 1130 var_start.Bind(ToSmiBetweenZeroAnd(&a, context, start, length));
1115 1131
1116 // Conversion and bounds-checks for {end}. 1132 // Conversion and bounds-checks for {end}.
1117 { 1133 {
1118 var_end.Bind(length); 1134 var_end.Bind(length);
1119 a->GotoIf(a->WordEqual(end, a->UndefinedConstant()), &out); 1135 a.GotoIf(a.WordEqual(end, a.UndefinedConstant()), &out);
1120 1136
1121 var_end.Bind(ToSmiBetweenZeroAnd(a, context, end, length)); 1137 var_end.Bind(ToSmiBetweenZeroAnd(&a, context, end, length));
1122 1138
1123 Label if_endislessthanstart(a); 1139 Label if_endislessthanstart(&a);
1124 a->Branch(a->SmiLessThan(var_end.value(), var_start.value()), 1140 a.Branch(a.SmiLessThan(var_end.value(), var_start.value()),
1125 &if_endislessthanstart, &out); 1141 &if_endislessthanstart, &out);
1126 1142
1127 a->Bind(&if_endislessthanstart); 1143 a.Bind(&if_endislessthanstart);
1128 { 1144 {
1129 Node* const tmp = var_end.value(); 1145 Node* const tmp = var_end.value();
1130 var_end.Bind(var_start.value()); 1146 var_end.Bind(var_start.value());
1131 var_start.Bind(tmp); 1147 var_start.Bind(tmp);
1132 a->Goto(&out); 1148 a.Goto(&out);
1133 } 1149 }
1134 } 1150 }
1135 1151
1136 a->Bind(&out); 1152 a.Bind(&out);
1137 { 1153 {
1138 Node* result = 1154 Node* result =
1139 a->SubString(context, string, var_start.value(), var_end.value()); 1155 a.SubString(context, string, var_start.value(), var_end.value());
1140 a->Return(result); 1156 a.Return(result);
1141 } 1157 }
1142 } 1158 }
1143 1159
1144 BUILTIN(StringPrototypeStartsWith) { 1160 BUILTIN(StringPrototypeStartsWith) {
1145 HandleScope handle_scope(isolate); 1161 HandleScope handle_scope(isolate);
1146 TO_THIS_STRING(str, "String.prototype.startsWith"); 1162 TO_THIS_STRING(str, "String.prototype.startsWith");
1147 1163
1148 // Check if the search string is a regExp and fail if it is. 1164 // Check if the search string is a regExp and fail if it is.
1149 Handle<Object> search = args.atOrUndefined(isolate, 1); 1165 Handle<Object> search = args.atOrUndefined(isolate, 1);
1150 Maybe<bool> is_reg_exp = RegExpUtils::IsRegExp(isolate, search); 1166 Maybe<bool> is_reg_exp = RegExpUtils::IsRegExp(isolate, search);
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
1184 1200
1185 for (int i = 0; i < search_string->length(); i++) { 1201 for (int i = 0; i < search_string->length(); i++) {
1186 if (str_reader.Get(start + i) != search_reader.Get(i)) { 1202 if (str_reader.Get(start + i) != search_reader.Get(i)) {
1187 return isolate->heap()->false_value(); 1203 return isolate->heap()->false_value();
1188 } 1204 }
1189 } 1205 }
1190 return isolate->heap()->true_value(); 1206 return isolate->heap()->true_value();
1191 } 1207 }
1192 1208
1193 // ES6 section 21.1.3.25 String.prototype.toString () 1209 // ES6 section 21.1.3.25 String.prototype.toString ()
1194 void Builtins::Generate_StringPrototypeToString(CodeStubAssembler* assembler) { 1210 void Builtins::Generate_StringPrototypeToString(
1211 compiler::CodeAssemblerState* state) {
1195 typedef compiler::Node Node; 1212 typedef compiler::Node Node;
1213 CodeStubAssembler assembler(state);
1196 1214
1197 Node* receiver = assembler->Parameter(0); 1215 Node* receiver = assembler.Parameter(0);
1198 Node* context = assembler->Parameter(3); 1216 Node* context = assembler.Parameter(3);
1199 1217
1200 Node* result = assembler->ToThisValue( 1218 Node* result = assembler.ToThisValue(
1201 context, receiver, PrimitiveType::kString, "String.prototype.toString"); 1219 context, receiver, PrimitiveType::kString, "String.prototype.toString");
1202 assembler->Return(result); 1220 assembler.Return(result);
1203 } 1221 }
1204 1222
1205 // ES6 section 21.1.3.27 String.prototype.trim () 1223 // ES6 section 21.1.3.27 String.prototype.trim ()
1206 BUILTIN(StringPrototypeTrim) { 1224 BUILTIN(StringPrototypeTrim) {
1207 HandleScope scope(isolate); 1225 HandleScope scope(isolate);
1208 TO_THIS_STRING(string, "String.prototype.trim"); 1226 TO_THIS_STRING(string, "String.prototype.trim");
1209 return *String::Trim(string, String::kTrim); 1227 return *String::Trim(string, String::kTrim);
1210 } 1228 }
1211 1229
1212 // Non-standard WebKit extension 1230 // Non-standard WebKit extension
1213 BUILTIN(StringPrototypeTrimLeft) { 1231 BUILTIN(StringPrototypeTrimLeft) {
1214 HandleScope scope(isolate); 1232 HandleScope scope(isolate);
1215 TO_THIS_STRING(string, "String.prototype.trimLeft"); 1233 TO_THIS_STRING(string, "String.prototype.trimLeft");
1216 return *String::Trim(string, String::kTrimLeft); 1234 return *String::Trim(string, String::kTrimLeft);
1217 } 1235 }
1218 1236
1219 // Non-standard WebKit extension 1237 // Non-standard WebKit extension
1220 BUILTIN(StringPrototypeTrimRight) { 1238 BUILTIN(StringPrototypeTrimRight) {
1221 HandleScope scope(isolate); 1239 HandleScope scope(isolate);
1222 TO_THIS_STRING(string, "String.prototype.trimRight"); 1240 TO_THIS_STRING(string, "String.prototype.trimRight");
1223 return *String::Trim(string, String::kTrimRight); 1241 return *String::Trim(string, String::kTrimRight);
1224 } 1242 }
1225 1243
1226 // ES6 section 21.1.3.28 String.prototype.valueOf ( ) 1244 // ES6 section 21.1.3.28 String.prototype.valueOf ( )
1227 void Builtins::Generate_StringPrototypeValueOf(CodeStubAssembler* assembler) { 1245 void Builtins::Generate_StringPrototypeValueOf(
1246 compiler::CodeAssemblerState* state) {
1228 typedef compiler::Node Node; 1247 typedef compiler::Node Node;
1248 CodeStubAssembler assembler(state);
1229 1249
1230 Node* receiver = assembler->Parameter(0); 1250 Node* receiver = assembler.Parameter(0);
1231 Node* context = assembler->Parameter(3); 1251 Node* context = assembler.Parameter(3);
1232 1252
1233 Node* result = assembler->ToThisValue( 1253 Node* result = assembler.ToThisValue(
1234 context, receiver, PrimitiveType::kString, "String.prototype.valueOf"); 1254 context, receiver, PrimitiveType::kString, "String.prototype.valueOf");
1235 assembler->Return(result); 1255 assembler.Return(result);
1236 } 1256 }
1237 1257
1238 void Builtins::Generate_StringPrototypeIterator(CodeStubAssembler* assembler) { 1258 void Builtins::Generate_StringPrototypeIterator(
1259 compiler::CodeAssemblerState* state) {
1239 typedef compiler::Node Node; 1260 typedef compiler::Node Node;
1261 CodeStubAssembler assembler(state);
1240 1262
1241 Node* receiver = assembler->Parameter(0); 1263 Node* receiver = assembler.Parameter(0);
1242 Node* context = assembler->Parameter(3); 1264 Node* context = assembler.Parameter(3);
1243 1265
1244 Node* string = assembler->ToThisString(context, receiver, 1266 Node* string = assembler.ToThisString(context, receiver,
1245 "String.prototype[Symbol.iterator]"); 1267 "String.prototype[Symbol.iterator]");
1246 1268
1247 Node* native_context = assembler->LoadNativeContext(context); 1269 Node* native_context = assembler.LoadNativeContext(context);
1248 Node* map = assembler->LoadFixedArrayElement( 1270 Node* map = assembler.LoadFixedArrayElement(
1249 native_context, 1271 native_context,
1250 assembler->IntPtrConstant(Context::STRING_ITERATOR_MAP_INDEX), 0, 1272 assembler.IntPtrConstant(Context::STRING_ITERATOR_MAP_INDEX), 0,
1251 CodeStubAssembler::INTPTR_PARAMETERS); 1273 CodeStubAssembler::INTPTR_PARAMETERS);
1252 Node* iterator = assembler->Allocate(JSStringIterator::kSize); 1274 Node* iterator = assembler.Allocate(JSStringIterator::kSize);
1253 assembler->StoreMapNoWriteBarrier(iterator, map); 1275 assembler.StoreMapNoWriteBarrier(iterator, map);
1254 assembler->StoreObjectFieldRoot(iterator, JSValue::kPropertiesOffset, 1276 assembler.StoreObjectFieldRoot(iterator, JSValue::kPropertiesOffset,
1255 Heap::kEmptyFixedArrayRootIndex); 1277 Heap::kEmptyFixedArrayRootIndex);
1256 assembler->StoreObjectFieldRoot(iterator, JSObject::kElementsOffset, 1278 assembler.StoreObjectFieldRoot(iterator, JSObject::kElementsOffset,
1257 Heap::kEmptyFixedArrayRootIndex); 1279 Heap::kEmptyFixedArrayRootIndex);
1258 assembler->StoreObjectFieldNoWriteBarrier( 1280 assembler.StoreObjectFieldNoWriteBarrier(
1259 iterator, JSStringIterator::kStringOffset, string); 1281 iterator, JSStringIterator::kStringOffset, string);
1260 Node* index = assembler->SmiConstant(Smi::kZero); 1282 Node* index = assembler.SmiConstant(Smi::kZero);
1261 assembler->StoreObjectFieldNoWriteBarrier( 1283 assembler.StoreObjectFieldNoWriteBarrier(
1262 iterator, JSStringIterator::kNextIndexOffset, index); 1284 iterator, JSStringIterator::kNextIndexOffset, index);
1263 assembler->Return(iterator); 1285 assembler.Return(iterator);
1264 } 1286 }
1265 1287
1266 namespace { 1288 namespace {
1267 1289
1268 // Return the |word32| codepoint at {index}. Supports SeqStrings and 1290 // Return the |word32| codepoint at {index}. Supports SeqStrings and
1269 // ExternalStrings. 1291 // ExternalStrings.
1270 compiler::Node* LoadSurrogatePairInternal(CodeStubAssembler* assembler, 1292 compiler::Node* LoadSurrogatePairInternal(CodeStubAssembler* assembler,
1271 compiler::Node* string, 1293 compiler::Node* string,
1272 compiler::Node* length, 1294 compiler::Node* length,
1273 compiler::Node* index, 1295 compiler::Node* index,
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
1348 compiler::Node* string, 1370 compiler::Node* string,
1349 compiler::Node* length, 1371 compiler::Node* length,
1350 compiler::Node* index) { 1372 compiler::Node* index) {
1351 return LoadSurrogatePairInternal(assembler, string, length, index, 1373 return LoadSurrogatePairInternal(assembler, string, length, index,
1352 UnicodeEncoding::UTF16); 1374 UnicodeEncoding::UTF16);
1353 } 1375 }
1354 1376
1355 } // namespace 1377 } // namespace
1356 1378
1357 void Builtins::Generate_StringIteratorPrototypeNext( 1379 void Builtins::Generate_StringIteratorPrototypeNext(
1358 CodeStubAssembler* assembler) { 1380 compiler::CodeAssemblerState* state) {
1359 typedef CodeStubAssembler::Label Label; 1381 typedef CodeStubAssembler::Label Label;
1360 typedef compiler::Node Node; 1382 typedef compiler::Node Node;
1361 typedef CodeStubAssembler::Variable Variable; 1383 typedef CodeStubAssembler::Variable Variable;
1384 CodeStubAssembler assembler(state);
1362 1385
1363 Variable var_value(assembler, MachineRepresentation::kTagged); 1386 Variable var_value(&assembler, MachineRepresentation::kTagged);
1364 Variable var_done(assembler, MachineRepresentation::kTagged); 1387 Variable var_done(&assembler, MachineRepresentation::kTagged);
1365 1388
1366 var_value.Bind(assembler->UndefinedConstant()); 1389 var_value.Bind(assembler.UndefinedConstant());
1367 var_done.Bind(assembler->BooleanConstant(true)); 1390 var_done.Bind(assembler.BooleanConstant(true));
1368 1391
1369 Label throw_bad_receiver(assembler), next_codepoint(assembler), 1392 Label throw_bad_receiver(&assembler), next_codepoint(&assembler),
1370 return_result(assembler); 1393 return_result(&assembler);
1371 1394
1372 Node* iterator = assembler->Parameter(0); 1395 Node* iterator = assembler.Parameter(0);
1373 Node* context = assembler->Parameter(3); 1396 Node* context = assembler.Parameter(3);
1374 1397
1375 assembler->GotoIf(assembler->TaggedIsSmi(iterator), &throw_bad_receiver); 1398 assembler.GotoIf(assembler.TaggedIsSmi(iterator), &throw_bad_receiver);
1376 assembler->GotoUnless( 1399 assembler.GotoUnless(
1377 assembler->WordEqual(assembler->LoadInstanceType(iterator), 1400 assembler.WordEqual(assembler.LoadInstanceType(iterator),
1378 assembler->Int32Constant(JS_STRING_ITERATOR_TYPE)), 1401 assembler.Int32Constant(JS_STRING_ITERATOR_TYPE)),
1379 &throw_bad_receiver); 1402 &throw_bad_receiver);
1380 1403
1381 Node* string = 1404 Node* string =
1382 assembler->LoadObjectField(iterator, JSStringIterator::kStringOffset); 1405 assembler.LoadObjectField(iterator, JSStringIterator::kStringOffset);
1383 Node* position = 1406 Node* position =
1384 assembler->LoadObjectField(iterator, JSStringIterator::kNextIndexOffset); 1407 assembler.LoadObjectField(iterator, JSStringIterator::kNextIndexOffset);
1385 Node* length = assembler->LoadObjectField(string, String::kLengthOffset); 1408 Node* length = assembler.LoadObjectField(string, String::kLengthOffset);
1386 1409
1387 assembler->Branch(assembler->SmiLessThan(position, length), &next_codepoint, 1410 assembler.Branch(assembler.SmiLessThan(position, length), &next_codepoint,
1388 &return_result); 1411 &return_result);
1389 1412
1390 assembler->Bind(&next_codepoint); 1413 assembler.Bind(&next_codepoint);
1391 { 1414 {
1392 Node* ch = LoadSurrogatePairAt(assembler, string, length, position); 1415 Node* ch = LoadSurrogatePairAt(&assembler, string, length, position);
1393 Node* value = assembler->StringFromCodePoint(ch, UnicodeEncoding::UTF16); 1416 Node* value = assembler.StringFromCodePoint(ch, UnicodeEncoding::UTF16);
1394 var_value.Bind(value); 1417 var_value.Bind(value);
1395 Node* length = assembler->LoadObjectField(value, String::kLengthOffset); 1418 Node* length = assembler.LoadObjectField(value, String::kLengthOffset);
1396 assembler->StoreObjectFieldNoWriteBarrier( 1419 assembler.StoreObjectFieldNoWriteBarrier(
1397 iterator, JSStringIterator::kNextIndexOffset, 1420 iterator, JSStringIterator::kNextIndexOffset,
1398 assembler->SmiAdd(position, length)); 1421 assembler.SmiAdd(position, length));
1399 var_done.Bind(assembler->BooleanConstant(false)); 1422 var_done.Bind(assembler.BooleanConstant(false));
1400 assembler->Goto(&return_result); 1423 assembler.Goto(&return_result);
1401 } 1424 }
1402 1425
1403 assembler->Bind(&return_result); 1426 assembler.Bind(&return_result);
1404 { 1427 {
1405 Node* native_context = assembler->LoadNativeContext(context); 1428 Node* native_context = assembler.LoadNativeContext(context);
1406 Node* map = assembler->LoadFixedArrayElement( 1429 Node* map = assembler.LoadFixedArrayElement(
1407 native_context, 1430 native_context,
1408 assembler->IntPtrConstant(Context::ITERATOR_RESULT_MAP_INDEX), 0, 1431 assembler.IntPtrConstant(Context::ITERATOR_RESULT_MAP_INDEX), 0,
1409 CodeStubAssembler::INTPTR_PARAMETERS); 1432 CodeStubAssembler::INTPTR_PARAMETERS);
1410 Node* result = assembler->Allocate(JSIteratorResult::kSize); 1433 Node* result = assembler.Allocate(JSIteratorResult::kSize);
1411 assembler->StoreMapNoWriteBarrier(result, map); 1434 assembler.StoreMapNoWriteBarrier(result, map);
1412 assembler->StoreObjectFieldRoot(result, JSIteratorResult::kPropertiesOffset, 1435 assembler.StoreObjectFieldRoot(result, JSIteratorResult::kPropertiesOffset,
1413 Heap::kEmptyFixedArrayRootIndex); 1436 Heap::kEmptyFixedArrayRootIndex);
1414 assembler->StoreObjectFieldRoot(result, JSIteratorResult::kElementsOffset, 1437 assembler.StoreObjectFieldRoot(result, JSIteratorResult::kElementsOffset,
1415 Heap::kEmptyFixedArrayRootIndex); 1438 Heap::kEmptyFixedArrayRootIndex);
1416 assembler->StoreObjectFieldNoWriteBarrier( 1439 assembler.StoreObjectFieldNoWriteBarrier(
1417 result, JSIteratorResult::kValueOffset, var_value.value()); 1440 result, JSIteratorResult::kValueOffset, var_value.value());
1418 assembler->StoreObjectFieldNoWriteBarrier( 1441 assembler.StoreObjectFieldNoWriteBarrier(
1419 result, JSIteratorResult::kDoneOffset, var_done.value()); 1442 result, JSIteratorResult::kDoneOffset, var_done.value());
1420 assembler->Return(result); 1443 assembler.Return(result);
1421 } 1444 }
1422 1445
1423 assembler->Bind(&throw_bad_receiver); 1446 assembler.Bind(&throw_bad_receiver);
1424 { 1447 {
1425 // The {receiver} is not a valid JSGeneratorObject. 1448 // The {receiver} is not a valid JSGeneratorObject.
1426 Node* result = assembler->CallRuntime( 1449 Node* result = assembler.CallRuntime(
1427 Runtime::kThrowIncompatibleMethodReceiver, context, 1450 Runtime::kThrowIncompatibleMethodReceiver, context,
1428 assembler->HeapConstant(assembler->factory()->NewStringFromAsciiChecked( 1451 assembler.HeapConstant(assembler.factory()->NewStringFromAsciiChecked(
1429 "String Iterator.prototype.next", TENURED)), 1452 "String Iterator.prototype.next", TENURED)),
1430 iterator); 1453 iterator);
1431 assembler->Return(result); // Never reached. 1454 assembler.Return(result); // Never reached.
1432 } 1455 }
1433 } 1456 }
1434 1457
1435 } // namespace internal 1458 } // namespace internal
1436 } // namespace v8 1459 } // namespace v8
OLDNEW
« no previous file with comments | « src/builtins/builtins-sharedarraybuffer.cc ('k') | src/builtins/builtins-symbol.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698