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

Side by Side Diff: src/jsregexp.cc

Issue 12746003: Merged r13788, r13658 into 3.16 branch. (Closed) Base URL: https://v8.googlecode.com/svn/branches/3.16
Patch Set: Created 7 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/messages.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 // 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 2280 matching lines...) Expand 10 before | Expand all | Expand 10 after
2291 2291
2292 // If we get here code has been generated for this node too many times or 2292 // If we get here code has been generated for this node too many times or
2293 // recursion is too deep. Time to switch to a generic version. The code for 2293 // recursion is too deep. Time to switch to a generic version. The code for
2294 // generic versions above can handle deep recursion properly. 2294 // generic versions above can handle deep recursion properly.
2295 trace->Flush(compiler, this); 2295 trace->Flush(compiler, this);
2296 return DONE; 2296 return DONE;
2297 } 2297 }
2298 2298
2299 2299
2300 int ActionNode::EatsAtLeast(int still_to_find, 2300 int ActionNode::EatsAtLeast(int still_to_find,
2301 int recursion_depth, 2301 int budget,
2302 bool not_at_start) { 2302 bool not_at_start) {
2303 if (recursion_depth > RegExpCompiler::kMaxRecursion) return 0; 2303 if (budget <= 0) return 0;
2304 if (type_ == POSITIVE_SUBMATCH_SUCCESS) return 0; // Rewinds input! 2304 if (type_ == POSITIVE_SUBMATCH_SUCCESS) return 0; // Rewinds input!
2305 return on_success()->EatsAtLeast(still_to_find, 2305 return on_success()->EatsAtLeast(still_to_find,
2306 recursion_depth + 1, 2306 budget - 1,
2307 not_at_start); 2307 not_at_start);
2308 } 2308 }
2309 2309
2310 2310
2311 void ActionNode::FillInBMInfo(int offset, 2311 void ActionNode::FillInBMInfo(int offset,
2312 int recursion_depth,
2313 int budget, 2312 int budget,
2314 BoyerMooreLookahead* bm, 2313 BoyerMooreLookahead* bm,
2315 bool not_at_start) { 2314 bool not_at_start) {
2316 if (type_ == BEGIN_SUBMATCH) { 2315 if (type_ == BEGIN_SUBMATCH) {
2317 bm->SetRest(offset); 2316 bm->SetRest(offset);
2318 } else if (type_ != POSITIVE_SUBMATCH_SUCCESS) { 2317 } else if (type_ != POSITIVE_SUBMATCH_SUCCESS) {
2319 on_success()->FillInBMInfo( 2318 on_success()->FillInBMInfo(offset, budget - 1, bm, not_at_start);
2320 offset, recursion_depth + 1, budget - 1, bm, not_at_start);
2321 } 2319 }
2322 SaveBMInfo(bm, not_at_start, offset); 2320 SaveBMInfo(bm, not_at_start, offset);
2323 } 2321 }
2324 2322
2325 2323
2326 int AssertionNode::EatsAtLeast(int still_to_find, 2324 int AssertionNode::EatsAtLeast(int still_to_find,
2327 int recursion_depth, 2325 int budget,
2328 bool not_at_start) { 2326 bool not_at_start) {
2329 if (recursion_depth > RegExpCompiler::kMaxRecursion) return 0; 2327 if (budget <= 0) return 0;
2330 // If we know we are not at the start and we are asked "how many characters 2328 // If we know we are not at the start and we are asked "how many characters
2331 // will you match if you succeed?" then we can answer anything since false 2329 // will you match if you succeed?" then we can answer anything since false
2332 // implies false. So lets just return the max answer (still_to_find) since 2330 // implies false. So lets just return the max answer (still_to_find) since
2333 // that won't prevent us from preloading a lot of characters for the other 2331 // that won't prevent us from preloading a lot of characters for the other
2334 // branches in the node graph. 2332 // branches in the node graph.
2335 if (type() == AT_START && not_at_start) return still_to_find; 2333 if (type() == AT_START && not_at_start) return still_to_find;
2336 return on_success()->EatsAtLeast(still_to_find, 2334 return on_success()->EatsAtLeast(still_to_find,
2337 recursion_depth + 1, 2335 budget - 1,
2338 not_at_start); 2336 not_at_start);
2339 } 2337 }
2340 2338
2341 2339
2342 void AssertionNode::FillInBMInfo(int offset, 2340 void AssertionNode::FillInBMInfo(int offset,
2343 int recursion_depth,
2344 int budget, 2341 int budget,
2345 BoyerMooreLookahead* bm, 2342 BoyerMooreLookahead* bm,
2346 bool not_at_start) { 2343 bool not_at_start) {
2347 // Match the behaviour of EatsAtLeast on this node. 2344 // Match the behaviour of EatsAtLeast on this node.
2348 if (type() == AT_START && not_at_start) return; 2345 if (type() == AT_START && not_at_start) return;
2349 on_success()->FillInBMInfo( 2346 on_success()->FillInBMInfo(offset, budget - 1, bm, not_at_start);
2350 offset, recursion_depth + 1, budget - 1, bm, not_at_start);
2351 SaveBMInfo(bm, not_at_start, offset); 2347 SaveBMInfo(bm, not_at_start, offset);
2352 } 2348 }
2353 2349
2354 2350
2355 int BackReferenceNode::EatsAtLeast(int still_to_find, 2351 int BackReferenceNode::EatsAtLeast(int still_to_find,
2356 int recursion_depth, 2352 int budget,
2357 bool not_at_start) { 2353 bool not_at_start) {
2358 if (recursion_depth > RegExpCompiler::kMaxRecursion) return 0; 2354 if (budget <= 0) return 0;
2359 return on_success()->EatsAtLeast(still_to_find, 2355 return on_success()->EatsAtLeast(still_to_find,
2360 recursion_depth + 1, 2356 budget - 1,
2361 not_at_start); 2357 not_at_start);
2362 } 2358 }
2363 2359
2364 2360
2365 int TextNode::EatsAtLeast(int still_to_find, 2361 int TextNode::EatsAtLeast(int still_to_find,
2366 int recursion_depth, 2362 int budget,
2367 bool not_at_start) { 2363 bool not_at_start) {
2368 int answer = Length(); 2364 int answer = Length();
2369 if (answer >= still_to_find) return answer; 2365 if (answer >= still_to_find) return answer;
2370 if (recursion_depth > RegExpCompiler::kMaxRecursion) return answer; 2366 if (budget <= 0) return answer;
2371 // We are not at start after this node so we set the last argument to 'true'. 2367 // We are not at start after this node so we set the last argument to 'true'.
2372 return answer + on_success()->EatsAtLeast(still_to_find - answer, 2368 return answer + on_success()->EatsAtLeast(still_to_find - answer,
2373 recursion_depth + 1, 2369 budget - 1,
2374 true); 2370 true);
2375 } 2371 }
2376 2372
2377 2373
2378 int NegativeLookaheadChoiceNode::EatsAtLeast(int still_to_find, 2374 int NegativeLookaheadChoiceNode::EatsAtLeast(int still_to_find,
2379 int recursion_depth, 2375 int budget,
2380 bool not_at_start) { 2376 bool not_at_start) {
2381 if (recursion_depth > RegExpCompiler::kMaxRecursion) return 0; 2377 if (budget <= 0) return 0;
2382 // Alternative 0 is the negative lookahead, alternative 1 is what comes 2378 // Alternative 0 is the negative lookahead, alternative 1 is what comes
2383 // afterwards. 2379 // afterwards.
2384 RegExpNode* node = alternatives_->at(1).node(); 2380 RegExpNode* node = alternatives_->at(1).node();
2385 return node->EatsAtLeast(still_to_find, recursion_depth + 1, not_at_start); 2381 return node->EatsAtLeast(still_to_find, budget - 1, not_at_start);
2386 } 2382 }
2387 2383
2388 2384
2389 void NegativeLookaheadChoiceNode::GetQuickCheckDetails( 2385 void NegativeLookaheadChoiceNode::GetQuickCheckDetails(
2390 QuickCheckDetails* details, 2386 QuickCheckDetails* details,
2391 RegExpCompiler* compiler, 2387 RegExpCompiler* compiler,
2392 int filled_in, 2388 int filled_in,
2393 bool not_at_start) { 2389 bool not_at_start) {
2394 // Alternative 0 is the negative lookahead, alternative 1 is what comes 2390 // Alternative 0 is the negative lookahead, alternative 1 is what comes
2395 // afterwards. 2391 // afterwards.
2396 RegExpNode* node = alternatives_->at(1).node(); 2392 RegExpNode* node = alternatives_->at(1).node();
2397 return node->GetQuickCheckDetails(details, compiler, filled_in, not_at_start); 2393 return node->GetQuickCheckDetails(details, compiler, filled_in, not_at_start);
2398 } 2394 }
2399 2395
2400 2396
2401 int ChoiceNode::EatsAtLeastHelper(int still_to_find, 2397 int ChoiceNode::EatsAtLeastHelper(int still_to_find,
2402 int recursion_depth, 2398 int budget,
2403 RegExpNode* ignore_this_node, 2399 RegExpNode* ignore_this_node,
2404 bool not_at_start) { 2400 bool not_at_start) {
2405 if (recursion_depth > RegExpCompiler::kMaxRecursion) return 0; 2401 if (budget <= 0) return 0;
2406 int min = 100; 2402 int min = 100;
2407 int choice_count = alternatives_->length(); 2403 int choice_count = alternatives_->length();
2404 budget = (budget - 1) / choice_count;
2408 for (int i = 0; i < choice_count; i++) { 2405 for (int i = 0; i < choice_count; i++) {
2409 RegExpNode* node = alternatives_->at(i).node(); 2406 RegExpNode* node = alternatives_->at(i).node();
2410 if (node == ignore_this_node) continue; 2407 if (node == ignore_this_node) continue;
2411 int node_eats_at_least = node->EatsAtLeast(still_to_find, 2408 int node_eats_at_least =
2412 recursion_depth + 1, 2409 node->EatsAtLeast(still_to_find, budget, not_at_start);
2413 not_at_start);
2414 if (node_eats_at_least < min) min = node_eats_at_least; 2410 if (node_eats_at_least < min) min = node_eats_at_least;
2411 if (min == 0) return 0;
2415 } 2412 }
2416 return min; 2413 return min;
2417 } 2414 }
2418 2415
2419 2416
2420 int LoopChoiceNode::EatsAtLeast(int still_to_find, 2417 int LoopChoiceNode::EatsAtLeast(int still_to_find,
2421 int recursion_depth, 2418 int budget,
2422 bool not_at_start) { 2419 bool not_at_start) {
2423 return EatsAtLeastHelper(still_to_find, 2420 return EatsAtLeastHelper(still_to_find,
2424 recursion_depth, 2421 budget - 1,
2425 loop_node_, 2422 loop_node_,
2426 not_at_start); 2423 not_at_start);
2427 } 2424 }
2428 2425
2429 2426
2430 int ChoiceNode::EatsAtLeast(int still_to_find, 2427 int ChoiceNode::EatsAtLeast(int still_to_find,
2431 int recursion_depth, 2428 int budget,
2432 bool not_at_start) { 2429 bool not_at_start) {
2433 return EatsAtLeastHelper(still_to_find, 2430 return EatsAtLeastHelper(still_to_find,
2434 recursion_depth, 2431 budget,
2435 NULL, 2432 NULL,
2436 not_at_start); 2433 not_at_start);
2437 } 2434 }
2438 2435
2439 2436
2440 // Takes the left-most 1-bit and smears it out, setting all bits to its right. 2437 // Takes the left-most 1-bit and smears it out, setting all bits to its right.
2441 static inline uint32_t SmearBitsRight(uint32_t v) { 2438 static inline uint32_t SmearBitsRight(uint32_t v) {
2442 v |= v >> 1; 2439 v |= v >> 1;
2443 v |= v >> 2; 2440 v |= v >> 2;
2444 v |= v >> 4; 2441 v |= v >> 4;
(...skipping 535 matching lines...) Expand 10 before | Expand all | Expand 10 after
2980 if (body_can_be_zero_length_ || info()->visited) return; 2977 if (body_can_be_zero_length_ || info()->visited) return;
2981 VisitMarker marker(info()); 2978 VisitMarker marker(info());
2982 return ChoiceNode::GetQuickCheckDetails(details, 2979 return ChoiceNode::GetQuickCheckDetails(details,
2983 compiler, 2980 compiler,
2984 characters_filled_in, 2981 characters_filled_in,
2985 not_at_start); 2982 not_at_start);
2986 } 2983 }
2987 2984
2988 2985
2989 void LoopChoiceNode::FillInBMInfo(int offset, 2986 void LoopChoiceNode::FillInBMInfo(int offset,
2990 int recursion_depth,
2991 int budget, 2987 int budget,
2992 BoyerMooreLookahead* bm, 2988 BoyerMooreLookahead* bm,
2993 bool not_at_start) { 2989 bool not_at_start) {
2994 if (body_can_be_zero_length_ || 2990 if (body_can_be_zero_length_ || budget <= 0) {
2995 recursion_depth > RegExpCompiler::kMaxRecursion ||
2996 budget <= 0) {
2997 bm->SetRest(offset); 2991 bm->SetRest(offset);
2998 SaveBMInfo(bm, not_at_start, offset); 2992 SaveBMInfo(bm, not_at_start, offset);
2999 return; 2993 return;
3000 } 2994 }
3001 ChoiceNode::FillInBMInfo( 2995 ChoiceNode::FillInBMInfo(offset, budget - 1, bm, not_at_start);
3002 offset, recursion_depth + 1, budget - 1, bm, not_at_start);
3003 SaveBMInfo(bm, not_at_start, offset); 2996 SaveBMInfo(bm, not_at_start, offset);
3004 } 2997 }
3005 2998
3006 2999
3007 void ChoiceNode::GetQuickCheckDetails(QuickCheckDetails* details, 3000 void ChoiceNode::GetQuickCheckDetails(QuickCheckDetails* details,
3008 RegExpCompiler* compiler, 3001 RegExpCompiler* compiler,
3009 int characters_filled_in, 3002 int characters_filled_in,
3010 bool not_at_start) { 3003 bool not_at_start) {
3011 not_at_start = (not_at_start || not_at_start_); 3004 not_at_start = (not_at_start || not_at_start_);
3012 int choice_count = alternatives_->length(); 3005 int choice_count = alternatives_->length();
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
3089 3082
3090 3083
3091 // Emit the code to handle \b and \B (word-boundary or non-word-boundary). 3084 // Emit the code to handle \b and \B (word-boundary or non-word-boundary).
3092 void AssertionNode::EmitBoundaryCheck(RegExpCompiler* compiler, Trace* trace) { 3085 void AssertionNode::EmitBoundaryCheck(RegExpCompiler* compiler, Trace* trace) {
3093 RegExpMacroAssembler* assembler = compiler->macro_assembler(); 3086 RegExpMacroAssembler* assembler = compiler->macro_assembler();
3094 Trace::TriBool next_is_word_character = Trace::UNKNOWN; 3087 Trace::TriBool next_is_word_character = Trace::UNKNOWN;
3095 bool not_at_start = (trace->at_start() == Trace::FALSE); 3088 bool not_at_start = (trace->at_start() == Trace::FALSE);
3096 BoyerMooreLookahead* lookahead = bm_info(not_at_start); 3089 BoyerMooreLookahead* lookahead = bm_info(not_at_start);
3097 if (lookahead == NULL) { 3090 if (lookahead == NULL) {
3098 int eats_at_least = 3091 int eats_at_least =
3099 Min(kMaxLookaheadForBoyerMoore, 3092 Min(kMaxLookaheadForBoyerMoore, EatsAtLeast(kMaxLookaheadForBoyerMoore,
3100 EatsAtLeast(kMaxLookaheadForBoyerMoore, 0, not_at_start)); 3093 kRecursionBudget,
3094 not_at_start));
3101 if (eats_at_least >= 1) { 3095 if (eats_at_least >= 1) {
3102 BoyerMooreLookahead* bm = 3096 BoyerMooreLookahead* bm =
3103 new(zone()) BoyerMooreLookahead(eats_at_least, compiler, zone()); 3097 new(zone()) BoyerMooreLookahead(eats_at_least, compiler, zone());
3104 FillInBMInfo(0, 0, kFillInBMBudget, bm, not_at_start); 3098 FillInBMInfo(0, kRecursionBudget, bm, not_at_start);
3105 if (bm->at(0)->is_non_word()) next_is_word_character = Trace::FALSE; 3099 if (bm->at(0)->is_non_word()) next_is_word_character = Trace::FALSE;
3106 if (bm->at(0)->is_word()) next_is_word_character = Trace::TRUE; 3100 if (bm->at(0)->is_word()) next_is_word_character = Trace::TRUE;
3107 } 3101 }
3108 } else { 3102 } else {
3109 if (lookahead->at(0)->is_non_word()) next_is_word_character = Trace::FALSE; 3103 if (lookahead->at(0)->is_non_word()) next_is_word_character = Trace::FALSE;
3110 if (lookahead->at(0)->is_word()) next_is_word_character = Trace::TRUE; 3104 if (lookahead->at(0)->is_word()) next_is_word_character = Trace::TRUE;
3111 } 3105 }
3112 bool at_boundary = (type_ == AssertionNode::AT_BOUNDARY); 3106 bool at_boundary = (type_ == AssertionNode::AT_BOUNDARY);
3113 if (next_is_word_character == Trace::UNKNOWN) { 3107 if (next_is_word_character == Trace::UNKNOWN) {
3114 Label before_non_word; 3108 Label before_non_word;
(...skipping 911 matching lines...) Expand 10 before | Expand all | Expand 10 after
4026 // At this point we know that we are at a non-greedy loop that will eat 4020 // At this point we know that we are at a non-greedy loop that will eat
4027 // any character one at a time. Any non-anchored regexp has such a 4021 // any character one at a time. Any non-anchored regexp has such a
4028 // loop prepended to it in order to find where it starts. We look for 4022 // loop prepended to it in order to find where it starts. We look for
4029 // a pattern of the form ...abc... where we can look 6 characters ahead 4023 // a pattern of the form ...abc... where we can look 6 characters ahead
4030 // and step forwards 3 if the character is not one of abc. Abc need 4024 // and step forwards 3 if the character is not one of abc. Abc need
4031 // not be atoms, they can be any reasonably limited character class or 4025 // not be atoms, they can be any reasonably limited character class or
4032 // small alternation. 4026 // small alternation.
4033 ASSERT(trace->is_trivial()); // This is the case on LoopChoiceNodes. 4027 ASSERT(trace->is_trivial()); // This is the case on LoopChoiceNodes.
4034 BoyerMooreLookahead* lookahead = bm_info(not_at_start); 4028 BoyerMooreLookahead* lookahead = bm_info(not_at_start);
4035 if (lookahead == NULL) { 4029 if (lookahead == NULL) {
4036 eats_at_least = 4030 eats_at_least = Min(kMaxLookaheadForBoyerMoore,
4037 Min(kMaxLookaheadForBoyerMoore, 4031 EatsAtLeast(kMaxLookaheadForBoyerMoore,
4038 EatsAtLeast(kMaxLookaheadForBoyerMoore, 0, not_at_start)); 4032 kRecursionBudget,
4033 not_at_start));
4039 if (eats_at_least >= 1) { 4034 if (eats_at_least >= 1) {
4040 BoyerMooreLookahead* bm = 4035 BoyerMooreLookahead* bm =
4041 new(zone()) BoyerMooreLookahead(eats_at_least, 4036 new(zone()) BoyerMooreLookahead(eats_at_least,
4042 compiler, 4037 compiler,
4043 zone()); 4038 zone());
4044 GuardedAlternative alt0 = alternatives_->at(0); 4039 GuardedAlternative alt0 = alternatives_->at(0);
4045 alt0.node()->FillInBMInfo(0, 0, kFillInBMBudget, bm, not_at_start); 4040 alt0.node()->FillInBMInfo(0, kRecursionBudget, bm, not_at_start);
4046 skip_was_emitted = bm->EmitSkipInstructions(macro_assembler); 4041 skip_was_emitted = bm->EmitSkipInstructions(macro_assembler);
4047 } 4042 }
4048 } else { 4043 } else {
4049 skip_was_emitted = lookahead->EmitSkipInstructions(macro_assembler); 4044 skip_was_emitted = lookahead->EmitSkipInstructions(macro_assembler);
4050 } 4045 }
4051 } 4046 }
4052 } 4047 }
4053 } 4048 }
4054 4049
4055 if (eats_at_least == kEatsAtLeastNotYetInitialized) { 4050 if (eats_at_least == kEatsAtLeastNotYetInitialized) {
4056 // Save some time by looking at most one machine word ahead. 4051 // Save some time by looking at most one machine word ahead.
4057 eats_at_least = EatsAtLeast(compiler->ascii() ? 4 : 2, 0, not_at_start); 4052 eats_at_least =
4053 EatsAtLeast(compiler->ascii() ? 4 : 2, kRecursionBudget, not_at_start);
4058 } 4054 }
4059 int preload_characters = CalculatePreloadCharacters(compiler, eats_at_least); 4055 int preload_characters = CalculatePreloadCharacters(compiler, eats_at_least);
4060 4056
4061 bool preload_is_current = !skip_was_emitted && 4057 bool preload_is_current = !skip_was_emitted &&
4062 (current_trace->characters_preloaded() == preload_characters); 4058 (current_trace->characters_preloaded() == preload_characters);
4063 bool preload_has_checked_bounds = preload_is_current; 4059 bool preload_has_checked_bounds = preload_is_current;
4064 4060
4065 AlternativeGenerationList alt_gens(choice_count, zone()); 4061 AlternativeGenerationList alt_gens(choice_count, zone());
4066 4062
4067 // For now we just call all choices one after the other. The idea ultimately 4063 // For now we just call all choices one after the other. The idea ultimately
(...skipping 1735 matching lines...) Expand 10 before | Expand all | Expand 10 after
5803 EnsureAnalyzed(that->on_success()); 5799 EnsureAnalyzed(that->on_success());
5804 } 5800 }
5805 5801
5806 5802
5807 void Analysis::VisitAssertion(AssertionNode* that) { 5803 void Analysis::VisitAssertion(AssertionNode* that) {
5808 EnsureAnalyzed(that->on_success()); 5804 EnsureAnalyzed(that->on_success());
5809 } 5805 }
5810 5806
5811 5807
5812 void BackReferenceNode::FillInBMInfo(int offset, 5808 void BackReferenceNode::FillInBMInfo(int offset,
5813 int recursion_depth,
5814 int budget, 5809 int budget,
5815 BoyerMooreLookahead* bm, 5810 BoyerMooreLookahead* bm,
5816 bool not_at_start) { 5811 bool not_at_start) {
5817 // Working out the set of characters that a backreference can match is too 5812 // Working out the set of characters that a backreference can match is too
5818 // hard, so we just say that any character can match. 5813 // hard, so we just say that any character can match.
5819 bm->SetRest(offset); 5814 bm->SetRest(offset);
5820 SaveBMInfo(bm, not_at_start, offset); 5815 SaveBMInfo(bm, not_at_start, offset);
5821 } 5816 }
5822 5817
5823 5818
5824 STATIC_ASSERT(BoyerMoorePositionInfo::kMapSize == 5819 STATIC_ASSERT(BoyerMoorePositionInfo::kMapSize ==
5825 RegExpMacroAssembler::kTableSize); 5820 RegExpMacroAssembler::kTableSize);
5826 5821
5827 5822
5828 void ChoiceNode::FillInBMInfo(int offset, 5823 void ChoiceNode::FillInBMInfo(int offset,
5829 int recursion_depth,
5830 int budget, 5824 int budget,
5831 BoyerMooreLookahead* bm, 5825 BoyerMooreLookahead* bm,
5832 bool not_at_start) { 5826 bool not_at_start) {
5833 ZoneList<GuardedAlternative>* alts = alternatives(); 5827 ZoneList<GuardedAlternative>* alts = alternatives();
5834 budget = (budget - 1) / alts->length(); 5828 budget = (budget - 1) / alts->length();
5835 for (int i = 0; i < alts->length(); i++) { 5829 for (int i = 0; i < alts->length(); i++) {
5836 GuardedAlternative& alt = alts->at(i); 5830 GuardedAlternative& alt = alts->at(i);
5837 if (alt.guards() != NULL && alt.guards()->length() != 0) { 5831 if (alt.guards() != NULL && alt.guards()->length() != 0) {
5838 bm->SetRest(offset); // Give up trying to fill in info. 5832 bm->SetRest(offset); // Give up trying to fill in info.
5839 SaveBMInfo(bm, not_at_start, offset); 5833 SaveBMInfo(bm, not_at_start, offset);
5840 return; 5834 return;
5841 } 5835 }
5842 alt.node()->FillInBMInfo( 5836 alt.node()->FillInBMInfo(offset, budget, bm, not_at_start);
5843 offset, recursion_depth + 1, budget, bm, not_at_start);
5844 } 5837 }
5845 SaveBMInfo(bm, not_at_start, offset); 5838 SaveBMInfo(bm, not_at_start, offset);
5846 } 5839 }
5847 5840
5848 5841
5849 void TextNode::FillInBMInfo(int initial_offset, 5842 void TextNode::FillInBMInfo(int initial_offset,
5850 int recursion_depth,
5851 int budget, 5843 int budget,
5852 BoyerMooreLookahead* bm, 5844 BoyerMooreLookahead* bm,
5853 bool not_at_start) { 5845 bool not_at_start) {
5854 if (initial_offset >= bm->length()) return; 5846 if (initial_offset >= bm->length()) return;
5855 int offset = initial_offset; 5847 int offset = initial_offset;
5856 int max_char = bm->max_char(); 5848 int max_char = bm->max_char();
5857 for (int i = 0; i < elements()->length(); i++) { 5849 for (int i = 0; i < elements()->length(); i++) {
5858 if (offset >= bm->length()) { 5850 if (offset >= bm->length()) {
5859 if (initial_offset == 0) set_bm_info(not_at_start, bm); 5851 if (initial_offset == 0) set_bm_info(not_at_start, bm);
5860 return; 5852 return;
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
5897 } 5889 }
5898 } 5890 }
5899 offset++; 5891 offset++;
5900 } 5892 }
5901 } 5893 }
5902 if (offset >= bm->length()) { 5894 if (offset >= bm->length()) {
5903 if (initial_offset == 0) set_bm_info(not_at_start, bm); 5895 if (initial_offset == 0) set_bm_info(not_at_start, bm);
5904 return; 5896 return;
5905 } 5897 }
5906 on_success()->FillInBMInfo(offset, 5898 on_success()->FillInBMInfo(offset,
5907 recursion_depth + 1,
5908 budget - 1, 5899 budget - 1,
5909 bm, 5900 bm,
5910 true); // Not at start after a text node. 5901 true); // Not at start after a text node.
5911 if (initial_offset == 0) set_bm_info(not_at_start, bm); 5902 if (initial_offset == 0) set_bm_info(not_at_start, bm);
5912 } 5903 }
5913 5904
5914 5905
5915 // ------------------------------------------------------------------- 5906 // -------------------------------------------------------------------
5916 // Dispatch table construction 5907 // Dispatch table construction
5917 5908
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after
6149 } 6140 }
6150 6141
6151 return compiler.Assemble(&macro_assembler, 6142 return compiler.Assemble(&macro_assembler,
6152 node, 6143 node,
6153 data->capture_count, 6144 data->capture_count,
6154 pattern); 6145 pattern);
6155 } 6146 }
6156 6147
6157 6148
6158 }} // namespace v8::internal 6149 }} // namespace v8::internal
OLDNEW
« no previous file with comments | « src/jsregexp.h ('k') | src/messages.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698