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