XPCDispJSPropertyInfo::XPCDispJSPropertyInfo(JSContext* cx, PRUint32 memid, JSObject* obj, jsval val) : mPropertyType(INVALID), mMemID(memid) { PRUint32 len; jschar * chars = xpc_JSString2String(cx, val, &len); if(!chars) return; mName = nsString(reinterpret_cast<const PRUnichar *>(chars), len); JSBool found; uintN attr; // Get the property's attributes, and make sure it's found and enumerable if(!JS_GetUCPropertyAttributes(cx, obj, chars, len, &attr, &found) || !found || (attr & JSPROP_ENUMERATE) == 0) return; // Retrieve the property if(!chars || !JS_GetUCProperty(cx, obj, chars, len, &mProperty) || JSVAL_IS_NULL(mProperty)) return; // If this is a function if(JSVAL_IS_OBJECT(mProperty) && JS_ObjectIsFunction(cx, JSVAL_TO_OBJECT(mProperty))) { mPropertyType = FUNCTION; JSObject * funcObj = JSVAL_TO_OBJECT(mProperty); JSIdArray * funcObjArray = JS_Enumerate(cx, funcObj); if(funcObjArray) { mParamCount = funcObjArray->length; } } else // It's a property { mParamCount = 0; if((attr & JSPROP_READONLY) != 0) { mPropertyType = READONLY_PROPERTY; } else { mPropertyType = PROPERTY; } } }
JSDProperty* jsd_GetValueProperty(JSDContext* jsdc, JSDValue* jsdval, JSString* name) { JSContext* cx = jsdc->dumbContext; JSDProperty* jsdprop; JSDProperty* iter = NULL; JSObject* obj; uintN attrs = 0; JSBool found; JSPropertyDesc pd; const jschar * nameChars; size_t nameLen; jsval val, nameval; jsid nameid; JSCrossCompartmentCall *call = NULL; if(!jsd_IsValueObject(jsdc, jsdval)) return NULL; /* If we already have the prop, then return it */ while(NULL != (jsdprop = jsd_IterateProperties(jsdc, jsdval, &iter))) { JSString* propName = jsd_GetValueString(jsdc, jsdprop->name); if(propName) { intN result; if (JS_CompareStrings(cx, propName, name, &result) && !result) return jsdprop; } JSD_DropProperty(jsdc, jsdprop); } /* Not found in property list, look it up explicitly */ if(!(obj = JSVAL_TO_OBJECT(jsdval->val))) return NULL; if (!(nameChars = JS_GetStringCharsZAndLength(cx, name, &nameLen))) return NULL; JS_BeginRequest(cx); call = JS_EnterCrossCompartmentCall(cx, obj); if(!call) { JS_EndRequest(cx); return NULL; } JS_GetUCPropertyAttributes(cx, obj, nameChars, nameLen, &attrs, &found); if (!found) { JS_LeaveCrossCompartmentCall(call); JS_EndRequest(cx); return NULL; } JS_ClearPendingException(cx); if(!JS_GetUCProperty(cx, obj, nameChars, nameLen, &val)) { if (JS_IsExceptionPending(cx)) { if (!JS_GetPendingException(cx, &pd.value)) { JS_LeaveCrossCompartmentCall(call); JS_EndRequest(cx); return NULL; } pd.flags = JSPD_EXCEPTION; } else { pd.flags = JSPD_ERROR; pd.value = JSVAL_VOID; } } else { pd.value = val; } JS_LeaveCrossCompartmentCall(call); JS_EndRequest(cx); nameval = STRING_TO_JSVAL(name); if (!JS_ValueToId(cx, nameval, &nameid) || !JS_IdToValue(cx, nameid, &pd.id)) { return NULL; } pd.slot = pd.spare = 0; pd.alias = JSVAL_NULL; pd.flags |= (attrs & JSPROP_ENUMERATE) ? JSPD_ENUMERATE : 0 | (attrs & JSPROP_READONLY) ? JSPD_READONLY : 0 | (attrs & JSPROP_PERMANENT) ? JSPD_PERMANENT : 0; return _newProperty(jsdc, &pd, JSDPD_HINTED); }