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