bd28bd90a9d7ff4312b5fc70d2b969951f5349e5
[WebKit-https.git] / Source / JavaScriptCore / bytecompiler / NodesCodegen.cpp
1 /*
2 *  Copyright (C) 1999-2002 Harri Porten (porten@kde.org)
3 *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
4 *  Copyright (C) 2003-2009, 2012-2013, 2015-2016 Apple Inc. All rights reserved.
5 *  Copyright (C) 2007 Cameron Zwarich (cwzwarich@uwaterloo.ca)
6 *  Copyright (C) 2007 Maks Orlovich
7 *  Copyright (C) 2007 Eric Seidel <eric@webkit.org>
8  * Copyright (C) 2012 Igalia, S.L.
9 *
10 *  This library is free software; you can redistribute it and/or
11 *  modify it under the terms of the GNU Library General Public
12 *  License as published by the Free Software Foundation; either
13 *  version 2 of the License, or (at your option) any later version.
14 *
15 *  This library is distributed in the hope that it will be useful,
16 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
17 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18 *  Library General Public License for more details.
19 *
20 *  You should have received a copy of the GNU Library General Public License
21 *  along with this library; see the file COPYING.LIB.  If not, write to
22 *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
23 *  Boston, MA 02110-1301, USA.
24 *
25 */
26
27 #include "config.h"
28 #include "Nodes.h"
29 #include "NodeConstructors.h"
30
31 #include "BuiltinNames.h"
32 #include "BytecodeGenerator.h"
33 #include "CallFrame.h"
34 #include "Debugger.h"
35 #include "JIT.h"
36 #include "JSFunction.h"
37 #include "JSGeneratorFunction.h"
38 #include "JSGlobalObject.h"
39 #include "JSONObject.h"
40 #include "LabelScope.h"
41 #include "Lexer.h"
42 #include "JSCInlines.h"
43 #include "JSTemplateRegistryKey.h"
44 #include "Parser.h"
45 #include "PropertyNameArray.h"
46 #include "RegExpCache.h"
47 #include "RegExpObject.h"
48 #include "StackAlignment.h"
49 #include "TemplateRegistryKey.h"
50 #include <wtf/Assertions.h>
51 #include <wtf/RefCountedLeakCounter.h>
52 #include <wtf/Threading.h>
53
54 using namespace WTF;
55
56 namespace JSC {
57
58 /*
59     Details of the emitBytecode function.
60
61     Return value: The register holding the production's value.
62              dst: An optional parameter specifying the most efficient destination at
63                   which to store the production's value. The callee must honor dst.
64
65     The dst argument provides for a crude form of copy propagation. For example,
66
67         x = 1
68
69     becomes
70     
71         load r[x], 1
72     
73     instead of 
74
75         load r0, 1
76         mov r[x], r0
77     
78     because the assignment node, "x =", passes r[x] as dst to the number node, "1".
79 */
80
81 void ExpressionNode::emitBytecodeInConditionContext(BytecodeGenerator& generator, Label* trueTarget, Label* falseTarget, FallThroughMode fallThroughMode)
82 {
83     RegisterID* result = generator.emitNode(this);
84     if (fallThroughMode == FallThroughMeansTrue)
85         generator.emitJumpIfFalse(result, falseTarget);
86     else
87         generator.emitJumpIfTrue(result, trueTarget);
88 }
89
90 // ------------------------------ ThrowableExpressionData --------------------------------
91
92 RegisterID* ThrowableExpressionData::emitThrowReferenceError(BytecodeGenerator& generator, const String& message)
93 {
94     generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
95     generator.emitThrowReferenceError(message);
96     return generator.newTemporary();
97 }
98
99 // ------------------------------ ConstantNode ----------------------------------
100
101 void ConstantNode::emitBytecodeInConditionContext(BytecodeGenerator& generator, Label* trueTarget, Label* falseTarget, FallThroughMode fallThroughMode)
102 {
103     TriState value = jsValue(generator).pureToBoolean();
104     if (value == MixedTriState)
105         ExpressionNode::emitBytecodeInConditionContext(generator, trueTarget, falseTarget, fallThroughMode);
106     else if (value == TrueTriState && fallThroughMode == FallThroughMeansFalse)
107         generator.emitJump(trueTarget);
108     else if (value == FalseTriState && fallThroughMode == FallThroughMeansTrue)
109         generator.emitJump(falseTarget);
110
111     // All other cases are unconditional fall-throughs, like "if (true)".
112 }
113
114 RegisterID* ConstantNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
115 {
116     if (dst == generator.ignoredResult())
117         return 0;
118     return generator.emitLoad(dst, jsValue(generator));
119 }
120
121 JSValue StringNode::jsValue(BytecodeGenerator& generator) const
122 {
123     return generator.addStringConstant(m_value);
124 }
125
126 // ------------------------------ NumberNode ----------------------------------
127
128 RegisterID* NumberNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
129 {
130     if (dst == generator.ignoredResult())
131         return nullptr;
132     return generator.emitLoad(dst, jsValue(generator), isIntegerNode() ? SourceCodeRepresentation::Integer : SourceCodeRepresentation::Double);
133 }
134
135 // ------------------------------ RegExpNode -----------------------------------
136
137 RegisterID* RegExpNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
138 {
139     if (dst == generator.ignoredResult())
140         return 0;
141     return generator.emitNewRegExp(generator.finalDestination(dst), RegExp::create(*generator.vm(), m_pattern.string(), regExpFlags(m_flags.string())));
142 }
143
144 // ------------------------------ ThisNode -------------------------------------
145
146 RegisterID* ThisNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
147 {
148     generator.ensureThis();
149     if (dst == generator.ignoredResult())
150         return 0;
151
152     RegisterID* result = generator.moveToDestinationIfNeeded(dst, generator.thisRegister());
153     static const unsigned thisLength = 4;
154     generator.emitProfileType(generator.thisRegister(), position(), JSTextPosition(-1, position().offset + thisLength, -1));
155     return result;
156 }
157
158 // ------------------------------ SuperNode -------------------------------------
159
160 static RegisterID* emitHomeObjectForCallee(BytecodeGenerator& generator)
161 {
162     if (generator.isDerivedClassContext() || generator.isDerivedConstructorContext()) {
163         RegisterID* derivedConstructor = generator.emitLoadDerivedConstructorFromArrowFunctionLexicalEnvironment();
164         return generator.emitGetById(generator.newTemporary(), derivedConstructor, generator.propertyNames().homeObjectPrivateName);
165     }
166
167     RegisterID callee;
168     callee.setIndex(JSStack::Callee);
169     return generator.emitGetById(generator.newTemporary(), &callee, generator.propertyNames().homeObjectPrivateName);
170 }
171
172 static RegisterID* emitSuperBaseForCallee(BytecodeGenerator& generator)
173 {
174     RefPtr<RegisterID> homeObject = emitHomeObjectForCallee(generator);
175     return generator.emitGetById(generator.newTemporary(), homeObject.get(), generator.propertyNames().underscoreProto);
176 }
177
178 static RegisterID* emitGetSuperFunctionForConstruct(BytecodeGenerator& generator)
179 {
180     if (generator.isDerivedConstructorContext())
181         return generator.emitGetById(generator.newTemporary(), generator.emitLoadDerivedConstructorFromArrowFunctionLexicalEnvironment(), generator.propertyNames().underscoreProto);
182
183     RegisterID callee;
184     callee.setIndex(JSStack::Callee);
185     return generator.emitGetById(generator.newTemporary(), &callee, generator.propertyNames().underscoreProto);
186 }
187
188 RegisterID* SuperNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
189 {
190     RegisterID* result = emitSuperBaseForCallee(generator);
191     return generator.moveToDestinationIfNeeded(generator.finalDestination(dst), result);
192 }
193
194 // ------------------------------ NewTargetNode ----------------------------------
195
196 RegisterID* NewTargetNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
197 {
198     if (dst == generator.ignoredResult())
199         return nullptr;
200
201     return generator.moveToDestinationIfNeeded(dst, generator.newTarget());
202 }
203
204 // ------------------------------ ResolveNode ----------------------------------
205
206 bool ResolveNode::isPure(BytecodeGenerator& generator) const
207 {
208     return generator.variable(m_ident).offset().isStack();
209 }
210
211 RegisterID* ResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
212 {
213     Variable var = generator.variable(m_ident);
214     if (RegisterID* local = var.local()) {
215         generator.emitTDZCheckIfNecessary(var, local, nullptr);
216         if (dst == generator.ignoredResult())
217             return nullptr;
218
219         generator.emitProfileType(local, var, m_position, JSTextPosition(-1, m_position.offset + m_ident.length(), -1));
220         return generator.moveToDestinationIfNeeded(dst, local);
221     }
222     
223     JSTextPosition divot = m_start + m_ident.length();
224     generator.emitExpressionInfo(divot, m_start, divot);
225     RefPtr<RegisterID> scope = generator.emitResolveScope(dst, var);
226     RegisterID* finalDest = generator.finalDestination(dst);
227     RegisterID* result = generator.emitGetFromScope(finalDest, scope.get(), var, ThrowIfNotFound);
228     generator.emitTDZCheckIfNecessary(var, finalDest, nullptr);
229     generator.emitProfileType(finalDest, var, m_position, JSTextPosition(-1, m_position.offset + m_ident.length(), -1));
230     return result;
231 }
232
233 // ------------------------------ TemplateStringNode -----------------------------------
234
235 RegisterID* TemplateStringNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
236 {
237     if (dst == generator.ignoredResult())
238         return nullptr;
239     return generator.emitLoad(dst, JSValue(generator.addStringConstant(cooked())));
240 }
241
242 // ------------------------------ TemplateLiteralNode -----------------------------------
243
244 RegisterID* TemplateLiteralNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
245 {
246     if (!m_templateExpressions) {
247         TemplateStringNode* templateString = m_templateStrings->value();
248         ASSERT_WITH_MESSAGE(!m_templateStrings->next(), "Only one template element exists because there's no expression in a given template literal.");
249         return generator.emitNode(dst, templateString);
250     }
251
252     Vector<RefPtr<RegisterID>, 16> temporaryRegisters;
253
254     TemplateStringListNode* templateString = m_templateStrings;
255     TemplateExpressionListNode* templateExpression = m_templateExpressions;
256     for (; templateExpression; templateExpression = templateExpression->next(), templateString = templateString->next()) {
257         // Evaluate TemplateString.
258         if (!templateString->value()->cooked().isEmpty()) {
259             temporaryRegisters.append(generator.newTemporary());
260             generator.emitNode(temporaryRegisters.last().get(), templateString->value());
261         }
262
263         // Evaluate Expression.
264         temporaryRegisters.append(generator.newTemporary());
265         generator.emitNode(temporaryRegisters.last().get(), templateExpression->value());
266         generator.emitToString(temporaryRegisters.last().get(), temporaryRegisters.last().get());
267     }
268
269     // Evaluate tail TemplateString.
270     if (!templateString->value()->cooked().isEmpty()) {
271         temporaryRegisters.append(generator.newTemporary());
272         generator.emitNode(temporaryRegisters.last().get(), templateString->value());
273     }
274
275     if (temporaryRegisters.size() == 1)
276         return generator.emitToString(generator.finalDestination(dst, temporaryRegisters[0].get()), temporaryRegisters[0].get());
277
278     return generator.emitStrcat(generator.finalDestination(dst, temporaryRegisters[0].get()), temporaryRegisters[0].get(), temporaryRegisters.size());
279 }
280
281 // ------------------------------ TaggedTemplateNode -----------------------------------
282
283 RegisterID* TaggedTemplateNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
284 {
285     ExpectedFunction expectedFunction = NoExpectedFunction;
286     RefPtr<RegisterID> tag = nullptr;
287     RefPtr<RegisterID> base = nullptr;
288     if (!m_tag->isLocation()) {
289         tag = generator.newTemporary();
290         tag = generator.emitNode(tag.get(), m_tag);
291     } else if (m_tag->isResolveNode()) {
292         ResolveNode* resolve = static_cast<ResolveNode*>(m_tag);
293         const Identifier& identifier = resolve->identifier();
294         expectedFunction = generator.expectedFunctionForIdentifier(identifier);
295
296         Variable var = generator.variable(identifier);
297         if (RegisterID* local = var.local()) {
298             generator.emitTDZCheckIfNecessary(var, local, nullptr);
299             tag = generator.emitMove(generator.newTemporary(), local);
300         } else {
301             tag = generator.newTemporary();
302             base = generator.newTemporary();
303
304             JSTextPosition newDivot = divotStart() + identifier.length();
305             generator.emitExpressionInfo(newDivot, divotStart(), newDivot);
306             generator.moveToDestinationIfNeeded(base.get(), generator.emitResolveScope(base.get(), var));
307             generator.emitGetFromScope(tag.get(), base.get(), var, ThrowIfNotFound);
308             generator.emitTDZCheckIfNecessary(var, tag.get(), nullptr);
309         }
310     } else if (m_tag->isBracketAccessorNode()) {
311         BracketAccessorNode* bracket = static_cast<BracketAccessorNode*>(m_tag);
312         base = generator.newTemporary();
313         base = generator.emitNode(base.get(), bracket->base());
314         RefPtr<RegisterID> property = generator.emitNode(bracket->subscript());
315         if (bracket->base()->isSuperNode()) {
316             RefPtr<RegisterID> thisValue = generator.ensureThis();
317             tag = generator.emitGetByVal(generator.newTemporary(), base.get(), thisValue.get(), property.get());
318         } else
319             tag = generator.emitGetByVal(generator.newTemporary(), base.get(), property.get());
320     } else {
321         ASSERT(m_tag->isDotAccessorNode());
322         DotAccessorNode* dot = static_cast<DotAccessorNode*>(m_tag);
323         base = generator.newTemporary();
324         base = generator.emitNode(base.get(), dot->base());
325         if (dot->base()->isSuperNode()) {
326             RefPtr<RegisterID> thisValue = generator.ensureThis();
327             tag = generator.emitGetById(generator.newTemporary(), base.get(), thisValue.get(), dot->identifier());
328         } else
329             tag = generator.emitGetById(generator.newTemporary(), base.get(), dot->identifier());
330     }
331
332     RefPtr<RegisterID> templateObject = generator.emitGetTemplateObject(generator.newTemporary(), this);
333
334     unsigned expressionsCount = 0;
335     for (TemplateExpressionListNode* templateExpression = m_templateLiteral->templateExpressions(); templateExpression; templateExpression = templateExpression->next())
336         ++expressionsCount;
337
338     CallArguments callArguments(generator, nullptr, 1 + expressionsCount);
339     if (base)
340         generator.emitMove(callArguments.thisRegister(), base.get());
341     else
342         generator.emitLoad(callArguments.thisRegister(), jsUndefined());
343
344     unsigned argumentIndex = 0;
345     generator.emitMove(callArguments.argumentRegister(argumentIndex++), templateObject.get());
346     for (TemplateExpressionListNode* templateExpression = m_templateLiteral->templateExpressions(); templateExpression; templateExpression = templateExpression->next())
347         generator.emitNode(callArguments.argumentRegister(argumentIndex++), templateExpression->value());
348
349     return generator.emitCall(generator.finalDestination(dst, tag.get()), tag.get(), expectedFunction, callArguments, divot(), divotStart(), divotEnd());
350 }
351
352 // ------------------------------ ArrayNode ------------------------------------
353
354 RegisterID* ArrayNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
355 {
356     // FIXME: Should we put all of this code into emitNewArray?
357
358     unsigned length = 0;
359     ElementNode* firstPutElement;
360     for (firstPutElement = m_element; firstPutElement; firstPutElement = firstPutElement->next()) {
361         if (firstPutElement->elision() || firstPutElement->value()->isSpreadExpression())
362             break;
363         ++length;
364     }
365
366     if (!firstPutElement && !m_elision)
367         return generator.emitNewArray(generator.finalDestination(dst), m_element, length);
368
369     RefPtr<RegisterID> array = generator.emitNewArray(generator.tempDestination(dst), m_element, length);
370     ElementNode* n = firstPutElement;
371     for (; n; n = n->next()) {
372         if (n->value()->isSpreadExpression())
373             goto handleSpread;
374         RegisterID* value = generator.emitNode(n->value());
375         length += n->elision();
376         generator.emitPutByIndex(array.get(), length++, value);
377     }
378
379     if (m_elision) {
380         RegisterID* value = generator.emitLoad(0, jsNumber(m_elision + length));
381         generator.emitPutById(array.get(), generator.propertyNames().length, value);
382     }
383
384     return generator.moveToDestinationIfNeeded(dst, array.get());
385     
386 handleSpread:
387     RefPtr<RegisterID> index = generator.emitLoad(generator.newTemporary(), jsNumber(length));
388     auto spreader = [this, array, index](BytecodeGenerator& generator, RegisterID* value)
389     {
390         generator.emitDirectPutByVal(array.get(), index.get(), value);
391         generator.emitInc(index.get());
392     };
393     for (; n; n = n->next()) {
394         if (n->elision())
395             generator.emitBinaryOp(op_add, index.get(), index.get(), generator.emitLoad(0, jsNumber(n->elision())), OperandTypes(ResultType::numberTypeIsInt32(), ResultType::numberTypeIsInt32()));
396         if (n->value()->isSpreadExpression()) {
397             SpreadExpressionNode* spread = static_cast<SpreadExpressionNode*>(n->value());
398             generator.emitEnumeration(spread, spread->expression(), spreader);
399         } else {
400             generator.emitDirectPutByVal(array.get(), index.get(), generator.emitNode(n->value()));
401             generator.emitInc(index.get());
402         }
403     }
404     
405     if (m_elision) {
406         generator.emitBinaryOp(op_add, index.get(), index.get(), generator.emitLoad(0, jsNumber(m_elision)), OperandTypes(ResultType::numberTypeIsInt32(), ResultType::numberTypeIsInt32()));
407         generator.emitPutById(array.get(), generator.propertyNames().length, index.get());
408     }
409     return generator.moveToDestinationIfNeeded(dst, array.get());
410 }
411
412 bool ArrayNode::isSimpleArray() const
413 {
414     if (m_elision || m_optional)
415         return false;
416     for (ElementNode* ptr = m_element; ptr; ptr = ptr->next()) {
417         if (ptr->elision())
418             return false;
419     }
420     return true;
421 }
422
423 ArgumentListNode* ArrayNode::toArgumentList(ParserArena& parserArena, int lineNumber, int startPosition) const
424 {
425     ASSERT(!m_elision && !m_optional);
426     ElementNode* ptr = m_element;
427     if (!ptr)
428         return 0;
429     JSTokenLocation location;
430     location.line = lineNumber;
431     location.startOffset = startPosition;
432     ArgumentListNode* head = new (parserArena) ArgumentListNode(location, ptr->value());
433     ArgumentListNode* tail = head;
434     ptr = ptr->next();
435     for (; ptr; ptr = ptr->next()) {
436         ASSERT(!ptr->elision());
437         tail = new (parserArena) ArgumentListNode(location, tail, ptr->value());
438     }
439     return head;
440 }
441
442 // ------------------------------ ObjectLiteralNode ----------------------------
443
444 RegisterID* ObjectLiteralNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
445 {
446     if (!m_list) {
447         if (dst == generator.ignoredResult())
448             return 0;
449         return generator.emitNewObject(generator.finalDestination(dst));
450     }
451     RefPtr<RegisterID> newObj = generator.emitNewObject(generator.tempDestination(dst));
452     generator.emitNode(newObj.get(), m_list);
453     return generator.moveToDestinationIfNeeded(dst, newObj.get());
454 }
455
456 // ------------------------------ PropertyListNode -----------------------------
457
458 static inline void emitPutHomeObject(BytecodeGenerator& generator, RegisterID* function, RegisterID* homeObject)
459 {
460     generator.emitPutById(function, generator.propertyNames().homeObjectPrivateName, homeObject);
461 }
462
463 RegisterID* PropertyListNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
464 {
465     // Fast case: this loop just handles regular value properties.
466     PropertyListNode* p = this;
467     for (; p && (p->m_node->m_type & PropertyNode::Constant); p = p->m_next)
468         emitPutConstantProperty(generator, dst, *p->m_node);
469
470     // Were there any get/set properties?
471     if (p) {
472         // Build a list of getter/setter pairs to try to put them at the same time. If we encounter
473         // a computed property, just emit everything as that may override previous values.
474         bool hasComputedProperty = false;
475
476         typedef std::pair<PropertyNode*, PropertyNode*> GetterSetterPair;
477         typedef HashMap<UniquedStringImpl*, GetterSetterPair, IdentifierRepHash> GetterSetterMap;
478         GetterSetterMap map;
479
480         // Build a map, pairing get/set values together.
481         for (PropertyListNode* q = p; q; q = q->m_next) {
482             PropertyNode* node = q->m_node;
483             if (node->m_type & PropertyNode::Computed) {
484                 hasComputedProperty = true;
485                 break;
486             }
487             if (node->m_type & PropertyNode::Constant)
488                 continue;
489
490             // Duplicates are possible.
491             GetterSetterPair pair(node, static_cast<PropertyNode*>(nullptr));
492             GetterSetterMap::AddResult result = map.add(node->name()->impl(), pair);
493             if (!result.isNewEntry) {
494                 if (result.iterator->value.first->m_type == node->m_type)
495                     result.iterator->value.first = node;
496                 else
497                     result.iterator->value.second = node;
498             }
499         }
500
501         // Iterate over the remaining properties in the list.
502         for (; p; p = p->m_next) {
503             PropertyNode* node = p->m_node;
504
505             // Handle regular values.
506             if (node->m_type & PropertyNode::Constant) {
507                 emitPutConstantProperty(generator, dst, *node);
508                 continue;
509             }
510
511             RefPtr<RegisterID> value = generator.emitNode(node->m_assign);
512             bool needsSuperBinding = node->needsSuperBinding();
513             if (needsSuperBinding)
514                 emitPutHomeObject(generator, value.get(), dst);
515
516             unsigned attributes = node->isClassProperty() ? (Accessor | DontEnum) : Accessor;
517
518             ASSERT(node->m_type & (PropertyNode::Getter | PropertyNode::Setter));
519
520             // This is a get/set property which may be overridden by a computed property later.
521             if (hasComputedProperty) {
522                 // Computed accessors.
523                 if (node->m_type & PropertyNode::Computed) {
524                     RefPtr<RegisterID> propertyName = generator.emitNode(node->m_expression);
525                     generator.emitSetFunctionNameIfNeeded(node->m_assign, value.get(), propertyName.get());
526                     if (node->m_type & PropertyNode::Getter)
527                         generator.emitPutGetterByVal(dst, propertyName.get(), attributes, value.get());
528                     else
529                         generator.emitPutSetterByVal(dst, propertyName.get(), attributes, value.get());
530                     continue;
531                 }
532
533                 if (node->m_type & PropertyNode::Getter)
534                     generator.emitPutGetterById(dst, *node->name(), attributes, value.get());
535                 else
536                     generator.emitPutSetterById(dst, *node->name(), attributes, value.get());
537                 continue;
538             }
539
540             // This is a get/set property pair.
541             GetterSetterMap::iterator it = map.find(node->name()->impl());
542             ASSERT(it != map.end());
543             GetterSetterPair& pair = it->value;
544
545             // Was this already generated as a part of its partner?
546             if (pair.second == node)
547                 continue;
548
549             // Generate the paired node now.
550             RefPtr<RegisterID> getterReg;
551             RefPtr<RegisterID> setterReg;
552             RegisterID* secondReg = nullptr;
553
554             if (node->m_type & PropertyNode::Getter) {
555                 getterReg = value;
556                 if (pair.second) {
557                     ASSERT(pair.second->m_type & PropertyNode::Setter);
558                     setterReg = generator.emitNode(pair.second->m_assign);
559                     secondReg = setterReg.get();
560                 } else {
561                     setterReg = generator.newTemporary();
562                     generator.emitLoad(setterReg.get(), jsUndefined());
563                 }
564             } else {
565                 ASSERT(node->m_type & PropertyNode::Setter);
566                 setterReg = value;
567                 if (pair.second) {
568                     ASSERT(pair.second->m_type & PropertyNode::Getter);
569                     getterReg = generator.emitNode(pair.second->m_assign);
570                     secondReg = getterReg.get();
571                 } else {
572                     getterReg = generator.newTemporary();
573                     generator.emitLoad(getterReg.get(), jsUndefined());
574                 }
575             }
576
577             ASSERT(!pair.second || needsSuperBinding == pair.second->needsSuperBinding());
578             if (needsSuperBinding && pair.second)
579                 emitPutHomeObject(generator, secondReg, dst);
580
581             generator.emitPutGetterSetter(dst, *node->name(), attributes, getterReg.get(), setterReg.get());
582         }
583     }
584
585     return dst;
586 }
587
588 void PropertyListNode::emitPutConstantProperty(BytecodeGenerator& generator, RegisterID* newObj, PropertyNode& node)
589 {
590     RefPtr<RegisterID> value = generator.emitNode(node.m_assign);
591     if (node.needsSuperBinding()) {
592         emitPutHomeObject(generator, value.get(), newObj);
593
594         RefPtr<RegisterID> propertyNameRegister;
595         if (node.name())
596             propertyNameRegister = generator.emitLoad(generator.newTemporary(), *node.name());
597         else
598             propertyNameRegister = generator.emitNode(node.m_expression);
599
600         unsigned attributes = BytecodeGenerator::PropertyConfigurable | BytecodeGenerator::PropertyWritable;
601         if (!node.isClassProperty())
602             attributes |= BytecodeGenerator::PropertyEnumerable;
603         generator.emitSetFunctionNameIfNeeded(node.m_assign, value.get(), propertyNameRegister.get());
604         generator.emitCallDefineProperty(newObj, propertyNameRegister.get(),
605             value.get(), nullptr, nullptr, attributes, m_position);
606         return;
607     }
608     if (const auto* identifier = node.name()) {
609         Optional<uint32_t> optionalIndex = parseIndex(*identifier);
610         if (!optionalIndex) {
611             generator.emitDirectPutById(newObj, *identifier, value.get(), node.putType());
612             return;
613         }
614
615         RefPtr<RegisterID> index = generator.emitLoad(generator.newTemporary(), jsNumber(optionalIndex.value()));
616         generator.emitDirectPutByVal(newObj, index.get(), value.get());
617         return;
618     }
619     RefPtr<RegisterID> propertyName = generator.emitNode(node.m_expression);
620     generator.emitSetFunctionNameIfNeeded(node.m_assign, value.get(), propertyName.get());
621     generator.emitDirectPutByVal(newObj, propertyName.get(), value.get());
622 }
623
624 // ------------------------------ BracketAccessorNode --------------------------------
625
626 static bool isNonIndexStringElement(ExpressionNode& element)
627 {
628     return element.isString() && !parseIndex(static_cast<StringNode&>(element).value());
629 }
630
631 RegisterID* BracketAccessorNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
632 {
633     if (m_base->isSuperNode()) {
634         RefPtr<RegisterID> finalDest = generator.finalDestination(dst);
635         RefPtr<RegisterID> thisValue = generator.ensureThis();
636         RefPtr<RegisterID> superBase = emitSuperBaseForCallee(generator);
637         if (isNonIndexStringElement(*m_subscript)) {
638             const Identifier& id = static_cast<StringNode*>(m_subscript)->value();
639             generator.emitGetById(finalDest.get(), superBase.get(), thisValue.get(), id);
640         } else  {
641             RefPtr<RegisterID> subscript = generator.emitNode(m_subscript);
642             generator.emitGetByVal(finalDest.get(), superBase.get(), thisValue.get(), subscript.get());
643         }
644
645         generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
646         generator.emitProfileType(finalDest.get(), divotStart(), divotEnd());
647         return finalDest.get();
648     }
649
650     RegisterID* ret;
651     RefPtr<RegisterID> finalDest = generator.finalDestination(dst);
652
653     if (isNonIndexStringElement(*m_subscript)) {
654         RefPtr<RegisterID> base = generator.emitNode(m_base);
655         ret = generator.emitGetById(finalDest.get(), base.get(), static_cast<StringNode*>(m_subscript)->value());
656     } else {
657         RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base, m_subscriptHasAssignments, m_subscript->isPure(generator));
658         RegisterID* property = generator.emitNode(m_subscript);
659         ret = generator.emitGetByVal(finalDest.get(), base.get(), property);
660     }
661
662     generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
663
664     generator.emitProfileType(finalDest.get(), divotStart(), divotEnd());
665     return ret;
666 }
667
668 // ------------------------------ DotAccessorNode --------------------------------
669
670 RegisterID* DotAccessorNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
671 {
672     bool baseIsSuper = m_base->isSuperNode();
673     RefPtr<RegisterID> base = baseIsSuper ? emitSuperBaseForCallee(generator) : generator.emitNode(m_base);
674     generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
675     RegisterID* finalDest = generator.finalDestination(dst);
676     RegisterID* ret;
677     if (baseIsSuper) {
678         RefPtr<RegisterID> thisValue = generator.ensureThis();
679         ret = generator.emitGetById(finalDest, base.get(), thisValue.get(), m_ident);
680     } else
681         ret = generator.emitGetById(finalDest, base.get(), m_ident);
682     generator.emitProfileType(finalDest, divotStart(), divotEnd());
683     return ret;
684 }
685
686 // ------------------------------ ArgumentListNode -----------------------------
687
688 RegisterID* ArgumentListNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
689 {
690     ASSERT(m_expr);
691     return generator.emitNode(dst, m_expr);
692 }
693
694 // ------------------------------ NewExprNode ----------------------------------
695
696 RegisterID* NewExprNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
697 {
698     ExpectedFunction expectedFunction;
699     if (m_expr->isResolveNode())
700         expectedFunction = generator.expectedFunctionForIdentifier(static_cast<ResolveNode*>(m_expr)->identifier());
701     else
702         expectedFunction = NoExpectedFunction;
703     RefPtr<RegisterID> func = generator.emitNode(m_expr);
704     RefPtr<RegisterID> returnValue = generator.finalDestination(dst, func.get());
705     CallArguments callArguments(generator, m_args);
706     generator.emitMove(callArguments.thisRegister(), func.get());
707     return generator.emitConstruct(returnValue.get(), func.get(), expectedFunction, callArguments, divot(), divotStart(), divotEnd());
708 }
709
710 CallArguments::CallArguments(BytecodeGenerator& generator, ArgumentsNode* argumentsNode, unsigned additionalArguments)
711     : m_argumentsNode(argumentsNode)
712     , m_padding(0)
713 {
714     size_t argumentCountIncludingThis = 1 + additionalArguments; // 'this' register.
715     if (argumentsNode) {
716         for (ArgumentListNode* node = argumentsNode->m_listNode; node; node = node->m_next)
717             ++argumentCountIncludingThis;
718     }
719
720     m_argv.grow(argumentCountIncludingThis);
721     for (int i = argumentCountIncludingThis - 1; i >= 0; --i) {
722         m_argv[i] = generator.newTemporary();
723         ASSERT(static_cast<size_t>(i) == m_argv.size() - 1 || m_argv[i]->index() == m_argv[i + 1]->index() - 1);
724     }
725
726     // We need to ensure that the frame size is stack-aligned
727     while ((JSStack::CallFrameHeaderSize + m_argv.size()) % stackAlignmentRegisters()) {
728         m_argv.insert(0, generator.newTemporary());
729         m_padding++;
730     }
731     
732     while (stackOffset() % stackAlignmentRegisters()) {
733         m_argv.insert(0, generator.newTemporary());
734         m_padding++;
735     }
736 }
737
738 // ------------------------------ EvalFunctionCallNode ----------------------------------
739
740 RegisterID* EvalFunctionCallNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
741 {
742     // We need try to load 'this' before call eval in constructor, because 'this' can created by 'super' in some of the arrow function
743     // var A = class A {
744     //   constructor () { this.id = 'A'; }
745     // }
746     //
747     // var B = class B extend A {
748     //    constructor () {
749     //       var arrow = () => super();
750     //       arrow();
751     //       eval("this.id = 'B'");
752     //    }
753     // }
754     if (generator.constructorKind() == ConstructorKind::Derived && generator.needsToUpdateArrowFunctionContext() && generator.isThisUsedInInnerArrowFunction())
755         generator.emitLoadThisFromArrowFunctionLexicalEnvironment();
756
757     Variable var = generator.variable(generator.propertyNames().eval);
758     if (RegisterID* local = var.local()) {
759         RefPtr<RegisterID> func = generator.emitMove(generator.tempDestination(dst), local);
760         CallArguments callArguments(generator, m_args);
761         generator.emitLoad(callArguments.thisRegister(), jsUndefined());
762         return generator.emitCallEval(generator.finalDestination(dst, func.get()), func.get(), callArguments, divot(), divotStart(), divotEnd());
763     }
764
765     RefPtr<RegisterID> func = generator.newTemporary();
766     CallArguments callArguments(generator, m_args);
767     JSTextPosition newDivot = divotStart() + 4;
768     generator.emitExpressionInfo(newDivot, divotStart(), newDivot);
769     generator.moveToDestinationIfNeeded(
770         callArguments.thisRegister(),
771         generator.emitResolveScope(callArguments.thisRegister(), var));
772     generator.emitGetFromScope(func.get(), callArguments.thisRegister(), var, ThrowIfNotFound);
773     return generator.emitCallEval(generator.finalDestination(dst, func.get()), func.get(), callArguments, divot(), divotStart(), divotEnd());
774 }
775
776 // ------------------------------ FunctionCallValueNode ----------------------------------
777
778 RegisterID* FunctionCallValueNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
779 {
780     if (m_expr->isSuperNode()) {
781         RefPtr<RegisterID> func = emitGetSuperFunctionForConstruct(generator);
782         RefPtr<RegisterID> returnValue = generator.finalDestination(dst, func.get());
783         CallArguments callArguments(generator, m_args);
784
785         ASSERT(generator.isConstructor() || generator.derivedContextType() == DerivedContextType::DerivedConstructorContext);
786         ASSERT(generator.constructorKind() == ConstructorKind::Derived || generator.derivedContextType() == DerivedContextType::DerivedConstructorContext);
787         generator.emitMove(callArguments.thisRegister(), generator.newTarget());
788         RegisterID* ret = generator.emitConstruct(returnValue.get(), func.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
789
790         bool isConstructorKindDerived = generator.constructorKind() == ConstructorKind::Derived;
791         bool doWeUseArrowFunctionInConstructor = isConstructorKindDerived && generator.needsToUpdateArrowFunctionContext();
792
793         if (generator.isDerivedConstructorContext() || (doWeUseArrowFunctionInConstructor && generator.isSuperCallUsedInInnerArrowFunction()))
794             generator.emitLoadThisFromArrowFunctionLexicalEnvironment();
795         
796         RefPtr<Label> thisIsEmptyLabel = generator.newLabel();
797         generator.emitJumpIfTrue(generator.emitIsEmpty(generator.newTemporary(), generator.thisRegister()), thisIsEmptyLabel.get());
798         generator.emitThrowReferenceError(ASCIILiteral("'super()' can't be called more than once in a constructor."));
799         generator.emitLabel(thisIsEmptyLabel.get());
800
801         generator.emitMove(generator.thisRegister(), ret);
802         
803         if (generator.isDerivedConstructorContext() || doWeUseArrowFunctionInConstructor)
804             generator.emitPutThisToArrowFunctionContextScope();
805         
806         return ret;
807     }
808     RefPtr<RegisterID> func = generator.emitNode(m_expr);
809     RefPtr<RegisterID> returnValue = generator.finalDestination(dst, func.get());
810     CallArguments callArguments(generator, m_args);
811     generator.emitLoad(callArguments.thisRegister(), jsUndefined());
812     RegisterID* ret = generator.emitCallInTailPosition(returnValue.get(), func.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
813     generator.emitProfileType(returnValue.get(), divotStart(), divotEnd());
814     return ret;
815 }
816
817 // ------------------------------ FunctionCallResolveNode ----------------------------------
818
819 RegisterID* FunctionCallResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
820 {
821     ExpectedFunction expectedFunction = generator.expectedFunctionForIdentifier(m_ident);
822
823     Variable var = generator.variable(m_ident);
824     if (RegisterID* local = var.local()) {
825         generator.emitTDZCheckIfNecessary(var, local, nullptr);
826         RefPtr<RegisterID> func = generator.emitMove(generator.tempDestination(dst), local);
827         RefPtr<RegisterID> returnValue = generator.finalDestination(dst, func.get());
828         CallArguments callArguments(generator, m_args);
829         generator.emitLoad(callArguments.thisRegister(), jsUndefined());
830         // This passes NoExpectedFunction because we expect that if the function is in a
831         // local variable, then it's not one of our built-in constructors.
832         RegisterID* ret = generator.emitCallInTailPosition(returnValue.get(), func.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
833         generator.emitProfileType(returnValue.get(), divotStart(), divotEnd());
834         return ret;
835     }
836
837     RefPtr<RegisterID> func = generator.newTemporary();
838     RefPtr<RegisterID> returnValue = generator.finalDestination(dst, func.get());
839     CallArguments callArguments(generator, m_args);
840
841     JSTextPosition newDivot = divotStart() + m_ident.length();
842     generator.emitExpressionInfo(newDivot, divotStart(), newDivot);
843     generator.moveToDestinationIfNeeded(
844         callArguments.thisRegister(),
845         generator.emitResolveScope(callArguments.thisRegister(), var));
846     generator.emitGetFromScope(func.get(), callArguments.thisRegister(), var, ThrowIfNotFound);
847     generator.emitTDZCheckIfNecessary(var, func.get(), nullptr);
848     RegisterID* ret = generator.emitCallInTailPosition(returnValue.get(), func.get(), expectedFunction, callArguments, divot(), divotStart(), divotEnd());
849     generator.emitProfileType(returnValue.get(), divotStart(), divotEnd());
850     return ret;
851 }
852
853 // ------------------------------ BytecodeIntrinsicNode ----------------------------------
854
855 RegisterID* BytecodeIntrinsicNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
856 {
857     return (this->*m_emitter)(generator, dst);
858 }
859
860 RegisterID* BytecodeIntrinsicNode::emit_intrinsic_argumentCount(BytecodeGenerator& generator, RegisterID* dst)
861 {
862     ASSERT(!m_args->m_listNode);
863
864     return generator.emitUnaryNoDstOp(op_argument_count, generator.finalDestination(dst));
865 }
866
867 RegisterID* BytecodeIntrinsicNode::emit_intrinsic_assert(BytecodeGenerator& generator, RegisterID* dst)
868 {
869 #ifndef NDEBUG
870     ArgumentListNode* node = m_args->m_listNode;
871     RefPtr<RegisterID> condition = generator.emitNode(node);
872     generator.emitAssert(condition.get(), node->firstLine());
873     return dst;
874 #else
875     UNUSED_PARAM(generator);
876     return dst;
877 #endif
878 }
879
880 RegisterID* BytecodeIntrinsicNode::emit_intrinsic_putByValDirect(BytecodeGenerator& generator, RegisterID* dst)
881 {
882     ArgumentListNode* node = m_args->m_listNode;
883     RefPtr<RegisterID> base = generator.emitNode(node);
884     node = node->m_next;
885     RefPtr<RegisterID> index = generator.emitNode(node);
886     node = node->m_next;
887     RefPtr<RegisterID> value = generator.emitNode(node);
888
889     ASSERT(!node->m_next);
890
891     return generator.moveToDestinationIfNeeded(dst, generator.emitDirectPutByVal(base.get(), index.get(), value.get()));
892 }
893
894 RegisterID* BytecodeIntrinsicNode::emit_intrinsic_tailCallForwardArguments(BytecodeGenerator& generator, RegisterID* dst)
895 {
896     ArgumentListNode* node = m_args->m_listNode;
897     RefPtr<RegisterID> function = generator.emitNode(node);
898     node = node->m_next;
899     RefPtr<RegisterID> thisRegister = generator.emitNode(node);
900     ASSERT(!node->m_next);
901
902     RefPtr<RegisterID> finalDst = generator.finalDestination(dst);
903     return generator.emitCallForwardArgumentsInTailPosition(finalDst.get(), function.get(), thisRegister.get(), generator.newTemporary(), 0, divot(), divotStart(), divotEnd());
904 }
905
906 RegisterID* BytecodeIntrinsicNode::emit_intrinsic_tryGetById(BytecodeGenerator& generator, RegisterID* dst)
907 {
908     ArgumentListNode* node = m_args->m_listNode;
909     RefPtr<RegisterID> base = generator.emitNode(node);
910     node = node->m_next;
911
912     // Since this is a builtin we expect the creator to use a string literal as the second argument.
913     ASSERT(node->m_expr->isString());
914     const Identifier& ident = static_cast<StringNode*>(node->m_expr)->value();
915     ASSERT(!node->m_next);
916
917     RefPtr<RegisterID> finalDest = generator.finalDestination(dst);
918     return generator.emitTryGetById(finalDest.get(), base.get(), ident);
919 }
920
921 RegisterID* BytecodeIntrinsicNode::emit_intrinsic_toString(BytecodeGenerator& generator, RegisterID* dst)
922 {
923     ArgumentListNode* node = m_args->m_listNode;
924     RefPtr<RegisterID> src = generator.emitNode(node);
925     ASSERT(!node->m_next);
926
927     return generator.moveToDestinationIfNeeded(dst, generator.emitToString(generator.tempDestination(dst), src.get()));
928 }
929
930 RegisterID* BytecodeIntrinsicNode::emit_intrinsic_isObject(BytecodeGenerator& generator, RegisterID* dst)
931 {
932     ArgumentListNode* node = m_args->m_listNode;
933     RefPtr<RegisterID> src = generator.emitNode(node);
934     ASSERT(!node->m_next);
935
936     return generator.moveToDestinationIfNeeded(dst, generator.emitIsObject(generator.tempDestination(dst), src.get()));
937 }
938
939
940 #define JSC_DECLARE_BYTECODE_INTRINSIC_CONSTANT_GENERATORS(name) \
941     RegisterID* BytecodeIntrinsicNode::emit_intrinsic_##name(BytecodeGenerator& generator, RegisterID* dst) \
942     { \
943         ASSERT(!m_args); \
944         ASSERT(type() == Type::Constant); \
945         if (dst == generator.ignoredResult()) \
946             return nullptr; \
947         return generator.emitLoad(dst, generator.vm()->bytecodeIntrinsicRegistry().name##Value(generator)); \
948     }
949     JSC_COMMON_BYTECODE_INTRINSIC_CONSTANTS_EACH_NAME(JSC_DECLARE_BYTECODE_INTRINSIC_CONSTANT_GENERATORS)
950 #undef JSC_DECLARE_BYTECODE_INTRINSIC_CONSTANT_GENERATORS
951
952 // ------------------------------ FunctionCallBracketNode ----------------------------------
953
954 RegisterID* FunctionCallBracketNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
955 {
956     bool baseIsSuper = m_base->isSuperNode();
957     bool subscriptIsNonIndexString = isNonIndexStringElement(*m_subscript);
958
959     RefPtr<RegisterID> base;
960     if (baseIsSuper)
961         base = emitSuperBaseForCallee(generator);
962     else {
963         if (subscriptIsNonIndexString)
964             base = generator.emitNode(m_base);
965         else
966             base = generator.emitNodeForLeftHandSide(m_base, m_subscriptHasAssignments, m_subscript->isPure(generator));
967     }
968
969     RefPtr<RegisterID> function;
970     RefPtr<RegisterID> thisRegister;
971     if (baseIsSuper) {
972         // Note that we only need to do this once because we either have a non-TDZ this or we throw. Once we have a non-TDZ this, we can't change its value back to TDZ.
973         thisRegister = generator.ensureThis();
974     }
975     if (subscriptIsNonIndexString) {
976         generator.emitExpressionInfo(subexpressionDivot(), subexpressionStart(), subexpressionEnd());
977         if (baseIsSuper)
978             function = generator.emitGetById(generator.tempDestination(dst), base.get(), thisRegister.get(), static_cast<StringNode*>(m_subscript)->value());
979         else
980             function = generator.emitGetById(generator.tempDestination(dst), base.get(), static_cast<StringNode*>(m_subscript)->value());
981     } else {
982         RefPtr<RegisterID> property = generator.emitNode(m_subscript);
983         generator.emitExpressionInfo(subexpressionDivot(), subexpressionStart(), subexpressionEnd());
984         if (baseIsSuper)
985             function = generator.emitGetByVal(generator.tempDestination(dst), base.get(), thisRegister.get(), property.get());
986         else
987             function = generator.emitGetByVal(generator.tempDestination(dst), base.get(), property.get());
988     }
989
990     RefPtr<RegisterID> returnValue = generator.finalDestination(dst, function.get());
991     CallArguments callArguments(generator, m_args);
992     if (baseIsSuper) {
993         generator.emitTDZCheck(generator.thisRegister());
994         generator.emitMove(callArguments.thisRegister(), thisRegister.get());
995     } else
996         generator.emitMove(callArguments.thisRegister(), base.get());
997     RegisterID* ret = generator.emitCallInTailPosition(returnValue.get(), function.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
998     generator.emitProfileType(returnValue.get(), divotStart(), divotEnd());
999     return ret;
1000 }
1001
1002 // ------------------------------ FunctionCallDotNode ----------------------------------
1003
1004 RegisterID* FunctionCallDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1005 {
1006     RefPtr<RegisterID> function = generator.tempDestination(dst);
1007     RefPtr<RegisterID> returnValue = generator.finalDestination(dst, function.get());
1008     CallArguments callArguments(generator, m_args);
1009     bool baseIsSuper = m_base->isSuperNode();
1010     if (baseIsSuper)
1011         generator.emitMove(callArguments.thisRegister(), generator.ensureThis());
1012     else
1013         generator.emitNode(callArguments.thisRegister(), m_base);
1014     generator.emitExpressionInfo(subexpressionDivot(), subexpressionStart(), subexpressionEnd());
1015     if (baseIsSuper) {
1016         RefPtr<RegisterID> superBase = emitSuperBaseForCallee(generator);
1017         generator.emitGetById(function.get(), superBase.get(), callArguments.thisRegister(), m_ident);
1018     } else
1019         generator.emitGetById(function.get(), callArguments.thisRegister(), m_ident);
1020     RegisterID* ret = generator.emitCallInTailPosition(returnValue.get(), function.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
1021     generator.emitProfileType(returnValue.get(), divotStart(), divotEnd());
1022     return ret;
1023 }
1024
1025 RegisterID* CallFunctionCallDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1026 {
1027     RefPtr<Label> realCall = generator.newLabel();
1028     RefPtr<Label> end = generator.newLabel();
1029     RefPtr<RegisterID> base = generator.emitNode(m_base);
1030     generator.emitExpressionInfo(subexpressionDivot(), subexpressionStart(), subexpressionEnd());
1031     RefPtr<RegisterID> function;
1032     bool emitCallCheck = !generator.isBuiltinFunction();
1033     if (emitCallCheck) {
1034         if (m_base->isSuperNode()) {
1035             RefPtr<RegisterID> thisValue = generator.ensureThis();
1036             function = generator.emitGetById(generator.tempDestination(dst), base.get(), thisValue.get(), generator.propertyNames().builtinNames().callPublicName());
1037         } else
1038             function = generator.emitGetById(generator.tempDestination(dst), base.get(), generator.propertyNames().builtinNames().callPublicName());
1039         generator.emitJumpIfNotFunctionCall(function.get(), realCall.get());
1040     }
1041     RefPtr<RegisterID> returnValue = generator.finalDestination(dst);
1042     {
1043         if (m_args->m_listNode && m_args->m_listNode->m_expr && m_args->m_listNode->m_expr->isSpreadExpression()) {
1044             SpreadExpressionNode* spread = static_cast<SpreadExpressionNode*>(m_args->m_listNode->m_expr);
1045             ExpressionNode* subject = spread->expression();
1046             RefPtr<RegisterID> argumentsRegister;
1047             argumentsRegister = generator.emitNode(subject);
1048             generator.emitExpressionInfo(spread->divot(), spread->divotStart(), spread->divotEnd());
1049             RefPtr<RegisterID> thisRegister = generator.emitGetByVal(generator.newTemporary(), argumentsRegister.get(), generator.emitLoad(0, jsNumber(0)));
1050             generator.emitCallVarargsInTailPosition(returnValue.get(), base.get(), thisRegister.get(), argumentsRegister.get(), generator.newTemporary(), 1, divot(), divotStart(), divotEnd());
1051         } else if (m_args->m_listNode && m_args->m_listNode->m_expr) {
1052             ArgumentListNode* oldList = m_args->m_listNode;
1053             m_args->m_listNode = m_args->m_listNode->m_next;
1054
1055             RefPtr<RegisterID> realFunction = generator.emitMove(generator.tempDestination(dst), base.get());
1056             CallArguments callArguments(generator, m_args);
1057             generator.emitNode(callArguments.thisRegister(), oldList->m_expr);
1058             generator.emitCallInTailPosition(returnValue.get(), realFunction.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
1059             m_args->m_listNode = oldList;
1060         } else {
1061             RefPtr<RegisterID> realFunction = generator.emitMove(generator.tempDestination(dst), base.get());
1062             CallArguments callArguments(generator, m_args);
1063             generator.emitLoad(callArguments.thisRegister(), jsUndefined());
1064             generator.emitCallInTailPosition(returnValue.get(), realFunction.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
1065         }
1066     }
1067     if (emitCallCheck) {
1068         generator.emitJump(end.get());
1069         generator.emitLabel(realCall.get());
1070         {
1071             CallArguments callArguments(generator, m_args);
1072             generator.emitMove(callArguments.thisRegister(), base.get());
1073             generator.emitCallInTailPosition(returnValue.get(), function.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
1074         }
1075         generator.emitLabel(end.get());
1076     }
1077     generator.emitProfileType(returnValue.get(), divotStart(), divotEnd());
1078     return returnValue.get();
1079 }
1080
1081 static bool areTrivialApplyArguments(ArgumentsNode* args)
1082 {
1083     return !args->m_listNode || !args->m_listNode->m_expr || !args->m_listNode->m_next
1084         || (!args->m_listNode->m_next->m_next && args->m_listNode->m_next->m_expr->isSimpleArray());
1085 }
1086
1087 RegisterID* ApplyFunctionCallDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1088 {
1089     // A few simple cases can be trivially handled as ordinary function calls.
1090     // function.apply(), function.apply(arg) -> identical to function.call
1091     // function.apply(thisArg, [arg0, arg1, ...]) -> can be trivially coerced into function.call(thisArg, arg0, arg1, ...) and saves object allocation
1092     bool mayBeCall = areTrivialApplyArguments(m_args);
1093
1094     RefPtr<Label> realCall = generator.newLabel();
1095     RefPtr<Label> end = generator.newLabel();
1096     RefPtr<RegisterID> base = generator.emitNode(m_base);
1097     generator.emitExpressionInfo(subexpressionDivot(), subexpressionStart(), subexpressionEnd());
1098     RefPtr<RegisterID> function;
1099     RefPtr<RegisterID> returnValue = generator.finalDestination(dst, function.get());
1100     bool emitCallCheck = !generator.isBuiltinFunction();
1101     if (emitCallCheck) {
1102         if (m_base->isSuperNode()) {
1103             RefPtr<RegisterID> thisValue = generator.ensureThis();
1104             function = generator.emitGetById(generator.tempDestination(dst), base.get(), thisValue.get(), generator.propertyNames().builtinNames().applyPublicName());
1105         } else
1106             function = generator.emitGetById(generator.tempDestination(dst), base.get(), generator.propertyNames().builtinNames().applyPublicName());
1107         generator.emitJumpIfNotFunctionApply(function.get(), realCall.get());
1108     }
1109     if (mayBeCall) {
1110         if (m_args->m_listNode && m_args->m_listNode->m_expr) {
1111             ArgumentListNode* oldList = m_args->m_listNode;
1112             if (m_args->m_listNode->m_expr->isSpreadExpression()) {
1113                 SpreadExpressionNode* spread = static_cast<SpreadExpressionNode*>(m_args->m_listNode->m_expr);
1114                 RefPtr<RegisterID> realFunction = generator.emitMove(generator.newTemporary(), base.get());
1115                 RefPtr<RegisterID> index = generator.emitLoad(generator.newTemporary(), jsNumber(0));
1116                 RefPtr<RegisterID> thisRegister = generator.emitLoad(generator.newTemporary(), jsUndefined());
1117                 RefPtr<RegisterID> argumentsRegister = generator.emitLoad(generator.newTemporary(), jsUndefined());
1118                 
1119                 auto extractor = [&thisRegister, &argumentsRegister, &index](BytecodeGenerator& generator, RegisterID* value)
1120                 {
1121                     RefPtr<Label> haveThis = generator.newLabel();
1122                     RefPtr<Label> end = generator.newLabel();
1123                     RefPtr<RegisterID> compareResult = generator.newTemporary();
1124                     RefPtr<RegisterID> indexZeroCompareResult = generator.emitBinaryOp(op_eq, compareResult.get(), index.get(), generator.emitLoad(0, jsNumber(0)), OperandTypes(ResultType::numberTypeIsInt32(), ResultType::numberTypeIsInt32()));
1125                     generator.emitJumpIfFalse(indexZeroCompareResult.get(), haveThis.get());
1126                     generator.emitMove(thisRegister.get(), value);
1127                     generator.emitLoad(index.get(), jsNumber(1));
1128                     generator.emitJump(end.get());
1129                     generator.emitLabel(haveThis.get());
1130                     RefPtr<RegisterID> indexOneCompareResult = generator.emitBinaryOp(op_eq, compareResult.get(), index.get(), generator.emitLoad(0, jsNumber(1)), OperandTypes(ResultType::numberTypeIsInt32(), ResultType::numberTypeIsInt32()));
1131                     generator.emitJumpIfFalse(indexOneCompareResult.get(), end.get());
1132                     generator.emitMove(argumentsRegister.get(), value);
1133                     generator.emitLoad(index.get(), jsNumber(2));
1134                     generator.emitLabel(end.get());
1135                 };
1136                 generator.emitEnumeration(this, spread->expression(), extractor);
1137                 generator.emitCallVarargsInTailPosition(returnValue.get(), realFunction.get(), thisRegister.get(), argumentsRegister.get(), generator.newTemporary(), 0, divot(), divotStart(), divotEnd());
1138             } else if (m_args->m_listNode->m_next) {
1139                 ASSERT(m_args->m_listNode->m_next->m_expr->isSimpleArray());
1140                 ASSERT(!m_args->m_listNode->m_next->m_next);
1141                 m_args->m_listNode = static_cast<ArrayNode*>(m_args->m_listNode->m_next->m_expr)->toArgumentList(generator.parserArena(), 0, 0);
1142                 RefPtr<RegisterID> realFunction = generator.emitMove(generator.tempDestination(dst), base.get());
1143                 CallArguments callArguments(generator, m_args);
1144                 generator.emitNode(callArguments.thisRegister(), oldList->m_expr);
1145                 generator.emitCallInTailPosition(returnValue.get(), realFunction.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
1146             } else {
1147                 m_args->m_listNode = m_args->m_listNode->m_next;
1148                 RefPtr<RegisterID> realFunction = generator.emitMove(generator.tempDestination(dst), base.get());
1149                 CallArguments callArguments(generator, m_args);
1150                 generator.emitNode(callArguments.thisRegister(), oldList->m_expr);
1151                 generator.emitCallInTailPosition(returnValue.get(), realFunction.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
1152             }
1153             m_args->m_listNode = oldList;
1154         } else {
1155             RefPtr<RegisterID> realFunction = generator.emitMove(generator.tempDestination(dst), base.get());
1156             CallArguments callArguments(generator, m_args);
1157             generator.emitLoad(callArguments.thisRegister(), jsUndefined());
1158             generator.emitCallInTailPosition(returnValue.get(), realFunction.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
1159         }
1160     } else {
1161         ASSERT(m_args->m_listNode && m_args->m_listNode->m_next);
1162         RefPtr<RegisterID> realFunction = generator.emitMove(generator.tempDestination(dst), base.get());
1163         RefPtr<RegisterID> thisRegister = generator.emitNode(m_args->m_listNode->m_expr);
1164         RefPtr<RegisterID> argsRegister;
1165         ArgumentListNode* args = m_args->m_listNode->m_next;
1166         argsRegister = generator.emitNode(args->m_expr);
1167
1168         // Function.prototype.apply ignores extra arguments, but we still
1169         // need to evaluate them for side effects.
1170         while ((args = args->m_next))
1171             generator.emitNode(args->m_expr);
1172
1173         generator.emitCallVarargsInTailPosition(returnValue.get(), realFunction.get(), thisRegister.get(), argsRegister.get(), generator.newTemporary(), 0, divot(), divotStart(), divotEnd());
1174     }
1175     if (emitCallCheck) {
1176         generator.emitJump(end.get());
1177         generator.emitLabel(realCall.get());
1178         CallArguments callArguments(generator, m_args);
1179         generator.emitMove(callArguments.thisRegister(), base.get());
1180         generator.emitCallInTailPosition(returnValue.get(), function.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
1181         generator.emitLabel(end.get());
1182     }
1183     generator.emitProfileType(returnValue.get(), divotStart(), divotEnd());
1184     return returnValue.get();
1185 }
1186
1187 // ------------------------------ PostfixNode ----------------------------------
1188
1189 static RegisterID* emitIncOrDec(BytecodeGenerator& generator, RegisterID* srcDst, Operator oper)
1190 {
1191     return (oper == OpPlusPlus) ? generator.emitInc(srcDst) : generator.emitDec(srcDst);
1192 }
1193
1194 static RegisterID* emitPostIncOrDec(BytecodeGenerator& generator, RegisterID* dst, RegisterID* srcDst, Operator oper)
1195 {
1196     if (dst == srcDst)
1197         return generator.emitToNumber(generator.finalDestination(dst), srcDst);
1198     RefPtr<RegisterID> tmp = generator.emitToNumber(generator.tempDestination(dst), srcDst);
1199     emitIncOrDec(generator, srcDst, oper);
1200     return generator.moveToDestinationIfNeeded(dst, tmp.get());
1201 }
1202
1203 RegisterID* PostfixNode::emitResolve(BytecodeGenerator& generator, RegisterID* dst)
1204 {
1205     if (dst == generator.ignoredResult())
1206         return PrefixNode::emitResolve(generator, dst);
1207
1208     ASSERT(m_expr->isResolveNode());
1209     ResolveNode* resolve = static_cast<ResolveNode*>(m_expr);
1210     const Identifier& ident = resolve->identifier();
1211
1212     Variable var = generator.variable(ident);
1213     if (RegisterID* local = var.local()) {
1214         generator.emitTDZCheckIfNecessary(var, local, nullptr);
1215         RefPtr<RegisterID> localReg = local;
1216         if (var.isReadOnly()) {
1217             generator.emitReadOnlyExceptionIfNeeded(var);
1218             localReg = generator.emitMove(generator.tempDestination(dst), local);
1219         }
1220         RefPtr<RegisterID> oldValue = emitPostIncOrDec(generator, generator.finalDestination(dst), localReg.get(), m_operator);
1221         generator.emitProfileType(localReg.get(), var, divotStart(), divotEnd());
1222         return oldValue.get();
1223     }
1224
1225     generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
1226     RefPtr<RegisterID> scope = generator.emitResolveScope(nullptr, var);
1227     RefPtr<RegisterID> value = generator.emitGetFromScope(generator.newTemporary(), scope.get(), var, ThrowIfNotFound);
1228     generator.emitTDZCheckIfNecessary(var, value.get(), nullptr);
1229     if (var.isReadOnly()) {
1230         bool threwException = generator.emitReadOnlyExceptionIfNeeded(var);
1231         if (threwException)
1232             return value.get();
1233     }
1234     RefPtr<RegisterID> oldValue = emitPostIncOrDec(generator, generator.finalDestination(dst), value.get(), m_operator);
1235     if (!var.isReadOnly()) {
1236         generator.emitPutToScope(scope.get(), var, value.get(), ThrowIfNotFound, InitializationMode::NotInitialization);
1237         generator.emitProfileType(value.get(), var, divotStart(), divotEnd());
1238     }
1239
1240     return oldValue.get();
1241 }
1242
1243 RegisterID* PostfixNode::emitBracket(BytecodeGenerator& generator, RegisterID* dst)
1244 {
1245     if (dst == generator.ignoredResult())
1246         return PrefixNode::emitBracket(generator, dst);
1247
1248     ASSERT(m_expr->isBracketAccessorNode());
1249     BracketAccessorNode* bracketAccessor = static_cast<BracketAccessorNode*>(m_expr);
1250     ExpressionNode* baseNode = bracketAccessor->base();
1251     ExpressionNode* subscript = bracketAccessor->subscript();
1252
1253     RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(baseNode, bracketAccessor->subscriptHasAssignments(), subscript->isPure(generator));
1254     RefPtr<RegisterID> property = generator.emitNode(subscript);
1255
1256     generator.emitExpressionInfo(bracketAccessor->divot(), bracketAccessor->divotStart(), bracketAccessor->divotEnd());
1257     RefPtr<RegisterID> value;
1258     RefPtr<RegisterID> thisValue;
1259     if (baseNode->isSuperNode()) {
1260         thisValue = generator.ensureThis();
1261         value = generator.emitGetByVal(generator.newTemporary(), base.get(), thisValue.get(), property.get());
1262     } else
1263         value = generator.emitGetByVal(generator.newTemporary(), base.get(), property.get());
1264     RegisterID* oldValue = emitPostIncOrDec(generator, generator.tempDestination(dst), value.get(), m_operator);
1265     generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
1266     if (baseNode->isSuperNode())
1267         generator.emitPutByVal(base.get(), thisValue.get(), property.get(), value.get());
1268     else
1269         generator.emitPutByVal(base.get(), property.get(), value.get());
1270     generator.emitProfileType(value.get(), divotStart(), divotEnd());
1271     return generator.moveToDestinationIfNeeded(dst, oldValue);
1272 }
1273
1274 RegisterID* PostfixNode::emitDot(BytecodeGenerator& generator, RegisterID* dst)
1275 {
1276     if (dst == generator.ignoredResult())
1277         return PrefixNode::emitDot(generator, dst);
1278
1279     ASSERT(m_expr->isDotAccessorNode());
1280     DotAccessorNode* dotAccessor = static_cast<DotAccessorNode*>(m_expr);
1281     ExpressionNode* baseNode = dotAccessor->base();
1282     bool baseIsSuper = baseNode->isSuperNode();
1283     const Identifier& ident = dotAccessor->identifier();
1284
1285     RefPtr<RegisterID> base = generator.emitNode(baseNode);
1286
1287     generator.emitExpressionInfo(dotAccessor->divot(), dotAccessor->divotStart(), dotAccessor->divotEnd());
1288     RefPtr<RegisterID> value;
1289     RefPtr<RegisterID> thisValue;
1290     if (baseIsSuper) {
1291         thisValue = generator.ensureThis();
1292         value = generator.emitGetById(generator.newTemporary(), base.get(), thisValue.get(), ident);
1293     } else
1294         value = generator.emitGetById(generator.newTemporary(), base.get(), ident);
1295     RegisterID* oldValue = emitPostIncOrDec(generator, generator.tempDestination(dst), value.get(), m_operator);
1296     generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
1297     if (baseIsSuper)
1298         generator.emitPutById(base.get(), thisValue.get(), ident, value.get());
1299     else
1300         generator.emitPutById(base.get(), ident, value.get());
1301     generator.emitProfileType(value.get(), divotStart(), divotEnd());
1302     return generator.moveToDestinationIfNeeded(dst, oldValue);
1303 }
1304
1305 RegisterID* PostfixNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1306 {
1307     if (m_expr->isResolveNode())
1308         return emitResolve(generator, dst);
1309
1310     if (m_expr->isBracketAccessorNode())
1311         return emitBracket(generator, dst);
1312
1313     if (m_expr->isDotAccessorNode())
1314         return emitDot(generator, dst);
1315
1316     return emitThrowReferenceError(generator, m_operator == OpPlusPlus
1317         ? ASCIILiteral("Postfix ++ operator applied to value that is not a reference.")
1318         : ASCIILiteral("Postfix -- operator applied to value that is not a reference."));
1319 }
1320
1321 // ------------------------------ DeleteResolveNode -----------------------------------
1322
1323 RegisterID* DeleteResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1324 {
1325     Variable var = generator.variable(m_ident);
1326     if (var.local()) {
1327         generator.emitTDZCheckIfNecessary(var, var.local(), nullptr);
1328         return generator.emitLoad(generator.finalDestination(dst), false);
1329     }
1330
1331     generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
1332     RefPtr<RegisterID> base = generator.emitResolveScope(dst, var);
1333     generator.emitTDZCheckIfNecessary(var, nullptr, base.get());
1334     return generator.emitDeleteById(generator.finalDestination(dst, base.get()), base.get(), m_ident);
1335 }
1336
1337 // ------------------------------ DeleteBracketNode -----------------------------------
1338
1339 RegisterID* DeleteBracketNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1340 {
1341     RefPtr<RegisterID> r0 = generator.emitNode(m_base);
1342     RefPtr<RegisterID> r1 = generator.emitNode(m_subscript);
1343
1344     generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
1345     if (m_base->isSuperNode())
1346         return emitThrowReferenceError(generator, "Cannot delete a super property");
1347     return generator.emitDeleteByVal(generator.finalDestination(dst), r0.get(), r1.get());
1348 }
1349
1350 // ------------------------------ DeleteDotNode -----------------------------------
1351
1352 RegisterID* DeleteDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1353 {
1354     RefPtr<RegisterID> r0 = generator.emitNode(m_base);
1355
1356     generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
1357     if (m_base->isSuperNode())
1358         return emitThrowReferenceError(generator, "Cannot delete a super property");
1359     return generator.emitDeleteById(generator.finalDestination(dst), r0.get(), m_ident);
1360 }
1361
1362 // ------------------------------ DeleteValueNode -----------------------------------
1363
1364 RegisterID* DeleteValueNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1365 {
1366     generator.emitNode(generator.ignoredResult(), m_expr);
1367
1368     // delete on a non-location expression ignores the value and returns true
1369     return generator.emitLoad(generator.finalDestination(dst), true);
1370 }
1371
1372 // ------------------------------ VoidNode -------------------------------------
1373
1374 RegisterID* VoidNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1375 {
1376     if (dst == generator.ignoredResult()) {
1377         generator.emitNode(generator.ignoredResult(), m_expr);
1378         return 0;
1379     }
1380     RefPtr<RegisterID> r0 = generator.emitNode(m_expr);
1381     return generator.emitLoad(dst, jsUndefined());
1382 }
1383
1384 // ------------------------------ TypeOfResolveNode -----------------------------------
1385
1386 RegisterID* TypeOfResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1387 {
1388     Variable var = generator.variable(m_ident);
1389     if (RegisterID* local = var.local()) {
1390         generator.emitTDZCheckIfNecessary(var, local, nullptr);
1391         if (dst == generator.ignoredResult())
1392             return 0;
1393         return generator.emitTypeOf(generator.finalDestination(dst), local);
1394     }
1395
1396     RefPtr<RegisterID> scope = generator.emitResolveScope(dst, var);
1397     RefPtr<RegisterID> value = generator.emitGetFromScope(generator.newTemporary(), scope.get(), var, DoNotThrowIfNotFound);
1398     generator.emitTDZCheckIfNecessary(var, value.get(), nullptr);
1399     if (dst == generator.ignoredResult())
1400         return 0;
1401     return generator.emitTypeOf(generator.finalDestination(dst, scope.get()), value.get());
1402 }
1403
1404 // ------------------------------ TypeOfValueNode -----------------------------------
1405
1406 RegisterID* TypeOfValueNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1407 {
1408     if (dst == generator.ignoredResult()) {
1409         generator.emitNode(generator.ignoredResult(), m_expr);
1410         return 0;
1411     }
1412     RefPtr<RegisterID> src = generator.emitNode(m_expr);
1413     return generator.emitTypeOf(generator.finalDestination(dst), src.get());
1414 }
1415
1416 // ------------------------------ PrefixNode ----------------------------------
1417
1418 RegisterID* PrefixNode::emitResolve(BytecodeGenerator& generator, RegisterID* dst)
1419 {
1420     ASSERT(m_expr->isResolveNode());
1421     ResolveNode* resolve = static_cast<ResolveNode*>(m_expr);
1422     const Identifier& ident = resolve->identifier();
1423
1424     Variable var = generator.variable(ident);
1425     if (RegisterID* local = var.local()) {
1426         generator.emitTDZCheckIfNecessary(var, local, nullptr);
1427         RefPtr<RegisterID> localReg = local;
1428         if (var.isReadOnly()) {
1429             generator.emitReadOnlyExceptionIfNeeded(var);
1430             localReg = generator.emitMove(generator.tempDestination(dst), localReg.get());
1431         } else if (generator.vm()->typeProfiler()) {
1432             RefPtr<RegisterID> tempDst = generator.tempDestination(dst);
1433             generator.emitMove(tempDst.get(), localReg.get());
1434             emitIncOrDec(generator, tempDst.get(), m_operator);
1435             generator.emitMove(localReg.get(), tempDst.get());
1436             generator.emitProfileType(localReg.get(), var, divotStart(), divotEnd());
1437             return generator.moveToDestinationIfNeeded(dst, tempDst.get());
1438         }
1439         emitIncOrDec(generator, localReg.get(), m_operator);
1440         return generator.moveToDestinationIfNeeded(dst, localReg.get());
1441     }
1442
1443     generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
1444     RefPtr<RegisterID> scope = generator.emitResolveScope(dst, var);
1445     RefPtr<RegisterID> value = generator.emitGetFromScope(generator.newTemporary(), scope.get(), var, ThrowIfNotFound);
1446     generator.emitTDZCheckIfNecessary(var, value.get(), nullptr);
1447     if (var.isReadOnly()) {
1448         bool threwException = generator.emitReadOnlyExceptionIfNeeded(var);
1449         if (threwException)
1450             return value.get();
1451     }
1452
1453     emitIncOrDec(generator, value.get(), m_operator);
1454     if (!var.isReadOnly()) {
1455         generator.emitPutToScope(scope.get(), var, value.get(), ThrowIfNotFound, InitializationMode::NotInitialization);
1456         generator.emitProfileType(value.get(), var, divotStart(), divotEnd());
1457     }
1458     return generator.moveToDestinationIfNeeded(dst, value.get());
1459 }
1460
1461 RegisterID* PrefixNode::emitBracket(BytecodeGenerator& generator, RegisterID* dst)
1462 {
1463     ASSERT(m_expr->isBracketAccessorNode());
1464     BracketAccessorNode* bracketAccessor = static_cast<BracketAccessorNode*>(m_expr);
1465     ExpressionNode* baseNode = bracketAccessor->base();
1466     ExpressionNode* subscript = bracketAccessor->subscript();
1467
1468     RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(baseNode, bracketAccessor->subscriptHasAssignments(), subscript->isPure(generator));
1469     RefPtr<RegisterID> property = generator.emitNode(subscript);
1470     RefPtr<RegisterID> propDst = generator.tempDestination(dst);
1471
1472     generator.emitExpressionInfo(bracketAccessor->divot(), bracketAccessor->divotStart(), bracketAccessor->divotEnd());
1473     RegisterID* value;
1474     RefPtr<RegisterID> thisValue;
1475     if (baseNode->isSuperNode()) {
1476         thisValue = generator.ensureThis();
1477         value = generator.emitGetByVal(propDst.get(), base.get(), thisValue.get(), property.get());
1478     } else
1479         value = generator.emitGetByVal(propDst.get(), base.get(), property.get());
1480     emitIncOrDec(generator, value, m_operator);
1481     generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
1482     if (baseNode->isSuperNode())
1483         generator.emitPutByVal(base.get(), thisValue.get(), property.get(), value);
1484     else
1485         generator.emitPutByVal(base.get(), property.get(), value);
1486     generator.emitProfileType(value, divotStart(), divotEnd());
1487     return generator.moveToDestinationIfNeeded(dst, propDst.get());
1488 }
1489
1490 RegisterID* PrefixNode::emitDot(BytecodeGenerator& generator, RegisterID* dst)
1491 {
1492     ASSERT(m_expr->isDotAccessorNode());
1493     DotAccessorNode* dotAccessor = static_cast<DotAccessorNode*>(m_expr);
1494     ExpressionNode* baseNode = dotAccessor->base();
1495     const Identifier& ident = dotAccessor->identifier();
1496
1497     RefPtr<RegisterID> base = generator.emitNode(baseNode);
1498     RefPtr<RegisterID> propDst = generator.tempDestination(dst);
1499
1500     generator.emitExpressionInfo(dotAccessor->divot(), dotAccessor->divotStart(), dotAccessor->divotEnd());
1501     RegisterID* value;
1502     RefPtr<RegisterID> thisValue;
1503     if (baseNode->isSuperNode()) {
1504         thisValue = generator.ensureThis();
1505         value = generator.emitGetById(propDst.get(), base.get(), thisValue.get(), ident);
1506     } else
1507         value = generator.emitGetById(propDst.get(), base.get(), ident);
1508     emitIncOrDec(generator, value, m_operator);
1509     generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
1510     if (baseNode->isSuperNode())
1511         generator.emitPutById(base.get(), thisValue.get(), ident, value);
1512     else
1513         generator.emitPutById(base.get(), ident, value);
1514     generator.emitProfileType(value, divotStart(), divotEnd());
1515     return generator.moveToDestinationIfNeeded(dst, propDst.get());
1516 }
1517
1518 RegisterID* PrefixNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1519 {
1520     if (m_expr->isResolveNode())
1521         return emitResolve(generator, dst);
1522
1523     if (m_expr->isBracketAccessorNode())
1524         return emitBracket(generator, dst);
1525
1526     if (m_expr->isDotAccessorNode())
1527         return emitDot(generator, dst);
1528
1529     return emitThrowReferenceError(generator, m_operator == OpPlusPlus
1530         ? ASCIILiteral("Prefix ++ operator applied to value that is not a reference.")
1531         : ASCIILiteral("Prefix -- operator applied to value that is not a reference."));
1532 }
1533
1534 // ------------------------------ Unary Operation Nodes -----------------------------------
1535
1536 RegisterID* UnaryOpNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1537 {
1538     RefPtr<RegisterID> src = generator.emitNode(m_expr);
1539     generator.emitExpressionInfo(position(), position(), position());
1540     return generator.emitUnaryOp(opcodeID(), generator.finalDestination(dst), src.get());
1541 }
1542
1543 // ------------------------------ BitwiseNotNode -----------------------------------
1544  
1545 RegisterID* BitwiseNotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1546 {
1547     RefPtr<RegisterID> src2 = generator.emitLoad(generator.newTemporary(), jsNumber(-1));
1548     RefPtr<RegisterID> src1 = generator.emitNode(m_expr);
1549     return generator.emitBinaryOp(op_bitxor, generator.finalDestination(dst, src1.get()), src1.get(), src2.get(), OperandTypes(m_expr->resultDescriptor(), ResultType::numberTypeIsInt32()));
1550 }
1551  
1552 // ------------------------------ LogicalNotNode -----------------------------------
1553
1554 void LogicalNotNode::emitBytecodeInConditionContext(BytecodeGenerator& generator, Label* trueTarget, Label* falseTarget, FallThroughMode fallThroughMode)
1555 {
1556     // reverse the true and false targets
1557     generator.emitNodeInConditionContext(expr(), falseTarget, trueTarget, invert(fallThroughMode));
1558 }
1559
1560
1561 // ------------------------------ Binary Operation Nodes -----------------------------------
1562
1563 // BinaryOpNode::emitStrcat:
1564 //
1565 // This node generates an op_strcat operation.  This opcode can handle concatenation of three or
1566 // more values, where we can determine a set of separate op_add operations would be operating on
1567 // string values.
1568 //
1569 // This function expects to be operating on a graph of AST nodes looking something like this:
1570 //
1571 //     (a)...     (b)
1572 //          \   /
1573 //           (+)     (c)
1574 //              \   /
1575 //      [d]     ((+))
1576 //         \    /
1577 //          [+=]
1578 //
1579 // The assignment operation is optional, if it exists the register holding the value on the
1580 // lefthand side of the assignment should be passing as the optional 'lhs' argument.
1581 //
1582 // The method should be called on the node at the root of the tree of regular binary add
1583 // operations (marked in the diagram with a double set of parentheses).  This node must
1584 // be performing a string concatenation (determined by statically detecting that at least
1585 // one child must be a string).  
1586 //
1587 // Since the minimum number of values being concatenated together is expected to be 3, if
1588 // a lhs to a concatenating assignment is not provided then the  root add should have at
1589 // least one left child that is also an add that can be determined to be operating on strings.
1590 //
1591 RegisterID* BinaryOpNode::emitStrcat(BytecodeGenerator& generator, RegisterID* dst, RegisterID* lhs, ReadModifyResolveNode* emitExpressionInfoForMe)
1592 {
1593     ASSERT(isAdd());
1594     ASSERT(resultDescriptor().definitelyIsString());
1595
1596     // Create a list of expressions for all the adds in the tree of nodes we can convert into
1597     // a string concatenation.  The rightmost node (c) is added first.  The rightmost node is
1598     // added first, and the leftmost child is never added, so the vector produced for the
1599     // example above will be [ c, b ].
1600     Vector<ExpressionNode*, 16> reverseExpressionList;
1601     reverseExpressionList.append(m_expr2);
1602
1603     // Examine the left child of the add.  So long as this is a string add, add its right-child
1604     // to the list, and keep processing along the left fork.
1605     ExpressionNode* leftMostAddChild = m_expr1;
1606     while (leftMostAddChild->isAdd() && leftMostAddChild->resultDescriptor().definitelyIsString()) {
1607         reverseExpressionList.append(static_cast<AddNode*>(leftMostAddChild)->m_expr2);
1608         leftMostAddChild = static_cast<AddNode*>(leftMostAddChild)->m_expr1;
1609     }
1610
1611     Vector<RefPtr<RegisterID>, 16> temporaryRegisters;
1612
1613     // If there is an assignment, allocate a temporary to hold the lhs after conversion.
1614     // We could possibly avoid this (the lhs is converted last anyway, we could let the
1615     // op_strcat node handle its conversion if required).
1616     if (lhs)
1617         temporaryRegisters.append(generator.newTemporary());
1618
1619     // Emit code for the leftmost node ((a) in the example).
1620     temporaryRegisters.append(generator.newTemporary());
1621     RegisterID* leftMostAddChildTempRegister = temporaryRegisters.last().get();
1622     generator.emitNode(leftMostAddChildTempRegister, leftMostAddChild);
1623
1624     // Note on ordering of conversions:
1625     //
1626     // We maintain the same ordering of conversions as we would see if the concatenations
1627     // was performed as a sequence of adds (otherwise this optimization could change
1628     // behaviour should an object have been provided a valueOf or toString method).
1629     //
1630     // Considering the above example, the sequnce of execution is:
1631     //     * evaluate operand (a)
1632     //     * evaluate operand (b)
1633     //     * convert (a) to primitive   <-  (this would be triggered by the first add)
1634     //     * convert (b) to primitive   <-  (ditto)
1635     //     * evaluate operand (c)
1636     //     * convert (c) to primitive   <-  (this would be triggered by the second add)
1637     // And optionally, if there is an assignment:
1638     //     * convert (d) to primitive   <-  (this would be triggered by the assigning addition)
1639     //
1640     // As such we do not plant an op to convert the leftmost child now.  Instead, use
1641     // 'leftMostAddChildTempRegister' as a flag to trigger generation of the conversion
1642     // once the second node has been generated.  However, if the leftmost child is an
1643     // immediate we can trivially determine that no conversion will be required.
1644     // If this is the case
1645     if (leftMostAddChild->isString())
1646         leftMostAddChildTempRegister = 0;
1647
1648     while (reverseExpressionList.size()) {
1649         ExpressionNode* node = reverseExpressionList.last();
1650         reverseExpressionList.removeLast();
1651
1652         // Emit the code for the current node.
1653         temporaryRegisters.append(generator.newTemporary());
1654         generator.emitNode(temporaryRegisters.last().get(), node);
1655
1656         // On the first iteration of this loop, when we first reach this point we have just
1657         // generated the second node, which means it is time to convert the leftmost operand.
1658         if (leftMostAddChildTempRegister) {
1659             generator.emitToPrimitive(leftMostAddChildTempRegister, leftMostAddChildTempRegister);
1660             leftMostAddChildTempRegister = 0; // Only do this once.
1661         }
1662         // Plant a conversion for this node, if necessary.
1663         if (!node->isString())
1664             generator.emitToPrimitive(temporaryRegisters.last().get(), temporaryRegisters.last().get());
1665     }
1666     ASSERT(temporaryRegisters.size() >= 3);
1667
1668     // Certain read-modify nodes require expression info to be emitted *after* m_right has been generated.
1669     // If this is required the node is passed as 'emitExpressionInfoForMe'; do so now.
1670     if (emitExpressionInfoForMe)
1671         generator.emitExpressionInfo(emitExpressionInfoForMe->divot(), emitExpressionInfoForMe->divotStart(), emitExpressionInfoForMe->divotEnd());
1672     // If there is an assignment convert the lhs now.  This will also copy lhs to
1673     // the temporary register we allocated for it.
1674     if (lhs)
1675         generator.emitToPrimitive(temporaryRegisters[0].get(), lhs);
1676
1677     return generator.emitStrcat(generator.finalDestination(dst, temporaryRegisters[0].get()), temporaryRegisters[0].get(), temporaryRegisters.size());
1678 }
1679
1680 void BinaryOpNode::emitBytecodeInConditionContext(BytecodeGenerator& generator, Label* trueTarget, Label* falseTarget, FallThroughMode fallThroughMode)
1681 {
1682     TriState branchCondition;
1683     ExpressionNode* branchExpression;
1684     tryFoldToBranch(generator, branchCondition, branchExpression);
1685
1686     if (branchCondition == MixedTriState)
1687         ExpressionNode::emitBytecodeInConditionContext(generator, trueTarget, falseTarget, fallThroughMode);
1688     else if (branchCondition == TrueTriState)
1689         generator.emitNodeInConditionContext(branchExpression, trueTarget, falseTarget, fallThroughMode);
1690     else
1691         generator.emitNodeInConditionContext(branchExpression, falseTarget, trueTarget, invert(fallThroughMode));
1692 }
1693
1694 static inline bool canFoldToBranch(OpcodeID opcodeID, ExpressionNode* branchExpression, JSValue constant)
1695 {
1696     ResultType expressionType = branchExpression->resultDescriptor();
1697
1698     if (expressionType.definitelyIsBoolean() && constant.isBoolean())
1699         return true;
1700     else if (expressionType.definitelyIsBoolean() && constant.isInt32() && (constant.asInt32() == 0 || constant.asInt32() == 1))
1701         return opcodeID == op_eq || opcodeID == op_neq; // Strict equality is false in the case of type mismatch.
1702     else if (expressionType.isInt32() && constant.isInt32() && constant.asInt32() == 0)
1703         return true;
1704
1705     return false;
1706 }
1707
1708 void BinaryOpNode::tryFoldToBranch(BytecodeGenerator& generator, TriState& branchCondition, ExpressionNode*& branchExpression)
1709 {
1710     branchCondition = MixedTriState;
1711     branchExpression = 0;
1712
1713     ConstantNode* constant = 0;
1714     if (m_expr1->isConstant()) {
1715         constant = static_cast<ConstantNode*>(m_expr1);
1716         branchExpression = m_expr2;
1717     } else if (m_expr2->isConstant()) {
1718         constant = static_cast<ConstantNode*>(m_expr2);
1719         branchExpression = m_expr1;
1720     }
1721
1722     if (!constant)
1723         return;
1724     ASSERT(branchExpression);
1725
1726     OpcodeID opcodeID = this->opcodeID();
1727     JSValue value = constant->jsValue(generator);
1728     bool canFoldToBranch = JSC::canFoldToBranch(opcodeID, branchExpression, value);
1729     if (!canFoldToBranch)
1730         return;
1731
1732     if (opcodeID == op_eq || opcodeID == op_stricteq)
1733         branchCondition = triState(value.pureToBoolean());
1734     else if (opcodeID == op_neq || opcodeID == op_nstricteq)
1735         branchCondition = triState(!value.pureToBoolean());
1736 }
1737
1738 RegisterID* BinaryOpNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1739 {
1740     OpcodeID opcodeID = this->opcodeID();
1741
1742     if (opcodeID == op_add && m_expr1->isAdd() && m_expr1->resultDescriptor().definitelyIsString()) {
1743         generator.emitExpressionInfo(position(), position(), position());
1744         return emitStrcat(generator, dst);
1745     }
1746
1747     if (opcodeID == op_neq) {
1748         if (m_expr1->isNull() || m_expr2->isNull()) {
1749             RefPtr<RegisterID> src = generator.tempDestination(dst);
1750             generator.emitNode(src.get(), m_expr1->isNull() ? m_expr2 : m_expr1);
1751             return generator.emitUnaryOp(op_neq_null, generator.finalDestination(dst, src.get()), src.get());
1752         }
1753     }
1754
1755     ExpressionNode* left = m_expr1;
1756     ExpressionNode* right = m_expr2;
1757     if (opcodeID == op_neq || opcodeID == op_nstricteq) {
1758         if (left->isString())
1759             std::swap(left, right);
1760     }
1761
1762     RefPtr<RegisterID> src1 = generator.emitNodeForLeftHandSide(left, m_rightHasAssignments, right->isPure(generator));
1763     bool wasTypeof = generator.lastOpcodeID() == op_typeof;
1764     RefPtr<RegisterID> src2 = generator.emitNode(right);
1765     generator.emitExpressionInfo(position(), position(), position());
1766     if (wasTypeof && (opcodeID == op_neq || opcodeID == op_nstricteq)) {
1767         RefPtr<RegisterID> tmp = generator.tempDestination(dst);
1768         if (opcodeID == op_neq)
1769             generator.emitEqualityOp(op_eq, generator.finalDestination(tmp.get(), src1.get()), src1.get(), src2.get());
1770         else if (opcodeID == op_nstricteq)
1771             generator.emitEqualityOp(op_stricteq, generator.finalDestination(tmp.get(), src1.get()), src1.get(), src2.get());
1772         else
1773             RELEASE_ASSERT_NOT_REACHED();
1774         return generator.emitUnaryOp(op_not, generator.finalDestination(dst, tmp.get()), tmp.get());
1775     }
1776     RegisterID* result = generator.emitBinaryOp(opcodeID, generator.finalDestination(dst, src1.get()), src1.get(), src2.get(), OperandTypes(left->resultDescriptor(), right->resultDescriptor()));
1777     if (opcodeID == op_urshift && dst != generator.ignoredResult())
1778         return generator.emitUnaryOp(op_unsigned, result, result);
1779     return result;
1780 }
1781
1782 RegisterID* EqualNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1783 {
1784     if (m_expr1->isNull() || m_expr2->isNull()) {
1785         RefPtr<RegisterID> src = generator.tempDestination(dst);
1786         generator.emitNode(src.get(), m_expr1->isNull() ? m_expr2 : m_expr1);
1787         return generator.emitUnaryOp(op_eq_null, generator.finalDestination(dst, src.get()), src.get());
1788     }
1789
1790     ExpressionNode* left = m_expr1;
1791     ExpressionNode* right = m_expr2;
1792     if (left->isString())
1793         std::swap(left, right);
1794
1795     RefPtr<RegisterID> src1 = generator.emitNodeForLeftHandSide(left, m_rightHasAssignments, m_expr2->isPure(generator));
1796     RefPtr<RegisterID> src2 = generator.emitNode(right);
1797     return generator.emitEqualityOp(op_eq, generator.finalDestination(dst, src1.get()), src1.get(), src2.get());
1798 }
1799
1800 RegisterID* StrictEqualNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1801 {
1802     ExpressionNode* left = m_expr1;
1803     ExpressionNode* right = m_expr2;
1804     if (left->isString())
1805         std::swap(left, right);
1806
1807     RefPtr<RegisterID> src1 = generator.emitNodeForLeftHandSide(left, m_rightHasAssignments, m_expr2->isPure(generator));
1808     RefPtr<RegisterID> src2 = generator.emitNode(right);
1809     return generator.emitEqualityOp(op_stricteq, generator.finalDestination(dst, src1.get()), src1.get(), src2.get());
1810 }
1811
1812 RegisterID* ThrowableBinaryOpNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1813 {
1814     RefPtr<RegisterID> src1 = generator.emitNodeForLeftHandSide(m_expr1, m_rightHasAssignments, m_expr2->isPure(generator));
1815     RefPtr<RegisterID> src2 = generator.emitNode(m_expr2);
1816     generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
1817     return generator.emitBinaryOp(opcodeID(), generator.finalDestination(dst, src1.get()), src1.get(), src2.get(), OperandTypes(m_expr1->resultDescriptor(), m_expr2->resultDescriptor()));
1818 }
1819
1820 RegisterID* InstanceOfNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1821 {
1822     RefPtr<RegisterID> hasInstanceValue = generator.newTemporary();
1823     RefPtr<RegisterID> isObject = generator.newTemporary();
1824     RefPtr<RegisterID> isCustom = generator.newTemporary();
1825     RefPtr<RegisterID> prototype = generator.newTemporary();
1826     RefPtr<RegisterID> value = generator.emitNodeForLeftHandSide(m_expr1, m_rightHasAssignments, m_expr2->isPure(generator));
1827     RefPtr<RegisterID> constructor = generator.emitNode(m_expr2);
1828     RefPtr<RegisterID> dstReg = generator.finalDestination(dst, value.get());
1829     RefPtr<Label> custom = generator.newLabel();
1830     RefPtr<Label> done = generator.newLabel();
1831     RefPtr<Label> typeError = generator.newLabel();
1832
1833     generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
1834     generator.emitIsObject(isObject.get(), constructor.get());
1835     generator.emitJumpIfFalse(isObject.get(), typeError.get());
1836
1837     generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
1838     generator.emitGetById(hasInstanceValue.get(), constructor.get(), generator.vm()->propertyNames->hasInstanceSymbol);
1839
1840     generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
1841     generator.emitOverridesHasInstance(isCustom.get(), constructor.get(), hasInstanceValue.get());
1842
1843     generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
1844     generator.emitJumpIfTrue(isCustom.get(), custom.get());
1845
1846     generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
1847     generator.emitGetById(prototype.get(), constructor.get(), generator.vm()->propertyNames->prototype);
1848
1849     generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
1850     generator.emitInstanceOf(dstReg.get(), value.get(), prototype.get());
1851
1852     generator.emitJump(done.get());
1853
1854     generator.emitLabel(typeError.get());
1855     generator.emitThrowTypeError("Right hand side of instanceof is not an object");
1856
1857     generator.emitLabel(custom.get());
1858
1859     generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
1860     generator.emitInstanceOfCustom(dstReg.get(), value.get(), constructor.get(), hasInstanceValue.get());
1861
1862     generator.emitLabel(done.get());
1863
1864     return dstReg.get();
1865 }
1866
1867 // ------------------------------ LogicalOpNode ----------------------------
1868
1869 RegisterID* LogicalOpNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1870 {
1871     RefPtr<RegisterID> temp = generator.tempDestination(dst);
1872     RefPtr<Label> target = generator.newLabel();
1873     
1874     generator.emitNode(temp.get(), m_expr1);
1875     if (m_operator == OpLogicalAnd)
1876         generator.emitJumpIfFalse(temp.get(), target.get());
1877     else
1878         generator.emitJumpIfTrue(temp.get(), target.get());
1879     generator.emitNodeInTailPosition(temp.get(), m_expr2);
1880     generator.emitLabel(target.get());
1881
1882     return generator.moveToDestinationIfNeeded(dst, temp.get());
1883 }
1884
1885 void LogicalOpNode::emitBytecodeInConditionContext(BytecodeGenerator& generator, Label* trueTarget, Label* falseTarget, FallThroughMode fallThroughMode)
1886 {
1887     RefPtr<Label> afterExpr1 = generator.newLabel();
1888     if (m_operator == OpLogicalAnd)
1889         generator.emitNodeInConditionContext(m_expr1, afterExpr1.get(), falseTarget, FallThroughMeansTrue);
1890     else 
1891         generator.emitNodeInConditionContext(m_expr1, trueTarget, afterExpr1.get(), FallThroughMeansFalse);
1892     generator.emitLabel(afterExpr1.get());
1893
1894     generator.emitNodeInConditionContext(m_expr2, trueTarget, falseTarget, fallThroughMode);
1895 }
1896
1897 // ------------------------------ ConditionalNode ------------------------------
1898
1899 RegisterID* ConditionalNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1900 {
1901     RefPtr<RegisterID> newDst = generator.finalDestination(dst);
1902     RefPtr<Label> beforeElse = generator.newLabel();
1903     RefPtr<Label> afterElse = generator.newLabel();
1904
1905     RefPtr<Label> beforeThen = generator.newLabel();
1906     generator.emitNodeInConditionContext(m_logical, beforeThen.get(), beforeElse.get(), FallThroughMeansTrue);
1907     generator.emitLabel(beforeThen.get());
1908
1909     generator.emitProfileControlFlow(m_expr1->startOffset());
1910     generator.emitNodeInTailPosition(newDst.get(), m_expr1);
1911     generator.emitJump(afterElse.get());
1912
1913     generator.emitLabel(beforeElse.get());
1914     generator.emitProfileControlFlow(m_expr1->endOffset() + 1);
1915     generator.emitNodeInTailPosition(newDst.get(), m_expr2);
1916
1917     generator.emitLabel(afterElse.get());
1918
1919     generator.emitProfileControlFlow(m_expr2->endOffset() + 1);
1920
1921     return newDst.get();
1922 }
1923
1924 // ------------------------------ ReadModifyResolveNode -----------------------------------
1925
1926 // FIXME: should this be moved to be a method on BytecodeGenerator?
1927 static ALWAYS_INLINE RegisterID* emitReadModifyAssignment(BytecodeGenerator& generator, RegisterID* dst, RegisterID* src1, ExpressionNode* m_right, Operator oper, OperandTypes types, ReadModifyResolveNode* emitExpressionInfoForMe = 0)
1928 {
1929     OpcodeID opcodeID;
1930     switch (oper) {
1931         case OpMultEq:
1932             opcodeID = op_mul;
1933             break;
1934         case OpDivEq:
1935             opcodeID = op_div;
1936             break;
1937         case OpPlusEq:
1938             if (m_right->isAdd() && m_right->resultDescriptor().definitelyIsString())
1939                 return static_cast<AddNode*>(m_right)->emitStrcat(generator, dst, src1, emitExpressionInfoForMe);
1940             opcodeID = op_add;
1941             break;
1942         case OpMinusEq:
1943             opcodeID = op_sub;
1944             break;
1945         case OpLShift:
1946             opcodeID = op_lshift;
1947             break;
1948         case OpRShift:
1949             opcodeID = op_rshift;
1950             break;
1951         case OpURShift:
1952             opcodeID = op_urshift;
1953             break;
1954         case OpAndEq:
1955             opcodeID = op_bitand;
1956             break;
1957         case OpXOrEq:
1958             opcodeID = op_bitxor;
1959             break;
1960         case OpOrEq:
1961             opcodeID = op_bitor;
1962             break;
1963         case OpModEq:
1964             opcodeID = op_mod;
1965             break;
1966         default:
1967             RELEASE_ASSERT_NOT_REACHED();
1968             return dst;
1969     }
1970
1971     RegisterID* src2 = generator.emitNode(m_right);
1972
1973     // Certain read-modify nodes require expression info to be emitted *after* m_right has been generated.
1974     // If this is required the node is passed as 'emitExpressionInfoForMe'; do so now.
1975     if (emitExpressionInfoForMe)
1976         generator.emitExpressionInfo(emitExpressionInfoForMe->divot(), emitExpressionInfoForMe->divotStart(), emitExpressionInfoForMe->divotEnd());
1977     RegisterID* result = generator.emitBinaryOp(opcodeID, dst, src1, src2, types);
1978     if (oper == OpURShift)
1979         return generator.emitUnaryOp(op_unsigned, result, result);
1980     return result;
1981 }
1982
1983 RegisterID* ReadModifyResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1984 {
1985     JSTextPosition newDivot = divotStart() + m_ident.length();
1986     Variable var = generator.variable(m_ident);
1987     if (RegisterID* local = var.local()) {
1988         generator.emitTDZCheckIfNecessary(var, local, nullptr);
1989         if (var.isReadOnly()) {
1990             generator.emitReadOnlyExceptionIfNeeded(var);
1991             RegisterID* result = emitReadModifyAssignment(generator, generator.finalDestination(dst), local, m_right, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()));
1992             generator.emitProfileType(result, divotStart(), divotEnd());
1993             return result;
1994         }
1995         
1996         if (generator.leftHandSideNeedsCopy(m_rightHasAssignments, m_right->isPure(generator))) {
1997             RefPtr<RegisterID> result = generator.newTemporary();
1998             generator.emitMove(result.get(), local);
1999             emitReadModifyAssignment(generator, result.get(), result.get(), m_right, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()));
2000             generator.emitMove(local, result.get());
2001             generator.invalidateForInContextForLocal(local);
2002             generator.emitProfileType(local, divotStart(), divotEnd());
2003             return generator.moveToDestinationIfNeeded(dst, result.get());
2004         }
2005         
2006         RegisterID* result = emitReadModifyAssignment(generator, local, local, m_right, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()));
2007         generator.invalidateForInContextForLocal(local);
2008         generator.emitProfileType(result, divotStart(), divotEnd());
2009         return generator.moveToDestinationIfNeeded(dst, result);
2010     }
2011
2012     generator.emitExpressionInfo(newDivot, divotStart(), newDivot);
2013     RefPtr<RegisterID> scope = generator.emitResolveScope(nullptr, var);
2014     RefPtr<RegisterID> value = generator.emitGetFromScope(generator.newTemporary(), scope.get(), var, ThrowIfNotFound);
2015     generator.emitTDZCheckIfNecessary(var, value.get(), nullptr);
2016     if (var.isReadOnly()) {
2017         bool threwException = generator.emitReadOnlyExceptionIfNeeded(var);
2018         if (threwException)
2019             return value.get();
2020     }
2021     RefPtr<RegisterID> result = emitReadModifyAssignment(generator, generator.finalDestination(dst, value.get()), value.get(), m_right, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()), this);
2022     RegisterID* returnResult = result.get();
2023     if (!var.isReadOnly()) {
2024         returnResult = generator.emitPutToScope(scope.get(), var, result.get(), ThrowIfNotFound, InitializationMode::NotInitialization);
2025         generator.emitProfileType(result.get(), var, divotStart(), divotEnd());
2026     }
2027     return returnResult;
2028 }
2029
2030 static InitializationMode initializationModeForAssignmentContext(AssignmentContext assignmentContext)
2031 {
2032     switch (assignmentContext) {
2033     case AssignmentContext::DeclarationStatement:
2034         return InitializationMode::Initialization;
2035     case AssignmentContext::ConstDeclarationStatement:
2036         return InitializationMode::ConstInitialization;
2037     case AssignmentContext::AssignmentExpression:
2038         return InitializationMode::NotInitialization;
2039     }
2040
2041     ASSERT_NOT_REACHED();
2042     return InitializationMode::NotInitialization;
2043 }
2044
2045 // ------------------------------ AssignResolveNode -----------------------------------
2046
2047 RegisterID* AssignResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2048 {
2049     Variable var = generator.variable(m_ident);
2050     bool isReadOnly = var.isReadOnly() && m_assignmentContext != AssignmentContext::ConstDeclarationStatement;
2051     if (RegisterID* local = var.local()) {
2052         RegisterID* result = nullptr;
2053         if (m_assignmentContext == AssignmentContext::AssignmentExpression)
2054             generator.emitTDZCheckIfNecessary(var, local, nullptr);
2055
2056         if (isReadOnly) {
2057             result = generator.emitNode(dst, m_right); // Execute side effects first.
2058             generator.emitReadOnlyExceptionIfNeeded(var);
2059             generator.emitProfileType(result, var, divotStart(), divotEnd());
2060         } else if (var.isSpecial()) {
2061             RefPtr<RegisterID> tempDst = generator.tempDestination(dst);
2062             generator.emitNode(tempDst.get(), m_right);
2063             generator.emitMove(local, tempDst.get());
2064             generator.emitProfileType(local, var, divotStart(), divotEnd());
2065             generator.invalidateForInContextForLocal(local);
2066             result = generator.moveToDestinationIfNeeded(dst, tempDst.get());
2067         } else {
2068             RegisterID* right = generator.emitNode(local, m_right);
2069             generator.emitProfileType(right, var, divotStart(), divotEnd());
2070             generator.invalidateForInContextForLocal(local);
2071             result = generator.moveToDestinationIfNeeded(dst, right);
2072         }
2073
2074         if (m_assignmentContext == AssignmentContext::DeclarationStatement || m_assignmentContext == AssignmentContext::ConstDeclarationStatement)
2075             generator.liftTDZCheckIfPossible(var);
2076         return result;
2077     }
2078
2079     if (generator.isStrictMode())
2080         generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
2081     RefPtr<RegisterID> scope = generator.emitResolveScope(nullptr, var);
2082     if (m_assignmentContext == AssignmentContext::AssignmentExpression)
2083         generator.emitTDZCheckIfNecessary(var, nullptr, scope.get());
2084     if (dst == generator.ignoredResult())
2085         dst = 0;
2086     RefPtr<RegisterID> result = generator.emitNode(dst, m_right);
2087     if (isReadOnly) {
2088         RegisterID* result = generator.emitNode(dst, m_right); // Execute side effects first.
2089         bool threwException = generator.emitReadOnlyExceptionIfNeeded(var);
2090         if (threwException)
2091             return result;
2092     }
2093     generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
2094     RegisterID* returnResult = result.get();
2095     if (!isReadOnly) {
2096         returnResult = generator.emitPutToScope(scope.get(), var, result.get(), generator.isStrictMode() ? ThrowIfNotFound : DoNotThrowIfNotFound, initializationModeForAssignmentContext(m_assignmentContext));
2097         generator.emitProfileType(result.get(), var, divotStart(), divotEnd());
2098     }
2099
2100     if (m_assignmentContext == AssignmentContext::DeclarationStatement || m_assignmentContext == AssignmentContext::ConstDeclarationStatement)
2101         generator.liftTDZCheckIfPossible(var);
2102     return returnResult;
2103 }
2104
2105 // ------------------------------ AssignDotNode -----------------------------------
2106
2107 RegisterID* AssignDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2108 {
2109     RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base, m_rightHasAssignments, m_right->isPure(generator));
2110     RefPtr<RegisterID> value = generator.destinationForAssignResult(dst);
2111     RefPtr<RegisterID> result = generator.emitNode(value.get(), m_right);
2112     generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
2113     RefPtr<RegisterID> forwardResult = (dst == generator.ignoredResult()) ? result.get() : generator.moveToDestinationIfNeeded(generator.tempDestination(result.get()), result.get());
2114     if (m_base->isSuperNode()) {
2115         RefPtr<RegisterID> thisValue = generator.ensureThis();
2116         generator.emitPutById(base.get(), thisValue.get(), m_ident, forwardResult.get());
2117     } else
2118         generator.emitPutById(base.get(), m_ident, forwardResult.get());
2119     generator.emitProfileType(forwardResult.get(), divotStart(), divotEnd());
2120     return generator.moveToDestinationIfNeeded(dst, forwardResult.get());
2121 }
2122
2123 // ------------------------------ ReadModifyDotNode -----------------------------------
2124
2125 RegisterID* ReadModifyDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2126 {
2127     RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base, m_rightHasAssignments, m_right->isPure(generator));
2128
2129     generator.emitExpressionInfo(subexpressionDivot(), subexpressionStart(), subexpressionEnd());
2130     RefPtr<RegisterID> value;
2131     RefPtr<RegisterID> thisValue;
2132     if (m_base->isSuperNode()) {
2133         thisValue = generator.ensureThis();
2134         value = generator.emitGetById(generator.tempDestination(dst), base.get(), thisValue.get(), m_ident);
2135     } else
2136         value = generator.emitGetById(generator.tempDestination(dst), base.get(), m_ident);
2137     RegisterID* updatedValue = emitReadModifyAssignment(generator, generator.finalDestination(dst, value.get()), value.get(), m_right, static_cast<JSC::Operator>(m_operator), OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()));
2138
2139     generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
2140     RegisterID* ret;
2141     if (m_base->isSuperNode())
2142         ret = generator.emitPutById(base.get(), thisValue.get(), m_ident, updatedValue);
2143     else
2144         ret = generator.emitPutById(base.get(), m_ident, updatedValue);
2145     generator.emitProfileType(updatedValue, divotStart(), divotEnd());
2146     return ret;
2147 }
2148
2149 // ------------------------------ AssignErrorNode -----------------------------------
2150
2151 RegisterID* AssignErrorNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
2152 {
2153     return emitThrowReferenceError(generator, ASCIILiteral("Left side of assignment is not a reference."));
2154 }
2155
2156 // ------------------------------ AssignBracketNode -----------------------------------
2157
2158 RegisterID* AssignBracketNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2159 {
2160     RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base, m_subscriptHasAssignments || m_rightHasAssignments, m_subscript->isPure(generator) && m_right->isPure(generator));
2161     RefPtr<RegisterID> property = generator.emitNodeForLeftHandSide(m_subscript, m_rightHasAssignments, m_right->isPure(generator));
2162     RefPtr<RegisterID> value = generator.destinationForAssignResult(dst);
2163     RefPtr<RegisterID> result = generator.emitNode(value.get(), m_right);
2164
2165     generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
2166     RegisterID* forwardResult = (dst == generator.ignoredResult()) ? result.get() : generator.moveToDestinationIfNeeded(generator.tempDestination(result.get()), result.get());
2167
2168     if (isNonIndexStringElement(*m_subscript)) {
2169         if (m_base->isSuperNode()) {
2170             RefPtr<RegisterID> thisValue = generator.ensureThis();
2171             generator.emitPutById(base.get(), thisValue.get(), static_cast<StringNode*>(m_subscript)->value(), forwardResult);
2172         } else
2173             generator.emitPutById(base.get(), static_cast<StringNode*>(m_subscript)->value(), forwardResult);
2174     } else {
2175         if (m_base->isSuperNode()) {
2176             RefPtr<RegisterID> thisValue = generator.ensureThis();
2177             generator.emitPutByVal(base.get(), thisValue.get(), property.get(), forwardResult);
2178         } else
2179             generator.emitPutByVal(base.get(), property.get(), forwardResult);
2180     }
2181
2182     generator.emitProfileType(forwardResult, divotStart(), divotEnd());
2183     return generator.moveToDestinationIfNeeded(dst, forwardResult);
2184 }
2185
2186 // ------------------------------ ReadModifyBracketNode -----------------------------------
2187
2188 RegisterID* ReadModifyBracketNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2189 {
2190     RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base, m_subscriptHasAssignments || m_rightHasAssignments, m_subscript->isPure(generator) && m_right->isPure(generator));
2191     RefPtr<RegisterID> property = generator.emitNodeForLeftHandSide(m_subscript, m_rightHasAssignments, m_right->isPure(generator));
2192
2193     generator.emitExpressionInfo(subexpressionDivot(), subexpressionStart(), subexpressionEnd());
2194     RefPtr<RegisterID> value;
2195     RefPtr<RegisterID> thisValue;
2196     if (m_base->isSuperNode()) {
2197         thisValue = generator.ensureThis();
2198         value = generator.emitGetByVal(generator.tempDestination(dst), base.get(), thisValue.get(), property.get());
2199     } else
2200         value = generator.emitGetByVal(generator.tempDestination(dst), base.get(), property.get());
2201     RegisterID* updatedValue = emitReadModifyAssignment(generator, generator.finalDestination(dst, value.get()), value.get(), m_right, static_cast<JSC::Operator>(m_operator), OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()));
2202
2203     generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
2204     if (m_base->isSuperNode())
2205         generator.emitPutByVal(base.get(), thisValue.get(), property.get(), updatedValue);
2206     else
2207         generator.emitPutByVal(base.get(), property.get(), updatedValue);
2208     generator.emitProfileType(updatedValue, divotStart(), divotEnd());
2209
2210     return updatedValue;
2211 }
2212
2213 // ------------------------------ CommaNode ------------------------------------
2214
2215 RegisterID* CommaNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2216 {
2217     CommaNode* node = this;
2218     for (; node && node->next(); node = node->next())
2219         generator.emitNode(generator.ignoredResult(), node->m_expr);
2220     return generator.emitNodeInTailPosition(dst, node->m_expr);
2221 }
2222
2223 // ------------------------------ SourceElements -------------------------------
2224
2225
2226 inline StatementNode* SourceElements::lastStatement() const
2227 {
2228     return m_tail;
2229 }
2230
2231 inline void SourceElements::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2232 {
2233     for (StatementNode* statement = m_head; statement; statement = statement->next())
2234         generator.emitNodeInTailPosition(dst, statement);
2235 }
2236
2237 // ------------------------------ BlockNode ------------------------------------
2238
2239 inline StatementNode* BlockNode::lastStatement() const
2240 {
2241     return m_statements ? m_statements->lastStatement() : 0;
2242 }
2243
2244 StatementNode* BlockNode::singleStatement() const
2245 {
2246     return m_statements ? m_statements->singleStatement() : 0;
2247 }
2248
2249 void BlockNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2250 {
2251     if (!m_statements)
2252         return;
2253     generator.pushLexicalScope(this, BytecodeGenerator::TDZCheckOptimization::Optimize, BytecodeGenerator::NestedScopeType::IsNested);
2254     m_statements->emitBytecode(generator, dst);
2255     generator.popLexicalScope(this);
2256 }
2257
2258 // ------------------------------ EmptyStatementNode ---------------------------
2259
2260 void EmptyStatementNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
2261 {
2262     generator.emitDebugHook(WillExecuteStatement, firstLine(), startOffset(), lineStartOffset());
2263 }
2264
2265 // ------------------------------ DebuggerStatementNode ---------------------------
2266
2267 void DebuggerStatementNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
2268 {
2269     generator.emitDebugHook(DidReachBreakpoint, lastLine(), startOffset(), lineStartOffset());
2270 }
2271
2272 // ------------------------------ ExprStatementNode ----------------------------
2273
2274 void ExprStatementNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2275 {
2276     ASSERT(m_expr);
2277     generator.emitDebugHook(WillExecuteStatement, firstLine(), startOffset(), lineStartOffset());
2278     generator.emitNode(dst, m_expr);
2279 }
2280
2281 // ------------------------------ DeclarationStatement ----------------------------
2282
2283 void DeclarationStatement::emitBytecode(BytecodeGenerator& generator, RegisterID*)
2284 {
2285     ASSERT(m_expr);
2286     generator.emitDebugHook(WillExecuteStatement, firstLine(), startOffset(), lineStartOffset());
2287     generator.emitNode(m_expr);
2288 }
2289
2290 // ------------------------------ EmptyVarExpression ----------------------------
2291
2292 RegisterID* EmptyVarExpression::emitBytecode(BytecodeGenerator& generator, RegisterID*)
2293 {
2294     // It's safe to return null here because this node will always be a child node of DeclarationStatement which ignores our return value.
2295     if (!generator.vm()->typeProfiler())
2296         return nullptr;
2297
2298     Variable var = generator.variable(m_ident);
2299     if (RegisterID* local = var.local())
2300         generator.emitProfileType(local, var, position(), JSTextPosition(-1, position().offset + m_ident.length(), -1));
2301     else {
2302         RefPtr<RegisterID> scope = generator.emitResolveScope(nullptr, var);
2303         RefPtr<RegisterID> value = generator.emitGetFromScope(generator.newTemporary(), scope.get(), var, DoNotThrowIfNotFound);
2304         generator.emitProfileType(value.get(), var, position(), JSTextPosition(-1, position().offset + m_ident.length(), -1));
2305     }
2306
2307     return nullptr;
2308 }
2309
2310 // ------------------------------ EmptyLetExpression ----------------------------
2311
2312 RegisterID* EmptyLetExpression::emitBytecode(BytecodeGenerator& generator, RegisterID*)
2313 {
2314     // Lexical declarations like 'let' must move undefined into their variables so we don't
2315     // get TDZ errors for situations like this: `let x; x;`
2316     Variable var = generator.variable(m_ident);
2317     if (RegisterID* local = var.local()) {
2318         generator.emitLoad(local, jsUndefined());
2319         generator.emitProfileType(local, var, position(), JSTextPosition(-1, position().offset + m_ident.length(), -1));
2320     } else {
2321         RefPtr<RegisterID> scope = generator.emitResolveScope(nullptr, var);
2322         RefPtr<RegisterID> value = generator.emitLoad(nullptr, jsUndefined());
2323         generator.emitPutToScope(scope.get(), var, value.get(), generator.isStrictMode() ? ThrowIfNotFound : DoNotThrowIfNotFound, InitializationMode::Initialization);
2324         generator.emitProfileType(value.get(), var, position(), JSTextPosition(-1, position().offset + m_ident.length(), -1)); 
2325     }
2326
2327     generator.liftTDZCheckIfPossible(var);
2328
2329     // It's safe to return null here because this node will always be a child node of DeclarationStatement which ignores our return value.
2330     return nullptr;
2331 }
2332
2333 // ------------------------------ IfElseNode ---------------------------------------
2334
2335 static inline StatementNode* singleStatement(StatementNode* statementNode)
2336 {
2337     if (statementNode->isBlock())
2338         return static_cast<BlockNode*>(statementNode)->singleStatement();
2339     return statementNode;
2340 }
2341
2342 bool IfElseNode::tryFoldBreakAndContinue(BytecodeGenerator& generator, StatementNode* ifBlock,
2343     Label*& trueTarget, FallThroughMode& fallThroughMode)
2344 {
2345     StatementNode* singleStatement = JSC::singleStatement(ifBlock);
2346     if (!singleStatement)
2347         return false;
2348
2349     if (singleStatement->isBreak()) {
2350         BreakNode* breakNode = static_cast<BreakNode*>(singleStatement);
2351         Label* target = breakNode->trivialTarget(generator);
2352         if (!target)
2353             return false;
2354         trueTarget = target;
2355         fallThroughMode = FallThroughMeansFalse;
2356         return true;
2357     }
2358
2359     if (singleStatement->isContinue()) {
2360         ContinueNode* continueNode = static_cast<ContinueNode*>(singleStatement);
2361         Label* target = continueNode->trivialTarget(generator);
2362         if (!target)
2363             return false;
2364         trueTarget = target;
2365         fallThroughMode = FallThroughMeansFalse;
2366         return true;
2367     }
2368
2369     return false;
2370 }
2371
2372 void IfElseNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2373 {
2374     generator.emitDebugHook(WillExecuteStatement, firstLine(), startOffset(), lineStartOffset());
2375     
2376     RefPtr<Label> beforeThen = generator.newLabel();
2377     RefPtr<Label> beforeElse = generator.newLabel();
2378     RefPtr<Label> afterElse = generator.newLabel();
2379
2380     Label* trueTarget = beforeThen.get();
2381     Label* falseTarget = beforeElse.get();
2382     FallThroughMode fallThroughMode = FallThroughMeansTrue;
2383     bool didFoldIfBlock = tryFoldBreakAndContinue(generator, m_ifBlock, trueTarget, fallThroughMode);
2384
2385     generator.emitNodeInConditionContext(m_condition, trueTarget, falseTarget, fallThroughMode);
2386     generator.emitLabel(beforeThen.get());
2387     generator.emitProfileControlFlow(m_ifBlock->startOffset());
2388
2389     if (!didFoldIfBlock) {
2390         generator.emitNodeInTailPosition(dst, m_ifBlock);
2391         if (m_elseBlock)
2392             generator.emitJump(afterElse.get());
2393     }
2394
2395     generator.emitLabel(beforeElse.get());
2396
2397     if (m_elseBlock) {
2398         generator.emitProfileControlFlow(m_ifBlock->endOffset() + (m_ifBlock->isBlock() ? 1 : 0));
2399         generator.emitNodeInTailPosition(dst, m_elseBlock);
2400     }
2401
2402     generator.emitLabel(afterElse.get());
2403     StatementNode* endingBlock = m_elseBlock ? m_elseBlock : m_ifBlock;
2404     generator.emitProfileControlFlow(endingBlock->endOffset() + (endingBlock->isBlock() ? 1 : 0));
2405 }
2406
2407 // ------------------------------ DoWhileNode ----------------------------------
2408
2409 void DoWhileNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2410 {
2411     LabelScopePtr scope = generator.newLabelScope(LabelScope::Loop);
2412
2413     RefPtr<Label> topOfLoop = generator.newLabel();
2414     generator.emitLabel(topOfLoop.get());
2415     generator.emitLoopHint();
2416     generator.emitDebugHook(WillExecuteStatement, lastLine(), startOffset(), lineStartOffset());
2417
2418     generator.emitNodeInTailPosition(dst, m_statement);
2419
2420     generator.emitLabel(scope->continueTarget());
2421     generator.emitDebugHook(WillExecuteStatement, lastLine(), startOffset(), lineStartOffset());
2422     generator.emitNodeInConditionContext(m_expr, topOfLoop.get(), scope->breakTarget(), FallThroughMeansFalse);
2423
2424     generator.emitLabel(scope->breakTarget());
2425 }
2426
2427 // ------------------------------ WhileNode ------------------------------------
2428
2429 void WhileNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2430 {
2431     LabelScopePtr scope = generator.newLabelScope(LabelScope::Loop);
2432     RefPtr<Label> topOfLoop = generator.newLabel();
2433
2434     generator.emitDebugHook(WillExecuteStatement, m_expr->firstLine(), m_expr->startOffset(), m_expr->lineStartOffset());
2435     generator.emitNodeInConditionContext(m_expr, topOfLoop.get(), scope->breakTarget(), FallThroughMeansTrue);
2436
2437     generator.emitLabel(topOfLoop.get());
2438     generator.emitLoopHint();
2439     
2440     generator.emitProfileControlFlow(m_statement->startOffset());
2441     generator.emitNodeInTailPosition(dst, m_statement);
2442
2443     generator.emitLabel(scope->continueTarget());
2444     generator.emitDebugHook(WillExecuteStatement, firstLine(), startOffset(), lineStartOffset());
2445
2446     generator.emitNodeInConditionContext(m_expr, topOfLoop.get(), scope->breakTarget(), FallThroughMeansFalse);
2447
2448     generator.emitLabel(scope->breakTarget());
2449
2450     generator.emitProfileControlFlow(m_statement->endOffset() + (m_statement->isBlock() ? 1 : 0));
2451 }
2452
2453 // ------------------------------ ForNode --------------------------------------
2454
2455 void ForNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2456 {
2457     LabelScopePtr scope = generator.newLabelScope(LabelScope::Loop);
2458
2459     RegisterID* forLoopSymbolTable = nullptr;
2460     generator.pushLexicalScope(this, BytecodeGenerator::TDZCheckOptimization::Optimize, BytecodeGenerator::NestedScopeType::IsNested, &forLoopSymbolTable);
2461
2462     generator.emitDebugHook(WillExecuteStatement, firstLine(), startOffset(), lineStartOffset());
2463
2464     if (m_expr1)
2465         generator.emitNode(generator.ignoredResult(), m_expr1);
2466     
2467     RefPtr<Label> topOfLoop = generator.newLabel();
2468     if (m_expr2)
2469         generator.emitNodeInConditionContext(m_expr2, topOfLoop.get(), scope->breakTarget(), FallThroughMeansTrue);
2470
2471     generator.emitLabel(topOfLoop.get());
2472     generator.emitLoopHint();
2473     generator.emitProfileControlFlow(m_statement->startOffset());
2474
2475     generator.emitNodeInTailPosition(dst, m_statement);
2476
2477     generator.emitLabel(scope->continueTarget());
2478     generator.emitDebugHook(WillExecuteStatement, firstLine(), startOffset(), lineStartOffset());
2479     generator.prepareLexicalScopeForNextForLoopIteration(this, forLoopSymbolTable);
2480     if (m_expr3)
2481         generator.emitNode(generator.ignoredResult(), m_expr3);
2482
2483     if (m_expr2)
2484         generator.emitNodeInConditionContext(m_expr2, topOfLoop.get(), scope->breakTarget(), FallThroughMeansFalse);
2485     else
2486         generator.emitJump(topOfLoop.get());
2487
2488     generator.emitLabel(scope->breakTarget());
2489     generator.popLexicalScope(this);
2490     generator.emitProfileControlFlow(m_statement->endOffset() + (m_statement->isBlock() ? 1 : 0));
2491 }
2492
2493 // ------------------------------ ForInNode ------------------------------------
2494
2495 RegisterID* ForInNode::tryGetBoundLocal(BytecodeGenerator& generator)
2496 {
2497     if (m_lexpr->isResolveNode()) {
2498         const Identifier& ident = static_cast<ResolveNode*>(m_lexpr)->identifier();
2499         return generator.variable(ident).local();
2500     }
2501
2502     if (m_lexpr->isDestructuringNode()) {
2503         DestructuringAssignmentNode* assignNode = static_cast<DestructuringAssignmentNode*>(m_lexpr);
2504         auto binding = assignNode->bindings();
2505         if (!binding->isBindingNode())
2506             return nullptr;
2507
2508         auto simpleBinding = static_cast<BindingNode*>(binding);
2509         const Identifier& ident = simpleBinding->boundProperty();
2510         Variable var = generator.variable(ident);
2511         if (var.isSpecial())
2512             return nullptr;
2513         return var.local();
2514     }
2515
2516     return nullptr;
2517 }
2518
2519 void ForInNode::emitLoopHeader(BytecodeGenerator& generator, RegisterID* propertyName)
2520 {
2521     if (m_lexpr->isResolveNode()) {
2522         const Identifier& ident = static_cast<ResolveNode*>(m_lexpr)->identifier();
2523         Variable var = generator.variable(ident);
2524         if (RegisterID* local = var.local())
2525             generator.emitMove(local, propertyName);
2526         else {
2527             if (generator.isStrictMode())
2528                 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
2529             RegisterID* scope = generator.emitResolveScope(nullptr, var);
2530             generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
2531             generator.emitPutToScope(scope, var, propertyName, generator.isStrictMode() ? ThrowIfNotFound : DoNotThrowIfNotFound, InitializationMode::NotInitialization);
2532         }
2533         generator.emitProfileType(propertyName, var, m_lexpr->position(), JSTextPosition(-1, m_lexpr->position().offset + ident.length(), -1));
2534         return;
2535     }
2536     if (m_lexpr->isDotAccessorNode()) {
2537         DotAccessorNode* assignNode = static_cast<DotAccessorNode*>(m_lexpr);
2538         const Identifier& ident = assignNode->identifier();
2539         RefPtr<RegisterID> base = generator.emitNode(assignNode->base());
2540         generator.emitExpressionInfo(assignNode->divot(), assignNode->divotStart(), assignNode->divotEnd());
2541         if (assignNode->base()->isSuperNode()) {
2542             RefPtr<RegisterID> thisValue = generator.ensureThis();
2543             generator.emitPutById(base.get(), thisValue.get(), ident, propertyName);
2544         } else
2545             generator.emitPutById(base.get(), ident, propertyName);
2546         generator.emitProfileType(propertyName, assignNode->divotStart(), assignNode->divotEnd());
2547         return;
2548     }
2549     if (m_lexpr->isBracketAccessorNode()) {
2550         BracketAccessorNode* assignNode = static_cast<BracketAccessorNode*>(m_lexpr);
2551         RefPtr<RegisterID> base = generator.emitNode(assignNode->base());
2552         RefPtr<RegisterID> subscript = generator.emitNode(assignNode->subscript());
2553         generator.emitExpressionInfo(assignNode->divot(), assignNode->divotStart(), assignNode->divotEnd());
2554         if (assignNode->base()->isSuperNode()) {
2555             RefPtr<RegisterID> thisValue = generator.ensureThis();
2556             generator.emitPutByVal(base.get(), thisValue.get(), subscript.get(), propertyName);
2557         } else
2558             generator.emitPutByVal(base.get(), subscript.get(), propertyName);
2559         generator.emitProfileType(propertyName, assignNode->divotStart(), assignNode->divotEnd());
2560         return;
2561     }
2562
2563     if (m_lexpr->isDestructuringNode()) {
2564         DestructuringAssignmentNode* assignNode = static_cast<DestructuringAssignmentNode*>(m_lexpr);
2565         auto binding = assignNode->bindings();
2566         if (!binding->isBindingNode()) {
2567             assignNode->bindings()->bindValue(generator, propertyName);
2568             return;
2569         }
2570
2571         auto simpleBinding = static_cast<BindingNode*>(binding);
2572         const Identifier& ident = simpleBinding->boundProperty();
2573         Variable var = generator.variable(ident);
2574         if (!var.local() || var.isSpecial()) {
2575             assignNode->bindings()->bindValue(generator, propertyName);
2576             return;
2577         }
2578         generator.emitMove(var.local(), propertyName);
2579         generator.emitProfileType(propertyName, var, simpleBinding->divotStart(), simpleBinding->divotEnd());
2580         return;
2581     }
2582
2583     RELEASE_ASSERT_NOT_REACHED();
2584 }
2585
2586 void ForInNode::emitMultiLoopBytecode(BytecodeGenerator& generator, RegisterID* dst)
2587 {
2588     if (!m_lexpr->isAssignmentLocation()) {
2589         emitThrowReferenceError(generator, ASCIILiteral("Left side of for-in statement is not a reference."));
2590         return;
2591     }
2592
2593     RefPtr<Label> end = generator.newLabel();
2594
2595     RegisterID* forLoopSymbolTable = nullptr;
2596     generator.pushLexicalScope(this, BytecodeGenerator::TDZCheckOptimization::Optimize, BytecodeGenerator::NestedScopeType::IsNested, &forLoopSymbolTable);
2597
2598     generator.emitDebugHook(WillExecuteStatement, firstLine(), startOffset(), lineStartOffset());
2599
2600     RefPtr<RegisterID> base = generator.newTemporary();
2601     RefPtr<RegisterID> length;
2602     RefPtr<RegisterID> enumerator;
2603     generator.emitNode(base.get(), m_expr);
2604     RefPtr<RegisterID> local = this->tryGetBoundLocal(generator);
2605     RefPtr<RegisterID> enumeratorIndex;
2606
2607     int profilerStartOffset = m_statement->startOffset();
2608     int profilerEndOffset = m_statement->endOffset() + (m_statement->isBlock() ? 1 : 0);
2609
2610     enumerator = generator.emitGetPropertyEnumerator(generator.newTemporary(), base.get());
2611
2612     // Indexed property loop.
2613     {
2614         LabelScopePtr scope = generator.newLabelScope(LabelScope::Loop);
2615         RefPtr<Label> loopStart = generator.newLabel();
2616         RefPtr<Label> loopEnd = generator.newLabel();
2617
2618         length = generator.emitGetEnumerableLength(generator.newTemporary(), enumerator.get());
2619         RefPtr<RegisterID> i = generator.emitLoad(generator.newTemporary(), jsNumber(0));
2620         RefPtr<RegisterID> propertyName = generator.newTemporary();
2621
2622         generator.emitLabel(loopStart.get());
2623         generator.emitLoopHint();
2624
2625         RefPtr<RegisterID> result = generator.emitEqualityOp(op_less, generator.newTemporary(), i.get(), length.get());
2626         generator.emitJumpIfFalse(result.get(), loopEnd.get());
2627         generator.emitHasIndexedProperty(result.get(), base.get(), i.get());
2628         generator.emitJumpIfFalse(result.get(), scope->continueTarget());
2629
2630         generator.emitToIndexString(propertyName.get(), i.get());
2631         this->emitLoopHeader(generator, propertyName.get());
2632
2633         generator.emitProfileControlFlow(profilerStartOffset);
2634
2635         generator.pushIndexedForInScope(local.get(), i.get());
2636         generator.emitNode(dst, m_statement);
2637         generator.popIndexedForInScope(local.get());
2638
2639         generator.emitProfileControlFlow(profilerEndOffset);
2640
2641         generator.emitLabel(scope->continueTarget());
2642         generator.prepareLexicalScopeForNextForLoopIteration(this, forLoopSymbolTable);
2643         generator.emitInc(i.get());
2644         generator.emitJump(loopStart.get());
2645
2646         generator.emitLabel(scope->breakTarget());
2647         generator.emitJump(end.get());
2648         generator.emitLabel(loopEnd.get());
2649     }
2650
2651     // Structure property loop.
2652     {
2653         LabelScopePtr scope = generator.newLabelScope(LabelScope::Loop);
2654         RefPtr<Label> loopStart = generator.newLabel();
2655         RefPtr<Label> loopEnd = generator.newLabel();
2656
2657         enumeratorIndex = generator.emitLoad(generator.newTemporary(), jsNumber(0));
2658         RefPtr<RegisterID> propertyName = generator.newTemporary();
2659         generator.emitEnumeratorStructurePropertyName(propertyName.get(), enumerator.get(), enumeratorIndex.get());
2660
2661         generator.emitLabel(loopStart.get());
2662         generator.emitLoopHint();
2663
2664         RefPtr<RegisterID> result = generator.emitUnaryOp(op_eq_null, generator.newTemporary(), propertyName.get());
2665         generator.emitJumpIfTrue(result.get(), loopEnd.get());
2666         generator.emitHasStructureProperty(result.get(), base.get(), propertyName.get(), enumerator.get());
2667         generator.emitJumpIfFalse(result.get(), scope->continueTarget());
2668
2669         this->emitLoopHeader(generator, propertyName.get());
2670
2671         generator.emitProfileControlFlow(profilerStartOffset);
2672
2673         generator.pushStructureForInScope(local.get(), enumeratorIndex.get(), propertyName.get(), enumerator.get());
2674         generator.emitNode(dst, m_statement);
2675         generator.popStructureForInScope(local.get());
2676
2677         generator.emitProfileControlFlow(profilerEndOffset);
2678
2679         generator.emitLabel(scope->continueTarget());
2680         generator.prepareLexicalScopeForNextForLoopIteration(this, forLoopSymbolTable);
2681         generator.emitInc(enumeratorIndex.get());
2682         generator.emitEnumeratorStructurePropertyName(propertyName.get(), enumerator.get(), enumeratorIndex.get());
2683         generator.emitJump(loopStart.get());
2684         
2685         generator.emitLabel(scope->breakTarget());
2686         generator.emitJump(end.get());
2687         generator.emitLabel(loopEnd.get());
2688     }
2689
2690     // Generic property loop.
2691     {
2692         LabelScopePtr scope = generator.newLabelScope(LabelScope::Loop);
2693         RefPtr<Label> loopStart = generator.newLabel();
2694         RefPtr<Label> loopEnd = generator.newLabel();
2695
2696         RefPtr<RegisterID> propertyName = generator.newTemporary();
2697
2698         generator.emitEnumeratorGenericPropertyName(propertyName.get(), enumerator.get(), enumeratorIndex.get());
2699
2700         generator.emitLabel(loopStart.get());
2701         generator.emitLoopHint();
2702
2703         RefPtr<RegisterID> result = generator.emitUnaryOp(op_eq_null, generator.newTemporary(), propertyName.get());
2704         generator.emitJumpIfTrue(result.get(), loopEnd.get());
2705
2706         generator.emitHasGenericProperty(result.get(), base.get(), propertyName.get());
2707         generator.emitJumpIfFalse(result.get(), scope->continueTarget());
2708
2709         this->emitLoopHeader(generator, propertyName.get());
2710
2711         generator.emitProfileControlFlow(profilerStartOffset);
2712
2713         generator.emitNode(dst, m_statement);
2714
2715         generator.emitLabel(scope->continueTarget());
2716         generator.prepareLexicalScopeForNextForLoopIteration(this, forLoopSymbolTable);
2717         generator.emitInc(enumeratorIndex.get());
2718         generator.emitEnumeratorGenericPropertyName(propertyName.get(), enumerator.get(), enumeratorIndex.get());
2719         generator.emitJump(loopStart.get());
2720
2721         generator.emitLabel(scope->breakTarget());
2722         generator.emitJump(end.get());
2723         generator.emitLabel(loopEnd.get());
2724     }
2725
2726     generator.emitDebugHook(WillExecuteStatement, firstLine(), startOffset(), lineStartOffset());
2727     generator.emitLabel(end.get());
2728     generator.popLexicalScope(this);
2729     generator.emitProfileControlFlow(profilerEndOffset);
2730 }
2731
2732 void ForInNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2733 {
2734     this->emitMultiLoopBytecode(generator, dst);
2735 }
2736
2737 // ------------------------------ ForOfNode ------------------------------------
2738 void ForOfNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2739 {
2740     if (!m_lexpr->isAssignmentLocation()) {
2741         emitThrowReferenceError(generator, ASCIILiteral("Left side of for-of statement is not a reference."));
2742         return;
2743     }
2744
2745     RegisterID* forLoopSymbolTable = nullptr;
2746     generator.pushLexicalScope(this, BytecodeGenerator::TDZCheckOptimization::Optimize, BytecodeGenerator::NestedScopeType::IsNested, &forLoopSymbolTable);
2747     generator.emitDebugHook(WillExecuteStatement, firstLine(), startOffset(), lineStartOffset());
2748     auto extractor = [this, dst](BytecodeGenerator& generator, RegisterID* value)
2749     {
2750         if (m_lexpr->isResolveNode()) {
2751             const Identifier& ident = static_cast<ResolveNode*>(m_lexpr)->identifier();
2752             Variable var = generator.variable(ident);
2753             if (RegisterID* local = var.local())
2754                 generator.emitMove(local, value);
2755             else {
2756                 if (generator.isStrictMode())
2757                     generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
2758                 RegisterID* scope = generator.emitResolveScope(nullptr, var);
2759                 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
2760                 generator.emitPutToScope(scope, var, value, generator.isStrictMode() ? ThrowIfNotFound : DoNotThrowIfNotFound, InitializationMode::NotInitialization);
2761             }
2762             generator.emitProfileType(value, var, m_lexpr->position(), JSTextPosition(-1, m_lexpr->position().offset + ident.length(), -1));
2763         } else if (m_lexpr->isDotAccessorNode()) {
2764             DotAccessorNode* assignNode = static_cast<DotAccessorNode*>(m_lexpr);
2765             const Identifier& ident = assignNode->identifier();
2766             RefPtr<RegisterID> base = generator.emitNode(assignNode->base());
2767             
2768             generator.emitExpressionInfo(assignNode->divot(), assignNode->divotStart(), assignNode->divotEnd());
2769             if (assignNode->base()->isSuperNode()) {
2770                 RefPtr<RegisterID> thisValue = generator.ensureThis();
2771                 generator.emitPutById(base.get(), thisValue.get(), ident, value);
2772             } else
2773                 generator.emitPutById(base.get(), ident, value);
2774             generator.emitProfileType(value, assignNode->divotStart(), assignNode->divotEnd());
2775         } else if (m_lexpr->isBracketAccessorNode()) {
2776             BracketAccessorNode* assignNode = static_cast<BracketAccessorNode*>(m_lexpr);
2777             RefPtr<RegisterID> base = generator.emitNode(assignNode->base());
2778             RegisterID* subscript = generator.emitNode(assignNode->subscript());
2779             
2780             generator.emitExpressionInfo(assignNode->divot(), assignNode->divotStart(), assignNode->divotEnd());
2781             if (assignNode->base()->isSuperNode()) {
2782                 RefPtr<RegisterID> thisValue = generator.ensureThis();
2783                 generator.emitPutByVal(base.get(), thisValue.get(), subscript, value);
2784             } else
2785                 generator.emitPutByVal(base.get(), subscript, value);
2786             generator.emitProfileType(value, assignNode->divotStart(), assignNode->divotEnd());
2787         } else {
2788             ASSERT(m_lexpr->isDestructuringNode());
2789             DestructuringAssignmentNode* assignNode = static_cast<DestructuringAssignmentNode*>(m_lexpr);
2790             assignNode->bindings()->bindValue(generator, value);
2791         }
2792         generator.emitProfileControlFlow(m_statement->startOffset());
2793         generator.emitNode(dst, m_statement);
2794     };
2795     generator.emitEnumeration(this, m_expr, extractor, this, forLoopSymbolTable);
2796     generator.popLexicalScope(this);
2797     generator.emitProfileControlFlow(m_statement->endOffset() + (m_statement->isBlock() ? 1 : 0));
2798 }
2799
2800 // ------------------------------ ContinueNode ---------------------------------
2801
2802 Label* ContinueNode::trivialTarget(BytecodeGenerator& generator)
2803 {
2804     if (generator.shouldEmitDebugHooks())
2805         return 0;
2806
2807     LabelScopePtr scope = generator.continueTarget(m_ident);
2808     ASSERT(scope);
2809
2810     if (generator.labelScopeDepth() != scope->scopeDepth())
2811         return 0;
2812
2813     return scope->continueTarget();
2814 }
2815
2816 void ContinueNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
2817 {
2818     generator.emitDebugHook(WillExecuteStatement, firstLine(), startOffset(), lineStartOffset());
2819     
2820     LabelScopePtr scope = generator.continueTarget(m_ident);
2821     ASSERT(scope);
2822
2823     generator.emitPopScopes(generator.scopeRegister(), scope->scopeDepth());
2824     generator.emitJump(scope->continueTarget());
2825
2826     generator.emitProfileControlFlow(endOffset());
2827 }
2828
2829 // ------------------------------ BreakNode ------------------------------------
2830
2831 Label* BreakNode::trivialTarget(BytecodeGenerator& generator)
2832 {
2833     if (generator.shouldEmitDebugHooks())
2834         return 0;
2835
2836     LabelScopePtr scope = generator.breakTarget(m_ident);
2837     ASSERT(scope);
2838
2839     if (generator.labelScopeDepth() != scope->scopeDepth())
2840         return 0;
2841
2842     return scope->breakTarget();
2843 }
2844
2845 void BreakNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
2846 {
2847     generator.emitDebugHook(WillExecuteStatement, firstLine(), startOffset(), lineStartOffset());
2848     
2849     LabelScopePtr scope = generator.breakTarget(m_ident);
2850     ASSERT(scope);
2851
2852     generator.emitPopScopes(generator.scopeRegister(), scope->scopeDepth());
2853     generator.emitJump(scope->breakTarget());
2854
2855     generator.emitProfileControlFlow(endOffset());
2856 }
2857
2858 // ------------------------------ ReturnNode -----------------------------------
2859
2860 void ReturnNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2861 {
2862     generator.emitDebugHook(WillExecuteStatement, firstLine(), startOffset(), lineStartOffset());
2863     ASSERT(generator.codeType() == FunctionCode);
2864
2865     if (dst == generator.ignoredResult())
2866         dst = 0;
2867
2868     RefPtr<RegisterID> returnRegister = m_value ? generator.emitNodeInTailPosition(dst, m_value) : generator.emitLoad(dst, jsUndefined());
2869
2870     generator.emitProfileType(returnRegister.get(), ProfileTypeBytecodeFunctionReturnStatement, divotStart(), divotEnd());
2871     if (generator.isInFinallyBlock()) {
2872         returnRegister = generator.emitMove(generator.newTemporary(), returnRegister.get());
2873         generator.emitPopScopes(generator.scopeRegister(), 0);
2874     }
2875
2876     generator.emitDebugHook(WillLeaveCallFrame, lastLine(), startOffset(), lineStartOffset());
2877     generator.emitReturn(returnRegister.get());
2878     generator.emitProfileControlFlow(endOffset()); 
2879     // Emitting an unreachable return here is needed in case this op_profile_control_flow is the 
2880     // last opcode in a CodeBlock because a CodeBlock's instructions must end with a terminal opcode.
2881     if (generator.vm()->controlFlowProfiler())
2882         generator.emitReturn(generator.emitLoad(nullptr, jsUndefined()));
2883 }
2884
2885 // ------------------------------ WithNode -------------------------------------
2886
2887 void WithNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2888 {
2889     generator.emitDebugHook(WillExecuteStatement, firstLine(), startOffset(), lineStartOffset());
2890
2891     RefPtr<RegisterID> scope = generator.emitNode(m_expr);
2892     generator.emitExpressionInfo(m_divot, m_divot - m_expressionLength, m_divot);
2893     generator.emitPushWithScope(scope.get());
2894     generator.emitNodeInTailPosition(dst, m_statement);
2895     generator.emitPopWithScope();
2896 }
2897
2898 // ------------------------------ CaseClauseNode --------------------------------
2899
2900 inline void CaseClauseNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2901 {
2902     generator.emitProfileControlFlow(m_startOffset);
2903     if (!m_statements)
2904         return;
2905     m_statements->emitBytecode(generator, dst);
2906 }
2907
2908 // ------------------------------ CaseBlockNode --------------------------------
2909
2910 enum SwitchKind { 
2911     SwitchUnset = 0,
2912     SwitchNumber = 1, 
2913     SwitchString = 2, 
2914     SwitchNeither = 3 
2915 };
2916
2917 static void processClauseList(ClauseListNode* list, Vector<ExpressionNode*, 8>& literalVector, SwitchKind& typeForTable, bool& singleCharacterSwitch, int32_t& min_num, int32_t& max_num)
2918 {
2919     for (; list; list = list->getNext()) {
2920         ExpressionNode* clauseExpression = list->getClause()->expr();
2921         literalVector.append(clauseExpression);
2922         if (clauseExpression->isNumber()) {
2923             double value = static_cast<NumberNode*>(clauseExpression)->value();
2924             int32_t intVal = static_cast<int32_t>(value);
2925             if ((typeForTable & ~SwitchNumber) || (intVal != value)) {
2926                 typeForTable = SwitchNeither;
2927                 break;
2928             }
2929             if (intVal < min_num)
2930                 min_num = intVal;
2931             if (intVal > max_num)
2932                 max_num = intVal;
2933             typeForTable = SwitchNumber;
2934             continue;
2935         }
2936         if (clauseExpression->isString()) {
2937             if (typeForTable & ~SwitchString) {
2938                 typeForTable = SwitchNeither;
2939                 break;
2940             }
2941             const String& value = static_cast<StringNode*>(clauseExpression)->value().string();
2942             if (singleCharacterSwitch &= value.length() == 1) {
2943                 int32_t intVal = value[0];
2944                 if (intVal < min_num)
2945                     min_num = intVal;
2946                 if (intVal > max_num)
2947                     max_num = intVal;
2948             }
2949             typeForTable = SwitchString;
2950             continue;
2951         }
2952         typeForTable = SwitchNeither;
2953         break;        
2954     }
2955 }
2956
2957 static inline size_t length(ClauseListNode* list1, ClauseListNode* list2)
2958 {
2959     size_t length = 0;
2960     for (ClauseListNode* node = list1; node; node = node->getNext())
2961         ++length;
2962     for (ClauseListNode* node = list2; node; node = node->getNext())
2963         ++length;
2964     return length;
2965 }
2966
2967 SwitchInfo::SwitchType CaseBlockNode::tryTableSwitch(Vector<ExpressionNode*, 8>& literalVector, int32_t& min_num, int32_t& max_num)
2968 {
2969     if (length(m_list1, m_list2) < s_tableSwitchMinimum)
2970         return SwitchInfo::SwitchNone;
2971
2972     SwitchKind typeForTable = SwitchUnset;
2973     bool singleCharacterSwitch = true;
2974     
2975     processClauseList(m_list1, literalVector, typeForTable, singleCharacterSwitch, min_num, max_num);
2976     processClauseList(m_list2, literalVector, typeForTable, singleCharacterSwitch, min_num, max_num);
2977     
2978     if (typeForTable == SwitchUnset || typeForTable == SwitchNeither)
2979         return SwitchInfo::SwitchNone;
2980     
2981     if (typeForTable == SwitchNumber) {
2982         int32_t range = max_num - min_num;
2983         if (min_num <= max_num && range <= 1000 && (range / literalVector.size()) < 10)
2984             return SwitchInfo::SwitchImmediate;
2985         return SwitchInfo::SwitchNone;
2986     } 
2987     
2988     ASSERT(typeForTable == SwitchString);
2989     
2990     if (singleCharacterSwitch) {
2991         int32_t range = max_num - min_num;
2992         if (min_num <= max_num && range <= 1000 && (range / literalVector.size()) < 10)
2993             return SwitchInfo::SwitchCharacter;
2994     }
2995
2996     return SwitchInfo::SwitchString;
2997 }
2998
2999 void CaseBlockNode::emitBytecodeForBlock(BytecodeGenerator& generator, RegisterID* switchExpression, RegisterID* dst)
3000 {
3001     RefPtr<Label> defaultLabel;
3002     Vector<RefPtr<Label>, 8> labelVector;
3003     Vector<ExpressionNode*, 8> literalVector;
3004     int32_t min_num = std::numeric_limits<int32_t>::max();
3005     int32_t max_num = std::numeric_limits<int32_t>::min();
3006     SwitchInfo::SwitchType switchType = tryTableSwitch(literalVector, min_num, max_num);
3007
3008     if (switchType != SwitchInfo::SwitchNone) {
3009         // Prepare the various labels
3010         for (uint32_t i = 0; i < literalVector.size(); i++)
3011             labelVector.append(generator.newLabel());
3012         defaultLabel = generator.newLabel();
3013         generator.beginSwitch(switchExpression, switchType);
3014     } else {
3015         // Setup jumps
3016         for (ClauseListNode* list = m_list1; list; list = list->getNext()) {
3017             RefPtr<RegisterID> clauseVal = generator.newTemporary();
3018             generator.emitNode(clauseVal.get(), list->getClause()->expr());
3019             generator.emitBinaryOp(op_stricteq, clauseVal.get(), clauseVal.get(), switchExpression, OperandTypes());
3020             labelVector.append(generator.newLabel());
3021             generator.emitJumpIfTrue(clauseVal.get(), labelVector[labelVector.size() - 1].get());
3022         }
3023         
3024         for (ClauseListNode* list = m_list2; list; list = list->getNext()) {
3025             RefPtr<RegisterID> clauseVal = generator.newTemporary();
3026             generator.emitNode(clauseVal.get(), list->getClause()->expr());
3027             generator.emitBinaryOp(op_stricteq, clauseVal.get(), clauseVal.get(), switchExpression, OperandTypes());
3028             labelVector.append(generator.newLabel());
3029             generator.emitJumpIfTrue(clauseVal.get(), labelVector[labelVector.size() - 1].get());
3030         }
3031         defaultLabel = generator.newLabel();
3032         generator.emitJump(defaultLabel.get());
3033     }
3034
3035     size_t i = 0;
3036     for (ClauseListNode* list = m_list1; list; list = list->getNext()) {
3037         generator.emitLabel(labelVector[i++].get());
3038         list->getClause()->emitBytecode(generator, dst);
3039     }
3040
3041     if (m_defaultClause) {
3042         generator.emitLabel(defaultLabel.get());
3043         m_defaultClause->emitBytecode(generator, dst);
3044     }
3045
3046     for (ClauseListNode* list = m_list2; list; list = list->getNext()) {
3047         generator.emitLabel(labelVector[i++].get());
3048         list->getClause()->emitBytecode(generator, dst);
3049     }
3050     if (!m_defaultClause)
3051         generator.emitLabel(defaultLabel.get());
3052
3053     ASSERT(i == labelVector.size());
3054     if (switchType != SwitchInfo::SwitchNone) {
3055         ASSERT(labelVector.size() == literalVector.size());
3056         generator.endSwitch(labelVector.size(), labelVector.data(), literalVector.data(), defaultLabel.get(), min_num, max_num);
3057     }
3058 }
3059
3060 // ------------------------------ SwitchNode -----------------------------------
3061
3062 void SwitchNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
3063 {
3064     generator.emitDebugHook(WillExecuteStatement, firstLine(), startOffset(), lineStartOffset());
3065     
3066     LabelScopePtr scope = generator.newLabelScope(LabelScope::Switch);
3067
3068     RefPtr<RegisterID> r0 = generator.emitNode(m_expr);
3069
3070     generator.pushLexicalScope(this, BytecodeGenerator::TDZCheckOptimization::DoNotOptimize, BytecodeGenerator::NestedScopeType::IsNested);
3071     m_block->emitBytecodeForBlock(generator, r0.get(), dst);
3072     generator.popLexicalScope(this);
3073
3074     generator.emitLabel(scope->breakTarget());
3075     generator.emitProfileControlFlow(endOffset());
3076 }
3077
3078 // ------------------------------ LabelNode ------------------------------------
3079
3080 void LabelNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
3081 {
3082     generator.emitDebugHook(WillExecuteStatement, firstLine(), startOffset(), lineStartOffset());
3083
3084     ASSERT(!generator.breakTarget(m_name));
3085
3086     LabelScopePtr scope = generator.newLabelScope(LabelScope::NamedLabel, &m_name);
3087     generator.emitNodeInTailPosition(dst, m_statement);
3088
3089     generator.emitLabel(scope->breakTarget());
3090 }
3091
3092 // ------------------------------ ThrowNode ------------------------------------
3093
3094 void ThrowNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
3095 {
3096     generator.emitDebugHook(WillExecuteStatement, firstLine(), startOffset(), lineStartOffset());
3097
3098     if (dst == generator.ignoredResult())
3099         dst = 0;
3100     RefPtr<RegisterID> expr = generator.emitNode(m_expr);
3101     generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
3102     generator.emitThrow(expr.get());
3103
3104     generator.emitProfileControlFlow(endOffset()); 
3105 }
3106
3107 // ------------------------------ TryNode --------------------------------------
3108
3109 void TryNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
3110 {
3111     // NOTE: The catch and finally blocks must be labeled explicitly, so the
3112     // optimizer knows they may be jumped to from anywhere.
3113
3114     generator.emitDebugHook(WillExecuteStatement, firstLine(), startOffset(), lineStartOffset());
3115
3116     ASSERT(m_catchBlock || m_finallyBlock);
3117
3118     RefPtr<Label> tryStartLabel = generator.newLabel();
3119     generator.emitLabel(tryStartLabel.get());
3120     
3121     if (m_finallyBlock)
3122         generator.pushFinallyContext(m_finallyBlock);
3123     TryData* tryData = generator.pushTry(tryStartLabel.get());
3124
3125     generator.emitNode(dst, m_tryBlock);
3126
3127     if (m_catchBlock) {
3128         RefPtr<Label> catchEndLabel = generator.newLabel();
3129         
3130         // Normal path: jump over the catch block.
3131         generator.emitJump(catchEndLabel.get());
3132
3133         // Uncaught exception path: the catch block.
3134         RefPtr<Label> here = generator.emitLabel(generator.newLabel().get());
3135         RefPtr<RegisterID> exceptionRegister = generator.newTemporary();
3136         RefPtr<RegisterID> thrownValueRegister = generator.newTemporary();
3137         generator.popTryAndEmitCatch(tryData, exceptionRegister.get(), thrownValueRegister.get(), here.get(), HandlerType::Catch);
3138         
3139         if (m_finallyBlock) {
3140             // If the catch block throws an exception and we have a finally block, then the finally
3141             // block should "catch" that exception.
3142             tryData = generator.pushTry(here.get());
3143         }
3144
3145         generator.emitPushCatchScope(m_lexicalVariables);
3146         m_catchPattern->bindValue(generator, thrownValueRegister.get());
3147         generator.emitProfileControlFlow(m_tryBlock->endOffset() + 1);
3148         if (m_finallyBlock)
3149             generator.emitNode(dst, m_catchBlock);
3150         else
3151             generator.emitNodeInTailPosition(dst, m_catchBlock);
3152         generator.emitLoad(thrownValueRegister.get(), jsUndefined());
3153         generator.emitPopCatchScope(m_lexicalVariables);
3154         generator.emitLabel(catchEndLabel.get());
3155     }
3156
3157     if (m_finallyBlock) {
3158         RefPtr<Label> preFinallyLabel = generator.emitLabel(generator.newLabel().get());
3159         
3160         generator.popFinallyContext();
3161
3162         RefPtr<Label> finallyEndLabel = generator.newLabel();
3163
3164         int finallyStartOffset = m_catchBlock ? m_catchBlock->endOffset() + 1 : m_tryBlock->endOffset() + 1;
3165
3166         // Normal path: run the finally code, and jump to the end.
3167         generator.emitProfileControlFlow(finallyStartOffset);
3168         generator.emitNodeInTailPosition(dst, m_finallyBlock);
3169         generator.emitProfileControlFlow(m_finallyBlock->endOffset() + 1);
3170         generator.emitJump(finallyEndLabel.get());
3171
3172         // Uncaught exception path: invoke the finally block, then re-throw the exception.
3173         RefPtr<RegisterID> exceptionRegister = generator.newTemporary();
3174         RefPtr<RegisterID> thrownValueRegister = generator.newTemporary();
3175         generator.popTryAndEmitCatch(tryData, exceptionRegister.get(), thrownValueRegister.get(), preFinallyLabel.get(), HandlerType::Finally);
3176         generator.emitProfileControlFlow(finallyStartOffset);
3177         generator.emitNodeInTailPosition(dst, m_finallyBlock);
3178         generator.emitThrow(exceptionRegister.get());
3179
3180         generator.emitLabel(finallyEndLabel.get());
3181         generator.emitProfileControlFlow(m_finallyBlock->endOffset() + 1);
3182     } else
3183         generator.emitProfileControlFlow(m_catchBlock->endOffset() + 1);
3184
3185 }
3186
3187 // ------------------------------ ScopeNode -----------------------------
3188
3189 inline void ScopeNode::emitStatementsBytecode(BytecodeGenerator& generator, RegisterID* dst)
3190 {
3191     if (!m_statements)
3192         return;
3193     m_statements->emitBytecode(generator, dst);
3194 }
3195
3196 static void emitProgramNodeBytecode(BytecodeGenerator& generator, ScopeNode& scopeNode)
3197 {
3198     generator.emitDebugHook(WillExecuteProgram, scopeNode.startLine(), scopeNode.startStartOffset(), scopeNode.startLineStartOffset());
3199
3200     RefPtr<RegisterID> dstRegister = generator.newTemporary();
3201     generator.emitLoad(dstRegister.get(), jsUndefined());
3202     generator.emitProfileControlFlow(scopeNode.startStartOffset());
3203     scopeNode.emitStatementsBytecode(generator, dstRegister.get());
3204
3205     generator.emitDebugHook(DidExecuteProgram, scopeNode.lastLine(), scopeNode.startOffset(), scopeNode.lineStartOffset());
3206     generator.emitEnd(dstRegister.get());
3207 }
3208
3209 // ------------------------------ ProgramNode -----------------------------
3210
3211 void ProgramNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
3212 {
3213     emitProgramNodeBytecode(generator, *this);
3214 }
3215
3216 // ------------------------------ ModuleProgramNode --------------------
3217
3218 void ModuleProgramNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
3219 {
3220     emitProgramNodeBytecode(generator, *this);
3221 }
3222
3223 // ------------------------------ EvalNode -----------------------------
3224
3225 void EvalNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
3226 {
3227     generator.emitDebugHook(WillExecuteProgram, startLine(), startStartOffset(), startLineStartOffset());
3228
3229     RefPtr<RegisterID> dstRegister = generator.newTemporary();
3230     generator.emitLoad(dstRegister.get(), jsUndefined());
3231     emitStatementsBytecode(generator, dstRegister.get());
3232
3233     generator.emitDebugHook(DidExecuteProgram, lastLine(), startOffset(), lineStartOffset());
3234     generator.emitEnd(dstRegister.get());
3235 }
3236
3237 // ------------------------------ FunctionNode -----------------------------
3238
3239 void FunctionNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
3240 {
3241     if (generator.vm()->typeProfiler()) {
3242         for (size_t i = 0; i < m_parameters->size(); i++) {
3243             // Destructuring parameters are handled in destructuring nodes.
3244             if (!m_parameters->at(i).first->isBindingNode())
3245                 continue;
3246             BindingNode* parameter = static_cast<BindingNode*>(m_parameters->at(i).first);
3247             RegisterID reg(CallFrame::argumentOffset(i));
3248             generator.emitProfileType(&reg, ProfileTypeBytecodeFunctionArgument, parameter->divotStart(), parameter->divotEnd());
3249         }
3250     }
3251
3252     generator.emitProfileControlFlow(startStartOffset());
3253     generator.emitDebugHook(DidEnterCallFrame, startLine(), startStartOffset(), startLineStartOffset());
3254
3255     switch (generator.parseMode()) {
3256     case SourceParseMode::GeneratorWrapperFunctionMode: {
3257         StatementNode* singleStatement = this->singleStatement();
3258         ASSERT(singleStatement->isExprStatement());
3259         ExprStatementNode* exprStatement = static_cast<ExprStatementNode*>(singleStatement);
3260         ExpressionNode* expr = exprStatement->expr();
3261         ASSERT(expr->isFuncExprNode());
3262         FuncExprNode* funcExpr = static_cast<FuncExprNode*>(expr);
3263
3264         RefPtr<RegisterID> next = generator.newTemporary();
3265         generator.emitNode(next.get(), funcExpr);
3266
3267         if (generator.superBinding() == SuperBinding::Needed) {
3268             RefPtr<RegisterID> homeObject = emitHomeObjectForCallee(generator);
3269             emitPutHomeObject(generator, next.get(), homeObject.get());
3270         }
3271
3272         // FIXME: Currently, we just create an object and store generator related fields as its properties for ease.
3273         // But to make it efficient, we will introduce JSGenerator class, add opcode new_generator and use its C++ fields instead of these private properties.
3274         // https://bugs.webkit.org/show_bug.cgi?id=151545
3275
3276         generator.emitDirectPutById(generator.generatorRegister(), generator.propertyNames().generatorNextPrivateName, next.get(), PropertyNode::KnownDirect);
3277
3278         generator.emitDirectPutById(generator.generatorRegister(), generator.propertyNames().generatorThisPrivateName, generator.thisRegister(), PropertyNode::KnownDirect);
3279
3280         RegisterID* initialState = generator.emitLoad(nullptr, jsNumber(0));
3281         generator.emitDirectPutById(generator.generatorRegister(), generator.propertyNames().generatorStatePrivateName, initialState, PropertyNode::KnownDirect);
3282
3283         generator.emitDirectPutById(generator.generatorRegister(), generator.propertyNames().generatorFramePrivateName, generator.emitLoad(nullptr, jsNull()), PropertyNode::KnownDirect);
3284
3285         ASSERT(startOffset() >= lineStartOffset());
3286         generator.emitDebugHook(WillLeaveCallFrame, lastLine(), startOffset(), lineStartOffset());
3287         generator.emitReturn(generator.generatorRegister());
3288         break;
3289     }
3290
3291     case SourceParseMode::GeneratorBodyMode: {
3292         RefPtr<Label> generatorBodyLabel = generator.newLabel();
3293         {
3294             RefPtr<RegisterID> condition = generator.newTemporary();
3295             generator.emitEqualityOp(op_stricteq, condition.get(), generator.generatorResumeModeRegister(), generator.emitLoad(nullptr, jsNumber(static_cast<int32_t>(JSGeneratorFunction::GeneratorResumeMode::NormalMode))));
3296             generator.emitJumpIfTrue(condition.get(), generatorBodyLabel.get());
3297
3298             RefPtr<Label> throwLabel = generator.newLabel();
3299             generator.emitEqualityOp(op_stricteq, condition.get(), generator.generatorResumeModeRegister(), generator.emitLoad(nullptr, jsNumber(static_cast<int32_t>(JSGeneratorFunction::GeneratorResumeMode::ThrowMode))));
3300             generator.emitJumpIfTrue(condition.get(), throwLabel.get());
3301
3302             generator.emitReturn(generator.generatorValueRegister());
3303
3304             generator.emitLabel(throwLabel.get());
3305             generator.emitThrow(generator.generatorValueRegister());
3306         }
3307
3308         generator.emitLabel(generatorBodyLabel.get());
3309
3310         emitStatementsBytecode(generator, generator.ignoredResult());
3311
3312         RefPtr<Label> done = generator.newLabel();
3313         generator.emitLabel(done.get());
3314         generator.emitReturn(generator.emitLoad(nullptr, jsUndefined()));
3315         generator.endGenerator(done.get());
3316         break;
3317     }
3318
3319     default: {
3320         emitStatementsBytecode(generator, generator.ignoredResult());
3321
3322         StatementNode* singleStatement = this->singleStatement();
3323         ReturnNode* returnNode = 0;
3324
3325         // Check for a return statement at the end of a function composed of a single block.
3326         if (singleStatement && singleStatement->isBlock()) {
3327             StatementNode* lastStatementInBlock = static_cast<BlockNode*>(singleStatement)->lastStatement();
3328             if (lastStatementInBlock && lastStatementInBlock->isReturnNode())
3329                 returnNode = static_cast<ReturnNode*>(lastStatementInBlock);
3330         }
3331
3332         // If there is no return we must automatically insert one.
3333         if (!returnNode) {
3334             if (generator.constructorKind() == ConstructorKind::Derived && generator.needsToUpdateArrowFunctionContext() && generator.isSuperCallUsedInInnerArrowFunction())
3335                 generator.emitLoadThisFromArrowFunctionLexicalEnvironment(); // Arrow function can invoke 'super' in constructor and before leave constructor we need load 'this' from lexical arrow function environment
3336             
3337             RegisterID* r0 = generator.isConstructor() ? generator.thisRegister() : generator.emitLoad(0, jsUndefined());
3338             generator.emitProfileType(r0, ProfileTypeBytecodeFunctionReturnStatement); // Do not emit expression info for this profile because it's not in the user's source code.
3339             ASSERT(startOffset() >= lineStartOffset());
3340             generator.emitDebugHook(WillLeaveCallFrame, lastLine(), startOffset(), lineStartOffset());
3341             generator.emitReturn(r0);
3342             return;
3343         }
3344         break;
3345     }
3346     }
3347 }
3348
3349 // ------------------------------ FuncDeclNode ---------------------------------
3350
3351 void FuncDeclNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
3352 {
3353     generator.hoistSloppyModeFunctionIfNecessary(metadata()->ident());
3354 }
3355
3356 // ------------------------------ FuncExprNode ---------------------------------
3357
3358 RegisterID* FuncExprNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
3359 {
3360     return generator.emitNewFunctionExpression(generator.finalDestination(dst), this);
3361 }
3362
3363 // ------------------------------ ArrowFuncExprNode ---------------------------------
3364
3365 RegisterID* ArrowFuncExprNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
3366 {
3367     return generator.emitNewArrowFunctionExpression(generator.finalDestination(dst), this);
3368 }
3369
3370 // ------------------------------ MethodDefinitionNode ---------------------------------
3371
3372 RegisterID* MethodDefinitionNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
3373 {
3374     return generator.emitNewMethodDefinition(generator.finalDestination(dst), this);
3375 }
3376
3377 // ------------------------------ YieldExprNode --------------------------------
3378
3379 RegisterID* YieldExprNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
3380 {
3381     if (!delegate()) {
3382         RefPtr<RegisterID> arg = nullptr;
3383         if (argument()) {
3384             arg = generator.newTemporary();
3385             generator.emitNode(arg.get(), argument());
3386         } else
3387             arg = generator.emitLoad(nullptr, jsUndefined());
3388         RefPtr<RegisterID> value = generator.emitYield(arg.get());
3389         if (dst == generator.ignoredResult())
3390             return nullptr;
3391         return generator.emitMove(generator.finalDestination(dst), value.get());
3392     }
3393     RefPtr<RegisterID> arg = generator.newTemporary();
3394     generator.emitNode(arg.get(), argument());
3395     RefPtr<RegisterID> value = generator.emitDelegateYield(arg.get(), this);
3396     if (dst == generator.ignoredResult())
3397         return nullptr;
3398     return generator.emitMove(generator.finalDestination(dst), value.get());
3399 }
3400
3401 // ------------------------------ ClassDeclNode ---------------------------------
3402
3403 void ClassDeclNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
3404 {
3405     generator.emitNode(dst, m_classDeclaration);
3406 }
3407
3408 // ------------------------------ ClassExprNode ---------------------------------
3409
3410 RegisterID* ClassExprNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
3411 {
3412     if (!m_name.isNull())
3413         generator.pushLexicalScope(this, BytecodeGenerator::TDZCheckOptimization::Optimize, BytecodeGenerator::NestedScopeType::IsNested);
3414
3415     RefPtr<RegisterID> superclass;
3416     if (m_classHeritage) {
3417         superclass = generator.newTemporary();
3418         generator.emitNode(superclass.get(), m_classHeritage);
3419     }
3420
3421     RefPtr<RegisterID> constructor;
3422
3423     // FIXME: Make the prototype non-configurable & non-writable.
3424     if (m_constructorExpression) {
3425         ASSERT(m_constructorExpression->isFuncExprNode());
3426         FunctionMetadataNode* metadata = static_cast<FuncExprNode*>(m_constructorExpression)->metadata();
3427         metadata->setEcmaName(ecmaName());
3428         metadata->setClassSource(m_classSource);
3429         constructor = generator.emitNode(dst, m_constructorExpression);
3430     } else {
3431         constructor = generator.emitNewDefaultConstructor(generator.finalDestination(dst),
3432             m_classHeritage ? ConstructorKind::Derived : ConstructorKind::Base,
3433             m_name, ecmaName(), m_classSource);
3434     }
3435
3436     const auto& propertyNames = generator.propertyNames();
3437     RefPtr<RegisterID> prototype = generator.emitNewObject(generator.newTemporary());
3438
3439     if (superclass) {
3440         RefPtr<RegisterID> protoParent = generator.newTemporary();
3441         generator.emitLoad(protoParent.get(), jsNull());
3442
3443         RefPtr<RegisterID> tempRegister = generator.newTemporary();
3444
3445         // FIXME: Throw TypeError if it's a generator function.
3446         RefPtr<Label> superclassIsUndefinedLabel = generator.newLabel();
3447         generator.emitJumpIfTrue(generator.emitIsUndefined(tempRegister.get(), superclass.get()), superclassIsUndefinedLabel.get());
3448
3449         RefPtr<Label> superclassIsNullLabel = generator.newLabel();
3450         generator.emitJumpIfTrue(generator.emitUnaryOp(op_eq_null, tempRegister.get(), superclass.get()), superclassIsNullLabel.get());
3451
3452         RefPtr<Label> superclassIsObjectLabel = generator.newLabel();
3453         generator.emitJumpIfTrue(generator.emitIsObject(tempRegister.get(), superclass.get()), superclassIsObjectLabel.get());
3454         generator.emitLabel(superclassIsUndefinedLabel.get());
3455         generator.emitThrowTypeError(ASCIILiteral("The superclass is not an object."));
3456         generator.emitLabel(superclassIsObjectLabel.get());
3457         generator.emitGetById(protoParent.get(), superclass.get(), generator.propertyNames().prototype);
3458
3459         RefPtr<Label> protoParentIsObjectOrNullLabel = generator.newLabel();
3460         generator.emitJumpIfTrue(generator.emitUnaryOp(op_is_object_or_null, tempRegister.get(), protoParent.get()), protoParentIsObjectOrNullLabel.get());
3461         generator.emitJumpIfTrue(generator.emitUnaryOp(op_is_function, tempRegister.get(), protoParent.get()), protoParentIsObjectOrNullLabel.get());
3462         generator.emitThrowTypeError(ASCIILiteral("The value of the superclass's prototype property is not an object."));
3463         generator.emitLabel(protoParentIsObjectOrNullLabel.get());
3464
3465         generator.emitDirectPutById(constructor.get(), generator.propertyNames().underscoreProto, superclass.get(), PropertyNode::Unknown);
3466         generator.emitLabel(superclassIsNullLabel.get());
3467         generator.emitDirectPutById(prototype.get(), generator.propertyNames().underscoreProto, protoParent.get(), PropertyNode::Unknown);
3468
3469         emitPutHomeObject(generator, constructor.get(), prototype.get());
3470     }
3471
3472     RefPtr<RegisterID> constructorNameRegister = generator.emitLoad(generator.newTemporary(), propertyNames.constructor);
3473     generator.emitCallDefineProperty(prototype.get(), constructorNameRegister.get(), constructor.get(), nullptr, nullptr,
3474         BytecodeGenerator::PropertyConfigurable | BytecodeGenerator::PropertyWritable, m_position);
3475
3476     RefPtr<RegisterID> prototypeNameRegister = generator.emitLoad(generator.newTemporary(), propertyNames.prototype);
3477     generator.emitCallDefineProperty(constructor.get(), prototypeNameRegister.get(), prototype.get(), nullptr, nullptr, 0, m_position);
3478
3479     if (m_staticMethods)
3480         generator.emitNode(constructor.get(), m_staticMethods);
3481
3482     if (m_instanceMethods)
3483         generator.emitNode(prototype.get(), m_instanceMethods);
3484
3485     if (!m_name.isNull()) {
3486         Variable classNameVar = generator.variable(m_name);
3487         RELEASE_ASSERT(classNameVar.isResolved());
3488         RefPtr<RegisterID> scope = generator.emitResolveScope(nullptr, classNameVar);
3489         generator.emitPutToScope(scope.get(), classNameVar, constructor.get(), ThrowIfNotFound, InitializationMode::Initialization);
3490         generator.popLexicalScope(this);
3491     }
3492
3493     return generator.moveToDestinationIfNeeded(dst, constructor.get());
3494 }
3495
3496 // ------------------------------ ImportDeclarationNode -----------------------
3497
3498 void ImportDeclarationNode::emitBytecode(BytecodeGenerator&, RegisterID*)
3499 {
3500     // Do nothing at runtime.
3501 }
3502
3503 // ------------------------------ ExportAllDeclarationNode --------------------
3504
3505 void ExportAllDeclarationNode::emitBytecode(BytecodeGenerator&, RegisterID*)
3506 {
3507     // Do nothing at runtime.
3508 }
3509
3510 // ------------------------------ ExportDefaultDeclarationNode ----------------
3511
3512 void ExportDefaultDeclarationNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
3513 {
3514     ASSERT(m_declaration);
3515     generator.emitNode(dst, m_declaration);
3516 }
3517
3518 // ------------------------------ ExportLocalDeclarationNode ------------------
3519
3520 void ExportLocalDeclarationNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
3521 {
3522     ASSERT(m_declaration);
3523     generator.emitNode(dst, m_declaration);
3524 }
3525
3526 // ------------------------------ ExportNamedDeclarationNode ------------------
3527
3528 void ExportNamedDeclarationNode::emitBytecode(BytecodeGenerator&, RegisterID*)
3529 {
3530     // Do nothing at runtime.
3531 }
3532
3533 // ------------------------------ DestructuringAssignmentNode -----------------
3534 RegisterID* DestructuringAssignmentNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
3535 {
3536     if (RegisterID* result = m_bindings->emitDirectBinding(generator, dst, m_initializer))
3537         return result;
3538     RefPtr<RegisterID> initializer = generator.tempDestination(dst);
3539     generator.emitNode(initializer.get(), m_initializer);
3540     m_bindings->bindValue(generator, initializer.get());
3541     return generator.moveToDestinationIfNeeded(dst, initializer.get());
3542 }
3543
3544 static void assignDefaultValueIfUndefined(BytecodeGenerator& generator, RegisterID* maybeUndefined, ExpressionNode* defaultValue)
3545 {
3546     ASSERT(defaultValue);
3547     RefPtr<Label> isNotUndefined = generator.newLabel();
3548     generator.emitJumpIfFalse(generator.emitIsUndefined(generator.newTemporary(), maybeUndefined), isNotUndefined.get());
3549     generator.emitNode(maybeUndefined, defaultValue);
3550     generator.emitLabel(isNotUndefined.get());
3551 }
3552
3553 void ArrayPatternNode::bindValue(BytecodeGenerator& generator, RegisterID* rhs) const
3554 {
3555     RefPtr<RegisterID> iterator = generator.newTemporary();
3556     {
3557         generator.emitGetById(iterator.get(), rhs, generator.propertyNames().iteratorSymbol);
3558         CallArguments args(generator, nullptr);
3559         generator.emitMove(args.thisRegister(), rhs);
3560         generator.emitCall(iterator.get(), iterator.get(), NoExpectedFunction, args, divot(), divotStart(), divotEnd());
3561     }
3562
3563     if (m_targetPatterns.isEmpty()) {
3564         generator.emitIteratorClose(iterator.get(), this);
3565         return;
3566     }
3567
3568     RefPtr<RegisterID> done;
3569     for (auto& target : m_targetPatterns) {
3570         switch (target.bindingType) {
3571         case BindingType::Elision:
3572         case BindingType::Element: {
3573             RefPtr<Label> iterationSkipped = generator.newLabel();
3574             if (!done)
3575                 done = generator.newTemporary();
3576             else
3577                 generator.emitJumpIfTrue(done.get(), iterationSkipped.get());
3578
3579             RefPtr<RegisterID> value = generator.newTemporary();
3580             generator.emitIteratorNext(value.get(), iterator.get(), this);
3581             generator.emitGetById(done.get(), value.get(), generator.propertyNames().done);
3582             generator.emitJumpIfTrue(done.get(), iterationSkipped.get());
3583             generator.emitGetById(value.get(), value.get(), generator.propertyNames().value);
3584
3585             {
3586                 RefPtr<Label> valueIsSet = generator.newLabel();
3587                 generator.emitJump(valueIsSet.get());
3588                 generator.emitLabel(iterationSkipped.get());
3589                 generator.emitLoad(value.get(), jsUndefined());
3590                 generator.emitLabel(valueIsSet.get());
3591             }
3592
3593             if (target.bindingType == BindingType::Element) {
3594                 if (target.defaultValue)
3595                     assignDefaultValueIfUndefined(generator, value.get(), target.defaultValue);
3596                 target.pattern->bindValue(generator, value.get());
3597             }
3598             break;
3599         }
3600
3601         case BindingType::RestElement: {
3602             RefPtr<RegisterID> array = generator.emitNewArray(generator.newTemporary(), 0, 0);
3603
3604             RefPtr<Label> iterationDone = generator.newLabel();
3605             if (!done)
3606                 done = generator.newTemporary();
3607             else
3608                 generator.emitJumpIfTrue(done.get(), iterationDone.get());
3609
3610             RefPtr<RegisterID> index = generator.newTemporary();
3611             generator.emitLoad(index.get(), jsNumber(0));
3612             RefPtr<Label> loopStart = generator.newLabel();
3613             generator.emitLabel(loopStart.get());
3614
3615             RefPtr<RegisterID> value = generator.newTemporary();
3616             generator.emitIteratorNext(value.get(), iterator.get(), this);
3617             generator.emitGetById(done.get(), value.get(), generator.propertyNames().done);
3618             generator.emitJumpIfTrue(done.get(), iterationDone.get());
3619             generator.emitGetById(value.get(), value.get(), generator.propertyNames().value);
3620
3621             generator.emitDirectPutByVal(array.get(), index.get(), value.get());
3622             generator.emitInc(index.get());
3623             generator.emitJump(loopStart.get());
3624
3625             generator.emitLabel(iterationDone.get());
3626             target.pattern->bindValue(generator, array.get());
3627             break;
3628         }
3629         }
3630     }
3631
3632     RefPtr<Label> iteratorClosed = generator.newLabel();
3633     generator.emitJumpIfTrue(done.get(), iteratorClosed.get());
3634     generator.emitIteratorClose(iterator.get(), this);
3635     generator.emitLabel(iteratorClosed.get());
3636 }
3637
3638 RegisterID* ArrayPatternNode::emitDirectBinding(BytecodeGenerator& generator, RegisterID* dst, ExpressionNode* rhs)
3639 {
3640     if (!rhs->isSimpleArray())
3641         return nullptr;
3642
3643     ElementNode* elementNodes = static_cast<ArrayNode*>(rhs)->elements();
3644     Vector<ExpressionNode*> elements;
3645     for (; elementNodes; elementNodes = elementNodes->next()) {
3646         ExpressionNode* value = elementNodes->value();
3647         if (value->isSpreadExpression())
3648             return nullptr;
3649         elements.append(value);
3650     }
3651
3652     RefPtr<RegisterID> resultRegister;
3653     if (dst && dst != generator.ignoredResult())
3654         resultRegister = generator.emitNewArray(generator.newTemporary(), 0, 0);
3655     if (m_targetPatterns.size() != elements.size())
3656         return nullptr;
3657     Vector<RefPtr<RegisterID>> registers;
3658     registers.reserveCapacity(m_targetPatterns.size());
3659     for (size_t i = 0; i < m_targetPatterns.size(); i++) {
3660         registers.uncheckedAppend(generator.newTemporary());
3661         generator.emitNode(registers.last().get(), elements[i]);
3662         if (m_targetPatterns[i].defaultValue)
3663             assignDefaultValueIfUndefined(generator, registers.last().get(), m_targetPatterns[i].defaultValue);
3664         if (resultRegister)
3665             generator.emitPutByIndex(resultRegister.get(), i, registers.last().get());
3666     }
3667     
3668     for (size_t i = 0; i < m_targetPatterns.size(); i++) {
3669         if (m_targetPatterns[i].pattern)
3670             m_targetPatterns[i].pattern->bindValue(generator, registers[i].get());
3671     }
3672     if (resultRegister)
3673         return generator.moveToDestinationIfNeeded(dst, resultRegister.get());
3674     return generator.emitLoad(generator.finalDestination(dst), jsUndefined());
3675 }
3676
3677 void ArrayPatternNode::toString(StringBuilder& builder) const
3678 {
3679     builder.append('[');
3680     for (size_t i = 0; i < m_targetPatterns.size(); i++) {
3681         const auto& target = m_targetPatterns[i];
3682
3683         switch (target.bindingType) {
3684         case BindingType::Elision:
3685             builder.append(',');
3686             break;
3687
3688         case BindingType::Element:
3689             target.pattern->toString(builder);
3690             if (i < m_targetPatterns.size() - 1)
3691                 builder.append(',');
3692             break;
3693
3694         case BindingType::RestElement:
3695             builder.append("...");
3696             target.pattern->toString(builder);
3697             break;
3698         }
3699     }
3700     builder.append(']');
3701 }
3702
3703 void ArrayPatternNode::collectBoundIdentifiers(Vector<Identifier>& identifiers) const
3704 {
3705     for (size_t i = 0; i < m_targetPatterns.size(); i++) {
3706         if (DestructuringPatternNode* node = m_targetPatterns[i].pattern)
3707             node->collectBoundIdentifiers(identifiers);
3708     }
3709 }
3710
3711 void ObjectPatternNode::toString(StringBuilder& builder) const
3712 {
3713     builder.append('{');
3714     for (size_t i = 0; i < m_targetPatterns.size(); i++) {
3715         if (m_targetPatterns[i].wasString)
3716             builder.appendQuotedJSONString(m_targetPatterns[i].propertyName.string());
3717         else
3718             builder.append(m_targetPatterns[i].propertyName.string());
3719         builder.append(':');
3720         m_targetPatterns[i].pattern->toString(builder);
3721         if (i < m_targetPatterns.size() - 1)
3722             builder.append(',');
3723     }
3724     builder.append('}');
3725 }
3726     
3727 void ObjectPatternNode::bindValue(BytecodeGenerator& generator, RegisterID* rhs) const
3728 {
3729     generator.emitRequireObjectCoercible(rhs, ASCIILiteral("Right side of assignment cannot be destructured"));
3730     for (size