| 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 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 186 } | 186 } |
| 187 } else { | 187 } else { |
| 188 i = 0; | 188 i = 0; |
| 189 } | 189 } |
| 190 | 190 |
| 191 %_Log('regexp', 'regexp-exec,%0r,%1S,%2i', [this, s, lastIndex]); | 191 %_Log('regexp', 'regexp-exec,%0r,%1S,%2i', [this, s, lastIndex]); |
| 192 // matchIndices is either null or the lastMatchInfo array. | 192 // matchIndices is either null or the lastMatchInfo array. |
| 193 var matchIndices = %_RegExpExec(this, s, i, lastMatchInfo); | 193 var matchIndices = %_RegExpExec(this, s, i, lastMatchInfo); |
| 194 | 194 |
| 195 if (matchIndices === null) { | 195 if (matchIndices === null) { |
| 196 if (global) { | 196 if (global) this.lastIndex = 0; |
| 197 this.lastIndex = 0; | |
| 198 } | |
| 199 return null; | 197 return null; |
| 200 } | 198 } |
| 201 | 199 |
| 202 // Successful match. | 200 // Successful match. |
| 203 lastMatchInfoOverride = null; | 201 lastMatchInfoOverride = null; |
| 204 var result = BuildResultFromMatchInfo(matchIndices, s); | |
| 205 | |
| 206 if (global) { | 202 if (global) { |
| 207 this.lastIndex = lastMatchInfo[CAPTURE1]; | 203 this.lastIndex = lastMatchInfo[CAPTURE1]; |
| 208 } | 204 } |
| 209 return result; | 205 return BuildResultFromMatchInfo(matchIndices, s); |
| 210 } | 206 } |
| 211 | 207 |
| 212 | 208 |
| 213 // One-element cache for the simplified test regexp. | 209 // One-element cache for the simplified test regexp. |
| 214 var regexp_key; | 210 var regexp_key; |
| 215 var regexp_val; | 211 var regexp_val; |
| 216 | 212 |
| 217 // Section 15.10.6.3 doesn't actually make sense, but the intention seems to be | 213 // Section 15.10.6.3 doesn't actually make sense, but the intention seems to be |
| 218 // that test is defined in terms of String.prototype.exec. However, it probably | 214 // that test is defined in terms of String.prototype.exec. However, it probably |
| 219 // means the original value of String.prototype.exec, which is what everybody | 215 // means the original value of String.prototype.exec, which is what everybody |
| (...skipping 17 matching lines...) Expand all Loading... |
| 237 } else { | 233 } else { |
| 238 s = ToString(string); | 234 s = ToString(string); |
| 239 } | 235 } |
| 240 | 236 |
| 241 var lastIndex = this.lastIndex; | 237 var lastIndex = this.lastIndex; |
| 242 | 238 |
| 243 // Conversion is required by the ES5 specification (RegExp.prototype.exec | 239 // Conversion is required by the ES5 specification (RegExp.prototype.exec |
| 244 // algorithm, step 5) even if the value is discarded for non-global RegExps. | 240 // algorithm, step 5) even if the value is discarded for non-global RegExps. |
| 245 var i = TO_INTEGER(lastIndex); | 241 var i = TO_INTEGER(lastIndex); |
| 246 | 242 |
| 247 var global = this.global; | 243 if (this.global) { |
| 248 if (global) { | |
| 249 if (i < 0 || i > s.length) { | 244 if (i < 0 || i > s.length) { |
| 250 this.lastIndex = 0; | 245 this.lastIndex = 0; |
| 251 return false; | 246 return false; |
| 252 } | 247 } |
| 248 %_Log('regexp', 'regexp-exec,%0r,%1S,%2i', [this, s, lastIndex]); |
| 249 // matchIndices is either null or the lastMatchInfo array. |
| 250 var matchIndices = %_RegExpExec(this, s, i, lastMatchInfo); |
| 251 if (matchIndices === null) { |
| 252 this.lastIndex = 0; |
| 253 return false; |
| 254 } |
| 255 lastMatchInfoOverride = null; |
| 256 this.lastIndex = lastMatchInfo[CAPTURE1]; |
| 257 return true; |
| 253 } else { | 258 } else { |
| 254 i = 0; | 259 // Non-global regexp. |
| 260 // Remove irrelevant preceeding '.*' in a non-global test regexp. |
| 261 // The expression checks whether this.source starts with '.*' and |
| 262 // that the third char is not a '?'. |
| 263 if (%_StringCharCodeAt(this.source, 0) == 46 && // '.' |
| 264 %_StringCharCodeAt(this.source, 1) == 42 && // '*' |
| 265 %_StringCharCodeAt(this.source, 2) != 63) { // '?' |
| 266 if (!%_ObjectEquals(regexp_key, this)) { |
| 267 regexp_key = this; |
| 268 regexp_val = new $RegExp(this.source.substring(2, this.source.length), |
| 269 (this.ignoreCase ? 'i' : '') |
| 270 + (this.multiline ? 'm' : '')); |
| 271 } |
| 272 if (!regexp_val.test(s)) return false; |
| 273 } |
| 274 %_Log('regexp', 'regexp-exec,%0r,%1S,%2i', [this, s, lastIndex]); |
| 275 // matchIndices is either null or the lastMatchInfo array. |
| 276 var matchIndices = %_RegExpExec(this, s, 0, lastMatchInfo); |
| 277 if (matchIndices === null) return false; |
| 278 lastMatchInfoOverride = null; |
| 279 return true; |
| 255 } | 280 } |
| 256 | |
| 257 // Remove irrelevant preceeding '.*' in a test regexp. The expression | |
| 258 // checks whether this.source starts with '.*' and that the third | |
| 259 // char is not a '?' | |
| 260 if (%_StringCharCodeAt(this.source, 0) == 46 && // '.' | |
| 261 %_StringCharCodeAt(this.source, 1) == 42 && // '*' | |
| 262 %_StringCharCodeAt(this.source, 2) != 63) { // '?' | |
| 263 if (!%_ObjectEquals(regexp_key, this)) { | |
| 264 regexp_key = this; | |
| 265 regexp_val = new $RegExp(this.source.substring(2, this.source.length), | |
| 266 (global ? 'g' : '') | |
| 267 + (this.ignoreCase ? 'i' : '') | |
| 268 + (this.multiline ? 'm' : '')); | |
| 269 } | |
| 270 if (!regexp_val.test(s)) return false; | |
| 271 } | |
| 272 | |
| 273 %_Log('regexp', 'regexp-exec,%0r,%1S,%2i', [this, s, lastIndex]); | |
| 274 // matchIndices is either null or the lastMatchInfo array. | |
| 275 var matchIndices = %_RegExpExec(this, s, i, lastMatchInfo); | |
| 276 | |
| 277 if (matchIndices === null) { | |
| 278 if (global) this.lastIndex = 0; | |
| 279 return false; | |
| 280 } | |
| 281 lastMatchInfoOverride = null; | |
| 282 if (global) this.lastIndex = lastMatchInfo[CAPTURE1]; | |
| 283 return true; | |
| 284 } | 281 } |
| 285 | 282 |
| 286 | 283 |
| 287 function RegExpToString() { | 284 function RegExpToString() { |
| 288 // If this.source is an empty string, output /(?:)/. | 285 // If this.source is an empty string, output /(?:)/. |
| 289 // http://bugzilla.mozilla.org/show_bug.cgi?id=225550 | 286 // http://bugzilla.mozilla.org/show_bug.cgi?id=225550 |
| 290 // ecma_2/RegExp/properties-001.js. | 287 // ecma_2/RegExp/properties-001.js. |
| 291 var src = this.source ? this.source : '(?:)'; | 288 var src = this.source ? this.source : '(?:)'; |
| 292 var result = '/' + src + '/'; | 289 var result = '/' + src + '/'; |
| 293 if (this.global) result += 'g'; | 290 if (this.global) result += 'g'; |
| (...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 478 %DefineAccessor($RegExp, "$'", SETTER, NoOpSetter, DONT_ENUM | DONT_DELETE); | 475 %DefineAccessor($RegExp, "$'", SETTER, NoOpSetter, DONT_ENUM | DONT_DELETE); |
| 479 | 476 |
| 480 for (var i = 1; i < 10; ++i) { | 477 for (var i = 1; i < 10; ++i) { |
| 481 %DefineAccessor($RegExp, '$' + i, GETTER, RegExpMakeCaptureGetter(i), DONT_D
ELETE); | 478 %DefineAccessor($RegExp, '$' + i, GETTER, RegExpMakeCaptureGetter(i), DONT_D
ELETE); |
| 482 %DefineAccessor($RegExp, '$' + i, SETTER, NoOpSetter, DONT_DELETE); | 479 %DefineAccessor($RegExp, '$' + i, SETTER, NoOpSetter, DONT_DELETE); |
| 483 } | 480 } |
| 484 } | 481 } |
| 485 | 482 |
| 486 | 483 |
| 487 SetupRegExp(); | 484 SetupRegExp(); |
| OLD | NEW |