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

Side by Side Diff: src/regexp.js

Issue 1695002: Fix incorrect handling of global RegExp properties for nested replace-regexp-with-function. (Closed)
Patch Set: Created 10 years, 8 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
« no previous file with comments | « no previous file | src/string.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 2006-2009 the V8 project authors. All rights reserved. 1 // Copyright 2006-2009 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
108 // behavior. 108 // behavior.
109 if (IS_UNDEFINED(pattern) && %_ArgumentsLength() != 0) { 109 if (IS_UNDEFINED(pattern) && %_ArgumentsLength() != 0) {
110 DoConstructRegExp(this, 'undefined', flags, false); 110 DoConstructRegExp(this, 'undefined', flags, false);
111 } else { 111 } else {
112 DoConstructRegExp(this, pattern, flags, false); 112 DoConstructRegExp(this, pattern, flags, false);
113 } 113 }
114 } 114 }
115 115
116 116
117 function DoRegExpExec(regexp, string, index) { 117 function DoRegExpExec(regexp, string, index) {
118 return %_RegExpExec(regexp, string, index, lastMatchInfo); 118 var result = %_RegExpExec(regexp, string, index, lastMatchInfo);
119 if (result !== null) lastMatchInfoOverride = null;
120 return result;
119 } 121 }
120 122
121 123
122 function RegExpCache() { 124 function RegExpCache() {
123 this.type = 'none'; 125 this.type = 'none';
124 this.regExp = 0; 126 this.regExp = 0;
125 this.subject = 0; 127 this.subject = 0;
126 this.replaceString = 0; 128 this.replaceString = 0;
127 this.lastIndex = 0; 129 this.lastIndex = 0;
128 this.answer = 0; 130 this.answer = 0;
129 // answerSaved marks whether the contents of answer is valid for a cache 131 // answerSaved marks whether the contents of answer is valid for a cache
130 // hit in RegExpExec, StringMatch and StringSplit. 132 // hit in RegExpExec, StringMatch and StringSplit.
131 this.answerSaved = false; 133 this.answerSaved = false;
132 } 134 }
133 135
134 136
135 var regExpCache = new RegExpCache(); 137 var regExpCache = new RegExpCache();
136 138
137 139
138 function CloneRegExpResult(array) { 140 function CloneRegExpResult(array) {
139 if (array == null) return null; 141 if (array == null) return null;
140 var length = array.length; 142 var length = array.length;
141 var answer = %_RegExpConstructResult(length, array.index, array.input); 143 var answer = %_RegExpConstructResult(length, array.index, array.input);
142 for (var i = 0; i < length; i++) { 144 for (var i = 0; i < length; i++) {
143 answer[i] = array[i]; 145 answer[i] = array[i];
144 } 146 }
145 return answer; 147 return answer;
146 } 148 }
147 149
148 150
149 function BuildResultFromMatchInfo(lastMatchInfo, s) { 151 function BuildResultFromMatchInfo(lastMatchInfo, s) {
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
230 if (matchIndices == null) { 232 if (matchIndices == null) {
231 if (this.global) this.lastIndex = 0; 233 if (this.global) this.lastIndex = 0;
232 cache.lastIndex = lastIndex; 234 cache.lastIndex = lastIndex;
233 cache.regExp = this; 235 cache.regExp = this;
234 cache.subject = s; 236 cache.subject = s;
235 cache.answer = matchIndices; // Null. 237 cache.answer = matchIndices; // Null.
236 cache.answerSaved = true; // Safe since no cloning is needed. 238 cache.answerSaved = true; // Safe since no cloning is needed.
237 cache.type = 'exec'; 239 cache.type = 'exec';
238 return matchIndices; // No match. 240 return matchIndices; // No match.
239 } 241 }
240 242 lastMatchInfoOverride = null;
241 var result = BuildResultFromMatchInfo(matchIndices, s); 243 var result = BuildResultFromMatchInfo(matchIndices, s);
242 244
243 if (this.global) { 245 if (this.global) {
244 this.lastIndex = lastMatchInfo[CAPTURE1]; 246 this.lastIndex = lastMatchInfo[CAPTURE1];
245 } else { 247 } else {
246 cache.regExp = this; 248 cache.regExp = this;
247 cache.subject = s; 249 cache.subject = s;
248 cache.lastIndex = lastIndex; 250 cache.lastIndex = lastIndex;
249 if (saveAnswer) cache.answer = CloneRegExpResult(result); 251 if (saveAnswer) cache.answer = CloneRegExpResult(result);
250 cache.answerSaved = saveAnswer; 252 cache.answerSaved = saveAnswer;
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
305 307
306 %_Log('regexp', 'regexp-exec,%0r,%1S,%2i', [this, s, lastIndex]); 308 %_Log('regexp', 'regexp-exec,%0r,%1S,%2i', [this, s, lastIndex]);
307 // matchIndices is either null or the lastMatchInfo array. 309 // matchIndices is either null or the lastMatchInfo array.
308 var matchIndices = %_RegExpExec(this, s, i, lastMatchInfo); 310 var matchIndices = %_RegExpExec(this, s, i, lastMatchInfo);
309 311
310 if (matchIndices == null) { 312 if (matchIndices == null) {
311 if (this.global) this.lastIndex = 0; 313 if (this.global) this.lastIndex = 0;
312 cache.answer = false; 314 cache.answer = false;
313 return false; 315 return false;
314 } 316 }
315 317 lastMatchInfoOverride = null;
316 if (this.global) this.lastIndex = lastMatchInfo[CAPTURE1]; 318 if (this.global) this.lastIndex = lastMatchInfo[CAPTURE1];
317 cache.answer = true; 319 cache.answer = true;
318 return true; 320 return true;
319 } 321 }
320 322
321 323
322 function RegExpToString() { 324 function RegExpToString() {
323 // If this.source is an empty string, output /(?:)/. 325 // If this.source is an empty string, output /(?:)/.
324 // http://bugzilla.mozilla.org/show_bug.cgi?id=225550 326 // http://bugzilla.mozilla.org/show_bug.cgi?id=225550
325 // ecma_2/RegExp/properties-001.js. 327 // ecma_2/RegExp/properties-001.js.
326 var src = this.source ? this.source : '(?:)'; 328 var src = this.source ? this.source : '(?:)';
327 var result = '/' + src + '/'; 329 var result = '/' + src + '/';
328 if (this.global) 330 if (this.global)
329 result += 'g'; 331 result += 'g';
330 if (this.ignoreCase) 332 if (this.ignoreCase)
331 result += 'i'; 333 result += 'i';
332 if (this.multiline) 334 if (this.multiline)
333 result += 'm'; 335 result += 'm';
334 return result; 336 return result;
335 } 337 }
336 338
337 339
338 // Getters for the static properties lastMatch, lastParen, leftContext, and 340 // Getters for the static properties lastMatch, lastParen, leftContext, and
339 // rightContext of the RegExp constructor. The properties are computed based 341 // rightContext of the RegExp constructor. The properties are computed based
340 // on the captures array of the last successful match and the subject string 342 // on the captures array of the last successful match and the subject string
341 // of the last successful match. 343 // of the last successful match.
342 function RegExpGetLastMatch() { 344 function RegExpGetLastMatch() {
343 if (lastMatchInfoOverride) { return lastMatchInfoOverride[0]; } 345 if (lastMatchInfoOverride !== null) {
346 return lastMatchInfoOverride[0];
347 }
344 var regExpSubject = LAST_SUBJECT(lastMatchInfo); 348 var regExpSubject = LAST_SUBJECT(lastMatchInfo);
345 return SubString(regExpSubject, 349 return SubString(regExpSubject,
346 lastMatchInfo[CAPTURE0], 350 lastMatchInfo[CAPTURE0],
347 lastMatchInfo[CAPTURE1]); 351 lastMatchInfo[CAPTURE1]);
348 } 352 }
349 353
350 354
351 function RegExpGetLastParen() { 355 function RegExpGetLastParen() {
352 if (lastMatchInfoOverride) { 356 if (lastMatchInfoOverride) {
353 var override = lastMatchInfoOverride; 357 var override = lastMatchInfoOverride;
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
515 %DefineAccessor($RegExp, "$'", SETTER, NoOpSetter, DONT_ENUM | DONT_DELETE); 519 %DefineAccessor($RegExp, "$'", SETTER, NoOpSetter, DONT_ENUM | DONT_DELETE);
516 520
517 for (var i = 1; i < 10; ++i) { 521 for (var i = 1; i < 10; ++i) {
518 %DefineAccessor($RegExp, '$' + i, GETTER, RegExpMakeCaptureGetter(i), DONT_D ELETE); 522 %DefineAccessor($RegExp, '$' + i, GETTER, RegExpMakeCaptureGetter(i), DONT_D ELETE);
519 %DefineAccessor($RegExp, '$' + i, SETTER, NoOpSetter, DONT_DELETE); 523 %DefineAccessor($RegExp, '$' + i, SETTER, NoOpSetter, DONT_DELETE);
520 } 524 }
521 } 525 }
522 526
523 527
524 SetupRegExp(); 528 SetupRegExp();
OLDNEW
« no previous file with comments | « no previous file | src/string.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698