| Index: src/regexp-delay.js
|
| ===================================================================
|
| --- src/regexp-delay.js (revision 4148)
|
| +++ src/regexp-delay.js (working copy)
|
| @@ -95,16 +95,7 @@
|
| %IgnoreAttributesAndSetProperty(object, 'ignoreCase', ignoreCase);
|
| %IgnoreAttributesAndSetProperty(object, 'multiline', multiline);
|
| %IgnoreAttributesAndSetProperty(object, 'lastIndex', 0);
|
| - // Clear the regexp result cache.
|
| - cachedRegexp = 0;
|
| - cachedSubject = 0;
|
| - cachedLastIndex = 0;
|
| - cachedAnswer = 0;
|
| - // These are from string.js.
|
| - cachedReplaceSubject = 0;
|
| - cachedReplaceRegexp = 0;
|
| - cachedReplaceReplacement = 0;
|
| - cachedReplaceAnswer = 0;
|
| + regExpCache.type = 'none';
|
| }
|
|
|
| // Call internal function to compile the pattern.
|
| @@ -150,12 +141,19 @@
|
| }
|
|
|
|
|
| -var cachedRegexp;
|
| -var cachedSubject;
|
| -var cachedLastIndex;
|
| -var cachedAnswer;
|
| +function RegExpCache() {
|
| + this.type = 'none';
|
| + this.regExp = 0;
|
| + this.subject = 0;
|
| + this.replaceString = 0;
|
| + this.lastIndex = 0;
|
| + this.answer = 0;
|
| +}
|
|
|
|
|
| +var regExpCache = new RegExpCache();
|
| +
|
| +
|
| function CloneRegexpAnswer(array) {
|
| var len = array.length;
|
| var answer = new $Array(len);
|
| @@ -169,10 +167,18 @@
|
|
|
|
|
| function RegExpExec(string) {
|
| - if (%_ObjectEquals(cachedLastIndex, this.lastIndex) &&
|
| - %_ObjectEquals(cachedRegexp, this) &&
|
| - %_ObjectEquals(cachedSubject, string)) {
|
| - var last = cachedAnswer;
|
| + if (!IS_REGEXP(this)) {
|
| + throw MakeTypeError('incompatible_method_receiver',
|
| + ['RegExp.prototype.exec', this]);
|
| + }
|
| +
|
| + var cache = regExpCache;
|
| +
|
| + if (%_ObjectEquals(cache.type, 'exec') &&
|
| + %_ObjectEquals(cache.lastIndex, this.lastIndex) &&
|
| + %_ObjectEquals(cache.regExp, this) &&
|
| + %_ObjectEquals(cache.subject, string)) {
|
| + var last = cache.answer;
|
| if (last == null) {
|
| return last;
|
| } else {
|
| @@ -180,10 +186,6 @@
|
| }
|
| }
|
|
|
| - if (!IS_REGEXP(this)) {
|
| - throw MakeTypeError('incompatible_method_receiver',
|
| - ['RegExp.prototype.exec', this]);
|
| - }
|
| if (%_ArgumentsLength() == 0) {
|
| var regExpInput = LAST_INPUT(lastMatchInfo);
|
| if (IS_UNDEFINED(regExpInput)) {
|
| @@ -212,10 +214,11 @@
|
|
|
| if (matchIndices == null) {
|
| if (this.global) this.lastIndex = 0;
|
| - cachedLastIndex = lastIndex;
|
| - cachedRegexp = this;
|
| - cachedSubject = s;
|
| - cachedAnswer = matchIndices; // Null.
|
| + cache.lastIndex = lastIndex;
|
| + cache.regExp = this;
|
| + cache.subject = s;
|
| + cache.answer = matchIndices; // Null.
|
| + cache.type = 'exec';
|
| return matchIndices; // No match.
|
| }
|
|
|
| @@ -246,10 +249,11 @@
|
| this.lastIndex = lastMatchInfo[CAPTURE1];
|
| return result;
|
| } else {
|
| - cachedRegexp = this;
|
| - cachedSubject = s;
|
| - cachedLastIndex = lastIndex;
|
| - cachedAnswer = result;
|
| + cache.regExp = this;
|
| + cache.subject = s;
|
| + cache.lastIndex = lastIndex;
|
| + cache.answer = result;
|
| + cache.type = 'exec';
|
| return CloneRegexpAnswer(result);
|
| }
|
| }
|
| @@ -271,13 +275,35 @@
|
| }
|
| string = regExpInput;
|
| }
|
| - var s = ToString(string);
|
| + var s;
|
| + if (IS_STRING(string)) {
|
| + s = string;
|
| + } else {
|
| + s = ToString(string);
|
| + }
|
| +
|
| + var lastIndex = this.lastIndex;
|
| +
|
| + var cache = regExpCache;
|
| +
|
| + if (%_ObjectEquals(cache.type, 'test') &&
|
| + %_ObjectEquals(cache.regExp, this) &&
|
| + %_ObjectEquals(cache.subject, string) &&
|
| + %_ObjectEquals(cache.lastIndex, lastIndex)) {
|
| + return cache.answer;
|
| + }
|
| +
|
| var length = s.length;
|
| - var lastIndex = this.lastIndex;
|
| var i = this.global ? TO_INTEGER(lastIndex) : 0;
|
|
|
| + cache.type = 'test';
|
| + cache.regExp = this;
|
| + cache.subject = s;
|
| + cache.lastIndex = i;
|
| +
|
| if (i < 0 || i > s.length) {
|
| this.lastIndex = 0;
|
| + cache.answer = false;
|
| return false;
|
| }
|
|
|
| @@ -287,10 +313,12 @@
|
|
|
| if (matchIndices == null) {
|
| if (this.global) this.lastIndex = 0;
|
| + cache.answer = false;
|
| return false;
|
| }
|
|
|
| if (this.global) this.lastIndex = lastMatchInfo[CAPTURE1];
|
| + cache.answer = true;
|
| return true;
|
| }
|
|
|
| @@ -409,6 +437,7 @@
|
| return IS_UNDEFINED(regExpInput) ? "" : regExpInput;
|
| }
|
| function RegExpSetInput(string) {
|
| + regExpCache.type = 'none';
|
| LAST_INPUT(lastMatchInfo) = ToString(string);
|
| };
|
|
|
|
|