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;
        }
    }
}
Exemple #2
0
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);
}