mirror of
https://github.com/oven-sh/bun
synced 2026-02-03 15:38:46 +00:00
Compare commits
1 Commits
build-scri
...
jarred/wor
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c5d637fbb1 |
@@ -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()) == ¤tWorld(lexicalGlobalObject);
|
||||
return !value.isObject() || &worldForDOMObject(*value.getObject()) == ¤tWorld(lexicalGlobalObject);
|
||||
}
|
||||
|
||||
inline DOMWrapperWorld& currentWorld(JSC::JSGlobalObject& lexicalGlobalObject)
|
||||
|
||||
44
src/javascript/jsc/bindings/FetchOptions.h
Normal file
44
src/javascript/jsc/bindings/FetchOptions.h
Normal 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 };
|
||||
};
|
||||
}
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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&);
|
||||
|
||||
@@ -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 };
|
||||
};
|
||||
}
|
||||
@@ -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())
|
||||
|
||||
@@ -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> {
|
||||
|
||||
0
src/javascript/jsc/bindings/not-implemented.h
Normal file
0
src/javascript/jsc/bindings/not-implemented.h
Normal 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
|
||||
77
src/javascript/jsc/bindings/webcore/AbstractWorker.cpp
Normal file
77
src/javascript/jsc/bindings/webcore/AbstractWorker.cpp
Normal 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
|
||||
63
src/javascript/jsc/bindings/webcore/AbstractWorker.h
Normal file
63
src/javascript/jsc/bindings/webcore/AbstractWorker.h
Normal 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
|
||||
36
src/javascript/jsc/bindings/webcore/AbstractWorker.idl
Normal file
36
src/javascript/jsc/bindings/webcore/AbstractWorker.idl
Normal 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;
|
||||
};
|
||||
|
||||
63
src/javascript/jsc/bindings/webcore/ActiveDOMCallback.cpp
Normal file
63
src/javascript/jsc/bindings/webcore/ActiveDOMCallback.cpp
Normal 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
|
||||
64
src/javascript/jsc/bindings/webcore/ActiveDOMCallback.h
Normal file
64
src/javascript/jsc/bindings/webcore/ActiveDOMCallback.h
Normal 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
|
||||
196
src/javascript/jsc/bindings/webcore/ActiveDOMObject.cpp
Normal file
196
src/javascript/jsc/bindings/webcore/ActiveDOMObject.cpp
Normal 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
|
||||
@@ -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
|
||||
|
||||
0
src/javascript/jsc/bindings/webcore/Blob.h
Normal file
0
src/javascript/jsc/bindings/webcore/Blob.h
Normal 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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
350
src/javascript/jsc/bindings/webcore/DOMPromiseProxy.h
Normal file
350
src/javascript/jsc/bindings/webcore/DOMPromiseProxy.h
Normal 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);
|
||||
}
|
||||
|
||||
}
|
||||
1
src/javascript/jsc/bindings/webcore/DOMWindow.h
Normal file
1
src/javascript/jsc/bindings/webcore/DOMWindow.h
Normal file
@@ -0,0 +1 @@
|
||||
// stub
|
||||
@@ -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
|
||||
110
src/javascript/jsc/bindings/webcore/DedicatedWorkerGlobalScope.h
Normal file
110
src/javascript/jsc/bindings/webcore/DedicatedWorkerGlobalScope.h
Normal 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()
|
||||
@@ -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;
|
||||
@@ -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
|
||||
65
src/javascript/jsc/bindings/webcore/DedicatedWorkerThread.h
Normal file
65
src/javascript/jsc/bindings/webcore/DedicatedWorkerThread.h
Normal 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
|
||||
191
src/javascript/jsc/bindings/webcore/EventLoop.cpp
Normal file
191
src/javascript/jsc/bindings/webcore/EventLoop.cpp
Normal 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
|
||||
206
src/javascript/jsc/bindings/webcore/EventLoop.h
Normal file
206
src/javascript/jsc/bindings/webcore/EventLoop.h
Normal 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
|
||||
@@ -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) \
|
||||
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
|
||||
@@ -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" };
|
||||
78
src/javascript/jsc/bindings/webcore/JSDOMGuardedObject.cpp
Normal file
78
src/javascript/jsc/bindings/webcore/JSDOMGuardedObject.cpp
Normal 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();
|
||||
}
|
||||
|
||||
}
|
||||
69
src/javascript/jsc/bindings/webcore/JSDOMGuardedObject.h
Normal file
69
src/javascript/jsc/bindings/webcore/JSDOMGuardedObject.h
Normal 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
|
||||
97
src/javascript/jsc/bindings/webcore/JSDOMPromise.cpp
Normal file
97
src/javascript/jsc/bindings/webcore/JSDOMPromise.cpp
Normal 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;
|
||||
}
|
||||
|
||||
}
|
||||
63
src/javascript/jsc/bindings/webcore/JSDOMPromise.h
Normal file
63
src/javascript/jsc/bindings/webcore/JSDOMPromise.h
Normal 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
|
||||
300
src/javascript/jsc/bindings/webcore/JSDOMPromiseDeferred.cpp
Normal file
300
src/javascript/jsc/bindings/webcore/JSDOMPromiseDeferred.cpp
Normal 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
|
||||
371
src/javascript/jsc/bindings/webcore/JSDOMPromiseDeferred.h
Normal file
371
src/javascript/jsc/bindings/webcore/JSDOMPromiseDeferred.h
Normal 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
|
||||
1
src/javascript/jsc/bindings/webcore/JSDOMWindow.h
Normal file
1
src/javascript/jsc/bindings/webcore/JSDOMWindow.h
Normal file
@@ -0,0 +1 @@
|
||||
// stub
|
||||
@@ -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
|
||||
@@ -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
|
||||
0
src/javascript/jsc/bindings/webcore/JSGPU.h
Normal file
0
src/javascript/jsc/bindings/webcore/JSGPU.h
Normal file
326
src/javascript/jsc/bindings/webcore/JSMessageChannel.cpp
Normal file
326
src/javascript/jsc/bindings/webcore/JSMessageChannel.cpp
Normal 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)
|
||||
1
src/javascript/jsc/bindings/webcore/JSMessageChannel.dep
Normal file
1
src/javascript/jsc/bindings/webcore/JSMessageChannel.dep
Normal file
@@ -0,0 +1 @@
|
||||
JSMessageChannel.h :
|
||||
101
src/javascript/jsc/bindings/webcore/JSMessageChannel.h
Normal file
101
src/javascript/jsc/bindings/webcore/JSMessageChannel.h
Normal 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)
|
||||
515
src/javascript/jsc/bindings/webcore/JSMessageEvent.cpp
Normal file
515
src/javascript/jsc/bindings/webcore/JSMessageEvent.cpp
Normal 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);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
3
src/javascript/jsc/bindings/webcore/JSMessageEvent.dep
Normal file
3
src/javascript/jsc/bindings/webcore/JSMessageEvent.dep
Normal file
@@ -0,0 +1,3 @@
|
||||
JSMessageEvent.h : Event.idl EventInit.idl
|
||||
Event.idl :
|
||||
EventInit.idl :
|
||||
91
src/javascript/jsc/bindings/webcore/JSMessageEvent.h
Normal file
91
src/javascript/jsc/bindings/webcore/JSMessageEvent.h
Normal 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
|
||||
415
src/javascript/jsc/bindings/webcore/JSMessagePort.cpp
Normal file
415
src/javascript/jsc/bindings/webcore/JSMessagePort.cpp
Normal 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;
|
||||
}
|
||||
|
||||
}
|
||||
2
src/javascript/jsc/bindings/webcore/JSMessagePort.dep
Normal file
2
src/javascript/jsc/bindings/webcore/JSMessagePort.dep
Normal file
@@ -0,0 +1,2 @@
|
||||
JSMessagePort.h : EventTarget.idl
|
||||
EventTarget.idl :
|
||||
102
src/javascript/jsc/bindings/webcore/JSMessagePort.h
Normal file
102
src/javascript/jsc/bindings/webcore/JSMessagePort.h
Normal 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
|
||||
377
src/javascript/jsc/bindings/webcore/JSPromiseRejectionEvent.cpp
Normal file
377
src/javascript/jsc/bindings/webcore/JSPromiseRejectionEvent.cpp
Normal 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);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
JSPromiseRejectionEvent.h : Event.idl EventInit.idl
|
||||
Event.idl :
|
||||
EventInit.idl :
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -0,0 +1 @@
|
||||
StructuredSerializeOptions.h :
|
||||
@@ -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
|
||||
0
src/javascript/jsc/bindings/webcore/JSWindowProxy.h
Normal file
0
src/javascript/jsc/bindings/webcore/JSWindowProxy.h
Normal file
402
src/javascript/jsc/bindings/webcore/JSWorkerLocation.cpp
Normal file
402
src/javascript/jsc/bindings/webcore/JSWorkerLocation.cpp
Normal 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;
|
||||
}
|
||||
|
||||
}
|
||||
1
src/javascript/jsc/bindings/webcore/JSWorkerLocation.dep
Normal file
1
src/javascript/jsc/bindings/webcore/JSWorkerLocation.dep
Normal file
@@ -0,0 +1 @@
|
||||
JSWorkerLocation.h :
|
||||
93
src/javascript/jsc/bindings/webcore/JSWorkerLocation.h
Normal file
93
src/javascript/jsc/bindings/webcore/JSWorkerLocation.h
Normal 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
|
||||
@@ -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.
|
||||
*/
|
||||
@@ -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.
|
||||
*/
|
||||
569
src/javascript/jsc/bindings/webcore/JSWorkerNavigator.cpp
Normal file
569
src/javascript/jsc/bindings/webcore/JSWorkerNavigator.cpp
Normal 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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
JSWorkerNavigator.h :
|
||||
97
src/javascript/jsc/bindings/webcore/JSWorkerNavigator.h
Normal file
97
src/javascript/jsc/bindings/webcore/JSWorkerNavigator.h
Normal 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
|
||||
84
src/javascript/jsc/bindings/webcore/JSWorkerOptions.cpp
Normal file
84
src/javascript/jsc/bindings/webcore/JSWorkerOptions.cpp
Normal 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
|
||||
1
src/javascript/jsc/bindings/webcore/JSWorkerOptions.dep
Normal file
1
src/javascript/jsc/bindings/webcore/JSWorkerOptions.dep
Normal file
@@ -0,0 +1 @@
|
||||
WorkerOptions.h :
|
||||
30
src/javascript/jsc/bindings/webcore/JSWorkerOptions.h
Normal file
30
src/javascript/jsc/bindings/webcore/JSWorkerOptions.h
Normal 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
|
||||
64
src/javascript/jsc/bindings/webcore/JSWorkerType.cpp
Normal file
64
src/javascript/jsc/bindings/webcore/JSWorkerType.cpp
Normal 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
|
||||
34
src/javascript/jsc/bindings/webcore/JSWorkerType.h
Normal file
34
src/javascript/jsc/bindings/webcore/JSWorkerType.h
Normal 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
|
||||
64
src/javascript/jsc/bindings/webcore/MessageChannel.cpp
Normal file
64
src/javascript/jsc/bindings/webcore/MessageChannel.cpp
Normal 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
|
||||
51
src/javascript/jsc/bindings/webcore/MessageChannel.h
Normal file
51
src/javascript/jsc/bindings/webcore/MessageChannel.h
Normal 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
|
||||
38
src/javascript/jsc/bindings/webcore/MessageChannel.idl
Normal file
38
src/javascript/jsc/bindings/webcore/MessageChannel.idl
Normal 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;
|
||||
|
||||
};
|
||||
|
||||
130
src/javascript/jsc/bindings/webcore/MessageEvent.cpp
Normal file
130
src/javascript/jsc/bindings/webcore/MessageEvent.cpp
Normal 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
|
||||
106
src/javascript/jsc/bindings/webcore/MessageEvent.h
Normal file
106
src/javascript/jsc/bindings/webcore/MessageEvent.h
Normal 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
|
||||
59
src/javascript/jsc/bindings/webcore/MessageEvent.idl
Normal file
59
src/javascript/jsc/bindings/webcore/MessageEvent.idl
Normal 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 = [];
|
||||
};
|
||||
440
src/javascript/jsc/bindings/webcore/MessagePort.cpp
Normal file
440
src/javascript/jsc/bindings/webcore/MessagePort.cpp
Normal 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
|
||||
135
src/javascript/jsc/bindings/webcore/MessagePort.h
Normal file
135
src/javascript/jsc/bindings/webcore/MessagePort.h
Normal 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
|
||||
40
src/javascript/jsc/bindings/webcore/MessagePort.idl
Normal file
40
src/javascript/jsc/bindings/webcore/MessagePort.idl
Normal 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;
|
||||
};
|
||||
233
src/javascript/jsc/bindings/webcore/MessagePortChannel.cpp
Normal file
233
src/javascript/jsc/bindings/webcore/MessagePortChannel.cpp
Normal 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
|
||||
82
src/javascript/jsc/bindings/webcore/MessagePortChannel.h
Normal file
82
src/javascript/jsc/bindings/webcore/MessagePortChannel.h
Normal 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
|
||||
@@ -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
|
||||
@@ -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
|
||||
>;
|
||||
};
|
||||
|
||||
}
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
108
src/javascript/jsc/bindings/webcore/MessagePortIdentifier.h
Normal file
108
src/javascript/jsc/bindings/webcore/MessagePortIdentifier.h
Normal 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
|
||||
@@ -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
|
||||
91
src/javascript/jsc/bindings/webcore/Microtasks.cpp
Normal file
91
src/javascript/jsc/bindings/webcore/Microtasks.cpp
Normal 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
|
||||
57
src/javascript/jsc/bindings/webcore/Microtasks.h
Normal file
57
src/javascript/jsc/bindings/webcore/Microtasks.h
Normal 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
|
||||
199
src/javascript/jsc/bindings/webcore/NavigatorBase.cpp
Normal file
199
src/javascript/jsc/bindings/webcore/NavigatorBase.cpp
Normal 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
|
||||
86
src/javascript/jsc/bindings/webcore/NavigatorBase.h
Normal file
86
src/javascript/jsc/bindings/webcore/NavigatorBase.h
Normal 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
|
||||
54
src/javascript/jsc/bindings/webcore/ProcessIdentifier.cpp
Normal file
54
src/javascript/jsc/bindings/webcore/ProcessIdentifier.cpp
Normal 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
Reference in New Issue
Block a user