1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2  * vim: set ts=8 sts=2 et sw=2 tw=80:
3  * This Source Code Form is subject to the terms of the Mozilla Public
4  * License, v. 2.0. If a copy of the MPL was not distributed with this
5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 
7 #ifndef vm_StencilEnums_h
8 #define vm_StencilEnums_h
9 
10 #include <stdint.h>  // uint8_t
11 
12 //
13 // Enum definitions shared between frontend, stencil, and the VM.
14 //
15 
16 namespace js {
17 
18 // [SMDOC] Try Notes
19 //
20 // Trynotes are attached to regions that are involved with
21 // exception unwinding. They can be broken up into four categories:
22 //
23 // 1. Catch and Finally: Basic exception handling. A Catch trynote
24 //    covers the range of the associated try. A Finally trynote covers
25 //    the try and the catch.
26 //
27 // 2. ForIn and Destructuring: These operations create an iterator
28 //    which must be cleaned up (by calling IteratorClose) during
29 //    exception unwinding.
30 //
31 // 3. ForOf and ForOfIterclose: For-of loops handle unwinding using
32 //    catch blocks. These trynotes are used for for-of breaks/returns,
33 //    which create regions that are lexically within a for-of block,
34 //    but logically outside of it. See TryNoteIter::settle for more
35 //    details.
36 //
37 // 4. Loop: This represents normal for/while/do-while loops. It is
38 //    unnecessary for exception unwinding, but storing the boundaries
39 //    of loops here is helpful for heuristics that need to know
40 //    whether a given op is inside a loop.
41 enum class TryNoteKind : uint8_t {
42   Catch,
43   Finally,
44   ForIn,
45   Destructuring,
46   ForOf,
47   ForOfIterClose,
48   Loop
49 };
50 
51 // [SMDOC] Script Flags
52 //
53 // Interpreted scripts represented by the BaseScript type use two flag words to
54 // encode an assortment of conditions and attributes about the script.
55 //
56 // The "immutable" flags are a combination of input flags describing aspects of
57 // the execution context that affect parsing (such as if we are an ES module or
58 // normal script), and flags derived from source text. These flags are preserved
59 // during cloning and serializing. As well, they should never change after the
60 // BaseScript is created (although there are currently a few exceptions for
61 // de-/re-lazification that remain).
62 //
63 // The "mutable" flags are temporary flags that are used by subsystems in the
64 // engine such as the debugger or JITs. These flags are not preserved through
65 // serialization or cloning since the attributes are generally associated with
66 // one specific instance of a BaseScript.
67 
68 enum class ImmutableScriptFlagsEnum : uint32_t {
69   // Input Flags
70   //
71   // These flags are from CompileOptions or the Parser entry point. They
72   // generally cannot be derived from the source text alone.
73   // ----
74 
75   // A script may have one of the following kinds: Global, Eval, Module,
76   // Function. At most one flag can be set, with a default of Global.
77   IsForEval = 1 << 0,
78   IsModule = 1 << 1,
79   IsFunction = 1 << 2,
80 
81   // The script is compiled as engine-internal self-hosted JavaScript. This mode
82   // is used to implement certain library functions and has special parse,
83   // bytecode, and runtime behaviour that differs from normal script.
84   SelfHosted = 1 << 3,
85 
86   // The script was compiled with the default mode set to strict mode. Note that
87   // this tracks the default value, while the actual mode used (after processing
88   // source and its directives) is the `Strict` flag below.
89   ForceStrict = 1 << 4,
90 
91   // The script has a non-syntactic scope on its environment chain. That is,
92   // there may be objects about which we know nothing between the outermost
93   // syntactic scope and the global.
94   HasNonSyntacticScope = 1 << 5,
95 
96   // The script return value will not be used and simplified code will be
97   // generated. This can only be applied to top-level scripts. The value this
98   // script returns will be UndefinedValue instead of what the spec normally
99   // prescribes.
100   NoScriptRval = 1 << 6,
101 
102   // TreatAsRunOnce roughly indicates that a script is expected to be run no
103   // more than once. This affects optimizations and heuristics.
104   //
105   // On top-level global/eval/module scripts, this is set when the embedding
106   // ensures this script will not be re-used. In this case, parser literals may
107   // be exposed directly instead of being cloned.
108   TreatAsRunOnce = 1 << 7,
109   // ----
110 
111   // Parser Flags
112   //
113   // Flags computed by the Parser from the source text and input flags.
114   // ----
115 
116   // Generated code will execute in strict mode. This is due to either the
117   // ForceStrict flag being specified above, or due to source text itself (such
118   // as "use strict" directives).
119   Strict = 1 << 8,
120 
121   // Script is parsed with a top-level goal of Module. This may be a top-level
122   // or an inner-function script.
123   HasModuleGoal = 1 << 9,
124 
125   // Script contains inner functions.
126   //
127   // Note: This prevents relazification since inner function close-over the
128   // current scripts scopes.
129   HasInnerFunctions = 1 << 10,
130 
131   // There is a direct eval statement in this script OR in any of its inner
132   // functions.
133   //
134   // Note: This prevents relazification since it can introduce inner functions.
135   HasDirectEval = 1 << 11,
136 
137   // The (static) bindings of this script must support dynamic name access for
138   // read/write. The environment chain is used to do these dynamic lookups and
139   // optimizations to avoid allocating environments are suppressed.
140   //
141   // This includes direct-eval, `with`, and `delete` in this script OR in any of
142   // its inner functions.
143   //
144   // Note: Access through the arguments object is not considered dynamic binding
145   // access since it does not go through the normal name lookup mechanism.
146   BindingsAccessedDynamically = 1 << 12,
147 
148   // A tagged template exists in the body (which will use JSOp::CallSiteObj in
149   // bytecode).
150   //
151   // Note: This prevents relazification since the template's object is
152   // observable to the user and cannot be recreated.
153   HasCallSiteObj = 1 << 13,
154 
155   // Parser Flags for Functions
156   // ----
157 
158   // This function's initial prototype is one of Function, GeneratorFunction,
159   // AsyncFunction, or AsyncGeneratorFunction as indicated by these flags.
160   //
161   // If either of these flags is set, the script may suspend and resume as it
162   // executes. Stack frames for this script also have a generator object.
163   IsAsync = 1 << 14,
164   IsGenerator = 1 << 15,
165 
166   // This function's body serves as the `var` environment for a non-strict
167   // direct eval. This matters because it's the only way bindings can be
168   // dynamically added to a local environment, possibly shadowing other
169   // variables.
170   FunHasExtensibleScope = 1 << 16,
171 
172   // This function has an internal .this binding and we need to emit
173   // JSOp::FunctionThis in the prologue to initialize it. This binding may be
174   // used directly for "this", or indirectly (such as class constructors).
175   FunctionHasThisBinding = 1 << 17,
176 
177   // This function is a class method that must uses an internal [[HomeObject]]
178   // slot. This slot is initialized when the class definition is executed in the
179   // enclosing function.
180   NeedsHomeObject = 1 << 18,
181 
182   // This function is a constructor for a derived class. This is a class that
183   // uses the `extends` syntax.
184   IsDerivedClassConstructor = 1 << 19,
185 
186   // This function is synthesized by the Parser. This is used for field
187   // initializer lambdas and missing constructors for classes. These functions
188   // have unusual source coordinates and may be hidden from things like
189   // Reflect.parse.
190   IsSyntheticFunction = 1 << 20,
191 
192   // This function is a class constructor that has MemberInitializer data
193   // associated with it.
194   UseMemberInitializers = 1 << 21,
195 
196   // This function has a rest (`...`) parameter.
197   HasRest = 1 << 22,
198 
199   // This function needs a call object or named lambda environment to be created
200   // in order to execute the function. This is done in the Stack or JIT frame
201   // setup code _before_ the bytecode prologue starts.
202   NeedsFunctionEnvironmentObjects = 1 << 23,
203 
204   // An extra VarScope is used as the body scope instead of the normal
205   // FunctionScope. This is needed when parameter expressions are used AND the
206   // function has var bindings or a sloppy-direct-eval. For example,
207   //    `function(x = eval("")) { var y; }`
208   FunctionHasExtraBodyVarScope = 1 << 24,
209 
210   // This function must define the implicit `arguments` binding on the function
211   // scope. If there are no free uses or an appropriate explicit binding exists,
212   // then this flag is unset.
213   //
214   // Note: Parameter expressions will not see an explicit `var arguments;`
215   // binding in the body and an implicit binding on the function-scope must
216   // still be used in that case.
217   ShouldDeclareArguments = 1 << 25,
218 
219   // This function has a local (implicit or explicit) `arguments` binding. This
220   // binding is initialized by the JSOp::Arguments bytecode.
221   //
222   // Technically, every function has a binding named `arguments`. Internally,
223   // this binding is only added when `arguments` is mentioned by the function
224   // body.
225   //
226   // Examples:
227   //   ```
228   //    // Explicit definition
229   //    function f() { var arguments; return arguments; }
230   //
231   //    // Implicit use
232   //    function f() { return arguments; }
233   //
234   //    // Implicit use in arrow function
235   //    function f() { return () => arguments; }
236   //
237   //    // Implicit use in parameter expression
238   //    function f(a = arguments) { return a; }
239   //   ```
240   NeedsArgsObj = 1 << 26,
241 
242   // This function must use the "mapped" form of an arguments object. This flag
243   // is set independently of whether we actually use an `arguments` binding. The
244   // conditions are specified in the ECMAScript spec.
245   HasMappedArgsObj = 1 << 27,
246 
247   // Large self-hosted methods that should be inlined anyway by the JIT for
248   // performance reasons can be marked with this flag.
249   IsInlinableLargeFunction = 1 << 28,
250 };
251 
252 enum class MutableScriptFlagsEnum : uint32_t {
253   // Number of times the |warmUpCount| was forcibly discarded. The counter is
254   // reset when a script is successfully jit-compiled.
255   WarmupResets_MASK = 0xFF,
256 
257   // If treatAsRunOnce, whether script has executed.
258   HasRunOnce = 1 << 8,
259 
260   // Script has been reused for a clone.
261   HasBeenCloned = 1 << 9,
262 
263   // Script has an entry in Realm::scriptCountsMap.
264   HasScriptCounts = 1 << 10,
265 
266   // Script has an entry in Realm::debugScriptMap.
267   HasDebugScript = 1 << 11,
268 
269   // (1 << 12) is unused.
270   // (1 << 13) is unused.
271 
272   // Script supports relazification where it releases bytecode and gcthings to
273   // save memory. This process is opt-in since various complexities may disallow
274   // this for some scripts.
275   // NOTE: Must check for isRelazifiable() before setting this flag.
276   AllowRelazify = 1 << 14,
277 
278   // Set if the script has opted into spew.
279   SpewEnabled = 1 << 15,
280 
281   // Set if we care about a script's final warmup count.
282   NeedsFinalWarmUpCount = 1 << 16,
283 
284   //
285   // IonMonkey compilation hints.
286   //
287 
288   // Whether Baseline or Ion compilation has been disabled for this script.
289   // IonDisabled is equivalent to |jitScript->canIonCompile() == false| but
290   // JitScript can be discarded on GC and we don't want this to affect
291   // observable behavior (see ArgumentsGetterImpl comment).
292   BaselineDisabled = 1 << 17,
293   IonDisabled = 1 << 18,
294 
295   // This script should not be inlined into others. This happens after inlining
296   // has failed.
297   Uninlineable = 1 << 19,
298 
299   // (1 << 20) is unused.
300 
301   // *****************************************************************
302   // The flags below are set when we bail out and invalidate a script.
303   // When we recompile, we will be more conservative.
304   // *****************************************************************
305 
306   // A hoisted bounds check bailed out.
307   FailedBoundsCheck = 1 << 21,
308 
309   // An instruction hoisted by LICM bailed out.
310   HadLICMInvalidation = 1 << 22,
311 
312   // An instruction hoisted by InstructionReordering bailed out.
313   HadReorderingBailout = 1 << 23,
314 
315   // An instruction inserted or truncated by Range Analysis bailed out.
316   HadEagerTruncationBailout = 1 << 24,
317 
318   // A lexical check bailed out.
319   FailedLexicalCheck = 1 << 25,
320 
321   // A guard inserted by phi specialization bailed out.
322   HadSpeculativePhiBailout = 1 << 26,
323 
324   // An unbox folded with a load bailed out.
325   HadUnboxFoldingBailout = 1 << 27,
326 };
327 
328 }  // namespace js
329 
330 #endif /* vm_StencilEnums_h */
331