Line data Source code
1 : /* THIS FILE IS AUTOGENERATED FROM SecureElement.webidl BY Codegen.py - DO NOT EDIT */
2 :
3 : #include "AtomList.h"
4 : #include "SecureElementBinding.h"
5 : #include "WrapperFactory.h"
6 : #include "XrayWrapper.h"
7 : #include "jsapi.h"
8 : #include "jsfriendapi.h"
9 : #include "mozilla/OwningNonNull.h"
10 : #include "mozilla/Preferences.h"
11 : #include "mozilla/dom/BindingUtils.h"
12 : #include "mozilla/dom/DOMJSClass.h"
13 : #include "mozilla/dom/NonRefcountedDOMObject.h"
14 : #include "mozilla/dom/Nullable.h"
15 : #include "mozilla/dom/PrimitiveConversions.h"
16 : #include "mozilla/dom/Promise.h"
17 : #include "mozilla/dom/ScriptSettings.h"
18 : #include "mozilla/dom/SimpleGlobalObject.h"
19 : #include "mozilla/dom/ToJSValue.h"
20 : #include "mozilla/dom/XrayExpandoClass.h"
21 : #include "nsContentUtils.h"
22 : #include "nsIGlobalObject.h"
23 :
24 : namespace mozilla {
25 : namespace dom {
26 :
27 : namespace SETypeValues {
28 : extern const EnumEntry strings[3] = {
29 : {"uicc", 4},
30 : {"eSE", 3},
31 : { nullptr, 0 }
32 : };
33 : } // namespace SETypeValues
34 :
35 : bool
36 0 : ToJSValue(JSContext* aCx, SEType aArgument, JS::MutableHandle<JS::Value> aValue)
37 : {
38 0 : MOZ_ASSERT(uint32_t(aArgument) < ArrayLength(SETypeValues::strings));
39 : JSString* resultStr =
40 0 : JS_NewStringCopyN(aCx, SETypeValues::strings[uint32_t(aArgument)].value,
41 0 : SETypeValues::strings[uint32_t(aArgument)].length);
42 0 : if (!resultStr) {
43 0 : return false;
44 : }
45 0 : aValue.setString(resultStr);
46 0 : return true;
47 : }
48 :
49 :
50 : namespace SEErrorValues {
51 : extern const EnumEntry strings[9] = {
52 : {"SESecurityError", 15},
53 : {"SEIoError", 9},
54 : {"SEBadStateError", 15},
55 : {"SEInvalidChannelError", 21},
56 : {"SEInvalidApplicationError", 25},
57 : {"SENotPresentError", 17},
58 : {"SEIllegalParameterError", 23},
59 : {"SEGenericError", 14},
60 : { nullptr, 0 }
61 : };
62 : } // namespace SEErrorValues
63 :
64 : bool
65 0 : ToJSValue(JSContext* aCx, SEError aArgument, JS::MutableHandle<JS::Value> aValue)
66 : {
67 0 : MOZ_ASSERT(uint32_t(aArgument) < ArrayLength(SEErrorValues::strings));
68 : JSString* resultStr =
69 0 : JS_NewStringCopyN(aCx, SEErrorValues::strings[uint32_t(aArgument)].value,
70 0 : SEErrorValues::strings[uint32_t(aArgument)].length);
71 0 : if (!resultStr) {
72 0 : return false;
73 : }
74 0 : aValue.setString(resultStr);
75 0 : return true;
76 : }
77 :
78 :
79 : namespace SEChannelTypeValues {
80 : extern const EnumEntry strings[3] = {
81 : {"basic", 5},
82 : {"logical", 7},
83 : { nullptr, 0 }
84 : };
85 : } // namespace SEChannelTypeValues
86 :
87 : bool
88 0 : ToJSValue(JSContext* aCx, SEChannelType aArgument, JS::MutableHandle<JS::Value> aValue)
89 : {
90 0 : MOZ_ASSERT(uint32_t(aArgument) < ArrayLength(SEChannelTypeValues::strings));
91 : JSString* resultStr =
92 0 : JS_NewStringCopyN(aCx, SEChannelTypeValues::strings[uint32_t(aArgument)].value,
93 0 : SEChannelTypeValues::strings[uint32_t(aArgument)].length);
94 0 : if (!resultStr) {
95 0 : return false;
96 : }
97 0 : aValue.setString(resultStr);
98 0 : return true;
99 : }
100 :
101 :
102 :
103 0 : SECommand::SECommand()
104 : {
105 : // Safe to pass a null context if we pass a null value
106 0 : Init(nullptr, JS::NullHandleValue);
107 0 : }
108 :
109 :
110 :
111 : bool
112 0 : SECommand::InitIds(JSContext* cx, SECommandAtoms* atomsCache)
113 : {
114 0 : MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
115 :
116 : // Initialize these in reverse order so that any failure leaves the first one
117 : // uninitialized.
118 0 : if (!atomsCache->p2_id.init(cx, "p2") ||
119 0 : !atomsCache->p1_id.init(cx, "p1") ||
120 0 : !atomsCache->le_id.init(cx, "le") ||
121 0 : !atomsCache->ins_id.init(cx, "ins") ||
122 0 : !atomsCache->data_id.init(cx, "data") ||
123 0 : !atomsCache->cla_id.init(cx, "cla")) {
124 0 : return false;
125 : }
126 0 : return true;
127 : }
128 :
129 : bool
130 0 : SECommand::Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
131 : {
132 : // Passing a null JSContext is OK only if we're initing from null,
133 : // Since in that case we will not have to do any property gets
134 : // Also evaluate isNullOrUndefined in order to avoid false-positive
135 : // checkers by static analysis tools
136 0 : MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
137 0 : SECommandAtoms* atomsCache = nullptr;
138 0 : if (cx) {
139 0 : atomsCache = GetAtomCache<SECommandAtoms>(cx);
140 0 : if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
141 0 : return false;
142 : }
143 : }
144 :
145 0 : if (!IsConvertibleToDictionary(val)) {
146 0 : return ThrowErrorMessage(cx, MSG_NOT_DICTIONARY, sourceDescription);
147 : }
148 :
149 0 : bool isNull = val.isNullOrUndefined();
150 : // We only need these if !isNull, in which case we have |cx|.
151 0 : Maybe<JS::Rooted<JSObject *> > object;
152 0 : Maybe<JS::Rooted<JS::Value> > temp;
153 0 : if (!isNull) {
154 0 : MOZ_ASSERT(cx);
155 0 : object.emplace(cx, &val.toObject());
156 0 : temp.emplace(cx);
157 : }
158 0 : if (!isNull) {
159 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->cla_id, temp.ptr())) {
160 0 : return false;
161 : }
162 : }
163 0 : if (!isNull && !temp->isUndefined()) {
164 0 : if (!ValueToPrimitive<uint8_t, eDefault>(cx, temp.ref(), &mCla)) {
165 0 : return false;
166 : }
167 0 : mIsAnyMemberPresent = true;
168 0 : } else if (cx) {
169 : // Don't error out if we have no cx. In that
170 : // situation the caller is default-constructing us and we'll
171 : // just assume they know what they're doing.
172 0 : return ThrowErrorMessage(cx, MSG_MISSING_REQUIRED_DICTIONARY_MEMBER,
173 0 : "'cla' member of SECommand");
174 : }
175 :
176 0 : if (!isNull) {
177 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->data_id, temp.ptr())) {
178 0 : return false;
179 : }
180 : }
181 0 : if (!isNull && !temp->isUndefined()) {
182 0 : if (temp.ref().isObject()) {
183 0 : JS::ForOfIterator iter(cx);
184 0 : if (!iter.init(temp.ref(), JS::ForOfIterator::AllowNonIterable)) {
185 0 : return false;
186 : }
187 0 : if (!iter.valueIsIterable()) {
188 0 : ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "'data' member of SECommand");
189 0 : return false;
190 : }
191 0 : Sequence<uint8_t> &arr = mData.SetValue();
192 0 : JS::Rooted<JS::Value> temp(cx);
193 : while (true) {
194 : bool done;
195 0 : if (!iter.next(&temp, &done)) {
196 0 : return false;
197 : }
198 0 : if (done) {
199 0 : break;
200 : }
201 0 : uint8_t* slotPtr = arr.AppendElement(mozilla::fallible);
202 0 : if (!slotPtr) {
203 0 : JS_ReportOutOfMemory(cx);
204 0 : return false;
205 : }
206 0 : uint8_t& slot = *slotPtr;
207 0 : if (!ValueToPrimitive<uint8_t, eDefault>(cx, temp, &slot)) {
208 0 : return false;
209 : }
210 0 : }
211 0 : } else if (temp.ref().isNullOrUndefined()) {
212 0 : mData.SetNull();
213 : } else {
214 0 : ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "'data' member of SECommand");
215 0 : return false;
216 : }
217 : } else {
218 0 : mData.SetNull();
219 : }
220 0 : mIsAnyMemberPresent = true;
221 :
222 0 : if (!isNull) {
223 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->ins_id, temp.ptr())) {
224 0 : return false;
225 : }
226 : }
227 0 : if (!isNull && !temp->isUndefined()) {
228 0 : if (!ValueToPrimitive<uint8_t, eDefault>(cx, temp.ref(), &mIns)) {
229 0 : return false;
230 : }
231 0 : mIsAnyMemberPresent = true;
232 0 : } else if (cx) {
233 : // Don't error out if we have no cx. In that
234 : // situation the caller is default-constructing us and we'll
235 : // just assume they know what they're doing.
236 0 : return ThrowErrorMessage(cx, MSG_MISSING_REQUIRED_DICTIONARY_MEMBER,
237 0 : "'ins' member of SECommand");
238 : }
239 :
240 0 : if (!isNull) {
241 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->le_id, temp.ptr())) {
242 0 : return false;
243 : }
244 : }
245 0 : if (!isNull && !temp->isUndefined()) {
246 0 : if (!ValueToPrimitive<int16_t, eDefault>(cx, temp.ref(), &mLe)) {
247 0 : return false;
248 : }
249 : } else {
250 0 : mLe = -1;
251 : }
252 0 : mIsAnyMemberPresent = true;
253 :
254 0 : if (!isNull) {
255 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->p1_id, temp.ptr())) {
256 0 : return false;
257 : }
258 : }
259 0 : if (!isNull && !temp->isUndefined()) {
260 0 : if (!ValueToPrimitive<uint8_t, eDefault>(cx, temp.ref(), &mP1)) {
261 0 : return false;
262 : }
263 0 : mIsAnyMemberPresent = true;
264 0 : } else if (cx) {
265 : // Don't error out if we have no cx. In that
266 : // situation the caller is default-constructing us and we'll
267 : // just assume they know what they're doing.
268 0 : return ThrowErrorMessage(cx, MSG_MISSING_REQUIRED_DICTIONARY_MEMBER,
269 0 : "'p1' member of SECommand");
270 : }
271 :
272 0 : if (!isNull) {
273 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->p2_id, temp.ptr())) {
274 0 : return false;
275 : }
276 : }
277 0 : if (!isNull && !temp->isUndefined()) {
278 0 : if (!ValueToPrimitive<uint8_t, eDefault>(cx, temp.ref(), &mP2)) {
279 0 : return false;
280 : }
281 0 : mIsAnyMemberPresent = true;
282 0 : } else if (cx) {
283 : // Don't error out if we have no cx. In that
284 : // situation the caller is default-constructing us and we'll
285 : // just assume they know what they're doing.
286 0 : return ThrowErrorMessage(cx, MSG_MISSING_REQUIRED_DICTIONARY_MEMBER,
287 0 : "'p2' member of SECommand");
288 : }
289 0 : return true;
290 : }
291 :
292 : bool
293 0 : SECommand::Init(const nsAString& aJSON)
294 : {
295 0 : AutoJSAPI jsapi;
296 0 : JSObject* cleanGlobal = SimpleGlobalObject::Create(SimpleGlobalObject::GlobalType::BindingDetail);
297 0 : if (!cleanGlobal) {
298 0 : return false;
299 : }
300 0 : if (!jsapi.Init(cleanGlobal)) {
301 0 : return false;
302 : }
303 0 : JSContext* cx = jsapi.cx();
304 0 : JS::Rooted<JS::Value> json(cx);
305 0 : bool ok = ParseJSON(cx, aJSON, &json);
306 0 : NS_ENSURE_TRUE(ok, false);
307 0 : return Init(cx, json);
308 : }
309 :
310 : bool
311 0 : SECommand::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
312 : {
313 0 : SECommandAtoms* atomsCache = GetAtomCache<SECommandAtoms>(cx);
314 0 : if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
315 0 : return false;
316 : }
317 :
318 0 : JS::Rooted<JSObject*> obj(cx, JS_NewPlainObject(cx));
319 0 : if (!obj) {
320 0 : return false;
321 : }
322 0 : rval.set(JS::ObjectValue(*obj));
323 :
324 : do {
325 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
326 0 : JS::Rooted<JS::Value> temp(cx);
327 0 : uint8_t const & currentValue = mCla;
328 0 : temp.setInt32(int32_t(currentValue));
329 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->cla_id, temp, JSPROP_ENUMERATE)) {
330 0 : return false;
331 : }
332 0 : break;
333 : } while(0);
334 :
335 : do {
336 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
337 0 : JS::Rooted<JS::Value> temp(cx);
338 0 : Nullable<Sequence<uint8_t>> const & currentValue = mData;
339 :
340 0 : if (currentValue.IsNull()) {
341 0 : temp.setNull();
342 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->data_id, temp, JSPROP_ENUMERATE)) {
343 0 : return false;
344 : }
345 0 : break;
346 : }
347 :
348 0 : uint32_t length = currentValue.Value().Length();
349 0 : JS::Rooted<JSObject*> returnArray(cx, JS_NewArrayObject(cx, length));
350 0 : if (!returnArray) {
351 0 : return false;
352 : }
353 : // Scope for 'tmp'
354 : {
355 0 : JS::Rooted<JS::Value> tmp(cx);
356 0 : for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
357 : // Control block to let us common up the JS_DefineElement calls when there
358 : // are different ways to succeed at wrapping the object.
359 : do {
360 0 : tmp.setInt32(int32_t(currentValue.Value()[sequenceIdx0]));
361 0 : break;
362 : } while (0);
363 0 : if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
364 : JSPROP_ENUMERATE)) {
365 0 : return false;
366 : }
367 : }
368 : }
369 0 : temp.setObject(*returnArray);
370 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->data_id, temp, JSPROP_ENUMERATE)) {
371 0 : return false;
372 : }
373 0 : break;
374 : } while(0);
375 :
376 : do {
377 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
378 0 : JS::Rooted<JS::Value> temp(cx);
379 0 : uint8_t const & currentValue = mIns;
380 0 : temp.setInt32(int32_t(currentValue));
381 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->ins_id, temp, JSPROP_ENUMERATE)) {
382 0 : return false;
383 : }
384 0 : break;
385 : } while(0);
386 :
387 : do {
388 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
389 0 : JS::Rooted<JS::Value> temp(cx);
390 0 : int16_t const & currentValue = mLe;
391 0 : temp.setInt32(int32_t(currentValue));
392 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->le_id, temp, JSPROP_ENUMERATE)) {
393 0 : return false;
394 : }
395 0 : break;
396 : } while(0);
397 :
398 : do {
399 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
400 0 : JS::Rooted<JS::Value> temp(cx);
401 0 : uint8_t const & currentValue = mP1;
402 0 : temp.setInt32(int32_t(currentValue));
403 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->p1_id, temp, JSPROP_ENUMERATE)) {
404 0 : return false;
405 : }
406 0 : break;
407 : } while(0);
408 :
409 : do {
410 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
411 0 : JS::Rooted<JS::Value> temp(cx);
412 0 : uint8_t const & currentValue = mP2;
413 0 : temp.setInt32(int32_t(currentValue));
414 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->p2_id, temp, JSPROP_ENUMERATE)) {
415 0 : return false;
416 : }
417 0 : break;
418 : } while(0);
419 :
420 0 : return true;
421 : }
422 :
423 : bool
424 0 : SECommand::ToJSON(nsAString& aJSON) const
425 : {
426 0 : AutoJSAPI jsapi;
427 0 : jsapi.Init();
428 0 : JSContext *cx = jsapi.cx();
429 : // It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here
430 : // because we'll only be creating objects, in ways that have no
431 : // side-effects, followed by a call to JS::ToJSONMaybeSafely,
432 : // which likewise guarantees no side-effects for the sorts of
433 : // things we will pass it.
434 0 : JSAutoCompartment ac(cx, binding_detail::UnprivilegedJunkScopeOrWorkerGlobal());
435 0 : JS::Rooted<JS::Value> val(cx);
436 0 : if (!ToObjectInternal(cx, &val)) {
437 0 : return false;
438 : }
439 0 : JS::Rooted<JSObject*> obj(cx, &val.toObject());
440 0 : return StringifyToJSON(cx, obj, aJSON);
441 : }
442 :
443 : void
444 0 : SECommand::TraceDictionary(JSTracer* trc)
445 : {
446 0 : }
447 :
448 : SECommand&
449 0 : SECommand::operator=(const SECommand& aOther)
450 : {
451 0 : mCla = aOther.mCla;
452 0 : mData = aOther.mData;
453 0 : mIns = aOther.mIns;
454 0 : mLe = aOther.mLe;
455 0 : mP1 = aOther.mP1;
456 0 : mP2 = aOther.mP2;
457 0 : return *this;
458 : }
459 :
460 : namespace binding_detail {
461 : } // namespace binding_detail
462 :
463 :
464 : namespace SEChannelBinding {
465 :
466 : static bool
467 0 : get_session(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::SEChannel* self, JSJitGetterCallArgs args)
468 : {
469 0 : Maybe<JS::Rooted<JSObject*> > unwrappedObj;
470 0 : bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
471 0 : if (objIsXray) {
472 0 : unwrappedObj.emplace(cx, obj);
473 : }
474 0 : if (objIsXray) {
475 0 : unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
476 0 : if (!unwrappedObj.ref()) {
477 0 : return false;
478 : }
479 : }
480 0 : binding_detail::FastErrorResult rv;
481 0 : auto result(StrongOrRawPtr<mozilla::dom::SESession>(self->GetSession(rv, js::GetObjectCompartment(unwrappedObj ? *unwrappedObj : obj))));
482 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
483 0 : return false;
484 : }
485 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
486 0 : if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
487 0 : MOZ_ASSERT(true || JS_IsExceptionPending(cx));
488 0 : return false;
489 : }
490 0 : return true;
491 : }
492 :
493 : static const JSJitInfo session_getterinfo = {
494 : { (JSJitGetterOp)get_session },
495 : { prototypes::id::SEChannel },
496 : { PrototypeTraits<prototypes::id::SEChannel>::Depth },
497 : JSJitInfo::Getter,
498 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
499 : JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
500 : false, /* isInfallible. False in setters. */
501 : false, /* isMovable. Not relevant for setters. */
502 : false, /* isEliminatable. Not relevant for setters. */
503 : false, /* isAlwaysInSlot. Only relevant for getters. */
504 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
505 : false, /* isTypedMethod. Only relevant for methods. */
506 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
507 : };
508 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
509 : static_assert(0 < 2, "There is no slot for us");
510 :
511 : static bool
512 0 : get_openResponse(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::SEChannel* self, JSJitGetterCallArgs args)
513 : {
514 : // Have to either root across the getter call or reget after.
515 : bool isXray;
516 0 : JS::Rooted<JSObject*> slotStorage(cx, GetCachedSlotStorageObject(cx, obj, &isXray));
517 0 : if (!slotStorage) {
518 0 : return false;
519 : }
520 0 : const size_t slotIndex = isXray ? (xpc::JSSLOT_EXPANDO_COUNT + 0) : (DOM_INSTANCE_RESERVED_SLOTS + 0);
521 0 : MOZ_ASSERT(JSCLASS_RESERVED_SLOTS(js::GetObjectClass(slotStorage)) > slotIndex);
522 : {
523 : // Scope for cachedVal
524 0 : JS::Value cachedVal = js::GetReservedSlot(slotStorage, slotIndex);
525 0 : if (!cachedVal.isUndefined()) {
526 0 : args.rval().set(cachedVal);
527 : // The cached value is in the compartment of slotStorage,
528 : // so wrap into the caller compartment as needed.
529 0 : return MaybeWrapNonDOMObjectOrNullValue(cx, args.rval());
530 : }
531 : }
532 :
533 0 : Maybe<JS::Rooted<JSObject*> > unwrappedObj;
534 0 : bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
535 0 : if (objIsXray) {
536 0 : unwrappedObj.emplace(cx, obj);
537 : }
538 0 : if (objIsXray) {
539 0 : unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
540 0 : if (!unwrappedObj.ref()) {
541 0 : return false;
542 : }
543 : }
544 0 : binding_detail::FastErrorResult rv;
545 0 : JS::Rooted<JSObject*> result(cx);
546 0 : self->GetOpenResponse(&result, rv, js::GetObjectCompartment(unwrappedObj ? *unwrappedObj : obj));
547 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
548 0 : return false;
549 : }
550 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
551 : {
552 0 : JS::Rooted<JSObject*> conversionScope(cx, isXray ? obj : slotStorage);
553 0 : JSAutoCompartment ac(cx, conversionScope);
554 : do { // block we break out of when done wrapping
555 0 : if (result) {
556 0 : JS::ExposeObjectToActiveJS(result);
557 : }
558 0 : args.rval().setObjectOrNull(result);
559 0 : if (!MaybeWrapNonDOMObjectOrNullValue(cx, args.rval())) {
560 0 : return false;
561 : }
562 0 : break;
563 : } while (0);
564 : }
565 : { // And now store things in the compartment of our slotStorage.
566 0 : JSAutoCompartment ac(cx, slotStorage);
567 : // Make a copy so that we don't do unnecessary wrapping on args.rval().
568 0 : JS::Rooted<JS::Value> storedVal(cx, args.rval());
569 0 : if (!MaybeWrapNonDOMObjectOrNullValue(cx, &storedVal)) {
570 0 : return false;
571 : }
572 0 : js::SetReservedSlot(slotStorage, slotIndex, storedVal);
573 0 : if (!isXray) {
574 : // In the Xray case we don't need to do this, because getting the
575 : // expando object already preserved our wrapper.
576 0 : PreserveWrapper(self);
577 : }
578 : }
579 : // And now make sure args.rval() is in the caller compartment
580 0 : return MaybeWrapNonDOMObjectOrNullValue(cx, args.rval());
581 : }
582 :
583 : static const JSJitInfo openResponse_getterinfo = {
584 : { (JSJitGetterOp)get_openResponse },
585 : { prototypes::id::SEChannel },
586 : { PrototypeTraits<prototypes::id::SEChannel>::Depth },
587 : JSJitInfo::Getter,
588 : JSJitInfo::AliasNone, /* aliasSet. Not relevant for setters. */
589 : JSVAL_TYPE_UNKNOWN, /* returnType. Not relevant for setters. */
590 : false, /* isInfallible. False in setters. */
591 : false, /* isMovable. Not relevant for setters. */
592 : false, /* isEliminatable. Not relevant for setters. */
593 : false, /* isAlwaysInSlot. Only relevant for getters. */
594 : true, /* isLazilyCachedInSlot. Only relevant for getters. */
595 : false, /* isTypedMethod. Only relevant for methods. */
596 : (DOM_INSTANCE_RESERVED_SLOTS + 0) /* Reserved slot index, if we're stored in a slot, else 0. */
597 : };
598 : static_assert((DOM_INSTANCE_RESERVED_SLOTS + 0) <= JSJitInfo::maxSlotIndex, "We won't fit");
599 : static_assert((DOM_INSTANCE_RESERVED_SLOTS + 0) < 2, "There is no slot for us");
600 :
601 : static bool
602 0 : get_isClosed(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::SEChannel* self, JSJitGetterCallArgs args)
603 : {
604 0 : Maybe<JS::Rooted<JSObject*> > unwrappedObj;
605 0 : bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
606 0 : if (objIsXray) {
607 0 : unwrappedObj.emplace(cx, obj);
608 : }
609 0 : if (objIsXray) {
610 0 : unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
611 0 : if (!unwrappedObj.ref()) {
612 0 : return false;
613 : }
614 : }
615 0 : binding_detail::FastErrorResult rv;
616 0 : bool result(self->GetIsClosed(rv, js::GetObjectCompartment(unwrappedObj ? *unwrappedObj : obj)));
617 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
618 0 : return false;
619 : }
620 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
621 0 : args.rval().setBoolean(result);
622 0 : return true;
623 : }
624 :
625 : static const JSJitInfo isClosed_getterinfo = {
626 : { (JSJitGetterOp)get_isClosed },
627 : { prototypes::id::SEChannel },
628 : { PrototypeTraits<prototypes::id::SEChannel>::Depth },
629 : JSJitInfo::Getter,
630 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
631 : JSVAL_TYPE_BOOLEAN, /* returnType. Not relevant for setters. */
632 : false, /* isInfallible. False in setters. */
633 : false, /* isMovable. Not relevant for setters. */
634 : false, /* isEliminatable. Not relevant for setters. */
635 : false, /* isAlwaysInSlot. Only relevant for getters. */
636 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
637 : false, /* isTypedMethod. Only relevant for methods. */
638 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
639 : };
640 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
641 : static_assert(0 < 2, "There is no slot for us");
642 :
643 : static bool
644 0 : get_type(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::SEChannel* self, JSJitGetterCallArgs args)
645 : {
646 0 : Maybe<JS::Rooted<JSObject*> > unwrappedObj;
647 0 : bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
648 0 : if (objIsXray) {
649 0 : unwrappedObj.emplace(cx, obj);
650 : }
651 0 : if (objIsXray) {
652 0 : unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
653 0 : if (!unwrappedObj.ref()) {
654 0 : return false;
655 : }
656 : }
657 0 : binding_detail::FastErrorResult rv;
658 0 : SEChannelType result(self->GetType(rv, js::GetObjectCompartment(unwrappedObj ? *unwrappedObj : obj)));
659 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
660 0 : return false;
661 : }
662 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
663 0 : if (!ToJSValue(cx, result, args.rval())) {
664 0 : return false;
665 : }
666 0 : return true;
667 : }
668 :
669 : static const JSJitInfo type_getterinfo = {
670 : { (JSJitGetterOp)get_type },
671 : { prototypes::id::SEChannel },
672 : { PrototypeTraits<prototypes::id::SEChannel>::Depth },
673 : JSJitInfo::Getter,
674 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
675 : JSVAL_TYPE_STRING, /* returnType. Not relevant for setters. */
676 : false, /* isInfallible. False in setters. */
677 : false, /* isMovable. Not relevant for setters. */
678 : false, /* isEliminatable. Not relevant for setters. */
679 : false, /* isAlwaysInSlot. Only relevant for getters. */
680 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
681 : false, /* isTypedMethod. Only relevant for methods. */
682 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
683 : };
684 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
685 : static_assert(0 < 2, "There is no slot for us");
686 :
687 : static bool
688 0 : transmit(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::SEChannel* self, const JSJitMethodCallArgs& args)
689 : {
690 0 : Maybe<JS::Rooted<JSObject*> > unwrappedObj;
691 0 : bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
692 0 : if (objIsXray) {
693 0 : unwrappedObj.emplace(cx, obj);
694 : }
695 0 : binding_detail::FastSECommand arg0;
696 0 : if (!arg0.Init(cx, (args.hasDefined(0)) ? args[0] : JS::NullHandleValue, "Argument 1 of SEChannel.transmit", true)) {
697 0 : return false;
698 : }
699 0 : if (objIsXray) {
700 0 : unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
701 0 : if (!unwrappedObj.ref()) {
702 0 : return false;
703 : }
704 : }
705 0 : binding_detail::FastErrorResult rv;
706 0 : auto result(StrongOrRawPtr<Promise>(self->Transmit(Constify(arg0), rv, js::GetObjectCompartment(unwrappedObj ? *unwrappedObj : obj))));
707 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
708 0 : return false;
709 : }
710 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
711 0 : if (!ToJSValue(cx, result, args.rval())) {
712 0 : return false;
713 : }
714 0 : return true;
715 : }
716 :
717 : static bool
718 0 : transmit_promiseWrapper(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::SEChannel* self, const JSJitMethodCallArgs& args)
719 : {
720 : // Make sure to save the callee before someone maybe messes
721 : // with rval().
722 0 : JS::Rooted<JSObject*> callee(cx, &args.callee());
723 0 : bool ok = transmit(cx, obj, self, args);
724 0 : if (ok) {
725 0 : return true;
726 : }
727 0 : return ConvertExceptionToPromise(cx, xpc::XrayAwareCalleeGlobal(callee),
728 0 : args.rval());
729 : }
730 :
731 : static const JSJitInfo transmit_methodinfo = {
732 : { (JSJitGetterOp)transmit_promiseWrapper },
733 : { prototypes::id::SEChannel },
734 : { PrototypeTraits<prototypes::id::SEChannel>::Depth },
735 : JSJitInfo::Method,
736 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
737 : JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
738 : false, /* isInfallible. False in setters. */
739 : false, /* isMovable. Not relevant for setters. */
740 : false, /* isEliminatable. Not relevant for setters. */
741 : false, /* isAlwaysInSlot. Only relevant for getters. */
742 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
743 : false, /* isTypedMethod. Only relevant for methods. */
744 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
745 : };
746 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
747 : static_assert(0 < 2, "There is no slot for us");
748 :
749 : static bool
750 0 : close(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::SEChannel* self, const JSJitMethodCallArgs& args)
751 : {
752 0 : Maybe<JS::Rooted<JSObject*> > unwrappedObj;
753 0 : bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
754 0 : if (objIsXray) {
755 0 : unwrappedObj.emplace(cx, obj);
756 : }
757 0 : if (objIsXray) {
758 0 : unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
759 0 : if (!unwrappedObj.ref()) {
760 0 : return false;
761 : }
762 : }
763 0 : binding_detail::FastErrorResult rv;
764 0 : auto result(StrongOrRawPtr<Promise>(self->Close(rv, js::GetObjectCompartment(unwrappedObj ? *unwrappedObj : obj))));
765 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
766 0 : return false;
767 : }
768 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
769 0 : if (!ToJSValue(cx, result, args.rval())) {
770 0 : return false;
771 : }
772 0 : return true;
773 : }
774 :
775 : static bool
776 0 : close_promiseWrapper(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::SEChannel* self, const JSJitMethodCallArgs& args)
777 : {
778 : // Make sure to save the callee before someone maybe messes
779 : // with rval().
780 0 : JS::Rooted<JSObject*> callee(cx, &args.callee());
781 0 : bool ok = close(cx, obj, self, args);
782 0 : if (ok) {
783 0 : return true;
784 : }
785 0 : return ConvertExceptionToPromise(cx, xpc::XrayAwareCalleeGlobal(callee),
786 0 : args.rval());
787 : }
788 :
789 : static const JSJitInfo close_methodinfo = {
790 : { (JSJitGetterOp)close_promiseWrapper },
791 : { prototypes::id::SEChannel },
792 : { PrototypeTraits<prototypes::id::SEChannel>::Depth },
793 : JSJitInfo::Method,
794 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
795 : JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
796 : false, /* isInfallible. False in setters. */
797 : false, /* isMovable. Not relevant for setters. */
798 : false, /* isEliminatable. Not relevant for setters. */
799 : false, /* isAlwaysInSlot. Only relevant for getters. */
800 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
801 : false, /* isTypedMethod. Only relevant for methods. */
802 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
803 : };
804 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
805 : static_assert(0 < 2, "There is no slot for us");
806 :
807 : static bool
808 0 : _addProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::Handle<JS::Value> val)
809 : {
810 0 : mozilla::dom::SEChannel* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::SEChannel>(obj);
811 : // We don't want to preserve if we don't have a wrapper, and we
812 : // obviously can't preserve if we're not initialized.
813 0 : if (self && self->GetWrapperPreserveColor()) {
814 0 : PreserveWrapper(self);
815 : }
816 0 : return true;
817 : }
818 :
819 : static void
820 0 : _finalize(js::FreeOp* fop, JSObject* obj)
821 : {
822 0 : mozilla::dom::SEChannel* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::SEChannel>(obj);
823 0 : if (self) {
824 0 : ClearWrapper(self, self, obj);
825 0 : AddForDeferredFinalization<mozilla::dom::SEChannel>(self);
826 : }
827 0 : }
828 :
829 : static void
830 0 : _objectMoved(JSObject* obj, const JSObject* old)
831 : {
832 0 : mozilla::dom::SEChannel* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::SEChannel>(obj);
833 0 : if (self) {
834 0 : UpdateWrapper(self, self, obj, old);
835 : }
836 0 : }
837 :
838 : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
839 : #if defined(__clang__)
840 : #pragma clang diagnostic push
841 : #pragma clang diagnostic ignored "-Wmissing-braces"
842 : #endif
843 : static const JSFunctionSpec sChromeStaticMethods_specs[] = {
844 : JS_FNSPEC("_create", SEChannel::_Create, nullptr, 2, 0, nullptr),
845 : JS_FS_END
846 : };
847 : #if defined(__clang__)
848 : #pragma clang diagnostic pop
849 : #endif
850 :
851 :
852 : // Can't be const because the pref-enabled boolean needs to be writable
853 : static Prefable<const JSFunctionSpec> sChromeStaticMethods[] = {
854 : { nullptr, &sChromeStaticMethods_specs[0] },
855 : { nullptr, nullptr }
856 : };
857 :
858 : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
859 : "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
860 : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
861 : "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
862 :
863 : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
864 : #if defined(__clang__)
865 : #pragma clang diagnostic push
866 : #pragma clang diagnostic ignored "-Wmissing-braces"
867 : #endif
868 : static const JSFunctionSpec sMethods_specs[] = {
869 : JS_FNSPEC("transmit", GenericPromiseReturningBindingMethod, reinterpret_cast<const JSJitInfo*>(&transmit_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
870 : JS_FNSPEC("close", GenericPromiseReturningBindingMethod, reinterpret_cast<const JSJitInfo*>(&close_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
871 : JS_FS_END
872 : };
873 : #if defined(__clang__)
874 : #pragma clang diagnostic pop
875 : #endif
876 :
877 :
878 : // Can't be const because the pref-enabled boolean needs to be writable
879 : static Prefable<const JSFunctionSpec> sMethods[] = {
880 : { nullptr, &sMethods_specs[0] },
881 : { nullptr, nullptr }
882 : };
883 :
884 : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
885 : "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
886 : static_assert(2 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
887 : "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
888 :
889 : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
890 : #if defined(__clang__)
891 : #pragma clang diagnostic push
892 : #pragma clang diagnostic ignored "-Wmissing-braces"
893 : #endif
894 : static const JSPropertySpec sAttributes_specs[] = {
895 : { "session", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &session_getterinfo, nullptr, nullptr },
896 : { "openResponse", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &openResponse_getterinfo, nullptr, nullptr },
897 : { "isClosed", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &isClosed_getterinfo, nullptr, nullptr },
898 : { "type", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &type_getterinfo, nullptr, nullptr },
899 : { nullptr, 0, nullptr, nullptr, nullptr, nullptr }
900 : };
901 : #if defined(__clang__)
902 : #pragma clang diagnostic pop
903 : #endif
904 :
905 :
906 : // Can't be const because the pref-enabled boolean needs to be writable
907 : static Prefable<const JSPropertySpec> sAttributes[] = {
908 : { nullptr, &sAttributes_specs[0] },
909 : { nullptr, nullptr }
910 : };
911 :
912 : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
913 : "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
914 : static_assert(4 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
915 : "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
916 :
917 :
918 : static uint16_t sNativeProperties_sortedPropertyIndices[6];
919 : static PropertyInfo sNativeProperties_propertyInfos[6];
920 :
921 : static const NativePropertiesN<2> sNativeProperties = {
922 : false, 0,
923 : false, 0,
924 : true, 0 /* sMethods */,
925 : true, 1 /* sAttributes */,
926 : false, 0,
927 : false, 0,
928 : false, 0,
929 : -1,
930 : 6,
931 : sNativeProperties_sortedPropertyIndices,
932 : {
933 : { sMethods, &sNativeProperties_propertyInfos[0] },
934 : { sAttributes, &sNativeProperties_propertyInfos[2] }
935 : }
936 : };
937 : static_assert(6 < 1ull << CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount),
938 : "We have a property info count that is oversized");
939 :
940 : static uint16_t sChromeOnlyNativeProperties_sortedPropertyIndices[1];
941 : static PropertyInfo sChromeOnlyNativeProperties_propertyInfos[1];
942 :
943 : static const NativePropertiesN<1> sChromeOnlyNativeProperties = {
944 : true, 0 /* sChromeStaticMethods */,
945 : false, 0,
946 : false, 0,
947 : false, 0,
948 : false, 0,
949 : false, 0,
950 : false, 0,
951 : -1,
952 : 1,
953 : sChromeOnlyNativeProperties_sortedPropertyIndices,
954 : {
955 : { sChromeStaticMethods, &sChromeOnlyNativeProperties_propertyInfos[0] }
956 : }
957 : };
958 : static_assert(1 < 1ull << CHAR_BIT * sizeof(sChromeOnlyNativeProperties.propertyInfoCount),
959 : "We have a property info count that is oversized");
960 :
961 : static const DOMIfaceAndProtoJSClass sInterfaceObjectClass = {
962 : {
963 : "Function",
964 : JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_SLOTS_BASE),
965 : &sBoringInterfaceObjectClassClassOps,
966 : JS_NULL_CLASS_SPEC,
967 : JS_NULL_CLASS_EXT,
968 : &sInterfaceObjectClassObjectOps
969 : },
970 : eInterface,
971 : true,
972 : prototypes::id::SEChannel,
973 : PrototypeTraits<prototypes::id::SEChannel>::Depth,
974 : sNativePropertyHooks,
975 : "function SEChannel() {\n [native code]\n}",
976 : JS::GetRealmFunctionPrototype
977 : };
978 :
979 : static const DOMIfaceAndProtoJSClass sPrototypeClass = {
980 : {
981 : "SEChannelPrototype",
982 : JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE),
983 : JS_NULL_CLASS_OPS,
984 : JS_NULL_CLASS_SPEC,
985 : JS_NULL_CLASS_EXT,
986 : JS_NULL_OBJECT_OPS
987 : },
988 : eInterfacePrototype,
989 : false,
990 : prototypes::id::SEChannel,
991 : PrototypeTraits<prototypes::id::SEChannel>::Depth,
992 : sNativePropertyHooks,
993 : "[object SEChannelPrototype]",
994 : JS::GetRealmObjectPrototype
995 : };
996 :
997 : bool
998 0 : ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
999 : {
1000 : static bool sPrefValue;
1001 : static bool sPrefCacheSetUp = false;
1002 0 : if (!sPrefCacheSetUp) {
1003 0 : sPrefCacheSetUp = true;
1004 0 : Preferences::AddBoolVarCache(&sPrefValue, "dom.secureelement.enabled");
1005 : }
1006 :
1007 0 : return sPrefValue &&
1008 0 : nsContentUtils::ThreadsafeIsSystemCaller(aCx);
1009 : }
1010 :
1011 : JSObject*
1012 0 : DefineDOMInterface(JSContext* aCx, JS::Handle<JSObject*> aGlobal, JS::Handle<jsid> id, bool aDefineOnGlobal)
1013 : {
1014 0 : return GetConstructorObjectHandle(aCx, aDefineOnGlobal);
1015 : }
1016 :
1017 : static const js::ClassOps sClassOps = {
1018 : _addProperty, /* addProperty */
1019 : nullptr, /* delProperty */
1020 : nullptr, /* getProperty */
1021 : nullptr, /* setProperty */
1022 : nullptr, /* enumerate */
1023 : nullptr, /* newEnumerate */
1024 : nullptr, /* resolve */
1025 : nullptr, /* mayResolve */
1026 : _finalize, /* finalize */
1027 : nullptr, /* call */
1028 : nullptr, /* hasInstance */
1029 : nullptr, /* construct */
1030 : nullptr, /* trace */
1031 : };
1032 :
1033 : static const js::ClassExtension sClassExtension = {
1034 : nullptr, /* weakmapKeyDelegateOp */
1035 : _objectMoved /* objectMovedOp */
1036 : };
1037 :
1038 : static const DOMJSClass sClass = {
1039 : { "SEChannel",
1040 : JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(2),
1041 : &sClassOps,
1042 : JS_NULL_CLASS_SPEC,
1043 : &sClassExtension,
1044 : JS_NULL_OBJECT_OPS
1045 : },
1046 : { prototypes::id::SEChannel, 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 },
1047 : IsBaseOf<nsISupports, mozilla::dom::SEChannel >::value,
1048 : sNativePropertyHooks,
1049 : FindAssociatedGlobalForNative<mozilla::dom::SEChannel>::Get,
1050 : GetProtoObjectHandle,
1051 : GetCCParticipant<mozilla::dom::SEChannel>::Get()
1052 : };
1053 : static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
1054 : "Must have the right minimal number of reserved slots.");
1055 : static_assert(2 >= 2,
1056 : "Must have enough reserved slots.");
1057 :
1058 : const JSClass*
1059 0 : GetJSClass()
1060 : {
1061 0 : return sClass.ToJSClass();
1062 : }
1063 :
1064 : bool
1065 0 : Wrap(JSContext* aCx, mozilla::dom::SEChannel* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
1066 : {
1067 : MOZ_ASSERT(static_cast<mozilla::dom::SEChannel*>(aObject) ==
1068 : reinterpret_cast<mozilla::dom::SEChannel*>(aObject),
1069 : "Multiple inheritance for mozilla::dom::SEChannel is broken.");
1070 0 : MOZ_ASSERT(ToSupportsIsCorrect(aObject));
1071 0 : MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
1072 0 : MOZ_ASSERT(!aCache->GetWrapper(),
1073 : "You should probably not be using Wrap() directly; use "
1074 : "GetOrCreateDOMReflector instead");
1075 :
1076 0 : MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
1077 : "nsISupports must be on our primary inheritance chain");
1078 :
1079 0 : JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
1080 0 : if (!global) {
1081 0 : return false;
1082 : }
1083 0 : MOZ_ASSERT(JS_IsGlobalObject(global));
1084 0 : MOZ_ASSERT(JS::ObjectIsNotGray(global));
1085 :
1086 : // That might have ended up wrapping us already, due to the wonders
1087 : // of XBL. Check for that, and bail out as needed.
1088 0 : aReflector.set(aCache->GetWrapper());
1089 0 : if (aReflector) {
1090 : #ifdef DEBUG
1091 0 : binding_detail::AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
1092 : #endif // DEBUG
1093 0 : return true;
1094 : }
1095 :
1096 0 : JSAutoCompartment ac(aCx, global);
1097 0 : JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
1098 0 : if (!canonicalProto) {
1099 0 : return false;
1100 : }
1101 0 : JS::Rooted<JSObject*> proto(aCx);
1102 0 : if (aGivenProto) {
1103 0 : proto = aGivenProto;
1104 : // Unfortunately, while aGivenProto was in the compartment of aCx
1105 : // coming in, we changed compartments to that of "parent" so may need
1106 : // to wrap the proto here.
1107 0 : if (js::GetContextCompartment(aCx) != js::GetObjectCompartment(proto)) {
1108 0 : if (!JS_WrapObject(aCx, &proto)) {
1109 0 : return false;
1110 : }
1111 : }
1112 : } else {
1113 0 : proto = canonicalProto;
1114 : }
1115 :
1116 0 : BindingJSObjectCreator<mozilla::dom::SEChannel> creator(aCx);
1117 0 : creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
1118 0 : if (!aReflector) {
1119 0 : return false;
1120 : }
1121 :
1122 0 : aCache->SetWrapper(aReflector);
1123 0 : creator.InitializationSucceeded();
1124 :
1125 0 : MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
1126 : aCache->GetWrapperPreserveColor() == aReflector);
1127 : // If proto != canonicalProto, we have to preserve our wrapper;
1128 : // otherwise we won't be able to properly recreate it later, since
1129 : // we won't know what proto to use. Note that we don't check
1130 : // aGivenProto here, since it's entirely possible (and even
1131 : // somewhat common) to have a non-null aGivenProto which is the
1132 : // same as canonicalProto.
1133 0 : if (proto != canonicalProto) {
1134 0 : PreserveWrapper(aObject);
1135 : }
1136 :
1137 0 : return true;
1138 : }
1139 :
1140 : // This may allocate too many slots, because we only really need
1141 : // slots for our non-interface-typed members that we cache. But
1142 : // allocating slots only for those would make the slot index
1143 : // computations much more complicated, so let's do this the simple
1144 : // way for now.
1145 : DEFINE_XRAY_EXPANDO_CLASS(static, sXrayExpandoObjectClass, 1);
1146 :
1147 : const NativePropertyHooks sNativePropertyHooks[] = { {
1148 : nullptr,
1149 : nullptr,
1150 : nullptr,
1151 : { sNativeProperties.Upcast(), sChromeOnlyNativeProperties.Upcast() },
1152 : prototypes::id::SEChannel,
1153 : constructors::id::SEChannel,
1154 : nullptr,
1155 : &sXrayExpandoObjectClass
1156 : } };
1157 :
1158 : void
1159 0 : CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, bool aDefineOnGlobal)
1160 : {
1161 0 : JS::Rooted<JSObject*> parentProto(aCx, JS::GetRealmObjectPrototype(aCx));
1162 0 : if (!parentProto) {
1163 0 : return;
1164 : }
1165 :
1166 0 : JS::Rooted<JSObject*> constructorProto(aCx, JS::GetRealmFunctionPrototype(aCx));
1167 0 : if (!constructorProto) {
1168 0 : return;
1169 : }
1170 :
1171 : static bool sIdsInited = false;
1172 0 : if (!sIdsInited && NS_IsMainThread()) {
1173 0 : if (!InitIds(aCx, sNativeProperties.Upcast())) {
1174 0 : return;
1175 : }
1176 0 : if (!InitIds(aCx, sChromeOnlyNativeProperties.Upcast())) {
1177 0 : return;
1178 : }
1179 0 : sIdsInited = true;
1180 : }
1181 :
1182 0 : JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::SEChannel);
1183 0 : JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::SEChannel);
1184 0 : dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
1185 : &sPrototypeClass.mBase, protoCache,
1186 : constructorProto, &sInterfaceObjectClass.mBase, 0, nullptr,
1187 : interfaceCache,
1188 : sNativeProperties.Upcast(),
1189 0 : nsContentUtils::ThreadsafeIsSystemCaller(aCx) ? sChromeOnlyNativeProperties.Upcast() : nullptr,
1190 : "SEChannel", aDefineOnGlobal,
1191 : nullptr,
1192 0 : false);
1193 : }
1194 :
1195 : JS::Handle<JSObject*>
1196 0 : GetProtoObjectHandle(JSContext* aCx)
1197 : {
1198 : /* Get the interface prototype object for this class. This will create the
1199 : object as needed. */
1200 0 : bool aDefineOnGlobal = true;
1201 :
1202 : /* Make sure our global is sane. Hopefully we can remove this sometime */
1203 0 : JSObject* global = JS::CurrentGlobalOrNull(aCx);
1204 0 : if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
1205 0 : return nullptr;
1206 : }
1207 :
1208 : /* Check to see whether the interface objects are already installed */
1209 0 : ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
1210 0 : if (!protoAndIfaceCache.HasEntryInSlot(prototypes::id::SEChannel)) {
1211 0 : JS::Rooted<JSObject*> rootedGlobal(aCx, global);
1212 0 : CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
1213 : }
1214 :
1215 : /*
1216 : * The object might _still_ be null, but that's OK.
1217 : *
1218 : * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
1219 : * traced by TraceProtoAndIfaceCache() and its contents are never
1220 : * changed after they have been set.
1221 : *
1222 : * Calling address() avoids the read read barrier that does gray
1223 : * unmarking, but it's not possible for the object to be gray here.
1224 : */
1225 :
1226 0 : const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(prototypes::id::SEChannel);
1227 0 : MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
1228 0 : return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
1229 : }
1230 :
1231 : JS::Handle<JSObject*>
1232 0 : GetConstructorObjectHandle(JSContext* aCx, bool aDefineOnGlobal)
1233 : {
1234 : /* Get the interface object for this class. This will create the object as
1235 : needed. */
1236 :
1237 : /* Make sure our global is sane. Hopefully we can remove this sometime */
1238 0 : JSObject* global = JS::CurrentGlobalOrNull(aCx);
1239 0 : if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
1240 0 : return nullptr;
1241 : }
1242 :
1243 : /* Check to see whether the interface objects are already installed */
1244 0 : ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
1245 0 : if (!protoAndIfaceCache.HasEntryInSlot(constructors::id::SEChannel)) {
1246 0 : JS::Rooted<JSObject*> rootedGlobal(aCx, global);
1247 0 : CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
1248 : }
1249 :
1250 : /*
1251 : * The object might _still_ be null, but that's OK.
1252 : *
1253 : * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
1254 : * traced by TraceProtoAndIfaceCache() and its contents are never
1255 : * changed after they have been set.
1256 : *
1257 : * Calling address() avoids the read read barrier that does gray
1258 : * unmarking, but it's not possible for the object to be gray here.
1259 : */
1260 :
1261 0 : const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(constructors::id::SEChannel);
1262 0 : MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
1263 0 : return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
1264 : }
1265 :
1266 : JSObject*
1267 0 : GetConstructorObject(JSContext* aCx)
1268 : {
1269 0 : return GetConstructorObjectHandle(aCx);
1270 : }
1271 :
1272 : } // namespace SEChannelBinding
1273 :
1274 :
1275 :
1276 : namespace SEReaderBinding {
1277 :
1278 : static bool
1279 0 : get_isSEPresent(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::SEReader* self, JSJitGetterCallArgs args)
1280 : {
1281 0 : Maybe<JS::Rooted<JSObject*> > unwrappedObj;
1282 0 : bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
1283 0 : if (objIsXray) {
1284 0 : unwrappedObj.emplace(cx, obj);
1285 : }
1286 0 : if (objIsXray) {
1287 0 : unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
1288 0 : if (!unwrappedObj.ref()) {
1289 0 : return false;
1290 : }
1291 : }
1292 0 : binding_detail::FastErrorResult rv;
1293 0 : bool result(self->GetIsSEPresent(rv, js::GetObjectCompartment(unwrappedObj ? *unwrappedObj : obj)));
1294 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
1295 0 : return false;
1296 : }
1297 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
1298 0 : args.rval().setBoolean(result);
1299 0 : return true;
1300 : }
1301 :
1302 : static const JSJitInfo isSEPresent_getterinfo = {
1303 : { (JSJitGetterOp)get_isSEPresent },
1304 : { prototypes::id::SEReader },
1305 : { PrototypeTraits<prototypes::id::SEReader>::Depth },
1306 : JSJitInfo::Getter,
1307 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
1308 : JSVAL_TYPE_BOOLEAN, /* returnType. Not relevant for setters. */
1309 : false, /* isInfallible. False in setters. */
1310 : false, /* isMovable. Not relevant for setters. */
1311 : false, /* isEliminatable. Not relevant for setters. */
1312 : false, /* isAlwaysInSlot. Only relevant for getters. */
1313 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
1314 : false, /* isTypedMethod. Only relevant for methods. */
1315 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
1316 : };
1317 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
1318 : static_assert(0 < 1, "There is no slot for us");
1319 :
1320 : static bool
1321 0 : get_type(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::SEReader* self, JSJitGetterCallArgs args)
1322 : {
1323 0 : Maybe<JS::Rooted<JSObject*> > unwrappedObj;
1324 0 : bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
1325 0 : if (objIsXray) {
1326 0 : unwrappedObj.emplace(cx, obj);
1327 : }
1328 0 : if (objIsXray) {
1329 0 : unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
1330 0 : if (!unwrappedObj.ref()) {
1331 0 : return false;
1332 : }
1333 : }
1334 0 : binding_detail::FastErrorResult rv;
1335 0 : SEType result(self->GetType(rv, js::GetObjectCompartment(unwrappedObj ? *unwrappedObj : obj)));
1336 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
1337 0 : return false;
1338 : }
1339 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
1340 0 : if (!ToJSValue(cx, result, args.rval())) {
1341 0 : return false;
1342 : }
1343 0 : return true;
1344 : }
1345 :
1346 : static const JSJitInfo type_getterinfo = {
1347 : { (JSJitGetterOp)get_type },
1348 : { prototypes::id::SEReader },
1349 : { PrototypeTraits<prototypes::id::SEReader>::Depth },
1350 : JSJitInfo::Getter,
1351 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
1352 : JSVAL_TYPE_STRING, /* returnType. Not relevant for setters. */
1353 : false, /* isInfallible. False in setters. */
1354 : false, /* isMovable. Not relevant for setters. */
1355 : false, /* isEliminatable. Not relevant for setters. */
1356 : false, /* isAlwaysInSlot. Only relevant for getters. */
1357 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
1358 : false, /* isTypedMethod. Only relevant for methods. */
1359 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
1360 : };
1361 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
1362 : static_assert(0 < 1, "There is no slot for us");
1363 :
1364 : static bool
1365 0 : openSession(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::SEReader* self, const JSJitMethodCallArgs& args)
1366 : {
1367 0 : Maybe<JS::Rooted<JSObject*> > unwrappedObj;
1368 0 : bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
1369 0 : if (objIsXray) {
1370 0 : unwrappedObj.emplace(cx, obj);
1371 : }
1372 0 : if (objIsXray) {
1373 0 : unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
1374 0 : if (!unwrappedObj.ref()) {
1375 0 : return false;
1376 : }
1377 : }
1378 0 : binding_detail::FastErrorResult rv;
1379 0 : auto result(StrongOrRawPtr<Promise>(self->OpenSession(rv, js::GetObjectCompartment(unwrappedObj ? *unwrappedObj : obj))));
1380 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
1381 0 : return false;
1382 : }
1383 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
1384 0 : if (!ToJSValue(cx, result, args.rval())) {
1385 0 : return false;
1386 : }
1387 0 : return true;
1388 : }
1389 :
1390 : static bool
1391 0 : openSession_promiseWrapper(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::SEReader* self, const JSJitMethodCallArgs& args)
1392 : {
1393 : // Make sure to save the callee before someone maybe messes
1394 : // with rval().
1395 0 : JS::Rooted<JSObject*> callee(cx, &args.callee());
1396 0 : bool ok = openSession(cx, obj, self, args);
1397 0 : if (ok) {
1398 0 : return true;
1399 : }
1400 0 : return ConvertExceptionToPromise(cx, xpc::XrayAwareCalleeGlobal(callee),
1401 0 : args.rval());
1402 : }
1403 :
1404 : static const JSJitInfo openSession_methodinfo = {
1405 : { (JSJitGetterOp)openSession_promiseWrapper },
1406 : { prototypes::id::SEReader },
1407 : { PrototypeTraits<prototypes::id::SEReader>::Depth },
1408 : JSJitInfo::Method,
1409 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
1410 : JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
1411 : false, /* isInfallible. False in setters. */
1412 : false, /* isMovable. Not relevant for setters. */
1413 : false, /* isEliminatable. Not relevant for setters. */
1414 : false, /* isAlwaysInSlot. Only relevant for getters. */
1415 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
1416 : false, /* isTypedMethod. Only relevant for methods. */
1417 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
1418 : };
1419 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
1420 : static_assert(0 < 1, "There is no slot for us");
1421 :
1422 : static bool
1423 0 : closeAll(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::SEReader* self, const JSJitMethodCallArgs& args)
1424 : {
1425 0 : Maybe<JS::Rooted<JSObject*> > unwrappedObj;
1426 0 : bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
1427 0 : if (objIsXray) {
1428 0 : unwrappedObj.emplace(cx, obj);
1429 : }
1430 0 : if (objIsXray) {
1431 0 : unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
1432 0 : if (!unwrappedObj.ref()) {
1433 0 : return false;
1434 : }
1435 : }
1436 0 : binding_detail::FastErrorResult rv;
1437 0 : auto result(StrongOrRawPtr<Promise>(self->CloseAll(rv, js::GetObjectCompartment(unwrappedObj ? *unwrappedObj : obj))));
1438 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
1439 0 : return false;
1440 : }
1441 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
1442 0 : if (!ToJSValue(cx, result, args.rval())) {
1443 0 : return false;
1444 : }
1445 0 : return true;
1446 : }
1447 :
1448 : static bool
1449 0 : closeAll_promiseWrapper(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::SEReader* self, const JSJitMethodCallArgs& args)
1450 : {
1451 : // Make sure to save the callee before someone maybe messes
1452 : // with rval().
1453 0 : JS::Rooted<JSObject*> callee(cx, &args.callee());
1454 0 : bool ok = closeAll(cx, obj, self, args);
1455 0 : if (ok) {
1456 0 : return true;
1457 : }
1458 0 : return ConvertExceptionToPromise(cx, xpc::XrayAwareCalleeGlobal(callee),
1459 0 : args.rval());
1460 : }
1461 :
1462 : static const JSJitInfo closeAll_methodinfo = {
1463 : { (JSJitGetterOp)closeAll_promiseWrapper },
1464 : { prototypes::id::SEReader },
1465 : { PrototypeTraits<prototypes::id::SEReader>::Depth },
1466 : JSJitInfo::Method,
1467 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
1468 : JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
1469 : false, /* isInfallible. False in setters. */
1470 : false, /* isMovable. Not relevant for setters. */
1471 : false, /* isEliminatable. Not relevant for setters. */
1472 : false, /* isAlwaysInSlot. Only relevant for getters. */
1473 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
1474 : false, /* isTypedMethod. Only relevant for methods. */
1475 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
1476 : };
1477 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
1478 : static_assert(0 < 1, "There is no slot for us");
1479 :
1480 : static bool
1481 0 : _addProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::Handle<JS::Value> val)
1482 : {
1483 0 : mozilla::dom::SEReader* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::SEReader>(obj);
1484 : // We don't want to preserve if we don't have a wrapper, and we
1485 : // obviously can't preserve if we're not initialized.
1486 0 : if (self && self->GetWrapperPreserveColor()) {
1487 0 : PreserveWrapper(self);
1488 : }
1489 0 : return true;
1490 : }
1491 :
1492 : static void
1493 0 : _finalize(js::FreeOp* fop, JSObject* obj)
1494 : {
1495 0 : mozilla::dom::SEReader* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::SEReader>(obj);
1496 0 : if (self) {
1497 0 : ClearWrapper(self, self, obj);
1498 0 : AddForDeferredFinalization<mozilla::dom::SEReader>(self);
1499 : }
1500 0 : }
1501 :
1502 : static void
1503 0 : _objectMoved(JSObject* obj, const JSObject* old)
1504 : {
1505 0 : mozilla::dom::SEReader* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::SEReader>(obj);
1506 0 : if (self) {
1507 0 : UpdateWrapper(self, self, obj, old);
1508 : }
1509 0 : }
1510 :
1511 : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
1512 : #if defined(__clang__)
1513 : #pragma clang diagnostic push
1514 : #pragma clang diagnostic ignored "-Wmissing-braces"
1515 : #endif
1516 : static const JSFunctionSpec sChromeStaticMethods_specs[] = {
1517 : JS_FNSPEC("_create", SEReader::_Create, nullptr, 2, 0, nullptr),
1518 : JS_FS_END
1519 : };
1520 : #if defined(__clang__)
1521 : #pragma clang diagnostic pop
1522 : #endif
1523 :
1524 :
1525 : // Can't be const because the pref-enabled boolean needs to be writable
1526 : static Prefable<const JSFunctionSpec> sChromeStaticMethods[] = {
1527 : { nullptr, &sChromeStaticMethods_specs[0] },
1528 : { nullptr, nullptr }
1529 : };
1530 :
1531 : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
1532 : "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
1533 : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
1534 : "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
1535 :
1536 : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
1537 : #if defined(__clang__)
1538 : #pragma clang diagnostic push
1539 : #pragma clang diagnostic ignored "-Wmissing-braces"
1540 : #endif
1541 : static const JSFunctionSpec sMethods_specs[] = {
1542 : JS_FNSPEC("openSession", GenericPromiseReturningBindingMethod, reinterpret_cast<const JSJitInfo*>(&openSession_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
1543 : JS_FNSPEC("closeAll", GenericPromiseReturningBindingMethod, reinterpret_cast<const JSJitInfo*>(&closeAll_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
1544 : JS_FS_END
1545 : };
1546 : #if defined(__clang__)
1547 : #pragma clang diagnostic pop
1548 : #endif
1549 :
1550 :
1551 : // Can't be const because the pref-enabled boolean needs to be writable
1552 : static Prefable<const JSFunctionSpec> sMethods[] = {
1553 : { nullptr, &sMethods_specs[0] },
1554 : { nullptr, nullptr }
1555 : };
1556 :
1557 : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
1558 : "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
1559 : static_assert(2 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
1560 : "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
1561 :
1562 : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
1563 : #if defined(__clang__)
1564 : #pragma clang diagnostic push
1565 : #pragma clang diagnostic ignored "-Wmissing-braces"
1566 : #endif
1567 : static const JSPropertySpec sAttributes_specs[] = {
1568 : { "isSEPresent", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &isSEPresent_getterinfo, nullptr, nullptr },
1569 : { "type", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &type_getterinfo, nullptr, nullptr },
1570 : { nullptr, 0, nullptr, nullptr, nullptr, nullptr }
1571 : };
1572 : #if defined(__clang__)
1573 : #pragma clang diagnostic pop
1574 : #endif
1575 :
1576 :
1577 : // Can't be const because the pref-enabled boolean needs to be writable
1578 : static Prefable<const JSPropertySpec> sAttributes[] = {
1579 : { nullptr, &sAttributes_specs[0] },
1580 : { nullptr, nullptr }
1581 : };
1582 :
1583 : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
1584 : "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
1585 : static_assert(2 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
1586 : "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
1587 :
1588 :
1589 : static uint16_t sNativeProperties_sortedPropertyIndices[4];
1590 : static PropertyInfo sNativeProperties_propertyInfos[4];
1591 :
1592 : static const NativePropertiesN<2> sNativeProperties = {
1593 : false, 0,
1594 : false, 0,
1595 : true, 0 /* sMethods */,
1596 : true, 1 /* sAttributes */,
1597 : false, 0,
1598 : false, 0,
1599 : false, 0,
1600 : -1,
1601 : 4,
1602 : sNativeProperties_sortedPropertyIndices,
1603 : {
1604 : { sMethods, &sNativeProperties_propertyInfos[0] },
1605 : { sAttributes, &sNativeProperties_propertyInfos[2] }
1606 : }
1607 : };
1608 : static_assert(4 < 1ull << CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount),
1609 : "We have a property info count that is oversized");
1610 :
1611 : static uint16_t sChromeOnlyNativeProperties_sortedPropertyIndices[1];
1612 : static PropertyInfo sChromeOnlyNativeProperties_propertyInfos[1];
1613 :
1614 : static const NativePropertiesN<1> sChromeOnlyNativeProperties = {
1615 : true, 0 /* sChromeStaticMethods */,
1616 : false, 0,
1617 : false, 0,
1618 : false, 0,
1619 : false, 0,
1620 : false, 0,
1621 : false, 0,
1622 : -1,
1623 : 1,
1624 : sChromeOnlyNativeProperties_sortedPropertyIndices,
1625 : {
1626 : { sChromeStaticMethods, &sChromeOnlyNativeProperties_propertyInfos[0] }
1627 : }
1628 : };
1629 : static_assert(1 < 1ull << CHAR_BIT * sizeof(sChromeOnlyNativeProperties.propertyInfoCount),
1630 : "We have a property info count that is oversized");
1631 :
1632 : static const DOMIfaceAndProtoJSClass sInterfaceObjectClass = {
1633 : {
1634 : "Function",
1635 : JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_SLOTS_BASE),
1636 : &sBoringInterfaceObjectClassClassOps,
1637 : JS_NULL_CLASS_SPEC,
1638 : JS_NULL_CLASS_EXT,
1639 : &sInterfaceObjectClassObjectOps
1640 : },
1641 : eInterface,
1642 : true,
1643 : prototypes::id::SEReader,
1644 : PrototypeTraits<prototypes::id::SEReader>::Depth,
1645 : sNativePropertyHooks,
1646 : "function SEReader() {\n [native code]\n}",
1647 : JS::GetRealmFunctionPrototype
1648 : };
1649 :
1650 : static const DOMIfaceAndProtoJSClass sPrototypeClass = {
1651 : {
1652 : "SEReaderPrototype",
1653 : JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE),
1654 : JS_NULL_CLASS_OPS,
1655 : JS_NULL_CLASS_SPEC,
1656 : JS_NULL_CLASS_EXT,
1657 : JS_NULL_OBJECT_OPS
1658 : },
1659 : eInterfacePrototype,
1660 : false,
1661 : prototypes::id::SEReader,
1662 : PrototypeTraits<prototypes::id::SEReader>::Depth,
1663 : sNativePropertyHooks,
1664 : "[object SEReaderPrototype]",
1665 : JS::GetRealmObjectPrototype
1666 : };
1667 :
1668 : bool
1669 0 : ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
1670 : {
1671 : static bool sPrefValue;
1672 : static bool sPrefCacheSetUp = false;
1673 0 : if (!sPrefCacheSetUp) {
1674 0 : sPrefCacheSetUp = true;
1675 0 : Preferences::AddBoolVarCache(&sPrefValue, "dom.secureelement.enabled");
1676 : }
1677 :
1678 0 : return sPrefValue &&
1679 0 : nsContentUtils::ThreadsafeIsSystemCaller(aCx);
1680 : }
1681 :
1682 : JSObject*
1683 0 : DefineDOMInterface(JSContext* aCx, JS::Handle<JSObject*> aGlobal, JS::Handle<jsid> id, bool aDefineOnGlobal)
1684 : {
1685 0 : return GetConstructorObjectHandle(aCx, aDefineOnGlobal);
1686 : }
1687 :
1688 : static const js::ClassOps sClassOps = {
1689 : _addProperty, /* addProperty */
1690 : nullptr, /* delProperty */
1691 : nullptr, /* getProperty */
1692 : nullptr, /* setProperty */
1693 : nullptr, /* enumerate */
1694 : nullptr, /* newEnumerate */
1695 : nullptr, /* resolve */
1696 : nullptr, /* mayResolve */
1697 : _finalize, /* finalize */
1698 : nullptr, /* call */
1699 : nullptr, /* hasInstance */
1700 : nullptr, /* construct */
1701 : nullptr, /* trace */
1702 : };
1703 :
1704 : static const js::ClassExtension sClassExtension = {
1705 : nullptr, /* weakmapKeyDelegateOp */
1706 : _objectMoved /* objectMovedOp */
1707 : };
1708 :
1709 : static const DOMJSClass sClass = {
1710 : { "SEReader",
1711 : JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1),
1712 : &sClassOps,
1713 : JS_NULL_CLASS_SPEC,
1714 : &sClassExtension,
1715 : JS_NULL_OBJECT_OPS
1716 : },
1717 : { prototypes::id::SEReader, 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 },
1718 : IsBaseOf<nsISupports, mozilla::dom::SEReader >::value,
1719 : sNativePropertyHooks,
1720 : FindAssociatedGlobalForNative<mozilla::dom::SEReader>::Get,
1721 : GetProtoObjectHandle,
1722 : GetCCParticipant<mozilla::dom::SEReader>::Get()
1723 : };
1724 : static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
1725 : "Must have the right minimal number of reserved slots.");
1726 : static_assert(1 >= 1,
1727 : "Must have enough reserved slots.");
1728 :
1729 : const JSClass*
1730 0 : GetJSClass()
1731 : {
1732 0 : return sClass.ToJSClass();
1733 : }
1734 :
1735 : bool
1736 0 : Wrap(JSContext* aCx, mozilla::dom::SEReader* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
1737 : {
1738 : MOZ_ASSERT(static_cast<mozilla::dom::SEReader*>(aObject) ==
1739 : reinterpret_cast<mozilla::dom::SEReader*>(aObject),
1740 : "Multiple inheritance for mozilla::dom::SEReader is broken.");
1741 0 : MOZ_ASSERT(ToSupportsIsCorrect(aObject));
1742 0 : MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
1743 0 : MOZ_ASSERT(!aCache->GetWrapper(),
1744 : "You should probably not be using Wrap() directly; use "
1745 : "GetOrCreateDOMReflector instead");
1746 :
1747 0 : MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
1748 : "nsISupports must be on our primary inheritance chain");
1749 :
1750 0 : JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
1751 0 : if (!global) {
1752 0 : return false;
1753 : }
1754 0 : MOZ_ASSERT(JS_IsGlobalObject(global));
1755 0 : MOZ_ASSERT(JS::ObjectIsNotGray(global));
1756 :
1757 : // That might have ended up wrapping us already, due to the wonders
1758 : // of XBL. Check for that, and bail out as needed.
1759 0 : aReflector.set(aCache->GetWrapper());
1760 0 : if (aReflector) {
1761 : #ifdef DEBUG
1762 0 : binding_detail::AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
1763 : #endif // DEBUG
1764 0 : return true;
1765 : }
1766 :
1767 0 : JSAutoCompartment ac(aCx, global);
1768 0 : JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
1769 0 : if (!canonicalProto) {
1770 0 : return false;
1771 : }
1772 0 : JS::Rooted<JSObject*> proto(aCx);
1773 0 : if (aGivenProto) {
1774 0 : proto = aGivenProto;
1775 : // Unfortunately, while aGivenProto was in the compartment of aCx
1776 : // coming in, we changed compartments to that of "parent" so may need
1777 : // to wrap the proto here.
1778 0 : if (js::GetContextCompartment(aCx) != js::GetObjectCompartment(proto)) {
1779 0 : if (!JS_WrapObject(aCx, &proto)) {
1780 0 : return false;
1781 : }
1782 : }
1783 : } else {
1784 0 : proto = canonicalProto;
1785 : }
1786 :
1787 0 : BindingJSObjectCreator<mozilla::dom::SEReader> creator(aCx);
1788 0 : creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
1789 0 : if (!aReflector) {
1790 0 : return false;
1791 : }
1792 :
1793 0 : aCache->SetWrapper(aReflector);
1794 0 : creator.InitializationSucceeded();
1795 :
1796 0 : MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
1797 : aCache->GetWrapperPreserveColor() == aReflector);
1798 : // If proto != canonicalProto, we have to preserve our wrapper;
1799 : // otherwise we won't be able to properly recreate it later, since
1800 : // we won't know what proto to use. Note that we don't check
1801 : // aGivenProto here, since it's entirely possible (and even
1802 : // somewhat common) to have a non-null aGivenProto which is the
1803 : // same as canonicalProto.
1804 0 : if (proto != canonicalProto) {
1805 0 : PreserveWrapper(aObject);
1806 : }
1807 :
1808 0 : return true;
1809 : }
1810 :
1811 : const NativePropertyHooks sNativePropertyHooks[] = { {
1812 : nullptr,
1813 : nullptr,
1814 : nullptr,
1815 : { sNativeProperties.Upcast(), sChromeOnlyNativeProperties.Upcast() },
1816 : prototypes::id::SEReader,
1817 : constructors::id::SEReader,
1818 : nullptr,
1819 : &DefaultXrayExpandoObjectClass
1820 : } };
1821 :
1822 : void
1823 0 : CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, bool aDefineOnGlobal)
1824 : {
1825 0 : JS::Rooted<JSObject*> parentProto(aCx, JS::GetRealmObjectPrototype(aCx));
1826 0 : if (!parentProto) {
1827 0 : return;
1828 : }
1829 :
1830 0 : JS::Rooted<JSObject*> constructorProto(aCx, JS::GetRealmFunctionPrototype(aCx));
1831 0 : if (!constructorProto) {
1832 0 : return;
1833 : }
1834 :
1835 : static bool sIdsInited = false;
1836 0 : if (!sIdsInited && NS_IsMainThread()) {
1837 0 : if (!InitIds(aCx, sNativeProperties.Upcast())) {
1838 0 : return;
1839 : }
1840 0 : if (!InitIds(aCx, sChromeOnlyNativeProperties.Upcast())) {
1841 0 : return;
1842 : }
1843 0 : sIdsInited = true;
1844 : }
1845 :
1846 0 : JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::SEReader);
1847 0 : JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::SEReader);
1848 0 : dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
1849 : &sPrototypeClass.mBase, protoCache,
1850 : constructorProto, &sInterfaceObjectClass.mBase, 0, nullptr,
1851 : interfaceCache,
1852 : sNativeProperties.Upcast(),
1853 0 : nsContentUtils::ThreadsafeIsSystemCaller(aCx) ? sChromeOnlyNativeProperties.Upcast() : nullptr,
1854 : "SEReader", aDefineOnGlobal,
1855 : nullptr,
1856 0 : false);
1857 : }
1858 :
1859 : JS::Handle<JSObject*>
1860 0 : GetProtoObjectHandle(JSContext* aCx)
1861 : {
1862 : /* Get the interface prototype object for this class. This will create the
1863 : object as needed. */
1864 0 : bool aDefineOnGlobal = true;
1865 :
1866 : /* Make sure our global is sane. Hopefully we can remove this sometime */
1867 0 : JSObject* global = JS::CurrentGlobalOrNull(aCx);
1868 0 : if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
1869 0 : return nullptr;
1870 : }
1871 :
1872 : /* Check to see whether the interface objects are already installed */
1873 0 : ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
1874 0 : if (!protoAndIfaceCache.HasEntryInSlot(prototypes::id::SEReader)) {
1875 0 : JS::Rooted<JSObject*> rootedGlobal(aCx, global);
1876 0 : CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
1877 : }
1878 :
1879 : /*
1880 : * The object might _still_ be null, but that's OK.
1881 : *
1882 : * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
1883 : * traced by TraceProtoAndIfaceCache() and its contents are never
1884 : * changed after they have been set.
1885 : *
1886 : * Calling address() avoids the read read barrier that does gray
1887 : * unmarking, but it's not possible for the object to be gray here.
1888 : */
1889 :
1890 0 : const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(prototypes::id::SEReader);
1891 0 : MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
1892 0 : return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
1893 : }
1894 :
1895 : JS::Handle<JSObject*>
1896 0 : GetConstructorObjectHandle(JSContext* aCx, bool aDefineOnGlobal)
1897 : {
1898 : /* Get the interface object for this class. This will create the object as
1899 : needed. */
1900 :
1901 : /* Make sure our global is sane. Hopefully we can remove this sometime */
1902 0 : JSObject* global = JS::CurrentGlobalOrNull(aCx);
1903 0 : if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
1904 0 : return nullptr;
1905 : }
1906 :
1907 : /* Check to see whether the interface objects are already installed */
1908 0 : ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
1909 0 : if (!protoAndIfaceCache.HasEntryInSlot(constructors::id::SEReader)) {
1910 0 : JS::Rooted<JSObject*> rootedGlobal(aCx, global);
1911 0 : CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
1912 : }
1913 :
1914 : /*
1915 : * The object might _still_ be null, but that's OK.
1916 : *
1917 : * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
1918 : * traced by TraceProtoAndIfaceCache() and its contents are never
1919 : * changed after they have been set.
1920 : *
1921 : * Calling address() avoids the read read barrier that does gray
1922 : * unmarking, but it's not possible for the object to be gray here.
1923 : */
1924 :
1925 0 : const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(constructors::id::SEReader);
1926 0 : MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
1927 0 : return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
1928 : }
1929 :
1930 : JSObject*
1931 0 : GetConstructorObject(JSContext* aCx)
1932 : {
1933 0 : return GetConstructorObjectHandle(aCx);
1934 : }
1935 :
1936 : } // namespace SEReaderBinding
1937 :
1938 :
1939 :
1940 : namespace SEResponseBinding {
1941 :
1942 : static bool
1943 0 : get_channel(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::SEResponse* self, JSJitGetterCallArgs args)
1944 : {
1945 0 : Maybe<JS::Rooted<JSObject*> > unwrappedObj;
1946 0 : bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
1947 0 : if (objIsXray) {
1948 0 : unwrappedObj.emplace(cx, obj);
1949 : }
1950 0 : if (objIsXray) {
1951 0 : unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
1952 0 : if (!unwrappedObj.ref()) {
1953 0 : return false;
1954 : }
1955 : }
1956 0 : binding_detail::FastErrorResult rv;
1957 0 : auto result(StrongOrRawPtr<mozilla::dom::SEChannel>(self->GetChannel(rv, js::GetObjectCompartment(unwrappedObj ? *unwrappedObj : obj))));
1958 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
1959 0 : return false;
1960 : }
1961 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
1962 0 : if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
1963 0 : MOZ_ASSERT(true || JS_IsExceptionPending(cx));
1964 0 : return false;
1965 : }
1966 0 : return true;
1967 : }
1968 :
1969 : static const JSJitInfo channel_getterinfo = {
1970 : { (JSJitGetterOp)get_channel },
1971 : { prototypes::id::SEResponse },
1972 : { PrototypeTraits<prototypes::id::SEResponse>::Depth },
1973 : JSJitInfo::Getter,
1974 : JSJitInfo::AliasNone, /* aliasSet. Not relevant for setters. */
1975 : JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
1976 : false, /* isInfallible. False in setters. */
1977 : false, /* isMovable. Not relevant for setters. */
1978 : false, /* isEliminatable. Not relevant for setters. */
1979 : false, /* isAlwaysInSlot. Only relevant for getters. */
1980 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
1981 : false, /* isTypedMethod. Only relevant for methods. */
1982 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
1983 : };
1984 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
1985 : static_assert(0 < 2, "There is no slot for us");
1986 :
1987 : static bool
1988 0 : get_sw1(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::SEResponse* self, JSJitGetterCallArgs args)
1989 : {
1990 0 : Maybe<JS::Rooted<JSObject*> > unwrappedObj;
1991 0 : bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
1992 0 : if (objIsXray) {
1993 0 : unwrappedObj.emplace(cx, obj);
1994 : }
1995 0 : if (objIsXray) {
1996 0 : unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
1997 0 : if (!unwrappedObj.ref()) {
1998 0 : return false;
1999 : }
2000 : }
2001 0 : binding_detail::FastErrorResult rv;
2002 0 : uint8_t result(self->GetSw1(rv, js::GetObjectCompartment(unwrappedObj ? *unwrappedObj : obj)));
2003 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
2004 0 : return false;
2005 : }
2006 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
2007 0 : args.rval().setInt32(int32_t(result));
2008 0 : return true;
2009 : }
2010 :
2011 : static const JSJitInfo sw1_getterinfo = {
2012 : { (JSJitGetterOp)get_sw1 },
2013 : { prototypes::id::SEResponse },
2014 : { PrototypeTraits<prototypes::id::SEResponse>::Depth },
2015 : JSJitInfo::Getter,
2016 : JSJitInfo::AliasNone, /* aliasSet. Not relevant for setters. */
2017 : JSVAL_TYPE_INT32, /* returnType. Not relevant for setters. */
2018 : false, /* isInfallible. False in setters. */
2019 : false, /* isMovable. Not relevant for setters. */
2020 : false, /* isEliminatable. Not relevant for setters. */
2021 : false, /* isAlwaysInSlot. Only relevant for getters. */
2022 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
2023 : false, /* isTypedMethod. Only relevant for methods. */
2024 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
2025 : };
2026 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
2027 : static_assert(0 < 2, "There is no slot for us");
2028 :
2029 : static bool
2030 0 : get_sw2(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::SEResponse* self, JSJitGetterCallArgs args)
2031 : {
2032 0 : Maybe<JS::Rooted<JSObject*> > unwrappedObj;
2033 0 : bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
2034 0 : if (objIsXray) {
2035 0 : unwrappedObj.emplace(cx, obj);
2036 : }
2037 0 : if (objIsXray) {
2038 0 : unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
2039 0 : if (!unwrappedObj.ref()) {
2040 0 : return false;
2041 : }
2042 : }
2043 0 : binding_detail::FastErrorResult rv;
2044 0 : uint8_t result(self->GetSw2(rv, js::GetObjectCompartment(unwrappedObj ? *unwrappedObj : obj)));
2045 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
2046 0 : return false;
2047 : }
2048 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
2049 0 : args.rval().setInt32(int32_t(result));
2050 0 : return true;
2051 : }
2052 :
2053 : static const JSJitInfo sw2_getterinfo = {
2054 : { (JSJitGetterOp)get_sw2 },
2055 : { prototypes::id::SEResponse },
2056 : { PrototypeTraits<prototypes::id::SEResponse>::Depth },
2057 : JSJitInfo::Getter,
2058 : JSJitInfo::AliasNone, /* aliasSet. Not relevant for setters. */
2059 : JSVAL_TYPE_INT32, /* returnType. Not relevant for setters. */
2060 : false, /* isInfallible. False in setters. */
2061 : false, /* isMovable. Not relevant for setters. */
2062 : false, /* isEliminatable. Not relevant for setters. */
2063 : false, /* isAlwaysInSlot. Only relevant for getters. */
2064 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
2065 : false, /* isTypedMethod. Only relevant for methods. */
2066 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
2067 : };
2068 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
2069 : static_assert(0 < 2, "There is no slot for us");
2070 :
2071 : static bool
2072 0 : get_data(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::SEResponse* self, JSJitGetterCallArgs args)
2073 : {
2074 : // Have to either root across the getter call or reget after.
2075 : bool isXray;
2076 0 : JS::Rooted<JSObject*> slotStorage(cx, GetCachedSlotStorageObject(cx, obj, &isXray));
2077 0 : if (!slotStorage) {
2078 0 : return false;
2079 : }
2080 0 : const size_t slotIndex = isXray ? (xpc::JSSLOT_EXPANDO_COUNT + 0) : (DOM_INSTANCE_RESERVED_SLOTS + 0);
2081 0 : MOZ_ASSERT(JSCLASS_RESERVED_SLOTS(js::GetObjectClass(slotStorage)) > slotIndex);
2082 : {
2083 : // Scope for cachedVal
2084 0 : JS::Value cachedVal = js::GetReservedSlot(slotStorage, slotIndex);
2085 0 : if (!cachedVal.isUndefined()) {
2086 0 : args.rval().set(cachedVal);
2087 : // The cached value is in the compartment of slotStorage,
2088 : // so wrap into the caller compartment as needed.
2089 0 : return MaybeWrapNonDOMObjectOrNullValue(cx, args.rval());
2090 : }
2091 : }
2092 :
2093 0 : Maybe<JS::Rooted<JSObject*> > unwrappedObj;
2094 0 : bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
2095 0 : if (objIsXray) {
2096 0 : unwrappedObj.emplace(cx, obj);
2097 : }
2098 0 : if (objIsXray) {
2099 0 : unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
2100 0 : if (!unwrappedObj.ref()) {
2101 0 : return false;
2102 : }
2103 : }
2104 0 : binding_detail::FastErrorResult rv;
2105 0 : Nullable<nsTArray<uint8_t>> result;
2106 0 : self->GetData(result, rv, js::GetObjectCompartment(unwrappedObj ? *unwrappedObj : obj));
2107 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
2108 0 : return false;
2109 : }
2110 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
2111 : {
2112 0 : JS::Rooted<JSObject*> conversionScope(cx, isXray ? obj : slotStorage);
2113 0 : JSAutoCompartment ac(cx, conversionScope);
2114 : do { // block we break out of when done wrapping
2115 :
2116 0 : if (result.IsNull()) {
2117 0 : args.rval().setNull();
2118 0 : break;
2119 : }
2120 :
2121 0 : uint32_t length = result.Value().Length();
2122 0 : JS::Rooted<JSObject*> returnArray(cx, JS_NewArrayObject(cx, length));
2123 0 : if (!returnArray) {
2124 0 : return false;
2125 : }
2126 : // Scope for 'tmp'
2127 : {
2128 0 : JS::Rooted<JS::Value> tmp(cx);
2129 0 : for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
2130 : // Control block to let us common up the JS_DefineElement calls when there
2131 : // are different ways to succeed at wrapping the object.
2132 : do {
2133 0 : tmp.setInt32(int32_t(result.Value()[sequenceIdx0]));
2134 0 : break;
2135 : } while (0);
2136 0 : if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
2137 : JSPROP_ENUMERATE)) {
2138 0 : return false;
2139 : }
2140 : }
2141 : }
2142 0 : args.rval().setObject(*returnArray);
2143 0 : break;
2144 : } while (0);
2145 : }
2146 : { // And now store things in the compartment of our slotStorage.
2147 0 : JSAutoCompartment ac(cx, slotStorage);
2148 : // Make a copy so that we don't do unnecessary wrapping on args.rval().
2149 0 : JS::Rooted<JS::Value> storedVal(cx, args.rval());
2150 0 : if (!MaybeWrapNonDOMObjectOrNullValue(cx, &storedVal)) {
2151 0 : return false;
2152 : }
2153 0 : js::SetReservedSlot(slotStorage, slotIndex, storedVal);
2154 0 : if (!isXray) {
2155 : // In the Xray case we don't need to do this, because getting the
2156 : // expando object already preserved our wrapper.
2157 0 : PreserveWrapper(self);
2158 : }
2159 : }
2160 : // And now make sure args.rval() is in the caller compartment
2161 0 : return MaybeWrapNonDOMObjectOrNullValue(cx, args.rval());
2162 : }
2163 :
2164 : static const JSJitInfo data_getterinfo = {
2165 : { (JSJitGetterOp)get_data },
2166 : { prototypes::id::SEResponse },
2167 : { PrototypeTraits<prototypes::id::SEResponse>::Depth },
2168 : JSJitInfo::Getter,
2169 : JSJitInfo::AliasDOMSets, /* aliasSet. Not relevant for setters. */
2170 : JSVAL_TYPE_UNKNOWN, /* returnType. Not relevant for setters. */
2171 : false, /* isInfallible. False in setters. */
2172 : false, /* isMovable. Not relevant for setters. */
2173 : false, /* isEliminatable. Not relevant for setters. */
2174 : false, /* isAlwaysInSlot. Only relevant for getters. */
2175 : true, /* isLazilyCachedInSlot. Only relevant for getters. */
2176 : false, /* isTypedMethod. Only relevant for methods. */
2177 : (DOM_INSTANCE_RESERVED_SLOTS + 0) /* Reserved slot index, if we're stored in a slot, else 0. */
2178 : };
2179 : static_assert((DOM_INSTANCE_RESERVED_SLOTS + 0) <= JSJitInfo::maxSlotIndex, "We won't fit");
2180 : static_assert((DOM_INSTANCE_RESERVED_SLOTS + 0) < 2, "There is no slot for us");
2181 :
2182 : static bool
2183 0 : _addProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::Handle<JS::Value> val)
2184 : {
2185 0 : mozilla::dom::SEResponse* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::SEResponse>(obj);
2186 : // We don't want to preserve if we don't have a wrapper, and we
2187 : // obviously can't preserve if we're not initialized.
2188 0 : if (self && self->GetWrapperPreserveColor()) {
2189 0 : PreserveWrapper(self);
2190 : }
2191 0 : return true;
2192 : }
2193 :
2194 : static void
2195 0 : _finalize(js::FreeOp* fop, JSObject* obj)
2196 : {
2197 0 : mozilla::dom::SEResponse* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::SEResponse>(obj);
2198 0 : if (self) {
2199 0 : ClearWrapper(self, self, obj);
2200 0 : AddForDeferredFinalization<mozilla::dom::SEResponse>(self);
2201 : }
2202 0 : }
2203 :
2204 : static void
2205 0 : _objectMoved(JSObject* obj, const JSObject* old)
2206 : {
2207 0 : mozilla::dom::SEResponse* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::SEResponse>(obj);
2208 0 : if (self) {
2209 0 : UpdateWrapper(self, self, obj, old);
2210 : }
2211 0 : }
2212 :
2213 : static bool
2214 0 : _ClearCachedDataValue(JSContext* cx, unsigned argc, JS::Value* vp)
2215 : {
2216 0 : JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
2217 0 : if (!args.thisv().isObject()) {
2218 0 : return ThrowErrorMessage(cx, MSG_THIS_DOES_NOT_IMPLEMENT_INTERFACE, "Value", "SEResponse");
2219 : }
2220 0 : JS::Rooted<JSObject*> obj(cx, &args.thisv().toObject());
2221 :
2222 : mozilla::dom::SEResponse* self;
2223 0 : JS::Rooted<JS::Value> rootSelf(cx, JS::ObjectValue(*obj));
2224 : {
2225 0 : nsresult rv = UnwrapObject<prototypes::id::SEResponse, mozilla::dom::SEResponse>(&rootSelf, self);
2226 0 : if (NS_FAILED(rv)) {
2227 0 : return ThrowErrorMessage(cx, MSG_THIS_DOES_NOT_IMPLEMENT_INTERFACE, "Value", "SEResponse");
2228 : }
2229 : }
2230 0 : SEResponseBinding::ClearCachedDataValue(self);
2231 0 : args.rval().setUndefined();
2232 0 : return true;
2233 : }
2234 :
2235 : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
2236 : #if defined(__clang__)
2237 : #pragma clang diagnostic push
2238 : #pragma clang diagnostic ignored "-Wmissing-braces"
2239 : #endif
2240 : static const JSFunctionSpec sChromeStaticMethods_specs[] = {
2241 : JS_FNSPEC("_create", SEResponse::_Create, nullptr, 2, 0, nullptr),
2242 : JS_FS_END
2243 : };
2244 : #if defined(__clang__)
2245 : #pragma clang diagnostic pop
2246 : #endif
2247 :
2248 :
2249 : // Can't be const because the pref-enabled boolean needs to be writable
2250 : static Prefable<const JSFunctionSpec> sChromeStaticMethods[] = {
2251 : { nullptr, &sChromeStaticMethods_specs[0] },
2252 : { nullptr, nullptr }
2253 : };
2254 :
2255 : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
2256 : "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
2257 : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
2258 : "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
2259 :
2260 : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
2261 : #if defined(__clang__)
2262 : #pragma clang diagnostic push
2263 : #pragma clang diagnostic ignored "-Wmissing-braces"
2264 : #endif
2265 : static const JSFunctionSpec sChromeMethods_specs[] = {
2266 : JS_FNSPEC("_clearCachedDataValue", _ClearCachedDataValue, nullptr, 0, 0, nullptr),
2267 : JS_FS_END
2268 : };
2269 : #if defined(__clang__)
2270 : #pragma clang diagnostic pop
2271 : #endif
2272 :
2273 :
2274 : // Can't be const because the pref-enabled boolean needs to be writable
2275 : static Prefable<const JSFunctionSpec> sChromeMethods[] = {
2276 : { nullptr, &sChromeMethods_specs[0] },
2277 : { nullptr, nullptr }
2278 : };
2279 :
2280 : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
2281 : "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
2282 : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
2283 : "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
2284 :
2285 : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
2286 : #if defined(__clang__)
2287 : #pragma clang diagnostic push
2288 : #pragma clang diagnostic ignored "-Wmissing-braces"
2289 : #endif
2290 : static const JSPropertySpec sAttributes_specs[] = {
2291 : { "channel", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &channel_getterinfo, nullptr, nullptr },
2292 : { "sw1", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &sw1_getterinfo, nullptr, nullptr },
2293 : { "sw2", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &sw2_getterinfo, nullptr, nullptr },
2294 : { "data", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &data_getterinfo, nullptr, nullptr },
2295 : { nullptr, 0, nullptr, nullptr, nullptr, nullptr }
2296 : };
2297 : #if defined(__clang__)
2298 : #pragma clang diagnostic pop
2299 : #endif
2300 :
2301 :
2302 : // Can't be const because the pref-enabled boolean needs to be writable
2303 : static Prefable<const JSPropertySpec> sAttributes[] = {
2304 : { nullptr, &sAttributes_specs[0] },
2305 : { nullptr, nullptr }
2306 : };
2307 :
2308 : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
2309 : "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
2310 : static_assert(4 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
2311 : "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
2312 :
2313 :
2314 : static uint16_t sNativeProperties_sortedPropertyIndices[4];
2315 : static PropertyInfo sNativeProperties_propertyInfos[4];
2316 :
2317 : static const NativePropertiesN<1> sNativeProperties = {
2318 : false, 0,
2319 : false, 0,
2320 : false, 0,
2321 : true, 0 /* sAttributes */,
2322 : false, 0,
2323 : false, 0,
2324 : false, 0,
2325 : -1,
2326 : 4,
2327 : sNativeProperties_sortedPropertyIndices,
2328 : {
2329 : { sAttributes, &sNativeProperties_propertyInfos[0] }
2330 : }
2331 : };
2332 : static_assert(4 < 1ull << CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount),
2333 : "We have a property info count that is oversized");
2334 :
2335 : static uint16_t sChromeOnlyNativeProperties_sortedPropertyIndices[2];
2336 : static PropertyInfo sChromeOnlyNativeProperties_propertyInfos[2];
2337 :
2338 : static const NativePropertiesN<2> sChromeOnlyNativeProperties = {
2339 : true, 0 /* sChromeStaticMethods */,
2340 : false, 0,
2341 : true, 1 /* sChromeMethods */,
2342 : false, 0,
2343 : false, 0,
2344 : false, 0,
2345 : false, 0,
2346 : -1,
2347 : 2,
2348 : sChromeOnlyNativeProperties_sortedPropertyIndices,
2349 : {
2350 : { sChromeStaticMethods, &sChromeOnlyNativeProperties_propertyInfos[0] },
2351 : { sChromeMethods, &sChromeOnlyNativeProperties_propertyInfos[1] }
2352 : }
2353 : };
2354 : static_assert(2 < 1ull << CHAR_BIT * sizeof(sChromeOnlyNativeProperties.propertyInfoCount),
2355 : "We have a property info count that is oversized");
2356 :
2357 : static const DOMIfaceAndProtoJSClass sInterfaceObjectClass = {
2358 : {
2359 : "Function",
2360 : JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_SLOTS_BASE),
2361 : &sBoringInterfaceObjectClassClassOps,
2362 : JS_NULL_CLASS_SPEC,
2363 : JS_NULL_CLASS_EXT,
2364 : &sInterfaceObjectClassObjectOps
2365 : },
2366 : eInterface,
2367 : true,
2368 : prototypes::id::SEResponse,
2369 : PrototypeTraits<prototypes::id::SEResponse>::Depth,
2370 : sNativePropertyHooks,
2371 : "function SEResponse() {\n [native code]\n}",
2372 : JS::GetRealmFunctionPrototype
2373 : };
2374 :
2375 : static const DOMIfaceAndProtoJSClass sPrototypeClass = {
2376 : {
2377 : "SEResponsePrototype",
2378 : JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE),
2379 : JS_NULL_CLASS_OPS,
2380 : JS_NULL_CLASS_SPEC,
2381 : JS_NULL_CLASS_EXT,
2382 : JS_NULL_OBJECT_OPS
2383 : },
2384 : eInterfacePrototype,
2385 : false,
2386 : prototypes::id::SEResponse,
2387 : PrototypeTraits<prototypes::id::SEResponse>::Depth,
2388 : sNativePropertyHooks,
2389 : "[object SEResponsePrototype]",
2390 : JS::GetRealmObjectPrototype
2391 : };
2392 :
2393 : bool
2394 0 : ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
2395 : {
2396 : static bool sPrefValue;
2397 : static bool sPrefCacheSetUp = false;
2398 0 : if (!sPrefCacheSetUp) {
2399 0 : sPrefCacheSetUp = true;
2400 0 : Preferences::AddBoolVarCache(&sPrefValue, "dom.secureelement.enabled");
2401 : }
2402 :
2403 0 : return sPrefValue &&
2404 0 : nsContentUtils::ThreadsafeIsSystemCaller(aCx);
2405 : }
2406 :
2407 : JSObject*
2408 0 : DefineDOMInterface(JSContext* aCx, JS::Handle<JSObject*> aGlobal, JS::Handle<jsid> id, bool aDefineOnGlobal)
2409 : {
2410 0 : return GetConstructorObjectHandle(aCx, aDefineOnGlobal);
2411 : }
2412 :
2413 : static const js::ClassOps sClassOps = {
2414 : _addProperty, /* addProperty */
2415 : nullptr, /* delProperty */
2416 : nullptr, /* getProperty */
2417 : nullptr, /* setProperty */
2418 : nullptr, /* enumerate */
2419 : nullptr, /* newEnumerate */
2420 : nullptr, /* resolve */
2421 : nullptr, /* mayResolve */
2422 : _finalize, /* finalize */
2423 : nullptr, /* call */
2424 : nullptr, /* hasInstance */
2425 : nullptr, /* construct */
2426 : nullptr, /* trace */
2427 : };
2428 :
2429 : static const js::ClassExtension sClassExtension = {
2430 : nullptr, /* weakmapKeyDelegateOp */
2431 : _objectMoved /* objectMovedOp */
2432 : };
2433 :
2434 : static const DOMJSClass sClass = {
2435 : { "SEResponse",
2436 : JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(2),
2437 : &sClassOps,
2438 : JS_NULL_CLASS_SPEC,
2439 : &sClassExtension,
2440 : JS_NULL_OBJECT_OPS
2441 : },
2442 : { prototypes::id::SEResponse, 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 },
2443 : IsBaseOf<nsISupports, mozilla::dom::SEResponse >::value,
2444 : sNativePropertyHooks,
2445 : FindAssociatedGlobalForNative<mozilla::dom::SEResponse>::Get,
2446 : GetProtoObjectHandle,
2447 : GetCCParticipant<mozilla::dom::SEResponse>::Get()
2448 : };
2449 : static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
2450 : "Must have the right minimal number of reserved slots.");
2451 : static_assert(2 >= 2,
2452 : "Must have enough reserved slots.");
2453 :
2454 : const JSClass*
2455 0 : GetJSClass()
2456 : {
2457 0 : return sClass.ToJSClass();
2458 : }
2459 :
2460 : bool
2461 0 : Wrap(JSContext* aCx, mozilla::dom::SEResponse* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
2462 : {
2463 : MOZ_ASSERT(static_cast<mozilla::dom::SEResponse*>(aObject) ==
2464 : reinterpret_cast<mozilla::dom::SEResponse*>(aObject),
2465 : "Multiple inheritance for mozilla::dom::SEResponse is broken.");
2466 0 : MOZ_ASSERT(ToSupportsIsCorrect(aObject));
2467 0 : MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
2468 0 : MOZ_ASSERT(!aCache->GetWrapper(),
2469 : "You should probably not be using Wrap() directly; use "
2470 : "GetOrCreateDOMReflector instead");
2471 :
2472 0 : MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
2473 : "nsISupports must be on our primary inheritance chain");
2474 :
2475 0 : JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
2476 0 : if (!global) {
2477 0 : return false;
2478 : }
2479 0 : MOZ_ASSERT(JS_IsGlobalObject(global));
2480 0 : MOZ_ASSERT(JS::ObjectIsNotGray(global));
2481 :
2482 : // That might have ended up wrapping us already, due to the wonders
2483 : // of XBL. Check for that, and bail out as needed.
2484 0 : aReflector.set(aCache->GetWrapper());
2485 0 : if (aReflector) {
2486 : #ifdef DEBUG
2487 0 : binding_detail::AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
2488 : #endif // DEBUG
2489 0 : return true;
2490 : }
2491 :
2492 0 : JSAutoCompartment ac(aCx, global);
2493 0 : JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
2494 0 : if (!canonicalProto) {
2495 0 : return false;
2496 : }
2497 0 : JS::Rooted<JSObject*> proto(aCx);
2498 0 : if (aGivenProto) {
2499 0 : proto = aGivenProto;
2500 : // Unfortunately, while aGivenProto was in the compartment of aCx
2501 : // coming in, we changed compartments to that of "parent" so may need
2502 : // to wrap the proto here.
2503 0 : if (js::GetContextCompartment(aCx) != js::GetObjectCompartment(proto)) {
2504 0 : if (!JS_WrapObject(aCx, &proto)) {
2505 0 : return false;
2506 : }
2507 : }
2508 : } else {
2509 0 : proto = canonicalProto;
2510 : }
2511 :
2512 0 : BindingJSObjectCreator<mozilla::dom::SEResponse> creator(aCx);
2513 0 : creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
2514 0 : if (!aReflector) {
2515 0 : return false;
2516 : }
2517 :
2518 0 : aCache->SetWrapper(aReflector);
2519 0 : creator.InitializationSucceeded();
2520 :
2521 0 : MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
2522 : aCache->GetWrapperPreserveColor() == aReflector);
2523 : // If proto != canonicalProto, we have to preserve our wrapper;
2524 : // otherwise we won't be able to properly recreate it later, since
2525 : // we won't know what proto to use. Note that we don't check
2526 : // aGivenProto here, since it's entirely possible (and even
2527 : // somewhat common) to have a non-null aGivenProto which is the
2528 : // same as canonicalProto.
2529 0 : if (proto != canonicalProto) {
2530 0 : PreserveWrapper(aObject);
2531 : }
2532 :
2533 0 : return true;
2534 : }
2535 :
2536 : // This may allocate too many slots, because we only really need
2537 : // slots for our non-interface-typed members that we cache. But
2538 : // allocating slots only for those would make the slot index
2539 : // computations much more complicated, so let's do this the simple
2540 : // way for now.
2541 : DEFINE_XRAY_EXPANDO_CLASS(static, sXrayExpandoObjectClass, 1);
2542 :
2543 : const NativePropertyHooks sNativePropertyHooks[] = { {
2544 : nullptr,
2545 : nullptr,
2546 : nullptr,
2547 : { sNativeProperties.Upcast(), sChromeOnlyNativeProperties.Upcast() },
2548 : prototypes::id::SEResponse,
2549 : constructors::id::SEResponse,
2550 : nullptr,
2551 : &sXrayExpandoObjectClass
2552 : } };
2553 :
2554 : void
2555 0 : ClearCachedDataValue(mozilla::dom::SEResponse* aObject)
2556 : {
2557 : JSObject* obj;
2558 0 : obj = aObject->GetWrapper();
2559 0 : if (!obj) {
2560 0 : return;
2561 : }
2562 0 : js::SetReservedSlot(obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), JS::UndefinedValue());
2563 0 : xpc::ClearXrayExpandoSlots(obj, (xpc::JSSLOT_EXPANDO_COUNT + 0));
2564 : }
2565 :
2566 : void
2567 0 : CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, bool aDefineOnGlobal)
2568 : {
2569 0 : JS::Rooted<JSObject*> parentProto(aCx, JS::GetRealmObjectPrototype(aCx));
2570 0 : if (!parentProto) {
2571 0 : return;
2572 : }
2573 :
2574 0 : JS::Rooted<JSObject*> constructorProto(aCx, JS::GetRealmFunctionPrototype(aCx));
2575 0 : if (!constructorProto) {
2576 0 : return;
2577 : }
2578 :
2579 : static bool sIdsInited = false;
2580 0 : if (!sIdsInited && NS_IsMainThread()) {
2581 0 : if (!InitIds(aCx, sNativeProperties.Upcast())) {
2582 0 : return;
2583 : }
2584 0 : if (!InitIds(aCx, sChromeOnlyNativeProperties.Upcast())) {
2585 0 : return;
2586 : }
2587 0 : sIdsInited = true;
2588 : }
2589 :
2590 0 : JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::SEResponse);
2591 0 : JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::SEResponse);
2592 0 : dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
2593 : &sPrototypeClass.mBase, protoCache,
2594 : constructorProto, &sInterfaceObjectClass.mBase, 0, nullptr,
2595 : interfaceCache,
2596 : sNativeProperties.Upcast(),
2597 0 : nsContentUtils::ThreadsafeIsSystemCaller(aCx) ? sChromeOnlyNativeProperties.Upcast() : nullptr,
2598 : "SEResponse", aDefineOnGlobal,
2599 : nullptr,
2600 0 : false);
2601 : }
2602 :
2603 : JS::Handle<JSObject*>
2604 0 : GetProtoObjectHandle(JSContext* aCx)
2605 : {
2606 : /* Get the interface prototype object for this class. This will create the
2607 : object as needed. */
2608 0 : bool aDefineOnGlobal = true;
2609 :
2610 : /* Make sure our global is sane. Hopefully we can remove this sometime */
2611 0 : JSObject* global = JS::CurrentGlobalOrNull(aCx);
2612 0 : if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
2613 0 : return nullptr;
2614 : }
2615 :
2616 : /* Check to see whether the interface objects are already installed */
2617 0 : ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
2618 0 : if (!protoAndIfaceCache.HasEntryInSlot(prototypes::id::SEResponse)) {
2619 0 : JS::Rooted<JSObject*> rootedGlobal(aCx, global);
2620 0 : CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
2621 : }
2622 :
2623 : /*
2624 : * The object might _still_ be null, but that's OK.
2625 : *
2626 : * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
2627 : * traced by TraceProtoAndIfaceCache() and its contents are never
2628 : * changed after they have been set.
2629 : *
2630 : * Calling address() avoids the read read barrier that does gray
2631 : * unmarking, but it's not possible for the object to be gray here.
2632 : */
2633 :
2634 0 : const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(prototypes::id::SEResponse);
2635 0 : MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
2636 0 : return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
2637 : }
2638 :
2639 : JS::Handle<JSObject*>
2640 0 : GetConstructorObjectHandle(JSContext* aCx, bool aDefineOnGlobal)
2641 : {
2642 : /* Get the interface object for this class. This will create the object as
2643 : needed. */
2644 :
2645 : /* Make sure our global is sane. Hopefully we can remove this sometime */
2646 0 : JSObject* global = JS::CurrentGlobalOrNull(aCx);
2647 0 : if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
2648 0 : return nullptr;
2649 : }
2650 :
2651 : /* Check to see whether the interface objects are already installed */
2652 0 : ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
2653 0 : if (!protoAndIfaceCache.HasEntryInSlot(constructors::id::SEResponse)) {
2654 0 : JS::Rooted<JSObject*> rootedGlobal(aCx, global);
2655 0 : CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
2656 : }
2657 :
2658 : /*
2659 : * The object might _still_ be null, but that's OK.
2660 : *
2661 : * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
2662 : * traced by TraceProtoAndIfaceCache() and its contents are never
2663 : * changed after they have been set.
2664 : *
2665 : * Calling address() avoids the read read barrier that does gray
2666 : * unmarking, but it's not possible for the object to be gray here.
2667 : */
2668 :
2669 0 : const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(constructors::id::SEResponse);
2670 0 : MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
2671 0 : return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
2672 : }
2673 :
2674 : JSObject*
2675 0 : GetConstructorObject(JSContext* aCx)
2676 : {
2677 0 : return GetConstructorObjectHandle(aCx);
2678 : }
2679 :
2680 : } // namespace SEResponseBinding
2681 :
2682 :
2683 :
2684 : namespace SESessionBinding {
2685 :
2686 : static bool
2687 0 : get_reader(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::SESession* self, JSJitGetterCallArgs args)
2688 : {
2689 0 : Maybe<JS::Rooted<JSObject*> > unwrappedObj;
2690 0 : bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
2691 0 : if (objIsXray) {
2692 0 : unwrappedObj.emplace(cx, obj);
2693 : }
2694 0 : if (objIsXray) {
2695 0 : unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
2696 0 : if (!unwrappedObj.ref()) {
2697 0 : return false;
2698 : }
2699 : }
2700 0 : binding_detail::FastErrorResult rv;
2701 0 : auto result(StrongOrRawPtr<mozilla::dom::SEReader>(self->GetReader(rv, js::GetObjectCompartment(unwrappedObj ? *unwrappedObj : obj))));
2702 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
2703 0 : return false;
2704 : }
2705 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
2706 0 : if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
2707 0 : MOZ_ASSERT(true || JS_IsExceptionPending(cx));
2708 0 : return false;
2709 : }
2710 0 : return true;
2711 : }
2712 :
2713 : static const JSJitInfo reader_getterinfo = {
2714 : { (JSJitGetterOp)get_reader },
2715 : { prototypes::id::SESession },
2716 : { PrototypeTraits<prototypes::id::SESession>::Depth },
2717 : JSJitInfo::Getter,
2718 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
2719 : JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
2720 : false, /* isInfallible. False in setters. */
2721 : false, /* isMovable. Not relevant for setters. */
2722 : false, /* isEliminatable. Not relevant for setters. */
2723 : false, /* isAlwaysInSlot. Only relevant for getters. */
2724 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
2725 : false, /* isTypedMethod. Only relevant for methods. */
2726 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
2727 : };
2728 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
2729 : static_assert(0 < 1, "There is no slot for us");
2730 :
2731 : static bool
2732 0 : get_isClosed(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::SESession* self, JSJitGetterCallArgs args)
2733 : {
2734 0 : Maybe<JS::Rooted<JSObject*> > unwrappedObj;
2735 0 : bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
2736 0 : if (objIsXray) {
2737 0 : unwrappedObj.emplace(cx, obj);
2738 : }
2739 0 : if (objIsXray) {
2740 0 : unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
2741 0 : if (!unwrappedObj.ref()) {
2742 0 : return false;
2743 : }
2744 : }
2745 0 : binding_detail::FastErrorResult rv;
2746 0 : bool result(self->GetIsClosed(rv, js::GetObjectCompartment(unwrappedObj ? *unwrappedObj : obj)));
2747 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
2748 0 : return false;
2749 : }
2750 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
2751 0 : args.rval().setBoolean(result);
2752 0 : return true;
2753 : }
2754 :
2755 : static const JSJitInfo isClosed_getterinfo = {
2756 : { (JSJitGetterOp)get_isClosed },
2757 : { prototypes::id::SESession },
2758 : { PrototypeTraits<prototypes::id::SESession>::Depth },
2759 : JSJitInfo::Getter,
2760 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
2761 : JSVAL_TYPE_BOOLEAN, /* returnType. Not relevant for setters. */
2762 : false, /* isInfallible. False in setters. */
2763 : false, /* isMovable. Not relevant for setters. */
2764 : false, /* isEliminatable. Not relevant for setters. */
2765 : false, /* isAlwaysInSlot. Only relevant for getters. */
2766 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
2767 : false, /* isTypedMethod. Only relevant for methods. */
2768 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
2769 : };
2770 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
2771 : static_assert(0 < 1, "There is no slot for us");
2772 :
2773 : static bool
2774 0 : openLogicalChannel(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::SESession* self, const JSJitMethodCallArgs& args)
2775 : {
2776 0 : if (MOZ_UNLIKELY(args.length() < 1)) {
2777 0 : return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "SESession.openLogicalChannel");
2778 : }
2779 0 : Maybe<JS::Rooted<JSObject*> > unwrappedObj;
2780 0 : bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
2781 0 : if (objIsXray) {
2782 0 : unwrappedObj.emplace(cx, obj);
2783 : }
2784 0 : RootedTypedArray<Nullable<Uint8Array>> arg0(cx);
2785 0 : if (args[0].isObject()) {
2786 0 : if (!arg0.SetValue().Init(&args[0].toObject())) {
2787 0 : ThrowErrorMessage(cx, MSG_DOES_NOT_IMPLEMENT_INTERFACE, "Argument 1 of SESession.openLogicalChannel", "Uint8ArrayOrNull");
2788 0 : return false;
2789 : }
2790 0 : } else if (args[0].isNullOrUndefined()) {
2791 0 : arg0.SetNull();
2792 : } else {
2793 0 : ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 1 of SESession.openLogicalChannel");
2794 0 : return false;
2795 : }
2796 0 : if (objIsXray) {
2797 0 : unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
2798 0 : if (!unwrappedObj.ref()) {
2799 0 : return false;
2800 : }
2801 : }
2802 0 : binding_detail::FastErrorResult rv;
2803 0 : auto result(StrongOrRawPtr<Promise>(self->OpenLogicalChannel(Constify(arg0), rv, js::GetObjectCompartment(unwrappedObj ? *unwrappedObj : obj))));
2804 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
2805 0 : return false;
2806 : }
2807 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
2808 0 : if (!ToJSValue(cx, result, args.rval())) {
2809 0 : return false;
2810 : }
2811 0 : return true;
2812 : }
2813 :
2814 : static bool
2815 0 : openLogicalChannel_promiseWrapper(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::SESession* self, const JSJitMethodCallArgs& args)
2816 : {
2817 : // Make sure to save the callee before someone maybe messes
2818 : // with rval().
2819 0 : JS::Rooted<JSObject*> callee(cx, &args.callee());
2820 0 : bool ok = openLogicalChannel(cx, obj, self, args);
2821 0 : if (ok) {
2822 0 : return true;
2823 : }
2824 0 : return ConvertExceptionToPromise(cx, xpc::XrayAwareCalleeGlobal(callee),
2825 0 : args.rval());
2826 : }
2827 :
2828 : static const JSJitInfo openLogicalChannel_methodinfo = {
2829 : { (JSJitGetterOp)openLogicalChannel_promiseWrapper },
2830 : { prototypes::id::SESession },
2831 : { PrototypeTraits<prototypes::id::SESession>::Depth },
2832 : JSJitInfo::Method,
2833 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
2834 : JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
2835 : false, /* isInfallible. False in setters. */
2836 : false, /* isMovable. Not relevant for setters. */
2837 : false, /* isEliminatable. Not relevant for setters. */
2838 : false, /* isAlwaysInSlot. Only relevant for getters. */
2839 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
2840 : false, /* isTypedMethod. Only relevant for methods. */
2841 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
2842 : };
2843 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
2844 : static_assert(0 < 1, "There is no slot for us");
2845 :
2846 : static bool
2847 0 : closeAll(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::SESession* self, const JSJitMethodCallArgs& args)
2848 : {
2849 0 : Maybe<JS::Rooted<JSObject*> > unwrappedObj;
2850 0 : bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
2851 0 : if (objIsXray) {
2852 0 : unwrappedObj.emplace(cx, obj);
2853 : }
2854 0 : if (objIsXray) {
2855 0 : unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
2856 0 : if (!unwrappedObj.ref()) {
2857 0 : return false;
2858 : }
2859 : }
2860 0 : binding_detail::FastErrorResult rv;
2861 0 : auto result(StrongOrRawPtr<Promise>(self->CloseAll(rv, js::GetObjectCompartment(unwrappedObj ? *unwrappedObj : obj))));
2862 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
2863 0 : return false;
2864 : }
2865 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
2866 0 : if (!ToJSValue(cx, result, args.rval())) {
2867 0 : return false;
2868 : }
2869 0 : return true;
2870 : }
2871 :
2872 : static bool
2873 0 : closeAll_promiseWrapper(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::SESession* self, const JSJitMethodCallArgs& args)
2874 : {
2875 : // Make sure to save the callee before someone maybe messes
2876 : // with rval().
2877 0 : JS::Rooted<JSObject*> callee(cx, &args.callee());
2878 0 : bool ok = closeAll(cx, obj, self, args);
2879 0 : if (ok) {
2880 0 : return true;
2881 : }
2882 0 : return ConvertExceptionToPromise(cx, xpc::XrayAwareCalleeGlobal(callee),
2883 0 : args.rval());
2884 : }
2885 :
2886 : static const JSJitInfo closeAll_methodinfo = {
2887 : { (JSJitGetterOp)closeAll_promiseWrapper },
2888 : { prototypes::id::SESession },
2889 : { PrototypeTraits<prototypes::id::SESession>::Depth },
2890 : JSJitInfo::Method,
2891 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
2892 : JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
2893 : false, /* isInfallible. False in setters. */
2894 : false, /* isMovable. Not relevant for setters. */
2895 : false, /* isEliminatable. Not relevant for setters. */
2896 : false, /* isAlwaysInSlot. Only relevant for getters. */
2897 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
2898 : false, /* isTypedMethod. Only relevant for methods. */
2899 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
2900 : };
2901 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
2902 : static_assert(0 < 1, "There is no slot for us");
2903 :
2904 : static bool
2905 0 : _addProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::Handle<JS::Value> val)
2906 : {
2907 0 : mozilla::dom::SESession* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::SESession>(obj);
2908 : // We don't want to preserve if we don't have a wrapper, and we
2909 : // obviously can't preserve if we're not initialized.
2910 0 : if (self && self->GetWrapperPreserveColor()) {
2911 0 : PreserveWrapper(self);
2912 : }
2913 0 : return true;
2914 : }
2915 :
2916 : static void
2917 0 : _finalize(js::FreeOp* fop, JSObject* obj)
2918 : {
2919 0 : mozilla::dom::SESession* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::SESession>(obj);
2920 0 : if (self) {
2921 0 : ClearWrapper(self, self, obj);
2922 0 : AddForDeferredFinalization<mozilla::dom::SESession>(self);
2923 : }
2924 0 : }
2925 :
2926 : static void
2927 0 : _objectMoved(JSObject* obj, const JSObject* old)
2928 : {
2929 0 : mozilla::dom::SESession* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::SESession>(obj);
2930 0 : if (self) {
2931 0 : UpdateWrapper(self, self, obj, old);
2932 : }
2933 0 : }
2934 :
2935 : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
2936 : #if defined(__clang__)
2937 : #pragma clang diagnostic push
2938 : #pragma clang diagnostic ignored "-Wmissing-braces"
2939 : #endif
2940 : static const JSFunctionSpec sChromeStaticMethods_specs[] = {
2941 : JS_FNSPEC("_create", SESession::_Create, nullptr, 2, 0, nullptr),
2942 : JS_FS_END
2943 : };
2944 : #if defined(__clang__)
2945 : #pragma clang diagnostic pop
2946 : #endif
2947 :
2948 :
2949 : // Can't be const because the pref-enabled boolean needs to be writable
2950 : static Prefable<const JSFunctionSpec> sChromeStaticMethods[] = {
2951 : { nullptr, &sChromeStaticMethods_specs[0] },
2952 : { nullptr, nullptr }
2953 : };
2954 :
2955 : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
2956 : "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
2957 : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
2958 : "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
2959 :
2960 : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
2961 : #if defined(__clang__)
2962 : #pragma clang diagnostic push
2963 : #pragma clang diagnostic ignored "-Wmissing-braces"
2964 : #endif
2965 : static const JSFunctionSpec sMethods_specs[] = {
2966 : JS_FNSPEC("openLogicalChannel", GenericPromiseReturningBindingMethod, reinterpret_cast<const JSJitInfo*>(&openLogicalChannel_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
2967 : JS_FNSPEC("closeAll", GenericPromiseReturningBindingMethod, reinterpret_cast<const JSJitInfo*>(&closeAll_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
2968 : JS_FS_END
2969 : };
2970 : #if defined(__clang__)
2971 : #pragma clang diagnostic pop
2972 : #endif
2973 :
2974 :
2975 : // Can't be const because the pref-enabled boolean needs to be writable
2976 : static Prefable<const JSFunctionSpec> sMethods[] = {
2977 : { nullptr, &sMethods_specs[0] },
2978 : { nullptr, nullptr }
2979 : };
2980 :
2981 : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
2982 : "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
2983 : static_assert(2 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
2984 : "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
2985 :
2986 : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
2987 : #if defined(__clang__)
2988 : #pragma clang diagnostic push
2989 : #pragma clang diagnostic ignored "-Wmissing-braces"
2990 : #endif
2991 : static const JSPropertySpec sAttributes_specs[] = {
2992 : { "reader", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &reader_getterinfo, nullptr, nullptr },
2993 : { "isClosed", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &isClosed_getterinfo, nullptr, nullptr },
2994 : { nullptr, 0, nullptr, nullptr, nullptr, nullptr }
2995 : };
2996 : #if defined(__clang__)
2997 : #pragma clang diagnostic pop
2998 : #endif
2999 :
3000 :
3001 : // Can't be const because the pref-enabled boolean needs to be writable
3002 : static Prefable<const JSPropertySpec> sAttributes[] = {
3003 : { nullptr, &sAttributes_specs[0] },
3004 : { nullptr, nullptr }
3005 : };
3006 :
3007 : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
3008 : "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
3009 : static_assert(2 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
3010 : "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
3011 :
3012 :
3013 : static uint16_t sNativeProperties_sortedPropertyIndices[4];
3014 : static PropertyInfo sNativeProperties_propertyInfos[4];
3015 :
3016 : static const NativePropertiesN<2> sNativeProperties = {
3017 : false, 0,
3018 : false, 0,
3019 : true, 0 /* sMethods */,
3020 : true, 1 /* sAttributes */,
3021 : false, 0,
3022 : false, 0,
3023 : false, 0,
3024 : -1,
3025 : 4,
3026 : sNativeProperties_sortedPropertyIndices,
3027 : {
3028 : { sMethods, &sNativeProperties_propertyInfos[0] },
3029 : { sAttributes, &sNativeProperties_propertyInfos[2] }
3030 : }
3031 : };
3032 : static_assert(4 < 1ull << CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount),
3033 : "We have a property info count that is oversized");
3034 :
3035 : static uint16_t sChromeOnlyNativeProperties_sortedPropertyIndices[1];
3036 : static PropertyInfo sChromeOnlyNativeProperties_propertyInfos[1];
3037 :
3038 : static const NativePropertiesN<1> sChromeOnlyNativeProperties = {
3039 : true, 0 /* sChromeStaticMethods */,
3040 : false, 0,
3041 : false, 0,
3042 : false, 0,
3043 : false, 0,
3044 : false, 0,
3045 : false, 0,
3046 : -1,
3047 : 1,
3048 : sChromeOnlyNativeProperties_sortedPropertyIndices,
3049 : {
3050 : { sChromeStaticMethods, &sChromeOnlyNativeProperties_propertyInfos[0] }
3051 : }
3052 : };
3053 : static_assert(1 < 1ull << CHAR_BIT * sizeof(sChromeOnlyNativeProperties.propertyInfoCount),
3054 : "We have a property info count that is oversized");
3055 :
3056 : static const DOMIfaceAndProtoJSClass sInterfaceObjectClass = {
3057 : {
3058 : "Function",
3059 : JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_SLOTS_BASE),
3060 : &sBoringInterfaceObjectClassClassOps,
3061 : JS_NULL_CLASS_SPEC,
3062 : JS_NULL_CLASS_EXT,
3063 : &sInterfaceObjectClassObjectOps
3064 : },
3065 : eInterface,
3066 : true,
3067 : prototypes::id::SESession,
3068 : PrototypeTraits<prototypes::id::SESession>::Depth,
3069 : sNativePropertyHooks,
3070 : "function SESession() {\n [native code]\n}",
3071 : JS::GetRealmFunctionPrototype
3072 : };
3073 :
3074 : static const DOMIfaceAndProtoJSClass sPrototypeClass = {
3075 : {
3076 : "SESessionPrototype",
3077 : JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE),
3078 : JS_NULL_CLASS_OPS,
3079 : JS_NULL_CLASS_SPEC,
3080 : JS_NULL_CLASS_EXT,
3081 : JS_NULL_OBJECT_OPS
3082 : },
3083 : eInterfacePrototype,
3084 : false,
3085 : prototypes::id::SESession,
3086 : PrototypeTraits<prototypes::id::SESession>::Depth,
3087 : sNativePropertyHooks,
3088 : "[object SESessionPrototype]",
3089 : JS::GetRealmObjectPrototype
3090 : };
3091 :
3092 : bool
3093 0 : ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
3094 : {
3095 : static bool sPrefValue;
3096 : static bool sPrefCacheSetUp = false;
3097 0 : if (!sPrefCacheSetUp) {
3098 0 : sPrefCacheSetUp = true;
3099 0 : Preferences::AddBoolVarCache(&sPrefValue, "dom.secureelement.enabled");
3100 : }
3101 :
3102 0 : return sPrefValue &&
3103 0 : nsContentUtils::ThreadsafeIsSystemCaller(aCx);
3104 : }
3105 :
3106 : JSObject*
3107 0 : DefineDOMInterface(JSContext* aCx, JS::Handle<JSObject*> aGlobal, JS::Handle<jsid> id, bool aDefineOnGlobal)
3108 : {
3109 0 : return GetConstructorObjectHandle(aCx, aDefineOnGlobal);
3110 : }
3111 :
3112 : static const js::ClassOps sClassOps = {
3113 : _addProperty, /* addProperty */
3114 : nullptr, /* delProperty */
3115 : nullptr, /* getProperty */
3116 : nullptr, /* setProperty */
3117 : nullptr, /* enumerate */
3118 : nullptr, /* newEnumerate */
3119 : nullptr, /* resolve */
3120 : nullptr, /* mayResolve */
3121 : _finalize, /* finalize */
3122 : nullptr, /* call */
3123 : nullptr, /* hasInstance */
3124 : nullptr, /* construct */
3125 : nullptr, /* trace */
3126 : };
3127 :
3128 : static const js::ClassExtension sClassExtension = {
3129 : nullptr, /* weakmapKeyDelegateOp */
3130 : _objectMoved /* objectMovedOp */
3131 : };
3132 :
3133 : static const DOMJSClass sClass = {
3134 : { "SESession",
3135 : JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1),
3136 : &sClassOps,
3137 : JS_NULL_CLASS_SPEC,
3138 : &sClassExtension,
3139 : JS_NULL_OBJECT_OPS
3140 : },
3141 : { prototypes::id::SESession, 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 },
3142 : IsBaseOf<nsISupports, mozilla::dom::SESession >::value,
3143 : sNativePropertyHooks,
3144 : FindAssociatedGlobalForNative<mozilla::dom::SESession>::Get,
3145 : GetProtoObjectHandle,
3146 : GetCCParticipant<mozilla::dom::SESession>::Get()
3147 : };
3148 : static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
3149 : "Must have the right minimal number of reserved slots.");
3150 : static_assert(1 >= 1,
3151 : "Must have enough reserved slots.");
3152 :
3153 : const JSClass*
3154 0 : GetJSClass()
3155 : {
3156 0 : return sClass.ToJSClass();
3157 : }
3158 :
3159 : bool
3160 0 : Wrap(JSContext* aCx, mozilla::dom::SESession* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
3161 : {
3162 : MOZ_ASSERT(static_cast<mozilla::dom::SESession*>(aObject) ==
3163 : reinterpret_cast<mozilla::dom::SESession*>(aObject),
3164 : "Multiple inheritance for mozilla::dom::SESession is broken.");
3165 0 : MOZ_ASSERT(ToSupportsIsCorrect(aObject));
3166 0 : MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
3167 0 : MOZ_ASSERT(!aCache->GetWrapper(),
3168 : "You should probably not be using Wrap() directly; use "
3169 : "GetOrCreateDOMReflector instead");
3170 :
3171 0 : MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
3172 : "nsISupports must be on our primary inheritance chain");
3173 :
3174 0 : JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
3175 0 : if (!global) {
3176 0 : return false;
3177 : }
3178 0 : MOZ_ASSERT(JS_IsGlobalObject(global));
3179 0 : MOZ_ASSERT(JS::ObjectIsNotGray(global));
3180 :
3181 : // That might have ended up wrapping us already, due to the wonders
3182 : // of XBL. Check for that, and bail out as needed.
3183 0 : aReflector.set(aCache->GetWrapper());
3184 0 : if (aReflector) {
3185 : #ifdef DEBUG
3186 0 : binding_detail::AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
3187 : #endif // DEBUG
3188 0 : return true;
3189 : }
3190 :
3191 0 : JSAutoCompartment ac(aCx, global);
3192 0 : JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
3193 0 : if (!canonicalProto) {
3194 0 : return false;
3195 : }
3196 0 : JS::Rooted<JSObject*> proto(aCx);
3197 0 : if (aGivenProto) {
3198 0 : proto = aGivenProto;
3199 : // Unfortunately, while aGivenProto was in the compartment of aCx
3200 : // coming in, we changed compartments to that of "parent" so may need
3201 : // to wrap the proto here.
3202 0 : if (js::GetContextCompartment(aCx) != js::GetObjectCompartment(proto)) {
3203 0 : if (!JS_WrapObject(aCx, &proto)) {
3204 0 : return false;
3205 : }
3206 : }
3207 : } else {
3208 0 : proto = canonicalProto;
3209 : }
3210 :
3211 0 : BindingJSObjectCreator<mozilla::dom::SESession> creator(aCx);
3212 0 : creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
3213 0 : if (!aReflector) {
3214 0 : return false;
3215 : }
3216 :
3217 0 : aCache->SetWrapper(aReflector);
3218 0 : creator.InitializationSucceeded();
3219 :
3220 0 : MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
3221 : aCache->GetWrapperPreserveColor() == aReflector);
3222 : // If proto != canonicalProto, we have to preserve our wrapper;
3223 : // otherwise we won't be able to properly recreate it later, since
3224 : // we won't know what proto to use. Note that we don't check
3225 : // aGivenProto here, since it's entirely possible (and even
3226 : // somewhat common) to have a non-null aGivenProto which is the
3227 : // same as canonicalProto.
3228 0 : if (proto != canonicalProto) {
3229 0 : PreserveWrapper(aObject);
3230 : }
3231 :
3232 0 : return true;
3233 : }
3234 :
3235 : const NativePropertyHooks sNativePropertyHooks[] = { {
3236 : nullptr,
3237 : nullptr,
3238 : nullptr,
3239 : { sNativeProperties.Upcast(), sChromeOnlyNativeProperties.Upcast() },
3240 : prototypes::id::SESession,
3241 : constructors::id::SESession,
3242 : nullptr,
3243 : &DefaultXrayExpandoObjectClass
3244 : } };
3245 :
3246 : void
3247 0 : CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, bool aDefineOnGlobal)
3248 : {
3249 0 : JS::Rooted<JSObject*> parentProto(aCx, JS::GetRealmObjectPrototype(aCx));
3250 0 : if (!parentProto) {
3251 0 : return;
3252 : }
3253 :
3254 0 : JS::Rooted<JSObject*> constructorProto(aCx, JS::GetRealmFunctionPrototype(aCx));
3255 0 : if (!constructorProto) {
3256 0 : return;
3257 : }
3258 :
3259 : static bool sIdsInited = false;
3260 0 : if (!sIdsInited && NS_IsMainThread()) {
3261 0 : if (!InitIds(aCx, sNativeProperties.Upcast())) {
3262 0 : return;
3263 : }
3264 0 : if (!InitIds(aCx, sChromeOnlyNativeProperties.Upcast())) {
3265 0 : return;
3266 : }
3267 0 : sIdsInited = true;
3268 : }
3269 :
3270 0 : JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::SESession);
3271 0 : JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::SESession);
3272 0 : dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
3273 : &sPrototypeClass.mBase, protoCache,
3274 : constructorProto, &sInterfaceObjectClass.mBase, 0, nullptr,
3275 : interfaceCache,
3276 : sNativeProperties.Upcast(),
3277 0 : nsContentUtils::ThreadsafeIsSystemCaller(aCx) ? sChromeOnlyNativeProperties.Upcast() : nullptr,
3278 : "SESession", aDefineOnGlobal,
3279 : nullptr,
3280 0 : false);
3281 : }
3282 :
3283 : JS::Handle<JSObject*>
3284 0 : GetProtoObjectHandle(JSContext* aCx)
3285 : {
3286 : /* Get the interface prototype object for this class. This will create the
3287 : object as needed. */
3288 0 : bool aDefineOnGlobal = true;
3289 :
3290 : /* Make sure our global is sane. Hopefully we can remove this sometime */
3291 0 : JSObject* global = JS::CurrentGlobalOrNull(aCx);
3292 0 : if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
3293 0 : return nullptr;
3294 : }
3295 :
3296 : /* Check to see whether the interface objects are already installed */
3297 0 : ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
3298 0 : if (!protoAndIfaceCache.HasEntryInSlot(prototypes::id::SESession)) {
3299 0 : JS::Rooted<JSObject*> rootedGlobal(aCx, global);
3300 0 : CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
3301 : }
3302 :
3303 : /*
3304 : * The object might _still_ be null, but that's OK.
3305 : *
3306 : * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
3307 : * traced by TraceProtoAndIfaceCache() and its contents are never
3308 : * changed after they have been set.
3309 : *
3310 : * Calling address() avoids the read read barrier that does gray
3311 : * unmarking, but it's not possible for the object to be gray here.
3312 : */
3313 :
3314 0 : const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(prototypes::id::SESession);
3315 0 : MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
3316 0 : return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
3317 : }
3318 :
3319 : JS::Handle<JSObject*>
3320 0 : GetConstructorObjectHandle(JSContext* aCx, bool aDefineOnGlobal)
3321 : {
3322 : /* Get the interface object for this class. This will create the object as
3323 : needed. */
3324 :
3325 : /* Make sure our global is sane. Hopefully we can remove this sometime */
3326 0 : JSObject* global = JS::CurrentGlobalOrNull(aCx);
3327 0 : if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
3328 0 : return nullptr;
3329 : }
3330 :
3331 : /* Check to see whether the interface objects are already installed */
3332 0 : ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
3333 0 : if (!protoAndIfaceCache.HasEntryInSlot(constructors::id::SESession)) {
3334 0 : JS::Rooted<JSObject*> rootedGlobal(aCx, global);
3335 0 : CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
3336 : }
3337 :
3338 : /*
3339 : * The object might _still_ be null, but that's OK.
3340 : *
3341 : * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
3342 : * traced by TraceProtoAndIfaceCache() and its contents are never
3343 : * changed after they have been set.
3344 : *
3345 : * Calling address() avoids the read read barrier that does gray
3346 : * unmarking, but it's not possible for the object to be gray here.
3347 : */
3348 :
3349 0 : const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(constructors::id::SESession);
3350 0 : MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
3351 0 : return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
3352 : }
3353 :
3354 : JSObject*
3355 0 : GetConstructorObject(JSContext* aCx)
3356 : {
3357 0 : return GetConstructorObjectHandle(aCx);
3358 : }
3359 :
3360 : } // namespace SESessionBinding
3361 :
3362 :
3363 :
3364 : already_AddRefed<Promise>
3365 0 : SEChannelJSImpl::Transmit(const SECommand& command, ErrorResult& aRv, JSCompartment* aCompartment)
3366 : {
3367 0 : CallSetup s(this, aRv, "SEChannel.transmit", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
3368 0 : JSContext* cx = s.GetContext();
3369 0 : if (!cx) {
3370 0 : MOZ_ASSERT(aRv.Failed());
3371 0 : return nullptr;
3372 : }
3373 0 : JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
3374 0 : JS::AutoValueVector argv(cx);
3375 0 : if (!argv.resize(1)) {
3376 0 : aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
3377 0 : return nullptr;
3378 : }
3379 0 : unsigned argc = 1;
3380 :
3381 : do {
3382 0 : if (!command.ToObjectInternal(cx, argv[0])) {
3383 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
3384 0 : return nullptr;
3385 : }
3386 0 : break;
3387 : } while (0);
3388 :
3389 0 : JS::Rooted<JS::Value> callable(cx);
3390 0 : SEChannelAtoms* atomsCache = GetAtomCache<SEChannelAtoms>(cx);
3391 0 : if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
3392 0 : !GetCallableProperty(cx, atomsCache->transmit_id, &callable)) {
3393 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
3394 0 : return nullptr;
3395 : }
3396 0 : JS::Rooted<JS::Value> thisValue(cx, JS::ObjectValue(*mCallback));
3397 0 : if (!JS::Call(cx, thisValue, callable,
3398 0 : JS::HandleValueArray::subarray(argv, 0, argc), &rval)) {
3399 0 : aRv.NoteJSContextException(cx);
3400 0 : return nullptr;
3401 : }
3402 0 : RefPtr<Promise> rvalDecl;
3403 : { // Scope for our GlobalObject, FastErrorResult, JSAutoCompartment,
3404 : // etc.
3405 :
3406 0 : JS::Rooted<JSObject*> globalObj(cx, JS::CurrentGlobalOrNull(cx));
3407 0 : if (!rval.isObject()) {
3408 0 : aRv.ThrowTypeError<MSG_NOT_OBJECT>(NS_LITERAL_STRING("return value of SEChannel.transmit"));
3409 0 : return nullptr;
3410 : }
3411 0 : JSObject* unwrappedVal = js::CheckedUnwrap(&rval.toObject());
3412 0 : if (!unwrappedVal) {
3413 : // A slight lie, but not much of one, for a dead object wrapper.
3414 0 : aRv.ThrowTypeError<MSG_NOT_OBJECT>(NS_LITERAL_STRING("return value of SEChannel.transmit"));
3415 0 : return nullptr;
3416 : }
3417 0 : globalObj = js::GetGlobalForObjectCrossCompartment(unwrappedVal);
3418 0 : JSAutoCompartment ac(cx, globalObj);
3419 0 : GlobalObject promiseGlobal(cx, globalObj);
3420 0 : if (promiseGlobal.Failed()) {
3421 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
3422 0 : return nullptr;
3423 : }
3424 :
3425 0 : JS::Rooted<JS::Value> valueToResolve(cx, rval);
3426 0 : if (!JS_WrapValue(cx, &valueToResolve)) {
3427 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
3428 0 : return nullptr;
3429 : }
3430 0 : binding_detail::FastErrorResult promiseRv;
3431 : nsCOMPtr<nsIGlobalObject> global =
3432 0 : do_QueryInterface(promiseGlobal.GetAsSupports());
3433 0 : if (!global) {
3434 0 : promiseRv.ThrowWithCustomCleanup(NS_ERROR_UNEXPECTED);
3435 0 : MOZ_ALWAYS_TRUE(promiseRv.MaybeSetPendingException(cx));
3436 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
3437 0 : return nullptr;
3438 : }
3439 0 : rvalDecl = Promise::Resolve(global, cx, valueToResolve,
3440 0 : promiseRv);
3441 0 : if (promiseRv.MaybeSetPendingException(cx)) {
3442 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
3443 0 : return nullptr;
3444 : }
3445 : }
3446 0 : return rvalDecl.forget();
3447 : }
3448 :
3449 : already_AddRefed<Promise>
3450 0 : SEChannelJSImpl::Close(ErrorResult& aRv, JSCompartment* aCompartment)
3451 : {
3452 0 : CallSetup s(this, aRv, "SEChannel.close", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
3453 0 : JSContext* cx = s.GetContext();
3454 0 : if (!cx) {
3455 0 : MOZ_ASSERT(aRv.Failed());
3456 0 : return nullptr;
3457 : }
3458 0 : JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
3459 :
3460 0 : JS::Rooted<JS::Value> callable(cx);
3461 0 : SEChannelAtoms* atomsCache = GetAtomCache<SEChannelAtoms>(cx);
3462 0 : if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
3463 0 : !GetCallableProperty(cx, atomsCache->close_id, &callable)) {
3464 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
3465 0 : return nullptr;
3466 : }
3467 0 : JS::Rooted<JS::Value> thisValue(cx, JS::ObjectValue(*mCallback));
3468 0 : if (!JS::Call(cx, thisValue, callable,
3469 0 : JS::HandleValueArray::empty(), &rval)) {
3470 0 : aRv.NoteJSContextException(cx);
3471 0 : return nullptr;
3472 : }
3473 0 : RefPtr<Promise> rvalDecl;
3474 : { // Scope for our GlobalObject, FastErrorResult, JSAutoCompartment,
3475 : // etc.
3476 :
3477 0 : JS::Rooted<JSObject*> globalObj(cx, JS::CurrentGlobalOrNull(cx));
3478 0 : if (!rval.isObject()) {
3479 0 : aRv.ThrowTypeError<MSG_NOT_OBJECT>(NS_LITERAL_STRING("return value of SEChannel.close"));
3480 0 : return nullptr;
3481 : }
3482 0 : JSObject* unwrappedVal = js::CheckedUnwrap(&rval.toObject());
3483 0 : if (!unwrappedVal) {
3484 : // A slight lie, but not much of one, for a dead object wrapper.
3485 0 : aRv.ThrowTypeError<MSG_NOT_OBJECT>(NS_LITERAL_STRING("return value of SEChannel.close"));
3486 0 : return nullptr;
3487 : }
3488 0 : globalObj = js::GetGlobalForObjectCrossCompartment(unwrappedVal);
3489 0 : JSAutoCompartment ac(cx, globalObj);
3490 0 : GlobalObject promiseGlobal(cx, globalObj);
3491 0 : if (promiseGlobal.Failed()) {
3492 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
3493 0 : return nullptr;
3494 : }
3495 :
3496 0 : JS::Rooted<JS::Value> valueToResolve(cx, rval);
3497 0 : if (!JS_WrapValue(cx, &valueToResolve)) {
3498 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
3499 0 : return nullptr;
3500 : }
3501 0 : binding_detail::FastErrorResult promiseRv;
3502 : nsCOMPtr<nsIGlobalObject> global =
3503 0 : do_QueryInterface(promiseGlobal.GetAsSupports());
3504 0 : if (!global) {
3505 0 : promiseRv.ThrowWithCustomCleanup(NS_ERROR_UNEXPECTED);
3506 0 : MOZ_ALWAYS_TRUE(promiseRv.MaybeSetPendingException(cx));
3507 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
3508 0 : return nullptr;
3509 : }
3510 0 : rvalDecl = Promise::Resolve(global, cx, valueToResolve,
3511 0 : promiseRv);
3512 0 : if (promiseRv.MaybeSetPendingException(cx)) {
3513 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
3514 0 : return nullptr;
3515 : }
3516 : }
3517 0 : return rvalDecl.forget();
3518 : }
3519 :
3520 : bool
3521 0 : SEChannelJSImpl::InitIds(JSContext* cx, SEChannelAtoms* atomsCache)
3522 : {
3523 0 : MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
3524 :
3525 : // Initialize these in reverse order so that any failure leaves the first one
3526 : // uninitialized.
3527 0 : if (!atomsCache->close_id.init(cx, "close") ||
3528 0 : !atomsCache->transmit_id.init(cx, "transmit") ||
3529 0 : !atomsCache->type_id.init(cx, "type") ||
3530 0 : !atomsCache->isClosed_id.init(cx, "isClosed") ||
3531 0 : !atomsCache->openResponse_id.init(cx, "openResponse") ||
3532 0 : !atomsCache->session_id.init(cx, "session")) {
3533 0 : return false;
3534 : }
3535 0 : return true;
3536 : }
3537 :
3538 :
3539 : already_AddRefed<SESession>
3540 0 : SEChannelJSImpl::GetSession(ErrorResult& aRv, JSCompartment* aCompartment)
3541 : {
3542 0 : CallSetup s(this, aRv, "SEChannel.session", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
3543 0 : JSContext* cx = s.GetContext();
3544 0 : if (!cx) {
3545 0 : MOZ_ASSERT(aRv.Failed());
3546 0 : return nullptr;
3547 : }
3548 0 : JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
3549 :
3550 0 : JS::Rooted<JSObject *> callback(cx, mCallback);
3551 0 : SEChannelAtoms* atomsCache = GetAtomCache<SEChannelAtoms>(cx);
3552 0 : if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
3553 0 : !JS_GetPropertyById(cx, callback, atomsCache->session_id, &rval)) {
3554 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
3555 0 : return nullptr;
3556 : }
3557 0 : RefPtr<mozilla::dom::SESession> rvalDecl;
3558 0 : if (rval.isObject()) {
3559 : static_assert(IsRefcounted<mozilla::dom::SESession>::value, "We can only store refcounted classes.");{
3560 0 : nsresult rv = UnwrapObject<prototypes::id::SESession, mozilla::dom::SESession>(rval, rvalDecl);
3561 0 : if (NS_FAILED(rv)) {
3562 : // Be careful to not wrap random DOM objects here, even if
3563 : // they're wrapped in opaque security wrappers for some reason.
3564 : // XXXbz Wish we could check for a JS-implemented object
3565 : // that already has a content reflection...
3566 0 : if (!IsDOMObject(js::UncheckedUnwrap(&rval.toObject()))) {
3567 0 : nsCOMPtr<nsIGlobalObject> contentGlobal;
3568 0 : JS::Handle<JSObject*> callback = CallbackOrNull();
3569 0 : if (!callback ||
3570 0 : !GetContentGlobalForJSImplementedObject(cx, callback, getter_AddRefs(contentGlobal))) {
3571 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
3572 0 : return nullptr;
3573 : }
3574 0 : JS::Rooted<JSObject*> jsImplSourceObj(cx, &rval.toObject());
3575 0 : rvalDecl = new mozilla::dom::SESession(jsImplSourceObj, contentGlobal);
3576 : } else {
3577 0 : ThrowErrorMessage(cx, MSG_DOES_NOT_IMPLEMENT_INTERFACE, "Return value of SEChannel.session", "SESession");
3578 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
3579 0 : return nullptr;
3580 : }
3581 : }
3582 : }
3583 : } else {
3584 0 : ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Return value of SEChannel.session");
3585 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
3586 0 : return nullptr;
3587 : }
3588 0 : return rvalDecl.forget();
3589 : }
3590 :
3591 : void
3592 0 : SEChannelJSImpl::GetOpenResponse(JS::MutableHandle<JSObject*> aRetVal, ErrorResult& aRv, JSCompartment* aCompartment)
3593 : {
3594 0 : CallSetup s(this, aRv, "SEChannel.openResponse", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
3595 0 : JSContext* cx = s.GetContext();
3596 0 : if (!cx) {
3597 0 : MOZ_ASSERT(aRv.Failed());
3598 0 : return;
3599 : }
3600 0 : JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
3601 :
3602 0 : JS::Rooted<JSObject *> callback(cx, mCallback);
3603 0 : SEChannelAtoms* atomsCache = GetAtomCache<SEChannelAtoms>(cx);
3604 0 : if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
3605 0 : !JS_GetPropertyById(cx, callback, atomsCache->openResponse_id, &rval)) {
3606 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
3607 0 : return;
3608 : }
3609 0 : RootedTypedArray<Nullable<Uint8Array>> rvalDecl(cx);
3610 0 : if (rval.isObject()) {
3611 0 : if (!rvalDecl.SetValue().Init(&rval.toObject())) {
3612 0 : ThrowErrorMessage(cx, MSG_DOES_NOT_IMPLEMENT_INTERFACE, "Return value of SEChannel.openResponse", "Uint8ArrayOrNull");
3613 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
3614 0 : return;
3615 : }
3616 0 : } else if (rval.isNullOrUndefined()) {
3617 0 : rvalDecl.SetNull();
3618 : } else {
3619 0 : ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Return value of SEChannel.openResponse");
3620 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
3621 0 : return;
3622 : }
3623 0 : aRetVal.set(rvalDecl.IsNull() ? nullptr : rvalDecl.Value().Obj());
3624 : }
3625 :
3626 : bool
3627 0 : SEChannelJSImpl::GetIsClosed(ErrorResult& aRv, JSCompartment* aCompartment)
3628 : {
3629 0 : CallSetup s(this, aRv, "SEChannel.isClosed", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
3630 0 : JSContext* cx = s.GetContext();
3631 0 : if (!cx) {
3632 0 : MOZ_ASSERT(aRv.Failed());
3633 0 : return bool(0);
3634 : }
3635 0 : JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
3636 :
3637 0 : JS::Rooted<JSObject *> callback(cx, mCallback);
3638 0 : SEChannelAtoms* atomsCache = GetAtomCache<SEChannelAtoms>(cx);
3639 0 : if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
3640 0 : !JS_GetPropertyById(cx, callback, atomsCache->isClosed_id, &rval)) {
3641 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
3642 0 : return bool(0);
3643 : }
3644 : bool rvalDecl;
3645 0 : if (!ValueToPrimitive<bool, eDefault>(cx, rval, &rvalDecl)) {
3646 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
3647 0 : return bool(0);
3648 : }
3649 0 : return rvalDecl;
3650 : }
3651 :
3652 : SEChannelType
3653 0 : SEChannelJSImpl::GetType(ErrorResult& aRv, JSCompartment* aCompartment)
3654 : {
3655 0 : CallSetup s(this, aRv, "SEChannel.type", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
3656 0 : JSContext* cx = s.GetContext();
3657 0 : if (!cx) {
3658 0 : MOZ_ASSERT(aRv.Failed());
3659 0 : return SEChannelType(0);
3660 : }
3661 0 : JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
3662 :
3663 0 : JS::Rooted<JSObject *> callback(cx, mCallback);
3664 0 : SEChannelAtoms* atomsCache = GetAtomCache<SEChannelAtoms>(cx);
3665 0 : if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
3666 0 : !JS_GetPropertyById(cx, callback, atomsCache->type_id, &rval)) {
3667 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
3668 0 : return SEChannelType(0);
3669 : }
3670 : SEChannelType rvalDecl;
3671 : {
3672 : int index;
3673 0 : if (!FindEnumStringIndex<true>(cx, rval, SEChannelTypeValues::strings, "SEChannelType", "Return value of SEChannel.type", &index)) {
3674 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
3675 0 : return SEChannelType(0);
3676 : }
3677 0 : MOZ_ASSERT(index >= 0);
3678 0 : rvalDecl = static_cast<SEChannelType>(index);
3679 : }
3680 0 : return rvalDecl;
3681 : }
3682 :
3683 :
3684 : NS_IMPL_CYCLE_COLLECTION_CLASS(SEChannel)
3685 0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(SEChannel)
3686 0 : NS_IMPL_CYCLE_COLLECTION_UNLINK(mImpl)
3687 0 : NS_IMPL_CYCLE_COLLECTION_UNLINK(mParent)
3688 0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
3689 0 : tmp->ClearWeakReferences();
3690 0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_END
3691 0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(SEChannel)
3692 0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mImpl)
3693 0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mParent)
3694 0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
3695 0 : NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(SEChannel)
3696 0 : NS_IMPL_CYCLE_COLLECTING_ADDREF(SEChannel)
3697 0 : NS_IMPL_CYCLE_COLLECTING_RELEASE(SEChannel)
3698 0 : NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(SEChannel)
3699 0 : NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
3700 0 : NS_INTERFACE_MAP_ENTRY(nsISupports)
3701 0 : NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
3702 0 : NS_INTERFACE_MAP_END
3703 :
3704 0 : SEChannel::SEChannel(JS::Handle<JSObject*> aJSImplObject, nsIGlobalObject* aParent)
3705 0 : : mImpl(new SEChannelJSImpl(nullptr, aJSImplObject, /* aIncumbentGlobal = */ nullptr)),
3706 0 : mParent(aParent)
3707 : {
3708 0 : }
3709 :
3710 :
3711 0 : SEChannel::~SEChannel()
3712 : {
3713 0 : }
3714 :
3715 : nsISupports*
3716 0 : SEChannel::GetParentObject() const
3717 : {
3718 0 : return mParent;
3719 : }
3720 :
3721 : JSObject*
3722 0 : SEChannel::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
3723 : {
3724 0 : JS::Rooted<JSObject*> obj(aCx, SEChannelBinding::Wrap(aCx, this, aGivenProto));
3725 0 : if (!obj) {
3726 0 : return nullptr;
3727 : }
3728 :
3729 : // Now define it on our chrome object
3730 0 : JSAutoCompartment ac(aCx, mImpl->CallbackOrNull());
3731 0 : if (!JS_WrapObject(aCx, &obj)) {
3732 0 : return nullptr;
3733 : }
3734 0 : if (!JS_DefineProperty(aCx, mImpl->CallbackOrNull(), "__DOM_IMPL__", obj, 0)) {
3735 0 : return nullptr;
3736 : }
3737 0 : return obj;
3738 : }
3739 :
3740 : // Return a raw pointer here to avoid refcounting, but make sure it's safe (the object should be kept alive by the callee).
3741 : already_AddRefed<SESession>
3742 0 : SEChannel::GetSession(ErrorResult& aRv, JSCompartment* aCompartment) const
3743 : {
3744 0 : return mImpl->GetSession(aRv, aCompartment);
3745 : }
3746 :
3747 : void
3748 0 : SEChannel::GetOpenResponse(JS::MutableHandle<JSObject*> aRetVal, ErrorResult& aRv, JSCompartment* aCompartment) const
3749 : {
3750 0 : return mImpl->GetOpenResponse(aRetVal, aRv, aCompartment);
3751 : }
3752 :
3753 : bool
3754 0 : SEChannel::GetIsClosed(ErrorResult& aRv, JSCompartment* aCompartment) const
3755 : {
3756 0 : return mImpl->GetIsClosed(aRv, aCompartment);
3757 : }
3758 :
3759 : SEChannelType
3760 0 : SEChannel::GetType(ErrorResult& aRv, JSCompartment* aCompartment) const
3761 : {
3762 0 : return mImpl->GetType(aRv, aCompartment);
3763 : }
3764 :
3765 : // Return a raw pointer here to avoid refcounting, but make sure it's safe (the object should be kept alive by the callee).
3766 : already_AddRefed<Promise>
3767 0 : SEChannel::Transmit(const SECommand& command, ErrorResult& aRv, JSCompartment* aCompartment)
3768 : {
3769 0 : return mImpl->Transmit(command, aRv, aCompartment);
3770 : }
3771 :
3772 : // Return a raw pointer here to avoid refcounting, but make sure it's safe (the object should be kept alive by the callee).
3773 : already_AddRefed<Promise>
3774 0 : SEChannel::Close(ErrorResult& aRv, JSCompartment* aCompartment)
3775 : {
3776 0 : return mImpl->Close(aRv, aCompartment);
3777 : }
3778 :
3779 : bool
3780 0 : SEChannel::_Create(JSContext* cx, unsigned argc, JS::Value* vp)
3781 : {
3782 0 : JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
3783 0 : if (args.length() < 2) {
3784 0 : return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "SEChannel._create");
3785 : }
3786 0 : if (!args[0].isObject()) {
3787 0 : return ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 1 of SEChannel._create");
3788 : }
3789 0 : if (!args[1].isObject()) {
3790 0 : return ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 2 of SEChannel._create");
3791 : }
3792 :
3793 : // GlobalObject will go through wrappers as needed for us, and
3794 : // is simpler than the right UnwrapArg incantation.
3795 0 : GlobalObject global(cx, &args[0].toObject());
3796 0 : if (global.Failed()) {
3797 0 : return false;
3798 : }
3799 0 : nsCOMPtr<nsIGlobalObject> globalHolder = do_QueryInterface(global.GetAsSupports());
3800 0 : MOZ_ASSERT(globalHolder);
3801 0 : JS::Rooted<JSObject*> arg(cx, &args[1].toObject());
3802 0 : RefPtr<SEChannel> impl = new SEChannel(arg, globalHolder);
3803 0 : MOZ_ASSERT(js::IsObjectInContextCompartment(arg, cx));
3804 0 : return GetOrCreateDOMReflector(cx, impl, args.rval());
3805 : }
3806 :
3807 :
3808 : already_AddRefed<Promise>
3809 0 : SEReaderJSImpl::OpenSession(ErrorResult& aRv, JSCompartment* aCompartment)
3810 : {
3811 0 : CallSetup s(this, aRv, "SEReader.openSession", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
3812 0 : JSContext* cx = s.GetContext();
3813 0 : if (!cx) {
3814 0 : MOZ_ASSERT(aRv.Failed());
3815 0 : return nullptr;
3816 : }
3817 0 : JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
3818 :
3819 0 : JS::Rooted<JS::Value> callable(cx);
3820 0 : SEReaderAtoms* atomsCache = GetAtomCache<SEReaderAtoms>(cx);
3821 0 : if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
3822 0 : !GetCallableProperty(cx, atomsCache->openSession_id, &callable)) {
3823 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
3824 0 : return nullptr;
3825 : }
3826 0 : JS::Rooted<JS::Value> thisValue(cx, JS::ObjectValue(*mCallback));
3827 0 : if (!JS::Call(cx, thisValue, callable,
3828 0 : JS::HandleValueArray::empty(), &rval)) {
3829 0 : aRv.NoteJSContextException(cx);
3830 0 : return nullptr;
3831 : }
3832 0 : RefPtr<Promise> rvalDecl;
3833 : { // Scope for our GlobalObject, FastErrorResult, JSAutoCompartment,
3834 : // etc.
3835 :
3836 0 : JS::Rooted<JSObject*> globalObj(cx, JS::CurrentGlobalOrNull(cx));
3837 0 : if (!rval.isObject()) {
3838 0 : aRv.ThrowTypeError<MSG_NOT_OBJECT>(NS_LITERAL_STRING("return value of SEReader.openSession"));
3839 0 : return nullptr;
3840 : }
3841 0 : JSObject* unwrappedVal = js::CheckedUnwrap(&rval.toObject());
3842 0 : if (!unwrappedVal) {
3843 : // A slight lie, but not much of one, for a dead object wrapper.
3844 0 : aRv.ThrowTypeError<MSG_NOT_OBJECT>(NS_LITERAL_STRING("return value of SEReader.openSession"));
3845 0 : return nullptr;
3846 : }
3847 0 : globalObj = js::GetGlobalForObjectCrossCompartment(unwrappedVal);
3848 0 : JSAutoCompartment ac(cx, globalObj);
3849 0 : GlobalObject promiseGlobal(cx, globalObj);
3850 0 : if (promiseGlobal.Failed()) {
3851 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
3852 0 : return nullptr;
3853 : }
3854 :
3855 0 : JS::Rooted<JS::Value> valueToResolve(cx, rval);
3856 0 : if (!JS_WrapValue(cx, &valueToResolve)) {
3857 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
3858 0 : return nullptr;
3859 : }
3860 0 : binding_detail::FastErrorResult promiseRv;
3861 : nsCOMPtr<nsIGlobalObject> global =
3862 0 : do_QueryInterface(promiseGlobal.GetAsSupports());
3863 0 : if (!global) {
3864 0 : promiseRv.ThrowWithCustomCleanup(NS_ERROR_UNEXPECTED);
3865 0 : MOZ_ALWAYS_TRUE(promiseRv.MaybeSetPendingException(cx));
3866 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
3867 0 : return nullptr;
3868 : }
3869 0 : rvalDecl = Promise::Resolve(global, cx, valueToResolve,
3870 0 : promiseRv);
3871 0 : if (promiseRv.MaybeSetPendingException(cx)) {
3872 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
3873 0 : return nullptr;
3874 : }
3875 : }
3876 0 : return rvalDecl.forget();
3877 : }
3878 :
3879 : already_AddRefed<Promise>
3880 0 : SEReaderJSImpl::CloseAll(ErrorResult& aRv, JSCompartment* aCompartment)
3881 : {
3882 0 : CallSetup s(this, aRv, "SEReader.closeAll", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
3883 0 : JSContext* cx = s.GetContext();
3884 0 : if (!cx) {
3885 0 : MOZ_ASSERT(aRv.Failed());
3886 0 : return nullptr;
3887 : }
3888 0 : JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
3889 :
3890 0 : JS::Rooted<JS::Value> callable(cx);
3891 0 : SEReaderAtoms* atomsCache = GetAtomCache<SEReaderAtoms>(cx);
3892 0 : if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
3893 0 : !GetCallableProperty(cx, atomsCache->closeAll_id, &callable)) {
3894 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
3895 0 : return nullptr;
3896 : }
3897 0 : JS::Rooted<JS::Value> thisValue(cx, JS::ObjectValue(*mCallback));
3898 0 : if (!JS::Call(cx, thisValue, callable,
3899 0 : JS::HandleValueArray::empty(), &rval)) {
3900 0 : aRv.NoteJSContextException(cx);
3901 0 : return nullptr;
3902 : }
3903 0 : RefPtr<Promise> rvalDecl;
3904 : { // Scope for our GlobalObject, FastErrorResult, JSAutoCompartment,
3905 : // etc.
3906 :
3907 0 : JS::Rooted<JSObject*> globalObj(cx, JS::CurrentGlobalOrNull(cx));
3908 0 : if (!rval.isObject()) {
3909 0 : aRv.ThrowTypeError<MSG_NOT_OBJECT>(NS_LITERAL_STRING("return value of SEReader.closeAll"));
3910 0 : return nullptr;
3911 : }
3912 0 : JSObject* unwrappedVal = js::CheckedUnwrap(&rval.toObject());
3913 0 : if (!unwrappedVal) {
3914 : // A slight lie, but not much of one, for a dead object wrapper.
3915 0 : aRv.ThrowTypeError<MSG_NOT_OBJECT>(NS_LITERAL_STRING("return value of SEReader.closeAll"));
3916 0 : return nullptr;
3917 : }
3918 0 : globalObj = js::GetGlobalForObjectCrossCompartment(unwrappedVal);
3919 0 : JSAutoCompartment ac(cx, globalObj);
3920 0 : GlobalObject promiseGlobal(cx, globalObj);
3921 0 : if (promiseGlobal.Failed()) {
3922 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
3923 0 : return nullptr;
3924 : }
3925 :
3926 0 : JS::Rooted<JS::Value> valueToResolve(cx, rval);
3927 0 : if (!JS_WrapValue(cx, &valueToResolve)) {
3928 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
3929 0 : return nullptr;
3930 : }
3931 0 : binding_detail::FastErrorResult promiseRv;
3932 : nsCOMPtr<nsIGlobalObject> global =
3933 0 : do_QueryInterface(promiseGlobal.GetAsSupports());
3934 0 : if (!global) {
3935 0 : promiseRv.ThrowWithCustomCleanup(NS_ERROR_UNEXPECTED);
3936 0 : MOZ_ALWAYS_TRUE(promiseRv.MaybeSetPendingException(cx));
3937 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
3938 0 : return nullptr;
3939 : }
3940 0 : rvalDecl = Promise::Resolve(global, cx, valueToResolve,
3941 0 : promiseRv);
3942 0 : if (promiseRv.MaybeSetPendingException(cx)) {
3943 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
3944 0 : return nullptr;
3945 : }
3946 : }
3947 0 : return rvalDecl.forget();
3948 : }
3949 :
3950 : bool
3951 0 : SEReaderJSImpl::InitIds(JSContext* cx, SEReaderAtoms* atomsCache)
3952 : {
3953 0 : MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
3954 :
3955 : // Initialize these in reverse order so that any failure leaves the first one
3956 : // uninitialized.
3957 0 : if (!atomsCache->closeAll_id.init(cx, "closeAll") ||
3958 0 : !atomsCache->openSession_id.init(cx, "openSession") ||
3959 0 : !atomsCache->type_id.init(cx, "type") ||
3960 0 : !atomsCache->isSEPresent_id.init(cx, "isSEPresent")) {
3961 0 : return false;
3962 : }
3963 0 : return true;
3964 : }
3965 :
3966 :
3967 : bool
3968 0 : SEReaderJSImpl::GetIsSEPresent(ErrorResult& aRv, JSCompartment* aCompartment)
3969 : {
3970 0 : CallSetup s(this, aRv, "SEReader.isSEPresent", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
3971 0 : JSContext* cx = s.GetContext();
3972 0 : if (!cx) {
3973 0 : MOZ_ASSERT(aRv.Failed());
3974 0 : return bool(0);
3975 : }
3976 0 : JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
3977 :
3978 0 : JS::Rooted<JSObject *> callback(cx, mCallback);
3979 0 : SEReaderAtoms* atomsCache = GetAtomCache<SEReaderAtoms>(cx);
3980 0 : if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
3981 0 : !JS_GetPropertyById(cx, callback, atomsCache->isSEPresent_id, &rval)) {
3982 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
3983 0 : return bool(0);
3984 : }
3985 : bool rvalDecl;
3986 0 : if (!ValueToPrimitive<bool, eDefault>(cx, rval, &rvalDecl)) {
3987 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
3988 0 : return bool(0);
3989 : }
3990 0 : return rvalDecl;
3991 : }
3992 :
3993 : SEType
3994 0 : SEReaderJSImpl::GetType(ErrorResult& aRv, JSCompartment* aCompartment)
3995 : {
3996 0 : CallSetup s(this, aRv, "SEReader.type", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
3997 0 : JSContext* cx = s.GetContext();
3998 0 : if (!cx) {
3999 0 : MOZ_ASSERT(aRv.Failed());
4000 0 : return SEType(0);
4001 : }
4002 0 : JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
4003 :
4004 0 : JS::Rooted<JSObject *> callback(cx, mCallback);
4005 0 : SEReaderAtoms* atomsCache = GetAtomCache<SEReaderAtoms>(cx);
4006 0 : if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
4007 0 : !JS_GetPropertyById(cx, callback, atomsCache->type_id, &rval)) {
4008 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
4009 0 : return SEType(0);
4010 : }
4011 : SEType rvalDecl;
4012 : {
4013 : int index;
4014 0 : if (!FindEnumStringIndex<true>(cx, rval, SETypeValues::strings, "SEType", "Return value of SEReader.type", &index)) {
4015 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
4016 0 : return SEType(0);
4017 : }
4018 0 : MOZ_ASSERT(index >= 0);
4019 0 : rvalDecl = static_cast<SEType>(index);
4020 : }
4021 0 : return rvalDecl;
4022 : }
4023 :
4024 :
4025 : NS_IMPL_CYCLE_COLLECTION_CLASS(SEReader)
4026 0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(SEReader)
4027 0 : NS_IMPL_CYCLE_COLLECTION_UNLINK(mImpl)
4028 0 : NS_IMPL_CYCLE_COLLECTION_UNLINK(mParent)
4029 0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
4030 0 : tmp->ClearWeakReferences();
4031 0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_END
4032 0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(SEReader)
4033 0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mImpl)
4034 0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mParent)
4035 0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
4036 0 : NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(SEReader)
4037 0 : NS_IMPL_CYCLE_COLLECTING_ADDREF(SEReader)
4038 0 : NS_IMPL_CYCLE_COLLECTING_RELEASE(SEReader)
4039 0 : NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(SEReader)
4040 0 : NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
4041 0 : NS_INTERFACE_MAP_ENTRY(nsISupports)
4042 0 : NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
4043 0 : NS_INTERFACE_MAP_END
4044 :
4045 0 : SEReader::SEReader(JS::Handle<JSObject*> aJSImplObject, nsIGlobalObject* aParent)
4046 0 : : mImpl(new SEReaderJSImpl(nullptr, aJSImplObject, /* aIncumbentGlobal = */ nullptr)),
4047 0 : mParent(aParent)
4048 : {
4049 0 : }
4050 :
4051 :
4052 0 : SEReader::~SEReader()
4053 : {
4054 0 : }
4055 :
4056 : nsISupports*
4057 0 : SEReader::GetParentObject() const
4058 : {
4059 0 : return mParent;
4060 : }
4061 :
4062 : JSObject*
4063 0 : SEReader::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
4064 : {
4065 0 : JS::Rooted<JSObject*> obj(aCx, SEReaderBinding::Wrap(aCx, this, aGivenProto));
4066 0 : if (!obj) {
4067 0 : return nullptr;
4068 : }
4069 :
4070 : // Now define it on our chrome object
4071 0 : JSAutoCompartment ac(aCx, mImpl->CallbackOrNull());
4072 0 : if (!JS_WrapObject(aCx, &obj)) {
4073 0 : return nullptr;
4074 : }
4075 0 : if (!JS_DefineProperty(aCx, mImpl->CallbackOrNull(), "__DOM_IMPL__", obj, 0)) {
4076 0 : return nullptr;
4077 : }
4078 0 : return obj;
4079 : }
4080 :
4081 : bool
4082 0 : SEReader::GetIsSEPresent(ErrorResult& aRv, JSCompartment* aCompartment) const
4083 : {
4084 0 : return mImpl->GetIsSEPresent(aRv, aCompartment);
4085 : }
4086 :
4087 : SEType
4088 0 : SEReader::GetType(ErrorResult& aRv, JSCompartment* aCompartment) const
4089 : {
4090 0 : return mImpl->GetType(aRv, aCompartment);
4091 : }
4092 :
4093 : // Return a raw pointer here to avoid refcounting, but make sure it's safe (the object should be kept alive by the callee).
4094 : already_AddRefed<Promise>
4095 0 : SEReader::OpenSession(ErrorResult& aRv, JSCompartment* aCompartment)
4096 : {
4097 0 : return mImpl->OpenSession(aRv, aCompartment);
4098 : }
4099 :
4100 : // Return a raw pointer here to avoid refcounting, but make sure it's safe (the object should be kept alive by the callee).
4101 : already_AddRefed<Promise>
4102 0 : SEReader::CloseAll(ErrorResult& aRv, JSCompartment* aCompartment)
4103 : {
4104 0 : return mImpl->CloseAll(aRv, aCompartment);
4105 : }
4106 :
4107 : bool
4108 0 : SEReader::_Create(JSContext* cx, unsigned argc, JS::Value* vp)
4109 : {
4110 0 : JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
4111 0 : if (args.length() < 2) {
4112 0 : return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "SEReader._create");
4113 : }
4114 0 : if (!args[0].isObject()) {
4115 0 : return ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 1 of SEReader._create");
4116 : }
4117 0 : if (!args[1].isObject()) {
4118 0 : return ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 2 of SEReader._create");
4119 : }
4120 :
4121 : // GlobalObject will go through wrappers as needed for us, and
4122 : // is simpler than the right UnwrapArg incantation.
4123 0 : GlobalObject global(cx, &args[0].toObject());
4124 0 : if (global.Failed()) {
4125 0 : return false;
4126 : }
4127 0 : nsCOMPtr<nsIGlobalObject> globalHolder = do_QueryInterface(global.GetAsSupports());
4128 0 : MOZ_ASSERT(globalHolder);
4129 0 : JS::Rooted<JSObject*> arg(cx, &args[1].toObject());
4130 0 : RefPtr<SEReader> impl = new SEReader(arg, globalHolder);
4131 0 : MOZ_ASSERT(js::IsObjectInContextCompartment(arg, cx));
4132 0 : return GetOrCreateDOMReflector(cx, impl, args.rval());
4133 : }
4134 :
4135 :
4136 : bool
4137 0 : SEResponseJSImpl::InitIds(JSContext* cx, SEResponseAtoms* atomsCache)
4138 : {
4139 0 : MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
4140 :
4141 : // Initialize these in reverse order so that any failure leaves the first one
4142 : // uninitialized.
4143 0 : if (!atomsCache->data_id.init(cx, "data") ||
4144 0 : !atomsCache->sw2_id.init(cx, "sw2") ||
4145 0 : !atomsCache->sw1_id.init(cx, "sw1") ||
4146 0 : !atomsCache->channel_id.init(cx, "channel")) {
4147 0 : return false;
4148 : }
4149 0 : return true;
4150 : }
4151 :
4152 :
4153 : already_AddRefed<SEChannel>
4154 0 : SEResponseJSImpl::GetChannel(ErrorResult& aRv, JSCompartment* aCompartment)
4155 : {
4156 0 : CallSetup s(this, aRv, "SEResponse.channel", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
4157 0 : JSContext* cx = s.GetContext();
4158 0 : if (!cx) {
4159 0 : MOZ_ASSERT(aRv.Failed());
4160 0 : return nullptr;
4161 : }
4162 0 : JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
4163 :
4164 0 : JS::Rooted<JSObject *> callback(cx, mCallback);
4165 0 : SEResponseAtoms* atomsCache = GetAtomCache<SEResponseAtoms>(cx);
4166 0 : if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
4167 0 : !JS_GetPropertyById(cx, callback, atomsCache->channel_id, &rval)) {
4168 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
4169 0 : return nullptr;
4170 : }
4171 0 : RefPtr<mozilla::dom::SEChannel> rvalDecl;
4172 0 : if (rval.isObject()) {
4173 : static_assert(IsRefcounted<mozilla::dom::SEChannel>::value, "We can only store refcounted classes.");{
4174 0 : nsresult rv = UnwrapObject<prototypes::id::SEChannel, mozilla::dom::SEChannel>(rval, rvalDecl);
4175 0 : if (NS_FAILED(rv)) {
4176 : // Be careful to not wrap random DOM objects here, even if
4177 : // they're wrapped in opaque security wrappers for some reason.
4178 : // XXXbz Wish we could check for a JS-implemented object
4179 : // that already has a content reflection...
4180 0 : if (!IsDOMObject(js::UncheckedUnwrap(&rval.toObject()))) {
4181 0 : nsCOMPtr<nsIGlobalObject> contentGlobal;
4182 0 : JS::Handle<JSObject*> callback = CallbackOrNull();
4183 0 : if (!callback ||
4184 0 : !GetContentGlobalForJSImplementedObject(cx, callback, getter_AddRefs(contentGlobal))) {
4185 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
4186 0 : return nullptr;
4187 : }
4188 0 : JS::Rooted<JSObject*> jsImplSourceObj(cx, &rval.toObject());
4189 0 : rvalDecl = new mozilla::dom::SEChannel(jsImplSourceObj, contentGlobal);
4190 : } else {
4191 0 : ThrowErrorMessage(cx, MSG_DOES_NOT_IMPLEMENT_INTERFACE, "Return value of SEResponse.channel", "SEChannel");
4192 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
4193 0 : return nullptr;
4194 : }
4195 : }
4196 : }
4197 : } else {
4198 0 : ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Return value of SEResponse.channel");
4199 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
4200 0 : return nullptr;
4201 : }
4202 0 : return rvalDecl.forget();
4203 : }
4204 :
4205 : uint8_t
4206 0 : SEResponseJSImpl::GetSw1(ErrorResult& aRv, JSCompartment* aCompartment)
4207 : {
4208 0 : CallSetup s(this, aRv, "SEResponse.sw1", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
4209 0 : JSContext* cx = s.GetContext();
4210 0 : if (!cx) {
4211 0 : MOZ_ASSERT(aRv.Failed());
4212 0 : return uint8_t(0);
4213 : }
4214 0 : JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
4215 :
4216 0 : JS::Rooted<JSObject *> callback(cx, mCallback);
4217 0 : SEResponseAtoms* atomsCache = GetAtomCache<SEResponseAtoms>(cx);
4218 0 : if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
4219 0 : !JS_GetPropertyById(cx, callback, atomsCache->sw1_id, &rval)) {
4220 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
4221 0 : return uint8_t(0);
4222 : }
4223 : uint8_t rvalDecl;
4224 0 : if (!ValueToPrimitive<uint8_t, eDefault>(cx, rval, &rvalDecl)) {
4225 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
4226 0 : return uint8_t(0);
4227 : }
4228 0 : return rvalDecl;
4229 : }
4230 :
4231 : uint8_t
4232 0 : SEResponseJSImpl::GetSw2(ErrorResult& aRv, JSCompartment* aCompartment)
4233 : {
4234 0 : CallSetup s(this, aRv, "SEResponse.sw2", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
4235 0 : JSContext* cx = s.GetContext();
4236 0 : if (!cx) {
4237 0 : MOZ_ASSERT(aRv.Failed());
4238 0 : return uint8_t(0);
4239 : }
4240 0 : JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
4241 :
4242 0 : JS::Rooted<JSObject *> callback(cx, mCallback);
4243 0 : SEResponseAtoms* atomsCache = GetAtomCache<SEResponseAtoms>(cx);
4244 0 : if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
4245 0 : !JS_GetPropertyById(cx, callback, atomsCache->sw2_id, &rval)) {
4246 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
4247 0 : return uint8_t(0);
4248 : }
4249 : uint8_t rvalDecl;
4250 0 : if (!ValueToPrimitive<uint8_t, eDefault>(cx, rval, &rvalDecl)) {
4251 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
4252 0 : return uint8_t(0);
4253 : }
4254 0 : return rvalDecl;
4255 : }
4256 :
4257 : void
4258 0 : SEResponseJSImpl::GetData(Nullable<nsTArray<uint8_t>>& aRetVal, ErrorResult& aRv, JSCompartment* aCompartment)
4259 : {
4260 0 : CallSetup s(this, aRv, "SEResponse.data", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
4261 0 : JSContext* cx = s.GetContext();
4262 0 : if (!cx) {
4263 0 : MOZ_ASSERT(aRv.Failed());
4264 0 : return;
4265 : }
4266 0 : JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
4267 :
4268 0 : JS::Rooted<JSObject *> callback(cx, mCallback);
4269 0 : SEResponseAtoms* atomsCache = GetAtomCache<SEResponseAtoms>(cx);
4270 0 : if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
4271 0 : !JS_GetPropertyById(cx, callback, atomsCache->data_id, &rval)) {
4272 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
4273 0 : return;
4274 : }
4275 0 : Nullable<Sequence<uint8_t>> rvalDecl;
4276 0 : if (rval.isObject()) {
4277 0 : JS::ForOfIterator iter(cx);
4278 0 : if (!iter.init(rval, JS::ForOfIterator::AllowNonIterable)) {
4279 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
4280 0 : return;
4281 : }
4282 0 : if (!iter.valueIsIterable()) {
4283 0 : ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "Return value of SEResponse.data");
4284 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
4285 0 : return;
4286 : }
4287 0 : Sequence<uint8_t> &arr = rvalDecl.SetValue();
4288 0 : JS::Rooted<JS::Value> temp(cx);
4289 : while (true) {
4290 : bool done;
4291 0 : if (!iter.next(&temp, &done)) {
4292 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
4293 0 : return;
4294 : }
4295 0 : if (done) {
4296 0 : break;
4297 : }
4298 0 : uint8_t* slotPtr = arr.AppendElement(mozilla::fallible);
4299 0 : if (!slotPtr) {
4300 0 : JS_ReportOutOfMemory(cx);
4301 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
4302 0 : return;
4303 : }
4304 0 : uint8_t& slot = *slotPtr;
4305 0 : if (!ValueToPrimitive<uint8_t, eDefault>(cx, temp, &slot)) {
4306 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
4307 0 : return;
4308 : }
4309 0 : }
4310 0 : } else if (rval.isNullOrUndefined()) {
4311 0 : rvalDecl.SetNull();
4312 : } else {
4313 0 : ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "Return value of SEResponse.data");
4314 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
4315 0 : return;
4316 : }
4317 0 : if (rvalDecl.IsNull()) {
4318 0 : aRetVal.SetNull();
4319 : } else {
4320 0 : aRetVal.SetValue().SwapElements(rvalDecl.Value());
4321 : }
4322 : }
4323 :
4324 :
4325 : NS_IMPL_CYCLE_COLLECTION_CLASS(SEResponse)
4326 0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(SEResponse)
4327 0 : NS_IMPL_CYCLE_COLLECTION_UNLINK(mImpl)
4328 0 : NS_IMPL_CYCLE_COLLECTION_UNLINK(mParent)
4329 0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
4330 0 : tmp->ClearWeakReferences();
4331 0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_END
4332 0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(SEResponse)
4333 0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mImpl)
4334 0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mParent)
4335 0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
4336 0 : NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(SEResponse)
4337 0 : NS_IMPL_CYCLE_COLLECTING_ADDREF(SEResponse)
4338 0 : NS_IMPL_CYCLE_COLLECTING_RELEASE(SEResponse)
4339 0 : NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(SEResponse)
4340 0 : NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
4341 0 : NS_INTERFACE_MAP_ENTRY(nsISupports)
4342 0 : NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
4343 0 : NS_INTERFACE_MAP_END
4344 :
4345 0 : SEResponse::SEResponse(JS::Handle<JSObject*> aJSImplObject, nsIGlobalObject* aParent)
4346 0 : : mImpl(new SEResponseJSImpl(nullptr, aJSImplObject, /* aIncumbentGlobal = */ nullptr)),
4347 0 : mParent(aParent)
4348 : {
4349 0 : }
4350 :
4351 :
4352 0 : SEResponse::~SEResponse()
4353 : {
4354 0 : }
4355 :
4356 : nsISupports*
4357 0 : SEResponse::GetParentObject() const
4358 : {
4359 0 : return mParent;
4360 : }
4361 :
4362 : JSObject*
4363 0 : SEResponse::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
4364 : {
4365 0 : JS::Rooted<JSObject*> obj(aCx, SEResponseBinding::Wrap(aCx, this, aGivenProto));
4366 0 : if (!obj) {
4367 0 : return nullptr;
4368 : }
4369 :
4370 : // Now define it on our chrome object
4371 0 : JSAutoCompartment ac(aCx, mImpl->CallbackOrNull());
4372 0 : if (!JS_WrapObject(aCx, &obj)) {
4373 0 : return nullptr;
4374 : }
4375 0 : if (!JS_DefineProperty(aCx, mImpl->CallbackOrNull(), "__DOM_IMPL__", obj, 0)) {
4376 0 : return nullptr;
4377 : }
4378 0 : return obj;
4379 : }
4380 :
4381 : // Return a raw pointer here to avoid refcounting, but make sure it's safe (the object should be kept alive by the callee).
4382 : already_AddRefed<SEChannel>
4383 0 : SEResponse::GetChannel(ErrorResult& aRv, JSCompartment* aCompartment) const
4384 : {
4385 0 : return mImpl->GetChannel(aRv, aCompartment);
4386 : }
4387 :
4388 : uint8_t
4389 0 : SEResponse::GetSw1(ErrorResult& aRv, JSCompartment* aCompartment) const
4390 : {
4391 0 : return mImpl->GetSw1(aRv, aCompartment);
4392 : }
4393 :
4394 : uint8_t
4395 0 : SEResponse::GetSw2(ErrorResult& aRv, JSCompartment* aCompartment) const
4396 : {
4397 0 : return mImpl->GetSw2(aRv, aCompartment);
4398 : }
4399 :
4400 : void
4401 0 : SEResponse::GetData(Nullable<nsTArray<uint8_t>>& aRetVal, ErrorResult& aRv, JSCompartment* aCompartment) const
4402 : {
4403 0 : return mImpl->GetData(aRetVal, aRv, aCompartment);
4404 : }
4405 :
4406 : bool
4407 0 : SEResponse::_Create(JSContext* cx, unsigned argc, JS::Value* vp)
4408 : {
4409 0 : JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
4410 0 : if (args.length() < 2) {
4411 0 : return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "SEResponse._create");
4412 : }
4413 0 : if (!args[0].isObject()) {
4414 0 : return ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 1 of SEResponse._create");
4415 : }
4416 0 : if (!args[1].isObject()) {
4417 0 : return ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 2 of SEResponse._create");
4418 : }
4419 :
4420 : // GlobalObject will go through wrappers as needed for us, and
4421 : // is simpler than the right UnwrapArg incantation.
4422 0 : GlobalObject global(cx, &args[0].toObject());
4423 0 : if (global.Failed()) {
4424 0 : return false;
4425 : }
4426 0 : nsCOMPtr<nsIGlobalObject> globalHolder = do_QueryInterface(global.GetAsSupports());
4427 0 : MOZ_ASSERT(globalHolder);
4428 0 : JS::Rooted<JSObject*> arg(cx, &args[1].toObject());
4429 0 : RefPtr<SEResponse> impl = new SEResponse(arg, globalHolder);
4430 0 : MOZ_ASSERT(js::IsObjectInContextCompartment(arg, cx));
4431 0 : return GetOrCreateDOMReflector(cx, impl, args.rval());
4432 : }
4433 :
4434 :
4435 : already_AddRefed<Promise>
4436 0 : SESessionJSImpl::OpenLogicalChannel(const Nullable<Uint8Array>& aid, ErrorResult& aRv, JSCompartment* aCompartment)
4437 : {
4438 0 : CallSetup s(this, aRv, "SESession.openLogicalChannel", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
4439 0 : JSContext* cx = s.GetContext();
4440 0 : if (!cx) {
4441 0 : MOZ_ASSERT(aRv.Failed());
4442 0 : return nullptr;
4443 : }
4444 0 : JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
4445 0 : JS::AutoValueVector argv(cx);
4446 0 : if (!argv.resize(1)) {
4447 0 : aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
4448 0 : return nullptr;
4449 : }
4450 0 : unsigned argc = 1;
4451 :
4452 : do {
4453 0 : if (aid.IsNull()) {
4454 0 : argv[0].setNull();
4455 0 : break;
4456 : }
4457 0 : argv[0].setObject(*aid.Value().Obj());
4458 0 : if (!MaybeWrapNonDOMObjectValue(cx, argv[0])) {
4459 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
4460 0 : return nullptr;
4461 : }
4462 0 : break;
4463 : } while (0);
4464 :
4465 0 : JS::Rooted<JS::Value> callable(cx);
4466 0 : SESessionAtoms* atomsCache = GetAtomCache<SESessionAtoms>(cx);
4467 0 : if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
4468 0 : !GetCallableProperty(cx, atomsCache->openLogicalChannel_id, &callable)) {
4469 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
4470 0 : return nullptr;
4471 : }
4472 0 : JS::Rooted<JS::Value> thisValue(cx, JS::ObjectValue(*mCallback));
4473 0 : if (!JS::Call(cx, thisValue, callable,
4474 0 : JS::HandleValueArray::subarray(argv, 0, argc), &rval)) {
4475 0 : aRv.NoteJSContextException(cx);
4476 0 : return nullptr;
4477 : }
4478 0 : RefPtr<Promise> rvalDecl;
4479 : { // Scope for our GlobalObject, FastErrorResult, JSAutoCompartment,
4480 : // etc.
4481 :
4482 0 : JS::Rooted<JSObject*> globalObj(cx, JS::CurrentGlobalOrNull(cx));
4483 0 : if (!rval.isObject()) {
4484 0 : aRv.ThrowTypeError<MSG_NOT_OBJECT>(NS_LITERAL_STRING("return value of SESession.openLogicalChannel"));
4485 0 : return nullptr;
4486 : }
4487 0 : JSObject* unwrappedVal = js::CheckedUnwrap(&rval.toObject());
4488 0 : if (!unwrappedVal) {
4489 : // A slight lie, but not much of one, for a dead object wrapper.
4490 0 : aRv.ThrowTypeError<MSG_NOT_OBJECT>(NS_LITERAL_STRING("return value of SESession.openLogicalChannel"));
4491 0 : return nullptr;
4492 : }
4493 0 : globalObj = js::GetGlobalForObjectCrossCompartment(unwrappedVal);
4494 0 : JSAutoCompartment ac(cx, globalObj);
4495 0 : GlobalObject promiseGlobal(cx, globalObj);
4496 0 : if (promiseGlobal.Failed()) {
4497 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
4498 0 : return nullptr;
4499 : }
4500 :
4501 0 : JS::Rooted<JS::Value> valueToResolve(cx, rval);
4502 0 : if (!JS_WrapValue(cx, &valueToResolve)) {
4503 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
4504 0 : return nullptr;
4505 : }
4506 0 : binding_detail::FastErrorResult promiseRv;
4507 : nsCOMPtr<nsIGlobalObject> global =
4508 0 : do_QueryInterface(promiseGlobal.GetAsSupports());
4509 0 : if (!global) {
4510 0 : promiseRv.ThrowWithCustomCleanup(NS_ERROR_UNEXPECTED);
4511 0 : MOZ_ALWAYS_TRUE(promiseRv.MaybeSetPendingException(cx));
4512 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
4513 0 : return nullptr;
4514 : }
4515 0 : rvalDecl = Promise::Resolve(global, cx, valueToResolve,
4516 0 : promiseRv);
4517 0 : if (promiseRv.MaybeSetPendingException(cx)) {
4518 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
4519 0 : return nullptr;
4520 : }
4521 : }
4522 0 : return rvalDecl.forget();
4523 : }
4524 :
4525 : already_AddRefed<Promise>
4526 0 : SESessionJSImpl::CloseAll(ErrorResult& aRv, JSCompartment* aCompartment)
4527 : {
4528 0 : CallSetup s(this, aRv, "SESession.closeAll", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
4529 0 : JSContext* cx = s.GetContext();
4530 0 : if (!cx) {
4531 0 : MOZ_ASSERT(aRv.Failed());
4532 0 : return nullptr;
4533 : }
4534 0 : JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
4535 :
4536 0 : JS::Rooted<JS::Value> callable(cx);
4537 0 : SESessionAtoms* atomsCache = GetAtomCache<SESessionAtoms>(cx);
4538 0 : if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
4539 0 : !GetCallableProperty(cx, atomsCache->closeAll_id, &callable)) {
4540 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
4541 0 : return nullptr;
4542 : }
4543 0 : JS::Rooted<JS::Value> thisValue(cx, JS::ObjectValue(*mCallback));
4544 0 : if (!JS::Call(cx, thisValue, callable,
4545 0 : JS::HandleValueArray::empty(), &rval)) {
4546 0 : aRv.NoteJSContextException(cx);
4547 0 : return nullptr;
4548 : }
4549 0 : RefPtr<Promise> rvalDecl;
4550 : { // Scope for our GlobalObject, FastErrorResult, JSAutoCompartment,
4551 : // etc.
4552 :
4553 0 : JS::Rooted<JSObject*> globalObj(cx, JS::CurrentGlobalOrNull(cx));
4554 0 : if (!rval.isObject()) {
4555 0 : aRv.ThrowTypeError<MSG_NOT_OBJECT>(NS_LITERAL_STRING("return value of SESession.closeAll"));
4556 0 : return nullptr;
4557 : }
4558 0 : JSObject* unwrappedVal = js::CheckedUnwrap(&rval.toObject());
4559 0 : if (!unwrappedVal) {
4560 : // A slight lie, but not much of one, for a dead object wrapper.
4561 0 : aRv.ThrowTypeError<MSG_NOT_OBJECT>(NS_LITERAL_STRING("return value of SESession.closeAll"));
4562 0 : return nullptr;
4563 : }
4564 0 : globalObj = js::GetGlobalForObjectCrossCompartment(unwrappedVal);
4565 0 : JSAutoCompartment ac(cx, globalObj);
4566 0 : GlobalObject promiseGlobal(cx, globalObj);
4567 0 : if (promiseGlobal.Failed()) {
4568 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
4569 0 : return nullptr;
4570 : }
4571 :
4572 0 : JS::Rooted<JS::Value> valueToResolve(cx, rval);
4573 0 : if (!JS_WrapValue(cx, &valueToResolve)) {
4574 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
4575 0 : return nullptr;
4576 : }
4577 0 : binding_detail::FastErrorResult promiseRv;
4578 : nsCOMPtr<nsIGlobalObject> global =
4579 0 : do_QueryInterface(promiseGlobal.GetAsSupports());
4580 0 : if (!global) {
4581 0 : promiseRv.ThrowWithCustomCleanup(NS_ERROR_UNEXPECTED);
4582 0 : MOZ_ALWAYS_TRUE(promiseRv.MaybeSetPendingException(cx));
4583 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
4584 0 : return nullptr;
4585 : }
4586 0 : rvalDecl = Promise::Resolve(global, cx, valueToResolve,
4587 0 : promiseRv);
4588 0 : if (promiseRv.MaybeSetPendingException(cx)) {
4589 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
4590 0 : return nullptr;
4591 : }
4592 : }
4593 0 : return rvalDecl.forget();
4594 : }
4595 :
4596 : bool
4597 0 : SESessionJSImpl::InitIds(JSContext* cx, SESessionAtoms* atomsCache)
4598 : {
4599 0 : MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
4600 :
4601 : // Initialize these in reverse order so that any failure leaves the first one
4602 : // uninitialized.
4603 0 : if (!atomsCache->closeAll_id.init(cx, "closeAll") ||
4604 0 : !atomsCache->openLogicalChannel_id.init(cx, "openLogicalChannel") ||
4605 0 : !atomsCache->isClosed_id.init(cx, "isClosed") ||
4606 0 : !atomsCache->reader_id.init(cx, "reader")) {
4607 0 : return false;
4608 : }
4609 0 : return true;
4610 : }
4611 :
4612 :
4613 : already_AddRefed<SEReader>
4614 0 : SESessionJSImpl::GetReader(ErrorResult& aRv, JSCompartment* aCompartment)
4615 : {
4616 0 : CallSetup s(this, aRv, "SESession.reader", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
4617 0 : JSContext* cx = s.GetContext();
4618 0 : if (!cx) {
4619 0 : MOZ_ASSERT(aRv.Failed());
4620 0 : return nullptr;
4621 : }
4622 0 : JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
4623 :
4624 0 : JS::Rooted<JSObject *> callback(cx, mCallback);
4625 0 : SESessionAtoms* atomsCache = GetAtomCache<SESessionAtoms>(cx);
4626 0 : if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
4627 0 : !JS_GetPropertyById(cx, callback, atomsCache->reader_id, &rval)) {
4628 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
4629 0 : return nullptr;
4630 : }
4631 0 : RefPtr<mozilla::dom::SEReader> rvalDecl;
4632 0 : if (rval.isObject()) {
4633 : static_assert(IsRefcounted<mozilla::dom::SEReader>::value, "We can only store refcounted classes.");{
4634 0 : nsresult rv = UnwrapObject<prototypes::id::SEReader, mozilla::dom::SEReader>(rval, rvalDecl);
4635 0 : if (NS_FAILED(rv)) {
4636 : // Be careful to not wrap random DOM objects here, even if
4637 : // they're wrapped in opaque security wrappers for some reason.
4638 : // XXXbz Wish we could check for a JS-implemented object
4639 : // that already has a content reflection...
4640 0 : if (!IsDOMObject(js::UncheckedUnwrap(&rval.toObject()))) {
4641 0 : nsCOMPtr<nsIGlobalObject> contentGlobal;
4642 0 : JS::Handle<JSObject*> callback = CallbackOrNull();
4643 0 : if (!callback ||
4644 0 : !GetContentGlobalForJSImplementedObject(cx, callback, getter_AddRefs(contentGlobal))) {
4645 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
4646 0 : return nullptr;
4647 : }
4648 0 : JS::Rooted<JSObject*> jsImplSourceObj(cx, &rval.toObject());
4649 0 : rvalDecl = new mozilla::dom::SEReader(jsImplSourceObj, contentGlobal);
4650 : } else {
4651 0 : ThrowErrorMessage(cx, MSG_DOES_NOT_IMPLEMENT_INTERFACE, "Return value of SESession.reader", "SEReader");
4652 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
4653 0 : return nullptr;
4654 : }
4655 : }
4656 : }
4657 : } else {
4658 0 : ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Return value of SESession.reader");
4659 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
4660 0 : return nullptr;
4661 : }
4662 0 : return rvalDecl.forget();
4663 : }
4664 :
4665 : bool
4666 0 : SESessionJSImpl::GetIsClosed(ErrorResult& aRv, JSCompartment* aCompartment)
4667 : {
4668 0 : CallSetup s(this, aRv, "SESession.isClosed", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
4669 0 : JSContext* cx = s.GetContext();
4670 0 : if (!cx) {
4671 0 : MOZ_ASSERT(aRv.Failed());
4672 0 : return bool(0);
4673 : }
4674 0 : JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
4675 :
4676 0 : JS::Rooted<JSObject *> callback(cx, mCallback);
4677 0 : SESessionAtoms* atomsCache = GetAtomCache<SESessionAtoms>(cx);
4678 0 : if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
4679 0 : !JS_GetPropertyById(cx, callback, atomsCache->isClosed_id, &rval)) {
4680 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
4681 0 : return bool(0);
4682 : }
4683 : bool rvalDecl;
4684 0 : if (!ValueToPrimitive<bool, eDefault>(cx, rval, &rvalDecl)) {
4685 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
4686 0 : return bool(0);
4687 : }
4688 0 : return rvalDecl;
4689 : }
4690 :
4691 :
4692 : NS_IMPL_CYCLE_COLLECTION_CLASS(SESession)
4693 0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(SESession)
4694 0 : NS_IMPL_CYCLE_COLLECTION_UNLINK(mImpl)
4695 0 : NS_IMPL_CYCLE_COLLECTION_UNLINK(mParent)
4696 0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
4697 0 : tmp->ClearWeakReferences();
4698 0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_END
4699 0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(SESession)
4700 0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mImpl)
4701 0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mParent)
4702 0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
4703 0 : NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(SESession)
4704 0 : NS_IMPL_CYCLE_COLLECTING_ADDREF(SESession)
4705 0 : NS_IMPL_CYCLE_COLLECTING_RELEASE(SESession)
4706 0 : NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(SESession)
4707 0 : NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
4708 0 : NS_INTERFACE_MAP_ENTRY(nsISupports)
4709 0 : NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
4710 0 : NS_INTERFACE_MAP_END
4711 :
4712 0 : SESession::SESession(JS::Handle<JSObject*> aJSImplObject, nsIGlobalObject* aParent)
4713 0 : : mImpl(new SESessionJSImpl(nullptr, aJSImplObject, /* aIncumbentGlobal = */ nullptr)),
4714 0 : mParent(aParent)
4715 : {
4716 0 : }
4717 :
4718 :
4719 0 : SESession::~SESession()
4720 : {
4721 0 : }
4722 :
4723 : nsISupports*
4724 0 : SESession::GetParentObject() const
4725 : {
4726 0 : return mParent;
4727 : }
4728 :
4729 : JSObject*
4730 0 : SESession::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
4731 : {
4732 0 : JS::Rooted<JSObject*> obj(aCx, SESessionBinding::Wrap(aCx, this, aGivenProto));
4733 0 : if (!obj) {
4734 0 : return nullptr;
4735 : }
4736 :
4737 : // Now define it on our chrome object
4738 0 : JSAutoCompartment ac(aCx, mImpl->CallbackOrNull());
4739 0 : if (!JS_WrapObject(aCx, &obj)) {
4740 0 : return nullptr;
4741 : }
4742 0 : if (!JS_DefineProperty(aCx, mImpl->CallbackOrNull(), "__DOM_IMPL__", obj, 0)) {
4743 0 : return nullptr;
4744 : }
4745 0 : return obj;
4746 : }
4747 :
4748 : // Return a raw pointer here to avoid refcounting, but make sure it's safe (the object should be kept alive by the callee).
4749 : already_AddRefed<SEReader>
4750 0 : SESession::GetReader(ErrorResult& aRv, JSCompartment* aCompartment) const
4751 : {
4752 0 : return mImpl->GetReader(aRv, aCompartment);
4753 : }
4754 :
4755 : bool
4756 0 : SESession::GetIsClosed(ErrorResult& aRv, JSCompartment* aCompartment) const
4757 : {
4758 0 : return mImpl->GetIsClosed(aRv, aCompartment);
4759 : }
4760 :
4761 : // Return a raw pointer here to avoid refcounting, but make sure it's safe (the object should be kept alive by the callee).
4762 : already_AddRefed<Promise>
4763 0 : SESession::OpenLogicalChannel(const Nullable<Uint8Array>& aid, ErrorResult& aRv, JSCompartment* aCompartment)
4764 : {
4765 0 : return mImpl->OpenLogicalChannel(aid, aRv, aCompartment);
4766 : }
4767 :
4768 : // Return a raw pointer here to avoid refcounting, but make sure it's safe (the object should be kept alive by the callee).
4769 : already_AddRefed<Promise>
4770 0 : SESession::CloseAll(ErrorResult& aRv, JSCompartment* aCompartment)
4771 : {
4772 0 : return mImpl->CloseAll(aRv, aCompartment);
4773 : }
4774 :
4775 : bool
4776 0 : SESession::_Create(JSContext* cx, unsigned argc, JS::Value* vp)
4777 : {
4778 0 : JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
4779 0 : if (args.length() < 2) {
4780 0 : return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "SESession._create");
4781 : }
4782 0 : if (!args[0].isObject()) {
4783 0 : return ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 1 of SESession._create");
4784 : }
4785 0 : if (!args[1].isObject()) {
4786 0 : return ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 2 of SESession._create");
4787 : }
4788 :
4789 : // GlobalObject will go through wrappers as needed for us, and
4790 : // is simpler than the right UnwrapArg incantation.
4791 0 : GlobalObject global(cx, &args[0].toObject());
4792 0 : if (global.Failed()) {
4793 0 : return false;
4794 : }
4795 0 : nsCOMPtr<nsIGlobalObject> globalHolder = do_QueryInterface(global.GetAsSupports());
4796 0 : MOZ_ASSERT(globalHolder);
4797 0 : JS::Rooted<JSObject*> arg(cx, &args[1].toObject());
4798 0 : RefPtr<SESession> impl = new SESession(arg, globalHolder);
4799 0 : MOZ_ASSERT(js::IsObjectInContextCompartment(arg, cx));
4800 0 : return GetOrCreateDOMReflector(cx, impl, args.rval());
4801 : }
4802 :
4803 :
4804 : } // namespace dom
4805 : } // namespace mozilla
|