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