[JSC] Drop direct references to Intl constructors by rewriting Intl JS builtins in C++
[WebKit-https.git] / Source / JavaScriptCore / builtins / BuiltinNames.h
1 /*
2  * Copyright (C) 2014, 2016 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(arrayIteratorNextIndex) \
49     macro(arrayIterationKind) \
50     macro(arrayIteratorNext) \
51     macro(arrayIteratorIsDone) \
52     macro(arrayIteratorKind) \
53     macro(assert) \
54     macro(charCodeAt) \
55     macro(executor) \
56     macro(isView) \
57     macro(iteratedObject) \
58     macro(iteratedString) \
59     macro(stringIteratorNextIndex) \
60     macro(promise) \
61     macro(Object) \
62     macro(Number) \
63     macro(Array) \
64     macro(ArrayBuffer) \
65     macro(RegExp) \
66     macro(Promise) \
67     macro(Reflect) \
68     macro(InternalPromise) \
69     macro(trunc) \
70     macro(create) \
71     macro(defineProperty) \
72     macro(getPrototypeOf) \
73     macro(getOwnPropertyDescriptor) \
74     macro(getOwnPropertyNames) \
75     macro(ownKeys) \
76     macro(Set) \
77     macro(TypeError) \
78     macro(typedArrayLength) \
79     macro(typedArraySort) \
80     macro(typedArrayGetOriginalConstructor) \
81     macro(typedArraySubarrayCreate) \
82     macro(BuiltinLog) \
83     macro(BuiltinDescribe) \
84     macro(homeObject) \
85     macro(templateRegistryKey) \
86     macro(enqueueJob) \
87     macro(hostPromiseRejectionTracker) \
88     macro(promiseIsHandled) \
89     macro(promiseState) \
90     macro(promiseReactions) \
91     macro(promiseResult) \
92     macro(onFulfilled) \
93     macro(onRejected) \
94     macro(push) \
95     macro(repeatCharacter) \
96     macro(capabilities) \
97     macro(starDefault) \
98     macro(InspectorInstrumentation) \
99     macro(get) \
100     macro(set) \
101     macro(shift) \
102     macro(allocateTypedArray) \
103     macro(Int8Array) \
104     macro(Int16Array) \
105     macro(Int32Array) \
106     macro(Uint8Array) \
107     macro(Uint8ClampedArray) \
108     macro(Uint16Array) \
109     macro(Uint32Array) \
110     macro(Float32Array) \
111     macro(Float64Array) \
112     macro(exec) \
113     macro(generator) \
114     macro(generatorNext) \
115     macro(generatorState) \
116     macro(generatorFrame) \
117     macro(generatorValue) \
118     macro(generatorThis) \
119     macro(syncIterator) \
120     macro(nextMethod) \
121     macro(asyncGeneratorState) \
122     macro(asyncGeneratorSuspendReason) \
123     macro(asyncGeneratorQueue) \
124     macro(asyncGeneratorQueueFirst) \
125     macro(asyncGeneratorQueueLast) \
126     macro(asyncGeneratorQueueItemNext) \
127     macro(asyncGeneratorQueueItemPrevious) \
128     macro(generatorResumeMode) \
129     macro(dateTimeFormat) \
130     macro(intlSubstituteValue) \
131     macro(thisTimeValue) \
132     macro(newTargetLocal) \
133     macro(derivedConstructor) \
134     macro(isTypedArrayView) \
135     macro(isBoundFunction) \
136     macro(hasInstanceBoundFunction) \
137     macro(instanceOf) \
138     macro(isArraySlow) \
139     macro(isArrayConstructor) \
140     macro(isConstructor) \
141     macro(concatMemcpy) \
142     macro(appendMemcpy) \
143     macro(regExpCreate) \
144     macro(replaceUsingRegExp) \
145     macro(replaceUsingStringSearch) \
146     macro(mapBucket) \
147     macro(mapBucketHead) \
148     macro(mapBucketNext) \
149     macro(mapBucketKey) \
150     macro(mapBucketValue) \
151     macro(mapIteratorKind) \
152     macro(setBucket) \
153     macro(setBucketHead) \
154     macro(setBucketNext) \
155     macro(setBucketKey) \
156     macro(setIteratorKind) \
157     macro(regExpBuiltinExec) \
158     macro(regExpMatchFast) \
159     macro(regExpProtoFlagsGetter) \
160     macro(regExpProtoGlobalGetter) \
161     macro(regExpProtoIgnoreCaseGetter) \
162     macro(regExpProtoMultilineGetter) \
163     macro(regExpProtoSourceGetter) \
164     macro(regExpProtoStickyGetter) \
165     macro(regExpProtoUnicodeGetter) \
166     macro(regExpPrototypeSymbolReplace) \
167     macro(regExpSearchFast) \
168     macro(regExpSplitFast) \
169     macro(regExpTestFast) \
170     macro(stringIncludesInternal) \
171     macro(stringSplitFast) \
172     macro(stringSubstrInternal) \
173     macro(makeBoundFunction) \
174     macro(hasOwnLengthProperty) \
175     macro(importModule) \
176     macro(propertyIsEnumerable) \
177     macro(meta) \
178     macro(webAssemblyCompileStreamingInternal) \
179     macro(webAssemblyInstantiateStreamingInternal) \
180
181 namespace Symbols {
182 #define DECLARE_BUILTIN_STATIC_SYMBOLS(name) extern JS_EXPORT_PRIVATE SymbolImpl::StaticSymbolImpl name##Symbol;
183 JSC_COMMON_PRIVATE_IDENTIFIERS_EACH_WELL_KNOWN_SYMBOL(DECLARE_BUILTIN_STATIC_SYMBOLS)
184 #undef DECLARE_BUILTIN_STATIC_SYMBOLS
185
186 #define DECLARE_BUILTIN_PRIVATE_NAMES(name) extern JS_EXPORT_PRIVATE SymbolImpl::StaticSymbolImpl name##PrivateName;
187 JSC_FOREACH_BUILTIN_FUNCTION_NAME(DECLARE_BUILTIN_PRIVATE_NAMES)
188 JSC_COMMON_PRIVATE_IDENTIFIERS_EACH_PROPERTY_NAME(DECLARE_BUILTIN_PRIVATE_NAMES)
189 #undef DECLARE_BUILTIN_PRIVATE_NAMES
190
191 extern JS_EXPORT_PRIVATE SymbolImpl::StaticSymbolImpl dollarVMPrivateName;
192 extern JS_EXPORT_PRIVATE SymbolImpl::StaticSymbolImpl polyProtoPrivateName;
193 }
194
195 class BuiltinNames {
196     WTF_MAKE_NONCOPYABLE(BuiltinNames); WTF_MAKE_FAST_ALLOCATED;
197     
198 public:
199     BuiltinNames(VM*, CommonIdentifiers*);
200
201     SymbolImpl* lookUpPrivateName(const Identifier&) const;
202     Identifier getPublicName(VM&, SymbolImpl*) const;
203     
204     void appendExternalName(const Identifier& publicName, const Identifier& privateName);
205
206     JSC_FOREACH_BUILTIN_FUNCTION_NAME(DECLARE_BUILTIN_IDENTIFIER_ACCESSOR_IN_JSC)
207     JSC_COMMON_PRIVATE_IDENTIFIERS_EACH_PROPERTY_NAME(DECLARE_BUILTIN_IDENTIFIER_ACCESSOR_IN_JSC)
208     JSC_COMMON_PRIVATE_IDENTIFIERS_EACH_WELL_KNOWN_SYMBOL(DECLARE_BUILTIN_SYMBOL_ACCESSOR)
209     const JSC::Identifier& dollarVMPublicName() const { return m_dollarVMName; }
210     const JSC::Identifier& dollarVMPrivateName() const { return m_dollarVMPrivateName; }
211     const JSC::Identifier& polyProtoName() const { return m_polyProtoPrivateName; }
212
213 private:
214     void checkPublicToPrivateMapConsistency(UniquedStringImpl* publicName, UniquedStringImpl* privateName);
215
216     Identifier m_emptyIdentifier;
217     JSC_FOREACH_BUILTIN_FUNCTION_NAME(DECLARE_BUILTIN_NAMES_IN_JSC)
218     JSC_COMMON_PRIVATE_IDENTIFIERS_EACH_PROPERTY_NAME(DECLARE_BUILTIN_NAMES_IN_JSC)
219     JSC_COMMON_PRIVATE_IDENTIFIERS_EACH_WELL_KNOWN_SYMBOL(DECLARE_BUILTIN_SYMBOLS_IN_JSC)
220     const JSC::Identifier m_dollarVMName;
221     const JSC::Identifier m_dollarVMPrivateName;
222     const JSC::Identifier m_polyProtoPrivateName;
223     typedef HashMap<RefPtr<UniquedStringImpl>, SymbolImpl*, IdentifierRepHash> BuiltinNamesMap;
224     BuiltinNamesMap m_publicToPrivateMap;
225 };
226
227 inline SymbolImpl* BuiltinNames::lookUpPrivateName(const Identifier& ident) const
228 {
229     auto iter = m_publicToPrivateMap.find(ident.impl());
230     if (iter != m_publicToPrivateMap.end())
231         return iter->value;
232     return nullptr;
233 }
234
235 inline Identifier BuiltinNames::getPublicName(VM& vm, SymbolImpl* symbol) const
236 {
237     if (symbol->isPrivate())
238         return Identifier::fromString(&vm, symbol);
239     // We have special handling for well-known symbols.
240     ASSERT(symbol->startsWith("Symbol."));
241     return Identifier::fromString(&vm, makeString(String(symbol->substring(strlen("Symbol."))), "Symbol"));
242 }
243
244 inline void BuiltinNames::checkPublicToPrivateMapConsistency(UniquedStringImpl* publicName, UniquedStringImpl* privateName)
245 {
246 #ifndef NDEBUG
247     for (const auto& key : m_publicToPrivateMap.keys())
248         ASSERT(String(publicName) != *key);
249
250     ASSERT(privateName->isSymbol());
251     SymbolImpl* symbol = static_cast<SymbolImpl*>(privateName);
252     if (symbol->isPrivate()) {
253         // This guarantees that we can get public symbols from private symbols by using content of private symbols.
254         ASSERT(String(symbol) == *publicName);
255     } else {
256         // We have a hack in m_publicToPrivateMap: adding non-private Symbol with readable name to use it
257         // in builtin code. The example is @iteratorSymbol => Symbol.iterator mapping. To allow the reverse
258         // transformation, we ensure that non-private symbol mapping has xxxSymbol => Symbol.xxx.
259         ASSERT(makeString(String(symbol), "Symbol") == makeString("Symbol.", String(publicName)));
260     }
261 #else
262     UNUSED_PARAM(publicName);
263     UNUSED_PARAM(privateName);
264 #endif
265 }
266
267 inline void BuiltinNames::appendExternalName(const Identifier& publicName, const Identifier& privateName)
268 {
269     checkPublicToPrivateMapConsistency(publicName.impl(), privateName.impl());
270     m_publicToPrivateMap.add(publicName.impl(), static_cast<SymbolImpl*>(privateName.impl()));
271 }
272
273 } // namespace JSC