Scopes that are not under TDZ should still push their variables onto the TDZ stack...
[WebKit-https.git] / Source / JavaScriptCore / bytecompiler / BytecodeGenerator.h
1 /*
2  * Copyright (C) 2008-2009, 2012-2016 Apple Inc. All rights reserved.
3  * Copyright (C) 2008 Cameron Zwarich <cwzwarich@uwaterloo.ca>
4  * Copyright (C) 2012 Igalia, S.L.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  *
10  * 1.  Redistributions of source code must retain the above copyright
11  *     notice, this list of conditions and the following disclaimer.
12  * 2.  Redistributions in binary form must reproduce the above copyright
13  *     notice, this list of conditions and the following disclaimer in the
14  *     documentation and/or other materials provided with the distribution.
15  * 3.  Neither the name of Apple Inc. ("Apple") nor the names of
16  *     its contributors may be used to endorse or promote products derived
17  *     from this software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
20  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
23  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
26  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30
31 #ifndef BytecodeGenerator_h
32 #define BytecodeGenerator_h
33
34 #include "CodeBlock.h"
35 #include <wtf/HashTraits.h>
36 #include "Instruction.h"
37 #include "Label.h"
38 #include "LabelScope.h"
39 #include "Interpreter.h"
40 #include "ParserError.h"
41 #include "RegisterID.h"
42 #include "SetForScope.h"
43 #include "SymbolTable.h"
44 #include "Debugger.h"
45 #include "Nodes.h"
46 #include "StaticPropertyAnalyzer.h"
47 #include "TemplateRegistryKey.h"
48 #include "UnlinkedCodeBlock.h"
49
50 #include <functional>
51
52 #include <wtf/PassRefPtr.h>
53 #include <wtf/SegmentedVector.h>
54 #include <wtf/Vector.h>
55
56
57 namespace JSC {
58
59     class Identifier;
60     class JSTemplateRegistryKey;
61
62     enum ExpectedFunction {
63         NoExpectedFunction,
64         ExpectObjectConstructor,
65         ExpectArrayConstructor
66     };
67
68     enum class ThisResolutionType { Local, Scoped };
69     
70     class CallArguments {
71     public:
72         CallArguments(BytecodeGenerator&, ArgumentsNode*, unsigned additionalArguments = 0);
73
74         RegisterID* thisRegister() { return m_argv[0].get(); }
75         RegisterID* argumentRegister(unsigned i) { return m_argv[i + 1].get(); }
76         unsigned stackOffset() { return -m_argv[0]->index() + JSStack::CallFrameHeaderSize; }
77         unsigned argumentCountIncludingThis() { return m_argv.size() - m_padding; }
78         ArgumentsNode* argumentsNode() { return m_argumentsNode; }
79
80     private:
81         ArgumentsNode* m_argumentsNode;
82         Vector<RefPtr<RegisterID>, 8, UnsafeVectorOverflow> m_argv;
83         unsigned m_padding;
84     };
85
86     struct FinallyContext {
87         StatementNode* finallyBlock;
88         RegisterID* iterator;
89         ThrowableExpressionData* enumerationNode;
90         unsigned scopeContextStackSize;
91         unsigned switchContextStackSize;
92         unsigned forInContextStackSize;
93         unsigned tryContextStackSize;
94         unsigned labelScopesSize;
95         unsigned symbolTableStackSize;
96         int finallyDepth;
97         int dynamicScopeDepth;
98     };
99
100     struct ControlFlowContext {
101         bool isFinallyBlock;
102         FinallyContext finallyContext;
103     };
104
105     class ForInContext : public RefCounted<ForInContext> {
106         WTF_MAKE_FAST_ALLOCATED;
107         WTF_MAKE_NONCOPYABLE(ForInContext);
108     public:
109         ForInContext(RegisterID* localRegister)
110             : m_localRegister(localRegister)
111             , m_isValid(true)
112         {
113         }
114
115         virtual ~ForInContext()
116         {
117         }
118
119         bool isValid() const { return m_isValid; }
120         void invalidate() { m_isValid = false; }
121
122         enum ForInContextType {
123             StructureForInContextType,
124             IndexedForInContextType
125         };
126         virtual ForInContextType type() const = 0;
127
128         RegisterID* local() const { return m_localRegister.get(); }
129
130     private:
131         RefPtr<RegisterID> m_localRegister;
132         bool m_isValid;
133     };
134
135     class StructureForInContext : public ForInContext {
136     public:
137         StructureForInContext(RegisterID* localRegister, RegisterID* indexRegister, RegisterID* propertyRegister, RegisterID* enumeratorRegister)
138             : ForInContext(localRegister)
139             , m_indexRegister(indexRegister)
140             , m_propertyRegister(propertyRegister)
141             , m_enumeratorRegister(enumeratorRegister)
142         {
143         }
144
145         virtual ForInContextType type() const
146         {
147             return StructureForInContextType;
148         }
149
150         RegisterID* index() const { return m_indexRegister.get(); }
151         RegisterID* property() const { return m_propertyRegister.get(); }
152         RegisterID* enumerator() const { return m_enumeratorRegister.get(); }
153
154     private:
155         RefPtr<RegisterID> m_indexRegister;
156         RefPtr<RegisterID> m_propertyRegister;
157         RefPtr<RegisterID> m_enumeratorRegister;
158     };
159
160     class IndexedForInContext : public ForInContext {
161     public:
162         IndexedForInContext(RegisterID* localRegister, RegisterID* indexRegister)
163             : ForInContext(localRegister)
164             , m_indexRegister(indexRegister)
165         {
166         }
167
168         virtual ForInContextType type() const
169         {
170             return IndexedForInContextType;
171         }
172
173         RegisterID* index() const { return m_indexRegister.get(); }
174
175     private:
176         RefPtr<RegisterID> m_indexRegister;
177     };
178
179     struct TryData {
180         RefPtr<Label> target;
181         HandlerType handlerType;
182     };
183
184     struct TryContext {
185         RefPtr<Label> start;
186         TryData* tryData;
187     };
188
189     class Variable {
190     public:
191         enum VariableKind { NormalVariable, SpecialVariable };
192
193         Variable()
194             : m_offset()
195             , m_local(nullptr)
196             , m_attributes(0)
197             , m_kind(NormalVariable)
198             , m_symbolTableConstantIndex(0) // This is meaningless here for this kind of Variable.
199             , m_isLexicallyScoped(false)
200         {
201         }
202         
203         Variable(const Identifier& ident)
204             : m_ident(ident)
205             , m_local(nullptr)
206             , m_attributes(0)
207             , m_kind(NormalVariable) // This is somewhat meaningless here for this kind of Variable.
208             , m_symbolTableConstantIndex(0) // This is meaningless here for this kind of Variable.
209             , m_isLexicallyScoped(false)
210         {
211         }
212
213         Variable(const Identifier& ident, VarOffset offset, RegisterID* local, unsigned attributes, VariableKind kind, int symbolTableConstantIndex, bool isLexicallyScoped)
214             : m_ident(ident)
215             , m_offset(offset)
216             , m_local(local)
217             , m_attributes(attributes)
218             , m_kind(kind)
219             , m_symbolTableConstantIndex(symbolTableConstantIndex)
220             , m_isLexicallyScoped(isLexicallyScoped)
221         {
222         }
223
224         // If it's unset, then it is a non-locally-scoped variable. If it is set, then it could be
225         // a stack variable, a scoped variable in a local scope, or a variable captured in the
226         // direct arguments object.
227         bool isResolved() const { return !!m_offset; }
228         int symbolTableConstantIndex() const { ASSERT(isResolved() && !isSpecial()); return m_symbolTableConstantIndex; }
229         
230         const Identifier& ident() const { return m_ident; }
231         
232         VarOffset offset() const { return m_offset; }
233         bool isLocal() const { return m_offset.isStack(); }
234         RegisterID* local() const { return m_local; }
235
236         bool isReadOnly() const { return m_attributes & ReadOnly; }
237         bool isSpecial() const { return m_kind != NormalVariable; }
238         bool isConst() const { return isReadOnly() && m_isLexicallyScoped; }
239         void setIsReadOnly() { m_attributes |= ReadOnly; }
240
241         void dump(PrintStream&) const;
242
243     private:
244         Identifier m_ident;
245         VarOffset m_offset;
246         RegisterID* m_local;
247         unsigned m_attributes;
248         VariableKind m_kind;
249         int m_symbolTableConstantIndex;
250         bool m_isLexicallyScoped;
251     };
252
253     struct TryRange {
254         RefPtr<Label> start;
255         RefPtr<Label> end;
256         TryData* tryData;
257     };
258
259     enum ProfileTypeBytecodeFlag {
260         ProfileTypeBytecodeClosureVar,
261         ProfileTypeBytecodeLocallyResolved,
262         ProfileTypeBytecodeDoesNotHaveGlobalID,
263         ProfileTypeBytecodeFunctionArgument,
264         ProfileTypeBytecodeFunctionReturnStatement
265     };
266
267     class BytecodeGenerator {
268         WTF_MAKE_FAST_ALLOCATED;
269         WTF_MAKE_NONCOPYABLE(BytecodeGenerator);
270     public:
271         typedef DeclarationStacks::FunctionStack FunctionStack;
272
273         BytecodeGenerator(VM&, ProgramNode*, UnlinkedProgramCodeBlock*, DebuggerMode, const VariableEnvironment*);
274         BytecodeGenerator(VM&, FunctionNode*, UnlinkedFunctionCodeBlock*, DebuggerMode, const VariableEnvironment*);
275         BytecodeGenerator(VM&, EvalNode*, UnlinkedEvalCodeBlock*, DebuggerMode, const VariableEnvironment*);
276         BytecodeGenerator(VM&, ModuleProgramNode*, UnlinkedModuleProgramCodeBlock*, DebuggerMode, const VariableEnvironment*);
277
278         ~BytecodeGenerator();
279         
280         VM* vm() const { return m_vm; }
281         ParserArena& parserArena() const { return m_scopeNode->parserArena(); }
282         const CommonIdentifiers& propertyNames() const { return *m_vm->propertyNames; }
283
284         bool isConstructor() const { return m_codeBlock->isConstructor(); }
285         DerivedContextType derivedContextType() const { return m_derivedContextType; }
286         bool usesArrowFunction() const { return m_scopeNode->usesArrowFunction(); }
287         bool needsToUpdateArrowFunctionContext() const { return m_needsToUpdateArrowFunctionContext; }
288         bool usesEval() const { return m_scopeNode->usesEval(); }
289         bool usesThis() const { return m_scopeNode->usesThis(); }
290         ConstructorKind constructorKind() const { return m_codeBlock->constructorKind(); }
291         SuperBinding superBinding() const { return m_codeBlock->superBinding(); }
292
293         template<typename... Args>
294         static ParserError generate(VM& vm, Args&& ...args)
295         {
296             DeferGC deferGC(vm.heap);
297             auto bytecodeGenerator = std::make_unique<BytecodeGenerator>(vm, std::forward<Args>(args)...);
298             return bytecodeGenerator->generate(); 
299         }
300
301         bool isArgumentNumber(const Identifier&, int);
302
303         Variable variable(const Identifier&, ThisResolutionType = ThisResolutionType::Local);
304         
305         enum ExistingVariableMode { VerifyExisting, IgnoreExisting };
306         void createVariable(const Identifier&, VarKind, SymbolTable*, ExistingVariableMode = VerifyExisting); // Creates the variable, or asserts that the already-created variable is sufficiently compatible.
307         
308         // Returns the register storing "this"
309         RegisterID* thisRegister() { return &m_thisRegister; }
310         RegisterID* argumentsRegister() { return m_argumentsRegister; }
311         RegisterID* newTarget()
312         {
313             return m_newTargetRegister;
314         }
315
316         RegisterID* scopeRegister() { return m_scopeRegister; }
317
318         RegisterID* generatorRegister() { return m_generatorRegister; }
319
320         // Returns the next available temporary register. Registers returned by
321         // newTemporary require a modified form of reference counting: any
322         // register with a refcount of 0 is considered "available", meaning that
323         // the next instruction may overwrite it.
324         RegisterID* newTemporary();
325
326         // The same as newTemporary(), but this function returns "suggestion" if
327         // "suggestion" is a temporary. This function is helpful in situations
328         // where you've put "suggestion" in a RefPtr, but you'd like to allow
329         // the next instruction to overwrite it anyway.
330         RegisterID* newTemporaryOr(RegisterID* suggestion) { return suggestion->isTemporary() ? suggestion : newTemporary(); }
331
332         // Functions for handling of dst register
333
334         RegisterID* ignoredResult() { return &m_ignoredResultRegister; }
335
336         // This will be allocated in the temporary region of registers, but it will
337         // not be marked as a temporary. This will ensure that finalDestination() does
338         // not overwrite a block scope variable that it mistakes as a temporary. These
339         // registers can be (and are) reclaimed when the lexical scope they belong to
340         // is no longer on the symbol table stack.
341         RegisterID* newBlockScopeVariable();
342
343         // Returns a place to write intermediate values of an operation
344         // which reuses dst if it is safe to do so.
345         RegisterID* tempDestination(RegisterID* dst)
346         {
347             return (dst && dst != ignoredResult() && dst->isTemporary()) ? dst : newTemporary();
348         }
349
350         // Returns the place to write the final output of an operation.
351         RegisterID* finalDestination(RegisterID* originalDst, RegisterID* tempDst = 0)
352         {
353             if (originalDst && originalDst != ignoredResult())
354                 return originalDst;
355             ASSERT(tempDst != ignoredResult());
356             if (tempDst && tempDst->isTemporary())
357                 return tempDst;
358             return newTemporary();
359         }
360
361         RegisterID* destinationForAssignResult(RegisterID* dst)
362         {
363             if (dst && dst != ignoredResult())
364                 return dst->isTemporary() ? dst : newTemporary();
365             return 0;
366         }
367
368         // Moves src to dst if dst is not null and is different from src, otherwise just returns src.
369         RegisterID* moveToDestinationIfNeeded(RegisterID* dst, RegisterID* src)
370         {
371             return dst == ignoredResult() ? 0 : (dst && dst != src) ? emitMove(dst, src) : src;
372         }
373
374         LabelScopePtr newLabelScope(LabelScope::Type, const Identifier* = 0);
375         PassRefPtr<Label> newLabel();
376
377         void emitNode(RegisterID* dst, StatementNode* n)
378         {
379             SetForScope<bool> tailPositionPoisoner(m_inTailPosition, false);
380             return emitNodeInTailPosition(dst, n);
381         }
382
383         void emitNodeInTailPosition(RegisterID* dst, StatementNode* n)
384         {
385             // Node::emitCode assumes that dst, if provided, is either a local or a referenced temporary.
386             ASSERT(!dst || dst == ignoredResult() || !dst->isTemporary() || dst->refCount());
387             if (!m_vm->isSafeToRecurse()) {
388                 emitThrowExpressionTooDeepException();
389                 return;
390             }
391             n->emitBytecode(*this, dst);
392         }
393
394         void emitNode(StatementNode* n)
395         {
396             emitNode(nullptr, n);
397         }
398
399         void emitNodeInTailPosition(StatementNode* n)
400         {
401             emitNodeInTailPosition(nullptr, n);
402         }
403
404         RegisterID* emitNode(RegisterID* dst, ExpressionNode* n)
405         {
406             SetForScope<bool> tailPositionPoisoner(m_inTailPosition, false);
407             return emitNodeInTailPosition(dst, n);
408         }
409
410         RegisterID* emitNodeInTailPosition(RegisterID* dst, ExpressionNode* n)
411         {
412             // Node::emitCode assumes that dst, if provided, is either a local or a referenced temporary.
413             ASSERT(!dst || dst == ignoredResult() || !dst->isTemporary() || dst->refCount());
414             if (!m_vm->isSafeToRecurse())
415                 return emitThrowExpressionTooDeepException();
416             return n->emitBytecode(*this, dst);
417         }
418
419         RegisterID* emitNode(ExpressionNode* n)
420         {
421             return emitNode(nullptr, n);
422         }
423
424         RegisterID* emitNodeInTailPosition(ExpressionNode* n)
425         {
426             return emitNodeInTailPosition(nullptr, n);
427         }
428
429         void emitNodeInConditionContext(ExpressionNode* n, Label* trueTarget, Label* falseTarget, FallThroughMode fallThroughMode)
430         {
431             if (!m_vm->isSafeToRecurse()) {
432                 emitThrowExpressionTooDeepException();
433                 return;
434             }
435
436             n->emitBytecodeInConditionContext(*this, trueTarget, falseTarget, fallThroughMode);
437         }
438
439         void emitExpressionInfo(const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd)
440         {            
441             ASSERT(divot.offset >= divotStart.offset);
442             ASSERT(divotEnd.offset >= divot.offset);
443
444             int sourceOffset = m_scopeNode->source().startOffset();
445             unsigned firstLine = m_scopeNode->source().firstLine();
446
447             int divotOffset = divot.offset - sourceOffset;
448             int startOffset = divot.offset - divotStart.offset;
449             int endOffset = divotEnd.offset - divot.offset;
450
451             unsigned line = divot.line;
452             ASSERT(line >= firstLine);
453             line -= firstLine;
454
455             int lineStart = divot.lineStartOffset;
456             if (lineStart > sourceOffset)
457                 lineStart -= sourceOffset;
458             else
459                 lineStart = 0;
460
461             if (divotOffset < lineStart)
462                 return;
463
464             unsigned column = divotOffset - lineStart;
465
466             unsigned instructionOffset = instructions().size();
467             if (!m_isBuiltinFunction)
468                 m_codeBlock->addExpressionInfo(instructionOffset, divotOffset, startOffset, endOffset, line, column);
469         }
470
471
472         ALWAYS_INLINE bool leftHandSideNeedsCopy(bool rightHasAssignments, bool rightIsPure)
473         {
474             return (m_codeType != FunctionCode || rightHasAssignments) && !rightIsPure;
475         }
476
477         ALWAYS_INLINE PassRefPtr<RegisterID> emitNodeForLeftHandSide(ExpressionNode* n, bool rightHasAssignments, bool rightIsPure)
478         {
479             if (leftHandSideNeedsCopy(rightHasAssignments, rightIsPure)) {
480                 PassRefPtr<RegisterID> dst = newTemporary();
481                 emitNode(dst.get(), n);
482                 return dst;
483             }
484
485             return emitNode(n);
486         }
487
488         void hoistSloppyModeFunctionIfNecessary(const Identifier& functionName);
489
490     private:
491         void emitTypeProfilerExpressionInfo(const JSTextPosition& startDivot, const JSTextPosition& endDivot);
492     public:
493
494         // This doesn't emit expression info. If using this, make sure you shouldn't be emitting text offset.
495         void emitProfileType(RegisterID* registerToProfile, ProfileTypeBytecodeFlag); 
496         // These variables are associated with variables in a program. They could be Locals, LocalClosureVar, or ClosureVar.
497         void emitProfileType(RegisterID* registerToProfile, const Variable&, const JSTextPosition& startDivot, const JSTextPosition& endDivot);
498
499         void emitProfileType(RegisterID* registerToProfile, ProfileTypeBytecodeFlag, const JSTextPosition& startDivot, const JSTextPosition& endDivot);
500         // These are not associated with variables and don't have a global id.
501         void emitProfileType(RegisterID* registerToProfile, const JSTextPosition& startDivot, const JSTextPosition& endDivot);
502
503         void emitProfileControlFlow(int);
504         
505         RegisterID* emitLoadArrowFunctionLexicalEnvironment(const Identifier&);
506         RegisterID* ensureThis();
507         void emitLoadThisFromArrowFunctionLexicalEnvironment();
508         RegisterID* emitLoadNewTargetFromArrowFunctionLexicalEnvironment();
509
510         RegisterID* emitLoad(RegisterID* dst, bool);
511         RegisterID* emitLoad(RegisterID* dst, const Identifier&);
512         RegisterID* emitLoad(RegisterID* dst, JSValue, SourceCodeRepresentation = SourceCodeRepresentation::Other);
513         RegisterID* emitLoadGlobalObject(RegisterID* dst);
514
515         RegisterID* emitUnaryOp(OpcodeID, RegisterID* dst, RegisterID* src);
516         RegisterID* emitUnaryOpProfiled(OpcodeID, RegisterID* dst, RegisterID* src);
517         RegisterID* emitBinaryOp(OpcodeID, RegisterID* dst, RegisterID* src1, RegisterID* src2, OperandTypes);
518         RegisterID* emitEqualityOp(OpcodeID, RegisterID* dst, RegisterID* src1, RegisterID* src2);
519         RegisterID* emitUnaryNoDstOp(OpcodeID, RegisterID* src);
520
521         RegisterID* emitCreateThis(RegisterID* dst);
522         void emitTDZCheck(RegisterID* target);
523         bool needsTDZCheck(const Variable&);
524         void emitTDZCheckIfNecessary(const Variable&, RegisterID* target, RegisterID* scope);
525         void liftTDZCheckIfPossible(const Variable&);
526         RegisterID* emitNewObject(RegisterID* dst);
527         RegisterID* emitNewArray(RegisterID* dst, ElementNode*, unsigned length); // stops at first elision
528         RegisterID* emitNewArrayWithSize(RegisterID* dst, RegisterID* length);
529
530         RegisterID* emitNewFunction(RegisterID* dst, FunctionMetadataNode*);
531         RegisterID* emitNewFunctionExpression(RegisterID* dst, FuncExprNode*);
532         RegisterID* emitNewDefaultConstructor(RegisterID* dst, ConstructorKind, const Identifier& name, const Identifier& ecmaName, const SourceCode& classSource);
533         RegisterID* emitNewArrowFunctionExpression(RegisterID*, ArrowFuncExprNode*);
534         RegisterID* emitNewMethodDefinition(RegisterID* dst, MethodDefinitionNode*);
535         RegisterID* emitNewRegExp(RegisterID* dst, RegExp*);
536
537         void emitSetFunctionNameIfNeeded(ExpressionNode* valueNode, RegisterID* value, RegisterID* name);
538
539         RegisterID* emitMoveLinkTimeConstant(RegisterID* dst, LinkTimeConstant);
540         RegisterID* emitMoveEmptyValue(RegisterID* dst);
541         RegisterID* emitMove(RegisterID* dst, RegisterID* src);
542
543         RegisterID* emitToNumber(RegisterID* dst, RegisterID* src) { return emitUnaryOpProfiled(op_to_number, dst, src); }
544         RegisterID* emitToString(RegisterID* dst, RegisterID* src) { return emitUnaryOp(op_to_string, dst, src); }
545         RegisterID* emitInc(RegisterID* srcDst);
546         RegisterID* emitDec(RegisterID* srcDst);
547
548         RegisterID* emitOverridesHasInstance(RegisterID* dst, RegisterID* constructor, RegisterID* hasInstanceValue);
549         RegisterID* emitInstanceOf(RegisterID* dst, RegisterID* value, RegisterID* basePrototype);
550         RegisterID* emitInstanceOfCustom(RegisterID* dst, RegisterID* value, RegisterID* constructor, RegisterID* hasInstanceValue);
551         RegisterID* emitTypeOf(RegisterID* dst, RegisterID* src) { return emitUnaryOp(op_typeof, dst, src); }
552         RegisterID* emitIn(RegisterID* dst, RegisterID* property, RegisterID* base) { return emitBinaryOp(op_in, dst, property, base, OperandTypes()); }
553
554         RegisterID* emitTryGetById(RegisterID* dst, RegisterID* base, const Identifier& property);
555         RegisterID* emitGetById(RegisterID* dst, RegisterID* base, const Identifier& property);
556         RegisterID* emitGetById(RegisterID* dst, RegisterID* base, RegisterID* thisVal, const Identifier& property);
557         RegisterID* emitPutById(RegisterID* base, const Identifier& property, RegisterID* value);
558         RegisterID* emitPutById(RegisterID* base, RegisterID* thisValue, const Identifier& property, RegisterID* value);
559         RegisterID* emitDirectPutById(RegisterID* base, const Identifier& property, RegisterID* value, PropertyNode::PutType);
560         RegisterID* emitDeleteById(RegisterID* dst, RegisterID* base, const Identifier&);
561         RegisterID* emitGetByVal(RegisterID* dst, RegisterID* base, RegisterID* property);
562         RegisterID* emitGetByVal(RegisterID* dst, RegisterID* base, RegisterID* thisValue, RegisterID* property);
563         RegisterID* emitGetArgumentByVal(RegisterID* dst, RegisterID* base, RegisterID* property);
564         RegisterID* emitPutByVal(RegisterID* base, RegisterID* property, RegisterID* value);
565         RegisterID* emitPutByVal(RegisterID* base, RegisterID* thisValue, RegisterID* property, RegisterID* value);
566         RegisterID* emitDirectPutByVal(RegisterID* base, RegisterID* property, RegisterID* value);
567         RegisterID* emitDeleteByVal(RegisterID* dst, RegisterID* base, RegisterID* property);
568         RegisterID* emitPutByIndex(RegisterID* base, unsigned index, RegisterID* value);
569
570         RegisterID* emitAssert(RegisterID* condition, int line);
571
572         void emitPutGetterById(RegisterID* base, const Identifier& property, unsigned propertyDescriptorOptions, RegisterID* getter);
573         void emitPutSetterById(RegisterID* base, const Identifier& property, unsigned propertyDescriptorOptions, RegisterID* setter);
574         void emitPutGetterSetter(RegisterID* base, const Identifier& property, unsigned attributes, RegisterID* getter, RegisterID* setter);
575         void emitPutGetterByVal(RegisterID* base, RegisterID* property, unsigned propertyDescriptorOptions, RegisterID* getter);
576         void emitPutSetterByVal(RegisterID* base, RegisterID* property, unsigned propertyDescriptorOptions, RegisterID* setter);
577         
578         ExpectedFunction expectedFunctionForIdentifier(const Identifier&);
579         RegisterID* emitCall(RegisterID* dst, RegisterID* func, ExpectedFunction, CallArguments&, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
580         RegisterID* emitCallInTailPosition(RegisterID* dst, RegisterID* func, ExpectedFunction, CallArguments&, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
581         RegisterID* emitCallEval(RegisterID* dst, RegisterID* func, CallArguments&, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
582         RegisterID* emitCallVarargs(RegisterID* dst, RegisterID* func, RegisterID* thisRegister, RegisterID* arguments, RegisterID* firstFreeRegister, int32_t firstVarArgOffset, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
583         RegisterID* emitCallVarargsInTailPosition(RegisterID* dst, RegisterID* func, RegisterID* thisRegister, RegisterID* arguments, RegisterID* firstFreeRegister, int32_t firstVarArgOffset, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
584         RegisterID* emitCallForwardArgumentsInTailPosition(RegisterID* dst, RegisterID* func, RegisterID* thisRegister, RegisterID* firstFreeRegister, int32_t firstVarArgOffset, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
585
586         enum PropertyDescriptorOption {
587             PropertyConfigurable = 1,
588             PropertyWritable     = 1 << 1,
589             PropertyEnumerable   = 1 << 2,
590         };
591         void emitCallDefineProperty(RegisterID* newObj, RegisterID* propertyNameRegister,
592             RegisterID* valueRegister, RegisterID* getterRegister, RegisterID* setterRegister, unsigned options, const JSTextPosition&);
593
594         void emitEnumeration(ThrowableExpressionData* enumerationNode, ExpressionNode* subjectNode, const std::function<void(BytecodeGenerator&, RegisterID*)>& callBack, VariableEnvironmentNode* = nullptr, RegisterID* forLoopSymbolTable = nullptr);
595
596         RegisterID* emitGetTemplateObject(RegisterID* dst, TaggedTemplateNode*);
597
598         RegisterID* emitReturn(RegisterID* src);
599         RegisterID* emitEnd(RegisterID* src) { return emitUnaryNoDstOp(op_end, src); }
600
601         RegisterID* emitConstruct(RegisterID* dst, RegisterID* func, ExpectedFunction, CallArguments&, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
602         RegisterID* emitStrcat(RegisterID* dst, RegisterID* src, int count);
603         void emitToPrimitive(RegisterID* dst, RegisterID* src);
604
605         ResolveType resolveType();
606         RegisterID* emitResolveConstantLocal(RegisterID* dst, const Variable&);
607         RegisterID* emitResolveScope(RegisterID* dst, const Variable&);
608         RegisterID* emitGetFromScope(RegisterID* dst, RegisterID* scope, const Variable&, ResolveMode);
609         RegisterID* emitPutToScope(RegisterID* scope, const Variable&, RegisterID* value, ResolveMode, InitializationMode);
610         RegisterID* initializeVariable(const Variable&, RegisterID* value);
611
612         PassRefPtr<Label> emitLabel(Label*);
613         void emitLoopHint();
614         PassRefPtr<Label> emitJump(Label* target);
615         PassRefPtr<Label> emitJumpIfTrue(RegisterID* cond, Label* target);
616         PassRefPtr<Label> emitJumpIfFalse(RegisterID* cond, Label* target);
617         PassRefPtr<Label> emitJumpIfNotFunctionCall(RegisterID* cond, Label* target);
618         PassRefPtr<Label> emitJumpIfNotFunctionApply(RegisterID* cond, Label* target);
619         void emitPopScopes(RegisterID* srcDst, int targetScopeDepth);
620
621         void emitEnter();
622         void emitWatchdog();
623
624         RegisterID* emitHasIndexedProperty(RegisterID* dst, RegisterID* base, RegisterID* propertyName);
625         RegisterID* emitHasStructureProperty(RegisterID* dst, RegisterID* base, RegisterID* propertyName, RegisterID* enumerator);
626         RegisterID* emitHasGenericProperty(RegisterID* dst, RegisterID* base, RegisterID* propertyName);
627         RegisterID* emitGetPropertyEnumerator(RegisterID* dst, RegisterID* base);
628         RegisterID* emitGetEnumerableLength(RegisterID* dst, RegisterID* base);
629         RegisterID* emitGetStructurePropertyEnumerator(RegisterID* dst, RegisterID* base, RegisterID* length);
630         RegisterID* emitGetGenericPropertyEnumerator(RegisterID* dst, RegisterID* base, RegisterID* length, RegisterID* structureEnumerator);
631         RegisterID* emitEnumeratorStructurePropertyName(RegisterID* dst, RegisterID* enumerator, RegisterID* index);
632         RegisterID* emitEnumeratorGenericPropertyName(RegisterID* dst, RegisterID* enumerator, RegisterID* index);
633         RegisterID* emitToIndexString(RegisterID* dst, RegisterID* index);
634
635         RegisterID* emitIsJSArray(RegisterID* dst, RegisterID* src) { return emitUnaryOp(op_is_jsarray, dst, src); }
636         RegisterID* emitIsObject(RegisterID* dst, RegisterID* src);
637         RegisterID* emitIsUndefined(RegisterID* dst, RegisterID* src);
638         RegisterID* emitIsEmpty(RegisterID* dst, RegisterID* src);
639         void emitRequireObjectCoercible(RegisterID* value, const String& error);
640
641         RegisterID* emitIteratorNext(RegisterID* dst, RegisterID* iterator, const ThrowableExpressionData* node);
642         RegisterID* emitIteratorNextWithValue(RegisterID* dst, RegisterID* iterator, RegisterID* value, const ThrowableExpressionData* node);
643         void emitIteratorClose(RegisterID* iterator, const ThrowableExpressionData* node);
644
645         RegisterID* emitRestParameter(RegisterID* result, unsigned numParametersToSkip);
646
647         bool emitReadOnlyExceptionIfNeeded(const Variable&);
648
649         // Start a try block. 'start' must have been emitted.
650         TryData* pushTry(Label* start);
651         // End a try block. 'end' must have been emitted.
652         void popTryAndEmitCatch(TryData*, RegisterID* exceptionRegister, RegisterID* thrownValueRegister, Label* end, HandlerType);
653
654         void emitThrow(RegisterID* exc)
655         { 
656             m_usesExceptions = true;
657             emitUnaryNoDstOp(op_throw, exc);
658         }
659
660         void emitThrowReferenceError(const String& message);
661         void emitThrowTypeError(const String& message);
662
663         void emitPushCatchScope(VariableEnvironment&);
664         void emitPopCatchScope(VariableEnvironment&);
665
666         void emitGetScope();
667         RegisterID* emitPushWithScope(RegisterID* objectScope);
668         void emitPopWithScope();
669         void emitPutThisToArrowFunctionContextScope();
670         void emitPutNewTargetToArrowFunctionContextScope();
671         void emitPutDerivedConstructorToArrowFunctionContextScope();
672         RegisterID* emitLoadDerivedConstructorFromArrowFunctionLexicalEnvironment();
673
674         void emitDebugHook(DebugHookID, unsigned line, unsigned charOffset, unsigned lineStart);
675
676         bool isInFinallyBlock() { return m_finallyDepth > 0; }
677
678         void pushFinallyContext(StatementNode* finallyBlock);
679         void popFinallyContext();
680         void pushIteratorCloseContext(RegisterID* iterator, ThrowableExpressionData* enumerationNode);
681         void popIteratorCloseContext();
682
683         void pushIndexedForInScope(RegisterID* local, RegisterID* index);
684         void popIndexedForInScope(RegisterID* local);
685         void pushStructureForInScope(RegisterID* local, RegisterID* index, RegisterID* property, RegisterID* enumerator);
686         void popStructureForInScope(RegisterID* local);
687         void invalidateForInContextForLocal(RegisterID* local);
688
689         LabelScopePtr breakTarget(const Identifier&);
690         LabelScopePtr continueTarget(const Identifier&);
691
692         void beginSwitch(RegisterID*, SwitchInfo::SwitchType);
693         void endSwitch(uint32_t clauseCount, RefPtr<Label>*, ExpressionNode**, Label* defaultLabel, int32_t min, int32_t range);
694
695         void emitYieldPoint(RegisterID*);
696         void emitSave(Label* mergePoint, unsigned liveCalleeLocalsIndex);
697         void emitResume(Label* mergePoint, unsigned liveCalleeLocalsIndex);
698
699         void emitGeneratorStateLabel();
700         void emitGeneratorStateChange(int32_t state);
701         RegisterID* emitYield(RegisterID* argument);
702         RegisterID* emitDelegateYield(RegisterID* argument, ThrowableExpressionData*);
703         void beginGenerator(RegisterID*);
704         void endGenerator(Label* defaultLabel);
705         RegisterID* generatorStateRegister() { return &m_parameters[2]; }
706         RegisterID* generatorValueRegister() { return &m_parameters[3]; }
707         RegisterID* generatorResumeModeRegister() { return &m_parameters[4]; }
708
709         CodeType codeType() const { return m_codeType; }
710
711         bool shouldEmitDebugHooks() { return m_shouldEmitDebugHooks; }
712         
713         bool isStrictMode() const { return m_codeBlock->isStrictMode(); }
714
715         SourceParseMode parseMode() const { return m_codeBlock->parseMode(); }
716         
717         bool isBuiltinFunction() const { return m_isBuiltinFunction; }
718
719         OpcodeID lastOpcodeID() const { return m_lastOpcodeID; }
720         
721         bool isDerivedConstructorContext() { return m_derivedContextType == DerivedContextType::DerivedConstructorContext; }
722         bool isDerivedClassContext() { return m_derivedContextType == DerivedContextType::DerivedMethodContext; }
723         bool isArrowFunction() { return m_codeBlock->isArrowFunction(); }
724
725         enum class TDZCheckOptimization { Optimize, DoNotOptimize };
726         enum class NestedScopeType { IsNested, IsNotNested };
727     private:
728         enum class TDZRequirement { UnderTDZ, NotUnderTDZ };
729         enum class ScopeType { CatchScope, LetConstScope, FunctionNameScope };
730         enum class ScopeRegisterType { Var, Block };
731         void pushLexicalScopeInternal(VariableEnvironment&, TDZCheckOptimization, NestedScopeType, RegisterID** constantSymbolTableResult, TDZRequirement, ScopeType, ScopeRegisterType);
732         void initializeBlockScopedFunctions(VariableEnvironment&, FunctionStack&, RegisterID* constantSymbolTable);
733         void popLexicalScopeInternal(VariableEnvironment&);
734         template<typename LookUpVarKindFunctor>
735         bool instantiateLexicalVariables(const VariableEnvironment&, SymbolTable*, ScopeRegisterType, LookUpVarKindFunctor);
736         void emitPrefillStackTDZVariables(const VariableEnvironment&, SymbolTable*);
737         void emitPopScope(RegisterID* dst, RegisterID* scope);
738         RegisterID* emitGetParentScope(RegisterID* dst, RegisterID* scope);
739         void emitPushFunctionNameScope(const Identifier& property, RegisterID* value, bool isCaptured);
740         void emitNewFunctionExpressionCommon(RegisterID*, FunctionMetadataNode*);
741         
742         bool isNewTargetUsedInInnerArrowFunction();
743         bool isSuperUsedInInnerArrowFunction();
744         bool isArgumentsUsedInInnerArrowFunction();
745
746     public:
747         bool isSuperCallUsedInInnerArrowFunction();
748         bool isThisUsedInInnerArrowFunction();
749         void pushLexicalScope(VariableEnvironmentNode*, TDZCheckOptimization, NestedScopeType = NestedScopeType::IsNotNested, RegisterID** constantSymbolTableResult = nullptr, bool shouldInitializeBlockScopedFunctions = true);
750         void popLexicalScope(VariableEnvironmentNode*);
751         void prepareLexicalScopeForNextForLoopIteration(VariableEnvironmentNode*, RegisterID* loopSymbolTable);
752         int labelScopeDepth() const;
753
754     private:
755         ParserError generate();
756         void reclaimFreeRegisters();
757         Variable variableForLocalEntry(const Identifier&, const SymbolTableEntry&, int symbolTableConstantIndex, bool isLexicallyScoped);
758
759         void emitOpcode(OpcodeID);
760         UnlinkedArrayAllocationProfile newArrayAllocationProfile();
761         UnlinkedObjectAllocationProfile newObjectAllocationProfile();
762         UnlinkedArrayProfile newArrayProfile();
763         UnlinkedValueProfile emitProfiledOpcode(OpcodeID);
764         int kill(RegisterID* dst)
765         {
766             int index = dst->index();
767             m_staticPropertyAnalyzer.kill(index);
768             return index;
769         }
770
771         void retrieveLastBinaryOp(int& dstIndex, int& src1Index, int& src2Index);
772         void retrieveLastUnaryOp(int& dstIndex, int& srcIndex);
773         ALWAYS_INLINE void rewindBinaryOp();
774         ALWAYS_INLINE void rewindUnaryOp();
775
776         void allocateCalleeSaveSpace();
777         void allocateAndEmitScope();
778         void emitComplexPopScopes(RegisterID*, ControlFlowContext* topScope, ControlFlowContext* bottomScope);
779
780         typedef HashMap<double, JSValue> NumberMap;
781         typedef HashMap<UniquedStringImpl*, JSString*, IdentifierRepHash> IdentifierStringMap;
782         typedef HashMap<TemplateRegistryKey, JSTemplateRegistryKey*> TemplateRegistryKeyMap;
783         
784         // Helper for emitCall() and emitConstruct(). This works because the set of
785         // expected functions have identical behavior for both call and construct
786         // (i.e. "Object()" is identical to "new Object()").
787         ExpectedFunction emitExpectedFunctionSnippet(RegisterID* dst, RegisterID* func, ExpectedFunction, CallArguments&, Label* done);
788         
789         RegisterID* emitCall(OpcodeID, RegisterID* dst, RegisterID* func, ExpectedFunction, CallArguments&, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
790
791         RegisterID* newRegister();
792
793         // Adds an anonymous local var slot. To give this slot a name, add it to symbolTable().
794         RegisterID* addVar()
795         {
796             ++m_codeBlock->m_numVars;
797             RegisterID* result = newRegister();
798             ASSERT(VirtualRegister(result->index()).toLocal() == m_codeBlock->m_numVars - 1);
799             result->ref(); // We should never free this slot.
800             return result;
801         }
802
803         // Initializes the stack form the parameter; does nothing for the symbol table.
804         RegisterID* initializeNextParameter();
805         UniquedStringImpl* visibleNameForParameter(DestructuringPatternNode*);
806         
807         RegisterID& registerFor(VirtualRegister reg)
808         {
809             if (reg.isLocal())
810                 return m_calleeLocals[reg.toLocal()];
811
812             if (reg.offset() == JSStack::Callee)
813                 return m_calleeRegister;
814
815             ASSERT(m_parameters.size());
816             return m_parameters[reg.toArgument()];
817         }
818
819         bool hasConstant(const Identifier&) const;
820         unsigned addConstant(const Identifier&);
821         RegisterID* addConstantValue(JSValue, SourceCodeRepresentation = SourceCodeRepresentation::Other);
822         RegisterID* addConstantEmptyValue();
823         unsigned addRegExp(RegExp*);
824
825         unsigned addConstantBuffer(unsigned length);
826         
827         UnlinkedFunctionExecutable* makeFunction(FunctionMetadataNode* metadata)
828         {
829             DerivedContextType newDerivedContextType = DerivedContextType::None;
830
831             if (metadata->parseMode() == SourceParseMode::ArrowFunctionMode) {
832                 if (constructorKind() == ConstructorKind::Derived || isDerivedConstructorContext())
833                     newDerivedContextType = DerivedContextType::DerivedConstructorContext;
834                 else if (m_codeBlock->isClassContext() || isDerivedClassContext())
835                     newDerivedContextType = DerivedContextType::DerivedMethodContext;
836             }
837
838             VariableEnvironment variablesUnderTDZ;
839             getVariablesUnderTDZ(variablesUnderTDZ);
840
841             // FIXME: These flags, ParserModes and propagation to XXXCodeBlocks should be reorganized.
842             // https://bugs.webkit.org/show_bug.cgi?id=151547
843             SourceParseMode parseMode = metadata->parseMode();
844             ConstructAbility constructAbility = ConstructAbility::CanConstruct;
845             if (parseMode == SourceParseMode::GetterMode || parseMode == SourceParseMode::SetterMode || parseMode == SourceParseMode::ArrowFunctionMode || parseMode == SourceParseMode::GeneratorWrapperFunctionMode)
846                 constructAbility = ConstructAbility::CannotConstruct;
847             else if (parseMode == SourceParseMode::MethodMode && metadata->constructorKind() == ConstructorKind::None)
848                 constructAbility = ConstructAbility::CannotConstruct;
849
850             return UnlinkedFunctionExecutable::create(m_vm, m_scopeNode->source(), metadata, isBuiltinFunction() ? UnlinkedBuiltinFunction : UnlinkedNormalFunction, constructAbility, variablesUnderTDZ, newDerivedContextType);
851         }
852
853         void getVariablesUnderTDZ(VariableEnvironment&);
854
855         RegisterID* emitConstructVarargs(RegisterID* dst, RegisterID* func, RegisterID* thisRegister, RegisterID* arguments, RegisterID* firstFreeRegister, int32_t firstVarArgOffset, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
856         RegisterID* emitCallVarargs(OpcodeID, RegisterID* dst, RegisterID* func, RegisterID* thisRegister, RegisterID* arguments, RegisterID* firstFreeRegister, int32_t firstVarArgOffset, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
857         
858         void emitLogShadowChickenPrologueIfNecessary();
859         void emitLogShadowChickenTailIfNecessary();
860
861         void initializeParameters(FunctionParameters&);
862         void initializeVarLexicalEnvironment(int symbolTableConstantIndex, SymbolTable* functionSymbolTable, bool hasCapturedVariables);
863         void initializeDefaultParameterValuesAndSetupFunctionScopeStack(FunctionParameters&, bool isSimpleParameterList, FunctionNode*, SymbolTable*, int symbolTableConstantIndex, const std::function<bool (UniquedStringImpl*)>& captures, bool shouldCreateArgumentsVariableInParameterScope);
864         void initializeArrowFunctionContextScopeIfNeeded(SymbolTable* functionSymbolTable = nullptr, bool canReuseLexicalEnvironment = false);
865
866     public:
867         JSString* addStringConstant(const Identifier&);
868         JSTemplateRegistryKey* addTemplateRegistryKeyConstant(const TemplateRegistryKey&);
869
870         Vector<UnlinkedInstruction, 0, UnsafeVectorOverflow>& instructions() { return m_instructions; }
871
872         RegisterID* emitThrowExpressionTooDeepException();
873
874     private:
875         Vector<UnlinkedInstruction, 0, UnsafeVectorOverflow> m_instructions;
876
877         bool m_shouldEmitDebugHooks;
878
879         struct SymbolTableStackEntry {
880             SymbolTable* m_symbolTable;
881             RegisterID* m_scope;
882             bool m_isWithScope;
883             int m_symbolTableConstantIndex;
884         };
885         Vector<SymbolTableStackEntry> m_symbolTableStack;
886         enum class TDZNecessityLevel {
887             NotNeeded,
888             Optimize,
889             DoNotOptimize
890         };
891         typedef HashMap<RefPtr<UniquedStringImpl>, TDZNecessityLevel, IdentifierRepHash> TDZMap;
892         Vector<TDZMap> m_TDZStack;
893         Optional<size_t> m_varScopeSymbolTableIndex;
894         void pushTDZVariables(const VariableEnvironment&, TDZCheckOptimization, TDZRequirement);
895
896         ScopeNode* const m_scopeNode;
897         Strong<UnlinkedCodeBlock> m_codeBlock;
898
899         // Some of these objects keep pointers to one another. They are arranged
900         // to ensure a sane destruction order that avoids references to freed memory.
901         HashSet<RefPtr<UniquedStringImpl>, IdentifierRepHash> m_functions;
902         RegisterID m_ignoredResultRegister;
903         RegisterID m_thisRegister;
904         RegisterID m_calleeRegister;
905         RegisterID* m_scopeRegister { nullptr };
906         RegisterID* m_topMostScope { nullptr };
907         RegisterID* m_argumentsRegister { nullptr };
908         RegisterID* m_lexicalEnvironmentRegister { nullptr };
909         RegisterID* m_generatorRegister { nullptr };
910         RegisterID* m_emptyValueRegister { nullptr };
911         RegisterID* m_globalObjectRegister { nullptr };
912         RegisterID* m_newTargetRegister { nullptr };
913         RegisterID* m_linkTimeConstantRegisters[LinkTimeConstantCount];
914         RegisterID* m_arrowFunctionContextLexicalEnvironmentRegister { nullptr };
915
916         SegmentedVector<RegisterID*, 16> m_localRegistersForCalleeSaveRegisters;
917         SegmentedVector<RegisterID, 32> m_constantPoolRegisters;
918         SegmentedVector<RegisterID, 32> m_calleeLocals;
919         SegmentedVector<RegisterID, 32> m_parameters;
920         SegmentedVector<Label, 32> m_labels;
921         LabelScopeStore m_labelScopes;
922         int m_finallyDepth { 0 };
923         int m_localScopeDepth { 0 };
924         const CodeType m_codeType;
925
926         int localScopeDepth() const;
927         void pushScopedControlFlowContext();
928         void popScopedControlFlowContext();
929
930         Vector<ControlFlowContext, 0, UnsafeVectorOverflow> m_scopeContextStack;
931         Vector<SwitchInfo> m_switchContextStack;
932         Vector<RefPtr<ForInContext>> m_forInContextStack;
933         Vector<TryContext> m_tryContextStack;
934         Vector<RefPtr<Label>> m_generatorResumeLabels;
935         enum FunctionVariableType : uint8_t { NormalFunctionVariable, GlobalFunctionVariable };
936         Vector<std::pair<FunctionMetadataNode*, FunctionVariableType>> m_functionsToInitialize;
937         bool m_needToInitializeArguments { false };
938         RestParameterNode* m_restParameter { nullptr };
939         
940         Vector<TryRange> m_tryRanges;
941         SegmentedVector<TryData, 8> m_tryData;
942
943         int m_nextConstantOffset { 0 };
944
945         typedef HashMap<FunctionMetadataNode*, unsigned> FunctionOffsetMap;
946         FunctionOffsetMap m_functionOffsets;
947         
948         // Constant pool
949         IdentifierMap m_identifierMap;
950
951         typedef HashMap<EncodedJSValueWithRepresentation, unsigned, EncodedJSValueWithRepresentationHash, EncodedJSValueWithRepresentationHashTraits> JSValueMap;
952         JSValueMap m_jsValueMap;
953         IdentifierStringMap m_stringMap;
954         TemplateRegistryKeyMap m_templateRegistryKeyMap;
955
956         StaticPropertyAnalyzer m_staticPropertyAnalyzer { &m_instructions };
957
958         VM* m_vm;
959
960         OpcodeID m_lastOpcodeID = op_end;
961 #ifndef NDEBUG
962         size_t m_lastOpcodePosition { 0 };
963 #endif
964
965         bool m_usesExceptions { false };
966         bool m_expressionTooDeep { false };
967         bool m_isBuiltinFunction { false };
968         bool m_usesNonStrictEval { false };
969         bool m_inTailPosition { false };
970         bool m_needsToUpdateArrowFunctionContext;
971         DerivedContextType m_derivedContextType { DerivedContextType::None };
972     };
973
974 }
975
976 namespace WTF {
977
978 void printInternal(PrintStream&, JSC::Variable::VariableKind);
979
980 } // namespace WTF
981
982 #endif // BytecodeGenerator_h