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