JavaScriptCore:
Reviewed by Darin Adler.
Fixed part of http://bugs.webkit.org/show_bug.cgi?id=15861
15% of string-validate-input.js is spent compiling the same regular expression.
Put RegExpImp properties into a static hashtable to avoid a slew of
PropertyMap churn when creating a RegExpImp.
Factored important bits of regular expression implementation out of
RegExpImp (the JS object) and into RegExp (the PCRE wrapper class),
making RegExp a ref-counted class. (This will help later.)
Removed PCRE_POSIX support because I didn't quite know how to test it
and keep it working with these changes.
1.1% SunSpider speedup. 5.8% speedup on string-validate-input.js.
* kjs/regexp.h: A few interface changes:
1. Renamed "subpatterns()" => "numSubpatterns()"
2. Made flag enumeration private and replaced it with public getters for
specific flags.
3. Made RegExp ref-counted so RegExps can be shared by RegExpImps.
4. Made RegExp take a string of flags instead of an int, eliminating
duplicated flag parsing code elsewhere.
* kjs/regexp_object.cpp:
(KJS::RegExpProtoFunc::callAsFunction): For RegExp.compile:
- Fixed a bug where compile(undefined) would throw an exception.
- Removed some now-redundant code.
- Used RegExp sharing to eliminate an allocation and a bunch of
PropertyMap thrash. (Not a big win since compile is a deprecated
function. I mainly did this to test the plubming.)
LayoutTests:
Reviewed by Darin Adler.
Beefed up the RegExp.compile testcase to cover a mistake in the
original check-in and a mistake I made while developing my new patch.
* fast/js/resources/regexp-compile.js:
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@27571 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/JavaScriptCore/kjs/string_object.cpp b/JavaScriptCore/kjs/string_object.cpp
index 39dd761..e59694e 100644
--- a/JavaScriptCore/kjs/string_object.cpp
+++ b/JavaScriptCore/kjs/string_object.cpp
@@ -276,13 +276,13 @@
} else if (ref >= '0' && ref <= '9') {
// 1- and 2-digit back references are allowed
unsigned backrefIndex = ref - '0';
- if (backrefIndex > (unsigned)reg->subPatterns())
+ if (backrefIndex > reg->numSubpatterns())
continue;
if (substitutedReplacement.size() > i + 2) {
ref = substitutedReplacement[i+2].unicode();
if (ref >= '0' && ref <= '9') {
backrefIndex = 10 * backrefIndex + ref - '0';
- if (backrefIndex > (unsigned)reg->subPatterns())
+ if (backrefIndex > reg->numSubpatterns())
backrefIndex = backrefIndex / 10; // Fall back to the 1-digit reference
else
advance = 1;
@@ -334,7 +334,7 @@
if (pattern->isObject() && static_cast<JSObject *>(pattern)->inherits(&RegExpImp::info)) {
RegExp *reg = static_cast<RegExpImp *>(pattern)->regExp();
- bool global = reg->flags() & RegExp::Global;
+ bool global = reg->global();
RegExpObjectImp* regExpObj = static_cast<RegExpObjectImp*>(exec->lexicalInterpreter()->builtinRegExp());
@@ -364,7 +364,7 @@
int completeMatchStart = ovector[0];
List args;
- for (unsigned i = 0; i < reg->subPatterns() + 1; i++) {
+ for (unsigned i = 0; i < reg->numSubpatterns() + 1; i++) {
int matchStart = ovector[i * 2];
int matchLen = ovector[i * 2 + 1] - matchStart;
@@ -519,7 +519,7 @@
* If regexp is not an object whose [[Class]] property is "RegExp", it is
* replaced with the result of the expression new RegExp(regexp).
*/
- reg = tmpReg = new RegExp(a0->toString(exec), RegExp::None);
+ reg = tmpReg = new RegExp(a0->toString(exec));
}
RegExpObjectImp* regExpObj = static_cast<RegExpObjectImp*>(exec->lexicalInterpreter()->builtinRegExp());
int pos;
@@ -529,7 +529,7 @@
result = jsNumber(pos);
} else {
// Match
- if ((reg->flags() & RegExp::Global) == 0) {
+ if (!(reg->global())) {
// case without 'g' flag is handled like RegExp.prototype.exec
if (pos < 0)
result = jsNull();
@@ -546,7 +546,7 @@
regExpObj->performMatch(reg, u, pos, pos, matchLength);
}
if (imp)
- imp->put(exec, "lastIndex", jsNumber(lastIndex), DontDelete|DontEnum);
+ imp->put(exec, exec->propertyNames().lastIndex, jsNumber(lastIndex), DontDelete|DontEnum);
if (list.isEmpty()) {
// if there are no matches at all, it's important to return
// Null instead of an empty array, because this matches
@@ -613,7 +613,7 @@
p0 = mpos + mlen;
i++;
}
- for (unsigned si = 1; si <= reg->subPatterns(); ++si) {
+ for (unsigned si = 1; si <= reg->numSubpatterns(); ++si) {
int spos = ovector[si * 2];
if (spos < 0)
res->put(exec, i++, jsUndefined());