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