Copy as Markdown

Other Tools

/* THIS FILE IS AUTOGENERATED FROM TestInterfaceJSDictionaries.webidl BY Codegen.py - DO NOT EDIT */
#include <type_traits>
#include "AtomList.h"
#include "MainThreadUtils.h"
#include "TestInterfaceJSDictionariesBinding.h"
#include "js/Array.h"
#include "js/CallAndConstruct.h"
#include "js/Exception.h"
#include "js/ForOfIterator.h"
#include "js/MapAndSet.h"
#include "js/Object.h"
#include "js/PropertyAndElement.h"
#include "js/PropertyDescriptor.h"
#include "js/experimental/JitInfo.h"
#include "mozilla/OwningNonNull.h"
#include "mozilla/dom/BindingCallContext.h"
#include "mozilla/dom/BindingUtils.h"
#include "mozilla/dom/NonRefcountedDOMObject.h"
#include "mozilla/dom/ScriptSettings.h"
namespace mozilla::dom {
namespace binding_detail {}; // Just to make sure it's known as a namespace
using namespace mozilla::dom::binding_detail;
TestInterfaceJSDictionary2::TestInterfaceJSDictionary2()
{
// Safe to pass a null context if we pass a null value
Init(nullptr, JS::NullHandleValue);
}
bool
TestInterfaceJSDictionary2::InitIds(JSContext* cx, TestInterfaceJSDictionary2Atoms* atomsCache)
{
MOZ_ASSERT(reinterpret_cast<jsid*>(atomsCache)->isVoid());
// Initialize these in reverse order so that any failure leaves the first one
// uninitialized.
if (!atomsCache->innerObject_id.init(cx, "innerObject")) {
return false;
}
return true;
}
bool
TestInterfaceJSDictionary2::Init(BindingCallContext& cx, JS::Handle<JS::Value> 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());
TestInterfaceJSDictionary2Atoms* atomsCache = nullptr;
if (cx) {
atomsCache = GetAtomCache<TestInterfaceJSDictionary2Atoms>(cx);
if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
!InitIds(cx, atomsCache)) {
return false;
}
}
if (!IsConvertibleToDictionary(val)) {
return cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>(sourceDescription, "dictionary");
}
bool isNull = val.isNullOrUndefined();
// We only need these if !isNull, in which case we have |cx|.
Maybe<JS::Rooted<JSObject *> > object;
Maybe<JS::Rooted<JS::Value> > temp;
if (!isNull) {
MOZ_ASSERT(cx);
object.emplace(cx, &val.toObject());
temp.emplace(cx);
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->innerObject_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
mInnerObject.Construct();
if (temp.ref().isObject()) {
#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
#pragma clang diagnostic ignored "-Wunreachable-code-return"
#endif // __clang__
if ((passedToJSImpl) && !CallerSubsumes(temp.ref())) {
cx.ThrowErrorMessage<MSG_PERMISSION_DENIED_TO_PASS_ARG>("'innerObject' member of TestInterfaceJSDictionary2");
return false;
}
#ifdef __clang__
#pragma clang diagnostic pop
#endif // __clang__
(mInnerObject.Value()) = &temp.ref().toObject();
} else {
cx.ThrowErrorMessage<MSG_NOT_OBJECT>("'innerObject' member of TestInterfaceJSDictionary2");
return false;
}
mIsAnyMemberPresent = true;
}
return true;
}
bool
TestInterfaceJSDictionary2::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
// We don't want to use sourceDescription for our context here;
// that's not really what it's formatted for.
BindingCallContext cx(cx_, nullptr);
return Init(cx, val, sourceDescription, passedToJSImpl);
}
bool
TestInterfaceJSDictionary2::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
{
TestInterfaceJSDictionary2Atoms* atomsCache = GetAtomCache<TestInterfaceJSDictionary2Atoms>(cx);
if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
!InitIds(cx, atomsCache)) {
return false;
}
JS::Rooted<JSObject*> obj(cx, JS_NewPlainObject(cx));
if (!obj) {
return false;
}
rval.set(JS::ObjectValue(*obj));
if (mInnerObject.WasPassed()) {
do {
// block for our 'break' successCode and scope for 'temp' and 'currentValue'
JS::Rooted<JS::Value> temp(cx);
JSObject* const & currentValue = mInnerObject.InternalValue();
JS::ExposeObjectToActiveJS(currentValue);
temp.setObject(*currentValue);
if (!MaybeWrapObjectValue(cx, &temp)) {
return false;
}
if (!JS_DefinePropertyById(cx, obj, atomsCache->innerObject_id, temp, JSPROP_ENUMERATE)) {
return false;
}
break;
} while(false);
}
return true;
}
void
TestInterfaceJSDictionary2::TraceDictionary(JSTracer* trc)
{
if (mInnerObject.WasPassed()) {
JS::TraceRoot(trc, &mInnerObject.Value(), "TestInterfaceJSDictionary2.mInnerObject");
}
}
TestInterfaceJSDictionary::TestInterfaceJSDictionary()
{
// Safe to pass a null context if we pass a null value
Init(nullptr, JS::NullHandleValue);
}
bool
TestInterfaceJSDictionary::InitIds(JSContext* cx, TestInterfaceJSDictionaryAtoms* atomsCache)
{
MOZ_ASSERT(reinterpret_cast<jsid*>(atomsCache)->isVoid());
// Initialize these in reverse order so that any failure leaves the first one
// uninitialized.
if (!atomsCache->objectRecordMember_id.init(cx, "objectRecordMember") ||
!atomsCache->objectOrStringMember_id.init(cx, "objectOrStringMember") ||
!atomsCache->objectMember_id.init(cx, "objectMember") ||
!atomsCache->innerDictionary_id.init(cx, "innerDictionary") ||
!atomsCache->anySequenceMember_id.init(cx, "anySequenceMember") ||
!atomsCache->anyMember_id.init(cx, "anyMember")) {
return false;
}
return true;
}
bool
TestInterfaceJSDictionary::Init(BindingCallContext& cx, JS::Handle<JS::Value> 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());
TestInterfaceJSDictionaryAtoms* atomsCache = nullptr;
if (cx) {
atomsCache = GetAtomCache<TestInterfaceJSDictionaryAtoms>(cx);
if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
!InitIds(cx, atomsCache)) {
return false;
}
}
if (!IsConvertibleToDictionary(val)) {
return cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>(sourceDescription, "dictionary");
}
bool isNull = val.isNullOrUndefined();
// We only need these if !isNull, in which case we have |cx|.
Maybe<JS::Rooted<JSObject *> > object;
Maybe<JS::Rooted<JS::Value> > temp;
if (!isNull) {
MOZ_ASSERT(cx);
object.emplace(cx, &val.toObject());
temp.emplace(cx);
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->anyMember_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
#pragma clang diagnostic ignored "-Wunreachable-code-return"
#endif // __clang__
if ((passedToJSImpl) && !CallerSubsumes(temp.ref())) {
cx.ThrowErrorMessage<MSG_PERMISSION_DENIED_TO_PASS_ARG>("'anyMember' member of TestInterfaceJSDictionary");
return false;
}
#ifdef __clang__
#pragma clang diagnostic pop
#endif // __clang__
mAnyMember = temp.ref();
} else {
mAnyMember = JS::UndefinedValue();
}
mIsAnyMemberPresent = true;
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->anySequenceMember_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
mAnySequenceMember.Construct();
if (temp.ref().isObject()) {
JS::ForOfIterator iter(cx);
if (!iter.init(temp.ref(), JS::ForOfIterator::AllowNonIterable)) {
return false;
}
if (!iter.valueIsIterable()) {
cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>("'anySequenceMember' member of TestInterfaceJSDictionary", "sequence");
return false;
}
Sequence<JS::Value> &arr = (mAnySequenceMember.Value());
JS::Rooted<JS::Value> temp(cx);
while (true) {
bool done;
if (!iter.next(&temp, &done)) {
return false;
}
if (done) {
break;
}
JS::Value* slotPtr = arr.AppendElement(mozilla::fallible);
if (!slotPtr) {
JS_ReportOutOfMemory(cx);
return false;
}
JS::Value& slot = *slotPtr;
#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
#pragma clang diagnostic ignored "-Wunreachable-code-return"
#endif // __clang__
if ((passedToJSImpl) && !CallerSubsumes(temp)) {
cx.ThrowErrorMessage<MSG_PERMISSION_DENIED_TO_PASS_ARG>("element of 'anySequenceMember' member of TestInterfaceJSDictionary");
return false;
}
#ifdef __clang__
#pragma clang diagnostic pop
#endif // __clang__
slot = temp;
}
} else {
cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>("'anySequenceMember' member of TestInterfaceJSDictionary", "sequence");
return false;
}
mIsAnyMemberPresent = true;
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->innerDictionary_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
mInnerDictionary.Construct();
if (!(mInnerDictionary.Value()).Init(cx, temp.ref(), "'innerDictionary' member of TestInterfaceJSDictionary", passedToJSImpl)) {
return false;
}
mIsAnyMemberPresent = true;
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->objectMember_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
mObjectMember.Construct();
if (temp.ref().isObject()) {
#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
#pragma clang diagnostic ignored "-Wunreachable-code-return"
#endif // __clang__
if ((passedToJSImpl) && !CallerSubsumes(temp.ref())) {
cx.ThrowErrorMessage<MSG_PERMISSION_DENIED_TO_PASS_ARG>("'objectMember' member of TestInterfaceJSDictionary");
return false;
}
#ifdef __clang__
#pragma clang diagnostic pop
#endif // __clang__
(mObjectMember.Value()) = &temp.ref().toObject();
} else {
cx.ThrowErrorMessage<MSG_NOT_OBJECT>("'objectMember' member of TestInterfaceJSDictionary");
return false;
}
mIsAnyMemberPresent = true;
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->objectOrStringMember_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
mObjectOrStringMember.Construct();
if (!(mObjectOrStringMember.Value()).Init(cx, temp.ref(), "'objectOrStringMember' member of TestInterfaceJSDictionary", passedToJSImpl)) {
return false;
}
mIsAnyMemberPresent = true;
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->objectRecordMember_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
mObjectRecordMember.Construct();
if (temp.ref().isObject()) {
auto& recordEntries = (mObjectRecordMember.Value()).Entries();
JS::Rooted<JSObject*> recordObj(cx, &temp.ref().toObject());
JS::RootedVector<jsid> ids(cx);
if (!js::GetPropertyKeys(cx, recordObj,
JSITER_OWNONLY | JSITER_HIDDEN | JSITER_SYMBOLS, &ids)) {
return false;
}
if (!recordEntries.SetCapacity(ids.length(), mozilla::fallible)) {
JS_ReportOutOfMemory(cx);
return false;
}
JS::Rooted<JS::Value> propNameValue(cx);
JS::Rooted<JS::Value> temp(cx);
JS::Rooted<jsid> curId(cx);
JS::Rooted<JS::Value> idVal(cx);
// Use a hashset to keep track of ids seen, to avoid
// introducing nasty O(N^2) behavior scanning for them all the
// time. Ideally we'd use a data structure with O(1) lookup
// _and_ ordering for the MozMap, but we don't have one lying
// around.
nsTHashtable<nsStringHashKey> idsSeen;
for (size_t i = 0; i < ids.length(); ++i) {
curId = ids[i];
JS::Rooted<mozilla::Maybe<JS::PropertyDescriptor>> desc(cx);
if (!JS_GetOwnPropertyDescriptorById(cx, recordObj, curId,
&desc)) {
return false;
}
if (desc.isNothing() || !desc->enumerable()) {
continue;
}
idVal = js::IdToValue(curId);
nsString propName;
// This will just throw if idVal is a Symbol, like the spec says
// to do.
if (!ConvertJSValueToString(cx, idVal, "key of 'objectRecordMember' member of TestInterfaceJSDictionary", propName)) {
return false;
}
if (!JS_GetPropertyById(cx, recordObj, curId, &temp)) {
return false;
}
Record<nsString, JSObject*>::EntryType* entry;
if (!idsSeen.EnsureInserted(propName)) {
// Find the existing entry.
auto idx = recordEntries.IndexOf(propName);
MOZ_ASSERT(idx != recordEntries.NoIndex,
"Why is it not found?");
// Now blow it away to make it look like it was just added
// to the array, because it's not obvious that it's
// safe to write to its already-initialized mValue via our
// normal codegen conversions. For example, the value
// could be a union and this would change its type, but
// codegen assumes we won't do that.
entry = recordEntries.ReconstructElementAt(idx);
} else {
// Safe to do an infallible append here, because we did a
// SetCapacity above to the right capacity.
entry = recordEntries.AppendElement();
}
entry->mKey = propName;
JSObject*& slot = entry->mValue;
if (temp.isObject()) {
#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
#pragma clang diagnostic ignored "-Wunreachable-code-return"
#endif // __clang__
if ((passedToJSImpl) && !CallerSubsumes(temp)) {
cx.ThrowErrorMessage<MSG_PERMISSION_DENIED_TO_PASS_ARG>("value in 'objectRecordMember' member of TestInterfaceJSDictionary");
return false;
}
#ifdef __clang__
#pragma clang diagnostic pop
#endif // __clang__
slot = &temp.toObject();
} else {
cx.ThrowErrorMessage<MSG_NOT_OBJECT>("Value in 'objectRecordMember' member of TestInterfaceJSDictionary");
return false;
}
}
} else {
cx.ThrowErrorMessage<MSG_NOT_OBJECT>("'objectRecordMember' member of TestInterfaceJSDictionary");
return false;
}
mIsAnyMemberPresent = true;
}
return true;
}
bool
TestInterfaceJSDictionary::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
// We don't want to use sourceDescription for our context here;
// that's not really what it's formatted for.
BindingCallContext cx(cx_, nullptr);
return Init(cx, val, sourceDescription, passedToJSImpl);
}
bool
TestInterfaceJSDictionary::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
{
TestInterfaceJSDictionaryAtoms* atomsCache = GetAtomCache<TestInterfaceJSDictionaryAtoms>(cx);
if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
!InitIds(cx, atomsCache)) {
return false;
}
JS::Rooted<JSObject*> obj(cx, JS_NewPlainObject(cx));
if (!obj) {
return false;
}
rval.set(JS::ObjectValue(*obj));
do {
// block for our 'break' successCode and scope for 'temp' and 'currentValue'
JS::Rooted<JS::Value> temp(cx);
JS::Value const & currentValue = mAnyMember;
JS::ExposeValueToActiveJS(currentValue);
temp.set(currentValue);
if (!MaybeWrapValue(cx, &temp)) {
return false;
}
if (!JS_DefinePropertyById(cx, obj, atomsCache->anyMember_id, temp, JSPROP_ENUMERATE)) {
return false;
}
break;
} while(false);
if (mAnySequenceMember.WasPassed()) {
do {
// block for our 'break' successCode and scope for 'temp' and 'currentValue'
JS::Rooted<JS::Value> temp(cx);
Sequence<JS::Value> const & currentValue = mAnySequenceMember.InternalValue();
uint32_t length = currentValue.Length();
JS::Rooted<JSObject*> returnArray(cx, JS::NewArrayObject(cx, length));
if (!returnArray) {
return false;
}
// Scope for 'tmp'
{
JS::Rooted<JS::Value> tmp(cx);
for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
// Control block to let us common up the JS_DefineElement calls when there
// are different ways to succeed at wrapping the object.
do {
JS::ExposeValueToActiveJS(currentValue[sequenceIdx0]);
tmp.set(currentValue[sequenceIdx0]);
if (!MaybeWrapValue(cx, &tmp)) {
return false;
}
break;
} while (false);
if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
JSPROP_ENUMERATE)) {
return false;
}
}
}
temp.setObject(*returnArray);
if (!JS_DefinePropertyById(cx, obj, atomsCache->anySequenceMember_id, temp, JSPROP_ENUMERATE)) {
return false;
}
break;
} while(false);
}
if (mInnerDictionary.WasPassed()) {
do {
// block for our 'break' successCode and scope for 'temp' and 'currentValue'
JS::Rooted<JS::Value> temp(cx);
TestInterfaceJSDictionary2 const & currentValue = mInnerDictionary.InternalValue();
if (!currentValue.ToObjectInternal(cx, &temp)) {
return false;
}
if (!JS_DefinePropertyById(cx, obj, atomsCache->innerDictionary_id, temp, JSPROP_ENUMERATE)) {
return false;
}
break;
} while(false);
}
if (mObjectMember.WasPassed()) {
do {
// block for our 'break' successCode and scope for 'temp' and 'currentValue'
JS::Rooted<JS::Value> temp(cx);
JSObject* const & currentValue = mObjectMember.InternalValue();
JS::ExposeObjectToActiveJS(currentValue);
temp.setObject(*currentValue);
if (!MaybeWrapObjectValue(cx, &temp)) {
return false;
}
if (!JS_DefinePropertyById(cx, obj, atomsCache->objectMember_id, temp, JSPROP_ENUMERATE)) {
return false;
}
break;
} while(false);
}
if (mObjectOrStringMember.WasPassed()) {
do {
// block for our 'break' successCode and scope for 'temp' and 'currentValue'
JS::Rooted<JS::Value> temp(cx);
OwningObjectOrString const & currentValue = mObjectOrStringMember.InternalValue();
if (!currentValue.ToJSVal(cx, obj, &temp)) {
return false;
}
if (!JS_DefinePropertyById(cx, obj, atomsCache->objectOrStringMember_id, temp, JSPROP_ENUMERATE)) {
return false;
}
break;
} while(false);
}
if (mObjectRecordMember.WasPassed()) {
do {
// block for our 'break' successCode and scope for 'temp' and 'currentValue'
JS::Rooted<JS::Value> temp(cx);
Record<nsString, JSObject*> const & currentValue = mObjectRecordMember.InternalValue();
JS::Rooted<JSObject*> returnObj(cx, JS_NewPlainObject(cx));
if (!returnObj) {
return false;
}
// Scope for 'tmp'
{
JS::Rooted<JS::Value> tmp(cx);
for (auto& entry : currentValue.Entries()) {
auto& recordValue0 = entry.mValue;
// Control block to let us common up the JS_DefineUCProperty calls when there
// are different ways to succeed at wrapping the value.
do {
JS::ExposeObjectToActiveJS(recordValue0);
tmp.setObject(*recordValue0);
if (!MaybeWrapObjectValue(cx, &tmp)) {
return false;
}
break;
} while (false);
if (!JS_DefineUCProperty(cx, returnObj,
entry.mKey.BeginReading(),
entry.mKey.Length(), tmp,
JSPROP_ENUMERATE)) {
return false;
}
}
}
temp.setObject(*returnObj);
if (!JS_DefinePropertyById(cx, obj, atomsCache->objectRecordMember_id, temp, JSPROP_ENUMERATE)) {
return false;
}
break;
} while(false);
}
return true;
}
void
TestInterfaceJSDictionary::TraceDictionary(JSTracer* trc)
{
JS::TraceRoot(trc, &mAnyMember, "TestInterfaceJSDictionary.mAnyMember");
if (mAnySequenceMember.WasPassed()) {
DoTraceSequence(trc, mAnySequenceMember.Value());
}
if (mInnerDictionary.WasPassed()) {
mInnerDictionary.Value().TraceDictionary(trc);
}
if (mObjectMember.WasPassed()) {
JS::TraceRoot(trc, &mObjectMember.Value(), "TestInterfaceJSDictionary.mObjectMember");
}
if (mObjectOrStringMember.WasPassed()) {
mObjectOrStringMember.Value().TraceUnion(trc);
}
if (mObjectRecordMember.WasPassed()) {
TraceRecord(trc, mObjectRecordMember.Value());
}
}
} // namespace mozilla::dom