bug 517749 - removal of weakRoots.newborn = null. r=mrbkap

This commit is contained in:
Igor Bukanov 2009-09-25 16:30:11 +04:00
parent 5025d78459
commit f6f7e598b9
10 changed files with 111 additions and 224 deletions

View File

@ -572,61 +572,51 @@ JS_ValueToSource(JSContext *cx, jsval v)
JS_PUBLIC_API(JSBool)
JS_ValueToNumber(JSContext *cx, jsval v, jsdouble *dp)
{
JSTempValueRooter tvr;
CHECK_REQUEST(cx);
JS_PUSH_SINGLE_TEMP_ROOT(cx, v, &tvr);
*dp = js_ValueToNumber(cx, &tvr.u.value);
JS_POP_TEMP_ROOT(cx, &tvr);
return !JSVAL_IS_NULL(tvr.u.value);
JSAutoTempValueRooter tvr(cx, v);
*dp = js_ValueToNumber(cx, tvr.addr());
return !JSVAL_IS_NULL(tvr.value());
}
JS_PUBLIC_API(JSBool)
JS_ValueToECMAInt32(JSContext *cx, jsval v, int32 *ip)
{
JSTempValueRooter tvr;
CHECK_REQUEST(cx);
JS_PUSH_SINGLE_TEMP_ROOT(cx, v, &tvr);
*ip = js_ValueToECMAInt32(cx, &tvr.u.value);
JS_POP_TEMP_ROOT(cx, &tvr);
return !JSVAL_IS_NULL(tvr.u.value);
JSAutoTempValueRooter tvr(cx, v);
*ip = js_ValueToECMAInt32(cx, tvr.addr());
return !JSVAL_IS_NULL(tvr.value());
}
JS_PUBLIC_API(JSBool)
JS_ValueToECMAUint32(JSContext *cx, jsval v, uint32 *ip)
{
JSTempValueRooter tvr;
CHECK_REQUEST(cx);
JS_PUSH_SINGLE_TEMP_ROOT(cx, v, &tvr);
*ip = js_ValueToECMAUint32(cx, &tvr.u.value);
JS_POP_TEMP_ROOT(cx, &tvr);
return !JSVAL_IS_NULL(tvr.u.value);
JSAutoTempValueRooter tvr(cx, v);
*ip = js_ValueToECMAUint32(cx, tvr.addr());
return !JSVAL_IS_NULL(tvr.value());
}
JS_PUBLIC_API(JSBool)
JS_ValueToInt32(JSContext *cx, jsval v, int32 *ip)
{
JSTempValueRooter tvr;
CHECK_REQUEST(cx);
JS_PUSH_SINGLE_TEMP_ROOT(cx, v, &tvr);
*ip = js_ValueToInt32(cx, &tvr.u.value);
JS_POP_TEMP_ROOT(cx, &tvr);
return !JSVAL_IS_NULL(tvr.u.value);
JSAutoTempValueRooter tvr(cx, v);
*ip = js_ValueToInt32(cx, tvr.addr());
return !JSVAL_IS_NULL(tvr.value());
}
JS_PUBLIC_API(JSBool)
JS_ValueToUint16(JSContext *cx, jsval v, uint16 *ip)
{
JSTempValueRooter tvr;
CHECK_REQUEST(cx);
JS_PUSH_SINGLE_TEMP_ROOT(cx, v, &tvr);
*ip = js_ValueToUint16(cx, &tvr.u.value);
JS_POP_TEMP_ROOT(cx, &tvr);
return !JSVAL_IS_NULL(tvr.u.value);
JSAutoTempValueRooter tvr(cx, v);
*ip = js_ValueToUint16(cx, tvr.addr());
return !JSVAL_IS_NULL(tvr.value());
}
JS_PUBLIC_API(JSBool)
@ -3042,7 +3032,6 @@ JS_DefineObject(JSContext *cx, JSObject *obj, const char *name, JSClass *clasp,
return NULL;
if (!DefineProperty(cx, obj, name, OBJECT_TO_JSVAL(nobj), NULL, NULL, attrs,
0, 0)) {
cx->weakRoots.newborn[GCX_OBJECT] = NULL;
return NULL;
}
return nobj;

View File

@ -555,22 +555,16 @@ js_SetLengthProperty(JSContext *cx, JSObject *obj, jsdouble length)
JSBool
js_HasLengthProperty(JSContext *cx, JSObject *obj, jsuint *lengthp)
{
JSErrorReporter older;
JSTempValueRooter tvr;
jsid id;
JSBool ok;
older = JS_SetErrorReporter(cx, NULL);
JS_PUSH_SINGLE_TEMP_ROOT(cx, JSVAL_NULL, &tvr);
id = ATOM_TO_JSID(cx->runtime->atomState.lengthAtom);
ok = obj->getProperty(cx, id, &tvr.u.value);
JSErrorReporter older = JS_SetErrorReporter(cx, NULL);
JSAutoTempValueRooter tvr(cx, JSVAL_NULL);
jsid id = ATOM_TO_JSID(cx->runtime->atomState.lengthAtom);
JSBool ok = obj->getProperty(cx, id, tvr.addr());
JS_SetErrorReporter(cx, older);
if (ok) {
*lengthp = ValueIsLength(cx, &tvr.u.value);
ok = !JSVAL_IS_NULL(tvr.u.value);
}
JS_POP_TEMP_ROOT(cx, &tvr);
return ok;
if (!ok)
return false;
*lengthp = ValueIsLength(cx, tvr.addr());
return !JSVAL_IS_NULL(tvr.value());
}
JSBool
@ -1809,12 +1803,8 @@ array_join(JSContext *cx, uintN argc, jsval *vp)
static JSBool
array_reverse(JSContext *cx, uintN argc, jsval *vp)
{
JSObject *obj;
JSTempValueRooter tvr;
jsuint len, half, i;
JSBool ok, hole, hole2;
obj = JS_THIS_OBJECT(cx, vp);
jsuint len;
JSObject *obj = JS_THIS_OBJECT(cx, vp);
if (!obj || !js_GetLengthProperty(cx, obj, &len))
return JS_FALSE;
*vp = OBJECT_TO_JSVAL(obj);
@ -1852,22 +1842,19 @@ array_reverse(JSContext *cx, uintN argc, jsval *vp)
return JS_TRUE;
}
ok = JS_TRUE;
JS_PUSH_SINGLE_TEMP_ROOT(cx, JSVAL_NULL, &tvr);
half = len / 2;
for (i = 0; i < half; i++) {
ok = JS_CHECK_OPERATION_LIMIT(cx) &&
GetArrayElement(cx, obj, i, &hole, &tvr.u.value) &&
GetArrayElement(cx, obj, len - i - 1, &hole2, vp) &&
SetOrDeleteArrayElement(cx, obj, len - i - 1, hole, tvr.u.value) &&
SetOrDeleteArrayElement(cx, obj, i, hole2, *vp);
if (!ok)
break;
JSAutoTempValueRooter tvr(cx, JSVAL_NULL);
for (jsuint i = 0, half = len / 2; i < half; i++) {
JSBool hole, hole2;
if (!JS_CHECK_OPERATION_LIMIT(cx) ||
!GetArrayElement(cx, obj, i, &hole, tvr.addr()) ||
!GetArrayElement(cx, obj, len - i - 1, &hole2, vp) ||
!SetOrDeleteArrayElement(cx, obj, len - i - 1, hole, tvr.value()) ||
!SetOrDeleteArrayElement(cx, obj, i, hole2, *vp)) {
return false;
}
}
JS_POP_TEMP_ROOT(cx, &tvr);
*vp = OBJECT_TO_JSVAL(obj);
return ok;
return true;
}
typedef struct MSortArgs {
@ -2810,8 +2797,7 @@ array_concat(JSContext *cx, uintN argc, jsval *vp)
JSObject *aobj, *nobj;
jsuint length, alength, slot;
uintN i;
JSBool hole, ok;
JSTempValueRooter tvr;
JSBool hole;
/* Treat our |this| object as the first argument; see ECMA 15.4.4.4. */
argv = JS_ARGV(cx, vp) - 1;
@ -2849,14 +2835,12 @@ array_concat(JSContext *cx, uintN argc, jsval *vp)
length = 0;
}
MUST_FLOW_THROUGH("out");
JS_PUSH_SINGLE_TEMP_ROOT(cx, JSVAL_NULL, &tvr);
JSAutoTempValueRooter tvr(cx, JSVAL_NULL);
/* Loop over [0, argc] to concat args into nobj, expanding all Arrays. */
for (i = 0; i <= argc; i++) {
ok = JS_CHECK_OPERATION_LIMIT(cx);
if (!ok)
goto out;
if (!JS_CHECK_OPERATION_LIMIT(cx))
return false;
v = argv[i];
if (!JSVAL_IS_PRIMITIVE(v)) {
JSObject *wobj;
@ -2864,30 +2848,25 @@ array_concat(JSContext *cx, uintN argc, jsval *vp)
aobj = JSVAL_TO_OBJECT(v);
wobj = js_GetWrappedObject(cx, aobj);
if (OBJ_IS_ARRAY(cx, wobj)) {
ok = aobj->getProperty(cx, ATOM_TO_JSID(cx->runtime->atomState.lengthAtom),
&tvr.u.value);
if (!ok)
goto out;
alength = ValueIsLength(cx, &tvr.u.value);
ok = !JSVAL_IS_NULL(tvr.u.value);
if (!ok)
goto out;
jsid id = ATOM_TO_JSID(cx->runtime->atomState.lengthAtom);
if (!aobj->getProperty(cx, id, tvr.addr()))
return false;
alength = ValueIsLength(cx, tvr.addr());
if (JSVAL_IS_NULL(tvr.value()))
return false;
for (slot = 0; slot < alength; slot++) {
ok = JS_CHECK_OPERATION_LIMIT(cx) &&
GetArrayElement(cx, aobj, slot, &hole,
&tvr.u.value);
if (!ok)
goto out;
if (!JS_CHECK_OPERATION_LIMIT(cx) ||
!GetArrayElement(cx, aobj, slot, &hole, tvr.addr())) {
return false;
}
/*
* Per ECMA 262, 15.4.4.4, step 9, ignore non-existent
* properties.
*/
if (!hole) {
ok = SetArrayElement(cx, nobj, length + slot,
tvr.u.value);
if (!ok)
goto out;
if (!hole &&
!SetArrayElement(cx, nobj, length+slot, tvr.value())) {
return false;
}
}
length += alength;
@ -2895,17 +2874,12 @@ array_concat(JSContext *cx, uintN argc, jsval *vp)
}
}
ok = SetArrayElement(cx, nobj, length, v);
if (!ok)
goto out;
if (!SetArrayElement(cx, nobj, length, v))
return false;
length++;
}
ok = js_SetLengthProperty(cx, nobj, length);
out:
JS_POP_TEMP_ROOT(cx, &tvr);
return ok;
return js_SetLengthProperty(cx, nobj, length);
}
static JSBool

View File

@ -2342,20 +2342,16 @@ js_InitFunctionClass(JSContext *cx, JSObject *obj)
return NULL;
fun = js_NewFunction(cx, proto, NULL, 0, JSFUN_INTERPRETED, obj, NULL);
if (!fun)
goto bad;
return NULL;
fun->u.i.script = js_NewScript(cx, 1, 1, 0, 0, 0, 0, 0);
if (!fun->u.i.script)
goto bad;
return NULL;
fun->u.i.script->code[0] = JSOP_STOP;
*fun->u.i.script->notes() = SRC_NULL;
#ifdef CHECK_SCRIPT_OWNER
fun->u.i.script->owner = NULL;
#endif
return proto;
bad:
cx->weakRoots.newborn[GCX_OBJECT] = NULL;
return NULL;
}
JSFunction *

