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

Unified Diff: src/regexp-delay.js

Issue 995005: Fix a bug in the regexp caching. Also add a few more places to... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 10 years, 9 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | src/string.js » ('j') | test/mjsunit/regexp-cache-replace.js » ('J')
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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);
};
« no previous file with comments | « no previous file | src/string.js » ('j') | test/mjsunit/regexp-cache-replace.js » ('J')

Powered by Google App Engine
This is Rietveld 408576698