コード例 #1
0
JSBool XPCDispInterface::Member::GetValue(XPCCallContext& ccx,
                                          XPCNativeInterface * iface, 
                                          jsval * retval) const
{
    // This is a method or attribute - we'll be needing a function object

    // We need to use the safe context for this thread because we don't want
    // to parent the new (and cached forever!) function object to the current
    // JSContext's global object. That would be bad!
    if((mType & RESOLVED) == 0)
    {
        JSContext* cx = ccx.GetSafeJSContext();
        if(!cx)
            return JS_FALSE;

        intN argc;
        JSNative callback;
        // Is this a function or a parameterized getter/setter
        if(IsFunction() || IsParameterizedProperty())
        {
            argc = GetParamCount();
            callback = XPC_IDispatch_CallMethod;
        }
        else
        {
            argc = 0;
            callback = XPC_IDispatch_GetterSetter;
        }

        JSFunction *fun = JS_NewFunctionById(cx, callback, argc, 0, nsnull, mName);
        if(!fun)
            return JS_FALSE;

        JSObject* funobj = JS_GetFunctionObject(fun);
        if(!funobj)
            return JS_FALSE;

        // Store ourselves and our native interface within the JSObject
        if(!JS_SetReservedSlot(ccx, funobj, 0, PRIVATE_TO_JSVAL((void *) this)))
            return JS_FALSE;

        if(!JS_SetReservedSlot(ccx, funobj, 1, PRIVATE_TO_JSVAL(iface)))
            return JS_FALSE;

        {   // scoped lock
            XPCAutoLock lock(ccx.GetRuntime()->GetMapLock());
            const_cast<Member*>(this)->mVal = OBJECT_TO_JSVAL(funobj);
            const_cast<Member*>(this)->mType |= RESOLVED;
        }
    }
    *retval = mVal;
    return JS_TRUE;
}
コード例 #2
0
JSBool
XPCNativeMember::Resolve(XPCCallContext& ccx, XPCNativeInterface* iface)
{
    if(IsConstant())
    {
        const nsXPTConstant* constant;
        if(NS_FAILED(iface->GetInterfaceInfo()->GetConstant(mIndex, &constant)))
            return JS_FALSE;

        const nsXPTCMiniVariant& mv = *constant->GetValue();

        // XXX Big Hack!
        nsXPTCVariant v;
        v.flags = 0;
        v.type = constant->GetType();
        memcpy(&v.val, &mv.val, sizeof(mv.val));

        jsval resultVal;

        if(!XPCConvert::NativeData2JS(ccx, &resultVal, &v.val, v.type,
                                      nsnull, nsnull, nsnull))
            return JS_FALSE;

        {   // scoped lock
            XPCAutoLock lock(ccx.GetRuntime()->GetMapLock());
            mVal = resultVal;
            mFlags |= RESOLVED;
        }

        return JS_TRUE;
    }
    // else...

    // This is a method or attribute - we'll be needing a function object

    intN argc;
    intN flags;
    JSNative callback;

    if(IsMethod())
    {
        const nsXPTMethodInfo* info;
        if(NS_FAILED(iface->GetInterfaceInfo()->GetMethodInfo(mIndex, &info)))
            return JS_FALSE;

        // Note: ASSUMES that retval is last arg.
        argc = (intN) info->GetParamCount();
        if(argc && info->GetParam((uint8)(argc-1)).IsRetval())
            argc-- ;

        flags = 0;
        callback = XPC_WN_CallMethod;
    }
    else
    {
        if(IsWritableAttribute())
            flags = JSFUN_GETTER | JSFUN_SETTER;
        else
            flags = JSFUN_GETTER;
        argc = 0;
        callback = XPC_WN_GetterSetter;
    }

    // We need to use the safe context for this thread because we don't want
    // to parent the new (and cached forever!) function object to the current
    // JSContext's global object. That would be bad!

    JSContext* cx = ccx.GetSafeJSContext();
    if(!cx)
        return JS_FALSE;

    const char *memberName = iface->GetMemberName(ccx, this);

    jsrefcount suspendDepth = 0;
    if(cx != ccx) {
        // Switching contexts, suspend the old and enter the new request.
        suspendDepth = JS_SuspendRequest(ccx);
        JS_BeginRequest(cx);
    }

    JSFunction *fun = JS_NewFunction(cx, callback, argc, flags, nsnull,
                                     memberName);

    if(suspendDepth) {
        JS_EndRequest(cx);
        JS_ResumeRequest(ccx, suspendDepth);
    }

    if(!fun)
        return JS_FALSE;

    JSObject* funobj = JS_GetFunctionObject(fun);
    if(!funobj)
        return JS_FALSE;

    AUTO_MARK_JSVAL(ccx, OBJECT_TO_JSVAL(funobj));

    STOBJ_CLEAR_PARENT(funobj);
    STOBJ_CLEAR_PROTO(funobj);

    if(!JS_SetReservedSlot(ccx, funobj, 0, PRIVATE_TO_JSVAL(iface))||
       !JS_SetReservedSlot(ccx, funobj, 1, PRIVATE_TO_JSVAL(this)))
        return JS_FALSE;

    {   // scoped lock
        XPCAutoLock lock(ccx.GetRuntime()->GetMapLock());
        mVal = OBJECT_TO_JSVAL(funobj);
        mFlags |= RESOLVED;
    }

    return JS_TRUE;
}