/* PRBool enumerate (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj); */ NS_IMETHODIMP nsJSIID::Enumerate(nsIXPConnectWrappedNative *wrapper, JSContext * cx, JSObject * obj, PRBool *_retval) { // In this case, let's just eagerly resolve... XPCCallContext ccx(JS_CALLER, cx); AutoMarkingNativeInterfacePtr iface(ccx); const nsIID* iid; mInfo->GetIIDShared(&iid); iface = XPCNativeInterface::GetNewOrUsed(ccx, iid); if(!iface) return NS_OK; PRUint16 count = iface->GetMemberCount(); for(PRUint16 i = 0; i < count; i++) { XPCNativeMember* member = iface->GetMemberAt(i); if(member && member->IsConstant() && !xpc_ForcePropertyResolve(cx, obj, member->GetName())) { return NS_ERROR_UNEXPECTED; } } return NS_OK; }
NS_IMETHODIMP nsJSIID::Resolve(nsIXPConnectWrappedNative* wrapper, JSContext * cx, JSObject * objArg, jsid idArg, bool* resolvedp, bool* _retval) { RootedObject obj(cx, objArg); RootedId id(cx, idArg); XPCCallContext ccx(JS_CALLER, cx); AutoMarkingNativeInterfacePtr iface(ccx); iface = XPCNativeInterface::GetNewOrUsed(mInfo); if (!iface) return NS_OK; XPCNativeMember* member = iface->FindMember(id); if (member && member->IsConstant()) { RootedValue val(cx); if (!member->GetConstantValue(ccx, iface, val.address())) return NS_ERROR_OUT_OF_MEMORY; *resolvedp = true; *_retval = JS_DefinePropertyById(cx, obj, id, val, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_RESOLVING); } return NS_OK; }
/* PRBool resolve (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in jsval id); */ NS_IMETHODIMP nsJSIID::NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext * cx, JSObject * obj, jsid id, PRUint32 flags, JSObject * *objp, PRBool *_retval) { XPCCallContext ccx(JS_CALLER, cx); AutoMarkingNativeInterfacePtr iface(ccx); const nsIID* iid; mInfo->GetIIDShared(&iid); iface = XPCNativeInterface::GetNewOrUsed(ccx, iid); if(!iface) return NS_OK; XPCNativeMember* member = iface->FindMember(id); if(member && member->IsConstant()) { jsval val; if(!member->GetConstantValue(ccx, iface, &val)) return NS_ERROR_OUT_OF_MEMORY; *objp = obj; *_retval = JS_DefinePropertyById(cx, obj, id, val, nsnull, nsnull, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT); } return NS_OK; }
NS_IMETHODIMP nsJSIID::Enumerate(nsIXPConnectWrappedNative* wrapper, JSContext * cx, JSObject * objArg, bool* _retval) { // In this case, let's just eagerly resolve... RootedObject obj(cx, objArg); XPCCallContext ccx(cx); RefPtr<XPCNativeInterface> iface = XPCNativeInterface::GetNewOrUsed(mInfo); if (!iface) return NS_OK; uint16_t count = iface->GetMemberCount(); for (uint16_t i = 0; i < count; i++) { XPCNativeMember* member = iface->GetMemberAt(i); if (member && member->IsConstant() && !xpc_ForcePropertyResolve(cx, obj, member->GetName())) { return NS_ERROR_UNEXPECTED; } } return NS_OK; }
static bool ResolveNativeProperty(JSContext *cx, JSObject *wrapper, JSObject *holder, jsid id, bool set, JSPropertyDescriptor *desc) { desc->obj = NULL; NS_ASSERTION(holder->getJSClass() == &HolderClass, "expected a native property holder object"); JSObject *wnObject = GetWrappedNativeObjectFromHolder(holder); XPCWrappedNative *wn = GetWrappedNative(wnObject); // This will do verification and the method lookup for us. XPCCallContext ccx(JS_CALLER, cx, wnObject, nsnull, id); // There are no native numeric properties, so we can shortcut here. We will not // find the property. if (!JSID_IS_ATOM(id)) { /* Not found */ return true; } XPCNativeInterface *iface; XPCNativeMember *member; if (ccx.GetWrapper() != wn || !wn->IsValid() || !(iface = ccx.GetInterface()) || !(member = ccx.GetMember())) { /* Not found */ return true; } desc->obj = holder; desc->attrs = JSPROP_ENUMERATE; desc->getter = NULL; desc->setter = NULL; desc->shortid = 0; desc->value = JSVAL_VOID; jsval fval = JSVAL_VOID; if (member->IsConstant()) { if (!member->GetConstantValue(ccx, iface, &desc->value)) { JS_ReportError(cx, "Failed to convert constant native property to JS value"); return false; } } else if (member->IsAttribute()) { // This is a getter/setter. Clone a function for it. if (!member->NewFunctionObject(ccx, iface, wrapper, &fval)) { JS_ReportError(cx, "Failed to clone function object for native getter/setter"); return false; } desc->attrs |= JSPROP_GETTER; if (member->IsWritableAttribute()) desc->attrs |= JSPROP_SETTER; // Make the property shared on the holder so no slot is allocated // for it. This avoids keeping garbage alive through that slot. desc->attrs |= JSPROP_SHARED; } else { // This is a method. Clone a function for it. if (!member->NewFunctionObject(ccx, iface, wrapper, &desc->value)) { JS_ReportError(cx, "Failed to clone function object for native function"); return false; } // Without a wrapper the function would live on the prototype. Since we // don't have one, we have to avoid calling the scriptable helper's // GetProperty method for this property, so stub out the getter and // setter here explicitly. desc->getter = JS_PropertyStub; desc->setter = JS_StrictPropertyStub; } if (!JS_WrapValue(cx, &desc->value) || !JS_WrapValue(cx, &fval)) return false; if (desc->attrs & JSPROP_GETTER) desc->getter = CastAsJSPropertyOp(JSVAL_TO_OBJECT(fval)); if (desc->attrs & JSPROP_SETTER) desc->setter = CastAsJSStrictPropertyOp(JSVAL_TO_OBJECT(fval)); // Define the property. return JS_DefinePropertyById(cx, holder, id, desc->value, desc->getter, desc->setter, desc->attrs); }