Line data Source code
1 : /* THIS FILE IS AUTOGENERATED FROM IDBCursor.webidl BY Codegen.py - DO NOT EDIT */
2 :
3 : #include "IDBCursorBinding.h"
4 : #include "WrapperFactory.h"
5 : #include "jsapi.h"
6 : #include "mozilla/OwningNonNull.h"
7 : #include "mozilla/dom/BindingUtils.h"
8 : #include "mozilla/dom/DOMJSClass.h"
9 : #include "mozilla/dom/IDBCursor.h"
10 : #include "mozilla/dom/IDBIndex.h"
11 : #include "mozilla/dom/IDBObjectStore.h"
12 : #include "mozilla/dom/IDBRequest.h"
13 : #include "mozilla/dom/NonRefcountedDOMObject.h"
14 : #include "mozilla/dom/PrimitiveConversions.h"
15 : #include "mozilla/dom/UnionConversions.h"
16 : #include "mozilla/dom/XrayExpandoClass.h"
17 :
18 : namespace mozilla {
19 : namespace dom {
20 :
21 : namespace IDBCursorDirectionValues {
22 : extern const EnumEntry strings[5] = {
23 : {"next", 4},
24 : {"nextunique", 10},
25 : {"prev", 4},
26 : {"prevunique", 10},
27 : { nullptr, 0 }
28 : };
29 : } // namespace IDBCursorDirectionValues
30 :
31 : bool
32 0 : ToJSValue(JSContext* aCx, IDBCursorDirection aArgument, JS::MutableHandle<JS::Value> aValue)
33 : {
34 0 : MOZ_ASSERT(uint32_t(aArgument) < ArrayLength(IDBCursorDirectionValues::strings));
35 : JSString* resultStr =
36 0 : JS_NewStringCopyN(aCx, IDBCursorDirectionValues::strings[uint32_t(aArgument)].value,
37 0 : IDBCursorDirectionValues::strings[uint32_t(aArgument)].length);
38 0 : if (!resultStr) {
39 0 : return false;
40 : }
41 0 : aValue.setString(resultStr);
42 0 : return true;
43 : }
44 :
45 :
46 : void
47 0 : ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback, OwningIDBObjectStoreOrIDBIndex& aUnion, const char* aName, uint32_t aFlags)
48 : {
49 0 : if (aUnion.IsIDBObjectStore()) {
50 0 : ImplCycleCollectionTraverse(aCallback, aUnion.GetAsIDBObjectStore(), "mIDBObjectStore", aFlags);
51 0 : } else if (aUnion.IsIDBIndex()) {
52 0 : ImplCycleCollectionTraverse(aCallback, aUnion.GetAsIDBIndex(), "mIDBIndex", aFlags);
53 : }
54 0 : }
55 :
56 :
57 : void
58 0 : ImplCycleCollectionUnlink(OwningIDBObjectStoreOrIDBIndex& aUnion)
59 : {
60 0 : aUnion.Uninit();
61 0 : }
62 :
63 :
64 : bool
65 0 : IDBObjectStoreOrIDBIndex::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
66 : {
67 0 : switch (mType) {
68 : case eUninitialized: {
69 0 : return false;
70 : break;
71 : }
72 : case eIDBObjectStore: {
73 0 : if (!GetOrCreateDOMReflector(cx, mValue.mIDBObjectStore.Value(), rval)) {
74 0 : MOZ_ASSERT(true || JS_IsExceptionPending(cx));
75 0 : return false;
76 : }
77 0 : return true;
78 : break;
79 : }
80 : case eIDBIndex: {
81 0 : if (!GetOrCreateDOMReflector(cx, mValue.mIDBIndex.Value(), rval)) {
82 0 : MOZ_ASSERT(true || JS_IsExceptionPending(cx));
83 0 : return false;
84 : }
85 0 : return true;
86 : break;
87 : }
88 : default: {
89 0 : return false;
90 : break;
91 : }
92 : }
93 :
94 : return false;
95 : }
96 :
97 :
98 : OwningNonNull<mozilla::dom::IDBObjectStore>&
99 0 : OwningIDBObjectStoreOrIDBIndex::RawSetAsIDBObjectStore()
100 : {
101 0 : if (mType == eIDBObjectStore) {
102 0 : return mValue.mIDBObjectStore.Value();
103 : }
104 0 : MOZ_ASSERT(mType == eUninitialized);
105 0 : mType = eIDBObjectStore;
106 0 : return mValue.mIDBObjectStore.SetValue();
107 : }
108 :
109 : OwningNonNull<mozilla::dom::IDBObjectStore>&
110 0 : OwningIDBObjectStoreOrIDBIndex::SetAsIDBObjectStore()
111 : {
112 0 : if (mType == eIDBObjectStore) {
113 0 : return mValue.mIDBObjectStore.Value();
114 : }
115 0 : Uninit();
116 0 : mType = eIDBObjectStore;
117 0 : return mValue.mIDBObjectStore.SetValue();
118 : }
119 :
120 : bool
121 0 : OwningIDBObjectStoreOrIDBIndex::TrySetToIDBObjectStore(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
122 : {
123 0 : tryNext = false;
124 : { // scope for memberSlot
125 0 : OwningNonNull<mozilla::dom::IDBObjectStore>& memberSlot = RawSetAsIDBObjectStore();
126 : static_assert(IsRefcounted<mozilla::dom::IDBObjectStore>::value, "We can only store refcounted classes.");{
127 0 : nsresult rv = UnwrapObject<prototypes::id::IDBObjectStore, mozilla::dom::IDBObjectStore>(value, memberSlot);
128 0 : if (NS_FAILED(rv)) {
129 0 : DestroyIDBObjectStore();
130 0 : tryNext = true;
131 0 : return true;
132 : }
133 : }
134 : }
135 0 : return true;
136 : }
137 :
138 : void
139 0 : OwningIDBObjectStoreOrIDBIndex::DestroyIDBObjectStore()
140 : {
141 0 : MOZ_ASSERT(IsIDBObjectStore(), "Wrong type!");
142 0 : mValue.mIDBObjectStore.Destroy();
143 0 : mType = eUninitialized;
144 0 : }
145 :
146 :
147 :
148 :
149 : OwningNonNull<mozilla::dom::IDBIndex>&
150 0 : OwningIDBObjectStoreOrIDBIndex::RawSetAsIDBIndex()
151 : {
152 0 : if (mType == eIDBIndex) {
153 0 : return mValue.mIDBIndex.Value();
154 : }
155 0 : MOZ_ASSERT(mType == eUninitialized);
156 0 : mType = eIDBIndex;
157 0 : return mValue.mIDBIndex.SetValue();
158 : }
159 :
160 : OwningNonNull<mozilla::dom::IDBIndex>&
161 0 : OwningIDBObjectStoreOrIDBIndex::SetAsIDBIndex()
162 : {
163 0 : if (mType == eIDBIndex) {
164 0 : return mValue.mIDBIndex.Value();
165 : }
166 0 : Uninit();
167 0 : mType = eIDBIndex;
168 0 : return mValue.mIDBIndex.SetValue();
169 : }
170 :
171 : bool
172 0 : OwningIDBObjectStoreOrIDBIndex::TrySetToIDBIndex(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
173 : {
174 0 : tryNext = false;
175 : { // scope for memberSlot
176 0 : OwningNonNull<mozilla::dom::IDBIndex>& memberSlot = RawSetAsIDBIndex();
177 : static_assert(IsRefcounted<mozilla::dom::IDBIndex>::value, "We can only store refcounted classes.");{
178 0 : nsresult rv = UnwrapObject<prototypes::id::IDBIndex, mozilla::dom::IDBIndex>(value, memberSlot);
179 0 : if (NS_FAILED(rv)) {
180 0 : DestroyIDBIndex();
181 0 : tryNext = true;
182 0 : return true;
183 : }
184 : }
185 : }
186 0 : return true;
187 : }
188 :
189 : void
190 0 : OwningIDBObjectStoreOrIDBIndex::DestroyIDBIndex()
191 : {
192 0 : MOZ_ASSERT(IsIDBIndex(), "Wrong type!");
193 0 : mValue.mIDBIndex.Destroy();
194 0 : mType = eUninitialized;
195 0 : }
196 :
197 :
198 :
199 :
200 : void
201 0 : OwningIDBObjectStoreOrIDBIndex::Uninit()
202 : {
203 0 : switch (mType) {
204 : case eUninitialized: {
205 0 : break;
206 : }
207 : case eIDBObjectStore: {
208 0 : DestroyIDBObjectStore();
209 0 : break;
210 : }
211 : case eIDBIndex: {
212 0 : DestroyIDBIndex();
213 0 : break;
214 : }
215 : }
216 0 : }
217 :
218 : bool
219 0 : OwningIDBObjectStoreOrIDBIndex::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
220 : {
221 0 : switch (mType) {
222 : case eUninitialized: {
223 0 : return false;
224 : break;
225 : }
226 : case eIDBObjectStore: {
227 0 : if (!GetOrCreateDOMReflector(cx, mValue.mIDBObjectStore.Value(), rval)) {
228 0 : MOZ_ASSERT(true || JS_IsExceptionPending(cx));
229 0 : return false;
230 : }
231 0 : return true;
232 : break;
233 : }
234 : case eIDBIndex: {
235 0 : if (!GetOrCreateDOMReflector(cx, mValue.mIDBIndex.Value(), rval)) {
236 0 : MOZ_ASSERT(true || JS_IsExceptionPending(cx));
237 0 : return false;
238 : }
239 0 : return true;
240 : break;
241 : }
242 : default: {
243 0 : return false;
244 : break;
245 : }
246 : }
247 :
248 : return false;
249 : }
250 :
251 : void
252 0 : OwningIDBObjectStoreOrIDBIndex::TraceUnion(JSTracer* trc)
253 : {
254 0 : }
255 :
256 : OwningIDBObjectStoreOrIDBIndex&
257 0 : OwningIDBObjectStoreOrIDBIndex::operator=(const OwningIDBObjectStoreOrIDBIndex& aOther)
258 : {
259 0 : switch (aOther.mType) {
260 : case eUninitialized: {
261 0 : MOZ_ASSERT(mType == eUninitialized,
262 : "We need to destroy ourselves?");
263 0 : break;
264 : }
265 : case eIDBObjectStore: {
266 0 : SetAsIDBObjectStore() = aOther.GetAsIDBObjectStore();
267 0 : break;
268 : }
269 : case eIDBIndex: {
270 0 : SetAsIDBIndex() = aOther.GetAsIDBIndex();
271 0 : break;
272 : }
273 : }
274 0 : return *this;
275 : }
276 :
277 :
278 : namespace IDBCursorBinding {
279 :
280 : static bool
281 0 : get_source(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::IDBCursor* self, JSJitGetterCallArgs args)
282 : {
283 0 : OwningIDBObjectStoreOrIDBIndex result;
284 0 : self->GetSource(result);
285 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
286 0 : if (!result.ToJSVal(cx, obj, args.rval())) {
287 0 : return false;
288 : }
289 0 : return true;
290 : }
291 :
292 : static const JSJitInfo source_getterinfo = {
293 : { (JSJitGetterOp)get_source },
294 : { prototypes::id::IDBCursor },
295 : { PrototypeTraits<prototypes::id::IDBCursor>::Depth },
296 : JSJitInfo::Getter,
297 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
298 : JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
299 : false, /* isInfallible. False in setters. */
300 : false, /* isMovable. Not relevant for setters. */
301 : false, /* isEliminatable. Not relevant for setters. */
302 : false, /* isAlwaysInSlot. Only relevant for getters. */
303 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
304 : false, /* isTypedMethod. Only relevant for methods. */
305 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
306 : };
307 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
308 : static_assert(0 < 1, "There is no slot for us");
309 :
310 : static bool
311 0 : get_direction(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::IDBCursor* self, JSJitGetterCallArgs args)
312 : {
313 0 : IDBCursorDirection result(self->GetDirection());
314 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
315 0 : if (!ToJSValue(cx, result, args.rval())) {
316 0 : return false;
317 : }
318 0 : return true;
319 : }
320 :
321 : static const JSJitInfo direction_getterinfo = {
322 : { (JSJitGetterOp)get_direction },
323 : { prototypes::id::IDBCursor },
324 : { PrototypeTraits<prototypes::id::IDBCursor>::Depth },
325 : JSJitInfo::Getter,
326 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
327 : JSVAL_TYPE_STRING, /* returnType. Not relevant for setters. */
328 : false, /* isInfallible. False in setters. */
329 : false, /* isMovable. Not relevant for setters. */
330 : false, /* isEliminatable. Not relevant for setters. */
331 : false, /* isAlwaysInSlot. Only relevant for getters. */
332 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
333 : false, /* isTypedMethod. Only relevant for methods. */
334 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
335 : };
336 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
337 : static_assert(0 < 1, "There is no slot for us");
338 :
339 : static bool
340 0 : get_key(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::IDBCursor* self, JSJitGetterCallArgs args)
341 : {
342 0 : binding_detail::FastErrorResult rv;
343 0 : JS::Rooted<JS::Value> result(cx);
344 0 : self->GetKey(cx, &result, rv);
345 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
346 0 : return false;
347 : }
348 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
349 0 : JS::ExposeValueToActiveJS(result);
350 0 : args.rval().set(result);
351 0 : if (!MaybeWrapValue(cx, args.rval())) {
352 0 : return false;
353 : }
354 0 : return true;
355 : }
356 :
357 : static const JSJitInfo key_getterinfo = {
358 : { (JSJitGetterOp)get_key },
359 : { prototypes::id::IDBCursor },
360 : { PrototypeTraits<prototypes::id::IDBCursor>::Depth },
361 : JSJitInfo::Getter,
362 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
363 : JSVAL_TYPE_UNKNOWN, /* returnType. Not relevant for setters. */
364 : false, /* isInfallible. False in setters. */
365 : false, /* isMovable. Not relevant for setters. */
366 : false, /* isEliminatable. Not relevant for setters. */
367 : false, /* isAlwaysInSlot. Only relevant for getters. */
368 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
369 : false, /* isTypedMethod. Only relevant for methods. */
370 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
371 : };
372 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
373 : static_assert(0 < 1, "There is no slot for us");
374 :
375 : static bool
376 0 : get_primaryKey(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::IDBCursor* self, JSJitGetterCallArgs args)
377 : {
378 0 : binding_detail::FastErrorResult rv;
379 0 : JS::Rooted<JS::Value> result(cx);
380 0 : self->GetPrimaryKey(cx, &result, rv);
381 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
382 0 : return false;
383 : }
384 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
385 0 : JS::ExposeValueToActiveJS(result);
386 0 : args.rval().set(result);
387 0 : if (!MaybeWrapValue(cx, args.rval())) {
388 0 : return false;
389 : }
390 0 : return true;
391 : }
392 :
393 : static const JSJitInfo primaryKey_getterinfo = {
394 : { (JSJitGetterOp)get_primaryKey },
395 : { prototypes::id::IDBCursor },
396 : { PrototypeTraits<prototypes::id::IDBCursor>::Depth },
397 : JSJitInfo::Getter,
398 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
399 : JSVAL_TYPE_UNKNOWN, /* returnType. Not relevant for setters. */
400 : false, /* isInfallible. False in setters. */
401 : false, /* isMovable. Not relevant for setters. */
402 : false, /* isEliminatable. Not relevant for setters. */
403 : false, /* isAlwaysInSlot. Only relevant for getters. */
404 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
405 : false, /* isTypedMethod. Only relevant for methods. */
406 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
407 : };
408 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
409 : static_assert(0 < 1, "There is no slot for us");
410 :
411 : static bool
412 0 : update(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::IDBCursor* self, const JSJitMethodCallArgs& args)
413 : {
414 0 : if (MOZ_UNLIKELY(args.length() < 1)) {
415 0 : return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "IDBCursor.update");
416 : }
417 0 : JS::Rooted<JS::Value> arg0(cx);
418 0 : arg0 = args[0];
419 0 : binding_detail::FastErrorResult rv;
420 0 : auto result(StrongOrRawPtr<mozilla::dom::IDBRequest>(self->Update(cx, arg0, rv)));
421 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
422 0 : return false;
423 : }
424 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
425 0 : if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
426 0 : MOZ_ASSERT(true || JS_IsExceptionPending(cx));
427 0 : return false;
428 : }
429 0 : return true;
430 : }
431 :
432 : static const JSJitInfo update_methodinfo = {
433 : { (JSJitGetterOp)update },
434 : { prototypes::id::IDBCursor },
435 : { PrototypeTraits<prototypes::id::IDBCursor>::Depth },
436 : JSJitInfo::Method,
437 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
438 : JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
439 : false, /* isInfallible. False in setters. */
440 : false, /* isMovable. Not relevant for setters. */
441 : false, /* isEliminatable. Not relevant for setters. */
442 : false, /* isAlwaysInSlot. Only relevant for getters. */
443 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
444 : false, /* isTypedMethod. Only relevant for methods. */
445 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
446 : };
447 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
448 : static_assert(0 < 1, "There is no slot for us");
449 :
450 : static bool
451 0 : advance(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::IDBCursor* self, const JSJitMethodCallArgs& args)
452 : {
453 0 : if (MOZ_UNLIKELY(args.length() < 1)) {
454 0 : return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "IDBCursor.advance");
455 : }
456 : uint32_t arg0;
457 0 : if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, args[0], &arg0)) {
458 0 : return false;
459 : }
460 0 : binding_detail::FastErrorResult rv;
461 0 : self->Advance(arg0, rv);
462 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
463 0 : return false;
464 : }
465 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
466 0 : args.rval().setUndefined();
467 0 : return true;
468 : }
469 :
470 : static const JSJitInfo advance_methodinfo = {
471 : { (JSJitGetterOp)advance },
472 : { prototypes::id::IDBCursor },
473 : { PrototypeTraits<prototypes::id::IDBCursor>::Depth },
474 : JSJitInfo::Method,
475 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
476 : JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
477 : false, /* isInfallible. False in setters. */
478 : false, /* isMovable. Not relevant for setters. */
479 : false, /* isEliminatable. Not relevant for setters. */
480 : false, /* isAlwaysInSlot. Only relevant for getters. */
481 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
482 : false, /* isTypedMethod. Only relevant for methods. */
483 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
484 : };
485 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
486 : static_assert(0 < 1, "There is no slot for us");
487 :
488 : static bool
489 0 : _continue_(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::IDBCursor* self, const JSJitMethodCallArgs& args)
490 : {
491 0 : JS::Rooted<JS::Value> arg0(cx);
492 0 : if (args.hasDefined(0)) {
493 0 : arg0 = args[0];
494 : } else {
495 0 : arg0 = JS::UndefinedValue();
496 : }
497 0 : binding_detail::FastErrorResult rv;
498 0 : self->Continue(cx, arg0, rv);
499 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
500 0 : return false;
501 : }
502 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
503 0 : args.rval().setUndefined();
504 0 : return true;
505 : }
506 :
507 : static const JSJitInfo continue_methodinfo = {
508 : { (JSJitGetterOp)_continue_ },
509 : { prototypes::id::IDBCursor },
510 : { PrototypeTraits<prototypes::id::IDBCursor>::Depth },
511 : JSJitInfo::Method,
512 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
513 : JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
514 : false, /* isInfallible. False in setters. */
515 : false, /* isMovable. Not relevant for setters. */
516 : false, /* isEliminatable. Not relevant for setters. */
517 : false, /* isAlwaysInSlot. Only relevant for getters. */
518 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
519 : false, /* isTypedMethod. Only relevant for methods. */
520 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
521 : };
522 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
523 : static_assert(0 < 1, "There is no slot for us");
524 :
525 : static bool
526 0 : continuePrimaryKey(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::IDBCursor* self, const JSJitMethodCallArgs& args)
527 : {
528 0 : if (MOZ_UNLIKELY(args.length() < 2)) {
529 0 : return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "IDBCursor.continuePrimaryKey");
530 : }
531 0 : JS::Rooted<JS::Value> arg0(cx);
532 0 : arg0 = args[0];
533 0 : JS::Rooted<JS::Value> arg1(cx);
534 0 : arg1 = args[1];
535 0 : binding_detail::FastErrorResult rv;
536 0 : self->ContinuePrimaryKey(cx, arg0, arg1, rv);
537 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
538 0 : return false;
539 : }
540 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
541 0 : args.rval().setUndefined();
542 0 : return true;
543 : }
544 :
545 : static const JSJitInfo continuePrimaryKey_methodinfo = {
546 : { (JSJitGetterOp)continuePrimaryKey },
547 : { prototypes::id::IDBCursor },
548 : { PrototypeTraits<prototypes::id::IDBCursor>::Depth },
549 : JSJitInfo::Method,
550 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
551 : JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
552 : false, /* isInfallible. False in setters. */
553 : false, /* isMovable. Not relevant for setters. */
554 : false, /* isEliminatable. Not relevant for setters. */
555 : false, /* isAlwaysInSlot. Only relevant for getters. */
556 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
557 : false, /* isTypedMethod. Only relevant for methods. */
558 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
559 : };
560 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
561 : static_assert(0 < 1, "There is no slot for us");
562 :
563 : static bool
564 0 : _delete_(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::IDBCursor* self, const JSJitMethodCallArgs& args)
565 : {
566 0 : binding_detail::FastErrorResult rv;
567 0 : auto result(StrongOrRawPtr<mozilla::dom::IDBRequest>(self->Delete(cx, rv)));
568 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
569 0 : return false;
570 : }
571 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
572 0 : if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
573 0 : MOZ_ASSERT(true || JS_IsExceptionPending(cx));
574 0 : return false;
575 : }
576 0 : return true;
577 : }
578 :
579 : static const JSJitInfo delete_methodinfo = {
580 : { (JSJitGetterOp)_delete_ },
581 : { prototypes::id::IDBCursor },
582 : { PrototypeTraits<prototypes::id::IDBCursor>::Depth },
583 : JSJitInfo::Method,
584 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
585 : JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
586 : false, /* isInfallible. False in setters. */
587 : false, /* isMovable. Not relevant for setters. */
588 : false, /* isEliminatable. Not relevant for setters. */
589 : false, /* isAlwaysInSlot. Only relevant for getters. */
590 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
591 : false, /* isTypedMethod. Only relevant for methods. */
592 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
593 : };
594 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
595 : static_assert(0 < 1, "There is no slot for us");
596 :
597 : static bool
598 0 : _addProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::Handle<JS::Value> val)
599 : {
600 0 : mozilla::dom::IDBCursor* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::IDBCursor>(obj);
601 : // We don't want to preserve if we don't have a wrapper, and we
602 : // obviously can't preserve if we're not initialized.
603 0 : if (self && self->GetWrapperPreserveColor()) {
604 0 : PreserveWrapper(self);
605 : }
606 0 : return true;
607 : }
608 :
609 : static void
610 0 : _finalize(js::FreeOp* fop, JSObject* obj)
611 : {
612 0 : mozilla::dom::IDBCursor* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::IDBCursor>(obj);
613 0 : if (self) {
614 0 : ClearWrapper(self, self, obj);
615 0 : AddForDeferredFinalization<mozilla::dom::IDBCursor>(self);
616 : }
617 0 : }
618 :
619 : static void
620 0 : _objectMoved(JSObject* obj, const JSObject* old)
621 : {
622 0 : mozilla::dom::IDBCursor* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::IDBCursor>(obj);
623 0 : if (self) {
624 0 : UpdateWrapper(self, self, obj, old);
625 : }
626 0 : }
627 :
628 : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
629 : #if defined(__clang__)
630 : #pragma clang diagnostic push
631 : #pragma clang diagnostic ignored "-Wmissing-braces"
632 : #endif
633 : static const JSFunctionSpec sMethods_specs[] = {
634 : JS_FNSPEC("update", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&update_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
635 : JS_FNSPEC("advance", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&advance_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
636 : JS_FNSPEC("continue", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&continue_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
637 : JS_FNSPEC("continuePrimaryKey", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&continuePrimaryKey_methodinfo), 2, JSPROP_ENUMERATE, nullptr),
638 : JS_FNSPEC("delete", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&delete_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
639 : JS_FS_END
640 : };
641 : #if defined(__clang__)
642 : #pragma clang diagnostic pop
643 : #endif
644 :
645 :
646 : // Can't be const because the pref-enabled boolean needs to be writable
647 : static Prefable<const JSFunctionSpec> sMethods[] = {
648 : { nullptr, &sMethods_specs[0] },
649 : { nullptr, nullptr }
650 : };
651 :
652 : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
653 : "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
654 : static_assert(5 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
655 : "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
656 :
657 : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
658 : #if defined(__clang__)
659 : #pragma clang diagnostic push
660 : #pragma clang diagnostic ignored "-Wmissing-braces"
661 : #endif
662 : static const JSPropertySpec sAttributes_specs[] = {
663 : { "source", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &source_getterinfo, nullptr, nullptr },
664 : { "direction", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &direction_getterinfo, nullptr, nullptr },
665 : { "key", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &key_getterinfo, nullptr, nullptr },
666 : { "primaryKey", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &primaryKey_getterinfo, nullptr, nullptr },
667 : { nullptr, 0, nullptr, nullptr, nullptr, nullptr }
668 : };
669 : #if defined(__clang__)
670 : #pragma clang diagnostic pop
671 : #endif
672 :
673 :
674 : // Can't be const because the pref-enabled boolean needs to be writable
675 : static Prefable<const JSPropertySpec> sAttributes[] = {
676 : { nullptr, &sAttributes_specs[0] },
677 : { nullptr, nullptr }
678 : };
679 :
680 : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
681 : "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
682 : static_assert(4 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
683 : "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
684 :
685 :
686 : static uint16_t sNativeProperties_sortedPropertyIndices[9];
687 : static PropertyInfo sNativeProperties_propertyInfos[9];
688 :
689 : static const NativePropertiesN<2> sNativeProperties = {
690 : false, 0,
691 : false, 0,
692 : true, 0 /* sMethods */,
693 : true, 1 /* sAttributes */,
694 : false, 0,
695 : false, 0,
696 : false, 0,
697 : -1,
698 : 9,
699 : sNativeProperties_sortedPropertyIndices,
700 : {
701 : { sMethods, &sNativeProperties_propertyInfos[0] },
702 : { sAttributes, &sNativeProperties_propertyInfos[5] }
703 : }
704 : };
705 : static_assert(9 < 1ull << CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount),
706 : "We have a property info count that is oversized");
707 :
708 : static const DOMIfaceAndProtoJSClass sInterfaceObjectClass = {
709 : {
710 : "Function",
711 : JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_SLOTS_BASE),
712 : &sBoringInterfaceObjectClassClassOps,
713 : JS_NULL_CLASS_SPEC,
714 : JS_NULL_CLASS_EXT,
715 : &sInterfaceObjectClassObjectOps
716 : },
717 : eInterface,
718 : true,
719 : prototypes::id::IDBCursor,
720 : PrototypeTraits<prototypes::id::IDBCursor>::Depth,
721 : sNativePropertyHooks,
722 : "function IDBCursor() {\n [native code]\n}",
723 : JS::GetRealmFunctionPrototype
724 : };
725 :
726 : static const DOMIfaceAndProtoJSClass sPrototypeClass = {
727 : {
728 : "IDBCursorPrototype",
729 : JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE),
730 : JS_NULL_CLASS_OPS,
731 : JS_NULL_CLASS_SPEC,
732 : JS_NULL_CLASS_EXT,
733 : JS_NULL_OBJECT_OPS
734 : },
735 : eInterfacePrototype,
736 : false,
737 : prototypes::id::IDBCursor,
738 : PrototypeTraits<prototypes::id::IDBCursor>::Depth,
739 : sNativePropertyHooks,
740 : "[object IDBCursorPrototype]",
741 : JS::GetRealmObjectPrototype
742 : };
743 :
744 : JSObject*
745 0 : DefineDOMInterface(JSContext* aCx, JS::Handle<JSObject*> aGlobal, JS::Handle<jsid> id, bool aDefineOnGlobal)
746 : {
747 0 : return GetConstructorObjectHandle(aCx, aDefineOnGlobal);
748 : }
749 :
750 : static const js::ClassOps sClassOps = {
751 : _addProperty, /* addProperty */
752 : nullptr, /* delProperty */
753 : nullptr, /* getProperty */
754 : nullptr, /* setProperty */
755 : nullptr, /* enumerate */
756 : nullptr, /* newEnumerate */
757 : nullptr, /* resolve */
758 : nullptr, /* mayResolve */
759 : _finalize, /* finalize */
760 : nullptr, /* call */
761 : nullptr, /* hasInstance */
762 : nullptr, /* construct */
763 : nullptr, /* trace */
764 : };
765 :
766 : static const js::ClassExtension sClassExtension = {
767 : nullptr, /* weakmapKeyDelegateOp */
768 : _objectMoved /* objectMovedOp */
769 : };
770 :
771 : static const DOMJSClass sClass = {
772 : { "IDBCursor",
773 : JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1),
774 : &sClassOps,
775 : JS_NULL_CLASS_SPEC,
776 : &sClassExtension,
777 : JS_NULL_OBJECT_OPS
778 : },
779 : { prototypes::id::IDBCursor, 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 },
780 : IsBaseOf<nsISupports, mozilla::dom::IDBCursor >::value,
781 : sNativePropertyHooks,
782 : FindAssociatedGlobalForNative<mozilla::dom::IDBCursor>::Get,
783 : GetProtoObjectHandle,
784 : GetCCParticipant<mozilla::dom::IDBCursor>::Get()
785 : };
786 : static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
787 : "Must have the right minimal number of reserved slots.");
788 : static_assert(1 >= 1,
789 : "Must have enough reserved slots.");
790 :
791 : const JSClass*
792 0 : GetJSClass()
793 : {
794 0 : return sClass.ToJSClass();
795 : }
796 :
797 : bool
798 0 : Wrap(JSContext* aCx, mozilla::dom::IDBCursor* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
799 : {
800 : MOZ_ASSERT(static_cast<mozilla::dom::IDBCursor*>(aObject) ==
801 : reinterpret_cast<mozilla::dom::IDBCursor*>(aObject),
802 : "Multiple inheritance for mozilla::dom::IDBCursor is broken.");
803 0 : MOZ_ASSERT(ToSupportsIsCorrect(aObject));
804 0 : MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
805 0 : MOZ_ASSERT(!aCache->GetWrapper(),
806 : "You should probably not be using Wrap() directly; use "
807 : "GetOrCreateDOMReflector instead");
808 :
809 0 : MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
810 : "nsISupports must be on our primary inheritance chain");
811 :
812 0 : JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
813 0 : if (!global) {
814 0 : return false;
815 : }
816 0 : MOZ_ASSERT(JS_IsGlobalObject(global));
817 0 : MOZ_ASSERT(JS::ObjectIsNotGray(global));
818 :
819 : // That might have ended up wrapping us already, due to the wonders
820 : // of XBL. Check for that, and bail out as needed.
821 0 : aReflector.set(aCache->GetWrapper());
822 0 : if (aReflector) {
823 : #ifdef DEBUG
824 0 : binding_detail::AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
825 : #endif // DEBUG
826 0 : return true;
827 : }
828 :
829 0 : JSAutoCompartment ac(aCx, global);
830 0 : JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
831 0 : if (!canonicalProto) {
832 0 : return false;
833 : }
834 0 : JS::Rooted<JSObject*> proto(aCx);
835 0 : if (aGivenProto) {
836 0 : proto = aGivenProto;
837 : // Unfortunately, while aGivenProto was in the compartment of aCx
838 : // coming in, we changed compartments to that of "parent" so may need
839 : // to wrap the proto here.
840 0 : if (js::GetContextCompartment(aCx) != js::GetObjectCompartment(proto)) {
841 0 : if (!JS_WrapObject(aCx, &proto)) {
842 0 : return false;
843 : }
844 : }
845 : } else {
846 0 : proto = canonicalProto;
847 : }
848 :
849 0 : BindingJSObjectCreator<mozilla::dom::IDBCursor> creator(aCx);
850 0 : creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
851 0 : if (!aReflector) {
852 0 : return false;
853 : }
854 :
855 0 : aCache->SetWrapper(aReflector);
856 0 : creator.InitializationSucceeded();
857 :
858 0 : MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
859 : aCache->GetWrapperPreserveColor() == aReflector);
860 : // If proto != canonicalProto, we have to preserve our wrapper;
861 : // otherwise we won't be able to properly recreate it later, since
862 : // we won't know what proto to use. Note that we don't check
863 : // aGivenProto here, since it's entirely possible (and even
864 : // somewhat common) to have a non-null aGivenProto which is the
865 : // same as canonicalProto.
866 0 : if (proto != canonicalProto) {
867 0 : PreserveWrapper(aObject);
868 : }
869 :
870 0 : return true;
871 : }
872 :
873 : const NativePropertyHooks sNativePropertyHooks[] = { {
874 : nullptr,
875 : nullptr,
876 : nullptr,
877 : { sNativeProperties.Upcast(), nullptr },
878 : prototypes::id::IDBCursor,
879 : constructors::id::IDBCursor,
880 : nullptr,
881 : &DefaultXrayExpandoObjectClass
882 : } };
883 :
884 : void
885 15 : CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, bool aDefineOnGlobal)
886 : {
887 30 : JS::Rooted<JSObject*> parentProto(aCx, JS::GetRealmObjectPrototype(aCx));
888 15 : if (!parentProto) {
889 0 : return;
890 : }
891 :
892 30 : JS::Rooted<JSObject*> constructorProto(aCx, JS::GetRealmFunctionPrototype(aCx));
893 15 : if (!constructorProto) {
894 0 : return;
895 : }
896 :
897 : static bool sIdsInited = false;
898 15 : if (!sIdsInited && NS_IsMainThread()) {
899 1 : if (!InitIds(aCx, sNativeProperties.Upcast())) {
900 0 : return;
901 : }
902 1 : sIdsInited = true;
903 : }
904 :
905 15 : JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::IDBCursor);
906 15 : JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::IDBCursor);
907 30 : dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
908 : &sPrototypeClass.mBase, protoCache,
909 : constructorProto, &sInterfaceObjectClass.mBase, 0, nullptr,
910 : interfaceCache,
911 : sNativeProperties.Upcast(),
912 : nullptr,
913 : "IDBCursor", aDefineOnGlobal,
914 : nullptr,
915 15 : false);
916 : }
917 :
918 : JS::Handle<JSObject*>
919 15 : GetProtoObjectHandle(JSContext* aCx)
920 : {
921 : /* Get the interface prototype object for this class. This will create the
922 : object as needed. */
923 15 : bool aDefineOnGlobal = true;
924 :
925 : /* Make sure our global is sane. Hopefully we can remove this sometime */
926 15 : JSObject* global = JS::CurrentGlobalOrNull(aCx);
927 15 : if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
928 0 : return nullptr;
929 : }
930 :
931 : /* Check to see whether the interface objects are already installed */
932 15 : ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
933 15 : if (!protoAndIfaceCache.HasEntryInSlot(prototypes::id::IDBCursor)) {
934 0 : JS::Rooted<JSObject*> rootedGlobal(aCx, global);
935 0 : CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
936 : }
937 :
938 : /*
939 : * The object might _still_ be null, but that's OK.
940 : *
941 : * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
942 : * traced by TraceProtoAndIfaceCache() and its contents are never
943 : * changed after they have been set.
944 : *
945 : * Calling address() avoids the read read barrier that does gray
946 : * unmarking, but it's not possible for the object to be gray here.
947 : */
948 :
949 15 : const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(prototypes::id::IDBCursor);
950 15 : MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
951 15 : return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
952 : }
953 :
954 : JSObject*
955 0 : GetProtoObject(JSContext* aCx)
956 : {
957 0 : return GetProtoObjectHandle(aCx);
958 : }
959 :
960 : JS::Handle<JSObject*>
961 30 : GetConstructorObjectHandle(JSContext* aCx, bool aDefineOnGlobal)
962 : {
963 : /* Get the interface object for this class. This will create the object as
964 : needed. */
965 :
966 : /* Make sure our global is sane. Hopefully we can remove this sometime */
967 30 : JSObject* global = JS::CurrentGlobalOrNull(aCx);
968 30 : if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
969 0 : return nullptr;
970 : }
971 :
972 : /* Check to see whether the interface objects are already installed */
973 30 : ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
974 30 : if (!protoAndIfaceCache.HasEntryInSlot(constructors::id::IDBCursor)) {
975 30 : JS::Rooted<JSObject*> rootedGlobal(aCx, global);
976 15 : CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
977 : }
978 :
979 : /*
980 : * The object might _still_ be null, but that's OK.
981 : *
982 : * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
983 : * traced by TraceProtoAndIfaceCache() and its contents are never
984 : * changed after they have been set.
985 : *
986 : * Calling address() avoids the read read barrier that does gray
987 : * unmarking, but it's not possible for the object to be gray here.
988 : */
989 :
990 30 : const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(constructors::id::IDBCursor);
991 30 : MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
992 30 : return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
993 : }
994 :
995 : JSObject*
996 15 : GetConstructorObject(JSContext* aCx)
997 : {
998 15 : return GetConstructorObjectHandle(aCx);
999 : }
1000 :
1001 : } // namespace IDBCursorBinding
1002 :
1003 :
1004 :
1005 : namespace IDBCursorWithValueBinding {
1006 :
1007 : static_assert(IsRefcounted<NativeType>::value == IsRefcounted<IDBCursorBinding::NativeType>::value,
1008 : "Can't inherit from an interface with a different ownership model.");
1009 :
1010 : static bool
1011 0 : get_value(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::IDBCursor* self, JSJitGetterCallArgs args)
1012 : {
1013 0 : binding_detail::FastErrorResult rv;
1014 0 : JS::Rooted<JS::Value> result(cx);
1015 0 : self->GetValue(cx, &result, rv);
1016 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
1017 0 : return false;
1018 : }
1019 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
1020 0 : JS::ExposeValueToActiveJS(result);
1021 0 : args.rval().set(result);
1022 0 : if (!MaybeWrapValue(cx, args.rval())) {
1023 0 : return false;
1024 : }
1025 0 : return true;
1026 : }
1027 :
1028 : static const JSJitInfo value_getterinfo = {
1029 : { (JSJitGetterOp)get_value },
1030 : { prototypes::id::IDBCursorWithValue },
1031 : { PrototypeTraits<prototypes::id::IDBCursorWithValue>::Depth },
1032 : JSJitInfo::Getter,
1033 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
1034 : JSVAL_TYPE_UNKNOWN, /* returnType. Not relevant for setters. */
1035 : false, /* isInfallible. False in setters. */
1036 : false, /* isMovable. Not relevant for setters. */
1037 : false, /* isEliminatable. Not relevant for setters. */
1038 : false, /* isAlwaysInSlot. Only relevant for getters. */
1039 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
1040 : false, /* isTypedMethod. Only relevant for methods. */
1041 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
1042 : };
1043 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
1044 : static_assert(0 < 1, "There is no slot for us");
1045 :
1046 : static bool
1047 0 : _addProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::Handle<JS::Value> val)
1048 : {
1049 0 : mozilla::dom::IDBCursor* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::IDBCursor>(obj);
1050 : // We don't want to preserve if we don't have a wrapper, and we
1051 : // obviously can't preserve if we're not initialized.
1052 0 : if (self && self->GetWrapperPreserveColor()) {
1053 0 : PreserveWrapper(self);
1054 : }
1055 0 : return true;
1056 : }
1057 :
1058 : static void
1059 0 : _finalize(js::FreeOp* fop, JSObject* obj)
1060 : {
1061 0 : mozilla::dom::IDBCursor* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::IDBCursor>(obj);
1062 0 : if (self) {
1063 0 : ClearWrapper(self, self, obj);
1064 0 : AddForDeferredFinalization<mozilla::dom::IDBCursor>(self);
1065 : }
1066 0 : }
1067 :
1068 : static void
1069 0 : _objectMoved(JSObject* obj, const JSObject* old)
1070 : {
1071 0 : mozilla::dom::IDBCursor* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::IDBCursor>(obj);
1072 0 : if (self) {
1073 0 : UpdateWrapper(self, self, obj, old);
1074 : }
1075 0 : }
1076 :
1077 : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
1078 : #if defined(__clang__)
1079 : #pragma clang diagnostic push
1080 : #pragma clang diagnostic ignored "-Wmissing-braces"
1081 : #endif
1082 : static const JSPropertySpec sAttributes_specs[] = {
1083 : { "value", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &value_getterinfo, nullptr, nullptr },
1084 : { nullptr, 0, nullptr, nullptr, nullptr, nullptr }
1085 : };
1086 : #if defined(__clang__)
1087 : #pragma clang diagnostic pop
1088 : #endif
1089 :
1090 :
1091 : // Can't be const because the pref-enabled boolean needs to be writable
1092 : static Prefable<const JSPropertySpec> sAttributes[] = {
1093 : { nullptr, &sAttributes_specs[0] },
1094 : { nullptr, nullptr }
1095 : };
1096 :
1097 : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
1098 : "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
1099 : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
1100 : "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
1101 :
1102 :
1103 : static uint16_t sNativeProperties_sortedPropertyIndices[1];
1104 : static PropertyInfo sNativeProperties_propertyInfos[1];
1105 :
1106 : static const NativePropertiesN<1> sNativeProperties = {
1107 : false, 0,
1108 : false, 0,
1109 : false, 0,
1110 : true, 0 /* sAttributes */,
1111 : false, 0,
1112 : false, 0,
1113 : false, 0,
1114 : -1,
1115 : 1,
1116 : sNativeProperties_sortedPropertyIndices,
1117 : {
1118 : { sAttributes, &sNativeProperties_propertyInfos[0] }
1119 : }
1120 : };
1121 : static_assert(1 < 1ull << CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount),
1122 : "We have a property info count that is oversized");
1123 :
1124 : static const DOMIfaceAndProtoJSClass sInterfaceObjectClass = {
1125 : {
1126 : "Function",
1127 : JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_SLOTS_BASE),
1128 : &sBoringInterfaceObjectClassClassOps,
1129 : JS_NULL_CLASS_SPEC,
1130 : JS_NULL_CLASS_EXT,
1131 : &sInterfaceObjectClassObjectOps
1132 : },
1133 : eInterface,
1134 : true,
1135 : prototypes::id::IDBCursorWithValue,
1136 : PrototypeTraits<prototypes::id::IDBCursorWithValue>::Depth,
1137 : sNativePropertyHooks,
1138 : "function IDBCursorWithValue() {\n [native code]\n}",
1139 : IDBCursorBinding::GetConstructorObject
1140 : };
1141 :
1142 : static const DOMIfaceAndProtoJSClass sPrototypeClass = {
1143 : {
1144 : "IDBCursorWithValuePrototype",
1145 : JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE),
1146 : JS_NULL_CLASS_OPS,
1147 : JS_NULL_CLASS_SPEC,
1148 : JS_NULL_CLASS_EXT,
1149 : JS_NULL_OBJECT_OPS
1150 : },
1151 : eInterfacePrototype,
1152 : false,
1153 : prototypes::id::IDBCursorWithValue,
1154 : PrototypeTraits<prototypes::id::IDBCursorWithValue>::Depth,
1155 : sNativePropertyHooks,
1156 : "[object IDBCursorWithValuePrototype]",
1157 : IDBCursorBinding::GetProtoObject
1158 : };
1159 :
1160 : JSObject*
1161 0 : DefineDOMInterface(JSContext* aCx, JS::Handle<JSObject*> aGlobal, JS::Handle<jsid> id, bool aDefineOnGlobal)
1162 : {
1163 0 : return GetConstructorObjectHandle(aCx, aDefineOnGlobal);
1164 : }
1165 :
1166 : static const js::ClassOps sClassOps = {
1167 : _addProperty, /* addProperty */
1168 : nullptr, /* delProperty */
1169 : nullptr, /* getProperty */
1170 : nullptr, /* setProperty */
1171 : nullptr, /* enumerate */
1172 : nullptr, /* newEnumerate */
1173 : nullptr, /* resolve */
1174 : nullptr, /* mayResolve */
1175 : _finalize, /* finalize */
1176 : nullptr, /* call */
1177 : nullptr, /* hasInstance */
1178 : nullptr, /* construct */
1179 : nullptr, /* trace */
1180 : };
1181 :
1182 : static const js::ClassExtension sClassExtension = {
1183 : nullptr, /* weakmapKeyDelegateOp */
1184 : _objectMoved /* objectMovedOp */
1185 : };
1186 :
1187 : static const DOMJSClass sClass = {
1188 : { "IDBCursorWithValue",
1189 : JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1),
1190 : &sClassOps,
1191 : JS_NULL_CLASS_SPEC,
1192 : &sClassExtension,
1193 : JS_NULL_OBJECT_OPS
1194 : },
1195 : { prototypes::id::IDBCursor, prototypes::id::IDBCursorWithValue, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
1196 : IsBaseOf<nsISupports, mozilla::dom::IDBCursor >::value,
1197 : sNativePropertyHooks,
1198 : FindAssociatedGlobalForNative<mozilla::dom::IDBCursor>::Get,
1199 : GetProtoObjectHandle,
1200 : GetCCParticipant<mozilla::dom::IDBCursor>::Get()
1201 : };
1202 : static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
1203 : "Must have the right minimal number of reserved slots.");
1204 : static_assert(1 >= 1,
1205 : "Must have enough reserved slots.");
1206 :
1207 : const JSClass*
1208 0 : GetJSClass()
1209 : {
1210 0 : return sClass.ToJSClass();
1211 : }
1212 :
1213 : bool
1214 0 : Wrap(JSContext* aCx, mozilla::dom::IDBCursor* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
1215 : {
1216 : MOZ_ASSERT(static_cast<mozilla::dom::IDBCursor*>(aObject) ==
1217 : reinterpret_cast<mozilla::dom::IDBCursor*>(aObject),
1218 : "Multiple inheritance for mozilla::dom::IDBCursor is broken.");
1219 : MOZ_ASSERT(static_cast<mozilla::dom::IDBCursor*>(aObject) ==
1220 : reinterpret_cast<mozilla::dom::IDBCursor*>(aObject),
1221 : "Multiple inheritance for mozilla::dom::IDBCursor is broken.");
1222 0 : MOZ_ASSERT(ToSupportsIsCorrect(aObject));
1223 0 : MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
1224 0 : MOZ_ASSERT(!aCache->GetWrapper(),
1225 : "You should probably not be using Wrap() directly; use "
1226 : "GetOrCreateDOMReflector instead");
1227 :
1228 0 : MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
1229 : "nsISupports must be on our primary inheritance chain");
1230 :
1231 0 : JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
1232 0 : if (!global) {
1233 0 : return false;
1234 : }
1235 0 : MOZ_ASSERT(JS_IsGlobalObject(global));
1236 0 : MOZ_ASSERT(JS::ObjectIsNotGray(global));
1237 :
1238 : // That might have ended up wrapping us already, due to the wonders
1239 : // of XBL. Check for that, and bail out as needed.
1240 0 : aReflector.set(aCache->GetWrapper());
1241 0 : if (aReflector) {
1242 : #ifdef DEBUG
1243 0 : binding_detail::AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
1244 : #endif // DEBUG
1245 0 : return true;
1246 : }
1247 :
1248 0 : JSAutoCompartment ac(aCx, global);
1249 0 : JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
1250 0 : if (!canonicalProto) {
1251 0 : return false;
1252 : }
1253 0 : JS::Rooted<JSObject*> proto(aCx);
1254 0 : if (aGivenProto) {
1255 0 : proto = aGivenProto;
1256 : // Unfortunately, while aGivenProto was in the compartment of aCx
1257 : // coming in, we changed compartments to that of "parent" so may need
1258 : // to wrap the proto here.
1259 0 : if (js::GetContextCompartment(aCx) != js::GetObjectCompartment(proto)) {
1260 0 : if (!JS_WrapObject(aCx, &proto)) {
1261 0 : return false;
1262 : }
1263 : }
1264 : } else {
1265 0 : proto = canonicalProto;
1266 : }
1267 :
1268 0 : BindingJSObjectCreator<mozilla::dom::IDBCursor> creator(aCx);
1269 0 : creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
1270 0 : if (!aReflector) {
1271 0 : return false;
1272 : }
1273 :
1274 0 : aCache->SetWrapper(aReflector);
1275 0 : creator.InitializationSucceeded();
1276 :
1277 0 : MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
1278 : aCache->GetWrapperPreserveColor() == aReflector);
1279 : // If proto != canonicalProto, we have to preserve our wrapper;
1280 : // otherwise we won't be able to properly recreate it later, since
1281 : // we won't know what proto to use. Note that we don't check
1282 : // aGivenProto here, since it's entirely possible (and even
1283 : // somewhat common) to have a non-null aGivenProto which is the
1284 : // same as canonicalProto.
1285 0 : if (proto != canonicalProto) {
1286 0 : PreserveWrapper(aObject);
1287 : }
1288 :
1289 0 : return true;
1290 : }
1291 :
1292 : const NativePropertyHooks sNativePropertyHooks[] = { {
1293 : nullptr,
1294 : nullptr,
1295 : nullptr,
1296 : { sNativeProperties.Upcast(), nullptr },
1297 : prototypes::id::IDBCursorWithValue,
1298 : constructors::id::IDBCursorWithValue,
1299 : IDBCursorBinding::sNativePropertyHooks,
1300 : &DefaultXrayExpandoObjectClass
1301 : } };
1302 :
1303 : void
1304 15 : CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, bool aDefineOnGlobal)
1305 : {
1306 15 : JS::Handle<JSObject*> parentProto(IDBCursorBinding::GetProtoObjectHandle(aCx));
1307 15 : if (!parentProto) {
1308 0 : return;
1309 : }
1310 :
1311 15 : JS::Handle<JSObject*> constructorProto(IDBCursorBinding::GetConstructorObjectHandle(aCx));
1312 15 : if (!constructorProto) {
1313 0 : return;
1314 : }
1315 :
1316 : static bool sIdsInited = false;
1317 15 : if (!sIdsInited && NS_IsMainThread()) {
1318 1 : if (!InitIds(aCx, sNativeProperties.Upcast())) {
1319 0 : return;
1320 : }
1321 1 : sIdsInited = true;
1322 : }
1323 :
1324 15 : JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::IDBCursorWithValue);
1325 15 : JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::IDBCursorWithValue);
1326 15 : dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
1327 : &sPrototypeClass.mBase, protoCache,
1328 : constructorProto, &sInterfaceObjectClass.mBase, 0, nullptr,
1329 : interfaceCache,
1330 : sNativeProperties.Upcast(),
1331 : nullptr,
1332 : "IDBCursorWithValue", aDefineOnGlobal,
1333 : nullptr,
1334 15 : false);
1335 : }
1336 :
1337 : JS::Handle<JSObject*>
1338 0 : GetProtoObjectHandle(JSContext* aCx)
1339 : {
1340 : /* Get the interface prototype object for this class. This will create the
1341 : object as needed. */
1342 0 : bool aDefineOnGlobal = true;
1343 :
1344 : /* Make sure our global is sane. Hopefully we can remove this sometime */
1345 0 : JSObject* global = JS::CurrentGlobalOrNull(aCx);
1346 0 : if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
1347 0 : return nullptr;
1348 : }
1349 :
1350 : /* Check to see whether the interface objects are already installed */
1351 0 : ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
1352 0 : if (!protoAndIfaceCache.HasEntryInSlot(prototypes::id::IDBCursorWithValue)) {
1353 0 : JS::Rooted<JSObject*> rootedGlobal(aCx, global);
1354 0 : CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
1355 : }
1356 :
1357 : /*
1358 : * The object might _still_ be null, but that's OK.
1359 : *
1360 : * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
1361 : * traced by TraceProtoAndIfaceCache() and its contents are never
1362 : * changed after they have been set.
1363 : *
1364 : * Calling address() avoids the read read barrier that does gray
1365 : * unmarking, but it's not possible for the object to be gray here.
1366 : */
1367 :
1368 0 : const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(prototypes::id::IDBCursorWithValue);
1369 0 : MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
1370 0 : return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
1371 : }
1372 :
1373 : JS::Handle<JSObject*>
1374 15 : GetConstructorObjectHandle(JSContext* aCx, bool aDefineOnGlobal)
1375 : {
1376 : /* Get the interface object for this class. This will create the object as
1377 : needed. */
1378 :
1379 : /* Make sure our global is sane. Hopefully we can remove this sometime */
1380 15 : JSObject* global = JS::CurrentGlobalOrNull(aCx);
1381 15 : if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
1382 0 : return nullptr;
1383 : }
1384 :
1385 : /* Check to see whether the interface objects are already installed */
1386 15 : ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
1387 15 : if (!protoAndIfaceCache.HasEntryInSlot(constructors::id::IDBCursorWithValue)) {
1388 30 : JS::Rooted<JSObject*> rootedGlobal(aCx, global);
1389 15 : CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
1390 : }
1391 :
1392 : /*
1393 : * The object might _still_ be null, but that's OK.
1394 : *
1395 : * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
1396 : * traced by TraceProtoAndIfaceCache() and its contents are never
1397 : * changed after they have been set.
1398 : *
1399 : * Calling address() avoids the read read barrier that does gray
1400 : * unmarking, but it's not possible for the object to be gray here.
1401 : */
1402 :
1403 15 : const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(constructors::id::IDBCursorWithValue);
1404 15 : MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
1405 15 : return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
1406 : }
1407 :
1408 : JSObject*
1409 15 : GetConstructorObject(JSContext* aCx)
1410 : {
1411 15 : return GetConstructorObjectHandle(aCx);
1412 : }
1413 :
1414 : } // namespace IDBCursorWithValueBinding
1415 :
1416 :
1417 :
1418 : } // namespace dom
1419 : } // namespace mozilla
|