Line data Source code
1 : /* THIS FILE IS AUTOGENERATED FROM FormData.webidl BY Codegen.py - DO NOT EDIT */
2 :
3 : #include "FormDataBinding.h"
4 : #include "WrapperFactory.h"
5 : #include "mozilla/OwningNonNull.h"
6 : #include "mozilla/dom/BindingUtils.h"
7 : #include "mozilla/dom/Blob.h"
8 : #include "mozilla/dom/DOMJSClass.h"
9 : #include "mozilla/dom/Directory.h"
10 : #include "mozilla/dom/FormData.h"
11 : #include "mozilla/dom/HTMLFormElement.h"
12 : #include "mozilla/dom/IterableIterator.h"
13 : #include "mozilla/dom/NonRefcountedDOMObject.h"
14 : #include "mozilla/dom/Nullable.h"
15 : #include "mozilla/dom/PrimitiveConversions.h"
16 : #include "mozilla/dom/ToJSValue.h"
17 : #include "mozilla/dom/UnionConversions.h"
18 : #include "mozilla/dom/XrayExpandoClass.h"
19 : #include "nsISupports.h"
20 : #include "xpcjsid.h"
21 :
22 : namespace mozilla {
23 : namespace dom {
24 :
25 : void
26 0 : ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback, OwningBlobOrDirectoryOrUSVString& aUnion, const char* aName, uint32_t aFlags)
27 : {
28 0 : if (aUnion.IsBlob()) {
29 0 : ImplCycleCollectionTraverse(aCallback, aUnion.GetAsBlob(), "mBlob", aFlags);
30 0 : } else if (aUnion.IsDirectory()) {
31 0 : ImplCycleCollectionTraverse(aCallback, aUnion.GetAsDirectory(), "mDirectory", aFlags);
32 : }
33 0 : }
34 :
35 :
36 : void
37 0 : ImplCycleCollectionUnlink(OwningBlobOrDirectoryOrUSVString& aUnion)
38 : {
39 0 : aUnion.Uninit();
40 0 : }
41 :
42 :
43 : bool
44 0 : BlobOrDirectoryOrUSVString::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
45 : {
46 0 : switch (mType) {
47 : case eUninitialized: {
48 0 : return false;
49 : break;
50 : }
51 : case eBlob: {
52 0 : if (!GetOrCreateDOMReflector(cx, mValue.mBlob.Value(), rval)) {
53 0 : MOZ_ASSERT(true || JS_IsExceptionPending(cx));
54 0 : return false;
55 : }
56 0 : return true;
57 : break;
58 : }
59 : case eDirectory: {
60 0 : if (!GetOrCreateDOMReflector(cx, mValue.mDirectory.Value(), rval)) {
61 0 : MOZ_ASSERT(true || JS_IsExceptionPending(cx));
62 0 : return false;
63 : }
64 0 : return true;
65 : break;
66 : }
67 : case eUSVString: {
68 0 : if (!xpc::NonVoidStringToJsval(cx, mValue.mUSVString.Value(), rval)) {
69 0 : return false;
70 : }
71 0 : return true;
72 : break;
73 : }
74 : default: {
75 0 : return false;
76 : break;
77 : }
78 : }
79 :
80 : return false;
81 : }
82 :
83 :
84 : OwningNonNull<mozilla::dom::Blob>&
85 0 : OwningBlobOrDirectoryOrUSVString::RawSetAsBlob()
86 : {
87 0 : if (mType == eBlob) {
88 0 : return mValue.mBlob.Value();
89 : }
90 0 : MOZ_ASSERT(mType == eUninitialized);
91 0 : mType = eBlob;
92 0 : return mValue.mBlob.SetValue();
93 : }
94 :
95 : OwningNonNull<mozilla::dom::Blob>&
96 0 : OwningBlobOrDirectoryOrUSVString::SetAsBlob()
97 : {
98 0 : if (mType == eBlob) {
99 0 : return mValue.mBlob.Value();
100 : }
101 0 : Uninit();
102 0 : mType = eBlob;
103 0 : return mValue.mBlob.SetValue();
104 : }
105 :
106 : bool
107 0 : OwningBlobOrDirectoryOrUSVString::TrySetToBlob(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
108 : {
109 0 : tryNext = false;
110 : { // scope for memberSlot
111 0 : OwningNonNull<mozilla::dom::Blob>& memberSlot = RawSetAsBlob();
112 : static_assert(IsRefcounted<mozilla::dom::Blob>::value, "We can only store refcounted classes.");{
113 0 : nsresult rv = UnwrapObject<prototypes::id::Blob, mozilla::dom::Blob>(value, memberSlot);
114 0 : if (NS_FAILED(rv)) {
115 0 : DestroyBlob();
116 0 : tryNext = true;
117 0 : return true;
118 : }
119 : }
120 : }
121 0 : return true;
122 : }
123 :
124 : void
125 0 : OwningBlobOrDirectoryOrUSVString::DestroyBlob()
126 : {
127 0 : MOZ_ASSERT(IsBlob(), "Wrong type!");
128 0 : mValue.mBlob.Destroy();
129 0 : mType = eUninitialized;
130 0 : }
131 :
132 :
133 :
134 :
135 : OwningNonNull<mozilla::dom::Directory>&
136 0 : OwningBlobOrDirectoryOrUSVString::RawSetAsDirectory()
137 : {
138 0 : if (mType == eDirectory) {
139 0 : return mValue.mDirectory.Value();
140 : }
141 0 : MOZ_ASSERT(mType == eUninitialized);
142 0 : mType = eDirectory;
143 0 : return mValue.mDirectory.SetValue();
144 : }
145 :
146 : OwningNonNull<mozilla::dom::Directory>&
147 0 : OwningBlobOrDirectoryOrUSVString::SetAsDirectory()
148 : {
149 0 : if (mType == eDirectory) {
150 0 : return mValue.mDirectory.Value();
151 : }
152 0 : Uninit();
153 0 : mType = eDirectory;
154 0 : return mValue.mDirectory.SetValue();
155 : }
156 :
157 : bool
158 0 : OwningBlobOrDirectoryOrUSVString::TrySetToDirectory(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
159 : {
160 0 : tryNext = false;
161 : { // scope for memberSlot
162 0 : OwningNonNull<mozilla::dom::Directory>& memberSlot = RawSetAsDirectory();
163 : static_assert(IsRefcounted<mozilla::dom::Directory>::value, "We can only store refcounted classes.");{
164 0 : nsresult rv = UnwrapObject<prototypes::id::Directory, mozilla::dom::Directory>(value, memberSlot);
165 0 : if (NS_FAILED(rv)) {
166 0 : DestroyDirectory();
167 0 : tryNext = true;
168 0 : return true;
169 : }
170 : }
171 : }
172 0 : return true;
173 : }
174 :
175 : void
176 0 : OwningBlobOrDirectoryOrUSVString::DestroyDirectory()
177 : {
178 0 : MOZ_ASSERT(IsDirectory(), "Wrong type!");
179 0 : mValue.mDirectory.Destroy();
180 0 : mType = eUninitialized;
181 0 : }
182 :
183 :
184 :
185 :
186 : nsString&
187 0 : OwningBlobOrDirectoryOrUSVString::RawSetAsUSVString()
188 : {
189 0 : if (mType == eUSVString) {
190 0 : return mValue.mUSVString.Value();
191 : }
192 0 : MOZ_ASSERT(mType == eUninitialized);
193 0 : mType = eUSVString;
194 0 : return mValue.mUSVString.SetValue();
195 : }
196 :
197 : nsString&
198 0 : OwningBlobOrDirectoryOrUSVString::SetAsUSVString()
199 : {
200 0 : if (mType == eUSVString) {
201 0 : return mValue.mUSVString.Value();
202 : }
203 0 : Uninit();
204 0 : mType = eUSVString;
205 0 : return mValue.mUSVString.SetValue();
206 : }
207 :
208 : bool
209 0 : OwningBlobOrDirectoryOrUSVString::TrySetToUSVString(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
210 : {
211 0 : tryNext = false;
212 : { // scope for memberSlot
213 0 : nsString& memberSlot = RawSetAsUSVString();
214 0 : if (!ConvertJSValueToString(cx, value, eStringify, eStringify, memberSlot)) {
215 0 : return false;
216 : }
217 0 : NormalizeUSVString(memberSlot);
218 : }
219 0 : return true;
220 : }
221 :
222 :
223 : void
224 0 : OwningBlobOrDirectoryOrUSVString::DestroyUSVString()
225 : {
226 0 : MOZ_ASSERT(IsUSVString(), "Wrong type!");
227 0 : mValue.mUSVString.Destroy();
228 0 : mType = eUninitialized;
229 0 : }
230 :
231 :
232 :
233 :
234 : void
235 0 : OwningBlobOrDirectoryOrUSVString::Uninit()
236 : {
237 0 : switch (mType) {
238 : case eUninitialized: {
239 0 : break;
240 : }
241 : case eBlob: {
242 0 : DestroyBlob();
243 0 : break;
244 : }
245 : case eDirectory: {
246 0 : DestroyDirectory();
247 0 : break;
248 : }
249 : case eUSVString: {
250 0 : DestroyUSVString();
251 0 : break;
252 : }
253 : }
254 0 : }
255 :
256 : bool
257 0 : OwningBlobOrDirectoryOrUSVString::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
258 : {
259 0 : switch (mType) {
260 : case eUninitialized: {
261 0 : return false;
262 : break;
263 : }
264 : case eBlob: {
265 0 : if (!GetOrCreateDOMReflector(cx, mValue.mBlob.Value(), rval)) {
266 0 : MOZ_ASSERT(true || JS_IsExceptionPending(cx));
267 0 : return false;
268 : }
269 0 : return true;
270 : break;
271 : }
272 : case eDirectory: {
273 0 : if (!GetOrCreateDOMReflector(cx, mValue.mDirectory.Value(), rval)) {
274 0 : MOZ_ASSERT(true || JS_IsExceptionPending(cx));
275 0 : return false;
276 : }
277 0 : return true;
278 : break;
279 : }
280 : case eUSVString: {
281 0 : if (!xpc::NonVoidStringToJsval(cx, mValue.mUSVString.Value(), rval)) {
282 0 : return false;
283 : }
284 0 : return true;
285 : break;
286 : }
287 : default: {
288 0 : return false;
289 : break;
290 : }
291 : }
292 :
293 : return false;
294 : }
295 :
296 : void
297 0 : OwningBlobOrDirectoryOrUSVString::TraceUnion(JSTracer* trc)
298 : {
299 0 : }
300 :
301 : OwningBlobOrDirectoryOrUSVString&
302 0 : OwningBlobOrDirectoryOrUSVString::operator=(const OwningBlobOrDirectoryOrUSVString& aOther)
303 : {
304 0 : switch (aOther.mType) {
305 : case eUninitialized: {
306 0 : MOZ_ASSERT(mType == eUninitialized,
307 : "We need to destroy ourselves?");
308 0 : break;
309 : }
310 : case eBlob: {
311 0 : SetAsBlob() = aOther.GetAsBlob();
312 0 : break;
313 : }
314 : case eDirectory: {
315 0 : SetAsDirectory() = aOther.GetAsDirectory();
316 0 : break;
317 : }
318 : case eUSVString: {
319 0 : SetAsUSVString() = aOther.GetAsUSVString();
320 0 : break;
321 : }
322 : }
323 0 : return *this;
324 : }
325 :
326 :
327 : namespace FormDataBinding {
328 :
329 : static bool
330 0 : append(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::FormData* self, const JSJitMethodCallArgs& args)
331 : {
332 0 : unsigned argcount = std::min(args.length(), 3u);
333 0 : switch (argcount) {
334 : case 2: {
335 0 : binding_detail::FakeString arg0;
336 0 : if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
337 0 : return false;
338 : }
339 0 : NormalizeUSVString(arg0);
340 0 : if (args[1].isObject()) {
341 : do {
342 0 : NonNull<mozilla::dom::Blob> arg1;
343 : {
344 0 : nsresult rv = UnwrapObject<prototypes::id::Blob, mozilla::dom::Blob>(args[1], arg1);
345 0 : if (NS_FAILED(rv)) {
346 0 : break;
347 : }
348 : }
349 0 : Optional<nsAString> arg2;
350 0 : binding_detail::FakeString arg2_holder;
351 0 : if (args.hasDefined(2)) {
352 0 : if (!ConvertJSValueToString(cx, args[2], eStringify, eStringify, arg2_holder)) {
353 0 : return false;
354 : }
355 0 : NormalizeUSVString(arg2_holder);
356 0 : arg2 = &arg2_holder;
357 : }
358 0 : binding_detail::FastErrorResult rv;
359 0 : self->Append(Constify(arg0), NonNullHelper(arg1), Constify(arg2), rv);
360 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
361 0 : return false;
362 : }
363 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
364 0 : args.rval().setUndefined();
365 0 : return true;
366 : } while (0);
367 : }
368 0 : binding_detail::FakeString arg1;
369 0 : if (!ConvertJSValueToString(cx, args[1], eStringify, eStringify, arg1)) {
370 0 : return false;
371 : }
372 0 : NormalizeUSVString(arg1);
373 0 : binding_detail::FastErrorResult rv;
374 0 : self->Append(Constify(arg0), Constify(arg1), rv);
375 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
376 0 : return false;
377 : }
378 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
379 0 : args.rval().setUndefined();
380 0 : return true;
381 : break;
382 : }
383 : case 3: {
384 0 : binding_detail::FakeString arg0;
385 0 : if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
386 0 : return false;
387 : }
388 0 : NormalizeUSVString(arg0);
389 0 : NonNull<mozilla::dom::Blob> arg1;
390 0 : if (args[1].isObject()) {
391 : {
392 0 : nsresult rv = UnwrapObject<prototypes::id::Blob, mozilla::dom::Blob>(args[1], arg1);
393 0 : if (NS_FAILED(rv)) {
394 0 : ThrowErrorMessage(cx, MSG_DOES_NOT_IMPLEMENT_INTERFACE, "Argument 2 of FormData.append", "Blob");
395 0 : return false;
396 : }
397 : }
398 : } else {
399 0 : ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 2 of FormData.append");
400 0 : return false;
401 : }
402 0 : Optional<nsAString> arg2;
403 0 : binding_detail::FakeString arg2_holder;
404 0 : if (args.hasDefined(2)) {
405 0 : if (!ConvertJSValueToString(cx, args[2], eStringify, eStringify, arg2_holder)) {
406 0 : return false;
407 : }
408 0 : NormalizeUSVString(arg2_holder);
409 0 : arg2 = &arg2_holder;
410 : }
411 0 : binding_detail::FastErrorResult rv;
412 0 : self->Append(Constify(arg0), NonNullHelper(arg1), Constify(arg2), rv);
413 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
414 0 : return false;
415 : }
416 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
417 0 : args.rval().setUndefined();
418 0 : return true;
419 : break;
420 : }
421 : default: {
422 0 : return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "FormData.append");
423 : break;
424 : }
425 : }
426 : MOZ_CRASH("We have an always-returning default case");
427 : return false;
428 : }
429 :
430 : static const JSJitInfo append_methodinfo = {
431 : { (JSJitGetterOp)append },
432 : { prototypes::id::FormData },
433 : { PrototypeTraits<prototypes::id::FormData>::Depth },
434 : JSJitInfo::Method,
435 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
436 : JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
437 : false, /* isInfallible. False in setters. */
438 : false, /* isMovable. Not relevant for setters. */
439 : false, /* isEliminatable. Not relevant for setters. */
440 : false, /* isAlwaysInSlot. Only relevant for getters. */
441 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
442 : false, /* isTypedMethod. Only relevant for methods. */
443 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
444 : };
445 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
446 : static_assert(0 < 1, "There is no slot for us");
447 :
448 : static bool
449 0 : _delete_(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::FormData* self, const JSJitMethodCallArgs& args)
450 : {
451 0 : if (MOZ_UNLIKELY(args.length() < 1)) {
452 0 : return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "FormData.delete");
453 : }
454 0 : binding_detail::FakeString arg0;
455 0 : if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
456 0 : return false;
457 : }
458 0 : NormalizeUSVString(arg0);
459 0 : self->Delete(Constify(arg0));
460 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
461 0 : args.rval().setUndefined();
462 0 : return true;
463 : }
464 :
465 : static const JSJitInfo delete_methodinfo = {
466 : { (JSJitGetterOp)_delete_ },
467 : { prototypes::id::FormData },
468 : { PrototypeTraits<prototypes::id::FormData>::Depth },
469 : JSJitInfo::Method,
470 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
471 : JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
472 : false, /* isInfallible. False in setters. */
473 : false, /* isMovable. Not relevant for setters. */
474 : false, /* isEliminatable. Not relevant for setters. */
475 : false, /* isAlwaysInSlot. Only relevant for getters. */
476 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
477 : false, /* isTypedMethod. Only relevant for methods. */
478 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
479 : };
480 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
481 : static_assert(0 < 1, "There is no slot for us");
482 :
483 : static bool
484 0 : get(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::FormData* self, const JSJitMethodCallArgs& args)
485 : {
486 0 : if (MOZ_UNLIKELY(args.length() < 1)) {
487 0 : return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "FormData.get");
488 : }
489 0 : binding_detail::FakeString arg0;
490 0 : if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
491 0 : return false;
492 : }
493 0 : NormalizeUSVString(arg0);
494 0 : Nullable<OwningBlobOrDirectoryOrUSVString> result;
495 0 : self->Get(Constify(arg0), result);
496 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
497 0 : if (result.IsNull()) {
498 0 : args.rval().setNull();
499 0 : return true;
500 : }
501 0 : if (!result.Value().ToJSVal(cx, obj, args.rval())) {
502 0 : return false;
503 : }
504 0 : return true;
505 : }
506 :
507 : static const JSJitInfo get_methodinfo = {
508 : { (JSJitGetterOp)get },
509 : { prototypes::id::FormData },
510 : { PrototypeTraits<prototypes::id::FormData>::Depth },
511 : JSJitInfo::Method,
512 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
513 : JSVAL_TYPE_UNKNOWN, /* returnType. Not relevant for setters. */
514 : false, /* isInfallible. False in setters. */
515 : false, /* isMovable. Not relevant for setters. */
516 : false, /* isEliminatable. Not relevant for setters. */
517 : false, /* isAlwaysInSlot. Only relevant for getters. */
518 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
519 : false, /* isTypedMethod. Only relevant for methods. */
520 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
521 : };
522 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
523 : static_assert(0 < 1, "There is no slot for us");
524 :
525 : static bool
526 0 : getAll(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::FormData* self, const JSJitMethodCallArgs& args)
527 : {
528 0 : if (MOZ_UNLIKELY(args.length() < 1)) {
529 0 : return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "FormData.getAll");
530 : }
531 0 : binding_detail::FakeString arg0;
532 0 : if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
533 0 : return false;
534 : }
535 0 : NormalizeUSVString(arg0);
536 0 : nsTArray<OwningBlobOrDirectoryOrUSVString> result;
537 0 : self->GetAll(Constify(arg0), result);
538 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
539 :
540 0 : uint32_t length = result.Length();
541 0 : JS::Rooted<JSObject*> returnArray(cx, JS_NewArrayObject(cx, length));
542 0 : if (!returnArray) {
543 0 : return false;
544 : }
545 : // Scope for 'tmp'
546 : {
547 0 : JS::Rooted<JS::Value> tmp(cx);
548 0 : for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
549 : // Control block to let us common up the JS_DefineElement calls when there
550 : // are different ways to succeed at wrapping the object.
551 : do {
552 0 : if (!result[sequenceIdx0].ToJSVal(cx, returnArray, &tmp)) {
553 0 : return false;
554 : }
555 0 : break;
556 : } while (0);
557 0 : if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
558 : JSPROP_ENUMERATE)) {
559 0 : return false;
560 : }
561 : }
562 : }
563 0 : args.rval().setObject(*returnArray);
564 0 : return true;
565 : }
566 :
567 : static const JSJitInfo getAll_methodinfo = {
568 : { (JSJitGetterOp)getAll },
569 : { prototypes::id::FormData },
570 : { PrototypeTraits<prototypes::id::FormData>::Depth },
571 : JSJitInfo::Method,
572 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
573 : JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
574 : false, /* isInfallible. False in setters. */
575 : false, /* isMovable. Not relevant for setters. */
576 : false, /* isEliminatable. Not relevant for setters. */
577 : false, /* isAlwaysInSlot. Only relevant for getters. */
578 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
579 : false, /* isTypedMethod. Only relevant for methods. */
580 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
581 : };
582 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
583 : static_assert(0 < 1, "There is no slot for us");
584 :
585 : static bool
586 0 : has(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::FormData* self, const JSJitMethodCallArgs& args)
587 : {
588 0 : if (MOZ_UNLIKELY(args.length() < 1)) {
589 0 : return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "FormData.has");
590 : }
591 0 : binding_detail::FakeString arg0;
592 0 : if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
593 0 : return false;
594 : }
595 0 : NormalizeUSVString(arg0);
596 0 : bool result(self->Has(Constify(arg0)));
597 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
598 0 : args.rval().setBoolean(result);
599 0 : return true;
600 : }
601 :
602 : static const JSJitInfo has_methodinfo = {
603 : { (JSJitGetterOp)has },
604 : { prototypes::id::FormData },
605 : { PrototypeTraits<prototypes::id::FormData>::Depth },
606 : JSJitInfo::Method,
607 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
608 : JSVAL_TYPE_BOOLEAN, /* returnType. Not relevant for setters. */
609 : false, /* isInfallible. False in setters. */
610 : false, /* isMovable. Not relevant for setters. */
611 : false, /* isEliminatable. Not relevant for setters. */
612 : false, /* isAlwaysInSlot. Only relevant for getters. */
613 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
614 : false, /* isTypedMethod. Only relevant for methods. */
615 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
616 : };
617 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
618 : static_assert(0 < 1, "There is no slot for us");
619 :
620 : static bool
621 0 : set(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::FormData* self, const JSJitMethodCallArgs& args)
622 : {
623 0 : unsigned argcount = std::min(args.length(), 3u);
624 0 : switch (argcount) {
625 : case 2: {
626 0 : binding_detail::FakeString arg0;
627 0 : if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
628 0 : return false;
629 : }
630 0 : NormalizeUSVString(arg0);
631 0 : if (args[1].isObject()) {
632 : do {
633 0 : NonNull<mozilla::dom::Blob> arg1;
634 : {
635 0 : nsresult rv = UnwrapObject<prototypes::id::Blob, mozilla::dom::Blob>(args[1], arg1);
636 0 : if (NS_FAILED(rv)) {
637 0 : break;
638 : }
639 : }
640 0 : Optional<nsAString> arg2;
641 0 : binding_detail::FakeString arg2_holder;
642 0 : if (args.hasDefined(2)) {
643 0 : if (!ConvertJSValueToString(cx, args[2], eStringify, eStringify, arg2_holder)) {
644 0 : return false;
645 : }
646 0 : NormalizeUSVString(arg2_holder);
647 0 : arg2 = &arg2_holder;
648 : }
649 0 : binding_detail::FastErrorResult rv;
650 0 : self->Set(Constify(arg0), NonNullHelper(arg1), Constify(arg2), rv);
651 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
652 0 : return false;
653 : }
654 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
655 0 : args.rval().setUndefined();
656 0 : return true;
657 : } while (0);
658 : }
659 0 : binding_detail::FakeString arg1;
660 0 : if (!ConvertJSValueToString(cx, args[1], eStringify, eStringify, arg1)) {
661 0 : return false;
662 : }
663 0 : NormalizeUSVString(arg1);
664 0 : binding_detail::FastErrorResult rv;
665 0 : self->Set(Constify(arg0), Constify(arg1), rv);
666 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
667 0 : return false;
668 : }
669 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
670 0 : args.rval().setUndefined();
671 0 : return true;
672 : break;
673 : }
674 : case 3: {
675 0 : binding_detail::FakeString arg0;
676 0 : if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
677 0 : return false;
678 : }
679 0 : NormalizeUSVString(arg0);
680 0 : NonNull<mozilla::dom::Blob> arg1;
681 0 : if (args[1].isObject()) {
682 : {
683 0 : nsresult rv = UnwrapObject<prototypes::id::Blob, mozilla::dom::Blob>(args[1], arg1);
684 0 : if (NS_FAILED(rv)) {
685 0 : ThrowErrorMessage(cx, MSG_DOES_NOT_IMPLEMENT_INTERFACE, "Argument 2 of FormData.set", "Blob");
686 0 : return false;
687 : }
688 : }
689 : } else {
690 0 : ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 2 of FormData.set");
691 0 : return false;
692 : }
693 0 : Optional<nsAString> arg2;
694 0 : binding_detail::FakeString arg2_holder;
695 0 : if (args.hasDefined(2)) {
696 0 : if (!ConvertJSValueToString(cx, args[2], eStringify, eStringify, arg2_holder)) {
697 0 : return false;
698 : }
699 0 : NormalizeUSVString(arg2_holder);
700 0 : arg2 = &arg2_holder;
701 : }
702 0 : binding_detail::FastErrorResult rv;
703 0 : self->Set(Constify(arg0), NonNullHelper(arg1), Constify(arg2), rv);
704 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
705 0 : return false;
706 : }
707 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
708 0 : args.rval().setUndefined();
709 0 : return true;
710 : break;
711 : }
712 : default: {
713 0 : return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "FormData.set");
714 : break;
715 : }
716 : }
717 : MOZ_CRASH("We have an always-returning default case");
718 : return false;
719 : }
720 :
721 : static const JSJitInfo set_methodinfo = {
722 : { (JSJitGetterOp)set },
723 : { prototypes::id::FormData },
724 : { PrototypeTraits<prototypes::id::FormData>::Depth },
725 : JSJitInfo::Method,
726 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
727 : JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
728 : false, /* isInfallible. False in setters. */
729 : false, /* isMovable. Not relevant for setters. */
730 : false, /* isEliminatable. Not relevant for setters. */
731 : false, /* isAlwaysInSlot. Only relevant for getters. */
732 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
733 : false, /* isTypedMethod. Only relevant for methods. */
734 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
735 : };
736 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
737 : static_assert(0 < 1, "There is no slot for us");
738 :
739 : static bool
740 0 : entries(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::FormData* self, const JSJitMethodCallArgs& args)
741 : {
742 : typedef mozilla::dom::IterableIterator<mozilla::dom::FormData> itrType;
743 : RefPtr<itrType> result(new itrType(self,
744 : itrType::IterableIteratorType::Entries,
745 0 : &FormDataIteratorBinding::Wrap));
746 : static_assert(!IsPointer<decltype(result)>::value,
747 : "NewObject implies that we need to keep the object alive with a strong reference.");
748 0 : if (!WrapNewBindingNonWrapperCachedObject(cx, obj, result, args.rval())) {
749 0 : MOZ_ASSERT(true || JS_IsExceptionPending(cx));
750 0 : return false;
751 : }
752 0 : return true;
753 : }
754 :
755 : static const JSJitInfo::ArgType entries_methodinfo_argTypes[] = { JSJitInfo::ArgTypeListEnd };
756 : static const JSTypedMethodJitInfo entries_methodinfo = {
757 : {
758 : { (JSJitGetterOp)entries },
759 : { prototypes::id::FormData },
760 : { PrototypeTraits<prototypes::id::FormData>::Depth },
761 : JSJitInfo::Method,
762 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
763 : JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
764 : false, /* isInfallible. False in setters. */
765 : false, /* isMovable. Not relevant for setters. */
766 : false, /* isEliminatable. Not relevant for setters. */
767 : false, /* isAlwaysInSlot. Only relevant for getters. */
768 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
769 : true, /* isTypedMethod. Only relevant for methods. */
770 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
771 : },
772 : entries_methodinfo_argTypes
773 : };
774 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
775 : static_assert(0 < 1, "There is no slot for us");
776 :
777 : static bool
778 0 : keys(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::FormData* self, const JSJitMethodCallArgs& args)
779 : {
780 : typedef mozilla::dom::IterableIterator<mozilla::dom::FormData> itrType;
781 : RefPtr<itrType> result(new itrType(self,
782 : itrType::IterableIteratorType::Keys,
783 0 : &FormDataIteratorBinding::Wrap));
784 : static_assert(!IsPointer<decltype(result)>::value,
785 : "NewObject implies that we need to keep the object alive with a strong reference.");
786 0 : if (!WrapNewBindingNonWrapperCachedObject(cx, obj, result, args.rval())) {
787 0 : MOZ_ASSERT(true || JS_IsExceptionPending(cx));
788 0 : return false;
789 : }
790 0 : return true;
791 : }
792 :
793 : static const JSJitInfo::ArgType keys_methodinfo_argTypes[] = { JSJitInfo::ArgTypeListEnd };
794 : static const JSTypedMethodJitInfo keys_methodinfo = {
795 : {
796 : { (JSJitGetterOp)keys },
797 : { prototypes::id::FormData },
798 : { PrototypeTraits<prototypes::id::FormData>::Depth },
799 : JSJitInfo::Method,
800 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
801 : JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
802 : false, /* isInfallible. False in setters. */
803 : false, /* isMovable. Not relevant for setters. */
804 : false, /* isEliminatable. Not relevant for setters. */
805 : false, /* isAlwaysInSlot. Only relevant for getters. */
806 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
807 : true, /* isTypedMethod. Only relevant for methods. */
808 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
809 : },
810 : keys_methodinfo_argTypes
811 : };
812 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
813 : static_assert(0 < 1, "There is no slot for us");
814 :
815 : static bool
816 0 : values(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::FormData* self, const JSJitMethodCallArgs& args)
817 : {
818 : typedef mozilla::dom::IterableIterator<mozilla::dom::FormData> itrType;
819 : RefPtr<itrType> result(new itrType(self,
820 : itrType::IterableIteratorType::Values,
821 0 : &FormDataIteratorBinding::Wrap));
822 : static_assert(!IsPointer<decltype(result)>::value,
823 : "NewObject implies that we need to keep the object alive with a strong reference.");
824 0 : if (!WrapNewBindingNonWrapperCachedObject(cx, obj, result, args.rval())) {
825 0 : MOZ_ASSERT(true || JS_IsExceptionPending(cx));
826 0 : return false;
827 : }
828 0 : return true;
829 : }
830 :
831 : static const JSJitInfo::ArgType values_methodinfo_argTypes[] = { JSJitInfo::ArgTypeListEnd };
832 : static const JSTypedMethodJitInfo values_methodinfo = {
833 : {
834 : { (JSJitGetterOp)values },
835 : { prototypes::id::FormData },
836 : { PrototypeTraits<prototypes::id::FormData>::Depth },
837 : JSJitInfo::Method,
838 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
839 : JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
840 : false, /* isInfallible. False in setters. */
841 : false, /* isMovable. Not relevant for setters. */
842 : false, /* isEliminatable. Not relevant for setters. */
843 : false, /* isAlwaysInSlot. Only relevant for getters. */
844 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
845 : true, /* isTypedMethod. Only relevant for methods. */
846 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
847 : },
848 : values_methodinfo_argTypes
849 : };
850 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
851 : static_assert(0 < 1, "There is no slot for us");
852 :
853 : static bool
854 0 : forEach(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::FormData* self, const JSJitMethodCallArgs& args)
855 : {
856 0 : JS::Rooted<JSObject*> arg0(cx);
857 0 : if (args.get(0).isObject()) {
858 0 : arg0 = &args.get(0).toObject();
859 : } else {
860 0 : ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 1 of FormData.forEach");
861 0 : return false;
862 : }
863 0 : JS::Rooted<JS::Value> arg1(cx);
864 0 : if (args.hasDefined(1)) {
865 0 : arg1 = args.get(1);
866 : } else {
867 0 : arg1 = JS::UndefinedValue();
868 : }
869 0 : if (!JS::IsCallable(arg0)) {
870 0 : ThrowErrorMessage(cx, MSG_NOT_CALLABLE, "Argument 1 of FormData.forEach");
871 0 : return false;
872 : }
873 0 : JS::AutoValueArray<3> callArgs(cx);
874 0 : callArgs[2].setObject(*obj);
875 0 : JS::Rooted<JS::Value> ignoredReturnVal(cx);
876 0 : for (size_t i = 0; i < self->GetIterableLength(); ++i) {
877 0 : if (!ToJSValue(cx, self->GetValueAtIndex(i), callArgs[0])) {
878 0 : return false;
879 : }
880 0 : if (!ToJSValue(cx, self->GetKeyAtIndex(i), callArgs[1])) {
881 0 : return false;
882 : }
883 0 : if (!JS::Call(cx, arg1, arg0, JS::HandleValueArray(callArgs),
884 : &ignoredReturnVal)) {
885 0 : return false;
886 : }
887 : }
888 0 : args.rval().setUndefined();
889 0 : return true;
890 : }
891 :
892 : static const JSJitInfo forEach_methodinfo = {
893 : { (JSJitGetterOp)forEach },
894 : { prototypes::id::FormData },
895 : { PrototypeTraits<prototypes::id::FormData>::Depth },
896 : JSJitInfo::Method,
897 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
898 : JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
899 : false, /* isInfallible. False in setters. */
900 : false, /* isMovable. Not relevant for setters. */
901 : false, /* isEliminatable. Not relevant for setters. */
902 : false, /* isAlwaysInSlot. Only relevant for getters. */
903 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
904 : false, /* isTypedMethod. Only relevant for methods. */
905 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
906 : };
907 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
908 : static_assert(0 < 1, "There is no slot for us");
909 :
910 : static bool
911 0 : _addProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::Handle<JS::Value> val)
912 : {
913 0 : mozilla::dom::FormData* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::FormData>(obj);
914 : // We don't want to preserve if we don't have a wrapper, and we
915 : // obviously can't preserve if we're not initialized.
916 0 : if (self && self->GetWrapperPreserveColor()) {
917 0 : PreserveWrapper(self);
918 : }
919 0 : return true;
920 : }
921 :
922 : static void
923 0 : _finalize(js::FreeOp* fop, JSObject* obj)
924 : {
925 0 : mozilla::dom::FormData* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::FormData>(obj);
926 0 : if (self) {
927 0 : ClearWrapper(self, self, obj);
928 0 : AddForDeferredFinalization<mozilla::dom::FormData>(self);
929 : }
930 0 : }
931 :
932 : static void
933 0 : _objectMoved(JSObject* obj, const JSObject* old)
934 : {
935 0 : mozilla::dom::FormData* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::FormData>(obj);
936 0 : if (self) {
937 0 : UpdateWrapper(self, self, obj, old);
938 : }
939 0 : }
940 :
941 : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
942 : #if defined(__clang__)
943 : #pragma clang diagnostic push
944 : #pragma clang diagnostic ignored "-Wmissing-braces"
945 : #endif
946 : static const JSFunctionSpec sMethods_specs[] = {
947 : JS_FNSPEC("append", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&append_methodinfo), 2, JSPROP_ENUMERATE, nullptr),
948 : JS_FNSPEC("delete", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&delete_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
949 : JS_FNSPEC("get", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&get_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
950 : JS_FNSPEC("getAll", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&getAll_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
951 : JS_FNSPEC("has", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&has_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
952 : JS_FNSPEC("set", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&set_methodinfo), 2, JSPROP_ENUMERATE, nullptr),
953 : JS_FNSPEC("entries", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&entries_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
954 : JS_FNSPEC("keys", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&keys_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
955 : JS_FNSPEC("values", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&values_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
956 : JS_FNSPEC("forEach", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&forEach_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
957 : JS_FS_END,
958 : JS_FNSPEC("QueryInterface", QueryInterface, nullptr, 1, 0, nullptr),
959 : JS_FS_END
960 : };
961 : #if defined(__clang__)
962 : #pragma clang diagnostic pop
963 : #endif
964 :
965 : static PrefableDisablers sMethods_disablers11 = {
966 : true, false, 0, &WantsQueryInterface<mozilla::dom::FormData>::Enabled
967 : };
968 :
969 : // Can't be const because the pref-enabled boolean needs to be writable
970 : static Prefable<const JSFunctionSpec> sMethods[] = {
971 : { nullptr, &sMethods_specs[0] },
972 : { &sMethods_disablers11, &sMethods_specs[11] },
973 : { nullptr, nullptr }
974 : };
975 :
976 : static_assert(2 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
977 : "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
978 : static_assert(10 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
979 : "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
980 :
981 :
982 : static uint16_t sNativeProperties_sortedPropertyIndices[11];
983 : static PropertyInfo sNativeProperties_propertyInfos[11];
984 :
985 : static const NativePropertiesN<1> sNativeProperties = {
986 : false, 0,
987 : false, 0,
988 : true, 0 /* sMethods */,
989 : false, 0,
990 : false, 0,
991 : false, 0,
992 : false, 0,
993 : 6,
994 : 11,
995 : sNativeProperties_sortedPropertyIndices,
996 : {
997 : { sMethods, &sNativeProperties_propertyInfos[0] }
998 : }
999 : };
1000 : static_assert(6 < 1ull << (CHAR_BIT * sizeof(sNativeProperties.iteratorAliasMethodIndex) - 1),
1001 : "We have an iterator alias index that is oversized");
1002 : static_assert(11 < 1ull << CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount),
1003 : "We have a property info count that is oversized");
1004 :
1005 : static bool
1006 0 : _constructor(JSContext* cx, unsigned argc, JS::Value* vp)
1007 : {
1008 0 : JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
1009 0 : JS::Rooted<JSObject*> obj(cx, &args.callee());
1010 0 : if (!args.isConstructing()) {
1011 : // XXXbz wish I could get the name from the callee instead of
1012 : // Adding more relocations
1013 0 : return ThrowConstructorWithoutNew(cx, "FormData");
1014 : }
1015 :
1016 0 : GlobalObject global(cx, obj);
1017 0 : if (global.Failed()) {
1018 0 : return false;
1019 : }
1020 :
1021 0 : JS::Rooted<JSObject*> desiredProto(cx);
1022 0 : if (!GetDesiredProto(cx, args, &desiredProto)) {
1023 0 : return false;
1024 : }
1025 :
1026 0 : bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
1027 0 : Optional<NonNull<mozilla::dom::HTMLFormElement>> arg0;
1028 0 : if (args.hasDefined(0)) {
1029 0 : arg0.Construct();
1030 0 : if (args[0].isObject()) {
1031 : {
1032 0 : nsresult rv = UnwrapObject<prototypes::id::HTMLFormElement, mozilla::dom::HTMLFormElement>(args[0], arg0.Value());
1033 0 : if (NS_FAILED(rv)) {
1034 0 : ThrowErrorMessage(cx, MSG_DOES_NOT_IMPLEMENT_INTERFACE, "Argument 1 of FormData.constructor", "HTMLFormElement");
1035 0 : return false;
1036 : }
1037 : }
1038 : } else {
1039 0 : ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 1 of FormData.constructor");
1040 0 : return false;
1041 : }
1042 : }
1043 0 : Maybe<JSAutoCompartment> ac;
1044 0 : if (objIsXray) {
1045 0 : obj = js::CheckedUnwrap(obj);
1046 0 : if (!obj) {
1047 0 : return false;
1048 : }
1049 0 : ac.emplace(cx, obj);
1050 0 : if (!JS_WrapObject(cx, &desiredProto)) {
1051 0 : return false;
1052 : }
1053 : }
1054 0 : binding_detail::FastErrorResult rv;
1055 0 : auto result(StrongOrRawPtr<mozilla::dom::FormData>(mozilla::dom::FormData::Constructor(global, NonNullHelper(Constify(arg0)), rv)));
1056 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
1057 0 : return false;
1058 : }
1059 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
1060 : static_assert(!IsPointer<decltype(result)>::value,
1061 : "NewObject implies that we need to keep the object alive with a strong reference.");
1062 0 : if (!GetOrCreateDOMReflector(cx, result, args.rval(), desiredProto)) {
1063 0 : MOZ_ASSERT(true || JS_IsExceptionPending(cx));
1064 0 : return false;
1065 : }
1066 0 : return true;
1067 : }
1068 :
1069 : static const js::ClassOps sInterfaceObjectClassOps = {
1070 : nullptr, /* addProperty */
1071 : nullptr, /* delProperty */
1072 : nullptr, /* getProperty */
1073 : nullptr, /* setProperty */
1074 : nullptr, /* enumerate */
1075 : nullptr, /* newEnumerate */
1076 : nullptr, /* resolve */
1077 : nullptr, /* mayResolve */
1078 : nullptr, /* finalize */
1079 : _constructor, /* call */
1080 : nullptr, /* hasInstance */
1081 : _constructor, /* construct */
1082 : nullptr, /* trace */
1083 : };
1084 :
1085 : static const DOMIfaceAndProtoJSClass sInterfaceObjectClass = {
1086 : {
1087 : "Function",
1088 : JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_SLOTS_BASE),
1089 : &sInterfaceObjectClassOps,
1090 : JS_NULL_CLASS_SPEC,
1091 : JS_NULL_CLASS_EXT,
1092 : &sInterfaceObjectClassObjectOps
1093 : },
1094 : eInterface,
1095 : true,
1096 : prototypes::id::FormData,
1097 : PrototypeTraits<prototypes::id::FormData>::Depth,
1098 : sNativePropertyHooks,
1099 : "function FormData() {\n [native code]\n}",
1100 : JS::GetRealmFunctionPrototype
1101 : };
1102 :
1103 : static const DOMIfaceAndProtoJSClass sPrototypeClass = {
1104 : {
1105 : "FormDataPrototype",
1106 : JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE),
1107 : JS_NULL_CLASS_OPS,
1108 : JS_NULL_CLASS_SPEC,
1109 : JS_NULL_CLASS_EXT,
1110 : JS_NULL_OBJECT_OPS
1111 : },
1112 : eInterfacePrototype,
1113 : false,
1114 : prototypes::id::FormData,
1115 : PrototypeTraits<prototypes::id::FormData>::Depth,
1116 : sNativePropertyHooks,
1117 : "[object FormDataPrototype]",
1118 : JS::GetRealmObjectPrototype
1119 : };
1120 :
1121 : JSObject*
1122 0 : DefineDOMInterface(JSContext* aCx, JS::Handle<JSObject*> aGlobal, JS::Handle<jsid> id, bool aDefineOnGlobal)
1123 : {
1124 0 : return GetConstructorObjectHandle(aCx, aDefineOnGlobal);
1125 : }
1126 :
1127 : static const js::ClassOps sClassOps = {
1128 : _addProperty, /* addProperty */
1129 : nullptr, /* delProperty */
1130 : nullptr, /* getProperty */
1131 : nullptr, /* setProperty */
1132 : nullptr, /* enumerate */
1133 : nullptr, /* newEnumerate */
1134 : nullptr, /* resolve */
1135 : nullptr, /* mayResolve */
1136 : _finalize, /* finalize */
1137 : nullptr, /* call */
1138 : nullptr, /* hasInstance */
1139 : nullptr, /* construct */
1140 : nullptr, /* trace */
1141 : };
1142 :
1143 : static const js::ClassExtension sClassExtension = {
1144 : nullptr, /* weakmapKeyDelegateOp */
1145 : _objectMoved /* objectMovedOp */
1146 : };
1147 :
1148 : static const DOMJSClass sClass = {
1149 : { "FormData",
1150 : JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1),
1151 : &sClassOps,
1152 : JS_NULL_CLASS_SPEC,
1153 : &sClassExtension,
1154 : JS_NULL_OBJECT_OPS
1155 : },
1156 : { prototypes::id::FormData, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
1157 : IsBaseOf<nsISupports, mozilla::dom::FormData >::value,
1158 : sNativePropertyHooks,
1159 : FindAssociatedGlobalForNative<mozilla::dom::FormData>::Get,
1160 : GetProtoObjectHandle,
1161 : GetCCParticipant<mozilla::dom::FormData>::Get()
1162 : };
1163 : static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
1164 : "Must have the right minimal number of reserved slots.");
1165 : static_assert(1 >= 1,
1166 : "Must have enough reserved slots.");
1167 :
1168 : const JSClass*
1169 0 : GetJSClass()
1170 : {
1171 0 : return sClass.ToJSClass();
1172 : }
1173 :
1174 : bool
1175 0 : Wrap(JSContext* aCx, mozilla::dom::FormData* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
1176 : {
1177 : MOZ_ASSERT(static_cast<mozilla::dom::FormData*>(aObject) ==
1178 : reinterpret_cast<mozilla::dom::FormData*>(aObject),
1179 : "Multiple inheritance for mozilla::dom::FormData is broken.");
1180 0 : MOZ_ASSERT(ToSupportsIsCorrect(aObject));
1181 0 : MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
1182 0 : MOZ_ASSERT(!aCache->GetWrapper(),
1183 : "You should probably not be using Wrap() directly; use "
1184 : "GetOrCreateDOMReflector instead");
1185 :
1186 0 : MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
1187 : "nsISupports must be on our primary inheritance chain");
1188 :
1189 0 : JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
1190 0 : if (!global) {
1191 0 : return false;
1192 : }
1193 0 : MOZ_ASSERT(JS_IsGlobalObject(global));
1194 0 : MOZ_ASSERT(JS::ObjectIsNotGray(global));
1195 :
1196 : // That might have ended up wrapping us already, due to the wonders
1197 : // of XBL. Check for that, and bail out as needed.
1198 0 : aReflector.set(aCache->GetWrapper());
1199 0 : if (aReflector) {
1200 : #ifdef DEBUG
1201 0 : binding_detail::AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
1202 : #endif // DEBUG
1203 0 : return true;
1204 : }
1205 :
1206 0 : JSAutoCompartment ac(aCx, global);
1207 0 : JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
1208 0 : if (!canonicalProto) {
1209 0 : return false;
1210 : }
1211 0 : JS::Rooted<JSObject*> proto(aCx);
1212 0 : if (aGivenProto) {
1213 0 : proto = aGivenProto;
1214 : // Unfortunately, while aGivenProto was in the compartment of aCx
1215 : // coming in, we changed compartments to that of "parent" so may need
1216 : // to wrap the proto here.
1217 0 : if (js::GetContextCompartment(aCx) != js::GetObjectCompartment(proto)) {
1218 0 : if (!JS_WrapObject(aCx, &proto)) {
1219 0 : return false;
1220 : }
1221 : }
1222 : } else {
1223 0 : proto = canonicalProto;
1224 : }
1225 :
1226 0 : BindingJSObjectCreator<mozilla::dom::FormData> creator(aCx);
1227 0 : creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
1228 0 : if (!aReflector) {
1229 0 : return false;
1230 : }
1231 :
1232 0 : aCache->SetWrapper(aReflector);
1233 0 : creator.InitializationSucceeded();
1234 :
1235 0 : MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
1236 : aCache->GetWrapperPreserveColor() == aReflector);
1237 : // If proto != canonicalProto, we have to preserve our wrapper;
1238 : // otherwise we won't be able to properly recreate it later, since
1239 : // we won't know what proto to use. Note that we don't check
1240 : // aGivenProto here, since it's entirely possible (and even
1241 : // somewhat common) to have a non-null aGivenProto which is the
1242 : // same as canonicalProto.
1243 0 : if (proto != canonicalProto) {
1244 0 : PreserveWrapper(aObject);
1245 : }
1246 :
1247 0 : return true;
1248 : }
1249 :
1250 : const NativePropertyHooks sNativePropertyHooks[] = { {
1251 : nullptr,
1252 : nullptr,
1253 : nullptr,
1254 : { sNativeProperties.Upcast(), nullptr },
1255 : prototypes::id::FormData,
1256 : constructors::id::FormData,
1257 : nullptr,
1258 : &DefaultXrayExpandoObjectClass
1259 : } };
1260 :
1261 : void
1262 1 : CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, bool aDefineOnGlobal)
1263 : {
1264 2 : JS::Rooted<JSObject*> parentProto(aCx, JS::GetRealmObjectPrototype(aCx));
1265 1 : if (!parentProto) {
1266 0 : return;
1267 : }
1268 :
1269 2 : JS::Rooted<JSObject*> constructorProto(aCx, JS::GetRealmFunctionPrototype(aCx));
1270 1 : if (!constructorProto) {
1271 0 : return;
1272 : }
1273 :
1274 : static bool sIdsInited = false;
1275 1 : if (!sIdsInited && NS_IsMainThread()) {
1276 0 : if (!InitIds(aCx, sNativeProperties.Upcast())) {
1277 0 : return;
1278 : }
1279 0 : sIdsInited = true;
1280 : }
1281 :
1282 1 : JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::FormData);
1283 1 : JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::FormData);
1284 2 : dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
1285 : &sPrototypeClass.mBase, protoCache,
1286 : constructorProto, &sInterfaceObjectClass.mBase, 0, nullptr,
1287 : interfaceCache,
1288 : sNativeProperties.Upcast(),
1289 : nullptr,
1290 : "FormData", aDefineOnGlobal,
1291 : nullptr,
1292 1 : false);
1293 :
1294 : // Set up aliases on the interface prototype object we just created.
1295 1 : JS::Handle<JSObject*> proto = GetProtoObjectHandle(aCx);
1296 1 : if (!proto) {
1297 0 : *protoCache = nullptr;
1298 0 : if (interfaceCache) {
1299 0 : *interfaceCache = nullptr;
1300 : }
1301 0 : return;
1302 : }
1303 :
1304 2 : JS::Rooted<JS::Value> aliasedVal(aCx);
1305 :
1306 1 : if (!JS_GetProperty(aCx, proto, "entries", &aliasedVal)) {
1307 0 : *protoCache = nullptr;
1308 0 : if (interfaceCache) {
1309 0 : *interfaceCache = nullptr;
1310 : }
1311 0 : return;
1312 : }
1313 2 : JS::Rooted<jsid> iteratorId(aCx, SYMBOL_TO_JSID(JS::GetWellKnownSymbol(aCx, JS::SymbolCode::iterator)));
1314 1 : if (!JS_DefinePropertyById(aCx, proto, iteratorId, aliasedVal, 0)) {
1315 0 : *protoCache = nullptr;
1316 0 : if (interfaceCache) {
1317 0 : *interfaceCache = nullptr;
1318 : }
1319 0 : return;
1320 : }
1321 : }
1322 :
1323 : JS::Handle<JSObject*>
1324 1 : GetProtoObjectHandle(JSContext* aCx)
1325 : {
1326 : /* Get the interface prototype object for this class. This will create the
1327 : object as needed. */
1328 1 : bool aDefineOnGlobal = true;
1329 :
1330 : /* Make sure our global is sane. Hopefully we can remove this sometime */
1331 1 : JSObject* global = JS::CurrentGlobalOrNull(aCx);
1332 1 : if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
1333 0 : return nullptr;
1334 : }
1335 :
1336 : /* Check to see whether the interface objects are already installed */
1337 1 : ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
1338 1 : if (!protoAndIfaceCache.HasEntryInSlot(prototypes::id::FormData)) {
1339 0 : JS::Rooted<JSObject*> rootedGlobal(aCx, global);
1340 0 : CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
1341 : }
1342 :
1343 : /*
1344 : * The object might _still_ be null, but that's OK.
1345 : *
1346 : * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
1347 : * traced by TraceProtoAndIfaceCache() and its contents are never
1348 : * changed after they have been set.
1349 : *
1350 : * Calling address() avoids the read read barrier that does gray
1351 : * unmarking, but it's not possible for the object to be gray here.
1352 : */
1353 :
1354 1 : const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(prototypes::id::FormData);
1355 1 : MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
1356 1 : return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
1357 : }
1358 :
1359 : JS::Handle<JSObject*>
1360 1 : GetConstructorObjectHandle(JSContext* aCx, bool aDefineOnGlobal)
1361 : {
1362 : /* Get the interface object for this class. This will create the object as
1363 : needed. */
1364 :
1365 : /* Make sure our global is sane. Hopefully we can remove this sometime */
1366 1 : JSObject* global = JS::CurrentGlobalOrNull(aCx);
1367 1 : if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
1368 0 : return nullptr;
1369 : }
1370 :
1371 : /* Check to see whether the interface objects are already installed */
1372 1 : ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
1373 1 : if (!protoAndIfaceCache.HasEntryInSlot(constructors::id::FormData)) {
1374 2 : JS::Rooted<JSObject*> rootedGlobal(aCx, global);
1375 1 : CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
1376 : }
1377 :
1378 : /*
1379 : * The object might _still_ be null, but that's OK.
1380 : *
1381 : * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
1382 : * traced by TraceProtoAndIfaceCache() and its contents are never
1383 : * changed after they have been set.
1384 : *
1385 : * Calling address() avoids the read read barrier that does gray
1386 : * unmarking, but it's not possible for the object to be gray here.
1387 : */
1388 :
1389 1 : const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(constructors::id::FormData);
1390 1 : MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
1391 1 : return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
1392 : }
1393 :
1394 : JSObject*
1395 1 : GetConstructorObject(JSContext* aCx)
1396 : {
1397 1 : return GetConstructorObjectHandle(aCx);
1398 : }
1399 :
1400 : } // namespace FormDataBinding
1401 :
1402 :
1403 :
1404 : namespace FormDataIteratorBinding {
1405 :
1406 : static bool
1407 0 : next(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::IterableIterator<mozilla::dom::FormData>* self, const JSJitMethodCallArgs& args)
1408 : {
1409 0 : binding_detail::FastErrorResult rv;
1410 0 : JS::Rooted<JSObject*> result(cx);
1411 0 : self->Next(cx, &result, rv);
1412 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
1413 0 : return false;
1414 : }
1415 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
1416 0 : JS::ExposeObjectToActiveJS(result);
1417 0 : args.rval().setObject(*result);
1418 0 : if (!MaybeWrapObjectValue(cx, args.rval())) {
1419 0 : return false;
1420 : }
1421 0 : return true;
1422 : }
1423 :
1424 : static const JSJitInfo next_methodinfo = {
1425 : { (JSJitGetterOp)next },
1426 : { prototypes::id::FormDataIterator },
1427 : { PrototypeTraits<prototypes::id::FormDataIterator>::Depth },
1428 : JSJitInfo::Method,
1429 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
1430 : JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
1431 : false, /* isInfallible. False in setters. */
1432 : false, /* isMovable. Not relevant for setters. */
1433 : false, /* isEliminatable. Not relevant for setters. */
1434 : false, /* isAlwaysInSlot. Only relevant for getters. */
1435 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
1436 : false, /* isTypedMethod. Only relevant for methods. */
1437 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
1438 : };
1439 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
1440 : static_assert(0 < 1, "There is no slot for us");
1441 :
1442 : static void
1443 0 : _finalize(js::FreeOp* fop, JSObject* obj)
1444 : {
1445 0 : mozilla::dom::IterableIterator<mozilla::dom::FormData>* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::IterableIterator<mozilla::dom::FormData>>(obj);
1446 0 : if (self) {
1447 0 : AddForDeferredFinalization<mozilla::dom::IterableIterator<mozilla::dom::FormData>>(self);
1448 : }
1449 0 : }
1450 :
1451 : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
1452 : #if defined(__clang__)
1453 : #pragma clang diagnostic push
1454 : #pragma clang diagnostic ignored "-Wmissing-braces"
1455 : #endif
1456 : static const JSFunctionSpec sMethods_specs[] = {
1457 : JS_FNSPEC("next", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&next_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
1458 : JS_FS_END
1459 : };
1460 : #if defined(__clang__)
1461 : #pragma clang diagnostic pop
1462 : #endif
1463 :
1464 :
1465 : // Can't be const because the pref-enabled boolean needs to be writable
1466 : static Prefable<const JSFunctionSpec> sMethods[] = {
1467 : { nullptr, &sMethods_specs[0] },
1468 : { nullptr, nullptr }
1469 : };
1470 :
1471 : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
1472 : "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
1473 : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
1474 : "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
1475 :
1476 :
1477 : static uint16_t sNativeProperties_sortedPropertyIndices[1];
1478 : static PropertyInfo sNativeProperties_propertyInfos[1];
1479 :
1480 : static const NativePropertiesN<1> sNativeProperties = {
1481 : false, 0,
1482 : false, 0,
1483 : true, 0 /* sMethods */,
1484 : false, 0,
1485 : false, 0,
1486 : false, 0,
1487 : false, 0,
1488 : -1,
1489 : 1,
1490 : sNativeProperties_sortedPropertyIndices,
1491 : {
1492 : { sMethods, &sNativeProperties_propertyInfos[0] }
1493 : }
1494 : };
1495 : static_assert(1 < 1ull << CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount),
1496 : "We have a property info count that is oversized");
1497 :
1498 : static const DOMIfaceAndProtoJSClass sPrototypeClass = {
1499 : {
1500 : "FormDataIteratorPrototype",
1501 : JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE),
1502 : JS_NULL_CLASS_OPS,
1503 : JS_NULL_CLASS_SPEC,
1504 : JS_NULL_CLASS_EXT,
1505 : JS_NULL_OBJECT_OPS
1506 : },
1507 : eInterfacePrototype,
1508 : false,
1509 : prototypes::id::FormDataIterator,
1510 : PrototypeTraits<prototypes::id::FormDataIterator>::Depth,
1511 : sNativePropertyHooks,
1512 : "[object FormDataIteratorPrototype]",
1513 : JS::GetRealmIteratorPrototype
1514 : };
1515 :
1516 : static const js::ClassOps sClassOps = {
1517 : nullptr, /* addProperty */
1518 : nullptr, /* delProperty */
1519 : nullptr, /* getProperty */
1520 : nullptr, /* setProperty */
1521 : nullptr, /* enumerate */
1522 : nullptr, /* newEnumerate */
1523 : nullptr, /* resolve */
1524 : nullptr, /* mayResolve */
1525 : _finalize, /* finalize */
1526 : nullptr, /* call */
1527 : nullptr, /* hasInstance */
1528 : nullptr, /* construct */
1529 : nullptr, /* trace */
1530 : };
1531 :
1532 : static const js::ClassExtension sClassExtension = {
1533 : nullptr, /* weakmapKeyDelegateOp */
1534 : nullptr /* objectMovedOp */
1535 : };
1536 :
1537 : static const DOMJSClass sClass = {
1538 : { "FormDataIterator",
1539 : JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1),
1540 : &sClassOps,
1541 : JS_NULL_CLASS_SPEC,
1542 : &sClassExtension,
1543 : JS_NULL_OBJECT_OPS
1544 : },
1545 : { prototypes::id::FormDataIterator, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
1546 : IsBaseOf<nsISupports, mozilla::dom::IterableIterator<mozilla::dom::FormData> >::value,
1547 : sNativePropertyHooks,
1548 : FindAssociatedGlobalForNative<mozilla::dom::IterableIterator<mozilla::dom::FormData>>::Get,
1549 : GetProtoObjectHandle,
1550 : GetCCParticipant<mozilla::dom::IterableIterator<mozilla::dom::FormData>>::Get()
1551 : };
1552 : static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
1553 : "Must have the right minimal number of reserved slots.");
1554 : static_assert(1 >= 1,
1555 : "Must have enough reserved slots.");
1556 :
1557 : const JSClass*
1558 0 : GetJSClass()
1559 : {
1560 0 : return sClass.ToJSClass();
1561 : }
1562 :
1563 : bool
1564 0 : Wrap(JSContext* aCx, mozilla::dom::IterableIterator<mozilla::dom::FormData>* aObject, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
1565 : {
1566 : MOZ_ASSERT(static_cast<mozilla::dom::IterableIterator<mozilla::dom::FormData>*>(aObject) ==
1567 : reinterpret_cast<mozilla::dom::IterableIterator<mozilla::dom::FormData>*>(aObject),
1568 : "Multiple inheritance for mozilla::dom::IterableIterator<mozilla::dom::FormData> is broken.");
1569 0 : MOZ_ASSERT(ToSupportsIsCorrect(aObject));
1570 0 : MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
1571 :
1572 0 : JS::Rooted<JSObject*> global(aCx, JS::CurrentGlobalOrNull(aCx));
1573 0 : JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
1574 0 : if (!canonicalProto) {
1575 0 : return false;
1576 : }
1577 0 : JS::Rooted<JSObject*> proto(aCx);
1578 0 : if (aGivenProto) {
1579 0 : proto = aGivenProto;
1580 : // Unfortunately, while aGivenProto was in the compartment of aCx
1581 : // coming in, we changed compartments to that of "parent" so may need
1582 : // to wrap the proto here.
1583 0 : if (js::GetContextCompartment(aCx) != js::GetObjectCompartment(proto)) {
1584 0 : if (!JS_WrapObject(aCx, &proto)) {
1585 0 : return false;
1586 : }
1587 : }
1588 : } else {
1589 0 : proto = canonicalProto;
1590 : }
1591 :
1592 0 : BindingJSObjectCreator<mozilla::dom::IterableIterator<mozilla::dom::FormData>> creator(aCx);
1593 0 : creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
1594 0 : if (!aReflector) {
1595 0 : return false;
1596 : }
1597 :
1598 :
1599 :
1600 0 : creator.InitializationSucceeded();
1601 0 : return true;
1602 : }
1603 :
1604 : const NativePropertyHooks sNativePropertyHooks[] = { {
1605 : nullptr,
1606 : nullptr,
1607 : nullptr,
1608 : { sNativeProperties.Upcast(), nullptr },
1609 : prototypes::id::FormDataIterator,
1610 : constructors::id::_ID_Count,
1611 : nullptr,
1612 : &DefaultXrayExpandoObjectClass
1613 : } };
1614 :
1615 : void
1616 0 : CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, bool aDefineOnGlobal)
1617 : {
1618 0 : JS::Rooted<JSObject*> parentProto(aCx, JS::GetRealmIteratorPrototype(aCx));
1619 0 : if (!parentProto) {
1620 0 : return;
1621 : }
1622 :
1623 : static bool sIdsInited = false;
1624 0 : if (!sIdsInited && NS_IsMainThread()) {
1625 0 : if (!InitIds(aCx, sNativeProperties.Upcast())) {
1626 0 : return;
1627 : }
1628 0 : sIdsInited = true;
1629 : }
1630 :
1631 0 : JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::FormDataIterator);
1632 0 : JS::Heap<JSObject*>* interfaceCache = nullptr;
1633 0 : dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
1634 : &sPrototypeClass.mBase, protoCache,
1635 : nullptr, nullptr, 0, nullptr,
1636 : interfaceCache,
1637 : sNativeProperties.Upcast(),
1638 : nullptr,
1639 : nullptr, aDefineOnGlobal,
1640 : nullptr,
1641 0 : false);
1642 : }
1643 :
1644 : JS::Handle<JSObject*>
1645 0 : GetProtoObjectHandle(JSContext* aCx)
1646 : {
1647 : /* Get the interface prototype object for this class. This will create the
1648 : object as needed. */
1649 0 : bool aDefineOnGlobal = true;
1650 :
1651 : /* Make sure our global is sane. Hopefully we can remove this sometime */
1652 0 : JSObject* global = JS::CurrentGlobalOrNull(aCx);
1653 0 : if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
1654 0 : return nullptr;
1655 : }
1656 :
1657 : /* Check to see whether the interface objects are already installed */
1658 0 : ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
1659 0 : if (!protoAndIfaceCache.HasEntryInSlot(prototypes::id::FormDataIterator)) {
1660 0 : JS::Rooted<JSObject*> rootedGlobal(aCx, global);
1661 0 : CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
1662 : }
1663 :
1664 : /*
1665 : * The object might _still_ be null, but that's OK.
1666 : *
1667 : * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
1668 : * traced by TraceProtoAndIfaceCache() and its contents are never
1669 : * changed after they have been set.
1670 : *
1671 : * Calling address() avoids the read read barrier that does gray
1672 : * unmarking, but it's not possible for the object to be gray here.
1673 : */
1674 :
1675 0 : const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(prototypes::id::FormDataIterator);
1676 0 : MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
1677 0 : return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
1678 : }
1679 :
1680 : } // namespace FormDataIteratorBinding
1681 :
1682 :
1683 :
1684 : } // namespace dom
1685 : } // namespace mozilla
|