[webkit-changes] cvs commit: JavaScriptCore/kjs create_hash_table
regexp.cpp regexp_object.cpp regexp_object.h string_object.cpp
Geoffrey
ggaren at opensource.apple.com
Tue Oct 11 13:43:51 PDT 2005
ggaren 05/10/11 13:43:51
Modified: . ChangeLog
JavaScriptCore.xcodeproj project.pbxproj
kjs create_hash_table regexp.cpp regexp_object.cpp
regexp_object.h string_object.cpp
Log:
- Implemented caching of match state inside the global RegExp object
(lastParen, leftContext, rightContext, lastMatch, input).
exec(), test(), match(), search(), and replace() now dipatch regular
expression matching through the RegExp object's performMatch function,
to facilitate caching. This replaces registerRegexp and
setSubPatterns.
- Implemented the special '$' aliases (e.g. RegExp.input aliases to
RegExp.$_).
- Moved support for backreferences into the new static hash table
used for other special RegExp properties. Truncated backreferences
at $9 to match IE, FF, and the "What's New in Netscape 1.2?" doc.
(String.replace still supports double-digit backreferences.)
- Tweaked RegExp.prototype.exec to handle ginormous values in lastIndex.
Fixes 11 -- count em, 11 -- JavaScriptCore tests.
Reviewed by NOBODY (OOPS!).
* JavaScriptCore.xcodeproj/project.pbxproj: Added regexp_object.lut.h
* kjs/create_hash_table: Tweaked to allow for more exotic characters.
We now rely on the compiler to catch illegal
identifiers.
* kjs/regexp.cpp:
(KJS::RegExp::RegExp):
* kjs/regexp_object.cpp:
(RegExpProtoFuncImp::callAsFunction):
(RegExpObjectImp::RegExpObjectImp):
(RegExpObjectImp::performMatch):
(RegExpObjectImp::arrayOfMatches):
(RegExpObjectImp::backrefGetter):
(RegExpObjectImp::getLastMatch):
(RegExpObjectImp::getLastParen):
(RegExpObjectImp::getLeftContext):
(RegExpObjectImp::getRightContext):
(RegExpObjectImp::getOwnPropertySlot):
(RegExpObjectImp::getValueProperty):
(RegExpObjectImp::put):
(RegExpObjectImp::putValueProperty):
* kjs/regexp_object.h:
(KJS::RegExpObjectImp::):
* kjs/string_object.cpp:
(substituteBackreferences):
(replace):
(StringProtoFuncImp::callAsFunction):
Revision Changes Path
1.860 +51 -0 JavaScriptCore/ChangeLog
Index: ChangeLog
===================================================================
RCS file: /cvs/root/JavaScriptCore/ChangeLog,v
retrieving revision 1.859
retrieving revision 1.860
diff -u -r1.859 -r1.860
--- ChangeLog 9 Oct 2005 22:57:59 -0000 1.859
+++ ChangeLog 11 Oct 2005 20:43:46 -0000 1.860
@@ -1,3 +1,54 @@
+2005-10-10 Geoffrey Garen <ggaren at apple.com>
+
+ - Implemented caching of match state inside the global RegExp object
+ (lastParen, leftContext, rightContext, lastMatch, input).
+
+ exec(), test(), match(), search(), and replace() now dipatch regular
+ expression matching through the RegExp object's performMatch function,
+ to facilitate caching. This replaces registerRegexp and
+ setSubPatterns.
+
+ - Implemented the special '$' aliases (e.g. RegExp.input aliases to
+ RegExp.$_).
+
+ - Moved support for backreferences into the new static hash table
+ used for other special RegExp properties. Truncated backreferences
+ at $9 to match IE, FF, and the "What's New in Netscape 1.2?" doc.
+ (String.replace still supports double-digit backreferences.)
+
+ - Tweaked RegExp.prototype.exec to handle ginormous values in lastIndex.
+
+ Fixes 11 -- count em, 11 -- JavaScriptCore tests.
+
+ Reviewed by NOBODY (OOPS!).
+
+ * JavaScriptCore.xcodeproj/project.pbxproj: Added regexp_object.lut.h
+ * kjs/create_hash_table: Tweaked to allow for more exotic characters.
+ We now rely on the compiler to catch illegal
+ identifiers.
+ * kjs/regexp.cpp:
+ (KJS::RegExp::RegExp):
+ * kjs/regexp_object.cpp:
+ (RegExpProtoFuncImp::callAsFunction):
+ (RegExpObjectImp::RegExpObjectImp):
+ (RegExpObjectImp::performMatch):
+ (RegExpObjectImp::arrayOfMatches):
+ (RegExpObjectImp::backrefGetter):
+ (RegExpObjectImp::getLastMatch):
+ (RegExpObjectImp::getLastParen):
+ (RegExpObjectImp::getLeftContext):
+ (RegExpObjectImp::getRightContext):
+ (RegExpObjectImp::getOwnPropertySlot):
+ (RegExpObjectImp::getValueProperty):
+ (RegExpObjectImp::put):
+ (RegExpObjectImp::putValueProperty):
+ * kjs/regexp_object.h:
+ (KJS::RegExpObjectImp::):
+ * kjs/string_object.cpp:
+ (substituteBackreferences):
+ (replace):
+ (StringProtoFuncImp::callAsFunction):
+
2005-10-09 Darin Adler <darin at apple.com>
Reviewed by Maciej; some changes done after review.
1.19 +18 -0 JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
Index: project.pbxproj
===================================================================
RCS file: /cvs/root/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -r1.18 -r1.19
--- project.pbxproj 5 Oct 2005 08:05:36 -0000 1.18
+++ project.pbxproj 11 Oct 2005 20:43:48 -0000 1.19
@@ -1129,6 +1129,7 @@
93F197EC08245819001E9ABC /* lexer.lut.h */,
93F1983308245BA1001E9ABC /* math_object.lut.h */,
93F1983108245B9E001E9ABC /* number_object.lut.h */,
+ 14F6037308FB039300E9E573 /* regexp_object.lut.h */,
93F1983508245BA6001E9ABC /* string_object.lut.h */,
932F5B3F0822A1C700736975 /* Headers */,
932F5B910822A1C700736975 /* Sources */,
@@ -1356,6 +1357,23 @@
/* End PBXProject section */
/* Begin PBXShellScriptBuildPhase section */
+ 14F6037308FB039300E9E573 /* regexp_object.lut.h */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ "kjs/create_hash_table\nkjs/create_hash_table",
+ kjs/regexp_object.cpp,
+ );
+ name = regexp_object.lut.h;
+ outputPaths = (
+ "$(DERIVED_FILE_DIR)/regexp_object.lut.h",
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "kjs/create_hash_table kjs/regexp_object.cpp -i > \"$DERIVED_FILE_DIR/regexp_object.lut.h\"";
+ };
93396BB50824516200AB803D /* chartables.c */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
1.6 +2 -2 JavaScriptCore/kjs/create_hash_table
Index: create_hash_table
===================================================================
RCS file: /cvs/root/JavaScriptCore/kjs/create_hash_table,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- create_hash_table 1 Jul 2005 09:48:20 -0000 1.5
+++ create_hash_table 11 Oct 2005 20:43:49 -0000 1.6
@@ -64,7 +64,7 @@
@attrs = ();
@params = ();
$inside = 0;
- } elsif (/^([-:\@\w\[\=\]]+)\s*([\w\:-]+)\s*([\w\|]*)\s*(\w*)\s*$/ && $inside) {
+ } elsif (/^(\S+)\s*(\S+)\s*([\w\|]*)\s*(\w*)\s*$/ && $inside) {
my $key = $1;
my $val = $2;
my $att = $3;
@@ -76,7 +76,7 @@
push(@attrs, length($att) > 0 ? $att : "0");
push(@params, length($param) > 0 ? $param : "0");
} elsif ($inside) {
- die "invalid data";
+ die "invalid data {" . $_ . "}";
}
}
1.14 +1 -0 JavaScriptCore/kjs/regexp.cpp
Index: regexp.cpp
===================================================================
RCS file: /cvs/root/JavaScriptCore/kjs/regexp.cpp,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -r1.13 -r1.14
--- regexp.cpp 3 Oct 2005 21:11:51 -0000 1.13
+++ regexp.cpp 11 Oct 2005 20:43:49 -0000 1.14
@@ -36,6 +36,7 @@
int options = PCRE_UTF8;
// Note: the Global flag is already handled by RegExpProtoFunc::execute.
+ // FIXME: That last comment is dubious. Not all RegExps get run through RegExpProtoFunc::execute.
if (flags & IgnoreCase)
options |= PCRE_CASELESS;
if (flags & Multiline)
1.26 +203 -71 JavaScriptCore/kjs/regexp_object.cpp
Index: regexp_object.cpp
===================================================================
RCS file: /cvs/root/JavaScriptCore/kjs/regexp_object.cpp,v
retrieving revision 1.25
retrieving revision 1.26
diff -u -r1.25 -r1.26
--- regexp_object.cpp 3 Oct 2005 21:11:51 -0000 1.25
+++ regexp_object.cpp 11 Oct 2005 20:43:49 -0000 1.26
@@ -23,6 +23,8 @@
#include "config.h"
#include "regexp_object.h"
+#include "regexp_object.lut.h"
+
#include <stdio.h>
#include "value.h"
#include "object.h"
@@ -32,6 +34,7 @@
#include "internal.h"
#include "regexp.h"
#include "error_object.h"
+#include "lookup.h"
using namespace KJS;
@@ -79,69 +82,64 @@
case ToString: return String("//");
}
}
+
return throwError(exec, TypeError);
}
- RegExpImp *reimp = static_cast<RegExpImp*>(thisObj);
- RegExp *re = reimp->regExp();
- UString s;
- UString str;
switch (id) {
- case Exec: // 15.10.6.2
- case Test:
+ case Test: // 15.10.6.2
+ case Exec:
{
- s = args[0]->toString(exec);
- int length = s.size();
- ValueImp *lastIndex = thisObj->get(exec,"lastIndex");
- int i = lastIndex->toInt32(exec);
- bool globalFlag = thisObj->get(exec,"global")->toBoolean(exec);
+ RegExp *regExp = static_cast<RegExpImp*>(thisObj)->regExp();
+ RegExpObjectImp* regExpObj = static_cast<RegExpObjectImp*>(exec->lexicalInterpreter()->builtinRegExp());
+
+ UString input;
+ if (args.isEmpty())
+ input = regExpObj->get(exec, "input")->toString(exec);
+ else
+ input = args[0]->toString(exec);
+
+ double lastIndex = thisObj->get(exec, "lastIndex")->toInteger(exec);
+
+ bool globalFlag = thisObj->get(exec, "global")->toBoolean(exec);
if (!globalFlag)
- i = 0;
- if (i < 0 || i > length) {
- thisObj->put(exec,"lastIndex", Number(0), DontDelete | DontEnum);
- if (id == Test)
- return Boolean(false);
- else
- return Null();
+ lastIndex = 0;
+ if (lastIndex < 0 || lastIndex > input.size()) {
+ thisObj->put(exec, "lastIndex", jsZero(), DontDelete | DontEnum);
+ return Null();
}
- RegExpObjectImp* regExpObj = static_cast<RegExpObjectImp*>(exec->lexicalInterpreter()->builtinRegExp());
- int **ovector = regExpObj->registerRegexp( re, s );
- str = re->match(s, i, 0L, ovector);
- regExpObj->setSubPatterns(re->subPatterns());
+ UString match = regExpObj->performMatch(regExp, input, static_cast<int>(lastIndex));
+ bool didMatch = !match.isNull();
+ // Test
if (id == Test)
- return Boolean(!str.isNull());
+ return Boolean(didMatch);
- if (str.isNull()) // no match
- {
+ // Exec
+ if (didMatch) {
if (globalFlag)
- thisObj->put(exec,"lastIndex",Number(0), DontDelete | DontEnum);
- return Null();
- }
- else // success
- {
+ thisObj->put(exec, "lastIndex", Number(lastIndex + match.size()), DontDelete | DontEnum);
+ return regExpObj->arrayOfMatches(exec, match);
+ } else {
if (globalFlag)
- thisObj->put(exec,"lastIndex",Number( (*ovector)[1] ), DontDelete | DontEnum);
- return regExpObj->arrayOfMatches(exec,str);
+ thisObj->put(exec, "lastIndex", jsZero(), DontDelete | DontEnum);
+ return Null();
}
}
break;
case ToString:
- s = thisObj->get(exec,"source")->toString(exec);
- str = "/";
- str += s;
- str += "/";
- if (thisObj->get(exec,"global")->toBoolean(exec)) {
- str += "g";
+ UString result = "/" + thisObj->get(exec, "source")->toString(exec) + "/";
+ if (thisObj->get(exec, "global")->toBoolean(exec)) {
+ result += "g";
}
- if (thisObj->get(exec,"ignoreCase")->toBoolean(exec)) {
- str += "i";
+ if (thisObj->get(exec, "ignoreCase")->toBoolean(exec)) {
+ result += "i";
}
- if (thisObj->get(exec,"multiline")->toBoolean(exec)) {
- str += "m";
+ if (thisObj->get(exec, "multiline")->toBoolean(exec)) {
+ result += "m";
}
- return String(str);
+ return String(result);
}
return Undefined();
@@ -163,11 +161,39 @@
// ------------------------------ RegExpObjectImp ------------------------------
+const ClassInfo RegExpObjectImp::info = {"RegExp", &InternalFunctionImp::info, &RegExpTable, 0};
+
+/* Source for regexp_object.lut.h
+ at begin RegExpTable 20
+ input RegExpObjectImp::Input None
+ $_ RegExpObjectImp::Input DontEnum
+ multiline RegExpObjectImp::Multiline None
+ $* RegExpObjectImp::Multiline DontEnum
+ lastMatch RegExpObjectImp::LastMatch DontDelete|ReadOnly
+ $& RegExpObjectImp::LastMatch DontDelete|ReadOnly|DontEnum
+ lastParen RegExpObjectImp::LastParen DontDelete|ReadOnly
+ $+ RegExpObjectImp::LastParen DontDelete|ReadOnly|DontEnum
+ leftContext RegExpObjectImp::LeftContext DontDelete|ReadOnly
+ $` RegExpObjectImp::LeftContext DontDelete|ReadOnly|DontEnum
+ rightContext RegExpObjectImp::RightContext DontDelete|ReadOnly
+ $' RegExpObjectImp::RightContext DontDelete|ReadOnly|DontEnum
+ $1 RegExpObjectImp::Dollar1 DontDelete|ReadOnly
+ $2 RegExpObjectImp::Dollar2 DontDelete|ReadOnly
+ $3 RegExpObjectImp::Dollar3 DontDelete|ReadOnly
+ $4 RegExpObjectImp::Dollar4 DontDelete|ReadOnly
+ $5 RegExpObjectImp::Dollar5 DontDelete|ReadOnly
+ $6 RegExpObjectImp::Dollar6 DontDelete|ReadOnly
+ $7 RegExpObjectImp::Dollar7 DontDelete|ReadOnly
+ $8 RegExpObjectImp::Dollar8 DontDelete|ReadOnly
+ $9 RegExpObjectImp::Dollar9 DontDelete|ReadOnly
+ at end
+*/
+
RegExpObjectImp::RegExpObjectImp(ExecState *exec,
FunctionPrototypeImp *funcProto,
RegExpPrototypeImp *regProto)
- : InternalFunctionImp(funcProto), lastOvector(0L), lastNrSubPatterns(0)
+ : InternalFunctionImp(funcProto), multiline(false), lastInput(""), lastOvector(0), lastNumSubPatterns(0)
{
// ECMA 15.10.5.1 RegExp.prototype
putDirect(prototypePropertyName, regProto, DontEnum|DontDelete|ReadOnly);
@@ -181,13 +207,32 @@
delete [] lastOvector;
}
-int **RegExpObjectImp::registerRegexp( const RegExp* re, const UString& s )
-{
- lastString = s;
- delete [] lastOvector;
- lastOvector = 0;
- lastNrSubPatterns = re->subPatterns();
- return &lastOvector;
+/*
+ To facilitate result caching, exec(), test(), match(), search(), and replace() dipatch regular
+ expression matching through the performMatch function. We use cached results to calculate,
+ e.g., RegExp.lastMatch and RegExp.leftParen.
+*/
+UString RegExpObjectImp::performMatch(RegExp* r, const UString& s, int startOffset, int *endOffset, int **ovector)
+{
+ int tmpOffset;
+ int *tmpOvector;
+ UString match = r->match(s, startOffset, &tmpOffset, &tmpOvector);
+
+ if (endOffset)
+ *endOffset = tmpOffset;
+ if (ovector)
+ *ovector = tmpOvector;
+
+ if (!match.isNull()) {
+ assert(tmpOvector);
+
+ lastInput = s;
+ delete [] lastOvector;
+ lastOvector = tmpOvector;
+ lastNumSubPatterns = r->subPatterns();
+ }
+
+ return match;
}
ObjectImp *RegExpObjectImp::arrayOfMatches(ExecState *exec, const UString &result) const
@@ -196,52 +241,139 @@
// The returned array contains 'result' as first item, followed by the list of matches
list.append(String(result));
if ( lastOvector )
- for ( unsigned i = 1 ; i < lastNrSubPatterns + 1 ; ++i )
+ for ( unsigned i = 1 ; i < lastNumSubPatterns + 1 ; ++i )
{
int start = lastOvector[2*i];
if (start == -1)
list.append(jsUndefined());
else {
- UString substring = lastString.substr( start, lastOvector[2*i+1] - start );
+ UString substring = lastInput.substr( start, lastOvector[2*i+1] - start );
list.append(String(substring));
}
}
ObjectImp *arr = exec->lexicalInterpreter()->builtinArray()->construct(exec, list);
arr->put(exec, "index", Number(lastOvector[0]));
- arr->put(exec, "input", String(lastString));
+ arr->put(exec, "input", String(lastInput));
return arr;
}
-ValueImp *RegExpObjectImp::backrefGetter(ExecState *exec, const Identifier& propertyName, const PropertySlot& slot)
+ValueImp *RegExpObjectImp::getBackref(unsigned i) const
{
- RegExpObjectImp *thisObj = static_cast<RegExpObjectImp *>(slot.slotBase());
- unsigned i = slot.index();
-
- if (i < thisObj->lastNrSubPatterns + 1) {
- int *lastOvector = thisObj->lastOvector;
- UString substring = thisObj->lastString.substr(lastOvector[2*i], lastOvector[2*i+1] - lastOvector[2*i] );
+ if (lastOvector && i < lastNumSubPatterns + 1) {
+ UString substring = lastInput.substr(lastOvector[2*i], lastOvector[2*i+1] - lastOvector[2*i] );
return String(substring);
}
return String("");
}
+ValueImp *RegExpObjectImp::getLastMatch() const
+{
+ if (lastOvector) {
+ UString substring = lastInput.substr(lastOvector[0], lastOvector[1] - lastOvector[0]);
+ return String(substring);
+ }
+
+ return String("");
+}
+
+ValueImp *RegExpObjectImp::getLastParen() const
+{
+ int i = lastNumSubPatterns;
+ if (i > 0) {
+ assert(lastOvector);
+ UString substring = lastInput.substr(lastOvector[2*i], lastOvector[2*i+1] - lastOvector[2*i]);
+ return String(substring);
+ }
+
+ return String("");
+}
+
+ValueImp *RegExpObjectImp::getLeftContext() const
+{
+ if (lastOvector) {
+ UString substring = lastInput.substr(0, lastOvector[0]);
+ return String(substring);
+ }
+
+ return String("");
+}
+
+ValueImp *RegExpObjectImp::getRightContext() const
+{
+ if (lastOvector) {
+ UString s = lastInput;
+ UString substring = s.substr(lastOvector[1], s.size() - lastOvector[1]);
+ return String(substring);
+ }
+
+ return String("");
+}
+
bool RegExpObjectImp::getOwnPropertySlot(ExecState *exec, const Identifier& propertyName, PropertySlot& slot)
{
- UString s = propertyName.ustring();
- if (s[0] == '$' && lastOvector)
- {
- bool ok;
- unsigned i = s.substr(1).toUInt32(&ok);
- if (ok) {
- slot.setCustomIndex(this, i, backrefGetter);
- return true;
- }
+ return getStaticValueSlot<RegExpObjectImp, InternalFunctionImp>(exec, &RegExpTable, this, propertyName, slot);
+}
+
+ValueImp *RegExpObjectImp::getValueProperty(ExecState *exec, int token) const
+{
+ switch (token) {
+ case Dollar1:
+ return getBackref(1);
+ case Dollar2:
+ return getBackref(2);
+ case Dollar3:
+ return getBackref(3);
+ case Dollar4:
+ return getBackref(4);
+ case Dollar5:
+ return getBackref(5);
+ case Dollar6:
+ return getBackref(6);
+ case Dollar7:
+ return getBackref(7);
+ case Dollar8:
+ return getBackref(8);
+ case Dollar9:
+ return getBackref(9);
+ case Input:
+ return jsString(lastInput);
+ case Multiline:
+ return jsBoolean(multiline);
+ case LastMatch:
+ return getLastMatch();
+ case LastParen:
+ return getLastParen();
+ case LeftContext:
+ return getLeftContext();
+ case RightContext:
+ return getRightContext();
+ default:
+ assert(0);
}
- return InternalFunctionImp::getOwnPropertySlot(exec, propertyName, slot);
+ return String("");
}
+void RegExpObjectImp::put(ExecState *exec, const Identifier &propertyName, ValueImp *value, int attr)
+{
+ lookupPut<RegExpObjectImp, InternalFunctionImp>(exec, propertyName, value, attr, &RegExpTable, this);
+}
+
+void RegExpObjectImp::putValueProperty(ExecState *exec, int token, ValueImp *value, int attr)
+{
+ switch (token) {
+ case Input:
+ lastInput = value->toString(exec);
+ break;
+ case Multiline:
+ multiline = value->toBoolean(exec);
+ break;
+ default:
+ assert(0);
+ }
+}
+
bool RegExpObjectImp::implementsConstruct() const
{
return true;
1.13 +21 -6 JavaScriptCore/kjs/regexp_object.h
Index: regexp_object.h
===================================================================
RCS file: /cvs/root/JavaScriptCore/kjs/regexp_object.h,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -r1.12 -r1.13
--- regexp_object.h 4 Sep 2005 01:18:13 -0000 1.12
+++ regexp_object.h 11 Oct 2005 20:43:49 -0000 1.13
@@ -65,6 +65,9 @@
class RegExpObjectImp : public InternalFunctionImp {
public:
+ enum { Dollar1, Dollar2, Dollar3, Dollar4, Dollar5, Dollar6, Dollar7, Dollar8, Dollar9,
+ Input, Multiline, LastMatch, LastParen, LeftContext, RightContext };
+
RegExpObjectImp(ExecState *exec,
FunctionPrototypeImp *funcProto,
RegExpPrototypeImp *regProto);
@@ -74,16 +77,28 @@
virtual bool implementsCall() const;
virtual ValueImp *callAsFunction(ExecState *exec, ObjectImp *thisObj, const List &args);
+ virtual void put(ExecState *, const Identifier &, ValueImp *, int attr = None);
+ void putValueProperty(ExecState *, int token, ValueImp *, int attr);
virtual bool getOwnPropertySlot(ExecState *, const Identifier&, PropertySlot&);
- int ** registerRegexp( const RegExp* re, const UString& s );
- void setSubPatterns(int num) { lastNrSubPatterns = num; }
+ ValueImp *getValueProperty(ExecState *, int token) const;
+ UString performMatch(RegExp *, const UString&, int startOffset = 0, int *endOffset = 0, int **ovector = 0);
ObjectImp *arrayOfMatches(ExecState *exec, const UString &result) const;
+
+ virtual const ClassInfo *classInfo() const { return &info; }
private:
- static ValueImp *backrefGetter(ExecState *exec, const Identifier&, const PropertySlot& slot);
-
- UString lastString;
+ ValueImp *getBackref(unsigned) const;
+ ValueImp *getLastMatch() const;
+ ValueImp *getLastParen() const;
+ ValueImp *getLeftContext() const;
+ ValueImp *getRightContext() const;
+
+ // Global search cache / settings
+ bool multiline;
+ UString lastInput;
int *lastOvector;
- unsigned lastNrSubPatterns;
+ unsigned lastNumSubPatterns;
+
+ static const ClassInfo info;
};
} // namespace
1.49 +14 -20 JavaScriptCore/kjs/string_object.cpp
Index: string_object.cpp
===================================================================
RCS file: /cvs/root/JavaScriptCore/kjs/string_object.cpp,v
retrieving revision 1.48
retrieving revision 1.49
diff -u -r1.48 -r1.49
--- string_object.cpp 6 Oct 2005 01:13:18 -0000 1.48
+++ string_object.cpp 11 Oct 2005 20:43:49 -0000 1.49
@@ -232,7 +232,7 @@
count++;
}
-static inline UString substituteBackreferences(const UString &replacement, const UString &source, int **ovector, RegExp *reg)
+static inline UString substituteBackreferences(const UString &replacement, const UString &source, int *ovector, RegExp *reg)
{
UString substitutedReplacement = replacement;
@@ -246,8 +246,8 @@
// Assume number part is one char exactly
unsigned backrefIndex = substitutedReplacement.substr(i+1,1).toUInt32(&converted, false /* tolerate empty string */);
if (converted && backrefIndex <= (unsigned)reg->subPatterns()) {
- int backrefStart = (*ovector)[2*backrefIndex];
- int backrefLength = (*ovector)[2*backrefIndex+1] - backrefStart;
+ int backrefStart = ovector[2*backrefIndex];
+ int backrefLength = ovector[2*backrefIndex+1] - backrefStart;
substitutedReplacement = substitutedReplacement.substr(0,i)
+ source.substr(backrefStart, backrefLength)
+ substitutedReplacement.substr(i+2);
@@ -288,9 +288,8 @@
// This is either a loop (if global is set) or a one-way (if not).
do {
- int **ovector = regExpObj->registerRegexp( reg, source );
- UString matchString = reg->match(source, startPosition, &matchIndex, ovector);
- regExpObj->setSubPatterns(reg->subPatterns());
+ int *ovector;
+ UString matchString = regExpObj->performMatch(reg, source, startPosition, &matchIndex, &ovector);
if (matchIndex == -1)
break;
int matchLen = matchString.size();
@@ -298,14 +297,14 @@
pushSourceRange(sourceRanges, sourceRangeCount, sourceRangeCapacity, UString::Range(lastIndex, matchIndex - lastIndex));
if (replacementFunction) {
- int completeMatchStart = (*ovector)[0];
+ int completeMatchStart = ovector[0];
List args;
args.append(jsString(matchString));
for (unsigned i = 0; i < reg->subPatterns(); i++) {
- int matchStart = (*ovector)[(i + 1) * 2];
- int matchLen = (*ovector)[(i + 1) * 2 + 1] - matchStart;
+ int matchStart = ovector[(i + 1) * 2];
+ int matchLen = ovector[(i + 1) * 2 + 1] - matchStart;
args.append(jsString(source.substr(matchStart, matchLen)));
}
@@ -454,13 +453,11 @@
u = s;
RegExp *reg, *tmpReg = 0;
RegExpImp *imp = 0;
- if (a0->isObject() && a0->getObject()->inherits(&RegExpImp::info))
- {
+ if (a0->isObject() && a0->getObject()->inherits(&RegExpImp::info)) {
imp = static_cast<RegExpImp *>(a0);
reg = imp->regExp();
- }
- else
- { /*
+ } else {
+ /*
* ECMA 15.5.4.12 String.prototype.search (regexp)
* If regexp is not an object whose [[Class]] property is "RegExp", it is
* replaced with the result of the expression new RegExp(regexp).
@@ -468,8 +465,7 @@
reg = tmpReg = new RegExp(a0->toString(exec), RegExp::None);
}
RegExpObjectImp* regExpObj = static_cast<RegExpObjectImp*>(exec->lexicalInterpreter()->builtinRegExp());
- int **ovector = regExpObj->registerRegexp(reg, u);
- UString mstr = reg->match(u, -1, &pos, ovector);
+ UString mstr = regExpObj->performMatch(reg, u, 0, &pos);
if (id == Search) {
result = Number(pos);
} else {
@@ -479,7 +475,6 @@
if (mstr.isNull()) {
result = Null();
} else {
- regExpObj->setSubPatterns(reg->subPatterns());
result = regExpObj->arrayOfMatches(exec,mstr);
}
} else {
@@ -493,8 +488,7 @@
list.append(String(mstr));
lastIndex = pos;
pos += mstr.isEmpty() ? 1 : mstr.size();
- delete [] *ovector;
- mstr = reg->match(u, pos, &pos, ovector);
+ mstr = regExpObj->performMatch(reg, u, pos, &pos);
}
if (imp)
imp->put(exec, "lastIndex", Number(lastIndex), DontDelete|DontEnum);
@@ -514,7 +508,7 @@
case Replace:
result = replace(exec, s, a0, a1);
break;
- case Slice: // http://developer.netscape.com/docs/manuals/js/client/jsref/string.htm#1194366
+ case Slice:
{
// The arg processing is very much like ArrayProtoFunc::Slice
double begin = args[0]->toInteger(exec);
More information about the webkit-changes
mailing list