From d2b5a1c3dbc97190130d25d2423a98ccab8d0e7a Mon Sep 17 00:00:00 2001 From: Jason Orendorff Date: Wed, 11 Feb 2009 13:33:17 -0600 Subject: [PATCH] Bug 477142 - _FAIL builtins need to be GC-safe. r=brendan. --HG-- extra : rebase_source : 10515f7d1f5a85c1965c812f55d91d3d0f49a28e --- js/src/jsarray.cpp | 31 ++++++++++++++++--------------- js/src/jscntxt.h | 25 ++++++++++++++++++++++++- js/src/jsobj.cpp | 2 +- js/src/jsstr.cpp | 4 +++- js/src/jstracer.cpp | 44 ++++++++++++++++++++++++-------------------- 5 files changed, 68 insertions(+), 38 deletions(-) diff --git a/js/src/jsarray.cpp b/js/src/jsarray.cpp index 7de231b4e72..59f704667d8 100644 --- a/js/src/jsarray.cpp +++ b/js/src/jsarray.cpp @@ -1540,23 +1540,23 @@ InitArrayObject(JSContext *cx, JSObject *obj, jsuint length, jsval *vector, static JSString* FASTCALL Array_p_join(JSContext* cx, JSObject* obj, JSString *str) { - jsval v; - if (!array_join_sub(cx, obj, TO_STRING, str, &v)) { + JSAutoTempValueRooter tvr(cx); + if (!array_join_sub(cx, obj, TO_STRING, str, tvr.addr())) { cx->builtinStatus |= JSBUILTIN_ERROR; return NULL; } - JS_ASSERT(JSVAL_IS_STRING(v)); - return JSVAL_TO_STRING(v); + return JSVAL_TO_STRING(tvr.value()); } static JSString* FASTCALL Array_p_toString(JSContext* cx, JSObject* obj) { - jsval v; - if (!array_join_sub(cx, obj, TO_STRING, NULL, &v)) + JSAutoTempValueRooter tvr(cx); + if (!array_join_sub(cx, obj, TO_STRING, NULL, tvr.addr())) { + cx->builtinStatus |= JSBUILTIN_ERROR; return NULL; - JS_ASSERT(JSVAL_IS_STRING(v)); - return JSVAL_TO_STRING(v); + } + return JSVAL_TO_STRING(tvr.value()); } #endif @@ -2163,10 +2163,11 @@ js_ArrayCompPush(JSContext *cx, JSObject *obj, jsval v) static jsval FASTCALL Array_p_push1(JSContext* cx, JSObject* obj, jsval v) { + JSAutoTempValueRooter tvr(cx, v); if (OBJ_IS_DENSE_ARRAY(cx, obj) - ? array_push1_dense(cx, obj, v, &v) - : array_push_slowly(cx, obj, 1, &v, &v)) { - return v; + ? array_push1_dense(cx, obj, v, tvr.addr()) + : array_push_slowly(cx, obj, 1, tvr.addr(), tvr.addr())) { + return tvr.value(); } cx->builtinStatus |= JSBUILTIN_ERROR; return JSVAL_VOID; @@ -2234,11 +2235,11 @@ array_pop_dense(JSContext *cx, JSObject* obj, jsval *vp) static jsval FASTCALL Array_p_pop(JSContext* cx, JSObject* obj) { - jsval v; + JSAutoTempValueRooter tvr(cx); if (OBJ_IS_DENSE_ARRAY(cx, obj) - ? array_pop_dense(cx, obj, &v) - : array_pop_slowly(cx, obj, &v)) { - return v; + ? array_pop_dense(cx, obj, tvr.addr()) + : array_pop_slowly(cx, obj, tvr.addr())) { + return tvr.value(); } cx->builtinStatus |= JSBUILTIN_ERROR; return JSVAL_VOID; diff --git a/js/src/jscntxt.h b/js/src/jscntxt.h index 714fc1a6d8f..35164623291 100644 --- a/js/src/jscntxt.h +++ b/js/src/jscntxt.h @@ -1050,7 +1050,7 @@ class JSAutoTempValueRooter : mContext(cx) { JS_PUSH_TEMP_ROOT(mContext, len, vec, &mTvr); } - JSAutoTempValueRooter(JSContext *cx, jsval v) + explicit JSAutoTempValueRooter(JSContext *cx, jsval v = JSVAL_NULL) : mContext(cx) { JS_PUSH_SINGLE_TEMP_ROOT(mContext, v, &mTvr); } @@ -1063,6 +1063,9 @@ class JSAutoTempValueRooter JS_POP_TEMP_ROOT(mContext, &mTvr); } + jsval value() { return mTvr.u.value; } + jsval * addr() { return &mTvr.u.value; } + protected: JSContext *mContext; @@ -1075,6 +1078,26 @@ class JSAutoTempValueRooter JSTempValueRooter mTvr; }; +class JSAutoTempIdRooter +{ +public: + explicit JSAutoTempIdRooter(JSContext *cx, jsid id = INT_TO_JSID(0)) + : mContext(cx) { + JS_PUSH_SINGLE_TEMP_ROOT(mContext, ID_TO_VALUE(id), &mTvr); + } + + ~JSAutoTempIdRooter() { + JS_POP_TEMP_ROOT(mContext, &mTvr); + } + + jsid id() { return (jsid) mTvr.u.value; } + jsid * addr() { return (jsid *) &mTvr.u.value; } + +private: + JSContext *mContext; + JSTempValueRooter mTvr; +}; + class JSAutoResolveFlags { public: diff --git a/js/src/jsobj.cpp b/js/src/jsobj.cpp index 8a6cf9ddeae..ecb05712477 100644 --- a/js/src/jsobj.cpp +++ b/js/src/jsobj.cpp @@ -1948,7 +1948,7 @@ const char js_lookupSetter_str[] = "__lookupSetter__"; #endif JS_DEFINE_TRCINFO_1(obj_valueOf, - (3, (static, JSVAL, Object_p_valueOf, CONTEXT, THIS, STRING, 0, 0))) + (3, (static, JSVAL, Object_p_valueOf, CONTEXT, THIS, STRING, 0, 0))) JS_DEFINE_TRCINFO_1(obj_hasOwnProperty, (3, (static, BOOL_FAIL, Object_p_hasOwnProperty, CONTEXT, THIS, STRING, 0, 0))) JS_DEFINE_TRCINFO_1(obj_propertyIsEnumerable, diff --git a/js/src/jsstr.cpp b/js/src/jsstr.cpp index b8e337c5011..0d08df7b055 100644 --- a/js/src/jsstr.cpp +++ b/js/src/jsstr.cpp @@ -1453,6 +1453,7 @@ static jsval 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) }; + JSAutoTempValueRooter tvr(cx, 3, vp); if (!StringMatchHelper(cx, 1, vp, pc)) { cx->builtinStatus |= JSBUILTIN_ERROR; return JSVAL_VOID; @@ -1464,6 +1465,7 @@ static jsval 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) }; + JSAutoTempValueRooter tvr(cx, 3, vp); if (!StringMatchHelper(cx, 1, vp, pc)) { cx->builtinStatus |= JSBUILTIN_ERROR; return JSVAL_VOID; @@ -2488,7 +2490,7 @@ JS_DEFINE_CALLINFO_2(extern, BOOL, js_EqualStrings, STRING, STRING, JS_DEFINE_CALLINFO_2(extern, INT32, js_CompareStrings, STRING, STRING, 1, 1) JS_DEFINE_TRCINFO_1(str_toString, - (2, (extern, STRING_FAIL, String_p_toString, CONTEXT, THIS, 1, 1))) + (2, (extern, STRING_RETRY, String_p_toString, CONTEXT, THIS, 1, 1))) JS_DEFINE_TRCINFO_2(str_substring, (4, (static, STRING_RETRY, String_p_substring, CONTEXT, THIS_STRING, INT32, INT32, 1, 1)), (3, (static, STRING_RETRY, String_p_substring_1, CONTEXT, THIS_STRING, INT32, 1, 1))) diff --git a/js/src/jstracer.cpp b/js/src/jstracer.cpp index e7f0ef3fc8b..962efcfb22b 100644 --- a/js/src/jstracer.cpp +++ b/js/src/jstracer.cpp @@ -7017,17 +7017,17 @@ GetProperty(JSContext *cx, uintN argc, jsval *vp) static jsval FASTCALL GetProperty_tn(JSContext *cx, jsbytecode *pc, JSObject *obj, JSString *name) { - jsid id; - jsval v; + JSAutoTempIdRooter idr(cx); + JSAutoTempValueRooter tvr(cx); BEGIN_PC_HINT(pc); - if (!js_ValueToStringId(cx, STRING_TO_JSVAL(name), &id) || - !OBJ_GET_PROPERTY(cx, obj, id, &v)) { + if (!js_ValueToStringId(cx, STRING_TO_JSVAL(name), idr.addr()) || + !OBJ_GET_PROPERTY(cx, obj, idr.id(), tvr.addr())) { cx->builtinStatus |= JSBUILTIN_ERROR; - v = JSVAL_ERROR_COOKIE; + *tvr.addr() = JSVAL_ERROR_COOKIE; } END_PC_HINT(); - return v; + return tvr.value(); } static JSBool @@ -7048,20 +7048,20 @@ GetElement(JSContext *cx, uintN argc, jsval *vp) static jsval FASTCALL GetElement_tn(JSContext* cx, jsbytecode *pc, JSObject* obj, int32 index) { - jsval v; - jsid id; + JSAutoTempValueRooter tvr(cx); + JSAutoTempIdRooter idr(cx); - if (!js_Int32ToId(cx, index, &id)) { + if (!js_Int32ToId(cx, index, idr.addr())) { cx->builtinStatus |= JSBUILTIN_ERROR; return JSVAL_ERROR_COOKIE; } BEGIN_PC_HINT(pc); - if (!OBJ_GET_PROPERTY(cx, obj, id, &v)) { + if (!OBJ_GET_PROPERTY(cx, obj, idr.id(), tvr.addr())) { cx->builtinStatus |= JSBUILTIN_ERROR; - v = JSVAL_ERROR_COOKIE; + *tvr.addr() = JSVAL_ERROR_COOKIE; } END_PC_HINT(); - return v; + return tvr.value(); } JS_DEFINE_TRCINFO_1(GetProperty, @@ -7163,10 +7163,11 @@ SetProperty(JSContext *cx, uintN argc, jsval *vp) static int32 FASTCALL SetProperty_tn(JSContext* cx, JSObject* obj, JSString* idstr, jsval v) { - jsid id; + JSAutoTempValueRooter tvr(cx, v); + JSAutoTempIdRooter idr(cx); - if (!js_ValueToStringId(cx, STRING_TO_JSVAL(idstr), &id) || - !OBJ_SET_PROPERTY(cx, obj, id, &v)) { + if (!js_ValueToStringId(cx, STRING_TO_JSVAL(idstr), idr.addr()) || + !OBJ_SET_PROPERTY(cx, obj, idr.id(), tvr.addr())) { cx->builtinStatus |= JSBUILTIN_ERROR; } return JSVAL_TO_PSEUDO_BOOLEAN(JSVAL_VOID); @@ -7193,10 +7194,13 @@ SetElement(JSContext *cx, uintN argc, jsval *vp) static int32 FASTCALL SetElement_tn(JSContext* cx, JSObject* obj, int32 index, jsval v) { - jsid id; + JSAutoTempIdRooter idr(cx); + JSAutoTempValueRooter tvr(cx, v); - if (!js_Int32ToId(cx, index, &id) || !OBJ_SET_PROPERTY(cx, obj, id, &v)) + if (!js_Int32ToId(cx, index, idr.addr()) || + !OBJ_SET_PROPERTY(cx, obj, idr.id(), tvr.addr())) { cx->builtinStatus |= JSBUILTIN_ERROR; + } return JSVAL_TO_PSEUDO_BOOLEAN(JSVAL_VOID); } @@ -9141,17 +9145,17 @@ CallIteratorNext(JSContext *cx, uintN argc, jsval *vp) static jsval FASTCALL CallIteratorNext_tn(JSContext* cx, jsbytecode* pc, JSObject* iterobj) { - jsval v; + JSAutoTempValueRooter tvr(cx); BEGIN_PC_HINT(pc); - bool ok = js_CallIteratorNext(cx, iterobj, &v); + bool ok = js_CallIteratorNext(cx, iterobj, tvr.addr()); END_PC_HINT(); if (!ok) { cx->builtinStatus |= JSBUILTIN_ERROR; return JSVAL_ERROR_COOKIE; } - return v; + return tvr.value(); } JS_DEFINE_TRCINFO_1(ObjectToIterator,