| OLD | NEW |
| 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 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 509 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 520 // it fails it will push back the characters read so the same characters | 520 // it fails it will push back the characters read so the same characters |
| 521 // can be reparsed. | 521 // can be reparsed. |
| 522 bool ParseBackReferenceIndex(int* index_out); | 522 bool ParseBackReferenceIndex(int* index_out); |
| 523 | 523 |
| 524 CharacterRange ParseClassAtom(uc16* char_class); | 524 CharacterRange ParseClassAtom(uc16* char_class); |
| 525 RegExpTree* ReportError(Vector<const char> message); | 525 RegExpTree* ReportError(Vector<const char> message); |
| 526 void Advance(); | 526 void Advance(); |
| 527 void Advance(int dist); | 527 void Advance(int dist); |
| 528 void Reset(int pos); | 528 void Reset(int pos); |
| 529 | 529 |
| 530 bool HasCharacterEscapes(); | 530 // Reports whether the pattern might be used as a literal search string. |
| 531 // Only use if the result of the parse is a single atom node. |
| 532 bool simple(); |
| 531 | 533 |
| 532 int captures_started() { return captures_ == NULL ? 0 : captures_->length(); } | 534 int captures_started() { return captures_ == NULL ? 0 : captures_->length(); } |
| 533 int position() { return next_pos_ - 1; } | 535 int position() { return next_pos_ - 1; } |
| 534 bool failed() { return failed_; } | 536 bool failed() { return failed_; } |
| 535 | 537 |
| 536 static const uc32 kEndMarker = (1 << 21); | 538 static const uc32 kEndMarker = (1 << 21); |
| 537 private: | 539 private: |
| 538 uc32 current() { return current_; } | 540 uc32 current() { return current_; } |
| 539 bool has_more() { return has_more_; } | 541 bool has_more() { return has_more_; } |
| 540 bool has_next() { return next_pos_ < in()->length(); } | 542 bool has_next() { return next_pos_ < in()->length(); } |
| 541 uc32 Next(); | 543 uc32 Next(); |
| 542 FlatStringReader* in() { return in_; } | 544 FlatStringReader* in() { return in_; } |
| 543 void ScanForCaptures(); | 545 void ScanForCaptures(); |
| 544 bool CaptureAvailable(int index); | 546 bool CaptureAvailable(int index); |
| 545 uc32 current_; | 547 uc32 current_; |
| 546 bool has_more_; | 548 bool has_more_; |
| 547 bool multiline_; | 549 bool multiline_; |
| 548 int next_pos_; | 550 int next_pos_; |
| 549 FlatStringReader* in_; | 551 FlatStringReader* in_; |
| 550 Handle<String>* error_; | 552 Handle<String>* error_; |
| 551 bool has_character_escapes_; | 553 bool simple_; |
| 552 ZoneList<RegExpCapture*>* captures_; | 554 ZoneList<RegExpCapture*>* captures_; |
| 553 bool is_scanned_for_captures_; | 555 bool is_scanned_for_captures_; |
| 554 // The capture count is only valid after we have scanned for captures. | 556 // The capture count is only valid after we have scanned for captures. |
| 555 int capture_count_; | 557 int capture_count_; |
| 556 bool failed_; | 558 bool failed_; |
| 557 }; | 559 }; |
| 558 | 560 |
| 559 | 561 |
| 560 // A temporary scope stores information during parsing, just like | 562 // A temporary scope stores information during parsing, just like |
| 561 // a plain scope. However, temporary scopes are not kept around | 563 // a plain scope. However, temporary scopes are not kept around |
| (...skipping 2932 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3494 | 3496 |
| 3495 RegExpParser::RegExpParser(FlatStringReader* in, | 3497 RegExpParser::RegExpParser(FlatStringReader* in, |
| 3496 Handle<String>* error, | 3498 Handle<String>* error, |
| 3497 bool multiline) | 3499 bool multiline) |
| 3498 : current_(kEndMarker), | 3500 : current_(kEndMarker), |
| 3499 has_more_(true), | 3501 has_more_(true), |
| 3500 multiline_(multiline), | 3502 multiline_(multiline), |
| 3501 next_pos_(0), | 3503 next_pos_(0), |
| 3502 in_(in), | 3504 in_(in), |
| 3503 error_(error), | 3505 error_(error), |
| 3504 has_character_escapes_(false), | 3506 simple_(true), |
| 3505 captures_(NULL), | 3507 captures_(NULL), |
| 3506 is_scanned_for_captures_(false), | 3508 is_scanned_for_captures_(false), |
| 3507 capture_count_(0), | 3509 capture_count_(0), |
| 3508 failed_(false) { | 3510 failed_(false) { |
| 3509 Advance(1); | 3511 Advance(1); |
| 3510 } | 3512 } |
| 3511 | 3513 |
| 3512 | 3514 |
| 3513 uc32 RegExpParser::Next() { | 3515 uc32 RegExpParser::Next() { |
| 3514 if (has_next()) { | 3516 if (has_next()) { |
| (...skipping 27 matching lines...) Expand all Loading... |
| 3542 Advance(); | 3544 Advance(); |
| 3543 } | 3545 } |
| 3544 | 3546 |
| 3545 | 3547 |
| 3546 void RegExpParser::Advance(int dist) { | 3548 void RegExpParser::Advance(int dist) { |
| 3547 for (int i = 0; i < dist; i++) | 3549 for (int i = 0; i < dist; i++) |
| 3548 Advance(); | 3550 Advance(); |
| 3549 } | 3551 } |
| 3550 | 3552 |
| 3551 | 3553 |
| 3552 // Reports whether the parsed string atoms contain any characters that were | 3554 bool RegExpParser::simple() { |
| 3553 // escaped in the original pattern. If not, all atoms are proper substrings | 3555 return simple_; |
| 3554 // of the original pattern. | |
| 3555 bool RegExpParser::HasCharacterEscapes() { | |
| 3556 return has_character_escapes_; | |
| 3557 } | 3556 } |
| 3558 | 3557 |
| 3559 RegExpTree* RegExpParser::ReportError(Vector<const char> message) { | 3558 RegExpTree* RegExpParser::ReportError(Vector<const char> message) { |
| 3560 failed_ = true; | 3559 failed_ = true; |
| 3561 *error_ = Factory::NewStringFromAscii(message, NOT_TENURED); | 3560 *error_ = Factory::NewStringFromAscii(message, NOT_TENURED); |
| 3562 // Zip to the end to make sure the no more input is read. | 3561 // Zip to the end to make sure the no more input is read. |
| 3563 current_ = kEndMarker; | 3562 current_ = kEndMarker; |
| 3564 next_pos_ = in()->length(); | 3563 next_pos_ = in()->length(); |
| 3565 return NULL; | 3564 return NULL; |
| 3566 } | 3565 } |
| (...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3761 builder.AddCharacter('u'); | 3760 builder.AddCharacter('u'); |
| 3762 } | 3761 } |
| 3763 break; | 3762 break; |
| 3764 } | 3763 } |
| 3765 default: | 3764 default: |
| 3766 // Identity escape. | 3765 // Identity escape. |
| 3767 builder.AddCharacter(Next()); | 3766 builder.AddCharacter(Next()); |
| 3768 Advance(2); | 3767 Advance(2); |
| 3769 break; | 3768 break; |
| 3770 } | 3769 } |
| 3771 has_character_escapes_ = true; | 3770 simple_ = false; |
| 3772 break; | 3771 break; |
| 3773 case '{': { | 3772 case '{': { |
| 3774 int dummy; | 3773 int dummy; |
| 3775 if (ParseIntervalQuantifier(&dummy, &dummy)) { | 3774 if (ParseIntervalQuantifier(&dummy, &dummy)) { |
| 3776 ReportError(CStrVector("Nothing to repeat") CHECK_FAILED); | 3775 ReportError(CStrVector("Nothing to repeat") CHECK_FAILED); |
| 3777 } | 3776 } |
| 3778 // fallthrough | 3777 // fallthrough |
| 3779 } | 3778 } |
| 3780 default: | 3779 default: |
| 3781 builder.AddCharacter(current()); | 3780 builder.AddCharacter(current()); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3814 continue; | 3813 continue; |
| 3815 } | 3814 } |
| 3816 default: | 3815 default: |
| 3817 continue; | 3816 continue; |
| 3818 } | 3817 } |
| 3819 bool is_greedy = true; | 3818 bool is_greedy = true; |
| 3820 if (current() == '?') { | 3819 if (current() == '?') { |
| 3821 is_greedy = false; | 3820 is_greedy = false; |
| 3822 Advance(); | 3821 Advance(); |
| 3823 } | 3822 } |
| 3823 simple_ = false; // Adding quantifier might *remove* look-ahead. |
| 3824 builder.AddQuantifierToAtom(min, max, is_greedy); | 3824 builder.AddQuantifierToAtom(min, max, is_greedy); |
| 3825 } | 3825 } |
| 3826 } | 3826 } |
| 3827 | 3827 |
| 3828 class SourceCharacter { | 3828 class SourceCharacter { |
| 3829 public: | 3829 public: |
| 3830 static bool Is(uc32 c) { | 3830 static bool Is(uc32 c) { |
| 3831 switch (c) { | 3831 switch (c) { |
| 3832 // case ']': case '}': | 3832 // case ']': case '}': |
| 3833 // In spidermonkey and jsc these are treated as source characters | 3833 // In spidermonkey and jsc these are treated as source characters |
| (...skipping 460 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4294 // The list owns the backing store so we need to clone the vector. | 4294 // The list owns the backing store so we need to clone the vector. |
| 4295 // That way, the result will be exactly the right size rather than | 4295 // That way, the result will be exactly the right size rather than |
| 4296 // the expected 50% too large. | 4296 // the expected 50% too large. |
| 4297 Vector<unsigned> store = parser.recorder()->store()->ToVector().Clone(); | 4297 Vector<unsigned> store = parser.recorder()->store()->ToVector().Clone(); |
| 4298 return new ScriptDataImpl(store); | 4298 return new ScriptDataImpl(store); |
| 4299 } | 4299 } |
| 4300 | 4300 |
| 4301 | 4301 |
| 4302 bool ParseRegExp(FlatStringReader* input, | 4302 bool ParseRegExp(FlatStringReader* input, |
| 4303 bool multiline, | 4303 bool multiline, |
| 4304 RegExpParseResult* result) { | 4304 RegExpCompileData* result) { |
| 4305 ASSERT(result != NULL); | 4305 ASSERT(result != NULL); |
| 4306 // Make sure we have a stack guard. | 4306 // Make sure we have a stack guard. |
| 4307 StackGuard guard; | 4307 StackGuard guard; |
| 4308 RegExpParser parser(input, &result->error, multiline); | 4308 RegExpParser parser(input, &result->error, multiline); |
| 4309 result->tree = parser.ParsePattern(); | 4309 RegExpTree* tree = parser.ParsePattern(); |
| 4310 if (parser.failed()) { | 4310 if (parser.failed()) { |
| 4311 ASSERT(result->tree == NULL); | 4311 ASSERT(tree == NULL); |
| 4312 ASSERT(!result->error.is_null()); | 4312 ASSERT(!result->error.is_null()); |
| 4313 } else { | 4313 } else { |
| 4314 ASSERT(result->tree != NULL); | 4314 ASSERT(tree != NULL); |
| 4315 ASSERT(result->error.is_null()); | 4315 ASSERT(result->error.is_null()); |
| 4316 result->has_character_escapes = parser.HasCharacterEscapes(); | 4316 result->tree = tree; |
| 4317 result->capture_count = parser.captures_started(); | 4317 int capture_count = parser.captures_started(); |
| 4318 result->simple = tree->IsAtom() && parser.simple() && capture_count == 0; |
| 4319 result->capture_count = capture_count; |
| 4318 } | 4320 } |
| 4319 return !parser.failed(); | 4321 return !parser.failed(); |
| 4320 } | 4322 } |
| 4321 | 4323 |
| 4322 | 4324 |
| 4323 FunctionLiteral* MakeAST(bool compile_in_global_context, | 4325 FunctionLiteral* MakeAST(bool compile_in_global_context, |
| 4324 Handle<Script> script, | 4326 Handle<Script> script, |
| 4325 v8::Extension* extension, | 4327 v8::Extension* extension, |
| 4326 ScriptDataImpl* pre_data) { | 4328 ScriptDataImpl* pre_data) { |
| 4327 bool allow_natives_syntax = | 4329 bool allow_natives_syntax = |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4365 start_position, | 4367 start_position, |
| 4366 is_expression); | 4368 is_expression); |
| 4367 return result; | 4369 return result; |
| 4368 } | 4370 } |
| 4369 | 4371 |
| 4370 | 4372 |
| 4371 #undef NEW | 4373 #undef NEW |
| 4372 | 4374 |
| 4373 | 4375 |
| 4374 } } // namespace v8::internal | 4376 } } // namespace v8::internal |
| OLD | NEW |