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