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 class CodeGenerationMode : uint8_t {
41 Debugger = 1 << 0,
42 TypeProfiler = 1 << 1,
43 ControlFlowProfiler = 1 << 2,
44};
45
46enum class FunctionMode { FunctionExpression, FunctionDeclaration, MethodDefinition };
47
48// Keep it less than 32, it means this should be within 5 bits.
49enum class SourceParseMode : uint8_t {
50 NormalFunctionMode = 0,
51 GeneratorBodyMode = 1,
52 GeneratorWrapperFunctionMode = 2,
53 GetterMode = 3,
54 SetterMode = 4,
55 MethodMode = 5,
56 ArrowFunctionMode = 6,
57 AsyncFunctionBodyMode = 7,
58 AsyncArrowFunctionBodyMode = 8,
59 AsyncFunctionMode = 9,
60 AsyncMethodMode = 10,
61 AsyncArrowFunctionMode = 11,
62 ProgramMode = 12,
63 ModuleAnalyzeMode = 13,
64 ModuleEvaluateMode = 14,
65 AsyncGeneratorBodyMode = 15,
66 AsyncGeneratorWrapperFunctionMode = 16,
67 AsyncGeneratorWrapperMethodMode = 17,
68 GeneratorWrapperMethodMode = 18,
69};
70
71class SourceParseModeSet {
72public:
73 template<typename... Modes>
74 constexpr SourceParseModeSet(Modes... args)
75 : m_mask(mergeSourceParseModes(args...))
76 {
77 }
78
79 ALWAYS_INLINE constexpr bool contains(SourceParseMode mode)
80 {
81 return (1U << static_cast<unsigned>(mode)) & m_mask;
82 }
83
84private:
85 ALWAYS_INLINE static constexpr unsigned mergeSourceParseModes(SourceParseMode mode)
86 {
87 return (1U << static_cast<unsigned>(mode));
88 }
89
90 template<typename... Rest>
91 ALWAYS_INLINE static constexpr unsigned mergeSourceParseModes(SourceParseMode mode, Rest... rest)
92 {
93 return (1U << static_cast<unsigned>(mode)) | mergeSourceParseModes(rest...);
94 }
95
96 const unsigned m_mask;
97};
98
99ALWAYS_INLINE bool isFunctionParseMode(SourceParseMode parseMode)
100{
101 return SourceParseModeSet(
102 SourceParseMode::NormalFunctionMode,
103 SourceParseMode::GeneratorBodyMode,
104 SourceParseMode::GeneratorWrapperFunctionMode,
105 SourceParseMode::GeneratorWrapperMethodMode,
106 SourceParseMode::GetterMode,
107 SourceParseMode::SetterMode,
108 SourceParseMode::MethodMode,
109 SourceParseMode::ArrowFunctionMode,
110 SourceParseMode::AsyncFunctionBodyMode,
111 SourceParseMode::AsyncFunctionMode,
112 SourceParseMode::AsyncMethodMode,
113 SourceParseMode::AsyncArrowFunctionMode,
114 SourceParseMode::AsyncArrowFunctionBodyMode,
115 SourceParseMode::AsyncGeneratorBodyMode,
116 SourceParseMode::AsyncGeneratorWrapperFunctionMode,
117 SourceParseMode::AsyncGeneratorWrapperMethodMode).contains(parseMode);
118}
119
120ALWAYS_INLINE bool isAsyncFunctionParseMode(SourceParseMode parseMode)
121{
122 return SourceParseModeSet(
123 SourceParseMode::AsyncGeneratorWrapperFunctionMode,
124 SourceParseMode::AsyncGeneratorBodyMode,
125 SourceParseMode::AsyncGeneratorWrapperMethodMode,
126 SourceParseMode::AsyncFunctionBodyMode,
127 SourceParseMode::AsyncFunctionMode,
128 SourceParseMode::AsyncMethodMode,
129 SourceParseMode::AsyncArrowFunctionMode,
130 SourceParseMode::AsyncArrowFunctionBodyMode).contains(parseMode);
131}
132
133ALWAYS_INLINE bool isAsyncArrowFunctionParseMode(SourceParseMode parseMode)
134{
135 return SourceParseModeSet(
136 SourceParseMode::AsyncArrowFunctionMode,
137 SourceParseMode::AsyncArrowFunctionBodyMode).contains(parseMode);
138}
139
140ALWAYS_INLINE bool isAsyncGeneratorParseMode(SourceParseMode parseMode)
141{
142 return SourceParseModeSet(
143 SourceParseMode::AsyncGeneratorWrapperFunctionMode,
144 SourceParseMode::AsyncGeneratorWrapperMethodMode,
145 SourceParseMode::AsyncGeneratorBodyMode).contains(parseMode);
146}
147
148ALWAYS_INLINE bool isAsyncGeneratorWrapperParseMode(SourceParseMode parseMode)
149{
150 return SourceParseModeSet(
151 SourceParseMode::AsyncGeneratorWrapperFunctionMode,
152 SourceParseMode::AsyncGeneratorWrapperMethodMode).contains(parseMode);
153}
154
155ALWAYS_INLINE bool isAsyncFunctionOrAsyncGeneratorWrapperParseMode(SourceParseMode parseMode)
156{
157 return SourceParseModeSet(
158 SourceParseMode::AsyncArrowFunctionMode,
159 SourceParseMode::AsyncFunctionMode,
160 SourceParseMode::AsyncGeneratorWrapperFunctionMode,
161 SourceParseMode::AsyncGeneratorWrapperMethodMode,
162 SourceParseMode::AsyncMethodMode).contains(parseMode);
163 }
164
165ALWAYS_INLINE bool isAsyncFunctionWrapperParseMode(SourceParseMode parseMode)
166{
167 return SourceParseModeSet(
168 SourceParseMode::AsyncArrowFunctionMode,
169 SourceParseMode::AsyncFunctionMode,
170 SourceParseMode::AsyncMethodMode).contains(parseMode);
171}
172
173ALWAYS_INLINE bool isAsyncFunctionBodyParseMode(SourceParseMode parseMode)
174{
175 return SourceParseModeSet(
176 SourceParseMode::AsyncFunctionBodyMode,
177 SourceParseMode::AsyncGeneratorBodyMode,
178 SourceParseMode::AsyncArrowFunctionBodyMode).contains(parseMode);
179}
180
181ALWAYS_INLINE bool isGeneratorMethodParseMode(SourceParseMode parseMode)
182{
183 return SourceParseModeSet(
184 SourceParseMode::GeneratorWrapperMethodMode).contains(parseMode);
185}
186
187ALWAYS_INLINE bool isAsyncMethodParseMode(SourceParseMode parseMode)
188{
189 return SourceParseModeSet(SourceParseMode::AsyncMethodMode).contains(parseMode);
190}
191
192ALWAYS_INLINE bool isAsyncGeneratorMethodParseMode(SourceParseMode parseMode)
193{
194 return SourceParseModeSet(SourceParseMode::AsyncGeneratorWrapperMethodMode).contains(parseMode);
195}
196
197ALWAYS_INLINE bool isMethodParseMode(SourceParseMode parseMode)
198{
199 return SourceParseModeSet(
200 SourceParseMode::GeneratorWrapperMethodMode,
201 SourceParseMode::GetterMode,
202 SourceParseMode::SetterMode,
203 SourceParseMode::MethodMode,
204 SourceParseMode::AsyncMethodMode,
205 SourceParseMode::AsyncGeneratorWrapperMethodMode).contains(parseMode);
206}
207
208ALWAYS_INLINE bool isGeneratorOrAsyncFunctionBodyParseMode(SourceParseMode parseMode)
209{
210 return SourceParseModeSet(
211 SourceParseMode::GeneratorBodyMode,
212 SourceParseMode::AsyncFunctionBodyMode,
213 SourceParseMode::AsyncGeneratorBodyMode,
214 SourceParseMode::AsyncArrowFunctionBodyMode).contains(parseMode);
215}
216
217ALWAYS_INLINE bool isGeneratorOrAsyncFunctionWrapperParseMode(SourceParseMode parseMode)
218{
219 return SourceParseModeSet(
220 SourceParseMode::GeneratorWrapperFunctionMode,
221 SourceParseMode::GeneratorWrapperMethodMode,
222 SourceParseMode::AsyncFunctionMode,
223 SourceParseMode::AsyncArrowFunctionMode,
224 SourceParseMode::AsyncGeneratorWrapperFunctionMode,
225 SourceParseMode::AsyncMethodMode,
226 SourceParseMode::AsyncGeneratorWrapperMethodMode).contains(parseMode);
227}
228
229ALWAYS_INLINE bool isGeneratorParseMode(SourceParseMode parseMode)
230{
231 return SourceParseModeSet(
232 SourceParseMode::GeneratorBodyMode,
233 SourceParseMode::GeneratorWrapperFunctionMode,
234 SourceParseMode::GeneratorWrapperMethodMode).contains(parseMode);
235}
236
237ALWAYS_INLINE bool isGeneratorWrapperParseMode(SourceParseMode parseMode)
238{
239 return SourceParseModeSet(
240 SourceParseMode::GeneratorWrapperFunctionMode,
241 SourceParseMode::GeneratorWrapperMethodMode).contains(parseMode);
242}
243
244ALWAYS_INLINE bool isArrowFunctionParseMode(SourceParseMode parseMode)
245{
246 return SourceParseModeSet(
247 SourceParseMode::ArrowFunctionMode,
248 SourceParseMode::AsyncArrowFunctionMode,
249 SourceParseMode::AsyncArrowFunctionBodyMode).contains(parseMode);
250}
251
252ALWAYS_INLINE bool isModuleParseMode(SourceParseMode parseMode)
253{
254 return SourceParseModeSet(
255 SourceParseMode::ModuleAnalyzeMode,
256 SourceParseMode::ModuleEvaluateMode).contains(parseMode);
257}
258
259ALWAYS_INLINE bool isProgramParseMode(SourceParseMode parseMode)
260{
261 return SourceParseModeSet(SourceParseMode::ProgramMode).contains(parseMode);
262}
263
264ALWAYS_INLINE bool isProgramOrModuleParseMode(SourceParseMode parseMode)
265{
266 return SourceParseModeSet(
267 SourceParseMode::ProgramMode,
268 SourceParseMode::ModuleAnalyzeMode,
269 SourceParseMode::ModuleEvaluateMode).contains(parseMode);
270}
271
272ALWAYS_INLINE ConstructAbility constructAbilityForParseMode(SourceParseMode parseMode)
273{
274 if (parseMode == SourceParseMode::NormalFunctionMode)
275 return ConstructAbility::CanConstruct;
276
277 return ConstructAbility::CannotConstruct;
278}
279
280inline bool functionNameIsInScope(const Identifier& name, FunctionMode functionMode)
281{
282 if (name.isNull())
283 return false;
284
285 if (functionMode != FunctionMode::FunctionExpression)
286 return false;
287
288 return true;
289}
290
291inline bool functionNameScopeIsDynamic(bool usesEval, bool isStrictMode)
292{
293 // If non-strict eval is in play, a function gets a separate object in the scope chain for its name.
294 // This enables eval to declare and then delete a name that shadows the function's name.
295
296 if (!usesEval)
297 return false;
298
299 if (isStrictMode)
300 return false;
301
302 return true;
303}
304
305typedef uint16_t CodeFeatures;
306
307const CodeFeatures NoFeatures = 0;
308const CodeFeatures EvalFeature = 1 << 0;
309const CodeFeatures ArgumentsFeature = 1 << 1;
310const CodeFeatures WithFeature = 1 << 2;
311const CodeFeatures ThisFeature = 1 << 3;
312const CodeFeatures StrictModeFeature = 1 << 4;
313const CodeFeatures ShadowsArgumentsFeature = 1 << 5;
314const CodeFeatures ArrowFunctionFeature = 1 << 6;
315const CodeFeatures ArrowFunctionContextFeature = 1 << 7;
316const CodeFeatures SuperCallFeature = 1 << 8;
317const CodeFeatures SuperPropertyFeature = 1 << 9;
318const CodeFeatures NewTargetFeature = 1 << 10;
319const CodeFeatures NoEvalCacheFeature = 1 << 11;
320
321const CodeFeatures AllFeatures = EvalFeature | ArgumentsFeature | WithFeature | ThisFeature | StrictModeFeature | ShadowsArgumentsFeature | ArrowFunctionFeature | ArrowFunctionContextFeature |
322 SuperCallFeature | SuperPropertyFeature | NewTargetFeature | NoEvalCacheFeature;
323
324typedef uint8_t InnerArrowFunctionCodeFeatures;
325
326const InnerArrowFunctionCodeFeatures NoInnerArrowFunctionFeatures = 0;
327const InnerArrowFunctionCodeFeatures EvalInnerArrowFunctionFeature = 1 << 0;
328const InnerArrowFunctionCodeFeatures ArgumentsInnerArrowFunctionFeature = 1 << 1;
329const InnerArrowFunctionCodeFeatures ThisInnerArrowFunctionFeature = 1 << 2;
330const InnerArrowFunctionCodeFeatures SuperCallInnerArrowFunctionFeature = 1 << 3;
331const InnerArrowFunctionCodeFeatures SuperPropertyInnerArrowFunctionFeature = 1 << 4;
332const InnerArrowFunctionCodeFeatures NewTargetInnerArrowFunctionFeature = 1 << 5;
333
334const InnerArrowFunctionCodeFeatures AllInnerArrowFunctionCodeFeatures = EvalInnerArrowFunctionFeature | ArgumentsInnerArrowFunctionFeature | ThisInnerArrowFunctionFeature | SuperCallInnerArrowFunctionFeature | SuperPropertyInnerArrowFunctionFeature | NewTargetInnerArrowFunctionFeature;
335static_assert(AllInnerArrowFunctionCodeFeatures <= 0b111111, "InnerArrowFunctionCodeFeatures must be 6bits");
336} // namespace JSC
337