Line data Source code
1 : /* THIS FILE IS AUTOGENERATED FROM Location.webidl BY Codegen.py - DO NOT EDIT */
2 :
3 : #include "LocationBinding.h"
4 : #include "WrapperFactory.h"
5 : #include "mozilla/OwningNonNull.h"
6 : #include "mozilla/dom/BindingUtils.h"
7 : #include "mozilla/dom/DOMJSClass.h"
8 : #include "mozilla/dom/DOMJSProxyHandler.h"
9 : #include "mozilla/dom/Location.h"
10 : #include "mozilla/dom/NonRefcountedDOMObject.h"
11 : #include "mozilla/dom/PrimitiveConversions.h"
12 : #include "mozilla/dom/XrayExpandoClass.h"
13 :
14 : namespace mozilla {
15 : namespace dom {
16 :
17 : namespace LocationBinding {
18 :
19 : static bool
20 0 : __stringifier(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::Location* self, const JSJitMethodCallArgs& args)
21 : {
22 0 : binding_detail::FastErrorResult rv;
23 0 : JSCompartment* compartment = js::GetContextCompartment(cx);
24 0 : MOZ_ASSERT(compartment);
25 0 : JSPrincipals* principals = JS_GetCompartmentPrincipals(compartment);
26 : // Initializing a nonnull is pretty darn annoying...
27 0 : NonNull<nsIPrincipal> subjectPrincipal;
28 0 : subjectPrincipal = static_cast<nsIPrincipal*>(nsJSPrincipals::get(principals));
29 0 : DOMString result;
30 0 : self->Stringify(result, subjectPrincipal, rv);
31 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
32 0 : return false;
33 : }
34 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
35 0 : if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
36 0 : return false;
37 : }
38 0 : return true;
39 : }
40 :
41 : static const JSJitInfo __stringifier_methodinfo = {
42 : { (JSJitGetterOp)__stringifier },
43 : { prototypes::id::Location },
44 : { PrototypeTraits<prototypes::id::Location>::Depth },
45 : JSJitInfo::Method,
46 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
47 : JSVAL_TYPE_STRING, /* returnType. Not relevant for setters. */
48 : false, /* isInfallible. False in setters. */
49 : false, /* isMovable. Not relevant for setters. */
50 : false, /* isEliminatable. Not relevant for setters. */
51 : false, /* isAlwaysInSlot. Only relevant for getters. */
52 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
53 : false, /* isTypedMethod. Only relevant for methods. */
54 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
55 : };
56 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
57 : static_assert(0 < 1, "There is no slot for us");
58 :
59 : static bool
60 5 : get_href(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::Location* self, JSJitGetterCallArgs args)
61 : {
62 10 : binding_detail::FastErrorResult rv;
63 5 : JSCompartment* compartment = js::GetContextCompartment(cx);
64 5 : MOZ_ASSERT(compartment);
65 5 : JSPrincipals* principals = JS_GetCompartmentPrincipals(compartment);
66 : // Initializing a nonnull is pretty darn annoying...
67 5 : NonNull<nsIPrincipal> subjectPrincipal;
68 5 : subjectPrincipal = static_cast<nsIPrincipal*>(nsJSPrincipals::get(principals));
69 10 : DOMString result;
70 5 : self->GetHref(result, subjectPrincipal, rv);
71 5 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
72 0 : return false;
73 : }
74 5 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
75 5 : if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
76 0 : return false;
77 : }
78 5 : return true;
79 : }
80 :
81 : static bool
82 0 : set_href(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::Location* self, JSJitSetterCallArgs args)
83 : {
84 0 : binding_detail::FakeString arg0;
85 0 : if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
86 0 : return false;
87 : }
88 0 : NormalizeUSVString(arg0);
89 0 : binding_detail::FastErrorResult rv;
90 0 : JSCompartment* compartment = js::GetContextCompartment(cx);
91 0 : MOZ_ASSERT(compartment);
92 0 : JSPrincipals* principals = JS_GetCompartmentPrincipals(compartment);
93 : // Initializing a nonnull is pretty darn annoying...
94 0 : NonNull<nsIPrincipal> subjectPrincipal;
95 0 : subjectPrincipal = static_cast<nsIPrincipal*>(nsJSPrincipals::get(principals));
96 0 : self->SetHref(Constify(arg0), subjectPrincipal, rv);
97 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
98 0 : return false;
99 : }
100 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
101 :
102 0 : return true;
103 : }
104 :
105 : static const JSJitInfo href_getterinfo = {
106 : { (JSJitGetterOp)get_href },
107 : { prototypes::id::Location },
108 : { PrototypeTraits<prototypes::id::Location>::Depth },
109 : JSJitInfo::Getter,
110 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
111 : JSVAL_TYPE_STRING, /* returnType. Not relevant for setters. */
112 : false, /* isInfallible. False in setters. */
113 : false, /* isMovable. Not relevant for setters. */
114 : false, /* isEliminatable. Not relevant for setters. */
115 : false, /* isAlwaysInSlot. Only relevant for getters. */
116 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
117 : false, /* isTypedMethod. Only relevant for methods. */
118 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
119 : };
120 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
121 : static_assert(0 < 1, "There is no slot for us");
122 : static const JSJitInfo href_setterinfo = {
123 : { (JSJitGetterOp)set_href },
124 : { prototypes::id::Location },
125 : { PrototypeTraits<prototypes::id::Location>::Depth },
126 : JSJitInfo::Setter,
127 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
128 : JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
129 : false, /* isInfallible. False in setters. */
130 : false, /* isMovable. Not relevant for setters. */
131 : false, /* isEliminatable. Not relevant for setters. */
132 : false, /* isAlwaysInSlot. Only relevant for getters. */
133 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
134 : false, /* isTypedMethod. Only relevant for methods. */
135 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
136 : };
137 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
138 : static_assert(0 < 1, "There is no slot for us");
139 :
140 : static bool
141 0 : get_origin(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::Location* self, JSJitGetterCallArgs args)
142 : {
143 0 : binding_detail::FastErrorResult rv;
144 0 : JSCompartment* compartment = js::GetContextCompartment(cx);
145 0 : MOZ_ASSERT(compartment);
146 0 : JSPrincipals* principals = JS_GetCompartmentPrincipals(compartment);
147 : // Initializing a nonnull is pretty darn annoying...
148 0 : NonNull<nsIPrincipal> subjectPrincipal;
149 0 : subjectPrincipal = static_cast<nsIPrincipal*>(nsJSPrincipals::get(principals));
150 0 : DOMString result;
151 0 : self->GetOrigin(result, subjectPrincipal, rv);
152 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
153 0 : return false;
154 : }
155 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
156 0 : if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
157 0 : return false;
158 : }
159 0 : return true;
160 : }
161 :
162 : static const JSJitInfo origin_getterinfo = {
163 : { (JSJitGetterOp)get_origin },
164 : { prototypes::id::Location },
165 : { PrototypeTraits<prototypes::id::Location>::Depth },
166 : JSJitInfo::Getter,
167 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
168 : JSVAL_TYPE_STRING, /* returnType. Not relevant for setters. */
169 : false, /* isInfallible. False in setters. */
170 : false, /* isMovable. Not relevant for setters. */
171 : false, /* isEliminatable. Not relevant for setters. */
172 : false, /* isAlwaysInSlot. Only relevant for getters. */
173 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
174 : false, /* isTypedMethod. Only relevant for methods. */
175 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
176 : };
177 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
178 : static_assert(0 < 1, "There is no slot for us");
179 :
180 : static bool
181 1 : get_protocol(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::Location* self, JSJitGetterCallArgs args)
182 : {
183 2 : binding_detail::FastErrorResult rv;
184 1 : JSCompartment* compartment = js::GetContextCompartment(cx);
185 1 : MOZ_ASSERT(compartment);
186 1 : JSPrincipals* principals = JS_GetCompartmentPrincipals(compartment);
187 : // Initializing a nonnull is pretty darn annoying...
188 1 : NonNull<nsIPrincipal> subjectPrincipal;
189 1 : subjectPrincipal = static_cast<nsIPrincipal*>(nsJSPrincipals::get(principals));
190 2 : DOMString result;
191 1 : self->GetProtocol(result, subjectPrincipal, rv);
192 1 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
193 0 : return false;
194 : }
195 1 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
196 1 : if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
197 0 : return false;
198 : }
199 1 : return true;
200 : }
201 :
202 : static bool
203 0 : set_protocol(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::Location* self, JSJitSetterCallArgs args)
204 : {
205 0 : binding_detail::FakeString arg0;
206 0 : if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
207 0 : return false;
208 : }
209 0 : NormalizeUSVString(arg0);
210 0 : binding_detail::FastErrorResult rv;
211 0 : JSCompartment* compartment = js::GetContextCompartment(cx);
212 0 : MOZ_ASSERT(compartment);
213 0 : JSPrincipals* principals = JS_GetCompartmentPrincipals(compartment);
214 : // Initializing a nonnull is pretty darn annoying...
215 0 : NonNull<nsIPrincipal> subjectPrincipal;
216 0 : subjectPrincipal = static_cast<nsIPrincipal*>(nsJSPrincipals::get(principals));
217 0 : self->SetProtocol(Constify(arg0), subjectPrincipal, rv);
218 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
219 0 : return false;
220 : }
221 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
222 :
223 0 : return true;
224 : }
225 :
226 : static const JSJitInfo protocol_getterinfo = {
227 : { (JSJitGetterOp)get_protocol },
228 : { prototypes::id::Location },
229 : { PrototypeTraits<prototypes::id::Location>::Depth },
230 : JSJitInfo::Getter,
231 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
232 : JSVAL_TYPE_STRING, /* returnType. Not relevant for setters. */
233 : false, /* isInfallible. False in setters. */
234 : false, /* isMovable. Not relevant for setters. */
235 : false, /* isEliminatable. Not relevant for setters. */
236 : false, /* isAlwaysInSlot. Only relevant for getters. */
237 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
238 : false, /* isTypedMethod. Only relevant for methods. */
239 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
240 : };
241 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
242 : static_assert(0 < 1, "There is no slot for us");
243 : static const JSJitInfo protocol_setterinfo = {
244 : { (JSJitGetterOp)set_protocol },
245 : { prototypes::id::Location },
246 : { PrototypeTraits<prototypes::id::Location>::Depth },
247 : JSJitInfo::Setter,
248 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
249 : JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
250 : false, /* isInfallible. False in setters. */
251 : false, /* isMovable. Not relevant for setters. */
252 : false, /* isEliminatable. Not relevant for setters. */
253 : false, /* isAlwaysInSlot. Only relevant for getters. */
254 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
255 : false, /* isTypedMethod. Only relevant for methods. */
256 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
257 : };
258 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
259 : static_assert(0 < 1, "There is no slot for us");
260 :
261 : static bool
262 0 : get_host(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::Location* self, JSJitGetterCallArgs args)
263 : {
264 0 : binding_detail::FastErrorResult rv;
265 0 : JSCompartment* compartment = js::GetContextCompartment(cx);
266 0 : MOZ_ASSERT(compartment);
267 0 : JSPrincipals* principals = JS_GetCompartmentPrincipals(compartment);
268 : // Initializing a nonnull is pretty darn annoying...
269 0 : NonNull<nsIPrincipal> subjectPrincipal;
270 0 : subjectPrincipal = static_cast<nsIPrincipal*>(nsJSPrincipals::get(principals));
271 0 : DOMString result;
272 0 : self->GetHost(result, subjectPrincipal, rv);
273 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
274 0 : return false;
275 : }
276 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
277 0 : if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
278 0 : return false;
279 : }
280 0 : return true;
281 : }
282 :
283 : static bool
284 0 : set_host(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::Location* self, JSJitSetterCallArgs args)
285 : {
286 0 : binding_detail::FakeString arg0;
287 0 : if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
288 0 : return false;
289 : }
290 0 : NormalizeUSVString(arg0);
291 0 : binding_detail::FastErrorResult rv;
292 0 : JSCompartment* compartment = js::GetContextCompartment(cx);
293 0 : MOZ_ASSERT(compartment);
294 0 : JSPrincipals* principals = JS_GetCompartmentPrincipals(compartment);
295 : // Initializing a nonnull is pretty darn annoying...
296 0 : NonNull<nsIPrincipal> subjectPrincipal;
297 0 : subjectPrincipal = static_cast<nsIPrincipal*>(nsJSPrincipals::get(principals));
298 0 : self->SetHost(Constify(arg0), subjectPrincipal, rv);
299 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
300 0 : return false;
301 : }
302 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
303 :
304 0 : return true;
305 : }
306 :
307 : static const JSJitInfo host_getterinfo = {
308 : { (JSJitGetterOp)get_host },
309 : { prototypes::id::Location },
310 : { PrototypeTraits<prototypes::id::Location>::Depth },
311 : JSJitInfo::Getter,
312 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
313 : JSVAL_TYPE_STRING, /* returnType. Not relevant for setters. */
314 : false, /* isInfallible. False in setters. */
315 : false, /* isMovable. Not relevant for setters. */
316 : false, /* isEliminatable. Not relevant for setters. */
317 : false, /* isAlwaysInSlot. Only relevant for getters. */
318 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
319 : false, /* isTypedMethod. Only relevant for methods. */
320 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
321 : };
322 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
323 : static_assert(0 < 1, "There is no slot for us");
324 : static const JSJitInfo host_setterinfo = {
325 : { (JSJitGetterOp)set_host },
326 : { prototypes::id::Location },
327 : { PrototypeTraits<prototypes::id::Location>::Depth },
328 : JSJitInfo::Setter,
329 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
330 : JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
331 : false, /* isInfallible. False in setters. */
332 : false, /* isMovable. Not relevant for setters. */
333 : false, /* isEliminatable. Not relevant for setters. */
334 : false, /* isAlwaysInSlot. Only relevant for getters. */
335 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
336 : false, /* isTypedMethod. Only relevant for methods. */
337 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
338 : };
339 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
340 : static_assert(0 < 1, "There is no slot for us");
341 :
342 : static bool
343 1 : get_hostname(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::Location* self, JSJitGetterCallArgs args)
344 : {
345 2 : binding_detail::FastErrorResult rv;
346 1 : JSCompartment* compartment = js::GetContextCompartment(cx);
347 1 : MOZ_ASSERT(compartment);
348 1 : JSPrincipals* principals = JS_GetCompartmentPrincipals(compartment);
349 : // Initializing a nonnull is pretty darn annoying...
350 1 : NonNull<nsIPrincipal> subjectPrincipal;
351 1 : subjectPrincipal = static_cast<nsIPrincipal*>(nsJSPrincipals::get(principals));
352 2 : DOMString result;
353 1 : self->GetHostname(result, subjectPrincipal, rv);
354 1 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
355 0 : return false;
356 : }
357 1 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
358 1 : if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
359 0 : return false;
360 : }
361 1 : return true;
362 : }
363 :
364 : static bool
365 0 : set_hostname(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::Location* self, JSJitSetterCallArgs args)
366 : {
367 0 : binding_detail::FakeString arg0;
368 0 : if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
369 0 : return false;
370 : }
371 0 : NormalizeUSVString(arg0);
372 0 : binding_detail::FastErrorResult rv;
373 0 : JSCompartment* compartment = js::GetContextCompartment(cx);
374 0 : MOZ_ASSERT(compartment);
375 0 : JSPrincipals* principals = JS_GetCompartmentPrincipals(compartment);
376 : // Initializing a nonnull is pretty darn annoying...
377 0 : NonNull<nsIPrincipal> subjectPrincipal;
378 0 : subjectPrincipal = static_cast<nsIPrincipal*>(nsJSPrincipals::get(principals));
379 0 : self->SetHostname(Constify(arg0), subjectPrincipal, rv);
380 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
381 0 : return false;
382 : }
383 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
384 :
385 0 : return true;
386 : }
387 :
388 : static const JSJitInfo hostname_getterinfo = {
389 : { (JSJitGetterOp)get_hostname },
390 : { prototypes::id::Location },
391 : { PrototypeTraits<prototypes::id::Location>::Depth },
392 : JSJitInfo::Getter,
393 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
394 : JSVAL_TYPE_STRING, /* returnType. Not relevant for setters. */
395 : false, /* isInfallible. False in setters. */
396 : false, /* isMovable. Not relevant for setters. */
397 : false, /* isEliminatable. Not relevant for setters. */
398 : false, /* isAlwaysInSlot. Only relevant for getters. */
399 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
400 : false, /* isTypedMethod. Only relevant for methods. */
401 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
402 : };
403 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
404 : static_assert(0 < 1, "There is no slot for us");
405 : static const JSJitInfo hostname_setterinfo = {
406 : { (JSJitGetterOp)set_hostname },
407 : { prototypes::id::Location },
408 : { PrototypeTraits<prototypes::id::Location>::Depth },
409 : JSJitInfo::Setter,
410 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
411 : JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
412 : false, /* isInfallible. False in setters. */
413 : false, /* isMovable. Not relevant for setters. */
414 : false, /* isEliminatable. Not relevant for setters. */
415 : false, /* isAlwaysInSlot. Only relevant for getters. */
416 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
417 : false, /* isTypedMethod. Only relevant for methods. */
418 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
419 : };
420 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
421 : static_assert(0 < 1, "There is no slot for us");
422 :
423 : static bool
424 0 : get_port(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::Location* self, JSJitGetterCallArgs args)
425 : {
426 0 : binding_detail::FastErrorResult rv;
427 0 : JSCompartment* compartment = js::GetContextCompartment(cx);
428 0 : MOZ_ASSERT(compartment);
429 0 : JSPrincipals* principals = JS_GetCompartmentPrincipals(compartment);
430 : // Initializing a nonnull is pretty darn annoying...
431 0 : NonNull<nsIPrincipal> subjectPrincipal;
432 0 : subjectPrincipal = static_cast<nsIPrincipal*>(nsJSPrincipals::get(principals));
433 0 : DOMString result;
434 0 : self->GetPort(result, subjectPrincipal, rv);
435 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
436 0 : return false;
437 : }
438 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
439 0 : if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
440 0 : return false;
441 : }
442 0 : return true;
443 : }
444 :
445 : static bool
446 0 : set_port(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::Location* self, JSJitSetterCallArgs args)
447 : {
448 0 : binding_detail::FakeString arg0;
449 0 : if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
450 0 : return false;
451 : }
452 0 : NormalizeUSVString(arg0);
453 0 : binding_detail::FastErrorResult rv;
454 0 : JSCompartment* compartment = js::GetContextCompartment(cx);
455 0 : MOZ_ASSERT(compartment);
456 0 : JSPrincipals* principals = JS_GetCompartmentPrincipals(compartment);
457 : // Initializing a nonnull is pretty darn annoying...
458 0 : NonNull<nsIPrincipal> subjectPrincipal;
459 0 : subjectPrincipal = static_cast<nsIPrincipal*>(nsJSPrincipals::get(principals));
460 0 : self->SetPort(Constify(arg0), subjectPrincipal, rv);
461 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
462 0 : return false;
463 : }
464 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
465 :
466 0 : return true;
467 : }
468 :
469 : static const JSJitInfo port_getterinfo = {
470 : { (JSJitGetterOp)get_port },
471 : { prototypes::id::Location },
472 : { PrototypeTraits<prototypes::id::Location>::Depth },
473 : JSJitInfo::Getter,
474 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
475 : JSVAL_TYPE_STRING, /* returnType. Not relevant for setters. */
476 : false, /* isInfallible. False in setters. */
477 : false, /* isMovable. Not relevant for setters. */
478 : false, /* isEliminatable. Not relevant for setters. */
479 : false, /* isAlwaysInSlot. Only relevant for getters. */
480 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
481 : false, /* isTypedMethod. Only relevant for methods. */
482 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
483 : };
484 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
485 : static_assert(0 < 1, "There is no slot for us");
486 : static const JSJitInfo port_setterinfo = {
487 : { (JSJitGetterOp)set_port },
488 : { prototypes::id::Location },
489 : { PrototypeTraits<prototypes::id::Location>::Depth },
490 : JSJitInfo::Setter,
491 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
492 : JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
493 : false, /* isInfallible. False in setters. */
494 : false, /* isMovable. Not relevant for setters. */
495 : false, /* isEliminatable. Not relevant for setters. */
496 : false, /* isAlwaysInSlot. Only relevant for getters. */
497 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
498 : false, /* isTypedMethod. Only relevant for methods. */
499 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
500 : };
501 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
502 : static_assert(0 < 1, "There is no slot for us");
503 :
504 : static bool
505 0 : get_pathname(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::Location* self, JSJitGetterCallArgs args)
506 : {
507 0 : binding_detail::FastErrorResult rv;
508 0 : JSCompartment* compartment = js::GetContextCompartment(cx);
509 0 : MOZ_ASSERT(compartment);
510 0 : JSPrincipals* principals = JS_GetCompartmentPrincipals(compartment);
511 : // Initializing a nonnull is pretty darn annoying...
512 0 : NonNull<nsIPrincipal> subjectPrincipal;
513 0 : subjectPrincipal = static_cast<nsIPrincipal*>(nsJSPrincipals::get(principals));
514 0 : DOMString result;
515 0 : self->GetPathname(result, subjectPrincipal, rv);
516 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
517 0 : return false;
518 : }
519 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
520 0 : if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
521 0 : return false;
522 : }
523 0 : return true;
524 : }
525 :
526 : static bool
527 0 : set_pathname(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::Location* self, JSJitSetterCallArgs args)
528 : {
529 0 : binding_detail::FakeString arg0;
530 0 : if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
531 0 : return false;
532 : }
533 0 : NormalizeUSVString(arg0);
534 0 : binding_detail::FastErrorResult rv;
535 0 : JSCompartment* compartment = js::GetContextCompartment(cx);
536 0 : MOZ_ASSERT(compartment);
537 0 : JSPrincipals* principals = JS_GetCompartmentPrincipals(compartment);
538 : // Initializing a nonnull is pretty darn annoying...
539 0 : NonNull<nsIPrincipal> subjectPrincipal;
540 0 : subjectPrincipal = static_cast<nsIPrincipal*>(nsJSPrincipals::get(principals));
541 0 : self->SetPathname(Constify(arg0), subjectPrincipal, rv);
542 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
543 0 : return false;
544 : }
545 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
546 :
547 0 : return true;
548 : }
549 :
550 : static const JSJitInfo pathname_getterinfo = {
551 : { (JSJitGetterOp)get_pathname },
552 : { prototypes::id::Location },
553 : { PrototypeTraits<prototypes::id::Location>::Depth },
554 : JSJitInfo::Getter,
555 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
556 : JSVAL_TYPE_STRING, /* returnType. Not relevant for setters. */
557 : false, /* isInfallible. False in setters. */
558 : false, /* isMovable. Not relevant for setters. */
559 : false, /* isEliminatable. Not relevant for setters. */
560 : false, /* isAlwaysInSlot. Only relevant for getters. */
561 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
562 : false, /* isTypedMethod. Only relevant for methods. */
563 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
564 : };
565 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
566 : static_assert(0 < 1, "There is no slot for us");
567 : static const JSJitInfo pathname_setterinfo = {
568 : { (JSJitGetterOp)set_pathname },
569 : { prototypes::id::Location },
570 : { PrototypeTraits<prototypes::id::Location>::Depth },
571 : JSJitInfo::Setter,
572 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
573 : JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
574 : false, /* isInfallible. False in setters. */
575 : false, /* isMovable. Not relevant for setters. */
576 : false, /* isEliminatable. Not relevant for setters. */
577 : false, /* isAlwaysInSlot. Only relevant for getters. */
578 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
579 : false, /* isTypedMethod. Only relevant for methods. */
580 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
581 : };
582 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
583 : static_assert(0 < 1, "There is no slot for us");
584 :
585 : static bool
586 1 : get_search(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::Location* self, JSJitGetterCallArgs args)
587 : {
588 2 : binding_detail::FastErrorResult rv;
589 1 : JSCompartment* compartment = js::GetContextCompartment(cx);
590 1 : MOZ_ASSERT(compartment);
591 1 : JSPrincipals* principals = JS_GetCompartmentPrincipals(compartment);
592 : // Initializing a nonnull is pretty darn annoying...
593 1 : NonNull<nsIPrincipal> subjectPrincipal;
594 1 : subjectPrincipal = static_cast<nsIPrincipal*>(nsJSPrincipals::get(principals));
595 2 : DOMString result;
596 1 : self->GetSearch(result, subjectPrincipal, rv);
597 1 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
598 0 : return false;
599 : }
600 1 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
601 1 : if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
602 0 : return false;
603 : }
604 1 : return true;
605 : }
606 :
607 : static bool
608 0 : set_search(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::Location* self, JSJitSetterCallArgs args)
609 : {
610 0 : binding_detail::FakeString arg0;
611 0 : if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
612 0 : return false;
613 : }
614 0 : NormalizeUSVString(arg0);
615 0 : binding_detail::FastErrorResult rv;
616 0 : JSCompartment* compartment = js::GetContextCompartment(cx);
617 0 : MOZ_ASSERT(compartment);
618 0 : JSPrincipals* principals = JS_GetCompartmentPrincipals(compartment);
619 : // Initializing a nonnull is pretty darn annoying...
620 0 : NonNull<nsIPrincipal> subjectPrincipal;
621 0 : subjectPrincipal = static_cast<nsIPrincipal*>(nsJSPrincipals::get(principals));
622 0 : self->SetSearch(Constify(arg0), subjectPrincipal, rv);
623 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
624 0 : return false;
625 : }
626 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
627 :
628 0 : return true;
629 : }
630 :
631 : static const JSJitInfo search_getterinfo = {
632 : { (JSJitGetterOp)get_search },
633 : { prototypes::id::Location },
634 : { PrototypeTraits<prototypes::id::Location>::Depth },
635 : JSJitInfo::Getter,
636 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
637 : JSVAL_TYPE_STRING, /* returnType. Not relevant for setters. */
638 : false, /* isInfallible. False in setters. */
639 : false, /* isMovable. Not relevant for setters. */
640 : false, /* isEliminatable. Not relevant for setters. */
641 : false, /* isAlwaysInSlot. Only relevant for getters. */
642 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
643 : false, /* isTypedMethod. Only relevant for methods. */
644 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
645 : };
646 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
647 : static_assert(0 < 1, "There is no slot for us");
648 : static const JSJitInfo search_setterinfo = {
649 : { (JSJitGetterOp)set_search },
650 : { prototypes::id::Location },
651 : { PrototypeTraits<prototypes::id::Location>::Depth },
652 : JSJitInfo::Setter,
653 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
654 : JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
655 : false, /* isInfallible. False in setters. */
656 : false, /* isMovable. Not relevant for setters. */
657 : false, /* isEliminatable. Not relevant for setters. */
658 : false, /* isAlwaysInSlot. Only relevant for getters. */
659 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
660 : false, /* isTypedMethod. Only relevant for methods. */
661 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
662 : };
663 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
664 : static_assert(0 < 1, "There is no slot for us");
665 :
666 : static bool
667 0 : get_hash(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::Location* self, JSJitGetterCallArgs args)
668 : {
669 0 : binding_detail::FastErrorResult rv;
670 0 : JSCompartment* compartment = js::GetContextCompartment(cx);
671 0 : MOZ_ASSERT(compartment);
672 0 : JSPrincipals* principals = JS_GetCompartmentPrincipals(compartment);
673 : // Initializing a nonnull is pretty darn annoying...
674 0 : NonNull<nsIPrincipal> subjectPrincipal;
675 0 : subjectPrincipal = static_cast<nsIPrincipal*>(nsJSPrincipals::get(principals));
676 0 : DOMString result;
677 0 : self->GetHash(result, subjectPrincipal, rv);
678 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
679 0 : return false;
680 : }
681 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
682 0 : if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
683 0 : return false;
684 : }
685 0 : return true;
686 : }
687 :
688 : static bool
689 0 : set_hash(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::Location* self, JSJitSetterCallArgs args)
690 : {
691 0 : binding_detail::FakeString arg0;
692 0 : if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
693 0 : return false;
694 : }
695 0 : NormalizeUSVString(arg0);
696 0 : binding_detail::FastErrorResult rv;
697 0 : JSCompartment* compartment = js::GetContextCompartment(cx);
698 0 : MOZ_ASSERT(compartment);
699 0 : JSPrincipals* principals = JS_GetCompartmentPrincipals(compartment);
700 : // Initializing a nonnull is pretty darn annoying...
701 0 : NonNull<nsIPrincipal> subjectPrincipal;
702 0 : subjectPrincipal = static_cast<nsIPrincipal*>(nsJSPrincipals::get(principals));
703 0 : self->SetHash(Constify(arg0), subjectPrincipal, rv);
704 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
705 0 : return false;
706 : }
707 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
708 :
709 0 : return true;
710 : }
711 :
712 : static const JSJitInfo hash_getterinfo = {
713 : { (JSJitGetterOp)get_hash },
714 : { prototypes::id::Location },
715 : { PrototypeTraits<prototypes::id::Location>::Depth },
716 : JSJitInfo::Getter,
717 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
718 : JSVAL_TYPE_STRING, /* returnType. Not relevant for setters. */
719 : false, /* isInfallible. False in setters. */
720 : false, /* isMovable. Not relevant for setters. */
721 : false, /* isEliminatable. Not relevant for setters. */
722 : false, /* isAlwaysInSlot. Only relevant for getters. */
723 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
724 : false, /* isTypedMethod. Only relevant for methods. */
725 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
726 : };
727 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
728 : static_assert(0 < 1, "There is no slot for us");
729 : static const JSJitInfo hash_setterinfo = {
730 : { (JSJitGetterOp)set_hash },
731 : { prototypes::id::Location },
732 : { PrototypeTraits<prototypes::id::Location>::Depth },
733 : JSJitInfo::Setter,
734 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
735 : JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
736 : false, /* isInfallible. False in setters. */
737 : false, /* isMovable. Not relevant for setters. */
738 : false, /* isEliminatable. Not relevant for setters. */
739 : false, /* isAlwaysInSlot. Only relevant for getters. */
740 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
741 : false, /* isTypedMethod. Only relevant for methods. */
742 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
743 : };
744 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
745 : static_assert(0 < 1, "There is no slot for us");
746 :
747 : static bool
748 0 : assign(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::Location* self, const JSJitMethodCallArgs& args)
749 : {
750 0 : if (MOZ_UNLIKELY(args.length() < 1)) {
751 0 : return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "Location.assign");
752 : }
753 0 : if (!mozilla::dom::EnforceNotInPrerendering(cx, obj)) {
754 : // Return false from the JSNative in order to trigger
755 : // an uncatchable exception.
756 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
757 0 : return false;
758 : }
759 0 : binding_detail::FakeString arg0;
760 0 : if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
761 0 : return false;
762 : }
763 0 : NormalizeUSVString(arg0);
764 0 : binding_detail::FastErrorResult rv;
765 0 : JSCompartment* compartment = js::GetContextCompartment(cx);
766 0 : MOZ_ASSERT(compartment);
767 0 : JSPrincipals* principals = JS_GetCompartmentPrincipals(compartment);
768 : // Initializing a nonnull is pretty darn annoying...
769 0 : NonNull<nsIPrincipal> subjectPrincipal;
770 0 : subjectPrincipal = static_cast<nsIPrincipal*>(nsJSPrincipals::get(principals));
771 0 : self->Assign(Constify(arg0), subjectPrincipal, rv);
772 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
773 0 : return false;
774 : }
775 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
776 0 : args.rval().setUndefined();
777 0 : return true;
778 : }
779 :
780 : static const JSJitInfo assign_methodinfo = {
781 : { (JSJitGetterOp)assign },
782 : { prototypes::id::Location },
783 : { PrototypeTraits<prototypes::id::Location>::Depth },
784 : JSJitInfo::Method,
785 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
786 : JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
787 : false, /* isInfallible. False in setters. */
788 : false, /* isMovable. Not relevant for setters. */
789 : false, /* isEliminatable. Not relevant for setters. */
790 : false, /* isAlwaysInSlot. Only relevant for getters. */
791 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
792 : false, /* isTypedMethod. Only relevant for methods. */
793 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
794 : };
795 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
796 : static_assert(0 < 1, "There is no slot for us");
797 :
798 : static bool
799 0 : replace(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::Location* self, const JSJitMethodCallArgs& args)
800 : {
801 0 : if (MOZ_UNLIKELY(args.length() < 1)) {
802 0 : return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "Location.replace");
803 : }
804 0 : if (!mozilla::dom::EnforceNotInPrerendering(cx, obj)) {
805 : // Return false from the JSNative in order to trigger
806 : // an uncatchable exception.
807 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
808 0 : return false;
809 : }
810 0 : binding_detail::FakeString arg0;
811 0 : if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
812 0 : return false;
813 : }
814 0 : NormalizeUSVString(arg0);
815 0 : binding_detail::FastErrorResult rv;
816 0 : JSCompartment* compartment = js::GetContextCompartment(cx);
817 0 : MOZ_ASSERT(compartment);
818 0 : JSPrincipals* principals = JS_GetCompartmentPrincipals(compartment);
819 : // Initializing a nonnull is pretty darn annoying...
820 0 : NonNull<nsIPrincipal> subjectPrincipal;
821 0 : subjectPrincipal = static_cast<nsIPrincipal*>(nsJSPrincipals::get(principals));
822 0 : self->Replace(Constify(arg0), subjectPrincipal, rv);
823 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
824 0 : return false;
825 : }
826 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
827 0 : args.rval().setUndefined();
828 0 : return true;
829 : }
830 :
831 : static const JSJitInfo replace_methodinfo = {
832 : { (JSJitGetterOp)replace },
833 : { prototypes::id::Location },
834 : { PrototypeTraits<prototypes::id::Location>::Depth },
835 : JSJitInfo::Method,
836 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
837 : JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
838 : false, /* isInfallible. False in setters. */
839 : false, /* isMovable. Not relevant for setters. */
840 : false, /* isEliminatable. Not relevant for setters. */
841 : false, /* isAlwaysInSlot. Only relevant for getters. */
842 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
843 : false, /* isTypedMethod. Only relevant for methods. */
844 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
845 : };
846 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
847 : static_assert(0 < 1, "There is no slot for us");
848 :
849 : static bool
850 0 : reload(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::Location* self, const JSJitMethodCallArgs& args)
851 : {
852 0 : if (!mozilla::dom::EnforceNotInPrerendering(cx, obj)) {
853 : // Return false from the JSNative in order to trigger
854 : // an uncatchable exception.
855 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
856 0 : return false;
857 : }
858 : bool arg0;
859 0 : if (args.hasDefined(0)) {
860 0 : if (!ValueToPrimitive<bool, eDefault>(cx, args[0], &arg0)) {
861 0 : return false;
862 : }
863 : } else {
864 0 : arg0 = false;
865 : }
866 0 : binding_detail::FastErrorResult rv;
867 0 : JSCompartment* compartment = js::GetContextCompartment(cx);
868 0 : MOZ_ASSERT(compartment);
869 0 : JSPrincipals* principals = JS_GetCompartmentPrincipals(compartment);
870 : // Initializing a nonnull is pretty darn annoying...
871 0 : NonNull<nsIPrincipal> subjectPrincipal;
872 0 : subjectPrincipal = static_cast<nsIPrincipal*>(nsJSPrincipals::get(principals));
873 0 : self->Reload(arg0, subjectPrincipal, rv);
874 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
875 0 : return false;
876 : }
877 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
878 0 : args.rval().setUndefined();
879 0 : return true;
880 : }
881 :
882 : static const JSJitInfo reload_methodinfo = {
883 : { (JSJitGetterOp)reload },
884 : { prototypes::id::Location },
885 : { PrototypeTraits<prototypes::id::Location>::Depth },
886 : JSJitInfo::Method,
887 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
888 : JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
889 : false, /* isInfallible. False in setters. */
890 : false, /* isMovable. Not relevant for setters. */
891 : false, /* isEliminatable. Not relevant for setters. */
892 : false, /* isAlwaysInSlot. Only relevant for getters. */
893 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
894 : false, /* isTypedMethod. Only relevant for methods. */
895 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
896 : };
897 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
898 : static_assert(0 < 1, "There is no slot for us");
899 :
900 : static bool
901 0 : genericCrossOriginMethod(JSContext* cx, unsigned argc, JS::Value* vp)
902 : {
903 0 : JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
904 0 : if (!args.thisv().isObject()) {
905 0 : return ThrowInvalidThis(cx, args, false, "Location");
906 : }
907 0 : JS::Rooted<JSObject*> obj(cx, &args.thisv().toObject());
908 :
909 : mozilla::dom::Location* self;
910 0 : JS::Rooted<JS::Value> rootSelf(cx, JS::ObjectValue(*obj));
911 0 : JS::Rooted<JSObject*> maybeUncheckedObj(cx, &rootSelf.toObject());
912 : {
913 0 : if (xpc::WrapperFactory::IsXrayWrapper(maybeUncheckedObj)) {
914 0 : maybeUncheckedObj = js::UncheckedUnwrap(maybeUncheckedObj);
915 : } else {
916 0 : maybeUncheckedObj = js::CheckedUnwrap(maybeUncheckedObj);
917 0 : if (!maybeUncheckedObj) {
918 0 : return ThrowInvalidThis(cx, args, true, "Location");
919 : }
920 : }
921 0 : nsresult rv = UnwrapObject<prototypes::id::Location, mozilla::dom::Location>(&maybeUncheckedObj, self);
922 0 : if (NS_FAILED(rv)) {
923 0 : return ThrowInvalidThis(cx, args, rv == NS_ERROR_XPC_SECURITY_MANAGER_VETO, "Location");
924 : }
925 : }
926 0 : const JSJitInfo *info = FUNCTION_VALUE_TO_JITINFO(args.calleev());
927 0 : MOZ_ASSERT(info->type() == JSJitInfo::Method);
928 0 : JSJitMethodOp method = info->method;
929 0 : bool ok = method(cx, obj, self, JSJitMethodCallArgs(args));
930 : #ifdef DEBUG
931 0 : if (ok) {
932 0 : AssertReturnTypeMatchesJitinfo(info, args.rval());
933 : }
934 : #endif
935 0 : return ok;
936 : }
937 :
938 : static bool
939 0 : genericCrossOriginSetter(JSContext* cx, unsigned argc, JS::Value* vp)
940 : {
941 0 : JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
942 0 : if (!args.thisv().isObject()) {
943 0 : return ThrowInvalidThis(cx, args, false, "Location");
944 : }
945 0 : JS::Rooted<JSObject*> obj(cx, &args.thisv().toObject());
946 :
947 : mozilla::dom::Location* self;
948 0 : JS::Rooted<JS::Value> rootSelf(cx, JS::ObjectValue(*obj));
949 0 : JS::Rooted<JSObject*> maybeUncheckedObj(cx, &rootSelf.toObject());
950 : {
951 0 : if (xpc::WrapperFactory::IsXrayWrapper(maybeUncheckedObj)) {
952 0 : maybeUncheckedObj = js::UncheckedUnwrap(maybeUncheckedObj);
953 : } else {
954 0 : maybeUncheckedObj = js::CheckedUnwrap(maybeUncheckedObj);
955 0 : if (!maybeUncheckedObj) {
956 0 : return ThrowInvalidThis(cx, args, true, "Location");
957 : }
958 : }
959 0 : nsresult rv = UnwrapObject<prototypes::id::Location, mozilla::dom::Location>(&maybeUncheckedObj, self);
960 0 : if (NS_FAILED(rv)) {
961 0 : return ThrowInvalidThis(cx, args, rv == NS_ERROR_XPC_SECURITY_MANAGER_VETO, "Location");
962 : }
963 : }
964 0 : if (args.length() == 0) {
965 0 : return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "Location attribute setter");
966 : }
967 0 : const JSJitInfo *info = FUNCTION_VALUE_TO_JITINFO(args.calleev());
968 0 : MOZ_ASSERT(info->type() == JSJitInfo::Setter);
969 0 : JSJitSetterOp setter = info->setter;
970 0 : if (!setter(cx, obj, self, JSJitSetterCallArgs(args))) {
971 0 : return false;
972 : }
973 0 : args.rval().setUndefined();
974 : #ifdef DEBUG
975 0 : AssertReturnTypeMatchesJitinfo(info, args.rval());
976 : #endif
977 0 : return true;
978 : }
979 :
980 : static void
981 0 : _objectMoved(JSObject* obj, const JSObject* old)
982 : {
983 0 : mozilla::dom::Location* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::Location>(obj);
984 0 : if (self) {
985 0 : UpdateWrapper(self, self, obj, old);
986 : }
987 0 : }
988 :
989 : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
990 : #if defined(__clang__)
991 : #pragma clang diagnostic push
992 : #pragma clang diagnostic ignored "-Wmissing-braces"
993 : #endif
994 : static const JSFunctionSpec sUnforgeableMethods_specs[] = {
995 : JS_FNSPEC("assign", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&assign_methodinfo), 1, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY, nullptr),
996 : JS_FNSPEC("replace", genericCrossOriginMethod, reinterpret_cast<const JSJitInfo*>(&replace_methodinfo), 1, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY, nullptr),
997 : JS_FNSPEC("reload", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&reload_methodinfo), 0, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY, nullptr),
998 : JS_FNSPEC("toString", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&__stringifier_methodinfo), 0, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY, nullptr),
999 : JS_FNSPEC("valueOf", nullptr, nullptr, 0, 0 | JSPROP_PERMANENT | JSPROP_READONLY, "Object_valueOf"),
1000 : JS_FS_END
1001 : };
1002 : #if defined(__clang__)
1003 : #pragma clang diagnostic pop
1004 : #endif
1005 :
1006 :
1007 : // Can't be const because the pref-enabled boolean needs to be writable
1008 : static Prefable<const JSFunctionSpec> sUnforgeableMethods[] = {
1009 : { nullptr, &sUnforgeableMethods_specs[0] },
1010 : { nullptr, nullptr }
1011 : };
1012 :
1013 : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
1014 : "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
1015 : static_assert(5 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
1016 : "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
1017 :
1018 : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
1019 : #if defined(__clang__)
1020 : #pragma clang diagnostic push
1021 : #pragma clang diagnostic ignored "-Wmissing-braces"
1022 : #endif
1023 : static const JSPropertySpec sUnforgeableAttributes_specs[] = {
1024 : { "href", JSPROP_SHARED | JSPROP_ENUMERATE | JSPROP_PERMANENT, GenericBindingGetter, &href_getterinfo, genericCrossOriginSetter, &href_setterinfo },
1025 : { "origin", JSPROP_SHARED | JSPROP_ENUMERATE | JSPROP_PERMANENT, GenericBindingGetter, &origin_getterinfo, nullptr, nullptr },
1026 : { "protocol", JSPROP_SHARED | JSPROP_ENUMERATE | JSPROP_PERMANENT, GenericBindingGetter, &protocol_getterinfo, GenericBindingSetter, &protocol_setterinfo },
1027 : { "host", JSPROP_SHARED | JSPROP_ENUMERATE | JSPROP_PERMANENT, GenericBindingGetter, &host_getterinfo, GenericBindingSetter, &host_setterinfo },
1028 : { "hostname", JSPROP_SHARED | JSPROP_ENUMERATE | JSPROP_PERMANENT, GenericBindingGetter, &hostname_getterinfo, GenericBindingSetter, &hostname_setterinfo },
1029 : { "port", JSPROP_SHARED | JSPROP_ENUMERATE | JSPROP_PERMANENT, GenericBindingGetter, &port_getterinfo, GenericBindingSetter, &port_setterinfo },
1030 : { "pathname", JSPROP_SHARED | JSPROP_ENUMERATE | JSPROP_PERMANENT, GenericBindingGetter, &pathname_getterinfo, GenericBindingSetter, &pathname_setterinfo },
1031 : { "search", JSPROP_SHARED | JSPROP_ENUMERATE | JSPROP_PERMANENT, GenericBindingGetter, &search_getterinfo, GenericBindingSetter, &search_setterinfo },
1032 : { "hash", JSPROP_SHARED | JSPROP_ENUMERATE | JSPROP_PERMANENT, GenericBindingGetter, &hash_getterinfo, GenericBindingSetter, &hash_setterinfo },
1033 : { nullptr, 0, nullptr, nullptr, nullptr, nullptr }
1034 : };
1035 : #if defined(__clang__)
1036 : #pragma clang diagnostic pop
1037 : #endif
1038 :
1039 :
1040 : // Can't be const because the pref-enabled boolean needs to be writable
1041 : static Prefable<const JSPropertySpec> sUnforgeableAttributes[] = {
1042 : { nullptr, &sUnforgeableAttributes_specs[0] },
1043 : { nullptr, nullptr }
1044 : };
1045 :
1046 : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
1047 : "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
1048 : static_assert(9 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
1049 : "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
1050 :
1051 :
1052 : static uint16_t sNativeProperties_sortedPropertyIndices[14];
1053 : static PropertyInfo sNativeProperties_propertyInfos[14];
1054 :
1055 : static const NativePropertiesN<2> sNativeProperties = {
1056 : false, 0,
1057 : false, 0,
1058 : false, 0,
1059 : false, 0,
1060 : true, 0 /* sUnforgeableMethods */,
1061 : true, 1 /* sUnforgeableAttributes */,
1062 : false, 0,
1063 : -1,
1064 : 14,
1065 : sNativeProperties_sortedPropertyIndices,
1066 : {
1067 : { sUnforgeableMethods, &sNativeProperties_propertyInfos[0] },
1068 : { sUnforgeableAttributes, &sNativeProperties_propertyInfos[5] }
1069 : }
1070 : };
1071 : static_assert(14 < 1ull << CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount),
1072 : "We have a property info count that is oversized");
1073 :
1074 : static const DOMIfaceAndProtoJSClass sInterfaceObjectClass = {
1075 : {
1076 : "Function",
1077 : JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_SLOTS_BASE),
1078 : &sBoringInterfaceObjectClassClassOps,
1079 : JS_NULL_CLASS_SPEC,
1080 : JS_NULL_CLASS_EXT,
1081 : &sInterfaceObjectClassObjectOps
1082 : },
1083 : eInterface,
1084 : true,
1085 : prototypes::id::Location,
1086 : PrototypeTraits<prototypes::id::Location>::Depth,
1087 : sNativePropertyHooks,
1088 : "function Location() {\n [native code]\n}",
1089 : JS::GetRealmFunctionPrototype
1090 : };
1091 :
1092 : static const DOMIfaceAndProtoJSClass sPrototypeClass = {
1093 : {
1094 : "LocationPrototype",
1095 : JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE + 1 /* slot for the JSObject holding the unforgeable properties */),
1096 : JS_NULL_CLASS_OPS,
1097 : JS_NULL_CLASS_SPEC,
1098 : JS_NULL_CLASS_EXT,
1099 : JS_NULL_OBJECT_OPS
1100 : },
1101 : eInterfacePrototype,
1102 : false,
1103 : prototypes::id::Location,
1104 : PrototypeTraits<prototypes::id::Location>::Depth,
1105 : sNativePropertyHooks,
1106 : "[object LocationPrototype]",
1107 : JS::GetRealmObjectPrototype
1108 : };
1109 :
1110 : JSObject*
1111 0 : DefineDOMInterface(JSContext* aCx, JS::Handle<JSObject*> aGlobal, JS::Handle<jsid> id, bool aDefineOnGlobal)
1112 : {
1113 0 : return GetConstructorObjectHandle(aCx, aDefineOnGlobal);
1114 : }
1115 :
1116 : static_assert(IsBaseOf<nsISupports, mozilla::dom::Location >::value,
1117 : "We don't support non-nsISupports native classes for "
1118 : "proxy-based bindings yet");
1119 :
1120 :
1121 : class DOMProxyHandler : public mozilla::dom::DOMProxyHandler
1122 : {
1123 : public:
1124 : explicit constexpr DOMProxyHandler()
1125 : {
1126 : }
1127 :
1128 : virtual bool
1129 : getOwnPropDescriptor(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id, bool ignoreNamedProps, JS::MutableHandle<JS::PropertyDescriptor> desc) const override;
1130 :
1131 : virtual bool
1132 : defineProperty(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id, JS::Handle<JS::PropertyDescriptor> desc, JS::ObjectOpResult& opresult, bool* defined) const override;
1133 :
1134 : using mozilla::dom::DOMProxyHandler::defineProperty;
1135 :
1136 : virtual bool
1137 : ownPropNames(JSContext* cx, JS::Handle<JSObject*> proxy, unsigned flags, JS::AutoIdVector& props) const override;
1138 :
1139 : virtual bool
1140 : hasOwn(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id, bool* bp) const override;
1141 :
1142 : virtual bool
1143 : get(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<JS::Value> receiver, JS::Handle<jsid> id, JS::MutableHandle<JS::Value> vp) const override;
1144 :
1145 : virtual const char*
1146 : className(JSContext* cx, JS::Handle<JSObject*> proxy) const override;
1147 :
1148 : virtual bool
1149 : finalizeInBackground(const JS::Value& priv) const override;
1150 :
1151 : virtual void
1152 : finalize(JSFreeOp* fop, JSObject* proxy) const override;
1153 :
1154 : static const DOMProxyHandler*
1155 : getInstance();
1156 :
1157 : virtual bool
1158 : delete_(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id, JS::ObjectOpResult& opresult) const override;
1159 :
1160 : virtual bool
1161 : getPrototypeIfOrdinary(JSContext* cx, JS::Handle<JSObject*> proxy, bool* isOrdinary, JS::MutableHandle<JSObject*> proto) const override;
1162 : };
1163 :
1164 : MOZ_ALWAYS_INLINE bool
1165 : IsProxy(JSObject* obj)
1166 : {
1167 : return js::IsProxy(obj) && js::GetProxyHandler(obj) == DOMProxyHandler::getInstance();
1168 : }
1169 :
1170 : MOZ_ALWAYS_INLINE mozilla::dom::Location*
1171 : UnwrapProxy(JSObject* obj)
1172 : {
1173 : MOZ_ASSERT(js::IsProxy(obj));
1174 : if (js::GetProxyHandler(obj) != DOMProxyHandler::getInstance()) {
1175 : MOZ_ASSERT(xpc::WrapperFactory::IsXrayWrapper(obj));
1176 : obj = js::UncheckedUnwrap(obj);
1177 : }
1178 : MOZ_ASSERT(IsProxy(obj));
1179 : return static_cast<mozilla::dom::Location*>(js::GetProxyReservedSlot(obj, DOM_OBJECT_SLOT).toPrivate());
1180 : }
1181 :
1182 : bool
1183 0 : DOMProxyHandler::getOwnPropDescriptor(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id, bool ignoreNamedProps, JS::MutableHandle<JS::PropertyDescriptor> desc) const
1184 : {
1185 0 : bool isXray = xpc::WrapperFactory::IsXrayWrapper(proxy);
1186 0 : JS::Rooted<JSObject*> expando(cx);
1187 0 : if (!isXray && (expando = GetExpandoObject(proxy))) {
1188 0 : if (!JS_GetOwnPropertyDescriptorById(cx, expando, id, desc)) {
1189 0 : return false;
1190 : }
1191 0 : if (desc.object()) {
1192 : // Pretend the property lives on the wrapper.
1193 0 : desc.object().set(proxy);
1194 0 : return true;
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 : return mozilla::dom::DOMProxyHandler::defineProperty(cx, proxy, id, desc, opresult, defined);
1206 : }
1207 :
1208 :
1209 : bool
1210 0 : DOMProxyHandler::ownPropNames(JSContext* cx, JS::Handle<JSObject*> proxy, unsigned flags, JS::AutoIdVector& props) const
1211 : {
1212 0 : bool isXray = xpc::WrapperFactory::IsXrayWrapper(proxy);
1213 :
1214 0 : JS::Rooted<JSObject*> expando(cx);
1215 0 : if (!isXray && (expando = DOMProxyHandler::GetExpandoObject(proxy)) &&
1216 0 : !js::GetPropertyKeys(cx, expando, flags, &props)) {
1217 0 : return false;
1218 : }
1219 :
1220 0 : return true;
1221 : }
1222 :
1223 : bool
1224 0 : DOMProxyHandler::hasOwn(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id, bool* bp) const
1225 : {
1226 0 : MOZ_ASSERT(!xpc::WrapperFactory::IsXrayWrapper(proxy),
1227 : "Should not have a XrayWrapper here");
1228 :
1229 :
1230 0 : JS::Rooted<JSObject*> expando(cx, GetExpandoObject(proxy));
1231 0 : if (expando) {
1232 0 : bool b = true;
1233 0 : bool ok = JS_HasPropertyById(cx, expando, id, &b);
1234 0 : *bp = !!b;
1235 0 : if (!ok || *bp) {
1236 0 : return ok;
1237 : }
1238 : }
1239 :
1240 0 : *bp = false;
1241 0 : return true;
1242 : }
1243 :
1244 : bool
1245 2 : DOMProxyHandler::get(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<JS::Value> receiver, JS::Handle<jsid> id, JS::MutableHandle<JS::Value> vp) const
1246 : {
1247 2 : MOZ_ASSERT(!xpc::WrapperFactory::IsXrayWrapper(proxy),
1248 : "Should not have a XrayWrapper here");
1249 :
1250 : { // Scope for expando
1251 2 : JS::Rooted<JSObject*> expando(cx, DOMProxyHandler::GetExpandoObject(proxy));
1252 2 : if (expando) {
1253 : bool hasProp;
1254 2 : if (!JS_HasPropertyById(cx, expando, id, &hasProp)) {
1255 2 : return false;
1256 : }
1257 :
1258 2 : if (hasProp) {
1259 : // Forward the get to the expando object, but our receiver is whatever our
1260 : // receiver is.
1261 2 : return JS_ForwardGetPropertyTo(cx, expando, id, receiver, vp);
1262 : }
1263 : }
1264 : }
1265 :
1266 : bool foundOnPrototype;
1267 0 : if (!GetPropertyOnPrototype(cx, proxy, receiver, id, &foundOnPrototype, vp)) {
1268 0 : return false;
1269 : }
1270 :
1271 0 : if (foundOnPrototype) {
1272 0 : return true;
1273 : }
1274 :
1275 0 : vp.setUndefined();
1276 0 : return true;
1277 : }
1278 :
1279 : const char*
1280 0 : DOMProxyHandler::className(JSContext* cx, JS::Handle<JSObject*> proxy) const
1281 : {
1282 0 : return "Location";
1283 : }
1284 :
1285 : bool
1286 3 : DOMProxyHandler::finalizeInBackground(const JS::Value& priv) const
1287 : {
1288 3 : return false;
1289 : }
1290 :
1291 : void
1292 0 : DOMProxyHandler::finalize(JSFreeOp* fop, JSObject* proxy) const
1293 : {
1294 0 : mozilla::dom::Location* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::Location>(proxy);
1295 0 : if (self) {
1296 0 : ClearWrapper(self, self, proxy);
1297 0 : AddForDeferredFinalization<mozilla::dom::Location>(self);
1298 : }
1299 0 : }
1300 :
1301 : const DOMProxyHandler*
1302 3 : DOMProxyHandler::getInstance()
1303 : {
1304 : static const DOMProxyHandler instance;
1305 3 : return &instance;
1306 : }
1307 :
1308 : bool
1309 0 : DOMProxyHandler::delete_(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id, JS::ObjectOpResult& opresult) const
1310 : {
1311 0 : MOZ_ASSERT(!xpc::WrapperFactory::IsXrayWrapper(proxy),
1312 : "Should not have a XrayWrapper here");
1313 :
1314 :
1315 0 : return dom::DOMProxyHandler::delete_(cx, proxy, id, opresult);
1316 : }
1317 :
1318 : bool
1319 0 : DOMProxyHandler::getPrototypeIfOrdinary(JSContext* cx, JS::Handle<JSObject*> proxy, bool* isOrdinary, JS::MutableHandle<JSObject*> proto) const
1320 : {
1321 0 : *isOrdinary = false;
1322 0 : return true;
1323 : }
1324 :
1325 : static const js::ClassExtension sClassExtension = PROXY_MAKE_EXT(
1326 : _objectMoved
1327 : );
1328 :
1329 : static const DOMJSClass sClass = {
1330 : PROXY_CLASS_WITH_EXT("Location",
1331 : JSCLASS_IS_DOMJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(1),
1332 : &sClassExtension),
1333 : { prototypes::id::Location, 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 },
1334 : IsBaseOf<nsISupports, mozilla::dom::Location >::value,
1335 : sNativePropertyHooks,
1336 : FindAssociatedGlobalForNative<mozilla::dom::Location>::Get,
1337 : GetProtoObjectHandle,
1338 : GetCCParticipant<mozilla::dom::Location>::Get()
1339 : };
1340 :
1341 : bool
1342 3 : Wrap(JSContext* aCx, mozilla::dom::Location* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
1343 : {
1344 : MOZ_ASSERT(static_cast<mozilla::dom::Location*>(aObject) ==
1345 : reinterpret_cast<mozilla::dom::Location*>(aObject),
1346 : "Multiple inheritance for mozilla::dom::Location is broken.");
1347 3 : MOZ_ASSERT(ToSupportsIsCorrect(aObject));
1348 3 : MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
1349 3 : MOZ_ASSERT(!aCache->GetWrapper(),
1350 : "You should probably not be using Wrap() directly; use "
1351 : "GetOrCreateDOMReflector instead");
1352 :
1353 3 : MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
1354 : "nsISupports must be on our primary inheritance chain");
1355 :
1356 6 : JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
1357 3 : if (!global) {
1358 0 : return false;
1359 : }
1360 3 : MOZ_ASSERT(JS_IsGlobalObject(global));
1361 3 : MOZ_ASSERT(JS::ObjectIsNotGray(global));
1362 :
1363 : // That might have ended up wrapping us already, due to the wonders
1364 : // of XBL. Check for that, and bail out as needed.
1365 3 : aReflector.set(aCache->GetWrapper());
1366 3 : if (aReflector) {
1367 : #ifdef DEBUG
1368 0 : binding_detail::AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
1369 : #endif // DEBUG
1370 0 : return true;
1371 : }
1372 :
1373 6 : JSAutoCompartment ac(aCx, global);
1374 3 : JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
1375 3 : if (!canonicalProto) {
1376 0 : return false;
1377 : }
1378 6 : JS::Rooted<JSObject*> proto(aCx);
1379 3 : if (aGivenProto) {
1380 0 : proto = aGivenProto;
1381 : // Unfortunately, while aGivenProto was in the compartment of aCx
1382 : // coming in, we changed compartments to that of "parent" so may need
1383 : // to wrap the proto here.
1384 0 : if (js::GetContextCompartment(aCx) != js::GetObjectCompartment(proto)) {
1385 0 : if (!JS_WrapObject(aCx, &proto)) {
1386 0 : return false;
1387 : }
1388 : }
1389 : } else {
1390 3 : proto = canonicalProto;
1391 : }
1392 :
1393 6 : BindingJSObjectCreator<mozilla::dom::Location> creator(aCx);
1394 6 : JS::Rooted<JS::Value> expandoValue(aCx, JS::UndefinedValue());
1395 6 : creator.CreateProxyObject(aCx, &sClass.mBase, DOMProxyHandler::getInstance(),
1396 3 : proto, aObject, expandoValue, aReflector);
1397 3 : if (!aReflector) {
1398 0 : return false;
1399 : }
1400 :
1401 :
1402 3 : aCache->SetWrapper(aReflector);
1403 :
1404 : // Important: do unforgeable property setup after we have handed
1405 : // over ownership of the C++ object to obj as needed, so that if
1406 : // we fail and it ends up GCed it won't have problems in the
1407 : // finalizer trying to drop its ownership of the C++ object.
1408 : JS::Rooted<JSObject*> expando(aCx,
1409 6 : DOMProxyHandler::EnsureExpandoObject(aCx, aReflector));
1410 3 : if (!expando) {
1411 0 : aCache->ReleaseWrapper(aObject);
1412 0 : aCache->ClearWrapper();
1413 0 : return false;
1414 : }
1415 : JS::Rooted<JSObject*> unforgeableHolder(aCx,
1416 6 : &js::GetReservedSlot(canonicalProto, DOM_INTERFACE_PROTO_SLOTS_BASE).toObject());
1417 3 : if (!JS_InitializePropertiesFromCompatibleNativeObject(aCx, expando, unforgeableHolder)) {
1418 0 : aCache->ReleaseWrapper(aObject);
1419 0 : aCache->ClearWrapper();
1420 0 : return false;
1421 : }
1422 : bool succeeded;
1423 3 : if (!JS_SetImmutablePrototype(aCx, aReflector, &succeeded)) {
1424 0 : aCache->ReleaseWrapper(aObject);
1425 0 : aCache->ClearWrapper();
1426 0 : return false;
1427 :
1428 : }
1429 3 : MOZ_ASSERT(succeeded,
1430 : "Making a fresh reflector instance have an immutable "
1431 : "prototype can internally fail, but it should never be "
1432 : "unsuccessful");
1433 3 : creator.InitializationSucceeded();
1434 :
1435 3 : MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
1436 : aCache->GetWrapperPreserveColor() == aReflector);
1437 : // If proto != canonicalProto, we have to preserve our wrapper;
1438 : // otherwise we won't be able to properly recreate it later, since
1439 : // we won't know what proto to use. Note that we don't check
1440 : // aGivenProto here, since it's entirely possible (and even
1441 : // somewhat common) to have a non-null aGivenProto which is the
1442 : // same as canonicalProto.
1443 3 : if (proto != canonicalProto) {
1444 0 : PreserveWrapper(aObject);
1445 : }
1446 :
1447 3 : return true;
1448 : }
1449 :
1450 : static bool
1451 0 : ResolveOwnProperty(JSContext* cx, JS::Handle<JSObject*> wrapper, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::MutableHandle<JS::PropertyDescriptor> desc)
1452 : {
1453 0 : return js::GetProxyHandler(obj)->getOwnPropertyDescriptor(cx, wrapper, id, desc);
1454 : }
1455 :
1456 : static bool
1457 0 : EnumerateOwnProperties(JSContext* cx, JS::Handle<JSObject*> wrapper, JS::Handle<JSObject*> obj, JS::AutoIdVector& props)
1458 : {
1459 0 : return js::GetProxyHandler(obj)->ownPropertyKeys(cx, wrapper, props);
1460 : }
1461 :
1462 : const NativePropertyHooks sNativePropertyHooks[] = { {
1463 : ResolveOwnProperty,
1464 : EnumerateOwnProperties,
1465 : nullptr,
1466 : { sNativeProperties.Upcast(), nullptr },
1467 : prototypes::id::Location,
1468 : constructors::id::Location,
1469 : nullptr,
1470 : &DefaultXrayExpandoObjectClass
1471 : } };
1472 :
1473 : void
1474 3 : CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, bool aDefineOnGlobal)
1475 : {
1476 6 : JS::Rooted<JSObject*> parentProto(aCx, JS::GetRealmObjectPrototype(aCx));
1477 3 : if (!parentProto) {
1478 0 : return;
1479 : }
1480 :
1481 6 : JS::Rooted<JSObject*> constructorProto(aCx, JS::GetRealmFunctionPrototype(aCx));
1482 3 : if (!constructorProto) {
1483 0 : return;
1484 : }
1485 :
1486 : static bool sIdsInited = false;
1487 3 : if (!sIdsInited && NS_IsMainThread()) {
1488 2 : if (!InitIds(aCx, sNativeProperties.Upcast())) {
1489 0 : return;
1490 : }
1491 2 : sIdsInited = true;
1492 : }
1493 :
1494 3 : JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::Location);
1495 3 : JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::Location);
1496 6 : dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
1497 : &sPrototypeClass.mBase, protoCache,
1498 : constructorProto, &sInterfaceObjectClass.mBase, 0, nullptr,
1499 : interfaceCache,
1500 : sNativeProperties.Upcast(),
1501 : nullptr,
1502 : "Location", aDefineOnGlobal,
1503 : nullptr,
1504 3 : false);
1505 :
1506 6 : JS::Rooted<JSObject*> unforgeableHolder(aCx);
1507 : {
1508 6 : JS::Rooted<JSObject*> holderProto(aCx, nullptr);
1509 3 : unforgeableHolder = JS_NewObjectWithoutMetadata(aCx, nullptr, holderProto);
1510 3 : if (!unforgeableHolder) {
1511 0 : *protoCache = nullptr;
1512 0 : if (interfaceCache) {
1513 0 : *interfaceCache = nullptr;
1514 : }
1515 0 : return;
1516 : }
1517 : }
1518 :
1519 3 : if (!DefineUnforgeableAttributes(aCx, unforgeableHolder, sUnforgeableAttributes)) {
1520 0 : *protoCache = nullptr;
1521 0 : if (interfaceCache) {
1522 0 : *interfaceCache = nullptr;
1523 : }
1524 0 : return;
1525 : }
1526 3 : if (!DefineUnforgeableMethods(aCx, unforgeableHolder, sUnforgeableMethods)) {
1527 0 : *protoCache = nullptr;
1528 0 : if (interfaceCache) {
1529 0 : *interfaceCache = nullptr;
1530 : }
1531 0 : return;
1532 : }
1533 : JS::RootedId toPrimitive(aCx,
1534 6 : SYMBOL_TO_JSID(JS::GetWellKnownSymbol(aCx, JS::SymbolCode::toPrimitive)));
1535 3 : if (!JS_DefinePropertyById(aCx, unforgeableHolder, toPrimitive,
1536 : JS::UndefinedHandleValue,
1537 : JSPROP_READONLY | JSPROP_PERMANENT)) {
1538 0 : *protoCache = nullptr;
1539 0 : if (interfaceCache) {
1540 0 : *interfaceCache = nullptr;
1541 : }
1542 0 : return;
1543 : }
1544 :
1545 3 : if (*protoCache) {
1546 3 : js::SetReservedSlot(*protoCache, DOM_INTERFACE_PROTO_SLOTS_BASE,
1547 6 : JS::ObjectValue(*unforgeableHolder));
1548 : }
1549 : }
1550 :
1551 : JS::Handle<JSObject*>
1552 3 : GetProtoObjectHandle(JSContext* aCx)
1553 : {
1554 : /* Get the interface prototype object for this class. This will create the
1555 : object as needed. */
1556 3 : bool aDefineOnGlobal = true;
1557 :
1558 : /* Make sure our global is sane. Hopefully we can remove this sometime */
1559 3 : JSObject* global = JS::CurrentGlobalOrNull(aCx);
1560 3 : if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
1561 0 : return nullptr;
1562 : }
1563 :
1564 : /* Check to see whether the interface objects are already installed */
1565 3 : ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
1566 3 : if (!protoAndIfaceCache.HasEntryInSlot(prototypes::id::Location)) {
1567 6 : JS::Rooted<JSObject*> rootedGlobal(aCx, global);
1568 3 : CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
1569 : }
1570 :
1571 : /*
1572 : * The object might _still_ be null, but that's OK.
1573 : *
1574 : * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
1575 : * traced by TraceProtoAndIfaceCache() and its contents are never
1576 : * changed after they have been set.
1577 : *
1578 : * Calling address() avoids the read read barrier that does gray
1579 : * unmarking, but it's not possible for the object to be gray here.
1580 : */
1581 :
1582 3 : const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(prototypes::id::Location);
1583 3 : MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
1584 3 : return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
1585 : }
1586 :
1587 : JS::Handle<JSObject*>
1588 0 : GetConstructorObjectHandle(JSContext* aCx, bool aDefineOnGlobal)
1589 : {
1590 : /* Get the interface object for this class. This will create the object as
1591 : needed. */
1592 :
1593 : /* Make sure our global is sane. Hopefully we can remove this sometime */
1594 0 : JSObject* global = JS::CurrentGlobalOrNull(aCx);
1595 0 : if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
1596 0 : return nullptr;
1597 : }
1598 :
1599 : /* Check to see whether the interface objects are already installed */
1600 0 : ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
1601 0 : if (!protoAndIfaceCache.HasEntryInSlot(constructors::id::Location)) {
1602 0 : JS::Rooted<JSObject*> rootedGlobal(aCx, global);
1603 0 : CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
1604 : }
1605 :
1606 : /*
1607 : * The object might _still_ be null, but that's OK.
1608 : *
1609 : * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
1610 : * traced by TraceProtoAndIfaceCache() and its contents are never
1611 : * changed after they have been set.
1612 : *
1613 : * Calling address() avoids the read read barrier that does gray
1614 : * unmarking, but it's not possible for the object to be gray here.
1615 : */
1616 :
1617 0 : const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(constructors::id::Location);
1618 0 : MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
1619 0 : return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
1620 : }
1621 :
1622 : JSObject*
1623 0 : GetConstructorObject(JSContext* aCx)
1624 : {
1625 0 : return GetConstructorObjectHandle(aCx);
1626 : }
1627 :
1628 : } // namespace LocationBinding
1629 :
1630 :
1631 :
1632 : } // namespace dom
1633 : } // namespace mozilla
|