1/*
2 * Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
3 * Copyright (C) 2001 Peter Kelly (pmk@post.com)
4 * Copyright (C) 2003-2019 Apple Inc. All rights reserved.
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public License
17 * along with this library; see the file COPYING.LIB. If not, write to
18 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 * Boston, MA 02110-1301, USA.
20 *
21 */
22
23#pragma once
24
25#include "CallFrame.h"
26#include "ConstructData.h"
27#include "JSCast.h"
28
29#if CPU(ARM64E)
30#include <ptrauth.h>
31#endif
32
33namespace WTF {
34class PrintStream;
35};
36
37namespace JSC {
38
39class HeapSnapshotBuilder;
40class JSArrayBufferView;
41class Snippet;
42struct HashTable;
43
44#if CPU(ARM64E)
45#define WTF_METHOD_TABLE_ENTRY(method) \
46 __ptrauth(ptrauth_key_process_independent_code, true, ptrauth_string_discriminator("MethodTable." #method)) method
47#else
48#define WTF_METHOD_TABLE_ENTRY(method) method
49#endif
50
51struct MethodTable {
52 using DestroyFunctionPtr = void (*)(JSCell*);
53 DestroyFunctionPtr WTF_METHOD_TABLE_ENTRY(destroy);
54
55 using VisitChildrenFunctionPtr = void (*)(JSCell*, SlotVisitor&);
56 VisitChildrenFunctionPtr WTF_METHOD_TABLE_ENTRY(visitChildren);
57
58 using GetCallDataFunctionPtr = CallType (*)(JSCell*, CallData&);
59 GetCallDataFunctionPtr WTF_METHOD_TABLE_ENTRY(getCallData);
60
61 using GetConstructDataFunctionPtr = ConstructType (*)(JSCell*, ConstructData&);
62 GetConstructDataFunctionPtr WTF_METHOD_TABLE_ENTRY(getConstructData);
63
64 using PutFunctionPtr = bool (*)(JSCell*, ExecState*, PropertyName propertyName, JSValue, PutPropertySlot&);
65 PutFunctionPtr WTF_METHOD_TABLE_ENTRY(put);
66
67 using PutByIndexFunctionPtr = bool (*)(JSCell*, ExecState*, unsigned propertyName, JSValue, bool shouldThrow);
68 PutByIndexFunctionPtr WTF_METHOD_TABLE_ENTRY(putByIndex);
69
70 using DeletePropertyFunctionPtr = bool (*)(JSCell*, ExecState*, PropertyName);
71 DeletePropertyFunctionPtr WTF_METHOD_TABLE_ENTRY(deleteProperty);
72
73 using DeletePropertyByIndexFunctionPtr = bool (*)(JSCell*, ExecState*, unsigned);
74 DeletePropertyByIndexFunctionPtr WTF_METHOD_TABLE_ENTRY(deletePropertyByIndex);
75
76 using GetOwnPropertySlotFunctionPtr = bool (*)(JSObject*, ExecState*, PropertyName, PropertySlot&);
77 GetOwnPropertySlotFunctionPtr WTF_METHOD_TABLE_ENTRY(getOwnPropertySlot);
78
79 using GetOwnPropertySlotByIndexFunctionPtr = bool (*)(JSObject*, ExecState*, unsigned, PropertySlot&);
80 GetOwnPropertySlotByIndexFunctionPtr WTF_METHOD_TABLE_ENTRY(getOwnPropertySlotByIndex);
81
82 using ToThisFunctionPtr = JSValue (*)(JSCell*, ExecState*, ECMAMode);
83 ToThisFunctionPtr WTF_METHOD_TABLE_ENTRY(toThis);
84
85 using DefaultValueFunctionPtr = JSValue (*)(const JSObject*, ExecState*, PreferredPrimitiveType);
86 DefaultValueFunctionPtr WTF_METHOD_TABLE_ENTRY(defaultValue);
87
88 using GetOwnPropertyNamesFunctionPtr = void (*)(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
89 GetOwnPropertyNamesFunctionPtr WTF_METHOD_TABLE_ENTRY(getOwnPropertyNames);
90
91 using GetOwnNonIndexPropertyNamesFunctionPtr = void (*)(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
92 GetOwnNonIndexPropertyNamesFunctionPtr WTF_METHOD_TABLE_ENTRY(getOwnNonIndexPropertyNames);
93
94 using GetPropertyNamesFunctionPtr = void (*)(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
95 GetPropertyNamesFunctionPtr WTF_METHOD_TABLE_ENTRY(getPropertyNames);
96
97 using GetEnumerableLengthFunctionPtr = uint32_t (*)(ExecState*, JSObject*);
98 GetEnumerableLengthFunctionPtr WTF_METHOD_TABLE_ENTRY(getEnumerableLength);
99
100 GetPropertyNamesFunctionPtr WTF_METHOD_TABLE_ENTRY(getStructurePropertyNames);
101 GetPropertyNamesFunctionPtr WTF_METHOD_TABLE_ENTRY(getGenericPropertyNames);
102
103 using ClassNameFunctionPtr = String (*)(const JSObject*, VM&);
104 ClassNameFunctionPtr WTF_METHOD_TABLE_ENTRY(className);
105
106 using ToStringNameFunctionPtr = String (*)(const JSObject*, ExecState*);
107 ToStringNameFunctionPtr WTF_METHOD_TABLE_ENTRY(toStringName);
108
109 using CustomHasInstanceFunctionPtr = bool (*)(JSObject*, ExecState*, JSValue);
110 CustomHasInstanceFunctionPtr WTF_METHOD_TABLE_ENTRY(customHasInstance);
111
112 using DefineOwnPropertyFunctionPtr = bool (*)(JSObject*, ExecState*, PropertyName, const PropertyDescriptor&, bool);
113 DefineOwnPropertyFunctionPtr WTF_METHOD_TABLE_ENTRY(defineOwnProperty);
114
115 using PreventExtensionsFunctionPtr = bool (*)(JSObject*, ExecState*);
116 PreventExtensionsFunctionPtr WTF_METHOD_TABLE_ENTRY(preventExtensions);
117
118 using IsExtensibleFunctionPtr = bool (*)(JSObject*, ExecState*);
119 IsExtensibleFunctionPtr WTF_METHOD_TABLE_ENTRY(isExtensible);
120
121 using SetPrototypeFunctionPtr = bool (*)(JSObject*, ExecState*, JSValue, bool shouldThrowIfCantSet);
122 SetPrototypeFunctionPtr WTF_METHOD_TABLE_ENTRY(setPrototype);
123
124 using GetPrototypeFunctionPtr = JSValue (*)(JSObject*, ExecState*);
125 GetPrototypeFunctionPtr WTF_METHOD_TABLE_ENTRY(getPrototype);
126
127 using DumpToStreamFunctionPtr = void (*)(const JSCell*, PrintStream&);
128 DumpToStreamFunctionPtr WTF_METHOD_TABLE_ENTRY(dumpToStream);
129
130 using HeapSnapshotFunctionPtr = void (*)(JSCell*, HeapSnapshotBuilder&);
131 HeapSnapshotFunctionPtr WTF_METHOD_TABLE_ENTRY(heapSnapshot);
132
133 using EstimatedSizeFunctionPtr = size_t (*)(JSCell*, VM&);
134 EstimatedSizeFunctionPtr WTF_METHOD_TABLE_ENTRY(estimatedSize);
135
136 using VisitOutputConstraintsPtr = void (*)(JSCell*, SlotVisitor&);
137 VisitOutputConstraintsPtr WTF_METHOD_TABLE_ENTRY(visitOutputConstraints);
138};
139
140#define CREATE_MEMBER_CHECKER(member) \
141 template <typename T> \
142 struct MemberCheck##member { \
143 struct Fallback { \
144 void member(...); \
145 }; \
146 struct Derived : T, Fallback { }; \
147 template <typename U, U> struct Check; \
148 typedef char Yes[2]; \
149 typedef char No[1]; \
150 template <typename U> \
151 static No &func(Check<void (Fallback::*)(...), &U::member>*); \
152 template <typename U> \
153 static Yes &func(...); \
154 enum { has = sizeof(func<Derived>(0)) == sizeof(Yes) }; \
155 }
156
157#define HAS_MEMBER_NAMED(klass, name) (MemberCheck##name<klass>::has)
158
159#define CREATE_METHOD_TABLE(ClassName) { \
160 &ClassName::destroy, \
161 &ClassName::visitChildren, \
162 &ClassName::getCallData, \
163 &ClassName::getConstructData, \
164 &ClassName::put, \
165 &ClassName::putByIndex, \
166 &ClassName::deleteProperty, \
167 &ClassName::deletePropertyByIndex, \
168 &ClassName::getOwnPropertySlot, \
169 &ClassName::getOwnPropertySlotByIndex, \
170 &ClassName::toThis, \
171 &ClassName::defaultValue, \
172 &ClassName::getOwnPropertyNames, \
173 &ClassName::getOwnNonIndexPropertyNames, \
174 &ClassName::getPropertyNames, \
175 &ClassName::getEnumerableLength, \
176 &ClassName::getStructurePropertyNames, \
177 &ClassName::getGenericPropertyNames, \
178 &ClassName::className, \
179 &ClassName::toStringName, \
180 &ClassName::customHasInstance, \
181 &ClassName::defineOwnProperty, \
182 &ClassName::preventExtensions, \
183 &ClassName::isExtensible, \
184 &ClassName::setPrototype, \
185 &ClassName::getPrototype, \
186 &ClassName::dumpToStream, \
187 &ClassName::heapSnapshot, \
188 &ClassName::estimatedSize, \
189 &ClassName::visitOutputConstraints, \
190 }, \
191 ClassName::TypedArrayStorageType
192
193struct ClassInfo {
194 // A string denoting the class name. Example: "Window".
195 const char* className;
196
197 // Pointer to the class information of the base class.
198 // nullptrif there is none.
199 const ClassInfo* parentClass;
200
201 static ptrdiff_t offsetOfParentClass()
202 {
203 return OBJECT_OFFSETOF(ClassInfo, parentClass);
204 }
205
206 bool isSubClassOf(const ClassInfo* other) const
207 {
208 for (const ClassInfo* ci = this; ci; ci = ci->parentClass) {
209 if (ci == other)
210 return true;
211 }
212 return false;
213 }
214
215 JS_EXPORT_PRIVATE void dump(PrintStream&) const;
216
217 JS_EXPORT_PRIVATE bool hasStaticSetterOrReadonlyProperties() const;
218
219 const HashTable* staticPropHashTable;
220
221 using CheckSubClassSnippetFunctionPtr = Ref<Snippet> (*)(void);
222 CheckSubClassSnippetFunctionPtr checkSubClassSnippet;
223
224 MethodTable methodTable;
225
226 TypedArrayType typedArrayStorageType;
227};
228
229} // namespace JSC
230