Line data Source code
1 : /* THIS FILE IS AUTOGENERATED FROM WebExtensionPolicy.webidl BY Codegen.py - DO NOT EDIT */
2 :
3 : #include "AtomList.h"
4 : #include "WebExtensionPolicyBinding.h"
5 : #include "WrapperFactory.h"
6 : #include "mozilla/OwningNonNull.h"
7 : #include "mozilla/dom/BindingUtils.h"
8 : #include "mozilla/dom/DOMJSClass.h"
9 : #include "mozilla/dom/NonRefcountedDOMObject.h"
10 : #include "mozilla/dom/Nullable.h"
11 : #include "mozilla/dom/PrimitiveConversions.h"
12 : #include "mozilla/dom/ScriptSettings.h"
13 : #include "mozilla/extensions/MatchPattern.h"
14 : #include "mozilla/extensions/WebExtensionContentScript.h"
15 : #include "mozilla/extensions/WebExtensionPolicy.h"
16 : #include "nsContentUtils.h"
17 : #include "nsIURI.h"
18 : #include "nsJSUtils.h"
19 : #include "nsThreadUtils.h"
20 :
21 : namespace mozilla {
22 : namespace dom {
23 :
24 :
25 0 : WebExtensionInit::WebExtensionInit()
26 : {
27 : // Safe to pass a null context if we pass a null value
28 0 : Init(nullptr, JS::NullHandleValue);
29 0 : }
30 :
31 :
32 : bool
33 0 : WebExtensionInit::InitIds(JSContext* cx, WebExtensionInitAtoms* atomsCache)
34 : {
35 0 : MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
36 :
37 : // Initialize these in reverse order so that any failure leaves the first one
38 : // uninitialized.
39 0 : if (!atomsCache->webAccessibleResources_id.init(cx, "webAccessibleResources") ||
40 0 : !atomsCache->permissions_id.init(cx, "permissions") ||
41 0 : !atomsCache->mozExtensionHostname_id.init(cx, "mozExtensionHostname") ||
42 0 : !atomsCache->localizeCallback_id.init(cx, "localizeCallback") ||
43 0 : !atomsCache->id_id.init(cx, "id") ||
44 0 : !atomsCache->contentSecurityPolicy_id.init(cx, "contentSecurityPolicy") ||
45 0 : !atomsCache->contentScripts_id.init(cx, "contentScripts") ||
46 0 : !atomsCache->baseURL_id.init(cx, "baseURL") ||
47 0 : !atomsCache->backgroundScripts_id.init(cx, "backgroundScripts") ||
48 0 : !atomsCache->allowedOrigins_id.init(cx, "allowedOrigins")) {
49 0 : return false;
50 : }
51 0 : return true;
52 : }
53 :
54 : bool
55 0 : WebExtensionInit::Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
56 : {
57 : // Passing a null JSContext is OK only if we're initing from null,
58 : // Since in that case we will not have to do any property gets
59 : // Also evaluate isNullOrUndefined in order to avoid false-positive
60 : // checkers by static analysis tools
61 0 : MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
62 0 : WebExtensionInitAtoms* atomsCache = nullptr;
63 0 : if (cx) {
64 0 : atomsCache = GetAtomCache<WebExtensionInitAtoms>(cx);
65 0 : if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
66 0 : return false;
67 : }
68 : }
69 :
70 0 : if (!IsConvertibleToDictionary(val)) {
71 0 : return ThrowErrorMessage(cx, MSG_NOT_DICTIONARY, sourceDescription);
72 : }
73 :
74 0 : bool isNull = val.isNullOrUndefined();
75 : // We only need these if !isNull, in which case we have |cx|.
76 0 : Maybe<JS::Rooted<JSObject *> > object;
77 0 : Maybe<JS::Rooted<JS::Value> > temp;
78 0 : if (!isNull) {
79 0 : MOZ_ASSERT(cx);
80 0 : object.emplace(cx, &val.toObject());
81 0 : temp.emplace(cx);
82 : }
83 0 : if (!isNull) {
84 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->allowedOrigins_id, temp.ptr())) {
85 0 : return false;
86 : }
87 : }
88 0 : if (!isNull && !temp->isUndefined()) {
89 0 : if (temp.ref().isObject()) {
90 : static_assert(IsRefcounted<mozilla::extensions::MatchPatternSet>::value, "We can only store refcounted classes.");{
91 0 : nsresult rv = UnwrapObject<prototypes::id::MatchPatternSet, mozilla::extensions::MatchPatternSet>(temp.ptr(), mAllowedOrigins);
92 0 : if (NS_FAILED(rv)) {
93 0 : ThrowErrorMessage(cx, MSG_DOES_NOT_IMPLEMENT_INTERFACE, "'allowedOrigins' member of WebExtensionInit", "MatchPatternSet");
94 0 : return false;
95 : }
96 : }
97 : } else {
98 0 : ThrowErrorMessage(cx, MSG_NOT_OBJECT, "'allowedOrigins' member of WebExtensionInit");
99 0 : return false;
100 : }
101 0 : mIsAnyMemberPresent = true;
102 0 : } else if (cx) {
103 : // Don't error out if we have no cx. In that
104 : // situation the caller is default-constructing us and we'll
105 : // just assume they know what they're doing.
106 0 : return ThrowErrorMessage(cx, MSG_MISSING_REQUIRED_DICTIONARY_MEMBER,
107 0 : "'allowedOrigins' member of WebExtensionInit");
108 : }
109 :
110 0 : if (!isNull) {
111 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->backgroundScripts_id, temp.ptr())) {
112 0 : return false;
113 : }
114 : }
115 0 : if (!isNull && !temp->isUndefined()) {
116 0 : if (temp.ref().isObject()) {
117 0 : JS::ForOfIterator iter(cx);
118 0 : if (!iter.init(temp.ref(), JS::ForOfIterator::AllowNonIterable)) {
119 0 : return false;
120 : }
121 0 : if (!iter.valueIsIterable()) {
122 0 : ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "'backgroundScripts' member of WebExtensionInit");
123 0 : return false;
124 : }
125 0 : Sequence<nsString> &arr = mBackgroundScripts.SetValue();
126 0 : JS::Rooted<JS::Value> temp(cx);
127 : while (true) {
128 : bool done;
129 0 : if (!iter.next(&temp, &done)) {
130 0 : return false;
131 : }
132 0 : if (done) {
133 0 : break;
134 : }
135 0 : nsString* slotPtr = arr.AppendElement(mozilla::fallible);
136 0 : if (!slotPtr) {
137 0 : JS_ReportOutOfMemory(cx);
138 0 : return false;
139 : }
140 0 : nsString& slot = *slotPtr;
141 0 : if (!ConvertJSValueToString(cx, temp, eStringify, eStringify, slot)) {
142 0 : return false;
143 : }
144 0 : }
145 0 : } else if (temp.ref().isNullOrUndefined()) {
146 0 : mBackgroundScripts.SetNull();
147 : } else {
148 0 : ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "'backgroundScripts' member of WebExtensionInit");
149 0 : return false;
150 : }
151 : } else {
152 0 : mBackgroundScripts.SetNull();
153 : }
154 0 : mIsAnyMemberPresent = true;
155 :
156 0 : if (!isNull) {
157 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->baseURL_id, temp.ptr())) {
158 0 : return false;
159 : }
160 : }
161 0 : if (!isNull && !temp->isUndefined()) {
162 0 : if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, mBaseURL)) {
163 0 : return false;
164 : }
165 0 : mIsAnyMemberPresent = true;
166 0 : } else if (cx) {
167 : // Don't error out if we have no cx. In that
168 : // situation the caller is default-constructing us and we'll
169 : // just assume they know what they're doing.
170 0 : return ThrowErrorMessage(cx, MSG_MISSING_REQUIRED_DICTIONARY_MEMBER,
171 0 : "'baseURL' member of WebExtensionInit");
172 : }
173 :
174 0 : if (!isNull) {
175 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->contentScripts_id, temp.ptr())) {
176 0 : return false;
177 : }
178 : }
179 0 : if (!isNull && !temp->isUndefined()) {
180 0 : if (temp.ref().isObject()) {
181 0 : JS::ForOfIterator iter(cx);
182 0 : if (!iter.init(temp.ref(), JS::ForOfIterator::AllowNonIterable)) {
183 0 : return false;
184 : }
185 0 : if (!iter.valueIsIterable()) {
186 0 : ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "'contentScripts' member of WebExtensionInit");
187 0 : return false;
188 : }
189 0 : Sequence<WebExtensionContentScriptInit> &arr = mContentScripts;
190 0 : JS::Rooted<JS::Value> temp(cx);
191 : while (true) {
192 : bool done;
193 0 : if (!iter.next(&temp, &done)) {
194 0 : return false;
195 : }
196 0 : if (done) {
197 0 : break;
198 : }
199 0 : WebExtensionContentScriptInit* slotPtr = arr.AppendElement(mozilla::fallible);
200 0 : if (!slotPtr) {
201 0 : JS_ReportOutOfMemory(cx);
202 0 : return false;
203 : }
204 0 : WebExtensionContentScriptInit& slot = *slotPtr;
205 0 : if (!slot.Init(cx, temp, "Element of 'contentScripts' member of WebExtensionInit", passedToJSImpl)) {
206 0 : return false;
207 : }
208 0 : }
209 : } else {
210 0 : ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "'contentScripts' member of WebExtensionInit");
211 0 : return false;
212 : }
213 : } else {
214 : /* Array is already empty; nothing to do */
215 : }
216 0 : mIsAnyMemberPresent = true;
217 :
218 0 : if (!isNull) {
219 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->contentSecurityPolicy_id, temp.ptr())) {
220 0 : return false;
221 : }
222 : }
223 0 : if (!isNull && !temp->isUndefined()) {
224 0 : if (!ConvertJSValueToString(cx, temp.ref(), eNull, eNull, mContentSecurityPolicy)) {
225 0 : return false;
226 : }
227 : } else {
228 0 : mContentSecurityPolicy.SetIsVoid(true);
229 : }
230 0 : mIsAnyMemberPresent = true;
231 :
232 0 : if (!isNull) {
233 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->id_id, temp.ptr())) {
234 0 : return false;
235 : }
236 : }
237 0 : if (!isNull && !temp->isUndefined()) {
238 0 : if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, mId)) {
239 0 : return false;
240 : }
241 0 : mIsAnyMemberPresent = true;
242 0 : } else if (cx) {
243 : // Don't error out if we have no cx. In that
244 : // situation the caller is default-constructing us and we'll
245 : // just assume they know what they're doing.
246 0 : return ThrowErrorMessage(cx, MSG_MISSING_REQUIRED_DICTIONARY_MEMBER,
247 0 : "'id' member of WebExtensionInit");
248 : }
249 :
250 0 : if (!isNull) {
251 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->localizeCallback_id, temp.ptr())) {
252 0 : return false;
253 : }
254 : }
255 0 : if (!isNull && !temp->isUndefined()) {
256 0 : if (temp.ref().isObject()) {
257 0 : if (JS::IsCallable(&temp.ref().toObject())) {
258 : { // scope for tempRoot
259 0 : JS::Rooted<JSObject*> tempRoot(cx, &temp.ref().toObject());
260 0 : mLocalizeCallback = new WebExtensionLocalizeCallback(cx, tempRoot, GetIncumbentGlobal());
261 : }
262 : } else {
263 0 : ThrowErrorMessage(cx, MSG_NOT_CALLABLE, "'localizeCallback' member of WebExtensionInit");
264 0 : return false;
265 : }
266 : } else {
267 0 : ThrowErrorMessage(cx, MSG_NOT_OBJECT, "'localizeCallback' member of WebExtensionInit");
268 0 : return false;
269 : }
270 0 : mIsAnyMemberPresent = true;
271 0 : } else if (cx) {
272 : // Don't error out if we have no cx. In that
273 : // situation the caller is default-constructing us and we'll
274 : // just assume they know what they're doing.
275 0 : return ThrowErrorMessage(cx, MSG_MISSING_REQUIRED_DICTIONARY_MEMBER,
276 0 : "'localizeCallback' member of WebExtensionInit");
277 : }
278 :
279 0 : if (!isNull) {
280 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->mozExtensionHostname_id, temp.ptr())) {
281 0 : return false;
282 : }
283 : }
284 0 : if (!isNull && !temp->isUndefined()) {
285 0 : if (!ConvertJSValueToByteString(cx, temp.ref(), false, mMozExtensionHostname)) {
286 0 : return false;
287 : }
288 0 : mIsAnyMemberPresent = true;
289 0 : } else if (cx) {
290 : // Don't error out if we have no cx. In that
291 : // situation the caller is default-constructing us and we'll
292 : // just assume they know what they're doing.
293 0 : return ThrowErrorMessage(cx, MSG_MISSING_REQUIRED_DICTIONARY_MEMBER,
294 0 : "'mozExtensionHostname' member of WebExtensionInit");
295 : }
296 :
297 0 : if (!isNull) {
298 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->permissions_id, temp.ptr())) {
299 0 : return false;
300 : }
301 : }
302 0 : if (!isNull && !temp->isUndefined()) {
303 0 : if (temp.ref().isObject()) {
304 0 : JS::ForOfIterator iter(cx);
305 0 : if (!iter.init(temp.ref(), JS::ForOfIterator::AllowNonIterable)) {
306 0 : return false;
307 : }
308 0 : if (!iter.valueIsIterable()) {
309 0 : ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "'permissions' member of WebExtensionInit");
310 0 : return false;
311 : }
312 0 : Sequence<nsString> &arr = mPermissions;
313 0 : JS::Rooted<JS::Value> temp(cx);
314 : while (true) {
315 : bool done;
316 0 : if (!iter.next(&temp, &done)) {
317 0 : return false;
318 : }
319 0 : if (done) {
320 0 : break;
321 : }
322 0 : nsString* slotPtr = arr.AppendElement(mozilla::fallible);
323 0 : if (!slotPtr) {
324 0 : JS_ReportOutOfMemory(cx);
325 0 : return false;
326 : }
327 0 : nsString& slot = *slotPtr;
328 0 : if (!ConvertJSValueToString(cx, temp, eStringify, eStringify, slot)) {
329 0 : return false;
330 : }
331 0 : }
332 : } else {
333 0 : ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "'permissions' member of WebExtensionInit");
334 0 : return false;
335 : }
336 : } else {
337 : /* Array is already empty; nothing to do */
338 : }
339 0 : mIsAnyMemberPresent = true;
340 :
341 0 : if (!isNull) {
342 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->webAccessibleResources_id, temp.ptr())) {
343 0 : return false;
344 : }
345 : }
346 0 : if (!isNull && !temp->isUndefined()) {
347 0 : if (temp.ref().isObject()) {
348 0 : JS::ForOfIterator iter(cx);
349 0 : if (!iter.init(temp.ref(), JS::ForOfIterator::AllowNonIterable)) {
350 0 : return false;
351 : }
352 0 : if (!iter.valueIsIterable()) {
353 0 : ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "'webAccessibleResources' member of WebExtensionInit");
354 0 : return false;
355 : }
356 0 : Sequence<OwningNonNull<mozilla::extensions::MatchGlob>> &arr = mWebAccessibleResources;
357 0 : JS::Rooted<JS::Value> temp(cx);
358 : while (true) {
359 : bool done;
360 0 : if (!iter.next(&temp, &done)) {
361 0 : return false;
362 : }
363 0 : if (done) {
364 0 : break;
365 : }
366 0 : OwningNonNull<mozilla::extensions::MatchGlob>* slotPtr = arr.AppendElement(mozilla::fallible);
367 0 : if (!slotPtr) {
368 0 : JS_ReportOutOfMemory(cx);
369 0 : return false;
370 : }
371 0 : OwningNonNull<mozilla::extensions::MatchGlob>& slot = *slotPtr;
372 0 : if (temp.isObject()) {
373 : static_assert(IsRefcounted<mozilla::extensions::MatchGlob>::value, "We can only store refcounted classes.");{
374 0 : nsresult rv = UnwrapObject<prototypes::id::MatchGlob, mozilla::extensions::MatchGlob>(&temp, slot);
375 0 : if (NS_FAILED(rv)) {
376 0 : ThrowErrorMessage(cx, MSG_DOES_NOT_IMPLEMENT_INTERFACE, "Element of 'webAccessibleResources' member of WebExtensionInit", "MatchGlob");
377 0 : return false;
378 : }
379 : }
380 : } else {
381 0 : ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Element of 'webAccessibleResources' member of WebExtensionInit");
382 0 : return false;
383 : }
384 0 : }
385 : } else {
386 0 : ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "'webAccessibleResources' member of WebExtensionInit");
387 0 : return false;
388 : }
389 : } else {
390 : /* Array is already empty; nothing to do */
391 : }
392 0 : mIsAnyMemberPresent = true;
393 0 : return true;
394 : }
395 :
396 : bool
397 0 : WebExtensionInit::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
398 : {
399 0 : WebExtensionInitAtoms* atomsCache = GetAtomCache<WebExtensionInitAtoms>(cx);
400 0 : if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
401 0 : return false;
402 : }
403 :
404 0 : JS::Rooted<JSObject*> obj(cx, JS_NewPlainObject(cx));
405 0 : if (!obj) {
406 0 : return false;
407 : }
408 0 : rval.set(JS::ObjectValue(*obj));
409 :
410 : do {
411 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
412 0 : JS::Rooted<JS::Value> temp(cx);
413 0 : OwningNonNull<mozilla::extensions::MatchPatternSet> const & currentValue = mAllowedOrigins;
414 0 : if (!GetOrCreateDOMReflector(cx, currentValue, &temp)) {
415 0 : MOZ_ASSERT(true || JS_IsExceptionPending(cx));
416 0 : return false;
417 : }
418 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->allowedOrigins_id, temp, JSPROP_ENUMERATE)) {
419 0 : return false;
420 : }
421 0 : break;
422 : } while(0);
423 :
424 : do {
425 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
426 0 : JS::Rooted<JS::Value> temp(cx);
427 0 : Nullable<Sequence<nsString>> const & currentValue = mBackgroundScripts;
428 :
429 0 : if (currentValue.IsNull()) {
430 0 : temp.setNull();
431 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->backgroundScripts_id, temp, JSPROP_ENUMERATE)) {
432 0 : return false;
433 : }
434 0 : break;
435 : }
436 :
437 0 : uint32_t length = currentValue.Value().Length();
438 0 : JS::Rooted<JSObject*> returnArray(cx, JS_NewArrayObject(cx, length));
439 0 : if (!returnArray) {
440 0 : return false;
441 : }
442 : // Scope for 'tmp'
443 : {
444 0 : JS::Rooted<JS::Value> tmp(cx);
445 0 : for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
446 : // Control block to let us common up the JS_DefineElement calls when there
447 : // are different ways to succeed at wrapping the object.
448 : do {
449 0 : if (!xpc::NonVoidStringToJsval(cx, currentValue.Value()[sequenceIdx0], &tmp)) {
450 0 : return false;
451 : }
452 0 : break;
453 : } while (0);
454 0 : if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
455 : JSPROP_ENUMERATE)) {
456 0 : return false;
457 : }
458 : }
459 : }
460 0 : temp.setObject(*returnArray);
461 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->backgroundScripts_id, temp, JSPROP_ENUMERATE)) {
462 0 : return false;
463 : }
464 0 : break;
465 : } while(0);
466 :
467 : do {
468 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
469 0 : JS::Rooted<JS::Value> temp(cx);
470 0 : nsString const & currentValue = mBaseURL;
471 0 : if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
472 0 : return false;
473 : }
474 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->baseURL_id, temp, JSPROP_ENUMERATE)) {
475 0 : return false;
476 : }
477 0 : break;
478 : } while(0);
479 :
480 : do {
481 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
482 0 : JS::Rooted<JS::Value> temp(cx);
483 0 : Sequence<WebExtensionContentScriptInit> const & currentValue = mContentScripts;
484 :
485 0 : uint32_t length = currentValue.Length();
486 0 : JS::Rooted<JSObject*> returnArray(cx, JS_NewArrayObject(cx, length));
487 0 : if (!returnArray) {
488 0 : return false;
489 : }
490 : // Scope for 'tmp'
491 : {
492 0 : JS::Rooted<JS::Value> tmp(cx);
493 0 : for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
494 : // Control block to let us common up the JS_DefineElement calls when there
495 : // are different ways to succeed at wrapping the object.
496 : do {
497 0 : if (!currentValue[sequenceIdx0].ToObjectInternal(cx, &tmp)) {
498 0 : return false;
499 : }
500 0 : break;
501 : } while (0);
502 0 : if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
503 : JSPROP_ENUMERATE)) {
504 0 : return false;
505 : }
506 : }
507 : }
508 0 : temp.setObject(*returnArray);
509 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->contentScripts_id, temp, JSPROP_ENUMERATE)) {
510 0 : return false;
511 : }
512 0 : break;
513 : } while(0);
514 :
515 : do {
516 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
517 0 : JS::Rooted<JS::Value> temp(cx);
518 0 : nsString const & currentValue = mContentSecurityPolicy;
519 0 : if (!xpc::StringToJsval(cx, currentValue, &temp)) {
520 0 : return false;
521 : }
522 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->contentSecurityPolicy_id, temp, JSPROP_ENUMERATE)) {
523 0 : return false;
524 : }
525 0 : break;
526 : } while(0);
527 :
528 : do {
529 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
530 0 : JS::Rooted<JS::Value> temp(cx);
531 0 : nsString const & currentValue = mId;
532 0 : if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
533 0 : return false;
534 : }
535 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->id_id, temp, JSPROP_ENUMERATE)) {
536 0 : return false;
537 : }
538 0 : break;
539 : } while(0);
540 :
541 : do {
542 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
543 0 : JS::Rooted<JS::Value> temp(cx);
544 0 : OwningNonNull<WebExtensionLocalizeCallback> const & currentValue = mLocalizeCallback;
545 0 : temp.setObjectOrNull(GetCallbackFromCallbackObject(currentValue));
546 0 : if (!MaybeWrapObjectValue(cx, &temp)) {
547 0 : return false;
548 : }
549 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->localizeCallback_id, temp, JSPROP_ENUMERATE)) {
550 0 : return false;
551 : }
552 0 : break;
553 : } while(0);
554 :
555 : do {
556 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
557 0 : JS::Rooted<JS::Value> temp(cx);
558 0 : nsCString const & currentValue = mMozExtensionHostname;
559 0 : if (!NonVoidByteStringToJsval(cx, currentValue, &temp)) {
560 0 : return false;
561 : }
562 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->mozExtensionHostname_id, temp, JSPROP_ENUMERATE)) {
563 0 : return false;
564 : }
565 0 : break;
566 : } while(0);
567 :
568 : do {
569 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
570 0 : JS::Rooted<JS::Value> temp(cx);
571 0 : Sequence<nsString> const & currentValue = mPermissions;
572 :
573 0 : uint32_t length = currentValue.Length();
574 0 : JS::Rooted<JSObject*> returnArray(cx, JS_NewArrayObject(cx, length));
575 0 : if (!returnArray) {
576 0 : return false;
577 : }
578 : // Scope for 'tmp'
579 : {
580 0 : JS::Rooted<JS::Value> tmp(cx);
581 0 : for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
582 : // Control block to let us common up the JS_DefineElement calls when there
583 : // are different ways to succeed at wrapping the object.
584 : do {
585 0 : if (!xpc::NonVoidStringToJsval(cx, currentValue[sequenceIdx0], &tmp)) {
586 0 : return false;
587 : }
588 0 : break;
589 : } while (0);
590 0 : if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
591 : JSPROP_ENUMERATE)) {
592 0 : return false;
593 : }
594 : }
595 : }
596 0 : temp.setObject(*returnArray);
597 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->permissions_id, temp, JSPROP_ENUMERATE)) {
598 0 : return false;
599 : }
600 0 : break;
601 : } while(0);
602 :
603 : do {
604 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
605 0 : JS::Rooted<JS::Value> temp(cx);
606 0 : Sequence<OwningNonNull<mozilla::extensions::MatchGlob>> const & currentValue = mWebAccessibleResources;
607 :
608 0 : uint32_t length = currentValue.Length();
609 0 : JS::Rooted<JSObject*> returnArray(cx, JS_NewArrayObject(cx, length));
610 0 : if (!returnArray) {
611 0 : return false;
612 : }
613 : // Scope for 'tmp'
614 : {
615 0 : JS::Rooted<JS::Value> tmp(cx);
616 0 : for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
617 : // Control block to let us common up the JS_DefineElement calls when there
618 : // are different ways to succeed at wrapping the object.
619 : do {
620 0 : if (!GetOrCreateDOMReflector(cx, currentValue[sequenceIdx0], &tmp)) {
621 0 : MOZ_ASSERT(true || JS_IsExceptionPending(cx));
622 0 : return false;
623 : }
624 0 : break;
625 : } while (0);
626 0 : if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
627 : JSPROP_ENUMERATE)) {
628 0 : return false;
629 : }
630 : }
631 : }
632 0 : temp.setObject(*returnArray);
633 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->webAccessibleResources_id, temp, JSPROP_ENUMERATE)) {
634 0 : return false;
635 : }
636 0 : break;
637 : } while(0);
638 :
639 0 : return true;
640 : }
641 :
642 : void
643 0 : WebExtensionInit::TraceDictionary(JSTracer* trc)
644 : {
645 0 : }
646 :
647 : namespace binding_detail {
648 : } // namespace binding_detail
649 :
650 :
651 : void
652 0 : WebExtensionLocalizeCallback::Call(JSContext* cx, JS::Handle<JS::Value> aThisVal, const nsAString& unlocalizedText, nsString& aRetVal, ErrorResult& aRv)
653 : {
654 0 : JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
655 0 : JS::AutoValueVector argv(cx);
656 0 : if (!argv.resize(1)) {
657 0 : aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
658 0 : return;
659 : }
660 0 : unsigned argc = 1;
661 :
662 : do {
663 0 : nsString mutableStr(unlocalizedText);
664 0 : if (!xpc::NonVoidStringToJsval(cx, mutableStr, argv[0])) {
665 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
666 0 : return;
667 : }
668 0 : break;
669 : } while (0);
670 :
671 0 : JS::Rooted<JS::Value> callable(cx, JS::ObjectValue(*mCallback));
672 0 : if (!JS::Call(cx, aThisVal, callable,
673 0 : JS::HandleValueArray::subarray(argv, 0, argc), &rval)) {
674 0 : aRv.NoteJSContextException(cx);
675 0 : return;
676 : }
677 0 : binding_detail::FakeString rvalDecl;
678 0 : if (!ConvertJSValueToString(cx, rval, eStringify, eStringify, rvalDecl)) {
679 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
680 0 : return;
681 : }
682 0 : aRetVal = rvalDecl;
683 : }
684 :
685 :
686 :
687 : namespace binding_detail {
688 : } // namespace binding_detail
689 :
690 :
691 : namespace WebExtensionPolicyBinding {
692 :
693 : static bool
694 0 : get_id(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::extensions::WebExtensionPolicy* self, JSJitGetterCallArgs args)
695 : {
696 : // Have to either root across the getter call or reget after.
697 0 : JS::Rooted<JSObject*> slotStorage(cx, js::UncheckedUnwrap(obj, /* stopAtWindowProxy = */ false));
698 0 : MOZ_ASSERT(IsDOMObject(slotStorage));
699 0 : const size_t slotIndex = (DOM_INSTANCE_RESERVED_SLOTS + 0);
700 0 : MOZ_ASSERT(JSCLASS_RESERVED_SLOTS(js::GetObjectClass(slotStorage)) > slotIndex);
701 : {
702 : // Scope for cachedVal
703 0 : JS::Value cachedVal = js::GetReservedSlot(slotStorage, slotIndex);
704 0 : if (!cachedVal.isUndefined()) {
705 0 : args.rval().set(cachedVal);
706 : // The cached value is in the compartment of slotStorage,
707 : // so wrap into the caller compartment as needed.
708 0 : return MaybeWrapValue(cx, args.rval());
709 : }
710 : }
711 :
712 0 : DOMString result;
713 0 : self->GetId(result);
714 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
715 : {
716 0 : JS::Rooted<JSObject*> conversionScope(cx, slotStorage);
717 0 : JSAutoCompartment ac(cx, conversionScope);
718 : do { // block we break out of when done wrapping
719 0 : if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
720 0 : return false;
721 : }
722 0 : break;
723 : } while (0);
724 : }
725 : { // And now store things in the compartment of our slotStorage.
726 0 : JSAutoCompartment ac(cx, slotStorage);
727 : // Make a copy so that we don't do unnecessary wrapping on args.rval().
728 0 : JS::Rooted<JS::Value> storedVal(cx, args.rval());
729 0 : if (!MaybeWrapValue(cx, &storedVal)) {
730 0 : return false;
731 : }
732 0 : js::SetReservedSlot(slotStorage, slotIndex, storedVal);
733 : }
734 : // And now make sure args.rval() is in the caller compartment
735 0 : return MaybeWrapValue(cx, args.rval());
736 : }
737 :
738 : static const JSJitInfo id_getterinfo = {
739 : { (JSJitGetterOp)get_id },
740 : { prototypes::id::WebExtensionPolicy },
741 : { PrototypeTraits<prototypes::id::WebExtensionPolicy>::Depth },
742 : JSJitInfo::Getter,
743 : JSJitInfo::AliasNone, /* aliasSet. Not relevant for setters. */
744 : JSVAL_TYPE_STRING, /* returnType. Not relevant for setters. */
745 : false, /* isInfallible. False in setters. */
746 : true, /* isMovable. Not relevant for setters. */
747 : true, /* isEliminatable. Not relevant for setters. */
748 : true, /* isAlwaysInSlot. Only relevant for getters. */
749 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
750 : false, /* isTypedMethod. Only relevant for methods. */
751 : (DOM_INSTANCE_RESERVED_SLOTS + 0) /* Reserved slot index, if we're stored in a slot, else 0. */
752 : };
753 : static_assert((DOM_INSTANCE_RESERVED_SLOTS + 0) <= JSJitInfo::maxSlotIndex, "We won't fit");
754 : static_assert((DOM_INSTANCE_RESERVED_SLOTS + 0) < 5, "There is no slot for us");
755 :
756 : static bool
757 0 : get_mozExtensionHostname(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::extensions::WebExtensionPolicy* self, JSJitGetterCallArgs args)
758 : {
759 : // Have to either root across the getter call or reget after.
760 0 : JS::Rooted<JSObject*> slotStorage(cx, js::UncheckedUnwrap(obj, /* stopAtWindowProxy = */ false));
761 0 : MOZ_ASSERT(IsDOMObject(slotStorage));
762 0 : const size_t slotIndex = (DOM_INSTANCE_RESERVED_SLOTS + 1);
763 0 : MOZ_ASSERT(JSCLASS_RESERVED_SLOTS(js::GetObjectClass(slotStorage)) > slotIndex);
764 : {
765 : // Scope for cachedVal
766 0 : JS::Value cachedVal = js::GetReservedSlot(slotStorage, slotIndex);
767 0 : if (!cachedVal.isUndefined()) {
768 0 : args.rval().set(cachedVal);
769 : // The cached value is in the compartment of slotStorage,
770 : // so wrap into the caller compartment as needed.
771 0 : return MaybeWrapValue(cx, args.rval());
772 : }
773 : }
774 :
775 0 : nsCString result;
776 0 : self->GetMozExtensionHostname(result);
777 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
778 : {
779 0 : JS::Rooted<JSObject*> conversionScope(cx, slotStorage);
780 0 : JSAutoCompartment ac(cx, conversionScope);
781 : do { // block we break out of when done wrapping
782 0 : if (!NonVoidByteStringToJsval(cx, result, args.rval())) {
783 0 : return false;
784 : }
785 0 : break;
786 : } while (0);
787 : }
788 : { // And now store things in the compartment of our slotStorage.
789 0 : JSAutoCompartment ac(cx, slotStorage);
790 : // Make a copy so that we don't do unnecessary wrapping on args.rval().
791 0 : JS::Rooted<JS::Value> storedVal(cx, args.rval());
792 0 : if (!MaybeWrapValue(cx, &storedVal)) {
793 0 : return false;
794 : }
795 0 : js::SetReservedSlot(slotStorage, slotIndex, storedVal);
796 : }
797 : // And now make sure args.rval() is in the caller compartment
798 0 : return MaybeWrapValue(cx, args.rval());
799 : }
800 :
801 : static const JSJitInfo mozExtensionHostname_getterinfo = {
802 : { (JSJitGetterOp)get_mozExtensionHostname },
803 : { prototypes::id::WebExtensionPolicy },
804 : { PrototypeTraits<prototypes::id::WebExtensionPolicy>::Depth },
805 : JSJitInfo::Getter,
806 : JSJitInfo::AliasNone, /* aliasSet. Not relevant for setters. */
807 : JSVAL_TYPE_STRING, /* returnType. Not relevant for setters. */
808 : false, /* isInfallible. False in setters. */
809 : true, /* isMovable. Not relevant for setters. */
810 : true, /* isEliminatable. Not relevant for setters. */
811 : true, /* isAlwaysInSlot. Only relevant for getters. */
812 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
813 : false, /* isTypedMethod. Only relevant for methods. */
814 : (DOM_INSTANCE_RESERVED_SLOTS + 1) /* Reserved slot index, if we're stored in a slot, else 0. */
815 : };
816 : static_assert((DOM_INSTANCE_RESERVED_SLOTS + 1) <= JSJitInfo::maxSlotIndex, "We won't fit");
817 : static_assert((DOM_INSTANCE_RESERVED_SLOTS + 1) < 5, "There is no slot for us");
818 :
819 : static bool
820 0 : get_baseURL(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::extensions::WebExtensionPolicy* self, JSJitGetterCallArgs args)
821 : {
822 0 : nsCString result;
823 0 : self->GetBaseURL(result);
824 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
825 0 : if (!NonVoidByteStringToJsval(cx, result, args.rval())) {
826 0 : return false;
827 : }
828 0 : return true;
829 : }
830 :
831 : static const JSJitInfo baseURL_getterinfo = {
832 : { (JSJitGetterOp)get_baseURL },
833 : { prototypes::id::WebExtensionPolicy },
834 : { PrototypeTraits<prototypes::id::WebExtensionPolicy>::Depth },
835 : JSJitInfo::Getter,
836 : JSJitInfo::AliasNone, /* aliasSet. Not relevant for setters. */
837 : JSVAL_TYPE_STRING, /* returnType. Not relevant for setters. */
838 : false, /* isInfallible. False in setters. */
839 : true, /* isMovable. Not relevant for setters. */
840 : true, /* isEliminatable. Not relevant for setters. */
841 : false, /* isAlwaysInSlot. Only relevant for getters. */
842 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
843 : false, /* isTypedMethod. Only relevant for methods. */
844 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
845 : };
846 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
847 : static_assert(0 < 5, "There is no slot for us");
848 :
849 : static bool
850 0 : get_contentSecurityPolicy(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::extensions::WebExtensionPolicy* self, JSJitGetterCallArgs args)
851 : {
852 0 : DOMString result;
853 0 : self->GetContentSecurityPolicy(result);
854 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
855 0 : if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
856 0 : return false;
857 : }
858 0 : return true;
859 : }
860 :
861 : static const JSJitInfo contentSecurityPolicy_getterinfo = {
862 : { (JSJitGetterOp)get_contentSecurityPolicy },
863 : { prototypes::id::WebExtensionPolicy },
864 : { PrototypeTraits<prototypes::id::WebExtensionPolicy>::Depth },
865 : JSJitInfo::Getter,
866 : JSJitInfo::AliasNone, /* aliasSet. Not relevant for setters. */
867 : JSVAL_TYPE_STRING, /* returnType. Not relevant for setters. */
868 : false, /* isInfallible. False in setters. */
869 : true, /* isMovable. Not relevant for setters. */
870 : true, /* isEliminatable. Not relevant for setters. */
871 : false, /* isAlwaysInSlot. Only relevant for getters. */
872 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
873 : false, /* isTypedMethod. Only relevant for methods. */
874 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
875 : };
876 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
877 : static_assert(0 < 5, "There is no slot for us");
878 :
879 : static bool
880 0 : get_permissions(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::extensions::WebExtensionPolicy* self, JSJitGetterCallArgs args)
881 : {
882 : // Have to either root across the getter call or reget after.
883 0 : JS::Rooted<JSObject*> slotStorage(cx, js::UncheckedUnwrap(obj, /* stopAtWindowProxy = */ false));
884 0 : MOZ_ASSERT(IsDOMObject(slotStorage));
885 0 : const size_t slotIndex = (DOM_INSTANCE_RESERVED_SLOTS + 2);
886 0 : MOZ_ASSERT(JSCLASS_RESERVED_SLOTS(js::GetObjectClass(slotStorage)) > slotIndex);
887 : {
888 : // Scope for cachedVal
889 0 : JS::Value cachedVal = js::GetReservedSlot(slotStorage, slotIndex);
890 0 : if (!cachedVal.isUndefined()) {
891 0 : args.rval().set(cachedVal);
892 : // The cached value is in the compartment of slotStorage,
893 : // so wrap into the caller compartment as needed.
894 0 : return MaybeWrapNonDOMObjectValue(cx, args.rval());
895 : }
896 : }
897 :
898 0 : nsTArray<nsString> result;
899 0 : self->GetPermissions(result);
900 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
901 : {
902 0 : JS::Rooted<JSObject*> conversionScope(cx, slotStorage);
903 0 : JSAutoCompartment ac(cx, conversionScope);
904 : do { // block we break out of when done wrapping
905 :
906 0 : uint32_t length = result.Length();
907 0 : JS::Rooted<JSObject*> returnArray(cx, JS_NewArrayObject(cx, length));
908 0 : if (!returnArray) {
909 0 : return false;
910 : }
911 : // Scope for 'tmp'
912 : {
913 0 : JS::Rooted<JS::Value> tmp(cx);
914 0 : for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
915 : // Control block to let us common up the JS_DefineElement calls when there
916 : // are different ways to succeed at wrapping the object.
917 : do {
918 0 : if (!xpc::NonVoidStringToJsval(cx, result[sequenceIdx0], &tmp)) {
919 0 : return false;
920 : }
921 0 : break;
922 : } while (0);
923 0 : if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
924 : JSPROP_ENUMERATE)) {
925 0 : return false;
926 : }
927 : }
928 : }
929 0 : args.rval().setObject(*returnArray);
930 0 : break;
931 : } while (0);
932 0 : JS::Rooted<JSObject*> rvalObj(cx, &args.rval().toObject());
933 0 : if (!JS_FreezeObject(cx, rvalObj)) {
934 0 : return false;
935 : }
936 : }
937 : { // And now store things in the compartment of our slotStorage.
938 0 : JSAutoCompartment ac(cx, slotStorage);
939 : // Make a copy so that we don't do unnecessary wrapping on args.rval().
940 0 : JS::Rooted<JS::Value> storedVal(cx, args.rval());
941 0 : if (!MaybeWrapNonDOMObjectValue(cx, &storedVal)) {
942 0 : return false;
943 : }
944 0 : js::SetReservedSlot(slotStorage, slotIndex, storedVal);
945 0 : PreserveWrapper(self);
946 : }
947 : // And now make sure args.rval() is in the caller compartment
948 0 : return MaybeWrapNonDOMObjectValue(cx, args.rval());
949 : }
950 :
951 : static bool
952 0 : set_permissions(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::extensions::WebExtensionPolicy* self, JSJitSetterCallArgs args)
953 : {
954 0 : binding_detail::AutoSequence<nsString> arg0;
955 0 : if (args[0].isObject()) {
956 0 : JS::ForOfIterator iter(cx);
957 0 : if (!iter.init(args[0], JS::ForOfIterator::AllowNonIterable)) {
958 0 : return false;
959 : }
960 0 : if (!iter.valueIsIterable()) {
961 0 : ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "Value being assigned to WebExtensionPolicy.permissions");
962 0 : return false;
963 : }
964 0 : binding_detail::AutoSequence<nsString> &arr = arg0;
965 0 : JS::Rooted<JS::Value> temp(cx);
966 : while (true) {
967 : bool done;
968 0 : if (!iter.next(&temp, &done)) {
969 0 : return false;
970 : }
971 0 : if (done) {
972 0 : break;
973 : }
974 0 : nsString* slotPtr = arr.AppendElement(mozilla::fallible);
975 0 : if (!slotPtr) {
976 0 : JS_ReportOutOfMemory(cx);
977 0 : return false;
978 : }
979 0 : nsString& slot = *slotPtr;
980 0 : if (!ConvertJSValueToString(cx, temp, eStringify, eStringify, slot)) {
981 0 : return false;
982 : }
983 0 : }
984 : } else {
985 0 : ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "Value being assigned to WebExtensionPolicy.permissions");
986 0 : return false;
987 : }
988 0 : self->SetPermissions(Constify(arg0));
989 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
990 :
991 0 : ClearCachedPermissionsValue(self);
992 0 : return true;
993 : }
994 :
995 : static const JSJitInfo permissions_getterinfo = {
996 : { (JSJitGetterOp)get_permissions },
997 : { prototypes::id::WebExtensionPolicy },
998 : { PrototypeTraits<prototypes::id::WebExtensionPolicy>::Depth },
999 : JSJitInfo::Getter,
1000 : JSJitInfo::AliasDOMSets, /* aliasSet. Not relevant for setters. */
1001 : JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
1002 : false, /* isInfallible. False in setters. */
1003 : true, /* isMovable. Not relevant for setters. */
1004 : true, /* isEliminatable. Not relevant for setters. */
1005 : false, /* isAlwaysInSlot. Only relevant for getters. */
1006 : true, /* isLazilyCachedInSlot. Only relevant for getters. */
1007 : false, /* isTypedMethod. Only relevant for methods. */
1008 : (DOM_INSTANCE_RESERVED_SLOTS + 2) /* Reserved slot index, if we're stored in a slot, else 0. */
1009 : };
1010 : static_assert((DOM_INSTANCE_RESERVED_SLOTS + 2) <= JSJitInfo::maxSlotIndex, "We won't fit");
1011 : static_assert((DOM_INSTANCE_RESERVED_SLOTS + 2) < 5, "There is no slot for us");
1012 : static const JSJitInfo permissions_setterinfo = {
1013 : { (JSJitGetterOp)set_permissions },
1014 : { prototypes::id::WebExtensionPolicy },
1015 : { PrototypeTraits<prototypes::id::WebExtensionPolicy>::Depth },
1016 : JSJitInfo::Setter,
1017 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
1018 : JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
1019 : false, /* isInfallible. False in setters. */
1020 : false, /* isMovable. Not relevant for setters. */
1021 : false, /* isEliminatable. Not relevant for setters. */
1022 : false, /* isAlwaysInSlot. Only relevant for getters. */
1023 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
1024 : false, /* isTypedMethod. Only relevant for methods. */
1025 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
1026 : };
1027 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
1028 : static_assert(0 < 5, "There is no slot for us");
1029 :
1030 : static bool
1031 0 : get_allowedOrigins(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::extensions::WebExtensionPolicy* self, JSJitGetterCallArgs args)
1032 : {
1033 0 : auto result(StrongOrRawPtr<mozilla::extensions::MatchPatternSet>(self->AllowedOrigins()));
1034 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
1035 0 : if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
1036 0 : MOZ_ASSERT(true || JS_IsExceptionPending(cx));
1037 0 : return false;
1038 : }
1039 0 : return true;
1040 : }
1041 :
1042 : static bool
1043 0 : set_allowedOrigins(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::extensions::WebExtensionPolicy* self, JSJitSetterCallArgs args)
1044 : {
1045 0 : NonNull<mozilla::extensions::MatchPatternSet> arg0;
1046 0 : if (args[0].isObject()) {
1047 : {
1048 0 : nsresult rv = UnwrapObject<prototypes::id::MatchPatternSet, mozilla::extensions::MatchPatternSet>(args[0], arg0);
1049 0 : if (NS_FAILED(rv)) {
1050 0 : ThrowErrorMessage(cx, MSG_DOES_NOT_IMPLEMENT_INTERFACE, "Value being assigned to WebExtensionPolicy.allowedOrigins", "MatchPatternSet");
1051 0 : return false;
1052 : }
1053 : }
1054 : } else {
1055 0 : ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Value being assigned to WebExtensionPolicy.allowedOrigins");
1056 0 : return false;
1057 : }
1058 0 : self->SetAllowedOrigins(NonNullHelper(arg0));
1059 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
1060 :
1061 0 : return true;
1062 : }
1063 :
1064 : static const JSJitInfo allowedOrigins_getterinfo = {
1065 : { (JSJitGetterOp)get_allowedOrigins },
1066 : { prototypes::id::WebExtensionPolicy },
1067 : { PrototypeTraits<prototypes::id::WebExtensionPolicy>::Depth },
1068 : JSJitInfo::Getter,
1069 : JSJitInfo::AliasDOMSets, /* aliasSet. Not relevant for setters. */
1070 : JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
1071 : false, /* isInfallible. False in setters. */
1072 : true, /* isMovable. Not relevant for setters. */
1073 : true, /* isEliminatable. Not relevant for setters. */
1074 : false, /* isAlwaysInSlot. Only relevant for getters. */
1075 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
1076 : false, /* isTypedMethod. Only relevant for methods. */
1077 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
1078 : };
1079 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
1080 : static_assert(0 < 5, "There is no slot for us");
1081 : static const JSJitInfo allowedOrigins_setterinfo = {
1082 : { (JSJitGetterOp)set_allowedOrigins },
1083 : { prototypes::id::WebExtensionPolicy },
1084 : { PrototypeTraits<prototypes::id::WebExtensionPolicy>::Depth },
1085 : JSJitInfo::Setter,
1086 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
1087 : JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
1088 : false, /* isInfallible. False in setters. */
1089 : false, /* isMovable. Not relevant for setters. */
1090 : false, /* isEliminatable. Not relevant for setters. */
1091 : false, /* isAlwaysInSlot. Only relevant for getters. */
1092 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
1093 : false, /* isTypedMethod. Only relevant for methods. */
1094 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
1095 : };
1096 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
1097 : static_assert(0 < 5, "There is no slot for us");
1098 :
1099 : static bool
1100 0 : get_contentScripts(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::extensions::WebExtensionPolicy* self, JSJitGetterCallArgs args)
1101 : {
1102 : // Have to either root across the getter call or reget after.
1103 0 : JS::Rooted<JSObject*> slotStorage(cx, js::UncheckedUnwrap(obj, /* stopAtWindowProxy = */ false));
1104 0 : MOZ_ASSERT(IsDOMObject(slotStorage));
1105 0 : const size_t slotIndex = (DOM_INSTANCE_RESERVED_SLOTS + 3);
1106 0 : MOZ_ASSERT(JSCLASS_RESERVED_SLOTS(js::GetObjectClass(slotStorage)) > slotIndex);
1107 : {
1108 : // Scope for cachedVal
1109 0 : JS::Value cachedVal = js::GetReservedSlot(slotStorage, slotIndex);
1110 0 : if (!cachedVal.isUndefined()) {
1111 0 : args.rval().set(cachedVal);
1112 : // The cached value is in the compartment of slotStorage,
1113 : // so wrap into the caller compartment as needed.
1114 0 : return MaybeWrapNonDOMObjectValue(cx, args.rval());
1115 : }
1116 : }
1117 :
1118 0 : nsTArray<StrongPtrForMember<mozilla::extensions::WebExtensionContentScript>::Type> result;
1119 0 : self->GetContentScripts(result);
1120 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
1121 : {
1122 0 : JS::Rooted<JSObject*> conversionScope(cx, slotStorage);
1123 0 : JSAutoCompartment ac(cx, conversionScope);
1124 : do { // block we break out of when done wrapping
1125 :
1126 0 : uint32_t length = result.Length();
1127 0 : JS::Rooted<JSObject*> returnArray(cx, JS_NewArrayObject(cx, length));
1128 0 : if (!returnArray) {
1129 0 : return false;
1130 : }
1131 : // Scope for 'tmp'
1132 : {
1133 0 : JS::Rooted<JS::Value> tmp(cx);
1134 0 : for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
1135 : // Control block to let us common up the JS_DefineElement calls when there
1136 : // are different ways to succeed at wrapping the object.
1137 : do {
1138 0 : if (!GetOrCreateDOMReflector(cx, result[sequenceIdx0], &tmp)) {
1139 0 : MOZ_ASSERT(true || JS_IsExceptionPending(cx));
1140 0 : return false;
1141 : }
1142 0 : break;
1143 : } while (0);
1144 0 : if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
1145 : JSPROP_ENUMERATE)) {
1146 0 : return false;
1147 : }
1148 : }
1149 : }
1150 0 : args.rval().setObject(*returnArray);
1151 0 : break;
1152 : } while (0);
1153 0 : JS::Rooted<JSObject*> rvalObj(cx, &args.rval().toObject());
1154 0 : if (!JS_FreezeObject(cx, rvalObj)) {
1155 0 : return false;
1156 : }
1157 : }
1158 : { // And now store things in the compartment of our slotStorage.
1159 0 : JSAutoCompartment ac(cx, slotStorage);
1160 : // Make a copy so that we don't do unnecessary wrapping on args.rval().
1161 0 : JS::Rooted<JS::Value> storedVal(cx, args.rval());
1162 0 : if (!MaybeWrapNonDOMObjectValue(cx, &storedVal)) {
1163 0 : return false;
1164 : }
1165 0 : js::SetReservedSlot(slotStorage, slotIndex, storedVal);
1166 0 : PreserveWrapper(self);
1167 : }
1168 : // And now make sure args.rval() is in the caller compartment
1169 0 : return MaybeWrapNonDOMObjectValue(cx, args.rval());
1170 : }
1171 :
1172 : static const JSJitInfo contentScripts_getterinfo = {
1173 : { (JSJitGetterOp)get_contentScripts },
1174 : { prototypes::id::WebExtensionPolicy },
1175 : { PrototypeTraits<prototypes::id::WebExtensionPolicy>::Depth },
1176 : JSJitInfo::Getter,
1177 : JSJitInfo::AliasNone, /* aliasSet. Not relevant for setters. */
1178 : JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
1179 : false, /* isInfallible. False in setters. */
1180 : true, /* isMovable. Not relevant for setters. */
1181 : true, /* isEliminatable. Not relevant for setters. */
1182 : false, /* isAlwaysInSlot. Only relevant for getters. */
1183 : true, /* isLazilyCachedInSlot. Only relevant for getters. */
1184 : false, /* isTypedMethod. Only relevant for methods. */
1185 : (DOM_INSTANCE_RESERVED_SLOTS + 3) /* Reserved slot index, if we're stored in a slot, else 0. */
1186 : };
1187 : static_assert((DOM_INSTANCE_RESERVED_SLOTS + 3) <= JSJitInfo::maxSlotIndex, "We won't fit");
1188 : static_assert((DOM_INSTANCE_RESERVED_SLOTS + 3) < 5, "There is no slot for us");
1189 :
1190 : static bool
1191 0 : get_active(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::extensions::WebExtensionPolicy* self, JSJitGetterCallArgs args)
1192 : {
1193 0 : bool result(self->Active());
1194 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
1195 0 : args.rval().setBoolean(result);
1196 0 : return true;
1197 : }
1198 :
1199 : static bool
1200 0 : set_active(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::extensions::WebExtensionPolicy* self, JSJitSetterCallArgs args)
1201 : {
1202 : bool arg0;
1203 0 : if (!ValueToPrimitive<bool, eDefault>(cx, args[0], &arg0)) {
1204 0 : return false;
1205 : }
1206 0 : binding_detail::FastErrorResult rv;
1207 0 : self->SetActive(arg0, rv);
1208 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
1209 0 : return false;
1210 : }
1211 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
1212 :
1213 0 : return true;
1214 : }
1215 :
1216 : static const JSJitInfo active_getterinfo = {
1217 : { (JSJitGetterOp)get_active },
1218 : { prototypes::id::WebExtensionPolicy },
1219 : { PrototypeTraits<prototypes::id::WebExtensionPolicy>::Depth },
1220 : JSJitInfo::Getter,
1221 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
1222 : JSVAL_TYPE_BOOLEAN, /* returnType. Not relevant for setters. */
1223 : true, /* isInfallible. False in setters. */
1224 : false, /* isMovable. Not relevant for setters. */
1225 : false, /* isEliminatable. Not relevant for setters. */
1226 : false, /* isAlwaysInSlot. Only relevant for getters. */
1227 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
1228 : false, /* isTypedMethod. Only relevant for methods. */
1229 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
1230 : };
1231 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
1232 : static_assert(0 < 5, "There is no slot for us");
1233 : static const JSJitInfo active_setterinfo = {
1234 : { (JSJitGetterOp)set_active },
1235 : { prototypes::id::WebExtensionPolicy },
1236 : { PrototypeTraits<prototypes::id::WebExtensionPolicy>::Depth },
1237 : JSJitInfo::Setter,
1238 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
1239 : JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
1240 : false, /* isInfallible. False in setters. */
1241 : false, /* isMovable. Not relevant for setters. */
1242 : false, /* isEliminatable. Not relevant for setters. */
1243 : false, /* isAlwaysInSlot. Only relevant for getters. */
1244 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
1245 : false, /* isTypedMethod. Only relevant for methods. */
1246 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
1247 : };
1248 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
1249 : static_assert(0 < 5, "There is no slot for us");
1250 :
1251 : static bool
1252 0 : get_isExtensionProcess(JSContext* cx, unsigned argc, JS::Value* vp)
1253 : {
1254 0 : JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
1255 0 : JS::Rooted<JSObject*> obj(cx, &args.callee());
1256 :
1257 0 : GlobalObject global(cx, xpc::XrayAwareCalleeGlobal(obj));
1258 0 : if (global.Failed()) {
1259 0 : return false;
1260 : }
1261 :
1262 0 : bool result(mozilla::extensions::WebExtensionPolicy::IsExtensionProcess(global));
1263 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
1264 0 : args.rval().setBoolean(result);
1265 0 : return true;
1266 : }
1267 :
1268 : static bool
1269 0 : canAccessURI(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::extensions::WebExtensionPolicy* self, const JSJitMethodCallArgs& args)
1270 : {
1271 0 : if (MOZ_UNLIKELY(args.length() < 1)) {
1272 0 : return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "WebExtensionPolicy.canAccessURI");
1273 : }
1274 : nsIURI* arg0;
1275 0 : RefPtr<nsIURI> arg0_holder;
1276 0 : if (args[0].isObject()) {
1277 0 : JS::Rooted<JSObject*> source(cx, &args[0].toObject());
1278 0 : if (NS_FAILED(UnwrapArg<nsIURI>(cx, source, getter_AddRefs(arg0_holder)))) {
1279 0 : ThrowErrorMessage(cx, MSG_DOES_NOT_IMPLEMENT_INTERFACE, "Argument 1 of WebExtensionPolicy.canAccessURI", "URI");
1280 0 : return false;
1281 : }
1282 0 : MOZ_ASSERT(arg0_holder);
1283 0 : arg0 = arg0_holder;
1284 : } else {
1285 0 : ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 1 of WebExtensionPolicy.canAccessURI");
1286 0 : return false;
1287 : }
1288 : bool arg1;
1289 0 : if (args.hasDefined(1)) {
1290 0 : if (!ValueToPrimitive<bool, eDefault>(cx, args[1], &arg1)) {
1291 0 : return false;
1292 : }
1293 : } else {
1294 0 : arg1 = false;
1295 : }
1296 0 : bool result(self->CanAccessURI(NonNullHelper(arg0), arg1));
1297 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
1298 0 : args.rval().setBoolean(result);
1299 0 : return true;
1300 : }
1301 :
1302 : static const JSJitInfo canAccessURI_methodinfo = {
1303 : { (JSJitGetterOp)canAccessURI },
1304 : { prototypes::id::WebExtensionPolicy },
1305 : { PrototypeTraits<prototypes::id::WebExtensionPolicy>::Depth },
1306 : JSJitInfo::Method,
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 < 5, "There is no slot for us");
1319 :
1320 : static bool
1321 0 : hasPermission(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::extensions::WebExtensionPolicy* self, const JSJitMethodCallArgs& args)
1322 : {
1323 0 : if (MOZ_UNLIKELY(args.length() < 1)) {
1324 0 : return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "WebExtensionPolicy.hasPermission");
1325 : }
1326 0 : binding_detail::FakeString arg0;
1327 0 : if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
1328 0 : return false;
1329 : }
1330 0 : bool result(self->HasPermission(NonNullHelper(Constify(arg0))));
1331 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
1332 0 : args.rval().setBoolean(result);
1333 0 : return true;
1334 : }
1335 :
1336 : static const JSJitInfo hasPermission_methodinfo = {
1337 : { (JSJitGetterOp)hasPermission },
1338 : { prototypes::id::WebExtensionPolicy },
1339 : { PrototypeTraits<prototypes::id::WebExtensionPolicy>::Depth },
1340 : JSJitInfo::Method,
1341 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
1342 : JSVAL_TYPE_BOOLEAN, /* returnType. Not relevant for setters. */
1343 : false, /* isInfallible. False in setters. */
1344 : false, /* isMovable. Not relevant for setters. */
1345 : false, /* isEliminatable. Not relevant for setters. */
1346 : false, /* isAlwaysInSlot. Only relevant for getters. */
1347 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
1348 : false, /* isTypedMethod. Only relevant for methods. */
1349 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
1350 : };
1351 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
1352 : static_assert(0 < 5, "There is no slot for us");
1353 :
1354 : static bool
1355 0 : isPathWebAccessible(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::extensions::WebExtensionPolicy* self, const JSJitMethodCallArgs& args)
1356 : {
1357 0 : if (MOZ_UNLIKELY(args.length() < 1)) {
1358 0 : return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "WebExtensionPolicy.isPathWebAccessible");
1359 : }
1360 0 : binding_detail::FakeString arg0;
1361 0 : if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
1362 0 : return false;
1363 : }
1364 0 : bool result(self->IsPathWebAccessible(NonNullHelper(Constify(arg0))));
1365 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
1366 0 : args.rval().setBoolean(result);
1367 0 : return true;
1368 : }
1369 :
1370 : static const JSJitInfo isPathWebAccessible_methodinfo = {
1371 : { (JSJitGetterOp)isPathWebAccessible },
1372 : { prototypes::id::WebExtensionPolicy },
1373 : { PrototypeTraits<prototypes::id::WebExtensionPolicy>::Depth },
1374 : JSJitInfo::Method,
1375 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
1376 : JSVAL_TYPE_BOOLEAN, /* returnType. Not relevant for setters. */
1377 : false, /* isInfallible. False in setters. */
1378 : false, /* isMovable. Not relevant for setters. */
1379 : false, /* isEliminatable. Not relevant for setters. */
1380 : false, /* isAlwaysInSlot. Only relevant for getters. */
1381 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
1382 : false, /* isTypedMethod. Only relevant for methods. */
1383 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
1384 : };
1385 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
1386 : static_assert(0 < 5, "There is no slot for us");
1387 :
1388 : static bool
1389 0 : localize(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::extensions::WebExtensionPolicy* self, const JSJitMethodCallArgs& args)
1390 : {
1391 0 : if (MOZ_UNLIKELY(args.length() < 1)) {
1392 0 : return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "WebExtensionPolicy.localize");
1393 : }
1394 0 : binding_detail::FakeString arg0;
1395 0 : if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
1396 0 : return false;
1397 : }
1398 0 : DOMString result;
1399 0 : self->Localize(NonNullHelper(Constify(arg0)), result);
1400 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
1401 0 : if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
1402 0 : return false;
1403 : }
1404 0 : return true;
1405 : }
1406 :
1407 : static const JSJitInfo localize_methodinfo = {
1408 : { (JSJitGetterOp)localize },
1409 : { prototypes::id::WebExtensionPolicy },
1410 : { PrototypeTraits<prototypes::id::WebExtensionPolicy>::Depth },
1411 : JSJitInfo::Method,
1412 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
1413 : JSVAL_TYPE_STRING, /* returnType. Not relevant for setters. */
1414 : false, /* isInfallible. False in setters. */
1415 : false, /* isMovable. Not relevant for setters. */
1416 : false, /* isEliminatable. Not relevant for setters. */
1417 : false, /* isAlwaysInSlot. Only relevant for getters. */
1418 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
1419 : false, /* isTypedMethod. Only relevant for methods. */
1420 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
1421 : };
1422 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
1423 : static_assert(0 < 5, "There is no slot for us");
1424 :
1425 : static bool
1426 0 : getURL(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::extensions::WebExtensionPolicy* self, const JSJitMethodCallArgs& args)
1427 : {
1428 0 : binding_detail::FakeString arg0;
1429 0 : if (args.hasDefined(0)) {
1430 0 : if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
1431 0 : return false;
1432 : }
1433 : } else {
1434 : static const char16_t data[] = { 0 };
1435 0 : arg0.Rebind(data, ArrayLength(data) - 1);
1436 : }
1437 0 : binding_detail::FastErrorResult rv;
1438 0 : DOMString result;
1439 0 : self->GetURL(NonNullHelper(Constify(arg0)), result, rv);
1440 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
1441 0 : return false;
1442 : }
1443 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
1444 0 : if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
1445 0 : return false;
1446 : }
1447 0 : return true;
1448 : }
1449 :
1450 : static const JSJitInfo getURL_methodinfo = {
1451 : { (JSJitGetterOp)getURL },
1452 : { prototypes::id::WebExtensionPolicy },
1453 : { PrototypeTraits<prototypes::id::WebExtensionPolicy>::Depth },
1454 : JSJitInfo::Method,
1455 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
1456 : JSVAL_TYPE_STRING, /* returnType. Not relevant for setters. */
1457 : false, /* isInfallible. False in setters. */
1458 : false, /* isMovable. Not relevant for setters. */
1459 : false, /* isEliminatable. Not relevant for setters. */
1460 : false, /* isAlwaysInSlot. Only relevant for getters. */
1461 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
1462 : false, /* isTypedMethod. Only relevant for methods. */
1463 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
1464 : };
1465 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
1466 : static_assert(0 < 5, "There is no slot for us");
1467 :
1468 : static bool
1469 0 : getActiveExtensions(JSContext* cx, unsigned argc, JS::Value* vp)
1470 : {
1471 0 : JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
1472 0 : JS::Rooted<JSObject*> obj(cx, &args.callee());
1473 :
1474 0 : GlobalObject global(cx, xpc::XrayAwareCalleeGlobal(obj));
1475 0 : if (global.Failed()) {
1476 0 : return false;
1477 : }
1478 :
1479 0 : nsTArray<StrongPtrForMember<mozilla::extensions::WebExtensionPolicy>::Type> result;
1480 0 : mozilla::extensions::WebExtensionPolicy::GetActiveExtensions(global, result);
1481 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
1482 :
1483 0 : uint32_t length = result.Length();
1484 0 : JS::Rooted<JSObject*> returnArray(cx, JS_NewArrayObject(cx, length));
1485 0 : if (!returnArray) {
1486 0 : return false;
1487 : }
1488 : // Scope for 'tmp'
1489 : {
1490 0 : JS::Rooted<JS::Value> tmp(cx);
1491 0 : for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
1492 : // Control block to let us common up the JS_DefineElement calls when there
1493 : // are different ways to succeed at wrapping the object.
1494 : do {
1495 0 : if (!GetOrCreateDOMReflector(cx, result[sequenceIdx0], &tmp)) {
1496 0 : MOZ_ASSERT(true || JS_IsExceptionPending(cx));
1497 0 : return false;
1498 : }
1499 0 : break;
1500 : } while (0);
1501 0 : if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
1502 : JSPROP_ENUMERATE)) {
1503 0 : return false;
1504 : }
1505 : }
1506 : }
1507 0 : args.rval().setObject(*returnArray);
1508 0 : return true;
1509 : }
1510 :
1511 : static bool
1512 0 : getByID(JSContext* cx, unsigned argc, JS::Value* vp)
1513 : {
1514 0 : JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
1515 0 : JS::Rooted<JSObject*> obj(cx, &args.callee());
1516 :
1517 0 : if (MOZ_UNLIKELY(args.length() < 1)) {
1518 0 : return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "WebExtensionPolicy.getByID");
1519 : }
1520 0 : GlobalObject global(cx, xpc::XrayAwareCalleeGlobal(obj));
1521 0 : if (global.Failed()) {
1522 0 : return false;
1523 : }
1524 :
1525 0 : binding_detail::FakeString arg0;
1526 0 : if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
1527 0 : return false;
1528 : }
1529 0 : auto result(StrongOrRawPtr<mozilla::extensions::WebExtensionPolicy>(mozilla::extensions::WebExtensionPolicy::GetByID(global, NonNullHelper(Constify(arg0)))));
1530 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
1531 0 : if (!result) {
1532 0 : args.rval().setNull();
1533 0 : return true;
1534 : }
1535 0 : if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
1536 0 : MOZ_ASSERT(true || JS_IsExceptionPending(cx));
1537 0 : return false;
1538 : }
1539 0 : return true;
1540 : }
1541 :
1542 : static bool
1543 0 : getByHostname(JSContext* cx, unsigned argc, JS::Value* vp)
1544 : {
1545 0 : JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
1546 0 : JS::Rooted<JSObject*> obj(cx, &args.callee());
1547 :
1548 0 : if (MOZ_UNLIKELY(args.length() < 1)) {
1549 0 : return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "WebExtensionPolicy.getByHostname");
1550 : }
1551 0 : GlobalObject global(cx, xpc::XrayAwareCalleeGlobal(obj));
1552 0 : if (global.Failed()) {
1553 0 : return false;
1554 : }
1555 :
1556 0 : nsCString arg0;
1557 0 : if (!ConvertJSValueToByteString(cx, args[0], false, arg0)) {
1558 0 : return false;
1559 : }
1560 0 : auto result(StrongOrRawPtr<mozilla::extensions::WebExtensionPolicy>(mozilla::extensions::WebExtensionPolicy::GetByHostname(global, Constify(arg0))));
1561 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
1562 0 : if (!result) {
1563 0 : args.rval().setNull();
1564 0 : return true;
1565 : }
1566 0 : if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
1567 0 : MOZ_ASSERT(true || JS_IsExceptionPending(cx));
1568 0 : return false;
1569 : }
1570 0 : return true;
1571 : }
1572 :
1573 : static bool
1574 0 : getByURI(JSContext* cx, unsigned argc, JS::Value* vp)
1575 : {
1576 0 : JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
1577 0 : JS::Rooted<JSObject*> obj(cx, &args.callee());
1578 :
1579 0 : if (MOZ_UNLIKELY(args.length() < 1)) {
1580 0 : return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "WebExtensionPolicy.getByURI");
1581 : }
1582 0 : GlobalObject global(cx, xpc::XrayAwareCalleeGlobal(obj));
1583 0 : if (global.Failed()) {
1584 0 : return false;
1585 : }
1586 :
1587 : nsIURI* arg0;
1588 0 : RefPtr<nsIURI> arg0_holder;
1589 0 : if (args[0].isObject()) {
1590 0 : JS::Rooted<JSObject*> source(cx, &args[0].toObject());
1591 0 : if (NS_FAILED(UnwrapArg<nsIURI>(cx, source, getter_AddRefs(arg0_holder)))) {
1592 0 : ThrowErrorMessage(cx, MSG_DOES_NOT_IMPLEMENT_INTERFACE, "Argument 1 of WebExtensionPolicy.getByURI", "URI");
1593 0 : return false;
1594 : }
1595 0 : MOZ_ASSERT(arg0_holder);
1596 0 : arg0 = arg0_holder;
1597 : } else {
1598 0 : ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 1 of WebExtensionPolicy.getByURI");
1599 0 : return false;
1600 : }
1601 0 : auto result(StrongOrRawPtr<mozilla::extensions::WebExtensionPolicy>(mozilla::extensions::WebExtensionPolicy::GetByURI(global, NonNullHelper(arg0))));
1602 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
1603 0 : if (!result) {
1604 0 : args.rval().setNull();
1605 0 : return true;
1606 : }
1607 0 : if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
1608 0 : MOZ_ASSERT(true || JS_IsExceptionPending(cx));
1609 0 : return false;
1610 : }
1611 0 : return true;
1612 : }
1613 :
1614 : static bool
1615 0 : _addProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::Handle<JS::Value> val)
1616 : {
1617 0 : mozilla::extensions::WebExtensionPolicy* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::extensions::WebExtensionPolicy>(obj);
1618 : // We don't want to preserve if we don't have a wrapper, and we
1619 : // obviously can't preserve if we're not initialized.
1620 0 : if (self && self->GetWrapperPreserveColor()) {
1621 0 : PreserveWrapper(self);
1622 : }
1623 0 : return true;
1624 : }
1625 :
1626 : static void
1627 0 : _finalize(js::FreeOp* fop, JSObject* obj)
1628 : {
1629 0 : mozilla::extensions::WebExtensionPolicy* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::extensions::WebExtensionPolicy>(obj);
1630 0 : if (self) {
1631 0 : ClearWrapper(self, self, obj);
1632 0 : AddForDeferredFinalization<mozilla::extensions::WebExtensionPolicy>(self);
1633 : }
1634 0 : }
1635 :
1636 : static void
1637 0 : _objectMoved(JSObject* obj, const JSObject* old)
1638 : {
1639 0 : mozilla::extensions::WebExtensionPolicy* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::extensions::WebExtensionPolicy>(obj);
1640 0 : if (self) {
1641 0 : UpdateWrapper(self, self, obj, old);
1642 : }
1643 0 : }
1644 :
1645 : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
1646 : #if defined(__clang__)
1647 : #pragma clang diagnostic push
1648 : #pragma clang diagnostic ignored "-Wmissing-braces"
1649 : #endif
1650 : static const JSFunctionSpec sStaticMethods_specs[] = {
1651 : JS_FNSPEC("getActiveExtensions", getActiveExtensions, nullptr, 0, JSPROP_ENUMERATE, nullptr),
1652 : JS_FNSPEC("getByID", getByID, nullptr, 1, JSPROP_ENUMERATE, nullptr),
1653 : JS_FNSPEC("getByHostname", getByHostname, nullptr, 1, JSPROP_ENUMERATE, nullptr),
1654 : JS_FNSPEC("getByURI", getByURI, nullptr, 1, JSPROP_ENUMERATE, nullptr),
1655 : JS_FS_END
1656 : };
1657 : #if defined(__clang__)
1658 : #pragma clang diagnostic pop
1659 : #endif
1660 :
1661 :
1662 : // Can't be const because the pref-enabled boolean needs to be writable
1663 : static Prefable<const JSFunctionSpec> sStaticMethods[] = {
1664 : { nullptr, &sStaticMethods_specs[0] },
1665 : { nullptr, nullptr }
1666 : };
1667 :
1668 : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
1669 : #if defined(__clang__)
1670 : #pragma clang diagnostic push
1671 : #pragma clang diagnostic ignored "-Wmissing-braces"
1672 : #endif
1673 : static const JSPropertySpec sStaticAttributes_specs[] = {
1674 : { "isExtensionProcess", JSPROP_SHARED | JSPROP_ENUMERATE, get_isExtensionProcess, nullptr, nullptr, nullptr },
1675 : { nullptr, 0, nullptr, nullptr, nullptr, nullptr }
1676 : };
1677 : #if defined(__clang__)
1678 : #pragma clang diagnostic pop
1679 : #endif
1680 :
1681 :
1682 : // Can't be const because the pref-enabled boolean needs to be writable
1683 : static Prefable<const JSPropertySpec> sStaticAttributes[] = {
1684 : { nullptr, &sStaticAttributes_specs[0] },
1685 : { nullptr, nullptr }
1686 : };
1687 :
1688 : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
1689 : #if defined(__clang__)
1690 : #pragma clang diagnostic push
1691 : #pragma clang diagnostic ignored "-Wmissing-braces"
1692 : #endif
1693 : static const JSFunctionSpec sMethods_specs[] = {
1694 : JS_FNSPEC("canAccessURI", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&canAccessURI_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
1695 : JS_FNSPEC("hasPermission", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&hasPermission_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
1696 : JS_FNSPEC("isPathWebAccessible", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&isPathWebAccessible_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
1697 : JS_FNSPEC("localize", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&localize_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
1698 : JS_FNSPEC("getURL", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&getURL_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
1699 : JS_FS_END
1700 : };
1701 : #if defined(__clang__)
1702 : #pragma clang diagnostic pop
1703 : #endif
1704 :
1705 :
1706 : // Can't be const because the pref-enabled boolean needs to be writable
1707 : static Prefable<const JSFunctionSpec> sMethods[] = {
1708 : { nullptr, &sMethods_specs[0] },
1709 : { nullptr, nullptr }
1710 : };
1711 :
1712 : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
1713 : #if defined(__clang__)
1714 : #pragma clang diagnostic push
1715 : #pragma clang diagnostic ignored "-Wmissing-braces"
1716 : #endif
1717 : static const JSPropertySpec sAttributes_specs[] = {
1718 : { "id", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &id_getterinfo, nullptr, nullptr },
1719 : { "mozExtensionHostname", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &mozExtensionHostname_getterinfo, nullptr, nullptr },
1720 : { "baseURL", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &baseURL_getterinfo, nullptr, nullptr },
1721 : { "contentSecurityPolicy", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &contentSecurityPolicy_getterinfo, nullptr, nullptr },
1722 : { "permissions", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &permissions_getterinfo, GenericBindingSetter, &permissions_setterinfo },
1723 : { "allowedOrigins", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &allowedOrigins_getterinfo, GenericBindingSetter, &allowedOrigins_setterinfo },
1724 : { "contentScripts", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &contentScripts_getterinfo, nullptr, nullptr },
1725 : { "active", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &active_getterinfo, GenericBindingSetter, &active_setterinfo },
1726 : { nullptr, 0, nullptr, nullptr, nullptr, nullptr }
1727 : };
1728 : #if defined(__clang__)
1729 : #pragma clang diagnostic pop
1730 : #endif
1731 :
1732 :
1733 : // Can't be const because the pref-enabled boolean needs to be writable
1734 : static Prefable<const JSPropertySpec> sAttributes[] = {
1735 : { nullptr, &sAttributes_specs[0] },
1736 : { nullptr, nullptr }
1737 : };
1738 :
1739 :
1740 : static const NativePropertiesN<4> sNativeProperties = {
1741 : true, 0 /* sStaticMethods */,
1742 : true, 1 /* sStaticAttributes */,
1743 : true, 2 /* sMethods */,
1744 : true, 3 /* sAttributes */,
1745 : false, 0,
1746 : false, 0,
1747 : false, 0,
1748 : -1,
1749 : 0,
1750 : nullptr,
1751 : {
1752 : { sStaticMethods, nullptr },
1753 : { sStaticAttributes, nullptr },
1754 : { sMethods, nullptr },
1755 : { sAttributes, nullptr }
1756 : }
1757 : };
1758 :
1759 : static bool
1760 0 : _constructor(JSContext* cx, unsigned argc, JS::Value* vp)
1761 : {
1762 0 : JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
1763 0 : JS::Rooted<JSObject*> obj(cx, &args.callee());
1764 0 : if (!args.isConstructing()) {
1765 : // XXXbz wish I could get the name from the callee instead of
1766 : // Adding more relocations
1767 0 : return ThrowConstructorWithoutNew(cx, "WebExtensionPolicy");
1768 : }
1769 :
1770 0 : GlobalObject global(cx, obj);
1771 0 : if (global.Failed()) {
1772 0 : return false;
1773 : }
1774 :
1775 0 : JS::Rooted<JSObject*> desiredProto(cx);
1776 0 : if (!GetDesiredProto(cx, args, &desiredProto)) {
1777 0 : return false;
1778 : }
1779 :
1780 0 : if (MOZ_UNLIKELY(args.length() < 1)) {
1781 0 : return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "WebExtensionPolicy");
1782 : }
1783 0 : bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
1784 0 : binding_detail::FastWebExtensionInit arg0;
1785 0 : if (!arg0.Init(cx, args[0], "Argument 1 of WebExtensionPolicy.constructor", false)) {
1786 0 : return false;
1787 : }
1788 0 : Maybe<JSAutoCompartment> ac;
1789 0 : if (objIsXray) {
1790 0 : obj = js::CheckedUnwrap(obj);
1791 0 : if (!obj) {
1792 0 : return false;
1793 : }
1794 0 : ac.emplace(cx, obj);
1795 0 : if (!JS_WrapObject(cx, &desiredProto)) {
1796 0 : return false;
1797 : }
1798 : }
1799 0 : binding_detail::FastErrorResult rv;
1800 0 : auto result(StrongOrRawPtr<mozilla::extensions::WebExtensionPolicy>(mozilla::extensions::WebExtensionPolicy::Constructor(global, Constify(arg0), rv)));
1801 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
1802 0 : return false;
1803 : }
1804 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
1805 : static_assert(!IsPointer<decltype(result)>::value,
1806 : "NewObject implies that we need to keep the object alive with a strong reference.");
1807 0 : if (!GetOrCreateDOMReflector(cx, result, args.rval(), desiredProto)) {
1808 0 : MOZ_ASSERT(true || JS_IsExceptionPending(cx));
1809 0 : return false;
1810 : }
1811 0 : return true;
1812 : }
1813 :
1814 : static const js::ClassOps sInterfaceObjectClassOps = {
1815 : nullptr, /* addProperty */
1816 : nullptr, /* delProperty */
1817 : nullptr, /* getProperty */
1818 : nullptr, /* setProperty */
1819 : nullptr, /* enumerate */
1820 : nullptr, /* newEnumerate */
1821 : nullptr, /* resolve */
1822 : nullptr, /* mayResolve */
1823 : nullptr, /* finalize */
1824 : _constructor, /* call */
1825 : nullptr, /* hasInstance */
1826 : _constructor, /* construct */
1827 : nullptr, /* trace */
1828 : };
1829 :
1830 : static const DOMIfaceAndProtoJSClass sInterfaceObjectClass = {
1831 : {
1832 : "Function",
1833 : JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_SLOTS_BASE),
1834 : &sInterfaceObjectClassOps,
1835 : JS_NULL_CLASS_SPEC,
1836 : JS_NULL_CLASS_EXT,
1837 : &sInterfaceObjectClassObjectOps
1838 : },
1839 : eInterface,
1840 : true,
1841 : prototypes::id::WebExtensionPolicy,
1842 : PrototypeTraits<prototypes::id::WebExtensionPolicy>::Depth,
1843 : &sEmptyNativePropertyHooks,
1844 : "function WebExtensionPolicy() {\n [native code]\n}",
1845 : JS::GetRealmFunctionPrototype
1846 : };
1847 :
1848 : static const DOMIfaceAndProtoJSClass sPrototypeClass = {
1849 : {
1850 : "WebExtensionPolicyPrototype",
1851 : JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE),
1852 : JS_NULL_CLASS_OPS,
1853 : JS_NULL_CLASS_SPEC,
1854 : JS_NULL_CLASS_EXT,
1855 : JS_NULL_OBJECT_OPS
1856 : },
1857 : eInterfacePrototype,
1858 : false,
1859 : prototypes::id::WebExtensionPolicy,
1860 : PrototypeTraits<prototypes::id::WebExtensionPolicy>::Depth,
1861 : &sEmptyNativePropertyHooks,
1862 : "[object WebExtensionPolicyPrototype]",
1863 : JS::GetRealmObjectPrototype
1864 : };
1865 :
1866 : bool
1867 0 : ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
1868 : {
1869 0 : return nsContentUtils::ThreadsafeIsSystemCaller(aCx);
1870 : }
1871 :
1872 : static const js::ClassOps sClassOps = {
1873 : _addProperty, /* addProperty */
1874 : nullptr, /* delProperty */
1875 : nullptr, /* getProperty */
1876 : nullptr, /* setProperty */
1877 : nullptr, /* enumerate */
1878 : nullptr, /* newEnumerate */
1879 : nullptr, /* resolve */
1880 : nullptr, /* mayResolve */
1881 : _finalize, /* finalize */
1882 : nullptr, /* call */
1883 : nullptr, /* hasInstance */
1884 : nullptr, /* construct */
1885 : nullptr, /* trace */
1886 : };
1887 :
1888 : static const js::ClassExtension sClassExtension = {
1889 : nullptr, /* weakmapKeyDelegateOp */
1890 : _objectMoved /* objectMovedOp */
1891 : };
1892 :
1893 : static const DOMJSClass sClass = {
1894 : { "WebExtensionPolicy",
1895 : JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(5),
1896 : &sClassOps,
1897 : JS_NULL_CLASS_SPEC,
1898 : &sClassExtension,
1899 : JS_NULL_OBJECT_OPS
1900 : },
1901 : { prototypes::id::WebExtensionPolicy, 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 },
1902 : IsBaseOf<nsISupports, mozilla::extensions::WebExtensionPolicy >::value,
1903 : &sEmptyNativePropertyHooks,
1904 : FindAssociatedGlobalForNative<mozilla::extensions::WebExtensionPolicy>::Get,
1905 : GetProtoObjectHandle,
1906 : GetCCParticipant<mozilla::extensions::WebExtensionPolicy>::Get()
1907 : };
1908 : static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
1909 : "Must have the right minimal number of reserved slots.");
1910 : static_assert(5 >= 5,
1911 : "Must have enough reserved slots.");
1912 :
1913 : const JSClass*
1914 0 : GetJSClass()
1915 : {
1916 0 : return sClass.ToJSClass();
1917 : }
1918 :
1919 : static bool
1920 0 : UpdateMemberSlots(JSContext* aCx, JS::Handle<JSObject*> aWrapper, mozilla::extensions::WebExtensionPolicy* aObject)
1921 : {
1922 0 : JS::Rooted<JS::Value> temp(aCx);
1923 0 : JSJitGetterCallArgs args(&temp);
1924 :
1925 : static_assert((DOM_INSTANCE_RESERVED_SLOTS + 0) < js::shadow::Object::MAX_FIXED_SLOTS,
1926 : "Not enough fixed slots to fit 'WebExtensionPolicy.id. Ion's visitGetDOMMemberV/visitGetDOMMemberT assume StoreInSlot things are all in fixed slots.");
1927 0 : if (!get_id(aCx, aWrapper, aObject, args)) {
1928 0 : return false;
1929 : }
1930 : // Getter handled setting our reserved slots
1931 :
1932 : static_assert((DOM_INSTANCE_RESERVED_SLOTS + 1) < js::shadow::Object::MAX_FIXED_SLOTS,
1933 : "Not enough fixed slots to fit 'WebExtensionPolicy.mozExtensionHostname. Ion's visitGetDOMMemberV/visitGetDOMMemberT assume StoreInSlot things are all in fixed slots.");
1934 0 : if (!get_mozExtensionHostname(aCx, aWrapper, aObject, args)) {
1935 0 : return false;
1936 : }
1937 : // Getter handled setting our reserved slots
1938 :
1939 0 : return true;
1940 : }
1941 :
1942 : bool
1943 0 : Wrap(JSContext* aCx, mozilla::extensions::WebExtensionPolicy* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
1944 : {
1945 : MOZ_ASSERT(static_cast<mozilla::extensions::WebExtensionPolicy*>(aObject) ==
1946 : reinterpret_cast<mozilla::extensions::WebExtensionPolicy*>(aObject),
1947 : "Multiple inheritance for mozilla::extensions::WebExtensionPolicy is broken.");
1948 0 : MOZ_ASSERT(ToSupportsIsCorrect(aObject));
1949 0 : MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
1950 0 : MOZ_ASSERT(!aCache->GetWrapper(),
1951 : "You should probably not be using Wrap() directly; use "
1952 : "GetOrCreateDOMReflector instead");
1953 :
1954 0 : MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
1955 : "nsISupports must be on our primary inheritance chain");
1956 :
1957 0 : JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
1958 0 : if (!global) {
1959 0 : return false;
1960 : }
1961 0 : MOZ_ASSERT(JS_IsGlobalObject(global));
1962 0 : MOZ_ASSERT(JS::ObjectIsNotGray(global));
1963 :
1964 : // That might have ended up wrapping us already, due to the wonders
1965 : // of XBL. Check for that, and bail out as needed.
1966 0 : aReflector.set(aCache->GetWrapper());
1967 0 : if (aReflector) {
1968 : #ifdef DEBUG
1969 0 : binding_detail::AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
1970 : #endif // DEBUG
1971 0 : return true;
1972 : }
1973 :
1974 0 : JSAutoCompartment ac(aCx, global);
1975 0 : JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
1976 0 : if (!canonicalProto) {
1977 0 : return false;
1978 : }
1979 0 : JS::Rooted<JSObject*> proto(aCx);
1980 0 : if (aGivenProto) {
1981 0 : proto = aGivenProto;
1982 : // Unfortunately, while aGivenProto was in the compartment of aCx
1983 : // coming in, we changed compartments to that of "parent" so may need
1984 : // to wrap the proto here.
1985 0 : if (js::GetContextCompartment(aCx) != js::GetObjectCompartment(proto)) {
1986 0 : if (!JS_WrapObject(aCx, &proto)) {
1987 0 : return false;
1988 : }
1989 : }
1990 : } else {
1991 0 : proto = canonicalProto;
1992 : }
1993 :
1994 0 : BindingJSObjectCreator<mozilla::extensions::WebExtensionPolicy> creator(aCx);
1995 0 : creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
1996 0 : if (!aReflector) {
1997 0 : return false;
1998 : }
1999 :
2000 0 : aCache->SetWrapper(aReflector);
2001 0 : if (!UpdateMemberSlots(aCx, aReflector, aObject)) {
2002 0 : aCache->ReleaseWrapper(aObject);
2003 0 : aCache->ClearWrapper();
2004 0 : return false;
2005 : }
2006 0 : creator.InitializationSucceeded();
2007 :
2008 0 : MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
2009 : aCache->GetWrapperPreserveColor() == aReflector);
2010 : // If proto != canonicalProto, we have to preserve our wrapper;
2011 : // otherwise we won't be able to properly recreate it later, since
2012 : // we won't know what proto to use. Note that we don't check
2013 : // aGivenProto here, since it's entirely possible (and even
2014 : // somewhat common) to have a non-null aGivenProto which is the
2015 : // same as canonicalProto.
2016 0 : if (proto != canonicalProto) {
2017 0 : PreserveWrapper(aObject);
2018 : }
2019 :
2020 0 : return true;
2021 : }
2022 :
2023 : void
2024 0 : ClearCachedPermissionsValue(mozilla::extensions::WebExtensionPolicy* aObject)
2025 : {
2026 : JSObject* obj;
2027 0 : obj = aObject->GetWrapper();
2028 0 : if (!obj) {
2029 0 : return;
2030 : }
2031 0 : js::SetReservedSlot(obj, (DOM_INSTANCE_RESERVED_SLOTS + 2), JS::UndefinedValue());
2032 : }
2033 :
2034 : void
2035 0 : CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, bool aDefineOnGlobal)
2036 : {
2037 0 : JS::Rooted<JSObject*> parentProto(aCx, JS::GetRealmObjectPrototype(aCx));
2038 0 : if (!parentProto) {
2039 0 : return;
2040 : }
2041 :
2042 0 : JS::Rooted<JSObject*> constructorProto(aCx, JS::GetRealmFunctionPrototype(aCx));
2043 0 : if (!constructorProto) {
2044 0 : return;
2045 : }
2046 :
2047 0 : JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::WebExtensionPolicy);
2048 0 : JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::WebExtensionPolicy);
2049 0 : dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
2050 : &sPrototypeClass.mBase, protoCache,
2051 : constructorProto, &sInterfaceObjectClass.mBase, 1, nullptr,
2052 : interfaceCache,
2053 : sNativeProperties.Upcast(),
2054 : nullptr,
2055 : "WebExtensionPolicy", aDefineOnGlobal,
2056 : nullptr,
2057 0 : false);
2058 : }
2059 :
2060 : JS::Handle<JSObject*>
2061 0 : GetProtoObjectHandle(JSContext* aCx)
2062 : {
2063 : /* Get the interface prototype object for this class. This will create the
2064 : object as needed. */
2065 0 : bool aDefineOnGlobal = true;
2066 :
2067 : /* Make sure our global is sane. Hopefully we can remove this sometime */
2068 0 : JSObject* global = JS::CurrentGlobalOrNull(aCx);
2069 0 : if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
2070 0 : return nullptr;
2071 : }
2072 :
2073 : /* Check to see whether the interface objects are already installed */
2074 0 : ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
2075 0 : if (!protoAndIfaceCache.HasEntryInSlot(prototypes::id::WebExtensionPolicy)) {
2076 0 : JS::Rooted<JSObject*> rootedGlobal(aCx, global);
2077 0 : CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
2078 : }
2079 :
2080 : /*
2081 : * The object might _still_ be null, but that's OK.
2082 : *
2083 : * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
2084 : * traced by TraceProtoAndIfaceCache() and its contents are never
2085 : * changed after they have been set.
2086 : *
2087 : * Calling address() avoids the read read barrier that does gray
2088 : * unmarking, but it's not possible for the object to be gray here.
2089 : */
2090 :
2091 0 : const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(prototypes::id::WebExtensionPolicy);
2092 0 : MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
2093 0 : return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
2094 : }
2095 :
2096 : JS::Handle<JSObject*>
2097 0 : GetConstructorObjectHandle(JSContext* aCx, bool aDefineOnGlobal)
2098 : {
2099 : /* Get the interface object for this class. This will create the object as
2100 : needed. */
2101 :
2102 : /* Make sure our global is sane. Hopefully we can remove this sometime */
2103 0 : JSObject* global = JS::CurrentGlobalOrNull(aCx);
2104 0 : if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
2105 0 : return nullptr;
2106 : }
2107 :
2108 : /* Check to see whether the interface objects are already installed */
2109 0 : ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
2110 0 : if (!protoAndIfaceCache.HasEntryInSlot(constructors::id::WebExtensionPolicy)) {
2111 0 : JS::Rooted<JSObject*> rootedGlobal(aCx, global);
2112 0 : CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
2113 : }
2114 :
2115 : /*
2116 : * The object might _still_ be null, but that's OK.
2117 : *
2118 : * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
2119 : * traced by TraceProtoAndIfaceCache() and its contents are never
2120 : * changed after they have been set.
2121 : *
2122 : * Calling address() avoids the read read barrier that does gray
2123 : * unmarking, but it's not possible for the object to be gray here.
2124 : */
2125 :
2126 0 : const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(constructors::id::WebExtensionPolicy);
2127 0 : MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
2128 0 : return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
2129 : }
2130 :
2131 : JSObject*
2132 0 : GetConstructorObject(JSContext* aCx)
2133 : {
2134 0 : return GetConstructorObjectHandle(aCx);
2135 : }
2136 :
2137 : } // namespace WebExtensionPolicyBinding
2138 :
2139 :
2140 :
2141 : } // namespace dom
2142 : } // namespace mozilla
|