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