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

Side by Side Diff: src/jsregexp.cc

Issue 28184: Avoids allocating a JSArray of capture information on each non-global... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 11 years, 9 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 | Annotate | Revision Log
« no previous file with comments | « src/jsregexp.h ('k') | src/macros.py » ('j') | src/macros.py » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2006-2009 the V8 project authors. All rights reserved. 1 // Copyright 2006-2009 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after
247 // and we can store it in the cache. 247 // and we can store it in the cache.
248 Handle<FixedArray> data(FixedArray::cast(re->data())); 248 Handle<FixedArray> data(FixedArray::cast(re->data()));
249 CompilationCache::PutRegExp(pattern, flags, data); 249 CompilationCache::PutRegExp(pattern, flags, data);
250 } 250 }
251 } 251 }
252 252
253 return result; 253 return result;
254 } 254 }
255 255
256 256
257 static void EnsureSize(Handle<JSArray> lastMatchInfo,
Christian Plesner Hansen 2009/02/26 15:18:53 You might consider making this a method on JSArray
258 int num_capture_registers) {
259 CHECK(lastMatchInfo->HasFastElements());
260 if (lastMatchInfo->elements()->length() >=
261 num_capture_registers + RegExpImpl::kLastMatchOverhead) return;
262 Handle<FixedArray> old_backing(lastMatchInfo->elements());
263 int old_size = old_backing->length();
264 int new_size = num_capture_registers + RegExpImpl::kLastMatchOverhead;
265 // Doubling in size would be overkill, but leave some slack to avoid
266 // constantly growing.
267 new_size += new_size >> 3;
268 Handle<FixedArray> new_backing = Factory::NewFixedArray(new_size);
269 for (int i = 0; i < old_size; i++) new_backing->set(i, old_backing->get(i));
270 lastMatchInfo->SetContent(*new_backing);
271 }
272
273
257 Handle<Object> RegExpImpl::Exec(Handle<JSRegExp> regexp, 274 Handle<Object> RegExpImpl::Exec(Handle<JSRegExp> regexp,
258 Handle<String> subject, 275 Handle<String> subject,
259 Handle<Object> index) { 276 Smi* index,
Christian Plesner Hansen 2009/02/26 15:18:53 Consider converting the index to a C right away --
277 Handle<JSArray> lastMatchInfo) {
260 switch (regexp->TypeTag()) { 278 switch (regexp->TypeTag()) {
261 case JSRegExp::ATOM: 279 case JSRegExp::ATOM:
262 return AtomExec(regexp, subject, index); 280 return AtomExec(regexp, subject, index, lastMatchInfo);
263 case JSRegExp::IRREGEXP: { 281 case JSRegExp::IRREGEXP: {
264 Handle<Object> result = IrregexpExec(regexp, subject, index); 282 Handle<Object> result =
283 IrregexpExec(regexp, subject, index, lastMatchInfo);
265 ASSERT(!result.is_null() || Top::has_pending_exception()); 284 ASSERT(!result.is_null() || Top::has_pending_exception());
266 return result; 285 return result;
267 } 286 }
268 default: 287 default:
269 UNREACHABLE(); 288 UNREACHABLE();
270 return Handle<Object>::null(); 289 return Handle<Object>::null();
271 } 290 }
272 } 291 }
273 292
274 293
275 Handle<Object> RegExpImpl::ExecGlobal(Handle<JSRegExp> regexp, 294 Handle<Object> RegExpImpl::ExecGlobal(Handle<JSRegExp> regexp,
276 Handle<String> subject) { 295 Handle<String> subject,
296 Handle<JSArray> lastMatchInfo) {
277 switch (regexp->TypeTag()) { 297 switch (regexp->TypeTag()) {
278 case JSRegExp::ATOM: 298 case JSRegExp::ATOM:
279 return AtomExecGlobal(regexp, subject); 299 return AtomExecGlobal(regexp, subject, lastMatchInfo);
280 case JSRegExp::IRREGEXP: { 300 case JSRegExp::IRREGEXP: {
281 Handle<Object> result = IrregexpExecGlobal(regexp, subject); 301 Handle<Object> result =
302 IrregexpExecGlobal(regexp, subject, lastMatchInfo);
282 ASSERT(!result.is_null() || Top::has_pending_exception()); 303 ASSERT(!result.is_null() || Top::has_pending_exception());
283 return result; 304 return result;
284 } 305 }
285 default: 306 default:
286 UNREACHABLE(); 307 UNREACHABLE();
287 return Handle<Object>::null(); 308 return Handle<Object>::null();
288 } 309 }
289 } 310 }
290 311
291 312
292 // RegExp Atom implementation: Simple string search using indexOf. 313 // RegExp Atom implementation: Simple string search using indexOf.
293 314
294 315
295 Handle<Object> RegExpImpl::AtomCompile(Handle<JSRegExp> re, 316 Handle<Object> RegExpImpl::AtomCompile(Handle<JSRegExp> re,
296 Handle<String> pattern, 317 Handle<String> pattern,
297 JSRegExp::Flags flags, 318 JSRegExp::Flags flags,
298 Handle<String> match_pattern) { 319 Handle<String> match_pattern) {
299 Factory::SetRegExpData(re, JSRegExp::ATOM, pattern, flags, match_pattern); 320 Factory::SetRegExpData(re, JSRegExp::ATOM, pattern, flags, match_pattern);
300 return re; 321 return re;
301 } 322 }
302 323
303 324
304 Handle<Object> RegExpImpl::AtomExec(Handle<JSRegExp> re, 325 Handle<Object> RegExpImpl::AtomExec(Handle<JSRegExp> re,
305 Handle<String> subject, 326 Handle<String> subject,
306 Handle<Object> index) { 327 Smi* index,
328 Handle<JSArray> lastMatchInfo) {
307 Handle<String> needle(String::cast(re->DataAt(JSRegExp::kAtomPatternIndex))); 329 Handle<String> needle(String::cast(re->DataAt(JSRegExp::kAtomPatternIndex)));
308 330
309 uint32_t start_index; 331 uint32_t start_index = index->value();
310 if (!Array::IndexFromObject(*index, &start_index)) {
311 return Handle<Smi>(Smi::FromInt(-1));
312 }
313 332
314 int value = Runtime::StringMatch(subject, needle, start_index); 333 int value = Runtime::StringMatch(subject, needle, start_index);
315 if (value == -1) return Factory::null_value(); 334 if (value == -1) return Factory::null_value();
335 CHECK(lastMatchInfo->HasFastElements());
316 336
317 Handle<FixedArray> array = Factory::NewFixedArray(2); 337 Handle<FixedArray> array(lastMatchInfo->elements());
318 array->set(0, Smi::FromInt(value)); 338 SetLastCaptureCount(*array, 2);
Christian Plesner Hansen 2009/02/26 15:18:53 Could this sequence of 'Set's be packed into a fun
319 array->set(1, Smi::FromInt(value + needle->length())); 339 SetLastSubject(*array, *subject);
320 return Factory::NewJSArrayWithElements(array); 340 SetLastInput(*array, *subject);
341 SetCapture(*array, 0, value);
342 SetCapture(*array, 1, value + needle->length());
343 return lastMatchInfo;
321 } 344 }
322 345
323 346
324 Handle<Object> RegExpImpl::AtomExecGlobal(Handle<JSRegExp> re, 347 Handle<Object> RegExpImpl::AtomExecGlobal(Handle<JSRegExp> re,
325 Handle<String> subject) { 348 Handle<String> subject,
349 Handle<JSArray> lastMatchInfo) {
326 Handle<String> needle(String::cast(re->DataAt(JSRegExp::kAtomPatternIndex))); 350 Handle<String> needle(String::cast(re->DataAt(JSRegExp::kAtomPatternIndex)));
351 CHECK(lastMatchInfo->HasFastElements());
Christian Plesner Hansen 2009/02/26 15:18:53 Don't you mean ASSERT?
327 Handle<JSArray> result = Factory::NewJSArray(1); 352 Handle<JSArray> result = Factory::NewJSArray(1);
328 int index = 0; 353 int index = 0;
329 int match_count = 0; 354 int match_count = 0;
330 int subject_length = subject->length(); 355 int subject_length = subject->length();
331 int needle_length = needle->length(); 356 int needle_length = needle->length();
357 int last_value = -1;
332 while (true) { 358 while (true) {
333 int value = -1; 359 int value = -1;
334 if (index + needle_length <= subject_length) { 360 if (index + needle_length <= subject_length) {
335 value = Runtime::StringMatch(subject, needle, index); 361 value = Runtime::StringMatch(subject, needle, index);
336 } 362 }
337 if (value == -1) break; 363 if (value == -1) {
364 if (last_value != -1) {
365 Handle<FixedArray> array(lastMatchInfo->elements());
Christian Plesner Hansen 2009/02/26 15:18:53 You're creating an unbounded number of handles her
366 SetLastCaptureCount(*array, 2);
367 SetLastSubject(*array, *subject);
368 SetLastInput(*array, *subject);
369 SetCapture(*array, 0, last_value);
370 SetCapture(*array, 1, last_value + needle->length());
371 }
372 break;
373 }
374
338 HandleScope scope; 375 HandleScope scope;
339 int end = value + needle_length; 376 int end = value + needle_length;
340 377
341 Handle<FixedArray> array = Factory::NewFixedArray(2); 378 // Create an array that looks like the static lastMatchInfo array
342 array->set(0, Smi::FromInt(value)); 379 // that is attached to the global RegExp object. We will be returning
343 array->set(1, Smi::FromInt(end)); 380 // an array of these.
381 Handle<FixedArray> array = Factory::NewFixedArray(kFirstCapture + 2);
382 SetCapture(*array, 0, value);
383 SetCapture(*array, 1, end);
384 SetLastCaptureCount(*array, 2);
344 Handle<JSArray> pair = Factory::NewJSArrayWithElements(array); 385 Handle<JSArray> pair = Factory::NewJSArrayWithElements(array);
345 SetElement(result, match_count, pair); 386 SetElement(result, match_count, pair);
346 match_count++; 387 match_count++;
347 index = end; 388 index = end;
348 if (needle_length == 0) index++; 389 if (needle_length == 0) index++;
390 last_value = value;
349 } 391 }
350 return result; 392 return result;
351 } 393 }
352 394
353 395
354 // Irregexp implementation. 396 // Irregexp implementation.
355 397
356 398
357 // Retrieves a compiled version of the regexp for either ASCII or non-ASCII 399 // Retrieves a compiled version of the regexp for either ASCII or non-ASCII
358 // strings. If the compiled version doesn't already exist, it is compiled 400 // strings. If the compiled version doesn't already exist, it is compiled
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
438 Handle<FixedArray> alternatives = Factory::NewFixedArray(2); 480 Handle<FixedArray> alternatives = Factory::NewFixedArray(2);
439 alternatives->set_null(0); 481 alternatives->set_null(0);
440 alternatives->set_null(1); 482 alternatives->set_null(1);
441 Factory::SetRegExpData(re, JSRegExp::IRREGEXP, pattern, flags, alternatives); 483 Factory::SetRegExpData(re, JSRegExp::IRREGEXP, pattern, flags, alternatives);
442 return re; 484 return re;
443 } 485 }
444 486
445 487
446 Handle<Object> RegExpImpl::IrregexpExec(Handle<JSRegExp> regexp, 488 Handle<Object> RegExpImpl::IrregexpExec(Handle<JSRegExp> regexp,
447 Handle<String> subject, 489 Handle<String> subject,
448 Handle<Object> index) { 490 Smi* index,
491 Handle<JSArray> lastMatchInfo) {
449 ASSERT_EQ(regexp->TypeTag(), JSRegExp::IRREGEXP); 492 ASSERT_EQ(regexp->TypeTag(), JSRegExp::IRREGEXP);
450 ASSERT(regexp->DataAt(JSRegExp::kIrregexpDataIndex)->IsFixedArray()); 493 ASSERT(regexp->DataAt(JSRegExp::kIrregexpDataIndex)->IsFixedArray());
451 494
452 bool is_ascii = StringShape(*subject).IsAsciiRepresentation(); 495 bool is_ascii = StringShape(*subject).IsAsciiRepresentation();
453 Handle<FixedArray> irregexp = GetCompiledIrregexp(regexp, is_ascii); 496 Handle<FixedArray> irregexp = GetCompiledIrregexp(regexp, is_ascii);
454 if (irregexp.is_null()) { 497 if (irregexp.is_null()) {
455 // We can't handle the RegExp with IRRegExp. 498 // We can't handle the RegExp with IRRegExp.
456 return Handle<Object>::null(); 499 return Handle<Object>::null();
457 } 500 }
458 501
459 // Prepare space for the return values. 502 // Prepare space for the return values.
460 int number_of_registers = IrregexpNumberOfRegisters(irregexp); 503 int number_of_capture_registers =
461 OffsetsVector offsets(number_of_registers); 504 (IrregexpNumberOfCaptures(irregexp) + 1) * 2;
462 505 OffsetsVector offsets(number_of_capture_registers);
463 int num_captures = IrregexpNumberOfCaptures(irregexp);
464 506
465 int previous_index = static_cast<int>(DoubleToInteger(index->Number())); 507 int previous_index = static_cast<int>(DoubleToInteger(index->Number()));
466 508
467 #ifdef DEBUG 509 #ifdef DEBUG
468 if (FLAG_trace_regexp_bytecodes) { 510 if (FLAG_trace_regexp_bytecodes) {
469 String* pattern = regexp->Pattern(); 511 String* pattern = regexp->Pattern();
470 PrintF("\n\nRegexp match: /%s/\n\n", *(pattern->ToCString())); 512 PrintF("\n\nRegexp match: /%s/\n\n", *(pattern->ToCString()));
471 PrintF("\n\nSubject string: '%s'\n\n", *(subject->ToCString())); 513 PrintF("\n\nSubject string: '%s'\n\n", *(subject->ToCString()));
472 } 514 }
473 #endif 515 #endif
474 516
475 if (!subject->IsFlat(StringShape(*subject))) { 517 if (!subject->IsFlat(StringShape(*subject))) {
476 FlattenString(subject); 518 FlattenString(subject);
477 } 519 }
478 520
521 EnsureSize(lastMatchInfo, kFirstCapture + number_of_capture_registers);
522
479 return IrregexpExecOnce(irregexp, 523 return IrregexpExecOnce(irregexp,
480 num_captures, 524 number_of_capture_registers,
525 lastMatchInfo,
481 subject, 526 subject,
482 previous_index, 527 previous_index,
483 offsets.vector(), 528 offsets.vector(),
484 offsets.length()); 529 offsets.length());
485 } 530 }
486 531
487 532
488 Handle<Object> RegExpImpl::IrregexpExecGlobal(Handle<JSRegExp> regexp, 533 Handle<Object> RegExpImpl::IrregexpExecGlobal(Handle<JSRegExp> regexp,
489 Handle<String> subject) { 534 Handle<String> subject,
535 Handle<JSArray> lastMatchInfo) {
490 ASSERT_EQ(regexp->TypeTag(), JSRegExp::IRREGEXP); 536 ASSERT_EQ(regexp->TypeTag(), JSRegExp::IRREGEXP);
491 537
492 bool is_ascii = StringShape(*subject).IsAsciiRepresentation(); 538 bool is_ascii = StringShape(*subject).IsAsciiRepresentation();
493 Handle<FixedArray> irregexp = GetCompiledIrregexp(regexp, is_ascii); 539 Handle<FixedArray> irregexp = GetCompiledIrregexp(regexp, is_ascii);
494 if (irregexp.is_null()) { 540 if (irregexp.is_null()) {
495 return Handle<Object>::null(); 541 return Handle<Object>::null();
496 } 542 }
497 543
498 // Prepare space for the return values. 544 // Prepare space for the return values.
499 int number_of_registers = IrregexpNumberOfRegisters(irregexp); 545 int number_of_capture_registers =
500 OffsetsVector offsets(number_of_registers); 546 (IrregexpNumberOfCaptures(irregexp) + 1) * 2;
547 OffsetsVector offsets(number_of_capture_registers);
501 548
502 int previous_index = 0; 549 int previous_index = 0;
503 550
504 Handle<JSArray> result = Factory::NewJSArray(0); 551 Handle<JSArray> result = Factory::NewJSArray(0);
505 int i = 0; 552 int result_length = 0;
506 Handle<Object> matches; 553 Handle<Object> matches;
507 554
508 if (!subject->IsFlat(StringShape(*subject))) { 555 if (!subject->IsFlat(StringShape(*subject))) {
509 FlattenString(subject); 556 FlattenString(subject);
510 } 557 }
511 558
559 EnsureSize(lastMatchInfo, kFirstCapture + number_of_capture_registers);
560
512 while (true) { 561 while (true) {
513 if (previous_index > subject->length() || previous_index < 0) { 562 if (previous_index > subject->length() || previous_index < 0) {
514 // Per ECMA-262 15.10.6.2, if the previous index is greater than the 563 // Per ECMA-262 15.10.6.2, if the previous index is greater than the
515 // string length, there is no match. 564 // string length, there is no match.
516 matches = Factory::null_value(); 565 matches = Factory::null_value();
517 return result; 566 return result;
518 } else { 567 } else {
519 #ifdef DEBUG 568 #ifdef DEBUG
520 if (FLAG_trace_regexp_bytecodes) { 569 if (FLAG_trace_regexp_bytecodes) {
521 String* pattern = regexp->Pattern(); 570 String* pattern = regexp->Pattern();
522 PrintF("\n\nRegexp match: /%s/\n\n", *(pattern->ToCString())); 571 PrintF("\n\nRegexp match: /%s/\n\n", *(pattern->ToCString()));
523 PrintF("\n\nSubject string: '%s'\n\n", *(subject->ToCString())); 572 PrintF("\n\nSubject string: '%s'\n\n", *(subject->ToCString()));
524 } 573 }
525 #endif 574 #endif
526 matches = IrregexpExecOnce(irregexp, 575 matches = IrregexpExecOnce(irregexp,
527 IrregexpNumberOfCaptures(irregexp), 576 number_of_capture_registers,
577 lastMatchInfo,
528 subject, 578 subject,
529 previous_index, 579 previous_index,
530 offsets.vector(), 580 offsets.vector(),
531 offsets.length()); 581 offsets.length());
532 582
533 if (matches.is_null()) { 583 if (matches.is_null()) {
534 ASSERT(Top::has_pending_exception()); 584 ASSERT(Top::has_pending_exception());
535 return matches; 585 return matches;
536 } 586 }
537 587
538 if (matches->IsJSArray()) { 588 if (matches->IsJSArray()) {
539 SetElement(result, i, matches); 589 // Create an array that looks like the static lastMatchInfo array
540 i++; 590 // that is attached to the global RegExp object. We will be returning
541 previous_index = offsets.vector()[1]; 591 // an array of these.
542 if (offsets.vector()[0] == offsets.vector()[1]) { 592 Handle<FixedArray> matches_array(JSArray::cast(*matches)->elements());
Christian Plesner Hansen 2009/02/26 15:18:53 Again with the unbounded number of handles.
593 Handle<JSArray> latest_match =
594 Factory::NewJSArray(kFirstCapture + number_of_capture_registers);
595 Handle<FixedArray> latest_match_array(latest_match->elements());
596
597 for (int i = 0; i < number_of_capture_registers; i++) {
598 SetCapture(*latest_match_array, i, GetCapture(*matches_array, i));
599 }
600 SetLastCaptureCount(*latest_match_array, number_of_capture_registers);
601
602 SetElement(result, result_length, latest_match);
603 result_length++;
604 previous_index = GetCapture(*matches_array, 1);
605 if (GetCapture(*matches_array, 0) == previous_index)
543 previous_index++; 606 previous_index++;
544 } 607
545 } else { 608 } else {
546 ASSERT(matches->IsNull()); 609 ASSERT(matches->IsNull());
547 return result; 610 return result;
548 } 611 }
549 } 612 }
550 } 613 }
551 } 614 }
552 615
553 616
554 Handle<Object> RegExpImpl::IrregexpExecOnce(Handle<FixedArray> irregexp, 617 Handle<Object> RegExpImpl::IrregexpExecOnce(Handle<FixedArray> irregexp,
555 int num_captures, 618 int number_of_capture_registers,
619 Handle<JSArray> lastMatchInfo,
556 Handle<String> subject, 620 Handle<String> subject,
557 int previous_index, 621 int previous_index,
558 int* offsets_vector, 622 int* offsets_vector,
559 int offsets_vector_length) { 623 int offsets_vector_length) {
560 ASSERT(subject->IsFlat(StringShape(*subject))); 624 ASSERT(subject->IsFlat(StringShape(*subject)));
561 bool rc; 625 bool rc;
562 626
563 int tag = Smi::cast(irregexp->get(kIrregexpImplementationIndex))->value(); 627 int tag = Smi::cast(irregexp->get(kIrregexpImplementationIndex))->value();
564 628
565 switch (tag) { 629 switch (tag) {
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
635 } 699 }
636 } 700 }
637 break; 701 break;
638 #else 702 #else
639 UNIMPLEMENTED(); 703 UNIMPLEMENTED();
640 rc = false; 704 rc = false;
641 break; 705 break;
642 #endif 706 #endif
643 } 707 }
644 case RegExpMacroAssembler::kBytecodeImplementation: { 708 case RegExpMacroAssembler::kBytecodeImplementation: {
645 for (int i = (num_captures + 1) * 2 - 1; i >= 0; i--) { 709 for (int i = number_of_capture_registers - 1; i >= 0; i--) {
646 offsets_vector[i] = -1; 710 offsets_vector[i] = -1;
647 } 711 }
648 Handle<ByteArray> byte_codes = IrregexpByteCode(irregexp); 712 Handle<ByteArray> byte_codes = IrregexpByteCode(irregexp);
649 713
650 rc = IrregexpInterpreter::Match(byte_codes, 714 rc = IrregexpInterpreter::Match(byte_codes,
651 subject, 715 subject,
652 offsets_vector, 716 offsets_vector,
653 previous_index); 717 previous_index);
654 break; 718 break;
655 } 719 }
656 case RegExpMacroAssembler::kARMImplementation: 720 case RegExpMacroAssembler::kARMImplementation:
657 default: 721 default:
658 UNREACHABLE(); 722 UNREACHABLE();
659 rc = false; 723 rc = false;
660 break; 724 break;
661 } 725 }
662 726
663 if (!rc) { 727 if (!rc) {
664 return Factory::null_value(); 728 return Factory::null_value();
665 } 729 }
666 730
667 Handle<FixedArray> array = Factory::NewFixedArray(2 * (num_captures+1)); 731 Handle<FixedArray> array(lastMatchInfo->elements());
668 // The captures come in (start, end+1) pairs. 732 // The captures come in (start, end+1) pairs.
669 for (int i = 0; i < 2 * (num_captures + 1); i += 2) { 733 for (int i = 0; i < number_of_capture_registers; i += 2) {
670 array->set(i, Smi::FromInt(offsets_vector[i])); 734 SetCapture(*array, i, offsets_vector[i]);
671 array->set(i + 1, Smi::FromInt(offsets_vector[i + 1])); 735 SetCapture(*array, i + 1, offsets_vector[i + 1]);
672 } 736 }
673 return Factory::NewJSArrayWithElements(array); 737 SetLastCaptureCount(*array, number_of_capture_registers);
738 SetLastSubject(*array, *subject);
739 SetLastInput(*array, *subject);
740 return lastMatchInfo;
674 } 741 }
675 742
676 743
677 // ------------------------------------------------------------------- 744 // -------------------------------------------------------------------
678 // Implmentation of the Irregexp regular expression engine. 745 // Implmentation of the Irregexp regular expression engine.
679 // 746 //
680 // The Irregexp regular expression engine is intended to be a complete 747 // The Irregexp regular expression engine is intended to be a complete
681 // implementation of ECMAScript regular expressions. It generates either 748 // implementation of ECMAScript regular expressions. It generates either
682 // bytecodes or native code. 749 // bytecodes or native code.
683 750
(...skipping 3032 matching lines...) Expand 10 before | Expand all | Expand 10 after
3716 // x{f, t} becomes this: 3783 // x{f, t} becomes this:
3717 // 3784 //
3718 // (r++)<-. 3785 // (r++)<-.
3719 // | ` 3786 // | `
3720 // | (x) 3787 // | (x)
3721 // v ^ 3788 // v ^
3722 // (r=0)-->(?)---/ [if r < t] 3789 // (r=0)-->(?)---/ [if r < t]
3723 // | 3790 // |
3724 // [if r >= f] \----> ... 3791 // [if r >= f] \----> ...
3725 // 3792 //
3726 //
3727 // TODO(someone): clear captures on repetition and handle empty
3728 // matches.
3729 3793
3730 // 15.10.2.5 RepeatMatcher algorithm. 3794 // 15.10.2.5 RepeatMatcher algorithm.
3731 // The parser has already eliminated the case where max is 0. In the case 3795 // The parser has already eliminated the case where max is 0. In the case
3732 // where max_match is zero the parser has removed the quantifier if min was 3796 // where max_match is zero the parser has removed the quantifier if min was
3733 // > 0 and removed the atom if min was 0. See AddQuantifierToAtom. 3797 // > 0 and removed the atom if min was 0. See AddQuantifierToAtom.
3734 3798
3735 // If we know that we cannot match zero length then things are a little 3799 // If we know that we cannot match zero length then things are a little
3736 // simpler since we don't need to make the special zero length match check 3800 // simpler since we don't need to make the special zero length match check
3737 // from step 2.1. If the min and max are small we can unroll a little in 3801 // from step 2.1. If the min and max are small we can unroll a little in
3738 // this case. 3802 // this case.
(...skipping 919 matching lines...) Expand 10 before | Expand all | Expand 10 after
4658 EmbeddedVector<byte, 1024> codes; 4722 EmbeddedVector<byte, 1024> codes;
4659 RegExpMacroAssemblerIrregexp macro_assembler(codes); 4723 RegExpMacroAssemblerIrregexp macro_assembler(codes);
4660 return compiler.Assemble(&macro_assembler, 4724 return compiler.Assemble(&macro_assembler,
4661 node, 4725 node,
4662 data->capture_count, 4726 data->capture_count,
4663 pattern); 4727 pattern);
4664 } 4728 }
4665 4729
4666 4730
4667 }} // namespace v8::internal 4731 }} // namespace v8::internal
OLDNEW
« no previous file with comments | « src/jsregexp.h ('k') | src/macros.py » ('j') | src/macros.py » ('J')

Powered by Google App Engine
This is Rietveld 408576698