-
Notifications
You must be signed in to change notification settings - Fork 2k
Expand file tree
/
Copy pathJSDOMWrapper.h
More file actions
125 lines (101 loc) · 6.15 KB
/
Copy pathJSDOMWrapper.h
File metadata and controls
125 lines (101 loc) · 6.15 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
/*
* Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
* Copyright (C) 2003-2018 Apple Inc. All rights reserved.
* Copyright (C) 2007 Samuel Weinig <sam@webkit.org>
* Copyright (C) 2009 Google, Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#pragma once
#include <JavaScriptCore/JSDestructibleObject.h>
#include <JavaScriptCore/JSEmbedderArrayLike.h>
#include <WebCore/JSDOMGlobalObject.h>
#include <WebCore/NodeType.h>
#include <wtf/SignedPtr.h>
namespace JSC {
class Structure;
}
namespace WebCore {
class ScriptExecutionContext;
// JSC allows us to extend JSType. If the highest 3 bits are set, we can add any Object types and they are
// recognized as OtherObj in JSC. And we encode Node type into JSType if the given JSType is subclass of Node.
// offset | 7 | 6 | 5 | 4 3 2 1 0 |
// value | 1 | 1 | 1 | Non-node DOM types |
// If the given JSType is a subclass of Node, the format is the following.
// offset | 7 | 6 | 5 | 4 | 3 2 1 0 |
// value | 1 | 1 | 1 | 1 | NodeType |
static constexpr uint8_t JSEmbedderArrayLikeType = JSC::EmbedderArrayLikeType;
static constexpr uint8_t JSDOMWrapperType = 0b11101110;
static constexpr uint8_t JSEventType = 0b11101111;
static constexpr uint8_t JSNodeType = 0b11110000;
static constexpr uint8_t JSNodeTypeMask = 0b00001111;
static constexpr uint8_t JSTextNodeType = JSNodeType | std::to_underlying(NodeType::Text);
static constexpr uint8_t JSProcessingInstructionNodeType = JSNodeType | std::to_underlying(NodeType::ProcessingInstruction);
static constexpr uint8_t JSDocumentTypeNodeType = JSNodeType | std::to_underlying(NodeType::DocumentType);
static constexpr uint8_t JSDocumentFragmentNodeType = JSNodeType | std::to_underlying(NodeType::DocumentFragment);
static constexpr uint8_t JSDocumentWrapperType = JSNodeType | std::to_underlying(NodeType::Document);
static constexpr uint8_t JSCommentNodeType = JSNodeType | std::to_underlying(NodeType::Comment);
static constexpr uint8_t JSCDATASectionNodeType = JSNodeType | std::to_underlying(NodeType::CDATASection);
static constexpr uint8_t JSAttrNodeType = JSNodeType | std::to_underlying(NodeType::Attribute);
static constexpr uint8_t JSElementType = 0b11110000 | std::to_underlying(NodeType::Element);
static_assert(JSDOMWrapperType > JSC::LastJSCObjectType, "JSC::JSType offers the highest bit.");
static_assert(JSEmbedderArrayLikeType > JSC::LastJSCObjectType, "EmbedderArrayLikeType must be above LastJSCObjectType.");
static_assert(JSEmbedderArrayLikeType != JSDOMWrapperType && JSC::EmbedderArrayLikeType != JSEventType, "EmbedderArrayLikeType must not collide with other WebCore types.");
static_assert(JSEmbedderArrayLikeType < JSNodeType, "EmbedderArrayLikeType must be below JSNodeType to avoid breaking node range checks.");
static_assert(lastNodeType <= JSNodeTypeMask, "NodeType should be represented in 4bit.");
class JSDOMObject : public JSC::JSDestructibleObject {
public:
typedef JSC::JSDestructibleObject Base;
template<typename, JSC::SubspaceAccess>
static void subspaceFor(JSC::VM&) { RELEASE_ASSERT_NOT_REACHED(); }
JSDOMGlobalObject* realm() const { return uncheckedDowncast<JSDOMGlobalObject>(JSC::JSNonFinalObject::realm()); }
ScriptExecutionContext* scriptExecutionContext() const { return realm()->scriptExecutionContext(); }
protected:
WEBCORE_EXPORT JSDOMObject(JSC::Structure*, JSC::JSGlobalObject&);
WEBCORE_EXPORT void finishCreation(JSC::VM&);
};
template<typename ImplementationClass, typename PtrTraits = RawPtrTraits<ImplementationClass>>
class JSDOMWrapper : public JSDOMObject {
public:
using Base = JSDOMObject;
using DOMWrapped = ImplementationClass;
ImplementationClass& wrapped() const LIFETIME_BOUND { return m_wrapped; }
static constexpr ptrdiff_t offsetOfWrapped() { return OBJECT_OFFSETOF(JSDOMWrapper, m_wrapped); }
constexpr static bool hasCustomPtrTraits() { return !std::is_same_v<PtrTraits, RawPtrTraits<ImplementationClass>>; };
protected:
JSDOMWrapper(JSC::Structure* structure, JSC::JSGlobalObject& globalObject, Ref<ImplementationClass>&& impl)
: Base(structure, globalObject)
, m_wrapped(WTF::move(impl)) { }
private:
const Ref<ImplementationClass, PtrTraits> m_wrapped;
};
template<typename ImplementationClass> struct JSDOMWrapperConverterTraits;
JSC::JSValue cloneAcrossWorlds(JSC::JSGlobalObject&, const JSDOMObject& owner, JSC::JSValue);
template<typename ImplementationClass>
class JSDOMEmbedderArrayLikeWrapper : public JSC::JSEmbedderArrayLike {
public:
using Base = JSC::JSEmbedderArrayLike;
using DOMWrapped = ImplementationClass;
template<typename, JSC::SubspaceAccess>
static void subspaceFor(JSC::VM&) { RELEASE_ASSERT_NOT_REACHED(); }
JSDOMGlobalObject* realm() const { return uncheckedDowncast<JSDOMGlobalObject>(JSC::JSNonFinalObject::realm()); }
ScriptExecutionContext* scriptExecutionContext() const { return realm()->scriptExecutionContext(); }
ImplementationClass& wrapped() const { return static_cast<ImplementationClass&>(embeddedArrayLike()); }
constexpr static bool hasCustomPtrTraits() { return false; };
protected:
JSDOMEmbedderArrayLikeWrapper(JSC::Structure* structure, JSC::JSGlobalObject& globalObject, Ref<ImplementationClass>&& impl)
: Base(globalObject.vm(), structure, WTF::move(impl)) { }
};
} // namespace WebCore