[JSC] Introduce LinkTimeConstant mechanism
[WebKit-https.git] / Source / JavaScriptCore / builtins / BuiltinNames.h
1 /*
2  * Copyright (C) 2014-2019 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #pragma once
27
28 #include "BuiltinUtils.h"
29 #include "BytecodeIntrinsicRegistry.h"
30 #include "CommonIdentifiers.h"
31 #include "JSCBuiltins.h"
32
33 namespace JSC {
34
35 #define DECLARE_BUILTIN_NAMES_IN_JSC(name) const JSC::Identifier m_##name;
36 #define DECLARE_BUILTIN_SYMBOLS_IN_JSC(name) const JSC::Identifier m_##name##Symbol; const JSC::Identifier m_##name##SymbolPrivateIdentifier;
37 #define DECLARE_BUILTIN_SYMBOL_ACCESSOR(name) \
38     const JSC::Identifier& name##Symbol() const { return m_##name##Symbol; }
39 #define DECLARE_BUILTIN_IDENTIFIER_ACCESSOR_IN_JSC(name) \
40     const JSC::Identifier& name##PublicName() const { return m_##name; } \
41     JSC::Identifier name##PrivateName() const { return JSC::Identifier::fromUid(*bitwise_cast<SymbolImpl*>(&JSC::Symbols::name##PrivateName)); }
42
43
44 #define JSC_COMMON_PRIVATE_IDENTIFIERS_EACH_PROPERTY_NAME(macro) \
45     JSC_COMMON_BYTECODE_INTRINSIC_FUNCTIONS_EACH_NAME(macro) \
46     JSC_COMMON_BYTECODE_INTRINSIC_CONSTANTS_EACH_NAME(macro) \
47     macro(add) \
48     macro(applyFunction) \
49     macro(arrayIteratorNextIndex) \
50     macro(arrayIterationKind) \
51     macro(arrayIteratorNext) \
52     macro(arrayIteratorIsDone) \
53     macro(arrayIteratorKind) \
54     macro(arraySpeciesCreate) \
55     macro(assert) \
56     macro(callFunction) \
57     macro(charCodeAt) \
58     macro(executor) \
59     macro(isView) \
60     macro(iteratedObject) \
61     macro(iteratedString) \
62     macro(stringIteratorNextIndex) \
63     macro(promise) \
64     macro(promiseOrCapability) \
65     macro(Object) \
66     macro(Number) \
67     macro(Array) \
68     macro(ArrayBuffer) \
69     macro(RegExp) \
70     macro(trunc) \
71     macro(create) \
72     macro(defineProperty) \
73     macro(defaultPromiseThen) \
74     macro(getPrototypeOf) \
75     macro(getOwnPropertyNames) \
76     macro(ownKeys) \
77     macro(Set) \
78     macro(throwTypeErrorFunction) \
79     macro(typedArrayLength) \
80     macro(typedArraySort) \
81     macro(typedArrayGetOriginalConstructor) \
82     macro(typedArraySubarrayCreate) \
83     macro(BuiltinLog) \
84     macro(BuiltinDescribe) \
85     macro(homeObject) \
86     macro(enqueueJob) \
87     macro(hostPromiseRejectionTracker) \
88     macro(onFulfilled) \
89     macro(onRejected) \
90     macro(push) \
91     macro(repeatCharacter) \
92     macro(starDefault) \
93     macro(InspectorInstrumentation) \
94     macro(get) \
95     macro(set) \
96     macro(shift) \
97     macro(allocateTypedArray) \
98     macro(Int8Array) \
99     macro(Int16Array) \
100     macro(Int32Array) \
101     macro(Uint8Array) \
102     macro(Uint8ClampedArray) \
103     macro(Uint16Array) \
104     macro(Uint32Array) \
105     macro(Float32Array) \
106     macro(Float64Array) \
107     macro(exec) \
108     macro(generator) \
109     macro(generatorNext) \
110     macro(generatorState) \
111     macro(generatorFrame) \
112     macro(generatorValue) \
113     macro(generatorThis) \
114     macro(generatorResumeMode) \
115     macro(syncIterator) \
116     macro(nextMethod) \
117     macro(asyncGeneratorQueueItemNext) \
118     macro(dateTimeFormat) \
119     macro(intlSubstituteValue) \
120     macro(thisTimeValue) \
121     macro(newTargetLocal) \
122     macro(derivedConstructor) \
123     macro(isTypedArrayView) \
124     macro(isBoundFunction) \
125     macro(hasInstanceBoundFunction) \
126     macro(instanceOf) \
127     macro(isArraySlow) \
128     macro(isConstructor) \
129     macro(concatMemcpy) \
130     macro(appendMemcpy) \
131     macro(regExpCreate) \
132     macro(isRegExp) \
133     macro(replaceUsingRegExp) \
134     macro(replaceUsingStringSearch) \
135     macro(makeTypeError) \
136     macro(mapBucket) \
137     macro(mapBucketHead) \
138     macro(mapBucketNext) \
139     macro(mapBucketKey) \
140     macro(mapBucketValue) \
141     macro(mapIteratorKind) \
142     macro(setBucket) \
143     macro(setBucketHead) \
144     macro(setBucketNext) \
145     macro(setBucketKey) \
146     macro(setIteratorKind) \
147     macro(regExpBuiltinExec) \
148     macro(regExpMatchFast) \
149     macro(regExpProtoFlagsGetter) \
150     macro(regExpProtoGlobalGetter) \
151     macro(regExpProtoIgnoreCaseGetter) \
152     macro(regExpProtoMultilineGetter) \
153     macro(regExpProtoSourceGetter) \
154     macro(regExpProtoStickyGetter) \
155     macro(regExpProtoUnicodeGetter) \
156     macro(regExpPrototypeSymbolReplace) \
157     macro(regExpSearchFast) \
158     macro(regExpSplitFast) \
159     macro(regExpTestFast) \
160     macro(regExpStringIteratorRegExp) \
161     macro(regExpStringIteratorString) \
162     macro(regExpStringIteratorGlobal) \
163     macro(regExpStringIteratorUnicode) \
164     macro(regExpStringIteratorDone) \
165     macro(stringIncludesInternal) \
166     macro(stringSplitFast) \
167     macro(stringSubstrInternal) \
168     macro(makeBoundFunction) \
169     macro(hasOwnLengthProperty) \
170     macro(importModule) \
171     macro(propertyIsEnumerable) \
172     macro(meta) \
173     macro(webAssemblyCompileStreamingInternal) \
174     macro(webAssemblyInstantiateStreamingInternal) \
175
176 namespace Symbols {
177 #define DECLARE_BUILTIN_STATIC_SYMBOLS(name) extern JS_EXPORT_PRIVATE SymbolImpl::StaticSymbolImpl name##Symbol;
178 JSC_COMMON_PRIVATE_IDENTIFIERS_EACH_WELL_KNOWN_SYMBOL(DECLARE_BUILTIN_STATIC_SYMBOLS)
179 #undef DECLARE_BUILTIN_STATIC_SYMBOLS
180
181 #define DECLARE_BUILTIN_PRIVATE_NAMES(name) extern JS_EXPORT_PRIVATE SymbolImpl::StaticSymbolImpl name##PrivateName;
182 JSC_FOREACH_BUILTIN_FUNCTION_NAME(DECLARE_BUILTIN_PRIVATE_NAMES)
183 JSC_COMMON_PRIVATE_IDENTIFIERS_EACH_PROPERTY_NAME(DECLARE_BUILTIN_PRIVATE_NAMES)
184 #undef DECLARE_BUILTIN_PRIVATE_NAMES
185
186 extern JS_EXPORT_PRIVATE SymbolImpl::StaticSymbolImpl dollarVMPrivateName;
187 extern JS_EXPORT_PRIVATE SymbolImpl::StaticSymbolImpl polyProtoPrivateName;
188 }
189
190 class BuiltinNames {
191     WTF_MAKE_NONCOPYABLE(BuiltinNames); WTF_MAKE_FAST_ALLOCATED;
192     
193 public:
194     BuiltinNames(VM&, CommonIdentifiers*);
195
196     SymbolImpl* lookUpPrivateName(const Identifier&) const;
197     Identifier getPublicName(VM&, SymbolImpl*) const;
198     
199     void appendExternalName(const Identifier& publicName, const Identifier& privateName);
200
201     JSC_FOREACH_BUILTIN_FUNCTION_NAME(DECLARE_BUILTIN_IDENTIFIER_ACCESSOR_IN_JSC)
202     JSC_COMMON_PRIVATE_IDENTIFIERS_EACH_PROPERTY_NAME(DECLARE_BUILTIN_IDENTIFIER_ACCESSOR_IN_JSC)
203     JSC_COMMON_PRIVATE_IDENTIFIERS_EACH_WELL_KNOWN_SYMBOL(DECLARE_BUILTIN_SYMBOL_ACCESSOR)
204     const JSC::Identifier& dollarVMPublicName() const { return m_dollarVMName; }
205     const JSC::Identifier& dollarVMPrivateName() const { return m_dollarVMPrivateName; }
206     const JSC::Identifier& polyProtoName() const { return m_polyProtoPrivateName; }
207
208 private:
209     void checkPublicToPrivateMapConsistency(UniquedStringImpl* publicName, UniquedStringImpl* privateName);
210
211     Identifier m_emptyIdentifier;
212     JSC_FOREACH_BUILTIN_FUNCTION_NAME(DECLARE_BUILTIN_NAMES_IN_JSC)
213     JSC_COMMON_PRIVATE_IDENTIFIERS_EACH_PROPERTY_NAME(DECLARE_BUILTIN_NAMES_IN_JSC)
214     JSC_COMMON_PRIVATE_IDENTIFIERS_EACH_WELL_KNOWN_SYMBOL(DECLARE_BUILTIN_SYMBOLS_IN_JSC)
215     const JSC::Identifier m_dollarVMName;
216     const JSC::Identifier m_dollarVMPrivateName;
217     const JSC::Identifier m_polyProtoPrivateName;
218     typedef HashMap<RefPtr<UniquedStringImpl>, SymbolImpl*, IdentifierRepHash> BuiltinNamesMap;
219     BuiltinNamesMap m_publicToPrivateMap;
220 };
221
222 inline SymbolImpl* BuiltinNames::lookUpPrivateName(const Identifier& ident) const
223 {
224     auto iter = m_publicToPrivateMap.find(ident.impl());
225     if (iter != m_publicToPrivateMap.end())
226         return iter->value;
227     return nullptr;
228 }
229
230 inline Identifier BuiltinNames::getPublicName(VM& vm, SymbolImpl* symbol) const
231 {
232     if (symbol->isPrivate())
233         return Identifier::fromString(vm, symbol);
234     // We have special handling for well-known symbols.
235     ASSERT(symbol->startsWith("Symbol."));
236     return Identifier::fromString(vm, makeString(String(symbol->substring(strlen("Symbol."))), "Symbol"));
237 }
238
239 inline void BuiltinNames::checkPublicToPrivateMapConsistency(UniquedStringImpl* publicName, UniquedStringImpl* privateName)
240 {
241 #ifndef NDEBUG
242     for (const auto& key : m_publicToPrivateMap.keys())
243         ASSERT(String(publicName) != *key);
244
245     ASSERT(privateName->isSymbol());
246     SymbolImpl* symbol = static_cast<SymbolImpl*>(privateName);
247     if (symbol->isPrivate()) {
248         // This guarantees that we can get public symbols from private symbols by using content of private symbols.
249         ASSERT(String(symbol) == *publicName);
250     } else {
251         // We have a hack in m_publicToPrivateMap: adding non-private Symbol with readable name to use it
252         // in builtin code. The example is @iteratorSymbol => Symbol.iterator mapping. To allow the reverse
253         // transformation, we ensure that non-private symbol mapping has xxxSymbol => Symbol.xxx.
254         ASSERT(makeString(String(symbol), "Symbol") == makeString("Symbol.", String(publicName)));
255     }
256 #else
257     UNUSED_PARAM(publicName);
258     UNUSED_PARAM(privateName);
259 #endif
260 }
261
262 inline void BuiltinNames::appendExternalName(const Identifier& publicName, const Identifier& privateName)
263 {
264     checkPublicToPrivateMapConsistency(publicName.impl(), privateName.impl());
265     m_publicToPrivateMap.add(publicName.impl(), static_cast<SymbolImpl*>(privateName.impl()));
266 }
267
268 } // namespace JSC