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

Side by Side Diff: src/jsregexp.cc

Issue 10443114: Progress towards making Zones independent of Isolates and Threads. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Fix nits and rebase on current bleeding_edge Created 8 years, 6 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/list.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 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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 213 matching lines...) Expand 10 before | Expand all | Expand 10 after
224 Handle<FixedArray> data(FixedArray::cast(re->data())); 224 Handle<FixedArray> data(FixedArray::cast(re->data()));
225 compilation_cache->PutRegExp(pattern, flags, data); 225 compilation_cache->PutRegExp(pattern, flags, data);
226 226
227 return re; 227 return re;
228 } 228 }
229 229
230 230
231 Handle<Object> RegExpImpl::Exec(Handle<JSRegExp> regexp, 231 Handle<Object> RegExpImpl::Exec(Handle<JSRegExp> regexp,
232 Handle<String> subject, 232 Handle<String> subject,
233 int index, 233 int index,
234 Handle<JSArray> last_match_info) { 234 Handle<JSArray> last_match_info,
235 Zone* zone) {
235 switch (regexp->TypeTag()) { 236 switch (regexp->TypeTag()) {
236 case JSRegExp::ATOM: 237 case JSRegExp::ATOM:
237 return AtomExec(regexp, subject, index, last_match_info); 238 return AtomExec(regexp, subject, index, last_match_info);
238 case JSRegExp::IRREGEXP: { 239 case JSRegExp::IRREGEXP: {
239 Handle<Object> result = 240 Handle<Object> result =
240 IrregexpExec(regexp, subject, index, last_match_info); 241 IrregexpExec(regexp, subject, index, last_match_info, zone);
241 ASSERT(!result.is_null() || 242 ASSERT(!result.is_null() ||
242 regexp->GetIsolate()->has_pending_exception()); 243 regexp->GetIsolate()->has_pending_exception());
243 return result; 244 return result;
244 } 245 }
245 default: 246 default:
246 UNREACHABLE(); 247 UNREACHABLE();
247 return Handle<Object>::null(); 248 return Handle<Object>::null();
248 } 249 }
249 } 250 }
250 251
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
337 338
338 // Irregexp implementation. 339 // Irregexp implementation.
339 340
340 // Ensures that the regexp object contains a compiled version of the 341 // Ensures that the regexp object contains a compiled version of the
341 // source for either ASCII or non-ASCII strings. 342 // source for either ASCII or non-ASCII strings.
342 // If the compiled version doesn't already exist, it is compiled 343 // If the compiled version doesn't already exist, it is compiled
343 // from the source pattern. 344 // from the source pattern.
344 // If compilation fails, an exception is thrown and this function 345 // If compilation fails, an exception is thrown and this function
345 // returns false. 346 // returns false.
346 bool RegExpImpl::EnsureCompiledIrregexp( 347 bool RegExpImpl::EnsureCompiledIrregexp(
347 Handle<JSRegExp> re, Handle<String> sample_subject, bool is_ascii) { 348 Handle<JSRegExp> re, Handle<String> sample_subject, bool is_ascii,
349 Zone* zone) {
348 Object* compiled_code = re->DataAt(JSRegExp::code_index(is_ascii)); 350 Object* compiled_code = re->DataAt(JSRegExp::code_index(is_ascii));
349 #ifdef V8_INTERPRETED_REGEXP 351 #ifdef V8_INTERPRETED_REGEXP
350 if (compiled_code->IsByteArray()) return true; 352 if (compiled_code->IsByteArray()) return true;
351 #else // V8_INTERPRETED_REGEXP (RegExp native code) 353 #else // V8_INTERPRETED_REGEXP (RegExp native code)
352 if (compiled_code->IsCode()) return true; 354 if (compiled_code->IsCode()) return true;
353 #endif 355 #endif
354 // We could potentially have marked this as flushable, but have kept 356 // We could potentially have marked this as flushable, but have kept
355 // a saved version if we did not flush it yet. 357 // a saved version if we did not flush it yet.
356 Object* saved_code = re->DataAt(JSRegExp::saved_code_index(is_ascii)); 358 Object* saved_code = re->DataAt(JSRegExp::saved_code_index(is_ascii));
357 if (saved_code->IsCode()) { 359 if (saved_code->IsCode()) {
358 // Reinstate the code in the original place. 360 // Reinstate the code in the original place.
359 re->SetDataAt(JSRegExp::code_index(is_ascii), saved_code); 361 re->SetDataAt(JSRegExp::code_index(is_ascii), saved_code);
360 ASSERT(compiled_code->IsSmi()); 362 ASSERT(compiled_code->IsSmi());
361 return true; 363 return true;
362 } 364 }
363 return CompileIrregexp(re, sample_subject, is_ascii); 365 return CompileIrregexp(re, sample_subject, is_ascii, zone);
364 } 366 }
365 367
366 368
367 static bool CreateRegExpErrorObjectAndThrow(Handle<JSRegExp> re, 369 static bool CreateRegExpErrorObjectAndThrow(Handle<JSRegExp> re,
368 bool is_ascii, 370 bool is_ascii,
369 Handle<String> error_message, 371 Handle<String> error_message,
370 Isolate* isolate) { 372 Isolate* isolate) {
371 Factory* factory = isolate->factory(); 373 Factory* factory = isolate->factory();
372 Handle<FixedArray> elements = factory->NewFixedArray(2); 374 Handle<FixedArray> elements = factory->NewFixedArray(2);
373 elements->set(0, re->Pattern()); 375 elements->set(0, re->Pattern());
374 elements->set(1, *error_message); 376 elements->set(1, *error_message);
375 Handle<JSArray> array = factory->NewJSArrayWithElements(elements); 377 Handle<JSArray> array = factory->NewJSArrayWithElements(elements);
376 Handle<Object> regexp_err = 378 Handle<Object> regexp_err =
377 factory->NewSyntaxError("malformed_regexp", array); 379 factory->NewSyntaxError("malformed_regexp", array);
378 isolate->Throw(*regexp_err); 380 isolate->Throw(*regexp_err);
379 return false; 381 return false;
380 } 382 }
381 383
382 384
383 bool RegExpImpl::CompileIrregexp(Handle<JSRegExp> re, 385 bool RegExpImpl::CompileIrregexp(Handle<JSRegExp> re,
384 Handle<String> sample_subject, 386 Handle<String> sample_subject,
385 bool is_ascii) { 387 bool is_ascii,
388 Zone* zone) {
386 // Compile the RegExp. 389 // Compile the RegExp.
387 Isolate* isolate = re->GetIsolate(); 390 Isolate* isolate = re->GetIsolate();
388 ZoneScope zone_scope(isolate, DELETE_ON_EXIT); 391 ZoneScope zone_scope(isolate, DELETE_ON_EXIT);
389 PostponeInterruptsScope postpone(isolate); 392 PostponeInterruptsScope postpone(isolate);
390 // If we had a compilation error the last time this is saved at the 393 // If we had a compilation error the last time this is saved at the
391 // saved code index. 394 // saved code index.
392 Object* entry = re->DataAt(JSRegExp::code_index(is_ascii)); 395 Object* entry = re->DataAt(JSRegExp::code_index(is_ascii));
393 // When arriving here entry can only be a smi, either representing an 396 // When arriving here entry can only be a smi, either representing an
394 // uncompiled regexp, a previous compilation error, or code that has 397 // uncompiled regexp, a previous compilation error, or code that has
395 // been flushed. 398 // been flushed.
(...skipping 30 matching lines...) Expand all
426 "malformed_regexp"); 429 "malformed_regexp");
427 return false; 430 return false;
428 } 431 }
429 RegExpEngine::CompilationResult result = 432 RegExpEngine::CompilationResult result =
430 RegExpEngine::Compile(&compile_data, 433 RegExpEngine::Compile(&compile_data,
431 flags.is_ignore_case(), 434 flags.is_ignore_case(),
432 flags.is_global(), 435 flags.is_global(),
433 flags.is_multiline(), 436 flags.is_multiline(),
434 pattern, 437 pattern,
435 sample_subject, 438 sample_subject,
436 is_ascii); 439 is_ascii,
440 zone);
437 if (result.error_message != NULL) { 441 if (result.error_message != NULL) {
438 // Unable to compile regexp. 442 // Unable to compile regexp.
439 Handle<String> error_message = 443 Handle<String> error_message =
440 isolate->factory()->NewStringFromUtf8(CStrVector(result.error_message)); 444 isolate->factory()->NewStringFromUtf8(CStrVector(result.error_message));
441 CreateRegExpErrorObjectAndThrow(re, is_ascii, error_message, isolate); 445 CreateRegExpErrorObjectAndThrow(re, is_ascii, error_message, isolate);
442 return false; 446 return false;
443 } 447 }
444 448
445 Handle<FixedArray> data = Handle<FixedArray>(FixedArray::cast(re->data())); 449 Handle<FixedArray> data = Handle<FixedArray>(FixedArray::cast(re->data()));
446 data->set(JSRegExp::code_index(is_ascii), result.code); 450 data->set(JSRegExp::code_index(is_ascii), result.code);
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
491 // Initialize compiled code entries to null. 495 // Initialize compiled code entries to null.
492 re->GetIsolate()->factory()->SetRegExpIrregexpData(re, 496 re->GetIsolate()->factory()->SetRegExpIrregexpData(re,
493 JSRegExp::IRREGEXP, 497 JSRegExp::IRREGEXP,
494 pattern, 498 pattern,
495 flags, 499 flags,
496 capture_count); 500 capture_count);
497 } 501 }
498 502
499 503
500 int RegExpImpl::IrregexpPrepare(Handle<JSRegExp> regexp, 504 int RegExpImpl::IrregexpPrepare(Handle<JSRegExp> regexp,
501 Handle<String> subject) { 505 Handle<String> subject,
506 Zone* zone) {
502 if (!subject->IsFlat()) FlattenString(subject); 507 if (!subject->IsFlat()) FlattenString(subject);
503 508
504 // Check the asciiness of the underlying storage. 509 // Check the asciiness of the underlying storage.
505 bool is_ascii = subject->IsAsciiRepresentationUnderneath(); 510 bool is_ascii = subject->IsAsciiRepresentationUnderneath();
506 if (!EnsureCompiledIrregexp(regexp, subject, is_ascii)) return -1; 511 if (!EnsureCompiledIrregexp(regexp, subject, is_ascii, zone)) return -1;
507 512
508 #ifdef V8_INTERPRETED_REGEXP 513 #ifdef V8_INTERPRETED_REGEXP
509 // Byte-code regexp needs space allocated for all its registers. 514 // Byte-code regexp needs space allocated for all its registers.
510 return IrregexpNumberOfRegisters(FixedArray::cast(regexp->data())); 515 return IrregexpNumberOfRegisters(FixedArray::cast(regexp->data()));
511 #else // V8_INTERPRETED_REGEXP 516 #else // V8_INTERPRETED_REGEXP
512 // Native regexp only needs room to output captures. Registers are handled 517 // Native regexp only needs room to output captures. Registers are handled
513 // internally. 518 // internally.
514 return (IrregexpNumberOfCaptures(FixedArray::cast(regexp->data())) + 1) * 2; 519 return (IrregexpNumberOfCaptures(FixedArray::cast(regexp->data())) + 1) * 2;
515 #endif // V8_INTERPRETED_REGEXP 520 #endif // V8_INTERPRETED_REGEXP
516 } 521 }
(...skipping 12 matching lines...) Expand all
529 *max_matches = size / registers_per_match; 534 *max_matches = size / registers_per_match;
530 return size; 535 return size;
531 #endif // V8_INTERPRETED_REGEXP 536 #endif // V8_INTERPRETED_REGEXP
532 } 537 }
533 538
534 539
535 int RegExpImpl::IrregexpExecRaw( 540 int RegExpImpl::IrregexpExecRaw(
536 Handle<JSRegExp> regexp, 541 Handle<JSRegExp> regexp,
537 Handle<String> subject, 542 Handle<String> subject,
538 int index, 543 int index,
539 Vector<int> output) { 544 Vector<int> output,
545 Zone* zone) {
540 Isolate* isolate = regexp->GetIsolate(); 546 Isolate* isolate = regexp->GetIsolate();
541 547
542 Handle<FixedArray> irregexp(FixedArray::cast(regexp->data()), isolate); 548 Handle<FixedArray> irregexp(FixedArray::cast(regexp->data()), isolate);
543 549
544 ASSERT(index >= 0); 550 ASSERT(index >= 0);
545 ASSERT(index <= subject->length()); 551 ASSERT(index <= subject->length());
546 ASSERT(subject->IsFlat()); 552 ASSERT(subject->IsFlat());
547 553
548 bool is_ascii = subject->IsAsciiRepresentationUnderneath(); 554 bool is_ascii = subject->IsAsciiRepresentationUnderneath();
549 555
550 #ifndef V8_INTERPRETED_REGEXP 556 #ifndef V8_INTERPRETED_REGEXP
551 ASSERT(output.length() >= (IrregexpNumberOfCaptures(*irregexp) + 1) * 2); 557 ASSERT(output.length() >= (IrregexpNumberOfCaptures(*irregexp) + 1) * 2);
552 do { 558 do {
553 EnsureCompiledIrregexp(regexp, subject, is_ascii); 559 EnsureCompiledIrregexp(regexp, subject, is_ascii, zone);
554 Handle<Code> code(IrregexpNativeCode(*irregexp, is_ascii), isolate); 560 Handle<Code> code(IrregexpNativeCode(*irregexp, is_ascii), isolate);
555 NativeRegExpMacroAssembler::Result res = 561 NativeRegExpMacroAssembler::Result res =
556 NativeRegExpMacroAssembler::Match(code, 562 NativeRegExpMacroAssembler::Match(code,
557 subject, 563 subject,
558 output.start(), 564 output.start(),
559 output.length(), 565 output.length(),
560 index, 566 index,
561 isolate); 567 isolate);
562 if (res != NativeRegExpMacroAssembler::RETRY) { 568 if (res != NativeRegExpMacroAssembler::RETRY) {
563 ASSERT(res != NativeRegExpMacroAssembler::EXCEPTION || 569 ASSERT(res != NativeRegExpMacroAssembler::EXCEPTION ||
564 isolate->has_pending_exception()); 570 isolate->has_pending_exception());
565 STATIC_ASSERT( 571 STATIC_ASSERT(
566 static_cast<int>(NativeRegExpMacroAssembler::SUCCESS) == RE_SUCCESS); 572 static_cast<int>(NativeRegExpMacroAssembler::SUCCESS) == RE_SUCCESS);
567 STATIC_ASSERT( 573 STATIC_ASSERT(
568 static_cast<int>(NativeRegExpMacroAssembler::FAILURE) == RE_FAILURE); 574 static_cast<int>(NativeRegExpMacroAssembler::FAILURE) == RE_FAILURE);
569 STATIC_ASSERT(static_cast<int>(NativeRegExpMacroAssembler::EXCEPTION) 575 STATIC_ASSERT(static_cast<int>(NativeRegExpMacroAssembler::EXCEPTION)
570 == RE_EXCEPTION); 576 == RE_EXCEPTION);
571 return static_cast<IrregexpResult>(res); 577 return static_cast<IrregexpResult>(res);
572 } 578 }
573 // If result is RETRY, the string has changed representation, and we 579 // If result is RETRY, the string has changed representation, and we
574 // must restart from scratch. 580 // must restart from scratch.
575 // In this case, it means we must make sure we are prepared to handle 581 // In this case, it means we must make sure we are prepared to handle
576 // the, potentially, different subject (the string can switch between 582 // the, potentially, different subject (the string can switch between
577 // being internal and external, and even between being ASCII and UC16, 583 // being internal and external, and even between being ASCII and UC16,
578 // but the characters are always the same). 584 // but the characters are always the same).
579 IrregexpPrepare(regexp, subject); 585 IrregexpPrepare(regexp, subject, zone);
580 is_ascii = subject->IsAsciiRepresentationUnderneath(); 586 is_ascii = subject->IsAsciiRepresentationUnderneath();
581 } while (true); 587 } while (true);
582 UNREACHABLE(); 588 UNREACHABLE();
583 return RE_EXCEPTION; 589 return RE_EXCEPTION;
584 #else // V8_INTERPRETED_REGEXP 590 #else // V8_INTERPRETED_REGEXP
585 591
586 ASSERT(output.length() >= IrregexpNumberOfRegisters(*irregexp)); 592 ASSERT(output.length() >= IrregexpNumberOfRegisters(*irregexp));
587 // We must have done EnsureCompiledIrregexp, so we can get the number of 593 // We must have done EnsureCompiledIrregexp, so we can get the number of
588 // registers. 594 // registers.
589 int* register_vector = output.start(); 595 int* register_vector = output.start();
(...skipping 14 matching lines...) Expand all
604 isolate->StackOverflow(); 610 isolate->StackOverflow();
605 } 611 }
606 return result; 612 return result;
607 #endif // V8_INTERPRETED_REGEXP 613 #endif // V8_INTERPRETED_REGEXP
608 } 614 }
609 615
610 616
611 Handle<Object> RegExpImpl::IrregexpExec(Handle<JSRegExp> jsregexp, 617 Handle<Object> RegExpImpl::IrregexpExec(Handle<JSRegExp> jsregexp,
612 Handle<String> subject, 618 Handle<String> subject,
613 int previous_index, 619 int previous_index,
614 Handle<JSArray> last_match_info) { 620 Handle<JSArray> last_match_info,
621 Zone* zone) {
615 Isolate* isolate = jsregexp->GetIsolate(); 622 Isolate* isolate = jsregexp->GetIsolate();
616 ASSERT_EQ(jsregexp->TypeTag(), JSRegExp::IRREGEXP); 623 ASSERT_EQ(jsregexp->TypeTag(), JSRegExp::IRREGEXP);
617 624
618 // Prepare space for the return values. 625 // Prepare space for the return values.
619 #ifdef V8_INTERPRETED_REGEXP 626 #ifdef V8_INTERPRETED_REGEXP
620 #ifdef DEBUG 627 #ifdef DEBUG
621 if (FLAG_trace_regexp_bytecodes) { 628 if (FLAG_trace_regexp_bytecodes) {
622 String* pattern = jsregexp->Pattern(); 629 String* pattern = jsregexp->Pattern();
623 PrintF("\n\nRegexp match: /%s/\n\n", *(pattern->ToCString())); 630 PrintF("\n\nRegexp match: /%s/\n\n", *(pattern->ToCString()));
624 PrintF("\n\nSubject string: '%s'\n\n", *(subject->ToCString())); 631 PrintF("\n\nSubject string: '%s'\n\n", *(subject->ToCString()));
625 } 632 }
626 #endif 633 #endif
627 #endif 634 #endif
628 int required_registers = RegExpImpl::IrregexpPrepare(jsregexp, subject); 635 int required_registers = RegExpImpl::IrregexpPrepare(jsregexp, subject, zone);
629 if (required_registers < 0) { 636 if (required_registers < 0) {
630 // Compiling failed with an exception. 637 // Compiling failed with an exception.
631 ASSERT(isolate->has_pending_exception()); 638 ASSERT(isolate->has_pending_exception());
632 return Handle<Object>::null(); 639 return Handle<Object>::null();
633 } 640 }
634 641
635 OffsetsVector registers(required_registers, isolate); 642 OffsetsVector registers(required_registers, isolate);
636 643
637 int res = RegExpImpl::IrregexpExecRaw( 644 int res = RegExpImpl::IrregexpExecRaw(jsregexp, subject, previous_index,
638 jsregexp, subject, previous_index, Vector<int>(registers.vector(), 645 Vector<int>(registers.vector(),
639 registers.length())); 646 registers.length()),
647 zone);
640 if (res == RE_SUCCESS) { 648 if (res == RE_SUCCESS) {
641 int capture_register_count = 649 int capture_register_count =
642 (IrregexpNumberOfCaptures(FixedArray::cast(jsregexp->data())) + 1) * 2; 650 (IrregexpNumberOfCaptures(FixedArray::cast(jsregexp->data())) + 1) * 2;
643 last_match_info->EnsureSize(capture_register_count + kLastMatchOverhead); 651 last_match_info->EnsureSize(capture_register_count + kLastMatchOverhead);
644 AssertNoAllocation no_gc; 652 AssertNoAllocation no_gc;
645 int* register_vector = registers.vector(); 653 int* register_vector = registers.vector();
646 FixedArray* array = FixedArray::cast(last_match_info->elements()); 654 FixedArray* array = FixedArray::cast(last_match_info->elements());
647 for (int i = 0; i < capture_register_count; i += 2) { 655 for (int i = 0; i < capture_register_count; i += 2) {
648 SetCapture(array, i, register_vector[i]); 656 SetCapture(array, i, register_vector[i]);
649 SetCapture(array, i + 1, register_vector[i + 1]); 657 SetCapture(array, i + 1, register_vector[i + 1]);
(...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after
910 918
911 919
912 private: 920 private:
913 CharacterFrequency frequencies_[RegExpMacroAssembler::kTableSize]; 921 CharacterFrequency frequencies_[RegExpMacroAssembler::kTableSize];
914 int total_samples_; 922 int total_samples_;
915 }; 923 };
916 924
917 925
918 class RegExpCompiler { 926 class RegExpCompiler {
919 public: 927 public:
920 RegExpCompiler(int capture_count, bool ignore_case, bool is_ascii); 928 RegExpCompiler(int capture_count, bool ignore_case, bool is_ascii,
929 Zone* zone);
921 930
922 int AllocateRegister() { 931 int AllocateRegister() {
923 if (next_register_ >= RegExpMacroAssembler::kMaxRegister) { 932 if (next_register_ >= RegExpMacroAssembler::kMaxRegister) {
924 reg_exp_too_big_ = true; 933 reg_exp_too_big_ = true;
925 return next_register_; 934 return next_register_;
926 } 935 }
927 return next_register_++; 936 return next_register_++;
928 } 937 }
929 938
930 RegExpEngine::CompilationResult Assemble(RegExpMacroAssembler* assembler, 939 RegExpEngine::CompilationResult Assemble(RegExpMacroAssembler* assembler,
(...skipping 19 matching lines...) Expand all
950 959
951 inline bool ignore_case() { return ignore_case_; } 960 inline bool ignore_case() { return ignore_case_; }
952 inline bool ascii() { return ascii_; } 961 inline bool ascii() { return ascii_; }
953 FrequencyCollator* frequency_collator() { return &frequency_collator_; } 962 FrequencyCollator* frequency_collator() { return &frequency_collator_; }
954 963
955 int current_expansion_factor() { return current_expansion_factor_; } 964 int current_expansion_factor() { return current_expansion_factor_; }
956 void set_current_expansion_factor(int value) { 965 void set_current_expansion_factor(int value) {
957 current_expansion_factor_ = value; 966 current_expansion_factor_ = value;
958 } 967 }
959 968
969 Zone* zone() { return zone_; }
970
960 static const int kNoRegister = -1; 971 static const int kNoRegister = -1;
961 972
962 private: 973 private:
963 EndNode* accept_; 974 EndNode* accept_;
964 int next_register_; 975 int next_register_;
965 List<RegExpNode*>* work_list_; 976 List<RegExpNode*>* work_list_;
966 int recursion_depth_; 977 int recursion_depth_;
967 RegExpMacroAssembler* macro_assembler_; 978 RegExpMacroAssembler* macro_assembler_;
968 bool ignore_case_; 979 bool ignore_case_;
969 bool ascii_; 980 bool ascii_;
970 bool reg_exp_too_big_; 981 bool reg_exp_too_big_;
971 int current_expansion_factor_; 982 int current_expansion_factor_;
972 FrequencyCollator frequency_collator_; 983 FrequencyCollator frequency_collator_;
984 Zone* zone_;
973 }; 985 };
974 986
975 987
976 class RecursionCheck { 988 class RecursionCheck {
977 public: 989 public:
978 explicit RecursionCheck(RegExpCompiler* compiler) : compiler_(compiler) { 990 explicit RecursionCheck(RegExpCompiler* compiler) : compiler_(compiler) {
979 compiler->IncrementRecursionDepth(); 991 compiler->IncrementRecursionDepth();
980 } 992 }
981 ~RecursionCheck() { compiler_->DecrementRecursionDepth(); } 993 ~RecursionCheck() { compiler_->DecrementRecursionDepth(); }
982 private: 994 private:
983 RegExpCompiler* compiler_; 995 RegExpCompiler* compiler_;
984 }; 996 };
985 997
986 998
987 static RegExpEngine::CompilationResult IrregexpRegExpTooBig() { 999 static RegExpEngine::CompilationResult IrregexpRegExpTooBig() {
988 return RegExpEngine::CompilationResult("RegExp too big"); 1000 return RegExpEngine::CompilationResult("RegExp too big");
989 } 1001 }
990 1002
991 1003
992 // Attempts to compile the regexp using an Irregexp code generator. Returns 1004 // Attempts to compile the regexp using an Irregexp code generator. Returns
993 // a fixed array or a null handle depending on whether it succeeded. 1005 // a fixed array or a null handle depending on whether it succeeded.
994 RegExpCompiler::RegExpCompiler(int capture_count, bool ignore_case, bool ascii) 1006 RegExpCompiler::RegExpCompiler(int capture_count, bool ignore_case, bool ascii,
1007 Zone* zone)
995 : next_register_(2 * (capture_count + 1)), 1008 : next_register_(2 * (capture_count + 1)),
996 work_list_(NULL), 1009 work_list_(NULL),
997 recursion_depth_(0), 1010 recursion_depth_(0),
998 ignore_case_(ignore_case), 1011 ignore_case_(ignore_case),
999 ascii_(ascii), 1012 ascii_(ascii),
1000 reg_exp_too_big_(false), 1013 reg_exp_too_big_(false),
1001 current_expansion_factor_(1), 1014 current_expansion_factor_(1),
1002 frequency_collator_() { 1015 frequency_collator_(),
1003 accept_ = new EndNode(EndNode::ACCEPT); 1016 zone_(zone) {
1017 accept_ = new EndNode(EndNode::ACCEPT, zone);
1004 ASSERT(next_register_ - 1 <= RegExpMacroAssembler::kMaxRegister); 1018 ASSERT(next_register_ - 1 <= RegExpMacroAssembler::kMaxRegister);
1005 } 1019 }
1006 1020
1007 1021
1008 RegExpEngine::CompilationResult RegExpCompiler::Assemble( 1022 RegExpEngine::CompilationResult RegExpCompiler::Assemble(
1009 RegExpMacroAssembler* macro_assembler, 1023 RegExpMacroAssembler* macro_assembler,
1010 RegExpNode* start, 1024 RegExpNode* start,
1011 int capture_count, 1025 int capture_count,
1012 Handle<String> pattern) { 1026 Handle<String> pattern) {
1013 Heap* heap = pattern->GetHeap(); 1027 Heap* heap = pattern->GetHeap();
(...skipping 1903 matching lines...) Expand 10 before | Expand all | Expand 10 after
2917 RegExpMacroAssembler* assembler = compiler->macro_assembler(); 2931 RegExpMacroAssembler* assembler = compiler->macro_assembler();
2918 Trace::TriBool next_is_word_character = Trace::UNKNOWN; 2932 Trace::TriBool next_is_word_character = Trace::UNKNOWN;
2919 bool not_at_start = (trace->at_start() == Trace::FALSE); 2933 bool not_at_start = (trace->at_start() == Trace::FALSE);
2920 BoyerMooreLookahead* lookahead = bm_info(not_at_start); 2934 BoyerMooreLookahead* lookahead = bm_info(not_at_start);
2921 if (lookahead == NULL) { 2935 if (lookahead == NULL) {
2922 int eats_at_least = 2936 int eats_at_least =
2923 Min(kMaxLookaheadForBoyerMoore, 2937 Min(kMaxLookaheadForBoyerMoore,
2924 EatsAtLeast(kMaxLookaheadForBoyerMoore, 0, not_at_start)); 2938 EatsAtLeast(kMaxLookaheadForBoyerMoore, 0, not_at_start));
2925 if (eats_at_least >= 1) { 2939 if (eats_at_least >= 1) {
2926 BoyerMooreLookahead* bm = 2940 BoyerMooreLookahead* bm =
2927 new BoyerMooreLookahead(eats_at_least, compiler); 2941 new BoyerMooreLookahead(eats_at_least, compiler, zone());
2928 FillInBMInfo(0, 0, kFillInBMBudget, bm, not_at_start); 2942 FillInBMInfo(0, 0, kFillInBMBudget, bm, not_at_start);
2929 if (bm->at(0)->is_non_word()) next_is_word_character = Trace::FALSE; 2943 if (bm->at(0)->is_non_word()) next_is_word_character = Trace::FALSE;
2930 if (bm->at(0)->is_word()) next_is_word_character = Trace::TRUE; 2944 if (bm->at(0)->is_word()) next_is_word_character = Trace::TRUE;
2931 } 2945 }
2932 } else { 2946 } else {
2933 if (lookahead->at(0)->is_non_word()) next_is_word_character = Trace::FALSE; 2947 if (lookahead->at(0)->is_non_word()) next_is_word_character = Trace::FALSE;
2934 if (lookahead->at(0)->is_word()) next_is_word_character = Trace::TRUE; 2948 if (lookahead->at(0)->is_word()) next_is_word_character = Trace::TRUE;
2935 } 2949 }
2936 bool at_boundary = (type_ == AssertionNode::AT_BOUNDARY); 2950 bool at_boundary = (type_ == AssertionNode::AT_BOUNDARY);
2937 if (next_is_word_character == Trace::UNKNOWN) { 2951 if (next_is_word_character == Trace::UNKNOWN) {
(...skipping 560 matching lines...) Expand 10 before | Expand all | Expand 10 after
3498 void BoyerMoorePositionInfo::SetAll() { 3512 void BoyerMoorePositionInfo::SetAll() {
3499 s_ = w_ = d_ = kLatticeUnknown; 3513 s_ = w_ = d_ = kLatticeUnknown;
3500 if (map_count_ != kMapSize) { 3514 if (map_count_ != kMapSize) {
3501 map_count_ = kMapSize; 3515 map_count_ = kMapSize;
3502 for (int i = 0; i < kMapSize; i++) map_->at(i) = true; 3516 for (int i = 0; i < kMapSize; i++) map_->at(i) = true;
3503 } 3517 }
3504 } 3518 }
3505 3519
3506 3520
3507 BoyerMooreLookahead::BoyerMooreLookahead( 3521 BoyerMooreLookahead::BoyerMooreLookahead(
3508 int length, RegExpCompiler* compiler) 3522 int length, RegExpCompiler* compiler, Zone* zone)
3509 : length_(length), 3523 : length_(length),
3510 compiler_(compiler) { 3524 compiler_(compiler) {
3511 if (compiler->ascii()) { 3525 if (compiler->ascii()) {
3512 max_char_ = String::kMaxAsciiCharCode; 3526 max_char_ = String::kMaxAsciiCharCode;
3513 } else { 3527 } else {
3514 max_char_ = String::kMaxUtf16CodeUnit; 3528 max_char_ = String::kMaxUtf16CodeUnit;
3515 } 3529 }
3516 bitmaps_ = new ZoneList<BoyerMoorePositionInfo*>(length); 3530 bitmaps_ = new ZoneList<BoyerMoorePositionInfo*>(length);
3517 for (int i = 0; i < length; i++) { 3531 for (int i = 0; i < length; i++) {
3518 bitmaps_->Add(new BoyerMoorePositionInfo()); 3532 bitmaps_->Add(new BoyerMoorePositionInfo(zone));
3519 } 3533 }
3520 } 3534 }
3521 3535
3522 3536
3523 // Find the longest range of lookahead that has the fewest number of different 3537 // Find the longest range of lookahead that has the fewest number of different
3524 // characters that can occur at a given position. Since we are optimizing two 3538 // characters that can occur at a given position. Since we are optimizing two
3525 // different parameters at once this is a tradeoff. 3539 // different parameters at once this is a tradeoff.
3526 bool BoyerMooreLookahead::FindWorthwhileInterval(int* from, int* to) { 3540 bool BoyerMooreLookahead::FindWorthwhileInterval(int* from, int* to) {
3527 int biggest_points = 0; 3541 int biggest_points = 0;
3528 // If more than 32 characters out of 128 can occur it is unlikely that we can 3542 // If more than 32 characters out of 128 can occur it is unlikely that we can
(...skipping 325 matching lines...) Expand 10 before | Expand all | Expand 10 after
3854 // not be atoms, they can be any reasonably limited character class or 3868 // not be atoms, they can be any reasonably limited character class or
3855 // small alternation. 3869 // small alternation.
3856 ASSERT(trace->is_trivial()); // This is the case on LoopChoiceNodes. 3870 ASSERT(trace->is_trivial()); // This is the case on LoopChoiceNodes.
3857 BoyerMooreLookahead* lookahead = bm_info(not_at_start); 3871 BoyerMooreLookahead* lookahead = bm_info(not_at_start);
3858 if (lookahead == NULL) { 3872 if (lookahead == NULL) {
3859 eats_at_least = 3873 eats_at_least =
3860 Min(kMaxLookaheadForBoyerMoore, 3874 Min(kMaxLookaheadForBoyerMoore,
3861 EatsAtLeast(kMaxLookaheadForBoyerMoore, 0, not_at_start)); 3875 EatsAtLeast(kMaxLookaheadForBoyerMoore, 0, not_at_start));
3862 if (eats_at_least >= 1) { 3876 if (eats_at_least >= 1) {
3863 BoyerMooreLookahead* bm = 3877 BoyerMooreLookahead* bm =
3864 new BoyerMooreLookahead(eats_at_least, compiler); 3878 new BoyerMooreLookahead(eats_at_least, compiler, zone());
3865 GuardedAlternative alt0 = alternatives_->at(0); 3879 GuardedAlternative alt0 = alternatives_->at(0);
3866 alt0.node()->FillInBMInfo(0, 0, kFillInBMBudget, bm, not_at_start); 3880 alt0.node()->FillInBMInfo(0, 0, kFillInBMBudget, bm, not_at_start);
3867 skip_was_emitted = bm->EmitSkipInstructions(macro_assembler); 3881 skip_was_emitted = bm->EmitSkipInstructions(macro_assembler);
3868 } 3882 }
3869 } else { 3883 } else {
3870 skip_was_emitted = lookahead->EmitSkipInstructions(macro_assembler); 3884 skip_was_emitted = lookahead->EmitSkipInstructions(macro_assembler);
3871 } 3885 }
3872 } 3886 }
3873 } 3887 }
3874 } 3888 }
(...skipping 767 matching lines...) Expand 10 before | Expand all | Expand 10 after
4642 RegExpNode* RegExpCharacterClass::ToNode(RegExpCompiler* compiler, 4656 RegExpNode* RegExpCharacterClass::ToNode(RegExpCompiler* compiler,
4643 RegExpNode* on_success) { 4657 RegExpNode* on_success) {
4644 return new TextNode(this, on_success); 4658 return new TextNode(this, on_success);
4645 } 4659 }
4646 4660
4647 4661
4648 RegExpNode* RegExpDisjunction::ToNode(RegExpCompiler* compiler, 4662 RegExpNode* RegExpDisjunction::ToNode(RegExpCompiler* compiler,
4649 RegExpNode* on_success) { 4663 RegExpNode* on_success) {
4650 ZoneList<RegExpTree*>* alternatives = this->alternatives(); 4664 ZoneList<RegExpTree*>* alternatives = this->alternatives();
4651 int length = alternatives->length(); 4665 int length = alternatives->length();
4652 ChoiceNode* result = new ChoiceNode(length); 4666 ChoiceNode* result = new ChoiceNode(length, compiler->zone());
4653 for (int i = 0; i < length; i++) { 4667 for (int i = 0; i < length; i++) {
4654 GuardedAlternative alternative(alternatives->at(i)->ToNode(compiler, 4668 GuardedAlternative alternative(alternatives->at(i)->ToNode(compiler,
4655 on_success)); 4669 on_success));
4656 result->AddAlternative(alternative); 4670 result->AddAlternative(alternative);
4657 } 4671 }
4658 return result; 4672 return result;
4659 } 4673 }
4660 4674
4661 4675
4662 RegExpNode* RegExpQuantifier::ToNode(RegExpCompiler* compiler, 4676 RegExpNode* RegExpQuantifier::ToNode(RegExpCompiler* compiler,
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
4765 return answer; 4779 return answer;
4766 } 4780 }
4767 } 4781 }
4768 if (max <= kMaxUnrolledMaxMatches && min == 0) { 4782 if (max <= kMaxUnrolledMaxMatches && min == 0) {
4769 ASSERT(max > 0); // Due to the 'if' above. 4783 ASSERT(max > 0); // Due to the 'if' above.
4770 RegExpExpansionLimiter limiter(compiler, max); 4784 RegExpExpansionLimiter limiter(compiler, max);
4771 if (limiter.ok_to_expand()) { 4785 if (limiter.ok_to_expand()) {
4772 // Unroll the optional matches up to max. 4786 // Unroll the optional matches up to max.
4773 RegExpNode* answer = on_success; 4787 RegExpNode* answer = on_success;
4774 for (int i = 0; i < max; i++) { 4788 for (int i = 0; i < max; i++) {
4775 ChoiceNode* alternation = new ChoiceNode(2); 4789 ChoiceNode* alternation = new ChoiceNode(2, compiler->zone());
4776 if (is_greedy) { 4790 if (is_greedy) {
4777 alternation->AddAlternative( 4791 alternation->AddAlternative(
4778 GuardedAlternative(body->ToNode(compiler, answer))); 4792 GuardedAlternative(body->ToNode(compiler, answer)));
4779 alternation->AddAlternative(GuardedAlternative(on_success)); 4793 alternation->AddAlternative(GuardedAlternative(on_success));
4780 } else { 4794 } else {
4781 alternation->AddAlternative(GuardedAlternative(on_success)); 4795 alternation->AddAlternative(GuardedAlternative(on_success));
4782 alternation->AddAlternative( 4796 alternation->AddAlternative(
4783 GuardedAlternative(body->ToNode(compiler, answer))); 4797 GuardedAlternative(body->ToNode(compiler, answer)));
4784 } 4798 }
4785 answer = alternation; 4799 answer = alternation;
4786 if (not_at_start) alternation->set_not_at_start(); 4800 if (not_at_start) alternation->set_not_at_start();
4787 } 4801 }
4788 return answer; 4802 return answer;
4789 } 4803 }
4790 } 4804 }
4791 } 4805 }
4792 bool has_min = min > 0; 4806 bool has_min = min > 0;
4793 bool has_max = max < RegExpTree::kInfinity; 4807 bool has_max = max < RegExpTree::kInfinity;
4794 bool needs_counter = has_min || has_max; 4808 bool needs_counter = has_min || has_max;
4795 int reg_ctr = needs_counter 4809 int reg_ctr = needs_counter
4796 ? compiler->AllocateRegister() 4810 ? compiler->AllocateRegister()
4797 : RegExpCompiler::kNoRegister; 4811 : RegExpCompiler::kNoRegister;
4798 LoopChoiceNode* center = new LoopChoiceNode(body->min_match() == 0); 4812 LoopChoiceNode* center = new LoopChoiceNode(body->min_match() == 0,
4813 compiler->zone());
4799 if (not_at_start) center->set_not_at_start(); 4814 if (not_at_start) center->set_not_at_start();
4800 RegExpNode* loop_return = needs_counter 4815 RegExpNode* loop_return = needs_counter
4801 ? static_cast<RegExpNode*>(ActionNode::IncrementRegister(reg_ctr, center)) 4816 ? static_cast<RegExpNode*>(ActionNode::IncrementRegister(reg_ctr, center))
4802 : static_cast<RegExpNode*>(center); 4817 : static_cast<RegExpNode*>(center);
4803 if (body_can_be_empty) { 4818 if (body_can_be_empty) {
4804 // If the body can be empty we need to check if it was and then 4819 // If the body can be empty we need to check if it was and then
4805 // backtrack. 4820 // backtrack.
4806 loop_return = ActionNode::EmptyMatchCheck(body_start_reg, 4821 loop_return = ActionNode::EmptyMatchCheck(body_start_reg,
4807 reg_ctr, 4822 reg_ctr,
4808 min, 4823 min,
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
4857 return AssertionNode::AtNonBoundary(on_success); 4872 return AssertionNode::AtNonBoundary(on_success);
4858 case END_OF_INPUT: 4873 case END_OF_INPUT:
4859 return AssertionNode::AtEnd(on_success); 4874 return AssertionNode::AtEnd(on_success);
4860 case END_OF_LINE: { 4875 case END_OF_LINE: {
4861 // Compile $ in multiline regexps as an alternation with a positive 4876 // Compile $ in multiline regexps as an alternation with a positive
4862 // lookahead in one side and an end-of-input on the other side. 4877 // lookahead in one side and an end-of-input on the other side.
4863 // We need two registers for the lookahead. 4878 // We need two registers for the lookahead.
4864 int stack_pointer_register = compiler->AllocateRegister(); 4879 int stack_pointer_register = compiler->AllocateRegister();
4865 int position_register = compiler->AllocateRegister(); 4880 int position_register = compiler->AllocateRegister();
4866 // The ChoiceNode to distinguish between a newline and end-of-input. 4881 // The ChoiceNode to distinguish between a newline and end-of-input.
4867 ChoiceNode* result = new ChoiceNode(2); 4882 ChoiceNode* result = new ChoiceNode(2, compiler->zone());
4868 // Create a newline atom. 4883 // Create a newline atom.
4869 ZoneList<CharacterRange>* newline_ranges = 4884 ZoneList<CharacterRange>* newline_ranges =
4870 new ZoneList<CharacterRange>(3); 4885 new ZoneList<CharacterRange>(3);
4871 CharacterRange::AddClassEscape('n', newline_ranges); 4886 CharacterRange::AddClassEscape('n', newline_ranges);
4872 RegExpCharacterClass* newline_atom = new RegExpCharacterClass('n'); 4887 RegExpCharacterClass* newline_atom = new RegExpCharacterClass('n');
4873 TextNode* newline_matcher = new TextNode( 4888 TextNode* newline_matcher = new TextNode(
4874 newline_atom, 4889 newline_atom,
4875 ActionNode::PositiveSubmatchSuccess(stack_pointer_register, 4890 ActionNode::PositiveSubmatchSuccess(stack_pointer_register,
4876 position_register, 4891 position_register,
4877 0, // No captures inside. 4892 0, // No captures inside.
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
4944 // the second alternative is tried, which is exactly the desired result 4959 // the second alternative is tried, which is exactly the desired result
4945 // for a negative lookahead. The NegativeLookaheadChoiceNode is a special 4960 // for a negative lookahead. The NegativeLookaheadChoiceNode is a special
4946 // ChoiceNode that knows to ignore the first exit when calculating quick 4961 // ChoiceNode that knows to ignore the first exit when calculating quick
4947 // checks. 4962 // checks.
4948 GuardedAlternative body_alt( 4963 GuardedAlternative body_alt(
4949 body()->ToNode( 4964 body()->ToNode(
4950 compiler, 4965 compiler,
4951 success = new NegativeSubmatchSuccess(stack_pointer_register, 4966 success = new NegativeSubmatchSuccess(stack_pointer_register,
4952 position_register, 4967 position_register,
4953 register_count, 4968 register_count,
4954 register_start))); 4969 register_start,
4970 compiler->zone())));
4955 ChoiceNode* choice_node = 4971 ChoiceNode* choice_node =
4956 new NegativeLookaheadChoiceNode(body_alt, 4972 new NegativeLookaheadChoiceNode(body_alt,
4957 GuardedAlternative(on_success)); 4973 GuardedAlternative(on_success),
4974 compiler->zone());
4958 return ActionNode::BeginSubmatch(stack_pointer_register, 4975 return ActionNode::BeginSubmatch(stack_pointer_register,
4959 position_register, 4976 position_register,
4960 choice_node); 4977 choice_node);
4961 } 4978 }
4962 } 4979 }
4963 4980
4964 4981
4965 RegExpNode* RegExpCapture::ToNode(RegExpCompiler* compiler, 4982 RegExpNode* RegExpCapture::ToNode(RegExpCompiler* compiler,
4966 RegExpNode* on_success) { 4983 RegExpNode* on_success) {
4967 return ToNode(body(), index(), compiler, on_success); 4984 return ToNode(body(), index(), compiler, on_success);
(...skipping 852 matching lines...) Expand 10 before | Expand all | Expand 10 after
5820 } 5837 }
5821 5838
5822 5839
5823 RegExpEngine::CompilationResult RegExpEngine::Compile( 5840 RegExpEngine::CompilationResult RegExpEngine::Compile(
5824 RegExpCompileData* data, 5841 RegExpCompileData* data,
5825 bool ignore_case, 5842 bool ignore_case,
5826 bool is_global, 5843 bool is_global,
5827 bool is_multiline, 5844 bool is_multiline,
5828 Handle<String> pattern, 5845 Handle<String> pattern,
5829 Handle<String> sample_subject, 5846 Handle<String> sample_subject,
5830 bool is_ascii) { 5847 bool is_ascii,
5848 Zone* zone) {
5831 if ((data->capture_count + 1) * 2 - 1 > RegExpMacroAssembler::kMaxRegister) { 5849 if ((data->capture_count + 1) * 2 - 1 > RegExpMacroAssembler::kMaxRegister) {
5832 return IrregexpRegExpTooBig(); 5850 return IrregexpRegExpTooBig();
5833 } 5851 }
5834 RegExpCompiler compiler(data->capture_count, ignore_case, is_ascii); 5852 RegExpCompiler compiler(data->capture_count, ignore_case, is_ascii, zone);
5835 5853
5836 // Sample some characters from the middle of the string. 5854 // Sample some characters from the middle of the string.
5837 static const int kSampleSize = 128; 5855 static const int kSampleSize = 128;
5838 5856
5839 FlattenString(sample_subject); 5857 FlattenString(sample_subject);
5840 int chars_sampled = 0; 5858 int chars_sampled = 0;
5841 int half_way = (sample_subject->length() - kSampleSize) / 2; 5859 int half_way = (sample_subject->length() - kSampleSize) / 2;
5842 for (int i = Max(0, half_way); 5860 for (int i = Max(0, half_way);
5843 i < sample_subject->length() && chars_sampled < kSampleSize; 5861 i < sample_subject->length() && chars_sampled < kSampleSize;
5844 i++, chars_sampled++) { 5862 i++, chars_sampled++) {
(...skipping 17 matching lines...) Expand all
5862 RegExpTree::kInfinity, 5880 RegExpTree::kInfinity,
5863 false, 5881 false,
5864 new RegExpCharacterClass('*'), 5882 new RegExpCharacterClass('*'),
5865 &compiler, 5883 &compiler,
5866 captured_body, 5884 captured_body,
5867 data->contains_anchor); 5885 data->contains_anchor);
5868 5886
5869 if (data->contains_anchor) { 5887 if (data->contains_anchor) {
5870 // Unroll loop once, to take care of the case that might start 5888 // Unroll loop once, to take care of the case that might start
5871 // at the start of input. 5889 // at the start of input.
5872 ChoiceNode* first_step_node = new ChoiceNode(2); 5890 ChoiceNode* first_step_node = new ChoiceNode(2, zone);
5873 first_step_node->AddAlternative(GuardedAlternative(captured_body)); 5891 first_step_node->AddAlternative(GuardedAlternative(captured_body));
5874 first_step_node->AddAlternative(GuardedAlternative( 5892 first_step_node->AddAlternative(GuardedAlternative(
5875 new TextNode(new RegExpCharacterClass('*'), loop_node))); 5893 new TextNode(new RegExpCharacterClass('*'), loop_node)));
5876 node = first_step_node; 5894 node = first_step_node;
5877 } else { 5895 } else {
5878 node = loop_node; 5896 node = loop_node;
5879 } 5897 }
5880 } 5898 }
5881 if (is_ascii) { 5899 if (is_ascii) {
5882 node = node->FilterASCII(RegExpCompiler::kMaxRecursion); 5900 node = node->FilterASCII(RegExpCompiler::kMaxRecursion);
5883 // Do it again to propagate the new nodes to places where they were not 5901 // Do it again to propagate the new nodes to places where they were not
5884 // put because they had not been calculated yet. 5902 // put because they had not been calculated yet.
5885 if (node != NULL) node = node->FilterASCII(RegExpCompiler::kMaxRecursion); 5903 if (node != NULL) node = node->FilterASCII(RegExpCompiler::kMaxRecursion);
5886 } 5904 }
5887 5905
5888 if (node == NULL) node = new EndNode(EndNode::BACKTRACK); 5906 if (node == NULL) node = new EndNode(EndNode::BACKTRACK, zone);
5889 data->node = node; 5907 data->node = node;
5890 Analysis analysis(ignore_case, is_ascii); 5908 Analysis analysis(ignore_case, is_ascii);
5891 analysis.EnsureAnalyzed(node); 5909 analysis.EnsureAnalyzed(node);
5892 if (analysis.has_failed()) { 5910 if (analysis.has_failed()) {
5893 const char* error_message = analysis.error_message(); 5911 const char* error_message = analysis.error_message();
5894 return CompilationResult(error_message); 5912 return CompilationResult(error_message);
5895 } 5913 }
5896 5914
5897 // Create the correct assembler for the architecture. 5915 // Create the correct assembler for the architecture.
5898 #ifndef V8_INTERPRETED_REGEXP 5916 #ifndef V8_INTERPRETED_REGEXP
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
5935 } 5953 }
5936 5954
5937 return compiler.Assemble(&macro_assembler, 5955 return compiler.Assemble(&macro_assembler,
5938 node, 5956 node,
5939 data->capture_count, 5957 data->capture_count,
5940 pattern); 5958 pattern);
5941 } 5959 }
5942 5960
5943 5961
5944 }} // namespace v8::internal 5962 }} // namespace v8::internal
OLDNEW
« no previous file with comments | « src/jsregexp.h ('k') | src/list.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698