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