Bug 623435: Rip out deprecated RegExp.compile. (r=brendan)

This commit is contained in:
Chris Leary 2011-01-25 14:32:53 -08:00
parent 2f7dae01d9
commit 07bf6c5ab7
4 changed files with 74 additions and 94 deletions

View File

@ -122,6 +122,8 @@ SwapObjectRegExp(JSContext *cx, JSObject *obj, AlreadyIncRefed<RegExp> newRegExp
{
RegExp *oldRegExp = RegExp::extractFrom(obj);
#ifdef DEBUG
if (oldRegExp)
assertSameCompartment(cx, obj, oldRegExp->compartment);
assertSameCompartment(cx, obj, newRegExp->compartment);
#endif
@ -218,8 +220,8 @@ RegExp::handleYarrError(JSContext *cx, int error)
void
RegExp::handlePCREError(JSContext *cx, int error)
{
#define REPORT(__msg) \
JS_ReportErrorFlagsAndNumberUC(cx, JSREPORT_ERROR, js_GetErrorMessage, NULL, __msg); \
#define REPORT(msg_) \
JS_ReportErrorFlagsAndNumberUC(cx, JSREPORT_ERROR, js_GetErrorMessage, NULL, msg_); \
return
switch (error) {
case 0: JS_NOT_REACHED("Precondition violation: an error must have occurred.");
@ -247,20 +249,20 @@ RegExp::handlePCREError(JSContext *cx, int error)
}
bool
RegExp::parseFlags(JSContext *cx, JSString *flagStr, uint32 &flagsOut)
RegExp::parseFlags(JSContext *cx, JSString *flagStr, uintN *flagsOut)
{
size_t n = flagStr->length();
const jschar *s = flagStr->getChars(cx);
if (!s)
return false;
flagsOut = 0;
*flagsOut = 0;
for (size_t i = 0; i < n; i++) {
#define HANDLE_FLAG(__name) \
JS_BEGIN_MACRO \
if (flagsOut & (__name)) \
goto bad_flag; \
flagsOut |= (__name); \
#define HANDLE_FLAG(name_) \
JS_BEGIN_MACRO \
if (*flagsOut & (name_)) \
goto bad_flag; \
*flagsOut |= (name_); \
JS_END_MACRO
switch (s[i]) {
case 'i': HANDLE_FLAG(JSREG_FOLD); break;
@ -288,8 +290,8 @@ RegExp::createFlagged(JSContext *cx, JSString *str, JSString *opt)
{
if (!opt)
return create(cx, str, 0);
uint32 flags = 0;
if (!parseFlags(cx, opt, flags))
uintN flags = 0;
if (!parseFlags(cx, opt, &flags))
return AlreadyIncRefed<RegExp>(NULL);
return create(cx, str, flags);
}
@ -664,7 +666,7 @@ EscapeNakedForwardSlashes(JSContext *cx, JSString *unescaped)
}
static bool
regexp_compile_sub_tail(JSContext *cx, JSObject *obj, Value *rval, JSString *str, uint32 flags = 0)
SwapRegExpInternals(JSContext *cx, JSObject *obj, Value *rval, JSString *str, uint32 flags = 0)
{
flags |= cx->regExpStatics()->getFlags();
AlreadyIncRefed<RegExp> re = RegExp::create(cx, str, flags);
@ -675,70 +677,6 @@ regexp_compile_sub_tail(JSContext *cx, JSObject *obj, Value *rval, JSString *str
return true;
}
static JSBool
regexp_compile_sub(JSContext *cx, JSObject *obj, uintN argc, Value *argv, Value *rval)
{
if (!InstanceOf(cx, obj, &js_RegExpClass, argv))
return false;
if (argc == 0)
return regexp_compile_sub_tail(cx, obj, rval, cx->runtime->emptyString);
Value sourceValue = argv[0];
if (sourceValue.isObject() && sourceValue.toObject().getClass() == &js_RegExpClass) {
/*
* If we get passed in a RegExp object we construct a new
* RegExp that is a duplicate of it by re-compiling the
* original source code. ECMA requires that it be an error
* here if the flags are specified. (We must use the flags
* from the original RegExp also).
*/
JSObject &sourceObj = sourceValue.toObject();
if (argc >= 2 && !argv[1].isUndefined()) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_NEWREGEXP_FLAGGED);
return false;
}
RegExp *re = RegExp::extractFrom(&sourceObj);
if (!re)
return false;
AlreadyIncRefed<RegExp> clone = RegExp::clone(cx, *re);
if (!clone)
return false;
SwapObjectRegExp(cx, obj, clone);
*rval = ObjectValue(*obj);
return true;
}
/* Coerce to string and compile. */
JSString *sourceStr = js_ValueToString(cx, sourceValue);
if (!sourceStr)
return false;
argv[0] = StringValue(sourceStr);
uint32 flags = 0;
if (argc > 1 && !argv[1].isUndefined()) {
JSString *flagStr = js_ValueToString(cx, argv[1]);
if (!flagStr)
return false;
argv[1] = StringValue(flagStr);
if (!RegExp::parseFlags(cx, flagStr, flags))
return false;
}
JSString *escapedSourceStr = EscapeNakedForwardSlashes(cx, sourceStr);
if (!escapedSourceStr)
return false;
argv[0] = StringValue(escapedSourceStr);
return regexp_compile_sub_tail(cx, obj, rval, escapedSourceStr, flags);
}
static JSBool
regexp_compile(JSContext *cx, uintN argc, Value *vp)
{
JSObject *obj = JS_THIS_OBJECT(cx, Jsvalify(vp));
return obj && regexp_compile_sub(cx, obj, argc, vp + 2, vp);
}
static JSBool
regexp_exec_sub(JSContext *cx, JSObject *obj, uintN argc, Value *argv, JSBool test, Value *rval)
{
@ -838,7 +776,6 @@ static JSFunctionSpec regexp_methods[] = {
JS_FN(js_toSource_str, regexp_toString, 0,0),
#endif
JS_FN(js_toString_str, regexp_toString, 0,0),
JS_FN("compile", regexp_compile, 2,0),
JS_FN("exec", js_regexp_exec, 1,0),
JS_FN("test", js_regexp_test, 1,0),
JS_FS_END
@ -848,29 +785,79 @@ static JSBool
regexp_construct(JSContext *cx, uintN argc, Value *vp)
{
Value *argv = JS_ARGV(cx, vp);
Value *rval = &JS_RVAL(cx, vp);
if (!IsConstructing(vp)) {
/*
* If first arg is regexp and no flags are given, just return the arg.
* (regexp_compile_sub detects the regexp + flags case and throws a
* TypeError.) See 15.10.3.1.
* Otherwise, delegate to the standard constructor.
* See ECMAv5 15.10.3.1.
*/
if (argc >= 1 && argv[0].isObject() && argv[0].toObject().isRegExp() &&
(argc == 1 || argv[1].isUndefined()))
{
(argc == 1 || argv[1].isUndefined())) {
*vp = argv[0];
return true;
}
}
/* Otherwise, replace obj with a new RegExp object. */
/*
* Per ECMAv5 15.10.4.1, we act on combinations of (pattern, flags):
* RegExp, undefined => flags := pattern.flags
* RegExp, _ => throw TypeError
* _ => pattern := ToString(pattern) if defined(pattern) else ''
* flags := ToString(flags) if defined(flags) else ''
*/
JSObject *obj = NewBuiltinClassInstance(cx, &js_RegExpClass);
if (!obj)
return false;
return regexp_compile_sub(cx, obj, argc, argv, vp);
if (argc == 0)
return SwapRegExpInternals(cx, obj, rval, cx->runtime->emptyString);
Value sourceValue = argv[0];
if (sourceValue.isObject() && sourceValue.toObject().getClass() == &js_RegExpClass) {
/*
* If we get passed in a RegExp object we return a new object with the
* same RegExp (internal matcher program) guts.
* Note: the regexp static flags are not taken into consideration here.
*/
JSObject &sourceObj = sourceValue.toObject();
if (argc >= 2 && !argv[1].isUndefined()) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_NEWREGEXP_FLAGGED);
return false;
}
RegExp *re = RegExp::extractFrom(&sourceObj);
if (!re)
return false;
re->incref(cx);
SwapObjectRegExp(cx, obj, AlreadyIncRefed<RegExp>(re));
*rval = ObjectValue(*obj);
return true;
}
/* Coerce to string and compile. */
JSString *sourceStr = js_ValueToString(cx, sourceValue);
if (!sourceStr)
return false;
uintN flags = 0;
if (argc > 1 && !argv[1].isUndefined()) {
JSString *flagStr = js_ValueToString(cx, argv[1]);
if (!flagStr || !RegExp::parseFlags(cx, flagStr, &flags))
return false;
}
JSString *escapedSourceStr = EscapeNakedForwardSlashes(cx, sourceStr);
if (!escapedSourceStr)
return false;
return SwapRegExpInternals(cx, obj, rval, escapedSourceStr, flags);
}
/* Similar to regexp_compile_sub_tail. */
/* Similar to SwapRegExpInternals. */
static bool
InitRegExpClassCompile(JSContext *cx, JSObject *obj)
{

View File

@ -141,7 +141,7 @@ class RegExp
* Parse regexp flags. Report an error and return false if an invalid
* sequence of flags is encountered (repeat/invalid flag).
*/
static bool parseFlags(JSContext *cx, JSString *flagStr, uint32 &flagsOut);
static bool parseFlags(JSContext *cx, JSString *flagStr, uintN *flagsOut);
/*
* Execute regexp on |input| at |*lastIndex|.
@ -179,7 +179,6 @@ class RegExp
static JSObject *createObjectNoStatics(JSContext *cx, const jschar *chars, size_t length,
uint32 flags);
static RegExp *extractFrom(JSObject *obj);
static AlreadyIncRefed<RegExp> clone(JSContext *cx, const RegExp &other);
/* Mutators */
@ -576,12 +575,6 @@ RegExp::extractFrom(JSObject *obj)
return re;
}
inline AlreadyIncRefed<RegExp>
RegExp::clone(JSContext *cx, const RegExp &other)
{
return create(cx, other.source, other.flags);
}
/* RegExpStatics inlines. */
inline RegExpStatics *

View File

@ -8,7 +8,7 @@ script regress-220367-002.js
script regress-228087.js
script regress-274152.js
script regress-320854.js
script regress-327170.js
skip script regress-327170.js # RegExp.compile removed.
script regress-368516.js
script regress-385393-03.js
script regress-429248.js

View File

@ -20,7 +20,7 @@ script backslash.js
script backspace.js
script beginLine.js
script character_class.js
script compile.js
skip script compile.js # RegExp.compile removed.
script control_characters.js
script digit.js
script dot.js