[ES6] "super" and "this" should be lexically bound inside an arrow function and shoul...
[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         void emitCheckHasInstance(RegisterID* dst, RegisterID* value, RegisterID* base, Label* target);
538         RegisterID* emitInstanceOf(RegisterID* dst, RegisterID* value, RegisterID* basePrototype);
539         RegisterID* emitTypeOf(RegisterID* dst, RegisterID* src) { return emitUnaryOp(op_typeof, dst, src); }
540         RegisterID* emitIn(RegisterID* dst, RegisterID* property, RegisterID* base) { return emitBinaryOp(op_in, dst, property, base, OperandTypes()); }
541
542         RegisterID* emitGetById(RegisterID* dst, RegisterID* base, const Identifier& property);
543         RegisterID* emitPutById(RegisterID* base, const Identifier& property, RegisterID* value);
544         RegisterID* emitDirectPutById(RegisterID* base, const Identifier& property, RegisterID* value, PropertyNode::PutType);
545         RegisterID* emitDeleteById(RegisterID* dst, RegisterID* base, const Identifier&);
546         RegisterID* emitGetByVal(RegisterID* dst, RegisterID* base, RegisterID* property);
547         RegisterID* emitGetArgumentByVal(RegisterID* dst, RegisterID* base, RegisterID* property);
548         RegisterID* emitPutByVal(RegisterID* base, RegisterID* property, RegisterID* value);
549         RegisterID* emitDirectPutByVal(RegisterID* base, RegisterID* property, RegisterID* value);
550         RegisterID* emitDeleteByVal(RegisterID* dst, RegisterID* base, RegisterID* property);
551         RegisterID* emitPutByIndex(RegisterID* base, unsigned index, RegisterID* value);
552
553         RegisterID* emitAssert(RegisterID* condition, int line);
554
555         void emitPutGetterById(RegisterID* base, const Identifier& property, unsigned propertyDescriptorOptions, RegisterID* getter);
556         void emitPutSetterById(RegisterID* base, const Identifier& property, unsigned propertyDescriptorOptions, RegisterID* setter);
557         void emitPutGetterSetter(RegisterID* base, const Identifier& property, unsigned attributes, RegisterID* getter, RegisterID* setter);
558         void emitPutGetterByVal(RegisterID* base, RegisterID* property, unsigned propertyDescriptorOptions, RegisterID* getter);
559         void emitPutSetterByVal(RegisterID* base, RegisterID* property, unsigned propertyDescriptorOptions, RegisterID* setter);
560         
561         ExpectedFunction expectedFunctionForIdentifier(const Identifier&);
562         RegisterID* emitCall(RegisterID* dst, RegisterID* func, ExpectedFunction, CallArguments&, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
563         RegisterID* emitCallInTailPosition(RegisterID* dst, RegisterID* func, ExpectedFunction, CallArguments&, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
564         RegisterID* emitCallEval(RegisterID* dst, RegisterID* func, CallArguments&, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
565         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);
566         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);
567
568         enum PropertyDescriptorOption {
569             PropertyConfigurable = 1,
570             PropertyWritable     = 1 << 1,
571             PropertyEnumerable   = 1 << 2,
572         };
573         void emitCallDefineProperty(RegisterID* newObj, RegisterID* propertyNameRegister,
574             RegisterID* valueRegister, RegisterID* getterRegister, RegisterID* setterRegister, unsigned options, const JSTextPosition&);
575
576         void emitEnumeration(ThrowableExpressionData* enumerationNode, ExpressionNode* subjectNode, const std::function<void(BytecodeGenerator&, RegisterID*)>& callBack, VariableEnvironmentNode* = nullptr, RegisterID* forLoopSymbolTable = nullptr);
577
578         RegisterID* emitGetTemplateObject(RegisterID* dst, TaggedTemplateNode*);
579
580         RegisterID* emitReturn(RegisterID* src);
581         RegisterID* emitEnd(RegisterID* src) { return emitUnaryNoDstOp(op_end, src); }
582
583         RegisterID* emitConstruct(RegisterID* dst, RegisterID* func, ExpectedFunction, CallArguments&, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
584         RegisterID* emitStrcat(RegisterID* dst, RegisterID* src, int count);
585         void emitToPrimitive(RegisterID* dst, RegisterID* src);
586
587         ResolveType resolveType();
588         RegisterID* emitResolveConstantLocal(RegisterID* dst, const Variable&);
589         RegisterID* emitResolveScope(RegisterID* dst, const Variable&);
590         RegisterID* emitGetFromScope(RegisterID* dst, RegisterID* scope, const Variable&, ResolveMode);
591         RegisterID* emitPutToScope(RegisterID* scope, const Variable&, RegisterID* value, ResolveMode, InitializationMode);
592         RegisterID* initializeVariable(const Variable&, RegisterID* value);
593
594         PassRefPtr<Label> emitLabel(Label*);
595         void emitLoopHint();
596         PassRefPtr<Label> emitJump(Label* target);
597         PassRefPtr<Label> emitJumpIfTrue(RegisterID* cond, Label* target);
598         PassRefPtr<Label> emitJumpIfFalse(RegisterID* cond, Label* target);
599         PassRefPtr<Label> emitJumpIfNotFunctionCall(RegisterID* cond, Label* target);
600         PassRefPtr<Label> emitJumpIfNotFunctionApply(RegisterID* cond, Label* target);
601         void emitPopScopes(RegisterID* srcDst, int targetScopeDepth);
602
603         RegisterID* emitHasIndexedProperty(RegisterID* dst, RegisterID* base, RegisterID* propertyName);
604         RegisterID* emitHasStructureProperty(RegisterID* dst, RegisterID* base, RegisterID* propertyName, RegisterID* enumerator);
605         RegisterID* emitHasGenericProperty(RegisterID* dst, RegisterID* base, RegisterID* propertyName);
606         RegisterID* emitGetPropertyEnumerator(RegisterID* dst, RegisterID* base);
607         RegisterID* emitGetEnumerableLength(RegisterID* dst, RegisterID* base);
608         RegisterID* emitGetStructurePropertyEnumerator(RegisterID* dst, RegisterID* base, RegisterID* length);
609         RegisterID* emitGetGenericPropertyEnumerator(RegisterID* dst, RegisterID* base, RegisterID* length, RegisterID* structureEnumerator);
610         RegisterID* emitEnumeratorStructurePropertyName(RegisterID* dst, RegisterID* enumerator, RegisterID* index);
611         RegisterID* emitEnumeratorGenericPropertyName(RegisterID* dst, RegisterID* enumerator, RegisterID* index);
612         RegisterID* emitToIndexString(RegisterID* dst, RegisterID* index);
613
614         RegisterID* emitIsObject(RegisterID* dst, RegisterID* src);
615         RegisterID* emitIsUndefined(RegisterID* dst, RegisterID* src);
616         void emitRequireObjectCoercible(RegisterID* value, const String& error);
617
618         RegisterID* emitIteratorNext(RegisterID* dst, RegisterID* iterator, const ThrowableExpressionData* node);
619         RegisterID* emitIteratorNextWithValue(RegisterID* dst, RegisterID* iterator, RegisterID* value, const ThrowableExpressionData* node);
620         void emitIteratorClose(RegisterID* iterator, const ThrowableExpressionData* node);
621
622         RegisterID* emitRestParameter(RegisterID* result, unsigned numParametersToSkip);
623
624         bool emitReadOnlyExceptionIfNeeded(const Variable&);
625
626         // Start a try block. 'start' must have been emitted.
627         TryData* pushTry(Label* start);
628         // End a try block. 'end' must have been emitted.
629         void popTryAndEmitCatch(TryData*, RegisterID* exceptionRegister, RegisterID* thrownValueRegister, Label* end, HandlerType);
630
631         void emitThrow(RegisterID* exc)
632         { 
633             m_usesExceptions = true;
634             emitUnaryNoDstOp(op_throw, exc);
635         }
636
637         void emitThrowReferenceError(const String& message);
638         void emitThrowTypeError(const String& message);
639
640         void emitPushCatchScope(const Identifier& property, RegisterID* exceptionValue, VariableEnvironment&);
641         void emitPopCatchScope(VariableEnvironment&);
642
643         void emitGetScope();
644         RegisterID* emitPushWithScope(RegisterID* objectScope);
645         void emitPopWithScope();
646         void emitPutThisToArrowFunctionContextScope();
647         void emitPutNewTargetToArrowFunctionContextScope();
648         void emitPutDerivedConstructorToArrowFunctionContextScope();
649         RegisterID* emitLoadDerivedConstructorFromArrowFunctionLexicalEnvironment();
650
651         void emitDebugHook(DebugHookID, unsigned line, unsigned charOffset, unsigned lineStart);
652
653         bool isInFinallyBlock() { return m_finallyDepth > 0; }
654
655         void pushFinallyContext(StatementNode* finallyBlock);
656         void popFinallyContext();
657         void pushIteratorCloseContext(RegisterID* iterator, ThrowableExpressionData* enumerationNode);
658         void popIteratorCloseContext();
659
660         void pushIndexedForInScope(RegisterID* local, RegisterID* index);
661         void popIndexedForInScope(RegisterID* local);
662         void pushStructureForInScope(RegisterID* local, RegisterID* index, RegisterID* property, RegisterID* enumerator);
663         void popStructureForInScope(RegisterID* local);
664         void invalidateForInContextForLocal(RegisterID* local);
665
666         LabelScopePtr breakTarget(const Identifier&);
667         LabelScopePtr continueTarget(const Identifier&);
668
669         void beginSwitch(RegisterID*, SwitchInfo::SwitchType);
670         void endSwitch(uint32_t clauseCount, RefPtr<Label>*, ExpressionNode**, Label* defaultLabel, int32_t min, int32_t range);
671
672         void emitYieldPoint(RegisterID*);
673         void emitSave(Label* mergePoint, unsigned liveCalleeLocalsIndex);
674         void emitResume(Label* mergePoint, unsigned liveCalleeLocalsIndex);
675
676         void emitGeneratorStateLabel();
677         void emitGeneratorStateChange(int32_t state);
678         RegisterID* emitYield(RegisterID* argument);
679         RegisterID* emitDelegateYield(RegisterID* argument, ThrowableExpressionData*);
680         void beginGenerator(RegisterID*);
681         void endGenerator(Label* defaultLabel);
682         RegisterID* generatorStateRegister() { return &m_parameters[2]; }
683         RegisterID* generatorValueRegister() { return &m_parameters[3]; }
684         RegisterID* generatorResumeModeRegister() { return &m_parameters[4]; }
685
686         CodeType codeType() const { return m_codeType; }
687
688         bool shouldEmitProfileHooks() { return m_shouldEmitProfileHooks; }
689         bool shouldEmitDebugHooks() { return m_shouldEmitDebugHooks; }
690         
691         bool isStrictMode() const { return m_codeBlock->isStrictMode(); }
692
693         SourceParseMode parseMode() const { return m_codeBlock->parseMode(); }
694         
695         bool isBuiltinFunction() const { return m_isBuiltinFunction; }
696
697         OpcodeID lastOpcodeID() const { return m_lastOpcodeID; }
698
699     private:
700         enum class TDZRequirement { UnderTDZ, NotUnderTDZ };
701         enum class ScopeType { CatchScope, LetConstScope, FunctionNameScope };
702         enum class ScopeRegisterType { Var, Block };
703         void pushLexicalScopeInternal(VariableEnvironment&, bool canOptimizeTDZChecks, RegisterID** constantSymbolTableResult, TDZRequirement, ScopeType, ScopeRegisterType);
704         void popLexicalScopeInternal(VariableEnvironment&, TDZRequirement);
705         template<typename LookUpVarKindFunctor>
706         bool instantiateLexicalVariables(const VariableEnvironment&, SymbolTable*, ScopeRegisterType, LookUpVarKindFunctor);
707         void emitPrefillStackTDZVariables(const VariableEnvironment&, SymbolTable*);
708         void emitPopScope(RegisterID* dst, RegisterID* scope);
709         RegisterID* emitGetParentScope(RegisterID* dst, RegisterID* scope);
710         void emitPushFunctionNameScope(const Identifier& property, RegisterID* value, bool isCaptured);
711         void emitNewFunctionExpressionCommon(RegisterID*, BaseFuncExprNode*);
712
713     public:
714         void pushLexicalScope(VariableEnvironmentNode*, bool canOptimizeTDZChecks, RegisterID** constantSymbolTableResult = nullptr);
715         void popLexicalScope(VariableEnvironmentNode*);
716         void prepareLexicalScopeForNextForLoopIteration(VariableEnvironmentNode*, RegisterID* loopSymbolTable);
717         int labelScopeDepth() const;
718
719     private:
720         void reclaimFreeRegisters();
721         Variable variableForLocalEntry(const Identifier&, const SymbolTableEntry&, int symbolTableConstantIndex, bool isLexicallyScoped);
722
723         void emitOpcode(OpcodeID);
724         UnlinkedArrayAllocationProfile newArrayAllocationProfile();
725         UnlinkedObjectAllocationProfile newObjectAllocationProfile();
726         UnlinkedArrayProfile newArrayProfile();
727         UnlinkedValueProfile emitProfiledOpcode(OpcodeID);
728         int kill(RegisterID* dst)
729         {
730             int index = dst->index();
731             m_staticPropertyAnalyzer.kill(index);
732             return index;
733         }
734
735         void retrieveLastBinaryOp(int& dstIndex, int& src1Index, int& src2Index);
736         void retrieveLastUnaryOp(int& dstIndex, int& srcIndex);
737         ALWAYS_INLINE void rewindBinaryOp();
738         ALWAYS_INLINE void rewindUnaryOp();
739
740         void allocateCalleeSaveSpace();
741         void allocateAndEmitScope();
742         void emitComplexPopScopes(RegisterID*, ControlFlowContext* topScope, ControlFlowContext* bottomScope);
743
744         typedef HashMap<double, JSValue> NumberMap;
745         typedef HashMap<UniquedStringImpl*, JSString*, IdentifierRepHash> IdentifierStringMap;
746         typedef HashMap<TemplateRegistryKey, JSTemplateRegistryKey*> TemplateRegistryKeyMap;
747         
748         // Helper for emitCall() and emitConstruct(). This works because the set of
749         // expected functions have identical behavior for both call and construct
750         // (i.e. "Object()" is identical to "new Object()").
751         ExpectedFunction emitExpectedFunctionSnippet(RegisterID* dst, RegisterID* func, ExpectedFunction, CallArguments&, Label* done);
752         
753         RegisterID* emitCall(OpcodeID, RegisterID* dst, RegisterID* func, ExpectedFunction, CallArguments&, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
754
755         RegisterID* newRegister();
756
757         // Adds an anonymous local var slot. To give this slot a name, add it to symbolTable().
758         RegisterID* addVar()
759         {
760             ++m_codeBlock->m_numVars;
761             RegisterID* result = newRegister();
762             ASSERT(VirtualRegister(result->index()).toLocal() == m_codeBlock->m_numVars - 1);
763             result->ref(); // We should never free this slot.
764             return result;
765         }
766
767         // Initializes the stack form the parameter; does nothing for the symbol table.
768         RegisterID* initializeNextParameter();
769         UniquedStringImpl* visibleNameForParameter(DestructuringPatternNode*);
770         
771         RegisterID& registerFor(VirtualRegister reg)
772         {
773             if (reg.isLocal())
774                 return m_calleeLocals[reg.toLocal()];
775
776             if (reg.offset() == JSStack::Callee)
777                 return m_calleeRegister;
778
779             ASSERT(m_parameters.size());
780             return m_parameters[reg.toArgument()];
781         }
782
783         bool hasConstant(const Identifier&) const;
784         unsigned addConstant(const Identifier&);
785         RegisterID* addConstantValue(JSValue, SourceCodeRepresentation = SourceCodeRepresentation::Other);
786         RegisterID* addConstantEmptyValue();
787         unsigned addRegExp(RegExp*);
788
789         unsigned addConstantBuffer(unsigned length);
790         
791         UnlinkedFunctionExecutable* makeFunction(FunctionMetadataNode* metadata)
792         {
793             bool newisDerivedConstructorContext = constructorKind() == ConstructorKind::Derived || (m_isDerivedConstructorContext && metadata->parseMode() == SourceParseMode::ArrowFunctionMode);
794
795             VariableEnvironment variablesUnderTDZ;
796             getVariablesUnderTDZ(variablesUnderTDZ);
797
798             // FIXME: These flags, ParserModes and propagation to XXXCodeBlocks should be reorganized.
799             // https://bugs.webkit.org/show_bug.cgi?id=151547
800             SourceParseMode parseMode = metadata->parseMode();
801             ConstructAbility constructAbility = ConstructAbility::CanConstruct;
802             if (parseMode == SourceParseMode::GetterMode || parseMode == SourceParseMode::SetterMode || parseMode == SourceParseMode::ArrowFunctionMode)
803                 constructAbility = ConstructAbility::CannotConstruct;
804             else if (parseMode == SourceParseMode::MethodMode && metadata->constructorKind() == ConstructorKind::None)
805                 constructAbility = ConstructAbility::CannotConstruct;
806             else if (parseMode == SourceParseMode::GeneratorWrapperFunctionMode && metadata->superBinding() == SuperBinding::Needed)
807                 constructAbility = ConstructAbility::CannotConstruct;
808
809             GeneratorThisMode generatorThisMode = GeneratorThisMode::NonEmpty;
810             if (parseMode == SourceParseMode::GeneratorBodyMode && isConstructor())
811                 generatorThisMode = GeneratorThisMode::Empty;
812
813             return UnlinkedFunctionExecutable::create(m_vm, m_scopeNode->source(), metadata, isBuiltinFunction() ? UnlinkedBuiltinFunction : UnlinkedNormalFunction, constructAbility, generatorThisMode, variablesUnderTDZ, newisDerivedConstructorContext);
814         }
815
816         void getVariablesUnderTDZ(VariableEnvironment&);
817
818         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);
819         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);
820
821         void initializeParameters(FunctionParameters&);
822         void initializeVarLexicalEnvironment(int symbolTableConstantIndex);
823         void initializeDefaultParameterValuesAndSetupFunctionScopeStack(FunctionParameters&, FunctionNode*, SymbolTable*, int symbolTableConstantIndex, const std::function<bool (UniquedStringImpl*)>& captures);
824         void initializeArrowFunctionContextScopeIfNeeded(SymbolTable* = nullptr);
825
826     public:
827         JSString* addStringConstant(const Identifier&);
828         JSTemplateRegistryKey* addTemplateRegistryKeyConstant(const TemplateRegistryKey&);
829
830         Vector<UnlinkedInstruction, 0, UnsafeVectorOverflow>& instructions() { return m_instructions; }
831
832         RegisterID* emitThrowExpressionTooDeepException();
833
834     private:
835         Vector<UnlinkedInstruction, 0, UnsafeVectorOverflow> m_instructions;
836
837         bool m_shouldEmitDebugHooks;
838         bool m_shouldEmitProfileHooks;
839
840         struct SymbolTableStackEntry {
841             Strong<SymbolTable> m_symbolTable;
842             RegisterID* m_scope;
843             bool m_isWithScope;
844             int m_symbolTableConstantIndex;
845         };
846         Vector<SymbolTableStackEntry> m_symbolTableStack;
847         Vector<std::pair<VariableEnvironment, bool>> m_TDZStack;
848
849         ScopeNode* const m_scopeNode;
850         Strong<UnlinkedCodeBlock> m_codeBlock;
851
852         // Some of these objects keep pointers to one another. They are arranged
853         // to ensure a sane destruction order that avoids references to freed memory.
854         HashSet<RefPtr<UniquedStringImpl>, IdentifierRepHash> m_functions;
855         RegisterID m_ignoredResultRegister;
856         RegisterID m_thisRegister;
857         RegisterID m_calleeRegister;
858         RegisterID* m_scopeRegister { nullptr };
859         RegisterID* m_topMostScope { nullptr };
860         RegisterID* m_argumentsRegister { nullptr };
861         RegisterID* m_lexicalEnvironmentRegister { nullptr };
862         RegisterID* m_generatorRegister { nullptr };
863         RegisterID* m_emptyValueRegister { nullptr };
864         RegisterID* m_globalObjectRegister { nullptr };
865         RegisterID* m_newTargetRegister { nullptr };
866         RegisterID* m_linkTimeConstantRegisters[LinkTimeConstantCount];
867         RegisterID* m_arrowFunctionContextLexicalEnvironmentRegister { nullptr };
868         RefPtr<RegisterID> m_resolvedArrowFunctionScopeContextRegister;
869
870         SegmentedVector<RegisterID*, 16> m_localRegistersForCalleeSaveRegisters;
871         SegmentedVector<RegisterID, 32> m_constantPoolRegisters;
872         SegmentedVector<RegisterID, 32> m_calleeLocals;
873         SegmentedVector<RegisterID, 32> m_parameters;
874         SegmentedVector<Label, 32> m_labels;
875         LabelScopeStore m_labelScopes;
876         int m_finallyDepth { 0 };
877         int m_localScopeDepth { 0 };
878         const CodeType m_codeType;
879
880         int localScopeDepth() const;
881         void pushScopedControlFlowContext();
882         void popScopedControlFlowContext();
883
884         Vector<ControlFlowContext, 0, UnsafeVectorOverflow> m_scopeContextStack;
885         Vector<SwitchInfo> m_switchContextStack;
886         Vector<std::unique_ptr<ForInContext>> m_forInContextStack;
887         Vector<TryContext> m_tryContextStack;
888         Vector<RefPtr<Label>> m_generatorResumeLabels;
889         enum FunctionVariableType : uint8_t { NormalFunctionVariable, GlobalFunctionVariable };
890         Vector<std::pair<FunctionMetadataNode*, FunctionVariableType>> m_functionsToInitialize;
891         bool m_needToInitializeArguments { false };
892         RestParameterNode* m_restParameter { nullptr };
893         
894         Vector<TryRange> m_tryRanges;
895         SegmentedVector<TryData, 8> m_tryData;
896
897         int m_nextConstantOffset { 0 };
898
899         typedef HashMap<FunctionMetadataNode*, unsigned> FunctionOffsetMap;
900         FunctionOffsetMap m_functionOffsets;
901         
902         // Constant pool
903         IdentifierMap m_identifierMap;
904
905         typedef HashMap<EncodedJSValueWithRepresentation, unsigned, EncodedJSValueWithRepresentationHash, EncodedJSValueWithRepresentationHashTraits> JSValueMap;
906         JSValueMap m_jsValueMap;
907         IdentifierStringMap m_stringMap;
908         TemplateRegistryKeyMap m_templateRegistryKeyMap;
909
910         StaticPropertyAnalyzer m_staticPropertyAnalyzer { &m_instructions };
911
912         VM* m_vm;
913
914         OpcodeID m_lastOpcodeID = op_end;
915 #ifndef NDEBUG
916         size_t m_lastOpcodePosition { 0 };
917 #endif
918
919         bool m_usesExceptions { false };
920         bool m_expressionTooDeep { false };
921         bool m_isBuiltinFunction { false };
922         bool m_usesNonStrictEval { false };
923         bool m_inTailPosition { false };
924         bool m_isDerivedConstructorContext { false };
925         bool m_needsToUpdateArrowFunctionContext;
926         bool m_isNewTargetLoadedInArrowFunction { false };
927     };
928
929 }
930
931 #endif // BytecodeGenerator_h