Chromium Code Reviews| 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 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 128 this.answer = 0; | 128 this.answer = 0; |
| 129 // answerSaved marks whether the contents of answer is valid for a cache | 129 // answerSaved marks whether the contents of answer is valid for a cache |
| 130 // hit in RegExpExec, StringMatch and StringSplit. | 130 // hit in RegExpExec, StringMatch and StringSplit. |
| 131 this.answerSaved = false; | 131 this.answerSaved = false; |
| 132 } | 132 } |
| 133 | 133 |
| 134 | 134 |
| 135 var regExpCache = new RegExpCache(); | 135 var regExpCache = new RegExpCache(); |
| 136 | 136 |
| 137 | 137 |
| 138 function CloneRegexpAnswer(array) { | 138 function CloneRegExpResult(array) { |
| 139 if (array == null) return null; | 139 if (array == null) return null; |
| 140 var len = array.length; | 140 var length = array.length; |
| 141 var answer = new $Array(len); | 141 var answer = %_RegExpConstructResult(length, array.index, array.input); |
|
Søren Thygesen Gjesse
2010/04/13 07:22:29
Will it be possible to pass in the array to have t
Lasse Reichstein
2010/04/13 09:50:56
It's a good idea for an optional argument. The fun
| |
| 142 for (var i = 0; i < len; i++) { | 142 for (var i = 0; i < length; i++) { |
| 143 answer[i] = array[i]; | 143 answer[i] = array[i]; |
| 144 } | 144 } |
| 145 answer.index = array.index; | |
| 146 answer.input = array.input; | |
| 147 return answer; | 145 return answer; |
| 148 } | 146 } |
| 149 | 147 |
| 150 | 148 |
| 149 function BuildResultFromMatchInfo(lastMatchInfo, s) { | |
| 150 var numResults = NUMBER_OF_CAPTURES(lastMatchInfo) >> 1; | |
| 151 var result = %_RegExpConstructResult(numResults, lastMatchInfo[CAPTURE0], s); | |
| 152 if (numResults === 1) { | |
| 153 var matchStart = lastMatchInfo[CAPTURE(0)]; | |
| 154 var matchEnd = lastMatchInfo[CAPTURE(1)]; | |
| 155 result[0] = SubString(s, matchStart, matchEnd); | |
| 156 } else { | |
| 157 for (var i = 0; i < numResults; i++) { | |
| 158 var matchStart = lastMatchInfo[CAPTURE(i << 1)]; | |
| 159 var matchEnd = lastMatchInfo[CAPTURE((i << 1) + 1)]; | |
| 160 if (matchStart != -1 && matchEnd != -1) { | |
| 161 result[i] = SubString(s, matchStart, matchEnd); | |
| 162 } else { | |
| 163 // Make sure the element is present. Avoid reading the undefined | |
| 164 // property from the global object since this may change. | |
| 165 result[i] = void 0; | |
| 166 } | |
| 167 } | |
| 168 } | |
| 169 return result; | |
| 170 } | |
| 171 | |
| 172 | |
| 173 function RegExpExecNoTests(regexp, string, start) { | |
| 174 // Must be called with RegExp, string and positive integer as arguments. | |
| 175 var matchInfo = DoRegExpExec(regexp, string, start); | |
| 176 var result = null; | |
| 177 if (matchInfo !== null) { | |
| 178 result = BuildResultFromMatchInfo(matchInfo, string); | |
| 179 } | |
| 180 return result; | |
| 181 } | |
| 182 | |
| 183 | |
| 151 function RegExpExec(string) { | 184 function RegExpExec(string) { |
| 152 if (!IS_REGEXP(this)) { | 185 if (!IS_REGEXP(this)) { |
| 153 throw MakeTypeError('incompatible_method_receiver', | 186 throw MakeTypeError('incompatible_method_receiver', |
| 154 ['RegExp.prototype.exec', this]); | 187 ['RegExp.prototype.exec', this]); |
| 155 } | 188 } |
| 156 | 189 |
| 157 var cache = regExpCache; | 190 var cache = regExpCache; |
| 158 var saveAnswer = false; | 191 var saveAnswer = false; |
| 159 | 192 |
| 160 if (%_ObjectEquals(cache.type, 'exec') && | 193 if (%_ObjectEquals(cache.type, 'exec') && |
| 161 %_ObjectEquals(cache.lastIndex, this.lastIndex) && | 194 %_ObjectEquals(cache.lastIndex, this.lastIndex) && |
| 162 %_ObjectEquals(cache.regExp, this) && | 195 %_ObjectEquals(cache.regExp, this) && |
| 163 %_ObjectEquals(cache.subject, string)) { | 196 %_ObjectEquals(cache.subject, string)) { |
| 164 if (cache.answerSaved) { | 197 if (cache.answerSaved) { |
| 165 return CloneRegexpAnswer(cache.answer); | 198 return CloneRegExpResult(cache.answer); |
| 166 } else { | 199 } else { |
| 167 saveAnswer = true; | 200 saveAnswer = true; |
| 168 } | 201 } |
| 169 } | 202 } |
| 170 | 203 |
| 171 if (%_ArgumentsLength() == 0) { | 204 if (%_ArgumentsLength() == 0) { |
| 172 var regExpInput = LAST_INPUT(lastMatchInfo); | 205 var regExpInput = LAST_INPUT(lastMatchInfo); |
| 173 if (IS_UNDEFINED(regExpInput)) { | 206 if (IS_UNDEFINED(regExpInput)) { |
| 174 throw MakeError('no_input_to_regexp', [this]); | 207 throw MakeError('no_input_to_regexp', [this]); |
| 175 } | 208 } |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 198 if (this.global) this.lastIndex = 0; | 231 if (this.global) this.lastIndex = 0; |
| 199 cache.lastIndex = lastIndex; | 232 cache.lastIndex = lastIndex; |
| 200 cache.regExp = this; | 233 cache.regExp = this; |
| 201 cache.subject = s; | 234 cache.subject = s; |
| 202 cache.answer = matchIndices; // Null. | 235 cache.answer = matchIndices; // Null. |
| 203 cache.answerSaved = true; // Safe since no cloning is needed. | 236 cache.answerSaved = true; // Safe since no cloning is needed. |
| 204 cache.type = 'exec'; | 237 cache.type = 'exec'; |
| 205 return matchIndices; // No match. | 238 return matchIndices; // No match. |
| 206 } | 239 } |
| 207 | 240 |
| 208 var numResults = NUMBER_OF_CAPTURES(lastMatchInfo) >> 1; | 241 var result = BuildResultFromMatchInfo(matchIndices, s); |
| 209 var result; | |
| 210 if (numResults === 1) { | |
| 211 var matchStart = lastMatchInfo[CAPTURE(0)]; | |
| 212 var matchEnd = lastMatchInfo[CAPTURE(1)]; | |
| 213 result = [SubString(s, matchStart, matchEnd)]; | |
| 214 } else { | |
| 215 result = new $Array(numResults); | |
| 216 for (var i = 0; i < numResults; i++) { | |
| 217 var matchStart = lastMatchInfo[CAPTURE(i << 1)]; | |
| 218 var matchEnd = lastMatchInfo[CAPTURE((i << 1) + 1)]; | |
| 219 if (matchStart != -1 && matchEnd != -1) { | |
| 220 result[i] = SubString(s, matchStart, matchEnd); | |
| 221 } else { | |
| 222 // Make sure the element is present. Avoid reading the undefined | |
| 223 // property from the global object since this may change. | |
| 224 result[i] = void 0; | |
| 225 } | |
| 226 } | |
| 227 } | |
| 228 | 242 |
| 229 result.index = lastMatchInfo[CAPTURE0]; | |
| 230 result.input = s; | |
| 231 if (this.global) { | 243 if (this.global) { |
| 232 this.lastIndex = lastMatchInfo[CAPTURE1]; | 244 this.lastIndex = lastMatchInfo[CAPTURE1]; |
| 233 } else { | 245 } else { |
| 234 cache.regExp = this; | 246 cache.regExp = this; |
| 235 cache.subject = s; | 247 cache.subject = s; |
| 236 cache.lastIndex = lastIndex; | 248 cache.lastIndex = lastIndex; |
| 237 if (saveAnswer) cache.answer = CloneRegexpAnswer(result); | 249 if (saveAnswer) cache.answer = CloneRegExpResult(result); |
| 238 cache.answerSaved = saveAnswer; | 250 cache.answerSaved = saveAnswer; |
| 239 cache.type = 'exec'; | 251 cache.type = 'exec'; |
| 240 } | 252 } |
| 241 return result; | 253 return result; |
| 242 | 254 |
| 243 } | 255 } |
| 244 | 256 |
| 245 | 257 |
| 246 // Section 15.10.6.3 doesn't actually make sense, but the intention seems to be | 258 // Section 15.10.6.3 doesn't actually make sense, but the intention seems to be |
| 247 // that test is defined in terms of String.prototype.exec. However, it probably | 259 // that test is defined in terms of String.prototype.exec. However, it probably |
| (...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 503 %DefineAccessor($RegExp, "$'", SETTER, NoOpSetter, DONT_ENUM | DONT_DELETE); | 515 %DefineAccessor($RegExp, "$'", SETTER, NoOpSetter, DONT_ENUM | DONT_DELETE); |
| 504 | 516 |
| 505 for (var i = 1; i < 10; ++i) { | 517 for (var i = 1; i < 10; ++i) { |
| 506 %DefineAccessor($RegExp, '$' + i, GETTER, RegExpMakeCaptureGetter(i), DONT_D ELETE); | 518 %DefineAccessor($RegExp, '$' + i, GETTER, RegExpMakeCaptureGetter(i), DONT_D ELETE); |
| 507 %DefineAccessor($RegExp, '$' + i, SETTER, NoOpSetter, DONT_DELETE); | 519 %DefineAccessor($RegExp, '$' + i, SETTER, NoOpSetter, DONT_DELETE); |
| 508 } | 520 } |
| 509 } | 521 } |
| 510 | 522 |
| 511 | 523 |
| 512 SetupRegExp(); | 524 SetupRegExp(); |
| OLD | NEW |