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

Side by Side Diff: src/regexp/jsregexp.cc

Issue 1528333002: [regexp] clear QuickCheckDetails for backward reads. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: fix assertions Created 5 years 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/regexp/jsregexp.h ('k') | test/mjsunit/regress/regress-crbug-570241.js » ('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 // 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/regexp/jsregexp.h" 5 #include "src/regexp/jsregexp.h"
6 6
7 #include "src/ast/ast.h" 7 #include "src/ast/ast.h"
8 #include "src/base/platform/platform.h" 8 #include "src/base/platform/platform.h"
9 #include "src/compilation-cache.h" 9 #include "src/compilation-cache.h"
10 #include "src/compiler.h" 10 #include "src/compiler.h"
(...skipping 2309 matching lines...) Expand 10 before | Expand all | Expand 10 after
2320 int answer = Length(); 2320 int answer = Length();
2321 if (answer >= still_to_find) return answer; 2321 if (answer >= still_to_find) return answer;
2322 if (budget <= 0) return answer; 2322 if (budget <= 0) return answer;
2323 // We are not at start after this node so we set the last argument to 'true'. 2323 // We are not at start after this node so we set the last argument to 'true'.
2324 return answer + on_success()->EatsAtLeast(still_to_find - answer, 2324 return answer + on_success()->EatsAtLeast(still_to_find - answer,
2325 budget - 1, 2325 budget - 1,
2326 true); 2326 true);
2327 } 2327 }
2328 2328
2329 2329
2330 int NegativeLookaheadChoiceNode::EatsAtLeast(int still_to_find, 2330 int NegativeLookaroundChoiceNode::EatsAtLeast(int still_to_find, int budget,
2331 int budget, 2331 bool not_at_start) {
2332 bool not_at_start) {
2333 if (budget <= 0) return 0; 2332 if (budget <= 0) return 0;
2334 // Alternative 0 is the negative lookahead, alternative 1 is what comes 2333 // Alternative 0 is the negative lookahead, alternative 1 is what comes
2335 // afterwards. 2334 // afterwards.
2336 RegExpNode* node = alternatives_->at(1).node(); 2335 RegExpNode* node = alternatives_->at(1).node();
2337 return node->EatsAtLeast(still_to_find, budget - 1, not_at_start); 2336 return node->EatsAtLeast(still_to_find, budget - 1, not_at_start);
2338 } 2337 }
2339 2338
2340 2339
2341 void NegativeLookaheadChoiceNode::GetQuickCheckDetails( 2340 void NegativeLookaroundChoiceNode::GetQuickCheckDetails(
2342 QuickCheckDetails* details, 2341 QuickCheckDetails* details, RegExpCompiler* compiler, int filled_in,
2343 RegExpCompiler* compiler,
2344 int filled_in,
2345 bool not_at_start) { 2342 bool not_at_start) {
2346 // Alternative 0 is the negative lookahead, alternative 1 is what comes 2343 // Alternative 0 is the negative lookahead, alternative 1 is what comes
2347 // afterwards. 2344 // afterwards.
2348 RegExpNode* node = alternatives_->at(1).node(); 2345 RegExpNode* node = alternatives_->at(1).node();
2349 return node->GetQuickCheckDetails(details, compiler, filled_in, not_at_start); 2346 return node->GetQuickCheckDetails(details, compiler, filled_in, not_at_start);
2350 } 2347 }
2351 2348
2352 2349
2353 int ChoiceNode::EatsAtLeastHelper(int still_to_find, 2350 int ChoiceNode::EatsAtLeastHelper(int still_to_find,
2354 int budget, 2351 int budget,
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
2504 // 2501 //
2505 // We iterate along the text object, building up for each character a 2502 // We iterate along the text object, building up for each character a
2506 // mask and value that can be used to test for a quick failure to match. 2503 // mask and value that can be used to test for a quick failure to match.
2507 // The masks and values for the positions will be combined into a single 2504 // The masks and values for the positions will be combined into a single
2508 // machine word for the current character width in order to be used in 2505 // machine word for the current character width in order to be used in
2509 // generating a quick check. 2506 // generating a quick check.
2510 void TextNode::GetQuickCheckDetails(QuickCheckDetails* details, 2507 void TextNode::GetQuickCheckDetails(QuickCheckDetails* details,
2511 RegExpCompiler* compiler, 2508 RegExpCompiler* compiler,
2512 int characters_filled_in, 2509 int characters_filled_in,
2513 bool not_at_start) { 2510 bool not_at_start) {
2511 // Do not collect any quick check details if the text node reads backward,
2512 // since it reads in the opposite direction than we use for quick checks.
2513 if (read_backward()) return;
2514 Isolate* isolate = compiler->macro_assembler()->isolate(); 2514 Isolate* isolate = compiler->macro_assembler()->isolate();
2515 DCHECK(characters_filled_in < details->characters()); 2515 DCHECK(characters_filled_in < details->characters());
2516 int characters = details->characters(); 2516 int characters = details->characters();
2517 int char_mask; 2517 int char_mask;
2518 if (compiler->one_byte()) { 2518 if (compiler->one_byte()) {
2519 char_mask = String::kMaxOneByteCharCode; 2519 char_mask = String::kMaxOneByteCharCode;
2520 } else { 2520 } else {
2521 char_mask = String::kMaxUtf16CodeUnit; 2521 char_mask = String::kMaxUtf16CodeUnit;
2522 } 2522 }
2523 for (int k = 0; k < elements()->length(); k++) { 2523 for (int k = 0; k < elements()->length(); k++) {
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
2665 for (int i = 0; i < characters_; i++) { 2665 for (int i = 0; i < characters_; i++) {
2666 positions_[i].mask = 0; 2666 positions_[i].mask = 0;
2667 positions_[i].value = 0; 2667 positions_[i].value = 0;
2668 positions_[i].determines_perfectly = false; 2668 positions_[i].determines_perfectly = false;
2669 } 2669 }
2670 characters_ = 0; 2670 characters_ = 0;
2671 } 2671 }
2672 2672
2673 2673
2674 void QuickCheckDetails::Advance(int by, bool one_byte) { 2674 void QuickCheckDetails::Advance(int by, bool one_byte) {
2675 if (by >= characters_) { 2675 if (by >= characters_ || by < 0) {
2676 DCHECK_IMPLIES(by < 0, characters_ == 0);
2676 Clear(); 2677 Clear();
2677 return; 2678 return;
2678 } 2679 }
2680 DCHECK_LE(characters_ - by, 4);
2681 DCHECK_LE(characters_, 4);
2679 for (int i = 0; i < characters_ - by; i++) { 2682 for (int i = 0; i < characters_ - by; i++) {
2680 positions_[i] = positions_[by + i]; 2683 positions_[i] = positions_[by + i];
2681 } 2684 }
2682 for (int i = characters_ - by; i < characters_; i++) { 2685 for (int i = characters_ - by; i < characters_; i++) {
2683 positions_[i].mask = 0; 2686 positions_[i].mask = 0;
2684 positions_[i].value = 0; 2687 positions_[i].value = 0;
2685 positions_[i].determines_perfectly = false; 2688 positions_[i].determines_perfectly = false;
2686 } 2689 }
2687 characters_ -= by; 2690 characters_ -= by;
2688 // We could change mask_ and value_ here but we would never advance unless 2691 // We could change mask_ and value_ here but we would never advance unless
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after
2884 if (replacement != NULL) { 2887 if (replacement != NULL) {
2885 alternatives_->at(i).set_node(replacement); 2888 alternatives_->at(i).set_node(replacement);
2886 new_alternatives->Add(alternatives_->at(i), zone()); 2889 new_alternatives->Add(alternatives_->at(i), zone());
2887 } 2890 }
2888 } 2891 }
2889 alternatives_ = new_alternatives; 2892 alternatives_ = new_alternatives;
2890 return this; 2893 return this;
2891 } 2894 }
2892 2895
2893 2896
2894 RegExpNode* NegativeLookaheadChoiceNode::FilterOneByte(int depth, 2897 RegExpNode* NegativeLookaroundChoiceNode::FilterOneByte(int depth,
2895 bool ignore_case) { 2898 bool ignore_case) {
2896 if (info()->replacement_calculated) return replacement(); 2899 if (info()->replacement_calculated) return replacement();
2897 if (depth < 0) return this; 2900 if (depth < 0) return this;
2898 if (info()->visited) return this; 2901 if (info()->visited) return this;
2899 VisitMarker marker(info()); 2902 VisitMarker marker(info());
2900 // Alternative 0 is the negative lookahead, alternative 1 is what comes 2903 // Alternative 0 is the negative lookahead, alternative 1 is what comes
2901 // afterwards. 2904 // afterwards.
2902 RegExpNode* node = alternatives_->at(1).node(); 2905 RegExpNode* node = alternatives_->at(1).node();
2903 RegExpNode* replacement = node->FilterOneByte(depth - 1, ignore_case); 2906 RegExpNode* replacement = node->FilterOneByte(depth - 1, ignore_case);
2904 if (replacement == NULL) return set_replacement(NULL); 2907 if (replacement == NULL) return set_replacement(NULL);
2905 alternatives_->at(1).set_node(replacement); 2908 alternatives_->at(1).set_node(replacement);
(...skipping 2460 matching lines...) Expand 10 before | Expand all | Expand 10 after
5366 // the second alternative is tried, which is exactly the desired result 5369 // the second alternative is tried, which is exactly the desired result
5367 // for a negative lookahead. The NegativeLookaheadChoiceNode is a special 5370 // for a negative lookahead. The NegativeLookaheadChoiceNode is a special
5368 // ChoiceNode that knows to ignore the first exit when calculating quick 5371 // ChoiceNode that knows to ignore the first exit when calculating quick
5369 // checks. 5372 // checks.
5370 Zone* zone = compiler->zone(); 5373 Zone* zone = compiler->zone();
5371 5374
5372 GuardedAlternative body_alt( 5375 GuardedAlternative body_alt(
5373 body()->ToNode(compiler, new (zone) NegativeSubmatchSuccess( 5376 body()->ToNode(compiler, new (zone) NegativeSubmatchSuccess(
5374 stack_pointer_register, position_register, 5377 stack_pointer_register, position_register,
5375 register_count, register_start, zone))); 5378 register_count, register_start, zone)));
5376 ChoiceNode* choice_node = 5379 ChoiceNode* choice_node = new (zone) NegativeLookaroundChoiceNode(
5377 new(zone) NegativeLookaheadChoiceNode(body_alt, 5380 body_alt, GuardedAlternative(on_success), zone);
5378 GuardedAlternative(on_success),
5379 zone);
5380 result = ActionNode::BeginSubmatch(stack_pointer_register, 5381 result = ActionNode::BeginSubmatch(stack_pointer_register,
5381 position_register, choice_node); 5382 position_register, choice_node);
5382 } 5383 }
5383 compiler->set_read_backward(was_reading_backward); 5384 compiler->set_read_backward(was_reading_backward);
5384 return result; 5385 return result;
5385 } 5386 }
5386 5387
5387 5388
5388 RegExpNode* RegExpCapture::ToNode(RegExpCompiler* compiler, 5389 RegExpNode* RegExpCapture::ToNode(RegExpCompiler* compiler,
5389 RegExpNode* on_success) { 5390 RegExpNode* on_success) {
(...skipping 1109 matching lines...) Expand 10 before | Expand all | Expand 10 after
6499 6500
6500 6501
6501 void RegExpResultsCache::Clear(FixedArray* cache) { 6502 void RegExpResultsCache::Clear(FixedArray* cache) {
6502 for (int i = 0; i < kRegExpResultsCacheSize; i++) { 6503 for (int i = 0; i < kRegExpResultsCacheSize; i++) {
6503 cache->set(i, Smi::FromInt(0)); 6504 cache->set(i, Smi::FromInt(0));
6504 } 6505 }
6505 } 6506 }
6506 6507
6507 } // namespace internal 6508 } // namespace internal
6508 } // namespace v8 6509 } // namespace v8
OLDNEW
« no previous file with comments | « src/regexp/jsregexp.h ('k') | test/mjsunit/regress/regress-crbug-570241.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698