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