summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKonstantin Tokarev <annulen@yandex.ru>2020-02-26 04:40:09 +0300
committerKonstantin Tokarev <annulen@yandex.ru>2020-02-26 04:41:40 +0300
commit8d9e85b5baf784727ecefaecda68716e03ec884e (patch)
tree37785846b69c9f0b8361175c413e07dc3f542a2f
parentcd875b317ba9ef63f946d2a07b7e67c1e05f93ac (diff)
Import QtWebKit commit bf94215feb57ddf9ce364bc6953eec8cd1387c3d
Change-Id: Ifc9d2e79e39fbfdd21bd40ede609c7696d2efe62 Reviewed-by: Konstantin Tokarev <annulen@yandex.ru>
-rw-r--r--Source/JavaScriptCore/heap/WeakInlines.h11
-rw-r--r--Source/WebCore/bindings/js/JSCustomEventCustom.cpp13
-rw-r--r--Source/WebCore/bindings/js/JSValueInWrappedObject.h137
-rw-r--r--Source/WebCore/dom/CustomEvent.cpp4
-rw-r--r--Source/WebCore/dom/CustomEvent.h7
-rw-r--r--Source/WebCore/dom/CustomEvent.idl1
6 files changed, 160 insertions, 13 deletions
diff --git a/Source/JavaScriptCore/heap/WeakInlines.h b/Source/JavaScriptCore/heap/WeakInlines.h
index 4653a9f8c..d5bd2ea2f 100644
--- a/Source/JavaScriptCore/heap/WeakInlines.h
+++ b/Source/JavaScriptCore/heap/WeakInlines.h
@@ -73,20 +73,23 @@ template<typename T> inline auto Weak<T>::operator=(Weak&& other) -> Weak&
template<typename T> inline T* Weak<T>::operator->() const
{
ASSERT(m_impl && m_impl->state() == WeakImpl::Live);
- return jsCast<T*>(m_impl->jsValue().asCell());
+ // We can't use jsCast here since we could be called in a finalizer.
+ return static_cast<T*>(m_impl->jsValue().asCell());
}
template<typename T> inline T& Weak<T>::operator*() const
{
ASSERT(m_impl && m_impl->state() == WeakImpl::Live);
- return *jsCast<T*>(m_impl->jsValue().asCell());
+ // We can't use jsCast here since we could be called in a finalizer.
+ return *static_cast<T*>(m_impl->jsValue().asCell());
}
template<typename T> inline T* Weak<T>::get() const
{
if (!m_impl || m_impl->state() != WeakImpl::Live)
- return 0;
- return jsCast<T*>(m_impl->jsValue().asCell());
+ return nullptr;
+ // We can't use jsCast here since we could be called in a finalizer.
+ return static_cast<T*>(m_impl->jsValue().asCell());
}
template<typename T> inline bool Weak<T>::was(T* other) const
diff --git a/Source/WebCore/bindings/js/JSCustomEventCustom.cpp b/Source/WebCore/bindings/js/JSCustomEventCustom.cpp
index c556c9e2e..a2d26b5af 100644
--- a/Source/WebCore/bindings/js/JSCustomEventCustom.cpp
+++ b/Source/WebCore/bindings/js/JSCustomEventCustom.cpp
@@ -38,13 +38,13 @@ namespace WebCore {
JSValue JSCustomEvent::detail(ExecState& state) const
{
- CustomEvent& event = wrapped();
+ auto& event = wrapped();
+
+ JSValue detail = event.detail();
- if (event.detail().hasNoValue())
+ if (!detail)
return jsNull();
- JSValue detail = event.detail().jsValue();
-
if (detail.isObject() && &worldForDOMObject(detail.getObject()) != &currentWorld(&state)) {
// We need to make sure CustomEvents do not leak their detail property across isolated DOM worlds.
// Ideally, we would check that the worlds have different privileges but that's not possible yet.
@@ -59,5 +59,10 @@ JSValue JSCustomEvent::detail(ExecState& state) const
return detail;
}
+void JSCustomEvent::visitAdditionalChildren(JSC::SlotVisitor& visitor)
+{
+ wrapped().detail().visit(visitor);
+}
+
} // namespace WebCore
diff --git a/Source/WebCore/bindings/js/JSValueInWrappedObject.h b/Source/WebCore/bindings/js/JSValueInWrappedObject.h
new file mode 100644
index 000000000..f1ee30b7e
--- /dev/null
+++ b/Source/WebCore/bindings/js/JSValueInWrappedObject.h
@@ -0,0 +1,137 @@
+/*
+ * 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 "DOMWrapperWorld.h"
+#include "JSDOMWrapper.h"
+#include <JavaScriptCore/JSCJSValue.h>
+#include <JavaScriptCore/SlotVisitor.h>
+#include <JavaScriptCore/Weak.h>
+
+namespace WebCore {
+
+class JSValueInWrappedObject {
+public:
+ JSValueInWrappedObject(JSC::JSValue = { });
+ JSValueInWrappedObject(const JSValueInWrappedObject&);
+ operator JSC::JSValue() const;
+ explicit operator bool() const;
+ JSValueInWrappedObject& operator=(const JSValueInWrappedObject& other);
+ void visit(JSC::SlotVisitor&);
+ void clear();
+
+private:
+ // Use a weak pointer here so that if this code or client code has a visiting mistake,
+ // we get null rather than a dangling pointer to a deleted object.
+ using Weak = JSC::Weak<JSC::JSCell>;
+
+ JSC::JSValue m_jsValue;
+ Weak m_weakValue;
+ bool m_isWeak;
+};
+
+inline JSValueInWrappedObject::JSValueInWrappedObject(JSC::JSValue value)
+{
+ if (!value.isCell()) {
+ m_jsValue = value;
+ m_isWeak = false;
+ } else {
+ // FIXME: This is not quite right. It is possible that this value is being
+ // stored in a wrapped object that does not yet have a wrapper. If garbage
+ // collection occurs before the wrapped object gets a wrapper, it's possible
+ // the value object could be collected, and this will become null. A future
+ // version of this class should prevent the value from being collected in
+ // that case. Unclear if this can actually happen in practice.
+ m_weakValue = Weak { value.asCell() };
+ m_isWeak = true;
+ }
+}
+
+inline JSValueInWrappedObject::JSValueInWrappedObject(const JSValueInWrappedObject& other)
+{
+ JSC::JSValue value = other;
+ if (!value.isCell()) {
+ m_jsValue = value;
+ m_isWeak = false;
+ } else {
+ // FIXME: This is not quite right. It is possible that this value is being
+ // stored in a wrapped object that does not yet have a wrapper. If garbage
+ // collection occurs before the wrapped object gets a wrapper, it's possible
+ // the value object could be collected, and this will become null. A future
+ // version of this class should prevent the value from being collected in
+ // that case. Unclear if this can actually happen in practice.
+ m_weakValue = Weak { value.asCell() };
+ m_isWeak = true;
+ }
+}
+
+inline JSValueInWrappedObject::operator JSC::JSValue() const
+{
+ if (!m_isWeak)
+ return m_jsValue;
+
+ return m_weakValue.get();
+}
+
+inline JSValueInWrappedObject::operator bool() const
+{
+ return JSC::JSValue { *this }.operator bool();
+}
+
+inline JSValueInWrappedObject& JSValueInWrappedObject::operator=(const JSValueInWrappedObject& other)
+{
+ JSC::JSValue value = other;
+ if (!value.isCell()) {
+ m_jsValue = value;
+ m_isWeak = false;
+ } else {
+ // FIXME: This is not quite right. It is possible that this value is being
+ // stored in a wrapped object that does not yet have a wrapper. If garbage
+ // collection occurs before the wrapped object gets a wrapper, it's possible
+ // the value object could be collected, and this will become null. A future
+ // version of this class should prevent the value from being collected in
+ // that case. Unclear if this can actually happen in practice.
+ m_weakValue = Weak { value.asCell() };
+ m_isWeak = true;
+ }
+ return *this;
+}
+
+inline void JSValueInWrappedObject::visit(JSC::SlotVisitor& visitor)
+{
+ if (!m_isWeak) {
+ // Nothing to visit.
+ } else {
+ visitor.appendUnbarrieredWeak(&m_weakValue);
+ };
+}
+
+inline void JSValueInWrappedObject::clear()
+{
+ if (m_isWeak)
+ m_weakValue.clear();
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/dom/CustomEvent.cpp b/Source/WebCore/dom/CustomEvent.cpp
index 495b5ab4b..fa1bc745d 100644
--- a/Source/WebCore/dom/CustomEvent.cpp
+++ b/Source/WebCore/dom/CustomEvent.cpp
@@ -45,7 +45,7 @@ CustomEvent::~CustomEvent()
{
}
-void CustomEvent::initCustomEvent(const AtomicString& type, bool canBubble, bool cancelable, const Deprecated::ScriptValue& detail)
+void CustomEvent::initCustomEvent(const AtomicString& type, bool canBubble, bool cancelable, JSC::JSValue detail)
{
if (dispatched())
return;
@@ -60,7 +60,7 @@ void CustomEvent::initCustomEvent(const AtomicString& type, bool canBubble, bool
RefPtr<SerializedScriptValue> CustomEvent::trySerializeDetail(JSC::ExecState* exec)
{
if (!m_serializedDetail && !m_triedToSerialize) {
- m_serializedDetail = SerializedScriptValue::create(exec, m_detail.jsValue(), nullptr, nullptr, NonThrowing);
+ m_serializedDetail = SerializedScriptValue::create(exec, m_detail, nullptr, nullptr, NonThrowing);
m_triedToSerialize = true;
}
diff --git a/Source/WebCore/dom/CustomEvent.h b/Source/WebCore/dom/CustomEvent.h
index 2cb5c164d..ac369d951 100644
--- a/Source/WebCore/dom/CustomEvent.h
+++ b/Source/WebCore/dom/CustomEvent.h
@@ -27,6 +27,7 @@
#define CustomEvent_h
#include "Event.h"
+#include "JSValueInWrappedObject.h"
#include "SerializedScriptValue.h"
#include <bindings/ScriptValue.h>
@@ -50,11 +51,11 @@ public:
return adoptRef(*new CustomEvent(type, initializer));
}
- void initCustomEvent(const AtomicString& type, bool canBubble, bool cancelable, const Deprecated::ScriptValue& detail);
+ void initCustomEvent(const AtomicString& type, bool canBubble, bool cancelable, JSC::JSValue detail);
virtual EventInterface eventInterface() const override;
- const Deprecated::ScriptValue& detail() const { return m_detail; }
+ JSValueInWrappedObject& detail() { return m_detail; }
RefPtr<SerializedScriptValue> trySerializeDetail(JSC::ExecState*);
@@ -62,7 +63,7 @@ private:
CustomEvent();
CustomEvent(const AtomicString& type, const CustomEventInit& initializer);
- Deprecated::ScriptValue m_detail;
+ JSValueInWrappedObject m_detail;
RefPtr<SerializedScriptValue> m_serializedDetail;
bool m_triedToSerialize { false };
};
diff --git a/Source/WebCore/dom/CustomEvent.idl b/Source/WebCore/dom/CustomEvent.idl
index 12e0ec37b..899ad1a97 100644
--- a/Source/WebCore/dom/CustomEvent.idl
+++ b/Source/WebCore/dom/CustomEvent.idl
@@ -26,6 +26,7 @@
// Introduced in DOM Level 3:
[
ConstructorTemplate=Event,
+ JSCustomMarkFunction,
] interface CustomEvent : Event {
[InitializedByEventConstructor, CustomGetter] readonly attribute any detail;