JSBool XPCNativeMember::NewFunctionObject(XPCCallContext& ccx, XPCNativeInterface* iface, JSObject *parent, jsval* pval) { NS_ASSERTION(!IsConstant(), "Only call this if you're sure this is not a constant!"); if(!IsResolved() && !Resolve(ccx, iface)) return JS_FALSE; AUTO_MARK_JSVAL(ccx, &mVal); JSObject* funobj = xpc_CloneJSFunction(ccx, JSVAL_TO_OBJECT(mVal), parent); if(!funobj) return JS_FALSE; *pval = OBJECT_TO_JSVAL(funobj); return JS_TRUE; }
JSBool XPCIDispatchExtension::DefineProperty(XPCCallContext & ccx, JSObject *obj, jsval idval, XPCWrappedNative* wrapperToReflectInterfaceNames, uintN propFlags, JSBool* resolved) { if(!JSVAL_IS_STRING(idval)) return JS_FALSE; // Look up the native interface for IDispatch and then find a tearoff XPCNativeInterface* iface = XPCNativeInterface::GetNewOrUsed(ccx, "IDispatch"); // The native interface isn't defined so just exit with an error if(iface == nsnull) return JS_FALSE; XPCWrappedNativeTearOff* to = wrapperToReflectInterfaceNames->LocateTearOff(ccx, iface); // This object has no IDispatch interface so bail. if(to == nsnull) return JS_FALSE; // Look up the member in the interface const XPCDispInterface::Member * member = to->GetIDispatchInfo()->FindMember(idval); if(!member) { // IDispatch is case insensitive, so if we don't find a case sensitive // match, we'll try a more expensive case-insensisitive search // TODO: We need to create cleaner solution that doesn't create // multiple properties of different case on the JS Object member = to->GetIDispatchInfo()->FindMemberCI(ccx, idval); if(!member) return JS_FALSE; } // Get the function object jsval funval; if(!member->GetValue(ccx, iface, &funval)) return JS_FALSE; // Protect the jsval AUTO_MARK_JSVAL(ccx, funval); // clone a function we can use for this object JSObject* funobj = xpc_CloneJSFunction(ccx, JSVAL_TO_OBJECT(funval), obj); if(!funobj) return JS_FALSE; jsid id; // If this is a function or a parameterized property if(member->IsFunction() || member->IsParameterizedProperty()) { // define the function on the object AutoResolveName arn(ccx, idval); if(resolved) *resolved = JS_TRUE; return JS_ValueToId(ccx, idval, &id) && OBJ_DEFINE_PROPERTY(ccx, obj, id, OBJECT_TO_JSVAL(funobj), nsnull, nsnull, propFlags, nsnull); } // Define the property on the object NS_ASSERTION(member->IsProperty(), "way broken!"); propFlags |= JSPROP_GETTER | JSPROP_SHARED; if(member->IsSetter()) { propFlags |= JSPROP_SETTER; propFlags &= ~JSPROP_READONLY; } AutoResolveName arn(ccx, idval); if(resolved) *resolved = JS_TRUE; return JS_ValueToId(ccx, idval, &id) && OBJ_DEFINE_PROPERTY(ccx, obj, id, JSVAL_VOID, (JSPropertyOp) funobj, (JSPropertyOp) funobj, propFlags, nsnull); }