/* THIS FILE IS AUTOGENERATED FROM AudioNode.webidl BY Codegen.py - DO NOT EDIT */ #include "AtomList.h" #include "AudioNodeBinding.h" #include "EventTargetBinding.h" #include "WrapperFactory.h" #include "jsapi.h" #include "mozilla/OwningNonNull.h" #include "mozilla/Preferences.h" #include "mozilla/dom/AudioContext.h" #include "mozilla/dom/AudioNode.h" #include "mozilla/dom/AudioParam.h" #include "mozilla/dom/BindingUtils.h" #include "mozilla/dom/DOMJSClass.h" #include "mozilla/dom/NonRefcountedDOMObject.h" #include "mozilla/dom/PrimitiveConversions.h" #include "mozilla/dom/ScriptSettings.h" #include "mozilla/dom/SimpleGlobalObject.h" #include "mozilla/dom/XrayExpandoClass.h" #include "nsContentUtils.h" namespace mozilla { namespace dom { namespace ChannelCountModeValues { extern const EnumEntry strings[4] = { {"max", 3}, {"clamped-max", 11}, {"explicit", 8}, { nullptr, 0 } }; } // namespace ChannelCountModeValues bool ToJSValue(JSContext* aCx, ChannelCountMode aArgument, JS::MutableHandle aValue) { MOZ_ASSERT(uint32_t(aArgument) < ArrayLength(ChannelCountModeValues::strings)); JSString* resultStr = JS_NewStringCopyN(aCx, ChannelCountModeValues::strings[uint32_t(aArgument)].value, ChannelCountModeValues::strings[uint32_t(aArgument)].length); if (!resultStr) { return false; } aValue.setString(resultStr); return true; } namespace ChannelInterpretationValues { extern const EnumEntry strings[3] = { {"speakers", 8}, {"discrete", 8}, { nullptr, 0 } }; } // namespace ChannelInterpretationValues bool ToJSValue(JSContext* aCx, ChannelInterpretation aArgument, JS::MutableHandle aValue) { MOZ_ASSERT(uint32_t(aArgument) < ArrayLength(ChannelInterpretationValues::strings)); JSString* resultStr = JS_NewStringCopyN(aCx, ChannelInterpretationValues::strings[uint32_t(aArgument)].value, ChannelInterpretationValues::strings[uint32_t(aArgument)].length); if (!resultStr) { return false; } aValue.setString(resultStr); return true; } AudioNodeOptions::AudioNodeOptions() { // Safe to pass a null context if we pass a null value Init(nullptr, JS::NullHandleValue); } bool AudioNodeOptions::InitIds(JSContext* cx, AudioNodeOptionsAtoms* atomsCache) { MOZ_ASSERT(!*reinterpret_cast(atomsCache)); // Initialize these in reverse order so that any failure leaves the first one // uninitialized. if (!atomsCache->channelInterpretation_id.init(cx, "channelInterpretation") || !atomsCache->channelCountMode_id.init(cx, "channelCountMode") || !atomsCache->channelCount_id.init(cx, "channelCount")) { return false; } return true; } bool AudioNodeOptions::Init(JSContext* cx, JS::Handle val, const char* sourceDescription, bool passedToJSImpl) { // Passing a null JSContext is OK only if we're initing from null, // Since in that case we will not have to do any property gets // Also evaluate isNullOrUndefined in order to avoid false-positive // checkers by static analysis tools MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined()); AudioNodeOptionsAtoms* atomsCache = nullptr; if (cx) { atomsCache = GetAtomCache(cx); if (!*reinterpret_cast(atomsCache) && !InitIds(cx, atomsCache)) { return false; } } if (!IsConvertibleToDictionary(val)) { return ThrowErrorMessage(cx, MSG_NOT_DICTIONARY, sourceDescription); } bool isNull = val.isNullOrUndefined(); // We only need these if !isNull, in which case we have |cx|. Maybe > object; Maybe > temp; if (!isNull) { MOZ_ASSERT(cx); object.emplace(cx, &val.toObject()); temp.emplace(cx); } if (!isNull) { if (!JS_GetPropertyById(cx, *object, atomsCache->channelCount_id, temp.ptr())) { return false; } } if (!isNull && !temp->isUndefined()) { mChannelCount.Construct(); if (!ValueToPrimitive(cx, temp.ref(), &(mChannelCount.Value()))) { return false; } mIsAnyMemberPresent = true; } if (!isNull) { if (!JS_GetPropertyById(cx, *object, atomsCache->channelCountMode_id, temp.ptr())) { return false; } } if (!isNull && !temp->isUndefined()) { mChannelCountMode.Construct(); { int index; if (!FindEnumStringIndex(cx, temp.ref(), ChannelCountModeValues::strings, "ChannelCountMode", "'channelCountMode' member of AudioNodeOptions", &index)) { return false; } MOZ_ASSERT(index >= 0); (mChannelCountMode.Value()) = static_cast(index); } mIsAnyMemberPresent = true; } if (!isNull) { if (!JS_GetPropertyById(cx, *object, atomsCache->channelInterpretation_id, temp.ptr())) { return false; } } if (!isNull && !temp->isUndefined()) { mChannelInterpretation.Construct(); { int index; if (!FindEnumStringIndex(cx, temp.ref(), ChannelInterpretationValues::strings, "ChannelInterpretation", "'channelInterpretation' member of AudioNodeOptions", &index)) { return false; } MOZ_ASSERT(index >= 0); (mChannelInterpretation.Value()) = static_cast(index); } mIsAnyMemberPresent = true; } return true; } bool AudioNodeOptions::Init(const nsAString& aJSON) { AutoJSAPI jsapi; JSObject* cleanGlobal = SimpleGlobalObject::Create(SimpleGlobalObject::GlobalType::BindingDetail); if (!cleanGlobal) { return false; } if (!jsapi.Init(cleanGlobal)) { return false; } JSContext* cx = jsapi.cx(); JS::Rooted json(cx); bool ok = ParseJSON(cx, aJSON, &json); NS_ENSURE_TRUE(ok, false); return Init(cx, json); } bool AudioNodeOptions::ToObjectInternal(JSContext* cx, JS::MutableHandle rval) const { AudioNodeOptionsAtoms* atomsCache = GetAtomCache(cx); if (!*reinterpret_cast(atomsCache) && !InitIds(cx, atomsCache)) { return false; } JS::Rooted obj(cx, JS_NewPlainObject(cx)); if (!obj) { return false; } rval.set(JS::ObjectValue(*obj)); if (mChannelCount.WasPassed()) { do { // block for our 'break' successCode and scope for 'temp' and 'currentValue' JS::Rooted temp(cx); uint32_t const & currentValue = mChannelCount.InternalValue(); temp.setNumber(currentValue); if (!JS_DefinePropertyById(cx, obj, atomsCache->channelCount_id, temp, JSPROP_ENUMERATE)) { return false; } break; } while(0); } if (mChannelCountMode.WasPassed()) { do { // block for our 'break' successCode and scope for 'temp' and 'currentValue' JS::Rooted temp(cx); ChannelCountMode const & currentValue = mChannelCountMode.InternalValue(); if (!ToJSValue(cx, currentValue, &temp)) { return false; } if (!JS_DefinePropertyById(cx, obj, atomsCache->channelCountMode_id, temp, JSPROP_ENUMERATE)) { return false; } break; } while(0); } if (mChannelInterpretation.WasPassed()) { do { // block for our 'break' successCode and scope for 'temp' and 'currentValue' JS::Rooted temp(cx); ChannelInterpretation const & currentValue = mChannelInterpretation.InternalValue(); if (!ToJSValue(cx, currentValue, &temp)) { return false; } if (!JS_DefinePropertyById(cx, obj, atomsCache->channelInterpretation_id, temp, JSPROP_ENUMERATE)) { return false; } break; } while(0); } return true; } bool AudioNodeOptions::ToJSON(nsAString& aJSON) const { AutoJSAPI jsapi; jsapi.Init(); JSContext *cx = jsapi.cx(); // It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here // because we'll only be creating objects, in ways that have no // side-effects, followed by a call to JS::ToJSONMaybeSafely, // which likewise guarantees no side-effects for the sorts of // things we will pass it. JSAutoCompartment ac(cx, binding_detail::UnprivilegedJunkScopeOrWorkerGlobal()); JS::Rooted val(cx); if (!ToObjectInternal(cx, &val)) { return false; } JS::Rooted obj(cx, &val.toObject()); return StringifyToJSON(cx, obj, aJSON); } void AudioNodeOptions::TraceDictionary(JSTracer* trc) { } AudioNodeOptions& AudioNodeOptions::operator=(const AudioNodeOptions& aOther) { mChannelCount.Reset(); if (aOther.mChannelCount.WasPassed()) { mChannelCount.Construct(aOther.mChannelCount.Value()); } mChannelCountMode.Reset(); if (aOther.mChannelCountMode.WasPassed()) { mChannelCountMode.Construct(aOther.mChannelCountMode.Value()); } mChannelInterpretation.Reset(); if (aOther.mChannelInterpretation.WasPassed()) { mChannelInterpretation.Construct(aOther.mChannelInterpretation.Value()); } return *this; } namespace binding_detail { } // namespace binding_detail namespace AudioNodeBinding { static_assert(IsRefcounted::value == IsRefcounted::value, "Can't inherit from an interface with a different ownership model."); static bool connect(JSContext* cx, JS::Handle obj, mozilla::dom::AudioNode* self, const JSJitMethodCallArgs& args) { unsigned argcount = std::min(args.length(), 3u); switch (argcount) { case 1: { MOZ_FALLTHROUGH; } case 2: { if (args[0].isObject()) { do { NonNull arg0; { nsresult rv = UnwrapObject(args[0], arg0); if (NS_FAILED(rv)) { break; } } uint32_t arg1; if (args.hasDefined(1)) { if (!ValueToPrimitive(cx, args[1], &arg1)) { return false; } } else { arg1 = 0U; } uint32_t arg2; if (args.hasDefined(2)) { if (!ValueToPrimitive(cx, args[2], &arg2)) { return false; } } else { arg2 = 0U; } binding_detail::FastErrorResult rv; auto result(StrongOrRawPtr(self->Connect(NonNullHelper(arg0), arg1, arg2, rv))); if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) { return false; } MOZ_ASSERT(!JS_IsExceptionPending(cx)); if (!GetOrCreateDOMReflector(cx, result, args.rval())) { MOZ_ASSERT(true || JS_IsExceptionPending(cx)); return false; } return true; } while (0); do { NonNull arg0; { nsresult rv = UnwrapObject(args[0], arg0); if (NS_FAILED(rv)) { break; } } uint32_t arg1; if (args.hasDefined(1)) { if (!ValueToPrimitive(cx, args[1], &arg1)) { return false; } } else { arg1 = 0U; } binding_detail::FastErrorResult rv; self->Connect(NonNullHelper(arg0), arg1, rv); if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) { return false; } MOZ_ASSERT(!JS_IsExceptionPending(cx)); args.rval().setUndefined(); return true; } while (0); } return ThrowErrorMessage(cx, MSG_OVERLOAD_RESOLUTION_FAILED, "1", "2", "AudioNode.connect"); break; } case 3: { NonNull arg0; if (args[0].isObject()) { { nsresult rv = UnwrapObject(args[0], arg0); if (NS_FAILED(rv)) { ThrowErrorMessage(cx, MSG_DOES_NOT_IMPLEMENT_INTERFACE, "Argument 1 of AudioNode.connect", "AudioNode"); return false; } } } else { ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 1 of AudioNode.connect"); return false; } uint32_t arg1; if (args.hasDefined(1)) { if (!ValueToPrimitive(cx, args[1], &arg1)) { return false; } } else { arg1 = 0U; } uint32_t arg2; if (args.hasDefined(2)) { if (!ValueToPrimitive(cx, args[2], &arg2)) { return false; } } else { arg2 = 0U; } binding_detail::FastErrorResult rv; auto result(StrongOrRawPtr(self->Connect(NonNullHelper(arg0), arg1, arg2, rv))); if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) { return false; } MOZ_ASSERT(!JS_IsExceptionPending(cx)); if (!GetOrCreateDOMReflector(cx, result, args.rval())) { MOZ_ASSERT(true || JS_IsExceptionPending(cx)); return false; } return true; break; } default: { return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "AudioNode.connect"); break; } } MOZ_CRASH("We have an always-returning default case"); return false; } static const JSJitInfo connect_methodinfo = { { (JSJitGetterOp)connect }, { prototypes::id::AudioNode }, { PrototypeTraits::Depth }, JSJitInfo::Method, JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */ JSVAL_TYPE_UNKNOWN, /* returnType. Not relevant for setters. */ false, /* isInfallible. False in setters. */ false, /* isMovable. Not relevant for setters. */ false, /* isEliminatable. Not relevant for setters. */ false, /* isAlwaysInSlot. Only relevant for getters. */ false, /* isLazilyCachedInSlot. Only relevant for getters. */ false, /* isTypedMethod. Only relevant for methods. */ 0 /* Reserved slot index, if we're stored in a slot, else 0. */ }; static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit"); static_assert(0 < 1, "There is no slot for us"); static bool disconnect(JSContext* cx, JS::Handle obj, mozilla::dom::AudioNode* self, const JSJitMethodCallArgs& args) { unsigned argcount = std::min(args.length(), 3u); switch (argcount) { case 0: { binding_detail::FastErrorResult rv; self->Disconnect(rv); if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) { return false; } MOZ_ASSERT(!JS_IsExceptionPending(cx)); args.rval().setUndefined(); return true; break; } case 1: { if (args[0].isObject()) { do { NonNull arg0; { nsresult rv = UnwrapObject(args[0], arg0); if (NS_FAILED(rv)) { break; } } binding_detail::FastErrorResult rv; self->Disconnect(NonNullHelper(arg0), rv); if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) { return false; } MOZ_ASSERT(!JS_IsExceptionPending(cx)); args.rval().setUndefined(); return true; } while (0); do { NonNull arg0; { nsresult rv = UnwrapObject(args[0], arg0); if (NS_FAILED(rv)) { break; } } binding_detail::FastErrorResult rv; self->Disconnect(NonNullHelper(arg0), rv); if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) { return false; } MOZ_ASSERT(!JS_IsExceptionPending(cx)); args.rval().setUndefined(); return true; } while (0); } uint32_t arg0; if (!ValueToPrimitive(cx, args[0], &arg0)) { return false; } binding_detail::FastErrorResult rv; self->Disconnect(arg0, rv); if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) { return false; } MOZ_ASSERT(!JS_IsExceptionPending(cx)); args.rval().setUndefined(); return true; break; } case 2: { if (args[0].isObject()) { do { NonNull arg0; { nsresult rv = UnwrapObject(args[0], arg0); if (NS_FAILED(rv)) { break; } } uint32_t arg1; if (!ValueToPrimitive(cx, args[1], &arg1)) { return false; } binding_detail::FastErrorResult rv; self->Disconnect(NonNullHelper(arg0), arg1, rv); if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) { return false; } MOZ_ASSERT(!JS_IsExceptionPending(cx)); args.rval().setUndefined(); return true; } while (0); do { NonNull arg0; { nsresult rv = UnwrapObject(args[0], arg0); if (NS_FAILED(rv)) { break; } } uint32_t arg1; if (!ValueToPrimitive(cx, args[1], &arg1)) { return false; } binding_detail::FastErrorResult rv; self->Disconnect(NonNullHelper(arg0), arg1, rv); if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) { return false; } MOZ_ASSERT(!JS_IsExceptionPending(cx)); args.rval().setUndefined(); return true; } while (0); } return ThrowErrorMessage(cx, MSG_OVERLOAD_RESOLUTION_FAILED, "1", "2", "AudioNode.disconnect"); break; } case 3: { NonNull arg0; if (args[0].isObject()) { { nsresult rv = UnwrapObject(args[0], arg0); if (NS_FAILED(rv)) { ThrowErrorMessage(cx, MSG_DOES_NOT_IMPLEMENT_INTERFACE, "Argument 1 of AudioNode.disconnect", "AudioNode"); return false; } } } else { ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 1 of AudioNode.disconnect"); return false; } uint32_t arg1; if (!ValueToPrimitive(cx, args[1], &arg1)) { return false; } uint32_t arg2; if (!ValueToPrimitive(cx, args[2], &arg2)) { return false; } binding_detail::FastErrorResult rv; self->Disconnect(NonNullHelper(arg0), arg1, arg2, rv); if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) { return false; } MOZ_ASSERT(!JS_IsExceptionPending(cx)); args.rval().setUndefined(); return true; break; } default: { return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "AudioNode.disconnect"); break; } } MOZ_CRASH("We have an always-returning default case"); return false; } static const JSJitInfo disconnect_methodinfo = { { (JSJitGetterOp)disconnect }, { prototypes::id::AudioNode }, { PrototypeTraits::Depth }, JSJitInfo::Method, JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */ JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */ false, /* isInfallible. False in setters. */ false, /* isMovable. Not relevant for setters. */ false, /* isEliminatable. Not relevant for setters. */ false, /* isAlwaysInSlot. Only relevant for getters. */ false, /* isLazilyCachedInSlot. Only relevant for getters. */ false, /* isTypedMethod. Only relevant for methods. */ 0 /* Reserved slot index, if we're stored in a slot, else 0. */ }; static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit"); static_assert(0 < 1, "There is no slot for us"); static bool get_context(JSContext* cx, JS::Handle obj, mozilla::dom::AudioNode* self, JSJitGetterCallArgs args) { auto result(StrongOrRawPtr(self->Context())); MOZ_ASSERT(!JS_IsExceptionPending(cx)); if (!GetOrCreateDOMReflector(cx, result, args.rval())) { MOZ_ASSERT(true || JS_IsExceptionPending(cx)); return false; } return true; } static const JSJitInfo context_getterinfo = { { (JSJitGetterOp)get_context }, { prototypes::id::AudioNode }, { PrototypeTraits::Depth }, JSJitInfo::Getter, JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */ JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */ false, /* isInfallible. False in setters. */ false, /* isMovable. Not relevant for setters. */ false, /* isEliminatable. Not relevant for setters. */ false, /* isAlwaysInSlot. Only relevant for getters. */ false, /* isLazilyCachedInSlot. Only relevant for getters. */ false, /* isTypedMethod. Only relevant for methods. */ 0 /* Reserved slot index, if we're stored in a slot, else 0. */ }; static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit"); static_assert(0 < 1, "There is no slot for us"); static bool get_numberOfInputs(JSContext* cx, JS::Handle obj, mozilla::dom::AudioNode* self, JSJitGetterCallArgs args) { uint32_t result(self->NumberOfInputs()); MOZ_ASSERT(!JS_IsExceptionPending(cx)); args.rval().setNumber(result); return true; } static const JSJitInfo numberOfInputs_getterinfo = { { (JSJitGetterOp)get_numberOfInputs }, { prototypes::id::AudioNode }, { PrototypeTraits::Depth }, JSJitInfo::Getter, JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */ JSVAL_TYPE_DOUBLE, /* returnType. Not relevant for setters. */ true, /* isInfallible. False in setters. */ false, /* isMovable. Not relevant for setters. */ false, /* isEliminatable. Not relevant for setters. */ false, /* isAlwaysInSlot. Only relevant for getters. */ false, /* isLazilyCachedInSlot. Only relevant for getters. */ false, /* isTypedMethod. Only relevant for methods. */ 0 /* Reserved slot index, if we're stored in a slot, else 0. */ }; static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit"); static_assert(0 < 1, "There is no slot for us"); static bool get_numberOfOutputs(JSContext* cx, JS::Handle obj, mozilla::dom::AudioNode* self, JSJitGetterCallArgs args) { uint32_t result(self->NumberOfOutputs()); MOZ_ASSERT(!JS_IsExceptionPending(cx)); args.rval().setNumber(result); return true; } static const JSJitInfo numberOfOutputs_getterinfo = { { (JSJitGetterOp)get_numberOfOutputs }, { prototypes::id::AudioNode }, { PrototypeTraits::Depth }, JSJitInfo::Getter, JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */ JSVAL_TYPE_DOUBLE, /* returnType. Not relevant for setters. */ true, /* isInfallible. False in setters. */ false, /* isMovable. Not relevant for setters. */ false, /* isEliminatable. Not relevant for setters. */ false, /* isAlwaysInSlot. Only relevant for getters. */ false, /* isLazilyCachedInSlot. Only relevant for getters. */ false, /* isTypedMethod. Only relevant for methods. */ 0 /* Reserved slot index, if we're stored in a slot, else 0. */ }; static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit"); static_assert(0 < 1, "There is no slot for us"); static bool get_channelCount(JSContext* cx, JS::Handle obj, mozilla::dom::AudioNode* self, JSJitGetterCallArgs args) { uint32_t result(self->ChannelCount()); MOZ_ASSERT(!JS_IsExceptionPending(cx)); args.rval().setNumber(result); return true; } static bool set_channelCount(JSContext* cx, JS::Handle obj, mozilla::dom::AudioNode* self, JSJitSetterCallArgs args) { uint32_t arg0; if (!ValueToPrimitive(cx, args[0], &arg0)) { return false; } binding_detail::FastErrorResult rv; self->SetChannelCount(arg0, rv); if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) { return false; } MOZ_ASSERT(!JS_IsExceptionPending(cx)); return true; } static const JSJitInfo channelCount_getterinfo = { { (JSJitGetterOp)get_channelCount }, { prototypes::id::AudioNode }, { PrototypeTraits::Depth }, JSJitInfo::Getter, JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */ JSVAL_TYPE_DOUBLE, /* returnType. Not relevant for setters. */ true, /* isInfallible. False in setters. */ false, /* isMovable. Not relevant for setters. */ false, /* isEliminatable. Not relevant for setters. */ false, /* isAlwaysInSlot. Only relevant for getters. */ false, /* isLazilyCachedInSlot. Only relevant for getters. */ false, /* isTypedMethod. Only relevant for methods. */ 0 /* Reserved slot index, if we're stored in a slot, else 0. */ }; static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit"); static_assert(0 < 1, "There is no slot for us"); static const JSJitInfo channelCount_setterinfo = { { (JSJitGetterOp)set_channelCount }, { prototypes::id::AudioNode }, { PrototypeTraits::Depth }, JSJitInfo::Setter, JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */ JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */ false, /* isInfallible. False in setters. */ false, /* isMovable. Not relevant for setters. */ false, /* isEliminatable. Not relevant for setters. */ false, /* isAlwaysInSlot. Only relevant for getters. */ false, /* isLazilyCachedInSlot. Only relevant for getters. */ false, /* isTypedMethod. Only relevant for methods. */ 0 /* Reserved slot index, if we're stored in a slot, else 0. */ }; static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit"); static_assert(0 < 1, "There is no slot for us"); static bool get_channelCountMode(JSContext* cx, JS::Handle obj, mozilla::dom::AudioNode* self, JSJitGetterCallArgs args) { ChannelCountMode result(self->ChannelCountModeValue()); MOZ_ASSERT(!JS_IsExceptionPending(cx)); if (!ToJSValue(cx, result, args.rval())) { return false; } return true; } static bool set_channelCountMode(JSContext* cx, JS::Handle obj, mozilla::dom::AudioNode* self, JSJitSetterCallArgs args) { ChannelCountMode arg0; { int index; if (!FindEnumStringIndex(cx, args[0], ChannelCountModeValues::strings, "ChannelCountMode", "Value being assigned to AudioNode.channelCountMode", &index)) { return false; } if (index < 0) { return true; } arg0 = static_cast(index); } binding_detail::FastErrorResult rv; self->SetChannelCountModeValue(arg0, rv); if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) { return false; } MOZ_ASSERT(!JS_IsExceptionPending(cx)); return true; } static const JSJitInfo channelCountMode_getterinfo = { { (JSJitGetterOp)get_channelCountMode }, { prototypes::id::AudioNode }, { PrototypeTraits::Depth }, JSJitInfo::Getter, JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */ JSVAL_TYPE_STRING, /* returnType. Not relevant for setters. */ false, /* isInfallible. False in setters. */ false, /* isMovable. Not relevant for setters. */ false, /* isEliminatable. Not relevant for setters. */ false, /* isAlwaysInSlot. Only relevant for getters. */ false, /* isLazilyCachedInSlot. Only relevant for getters. */ false, /* isTypedMethod. Only relevant for methods. */ 0 /* Reserved slot index, if we're stored in a slot, else 0. */ }; static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit"); static_assert(0 < 1, "There is no slot for us"); static const JSJitInfo channelCountMode_setterinfo = { { (JSJitGetterOp)set_channelCountMode }, { prototypes::id::AudioNode }, { PrototypeTraits::Depth }, JSJitInfo::Setter, JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */ JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */ false, /* isInfallible. False in setters. */ false, /* isMovable. Not relevant for setters. */ false, /* isEliminatable. Not relevant for setters. */ false, /* isAlwaysInSlot. Only relevant for getters. */ false, /* isLazilyCachedInSlot. Only relevant for getters. */ false, /* isTypedMethod. Only relevant for methods. */ 0 /* Reserved slot index, if we're stored in a slot, else 0. */ }; static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit"); static_assert(0 < 1, "There is no slot for us"); static bool get_channelInterpretation(JSContext* cx, JS::Handle obj, mozilla::dom::AudioNode* self, JSJitGetterCallArgs args) { ChannelInterpretation result(self->ChannelInterpretationValue()); MOZ_ASSERT(!JS_IsExceptionPending(cx)); if (!ToJSValue(cx, result, args.rval())) { return false; } return true; } static bool set_channelInterpretation(JSContext* cx, JS::Handle obj, mozilla::dom::AudioNode* self, JSJitSetterCallArgs args) { ChannelInterpretation arg0; { int index; if (!FindEnumStringIndex(cx, args[0], ChannelInterpretationValues::strings, "ChannelInterpretation", "Value being assigned to AudioNode.channelInterpretation", &index)) { return false; } if (index < 0) { return true; } arg0 = static_cast(index); } self->SetChannelInterpretationValue(arg0); MOZ_ASSERT(!JS_IsExceptionPending(cx)); return true; } static const JSJitInfo channelInterpretation_getterinfo = { { (JSJitGetterOp)get_channelInterpretation }, { prototypes::id::AudioNode }, { PrototypeTraits::Depth }, JSJitInfo::Getter, JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */ JSVAL_TYPE_STRING, /* returnType. Not relevant for setters. */ false, /* isInfallible. False in setters. */ false, /* isMovable. Not relevant for setters. */ false, /* isEliminatable. Not relevant for setters. */ false, /* isAlwaysInSlot. Only relevant for getters. */ false, /* isLazilyCachedInSlot. Only relevant for getters. */ false, /* isTypedMethod. Only relevant for methods. */ 0 /* Reserved slot index, if we're stored in a slot, else 0. */ }; static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit"); static_assert(0 < 1, "There is no slot for us"); static const JSJitInfo channelInterpretation_setterinfo = { { (JSJitGetterOp)set_channelInterpretation }, { prototypes::id::AudioNode }, { PrototypeTraits::Depth }, JSJitInfo::Setter, JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */ JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */ false, /* isInfallible. False in setters. */ false, /* isMovable. Not relevant for setters. */ false, /* isEliminatable. Not relevant for setters. */ false, /* isAlwaysInSlot. Only relevant for getters. */ false, /* isLazilyCachedInSlot. Only relevant for getters. */ false, /* isTypedMethod. Only relevant for methods. */ 0 /* Reserved slot index, if we're stored in a slot, else 0. */ }; static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit"); static_assert(0 < 1, "There is no slot for us"); static bool get_id(JSContext* cx, JS::Handle obj, mozilla::dom::AudioNode* self, JSJitGetterCallArgs args) { uint32_t result(self->Id()); MOZ_ASSERT(!JS_IsExceptionPending(cx)); args.rval().setNumber(result); return true; } static const JSJitInfo id_getterinfo = { { (JSJitGetterOp)get_id }, { prototypes::id::AudioNode }, { PrototypeTraits::Depth }, JSJitInfo::Getter, JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */ JSVAL_TYPE_DOUBLE, /* returnType. Not relevant for setters. */ true, /* isInfallible. False in setters. */ false, /* isMovable. Not relevant for setters. */ false, /* isEliminatable. Not relevant for setters. */ false, /* isAlwaysInSlot. Only relevant for getters. */ false, /* isLazilyCachedInSlot. Only relevant for getters. */ false, /* isTypedMethod. Only relevant for methods. */ 0 /* Reserved slot index, if we're stored in a slot, else 0. */ }; static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit"); static_assert(0 < 1, "There is no slot for us"); // We deliberately use brace-elision to make Visual Studio produce better initalization code. #if defined(__clang__) #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wmissing-braces" #endif static const JSFunctionSpec sMethods_specs[] = { JS_FNSPEC("connect", GenericBindingMethod, reinterpret_cast(&connect_methodinfo), 1, JSPROP_ENUMERATE, nullptr), JS_FNSPEC("disconnect", GenericBindingMethod, reinterpret_cast(&disconnect_methodinfo), 0, JSPROP_ENUMERATE, nullptr), JS_FS_END }; #if defined(__clang__) #pragma clang diagnostic pop #endif // Can't be const because the pref-enabled boolean needs to be writable static Prefable sMethods[] = { { nullptr, &sMethods_specs[0] }, { nullptr, nullptr } }; static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX, "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)"); static_assert(2 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX, "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)"); // We deliberately use brace-elision to make Visual Studio produce better initalization code. #if defined(__clang__) #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wmissing-braces" #endif static const JSPropertySpec sAttributes_specs[] = { { "context", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &context_getterinfo, nullptr, nullptr }, { "numberOfInputs", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &numberOfInputs_getterinfo, nullptr, nullptr }, { "numberOfOutputs", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &numberOfOutputs_getterinfo, nullptr, nullptr }, { "channelCount", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &channelCount_getterinfo, GenericBindingSetter, &channelCount_setterinfo }, { "channelCountMode", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &channelCountMode_getterinfo, GenericBindingSetter, &channelCountMode_setterinfo }, { "channelInterpretation", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &channelInterpretation_getterinfo, GenericBindingSetter, &channelInterpretation_setterinfo }, { nullptr, 0, nullptr, nullptr, nullptr, nullptr } }; #if defined(__clang__) #pragma clang diagnostic pop #endif // Can't be const because the pref-enabled boolean needs to be writable static Prefable sAttributes[] = { { nullptr, &sAttributes_specs[0] }, { nullptr, nullptr } }; static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX, "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)"); static_assert(6 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX, "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)"); // We deliberately use brace-elision to make Visual Studio produce better initalization code. #if defined(__clang__) #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wmissing-braces" #endif static const JSPropertySpec sChromeAttributes_specs[] = { { "id", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &id_getterinfo, nullptr, nullptr }, { nullptr, 0, nullptr, nullptr, nullptr, nullptr } }; #if defined(__clang__) #pragma clang diagnostic pop #endif // Can't be const because the pref-enabled boolean needs to be writable static Prefable sChromeAttributes[] = { { nullptr, &sChromeAttributes_specs[0] }, { nullptr, nullptr } }; static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX, "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)"); static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX, "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)"); static uint16_t sNativeProperties_sortedPropertyIndices[8]; static PropertyInfo sNativeProperties_propertyInfos[8]; static const NativePropertiesN<2> sNativeProperties = { false, 0, false, 0, true, 0 /* sMethods */, true, 1 /* sAttributes */, false, 0, false, 0, false, 0, -1, 8, sNativeProperties_sortedPropertyIndices, { { sMethods, &sNativeProperties_propertyInfos[0] }, { sAttributes, &sNativeProperties_propertyInfos[2] } } }; static_assert(8 < 1ull << CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount), "We have a property info count that is oversized"); static uint16_t sChromeOnlyNativeProperties_sortedPropertyIndices[1]; static PropertyInfo sChromeOnlyNativeProperties_propertyInfos[1]; static const NativePropertiesN<1> sChromeOnlyNativeProperties = { false, 0, false, 0, false, 0, true, 0 /* sChromeAttributes */, false, 0, false, 0, false, 0, -1, 1, sChromeOnlyNativeProperties_sortedPropertyIndices, { { sChromeAttributes, &sChromeOnlyNativeProperties_propertyInfos[0] } } }; static_assert(1 < 1ull << CHAR_BIT * sizeof(sChromeOnlyNativeProperties.propertyInfoCount), "We have a property info count that is oversized"); static const DOMIfaceAndProtoJSClass sInterfaceObjectClass = { { "Function", JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_SLOTS_BASE), &sBoringInterfaceObjectClassClassOps, JS_NULL_CLASS_SPEC, JS_NULL_CLASS_EXT, &sInterfaceObjectClassObjectOps }, eInterface, true, prototypes::id::AudioNode, PrototypeTraits::Depth, sNativePropertyHooks, "function AudioNode() {\n [native code]\n}", EventTargetBinding::GetConstructorObject }; static const DOMIfaceAndProtoJSClass sPrototypeClass = { { "AudioNodePrototype", JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE), JS_NULL_CLASS_OPS, JS_NULL_CLASS_SPEC, JS_NULL_CLASS_EXT, JS_NULL_OBJECT_OPS }, eInterfacePrototype, false, prototypes::id::AudioNode, PrototypeTraits::Depth, sNativePropertyHooks, "[object AudioNodePrototype]", EventTargetBinding::GetProtoObject }; bool ConstructorEnabled(JSContext* aCx, JS::Handle aObj) { static bool sPrefValue; static bool sPrefCacheSetUp = false; if (!sPrefCacheSetUp) { sPrefCacheSetUp = true; Preferences::AddBoolVarCache(&sPrefValue, "dom.webaudio.enabled"); } return sPrefValue; } JSObject* DefineDOMInterface(JSContext* aCx, JS::Handle aGlobal, JS::Handle id, bool aDefineOnGlobal) { return GetConstructorObjectHandle(aCx, aDefineOnGlobal); } const NativePropertyHooks sNativePropertyHooks[] = { { nullptr, nullptr, nullptr, { sNativeProperties.Upcast(), sChromeOnlyNativeProperties.Upcast() }, prototypes::id::AudioNode, constructors::id::AudioNode, EventTargetBinding::sNativePropertyHooks, &DefaultXrayExpandoObjectClass } }; void CreateInterfaceObjects(JSContext* aCx, JS::Handle aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, bool aDefineOnGlobal) { JS::Handle parentProto(EventTargetBinding::GetProtoObjectHandle(aCx)); if (!parentProto) { return; } JS::Handle constructorProto(EventTargetBinding::GetConstructorObjectHandle(aCx)); if (!constructorProto) { return; } static bool sIdsInited = false; if (!sIdsInited && NS_IsMainThread()) { if (!InitIds(aCx, sNativeProperties.Upcast())) { return; } if (!InitIds(aCx, sChromeOnlyNativeProperties.Upcast())) { return; } sIdsInited = true; } JS::Heap* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::AudioNode); JS::Heap* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::AudioNode); dom::CreateInterfaceObjects(aCx, aGlobal, parentProto, &sPrototypeClass.mBase, protoCache, constructorProto, &sInterfaceObjectClass.mBase, 0, nullptr, interfaceCache, sNativeProperties.Upcast(), nsContentUtils::ThreadsafeIsSystemCaller(aCx) ? sChromeOnlyNativeProperties.Upcast() : nullptr, "AudioNode", aDefineOnGlobal, nullptr, false); } JS::Handle GetProtoObjectHandle(JSContext* aCx) { /* Get the interface prototype object for this class. This will create the object as needed. */ bool aDefineOnGlobal = true; /* Make sure our global is sane. Hopefully we can remove this sometime */ JSObject* global = JS::CurrentGlobalOrNull(aCx); if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) { return nullptr; } /* Check to see whether the interface objects are already installed */ ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global); if (!protoAndIfaceCache.HasEntryInSlot(prototypes::id::AudioNode)) { JS::Rooted rootedGlobal(aCx, global); CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal); } /* * The object might _still_ be null, but that's OK. * * Calling fromMarkedLocation() is safe because protoAndIfaceCache is * traced by TraceProtoAndIfaceCache() and its contents are never * changed after they have been set. * * Calling address() avoids the read read barrier that does gray * unmarking, but it's not possible for the object to be gray here. */ const JS::Heap& entrySlot = protoAndIfaceCache.EntrySlotMustExist(prototypes::id::AudioNode); MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot)); return JS::Handle::fromMarkedLocation(entrySlot.address()); } JSObject* GetProtoObject(JSContext* aCx) { return GetProtoObjectHandle(aCx); } JS::Handle GetConstructorObjectHandle(JSContext* aCx, bool aDefineOnGlobal) { /* Get the interface object for this class. This will create the object as needed. */ /* Make sure our global is sane. Hopefully we can remove this sometime */ JSObject* global = JS::CurrentGlobalOrNull(aCx); if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) { return nullptr; } /* Check to see whether the interface objects are already installed */ ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global); if (!protoAndIfaceCache.HasEntryInSlot(constructors::id::AudioNode)) { JS::Rooted rootedGlobal(aCx, global); CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal); } /* * The object might _still_ be null, but that's OK. * * Calling fromMarkedLocation() is safe because protoAndIfaceCache is * traced by TraceProtoAndIfaceCache() and its contents are never * changed after they have been set. * * Calling address() avoids the read read barrier that does gray * unmarking, but it's not possible for the object to be gray here. */ const JS::Heap& entrySlot = protoAndIfaceCache.EntrySlotMustExist(constructors::id::AudioNode); MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot)); return JS::Handle::fromMarkedLocation(entrySlot.address()); } JSObject* GetConstructorObject(JSContext* aCx) { return GetConstructorObjectHandle(aCx); } } // namespace AudioNodeBinding } // namespace dom } // namespace mozilla