Ensure that ForInContexts are invalidated if their loop local is over-written.
[WebKit-https.git] / Source / JavaScriptCore / bytecompiler / BytecodeGenerator.h
1 /*
2  * Copyright (C) 2008-2018 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 #pragma once
32
33 #include "CodeBlock.h"
34 #include "Instruction.h"
35 #include "Interpreter.h"
36 #include "JSAsyncGeneratorFunction.h"
37 #include "JSBigInt.h"
38 #include "JSGeneratorFunction.h"
39 #include "JSTemplateObjectDescriptor.h"
40 #include "Label.h"
41 #include "LabelScope.h"
42 #include "Nodes.h"
43 #include "ParserError.h"
44 #include "RegisterID.h"
45 #include "StaticPropertyAnalyzer.h"
46 #include "SymbolTable.h"
47 #include "UnlinkedCodeBlock.h"
48 #include <functional>
49 #include <wtf/CheckedArithmetic.h>
50 #include <wtf/HashFunctions.h>
51 #include <wtf/SegmentedVector.h>
52 #include <wtf/SetForScope.h>
53 #include <wtf/Vector.h>
54
55 namespace JSC {
56
57     class JSImmutableButterfly;
58     class Identifier;
59     class IndexedForInContext;
60     class StructureForInContext;
61
62     enum ExpectedFunction {
63         NoExpectedFunction,
64         ExpectObjectConstructor,
65         ExpectArrayConstructor
66     };
67
68     enum class EmitAwait { Yes, No };
69
70     enum class DebuggableCall { Yes, No };
71     enum class ThisResolutionType { Local, Scoped };
72     
73     class CallArguments {
74     public:
75         CallArguments(BytecodeGenerator&, ArgumentsNode*, unsigned additionalArguments = 0);
76
77         RegisterID* thisRegister() { return m_argv[0].get(); }
78         RegisterID* argumentRegister(unsigned i) { return m_argv[i + 1].get(); }
79         unsigned stackOffset() { return -m_argv[0]->index() + CallFrame::headerSizeInRegisters; }
80         unsigned argumentCountIncludingThis() { return m_argv.size() - m_padding; }
81         ArgumentsNode* argumentsNode() { return m_argumentsNode; }
82
83     private:
84         ArgumentsNode* m_argumentsNode;
85         Vector<RefPtr<RegisterID>, 8, UnsafeVectorOverflow> m_argv;
86         unsigned m_padding;
87     };
88
89     // https://tc39.github.io/ecma262/#sec-completion-record-specification-type
90     //
91     // For the Break and Continue cases, instead of using the Break and Continue enum values
92     // below, we use the unique jumpID of the break and continue statement as the encoding
93     // for the CompletionType value. emitFinallyCompletion() uses this jumpID value later
94     // to determine the appropriate jump target to jump to after executing the relevant finally
95     // blocks. The jumpID is computed as:
96     //     jumpID = bytecodeOffset (of the break/continue node) + CompletionType::NumberOfTypes.
97     // Hence, there won't be any collision between jumpIDs and CompletionType enums.
98     enum class CompletionType : int {
99         Normal,
100         Break,
101         Continue,
102         Return,
103         Throw,
104         
105         NumberOfTypes
106     };
107
108     inline CompletionType bytecodeOffsetToJumpID(unsigned offset)
109     {
110         int jumpIDAsInt = offset + static_cast<int>(CompletionType::NumberOfTypes);
111         ASSERT(jumpIDAsInt >= static_cast<int>(CompletionType::NumberOfTypes));
112         return static_cast<CompletionType>(jumpIDAsInt);
113     }
114
115     struct FinallyJump {
116         FinallyJump(CompletionType jumpID, int targetLexicalScopeIndex, Label& targetLabel)
117             : jumpID(jumpID)
118             , targetLexicalScopeIndex(targetLexicalScopeIndex)
119             , targetLabel(targetLabel)
120         { }
121
122         CompletionType jumpID;
123         int targetLexicalScopeIndex;
124         Ref<Label> targetLabel;
125     };
126
127     struct FinallyContext {
128         FinallyContext() { }
129         FinallyContext(FinallyContext* outerContext, Label& finallyLabel)
130             : m_outerContext(outerContext)
131             , m_finallyLabel(&finallyLabel)
132         {
133             ASSERT(m_jumps.isEmpty());
134         }
135
136         FinallyContext* outerContext() const { return m_outerContext; }
137         Label* finallyLabel() const { return m_finallyLabel; }
138
139         uint32_t numberOfBreaksOrContinues() const { return m_numberOfBreaksOrContinues.unsafeGet(); }
140         void incNumberOfBreaksOrContinues() { m_numberOfBreaksOrContinues++; }
141
142         bool handlesReturns() const { return m_handlesReturns; }
143         void setHandlesReturns() { m_handlesReturns = true; }
144
145         void registerJump(CompletionType jumpID, int lexicalScopeIndex, Label& targetLabel)
146         {
147             m_jumps.append(FinallyJump(jumpID, lexicalScopeIndex, targetLabel));
148         }
149
150         size_t numberOfJumps() const { return m_jumps.size(); }
151         FinallyJump& jumps(size_t i) { return m_jumps[i]; }
152
153     private:
154         FinallyContext* m_outerContext { nullptr };
155         Label* m_finallyLabel { nullptr };
156         Checked<uint32_t, WTF::CrashOnOverflow> m_numberOfBreaksOrContinues;
157         bool m_handlesReturns { false };
158         Vector<FinallyJump> m_jumps;
159     };
160
161     struct ControlFlowScope {
162         typedef uint8_t Type;
163         enum {
164             Label,
165             Finally
166         };
167         ControlFlowScope(Type type, int lexicalScopeIndex, FinallyContext&& finallyContext = FinallyContext())
168             : type(type)
169             , lexicalScopeIndex(lexicalScopeIndex)
170             , finallyContext(std::forward<FinallyContext>(finallyContext))
171         { }
172
173         bool isLabelScope() const { return type == Label; }
174         bool isFinallyScope() const { return type == Finally; }
175
176         Type type;
177         int lexicalScopeIndex;
178         FinallyContext finallyContext;
179     };
180
181     class ForInContext : public RefCounted<ForInContext> {
182         WTF_MAKE_FAST_ALLOCATED;
183         WTF_MAKE_NONCOPYABLE(ForInContext);
184     public:
185         virtual ~ForInContext() = default;
186
187         bool isValid() const { return m_isValid; }
188         void invalidate() { m_isValid = false; }
189
190         enum class Type : uint8_t {
191             IndexedForIn,
192             StructureForIn
193         };
194
195         Type type() const { return m_type; }
196         bool isIndexedForInContext() const { return m_type == Type::IndexedForIn; }
197         bool isStructureForInContext() const { return m_type == Type::StructureForIn; }
198
199         IndexedForInContext& asIndexedForInContext()
200         {
201             ASSERT(isIndexedForInContext());
202             return *reinterpret_cast<IndexedForInContext*>(this);
203         }
204
205         StructureForInContext& asStructureForInContext()
206         {
207             ASSERT(isStructureForInContext());
208             return *reinterpret_cast<StructureForInContext*>(this);
209         }
210
211         RegisterID* local() const { return m_localRegister.get(); }
212
213     protected:
214         ForInContext(RegisterID* localRegister, Type type, unsigned bodyBytecodeStartOffset)
215             : m_localRegister(localRegister)
216             , m_type(type)
217             , m_bodyBytecodeStartOffset(bodyBytecodeStartOffset)
218         { }
219
220         unsigned bodyBytecodeStartOffset() const { return m_bodyBytecodeStartOffset; }
221
222         void finalize(BytecodeGenerator&, UnlinkedCodeBlock*, unsigned bodyBytecodeEndOffset);
223
224     private:
225         RefPtr<RegisterID> m_localRegister;
226         bool m_isValid { true };
227         Type m_type;
228         unsigned m_bodyBytecodeStartOffset;
229     };
230
231     class StructureForInContext : public ForInContext {
232         using Base = ForInContext;
233     public:
234         using GetInst = std::tuple<unsigned, int, UnlinkedValueProfile>;
235
236         StructureForInContext(RegisterID* localRegister, RegisterID* indexRegister, RegisterID* propertyRegister, RegisterID* enumeratorRegister, unsigned bodyBytecodeStartOffset)
237             : ForInContext(localRegister, Type::StructureForIn, bodyBytecodeStartOffset)
238             , m_indexRegister(indexRegister)
239             , m_propertyRegister(propertyRegister)
240             , m_enumeratorRegister(enumeratorRegister)
241         {
242         }
243
244         RegisterID* index() const { return m_indexRegister.get(); }
245         RegisterID* property() const { return m_propertyRegister.get(); }
246         RegisterID* enumerator() const { return m_enumeratorRegister.get(); }
247
248         void addGetInst(unsigned instIndex, int propertyRegIndex, UnlinkedValueProfile valueProfile)
249         {
250             m_getInsts.append(GetInst { instIndex, propertyRegIndex, valueProfile });
251         }
252
253         void finalize(BytecodeGenerator&, UnlinkedCodeBlock*, unsigned bodyBytecodeEndOffset);
254
255     private:
256         RefPtr<RegisterID> m_indexRegister;
257         RefPtr<RegisterID> m_propertyRegister;
258         RefPtr<RegisterID> m_enumeratorRegister;
259         Vector<GetInst> m_getInsts;
260     };
261
262     class IndexedForInContext : public ForInContext {
263         using Base = ForInContext;
264     public:
265         IndexedForInContext(RegisterID* localRegister, RegisterID* indexRegister, unsigned bodyBytecodeStartOffset)
266             : ForInContext(localRegister, Type::IndexedForIn, bodyBytecodeStartOffset)
267             , m_indexRegister(indexRegister)
268         {
269         }
270
271         RegisterID* index() const { return m_indexRegister.get(); }
272
273         void finalize(BytecodeGenerator&, UnlinkedCodeBlock*, unsigned bodyBytecodeEndOffset);
274         void addGetInst(unsigned instIndex, int propertyIndex) { m_getInsts.append({ instIndex, propertyIndex }); }
275
276     private:
277         RefPtr<RegisterID> m_indexRegister;
278         Vector<std::pair<unsigned, int>> m_getInsts;
279     };
280
281     struct TryData {
282         Ref<Label> target;
283         HandlerType handlerType;
284     };
285
286     struct TryContext {
287         Ref<Label> start;
288         TryData* tryData;
289     };
290
291     class Variable {
292     public:
293         enum VariableKind { NormalVariable, SpecialVariable };
294
295         Variable()
296             : m_offset()
297             , m_local(nullptr)
298             , m_attributes(0)
299             , m_kind(NormalVariable)
300             , m_symbolTableConstantIndex(0) // This is meaningless here for this kind of Variable.
301             , m_isLexicallyScoped(false)
302         {
303         }
304         
305         Variable(const Identifier& ident)
306             : m_ident(ident)
307             , m_local(nullptr)
308             , m_attributes(0)
309             , m_kind(NormalVariable) // This is somewhat meaningless here for this kind of Variable.
310             , m_symbolTableConstantIndex(0) // This is meaningless here for this kind of Variable.
311             , m_isLexicallyScoped(false)
312         {
313         }
314
315         Variable(const Identifier& ident, VarOffset offset, RegisterID* local, unsigned attributes, VariableKind kind, int symbolTableConstantIndex, bool isLexicallyScoped)
316             : m_ident(ident)
317             , m_offset(offset)
318             , m_local(local)
319             , m_attributes(attributes)
320             , m_kind(kind)
321             , m_symbolTableConstantIndex(symbolTableConstantIndex)
322             , m_isLexicallyScoped(isLexicallyScoped)
323         {
324         }
325
326         // If it's unset, then it is a non-locally-scoped variable. If it is set, then it could be
327         // a stack variable, a scoped variable in a local scope, or a variable captured in the
328         // direct arguments object.
329         bool isResolved() const { return !!m_offset; }
330         int symbolTableConstantIndex() const { ASSERT(isResolved() && !isSpecial()); return m_symbolTableConstantIndex; }
331         
332         const Identifier& ident() const { return m_ident; }
333         
334         VarOffset offset() const { return m_offset; }
335         bool isLocal() const { return m_offset.isStack(); }
336         RegisterID* local() const { return m_local; }
337
338         bool isReadOnly() const { return m_attributes & PropertyAttribute::ReadOnly; }
339         bool isSpecial() const { return m_kind != NormalVariable; }
340         bool isConst() const { return isReadOnly() && m_isLexicallyScoped; }
341         void setIsReadOnly() { m_attributes |= PropertyAttribute::ReadOnly; }
342
343         void dump(PrintStream&) const;
344
345     private:
346         Identifier m_ident;
347         VarOffset m_offset;
348         RegisterID* m_local;
349         unsigned m_attributes;
350         VariableKind m_kind;
351         int m_symbolTableConstantIndex;
352         bool m_isLexicallyScoped;
353     };
354
355     struct TryRange {
356         Ref<Label> start;
357         Ref<Label> end;
358         TryData* tryData;
359     };
360
361     enum ProfileTypeBytecodeFlag {
362         ProfileTypeBytecodeClosureVar,
363         ProfileTypeBytecodeLocallyResolved,
364         ProfileTypeBytecodeDoesNotHaveGlobalID,
365         ProfileTypeBytecodeFunctionArgument,
366         ProfileTypeBytecodeFunctionReturnStatement
367     };
368
369     class BytecodeGenerator {
370         WTF_MAKE_FAST_ALLOCATED;
371         WTF_MAKE_NONCOPYABLE(BytecodeGenerator);
372     public:
373         typedef DeclarationStacks::FunctionStack FunctionStack;
374
375         BytecodeGenerator(VM&, ProgramNode*, UnlinkedProgramCodeBlock*, DebuggerMode, const VariableEnvironment*);
376         BytecodeGenerator(VM&, FunctionNode*, UnlinkedFunctionCodeBlock*, DebuggerMode, const VariableEnvironment*);
377         BytecodeGenerator(VM&, EvalNode*, UnlinkedEvalCodeBlock*, DebuggerMode, const VariableEnvironment*);
378         BytecodeGenerator(VM&, ModuleProgramNode*, UnlinkedModuleProgramCodeBlock*, DebuggerMode, const VariableEnvironment*);
379
380         ~BytecodeGenerator();
381         
382         VM* vm() const { return m_vm; }
383         ParserArena& parserArena() const { return m_scopeNode->parserArena(); }
384         const CommonIdentifiers& propertyNames() const { return *m_vm->propertyNames; }
385
386         bool isConstructor() const { return m_codeBlock->isConstructor(); }
387         DerivedContextType derivedContextType() const { return m_derivedContextType; }
388         bool usesArrowFunction() const { return m_scopeNode->usesArrowFunction(); }
389         bool needsToUpdateArrowFunctionContext() const { return m_needsToUpdateArrowFunctionContext; }
390         bool usesEval() const { return m_scopeNode->usesEval(); }
391         bool usesThis() const { return m_scopeNode->usesThis(); }
392         ConstructorKind constructorKind() const { return m_codeBlock->constructorKind(); }
393         SuperBinding superBinding() const { return m_codeBlock->superBinding(); }
394         JSParserScriptMode scriptMode() const { return m_codeBlock->scriptMode(); }
395
396         template<typename Node, typename UnlinkedCodeBlock>
397         static ParserError generate(VM& vm, Node* node, const SourceCode& sourceCode, UnlinkedCodeBlock* unlinkedCodeBlock, DebuggerMode debuggerMode, const VariableEnvironment* environment)
398         {
399             MonotonicTime before;
400             if (UNLIKELY(Options::reportBytecodeCompileTimes()))
401                 before = MonotonicTime::now();
402
403             DeferGC deferGC(vm.heap);
404             auto bytecodeGenerator = std::make_unique<BytecodeGenerator>(vm, node, unlinkedCodeBlock, debuggerMode, environment);
405             auto result = bytecodeGenerator->generate();
406
407             if (UNLIKELY(Options::reportBytecodeCompileTimes())) {
408                 MonotonicTime after = MonotonicTime::now();
409                 dataLogLn(result.isValid() ? "Failed to compile #" : "Compiled #", CodeBlockHash(sourceCode, unlinkedCodeBlock->isConstructor() ? CodeForConstruct : CodeForCall), " into bytecode ", bytecodeGenerator->instructions().size(), " instructions in ", (after - before).milliseconds(), " ms.");
410             }
411             return result;
412         }
413
414         bool isArgumentNumber(const Identifier&, int);
415
416         Variable variable(const Identifier&, ThisResolutionType = ThisResolutionType::Local);
417         
418         enum ExistingVariableMode { VerifyExisting, IgnoreExisting };
419         void createVariable(const Identifier&, VarKind, SymbolTable*, ExistingVariableMode = VerifyExisting); // Creates the variable, or asserts that the already-created variable is sufficiently compatible.
420         
421         // Returns the register storing "this"
422         RegisterID* thisRegister() { return &m_thisRegister; }
423         RegisterID* argumentsRegister() { return m_argumentsRegister; }
424         RegisterID* newTarget()
425         {
426             return m_newTargetRegister;
427         }
428
429         RegisterID* scopeRegister() { return m_scopeRegister; }
430
431         RegisterID* generatorRegister() { return m_generatorRegister; }
432
433         RegisterID* promiseCapabilityRegister() { return m_promiseCapabilityRegister; }
434
435         // Returns the next available temporary register. Registers returned by
436         // newTemporary require a modified form of reference counting: any
437         // register with a refcount of 0 is considered "available", meaning that
438         // the next instruction may overwrite it.
439         RegisterID* newTemporary();
440
441         // The same as newTemporary(), but this function returns "suggestion" if
442         // "suggestion" is a temporary. This function is helpful in situations
443         // where you've put "suggestion" in a RefPtr, but you'd like to allow
444         // the next instruction to overwrite it anyway.
445         RegisterID* newTemporaryOr(RegisterID* suggestion) { return suggestion->isTemporary() ? suggestion : newTemporary(); }
446
447         // Functions for handling of dst register
448
449         RegisterID* ignoredResult() { return &m_ignoredResultRegister; }
450
451         // This will be allocated in the temporary region of registers, but it will
452         // not be marked as a temporary. This will ensure that finalDestination() does
453         // not overwrite a block scope variable that it mistakes as a temporary. These
454         // registers can be (and are) reclaimed when the lexical scope they belong to
455         // is no longer on the symbol table stack.
456         RegisterID* newBlockScopeVariable();
457
458         // Returns a place to write intermediate values of an operation
459         // which reuses dst if it is safe to do so.
460         RegisterID* tempDestination(RegisterID* dst)
461         {
462             return (dst && dst != ignoredResult() && dst->isTemporary()) ? dst : newTemporary();
463         }
464
465         // Returns the place to write the final output of an operation.
466         RegisterID* finalDestination(RegisterID* originalDst, RegisterID* tempDst = 0)
467         {
468             if (originalDst && originalDst != ignoredResult())
469                 return originalDst;
470             ASSERT(tempDst != ignoredResult());
471             if (tempDst && tempDst->isTemporary())
472                 return tempDst;
473             return newTemporary();
474         }
475
476         RegisterID* destinationForAssignResult(RegisterID* dst)
477         {
478             if (dst && dst != ignoredResult())
479                 return dst->isTemporary() ? dst : newTemporary();
480             return 0;
481         }
482
483         // Moves src to dst if dst is not null and is different from src, otherwise just returns src.
484         RegisterID* move(RegisterID* dst, RegisterID* src)
485         {
486             return dst == ignoredResult() ? nullptr : (dst && dst != src) ? emitMove(dst, src) : src;
487         }
488
489         Ref<LabelScope> newLabelScope(LabelScope::Type, const Identifier* = 0);
490         Ref<Label> newLabel();
491         Ref<Label> newEmittedLabel();
492
493         void emitNode(RegisterID* dst, StatementNode* n)
494         {
495             SetForScope<bool> tailPositionPoisoner(m_inTailPosition, false);
496             return emitNodeInTailPosition(dst, n);
497         }
498
499         void emitNodeInTailPosition(RegisterID* dst, StatementNode* n)
500         {
501             // Node::emitCode assumes that dst, if provided, is either a local or a referenced temporary.
502             ASSERT(!dst || dst == ignoredResult() || !dst->isTemporary() || dst->refCount());
503             if (UNLIKELY(!m_vm->isSafeToRecurse())) {
504                 emitThrowExpressionTooDeepException();
505                 return;
506             }
507             if (UNLIKELY(n->needsDebugHook()))
508                 emitDebugHook(n);
509             n->emitBytecode(*this, dst);
510         }
511
512         void emitNode(StatementNode* n)
513         {
514             emitNode(nullptr, n);
515         }
516
517         void emitNodeInTailPosition(StatementNode* n)
518         {
519             emitNodeInTailPosition(nullptr, n);
520         }
521
522         RegisterID* emitNode(RegisterID* dst, ExpressionNode* n)
523         {
524             SetForScope<bool> tailPositionPoisoner(m_inTailPosition, false);
525             return emitNodeInTailPosition(dst, n);
526         }
527
528         RegisterID* emitNodeInTailPosition(RegisterID* dst, ExpressionNode* n)
529         {
530             // Node::emitCode assumes that dst, if provided, is either a local or a referenced temporary.
531             ASSERT(!dst || dst == ignoredResult() || !dst->isTemporary() || dst->refCount());
532             if (UNLIKELY(!m_vm->isSafeToRecurse()))
533                 return emitThrowExpressionTooDeepException();
534             if (UNLIKELY(n->needsDebugHook()))
535                 emitDebugHook(n);
536             return n->emitBytecode(*this, dst);
537         }
538
539         RegisterID* emitNode(ExpressionNode* n)
540         {
541             return emitNode(nullptr, n);
542         }
543
544         RegisterID* emitNodeInTailPosition(ExpressionNode* n)
545         {
546             return emitNodeInTailPosition(nullptr, n);
547         }
548
549         RegisterID* emitDefineClassElements(PropertyListNode* n, RegisterID* constructor, RegisterID* prototype)
550         {
551             ASSERT(constructor->refCount() && prototype->refCount());
552             if (UNLIKELY(!m_vm->isSafeToRecurse()))
553                 return emitThrowExpressionTooDeepException();
554             if (UNLIKELY(n->needsDebugHook()))
555                 emitDebugHook(n);
556             return n->emitBytecode(*this, constructor, prototype);
557         }
558
559         RegisterID* emitNodeForProperty(RegisterID* dst, ExpressionNode* node)
560         {
561             if (node->isString()) {
562                 if (std::optional<uint32_t> index = parseIndex(static_cast<StringNode*>(node)->value()))
563                     return emitLoad(dst, jsNumber(index.value()));
564             }
565             return emitNode(dst, node);
566         }
567
568         RegisterID* emitNodeForProperty(ExpressionNode* n)
569         {
570             return emitNodeForProperty(nullptr, n);
571         }
572
573         void emitNodeInConditionContext(ExpressionNode* n, Label& trueTarget, Label& falseTarget, FallThroughMode fallThroughMode)
574         {
575             if (UNLIKELY(!m_vm->isSafeToRecurse())) {
576                 emitThrowExpressionTooDeepException();
577                 return;
578             }
579             n->emitBytecodeInConditionContext(*this, trueTarget, falseTarget, fallThroughMode);
580         }
581
582         void emitExpressionInfo(const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd)
583         {            
584             ASSERT(divot.offset >= divotStart.offset);
585             ASSERT(divotEnd.offset >= divot.offset);
586
587             int sourceOffset = m_scopeNode->source().startOffset();
588             unsigned firstLine = m_scopeNode->source().firstLine().oneBasedInt();
589
590             int divotOffset = divot.offset - sourceOffset;
591             int startOffset = divot.offset - divotStart.offset;
592             int endOffset = divotEnd.offset - divot.offset;
593
594             unsigned line = divot.line;
595             ASSERT(line >= firstLine);
596             line -= firstLine;
597
598             int lineStart = divot.lineStartOffset;
599             if (lineStart > sourceOffset)
600                 lineStart -= sourceOffset;
601             else
602                 lineStart = 0;
603
604             if (divotOffset < lineStart)
605                 return;
606
607             unsigned column = divotOffset - lineStart;
608
609             unsigned instructionOffset = instructions().size();
610             if (!m_isBuiltinFunction)
611                 m_codeBlock->addExpressionInfo(instructionOffset, divotOffset, startOffset, endOffset, line, column);
612         }
613
614
615         ALWAYS_INLINE bool leftHandSideNeedsCopy(bool rightHasAssignments, bool rightIsPure)
616         {
617             return (m_codeType != FunctionCode || rightHasAssignments) && !rightIsPure;
618         }
619
620         ALWAYS_INLINE RefPtr<RegisterID> emitNodeForLeftHandSide(ExpressionNode* n, bool rightHasAssignments, bool rightIsPure)
621         {
622             if (leftHandSideNeedsCopy(rightHasAssignments, rightIsPure)) {
623                 RefPtr<RegisterID> dst = newTemporary();
624                 emitNode(dst.get(), n);
625                 return dst;
626             }
627
628             return emitNode(n);
629         }
630
631         ALWAYS_INLINE RefPtr<RegisterID> emitNodeForLeftHandSideForProperty(ExpressionNode* n, bool rightHasAssignments, bool rightIsPure)
632         {
633             if (leftHandSideNeedsCopy(rightHasAssignments, rightIsPure)) {
634                 RefPtr<RegisterID> dst = newTemporary();
635                 emitNodeForProperty(dst.get(), n);
636                 return dst;
637             }
638
639             return emitNodeForProperty(n);
640         }
641
642         void hoistSloppyModeFunctionIfNecessary(const Identifier& functionName);
643
644     private:
645         void emitTypeProfilerExpressionInfo(const JSTextPosition& startDivot, const JSTextPosition& endDivot);
646     public:
647
648         // This doesn't emit expression info. If using this, make sure you shouldn't be emitting text offset.
649         void emitProfileType(RegisterID* registerToProfile, ProfileTypeBytecodeFlag); 
650         // These variables are associated with variables in a program. They could be Locals, LocalClosureVar, or ClosureVar.
651         void emitProfileType(RegisterID* registerToProfile, const Variable&, const JSTextPosition& startDivot, const JSTextPosition& endDivot);
652
653         void emitProfileType(RegisterID* registerToProfile, ProfileTypeBytecodeFlag, const JSTextPosition& startDivot, const JSTextPosition& endDivot);
654         // These are not associated with variables and don't have a global id.
655         void emitProfileType(RegisterID* registerToProfile, const JSTextPosition& startDivot, const JSTextPosition& endDivot);
656
657         void emitProfileControlFlow(int);
658         
659         RegisterID* emitLoadArrowFunctionLexicalEnvironment(const Identifier&);
660         RegisterID* ensureThis();
661         void emitLoadThisFromArrowFunctionLexicalEnvironment();
662         RegisterID* emitLoadNewTargetFromArrowFunctionLexicalEnvironment();
663
664         unsigned addConstantIndex();
665         RegisterID* emitLoad(RegisterID* dst, bool);
666         RegisterID* emitLoad(RegisterID* dst, const Identifier&);
667         RegisterID* emitLoad(RegisterID* dst, JSValue, SourceCodeRepresentation = SourceCodeRepresentation::Other);
668         RegisterID* emitLoad(RegisterID* dst, IdentifierSet& excludedList);
669         RegisterID* emitLoadGlobalObject(RegisterID* dst);
670
671         RegisterID* emitUnaryOp(OpcodeID, RegisterID* dst, RegisterID* src);
672         RegisterID* emitUnaryOp(OpcodeID, RegisterID* dst, RegisterID* src, OperandTypes);
673         RegisterID* emitUnaryOpProfiled(OpcodeID, RegisterID* dst, RegisterID* src);
674         RegisterID* emitBinaryOp(OpcodeID, RegisterID* dst, RegisterID* src1, RegisterID* src2, OperandTypes);
675         RegisterID* emitEqualityOp(OpcodeID, RegisterID* dst, RegisterID* src1, RegisterID* src2);
676         RegisterID* emitUnaryNoDstOp(OpcodeID, RegisterID* src);
677
678         RegisterID* emitCreateThis(RegisterID* dst);
679         void emitTDZCheck(RegisterID* target);
680         bool needsTDZCheck(const Variable&);
681         void emitTDZCheckIfNecessary(const Variable&, RegisterID* target, RegisterID* scope);
682         void liftTDZCheckIfPossible(const Variable&);
683         RegisterID* emitNewObject(RegisterID* dst);
684         RegisterID* emitNewArray(RegisterID* dst, ElementNode*, unsigned length, IndexingType recommendedIndexingType); // stops at first elision
685         RegisterID* emitNewArrayBuffer(RegisterID* dst, JSImmutableButterfly*, IndexingType recommendedIndexingType);
686         // FIXME: new_array_with_spread should use an array allocation profile and take a recommendedIndexingType
687         RegisterID* emitNewArrayWithSpread(RegisterID* dst, ElementNode*);
688         RegisterID* emitNewArrayWithSize(RegisterID* dst, RegisterID* length);
689
690         RegisterID* emitNewFunction(RegisterID* dst, FunctionMetadataNode*);
691         RegisterID* emitNewFunctionExpression(RegisterID* dst, FuncExprNode*);
692         RegisterID* emitNewDefaultConstructor(RegisterID* dst, ConstructorKind, const Identifier& name, const Identifier& ecmaName, const SourceCode& classSource);
693         RegisterID* emitNewArrowFunctionExpression(RegisterID*, ArrowFuncExprNode*);
694         RegisterID* emitNewMethodDefinition(RegisterID* dst, MethodDefinitionNode*);
695         RegisterID* emitNewRegExp(RegisterID* dst, RegExp*);
696
697         void emitSetFunctionNameIfNeeded(ExpressionNode* valueNode, RegisterID* value, RegisterID* name);
698
699         RegisterID* moveLinkTimeConstant(RegisterID* dst, LinkTimeConstant);
700         RegisterID* moveEmptyValue(RegisterID* dst);
701
702         RegisterID* emitToNumber(RegisterID* dst, RegisterID* src) { return emitUnaryOpProfiled(op_to_number, dst, src); }
703         RegisterID* emitToString(RegisterID* dst, RegisterID* src) { return emitUnaryOp(op_to_string, dst, src); }
704         RegisterID* emitToObject(RegisterID* dst, RegisterID* src, const Identifier& message);
705         RegisterID* emitInc(RegisterID* srcDst);
706         RegisterID* emitDec(RegisterID* srcDst);
707
708         RegisterID* emitOverridesHasInstance(RegisterID* dst, RegisterID* constructor, RegisterID* hasInstanceValue);
709         RegisterID* emitInstanceOf(RegisterID* dst, RegisterID* value, RegisterID* basePrototype);
710         RegisterID* emitInstanceOfCustom(RegisterID* dst, RegisterID* value, RegisterID* constructor, RegisterID* hasInstanceValue);
711         RegisterID* emitTypeOf(RegisterID* dst, RegisterID* src) { return emitUnaryOp(op_typeof, dst, src); }
712         RegisterID* emitInByVal(RegisterID* dst, RegisterID* property, RegisterID* base);
713         RegisterID* emitInById(RegisterID* dst, RegisterID* base, const Identifier& property);
714
715         RegisterID* emitTryGetById(RegisterID* dst, RegisterID* base, const Identifier& property);
716         RegisterID* emitGetById(RegisterID* dst, RegisterID* base, const Identifier& property);
717         RegisterID* emitGetById(RegisterID* dst, RegisterID* base, RegisterID* thisVal, const Identifier& property);
718         RegisterID* emitDirectGetById(RegisterID* dst, RegisterID* base, const Identifier& property);
719         RegisterID* emitPutById(RegisterID* base, const Identifier& property, RegisterID* value);
720         RegisterID* emitPutById(RegisterID* base, RegisterID* thisValue, const Identifier& property, RegisterID* value);
721         RegisterID* emitDirectPutById(RegisterID* base, const Identifier& property, RegisterID* value, PropertyNode::PutType);
722         RegisterID* emitDeleteById(RegisterID* dst, RegisterID* base, const Identifier&);
723         RegisterID* emitGetByVal(RegisterID* dst, RegisterID* base, RegisterID* property);
724         RegisterID* emitGetByVal(RegisterID* dst, RegisterID* base, RegisterID* thisValue, RegisterID* property);
725         RegisterID* emitPutByVal(RegisterID* base, RegisterID* property, RegisterID* value);
726         RegisterID* emitPutByVal(RegisterID* base, RegisterID* thisValue, RegisterID* property, RegisterID* value);
727         RegisterID* emitDirectPutByVal(RegisterID* base, RegisterID* property, RegisterID* value);
728         RegisterID* emitDeleteByVal(RegisterID* dst, RegisterID* base, RegisterID* property);
729
730         void emitSuperSamplerBegin();
731         void emitSuperSamplerEnd();
732
733         RegisterID* emitIdWithProfile(RegisterID* src, SpeculatedType profile);
734         void emitUnreachable();
735
736         void emitPutGetterById(RegisterID* base, const Identifier& property, unsigned propertyDescriptorOptions, RegisterID* getter);
737         void emitPutSetterById(RegisterID* base, const Identifier& property, unsigned propertyDescriptorOptions, RegisterID* setter);
738         void emitPutGetterSetter(RegisterID* base, const Identifier& property, unsigned attributes, RegisterID* getter, RegisterID* setter);
739         void emitPutGetterByVal(RegisterID* base, RegisterID* property, unsigned propertyDescriptorOptions, RegisterID* getter);
740         void emitPutSetterByVal(RegisterID* base, RegisterID* property, unsigned propertyDescriptorOptions, RegisterID* setter);
741
742         RegisterID* emitGetArgument(RegisterID* dst, int32_t index);
743
744         // Initialize object with generator fields (@generatorThis, @generatorNext, @generatorState, @generatorFrame)
745         void emitPutGeneratorFields(RegisterID* nextFunction);
746         
747         void emitPutAsyncGeneratorFields(RegisterID* nextFunction);
748
749         ExpectedFunction expectedFunctionForIdentifier(const Identifier&);
750         RegisterID* emitCall(RegisterID* dst, RegisterID* func, ExpectedFunction, CallArguments&, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd, DebuggableCall);
751         RegisterID* emitCallInTailPosition(RegisterID* dst, RegisterID* func, ExpectedFunction, CallArguments&, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd, DebuggableCall);
752         RegisterID* emitCallEval(RegisterID* dst, RegisterID* func, CallArguments&, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd, DebuggableCall);
753         RegisterID* emitCallVarargs(RegisterID* dst, RegisterID* func, RegisterID* thisRegister, RegisterID* arguments, RegisterID* firstFreeRegister, int32_t firstVarArgOffset, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd, DebuggableCall);
754         RegisterID* emitCallVarargsInTailPosition(RegisterID* dst, RegisterID* func, RegisterID* thisRegister, RegisterID* arguments, RegisterID* firstFreeRegister, int32_t firstVarArgOffset, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd, DebuggableCall);
755         RegisterID* emitCallForwardArgumentsInTailPosition(RegisterID* dst, RegisterID* func, RegisterID* thisRegister, RegisterID* firstFreeRegister, int32_t firstVarArgOffset, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd, DebuggableCall);
756
757         enum PropertyDescriptorOption {
758             PropertyConfigurable = 1,
759             PropertyWritable     = 1 << 1,
760             PropertyEnumerable   = 1 << 2,
761         };
762         void emitCallDefineProperty(RegisterID* newObj, RegisterID* propertyNameRegister,
763             RegisterID* valueRegister, RegisterID* getterRegister, RegisterID* setterRegister, unsigned options, const JSTextPosition&);
764
765         void emitEnumeration(ThrowableExpressionData* enumerationNode, ExpressionNode* subjectNode, const ScopedLambda<void(BytecodeGenerator&, RegisterID*)>& callBack, ForOfNode* = nullptr, RegisterID* forLoopSymbolTable = nullptr);
766
767         RegisterID* emitGetTemplateObject(RegisterID* dst, TaggedTemplateNode*);
768         RegisterID* emitGetGlobalPrivate(RegisterID* dst, const Identifier& property);
769
770         enum class ReturnFrom { Normal, Finally };
771         RegisterID* emitReturn(RegisterID* src, ReturnFrom = ReturnFrom::Normal);
772         RegisterID* emitEnd(RegisterID* src) { return emitUnaryNoDstOp(op_end, src); }
773
774         RegisterID* emitConstruct(RegisterID* dst, RegisterID* func, RegisterID* lazyThis, ExpectedFunction, CallArguments&, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
775         RegisterID* emitStrcat(RegisterID* dst, RegisterID* src, int count);
776         void emitToPrimitive(RegisterID* dst, RegisterID* src);
777
778         ResolveType resolveType();
779         RegisterID* emitResolveConstantLocal(RegisterID* dst, const Variable&);
780         RegisterID* emitResolveScope(RegisterID* dst, const Variable&);
781         RegisterID* emitGetFromScope(RegisterID* dst, RegisterID* scope, const Variable&, ResolveMode);
782         RegisterID* emitPutToScope(RegisterID* scope, const Variable&, RegisterID* value, ResolveMode, InitializationMode);
783
784         RegisterID* emitResolveScopeForHoistingFuncDeclInEval(RegisterID* dst, const Identifier&);
785
786         RegisterID* initializeVariable(const Variable&, RegisterID* value);
787
788         void emitLabel(Label&);
789         void emitLoopHint();
790         void emitJump(Label& target);
791         void emitJumpIfTrue(RegisterID* cond, Label& target);
792         void emitJumpIfFalse(RegisterID* cond, Label& target);
793         void emitJumpIfNotFunctionCall(RegisterID* cond, Label& target);
794         void emitJumpIfNotFunctionApply(RegisterID* cond, Label& target);
795
796         void emitEnter();
797         void emitCheckTraps();
798
799         RegisterID* emitHasIndexedProperty(RegisterID* dst, RegisterID* base, RegisterID* propertyName);
800         RegisterID* emitHasStructureProperty(RegisterID* dst, RegisterID* base, RegisterID* propertyName, RegisterID* enumerator);
801         RegisterID* emitHasGenericProperty(RegisterID* dst, RegisterID* base, RegisterID* propertyName);
802         RegisterID* emitGetPropertyEnumerator(RegisterID* dst, RegisterID* base);
803         RegisterID* emitGetEnumerableLength(RegisterID* dst, RegisterID* base);
804         RegisterID* emitGetStructurePropertyEnumerator(RegisterID* dst, RegisterID* base, RegisterID* length);
805         RegisterID* emitGetGenericPropertyEnumerator(RegisterID* dst, RegisterID* base, RegisterID* length, RegisterID* structureEnumerator);
806         RegisterID* emitEnumeratorStructurePropertyName(RegisterID* dst, RegisterID* enumerator, RegisterID* index);
807         RegisterID* emitEnumeratorGenericPropertyName(RegisterID* dst, RegisterID* enumerator, RegisterID* index);
808         RegisterID* emitToIndexString(RegisterID* dst, RegisterID* index);
809
810         RegisterID* emitIsCellWithType(RegisterID* dst, RegisterID* src, JSType);
811         RegisterID* emitIsJSArray(RegisterID* dst, RegisterID* src) { return emitIsCellWithType(dst, src, ArrayType); }
812         RegisterID* emitIsProxyObject(RegisterID* dst, RegisterID* src) { return emitIsCellWithType(dst, src, ProxyObjectType); }
813         RegisterID* emitIsRegExpObject(RegisterID* dst, RegisterID* src) { return emitIsCellWithType(dst, src, RegExpObjectType); }
814         RegisterID* emitIsMap(RegisterID* dst, RegisterID* src) { return emitIsCellWithType(dst, src, JSMapType); }
815         RegisterID* emitIsSet(RegisterID* dst, RegisterID* src) { return emitIsCellWithType(dst, src, JSSetType); }
816         RegisterID* emitIsObject(RegisterID* dst, RegisterID* src);
817         RegisterID* emitIsNumber(RegisterID* dst, RegisterID* src);
818         RegisterID* emitIsUndefined(RegisterID* dst, RegisterID* src);
819         RegisterID* emitIsEmpty(RegisterID* dst, RegisterID* src);
820         RegisterID* emitIsDerivedArray(RegisterID* dst, RegisterID* src) { return emitIsCellWithType(dst, src, DerivedArrayType); }
821         void emitRequireObjectCoercible(RegisterID* value, const String& error);
822
823         RegisterID* emitIteratorNext(RegisterID* dst, RegisterID* nextMethod, RegisterID* iterator, const ThrowableExpressionData* node, JSC::EmitAwait = JSC::EmitAwait::No);
824         RegisterID* emitIteratorNextWithValue(RegisterID* dst, RegisterID* nextMethod, RegisterID* iterator, RegisterID* value, const ThrowableExpressionData* node);
825         void emitIteratorClose(RegisterID* iterator, const ThrowableExpressionData* node, EmitAwait = EmitAwait::No);
826
827         RegisterID* emitRestParameter(RegisterID* result, unsigned numParametersToSkip);
828
829         bool emitReadOnlyExceptionIfNeeded(const Variable&);
830
831         // Start a try block. 'start' must have been emitted.
832         TryData* pushTry(Label& start, Label& handlerLabel, HandlerType);
833         // End a try block. 'end' must have been emitted.
834         void popTry(TryData*, Label& end);
835         void emitCatch(RegisterID* exceptionRegister, RegisterID* thrownValueRegister, TryData*);
836
837     private:
838         static const int CurrentLexicalScopeIndex = -2;
839         static const int OutermostLexicalScopeIndex = -1;
840
841         int currentLexicalScopeIndex() const
842         {
843             int size = static_cast<int>(m_lexicalScopeStack.size());
844             ASSERT(static_cast<size_t>(size) == m_lexicalScopeStack.size());
845             ASSERT(size >= 0);
846             if (!size)
847                 return OutermostLexicalScopeIndex;
848             return size - 1;
849         }
850
851     public:
852         void restoreScopeRegister();
853         void restoreScopeRegister(int lexicalScopeIndex);
854
855         int labelScopeDepthToLexicalScopeIndex(int labelScopeDepth);
856
857         void emitThrow(RegisterID* exc)
858         { 
859             m_usesExceptions = true;
860             emitUnaryNoDstOp(op_throw, exc);
861         }
862
863         void emitThrowStaticError(ErrorType, RegisterID*);
864         void emitThrowStaticError(ErrorType, const Identifier& message);
865         void emitThrowReferenceError(const String& message);
866         void emitThrowTypeError(const String& message);
867         void emitThrowTypeError(const Identifier& message);
868         void emitThrowRangeError(const Identifier& message);
869         void emitThrowOutOfMemoryError();
870
871         void emitPushCatchScope(VariableEnvironment&);
872         void emitPopCatchScope(VariableEnvironment&);
873
874         RegisterID* emitGetIterator(RegisterID*, ThrowableExpressionData*);
875         RegisterID* emitGetAsyncIterator(RegisterID*, ThrowableExpressionData*);
876
877         void emitAwait(RegisterID*);
878         void emitGetScope();
879         RegisterID* emitPushWithScope(RegisterID* objectScope);
880         void emitPopWithScope();
881         void emitPutThisToArrowFunctionContextScope();
882         void emitPutNewTargetToArrowFunctionContextScope();
883         void emitPutDerivedConstructorToArrowFunctionContextScope();
884         RegisterID* emitLoadDerivedConstructorFromArrowFunctionLexicalEnvironment();
885
886         void emitDebugHook(DebugHookType, const JSTextPosition&);
887         void emitDebugHook(DebugHookType, unsigned line, unsigned charOffset, unsigned lineStart);
888         void emitDebugHook(StatementNode*);
889         void emitDebugHook(ExpressionNode*);
890         void emitWillLeaveCallFrameDebugHook();
891
892         class CompletionRecordScope {
893         public:
894             CompletionRecordScope(BytecodeGenerator& generator, bool needCompletionRecordRegisters = true)
895                 : m_generator(generator)
896             {
897                 if (needCompletionRecordRegisters && m_generator.allocateCompletionRecordRegisters())
898                     m_needToReleaseOnDestruction = true;
899             }
900             ~CompletionRecordScope()
901             {
902                 if (m_needToReleaseOnDestruction)
903                     m_generator.releaseCompletionRecordRegisters();
904             }
905
906         private:
907             BytecodeGenerator& m_generator;
908             bool m_needToReleaseOnDestruction { false };
909         };
910
911         RegisterID* completionTypeRegister() const
912         {
913             ASSERT(m_completionTypeRegister);
914             return m_completionTypeRegister.get();
915         }
916         RegisterID* completionValueRegister() const
917         {
918             ASSERT(m_completionValueRegister);
919             return m_completionValueRegister.get();
920         }
921
922         void emitSetCompletionType(CompletionType type)
923         {
924             emitLoad(completionTypeRegister(), JSValue(static_cast<int>(type)));
925         }
926         void emitSetCompletionValue(RegisterID* reg)
927         {
928             move(completionValueRegister(), reg);
929         }
930
931         void emitJumpIf(OpcodeID compareOpcode, RegisterID* completionTypeRegister, CompletionType, Label& jumpTarget);
932
933         bool emitJumpViaFinallyIfNeeded(int targetLabelScopeDepth, Label& jumpTarget);
934         bool emitReturnViaFinallyIfNeeded(RegisterID* returnRegister);
935         void emitFinallyCompletion(FinallyContext&, RegisterID* completionTypeRegister, Label& normalCompletionLabel);
936
937     private:
938         bool allocateCompletionRecordRegisters();
939         void releaseCompletionRecordRegisters();
940
941     public:
942         FinallyContext* pushFinallyControlFlowScope(Label& finallyLabel);
943         FinallyContext popFinallyControlFlowScope();
944
945         void pushIndexedForInScope(RegisterID* local, RegisterID* index);
946         void popIndexedForInScope(RegisterID* local);
947         void pushStructureForInScope(RegisterID* local, RegisterID* index, RegisterID* property, RegisterID* enumerator);
948         void popStructureForInScope(RegisterID* local);
949
950         LabelScope* breakTarget(const Identifier&);
951         LabelScope* continueTarget(const Identifier&);
952
953         void beginSwitch(RegisterID*, SwitchInfo::SwitchType);
954         void endSwitch(uint32_t clauseCount, const Vector<Ref<Label>, 8>&, ExpressionNode**, Label& defaultLabel, int32_t min, int32_t range);
955
956         void emitYieldPoint(RegisterID*, JSAsyncGeneratorFunction::AsyncGeneratorSuspendReason);
957
958         void emitGeneratorStateLabel();
959         void emitGeneratorStateChange(int32_t state);
960         RegisterID* emitYield(RegisterID* argument, JSAsyncGeneratorFunction::AsyncGeneratorSuspendReason = JSAsyncGeneratorFunction::AsyncGeneratorSuspendReason::Yield);
961         RegisterID* emitDelegateYield(RegisterID* argument, ThrowableExpressionData*);
962         RegisterID* generatorStateRegister() { return &m_parameters[static_cast<int32_t>(JSGeneratorFunction::GeneratorArgument::State)]; }
963         RegisterID* generatorValueRegister() { return &m_parameters[static_cast<int32_t>(JSGeneratorFunction::GeneratorArgument::Value)]; }
964         RegisterID* generatorResumeModeRegister() { return &m_parameters[static_cast<int32_t>(JSGeneratorFunction::GeneratorArgument::ResumeMode)]; }
965         RegisterID* generatorFrameRegister() { return &m_parameters[static_cast<int32_t>(JSGeneratorFunction::GeneratorArgument::Frame)]; }
966
967         CodeType codeType() const { return m_codeType; }
968
969         bool shouldBeConcernedWithCompletionValue() const { return m_codeType != FunctionCode; }
970
971         bool shouldEmitDebugHooks() const { return m_shouldEmitDebugHooks; }
972         
973         bool isStrictMode() const { return m_codeBlock->isStrictMode(); }
974
975         SourceParseMode parseMode() const { return m_codeBlock->parseMode(); }
976         
977         bool isBuiltinFunction() const { return m_isBuiltinFunction; }
978
979         OpcodeID lastOpcodeID() const { return m_lastOpcodeID; }
980         
981         bool isDerivedConstructorContext() { return m_derivedContextType == DerivedContextType::DerivedConstructorContext; }
982         bool isDerivedClassContext() { return m_derivedContextType == DerivedContextType::DerivedMethodContext; }
983         bool isArrowFunction() { return m_codeBlock->isArrowFunction(); }
984
985         enum class TDZCheckOptimization { Optimize, DoNotOptimize };
986         enum class NestedScopeType { IsNested, IsNotNested };
987     private:
988         enum class TDZRequirement { UnderTDZ, NotUnderTDZ };
989         enum class ScopeType { CatchScope, LetConstScope, FunctionNameScope };
990         enum class ScopeRegisterType { Var, Block };
991         void pushLexicalScopeInternal(VariableEnvironment&, TDZCheckOptimization, NestedScopeType, RegisterID** constantSymbolTableResult, TDZRequirement, ScopeType, ScopeRegisterType);
992         void initializeBlockScopedFunctions(VariableEnvironment&, FunctionStack&, RegisterID* constantSymbolTable);
993         void popLexicalScopeInternal(VariableEnvironment&);
994         template<typename LookUpVarKindFunctor>
995         bool instantiateLexicalVariables(const VariableEnvironment&, SymbolTable*, ScopeRegisterType, LookUpVarKindFunctor);
996         void emitPrefillStackTDZVariables(const VariableEnvironment&, SymbolTable*);
997         void emitPopScope(RegisterID* dst, RegisterID* scope);
998         RegisterID* emitGetParentScope(RegisterID* dst, RegisterID* scope);
999         void emitPushFunctionNameScope(const Identifier& property, RegisterID* value, bool isCaptured);
1000         void emitNewFunctionExpressionCommon(RegisterID*, FunctionMetadataNode*);
1001         
1002         bool isNewTargetUsedInInnerArrowFunction();
1003         bool isArgumentsUsedInInnerArrowFunction();
1004
1005         void emitToThis();
1006
1007         RegisterID* emitMove(RegisterID* dst, RegisterID* src);
1008
1009     public:
1010         bool isSuperUsedInInnerArrowFunction();
1011         bool isSuperCallUsedInInnerArrowFunction();
1012         bool isThisUsedInInnerArrowFunction();
1013         void pushLexicalScope(VariableEnvironmentNode*, TDZCheckOptimization, NestedScopeType = NestedScopeType::IsNotNested, RegisterID** constantSymbolTableResult = nullptr, bool shouldInitializeBlockScopedFunctions = true);
1014         void popLexicalScope(VariableEnvironmentNode*);
1015         void prepareLexicalScopeForNextForLoopIteration(VariableEnvironmentNode*, RegisterID* loopSymbolTable);
1016         int labelScopeDepth() const;
1017         UnlinkedArrayProfile newArrayProfile();
1018
1019     private:
1020         ParserError generate();
1021         void reclaimFreeRegisters();
1022         Variable variableForLocalEntry(const Identifier&, const SymbolTableEntry&, int symbolTableConstantIndex, bool isLexicallyScoped);
1023
1024         void emitOpcode(OpcodeID);
1025         UnlinkedArrayAllocationProfile newArrayAllocationProfile(IndexingType);
1026         UnlinkedObjectAllocationProfile newObjectAllocationProfile();
1027         UnlinkedValueProfile emitProfiledOpcode(OpcodeID);
1028         int kill(RegisterID* dst)
1029         {
1030             int index = dst->index();
1031             m_staticPropertyAnalyzer.kill(index);
1032             return index;
1033         }
1034
1035         void retrieveLastBinaryOp(int& dstIndex, int& src1Index, int& src2Index);
1036         void retrieveLastUnaryOp(int& dstIndex, int& srcIndex);
1037         ALWAYS_INLINE void rewindBinaryOp();
1038         ALWAYS_INLINE void rewindUnaryOp();
1039
1040         void allocateCalleeSaveSpace();
1041         void allocateAndEmitScope();
1042
1043         using BigIntMapEntry = std::tuple<UniquedStringImpl*, uint8_t, bool>;
1044
1045         using NumberMap = HashMap<double, JSValue>;
1046         using IdentifierStringMap = HashMap<UniquedStringImpl*, JSString*, IdentifierRepHash>;
1047         using IdentifierBigIntMap = HashMap<BigIntMapEntry, JSBigInt*>;
1048         using TemplateObjectDescriptorMap = HashMap<Ref<TemplateObjectDescriptor>, JSTemplateObjectDescriptor*>;
1049
1050         // Helper for emitCall() and emitConstruct(). This works because the set of
1051         // expected functions have identical behavior for both call and construct
1052         // (i.e. "Object()" is identical to "new Object()").
1053         ExpectedFunction emitExpectedFunctionSnippet(RegisterID* dst, RegisterID* func, ExpectedFunction, CallArguments&, Label& done);
1054         
1055         RegisterID* emitCall(OpcodeID, RegisterID* dst, RegisterID* func, ExpectedFunction, CallArguments&, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd, DebuggableCall);
1056
1057         RegisterID* emitCallIterator(RegisterID* iterator, RegisterID* argument, ThrowableExpressionData*);
1058         RegisterID* newRegister();
1059
1060         // Adds an anonymous local var slot. To give this slot a name, add it to symbolTable().
1061         RegisterID* addVar()
1062         {
1063             ++m_codeBlock->m_numVars;
1064             RegisterID* result = newRegister();
1065             ASSERT(VirtualRegister(result->index()).toLocal() == m_codeBlock->m_numVars - 1);
1066             result->ref(); // We should never free this slot.
1067             return result;
1068         }
1069
1070         // Initializes the stack form the parameter; does nothing for the symbol table.
1071         RegisterID* initializeNextParameter();
1072         UniquedStringImpl* visibleNameForParameter(DestructuringPatternNode*);
1073         
1074         RegisterID& registerFor(VirtualRegister reg)
1075         {
1076             if (reg.isLocal())
1077                 return m_calleeLocals[reg.toLocal()];
1078
1079             if (reg.offset() == CallFrameSlot::callee)
1080                 return m_calleeRegister;
1081
1082             ASSERT(m_parameters.size());
1083             return m_parameters[reg.toArgument()];
1084         }
1085
1086         bool hasConstant(const Identifier&) const;
1087         unsigned addConstant(const Identifier&);
1088         RegisterID* addConstantValue(JSValue, SourceCodeRepresentation = SourceCodeRepresentation::Other);
1089         RegisterID* addConstantEmptyValue();
1090
1091         UnlinkedFunctionExecutable* makeFunction(FunctionMetadataNode* metadata)
1092         {
1093             DerivedContextType newDerivedContextType = DerivedContextType::None;
1094
1095             if (SourceParseModeSet(SourceParseMode::ArrowFunctionMode, SourceParseMode::AsyncArrowFunctionMode, SourceParseMode::AsyncArrowFunctionBodyMode).contains(metadata->parseMode())) {
1096                 if (constructorKind() == ConstructorKind::Extends || isDerivedConstructorContext())
1097                     newDerivedContextType = DerivedContextType::DerivedConstructorContext;
1098                 else if (m_codeBlock->isClassContext() || isDerivedClassContext())
1099                     newDerivedContextType = DerivedContextType::DerivedMethodContext;
1100             }
1101
1102             VariableEnvironment variablesUnderTDZ;
1103             getVariablesUnderTDZ(variablesUnderTDZ);
1104
1105             // FIXME: These flags, ParserModes and propagation to XXXCodeBlocks should be reorganized.
1106             // https://bugs.webkit.org/show_bug.cgi?id=151547
1107             SourceParseMode parseMode = metadata->parseMode();
1108             ConstructAbility constructAbility = constructAbilityForParseMode(parseMode);
1109             if (parseMode == SourceParseMode::MethodMode && metadata->constructorKind() != ConstructorKind::None)
1110                 constructAbility = ConstructAbility::CanConstruct;
1111
1112             return UnlinkedFunctionExecutable::create(m_vm, m_scopeNode->source(), metadata, isBuiltinFunction() ? UnlinkedBuiltinFunction : UnlinkedNormalFunction, constructAbility, scriptMode(), variablesUnderTDZ, newDerivedContextType);
1113         }
1114
1115         void getVariablesUnderTDZ(VariableEnvironment&);
1116
1117         RegisterID* emitConstructVarargs(RegisterID* dst, RegisterID* func, RegisterID* thisRegister, RegisterID* arguments, RegisterID* firstFreeRegister, int32_t firstVarArgOffset, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd, DebuggableCall);
1118         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, DebuggableCall);
1119         
1120         void emitLogShadowChickenPrologueIfNecessary();
1121         void emitLogShadowChickenTailIfNecessary();
1122
1123         void initializeParameters(FunctionParameters&);
1124         void initializeVarLexicalEnvironment(int symbolTableConstantIndex, SymbolTable* functionSymbolTable, bool hasCapturedVariables);
1125         void initializeDefaultParameterValuesAndSetupFunctionScopeStack(FunctionParameters&, bool isSimpleParameterList, FunctionNode*, SymbolTable*, int symbolTableConstantIndex, const ScopedLambda<bool (UniquedStringImpl*)>& captures, bool shouldCreateArgumentsVariableInParameterScope);
1126         void initializeArrowFunctionContextScopeIfNeeded(SymbolTable* functionSymbolTable = nullptr, bool canReuseLexicalEnvironment = false);
1127         bool needsDerivedConstructorInArrowFunctionLexicalEnvironment();
1128
1129         enum class TDZNecessityLevel {
1130             NotNeeded,
1131             Optimize,
1132             DoNotOptimize
1133         };
1134         typedef HashMap<RefPtr<UniquedStringImpl>, TDZNecessityLevel, IdentifierRepHash> TDZMap;
1135
1136     public:
1137         JSString* addStringConstant(const Identifier&);
1138         JSValue addBigIntConstant(const Identifier&, uint8_t radix, bool sign);
1139         RegisterID* addTemplateObjectConstant(Ref<TemplateObjectDescriptor>&&);
1140
1141         Vector<UnlinkedInstruction, 0, UnsafeVectorOverflow>& instructions() { return m_instructions; }
1142
1143         RegisterID* emitThrowExpressionTooDeepException();
1144
1145         class PreservedTDZStack {
1146         private:
1147             Vector<TDZMap> m_preservedTDZStack;
1148             friend class BytecodeGenerator;
1149         };
1150
1151         void preserveTDZStack(PreservedTDZStack&);
1152         void restoreTDZStack(const PreservedTDZStack&);
1153
1154     private:
1155         Vector<UnlinkedInstruction, 0, UnsafeVectorOverflow> m_instructions;
1156
1157         bool m_shouldEmitDebugHooks;
1158
1159         struct LexicalScopeStackEntry {
1160             SymbolTable* m_symbolTable;
1161             RegisterID* m_scope;
1162             bool m_isWithScope;
1163             int m_symbolTableConstantIndex;
1164         };
1165         Vector<LexicalScopeStackEntry> m_lexicalScopeStack;
1166
1167         Vector<TDZMap> m_TDZStack;
1168         std::optional<size_t> m_varScopeLexicalScopeStackIndex;
1169         void pushTDZVariables(const VariableEnvironment&, TDZCheckOptimization, TDZRequirement);
1170
1171         ScopeNode* const m_scopeNode;
1172         Strong<UnlinkedCodeBlock> m_codeBlock;
1173
1174         // Some of these objects keep pointers to one another. They are arranged
1175         // to ensure a sane destruction order that avoids references to freed memory.
1176         HashSet<RefPtr<UniquedStringImpl>, IdentifierRepHash> m_functions;
1177         RegisterID m_ignoredResultRegister;
1178         RegisterID m_thisRegister;
1179         RegisterID m_calleeRegister;
1180         RegisterID* m_scopeRegister { nullptr };
1181         RegisterID* m_topMostScope { nullptr };
1182         RegisterID* m_argumentsRegister { nullptr };
1183         RegisterID* m_lexicalEnvironmentRegister { nullptr };
1184         RegisterID* m_generatorRegister { nullptr };
1185         RegisterID* m_emptyValueRegister { nullptr };
1186         RegisterID* m_globalObjectRegister { nullptr };
1187         RegisterID* m_newTargetRegister { nullptr };
1188         RegisterID* m_isDerivedConstuctor { nullptr };
1189         RegisterID* m_linkTimeConstantRegisters[LinkTimeConstantCount];
1190         RegisterID* m_arrowFunctionContextLexicalEnvironmentRegister { nullptr };
1191         RegisterID* m_promiseCapabilityRegister { nullptr };
1192
1193         RefPtr<RegisterID> m_completionTypeRegister;
1194         RefPtr<RegisterID> m_completionValueRegister;
1195
1196         FinallyContext* m_currentFinallyContext { nullptr };
1197
1198         SegmentedVector<RegisterID*, 16> m_localRegistersForCalleeSaveRegisters;
1199         SegmentedVector<RegisterID, 32> m_constantPoolRegisters;
1200         SegmentedVector<RegisterID, 32> m_calleeLocals;
1201         SegmentedVector<RegisterID, 32> m_parameters;
1202         SegmentedVector<Label, 32> m_labels;
1203         SegmentedVector<LabelScope, 32> m_labelScopes;
1204         unsigned m_finallyDepth { 0 };
1205         int m_localScopeDepth { 0 };
1206         const CodeType m_codeType;
1207
1208         int localScopeDepth() const;
1209         void pushLocalControlFlowScope();
1210         void popLocalControlFlowScope();
1211
1212         // FIXME: Restore overflow checking with UnsafeVectorOverflow once SegmentVector supports it.
1213         // https://bugs.webkit.org/show_bug.cgi?id=165980
1214         SegmentedVector<ControlFlowScope, 16> m_controlFlowScopeStack;
1215         Vector<SwitchInfo> m_switchContextStack;
1216         Vector<Ref<ForInContext>> m_forInContextStack;
1217         Vector<TryContext> m_tryContextStack;
1218         unsigned m_yieldPoints { 0 };
1219
1220         Strong<SymbolTable> m_generatorFrameSymbolTable;
1221         int m_generatorFrameSymbolTableIndex { 0 };
1222
1223         enum FunctionVariableType : uint8_t { NormalFunctionVariable, TopLevelFunctionVariable };
1224         Vector<std::pair<FunctionMetadataNode*, FunctionVariableType>> m_functionsToInitialize;
1225         bool m_needToInitializeArguments { false };
1226         RestParameterNode* m_restParameter { nullptr };
1227         
1228         Vector<TryRange> m_tryRanges;
1229         SegmentedVector<TryData, 8> m_tryData;
1230
1231         int m_nextConstantOffset { 0 };
1232
1233         typedef HashMap<FunctionMetadataNode*, unsigned> FunctionOffsetMap;
1234         FunctionOffsetMap m_functionOffsets;
1235         
1236         // Constant pool
1237         IdentifierMap m_identifierMap;
1238
1239         typedef HashMap<EncodedJSValueWithRepresentation, unsigned, EncodedJSValueWithRepresentationHash, EncodedJSValueWithRepresentationHashTraits> JSValueMap;
1240         JSValueMap m_jsValueMap;
1241         IdentifierStringMap m_stringMap;
1242         IdentifierBigIntMap m_bigIntMap;
1243         TemplateObjectDescriptorMap m_templateObjectDescriptorMap;
1244
1245         StaticPropertyAnalyzer m_staticPropertyAnalyzer { &m_instructions };
1246
1247         VM* m_vm;
1248
1249         OpcodeID m_lastOpcodeID = op_end;
1250 #ifndef NDEBUG
1251         size_t m_lastOpcodePosition { 0 };
1252 #endif
1253
1254         bool m_usesExceptions { false };
1255         bool m_expressionTooDeep { false };
1256         bool m_isBuiltinFunction { false };
1257         bool m_usesNonStrictEval { false };
1258         bool m_inTailPosition { false };
1259         bool m_needsToUpdateArrowFunctionContext;
1260         DerivedContextType m_derivedContextType { DerivedContextType::None };
1261
1262         using CatchEntry = std::tuple<TryData*, int, int>;
1263         Vector<CatchEntry> m_catchesToEmit;
1264     };
1265
1266 } // namespace JSC
1267
1268 namespace WTF {
1269
1270 void printInternal(PrintStream&, JSC::Variable::VariableKind);
1271
1272 } // namespace WTF