1 | /* |
2 | * Copyright (C) 1999-2001 Harri Porten ([email protected]) |
3 | * Copyright (C) 2001 Peter Kelly ([email protected]) |
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 | |
33 | namespace WTF { |
34 | class PrintStream; |
35 | }; |
36 | |
37 | namespace JSC { |
38 | |
39 | class HeapSnapshotBuilder; |
40 | class JSArrayBufferView; |
41 | class Snippet; |
42 | struct 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 | |
51 | struct 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 | |
193 | struct 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 | |