Line data Source code
1 : /* THIS FILE IS AUTOGENERATED FROM TCPServerSocket.webidl BY Codegen.py - DO NOT EDIT */
2 :
3 : #include "AtomList.h"
4 : #include "EventHandlerBinding.h"
5 : #include "EventTargetBinding.h"
6 : #include "TCPServerSocketBinding.h"
7 : #include "WrapperFactory.h"
8 : #include "mozilla/OwningNonNull.h"
9 : #include "mozilla/dom/BindingUtils.h"
10 : #include "mozilla/dom/DOMJSClass.h"
11 : #include "mozilla/dom/NonRefcountedDOMObject.h"
12 : #include "mozilla/dom/Nullable.h"
13 : #include "mozilla/dom/PrimitiveConversions.h"
14 : #include "mozilla/dom/ScriptSettings.h"
15 : #include "mozilla/dom/SimpleGlobalObject.h"
16 : #include "mozilla/dom/TCPServerSocket.h"
17 : #include "mozilla/dom/TCPSocket.h"
18 : #include "mozilla/dom/XrayExpandoClass.h"
19 :
20 : namespace mozilla {
21 : namespace dom {
22 :
23 :
24 0 : ServerSocketOptions::ServerSocketOptions()
25 : {
26 : // Safe to pass a null context if we pass a null value
27 0 : Init(nullptr, JS::NullHandleValue);
28 0 : }
29 :
30 :
31 :
32 : bool
33 0 : ServerSocketOptions::InitIds(JSContext* cx, ServerSocketOptionsAtoms* atomsCache)
34 : {
35 0 : MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
36 :
37 : // Initialize these in reverse order so that any failure leaves the first one
38 : // uninitialized.
39 0 : if (!atomsCache->binaryType_id.init(cx, "binaryType")) {
40 0 : return false;
41 : }
42 0 : return true;
43 : }
44 :
45 : bool
46 0 : ServerSocketOptions::Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
47 : {
48 : // Passing a null JSContext is OK only if we're initing from null,
49 : // Since in that case we will not have to do any property gets
50 : // Also evaluate isNullOrUndefined in order to avoid false-positive
51 : // checkers by static analysis tools
52 0 : MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
53 0 : ServerSocketOptionsAtoms* atomsCache = nullptr;
54 0 : if (cx) {
55 0 : atomsCache = GetAtomCache<ServerSocketOptionsAtoms>(cx);
56 0 : if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
57 0 : return false;
58 : }
59 : }
60 :
61 0 : if (!IsConvertibleToDictionary(val)) {
62 0 : return ThrowErrorMessage(cx, MSG_NOT_DICTIONARY, sourceDescription);
63 : }
64 :
65 0 : bool isNull = val.isNullOrUndefined();
66 : // We only need these if !isNull, in which case we have |cx|.
67 0 : Maybe<JS::Rooted<JSObject *> > object;
68 0 : Maybe<JS::Rooted<JS::Value> > temp;
69 0 : if (!isNull) {
70 0 : MOZ_ASSERT(cx);
71 0 : object.emplace(cx, &val.toObject());
72 0 : temp.emplace(cx);
73 : }
74 0 : if (!isNull) {
75 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->binaryType_id, temp.ptr())) {
76 0 : return false;
77 : }
78 : }
79 0 : if (!isNull && !temp->isUndefined()) {
80 : {
81 : int index;
82 0 : if (!FindEnumStringIndex<true>(cx, temp.ref(), TCPSocketBinaryTypeValues::strings, "TCPSocketBinaryType", "'binaryType' member of ServerSocketOptions", &index)) {
83 0 : return false;
84 : }
85 0 : MOZ_ASSERT(index >= 0);
86 0 : mBinaryType = static_cast<TCPSocketBinaryType>(index);
87 : }
88 : } else {
89 0 : mBinaryType = TCPSocketBinaryType::String;
90 : }
91 0 : mIsAnyMemberPresent = true;
92 0 : return true;
93 : }
94 :
95 : bool
96 0 : ServerSocketOptions::Init(const nsAString& aJSON)
97 : {
98 0 : AutoJSAPI jsapi;
99 0 : JSObject* cleanGlobal = SimpleGlobalObject::Create(SimpleGlobalObject::GlobalType::BindingDetail);
100 0 : if (!cleanGlobal) {
101 0 : return false;
102 : }
103 0 : if (!jsapi.Init(cleanGlobal)) {
104 0 : return false;
105 : }
106 0 : JSContext* cx = jsapi.cx();
107 0 : JS::Rooted<JS::Value> json(cx);
108 0 : bool ok = ParseJSON(cx, aJSON, &json);
109 0 : NS_ENSURE_TRUE(ok, false);
110 0 : return Init(cx, json);
111 : }
112 :
113 : bool
114 0 : ServerSocketOptions::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
115 : {
116 0 : ServerSocketOptionsAtoms* atomsCache = GetAtomCache<ServerSocketOptionsAtoms>(cx);
117 0 : if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
118 0 : return false;
119 : }
120 :
121 0 : JS::Rooted<JSObject*> obj(cx, JS_NewPlainObject(cx));
122 0 : if (!obj) {
123 0 : return false;
124 : }
125 0 : rval.set(JS::ObjectValue(*obj));
126 :
127 : do {
128 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
129 0 : JS::Rooted<JS::Value> temp(cx);
130 0 : TCPSocketBinaryType const & currentValue = mBinaryType;
131 0 : if (!ToJSValue(cx, currentValue, &temp)) {
132 0 : return false;
133 : }
134 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->binaryType_id, temp, JSPROP_ENUMERATE)) {
135 0 : return false;
136 : }
137 0 : break;
138 : } while(0);
139 :
140 0 : return true;
141 : }
142 :
143 : bool
144 0 : ServerSocketOptions::ToJSON(nsAString& aJSON) const
145 : {
146 0 : AutoJSAPI jsapi;
147 0 : jsapi.Init();
148 0 : JSContext *cx = jsapi.cx();
149 : // It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here
150 : // because we'll only be creating objects, in ways that have no
151 : // side-effects, followed by a call to JS::ToJSONMaybeSafely,
152 : // which likewise guarantees no side-effects for the sorts of
153 : // things we will pass it.
154 0 : JSAutoCompartment ac(cx, binding_detail::UnprivilegedJunkScopeOrWorkerGlobal());
155 0 : JS::Rooted<JS::Value> val(cx);
156 0 : if (!ToObjectInternal(cx, &val)) {
157 0 : return false;
158 : }
159 0 : JS::Rooted<JSObject*> obj(cx, &val.toObject());
160 0 : return StringifyToJSON(cx, obj, aJSON);
161 : }
162 :
163 : void
164 0 : ServerSocketOptions::TraceDictionary(JSTracer* trc)
165 : {
166 0 : }
167 :
168 : ServerSocketOptions&
169 0 : ServerSocketOptions::operator=(const ServerSocketOptions& aOther)
170 : {
171 0 : mBinaryType = aOther.mBinaryType;
172 0 : return *this;
173 : }
174 :
175 : namespace binding_detail {
176 : } // namespace binding_detail
177 :
178 :
179 : namespace TCPServerSocketBinding {
180 :
181 : static_assert(IsRefcounted<NativeType>::value == IsRefcounted<EventTargetBinding::NativeType>::value,
182 : "Can't inherit from an interface with a different ownership model.");
183 :
184 : static bool
185 0 : get_localPort(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TCPServerSocket* self, JSJitGetterCallArgs args)
186 : {
187 0 : uint16_t result(self->LocalPort());
188 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
189 0 : args.rval().setInt32(int32_t(result));
190 0 : return true;
191 : }
192 :
193 : static const JSJitInfo localPort_getterinfo = {
194 : { (JSJitGetterOp)get_localPort },
195 : { prototypes::id::TCPServerSocket },
196 : { PrototypeTraits<prototypes::id::TCPServerSocket>::Depth },
197 : JSJitInfo::Getter,
198 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
199 : JSVAL_TYPE_INT32, /* returnType. Not relevant for setters. */
200 : true, /* isInfallible. False in setters. */
201 : false, /* isMovable. Not relevant for setters. */
202 : false, /* isEliminatable. Not relevant for setters. */
203 : false, /* isAlwaysInSlot. Only relevant for getters. */
204 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
205 : false, /* isTypedMethod. Only relevant for methods. */
206 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
207 : };
208 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
209 : static_assert(0 < 1, "There is no slot for us");
210 :
211 : static bool
212 0 : get_onconnect(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TCPServerSocket* self, JSJitGetterCallArgs args)
213 : {
214 0 : RefPtr<EventHandlerNonNull> result(self->GetOnconnect());
215 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
216 0 : if (result) {
217 0 : args.rval().setObjectOrNull(GetCallbackFromCallbackObject(result));
218 0 : if (!MaybeWrapObjectOrNullValue(cx, args.rval())) {
219 0 : return false;
220 : }
221 0 : return true;
222 : } else {
223 0 : args.rval().setNull();
224 0 : return true;
225 : }
226 : }
227 :
228 : static bool
229 0 : set_onconnect(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TCPServerSocket* self, JSJitSetterCallArgs args)
230 : {
231 0 : RootedCallback<RefPtr<binding_detail::FastEventHandlerNonNull>> arg0(cx);
232 0 : if (args[0].isObject()) {
233 : { // scope for tempRoot
234 0 : JS::Rooted<JSObject*> tempRoot(cx, &args[0].toObject());
235 0 : arg0 = new binding_detail::FastEventHandlerNonNull(tempRoot);
236 : }
237 : } else {
238 0 : arg0 = nullptr;
239 : }
240 0 : self->SetOnconnect(Constify(arg0));
241 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
242 :
243 0 : return true;
244 : }
245 :
246 : static const JSJitInfo onconnect_getterinfo = {
247 : { (JSJitGetterOp)get_onconnect },
248 : { prototypes::id::TCPServerSocket },
249 : { PrototypeTraits<prototypes::id::TCPServerSocket>::Depth },
250 : JSJitInfo::Getter,
251 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
252 : JSVAL_TYPE_UNKNOWN, /* returnType. Not relevant for setters. */
253 : false, /* isInfallible. False in setters. */
254 : false, /* isMovable. Not relevant for setters. */
255 : false, /* isEliminatable. Not relevant for setters. */
256 : false, /* isAlwaysInSlot. Only relevant for getters. */
257 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
258 : false, /* isTypedMethod. Only relevant for methods. */
259 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
260 : };
261 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
262 : static_assert(0 < 1, "There is no slot for us");
263 : static const JSJitInfo onconnect_setterinfo = {
264 : { (JSJitGetterOp)set_onconnect },
265 : { prototypes::id::TCPServerSocket },
266 : { PrototypeTraits<prototypes::id::TCPServerSocket>::Depth },
267 : JSJitInfo::Setter,
268 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
269 : JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
270 : false, /* isInfallible. False in setters. */
271 : false, /* isMovable. Not relevant for setters. */
272 : false, /* isEliminatable. Not relevant for setters. */
273 : false, /* isAlwaysInSlot. Only relevant for getters. */
274 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
275 : false, /* isTypedMethod. Only relevant for methods. */
276 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
277 : };
278 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
279 : static_assert(0 < 1, "There is no slot for us");
280 :
281 : static bool
282 0 : get_onerror(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TCPServerSocket* self, JSJitGetterCallArgs args)
283 : {
284 0 : RefPtr<EventHandlerNonNull> result(self->GetOnerror());
285 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
286 0 : if (result) {
287 0 : args.rval().setObjectOrNull(GetCallbackFromCallbackObject(result));
288 0 : if (!MaybeWrapObjectOrNullValue(cx, args.rval())) {
289 0 : return false;
290 : }
291 0 : return true;
292 : } else {
293 0 : args.rval().setNull();
294 0 : return true;
295 : }
296 : }
297 :
298 : static bool
299 0 : set_onerror(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TCPServerSocket* self, JSJitSetterCallArgs args)
300 : {
301 0 : RootedCallback<RefPtr<binding_detail::FastEventHandlerNonNull>> arg0(cx);
302 0 : if (args[0].isObject()) {
303 : { // scope for tempRoot
304 0 : JS::Rooted<JSObject*> tempRoot(cx, &args[0].toObject());
305 0 : arg0 = new binding_detail::FastEventHandlerNonNull(tempRoot);
306 : }
307 : } else {
308 0 : arg0 = nullptr;
309 : }
310 0 : self->SetOnerror(Constify(arg0));
311 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
312 :
313 0 : return true;
314 : }
315 :
316 : static const JSJitInfo onerror_getterinfo = {
317 : { (JSJitGetterOp)get_onerror },
318 : { prototypes::id::TCPServerSocket },
319 : { PrototypeTraits<prototypes::id::TCPServerSocket>::Depth },
320 : JSJitInfo::Getter,
321 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
322 : JSVAL_TYPE_UNKNOWN, /* returnType. Not relevant for setters. */
323 : false, /* isInfallible. False in setters. */
324 : false, /* isMovable. Not relevant for setters. */
325 : false, /* isEliminatable. Not relevant for setters. */
326 : false, /* isAlwaysInSlot. Only relevant for getters. */
327 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
328 : false, /* isTypedMethod. Only relevant for methods. */
329 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
330 : };
331 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
332 : static_assert(0 < 1, "There is no slot for us");
333 : static const JSJitInfo onerror_setterinfo = {
334 : { (JSJitGetterOp)set_onerror },
335 : { prototypes::id::TCPServerSocket },
336 : { PrototypeTraits<prototypes::id::TCPServerSocket>::Depth },
337 : JSJitInfo::Setter,
338 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
339 : JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
340 : false, /* isInfallible. False in setters. */
341 : false, /* isMovable. Not relevant for setters. */
342 : false, /* isEliminatable. Not relevant for setters. */
343 : false, /* isAlwaysInSlot. Only relevant for getters. */
344 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
345 : false, /* isTypedMethod. Only relevant for methods. */
346 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
347 : };
348 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
349 : static_assert(0 < 1, "There is no slot for us");
350 :
351 : static bool
352 0 : close(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TCPServerSocket* self, const JSJitMethodCallArgs& args)
353 : {
354 0 : self->Close();
355 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
356 0 : args.rval().setUndefined();
357 0 : return true;
358 : }
359 :
360 : static const JSJitInfo close_methodinfo = {
361 : { (JSJitGetterOp)close },
362 : { prototypes::id::TCPServerSocket },
363 : { PrototypeTraits<prototypes::id::TCPServerSocket>::Depth },
364 : JSJitInfo::Method,
365 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
366 : JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
367 : true, /* isInfallible. False in setters. */
368 : false, /* isMovable. Not relevant for setters. */
369 : false, /* isEliminatable. Not relevant for setters. */
370 : false, /* isAlwaysInSlot. Only relevant for getters. */
371 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
372 : false, /* isTypedMethod. Only relevant for methods. */
373 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
374 : };
375 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
376 : static_assert(0 < 1, "There is no slot for us");
377 :
378 : static bool
379 0 : _addProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::Handle<JS::Value> val)
380 : {
381 0 : mozilla::dom::TCPServerSocket* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::TCPServerSocket>(obj);
382 : // We don't want to preserve if we don't have a wrapper, and we
383 : // obviously can't preserve if we're not initialized.
384 0 : if (self && self->GetWrapperPreserveColor()) {
385 0 : PreserveWrapper(self);
386 : }
387 0 : return true;
388 : }
389 :
390 : static void
391 0 : _finalize(js::FreeOp* fop, JSObject* obj)
392 : {
393 0 : mozilla::dom::TCPServerSocket* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::TCPServerSocket>(obj);
394 0 : if (self) {
395 0 : ClearWrapper(self, self, obj);
396 0 : AddForDeferredFinalization<mozilla::dom::TCPServerSocket>(self);
397 : }
398 0 : }
399 :
400 : static void
401 0 : _objectMoved(JSObject* obj, const JSObject* old)
402 : {
403 0 : mozilla::dom::TCPServerSocket* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::TCPServerSocket>(obj);
404 0 : if (self) {
405 0 : UpdateWrapper(self, self, obj, old);
406 : }
407 0 : }
408 :
409 : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
410 : #if defined(__clang__)
411 : #pragma clang diagnostic push
412 : #pragma clang diagnostic ignored "-Wmissing-braces"
413 : #endif
414 : static const JSFunctionSpec sMethods_specs[] = {
415 : JS_FNSPEC("close", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&close_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
416 : JS_FS_END
417 : };
418 : #if defined(__clang__)
419 : #pragma clang diagnostic pop
420 : #endif
421 :
422 :
423 : // Can't be const because the pref-enabled boolean needs to be writable
424 : static Prefable<const JSFunctionSpec> sMethods[] = {
425 : { nullptr, &sMethods_specs[0] },
426 : { nullptr, nullptr }
427 : };
428 :
429 : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
430 : "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
431 : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
432 : "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
433 :
434 : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
435 : #if defined(__clang__)
436 : #pragma clang diagnostic push
437 : #pragma clang diagnostic ignored "-Wmissing-braces"
438 : #endif
439 : static const JSPropertySpec sAttributes_specs[] = {
440 : { "localPort", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &localPort_getterinfo, nullptr, nullptr },
441 : { "onconnect", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &onconnect_getterinfo, GenericBindingSetter, &onconnect_setterinfo },
442 : { "onerror", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &onerror_getterinfo, GenericBindingSetter, &onerror_setterinfo },
443 : { nullptr, 0, nullptr, nullptr, nullptr, nullptr }
444 : };
445 : #if defined(__clang__)
446 : #pragma clang diagnostic pop
447 : #endif
448 :
449 :
450 : // Can't be const because the pref-enabled boolean needs to be writable
451 : static Prefable<const JSPropertySpec> sAttributes[] = {
452 : { nullptr, &sAttributes_specs[0] },
453 : { nullptr, nullptr }
454 : };
455 :
456 : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
457 : "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
458 : static_assert(3 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
459 : "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
460 :
461 :
462 : static uint16_t sNativeProperties_sortedPropertyIndices[4];
463 : static PropertyInfo sNativeProperties_propertyInfos[4];
464 :
465 : static const NativePropertiesN<2> sNativeProperties = {
466 : false, 0,
467 : false, 0,
468 : true, 0 /* sMethods */,
469 : true, 1 /* sAttributes */,
470 : false, 0,
471 : false, 0,
472 : false, 0,
473 : -1,
474 : 4,
475 : sNativeProperties_sortedPropertyIndices,
476 : {
477 : { sMethods, &sNativeProperties_propertyInfos[0] },
478 : { sAttributes, &sNativeProperties_propertyInfos[1] }
479 : }
480 : };
481 : static_assert(4 < 1ull << CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount),
482 : "We have a property info count that is oversized");
483 :
484 : static bool
485 0 : _constructor(JSContext* cx, unsigned argc, JS::Value* vp)
486 : {
487 0 : JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
488 0 : JS::Rooted<JSObject*> obj(cx, &args.callee());
489 0 : if (!args.isConstructing()) {
490 : // XXXbz wish I could get the name from the callee instead of
491 : // Adding more relocations
492 0 : return ThrowConstructorWithoutNew(cx, "TCPServerSocket");
493 : }
494 :
495 0 : GlobalObject global(cx, obj);
496 0 : if (global.Failed()) {
497 0 : return false;
498 : }
499 :
500 0 : JS::Rooted<JSObject*> desiredProto(cx);
501 0 : if (!GetDesiredProto(cx, args, &desiredProto)) {
502 0 : return false;
503 : }
504 :
505 0 : if (MOZ_UNLIKELY(args.length() < 1)) {
506 0 : return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "TCPServerSocket");
507 : }
508 0 : bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
509 : uint16_t arg0;
510 0 : if (!ValueToPrimitive<uint16_t, eDefault>(cx, args[0], &arg0)) {
511 0 : return false;
512 : }
513 0 : binding_detail::FastServerSocketOptions arg1;
514 0 : if (!arg1.Init(cx, (args.hasDefined(1)) ? args[1] : JS::NullHandleValue, "Argument 2 of TCPServerSocket.constructor", false)) {
515 0 : return false;
516 : }
517 : uint16_t arg2;
518 0 : if (args.hasDefined(2)) {
519 0 : if (!ValueToPrimitive<uint16_t, eDefault>(cx, args[2], &arg2)) {
520 0 : return false;
521 : }
522 : } else {
523 0 : arg2 = 0;
524 : }
525 0 : Maybe<JSAutoCompartment> ac;
526 0 : if (objIsXray) {
527 0 : obj = js::CheckedUnwrap(obj);
528 0 : if (!obj) {
529 0 : return false;
530 : }
531 0 : ac.emplace(cx, obj);
532 0 : if (!JS_WrapObject(cx, &desiredProto)) {
533 0 : return false;
534 : }
535 : }
536 0 : binding_detail::FastErrorResult rv;
537 0 : auto result(StrongOrRawPtr<mozilla::dom::TCPServerSocket>(mozilla::dom::TCPServerSocket::Constructor(global, arg0, Constify(arg1), arg2, rv)));
538 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
539 0 : return false;
540 : }
541 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
542 : static_assert(!IsPointer<decltype(result)>::value,
543 : "NewObject implies that we need to keep the object alive with a strong reference.");
544 0 : if (!GetOrCreateDOMReflector(cx, result, args.rval(), desiredProto)) {
545 0 : MOZ_ASSERT(true || JS_IsExceptionPending(cx));
546 0 : return false;
547 : }
548 0 : return true;
549 : }
550 :
551 : static const js::ClassOps sInterfaceObjectClassOps = {
552 : nullptr, /* addProperty */
553 : nullptr, /* delProperty */
554 : nullptr, /* getProperty */
555 : nullptr, /* setProperty */
556 : nullptr, /* enumerate */
557 : nullptr, /* newEnumerate */
558 : nullptr, /* resolve */
559 : nullptr, /* mayResolve */
560 : nullptr, /* finalize */
561 : _constructor, /* call */
562 : nullptr, /* hasInstance */
563 : _constructor, /* construct */
564 : nullptr, /* trace */
565 : };
566 :
567 : static const DOMIfaceAndProtoJSClass sInterfaceObjectClass = {
568 : {
569 : "Function",
570 : JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_SLOTS_BASE),
571 : &sInterfaceObjectClassOps,
572 : JS_NULL_CLASS_SPEC,
573 : JS_NULL_CLASS_EXT,
574 : &sInterfaceObjectClassObjectOps
575 : },
576 : eInterface,
577 : true,
578 : prototypes::id::TCPServerSocket,
579 : PrototypeTraits<prototypes::id::TCPServerSocket>::Depth,
580 : sNativePropertyHooks,
581 : "function TCPServerSocket() {\n [native code]\n}",
582 : EventTargetBinding::GetConstructorObject
583 : };
584 :
585 : static const DOMIfaceAndProtoJSClass sPrototypeClass = {
586 : {
587 : "TCPServerSocketPrototype",
588 : JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE),
589 : JS_NULL_CLASS_OPS,
590 : JS_NULL_CLASS_SPEC,
591 : JS_NULL_CLASS_EXT,
592 : JS_NULL_OBJECT_OPS
593 : },
594 : eInterfacePrototype,
595 : false,
596 : prototypes::id::TCPServerSocket,
597 : PrototypeTraits<prototypes::id::TCPServerSocket>::Depth,
598 : sNativePropertyHooks,
599 : "[object TCPServerSocketPrototype]",
600 : EventTargetBinding::GetProtoObject
601 : };
602 :
603 : bool
604 0 : ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
605 : {
606 0 : return mozilla::dom::TCPSocket::ShouldTCPSocketExist(aCx, aObj);
607 : }
608 :
609 : JSObject*
610 0 : DefineDOMInterface(JSContext* aCx, JS::Handle<JSObject*> aGlobal, JS::Handle<jsid> id, bool aDefineOnGlobal)
611 : {
612 0 : return GetConstructorObjectHandle(aCx, aDefineOnGlobal);
613 : }
614 :
615 : static const js::ClassOps sClassOps = {
616 : _addProperty, /* addProperty */
617 : nullptr, /* delProperty */
618 : nullptr, /* getProperty */
619 : nullptr, /* setProperty */
620 : nullptr, /* enumerate */
621 : nullptr, /* newEnumerate */
622 : nullptr, /* resolve */
623 : nullptr, /* mayResolve */
624 : _finalize, /* finalize */
625 : nullptr, /* call */
626 : nullptr, /* hasInstance */
627 : nullptr, /* construct */
628 : nullptr, /* trace */
629 : };
630 :
631 : static const js::ClassExtension sClassExtension = {
632 : nullptr, /* weakmapKeyDelegateOp */
633 : _objectMoved /* objectMovedOp */
634 : };
635 :
636 : static const DOMJSClass sClass = {
637 : { "TCPServerSocket",
638 : JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1),
639 : &sClassOps,
640 : JS_NULL_CLASS_SPEC,
641 : &sClassExtension,
642 : JS_NULL_OBJECT_OPS
643 : },
644 : { prototypes::id::EventTarget, prototypes::id::TCPServerSocket, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
645 : IsBaseOf<nsISupports, mozilla::dom::TCPServerSocket >::value,
646 : sNativePropertyHooks,
647 : FindAssociatedGlobalForNative<mozilla::dom::TCPServerSocket>::Get,
648 : GetProtoObjectHandle,
649 : GetCCParticipant<mozilla::dom::TCPServerSocket>::Get()
650 : };
651 : static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
652 : "Must have the right minimal number of reserved slots.");
653 : static_assert(1 >= 1,
654 : "Must have enough reserved slots.");
655 :
656 : const JSClass*
657 0 : GetJSClass()
658 : {
659 0 : return sClass.ToJSClass();
660 : }
661 :
662 : bool
663 0 : Wrap(JSContext* aCx, mozilla::dom::TCPServerSocket* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
664 : {
665 : MOZ_ASSERT(static_cast<mozilla::dom::TCPServerSocket*>(aObject) ==
666 : reinterpret_cast<mozilla::dom::TCPServerSocket*>(aObject),
667 : "Multiple inheritance for mozilla::dom::TCPServerSocket is broken.");
668 : MOZ_ASSERT(static_cast<mozilla::dom::EventTarget*>(aObject) ==
669 : reinterpret_cast<mozilla::dom::EventTarget*>(aObject),
670 : "Multiple inheritance for mozilla::dom::EventTarget is broken.");
671 0 : MOZ_ASSERT(ToSupportsIsCorrect(aObject));
672 0 : MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
673 0 : MOZ_ASSERT(!aCache->GetWrapper(),
674 : "You should probably not be using Wrap() directly; use "
675 : "GetOrCreateDOMReflector instead");
676 :
677 0 : MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
678 : "nsISupports must be on our primary inheritance chain");
679 :
680 0 : JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
681 0 : if (!global) {
682 0 : return false;
683 : }
684 0 : MOZ_ASSERT(JS_IsGlobalObject(global));
685 0 : MOZ_ASSERT(JS::ObjectIsNotGray(global));
686 :
687 : // That might have ended up wrapping us already, due to the wonders
688 : // of XBL. Check for that, and bail out as needed.
689 0 : aReflector.set(aCache->GetWrapper());
690 0 : if (aReflector) {
691 : #ifdef DEBUG
692 0 : binding_detail::AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
693 : #endif // DEBUG
694 0 : return true;
695 : }
696 :
697 0 : JSAutoCompartment ac(aCx, global);
698 0 : JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
699 0 : if (!canonicalProto) {
700 0 : return false;
701 : }
702 0 : JS::Rooted<JSObject*> proto(aCx);
703 0 : if (aGivenProto) {
704 0 : proto = aGivenProto;
705 : // Unfortunately, while aGivenProto was in the compartment of aCx
706 : // coming in, we changed compartments to that of "parent" so may need
707 : // to wrap the proto here.
708 0 : if (js::GetContextCompartment(aCx) != js::GetObjectCompartment(proto)) {
709 0 : if (!JS_WrapObject(aCx, &proto)) {
710 0 : return false;
711 : }
712 : }
713 : } else {
714 0 : proto = canonicalProto;
715 : }
716 :
717 0 : BindingJSObjectCreator<mozilla::dom::TCPServerSocket> creator(aCx);
718 0 : creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
719 0 : if (!aReflector) {
720 0 : return false;
721 : }
722 :
723 0 : aCache->SetWrapper(aReflector);
724 0 : creator.InitializationSucceeded();
725 :
726 0 : MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
727 : aCache->GetWrapperPreserveColor() == aReflector);
728 : // If proto != canonicalProto, we have to preserve our wrapper;
729 : // otherwise we won't be able to properly recreate it later, since
730 : // we won't know what proto to use. Note that we don't check
731 : // aGivenProto here, since it's entirely possible (and even
732 : // somewhat common) to have a non-null aGivenProto which is the
733 : // same as canonicalProto.
734 0 : if (proto != canonicalProto) {
735 0 : PreserveWrapper(aObject);
736 : }
737 :
738 0 : return true;
739 : }
740 :
741 : const NativePropertyHooks sNativePropertyHooks[] = { {
742 : nullptr,
743 : nullptr,
744 : nullptr,
745 : { sNativeProperties.Upcast(), nullptr },
746 : prototypes::id::TCPServerSocket,
747 : constructors::id::TCPServerSocket,
748 : EventTargetBinding::sNativePropertyHooks,
749 : &DefaultXrayExpandoObjectClass
750 : } };
751 :
752 : void
753 0 : CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, bool aDefineOnGlobal)
754 : {
755 0 : JS::Handle<JSObject*> parentProto(EventTargetBinding::GetProtoObjectHandle(aCx));
756 0 : if (!parentProto) {
757 0 : return;
758 : }
759 :
760 0 : JS::Handle<JSObject*> constructorProto(EventTargetBinding::GetConstructorObjectHandle(aCx));
761 0 : if (!constructorProto) {
762 0 : return;
763 : }
764 :
765 : static bool sIdsInited = false;
766 0 : if (!sIdsInited && NS_IsMainThread()) {
767 0 : if (!InitIds(aCx, sNativeProperties.Upcast())) {
768 0 : return;
769 : }
770 0 : sIdsInited = true;
771 : }
772 :
773 0 : JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::TCPServerSocket);
774 0 : JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::TCPServerSocket);
775 0 : dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
776 : &sPrototypeClass.mBase, protoCache,
777 : constructorProto, &sInterfaceObjectClass.mBase, 1, nullptr,
778 : interfaceCache,
779 : sNativeProperties.Upcast(),
780 : nullptr,
781 : "TCPServerSocket", aDefineOnGlobal,
782 : nullptr,
783 0 : false);
784 : }
785 :
786 : JS::Handle<JSObject*>
787 0 : GetProtoObjectHandle(JSContext* aCx)
788 : {
789 : /* Get the interface prototype object for this class. This will create the
790 : object as needed. */
791 0 : bool aDefineOnGlobal = true;
792 :
793 : /* Make sure our global is sane. Hopefully we can remove this sometime */
794 0 : JSObject* global = JS::CurrentGlobalOrNull(aCx);
795 0 : if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
796 0 : return nullptr;
797 : }
798 :
799 : /* Check to see whether the interface objects are already installed */
800 0 : ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
801 0 : if (!protoAndIfaceCache.HasEntryInSlot(prototypes::id::TCPServerSocket)) {
802 0 : JS::Rooted<JSObject*> rootedGlobal(aCx, global);
803 0 : CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
804 : }
805 :
806 : /*
807 : * The object might _still_ be null, but that's OK.
808 : *
809 : * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
810 : * traced by TraceProtoAndIfaceCache() and its contents are never
811 : * changed after they have been set.
812 : *
813 : * Calling address() avoids the read read barrier that does gray
814 : * unmarking, but it's not possible for the object to be gray here.
815 : */
816 :
817 0 : const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(prototypes::id::TCPServerSocket);
818 0 : MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
819 0 : return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
820 : }
821 :
822 : JS::Handle<JSObject*>
823 0 : GetConstructorObjectHandle(JSContext* aCx, bool aDefineOnGlobal)
824 : {
825 : /* Get the interface object for this class. This will create the object as
826 : needed. */
827 :
828 : /* Make sure our global is sane. Hopefully we can remove this sometime */
829 0 : JSObject* global = JS::CurrentGlobalOrNull(aCx);
830 0 : if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
831 0 : return nullptr;
832 : }
833 :
834 : /* Check to see whether the interface objects are already installed */
835 0 : ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
836 0 : if (!protoAndIfaceCache.HasEntryInSlot(constructors::id::TCPServerSocket)) {
837 0 : JS::Rooted<JSObject*> rootedGlobal(aCx, global);
838 0 : CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
839 : }
840 :
841 : /*
842 : * The object might _still_ be null, but that's OK.
843 : *
844 : * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
845 : * traced by TraceProtoAndIfaceCache() and its contents are never
846 : * changed after they have been set.
847 : *
848 : * Calling address() avoids the read read barrier that does gray
849 : * unmarking, but it's not possible for the object to be gray here.
850 : */
851 :
852 0 : const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(constructors::id::TCPServerSocket);
853 0 : MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
854 0 : return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
855 : }
856 :
857 : JSObject*
858 0 : GetConstructorObject(JSContext* aCx)
859 : {
860 0 : return GetConstructorObjectHandle(aCx);
861 : }
862 :
863 : } // namespace TCPServerSocketBinding
864 :
865 :
866 :
867 : } // namespace dom
868 : } // namespace mozilla
|