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