View File

@ -997,49 +997,35 @@ JSClass js_NoSuchMethodClass = {
JS_STATIC_INTERPRET JSBool
js_OnUnknownMethod(JSContext *cx, jsval *vp)
{
JSObject *obj;
jsid id;
JSTempValueRooter tvr;
JSBool ok;
JS_ASSERT(!JSVAL_IS_PRIMITIVE(vp[1]));
obj = JSVAL_TO_OBJECT(vp[1]);
JS_PUSH_SINGLE_TEMP_ROOT(cx, JSVAL_NULL, &tvr);
MUST_FLOW_THROUGH("out");
id = ATOM_TO_JSID(cx->runtime->atomState.noSuchMethodAtom);
ok = js_GetMethod(cx, obj, id, JSGET_NO_METHOD_BARRIER, &tvr.u.value);
if (!ok)
goto out;
if (JSVAL_IS_PRIMITIVE(tvr.u.value)) {
vp[0] = tvr.u.value;
JSObject *obj = JSVAL_TO_OBJECT(vp[1]);
jsid id = ATOM_TO_JSID(cx->runtime->atomState.noSuchMethodAtom);
JSAutoTempValueRooter tvr(cx, JSVAL_NULL);
if (!js_GetMethod(cx, obj, id, JSGET_NO_METHOD_BARRIER, tvr.addr()))
return false;
if (JSVAL_IS_PRIMITIVE(tvr.value())) {
vp[0] = tvr.value();
} else {
#if JS_HAS_XML_SUPPORT
/* Extract the function name from function::name qname. */
if (!JSVAL_IS_PRIMITIVE(vp[0])) {
obj = JSVAL_TO_OBJECT(vp[0]);
ok = js_IsFunctionQName(cx, obj, &id);
if (!ok)
goto out;
if (!js_IsFunctionQName(cx, obj, &id))
return false;
if (id != 0)
vp[0] = ID_TO_VALUE(id);
}
#endif
obj = js_NewObjectWithGivenProto(cx, &js_NoSuchMethodClass,
NULL, NULL);
if (!obj) {
ok = JS_FALSE;
goto out;
}
obj->fslots[JSSLOT_FOUND_FUNCTION] = tvr.u.value;
if (!obj)
return false;
obj->fslots[JSSLOT_FOUND_FUNCTION] = tvr.value();
obj->fslots[JSSLOT_SAVED_ID] = vp[0];
vp[0] = OBJECT_TO_JSVAL(obj);
}
ok = JS_TRUE;
out:
JS_POP_TEMP_ROOT(cx, &tvr);
return ok;
return true;
}
static JS_REQUIRES_STACK JSBool
@ -1876,10 +1862,8 @@ js_InvokeConstructor(JSContext *cx, uintN argc, JSBool clampReturn, jsval *vp)
/* Now we have an object with a constructor method; call it. */
vp[1] = OBJECT_TO_JSVAL(obj);
if (!js_Invoke(cx, argc, vp, JSINVOKE_CONSTRUCT)) {
cx->weakRoots.newborn[GCX_OBJECT] = NULL;
if (!js_Invoke(cx, argc, vp, JSINVOKE_CONSTRUCT))
return JS_FALSE;
}
/* Check the return value and if it's primitive, force it to be obj. */
rval = *vp;

View File

@ -940,7 +940,6 @@ js_ValueToNumber(JSContext *cx, jsval *vp)
const jschar *bp, *end, *ep;
jsdouble d, *dp;
JSObject *obj;
JSTempValueRooter tvr;
v = *vp;
for (;;) {
@ -1004,12 +1003,11 @@ js_ValueToNumber(JSContext *cx, jsval *vp)
* vp roots obj so we cannot use it as an extra root for
* obj->defaultValue result when calling the hook.
*/
JS_PUSH_SINGLE_TEMP_ROOT(cx, v, &tvr);
if (!obj->defaultValue(cx, JSTYPE_NUMBER, &tvr.u.value))
JSAutoTempValueRooter tvr(cx, v);
if (!obj->defaultValue(cx, JSTYPE_NUMBER, tvr.addr()))
obj = NULL;
else
v = *vp = tvr.u.value;
JS_POP_TEMP_ROOT(cx, &tvr);
v = *vp = tvr.value();
if (!obj) {
*vp = JSVAL_NULL;
return 0.0;

View File

@ -2836,7 +2836,6 @@ js_XDRBlockObject(JSXDRState *xdr, JSObject **objp)
JSObject *obj, *parent;
uint16 depth, count, i;
uint32 tmp;
JSTempValueRooter tvr;
JSScopeProperty *sprop;
jsid propid;
JSAtom *atom;
@ -2884,12 +2883,10 @@ js_XDRBlockObject(JSXDRState *xdr, JSObject **objp)
STOBJ_SET_PARENT(obj, parent);
}
JS_PUSH_SINGLE_TEMP_ROOT(cx, OBJECT_TO_JSVAL(obj), &tvr);
JSAutoTempValueRooter tvr(cx, obj);
if (!JS_XDRUint32(xdr, &tmp)) {
JS_POP_TEMP_ROOT(cx, &tvr);
return JS_FALSE;
}
if (!JS_XDRUint32(xdr, &tmp))
return false;
if (xdr->mode == JSXDR_DECODE) {
depth = (uint16)(tmp >> 16);
@ -2923,15 +2920,12 @@ js_XDRBlockObject(JSXDRState *xdr, JSObject **objp)
/* XDR the real id, then the shortid. */
if (!js_XDRStringAtom(xdr, &atom) ||
!JS_XDRUint16(xdr, (uint16 *)&shortid)) {
ok = JS_FALSE;
break;
return false;
}
if (xdr->mode == JSXDR_DECODE) {
if (!js_DefineBlockVariable(cx, obj, ATOM_TO_JSID(atom), shortid)) {
ok = JS_FALSE;
break;
}
if (!js_DefineBlockVariable(cx, obj, ATOM_TO_JSID(atom), shortid))
return false;
}
}
@ -2939,9 +2933,7 @@ js_XDRBlockObject(JSXDRState *xdr, JSObject **objp)
/* Do as the parser does and make this block scope shareable. */
OBJ_SCOPE(obj)->object = NULL;
}
JS_POP_TEMP_ROOT(cx, &tvr);
return ok;
return true;
}
#endif
@ -3447,29 +3439,22 @@ js_ConstructObject(JSContext *cx, JSClass *clasp, JSObject *proto,
{
jsid id;
jsval cval, rval;
JSTempValueRooter argtvr, tvr;
JSObject *obj, *ctor;
JS_PUSH_TEMP_ROOT(cx, argc, argv, &argtvr);
JSAutoTempValueRooter argtvr(cx, argc, argv);
if (!js_GetClassId(cx, clasp, &id) ||
!js_FindClassObject(cx, parent, id, &cval)) {
JS_POP_TEMP_ROOT(cx, &argtvr);
return NULL;
}
if (JSVAL_IS_PRIMITIVE(cval)) {
js_ReportIsNotFunction(cx, &cval, JSV2F_CONSTRUCT | JSV2F_SEARCH_STACK);
JS_POP_TEMP_ROOT(cx, &argtvr);
return NULL;
}
/*
* Protect cval in case a crazy getter for .prototype uproots it. After
* this point, all control flow must exit through label out with obj set.
*/
JS_PUSH_SINGLE_TEMP_ROOT(cx, cval, &tvr);
MUST_FLOW_THROUGH("out");
/* Protect cval in case a crazy getter for .prototype uproots it. */
JSAutoTempValueRooter tvr(cx, cval);
/*
* If proto or parent are NULL, set them to Constructor.prototype and/or
@ -3481,8 +3466,7 @@ js_ConstructObject(JSContext *cx, JSClass *clasp, JSObject *proto,
if (!proto) {
if (!ctor->getProperty(cx, ATOM_TO_JSID(cx->runtime->atomState.classPrototypeAtom),
&rval)) {
obj = NULL;
goto out;
return NULL;
}
if (JSVAL_IS_OBJECT(rval))
proto = JSVAL_TO_OBJECT(rval);
@ -3490,14 +3474,13 @@ js_ConstructObject(JSContext *cx, JSClass *clasp, JSObject *proto,
obj = js_NewObject(cx, clasp, proto, parent);
if (!obj)
goto out;
return NULL;
if (!js_InternalConstruct(cx, obj, cval, argc, argv, &rval))
goto bad;
return NULL;
if (JSVAL_IS_PRIMITIVE(rval))
goto out;
obj = JSVAL_TO_OBJECT(rval);
return obj;
/*
* If the instance's class differs from what was requested, throw a type
@ -3506,24 +3489,16 @@ js_ConstructObject(JSContext *cx, JSClass *clasp, JSObject *proto,
* private data set at this point, then the constructor was replaced and
* we should throw a type error.
*/
obj = JSVAL_TO_OBJECT(rval);
if (OBJ_GET_CLASS(cx, obj) != clasp ||
(!(~clasp->flags & (JSCLASS_HAS_PRIVATE |
JSCLASS_CONSTRUCT_PROTOTYPE)) &&
!obj->getPrivate())) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
JSMSG_WRONG_CONSTRUCTOR, clasp->name);
goto bad;
return NULL;
}
out:
JS_POP_TEMP_ROOT(cx, &tvr);
JS_POP_TEMP_ROOT(cx, &argtvr);
return obj;
bad:
cx->weakRoots.newborn[GCX_OBJECT] = NULL;
obj = NULL;
goto out;
}
/* XXXbe if one adds props, deletes earlier props, adds more, the last added

View File

@ -3097,10 +3097,8 @@
restore_scope:
/* Restore fp->scopeChain now that obj is defined in fp->varobj. */
fp->scopeChain = obj2;
if (!ok) {
cx->weakRoots.newborn[GCX_OBJECT] = NULL;
if (!ok)
goto error;
}
}
END_CASE(JSOP_DEFFUN)
@ -3148,10 +3146,8 @@
}
}
if (!ok) {
cx->weakRoots.newborn[GCX_OBJECT] = NULL;
if (!ok)
goto error;
}
END_CASE(JSOP_DEFFUN_FC)
BEGIN_CASE(JSOP_DEFLOCALFUN)

