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
23#if ENABLE(SERVICE_WORKER)
24
25#include "JSServiceWorker.h"
26
27#include "EventNames.h"
28#include "JSDOMAttribute.h"
29#include "JSDOMBinding.h"
30#include "JSDOMConstructorNotConstructable.h"
31#include "JSDOMConvertAny.h"
32#include "JSDOMConvertObject.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/JSArray.h>
42#include <JavaScriptCore/JSCInlines.h>
43#include <JavaScriptCore/JSString.h>
44#include <wtf/GetPtr.h>
45#include <wtf/PointerPreparations.h>
46#include <wtf/URL.h>
47
48
49namespace WebCore {
50using namespace JSC;
51
52String convertEnumerationToString(ServiceWorker::State enumerationValue)
53{
54 static const NeverDestroyed<String> values[] = {
55 MAKE_STATIC_STRING_IMPL("installing"),
56 MAKE_STATIC_STRING_IMPL("installed"),
57 MAKE_STATIC_STRING_IMPL("activating"),
58 MAKE_STATIC_STRING_IMPL("activated"),
59 MAKE_STATIC_STRING_IMPL("redundant"),
60 };
61 static_assert(static_cast<size_t>(ServiceWorker::State::Installing) == 0, "ServiceWorker::State::Installing is not 0 as expected");
62 static_assert(static_cast<size_t>(ServiceWorker::State::Installed) == 1, "ServiceWorker::State::Installed is not 1 as expected");
63 static_assert(static_cast<size_t>(ServiceWorker::State::Activating) == 2, "ServiceWorker::State::Activating is not 2 as expected");
64 static_assert(static_cast<size_t>(ServiceWorker::State::Activated) == 3, "ServiceWorker::State::Activated is not 3 as expected");
65 static_assert(static_cast<size_t>(ServiceWorker::State::Redundant) == 4, "ServiceWorker::State::Redundant is not 4 as expected");
66 ASSERT(static_cast<size_t>(enumerationValue) < WTF_ARRAY_LENGTH(values));
67 return values[static_cast<size_t>(enumerationValue)];
68}
69
70template<> JSString* convertEnumerationToJS(ExecState& state, ServiceWorker::State enumerationValue)
71{
72 return jsStringWithCache(&state, convertEnumerationToString(enumerationValue));
73}
74
75template<> Optional<ServiceWorker::State> parseEnumeration<ServiceWorker::State>(ExecState& state, JSValue value)
76{
77 auto stringValue = value.toWTFString(&state);
78 if (stringValue == "installing")
79 return ServiceWorker::State::Installing;
80 if (stringValue == "installed")
81 return ServiceWorker::State::Installed;
82 if (stringValue == "activating")
83 return ServiceWorker::State::Activating;
84 if (stringValue == "activated")
85 return ServiceWorker::State::Activated;
86 if (stringValue == "redundant")
87 return ServiceWorker::State::Redundant;
88 return WTF::nullopt;
89}
90
91template<> const char* expectedEnumerationValues<ServiceWorker::State>()
92{
93 return "\"installing\", \"installed\", \"activating\", \"activated\", \"redundant\"";
94}
95
96// Functions
97
98JSC::EncodedJSValue JSC_HOST_CALL jsServiceWorkerPrototypeFunctionPostMessage(JSC::ExecState*);
99
100// Attributes
101
102JSC::EncodedJSValue jsServiceWorkerConstructor(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
103bool setJSServiceWorkerConstructor(JSC::ExecState*, JSC::EncodedJSValue, JSC::EncodedJSValue);
104JSC::EncodedJSValue jsServiceWorkerScriptURL(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
105JSC::EncodedJSValue jsServiceWorkerState(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
106JSC::EncodedJSValue jsServiceWorkerOnstatechange(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
107bool setJSServiceWorkerOnstatechange(JSC::ExecState*, JSC::EncodedJSValue, JSC::EncodedJSValue);
108JSC::EncodedJSValue jsServiceWorkerOnerror(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
109bool setJSServiceWorkerOnerror(JSC::ExecState*, JSC::EncodedJSValue, JSC::EncodedJSValue);
110
111class JSServiceWorkerPrototype : public JSC::JSNonFinalObject {
112public:
113 using Base = JSC::JSNonFinalObject;
114 static JSServiceWorkerPrototype* create(JSC::VM& vm, JSDOMGlobalObject* globalObject, JSC::Structure* structure)
115 {
116 JSServiceWorkerPrototype* ptr = new (NotNull, JSC::allocateCell<JSServiceWorkerPrototype>(vm.heap)) JSServiceWorkerPrototype(vm, globalObject, structure);
117 ptr->finishCreation(vm);
118 return ptr;
119 }
120
121 DECLARE_INFO;
122 static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
123 {
124 return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info());
125 }
126
127private:
128 JSServiceWorkerPrototype(JSC::VM& vm, JSC::JSGlobalObject*, JSC::Structure* structure)
129 : JSC::JSNonFinalObject(vm, structure)
130 {
131 }
132
133 void finishCreation(JSC::VM&);
134};
135
136using JSServiceWorkerConstructor = JSDOMConstructorNotConstructable<JSServiceWorker>;
137
138template<> JSValue JSServiceWorkerConstructor::prototypeForStructure(JSC::VM& vm, const JSDOMGlobalObject& globalObject)
139{
140 return JSEventTarget::getConstructor(vm, &globalObject);
141}
142
143template<> void JSServiceWorkerConstructor::initializeProperties(VM& vm, JSDOMGlobalObject& globalObject)
144{
145 putDirect(vm, vm.propertyNames->prototype, JSServiceWorker::prototype(vm, globalObject), JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum);
146 putDirect(vm, vm.propertyNames->name, jsNontrivialString(&vm, String("ServiceWorker"_s)), JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum);
147 putDirect(vm, vm.propertyNames->length, jsNumber(0), JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum);
148}
149
150template<> const ClassInfo JSServiceWorkerConstructor::s_info = { "ServiceWorker", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSServiceWorkerConstructor) };
151
152/* Hash table for prototype */
153
154static const HashTableValue JSServiceWorkerPrototypeTableValues[] =
155{
156 { "constructor", static_cast<unsigned>(JSC::PropertyAttribute::DontEnum), NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsServiceWorkerConstructor), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(setJSServiceWorkerConstructor) } },
157 { "scriptURL", static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsServiceWorkerScriptURL), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
158 { "state", static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsServiceWorkerState), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
159 { "onstatechange", static_cast<unsigned>(JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsServiceWorkerOnstatechange), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(setJSServiceWorkerOnstatechange) } },
160 { "onerror", static_cast<unsigned>(JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsServiceWorkerOnerror), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(setJSServiceWorkerOnerror) } },
161 { "postMessage", static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t)static_cast<RawNativeFunction>(jsServiceWorkerPrototypeFunctionPostMessage), (intptr_t) (1) } },
162};
163
164const ClassInfo JSServiceWorkerPrototype::s_info = { "ServiceWorkerPrototype", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSServiceWorkerPrototype) };
165
166void JSServiceWorkerPrototype::finishCreation(VM& vm)
167{
168 Base::finishCreation(vm);
169 reifyStaticProperties(vm, JSServiceWorker::info(), JSServiceWorkerPrototypeTableValues, *this);
170}
171
172const ClassInfo JSServiceWorker::s_info = { "ServiceWorker", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSServiceWorker) };
173
174JSServiceWorker::JSServiceWorker(Structure* structure, JSDOMGlobalObject& globalObject, Ref<ServiceWorker>&& impl)
175 : JSEventTarget(structure, globalObject, WTFMove(impl))
176{
177}
178
179void JSServiceWorker::finishCreation(VM& vm)
180{
181 Base::finishCreation(vm);
182 ASSERT(inherits(vm, info()));
183
184}
185
186JSObject* JSServiceWorker::createPrototype(VM& vm, JSDOMGlobalObject& globalObject)
187{
188 return JSServiceWorkerPrototype::create(vm, &globalObject, JSServiceWorkerPrototype::createStructure(vm, &globalObject, JSEventTarget::prototype(vm, globalObject)));
189}
190
191JSObject* JSServiceWorker::prototype(VM& vm, JSDOMGlobalObject& globalObject)
192{
193 return getDOMPrototype<JSServiceWorker>(vm, globalObject);
194}
195
196JSValue JSServiceWorker::getConstructor(VM& vm, const JSGlobalObject* globalObject)
197{
198 return getDOMConstructor<JSServiceWorkerConstructor>(vm, *jsCast<const JSDOMGlobalObject*>(globalObject));
199}
200
201template<> inline JSServiceWorker* IDLAttribute<JSServiceWorker>::cast(ExecState& state, EncodedJSValue thisValue)
202{
203 return jsDynamicCast<JSServiceWorker*>(state.vm(), JSValue::decode(thisValue));
204}
205
206template<> inline JSServiceWorker* IDLOperation<JSServiceWorker>::cast(ExecState& state)
207{
208 return jsDynamicCast<JSServiceWorker*>(state.vm(), state.thisValue());
209}
210
211EncodedJSValue jsServiceWorkerConstructor(ExecState* state, EncodedJSValue thisValue, PropertyName)
212{
213 VM& vm = state->vm();
214 auto throwScope = DECLARE_THROW_SCOPE(vm);
215 auto* prototype = jsDynamicCast<JSServiceWorkerPrototype*>(vm, JSValue::decode(thisValue));
216 if (UNLIKELY(!prototype))
217 return throwVMTypeError(state, throwScope);
218 return JSValue::encode(JSServiceWorker::getConstructor(state->vm(), prototype->globalObject()));
219}
220
221bool setJSServiceWorkerConstructor(ExecState* state, EncodedJSValue thisValue, EncodedJSValue encodedValue)
222{
223 VM& vm = state->vm();
224 auto throwScope = DECLARE_THROW_SCOPE(vm);
225 auto* prototype = jsDynamicCast<JSServiceWorkerPrototype*>(vm, JSValue::decode(thisValue));
226 if (UNLIKELY(!prototype)) {
227 throwVMTypeError(state, throwScope);
228 return false;
229 }
230 // Shadowing a built-in constructor
231 return prototype->putDirect(vm, vm.propertyNames->constructor, JSValue::decode(encodedValue));
232}
233
234static inline JSValue jsServiceWorkerScriptURLGetter(ExecState& state, JSServiceWorker& thisObject, ThrowScope& throwScope)
235{
236 UNUSED_PARAM(throwScope);
237 UNUSED_PARAM(state);
238 auto& impl = thisObject.wrapped();
239 JSValue result = toJS<IDLUSVString>(state, throwScope, impl.scriptURL());
240 return result;
241}
242
243EncodedJSValue jsServiceWorkerScriptURL(ExecState* state, EncodedJSValue thisValue, PropertyName)
244{
245 return IDLAttribute<JSServiceWorker>::get<jsServiceWorkerScriptURLGetter, CastedThisErrorBehavior::Assert>(*state, thisValue, "scriptURL");
246}
247
248static inline JSValue jsServiceWorkerStateGetter(ExecState& state, JSServiceWorker& thisObject, ThrowScope& throwScope)
249{
250 UNUSED_PARAM(throwScope);
251 UNUSED_PARAM(state);
252 auto& impl = thisObject.wrapped();
253 JSValue result = toJS<IDLEnumeration<ServiceWorker::State>>(state, throwScope, impl.state());
254 return result;
255}
256
257EncodedJSValue jsServiceWorkerState(ExecState* state, EncodedJSValue thisValue, PropertyName)
258{
259 return IDLAttribute<JSServiceWorker>::get<jsServiceWorkerStateGetter, CastedThisErrorBehavior::Assert>(*state, thisValue, "state");
260}
261
262static inline JSValue jsServiceWorkerOnstatechangeGetter(ExecState& state, JSServiceWorker& thisObject, ThrowScope& throwScope)
263{
264 UNUSED_PARAM(throwScope);
265 UNUSED_PARAM(state);
266 return eventHandlerAttribute(thisObject.wrapped(), eventNames().statechangeEvent, worldForDOMObject(thisObject));
267}
268
269EncodedJSValue jsServiceWorkerOnstatechange(ExecState* state, EncodedJSValue thisValue, PropertyName)
270{
271 return IDLAttribute<JSServiceWorker>::get<jsServiceWorkerOnstatechangeGetter, CastedThisErrorBehavior::Assert>(*state, thisValue, "onstatechange");
272}
273
274static inline bool setJSServiceWorkerOnstatechangeSetter(ExecState& state, JSServiceWorker& thisObject, JSValue value, ThrowScope& throwScope)
275{
276 UNUSED_PARAM(throwScope);
277 setEventHandlerAttribute(state, thisObject, thisObject.wrapped(), eventNames().statechangeEvent, value);
278 return true;
279}
280
281bool setJSServiceWorkerOnstatechange(ExecState* state, EncodedJSValue thisValue, EncodedJSValue encodedValue)
282{
283 return IDLAttribute<JSServiceWorker>::set<setJSServiceWorkerOnstatechangeSetter>(*state, thisValue, encodedValue, "onstatechange");
284}
285
286static inline JSValue jsServiceWorkerOnerrorGetter(ExecState& state, JSServiceWorker& thisObject, ThrowScope& throwScope)
287{
288 UNUSED_PARAM(throwScope);
289 UNUSED_PARAM(state);
290 return eventHandlerAttribute(thisObject.wrapped(), eventNames().errorEvent, worldForDOMObject(thisObject));
291}
292
293EncodedJSValue jsServiceWorkerOnerror(ExecState* state, EncodedJSValue thisValue, PropertyName)
294{
295 return IDLAttribute<JSServiceWorker>::get<jsServiceWorkerOnerrorGetter, CastedThisErrorBehavior::Assert>(*state, thisValue, "onerror");
296}
297
298static inline bool setJSServiceWorkerOnerrorSetter(ExecState& state, JSServiceWorker& thisObject, JSValue value, ThrowScope& throwScope)
299{
300 UNUSED_PARAM(throwScope);
301 setEventHandlerAttribute(state, thisObject, thisObject.wrapped(), eventNames().errorEvent, value);
302 return true;
303}
304
305bool setJSServiceWorkerOnerror(ExecState* state, EncodedJSValue thisValue, EncodedJSValue encodedValue)
306{
307 return IDLAttribute<JSServiceWorker>::set<setJSServiceWorkerOnerrorSetter>(*state, thisValue, encodedValue, "onerror");
308}
309
310static inline JSC::EncodedJSValue jsServiceWorkerPrototypeFunctionPostMessageBody(JSC::ExecState* state, typename IDLOperation<JSServiceWorker>::ClassParameter castedThis, JSC::ThrowScope& throwScope)
311{
312 UNUSED_PARAM(state);
313 UNUSED_PARAM(throwScope);
314 auto& impl = castedThis->wrapped();
315 if (UNLIKELY(state->argumentCount() < 1))
316 return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
317 auto* context = jsCast<JSDOMGlobalObject*>(state->lexicalGlobalObject())->scriptExecutionContext();
318 if (UNLIKELY(!context))
319 return JSValue::encode(jsUndefined());
320 auto message = convert<IDLAny>(*state, state->uncheckedArgument(0));
321 RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
322 auto transfer = state->argument(1).isUndefined() ? Converter<IDLSequence<IDLObject>>::ReturnType{ } : convert<IDLSequence<IDLObject>>(*state, state->uncheckedArgument(1));
323 RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
324 propagateException(*state, throwScope, impl.postMessage(*context, WTFMove(message), WTFMove(transfer)));
325 return JSValue::encode(jsUndefined());
326}
327
328EncodedJSValue JSC_HOST_CALL jsServiceWorkerPrototypeFunctionPostMessage(ExecState* state)
329{
330 return IDLOperation<JSServiceWorker>::call<jsServiceWorkerPrototypeFunctionPostMessageBody>(*state, "postMessage");
331}
332
333void JSServiceWorker::heapSnapshot(JSCell* cell, HeapSnapshotBuilder& builder)
334{
335 auto* thisObject = jsCast<JSServiceWorker*>(cell);
336 builder.setWrappedObjectForCell(cell, &thisObject->wrapped());
337 if (thisObject->scriptExecutionContext())
338 builder.setLabelForCell(cell, "url " + thisObject->scriptExecutionContext()->url().string());
339 Base::heapSnapshot(cell, builder);
340}
341
342bool JSServiceWorkerOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor, const char** reason)
343{
344 auto* jsServiceWorker = jsCast<JSServiceWorker*>(handle.slot()->asCell());
345 if (jsServiceWorker->wrapped().hasPendingActivity()) {
346 if (UNLIKELY(reason))
347 *reason = "ActiveDOMObject with pending activity";
348 return true;
349 }
350 if (jsServiceWorker->wrapped().isFiringEventListeners()) {
351 if (UNLIKELY(reason))
352 *reason = "EventTarget firing event listeners";
353 return true;
354 }
355 UNUSED_PARAM(visitor);
356 UNUSED_PARAM(reason);
357 return false;
358}
359
360void JSServiceWorkerOwner::finalize(JSC::Handle<JSC::Unknown> handle, void* context)
361{
362 auto* jsServiceWorker = static_cast<JSServiceWorker*>(handle.slot()->asCell());
363 auto& world = *static_cast<DOMWrapperWorld*>(context);
364 uncacheWrapper(world, &jsServiceWorker->wrapped(), jsServiceWorker);
365}
366
367#if ENABLE(BINDING_INTEGRITY)
368#if PLATFORM(WIN)
369#pragma warning(disable: 4483)
370extern "C" { extern void (*const __identifier("??_7ServiceWorker@WebCore@@6B@")[])(); }
371#else
372extern "C" { extern void* _ZTVN7WebCore13ServiceWorkerE[]; }
373#endif
374#endif
375
376JSC::JSValue toJSNewlyCreated(JSC::ExecState*, JSDOMGlobalObject* globalObject, Ref<ServiceWorker>&& impl)
377{
378
379#if ENABLE(BINDING_INTEGRITY)
380 void* actualVTablePointer = *(reinterpret_cast<void**>(impl.ptr()));
381#if PLATFORM(WIN)
382 void* expectedVTablePointer = WTF_PREPARE_VTBL_POINTER_FOR_INSPECTION(__identifier("??_7ServiceWorker@WebCore@@6B@"));
383#else
384 void* expectedVTablePointer = WTF_PREPARE_VTBL_POINTER_FOR_INSPECTION(&_ZTVN7WebCore13ServiceWorkerE[2]);
385#endif
386
387 // If this fails ServiceWorker does not have a vtable, so you need to add the
388 // ImplementationLacksVTable attribute to the interface definition
389 static_assert(std::is_polymorphic<ServiceWorker>::value, "ServiceWorker is not polymorphic");
390
391 // If you hit this assertion you either have a use after free bug, or
392 // ServiceWorker has subclasses. If ServiceWorker has subclasses that get passed
393 // to toJS() we currently require ServiceWorker you to opt out of binding hardening
394 // by adding the SkipVTableValidation attribute to the interface IDL definition
395 RELEASE_ASSERT(actualVTablePointer == expectedVTablePointer);
396#endif
397 return createWrapper<ServiceWorker>(globalObject, WTFMove(impl));
398}
399
400JSC::JSValue toJS(JSC::ExecState* state, JSDOMGlobalObject* globalObject, ServiceWorker& impl)
401{
402 return wrap(state, globalObject, impl);
403}
404
405ServiceWorker* JSServiceWorker::toWrapped(JSC::VM& vm, JSC::JSValue value)
406{
407 if (auto* wrapper = jsDynamicCast<JSServiceWorker*>(vm, value))
408 return &wrapper->wrapped();
409 return nullptr;
410}
411
412}
413
414#endif // ENABLE(SERVICE_WORKER)
415