[JSC] Recover parser performance regression by async support
[WebKit-https.git] / Source / JavaScriptCore / parser / ParserModes.h
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
27 #ifndef ParserModes_h
28 #define ParserModes_h
29
30 #include "ConstructAbility.h"
31 #include "Identifier.h"
32
33 namespace JSC {
34
35 enum class JSParserStrictMode { NotStrict, Strict };
36 enum class JSParserBuiltinMode { NotBuiltin, Builtin };
37 enum class JSParserCodeType { Program, Function, Module };
38
39 enum class ConstructorKind { None, Base, Derived };
40 enum class SuperBinding { Needed, NotNeeded };
41
42 enum DebuggerMode { DebuggerOff, DebuggerOn };
43
44 enum class FunctionMode { FunctionExpression, FunctionDeclaration, MethodDefinition };
45
46 // When you add a new source parse mode, do not forget to ensure that the predicates defined in this
47 // file work with the newly added mode.
48 enum class SourceParseMode : uint16_t {
49     NormalFunctionMode            = 0b0000000000000001,
50     GeneratorBodyMode             = 0b0000000000000010,
51     GeneratorWrapperFunctionMode  = 0b0000000000000100,
52     GetterMode                    = 0b0000000000001000,
53     SetterMode                    = 0b0000000000010000,
54     MethodMode                    = 0b0000000000100000,
55     ArrowFunctionMode             = 0b0000000001000000,
56     AsyncFunctionBodyMode         = 0b0000000010000000,
57     AsyncArrowFunctionBodyMode    = 0b0000000100000000,
58     AsyncFunctionMode             = 0b0000001000000000,
59     AsyncMethodMode               = 0b0000010000000000,
60     AsyncArrowFunctionMode        = 0b0000100000000000,
61     ProgramMode                   = 0b0001000000000000,
62     ModuleAnalyzeMode             = 0b0010000000000000,
63     ModuleEvaluateMode            = 0b0100000000000000,
64 };
65
66 class SourceParseModeSet {
67 public:
68     template<typename... Modes>
69     SourceParseModeSet(Modes... args)
70         : m_mask(mergeSourceParseModes(args...))
71     {
72     }
73
74     ALWAYS_INLINE bool contains(SourceParseMode mode)
75     {
76         return static_cast<unsigned>(mode) & m_mask;
77     }
78
79 private:
80     ALWAYS_INLINE static unsigned mergeSourceParseModes(SourceParseMode mode)
81     {
82         return static_cast<unsigned>(mode);
83     }
84
85     template<typename... Rest>
86     ALWAYS_INLINE static unsigned mergeSourceParseModes(SourceParseMode mode, Rest... rest)
87     {
88         return static_cast<unsigned>(mode) | mergeSourceParseModes(rest...);
89     }
90
91     const unsigned m_mask;
92 };
93
94 ALWAYS_INLINE bool isFunctionParseMode(SourceParseMode parseMode)
95 {
96     return SourceParseModeSet(
97         SourceParseMode::NormalFunctionMode,
98         SourceParseMode::GeneratorBodyMode,
99         SourceParseMode::GeneratorWrapperFunctionMode,
100         SourceParseMode::GetterMode,
101         SourceParseMode::SetterMode,
102         SourceParseMode::MethodMode,
103         SourceParseMode::ArrowFunctionMode,
104         SourceParseMode::AsyncFunctionBodyMode,
105         SourceParseMode::AsyncFunctionMode,
106         SourceParseMode::AsyncMethodMode,
107         SourceParseMode::AsyncArrowFunctionMode,
108         SourceParseMode::AsyncArrowFunctionBodyMode).contains(parseMode);
109 }
110
111 ALWAYS_INLINE bool isAsyncFunctionParseMode(SourceParseMode parseMode)
112 {
113     return SourceParseModeSet(
114         SourceParseMode::AsyncFunctionBodyMode,
115         SourceParseMode::AsyncFunctionMode,
116         SourceParseMode::AsyncMethodMode,
117         SourceParseMode::AsyncArrowFunctionMode,
118         SourceParseMode::AsyncArrowFunctionBodyMode).contains(parseMode);
119 }
120
121 ALWAYS_INLINE bool isAsyncArrowFunctionParseMode(SourceParseMode parseMode)
122 {
123     return SourceParseModeSet(
124         SourceParseMode::AsyncArrowFunctionMode,
125         SourceParseMode::AsyncArrowFunctionBodyMode).contains(parseMode);
126 }
127
128 ALWAYS_INLINE bool isAsyncFunctionWrapperParseMode(SourceParseMode parseMode)
129 {
130     return SourceParseModeSet(
131         SourceParseMode::AsyncArrowFunctionMode,
132         SourceParseMode::AsyncFunctionMode,
133         SourceParseMode::AsyncMethodMode).contains(parseMode);
134 }
135
136 ALWAYS_INLINE bool isAsyncFunctionBodyParseMode(SourceParseMode parseMode)
137 {
138     return SourceParseModeSet(
139         SourceParseMode::AsyncFunctionBodyMode,
140         SourceParseMode::AsyncArrowFunctionBodyMode).contains(parseMode);
141 }
142
143 ALWAYS_INLINE bool isModuleParseMode(SourceParseMode parseMode)
144 {
145     return SourceParseModeSet(
146         SourceParseMode::ModuleAnalyzeMode,
147         SourceParseMode::ModuleEvaluateMode).contains(parseMode);
148 }
149
150 ALWAYS_INLINE bool isProgramParseMode(SourceParseMode parseMode)
151 {
152     return SourceParseModeSet(SourceParseMode::ProgramMode).contains(parseMode);
153 }
154
155 ALWAYS_INLINE ConstructAbility constructAbilityForParseMode(SourceParseMode parseMode)
156 {
157     if (parseMode == SourceParseMode::NormalFunctionMode)
158         return ConstructAbility::CanConstruct;
159     return ConstructAbility::CannotConstruct;
160 }
161
162 inline bool functionNameIsInScope(const Identifier& name, FunctionMode functionMode)
163 {
164     if (name.isNull())
165         return false;
166
167     if (functionMode != FunctionMode::FunctionExpression)
168         return false;
169
170     return true;
171 }
172
173 inline bool functionNameScopeIsDynamic(bool usesEval, bool isStrictMode)
174 {
175     // If non-strict eval is in play, a function gets a separate object in the scope chain for its name.
176     // This enables eval to declare and then delete a name that shadows the function's name.
177
178     if (!usesEval)
179         return false;
180
181     if (isStrictMode)
182         return false;
183
184     return true;
185 }
186
187 typedef uint16_t CodeFeatures;
188
189 const CodeFeatures NoFeatures =                       0;
190 const CodeFeatures EvalFeature =                 1 << 0;
191 const CodeFeatures ArgumentsFeature =            1 << 1;
192 const CodeFeatures WithFeature =                 1 << 2;
193 const CodeFeatures ThisFeature =                 1 << 3;
194 const CodeFeatures StrictModeFeature =           1 << 4;
195 const CodeFeatures ShadowsArgumentsFeature =     1 << 5;
196 const CodeFeatures ArrowFunctionFeature =        1 << 6;
197 const CodeFeatures ArrowFunctionContextFeature = 1 << 7;
198 const CodeFeatures SuperCallFeature =            1 << 8;
199 const CodeFeatures SuperPropertyFeature =        1 << 9;
200 const CodeFeatures NewTargetFeature =            1 << 10;
201
202 const CodeFeatures AllFeatures = EvalFeature | ArgumentsFeature | WithFeature | ThisFeature | StrictModeFeature | ShadowsArgumentsFeature | ArrowFunctionFeature | ArrowFunctionContextFeature |
203     SuperCallFeature | SuperPropertyFeature | NewTargetFeature;
204
205 typedef uint8_t InnerArrowFunctionCodeFeatures;
206     
207 const InnerArrowFunctionCodeFeatures NoInnerArrowFunctionFeatures =                0;
208 const InnerArrowFunctionCodeFeatures EvalInnerArrowFunctionFeature =          1 << 0;
209 const InnerArrowFunctionCodeFeatures ArgumentsInnerArrowFunctionFeature =     1 << 1;
210 const InnerArrowFunctionCodeFeatures ThisInnerArrowFunctionFeature =          1 << 2;
211 const InnerArrowFunctionCodeFeatures SuperCallInnerArrowFunctionFeature =     1 << 3;
212 const InnerArrowFunctionCodeFeatures SuperPropertyInnerArrowFunctionFeature = 1 << 4;
213 const InnerArrowFunctionCodeFeatures NewTargetInnerArrowFunctionFeature =     1 << 5;
214     
215 const InnerArrowFunctionCodeFeatures AllInnerArrowFunctionCodeFeatures = EvalInnerArrowFunctionFeature | ArgumentsInnerArrowFunctionFeature | ThisInnerArrowFunctionFeature | SuperCallInnerArrowFunctionFeature | SuperPropertyInnerArrowFunctionFeature | NewTargetInnerArrowFunctionFeature;
216 } // namespace JSC
217
218 #endif // ParserModes_h