| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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(); |
| OLD | NEW |