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 "ConstructData.h" |
26 | #include "JSCast.h" |
27 | #include <wtf/PtrTag.h> |
28 | |
29 | namespace WTF { |
30 | class PrintStream; |
31 | }; |
32 | |
33 | namespace JSC { |
34 | |
35 | class HeapAnalyzer; |
36 | class JSArrayBufferView; |
37 | class Snippet; |
38 | struct HashTable; |
39 | |
40 | #define METHOD_TABLE_ENTRY(method) \ |
41 | WTF_VTBL_FUNCPTR_PTRAUTH_STR("MethodTable." #method) method |
42 | |
43 | struct MethodTable { |
44 | using DestroyFunctionPtr = void (*)(JSCell*); |
45 | DestroyFunctionPtr METHOD_TABLE_ENTRY(destroy); |
46 | |
47 | using VisitChildrenFunctionPtr = void (*)(JSCell*, SlotVisitor&); |
48 | VisitChildrenFunctionPtr METHOD_TABLE_ENTRY(visitChildren); |
49 | |
50 | using GetCallDataFunctionPtr = CallType (*)(JSCell*, CallData&); |
51 | GetCallDataFunctionPtr METHOD_TABLE_ENTRY(getCallData); |
52 | |
53 | using GetConstructDataFunctionPtr = ConstructType (*)(JSCell*, ConstructData&); |
54 | GetConstructDataFunctionPtr METHOD_TABLE_ENTRY(getConstructData); |
55 | |
56 | using PutFunctionPtr = bool (*)(JSCell*, JSGlobalObject*, PropertyName propertyName, JSValue, PutPropertySlot&); |
57 | PutFunctionPtr METHOD_TABLE_ENTRY(put); |
58 | |
59 | using PutByIndexFunctionPtr = bool (*)(JSCell*, JSGlobalObject*, unsigned propertyName, JSValue, bool shouldThrow); |
60 | PutByIndexFunctionPtr METHOD_TABLE_ENTRY(putByIndex); |
61 | |
62 | using DeletePropertyFunctionPtr = bool (*)(JSCell*, JSGlobalObject*, PropertyName); |
63 | DeletePropertyFunctionPtr METHOD_TABLE_ENTRY(deleteProperty); |
64 | |
65 | using DeletePropertyByIndexFunctionPtr = bool (*)(JSCell*, JSGlobalObject*, unsigned); |
66 | DeletePropertyByIndexFunctionPtr METHOD_TABLE_ENTRY(deletePropertyByIndex); |
67 | |
68 | using GetOwnPropertySlotFunctionPtr = bool (*)(JSObject*, JSGlobalObject*, PropertyName, PropertySlot&); |
69 | GetOwnPropertySlotFunctionPtr METHOD_TABLE_ENTRY(getOwnPropertySlot); |
70 | |
71 | using GetOwnPropertySlotByIndexFunctionPtr = bool (*)(JSObject*, JSGlobalObject*, unsigned, PropertySlot&); |
72 | GetOwnPropertySlotByIndexFunctionPtr METHOD_TABLE_ENTRY(getOwnPropertySlotByIndex); |
73 | |
74 | using DoPutPropertySecurityCheckFunctionPtr = void (*)(JSObject*, JSGlobalObject*, PropertyName, PutPropertySlot&); |
75 | DoPutPropertySecurityCheckFunctionPtr METHOD_TABLE_ENTRY(doPutPropertySecurityCheck); |
76 | |
77 | using ToThisFunctionPtr = JSValue (*)(JSCell*, JSGlobalObject*, ECMAMode); |
78 | ToThisFunctionPtr METHOD_TABLE_ENTRY(toThis); |
79 | |
80 | using DefaultValueFunctionPtr = JSValue (*)(const JSObject*, JSGlobalObject*, PreferredPrimitiveType); |
81 | DefaultValueFunctionPtr METHOD_TABLE_ENTRY(defaultValue); |
82 | |
83 | using GetOwnPropertyNamesFunctionPtr = void (*)(JSObject*, JSGlobalObject*, PropertyNameArray&, EnumerationMode); |
84 | GetOwnPropertyNamesFunctionPtr METHOD_TABLE_ENTRY(getOwnPropertyNames); |
85 | |
86 | using GetOwnNonIndexPropertyNamesFunctionPtr = void (*)(JSObject*, JSGlobalObject*, PropertyNameArray&, EnumerationMode); |
87 | GetOwnNonIndexPropertyNamesFunctionPtr METHOD_TABLE_ENTRY(getOwnNonIndexPropertyNames); |
88 | |
89 | using GetPropertyNamesFunctionPtr = void (*)(JSObject*, JSGlobalObject*, PropertyNameArray&, EnumerationMode); |
90 | GetPropertyNamesFunctionPtr METHOD_TABLE_ENTRY(getPropertyNames); |
91 | |
92 | using GetEnumerableLengthFunctionPtr = uint32_t (*)(JSGlobalObject*, JSObject*); |
93 | GetEnumerableLengthFunctionPtr METHOD_TABLE_ENTRY(getEnumerableLength); |
94 | |
95 | GetPropertyNamesFunctionPtr METHOD_TABLE_ENTRY(getStructurePropertyNames); |
96 | GetPropertyNamesFunctionPtr METHOD_TABLE_ENTRY(getGenericPropertyNames); |
97 | |
98 | using ClassNameFunctionPtr = String (*)(const JSObject*, VM&); |
99 | ClassNameFunctionPtr METHOD_TABLE_ENTRY(className); |
100 | |
101 | using ToStringNameFunctionPtr = String (*)(const JSObject*, JSGlobalObject*); |
102 | ToStringNameFunctionPtr METHOD_TABLE_ENTRY(toStringName); |
103 | |
104 | using CustomHasInstanceFunctionPtr = bool (*)(JSObject*, JSGlobalObject*, JSValue); |
105 | CustomHasInstanceFunctionPtr METHOD_TABLE_ENTRY(customHasInstance); |
106 | |
107 | using DefineOwnPropertyFunctionPtr = bool (*)(JSObject*, JSGlobalObject*, PropertyName, const PropertyDescriptor&, bool); |
108 | DefineOwnPropertyFunctionPtr METHOD_TABLE_ENTRY(defineOwnProperty); |
109 | |
110 | using PreventExtensionsFunctionPtr = bool (*)(JSObject*, JSGlobalObject*); |
111 | PreventExtensionsFunctionPtr METHOD_TABLE_ENTRY(preventExtensions); |
112 | |
113 | using IsExtensibleFunctionPtr = bool (*)(JSObject*, JSGlobalObject*); |
114 | IsExtensibleFunctionPtr METHOD_TABLE_ENTRY(isExtensible); |
115 | |
116 | using SetPrototypeFunctionPtr = bool (*)(JSObject*, JSGlobalObject*, JSValue, bool shouldThrowIfCantSet); |
117 | SetPrototypeFunctionPtr METHOD_TABLE_ENTRY(setPrototype); |
118 | |
119 | using GetPrototypeFunctionPtr = JSValue (*)(JSObject*, JSGlobalObject*); |
120 | GetPrototypeFunctionPtr METHOD_TABLE_ENTRY(getPrototype); |
121 | |
122 | using DumpToStreamFunctionPtr = void (*)(const JSCell*, PrintStream&); |
123 | DumpToStreamFunctionPtr METHOD_TABLE_ENTRY(dumpToStream); |
124 | |
125 | using AnalyzeHeapFunctionPtr = void (*)(JSCell*, HeapAnalyzer&); |
126 | AnalyzeHeapFunctionPtr METHOD_TABLE_ENTRY(analyzeHeap); |
127 | |
128 | using EstimatedSizeFunctionPtr = size_t (*)(JSCell*, VM&); |
129 | EstimatedSizeFunctionPtr METHOD_TABLE_ENTRY(estimatedSize); |
130 | |
131 | using VisitOutputConstraintsPtr = void (*)(JSCell*, SlotVisitor&); |
132 | VisitOutputConstraintsPtr METHOD_TABLE_ENTRY(visitOutputConstraints); |
133 | }; |
134 | |
135 | #define CREATE_MEMBER_CHECKER(member) \ |
136 | template <typename T> \ |
137 | struct MemberCheck##member { \ |
138 | struct Fallback { \ |
139 | void member(...); \ |
140 | }; \ |
141 | struct Derived : T, Fallback { }; \ |
142 | template <typename U, U> struct Check; \ |
143 | typedef char Yes[2]; \ |
144 | typedef char No[1]; \ |
145 | template <typename U> \ |
146 | static No &func(Check<void (Fallback::*)(...), &U::member>*); \ |
147 | template <typename U> \ |
148 | static Yes &func(...); \ |
149 | enum { has = sizeof(func<Derived>(0)) == sizeof(Yes) }; \ |
150 | } |
151 | |
152 | #define HAS_MEMBER_NAMED(klass, name) (MemberCheck##name<klass>::has) |
153 | |
154 | #define CREATE_METHOD_TABLE(ClassName) { \ |
155 | &ClassName::destroy, \ |
156 | &ClassName::visitChildren, \ |
157 | &ClassName::getCallData, \ |
158 | &ClassName::getConstructData, \ |
159 | &ClassName::put, \ |
160 | &ClassName::putByIndex, \ |
161 | &ClassName::deleteProperty, \ |
162 | &ClassName::deletePropertyByIndex, \ |
163 | &ClassName::getOwnPropertySlot, \ |
164 | &ClassName::getOwnPropertySlotByIndex, \ |
165 | &ClassName::doPutPropertySecurityCheck, \ |
166 | &ClassName::toThis, \ |
167 | &ClassName::defaultValue, \ |
168 | &ClassName::getOwnPropertyNames, \ |
169 | &ClassName::getOwnNonIndexPropertyNames, \ |
170 | &ClassName::getPropertyNames, \ |
171 | &ClassName::getEnumerableLength, \ |
172 | &ClassName::getStructurePropertyNames, \ |
173 | &ClassName::getGenericPropertyNames, \ |
174 | &ClassName::className, \ |
175 | &ClassName::toStringName, \ |
176 | &ClassName::customHasInstance, \ |
177 | &ClassName::defineOwnProperty, \ |
178 | &ClassName::preventExtensions, \ |
179 | &ClassName::isExtensible, \ |
180 | &ClassName::setPrototype, \ |
181 | &ClassName::getPrototype, \ |
182 | &ClassName::dumpToStream, \ |
183 | &ClassName::analyzeHeap, \ |
184 | &ClassName::estimatedSize, \ |
185 | &ClassName::visitOutputConstraints, \ |
186 | }, \ |
187 | ClassName::TypedArrayStorageType, \ |
188 | sizeof(ClassName) |
189 | |
190 | struct ClassInfo { |
191 | using CheckSubClassSnippetFunctionPtr = Ref<Snippet> (*)(void); |
192 | |
193 | // A string denoting the class name. Example: "Window". |
194 | const char* className; |
195 | // Pointer to the class information of the base class. |
196 | // nullptrif there is none. |
197 | const ClassInfo* parentClass; |
198 | const HashTable* staticPropHashTable; |
199 | CheckSubClassSnippetFunctionPtr checkSubClassSnippet; |
200 | MethodTable methodTable; |
201 | TypedArrayType typedArrayStorageType; |
202 | unsigned staticClassSize; |
203 | |
204 | static ptrdiff_t offsetOfParentClass() |
205 | { |
206 | return OBJECT_OFFSETOF(ClassInfo, parentClass); |
207 | } |
208 | |
209 | bool isSubClassOf(const ClassInfo* other) const |
210 | { |
211 | for (const ClassInfo* ci = this; ci; ci = ci->parentClass) { |
212 | if (ci == other) |
213 | return true; |
214 | } |
215 | return false; |
216 | } |
217 | |
218 | JS_EXPORT_PRIVATE void dump(PrintStream&) const; |
219 | |
220 | JS_EXPORT_PRIVATE bool hasStaticSetterOrReadonlyProperties() const; |
221 | }; |
222 | |
223 | } // namespace JSC |
224 | |