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