Bug 630284: Restore |RegExp.compile|, don't break the web. (r=brendan, a=sayrer)

This commit is contained in:
Chris Leary 2011-02-01 15:07:31 -08:00
parent 90e40ea45f
commit 403f8bb077
3 changed files with 61 additions and 42 deletions

View File

@ -779,47 +779,20 @@ js_regexp_test(JSContext *cx, uintN argc, Value *vp)
return true;
}
static JSFunctionSpec regexp_methods[] = {
#if JS_HAS_TOSOURCE
JS_FN(js_toSource_str, regexp_toString, 0,0),
#endif
JS_FN(js_toString_str, regexp_toString, 0,0),
JS_FN("exec", js_regexp_exec, 1,0),
JS_FN("test", js_regexp_test, 1,0),
JS_FS_END
};
static JSBool
regexp_construct(JSContext *cx, uintN argc, Value *vp)
/*
* Compile new js::RegExp guts for obj.
*
* Per ECMAv5 15.10.4.1, we act on combinations of (pattern, flags) as
* arguments:
*
* RegExp, undefined => flags := pattern.flags
* RegExp, _ => throw TypeError
* _ => pattern := ToString(pattern) if defined(pattern) else ''
* flags := ToString(flags) if defined(flags) else ''
*/
static bool
CompileRegExpAndSwap(JSContext *cx, JSObject *obj, uintN argc, Value *argv, Value *rval)
{
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.
* 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())) {
*vp = argv[0];
return true;
}
}
/*
* 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;
if (argc == 0)
return SwapRegExpInternals(cx, obj, rval, cx->runtime->emptyString);
@ -868,6 +841,52 @@ regexp_construct(JSContext *cx, uintN argc, Value *vp)
return SwapRegExpInternals(cx, obj, rval, escapedSourceStr, flags);
}
static JSBool
regexp_compile(JSContext *cx, uintN argc, Value *vp)
{
JSObject *obj = ToObject(cx, &vp[1]);
if (!obj || !InstanceOf(cx, obj, &js_RegExpClass, JS_ARGV(cx, vp)))
return false;
return CompileRegExpAndSwap(cx, obj, argc, JS_ARGV(cx, vp), &JS_RVAL(cx, vp));
}
static JSBool
regexp_construct(JSContext *cx, uintN argc, Value *vp)
{
Value *argv = JS_ARGV(cx, vp);
if (!IsConstructing(vp)) {
/*
* If first arg is regexp and no flags are given, just return the arg.
* 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())) {
*vp = argv[0];
return true;
}
}
JSObject *obj = NewBuiltinClassInstance(cx, &js_RegExpClass);
if (!obj)
return false;
return CompileRegExpAndSwap(cx, obj, argc, argv, &JS_RVAL(cx, vp));
}
static JSFunctionSpec regexp_methods[] = {
#if JS_HAS_TOSOURCE
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
};
/* Similar to SwapRegExpInternals. */
static bool
InitRegExpClassCompile(JSContext *cx, JSObject *obj)

View File

@ -8,7 +8,7 @@ script regress-220367-002.js
script regress-228087.js
script regress-274152.js
script regress-320854.js
skip script regress-327170.js # RegExp.compile removed.
script regress-327170.js
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
skip script compile.js # RegExp.compile removed.
script compile.js
script control_characters.js
script digit.js
script dot.js