static bool XPC_WN_TearOff_Resolve(JSContext* cx, HandleObject obj, HandleId id, bool* resolvedp) { XPCCallContext ccx(cx, obj); XPCWrappedNative* wrapper = ccx.GetWrapper(); THROW_AND_RETURN_IF_BAD_WRAPPER(cx, wrapper); XPCWrappedNativeTearOff* to = ccx.GetTearOff(); XPCNativeInterface* iface; if (!to || nullptr == (iface = to->GetInterface())) return Throw(NS_ERROR_XPC_BAD_OP_ON_WN_PROTO, cx); return DefinePropertyIfFound(ccx, obj, id, nullptr, iface, nullptr, wrapper->GetScope(), true, nullptr, nullptr, nullptr, JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_ENUMERATE, resolvedp); }
static bool XPC_WN_NoHelper_Resolve(JSContext* cx, HandleObject obj, HandleId id, bool* resolvedp) { XPCCallContext ccx(cx, obj, nullptr, id); XPCWrappedNative* wrapper = ccx.GetWrapper(); THROW_AND_RETURN_IF_BAD_WRAPPER(cx, wrapper); XPCNativeSet* set = ccx.GetSet(); if (!set) return true; // Don't resolve properties that are on our prototype. if (ccx.GetInterface() && !ccx.GetStaticMemberIsLocal()) return true; return DefinePropertyIfFound(ccx, obj, id, set, nullptr, nullptr, wrapper->GetScope(), true, wrapper, wrapper, nullptr, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT, resolvedp); }
JSBool WrapObject(JSContext *cx, JSObject *parent, jsval *vp, XPCWrappedNative* wn) { NS_ASSERTION(XPCPerThreadData::IsMainThread(cx), "Can't do this off the main thread!"); // Our argument should be a wrapped native object, but the caller may have // passed it in as an optimization. JSObject *wrappedObj; if (JSVAL_IS_PRIMITIVE(*vp) || !(wrappedObj = JSVAL_TO_OBJECT(*vp)) || wrappedObj->getClass() == &XOWClass) { return JS_TRUE; } if (!wn && !(wn = XPCWrappedNative::GetAndMorphWrappedNativeOfJSObject(cx, wrappedObj))) { return JS_TRUE; } CheckWindow(wn); // The parent must be the inner global object for its scope. parent = JS_GetGlobalForObject(cx, parent); OBJ_TO_INNER_OBJECT(cx, parent); if (!parent) { return JS_FALSE; } XPCWrappedNativeWithXOW *wnxow = nsnull; if (wn->NeedsXOW()) { JSObject *innerWrappedObj = wrappedObj; OBJ_TO_INNER_OBJECT(cx, innerWrappedObj); if (!innerWrappedObj) { return JS_FALSE; } if (innerWrappedObj == parent) { wnxow = static_cast<XPCWrappedNativeWithXOW *>(wn); JSObject *xow = wnxow->GetXOW(); if (xow) { *vp = OBJECT_TO_JSVAL(xow); return JS_TRUE; } } } XPCWrappedNative *parentwn = XPCWrappedNative::GetWrappedNativeOfJSObject(cx, parent); XPCWrappedNativeScope *parentScope; if (NS_LIKELY(parentwn)) { parentScope = parentwn->GetScope(); } else { parentScope = XPCWrappedNativeScope::FindInJSObjectScope(cx, parent); } JSObject *outerObj = nsnull; WrappedNative2WrapperMap *map = parentScope->GetWrapperMap(); outerObj = map->Find(wrappedObj); if (outerObj) { NS_ASSERTION(outerObj->getClass() == &XOWClass, "What crazy object are we getting here?"); *vp = OBJECT_TO_JSVAL(outerObj); if (wnxow) { // NB: wnxow->GetXOW() must have returned false. SetFlags(cx, outerObj, AddFlags(GetFlags(cx, outerObj), FLAG_IS_CACHED)); wnxow->SetXOW(outerObj); } return JS_TRUE; } outerObj = JS_NewObjectWithGivenProto(cx, js::Jsvalify(&XOWClass), nsnull, parent); if (!outerObj) { return JS_FALSE; } jsval flags = INT_TO_JSVAL(wnxow ? FLAG_IS_CACHED : 0); if (!JS_SetReservedSlot(cx, outerObj, sWrappedObjSlot, *vp) || !JS_SetReservedSlot(cx, outerObj, sFlagsSlot, flags) || !JS_SetReservedSlot(cx, outerObj, XPC_XOW_ScopeSlot, PRIVATE_TO_JSVAL(parentScope))) { return JS_FALSE; } *vp = OBJECT_TO_JSVAL(outerObj); map->Add(wn->GetScope()->GetWrapperMap(), wrappedObj, outerObj); if(wnxow) { wnxow->SetXOW(outerObj); } return JS_TRUE; }
bool XPC_WN_Helper_Resolve(JSContext* cx, HandleObject obj, HandleId id, bool* resolvedp) { nsresult rv = NS_OK; bool retval = true; bool resolved = false; XPCCallContext ccx(cx, obj); XPCWrappedNative* wrapper = ccx.GetWrapper(); THROW_AND_RETURN_IF_BAD_WRAPPER(cx, wrapper); RootedId old(cx, ccx.SetResolveName(id)); XPCNativeScriptableInfo* si = wrapper->GetScriptableInfo(); if (si && si->GetFlags().WantResolve()) { XPCWrappedNative* oldResolvingWrapper; bool allowPropMods = si->GetFlags().AllowPropModsDuringResolve(); if (allowPropMods) oldResolvingWrapper = ccx.SetResolvingWrapper(wrapper); rv = si->GetCallback()->Resolve(wrapper, cx, obj, id, &resolved, &retval); if (allowPropMods) (void)ccx.SetResolvingWrapper(oldResolvingWrapper); } old = ccx.SetResolveName(old); MOZ_ASSERT(old == id, "bad nest"); if (NS_FAILED(rv)) { return Throw(rv, cx); } if (resolved) { *resolvedp = true; } else if (wrapper->HasMutatedSet()) { // We are here if scriptable did not resolve this property and // it *might* be in the instance set but not the proto set. XPCNativeSet* set = wrapper->GetSet(); XPCNativeSet* protoSet = wrapper->HasProto() ? wrapper->GetProto()->GetSet() : nullptr; XPCNativeMember* member = nullptr; RefPtr<XPCNativeInterface> iface; bool IsLocal = false; if (set->FindMember(id, &member, &iface, protoSet, &IsLocal) && IsLocal) { XPCWrappedNative* oldResolvingWrapper; XPCNativeScriptableFlags siFlags(0); if (si) siFlags = si->GetFlags(); XPCWrappedNative* wrapperForInterfaceNames = siFlags.DontReflectInterfaceNames() ? nullptr : wrapper; oldResolvingWrapper = ccx.SetResolvingWrapper(wrapper); retval = DefinePropertyIfFound(ccx, obj, id, set, iface, member, wrapper->GetScope(), false, wrapperForInterfaceNames, nullptr, si, JSPROP_ENUMERATE, resolvedp); (void)ccx.SetResolvingWrapper(oldResolvingWrapper); } } return retval; }