1/*
2 This file is part of the WebKit open source project.
3 This file has been generated by generate-bindings.pl. DO NOT MODIFY!
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public
7 License as published by the Free Software Foundation; either
8 version 2 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
14
15 You should have received a copy of the GNU Library General Public License
16 along with this library; see the file COPYING.LIB. If not, write to
17 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/
20
21#include "config.h"
22#include "JSWebSocket.h"
23
24#include "EventNames.h"
25#include "JSBlob.h"
26#include "JSDOMAttribute.h"
27#include "JSDOMBinding.h"
28#include "JSDOMConstructor.h"
29#include "JSDOMConvertBufferSource.h"
30#include "JSDOMConvertInterface.h"
31#include "JSDOMConvertNullable.h"
32#include "JSDOMConvertNumbers.h"
33#include "JSDOMConvertSequences.h"
34#include "JSDOMConvertStrings.h"
35#include "JSDOMExceptionHandling.h"
36#include "JSDOMOperation.h"
37#include "JSDOMWrapperCache.h"
38#include "JSEventListener.h"
39#include "ScriptExecutionContext.h"
40#include <JavaScriptCore/HeapSnapshotBuilder.h>
41#include <JavaScriptCore/IteratorOperations.h>
42#include <JavaScriptCore/JSArray.h>
43#include <JavaScriptCore/JSCInlines.h>
44#include <wtf/GetPtr.h>
45#include <wtf/PointerPreparations.h>
46#include <wtf/URL.h>
47
48
49namespace WebCore {
50using namespace JSC;
51
52// Functions
53
54JSC::EncodedJSValue JSC_HOST_CALL jsWebSocketPrototypeFunctionSend(JSC::ExecState*);
55JSC::EncodedJSValue JSC_HOST_CALL jsWebSocketPrototypeFunctionClose(JSC::ExecState*);
56
57// Attributes
58
59JSC::EncodedJSValue jsWebSocketConstructor(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
60bool setJSWebSocketConstructor(JSC::ExecState*, JSC::EncodedJSValue, JSC::EncodedJSValue);
61JSC::EncodedJSValue jsWebSocketURL(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
62JSC::EncodedJSValue jsWebSocketUrl(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
63JSC::EncodedJSValue jsWebSocketReadyState(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
64JSC::EncodedJSValue jsWebSocketBufferedAmount(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
65JSC::EncodedJSValue jsWebSocketOnopen(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
66bool setJSWebSocketOnopen(JSC::ExecState*, JSC::EncodedJSValue, JSC::EncodedJSValue);
67JSC::EncodedJSValue jsWebSocketOnmessage(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
68bool setJSWebSocketOnmessage(JSC::ExecState*, JSC::EncodedJSValue, JSC::EncodedJSValue);
69JSC::EncodedJSValue jsWebSocketOnerror(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
70bool setJSWebSocketOnerror(JSC::ExecState*, JSC::EncodedJSValue, JSC::EncodedJSValue);
71JSC::EncodedJSValue jsWebSocketOnclose(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
72bool setJSWebSocketOnclose(JSC::ExecState*, JSC::EncodedJSValue, JSC::EncodedJSValue);
73JSC::EncodedJSValue jsWebSocketProtocol(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
74JSC::EncodedJSValue jsWebSocketExtensions(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
75JSC::EncodedJSValue jsWebSocketBinaryType(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
76bool setJSWebSocketBinaryType(JSC::ExecState*, JSC::EncodedJSValue, JSC::EncodedJSValue);
77
78class JSWebSocketPrototype : public JSC::JSNonFinalObject {
79public:
80 using Base = JSC::JSNonFinalObject;
81 static JSWebSocketPrototype* create(JSC::VM& vm, JSDOMGlobalObject* globalObject, JSC::Structure* structure)
82 {
83 JSWebSocketPrototype* ptr = new (NotNull, JSC::allocateCell<JSWebSocketPrototype>(vm.heap)) JSWebSocketPrototype(vm, globalObject, structure);
84 ptr->finishCreation(vm);
85 return ptr;
86 }
87
88 DECLARE_INFO;
89 static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
90 {
91 return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info());
92 }
93
94private:
95 JSWebSocketPrototype(JSC::VM& vm, JSC::JSGlobalObject*, JSC::Structure* structure)
96 : JSC::JSNonFinalObject(vm, structure)
97 {
98 }
99
100 void finishCreation(JSC::VM&);
101};
102
103using JSWebSocketConstructor = JSDOMConstructor<JSWebSocket>;
104
105/* Hash table for constructor */
106
107static const HashTableValue JSWebSocketConstructorTableValues[] =
108{
109 { "CONNECTING", JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::ConstantInteger, NoIntrinsic, { (long long)(0) } },
110 { "OPEN", JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::ConstantInteger, NoIntrinsic, { (long long)(1) } },
111 { "CLOSING", JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::ConstantInteger, NoIntrinsic, { (long long)(2) } },
112 { "CLOSED", JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::ConstantInteger, NoIntrinsic, { (long long)(3) } },
113};
114
115static_assert(WebSocket::CONNECTING == 0, "CONNECTING in WebSocket does not match value from IDL");
116static_assert(WebSocket::OPEN == 1, "OPEN in WebSocket does not match value from IDL");
117static_assert(WebSocket::CLOSING == 2, "CLOSING in WebSocket does not match value from IDL");
118static_assert(WebSocket::CLOSED == 3, "CLOSED in WebSocket does not match value from IDL");
119
120static inline EncodedJSValue constructJSWebSocket1(ExecState* state)
121{
122 VM& vm = state->vm();
123 auto throwScope = DECLARE_THROW_SCOPE(vm);
124 UNUSED_PARAM(throwScope);
125 auto* castedThis = jsCast<JSWebSocketConstructor*>(state->jsCallee());
126 ASSERT(castedThis);
127 auto* context = castedThis->scriptExecutionContext();
128 if (UNLIKELY(!context))
129 return throwConstructorScriptExecutionContextUnavailableError(*state, throwScope, "WebSocket");
130 auto url = convert<IDLUSVString>(*state, state->uncheckedArgument(0));
131 RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
132 auto protocols = state->argument(1).isUndefined() ? Converter<IDLSequence<IDLDOMString>>::ReturnType{ } : convert<IDLSequence<IDLDOMString>>(*state, state->uncheckedArgument(1));
133 RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
134 auto object = WebSocket::create(*context, WTFMove(url), WTFMove(protocols));
135 return JSValue::encode(toJSNewlyCreated<IDLInterface<WebSocket>>(*state, *castedThis->globalObject(), throwScope, WTFMove(object)));
136}
137
138static inline EncodedJSValue constructJSWebSocket2(ExecState* state)
139{
140 VM& vm = state->vm();
141 auto throwScope = DECLARE_THROW_SCOPE(vm);
142 UNUSED_PARAM(throwScope);
143 auto* castedThis = jsCast<JSWebSocketConstructor*>(state->jsCallee());
144 ASSERT(castedThis);
145 auto* context = castedThis->scriptExecutionContext();
146 if (UNLIKELY(!context))
147 return throwConstructorScriptExecutionContextUnavailableError(*state, throwScope, "WebSocket");
148 auto url = convert<IDLUSVString>(*state, state->uncheckedArgument(0));
149 RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
150 auto protocol = convert<IDLDOMString>(*state, state->uncheckedArgument(1));
151 RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
152 auto object = WebSocket::create(*context, WTFMove(url), WTFMove(protocol));
153 return JSValue::encode(toJSNewlyCreated<IDLInterface<WebSocket>>(*state, *castedThis->globalObject(), throwScope, WTFMove(object)));
154}
155
156template<> EncodedJSValue JSC_HOST_CALL JSWebSocketConstructor::construct(ExecState* state)
157{
158 VM& vm = state->vm();
159 auto throwScope = DECLARE_THROW_SCOPE(vm);
160 UNUSED_PARAM(throwScope);
161 size_t argsCount = std::min<size_t>(2, state->argumentCount());
162 if (argsCount == 1) {
163 return constructJSWebSocket1(state);
164 }
165 if (argsCount == 2) {
166 JSValue distinguishingArg = state->uncheckedArgument(1);
167 if (distinguishingArg.isUndefined())
168 return constructJSWebSocket1(state);
169 if (hasIteratorMethod(*state, distinguishingArg))
170 return constructJSWebSocket1(state);
171 return constructJSWebSocket2(state);
172 }
173 return argsCount < 1 ? throwVMError(state, throwScope, createNotEnoughArgumentsError(state)) : throwVMTypeError(state, throwScope);
174}
175
176template<> JSValue JSWebSocketConstructor::prototypeForStructure(JSC::VM& vm, const JSDOMGlobalObject& globalObject)
177{
178 return JSEventTarget::getConstructor(vm, &globalObject);
179}
180
181template<> void JSWebSocketConstructor::initializeProperties(VM& vm, JSDOMGlobalObject& globalObject)
182{
183 putDirect(vm, vm.propertyNames->prototype, JSWebSocket::prototype(vm, globalObject), JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum);
184 putDirect(vm, vm.propertyNames->name, jsNontrivialString(&vm, String("WebSocket"_s)), JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum);
185 putDirect(vm, vm.propertyNames->length, jsNumber(1), JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum);
186 reifyStaticProperties(vm, JSWebSocket::info(), JSWebSocketConstructorTableValues, *this);
187}
188
189template<> const ClassInfo JSWebSocketConstructor::s_info = { "WebSocket", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSWebSocketConstructor) };
190
191/* Hash table for prototype */
192
193static const HashTableValue JSWebSocketPrototypeTableValues[] =
194{
195 { "constructor", static_cast<unsigned>(JSC::PropertyAttribute::DontEnum), NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsWebSocketConstructor), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(setJSWebSocketConstructor) } },
196 { "URL", static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsWebSocketURL), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
197 { "url", static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsWebSocketUrl), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
198 { "readyState", static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsWebSocketReadyState), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
199 { "bufferedAmount", static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsWebSocketBufferedAmount), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
200 { "onopen", static_cast<unsigned>(JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsWebSocketOnopen), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(setJSWebSocketOnopen) } },
201 { "onmessage", static_cast<unsigned>(JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsWebSocketOnmessage), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(setJSWebSocketOnmessage) } },
202 { "onerror", static_cast<unsigned>(JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsWebSocketOnerror), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(setJSWebSocketOnerror) } },
203 { "onclose", static_cast<unsigned>(JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsWebSocketOnclose), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(setJSWebSocketOnclose) } },
204 { "protocol", static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsWebSocketProtocol), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
205 { "extensions", static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsWebSocketExtensions), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
206 { "binaryType", static_cast<unsigned>(JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsWebSocketBinaryType), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(setJSWebSocketBinaryType) } },
207 { "send", static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t)static_cast<RawNativeFunction>(jsWebSocketPrototypeFunctionSend), (intptr_t) (1) } },
208 { "close", static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t)static_cast<RawNativeFunction>(jsWebSocketPrototypeFunctionClose), (intptr_t) (0) } },
209 { "CONNECTING", JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::ConstantInteger, NoIntrinsic, { (long long)(0) } },
210 { "OPEN", JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::ConstantInteger, NoIntrinsic, { (long long)(1) } },
211 { "CLOSING", JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::ConstantInteger, NoIntrinsic, { (long long)(2) } },
212 { "CLOSED", JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::ConstantInteger, NoIntrinsic, { (long long)(3) } },
213};
214
215const ClassInfo JSWebSocketPrototype::s_info = { "WebSocketPrototype", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSWebSocketPrototype) };
216
217void JSWebSocketPrototype::finishCreation(VM& vm)
218{
219 Base::finishCreation(vm);
220 reifyStaticProperties(vm, JSWebSocket::info(), JSWebSocketPrototypeTableValues, *this);
221}
222
223const ClassInfo JSWebSocket::s_info = { "WebSocket", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSWebSocket) };
224
225JSWebSocket::JSWebSocket(Structure* structure, JSDOMGlobalObject& globalObject, Ref<WebSocket>&& impl)
226 : JSEventTarget(structure, globalObject, WTFMove(impl))
227{
228}
229
230void JSWebSocket::finishCreation(VM& vm)
231{
232 Base::finishCreation(vm);
233 ASSERT(inherits(vm, info()));
234
235}
236
237JSObject* JSWebSocket::createPrototype(VM& vm, JSDOMGlobalObject& globalObject)
238{
239 return JSWebSocketPrototype::create(vm, &globalObject, JSWebSocketPrototype::createStructure(vm, &globalObject, JSEventTarget::prototype(vm, globalObject)));
240}
241
242JSObject* JSWebSocket::prototype(VM& vm, JSDOMGlobalObject& globalObject)
243{
244 return getDOMPrototype<JSWebSocket>(vm, globalObject);
245}
246
247JSValue JSWebSocket::getConstructor(VM& vm, const JSGlobalObject* globalObject)
248{
249 return getDOMConstructor<JSWebSocketConstructor>(vm, *jsCast<const JSDOMGlobalObject*>(globalObject));
250}
251
252template<> inline JSWebSocket* IDLAttribute<JSWebSocket>::cast(ExecState& state, EncodedJSValue thisValue)
253{
254 return jsDynamicCast<JSWebSocket*>(state.vm(), JSValue::decode(thisValue));
255}
256
257template<> inline JSWebSocket* IDLOperation<JSWebSocket>::cast(ExecState& state)
258{
259 return jsDynamicCast<JSWebSocket*>(state.vm(), state.thisValue());
260}
261
262EncodedJSValue jsWebSocketConstructor(ExecState* state, EncodedJSValue thisValue, PropertyName)
263{
264 VM& vm = state->vm();
265 auto throwScope = DECLARE_THROW_SCOPE(vm);
266 auto* prototype = jsDynamicCast<JSWebSocketPrototype*>(vm, JSValue::decode(thisValue));
267 if (UNLIKELY(!prototype))
268 return throwVMTypeError(state, throwScope);
269 return JSValue::encode(JSWebSocket::getConstructor(state->vm(), prototype->globalObject()));
270}
271
272bool setJSWebSocketConstructor(ExecState* state, EncodedJSValue thisValue, EncodedJSValue encodedValue)
273{
274 VM& vm = state->vm();
275 auto throwScope = DECLARE_THROW_SCOPE(vm);
276 auto* prototype = jsDynamicCast<JSWebSocketPrototype*>(vm, JSValue::decode(thisValue));
277 if (UNLIKELY(!prototype)) {
278 throwVMTypeError(state, throwScope);
279 return false;
280 }
281 // Shadowing a built-in constructor
282 return prototype->putDirect(vm, vm.propertyNames->constructor, JSValue::decode(encodedValue));
283}
284
285static inline JSValue jsWebSocketURLGetter(ExecState& state, JSWebSocket& thisObject, ThrowScope& throwScope)
286{
287 UNUSED_PARAM(throwScope);
288 UNUSED_PARAM(state);
289 auto& impl = thisObject.wrapped();
290 JSValue result = toJS<IDLUSVString>(state, throwScope, impl.url());
291 return result;
292}
293
294EncodedJSValue jsWebSocketURL(ExecState* state, EncodedJSValue thisValue, PropertyName)
295{
296 return IDLAttribute<JSWebSocket>::get<jsWebSocketURLGetter, CastedThisErrorBehavior::Assert>(*state, thisValue, "URL");
297}
298
299static inline JSValue jsWebSocketUrlGetter(ExecState& state, JSWebSocket& thisObject, ThrowScope& throwScope)
300{
301 UNUSED_PARAM(throwScope);
302 UNUSED_PARAM(state);
303 auto& impl = thisObject.wrapped();
304 JSValue result = toJS<IDLUSVString>(state, throwScope, impl.url());
305 return result;
306}
307
308EncodedJSValue jsWebSocketUrl(ExecState* state, EncodedJSValue thisValue, PropertyName)
309{
310 return IDLAttribute<JSWebSocket>::get<jsWebSocketUrlGetter, CastedThisErrorBehavior::Assert>(*state, thisValue, "url");
311}
312
313static inline JSValue jsWebSocketReadyStateGetter(ExecState& state, JSWebSocket& thisObject, ThrowScope& throwScope)
314{
315 UNUSED_PARAM(throwScope);
316 UNUSED_PARAM(state);
317 auto& impl = thisObject.wrapped();
318 JSValue result = toJS<IDLUnsignedShort>(state, throwScope, impl.readyState());
319 return result;
320}
321
322EncodedJSValue jsWebSocketReadyState(ExecState* state, EncodedJSValue thisValue, PropertyName)
323{
324 return IDLAttribute<JSWebSocket>::get<jsWebSocketReadyStateGetter, CastedThisErrorBehavior::Assert>(*state, thisValue, "readyState");
325}
326
327static inline JSValue jsWebSocketBufferedAmountGetter(ExecState& state, JSWebSocket& thisObject, ThrowScope& throwScope)
328{
329 UNUSED_PARAM(throwScope);
330 UNUSED_PARAM(state);
331 auto& impl = thisObject.wrapped();
332 JSValue result = toJS<IDLUnsignedLong>(state, throwScope, impl.bufferedAmount());
333 return result;
334}
335
336EncodedJSValue jsWebSocketBufferedAmount(ExecState* state, EncodedJSValue thisValue, PropertyName)
337{
338 return IDLAttribute<JSWebSocket>::get<jsWebSocketBufferedAmountGetter, CastedThisErrorBehavior::Assert>(*state, thisValue, "bufferedAmount");
339}
340
341static inline JSValue jsWebSocketOnopenGetter(ExecState& state, JSWebSocket& thisObject, ThrowScope& throwScope)
342{
343 UNUSED_PARAM(throwScope);
344 UNUSED_PARAM(state);
345 return eventHandlerAttribute(thisObject.wrapped(), eventNames().openEvent, worldForDOMObject(thisObject));
346}
347
348EncodedJSValue jsWebSocketOnopen(ExecState* state, EncodedJSValue thisValue, PropertyName)
349{
350 return IDLAttribute<JSWebSocket>::get<jsWebSocketOnopenGetter, CastedThisErrorBehavior::Assert>(*state, thisValue, "onopen");
351}
352
353static inline bool setJSWebSocketOnopenSetter(ExecState& state, JSWebSocket& thisObject, JSValue value, ThrowScope& throwScope)
354{
355 UNUSED_PARAM(throwScope);
356 setEventHandlerAttribute(state, thisObject, thisObject.wrapped(), eventNames().openEvent, value);
357 return true;
358}
359
360bool setJSWebSocketOnopen(ExecState* state, EncodedJSValue thisValue, EncodedJSValue encodedValue)
361{
362 return IDLAttribute<JSWebSocket>::set<setJSWebSocketOnopenSetter>(*state, thisValue, encodedValue, "onopen");
363}
364
365static inline JSValue jsWebSocketOnmessageGetter(ExecState& state, JSWebSocket& thisObject, ThrowScope& throwScope)
366{
367 UNUSED_PARAM(throwScope);
368 UNUSED_PARAM(state);
369 return eventHandlerAttribute(thisObject.wrapped(), eventNames().messageEvent, worldForDOMObject(thisObject));
370}
371
372EncodedJSValue jsWebSocketOnmessage(ExecState* state, EncodedJSValue thisValue, PropertyName)
373{
374 return IDLAttribute<JSWebSocket>::get<jsWebSocketOnmessageGetter, CastedThisErrorBehavior::Assert>(*state, thisValue, "onmessage");
375}
376
377static inline bool setJSWebSocketOnmessageSetter(ExecState& state, JSWebSocket& thisObject, JSValue value, ThrowScope& throwScope)
378{
379 UNUSED_PARAM(throwScope);
380 setEventHandlerAttribute(state, thisObject, thisObject.wrapped(), eventNames().messageEvent, value);
381 return true;
382}
383
384bool setJSWebSocketOnmessage(ExecState* state, EncodedJSValue thisValue, EncodedJSValue encodedValue)
385{
386 return IDLAttribute<JSWebSocket>::set<setJSWebSocketOnmessageSetter>(*state, thisValue, encodedValue, "onmessage");
387}
388
389static inline JSValue jsWebSocketOnerrorGetter(ExecState& state, JSWebSocket& thisObject, ThrowScope& throwScope)
390{
391 UNUSED_PARAM(throwScope);
392 UNUSED_PARAM(state);
393 return eventHandlerAttribute(thisObject.wrapped(), eventNames().errorEvent, worldForDOMObject(thisObject));
394}
395
396EncodedJSValue jsWebSocketOnerror(ExecState* state, EncodedJSValue thisValue, PropertyName)
397{
398 return IDLAttribute<JSWebSocket>::get<jsWebSocketOnerrorGetter, CastedThisErrorBehavior::Assert>(*state, thisValue, "onerror");
399}
400
401static inline bool setJSWebSocketOnerrorSetter(ExecState& state, JSWebSocket& thisObject, JSValue value, ThrowScope& throwScope)
402{
403 UNUSED_PARAM(throwScope);
404 setEventHandlerAttribute(state, thisObject, thisObject.wrapped(), eventNames().errorEvent, value);
405 return true;
406}
407
408bool setJSWebSocketOnerror(ExecState* state, EncodedJSValue thisValue, EncodedJSValue encodedValue)
409{
410 return IDLAttribute<JSWebSocket>::set<setJSWebSocketOnerrorSetter>(*state, thisValue, encodedValue, "onerror");
411}
412
413static inline JSValue jsWebSocketOncloseGetter(ExecState& state, JSWebSocket& thisObject, ThrowScope& throwScope)
414{
415 UNUSED_PARAM(throwScope);
416 UNUSED_PARAM(state);
417 return eventHandlerAttribute(thisObject.wrapped(), eventNames().closeEvent, worldForDOMObject(thisObject));
418}
419
420EncodedJSValue jsWebSocketOnclose(ExecState* state, EncodedJSValue thisValue, PropertyName)
421{
422 return IDLAttribute<JSWebSocket>::get<jsWebSocketOncloseGetter, CastedThisErrorBehavior::Assert>(*state, thisValue, "onclose");
423}
424
425static inline bool setJSWebSocketOncloseSetter(ExecState& state, JSWebSocket& thisObject, JSValue value, ThrowScope& throwScope)
426{
427 UNUSED_PARAM(throwScope);
428 setEventHandlerAttribute(state, thisObject, thisObject.wrapped(), eventNames().closeEvent, value);
429 return true;
430}
431
432bool setJSWebSocketOnclose(ExecState* state, EncodedJSValue thisValue, EncodedJSValue encodedValue)
433{
434 return IDLAttribute<JSWebSocket>::set<setJSWebSocketOncloseSetter>(*state, thisValue, encodedValue, "onclose");
435}
436
437static inline JSValue jsWebSocketProtocolGetter(ExecState& state, JSWebSocket& thisObject, ThrowScope& throwScope)
438{
439 UNUSED_PARAM(throwScope);
440 UNUSED_PARAM(state);
441 auto& impl = thisObject.wrapped();
442 JSValue result = toJS<IDLNullable<IDLDOMString>>(state, throwScope, impl.protocol());
443 return result;
444}
445
446EncodedJSValue jsWebSocketProtocol(ExecState* state, EncodedJSValue thisValue, PropertyName)
447{
448 return IDLAttribute<JSWebSocket>::get<jsWebSocketProtocolGetter, CastedThisErrorBehavior::Assert>(*state, thisValue, "protocol");
449}
450
451static inline JSValue jsWebSocketExtensionsGetter(ExecState& state, JSWebSocket& thisObject, ThrowScope& throwScope)
452{
453 UNUSED_PARAM(throwScope);
454 UNUSED_PARAM(state);
455 auto& impl = thisObject.wrapped();
456 JSValue result = toJS<IDLNullable<IDLDOMString>>(state, throwScope, impl.extensions());
457 return result;
458}
459
460EncodedJSValue jsWebSocketExtensions(ExecState* state, EncodedJSValue thisValue, PropertyName)
461{
462 return IDLAttribute<JSWebSocket>::get<jsWebSocketExtensionsGetter, CastedThisErrorBehavior::Assert>(*state, thisValue, "extensions");
463}
464
465static inline JSValue jsWebSocketBinaryTypeGetter(ExecState& state, JSWebSocket& thisObject, ThrowScope& throwScope)
466{
467 UNUSED_PARAM(throwScope);
468 UNUSED_PARAM(state);
469 auto& impl = thisObject.wrapped();
470 JSValue result = toJS<IDLDOMString>(state, throwScope, impl.binaryType());
471 return result;
472}
473
474EncodedJSValue jsWebSocketBinaryType(ExecState* state, EncodedJSValue thisValue, PropertyName)
475{
476 return IDLAttribute<JSWebSocket>::get<jsWebSocketBinaryTypeGetter, CastedThisErrorBehavior::Assert>(*state, thisValue, "binaryType");
477}
478
479static inline bool setJSWebSocketBinaryTypeSetter(ExecState& state, JSWebSocket& thisObject, JSValue value, ThrowScope& throwScope)
480{
481 UNUSED_PARAM(throwScope);
482 auto& impl = thisObject.wrapped();
483 auto nativeValue = convert<IDLDOMString>(state, value);
484 RETURN_IF_EXCEPTION(throwScope, false);
485 AttributeSetter::call(state, throwScope, [&] {
486 return impl.setBinaryType(WTFMove(nativeValue));
487 });
488 return true;
489}
490
491bool setJSWebSocketBinaryType(ExecState* state, EncodedJSValue thisValue, EncodedJSValue encodedValue)
492{
493 return IDLAttribute<JSWebSocket>::set<setJSWebSocketBinaryTypeSetter>(*state, thisValue, encodedValue, "binaryType");
494}
495
496static inline JSC::EncodedJSValue jsWebSocketPrototypeFunctionSend1Body(JSC::ExecState* state, typename IDLOperation<JSWebSocket>::ClassParameter castedThis, JSC::ThrowScope& throwScope)
497{
498 UNUSED_PARAM(state);
499 UNUSED_PARAM(throwScope);
500 auto& impl = castedThis->wrapped();
501 auto data = convert<IDLArrayBuffer>(*state, state->uncheckedArgument(0), [](JSC::ExecState& state, JSC::ThrowScope& scope) { throwArgumentTypeError(state, scope, 0, "data", "WebSocket", "send", "ArrayBuffer"); });
502 RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
503 propagateException(*state, throwScope, impl.send(*data));
504 return JSValue::encode(jsUndefined());
505}
506
507static inline JSC::EncodedJSValue jsWebSocketPrototypeFunctionSend2Body(JSC::ExecState* state, typename IDLOperation<JSWebSocket>::ClassParameter castedThis, JSC::ThrowScope& throwScope)
508{
509 UNUSED_PARAM(state);
510 UNUSED_PARAM(throwScope);
511 auto& impl = castedThis->wrapped();
512 auto data = convert<IDLArrayBufferView>(*state, state->uncheckedArgument(0), [](JSC::ExecState& state, JSC::ThrowScope& scope) { throwArgumentTypeError(state, scope, 0, "data", "WebSocket", "send", "ArrayBufferView"); });
513 RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
514 propagateException(*state, throwScope, impl.send(data.releaseNonNull()));
515 return JSValue::encode(jsUndefined());
516}
517
518static inline JSC::EncodedJSValue jsWebSocketPrototypeFunctionSend3Body(JSC::ExecState* state, typename IDLOperation<JSWebSocket>::ClassParameter castedThis, JSC::ThrowScope& throwScope)
519{
520 UNUSED_PARAM(state);
521 UNUSED_PARAM(throwScope);
522 auto& impl = castedThis->wrapped();
523 auto data = convert<IDLInterface<Blob>>(*state, state->uncheckedArgument(0), [](JSC::ExecState& state, JSC::ThrowScope& scope) { throwArgumentTypeError(state, scope, 0, "data", "WebSocket", "send", "Blob"); });
524 RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
525 propagateException(*state, throwScope, impl.send(*data));
526 return JSValue::encode(jsUndefined());
527}
528
529static inline JSC::EncodedJSValue jsWebSocketPrototypeFunctionSend4Body(JSC::ExecState* state, typename IDLOperation<JSWebSocket>::ClassParameter castedThis, JSC::ThrowScope& throwScope)
530{
531 UNUSED_PARAM(state);
532 UNUSED_PARAM(throwScope);
533 auto& impl = castedThis->wrapped();
534 auto data = convert<IDLUSVString>(*state, state->uncheckedArgument(0));
535 RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
536 propagateException(*state, throwScope, impl.send(WTFMove(data)));
537 return JSValue::encode(jsUndefined());
538}
539
540static inline JSC::EncodedJSValue jsWebSocketPrototypeFunctionSendOverloadDispatcher(JSC::ExecState* state, typename IDLOperation<JSWebSocket>::ClassParameter castedThis, JSC::ThrowScope& throwScope)
541{
542 UNUSED_PARAM(state);
543 UNUSED_PARAM(throwScope);
544 VM& vm = state->vm();
545 UNUSED_PARAM(vm);
546 size_t argsCount = std::min<size_t>(1, state->argumentCount());
547 if (argsCount == 1) {
548 JSValue distinguishingArg = state->uncheckedArgument(0);
549 if (distinguishingArg.isObject() && asObject(distinguishingArg)->inherits<JSArrayBuffer>(vm))
550 return jsWebSocketPrototypeFunctionSend1Body(state, castedThis, throwScope);
551 if (distinguishingArg.isObject() && asObject(distinguishingArg)->inherits<JSArrayBufferView>(vm))
552 return jsWebSocketPrototypeFunctionSend2Body(state, castedThis, throwScope);
553 if (distinguishingArg.isObject() && asObject(distinguishingArg)->inherits<JSBlob>(vm))
554 return jsWebSocketPrototypeFunctionSend3Body(state, castedThis, throwScope);
555 return jsWebSocketPrototypeFunctionSend4Body(state, castedThis, throwScope);
556 }
557 return argsCount < 1 ? throwVMError(state, throwScope, createNotEnoughArgumentsError(state)) : throwVMTypeError(state, throwScope);
558}
559
560EncodedJSValue JSC_HOST_CALL jsWebSocketPrototypeFunctionSend(ExecState* state)
561{
562 return IDLOperation<JSWebSocket>::call<jsWebSocketPrototypeFunctionSendOverloadDispatcher>(*state, "send");
563}
564
565static inline JSC::EncodedJSValue jsWebSocketPrototypeFunctionCloseBody(JSC::ExecState* state, typename IDLOperation<JSWebSocket>::ClassParameter castedThis, JSC::ThrowScope& throwScope)
566{
567 UNUSED_PARAM(state);
568 UNUSED_PARAM(throwScope);
569 auto& impl = castedThis->wrapped();
570 auto code = state->argument(0).isUndefined() ? Optional<Converter<IDLClampAdaptor<IDLUnsignedShort>>::ReturnType>() : Optional<Converter<IDLClampAdaptor<IDLUnsignedShort>>::ReturnType>(convert<IDLClampAdaptor<IDLUnsignedShort>>(*state, state->uncheckedArgument(0)));
571 RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
572 auto reason = state->argument(1).isUndefined() ? String() : convert<IDLDOMString>(*state, state->uncheckedArgument(1));
573 RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
574 propagateException(*state, throwScope, impl.close(WTFMove(code), WTFMove(reason)));
575 return JSValue::encode(jsUndefined());
576}
577
578EncodedJSValue JSC_HOST_CALL jsWebSocketPrototypeFunctionClose(ExecState* state)
579{
580 return IDLOperation<JSWebSocket>::call<jsWebSocketPrototypeFunctionCloseBody>(*state, "close");
581}
582
583void JSWebSocket::heapSnapshot(JSCell* cell, HeapSnapshotBuilder& builder)
584{
585 auto* thisObject = jsCast<JSWebSocket*>(cell);
586 builder.setWrappedObjectForCell(cell, &thisObject->wrapped());
587 if (thisObject->scriptExecutionContext())
588 builder.setLabelForCell(cell, "url " + thisObject->scriptExecutionContext()->url().string());
589 Base::heapSnapshot(cell, builder);
590}
591
592bool JSWebSocketOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor, const char** reason)
593{
594 auto* jsWebSocket = jsCast<JSWebSocket*>(handle.slot()->asCell());
595 if (jsWebSocket->wrapped().hasPendingActivity()) {
596 if (UNLIKELY(reason))
597 *reason = "ActiveDOMObject with pending activity";
598 return true;
599 }
600 if (jsWebSocket->wrapped().isFiringEventListeners()) {
601 if (UNLIKELY(reason))
602 *reason = "EventTarget firing event listeners";
603 return true;
604 }
605 UNUSED_PARAM(visitor);
606 UNUSED_PARAM(reason);
607 return false;
608}
609
610void JSWebSocketOwner::finalize(JSC::Handle<JSC::Unknown> handle, void* context)
611{
612 auto* jsWebSocket = static_cast<JSWebSocket*>(handle.slot()->asCell());
613 auto& world = *static_cast<DOMWrapperWorld*>(context);
614 uncacheWrapper(world, &jsWebSocket->wrapped(), jsWebSocket);
615}
616
617#if ENABLE(BINDING_INTEGRITY)
618#if PLATFORM(WIN)
619#pragma warning(disable: 4483)
620extern "C" { extern void (*const __identifier("??_7WebSocket@WebCore@@6B@")[])(); }
621#else
622extern "C" { extern void* _ZTVN7WebCore9WebSocketE[]; }
623#endif
624#endif
625
626JSC::JSValue toJSNewlyCreated(JSC::ExecState*, JSDOMGlobalObject* globalObject, Ref<WebSocket>&& impl)
627{
628
629#if ENABLE(BINDING_INTEGRITY)
630 void* actualVTablePointer = *(reinterpret_cast<void**>(impl.ptr()));
631#if PLATFORM(WIN)
632 void* expectedVTablePointer = WTF_PREPARE_VTBL_POINTER_FOR_INSPECTION(__identifier("??_7WebSocket@WebCore@@6B@"));
633#else
634 void* expectedVTablePointer = WTF_PREPARE_VTBL_POINTER_FOR_INSPECTION(&_ZTVN7WebCore9WebSocketE[2]);
635#endif
636
637 // If this fails WebSocket does not have a vtable, so you need to add the
638 // ImplementationLacksVTable attribute to the interface definition
639 static_assert(std::is_polymorphic<WebSocket>::value, "WebSocket is not polymorphic");
640
641 // If you hit this assertion you either have a use after free bug, or
642 // WebSocket has subclasses. If WebSocket has subclasses that get passed
643 // to toJS() we currently require WebSocket you to opt out of binding hardening
644 // by adding the SkipVTableValidation attribute to the interface IDL definition
645 RELEASE_ASSERT(actualVTablePointer == expectedVTablePointer);
646#endif
647 return createWrapper<WebSocket>(globalObject, WTFMove(impl));
648}
649
650JSC::JSValue toJS(JSC::ExecState* state, JSDOMGlobalObject* globalObject, WebSocket& impl)
651{
652 return wrap(state, globalObject, impl);
653}
654
655WebSocket* JSWebSocket::toWrapped(JSC::VM& vm, JSC::JSValue value)
656{
657 if (auto* wrapper = jsDynamicCast<JSWebSocket*>(vm, value))
658 return &wrapper->wrapped();
659 return nullptr;
660}
661
662}
663