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

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

Issue 2339123002: [builtins] Move StringLastIndexOf to a builtin. (Closed)
Patch Set: variable renaming Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2016 the V8 project authors. All rights reserved. 1 // Copyright 2016 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/builtins/builtins.h" 5 #include "src/builtins/builtins.h"
6 #include "src/builtins/builtins-utils.h" 6 #include "src/builtins/builtins-utils.h"
7 7
8 #include "src/code-factory.h" 8 #include "src/code-factory.h"
9 9
10 namespace v8 { 10 namespace v8 {
(...skipping 459 matching lines...) Expand 10 before | Expand all | Expand 10 after
470 assembler->Return(assembler->NaNConstant()); 470 assembler->Return(assembler->NaNConstant());
471 assembler->Bind(&if_positioninbounds); 471 assembler->Bind(&if_positioninbounds);
472 } 472 }
473 473
474 // Load the character at the {position} from the {receiver}. 474 // Load the character at the {position} from the {receiver}.
475 Node* value = assembler->StringCharCodeAt(receiver, position); 475 Node* value = assembler->StringCharCodeAt(receiver, position);
476 Node* result = assembler->SmiFromWord32(value); 476 Node* result = assembler->SmiFromWord32(value);
477 assembler->Return(result); 477 assembler->Return(result);
478 } 478 }
479 479
480 template <typename schar, typename pchar>
Franzi 2016/09/14 15:05:01 I think this should be inside an anonymous namespa
Benedikt Meurer 2016/09/14 17:02:31 Yes, please remove the static and put it into anon
petermarshall 2016/09/15 12:19:59 Done
481 static int StringMatchBackwards(Vector<const schar> subject,
482 Vector<const pchar> pattern, int idx) {
483 int pattern_length = pattern.length();
484 DCHECK(pattern_length >= 1);
485 DCHECK(idx + pattern_length <= subject.length());
486
487 if (sizeof(schar) == 1 && sizeof(pchar) > 1) {
488 for (int i = 0; i < pattern_length; i++) {
489 uc16 c = pattern[i];
490 if (c > String::kMaxOneByteCharCode) {
491 return -1;
492 }
493 }
494 }
495
496 pchar pattern_first_char = pattern[0];
497 for (int i = idx; i >= 0; i--) {
498 if (subject[i] != pattern_first_char) continue;
499 int j = 1;
500 while (j < pattern_length) {
501 if (pattern[j] != subject[i + j]) {
502 break;
503 }
504 j++;
505 }
506 if (j == pattern_length) {
507 return i;
508 }
509 }
510 return -1;
511 }
512
513 // ES6 section 21.1.3.9
514 // String.prototype.lastIndexOf ( searchString [ , position ] )
515 BUILTIN(StringPrototypeLastIndexOf) {
516 HandleScope handle_scope(isolate);
517 TO_THIS_STRING(sub, "String.prototype.lastIndexOf");
518
519 Handle<String> pat;
520 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
521 isolate, pat,
522 Object::ToString(isolate, args.atOrUndefined(isolate, 1)));
523
524 Handle<Object> position;
525 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
526 isolate, position, Object::ToNumber(args.atOrUndefined(isolate, 2)));
527
528 if (position->IsNaN()) {
529 position = isolate->factory()->infinity_value();
Benedikt Meurer 2016/09/14 17:02:32 You can just default to sub->length here, as infin
530 } else {
531 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, position,
532 Object::ToInteger(isolate, position));
533 }
534
535 Handle<Object> zero = isolate->factory()->NewNumberFromInt(0);
Benedikt Meurer 2016/09/14 17:02:32 You don't need this boxed zero valid, see comments
536
537 if (Object::LessThan(position, zero).FromJust()) {
Benedikt Meurer 2016/09/14 17:02:31 No need to use Object::LessThan here, which corres
538 position = zero;
539 }
540
541 Handle<Object> sub_len_obj =
542 isolate->factory()->NewNumberFromInt(sub->length());
Benedikt Meurer 2016/09/14 17:02:31 No need to box the sub->length, just compare again
543 if (Object::LessThan(sub_len_obj, position).FromJust()) {
544 position = sub_len_obj;
545 }
546
547 uint32_t start_index;
548 if (!position->ToArrayIndex(&start_index)) return Smi::FromInt(-1);
Benedikt Meurer 2016/09/14 17:02:32 At this point you know that position_number is wit
petermarshall 2016/09/15 12:19:59 I reworked this whole section with your comments
549
550 uint32_t pat_length = pat->length();
551 uint32_t sub_length = sub->length();
552
553 if (start_index + pat_length > sub_length) {
554 start_index = sub_length - pat_length;
555 }
556
557 if (pat_length == 0) {
558 return Smi::FromInt(start_index);
559 }
560
561 sub = String::Flatten(sub);
562 pat = String::Flatten(pat);
563
564 int last_index = -1;
565 DisallowHeapAllocation no_gc; // ensure vectors stay valid
566
567 String::FlatContent sub_content = sub->GetFlatContent();
568 String::FlatContent pat_content = pat->GetFlatContent();
569
570 if (pat_content.IsOneByte()) {
571 Vector<const uint8_t> pat_vector = pat_content.ToOneByteVector();
572 if (sub_content.IsOneByte()) {
573 last_index = StringMatchBackwards(sub_content.ToOneByteVector(),
574 pat_vector, start_index);
575 } else {
576 last_index = StringMatchBackwards(sub_content.ToUC16Vector(), pat_vector,
577 start_index);
578 }
579 } else {
580 Vector<const uc16> pat_vector = pat_content.ToUC16Vector();
581 if (sub_content.IsOneByte()) {
582 last_index = StringMatchBackwards(sub_content.ToOneByteVector(),
583 pat_vector, start_index);
584 } else {
585 last_index = StringMatchBackwards(sub_content.ToUC16Vector(), pat_vector,
586 start_index);
587 }
588 }
589 return Smi::FromInt(last_index);
590 }
591
480 // ES6 section 21.1.3.10 String.prototype.localeCompare ( that ) 592 // ES6 section 21.1.3.10 String.prototype.localeCompare ( that )
481 // 593 //
482 // This function is implementation specific. For now, we do not 594 // This function is implementation specific. For now, we do not
483 // do anything locale specific. 595 // do anything locale specific.
484 // If internationalization is enabled, then i18n.js will override this function 596 // If internationalization is enabled, then i18n.js will override this function
485 // and provide the proper functionality, so this is just a fallback. 597 // and provide the proper functionality, so this is just a fallback.
486 BUILTIN(StringPrototypeLocaleCompare) { 598 BUILTIN(StringPrototypeLocaleCompare) {
487 HandleScope handle_scope(isolate); 599 HandleScope handle_scope(isolate);
488 DCHECK_EQ(2, args.length()); 600 DCHECK_EQ(2, args.length());
489 601
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
602 Node* receiver = assembler->Parameter(0); 714 Node* receiver = assembler->Parameter(0);
603 Node* context = assembler->Parameter(3); 715 Node* context = assembler->Parameter(3);
604 716
605 Node* result = assembler->ToThisValue( 717 Node* result = assembler->ToThisValue(
606 context, receiver, PrimitiveType::kString, "String.prototype.valueOf"); 718 context, receiver, PrimitiveType::kString, "String.prototype.valueOf");
607 assembler->Return(result); 719 assembler->Return(result);
608 } 720 }
609 721
610 } // namespace internal 722 } // namespace internal
611 } // namespace v8 723 } // namespace v8
OLDNEW
« no previous file with comments | « src/builtins/builtins.h ('k') | src/js/i18n.js » ('j') | src/js/i18n.js » ('J')

Powered by Google App Engine
This is Rietveld 408576698