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

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

Issue 2315473002: Revert of [regexp] Port RegExpExec (Closed)
Patch Set: Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/builtins/builtins.h ('k') | src/heap-symbols.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 the V8 project authors. All rights reserved. 1 // Copyright 2016 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/builtins/builtins.h" 5 #include "src/builtins/builtins.h"
6 #include "src/builtins/builtins-utils.h" 6 #include "src/builtins/builtins-utils.h"
7 7
8 #include "src/regexp/jsregexp.h"
9 #include "src/string-builder.h" 8 #include "src/string-builder.h"
10 9
11 namespace v8 { 10 namespace v8 {
12 namespace internal { 11 namespace internal {
13 12
14 // ----------------------------------------------------------------------------- 13 // -----------------------------------------------------------------------------
15 // ES6 section 21.2 RegExp Objects 14 // ES6 section 21.2 RegExp Objects
16 15
17 namespace { 16 namespace {
18 17
(...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after
315 314
316 // Constants for accessing RegExpLastMatchInfo. 315 // Constants for accessing RegExpLastMatchInfo.
317 // TODO(jgruber): Currently, RegExpLastMatchInfo is still a JSObject maintained 316 // TODO(jgruber): Currently, RegExpLastMatchInfo is still a JSObject maintained
318 // and accessed from JS. This is a crutch until all RegExp logic is ported, then 317 // and accessed from JS. This is a crutch until all RegExp logic is ported, then
319 // we can take care of RegExpLastMatchInfo. 318 // we can take care of RegExpLastMatchInfo.
320 const int kNumberOfCapturesIndex = 0; 319 const int kNumberOfCapturesIndex = 0;
321 const int kLastSubjectIndex = 1; 320 const int kLastSubjectIndex = 1;
322 const int kLastInputIndex = 2; 321 const int kLastInputIndex = 2;
323 const int kFirstCaptureIndex = 3; 322 const int kFirstCaptureIndex = 3;
324 323
325 Handle<JSObject> GetLastMatchInfo(Isolate* isolate) { 324 Handle<Object> GetLastMatchField(Isolate* isolate, int index) {
326 Handle<JSFunction> global_regexp = isolate->regexp_function(); 325 Handle<JSFunction> global_regexp = isolate->regexp_function();
327 Handle<Object> last_match_info_obj = JSReceiver::GetDataProperty( 326 Handle<Object> last_match_info_obj = JSReceiver::GetDataProperty(
328 global_regexp, isolate->factory()->regexp_last_match_info_symbol()); 327 global_regexp, isolate->factory()->regexp_last_match_info_symbol());
329 328
330 return Handle<JSObject>::cast(last_match_info_obj); 329 Handle<JSReceiver> last_match_info =
331 } 330 Handle<JSReceiver>::cast(last_match_info_obj);
332
333 Handle<Object> GetLastMatchField(Isolate* isolate, int index) {
334 Handle<JSObject> last_match_info = GetLastMatchInfo(isolate);
335 return JSReceiver::GetElement(isolate, last_match_info, index) 331 return JSReceiver::GetElement(isolate, last_match_info, index)
336 .ToHandleChecked(); 332 .ToHandleChecked();
337 } 333 }
338 334
339 void SetLastMatchField(Isolate* isolate, int index, Handle<Object> value) { 335 void SetLastMatchField(Isolate* isolate, int index, Handle<Object> value) {
340 Handle<JSFunction> global_regexp = isolate->regexp_function(); 336 Handle<JSFunction> global_regexp = isolate->regexp_function();
341 Handle<Object> last_match_info_obj = JSReceiver::GetDataProperty( 337 Handle<Object> last_match_info_obj = JSReceiver::GetDataProperty(
342 global_regexp, isolate->factory()->regexp_last_match_info_symbol()); 338 global_regexp, isolate->factory()->regexp_last_match_info_symbol());
343 339
344 Handle<JSReceiver> last_match_info = 340 Handle<JSReceiver> last_match_info =
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
456 } 452 }
457 453
458 BUILTIN(RegExpPrototypeRightContextGetter) { 454 BUILTIN(RegExpPrototypeRightContextGetter) {
459 HandleScope scope(isolate); 455 HandleScope scope(isolate);
460 const int start_index = GetLastMatchCapture(isolate, 1); 456 const int start_index = GetLastMatchCapture(isolate, 1);
461 Handle<String> last_subject = GetLastMatchSubject(isolate); 457 Handle<String> last_subject = GetLastMatchSubject(isolate);
462 const int len = last_subject->length(); 458 const int len = last_subject->length();
463 return *isolate->factory()->NewSubString(last_subject, start_index, len); 459 return *isolate->factory()->NewSubString(last_subject, start_index, len);
464 } 460 }
465 461
466 namespace {
467
468 MaybeHandle<Object> SetLastIndex(Isolate* isolate, Handle<JSRegExp> regexp,
469 int value) {
470 return Object::SetProperty(regexp, isolate->factory()->lastIndex_string(),
471 handle(Smi::FromInt(value), isolate), SLOPPY);
472 }
473
474 Handle<JSArray> ConstructResult(Isolate* isolate, int size, int index,
475 Handle<String> input) {
476 Handle<FixedArray> elements = isolate->factory()->NewFixedArray(size);
477 Handle<Map> regexp_map(isolate->native_context()->regexp_result_map());
478 Handle<JSObject> object =
479 isolate->factory()->NewJSObjectFromMap(regexp_map, NOT_TENURED);
480 Handle<JSArray> array = Handle<JSArray>::cast(object);
481 array->set_elements(*elements);
482 array->set_length(Smi::FromInt(size));
483 // Write in-object properties after the length of the array.
484 array->InObjectPropertyAtPut(JSRegExpResult::kIndexIndex,
485 Smi::FromInt(index));
486 array->InObjectPropertyAtPut(JSRegExpResult::kInputIndex, *input);
487 return array;
488 }
489
490 Handle<Object> ReturnNewResultFromMatchInfo(Isolate* isolate,
491 Handle<Object> match_info,
492 Handle<String> string) {
493 const int num_captures = GetLastMatchNumberOfCaptures(isolate);
494 DCHECK_EQ(0, num_captures % 2);
495
496 const int num_results = num_captures / 2;
497 int start = GetLastMatchCapture(isolate, 0);
498 int end = GetLastMatchCapture(isolate, 1);
499
500 // Calculate the substring of the first match before creating the result array
501 // to avoid an unnecessary write barrier storing the first result.
502 Handle<String> first = isolate->factory()->NewSubString(string, start, end);
503 Handle<JSArray> result = ConstructResult(isolate, num_results, start, string);
504
505 Handle<FixedArray> elems =
506 handle(FixedArray::cast(result->elements()), isolate);
507 elems->set(0, *first);
508
509 for (int i = 1; i < num_results; i++) {
510 start = GetLastMatchCapture(isolate, i * 2);
511 if (start != -1) {
512 end = GetLastMatchCapture(isolate, i * 2 + 1);
513 Handle<String> capture =
514 isolate->factory()->NewSubString(string, start, end);
515 elems->set(i, *capture);
516 }
517 }
518
519 return result;
520 }
521
522 MaybeHandle<Object> RegExpExecJS(Isolate* isolate, Handle<JSRegExp> regexp,
523 Handle<String> string) {
524 Handle<Object> last_index_obj;
525 ASSIGN_RETURN_ON_EXCEPTION(
526 isolate, last_index_obj,
527 Object::GetProperty(regexp, isolate->factory()->lastIndex_string()),
528 Object);
529
530 // Conversion is required by the ES2015 specification (RegExpBuiltinExec
531 // algorithm, step 4) even if the value is discarded for non-global RegExps.
532 ASSIGN_RETURN_ON_EXCEPTION(isolate, last_index_obj,
533 Object::ToLength(isolate, last_index_obj), Object);
534
535 int last_index = Handle<Smi>::cast(last_index_obj)->value();
536
537 const int flags = regexp->GetFlags();
538 const bool global = (flags & JSRegExp::kGlobal) != 0;
539 const bool sticky = (flags & JSRegExp::kSticky) != 0;
540 const bool update_last_index = (global || sticky);
541
542 if (update_last_index) {
543 if (last_index > string->length()) {
544 RETURN_ON_EXCEPTION(isolate, SetLastIndex(isolate, regexp, 0), Object);
545 return isolate->factory()->null_value();
546 }
547 } else {
548 last_index = 0;
549 }
550
551 Handle<JSObject> last_match_info = GetLastMatchInfo(isolate);
552
553 // matchIndices is either null or the RegExpLastMatchInfo array.
554 // TODO(littledan): Whether a RegExp is sticky is compiled into the RegExp
555 // itself, but ES2015 allows monkey-patching this property to differ from
556 // the internal flags. If it differs, recompile a different RegExp?
557 // TODO(jgruber): The result of Exec does not need to be a JSArray.
558 Handle<Object> match_indices;
559 ASSIGN_RETURN_ON_EXCEPTION(
560 isolate, match_indices,
561 RegExpImpl::Exec(regexp, string, last_index, last_match_info), Object);
562
563 if (match_indices->IsNull(isolate)) {
564 RETURN_ON_EXCEPTION(isolate, SetLastIndex(isolate, regexp, 0), Object);
565 return isolate->factory()->null_value();
566 }
567
568 // Successful match.
569 if (update_last_index) {
570 last_index = GetLastMatchCapture(isolate, 1);
571 RETURN_ON_EXCEPTION(isolate, SetLastIndex(isolate, regexp, last_index),
572 Object);
573 }
574
575 return ReturnNewResultFromMatchInfo(isolate, match_indices, string);
576 }
577
578 } // namespace
579
580 // ES#sec-regexp.prototype.exec
581 // RegExp.prototype.exec ( string )
582 BUILTIN(RegExpPrototypeExec) {
583 HandleScope scope(isolate);
584 CHECK_RECEIVER(JSRegExp, regexp, "RegExp.prototype.exec");
585
586 Handle<Object> string_obj = args.atOrUndefined(isolate, 1);
587
588 Handle<String> string;
589 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, string,
590 Object::ToString(isolate, string_obj));
591
592 RETURN_RESULT_OR_FAILURE(isolate, RegExpExecJS(isolate, regexp, string));
593 }
594
595 } // namespace internal 462 } // namespace internal
596 } // namespace v8 463 } // namespace v8
OLDNEW
« no previous file with comments | « src/builtins/builtins.h ('k') | src/heap-symbols.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698