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

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

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