View File

@ -4906,17 +4906,13 @@ js_ExecuteRegExp(JSContext *cx, JSRegExp *re, JSString *str, size_t *indexp,
ok = js_DefineProperty(cx, obj, id, val, \
JS_PropertyStub, JS_PropertyStub, \
JSPROP_ENUMERATE); \
if (!ok) { \
cx->weakRoots.newborn[GCX_OBJECT] = NULL; \
cx->weakRoots.newborn[GCX_STRING] = NULL; \
if (!ok) \
goto out; \
} \
}
matchstr = js_NewDependentString(cx, str, cp - str->chars(),
matchlen);
if (!matchstr) {
cx->weakRoots.newborn[GCX_OBJECT] = NULL;
ok = JS_FALSE;
goto out;
}
@ -4953,8 +4949,6 @@ js_ExecuteRegExp(JSContext *cx, JSRegExp *re, JSString *str, size_t *indexp,
res->moreLength * sizeof(JSSubString));
}
if (!morepar) {
cx->weakRoots.newborn[GCX_OBJECT] = NULL;
cx->weakRoots.newborn[GCX_STRING] = NULL;
ok = JS_FALSE;
goto out;
}
@ -4978,19 +4972,14 @@ js_ExecuteRegExp(JSContext *cx, JSRegExp *re, JSString *str, size_t *indexp,
str->chars(),
parsub->length);
if (!parstr) {
cx->weakRoots.newborn[GCX_OBJECT] = NULL;
cx->weakRoots.newborn[GCX_STRING] = NULL;
ok = JS_FALSE;
goto out;
}
ok = js_DefineProperty(cx, obj, INT_TO_JSID(num + 1), STRING_TO_JSVAL(parstr),
NULL, NULL, JSPROP_ENUMERATE);
}
if (!ok) {
cx->weakRoots.newborn[GCX_OBJECT] = NULL;
cx->weakRoots.newborn[GCX_STRING] = NULL;
if (!ok)
goto out;
}
}
if (parsub->index == -1) {
res->lastParen = js_EmptySubString;

View File

@ -3272,9 +3272,6 @@ js_ValueToCharBuffer(JSContext *cx, jsval v, JSCharBuffer &cb)
JS_FRIEND_API(JSString *)
js_ValueToSource(JSContext *cx, jsval v)
{
JSTempValueRooter tvr;
JSString *str;
if (JSVAL_IS_VOID(v))
return ATOM_TO_STRING(cx->runtime->atomState.void0Atom);
if (JSVAL_IS_STRING(v))
@ -3290,16 +3287,11 @@ js_ValueToSource(JSContext *cx, jsval v)
return js_ValueToString(cx, v);
}
JS_PUSH_SINGLE_TEMP_ROOT(cx, JSVAL_NULL, &tvr);
if (!js_TryMethod(cx, JSVAL_TO_OBJECT(v),
cx->runtime->atomState.toSourceAtom,
0, NULL, &tvr.u.value)) {
str = NULL;
} else {
str = js_ValueToString(cx, tvr.u.value);
}
JS_POP_TEMP_ROOT(cx, &tvr);
return str;
JSAtom *atom = cx->runtime->atomState.toSourceAtom;
JSAutoTempValueRooter tvr(cx, JSVAL_NULL);
if (!js_TryMethod(cx, JSVAL_TO_OBJECT(v), atom, 0, NULL, tvr.addr()))
return NULL;
return js_ValueToString(cx, tvr.value());
}
/*

View File

@ -5466,20 +5466,14 @@ xml_attribute(JSContext *cx, uintN argc, jsval *vp)
static JSBool
xml_attributes(JSContext *cx, uintN argc, jsval *vp)
{
jsval name;
JSObject *qn;
JSTempValueRooter tvr;
JSBool ok;
name = ATOM_KEY(cx->runtime->atomState.starAtom);
qn = ToAttributeName(cx, name);
jsval name = ATOM_KEY(cx->runtime->atomState.starAtom);
JSObject *qn = ToAttributeName(cx, name);
if (!qn)
return JS_FALSE;
name = OBJECT_TO_JSVAL(qn);
JS_PUSH_SINGLE_TEMP_ROOT(cx, name, &tvr);
ok = GetProperty(cx, JS_THIS_OBJECT(cx, vp), name, vp);
JS_POP_TEMP_ROOT(cx, &tvr);
return ok;
JSAutoTempValueRooter tvr(cx, name);
return GetProperty(cx, JS_THIS_OBJECT(cx, vp), name, vp);
}
static JSXML *