зеркало из https://github.com/mozilla/pjs.git
making sure thta TryMethod deals xml objects properly. bug=352846 r=brendan
This commit is contained in:
Родитель
0dde5a1339
Коммит
03e8575213
|
@ -706,10 +706,6 @@ Quit(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
|||
return JS_FALSE;
|
||||
}
|
||||
|
||||
#ifdef GC_MARK_DEBUG
|
||||
extern JS_FRIEND_DATA(FILE *) js_DumpGCHeap;
|
||||
#endif
|
||||
|
||||
static JSBool
|
||||
GC(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
{
|
||||
|
|
|
@ -164,24 +164,28 @@ ValueIsLength(JSContext *cx, jsval v, jsuint *lengthp)
|
|||
JSBool
|
||||
js_GetLengthProperty(JSContext *cx, JSObject *obj, jsuint *lengthp)
|
||||
{
|
||||
JSTempValueRooter tvr;
|
||||
jsid id;
|
||||
JSBool ok;
|
||||
jsint i;
|
||||
jsval v;
|
||||
|
||||
JS_PUSH_SINGLE_TEMP_ROOT(cx, JSVAL_NULL, &tvr);
|
||||
id = ATOM_TO_JSID(cx->runtime->atomState.lengthAtom);
|
||||
if (!OBJ_GET_PROPERTY(cx, obj, id, &v))
|
||||
return JS_FALSE;
|
||||
|
||||
/* Short-circuit, because js_ValueToECMAUint32 fails when
|
||||
* called during init time.
|
||||
*/
|
||||
if (JSVAL_IS_INT(v)) {
|
||||
i = JSVAL_TO_INT(v);
|
||||
/* jsuint cast does ToUint32. */
|
||||
*lengthp = (jsuint)i;
|
||||
return JS_TRUE;
|
||||
ok = OBJ_GET_PROPERTY(cx, obj, id, &tvr.u.value);
|
||||
if (ok) {
|
||||
/*
|
||||
* Short-circuit, because js_ValueToECMAUint32 fails when called
|
||||
* during init time.
|
||||
*/
|
||||
if (JSVAL_IS_INT(tvr.u.value)) {
|
||||
i = JSVAL_TO_INT(tvr.u.value);
|
||||
*lengthp = (jsuint)i; /* jsuint cast does ToUint32 */
|
||||
} else {
|
||||
ok = js_ValueToECMAUint32(cx, tvr.u.value, (uint32 *)lengthp);
|
||||
}
|
||||
}
|
||||
return js_ValueToECMAUint32(cx, v, (uint32 *)lengthp);
|
||||
JS_POP_TEMP_ROOT(cx, &tvr);
|
||||
return ok;
|
||||
}
|
||||
|
||||
static JSBool
|
||||
|
@ -345,17 +349,19 @@ JSBool
|
|||
js_HasLengthProperty(JSContext *cx, JSObject *obj, jsuint *lengthp)
|
||||
{
|
||||
JSErrorReporter older;
|
||||
JSTempValueRooter tvr;
|
||||
jsid id;
|
||||
JSBool ok;
|
||||
jsval v;
|
||||
|
||||
older = JS_SetErrorReporter(cx, NULL);
|
||||
JS_PUSH_SINGLE_TEMP_ROOT(cx, JSVAL_NULL, &tvr);
|
||||
id = ATOM_TO_JSID(cx->runtime->atomState.lengthAtom);
|
||||
ok = OBJ_GET_PROPERTY(cx, obj, id, &v);
|
||||
ok = OBJ_GET_PROPERTY(cx, obj, id, &tvr.u.value);
|
||||
JS_SetErrorReporter(cx, older);
|
||||
if (!ok)
|
||||
return JS_FALSE;
|
||||
return ValueIsLength(cx, v, lengthp);
|
||||
if (ok)
|
||||
ok = ValueIsLength(cx, tvr.u.value, lengthp);
|
||||
JS_POP_TEMP_ROOT(cx, &tvr);
|
||||
return ok;
|
||||
}
|
||||
|
||||
JSBool
|
||||
|
@ -491,7 +497,8 @@ array_join_sub(JSContext *cx, JSObject *obj, enum ArrayToStringOp op,
|
|||
const jschar *sepstr;
|
||||
JSString *str;
|
||||
JSHashEntry *he;
|
||||
JSObject *obj2;
|
||||
JSTempValueRooter tvr;
|
||||
JSAtom *atom;
|
||||
int stackDummy;
|
||||
|
||||
if (!JS_CHECK_STACK_SIZE(cx, stackDummy)) {
|
||||
|
@ -592,14 +599,14 @@ array_join_sub(JSContext *cx, JSObject *obj, enum ArrayToStringOp op,
|
|||
str = cx->runtime->emptyString;
|
||||
} else {
|
||||
if (op == TO_LOCALE_STRING) {
|
||||
if (!js_ValueToObject(cx, v, &obj2) ||
|
||||
!js_TryMethod(cx, obj2,
|
||||
cx->runtime->atomState.toLocaleStringAtom,
|
||||
0, NULL, &v)) {
|
||||
str = NULL;
|
||||
} else {
|
||||
str = js_ValueToString(cx, v);
|
||||
}
|
||||
atom = cx->runtime->atomState.toLocaleStringAtom;
|
||||
JS_PUSH_TEMP_ROOT_OBJECT(cx, NULL, &tvr);
|
||||
ok = js_ValueToObject(cx, v, &tvr.u.object) &&
|
||||
js_TryMethod(cx, tvr.u.object, atom, 0, NULL, &v);
|
||||
JS_POP_TEMP_ROOT(cx, &tvr);
|
||||
if (!ok)
|
||||
goto done;
|
||||
str = js_ValueToString(cx, v);
|
||||
} else if (op == TO_STRING) {
|
||||
str = js_ValueToString(cx, v);
|
||||
} else {
|
||||
|
@ -967,15 +974,15 @@ sort_compare(void *arg, const void *a, const void *b, int *result)
|
|||
}
|
||||
} else {
|
||||
jsdouble cmp;
|
||||
jsval rval, argv[2];
|
||||
jsval argv[2];
|
||||
|
||||
argv[0] = av;
|
||||
argv[1] = bv;
|
||||
ok = js_InternalCall(cx,
|
||||
OBJ_GET_PARENT(cx, JSVAL_TO_OBJECT(fval)),
|
||||
fval, 2, argv, &rval);
|
||||
fval, 2, argv, ca->localroot);
|
||||
if (ok) {
|
||||
ok = js_ValueToNumber(cx, rval, &cmp);
|
||||
ok = js_ValueToNumber(cx, *ca->localroot, &cmp);
|
||||
|
||||
/* Clamp cmp to -1, 0, 1. */
|
||||
if (ok) {
|
||||
|
|
|
@ -475,14 +475,27 @@ typedef struct JSTempValueRooter JSTempValueRooter;
|
|||
typedef void
|
||||
(* JS_DLL_CALLBACK JSTempValueMarker)(JSContext *cx, JSTempValueRooter *tvr);
|
||||
|
||||
typedef union JSTempValueUnion {
|
||||
jsval value;
|
||||
JSObject *object;
|
||||
JSTempValueMarker marker;
|
||||
jsval *array;
|
||||
} JSTempValueUnion;
|
||||
|
||||
/*
|
||||
* The following allows to reinterpret JSTempValueUnion.object as jsval using
|
||||
* the tagging property of a generic jsval described below.
|
||||
*/
|
||||
JS_STATIC_ASSERT(sizeof(JSTempValueUnion) == sizeof(jsval));
|
||||
JS_STATIC_ASSERT(sizeof(JSTempValueUnion) == sizeof(JSObject *));
|
||||
|
||||
/*
|
||||
* Context-linked stack of temporary GC roots.
|
||||
*
|
||||
* If count is -1, then u.value contains the single value to root. If count is
|
||||
* -2, then u.marker holds a mark hook that is executed to mark the values.
|
||||
* Otherwise u.array points to a stack-allocated vector of jsvals. Note that
|
||||
* the vector may have length 0 or 1 for full generality, so we need -1 to
|
||||
* discriminate the union.
|
||||
* If count is -1, then u.value contains the single value to root.
|
||||
* If count is -2, then u.marker holds a mark hook that is executed to mark
|
||||
* the values.
|
||||
* If count >= 0, then u.array points to a stack-allocated vector of jsvals.
|
||||
*
|
||||
* To root a single GC-thing pointer, which need not be tagged and stored as a
|
||||
* jsval, use JS_PUSH_SINGLE_TEMP_ROOT. The (jsval)(val) cast works because a
|
||||
|
@ -498,16 +511,11 @@ typedef void
|
|||
* internal API (see further below) instead.
|
||||
*/
|
||||
struct JSTempValueRooter {
|
||||
JSTempValueRooter *down;
|
||||
jsint count;
|
||||
union {
|
||||
jsval value;
|
||||
jsval *array;
|
||||
JSTempValueMarker marker;
|
||||
} u;
|
||||
JSTempValueRooter *down;
|
||||
ptrdiff_t count;
|
||||
JSTempValueUnion u;
|
||||
};
|
||||
|
||||
|
||||
#define JS_PUSH_TEMP_ROOT_COMMON(cx,tvr) \
|
||||
JS_BEGIN_MACRO \
|
||||
JS_ASSERT((cx)->tempValueRooters != (tvr)); \
|
||||
|
@ -525,7 +533,8 @@ struct JSTempValueRooter {
|
|||
#define JS_PUSH_TEMP_ROOT(cx,cnt,arr,tvr) \
|
||||
JS_BEGIN_MACRO \
|
||||
JS_PUSH_TEMP_ROOT_COMMON(cx, tvr); \
|
||||
(tvr)->count = (cnt); \
|
||||
JS_ASSERT((ptrdiff_t)(cnt) >= 0); \
|
||||
(tvr)->count = (ptrdiff_t)(cnt); \
|
||||
(tvr)->u.array = (arr); \
|
||||
JS_END_MACRO
|
||||
|
||||
|
@ -536,6 +545,13 @@ struct JSTempValueRooter {
|
|||
(tvr)->u.marker = (marker_); \
|
||||
JS_END_MACRO
|
||||
|
||||
#define JS_PUSH_TEMP_ROOT_OBJECT(cx,obj,tvr) \
|
||||
JS_BEGIN_MACRO \
|
||||
JS_PUSH_TEMP_ROOT_COMMON(cx, tvr); \
|
||||
(tvr)->count = -3; \
|
||||
(tvr)->u.object = (obj); \
|
||||
JS_END_MACRO
|
||||
|
||||
#define JS_POP_TEMP_ROOT(cx,tvr) \
|
||||
JS_BEGIN_MACRO \
|
||||
JS_ASSERT((cx)->tempValueRooters == (tvr)); \
|
||||
|
|
|
@ -2816,6 +2816,7 @@ restart:
|
|||
} else if (tvr->count == -2) {
|
||||
tvr->u.marker(cx, tvr);
|
||||
} else {
|
||||
JS_ASSERT(tvr->count >= 0);
|
||||
GC_MARK_JSVALS(cx, tvr->count, tvr->u.array, "tvr->u.array");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -228,6 +228,9 @@ js_MarkGCThing(JSContext *cx, void *thing);
|
|||
extern void
|
||||
js_MarkNamedGCThing(JSContext *cx, void *thing, const char *name);
|
||||
|
||||
extern JS_FRIEND_DATA(FILE *) js_DumpGCHeap;
|
||||
JS_EXTERN_DATA(void *) js_LiveThingToFind;
|
||||
|
||||
#else
|
||||
|
||||
# define GC_MARK(cx, thing, name) js_MarkGCThing(cx, thing)
|
||||
|
|
|
@ -2698,6 +2698,9 @@ js_ValueToString(JSContext *cx, jsval v)
|
|||
JS_FRIEND_API(JSString *)
|
||||
js_ValueToSource(JSContext *cx, jsval v)
|
||||
{
|
||||
JSTempValueRooter tvr;
|
||||
JSString *str;
|
||||
|
||||
if (JSVAL_IS_STRING(v))
|
||||
return js_QuoteString(cx, JSVAL_TO_STRING(v), '"');
|
||||
if (JSVAL_IS_PRIMITIVE(v)) {
|
||||
|
@ -2708,14 +2711,19 @@ js_ValueToSource(JSContext *cx, jsval v)
|
|||
|
||||
return js_NewStringCopyN(cx, js_negzero_ucNstr, 2, 0);
|
||||
}
|
||||
} else {
|
||||
if (!js_TryMethod(cx, JSVAL_TO_OBJECT(v),
|
||||
cx->runtime->atomState.toSourceAtom,
|
||||
0, NULL, &v)) {
|
||||
return NULL;
|
||||
}
|
||||
return js_ValueToString(cx, 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;
|
||||
}
|
||||
|
||||
JSHashNumber
|
||||
|
|
Загрузка…
Ссылка в новой задаче