JS_LOCK_OBJ(cx, obj2); LOCKED_OBJ_SET_SLOT(obj2, slot, *vp); PROPERTY_CACHE_FILL(cx, &cx->runtime->propertyCache, obj2, id, (JSProperty *)sprop); OBJ_DROP_PROPERTY(cx, obj2, (JSProperty *)sprop);
JS_LOCK_SCOPE(cx, scope); sprop = js_DropScopeProperty(cx, scope, sprop); if (sprop && SPROP_HAS_VALID_SLOT(sprop)) { LOCKED_OBJ_SET_SLOT(obj2, slot, *vp); PROPERTY_CACHE_FILL(cx, &cx->runtime->propertyCache, obj2, id, (JSProperty *)sprop); } JS_UNLOCK_SCOPE(cx, scope);
js_GetProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp){    JSObject *obj2;    JSScopeProperty *sprop;    jsint slot;    if (!js_LookupProperty(cx, obj, id, &obj2, (JSProperty **)&sprop))	return JS_FALSE;    if (!sprop) {	/*	 * Handle old bug that treated empty string as zero index.	 * Also convert string indices to numbers if applicable.	 */	CHECK_FOR_FUNNY_INDEX(id);#if JS_BUG_NULL_INDEX_PROPS	/* Indexed properties defaulted to null in old versions. */	*vp = (JSVAL_IS_INT(id) && JSVAL_TO_INT(id) >= 0)	      ? JSVAL_NULL	      : JSVAL_VOID;#else	*vp = JSVAL_VOID;#endif	return OBJ_GET_CLASS(cx, obj)->getProperty(cx, obj, js_IdToValue(id),			     vp);    }    if (!OBJ_IS_NATIVE(obj2)) {	OBJ_DROP_PROPERTY(cx, obj2, (JSProperty *)sprop);	return OBJ_GET_PROPERTY(cx, obj2, id, vp);    }    /* Unlock obj2 before calling getter, relock after to avoid deadlock. */    slot = sprop->slot;    *vp = LOCKED_OBJ_GET_SLOT(obj2, slot);    JS_UNLOCK_OBJ(cx, obj2);    if (!SPROP_GET(cx, sprop, obj, obj2, vp)) {	JS_LOCK_OBJ(cx, obj2);	OBJ_DROP_PROPERTY(cx, obj2, (JSProperty *)sprop);	return JS_FALSE;    }    JS_LOCK_OBJ(cx, obj2);    LOCKED_OBJ_SET_SLOT(obj2, slot, *vp);    PROPERTY_CACHE_FILL(cx, &cx->runtime->propertyCache, obj2, id,			(JSProperty *)sprop);    OBJ_DROP_PROPERTY(cx, obj2, (JSProperty *)sprop);    return JS_TRUE;}