update a class extending null w.r.t the ES7 spec
[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().builtinNames().homeObjectPrivateName());
165     }
166
167     RegisterID callee;
168     callee.setIndex(CallFrameSlot::callee);
169     return generator.emitGetById(generator.newTemporary(), &callee, generator.propertyNames().builtinNames().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(CallFrameSlot::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().builtinNames().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 ((CallFrame::headerSizeInRegisters + 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::Extends && generator.needsToUpdateArrowFunctionContext() && generator.isThisUsedInInnerArrowFunction())
755         generator.emitLoadThisFromArrowFunctionLexicalEnvironment();
756
757     Variable var = generator.variable(generator.propertyNames().eval);
758     if (RegisterID* local = var.local()) {
759         generator.emitTDZCheckIfNecessary(var, local, nullptr);
760         RefPtr<RegisterID> func = generator.emitMove(generator.tempDestination(dst), local);
761         CallArguments callArguments(generator, m_args);
762         generator.emitLoad(callArguments.thisRegister(), jsUndefined());
763         return generator.emitCallEval(generator.finalDestination(dst, func.get()), func.get(), callArguments, divot(), divotStart(), divotEnd());
764     }
765
766     RefPtr<RegisterID> func = generator.newTemporary();
767     CallArguments callArguments(generator, m_args);
768     JSTextPosition newDivot = divotStart() + 4;
769     generator.emitExpressionInfo(newDivot, divotStart(), newDivot);
770     generator.moveToDestinationIfNeeded(
771         callArguments.thisRegister(),
772         generator.emitResolveScope(callArguments.thisRegister(), var));
773     generator.emitGetFromScope(func.get(), callArguments.thisRegister(), var, ThrowIfNotFound);
774     generator.emitTDZCheckIfNecessary(var, func.get(), nullptr);
775     return generator.emitCallEval(generator.finalDestination(dst, func.get()), func.get(), callArguments, divot(), divotStart(), divotEnd());
776 }
777
778 // ------------------------------ FunctionCallValueNode ----------------------------------
779
780 RegisterID* FunctionCallValueNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
781 {
782     if (m_expr->isSuperNode()) {
783         RefPtr<RegisterID> func = emitGetSuperFunctionForConstruct(generator);
784         RefPtr<RegisterID> returnValue = generator.finalDestination(dst, func.get());
785         CallArguments callArguments(generator, m_args);
786
787         ASSERT(generator.isConstructor() || generator.derivedContextType() == DerivedContextType::DerivedConstructorContext);
788         ASSERT(generator.constructorKind() == ConstructorKind::Extends || generator.derivedContextType() == DerivedContextType::DerivedConstructorContext);
789         generator.emitMove(callArguments.thisRegister(), generator.newTarget());
790         RegisterID* ret = generator.emitConstruct(returnValue.get(), func.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
791
792         bool isConstructorKindDerived = generator.constructorKind() == ConstructorKind::Extends;
793         bool doWeUseArrowFunctionInConstructor = isConstructorKindDerived && generator.needsToUpdateArrowFunctionContext();
794
795         if (generator.isDerivedConstructorContext() || (doWeUseArrowFunctionInConstructor && generator.isSuperCallUsedInInnerArrowFunction()))
796             generator.emitLoadThisFromArrowFunctionLexicalEnvironment();
797         
798         RefPtr<Label> thisIsEmptyLabel = generator.newLabel();
799         generator.emitJumpIfTrue(generator.emitIsEmpty(generator.newTemporary(), generator.thisRegister()), thisIsEmptyLabel.get());
800         generator.emitThrowReferenceError(ASCIILiteral("'super()' can't be called more than once in a constructor."));
801         generator.emitLabel(thisIsEmptyLabel.get());
802
803         generator.emitMove(generator.thisRegister(), ret);
804         
805         if (generator.isDerivedConstructorContext() || doWeUseArrowFunctionInConstructor)
806             generator.emitPutThisToArrowFunctionContextScope();
807         
808         return ret;
809     }
810     RefPtr<RegisterID> func = generator.emitNode(m_expr);
811     RefPtr<RegisterID> returnValue = generator.finalDestination(dst, func.get());
812     CallArguments callArguments(generator, m_args);
813     generator.emitLoad(callArguments.thisRegister(), jsUndefined());
814     RegisterID* ret = generator.emitCallInTailPosition(returnValue.get(), func.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
815     generator.emitProfileType(returnValue.get(), divotStart(), divotEnd());
816     return ret;
817 }
818
819 // ------------------------------ FunctionCallResolveNode ----------------------------------
820
821 RegisterID* FunctionCallResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
822 {
823     ExpectedFunction expectedFunction = generator.expectedFunctionForIdentifier(m_ident);
824
825     Variable var = generator.variable(m_ident);
826     if (RegisterID* local = var.local()) {
827         generator.emitTDZCheckIfNecessary(var, local, nullptr);
828         RefPtr<RegisterID> func = generator.emitMove(generator.tempDestination(dst), local);
829         RefPtr<RegisterID> returnValue = generator.finalDestination(dst, func.get());
830         CallArguments callArguments(generator, m_args);
831         generator.emitLoad(callArguments.thisRegister(), jsUndefined());
832         // This passes NoExpectedFunction because we expect that if the function is in a
833         // local variable, then it's not one of our built-in constructors.
834         RegisterID* ret = generator.emitCallInTailPosition(returnValue.get(), func.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
835         generator.emitProfileType(returnValue.get(), divotStart(), divotEnd());
836         return ret;
837     }
838
839     RefPtr<RegisterID> func = generator.newTemporary();
840     RefPtr<RegisterID> returnValue = generator.finalDestination(dst, func.get());
841     CallArguments callArguments(generator, m_args);
842
843     JSTextPosition newDivot = divotStart() + m_ident.length();
844     generator.emitExpressionInfo(newDivot, divotStart(), newDivot);
845     generator.moveToDestinationIfNeeded(
846         callArguments.thisRegister(),
847         generator.emitResolveScope(callArguments.thisRegister(), var));
848     generator.emitGetFromScope(func.get(), callArguments.thisRegister(), var, ThrowIfNotFound);
849     generator.emitTDZCheckIfNecessary(var, func.get(), nullptr);
850     RegisterID* ret = generator.emitCallInTailPosition(returnValue.get(), func.get(), expectedFunction, callArguments, divot(), divotStart(), divotEnd());
851     generator.emitProfileType(returnValue.get(), divotStart(), divotEnd());
852     return ret;
853 }
854
855 // ------------------------------ BytecodeIntrinsicNode ----------------------------------
856
857 RegisterID* BytecodeIntrinsicNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
858 {
859     return (this->*m_emitter)(generator, dst);
860 }
861
862 RegisterID* BytecodeIntrinsicNode::emit_intrinsic_argumentCount(BytecodeGenerator& generator, RegisterID* dst)
863 {
864     ASSERT(!m_args->m_listNode);
865
866     return generator.emitUnaryNoDstOp(op_argument_count, generator.finalDestination(dst));
867 }
868
869 RegisterID* BytecodeIntrinsicNode::emit_intrinsic_assert(BytecodeGenerator& generator, RegisterID* dst)
870 {
871 #ifndef NDEBUG
872     ArgumentListNode* node = m_args->m_listNode;
873     RefPtr<RegisterID> condition = generator.emitNode(node);
874     generator.emitAssert(condition.get(), node->firstLine());
875     return dst;
876 #else
877     UNUSED_PARAM(generator);
878     return dst;
879 #endif
880 }
881
882 RegisterID* BytecodeIntrinsicNode::emit_intrinsic_putByValDirect(BytecodeGenerator& generator, RegisterID* dst)
883 {
884     ArgumentListNode* node = m_args->m_listNode;
885     RefPtr<RegisterID> base = generator.emitNode(node);
886     node = node->m_next;
887     RefPtr<RegisterID> index = generator.emitNode(node);
888     node = node->m_next;
889     RefPtr<RegisterID> value = generator.emitNode(node);
890
891     ASSERT(!node->m_next);
892
893     return generator.moveToDestinationIfNeeded(dst, generator.emitDirectPutByVal(base.get(), index.get(), value.get()));
894 }
895
896 RegisterID* BytecodeIntrinsicNode::emit_intrinsic_tailCallForwardArguments(BytecodeGenerator& generator, RegisterID* dst)
897 {
898     ArgumentListNode* node = m_args->m_listNode;
899     RefPtr<RegisterID> function = generator.emitNode(node);
900     node = node->m_next;
901     RefPtr<RegisterID> thisRegister = generator.emitNode(node);
902     ASSERT(!node->m_next);
903
904     RefPtr<RegisterID> finalDst = generator.finalDestination(dst);
905     return generator.emitCallForwardArgumentsInTailPosition(finalDst.get(), function.get(), thisRegister.get(), generator.newTemporary(), 0, divot(), divotStart(), divotEnd());
906 }
907
908 RegisterID* BytecodeIntrinsicNode::emit_intrinsic_tryGetById(BytecodeGenerator& generator, RegisterID* dst)
909 {
910     ArgumentListNode* node = m_args->m_listNode;
911     RefPtr<RegisterID> base = generator.emitNode(node);
912     node = node->m_next;
913
914     // Since this is a builtin we expect the creator to use a string literal as the second argument.
915     ASSERT(node->m_expr->isString());
916     const Identifier& ident = static_cast<StringNode*>(node->m_expr)->value();
917     ASSERT(!node->m_next);
918
919     RefPtr<RegisterID> finalDest = generator.finalDestination(dst);
920     return generator.emitTryGetById(finalDest.get(), base.get(), ident);
921 }
922
923 RegisterID* BytecodeIntrinsicNode::emit_intrinsic_toNumber(BytecodeGenerator& generator, RegisterID* dst)
924 {
925     ArgumentListNode* node = m_args->m_listNode;
926     RefPtr<RegisterID> src = generator.emitNode(node);
927     ASSERT(!node->m_next);
928
929     return generator.moveToDestinationIfNeeded(dst, generator.emitToNumber(generator.tempDestination(dst), src.get()));
930 }
931
932 RegisterID* BytecodeIntrinsicNode::emit_intrinsic_toString(BytecodeGenerator& generator, RegisterID* dst)
933 {
934     ArgumentListNode* node = m_args->m_listNode;
935     RefPtr<RegisterID> src = generator.emitNode(node);
936     ASSERT(!node->m_next);
937
938     return generator.moveToDestinationIfNeeded(dst, generator.emitToString(generator.tempDestination(dst), src.get()));
939 }
940     
941 RegisterID* BytecodeIntrinsicNode::emit_intrinsic_isJSArray(JSC::BytecodeGenerator& generator, JSC::RegisterID* dst)
942 {
943     ArgumentListNode* node = m_args->m_listNode;
944     RefPtr<RegisterID> src = generator.emitNode(node);
945     ASSERT(!node->m_next);
946
947     return generator.moveToDestinationIfNeeded(dst, generator.emitIsJSArray(generator.tempDestination(dst), src.get()));
948 }
949
950 RegisterID* BytecodeIntrinsicNode::emit_intrinsic_isObject(BytecodeGenerator& generator, RegisterID* dst)
951 {
952     ArgumentListNode* node = m_args->m_listNode;
953     RefPtr<RegisterID> src = generator.emitNode(node);
954     ASSERT(!node->m_next);
955
956     return generator.moveToDestinationIfNeeded(dst, generator.emitIsObject(generator.tempDestination(dst), src.get()));
957 }
958
959
960 #define JSC_DECLARE_BYTECODE_INTRINSIC_CONSTANT_GENERATORS(name) \
961     RegisterID* BytecodeIntrinsicNode::emit_intrinsic_##name(BytecodeGenerator& generator, RegisterID* dst) \
962     { \
963         ASSERT(!m_args); \
964         ASSERT(type() == Type::Constant); \
965         if (dst == generator.ignoredResult()) \
966             return nullptr; \
967         return generator.emitLoad(dst, generator.vm()->bytecodeIntrinsicRegistry().name##Value(generator)); \
968     }
969     JSC_COMMON_BYTECODE_INTRINSIC_CONSTANTS_EACH_NAME(JSC_DECLARE_BYTECODE_INTRINSIC_CONSTANT_GENERATORS)
970 #undef JSC_DECLARE_BYTECODE_INTRINSIC_CONSTANT_GENERATORS
971
972 // ------------------------------ FunctionCallBracketNode ----------------------------------
973
974 RegisterID* FunctionCallBracketNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
975 {
976     bool baseIsSuper = m_base->isSuperNode();
977     bool subscriptIsNonIndexString = isNonIndexStringElement(*m_subscript);
978
979     RefPtr<RegisterID> base;
980     if (baseIsSuper)
981         base = emitSuperBaseForCallee(generator);
982     else {
983         if (subscriptIsNonIndexString)
984             base = generator.emitNode(m_base);
985         else
986             base = generator.emitNodeForLeftHandSide(m_base, m_subscriptHasAssignments, m_subscript->isPure(generator));
987     }
988
989     RefPtr<RegisterID> function;
990     RefPtr<RegisterID> thisRegister;
991     if (baseIsSuper) {
992         // 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.
993         thisRegister = generator.ensureThis();
994     }
995     if (subscriptIsNonIndexString) {
996         generator.emitExpressionInfo(subexpressionDivot(), subexpressionStart(), subexpressionEnd());
997         if (baseIsSuper)
998             function = generator.emitGetById(generator.tempDestination(dst), base.get(), thisRegister.get(), static_cast<StringNode*>(m_subscript)->value());
999         else
1000             function = generator.emitGetById(generator.tempDestination(dst), base.get(), static_cast<StringNode*>(m_subscript)->value());
1001     } else {
1002         RefPtr<RegisterID> property = generator.emitNode(m_subscript);
1003         generator.emitExpressionInfo(subexpressionDivot(), subexpressionStart(), subexpressionEnd());
1004         if (baseIsSuper)
1005             function = generator.emitGetByVal(generator.tempDestination(dst), base.get(), thisRegister.get(), property.get());
1006         else
1007             function = generator.emitGetByVal(generator.tempDestination(dst), base.get(), property.get());
1008     }
1009
1010     RefPtr<RegisterID> returnValue = generator.finalDestination(dst, function.get());
1011     CallArguments callArguments(generator, m_args);
1012     if (baseIsSuper) {
1013         generator.emitTDZCheck(generator.thisRegister());
1014         generator.emitMove(callArguments.thisRegister(), thisRegister.get());
1015     } else
1016         generator.emitMove(callArguments.thisRegister(), base.get());
1017     RegisterID* ret = generator.emitCallInTailPosition(returnValue.get(), function.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
1018     generator.emitProfileType(returnValue.get(), divotStart(), divotEnd());
1019     return ret;
1020 }
1021
1022 // ------------------------------ FunctionCallDotNode ----------------------------------
1023
1024 RegisterID* FunctionCallDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1025 {
1026     RefPtr<RegisterID> function = generator.tempDestination(dst);
1027     RefPtr<RegisterID> returnValue = generator.finalDestination(dst, function.get());
1028     CallArguments callArguments(generator, m_args);
1029     bool baseIsSuper = m_base->isSuperNode();
1030     if (baseIsSuper)
1031         generator.emitMove(callArguments.thisRegister(), generator.ensureThis());
1032     else
1033         generator.emitNode(callArguments.thisRegister(), m_base);
1034     generator.emitExpressionInfo(subexpressionDivot(), subexpressionStart(), subexpressionEnd());
1035     if (baseIsSuper) {
1036         RefPtr<RegisterID> superBase = emitSuperBaseForCallee(generator);
1037         generator.emitGetById(function.get(), superBase.get(), callArguments.thisRegister(), m_ident);
1038     } else
1039         generator.emitGetById(function.get(), callArguments.thisRegister(), m_ident);
1040     RegisterID* ret = generator.emitCallInTailPosition(returnValue.get(), function.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
1041     generator.emitProfileType(returnValue.get(), divotStart(), divotEnd());
1042     return ret;
1043 }
1044
1045 RegisterID* CallFunctionCallDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1046 {
1047     RefPtr<Label> realCall = generator.newLabel();
1048     RefPtr<Label> end = generator.newLabel();
1049     RefPtr<RegisterID> base = generator.emitNode(m_base);
1050     generator.emitExpressionInfo(subexpressionDivot(), subexpressionStart(), subexpressionEnd());
1051     RefPtr<RegisterID> function;
1052     bool emitCallCheck = !generator.isBuiltinFunction();
1053     if (emitCallCheck) {
1054         if (m_base->isSuperNode()) {
1055             RefPtr<RegisterID> thisValue = generator.ensureThis();
1056             function = generator.emitGetById(generator.tempDestination(dst), base.get(), thisValue.get(), generator.propertyNames().builtinNames().callPublicName());
1057         } else
1058             function = generator.emitGetById(generator.tempDestination(dst), base.get(), generator.propertyNames().builtinNames().callPublicName());
1059         generator.emitJumpIfNotFunctionCall(function.get(), realCall.get());
1060     }
1061     RefPtr<RegisterID> returnValue = generator.finalDestination(dst);
1062     {
1063         if (m_args->m_listNode && m_args->m_listNode->m_expr && m_args->m_listNode->m_expr->isSpreadExpression()) {
1064             SpreadExpressionNode* spread = static_cast<SpreadExpressionNode*>(m_args->m_listNode->m_expr);
1065             ExpressionNode* subject = spread->expression();
1066             RefPtr<RegisterID> argumentsRegister;
1067             argumentsRegister = generator.emitNode(subject);
1068             generator.emitExpressionInfo(spread->divot(), spread->divotStart(), spread->divotEnd());
1069             RefPtr<RegisterID> thisRegister = generator.emitGetByVal(generator.newTemporary(), argumentsRegister.get(), generator.emitLoad(0, jsNumber(0)));
1070             generator.emitCallVarargsInTailPosition(returnValue.get(), base.get(), thisRegister.get(), argumentsRegister.get(), generator.newTemporary(), 1, divot(), divotStart(), divotEnd());
1071         } else if (m_args->m_listNode && m_args->m_listNode->m_expr) {
1072             ArgumentListNode* oldList = m_args->m_listNode;
1073             m_args->m_listNode = m_args->m_listNode->m_next;
1074
1075             RefPtr<RegisterID> realFunction = generator.emitMove(generator.tempDestination(dst), base.get());
1076             CallArguments callArguments(generator, m_args);
1077             generator.emitNode(callArguments.thisRegister(), oldList->m_expr);
1078             generator.emitCallInTailPosition(returnValue.get(), realFunction.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
1079             m_args->m_listNode = oldList;
1080         } else {
1081             RefPtr<RegisterID> realFunction = generator.emitMove(generator.tempDestination(dst), base.get());
1082             CallArguments callArguments(generator, m_args);
1083             generator.emitLoad(callArguments.thisRegister(), jsUndefined());
1084             generator.emitCallInTailPosition(returnValue.get(), realFunction.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
1085         }
1086     }
1087     if (emitCallCheck) {
1088         generator.emitJump(end.get());
1089         generator.emitLabel(realCall.get());
1090         {
1091             CallArguments callArguments(generator, m_args);
1092             generator.emitMove(callArguments.thisRegister(), base.get());
1093             generator.emitCallInTailPosition(returnValue.get(), function.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
1094         }
1095         generator.emitLabel(end.get());
1096     }
1097     generator.emitProfileType(returnValue.get(), divotStart(), divotEnd());
1098     return returnValue.get();
1099 }
1100
1101 static bool areTrivialApplyArguments(ArgumentsNode* args)
1102 {
1103     return !args->m_listNode || !args->m_listNode->m_expr || !args->m_listNode->m_next
1104         || (!args->m_listNode->m_next->m_next && args->m_listNode->m_next->m_expr->isSimpleArray());
1105 }
1106
1107 RegisterID* ApplyFunctionCallDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1108 {
1109     // A few simple cases can be trivially handled as ordinary function calls.
1110     // function.apply(), function.apply(arg) -> identical to function.call
1111     // function.apply(thisArg, [arg0, arg1, ...]) -> can be trivially coerced into function.call(thisArg, arg0, arg1, ...) and saves object allocation
1112     bool mayBeCall = areTrivialApplyArguments(m_args);
1113
1114     RefPtr<Label> realCall = generator.newLabel();
1115     RefPtr<Label> end = generator.newLabel();
1116     RefPtr<RegisterID> base = generator.emitNode(m_base);
1117     generator.emitExpressionInfo(subexpressionDivot(), subexpressionStart(), subexpressionEnd());
1118     RefPtr<RegisterID> function;
1119     RefPtr<RegisterID> returnValue = generator.finalDestination(dst, function.get());
1120     bool emitCallCheck = !generator.isBuiltinFunction();
1121     if (emitCallCheck) {
1122         if (m_base->isSuperNode()) {
1123             RefPtr<RegisterID> thisValue = generator.ensureThis();
1124             function = generator.emitGetById(generator.tempDestination(dst), base.get(), thisValue.get(), generator.propertyNames().builtinNames().applyPublicName());
1125         } else
1126             function = generator.emitGetById(generator.tempDestination(dst), base.get(), generator.propertyNames().builtinNames().applyPublicName());
1127         generator.emitJumpIfNotFunctionApply(function.get(), realCall.get());
1128     }
1129     if (mayBeCall) {
1130         if (m_args->m_listNode && m_args->m_listNode->m_expr) {
1131             ArgumentListNode* oldList = m_args->m_listNode;
1132             if (m_args->m_listNode->m_expr->isSpreadExpression()) {
1133                 SpreadExpressionNode* spread = static_cast<SpreadExpressionNode*>(m_args->m_listNode->m_expr);
1134                 RefPtr<RegisterID> realFunction = generator.emitMove(generator.newTemporary(), base.get());
1135                 RefPtr<RegisterID> index = generator.emitLoad(generator.newTemporary(), jsNumber(0));
1136                 RefPtr<RegisterID> thisRegister = generator.emitLoad(generator.newTemporary(), jsUndefined());
1137                 RefPtr<RegisterID> argumentsRegister = generator.emitLoad(generator.newTemporary(), jsUndefined());
1138                 
1139                 auto extractor = [&thisRegister, &argumentsRegister, &index](BytecodeGenerator& generator, RegisterID* value)
1140                 {
1141                     RefPtr<Label> haveThis = generator.newLabel();
1142                     RefPtr<Label> end = generator.newLabel();
1143                     RefPtr<RegisterID> compareResult = generator.newTemporary();
1144                     RefPtr<RegisterID> indexZeroCompareResult = generator.emitBinaryOp(op_eq, compareResult.get(), index.get(), generator.emitLoad(0, jsNumber(0)), OperandTypes(ResultType::numberTypeIsInt32(), ResultType::numberTypeIsInt32()));
1145                     generator.emitJumpIfFalse(indexZeroCompareResult.get(), haveThis.get());
1146                     generator.emitMove(thisRegister.get(), value);
1147                     generator.emitLoad(index.get(), jsNumber(1));
1148                     generator.emitJump(end.get());
1149                     generator.emitLabel(haveThis.get());
1150                     RefPtr<RegisterID> indexOneCompareResult = generator.emitBinaryOp(op_eq, compareResult.get(), index.get(), generator.emitLoad(0, jsNumber(1)), OperandTypes(ResultType::numberTypeIsInt32(), ResultType::numberTypeIsInt32()));
1151                     generator.emitJumpIfFalse(indexOneCompareResult.get(), end.get());
1152                     generator.emitMove(argumentsRegister.get(), value);
1153                     generator.emitLoad(index.get(), jsNumber(2));
1154                     generator.emitLabel(end.get());
1155                 };
1156                 generator.emitEnumeration(this, spread->expression(), extractor);
1157                 generator.emitCallVarargsInTailPosition(returnValue.get(), realFunction.get(), thisRegister.get(), argumentsRegister.get(), generator.newTemporary(), 0, divot(), divotStart(), divotEnd());
1158             } else if (m_args->m_listNode->m_next) {
1159                 ASSERT(m_args->m_listNode->m_next->m_expr->isSimpleArray());
1160                 ASSERT(!m_args->m_listNode->m_next->m_next);
1161                 m_args->m_listNode = static_cast<ArrayNode*>(m_args->m_listNode->m_next->m_expr)->toArgumentList(generator.parserArena(), 0, 0);
1162                 RefPtr<RegisterID> realFunction = generator.emitMove(generator.tempDestination(dst), base.get());
1163                 CallArguments callArguments(generator, m_args);
1164                 generator.emitNode(callArguments.thisRegister(), oldList->m_expr);
1165                 generator.emitCallInTailPosition(returnValue.get(), realFunction.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
1166             } else {
1167                 m_args->m_listNode = m_args->m_listNode->m_next;
1168                 RefPtr<RegisterID> realFunction = generator.emitMove(generator.tempDestination(dst), base.get());
1169                 CallArguments callArguments(generator, m_args);
1170                 generator.emitNode(callArguments.thisRegister(), oldList->m_expr);
1171                 generator.emitCallInTailPosition(returnValue.get(), realFunction.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
1172             }
1173             m_args->m_listNode = oldList;
1174         } else {
1175             RefPtr<RegisterID> realFunction = generator.emitMove(generator.tempDestination(dst), base.get());
1176             CallArguments callArguments(generator, m_args);
1177             generator.emitLoad(callArguments.thisRegister(), jsUndefined());
1178             generator.emitCallInTailPosition(returnValue.get(), realFunction.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
1179         }
1180     } else {
1181         ASSERT(m_args->m_listNode && m_args->m_listNode->m_next);
1182         RefPtr<RegisterID> realFunction = generator.emitMove(generator.tempDestination(dst), base.get());
1183         RefPtr<RegisterID> thisRegister = generator.emitNode(m_args->m_listNode->m_expr);
1184         RefPtr<RegisterID> argsRegister;
1185         ArgumentListNode* args = m_args->m_listNode->m_next;
1186         argsRegister = generator.emitNode(args->m_expr);
1187
1188         // Function.prototype.apply ignores extra arguments, but we still
1189         // need to evaluate them for side effects.
1190         while ((args = args->m_next))
1191             generator.emitNode(args->m_expr);
1192
1193         generator.emitCallVarargsInTailPosition(returnValue.get(), realFunction.get(), thisRegister.get(), argsRegister.get(), generator.newTemporary(), 0, divot(), divotStart(), divotEnd());
1194     }
1195     if (emitCallCheck) {
1196         generator.emitJump(end.get());
1197         generator.emitLabel(realCall.get());
1198         CallArguments callArguments(generator, m_args);
1199         generator.emitMove(callArguments.thisRegister(), base.get());
1200         generator.emitCallInTailPosition(returnValue.get(), function.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
1201         generator.emitLabel(end.get());
1202     }
1203     generator.emitProfileType(returnValue.get(), divotStart(), divotEnd());
1204     return returnValue.get();
1205 }
1206
1207 // ------------------------------ PostfixNode ----------------------------------
1208
1209 static RegisterID* emitIncOrDec(BytecodeGenerator& generator, RegisterID* srcDst, Operator oper)
1210 {
1211     return (oper == OpPlusPlus) ? generator.emitInc(srcDst) : generator.emitDec(srcDst);
1212 }
1213
1214 static RegisterID* emitPostIncOrDec(BytecodeGenerator& generator, RegisterID* dst, RegisterID* srcDst, Operator oper)
1215 {
1216     if (dst == srcDst)
1217         return generator.emitToNumber(generator.finalDestination(dst), srcDst);
1218     RefPtr<RegisterID> tmp = generator.emitToNumber(generator.tempDestination(dst), srcDst);
1219     emitIncOrDec(generator, srcDst, oper);
1220     return generator.moveToDestinationIfNeeded(dst, tmp.get());
1221 }
1222
1223 RegisterID* PostfixNode::emitResolve(BytecodeGenerator& generator, RegisterID* dst)
1224 {
1225     if (dst == generator.ignoredResult())
1226         return PrefixNode::emitResolve(generator, dst);
1227
1228     ASSERT(m_expr->isResolveNode());
1229     ResolveNode* resolve = static_cast<ResolveNode*>(m_expr);
1230     const Identifier& ident = resolve->identifier();
1231
1232     Variable var = generator.variable(ident);
1233     if (RegisterID* local = var.local()) {
1234         generator.emitTDZCheckIfNecessary(var, local, nullptr);
1235         RefPtr<RegisterID> localReg = local;
1236         if (var.isReadOnly()) {
1237             generator.emitReadOnlyExceptionIfNeeded(var);
1238             localReg = generator.emitMove(generator.tempDestination(dst), local);
1239         }
1240         RefPtr<RegisterID> oldValue = emitPostIncOrDec(generator, generator.finalDestination(dst), localReg.get(), m_operator);
1241         generator.emitProfileType(localReg.get(), var, divotStart(), divotEnd());
1242         return oldValue.get();
1243     }
1244
1245     generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
1246     RefPtr<RegisterID> scope = generator.emitResolveScope(nullptr, var);
1247     RefPtr<RegisterID> value = generator.emitGetFromScope(generator.newTemporary(), scope.get(), var, ThrowIfNotFound);
1248     generator.emitTDZCheckIfNecessary(var, value.get(), nullptr);
1249     if (var.isReadOnly()) {
1250         bool threwException = generator.emitReadOnlyExceptionIfNeeded(var);
1251         if (threwException)
1252             return value.get();
1253     }
1254     RefPtr<RegisterID> oldValue = emitPostIncOrDec(generator, generator.finalDestination(dst), value.get(), m_operator);
1255     if (!var.isReadOnly()) {
1256         generator.emitPutToScope(scope.get(), var, value.get(), ThrowIfNotFound, InitializationMode::NotInitialization);
1257         generator.emitProfileType(value.get(), var, divotStart(), divotEnd());
1258     }
1259
1260     return oldValue.get();
1261 }
1262
1263 RegisterID* PostfixNode::emitBracket(BytecodeGenerator& generator, RegisterID* dst)
1264 {
1265     if (dst == generator.ignoredResult())
1266         return PrefixNode::emitBracket(generator, dst);
1267
1268     ASSERT(m_expr->isBracketAccessorNode());
1269     BracketAccessorNode* bracketAccessor = static_cast<BracketAccessorNode*>(m_expr);
1270     ExpressionNode* baseNode = bracketAccessor->base();
1271     ExpressionNode* subscript = bracketAccessor->subscript();
1272
1273     RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(baseNode, bracketAccessor->subscriptHasAssignments(), subscript->isPure(generator));
1274     RefPtr<RegisterID> property = generator.emitNode(subscript);
1275
1276     generator.emitExpressionInfo(bracketAccessor->divot(), bracketAccessor->divotStart(), bracketAccessor->divotEnd());
1277     RefPtr<RegisterID> value;
1278     RefPtr<RegisterID> thisValue;
1279     if (baseNode->isSuperNode()) {
1280         thisValue = generator.ensureThis();
1281         value = generator.emitGetByVal(generator.newTemporary(), base.get(), thisValue.get(), property.get());
1282     } else
1283         value = generator.emitGetByVal(generator.newTemporary(), base.get(), property.get());
1284     RegisterID* oldValue = emitPostIncOrDec(generator, generator.tempDestination(dst), value.get(), m_operator);
1285     generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
1286     if (baseNode->isSuperNode())
1287         generator.emitPutByVal(base.get(), thisValue.get(), property.get(), value.get());
1288     else
1289         generator.emitPutByVal(base.get(), property.get(), value.get());
1290     generator.emitProfileType(value.get(), divotStart(), divotEnd());
1291     return generator.moveToDestinationIfNeeded(dst, oldValue);
1292 }
1293
1294 RegisterID* PostfixNode::emitDot(BytecodeGenerator& generator, RegisterID* dst)
1295 {
1296     if (dst == generator.ignoredResult())
1297         return PrefixNode::emitDot(generator, dst);
1298
1299     ASSERT(m_expr->isDotAccessorNode());
1300     DotAccessorNode* dotAccessor = static_cast<DotAccessorNode*>(m_expr);
1301     ExpressionNode* baseNode = dotAccessor->base();
1302     bool baseIsSuper = baseNode->isSuperNode();
1303     const Identifier& ident = dotAccessor->identifier();
1304
1305     RefPtr<RegisterID> base = generator.emitNode(baseNode);
1306
1307     generator.emitExpressionInfo(dotAccessor->divot(), dotAccessor->divotStart(), dotAccessor->divotEnd());
1308     RefPtr<RegisterID> value;
1309     RefPtr<RegisterID> thisValue;
1310     if (baseIsSuper) {
1311         thisValue = generator.ensureThis();
1312         value = generator.emitGetById(generator.newTemporary(), base.get(), thisValue.get(), ident);
1313     } else
1314         value = generator.emitGetById(generator.newTemporary(), base.get(), ident);
1315     RegisterID* oldValue = emitPostIncOrDec(generator, generator.tempDestination(dst), value.get(), m_operator);
1316     generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
1317     if (baseIsSuper)
1318         generator.emitPutById(base.get(), thisValue.get(), ident, value.get());
1319     else
1320         generator.emitPutById(base.get(), ident, value.get());
1321     generator.emitProfileType(value.get(), divotStart(), divotEnd());
1322     return generator.moveToDestinationIfNeeded(dst, oldValue);
1323 }
1324
1325 RegisterID* PostfixNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1326 {
1327     if (m_expr->isResolveNode())
1328         return emitResolve(generator, dst);
1329
1330     if (m_expr->isBracketAccessorNode())
1331         return emitBracket(generator, dst);
1332
1333     if (m_expr->isDotAccessorNode())
1334         return emitDot(generator, dst);
1335
1336     return emitThrowReferenceError(generator, m_operator == OpPlusPlus
1337         ? ASCIILiteral("Postfix ++ operator applied to value that is not a reference.")
1338         : ASCIILiteral("Postfix -- operator applied to value that is not a reference."));
1339 }
1340
1341 // ------------------------------ DeleteResolveNode -----------------------------------
1342
1343 RegisterID* DeleteResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1344 {
1345     Variable var = generator.variable(m_ident);
1346     if (var.local()) {
1347         generator.emitTDZCheckIfNecessary(var, var.local(), nullptr);
1348         return generator.emitLoad(generator.finalDestination(dst), false);
1349     }
1350
1351     generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
1352     RefPtr<RegisterID> base = generator.emitResolveScope(dst, var);
1353     generator.emitTDZCheckIfNecessary(var, nullptr, base.get());
1354     return generator.emitDeleteById(generator.finalDestination(dst, base.get()), base.get(), m_ident);
1355 }
1356
1357 // ------------------------------ DeleteBracketNode -----------------------------------
1358
1359 RegisterID* DeleteBracketNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1360 {
1361     RefPtr<RegisterID> r0 = generator.emitNode(m_base);
1362     RefPtr<RegisterID> r1 = generator.emitNode(m_subscript);
1363
1364     generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
1365     if (m_base->isSuperNode())
1366         return emitThrowReferenceError(generator, "Cannot delete a super property");
1367     return generator.emitDeleteByVal(generator.finalDestination(dst), r0.get(), r1.get());
1368 }
1369
1370 // ------------------------------ DeleteDotNode -----------------------------------
1371
1372 RegisterID* DeleteDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1373 {
1374     RefPtr<RegisterID> r0 = generator.emitNode(m_base);
1375
1376     generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
1377     if (m_base->isSuperNode())
1378         return emitThrowReferenceError(generator, "Cannot delete a super property");
1379     return generator.emitDeleteById(generator.finalDestination(dst), r0.get(), m_ident);
1380 }
1381
1382 // ------------------------------ DeleteValueNode -----------------------------------
1383
1384 RegisterID* DeleteValueNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1385 {
1386     generator.emitNode(generator.ignoredResult(), m_expr);
1387
1388     // delete on a non-location expression ignores the value and returns true
1389     return generator.emitLoad(generator.finalDestination(dst), true);
1390 }
1391
1392 // ------------------------------ VoidNode -------------------------------------
1393
1394 RegisterID* VoidNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1395 {
1396     if (dst == generator.ignoredResult()) {
1397         generator.emitNode(generator.ignoredResult(), m_expr);
1398         return 0;
1399     }
1400     RefPtr<RegisterID> r0 = generator.emitNode(m_expr);
1401     return generator.emitLoad(dst, jsUndefined());
1402 }
1403
1404 // ------------------------------ TypeOfResolveNode -----------------------------------
1405
1406 RegisterID* TypeOfResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1407 {
1408     Variable var = generator.variable(m_ident);
1409     if (RegisterID* local = var.local()) {
1410         generator.emitTDZCheckIfNecessary(var, local, nullptr);
1411         if (dst == generator.ignoredResult())
1412             return 0;
1413         return generator.emitTypeOf(generator.finalDestination(dst), local);
1414     }
1415
1416     RefPtr<RegisterID> scope = generator.emitResolveScope(dst, var);
1417     RefPtr<RegisterID> value = generator.emitGetFromScope(generator.newTemporary(), scope.get(), var, DoNotThrowIfNotFound);
1418     generator.emitTDZCheckIfNecessary(var, value.get(), nullptr);
1419     if (dst == generator.ignoredResult())
1420         return 0;
1421     return generator.emitTypeOf(generator.finalDestination(dst, scope.get()), value.get());
1422 }
1423
1424 // ------------------------------ TypeOfValueNode -----------------------------------
1425
1426 RegisterID* TypeOfValueNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1427 {
1428     if (dst == generator.ignoredResult()) {
1429         generator.emitNode(generator.ignoredResult(), m_expr);
1430         return 0;
1431     }
1432     RefPtr<RegisterID> src = generator.emitNode(m_expr);
1433     return generator.emitTypeOf(generator.finalDestination(dst), src.get());
1434 }
1435
1436 // ------------------------------ PrefixNode ----------------------------------
1437
1438 RegisterID* PrefixNode::emitResolve(BytecodeGenerator& generator, RegisterID* dst)
1439 {
1440     ASSERT(m_expr->isResolveNode());
1441     ResolveNode* resolve = static_cast<ResolveNode*>(m_expr);
1442     const Identifier& ident = resolve->identifier();
1443
1444     Variable var = generator.variable(ident);
1445     if (RegisterID* local = var.local()) {
1446         generator.emitTDZCheckIfNecessary(var, local, nullptr);
1447         RefPtr<RegisterID> localReg = local;
1448         if (var.isReadOnly()) {
1449             generator.emitReadOnlyExceptionIfNeeded(var);
1450             localReg = generator.emitMove(generator.tempDestination(dst), localReg.get());
1451         } else if (generator.vm()->typeProfiler()) {
1452             RefPtr<RegisterID> tempDst = generator.tempDestination(dst);
1453             generator.emitMove(tempDst.get(), localReg.get());
1454             emitIncOrDec(generator, tempDst.get(), m_operator);
1455             generator.emitMove(localReg.get(), tempDst.get());
1456             generator.emitProfileType(localReg.get(), var, divotStart(), divotEnd());
1457             return generator.moveToDestinationIfNeeded(dst, tempDst.get());
1458         }
1459         emitIncOrDec(generator, localReg.get(), m_operator);
1460         return generator.moveToDestinationIfNeeded(dst, localReg.get());
1461     }
1462
1463     generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
1464     RefPtr<RegisterID> scope = generator.emitResolveScope(dst, var);
1465     RefPtr<RegisterID> value = generator.emitGetFromScope(generator.newTemporary(), scope.get(), var, ThrowIfNotFound);
1466     generator.emitTDZCheckIfNecessary(var, value.get(), nullptr);
1467     if (var.isReadOnly()) {
1468         bool threwException = generator.emitReadOnlyExceptionIfNeeded(var);
1469         if (threwException)
1470             return value.get();
1471     }
1472
1473     emitIncOrDec(generator, value.get(), m_operator);
1474     if (!var.isReadOnly()) {
1475         generator.emitPutToScope(scope.get(), var, value.get(), ThrowIfNotFound, InitializationMode::NotInitialization);
1476         generator.emitProfileType(value.get(), var, divotStart(), divotEnd());
1477     }
1478     return generator.moveToDestinationIfNeeded(dst, value.get());
1479 }
1480
1481 RegisterID* PrefixNode::emitBracket(BytecodeGenerator& generator, RegisterID* dst)
1482 {
1483     ASSERT(m_expr->isBracketAccessorNode());
1484     BracketAccessorNode* bracketAccessor = static_cast<BracketAccessorNode*>(m_expr);
1485     ExpressionNode* baseNode = bracketAccessor->base();
1486     ExpressionNode* subscript = bracketAccessor->subscript();
1487
1488     RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(baseNode, bracketAccessor->subscriptHasAssignments(), subscript->isPure(generator));
1489     RefPtr<RegisterID> property = generator.emitNode(subscript);
1490     RefPtr<RegisterID> propDst = generator.tempDestination(dst);
1491
1492     generator.emitExpressionInfo(bracketAccessor->divot(), bracketAccessor->divotStart(), bracketAccessor->divotEnd());
1493     RegisterID* value;
1494     RefPtr<RegisterID> thisValue;
1495     if (baseNode->isSuperNode()) {
1496         thisValue = generator.ensureThis();
1497         value = generator.emitGetByVal(propDst.get(), base.get(), thisValue.get(), property.get());
1498     } else
1499         value = generator.emitGetByVal(propDst.get(), base.get(), property.get());
1500     emitIncOrDec(generator, value, m_operator);
1501     generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
1502     if (baseNode->isSuperNode())
1503         generator.emitPutByVal(base.get(), thisValue.get(), property.get(), value);
1504     else
1505         generator.emitPutByVal(base.get(), property.get(), value);
1506     generator.emitProfileType(value, divotStart(), divotEnd());
1507     return generator.moveToDestinationIfNeeded(dst, propDst.get());
1508 }
1509
1510 RegisterID* PrefixNode::emitDot(BytecodeGenerator& generator, RegisterID* dst)
1511 {
1512     ASSERT(m_expr->isDotAccessorNode());
1513     DotAccessorNode* dotAccessor = static_cast<DotAccessorNode*>(m_expr);
1514     ExpressionNode* baseNode = dotAccessor->base();
1515     const Identifier& ident = dotAccessor->identifier();
1516
1517     RefPtr<RegisterID> base = generator.emitNode(baseNode);
1518     RefPtr<RegisterID> propDst = generator.tempDestination(dst);
1519
1520     generator.emitExpressionInfo(dotAccessor->divot(), dotAccessor->divotStart(), dotAccessor->divotEnd());
1521     RegisterID* value;
1522     RefPtr<RegisterID> thisValue;
1523     if (baseNode->isSuperNode()) {
1524         thisValue = generator.ensureThis();
1525         value = generator.emitGetById(propDst.get(), base.get(), thisValue.get(), ident);
1526     } else
1527         value = generator.emitGetById(propDst.get(), base.get(), ident);
1528     emitIncOrDec(generator, value, m_operator);
1529     generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
1530     if (baseNode->isSuperNode())
1531         generator.emitPutById(base.get(), thisValue.get(), ident, value);
1532     else
1533         generator.emitPutById(base.get(), ident, value);
1534     generator.emitProfileType(value, divotStart(), divotEnd());
1535     return generator.moveToDestinationIfNeeded(dst, propDst.get());
1536 }
1537
1538 RegisterID* PrefixNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1539 {
1540     if (m_expr->isResolveNode())
1541         return emitResolve(generator, dst);
1542
1543     if (m_expr->isBracketAccessorNode())
1544         return emitBracket(generator, dst);
1545
1546     if (m_expr->isDotAccessorNode())
1547         return emitDot(generator, dst);
1548
1549     return emitThrowReferenceError(generator, m_operator == OpPlusPlus
1550         ? ASCIILiteral("Prefix ++ operator applied to value that is not a reference.")
1551         : ASCIILiteral("Prefix -- operator applied to value that is not a reference."));
1552 }
1553
1554 // ------------------------------ Unary Operation Nodes -----------------------------------
1555
1556 RegisterID* UnaryOpNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1557 {
1558     RefPtr<RegisterID> src = generator.emitNode(m_expr);
1559     generator.emitExpressionInfo(position(), position(), position());
1560     return generator.emitUnaryOp(opcodeID(), generator.finalDestination(dst), src.get());
1561 }
1562
1563 // ------------------------------ UnaryPlusNode -----------------------------------
1564
1565 RegisterID* UnaryPlusNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1566 {
1567     ASSERT(opcodeID() == op_to_number);
1568     RefPtr<RegisterID> src = generator.emitNode(expr());
1569     generator.emitExpressionInfo(position(), position(), position());
1570     return generator.emitToNumber(generator.finalDestination(dst), src.get());
1571 }
1572
1573 // ------------------------------ BitwiseNotNode -----------------------------------
1574  
1575 RegisterID* BitwiseNotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1576 {
1577     RefPtr<RegisterID> src2 = generator.emitLoad(generator.newTemporary(), jsNumber(-1));
1578     RefPtr<RegisterID> src1 = generator.emitNode(m_expr);
1579     return generator.emitBinaryOp(op_bitxor, generator.finalDestination(dst, src1.get()), src1.get(), src2.get(), OperandTypes(m_expr->resultDescriptor(), ResultType::numberTypeIsInt32()));
1580 }
1581  
1582 // ------------------------------ LogicalNotNode -----------------------------------
1583
1584 void LogicalNotNode::emitBytecodeInConditionContext(BytecodeGenerator& generator, Label* trueTarget, Label* falseTarget, FallThroughMode fallThroughMode)
1585 {
1586     // reverse the true and false targets
1587     generator.emitNodeInConditionContext(expr(), falseTarget, trueTarget, invert(fallThroughMode));
1588 }
1589
1590
1591 // ------------------------------ Binary Operation Nodes -----------------------------------
1592
1593 // BinaryOpNode::emitStrcat:
1594 //
1595 // This node generates an op_strcat operation.  This opcode can handle concatenation of three or
1596 // more values, where we can determine a set of separate op_add operations would be operating on
1597 // string values.
1598 //
1599 // This function expects to be operating on a graph of AST nodes looking something like this:
1600 //
1601 //     (a)...     (b)
1602 //          \   /
1603 //           (+)     (c)
1604 //              \   /
1605 //      [d]     ((+))
1606 //         \    /
1607 //          [+=]
1608 //
1609 // The assignment operation is optional, if it exists the register holding the value on the
1610 // lefthand side of the assignment should be passing as the optional 'lhs' argument.
1611 //
1612 // The method should be called on the node at the root of the tree of regular binary add
1613 // operations (marked in the diagram with a double set of parentheses).  This node must
1614 // be performing a string concatenation (determined by statically detecting that at least
1615 // one child must be a string).  
1616 //
1617 // Since the minimum number of values being concatenated together is expected to be 3, if
1618 // a lhs to a concatenating assignment is not provided then the  root add should have at
1619 // least one left child that is also an add that can be determined to be operating on strings.
1620 //
1621 RegisterID* BinaryOpNode::emitStrcat(BytecodeGenerator& generator, RegisterID* dst, RegisterID* lhs, ReadModifyResolveNode* emitExpressionInfoForMe)
1622 {
1623     ASSERT(isAdd());
1624     ASSERT(resultDescriptor().definitelyIsString());
1625
1626     // Create a list of expressions for all the adds in the tree of nodes we can convert into
1627     // a string concatenation.  The rightmost node (c) is added first.  The rightmost node is
1628     // added first, and the leftmost child is never added, so the vector produced for the
1629     // example above will be [ c, b ].
1630     Vector<ExpressionNode*, 16> reverseExpressionList;
1631     reverseExpressionList.append(m_expr2);
1632
1633     // Examine the left child of the add.  So long as this is a string add, add its right-child
1634     // to the list, and keep processing along the left fork.
1635     ExpressionNode* leftMostAddChild = m_expr1;
1636     while (leftMostAddChild->isAdd() && leftMostAddChild->resultDescriptor().definitelyIsString()) {
1637         reverseExpressionList.append(static_cast<AddNode*>(leftMostAddChild)->m_expr2);
1638         leftMostAddChild = static_cast<AddNode*>(leftMostAddChild)->m_expr1;
1639     }
1640
1641     Vector<RefPtr<RegisterID>, 16> temporaryRegisters;
1642
1643     // If there is an assignment, allocate a temporary to hold the lhs after conversion.
1644     // We could possibly avoid this (the lhs is converted last anyway, we could let the
1645     // op_strcat node handle its conversion if required).
1646     if (lhs)
1647         temporaryRegisters.append(generator.newTemporary());
1648
1649     // Emit code for the leftmost node ((a) in the example).
1650     temporaryRegisters.append(generator.newTemporary());
1651     RegisterID* leftMostAddChildTempRegister = temporaryRegisters.last().get();
1652     generator.emitNode(leftMostAddChildTempRegister, leftMostAddChild);
1653
1654     // Note on ordering of conversions:
1655     //
1656     // We maintain the same ordering of conversions as we would see if the concatenations
1657     // was performed as a sequence of adds (otherwise this optimization could change
1658     // behaviour should an object have been provided a valueOf or toString method).
1659     //
1660     // Considering the above example, the sequnce of execution is:
1661     //     * evaluate operand (a)
1662     //     * evaluate operand (b)
1663     //     * convert (a) to primitive   <-  (this would be triggered by the first add)
1664     //     * convert (b) to primitive   <-  (ditto)
1665     //     * evaluate operand (c)
1666     //     * convert (c) to primitive   <-  (this would be triggered by the second add)
1667     // And optionally, if there is an assignment:
1668     //     * convert (d) to primitive   <-  (this would be triggered by the assigning addition)
1669     //
1670     // As such we do not plant an op to convert the leftmost child now.  Instead, use
1671     // 'leftMostAddChildTempRegister' as a flag to trigger generation of the conversion
1672     // once the second node has been generated.  However, if the leftmost child is an
1673     // immediate we can trivially determine that no conversion will be required.
1674     // If this is the case
1675     if (leftMostAddChild->isString())
1676         leftMostAddChildTempRegister = 0;
1677
1678     while (reverseExpressionList.size()) {
1679         ExpressionNode* node = reverseExpressionList.last();
1680         reverseExpressionList.removeLast();
1681
1682         // Emit the code for the current node.
1683         temporaryRegisters.append(generator.newTemporary());
1684         generator.emitNode(temporaryRegisters.last().get(), node);
1685
1686         // On the first iteration of this loop, when we first reach this point we have just
1687         // generated the second node, which means it is time to convert the leftmost operand.
1688         if (leftMostAddChildTempRegister) {
1689             generator.emitToPrimitive(leftMostAddChildTempRegister, leftMostAddChildTempRegister);
1690             leftMostAddChildTempRegister = 0; // Only do this once.
1691         }
1692         // Plant a conversion for this node, if necessary.
1693         if (!node->isString())
1694             generator.emitToPrimitive(temporaryRegisters.last().get(), temporaryRegisters.last().get());
1695     }
1696     ASSERT(temporaryRegisters.size() >= 3);
1697
1698     // Certain read-modify nodes require expression info to be emitted *after* m_right has been generated.
1699     // If this is required the node is passed as 'emitExpressionInfoForMe'; do so now.
1700     if (emitExpressionInfoForMe)
1701         generator.emitExpressionInfo(emitExpressionInfoForMe->divot(), emitExpressionInfoForMe->divotStart(), emitExpressionInfoForMe->divotEnd());
1702     // If there is an assignment convert the lhs now.  This will also copy lhs to
1703     // the temporary register we allocated for it.
1704     if (lhs)
1705         generator.emitToPrimitive(temporaryRegisters[0].get(), lhs);
1706
1707     return generator.emitStrcat(generator.finalDestination(dst, temporaryRegisters[0].get()), temporaryRegisters[0].get(), temporaryRegisters.size());
1708 }
1709
1710 void BinaryOpNode::emitBytecodeInConditionContext(BytecodeGenerator& generator, Label* trueTarget, Label* falseTarget, FallThroughMode fallThroughMode)
1711 {
1712     TriState branchCondition;
1713     ExpressionNode* branchExpression;
1714     tryFoldToBranch(generator, branchCondition, branchExpression);
1715
1716     if (branchCondition == MixedTriState)
1717         ExpressionNode::emitBytecodeInConditionContext(generator, trueTarget, falseTarget, fallThroughMode);
1718     else if (branchCondition == TrueTriState)
1719         generator.emitNodeInConditionContext(branchExpression, trueTarget, falseTarget, fallThroughMode);
1720     else
1721         generator.emitNodeInConditionContext(branchExpression, falseTarget, trueTarget, invert(fallThroughMode));
1722 }
1723
1724 static inline bool canFoldToBranch(OpcodeID opcodeID, ExpressionNode* branchExpression, JSValue constant)
1725 {
1726     ResultType expressionType = branchExpression->resultDescriptor();
1727
1728     if (expressionType.definitelyIsBoolean() && constant.isBoolean())
1729         return true;
1730     else if (expressionType.definitelyIsBoolean() && constant.isInt32() && (constant.asInt32() == 0 || constant.asInt32() == 1))
1731         return opcodeID == op_eq || opcodeID == op_neq; // Strict equality is false in the case of type mismatch.
1732     else if (expressionType.isInt32() && constant.isInt32() && constant.asInt32() == 0)
1733         return true;
1734
1735     return false;
1736 }
1737
1738 void BinaryOpNode::tryFoldToBranch(BytecodeGenerator& generator, TriState& branchCondition, ExpressionNode*& branchExpression)
1739 {
1740     branchCondition = MixedTriState;
1741     branchExpression = 0;
1742
1743     ConstantNode* constant = 0;
1744     if (m_expr1->isConstant()) {
1745         constant = static_cast<ConstantNode*>(m_expr1);
1746         branchExpression = m_expr2;
1747     } else if (m_expr2->isConstant()) {
1748         constant = static_cast<ConstantNode*>(m_expr2);
1749         branchExpression = m_expr1;
1750     }
1751
1752     if (!constant)
1753         return;
1754     ASSERT(branchExpression);
1755
1756     OpcodeID opcodeID = this->opcodeID();
1757     JSValue value = constant->jsValue(generator);
1758     bool canFoldToBranch = JSC::canFoldToBranch(opcodeID, branchExpression, value);
1759     if (!canFoldToBranch)
1760         return;
1761
1762     if (opcodeID == op_eq || opcodeID == op_stricteq)
1763         branchCondition = triState(value.pureToBoolean());
1764     else if (opcodeID == op_neq || opcodeID == op_nstricteq)
1765         branchCondition = triState(!value.pureToBoolean());
1766 }
1767
1768 RegisterID* BinaryOpNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1769 {
1770     OpcodeID opcodeID = this->opcodeID();
1771
1772     if (opcodeID == op_add && m_expr1->isAdd() && m_expr1->resultDescriptor().definitelyIsString()) {
1773         generator.emitExpressionInfo(position(), position(), position());
1774         return emitStrcat(generator, dst);
1775     }
1776
1777     if (opcodeID == op_neq) {
1778         if (m_expr1->isNull() || m_expr2->isNull()) {
1779             RefPtr<RegisterID> src = generator.tempDestination(dst);
1780             generator.emitNode(src.get(), m_expr1->isNull() ? m_expr2 : m_expr1);
1781             return generator.emitUnaryOp(op_neq_null, generator.finalDestination(dst, src.get()), src.get());
1782         }
1783     }
1784
1785     ExpressionNode* left = m_expr1;
1786     ExpressionNode* right = m_expr2;
1787     if (opcodeID == op_neq || opcodeID == op_nstricteq) {
1788         if (left->isString())
1789             std::swap(left, right);
1790     }
1791
1792     RefPtr<RegisterID> src1 = generator.emitNodeForLeftHandSide(left, m_rightHasAssignments, right->isPure(generator));
1793     bool wasTypeof = generator.lastOpcodeID() == op_typeof;
1794     RefPtr<RegisterID> src2 = generator.emitNode(right);
1795     generator.emitExpressionInfo(position(), position(), position());
1796     if (wasTypeof && (opcodeID == op_neq || opcodeID == op_nstricteq)) {
1797         RefPtr<RegisterID> tmp = generator.tempDestination(dst);
1798         if (opcodeID == op_neq)
1799             generator.emitEqualityOp(op_eq, generator.finalDestination(tmp.get(), src1.get()), src1.get(), src2.get());
1800         else if (opcodeID == op_nstricteq)
1801             generator.emitEqualityOp(op_stricteq, generator.finalDestination(tmp.get(), src1.get()), src1.get(), src2.get());
1802         else
1803             RELEASE_ASSERT_NOT_REACHED();
1804         return generator.emitUnaryOp(op_not, generator.finalDestination(dst, tmp.get()), tmp.get());
1805     }
1806     RegisterID* result = generator.emitBinaryOp(opcodeID, generator.finalDestination(dst, src1.get()), src1.get(), src2.get(), OperandTypes(left->resultDescriptor(), right->resultDescriptor()));
1807     if (opcodeID == op_urshift && dst != generator.ignoredResult())
1808         return generator.emitUnaryOp(op_unsigned, result, result);
1809     return result;
1810 }
1811
1812 RegisterID* EqualNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1813 {
1814     if (m_expr1->isNull() || m_expr2->isNull()) {
1815         RefPtr<RegisterID> src = generator.tempDestination(dst);
1816         generator.emitNode(src.get(), m_expr1->isNull() ? m_expr2 : m_expr1);
1817         return generator.emitUnaryOp(op_eq_null, generator.finalDestination(dst, src.get()), src.get());
1818     }
1819
1820     ExpressionNode* left = m_expr1;
1821     ExpressionNode* right = m_expr2;
1822     if (left->isString())
1823         std::swap(left, right);
1824
1825     RefPtr<RegisterID> src1 = generator.emitNodeForLeftHandSide(left, m_rightHasAssignments, m_expr2->isPure(generator));
1826     RefPtr<RegisterID> src2 = generator.emitNode(right);
1827     return generator.emitEqualityOp(op_eq, generator.finalDestination(dst, src1.get()), src1.get(), src2.get());
1828 }
1829
1830 RegisterID* StrictEqualNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1831 {
1832     ExpressionNode* left = m_expr1;
1833     ExpressionNode* right = m_expr2;
1834     if (left->isString())
1835         std::swap(left, right);
1836
1837     RefPtr<RegisterID> src1 = generator.emitNodeForLeftHandSide(left, m_rightHasAssignments, m_expr2->isPure(generator));
1838     RefPtr<RegisterID> src2 = generator.emitNode(right);
1839     return generator.emitEqualityOp(op_stricteq, generator.finalDestination(dst, src1.get()), src1.get(), src2.get());
1840 }
1841
1842 RegisterID* ThrowableBinaryOpNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1843 {
1844     RefPtr<RegisterID> src1 = generator.emitNodeForLeftHandSide(m_expr1, m_rightHasAssignments, m_expr2->isPure(generator));
1845     RefPtr<RegisterID> src2 = generator.emitNode(m_expr2);
1846     generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
1847     return generator.emitBinaryOp(opcodeID(), generator.finalDestination(dst, src1.get()), src1.get(), src2.get(), OperandTypes(m_expr1->resultDescriptor(), m_expr2->resultDescriptor()));
1848 }
1849
1850 RegisterID* InstanceOfNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1851 {
1852     RefPtr<RegisterID> hasInstanceValue = generator.newTemporary();
1853     RefPtr<RegisterID> isObject = generator.newTemporary();
1854     RefPtr<RegisterID> isCustom = generator.newTemporary();
1855     RefPtr<RegisterID> prototype = generator.newTemporary();
1856     RefPtr<RegisterID> value = generator.emitNodeForLeftHandSide(m_expr1, m_rightHasAssignments, m_expr2->isPure(generator));
1857     RefPtr<RegisterID> constructor = generator.emitNode(m_expr2);
1858     RefPtr<RegisterID> dstReg = generator.finalDestination(dst, value.get());
1859     RefPtr<Label> custom = generator.newLabel();
1860     RefPtr<Label> done = generator.newLabel();
1861     RefPtr<Label> typeError = generator.newLabel();
1862
1863     generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
1864     generator.emitIsObject(isObject.get(), constructor.get());
1865     generator.emitJumpIfFalse(isObject.get(), typeError.get());
1866
1867     generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
1868     generator.emitGetById(hasInstanceValue.get(), constructor.get(), generator.vm()->propertyNames->hasInstanceSymbol);
1869
1870     generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
1871     generator.emitOverridesHasInstance(isCustom.get(), constructor.get(), hasInstanceValue.get());
1872
1873     generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
1874     generator.emitJumpIfTrue(isCustom.get(), custom.get());
1875
1876     generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
1877     generator.emitGetById(prototype.get(), constructor.get(), generator.vm()->propertyNames->prototype);
1878
1879     generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
1880     generator.emitInstanceOf(dstReg.get(), value.get(), prototype.get());
1881
1882     generator.emitJump(done.get());
1883
1884     generator.emitLabel(typeError.get());
1885     generator.emitThrowTypeError("Right hand side of instanceof is not an object");
1886
1887     generator.emitLabel(custom.get());
1888
1889     generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
1890     generator.emitInstanceOfCustom(dstReg.get(), value.get(), constructor.get(), hasInstanceValue.get());
1891
1892     generator.emitLabel(done.get());
1893
1894     return dstReg.get();
1895 }
1896
1897 // ------------------------------ LogicalOpNode ----------------------------
1898
1899 RegisterID* LogicalOpNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1900 {
1901     RefPtr<RegisterID> temp = generator.tempDestination(dst);
1902     RefPtr<Label> target = generator.newLabel();
1903     
1904     generator.emitNode(temp.get(), m_expr1);
1905     if (m_operator == OpLogicalAnd)
1906         generator.emitJumpIfFalse(temp.get(), target.get());
1907     else
1908         generator.emitJumpIfTrue(temp.get(), target.get());
1909     generator.emitNodeInTailPosition(temp.get(), m_expr2);
1910     generator.emitLabel(target.get());
1911
1912     return generator.moveToDestinationIfNeeded(dst, temp.get());
1913 }
1914
1915 void LogicalOpNode::emitBytecodeInConditionContext(BytecodeGenerator& generator, Label* trueTarget, Label* falseTarget, FallThroughMode fallThroughMode)
1916 {
1917     RefPtr<Label> afterExpr1 = generator.newLabel();
1918     if (m_operator == OpLogicalAnd)
1919         generator.emitNodeInConditionContext(m_expr1, afterExpr1.get(), falseTarget, FallThroughMeansTrue);
1920     else 
1921         generator.emitNodeInConditionContext(m_expr1, trueTarget, afterExpr1.get(), FallThroughMeansFalse);
1922     generator.emitLabel(afterExpr1.get());
1923
1924     generator.emitNodeInConditionContext(m_expr2, trueTarget, falseTarget, fallThroughMode);
1925 }
1926
1927 // ------------------------------ ConditionalNode ------------------------------
1928
1929 RegisterID* ConditionalNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1930 {
1931     RefPtr<RegisterID> newDst = generator.finalDestination(dst);
1932     RefPtr<Label> beforeElse = generator.newLabel();
1933     RefPtr<Label> afterElse = generator.newLabel();
1934
1935     RefPtr<Label> beforeThen = generator.newLabel();
1936     generator.emitNodeInConditionContext(m_logical, beforeThen.get(), beforeElse.get(), FallThroughMeansTrue);
1937     generator.emitLabel(beforeThen.get());
1938
1939     generator.emitProfileControlFlow(m_expr1->startOffset());
1940     generator.emitNodeInTailPosition(newDst.get(), m_expr1);
1941     generator.emitJump(afterElse.get());
1942
1943     generator.emitLabel(beforeElse.get());
1944     generator.emitProfileControlFlow(m_expr1->endOffset() + 1);
1945     generator.emitNodeInTailPosition(newDst.get(), m_expr2);
1946
1947     generator.emitLabel(afterElse.get());
1948
1949     generator.emitProfileControlFlow(m_expr2->endOffset() + 1);
1950
1951     return newDst.get();
1952 }
1953
1954 // ------------------------------ ReadModifyResolveNode -----------------------------------
1955
1956 // FIXME: should this be moved to be a method on BytecodeGenerator?
1957 static ALWAYS_INLINE RegisterID* emitReadModifyAssignment(BytecodeGenerator& generator, RegisterID* dst, RegisterID* src1, ExpressionNode* m_right, Operator oper, OperandTypes types, ReadModifyResolveNode* emitExpressionInfoForMe = 0)
1958 {
1959     OpcodeID opcodeID;
1960     switch (oper) {
1961         case OpMultEq:
1962             opcodeID = op_mul;
1963             break;
1964         case OpDivEq:
1965             opcodeID = op_div;
1966             break;
1967         case OpPlusEq:
1968             if (m_right->isAdd() && m_right->resultDescriptor().definitelyIsString())
1969                 return static_cast<AddNode*>(m_right)->emitStrcat(generator, dst, src1, emitExpressionInfoForMe);
1970             opcodeID = op_add;
1971             break;
1972         case OpMinusEq:
1973             opcodeID = op_sub;
1974             break;
1975         case OpLShift:
1976             opcodeID = op_lshift;
1977             break;
1978         case OpRShift:
1979             opcodeID = op_rshift;
1980             break;
1981         case OpURShift:
1982             opcodeID = op_urshift;
1983             break;
1984         case OpAndEq:
1985             opcodeID = op_bitand;
1986             break;
1987         case OpXOrEq:
1988             opcodeID = op_bitxor;
1989             break;
1990         case OpOrEq:
1991             opcodeID = op_bitor;
1992             break;
1993         case OpModEq:
1994             opcodeID = op_mod;
1995             break;
1996         case OpPowEq:
1997             opcodeID = op_pow;
1998             break;
1999         default:
2000             RELEASE_ASSERT_NOT_REACHED();
2001             return dst;
2002     }
2003
2004     RegisterID* src2 = generator.emitNode(m_right);
2005
2006     // Certain read-modify nodes require expression info to be emitted *after* m_right has been generated.
2007     // If this is required the node is passed as 'emitExpressionInfoForMe'; do so now.
2008     if (emitExpressionInfoForMe)
2009         generator.emitExpressionInfo(emitExpressionInfoForMe->divot(), emitExpressionInfoForMe->divotStart(), emitExpressionInfoForMe->divotEnd());
2010     RegisterID* result = generator.emitBinaryOp(opcodeID, dst, src1, src2, types);
2011     if (oper == OpURShift)
2012         return generator.emitUnaryOp(op_unsigned, result, result);
2013     return result;
2014 }
2015
2016 RegisterID* ReadModifyResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2017 {
2018     JSTextPosition newDivot = divotStart() + m_ident.length();
2019     Variable var = generator.variable(m_ident);
2020     if (RegisterID* local = var.local()) {
2021         generator.emitTDZCheckIfNecessary(var, local, nullptr);
2022         if (var.isReadOnly()) {
2023             generator.emitReadOnlyExceptionIfNeeded(var);
2024             RegisterID* result = emitReadModifyAssignment(generator, generator.finalDestination(dst), local, m_right, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()));
2025             generator.emitProfileType(result, divotStart(), divotEnd());
2026             return result;
2027         }
2028         
2029         if (generator.leftHandSideNeedsCopy(m_rightHasAssignments, m_right->isPure(generator))) {
2030             RefPtr<RegisterID> result = generator.newTemporary();
2031             generator.emitMove(result.get(), local);
2032             emitReadModifyAssignment(generator, result.get(), result.get(), m_right, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()));
2033             generator.emitMove(local, result.get());
2034             generator.invalidateForInContextForLocal(local);
2035             generator.emitProfileType(local, divotStart(), divotEnd());
2036             return generator.moveToDestinationIfNeeded(dst, result.get());
2037         }
2038         
2039         RegisterID* result = emitReadModifyAssignment(generator, local, local, m_right, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()));
2040         generator.invalidateForInContextForLocal(local);
2041         generator.emitProfileType(result, divotStart(), divotEnd());
2042         return generator.moveToDestinationIfNeeded(dst, result);
2043     }
2044
2045     generator.emitExpressionInfo(newDivot, divotStart(), newDivot);
2046     RefPtr<RegisterID> scope = generator.emitResolveScope(nullptr, var);
2047     RefPtr<RegisterID> value = generator.emitGetFromScope(generator.newTemporary(), scope.get(), var, ThrowIfNotFound);
2048     generator.emitTDZCheckIfNecessary(var, value.get(), nullptr);
2049     if (var.isReadOnly()) {
2050         bool threwException = generator.emitReadOnlyExceptionIfNeeded(var);
2051         if (threwException)
2052             return value.get();
2053     }
2054     RefPtr<RegisterID> result = emitReadModifyAssignment(generator, generator.finalDestination(dst, value.get()), value.get(), m_right, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()), this);
2055     RegisterID* returnResult = result.get();
2056     if (!var.isReadOnly()) {
2057         returnResult = generator.emitPutToScope(scope.get(), var, result.get(), ThrowIfNotFound, InitializationMode::NotInitialization);
2058         generator.emitProfileType(result.get(), var, divotStart(), divotEnd());
2059     }
2060     return returnResult;
2061 }
2062
2063 static InitializationMode initializationModeForAssignmentContext(AssignmentContext assignmentContext)
2064 {
2065     switch (assignmentContext) {
2066     case AssignmentContext::DeclarationStatement:
2067         return InitializationMode::Initialization;
2068     case AssignmentContext::ConstDeclarationStatement:
2069         return InitializationMode::ConstInitialization;
2070     case AssignmentContext::AssignmentExpression:
2071         return InitializationMode::NotInitialization;
2072     }
2073
2074     ASSERT_NOT_REACHED();
2075     return InitializationMode::NotInitialization;
2076 }
2077
2078 // ------------------------------ AssignResolveNode -----------------------------------
2079
2080 RegisterID* AssignResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2081 {
2082     Variable var = generator.variable(m_ident);
2083     bool isReadOnly = var.isReadOnly() && m_assignmentContext != AssignmentContext::ConstDeclarationStatement;
2084     if (RegisterID* local = var.local()) {
2085         RegisterID* result = nullptr;
2086         if (m_assignmentContext == AssignmentContext::AssignmentExpression)
2087             generator.emitTDZCheckIfNecessary(var, local, nullptr);
2088
2089         if (isReadOnly) {
2090             result = generator.emitNode(dst, m_right); // Execute side effects first.
2091             generator.emitReadOnlyExceptionIfNeeded(var);
2092             generator.emitProfileType(result, var, divotStart(), divotEnd());
2093         } else if (var.isSpecial()) {
2094             RefPtr<RegisterID> tempDst = generator.tempDestination(dst);
2095             generator.emitNode(tempDst.get(), m_right);
2096             generator.emitMove(local, tempDst.get());
2097             generator.emitProfileType(local, var, divotStart(), divotEnd());
2098             generator.invalidateForInContextForLocal(local);
2099             result = generator.moveToDestinationIfNeeded(dst, tempDst.get());
2100         } else {
2101             RegisterID* right = generator.emitNode(local, m_right);
2102             generator.emitProfileType(right, var, divotStart(), divotEnd());
2103             generator.invalidateForInContextForLocal(local);
2104             result = generator.moveToDestinationIfNeeded(dst, right);
2105         }
2106
2107         if (m_assignmentContext == AssignmentContext::DeclarationStatement || m_assignmentContext == AssignmentContext::ConstDeclarationStatement)
2108             generator.liftTDZCheckIfPossible(var);
2109         return result;
2110     }
2111
2112     if (generator.isStrictMode())
2113         generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
2114     RefPtr<RegisterID> scope = generator.emitResolveScope(nullptr, var);
2115     if (m_assignmentContext == AssignmentContext::AssignmentExpression)
2116         generator.emitTDZCheckIfNecessary(var, nullptr, scope.get());
2117     if (dst == generator.ignoredResult())
2118         dst = 0;
2119     RefPtr<RegisterID> result = generator.emitNode(dst, m_right);
2120     if (isReadOnly) {
2121         RegisterID* result = generator.emitNode(dst, m_right); // Execute side effects first.
2122         bool threwException = generator.emitReadOnlyExceptionIfNeeded(var);
2123         if (threwException)
2124             return result;
2125     }
2126     generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
2127     RegisterID* returnResult = result.get();
2128     if (!isReadOnly) {
2129         returnResult = generator.emitPutToScope(scope.get(), var, result.get(), generator.isStrictMode() ? ThrowIfNotFound : DoNotThrowIfNotFound, initializationModeForAssignmentContext(m_assignmentContext));
2130         generator.emitProfileType(result.get(), var, divotStart(), divotEnd());
2131     }
2132
2133     if (m_assignmentContext == AssignmentContext::DeclarationStatement || m_assignmentContext == AssignmentContext::ConstDeclarationStatement)
2134         generator.liftTDZCheckIfPossible(var);
2135     return returnResult;
2136 }
2137
2138 // ------------------------------ AssignDotNode -----------------------------------
2139
2140 RegisterID* AssignDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2141 {
2142     RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base, m_rightHasAssignments, m_right->isPure(generator));
2143     RefPtr<RegisterID> value = generator.destinationForAssignResult(dst);
2144     RefPtr<RegisterID> result = generator.emitNode(value.get(), m_right);
2145     generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
2146     RefPtr<RegisterID> forwardResult = (dst == generator.ignoredResult()) ? result.get() : generator.moveToDestinationIfNeeded(generator.tempDestination(result.get()), result.get());
2147     if (m_base->isSuperNode()) {
2148         RefPtr<RegisterID> thisValue = generator.ensureThis();
2149         generator.emitPutById(base.get(), thisValue.get(), m_ident, forwardResult.get());
2150     } else
2151         generator.emitPutById(base.get(), m_ident, forwardResult.get());
2152     generator.emitProfileType(forwardResult.get(), divotStart(), divotEnd());
2153     return generator.moveToDestinationIfNeeded(dst, forwardResult.get());
2154 }
2155
2156 // ------------------------------ ReadModifyDotNode -----------------------------------
2157
2158 RegisterID* ReadModifyDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2159 {
2160     RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base, m_rightHasAssignments, m_right->isPure(generator));
2161
2162     generator.emitExpressionInfo(subexpressionDivot(), subexpressionStart(), subexpressionEnd());
2163     RefPtr<RegisterID> value;
2164     RefPtr<RegisterID> thisValue;
2165     if (m_base->isSuperNode()) {
2166         thisValue = generator.ensureThis();
2167         value = generator.emitGetById(generator.tempDestination(dst), base.get(), thisValue.get(), m_ident);
2168     } else
2169         value = generator.emitGetById(generator.tempDestination(dst), base.get(), m_ident);
2170     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()));
2171
2172     generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
2173     RegisterID* ret;
2174     if (m_base->isSuperNode())
2175         ret = generator.emitPutById(base.get(), thisValue.get(), m_ident, updatedValue);
2176     else
2177         ret = generator.emitPutById(base.get(), m_ident, updatedValue);
2178     generator.emitProfileType(updatedValue, divotStart(), divotEnd());
2179     return ret;
2180 }
2181
2182 // ------------------------------ AssignErrorNode -----------------------------------
2183
2184 RegisterID* AssignErrorNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
2185 {
2186     return emitThrowReferenceError(generator, ASCIILiteral("Left side of assignment is not a reference."));
2187 }
2188
2189 // ------------------------------ AssignBracketNode -----------------------------------
2190
2191 RegisterID* AssignBracketNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2192 {
2193     RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base, m_subscriptHasAssignments || m_rightHasAssignments, m_subscript->isPure(generator) && m_right->isPure(generator));
2194     RefPtr<RegisterID> property = generator.emitNodeForLeftHandSide(m_subscript, m_rightHasAssignments, m_right->isPure(generator));
2195     RefPtr<RegisterID> value = generator.destinationForAssignResult(dst);
2196     RefPtr<RegisterID> result = generator.emitNode(value.get(), m_right);
2197
2198     generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
2199     RegisterID* forwardResult = (dst == generator.ignoredResult()) ? result.get() : generator.moveToDestinationIfNeeded(generator.tempDestination(result.get()), result.get());
2200
2201     if (isNonIndexStringElement(*m_subscript)) {
2202         if (m_base->isSuperNode()) {
2203             RefPtr<RegisterID> thisValue = generator.ensureThis();
2204             generator.emitPutById(base.get(), thisValue.get(), static_cast<StringNode*>(m_subscript)->value(), forwardResult);
2205         } else
2206             generator.emitPutById(base.get(), static_cast<StringNode*>(m_subscript)->value(), forwardResult);
2207     } else {
2208         if (m_base->isSuperNode()) {
2209             RefPtr<RegisterID> thisValue = generator.ensureThis();
2210             generator.emitPutByVal(base.get(), thisValue.get(), property.get(), forwardResult);
2211         } else
2212             generator.emitPutByVal(base.get(), property.get(), forwardResult);
2213     }
2214
2215     generator.emitProfileType(forwardResult, divotStart(), divotEnd());
2216     return generator.moveToDestinationIfNeeded(dst, forwardResult);
2217 }
2218
2219 // ------------------------------ ReadModifyBracketNode -----------------------------------
2220
2221 RegisterID* ReadModifyBracketNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2222 {
2223     RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base, m_subscriptHasAssignments || m_rightHasAssignments, m_subscript->isPure(generator) && m_right->isPure(generator));
2224     RefPtr<RegisterID> property = generator.emitNodeForLeftHandSide(m_subscript, m_rightHasAssignments, m_right->isPure(generator));
2225
2226     generator.emitExpressionInfo(subexpressionDivot(), subexpressionStart(), subexpressionEnd());
2227     RefPtr<RegisterID> value;
2228     RefPtr<RegisterID> thisValue;
2229     if (m_base->isSuperNode()) {
2230         thisValue = generator.ensureThis();
2231         value = generator.emitGetByVal(generator.tempDestination(dst), base.get(), thisValue.get(), property.get());
2232     } else
2233         value = generator.emitGetByVal(generator.tempDestination(dst), base.get(), property.get());
2234     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()));
2235
2236     generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
2237     if (m_base->isSuperNode())
2238         generator.emitPutByVal(base.get(), thisValue.get(), property.get(), updatedValue);
2239     else
2240         generator.emitPutByVal(base.get(), property.get(), updatedValue);
2241     generator.emitProfileType(updatedValue, divotStart(), divotEnd());
2242
2243     return updatedValue;
2244 }
2245
2246 // ------------------------------ CommaNode ------------------------------------
2247
2248 RegisterID* CommaNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2249 {
2250     CommaNode* node = this;
2251     for (; node && node->next(); node = node->next())
2252         generator.emitNode(generator.ignoredResult(), node->m_expr);
2253     return generator.emitNodeInTailPosition(dst, node->m_expr);
2254 }
2255
2256 // ------------------------------ SourceElements -------------------------------
2257
2258
2259 inline StatementNode* SourceElements::lastStatement() const
2260 {
2261     return m_tail;
2262 }
2263
2264 inline void SourceElements::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2265 {
2266     for (StatementNode* statement = m_head; statement; statement = statement->next())
2267         generator.emitNodeInTailPosition(dst, statement);
2268 }
2269
2270 // ------------------------------ BlockNode ------------------------------------
2271
2272 inline StatementNode* BlockNode::lastStatement() const
2273 {
2274     return m_statements ? m_statements->lastStatement() : 0;
2275 }
2276
2277 StatementNode* BlockNode::singleStatement() const
2278 {
2279     return m_statements ? m_statements->singleStatement() : 0;
2280 }
2281
2282 void BlockNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2283 {
2284     if (!m_statements)
2285         return;
2286     generator.pushLexicalScope(this, BytecodeGenerator::TDZCheckOptimization::Optimize, BytecodeGenerator::NestedScopeType::IsNested);
2287     m_statements->emitBytecode(generator, dst);
2288     generator.popLexicalScope(this);
2289 }
2290
2291 // ------------------------------ EmptyStatementNode ---------------------------
2292
2293 void EmptyStatementNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
2294 {
2295     generator.emitDebugHook(WillExecuteStatement, firstLine(), startOffset(), lineStartOffset());
2296 }
2297
2298 // ------------------------------ DebuggerStatementNode ---------------------------
2299
2300 void DebuggerStatementNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
2301 {
2302     generator.emitDebugHook(DidReachBreakpoint, lastLine(), startOffset(), lineStartOffset());
2303 }
2304
2305 // ------------------------------ ExprStatementNode ----------------------------
2306
2307 void ExprStatementNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2308 {
2309     ASSERT(m_expr);
2310     generator.emitDebugHook(WillExecuteStatement, firstLine(), startOffset(), lineStartOffset());
2311     generator.emitNode(dst, m_expr);
2312 }
2313
2314 // ------------------------------ DeclarationStatement ----------------------------
2315
2316 void DeclarationStatement::emitBytecode(BytecodeGenerator& generator, RegisterID*)
2317 {
2318     ASSERT(m_expr);
2319     generator.emitDebugHook(WillExecuteStatement, firstLine(), startOffset(), lineStartOffset());
2320     generator.emitNode(m_expr);
2321 }
2322
2323 // ------------------------------ EmptyVarExpression ----------------------------
2324
2325 RegisterID* EmptyVarExpression::emitBytecode(BytecodeGenerator& generator, RegisterID*)
2326 {
2327     // It's safe to return null here because this node will always be a child node of DeclarationStatement which ignores our return value.
2328     if (!generator.vm()->typeProfiler())
2329         return nullptr;
2330
2331     Variable var = generator.variable(m_ident);
2332     if (RegisterID* local = var.local())
2333         generator.emitProfileType(local, var, position(), JSTextPosition(-1, position().offset + m_ident.length(), -1));
2334     else {
2335         RefPtr<RegisterID> scope = generator.emitResolveScope(nullptr, var);
2336         RefPtr<RegisterID> value = generator.emitGetFromScope(generator.newTemporary(), scope.get(), var, DoNotThrowIfNotFound);
2337         generator.emitProfileType(value.get(), var, position(), JSTextPosition(-1, position().offset + m_ident.length(), -1));
2338     }
2339
2340     return nullptr;
2341 }
2342
2343 // ------------------------------ EmptyLetExpression ----------------------------
2344
2345 RegisterID* EmptyLetExpression::emitBytecode(BytecodeGenerator& generator, RegisterID*)
2346 {
2347     // Lexical declarations like 'let' must move undefined into their variables so we don't
2348     // get TDZ errors for situations like this: `let x; x;`
2349     Variable var = generator.variable(m_ident);
2350     if (RegisterID* local = var.local()) {
2351         generator.emitLoad(local, jsUndefined());
2352         generator.emitProfileType(local, var, position(), JSTextPosition(-1, position().offset + m_ident.length(), -1));
2353     } else {
2354         RefPtr<RegisterID> scope = generator.emitResolveScope(nullptr, var);
2355         RefPtr<RegisterID> value = generator.emitLoad(nullptr, jsUndefined());
2356         generator.emitPutToScope(scope.get(), var, value.get(), generator.isStrictMode() ? ThrowIfNotFound : DoNotThrowIfNotFound, InitializationMode::Initialization);
2357         generator.emitProfileType(value.get(), var, position(), JSTextPosition(-1, position().offset + m_ident.length(), -1)); 
2358     }
2359
2360     generator.liftTDZCheckIfPossible(var);
2361
2362     // It's safe to return null here because this node will always be a child node of DeclarationStatement which ignores our return value.
2363     return nullptr;
2364 }
2365
2366 // ------------------------------ IfElseNode ---------------------------------------
2367
2368 static inline StatementNode* singleStatement(StatementNode* statementNode)
2369 {
2370     if (statementNode->isBlock())
2371         return static_cast<BlockNode*>(statementNode)->singleStatement();
2372     return statementNode;
2373 }
2374
2375 bool IfElseNode::tryFoldBreakAndContinue(BytecodeGenerator& generator, StatementNode* ifBlock,
2376     Label*& trueTarget, FallThroughMode& fallThroughMode)
2377 {
2378     StatementNode* singleStatement = JSC::singleStatement(ifBlock);
2379     if (!singleStatement)
2380         return false;
2381
2382     if (singleStatement->isBreak()) {
2383         BreakNode* breakNode = static_cast<BreakNode*>(singleStatement);
2384         Label* target = breakNode->trivialTarget(generator);
2385         if (!target)
2386             return false;
2387         trueTarget = target;
2388         fallThroughMode = FallThroughMeansFalse;
2389         return true;
2390     }
2391
2392     if (singleStatement->isContinue()) {
2393         ContinueNode* continueNode = static_cast<ContinueNode*>(singleStatement);
2394         Label* target = continueNode->trivialTarget(generator);
2395         if (!target)
2396             return false;
2397         trueTarget = target;
2398         fallThroughMode = FallThroughMeansFalse;
2399         return true;
2400     }
2401
2402     return false;
2403 }
2404
2405 void IfElseNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2406 {
2407     generator.emitDebugHook(WillExecuteStatement, firstLine(), startOffset(), lineStartOffset());
2408     
2409     RefPtr<Label> beforeThen = generator.newLabel();
2410     RefPtr<Label> beforeElse = generator.newLabel();
2411     RefPtr<Label> afterElse = generator.newLabel();
2412
2413     Label* trueTarget = beforeThen.get();
2414     Label* falseTarget = beforeElse.get();
2415     FallThroughMode fallThroughMode = FallThroughMeansTrue;
2416     bool didFoldIfBlock = tryFoldBreakAndContinue(generator, m_ifBlock, trueTarget, fallThroughMode);
2417
2418     generator.emitNodeInConditionContext(m_condition, trueTarget, falseTarget, fallThroughMode);
2419     generator.emitLabel(beforeThen.get());
2420     generator.emitProfileControlFlow(m_ifBlock->startOffset());
2421
2422     if (!didFoldIfBlock) {
2423         generator.emitNodeInTailPosition(dst, m_ifBlock);
2424         if (m_elseBlock)
2425             generator.emitJump(afterElse.get());
2426     }
2427
2428     generator.emitLabel(beforeElse.get());
2429
2430     if (m_elseBlock) {
2431         generator.emitProfileControlFlow(m_ifBlock->endOffset() + (m_ifBlock->isBlock() ? 1 : 0));
2432         generator.emitNodeInTailPosition(dst, m_elseBlock);
2433     }
2434
2435     generator.emitLabel(afterElse.get());
2436     StatementNode* endingBlock = m_elseBlock ? m_elseBlock : m_ifBlock;
2437     generator.emitProfileControlFlow(endingBlock->endOffset() + (endingBlock->isBlock() ? 1 : 0));
2438 }
2439
2440 // ------------------------------ DoWhileNode ----------------------------------
2441
2442 void DoWhileNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2443 {
2444     LabelScopePtr scope = generator.newLabelScope(LabelScope::Loop);
2445
2446     RefPtr<Label> topOfLoop = generator.newLabel();
2447     generator.emitLabel(topOfLoop.get());
2448     generator.emitLoopHint();
2449     generator.emitDebugHook(WillExecuteStatement, lastLine(), startOffset(), lineStartOffset());
2450
2451     generator.emitNodeInTailPosition(dst, m_statement);
2452
2453     generator.emitLabel(scope->continueTarget());
2454     generator.emitDebugHook(WillExecuteStatement, lastLine(), startOffset(), lineStartOffset());
2455     generator.emitNodeInConditionContext(m_expr, topOfLoop.get(), scope->breakTarget(), FallThroughMeansFalse);
2456
2457     generator.emitLabel(scope->breakTarget());
2458 }
2459
2460 // ------------------------------ WhileNode ------------------------------------
2461
2462 void WhileNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2463 {
2464     LabelScopePtr scope = generator.newLabelScope(LabelScope::Loop);
2465     RefPtr<Label> topOfLoop = generator.newLabel();
2466
2467     generator.emitDebugHook(WillExecuteStatement, m_expr->firstLine(), m_expr->startOffset(), m_expr->lineStartOffset());
2468     generator.emitNodeInConditionContext(m_expr, topOfLoop.get(), scope->breakTarget(), FallThroughMeansTrue);
2469
2470     generator.emitLabel(topOfLoop.get());
2471     generator.emitLoopHint();
2472     
2473     generator.emitProfileControlFlow(m_statement->startOffset());
2474     generator.emitNodeInTailPosition(dst, m_statement);
2475
2476     generator.emitLabel(scope->continueTarget());
2477     generator.emitDebugHook(WillExecuteStatement, firstLine(), startOffset(), lineStartOffset());
2478
2479     generator.emitNodeInConditionContext(m_expr, topOfLoop.get(), scope->breakTarget(), FallThroughMeansFalse);
2480
2481     generator.emitLabel(scope->breakTarget());
2482
2483     generator.emitProfileControlFlow(m_statement->endOffset() + (m_statement->isBlock() ? 1 : 0));
2484 }
2485
2486 // ------------------------------ ForNode --------------------------------------
2487
2488 void ForNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2489 {
2490     LabelScopePtr scope = generator.newLabelScope(LabelScope::Loop);
2491
2492     RegisterID* forLoopSymbolTable = nullptr;
2493     generator.pushLexicalScope(this, BytecodeGenerator::TDZCheckOptimization::Optimize, BytecodeGenerator::NestedScopeType::IsNested, &forLoopSymbolTable);
2494
2495     generator.emitDebugHook(WillExecuteStatement, firstLine(), startOffset(), lineStartOffset());
2496
2497     if (m_expr1)
2498         generator.emitNode(generator.ignoredResult(), m_expr1);
2499     
2500     RefPtr<Label> topOfLoop = generator.newLabel();
2501     if (m_expr2)
2502         generator.emitNodeInConditionContext(m_expr2, topOfLoop.get(), scope->breakTarget(), FallThroughMeansTrue);
2503
2504     generator.emitLabel(topOfLoop.get());
2505     generator.emitLoopHint();
2506     generator.emitProfileControlFlow(m_statement->startOffset());
2507
2508     generator.emitNodeInTailPosition(dst, m_statement);
2509
2510     generator.emitLabel(scope->continueTarget());
2511     generator.emitDebugHook(WillExecuteStatement, firstLine(), startOffset(), lineStartOffset());
2512     generator.prepareLexicalScopeForNextForLoopIteration(this, forLoopSymbolTable);
2513     if (m_expr3)
2514         generator.emitNode(generator.ignoredResult(), m_expr3);
2515
2516     if (m_expr2)
2517         generator.emitNodeInConditionContext(m_expr2, topOfLoop.get(), scope->breakTarget(), FallThroughMeansFalse);
2518     else
2519         generator.emitJump(topOfLoop.get());
2520
2521     generator.emitLabel(scope->breakTarget());
2522     generator.popLexicalScope(this);
2523     generator.emitProfileControlFlow(m_statement->endOffset() + (m_statement->isBlock() ? 1 : 0));
2524 }
2525
2526 // ------------------------------ ForInNode ------------------------------------
2527
2528 RegisterID* ForInNode::tryGetBoundLocal(BytecodeGenerator& generator)
2529 {
2530     if (m_lexpr->isResolveNode()) {
2531         const Identifier& ident = static_cast<ResolveNode*>(m_lexpr)->identifier();
2532         return generator.variable(ident).local();
2533     }
2534
2535     if (m_lexpr->isDestructuringNode()) {
2536         DestructuringAssignmentNode* assignNode = static_cast<DestructuringAssignmentNode*>(m_lexpr);
2537         auto binding = assignNode->bindings();
2538         if (!binding->isBindingNode())
2539             return nullptr;
2540
2541         auto simpleBinding = static_cast<BindingNode*>(binding);
2542         const Identifier& ident = simpleBinding->boundProperty();
2543         Variable var = generator.variable(ident);
2544         if (var.isSpecial())
2545             return nullptr;
2546         return var.local();
2547     }
2548
2549     return nullptr;
2550 }
2551
2552 void ForInNode::emitLoopHeader(BytecodeGenerator& generator, RegisterID* propertyName)
2553 {
2554     if (m_lexpr->isResolveNode()) {
2555         const Identifier& ident = static_cast<ResolveNode*>(m_lexpr)->identifier();
2556         Variable var = generator.variable(ident);
2557         if (RegisterID* local = var.local())
2558             generator.emitMove(local, propertyName);
2559         else {
2560             if (generator.isStrictMode())
2561                 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
2562             RegisterID* scope = generator.emitResolveScope(nullptr, var);
2563             generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
2564             generator.emitPutToScope(scope, var, propertyName, generator.isStrictMode() ? ThrowIfNotFound : DoNotThrowIfNotFound, InitializationMode::NotInitialization);
2565         }
2566         generator.emitProfileType(propertyName, var, m_lexpr->position(), JSTextPosition(-1, m_lexpr->position().offset + ident.length(), -1));
2567         return;
2568     }
2569     if (m_lexpr->isDotAccessorNode()) {
2570         DotAccessorNode* assignNode = static_cast<DotAccessorNode*>(m_lexpr);
2571         const Identifier& ident = assignNode->identifier();
2572         RefPtr<RegisterID> base = generator.emitNode(assignNode->base());
2573         generator.emitExpressionInfo(assignNode->divot(), assignNode->divotStart(), assignNode->divotEnd());
2574         if (assignNode->base()->isSuperNode()) {
2575             RefPtr<RegisterID> thisValue = generator.ensureThis();
2576             generator.emitPutById(base.get(), thisValue.get(), ident, propertyName);
2577         } else
2578             generator.emitPutById(base.get(), ident, propertyName);
2579         generator.emitProfileType(propertyName, assignNode->divotStart(), assignNode->divotEnd());
2580         return;
2581     }
2582     if (m_lexpr->isBracketAccessorNode()) {
2583         BracketAccessorNode* assignNode = static_cast<BracketAccessorNode*>(m_lexpr);
2584         RefPtr<RegisterID> base = generator.emitNode(assignNode->base());
2585         RefPtr<RegisterID> subscript = generator.emitNode(assignNode->subscript());
2586         generator.emitExpressionInfo(assignNode->divot(), assignNode->divotStart(), assignNode->divotEnd());
2587         if (assignNode->base()->isSuperNode()) {
2588             RefPtr<RegisterID> thisValue = generator.ensureThis();
2589             generator.emitPutByVal(base.get(), thisValue.get(), subscript.get(), propertyName);
2590         } else
2591             generator.emitPutByVal(base.get(), subscript.get(), propertyName);
2592         generator.emitProfileType(propertyName, assignNode->divotStart(), assignNode->divotEnd());
2593         return;
2594     }
2595
2596     if (m_lexpr->isDestructuringNode()) {
2597         DestructuringAssignmentNode* assignNode = static_cast<DestructuringAssignmentNode*>(m_lexpr);
2598         auto binding = assignNode->bindings();
2599         if (!binding->isBindingNode()) {
2600             assignNode->bindings()->bindValue(generator, propertyName);
2601             return;
2602         }
2603
2604         auto simpleBinding = static_cast<BindingNode*>(binding);
2605         const Identifier& ident = simpleBinding->boundProperty();
2606         Variable var = generator.variable(ident);
2607         if (!var.local() || var.isSpecial()) {
2608             assignNode->bindings()->bindValue(generator, propertyName);
2609             return;
2610         }
2611         generator.emitMove(var.local(), propertyName);
2612         generator.emitProfileType(propertyName, var, simpleBinding->divotStart(), simpleBinding->divotEnd());
2613         return;
2614     }
2615
2616     RELEASE_ASSERT_NOT_REACHED();
2617 }
2618
2619 void ForInNode::emitMultiLoopBytecode(BytecodeGenerator& generator, RegisterID* dst)
2620 {
2621     if (!m_lexpr->isAssignmentLocation()) {
2622         emitThrowReferenceError(generator, ASCIILiteral("Left side of for-in statement is not a reference."));
2623         return;
2624     }
2625
2626     RefPtr<Label> end = generator.newLabel();
2627
2628     RegisterID* forLoopSymbolTable = nullptr;
2629     generator.pushLexicalScope(this, BytecodeGenerator::TDZCheckOptimization::Optimize, BytecodeGenerator::NestedScopeType::IsNested, &forLoopSymbolTable);
2630
2631     generator.emitDebugHook(WillExecuteStatement, firstLine(), startOffset(), lineStartOffset());
2632
2633     RefPtr<RegisterID> base = generator.newTemporary();
2634     RefPtr<RegisterID> length;
2635     RefPtr<RegisterID> enumerator;
2636     generator.emitNode(base.get(), m_expr);
2637     RefPtr<RegisterID> local = this->tryGetBoundLocal(generator);
2638     RefPtr<RegisterID> enumeratorIndex;
2639
2640     int profilerStartOffset = m_statement->startOffset();
2641     int profilerEndOffset = m_statement->endOffset() + (m_statement->isBlock() ? 1 : 0);
2642
2643     enumerator = generator.emitGetPropertyEnumerator(generator.newTemporary(), base.get());
2644
2645     // Indexed property loop.
2646     {
2647         LabelScopePtr scope = generator.newLabelScope(LabelScope::Loop);
2648         RefPtr<Label> loopStart = generator.newLabel();
2649         RefPtr<Label> loopEnd = generator.newLabel();
2650
2651         length = generator.emitGetEnumerableLength(generator.newTemporary(), enumerator.get());
2652         RefPtr<RegisterID> i = generator.emitLoad(generator.newTemporary(), jsNumber(0));
2653         RefPtr<RegisterID> propertyName = generator.newTemporary();
2654
2655         generator.emitLabel(loopStart.get());
2656         generator.emitLoopHint();
2657
2658         RefPtr<RegisterID> result = generator.emitEqualityOp(op_less, generator.newTemporary(), i.get(), length.get());
2659         generator.emitJumpIfFalse(result.get(), loopEnd.get());
2660         generator.emitHasIndexedProperty(result.get(), base.get(), i.get());
2661         generator.emitJumpIfFalse(result.get(), scope->continueTarget());
2662
2663         generator.emitToIndexString(propertyName.get(), i.get());
2664         this->emitLoopHeader(generator, propertyName.get());
2665
2666         generator.emitProfileControlFlow(profilerStartOffset);
2667
2668         generator.pushIndexedForInScope(local.get(), i.get());
2669         generator.emitNode(dst, m_statement);
2670         generator.popIndexedForInScope(local.get());
2671
2672         generator.emitProfileControlFlow(profilerEndOffset);
2673
2674         generator.emitLabel(scope->continueTarget());
2675         generator.prepareLexicalScopeForNextForLoopIteration(this, forLoopSymbolTable);
2676         generator.emitInc(i.get());
2677         generator.emitJump(loopStart.get());
2678
2679         generator.emitLabel(scope->breakTarget());
2680         generator.emitJump(end.get());
2681         generator.emitLabel(loopEnd.get());
2682     }
2683
2684     // Structure property loop.
2685     {
2686         LabelScopePtr scope = generator.newLabelScope(LabelScope::Loop);
2687         RefPtr<Label> loopStart = generator.newLabel();
2688         RefPtr<Label> loopEnd = generator.newLabel();
2689
2690         enumeratorIndex = generator.emitLoad(generator.newTemporary(), jsNumber(0));
2691         RefPtr<RegisterID> propertyName = generator.newTemporary();
2692         generator.emitEnumeratorStructurePropertyName(propertyName.get(), enumerator.get(), enumeratorIndex.get());
2693
2694         generator.emitLabel(loopStart.get());
2695         generator.emitLoopHint();
2696
2697         RefPtr<RegisterID> result = generator.emitUnaryOp(op_eq_null, generator.newTemporary(), propertyName.get());
2698         generator.emitJumpIfTrue(result.get(), loopEnd.get());
2699         generator.emitHasStructureProperty(result.get(), base.get(), propertyName.get(), enumerator.get());
2700         generator.emitJumpIfFalse(result.get(), scope->continueTarget());
2701
2702         this->emitLoopHeader(generator, propertyName.get());
2703
2704         generator.emitProfileControlFlow(profilerStartOffset);
2705
2706         generator.pushStructureForInScope(local.get(), enumeratorIndex.get(), propertyName.get(), enumerator.get());
2707         generator.emitNode(dst, m_statement);
2708         generator.popStructureForInScope(local.get());
2709
2710         generator.emitProfileControlFlow(profilerEndOffset);
2711
2712         generator.emitLabel(scope->continueTarget());
2713         generator.prepareLexicalScopeForNextForLoopIteration(this, forLoopSymbolTable);
2714         generator.emitInc(enumeratorIndex.get());
2715         generator.emitEnumeratorStructurePropertyName(propertyName.get(), enumerator.get(), enumeratorIndex.get());
2716         generator.emitJump(loopStart.get());
2717         
2718         generator.emitLabel(scope->breakTarget());
2719         generator.emitJump(end.get());
2720         generator.emitLabel(loopEnd.get());
2721     }
2722
2723     // Generic property loop.
2724     {
2725         LabelScopePtr scope = generator.newLabelScope(LabelScope::Loop);
2726         RefPtr<Label> loopStart = generator.newLabel();
2727         RefPtr<Label> loopEnd = generator.newLabel();
2728
2729         RefPtr<RegisterID> propertyName = generator.newTemporary();
2730
2731         generator.emitEnumeratorGenericPropertyName(propertyName.get(), enumerator.get(), enumeratorIndex.get());
2732
2733         generator.emitLabel(loopStart.get());
2734         generator.emitLoopHint();
2735
2736         RefPtr<RegisterID> result = generator.emitUnaryOp(op_eq_null, generator.newTemporary(), propertyName.get());
2737         generator.emitJumpIfTrue(result.get(), loopEnd.get());
2738
2739         generator.emitHasGenericProperty(result.get(), base.get(), propertyName.get());
2740         generator.emitJumpIfFalse(result.get(), scope->continueTarget());
2741
2742         this->emitLoopHeader(generator, propertyName.get());
2743
2744         generator.emitProfileControlFlow(profilerStartOffset);
2745
2746         generator.emitNode(dst, m_statement);
2747
2748         generator.emitLabel(scope->continueTarget());
2749         generator.prepareLexicalScopeForNextForLoopIteration(this, forLoopSymbolTable);
2750         generator.emitInc(enumeratorIndex.get());
2751         generator.emitEnumeratorGenericPropertyName(propertyName.get(), enumerator.get(), enumeratorIndex.get());
2752         generator.emitJump(loopStart.get());
2753
2754         generator.emitLabel(scope->breakTarget());
2755         generator.emitJump(end.get());
2756         generator.emitLabel(loopEnd.get());
2757     }
2758
2759     generator.emitDebugHook(WillExecuteStatement, firstLine(), startOffset(), lineStartOffset());
2760     generator.emitLabel(end.get());
2761     generator.popLexicalScope(this);
2762     generator.emitProfileControlFlow(profilerEndOffset);
2763 }
2764
2765 void ForInNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2766 {
2767     this->emitMultiLoopBytecode(generator, dst);
2768 }
2769
2770 // ------------------------------ ForOfNode ------------------------------------
2771 void ForOfNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2772 {
2773     if (!m_lexpr->isAssignmentLocation()) {
2774         emitThrowReferenceError(generator, ASCIILiteral("Left side of for-of statement is not a reference."));
2775         return;
2776     }
2777
2778     RegisterID* forLoopSymbolTable = nullptr;
2779     generator.pushLexicalScope(this, BytecodeGenerator::TDZCheckOptimization::Optimize, BytecodeGenerator::NestedScopeType::IsNested, &forLoopSymbolTable);
2780     generator.emitDebugHook(WillExecuteStatement, firstLine(), startOffset(), lineStartOffset());
2781     auto extractor = [this, dst](BytecodeGenerator& generator, RegisterID* value)
2782     {
2783         if (m_lexpr->isResolveNode()) {
2784             const Identifier& ident = static_cast<ResolveNode*>(m_lexpr)->identifier();
2785             Variable var = generator.variable(ident);
2786             if (RegisterID* local = var.local())
2787                 generator.emitMove(local, value);
2788             else {
2789                 if (generator.isStrictMode())
2790                     generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
2791                 RegisterID* scope = generator.emitResolveScope(nullptr, var);
2792                 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
2793                 generator.emitPutToScope(scope, var, value, generator.isStrictMode() ? ThrowIfNotFound : DoNotThrowIfNotFound, InitializationMode::NotInitialization);
2794             }
2795             generator.emitProfileType(value, var, m_lexpr->position(), JSTextPosition(-1, m_lexpr->position().offset + ident.length(), -1));
2796         } else if (m_lexpr->isDotAccessorNode()) {
2797             DotAccessorNode* assignNode = static_cast<DotAccessorNode*>(m_lexpr);
2798             const Identifier& ident = assignNode->identifier();
2799             RefPtr<RegisterID> base = generator.emitNode(assignNode->base());
2800             
2801             generator.emitExpressionInfo(assignNode->divot(), assignNode->divotStart(), assignNode->divotEnd());
2802             if (assignNode->base()->isSuperNode()) {
2803                 RefPtr<RegisterID> thisValue = generator.ensureThis();
2804                 generator.emitPutById(base.get(), thisValue.get(), ident, value);
2805             } else
2806                 generator.emitPutById(base.get(), ident, value);
2807             generator.emitProfileType(value, assignNode->divotStart(), assignNode->divotEnd());
2808         } else if (m_lexpr->isBracketAccessorNode()) {
2809             BracketAccessorNode* assignNode = static_cast<BracketAccessorNode*>(m_lexpr);
2810             RefPtr<RegisterID> base = generator.emitNode(assignNode->base());
2811             RegisterID* subscript = generator.emitNode(assignNode->subscript());
2812             
2813             generator.emitExpressionInfo(assignNode->divot(), assignNode->divotStart(), assignNode->divotEnd());
2814             if (assignNode->base()->isSuperNode()) {
2815                 RefPtr<RegisterID> thisValue = generator.ensureThis();
2816                 generator.emitPutByVal(base.get(), thisValue.get(), subscript, value);
2817             } else
2818                 generator.emitPutByVal(base.get(), subscript, value);
2819             generator.emitProfileType(value, assignNode->divotStart(), assignNode->divotEnd());
2820         } else {
2821             ASSERT(m_lexpr->isDestructuringNode());
2822             DestructuringAssignmentNode* assignNode = static_cast<DestructuringAssignmentNode*>(m_lexpr);
2823             assignNode->bindings()->bindValue(generator, value);
2824         }
2825         generator.emitProfileControlFlow(m_statement->startOffset());
2826         generator.emitNode(dst, m_statement);
2827     };
2828     generator.emitEnumeration(this, m_expr, extractor, this, forLoopSymbolTable);
2829     generator.popLexicalScope(this);
2830     generator.emitProfileControlFlow(m_statement->endOffset() + (m_statement->isBlock() ? 1 : 0));
2831 }
2832
2833 // ------------------------------ ContinueNode ---------------------------------
2834
2835 Label* ContinueNode::trivialTarget(BytecodeGenerator& generator)
2836 {
2837     if (generator.shouldEmitDebugHooks())
2838         return 0;
2839
2840     LabelScopePtr scope = generator.continueTarget(m_ident);
2841     ASSERT(scope);
2842
2843     if (generator.labelScopeDepth() != scope->scopeDepth())
2844         return 0;
2845
2846     return scope->continueTarget();
2847 }
2848
2849 void ContinueNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
2850 {
2851     generator.emitDebugHook(WillExecuteStatement, firstLine(), startOffset(), lineStartOffset());
2852     
2853     LabelScopePtr scope = generator.continueTarget(m_ident);
2854     ASSERT(scope);
2855
2856     generator.emitPopScopes(generator.scopeRegister(), scope->scopeDepth());
2857     generator.emitJump(scope->continueTarget());
2858
2859     generator.emitProfileControlFlow(endOffset());
2860 }
2861
2862 // ------------------------------ BreakNode ------------------------------------
2863
2864 Label* BreakNode::trivialTarget(BytecodeGenerator& generator)
2865 {
2866     if (generator.shouldEmitDebugHooks())
2867         return 0;
2868
2869     LabelScopePtr scope = generator.breakTarget(m_ident);
2870     ASSERT(scope);
2871
2872     if (generator.labelScopeDepth() != scope->scopeDepth())
2873         return 0;
2874
2875     return scope->breakTarget();
2876 }
2877
2878 void BreakNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
2879 {
2880     generator.emitDebugHook(WillExecuteStatement, firstLine(), startOffset(), lineStartOffset());
2881     
2882     LabelScopePtr scope = generator.breakTarget(m_ident);
2883     ASSERT(scope);
2884
2885     generator.emitPopScopes(generator.scopeRegister(), scope->scopeDepth());
2886     generator.emitJump(scope->breakTarget());
2887
2888     generator.emitProfileControlFlow(endOffset());
2889 }
2890
2891 // ------------------------------ ReturnNode -----------------------------------
2892
2893 void ReturnNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2894 {
2895     generator.emitDebugHook(WillExecuteStatement, firstLine(), startOffset(), lineStartOffset());
2896     ASSERT(generator.codeType() == FunctionCode);
2897
2898     if (dst == generator.ignoredResult())
2899         dst = 0;
2900
2901     RefPtr<RegisterID> returnRegister = m_value ? generator.emitNodeInTailPosition(dst, m_value) : generator.emitLoad(dst, jsUndefined());
2902
2903     generator.emitProfileType(returnRegister.get(), ProfileTypeBytecodeFunctionReturnStatement, divotStart(), divotEnd());
2904     if (generator.isInFinallyBlock()) {
2905         returnRegister = generator.emitMove(generator.newTemporary(), returnRegister.get());
2906         generator.emitPopScopes(generator.scopeRegister(), 0);
2907     }
2908
2909     generator.emitDebugHook(WillLeaveCallFrame, lastLine(), startOffset(), lineStartOffset());
2910     generator.emitReturn(returnRegister.get());
2911     generator.emitProfileControlFlow(endOffset()); 
2912     // Emitting an unreachable return here is needed in case this op_profile_control_flow is the 
2913     // last opcode in a CodeBlock because a CodeBlock's instructions must end with a terminal opcode.
2914     if (generator.vm()->controlFlowProfiler())
2915         generator.emitReturn(generator.emitLoad(nullptr, jsUndefined()));
2916 }
2917
2918 // ------------------------------ WithNode -------------------------------------
2919
2920 void WithNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2921 {
2922     generator.emitDebugHook(WillExecuteStatement, firstLine(), startOffset(), lineStartOffset());
2923
2924     RefPtr<RegisterID> scope = generator.emitNode(m_expr);
2925     generator.emitExpressionInfo(m_divot, m_divot - m_expressionLength, m_divot);
2926     generator.emitPushWithScope(scope.get());
2927     generator.emitNodeInTailPosition(dst, m_statement);
2928     generator.emitPopWithScope();
2929 }
2930
2931 // ------------------------------ CaseClauseNode --------------------------------
2932
2933 inline void CaseClauseNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2934 {
2935     generator.emitProfileControlFlow(m_startOffset);
2936     if (!m_statements)
2937         return;
2938     m_statements->emitBytecode(generator, dst);
2939 }
2940
2941 // ------------------------------ CaseBlockNode --------------------------------
2942
2943 enum SwitchKind { 
2944     SwitchUnset = 0,
2945     SwitchNumber = 1, 
2946     SwitchString = 2, 
2947     SwitchNeither = 3 
2948 };
2949
2950 static void processClauseList(ClauseListNode* list, Vector<ExpressionNode*, 8>& literalVector, SwitchKind& typeForTable, bool& singleCharacterSwitch, int32_t& min_num, int32_t& max_num)
2951 {
2952     for (; list; list = list->getNext()) {
2953         ExpressionNode* clauseExpression = list->getClause()->expr();
2954         literalVector.append(clauseExpression);
2955         if (clauseExpression->isNumber()) {
2956             double value = static_cast<NumberNode*>(clauseExpression)->value();
2957             int32_t intVal = static_cast<int32_t>(value);
2958             if ((typeForTable & ~SwitchNumber) || (intVal != value)) {
2959                 typeForTable = SwitchNeither;
2960                 break;
2961             }
2962             if (intVal < min_num)
2963                 min_num = intVal;
2964             if (intVal > max_num)
2965                 max_num = intVal;
2966             typeForTable = SwitchNumber;
2967             continue;
2968         }
2969         if (clauseExpression->isString()) {
2970             if (typeForTable & ~SwitchString) {
2971                 typeForTable = SwitchNeither;
2972                 break;
2973             }
2974             const String& value = static_cast<StringNode*>(clauseExpression)->value().string();
2975             if (singleCharacterSwitch &= value.length() == 1) {
2976                 int32_t intVal = value[0];
2977                 if (intVal < min_num)
2978                     min_num = intVal;
2979                 if (intVal > max_num)
2980                     max_num = intVal;
2981             }
2982             typeForTable = SwitchString;
2983             continue;
2984         }
2985         typeForTable = SwitchNeither;
2986         break;        
2987     }
2988 }
2989
2990 static inline size_t length(ClauseListNode* list1, ClauseListNode* list2)
2991 {
2992     size_t length = 0;
2993     for (ClauseListNode* node = list1; node; node = node->getNext())
2994         ++length;
2995     for (ClauseListNode* node = list2; node; node = node->getNext())
2996         ++length;
2997     return length;
2998 }
2999
3000 SwitchInfo::SwitchType CaseBlockNode::tryTableSwitch(Vector<ExpressionNode*, 8>& literalVector, int32_t& min_num, int32_t& max_num)
3001 {
3002     if (length(m_list1, m_list2) < s_tableSwitchMinimum)
3003         return SwitchInfo::SwitchNone;
3004
3005     SwitchKind typeForTable = SwitchUnset;
3006     bool singleCharacterSwitch = true;
3007     
3008     processClauseList(m_list1, literalVector, typeForTable, singleCharacterSwitch, min_num, max_num);
3009     processClauseList(m_list2, literalVector, typeForTable, singleCharacterSwitch, min_num, max_num);
3010     
3011     if (typeForTable == SwitchUnset || typeForTable == SwitchNeither)
3012         return SwitchInfo::SwitchNone;
3013     
3014     if (typeForTable == SwitchNumber) {
3015         int32_t range = max_num - min_num;
3016         if (min_num <= max_num && range <= 1000 && (range / literalVector.size()) < 10)
3017             return SwitchInfo::SwitchImmediate;
3018         return SwitchInfo::SwitchNone;
3019     } 
3020     
3021     ASSERT(typeForTable == SwitchString);
3022     
3023     if (singleCharacterSwitch) {
3024         int32_t range = max_num - min_num;
3025         if (min_num <= max_num && range <= 1000 && (range / literalVector.size()) < 10)
3026             return SwitchInfo::SwitchCharacter;
3027     }
3028
3029     return SwitchInfo::SwitchString;
3030 }
3031
3032 void CaseBlockNode::emitBytecodeForBlock(BytecodeGenerator& generator, RegisterID* switchExpression, RegisterID* dst)
3033 {
3034     RefPtr<Label> defaultLabel;
3035     Vector<RefPtr<Label>, 8> labelVector;
3036     Vector<ExpressionNode*, 8> literalVector;
3037     int32_t min_num = std::numeric_limits<int32_t>::max();
3038     int32_t max_num = std::numeric_limits<int32_t>::min();
3039     SwitchInfo::SwitchType switchType = tryTableSwitch(literalVector, min_num, max_num);
3040
3041     if (switchType != SwitchInfo::SwitchNone) {
3042         // Prepare the various labels
3043         for (uint32_t i = 0; i < literalVector.size(); i++)
3044             labelVector.append(generator.newLabel());
3045         defaultLabel = generator.newLabel();
3046         generator.beginSwitch(switchExpression, switchType);
3047     } else {
3048         // Setup jumps
3049         for (ClauseListNode* list = m_list1; list; list = list->getNext()) {
3050             RefPtr<RegisterID> clauseVal = generator.newTemporary();
3051             generator.emitNode(clauseVal.get(), list->getClause()->expr());
3052             generator.emitBinaryOp(op_stricteq, clauseVal.get(), clauseVal.get(), switchExpression, OperandTypes());
3053             labelVector.append(generator.newLabel());
3054             generator.emitJumpIfTrue(clauseVal.get(), labelVector[labelVector.size() - 1].get());
3055         }
3056         
3057         for (ClauseListNode* list = m_list2; list; list = list->getNext()) {
3058             RefPtr<RegisterID> clauseVal = generator.newTemporary();
3059             generator.emitNode(clauseVal.get(), list->getClause()->expr());
3060             generator.emitBinaryOp(op_stricteq, clauseVal.get(), clauseVal.get(), switchExpression, OperandTypes());
3061             labelVector.append(generator.newLabel());
3062             generator.emitJumpIfTrue(clauseVal.get(), labelVector[labelVector.size() - 1].get());
3063         }
3064         defaultLabel = generator.newLabel();
3065         generator.emitJump(defaultLabel.get());
3066     }
3067
3068     size_t i = 0;
3069     for (ClauseListNode* list = m_list1; list; list = list->getNext()) {
3070         generator.emitLabel(labelVector[i++].get());
3071         list->getClause()->emitBytecode(generator, dst);
3072     }
3073
3074     if (m_defaultClause) {
3075         generator.emitLabel(defaultLabel.get());
3076         m_defaultClause->emitBytecode(generator, dst);
3077     }
3078
3079     for (ClauseListNode* list = m_list2; list; list = list->getNext()) {
3080         generator.emitLabel(labelVector[i++].get());
3081         list->getClause()->emitBytecode(generator, dst);
3082     }
3083     if (!m_defaultClause)
3084         generator.emitLabel(defaultLabel.get());
3085
3086     ASSERT(i == labelVector.size());
3087     if (switchType != SwitchInfo::SwitchNone) {
3088         ASSERT(labelVector.size() == literalVector.size());
3089         generator.endSwitch(labelVector.size(), labelVector.data(), literalVector.data(), defaultLabel.get(), min_num, max_num);
3090     }
3091 }
3092
3093 // ------------------------------ SwitchNode -----------------------------------
3094
3095 void SwitchNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
3096 {
3097     generator.emitDebugHook(WillExecuteStatement, firstLine(), startOffset(), lineStartOffset());
3098     
3099     LabelScopePtr scope = generator.newLabelScope(LabelScope::Switch);
3100
3101     RefPtr<RegisterID> r0 = generator.emitNode(m_expr);
3102
3103     generator.pushLexicalScope(this, BytecodeGenerator::TDZCheckOptimization::DoNotOptimize, BytecodeGenerator::NestedScopeType::IsNested);
3104     m_block->emitBytecodeForBlock(generator, r0.get(), dst);
3105     generator.popLexicalScope(this);
3106
3107     generator.emitLabel(scope->breakTarget());
3108     generator.emitProfileControlFlow(endOffset());
3109 }
3110
3111 // ------------------------------ LabelNode ------------------------------------
3112
3113 void LabelNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
3114 {
3115     generator.emitDebugHook(WillExecuteStatement, firstLine(), startOffset(), lineStartOffset());
3116
3117     ASSERT(!generator.breakTarget(m_name));
3118
3119     LabelScopePtr scope = generator.newLabelScope(LabelScope::NamedLabel, &m_name);
3120     generator.emitNodeInTailPosition(dst, m_statement);
3121
3122     generator.emitLabel(scope->breakTarget());
3123 }
3124
3125 // ------------------------------ ThrowNode ------------------------------------
3126
3127 void ThrowNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
3128 {
3129     generator.emitDebugHook(WillExecuteStatement, firstLine(), startOffset(), lineStartOffset());
3130
3131     if (dst == generator.ignoredResult())
3132         dst = 0;
3133     RefPtr<RegisterID> expr = generator.emitNode(m_expr);
3134     generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
3135     generator.emitThrow(expr.get());
3136
3137     generator.emitProfileControlFlow(endOffset()); 
3138 }
3139
3140 // ------------------------------ TryNode --------------------------------------
3141
3142 void TryNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
3143 {
3144     // NOTE: The catch and finally blocks must be labeled explicitly, so the
3145     // optimizer knows they may be jumped to from anywhere.
3146
3147     generator.emitDebugHook(WillExecuteStatement, firstLine(), startOffset(), lineStartOffset());
3148
3149     ASSERT(m_catchBlock || m_finallyBlock);
3150
3151     RefPtr<Label> tryStartLabel = generator.newLabel();
3152     generator.emitLabel(tryStartLabel.get());
3153     
3154     if (m_finallyBlock)
3155         generator.pushFinallyContext(m_finallyBlock);
3156     TryData* tryData = generator.pushTry(tryStartLabel.get());
3157
3158     generator.emitNode(dst, m_tryBlock);
3159
3160     if (m_catchBlock) {
3161         RefPtr<Label> catchEndLabel = generator.newLabel();
3162         
3163         // Normal path: jump over the catch block.
3164         generator.emitJump(catchEndLabel.get());
3165
3166         // Uncaught exception path: the catch block.
3167         RefPtr<Label> here = generator.emitLabel(generator.newLabel().get());
3168         RefPtr<RegisterID> exceptionRegister = generator.newTemporary();
3169         RefPtr<RegisterID> thrownValueRegister = generator.newTemporary();
3170         generator.popTryAndEmitCatch(tryData, exceptionRegister.get(), thrownValueRegister.get(), here.get(), HandlerType::Catch);
3171         
3172         if (m_finallyBlock) {
3173             // If the catch block throws an exception and we have a finally block, then the finally
3174             // block should "catch" that exception.
3175             tryData = generator.pushTry(here.get());
3176         }
3177
3178         generator.emitPushCatchScope(m_lexicalVariables);
3179         m_catchPattern->bindValue(generator, thrownValueRegister.get());
3180         generator.emitProfileControlFlow(m_tryBlock->endOffset() + 1);
3181         if (m_finallyBlock)
3182             generator.emitNode(dst, m_catchBlock);
3183         else
3184             generator.emitNodeInTailPosition(dst, m_catchBlock);
3185         generator.emitLoad(thrownValueRegister.get(), jsUndefined());
3186         generator.emitPopCatchScope(m_lexicalVariables);
3187         generator.emitLabel(catchEndLabel.get());
3188     }
3189
3190     if (m_finallyBlock) {
3191         RefPtr<Label> preFinallyLabel = generator.emitLabel(generator.newLabel().get());
3192         
3193         generator.popFinallyContext();
3194
3195         RefPtr<Label> finallyEndLabel = generator.newLabel();
3196
3197         int finallyStartOffset = m_catchBlock ? m_catchBlock->endOffset() + 1 : m_tryBlock->endOffset() + 1;
3198
3199         // Normal path: run the finally code, and jump to the end.
3200         generator.emitProfileControlFlow(finallyStartOffset);
3201         generator.emitNodeInTailPosition(dst, m_finallyBlock);
3202         generator.emitProfileControlFlow(m_finallyBlock->endOffset() + 1);
3203         generator.emitJump(finallyEndLabel.get());
3204
3205         // Uncaught exception path: invoke the finally block, then re-throw the exception.
3206         RefPtr<RegisterID> exceptionRegister = generator.newTemporary();
3207         RefPtr<RegisterID> thrownValueRegister = generator.newTemporary();
3208         generator.popTryAndEmitCatch(tryData, exceptionRegister.get(), thrownValueRegister.get(), preFinallyLabel.get(), HandlerType::Finally);
3209         generator.emitProfileControlFlow(finallyStartOffset);
3210         generator.emitNodeInTailPosition(dst, m_finallyBlock);
3211         generator.emitThrow(exceptionRegister.get());
3212
3213         generator.emitLabel(finallyEndLabel.get());
3214         generator.emitProfileControlFlow(m_finallyBlock->endOffset() + 1);
3215     } else
3216         generator.emitProfileControlFlow(m_catchBlock->endOffset() + 1);
3217