Line data Source code
1 : /* THIS FILE IS AUTOGENERATED FROM DOMParser.webidl BY Codegen.py - DO NOT EDIT */
2 :
3 : #include "DOMParserBinding.h"
4 : #include "WrapperFactory.h"
5 : #include "jsapi.h"
6 : #include "jsfriendapi.h"
7 : #include "mozilla/OwningNonNull.h"
8 : #include "mozilla/dom/BindingUtils.h"
9 : #include "mozilla/dom/DOMJSClass.h"
10 : #include "mozilla/dom/DOMParser.h"
11 : #include "mozilla/dom/NonRefcountedDOMObject.h"
12 : #include "mozilla/dom/Nullable.h"
13 : #include "mozilla/dom/PrimitiveConversions.h"
14 : #include "mozilla/dom/TypedArray.h"
15 : #include "mozilla/dom/XrayExpandoClass.h"
16 : #include "nsContentUtils.h"
17 : #include "nsIDocument.h"
18 : #include "nsIInputStream.h"
19 : #include "nsIPrincipal.h"
20 : #include "nsISupports.h"
21 : #include "nsIURI.h"
22 : #include "xpcjsid.h"
23 :
24 : namespace mozilla {
25 : namespace dom {
26 :
27 : namespace SupportedTypeValues {
28 : extern const EnumEntry strings[6] = {
29 : {"text/html", 9},
30 : {"text/xml", 8},
31 : {"application/xml", 15},
32 : {"application/xhtml+xml", 21},
33 : {"image/svg+xml", 13},
34 : { nullptr, 0 }
35 : };
36 : } // namespace SupportedTypeValues
37 :
38 : bool
39 0 : ToJSValue(JSContext* aCx, SupportedType aArgument, JS::MutableHandle<JS::Value> aValue)
40 : {
41 0 : MOZ_ASSERT(uint32_t(aArgument) < ArrayLength(SupportedTypeValues::strings));
42 : JSString* resultStr =
43 0 : JS_NewStringCopyN(aCx, SupportedTypeValues::strings[uint32_t(aArgument)].value,
44 0 : SupportedTypeValues::strings[uint32_t(aArgument)].length);
45 0 : if (!resultStr) {
46 0 : return false;
47 : }
48 0 : aValue.setString(resultStr);
49 0 : return true;
50 : }
51 :
52 :
53 : namespace DOMParserBinding {
54 :
55 : static bool
56 0 : parseFromString(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::DOMParser* self, const JSJitMethodCallArgs& args)
57 : {
58 0 : if (MOZ_UNLIKELY(args.length() < 2)) {
59 0 : return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "DOMParser.parseFromString");
60 : }
61 0 : binding_detail::FakeString arg0;
62 0 : if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
63 0 : return false;
64 : }
65 : SupportedType arg1;
66 : {
67 : int index;
68 0 : if (!FindEnumStringIndex<true>(cx, args[1], SupportedTypeValues::strings, "SupportedType", "Argument 2 of DOMParser.parseFromString", &index)) {
69 0 : return false;
70 : }
71 0 : MOZ_ASSERT(index >= 0);
72 0 : arg1 = static_cast<SupportedType>(index);
73 : }
74 0 : binding_detail::FastErrorResult rv;
75 0 : auto result(StrongOrRawPtr<nsIDocument>(self->ParseFromString(NonNullHelper(Constify(arg0)), arg1, rv)));
76 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
77 0 : return false;
78 : }
79 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
80 : static_assert(!IsPointer<decltype(result)>::value,
81 : "NewObject implies that we need to keep the object alive with a strong reference.");
82 0 : if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
83 0 : MOZ_ASSERT(true || JS_IsExceptionPending(cx));
84 0 : return false;
85 : }
86 0 : return true;
87 : }
88 :
89 : static const JSJitInfo parseFromString_methodinfo = {
90 : { (JSJitGetterOp)parseFromString },
91 : { prototypes::id::DOMParser },
92 : { PrototypeTraits<prototypes::id::DOMParser>::Depth },
93 : JSJitInfo::Method,
94 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
95 : JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
96 : false, /* isInfallible. False in setters. */
97 : false, /* isMovable. Not relevant for setters. */
98 : false, /* isEliminatable. Not relevant for setters. */
99 : false, /* isAlwaysInSlot. Only relevant for getters. */
100 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
101 : false, /* isTypedMethod. Only relevant for methods. */
102 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
103 : };
104 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
105 : static_assert(0 < 1, "There is no slot for us");
106 :
107 : static bool
108 0 : parseFromBuffer(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::DOMParser* self, const JSJitMethodCallArgs& args)
109 : {
110 0 : unsigned argcount = std::min(args.length(), 3u);
111 0 : switch (argcount) {
112 : case 3: {
113 0 : if (args[0].isObject()) {
114 : do {
115 0 : RootedTypedArray<Uint8Array> arg0(cx);
116 0 : if (!arg0.Init(&args[0].toObject())) {
117 0 : break;
118 : }
119 : uint32_t arg1;
120 0 : if (!ValueToPrimitive<uint32_t, eDefault>(cx, args[1], &arg1)) {
121 0 : return false;
122 : }
123 : SupportedType arg2;
124 : {
125 : int index;
126 0 : if (!FindEnumStringIndex<true>(cx, args[2], SupportedTypeValues::strings, "SupportedType", "Argument 3 of DOMParser.parseFromBuffer", &index)) {
127 0 : return false;
128 : }
129 0 : MOZ_ASSERT(index >= 0);
130 0 : arg2 = static_cast<SupportedType>(index);
131 : }
132 0 : binding_detail::FastErrorResult rv;
133 0 : auto result(StrongOrRawPtr<nsIDocument>(self->ParseFromBuffer(Constify(arg0), arg1, arg2, rv)));
134 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
135 0 : return false;
136 : }
137 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
138 : static_assert(!IsPointer<decltype(result)>::value,
139 : "NewObject implies that we need to keep the object alive with a strong reference.");
140 0 : if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
141 0 : MOZ_ASSERT(true || JS_IsExceptionPending(cx));
142 0 : return false;
143 : }
144 0 : return true;
145 : } while (0);
146 : do {
147 0 : binding_detail::AutoSequence<uint8_t> arg0;
148 0 : JS::ForOfIterator iter(cx);
149 0 : if (!iter.init(args[0], JS::ForOfIterator::AllowNonIterable)) {
150 0 : return false;
151 : }
152 0 : if (!iter.valueIsIterable()) {
153 0 : break;
154 : }
155 0 : binding_detail::AutoSequence<uint8_t> &arr = arg0;
156 0 : JS::Rooted<JS::Value> temp(cx);
157 : while (true) {
158 : bool done;
159 0 : if (!iter.next(&temp, &done)) {
160 0 : return false;
161 : }
162 0 : if (done) {
163 0 : break;
164 : }
165 0 : uint8_t* slotPtr = arr.AppendElement(mozilla::fallible);
166 0 : if (!slotPtr) {
167 0 : JS_ReportOutOfMemory(cx);
168 0 : return false;
169 : }
170 0 : uint8_t& slot = *slotPtr;
171 0 : if (!ValueToPrimitive<uint8_t, eDefault>(cx, temp, &slot)) {
172 0 : return false;
173 : }
174 0 : }
175 : uint32_t arg1;
176 0 : if (!ValueToPrimitive<uint32_t, eDefault>(cx, args[1], &arg1)) {
177 0 : return false;
178 : }
179 : SupportedType arg2;
180 : {
181 : int index;
182 0 : if (!FindEnumStringIndex<true>(cx, args[2], SupportedTypeValues::strings, "SupportedType", "Argument 3 of DOMParser.parseFromBuffer", &index)) {
183 0 : return false;
184 : }
185 0 : MOZ_ASSERT(index >= 0);
186 0 : arg2 = static_cast<SupportedType>(index);
187 : }
188 0 : binding_detail::FastErrorResult rv;
189 0 : auto result(StrongOrRawPtr<nsIDocument>(self->ParseFromBuffer(Constify(arg0), arg1, arg2, rv)));
190 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
191 0 : return false;
192 : }
193 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
194 : static_assert(!IsPointer<decltype(result)>::value,
195 : "NewObject implies that we need to keep the object alive with a strong reference.");
196 0 : if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
197 0 : MOZ_ASSERT(true || JS_IsExceptionPending(cx));
198 0 : return false;
199 : }
200 0 : return true;
201 : } while (0);
202 : }
203 0 : return ThrowErrorMessage(cx, MSG_OVERLOAD_RESOLUTION_FAILED, "1", "3", "DOMParser.parseFromBuffer");
204 : break;
205 : }
206 : default: {
207 0 : return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "DOMParser.parseFromBuffer");
208 : break;
209 : }
210 : }
211 : MOZ_CRASH("We have an always-returning default case");
212 : return false;
213 : }
214 :
215 : static const JSJitInfo parseFromBuffer_methodinfo = {
216 : { (JSJitGetterOp)parseFromBuffer },
217 : { prototypes::id::DOMParser },
218 : { PrototypeTraits<prototypes::id::DOMParser>::Depth },
219 : JSJitInfo::Method,
220 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
221 : JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
222 : false, /* isInfallible. False in setters. */
223 : false, /* isMovable. Not relevant for setters. */
224 : false, /* isEliminatable. Not relevant for setters. */
225 : false, /* isAlwaysInSlot. Only relevant for getters. */
226 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
227 : false, /* isTypedMethod. Only relevant for methods. */
228 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
229 : };
230 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
231 : static_assert(0 < 1, "There is no slot for us");
232 :
233 : static bool
234 0 : parseFromStream(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::DOMParser* self, const JSJitMethodCallArgs& args)
235 : {
236 0 : if (MOZ_UNLIKELY(args.length() < 4)) {
237 0 : return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "DOMParser.parseFromStream");
238 : }
239 : nsIInputStream* arg0;
240 0 : RefPtr<nsIInputStream> arg0_holder;
241 0 : if (args[0].isObject()) {
242 0 : JS::Rooted<JSObject*> source(cx, &args[0].toObject());
243 0 : if (NS_FAILED(UnwrapArg<nsIInputStream>(cx, source, getter_AddRefs(arg0_holder)))) {
244 0 : ThrowErrorMessage(cx, MSG_DOES_NOT_IMPLEMENT_INTERFACE, "Argument 1 of DOMParser.parseFromStream", "InputStream");
245 0 : return false;
246 : }
247 0 : MOZ_ASSERT(arg0_holder);
248 0 : arg0 = arg0_holder;
249 : } else {
250 0 : ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 1 of DOMParser.parseFromStream");
251 0 : return false;
252 : }
253 0 : binding_detail::FakeString arg1;
254 0 : if (!ConvertJSValueToString(cx, args[1], eNull, eNull, arg1)) {
255 0 : return false;
256 : }
257 : int32_t arg2;
258 0 : if (!ValueToPrimitive<int32_t, eDefault>(cx, args[2], &arg2)) {
259 0 : return false;
260 : }
261 : SupportedType arg3;
262 : {
263 : int index;
264 0 : if (!FindEnumStringIndex<true>(cx, args[3], SupportedTypeValues::strings, "SupportedType", "Argument 4 of DOMParser.parseFromStream", &index)) {
265 0 : return false;
266 : }
267 0 : MOZ_ASSERT(index >= 0);
268 0 : arg3 = static_cast<SupportedType>(index);
269 : }
270 0 : binding_detail::FastErrorResult rv;
271 0 : auto result(StrongOrRawPtr<nsIDocument>(self->ParseFromStream(NonNullHelper(arg0), NonNullHelper(Constify(arg1)), arg2, arg3, rv)));
272 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
273 0 : return false;
274 : }
275 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
276 : static_assert(!IsPointer<decltype(result)>::value,
277 : "NewObject implies that we need to keep the object alive with a strong reference.");
278 0 : if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
279 0 : MOZ_ASSERT(true || JS_IsExceptionPending(cx));
280 0 : return false;
281 : }
282 0 : return true;
283 : }
284 :
285 : static const JSJitInfo parseFromStream_methodinfo = {
286 : { (JSJitGetterOp)parseFromStream },
287 : { prototypes::id::DOMParser },
288 : { PrototypeTraits<prototypes::id::DOMParser>::Depth },
289 : JSJitInfo::Method,
290 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
291 : JSVAL_TYPE_OBJECT, /* 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 : init(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::DOMParser* self, const JSJitMethodCallArgs& args)
305 : {
306 : nsIPrincipal* arg0;
307 0 : RefPtr<nsIPrincipal> arg0_holder;
308 0 : if (args.hasDefined(0)) {
309 0 : if (args[0].isObject()) {
310 0 : JS::Rooted<JSObject*> source(cx, &args[0].toObject());
311 0 : if (NS_FAILED(UnwrapArg<nsIPrincipal>(cx, source, getter_AddRefs(arg0_holder)))) {
312 0 : ThrowErrorMessage(cx, MSG_DOES_NOT_IMPLEMENT_INTERFACE, "Argument 1 of DOMParser.init", "Principal");
313 0 : return false;
314 : }
315 0 : MOZ_ASSERT(arg0_holder);
316 0 : arg0 = arg0_holder;
317 0 : } else if (args[0].isNullOrUndefined()) {
318 0 : arg0 = nullptr;
319 : } else {
320 0 : ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 1 of DOMParser.init");
321 0 : return false;
322 : }
323 : } else {
324 0 : arg0 = nullptr;
325 : }
326 : nsIURI* arg1;
327 0 : RefPtr<nsIURI> arg1_holder;
328 0 : if (args.hasDefined(1)) {
329 0 : if (args[1].isObject()) {
330 0 : JS::Rooted<JSObject*> source(cx, &args[1].toObject());
331 0 : if (NS_FAILED(UnwrapArg<nsIURI>(cx, source, getter_AddRefs(arg1_holder)))) {
332 0 : ThrowErrorMessage(cx, MSG_DOES_NOT_IMPLEMENT_INTERFACE, "Argument 2 of DOMParser.init", "URI");
333 0 : return false;
334 : }
335 0 : MOZ_ASSERT(arg1_holder);
336 0 : arg1 = arg1_holder;
337 0 : } else if (args[1].isNullOrUndefined()) {
338 0 : arg1 = nullptr;
339 : } else {
340 0 : ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 2 of DOMParser.init");
341 0 : return false;
342 : }
343 : } else {
344 0 : arg1 = nullptr;
345 : }
346 : nsIURI* arg2;
347 0 : RefPtr<nsIURI> arg2_holder;
348 0 : if (args.hasDefined(2)) {
349 0 : if (args[2].isObject()) {
350 0 : JS::Rooted<JSObject*> source(cx, &args[2].toObject());
351 0 : if (NS_FAILED(UnwrapArg<nsIURI>(cx, source, getter_AddRefs(arg2_holder)))) {
352 0 : ThrowErrorMessage(cx, MSG_DOES_NOT_IMPLEMENT_INTERFACE, "Argument 3 of DOMParser.init", "URI");
353 0 : return false;
354 : }
355 0 : MOZ_ASSERT(arg2_holder);
356 0 : arg2 = arg2_holder;
357 0 : } else if (args[2].isNullOrUndefined()) {
358 0 : arg2 = nullptr;
359 : } else {
360 0 : ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 3 of DOMParser.init");
361 0 : return false;
362 : }
363 : } else {
364 0 : arg2 = nullptr;
365 : }
366 0 : binding_detail::FastErrorResult rv;
367 0 : self->Init(Constify(arg0), Constify(arg1), Constify(arg2), rv);
368 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
369 0 : return false;
370 : }
371 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
372 0 : args.rval().setUndefined();
373 0 : return true;
374 : }
375 :
376 : static const JSJitInfo init_methodinfo = {
377 : { (JSJitGetterOp)init },
378 : { prototypes::id::DOMParser },
379 : { PrototypeTraits<prototypes::id::DOMParser>::Depth },
380 : JSJitInfo::Method,
381 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
382 : JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
383 : false, /* isInfallible. False in setters. */
384 : false, /* isMovable. Not relevant for setters. */
385 : false, /* isEliminatable. Not relevant for setters. */
386 : false, /* isAlwaysInSlot. Only relevant for getters. */
387 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
388 : false, /* isTypedMethod. Only relevant for methods. */
389 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
390 : };
391 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
392 : static_assert(0 < 1, "There is no slot for us");
393 :
394 : static bool
395 0 : _addProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::Handle<JS::Value> val)
396 : {
397 0 : mozilla::dom::DOMParser* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::DOMParser>(obj);
398 : // We don't want to preserve if we don't have a wrapper, and we
399 : // obviously can't preserve if we're not initialized.
400 0 : if (self && self->GetWrapperPreserveColor()) {
401 0 : PreserveWrapper(self);
402 : }
403 0 : return true;
404 : }
405 :
406 : static void
407 0 : _finalize(js::FreeOp* fop, JSObject* obj)
408 : {
409 0 : mozilla::dom::DOMParser* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::DOMParser>(obj);
410 0 : if (self) {
411 0 : ClearWrapper(self, self, obj);
412 0 : AddForDeferredFinalization<mozilla::dom::DOMParser>(self);
413 : }
414 0 : }
415 :
416 : static void
417 0 : _objectMoved(JSObject* obj, const JSObject* old)
418 : {
419 0 : mozilla::dom::DOMParser* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::DOMParser>(obj);
420 0 : if (self) {
421 0 : UpdateWrapper(self, self, obj, old);
422 : }
423 0 : }
424 :
425 : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
426 : #if defined(__clang__)
427 : #pragma clang diagnostic push
428 : #pragma clang diagnostic ignored "-Wmissing-braces"
429 : #endif
430 : static const JSFunctionSpec sMethods_specs[] = {
431 : JS_FNSPEC("parseFromString", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&parseFromString_methodinfo), 2, JSPROP_ENUMERATE, nullptr),
432 : JS_FS_END,
433 : JS_FNSPEC("QueryInterface", QueryInterface, nullptr, 1, 0, nullptr),
434 : JS_FS_END
435 : };
436 : #if defined(__clang__)
437 : #pragma clang diagnostic pop
438 : #endif
439 :
440 : static PrefableDisablers sMethods_disablers2 = {
441 : true, false, 0, &WantsQueryInterface<mozilla::dom::DOMParser>::Enabled
442 : };
443 :
444 : // Can't be const because the pref-enabled boolean needs to be writable
445 : static Prefable<const JSFunctionSpec> sMethods[] = {
446 : { nullptr, &sMethods_specs[0] },
447 : { &sMethods_disablers2, &sMethods_specs[2] },
448 : { nullptr, nullptr }
449 : };
450 :
451 : static_assert(2 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
452 : "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
453 : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
454 : "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
455 :
456 : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
457 : #if defined(__clang__)
458 : #pragma clang diagnostic push
459 : #pragma clang diagnostic ignored "-Wmissing-braces"
460 : #endif
461 : static const JSFunctionSpec sChromeMethods_specs[] = {
462 : JS_FNSPEC("parseFromBuffer", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&parseFromBuffer_methodinfo), 3, JSPROP_ENUMERATE, nullptr),
463 : JS_FNSPEC("parseFromStream", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&parseFromStream_methodinfo), 4, JSPROP_ENUMERATE, nullptr),
464 : JS_FNSPEC("init", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&init_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
465 : JS_FS_END
466 : };
467 : #if defined(__clang__)
468 : #pragma clang diagnostic pop
469 : #endif
470 :
471 :
472 : // Can't be const because the pref-enabled boolean needs to be writable
473 : static Prefable<const JSFunctionSpec> sChromeMethods[] = {
474 : { nullptr, &sChromeMethods_specs[0] },
475 : { nullptr, nullptr }
476 : };
477 :
478 : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
479 : "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
480 : static_assert(3 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
481 : "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
482 :
483 :
484 : static uint16_t sNativeProperties_sortedPropertyIndices[2];
485 : static PropertyInfo sNativeProperties_propertyInfos[2];
486 :
487 : static const NativePropertiesN<1> sNativeProperties = {
488 : false, 0,
489 : false, 0,
490 : true, 0 /* sMethods */,
491 : false, 0,
492 : false, 0,
493 : false, 0,
494 : false, 0,
495 : -1,
496 : 2,
497 : sNativeProperties_sortedPropertyIndices,
498 : {
499 : { sMethods, &sNativeProperties_propertyInfos[0] }
500 : }
501 : };
502 : static_assert(2 < 1ull << CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount),
503 : "We have a property info count that is oversized");
504 :
505 : static uint16_t sChromeOnlyNativeProperties_sortedPropertyIndices[3];
506 : static PropertyInfo sChromeOnlyNativeProperties_propertyInfos[3];
507 :
508 : static const NativePropertiesN<1> sChromeOnlyNativeProperties = {
509 : false, 0,
510 : false, 0,
511 : true, 0 /* sChromeMethods */,
512 : false, 0,
513 : false, 0,
514 : false, 0,
515 : false, 0,
516 : -1,
517 : 3,
518 : sChromeOnlyNativeProperties_sortedPropertyIndices,
519 : {
520 : { sChromeMethods, &sChromeOnlyNativeProperties_propertyInfos[0] }
521 : }
522 : };
523 : static_assert(3 < 1ull << CHAR_BIT * sizeof(sChromeOnlyNativeProperties.propertyInfoCount),
524 : "We have a property info count that is oversized");
525 :
526 : static bool
527 0 : _constructor(JSContext* cx, unsigned argc, JS::Value* vp)
528 : {
529 0 : JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
530 0 : JS::Rooted<JSObject*> obj(cx, &args.callee());
531 0 : if (!args.isConstructing()) {
532 : // XXXbz wish I could get the name from the callee instead of
533 : // Adding more relocations
534 0 : return ThrowConstructorWithoutNew(cx, "DOMParser");
535 : }
536 :
537 0 : GlobalObject global(cx, obj);
538 0 : if (global.Failed()) {
539 0 : return false;
540 : }
541 :
542 0 : JS::Rooted<JSObject*> desiredProto(cx);
543 0 : if (!GetDesiredProto(cx, args, &desiredProto)) {
544 0 : return false;
545 : }
546 :
547 0 : unsigned argcount = std::min(args.length(), 3u);
548 0 : switch (argcount) {
549 : case 0: {
550 0 : bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
551 0 : Maybe<JSAutoCompartment> ac;
552 0 : if (objIsXray) {
553 0 : obj = js::CheckedUnwrap(obj);
554 0 : if (!obj) {
555 0 : return false;
556 : }
557 0 : ac.emplace(cx, obj);
558 0 : if (!JS_WrapObject(cx, &desiredProto)) {
559 0 : return false;
560 : }
561 : }
562 0 : binding_detail::FastErrorResult rv;
563 0 : auto result(StrongOrRawPtr<mozilla::dom::DOMParser>(mozilla::dom::DOMParser::Constructor(global, rv)));
564 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
565 0 : return false;
566 : }
567 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
568 : static_assert(!IsPointer<decltype(result)>::value,
569 : "NewObject implies that we need to keep the object alive with a strong reference.");
570 0 : if (!GetOrCreateDOMReflector(cx, result, args.rval(), desiredProto)) {
571 0 : MOZ_ASSERT(true || JS_IsExceptionPending(cx));
572 0 : return false;
573 : }
574 0 : return true;
575 : break;
576 : }
577 : case 1: {
578 : MOZ_FALLTHROUGH;
579 : }
580 : case 2: {
581 : MOZ_FALLTHROUGH;
582 : }
583 : case 3: {
584 0 : bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
585 : nsIPrincipal* arg0;
586 0 : RefPtr<nsIPrincipal> arg0_holder;
587 0 : if (args[0].isObject()) {
588 0 : JS::Rooted<JSObject*> source(cx, &args[0].toObject());
589 0 : if (NS_FAILED(UnwrapArg<nsIPrincipal>(cx, source, getter_AddRefs(arg0_holder)))) {
590 0 : ThrowErrorMessage(cx, MSG_DOES_NOT_IMPLEMENT_INTERFACE, "Argument 1 of DOMParser.constructor", "Principal");
591 0 : return false;
592 : }
593 0 : MOZ_ASSERT(arg0_holder);
594 0 : arg0 = arg0_holder;
595 0 : } else if (args[0].isNullOrUndefined()) {
596 0 : arg0 = nullptr;
597 : } else {
598 0 : ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 1 of DOMParser.constructor");
599 0 : return false;
600 : }
601 : nsIURI* arg1;
602 0 : RefPtr<nsIURI> arg1_holder;
603 0 : if (args.hasDefined(1)) {
604 0 : if (args[1].isObject()) {
605 0 : JS::Rooted<JSObject*> source(cx, &args[1].toObject());
606 0 : if (NS_FAILED(UnwrapArg<nsIURI>(cx, source, getter_AddRefs(arg1_holder)))) {
607 0 : ThrowErrorMessage(cx, MSG_DOES_NOT_IMPLEMENT_INTERFACE, "Argument 2 of DOMParser.constructor", "URI");
608 0 : return false;
609 : }
610 0 : MOZ_ASSERT(arg1_holder);
611 0 : arg1 = arg1_holder;
612 0 : } else if (args[1].isNullOrUndefined()) {
613 0 : arg1 = nullptr;
614 : } else {
615 0 : ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 2 of DOMParser.constructor");
616 0 : return false;
617 : }
618 : } else {
619 0 : arg1 = nullptr;
620 : }
621 : nsIURI* arg2;
622 0 : RefPtr<nsIURI> arg2_holder;
623 0 : if (args.hasDefined(2)) {
624 0 : if (args[2].isObject()) {
625 0 : JS::Rooted<JSObject*> source(cx, &args[2].toObject());
626 0 : if (NS_FAILED(UnwrapArg<nsIURI>(cx, source, getter_AddRefs(arg2_holder)))) {
627 0 : ThrowErrorMessage(cx, MSG_DOES_NOT_IMPLEMENT_INTERFACE, "Argument 3 of DOMParser.constructor", "URI");
628 0 : return false;
629 : }
630 0 : MOZ_ASSERT(arg2_holder);
631 0 : arg2 = arg2_holder;
632 0 : } else if (args[2].isNullOrUndefined()) {
633 0 : arg2 = nullptr;
634 : } else {
635 0 : ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 3 of DOMParser.constructor");
636 0 : return false;
637 : }
638 : } else {
639 0 : arg2 = nullptr;
640 : }
641 0 : Maybe<JSAutoCompartment> ac;
642 0 : if (objIsXray) {
643 0 : obj = js::CheckedUnwrap(obj);
644 0 : if (!obj) {
645 0 : return false;
646 : }
647 0 : ac.emplace(cx, obj);
648 0 : if (!JS_WrapObject(cx, &desiredProto)) {
649 0 : return false;
650 : }
651 : }
652 0 : binding_detail::FastErrorResult rv;
653 0 : auto result(StrongOrRawPtr<mozilla::dom::DOMParser>(mozilla::dom::DOMParser::Constructor(global, Constify(arg0), Constify(arg1), Constify(arg2), rv)));
654 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
655 0 : return false;
656 : }
657 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
658 : static_assert(!IsPointer<decltype(result)>::value,
659 : "NewObject implies that we need to keep the object alive with a strong reference.");
660 0 : if (!GetOrCreateDOMReflector(cx, result, args.rval(), desiredProto)) {
661 0 : MOZ_ASSERT(true || JS_IsExceptionPending(cx));
662 0 : return false;
663 : }
664 0 : return true;
665 : break;
666 : }
667 : default: {
668 0 : return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "DOMParser");
669 : break;
670 : }
671 : }
672 : MOZ_CRASH("We have an always-returning default case");
673 : return false;
674 : }
675 :
676 : static const js::ClassOps sInterfaceObjectClassOps = {
677 : nullptr, /* addProperty */
678 : nullptr, /* delProperty */
679 : nullptr, /* getProperty */
680 : nullptr, /* setProperty */
681 : nullptr, /* enumerate */
682 : nullptr, /* newEnumerate */
683 : nullptr, /* resolve */
684 : nullptr, /* mayResolve */
685 : nullptr, /* finalize */
686 : _constructor, /* call */
687 : nullptr, /* hasInstance */
688 : _constructor, /* construct */
689 : nullptr, /* trace */
690 : };
691 :
692 : static const DOMIfaceAndProtoJSClass sInterfaceObjectClass = {
693 : {
694 : "Function",
695 : JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_SLOTS_BASE),
696 : &sInterfaceObjectClassOps,
697 : JS_NULL_CLASS_SPEC,
698 : JS_NULL_CLASS_EXT,
699 : &sInterfaceObjectClassObjectOps
700 : },
701 : eInterface,
702 : true,
703 : prototypes::id::DOMParser,
704 : PrototypeTraits<prototypes::id::DOMParser>::Depth,
705 : sNativePropertyHooks,
706 : "function DOMParser() {\n [native code]\n}",
707 : JS::GetRealmFunctionPrototype
708 : };
709 :
710 : static const DOMIfaceAndProtoJSClass sPrototypeClass = {
711 : {
712 : "DOMParserPrototype",
713 : JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE),
714 : JS_NULL_CLASS_OPS,
715 : JS_NULL_CLASS_SPEC,
716 : JS_NULL_CLASS_EXT,
717 : JS_NULL_OBJECT_OPS
718 : },
719 : eInterfacePrototype,
720 : false,
721 : prototypes::id::DOMParser,
722 : PrototypeTraits<prototypes::id::DOMParser>::Depth,
723 : sNativePropertyHooks,
724 : "[object DOMParserPrototype]",
725 : JS::GetRealmObjectPrototype
726 : };
727 :
728 : JSObject*
729 0 : DefineDOMInterface(JSContext* aCx, JS::Handle<JSObject*> aGlobal, JS::Handle<jsid> id, bool aDefineOnGlobal)
730 : {
731 0 : return GetConstructorObjectHandle(aCx, aDefineOnGlobal);
732 : }
733 :
734 : static const js::ClassOps sClassOps = {
735 : _addProperty, /* addProperty */
736 : nullptr, /* delProperty */
737 : nullptr, /* getProperty */
738 : nullptr, /* setProperty */
739 : nullptr, /* enumerate */
740 : nullptr, /* newEnumerate */
741 : nullptr, /* resolve */
742 : nullptr, /* mayResolve */
743 : _finalize, /* finalize */
744 : nullptr, /* call */
745 : nullptr, /* hasInstance */
746 : nullptr, /* construct */
747 : nullptr, /* trace */
748 : };
749 :
750 : static const js::ClassExtension sClassExtension = {
751 : nullptr, /* weakmapKeyDelegateOp */
752 : _objectMoved /* objectMovedOp */
753 : };
754 :
755 : static const DOMJSClass sClass = {
756 : { "DOMParser",
757 : JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1),
758 : &sClassOps,
759 : JS_NULL_CLASS_SPEC,
760 : &sClassExtension,
761 : JS_NULL_OBJECT_OPS
762 : },
763 : { prototypes::id::DOMParser, 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 },
764 : IsBaseOf<nsISupports, mozilla::dom::DOMParser >::value,
765 : sNativePropertyHooks,
766 : FindAssociatedGlobalForNative<mozilla::dom::DOMParser>::Get,
767 : GetProtoObjectHandle,
768 : GetCCParticipant<mozilla::dom::DOMParser>::Get()
769 : };
770 : static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
771 : "Must have the right minimal number of reserved slots.");
772 : static_assert(1 >= 1,
773 : "Must have enough reserved slots.");
774 :
775 : const JSClass*
776 0 : GetJSClass()
777 : {
778 0 : return sClass.ToJSClass();
779 : }
780 :
781 : bool
782 0 : Wrap(JSContext* aCx, mozilla::dom::DOMParser* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
783 : {
784 : MOZ_ASSERT(static_cast<mozilla::dom::DOMParser*>(aObject) ==
785 : reinterpret_cast<mozilla::dom::DOMParser*>(aObject),
786 : "Multiple inheritance for mozilla::dom::DOMParser is broken.");
787 0 : MOZ_ASSERT(ToSupportsIsCorrect(aObject));
788 0 : MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
789 0 : MOZ_ASSERT(!aCache->GetWrapper(),
790 : "You should probably not be using Wrap() directly; use "
791 : "GetOrCreateDOMReflector instead");
792 :
793 0 : MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
794 : "nsISupports must be on our primary inheritance chain");
795 :
796 0 : JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
797 0 : if (!global) {
798 0 : return false;
799 : }
800 0 : MOZ_ASSERT(JS_IsGlobalObject(global));
801 0 : MOZ_ASSERT(JS::ObjectIsNotGray(global));
802 :
803 : // That might have ended up wrapping us already, due to the wonders
804 : // of XBL. Check for that, and bail out as needed.
805 0 : aReflector.set(aCache->GetWrapper());
806 0 : if (aReflector) {
807 : #ifdef DEBUG
808 0 : binding_detail::AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
809 : #endif // DEBUG
810 0 : return true;
811 : }
812 :
813 0 : JSAutoCompartment ac(aCx, global);
814 0 : JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
815 0 : if (!canonicalProto) {
816 0 : return false;
817 : }
818 0 : JS::Rooted<JSObject*> proto(aCx);
819 0 : if (aGivenProto) {
820 0 : proto = aGivenProto;
821 : // Unfortunately, while aGivenProto was in the compartment of aCx
822 : // coming in, we changed compartments to that of "parent" so may need
823 : // to wrap the proto here.
824 0 : if (js::GetContextCompartment(aCx) != js::GetObjectCompartment(proto)) {
825 0 : if (!JS_WrapObject(aCx, &proto)) {
826 0 : return false;
827 : }
828 : }
829 : } else {
830 0 : proto = canonicalProto;
831 : }
832 :
833 0 : BindingJSObjectCreator<mozilla::dom::DOMParser> creator(aCx);
834 0 : creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
835 0 : if (!aReflector) {
836 0 : return false;
837 : }
838 :
839 0 : aCache->SetWrapper(aReflector);
840 0 : creator.InitializationSucceeded();
841 :
842 0 : MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
843 : aCache->GetWrapperPreserveColor() == aReflector);
844 : // If proto != canonicalProto, we have to preserve our wrapper;
845 : // otherwise we won't be able to properly recreate it later, since
846 : // we won't know what proto to use. Note that we don't check
847 : // aGivenProto here, since it's entirely possible (and even
848 : // somewhat common) to have a non-null aGivenProto which is the
849 : // same as canonicalProto.
850 0 : if (proto != canonicalProto) {
851 0 : PreserveWrapper(aObject);
852 : }
853 :
854 0 : return true;
855 : }
856 :
857 : const NativePropertyHooks sNativePropertyHooks[] = { {
858 : nullptr,
859 : nullptr,
860 : nullptr,
861 : { sNativeProperties.Upcast(), sChromeOnlyNativeProperties.Upcast() },
862 : prototypes::id::DOMParser,
863 : constructors::id::DOMParser,
864 : nullptr,
865 : &DefaultXrayExpandoObjectClass
866 : } };
867 :
868 : void
869 0 : CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, bool aDefineOnGlobal)
870 : {
871 0 : JS::Rooted<JSObject*> parentProto(aCx, JS::GetRealmObjectPrototype(aCx));
872 0 : if (!parentProto) {
873 0 : return;
874 : }
875 :
876 0 : JS::Rooted<JSObject*> constructorProto(aCx, JS::GetRealmFunctionPrototype(aCx));
877 0 : if (!constructorProto) {
878 0 : return;
879 : }
880 :
881 : static bool sIdsInited = false;
882 0 : if (!sIdsInited && NS_IsMainThread()) {
883 0 : if (!InitIds(aCx, sNativeProperties.Upcast())) {
884 0 : return;
885 : }
886 0 : if (!InitIds(aCx, sChromeOnlyNativeProperties.Upcast())) {
887 0 : return;
888 : }
889 0 : sIdsInited = true;
890 : }
891 :
892 0 : JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::DOMParser);
893 0 : JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::DOMParser);
894 0 : dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
895 : &sPrototypeClass.mBase, protoCache,
896 : constructorProto, &sInterfaceObjectClass.mBase, 0, nullptr,
897 : interfaceCache,
898 : sNativeProperties.Upcast(),
899 0 : nsContentUtils::ThreadsafeIsSystemCaller(aCx) ? sChromeOnlyNativeProperties.Upcast() : nullptr,
900 : "DOMParser", aDefineOnGlobal,
901 : nullptr,
902 0 : false);
903 : }
904 :
905 : JS::Handle<JSObject*>
906 0 : GetProtoObjectHandle(JSContext* aCx)
907 : {
908 : /* Get the interface prototype object for this class. This will create the
909 : object as needed. */
910 0 : bool aDefineOnGlobal = true;
911 :
912 : /* Make sure our global is sane. Hopefully we can remove this sometime */
913 0 : JSObject* global = JS::CurrentGlobalOrNull(aCx);
914 0 : if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
915 0 : return nullptr;
916 : }
917 :
918 : /* Check to see whether the interface objects are already installed */
919 0 : ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
920 0 : if (!protoAndIfaceCache.HasEntryInSlot(prototypes::id::DOMParser)) {
921 0 : JS::Rooted<JSObject*> rootedGlobal(aCx, global);
922 0 : CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
923 : }
924 :
925 : /*
926 : * The object might _still_ be null, but that's OK.
927 : *
928 : * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
929 : * traced by TraceProtoAndIfaceCache() and its contents are never
930 : * changed after they have been set.
931 : *
932 : * Calling address() avoids the read read barrier that does gray
933 : * unmarking, but it's not possible for the object to be gray here.
934 : */
935 :
936 0 : const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(prototypes::id::DOMParser);
937 0 : MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
938 0 : return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
939 : }
940 :
941 : JS::Handle<JSObject*>
942 0 : GetConstructorObjectHandle(JSContext* aCx, bool aDefineOnGlobal)
943 : {
944 : /* Get the interface object for this class. This will create the object as
945 : needed. */
946 :
947 : /* Make sure our global is sane. Hopefully we can remove this sometime */
948 0 : JSObject* global = JS::CurrentGlobalOrNull(aCx);
949 0 : if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
950 0 : return nullptr;
951 : }
952 :
953 : /* Check to see whether the interface objects are already installed */
954 0 : ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
955 0 : if (!protoAndIfaceCache.HasEntryInSlot(constructors::id::DOMParser)) {
956 0 : JS::Rooted<JSObject*> rootedGlobal(aCx, global);
957 0 : CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
958 : }
959 :
960 : /*
961 : * The object might _still_ be null, but that's OK.
962 : *
963 : * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
964 : * traced by TraceProtoAndIfaceCache() and its contents are never
965 : * changed after they have been set.
966 : *
967 : * Calling address() avoids the read read barrier that does gray
968 : * unmarking, but it's not possible for the object to be gray here.
969 : */
970 :
971 0 : const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(constructors::id::DOMParser);
972 0 : MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
973 0 : return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
974 : }
975 :
976 : JSObject*
977 0 : GetConstructorObject(JSContext* aCx)
978 : {
979 0 : return GetConstructorObjectHandle(aCx);
980 : }
981 :
982 : } // namespace DOMParserBinding
983 :
984 :
985 :
986 : } // namespace dom
987 : } // namespace mozilla
|