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