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