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