Compare commits

...

1 Commits

Author SHA1 Message Date
Jarred Sumner
c5d637fbb1 WIP 2022-04-09 19:53:17 -07:00
154 changed files with 19232 additions and 38 deletions

View File

@@ -44,8 +44,7 @@ inline DOMWrapperWorld& worldForDOMObject(JSC::JSObject& object);
inline bool isWorldCompatible(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value)
{
return true;
// return !value.isObject() || &worldForDOMObject(*value.getObject()) == &currentWorld(lexicalGlobalObject);
return !value.isObject() || &worldForDOMObject(*value.getObject()) == &currentWorld(lexicalGlobalObject);
}
inline DOMWrapperWorld& currentWorld(JSC::JSGlobalObject& lexicalGlobalObject)

View File

@@ -0,0 +1,44 @@
#pragma once
namespace WebCore {
struct FetchOptions {
enum class Destination : uint8_t { EmptyString,
Audio,
Audioworklet,
Document,
Embed,
Font,
Image,
Iframe,
Manifest,
Model,
Object,
Paintworklet,
Report,
Script,
Serviceworker,
Sharedworker,
Style,
Track,
Video,
Worker,
Xslt };
enum class Mode : uint8_t { Navigate,
SameOrigin,
NoCors,
Cors };
enum class Credentials : uint8_t { Omit,
SameOrigin,
Include };
enum class Cache : uint8_t { Default,
NoStore,
Reload,
NoCache,
ForceCache,
OnlyIfCached };
enum class Redirect : uint8_t { Follow,
Error,
Manual };
};
}

View File

@@ -24,6 +24,7 @@
#include "DOMException.h"
#include "JSDOMException.h"
#include "JSDOMExceptionHandling.h"
#include "JSDOMPromiseDeferred.h"
#include "JavaScriptCore/ErrorHandlingScope.h"
#include "JavaScriptCore/Exception.h"
@@ -275,10 +276,10 @@ void throwNonFiniteTypeError(JSGlobalObject& lexicalGlobalObject, JSC::ThrowScop
throwTypeError(&lexicalGlobalObject, scope, "The provided value is non-finite"_s);
}
// JSC::EncodedJSValue rejectPromiseWithGetterTypeError(JSC::JSGlobalObject& lexicalGlobalObject, const JSC::ClassInfo* classInfo, JSC::PropertyName attributeName)
// {
// return createRejectedPromiseWithTypeError(lexicalGlobalObject, JSC::makeDOMAttributeGetterTypeErrorMessage(classInfo->className, String(attributeName.uid())), RejectedPromiseWithTypeErrorCause::NativeGetter);
// }
JSC::EncodedJSValue rejectPromiseWithGetterTypeError(JSC::JSGlobalObject& lexicalGlobalObject, const JSC::ClassInfo* classInfo, JSC::PropertyName attributeName)
{
return createRejectedPromiseWithTypeError(lexicalGlobalObject, JSC::makeDOMAttributeGetterTypeErrorMessage(classInfo->className, String(attributeName.uid())), RejectedPromiseWithTypeErrorCause::NativeGetter);
}
String makeThisTypeErrorMessage(const char* interfaceName, const char* functionName)
{
@@ -295,16 +296,16 @@ EncodedJSValue throwThisTypeError(JSC::JSGlobalObject& lexicalGlobalObject, JSC:
return throwTypeError(lexicalGlobalObject, scope, makeThisTypeErrorMessage(interfaceName, functionName));
}
// JSC::EncodedJSValue rejectPromiseWithThisTypeError(DeferredPromise& promise, const char* interfaceName, const char* methodName)
// {
// promise.reject(TypeError, makeThisTypeErrorMessage(interfaceName, methodName));
// return JSValue::encode(jsUndefined());
// }
JSC::EncodedJSValue rejectPromiseWithThisTypeError(DeferredPromise& promise, const char* interfaceName, const char* methodName)
{
promise.reject(TypeError, makeThisTypeErrorMessage(interfaceName, methodName));
return JSValue::encode(jsUndefined());
}
// JSC::EncodedJSValue rejectPromiseWithThisTypeError(JSC::JSGlobalObject& lexicalGlobalObject, const char* interfaceName, const char* methodName)
// {
// return createRejectedPromiseWithTypeError(lexicalGlobalObject, makeThisTypeErrorMessage(interfaceName, methodName), RejectedPromiseWithTypeErrorCause::InvalidThis);
// }
JSC::EncodedJSValue rejectPromiseWithThisTypeError(JSC::JSGlobalObject& lexicalGlobalObject, const char* interfaceName, const char* methodName)
{
return createRejectedPromiseWithTypeError(lexicalGlobalObject, makeThisTypeErrorMessage(interfaceName, methodName), RejectedPromiseWithTypeErrorCause::InvalidThis);
}
void throwDOMSyntaxError(JSC::JSGlobalObject& lexicalGlobalObject, JSC::ThrowScope& scope, ASCIILiteral message)
{

View File

@@ -60,9 +60,9 @@ String makeUnsupportedIndexedSetterErrorMessage(const char* interfaceName);
WEBCORE_EXPORT JSC::EncodedJSValue throwThisTypeError(JSC::JSGlobalObject&, JSC::ThrowScope&, const char* interfaceName, const char* functionName);
// WEBCORE_EXPORT JSC::EncodedJSValue rejectPromiseWithGetterTypeError(JSC::JSGlobalObject&, const JSC::ClassInfo*, JSC::PropertyName attributeName);
// WEBCORE_EXPORT JSC::EncodedJSValue rejectPromiseWithThisTypeError(DeferredPromise&, const char* interfaceName, const char* operationName);
// WEBCORE_EXPORT JSC::EncodedJSValue rejectPromiseWithThisTypeError(JSC::JSGlobalObject&, const char* interfaceName, const char* operationName);
WEBCORE_EXPORT JSC::EncodedJSValue rejectPromiseWithGetterTypeError(JSC::JSGlobalObject&, const JSC::ClassInfo*, JSC::PropertyName attributeName);
WEBCORE_EXPORT JSC::EncodedJSValue rejectPromiseWithThisTypeError(DeferredPromise&, const char* interfaceName, const char* operationName);
WEBCORE_EXPORT JSC::EncodedJSValue rejectPromiseWithThisTypeError(JSC::JSGlobalObject&, const char* interfaceName, const char* operationName);
String retrieveErrorMessageWithoutName(JSC::JSGlobalObject&, JSC::VM&, JSC::JSValue exception, JSC::CatchScope&);
String retrieveErrorMessage(JSC::JSGlobalObject&, JSC::VM&, JSC::JSValue exception, JSC::CatchScope&);

View File

@@ -1,7 +1,6 @@
#pragma once
#include "root.h"
#include "ActiveDOMObject.h"
#include <wtf/CrossThreadTask.h>
#include <wtf/Function.h>
#include <wtf/HashSet.h>
@@ -65,12 +64,37 @@ public:
bool isDocument() { return false; }
bool isWorkerGlobalScope() { return true; }
bool isJSExecutionForbidden() { return false; }
EventLoopTaskGroup& eventLoop() { return m_eventLoop; }
void reportException(const String& errorMessage, int lineNumber, int columnNumber, const String& sourceURL, JSC::Exception* exception, RefPtr<void*>&&, CachedScript* = nullptr, bool = false)
{
}
// void reportUnhandledPromiseRejection(JSC::JSGlobalObject&, JSC::JSPromise&, RefPtr<Inspector::ScriptCallStack>&&)
// {
// }
void reportUnhandledPromiseRejection(JSC::JSGlobalObject&, JSC::JSPromise&, RefPtr<Inspector::ScriptCallStack>&&)
{
}
// Called from the constructor and destructors of ActiveDOMObject.
void didCreateActiveDOMObject(ActiveDOMObject&);
void willDestroyActiveDOMObject(ActiveDOMObject&);
// Called after the construction of an ActiveDOMObject to synchronize suspend state.
void suspendActiveDOMObjectIfNeeded(ActiveDOMObject&);
void didCreateDestructionObserver(ContextDestructionObserver&);
void willDestroyDestructionObserver(ContextDestructionObserver&);
// MessagePort is conceptually a kind of ActiveDOMObject, but it needs to be tracked separately for message dispatch.
void processMessageWithMessagePortsSoon();
void dispatchMessagePortEvents();
void createdMessagePort(MessagePort&);
void destroyedMessagePort(MessagePort&);
ReasonForSuspension reasonForSuspendingActiveDOMObjects() const { return m_reasonForSuspendingActiveDOMObjects; }
bool hasPendingActivity() const;
void removeFromContextsMap();
void removeRejectedPromiseTracker();
void regenerateIdentifier();
void postTask(Task&&)
{
@@ -91,5 +115,21 @@ private:
JSC::VM* m_vm = nullptr;
JSC::JSGlobalObject* m_globalObject = nullptr;
WTF::URL m_url = WTF::URL();
enum class ShouldContinue { No,
Yes };
void forEachActiveDOMObject(const Function<ShouldContinue(ActiveDOMObject&)>&) const;
RejectedPromiseTracker& ensureRejectedPromiseTrackerSlow();
HashSet<MessagePort*> m_messagePorts;
HashSet<ContextDestructionObserver*> m_destructionObservers;
HashSet<ActiveDOMObject*> m_activeDOMObjects;
std::unique_ptr<RejectedPromiseTracker> m_rejectedPromiseTracker;
ReasonForSuspension m_reasonForSuspendingActiveDOMObjects { static_cast<ReasonForSuspension>(-1) };
bool m_activeDOMObjectsAreSuspended { false };
bool m_activeDOMObjectsAreStopped { false };
bool m_inDispatchErrorEvent { false };
mutable bool m_activeDOMObjectAdditionForbidden { false };
bool m_willprocessMessageWithMessagePortsSoon { false };
};
}

View File

@@ -87,6 +87,7 @@
#include "Process.h"
#include "JavaScriptCore/RemoteInspectorServer.h"
#include "JSDOMGuardedObject.h"
using JSGlobalObject = JSC::JSGlobalObject;
using Exception = JSC::Exception;
@@ -287,6 +288,7 @@ GlobalObject::GlobalObject(JSC::VM& vm, JSC::Structure* structure)
, m_constructors(makeUnique<WebCore::DOMConstructors>())
, m_world(WebCore::DOMWrapperWorld::create(vm, WebCore::DOMWrapperWorld::Type::Normal))
, m_worldIsNormal(true)
, m_guardedObjects()
{
m_scriptExecutionContext = new WebCore::ScriptExecutionContext(&vm, this);
@@ -482,6 +484,16 @@ JSC_DEFINE_CUSTOM_GETTER(property_lazyProcessGetter,
return JSC::JSValue::encode(JSC::JSValue(process));
}
void JSDOMGlobalObject::clearDOMGuardedObjects() const
{
// No locking is necessary here since we are not directly modifying the returned container.
// Calling JSDOMGuardedObject::clear() will however modify the guarded objects container but
// it will grab the lock as needed.
auto guardedObjectsCopy = guardedObjects();
for (auto& guarded : guardedObjectsCopy)
guarded->clear();
}
static JSC_DECLARE_HOST_FUNCTION(functionQueueMicrotask);
static JSC_DEFINE_HOST_FUNCTION(functionQueueMicrotask,
@@ -896,8 +908,8 @@ void GlobalObject::visitChildrenImpl(JSCell* cell, Visitor& visitor)
for (auto& structure : thisObject->m_structures.values())
visitor.append(structure);
// for (auto& guarded : thisObject->m_guardedObjects)
// guarded->visitAggregate(visitor);
for (auto& guarded : thisObject->m_guardedObjects)
guarded->visitAggregate(visitor);
}
for (auto& constructor : thisObject->constructors().array())

View File

@@ -11,6 +11,7 @@ class Identifier;
namespace WebCore {
class ScriptExecutionContext;
class DOMGuardedObject;
}
#include "root.h"
@@ -30,6 +31,7 @@ class ScriptExecutionContext;
#include "DOMIsoSubspaces.h"
namespace Zig {
using DOMGuardedObjectSet = HashSet<WebCore::DOMGuardedObject*>;
using JSDOMStructureMap = HashMap<const JSC::ClassInfo*, JSC::WriteBarrier<JSC::Structure>>;
@@ -83,6 +85,20 @@ public:
return *m_constructors;
}
Zig::DOMGuardedObjectSet& guardedObjects() WTF_REQUIRES_LOCK(m_gcLock) { return m_guardedObjects; }
const Zig::DOMGuardedObjectSet& guardedObjects() const WTF_IGNORES_THREAD_SAFETY_ANALYSIS
{
ASSERT(!Thread::mayBeGCThread());
return m_guardedObjects;
}
Zig::DOMGuardedObjectSet& guardedObjects(NoLockingNecessaryTag) WTF_IGNORES_THREAD_SAFETY_ANALYSIS
{
ASSERT(!vm().heap.mutatorShouldBeFenced());
return m_guardedObjects;
}
WebCore::DOMWrapperWorld& world() { return m_world.get(); }
DECLARE_VISIT_CHILDREN;
@@ -90,6 +106,8 @@ public:
bool worldIsNormal() const { return m_worldIsNormal; }
static ptrdiff_t offsetOfWorldIsNormal() { return OBJECT_OFFSETOF(GlobalObject, m_worldIsNormal); }
void clearDOMGuardedObjects();
WebCore::ScriptExecutionContext* scriptExecutionContext();
WebCore::ScriptExecutionContext* scriptExecutionContext() const;
@@ -134,6 +152,7 @@ private:
Lock m_gcLock;
WebCore::ScriptExecutionContext* m_scriptExecutionContext;
Ref<WebCore::DOMWrapperWorld> m_world;
Zig::DOMGuardedObjectSet m_guardedObjects WTF_GUARDED_BY_LOCK(m_gcLock);
};
class JSMicrotaskCallback : public RefCounted<JSMicrotaskCallback> {

View File

@@ -78,4 +78,7 @@
#define WTF_MAKE_ISO_ALLOCATED_EXPORT(className, a) WTF_MAKE_FAST_ALLOCATED_WITH_HEAP_IDENTIFIER(className);
#define WTF_MAKE_ISO_ALLOCATED_IMPL(className)
#define JSC_NOT_IMPLEMENTED_GETTER_BODY return JSC::JSValue::encode(JSC::jsUndefined())
#endif

View File

@@ -0,0 +1,77 @@
/*
* Copyright (C) 2010 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#include "AbstractWorker.h"
// #include "ContentSecurityPolicy.h"
#include "ScriptExecutionContext.h"
// #include "SecurityOrigin.h"
#include "WorkerOptions.h"
#include <wtf/IsoMallocInlines.h>
namespace WebCore {
WTF_MAKE_ISO_ALLOCATED_IMPL(AbstractWorker);
FetchOptions AbstractWorker::workerFetchOptions(const WorkerOptions& options, FetchOptions::Destination destination)
{
FetchOptions fetchOptions;
fetchOptions.mode = FetchOptions::Mode::SameOrigin;
if (options.type == WorkerType::Module)
fetchOptions.credentials = options.credentials;
else
fetchOptions.credentials = FetchOptions::Credentials::SameOrigin;
fetchOptions.cache = FetchOptions::Cache::Default;
fetchOptions.redirect = FetchOptions::Redirect::Follow;
fetchOptions.destination = destination;
return fetchOptions;
}
ExceptionOr<URL> AbstractWorker::resolveURL(const String& url)
{
auto& context = *scriptExecutionContext();
// FIXME: This should use the dynamic global scope (bug #27887).
URL scriptURL = context.completeURL(url);
if (!scriptURL.isValid())
return Exception { SyntaxError };
// if (!context.securityOrigin()->canRequest(scriptURL) && !scriptURL.protocolIsData())
// return Exception { SecurityError };
// ASSERT(context.contentSecurityPolicy());
// if (!context.contentSecurityPolicy()->allowWorkerFromSource(scriptURL))
// return Exception { SecurityError };
return scriptURL;
}
} // namespace WebCore

View File

@@ -0,0 +1,63 @@
/*
* Copyright (C) 2010 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#pragma once
#include "EventTarget.h"
#include "ExceptionOr.h"
#include "FetchOptions.h"
namespace WebCore {
struct FetchOptions;
struct WorkerOptions;
class AbstractWorker : public RefCounted<AbstractWorker>, public EventTargetWithInlineData {
WTF_MAKE_ISO_ALLOCATED(AbstractWorker);
public:
using RefCounted::ref;
using RefCounted::deref;
static FetchOptions workerFetchOptions(const WorkerOptions&, FetchOptions::Destination);
protected:
AbstractWorker() = default;
// Helper function that converts a URL to an absolute URL and checks the result for validity.
ExceptionOr<URL> resolveURL(const String& url);
intptr_t asID() const { return reinterpret_cast<intptr_t>(this); }
private:
void refEventTarget() final { ref(); }
void derefEventTarget() final { deref(); }
};
} // namespace WebCore

View File

@@ -0,0 +1,36 @@
/*
* Copyright (C) 2009 Google Inc. All rights reserved.
* Copyright (C) 2011, 2020 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
// https://html.spec.whatwg.org/multipage/workers.html#abstractworker
interface mixin AbstractWorker {
attribute EventHandler onerror;
};

View File

@@ -0,0 +1,63 @@
/*
* Copyright (C) 2010. 2012 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#include "ActiveDOMCallback.h"
#include "ScriptExecutionContext.h"
namespace WebCore {
ActiveDOMCallback::ActiveDOMCallback(ScriptExecutionContext* context)
: ContextDestructionObserver(context)
{
}
ActiveDOMCallback::~ActiveDOMCallback() = default;
bool ActiveDOMCallback::canInvokeCallback() const
{
ScriptExecutionContext* context = scriptExecutionContext();
return context && !context->activeDOMObjectsAreSuspended() && !context->activeDOMObjectsAreStopped();
}
bool ActiveDOMCallback::activeDOMObjectsAreSuspended() const
{
auto* context = scriptExecutionContext();
return context && context->activeDOMObjectsAreSuspended();
}
bool ActiveDOMCallback::activeDOMObjectAreStopped() const
{
auto* context = scriptExecutionContext();
return !context || context->activeDOMObjectsAreStopped();
}
} // namespace WebCore

View File

@@ -0,0 +1,64 @@
/*
* Copyright (C) 2010, 2012 Google Inc. All rights reserved.
* Copyright (C) 2021 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#pragma once
#include "ContextDestructionObserver.h"
namespace JSC {
class AbstractSlotVisitor;
class SlotVisitor;
}
namespace WebCore {
class ScriptExecutionContext;
// A base class that prevents binding callbacks from executing when
// active dom objects are stopped or suspended.
//
// Should only be created, used, and destroyed on the script execution
// context thread.
class ActiveDOMCallback : public ContextDestructionObserver {
public:
WEBCORE_EXPORT ActiveDOMCallback(ScriptExecutionContext*);
WEBCORE_EXPORT virtual ~ActiveDOMCallback();
WEBCORE_EXPORT bool canInvokeCallback() const;
WEBCORE_EXPORT bool activeDOMObjectsAreSuspended() const;
WEBCORE_EXPORT bool activeDOMObjectAreStopped() const;
virtual void visitJSFunction(JSC::AbstractSlotVisitor&) { }
virtual void visitJSFunction(JSC::SlotVisitor&) { }
};
} // namespace WebCore

View File

@@ -0,0 +1,196 @@
/*
* Copyright (C) 2008 Apple Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include "config.h"
#include "ActiveDOMObject.h"
// #include "Document.h"
#include "Event.h"
#include "EventTarget.h"
#include "EventLoop.h"
#include "ScriptExecutionContext.h"
namespace WebCore {
static inline ScriptExecutionContext* suitableScriptExecutionContext(ScriptExecutionContext* scriptExecutionContext)
{
// For detached documents, make sure we observe their context document instead.
// return is<Document>(scriptExecutionContext) ? &downcast<Document>(*scriptExecutionContext).contextDocument() : scriptExecutionContext;
return scriptExecutionContext;
}
inline ActiveDOMObject::ActiveDOMObject(ScriptExecutionContext* context, CheckedScriptExecutionContextType)
: ContextDestructionObserver(context)
{
// ASSERT(!is<Document>(context) || &downcast<Document>(context)->contextDocument() == downcast<Document>(context));
if (!context)
return;
ASSERT(context->isContextThread());
context->didCreateActiveDOMObject(*this);
}
ActiveDOMObject::ActiveDOMObject(ScriptExecutionContext* scriptExecutionContext)
: ActiveDOMObject(suitableScriptExecutionContext(scriptExecutionContext), CheckedScriptExecutionContext)
{
}
// ActiveDOMObject::ActiveDOMObject(Document* document)
// : ActiveDOMObject(document ? &document->contextDocument() : nullptr, CheckedScriptExecutionContext)
// {
// }
// ActiveDOMObject::ActiveDOMObject(Document& document)
// : ActiveDOMObject(&document.contextDocument(), CheckedScriptExecutionContext)
// {
// }
ActiveDOMObject::~ActiveDOMObject()
{
ASSERT(canCurrentThreadAccessThreadLocalData(m_creationThread));
// ActiveDOMObject may be inherited by a sub-class whose life-cycle
// exceeds that of the associated ScriptExecutionContext. In those cases,
// m_scriptExecutionContext would/should have been nullified by
// ContextDestructionObserver::contextDestroyed() (which we implement /
// inherit). Hence, we should ensure that this is not 0 before use it
// here.
auto* context = scriptExecutionContext();
if (!context)
return;
ASSERT(m_suspendIfNeededWasCalled);
ASSERT(context->isContextThread());
context->willDestroyActiveDOMObject(*this);
}
void ActiveDOMObject::suspendIfNeeded()
{
#if ASSERT_ENABLED
ASSERT(!m_suspendIfNeededWasCalled);
m_suspendIfNeededWasCalled = true;
#endif
if (auto* context = scriptExecutionContext())
context->suspendActiveDOMObjectIfNeeded(*this);
}
#if ASSERT_ENABLED
void ActiveDOMObject::assertSuspendIfNeededWasCalled() const
{
if (!m_suspendIfNeededWasCalled)
WTFLogAlways("Failed to call suspendIfNeeded() for %s", activeDOMObjectName());
ASSERT(m_suspendIfNeededWasCalled);
}
#endif // ASSERT_ENABLED
void ActiveDOMObject::suspend(ReasonForSuspension)
{
}
void ActiveDOMObject::resume()
{
}
void ActiveDOMObject::stop()
{
}
bool ActiveDOMObject::isContextStopped() const
{
return !scriptExecutionContext() || scriptExecutionContext()->activeDOMObjectsAreStopped();
}
bool ActiveDOMObject::isAllowedToRunScript() const
{
return scriptExecutionContext() && !scriptExecutionContext()->activeDOMObjectsAreStopped() && !scriptExecutionContext()->activeDOMObjectsAreSuspended();
}
void ActiveDOMObject::queueTaskInEventLoop(TaskSource source, Function<void()>&& function)
{
auto* context = scriptExecutionContext();
if (!context)
return;
context->eventLoop().queueTask(source, WTFMove(function));
}
class ActiveDOMObjectEventDispatchTask : public EventLoopTask {
public:
ActiveDOMObjectEventDispatchTask(TaskSource source, EventLoopTaskGroup& group, ActiveDOMObject& object, Function<void()>&& dispatchEvent)
: EventLoopTask(source, group)
, m_object(object)
, m_dispatchEvent(WTFMove(dispatchEvent))
{
++m_object.m_pendingActivityInstanceCount;
}
~ActiveDOMObjectEventDispatchTask()
{
ASSERT(m_object.m_pendingActivityInstanceCount);
--m_object.m_pendingActivityInstanceCount;
}
void execute() final
{
// If this task executes after the script execution context has been stopped, don't
// actually dispatch the event.
if (m_object.isAllowedToRunScript())
m_dispatchEvent();
}
private:
ActiveDOMObject& m_object;
Function<void()> m_dispatchEvent;
};
void ActiveDOMObject::queueTaskToDispatchEventInternal(EventTarget& target, TaskSource source, Ref<Event>&& event)
{
ASSERT(!event->target() || &target == event->target());
auto* context = scriptExecutionContext();
if (!context)
return;
auto& eventLoopTaskGroup = context->eventLoop();
auto task = makeUnique<ActiveDOMObjectEventDispatchTask>(source, eventLoopTaskGroup, *this, [target = Ref { target }, event = WTFMove(event)] {
target->dispatchEvent(event);
});
eventLoopTaskGroup.queueTask(WTFMove(task));
}
void ActiveDOMObject::queueCancellableTaskToDispatchEventInternal(EventTarget& target, TaskSource source, TaskCancellationGroup& cancellationGroup, Ref<Event>&& event)
{
ASSERT(!event->target() || &target == event->target());
auto* context = scriptExecutionContext();
if (!context)
return;
auto& eventLoopTaskGroup = context->eventLoop();
auto task = makeUnique<ActiveDOMObjectEventDispatchTask>(source, eventLoopTaskGroup, *this, CancellableTask(cancellationGroup, [target = Ref { target }, event = WTFMove(event)] {
target->dispatchEvent(event);
}));
eventLoopTaskGroup.queueTask(WTFMove(task));
}
} // namespace WebCore

View File

@@ -0,0 +1,173 @@
/*
* Copyright (C) 2008 Apple Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#pragma once
#include "root.h"
#include "ScriptExecutionContext.h"
#include "ContextDestructionObserver.h"
#include "TaskSource.h"
#include <wtf/Assertions.h>
#include <wtf/CancellableTask.h>
#include <wtf/Forward.h>
#include <wtf/Function.h>
#include <wtf/RefCounted.h>
#include <wtf/Threading.h>
namespace WebCore {
// class Document;
class Event;
class EventLoopTaskGroup;
class EventTarget;
enum class ReasonForSuspension {
JavaScriptDebuggerPaused,
WillDeferLoading,
BackForwardCache,
PageWillBeSuspended,
};
class WEBCORE_EXPORT ActiveDOMObject : public ContextDestructionObserver {
public:
// The suspendIfNeeded must be called exactly once after object construction to update
// the suspended state to match that of the ScriptExecutionContext.
void suspendIfNeeded();
void assertSuspendIfNeededWasCalled() const;
// This function is used by JS bindings to determine if the JS wrapper should be kept alive or not.
bool hasPendingActivity() const { return m_pendingActivityInstanceCount || virtualHasPendingActivity(); }
// However, the suspend function will sometimes be called even if canSuspendForDocumentSuspension() returns false.
// That happens in step-by-step JS debugging for example - in this case it would be incorrect
// to stop the object. Exact semantics of suspend is up to the object in cases like that.
virtual const char* activeDOMObjectName() const = 0;
// These functions must not have a side effect of creating or destroying
// any ActiveDOMObject. That means they must not result in calls to arbitrary JavaScript.
virtual void suspend(ReasonForSuspension);
virtual void resume();
// This function must not have a side effect of creating an ActiveDOMObject.
// That means it must not result in calls to arbitrary JavaScript.
// It can, however, have a side effect of deleting an ActiveDOMObject.
virtual void stop();
template<class T>
class PendingActivity : public RefCounted<PendingActivity<T>> {
public:
explicit PendingActivity(T& thisObject)
: m_thisObject(thisObject)
{
++(m_thisObject->m_pendingActivityInstanceCount);
}
~PendingActivity()
{
ASSERT(m_thisObject->m_pendingActivityInstanceCount > 0);
--(m_thisObject->m_pendingActivityInstanceCount);
}
private:
Ref<T> m_thisObject;
};
template<class T> Ref<PendingActivity<T>> makePendingActivity(T& thisObject)
{
ASSERT(&thisObject == this);
return adoptRef(*new PendingActivity<T>(thisObject));
}
bool isContextStopped() const;
bool isAllowedToRunScript() const;
template<typename T>
static void queueTaskKeepingObjectAlive(T& object, TaskSource source, Function<void()>&& task)
{
object.queueTaskInEventLoop(source, [protectedObject = Ref { object }, activity = object.ActiveDOMObject::makePendingActivity(object), task = WTFMove(task)]() {
task();
});
}
template<typename T>
static void queueCancellableTaskKeepingObjectAlive(T& object, TaskSource source, TaskCancellationGroup& cancellationGroup, Function<void()>&& task)
{
CancellableTask cancellableTask(cancellationGroup, WTFMove(task));
object.queueTaskInEventLoop(source, [protectedObject = Ref { object }, activity = object.ActiveDOMObject::makePendingActivity(object), cancellableTask = WTFMove(cancellableTask)]() mutable {
cancellableTask();
});
}
template<typename EventTargetType>
static void queueTaskToDispatchEvent(EventTargetType& target, TaskSource source, Ref<Event>&& event)
{
target.queueTaskToDispatchEventInternal(target, source, WTFMove(event));
}
template<typename EventTargetType>
static void queueCancellableTaskToDispatchEvent(EventTargetType& target, TaskSource source, TaskCancellationGroup& cancellationGroup, Ref<Event>&& event)
{
target.queueCancellableTaskToDispatchEventInternal(target, source, cancellationGroup, WTFMove(event));
}
protected:
explicit ActiveDOMObject(ScriptExecutionContext*);
// explicit ActiveDOMObject(Document*);
// explicit ActiveDOMObject(Document&);
virtual ~ActiveDOMObject();
private:
enum CheckedScriptExecutionContextType { CheckedScriptExecutionContext };
ActiveDOMObject(ScriptExecutionContext*, CheckedScriptExecutionContextType);
// This is used by subclasses to indicate that they have pending activity, meaning that they would
// like the JS wrapper to stay alive (because they may still fire JS events).
virtual bool virtualHasPendingActivity() const { return false; }
void queueTaskInEventLoop(TaskSource, Function<void()>&&);
void queueTaskToDispatchEventInternal(EventTarget&, TaskSource, Ref<Event>&&);
void queueCancellableTaskToDispatchEventInternal(EventTarget&, TaskSource, TaskCancellationGroup&, Ref<Event>&&);
uint64_t m_pendingActivityInstanceCount { 0 };
#if ASSERT_ENABLED
bool m_suspendIfNeededWasCalled { false };
Ref<Thread> m_creationThread { Thread::current() };
#endif
friend class ActiveDOMObjectEventDispatchTask;
};
#if !ASSERT_ENABLED
inline void ActiveDOMObject::assertSuspendIfNeededWasCalled() const
{
}
#endif
} // namespace WebCore

View File

@@ -416,9 +416,9 @@ public:
// std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForIdleDeadline;
// std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForInputEvent;
// std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForKeyboardEvent;
// std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForMessageChannel;
// std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForMessageEvent;
// std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForMessagePort;
std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForMessageChannel;
std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForMessageEvent;
std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForMessagePort;
// std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForMouseEvent;
// std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForMutationEvent;
// std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForMutationObserver;
@@ -434,7 +434,7 @@ public:
// std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForPopStateEvent;
// std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForProcessingInstruction;
// std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForProgressEvent;
// std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForPromiseRejectionEvent;
std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForPromiseRejectionEvent;
// std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForRange;
// std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSecurityPolicyViolationEvent;
// std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForShadowRoot;
@@ -671,7 +671,7 @@ public:
// std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForVisualViewport;
// std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForWebKitNamespace;
// std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForWebKitPoint;
// std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForWorkerNavigator;
std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForWorkerNavigator;
// std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForDOMMimeType;
// std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForDOMMimeTypeArray;
// std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForDOMPlugin;
@@ -835,7 +835,7 @@ public:
// std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForDedicatedWorkerGlobalScope;
// std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForWorker;
// std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForWorkerGlobalScope;
// std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForWorkerLocation;
std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForWorkerLocation;
// std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForExtendableEvent;
// std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForExtendableMessageEvent;
// std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForFetchEvent;

View File

@@ -407,9 +407,9 @@ public:
// std::unique_ptr<IsoSubspace> m_subspaceForIdleDeadline;
// std::unique_ptr<IsoSubspace> m_subspaceForInputEvent;
// std::unique_ptr<IsoSubspace> m_subspaceForKeyboardEvent;
// std::unique_ptr<IsoSubspace> m_subspaceForMessageChannel;
// std::unique_ptr<IsoSubspace> m_subspaceForMessageEvent;
// std::unique_ptr<IsoSubspace> m_subspaceForMessagePort;
std::unique_ptr<IsoSubspace> m_subspaceForMessageChannel;
std::unique_ptr<IsoSubspace> m_subspaceForMessageEvent;
std::unique_ptr<IsoSubspace> m_subspaceForMessagePort;
// std::unique_ptr<IsoSubspace> m_subspaceForMouseEvent;
// std::unique_ptr<IsoSubspace> m_subspaceForMutationEvent;
// std::unique_ptr<IsoSubspace> m_subspaceForMutationObserver;
@@ -425,7 +425,7 @@ public:
// std::unique_ptr<IsoSubspace> m_subspaceForPopStateEvent;
// std::unique_ptr<IsoSubspace> m_subspaceForProcessingInstruction;
// std::unique_ptr<IsoSubspace> m_subspaceForProgressEvent;
// std::unique_ptr<IsoSubspace> m_subspaceForPromiseRejectionEvent;
std::unique_ptr<IsoSubspace> m_subspaceForPromiseRejectionEvent;
// std::unique_ptr<IsoSubspace> m_subspaceForRange;
// std::unique_ptr<IsoSubspace> m_subspaceForSecurityPolicyViolationEvent;
// std::unique_ptr<IsoSubspace> m_subspaceForShadowRoot;
@@ -662,7 +662,7 @@ public:
// std::unique_ptr<IsoSubspace> m_subspaceForVisualViewport;
// std::unique_ptr<IsoSubspace> m_subspaceForWebKitNamespace;
// std::unique_ptr<IsoSubspace> m_subspaceForWebKitPoint;
// std::unique_ptr<IsoSubspace> m_subspaceForWorkerNavigator;
std::unique_ptr<IsoSubspace> m_subspaceForWorkerNavigator;
// std::unique_ptr<IsoSubspace> m_subspaceForDOMMimeType;
// std::unique_ptr<IsoSubspace> m_subspaceForDOMMimeTypeArray;
// std::unique_ptr<IsoSubspace> m_subspaceForDOMPlugin;
@@ -826,7 +826,7 @@ public:
// std::unique_ptr<IsoSubspace> m_subspaceForDedicatedWorkerGlobalScope;
// std::unique_ptr<IsoSubspace> m_subspaceForWorker;
std::unique_ptr<IsoSubspace> m_subspaceForWorkerGlobalScope;
// std::unique_ptr<IsoSubspace> m_subspaceForWorkerLocation;
std::unique_ptr<IsoSubspace> m_subspaceForWorkerLocation;
// std::unique_ptr<IsoSubspace> m_subspaceForExtendableEvent;
// std::unique_ptr<IsoSubspace> m_subspaceForExtendableMessageEvent;
// std::unique_ptr<IsoSubspace> m_subspaceForFetchEvent;

View File

@@ -0,0 +1,350 @@
/*
* Copyright (C) 2017-2021 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#pragma once
#include "ExceptionOr.h"
#include "JSDOMGlobalObject.h"
#include "JSDOMPromiseDeferred.h"
#include <wtf/Function.h>
#include <wtf/Vector.h>
namespace WebCore {
template<typename IDLType>
class DOMPromiseProxy {
WTF_MAKE_FAST_ALLOCATED;
public:
using Value = typename IDLType::StorageType;
DOMPromiseProxy() = default;
~DOMPromiseProxy() = default;
JSC::JSValue promise(JSC::JSGlobalObject&, JSDOMGlobalObject&);
void clear();
bool isFulfilled() const;
void resolve(typename IDLType::StorageType);
void resolveWithNewlyCreated(typename IDLType::StorageType);
void reject(Exception, RejectAsHandled = RejectAsHandled::No);
private:
JSC::JSValue resolvePromise(JSC::JSGlobalObject&, JSDOMGlobalObject&, const Function<void(DeferredPromise&)>&);
std::optional<ExceptionOr<Value>> m_valueOrException;
Vector<Ref<DeferredPromise>, 1> m_deferredPromises;
};
template<>
class DOMPromiseProxy<IDLUndefined> {
WTF_MAKE_FAST_ALLOCATED;
public:
DOMPromiseProxy() = default;
~DOMPromiseProxy() = default;
JSC::JSValue promise(JSC::JSGlobalObject&, JSDOMGlobalObject&);
void clear();
bool isFulfilled() const;
void resolve();
void reject(Exception, RejectAsHandled = RejectAsHandled::No);
private:
std::optional<ExceptionOr<void>> m_valueOrException;
Vector<Ref<DeferredPromise>, 1> m_deferredPromises;
};
// Instead of storing the value of the resolution directly, DOMPromiseProxyWithResolveCallback
// allows the owner to specify callback to be called when the resolved value is needed. This is
// needed to avoid reference cycles when the resolved value is the owner, such as is the case with
// FontFace and FontFaceSet.
template<typename IDLType>
class DOMPromiseProxyWithResolveCallback {
WTF_MAKE_FAST_ALLOCATED;
public:
using ResolveCallback = Function<typename IDLType::ParameterType()>;
template <typename Class, typename BaseClass>
DOMPromiseProxyWithResolveCallback(Class&, typename IDLType::ParameterType (BaseClass::*)());
DOMPromiseProxyWithResolveCallback(ResolveCallback&&);
~DOMPromiseProxyWithResolveCallback() = default;
JSC::JSValue promise(JSC::JSGlobalObject&, JSDOMGlobalObject&);
void clear();
bool isFulfilled() const;
void resolve(typename IDLType::ParameterType);
void resolveWithNewlyCreated(typename IDLType::ParameterType);
void reject(Exception, RejectAsHandled = RejectAsHandled::No);
private:
ResolveCallback m_resolveCallback;
std::optional<ExceptionOr<void>> m_valueOrException;
Vector<Ref<DeferredPromise>, 1> m_deferredPromises;
};
// MARK: - DOMPromiseProxy<IDLType> generic implementation
template<typename IDLType>
inline JSC::JSValue DOMPromiseProxy<IDLType>::resolvePromise(JSC::JSGlobalObject& lexicalGlobalObject, JSDOMGlobalObject& globalObject, const Function<void(DeferredPromise&)>& resolvePromiseCallback)
{
UNUSED_PARAM(lexicalGlobalObject);
for (auto& deferredPromise : m_deferredPromises) {
if (deferredPromise->globalObject() == &globalObject)
return deferredPromise->promise();
}
// DeferredPromise can fail construction during worker abrupt termination.
auto deferredPromise = DeferredPromise::create(globalObject, DeferredPromise::Mode::RetainPromiseOnResolve);
if (!deferredPromise)
return JSC::jsUndefined();
if (m_valueOrException) {
if (m_valueOrException->hasException())
deferredPromise->reject(m_valueOrException->exception());
else
resolvePromiseCallback(*deferredPromise);
}
auto result = deferredPromise->promise();
m_deferredPromises.append(deferredPromise.releaseNonNull());
return result;
}
template<typename IDLType>
inline JSC::JSValue DOMPromiseProxy<IDLType>::promise(JSC::JSGlobalObject& lexicalGlobalObject, JSDOMGlobalObject& globalObject)
{
return resolvePromise(lexicalGlobalObject, globalObject, [this](auto& deferredPromise) {
deferredPromise.template resolve<IDLType>(m_valueOrException->returnValue());
});
}
template<>
inline JSC::JSValue DOMPromiseProxy<IDLAny>::promise(JSC::JSGlobalObject& lexicalGlobalObject, JSDOMGlobalObject& globalObject)
{
return resolvePromise(lexicalGlobalObject, globalObject, [this](auto& deferredPromise) {
deferredPromise.resolveWithJSValue(m_valueOrException->returnValue().get());
});
}
template<typename IDLType>
inline void DOMPromiseProxy<IDLType>::clear()
{
m_valueOrException = std::nullopt;
m_deferredPromises.clear();
}
template<typename IDLType>
inline bool DOMPromiseProxy<IDLType>::isFulfilled() const
{
return m_valueOrException.has_value();
}
template<typename IDLType>
inline void DOMPromiseProxy<IDLType>::resolve(typename IDLType::StorageType value)
{
ASSERT(!m_valueOrException);
m_valueOrException = ExceptionOr<Value> { std::forward<typename IDLType::StorageType>(value) };
for (auto& deferredPromise : m_deferredPromises)
deferredPromise->template resolve<IDLType>(m_valueOrException->returnValue());
}
template<>
inline void DOMPromiseProxy<IDLAny>::resolve(typename IDLAny::StorageType value)
{
ASSERT(!m_valueOrException);
m_valueOrException = ExceptionOr<Value> { std::forward<typename IDLAny::StorageType>(value) };
for (auto& deferredPromise : m_deferredPromises)
deferredPromise->resolveWithJSValue(m_valueOrException->returnValue().get());
}
template<typename IDLType>
inline void DOMPromiseProxy<IDLType>::resolveWithNewlyCreated(typename IDLType::StorageType value)
{
ASSERT(!m_valueOrException);
m_valueOrException = ExceptionOr<Value> { std::forward<typename IDLType::StorageType>(value) };
for (auto& deferredPromise : m_deferredPromises)
deferredPromise->template resolveWithNewlyCreated<IDLType>(m_valueOrException->returnValue());
}
template<typename IDLType>
inline void DOMPromiseProxy<IDLType>::reject(Exception exception, RejectAsHandled rejectAsHandled)
{
ASSERT(!m_valueOrException);
m_valueOrException = ExceptionOr<Value> { WTFMove(exception) };
for (auto& deferredPromise : m_deferredPromises)
deferredPromise->reject(m_valueOrException->exception(), rejectAsHandled);
}
// MARK: - DOMPromiseProxy<IDLUndefined> specialization
inline JSC::JSValue DOMPromiseProxy<IDLUndefined>::promise(JSC::JSGlobalObject& lexicalGlobalObject, JSDOMGlobalObject& globalObject)
{
UNUSED_PARAM(lexicalGlobalObject);
for (auto& deferredPromise : m_deferredPromises) {
if (deferredPromise->globalObject() == &globalObject)
return deferredPromise->promise();
}
// DeferredPromise can fail construction during worker abrupt termination.
auto deferredPromise = DeferredPromise::create(globalObject, DeferredPromise::Mode::RetainPromiseOnResolve);
if (!deferredPromise)
return JSC::jsUndefined();
if (m_valueOrException) {
if (m_valueOrException->hasException())
deferredPromise->reject(m_valueOrException->exception());
else
deferredPromise->resolve();
}
auto result = deferredPromise->promise();
m_deferredPromises.append(deferredPromise.releaseNonNull());
return result;
}
inline void DOMPromiseProxy<IDLUndefined>::clear()
{
m_valueOrException = std::nullopt;
m_deferredPromises.clear();
}
inline bool DOMPromiseProxy<IDLUndefined>::isFulfilled() const
{
return m_valueOrException.has_value();
}
inline void DOMPromiseProxy<IDLUndefined>::resolve()
{
ASSERT(!m_valueOrException);
m_valueOrException = ExceptionOr<void> { };
for (auto& deferredPromise : m_deferredPromises)
deferredPromise->resolve();
}
inline void DOMPromiseProxy<IDLUndefined>::reject(Exception exception, RejectAsHandled rejectAsHandled)
{
ASSERT(!m_valueOrException);
m_valueOrException = ExceptionOr<void> { WTFMove(exception) };
for (auto& deferredPromise : m_deferredPromises)
deferredPromise->reject(m_valueOrException->exception(), rejectAsHandled);
}
// MARK: - DOMPromiseProxyWithResolveCallback<IDLType> implementation
template<typename IDLType>
template <typename Class, typename BaseClass>
inline DOMPromiseProxyWithResolveCallback<IDLType>::DOMPromiseProxyWithResolveCallback(Class& object, typename IDLType::ParameterType (BaseClass::*function)())
: m_resolveCallback(std::bind(function, &object))
{
}
template<typename IDLType>
inline DOMPromiseProxyWithResolveCallback<IDLType>::DOMPromiseProxyWithResolveCallback(ResolveCallback&& function)
: m_resolveCallback(WTFMove(function))
{
}
template<typename IDLType>
inline JSC::JSValue DOMPromiseProxyWithResolveCallback<IDLType>::promise(JSC::JSGlobalObject& lexicalGlobalObject, JSDOMGlobalObject& globalObject)
{
UNUSED_PARAM(lexicalGlobalObject);
for (auto& deferredPromise : m_deferredPromises) {
if (deferredPromise->globalObject() == &globalObject)
return deferredPromise->promise();
}
// DeferredPromise can fail construction during worker abrupt termination.
auto deferredPromise = DeferredPromise::create(globalObject, DeferredPromise::Mode::RetainPromiseOnResolve);
if (!deferredPromise)
return JSC::jsUndefined();
if (m_valueOrException) {
if (m_valueOrException->hasException())
deferredPromise->reject(m_valueOrException->exception());
else
deferredPromise->template resolve<IDLType>(m_resolveCallback());
}
auto result = deferredPromise->promise();
m_deferredPromises.append(deferredPromise.releaseNonNull());
return result;
}
template<typename IDLType>
inline void DOMPromiseProxyWithResolveCallback<IDLType>::clear()
{
m_valueOrException = std::nullopt;
m_deferredPromises.clear();
}
template<typename IDLType>
inline bool DOMPromiseProxyWithResolveCallback<IDLType>::isFulfilled() const
{
return m_valueOrException.has_value();
}
template<typename IDLType>
inline void DOMPromiseProxyWithResolveCallback<IDLType>::resolve(typename IDLType::ParameterType value)
{
ASSERT(!m_valueOrException);
m_valueOrException = ExceptionOr<void> { };
for (auto& deferredPromise : m_deferredPromises)
deferredPromise->template resolve<IDLType>(value);
}
template<typename IDLType>
inline void DOMPromiseProxyWithResolveCallback<IDLType>::resolveWithNewlyCreated(typename IDLType::ParameterType value)
{
ASSERT(!m_valueOrException);
m_valueOrException = ExceptionOr<void> { };
for (auto& deferredPromise : m_deferredPromises)
deferredPromise->template resolveWithNewlyCreated<IDLType>(value);
}
template<typename IDLType>
inline void DOMPromiseProxyWithResolveCallback<IDLType>::reject(Exception exception, RejectAsHandled rejectAsHandled)
{
ASSERT(!m_valueOrException);
m_valueOrException = ExceptionOr<void> { WTFMove(exception) };
for (auto& deferredPromise : m_deferredPromises)
deferredPromise->reject(m_valueOrException->exception(), rejectAsHandled);
}
}

View File

@@ -0,0 +1 @@
// stub

View File

@@ -0,0 +1,137 @@
/*
* Copyright (C) 2009 Google Inc. All rights reserved.
* Copyright (C) 2016 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#include "DedicatedWorkerGlobalScope.h"
#include "ContentSecurityPolicyResponseHeaders.h"
#include "DOMWindow.h"
#include "DedicatedWorkerThread.h"
#include "EventNames.h"
#include "JSRTCRtpScriptTransformer.h"
#include "MessageEvent.h"
#include "RTCTransformEvent.h"
#include "RequestAnimationFrameCallback.h"
#include "SecurityOrigin.h"
#include "StructuredSerializeOptions.h"
#include "Worker.h"
#if ENABLE(OFFSCREEN_CANVAS)
#include "WorkerAnimationController.h"
#endif
#include "WorkerObjectProxy.h"
#include <wtf/IsoMallocInlines.h>
namespace WebCore {
WTF_MAKE_ISO_ALLOCATED_IMPL(DedicatedWorkerGlobalScope);
Ref<DedicatedWorkerGlobalScope> DedicatedWorkerGlobalScope::create(const WorkerParameters& params, Ref<SecurityOrigin>&& origin, DedicatedWorkerThread& thread, Ref<SecurityOrigin>&& topOrigin, IDBClient::IDBConnectionProxy* connectionProxy, SocketProvider* socketProvider)
{
auto context = adoptRef(*new DedicatedWorkerGlobalScope(params, WTFMove(origin), thread, WTFMove(topOrigin), connectionProxy, socketProvider));
if (!params.shouldBypassMainWorldContentSecurityPolicy)
context->applyContentSecurityPolicyResponseHeaders(params.contentSecurityPolicyResponseHeaders);
return context;
}
DedicatedWorkerGlobalScope::DedicatedWorkerGlobalScope(const WorkerParameters& params, Ref<SecurityOrigin>&& origin, DedicatedWorkerThread& thread, Ref<SecurityOrigin>&& topOrigin, IDBClient::IDBConnectionProxy* connectionProxy, SocketProvider* socketProvider)
: WorkerGlobalScope(WorkerThreadType::DedicatedWorker, params, WTFMove(origin), thread, WTFMove(topOrigin), connectionProxy, socketProvider)
, m_name(params.name)
{
}
DedicatedWorkerGlobalScope::~DedicatedWorkerGlobalScope() = default;
EventTargetInterface DedicatedWorkerGlobalScope::eventTargetInterface() const
{
return DedicatedWorkerGlobalScopeEventTargetInterfaceType;
}
void DedicatedWorkerGlobalScope::prepareForDestruction()
{
WorkerGlobalScope::prepareForDestruction();
}
ExceptionOr<void> DedicatedWorkerGlobalScope::postMessage(JSC::JSGlobalObject& state, JSC::JSValue messageValue, StructuredSerializeOptions&& options)
{
Vector<RefPtr<MessagePort>> ports;
auto message = SerializedScriptValue::create(state, messageValue, WTFMove(options.transfer), ports, SerializationContext::WorkerPostMessage);
if (message.hasException())
return message.releaseException();
// Disentangle the port in preparation for sending it to the remote context.
auto channels = MessagePort::disentanglePorts(WTFMove(ports));
if (channels.hasException())
return channels.releaseException();
thread().workerObjectProxy().postMessageToWorkerObject({ message.releaseReturnValue(), channels.releaseReturnValue() });
return { };
}
ExceptionOr<void> DedicatedWorkerGlobalScope::importScripts(const FixedVector<String>& urls)
{
auto result = Base::importScripts(urls);
thread().workerObjectProxy().reportPendingActivity(hasPendingActivity());
return result;
}
DedicatedWorkerThread& DedicatedWorkerGlobalScope::thread()
{
return static_cast<DedicatedWorkerThread&>(Base::thread());
}
#if ENABLE(OFFSCREEN_CANVAS)
CallbackId DedicatedWorkerGlobalScope::requestAnimationFrame(Ref<RequestAnimationFrameCallback>&& callback)
{
if (!m_workerAnimationController)
m_workerAnimationController = WorkerAnimationController::create(*this);
return m_workerAnimationController->requestAnimationFrame(WTFMove(callback));
}
void DedicatedWorkerGlobalScope::cancelAnimationFrame(CallbackId callbackId)
{
if (m_workerAnimationController)
m_workerAnimationController->cancelAnimationFrame(callbackId);
}
#endif
#if ENABLE(WEB_RTC)
RefPtr<RTCRtpScriptTransformer> DedicatedWorkerGlobalScope::createRTCRtpScriptTransformer(MessageWithMessagePorts&& options)
{
auto transformerOrException = RTCRtpScriptTransformer::create(*this, WTFMove(options));
if (transformerOrException.hasException())
return nullptr;
auto transformer = transformerOrException.releaseReturnValue();
dispatchEvent(RTCTransformEvent::create(eventNames().rtctransformEvent, transformer.copyRef(), Event::IsTrusted::Yes));
return transformer;
}
#endif
} // namespace WebCore

View File

@@ -0,0 +1,110 @@
/*
* Copyright (C) 2009 Google Inc. All rights reserved.
* Copyright (C) 2016 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#pragma once
#include "MessagePort.h"
#include "WorkerGlobalScope.h"
namespace JSC {
class CallFrame;
class JSObject;
class JSValue;
}
namespace WebCore {
class ContentSecurityPolicyResponseHeaders;
class DedicatedWorkerThread;
class JSRTCRtpScriptTransformerConstructor;
class RTCRtpScriptTransformer;
class RequestAnimationFrameCallback;
class SerializedScriptValue;
struct StructuredSerializeOptions;
#if ENABLE(OFFSCREEN_CANVAS_IN_WORKERS)
class WorkerAnimationController;
using CallbackId = int;
#endif
using TransferredMessagePort = std::pair<WebCore::MessagePortIdentifier, WebCore::MessagePortIdentifier>;
class DedicatedWorkerGlobalScope final : public WorkerGlobalScope {
WTF_MAKE_ISO_ALLOCATED(DedicatedWorkerGlobalScope);
public:
static Ref<DedicatedWorkerGlobalScope> create(const WorkerParameters&, Ref<SecurityOrigin>&&, DedicatedWorkerThread&, Ref<SecurityOrigin>&& topOrigin, IDBClient::IDBConnectionProxy*, SocketProvider*);
virtual ~DedicatedWorkerGlobalScope();
const String& name() const { return m_name; }
ExceptionOr<void> postMessage(JSC::JSGlobalObject&, JSC::JSValue message, StructuredSerializeOptions&&);
DedicatedWorkerThread& thread();
// #if ENABLE(OFFSCREEN_CANVAS_IN_WORKERS)
// CallbackId requestAnimationFrame(Ref<RequestAnimationFrameCallback>&&);
// void cancelAnimationFrame(CallbackId);
// #endif
// #if ENABLE(WEB_RTC)
// RefPtr<RTCRtpScriptTransformer> createRTCRtpScriptTransformer(MessageWithMessagePorts&&);
// #endif
FetchOptions::Destination destination() const final { return FetchOptions::Destination::Worker; }
private:
using Base = WorkerGlobalScope;
DedicatedWorkerGlobalScope(const WorkerParameters&, Ref<SecurityOrigin>&&, DedicatedWorkerThread&, Ref<SecurityOrigin>&& topOrigin, IDBClient::IDBConnectionProxy*, SocketProvider*);
Type type() const final { return Type::DedicatedWorker; }
ExceptionOr<void> importScripts(const FixedVector<String>& urls) final;
EventTargetInterface eventTargetInterface() const final;
void prepareForDestruction() final;
String m_name;
// #if ENABLE(OFFSCREEN_CANVAS_IN_WORKERS)
// RefPtr<WorkerAnimationController> m_workerAnimationController;
// #endif
};
} // namespace WebCore
SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::DedicatedWorkerGlobalScope)
static bool isType(const WebCore::ScriptExecutionContext& context) { return is<WebCore::WorkerGlobalScope>(context) && downcast<WebCore::WorkerGlobalScope>(context).type() == WebCore::WorkerGlobalScope::Type::DedicatedWorker; }
static bool isType(const WebCore::WorkerGlobalScope& context) { return context.type() == WebCore::WorkerGlobalScope::Type::DedicatedWorker; }
SPECIALIZE_TYPE_TRAITS_END()

View File

@@ -0,0 +1,49 @@
/*
* Copyright (C) 2009, 2011 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
[
Exposed=DedicatedWorker,
Global=(Worker,DedicatedWorker),
JSGenerateToNativeObject,
IsImmutablePrototypeExoticObject,
IsImmutablePrototypeExoticObjectOnPrototype,
] interface DedicatedWorkerGlobalScope : WorkerGlobalScope {
[Replaceable] readonly attribute DOMString name;
[CallWith=CurrentGlobalObject] undefined postMessage(any message, sequence<object> transfer);
[CallWith=CurrentGlobalObject] undefined postMessage(any message, optional StructuredSerializeOptions options);
undefined close();
attribute EventHandler onmessage;
};
[Conditional=OFFSCREEN_CANVAS_IN_WORKERS, EnabledAtRuntime=OffscreenCanvasInWorkersEnabled] DedicatedWorkerGlobalScope includes AnimationFrameProvider;
[Conditional=WEB_RTC, EnabledBySetting=WebRTCEncodedTransformEnabled] DedicatedWorkerGlobalScope includes RTCRtpScriptTransformProvider;

View File

@@ -0,0 +1,61 @@
/*
* Copyright (C) 2009 Google Inc. All rights reserved.
* Copyright (C) 2016 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#include "DedicatedWorkerThread.h"
#include "DedicatedWorkerGlobalScope.h"
#include "SecurityOrigin.h"
#include "WorkerObjectProxy.h"
namespace WebCore {
DedicatedWorkerThread::DedicatedWorkerThread(const WorkerParameters& params, const ScriptBuffer& sourceCode, WorkerLoaderProxy& workerLoaderProxy, WorkerDebuggerProxy& workerDebuggerProxy, WorkerObjectProxy& workerObjectProxy, WorkerThreadStartMode startMode, const SecurityOrigin& topOrigin, IDBClient::IDBConnectionProxy* connectionProxy, SocketProvider* socketProvider, JSC::RuntimeFlags runtimeFlags)
: WorkerThread(params, sourceCode, workerLoaderProxy, workerDebuggerProxy, workerObjectProxy, startMode, topOrigin, connectionProxy, socketProvider, runtimeFlags)
, m_workerObjectProxy(workerObjectProxy)
{
}
DedicatedWorkerThread::~DedicatedWorkerThread() = default;
Ref<WorkerGlobalScope> DedicatedWorkerThread::createWorkerGlobalScope(const WorkerParameters& params, /*Ref<SecurityOrigin>&& origin,*/ Ref<SecurityOrigin>&& topOrigin)
{
return DedicatedWorkerGlobalScope::create(params, WTFMove(origin), *this, WTFMove(topOrigin), idbConnectionProxy(), socketProvider());
}
void DedicatedWorkerThread::runEventLoop()
{
// Notify the parent object of our current active state before calling the superclass to run the event loop.
m_workerObjectProxy.reportPendingActivity(globalScope()->hasPendingActivity());
WorkerThread::runEventLoop();
}
} // namespace WebCore

View File

@@ -0,0 +1,65 @@
/*
* Copyright (C) 2009 Google Inc. All rights reserved.
* Copyright (C) 2016 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#pragma once
#include "WorkerThread.h"
namespace WebCore {
class ContentSecurityPolicyResponseHeaders;
class ScriptBuffer;
class WorkerObjectProxy;
class DedicatedWorkerThread : public WorkerThread {
public:
template<typename... Args> static Ref<DedicatedWorkerThread> create(Args&&... args)
{
return adoptRef(*new DedicatedWorkerThread(std::forward<Args>(args)...));
}
virtual ~DedicatedWorkerThread();
WorkerObjectProxy& workerObjectProxy() const { return m_workerObjectProxy; }
void start() { WorkerThread::start(nullptr); }
protected:
Ref<WorkerGlobalScope> createWorkerGlobalScope(const WorkerParameters&, Ref<SecurityOrigin>&&, Ref<SecurityOrigin>&& topOrigin) override;
void runEventLoop() override;
private:
DedicatedWorkerThread(const WorkerParameters&, const ScriptBuffer& sourceCode, WorkerLoaderProxy&, WorkerDebuggerProxy&, WorkerObjectProxy&, WorkerThreadStartMode, const SecurityOrigin& topOrigin, IDBClient::IDBConnectionProxy*, SocketProvider*, JSC::RuntimeFlags);
ASCIILiteral threadName() const final { return "WebCore: Worker"_s; }
WorkerObjectProxy& m_workerObjectProxy;
};
} // namespace WebCore

View File

@@ -0,0 +1,191 @@
/*
* Copyright (C) 2019 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#include "EventLoop.h"
#include "Microtasks.h"
namespace WebCore {
void EventLoop::queueTask(std::unique_ptr<EventLoopTask>&& task)
{
ASSERT(task->taskSource() != TaskSource::Microtask);
ASSERT(task->group());
ASSERT(isContextThread());
scheduleToRunIfNeeded();
m_tasks.append(WTFMove(task));
}
void EventLoop::queueMicrotask(std::unique_ptr<EventLoopTask>&& microtask)
{
ASSERT(microtask->taskSource() == TaskSource::Microtask);
microtaskQueue().append(WTFMove(microtask));
scheduleToRunIfNeeded(); // FIXME: Remove this once everything is integrated with the event loop.
}
void EventLoop::performMicrotaskCheckpoint()
{
microtaskQueue().performMicrotaskCheckpoint();
}
void EventLoop::resumeGroup(EventLoopTaskGroup& group)
{
ASSERT(isContextThread());
if (!m_groupsWithSuspendedTasks.contains(group))
return;
scheduleToRunIfNeeded();
}
void EventLoop::registerGroup(EventLoopTaskGroup& group)
{
ASSERT(isContextThread());
m_associatedGroups.add(group);
}
void EventLoop::unregisterGroup(EventLoopTaskGroup& group)
{
ASSERT(isContextThread());
if (m_associatedGroups.remove(group))
stopAssociatedGroupsIfNecessary();
}
void EventLoop::stopAssociatedGroupsIfNecessary()
{
ASSERT(isContextThread());
for (auto& group : m_associatedGroups) {
if (!group.isReadyToStop())
return;
}
auto associatedGroups = std::exchange(m_associatedGroups, { });
for (auto& group : associatedGroups)
group.stopAndDiscardAllTasks();
}
void EventLoop::stopGroup(EventLoopTaskGroup& group)
{
ASSERT(isContextThread());
m_tasks.removeAllMatching([&group] (auto& task) {
return group.matchesTask(*task);
});
}
void EventLoop::scheduleToRunIfNeeded()
{
if (m_isScheduledToRun)
return;
m_isScheduledToRun = true;
scheduleToRun();
}
void EventLoop::run()
{
m_isScheduledToRun = false;
bool didPerformMicrotaskCheckpoint = false;
if (!m_tasks.isEmpty()) {
auto tasks = std::exchange(m_tasks, { });
m_groupsWithSuspendedTasks.clear();
Vector<std::unique_ptr<EventLoopTask>> remainingTasks;
for (auto& task : tasks) {
auto* group = task->group();
if (!group || group->isStoppedPermanently())
continue;
if (group->isSuspended()) {
m_groupsWithSuspendedTasks.add(*group);
remainingTasks.append(WTFMove(task));
continue;
}
task->execute();
didPerformMicrotaskCheckpoint = true;
microtaskQueue().performMicrotaskCheckpoint();
}
for (auto& task : m_tasks)
remainingTasks.append(WTFMove(task));
m_tasks = WTFMove(remainingTasks);
}
// FIXME: Remove this once everything is integrated with the event loop.
if (!didPerformMicrotaskCheckpoint)
microtaskQueue().performMicrotaskCheckpoint();
}
void EventLoop::clearAllTasks()
{
m_tasks.clear();
m_groupsWithSuspendedTasks.clear();
}
void EventLoopTaskGroup::queueTask(std::unique_ptr<EventLoopTask>&& task)
{
if (m_state == State::Stopped || !m_eventLoop)
return;
ASSERT(task->group() == this);
m_eventLoop->queueTask(WTFMove(task));
}
class EventLoopFunctionDispatchTask : public EventLoopTask {
public:
EventLoopFunctionDispatchTask(TaskSource source, EventLoopTaskGroup& group, EventLoop::TaskFunction&& function)
: EventLoopTask(source, group)
, m_function(WTFMove(function))
{
}
void execute() final { m_function(); }
private:
EventLoop::TaskFunction m_function;
};
void EventLoopTaskGroup::queueTask(TaskSource source, EventLoop::TaskFunction&& function)
{
return queueTask(makeUnique<EventLoopFunctionDispatchTask>(source, *this, WTFMove(function)));
}
void EventLoopTaskGroup::queueMicrotask(EventLoop::TaskFunction&& function)
{
if (m_state == State::Stopped || !m_eventLoop)
return;
m_eventLoop->queueMicrotask(makeUnique<EventLoopFunctionDispatchTask>(TaskSource::Microtask, *this, WTFMove(function)));
}
void EventLoopTaskGroup::performMicrotaskCheckpoint()
{
if (m_eventLoop)
m_eventLoop->performMicrotaskCheckpoint();
}
void EventLoopTaskGroup::runAtEndOfMicrotaskCheckpoint(EventLoop::TaskFunction&& function)
{
if (m_state == State::Stopped || !m_eventLoop)
return;
microtaskQueue().addCheckpointTask(makeUnique<EventLoopFunctionDispatchTask>(TaskSource::IndexedDB, *this, WTFMove(function)));
}
} // namespace WebCore

View File

@@ -0,0 +1,206 @@
/*
* Copyright (C) 2019 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#pragma once
#include "TaskSource.h"
#include <wtf/Function.h>
#include <wtf/RefCounted.h>
#include <wtf/StdLibExtras.h>
#include <wtf/WeakHashSet.h>
#include <wtf/WeakPtr.h>
namespace WebCore {
class ActiveDOMCallbackMicrotask;
class EventLoopTaskGroup;
class EventTarget;
class MicrotaskQueue;
class ScriptExecutionContext;
class EventLoopTask {
WTF_MAKE_NONCOPYABLE(EventLoopTask);
WTF_MAKE_FAST_ALLOCATED;
public:
virtual ~EventLoopTask() = default;
TaskSource taskSource() { return m_taskSource; }
virtual void execute() = 0;
EventLoopTaskGroup* group() const { return m_group.get(); }
protected:
EventLoopTask(TaskSource, EventLoopTaskGroup&);
private:
const TaskSource m_taskSource;
WeakPtr<EventLoopTaskGroup> m_group;
};
// https://html.spec.whatwg.org/multipage/webappapis.html#event-loop
class EventLoop : public RefCounted<EventLoop>, public CanMakeWeakPtr<EventLoop> {
public:
virtual ~EventLoop() = default;
typedef Function<void ()> TaskFunction;
void queueTask(std::unique_ptr<EventLoopTask>&&);
// https://html.spec.whatwg.org/multipage/webappapis.html#queue-a-microtask
void queueMicrotask(std::unique_ptr<EventLoopTask>&&);
// https://html.spec.whatwg.org/multipage/webappapis.html#perform-a-microtask-checkpoint
void performMicrotaskCheckpoint();
virtual MicrotaskQueue& microtaskQueue() = 0;
void resumeGroup(EventLoopTaskGroup&);
void stopGroup(EventLoopTaskGroup&);
void registerGroup(EventLoopTaskGroup&);
void unregisterGroup(EventLoopTaskGroup&);
void stopAssociatedGroupsIfNecessary();
protected:
EventLoop() = default;
void run();
void clearAllTasks();
private:
void scheduleToRunIfNeeded();
virtual void scheduleToRun() = 0;
virtual bool isContextThread() const = 0;
// Use a global queue instead of multiple task queues since HTML5 spec allows UA to pick arbitrary queue.
Vector<std::unique_ptr<EventLoopTask>> m_tasks;
WeakHashSet<EventLoopTaskGroup> m_associatedGroups;
WeakHashSet<EventLoopTaskGroup> m_groupsWithSuspendedTasks;
bool m_isScheduledToRun { false };
};
class EventLoopTaskGroup : public CanMakeWeakPtr<EventLoopTaskGroup> {
WTF_MAKE_NONCOPYABLE(EventLoopTaskGroup);
WTF_MAKE_FAST_ALLOCATED;
public:
EventLoopTaskGroup(EventLoop& eventLoop)
: m_eventLoop(eventLoop)
{
eventLoop.registerGroup(*this);
}
~EventLoopTaskGroup()
{
if (auto* eventLoop = m_eventLoop.get())
eventLoop->unregisterGroup(*this);
}
bool hasSameEventLoopAs(EventLoopTaskGroup& otherGroup)
{
ASSERT(m_eventLoop);
return m_eventLoop == otherGroup.m_eventLoop;
}
bool matchesTask(EventLoopTask& task) const
{
auto* group = task.group();
return group == this;
}
// Marks the group as ready to stop but it won't actually be stopped
// until all groups in this event loop are ready to stop.
void markAsReadyToStop()
{
if (isReadyToStop() || isStoppedPermanently())
return;
bool wasSuspended = isSuspended();
m_state = State::ReadyToStop;
if (auto* eventLoop = m_eventLoop.get())
eventLoop->stopAssociatedGroupsIfNecessary();
if (wasSuspended && !isStoppedPermanently()) {
// We we get marked as ready to stop while suspended (happens when a CachedPage gets destroyed) then the
// queued tasks will never be able to run (since tasks don't run while suspended and we will never resume).
// As a result, we can simply discard our tasks and stop permanently.
stopAndDiscardAllTasks();
}
}
// This gets called by the event loop when all groups in the EventLoop as ready to stop.
void stopAndDiscardAllTasks()
{
ASSERT(isReadyToStop());
m_state = State::Stopped;
if (auto* eventLoop = m_eventLoop.get())
eventLoop->stopGroup(*this);
}
void suspend()
{
ASSERT(!isStoppedPermanently());
ASSERT(!isReadyToStop());
m_state = State::Suspended;
// We don't remove suspended tasks to preserve the ordering.
// EventLoop::run checks whether each task's group is suspended or not.
}
void resume()
{
ASSERT(!isStoppedPermanently());
ASSERT(!isReadyToStop());
m_state = State::Running;
if (auto* eventLoop = m_eventLoop.get())
eventLoop->resumeGroup(*this);
}
bool isStoppedPermanently() const { return m_state == State::Stopped; }
bool isSuspended() const { return m_state == State::Suspended; }
bool isReadyToStop() const { return m_state == State::ReadyToStop; }
void queueTask(std::unique_ptr<EventLoopTask>&&);
WEBCORE_EXPORT void queueTask(TaskSource, EventLoop::TaskFunction&&);
// https://html.spec.whatwg.org/multipage/webappapis.html#queue-a-microtask
WEBCORE_EXPORT void queueMicrotask(EventLoop::TaskFunction&&);
MicrotaskQueue& microtaskQueue() { return m_eventLoop->microtaskQueue(); }
// https://html.spec.whatwg.org/multipage/webappapis.html#perform-a-microtask-checkpoint
void performMicrotaskCheckpoint();
void runAtEndOfMicrotaskCheckpoint(EventLoop::TaskFunction&&);
private:
enum class State : uint8_t { Running, Suspended, ReadyToStop, Stopped };
WeakPtr<EventLoop> m_eventLoop;
State m_state { State::Running };
};
inline EventLoopTask::EventLoopTask(TaskSource source, EventLoopTaskGroup& group)
: m_taskSource(source)
, m_group(group)
{ }
} // namespace WebCore

View File

@@ -31,8 +31,10 @@ namespace WebCore {
#define DOM_EVENT_NAMES_FOR_EACH(macro) \
macro(error) \
macro(abort)
//
macro(abort) \
macro(unhandledrejection) \
macro(message)
// end of DOM_EVENT_NAMES_FOR_EACH
// macro(DOMActivate) \
// macro(DOMCharacterDataModified) \

View File

@@ -0,0 +1,35 @@
/*
* Copyright (C) 2017 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#pragma once
#include "FetchOptions.h"
namespace WebCore {
using FetchRequestCredentials = FetchOptions::Credentials;
}

View File

@@ -0,0 +1,26 @@
/*
* Copyright (C) 2017 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
enum FetchRequestCredentials { "omit", "same-origin", "include" };

View File

@@ -0,0 +1,78 @@
/*
* Copyright (C) 2017-2021 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#include "JSDOMGuardedObject.h"
namespace WebCore {
using namespace JSC;
DOMGuardedObject::DOMGuardedObject(JSDOMGlobalObject& globalObject, JSCell& guarded)
: ActiveDOMCallback(globalObject.scriptExecutionContext())
, m_guarded(&guarded)
, m_globalObject(&globalObject)
{
globalObject.vm().writeBarrier(&globalObject, &guarded);
if (globalObject.vm().heap.mutatorShouldBeFenced()) {
Locker locker { globalObject.gcLock() };
globalObject.guardedObjects().add(this);
return;
}
globalObject.guardedObjects(NoLockingNecessary).add(this);
}
DOMGuardedObject::~DOMGuardedObject()
{
clear();
}
void DOMGuardedObject::clear()
{
ASSERT(!m_guarded || m_globalObject);
removeFromGlobalObject();
m_guarded.clear();
m_globalObject.clear();
}
void DOMGuardedObject::removeFromGlobalObject()
{
if (!m_guarded || !m_globalObject)
return;
if (m_globalObject->vm().heap.mutatorShouldBeFenced()) {
Locker locker { m_globalObject->gcLock() };
m_globalObject->guardedObjects().remove(this);
} else
m_globalObject->guardedObjects(NoLockingNecessary).remove(this);
}
void DOMGuardedObject::contextDestroyed()
{
ActiveDOMCallback::contextDestroyed();
clear();
}
}

View File

@@ -0,0 +1,69 @@
/*
* Copyright (C) 2017-2021 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#pragma once
#include "ActiveDOMCallback.h"
#include "JSDOMGlobalObject.h"
#include <JavaScriptCore/HeapInlines.h>
#include <JavaScriptCore/JSCell.h>
#include <JavaScriptCore/SlotVisitorInlines.h>
#include <JavaScriptCore/StrongInlines.h>
namespace WebCore {
class WEBCORE_EXPORT DOMGuardedObject : public RefCounted<DOMGuardedObject>, public ActiveDOMCallback {
public:
~DOMGuardedObject();
bool isSuspended() const { return !m_guarded || !canInvokeCallback(); } // The wrapper world has gone away or active DOM objects have been suspended.
template<typename Visitor> void visitAggregate(Visitor& visitor) { visitor.append(m_guarded); }
JSC::JSValue guardedObject() const { return m_guarded.get(); }
JSDOMGlobalObject* globalObject() const { return m_globalObject.get(); }
void clear();
protected:
DOMGuardedObject(JSDOMGlobalObject&, JSC::JSCell&);
void contextDestroyed() override;
bool isEmpty() const { return !m_guarded; }
JSC::Weak<JSC::JSCell> m_guarded;
JSC::Weak<JSDOMGlobalObject> m_globalObject;
private:
void removeFromGlobalObject();
};
template <typename T> class DOMGuarded : public DOMGuardedObject {
protected:
DOMGuarded(JSDOMGlobalObject& globalObject, T& guarded) : DOMGuardedObject(globalObject, guarded) { }
T* guarded() const { return JSC::jsDynamicCast<T*>(globalObject()->vm(), guardedObject()); }
};
} // namespace WebCore

View File

@@ -0,0 +1,97 @@
/*
* Copyright (C) 2017-2021 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#include "JSDOMPromise.h"
// #include "DOMWindow.h"
// #include "JSDOMWindow.h"
#include <JavaScriptCore/BuiltinNames.h>
#include <JavaScriptCore/CatchScope.h>
#include <JavaScriptCore/Exception.h>
#include <JavaScriptCore/JSNativeStdFunction.h>
#include <JavaScriptCore/JSPromiseConstructor.h>
using namespace JSC;
namespace WebCore {
auto DOMPromise::whenSettled(std::function<void()>&& callback) -> IsCallbackRegistered
{
return whenPromiseIsSettled(globalObject(), promise(), WTFMove(callback));
}
auto DOMPromise::whenPromiseIsSettled(JSDOMGlobalObject* globalObject, JSC::JSObject* promise, Function<void()>&& callback) -> IsCallbackRegistered
{
auto& lexicalGlobalObject = *globalObject;
auto& vm = lexicalGlobalObject.vm();
JSLockHolder lock(vm);
auto* handler = JSC::JSNativeStdFunction::create(vm, globalObject, 1, String {}, [callback = WTFMove(callback)](JSGlobalObject*, CallFrame*) mutable {
callback();
return JSC::JSValue::encode(JSC::jsUndefined());
});
auto scope = DECLARE_THROW_SCOPE(vm);
const JSC::Identifier& privateName = vm.propertyNames->builtinNames().thenPrivateName();
auto thenFunction = promise->get(&lexicalGlobalObject, privateName);
EXCEPTION_ASSERT(!scope.exception() || vm.hasPendingTerminationException());
if (scope.exception())
return IsCallbackRegistered::No;
ASSERT(thenFunction.isCallable(vm));
JSC::MarkedArgumentBuffer arguments;
arguments.append(handler);
arguments.append(handler);
auto callData = JSC::getCallData(vm, thenFunction);
ASSERT(callData.type != JSC::CallData::Type::None);
call(&lexicalGlobalObject, thenFunction, callData, promise, arguments);
EXCEPTION_ASSERT(!scope.exception() || vm.hasPendingTerminationException());
return scope.exception() ? IsCallbackRegistered::No : IsCallbackRegistered::Yes;
}
JSC::JSValue DOMPromise::result() const
{
return promise()->result(m_globalObject->vm());
}
DOMPromise::Status DOMPromise::status() const
{
switch (promise()->status(m_globalObject->vm())) {
case JSC::JSPromise::Status::Pending:
return Status::Pending;
case JSC::JSPromise::Status::Fulfilled:
return Status::Fulfilled;
case JSC::JSPromise::Status::Rejected:
return Status::Rejected;
};
ASSERT_NOT_REACHED();
return Status::Rejected;
}
}

View File

@@ -0,0 +1,63 @@
/*
* Copyright (C) 2013-2017 Apple Inc. All rights reserved.
* Copyright (C) 2017 Yusuke Suzuki <utatane.tea@gmail.com>.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#pragma once
#include "JSDOMGuardedObject.h"
#include <JavaScriptCore/JSPromise.h>
namespace WebCore {
class DOMPromise : public DOMGuarded<JSC::JSPromise> {
public:
static Ref<DOMPromise> create(JSDOMGlobalObject& globalObject, JSC::JSPromise& promise)
{
return adoptRef(*new DOMPromise(globalObject, promise));
}
JSC::JSPromise* promise() const
{
ASSERT(!isSuspended());
return guarded();
}
enum class IsCallbackRegistered { No, Yes };
IsCallbackRegistered whenSettled(std::function<void()>&&);
JSC::JSValue result() const;
enum class Status { Pending, Fulfilled, Rejected };
Status status() const;
static IsCallbackRegistered whenPromiseIsSettled(JSDOMGlobalObject*, JSC::JSObject* promise, Function<void()>&&);
private:
DOMPromise(JSDOMGlobalObject& globalObject, JSC::JSPromise& promise)
: DOMGuarded<JSC::JSPromise>(globalObject, promise)
{
}
};
} // namespace WebCore

View File

@@ -0,0 +1,300 @@
/*
* Copyright (C) 2013-2021 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#include "JSDOMPromiseDeferred.h"
#include "DOMWindow.h"
#include "EventLoop.h"
#include "JSDOMExceptionHandling.h"
#include "JSDOMPromise.h"
#include "JSDOMWindow.h"
// #include "ScriptController.h"
#include "WorkerGlobalScope.h"
#include <JavaScriptCore/BuiltinNames.h>
#include <JavaScriptCore/Exception.h>
#include <JavaScriptCore/JSONObject.h>
#include <JavaScriptCore/JSPromiseConstructor.h>
#include <JavaScriptCore/Strong.h>
namespace WebCore {
using namespace JSC;
JSC::JSValue DeferredPromise::promise() const
{
if (isEmpty())
return jsUndefined();
ASSERT(deferred());
return deferred();
}
void DeferredPromise::callFunction(JSGlobalObject& lexicalGlobalObject, ResolveMode mode, JSValue resolution)
{
if (shouldIgnoreRequestToFulfill())
return;
if (activeDOMObjectsAreSuspended()) {
JSC::Strong<JSC::Unknown, ShouldStrongDestructorGrabLock::Yes> strongResolution(lexicalGlobalObject.vm(), resolution);
ASSERT(scriptExecutionContext()->eventLoop().isSuspended());
scriptExecutionContext()->eventLoop().queueTask(TaskSource::Networking, [this, protectedThis = Ref { *this }, mode, strongResolution = WTFMove(strongResolution)]() mutable {
if (shouldIgnoreRequestToFulfill())
return;
JSC::JSGlobalObject* lexicalGlobalObject = globalObject();
JSC::JSLockHolder locker(lexicalGlobalObject);
callFunction(*globalObject(), mode, strongResolution.get());
});
return;
}
// FIXME: We could have error since any JS call can throw stack-overflow errors.
// https://bugs.webkit.org/show_bug.cgi?id=203402
switch (mode) {
case ResolveMode::Resolve:
deferred()->resolve(&lexicalGlobalObject, resolution);
break;
case ResolveMode::Reject:
deferred()->reject(&lexicalGlobalObject, resolution);
break;
case ResolveMode::RejectAsHandled:
deferred()->rejectAsHandled(&lexicalGlobalObject, resolution);
break;
}
if (m_mode == Mode::ClearPromiseOnResolve)
clear();
}
void DeferredPromise::whenSettled(Function<void()>&& callback)
{
if (shouldIgnoreRequestToFulfill())
return;
if (activeDOMObjectsAreSuspended()) {
scriptExecutionContext()->eventLoop().queueTask(TaskSource::Networking, [this, protectedThis = Ref { *this }, callback = WTFMove(callback)]() mutable {
whenSettled(WTFMove(callback));
});
return;
}
DOMPromise::whenPromiseIsSettled(globalObject(), deferred(), WTFMove(callback));
}
void DeferredPromise::reject(RejectAsHandled rejectAsHandled)
{
if (shouldIgnoreRequestToFulfill())
return;
ASSERT(deferred());
ASSERT(m_globalObject);
auto& lexicalGlobalObject = *m_globalObject;
JSC::JSLockHolder locker(&lexicalGlobalObject);
reject(lexicalGlobalObject, JSC::jsUndefined(), rejectAsHandled);
}
void DeferredPromise::reject(std::nullptr_t, RejectAsHandled rejectAsHandled)
{
if (shouldIgnoreRequestToFulfill())
return;
ASSERT(deferred());
ASSERT(m_globalObject);
auto& lexicalGlobalObject = *m_globalObject;
JSC::JSLockHolder locker(&lexicalGlobalObject);
reject(lexicalGlobalObject, JSC::jsNull(), rejectAsHandled);
}
void DeferredPromise::reject(Exception exception, RejectAsHandled rejectAsHandled)
{
if (shouldIgnoreRequestToFulfill())
return;
Ref protectedThis(*this);
ASSERT(deferred());
ASSERT(m_globalObject);
auto& lexicalGlobalObject = *m_globalObject;
JSC::VM& vm = lexicalGlobalObject.vm();
JSC::JSLockHolder locker(vm);
auto scope = DECLARE_CATCH_SCOPE(vm);
if (exception.code() == ExistingExceptionError) {
EXCEPTION_ASSERT(scope.exception());
auto error = scope.exception()->value();
bool isTerminating = handleTerminationExceptionIfNeeded(scope, lexicalGlobalObject);
scope.clearException();
if (!isTerminating)
reject<IDLAny>(error, rejectAsHandled);
return;
}
auto error = createDOMException(lexicalGlobalObject, WTFMove(exception));
if (UNLIKELY(scope.exception())) {
handleUncaughtException(scope, lexicalGlobalObject);
return;
}
reject(lexicalGlobalObject, error, rejectAsHandled);
if (UNLIKELY(scope.exception()))
handleUncaughtException(scope, lexicalGlobalObject);
}
void DeferredPromise::reject(ExceptionCode ec, const String& message, RejectAsHandled rejectAsHandled)
{
if (shouldIgnoreRequestToFulfill())
return;
Ref protectedThis(*this);
ASSERT(deferred());
ASSERT(m_globalObject);
auto& lexicalGlobalObject = *m_globalObject;
JSC::VM& vm = lexicalGlobalObject.vm();
JSC::JSLockHolder locker(vm);
auto scope = DECLARE_CATCH_SCOPE(vm);
if (ec == ExistingExceptionError) {
EXCEPTION_ASSERT(scope.exception());
auto error = scope.exception()->value();
bool isTerminating = handleTerminationExceptionIfNeeded(scope, lexicalGlobalObject);
scope.clearException();
if (!isTerminating)
reject<IDLAny>(error, rejectAsHandled);
return;
}
auto error = createDOMException(&lexicalGlobalObject, ec, message);
if (UNLIKELY(scope.exception())) {
handleUncaughtException(scope, lexicalGlobalObject);
return;
}
reject(lexicalGlobalObject, error, rejectAsHandled);
if (UNLIKELY(scope.exception()))
handleUncaughtException(scope, lexicalGlobalObject);
}
void DeferredPromise::reject(const JSC::PrivateName& privateName, RejectAsHandled rejectAsHandled)
{
if (shouldIgnoreRequestToFulfill())
return;
ASSERT(deferred());
ASSERT(m_globalObject);
JSC::JSGlobalObject* lexicalGlobalObject = m_globalObject.get();
JSC::JSLockHolder locker(lexicalGlobalObject);
reject(*lexicalGlobalObject, JSC::Symbol::create(lexicalGlobalObject->vm(), privateName.uid()), rejectAsHandled);
}
void rejectPromiseWithExceptionIfAny(JSC::JSGlobalObject& lexicalGlobalObject, JSDOMGlobalObject& globalObject, JSPromise& promise, JSC::CatchScope& catchScope)
{
UNUSED_PARAM(lexicalGlobalObject);
if (LIKELY(!catchScope.exception()))
return;
JSValue error = catchScope.exception()->value();
catchScope.clearException();
DeferredPromise::create(globalObject, promise)->reject<IDLAny>(error);
}
JSC::EncodedJSValue createRejectedPromiseWithTypeError(JSC::JSGlobalObject& lexicalGlobalObject, const String& errorMessage, RejectedPromiseWithTypeErrorCause cause)
{
auto& globalObject = lexicalGlobalObject;
auto& vm = lexicalGlobalObject.vm();
auto scope = DECLARE_THROW_SCOPE(vm);
auto promiseConstructor = globalObject.promiseConstructor();
auto rejectFunction = promiseConstructor->get(&lexicalGlobalObject, vm.propertyNames->builtinNames().rejectPrivateName());
RETURN_IF_EXCEPTION(scope, {});
auto* rejectionValue = static_cast<ErrorInstance*>(createTypeError(&lexicalGlobalObject, errorMessage));
if (cause == RejectedPromiseWithTypeErrorCause::NativeGetter)
rejectionValue->setNativeGetterTypeError();
auto callData = getCallData(vm, rejectFunction);
ASSERT(callData.type != CallData::Type::None);
MarkedArgumentBuffer arguments;
arguments.append(rejectionValue);
ASSERT(!arguments.hasOverflowed());
RELEASE_AND_RETURN(scope, JSValue::encode(call(&lexicalGlobalObject, rejectFunction, callData, promiseConstructor, arguments)));
}
static inline JSC::JSValue parseAsJSON(JSC::JSGlobalObject* lexicalGlobalObject, const String& data)
{
JSC::JSLockHolder lock(lexicalGlobalObject);
return JSC::JSONParse(lexicalGlobalObject, data);
}
void fulfillPromiseWithJSON(Ref<DeferredPromise>&& promise, const String& data)
{
JSC::JSValue value = parseAsJSON(promise->globalObject(), data);
if (!value)
promise->reject(SyntaxError);
else
promise->resolve<IDLAny>(value);
}
void fulfillPromiseWithArrayBuffer(Ref<DeferredPromise>&& promise, ArrayBuffer* arrayBuffer)
{
if (!arrayBuffer) {
promise->reject<IDLAny>(createOutOfMemoryError(promise->globalObject()));
return;
}
promise->resolve<IDLInterface<ArrayBuffer>>(*arrayBuffer);
}
void fulfillPromiseWithArrayBuffer(Ref<DeferredPromise>&& promise, const void* data, size_t length)
{
fulfillPromiseWithArrayBuffer(WTFMove(promise), ArrayBuffer::tryCreate(data, length).get());
}
bool DeferredPromise::handleTerminationExceptionIfNeeded(CatchScope& scope, JSDOMGlobalObject& lexicalGlobalObject)
{
auto* exception = scope.exception();
VM& vm = scope.vm();
auto& scriptExecutionContext = *lexicalGlobalObject.scriptExecutionContext();
if (is<WorkerGlobalScope>(scriptExecutionContext)) {
auto* scriptController = downcast<WorkerGlobalScope>(scriptExecutionContext).script();
bool terminatorCausedException = vm.isTerminationException(exception);
if (terminatorCausedException || (scriptController && scriptController->isTerminatingExecution())) {
scriptController->forbidExecution();
return true;
}
}
return false;
}
void DeferredPromise::handleUncaughtException(CatchScope& scope, JSDOMGlobalObject& lexicalGlobalObject)
{
auto* exception = scope.exception();
handleTerminationExceptionIfNeeded(scope, lexicalGlobalObject);
reportException(&lexicalGlobalObject, exception);
};
} // namespace WebCore

View File

@@ -0,0 +1,371 @@
/*
* Copyright (C) 2013-2021 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#pragma once
#include "ExceptionOr.h"
#include "JSDOMConvert.h"
#include "JSDOMGuardedObject.h"
#include "ScriptExecutionContext.h"
#include <JavaScriptCore/CatchScope.h>
#include <JavaScriptCore/JSPromise.h>
namespace WebCore {
class JSDOMWindow;
enum class RejectAsHandled : uint8_t { No, Yes };
class DeferredPromise : public DOMGuarded<JSC::JSPromise> {
public:
enum class Mode {
ClearPromiseOnResolve,
RetainPromiseOnResolve
};
static RefPtr<DeferredPromise> create(JSDOMGlobalObject& globalObject, Mode mode = Mode::ClearPromiseOnResolve)
{
JSC::VM& vm = JSC::getVM(&globalObject);
auto* promise = JSC::JSPromise::create(vm, globalObject.promiseStructure());
ASSERT(promise);
return adoptRef(new DeferredPromise(globalObject, *promise, mode));
}
static Ref<DeferredPromise> create(JSDOMGlobalObject& globalObject, JSC::JSPromise& deferred, Mode mode = Mode::ClearPromiseOnResolve)
{
return adoptRef(*new DeferredPromise(globalObject, deferred, mode));
}
template<class IDLType>
void resolve(typename IDLType::ParameterType value)
{
if (shouldIgnoreRequestToFulfill())
return;
ASSERT(deferred());
ASSERT(globalObject());
JSC::JSGlobalObject* lexicalGlobalObject = globalObject();
JSC::JSLockHolder locker(lexicalGlobalObject);
resolve(*lexicalGlobalObject, toJS<IDLType>(*lexicalGlobalObject, *globalObject(), std::forward<typename IDLType::ParameterType>(value)));
}
void resolveWithJSValue(JSC::JSValue resolution)
{
if (shouldIgnoreRequestToFulfill())
return;
ASSERT(deferred());
ASSERT(globalObject());
JSC::JSGlobalObject* lexicalGlobalObject = globalObject();
JSC::JSLockHolder locker(lexicalGlobalObject);
resolve(*lexicalGlobalObject, resolution);
}
void resolve()
{
if (shouldIgnoreRequestToFulfill())
return;
ASSERT(deferred());
ASSERT(globalObject());
JSC::JSGlobalObject* lexicalGlobalObject = globalObject();
JSC::JSLockHolder locker(lexicalGlobalObject);
resolve(*lexicalGlobalObject, JSC::jsUndefined());
}
template<class IDLType>
void resolveWithNewlyCreated(typename IDLType::ParameterType value)
{
if (shouldIgnoreRequestToFulfill())
return;
ASSERT(deferred());
ASSERT(globalObject());
JSC::JSGlobalObject* lexicalGlobalObject = globalObject();
JSC::JSLockHolder locker(lexicalGlobalObject);
resolve(*lexicalGlobalObject, toJSNewlyCreated<IDLType>(*lexicalGlobalObject, *globalObject(), std::forward<typename IDLType::ParameterType>(value)));
}
template<class IDLType>
void resolveCallbackValueWithNewlyCreated(const Function<typename IDLType::InnerParameterType(ScriptExecutionContext&)>& createValue)
{
if (shouldIgnoreRequestToFulfill())
return;
ASSERT(deferred());
ASSERT(globalObject());
auto* lexicalGlobalObject = globalObject();
JSC::JSLockHolder locker(lexicalGlobalObject);
resolve(*lexicalGlobalObject, toJSNewlyCreated<IDLType>(*lexicalGlobalObject, *globalObject(), createValue(*globalObject()->scriptExecutionContext())));
}
template<class IDLType>
void reject(typename IDLType::ParameterType value, RejectAsHandled rejectAsHandled = RejectAsHandled::No)
{
if (shouldIgnoreRequestToFulfill())
return;
ASSERT(deferred());
ASSERT(globalObject());
JSC::JSGlobalObject* lexicalGlobalObject = globalObject();
JSC::JSLockHolder locker(lexicalGlobalObject);
reject(*lexicalGlobalObject, toJS<IDLType>(*lexicalGlobalObject, *globalObject(), std::forward<typename IDLType::ParameterType>(value)), rejectAsHandled);
}
void reject(RejectAsHandled = RejectAsHandled::No);
void reject(std::nullptr_t, RejectAsHandled = RejectAsHandled::No);
WEBCORE_EXPORT void reject(Exception, RejectAsHandled = RejectAsHandled::No);
WEBCORE_EXPORT void reject(ExceptionCode, const String& = { }, RejectAsHandled = RejectAsHandled::No);
void reject(const JSC::PrivateName&, RejectAsHandled = RejectAsHandled::No);
template<typename Callback>
void resolveWithCallback(Callback callback)
{
if (shouldIgnoreRequestToFulfill())
return;
ASSERT(deferred());
ASSERT(globalObject());
auto* lexicalGlobalObject = globalObject();
JSC::VM& vm = lexicalGlobalObject->vm();
JSC::JSLockHolder locker(vm);
auto scope = DECLARE_CATCH_SCOPE(vm);
resolve(*lexicalGlobalObject, callback(*globalObject()));
if (UNLIKELY(scope.exception()))
handleUncaughtException(scope, *lexicalGlobalObject);
}
template<typename Callback>
void rejectWithCallback(Callback callback, RejectAsHandled rejectAsHandled = RejectAsHandled::No)
{
if (shouldIgnoreRequestToFulfill())
return;
ASSERT(deferred());
ASSERT(globalObject());
auto* lexicalGlobalObject = globalObject();
JSC::VM& vm = lexicalGlobalObject->vm();
JSC::JSLockHolder locker(vm);
auto scope = DECLARE_CATCH_SCOPE(vm);
reject(*lexicalGlobalObject, callback(*globalObject()), rejectAsHandled);
if (UNLIKELY(scope.exception()))
handleUncaughtException(scope, *lexicalGlobalObject);
}
JSC::JSValue promise() const;
void whenSettled(Function<void()>&&);
private:
DeferredPromise(JSDOMGlobalObject& globalObject, JSC::JSPromise& deferred, Mode mode)
: DOMGuarded<JSC::JSPromise>(globalObject, deferred)
, m_mode(mode)
{
}
bool shouldIgnoreRequestToFulfill() const { return isEmpty(); }
JSC::JSPromise* deferred() const { return guarded(); }
enum class ResolveMode { Resolve, Reject, RejectAsHandled };
WEBCORE_EXPORT void callFunction(JSC::JSGlobalObject&, ResolveMode, JSC::JSValue resolution);
void resolve(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue resolution) { callFunction(lexicalGlobalObject, ResolveMode::Resolve, resolution); }
void reject(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue resolution, RejectAsHandled rejectAsHandled)
{
callFunction(lexicalGlobalObject, rejectAsHandled == RejectAsHandled::Yes ? ResolveMode::RejectAsHandled : ResolveMode::Reject, resolution);
}
bool handleTerminationExceptionIfNeeded(JSC::CatchScope&, JSDOMGlobalObject& lexicalGlobalObject);
void handleUncaughtException(JSC::CatchScope&, JSDOMGlobalObject& lexicalGlobalObject);
Mode m_mode;
};
class DOMPromiseDeferredBase {
WTF_MAKE_FAST_ALLOCATED;
public:
DOMPromiseDeferredBase(Ref<DeferredPromise>&& genericPromise)
: m_promise(WTFMove(genericPromise))
{
}
DOMPromiseDeferredBase(DOMPromiseDeferredBase&& promise)
: m_promise(WTFMove(promise.m_promise))
{
}
DOMPromiseDeferredBase(const DOMPromiseDeferredBase& other)
: m_promise(other.m_promise.copyRef())
{
}
DOMPromiseDeferredBase& operator=(const DOMPromiseDeferredBase& other)
{
m_promise = other.m_promise.copyRef();
return *this;
}
DOMPromiseDeferredBase& operator=(DOMPromiseDeferredBase&& other)
{
m_promise = WTFMove(other.m_promise);
return *this;
}
void reject(RejectAsHandled rejectAsHandled = RejectAsHandled::No)
{
m_promise->reject(rejectAsHandled);
}
template<typename... ErrorType>
void reject(ErrorType&&... error)
{
m_promise->reject(std::forward<ErrorType>(error)...);
}
template<typename IDLType>
void rejectType(typename IDLType::ParameterType value, RejectAsHandled rejectAsHandled = RejectAsHandled::No)
{
m_promise->reject<IDLType>(std::forward<typename IDLType::ParameterType>(value), rejectAsHandled);
}
JSC::JSValue promise() const { return m_promise->promise(); };
void whenSettled(Function<void()>&& function)
{
m_promise->whenSettled(WTFMove(function));
}
protected:
Ref<DeferredPromise> m_promise;
};
template<typename IDLType>
class DOMPromiseDeferred : public DOMPromiseDeferredBase {
public:
using DOMPromiseDeferredBase::DOMPromiseDeferredBase;
using DOMPromiseDeferredBase::operator=;
using DOMPromiseDeferredBase::promise;
using DOMPromiseDeferredBase::reject;
void resolve(typename IDLType::ParameterType value)
{
m_promise->resolve<IDLType>(std::forward<typename IDLType::ParameterType>(value));
}
template<typename U>
void settle(ExceptionOr<U>&& result)
{
if (result.hasException()) {
reject(result.releaseException());
return;
}
resolve(result.releaseReturnValue());
}
};
template<> class DOMPromiseDeferred<void> : public DOMPromiseDeferredBase {
public:
using DOMPromiseDeferredBase::DOMPromiseDeferredBase;
using DOMPromiseDeferredBase::operator=;
using DOMPromiseDeferredBase::promise;
using DOMPromiseDeferredBase::reject;
void resolve()
{
m_promise->resolve();
}
void settle(ExceptionOr<void>&& result)
{
if (result.hasException()) {
reject(result.releaseException());
return;
}
resolve();
}
};
void fulfillPromiseWithJSON(Ref<DeferredPromise>&&, const String&);
void fulfillPromiseWithArrayBuffer(Ref<DeferredPromise>&&, ArrayBuffer*);
void fulfillPromiseWithArrayBuffer(Ref<DeferredPromise>&&, const void*, size_t);
WEBCORE_EXPORT void rejectPromiseWithExceptionIfAny(JSC::JSGlobalObject&, JSDOMGlobalObject&, JSC::JSPromise&, JSC::CatchScope&);
enum class RejectedPromiseWithTypeErrorCause { NativeGetter, InvalidThis };
JSC::EncodedJSValue createRejectedPromiseWithTypeError(JSC::JSGlobalObject&, const String&, RejectedPromiseWithTypeErrorCause);
using PromiseFunction = void(JSC::JSGlobalObject&, JSC::CallFrame&, Ref<DeferredPromise>&&);
template<PromiseFunction promiseFunction>
inline JSC::JSValue callPromiseFunction(JSC::JSGlobalObject& lexicalGlobalObject, JSC::CallFrame& callFrame)
{
JSC::VM& vm = JSC::getVM(&lexicalGlobalObject);
auto catchScope = DECLARE_CATCH_SCOPE(vm);
auto& globalObject = *JSC::jsSecureCast<JSDOMGlobalObject*>(vm, &lexicalGlobalObject);
auto* promise = JSC::JSPromise::create(vm, globalObject.promiseStructure());
ASSERT(promise);
promiseFunction(lexicalGlobalObject, callFrame, DeferredPromise::create(globalObject, *promise));
rejectPromiseWithExceptionIfAny(lexicalGlobalObject, globalObject, *promise, catchScope);
// FIXME: We could have error since any JS call can throw stack-overflow errors.
// https://bugs.webkit.org/show_bug.cgi?id=203402
RETURN_IF_EXCEPTION(catchScope, JSC::jsUndefined());
return promise;
}
template<typename PromiseFunctor>
inline JSC::JSValue callPromiseFunction(JSC::JSGlobalObject& lexicalGlobalObject, JSC::CallFrame& callFrame, PromiseFunctor functor)
{
JSC::VM& vm = JSC::getVM(&lexicalGlobalObject);
auto catchScope = DECLARE_CATCH_SCOPE(vm);
auto& globalObject = *JSC::jsSecureCast<JSDOMGlobalObject*>(vm, &lexicalGlobalObject);
auto* promise = JSC::JSPromise::create(vm, globalObject.promiseStructure());
ASSERT(promise);
functor(lexicalGlobalObject, callFrame, DeferredPromise::create(globalObject, *promise));
rejectPromiseWithExceptionIfAny(lexicalGlobalObject, globalObject, *promise, catchScope);
// FIXME: We could have error since any JS call can throw stack-overflow errors.
// https://bugs.webkit.org/show_bug.cgi?id=203402
RETURN_IF_EXCEPTION(catchScope, JSC::jsUndefined());
return promise;
}
using BindingPromiseFunction = JSC::EncodedJSValue(JSC::JSGlobalObject*, JSC::CallFrame*, Ref<DeferredPromise>&&);
template<BindingPromiseFunction bindingFunction>
inline void bindingPromiseFunctionAdapter(JSC::JSGlobalObject& lexicalGlobalObject, JSC::CallFrame& callFrame, Ref<DeferredPromise>&& promise)
{
bindingFunction(&lexicalGlobalObject, &callFrame, WTFMove(promise));
}
template<BindingPromiseFunction bindingPromiseFunction>
inline JSC::JSValue callPromiseFunction(JSC::JSGlobalObject& lexicalGlobalObject, JSC::CallFrame& callFrame)
{
return callPromiseFunction<bindingPromiseFunctionAdapter<bindingPromiseFunction>>(lexicalGlobalObject, callFrame);
}
} // namespace WebCore

View File

@@ -0,0 +1 @@
// stub

View File

@@ -0,0 +1,68 @@
/*
This file is part of the WebKit open source project.
This file has been generated by generate-bindings.pl. DO NOT MODIFY!
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include "config.h"
#include "JSFetchRequestCredentials.h"
#include <JavaScriptCore/JSCInlines.h>
#include <JavaScriptCore/JSString.h>
#include <wtf/NeverDestroyed.h>
namespace WebCore {
using namespace JSC;
String convertEnumerationToString(FetchRequestCredentials enumerationValue)
{
static const NeverDestroyed<String> values[] = {
MAKE_STATIC_STRING_IMPL("omit"),
MAKE_STATIC_STRING_IMPL("same-origin"),
MAKE_STATIC_STRING_IMPL("include"),
};
static_assert(static_cast<size_t>(FetchRequestCredentials::Omit) == 0, "FetchRequestCredentials::Omit is not 0 as expected");
static_assert(static_cast<size_t>(FetchRequestCredentials::SameOrigin) == 1, "FetchRequestCredentials::SameOrigin is not 1 as expected");
static_assert(static_cast<size_t>(FetchRequestCredentials::Include) == 2, "FetchRequestCredentials::Include is not 2 as expected");
ASSERT(static_cast<size_t>(enumerationValue) < WTF_ARRAY_LENGTH(values));
return values[static_cast<size_t>(enumerationValue)];
}
template<> JSString* convertEnumerationToJS(JSGlobalObject& lexicalGlobalObject, FetchRequestCredentials enumerationValue)
{
return jsStringWithCache(lexicalGlobalObject.vm(), convertEnumerationToString(enumerationValue));
}
template<> std::optional<FetchRequestCredentials> parseEnumeration<FetchRequestCredentials>(JSGlobalObject& lexicalGlobalObject, JSValue value)
{
auto stringValue = value.toWTFString(&lexicalGlobalObject);
if (stringValue == "omit")
return FetchRequestCredentials::Omit;
if (stringValue == "same-origin")
return FetchRequestCredentials::SameOrigin;
if (stringValue == "include")
return FetchRequestCredentials::Include;
return std::nullopt;
}
template<> const char* expectedEnumerationValues<FetchRequestCredentials>()
{
return "\"omit\", \"same-origin\", \"include\"";
}
} // namespace WebCore

View File

@@ -0,0 +1,34 @@
/*
This file is part of the WebKit open source project.
This file has been generated by generate-bindings.pl. DO NOT MODIFY!
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#pragma once
#include "FetchRequestCredentials.h"
#include "JSDOMConvertEnumeration.h"
namespace WebCore {
String convertEnumerationToString(FetchRequestCredentials);
template<> JSC::JSString* convertEnumerationToJS(JSC::JSGlobalObject&, FetchRequestCredentials);
template<> std::optional<FetchRequestCredentials> parseEnumeration<FetchRequestCredentials>(JSC::JSGlobalObject&, JSC::JSValue);
template<> const char* expectedEnumerationValues<FetchRequestCredentials>();
} // namespace WebCore

View File

@@ -0,0 +1,326 @@
/*
This file is part of the WebKit open source project.
This file has been generated by generate-bindings.pl. DO NOT MODIFY!
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include "config.h"
#if ENABLE(CHANNEL_MESSAGING)
#include "JSMessageChannel.h"
#include "ActiveDOMObject.h"
#include "ExtendedDOMClientIsoSubspaces.h"
#include "ExtendedDOMIsoSubspaces.h"
#include "JSDOMAttribute.h"
#include "JSDOMBinding.h"
#include "JSDOMConstructor.h"
#include "JSDOMConvertInterface.h"
#include "JSDOMExceptionHandling.h"
#include "JSDOMGlobalObject.h"
#include "JSDOMGlobalObjectInlines.h"
#include "JSDOMWrapperCache.h"
#include "JSMessagePort.h"
#include "ScriptExecutionContext.h"
#include "WebCoreJSClientData.h"
#include <JavaScriptCore/FunctionPrototype.h>
#include <JavaScriptCore/HeapAnalyzer.h>
#include <JavaScriptCore/JSCInlines.h>
#include <JavaScriptCore/JSDestructibleObjectHeapCellType.h>
#include <JavaScriptCore/SlotVisitorMacros.h>
#include <JavaScriptCore/SubspaceInlines.h>
#include <wtf/GetPtr.h>
#include <wtf/PointerPreparations.h>
#include <wtf/URL.h>
namespace WebCore {
using namespace JSC;
// Attributes
static JSC_DECLARE_CUSTOM_GETTER(jsMessageChannelConstructor);
static JSC_DECLARE_CUSTOM_GETTER(jsMessageChannel_port1);
static JSC_DECLARE_CUSTOM_GETTER(jsMessageChannel_port2);
class JSMessageChannelPrototype final : public JSC::JSNonFinalObject {
public:
using Base = JSC::JSNonFinalObject;
static JSMessageChannelPrototype* create(JSC::VM& vm, JSDOMGlobalObject* globalObject, JSC::Structure* structure)
{
JSMessageChannelPrototype* ptr = new (NotNull, JSC::allocateCell<JSMessageChannelPrototype>(vm)) JSMessageChannelPrototype(vm, globalObject, structure);
ptr->finishCreation(vm);
return ptr;
}
DECLARE_INFO;
template<typename CellType, JSC::SubspaceAccess>
static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
{
STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSMessageChannelPrototype, Base);
return &vm.plainObjectSpace();
}
static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
{
return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info());
}
private:
JSMessageChannelPrototype(JSC::VM& vm, JSC::JSGlobalObject*, JSC::Structure* structure)
: JSC::JSNonFinalObject(vm, structure)
{
}
void finishCreation(JSC::VM&);
};
STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSMessageChannelPrototype, JSMessageChannelPrototype::Base);
using JSMessageChannelDOMConstructor = JSDOMConstructor<JSMessageChannel>;
template<> EncodedJSValue JSC_HOST_CALL_ATTRIBUTES JSMessageChannelDOMConstructor::construct(JSGlobalObject* lexicalGlobalObject, CallFrame* callFrame)
{
VM& vm = lexicalGlobalObject->vm();
auto throwScope = DECLARE_THROW_SCOPE(vm);
auto* castedThis = jsCast<JSMessageChannelDOMConstructor*>(callFrame->jsCallee());
ASSERT(castedThis);
auto* context = castedThis->scriptExecutionContext();
if (UNLIKELY(!context))
return throwConstructorScriptExecutionContextUnavailableError(*lexicalGlobalObject, throwScope, "MessageChannel");
auto object = MessageChannel::create(*context);
if constexpr (IsExceptionOr<decltype(object)>)
RETURN_IF_EXCEPTION(throwScope, { });
static_assert(TypeOrExceptionOrUnderlyingType<decltype(object)>::isRef);
auto jsValue = toJSNewlyCreated<IDLInterface<MessageChannel>>(*lexicalGlobalObject, *castedThis->globalObject(), throwScope, WTFMove(object));
if constexpr (IsExceptionOr<decltype(object)>)
RETURN_IF_EXCEPTION(throwScope, { });
setSubclassStructureIfNeeded<MessageChannel>(lexicalGlobalObject, callFrame, asObject(jsValue));
RETURN_IF_EXCEPTION(throwScope, { });
return JSValue::encode(jsValue);
}
JSC_ANNOTATE_HOST_FUNCTION(JSMessageChannelDOMConstructorConstruct, JSMessageChannelDOMConstructor::construct);
template<> const ClassInfo JSMessageChannelDOMConstructor::s_info = { "MessageChannel"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSMessageChannelDOMConstructor) };
template<> JSValue JSMessageChannelDOMConstructor::prototypeForStructure(JSC::VM& vm, const JSDOMGlobalObject& globalObject)
{
UNUSED_PARAM(vm);
return globalObject.functionPrototype();
}
template<> void JSMessageChannelDOMConstructor::initializeProperties(VM& vm, JSDOMGlobalObject& globalObject)
{
putDirect(vm, vm.propertyNames->length, jsNumber(0), JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum);
JSString* nameString = jsNontrivialString(vm, "MessageChannel"_s);
m_originalName.set(vm, this, nameString);
putDirect(vm, vm.propertyNames->name, nameString, JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum);
putDirect(vm, vm.propertyNames->prototype, JSMessageChannel::prototype(vm, globalObject), JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::DontDelete);
}
/* Hash table for prototype */
static const HashTableValue JSMessageChannelPrototypeTableValues[] =
{
{ "constructor", static_cast<unsigned>(JSC::PropertyAttribute::DontEnum), NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsMessageChannelConstructor), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
{ "port1", static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsMessageChannel_port1), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
{ "port2", static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsMessageChannel_port2), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
};
const ClassInfo JSMessageChannelPrototype::s_info = { "MessageChannel"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSMessageChannelPrototype) };
void JSMessageChannelPrototype::finishCreation(VM& vm)
{
Base::finishCreation(vm);
reifyStaticProperties(vm, JSMessageChannel::info(), JSMessageChannelPrototypeTableValues, *this);
JSC_TO_STRING_TAG_WITHOUT_TRANSITION();
}
const ClassInfo JSMessageChannel::s_info = { "MessageChannel"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSMessageChannel) };
JSMessageChannel::JSMessageChannel(Structure* structure, JSDOMGlobalObject& globalObject, Ref<MessageChannel>&& impl)
: JSDOMWrapper<MessageChannel>(structure, globalObject, WTFMove(impl))
{
}
void JSMessageChannel::finishCreation(VM& vm)
{
Base::finishCreation(vm);
ASSERT(inherits(vm, info()));
static_assert(!std::is_base_of<ActiveDOMObject, MessageChannel>::value, "Interface is not marked as [ActiveDOMObject] even though implementation class subclasses ActiveDOMObject.");
}
JSObject* JSMessageChannel::createPrototype(VM& vm, JSDOMGlobalObject& globalObject)
{
return JSMessageChannelPrototype::create(vm, &globalObject, JSMessageChannelPrototype::createStructure(vm, &globalObject, globalObject.objectPrototype()));
}
JSObject* JSMessageChannel::prototype(VM& vm, JSDOMGlobalObject& globalObject)
{
return getDOMPrototype<JSMessageChannel>(vm, globalObject);
}
JSValue JSMessageChannel::getConstructor(VM& vm, const JSGlobalObject* globalObject)
{
return getDOMConstructor<JSMessageChannelDOMConstructor, DOMConstructorID::MessageChannel>(vm, *jsCast<const JSDOMGlobalObject*>(globalObject));
}
void JSMessageChannel::destroy(JSC::JSCell* cell)
{
JSMessageChannel* thisObject = static_cast<JSMessageChannel*>(cell);
thisObject->JSMessageChannel::~JSMessageChannel();
}
JSC_DEFINE_CUSTOM_GETTER(jsMessageChannelConstructor, (JSGlobalObject* lexicalGlobalObject, EncodedJSValue thisValue, PropertyName))
{
VM& vm = JSC::getVM(lexicalGlobalObject);
auto throwScope = DECLARE_THROW_SCOPE(vm);
auto* prototype = jsDynamicCast<JSMessageChannelPrototype*>(vm, JSValue::decode(thisValue));
if (UNLIKELY(!prototype))
return throwVMTypeError(lexicalGlobalObject, throwScope);
return JSValue::encode(JSMessageChannel::getConstructor(JSC::getVM(lexicalGlobalObject), prototype->globalObject()));
}
static inline JSValue jsMessageChannel_port1Getter(JSGlobalObject& lexicalGlobalObject, JSMessageChannel& thisObject)
{
auto& vm = JSC::getVM(&lexicalGlobalObject);
auto throwScope = DECLARE_THROW_SCOPE(vm);
auto& impl = thisObject.wrapped();
RELEASE_AND_RETURN(throwScope, (toJS<IDLInterface<MessagePort>>(lexicalGlobalObject, *thisObject.globalObject(), throwScope, impl.port1())));
}
JSC_DEFINE_CUSTOM_GETTER(jsMessageChannel_port1, (JSGlobalObject* lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName))
{
return IDLAttribute<JSMessageChannel>::get<jsMessageChannel_port1Getter, CastedThisErrorBehavior::Assert>(*lexicalGlobalObject, thisValue, attributeName);
}
static inline JSValue jsMessageChannel_port2Getter(JSGlobalObject& lexicalGlobalObject, JSMessageChannel& thisObject)
{
auto& vm = JSC::getVM(&lexicalGlobalObject);
auto throwScope = DECLARE_THROW_SCOPE(vm);
auto& impl = thisObject.wrapped();
RELEASE_AND_RETURN(throwScope, (toJS<IDLInterface<MessagePort>>(lexicalGlobalObject, *thisObject.globalObject(), throwScope, impl.port2())));
}
JSC_DEFINE_CUSTOM_GETTER(jsMessageChannel_port2, (JSGlobalObject* lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName))
{
return IDLAttribute<JSMessageChannel>::get<jsMessageChannel_port2Getter, CastedThisErrorBehavior::Assert>(*lexicalGlobalObject, thisValue, attributeName);
}
JSC::GCClient::IsoSubspace* JSMessageChannel::subspaceForImpl(JSC::VM& vm)
{
return WebCore::subspaceForImpl<JSMessageChannel, UseCustomHeapCellType::No>(vm,
[] (auto& spaces) { return spaces.m_clientSubspaceForMessageChannel.get(); },
[] (auto& spaces, auto&& space) { spaces.m_clientSubspaceForMessageChannel = WTFMove(space); },
[] (auto& spaces) { return spaces.m_subspaceForMessageChannel.get(); },
[] (auto& spaces, auto&& space) { spaces.m_subspaceForMessageChannel = WTFMove(space); }
);
}
template<typename Visitor>
void JSMessageChannel::visitChildrenImpl(JSCell* cell, Visitor& visitor)
{
auto* thisObject = jsCast<JSMessageChannel*>(cell);
ASSERT_GC_OBJECT_INHERITS(thisObject, info());
Base::visitChildren(thisObject, visitor);
thisObject->visitAdditionalChildren(visitor);
}
DEFINE_VISIT_CHILDREN(JSMessageChannel);
template<typename Visitor>
void JSMessageChannel::visitOutputConstraints(JSCell* cell, Visitor& visitor)
{
auto* thisObject = jsCast<JSMessageChannel*>(cell);
ASSERT_GC_OBJECT_INHERITS(thisObject, info());
Base::visitOutputConstraints(thisObject, visitor);
thisObject->visitAdditionalChildren(visitor);
}
template void JSMessageChannel::visitOutputConstraints(JSCell*, AbstractSlotVisitor&);
template void JSMessageChannel::visitOutputConstraints(JSCell*, SlotVisitor&);
void JSMessageChannel::analyzeHeap(JSCell* cell, HeapAnalyzer& analyzer)
{
auto* thisObject = jsCast<JSMessageChannel*>(cell);
analyzer.setWrappedObjectForCell(cell, &thisObject->wrapped());
if (thisObject->scriptExecutionContext())
analyzer.setLabelForCell(cell, "url " + thisObject->scriptExecutionContext()->url().string());
Base::analyzeHeap(cell, analyzer);
}
bool JSMessageChannelOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, AbstractSlotVisitor& visitor, const char** reason)
{
UNUSED_PARAM(handle);
UNUSED_PARAM(visitor);
UNUSED_PARAM(reason);
return false;
}
void JSMessageChannelOwner::finalize(JSC::Handle<JSC::Unknown> handle, void* context)
{
auto* jsMessageChannel = static_cast<JSMessageChannel*>(handle.slot()->asCell());
auto& world = *static_cast<DOMWrapperWorld*>(context);
uncacheWrapper(world, &jsMessageChannel->wrapped(), jsMessageChannel);
}
#if ENABLE(BINDING_INTEGRITY)
#if PLATFORM(WIN)
#pragma warning(disable: 4483)
extern "C" { extern void (*const __identifier("??_7MessageChannel@WebCore@@6B@")[])(); }
#else
extern "C" { extern void* _ZTVN7WebCore14MessageChannelE[]; }
#endif
#endif
JSC::JSValue toJSNewlyCreated(JSC::JSGlobalObject*, JSDOMGlobalObject* globalObject, Ref<MessageChannel>&& impl)
{
if constexpr (std::is_polymorphic_v<MessageChannel>) {
#if ENABLE(BINDING_INTEGRITY)
const void* actualVTablePointer = getVTablePointer(impl.ptr());
#if PLATFORM(WIN)
void* expectedVTablePointer = __identifier("??_7MessageChannel@WebCore@@6B@");
#else
void* expectedVTablePointer = &_ZTVN7WebCore14MessageChannelE[2];
#endif
// If you hit this assertion you either have a use after free bug, or
// MessageChannel has subclasses. If MessageChannel has subclasses that get passed
// to toJS() we currently require MessageChannel you to opt out of binding hardening
// by adding the SkipVTableValidation attribute to the interface IDL definition
RELEASE_ASSERT(actualVTablePointer == expectedVTablePointer);
#endif
}
return createWrapper<MessageChannel>(globalObject, WTFMove(impl));
}
JSC::JSValue toJS(JSC::JSGlobalObject* lexicalGlobalObject, JSDOMGlobalObject* globalObject, MessageChannel& impl)
{
return wrap(lexicalGlobalObject, globalObject, impl);
}
MessageChannel* JSMessageChannel::toWrapped(JSC::VM& vm, JSC::JSValue value)
{
if (auto* wrapper = jsDynamicCast<JSMessageChannel*>(vm, value))
return &wrapper->wrapped();
return nullptr;
}
}
#endif // ENABLE(CHANNEL_MESSAGING)

View File

@@ -0,0 +1 @@
JSMessageChannel.h :

View File

@@ -0,0 +1,101 @@
/*
This file is part of the WebKit open source project.
This file has been generated by generate-bindings.pl. DO NOT MODIFY!
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#pragma once
#if ENABLE(CHANNEL_MESSAGING)
#include "JSDOMWrapper.h"
#include "MessageChannel.h"
#include <wtf/NeverDestroyed.h>
namespace WebCore {
class JSMessageChannel : public JSDOMWrapper<MessageChannel> {
public:
using Base = JSDOMWrapper<MessageChannel>;
static JSMessageChannel* create(JSC::Structure* structure, JSDOMGlobalObject* globalObject, Ref<MessageChannel>&& impl)
{
JSMessageChannel* ptr = new (NotNull, JSC::allocateCell<JSMessageChannel>(globalObject->vm())) JSMessageChannel(structure, *globalObject, WTFMove(impl));
ptr->finishCreation(globalObject->vm());
return ptr;
}
static JSC::JSObject* createPrototype(JSC::VM&, JSDOMGlobalObject&);
static JSC::JSObject* prototype(JSC::VM&, JSDOMGlobalObject&);
static MessageChannel* toWrapped(JSC::VM&, JSC::JSValue);
static void destroy(JSC::JSCell*);
DECLARE_INFO;
static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
{
return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info(), JSC::NonArray);
}
static JSC::JSValue getConstructor(JSC::VM&, const JSC::JSGlobalObject*);
template<typename, JSC::SubspaceAccess mode> static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
{
if constexpr (mode == JSC::SubspaceAccess::Concurrently)
return nullptr;
return subspaceForImpl(vm);
}
static JSC::GCClient::IsoSubspace* subspaceForImpl(JSC::VM& vm);
DECLARE_VISIT_CHILDREN;
template<typename Visitor> void visitAdditionalChildren(Visitor&);
template<typename Visitor> static void visitOutputConstraints(JSCell*, Visitor&);
static void analyzeHeap(JSCell*, JSC::HeapAnalyzer&);
protected:
JSMessageChannel(JSC::Structure*, JSDOMGlobalObject&, Ref<MessageChannel>&&);
void finishCreation(JSC::VM&);
};
class JSMessageChannelOwner final : public JSC::WeakHandleOwner {
public:
bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::AbstractSlotVisitor&, const char**) final;
void finalize(JSC::Handle<JSC::Unknown>, void* context) final;
};
inline JSC::WeakHandleOwner* wrapperOwner(DOMWrapperWorld&, MessageChannel*)
{
static NeverDestroyed<JSMessageChannelOwner> owner;
return &owner.get();
}
inline void* wrapperKey(MessageChannel* wrappableObject)
{
return wrappableObject;
}
JSC::JSValue toJS(JSC::JSGlobalObject*, JSDOMGlobalObject*, MessageChannel&);
inline JSC::JSValue toJS(JSC::JSGlobalObject* lexicalGlobalObject, JSDOMGlobalObject* globalObject, MessageChannel* impl) { return impl ? toJS(lexicalGlobalObject, globalObject, *impl) : JSC::jsNull(); }
JSC::JSValue toJSNewlyCreated(JSC::JSGlobalObject*, JSDOMGlobalObject*, Ref<MessageChannel>&&);
inline JSC::JSValue toJSNewlyCreated(JSC::JSGlobalObject* lexicalGlobalObject, JSDOMGlobalObject* globalObject, RefPtr<MessageChannel>&& impl) { return impl ? toJSNewlyCreated(lexicalGlobalObject, globalObject, impl.releaseNonNull()) : JSC::jsNull(); }
template<> struct JSDOMWrapperConverterTraits<MessageChannel> {
using WrapperClass = JSMessageChannel;
using ToWrappedReturnType = MessageChannel*;
};
} // namespace WebCore
#endif // ENABLE(CHANNEL_MESSAGING)

View File

@@ -0,0 +1,515 @@
/*
This file is part of the WebKit open source project.
This file has been generated by generate-bindings.pl. DO NOT MODIFY!
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include "config.h"
#include "JSMessageEvent.h"
#include "ActiveDOMObject.h"
#include "ExtendedDOMClientIsoSubspaces.h"
#include "ExtendedDOMIsoSubspaces.h"
#include "IDLTypes.h"
#include "JSDOMAttribute.h"
#include "JSDOMBinding.h"
#include "JSDOMConstructor.h"
#include "JSDOMConvertAny.h"
#include "JSDOMConvertBase.h"
#include "JSDOMConvertBoolean.h"
#include "JSDOMConvertInterface.h"
#include "JSDOMConvertNullable.h"
#include "JSDOMConvertSequences.h"
#include "JSDOMConvertStrings.h"
#include "JSDOMConvertUnion.h"
#include "JSDOMExceptionHandling.h"
#include "JSDOMGlobalObject.h"
#include "JSDOMGlobalObjectInlines.h"
#include "JSDOMOperation.h"
#include "JSDOMWrapperCache.h"
#include "JSMessagePort.h"
#include "JSServiceWorker.h"
#include "JSWindowProxy.h"
#include "ScriptExecutionContext.h"
#include "WebCoreJSClientData.h"
#include <JavaScriptCore/HeapAnalyzer.h>
#include <JavaScriptCore/JSArray.h>
#include <JavaScriptCore/JSCInlines.h>
#include <JavaScriptCore/JSDestructibleObjectHeapCellType.h>
#include <JavaScriptCore/SlotVisitorMacros.h>
#include <JavaScriptCore/SubspaceInlines.h>
#include <variant>
#include <wtf/GetPtr.h>
#include <wtf/PointerPreparations.h>
#include <wtf/URL.h>
namespace WebCore {
using namespace JSC;
template<> MessageEvent::Init convertDictionary<MessageEvent::Init>(JSGlobalObject& lexicalGlobalObject, JSValue value)
{
VM& vm = JSC::getVM(&lexicalGlobalObject);
auto throwScope = DECLARE_THROW_SCOPE(vm);
bool isNullOrUndefined = value.isUndefinedOrNull();
auto* object = isNullOrUndefined ? nullptr : value.getObject();
if (UNLIKELY(!isNullOrUndefined && !object)) {
throwTypeError(&lexicalGlobalObject, throwScope);
return { };
}
MessageEvent::Init result;
JSValue bubblesValue;
if (isNullOrUndefined)
bubblesValue = jsUndefined();
else {
bubblesValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "bubbles"));
RETURN_IF_EXCEPTION(throwScope, { });
}
if (!bubblesValue.isUndefined()) {
result.bubbles = convert<IDLBoolean>(lexicalGlobalObject, bubblesValue);
RETURN_IF_EXCEPTION(throwScope, { });
} else
result.bubbles = false;
JSValue cancelableValue;
if (isNullOrUndefined)
cancelableValue = jsUndefined();
else {
cancelableValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "cancelable"));
RETURN_IF_EXCEPTION(throwScope, { });
}
if (!cancelableValue.isUndefined()) {
result.cancelable = convert<IDLBoolean>(lexicalGlobalObject, cancelableValue);
RETURN_IF_EXCEPTION(throwScope, { });
} else
result.cancelable = false;
JSValue composedValue;
if (isNullOrUndefined)
composedValue = jsUndefined();
else {
composedValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "composed"));
RETURN_IF_EXCEPTION(throwScope, { });
}
if (!composedValue.isUndefined()) {
result.composed = convert<IDLBoolean>(lexicalGlobalObject, composedValue);
RETURN_IF_EXCEPTION(throwScope, { });
} else
result.composed = false;
JSValue dataValue;
if (isNullOrUndefined)
dataValue = jsUndefined();
else {
dataValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "data"));
RETURN_IF_EXCEPTION(throwScope, { });
}
if (!dataValue.isUndefined()) {
result.data = convert<IDLAny>(lexicalGlobalObject, dataValue);
RETURN_IF_EXCEPTION(throwScope, { });
} else
result.data = jsNull();
JSValue lastEventIdValue;
if (isNullOrUndefined)
lastEventIdValue = jsUndefined();
else {
lastEventIdValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "lastEventId"));
RETURN_IF_EXCEPTION(throwScope, { });
}
if (!lastEventIdValue.isUndefined()) {
result.lastEventId = convert<IDLDOMString>(lexicalGlobalObject, lastEventIdValue);
RETURN_IF_EXCEPTION(throwScope, { });
} else
result.lastEventId = emptyString();
JSValue originValue;
if (isNullOrUndefined)
originValue = jsUndefined();
else {
originValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "origin"));
RETURN_IF_EXCEPTION(throwScope, { });
}
if (!originValue.isUndefined()) {
result.origin = convert<IDLUSVString>(lexicalGlobalObject, originValue);
RETURN_IF_EXCEPTION(throwScope, { });
} else
result.origin = emptyString();
JSValue portsValue;
if (isNullOrUndefined)
portsValue = jsUndefined();
else {
portsValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "ports"));
RETURN_IF_EXCEPTION(throwScope, { });
}
if (!portsValue.isUndefined()) {
result.ports = convert<IDLSequence<IDLInterface<MessagePort>>>(lexicalGlobalObject, portsValue);
RETURN_IF_EXCEPTION(throwScope, { });
} else
result.ports = Converter<IDLSequence<IDLInterface<MessagePort>>>::ReturnType{ };
JSValue sourceValue;
if (isNullOrUndefined)
sourceValue = jsUndefined();
else {
sourceValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "source"));
RETURN_IF_EXCEPTION(throwScope, { });
}
if (!sourceValue.isUndefined()) {
result.source = convert<IDLNullable<IDLUnion<IDLInterface<WindowProxy>, IDLInterface<MessagePort>, IDLInterface<ServiceWorker>>>>(lexicalGlobalObject, sourceValue);
RETURN_IF_EXCEPTION(throwScope, { });
} else
result.source = std::nullopt;
return result;
}
// Functions
static JSC_DECLARE_HOST_FUNCTION(jsMessageEventPrototypeFunction_initMessageEvent);
// Attributes
static JSC_DECLARE_CUSTOM_GETTER(jsMessageEventConstructor);
static JSC_DECLARE_CUSTOM_GETTER(jsMessageEvent_origin);
static JSC_DECLARE_CUSTOM_GETTER(jsMessageEvent_lastEventId);
static JSC_DECLARE_CUSTOM_GETTER(jsMessageEvent_source);
static JSC_DECLARE_CUSTOM_GETTER(jsMessageEvent_data);
static JSC_DECLARE_CUSTOM_GETTER(jsMessageEvent_ports);
class JSMessageEventPrototype final : public JSC::JSNonFinalObject {
public:
using Base = JSC::JSNonFinalObject;
static JSMessageEventPrototype* create(JSC::VM& vm, JSDOMGlobalObject* globalObject, JSC::Structure* structure)
{
JSMessageEventPrototype* ptr = new (NotNull, JSC::allocateCell<JSMessageEventPrototype>(vm)) JSMessageEventPrototype(vm, globalObject, structure);
ptr->finishCreation(vm);
return ptr;
}
DECLARE_INFO;
template<typename CellType, JSC::SubspaceAccess>
static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
{
STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSMessageEventPrototype, Base);
return &vm.plainObjectSpace();
}
static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
{
return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info());
}
private:
JSMessageEventPrototype(JSC::VM& vm, JSC::JSGlobalObject*, JSC::Structure* structure)
: JSC::JSNonFinalObject(vm, structure)
{
}
void finishCreation(JSC::VM&);
};
STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSMessageEventPrototype, JSMessageEventPrototype::Base);
using JSMessageEventDOMConstructor = JSDOMConstructor<JSMessageEvent>;
template<> EncodedJSValue JSC_HOST_CALL_ATTRIBUTES JSMessageEventDOMConstructor::construct(JSGlobalObject* lexicalGlobalObject, CallFrame* callFrame)
{
VM& vm = lexicalGlobalObject->vm();
auto throwScope = DECLARE_THROW_SCOPE(vm);
auto* castedThis = jsCast<JSMessageEventDOMConstructor*>(callFrame->jsCallee());
ASSERT(castedThis);
if (UNLIKELY(callFrame->argumentCount() < 1))
return throwVMError(lexicalGlobalObject, throwScope, createNotEnoughArgumentsError(lexicalGlobalObject));
EnsureStillAliveScope argument0 = callFrame->uncheckedArgument(0);
auto type = convert<IDLDOMString>(*lexicalGlobalObject, argument0.value());
RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
EnsureStillAliveScope argument1 = callFrame->argument(1);
auto eventInitDict = convert<IDLDictionary<MessageEvent::Init>>(*lexicalGlobalObject, argument1.value());
RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
auto object = MessageEvent::create(WTFMove(type), WTFMove(eventInitDict));
if constexpr (IsExceptionOr<decltype(object)>)
RETURN_IF_EXCEPTION(throwScope, { });
static_assert(TypeOrExceptionOrUnderlyingType<decltype(object)>::isRef);
auto jsValue = toJSNewlyCreated<IDLInterface<MessageEvent>>(*lexicalGlobalObject, *castedThis->globalObject(), throwScope, WTFMove(object));
if constexpr (IsExceptionOr<decltype(object)>)
RETURN_IF_EXCEPTION(throwScope, { });
setSubclassStructureIfNeeded<MessageEvent>(lexicalGlobalObject, callFrame, asObject(jsValue));
RETURN_IF_EXCEPTION(throwScope, { });
return JSValue::encode(jsValue);
}
JSC_ANNOTATE_HOST_FUNCTION(JSMessageEventDOMConstructorConstruct, JSMessageEventDOMConstructor::construct);
template<> const ClassInfo JSMessageEventDOMConstructor::s_info = { "MessageEvent"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSMessageEventDOMConstructor) };
template<> JSValue JSMessageEventDOMConstructor::prototypeForStructure(JSC::VM& vm, const JSDOMGlobalObject& globalObject)
{
return JSEvent::getConstructor(vm, &globalObject);
}
template<> void JSMessageEventDOMConstructor::initializeProperties(VM& vm, JSDOMGlobalObject& globalObject)
{
putDirect(vm, vm.propertyNames->length, jsNumber(1), JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum);
JSString* nameString = jsNontrivialString(vm, "MessageEvent"_s);
m_originalName.set(vm, this, nameString);
putDirect(vm, vm.propertyNames->name, nameString, JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum);
putDirect(vm, vm.propertyNames->prototype, JSMessageEvent::prototype(vm, globalObject), JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::DontDelete);
}
/* Hash table for prototype */
static const HashTableValue JSMessageEventPrototypeTableValues[] =
{
{ "constructor", static_cast<unsigned>(JSC::PropertyAttribute::DontEnum), NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsMessageEventConstructor), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
{ "origin", static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsMessageEvent_origin), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
{ "lastEventId", static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsMessageEvent_lastEventId), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
{ "source", static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsMessageEvent_source), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
{ "data", static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsMessageEvent_data), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
{ "ports", static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsMessageEvent_ports), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
{ "initMessageEvent", static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t)static_cast<RawNativeFunction>(jsMessageEventPrototypeFunction_initMessageEvent), (intptr_t) (1) } },
};
const ClassInfo JSMessageEventPrototype::s_info = { "MessageEvent"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSMessageEventPrototype) };
void JSMessageEventPrototype::finishCreation(VM& vm)
{
Base::finishCreation(vm);
reifyStaticProperties(vm, JSMessageEvent::info(), JSMessageEventPrototypeTableValues, *this);
JSC_TO_STRING_TAG_WITHOUT_TRANSITION();
}
const ClassInfo JSMessageEvent::s_info = { "MessageEvent"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSMessageEvent) };
JSMessageEvent::JSMessageEvent(Structure* structure, JSDOMGlobalObject& globalObject, Ref<MessageEvent>&& impl)
: JSEvent(structure, globalObject, WTFMove(impl))
{
}
void JSMessageEvent::finishCreation(VM& vm)
{
Base::finishCreation(vm);
ASSERT(inherits(vm, info()));
static_assert(!std::is_base_of<ActiveDOMObject, MessageEvent>::value, "Interface is not marked as [ActiveDOMObject] even though implementation class subclasses ActiveDOMObject.");
vm.heap.reportExtraMemoryAllocated(wrapped().memoryCost());
}
JSObject* JSMessageEvent::createPrototype(VM& vm, JSDOMGlobalObject& globalObject)
{
return JSMessageEventPrototype::create(vm, &globalObject, JSMessageEventPrototype::createStructure(vm, &globalObject, JSEvent::prototype(vm, globalObject)));
}
JSObject* JSMessageEvent::prototype(VM& vm, JSDOMGlobalObject& globalObject)
{
return getDOMPrototype<JSMessageEvent>(vm, globalObject);
}
JSValue JSMessageEvent::getConstructor(VM& vm, const JSGlobalObject* globalObject)
{
return getDOMConstructor<JSMessageEventDOMConstructor, DOMConstructorID::MessageEvent>(vm, *jsCast<const JSDOMGlobalObject*>(globalObject));
}
JSC_DEFINE_CUSTOM_GETTER(jsMessageEventConstructor, (JSGlobalObject* lexicalGlobalObject, EncodedJSValue thisValue, PropertyName))
{
VM& vm = JSC::getVM(lexicalGlobalObject);
auto throwScope = DECLARE_THROW_SCOPE(vm);
auto* prototype = jsDynamicCast<JSMessageEventPrototype*>(vm, JSValue::decode(thisValue));
if (UNLIKELY(!prototype))
return throwVMTypeError(lexicalGlobalObject, throwScope);
return JSValue::encode(JSMessageEvent::getConstructor(JSC::getVM(lexicalGlobalObject), prototype->globalObject()));
}
static inline JSValue jsMessageEvent_originGetter(JSGlobalObject& lexicalGlobalObject, JSMessageEvent& thisObject)
{
auto& vm = JSC::getVM(&lexicalGlobalObject);
auto throwScope = DECLARE_THROW_SCOPE(vm);
auto& impl = thisObject.wrapped();
RELEASE_AND_RETURN(throwScope, (toJS<IDLUSVString>(lexicalGlobalObject, throwScope, impl.origin())));
}
JSC_DEFINE_CUSTOM_GETTER(jsMessageEvent_origin, (JSGlobalObject* lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName))
{
return IDLAttribute<JSMessageEvent>::get<jsMessageEvent_originGetter, CastedThisErrorBehavior::Assert>(*lexicalGlobalObject, thisValue, attributeName);
}
static inline JSValue jsMessageEvent_lastEventIdGetter(JSGlobalObject& lexicalGlobalObject, JSMessageEvent& thisObject)
{
auto& vm = JSC::getVM(&lexicalGlobalObject);
auto throwScope = DECLARE_THROW_SCOPE(vm);
auto& impl = thisObject.wrapped();
RELEASE_AND_RETURN(throwScope, (toJS<IDLDOMString>(lexicalGlobalObject, throwScope, impl.lastEventId())));
}
JSC_DEFINE_CUSTOM_GETTER(jsMessageEvent_lastEventId, (JSGlobalObject* lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName))
{
return IDLAttribute<JSMessageEvent>::get<jsMessageEvent_lastEventIdGetter, CastedThisErrorBehavior::Assert>(*lexicalGlobalObject, thisValue, attributeName);
}
static inline JSValue jsMessageEvent_sourceGetter(JSGlobalObject& lexicalGlobalObject, JSMessageEvent& thisObject)
{
auto& vm = JSC::getVM(&lexicalGlobalObject);
auto throwScope = DECLARE_THROW_SCOPE(vm);
auto& impl = thisObject.wrapped();
RELEASE_AND_RETURN(throwScope, (toJS<IDLNullable<IDLUnion<IDLInterface<WindowProxy>, IDLInterface<MessagePort>, IDLInterface<ServiceWorker>>>>(lexicalGlobalObject, *thisObject.globalObject(), throwScope, impl.source())));
}
JSC_DEFINE_CUSTOM_GETTER(jsMessageEvent_source, (JSGlobalObject* lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName))
{
return IDLAttribute<JSMessageEvent>::get<jsMessageEvent_sourceGetter, CastedThisErrorBehavior::Assert>(*lexicalGlobalObject, thisValue, attributeName);
}
static inline JSValue jsMessageEvent_dataGetter(JSGlobalObject& lexicalGlobalObject, JSMessageEvent& thisObject)
{
UNUSED_PARAM(lexicalGlobalObject);
return thisObject.data(lexicalGlobalObject);
}
JSC_DEFINE_CUSTOM_GETTER(jsMessageEvent_data, (JSGlobalObject* lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName))
{
return IDLAttribute<JSMessageEvent>::get<jsMessageEvent_dataGetter, CastedThisErrorBehavior::Assert>(*lexicalGlobalObject, thisValue, attributeName);
}
static inline JSValue jsMessageEvent_portsGetter(JSGlobalObject& lexicalGlobalObject, JSMessageEvent& thisObject)
{
UNUSED_PARAM(lexicalGlobalObject);
return thisObject.ports(lexicalGlobalObject);
}
JSC_DEFINE_CUSTOM_GETTER(jsMessageEvent_ports, (JSGlobalObject* lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName))
{
return IDLAttribute<JSMessageEvent>::get<jsMessageEvent_portsGetter, CastedThisErrorBehavior::Assert>(*lexicalGlobalObject, thisValue, attributeName);
}
static inline JSC::EncodedJSValue jsMessageEventPrototypeFunction_initMessageEventBody(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, typename IDLOperation<JSMessageEvent>::ClassParameter castedThis)
{
auto& vm = JSC::getVM(lexicalGlobalObject);
auto throwScope = DECLARE_THROW_SCOPE(vm);
UNUSED_PARAM(throwScope);
UNUSED_PARAM(callFrame);
auto& impl = castedThis->wrapped();
if (UNLIKELY(callFrame->argumentCount() < 1))
return throwVMError(lexicalGlobalObject, throwScope, createNotEnoughArgumentsError(lexicalGlobalObject));
EnsureStillAliveScope argument0 = callFrame->uncheckedArgument(0);
auto type = convert<IDLDOMString>(*lexicalGlobalObject, argument0.value());
RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
EnsureStillAliveScope argument1 = callFrame->argument(1);
auto bubbles = convert<IDLBoolean>(*lexicalGlobalObject, argument1.value());
RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
EnsureStillAliveScope argument2 = callFrame->argument(2);
auto cancelable = convert<IDLBoolean>(*lexicalGlobalObject, argument2.value());
RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
EnsureStillAliveScope argument3 = callFrame->argument(3);
auto data = argument3.value().isUndefined() ? jsNull() : convert<IDLAny>(*lexicalGlobalObject, argument3.value());
RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
EnsureStillAliveScope argument4 = callFrame->argument(4);
auto originArg = argument4.value().isUndefined() ? emptyString() : convert<IDLUSVString>(*lexicalGlobalObject, argument4.value());
RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
EnsureStillAliveScope argument5 = callFrame->argument(5);
auto lastEventId = argument5.value().isUndefined() ? emptyString() : convert<IDLDOMString>(*lexicalGlobalObject, argument5.value());
RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
EnsureStillAliveScope argument6 = callFrame->argument(6);
auto source = argument6.value().isUndefined() ? std::nullopt : convert<IDLNullable<IDLUnion<IDLInterface<WindowProxy>, IDLInterface<MessagePort>, IDLInterface<ServiceWorker>>>>(*lexicalGlobalObject, argument6.value());
RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
EnsureStillAliveScope argument7 = callFrame->argument(7);
auto messagePorts = argument7.value().isUndefined() ? Converter<IDLSequence<IDLInterface<MessagePort>>>::ReturnType{ } : convert<IDLSequence<IDLInterface<MessagePort>>>(*lexicalGlobalObject, argument7.value());
RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
RELEASE_AND_RETURN(throwScope, JSValue::encode(toJS<IDLUndefined>(*lexicalGlobalObject, throwScope, [&]() -> decltype(auto) { return impl.initMessageEvent(WTFMove(type), WTFMove(bubbles), WTFMove(cancelable), WTFMove(data), WTFMove(originArg), WTFMove(lastEventId), WTFMove(source), WTFMove(messagePorts)); })));
}
JSC_DEFINE_HOST_FUNCTION(jsMessageEventPrototypeFunction_initMessageEvent, (JSGlobalObject* lexicalGlobalObject, CallFrame* callFrame))
{
return IDLOperation<JSMessageEvent>::call<jsMessageEventPrototypeFunction_initMessageEventBody>(*lexicalGlobalObject, *callFrame, "initMessageEvent");
}
JSC::GCClient::IsoSubspace* JSMessageEvent::subspaceForImpl(JSC::VM& vm)
{
return WebCore::subspaceForImpl<JSMessageEvent, UseCustomHeapCellType::No>(vm,
[] (auto& spaces) { return spaces.m_clientSubspaceForMessageEvent.get(); },
[] (auto& spaces, auto&& space) { spaces.m_clientSubspaceForMessageEvent = WTFMove(space); },
[] (auto& spaces) { return spaces.m_subspaceForMessageEvent.get(); },
[] (auto& spaces, auto&& space) { spaces.m_subspaceForMessageEvent = WTFMove(space); }
);
}
template<typename Visitor>
void JSMessageEvent::visitChildrenImpl(JSCell* cell, Visitor& visitor)
{
auto* thisObject = jsCast<JSMessageEvent*>(cell);
ASSERT_GC_OBJECT_INHERITS(thisObject, info());
Base::visitChildren(thisObject, visitor);
thisObject->visitAdditionalChildren(visitor);
visitor.reportExtraMemoryVisited(thisObject->wrapped().memoryCost());
}
DEFINE_VISIT_CHILDREN(JSMessageEvent);
template<typename Visitor>
void JSMessageEvent::visitOutputConstraints(JSCell* cell, Visitor& visitor)
{
auto* thisObject = jsCast<JSMessageEvent*>(cell);
ASSERT_GC_OBJECT_INHERITS(thisObject, info());
Base::visitOutputConstraints(thisObject, visitor);
thisObject->visitAdditionalChildren(visitor);
}
template void JSMessageEvent::visitOutputConstraints(JSCell*, AbstractSlotVisitor&);
template void JSMessageEvent::visitOutputConstraints(JSCell*, SlotVisitor&);
size_t JSMessageEvent::estimatedSize(JSCell* cell, VM& vm)
{
auto* thisObject = jsCast<JSMessageEvent*>(cell);
return Base::estimatedSize(thisObject, vm) + thisObject->wrapped().memoryCost();
}
void JSMessageEvent::analyzeHeap(JSCell* cell, HeapAnalyzer& analyzer)
{
auto* thisObject = jsCast<JSMessageEvent*>(cell);
analyzer.setWrappedObjectForCell(cell, &thisObject->wrapped());
if (thisObject->scriptExecutionContext())
analyzer.setLabelForCell(cell, "url " + thisObject->scriptExecutionContext()->url().string());
Base::analyzeHeap(cell, analyzer);
}
#if ENABLE(BINDING_INTEGRITY)
#if PLATFORM(WIN)
#pragma warning(disable: 4483)
extern "C" { extern void (*const __identifier("??_7MessageEvent@WebCore@@6B@")[])(); }
#else
extern "C" { extern void* _ZTVN7WebCore12MessageEventE[]; }
#endif
#endif
JSC::JSValue toJSNewlyCreated(JSC::JSGlobalObject*, JSDOMGlobalObject* globalObject, Ref<MessageEvent>&& impl)
{
if constexpr (std::is_polymorphic_v<MessageEvent>) {
#if ENABLE(BINDING_INTEGRITY)
const void* actualVTablePointer = getVTablePointer(impl.ptr());
#if PLATFORM(WIN)
void* expectedVTablePointer = __identifier("??_7MessageEvent@WebCore@@6B@");
#else
void* expectedVTablePointer = &_ZTVN7WebCore12MessageEventE[2];
#endif
// If you hit this assertion you either have a use after free bug, or
// MessageEvent has subclasses. If MessageEvent has subclasses that get passed
// to toJS() we currently require MessageEvent you to opt out of binding hardening
// by adding the SkipVTableValidation attribute to the interface IDL definition
RELEASE_ASSERT(actualVTablePointer == expectedVTablePointer);
#endif
}
return createWrapper<MessageEvent>(globalObject, WTFMove(impl));
}
JSC::JSValue toJS(JSC::JSGlobalObject* lexicalGlobalObject, JSDOMGlobalObject* globalObject, MessageEvent& impl)
{
return wrap(lexicalGlobalObject, globalObject, impl);
}
}

View File

@@ -0,0 +1,3 @@
JSMessageEvent.h : Event.idl EventInit.idl
Event.idl :
EventInit.idl :

View File

@@ -0,0 +1,91 @@
/*
This file is part of the WebKit open source project.
This file has been generated by generate-bindings.pl. DO NOT MODIFY!
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#pragma once
#include "JSDOMConvertDictionary.h"
#include "JSDOMWrapper.h"
#include "JSEvent.h"
#include "MessageEvent.h"
namespace WebCore {
class JSMessageEvent : public JSEvent {
public:
using Base = JSEvent;
using DOMWrapped = MessageEvent;
static JSMessageEvent* create(JSC::Structure* structure, JSDOMGlobalObject* globalObject, Ref<MessageEvent>&& impl)
{
JSMessageEvent* ptr = new (NotNull, JSC::allocateCell<JSMessageEvent>(globalObject->vm())) JSMessageEvent(structure, *globalObject, WTFMove(impl));
ptr->finishCreation(globalObject->vm());
return ptr;
}
static JSC::JSObject* createPrototype(JSC::VM&, JSDOMGlobalObject&);
static JSC::JSObject* prototype(JSC::VM&, JSDOMGlobalObject&);
static size_t estimatedSize(JSCell*, JSC::VM&);
DECLARE_INFO;
static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
{
return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::JSType(JSEventType), StructureFlags), info(), JSC::NonArray);
}
static JSC::JSValue getConstructor(JSC::VM&, const JSC::JSGlobalObject*);
template<typename, JSC::SubspaceAccess mode> static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
{
if constexpr (mode == JSC::SubspaceAccess::Concurrently)
return nullptr;
return subspaceForImpl(vm);
}
static JSC::GCClient::IsoSubspace* subspaceForImpl(JSC::VM& vm);
DECLARE_VISIT_CHILDREN;
template<typename Visitor> void visitAdditionalChildren(Visitor&);
template<typename Visitor> static void visitOutputConstraints(JSCell*, Visitor&);
static void analyzeHeap(JSCell*, JSC::HeapAnalyzer&);
// Custom attributes
JSC::JSValue data(JSC::JSGlobalObject&) const;
JSC::JSValue ports(JSC::JSGlobalObject&) const;
MessageEvent& wrapped() const
{
return static_cast<MessageEvent&>(Base::wrapped());
}
protected:
JSMessageEvent(JSC::Structure*, JSDOMGlobalObject&, Ref<MessageEvent>&&);
void finishCreation(JSC::VM&);
};
JSC::JSValue toJS(JSC::JSGlobalObject*, JSDOMGlobalObject*, MessageEvent&);
inline JSC::JSValue toJS(JSC::JSGlobalObject* lexicalGlobalObject, JSDOMGlobalObject* globalObject, MessageEvent* impl) { return impl ? toJS(lexicalGlobalObject, globalObject, *impl) : JSC::jsNull(); }
JSC::JSValue toJSNewlyCreated(JSC::JSGlobalObject*, JSDOMGlobalObject*, Ref<MessageEvent>&&);
inline JSC::JSValue toJSNewlyCreated(JSC::JSGlobalObject* lexicalGlobalObject, JSDOMGlobalObject* globalObject, RefPtr<MessageEvent>&& impl) { return impl ? toJSNewlyCreated(lexicalGlobalObject, globalObject, impl.releaseNonNull()) : JSC::jsNull(); }
template<> struct JSDOMWrapperConverterTraits<MessageEvent> {
using WrapperClass = JSMessageEvent;
using ToWrappedReturnType = MessageEvent*;
};
template<> MessageEvent::Init convertDictionary<MessageEvent::Init>(JSC::JSGlobalObject&, JSC::JSValue);
} // namespace WebCore

View File

@@ -0,0 +1,415 @@
/*
This file is part of the WebKit open source project.
This file has been generated by generate-bindings.pl. DO NOT MODIFY!
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include "config.h"
#include "JSMessagePort.h"
#include "ActiveDOMObject.h"
#include "EventNames.h"
#include "ExtendedDOMClientIsoSubspaces.h"
#include "ExtendedDOMIsoSubspaces.h"
#include "IDLTypes.h"
#include "JSDOMAttribute.h"
#include "JSDOMBinding.h"
#include "JSDOMConstructorNotConstructable.h"
#include "JSDOMConvertAny.h"
#include "JSDOMConvertBase.h"
#include "JSDOMConvertDictionary.h"
#include "JSDOMConvertObject.h"
#include "JSDOMConvertSequences.h"
#include "JSDOMExceptionHandling.h"
#include "JSDOMGlobalObjectInlines.h"
#include "JSDOMOperation.h"
#include "JSDOMWrapperCache.h"
#include "JSEventListener.h"
#include "JSStructuredSerializeOptions.h"
#include "ScriptExecutionContext.h"
#include "WebCoreJSClientData.h"
#include <JavaScriptCore/HeapAnalyzer.h>
#include <JavaScriptCore/IteratorOperations.h>
#include <JavaScriptCore/JSArray.h>
#include <JavaScriptCore/JSCInlines.h>
#include <JavaScriptCore/JSDestructibleObjectHeapCellType.h>
#include <JavaScriptCore/SlotVisitorMacros.h>
#include <JavaScriptCore/SubspaceInlines.h>
#include <wtf/GetPtr.h>
#include <wtf/PointerPreparations.h>
#include <wtf/URL.h>
namespace WebCore {
using namespace JSC;
// Functions
static JSC_DECLARE_HOST_FUNCTION(jsMessagePortPrototypeFunction_postMessage);
static JSC_DECLARE_HOST_FUNCTION(jsMessagePortPrototypeFunction_start);
static JSC_DECLARE_HOST_FUNCTION(jsMessagePortPrototypeFunction_close);
// Attributes
static JSC_DECLARE_CUSTOM_GETTER(jsMessagePortConstructor);
static JSC_DECLARE_CUSTOM_GETTER(jsMessagePort_onmessage);
static JSC_DECLARE_CUSTOM_SETTER(setJSMessagePort_onmessage);
class JSMessagePortPrototype final : public JSC::JSNonFinalObject {
public:
using Base = JSC::JSNonFinalObject;
static JSMessagePortPrototype* create(JSC::VM& vm, JSDOMGlobalObject* globalObject, JSC::Structure* structure)
{
JSMessagePortPrototype* ptr = new (NotNull, JSC::allocateCell<JSMessagePortPrototype>(vm)) JSMessagePortPrototype(vm, globalObject, structure);
ptr->finishCreation(vm);
return ptr;
}
DECLARE_INFO;
template<typename CellType, JSC::SubspaceAccess>
static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
{
STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSMessagePortPrototype, Base);
return &vm.plainObjectSpace();
}
static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
{
return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info());
}
private:
JSMessagePortPrototype(JSC::VM& vm, JSC::JSGlobalObject*, JSC::Structure* structure)
: JSC::JSNonFinalObject(vm, structure)
{
}
void finishCreation(JSC::VM&);
};
STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSMessagePortPrototype, JSMessagePortPrototype::Base);
using JSMessagePortDOMConstructor = JSDOMConstructorNotConstructable<JSMessagePort>;
template<> const ClassInfo JSMessagePortDOMConstructor::s_info = { "MessagePort"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSMessagePortDOMConstructor) };
template<> JSValue JSMessagePortDOMConstructor::prototypeForStructure(JSC::VM& vm, const JSDOMGlobalObject& globalObject)
{
return JSEventTarget::getConstructor(vm, &globalObject);
}
template<> void JSMessagePortDOMConstructor::initializeProperties(VM& vm, JSDOMGlobalObject& globalObject)
{
putDirect(vm, vm.propertyNames->length, jsNumber(0), JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum);
JSString* nameString = jsNontrivialString(vm, "MessagePort"_s);
m_originalName.set(vm, this, nameString);
putDirect(vm, vm.propertyNames->name, nameString, JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum);
putDirect(vm, vm.propertyNames->prototype, JSMessagePort::prototype(vm, globalObject), JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::DontDelete);
}
/* Hash table for prototype */
static const HashTableValue JSMessagePortPrototypeTableValues[] =
{
{ "constructor", static_cast<unsigned>(JSC::PropertyAttribute::DontEnum), NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsMessagePortConstructor), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
{ "onmessage", static_cast<unsigned>(JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsMessagePort_onmessage), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(setJSMessagePort_onmessage) } },
{ "postMessage", static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t)static_cast<RawNativeFunction>(jsMessagePortPrototypeFunction_postMessage), (intptr_t) (1) } },
{ "start", static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t)static_cast<RawNativeFunction>(jsMessagePortPrototypeFunction_start), (intptr_t) (0) } },
{ "close", static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t)static_cast<RawNativeFunction>(jsMessagePortPrototypeFunction_close), (intptr_t) (0) } },
};
const ClassInfo JSMessagePortPrototype::s_info = { "MessagePort"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSMessagePortPrototype) };
void JSMessagePortPrototype::finishCreation(VM& vm)
{
Base::finishCreation(vm);
reifyStaticProperties(vm, JSMessagePort::info(), JSMessagePortPrototypeTableValues, *this);
JSC_TO_STRING_TAG_WITHOUT_TRANSITION();
}
const ClassInfo JSMessagePort::s_info = { "MessagePort"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSMessagePort) };
JSMessagePort::JSMessagePort(Structure* structure, JSDOMGlobalObject& globalObject, Ref<MessagePort>&& impl)
: JSEventTarget(structure, globalObject, WTFMove(impl))
{
}
void JSMessagePort::finishCreation(VM& vm)
{
Base::finishCreation(vm);
ASSERT(inherits(vm, info()));
static_assert(std::is_base_of<ActiveDOMObject, MessagePort>::value, "Interface is marked as [ActiveDOMObject] but implementation class does not subclass ActiveDOMObject.");
}
JSObject* JSMessagePort::createPrototype(VM& vm, JSDOMGlobalObject& globalObject)
{
return JSMessagePortPrototype::create(vm, &globalObject, JSMessagePortPrototype::createStructure(vm, &globalObject, JSEventTarget::prototype(vm, globalObject)));
}
JSObject* JSMessagePort::prototype(VM& vm, JSDOMGlobalObject& globalObject)
{
return getDOMPrototype<JSMessagePort>(vm, globalObject);
}
JSValue JSMessagePort::getConstructor(VM& vm, const JSGlobalObject* globalObject)
{
return getDOMConstructor<JSMessagePortDOMConstructor, DOMConstructorID::MessagePort>(vm, *jsCast<const JSDOMGlobalObject*>(globalObject));
}
JSC_DEFINE_CUSTOM_GETTER(jsMessagePortConstructor, (JSGlobalObject* lexicalGlobalObject, EncodedJSValue thisValue, PropertyName))
{
VM& vm = JSC::getVM(lexicalGlobalObject);
auto throwScope = DECLARE_THROW_SCOPE(vm);
auto* prototype = jsDynamicCast<JSMessagePortPrototype*>(vm, JSValue::decode(thisValue));
if (UNLIKELY(!prototype))
return throwVMTypeError(lexicalGlobalObject, throwScope);
return JSValue::encode(JSMessagePort::getConstructor(JSC::getVM(lexicalGlobalObject), prototype->globalObject()));
}
static inline JSValue jsMessagePort_onmessageGetter(JSGlobalObject& lexicalGlobalObject, JSMessagePort& thisObject)
{
UNUSED_PARAM(lexicalGlobalObject);
return eventHandlerAttribute(thisObject.wrapped(), eventNames().messageEvent, worldForDOMObject(thisObject));
}
JSC_DEFINE_CUSTOM_GETTER(jsMessagePort_onmessage, (JSGlobalObject* lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName))
{
return IDLAttribute<JSMessagePort>::get<jsMessagePort_onmessageGetter, CastedThisErrorBehavior::Assert>(*lexicalGlobalObject, thisValue, attributeName);
}
static inline bool setJSMessagePort_onmessageSetter(JSGlobalObject& lexicalGlobalObject, JSMessagePort& thisObject, JSValue value)
{
auto& vm = JSC::getVM(&lexicalGlobalObject);
setEventHandlerAttribute<JSEventListener>(thisObject.wrapped(), eventNames().messageEvent, value, thisObject);
vm.writeBarrier(&thisObject, value);
ensureStillAliveHere(value);
return true;
}
JSC_DEFINE_CUSTOM_SETTER(setJSMessagePort_onmessage, (JSGlobalObject* lexicalGlobalObject, EncodedJSValue thisValue, EncodedJSValue encodedValue, PropertyName attributeName))
{
return IDLAttribute<JSMessagePort>::set<setJSMessagePort_onmessageSetter>(*lexicalGlobalObject, thisValue, encodedValue, attributeName);
}
static inline JSC::EncodedJSValue jsMessagePortPrototypeFunction_postMessage1Body(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, typename IDLOperation<JSMessagePort>::ClassParameter castedThis)
{
auto& vm = JSC::getVM(lexicalGlobalObject);
auto throwScope = DECLARE_THROW_SCOPE(vm);
UNUSED_PARAM(throwScope);
UNUSED_PARAM(callFrame);
auto& impl = castedThis->wrapped();
EnsureStillAliveScope argument0 = callFrame->uncheckedArgument(0);
auto message = convert<IDLAny>(*lexicalGlobalObject, argument0.value());
RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
EnsureStillAliveScope argument1 = callFrame->uncheckedArgument(1);
auto transfer = convert<IDLSequence<IDLObject>>(*lexicalGlobalObject, argument1.value());
RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
RELEASE_AND_RETURN(throwScope, JSValue::encode(toJS<IDLUndefined>(*lexicalGlobalObject, throwScope, [&]() -> decltype(auto) { return impl.postMessage(*jsCast<JSDOMGlobalObject*>(lexicalGlobalObject), WTFMove(message), WTFMove(transfer)); })));
}
static inline JSC::EncodedJSValue jsMessagePortPrototypeFunction_postMessage2Body(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, typename IDLOperation<JSMessagePort>::ClassParameter castedThis)
{
auto& vm = JSC::getVM(lexicalGlobalObject);
auto throwScope = DECLARE_THROW_SCOPE(vm);
UNUSED_PARAM(throwScope);
UNUSED_PARAM(callFrame);
auto& impl = castedThis->wrapped();
EnsureStillAliveScope argument0 = callFrame->uncheckedArgument(0);
auto message = convert<IDLAny>(*lexicalGlobalObject, argument0.value());
RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
EnsureStillAliveScope argument1 = callFrame->argument(1);
auto options = convert<IDLDictionary<StructuredSerializeOptions>>(*lexicalGlobalObject, argument1.value());
RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
RELEASE_AND_RETURN(throwScope, JSValue::encode(toJS<IDLUndefined>(*lexicalGlobalObject, throwScope, [&]() -> decltype(auto) { return impl.postMessage(*jsCast<JSDOMGlobalObject*>(lexicalGlobalObject), WTFMove(message), WTFMove(options)); })));
}
static inline JSC::EncodedJSValue jsMessagePortPrototypeFunction_postMessageOverloadDispatcher(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, typename IDLOperation<JSMessagePort>::ClassParameter castedThis)
{
auto& vm = JSC::getVM(lexicalGlobalObject);
auto throwScope = DECLARE_THROW_SCOPE(vm);
UNUSED_PARAM(throwScope);
UNUSED_PARAM(callFrame);
size_t argsCount = std::min<size_t>(2, callFrame->argumentCount());
if (argsCount == 1) {
RELEASE_AND_RETURN(throwScope, (jsMessagePortPrototypeFunction_postMessage2Body(lexicalGlobalObject, callFrame, castedThis)));
}
if (argsCount == 2) {
JSValue distinguishingArg = callFrame->uncheckedArgument(1);
if (distinguishingArg.isUndefined())
RELEASE_AND_RETURN(throwScope, (jsMessagePortPrototypeFunction_postMessage2Body(lexicalGlobalObject, callFrame, castedThis)));
if (distinguishingArg.isUndefinedOrNull())
RELEASE_AND_RETURN(throwScope, (jsMessagePortPrototypeFunction_postMessage2Body(lexicalGlobalObject, callFrame, castedThis)));
{
bool success = hasIteratorMethod(lexicalGlobalObject, distinguishingArg);
RETURN_IF_EXCEPTION(throwScope, { });
if (success)
RELEASE_AND_RETURN(throwScope, (jsMessagePortPrototypeFunction_postMessage1Body(lexicalGlobalObject, callFrame, castedThis)));
}
if (distinguishingArg.isObject())
RELEASE_AND_RETURN(throwScope, (jsMessagePortPrototypeFunction_postMessage2Body(lexicalGlobalObject, callFrame, castedThis)));
}
return argsCount < 1 ? throwVMError(lexicalGlobalObject, throwScope, createNotEnoughArgumentsError(lexicalGlobalObject)) : throwVMTypeError(lexicalGlobalObject, throwScope);
}
JSC_DEFINE_HOST_FUNCTION(jsMessagePortPrototypeFunction_postMessage, (JSGlobalObject* lexicalGlobalObject, CallFrame* callFrame))
{
return IDLOperation<JSMessagePort>::call<jsMessagePortPrototypeFunction_postMessageOverloadDispatcher>(*lexicalGlobalObject, *callFrame, "postMessage");
}
static inline JSC::EncodedJSValue jsMessagePortPrototypeFunction_startBody(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, typename IDLOperation<JSMessagePort>::ClassParameter castedThis)
{
auto& vm = JSC::getVM(lexicalGlobalObject);
auto throwScope = DECLARE_THROW_SCOPE(vm);
UNUSED_PARAM(throwScope);
UNUSED_PARAM(callFrame);
auto& impl = castedThis->wrapped();
RELEASE_AND_RETURN(throwScope, JSValue::encode(toJS<IDLUndefined>(*lexicalGlobalObject, throwScope, [&]() -> decltype(auto) { return impl.start(); })));
}
JSC_DEFINE_HOST_FUNCTION(jsMessagePortPrototypeFunction_start, (JSGlobalObject* lexicalGlobalObject, CallFrame* callFrame))
{
return IDLOperation<JSMessagePort>::call<jsMessagePortPrototypeFunction_startBody>(*lexicalGlobalObject, *callFrame, "start");
}
static inline JSC::EncodedJSValue jsMessagePortPrototypeFunction_closeBody(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, typename IDLOperation<JSMessagePort>::ClassParameter castedThis)
{
auto& vm = JSC::getVM(lexicalGlobalObject);
auto throwScope = DECLARE_THROW_SCOPE(vm);
UNUSED_PARAM(throwScope);
UNUSED_PARAM(callFrame);
auto& impl = castedThis->wrapped();
RELEASE_AND_RETURN(throwScope, JSValue::encode(toJS<IDLUndefined>(*lexicalGlobalObject, throwScope, [&]() -> decltype(auto) { return impl.close(); })));
}
JSC_DEFINE_HOST_FUNCTION(jsMessagePortPrototypeFunction_close, (JSGlobalObject* lexicalGlobalObject, CallFrame* callFrame))
{
return IDLOperation<JSMessagePort>::call<jsMessagePortPrototypeFunction_closeBody>(*lexicalGlobalObject, *callFrame, "close");
}
JSC::GCClient::IsoSubspace* JSMessagePort::subspaceForImpl(JSC::VM& vm)
{
return WebCore::subspaceForImpl<JSMessagePort, UseCustomHeapCellType::No>(vm,
[] (auto& spaces) { return spaces.m_clientSubspaceForMessagePort.get(); },
[] (auto& spaces, auto&& space) { spaces.m_clientSubspaceForMessagePort = WTFMove(space); },
[] (auto& spaces) { return spaces.m_subspaceForMessagePort.get(); },
[] (auto& spaces, auto&& space) { spaces.m_subspaceForMessagePort = WTFMove(space); }
);
}
template<typename Visitor>
void JSMessagePort::visitChildrenImpl(JSCell* cell, Visitor& visitor)
{
auto* thisObject = jsCast<JSMessagePort*>(cell);
ASSERT_GC_OBJECT_INHERITS(thisObject, info());
Base::visitChildren(thisObject, visitor);
thisObject->visitAdditionalChildren(visitor);
}
DEFINE_VISIT_CHILDREN(JSMessagePort);
template<typename Visitor>
void JSMessagePort::visitOutputConstraints(JSCell* cell, Visitor& visitor)
{
auto* thisObject = jsCast<JSMessagePort*>(cell);
ASSERT_GC_OBJECT_INHERITS(thisObject, info());
Base::visitOutputConstraints(thisObject, visitor);
thisObject->visitAdditionalChildren(visitor);
}
template void JSMessagePort::visitOutputConstraints(JSCell*, AbstractSlotVisitor&);
template void JSMessagePort::visitOutputConstraints(JSCell*, SlotVisitor&);
void JSMessagePort::analyzeHeap(JSCell* cell, HeapAnalyzer& analyzer)
{
auto* thisObject = jsCast<JSMessagePort*>(cell);
analyzer.setWrappedObjectForCell(cell, &thisObject->wrapped());
if (thisObject->scriptExecutionContext())
analyzer.setLabelForCell(cell, "url " + thisObject->scriptExecutionContext()->url().string());
Base::analyzeHeap(cell, analyzer);
}
bool JSMessagePortOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, AbstractSlotVisitor& visitor, const char** reason)
{
auto* jsMessagePort = jsCast<JSMessagePort*>(handle.slot()->asCell());
auto& wrapped = jsMessagePort->wrapped();
if (!wrapped.isContextStopped() && wrapped.hasPendingActivity()) {
if (UNLIKELY(reason))
*reason = "ActiveDOMObject with pending activity";
return true;
}
if (jsMessagePort->wrapped().isFiringEventListeners()) {
if (UNLIKELY(reason))
*reason = "EventTarget firing event listeners";
return true;
}
MessagePort* root = &jsMessagePort->wrapped();
if (UNLIKELY(reason))
*reason = "Reachable from MessagePort";
return visitor.containsOpaqueRoot(root);
}
void JSMessagePortOwner::finalize(JSC::Handle<JSC::Unknown> handle, void* context)
{
auto* jsMessagePort = static_cast<JSMessagePort*>(handle.slot()->asCell());
auto& world = *static_cast<DOMWrapperWorld*>(context);
uncacheWrapper(world, &jsMessagePort->wrapped(), jsMessagePort);
}
#if ENABLE(BINDING_INTEGRITY)
#if PLATFORM(WIN)
#pragma warning(disable: 4483)
extern "C" { extern void (*const __identifier("??_7MessagePort@WebCore@@6B@")[])(); }
#else
extern "C" { extern void* _ZTVN7WebCore11MessagePortE[]; }
#endif
#endif
JSC::JSValue toJSNewlyCreated(JSC::JSGlobalObject*, JSDOMGlobalObject* globalObject, Ref<MessagePort>&& impl)
{
if constexpr (std::is_polymorphic_v<MessagePort>) {
#if ENABLE(BINDING_INTEGRITY)
const void* actualVTablePointer = getVTablePointer(impl.ptr());
#if PLATFORM(WIN)
void* expectedVTablePointer = __identifier("??_7MessagePort@WebCore@@6B@");
#else
void* expectedVTablePointer = &_ZTVN7WebCore11MessagePortE[2];
#endif
// If you hit this assertion you either have a use after free bug, or
// MessagePort has subclasses. If MessagePort has subclasses that get passed
// to toJS() we currently require MessagePort you to opt out of binding hardening
// by adding the SkipVTableValidation attribute to the interface IDL definition
RELEASE_ASSERT(actualVTablePointer == expectedVTablePointer);
#endif
}
return createWrapper<MessagePort>(globalObject, WTFMove(impl));
}
JSC::JSValue toJS(JSC::JSGlobalObject* lexicalGlobalObject, JSDOMGlobalObject* globalObject, MessagePort& impl)
{
return wrap(lexicalGlobalObject, globalObject, impl);
}
MessagePort* JSMessagePort::toWrapped(JSC::VM& vm, JSC::JSValue value)
{
if (auto* wrapper = jsDynamicCast<JSMessagePort*>(vm, value))
return &wrapper->wrapped();
return nullptr;
}
}

View File

@@ -0,0 +1,2 @@
JSMessagePort.h : EventTarget.idl
EventTarget.idl :

View File

@@ -0,0 +1,102 @@
/*
This file is part of the WebKit open source project.
This file has been generated by generate-bindings.pl. DO NOT MODIFY!
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#pragma once
#include "JSDOMWrapper.h"
#include "JSEventTarget.h"
#include "MessagePort.h"
#include <wtf/NeverDestroyed.h>
namespace WebCore {
class JSMessagePort : public JSEventTarget {
public:
using Base = JSEventTarget;
using DOMWrapped = MessagePort;
static JSMessagePort* create(JSC::Structure* structure, JSDOMGlobalObject* globalObject, Ref<MessagePort>&& impl)
{
JSMessagePort* ptr = new (NotNull, JSC::allocateCell<JSMessagePort>(globalObject->vm())) JSMessagePort(structure, *globalObject, WTFMove(impl));
ptr->finishCreation(globalObject->vm());
return ptr;
}
static JSC::JSObject* createPrototype(JSC::VM&, JSDOMGlobalObject&);
static JSC::JSObject* prototype(JSC::VM&, JSDOMGlobalObject&);
static MessagePort* toWrapped(JSC::VM&, JSC::JSValue);
DECLARE_INFO;
static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
{
return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info(), JSC::NonArray);
}
static JSC::JSValue getConstructor(JSC::VM&, const JSC::JSGlobalObject*);
template<typename, JSC::SubspaceAccess mode> static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
{
if constexpr (mode == JSC::SubspaceAccess::Concurrently)
return nullptr;
return subspaceForImpl(vm);
}
static JSC::GCClient::IsoSubspace* subspaceForImpl(JSC::VM& vm);
DECLARE_VISIT_CHILDREN;
template<typename Visitor> void visitAdditionalChildren(Visitor&);
template<typename Visitor> static void visitOutputConstraints(JSCell*, Visitor&);
static void analyzeHeap(JSCell*, JSC::HeapAnalyzer&);
MessagePort& wrapped() const
{
return static_cast<MessagePort&>(Base::wrapped());
}
protected:
JSMessagePort(JSC::Structure*, JSDOMGlobalObject&, Ref<MessagePort>&&);
void finishCreation(JSC::VM&);
};
class JSMessagePortOwner final : public JSC::WeakHandleOwner {
public:
bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::AbstractSlotVisitor&, const char**) final;
void finalize(JSC::Handle<JSC::Unknown>, void* context) final;
};
inline JSC::WeakHandleOwner* wrapperOwner(DOMWrapperWorld&, MessagePort*)
{
static NeverDestroyed<JSMessagePortOwner> owner;
return &owner.get();
}
inline void* wrapperKey(MessagePort* wrappableObject)
{
return wrappableObject;
}
JSC::JSValue toJS(JSC::JSGlobalObject*, JSDOMGlobalObject*, MessagePort&);
inline JSC::JSValue toJS(JSC::JSGlobalObject* lexicalGlobalObject, JSDOMGlobalObject* globalObject, MessagePort* impl) { return impl ? toJS(lexicalGlobalObject, globalObject, *impl) : JSC::jsNull(); }
JSC::JSValue toJSNewlyCreated(JSC::JSGlobalObject*, JSDOMGlobalObject*, Ref<MessagePort>&&);
inline JSC::JSValue toJSNewlyCreated(JSC::JSGlobalObject* lexicalGlobalObject, JSDOMGlobalObject* globalObject, RefPtr<MessagePort>&& impl) { return impl ? toJSNewlyCreated(lexicalGlobalObject, globalObject, impl.releaseNonNull()) : JSC::jsNull(); }
template<> struct JSDOMWrapperConverterTraits<MessagePort> {
using WrapperClass = JSMessagePort;
using ToWrappedReturnType = MessagePort*;
};
} // namespace WebCore

View File

@@ -0,0 +1,377 @@
/*
This file is part of the WebKit open source project.
This file has been generated by generate-bindings.pl. DO NOT MODIFY!
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include "config.h"
#include "JSPromiseRejectionEvent.h"
#include "ActiveDOMObject.h"
#include "DOMPromiseProxy.h"
#include "ExtendedDOMClientIsoSubspaces.h"
#include "ExtendedDOMIsoSubspaces.h"
#include "JSDOMAttribute.h"
#include "JSDOMBinding.h"
#include "JSDOMConstructor.h"
#include "JSDOMConvertAny.h"
#include "JSDOMConvertBoolean.h"
#include "JSDOMConvertInterface.h"
#include "JSDOMConvertPromise.h"
#include "JSDOMConvertStrings.h"
#include "JSDOMExceptionHandling.h"
#include "JSDOMGlobalObject.h"
#include "JSDOMGlobalObjectInlines.h"
#include "JSDOMWrapperCache.h"
#include "ScriptExecutionContext.h"
#include "WebCoreJSClientData.h"
#include <JavaScriptCore/HeapAnalyzer.h>
#include <JavaScriptCore/JSCInlines.h>
#include <JavaScriptCore/JSDestructibleObjectHeapCellType.h>
#include <JavaScriptCore/SlotVisitorMacros.h>
#include <JavaScriptCore/SubspaceInlines.h>
#include <wtf/GetPtr.h>
#include <wtf/PointerPreparations.h>
#include <wtf/URL.h>
namespace WebCore {
using namespace JSC;
template<> PromiseRejectionEvent::Init convertDictionary<PromiseRejectionEvent::Init>(JSGlobalObject& lexicalGlobalObject, JSValue value)
{
VM& vm = JSC::getVM(&lexicalGlobalObject);
auto throwScope = DECLARE_THROW_SCOPE(vm);
bool isNullOrUndefined = value.isUndefinedOrNull();
auto* object = isNullOrUndefined ? nullptr : value.getObject();
if (UNLIKELY(!isNullOrUndefined && !object)) {
throwTypeError(&lexicalGlobalObject, throwScope);
return { };
}
PromiseRejectionEvent::Init result;
JSValue bubblesValue;
if (isNullOrUndefined)
bubblesValue = jsUndefined();
else {
bubblesValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "bubbles"));
RETURN_IF_EXCEPTION(throwScope, { });
}
if (!bubblesValue.isUndefined()) {
result.bubbles = convert<IDLBoolean>(lexicalGlobalObject, bubblesValue);
RETURN_IF_EXCEPTION(throwScope, { });
} else
result.bubbles = false;
JSValue cancelableValue;
if (isNullOrUndefined)
cancelableValue = jsUndefined();
else {
cancelableValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "cancelable"));
RETURN_IF_EXCEPTION(throwScope, { });
}
if (!cancelableValue.isUndefined()) {
result.cancelable = convert<IDLBoolean>(lexicalGlobalObject, cancelableValue);
RETURN_IF_EXCEPTION(throwScope, { });
} else
result.cancelable = false;
JSValue composedValue;
if (isNullOrUndefined)
composedValue = jsUndefined();
else {
composedValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "composed"));
RETURN_IF_EXCEPTION(throwScope, { });
}
if (!composedValue.isUndefined()) {
result.composed = convert<IDLBoolean>(lexicalGlobalObject, composedValue);
RETURN_IF_EXCEPTION(throwScope, { });
} else
result.composed = false;
JSValue promiseValue;
if (isNullOrUndefined)
promiseValue = jsUndefined();
else {
promiseValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "promise"));
RETURN_IF_EXCEPTION(throwScope, { });
}
if (!promiseValue.isUndefined()) {
result.promise = convert<IDLPromise<IDLAny>>(lexicalGlobalObject, promiseValue);
RETURN_IF_EXCEPTION(throwScope, { });
} else {
throwRequiredMemberTypeError(lexicalGlobalObject, throwScope, "promise", "PromiseRejectionEventInit", "Promise");
return { };
}
JSValue reasonValue;
if (isNullOrUndefined)
reasonValue = jsUndefined();
else {
reasonValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "reason"));
RETURN_IF_EXCEPTION(throwScope, { });
}
if (!reasonValue.isUndefined()) {
result.reason = convert<IDLAny>(lexicalGlobalObject, reasonValue);
RETURN_IF_EXCEPTION(throwScope, { });
} else
result.reason = jsUndefined();
return result;
}
// Attributes
static JSC_DECLARE_CUSTOM_GETTER(jsPromiseRejectionEventConstructor);
static JSC_DECLARE_CUSTOM_GETTER(jsPromiseRejectionEvent_promise);
static JSC_DECLARE_CUSTOM_GETTER(jsPromiseRejectionEvent_reason);
class JSPromiseRejectionEventPrototype final : public JSC::JSNonFinalObject {
public:
using Base = JSC::JSNonFinalObject;
static JSPromiseRejectionEventPrototype* create(JSC::VM& vm, JSDOMGlobalObject* globalObject, JSC::Structure* structure)
{
JSPromiseRejectionEventPrototype* ptr = new (NotNull, JSC::allocateCell<JSPromiseRejectionEventPrototype>(vm)) JSPromiseRejectionEventPrototype(vm, globalObject, structure);
ptr->finishCreation(vm);
return ptr;
}
DECLARE_INFO;
template<typename CellType, JSC::SubspaceAccess>
static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
{
STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSPromiseRejectionEventPrototype, Base);
return &vm.plainObjectSpace();
}
static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
{
return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info());
}
private:
JSPromiseRejectionEventPrototype(JSC::VM& vm, JSC::JSGlobalObject*, JSC::Structure* structure)
: JSC::JSNonFinalObject(vm, structure)
{
}
void finishCreation(JSC::VM&);
};
STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSPromiseRejectionEventPrototype, JSPromiseRejectionEventPrototype::Base);
using JSPromiseRejectionEventDOMConstructor = JSDOMConstructor<JSPromiseRejectionEvent>;
template<> EncodedJSValue JSC_HOST_CALL_ATTRIBUTES JSPromiseRejectionEventDOMConstructor::construct(JSGlobalObject* lexicalGlobalObject, CallFrame* callFrame)
{
VM& vm = lexicalGlobalObject->vm();
auto throwScope = DECLARE_THROW_SCOPE(vm);
auto* castedThis = jsCast<JSPromiseRejectionEventDOMConstructor*>(callFrame->jsCallee());
ASSERT(castedThis);
if (UNLIKELY(callFrame->argumentCount() < 2))
return throwVMError(lexicalGlobalObject, throwScope, createNotEnoughArgumentsError(lexicalGlobalObject));
EnsureStillAliveScope argument0 = callFrame->uncheckedArgument(0);
auto type = convert<IDLDOMString>(*lexicalGlobalObject, argument0.value());
RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
EnsureStillAliveScope argument1 = callFrame->uncheckedArgument(1);
auto eventInitDict = convert<IDLDictionary<PromiseRejectionEvent::Init>>(*lexicalGlobalObject, argument1.value());
RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
auto object = PromiseRejectionEvent::create(WTFMove(type), WTFMove(eventInitDict));
if constexpr (IsExceptionOr<decltype(object)>)
RETURN_IF_EXCEPTION(throwScope, { });
static_assert(TypeOrExceptionOrUnderlyingType<decltype(object)>::isRef);
auto jsValue = toJSNewlyCreated<IDLInterface<PromiseRejectionEvent>>(*lexicalGlobalObject, *castedThis->globalObject(), throwScope, WTFMove(object));
if constexpr (IsExceptionOr<decltype(object)>)
RETURN_IF_EXCEPTION(throwScope, { });
setSubclassStructureIfNeeded<PromiseRejectionEvent>(lexicalGlobalObject, callFrame, asObject(jsValue));
RETURN_IF_EXCEPTION(throwScope, { });
return JSValue::encode(jsValue);
}
JSC_ANNOTATE_HOST_FUNCTION(JSPromiseRejectionEventDOMConstructorConstruct, JSPromiseRejectionEventDOMConstructor::construct);
template<> const ClassInfo JSPromiseRejectionEventDOMConstructor::s_info = { "PromiseRejectionEvent"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSPromiseRejectionEventDOMConstructor) };
template<> JSValue JSPromiseRejectionEventDOMConstructor::prototypeForStructure(JSC::VM& vm, const JSDOMGlobalObject& globalObject)
{
return JSEvent::getConstructor(vm, &globalObject);
}
template<> void JSPromiseRejectionEventDOMConstructor::initializeProperties(VM& vm, JSDOMGlobalObject& globalObject)
{
putDirect(vm, vm.propertyNames->length, jsNumber(2), JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum);
JSString* nameString = jsNontrivialString(vm, "PromiseRejectionEvent"_s);
m_originalName.set(vm, this, nameString);
putDirect(vm, vm.propertyNames->name, nameString, JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum);
putDirect(vm, vm.propertyNames->prototype, JSPromiseRejectionEvent::prototype(vm, globalObject), JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::DontDelete);
}
/* Hash table for prototype */
static const HashTableValue JSPromiseRejectionEventPrototypeTableValues[] =
{
{ "constructor", static_cast<unsigned>(JSC::PropertyAttribute::DontEnum), NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsPromiseRejectionEventConstructor), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
{ "promise", static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor), NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsPromiseRejectionEvent_promise), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
{ "reason", static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsPromiseRejectionEvent_reason), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
};
const ClassInfo JSPromiseRejectionEventPrototype::s_info = { "PromiseRejectionEvent"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSPromiseRejectionEventPrototype) };
void JSPromiseRejectionEventPrototype::finishCreation(VM& vm)
{
Base::finishCreation(vm);
reifyStaticProperties(vm, JSPromiseRejectionEvent::info(), JSPromiseRejectionEventPrototypeTableValues, *this);
JSC_TO_STRING_TAG_WITHOUT_TRANSITION();
}
const ClassInfo JSPromiseRejectionEvent::s_info = { "PromiseRejectionEvent"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSPromiseRejectionEvent) };
JSPromiseRejectionEvent::JSPromiseRejectionEvent(Structure* structure, JSDOMGlobalObject& globalObject, Ref<PromiseRejectionEvent>&& impl)
: JSEvent(structure, globalObject, WTFMove(impl))
{
}
void JSPromiseRejectionEvent::finishCreation(VM& vm)
{
Base::finishCreation(vm);
ASSERT(inherits(vm, info()));
static_assert(!std::is_base_of<ActiveDOMObject, PromiseRejectionEvent>::value, "Interface is not marked as [ActiveDOMObject] even though implementation class subclasses ActiveDOMObject.");
}
JSObject* JSPromiseRejectionEvent::createPrototype(VM& vm, JSDOMGlobalObject& globalObject)
{
return JSPromiseRejectionEventPrototype::create(vm, &globalObject, JSPromiseRejectionEventPrototype::createStructure(vm, &globalObject, JSEvent::prototype(vm, globalObject)));
}
JSObject* JSPromiseRejectionEvent::prototype(VM& vm, JSDOMGlobalObject& globalObject)
{
return getDOMPrototype<JSPromiseRejectionEvent>(vm, globalObject);
}
JSValue JSPromiseRejectionEvent::getConstructor(VM& vm, const JSGlobalObject* globalObject)
{
return getDOMConstructor<JSPromiseRejectionEventDOMConstructor, DOMConstructorID::PromiseRejectionEvent>(vm, *jsCast<const JSDOMGlobalObject*>(globalObject));
}
JSC_DEFINE_CUSTOM_GETTER(jsPromiseRejectionEventConstructor, (JSGlobalObject* lexicalGlobalObject, EncodedJSValue thisValue, PropertyName))
{
VM& vm = JSC::getVM(lexicalGlobalObject);
auto throwScope = DECLARE_THROW_SCOPE(vm);
auto* prototype = jsDynamicCast<JSPromiseRejectionEventPrototype*>(vm, JSValue::decode(thisValue));
if (UNLIKELY(!prototype))
return throwVMTypeError(lexicalGlobalObject, throwScope);
return JSValue::encode(JSPromiseRejectionEvent::getConstructor(JSC::getVM(lexicalGlobalObject), prototype->globalObject()));
}
static inline JSValue jsPromiseRejectionEvent_promiseGetter(JSGlobalObject& lexicalGlobalObject, JSPromiseRejectionEvent& thisObject)
{
auto& vm = JSC::getVM(&lexicalGlobalObject);
auto throwScope = DECLARE_THROW_SCOPE(vm);
auto& impl = thisObject.wrapped();
RELEASE_AND_RETURN(throwScope, (toJS<IDLPromise<IDLAny>>(lexicalGlobalObject, *thisObject.globalObject(), throwScope, [&]() -> decltype(auto) { return impl.promise(); })));
}
JSC_DEFINE_CUSTOM_GETTER(jsPromiseRejectionEvent_promise, (JSGlobalObject* lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName))
{
return IDLAttribute<JSPromiseRejectionEvent>::get<jsPromiseRejectionEvent_promiseGetter, CastedThisErrorBehavior::RejectPromise>(*lexicalGlobalObject, thisValue, attributeName);
}
static inline JSValue jsPromiseRejectionEvent_reasonGetter(JSGlobalObject& lexicalGlobalObject, JSPromiseRejectionEvent& thisObject)
{
auto& vm = JSC::getVM(&lexicalGlobalObject);
auto throwScope = DECLARE_THROW_SCOPE(vm);
auto& impl = thisObject.wrapped();
RELEASE_AND_RETURN(throwScope, (toJS<IDLAny>(lexicalGlobalObject, throwScope, impl.reason())));
}
JSC_DEFINE_CUSTOM_GETTER(jsPromiseRejectionEvent_reason, (JSGlobalObject* lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName))
{
return IDLAttribute<JSPromiseRejectionEvent>::get<jsPromiseRejectionEvent_reasonGetter, CastedThisErrorBehavior::Assert>(*lexicalGlobalObject, thisValue, attributeName);
}
JSC::GCClient::IsoSubspace* JSPromiseRejectionEvent::subspaceForImpl(JSC::VM& vm)
{
return WebCore::subspaceForImpl<JSPromiseRejectionEvent, UseCustomHeapCellType::No>(vm,
[] (auto& spaces) { return spaces.m_clientSubspaceForPromiseRejectionEvent.get(); },
[] (auto& spaces, auto&& space) { spaces.m_clientSubspaceForPromiseRejectionEvent = WTFMove(space); },
[] (auto& spaces) { return spaces.m_subspaceForPromiseRejectionEvent.get(); },
[] (auto& spaces, auto&& space) { spaces.m_subspaceForPromiseRejectionEvent = WTFMove(space); }
);
}
template<typename Visitor>
void JSPromiseRejectionEvent::visitChildrenImpl(JSCell* cell, Visitor& visitor)
{
auto* thisObject = jsCast<JSPromiseRejectionEvent*>(cell);
ASSERT_GC_OBJECT_INHERITS(thisObject, info());
Base::visitChildren(thisObject, visitor);
thisObject->visitAdditionalChildren(visitor);
}
DEFINE_VISIT_CHILDREN(JSPromiseRejectionEvent);
template<typename Visitor>
void JSPromiseRejectionEvent::visitOutputConstraints(JSCell* cell, Visitor& visitor)
{
auto* thisObject = jsCast<JSPromiseRejectionEvent*>(cell);
ASSERT_GC_OBJECT_INHERITS(thisObject, info());
Base::visitOutputConstraints(thisObject, visitor);
thisObject->visitAdditionalChildren(visitor);
}
template void JSPromiseRejectionEvent::visitOutputConstraints(JSCell*, AbstractSlotVisitor&);
template void JSPromiseRejectionEvent::visitOutputConstraints(JSCell*, SlotVisitor&);
void JSPromiseRejectionEvent::analyzeHeap(JSCell* cell, HeapAnalyzer& analyzer)
{
auto* thisObject = jsCast<JSPromiseRejectionEvent*>(cell);
analyzer.setWrappedObjectForCell(cell, &thisObject->wrapped());
if (thisObject->scriptExecutionContext())
analyzer.setLabelForCell(cell, "url " + thisObject->scriptExecutionContext()->url().string());
Base::analyzeHeap(cell, analyzer);
}
#if ENABLE(BINDING_INTEGRITY)
#if PLATFORM(WIN)
#pragma warning(disable: 4483)
extern "C" { extern void (*const __identifier("??_7PromiseRejectionEvent@WebCore@@6B@")[])(); }
#else
extern "C" { extern void* _ZTVN7WebCore21PromiseRejectionEventE[]; }
#endif
#endif
JSC::JSValue toJSNewlyCreated(JSC::JSGlobalObject*, JSDOMGlobalObject* globalObject, Ref<PromiseRejectionEvent>&& impl)
{
if constexpr (std::is_polymorphic_v<PromiseRejectionEvent>) {
#if ENABLE(BINDING_INTEGRITY)
const void* actualVTablePointer = getVTablePointer(impl.ptr());
#if PLATFORM(WIN)
void* expectedVTablePointer = __identifier("??_7PromiseRejectionEvent@WebCore@@6B@");
#else
void* expectedVTablePointer = &_ZTVN7WebCore21PromiseRejectionEventE[2];
#endif
// If you hit this assertion you either have a use after free bug, or
// PromiseRejectionEvent has subclasses. If PromiseRejectionEvent has subclasses that get passed
// to toJS() we currently require PromiseRejectionEvent you to opt out of binding hardening
// by adding the SkipVTableValidation attribute to the interface IDL definition
RELEASE_ASSERT(actualVTablePointer == expectedVTablePointer);
#endif
}
return createWrapper<PromiseRejectionEvent>(globalObject, WTFMove(impl));
}
JSC::JSValue toJS(JSC::JSGlobalObject* lexicalGlobalObject, JSDOMGlobalObject* globalObject, PromiseRejectionEvent& impl)
{
return wrap(lexicalGlobalObject, globalObject, impl);
}
}

View File

@@ -0,0 +1,3 @@
JSPromiseRejectionEvent.h : Event.idl EventInit.idl
Event.idl :
EventInit.idl :

View File

@@ -0,0 +1,86 @@
/*
This file is part of the WebKit open source project.
This file has been generated by generate-bindings.pl. DO NOT MODIFY!
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#pragma once
#include "JSDOMConvertDictionary.h"
#include "JSDOMWrapper.h"
#include "JSEvent.h"
#include "PromiseRejectionEvent.h"
namespace WebCore {
class JSPromiseRejectionEvent : public JSEvent {
public:
using Base = JSEvent;
using DOMWrapped = PromiseRejectionEvent;
static JSPromiseRejectionEvent* create(JSC::Structure* structure, JSDOMGlobalObject* globalObject, Ref<PromiseRejectionEvent>&& impl)
{
JSPromiseRejectionEvent* ptr = new (NotNull, JSC::allocateCell<JSPromiseRejectionEvent>(globalObject->vm())) JSPromiseRejectionEvent(structure, *globalObject, WTFMove(impl));
ptr->finishCreation(globalObject->vm());
return ptr;
}
static JSC::JSObject* createPrototype(JSC::VM&, JSDOMGlobalObject&);
static JSC::JSObject* prototype(JSC::VM&, JSDOMGlobalObject&);
DECLARE_INFO;
static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
{
return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::JSType(JSEventType), StructureFlags), info(), JSC::NonArray);
}
static JSC::JSValue getConstructor(JSC::VM&, const JSC::JSGlobalObject*);
template<typename, JSC::SubspaceAccess mode> static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
{
if constexpr (mode == JSC::SubspaceAccess::Concurrently)
return nullptr;
return subspaceForImpl(vm);
}
static JSC::GCClient::IsoSubspace* subspaceForImpl(JSC::VM& vm);
DECLARE_VISIT_CHILDREN;
template<typename Visitor> void visitAdditionalChildren(Visitor&);
template<typename Visitor> static void visitOutputConstraints(JSCell*, Visitor&);
static void analyzeHeap(JSCell*, JSC::HeapAnalyzer&);
PromiseRejectionEvent& wrapped() const
{
return static_cast<PromiseRejectionEvent&>(Base::wrapped());
}
protected:
JSPromiseRejectionEvent(JSC::Structure*, JSDOMGlobalObject&, Ref<PromiseRejectionEvent>&&);
void finishCreation(JSC::VM&);
};
JSC::JSValue toJS(JSC::JSGlobalObject*, JSDOMGlobalObject*, PromiseRejectionEvent&);
inline JSC::JSValue toJS(JSC::JSGlobalObject* lexicalGlobalObject, JSDOMGlobalObject* globalObject, PromiseRejectionEvent* impl) { return impl ? toJS(lexicalGlobalObject, globalObject, *impl) : JSC::jsNull(); }
JSC::JSValue toJSNewlyCreated(JSC::JSGlobalObject*, JSDOMGlobalObject*, Ref<PromiseRejectionEvent>&&);
inline JSC::JSValue toJSNewlyCreated(JSC::JSGlobalObject* lexicalGlobalObject, JSDOMGlobalObject* globalObject, RefPtr<PromiseRejectionEvent>&& impl) { return impl ? toJSNewlyCreated(lexicalGlobalObject, globalObject, impl.releaseNonNull()) : JSC::jsNull(); }
template<> struct JSDOMWrapperConverterTraits<PromiseRejectionEvent> {
using WrapperClass = JSPromiseRejectionEvent;
using ToWrappedReturnType = PromiseRejectionEvent*;
};
template<> PromiseRejectionEvent::Init convertDictionary<PromiseRejectionEvent::Init>(JSC::JSGlobalObject&, JSC::JSValue);
} // namespace WebCore

View File

@@ -0,0 +1,59 @@
/*
This file is part of the WebKit open source project.
This file has been generated by generate-bindings.pl. DO NOT MODIFY!
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include "config.h"
#include "JSStructuredSerializeOptions.h"
#include "JSDOMConvertObject.h"
#include "JSDOMConvertSequences.h"
#include <JavaScriptCore/JSArray.h>
#include <JavaScriptCore/JSCInlines.h>
namespace WebCore {
using namespace JSC;
template<> StructuredSerializeOptions convertDictionary<StructuredSerializeOptions>(JSGlobalObject& lexicalGlobalObject, JSValue value)
{
VM& vm = JSC::getVM(&lexicalGlobalObject);
auto throwScope = DECLARE_THROW_SCOPE(vm);
bool isNullOrUndefined = value.isUndefinedOrNull();
auto* object = isNullOrUndefined ? nullptr : value.getObject();
if (UNLIKELY(!isNullOrUndefined && !object)) {
throwTypeError(&lexicalGlobalObject, throwScope);
return { };
}
StructuredSerializeOptions result;
JSValue transferValue;
if (isNullOrUndefined)
transferValue = jsUndefined();
else {
transferValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "transfer"));
RETURN_IF_EXCEPTION(throwScope, { });
}
if (!transferValue.isUndefined()) {
result.transfer = convert<IDLSequence<IDLObject>>(lexicalGlobalObject, transferValue);
RETURN_IF_EXCEPTION(throwScope, { });
} else
result.transfer = Converter<IDLSequence<IDLObject>>::ReturnType{ };
return result;
}
} // namespace WebCore

View File

@@ -0,0 +1 @@
StructuredSerializeOptions.h :

View File

@@ -0,0 +1,30 @@
/*
This file is part of the WebKit open source project.
This file has been generated by generate-bindings.pl. DO NOT MODIFY!
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#pragma once
#include "JSDOMConvertDictionary.h"
#include "StructuredSerializeOptions.h"
namespace WebCore {
template<> StructuredSerializeOptions convertDictionary<StructuredSerializeOptions>(JSC::JSGlobalObject&, JSC::JSValue);
} // namespace WebCore

View File

@@ -0,0 +1,402 @@
/*
This file is part of the WebKit open source project.
This file has been generated by generate-bindings.pl. DO NOT MODIFY!
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include "config.h"
#include "JSWorkerLocation.h"
#include "ActiveDOMObject.h"
#include "ExtendedDOMClientIsoSubspaces.h"
#include "ExtendedDOMIsoSubspaces.h"
#include "JSDOMAttribute.h"
#include "JSDOMBinding.h"
#include "JSDOMConstructorNotConstructable.h"
#include "JSDOMConvertStrings.h"
#include "JSDOMExceptionHandling.h"
#include "JSDOMGlobalObjectInlines.h"
#include "JSDOMOperation.h"
#include "JSDOMWrapperCache.h"
#include "ScriptExecutionContext.h"
#include "WebCoreJSClientData.h"
#include <JavaScriptCore/FunctionPrototype.h>
#include <JavaScriptCore/HeapAnalyzer.h>
#include <JavaScriptCore/JSCInlines.h>
#include <JavaScriptCore/JSDestructibleObjectHeapCellType.h>
#include <JavaScriptCore/SlotVisitorMacros.h>
#include <JavaScriptCore/SubspaceInlines.h>
#include <wtf/GetPtr.h>
#include <wtf/PointerPreparations.h>
#include <wtf/URL.h>
namespace WebCore {
using namespace JSC;
// Functions
static JSC_DECLARE_HOST_FUNCTION(jsWorkerLocationPrototypeFunction_toString);
// Attributes
static JSC_DECLARE_CUSTOM_GETTER(jsWorkerLocationConstructor);
static JSC_DECLARE_CUSTOM_GETTER(jsWorkerLocation_href);
static JSC_DECLARE_CUSTOM_GETTER(jsWorkerLocation_protocol);
static JSC_DECLARE_CUSTOM_GETTER(jsWorkerLocation_host);
static JSC_DECLARE_CUSTOM_GETTER(jsWorkerLocation_hostname);
static JSC_DECLARE_CUSTOM_GETTER(jsWorkerLocation_port);
static JSC_DECLARE_CUSTOM_GETTER(jsWorkerLocation_pathname);
static JSC_DECLARE_CUSTOM_GETTER(jsWorkerLocation_search);
static JSC_DECLARE_CUSTOM_GETTER(jsWorkerLocation_hash);
static JSC_DECLARE_CUSTOM_GETTER(jsWorkerLocation_origin);
class JSWorkerLocationPrototype final : public JSC::JSNonFinalObject {
public:
using Base = JSC::JSNonFinalObject;
static JSWorkerLocationPrototype* create(JSC::VM& vm, JSDOMGlobalObject* globalObject, JSC::Structure* structure)
{
JSWorkerLocationPrototype* ptr = new (NotNull, JSC::allocateCell<JSWorkerLocationPrototype>(vm)) JSWorkerLocationPrototype(vm, globalObject, structure);
ptr->finishCreation(vm);
return ptr;
}
DECLARE_INFO;
template<typename CellType, JSC::SubspaceAccess>
static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
{
STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSWorkerLocationPrototype, Base);
return &vm.plainObjectSpace();
}
static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
{
return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info());
}
private:
JSWorkerLocationPrototype(JSC::VM& vm, JSC::JSGlobalObject*, JSC::Structure* structure)
: JSC::JSNonFinalObject(vm, structure)
{
}
void finishCreation(JSC::VM&);
};
STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSWorkerLocationPrototype, JSWorkerLocationPrototype::Base);
using JSWorkerLocationDOMConstructor = JSDOMConstructorNotConstructable<JSWorkerLocation>;
template<> const ClassInfo JSWorkerLocationDOMConstructor::s_info = { "WorkerLocation"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSWorkerLocationDOMConstructor) };
template<> JSValue JSWorkerLocationDOMConstructor::prototypeForStructure(JSC::VM& vm, const JSDOMGlobalObject& globalObject)
{
UNUSED_PARAM(vm);
return globalObject.functionPrototype();
}
template<> void JSWorkerLocationDOMConstructor::initializeProperties(VM& vm, JSDOMGlobalObject& globalObject)
{
putDirect(vm, vm.propertyNames->length, jsNumber(0), JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum);
JSString* nameString = jsNontrivialString(vm, "WorkerLocation"_s);
m_originalName.set(vm, this, nameString);
putDirect(vm, vm.propertyNames->name, nameString, JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum);
putDirect(vm, vm.propertyNames->prototype, JSWorkerLocation::prototype(vm, globalObject), JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::DontDelete);
}
/* Hash table for prototype */
static const HashTableValue JSWorkerLocationPrototypeTableValues[] =
{
{ "constructor", static_cast<unsigned>(JSC::PropertyAttribute::DontEnum), NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsWorkerLocationConstructor), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
{ "href", static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsWorkerLocation_href), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
{ "protocol", static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsWorkerLocation_protocol), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
{ "host", static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsWorkerLocation_host), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
{ "hostname", static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsWorkerLocation_hostname), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
{ "port", static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsWorkerLocation_port), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
{ "pathname", static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsWorkerLocation_pathname), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
{ "search", static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsWorkerLocation_search), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
{ "hash", static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsWorkerLocation_hash), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
{ "origin", static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsWorkerLocation_origin), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
{ "toString", static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t)static_cast<RawNativeFunction>(jsWorkerLocationPrototypeFunction_toString), (intptr_t) (0) } },
};
const ClassInfo JSWorkerLocationPrototype::s_info = { "WorkerLocation"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSWorkerLocationPrototype) };
void JSWorkerLocationPrototype::finishCreation(VM& vm)
{
Base::finishCreation(vm);
reifyStaticProperties(vm, JSWorkerLocation::info(), JSWorkerLocationPrototypeTableValues, *this);
JSC_TO_STRING_TAG_WITHOUT_TRANSITION();
}
const ClassInfo JSWorkerLocation::s_info = { "WorkerLocation"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSWorkerLocation) };
JSWorkerLocation::JSWorkerLocation(Structure* structure, JSDOMGlobalObject& globalObject, Ref<WorkerLocation>&& impl)
: JSDOMWrapper<WorkerLocation>(structure, globalObject, WTFMove(impl))
{
}
void JSWorkerLocation::finishCreation(VM& vm)
{
Base::finishCreation(vm);
ASSERT(inherits(vm, info()));
static_assert(!std::is_base_of<ActiveDOMObject, WorkerLocation>::value, "Interface is not marked as [ActiveDOMObject] even though implementation class subclasses ActiveDOMObject.");
}
JSObject* JSWorkerLocation::createPrototype(VM& vm, JSDOMGlobalObject& globalObject)
{
return JSWorkerLocationPrototype::create(vm, &globalObject, JSWorkerLocationPrototype::createStructure(vm, &globalObject, globalObject.objectPrototype()));
}
JSObject* JSWorkerLocation::prototype(VM& vm, JSDOMGlobalObject& globalObject)
{
return getDOMPrototype<JSWorkerLocation>(vm, globalObject);
}
JSValue JSWorkerLocation::getConstructor(VM& vm, const JSGlobalObject* globalObject)
{
return getDOMConstructor<JSWorkerLocationDOMConstructor, DOMConstructorID::WorkerLocation>(vm, *jsCast<const JSDOMGlobalObject*>(globalObject));
}
void JSWorkerLocation::destroy(JSC::JSCell* cell)
{
JSWorkerLocation* thisObject = static_cast<JSWorkerLocation*>(cell);
thisObject->JSWorkerLocation::~JSWorkerLocation();
}
JSC_DEFINE_CUSTOM_GETTER(jsWorkerLocationConstructor, (JSGlobalObject* lexicalGlobalObject, EncodedJSValue thisValue, PropertyName))
{
VM& vm = JSC::getVM(lexicalGlobalObject);
auto throwScope = DECLARE_THROW_SCOPE(vm);
auto* prototype = jsDynamicCast<JSWorkerLocationPrototype*>(vm, JSValue::decode(thisValue));
if (UNLIKELY(!prototype))
return throwVMTypeError(lexicalGlobalObject, throwScope);
return JSValue::encode(JSWorkerLocation::getConstructor(JSC::getVM(lexicalGlobalObject), prototype->globalObject()));
}
static inline JSValue jsWorkerLocation_hrefGetter(JSGlobalObject& lexicalGlobalObject, JSWorkerLocation& thisObject)
{
auto& vm = JSC::getVM(&lexicalGlobalObject);
auto throwScope = DECLARE_THROW_SCOPE(vm);
auto& impl = thisObject.wrapped();
RELEASE_AND_RETURN(throwScope, (toJS<IDLUSVString>(lexicalGlobalObject, throwScope, impl.href())));
}
JSC_DEFINE_CUSTOM_GETTER(jsWorkerLocation_href, (JSGlobalObject* lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName))
{
return IDLAttribute<JSWorkerLocation>::get<jsWorkerLocation_hrefGetter, CastedThisErrorBehavior::Assert>(*lexicalGlobalObject, thisValue, attributeName);
}
static inline JSValue jsWorkerLocation_protocolGetter(JSGlobalObject& lexicalGlobalObject, JSWorkerLocation& thisObject)
{
auto& vm = JSC::getVM(&lexicalGlobalObject);
auto throwScope = DECLARE_THROW_SCOPE(vm);
auto& impl = thisObject.wrapped();
RELEASE_AND_RETURN(throwScope, (toJS<IDLUSVString>(lexicalGlobalObject, throwScope, impl.protocol())));
}
JSC_DEFINE_CUSTOM_GETTER(jsWorkerLocation_protocol, (JSGlobalObject* lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName))
{
return IDLAttribute<JSWorkerLocation>::get<jsWorkerLocation_protocolGetter, CastedThisErrorBehavior::Assert>(*lexicalGlobalObject, thisValue, attributeName);
}
static inline JSValue jsWorkerLocation_hostGetter(JSGlobalObject& lexicalGlobalObject, JSWorkerLocation& thisObject)
{
auto& vm = JSC::getVM(&lexicalGlobalObject);
auto throwScope = DECLARE_THROW_SCOPE(vm);
auto& impl = thisObject.wrapped();
RELEASE_AND_RETURN(throwScope, (toJS<IDLUSVString>(lexicalGlobalObject, throwScope, impl.host())));
}
JSC_DEFINE_CUSTOM_GETTER(jsWorkerLocation_host, (JSGlobalObject* lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName))
{
return IDLAttribute<JSWorkerLocation>::get<jsWorkerLocation_hostGetter, CastedThisErrorBehavior::Assert>(*lexicalGlobalObject, thisValue, attributeName);
}
static inline JSValue jsWorkerLocation_hostnameGetter(JSGlobalObject& lexicalGlobalObject, JSWorkerLocation& thisObject)
{
auto& vm = JSC::getVM(&lexicalGlobalObject);
auto throwScope = DECLARE_THROW_SCOPE(vm);
auto& impl = thisObject.wrapped();
RELEASE_AND_RETURN(throwScope, (toJS<IDLUSVString>(lexicalGlobalObject, throwScope, impl.hostname())));
}
JSC_DEFINE_CUSTOM_GETTER(jsWorkerLocation_hostname, (JSGlobalObject* lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName))
{
return IDLAttribute<JSWorkerLocation>::get<jsWorkerLocation_hostnameGetter, CastedThisErrorBehavior::Assert>(*lexicalGlobalObject, thisValue, attributeName);
}
static inline JSValue jsWorkerLocation_portGetter(JSGlobalObject& lexicalGlobalObject, JSWorkerLocation& thisObject)
{
auto& vm = JSC::getVM(&lexicalGlobalObject);
auto throwScope = DECLARE_THROW_SCOPE(vm);
auto& impl = thisObject.wrapped();
RELEASE_AND_RETURN(throwScope, (toJS<IDLUSVString>(lexicalGlobalObject, throwScope, impl.port())));
}
JSC_DEFINE_CUSTOM_GETTER(jsWorkerLocation_port, (JSGlobalObject* lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName))
{
return IDLAttribute<JSWorkerLocation>::get<jsWorkerLocation_portGetter, CastedThisErrorBehavior::Assert>(*lexicalGlobalObject, thisValue, attributeName);
}
static inline JSValue jsWorkerLocation_pathnameGetter(JSGlobalObject& lexicalGlobalObject, JSWorkerLocation& thisObject)
{
auto& vm = JSC::getVM(&lexicalGlobalObject);
auto throwScope = DECLARE_THROW_SCOPE(vm);
auto& impl = thisObject.wrapped();
RELEASE_AND_RETURN(throwScope, (toJS<IDLUSVString>(lexicalGlobalObject, throwScope, impl.pathname())));
}
JSC_DEFINE_CUSTOM_GETTER(jsWorkerLocation_pathname, (JSGlobalObject* lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName))
{
return IDLAttribute<JSWorkerLocation>::get<jsWorkerLocation_pathnameGetter, CastedThisErrorBehavior::Assert>(*lexicalGlobalObject, thisValue, attributeName);
}
static inline JSValue jsWorkerLocation_searchGetter(JSGlobalObject& lexicalGlobalObject, JSWorkerLocation& thisObject)
{
auto& vm = JSC::getVM(&lexicalGlobalObject);
auto throwScope = DECLARE_THROW_SCOPE(vm);
auto& impl = thisObject.wrapped();
RELEASE_AND_RETURN(throwScope, (toJS<IDLUSVString>(lexicalGlobalObject, throwScope, impl.search())));
}
JSC_DEFINE_CUSTOM_GETTER(jsWorkerLocation_search, (JSGlobalObject* lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName))
{
return IDLAttribute<JSWorkerLocation>::get<jsWorkerLocation_searchGetter, CastedThisErrorBehavior::Assert>(*lexicalGlobalObject, thisValue, attributeName);
}
static inline JSValue jsWorkerLocation_hashGetter(JSGlobalObject& lexicalGlobalObject, JSWorkerLocation& thisObject)
{
auto& vm = JSC::getVM(&lexicalGlobalObject);
auto throwScope = DECLARE_THROW_SCOPE(vm);
auto& impl = thisObject.wrapped();
RELEASE_AND_RETURN(throwScope, (toJS<IDLUSVString>(lexicalGlobalObject, throwScope, impl.hash())));
}
JSC_DEFINE_CUSTOM_GETTER(jsWorkerLocation_hash, (JSGlobalObject* lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName))
{
return IDLAttribute<JSWorkerLocation>::get<jsWorkerLocation_hashGetter, CastedThisErrorBehavior::Assert>(*lexicalGlobalObject, thisValue, attributeName);
}
static inline JSValue jsWorkerLocation_originGetter(JSGlobalObject& lexicalGlobalObject, JSWorkerLocation& thisObject)
{
auto& vm = JSC::getVM(&lexicalGlobalObject);
auto throwScope = DECLARE_THROW_SCOPE(vm);
auto& impl = thisObject.wrapped();
RELEASE_AND_RETURN(throwScope, (toJS<IDLUSVString>(lexicalGlobalObject, throwScope, impl.origin())));
}
JSC_DEFINE_CUSTOM_GETTER(jsWorkerLocation_origin, (JSGlobalObject* lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName))
{
return IDLAttribute<JSWorkerLocation>::get<jsWorkerLocation_originGetter, CastedThisErrorBehavior::Assert>(*lexicalGlobalObject, thisValue, attributeName);
}
static inline JSC::EncodedJSValue jsWorkerLocationPrototypeFunction_toStringBody(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, typename IDLOperation<JSWorkerLocation>::ClassParameter castedThis)
{
auto& vm = JSC::getVM(lexicalGlobalObject);
auto throwScope = DECLARE_THROW_SCOPE(vm);
UNUSED_PARAM(throwScope);
UNUSED_PARAM(callFrame);
auto& impl = castedThis->wrapped();
RELEASE_AND_RETURN(throwScope, JSValue::encode(toJS<IDLUSVString>(*lexicalGlobalObject, throwScope, impl.href())));
}
JSC_DEFINE_HOST_FUNCTION(jsWorkerLocationPrototypeFunction_toString, (JSGlobalObject* lexicalGlobalObject, CallFrame* callFrame))
{
return IDLOperation<JSWorkerLocation>::call<jsWorkerLocationPrototypeFunction_toStringBody>(*lexicalGlobalObject, *callFrame, "toString");
}
JSC::GCClient::IsoSubspace* JSWorkerLocation::subspaceForImpl(JSC::VM& vm)
{
return WebCore::subspaceForImpl<JSWorkerLocation, UseCustomHeapCellType::No>(vm,
[] (auto& spaces) { return spaces.m_clientSubspaceForWorkerLocation.get(); },
[] (auto& spaces, auto&& space) { spaces.m_clientSubspaceForWorkerLocation = WTFMove(space); },
[] (auto& spaces) { return spaces.m_subspaceForWorkerLocation.get(); },
[] (auto& spaces, auto&& space) { spaces.m_subspaceForWorkerLocation = WTFMove(space); }
);
}
void JSWorkerLocation::analyzeHeap(JSCell* cell, HeapAnalyzer& analyzer)
{
auto* thisObject = jsCast<JSWorkerLocation*>(cell);
analyzer.setWrappedObjectForCell(cell, &thisObject->wrapped());
if (thisObject->scriptExecutionContext())
analyzer.setLabelForCell(cell, "url " + thisObject->scriptExecutionContext()->url().string());
Base::analyzeHeap(cell, analyzer);
}
bool JSWorkerLocationOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, AbstractSlotVisitor& visitor, const char** reason)
{
auto* jsWorkerLocation = jsCast<JSWorkerLocation*>(handle.slot()->asCell());
WorkerLocation* root = &jsWorkerLocation->wrapped();
if (UNLIKELY(reason))
*reason = "Reachable from WorkerLocation";
return visitor.containsOpaqueRoot(root);
}
void JSWorkerLocationOwner::finalize(JSC::Handle<JSC::Unknown> handle, void* context)
{
auto* jsWorkerLocation = static_cast<JSWorkerLocation*>(handle.slot()->asCell());
auto& world = *static_cast<DOMWrapperWorld*>(context);
uncacheWrapper(world, &jsWorkerLocation->wrapped(), jsWorkerLocation);
}
#if ENABLE(BINDING_INTEGRITY)
#if PLATFORM(WIN)
#pragma warning(disable: 4483)
extern "C" { extern void (*const __identifier("??_7WorkerLocation@WebCore@@6B@")[])(); }
#else
extern "C" { extern void* _ZTVN7WebCore14WorkerLocationE[]; }
#endif
#endif
JSC::JSValue toJSNewlyCreated(JSC::JSGlobalObject*, JSDOMGlobalObject* globalObject, Ref<WorkerLocation>&& impl)
{
if constexpr (std::is_polymorphic_v<WorkerLocation>) {
#if ENABLE(BINDING_INTEGRITY)
const void* actualVTablePointer = getVTablePointer(impl.ptr());
#if PLATFORM(WIN)
void* expectedVTablePointer = __identifier("??_7WorkerLocation@WebCore@@6B@");
#else
void* expectedVTablePointer = &_ZTVN7WebCore14WorkerLocationE[2];
#endif
// If you hit this assertion you either have a use after free bug, or
// WorkerLocation has subclasses. If WorkerLocation has subclasses that get passed
// to toJS() we currently require WorkerLocation you to opt out of binding hardening
// by adding the SkipVTableValidation attribute to the interface IDL definition
RELEASE_ASSERT(actualVTablePointer == expectedVTablePointer);
#endif
}
return createWrapper<WorkerLocation>(globalObject, WTFMove(impl));
}
JSC::JSValue toJS(JSC::JSGlobalObject* lexicalGlobalObject, JSDOMGlobalObject* globalObject, WorkerLocation& impl)
{
return wrap(lexicalGlobalObject, globalObject, impl);
}
WorkerLocation* JSWorkerLocation::toWrapped(JSC::VM& vm, JSC::JSValue value)
{
if (auto* wrapper = jsDynamicCast<JSWorkerLocation*>(vm, value))
return &wrapper->wrapped();
return nullptr;
}
}

View File

@@ -0,0 +1 @@
JSWorkerLocation.h :

View File

@@ -0,0 +1,93 @@
/*
This file is part of the WebKit open source project.
This file has been generated by generate-bindings.pl. DO NOT MODIFY!
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#pragma once
#include "JSDOMWrapper.h"
#include "WorkerLocation.h"
#include <wtf/NeverDestroyed.h>
namespace WebCore {
class JSWorkerLocation : public JSDOMWrapper<WorkerLocation> {
public:
using Base = JSDOMWrapper<WorkerLocation>;
static JSWorkerLocation* create(JSC::Structure* structure, JSDOMGlobalObject* globalObject, Ref<WorkerLocation>&& impl)
{
JSWorkerLocation* ptr = new (NotNull, JSC::allocateCell<JSWorkerLocation>(globalObject->vm())) JSWorkerLocation(structure, *globalObject, WTFMove(impl));
ptr->finishCreation(globalObject->vm());
return ptr;
}
static JSC::JSObject* createPrototype(JSC::VM&, JSDOMGlobalObject&);
static JSC::JSObject* prototype(JSC::VM&, JSDOMGlobalObject&);
static WorkerLocation* toWrapped(JSC::VM&, JSC::JSValue);
static void destroy(JSC::JSCell*);
DECLARE_INFO;
static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
{
return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info(), JSC::NonArray);
}
static JSC::JSValue getConstructor(JSC::VM&, const JSC::JSGlobalObject*);
template<typename, JSC::SubspaceAccess mode> static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
{
if constexpr (mode == JSC::SubspaceAccess::Concurrently)
return nullptr;
return subspaceForImpl(vm);
}
static JSC::GCClient::IsoSubspace* subspaceForImpl(JSC::VM& vm);
static void analyzeHeap(JSCell*, JSC::HeapAnalyzer&);
protected:
JSWorkerLocation(JSC::Structure*, JSDOMGlobalObject&, Ref<WorkerLocation>&&);
void finishCreation(JSC::VM&);
};
class JSWorkerLocationOwner final : public JSC::WeakHandleOwner {
public:
bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::AbstractSlotVisitor&, const char**) final;
void finalize(JSC::Handle<JSC::Unknown>, void* context) final;
};
inline JSC::WeakHandleOwner* wrapperOwner(DOMWrapperWorld&, WorkerLocation*)
{
static NeverDestroyed<JSWorkerLocationOwner> owner;
return &owner.get();
}
inline void* wrapperKey(WorkerLocation* wrappableObject)
{
return wrappableObject;
}
JSC::JSValue toJS(JSC::JSGlobalObject*, JSDOMGlobalObject*, WorkerLocation&);
inline JSC::JSValue toJS(JSC::JSGlobalObject* lexicalGlobalObject, JSDOMGlobalObject* globalObject, WorkerLocation* impl) { return impl ? toJS(lexicalGlobalObject, globalObject, *impl) : JSC::jsNull(); }
JSC::JSValue toJSNewlyCreated(JSC::JSGlobalObject*, JSDOMGlobalObject*, Ref<WorkerLocation>&&);
inline JSC::JSValue toJSNewlyCreated(JSC::JSGlobalObject* lexicalGlobalObject, JSDOMGlobalObject* globalObject, RefPtr<WorkerLocation>&& impl) { return impl ? toJSNewlyCreated(lexicalGlobalObject, globalObject, impl.releaseNonNull()) : JSC::jsNull(); }
template<> struct JSDOMWrapperConverterTraits<WorkerLocation> {
using WrapperClass = JSWorkerLocation;
using ToWrappedReturnType = WorkerLocation*;
};
} // namespace WebCore

View File

@@ -0,0 +1,5 @@
/*
This file is generated to inform build scripts that JSWorkerNavigator+MediaCapabilities.h and
JSWorkerNavigator+MediaCapabilities.cpp were created for WorkerNavigator+MediaCapabilities.idl, and prevent the build
scripts from trying to regenerate JSWorkerNavigator+MediaCapabilities.h and JSWorkerNavigator+MediaCapabilities.cpp on every build.
*/

View File

@@ -0,0 +1,5 @@
/*
This file is generated to inform build scripts that JSWorkerNavigator+MediaCapabilities.h and
JSWorkerNavigator+MediaCapabilities.cpp were created for WorkerNavigator+MediaCapabilities.idl, and prevent the build
scripts from trying to regenerate JSWorkerNavigator+MediaCapabilities.h and JSWorkerNavigator+MediaCapabilities.cpp on every build.
*/

View File

@@ -0,0 +1,569 @@
/*
This file is part of the WebKit open source project.
This file has been generated by generate-bindings.pl. DO NOT MODIFY!
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include "config.h"
#include "JSWorkerNavigator.h"
#include "ActiveDOMObject.h"
#include "ExtendedDOMClientIsoSubspaces.h"
#include "ExtendedDOMIsoSubspaces.h"
#include "JSDOMAttribute.h"
#include "JSDOMBinding.h"
#include "JSDOMConstructorNotConstructable.h"
#include "JSDOMConvertBoolean.h"
#include "JSDOMConvertInterface.h"
#include "JSDOMConvertNumbers.h"
#include "JSDOMConvertSequences.h"
#include "JSDOMConvertStrings.h"
#include "JSDOMExceptionHandling.h"
#include "JSDOMGlobalObject.h"
#include "JSDOMGlobalObjectInlines.h"
#include "JSDOMWrapperCache.h"
#include "JSGPU.h"
#include "JSMediaCapabilities.h"
#include "JSStorageManager.h"
#include "JSWebLockManager.h"
#include "ScriptExecutionContext.h"
#include "WebCoreJSClientData.h"
// #include "WorkerNavigatorMediaCapabilities.h"
#include <JavaScriptCore/FunctionPrototype.h>
#include <JavaScriptCore/HeapAnalyzer.h>
#include <JavaScriptCore/JSArray.h>
#include <JavaScriptCore/JSCInlines.h>
#include <JavaScriptCore/JSDestructibleObjectHeapCellType.h>
#include <JavaScriptCore/SlotVisitorMacros.h>
#include <JavaScriptCore/SubspaceInlines.h>
#include <wtf/GetPtr.h>
#include <wtf/PointerPreparations.h>
#include <wtf/URL.h>
#if ENABLE(SERVICE_WORKER)
#include "JSServiceWorkerContainer.h"
#endif
namespace WebCore {
using namespace JSC;
// Attributes
static JSC_DECLARE_CUSTOM_GETTER(jsWorkerNavigatorConstructor);
static JSC_DECLARE_CUSTOM_GETTER(jsWorkerNavigator_hardwareConcurrency);
static JSC_DECLARE_CUSTOM_GETTER(jsWorkerNavigator_gpu);
static JSC_DECLARE_CUSTOM_GETTER(jsWorkerNavigator_mediaCapabilities);
static JSC_DECLARE_CUSTOM_GETTER(jsWorkerNavigator_locks);
static JSC_DECLARE_CUSTOM_GETTER(jsWorkerNavigator_appCodeName);
static JSC_DECLARE_CUSTOM_GETTER(jsWorkerNavigator_appName);
static JSC_DECLARE_CUSTOM_GETTER(jsWorkerNavigator_appVersion);
static JSC_DECLARE_CUSTOM_GETTER(jsWorkerNavigator_platform);
static JSC_DECLARE_CUSTOM_GETTER(jsWorkerNavigator_product);
static JSC_DECLARE_CUSTOM_GETTER(jsWorkerNavigator_userAgent);
static JSC_DECLARE_CUSTOM_GETTER(jsWorkerNavigator_language);
static JSC_DECLARE_CUSTOM_GETTER(jsWorkerNavigator_languages);
static JSC_DECLARE_CUSTOM_GETTER(jsWorkerNavigator_onLine);
#if ENABLE(SERVICE_WORKER)
static JSC_DECLARE_CUSTOM_GETTER(jsWorkerNavigator_serviceWorker);
#endif
static JSC_DECLARE_CUSTOM_GETTER(jsWorkerNavigator_storage);
class JSWorkerNavigatorPrototype final : public JSC::JSNonFinalObject {
public:
using Base = JSC::JSNonFinalObject;
static JSWorkerNavigatorPrototype* create(JSC::VM& vm, JSDOMGlobalObject* globalObject, JSC::Structure* structure)
{
JSWorkerNavigatorPrototype* ptr = new (NotNull, JSC::allocateCell<JSWorkerNavigatorPrototype>(vm)) JSWorkerNavigatorPrototype(vm, globalObject, structure);
ptr->finishCreation(vm);
return ptr;
}
DECLARE_INFO;
template<typename CellType, JSC::SubspaceAccess>
static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
{
STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSWorkerNavigatorPrototype, Base);
return &vm.plainObjectSpace();
}
static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
{
return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info());
}
private:
JSWorkerNavigatorPrototype(JSC::VM& vm, JSC::JSGlobalObject*, JSC::Structure* structure)
: JSC::JSNonFinalObject(vm, structure)
{
}
void finishCreation(JSC::VM&);
};
STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSWorkerNavigatorPrototype, JSWorkerNavigatorPrototype::Base);
using JSWorkerNavigatorDOMConstructor = JSDOMConstructorNotConstructable<JSWorkerNavigator>;
template<> const ClassInfo JSWorkerNavigatorDOMConstructor::s_info = { "WorkerNavigator"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSWorkerNavigatorDOMConstructor) };
template<> JSValue JSWorkerNavigatorDOMConstructor::prototypeForStructure(JSC::VM& vm, const JSDOMGlobalObject& globalObject)
{
UNUSED_PARAM(vm);
return globalObject.functionPrototype();
}
template<> void JSWorkerNavigatorDOMConstructor::initializeProperties(VM& vm, JSDOMGlobalObject& globalObject)
{
putDirect(vm, vm.propertyNames->length, jsNumber(0), JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum);
JSString* nameString = jsNontrivialString(vm, "WorkerNavigator"_s);
m_originalName.set(vm, this, nameString);
putDirect(vm, vm.propertyNames->name, nameString, JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum);
putDirect(vm, vm.propertyNames->prototype, JSWorkerNavigator::prototype(vm, globalObject), JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::DontDelete);
}
/* Hash table for prototype */
static const HashTableValue JSWorkerNavigatorPrototypeTableValues[] = {
{ "constructor", static_cast<unsigned>(JSC::PropertyAttribute::DontEnum), NoIntrinsic, { (intptr_t) static_cast<PropertySlot::GetValueFunc>(jsWorkerNavigatorConstructor), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
{ "hardwareConcurrency", static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { (intptr_t) static_cast<PropertySlot::GetValueFunc>(jsWorkerNavigator_hardwareConcurrency), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
{ "gpu", static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { (intptr_t) static_cast<PropertySlot::GetValueFunc>(jsWorkerNavigator_gpu), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
{ "mediaCapabilities", static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { (intptr_t) static_cast<PropertySlot::GetValueFunc>(jsWorkerNavigator_mediaCapabilities), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
{ "locks", static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { (intptr_t) static_cast<PropertySlot::GetValueFunc>(jsWorkerNavigator_locks), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
{ "appCodeName", static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { (intptr_t) static_cast<PropertySlot::GetValueFunc>(jsWorkerNavigator_appCodeName), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
{ "appName", static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { (intptr_t) static_cast<PropertySlot::GetValueFunc>(jsWorkerNavigator_appName), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
{ "appVersion", static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { (intptr_t) static_cast<PropertySlot::GetValueFunc>(jsWorkerNavigator_appVersion), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
{ "platform", static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { (intptr_t) static_cast<PropertySlot::GetValueFunc>(jsWorkerNavigator_platform), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
{ "product", static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { (intptr_t) static_cast<PropertySlot::GetValueFunc>(jsWorkerNavigator_product), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
{ "userAgent", static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { (intptr_t) static_cast<PropertySlot::GetValueFunc>(jsWorkerNavigator_userAgent), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
{ "language", static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { (intptr_t) static_cast<PropertySlot::GetValueFunc>(jsWorkerNavigator_language), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
{ "languages", static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { (intptr_t) static_cast<PropertySlot::GetValueFunc>(jsWorkerNavigator_languages), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
{ "onLine", static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { (intptr_t) static_cast<PropertySlot::GetValueFunc>(jsWorkerNavigator_onLine), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
#if ENABLE(SERVICE_WORKER)
{ "serviceWorker", static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { (intptr_t) static_cast<PropertySlot::GetValueFunc>(jsWorkerNavigator_serviceWorker), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
#else
{ 0, 0, NoIntrinsic, { 0, 0 } },
#endif
{ "storage", static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { (intptr_t) static_cast<PropertySlot::GetValueFunc>(jsWorkerNavigator_storage), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
};
const ClassInfo JSWorkerNavigatorPrototype::s_info = { "WorkerNavigator"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSWorkerNavigatorPrototype) };
void JSWorkerNavigatorPrototype::finishCreation(VM& vm)
{
Base::finishCreation(vm);
reifyStaticProperties(vm, JSWorkerNavigator::info(), JSWorkerNavigatorPrototypeTableValues, *this);
bool hasDisabledRuntimeProperties = false;
if (true) {
// if (!(jsCast<JSDOMGlobalObject*>(globalObject())->scriptExecutionContext()->isSecureContext() && jsCast<JSDOMGlobalObject*>(globalObject())->scriptExecutionContext()->settingsValues().webGPU)) {
hasDisabledRuntimeProperties = true;
auto propertyName = Identifier::fromString(vm, reinterpret_cast<const LChar*>("gpu"), strlen("gpu"));
VM::DeletePropertyModeScope scope(vm, VM::DeletePropertyMode::IgnoreConfigurable);
DeletePropertySlot slot;
JSObject::deleteProperty(this, globalObject(), propertyName, slot);
}
if (true) {
// if (!jsCast<JSDOMGlobalObject*>(globalObject())->scriptExecutionContext()->settingsValues().mediaCapabilitiesEnabled) {
hasDisabledRuntimeProperties = true;
auto propertyName = Identifier::fromString(vm, reinterpret_cast<const LChar*>("mediaCapabilities"), strlen("mediaCapabilities"));
VM::DeletePropertyModeScope scope(vm, VM::DeletePropertyMode::IgnoreConfigurable);
DeletePropertySlot slot;
JSObject::deleteProperty(this, globalObject(), propertyName, slot);
}
if (true) {
// if (!(jsCast<JSDOMGlobalObject*>(globalObject())->scriptExecutionContext()->isSecureContext() && jsCast<JSDOMGlobalObject*>(globalObject())->scriptExecutionContext()->settingsValues().webLocksAPIEnabled)) {
hasDisabledRuntimeProperties = true;
auto propertyName = Identifier::fromString(vm, reinterpret_cast<const LChar*>("locks"), strlen("locks"));
VM::DeletePropertyModeScope scope(vm, VM::DeletePropertyMode::IgnoreConfigurable);
DeletePropertySlot slot;
JSObject::deleteProperty(this, globalObject(), propertyName, slot);
}
#if ENABLE(SERVICE_WORKER)
if (!(jsCast<JSDOMGlobalObject*>(globalObject())->scriptExecutionContext()->isSecureContext() && jsCast<JSDOMGlobalObject*>(globalObject())->scriptExecutionContext()->settingsValues().serviceWorkersEnabled)) {
hasDisabledRuntimeProperties = true;
auto propertyName = Identifier::fromString(vm, reinterpret_cast<const LChar*>("serviceWorker"), strlen("serviceWorker"));
VM::DeletePropertyModeScope scope(vm, VM::DeletePropertyMode::IgnoreConfigurable);
DeletePropertySlot slot;
JSObject::deleteProperty(this, globalObject(), propertyName, slot);
}
#endif
if (true) {
// if (!(jsCast<JSDOMGlobalObject*>(globalObject())->scriptExecutionContext()->isSecureContext() && jsCast<JSDOMGlobalObject*>(globalObject())->scriptExecutionContext()->settingsValues().storageAPIEnabled)) {
hasDisabledRuntimeProperties = true;
auto propertyName = Identifier::fromString(vm, reinterpret_cast<const LChar*>("storage"), strlen("storage"));
VM::DeletePropertyModeScope scope(vm, VM::DeletePropertyMode::IgnoreConfigurable);
DeletePropertySlot slot;
JSObject::deleteProperty(this, globalObject(), propertyName, slot);
}
if (hasDisabledRuntimeProperties && structure()->isDictionary())
flattenDictionaryObject(vm);
JSC_TO_STRING_TAG_WITHOUT_TRANSITION();
}
const ClassInfo JSWorkerNavigator::s_info = { "WorkerNavigator"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSWorkerNavigator) };
JSWorkerNavigator::JSWorkerNavigator(Structure* structure, JSDOMGlobalObject& globalObject, Ref<WorkerNavigator>&& impl)
: JSDOMWrapper<WorkerNavigator>(structure, globalObject, WTFMove(impl))
{
}
void JSWorkerNavigator::finishCreation(VM& vm)
{
Base::finishCreation(vm);
ASSERT(inherits(vm, info()));
static_assert(!std::is_base_of<ActiveDOMObject, WorkerNavigator>::value, "Interface is not marked as [ActiveDOMObject] even though implementation class subclasses ActiveDOMObject.");
}
JSObject* JSWorkerNavigator::createPrototype(VM& vm, JSDOMGlobalObject& globalObject)
{
return JSWorkerNavigatorPrototype::create(vm, &globalObject, JSWorkerNavigatorPrototype::createStructure(vm, &globalObject, globalObject.objectPrototype()));
}
JSObject* JSWorkerNavigator::prototype(VM& vm, JSDOMGlobalObject& globalObject)
{
return getDOMPrototype<JSWorkerNavigator>(vm, globalObject);
}
JSValue JSWorkerNavigator::getConstructor(VM& vm, const JSGlobalObject* globalObject)
{
return getDOMConstructor<JSWorkerNavigatorDOMConstructor, DOMConstructorID::WorkerNavigator>(vm, *jsCast<const JSDOMGlobalObject*>(globalObject));
}
void JSWorkerNavigator::destroy(JSC::JSCell* cell)
{
JSWorkerNavigator* thisObject = static_cast<JSWorkerNavigator*>(cell);
thisObject->JSWorkerNavigator::~JSWorkerNavigator();
}
JSC_DEFINE_CUSTOM_GETTER(jsWorkerNavigatorConstructor, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName))
{
VM& vm = JSC::getVM(lexicalGlobalObject);
auto throwScope = DECLARE_THROW_SCOPE(vm);
auto* prototype = jsDynamicCast<JSWorkerNavigatorPrototype*>(vm, JSValue::decode(thisValue));
if (UNLIKELY(!prototype))
return throwVMTypeError(lexicalGlobalObject, throwScope);
return JSValue::encode(JSWorkerNavigator::getConstructor(JSC::getVM(lexicalGlobalObject), prototype->globalObject()));
}
static inline JSValue jsWorkerNavigator_hardwareConcurrencyGetter(JSGlobalObject& lexicalGlobalObject, JSWorkerNavigator& thisObject)
{
auto& vm = JSC::getVM(&lexicalGlobalObject);
auto throwScope = DECLARE_THROW_SCOPE(vm);
auto& impl = thisObject.wrapped();
RELEASE_AND_RETURN(throwScope, (toJS<IDLUnsignedLongLong>(lexicalGlobalObject, throwScope, impl.hardwareConcurrency())));
}
JSC_DEFINE_CUSTOM_GETTER(jsWorkerNavigator_hardwareConcurrency, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName))
{
return IDLAttribute<JSWorkerNavigator>::get<jsWorkerNavigator_hardwareConcurrencyGetter, CastedThisErrorBehavior::Assert>(*lexicalGlobalObject, thisValue, attributeName);
}
// static inline JSValue jsWorkerNavigator_gpuGetter(JSGlobalObject& lexicalGlobalObject, JSWorkerNavigator& thisObject)
// {
// auto& vm = JSC::getVM(&lexicalGlobalObject);
// auto throwScope = DECLARE_THROW_SCOPE(vm);
// auto& impl = thisObject.wrapped();
// RELEASE_AND_RETURN(throwScope, (toJS<IDLInterface<GPU>>(lexicalGlobalObject, *thisObject.globalObject(), throwScope, impl.gpu())));
// }
JSC_DEFINE_CUSTOM_GETTER(jsWorkerNavigator_gpu, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName))
{
JSC_NOT_IMPLEMENTED_GETTER_BODY;
// return IDLAttribute<JSWorkerNavigator>::get<jsWorkerNavigator_gpuGetter, CastedThisErrorBehavior::Assert>(*lexicalGlobalObject, thisValue, attributeName);
}
// static inline JSValue jsWorkerNavigator_mediaCapabilitiesGetter(JSGlobalObject& lexicalGlobalObject, JSWorkerNavigator& thisObject)
// {
// // auto& vm = JSC::getVM(&lexicalGlobalObject);
// // auto throwScope = DECLARE_THROW_SCOPE(vm);
// // auto& impl = thisObject.wrapped();
// // RELEASE_AND_RETURN(throwScope, (toJS<IDLInterface<MediaCapabilities>>(lexicalGlobalObject, *thisObject.globalObject(), throwScope, WebCore::WorkerNavigatorMediaCapabilities::mediaCapabilities(impl))));
// }
JSC_DEFINE_CUSTOM_GETTER(jsWorkerNavigator_mediaCapabilities, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName))
{
JSC_NOT_IMPLEMENTED_GETTER_BODY;
// return IDLAttribute<JSWorkerNavigator>::get<jsWorkerNavigator_mediaCapabilitiesGetter, CastedThisErrorBehavior::Assert>(*lexicalGlobalObject, thisValue, attributeName);
}
// static inline JSValue jsWorkerNavigator_locksGetter(JSGlobalObject& lexicalGlobalObject, JSWorkerNavigator& thisObject)
// {
// auto& vm = JSC::getVM(&lexicalGlobalObject);
// auto throwScope = DECLARE_THROW_SCOPE(vm);
// auto& impl = thisObject.wrapped();
// RELEASE_AND_RETURN(throwScope, (toJS<IDLInterface<WebLockManager>>(lexicalGlobalObject, *thisObject.globalObject(), throwScope, impl.locks())));
// }
JSC_DEFINE_CUSTOM_GETTER(jsWorkerNavigator_locks, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName))
{
JSC_NOT_IMPLEMENTED_GETTER_BODY;
// return IDLAttribute<JSWorkerNavigator>::get<jsWorkerNavigator_locksGetter, CastedThisErrorBehavior::Assert>(*lexicalGlobalObject, thisValue, attributeName);
}
static inline JSValue jsWorkerNavigator_appCodeNameGetter(JSGlobalObject& lexicalGlobalObject, JSWorkerNavigator& thisObject)
{
auto& vm = JSC::getVM(&lexicalGlobalObject);
auto throwScope = DECLARE_THROW_SCOPE(vm);
auto& impl = thisObject.wrapped();
RELEASE_AND_RETURN(throwScope, (toJS<IDLDOMString>(lexicalGlobalObject, throwScope, impl.appCodeName())));
}
JSC_DEFINE_CUSTOM_GETTER(jsWorkerNavigator_appCodeName, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName))
{
return IDLAttribute<JSWorkerNavigator>::get<jsWorkerNavigator_appCodeNameGetter, CastedThisErrorBehavior::Assert>(*lexicalGlobalObject, thisValue, attributeName);
}
static inline JSValue jsWorkerNavigator_appNameGetter(JSGlobalObject& lexicalGlobalObject, JSWorkerNavigator& thisObject)
{
auto& vm = JSC::getVM(&lexicalGlobalObject);
auto throwScope = DECLARE_THROW_SCOPE(vm);
auto& impl = thisObject.wrapped();
RELEASE_AND_RETURN(throwScope, (toJS<IDLDOMString>(lexicalGlobalObject, throwScope, impl.appName())));
}
JSC_DEFINE_CUSTOM_GETTER(jsWorkerNavigator_appName, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName))
{
return IDLAttribute<JSWorkerNavigator>::get<jsWorkerNavigator_appNameGetter, CastedThisErrorBehavior::Assert>(*lexicalGlobalObject, thisValue, attributeName);
}
static inline JSValue jsWorkerNavigator_appVersionGetter(JSGlobalObject& lexicalGlobalObject, JSWorkerNavigator& thisObject)
{
auto& vm = JSC::getVM(&lexicalGlobalObject);
auto throwScope = DECLARE_THROW_SCOPE(vm);
auto& impl = thisObject.wrapped();
RELEASE_AND_RETURN(throwScope, (toJS<IDLDOMString>(lexicalGlobalObject, throwScope, impl.appVersion())));
}
JSC_DEFINE_CUSTOM_GETTER(jsWorkerNavigator_appVersion, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName))
{
return IDLAttribute<JSWorkerNavigator>::get<jsWorkerNavigator_appVersionGetter, CastedThisErrorBehavior::Assert>(*lexicalGlobalObject, thisValue, attributeName);
}
static inline JSValue jsWorkerNavigator_platformGetter(JSGlobalObject& lexicalGlobalObject, JSWorkerNavigator& thisObject)
{
auto& vm = JSC::getVM(&lexicalGlobalObject);
auto throwScope = DECLARE_THROW_SCOPE(vm);
auto& impl = thisObject.wrapped();
RELEASE_AND_RETURN(throwScope, (toJS<IDLDOMString>(lexicalGlobalObject, throwScope, impl.platform())));
}
JSC_DEFINE_CUSTOM_GETTER(jsWorkerNavigator_platform, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName))
{
return IDLAttribute<JSWorkerNavigator>::get<jsWorkerNavigator_platformGetter, CastedThisErrorBehavior::Assert>(*lexicalGlobalObject, thisValue, attributeName);
}
static inline JSValue jsWorkerNavigator_productGetter(JSGlobalObject& lexicalGlobalObject, JSWorkerNavigator& thisObject)
{
auto& vm = JSC::getVM(&lexicalGlobalObject);
auto throwScope = DECLARE_THROW_SCOPE(vm);
auto& impl = thisObject.wrapped();
RELEASE_AND_RETURN(throwScope, (toJS<IDLDOMString>(lexicalGlobalObject, throwScope, impl.product())));
}
JSC_DEFINE_CUSTOM_GETTER(jsWorkerNavigator_product, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName))
{
return IDLAttribute<JSWorkerNavigator>::get<jsWorkerNavigator_productGetter, CastedThisErrorBehavior::Assert>(*lexicalGlobalObject, thisValue, attributeName);
}
static inline JSValue jsWorkerNavigator_userAgentGetter(JSGlobalObject& lexicalGlobalObject, JSWorkerNavigator& thisObject)
{
auto& vm = JSC::getVM(&lexicalGlobalObject);
auto throwScope = DECLARE_THROW_SCOPE(vm);
auto& impl = thisObject.wrapped();
RELEASE_AND_RETURN(throwScope, (toJS<IDLDOMString>(lexicalGlobalObject, throwScope, impl.userAgent())));
}
JSC_DEFINE_CUSTOM_GETTER(jsWorkerNavigator_userAgent, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName))
{
return IDLAttribute<JSWorkerNavigator>::get<jsWorkerNavigator_userAgentGetter, CastedThisErrorBehavior::Assert>(*lexicalGlobalObject, thisValue, attributeName);
}
static inline JSValue jsWorkerNavigator_languageGetter(JSGlobalObject& lexicalGlobalObject, JSWorkerNavigator& thisObject)
{
auto& vm = JSC::getVM(&lexicalGlobalObject);
auto throwScope = DECLARE_THROW_SCOPE(vm);
auto& impl = thisObject.wrapped();
RELEASE_AND_RETURN(throwScope, (toJS<IDLDOMString>(lexicalGlobalObject, throwScope, impl.language())));
}
JSC_DEFINE_CUSTOM_GETTER(jsWorkerNavigator_language, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName))
{
return IDLAttribute<JSWorkerNavigator>::get<jsWorkerNavigator_languageGetter, CastedThisErrorBehavior::Assert>(*lexicalGlobalObject, thisValue, attributeName);
}
static inline JSValue jsWorkerNavigator_languagesGetter(JSGlobalObject& lexicalGlobalObject, JSWorkerNavigator& thisObject)
{
auto& vm = JSC::getVM(&lexicalGlobalObject);
auto throwScope = DECLARE_THROW_SCOPE(vm);
auto& impl = thisObject.wrapped();
RELEASE_AND_RETURN(throwScope, (toJS<IDLFrozenArray<IDLDOMString>>(lexicalGlobalObject, *thisObject.globalObject(), throwScope, impl.languages())));
}
JSC_DEFINE_CUSTOM_GETTER(jsWorkerNavigator_languages, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName))
{
return IDLAttribute<JSWorkerNavigator>::get<jsWorkerNavigator_languagesGetter, CastedThisErrorBehavior::Assert>(*lexicalGlobalObject, thisValue, attributeName);
}
static inline JSValue jsWorkerNavigator_onLineGetter(JSGlobalObject& lexicalGlobalObject, JSWorkerNavigator& thisObject)
{
auto& vm = JSC::getVM(&lexicalGlobalObject);
auto throwScope = DECLARE_THROW_SCOPE(vm);
auto& impl = thisObject.wrapped();
RELEASE_AND_RETURN(throwScope, (toJS<IDLBoolean>(lexicalGlobalObject, throwScope, impl.onLine())));
}
JSC_DEFINE_CUSTOM_GETTER(jsWorkerNavigator_onLine, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName))
{
return IDLAttribute<JSWorkerNavigator>::get<jsWorkerNavigator_onLineGetter, CastedThisErrorBehavior::Assert>(*lexicalGlobalObject, thisValue, attributeName);
}
#if ENABLE(SERVICE_WORKER)
static inline JSValue jsWorkerNavigator_serviceWorkerGetter(JSGlobalObject& lexicalGlobalObject, JSWorkerNavigator& thisObject)
{
auto& vm = JSC::getVM(&lexicalGlobalObject);
auto throwScope = DECLARE_THROW_SCOPE(vm);
auto* context = jsCast<JSDOMGlobalObject*>(&lexicalGlobalObject)->scriptExecutionContext();
if (UNLIKELY(!context))
return jsUndefined();
auto& impl = thisObject.wrapped();
RELEASE_AND_RETURN(throwScope, (toJS<IDLInterface<ServiceWorkerContainer>>(lexicalGlobalObject, *thisObject.globalObject(), throwScope, impl.serviceWorker(*context))));
}
JSC_DEFINE_CUSTOM_GETTER(jsWorkerNavigator_serviceWorker, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName))
{
return IDLAttribute<JSWorkerNavigator>::get<jsWorkerNavigator_serviceWorkerGetter, CastedThisErrorBehavior::Assert>(*lexicalGlobalObject, thisValue, attributeName);
}
#endif
// static inline JSValue jsWorkerNavigator_storageGetter(JSGlobalObject& lexicalGlobalObject, JSWorkerNavigator& thisObject)
// {
// auto& vm = JSC::getVM(&lexicalGlobalObject);
// auto throwScope = DECLARE_THROW_SCOPE(vm);
// auto& impl = thisObject.wrapped();
// RELEASE_AND_RETURN(throwScope, (toJS<IDLInterface<StorageManager>>(lexicalGlobalObject, *thisObject.globalObject(), throwScope, impl.storage())));
// }
JSC_DEFINE_CUSTOM_GETTER(jsWorkerNavigator_storage, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName))
{
JSC_NOT_IMPLEMENTED_GETTER_BODY;
// return IDLAttribute<JSWorkerNavigator>::get<jsWorkerNavigator_storageGetter, CastedThisErrorBehavior::Assert>(*lexicalGlobalObject, thisValue, attributeName);
}
JSC::GCClient::IsoSubspace* JSWorkerNavigator::subspaceForImpl(JSC::VM& vm)
{
return WebCore::subspaceForImpl<JSWorkerNavigator, UseCustomHeapCellType::No>(
vm,
[](auto& spaces) { return spaces.m_clientSubspaceForWorkerNavigator.get(); },
[](auto& spaces, auto&& space) { spaces.m_clientSubspaceForWorkerNavigator = WTFMove(space); },
[](auto& spaces) { return spaces.m_subspaceForWorkerNavigator.get(); },
[](auto& spaces, auto&& space) { spaces.m_subspaceForWorkerNavigator = WTFMove(space); });
}
template<typename Visitor>
void JSWorkerNavigator::visitChildrenImpl(JSCell* cell, Visitor& visitor)
{
auto* thisObject = jsCast<JSWorkerNavigator*>(cell);
ASSERT_GC_OBJECT_INHERITS(thisObject, info());
Base::visitChildren(thisObject, visitor);
thisObject->visitAdditionalChildren(visitor);
}
DEFINE_VISIT_CHILDREN(JSWorkerNavigator);
template<typename Visitor>
void JSWorkerNavigator::visitOutputConstraints(JSCell* cell, Visitor& visitor)
{
auto* thisObject = jsCast<JSWorkerNavigator*>(cell);
ASSERT_GC_OBJECT_INHERITS(thisObject, info());
Base::visitOutputConstraints(thisObject, visitor);
thisObject->visitAdditionalChildren(visitor);
}
template void JSWorkerNavigator::visitOutputConstraints(JSCell*, AbstractSlotVisitor&);
template void JSWorkerNavigator::visitOutputConstraints(JSCell*, SlotVisitor&);
void JSWorkerNavigator::analyzeHeap(JSCell* cell, HeapAnalyzer& analyzer)
{
auto* thisObject = jsCast<JSWorkerNavigator*>(cell);
analyzer.setWrappedObjectForCell(cell, &thisObject->wrapped());
if (thisObject->scriptExecutionContext())
analyzer.setLabelForCell(cell, "url " + thisObject->scriptExecutionContext()->url().string());
Base::analyzeHeap(cell, analyzer);
}
bool JSWorkerNavigatorOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, AbstractSlotVisitor& visitor, const char** reason)
{
auto* jsWorkerNavigator = jsCast<JSWorkerNavigator*>(handle.slot()->asCell());
WorkerNavigator* root = &jsWorkerNavigator->wrapped();
if (UNLIKELY(reason))
*reason = "Reachable from WorkerNavigator";
return visitor.containsOpaqueRoot(root);
}
void JSWorkerNavigatorOwner::finalize(JSC::Handle<JSC::Unknown> handle, void* context)
{
auto* jsWorkerNavigator = static_cast<JSWorkerNavigator*>(handle.slot()->asCell());
auto& world = *static_cast<DOMWrapperWorld*>(context);
uncacheWrapper(world, &jsWorkerNavigator->wrapped(), jsWorkerNavigator);
}
#if ENABLE(BINDING_INTEGRITY)
#if PLATFORM(WIN)
#pragma warning(disable : 4483)
extern "C" {
extern void (*const __identifier("??_7WorkerNavigator@WebCore@@6B@")[])();
}
#else
extern "C" {
extern void* _ZTVN7WebCore15WorkerNavigatorE[];
}
#endif
#endif
JSC::JSValue toJSNewlyCreated(JSC::JSGlobalObject*, JSDOMGlobalObject* globalObject, Ref<WorkerNavigator>&& impl)
{
if constexpr (std::is_polymorphic_v<WorkerNavigator>) {
#if ENABLE(BINDING_INTEGRITY)
const void* actualVTablePointer = getVTablePointer(impl.ptr());
#if PLATFORM(WIN)
void* expectedVTablePointer = __identifier("??_7WorkerNavigator@WebCore@@6B@");
#else
void* expectedVTablePointer = &_ZTVN7WebCore15WorkerNavigatorE[2];
#endif
// If you hit this assertion you either have a use after free bug, or
// WorkerNavigator has subclasses. If WorkerNavigator has subclasses that get passed
// to toJS() we currently require WorkerNavigator you to opt out of binding hardening
// by adding the SkipVTableValidation attribute to the interface IDL definition
RELEASE_ASSERT(actualVTablePointer == expectedVTablePointer);
#endif
}
return createWrapper<WorkerNavigator>(globalObject, WTFMove(impl));
}
JSC::JSValue toJS(JSC::JSGlobalObject* lexicalGlobalObject, JSDOMGlobalObject* globalObject, WorkerNavigator& impl)
{
return wrap(lexicalGlobalObject, globalObject, impl);
}
WorkerNavigator* JSWorkerNavigator::toWrapped(JSC::VM& vm, JSC::JSValue value)
{
if (auto* wrapper = jsDynamicCast<JSWorkerNavigator*>(vm, value))
return &wrapper->wrapped();
return nullptr;
}
}

View File

@@ -0,0 +1 @@
JSWorkerNavigator.h :

View File

@@ -0,0 +1,97 @@
/*
This file is part of the WebKit open source project.
This file has been generated by generate-bindings.pl. DO NOT MODIFY!
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#pragma once
#include "JSDOMWrapper.h"
#include "WorkerNavigator.h"
#include <wtf/NeverDestroyed.h>
namespace WebCore {
class JSWorkerNavigator : public JSDOMWrapper<WorkerNavigator> {
public:
using Base = JSDOMWrapper<WorkerNavigator>;
static JSWorkerNavigator* create(JSC::Structure* structure, JSDOMGlobalObject* globalObject, Ref<WorkerNavigator>&& impl)
{
JSWorkerNavigator* ptr = new (NotNull, JSC::allocateCell<JSWorkerNavigator>(globalObject->vm())) JSWorkerNavigator(structure, *globalObject, WTFMove(impl));
ptr->finishCreation(globalObject->vm());
return ptr;
}
static JSC::JSObject* createPrototype(JSC::VM&, JSDOMGlobalObject&);
static JSC::JSObject* prototype(JSC::VM&, JSDOMGlobalObject&);
static WorkerNavigator* toWrapped(JSC::VM&, JSC::JSValue);
static void destroy(JSC::JSCell*);
DECLARE_INFO;
static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
{
return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info(), JSC::NonArray);
}
static JSC::JSValue getConstructor(JSC::VM&, const JSC::JSGlobalObject*);
template<typename, JSC::SubspaceAccess mode> static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
{
if constexpr (mode == JSC::SubspaceAccess::Concurrently)
return nullptr;
return subspaceForImpl(vm);
}
static JSC::GCClient::IsoSubspace* subspaceForImpl(JSC::VM& vm);
DECLARE_VISIT_CHILDREN;
template<typename Visitor> void visitAdditionalChildren(Visitor&);
template<typename Visitor> static void visitOutputConstraints(JSCell*, Visitor&);
static void analyzeHeap(JSCell*, JSC::HeapAnalyzer&);
protected:
JSWorkerNavigator(JSC::Structure*, JSDOMGlobalObject&, Ref<WorkerNavigator>&&);
void finishCreation(JSC::VM&);
};
class JSWorkerNavigatorOwner final : public JSC::WeakHandleOwner {
public:
bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::AbstractSlotVisitor&, const char**) final;
void finalize(JSC::Handle<JSC::Unknown>, void* context) final;
};
inline JSC::WeakHandleOwner* wrapperOwner(DOMWrapperWorld&, WorkerNavigator*)
{
static NeverDestroyed<JSWorkerNavigatorOwner> owner;
return &owner.get();
}
inline void* wrapperKey(WorkerNavigator* wrappableObject)
{
return wrappableObject;
}
JSC::JSValue toJS(JSC::JSGlobalObject*, JSDOMGlobalObject*, WorkerNavigator&);
inline JSC::JSValue toJS(JSC::JSGlobalObject* lexicalGlobalObject, JSDOMGlobalObject* globalObject, WorkerNavigator* impl) { return impl ? toJS(lexicalGlobalObject, globalObject, *impl) : JSC::jsNull(); }
JSC::JSValue toJSNewlyCreated(JSC::JSGlobalObject*, JSDOMGlobalObject*, Ref<WorkerNavigator>&&);
inline JSC::JSValue toJSNewlyCreated(JSC::JSGlobalObject* lexicalGlobalObject, JSDOMGlobalObject* globalObject, RefPtr<WorkerNavigator>&& impl) { return impl ? toJSNewlyCreated(lexicalGlobalObject, globalObject, impl.releaseNonNull()) : JSC::jsNull(); }
template<> struct JSDOMWrapperConverterTraits<WorkerNavigator> {
using WrapperClass = JSWorkerNavigator;
using ToWrappedReturnType = WorkerNavigator*;
};
} // namespace WebCore

View File

@@ -0,0 +1,84 @@
/*
This file is part of the WebKit open source project.
This file has been generated by generate-bindings.pl. DO NOT MODIFY!
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include "config.h"
#include "JSWorkerOptions.h"
#include "JSDOMConvertEnumeration.h"
#include "JSDOMConvertStrings.h"
#include "JSFetchRequestCredentials.h"
#include "JSWorkerType.h"
#include <JavaScriptCore/JSCInlines.h>
namespace WebCore {
using namespace JSC;
template<> WorkerOptions convertDictionary<WorkerOptions>(JSGlobalObject& lexicalGlobalObject, JSValue value)
{
VM& vm = JSC::getVM(&lexicalGlobalObject);
auto throwScope = DECLARE_THROW_SCOPE(vm);
bool isNullOrUndefined = value.isUndefinedOrNull();
auto* object = isNullOrUndefined ? nullptr : value.getObject();
if (UNLIKELY(!isNullOrUndefined && !object)) {
throwTypeError(&lexicalGlobalObject, throwScope);
return { };
}
WorkerOptions result;
JSValue credentialsValue;
if (isNullOrUndefined)
credentialsValue = jsUndefined();
else {
credentialsValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "credentials"));
RETURN_IF_EXCEPTION(throwScope, { });
}
if (!credentialsValue.isUndefined()) {
result.credentials = convert<IDLEnumeration<FetchRequestCredentials>>(lexicalGlobalObject, credentialsValue);
RETURN_IF_EXCEPTION(throwScope, { });
} else
result.credentials = FetchRequestCredentials::SameOrigin;
JSValue nameValue;
if (isNullOrUndefined)
nameValue = jsUndefined();
else {
nameValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "name"));
RETURN_IF_EXCEPTION(throwScope, { });
}
if (!nameValue.isUndefined()) {
result.name = convert<IDLDOMString>(lexicalGlobalObject, nameValue);
RETURN_IF_EXCEPTION(throwScope, { });
} else
result.name = emptyString();
JSValue typeValue;
if (isNullOrUndefined)
typeValue = jsUndefined();
else {
typeValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "type"));
RETURN_IF_EXCEPTION(throwScope, { });
}
if (!typeValue.isUndefined()) {
result.type = convert<IDLEnumeration<WorkerType>>(lexicalGlobalObject, typeValue);
RETURN_IF_EXCEPTION(throwScope, { });
} else
result.type = WorkerType::Classic;
return result;
}
} // namespace WebCore

View File

@@ -0,0 +1 @@
WorkerOptions.h :

View File

@@ -0,0 +1,30 @@
/*
This file is part of the WebKit open source project.
This file has been generated by generate-bindings.pl. DO NOT MODIFY!
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#pragma once
#include "JSDOMConvertDictionary.h"
#include "WorkerOptions.h"
namespace WebCore {
template<> WorkerOptions convertDictionary<WorkerOptions>(JSC::JSGlobalObject&, JSC::JSValue);
} // namespace WebCore

View File

@@ -0,0 +1,64 @@
/*
This file is part of the WebKit open source project.
This file has been generated by generate-bindings.pl. DO NOT MODIFY!
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include "config.h"
#include "JSWorkerType.h"
#include <JavaScriptCore/JSCInlines.h>
#include <JavaScriptCore/JSString.h>
#include <wtf/NeverDestroyed.h>
namespace WebCore {
using namespace JSC;
String convertEnumerationToString(WorkerType enumerationValue)
{
static const NeverDestroyed<String> values[] = {
MAKE_STATIC_STRING_IMPL("classic"),
MAKE_STATIC_STRING_IMPL("module"),
};
static_assert(static_cast<size_t>(WorkerType::Classic) == 0, "WorkerType::Classic is not 0 as expected");
static_assert(static_cast<size_t>(WorkerType::Module) == 1, "WorkerType::Module is not 1 as expected");
ASSERT(static_cast<size_t>(enumerationValue) < WTF_ARRAY_LENGTH(values));
return values[static_cast<size_t>(enumerationValue)];
}
template<> JSString* convertEnumerationToJS(JSGlobalObject& lexicalGlobalObject, WorkerType enumerationValue)
{
return jsStringWithCache(lexicalGlobalObject.vm(), convertEnumerationToString(enumerationValue));
}
template<> std::optional<WorkerType> parseEnumeration<WorkerType>(JSGlobalObject& lexicalGlobalObject, JSValue value)
{
auto stringValue = value.toWTFString(&lexicalGlobalObject);
if (stringValue == "classic")
return WorkerType::Classic;
if (stringValue == "module")
return WorkerType::Module;
return std::nullopt;
}
template<> const char* expectedEnumerationValues<WorkerType>()
{
return "\"classic\", \"module\"";
}
} // namespace WebCore

View File

@@ -0,0 +1,34 @@
/*
This file is part of the WebKit open source project.
This file has been generated by generate-bindings.pl. DO NOT MODIFY!
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#pragma once
#include "JSDOMConvertEnumeration.h"
#include "WorkerType.h"
namespace WebCore {
String convertEnumerationToString(WorkerType);
template<> JSC::JSString* convertEnumerationToJS(JSC::JSGlobalObject&, WorkerType);
template<> std::optional<WorkerType> parseEnumeration<WorkerType>(JSC::JSGlobalObject&, JSC::JSValue);
template<> const char* expectedEnumerationValues<WorkerType>();
} // namespace WebCore

View File

@@ -0,0 +1,64 @@
/*
* Copyright (C) 2008 Apple Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include "config.h"
#include "MessageChannel.h"
#include "MessagePort.h"
#include "MessagePortChannelProvider.h"
#include "ScriptExecutionContext.h"
namespace WebCore {
static std::pair<Ref<MessagePort>, Ref<MessagePort>> generateMessagePorts(ScriptExecutionContext& context)
{
MessagePortIdentifier id1 = { Process::identifier(), ObjectIdentifier<MessagePortIdentifier::PortIdentifierType>::generate() };
MessagePortIdentifier id2 = { Process::identifier(), ObjectIdentifier<MessagePortIdentifier::PortIdentifierType>::generate() };
return { MessagePort::create(context, id1, id2), MessagePort::create(context, id2, id1) };
}
Ref<MessageChannel> MessageChannel::create(ScriptExecutionContext& context)
{
return adoptRef(*new MessageChannel(context));
}
MessageChannel::MessageChannel(ScriptExecutionContext& context)
: m_ports(generateMessagePorts(context))
{
if (!context.activeDOMObjectsAreStopped()) {
ASSERT(!port1().closed());
ASSERT(!port2().closed());
MessagePortChannelProvider::fromContext(context).createNewMessagePortChannel(port1().identifier(), port2().identifier());
} else {
ASSERT(port1().closed());
ASSERT(port2().closed());
}
}
MessageChannel::~MessageChannel() = default;
} // namespace WebCore

View File

@@ -0,0 +1,51 @@
/*
* Copyright (C) 2008 Apple Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#pragma once
#include <wtf/RefCounted.h>
#include <wtf/RefPtr.h>
namespace WebCore {
class MessagePort;
class ScriptExecutionContext;
class MessageChannel : public RefCounted<MessageChannel> {
public:
static Ref<MessageChannel> create(ScriptExecutionContext&);
~MessageChannel();
MessagePort& port1() const { return m_ports.first; }
MessagePort& port2() const { return m_ports.second; }
private:
explicit MessageChannel(ScriptExecutionContext&);
std::pair<Ref<MessagePort>, Ref<MessagePort>> m_ports;
};
} // namespace WebCore

View File

@@ -0,0 +1,38 @@
/*
* Copyright (C) 2008, 2010 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
[
Exposed=(Window,Worker),
Conditional=CHANNEL_MESSAGING,
JSCustomMarkFunction,
] interface MessageChannel {
[CallWith=CurrentScriptExecutionContext] constructor();
readonly attribute MessagePort port1;
readonly attribute MessagePort port2;
};

View File

@@ -0,0 +1,130 @@
/*
* Copyright (C) 2007 Henry Mason (hmason@mac.com)
* Copyright (C) 2003-2018 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include "config.h"
#include "MessageEvent.h"
#include "Blob.h"
#include "EventNames.h"
#include <JavaScriptCore/JSCInlines.h>
#include <wtf/IsoMallocInlines.h>
namespace WebCore {
using namespace JSC;
WTF_MAKE_ISO_ALLOCATED_IMPL(MessageEvent);
MessageEvent::MessageEvent() = default;
inline MessageEvent::MessageEvent(const AtomString& type, Init&& initializer, IsTrusted isTrusted)
: Event(type, initializer, isTrusted)
, m_data(JSValueTag { })
, m_origin(initializer.origin)
, m_lastEventId(initializer.lastEventId)
, m_source(WTFMove(initializer.source))
, m_ports(WTFMove(initializer.ports))
, m_jsData(initializer.data)
{
}
inline MessageEvent::MessageEvent(const AtomString& type, DataType&& data, const String& origin, const String& lastEventId, std::optional<MessageEventSource>&& source, Vector<RefPtr<MessagePort>>&& ports)
: Event(type, CanBubble::No, IsCancelable::No)
, m_data(WTFMove(data))
, m_origin(origin)
, m_lastEventId(lastEventId)
, m_source(WTFMove(source))
, m_ports(WTFMove(ports))
{
}
Ref<MessageEvent> MessageEvent::create(const AtomString& type, DataType&& data, const String& origin, const String& lastEventId, std::optional<MessageEventSource>&& source, Vector<RefPtr<MessagePort>>&& ports)
{
return adoptRef(*new MessageEvent(type, WTFMove(data), origin, lastEventId, WTFMove(source), WTFMove(ports)));
}
Ref<MessageEvent> MessageEvent::create(DataType&& data, const String& origin, const String& lastEventId, std::optional<MessageEventSource>&& source, Vector<RefPtr<MessagePort>>&& ports)
{
return create(eventNames().messageEvent, WTFMove(data), origin, lastEventId, WTFMove(source), WTFMove(ports));
}
Ref<MessageEvent> MessageEvent::createForBindings()
{
return adoptRef(*new MessageEvent);
}
Ref<MessageEvent> MessageEvent::create(const AtomString& type, Init&& initializer, IsTrusted isTrusted)
{
return adoptRef(*new MessageEvent(type, WTFMove(initializer), isTrusted));
}
MessageEvent::~MessageEvent() = default;
void MessageEvent::initMessageEvent(const AtomString& type, bool canBubble, bool cancelable, JSValue data, const String& origin, const String& lastEventId, std::optional<MessageEventSource>&& source, Vector<RefPtr<MessagePort>>&& ports)
{
if (isBeingDispatched())
return;
initEvent(type, canBubble, cancelable);
{
Locker { m_concurrentDataAccessLock };
m_data = JSValueTag { };
}
// FIXME: This code is wrong: we should emit a write-barrier. Otherwise, GC can collect it.
// https://bugs.webkit.org/show_bug.cgi?id=236353
m_jsData.setWeakly(data);
m_cachedData.clear();
m_origin = origin;
m_lastEventId = lastEventId;
m_source = WTFMove(source);
m_ports = WTFMove(ports);
m_cachedPorts.clear();
}
EventInterface MessageEvent::eventInterface() const
{
return MessageEventInterfaceType;
}
size_t MessageEvent::memoryCost() const
{
Locker { m_concurrentDataAccessLock };
return WTF::switchOn(m_data, [] (JSValueTag) -> size_t {
return 0;
}, [] (const Ref<SerializedScriptValue>& data) -> size_t {
return data->memoryCost();
}, [] (const String& string) -> size_t {
return string.sizeInBytes();
}, [] (const Ref<Blob>& blob) -> size_t {
return blob->size();
}, [] (const Ref<ArrayBuffer>& buffer) -> size_t {
return buffer->byteLength();
});
}
} // namespace WebCore

View File

@@ -0,0 +1,106 @@
/*
* Copyright (C) 2007 Henry Mason (hmason@mac.com)
* Copyright (C) 2003-2018 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#pragma once
#include "Event.h"
#include "JSValueInWrappedObject.h"
#include "MessagePort.h"
#include "SerializedScriptValue.h"
#include "ServiceWorker.h"
#include "WindowProxy.h"
#include <variant>
namespace WebCore {
// class Blob;
// #if ENABLE(SERVICE_WORKER)
// using MessageEventSource = std::variant<RefPtr<WindowProxy>, RefPtr<MessagePort>, RefPtr<ServiceWorker>>;
// #else
// using MessageEventSource = std::variant<RefPtr<WindowProxy>, RefPtr<MessagePort>>;
// #endif
using MessageEventSource = std::variant<RefPtr<MessagePort>>;
class MessageEvent final : public Event {
WTF_MAKE_ISO_ALLOCATED(MessageEvent);
public:
struct JSValueTag {
};
using DataType = std::variant<JSValueTag, Ref<SerializedScriptValue>, String, /*Ref<Blob>,*/ Ref<ArrayBuffer>>;
static Ref<MessageEvent> create(const AtomString& type, DataType&&, const String& origin = {}, const String& lastEventId = {}, std::optional<MessageEventSource>&& = std::nullopt, Vector<RefPtr<MessagePort>>&& = {});
static Ref<MessageEvent> create(DataType&&, const String& origin = {}, const String& lastEventId = {}, std::optional<MessageEventSource>&& = std::nullopt, Vector<RefPtr<MessagePort>>&& = {});
static Ref<MessageEvent> createForBindings();
struct Init : EventInit {
JSC::JSValue data;
String origin;
String lastEventId;
std::optional<MessageEventSource> source;
Vector<RefPtr<MessagePort>> ports;
};
static Ref<MessageEvent> create(const AtomString& type, Init&&, IsTrusted = IsTrusted::No);
virtual ~MessageEvent();
void initMessageEvent(const AtomString& type, bool canBubble, bool cancelable, JSC::JSValue data, const String& origin, const String& lastEventId, std::optional<MessageEventSource>&&, Vector<RefPtr<MessagePort>>&&);
const String& origin() const { return m_origin; }
const String& lastEventId() const { return m_lastEventId; }
const std::optional<MessageEventSource>& source() const { return m_source; }
const Vector<RefPtr<MessagePort>>& ports() const { return m_ports; }
const DataType& data() const { return m_data; }
JSValueInWrappedObject& jsData() { return m_jsData; }
JSValueInWrappedObject& cachedData() { return m_cachedData; }
JSValueInWrappedObject& cachedPorts() { return m_cachedPorts; }
size_t memoryCost() const;
private:
MessageEvent();
MessageEvent(const AtomString& type, Init&&, IsTrusted);
MessageEvent(const AtomString& type, DataType&&, const String& origin, const String& lastEventId = {}, std::optional<MessageEventSource>&& = std::nullopt, Vector<RefPtr<MessagePort>>&& = {});
EventInterface eventInterface() const final;
DataType m_data;
String m_origin;
String m_lastEventId;
std::optional<MessageEventSource> m_source;
Vector<RefPtr<MessagePort>> m_ports;
JSValueInWrappedObject m_jsData;
JSValueInWrappedObject m_cachedData;
JSValueInWrappedObject m_cachedPorts;
mutable Lock m_concurrentDataAccessLock;
};
} // namespace WebCore

View File

@@ -0,0 +1,59 @@
/*
* Copyright (C) 2007 Henry Mason <hmason@mac.com>
* Copyright (C) 2011 Google Inc. All rights reserved.
* Copyright (C) 2016 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#if defined(ENABLE_SERVICE_WORKER) && ENABLE_SERVICE_WORKER
typedef (WindowProxy or MessagePort or ServiceWorker) MessageEventSource;
#else
typedef (WindowProxy or MessagePort) MessageEventSource;
#endif
[
Exposed=(Window,Worker,AudioWorklet),
JSCustomMarkFunction,
ReportExtraMemoryCost,
] interface MessageEvent : Event {
constructor(DOMString type, optional MessageEventInit eventInitDict);
readonly attribute USVString origin;
readonly attribute DOMString lastEventId;
readonly attribute MessageEventSource? source;
[CustomGetter] readonly attribute any data;
[CustomGetter] readonly attribute FrozenArray<MessagePort> ports;
undefined initMessageEvent(DOMString type, optional boolean bubbles = false, optional boolean cancelable = false,
optional any data = null, optional USVString originArg = "", optional DOMString lastEventId = "", optional MessageEventSource? source = null,
optional sequence<MessagePort> messagePorts = []);
};
dictionary MessageEventInit : EventInit {
any data = null;
USVString origin = "";
DOMString lastEventId = "";
MessageEventSource? source = null;
sequence<MessagePort> ports = [];
};

View File

@@ -0,0 +1,440 @@
/*
* Copyright (C) 2008 Apple Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include "config.h"
#include "MessagePort.h"
#include "Document.h"
#include "EventNames.h"
#include "Logging.h"
#include "MessageEvent.h"
#include "MessagePortChannelProvider.h"
#include "MessageWithMessagePorts.h"
#include "StructuredSerializeOptions.h"
#include "WorkerGlobalScope.h"
#include "WorkerThread.h"
#include <wtf/CompletionHandler.h>
#include <wtf/IsoMallocInlines.h>
#include <wtf/Lock.h>
#include <wtf/Scope.h>
namespace WebCore {
WTF_MAKE_ISO_ALLOCATED_IMPL(MessagePort);
static Lock allMessagePortsLock;
static HashMap<MessagePortIdentifier, MessagePort*>& allMessagePorts() WTF_REQUIRES_LOCK(allMessagePortsLock)
{
static NeverDestroyed<HashMap<MessagePortIdentifier, MessagePort*>> map;
return map;
}
void MessagePort::ref() const
{
++m_refCount;
}
void MessagePort::deref() const
{
// This custom deref() function ensures that as long as the lock to allMessagePortsLock is taken, no MessagePort will be destroyed.
// This allows isExistingMessagePortLocallyReachable and notifyMessageAvailable to easily query the map and manipulate MessagePort instances.
if (!--m_refCount) {
Locker locker { allMessagePortsLock };
if (m_refCount)
return;
auto iterator = allMessagePorts().find(m_identifier);
if (iterator != allMessagePorts().end() && iterator->value == this)
allMessagePorts().remove(iterator);
delete this;
}
}
bool MessagePort::isExistingMessagePortLocallyReachable(const MessagePortIdentifier& identifier)
{
Locker locker { allMessagePortsLock };
auto* port = allMessagePorts().get(identifier);
return port && port->isLocallyReachable();
}
void MessagePort::notifyMessageAvailable(const MessagePortIdentifier& identifier)
{
Locker locker { allMessagePortsLock };
if (auto* port = allMessagePorts().get(identifier))
port->messageAvailable();
}
Ref<MessagePort> MessagePort::create(ScriptExecutionContext& scriptExecutionContext, const MessagePortIdentifier& local, const MessagePortIdentifier& remote)
{
auto messagePort = adoptRef(*new MessagePort(scriptExecutionContext, local, remote));
messagePort->suspendIfNeeded();
return messagePort;
}
MessagePort::MessagePort(ScriptExecutionContext& scriptExecutionContext, const MessagePortIdentifier& local, const MessagePortIdentifier& remote)
: ActiveDOMObject(&scriptExecutionContext)
, m_identifier(local)
, m_remoteIdentifier(remote)
{
LOG(MessagePorts, "Created MessagePort %s (%p) in process %" PRIu64, m_identifier.logString().utf8().data(), this, Process::identifier().toUInt64());
Locker locker { allMessagePortsLock };
allMessagePorts().set(m_identifier, this);
// Make sure the WeakPtrFactory gets initialized eagerly on the thread the MessagePort gets constructed on for thread-safety reasons.
initializeWeakPtrFactory();
scriptExecutionContext.createdMessagePort(*this);
// Don't need to call processMessageWithMessagePortsSoon() here, because the port will not be opened until start() is invoked.
}
MessagePort::~MessagePort()
{
LOG(MessagePorts, "Destroyed MessagePort %s (%p) in process %" PRIu64, m_identifier.logString().utf8().data(), this, Process::identifier().toUInt64());
ASSERT(allMessagePortsLock.isLocked());
if (m_entangled)
close();
if (auto* context = scriptExecutionContext())
context->destroyedMessagePort(*this);
}
void MessagePort::entangle()
{
MessagePortChannelProvider::fromContext(*scriptExecutionContext()).entangleLocalPortInThisProcessToRemote(m_identifier, m_remoteIdentifier);
}
ExceptionOr<void> MessagePort::postMessage(JSC::JSGlobalObject& state, JSC::JSValue messageValue, StructuredSerializeOptions&& options)
{
LOG(MessagePorts, "Attempting to post message to port %s (to be received by port %s)", m_identifier.logString().utf8().data(), m_remoteIdentifier.logString().utf8().data());
registerLocalActivity();
Vector<RefPtr<MessagePort>> ports;
auto messageData = SerializedScriptValue::create(state, messageValue, WTFMove(options.transfer), ports);
if (messageData.hasException())
return messageData.releaseException();
if (!isEntangled())
return { };
ASSERT(scriptExecutionContext());
Vector<TransferredMessagePort> transferredPorts;
// Make sure we aren't connected to any of the passed-in ports.
if (!ports.isEmpty()) {
for (auto& port : ports) {
if (port->identifier() == m_identifier || port->identifier() == m_remoteIdentifier)
return Exception { DataCloneError };
}
auto disentangleResult = MessagePort::disentanglePorts(WTFMove(ports));
if (disentangleResult.hasException())
return disentangleResult.releaseException();
transferredPorts = disentangleResult.releaseReturnValue();
}
MessageWithMessagePorts message { messageData.releaseReturnValue(), WTFMove(transferredPorts) };
LOG(MessagePorts, "Actually posting message to port %s (to be received by port %s)", m_identifier.logString().utf8().data(), m_remoteIdentifier.logString().utf8().data());
MessagePortChannelProvider::fromContext(*scriptExecutionContext()).postMessageToRemote(WTFMove(message), m_remoteIdentifier);
return { };
}
TransferredMessagePort MessagePort::disentangle()
{
ASSERT(m_entangled);
m_entangled = false;
registerLocalActivity();
auto& context = *scriptExecutionContext();
MessagePortChannelProvider::fromContext(context).messagePortDisentangled(m_identifier);
// We can't receive any messages or generate any events after this, so remove ourselves from the list of active ports.
context.destroyedMessagePort(*this);
context.willDestroyActiveDOMObject(*this);
context.willDestroyDestructionObserver(*this);
observeContext(nullptr);
return { identifier(), remoteIdentifier() };
}
void MessagePort::registerLocalActivity()
{
// Any time certain local operations happen, we dirty our own state to delay GC.
m_hasHadLocalActivitySinceLastCheck = true;
m_mightBeEligibleForGC = false;
}
// Invoked to notify us that there are messages available for this port.
// This code may be called from another thread, and so should not call any non-threadsafe APIs (i.e. should not call into the entangled channel or access mutable variables).
void MessagePort::messageAvailable()
{
// This MessagePort object might be disentangled because the port is being transferred,
// in which case we'll notify it that messages are available once a new end point is created.
auto* context = scriptExecutionContext();
if (!context || context->activeDOMObjectsAreSuspended())
return;
context->processMessageWithMessagePortsSoon();
}
void MessagePort::start()
{
// Do nothing if we've been cloned or closed.
if (!isEntangled())
return;
registerLocalActivity();
ASSERT(scriptExecutionContext());
if (m_started)
return;
m_started = true;
scriptExecutionContext()->processMessageWithMessagePortsSoon();
}
void MessagePort::close()
{
m_mightBeEligibleForGC = true;
if (m_closed)
return;
m_closed = true;
ensureOnMainThread([identifier = m_identifier] {
MessagePortChannelProvider::singleton().messagePortClosed(identifier);
});
removeAllEventListeners();
}
void MessagePort::contextDestroyed()
{
ASSERT(scriptExecutionContext());
close();
ActiveDOMObject::contextDestroyed();
}
void MessagePort::dispatchMessages()
{
// Messages for contexts that are not fully active get dispatched too, but JSAbstractEventListener::handleEvent() doesn't call handlers for these.
// The HTML5 spec specifies that any messages sent to a document that is not fully active should be dropped, so this behavior is OK.
ASSERT(started());
auto* context = scriptExecutionContext();
if (!context || context->activeDOMObjectsAreSuspended() || !isEntangled())
return;
auto messagesTakenHandler = [this, weakThis = WeakPtr { *this }](Vector<MessageWithMessagePorts>&& messages, CompletionHandler<void()>&& completionCallback) mutable {
auto scopeExit = makeScopeExit(WTFMove(completionCallback));
if (!weakThis)
return;
LOG(MessagePorts, "MessagePort %s (%p) dispatching %zu messages", m_identifier.logString().utf8().data(), this, messages.size());
auto* context = scriptExecutionContext();
if (!context)
return;
if (!messages.isEmpty())
registerLocalActivity();
ASSERT(context->isContextThread());
bool contextIsWorker = is<WorkerGlobalScope>(*context);
for (auto& message : messages) {
// close() in Worker onmessage handler should prevent next message from dispatching.
if (contextIsWorker && downcast<WorkerGlobalScope>(*context).isClosing())
return;
auto ports = MessagePort::entanglePorts(*context, WTFMove(message.transferredPorts));
// Per specification, each MessagePort object has a task source called the port message queue.
queueTaskToDispatchEvent(*this, TaskSource::PostedMessageQueue, MessageEvent::create(message.message.releaseNonNull(), { }, { }, { }, WTFMove(ports)));
}
};
MessagePortChannelProvider::fromContext(*scriptExecutionContext()).takeAllMessagesForPort(m_identifier, WTFMove(messagesTakenHandler));
}
void MessagePort::dispatchEvent(Event& event)
{
if (m_closed)
return;
auto* context = scriptExecutionContext();
if (is<WorkerGlobalScope>(*context) && downcast<WorkerGlobalScope>(*context).isClosing())
return;
EventTarget::dispatchEvent(event);
}
void MessagePort::updateActivity(MessagePortChannelProvider::HasActivity hasActivity)
{
bool hasHadLocalActivity = m_hasHadLocalActivitySinceLastCheck;
m_hasHadLocalActivitySinceLastCheck = false;
if (hasActivity == MessagePortChannelProvider::HasActivity::No && !hasHadLocalActivity)
m_isRemoteEligibleForGC = true;
if (hasActivity == MessagePortChannelProvider::HasActivity::Yes)
m_isRemoteEligibleForGC = false;
m_isAskingRemoteAboutGC = false;
}
bool MessagePort::virtualHasPendingActivity() const
{
m_mightBeEligibleForGC = true;
// If the ScriptExecutionContext has been shut down on this object close()'ed, we can GC.
auto* context = scriptExecutionContext();
if (!context || m_closed)
return false;
// If this object has been idle since the remote port declared itself elgibile for GC, we can GC.
if (!m_hasHadLocalActivitySinceLastCheck && m_isRemoteEligibleForGC)
return false;
// If this MessagePort has no message event handler then the existence of remote activity cannot keep it alive.
if (!m_hasMessageEventListener)
return false;
// If we're not in the middle of asking the remote port about collectability, do so now.
if (!m_isAskingRemoteAboutGC) {
RefPtr<WorkerOrWorkletThread> workerOrWorkletThread;
if (is<WorkerOrWorkletGlobalScope>(*context))
workerOrWorkletThread = downcast<WorkerOrWorkletGlobalScope>(*context).workerOrWorkletThread();
callOnMainThread([remoteIdentifier = m_remoteIdentifier, weakThis = WeakPtr { *this }, workerOrWorkletThread = WTFMove(workerOrWorkletThread)]() mutable {
MessagePortChannelProvider::singleton().checkRemotePortForActivity(remoteIdentifier, [weakThis = WTFMove(weakThis), workerOrWorkletThread = WTFMove(workerOrWorkletThread)](auto hasActivity) mutable {
if (!workerOrWorkletThread) {
if (weakThis)
weakThis->updateActivity(hasActivity);
return;
}
workerOrWorkletThread->runLoop().postTaskForMode([weakThis = WTFMove(weakThis), hasActivity](auto&) mutable {
if (weakThis)
weakThis->updateActivity(hasActivity);
}, WorkerRunLoop::defaultMode());
});
});
m_isAskingRemoteAboutGC = true;
}
// Since we need an answer from the remote object, we have to pretend we have pending activity for now.
return true;
}
bool MessagePort::isLocallyReachable() const
{
return !m_mightBeEligibleForGC;
}
MessagePort* MessagePort::locallyEntangledPort() const
{
// FIXME: As the header describes, this is an optional optimization.
// Even in the new async model we should be able to get it right.
return nullptr;
}
ExceptionOr<Vector<TransferredMessagePort>> MessagePort::disentanglePorts(Vector<RefPtr<MessagePort>>&& ports)
{
if (ports.isEmpty())
return Vector<TransferredMessagePort> { };
// Walk the incoming array - if there are any duplicate ports, or null ports or cloned ports, throw an error (per section 8.3.3 of the HTML5 spec).
HashSet<MessagePort*> portSet;
for (auto& port : ports) {
if (!port || !port->m_entangled || !portSet.add(port.get()).isNewEntry)
return Exception { DataCloneError };
}
// Passed-in ports passed validity checks, so we can disentangle them.
return WTF::map(ports, [](auto& port) {
return port->disentangle();
});
}
Vector<RefPtr<MessagePort>> MessagePort::entanglePorts(ScriptExecutionContext& context, Vector<TransferredMessagePort>&& transferredPorts)
{
LOG(MessagePorts, "Entangling %zu transferred ports to ScriptExecutionContext %s (%p)", transferredPorts.size(), context.url().string().utf8().data(), &context);
if (transferredPorts.isEmpty())
return { };
return WTF::map(transferredPorts, [&](auto& port) -> RefPtr<MessagePort> {
return MessagePort::entangle(context, WTFMove(port));
});
}
Ref<MessagePort> MessagePort::entangle(ScriptExecutionContext& context, TransferredMessagePort&& transferredPort)
{
auto port = MessagePort::create(context, transferredPort.first, transferredPort.second);
port->entangle();
return port;
}
bool MessagePort::addEventListener(const AtomString& eventType, Ref<EventListener>&& listener, const AddEventListenerOptions& options)
{
if (eventType == eventNames().messageEvent) {
if (listener->isAttribute())
start();
m_hasMessageEventListener = true;
registerLocalActivity();
}
return EventTargetWithInlineData::addEventListener(eventType, WTFMove(listener), options);
}
bool MessagePort::removeEventListener(const AtomString& eventType, EventListener& listener, const EventListenerOptions& options)
{
auto result = EventTargetWithInlineData::removeEventListener(eventType, listener, options);
if (!hasEventListeners(eventNames().messageEvent))
m_hasMessageEventListener = false;
return result;
}
const char* MessagePort::activeDOMObjectName() const
{
return "MessagePort";
}
} // namespace WebCore

View File

@@ -0,0 +1,135 @@
/*
* Copyright (C) 2008 Apple Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#pragma once
#include "ActiveDOMObject.h"
#include "EventTarget.h"
#include "ExceptionOr.h"
#include "MessagePortChannel.h"
#include "MessagePortIdentifier.h"
#include "MessageWithMessagePorts.h"
#include <wtf/WeakPtr.h>
namespace JSC {
class CallFrame;
class JSObject;
class JSValue;
}
namespace WebCore {
class Frame;
struct StructuredSerializeOptions;
class MessagePort final : public ActiveDOMObject, public EventTargetWithInlineData {
WTF_MAKE_NONCOPYABLE(MessagePort);
WTF_MAKE_ISO_ALLOCATED(MessagePort);
public:
static Ref<MessagePort> create(ScriptExecutionContext&, const MessagePortIdentifier& local, const MessagePortIdentifier& remote);
virtual ~MessagePort();
ExceptionOr<void> postMessage(JSC::JSGlobalObject&, JSC::JSValue message, StructuredSerializeOptions&&);
void start();
void close();
void entangle();
// Returns nullptr if the passed-in vector is empty.
static ExceptionOr<Vector<TransferredMessagePort>> disentanglePorts(Vector<RefPtr<MessagePort>>&&);
static Vector<RefPtr<MessagePort>> entanglePorts(ScriptExecutionContext&, Vector<TransferredMessagePort>&&);
WEBCORE_EXPORT static bool isExistingMessagePortLocallyReachable(const MessagePortIdentifier&);
WEBCORE_EXPORT static void notifyMessageAvailable(const MessagePortIdentifier&);
WEBCORE_EXPORT void messageAvailable();
bool started() const { return m_started; }
bool closed() const { return m_closed; }
void dispatchMessages();
// Returns null if there is no entangled port, or if the entangled port is run by a different thread.
// This is used solely to enable a GC optimization. Some platforms may not be able to determine ownership
// of the remote port (since it may live cross-process) - those platforms may always return null.
MessagePort* locallyEntangledPort() const;
const MessagePortIdentifier& identifier() const { return m_identifier; }
const MessagePortIdentifier& remoteIdentifier() const { return m_remoteIdentifier; }
WEBCORE_EXPORT void ref() const;
WEBCORE_EXPORT void deref() const;
WEBCORE_EXPORT bool isLocallyReachable() const;
// EventTargetWithInlineData.
EventTargetInterface eventTargetInterface() const final { return MessagePortEventTargetInterfaceType; }
ScriptExecutionContext* scriptExecutionContext() const final { return ActiveDOMObject::scriptExecutionContext(); }
void refEventTarget() final { ref(); }
void derefEventTarget() final { deref(); }
void dispatchEvent(Event&) final;
TransferredMessagePort disentangle();
static Ref<MessagePort> entangle(ScriptExecutionContext&, TransferredMessagePort&&);
private:
explicit MessagePort(ScriptExecutionContext&, const MessagePortIdentifier& local, const MessagePortIdentifier& remote);
bool addEventListener(const AtomString& eventType, Ref<EventListener>&&, const AddEventListenerOptions&) final;
bool removeEventListener(const AtomString& eventType, EventListener&, const EventListenerOptions&) final;
// ActiveDOMObject
const char* activeDOMObjectName() const final;
void contextDestroyed() final;
void stop() final { close(); }
bool virtualHasPendingActivity() const final;
void registerLocalActivity();
// A port starts out its life entangled, and remains entangled until it is closed or is cloned.
bool isEntangled() const { return !m_closed && m_entangled; }
void updateActivity(MessagePortChannelProvider::HasActivity);
bool m_started { false };
bool m_closed { false };
bool m_entangled { true };
// Flags to manage querying the remote port for GC purposes
mutable bool m_mightBeEligibleForGC { false };
mutable bool m_hasHadLocalActivitySinceLastCheck { false };
mutable bool m_isRemoteEligibleForGC { false };
mutable bool m_isAskingRemoteAboutGC { false };
bool m_hasMessageEventListener { false };
MessagePortIdentifier m_identifier;
MessagePortIdentifier m_remoteIdentifier;
mutable std::atomic<unsigned> m_refCount { 1 };
};
} // namespace WebCore

View File

@@ -0,0 +1,40 @@
/*
* Copyright (C) 2008 Apple Inc. All Rights Reserved.
* Copyright (C) 2011 Google Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
[
ActiveDOMObject,
Exposed=(Window,Worker,AudioWorklet),
GenerateIsReachable=Impl,
JSCustomMarkFunction,
] interface MessagePort : EventTarget {
[CallWith=CurrentGlobalObject] undefined postMessage(any message, sequence<object> transfer);
[CallWith=CurrentGlobalObject] undefined postMessage(any message, optional StructuredSerializeOptions options);
undefined start();
undefined close();
attribute EventHandler onmessage;
};

View File

@@ -0,0 +1,233 @@
/*
* Copyright (C) 2018 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#include "MessagePortChannel.h"
#include "Logging.h"
#include "MessagePortChannelRegistry.h"
#include <wtf/CompletionHandler.h>
#include <wtf/MainThread.h>
namespace WebCore {
Ref<MessagePortChannel> MessagePortChannel::create(MessagePortChannelRegistry& registry, const MessagePortIdentifier& port1, const MessagePortIdentifier& port2)
{
return adoptRef(*new MessagePortChannel(registry, port1, port2));
}
MessagePortChannel::MessagePortChannel(MessagePortChannelRegistry& registry, const MessagePortIdentifier& port1, const MessagePortIdentifier& port2)
: m_registry(registry)
{
ASSERT(isMainThread());
relaxAdoptionRequirement();
m_ports[0] = port1;
m_processes[0] = port1.processIdentifier;
m_entangledToProcessProtectors[0] = this;
m_ports[1] = port2;
m_processes[1] = port2.processIdentifier;
m_entangledToProcessProtectors[1] = this;
m_registry.messagePortChannelCreated(*this);
}
MessagePortChannel::~MessagePortChannel()
{
m_registry.messagePortChannelDestroyed(*this);
}
std::optional<ProcessIdentifier> MessagePortChannel::processForPort(const MessagePortIdentifier& port)
{
ASSERT(isMainThread());
ASSERT(port == m_ports[0] || port == m_ports[1]);
size_t i = port == m_ports[0] ? 0 : 1;
return m_processes[i];
}
bool MessagePortChannel::includesPort(const MessagePortIdentifier& port)
{
ASSERT(isMainThread());
return m_ports[0] == port || m_ports[1] == port;
}
void MessagePortChannel::entanglePortWithProcess(const MessagePortIdentifier& port, ProcessIdentifier process)
{
ASSERT(isMainThread());
ASSERT(port == m_ports[0] || port == m_ports[1]);
size_t i = port == m_ports[0] ? 0 : 1;
LOG(MessagePorts, "MessagePortChannel %s (%p) entangling port %s (that port has %zu messages available)", logString().utf8().data(), this, port.logString().utf8().data(), m_pendingMessages[i].size());
ASSERT(!m_processes[i] || *m_processes[i] == process);
m_processes[i] = process;
m_entangledToProcessProtectors[i] = this;
m_pendingMessagePortTransfers[i].remove(this);
}
void MessagePortChannel::disentanglePort(const MessagePortIdentifier& port)
{
ASSERT(isMainThread());
LOG(MessagePorts, "MessagePortChannel %s (%p) disentangling port %s", logString().utf8().data(), this, port.logString().utf8().data());
ASSERT(port == m_ports[0] || port == m_ports[1]);
size_t i = port == m_ports[0] ? 0 : 1;
ASSERT(m_processes[i] || m_isClosed[i]);
m_processes[i] = std::nullopt;
m_pendingMessagePortTransfers[i].add(this);
// This set of steps is to guarantee that the lock is unlocked before the
// last ref to this object is released.
auto protectedThis = WTFMove(m_entangledToProcessProtectors[i]);
}
void MessagePortChannel::closePort(const MessagePortIdentifier& port)
{
ASSERT(isMainThread());
ASSERT(port == m_ports[0] || port == m_ports[1]);
size_t i = port == m_ports[0] ? 0 : 1;
m_processes[i] = std::nullopt;
m_isClosed[i] = true;
// This set of steps is to guarantee that the lock is unlocked before the
// last ref to this object is released.
Ref protectedThis { *this };
m_pendingMessages[i].clear();
m_pendingMessagePortTransfers[i].clear();
m_pendingMessageProtectors[i] = nullptr;
m_entangledToProcessProtectors[i] = nullptr;
}
bool MessagePortChannel::postMessageToRemote(MessageWithMessagePorts&& message, const MessagePortIdentifier& remoteTarget)
{
ASSERT(isMainThread());
ASSERT(remoteTarget == m_ports[0] || remoteTarget == m_ports[1]);
size_t i = remoteTarget == m_ports[0] ? 0 : 1;
m_pendingMessages[i].append(WTFMove(message));
LOG(MessagePorts, "MessagePortChannel %s (%p) now has %zu messages pending on port %s", logString().utf8().data(), this, m_pendingMessages[i].size(), remoteTarget.logString().utf8().data());
if (m_pendingMessages[i].size() == 1) {
m_pendingMessageProtectors[i] = this;
return true;
}
ASSERT(m_pendingMessageProtectors[i] == this);
return false;
}
void MessagePortChannel::takeAllMessagesForPort(const MessagePortIdentifier& port, CompletionHandler<void(Vector<MessageWithMessagePorts>&&, CompletionHandler<void()>&&)>&& callback)
{
ASSERT(isMainThread());
LOG(MessagePorts, "MessagePortChannel %p taking all messages for port %s", this, port.logString().utf8().data());
ASSERT(port == m_ports[0] || port == m_ports[1]);
size_t i = port == m_ports[0] ? 0 : 1;
if (m_pendingMessages[i].isEmpty()) {
callback({ }, [] { });
return;
}
ASSERT(m_pendingMessageProtectors[i]);
Vector<MessageWithMessagePorts> result;
result.swap(m_pendingMessages[i]);
++m_messageBatchesInFlight;
LOG(MessagePorts, "There are %zu messages to take for port %s. Taking them now, messages in flight is now %" PRIu64, result.size(), port.logString().utf8().data(), m_messageBatchesInFlight);
auto size = result.size();
callback(WTFMove(result), [size, this, port, protectedThis = WTFMove(m_pendingMessageProtectors[i])] {
UNUSED_PARAM(port);
#if LOG_DISABLED
UNUSED_PARAM(size);
#endif
--m_messageBatchesInFlight;
LOG(MessagePorts, "Message port channel %s was notified that a batch of %zu message port messages targeted for port %s just completed dispatch, in flight is now %" PRIu64, logString().utf8().data(), size, port.logString().utf8().data(), m_messageBatchesInFlight);
});
}
void MessagePortChannel::checkRemotePortForActivity(const MessagePortIdentifier& remotePort, CompletionHandler<void(MessagePortChannelProvider::HasActivity)>&& callback)
{
ASSERT(isMainThread());
ASSERT(remotePort == m_ports[0] || remotePort == m_ports[1]);
// If the remote port is closed there is no pending activity.
size_t i = remotePort == m_ports[0] ? 0 : 1;
if (m_isClosed[i]) {
callback(MessagePortChannelProvider::HasActivity::No);
return;
}
// If there are any messages in flight between the ports, there is pending activity.
if (hasAnyMessagesPendingOrInFlight()) {
callback(MessagePortChannelProvider::HasActivity::Yes);
return;
}
// If the port is not currently in a process then it's being transferred as part of a postMessage.
// We treat these ports as if they do have activity since they will be revived when the message is delivered.
if (!m_processes[i]) {
callback(MessagePortChannelProvider::HasActivity::Yes);
return;
}
CompletionHandler<void(MessagePortChannelProvider::HasActivity)> outerCallback = [this, protectedThis = Ref { *this }, callback = WTFMove(callback)](auto hasActivity) mutable {
if (hasActivity == MessagePortChannelProvider::HasActivity::Yes) {
callback(hasActivity);
return;
}
// If the remote port said it had no activity, check again for any messages that might be in flight.
// This is because it might have asynchronously sent a message just before it was asked about local activity.
if (hasAnyMessagesPendingOrInFlight())
hasActivity = MessagePortChannelProvider::HasActivity::Yes;
callback(hasActivity);
};
m_registry.checkProcessLocalPortForActivity(remotePort, *m_processes[i], WTFMove(outerCallback));
}
bool MessagePortChannel::hasAnyMessagesPendingOrInFlight() const
{
ASSERT(isMainThread());
return m_messageBatchesInFlight || !m_pendingMessages[0].isEmpty() || !m_pendingMessages[1].isEmpty();
}
} // namespace WebCore

View File

@@ -0,0 +1,82 @@
/*
* Copyright (C) 2018 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#pragma once
#include "MessagePortChannelProvider.h"
#include "MessagePortIdentifier.h"
#include "MessageWithMessagePorts.h"
#include "ProcessIdentifier.h"
#include <wtf/HashSet.h>
#include <wtf/RefCounted.h>
#include <wtf/text/WTFString.h>
namespace WebCore {
class MessagePortChannelRegistry;
class MessagePortChannel : public RefCounted<MessagePortChannel> {
public:
static Ref<MessagePortChannel> create(MessagePortChannelRegistry&, const MessagePortIdentifier& port1, const MessagePortIdentifier& port2);
~MessagePortChannel();
const MessagePortIdentifier& port1() const { return m_ports[0]; }
const MessagePortIdentifier& port2() const { return m_ports[1]; }
WEBCORE_EXPORT std::optional<ProcessIdentifier> processForPort(const MessagePortIdentifier&);
bool includesPort(const MessagePortIdentifier&);
void entanglePortWithProcess(const MessagePortIdentifier&, ProcessIdentifier);
void disentanglePort(const MessagePortIdentifier&);
void closePort(const MessagePortIdentifier&);
bool postMessageToRemote(MessageWithMessagePorts&&, const MessagePortIdentifier& remoteTarget);
void takeAllMessagesForPort(const MessagePortIdentifier&, CompletionHandler<void(Vector<MessageWithMessagePorts>&&, CompletionHandler<void()>&&)>&&);
void checkRemotePortForActivity(const MessagePortIdentifier&, CompletionHandler<void(MessagePortChannelProvider::HasActivity)>&& callback);
WEBCORE_EXPORT bool hasAnyMessagesPendingOrInFlight() const;
uint64_t beingTransferredCount();
#if !LOG_DISABLED
String logString() const { return makeString(m_ports[0].logString(), ":", m_ports[1].logString()); }
#endif
private:
MessagePortChannel(MessagePortChannelRegistry&, const MessagePortIdentifier& port1, const MessagePortIdentifier& port2);
MessagePortIdentifier m_ports[2];
bool m_isClosed[2] { false, false };
std::optional<ProcessIdentifier> m_processes[2];
RefPtr<MessagePortChannel> m_entangledToProcessProtectors[2];
Vector<MessageWithMessagePorts> m_pendingMessages[2];
HashSet<RefPtr<MessagePortChannel>> m_pendingMessagePortTransfers[2];
RefPtr<MessagePortChannel> m_pendingMessageProtectors[2];
uint64_t m_messageBatchesInFlight { 0 };
MessagePortChannelRegistry& m_registry;
};
} // namespace WebCore

View File

@@ -0,0 +1,69 @@
/*
* Copyright (C) 2018 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#include "MessagePortChannelProvider.h"
#include "Document.h"
#include "MessagePortChannelProviderImpl.h"
#include "WorkerGlobalScope.h"
#include "WorkletGlobalScope.h"
#include <wtf/MainThread.h>
namespace WebCore {
static MessagePortChannelProvider* globalProvider;
MessagePortChannelProvider& MessagePortChannelProvider::singleton()
{
ASSERT(isMainThread());
static std::once_flag onceFlag;
std::call_once(onceFlag, [] {
if (!globalProvider)
globalProvider = new MessagePortChannelProviderImpl;
});
return *globalProvider;
}
void MessagePortChannelProvider::setSharedProvider(MessagePortChannelProvider& provider)
{
RELEASE_ASSERT(isMainThread());
RELEASE_ASSERT(!globalProvider);
globalProvider = &provider;
}
MessagePortChannelProvider& MessagePortChannelProvider::fromContext(ScriptExecutionContext& context)
{
if (auto document = dynamicDowncast<Document>(context))
return document->messagePortChannelProvider();
if (auto workletScope = dynamicDowncast<WorkletGlobalScope>(context))
return workletScope->messagePortChannelProvider();
return downcast<WorkerGlobalScope>(context).messagePortChannelProvider();
}
} // namespace WebCore

View File

@@ -0,0 +1,78 @@
/*
* Copyright (C) 2018 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#pragma once
#include "ProcessIdentifier.h"
#include <wtf/CompletionHandler.h>
#include <wtf/Vector.h>
namespace WebCore {
class ScriptExecutionContext;
struct MessagePortIdentifier;
struct MessageWithMessagePorts;
class MessagePortChannelProvider {
public:
static MessagePortChannelProvider& fromContext(ScriptExecutionContext&);
static MessagePortChannelProvider& singleton();
WEBCORE_EXPORT static void setSharedProvider(MessagePortChannelProvider&);
virtual ~MessagePortChannelProvider() { }
// Operations that WebProcesses perform
virtual void createNewMessagePortChannel(const MessagePortIdentifier& local, const MessagePortIdentifier& remote) = 0;
virtual void entangleLocalPortInThisProcessToRemote(const MessagePortIdentifier& local, const MessagePortIdentifier& remote) = 0;
virtual void messagePortDisentangled(const MessagePortIdentifier& local) = 0;
virtual void messagePortClosed(const MessagePortIdentifier& local) = 0;
virtual void takeAllMessagesForPort(const MessagePortIdentifier&, CompletionHandler<void(Vector<MessageWithMessagePorts>&&, CompletionHandler<void()>&&)>&&) = 0;
virtual void postMessageToRemote(MessageWithMessagePorts&&, const MessagePortIdentifier& remoteTarget) = 0;
enum class HasActivity {
Yes,
No,
};
virtual void checkRemotePortForActivity(const MessagePortIdentifier& remoteTarget, CompletionHandler<void(HasActivity)>&& callback) = 0;
private:
};
} // namespace WebCore
namespace WTF {
template<> struct EnumTraits<WebCore::MessagePortChannelProvider::HasActivity> {
using values = EnumValues<
WebCore::MessagePortChannelProvider::HasActivity,
WebCore::MessagePortChannelProvider::HasActivity::No,
WebCore::MessagePortChannelProvider::HasActivity::Yes
>;
};
}

View File

@@ -0,0 +1,114 @@
/*
* Copyright (C) 2018 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#include "MessagePortChannelProviderImpl.h"
#include "MessagePort.h"
#include <wtf/MainThread.h>
#include <wtf/RunLoop.h>
namespace WebCore {
static inline MessagePortChannelRegistry::CheckProcessLocalPortForActivityCallback checkActivityCallback()
{
return [](auto& messagePortIdentifier, auto, auto&& callback) {
ASSERT(isMainThread());
callback(MessagePort::isExistingMessagePortLocallyReachable(messagePortIdentifier) ? MessagePortChannelProvider::HasActivity::Yes : MessagePortChannelProvider::HasActivity::No);
};
}
MessagePortChannelProviderImpl::MessagePortChannelProviderImpl()
: m_registry(checkActivityCallback())
{
}
MessagePortChannelProviderImpl::~MessagePortChannelProviderImpl()
{
ASSERT_NOT_REACHED();
}
void MessagePortChannelProviderImpl::createNewMessagePortChannel(const MessagePortIdentifier& local, const MessagePortIdentifier& remote)
{
ensureOnMainThread([registry = &m_registry, local, remote] {
registry->didCreateMessagePortChannel(local, remote);
});
}
void MessagePortChannelProviderImpl::entangleLocalPortInThisProcessToRemote(const MessagePortIdentifier& local, const MessagePortIdentifier& remote)
{
ensureOnMainThread([registry = &m_registry, local, remote] {
registry->didEntangleLocalToRemote(local, remote, Process::identifier());
});
}
void MessagePortChannelProviderImpl::messagePortDisentangled(const MessagePortIdentifier& local)
{
ensureOnMainThread([registry = &m_registry, local] {
registry->didDisentangleMessagePort(local);
});
}
void MessagePortChannelProviderImpl::messagePortClosed(const MessagePortIdentifier& local)
{
ensureOnMainThread([registry = &m_registry, local] {
registry->didCloseMessagePort(local);
});
}
void MessagePortChannelProviderImpl::postMessageToRemote(MessageWithMessagePorts&& message, const MessagePortIdentifier& remoteTarget)
{
ensureOnMainThread([registry = &m_registry, message = WTFMove(message), remoteTarget]() mutable {
if (registry->didPostMessageToRemote(WTFMove(message), remoteTarget))
MessagePort::notifyMessageAvailable(remoteTarget);
});
}
void MessagePortChannelProviderImpl::takeAllMessagesForPort(const MessagePortIdentifier& port, CompletionHandler<void(Vector<MessageWithMessagePorts>&&, CompletionHandler<void()>&&)>&& outerCallback)
{
// It is the responsibility of outerCallback to get itself to the appropriate thread (e.g. WebWorker thread)
auto callback = [outerCallback = WTFMove(outerCallback)](Vector<MessageWithMessagePorts>&& messages, CompletionHandler<void()>&& messageDeliveryCallback) mutable {
ASSERT(isMainThread());
outerCallback(WTFMove(messages), WTFMove(messageDeliveryCallback));
};
ensureOnMainThread([registry = &m_registry, port, callback = WTFMove(callback)]() mutable {
registry->takeAllMessagesForPort(port, WTFMove(callback));
});
}
void MessagePortChannelProviderImpl::checkRemotePortForActivity(const MessagePortIdentifier& remoteTarget, CompletionHandler<void(HasActivity)>&& outerCallback)
{
auto callback = Function<void(HasActivity)> { [outerCallback = WTFMove(outerCallback)](HasActivity hasActivity) mutable {
ASSERT(isMainThread());
outerCallback(hasActivity);
} };
ensureOnMainThread([registry = &m_registry, remoteTarget, callback = WTFMove(callback)]() mutable {
registry->checkRemotePortForActivity(remoteTarget, WTFMove(callback));
});
}
} // namespace WebCore

View File

@@ -0,0 +1,50 @@
/*
* Copyright (C) 2018 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#pragma once
#include "MessagePortChannelProvider.h"
#include "MessagePortChannelRegistry.h"
namespace WebCore {
class MessagePortChannelProviderImpl final : public MessagePortChannelProvider {
public:
MessagePortChannelProviderImpl();
~MessagePortChannelProviderImpl() final;
private:
void createNewMessagePortChannel(const MessagePortIdentifier& local, const MessagePortIdentifier& remote) final;
void entangleLocalPortInThisProcessToRemote(const MessagePortIdentifier& local, const MessagePortIdentifier& remote) final;
void messagePortDisentangled(const MessagePortIdentifier& local) final;
void messagePortClosed(const MessagePortIdentifier& local) final;
void postMessageToRemote(MessageWithMessagePorts&&, const MessagePortIdentifier& remoteTarget) final;
void takeAllMessagesForPort(const MessagePortIdentifier&, CompletionHandler<void(Vector<MessageWithMessagePorts>&&, CompletionHandler<void()>&&)>&&) final;
void checkRemotePortForActivity(const MessagePortIdentifier& remoteTarget, CompletionHandler<void(HasActivity)>&& callback) final;
MessagePortChannelRegistry m_registry;
};
} // namespace WebCore

View File

@@ -0,0 +1,186 @@
/*
* Copyright (C) 2018 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#include "MessagePortChannelRegistry.h"
#include "Logging.h"
#include <wtf/CompletionHandler.h>
#include <wtf/MainThread.h>
namespace WebCore {
MessagePortChannelRegistry::MessagePortChannelRegistry(CheckProcessLocalPortForActivityCallback&& checkProcessLocalPortForActivityCallback)
: m_checkProcessLocalPortForActivityCallback(WTFMove(checkProcessLocalPortForActivityCallback))
{
}
MessagePortChannelRegistry::~MessagePortChannelRegistry()
{
ASSERT(m_openChannels.isEmpty());
}
void MessagePortChannelRegistry::didCreateMessagePortChannel(const MessagePortIdentifier& port1, const MessagePortIdentifier& port2)
{
LOG(MessagePorts, "Registry: Creating MessagePortChannel %p linking %s and %s", this, port1.logString().utf8().data(), port2.logString().utf8().data());
ASSERT(isMainThread());
MessagePortChannel::create(*this, port1, port2);
}
void MessagePortChannelRegistry::messagePortChannelCreated(MessagePortChannel& channel)
{
ASSERT(isMainThread());
auto result = m_openChannels.ensure(channel.port1(), [channel = &channel] {
return channel;
});
ASSERT(result.isNewEntry);
result = m_openChannels.ensure(channel.port2(), [channel = &channel] {
return channel;
});
ASSERT(result.isNewEntry);
}
void MessagePortChannelRegistry::messagePortChannelDestroyed(MessagePortChannel& channel)
{
ASSERT(isMainThread());
ASSERT(m_openChannels.get(channel.port1()) == &channel);
ASSERT(m_openChannels.get(channel.port2()) == &channel);
m_openChannels.remove(channel.port1());
m_openChannels.remove(channel.port2());
LOG(MessagePorts, "Registry: After removing channel %s there are %u channels left in the registry:", channel.logString().utf8().data(), m_openChannels.size());
}
void MessagePortChannelRegistry::didEntangleLocalToRemote(const MessagePortIdentifier& local, const MessagePortIdentifier& remote, ProcessIdentifier process)
{
ASSERT(isMainThread());
// The channel might be gone if the remote side was closed.
auto* channel = m_openChannels.get(local);
if (!channel)
return;
ASSERT_UNUSED(remote, channel->includesPort(remote));
channel->entanglePortWithProcess(local, process);
}
void MessagePortChannelRegistry::didDisentangleMessagePort(const MessagePortIdentifier& port)
{
ASSERT(isMainThread());
// The channel might be gone if the remote side was closed.
auto* channel = m_openChannels.get(port);
if (!channel)
return;
channel->disentanglePort(port);
}
void MessagePortChannelRegistry::didCloseMessagePort(const MessagePortIdentifier& port)
{
ASSERT(isMainThread());
LOG(MessagePorts, "Registry: MessagePort %s closed in registry", port.logString().utf8().data());
auto* channel = m_openChannels.get(port);
if (!channel)
return;
#ifndef NDEBUG
if (channel && channel->hasAnyMessagesPendingOrInFlight())
LOG(MessagePorts, "Registry: (Note) The channel closed for port %s had messages pending or in flight", port.logString().utf8().data());
#endif
channel->closePort(port);
// FIXME: When making message ports be multi-process, this should probably push a notification
// to the remaining port to tell it this port closed.
}
bool MessagePortChannelRegistry::didPostMessageToRemote(MessageWithMessagePorts&& message, const MessagePortIdentifier& remoteTarget)
{
ASSERT(isMainThread());
LOG(MessagePorts, "Registry: Posting message to MessagePort %s in registry", remoteTarget.logString().utf8().data());
// The channel might be gone if the remote side was closed.
auto* channel = m_openChannels.get(remoteTarget);
if (!channel) {
LOG(MessagePorts, "Registry: Could not find MessagePortChannel for port %s; It was probably closed. Message will be dropped.", remoteTarget.logString().utf8().data());
return false;
}
return channel->postMessageToRemote(WTFMove(message), remoteTarget);
}
void MessagePortChannelRegistry::takeAllMessagesForPort(const MessagePortIdentifier& port, CompletionHandler<void(Vector<MessageWithMessagePorts>&&, CompletionHandler<void()>&&)>&& callback)
{
ASSERT(isMainThread());
LOG(MessagePorts, "Registry: Taking all messages for MessagePort %s", port.logString().utf8().data());
// The channel might be gone if the remote side was closed.
auto* channel = m_openChannels.get(port);
if (!channel) {
callback({ }, [] { });
return;
}
channel->takeAllMessagesForPort(port, WTFMove(callback));
}
void MessagePortChannelRegistry::checkRemotePortForActivity(const MessagePortIdentifier& remoteTarget, CompletionHandler<void(MessagePortChannelProvider::HasActivity)>&& callback)
{
ASSERT(isMainThread());
// The channel might be gone if the remote side was closed.
auto* channel = m_openChannels.get(remoteTarget);
if (!channel) {
callback(MessagePortChannelProvider::HasActivity::No);
return;
}
channel->checkRemotePortForActivity(remoteTarget, WTFMove(callback));
}
MessagePortChannel* MessagePortChannelRegistry::existingChannelContainingPort(const MessagePortIdentifier& port)
{
ASSERT(isMainThread());
return m_openChannels.get(port);
}
void MessagePortChannelRegistry::checkProcessLocalPortForActivity(const MessagePortIdentifier& messagePortIdentifier, ProcessIdentifier processIdentifier, CompletionHandler<void(MessagePortChannelProvider::HasActivity)>&& callback)
{
m_checkProcessLocalPortForActivityCallback(messagePortIdentifier, processIdentifier, WTFMove(callback));
}
} // namespace WebCore

View File

@@ -0,0 +1,63 @@
/*
* Copyright (C) 2018 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#pragma once
#include "MessagePortChannel.h"
#include "MessagePortChannelProvider.h"
#include "MessagePortIdentifier.h"
#include "ProcessIdentifier.h"
#include <wtf/HashMap.h>
namespace WebCore {
class MessagePortChannelRegistry {
public:
using CheckProcessLocalPortForActivityCallback = Function<void(const MessagePortIdentifier&, ProcessIdentifier, CompletionHandler<void(MessagePortChannelProvider::HasActivity)>&&)>;
WEBCORE_EXPORT explicit MessagePortChannelRegistry(CheckProcessLocalPortForActivityCallback&&);
WEBCORE_EXPORT ~MessagePortChannelRegistry();
WEBCORE_EXPORT void didCreateMessagePortChannel(const MessagePortIdentifier& port1, const MessagePortIdentifier& port2);
WEBCORE_EXPORT void didEntangleLocalToRemote(const MessagePortIdentifier& local, const MessagePortIdentifier& remote, ProcessIdentifier);
WEBCORE_EXPORT void didDisentangleMessagePort(const MessagePortIdentifier& local);
WEBCORE_EXPORT void didCloseMessagePort(const MessagePortIdentifier& local);
WEBCORE_EXPORT bool didPostMessageToRemote(MessageWithMessagePorts&&, const MessagePortIdentifier& remoteTarget);
WEBCORE_EXPORT void takeAllMessagesForPort(const MessagePortIdentifier&, CompletionHandler<void(Vector<MessageWithMessagePorts>&&, CompletionHandler<void()>&&)>&&);
WEBCORE_EXPORT void checkRemotePortForActivity(const MessagePortIdentifier& remoteTarget, CompletionHandler<void(MessagePortChannelProvider::HasActivity)>&& callback);
WEBCORE_EXPORT MessagePortChannel* existingChannelContainingPort(const MessagePortIdentifier&);
WEBCORE_EXPORT void messagePortChannelCreated(MessagePortChannel&);
WEBCORE_EXPORT void messagePortChannelDestroyed(MessagePortChannel&);
void checkProcessLocalPortForActivity(const MessagePortIdentifier&, ProcessIdentifier, CompletionHandler<void(MessagePortChannelProvider::HasActivity)>&&);
private:
HashMap<MessagePortIdentifier, MessagePortChannel*> m_openChannels;
CheckProcessLocalPortForActivityCallback m_checkProcessLocalPortForActivityCallback;
};
} // namespace WebCore

View File

@@ -0,0 +1,108 @@
/*
* Copyright (C) 2018 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#pragma once
#include "ProcessIdentifier.h"
#include <wtf/Hasher.h>
#include <wtf/text/StringConcatenateNumbers.h>
namespace WebCore {
struct MessagePortIdentifier {
ProcessIdentifier processIdentifier;
enum PortIdentifierType { };
ObjectIdentifier<PortIdentifierType> portIdentifier;
template<class Encoder> void encode(Encoder&) const;
template<class Decoder> static std::optional<MessagePortIdentifier> decode(Decoder&);
#if !LOG_DISABLED
String logString() const;
#endif
};
inline void add(Hasher& hasher, const MessagePortIdentifier& identifier)
{
add(hasher, identifier.processIdentifier, identifier.portIdentifier);
}
inline bool operator==(const MessagePortIdentifier& a, const MessagePortIdentifier& b)
{
return a.processIdentifier == b.processIdentifier && a.portIdentifier == b.portIdentifier;
}
template<class Encoder>
void MessagePortIdentifier::encode(Encoder& encoder) const
{
encoder << processIdentifier << portIdentifier;
}
template<class Decoder>
std::optional<MessagePortIdentifier> MessagePortIdentifier::decode(Decoder& decoder)
{
std::optional<ProcessIdentifier> processIdentifier;
decoder >> processIdentifier;
if (!processIdentifier)
return std::nullopt;
std::optional<ObjectIdentifier<PortIdentifierType>> portIdentifier;
decoder >> portIdentifier;
if (!portIdentifier)
return std::nullopt;
return { { WTFMove(*processIdentifier), WTFMove(*portIdentifier) } };
}
#if !LOG_DISABLED
inline String MessagePortIdentifier::logString() const
{
return makeString(processIdentifier.toUInt64(), '-', portIdentifier.toUInt64());
}
#endif
} // namespace WebCore
namespace WTF {
struct MessagePortIdentifierHash {
static unsigned hash(const WebCore::MessagePortIdentifier& key) { return computeHash(key); }
static bool equal(const WebCore::MessagePortIdentifier& a, const WebCore::MessagePortIdentifier& b) { return a == b; }
static const bool safeToCompareToEmptyOrDeleted = true;
};
template<> struct HashTraits<WebCore::MessagePortIdentifier> : GenericHashTraits<WebCore::MessagePortIdentifier> {
static WebCore::MessagePortIdentifier emptyValue() { return { }; }
static void constructDeletedValue(WebCore::MessagePortIdentifier& slot) { new (NotNull, &slot.processIdentifier) WebCore::ProcessIdentifier(WTF::HashTableDeletedValue); }
static bool isDeletedValue(const WebCore::MessagePortIdentifier& slot) { return slot.processIdentifier.isHashTableDeletedValue(); }
};
template<> struct DefaultHash<WebCore::MessagePortIdentifier> : MessagePortIdentifierHash { };
} // namespace WTF

View File

@@ -0,0 +1,65 @@
/*
* Copyright (C) 2018 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#pragma once
#include "SerializedScriptValue.h"
#include "TransferredMessagePort.h"
#include <wtf/RefPtr.h>
namespace WebCore {
struct MessageWithMessagePorts {
RefPtr<SerializedScriptValue> message;
Vector<TransferredMessagePort> transferredPorts;
template<class Encoder> void encode(Encoder&) const;
template<class Decoder> static std::optional<MessageWithMessagePorts> decode(Decoder&);
};
template<class Encoder>
void MessageWithMessagePorts::encode(Encoder& encoder) const
{
ASSERT(message);
encoder << *message << transferredPorts;
}
template<class Decoder>
std::optional<MessageWithMessagePorts> MessageWithMessagePorts::decode(Decoder& decoder)
{
MessageWithMessagePorts result;
result.message = SerializedScriptValue::decode(decoder);
if (!result.message)
return std::nullopt;
if (!decoder.decode(result.transferredPorts))
return std::nullopt;
return result;
}
} // namespace WebCore

View File

@@ -0,0 +1,91 @@
/*
* Copyright (C) 2014 Yoav Weiss (yoav@yoav.ws)
* Copyright (C) 2015 Akamai Technologies Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*
*/
#include "config.h"
#include "Microtasks.h"
// #include "CommonVM.h"
#include "EventLoop.h"
#include "WorkerGlobalScope.h"
#include <wtf/MainThread.h>
#include <wtf/NeverDestroyed.h>
#include <wtf/SetForScope.h>
namespace WebCore {
MicrotaskQueue::MicrotaskQueue(JSC::VM& vm)
: m_vm(vm)
{
}
MicrotaskQueue::~MicrotaskQueue() = default;
void MicrotaskQueue::append(std::unique_ptr<EventLoopTask>&& task)
{
m_microtaskQueue.append(WTFMove(task));
}
void MicrotaskQueue::performMicrotaskCheckpoint()
{
if (m_performingMicrotaskCheckpoint)
return;
SetForScope change(m_performingMicrotaskCheckpoint, true);
JSC::JSLockHolder locker(vm());
Vector<std::unique_ptr<EventLoopTask>> toKeep;
while (!m_microtaskQueue.isEmpty()) {
Vector<std::unique_ptr<EventLoopTask>> queue = WTFMove(m_microtaskQueue);
for (auto& task : queue) {
auto* group = task->group();
if (!group || group->isStoppedPermanently())
continue;
if (group->isSuspended())
toKeep.append(WTFMove(task));
else
task->execute();
}
}
vm().finalizeSynchronousJSExecution();
m_microtaskQueue = WTFMove(toKeep);
auto checkpointTasks = std::exchange(m_checkpointTasks, {});
for (auto& checkpointTask : checkpointTasks) {
auto* group = checkpointTask->group();
if (!group || group->isStoppedPermanently())
continue;
if (group->isSuspended()) {
m_checkpointTasks.append(WTFMove(checkpointTask));
continue;
}
checkpointTask->execute();
}
}
void MicrotaskQueue::addCheckpointTask(std::unique_ptr<EventLoopTask>&& task)
{
m_checkpointTasks.append(WTFMove(task));
}
} // namespace WebCore

View File

@@ -0,0 +1,57 @@
/*
* Copyright (C) 2014 Yoav Weiss (yoav@yoav.ws)
* Copyright (C) 2015 Akamai Technologies Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*
*/
#pragma once
#include <wtf/Forward.h>
#include <wtf/Vector.h>
namespace JSC {
class VM;
} // namespace JSC
namespace WebCore {
class EventLoopTask;
class MicrotaskQueue final {
WTF_MAKE_FAST_ALLOCATED;
public:
WEBCORE_EXPORT MicrotaskQueue(JSC::VM&);
WEBCORE_EXPORT ~MicrotaskQueue();
WEBCORE_EXPORT void append(std::unique_ptr<EventLoopTask>&&);
WEBCORE_EXPORT void performMicrotaskCheckpoint();
WEBCORE_EXPORT void addCheckpointTask(std::unique_ptr<EventLoopTask>&&);
private:
JSC::VM& vm() const { return m_vm.get(); }
bool m_performingMicrotaskCheckpoint { false };
Vector<std::unique_ptr<EventLoopTask>> m_microtaskQueue;
// For the main thread the VM lives forever. For workers it's lifetime is tied to our owning WorkerGlobalScope. Regardless, we retain the VM here to be safe.
Ref<JSC::VM> m_vm;
Vector<std::unique_ptr<EventLoopTask>> m_checkpointTasks;
};
} // namespace WebCore

View File

@@ -0,0 +1,199 @@
/*
* Copyright (C) 2008 Apple Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include "config.h"
#include "NavigatorBase.h"
#include "Document.h"
#include "GPU.h"
#include "RuntimeEnabledFeatures.h"
#include "ServiceWorkerContainer.h"
#include "StorageManager.h"
#include "WebLockManager.h"
#include <mutex>
#include <wtf/Language.h>
#include <wtf/NeverDestroyed.h>
#include <wtf/NumberOfCores.h>
#include <wtf/UniqueRef.h>
#include <wtf/text/WTFString.h>
#if OS(LINUX)
#include "sys/utsname.h"
#include <wtf/StdLibExtras.h>
#endif
#if PLATFORM(IOS_FAMILY)
#include "Device.h"
#endif
#ifndef WEBCORE_NAVIGATOR_PRODUCT
#define WEBCORE_NAVIGATOR_PRODUCT "Gecko"_s
#endif // ifndef WEBCORE_NAVIGATOR_PRODUCT
#ifndef WEBCORE_NAVIGATOR_PRODUCT_SUB
#define WEBCORE_NAVIGATOR_PRODUCT_SUB "20030107"_s
#endif // ifndef WEBCORE_NAVIGATOR_PRODUCT_SUB
#ifndef WEBCORE_NAVIGATOR_VENDOR
#define WEBCORE_NAVIGATOR_VENDOR "Apple Computer, Inc."_s
#endif // ifndef WEBCORE_NAVIGATOR_VENDOR
#ifndef WEBCORE_NAVIGATOR_VENDOR_SUB
#define WEBCORE_NAVIGATOR_VENDOR_SUB emptyString()
#endif // ifndef WEBCORE_NAVIGATOR_VENDOR_SUB
namespace WebCore {
NavigatorBase::NavigatorBase(ScriptExecutionContext* context)
: ContextDestructionObserver(context)
{
}
NavigatorBase::~NavigatorBase() = default;
String NavigatorBase::appName()
{
return "Netscape"_s;
}
String NavigatorBase::appVersion() const
{
// Version is everything in the user agent string past the "Mozilla/" prefix.
const String& agent = userAgent();
return agent.substring(agent.find('/') + 1);
}
String NavigatorBase::platform() const
{
#if OS(LINUX)
static LazyNeverDestroyed<String> platformName;
static std::once_flag onceKey;
std::call_once(onceKey, [] {
struct utsname osname;
platformName.construct(uname(&osname) >= 0 ? String(osname.sysname) + " "_str + String(osname.machine) : String(""_s));
});
return platformName->isolatedCopy();
#elif PLATFORM(IOS_FAMILY)
return deviceName();
#elif OS(MAC_OS_X)
return "MacIntel"_s;
#elif OS(WINDOWS)
return "Win32"_s;
#else
return ""_s;
#endif
}
String NavigatorBase::appCodeName()
{
return "Mozilla"_s;
}
String NavigatorBase::product()
{
return WEBCORE_NAVIGATOR_PRODUCT;
}
String NavigatorBase::productSub()
{
return WEBCORE_NAVIGATOR_PRODUCT_SUB;
}
String NavigatorBase::vendor()
{
return WEBCORE_NAVIGATOR_VENDOR;
}
String NavigatorBase::vendorSub()
{
return WEBCORE_NAVIGATOR_VENDOR_SUB;
}
String NavigatorBase::language()
{
return defaultLanguage();
}
Vector<String> NavigatorBase::languages()
{
// We intentionally expose only the primary language for privacy reasons.
return { defaultLanguage() };
}
StorageManager& NavigatorBase::storage()
{
if (!m_storageManager)
m_storageManager = StorageManager::create(*this);
return *m_storageManager;
}
WebLockManager& NavigatorBase::locks()
{
if (!m_webLockManager)
m_webLockManager = WebLockManager::create(*this);
return *m_webLockManager;
}
#if ENABLE(SERVICE_WORKER)
ServiceWorkerContainer& NavigatorBase::serviceWorker()
{
ASSERT(!scriptExecutionContext() || scriptExecutionContext()->settingsValues().serviceWorkersEnabled);
if (!m_serviceWorkerContainer)
m_serviceWorkerContainer = ServiceWorkerContainer::create(scriptExecutionContext(), *this).moveToUniquePtr();
return *m_serviceWorkerContainer;
}
ExceptionOr<ServiceWorkerContainer&> NavigatorBase::serviceWorker(ScriptExecutionContext& context)
{
if (is<Document>(context) && downcast<Document>(context).isSandboxed(SandboxOrigin))
return Exception { SecurityError, "Service Worker is disabled because the context is sandboxed and lacks the 'allow-same-origin' flag" };
return serviceWorker();
}
#endif
int NavigatorBase::hardwareConcurrency()
{
static int numberOfCores;
static std::once_flag once;
std::call_once(once, [] {
// Enforce a maximum for the number of cores reported to mitigate
// fingerprinting for the minority of machines with large numbers of cores.
// If machines with more than 8 cores become commonplace, we should bump this number.
// see https://bugs.webkit.org/show_bug.cgi?id=132588 for the
// rationale behind this decision.
if (WTF::numberOfProcessorCores() < 8)
numberOfCores = 4;
else
numberOfCores = 8;
});
return numberOfCores;
}
} // namespace WebCore

View File

@@ -0,0 +1,86 @@
/*
* Copyright (C) 2008 Apple Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#pragma once
#include "ContextDestructionObserver.h"
#include "ExceptionOr.h"
#include <wtf/Forward.h>
#include <wtf/RefCounted.h>
#include <wtf/UniqueRef.h>
#include <wtf/Vector.h>
#include <wtf/WeakPtr.h>
namespace WebCore {
// class GPU;
class ScriptExecutionContext;
class ServiceWorkerContainer;
// class StorageManager;
// class WebLockManager;
class NavigatorBase : public RefCounted<NavigatorBase>, public ContextDestructionObserver, public CanMakeWeakPtr<NavigatorBase> {
public:
virtual ~NavigatorBase();
static String appName();
String appVersion() const;
virtual const String& userAgent() const = 0;
virtual String platform() const;
static String appCodeName();
static String product();
static String productSub();
static String vendor();
static String vendorSub();
virtual bool onLine() const = 0;
static String language();
static Vector<String> languages();
// StorageManager& storage();
// WebLockManager& locks();
static int hardwareConcurrency();
protected:
explicit NavigatorBase(ScriptExecutionContext*);
private:
// RefPtr<StorageManager> m_storageManager;
// RefPtr<WebLockManager> m_webLockManager;
// #if ENABLE(SERVICE_WORKER)
// public:
// ServiceWorkerContainer& serviceWorker();
// ExceptionOr<ServiceWorkerContainer&> serviceWorker(ScriptExecutionContext&);
// private:
// std::unique_ptr<ServiceWorkerContainer> m_serviceWorkerContainer;
// #endif
};
} // namespace WebCore

View File

@@ -0,0 +1,54 @@
/*
* Copyright (C) 2017 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#include "ProcessIdentifier.h"
#include <wtf/MainThread.h>
namespace WebCore {
namespace Process {
static std::optional<ProcessIdentifier> globalIdentifier;
void setIdentifier(ProcessIdentifier processIdentifier)
{
ASSERT(isUIThread());
globalIdentifier = processIdentifier;
}
ProcessIdentifier identifier()
{
static std::once_flag onceFlag;
std::call_once(onceFlag, [] {
if (!globalIdentifier)
globalIdentifier = ProcessIdentifier::generate();
});
return *globalIdentifier;
}
} // namespace Process
} // namespace WebCore

Some files were not shown because too many files have changed in this diff Show More