Line data Source code
1 : /* THIS FILE IS AUTOGENERATED FROM HTMLCanvasElement.webidl BY Codegen.py - DO NOT EDIT */
2 :
3 : #include "HTMLCanvasElementBinding.h"
4 : #include "HTMLElementBinding.h"
5 : #include "WrapperFactory.h"
6 : #include "mozilla/FloatingPoint.h"
7 : #include "mozilla/OwningNonNull.h"
8 : #include "mozilla/Preferences.h"
9 : #include "mozilla/dom/BindingUtils.h"
10 : #include "mozilla/dom/Blob.h"
11 : #include "mozilla/dom/CanvasCaptureMediaStream.h"
12 : #include "mozilla/dom/CustomElementRegistry.h"
13 : #include "mozilla/dom/DOMJSClass.h"
14 : #include "mozilla/dom/File.h"
15 : #include "mozilla/dom/HTMLCanvasElement.h"
16 : #include "mozilla/dom/NonRefcountedDOMObject.h"
17 : #include "mozilla/dom/Nullable.h"
18 : #include "mozilla/dom/OffscreenCanvas.h"
19 : #include "mozilla/dom/PrimitiveConversions.h"
20 : #include "mozilla/dom/XrayExpandoClass.h"
21 : #include "nsContentUtils.h"
22 : #include "nsISupports.h"
23 :
24 : namespace mozilla {
25 : namespace dom {
26 :
27 : void
28 0 : PrintCallback::Call(JSContext* cx, JS::Handle<JS::Value> aThisVal, HTMLCanvasPrintState& ctx, ErrorResult& aRv)
29 : {
30 0 : JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
31 0 : JS::AutoValueVector argv(cx);
32 0 : if (!argv.resize(1)) {
33 0 : aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
34 0 : return;
35 : }
36 0 : unsigned argc = 1;
37 :
38 : do {
39 0 : if (!GetOrCreateDOMReflector(cx, ctx, argv[0])) {
40 0 : MOZ_ASSERT(true || JS_IsExceptionPending(cx));
41 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
42 0 : return;
43 : }
44 0 : break;
45 : } while (0);
46 :
47 0 : JS::Rooted<JS::Value> callable(cx, JS::ObjectValue(*mCallback));
48 0 : if (!JS::Call(cx, aThisVal, callable,
49 0 : JS::HandleValueArray::subarray(argv, 0, argc), &rval)) {
50 0 : aRv.NoteJSContextException(cx);
51 0 : return;
52 : }
53 : }
54 :
55 :
56 :
57 : void
58 0 : BlobCallback::Call(JSContext* cx, JS::Handle<JS::Value> aThisVal, Blob* blob, ErrorResult& aRv)
59 : {
60 0 : JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
61 0 : JS::AutoValueVector argv(cx);
62 0 : if (!argv.resize(1)) {
63 0 : aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
64 0 : return;
65 : }
66 0 : unsigned argc = 1;
67 :
68 : do {
69 0 : if (!blob) {
70 0 : argv[0].setNull();
71 0 : break;
72 : }
73 0 : if (!GetOrCreateDOMReflector(cx, blob, argv[0])) {
74 0 : MOZ_ASSERT(true || JS_IsExceptionPending(cx));
75 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
76 0 : return;
77 : }
78 0 : break;
79 : } while (0);
80 :
81 0 : JS::Rooted<JS::Value> callable(cx, JS::ObjectValue(*mCallback));
82 0 : if (!JS::Call(cx, aThisVal, callable,
83 0 : JS::HandleValueArray::subarray(argv, 0, argc), &rval)) {
84 0 : aRv.NoteJSContextException(cx);
85 0 : return;
86 : }
87 : }
88 :
89 :
90 :
91 : namespace binding_detail {
92 : } // namespace binding_detail
93 :
94 :
95 : namespace binding_detail {
96 : } // namespace binding_detail
97 :
98 :
99 : namespace HTMLCanvasElementBinding {
100 :
101 : static_assert(IsRefcounted<NativeType>::value == IsRefcounted<HTMLElementBinding::NativeType>::value,
102 : "Can't inherit from an interface with a different ownership model.");
103 :
104 : static bool
105 0 : get_width(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::HTMLCanvasElement* self, JSJitGetterCallArgs args)
106 : {
107 0 : uint32_t result(self->Width());
108 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
109 0 : args.rval().setNumber(result);
110 0 : return true;
111 : }
112 :
113 : static bool
114 0 : set_width(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::HTMLCanvasElement* self, JSJitSetterCallArgs args)
115 : {
116 : uint32_t arg0;
117 0 : if (!ValueToPrimitive<uint32_t, eDefault>(cx, args[0], &arg0)) {
118 0 : return false;
119 : }
120 0 : CustomElementReactionsStack* reactionsStack = GetCustomElementReactionsStack(obj);
121 0 : Maybe<AutoCEReaction> ceReaction;
122 0 : if (reactionsStack) {
123 0 : ceReaction.emplace(reactionsStack);
124 : }
125 0 : binding_detail::FastErrorResult rv;
126 0 : self->SetWidth(arg0, rv);
127 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
128 0 : return false;
129 : }
130 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
131 :
132 0 : return true;
133 : }
134 :
135 : static const JSJitInfo width_getterinfo = {
136 : { (JSJitGetterOp)get_width },
137 : { prototypes::id::HTMLCanvasElement },
138 : { PrototypeTraits<prototypes::id::HTMLCanvasElement>::Depth },
139 : JSJitInfo::Getter,
140 : JSJitInfo::AliasDOMSets, /* aliasSet. Not relevant for setters. */
141 : JSVAL_TYPE_DOUBLE, /* returnType. Not relevant for setters. */
142 : true, /* isInfallible. False in setters. */
143 : true, /* isMovable. Not relevant for setters. */
144 : true, /* isEliminatable. Not relevant for setters. */
145 : false, /* isAlwaysInSlot. Only relevant for getters. */
146 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
147 : false, /* isTypedMethod. Only relevant for methods. */
148 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
149 : };
150 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
151 : static_assert(0 < 1, "There is no slot for us");
152 : static const JSJitInfo width_setterinfo = {
153 : { (JSJitGetterOp)set_width },
154 : { prototypes::id::HTMLCanvasElement },
155 : { PrototypeTraits<prototypes::id::HTMLCanvasElement>::Depth },
156 : JSJitInfo::Setter,
157 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
158 : JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
159 : false, /* isInfallible. False in setters. */
160 : false, /* isMovable. Not relevant for setters. */
161 : false, /* isEliminatable. Not relevant for setters. */
162 : false, /* isAlwaysInSlot. Only relevant for getters. */
163 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
164 : false, /* isTypedMethod. Only relevant for methods. */
165 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
166 : };
167 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
168 : static_assert(0 < 1, "There is no slot for us");
169 :
170 : static bool
171 0 : get_height(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::HTMLCanvasElement* self, JSJitGetterCallArgs args)
172 : {
173 0 : uint32_t result(self->Height());
174 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
175 0 : args.rval().setNumber(result);
176 0 : return true;
177 : }
178 :
179 : static bool
180 0 : set_height(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::HTMLCanvasElement* self, JSJitSetterCallArgs args)
181 : {
182 : uint32_t arg0;
183 0 : if (!ValueToPrimitive<uint32_t, eDefault>(cx, args[0], &arg0)) {
184 0 : return false;
185 : }
186 0 : CustomElementReactionsStack* reactionsStack = GetCustomElementReactionsStack(obj);
187 0 : Maybe<AutoCEReaction> ceReaction;
188 0 : if (reactionsStack) {
189 0 : ceReaction.emplace(reactionsStack);
190 : }
191 0 : binding_detail::FastErrorResult rv;
192 0 : self->SetHeight(arg0, rv);
193 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
194 0 : return false;
195 : }
196 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
197 :
198 0 : return true;
199 : }
200 :
201 : static const JSJitInfo height_getterinfo = {
202 : { (JSJitGetterOp)get_height },
203 : { prototypes::id::HTMLCanvasElement },
204 : { PrototypeTraits<prototypes::id::HTMLCanvasElement>::Depth },
205 : JSJitInfo::Getter,
206 : JSJitInfo::AliasDOMSets, /* aliasSet. Not relevant for setters. */
207 : JSVAL_TYPE_DOUBLE, /* returnType. Not relevant for setters. */
208 : true, /* isInfallible. False in setters. */
209 : true, /* isMovable. Not relevant for setters. */
210 : true, /* isEliminatable. Not relevant for setters. */
211 : false, /* isAlwaysInSlot. Only relevant for getters. */
212 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
213 : false, /* isTypedMethod. Only relevant for methods. */
214 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
215 : };
216 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
217 : static_assert(0 < 1, "There is no slot for us");
218 : static const JSJitInfo height_setterinfo = {
219 : { (JSJitGetterOp)set_height },
220 : { prototypes::id::HTMLCanvasElement },
221 : { PrototypeTraits<prototypes::id::HTMLCanvasElement>::Depth },
222 : JSJitInfo::Setter,
223 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
224 : JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
225 : false, /* isInfallible. False in setters. */
226 : false, /* isMovable. Not relevant for setters. */
227 : false, /* isEliminatable. Not relevant for setters. */
228 : false, /* isAlwaysInSlot. Only relevant for getters. */
229 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
230 : false, /* isTypedMethod. Only relevant for methods. */
231 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
232 : };
233 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
234 : static_assert(0 < 1, "There is no slot for us");
235 :
236 : static bool
237 0 : getContext(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::HTMLCanvasElement* self, const JSJitMethodCallArgs& args)
238 : {
239 0 : if (MOZ_UNLIKELY(args.length() < 1)) {
240 0 : return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "HTMLCanvasElement.getContext");
241 : }
242 0 : binding_detail::FakeString arg0;
243 0 : if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
244 0 : return false;
245 : }
246 0 : JS::Rooted<JS::Value> arg1(cx);
247 0 : if (args.hasDefined(1)) {
248 0 : arg1 = args[1];
249 : } else {
250 0 : arg1 = JS::NullValue();
251 : }
252 0 : binding_detail::FastErrorResult rv;
253 0 : auto result(StrongOrRawPtr<nsISupports>(self->GetContext(cx, NonNullHelper(Constify(arg0)), arg1, rv)));
254 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
255 0 : return false;
256 : }
257 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
258 0 : if (!result) {
259 0 : args.rval().setNull();
260 0 : return true;
261 : }
262 0 : if (!WrapObject(cx, result, args.rval())) {
263 0 : return false;
264 : }
265 0 : return true;
266 : }
267 :
268 : static const JSJitInfo getContext_methodinfo = {
269 : { (JSJitGetterOp)getContext },
270 : { prototypes::id::HTMLCanvasElement },
271 : { PrototypeTraits<prototypes::id::HTMLCanvasElement>::Depth },
272 : JSJitInfo::Method,
273 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
274 : JSVAL_TYPE_UNKNOWN, /* returnType. Not relevant for setters. */
275 : false, /* isInfallible. False in setters. */
276 : false, /* isMovable. Not relevant for setters. */
277 : false, /* isEliminatable. Not relevant for setters. */
278 : false, /* isAlwaysInSlot. Only relevant for getters. */
279 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
280 : false, /* isTypedMethod. Only relevant for methods. */
281 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
282 : };
283 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
284 : static_assert(0 < 1, "There is no slot for us");
285 :
286 : static bool
287 0 : toDataURL(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::HTMLCanvasElement* self, const JSJitMethodCallArgs& args)
288 : {
289 0 : binding_detail::FakeString arg0;
290 0 : if (args.hasDefined(0)) {
291 0 : if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
292 0 : return false;
293 : }
294 : } else {
295 : static const char16_t data[] = { 0 };
296 0 : arg0.Rebind(data, ArrayLength(data) - 1);
297 : }
298 0 : JS::Rooted<JS::Value> arg1(cx);
299 0 : if (args.hasDefined(1)) {
300 0 : arg1 = args[1];
301 : } else {
302 0 : arg1 = JS::UndefinedValue();
303 : }
304 0 : binding_detail::FastErrorResult rv;
305 0 : DOMString result;
306 0 : self->ToDataURL(cx, NonNullHelper(Constify(arg0)), arg1, result, rv);
307 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
308 0 : return false;
309 : }
310 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
311 0 : if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
312 0 : return false;
313 : }
314 0 : return true;
315 : }
316 :
317 : static const JSJitInfo toDataURL_methodinfo = {
318 : { (JSJitGetterOp)toDataURL },
319 : { prototypes::id::HTMLCanvasElement },
320 : { PrototypeTraits<prototypes::id::HTMLCanvasElement>::Depth },
321 : JSJitInfo::Method,
322 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
323 : JSVAL_TYPE_STRING, /* returnType. Not relevant for setters. */
324 : false, /* isInfallible. False in setters. */
325 : false, /* isMovable. Not relevant for setters. */
326 : false, /* isEliminatable. Not relevant for setters. */
327 : false, /* isAlwaysInSlot. Only relevant for getters. */
328 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
329 : false, /* isTypedMethod. Only relevant for methods. */
330 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
331 : };
332 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
333 : static_assert(0 < 1, "There is no slot for us");
334 :
335 : static bool
336 0 : toBlob(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::HTMLCanvasElement* self, const JSJitMethodCallArgs& args)
337 : {
338 0 : if (MOZ_UNLIKELY(args.length() < 1)) {
339 0 : return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "HTMLCanvasElement.toBlob");
340 : }
341 0 : RootedCallback<OwningNonNull<binding_detail::FastBlobCallback>> arg0(cx);
342 0 : if (args[0].isObject()) {
343 0 : if (JS::IsCallable(&args[0].toObject())) {
344 : { // scope for tempRoot
345 0 : JS::Rooted<JSObject*> tempRoot(cx, &args[0].toObject());
346 0 : arg0 = new binding_detail::FastBlobCallback(tempRoot);
347 : }
348 : } else {
349 0 : ThrowErrorMessage(cx, MSG_NOT_CALLABLE, "Argument 1 of HTMLCanvasElement.toBlob");
350 0 : return false;
351 : }
352 : } else {
353 0 : ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 1 of HTMLCanvasElement.toBlob");
354 0 : return false;
355 : }
356 0 : binding_detail::FakeString arg1;
357 0 : if (args.hasDefined(1)) {
358 0 : if (!ConvertJSValueToString(cx, args[1], eStringify, eStringify, arg1)) {
359 0 : return false;
360 : }
361 : } else {
362 : static const char16_t data[] = { 0 };
363 0 : arg1.Rebind(data, ArrayLength(data) - 1);
364 : }
365 0 : JS::Rooted<JS::Value> arg2(cx);
366 0 : if (args.hasDefined(2)) {
367 0 : arg2 = args[2];
368 : } else {
369 0 : arg2 = JS::UndefinedValue();
370 : }
371 0 : binding_detail::FastErrorResult rv;
372 0 : self->ToBlob(cx, NonNullHelper(arg0), NonNullHelper(Constify(arg1)), arg2, rv);
373 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
374 0 : return false;
375 : }
376 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
377 0 : args.rval().setUndefined();
378 0 : return true;
379 : }
380 :
381 : static const JSJitInfo toBlob_methodinfo = {
382 : { (JSJitGetterOp)toBlob },
383 : { prototypes::id::HTMLCanvasElement },
384 : { PrototypeTraits<prototypes::id::HTMLCanvasElement>::Depth },
385 : JSJitInfo::Method,
386 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
387 : JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
388 : false, /* isInfallible. False in setters. */
389 : false, /* isMovable. Not relevant for setters. */
390 : false, /* isEliminatable. Not relevant for setters. */
391 : false, /* isAlwaysInSlot. Only relevant for getters. */
392 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
393 : false, /* isTypedMethod. Only relevant for methods. */
394 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
395 : };
396 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
397 : static_assert(0 < 1, "There is no slot for us");
398 :
399 : static bool
400 0 : get_mozOpaque(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::HTMLCanvasElement* self, JSJitGetterCallArgs args)
401 : {
402 0 : bool result(self->MozOpaque());
403 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
404 0 : args.rval().setBoolean(result);
405 0 : return true;
406 : }
407 :
408 : static bool
409 0 : set_mozOpaque(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::HTMLCanvasElement* self, JSJitSetterCallArgs args)
410 : {
411 : bool arg0;
412 0 : if (!ValueToPrimitive<bool, eDefault>(cx, args[0], &arg0)) {
413 0 : return false;
414 : }
415 0 : binding_detail::FastErrorResult rv;
416 0 : self->SetMozOpaque(arg0, rv);
417 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
418 0 : return false;
419 : }
420 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
421 :
422 0 : return true;
423 : }
424 :
425 : static const JSJitInfo mozOpaque_getterinfo = {
426 : { (JSJitGetterOp)get_mozOpaque },
427 : { prototypes::id::HTMLCanvasElement },
428 : { PrototypeTraits<prototypes::id::HTMLCanvasElement>::Depth },
429 : JSJitInfo::Getter,
430 : JSJitInfo::AliasDOMSets, /* aliasSet. Not relevant for setters. */
431 : JSVAL_TYPE_BOOLEAN, /* returnType. Not relevant for setters. */
432 : true, /* isInfallible. False in setters. */
433 : true, /* isMovable. Not relevant for setters. */
434 : true, /* isEliminatable. Not relevant for setters. */
435 : false, /* isAlwaysInSlot. Only relevant for getters. */
436 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
437 : false, /* isTypedMethod. Only relevant for methods. */
438 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
439 : };
440 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
441 : static_assert(0 < 1, "There is no slot for us");
442 : static const JSJitInfo mozOpaque_setterinfo = {
443 : { (JSJitGetterOp)set_mozOpaque },
444 : { prototypes::id::HTMLCanvasElement },
445 : { PrototypeTraits<prototypes::id::HTMLCanvasElement>::Depth },
446 : JSJitInfo::Setter,
447 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
448 : JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
449 : false, /* isInfallible. False in setters. */
450 : false, /* isMovable. Not relevant for setters. */
451 : false, /* isEliminatable. Not relevant for setters. */
452 : false, /* isAlwaysInSlot. Only relevant for getters. */
453 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
454 : false, /* isTypedMethod. Only relevant for methods. */
455 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
456 : };
457 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
458 : static_assert(0 < 1, "There is no slot for us");
459 :
460 : static bool
461 0 : mozGetAsFile(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::HTMLCanvasElement* self, const JSJitMethodCallArgs& args)
462 : {
463 0 : if (MOZ_UNLIKELY(args.length() < 1)) {
464 0 : return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "HTMLCanvasElement.mozGetAsFile");
465 : }
466 0 : binding_detail::FakeString arg0;
467 0 : if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
468 0 : return false;
469 : }
470 0 : binding_detail::FakeString arg1;
471 0 : if (args.hasDefined(1)) {
472 0 : if (!ConvertJSValueToString(cx, args[1], eNull, eNull, arg1)) {
473 0 : return false;
474 : }
475 : } else {
476 0 : arg1.SetIsVoid(true);
477 : }
478 0 : binding_detail::FastErrorResult rv;
479 0 : auto result(StrongOrRawPtr<mozilla::dom::File>(self->MozGetAsFile(NonNullHelper(Constify(arg0)), NonNullHelper(Constify(arg1)), nsContentUtils::IsSystemCaller(cx) ? CallerType::System : CallerType::NonSystem, rv)));
480 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
481 0 : return false;
482 : }
483 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
484 0 : if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
485 0 : MOZ_ASSERT(true || JS_IsExceptionPending(cx));
486 0 : return false;
487 : }
488 0 : return true;
489 : }
490 :
491 : static const JSJitInfo mozGetAsFile_methodinfo = {
492 : { (JSJitGetterOp)mozGetAsFile },
493 : { prototypes::id::HTMLCanvasElement },
494 : { PrototypeTraits<prototypes::id::HTMLCanvasElement>::Depth },
495 : JSJitInfo::Method,
496 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
497 : JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
498 : false, /* isInfallible. False in setters. */
499 : false, /* isMovable. Not relevant for setters. */
500 : false, /* isEliminatable. Not relevant for setters. */
501 : false, /* isAlwaysInSlot. Only relevant for getters. */
502 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
503 : false, /* isTypedMethod. Only relevant for methods. */
504 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
505 : };
506 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
507 : static_assert(0 < 1, "There is no slot for us");
508 :
509 : static bool
510 0 : MozGetIPCContext(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::HTMLCanvasElement* self, const JSJitMethodCallArgs& args)
511 : {
512 0 : if (MOZ_UNLIKELY(args.length() < 1)) {
513 0 : return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "HTMLCanvasElement.MozGetIPCContext");
514 : }
515 0 : binding_detail::FakeString arg0;
516 0 : if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
517 0 : return false;
518 : }
519 0 : binding_detail::FastErrorResult rv;
520 0 : auto result(StrongOrRawPtr<nsISupports>(self->MozGetIPCContext(NonNullHelper(Constify(arg0)), rv)));
521 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
522 0 : return false;
523 : }
524 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
525 0 : if (!result) {
526 0 : args.rval().setNull();
527 0 : return true;
528 : }
529 0 : if (!WrapObject(cx, result, args.rval())) {
530 0 : return false;
531 : }
532 0 : return true;
533 : }
534 :
535 : static const JSJitInfo MozGetIPCContext_methodinfo = {
536 : { (JSJitGetterOp)MozGetIPCContext },
537 : { prototypes::id::HTMLCanvasElement },
538 : { PrototypeTraits<prototypes::id::HTMLCanvasElement>::Depth },
539 : JSJitInfo::Method,
540 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
541 : JSVAL_TYPE_UNKNOWN, /* returnType. Not relevant for setters. */
542 : false, /* isInfallible. False in setters. */
543 : false, /* isMovable. Not relevant for setters. */
544 : false, /* isEliminatable. Not relevant for setters. */
545 : false, /* isAlwaysInSlot. Only relevant for getters. */
546 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
547 : false, /* isTypedMethod. Only relevant for methods. */
548 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
549 : };
550 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
551 : static_assert(0 < 1, "There is no slot for us");
552 :
553 : static bool
554 0 : get_mozPrintCallback(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::HTMLCanvasElement* self, JSJitGetterCallArgs args)
555 : {
556 0 : RefPtr<PrintCallback> result(self->GetMozPrintCallback());
557 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
558 0 : if (result) {
559 0 : args.rval().setObjectOrNull(GetCallbackFromCallbackObject(result));
560 0 : if (!MaybeWrapObjectOrNullValue(cx, args.rval())) {
561 0 : return false;
562 : }
563 0 : return true;
564 : } else {
565 0 : args.rval().setNull();
566 0 : return true;
567 : }
568 : }
569 :
570 : static bool
571 0 : set_mozPrintCallback(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::HTMLCanvasElement* self, JSJitSetterCallArgs args)
572 : {
573 0 : RootedCallback<RefPtr<binding_detail::FastPrintCallback>> arg0(cx);
574 0 : if (args[0].isObject()) {
575 0 : if (JS::IsCallable(&args[0].toObject())) {
576 : { // scope for tempRoot
577 0 : JS::Rooted<JSObject*> tempRoot(cx, &args[0].toObject());
578 0 : arg0 = new binding_detail::FastPrintCallback(tempRoot);
579 : }
580 : } else {
581 0 : ThrowErrorMessage(cx, MSG_NOT_CALLABLE, "Value being assigned to HTMLCanvasElement.mozPrintCallback");
582 0 : return false;
583 : }
584 0 : } else if (args[0].isNullOrUndefined()) {
585 0 : arg0 = nullptr;
586 : } else {
587 0 : ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Value being assigned to HTMLCanvasElement.mozPrintCallback");
588 0 : return false;
589 : }
590 0 : self->SetMozPrintCallback(Constify(arg0));
591 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
592 :
593 0 : return true;
594 : }
595 :
596 : static const JSJitInfo mozPrintCallback_getterinfo = {
597 : { (JSJitGetterOp)get_mozPrintCallback },
598 : { prototypes::id::HTMLCanvasElement },
599 : { PrototypeTraits<prototypes::id::HTMLCanvasElement>::Depth },
600 : JSJitInfo::Getter,
601 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
602 : JSVAL_TYPE_UNKNOWN, /* returnType. Not relevant for setters. */
603 : false, /* isInfallible. False in setters. */
604 : false, /* isMovable. Not relevant for setters. */
605 : false, /* isEliminatable. Not relevant for setters. */
606 : false, /* isAlwaysInSlot. Only relevant for getters. */
607 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
608 : false, /* isTypedMethod. Only relevant for methods. */
609 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
610 : };
611 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
612 : static_assert(0 < 1, "There is no slot for us");
613 : static const JSJitInfo mozPrintCallback_setterinfo = {
614 : { (JSJitGetterOp)set_mozPrintCallback },
615 : { prototypes::id::HTMLCanvasElement },
616 : { PrototypeTraits<prototypes::id::HTMLCanvasElement>::Depth },
617 : JSJitInfo::Setter,
618 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
619 : JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
620 : false, /* isInfallible. False in setters. */
621 : false, /* isMovable. Not relevant for setters. */
622 : false, /* isEliminatable. Not relevant for setters. */
623 : false, /* isAlwaysInSlot. Only relevant for getters. */
624 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
625 : false, /* isTypedMethod. Only relevant for methods. */
626 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
627 : };
628 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
629 : static_assert(0 < 1, "There is no slot for us");
630 :
631 : static bool
632 0 : captureStream(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::HTMLCanvasElement* self, const JSJitMethodCallArgs& args)
633 : {
634 0 : if (!mozilla::dom::EnforceNotInPrerendering(cx, obj)) {
635 : // Return false from the JSNative in order to trigger
636 : // an uncatchable exception.
637 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
638 0 : return false;
639 : }
640 0 : Optional<double> arg0;
641 0 : if (args.hasDefined(0)) {
642 0 : arg0.Construct();
643 0 : if (!ValueToPrimitive<double, eDefault>(cx, args[0], &arg0.Value())) {
644 0 : return false;
645 0 : } else if (!mozilla::IsFinite(arg0.Value())) {
646 0 : ThrowErrorMessage(cx, MSG_NOT_FINITE, "Argument 1 of HTMLCanvasElement.captureStream");
647 0 : return false;
648 : }
649 : }
650 0 : binding_detail::FastErrorResult rv;
651 0 : auto result(StrongOrRawPtr<mozilla::dom::CanvasCaptureMediaStream>(self->CaptureStream(Constify(arg0), rv)));
652 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
653 0 : return false;
654 : }
655 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
656 0 : if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
657 0 : MOZ_ASSERT(true || JS_IsExceptionPending(cx));
658 0 : return false;
659 : }
660 0 : return true;
661 : }
662 :
663 : static const JSJitInfo captureStream_methodinfo = {
664 : { (JSJitGetterOp)captureStream },
665 : { prototypes::id::HTMLCanvasElement },
666 : { PrototypeTraits<prototypes::id::HTMLCanvasElement>::Depth },
667 : JSJitInfo::Method,
668 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
669 : JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
670 : false, /* isInfallible. False in setters. */
671 : false, /* isMovable. Not relevant for setters. */
672 : false, /* isEliminatable. Not relevant for setters. */
673 : false, /* isAlwaysInSlot. Only relevant for getters. */
674 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
675 : false, /* isTypedMethod. Only relevant for methods. */
676 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
677 : };
678 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
679 : static_assert(0 < 1, "There is no slot for us");
680 :
681 : static bool
682 0 : transferControlToOffscreen(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::HTMLCanvasElement* self, const JSJitMethodCallArgs& args)
683 : {
684 0 : binding_detail::FastErrorResult rv;
685 0 : auto result(StrongOrRawPtr<mozilla::dom::OffscreenCanvas>(self->TransferControlToOffscreen(rv)));
686 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
687 0 : return false;
688 : }
689 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
690 0 : if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
691 0 : MOZ_ASSERT(true || JS_IsExceptionPending(cx));
692 0 : return false;
693 : }
694 0 : return true;
695 : }
696 :
697 : static const JSJitInfo transferControlToOffscreen_methodinfo = {
698 : { (JSJitGetterOp)transferControlToOffscreen },
699 : { prototypes::id::HTMLCanvasElement },
700 : { PrototypeTraits<prototypes::id::HTMLCanvasElement>::Depth },
701 : JSJitInfo::Method,
702 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
703 : JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
704 : false, /* isInfallible. False in setters. */
705 : false, /* isMovable. Not relevant for setters. */
706 : false, /* isEliminatable. Not relevant for setters. */
707 : false, /* isAlwaysInSlot. Only relevant for getters. */
708 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
709 : false, /* isTypedMethod. Only relevant for methods. */
710 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
711 : };
712 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
713 : static_assert(0 < 1, "There is no slot for us");
714 :
715 : static bool
716 0 : _addProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::Handle<JS::Value> val)
717 : {
718 0 : mozilla::dom::HTMLCanvasElement* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::HTMLCanvasElement>(obj);
719 : // We don't want to preserve if we don't have a wrapper, and we
720 : // obviously can't preserve if we're not initialized.
721 0 : if (self && self->GetWrapperPreserveColor()) {
722 0 : PreserveWrapper(self);
723 : }
724 0 : return true;
725 : }
726 :
727 : static void
728 0 : _finalize(js::FreeOp* fop, JSObject* obj)
729 : {
730 0 : mozilla::dom::HTMLCanvasElement* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::HTMLCanvasElement>(obj);
731 0 : if (self) {
732 0 : ClearWrapper(self, self, obj);
733 0 : AddForDeferredFinalization<mozilla::dom::HTMLCanvasElement>(self);
734 : }
735 0 : }
736 :
737 : static void
738 0 : _objectMoved(JSObject* obj, const JSObject* old)
739 : {
740 0 : mozilla::dom::HTMLCanvasElement* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::HTMLCanvasElement>(obj);
741 0 : if (self) {
742 0 : UpdateWrapper(self, self, obj, old);
743 : }
744 0 : }
745 :
746 : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
747 : #if defined(__clang__)
748 : #pragma clang diagnostic push
749 : #pragma clang diagnostic ignored "-Wmissing-braces"
750 : #endif
751 : static const JSFunctionSpec sMethods_specs[] = {
752 : JS_FNSPEC("getContext", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&getContext_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
753 : JS_FNSPEC("toDataURL", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&toDataURL_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
754 : JS_FNSPEC("toBlob", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&toBlob_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
755 : JS_FNSPEC("mozGetAsFile", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&mozGetAsFile_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
756 : JS_FS_END,
757 : JS_FNSPEC("captureStream", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&captureStream_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
758 : JS_FS_END,
759 : JS_FNSPEC("transferControlToOffscreen", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&transferControlToOffscreen_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
760 : JS_FS_END
761 : };
762 : #if defined(__clang__)
763 : #pragma clang diagnostic pop
764 : #endif
765 :
766 : static PrefableDisablers sMethods_disablers5 = {
767 : true, false, 0, nullptr
768 : };
769 :
770 : static PrefableDisablers sMethods_disablers7 = {
771 : true, false, 0, nullptr
772 : };
773 :
774 : // Can't be const because the pref-enabled boolean needs to be writable
775 : static Prefable<const JSFunctionSpec> sMethods[] = {
776 : { nullptr, &sMethods_specs[0] },
777 : { &sMethods_disablers5, &sMethods_specs[5] },
778 : { &sMethods_disablers7, &sMethods_specs[7] },
779 : { nullptr, nullptr }
780 : };
781 :
782 : static_assert(3 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
783 : "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
784 : static_assert(4 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
785 : "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
786 :
787 : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
788 : #if defined(__clang__)
789 : #pragma clang diagnostic push
790 : #pragma clang diagnostic ignored "-Wmissing-braces"
791 : #endif
792 : static const JSFunctionSpec sChromeMethods_specs[] = {
793 : JS_FNSPEC("MozGetIPCContext", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&MozGetIPCContext_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
794 : JS_FS_END
795 : };
796 : #if defined(__clang__)
797 : #pragma clang diagnostic pop
798 : #endif
799 :
800 :
801 : // Can't be const because the pref-enabled boolean needs to be writable
802 : static Prefable<const JSFunctionSpec> sChromeMethods[] = {
803 : { nullptr, &sChromeMethods_specs[0] },
804 : { nullptr, nullptr }
805 : };
806 :
807 : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
808 : "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
809 : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
810 : "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
811 :
812 : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
813 : #if defined(__clang__)
814 : #pragma clang diagnostic push
815 : #pragma clang diagnostic ignored "-Wmissing-braces"
816 : #endif
817 : static const JSPropertySpec sAttributes_specs[] = {
818 : { "width", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &width_getterinfo, GenericBindingSetter, &width_setterinfo },
819 : { "height", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &height_getterinfo, GenericBindingSetter, &height_setterinfo },
820 : { "mozOpaque", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &mozOpaque_getterinfo, GenericBindingSetter, &mozOpaque_setterinfo },
821 : { "mozPrintCallback", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &mozPrintCallback_getterinfo, GenericBindingSetter, &mozPrintCallback_setterinfo },
822 : { nullptr, 0, nullptr, nullptr, nullptr, nullptr }
823 : };
824 : #if defined(__clang__)
825 : #pragma clang diagnostic pop
826 : #endif
827 :
828 :
829 : // Can't be const because the pref-enabled boolean needs to be writable
830 : static Prefable<const JSPropertySpec> sAttributes[] = {
831 : { nullptr, &sAttributes_specs[0] },
832 : { nullptr, nullptr }
833 : };
834 :
835 : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
836 : "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
837 : static_assert(4 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
838 : "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
839 :
840 :
841 : static uint16_t sNativeProperties_sortedPropertyIndices[10];
842 : static PropertyInfo sNativeProperties_propertyInfos[10];
843 :
844 : static const NativePropertiesN<2> sNativeProperties = {
845 : false, 0,
846 : false, 0,
847 : true, 0 /* sMethods */,
848 : true, 1 /* sAttributes */,
849 : false, 0,
850 : false, 0,
851 : false, 0,
852 : -1,
853 : 10,
854 : sNativeProperties_sortedPropertyIndices,
855 : {
856 : { sMethods, &sNativeProperties_propertyInfos[0] },
857 : { sAttributes, &sNativeProperties_propertyInfos[6] }
858 : }
859 : };
860 : static_assert(10 < 1ull << CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount),
861 : "We have a property info count that is oversized");
862 :
863 : static uint16_t sChromeOnlyNativeProperties_sortedPropertyIndices[1];
864 : static PropertyInfo sChromeOnlyNativeProperties_propertyInfos[1];
865 :
866 : static const NativePropertiesN<1> sChromeOnlyNativeProperties = {
867 : false, 0,
868 : false, 0,
869 : true, 0 /* sChromeMethods */,
870 : false, 0,
871 : false, 0,
872 : false, 0,
873 : false, 0,
874 : -1,
875 : 1,
876 : sChromeOnlyNativeProperties_sortedPropertyIndices,
877 : {
878 : { sChromeMethods, &sChromeOnlyNativeProperties_propertyInfos[0] }
879 : }
880 : };
881 : static_assert(1 < 1ull << CHAR_BIT * sizeof(sChromeOnlyNativeProperties.propertyInfoCount),
882 : "We have a property info count that is oversized");
883 :
884 : static bool
885 0 : _constructor(JSContext* cx, unsigned argc, JS::Value* vp)
886 : {
887 0 : JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
888 0 : JS::Rooted<JSObject*> obj(cx, &args.callee());
889 0 : if (!args.isConstructing()) {
890 : // XXXbz wish I could get the name from the callee instead of
891 : // Adding more relocations
892 0 : return ThrowConstructorWithoutNew(cx, "HTMLCanvasElement");
893 : }
894 :
895 0 : GlobalObject global(cx, obj);
896 0 : if (global.Failed()) {
897 0 : return false;
898 : }
899 :
900 : // The newTarget might be a cross-compartment wrapper. Get the underlying object
901 : // so we can do the spec's object-identity checks.
902 0 : JS::Rooted<JSObject*> newTarget(cx, js::CheckedUnwrap(&args.newTarget().toObject()));
903 0 : if (!newTarget) {
904 0 : return ThrowErrorMessage(cx, MSG_ILLEGAL_CONSTRUCTOR);
905 : }
906 :
907 : // Step 2 of https://html.spec.whatwg.org/multipage/dom.html#htmlconstructor.
908 : // Enter the compartment of our underlying newTarget object, so we end
909 : // up comparing to the constructor object for our interface from that global.
910 : {
911 0 : JSAutoCompartment ac(cx, newTarget);
912 0 : JS::Handle<JSObject*> constructor(GetConstructorObjectHandle(cx));
913 0 : if (!constructor) {
914 0 : return false;
915 : }
916 0 : if (newTarget == constructor) {
917 0 : return ThrowErrorMessage(cx, MSG_ILLEGAL_CONSTRUCTOR);
918 : }
919 : }
920 :
921 0 : JS::Rooted<JSObject*> desiredProto(cx);
922 0 : if (!GetDesiredProto(cx, args, &desiredProto)) {
923 0 : return false;
924 : }
925 0 : if (!desiredProto) {
926 : // Step 7 of https://html.spec.whatwg.org/multipage/dom.html#htmlconstructor.
927 : // This fallback behavior is designed to match analogous behavior for the
928 : // JavaScript built-ins. So we enter the compartment of our underlying
929 : // newTarget object and fall back to the prototype object from that global.
930 : // XXX The spec says to use GetFunctionRealm(), which is not actually
931 : // the same thing as what we have here (e.g. in the case of scripted callable proxies
932 : // whose target is not same-compartment with the proxy, or bound functions, etc).
933 : // https://bugzilla.mozilla.org/show_bug.cgi?id=1317658
934 : {
935 0 : JSAutoCompartment ac(cx, newTarget);
936 0 : desiredProto = GetProtoObjectHandle(cx);
937 0 : if (!desiredProto) {
938 0 : return false;
939 : }
940 : }
941 :
942 : // desiredProto is in the compartment of the underlying newTarget object.
943 : // Wrap it into the context compartment.
944 0 : if (!JS_WrapObject(cx, &desiredProto)) {
945 0 : return false;
946 : }
947 : }
948 :
949 0 : bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
950 0 : Maybe<JSAutoCompartment> ac;
951 0 : if (objIsXray) {
952 0 : obj = js::CheckedUnwrap(obj);
953 0 : if (!obj) {
954 0 : return false;
955 : }
956 0 : ac.emplace(cx, obj);
957 0 : if (!JS_WrapObject(cx, &desiredProto)) {
958 0 : return false;
959 : }
960 : }
961 0 : binding_detail::FastErrorResult rv;
962 0 : auto result(StrongOrRawPtr<mozilla::dom::HTMLCanvasElement>(CreateHTMLElement(global, args, rv)));
963 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
964 0 : return false;
965 : }
966 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
967 : static_assert(!IsPointer<decltype(result)>::value,
968 : "NewObject implies that we need to keep the object alive with a strong reference.");
969 0 : if (!GetOrCreateDOMReflector(cx, result, args.rval(), desiredProto)) {
970 0 : MOZ_ASSERT(true || JS_IsExceptionPending(cx));
971 0 : return false;
972 : }
973 0 : return true;
974 : }
975 :
976 : static const js::ClassOps sInterfaceObjectClassOps = {
977 : nullptr, /* addProperty */
978 : nullptr, /* delProperty */
979 : nullptr, /* getProperty */
980 : nullptr, /* setProperty */
981 : nullptr, /* enumerate */
982 : nullptr, /* newEnumerate */
983 : nullptr, /* resolve */
984 : nullptr, /* mayResolve */
985 : nullptr, /* finalize */
986 : _constructor, /* call */
987 : nullptr, /* hasInstance */
988 : _constructor, /* construct */
989 : nullptr, /* trace */
990 : };
991 :
992 : static const DOMIfaceAndProtoJSClass sInterfaceObjectClass = {
993 : {
994 : "Function",
995 : JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_SLOTS_BASE),
996 : &sInterfaceObjectClassOps,
997 : JS_NULL_CLASS_SPEC,
998 : JS_NULL_CLASS_EXT,
999 : &sInterfaceObjectClassObjectOps
1000 : },
1001 : eInterface,
1002 : true,
1003 : prototypes::id::HTMLCanvasElement,
1004 : PrototypeTraits<prototypes::id::HTMLCanvasElement>::Depth,
1005 : sNativePropertyHooks,
1006 : "function HTMLCanvasElement() {\n [native code]\n}",
1007 : HTMLElementBinding::GetConstructorObject
1008 : };
1009 :
1010 : static const DOMIfaceAndProtoJSClass sPrototypeClass = {
1011 : {
1012 : "HTMLCanvasElementPrototype",
1013 : JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE),
1014 : JS_NULL_CLASS_OPS,
1015 : JS_NULL_CLASS_SPEC,
1016 : JS_NULL_CLASS_EXT,
1017 : JS_NULL_OBJECT_OPS
1018 : },
1019 : eInterfacePrototype,
1020 : false,
1021 : prototypes::id::HTMLCanvasElement,
1022 : PrototypeTraits<prototypes::id::HTMLCanvasElement>::Depth,
1023 : sNativePropertyHooks,
1024 : "[object HTMLCanvasElementPrototype]",
1025 : HTMLElementBinding::GetProtoObject
1026 : };
1027 :
1028 : JSObject*
1029 0 : DefineDOMInterface(JSContext* aCx, JS::Handle<JSObject*> aGlobal, JS::Handle<jsid> id, bool aDefineOnGlobal)
1030 : {
1031 0 : return GetConstructorObjectHandle(aCx, aDefineOnGlobal);
1032 : }
1033 :
1034 : static const js::ClassOps sClassOps = {
1035 : _addProperty, /* addProperty */
1036 : nullptr, /* delProperty */
1037 : nullptr, /* getProperty */
1038 : nullptr, /* setProperty */
1039 : nullptr, /* enumerate */
1040 : nullptr, /* newEnumerate */
1041 : nullptr, /* resolve */
1042 : nullptr, /* mayResolve */
1043 : _finalize, /* finalize */
1044 : nullptr, /* call */
1045 : nullptr, /* hasInstance */
1046 : nullptr, /* construct */
1047 : nullptr, /* trace */
1048 : };
1049 :
1050 : static const js::ClassExtension sClassExtension = {
1051 : nullptr, /* weakmapKeyDelegateOp */
1052 : _objectMoved /* objectMovedOp */
1053 : };
1054 :
1055 : static const DOMJSClass sClass = {
1056 : { "HTMLCanvasElement",
1057 : JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1),
1058 : &sClassOps,
1059 : JS_NULL_CLASS_SPEC,
1060 : &sClassExtension,
1061 : JS_NULL_OBJECT_OPS
1062 : },
1063 : { prototypes::id::EventTarget, prototypes::id::Node, prototypes::id::Element, prototypes::id::HTMLElement, prototypes::id::HTMLCanvasElement, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
1064 : IsBaseOf<nsISupports, mozilla::dom::HTMLCanvasElement >::value,
1065 : sNativePropertyHooks,
1066 : FindAssociatedGlobalForNative<mozilla::dom::HTMLCanvasElement>::Get,
1067 : GetProtoObjectHandle,
1068 : GetCCParticipant<mozilla::dom::HTMLCanvasElement>::Get()
1069 : };
1070 : static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
1071 : "Must have the right minimal number of reserved slots.");
1072 : static_assert(1 >= 1,
1073 : "Must have enough reserved slots.");
1074 :
1075 : const JSClass*
1076 0 : GetJSClass()
1077 : {
1078 0 : return sClass.ToJSClass();
1079 : }
1080 :
1081 : bool
1082 0 : Wrap(JSContext* aCx, mozilla::dom::HTMLCanvasElement* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
1083 : {
1084 : MOZ_ASSERT(static_cast<mozilla::dom::HTMLCanvasElement*>(aObject) ==
1085 : reinterpret_cast<mozilla::dom::HTMLCanvasElement*>(aObject),
1086 : "Multiple inheritance for mozilla::dom::HTMLCanvasElement is broken.");
1087 : MOZ_ASSERT(static_cast<nsGenericHTMLElement*>(aObject) ==
1088 : reinterpret_cast<nsGenericHTMLElement*>(aObject),
1089 : "Multiple inheritance for nsGenericHTMLElement is broken.");
1090 : MOZ_ASSERT(static_cast<mozilla::dom::Element*>(aObject) ==
1091 : reinterpret_cast<mozilla::dom::Element*>(aObject),
1092 : "Multiple inheritance for mozilla::dom::Element is broken.");
1093 : MOZ_ASSERT(static_cast<nsINode*>(aObject) ==
1094 : reinterpret_cast<nsINode*>(aObject),
1095 : "Multiple inheritance for nsINode is broken.");
1096 : MOZ_ASSERT(static_cast<mozilla::dom::EventTarget*>(aObject) ==
1097 : reinterpret_cast<mozilla::dom::EventTarget*>(aObject),
1098 : "Multiple inheritance for mozilla::dom::EventTarget is broken.");
1099 0 : MOZ_ASSERT(ToSupportsIsCorrect(aObject));
1100 0 : MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
1101 0 : MOZ_ASSERT(!aCache->GetWrapper(),
1102 : "You should probably not be using Wrap() directly; use "
1103 : "GetOrCreateDOMReflector instead");
1104 :
1105 0 : MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
1106 : "nsISupports must be on our primary inheritance chain");
1107 :
1108 0 : JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
1109 0 : if (!global) {
1110 0 : return false;
1111 : }
1112 0 : MOZ_ASSERT(JS_IsGlobalObject(global));
1113 0 : MOZ_ASSERT(JS::ObjectIsNotGray(global));
1114 :
1115 : // That might have ended up wrapping us already, due to the wonders
1116 : // of XBL. Check for that, and bail out as needed.
1117 0 : aReflector.set(aCache->GetWrapper());
1118 0 : if (aReflector) {
1119 : #ifdef DEBUG
1120 0 : binding_detail::AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
1121 : #endif // DEBUG
1122 0 : return true;
1123 : }
1124 :
1125 0 : JSAutoCompartment ac(aCx, global);
1126 0 : JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
1127 0 : if (!canonicalProto) {
1128 0 : return false;
1129 : }
1130 0 : JS::Rooted<JSObject*> proto(aCx);
1131 0 : if (aGivenProto) {
1132 0 : proto = aGivenProto;
1133 : // Unfortunately, while aGivenProto was in the compartment of aCx
1134 : // coming in, we changed compartments to that of "parent" so may need
1135 : // to wrap the proto here.
1136 0 : if (js::GetContextCompartment(aCx) != js::GetObjectCompartment(proto)) {
1137 0 : if (!JS_WrapObject(aCx, &proto)) {
1138 0 : return false;
1139 : }
1140 : }
1141 : } else {
1142 0 : proto = canonicalProto;
1143 : }
1144 :
1145 0 : BindingJSObjectCreator<mozilla::dom::HTMLCanvasElement> creator(aCx);
1146 0 : creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
1147 0 : if (!aReflector) {
1148 0 : return false;
1149 : }
1150 :
1151 0 : aCache->SetWrapper(aReflector);
1152 0 : creator.InitializationSucceeded();
1153 :
1154 0 : MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
1155 : aCache->GetWrapperPreserveColor() == aReflector);
1156 : // If proto != canonicalProto, we have to preserve our wrapper;
1157 : // otherwise we won't be able to properly recreate it later, since
1158 : // we won't know what proto to use. Note that we don't check
1159 : // aGivenProto here, since it's entirely possible (and even
1160 : // somewhat common) to have a non-null aGivenProto which is the
1161 : // same as canonicalProto.
1162 0 : if (proto != canonicalProto) {
1163 0 : PreserveWrapper(aObject);
1164 : }
1165 :
1166 0 : return true;
1167 : }
1168 :
1169 : const NativePropertyHooks sNativePropertyHooks[] = { {
1170 : nullptr,
1171 : nullptr,
1172 : nullptr,
1173 : { sNativeProperties.Upcast(), sChromeOnlyNativeProperties.Upcast() },
1174 : prototypes::id::HTMLCanvasElement,
1175 : constructors::id::HTMLCanvasElement,
1176 : HTMLElementBinding::sNativePropertyHooks,
1177 : &DefaultXrayExpandoObjectClass
1178 : } };
1179 :
1180 : void
1181 0 : CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, bool aDefineOnGlobal)
1182 : {
1183 0 : JS::Handle<JSObject*> parentProto(HTMLElementBinding::GetProtoObjectHandle(aCx));
1184 0 : if (!parentProto) {
1185 0 : return;
1186 : }
1187 :
1188 0 : JS::Handle<JSObject*> constructorProto(HTMLElementBinding::GetConstructorObjectHandle(aCx));
1189 0 : if (!constructorProto) {
1190 0 : return;
1191 : }
1192 :
1193 : static bool sIdsInited = false;
1194 0 : if (!sIdsInited && NS_IsMainThread()) {
1195 0 : if (!InitIds(aCx, sNativeProperties.Upcast())) {
1196 0 : return;
1197 : }
1198 0 : if (!InitIds(aCx, sChromeOnlyNativeProperties.Upcast())) {
1199 0 : return;
1200 : }
1201 0 : sIdsInited = true;
1202 : }
1203 :
1204 : static bool sPrefCachesInited = false;
1205 0 : if (!sPrefCachesInited && NS_IsMainThread()) {
1206 0 : sPrefCachesInited = true;
1207 0 : Preferences::AddBoolVarCache(&sMethods[1].disablers->enabled, "canvas.capturestream.enabled");
1208 0 : Preferences::AddBoolVarCache(&sMethods[2].disablers->enabled, "gfx.offscreencanvas.enabled");
1209 : }
1210 :
1211 0 : JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::HTMLCanvasElement);
1212 0 : JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::HTMLCanvasElement);
1213 0 : dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
1214 : &sPrototypeClass.mBase, protoCache,
1215 : constructorProto, &sInterfaceObjectClass.mBase, 0, nullptr,
1216 : interfaceCache,
1217 : sNativeProperties.Upcast(),
1218 0 : nsContentUtils::ThreadsafeIsSystemCaller(aCx) ? sChromeOnlyNativeProperties.Upcast() : nullptr,
1219 : "HTMLCanvasElement", aDefineOnGlobal,
1220 : nullptr,
1221 0 : false);
1222 : }
1223 :
1224 : JS::Handle<JSObject*>
1225 0 : GetProtoObjectHandle(JSContext* aCx)
1226 : {
1227 : /* Get the interface prototype object for this class. This will create the
1228 : object as needed. */
1229 0 : bool aDefineOnGlobal = true;
1230 :
1231 : /* Make sure our global is sane. Hopefully we can remove this sometime */
1232 0 : JSObject* global = JS::CurrentGlobalOrNull(aCx);
1233 0 : if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
1234 0 : return nullptr;
1235 : }
1236 :
1237 : /* Check to see whether the interface objects are already installed */
1238 0 : ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
1239 0 : if (!protoAndIfaceCache.HasEntryInSlot(prototypes::id::HTMLCanvasElement)) {
1240 0 : JS::Rooted<JSObject*> rootedGlobal(aCx, global);
1241 0 : CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
1242 : }
1243 :
1244 : /*
1245 : * The object might _still_ be null, but that's OK.
1246 : *
1247 : * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
1248 : * traced by TraceProtoAndIfaceCache() and its contents are never
1249 : * changed after they have been set.
1250 : *
1251 : * Calling address() avoids the read read barrier that does gray
1252 : * unmarking, but it's not possible for the object to be gray here.
1253 : */
1254 :
1255 0 : const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(prototypes::id::HTMLCanvasElement);
1256 0 : MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
1257 0 : return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
1258 : }
1259 :
1260 : JS::Handle<JSObject*>
1261 0 : GetConstructorObjectHandle(JSContext* aCx, bool aDefineOnGlobal)
1262 : {
1263 : /* Get the interface object for this class. This will create the object as
1264 : needed. */
1265 :
1266 : /* Make sure our global is sane. Hopefully we can remove this sometime */
1267 0 : JSObject* global = JS::CurrentGlobalOrNull(aCx);
1268 0 : if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
1269 0 : return nullptr;
1270 : }
1271 :
1272 : /* Check to see whether the interface objects are already installed */
1273 0 : ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
1274 0 : if (!protoAndIfaceCache.HasEntryInSlot(constructors::id::HTMLCanvasElement)) {
1275 0 : JS::Rooted<JSObject*> rootedGlobal(aCx, global);
1276 0 : CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
1277 : }
1278 :
1279 : /*
1280 : * The object might _still_ be null, but that's OK.
1281 : *
1282 : * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
1283 : * traced by TraceProtoAndIfaceCache() and its contents are never
1284 : * changed after they have been set.
1285 : *
1286 : * Calling address() avoids the read read barrier that does gray
1287 : * unmarking, but it's not possible for the object to be gray here.
1288 : */
1289 :
1290 0 : const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(constructors::id::HTMLCanvasElement);
1291 0 : MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
1292 0 : return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
1293 : }
1294 :
1295 : JSObject*
1296 0 : GetConstructorObject(JSContext* aCx)
1297 : {
1298 0 : return GetConstructorObjectHandle(aCx);
1299 : }
1300 :
1301 : } // namespace HTMLCanvasElementBinding
1302 :
1303 :
1304 :
1305 : namespace MozCanvasPrintStateBinding {
1306 :
1307 : static bool
1308 0 : get_context(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::HTMLCanvasPrintState* self, JSJitGetterCallArgs args)
1309 : {
1310 0 : auto result(StrongOrRawPtr<nsISupports>(self->Context()));
1311 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
1312 0 : if (!WrapObject(cx, result, args.rval())) {
1313 0 : return false;
1314 : }
1315 0 : return true;
1316 : }
1317 :
1318 : static const JSJitInfo context_getterinfo = {
1319 : { (JSJitGetterOp)get_context },
1320 : { prototypes::id::MozCanvasPrintState },
1321 : { PrototypeTraits<prototypes::id::MozCanvasPrintState>::Depth },
1322 : JSJitInfo::Getter,
1323 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
1324 : JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
1325 : false, /* isInfallible. False in setters. */
1326 : false, /* isMovable. Not relevant for setters. */
1327 : false, /* isEliminatable. Not relevant for setters. */
1328 : false, /* isAlwaysInSlot. Only relevant for getters. */
1329 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
1330 : false, /* isTypedMethod. Only relevant for methods. */
1331 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
1332 : };
1333 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
1334 : static_assert(0 < 1, "There is no slot for us");
1335 :
1336 : static bool
1337 0 : done(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::HTMLCanvasPrintState* self, const JSJitMethodCallArgs& args)
1338 : {
1339 0 : self->Done();
1340 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
1341 0 : args.rval().setUndefined();
1342 0 : return true;
1343 : }
1344 :
1345 : static const JSJitInfo done_methodinfo = {
1346 : { (JSJitGetterOp)done },
1347 : { prototypes::id::MozCanvasPrintState },
1348 : { PrototypeTraits<prototypes::id::MozCanvasPrintState>::Depth },
1349 : JSJitInfo::Method,
1350 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
1351 : JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
1352 : true, /* isInfallible. False in setters. */
1353 : false, /* isMovable. Not relevant for setters. */
1354 : false, /* isEliminatable. Not relevant for setters. */
1355 : false, /* isAlwaysInSlot. Only relevant for getters. */
1356 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
1357 : false, /* isTypedMethod. Only relevant for methods. */
1358 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
1359 : };
1360 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
1361 : static_assert(0 < 1, "There is no slot for us");
1362 :
1363 : static bool
1364 0 : _addProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::Handle<JS::Value> val)
1365 : {
1366 0 : mozilla::dom::HTMLCanvasPrintState* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::HTMLCanvasPrintState>(obj);
1367 : // We don't want to preserve if we don't have a wrapper, and we
1368 : // obviously can't preserve if we're not initialized.
1369 0 : if (self && self->GetWrapperPreserveColor()) {
1370 0 : PreserveWrapper(self);
1371 : }
1372 0 : return true;
1373 : }
1374 :
1375 : static void
1376 0 : _finalize(js::FreeOp* fop, JSObject* obj)
1377 : {
1378 0 : mozilla::dom::HTMLCanvasPrintState* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::HTMLCanvasPrintState>(obj);
1379 0 : if (self) {
1380 0 : ClearWrapper(self, self, obj);
1381 0 : AddForDeferredFinalization<mozilla::dom::HTMLCanvasPrintState>(self);
1382 : }
1383 0 : }
1384 :
1385 : static void
1386 0 : _objectMoved(JSObject* obj, const JSObject* old)
1387 : {
1388 0 : mozilla::dom::HTMLCanvasPrintState* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::HTMLCanvasPrintState>(obj);
1389 0 : if (self) {
1390 0 : UpdateWrapper(self, self, obj, old);
1391 : }
1392 0 : }
1393 :
1394 : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
1395 : #if defined(__clang__)
1396 : #pragma clang diagnostic push
1397 : #pragma clang diagnostic ignored "-Wmissing-braces"
1398 : #endif
1399 : static const JSFunctionSpec sMethods_specs[] = {
1400 : JS_FNSPEC("done", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&done_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
1401 : JS_FS_END
1402 : };
1403 : #if defined(__clang__)
1404 : #pragma clang diagnostic pop
1405 : #endif
1406 :
1407 :
1408 : // Can't be const because the pref-enabled boolean needs to be writable
1409 : static Prefable<const JSFunctionSpec> sMethods[] = {
1410 : { nullptr, &sMethods_specs[0] },
1411 : { nullptr, nullptr }
1412 : };
1413 :
1414 : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
1415 : "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
1416 : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
1417 : "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
1418 :
1419 : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
1420 : #if defined(__clang__)
1421 : #pragma clang diagnostic push
1422 : #pragma clang diagnostic ignored "-Wmissing-braces"
1423 : #endif
1424 : static const JSPropertySpec sAttributes_specs[] = {
1425 : { "context", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &context_getterinfo, nullptr, nullptr },
1426 : { nullptr, 0, nullptr, nullptr, nullptr, nullptr }
1427 : };
1428 : #if defined(__clang__)
1429 : #pragma clang diagnostic pop
1430 : #endif
1431 :
1432 :
1433 : // Can't be const because the pref-enabled boolean needs to be writable
1434 : static Prefable<const JSPropertySpec> sAttributes[] = {
1435 : { nullptr, &sAttributes_specs[0] },
1436 : { nullptr, nullptr }
1437 : };
1438 :
1439 : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
1440 : "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
1441 : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
1442 : "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
1443 :
1444 :
1445 : static uint16_t sNativeProperties_sortedPropertyIndices[2];
1446 : static PropertyInfo sNativeProperties_propertyInfos[2];
1447 :
1448 : static const NativePropertiesN<2> sNativeProperties = {
1449 : false, 0,
1450 : false, 0,
1451 : true, 0 /* sMethods */,
1452 : true, 1 /* sAttributes */,
1453 : false, 0,
1454 : false, 0,
1455 : false, 0,
1456 : -1,
1457 : 2,
1458 : sNativeProperties_sortedPropertyIndices,
1459 : {
1460 : { sMethods, &sNativeProperties_propertyInfos[0] },
1461 : { sAttributes, &sNativeProperties_propertyInfos[1] }
1462 : }
1463 : };
1464 : static_assert(2 < 1ull << CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount),
1465 : "We have a property info count that is oversized");
1466 :
1467 : static const DOMIfaceAndProtoJSClass sInterfaceObjectClass = {
1468 : {
1469 : "Function",
1470 : JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_SLOTS_BASE),
1471 : &sBoringInterfaceObjectClassClassOps,
1472 : JS_NULL_CLASS_SPEC,
1473 : JS_NULL_CLASS_EXT,
1474 : &sInterfaceObjectClassObjectOps
1475 : },
1476 : eInterface,
1477 : true,
1478 : prototypes::id::MozCanvasPrintState,
1479 : PrototypeTraits<prototypes::id::MozCanvasPrintState>::Depth,
1480 : sNativePropertyHooks,
1481 : "function MozCanvasPrintState() {\n [native code]\n}",
1482 : JS::GetRealmFunctionPrototype
1483 : };
1484 :
1485 : static const DOMIfaceAndProtoJSClass sPrototypeClass = {
1486 : {
1487 : "MozCanvasPrintStatePrototype",
1488 : JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE),
1489 : JS_NULL_CLASS_OPS,
1490 : JS_NULL_CLASS_SPEC,
1491 : JS_NULL_CLASS_EXT,
1492 : JS_NULL_OBJECT_OPS
1493 : },
1494 : eInterfacePrototype,
1495 : false,
1496 : prototypes::id::MozCanvasPrintState,
1497 : PrototypeTraits<prototypes::id::MozCanvasPrintState>::Depth,
1498 : sNativePropertyHooks,
1499 : "[object MozCanvasPrintStatePrototype]",
1500 : JS::GetRealmObjectPrototype
1501 : };
1502 :
1503 : bool
1504 0 : ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
1505 : {
1506 0 : return nsContentUtils::ThreadsafeIsSystemCaller(aCx);
1507 : }
1508 :
1509 : JSObject*
1510 0 : DefineDOMInterface(JSContext* aCx, JS::Handle<JSObject*> aGlobal, JS::Handle<jsid> id, bool aDefineOnGlobal)
1511 : {
1512 0 : return GetConstructorObjectHandle(aCx, aDefineOnGlobal);
1513 : }
1514 :
1515 : static const js::ClassOps sClassOps = {
1516 : _addProperty, /* addProperty */
1517 : nullptr, /* delProperty */
1518 : nullptr, /* getProperty */
1519 : nullptr, /* setProperty */
1520 : nullptr, /* enumerate */
1521 : nullptr, /* newEnumerate */
1522 : nullptr, /* resolve */
1523 : nullptr, /* mayResolve */
1524 : _finalize, /* finalize */
1525 : nullptr, /* call */
1526 : nullptr, /* hasInstance */
1527 : nullptr, /* construct */
1528 : nullptr, /* trace */
1529 : };
1530 :
1531 : static const js::ClassExtension sClassExtension = {
1532 : nullptr, /* weakmapKeyDelegateOp */
1533 : _objectMoved /* objectMovedOp */
1534 : };
1535 :
1536 : static const DOMJSClass sClass = {
1537 : { "MozCanvasPrintState",
1538 : JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1),
1539 : &sClassOps,
1540 : JS_NULL_CLASS_SPEC,
1541 : &sClassExtension,
1542 : JS_NULL_OBJECT_OPS
1543 : },
1544 : { prototypes::id::MozCanvasPrintState, 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 },
1545 : IsBaseOf<nsISupports, mozilla::dom::HTMLCanvasPrintState >::value,
1546 : sNativePropertyHooks,
1547 : FindAssociatedGlobalForNative<mozilla::dom::HTMLCanvasPrintState>::Get,
1548 : GetProtoObjectHandle,
1549 : GetCCParticipant<mozilla::dom::HTMLCanvasPrintState>::Get()
1550 : };
1551 : static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
1552 : "Must have the right minimal number of reserved slots.");
1553 : static_assert(1 >= 1,
1554 : "Must have enough reserved slots.");
1555 :
1556 : const JSClass*
1557 0 : GetJSClass()
1558 : {
1559 0 : return sClass.ToJSClass();
1560 : }
1561 :
1562 : bool
1563 0 : Wrap(JSContext* aCx, mozilla::dom::HTMLCanvasPrintState* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
1564 : {
1565 : MOZ_ASSERT(static_cast<mozilla::dom::HTMLCanvasPrintState*>(aObject) ==
1566 : reinterpret_cast<mozilla::dom::HTMLCanvasPrintState*>(aObject),
1567 : "Multiple inheritance for mozilla::dom::HTMLCanvasPrintState is broken.");
1568 0 : MOZ_ASSERT(ToSupportsIsCorrect(aObject));
1569 0 : MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
1570 0 : MOZ_ASSERT(!aCache->GetWrapper(),
1571 : "You should probably not be using Wrap() directly; use "
1572 : "GetOrCreateDOMReflector instead");
1573 :
1574 0 : MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
1575 : "nsISupports must be on our primary inheritance chain");
1576 :
1577 0 : JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
1578 0 : if (!global) {
1579 0 : return false;
1580 : }
1581 0 : MOZ_ASSERT(JS_IsGlobalObject(global));
1582 0 : MOZ_ASSERT(JS::ObjectIsNotGray(global));
1583 :
1584 : // That might have ended up wrapping us already, due to the wonders
1585 : // of XBL. Check for that, and bail out as needed.
1586 0 : aReflector.set(aCache->GetWrapper());
1587 0 : if (aReflector) {
1588 : #ifdef DEBUG
1589 0 : binding_detail::AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
1590 : #endif // DEBUG
1591 0 : return true;
1592 : }
1593 :
1594 0 : JSAutoCompartment ac(aCx, global);
1595 0 : JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
1596 0 : if (!canonicalProto) {
1597 0 : return false;
1598 : }
1599 0 : JS::Rooted<JSObject*> proto(aCx);
1600 0 : if (aGivenProto) {
1601 0 : proto = aGivenProto;
1602 : // Unfortunately, while aGivenProto was in the compartment of aCx
1603 : // coming in, we changed compartments to that of "parent" so may need
1604 : // to wrap the proto here.
1605 0 : if (js::GetContextCompartment(aCx) != js::GetObjectCompartment(proto)) {
1606 0 : if (!JS_WrapObject(aCx, &proto)) {
1607 0 : return false;
1608 : }
1609 : }
1610 : } else {
1611 0 : proto = canonicalProto;
1612 : }
1613 :
1614 0 : BindingJSObjectCreator<mozilla::dom::HTMLCanvasPrintState> creator(aCx);
1615 0 : creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
1616 0 : if (!aReflector) {
1617 0 : return false;
1618 : }
1619 :
1620 0 : aCache->SetWrapper(aReflector);
1621 0 : creator.InitializationSucceeded();
1622 :
1623 0 : MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
1624 : aCache->GetWrapperPreserveColor() == aReflector);
1625 : // If proto != canonicalProto, we have to preserve our wrapper;
1626 : // otherwise we won't be able to properly recreate it later, since
1627 : // we won't know what proto to use. Note that we don't check
1628 : // aGivenProto here, since it's entirely possible (and even
1629 : // somewhat common) to have a non-null aGivenProto which is the
1630 : // same as canonicalProto.
1631 0 : if (proto != canonicalProto) {
1632 0 : PreserveWrapper(aObject);
1633 : }
1634 :
1635 0 : return true;
1636 : }
1637 :
1638 : const NativePropertyHooks sNativePropertyHooks[] = { {
1639 : nullptr,
1640 : nullptr,
1641 : nullptr,
1642 : { sNativeProperties.Upcast(), nullptr },
1643 : prototypes::id::MozCanvasPrintState,
1644 : constructors::id::MozCanvasPrintState,
1645 : nullptr,
1646 : &DefaultXrayExpandoObjectClass
1647 : } };
1648 :
1649 : void
1650 0 : CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, bool aDefineOnGlobal)
1651 : {
1652 0 : JS::Rooted<JSObject*> parentProto(aCx, JS::GetRealmObjectPrototype(aCx));
1653 0 : if (!parentProto) {
1654 0 : return;
1655 : }
1656 :
1657 0 : JS::Rooted<JSObject*> constructorProto(aCx, JS::GetRealmFunctionPrototype(aCx));
1658 0 : if (!constructorProto) {
1659 0 : return;
1660 : }
1661 :
1662 : static bool sIdsInited = false;
1663 0 : if (!sIdsInited && NS_IsMainThread()) {
1664 0 : if (!InitIds(aCx, sNativeProperties.Upcast())) {
1665 0 : return;
1666 : }
1667 0 : sIdsInited = true;
1668 : }
1669 :
1670 0 : JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::MozCanvasPrintState);
1671 0 : JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::MozCanvasPrintState);
1672 0 : dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
1673 : &sPrototypeClass.mBase, protoCache,
1674 : constructorProto, &sInterfaceObjectClass.mBase, 0, nullptr,
1675 : interfaceCache,
1676 : sNativeProperties.Upcast(),
1677 : nullptr,
1678 : "MozCanvasPrintState", aDefineOnGlobal,
1679 : nullptr,
1680 0 : false);
1681 : }
1682 :
1683 : JS::Handle<JSObject*>
1684 0 : GetProtoObjectHandle(JSContext* aCx)
1685 : {
1686 : /* Get the interface prototype object for this class. This will create the
1687 : object as needed. */
1688 0 : bool aDefineOnGlobal = true;
1689 :
1690 : /* Make sure our global is sane. Hopefully we can remove this sometime */
1691 0 : JSObject* global = JS::CurrentGlobalOrNull(aCx);
1692 0 : if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
1693 0 : return nullptr;
1694 : }
1695 :
1696 : /* Check to see whether the interface objects are already installed */
1697 0 : ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
1698 0 : if (!protoAndIfaceCache.HasEntryInSlot(prototypes::id::MozCanvasPrintState)) {
1699 0 : JS::Rooted<JSObject*> rootedGlobal(aCx, global);
1700 0 : CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
1701 : }
1702 :
1703 : /*
1704 : * The object might _still_ be null, but that's OK.
1705 : *
1706 : * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
1707 : * traced by TraceProtoAndIfaceCache() and its contents are never
1708 : * changed after they have been set.
1709 : *
1710 : * Calling address() avoids the read read barrier that does gray
1711 : * unmarking, but it's not possible for the object to be gray here.
1712 : */
1713 :
1714 0 : const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(prototypes::id::MozCanvasPrintState);
1715 0 : MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
1716 0 : return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
1717 : }
1718 :
1719 : JS::Handle<JSObject*>
1720 0 : GetConstructorObjectHandle(JSContext* aCx, bool aDefineOnGlobal)
1721 : {
1722 : /* Get the interface object for this class. This will create the object as
1723 : needed. */
1724 :
1725 : /* Make sure our global is sane. Hopefully we can remove this sometime */
1726 0 : JSObject* global = JS::CurrentGlobalOrNull(aCx);
1727 0 : if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
1728 0 : return nullptr;
1729 : }
1730 :
1731 : /* Check to see whether the interface objects are already installed */
1732 0 : ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
1733 0 : if (!protoAndIfaceCache.HasEntryInSlot(constructors::id::MozCanvasPrintState)) {
1734 0 : JS::Rooted<JSObject*> rootedGlobal(aCx, global);
1735 0 : CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
1736 : }
1737 :
1738 : /*
1739 : * The object might _still_ be null, but that's OK.
1740 : *
1741 : * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
1742 : * traced by TraceProtoAndIfaceCache() and its contents are never
1743 : * changed after they have been set.
1744 : *
1745 : * Calling address() avoids the read read barrier that does gray
1746 : * unmarking, but it's not possible for the object to be gray here.
1747 : */
1748 :
1749 0 : const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(constructors::id::MozCanvasPrintState);
1750 0 : MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
1751 0 : return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
1752 : }
1753 :
1754 : JSObject*
1755 0 : GetConstructorObject(JSContext* aCx)
1756 : {
1757 0 : return GetConstructorObjectHandle(aCx);
1758 : }
1759 :
1760 : } // namespace MozCanvasPrintStateBinding
1761 :
1762 :
1763 :
1764 : } // namespace dom
1765 : } // namespace mozilla
|