1/*
2 * Copyright (C) 2012-2013, 2015-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. AND ITS CONTRIBUTORS ``AS IS''
14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23 * THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#pragma once
27
28#include "ConstructAbility.h"
29#include "Identifier.h"
30
31namespace JSC {
32
33enum class JSParserStrictMode { NotStrict, Strict };
34enum class JSParserBuiltinMode { NotBuiltin, Builtin };
35enum class JSParserScriptMode { Classic, Module };
36
37enum class ConstructorKind { None, Base, Extends };
38enum class SuperBinding { Needed, NotNeeded };
39
40enum DebuggerMode { DebuggerOff, DebuggerOn };
41
42enum class FunctionMode { FunctionExpression, FunctionDeclaration, MethodDefinition };
43
44// Keep it less than 32, it means this should be within 5 bits.
45enum class SourceParseMode : uint8_t {
46 NormalFunctionMode = 0,
47 GeneratorBodyMode = 1,
48 GeneratorWrapperFunctionMode = 2,
49 GetterMode = 3,
50 SetterMode = 4,
51 MethodMode = 5,
52 ArrowFunctionMode = 6,
53 AsyncFunctionBodyMode = 7,
54 AsyncArrowFunctionBodyMode = 8,
55 AsyncFunctionMode = 9,
56 AsyncMethodMode = 10,
57 AsyncArrowFunctionMode = 11,
58 ProgramMode = 12,
59 ModuleAnalyzeMode = 13,
60 ModuleEvaluateMode = 14,
61 AsyncGeneratorBodyMode = 15,
62 AsyncGeneratorWrapperFunctionMode = 16,
63 AsyncGeneratorWrapperMethodMode = 17,
64 GeneratorWrapperMethodMode = 18,
65};
66
67class SourceParseModeSet {
68public:
69 template<typename... Modes>
70 constexpr SourceParseModeSet(Modes... args)
71 : m_mask(mergeSourceParseModes(args...))
72 {
73 }
74
75 ALWAYS_INLINE constexpr bool contains(SourceParseMode mode)
76 {
77 return (1U << static_cast<unsigned>(mode)) & m_mask;
78 }
79
80private:
81 ALWAYS_INLINE static constexpr unsigned mergeSourceParseModes(SourceParseMode mode)
82 {
83 return (1U << static_cast<unsigned>(mode));
84 }
85
86 template<typename... Rest>
87 ALWAYS_INLINE static constexpr unsigned mergeSourceParseModes(SourceParseMode mode, Rest... rest)
88 {
89 return (1U << static_cast<unsigned>(mode)) | mergeSourceParseModes(rest...);
90 }
91
92 const unsigned m_mask;
93};
94
95ALWAYS_INLINE bool isFunctionParseMode(SourceParseMode parseMode)
96{
97 return SourceParseModeSet(
98 SourceParseMode::NormalFunctionMode,
99 SourceParseMode::GeneratorBodyMode,
100 SourceParseMode::GeneratorWrapperFunctionMode,
101 SourceParseMode::GeneratorWrapperMethodMode,
102 SourceParseMode::GetterMode,
103 SourceParseMode::SetterMode,
104 SourceParseMode::MethodMode,
105 SourceParseMode::ArrowFunctionMode,
106 SourceParseMode::AsyncFunctionBodyMode,
107 SourceParseMode::AsyncFunctionMode,
108 SourceParseMode::AsyncMethodMode,
109 SourceParseMode::AsyncArrowFunctionMode,
110 SourceParseMode::AsyncArrowFunctionBodyMode,
111 SourceParseMode::AsyncGeneratorBodyMode,
112 SourceParseMode::AsyncGeneratorWrapperFunctionMode,
113 SourceParseMode::AsyncGeneratorWrapperMethodMode).contains(parseMode);
114}
115
116ALWAYS_INLINE bool isAsyncFunctionParseMode(SourceParseMode parseMode)
117{
118 return SourceParseModeSet(
119 SourceParseMode::AsyncGeneratorWrapperFunctionMode,
120 SourceParseMode::AsyncGeneratorBodyMode,
121 SourceParseMode::AsyncGeneratorWrapperMethodMode,
122 SourceParseMode::AsyncFunctionBodyMode,
123 SourceParseMode::AsyncFunctionMode,
124 SourceParseMode::AsyncMethodMode,
125 SourceParseMode::AsyncArrowFunctionMode,
126 SourceParseMode::AsyncArrowFunctionBodyMode).contains(parseMode);
127}
128
129ALWAYS_INLINE bool isAsyncArrowFunctionParseMode(SourceParseMode parseMode)
130{
131 return SourceParseModeSet(
132 SourceParseMode::AsyncArrowFunctionMode,
133 SourceParseMode::AsyncArrowFunctionBodyMode).contains(parseMode);
134}
135
136ALWAYS_INLINE bool isAsyncGeneratorParseMode(SourceParseMode parseMode)
137{
138 return SourceParseModeSet(
139 SourceParseMode::AsyncGeneratorWrapperFunctionMode,
140 SourceParseMode::AsyncGeneratorWrapperMethodMode,
141 SourceParseMode::AsyncGeneratorBodyMode).contains(parseMode);
142}
143
144ALWAYS_INLINE bool isAsyncGeneratorWrapperParseMode(SourceParseMode parseMode)
145{
146 return SourceParseModeSet(
147 SourceParseMode::AsyncGeneratorWrapperFunctionMode,
148 SourceParseMode::AsyncGeneratorWrapperMethodMode).contains(parseMode);
149}
150
151ALWAYS_INLINE bool isAsyncFunctionOrAsyncGeneratorWrapperParseMode(SourceParseMode parseMode)
152{
153 return SourceParseModeSet(
154 SourceParseMode::AsyncArrowFunctionMode,
155 SourceParseMode::AsyncFunctionMode,
156 SourceParseMode::AsyncGeneratorWrapperFunctionMode,
157 SourceParseMode::AsyncGeneratorWrapperMethodMode,
158 SourceParseMode::AsyncMethodMode).contains(parseMode);
159 }
160
161ALWAYS_INLINE bool isAsyncFunctionWrapperParseMode(SourceParseMode parseMode)
162{
163 return SourceParseModeSet(
164 SourceParseMode::AsyncArrowFunctionMode,
165 SourceParseMode::AsyncFunctionMode,
166 SourceParseMode::AsyncMethodMode).contains(parseMode);
167}
168
169ALWAYS_INLINE bool isAsyncFunctionBodyParseMode(SourceParseMode parseMode)
170{
171 return SourceParseModeSet(
172 SourceParseMode::AsyncFunctionBodyMode,
173 SourceParseMode::AsyncGeneratorBodyMode,
174 SourceParseMode::AsyncArrowFunctionBodyMode).contains(parseMode);
175}
176
177ALWAYS_INLINE bool isGeneratorMethodParseMode(SourceParseMode parseMode)
178{
179 return SourceParseModeSet(
180 SourceParseMode::GeneratorWrapperMethodMode).contains(parseMode);
181}
182
183ALWAYS_INLINE bool isAsyncMethodParseMode(SourceParseMode parseMode)
184{
185 return SourceParseModeSet(SourceParseMode::AsyncMethodMode).contains(parseMode);
186}
187
188ALWAYS_INLINE bool isAsyncGeneratorMethodParseMode(SourceParseMode parseMode)
189{
190 return SourceParseModeSet(SourceParseMode::AsyncGeneratorWrapperMethodMode).contains(parseMode);
191}
192
193ALWAYS_INLINE bool isMethodParseMode(SourceParseMode parseMode)
194{
195 return SourceParseModeSet(
196 SourceParseMode::GeneratorWrapperMethodMode,
197 SourceParseMode::GetterMode,
198 SourceParseMode::SetterMode,
199 SourceParseMode::MethodMode,
200 SourceParseMode::AsyncMethodMode,
201 SourceParseMode::AsyncGeneratorWrapperMethodMode).contains(parseMode);
202}
203
204ALWAYS_INLINE bool isGeneratorOrAsyncFunctionBodyParseMode(SourceParseMode parseMode)
205{
206 return SourceParseModeSet(
207 SourceParseMode::GeneratorBodyMode,
208 SourceParseMode::AsyncFunctionBodyMode,
209 SourceParseMode::AsyncGeneratorBodyMode,
210 SourceParseMode::AsyncArrowFunctionBodyMode).contains(parseMode);
211}
212
213ALWAYS_INLINE bool isGeneratorOrAsyncFunctionWrapperParseMode(SourceParseMode parseMode)
214{
215 return SourceParseModeSet(
216 SourceParseMode::GeneratorWrapperFunctionMode,
217 SourceParseMode::GeneratorWrapperMethodMode,
218 SourceParseMode::AsyncFunctionMode,
219 SourceParseMode::AsyncArrowFunctionMode,
220 SourceParseMode::AsyncGeneratorWrapperFunctionMode,
221 SourceParseMode::AsyncMethodMode,
222 SourceParseMode::AsyncGeneratorWrapperMethodMode).contains(parseMode);
223}
224
225ALWAYS_INLINE bool isGeneratorParseMode(SourceParseMode parseMode)
226{
227 return SourceParseModeSet(
228 SourceParseMode::GeneratorBodyMode,
229 SourceParseMode::GeneratorWrapperFunctionMode,
230 SourceParseMode::GeneratorWrapperMethodMode).contains(parseMode);
231}
232
233ALWAYS_INLINE bool isGeneratorWrapperParseMode(SourceParseMode parseMode)
234{
235 return SourceParseModeSet(
236 SourceParseMode::GeneratorWrapperFunctionMode,
237 SourceParseMode::GeneratorWrapperMethodMode).contains(parseMode);
238}
239
240ALWAYS_INLINE bool isArrowFunctionParseMode(SourceParseMode parseMode)
241{
242 return SourceParseModeSet(
243 SourceParseMode::ArrowFunctionMode,
244 SourceParseMode::AsyncArrowFunctionMode,
245 SourceParseMode::AsyncArrowFunctionBodyMode).contains(parseMode);
246}
247
248ALWAYS_INLINE bool isModuleParseMode(SourceParseMode parseMode)
249{
250 return SourceParseModeSet(
251 SourceParseMode::ModuleAnalyzeMode,
252 SourceParseMode::ModuleEvaluateMode).contains(parseMode);
253}
254
255ALWAYS_INLINE bool isProgramParseMode(SourceParseMode parseMode)
256{
257 return SourceParseModeSet(SourceParseMode::ProgramMode).contains(parseMode);
258}
259
260ALWAYS_INLINE bool isProgramOrModuleParseMode(SourceParseMode parseMode)
261{
262 return SourceParseModeSet(
263 SourceParseMode::ProgramMode,
264 SourceParseMode::ModuleAnalyzeMode,
265 SourceParseMode::ModuleEvaluateMode).contains(parseMode);
266}
267
268ALWAYS_INLINE ConstructAbility constructAbilityForParseMode(SourceParseMode parseMode)
269{
270 if (parseMode == SourceParseMode::NormalFunctionMode)
271 return ConstructAbility::CanConstruct;
272
273 return ConstructAbility::CannotConstruct;
274}
275
276inline bool functionNameIsInScope(const Identifier& name, FunctionMode functionMode)
277{
278 if (name.isNull())
279 return false;
280
281 if (functionMode != FunctionMode::FunctionExpression)
282 return false;
283
284 return true;
285}
286
287inline bool functionNameScopeIsDynamic(bool usesEval, bool isStrictMode)
288{
289 // If non-strict eval is in play, a function gets a separate object in the scope chain for its name.
290 // This enables eval to declare and then delete a name that shadows the function's name.
291
292 if (!usesEval)
293 return false;
294
295 if (isStrictMode)
296 return false;
297
298 return true;
299}
300
301typedef uint16_t CodeFeatures;
302
303const CodeFeatures NoFeatures = 0;
304const CodeFeatures EvalFeature = 1 << 0;
305const CodeFeatures ArgumentsFeature = 1 << 1;
306const CodeFeatures WithFeature = 1 << 2;
307const CodeFeatures ThisFeature = 1 << 3;
308const CodeFeatures StrictModeFeature = 1 << 4;
309const CodeFeatures ShadowsArgumentsFeature = 1 << 5;
310const CodeFeatures ArrowFunctionFeature = 1 << 6;
311const CodeFeatures ArrowFunctionContextFeature = 1 << 7;
312const CodeFeatures SuperCallFeature = 1 << 8;
313const CodeFeatures SuperPropertyFeature = 1 << 9;
314const CodeFeatures NewTargetFeature = 1 << 10;
315const CodeFeatures NoEvalCacheFeature = 1 << 11;
316
317const CodeFeatures AllFeatures = EvalFeature | ArgumentsFeature | WithFeature | ThisFeature | StrictModeFeature | ShadowsArgumentsFeature | ArrowFunctionFeature | ArrowFunctionContextFeature |
318 SuperCallFeature | SuperPropertyFeature | NewTargetFeature | NoEvalCacheFeature;
319
320typedef uint8_t InnerArrowFunctionCodeFeatures;
321
322const InnerArrowFunctionCodeFeatures NoInnerArrowFunctionFeatures = 0;
323const InnerArrowFunctionCodeFeatures EvalInnerArrowFunctionFeature = 1 << 0;
324const InnerArrowFunctionCodeFeatures ArgumentsInnerArrowFunctionFeature = 1 << 1;
325const InnerArrowFunctionCodeFeatures ThisInnerArrowFunctionFeature = 1 << 2;
326const InnerArrowFunctionCodeFeatures SuperCallInnerArrowFunctionFeature = 1 << 3;
327const InnerArrowFunctionCodeFeatures SuperPropertyInnerArrowFunctionFeature = 1 << 4;
328const InnerArrowFunctionCodeFeatures NewTargetInnerArrowFunctionFeature = 1 << 5;
329
330const InnerArrowFunctionCodeFeatures AllInnerArrowFunctionCodeFeatures = EvalInnerArrowFunctionFeature | ArgumentsInnerArrowFunctionFeature | ThisInnerArrowFunctionFeature | SuperCallInnerArrowFunctionFeature | SuperPropertyInnerArrowFunctionFeature | NewTargetInnerArrowFunctionFeature;
331static_assert(AllInnerArrowFunctionCodeFeatures <= 0b111111, "InnerArrowFunctionCodeFeatures must be 6bits");
332} // namespace JSC
333