Bug 453564 - TM: Assertion failure: JSVAL_IS_NULL(vp[0]) || (!JSVAL_IS_PRIMITIVE(vp[0]) && OBJ_IS_ARRAY(cx, JSVAL_TO_OBJECT(vp[0]))). r=gal.

--HG--
extra : rebase_source : be08d1a4ca8a3765523b992a5d4e469e67ba8811
This commit is contained in:
Jason Orendorff 2008-12-09 11:43:32 -06:00
parent 903336fe43
commit 413e752410
3 changed files with 33 additions and 15 deletions

View File

@ -1343,6 +1343,8 @@ match_or_replace(JSContext *cx,
destroy(cx, data);
}
} else {
jsval savedObject = JSVAL_NULL;
if (GET_MODE(data->flags) == MODE_REPLACE) {
test = JS_TRUE;
} else {
@ -1350,7 +1352,10 @@ match_or_replace(JSContext *cx,
* MODE_MATCH implies str_match is being called from a script or a
* scripted function. If the caller cares only about testing null
* vs. non-null return value, optimize away the array object that
* would normally be returned in *vp.
* would normally be returned in *vp. Instead return an arbitrary
* object (not JSVAL_TRUE, for type map integrity; see bug 453564).
* The caller provides the object in *vp and is responsible for
* rooting it elsewhere.
*
* Assume a full array result is required, then prove otherwise.
*/
@ -1364,12 +1369,16 @@ match_or_replace(JSContext *cx,
case JSOP_IFEQX:
case JSOP_IFNEX:
test = JS_TRUE;
savedObject = *vp;
JS_ASSERT(!JSVAL_IS_PRIMITIVE(savedObject));
break;
default:;
}
}
}
ok = js_ExecuteRegExp(cx, re, str, &index, test, vp);
if (ok && !JSVAL_IS_NULL(savedObject) && *vp == JSVAL_TRUE)
*vp = savedObject;
}
DROP_REGEXP(cx, re);
@ -1418,8 +1427,8 @@ match_glob(JSContext *cx, jsint count, GlobData *data)
return OBJ_SET_PROPERTY(cx, arrayobj, INT_TO_JSID(count), &v);
}
JSBool
js_StringMatchHelper(JSContext *cx, uintN argc, jsval *vp, jsbytecode *pc)
static JSBool
StringMatchHelper(JSContext *cx, uintN argc, jsval *vp, jsbytecode *pc)
{
JSTempValueRooter tvr;
MatchData mdata;
@ -1444,29 +1453,32 @@ str_match(JSContext *cx, uintN argc, jsval *vp)
for (fp = js_GetTopStackFrame(cx); fp && !fp->regs; fp = fp->down)
JS_ASSERT(!fp->script);
return js_StringMatchHelper(cx, argc, vp, fp ? fp->regs->pc : NULL);
/* Root the object in vp[0]. See comment in match_or_replace. */
JSAutoTempValueRooter tvr(cx, vp[0]);
return StringMatchHelper(cx, argc, vp, fp ? fp->regs->pc : NULL);
}
#ifdef JS_TRACER
static JSObject* FASTCALL
String_p_match(JSContext* cx, JSString* str, jsbytecode *pc, JSObject* regexp)
{
jsval vp[3] = { JSVAL_NULL, STRING_TO_JSVAL(str), OBJECT_TO_JSVAL(regexp) };
if (!js_StringMatchHelper(cx, 1, vp, pc))
/* arbitrary object in vp[0] */
jsval vp[3] = { OBJECT_TO_JSVAL(regexp), STRING_TO_JSVAL(str), OBJECT_TO_JSVAL(regexp) };
if (!StringMatchHelper(cx, 1, vp, pc))
return (JSObject*) JSVAL_TO_BOOLEAN(JSVAL_VOID);
JS_ASSERT(JSVAL_IS_NULL(vp[0]) ||
(!JSVAL_IS_PRIMITIVE(vp[0]) && OBJ_IS_ARRAY(cx, JSVAL_TO_OBJECT(vp[0]))));
JS_ASSERT(JSVAL_IS_OBJECT(vp[0]));
return JSVAL_TO_OBJECT(vp[0]);
}
static JSObject* FASTCALL
String_p_match_obj(JSContext* cx, JSObject* str, jsbytecode *pc, JSObject* regexp)
{
jsval vp[3] = { JSVAL_NULL, OBJECT_TO_JSVAL(str), OBJECT_TO_JSVAL(regexp) };
if (!js_StringMatchHelper(cx, 1, vp, pc))
/* arbitrary object in vp[0] */
jsval vp[3] = { OBJECT_TO_JSVAL(regexp), OBJECT_TO_JSVAL(str), OBJECT_TO_JSVAL(regexp) };
if (!StringMatchHelper(cx, 1, vp, pc))
return (JSObject*) JSVAL_TO_BOOLEAN(JSVAL_VOID);
JS_ASSERT(JSVAL_IS_NULL(vp[0]) ||
(!JSVAL_IS_PRIMITIVE(vp[0]) && OBJ_IS_ARRAY(cx, JSVAL_TO_OBJECT(vp[0]))));
JS_ASSERT(JSVAL_IS_OBJECT(vp[0]));
return JSVAL_TO_OBJECT(vp[0]);
}
#endif

View File

@ -617,9 +617,6 @@ extern JSBool
js_str_escape(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
jsval *rval);
extern JSBool
js_StringMatchHelper(JSContext *cx, uintN argc, jsval *vp, jsbytecode *pc);
extern JSBool
js_StringReplaceHelper(JSContext *cx, uintN argc, JSObject *lambda,
JSString *repstr, jsval *vp);

View File

@ -887,6 +887,15 @@ function matchInLoop() {
matchInLoop.expected = true;
test(matchInLoop);
function testMatchAsCondition() {
var a = ['0', '0', '0', '0'];
var r = /0/;
"x".q;
for (var z = 0; z < 4; z++)
a[z].match(r) ? 1 : 2;
}
test(testMatchAsCondition);
function deep1(x) {
if (x > 90)
return 1;