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(regExpStringIteratorRegExp) \
168 macro(regExpStringIteratorString) \
169 macro(regExpStringIteratorGlobal) \
170 macro(regExpStringIteratorUnicode) \
171 macro(regExpStringIteratorDone) \
172 macro(stringIncludesInternal) \
173 macro(stringSplitFast) \
174 macro(stringSubstrInternal) \
175 macro(makeBoundFunction) \
176 macro(hasOwnLengthProperty) \
177 macro(importModule) \
178 macro(propertyIsEnumerable) \
179 macro(meta) \
180 macro(webAssemblyCompileStreamingInternal) \
181 macro(webAssemblyInstantiateStreamingInternal) \
182
183namespace Symbols {
184#define DECLARE_BUILTIN_STATIC_SYMBOLS(name) extern JS_EXPORT_PRIVATE SymbolImpl::StaticSymbolImpl name##Symbol;
185JSC_COMMON_PRIVATE_IDENTIFIERS_EACH_WELL_KNOWN_SYMBOL(DECLARE_BUILTIN_STATIC_SYMBOLS)
186#undef DECLARE_BUILTIN_STATIC_SYMBOLS
187
188#define DECLARE_BUILTIN_PRIVATE_NAMES(name) extern JS_EXPORT_PRIVATE SymbolImpl::StaticSymbolImpl name##PrivateName;
189JSC_FOREACH_BUILTIN_FUNCTION_NAME(DECLARE_BUILTIN_PRIVATE_NAMES)
190JSC_COMMON_PRIVATE_IDENTIFIERS_EACH_PROPERTY_NAME(DECLARE_BUILTIN_PRIVATE_NAMES)
191#undef DECLARE_BUILTIN_PRIVATE_NAMES
192
193extern JS_EXPORT_PRIVATE SymbolImpl::StaticSymbolImpl dollarVMPrivateName;
194extern JS_EXPORT_PRIVATE SymbolImpl::StaticSymbolImpl polyProtoPrivateName;
195}
196
197class BuiltinNames {
198 WTF_MAKE_NONCOPYABLE(BuiltinNames); WTF_MAKE_FAST_ALLOCATED;
199
200public:
201 BuiltinNames(VM*, CommonIdentifiers*);
202
203 SymbolImpl* lookUpPrivateName(const Identifier&) const;
204 Identifier getPublicName(VM&, SymbolImpl*) const;
205
206 void appendExternalName(const Identifier& publicName, const Identifier& privateName);
207
208 JSC_FOREACH_BUILTIN_FUNCTION_NAME(DECLARE_BUILTIN_IDENTIFIER_ACCESSOR_IN_JSC)
209 JSC_COMMON_PRIVATE_IDENTIFIERS_EACH_PROPERTY_NAME(DECLARE_BUILTIN_IDENTIFIER_ACCESSOR_IN_JSC)
210 JSC_COMMON_PRIVATE_IDENTIFIERS_EACH_WELL_KNOWN_SYMBOL(DECLARE_BUILTIN_SYMBOL_ACCESSOR)
211 const JSC::Identifier& dollarVMPublicName() const { return m_dollarVMName; }
212 const JSC::Identifier& dollarVMPrivateName() const { return m_dollarVMPrivateName; }
213 const JSC::Identifier& polyProtoName() const { return m_polyProtoPrivateName; }
214
215private:
216 void checkPublicToPrivateMapConsistency(UniquedStringImpl* publicName, UniquedStringImpl* privateName);
217
218 Identifier m_emptyIdentifier;
219 JSC_FOREACH_BUILTIN_FUNCTION_NAME(DECLARE_BUILTIN_NAMES_IN_JSC)
220 JSC_COMMON_PRIVATE_IDENTIFIERS_EACH_PROPERTY_NAME(DECLARE_BUILTIN_NAMES_IN_JSC)
221 JSC_COMMON_PRIVATE_IDENTIFIERS_EACH_WELL_KNOWN_SYMBOL(DECLARE_BUILTIN_SYMBOLS_IN_JSC)
222 const JSC::Identifier m_dollarVMName;
223 const JSC::Identifier m_dollarVMPrivateName;
224 const JSC::Identifier m_polyProtoPrivateName;
225 typedef HashMap<RefPtr<UniquedStringImpl>, SymbolImpl*, IdentifierRepHash> BuiltinNamesMap;
226 BuiltinNamesMap m_publicToPrivateMap;
227};
228
229inline SymbolImpl* BuiltinNames::lookUpPrivateName(const Identifier& ident) const
230{
231 auto iter = m_publicToPrivateMap.find(ident.impl());
232 if (iter != m_publicToPrivateMap.end())
233 return iter->value;
234 return nullptr;
235}
236
237inline Identifier BuiltinNames::getPublicName(VM& vm, SymbolImpl* symbol) const
238{
239 if (symbol->isPrivate())
240 return Identifier::fromString(&vm, symbol);
241 // We have special handling for well-known symbols.
242 ASSERT(symbol->startsWith("Symbol."));
243 return Identifier::fromString(&vm, makeString(String(symbol->substring(strlen("Symbol."))), "Symbol"));
244}
245
246inline void BuiltinNames::checkPublicToPrivateMapConsistency(UniquedStringImpl* publicName, UniquedStringImpl* privateName)
247{
248#ifndef NDEBUG
249 for (const auto& key : m_publicToPrivateMap.keys())
250 ASSERT(String(publicName) != *key);
251
252 ASSERT(privateName->isSymbol());
253 SymbolImpl* symbol = static_cast<SymbolImpl*>(privateName);
254 if (symbol->isPrivate()) {
255 // This guarantees that we can get public symbols from private symbols by using content of private symbols.
256 ASSERT(String(symbol) == *publicName);
257 } else {
258 // We have a hack in m_publicToPrivateMap: adding non-private Symbol with readable name to use it
259 // in builtin code. The example is @iteratorSymbol => Symbol.iterator mapping. To allow the reverse
260 // transformation, we ensure that non-private symbol mapping has xxxSymbol => Symbol.xxx.
261 ASSERT(makeString(String(symbol), "Symbol") == makeString("Symbol.", String(publicName)));
262 }
263#else
264 UNUSED_PARAM(publicName);
265 UNUSED_PARAM(privateName);
266#endif
267}
268
269inline void BuiltinNames::appendExternalName(const Identifier& publicName, const Identifier& privateName)
270{
271 checkPublicToPrivateMapConsistency(publicName.impl(), privateName.impl());
272 m_publicToPrivateMap.add(publicName.impl(), static_cast<SymbolImpl*>(privateName.impl()));
273}
274
275} // namespace JSC
276