bool XPC_WN_Shared_Enumerate(JSContext* cx, HandleObject obj) { XPCCallContext ccx(cx, obj); XPCWrappedNative* wrapper = ccx.GetWrapper(); THROW_AND_RETURN_IF_BAD_WRAPPER(cx, wrapper); // Since we aren't going to enumerate tearoff names and the prototype // handles non-mutated members, we can do this potential short-circuit. if (!wrapper->HasMutatedSet()) return true; XPCNativeSet* set = wrapper->GetSet(); XPCNativeSet* protoSet = wrapper->HasProto() ? wrapper->GetProto()->GetSet() : nullptr; uint16_t interface_count = set->GetInterfaceCount(); XPCNativeInterface** interfaceArray = set->GetInterfaceArray(); for (uint16_t i = 0; i < interface_count; i++) { XPCNativeInterface* iface = interfaceArray[i]; uint16_t member_count = iface->GetMemberCount(); for (uint16_t k = 0; k < member_count; k++) { XPCNativeMember* member = iface->GetMemberAt(k); jsid name = member->GetName(); // Skip if this member is going to come from the proto. uint16_t index; if (protoSet && protoSet->FindMember(name, nullptr, &index) && index == i) continue; if (!xpc_ForcePropertyResolve(cx, obj, name)) return false; } } return 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; }