Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |