From 844fdc31f32fca3c1c4bdbd1fc968194ae1e144c Mon Sep 17 00:00:00 2001 From: "rogerl%netscape.com" Date: Thu, 22 May 2003 23:04:27 +0000 Subject: [PATCH] Forcing flat regexp for string.replace --- js2/src/js2metadata.h | 4 +++- js2/src/js2regexp.cpp | 12 ++++++++++-- js2/src/js2string.cpp | 21 ++++++++++++--------- js2/src/regexp/regexp.h | 2 +- js2/src/regexpwrapper.cpp | 14 +++++++++++--- 5 files changed, 37 insertions(+), 16 deletions(-) diff --git a/js2/src/js2metadata.h b/js2/src/js2metadata.h index 9bd2208d357b..985a8971792b 100644 --- a/js2/src/js2metadata.h +++ b/js2/src/js2metadata.h @@ -82,6 +82,7 @@ extern js2val TypeError_Constructor(JS2Metadata *meta, const js2val thisValue, j extern js2val UriError_Constructor(JS2Metadata *meta, const js2val thisValue, js2val *argv, uint32 argc); extern js2val String_Constructor(JS2Metadata *meta, const js2val thisValue, js2val *argv, uint32 argc); extern js2val RegExp_Constructor(JS2Metadata *meta, const js2val thisValue, js2val *argv, uint32 argc); +extern js2val RegExp_ConstructorOpt(JS2Metadata *meta, const js2val thisValue, js2val *argv, uint32 argc, bool flat); extern js2val RegExp_exec(JS2Metadata *meta, const js2val thisValue, js2val *argv, uint32 argc); extern js2val Boolean_Constructor(JS2Metadata *meta, const js2val thisValue, js2val *argv, uint32 argc); extern js2val Number_Constructor(JS2Metadata *meta, const js2val thisValue, js2val *argv, uint32 argc); @@ -1045,7 +1046,8 @@ class SpiderMonkeyInstance : public SimpleInstance { public: SpiderMonkeyInstance(JS2Metadata *meta, js2val parent, JS2Class *type) : SimpleInstance(meta, parent, type) { } - void *uData; + void *jsObject; + void *pluginInstance; virtual ~SpiderMonkeyInstance() { } }; diff --git a/js2/src/js2regexp.cpp b/js2/src/js2regexp.cpp index b78f00d1828e..41c76ae0f70a 100644 --- a/js2/src/js2regexp.cpp +++ b/js2/src/js2regexp.cpp @@ -292,7 +292,7 @@ namespace MetaData { const String *flagStr = meta->engine->Empty_StringAtom; DEFINE_ROOTKEEPER(rk2, flagStr); if (argc > 0) { - if (JS2VAL_IS_OBJECT(argv[0]) + if (JS2VAL_IS_OBJECT(argv[0]) && !JS2VAL_IS_NULL(argv[0]) && (JS2VAL_TO_OBJECT(argv[0])->kind == SimpleInstanceKind) && (checked_cast(JS2VAL_TO_OBJECT(argv[0]))->type == meta->regexpClass)) { if ((argc == 1) || JS2VAL_IS_UNDEFINED(argv[1])) { @@ -313,7 +313,7 @@ namespace MetaData { meta->reportError(Exception::syntaxError, "Failed to parse RegExp : '{0}'", meta->engine->errorPos(), *regexpStr + "/" + *flagStr); // XXX error message? } } - JS2RegExp *re = RECompile(meta, regexpStr->begin(), (int32)regexpStr->length(), flags); + JS2RegExp *re = RECompile(meta, regexpStr->begin(), (int32)regexpStr->length(), flags, false); if (re) { thisInst->mRegExp = re; // XXX ECMA spec says these are DONTENUM @@ -328,6 +328,14 @@ namespace MetaData { return thisValue; } + js2val RegExp_ConstructorOpt(JS2Metadata *meta, const js2val /* thisValue */, js2val *argv, uint32 argc, bool flat) + { + RegExpInstance *thisInst = new RegExpInstance(meta, meta->regexpClass->prototype, meta->regexpClass); + DEFINE_ROOTKEEPER(rk, thisInst); + js2val thatValue = OBJECT_TO_JS2VAL(thisInst); + return RegExp_compile(meta, thatValue, argv, argc); + } + js2val RegExp_Constructor(JS2Metadata *meta, const js2val /* thisValue */, js2val *argv, uint32 argc) { RegExpInstance *thisInst = new RegExpInstance(meta, meta->regexpClass->prototype, meta->regexpClass); diff --git a/js2/src/js2string.cpp b/js2/src/js2string.cpp index f3a8bccddc0a..236d42b07fe0 100644 --- a/js2/src/js2string.cpp +++ b/js2/src/js2string.cpp @@ -283,19 +283,22 @@ static js2val String_replace(JS2Metadata *meta, const js2val thisValue, js2val * js2val searchValue = JS2VAL_UNDEFINED; js2val replaceValue = JS2VAL_UNDEFINED; - if (argc > 0) searchValue = argv[0]; + if (argc > 0) { + searchValue = argv[0]; + if (meta->objectType(searchValue) != meta->regexpClass) { + js2val regexp = JS2VAL_NULL; + js2val reArgs[2]; + reArgs[0] = searchValue; + reArgs[1] = (argc > 2) ? argv[2] : JS2VAL_UNDEFINED; + regexp = RegExp_ConstructorOpt(meta, regexp, reArgs, 2, true); + searchValue = regexp; + } + } + if (argc > 1) replaceValue = argv[1]; const String *replaceStr = meta->toString(replaceValue); DEFINE_ROOTKEEPER(rk2, replaceStr); - if (meta->objectType(searchValue) != meta->regexpClass) { - js2val regexp = JS2VAL_NULL; - js2val reArgs[2]; - reArgs[0] = argv[0]; - reArgs[1] = (argc > 2) ? argv[2] : JS2VAL_UNDEFINED; - regexp = RegExp_Constructor(meta, regexp, reArgs, 2); - searchValue = regexp; - } RegExpInstance *reInst = checked_cast(JS2VAL_TO_OBJECT(searchValue)); JS2RegExp *re = reInst->mRegExp; diff --git a/js2/src/regexp/regexp.h b/js2/src/regexp/regexp.h index f3fc411c25a9..08a41c96f2c4 100644 --- a/js2/src/regexp/regexp.h +++ b/js2/src/regexp/regexp.h @@ -96,7 +96,7 @@ class JS2Metadata; REMatchResult *REExecute(JS2Metadata *meta, JS2RegExp *re, const jschar *str, uint32 index, uint32 length, bool globalMultiline); // Compile the source re, return NULL for failure (error functions called) -JS2RegExp *RECompile(JS2Metadata *meta, const jschar *str, uint32 length, uint32 flags); +JS2RegExp *RECompile(JS2Metadata *meta, const jschar *str, uint32 length, uint32 flags, bool flat); // Compile the flag source and build a flag bit set. Return true/false for success/failure bool parseFlags(JS2Metadata *meta, const jschar *flagStr, uint32 length, uint32 *flags); diff --git a/js2/src/regexpwrapper.cpp b/js2/src/regexpwrapper.cpp index 9c1dfe1d061d..96f8fe7b0fea 100644 --- a/js2/src/regexpwrapper.cpp +++ b/js2/src/regexpwrapper.cpp @@ -2887,7 +2887,7 @@ bool parseFlags(JS2Metadata *meta, const jschar *flagStr, uint32 length, uint32 #define JS_ROUNDUP(x,y) (JS_HOWMANY(x,y)*(y)) // Compile the source re, return NULL for failure (error functions called) -JS2RegExp *RECompile(JS2Metadata *meta, const jschar *str, uint32 length, uint32 flags) +JS2RegExp *RECompile(JS2Metadata *meta, const jschar *str, uint32 length, uint32 flags, bool flat) { JS2RegExp *re; CompilerState state; @@ -2911,8 +2911,16 @@ JS2RegExp *RECompile(JS2Metadata *meta, const jschar *str, uint32 length, uint32 state.classCache[i].start = NULL; len = length; - if (!parseRegExp(&state)) - goto out; + if (len != 0 && flat) { + state.result = NewRENode(&state, REOP_FLAT); + state.result->u.flat.chr = *state.cpbegin; + state.result->u.flat.length = length; + state.result->kid = (void *)(state.cpbegin); + state.progLength += 5; + } + else + if (!parseRegExp(&state)) + goto out; resize = sizeof *re + state.progLength + 1; re = (JS2RegExp *) malloc(JS_ROUNDUP(resize, sizeof(uint32)));