Line data Source code
1 : /* THIS FILE IS AUTOGENERATED FROM History.webidl BY Codegen.py - DO NOT EDIT */
2 :
3 : #include "HistoryBinding.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/NonRefcountedDOMObject.h"
10 : #include "mozilla/dom/Nullable.h"
11 : #include "mozilla/dom/PrimitiveConversions.h"
12 : #include "mozilla/dom/XrayExpandoClass.h"
13 : #include "nsHistory.h"
14 : #include "nsISupports.h"
15 : #include "xpcjsid.h"
16 :
17 : namespace mozilla {
18 : namespace dom {
19 :
20 : namespace ScrollRestorationValues {
21 : extern const EnumEntry strings[3] = {
22 : {"auto", 4},
23 : {"manual", 6},
24 : { nullptr, 0 }
25 : };
26 : } // namespace ScrollRestorationValues
27 :
28 : bool
29 0 : ToJSValue(JSContext* aCx, ScrollRestoration aArgument, JS::MutableHandle<JS::Value> aValue)
30 : {
31 0 : MOZ_ASSERT(uint32_t(aArgument) < ArrayLength(ScrollRestorationValues::strings));
32 : JSString* resultStr =
33 0 : JS_NewStringCopyN(aCx, ScrollRestorationValues::strings[uint32_t(aArgument)].value,
34 0 : ScrollRestorationValues::strings[uint32_t(aArgument)].length);
35 0 : if (!resultStr) {
36 0 : return false;
37 : }
38 0 : aValue.setString(resultStr);
39 0 : return true;
40 : }
41 :
42 :
43 : namespace HistoryBinding {
44 :
45 : static bool
46 0 : get_length(JSContext* cx, JS::Handle<JSObject*> obj, nsHistory* self, JSJitGetterCallArgs args)
47 : {
48 0 : binding_detail::FastErrorResult rv;
49 0 : uint32_t result(self->GetLength(rv));
50 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
51 0 : return false;
52 : }
53 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
54 0 : args.rval().setNumber(result);
55 0 : return true;
56 : }
57 :
58 : static const JSJitInfo length_getterinfo = {
59 : { (JSJitGetterOp)get_length },
60 : { prototypes::id::History },
61 : { PrototypeTraits<prototypes::id::History>::Depth },
62 : JSJitInfo::Getter,
63 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
64 : JSVAL_TYPE_DOUBLE, /* returnType. Not relevant for setters. */
65 : false, /* isInfallible. False in setters. */
66 : false, /* isMovable. Not relevant for setters. */
67 : false, /* isEliminatable. Not relevant for setters. */
68 : false, /* isAlwaysInSlot. Only relevant for getters. */
69 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
70 : false, /* isTypedMethod. Only relevant for methods. */
71 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
72 : };
73 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
74 : static_assert(0 < 1, "There is no slot for us");
75 :
76 : static bool
77 0 : get_scrollRestoration(JSContext* cx, JS::Handle<JSObject*> obj, nsHistory* self, JSJitGetterCallArgs args)
78 : {
79 0 : binding_detail::FastErrorResult rv;
80 0 : ScrollRestoration result(self->GetScrollRestoration(rv));
81 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
82 0 : return false;
83 : }
84 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
85 0 : if (!ToJSValue(cx, result, args.rval())) {
86 0 : return false;
87 : }
88 0 : return true;
89 : }
90 :
91 : static bool
92 0 : set_scrollRestoration(JSContext* cx, JS::Handle<JSObject*> obj, nsHistory* self, JSJitSetterCallArgs args)
93 : {
94 : ScrollRestoration arg0;
95 : {
96 : int index;
97 0 : if (!FindEnumStringIndex<false>(cx, args[0], ScrollRestorationValues::strings, "ScrollRestoration", "Value being assigned to History.scrollRestoration", &index)) {
98 0 : return false;
99 : }
100 0 : if (index < 0) {
101 0 : return true;
102 : }
103 0 : arg0 = static_cast<ScrollRestoration>(index);
104 : }
105 0 : binding_detail::FastErrorResult rv;
106 0 : self->SetScrollRestoration(arg0, rv);
107 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
108 0 : return false;
109 : }
110 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
111 :
112 0 : return true;
113 : }
114 :
115 : static const JSJitInfo scrollRestoration_getterinfo = {
116 : { (JSJitGetterOp)get_scrollRestoration },
117 : { prototypes::id::History },
118 : { PrototypeTraits<prototypes::id::History>::Depth },
119 : JSJitInfo::Getter,
120 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
121 : JSVAL_TYPE_STRING, /* returnType. Not relevant for setters. */
122 : false, /* isInfallible. False in setters. */
123 : false, /* isMovable. Not relevant for setters. */
124 : false, /* isEliminatable. Not relevant for setters. */
125 : false, /* isAlwaysInSlot. Only relevant for getters. */
126 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
127 : false, /* isTypedMethod. Only relevant for methods. */
128 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
129 : };
130 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
131 : static_assert(0 < 1, "There is no slot for us");
132 : static const JSJitInfo scrollRestoration_setterinfo = {
133 : { (JSJitGetterOp)set_scrollRestoration },
134 : { prototypes::id::History },
135 : { PrototypeTraits<prototypes::id::History>::Depth },
136 : JSJitInfo::Setter,
137 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
138 : JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
139 : false, /* isInfallible. False in setters. */
140 : false, /* isMovable. Not relevant for setters. */
141 : false, /* isEliminatable. Not relevant for setters. */
142 : false, /* isAlwaysInSlot. Only relevant for getters. */
143 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
144 : false, /* isTypedMethod. Only relevant for methods. */
145 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
146 : };
147 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
148 : static_assert(0 < 1, "There is no slot for us");
149 :
150 : static bool
151 0 : get_state(JSContext* cx, JS::Handle<JSObject*> obj, nsHistory* self, JSJitGetterCallArgs args)
152 : {
153 0 : binding_detail::FastErrorResult rv;
154 0 : JS::Rooted<JS::Value> result(cx);
155 0 : self->GetState(cx, &result, rv);
156 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
157 0 : return false;
158 : }
159 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
160 0 : JS::ExposeValueToActiveJS(result);
161 0 : args.rval().set(result);
162 0 : if (!MaybeWrapValue(cx, args.rval())) {
163 0 : return false;
164 : }
165 0 : return true;
166 : }
167 :
168 : static const JSJitInfo state_getterinfo = {
169 : { (JSJitGetterOp)get_state },
170 : { prototypes::id::History },
171 : { PrototypeTraits<prototypes::id::History>::Depth },
172 : JSJitInfo::Getter,
173 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
174 : JSVAL_TYPE_UNKNOWN, /* returnType. Not relevant for setters. */
175 : false, /* isInfallible. False in setters. */
176 : false, /* isMovable. Not relevant for setters. */
177 : false, /* isEliminatable. Not relevant for setters. */
178 : false, /* isAlwaysInSlot. Only relevant for getters. */
179 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
180 : false, /* isTypedMethod. Only relevant for methods. */
181 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
182 : };
183 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
184 : static_assert(0 < 1, "There is no slot for us");
185 :
186 : static bool
187 0 : go(JSContext* cx, JS::Handle<JSObject*> obj, nsHistory* self, const JSJitMethodCallArgs& args)
188 : {
189 0 : if (!mozilla::dom::EnforceNotInPrerendering(cx, obj)) {
190 : // Return false from the JSNative in order to trigger
191 : // an uncatchable exception.
192 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
193 0 : return false;
194 : }
195 : int32_t arg0;
196 0 : if (args.hasDefined(0)) {
197 0 : if (!ValueToPrimitive<int32_t, eDefault>(cx, args[0], &arg0)) {
198 0 : return false;
199 : }
200 : } else {
201 0 : arg0 = 0;
202 : }
203 0 : binding_detail::FastErrorResult rv;
204 0 : self->Go(arg0, rv);
205 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
206 0 : return false;
207 : }
208 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
209 0 : args.rval().setUndefined();
210 0 : return true;
211 : }
212 :
213 : static const JSJitInfo go_methodinfo = {
214 : { (JSJitGetterOp)go },
215 : { prototypes::id::History },
216 : { PrototypeTraits<prototypes::id::History>::Depth },
217 : JSJitInfo::Method,
218 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
219 : JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
220 : false, /* isInfallible. False in setters. */
221 : false, /* isMovable. Not relevant for setters. */
222 : false, /* isEliminatable. Not relevant for setters. */
223 : false, /* isAlwaysInSlot. Only relevant for getters. */
224 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
225 : false, /* isTypedMethod. Only relevant for methods. */
226 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
227 : };
228 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
229 : static_assert(0 < 1, "There is no slot for us");
230 :
231 : static bool
232 0 : back(JSContext* cx, JS::Handle<JSObject*> obj, nsHistory* self, const JSJitMethodCallArgs& args)
233 : {
234 0 : if (!mozilla::dom::EnforceNotInPrerendering(cx, obj)) {
235 : // Return false from the JSNative in order to trigger
236 : // an uncatchable exception.
237 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
238 0 : return false;
239 : }
240 0 : binding_detail::FastErrorResult rv;
241 0 : self->Back(rv);
242 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
243 0 : return false;
244 : }
245 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
246 0 : args.rval().setUndefined();
247 0 : return true;
248 : }
249 :
250 : static const JSJitInfo back_methodinfo = {
251 : { (JSJitGetterOp)back },
252 : { prototypes::id::History },
253 : { PrototypeTraits<prototypes::id::History>::Depth },
254 : JSJitInfo::Method,
255 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
256 : JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
257 : false, /* isInfallible. False in setters. */
258 : false, /* isMovable. Not relevant for setters. */
259 : false, /* isEliminatable. Not relevant for setters. */
260 : false, /* isAlwaysInSlot. Only relevant for getters. */
261 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
262 : false, /* isTypedMethod. Only relevant for methods. */
263 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
264 : };
265 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
266 : static_assert(0 < 1, "There is no slot for us");
267 :
268 : static bool
269 0 : forward(JSContext* cx, JS::Handle<JSObject*> obj, nsHistory* self, const JSJitMethodCallArgs& args)
270 : {
271 0 : if (!mozilla::dom::EnforceNotInPrerendering(cx, obj)) {
272 : // Return false from the JSNative in order to trigger
273 : // an uncatchable exception.
274 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
275 0 : return false;
276 : }
277 0 : binding_detail::FastErrorResult rv;
278 0 : self->Forward(rv);
279 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
280 0 : return false;
281 : }
282 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
283 0 : args.rval().setUndefined();
284 0 : return true;
285 : }
286 :
287 : static const JSJitInfo forward_methodinfo = {
288 : { (JSJitGetterOp)forward },
289 : { prototypes::id::History },
290 : { PrototypeTraits<prototypes::id::History>::Depth },
291 : JSJitInfo::Method,
292 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
293 : JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
294 : false, /* isInfallible. False in setters. */
295 : false, /* isMovable. Not relevant for setters. */
296 : false, /* isEliminatable. Not relevant for setters. */
297 : false, /* isAlwaysInSlot. Only relevant for getters. */
298 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
299 : false, /* isTypedMethod. Only relevant for methods. */
300 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
301 : };
302 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
303 : static_assert(0 < 1, "There is no slot for us");
304 :
305 : static bool
306 0 : pushState(JSContext* cx, JS::Handle<JSObject*> obj, nsHistory* self, const JSJitMethodCallArgs& args)
307 : {
308 0 : if (MOZ_UNLIKELY(args.length() < 2)) {
309 0 : return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "History.pushState");
310 : }
311 0 : JS::Rooted<JS::Value> arg0(cx);
312 0 : arg0 = args[0];
313 0 : binding_detail::FakeString arg1;
314 0 : if (!ConvertJSValueToString(cx, args[1], eStringify, eStringify, arg1)) {
315 0 : return false;
316 : }
317 0 : binding_detail::FakeString arg2;
318 0 : if (args.hasDefined(2)) {
319 0 : if (!ConvertJSValueToString(cx, args[2], eNull, eNull, arg2)) {
320 0 : return false;
321 : }
322 : } else {
323 0 : arg2.SetIsVoid(true);
324 : }
325 0 : binding_detail::FastErrorResult rv;
326 0 : self->PushState(cx, arg0, NonNullHelper(Constify(arg1)), NonNullHelper(Constify(arg2)), rv);
327 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
328 0 : return false;
329 : }
330 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
331 0 : args.rval().setUndefined();
332 0 : return true;
333 : }
334 :
335 : static const JSJitInfo pushState_methodinfo = {
336 : { (JSJitGetterOp)pushState },
337 : { prototypes::id::History },
338 : { PrototypeTraits<prototypes::id::History>::Depth },
339 : JSJitInfo::Method,
340 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
341 : JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
342 : false, /* isInfallible. False in setters. */
343 : false, /* isMovable. Not relevant for setters. */
344 : false, /* isEliminatable. Not relevant for setters. */
345 : false, /* isAlwaysInSlot. Only relevant for getters. */
346 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
347 : false, /* isTypedMethod. Only relevant for methods. */
348 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
349 : };
350 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
351 : static_assert(0 < 1, "There is no slot for us");
352 :
353 : static bool
354 0 : replaceState(JSContext* cx, JS::Handle<JSObject*> obj, nsHistory* self, const JSJitMethodCallArgs& args)
355 : {
356 0 : if (MOZ_UNLIKELY(args.length() < 2)) {
357 0 : return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "History.replaceState");
358 : }
359 0 : JS::Rooted<JS::Value> arg0(cx);
360 0 : arg0 = args[0];
361 0 : binding_detail::FakeString arg1;
362 0 : if (!ConvertJSValueToString(cx, args[1], eStringify, eStringify, arg1)) {
363 0 : return false;
364 : }
365 0 : binding_detail::FakeString arg2;
366 0 : if (args.hasDefined(2)) {
367 0 : if (!ConvertJSValueToString(cx, args[2], eNull, eNull, arg2)) {
368 0 : return false;
369 : }
370 : } else {
371 0 : arg2.SetIsVoid(true);
372 : }
373 0 : binding_detail::FastErrorResult rv;
374 0 : self->ReplaceState(cx, arg0, NonNullHelper(Constify(arg1)), NonNullHelper(Constify(arg2)), rv);
375 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
376 0 : return false;
377 : }
378 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
379 0 : args.rval().setUndefined();
380 0 : return true;
381 : }
382 :
383 : static const JSJitInfo replaceState_methodinfo = {
384 : { (JSJitGetterOp)replaceState },
385 : { prototypes::id::History },
386 : { PrototypeTraits<prototypes::id::History>::Depth },
387 : JSJitInfo::Method,
388 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
389 : JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
390 : false, /* isInfallible. False in setters. */
391 : false, /* isMovable. Not relevant for setters. */
392 : false, /* isEliminatable. Not relevant for setters. */
393 : false, /* isAlwaysInSlot. Only relevant for getters. */
394 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
395 : false, /* isTypedMethod. Only relevant for methods. */
396 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
397 : };
398 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
399 : static_assert(0 < 1, "There is no slot for us");
400 :
401 : static bool
402 0 : _addProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::Handle<JS::Value> val)
403 : {
404 0 : nsHistory* self = UnwrapPossiblyNotInitializedDOMObject<nsHistory>(obj);
405 : // We don't want to preserve if we don't have a wrapper, and we
406 : // obviously can't preserve if we're not initialized.
407 0 : if (self && self->GetWrapperPreserveColor()) {
408 0 : PreserveWrapper(self);
409 : }
410 0 : return true;
411 : }
412 :
413 : static void
414 0 : _finalize(js::FreeOp* fop, JSObject* obj)
415 : {
416 0 : nsHistory* self = UnwrapPossiblyNotInitializedDOMObject<nsHistory>(obj);
417 0 : if (self) {
418 0 : ClearWrapper(self, self, obj);
419 0 : AddForDeferredFinalization<nsHistory>(self);
420 : }
421 0 : }
422 :
423 : static void
424 0 : _objectMoved(JSObject* obj, const JSObject* old)
425 : {
426 0 : nsHistory* self = UnwrapPossiblyNotInitializedDOMObject<nsHistory>(obj);
427 0 : if (self) {
428 0 : UpdateWrapper(self, self, obj, old);
429 : }
430 0 : }
431 :
432 : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
433 : #if defined(__clang__)
434 : #pragma clang diagnostic push
435 : #pragma clang diagnostic ignored "-Wmissing-braces"
436 : #endif
437 : static const JSFunctionSpec sMethods_specs[] = {
438 : JS_FNSPEC("go", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&go_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
439 : JS_FNSPEC("back", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&back_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
440 : JS_FNSPEC("forward", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&forward_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
441 : JS_FNSPEC("pushState", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&pushState_methodinfo), 2, JSPROP_ENUMERATE, nullptr),
442 : JS_FNSPEC("replaceState", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&replaceState_methodinfo), 2, JSPROP_ENUMERATE, nullptr),
443 : JS_FS_END,
444 : JS_FNSPEC("QueryInterface", QueryInterface, nullptr, 1, 0, nullptr),
445 : JS_FS_END
446 : };
447 : #if defined(__clang__)
448 : #pragma clang diagnostic pop
449 : #endif
450 :
451 : static PrefableDisablers sMethods_disablers6 = {
452 : true, false, 0, &WantsQueryInterface<nsHistory>::Enabled
453 : };
454 :
455 : // Can't be const because the pref-enabled boolean needs to be writable
456 : static Prefable<const JSFunctionSpec> sMethods[] = {
457 : { nullptr, &sMethods_specs[0] },
458 : { &sMethods_disablers6, &sMethods_specs[6] },
459 : { nullptr, nullptr }
460 : };
461 :
462 : static_assert(2 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
463 : "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
464 : static_assert(5 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
465 : "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
466 :
467 : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
468 : #if defined(__clang__)
469 : #pragma clang diagnostic push
470 : #pragma clang diagnostic ignored "-Wmissing-braces"
471 : #endif
472 : static const JSPropertySpec sAttributes_specs[] = {
473 : { "length", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &length_getterinfo, nullptr, nullptr },
474 : { "scrollRestoration", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &scrollRestoration_getterinfo, GenericBindingSetter, &scrollRestoration_setterinfo },
475 : { "state", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &state_getterinfo, nullptr, nullptr },
476 : { nullptr, 0, nullptr, nullptr, nullptr, nullptr }
477 : };
478 : #if defined(__clang__)
479 : #pragma clang diagnostic pop
480 : #endif
481 :
482 :
483 : // Can't be const because the pref-enabled boolean needs to be writable
484 : static Prefable<const JSPropertySpec> sAttributes[] = {
485 : { nullptr, &sAttributes_specs[0] },
486 : { nullptr, nullptr }
487 : };
488 :
489 : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
490 : "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
491 : static_assert(3 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
492 : "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
493 :
494 :
495 : static uint16_t sNativeProperties_sortedPropertyIndices[9];
496 : static PropertyInfo sNativeProperties_propertyInfos[9];
497 :
498 : static const NativePropertiesN<2> sNativeProperties = {
499 : false, 0,
500 : false, 0,
501 : true, 0 /* sMethods */,
502 : true, 1 /* sAttributes */,
503 : false, 0,
504 : false, 0,
505 : false, 0,
506 : -1,
507 : 9,
508 : sNativeProperties_sortedPropertyIndices,
509 : {
510 : { sMethods, &sNativeProperties_propertyInfos[0] },
511 : { sAttributes, &sNativeProperties_propertyInfos[6] }
512 : }
513 : };
514 : static_assert(9 < 1ull << CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount),
515 : "We have a property info count that is oversized");
516 :
517 : static const DOMIfaceAndProtoJSClass sInterfaceObjectClass = {
518 : {
519 : "Function",
520 : JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_SLOTS_BASE),
521 : &sBoringInterfaceObjectClassClassOps,
522 : JS_NULL_CLASS_SPEC,
523 : JS_NULL_CLASS_EXT,
524 : &sInterfaceObjectClassObjectOps
525 : },
526 : eInterface,
527 : true,
528 : prototypes::id::History,
529 : PrototypeTraits<prototypes::id::History>::Depth,
530 : sNativePropertyHooks,
531 : "function History() {\n [native code]\n}",
532 : JS::GetRealmFunctionPrototype
533 : };
534 :
535 : static const DOMIfaceAndProtoJSClass sPrototypeClass = {
536 : {
537 : "HistoryPrototype",
538 : JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE),
539 : JS_NULL_CLASS_OPS,
540 : JS_NULL_CLASS_SPEC,
541 : JS_NULL_CLASS_EXT,
542 : JS_NULL_OBJECT_OPS
543 : },
544 : eInterfacePrototype,
545 : false,
546 : prototypes::id::History,
547 : PrototypeTraits<prototypes::id::History>::Depth,
548 : sNativePropertyHooks,
549 : "[object HistoryPrototype]",
550 : JS::GetRealmObjectPrototype
551 : };
552 :
553 : JSObject*
554 0 : DefineDOMInterface(JSContext* aCx, JS::Handle<JSObject*> aGlobal, JS::Handle<jsid> id, bool aDefineOnGlobal)
555 : {
556 0 : return GetConstructorObjectHandle(aCx, aDefineOnGlobal);
557 : }
558 :
559 : static const js::ClassOps sClassOps = {
560 : _addProperty, /* addProperty */
561 : nullptr, /* delProperty */
562 : nullptr, /* getProperty */
563 : nullptr, /* setProperty */
564 : nullptr, /* enumerate */
565 : nullptr, /* newEnumerate */
566 : nullptr, /* resolve */
567 : nullptr, /* mayResolve */
568 : _finalize, /* finalize */
569 : nullptr, /* call */
570 : nullptr, /* hasInstance */
571 : nullptr, /* construct */
572 : nullptr, /* trace */
573 : };
574 :
575 : static const js::ClassExtension sClassExtension = {
576 : nullptr, /* weakmapKeyDelegateOp */
577 : _objectMoved /* objectMovedOp */
578 : };
579 :
580 : static const DOMJSClass sClass = {
581 : { "History",
582 : JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1),
583 : &sClassOps,
584 : JS_NULL_CLASS_SPEC,
585 : &sClassExtension,
586 : JS_NULL_OBJECT_OPS
587 : },
588 : { prototypes::id::History, 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 },
589 : IsBaseOf<nsISupports, nsHistory >::value,
590 : sNativePropertyHooks,
591 : FindAssociatedGlobalForNative<nsHistory>::Get,
592 : GetProtoObjectHandle,
593 : GetCCParticipant<nsHistory>::Get()
594 : };
595 : static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
596 : "Must have the right minimal number of reserved slots.");
597 : static_assert(1 >= 1,
598 : "Must have enough reserved slots.");
599 :
600 : const JSClass*
601 0 : GetJSClass()
602 : {
603 0 : return sClass.ToJSClass();
604 : }
605 :
606 : bool
607 0 : Wrap(JSContext* aCx, nsHistory* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
608 : {
609 : MOZ_ASSERT(static_cast<nsHistory*>(aObject) ==
610 : reinterpret_cast<nsHistory*>(aObject),
611 : "Multiple inheritance for nsHistory is broken.");
612 0 : MOZ_ASSERT(ToSupportsIsCorrect(aObject));
613 0 : MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
614 0 : MOZ_ASSERT(!aCache->GetWrapper(),
615 : "You should probably not be using Wrap() directly; use "
616 : "GetOrCreateDOMReflector instead");
617 :
618 0 : MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
619 : "nsISupports must be on our primary inheritance chain");
620 :
621 0 : JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
622 0 : if (!global) {
623 0 : return false;
624 : }
625 0 : MOZ_ASSERT(JS_IsGlobalObject(global));
626 0 : MOZ_ASSERT(JS::ObjectIsNotGray(global));
627 :
628 : // That might have ended up wrapping us already, due to the wonders
629 : // of XBL. Check for that, and bail out as needed.
630 0 : aReflector.set(aCache->GetWrapper());
631 0 : if (aReflector) {
632 : #ifdef DEBUG
633 0 : binding_detail::AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
634 : #endif // DEBUG
635 0 : return true;
636 : }
637 :
638 0 : JSAutoCompartment ac(aCx, global);
639 0 : JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
640 0 : if (!canonicalProto) {
641 0 : return false;
642 : }
643 0 : JS::Rooted<JSObject*> proto(aCx);
644 0 : if (aGivenProto) {
645 0 : proto = aGivenProto;
646 : // Unfortunately, while aGivenProto was in the compartment of aCx
647 : // coming in, we changed compartments to that of "parent" so may need
648 : // to wrap the proto here.
649 0 : if (js::GetContextCompartment(aCx) != js::GetObjectCompartment(proto)) {
650 0 : if (!JS_WrapObject(aCx, &proto)) {
651 0 : return false;
652 : }
653 : }
654 : } else {
655 0 : proto = canonicalProto;
656 : }
657 :
658 0 : BindingJSObjectCreator<nsHistory> creator(aCx);
659 0 : creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
660 0 : if (!aReflector) {
661 0 : return false;
662 : }
663 :
664 0 : aCache->SetWrapper(aReflector);
665 0 : creator.InitializationSucceeded();
666 :
667 0 : MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
668 : aCache->GetWrapperPreserveColor() == aReflector);
669 : // If proto != canonicalProto, we have to preserve our wrapper;
670 : // otherwise we won't be able to properly recreate it later, since
671 : // we won't know what proto to use. Note that we don't check
672 : // aGivenProto here, since it's entirely possible (and even
673 : // somewhat common) to have a non-null aGivenProto which is the
674 : // same as canonicalProto.
675 0 : if (proto != canonicalProto) {
676 0 : PreserveWrapper(aObject);
677 : }
678 :
679 0 : return true;
680 : }
681 :
682 : const NativePropertyHooks sNativePropertyHooks[] = { {
683 : nullptr,
684 : nullptr,
685 : nullptr,
686 : { sNativeProperties.Upcast(), nullptr },
687 : prototypes::id::History,
688 : constructors::id::History,
689 : nullptr,
690 : &DefaultXrayExpandoObjectClass
691 : } };
692 :
693 : void
694 0 : CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, bool aDefineOnGlobal)
695 : {
696 0 : JS::Rooted<JSObject*> parentProto(aCx, JS::GetRealmObjectPrototype(aCx));
697 0 : if (!parentProto) {
698 0 : return;
699 : }
700 :
701 0 : JS::Rooted<JSObject*> constructorProto(aCx, JS::GetRealmFunctionPrototype(aCx));
702 0 : if (!constructorProto) {
703 0 : return;
704 : }
705 :
706 : static bool sIdsInited = false;
707 0 : if (!sIdsInited && NS_IsMainThread()) {
708 0 : if (!InitIds(aCx, sNativeProperties.Upcast())) {
709 0 : return;
710 : }
711 0 : sIdsInited = true;
712 : }
713 :
714 0 : JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::History);
715 0 : JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::History);
716 0 : dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
717 : &sPrototypeClass.mBase, protoCache,
718 : constructorProto, &sInterfaceObjectClass.mBase, 0, nullptr,
719 : interfaceCache,
720 : sNativeProperties.Upcast(),
721 : nullptr,
722 : "History", aDefineOnGlobal,
723 : nullptr,
724 0 : false);
725 : }
726 :
727 : JS::Handle<JSObject*>
728 0 : GetProtoObjectHandle(JSContext* aCx)
729 : {
730 : /* Get the interface prototype object for this class. This will create the
731 : object as needed. */
732 0 : bool aDefineOnGlobal = true;
733 :
734 : /* Make sure our global is sane. Hopefully we can remove this sometime */
735 0 : JSObject* global = JS::CurrentGlobalOrNull(aCx);
736 0 : if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
737 0 : return nullptr;
738 : }
739 :
740 : /* Check to see whether the interface objects are already installed */
741 0 : ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
742 0 : if (!protoAndIfaceCache.HasEntryInSlot(prototypes::id::History)) {
743 0 : JS::Rooted<JSObject*> rootedGlobal(aCx, global);
744 0 : CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
745 : }
746 :
747 : /*
748 : * The object might _still_ be null, but that's OK.
749 : *
750 : * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
751 : * traced by TraceProtoAndIfaceCache() and its contents are never
752 : * changed after they have been set.
753 : *
754 : * Calling address() avoids the read read barrier that does gray
755 : * unmarking, but it's not possible for the object to be gray here.
756 : */
757 :
758 0 : const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(prototypes::id::History);
759 0 : MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
760 0 : return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
761 : }
762 :
763 : JS::Handle<JSObject*>
764 0 : GetConstructorObjectHandle(JSContext* aCx, bool aDefineOnGlobal)
765 : {
766 : /* Get the interface object for this class. This will create the object as
767 : needed. */
768 :
769 : /* Make sure our global is sane. Hopefully we can remove this sometime */
770 0 : JSObject* global = JS::CurrentGlobalOrNull(aCx);
771 0 : if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
772 0 : return nullptr;
773 : }
774 :
775 : /* Check to see whether the interface objects are already installed */
776 0 : ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
777 0 : if (!protoAndIfaceCache.HasEntryInSlot(constructors::id::History)) {
778 0 : JS::Rooted<JSObject*> rootedGlobal(aCx, global);
779 0 : CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
780 : }
781 :
782 : /*
783 : * The object might _still_ be null, but that's OK.
784 : *
785 : * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
786 : * traced by TraceProtoAndIfaceCache() and its contents are never
787 : * changed after they have been set.
788 : *
789 : * Calling address() avoids the read read barrier that does gray
790 : * unmarking, but it's not possible for the object to be gray here.
791 : */
792 :
793 0 : const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(constructors::id::History);
794 0 : MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
795 0 : return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
796 : }
797 :
798 : JSObject*
799 0 : GetConstructorObject(JSContext* aCx)
800 : {
801 0 : return GetConstructorObjectHandle(aCx);
802 : }
803 :
804 : } // namespace HistoryBinding
805 :
806 :
807 :
808 : } // namespace dom
809 : } // namespace mozilla
|