129ffa357cf814c086b068ce46adab7c3cce5939
[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 "JSGlobalObject.h"
38 #include "JSNameScope.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)
150         generator.emitTDZCheck(generator.thisRegister());
151
152     if (dst == generator.ignoredResult())
153         return 0;
154
155     RegisterID* result = generator.moveToDestinationIfNeeded(dst, generator.thisRegister());
156     if (generator.vm()->typeProfiler()) {
157         generator.emitProfileType(generator.thisRegister(), ProfileTypeBytecodeDoesNotHaveGlobalID, nullptr);
158         static const unsigned thisLength = 4;
159         generator.emitTypeProfilerExpressionInfo(position(), JSTextPosition(-1, position().offset + thisLength, -1));
160     }
161     return result;
162 }
163
164 // ------------------------------ SuperNode -------------------------------------
165
166 RegisterID* SuperNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
167 {
168     if (dst == generator.ignoredResult())
169         return 0;
170
171     RegisterID callee;
172     callee.setIndex(JSStack::Callee);
173
174     RefPtr<RegisterID> homeObject = generator.emitGetById(generator.newTemporary(), &callee, generator.propertyNames().homeObjectPrivateName);
175     RefPtr<RegisterID> protoParent = generator.emitGetById(generator.newTemporary(), homeObject.get(), generator.propertyNames().underscoreProto);
176     return generator.emitGetById(generator.finalDestination(dst), protoParent.get(), generator.propertyNames().constructor);
177 }
178
179 static RegisterID* emitSuperBaseForCallee(BytecodeGenerator& generator)
180 {
181     RegisterID callee;
182     callee.setIndex(JSStack::Callee);
183
184     RefPtr<RegisterID> homeObject = generator.emitGetById(generator.newTemporary(), &callee, generator.propertyNames().homeObjectPrivateName);
185     return generator.emitGetById(generator.newTemporary(), homeObject.get(), generator.propertyNames().underscoreProto);
186 }
187
188 // ------------------------------ ResolveNode ----------------------------------
189
190 bool ResolveNode::isPure(BytecodeGenerator& generator) const
191 {
192     return generator.variable(m_ident).offset().isStack();
193 }
194
195 RegisterID* ResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
196 {
197     Variable var = generator.variable(m_ident);
198     if (RegisterID* local = var.local()) {
199         if (dst == generator.ignoredResult())
200             return nullptr;
201         if (generator.vm()->typeProfiler()) {
202             generator.emitProfileType(local, ProfileTypeBytecodeHasGlobalID, nullptr);
203             generator.emitTypeProfilerExpressionInfo(m_position, JSTextPosition(-1, m_position.offset + m_ident.length(), -1));
204         }
205         return generator.moveToDestinationIfNeeded(dst, local);
206     }
207     
208     JSTextPosition divot = m_start + m_ident.length();
209     generator.emitExpressionInfo(divot, m_start, divot);
210     RefPtr<RegisterID> scope = generator.emitResolveScope(dst, var);
211     RegisterID* finalDest = generator.finalDestination(dst);
212     RegisterID* result = generator.emitGetFromScope(finalDest, scope.get(), var, ThrowIfNotFound);
213     if (generator.vm()->typeProfiler()) {
214         generator.emitProfileType(finalDest, var.isResolved() ? ProfileTypeBytecodeGetFromLocalScope : ProfileTypeBytecodeGetFromScope, &m_ident);
215         generator.emitTypeProfilerExpressionInfo(m_position, JSTextPosition(-1, m_position.offset + m_ident.length(), -1));
216     }
217     return result;
218 }
219
220 #if ENABLE(ES6_TEMPLATE_LITERAL_SYNTAX)
221 // ------------------------------ TemplateStringNode -----------------------------------
222
223 RegisterID* TemplateStringNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
224 {
225     if (dst == generator.ignoredResult())
226         return nullptr;
227     return generator.emitLoad(dst, JSValue(generator.addStringConstant(cooked())));
228 }
229
230 // ------------------------------ TemplateLiteralNode -----------------------------------
231
232 RegisterID* TemplateLiteralNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
233 {
234     if (!m_templateExpressions) {
235         TemplateStringNode* templateString = m_templateStrings->value();
236         ASSERT_WITH_MESSAGE(!m_templateStrings->next(), "Only one template element exists because there's no expression in a given template literal.");
237         return generator.emitNode(dst, templateString);
238     }
239
240     Vector<RefPtr<RegisterID>, 16> temporaryRegisters;
241
242     TemplateStringListNode* templateString = m_templateStrings;
243     TemplateExpressionListNode* templateExpression = m_templateExpressions;
244     for (; templateExpression; templateExpression = templateExpression->next(), templateString = templateString->next()) {
245         // Evaluate TemplateString.
246         if (!templateString->value()->cooked().isEmpty()) {
247             temporaryRegisters.append(generator.newTemporary());
248             generator.emitNode(temporaryRegisters.last().get(), templateString->value());
249         }
250
251         // Evaluate Expression.
252         temporaryRegisters.append(generator.newTemporary());
253         generator.emitNode(temporaryRegisters.last().get(), templateExpression->value());
254         generator.emitToString(temporaryRegisters.last().get(), temporaryRegisters.last().get());
255     }
256
257     // Evaluate tail TemplateString.
258     if (!templateString->value()->cooked().isEmpty()) {
259         temporaryRegisters.append(generator.newTemporary());
260         generator.emitNode(temporaryRegisters.last().get(), templateString->value());
261     }
262
263     return generator.emitStrcat(generator.finalDestination(dst, temporaryRegisters[0].get()), temporaryRegisters[0].get(), temporaryRegisters.size());
264 }
265
266 // ------------------------------ TaggedTemplateNode -----------------------------------
267
268 RegisterID* TaggedTemplateNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
269 {
270     ExpectedFunction expectedFunction = NoExpectedFunction;
271     RefPtr<RegisterID> tag = nullptr;
272     RefPtr<RegisterID> base = nullptr;
273     if (!m_tag->isLocation()) {
274         tag = generator.newTemporary();
275         tag = generator.emitNode(tag.get(), m_tag);
276     } else if (m_tag->isResolveNode()) {
277         ResolveNode* resolve = static_cast<ResolveNode*>(m_tag);
278         const Identifier& identifier = resolve->identifier();
279         expectedFunction = generator.expectedFunctionForIdentifier(identifier);
280
281         Variable var = generator.variable(identifier);
282         if (RegisterID* local = var.local())
283             tag = generator.emitMove(generator.newTemporary(), local);
284         else {
285             tag = generator.newTemporary();
286             base = generator.newTemporary();
287
288             JSTextPosition newDivot = divotStart() + identifier.length();
289             generator.emitExpressionInfo(newDivot, divotStart(), newDivot);
290             generator.moveToDestinationIfNeeded(base.get(), generator.emitResolveScope(base.get(), var));
291             generator.emitGetFromScope(tag.get(), base.get(), var, ThrowIfNotFound);
292         }
293     } else if (m_tag->isBracketAccessorNode()) {
294         BracketAccessorNode* bracket = static_cast<BracketAccessorNode*>(m_tag);
295         base = generator.newTemporary();
296         base = generator.emitNode(base.get(), bracket->base());
297         RefPtr<RegisterID> property = generator.emitNode(bracket->subscript());
298         tag = generator.emitGetByVal(generator.newTemporary(), base.get(), property.get());
299     } else {
300         ASSERT(m_tag->isDotAccessorNode());
301         DotAccessorNode* dot = static_cast<DotAccessorNode*>(m_tag);
302         base = generator.newTemporary();
303         base = generator.emitNode(base.get(), dot->base());
304         tag = generator.emitGetById(generator.newTemporary(), base.get(), dot->identifier());
305     }
306
307     RefPtr<RegisterID> templateObject = generator.emitGetTemplateObject(generator.newTemporary(), this);
308
309     unsigned expressionsCount = 0;
310     for (TemplateExpressionListNode* templateExpression = m_templateLiteral->templateExpressions(); templateExpression; templateExpression = templateExpression->next())
311         ++expressionsCount;
312
313     CallArguments callArguments(generator, nullptr, 1 + expressionsCount);
314     if (base)
315         generator.emitMove(callArguments.thisRegister(), base.get());
316     else
317         generator.emitLoad(callArguments.thisRegister(), jsUndefined());
318
319     unsigned argumentIndex = 0;
320     generator.emitMove(callArguments.argumentRegister(argumentIndex++), templateObject.get());
321     for (TemplateExpressionListNode* templateExpression = m_templateLiteral->templateExpressions(); templateExpression; templateExpression = templateExpression->next())
322         generator.emitNode(callArguments.argumentRegister(argumentIndex++), templateExpression->value());
323
324     return generator.emitCall(generator.finalDestination(dst, tag.get()), tag.get(), expectedFunction, callArguments, divot(), divotStart(), divotEnd());
325 }
326 #endif
327
328 // ------------------------------ ArrayNode ------------------------------------
329
330 RegisterID* ArrayNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
331 {
332     // FIXME: Should we put all of this code into emitNewArray?
333
334     unsigned length = 0;
335     ElementNode* firstPutElement;
336     for (firstPutElement = m_element; firstPutElement; firstPutElement = firstPutElement->next()) {
337         if (firstPutElement->elision() || firstPutElement->value()->isSpreadExpression())
338             break;
339         ++length;
340     }
341
342     if (!firstPutElement && !m_elision)
343         return generator.emitNewArray(generator.finalDestination(dst), m_element, length);
344
345     RefPtr<RegisterID> array = generator.emitNewArray(generator.tempDestination(dst), m_element, length);
346     ElementNode* n = firstPutElement;
347     for (; n; n = n->next()) {
348         if (n->value()->isSpreadExpression())
349             goto handleSpread;
350         RegisterID* value = generator.emitNode(n->value());
351         length += n->elision();
352         generator.emitPutByIndex(array.get(), length++, value);
353     }
354
355     if (m_elision) {
356         RegisterID* value = generator.emitLoad(0, jsNumber(m_elision + length));
357         generator.emitPutById(array.get(), generator.propertyNames().length, value);
358     }
359
360     return generator.moveToDestinationIfNeeded(dst, array.get());
361     
362 handleSpread:
363     RefPtr<RegisterID> index = generator.emitLoad(generator.newTemporary(), jsNumber(length));
364     auto spreader = [this, array, index](BytecodeGenerator& generator, RegisterID* value)
365     {
366         generator.emitDirectPutByVal(array.get(), index.get(), value);
367         generator.emitInc(index.get());
368     };
369     for (; n; n = n->next()) {
370         if (n->elision())
371             generator.emitBinaryOp(op_add, index.get(), index.get(), generator.emitLoad(0, jsNumber(n->elision())), OperandTypes(ResultType::numberTypeIsInt32(), ResultType::numberTypeIsInt32()));
372         if (n->value()->isSpreadExpression()) {
373             SpreadExpressionNode* spread = static_cast<SpreadExpressionNode*>(n->value());
374             generator.emitEnumeration(spread, spread->expression(), spreader);
375         } else {
376             generator.emitDirectPutByVal(array.get(), index.get(), generator.emitNode(n->value()));
377             generator.emitInc(index.get());
378         }
379     }
380     
381     if (m_elision) {
382         generator.emitBinaryOp(op_add, index.get(), index.get(), generator.emitLoad(0, jsNumber(m_elision)), OperandTypes(ResultType::numberTypeIsInt32(), ResultType::numberTypeIsInt32()));
383         generator.emitPutById(array.get(), generator.propertyNames().length, index.get());
384     }
385     return generator.moveToDestinationIfNeeded(dst, array.get());
386 }
387
388 bool ArrayNode::isSimpleArray() const
389 {
390     if (m_elision || m_optional)
391         return false;
392     for (ElementNode* ptr = m_element; ptr; ptr = ptr->next()) {
393         if (ptr->elision())
394             return false;
395     }
396     return true;
397 }
398
399 ArgumentListNode* ArrayNode::toArgumentList(ParserArena& parserArena, int lineNumber, int startPosition) const
400 {
401     ASSERT(!m_elision && !m_optional);
402     ElementNode* ptr = m_element;
403     if (!ptr)
404         return 0;
405     JSTokenLocation location;
406     location.line = lineNumber;
407     location.startOffset = startPosition;
408     ArgumentListNode* head = new (parserArena) ArgumentListNode(location, ptr->value());
409     ArgumentListNode* tail = head;
410     ptr = ptr->next();
411     for (; ptr; ptr = ptr->next()) {
412         ASSERT(!ptr->elision());
413         tail = new (parserArena) ArgumentListNode(location, tail, ptr->value());
414     }
415     return head;
416 }
417
418 // ------------------------------ ObjectLiteralNode ----------------------------
419
420 RegisterID* ObjectLiteralNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
421 {
422     if (!m_list) {
423         if (dst == generator.ignoredResult())
424             return 0;
425         return generator.emitNewObject(generator.finalDestination(dst));
426     }
427     RefPtr<RegisterID> newObj = generator.emitNewObject(generator.tempDestination(dst));
428     generator.emitNode(newObj.get(), m_list);
429     return generator.moveToDestinationIfNeeded(dst, newObj.get());
430 }
431
432 // ------------------------------ PropertyListNode -----------------------------
433
434 static inline void emitPutHomeObject(BytecodeGenerator& generator, RegisterID* function, RegisterID* homeObject)
435 {
436     generator.emitPutById(function, generator.propertyNames().homeObjectPrivateName, homeObject);
437 }
438
439 RegisterID* PropertyListNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
440 {
441     // Fast case: this loop just handles regular value properties.
442     PropertyListNode* p = this;
443     for (; p && (p->m_node->m_type & PropertyNode::Constant); p = p->m_next)
444         emitPutConstantProperty(generator, dst, *p->m_node);
445
446     // Were there any get/set properties?
447     if (p) {
448         // Build a list of getter/setter pairs to try to put them at the same time. If we encounter
449         // a computed property, just emit everything as that may override previous values.
450         bool hasComputedProperty = false;
451
452         typedef std::pair<PropertyNode*, PropertyNode*> GetterSetterPair;
453         typedef HashMap<UniquedStringImpl*, GetterSetterPair, IdentifierRepHash> GetterSetterMap;
454         GetterSetterMap map;
455
456         // Build a map, pairing get/set values together.
457         for (PropertyListNode* q = p; q; q = q->m_next) {
458             PropertyNode* node = q->m_node;
459             if (node->m_type & PropertyNode::Computed) {
460                 hasComputedProperty = true;
461                 break;
462             }
463             if (node->m_type & PropertyNode::Constant)
464                 continue;
465
466             // Duplicates are possible.
467             GetterSetterPair pair(node, static_cast<PropertyNode*>(nullptr));
468             GetterSetterMap::AddResult result = map.add(node->name()->impl(), pair);
469             if (!result.isNewEntry) {
470                 if (result.iterator->value.first->m_type == node->m_type)
471                     result.iterator->value.first = node;
472                 else
473                     result.iterator->value.second = node;
474             }
475         }
476
477         // Iterate over the remaining properties in the list.
478         for (; p; p = p->m_next) {
479             PropertyNode* node = p->m_node;
480
481             // Handle regular values.
482             if (node->m_type & PropertyNode::Constant) {
483                 emitPutConstantProperty(generator, dst, *node);
484                 continue;
485             }
486
487             RegisterID* value = generator.emitNode(node->m_assign);
488             bool isClassProperty = node->needsSuperBinding();
489             if (isClassProperty)
490                 emitPutHomeObject(generator, value, dst);
491
492             ASSERT(node->m_type & (PropertyNode::Getter | PropertyNode::Setter));
493
494             // This is a get/set property which may be overridden by a computed property later.
495             if (hasComputedProperty) {
496                 if (node->m_type & PropertyNode::Getter)
497                     generator.emitPutGetterById(dst, *node->name(), value);
498                 else
499                     generator.emitPutSetterById(dst, *node->name(), value);
500                 continue;
501             }
502
503             // This is a get/set property pair.
504             GetterSetterMap::iterator it = map.find(node->name()->impl());
505             ASSERT(it != map.end());
506             GetterSetterPair& pair = it->value;
507
508             // Was this already generated as a part of its partner?
509             if (pair.second == node)
510                 continue;
511
512             // Generate the paired node now.
513             RefPtr<RegisterID> getterReg;
514             RefPtr<RegisterID> setterReg;
515             RegisterID* secondReg = nullptr;
516
517             if (node->m_type & PropertyNode::Getter) {
518                 getterReg = value;
519                 if (pair.second) {
520                     ASSERT(pair.second->m_type & PropertyNode::Setter);
521                     setterReg = generator.emitNode(pair.second->m_assign);
522                     secondReg = setterReg.get();
523                 } else {
524                     setterReg = generator.newTemporary();
525                     generator.emitLoad(setterReg.get(), jsUndefined());
526                 }
527             } else {
528                 ASSERT(node->m_type & PropertyNode::Setter);
529                 setterReg = value;
530                 if (pair.second) {
531                     ASSERT(pair.second->m_type & PropertyNode::Getter);
532                     getterReg = generator.emitNode(pair.second->m_assign);
533                     secondReg = getterReg.get();
534                 } else {
535                     getterReg = generator.newTemporary();
536                     generator.emitLoad(getterReg.get(), jsUndefined());
537                 }
538             }
539
540             ASSERT(!pair.second || isClassProperty == pair.second->needsSuperBinding());
541             if (isClassProperty && pair.second)
542                 emitPutHomeObject(generator, secondReg, dst);
543
544             if (isClassProperty) {
545                 RefPtr<RegisterID> propertyNameRegister = generator.emitLoad(generator.newTemporary(), *node->name());
546                 generator.emitCallDefineProperty(dst, propertyNameRegister.get(),
547                     nullptr, getterReg.get(), setterReg.get(), BytecodeGenerator::PropertyConfigurable, m_position);
548             } else
549                 generator.emitPutGetterSetter(dst, *node->name(), getterReg.get(), setterReg.get());
550         }
551     }
552
553     return dst;
554 }
555
556 void PropertyListNode::emitPutConstantProperty(BytecodeGenerator& generator, RegisterID* newObj, PropertyNode& node)
557 {
558     RefPtr<RegisterID> value = generator.emitNode(node.m_assign);
559     if (node.needsSuperBinding()) {
560         emitPutHomeObject(generator, value.get(), newObj);
561
562         RefPtr<RegisterID> propertyNameRegister;
563         if (node.name())
564             propertyNameRegister = generator.emitLoad(generator.newTemporary(), *node.name());
565         else
566             propertyNameRegister = generator.emitNode(node.m_expression);
567
568         generator.emitCallDefineProperty(newObj, propertyNameRegister.get(),
569             value.get(), nullptr, nullptr, BytecodeGenerator::PropertyConfigurable | BytecodeGenerator::PropertyWritable, m_position);
570         return;
571     }
572     if (const auto* identifier = node.name()) {
573         Optional<uint32_t> optionalIndex = parseIndex(*identifier);
574         if (!optionalIndex) {
575             generator.emitDirectPutById(newObj, *identifier, value.get(), node.putType());
576             return;
577         }
578
579         RefPtr<RegisterID> index = generator.emitLoad(generator.newTemporary(), jsNumber(optionalIndex.value()));
580         generator.emitDirectPutByVal(newObj, index.get(), value.get());
581         return;
582     }
583     RefPtr<RegisterID> propertyName = generator.emitNode(node.m_expression);
584     generator.emitDirectPutByVal(newObj, propertyName.get(), value.get());
585 }
586
587 // ------------------------------ BracketAccessorNode --------------------------------
588
589 RegisterID* BracketAccessorNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
590 {
591     if (m_base->isSuperNode()) {
592         // FIXME: Should we generate the profiler info?
593         if (m_subscript->isString()) {
594             const Identifier& id = static_cast<StringNode*>(m_subscript)->value();
595             return generator.emitGetById(generator.finalDestination(dst), emitSuperBaseForCallee(generator), id);
596         }
597         return generator.emitGetByVal(generator.finalDestination(dst), emitSuperBaseForCallee(generator), generator.emitNode(m_subscript));
598     }
599
600     RegisterID* ret;
601     RegisterID* finalDest = generator.finalDestination(dst);
602
603     if (m_subscript->isString()) {
604         RefPtr<RegisterID> base = generator.emitNode(m_base);
605         ret = generator.emitGetById(finalDest, base.get(), static_cast<StringNode*>(m_subscript)->value());
606     } else {
607         RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base, m_subscriptHasAssignments, m_subscript->isPure(generator));
608         RegisterID* property = generator.emitNode(m_subscript);
609         ret = generator.emitGetByVal(finalDest, base.get(), property);
610     }
611
612     generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
613
614     if (generator.vm()->typeProfiler()) {
615         generator.emitProfileType(finalDest, ProfileTypeBytecodeDoesNotHaveGlobalID, nullptr);
616         generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd());
617     }
618     return ret;
619 }
620
621 // ------------------------------ DotAccessorNode --------------------------------
622
623 RegisterID* DotAccessorNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
624 {
625     RefPtr<RegisterID> base = m_base->isSuperNode() ? emitSuperBaseForCallee(generator) : generator.emitNode(m_base);
626     generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
627     RegisterID* finalDest = generator.finalDestination(dst);
628     RegisterID* ret = generator.emitGetById(finalDest, base.get(), m_ident);
629     if (generator.vm()->typeProfiler()) {
630         generator.emitProfileType(finalDest, ProfileTypeBytecodeDoesNotHaveGlobalID, nullptr);
631         generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd());
632     }
633     return ret;
634 }
635
636 // ------------------------------ ArgumentListNode -----------------------------
637
638 RegisterID* ArgumentListNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
639 {
640     ASSERT(m_expr);
641     return generator.emitNode(dst, m_expr);
642 }
643
644 // ------------------------------ NewExprNode ----------------------------------
645
646 RegisterID* NewExprNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
647 {
648     ExpectedFunction expectedFunction;
649     if (m_expr->isResolveNode())
650         expectedFunction = generator.expectedFunctionForIdentifier(static_cast<ResolveNode*>(m_expr)->identifier());
651     else
652         expectedFunction = NoExpectedFunction;
653     RefPtr<RegisterID> func = generator.emitNode(m_expr);
654     RefPtr<RegisterID> returnValue = generator.finalDestination(dst, func.get());
655     CallArguments callArguments(generator, m_args);
656     generator.emitMove(callArguments.thisRegister(), func.get());
657     return generator.emitConstruct(returnValue.get(), func.get(), expectedFunction, callArguments, divot(), divotStart(), divotEnd());
658 }
659
660 CallArguments::CallArguments(BytecodeGenerator& generator, ArgumentsNode* argumentsNode, unsigned additionalArguments)
661     : m_argumentsNode(argumentsNode)
662     , m_padding(0)
663 {
664     if (generator.shouldEmitProfileHooks())
665         m_profileHookRegister = generator.newTemporary();
666
667     size_t argumentCountIncludingThis = 1 + additionalArguments; // 'this' register.
668     if (argumentsNode) {
669         for (ArgumentListNode* node = argumentsNode->m_listNode; node; node = node->m_next)
670             ++argumentCountIncludingThis;
671     }
672
673     m_argv.grow(argumentCountIncludingThis);
674     for (int i = argumentCountIncludingThis - 1; i >= 0; --i) {
675         m_argv[i] = generator.newTemporary();
676         ASSERT(static_cast<size_t>(i) == m_argv.size() - 1 || m_argv[i]->index() == m_argv[i + 1]->index() - 1);
677     }
678     
679     while (stackOffset() % stackAlignmentRegisters()) {
680         m_argv.insert(0, generator.newTemporary());
681         m_padding++;
682     }
683 }
684
685 // ------------------------------ EvalFunctionCallNode ----------------------------------
686
687 RegisterID* EvalFunctionCallNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
688 {
689     Variable var = generator.variable(generator.propertyNames().eval);
690     if (RegisterID* local = var.local()) {
691         RefPtr<RegisterID> func = generator.emitMove(generator.tempDestination(dst), local);
692         CallArguments callArguments(generator, m_args);
693         generator.emitLoad(callArguments.thisRegister(), jsUndefined());
694         return generator.emitCallEval(generator.finalDestination(dst, func.get()), func.get(), callArguments, divot(), divotStart(), divotEnd());
695     }
696
697     RefPtr<RegisterID> func = generator.newTemporary();
698     CallArguments callArguments(generator, m_args);
699     JSTextPosition newDivot = divotStart() + 4;
700     generator.emitExpressionInfo(newDivot, divotStart(), newDivot);
701     generator.moveToDestinationIfNeeded(
702         callArguments.thisRegister(),
703         generator.emitResolveScope(callArguments.thisRegister(), var));
704     generator.emitGetFromScope(func.get(), callArguments.thisRegister(), var, ThrowIfNotFound);
705     return generator.emitCallEval(generator.finalDestination(dst, func.get()), func.get(), callArguments, divot(), divotStart(), divotEnd());
706 }
707
708 // ------------------------------ FunctionCallValueNode ----------------------------------
709
710 RegisterID* FunctionCallValueNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
711 {
712     RefPtr<RegisterID> func = generator.emitNode(m_expr);
713     RefPtr<RegisterID> returnValue = generator.finalDestination(dst, func.get());
714     CallArguments callArguments(generator, m_args);
715     if (m_expr->isSuperNode()) {
716         ASSERT(generator.isConstructor());
717         ASSERT(generator.constructorKind() == ConstructorKind::Derived);
718         generator.emitMove(callArguments.thisRegister(), generator.newTarget());
719         RegisterID* ret = generator.emitConstruct(returnValue.get(), func.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
720         generator.emitMove(generator.thisRegister(), ret);
721         return ret;
722     }
723     generator.emitLoad(callArguments.thisRegister(), jsUndefined());
724     RegisterID* ret = generator.emitCall(returnValue.get(), func.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
725     if (generator.vm()->typeProfiler()) {
726         generator.emitProfileType(returnValue.get(), ProfileTypeBytecodeDoesNotHaveGlobalID, nullptr);
727         generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd());
728     }
729     return ret;
730 }
731
732 // ------------------------------ FunctionCallResolveNode ----------------------------------
733
734 RegisterID* FunctionCallResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
735 {
736     ExpectedFunction expectedFunction = generator.expectedFunctionForIdentifier(m_ident);
737
738     Variable var = generator.variable(m_ident);
739     if (RegisterID* local = var.local()) {
740         RefPtr<RegisterID> func = generator.emitMove(generator.tempDestination(dst), local);
741         RefPtr<RegisterID> returnValue = generator.finalDestination(dst, func.get());
742         CallArguments callArguments(generator, m_args);
743         generator.emitLoad(callArguments.thisRegister(), jsUndefined());
744         // This passes NoExpectedFunction because we expect that if the function is in a
745         // local variable, then it's not one of our built-in constructors.
746         RegisterID* ret = generator.emitCall(returnValue.get(), func.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
747         if (generator.vm()->typeProfiler()) {
748             generator.emitProfileType(returnValue.get(), ProfileTypeBytecodeDoesNotHaveGlobalID, nullptr);
749             generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd());
750         }
751         return ret;
752     }
753
754     RefPtr<RegisterID> func = generator.newTemporary();
755     RefPtr<RegisterID> returnValue = generator.finalDestination(dst, func.get());
756     CallArguments callArguments(generator, m_args);
757
758     JSTextPosition newDivot = divotStart() + m_ident.length();
759     generator.emitExpressionInfo(newDivot, divotStart(), newDivot);
760     generator.moveToDestinationIfNeeded(
761         callArguments.thisRegister(),
762         generator.emitResolveScope(callArguments.thisRegister(), var));
763     generator.emitGetFromScope(func.get(), callArguments.thisRegister(), var, ThrowIfNotFound);
764     RegisterID* ret = generator.emitCall(returnValue.get(), func.get(), expectedFunction, callArguments, divot(), divotStart(), divotEnd());
765     if (generator.vm()->typeProfiler()) {
766         generator.emitProfileType(returnValue.get(), ProfileTypeBytecodeDoesNotHaveGlobalID, nullptr);
767         generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd());
768     }
769     return ret;
770 }
771
772 // ------------------------------ BytecodeIntrinsicNode ----------------------------------
773
774 RegisterID* BytecodeIntrinsicNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
775 {
776     return (this->*m_emitter)(generator, dst);
777 }
778
779 RegisterID* BytecodeIntrinsicNode::emit_intrinsic_putByValDirect(BytecodeGenerator& generator, RegisterID* dst)
780 {
781     ArgumentListNode* node = m_args->m_listNode;
782     RefPtr<RegisterID> base = generator.emitNode(node);
783     node = node->m_next;
784     RefPtr<RegisterID> index = generator.emitNode(node);
785     node = node->m_next;
786     RefPtr<RegisterID> value = generator.emitNode(node);
787
788     ASSERT(!node->m_next);
789
790     return generator.moveToDestinationIfNeeded(dst, generator.emitDirectPutByVal(base.get(), index.get(), value.get()));
791 }
792
793 RegisterID* BytecodeIntrinsicNode::emit_intrinsic_toString(BytecodeGenerator& generator, RegisterID* dst)
794 {
795     ArgumentListNode* node = m_args->m_listNode;
796     RefPtr<RegisterID> src = generator.emitNode(node);
797     ASSERT(!node->m_next);
798
799     return generator.moveToDestinationIfNeeded(dst, generator.emitToString(generator.tempDestination(dst), src.get()));
800 }
801
802 // ------------------------------ FunctionCallBracketNode ----------------------------------
803
804 RegisterID* FunctionCallBracketNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
805 {
806     bool baseIsSuper = m_base->isSuperNode();
807     bool subscriptIsString = m_subscript->isString();
808
809     RefPtr<RegisterID> base;
810     if (baseIsSuper)
811         base = emitSuperBaseForCallee(generator);
812     else {
813         if (subscriptIsString)
814             base = generator.emitNode(m_base);
815         else
816             base = generator.emitNodeForLeftHandSide(m_base, m_subscriptHasAssignments, m_subscript->isPure(generator));
817     }
818
819     RefPtr<RegisterID> function;
820     if (subscriptIsString) {
821         generator.emitExpressionInfo(subexpressionDivot(), subexpressionStart(), subexpressionEnd());
822         function = generator.emitGetById(generator.tempDestination(dst), base.get(), static_cast<StringNode*>(m_subscript)->value());
823     } else {
824         RefPtr<RegisterID> property = generator.emitNode(m_subscript);
825         generator.emitExpressionInfo(subexpressionDivot(), subexpressionStart(), subexpressionEnd());
826         function = generator.emitGetByVal(generator.tempDestination(dst), base.get(), property.get());
827     }
828
829     RefPtr<RegisterID> returnValue = generator.finalDestination(dst, function.get());
830     CallArguments callArguments(generator, m_args);
831     if (baseIsSuper)
832         generator.emitMove(callArguments.thisRegister(), generator.thisRegister());
833     else
834         generator.emitMove(callArguments.thisRegister(), base.get());
835     RegisterID* ret = generator.emitCall(returnValue.get(), function.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
836     if (generator.vm()->typeProfiler()) {
837         generator.emitProfileType(returnValue.get(), ProfileTypeBytecodeDoesNotHaveGlobalID, nullptr);
838         generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd());
839     }
840     return ret;
841 }
842
843 // ------------------------------ FunctionCallDotNode ----------------------------------
844
845 RegisterID* FunctionCallDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
846 {
847     RefPtr<RegisterID> function = generator.tempDestination(dst);
848     RefPtr<RegisterID> returnValue = generator.finalDestination(dst, function.get());
849     CallArguments callArguments(generator, m_args);
850     bool baseIsSuper = m_base->isSuperNode();
851     if (baseIsSuper)
852         generator.emitMove(callArguments.thisRegister(), generator.thisRegister());
853     else
854         generator.emitNode(callArguments.thisRegister(), m_base);
855     generator.emitExpressionInfo(subexpressionDivot(), subexpressionStart(), subexpressionEnd());
856     generator.emitGetById(function.get(), baseIsSuper ? emitSuperBaseForCallee(generator) : callArguments.thisRegister(), m_ident);
857     RegisterID* ret = generator.emitCall(returnValue.get(), function.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
858     if (generator.vm()->typeProfiler()) {
859         generator.emitProfileType(returnValue.get(), ProfileTypeBytecodeDoesNotHaveGlobalID, nullptr);
860         generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd());
861     }
862     return ret;
863 }
864
865 RegisterID* CallFunctionCallDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
866 {
867     RefPtr<Label> realCall = generator.newLabel();
868     RefPtr<Label> end = generator.newLabel();
869     RefPtr<RegisterID> base = generator.emitNode(m_base);
870     generator.emitExpressionInfo(subexpressionDivot(), subexpressionStart(), subexpressionEnd());
871     RefPtr<RegisterID> function;
872     bool emitCallCheck = !generator.isBuiltinFunction();
873     if (emitCallCheck) {
874         function = generator.emitGetById(generator.tempDestination(dst), base.get(), generator.propertyNames().builtinNames().callPublicName());
875         generator.emitJumpIfNotFunctionCall(function.get(), realCall.get());
876     }
877     RefPtr<RegisterID> returnValue = generator.finalDestination(dst);
878     {
879         if (m_args->m_listNode && m_args->m_listNode->m_expr && m_args->m_listNode->m_expr->isSpreadExpression()) {
880             RefPtr<RegisterID> profileHookRegister;
881             if (generator.shouldEmitProfileHooks())
882                 profileHookRegister = generator.newTemporary();
883             SpreadExpressionNode* spread = static_cast<SpreadExpressionNode*>(m_args->m_listNode->m_expr);
884             ExpressionNode* subject = spread->expression();
885             RefPtr<RegisterID> argumentsRegister;
886             argumentsRegister = generator.emitNode(subject);
887             generator.emitExpressionInfo(spread->divot(), spread->divotStart(), spread->divotEnd());
888             RefPtr<RegisterID> thisRegister = generator.emitGetByVal(generator.newTemporary(), argumentsRegister.get(), generator.emitLoad(0, jsNumber(0)));
889             generator.emitCallVarargs(returnValue.get(), base.get(), thisRegister.get(), argumentsRegister.get(), generator.newTemporary(), 1, profileHookRegister.get(), divot(), divotStart(), divotEnd());
890         } else if (m_args->m_listNode && m_args->m_listNode->m_expr) {
891             ArgumentListNode* oldList = m_args->m_listNode;
892             m_args->m_listNode = m_args->m_listNode->m_next;
893
894             RefPtr<RegisterID> realFunction = generator.emitMove(generator.tempDestination(dst), base.get());
895             CallArguments callArguments(generator, m_args);
896             generator.emitNode(callArguments.thisRegister(), oldList->m_expr);
897             generator.emitCall(returnValue.get(), realFunction.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
898             m_args->m_listNode = oldList;
899         } else {
900             RefPtr<RegisterID> realFunction = generator.emitMove(generator.tempDestination(dst), base.get());
901             CallArguments callArguments(generator, m_args);
902             generator.emitLoad(callArguments.thisRegister(), jsUndefined());
903             generator.emitCall(returnValue.get(), realFunction.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
904         }
905     }
906     if (emitCallCheck) {
907         generator.emitJump(end.get());
908         generator.emitLabel(realCall.get());
909         {
910             CallArguments callArguments(generator, m_args);
911             generator.emitMove(callArguments.thisRegister(), base.get());
912             generator.emitCall(returnValue.get(), function.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
913         }
914         generator.emitLabel(end.get());
915     }
916     if (generator.vm()->typeProfiler()) {
917         generator.emitProfileType(returnValue.get(), ProfileTypeBytecodeDoesNotHaveGlobalID, nullptr);
918         generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd());
919     }
920     return returnValue.get();
921 }
922
923 static bool areTrivialApplyArguments(ArgumentsNode* args)
924 {
925     return !args->m_listNode || !args->m_listNode->m_expr || !args->m_listNode->m_next
926         || (!args->m_listNode->m_next->m_next && args->m_listNode->m_next->m_expr->isSimpleArray());
927 }
928
929 RegisterID* ApplyFunctionCallDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
930 {
931     // A few simple cases can be trivially handled as ordinary function calls.
932     // function.apply(), function.apply(arg) -> identical to function.call
933     // function.apply(thisArg, [arg0, arg1, ...]) -> can be trivially coerced into function.call(thisArg, arg0, arg1, ...) and saves object allocation
934     bool mayBeCall = areTrivialApplyArguments(m_args);
935
936     RefPtr<Label> realCall = generator.newLabel();
937     RefPtr<Label> end = generator.newLabel();
938     RefPtr<RegisterID> base = generator.emitNode(m_base);
939     generator.emitExpressionInfo(subexpressionDivot(), subexpressionStart(), subexpressionEnd());
940     RefPtr<RegisterID> function;
941     RefPtr<RegisterID> returnValue = generator.finalDestination(dst, function.get());
942     bool emitCallCheck = !generator.isBuiltinFunction();
943     if (emitCallCheck) {
944         function = generator.emitGetById(generator.tempDestination(dst), base.get(), generator.propertyNames().builtinNames().applyPublicName());
945         generator.emitJumpIfNotFunctionApply(function.get(), realCall.get());
946     }
947     if (mayBeCall) {
948         if (m_args->m_listNode && m_args->m_listNode->m_expr) {
949             ArgumentListNode* oldList = m_args->m_listNode;
950             if (m_args->m_listNode->m_expr->isSpreadExpression()) {
951                 SpreadExpressionNode* spread = static_cast<SpreadExpressionNode*>(m_args->m_listNode->m_expr);
952                 RefPtr<RegisterID> profileHookRegister;
953                 if (generator.shouldEmitProfileHooks())
954                     profileHookRegister = generator.newTemporary();
955                 RefPtr<RegisterID> realFunction = generator.emitMove(generator.newTemporary(), base.get());
956                 RefPtr<RegisterID> index = generator.emitLoad(generator.newTemporary(), jsNumber(0));
957                 RefPtr<RegisterID> thisRegister = generator.emitLoad(generator.newTemporary(), jsUndefined());
958                 RefPtr<RegisterID> argumentsRegister = generator.emitLoad(generator.newTemporary(), jsUndefined());
959                 
960                 auto extractor = [&thisRegister, &argumentsRegister, &index](BytecodeGenerator& generator, RegisterID* value)
961                 {
962                     RefPtr<Label> haveThis = generator.newLabel();
963                     RefPtr<Label> end = generator.newLabel();
964                     RefPtr<RegisterID> compareResult = generator.newTemporary();
965                     RefPtr<RegisterID> indexZeroCompareResult = generator.emitBinaryOp(op_eq, compareResult.get(), index.get(), generator.emitLoad(0, jsNumber(0)), OperandTypes(ResultType::numberTypeIsInt32(), ResultType::numberTypeIsInt32()));
966                     generator.emitJumpIfFalse(indexZeroCompareResult.get(), haveThis.get());
967                     generator.emitMove(thisRegister.get(), value);
968                     generator.emitLoad(index.get(), jsNumber(1));
969                     generator.emitJump(end.get());
970                     generator.emitLabel(haveThis.get());
971                     RefPtr<RegisterID> indexOneCompareResult = generator.emitBinaryOp(op_eq, compareResult.get(), index.get(), generator.emitLoad(0, jsNumber(1)), OperandTypes(ResultType::numberTypeIsInt32(), ResultType::numberTypeIsInt32()));
972                     generator.emitJumpIfFalse(indexOneCompareResult.get(), end.get());
973                     generator.emitMove(argumentsRegister.get(), value);
974                     generator.emitLoad(index.get(), jsNumber(2));
975                     generator.emitLabel(end.get());
976                 };
977                 generator.emitEnumeration(this, spread->expression(), extractor);
978                 generator.emitCallVarargs(returnValue.get(), realFunction.get(), thisRegister.get(), argumentsRegister.get(), generator.newTemporary(), 0, profileHookRegister.get(), divot(), divotStart(), divotEnd());
979             } else if (m_args->m_listNode->m_next) {
980                 ASSERT(m_args->m_listNode->m_next->m_expr->isSimpleArray());
981                 ASSERT(!m_args->m_listNode->m_next->m_next);
982                 m_args->m_listNode = static_cast<ArrayNode*>(m_args->m_listNode->m_next->m_expr)->toArgumentList(generator.parserArena(), 0, 0);
983                 RefPtr<RegisterID> realFunction = generator.emitMove(generator.tempDestination(dst), base.get());
984                 CallArguments callArguments(generator, m_args);
985                 generator.emitNode(callArguments.thisRegister(), oldList->m_expr);
986                 generator.emitCall(returnValue.get(), realFunction.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
987             } else {
988                 m_args->m_listNode = m_args->m_listNode->m_next;
989                 RefPtr<RegisterID> realFunction = generator.emitMove(generator.tempDestination(dst), base.get());
990                 CallArguments callArguments(generator, m_args);
991                 generator.emitNode(callArguments.thisRegister(), oldList->m_expr);
992                 generator.emitCall(returnValue.get(), realFunction.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
993             }
994             m_args->m_listNode = oldList;
995         } else {
996             RefPtr<RegisterID> realFunction = generator.emitMove(generator.tempDestination(dst), base.get());
997             CallArguments callArguments(generator, m_args);
998             generator.emitLoad(callArguments.thisRegister(), jsUndefined());
999             generator.emitCall(returnValue.get(), realFunction.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
1000         }
1001     } else {
1002         ASSERT(m_args->m_listNode && m_args->m_listNode->m_next);
1003         RefPtr<RegisterID> profileHookRegister;
1004         if (generator.shouldEmitProfileHooks())
1005             profileHookRegister = generator.newTemporary();
1006         RefPtr<RegisterID> realFunction = generator.emitMove(generator.tempDestination(dst), base.get());
1007         RefPtr<RegisterID> thisRegister = generator.emitNode(m_args->m_listNode->m_expr);
1008         RefPtr<RegisterID> argsRegister;
1009         ArgumentListNode* args = m_args->m_listNode->m_next;
1010         argsRegister = generator.emitNode(args->m_expr);
1011
1012         // Function.prototype.apply ignores extra arguments, but we still
1013         // need to evaluate them for side effects.
1014         while ((args = args->m_next))
1015             generator.emitNode(args->m_expr);
1016
1017         generator.emitCallVarargs(returnValue.get(), realFunction.get(), thisRegister.get(), argsRegister.get(), generator.newTemporary(), 0, profileHookRegister.get(), divot(), divotStart(), divotEnd());
1018     }
1019     if (emitCallCheck) {
1020         generator.emitJump(end.get());
1021         generator.emitLabel(realCall.get());
1022         CallArguments callArguments(generator, m_args);
1023         generator.emitMove(callArguments.thisRegister(), base.get());
1024         generator.emitCall(returnValue.get(), function.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd());
1025         generator.emitLabel(end.get());
1026     }
1027     if (generator.vm()->typeProfiler()) {
1028         generator.emitProfileType(returnValue.get(), ProfileTypeBytecodeDoesNotHaveGlobalID, nullptr);
1029         generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd());
1030     }
1031     return returnValue.get();
1032 }
1033
1034 // ------------------------------ PostfixNode ----------------------------------
1035
1036 static RegisterID* emitIncOrDec(BytecodeGenerator& generator, RegisterID* srcDst, Operator oper)
1037 {
1038     return (oper == OpPlusPlus) ? generator.emitInc(srcDst) : generator.emitDec(srcDst);
1039 }
1040
1041 static RegisterID* emitPostIncOrDec(BytecodeGenerator& generator, RegisterID* dst, RegisterID* srcDst, Operator oper)
1042 {
1043     if (dst == srcDst)
1044         return generator.emitToNumber(generator.finalDestination(dst), srcDst);
1045     RefPtr<RegisterID> tmp = generator.emitToNumber(generator.tempDestination(dst), srcDst);
1046     emitIncOrDec(generator, srcDst, oper);
1047     return generator.moveToDestinationIfNeeded(dst, tmp.get());
1048 }
1049
1050 RegisterID* PostfixNode::emitResolve(BytecodeGenerator& generator, RegisterID* dst)
1051 {
1052     if (dst == generator.ignoredResult())
1053         return PrefixNode::emitResolve(generator, dst);
1054
1055     ASSERT(m_expr->isResolveNode());
1056     ResolveNode* resolve = static_cast<ResolveNode*>(m_expr);
1057     const Identifier& ident = resolve->identifier();
1058
1059     Variable var = generator.variable(ident);
1060     if (RegisterID* local = var.local()) {
1061         RefPtr<RegisterID> localReg = local;
1062         if (var.isReadOnly()) {
1063             generator.emitReadOnlyExceptionIfNeeded();
1064             localReg = generator.emitMove(generator.tempDestination(dst), local);
1065         } else if (generator.vm()->typeProfiler()) {
1066             RefPtr<RegisterID> tempDst = generator.finalDestination(dst);
1067             ASSERT(dst != localReg);
1068             RefPtr<RegisterID> tempDstSrc = generator.newTemporary();
1069             generator.emitToNumber(tempDst.get(), localReg.get());
1070             generator.emitMove(tempDstSrc.get(), localReg.get());
1071             emitIncOrDec(generator, tempDstSrc.get(), m_operator);
1072             generator.emitMove(localReg.get(), tempDstSrc.get());
1073             if (generator.vm()->typeProfiler())
1074                 generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd());
1075             return tempDst.get();
1076         }
1077         return emitPostIncOrDec(generator, generator.finalDestination(dst), localReg.get(), m_operator);
1078     }
1079
1080     generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
1081     RefPtr<RegisterID> scope = generator.emitResolveScope(nullptr, var);
1082     RefPtr<RegisterID> value = generator.emitGetFromScope(generator.newTemporary(), scope.get(), var, ThrowIfNotFound);
1083     RefPtr<RegisterID> oldValue = emitPostIncOrDec(generator, generator.finalDestination(dst), value.get(), m_operator);
1084     generator.emitPutToScope(scope.get(), var, value.get(), ThrowIfNotFound);
1085     if (generator.vm()->typeProfiler()) {
1086         generator.emitProfileType(value.get(), var.isResolved() ? ProfileTypeBytecodePutToLocalScope : ProfileTypeBytecodePutToScope, &ident);
1087         generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd());
1088     }
1089
1090     return oldValue.get();
1091 }
1092
1093 RegisterID* PostfixNode::emitBracket(BytecodeGenerator& generator, RegisterID* dst)
1094 {
1095     if (dst == generator.ignoredResult())
1096         return PrefixNode::emitBracket(generator, dst);
1097
1098     ASSERT(m_expr->isBracketAccessorNode());
1099     BracketAccessorNode* bracketAccessor = static_cast<BracketAccessorNode*>(m_expr);
1100     ExpressionNode* baseNode = bracketAccessor->base();
1101     ExpressionNode* subscript = bracketAccessor->subscript();
1102
1103     RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(baseNode, bracketAccessor->subscriptHasAssignments(), subscript->isPure(generator));
1104     RefPtr<RegisterID> property = generator.emitNode(subscript);
1105
1106     generator.emitExpressionInfo(bracketAccessor->divot(), bracketAccessor->divotStart(), bracketAccessor->divotEnd());
1107     RefPtr<RegisterID> value = generator.emitGetByVal(generator.newTemporary(), base.get(), property.get());
1108     RegisterID* oldValue = emitPostIncOrDec(generator, generator.tempDestination(dst), value.get(), m_operator);
1109     generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
1110     generator.emitPutByVal(base.get(), property.get(), value.get());
1111     if (generator.vm()->typeProfiler()) {
1112         generator.emitProfileType(value.get(), ProfileTypeBytecodeDoesNotHaveGlobalID, nullptr);
1113         generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd());
1114     }
1115     return generator.moveToDestinationIfNeeded(dst, oldValue);
1116 }
1117
1118 RegisterID* PostfixNode::emitDot(BytecodeGenerator& generator, RegisterID* dst)
1119 {
1120     if (dst == generator.ignoredResult())
1121         return PrefixNode::emitDot(generator, dst);
1122
1123     ASSERT(m_expr->isDotAccessorNode());
1124     DotAccessorNode* dotAccessor = static_cast<DotAccessorNode*>(m_expr);
1125     ExpressionNode* baseNode = dotAccessor->base();
1126     const Identifier& ident = dotAccessor->identifier();
1127
1128     RefPtr<RegisterID> base = generator.emitNode(baseNode);
1129
1130     generator.emitExpressionInfo(dotAccessor->divot(), dotAccessor->divotStart(), dotAccessor->divotEnd());
1131     RefPtr<RegisterID> value = generator.emitGetById(generator.newTemporary(), base.get(), ident);
1132     RegisterID* oldValue = emitPostIncOrDec(generator, generator.tempDestination(dst), value.get(), m_operator);
1133     generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
1134     generator.emitPutById(base.get(), ident, value.get());
1135     if (generator.vm()->typeProfiler()) {
1136         generator.emitProfileType(value.get(), ProfileTypeBytecodeDoesNotHaveGlobalID, nullptr);
1137         generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd());
1138     }
1139     return generator.moveToDestinationIfNeeded(dst, oldValue);
1140 }
1141
1142 RegisterID* PostfixNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1143 {
1144     if (m_expr->isResolveNode())
1145         return emitResolve(generator, dst);
1146
1147     if (m_expr->isBracketAccessorNode())
1148         return emitBracket(generator, dst);
1149
1150     if (m_expr->isDotAccessorNode())
1151         return emitDot(generator, dst);
1152
1153     return emitThrowReferenceError(generator, m_operator == OpPlusPlus
1154         ? ASCIILiteral("Postfix ++ operator applied to value that is not a reference.")
1155         : ASCIILiteral("Postfix -- operator applied to value that is not a reference."));
1156 }
1157
1158 // ------------------------------ DeleteResolveNode -----------------------------------
1159
1160 RegisterID* DeleteResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1161 {
1162     Variable var = generator.variable(m_ident);
1163     if (var.local())
1164         return generator.emitLoad(generator.finalDestination(dst), false);
1165
1166     generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
1167     RefPtr<RegisterID> base = generator.emitResolveScope(dst, var);
1168     return generator.emitDeleteById(generator.finalDestination(dst, base.get()), base.get(), m_ident);
1169 }
1170
1171 // ------------------------------ DeleteBracketNode -----------------------------------
1172
1173 RegisterID* DeleteBracketNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1174 {
1175     RefPtr<RegisterID> r0 = generator.emitNode(m_base);
1176     RefPtr<RegisterID> r1 = generator.emitNode(m_subscript);
1177
1178     generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
1179     if (m_base->isSuperNode())
1180         return emitThrowReferenceError(generator, "Cannot delete a super property");
1181     return generator.emitDeleteByVal(generator.finalDestination(dst), r0.get(), r1.get());
1182 }
1183
1184 // ------------------------------ DeleteDotNode -----------------------------------
1185
1186 RegisterID* DeleteDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1187 {
1188     RefPtr<RegisterID> r0 = generator.emitNode(m_base);
1189
1190     generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
1191     if (m_base->isSuperNode())
1192         return emitThrowReferenceError(generator, "Cannot delete a super property");
1193     return generator.emitDeleteById(generator.finalDestination(dst), r0.get(), m_ident);
1194 }
1195
1196 // ------------------------------ DeleteValueNode -----------------------------------
1197
1198 RegisterID* DeleteValueNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1199 {
1200     generator.emitNode(generator.ignoredResult(), m_expr);
1201
1202     // delete on a non-location expression ignores the value and returns true
1203     return generator.emitLoad(generator.finalDestination(dst), true);
1204 }
1205
1206 // ------------------------------ VoidNode -------------------------------------
1207
1208 RegisterID* VoidNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1209 {
1210     if (dst == generator.ignoredResult()) {
1211         generator.emitNode(generator.ignoredResult(), m_expr);
1212         return 0;
1213     }
1214     RefPtr<RegisterID> r0 = generator.emitNode(m_expr);
1215     return generator.emitLoad(dst, jsUndefined());
1216 }
1217
1218 // ------------------------------ TypeOfResolveNode -----------------------------------
1219
1220 RegisterID* TypeOfResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1221 {
1222     Variable var = generator.variable(m_ident);
1223     if (RegisterID* local = var.local()) {
1224         if (dst == generator.ignoredResult())
1225             return 0;
1226         return generator.emitTypeOf(generator.finalDestination(dst), local);
1227     }
1228
1229     RefPtr<RegisterID> scope = generator.emitResolveScope(dst, var);
1230     RefPtr<RegisterID> value = generator.emitGetFromScope(generator.newTemporary(), scope.get(), var, DoNotThrowIfNotFound);
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         RefPtr<RegisterID> localReg = local;
1259         if (var.isReadOnly()) {
1260             generator.emitReadOnlyExceptionIfNeeded();
1261             localReg = generator.emitMove(generator.tempDestination(dst), localReg.get());
1262         } else if (generator.vm()->typeProfiler()) {
1263             RefPtr<RegisterID> tempDst = generator.tempDestination(dst);
1264             generator.emitMove(tempDst.get(), localReg.get());
1265             emitIncOrDec(generator, tempDst.get(), m_operator);
1266             generator.emitMove(localReg.get(), tempDst.get());
1267             if (generator.vm()->typeProfiler())
1268                 generator.emitTypeProfilerExpressionInfo(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     emitIncOrDec(generator, value.get(), m_operator);
1279     generator.emitPutToScope(scope.get(), var, value.get(), ThrowIfNotFound);
1280     if (generator.vm()->typeProfiler()) {
1281         generator.emitProfileType(value.get(), var.isResolved() ? ProfileTypeBytecodePutToLocalScope : ProfileTypeBytecodePutToScope, &ident);
1282         generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd());
1283     }
1284     return generator.moveToDestinationIfNeeded(dst, value.get());
1285 }
1286
1287 RegisterID* PrefixNode::emitBracket(BytecodeGenerator& generator, RegisterID* dst)
1288 {
1289     ASSERT(m_expr->isBracketAccessorNode());
1290     BracketAccessorNode* bracketAccessor = static_cast<BracketAccessorNode*>(m_expr);
1291     ExpressionNode* baseNode = bracketAccessor->base();
1292     ExpressionNode* subscript = bracketAccessor->subscript();
1293
1294     RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(baseNode, bracketAccessor->subscriptHasAssignments(), subscript->isPure(generator));
1295     RefPtr<RegisterID> property = generator.emitNode(subscript);
1296     RefPtr<RegisterID> propDst = generator.tempDestination(dst);
1297
1298     generator.emitExpressionInfo(bracketAccessor->divot(), bracketAccessor->divotStart(), bracketAccessor->divotEnd());
1299     RegisterID* value = generator.emitGetByVal(propDst.get(), base.get(), property.get());
1300     emitIncOrDec(generator, value, m_operator);
1301     generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
1302     generator.emitPutByVal(base.get(), property.get(), value);
1303     if (generator.vm()->typeProfiler()) {
1304         generator.emitProfileType(value, ProfileTypeBytecodeDoesNotHaveGlobalID, nullptr);
1305         generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd());
1306     }
1307     return generator.moveToDestinationIfNeeded(dst, propDst.get());
1308 }
1309
1310 RegisterID* PrefixNode::emitDot(BytecodeGenerator& generator, RegisterID* dst)
1311 {
1312     ASSERT(m_expr->isDotAccessorNode());
1313     DotAccessorNode* dotAccessor = static_cast<DotAccessorNode*>(m_expr);
1314     ExpressionNode* baseNode = dotAccessor->base();
1315     const Identifier& ident = dotAccessor->identifier();
1316
1317     RefPtr<RegisterID> base = generator.emitNode(baseNode);
1318     RefPtr<RegisterID> propDst = generator.tempDestination(dst);
1319
1320     generator.emitExpressionInfo(dotAccessor->divot(), dotAccessor->divotStart(), dotAccessor->divotEnd());
1321     RegisterID* value = generator.emitGetById(propDst.get(), base.get(), ident);
1322     emitIncOrDec(generator, value, m_operator);
1323     generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
1324     generator.emitPutById(base.get(), ident, value);
1325     if (generator.vm()->typeProfiler()) {
1326         generator.emitProfileType(value, ProfileTypeBytecodeDoesNotHaveGlobalID, nullptr);
1327         generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd());
1328     }
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.emitNode(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.emitNode(newDst.get(), m_expr1);
1698     generator.emitJump(afterElse.get());
1699
1700     generator.emitLabel(beforeElse.get());
1701     generator.emitProfileControlFlow(m_expr1->endOffset() + 1);
1702     generator.emitNode(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         if (var.isReadOnly()) {
1776             generator.emitReadOnlyExceptionIfNeeded();
1777             return emitReadModifyAssignment(generator, generator.finalDestination(dst), local, m_right, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()));
1778         }
1779         
1780         if (generator.vm()->typeProfiler()
1781             || generator.leftHandSideNeedsCopy(m_rightHasAssignments, m_right->isPure(generator))) {
1782             RefPtr<RegisterID> result = generator.newTemporary();
1783             generator.emitMove(result.get(), local);
1784             emitReadModifyAssignment(generator, result.get(), result.get(), m_right, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()));
1785             generator.emitMove(local, result.get());
1786             generator.invalidateForInContextForLocal(local);
1787             if (generator.vm()->typeProfiler())
1788                 generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd());
1789             return generator.moveToDestinationIfNeeded(dst, result.get());
1790         }
1791         
1792         RegisterID* result = emitReadModifyAssignment(generator, local, local, m_right, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()));
1793         generator.invalidateForInContextForLocal(local);
1794         return generator.moveToDestinationIfNeeded(dst, result);
1795     }
1796
1797     generator.emitExpressionInfo(newDivot, divotStart(), newDivot);
1798     RefPtr<RegisterID> scope = generator.emitResolveScope(nullptr, var);
1799     RefPtr<RegisterID> value = generator.emitGetFromScope(generator.newTemporary(), scope.get(), var, ThrowIfNotFound);
1800     RefPtr<RegisterID> result = emitReadModifyAssignment(generator, generator.finalDestination(dst, value.get()), value.get(), m_right, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()), this);
1801     RegisterID* returnResult = generator.emitPutToScope(scope.get(), var, result.get(), ThrowIfNotFound);
1802     if (generator.vm()->typeProfiler()) {
1803         generator.emitProfileType(result.get(), var.isResolved() ? ProfileTypeBytecodePutToLocalScope : ProfileTypeBytecodePutToScope, &m_ident);
1804         generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd());
1805     }
1806     return returnResult;
1807 }
1808
1809 // ------------------------------ AssignResolveNode -----------------------------------
1810
1811 RegisterID* AssignResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1812 {
1813     Variable var = generator.variable(m_ident);
1814     if (RegisterID* local = var.local()) {
1815         if (var.isReadOnly()) {
1816             generator.emitReadOnlyExceptionIfNeeded();
1817             return generator.emitNode(dst, m_right);
1818         }
1819         if (var.isSpecial() || generator.vm()->typeProfiler()) {
1820             RefPtr<RegisterID> tempDst = generator.tempDestination(dst);
1821             generator.emitNode(tempDst.get(), m_right);
1822             generator.emitMove(local, tempDst.get());
1823             generator.invalidateForInContextForLocal(local);
1824             if (generator.vm()->typeProfiler())
1825                 generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd());
1826             return generator.moveToDestinationIfNeeded(dst, tempDst.get());
1827         }
1828         RegisterID* result = generator.emitNode(local, m_right);
1829         generator.invalidateForInContextForLocal(local);
1830         return generator.moveToDestinationIfNeeded(dst, result);
1831     }
1832
1833     if (generator.isStrictMode())
1834         generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
1835     RefPtr<RegisterID> scope = generator.emitResolveScope(nullptr, var);
1836     if (dst == generator.ignoredResult())
1837         dst = 0;
1838     RefPtr<RegisterID> result = generator.emitNode(dst, m_right);
1839     generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
1840     RegisterID* returnResult = generator.emitPutToScope(scope.get(), var, result.get(), generator.isStrictMode() ? ThrowIfNotFound : DoNotThrowIfNotFound);
1841     if (generator.vm()->typeProfiler()) {
1842         generator.emitProfileType(result.get(), var.isResolved() ? ProfileTypeBytecodePutToLocalScope : ProfileTypeBytecodePutToScope, &m_ident);
1843         generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd());
1844     } 
1845     return returnResult;
1846 }
1847
1848 // ------------------------------ AssignDotNode -----------------------------------
1849
1850 RegisterID* AssignDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1851 {
1852     RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base, m_rightHasAssignments, m_right->isPure(generator));
1853     RefPtr<RegisterID> value = generator.destinationForAssignResult(dst);
1854     RefPtr<RegisterID> result = generator.emitNode(value.get(), m_right);
1855     generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
1856     RegisterID* forwardResult = (dst == generator.ignoredResult()) ? result.get() : generator.moveToDestinationIfNeeded(generator.tempDestination(result.get()), result.get());
1857     generator.emitPutById(base.get(), m_ident, forwardResult);
1858     if (generator.vm()->typeProfiler()) {
1859         generator.emitProfileType(forwardResult, ProfileTypeBytecodeDoesNotHaveGlobalID, nullptr);
1860         generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd());
1861     }
1862     return generator.moveToDestinationIfNeeded(dst, forwardResult);
1863 }
1864
1865 // ------------------------------ ReadModifyDotNode -----------------------------------
1866
1867 RegisterID* ReadModifyDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1868 {
1869     RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base, m_rightHasAssignments, m_right->isPure(generator));
1870
1871     generator.emitExpressionInfo(subexpressionDivot(), subexpressionStart(), subexpressionEnd());
1872     RefPtr<RegisterID> value = generator.emitGetById(generator.tempDestination(dst), base.get(), m_ident);
1873     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()));
1874
1875     generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
1876     RegisterID* ret = generator.emitPutById(base.get(), m_ident, updatedValue);
1877     if (generator.vm()->typeProfiler()) {
1878         generator.emitProfileType(updatedValue, ProfileTypeBytecodeDoesNotHaveGlobalID, nullptr);
1879         generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd());
1880     }
1881     return ret;
1882 }
1883
1884 // ------------------------------ AssignErrorNode -----------------------------------
1885
1886 RegisterID* AssignErrorNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
1887 {
1888     return emitThrowReferenceError(generator, ASCIILiteral("Left side of assignment is not a reference."));
1889 }
1890
1891 // ------------------------------ AssignBracketNode -----------------------------------
1892
1893 RegisterID* AssignBracketNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1894 {
1895     RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base, m_subscriptHasAssignments || m_rightHasAssignments, m_subscript->isPure(generator) && m_right->isPure(generator));
1896     RefPtr<RegisterID> property = generator.emitNodeForLeftHandSide(m_subscript, m_rightHasAssignments, m_right->isPure(generator));
1897     RefPtr<RegisterID> value = generator.destinationForAssignResult(dst);
1898     RefPtr<RegisterID> result = generator.emitNode(value.get(), m_right);
1899
1900     generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
1901     RegisterID* forwardResult = (dst == generator.ignoredResult()) ? result.get() : generator.moveToDestinationIfNeeded(generator.tempDestination(result.get()), result.get());
1902
1903     if (m_subscript->isString())
1904         generator.emitPutById(base.get(), static_cast<StringNode*>(m_subscript)->value(), forwardResult);
1905     else
1906         generator.emitPutByVal(base.get(), property.get(), forwardResult);
1907
1908     if (generator.vm()->typeProfiler()) {
1909         generator.emitProfileType(forwardResult, ProfileTypeBytecodeDoesNotHaveGlobalID, nullptr);
1910         generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd());
1911     }
1912     return generator.moveToDestinationIfNeeded(dst, forwardResult);
1913 }
1914
1915 // ------------------------------ ReadModifyBracketNode -----------------------------------
1916
1917 RegisterID* ReadModifyBracketNode::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
1922     generator.emitExpressionInfo(subexpressionDivot(), subexpressionStart(), subexpressionEnd());
1923     RefPtr<RegisterID> value = generator.emitGetByVal(generator.tempDestination(dst), base.get(), property.get());
1924     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()));
1925
1926     generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
1927     generator.emitPutByVal(base.get(), property.get(), updatedValue);
1928     if (generator.vm()->typeProfiler()) {
1929         generator.emitProfileType(updatedValue, ProfileTypeBytecodeDoesNotHaveGlobalID, nullptr);
1930         generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd());
1931     }
1932
1933     return updatedValue;
1934 }
1935
1936 // ------------------------------ CommaNode ------------------------------------
1937
1938 RegisterID* CommaNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1939 {
1940     CommaNode* node = this;
1941     for (; node && node->next(); node = node->next())
1942         generator.emitNode(generator.ignoredResult(), node->m_expr);
1943     return generator.emitNode(dst, node->m_expr);
1944 }
1945
1946 // ------------------------------ ConstDeclNode ------------------------------------
1947
1948 RegisterID* ConstDeclNode::emitCodeSingle(BytecodeGenerator& generator)
1949 {
1950     // FIXME: This code does not match the behavior of const in Firefox.
1951     Variable var = generator.variable(m_ident);
1952     if (RegisterID* local = var.local()) {
1953         if (!m_init)
1954             return local;
1955
1956         // FIXME: Maybe call emitExpressionInfo here.
1957         if (var.isSpecial() || generator.vm()->typeProfiler()) {
1958             RefPtr<RegisterID> tempDst = generator.newTemporary();
1959             generator.emitNode(tempDst.get(), m_init);
1960             return generator.emitMove(local, tempDst.get());
1961         }
1962         
1963         return generator.emitNode(local, m_init);
1964     }
1965
1966     RefPtr<RegisterID> value = m_init ? generator.emitNode(m_init) : generator.emitLoad(0, jsUndefined());
1967
1968     if (generator.codeType() == GlobalCode)
1969         return generator.emitInitGlobalConst(m_ident, value.get());
1970
1971     if (generator.codeType() != EvalCode) {
1972         // Do a special kind of resolution. If anything fails, then don't perform the assignment. This is
1973         // pretty shady - particularly how negligent it is with inteleaving scopes - but it's the
1974         // behavior that JSC has had for a long time.
1975         
1976         ASSERT(generator.codeType() == FunctionCode);
1977         
1978         var = generator.variablePerSymbolTable(m_ident);
1979         if (!var.isResolved())
1980             return value.get();
1981         
1982         RefPtr<RegisterID> scope = generator.emitResolveScope(generator.newTemporary(), var);
1983         return generator.emitPutToScope(scope.get(), var, value.get(), DoNotThrowIfNotFound);
1984     }
1985
1986     // FIXME: This will result in incorrect assignment if m_ident exists in an intervening with scope.
1987     RefPtr<RegisterID> scope = generator.emitResolveScope(nullptr, var);
1988     return generator.emitPutToScope(scope.get(), var, value.get(), DoNotThrowIfNotFound);
1989 }
1990
1991 RegisterID* ConstDeclNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
1992 {
1993     RegisterID* result = 0;
1994     for (ConstDeclNode* n = this; n; n = n->m_next)
1995         result = n->emitCodeSingle(generator);
1996
1997     return result;
1998 }
1999
2000 // ------------------------------ ConstStatementNode -----------------------------
2001
2002 void ConstStatementNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
2003 {
2004     generator.emitDebugHook(WillExecuteStatement, firstLine(), startOffset(), lineStartOffset());
2005     generator.emitNode(m_next);
2006 }
2007
2008 // ------------------------------ SourceElements -------------------------------
2009
2010
2011 inline StatementNode* SourceElements::lastStatement() const
2012 {
2013     return m_tail;
2014 }
2015
2016 inline void SourceElements::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2017 {
2018     for (StatementNode* statement = m_head; statement; statement = statement->next())
2019         generator.emitNode(dst, statement);
2020 }
2021
2022 // ------------------------------ BlockNode ------------------------------------
2023
2024 inline StatementNode* BlockNode::lastStatement() const
2025 {
2026     return m_statements ? m_statements->lastStatement() : 0;
2027 }
2028
2029 StatementNode* BlockNode::singleStatement() const
2030 {
2031     return m_statements ? m_statements->singleStatement() : 0;
2032 }
2033
2034 void BlockNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2035 {
2036     if (!m_statements)
2037         return;
2038     m_statements->emitBytecode(generator, dst);
2039 }
2040
2041 // ------------------------------ EmptyStatementNode ---------------------------
2042
2043 void EmptyStatementNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
2044 {
2045     generator.emitDebugHook(WillExecuteStatement, firstLine(), startOffset(), lineStartOffset());
2046 }
2047
2048 // ------------------------------ DebuggerStatementNode ---------------------------
2049
2050 void DebuggerStatementNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
2051 {
2052     generator.emitDebugHook(DidReachBreakpoint, lastLine(), startOffset(), lineStartOffset());
2053 }
2054
2055 // ------------------------------ ExprStatementNode ----------------------------
2056
2057 void ExprStatementNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2058 {
2059     ASSERT(m_expr);
2060     generator.emitDebugHook(WillExecuteStatement, firstLine(), startOffset(), lineStartOffset());
2061     generator.emitNode(dst, m_expr);
2062 }
2063
2064 // ------------------------------ VarStatementNode ----------------------------
2065
2066 void VarStatementNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
2067 {
2068     ASSERT(m_expr);
2069     generator.emitDebugHook(WillExecuteStatement, firstLine(), startOffset(), lineStartOffset());
2070     generator.emitNode(m_expr);
2071 }
2072
2073 // ------------------------------ EmptyVarExpression ----------------------------
2074
2075 RegisterID* EmptyVarExpression::emitBytecode(BytecodeGenerator& generator, RegisterID*)
2076 {
2077     if (!generator.vm()->typeProfiler())
2078         return nullptr;
2079
2080     Variable var = generator.variable(m_ident);
2081     if (RegisterID* local = var.local())
2082         generator.emitProfileType(local, ProfileTypeBytecodeHasGlobalID, nullptr);
2083     else {
2084         RefPtr<RegisterID> scope = generator.emitResolveScope(nullptr, var);
2085         RefPtr<RegisterID> value = generator.emitGetFromScope(generator.newTemporary(), scope.get(), var, DoNotThrowIfNotFound);
2086         generator.emitProfileType(value.get(), var.isResolved() ? ProfileTypeBytecodeGetFromLocalScope : ProfileTypeBytecodeGetFromScope, &m_ident);
2087     }
2088
2089     generator.emitTypeProfilerExpressionInfo(position(), JSTextPosition(-1, position().offset + m_ident.length(), -1));
2090
2091     // It's safe to return null here because this node will always be a child node of VarStatementNode which ignores our return value.
2092     return nullptr;
2093 }
2094
2095 // ------------------------------ IfElseNode ---------------------------------------
2096
2097 static inline StatementNode* singleStatement(StatementNode* statementNode)
2098 {
2099     if (statementNode->isBlock())
2100         return static_cast<BlockNode*>(statementNode)->singleStatement();
2101     return statementNode;
2102 }
2103
2104 bool IfElseNode::tryFoldBreakAndContinue(BytecodeGenerator& generator, StatementNode* ifBlock,
2105     Label*& trueTarget, FallThroughMode& fallThroughMode)
2106 {
2107     StatementNode* singleStatement = JSC::singleStatement(ifBlock);
2108     if (!singleStatement)
2109         return false;
2110
2111     if (singleStatement->isBreak()) {
2112         BreakNode* breakNode = static_cast<BreakNode*>(singleStatement);
2113         Label* target = breakNode->trivialTarget(generator);
2114         if (!target)
2115             return false;
2116         trueTarget = target;
2117         fallThroughMode = FallThroughMeansFalse;
2118         return true;
2119     }
2120
2121     if (singleStatement->isContinue()) {
2122         ContinueNode* continueNode = static_cast<ContinueNode*>(singleStatement);
2123         Label* target = continueNode->trivialTarget(generator);
2124         if (!target)
2125             return false;
2126         trueTarget = target;
2127         fallThroughMode = FallThroughMeansFalse;
2128         return true;
2129     }
2130
2131     return false;
2132 }
2133
2134 void IfElseNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2135 {
2136     generator.emitDebugHook(WillExecuteStatement, firstLine(), startOffset(), lineStartOffset());
2137     
2138     RefPtr<Label> beforeThen = generator.newLabel();
2139     RefPtr<Label> beforeElse = generator.newLabel();
2140     RefPtr<Label> afterElse = generator.newLabel();
2141
2142     Label* trueTarget = beforeThen.get();
2143     Label* falseTarget = beforeElse.get();
2144     FallThroughMode fallThroughMode = FallThroughMeansTrue;
2145     bool didFoldIfBlock = tryFoldBreakAndContinue(generator, m_ifBlock, trueTarget, fallThroughMode);
2146
2147     generator.emitNodeInConditionContext(m_condition, trueTarget, falseTarget, fallThroughMode);
2148     generator.emitLabel(beforeThen.get());
2149     generator.emitProfileControlFlow(m_ifBlock->startOffset());
2150
2151     if (!didFoldIfBlock) {
2152         generator.emitNode(dst, m_ifBlock);
2153         if (m_elseBlock)
2154             generator.emitJump(afterElse.get());
2155     }
2156
2157     generator.emitLabel(beforeElse.get());
2158
2159     if (m_elseBlock) {
2160         generator.emitProfileControlFlow(m_ifBlock->endOffset() + (m_ifBlock->isBlock() ? 1 : 0));
2161         generator.emitNode(dst, m_elseBlock);
2162     }
2163
2164     generator.emitLabel(afterElse.get());
2165     StatementNode* endingBlock = m_elseBlock ? m_elseBlock : m_ifBlock;
2166     generator.emitProfileControlFlow(endingBlock->endOffset() + (endingBlock->isBlock() ? 1 : 0));
2167 }
2168
2169 // ------------------------------ DoWhileNode ----------------------------------
2170
2171 void DoWhileNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2172 {
2173     LabelScopePtr scope = generator.newLabelScope(LabelScope::Loop);
2174
2175     RefPtr<Label> topOfLoop = generator.newLabel();
2176     generator.emitLabel(topOfLoop.get());
2177     generator.emitLoopHint();
2178     generator.emitDebugHook(WillExecuteStatement, lastLine(), startOffset(), lineStartOffset());
2179
2180     generator.emitNode(dst, m_statement);
2181
2182     generator.emitLabel(scope->continueTarget());
2183     generator.emitDebugHook(WillExecuteStatement, lastLine(), startOffset(), lineStartOffset());
2184     generator.emitNodeInConditionContext(m_expr, topOfLoop.get(), scope->breakTarget(), FallThroughMeansFalse);
2185
2186     generator.emitLabel(scope->breakTarget());
2187 }
2188
2189 // ------------------------------ WhileNode ------------------------------------
2190
2191 void WhileNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2192 {
2193     LabelScopePtr scope = generator.newLabelScope(LabelScope::Loop);
2194     RefPtr<Label> topOfLoop = generator.newLabel();
2195
2196     generator.emitDebugHook(WillExecuteStatement, m_expr->firstLine(), m_expr->startOffset(), m_expr->lineStartOffset());
2197     generator.emitNodeInConditionContext(m_expr, topOfLoop.get(), scope->breakTarget(), FallThroughMeansTrue);
2198
2199     generator.emitLabel(topOfLoop.get());
2200     generator.emitLoopHint();
2201     
2202     generator.emitProfileControlFlow(m_statement->startOffset());
2203     generator.emitNode(dst, m_statement);
2204
2205     generator.emitLabel(scope->continueTarget());
2206     generator.emitDebugHook(WillExecuteStatement, firstLine(), startOffset(), lineStartOffset());
2207
2208     generator.emitNodeInConditionContext(m_expr, topOfLoop.get(), scope->breakTarget(), FallThroughMeansFalse);
2209
2210     generator.emitLabel(scope->breakTarget());
2211
2212     generator.emitProfileControlFlow(m_statement->endOffset() + (m_statement->isBlock() ? 1 : 0));
2213 }
2214
2215 // ------------------------------ ForNode --------------------------------------
2216
2217 void ForNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2218 {
2219     LabelScopePtr scope = generator.newLabelScope(LabelScope::Loop);
2220
2221     generator.emitDebugHook(WillExecuteStatement, firstLine(), startOffset(), lineStartOffset());
2222
2223     if (m_expr1)
2224         generator.emitNode(generator.ignoredResult(), m_expr1);
2225     
2226     RefPtr<Label> topOfLoop = generator.newLabel();
2227     if (m_expr2)
2228         generator.emitNodeInConditionContext(m_expr2, topOfLoop.get(), scope->breakTarget(), FallThroughMeansTrue);
2229
2230     generator.emitLabel(topOfLoop.get());
2231     generator.emitLoopHint();
2232     generator.emitProfileControlFlow(m_statement->startOffset());
2233
2234     generator.emitNode(dst, m_statement);
2235
2236     generator.emitLabel(scope->continueTarget());
2237     generator.emitDebugHook(WillExecuteStatement, firstLine(), startOffset(), lineStartOffset());
2238     if (m_expr3)
2239         generator.emitNode(generator.ignoredResult(), m_expr3);
2240
2241     if (m_expr2)
2242         generator.emitNodeInConditionContext(m_expr2, topOfLoop.get(), scope->breakTarget(), FallThroughMeansFalse);
2243     else
2244         generator.emitJump(topOfLoop.get());
2245
2246     generator.emitLabel(scope->breakTarget());
2247     generator.emitProfileControlFlow(m_statement->endOffset() + (m_statement->isBlock() ? 1 : 0));
2248 }
2249
2250 // ------------------------------ ForInNode ------------------------------------
2251
2252 RegisterID* ForInNode::tryGetBoundLocal(BytecodeGenerator& generator)
2253 {
2254     if (m_lexpr->isResolveNode()) {
2255         const Identifier& ident = static_cast<ResolveNode*>(m_lexpr)->identifier();
2256         return generator.variable(ident).local();
2257     }
2258
2259     if (m_lexpr->isDeconstructionNode()) {
2260         DeconstructingAssignmentNode* assignNode = static_cast<DeconstructingAssignmentNode*>(m_lexpr);
2261         auto binding = assignNode->bindings();
2262         if (!binding->isBindingNode())
2263             return nullptr;
2264
2265         auto simpleBinding = static_cast<BindingNode*>(binding);
2266         const Identifier& ident = simpleBinding->boundProperty();
2267         Variable var = generator.variable(ident);
2268         if (var.isSpecial())
2269             return nullptr;
2270         return var.local();
2271     }
2272
2273     return nullptr;
2274 }
2275
2276 void ForInNode::emitLoopHeader(BytecodeGenerator& generator, RegisterID* propertyName)
2277 {
2278     if (m_lexpr->isResolveNode()) {
2279         const Identifier& ident = static_cast<ResolveNode*>(m_lexpr)->identifier();
2280         Variable var = generator.variable(ident);
2281         if (RegisterID* local = var.local())
2282             generator.emitMove(local, propertyName);
2283         else {
2284             if (generator.isStrictMode())
2285                 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
2286             RegisterID* scope = generator.emitResolveScope(nullptr, var);
2287             generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
2288             generator.emitPutToScope(scope, var, propertyName, generator.isStrictMode() ? ThrowIfNotFound : DoNotThrowIfNotFound);
2289             if (generator.vm()->typeProfiler())
2290                 generator.emitProfileType(propertyName, var.isResolved() ? ProfileTypeBytecodePutToLocalScope : ProfileTypeBytecodePutToScope, &ident);
2291         }
2292         if (generator.vm()->typeProfiler())
2293             generator.emitTypeProfilerExpressionInfo(m_lexpr->position(), JSTextPosition(-1, m_lexpr->position().offset + ident.length(), -1));
2294         return;
2295     }
2296     if (m_lexpr->isDotAccessorNode()) {
2297         DotAccessorNode* assignNode = static_cast<DotAccessorNode*>(m_lexpr);
2298         const Identifier& ident = assignNode->identifier();
2299         RegisterID* base = generator.emitNode(assignNode->base());
2300         generator.emitExpressionInfo(assignNode->divot(), assignNode->divotStart(), assignNode->divotEnd());
2301         generator.emitPutById(base, ident, propertyName);
2302         if (generator.vm()->typeProfiler()) {
2303             generator.emitProfileType(propertyName, ProfileTypeBytecodeDoesNotHaveGlobalID, nullptr);
2304             generator.emitTypeProfilerExpressionInfo(assignNode->divotStart(), assignNode->divotEnd());
2305         }
2306         return;
2307     }
2308     if (m_lexpr->isBracketAccessorNode()) {
2309         BracketAccessorNode* assignNode = static_cast<BracketAccessorNode*>(m_lexpr);
2310         RefPtr<RegisterID> base = generator.emitNode(assignNode->base());
2311         RegisterID* subscript = generator.emitNode(assignNode->subscript());
2312         generator.emitExpressionInfo(assignNode->divot(), assignNode->divotStart(), assignNode->divotEnd());
2313         generator.emitPutByVal(base.get(), subscript, propertyName);
2314         if (generator.vm()->typeProfiler()) {
2315             generator.emitProfileType(propertyName, ProfileTypeBytecodeDoesNotHaveGlobalID, nullptr);
2316             generator.emitTypeProfilerExpressionInfo(assignNode->divotStart(), assignNode->divotEnd());
2317         }
2318         return;
2319     }
2320
2321     if (m_lexpr->isDeconstructionNode()) {
2322         DeconstructingAssignmentNode* assignNode = static_cast<DeconstructingAssignmentNode*>(m_lexpr);
2323         auto binding = assignNode->bindings();
2324         if (!binding->isBindingNode()) {
2325             assignNode->bindings()->bindValue(generator, propertyName);
2326             return;
2327         }
2328
2329         auto simpleBinding = static_cast<BindingNode*>(binding);
2330         const Identifier& ident = simpleBinding->boundProperty();
2331         Variable var = generator.variable(ident);
2332         if (!var.local() || var.isSpecial()) {
2333             assignNode->bindings()->bindValue(generator, propertyName);
2334             return;
2335         }
2336         generator.emitMove(var.local(), propertyName);
2337         if (generator.vm()->typeProfiler())
2338             generator.emitTypeProfilerExpressionInfo(simpleBinding->divotStart(), simpleBinding->divotEnd());
2339         return;
2340     }
2341
2342     RELEASE_ASSERT_NOT_REACHED();
2343 }
2344
2345 void ForInNode::emitMultiLoopBytecode(BytecodeGenerator& generator, RegisterID* dst)
2346 {
2347     if (!m_lexpr->isAssignmentLocation()) {
2348         emitThrowReferenceError(generator, ASCIILiteral("Left side of for-in statement is not a reference."));
2349         return;
2350     }
2351
2352     RefPtr<Label> end = generator.newLabel();
2353
2354     generator.emitDebugHook(WillExecuteStatement, firstLine(), startOffset(), lineStartOffset());
2355
2356     RefPtr<RegisterID> base = generator.newTemporary();
2357     RefPtr<RegisterID> length;
2358     RefPtr<RegisterID> enumerator;
2359     generator.emitNode(base.get(), m_expr);
2360     RefPtr<RegisterID> local = this->tryGetBoundLocal(generator);
2361     RefPtr<RegisterID> enumeratorIndex;
2362
2363     int profilerStartOffset = m_statement->startOffset();
2364     int profilerEndOffset = m_statement->endOffset() + (m_statement->isBlock() ? 1 : 0);
2365
2366     enumerator = generator.emitGetPropertyEnumerator(generator.newTemporary(), base.get());
2367
2368     // Indexed property loop.
2369     {
2370         LabelScopePtr scope = generator.newLabelScope(LabelScope::Loop);
2371         RefPtr<Label> loopStart = generator.newLabel();
2372         RefPtr<Label> loopEnd = generator.newLabel();
2373
2374         length = generator.emitGetEnumerableLength(generator.newTemporary(), enumerator.get());
2375         RefPtr<RegisterID> i = generator.emitLoad(generator.newTemporary(), jsNumber(0));
2376         RefPtr<RegisterID> propertyName = generator.newTemporary();
2377
2378         generator.emitLabel(loopStart.get());
2379         generator.emitLoopHint();
2380
2381         RefPtr<RegisterID> result = generator.emitEqualityOp(op_less, generator.newTemporary(), i.get(), length.get());
2382         generator.emitJumpIfFalse(result.get(), loopEnd.get());
2383         generator.emitHasIndexedProperty(result.get(), base.get(), i.get());
2384         generator.emitJumpIfFalse(result.get(), scope->continueTarget());
2385
2386         generator.emitToIndexString(propertyName.get(), i.get());
2387         this->emitLoopHeader(generator, propertyName.get());
2388
2389         generator.emitProfileControlFlow(profilerStartOffset);
2390
2391         generator.pushIndexedForInScope(local.get(), i.get());
2392         generator.emitNode(dst, m_statement);
2393         generator.popIndexedForInScope(local.get());
2394
2395         generator.emitProfileControlFlow(profilerEndOffset);
2396
2397         generator.emitLabel(scope->continueTarget());
2398         generator.emitInc(i.get());
2399         generator.emitJump(loopStart.get());
2400
2401         generator.emitLabel(scope->breakTarget());
2402         generator.emitJump(end.get());
2403         generator.emitLabel(loopEnd.get());
2404     }
2405
2406     // Structure property loop.
2407     {
2408         LabelScopePtr scope = generator.newLabelScope(LabelScope::Loop);
2409         RefPtr<Label> loopStart = generator.newLabel();
2410         RefPtr<Label> loopEnd = generator.newLabel();
2411
2412         enumeratorIndex = generator.emitLoad(generator.newTemporary(), jsNumber(0));
2413         RefPtr<RegisterID> propertyName = generator.newTemporary();
2414         generator.emitEnumeratorStructurePropertyName(propertyName.get(), enumerator.get(), enumeratorIndex.get());
2415
2416         generator.emitLabel(loopStart.get());
2417         generator.emitLoopHint();
2418
2419         RefPtr<RegisterID> result = generator.emitUnaryOp(op_eq_null, generator.newTemporary(), propertyName.get());
2420         generator.emitJumpIfTrue(result.get(), loopEnd.get());
2421         generator.emitHasStructureProperty(result.get(), base.get(), propertyName.get(), enumerator.get());
2422         generator.emitJumpIfFalse(result.get(), scope->continueTarget());
2423
2424         this->emitLoopHeader(generator, propertyName.get());
2425
2426         generator.emitProfileControlFlow(profilerStartOffset);
2427
2428         generator.pushStructureForInScope(local.get(), enumeratorIndex.get(), propertyName.get(), enumerator.get());
2429         generator.emitNode(dst, m_statement);
2430         generator.popStructureForInScope(local.get());
2431
2432         generator.emitProfileControlFlow(profilerEndOffset);
2433
2434         generator.emitLabel(scope->continueTarget());
2435         generator.emitInc(enumeratorIndex.get());
2436         generator.emitEnumeratorStructurePropertyName(propertyName.get(), enumerator.get(), enumeratorIndex.get());
2437         generator.emitJump(loopStart.get());
2438         
2439         generator.emitLabel(scope->breakTarget());
2440         generator.emitJump(end.get());
2441         generator.emitLabel(loopEnd.get());
2442     }
2443
2444     // Generic property loop.
2445     {
2446         LabelScopePtr scope = generator.newLabelScope(LabelScope::Loop);
2447         RefPtr<Label> loopStart = generator.newLabel();
2448         RefPtr<Label> loopEnd = generator.newLabel();
2449
2450         RefPtr<RegisterID> propertyName = generator.newTemporary();
2451
2452         generator.emitEnumeratorGenericPropertyName(propertyName.get(), enumerator.get(), enumeratorIndex.get());
2453
2454         generator.emitLabel(loopStart.get());
2455         generator.emitLoopHint();
2456
2457         RefPtr<RegisterID> result = generator.emitUnaryOp(op_eq_null, generator.newTemporary(), propertyName.get());
2458         generator.emitJumpIfTrue(result.get(), loopEnd.get());
2459
2460         generator.emitHasGenericProperty(result.get(), base.get(), propertyName.get());
2461         generator.emitJumpIfFalse(result.get(), scope->continueTarget());
2462
2463         this->emitLoopHeader(generator, propertyName.get());
2464
2465         generator.emitProfileControlFlow(profilerStartOffset);
2466
2467         generator.emitNode(dst, m_statement);
2468
2469         generator.emitLabel(scope->continueTarget());
2470         generator.emitInc(enumeratorIndex.get());
2471         generator.emitEnumeratorGenericPropertyName(propertyName.get(), enumerator.get(), enumeratorIndex.get());
2472         generator.emitJump(loopStart.get());
2473
2474         generator.emitLabel(scope->breakTarget());
2475         generator.emitJump(end.get());
2476         generator.emitLabel(loopEnd.get());
2477     }
2478
2479     generator.emitDebugHook(WillExecuteStatement, firstLine(), startOffset(), lineStartOffset());
2480     generator.emitLabel(end.get());
2481     generator.emitProfileControlFlow(profilerEndOffset);
2482 }
2483
2484 void ForInNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2485 {
2486     this->emitMultiLoopBytecode(generator, dst);
2487 }
2488
2489 // ------------------------------ ForOfNode ------------------------------------
2490 void ForOfNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2491 {
2492     if (!m_lexpr->isAssignmentLocation()) {
2493         emitThrowReferenceError(generator, ASCIILiteral("Left side of for-of statement is not a reference."));
2494         return;
2495     }
2496
2497     generator.emitDebugHook(WillExecuteStatement, firstLine(), startOffset(), lineStartOffset());
2498     auto extractor = [this, dst](BytecodeGenerator& generator, RegisterID* value)
2499     {
2500         if (m_lexpr->isResolveNode()) {
2501             const Identifier& ident = static_cast<ResolveNode*>(m_lexpr)->identifier();
2502             Variable var = generator.variable(ident);
2503             if (RegisterID* local = var.local())
2504                 generator.emitMove(local, value);
2505             else {
2506                 if (generator.isStrictMode())
2507                     generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
2508                 RegisterID* scope = generator.emitResolveScope(nullptr, var);
2509                 generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
2510                 generator.emitPutToScope(scope, var, value, generator.isStrictMode() ? ThrowIfNotFound : DoNotThrowIfNotFound);
2511                 if (generator.vm()->typeProfiler())
2512                     generator.emitProfileType(value, var.isResolved() ? ProfileTypeBytecodePutToLocalScope : ProfileTypeBytecodePutToScope, &ident);
2513             }
2514             if (generator.vm()->typeProfiler())
2515                 generator.emitTypeProfilerExpressionInfo(m_lexpr->position(), JSTextPosition(-1, m_lexpr->position().offset + ident.length(), -1));
2516         } else if (m_lexpr->isDotAccessorNode()) {
2517             DotAccessorNode* assignNode = static_cast<DotAccessorNode*>(m_lexpr);
2518             const Identifier& ident = assignNode->identifier();
2519             RefPtr<RegisterID> base = generator.emitNode(assignNode->base());
2520             
2521             generator.emitExpressionInfo(assignNode->divot(), assignNode->divotStart(), assignNode->divotEnd());
2522             generator.emitPutById(base.get(), ident, value);
2523             if (generator.vm()->typeProfiler()) {
2524                 generator.emitProfileType(value, ProfileTypeBytecodeDoesNotHaveGlobalID, nullptr);
2525                 generator.emitTypeProfilerExpressionInfo(assignNode->divotStart(), assignNode->divotEnd());
2526             }
2527         } else if (m_lexpr->isBracketAccessorNode()) {
2528             BracketAccessorNode* assignNode = static_cast<BracketAccessorNode*>(m_lexpr);
2529             RefPtr<RegisterID> base = generator.emitNode(assignNode->base());
2530             RegisterID* subscript = generator.emitNode(assignNode->subscript());
2531             
2532             generator.emitExpressionInfo(assignNode->divot(), assignNode->divotStart(), assignNode->divotEnd());
2533             generator.emitPutByVal(base.get(), subscript, value);
2534             if (generator.vm()->typeProfiler()) {
2535                 generator.emitProfileType(value, ProfileTypeBytecodeDoesNotHaveGlobalID, nullptr);
2536                 generator.emitTypeProfilerExpressionInfo(assignNode->divotStart(), assignNode->divotEnd());
2537             }
2538         } else {
2539             ASSERT(m_lexpr->isDeconstructionNode());
2540             DeconstructingAssignmentNode* assignNode = static_cast<DeconstructingAssignmentNode*>(m_lexpr);
2541             assignNode->bindings()->bindValue(generator, value);
2542         }
2543         generator.emitProfileControlFlow(m_statement->startOffset());
2544         generator.emitNode(dst, m_statement);
2545     };
2546     generator.emitEnumeration(this, m_expr, extractor);
2547     generator.emitProfileControlFlow(m_statement->endOffset() + (m_statement->isBlock() ? 1 : 0));
2548 }
2549
2550 // ------------------------------ ContinueNode ---------------------------------
2551
2552 Label* ContinueNode::trivialTarget(BytecodeGenerator& generator)
2553 {
2554     if (generator.shouldEmitDebugHooks())
2555         return 0;
2556
2557     LabelScopePtr scope = generator.continueTarget(m_ident);
2558     ASSERT(scope);
2559
2560     if (generator.scopeDepth() != scope->scopeDepth())
2561         return 0;
2562
2563     return scope->continueTarget();
2564 }
2565
2566 void ContinueNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
2567 {
2568     generator.emitDebugHook(WillExecuteStatement, firstLine(), startOffset(), lineStartOffset());
2569     
2570     LabelScopePtr scope = generator.continueTarget(m_ident);
2571     ASSERT(scope);
2572
2573     generator.emitPopScopes(generator.scopeRegister(), scope->scopeDepth());
2574     generator.emitJump(scope->continueTarget());
2575
2576     generator.emitProfileControlFlow(endOffset());
2577 }
2578
2579 // ------------------------------ BreakNode ------------------------------------
2580
2581 Label* BreakNode::trivialTarget(BytecodeGenerator& generator)
2582 {
2583     if (generator.shouldEmitDebugHooks())
2584         return 0;
2585
2586     LabelScopePtr scope = generator.breakTarget(m_ident);
2587     ASSERT(scope);
2588
2589     if (generator.scopeDepth() != scope->scopeDepth())
2590         return 0;
2591
2592     return scope->breakTarget();
2593 }
2594
2595 void BreakNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
2596 {
2597     generator.emitDebugHook(WillExecuteStatement, firstLine(), startOffset(), lineStartOffset());
2598     
2599     LabelScopePtr scope = generator.breakTarget(m_ident);
2600     ASSERT(scope);
2601
2602     generator.emitPopScopes(generator.scopeRegister(), scope->scopeDepth());
2603     generator.emitJump(scope->breakTarget());
2604
2605     generator.emitProfileControlFlow(endOffset());
2606 }
2607
2608 // ------------------------------ ReturnNode -----------------------------------
2609
2610 void ReturnNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2611 {
2612     generator.emitDebugHook(WillExecuteStatement, firstLine(), startOffset(), lineStartOffset());
2613     ASSERT(generator.codeType() == FunctionCode);
2614
2615     if (dst == generator.ignoredResult())
2616         dst = 0;
2617
2618     RefPtr<RegisterID> returnRegister = m_value ? generator.emitNode(dst, m_value) : generator.emitLoad(dst, jsUndefined());
2619     if (generator.vm()->typeProfiler()) {
2620         generator.emitProfileType(returnRegister.get(), ProfileTypeBytecodeFunctionReturnStatement, nullptr);
2621         generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd());
2622     }
2623     if (generator.scopeDepth()) {
2624         returnRegister = generator.emitMove(generator.newTemporary(), returnRegister.get());
2625         generator.emitPopScopes(generator.scopeRegister(), 0);
2626     }
2627
2628     generator.emitDebugHook(WillLeaveCallFrame, lastLine(), startOffset(), lineStartOffset());
2629     generator.emitReturn(returnRegister.get());
2630     generator.emitProfileControlFlow(endOffset()); 
2631     // Emitting an unreachable return here is needed in case this op_profile_control_flow is the 
2632     // last opcode in a CodeBlock because a CodeBlock's instructions must end with a terminal opcode.
2633     if (generator.vm()->controlFlowProfiler())
2634         generator.emitReturn(generator.emitLoad(nullptr, jsUndefined()));
2635 }
2636
2637 // ------------------------------ WithNode -------------------------------------
2638
2639 void WithNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2640 {
2641     generator.emitDebugHook(WillExecuteStatement, firstLine(), startOffset(), lineStartOffset());
2642
2643     RefPtr<RegisterID> scope = generator.emitNode(m_expr);
2644     generator.emitExpressionInfo(m_divot, m_divot - m_expressionLength, m_divot);
2645     generator.emitPushWithScope(generator.scopeRegister(), scope.get());
2646     generator.emitNode(dst, m_statement);
2647     generator.emitPopScope(generator.scopeRegister());
2648 }
2649
2650 // ------------------------------ CaseClauseNode --------------------------------
2651
2652 inline void CaseClauseNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2653 {
2654     generator.emitProfileControlFlow(m_startOffset);
2655     if (!m_statements)
2656         return;
2657     m_statements->emitBytecode(generator, dst);
2658 }
2659
2660 // ------------------------------ CaseBlockNode --------------------------------
2661
2662 enum SwitchKind { 
2663     SwitchUnset = 0,
2664     SwitchNumber = 1, 
2665     SwitchString = 2, 
2666     SwitchNeither = 3 
2667 };
2668
2669 static void processClauseList(ClauseListNode* list, Vector<ExpressionNode*, 8>& literalVector, SwitchKind& typeForTable, bool& singleCharacterSwitch, int32_t& min_num, int32_t& max_num)
2670 {
2671     for (; list; list = list->getNext()) {
2672         ExpressionNode* clauseExpression = list->getClause()->expr();
2673         literalVector.append(clauseExpression);
2674         if (clauseExpression->isNumber()) {
2675             double value = static_cast<NumberNode*>(clauseExpression)->value();
2676             int32_t intVal = static_cast<int32_t>(value);
2677             if ((typeForTable & ~SwitchNumber) || (intVal != value)) {
2678                 typeForTable = SwitchNeither;
2679                 break;
2680             }
2681             if (intVal < min_num)
2682                 min_num = intVal;
2683             if (intVal > max_num)
2684                 max_num = intVal;
2685             typeForTable = SwitchNumber;
2686             continue;
2687         }
2688         if (clauseExpression->isString()) {
2689             if (typeForTable & ~SwitchString) {
2690                 typeForTable = SwitchNeither;
2691                 break;
2692             }
2693             const String& value = static_cast<StringNode*>(clauseExpression)->value().string();
2694             if (singleCharacterSwitch &= value.length() == 1) {
2695                 int32_t intVal = value[0];
2696                 if (intVal < min_num)
2697                     min_num = intVal;
2698                 if (intVal > max_num)
2699                     max_num = intVal;
2700             }
2701             typeForTable = SwitchString;
2702             continue;
2703         }
2704         typeForTable = SwitchNeither;
2705         break;        
2706     }
2707 }
2708
2709 static inline size_t length(ClauseListNode* list1, ClauseListNode* list2)
2710 {
2711     size_t length = 0;
2712     for (ClauseListNode* node = list1; node; node = node->getNext())
2713         ++length;
2714     for (ClauseListNode* node = list2; node; node = node->getNext())
2715         ++length;
2716     return length;
2717 }
2718
2719 SwitchInfo::SwitchType CaseBlockNode::tryTableSwitch(Vector<ExpressionNode*, 8>& literalVector, int32_t& min_num, int32_t& max_num)
2720 {
2721     if (length(m_list1, m_list2) < s_tableSwitchMinimum)
2722         return SwitchInfo::SwitchNone;
2723
2724     SwitchKind typeForTable = SwitchUnset;
2725     bool singleCharacterSwitch = true;
2726     
2727     processClauseList(m_list1, literalVector, typeForTable, singleCharacterSwitch, min_num, max_num);
2728     processClauseList(m_list2, literalVector, typeForTable, singleCharacterSwitch, min_num, max_num);
2729     
2730     if (typeForTable == SwitchUnset || typeForTable == SwitchNeither)
2731         return SwitchInfo::SwitchNone;
2732     
2733     if (typeForTable == SwitchNumber) {
2734         int32_t range = max_num - min_num;
2735         if (min_num <= max_num && range <= 1000 && (range / literalVector.size()) < 10)
2736             return SwitchInfo::SwitchImmediate;
2737         return SwitchInfo::SwitchNone;
2738     } 
2739     
2740     ASSERT(typeForTable == SwitchString);
2741     
2742     if (singleCharacterSwitch) {
2743         int32_t range = max_num - min_num;
2744         if (min_num <= max_num && range <= 1000 && (range / literalVector.size()) < 10)
2745             return SwitchInfo::SwitchCharacter;
2746     }
2747
2748     return SwitchInfo::SwitchString;
2749 }
2750
2751 void CaseBlockNode::emitBytecodeForBlock(BytecodeGenerator& generator, RegisterID* switchExpression, RegisterID* dst)
2752 {
2753     RefPtr<Label> defaultLabel;
2754     Vector<RefPtr<Label>, 8> labelVector;
2755     Vector<ExpressionNode*, 8> literalVector;
2756     int32_t min_num = std::numeric_limits<int32_t>::max();
2757     int32_t max_num = std::numeric_limits<int32_t>::min();
2758     SwitchInfo::SwitchType switchType = tryTableSwitch(literalVector, min_num, max_num);
2759
2760     if (switchType != SwitchInfo::SwitchNone) {
2761         // Prepare the various labels
2762         for (uint32_t i = 0; i < literalVector.size(); i++)
2763             labelVector.append(generator.newLabel());
2764         defaultLabel = generator.newLabel();
2765         generator.beginSwitch(switchExpression, switchType);
2766     } else {
2767         // Setup jumps
2768         for (ClauseListNode* list = m_list1; list; list = list->getNext()) {
2769             RefPtr<RegisterID> clauseVal = generator.newTemporary();
2770             generator.emitNode(clauseVal.get(), list->getClause()->expr());
2771             generator.emitBinaryOp(op_stricteq, clauseVal.get(), clauseVal.get(), switchExpression, OperandTypes());
2772             labelVector.append(generator.newLabel());
2773             generator.emitJumpIfTrue(clauseVal.get(), labelVector[labelVector.size() - 1].get());
2774         }
2775         
2776         for (ClauseListNode* list = m_list2; list; list = list->getNext()) {
2777             RefPtr<RegisterID> clauseVal = generator.newTemporary();
2778             generator.emitNode(clauseVal.get(), list->getClause()->expr());
2779             generator.emitBinaryOp(op_stricteq, clauseVal.get(), clauseVal.get(), switchExpression, OperandTypes());
2780             labelVector.append(generator.newLabel());
2781             generator.emitJumpIfTrue(clauseVal.get(), labelVector[labelVector.size() - 1].get());
2782         }
2783         defaultLabel = generator.newLabel();
2784         generator.emitJump(defaultLabel.get());
2785     }
2786
2787     size_t i = 0;
2788     for (ClauseListNode* list = m_list1; list; list = list->getNext()) {
2789         generator.emitLabel(labelVector[i++].get());
2790         list->getClause()->emitBytecode(generator, dst);
2791     }
2792
2793     if (m_defaultClause) {
2794         generator.emitLabel(defaultLabel.get());
2795         m_defaultClause->emitBytecode(generator, dst);
2796     }
2797
2798     for (ClauseListNode* list = m_list2; list; list = list->getNext()) {
2799         generator.emitLabel(labelVector[i++].get());
2800         list->getClause()->emitBytecode(generator, dst);
2801     }
2802     if (!m_defaultClause)
2803         generator.emitLabel(defaultLabel.get());
2804
2805     ASSERT(i == labelVector.size());
2806     if (switchType != SwitchInfo::SwitchNone) {
2807         ASSERT(labelVector.size() == literalVector.size());
2808         generator.endSwitch(labelVector.size(), labelVector.data(), literalVector.data(), defaultLabel.get(), min_num, max_num);
2809     }
2810 }
2811
2812 // ------------------------------ SwitchNode -----------------------------------
2813
2814 void SwitchNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2815 {
2816     generator.emitDebugHook(WillExecuteStatement, firstLine(), startOffset(), lineStartOffset());
2817     
2818     LabelScopePtr scope = generator.newLabelScope(LabelScope::Switch);
2819
2820     RefPtr<RegisterID> r0 = generator.emitNode(m_expr);
2821     m_block->emitBytecodeForBlock(generator, r0.get(), dst);
2822
2823     generator.emitLabel(scope->breakTarget());
2824     generator.emitProfileControlFlow(endOffset());
2825 }
2826
2827 // ------------------------------ LabelNode ------------------------------------
2828
2829 void LabelNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2830 {
2831     generator.emitDebugHook(WillExecuteStatement, firstLine(), startOffset(), lineStartOffset());
2832
2833     ASSERT(!generator.breakTarget(m_name));
2834
2835     LabelScopePtr scope = generator.newLabelScope(LabelScope::NamedLabel, &m_name);
2836     generator.emitNode(dst, m_statement);
2837
2838     generator.emitLabel(scope->breakTarget());
2839 }
2840
2841 // ------------------------------ ThrowNode ------------------------------------
2842
2843 void ThrowNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2844 {
2845     generator.emitDebugHook(WillExecuteStatement, firstLine(), startOffset(), lineStartOffset());
2846
2847     if (dst == generator.ignoredResult())
2848         dst = 0;
2849     RefPtr<RegisterID> expr = generator.emitNode(m_expr);
2850     generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
2851     generator.emitThrow(expr.get());
2852
2853     generator.emitProfileControlFlow(endOffset()); 
2854 }
2855
2856 // ------------------------------ TryNode --------------------------------------
2857
2858 void TryNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2859 {
2860     // NOTE: The catch and finally blocks must be labeled explicitly, so the
2861     // optimizer knows they may be jumped to from anywhere.
2862
2863     generator.emitDebugHook(WillExecuteStatement, firstLine(), startOffset(), lineStartOffset());
2864
2865     ASSERT(m_catchBlock || m_finallyBlock);
2866
2867     RefPtr<Label> tryStartLabel = generator.newLabel();
2868     generator.emitLabel(tryStartLabel.get());
2869     
2870     if (m_finallyBlock)
2871         generator.pushFinallyContext(m_finallyBlock);
2872     TryData* tryData = generator.pushTry(tryStartLabel.get());
2873
2874     generator.emitNode(dst, m_tryBlock);
2875
2876     if (m_catchBlock) {
2877         RefPtr<Label> catchEndLabel = generator.newLabel();
2878         
2879         // Normal path: jump over the catch block.
2880         generator.emitJump(catchEndLabel.get());
2881
2882         // Uncaught exception path: the catch block.
2883         RefPtr<Label> here = generator.emitLabel(generator.newLabel().get());
2884         RefPtr<RegisterID> exceptionRegister = generator.popTryAndEmitCatch(tryData, generator.newTemporary(), here.get(), HandlerType::Catch);
2885         
2886         if (m_finallyBlock) {
2887             // If the catch block throws an exception and we have a finally block, then the finally
2888             // block should "catch" that exception.
2889             tryData = generator.pushTry(here.get());
2890         }
2891
2892         generator.emitPushCatchScope(generator.scopeRegister(), m_exceptionIdent, exceptionRegister.get(), DontDelete);
2893         generator.emitProfileControlFlow(m_tryBlock->endOffset() + 1);
2894         generator.emitNode(dst, m_catchBlock);
2895         generator.emitPopScope(generator.scopeRegister());
2896         generator.emitLabel(catchEndLabel.get());
2897     }
2898
2899     if (m_finallyBlock) {
2900         RefPtr<Label> preFinallyLabel = generator.emitLabel(generator.newLabel().get());
2901         
2902         generator.popFinallyContext();
2903
2904         RefPtr<Label> finallyEndLabel = generator.newLabel();
2905
2906         int finallyStartOffset = m_catchBlock ? m_catchBlock->endOffset() + 1 : m_tryBlock->endOffset() + 1;
2907
2908         // Normal path: run the finally code, and jump to the end.
2909         generator.emitProfileControlFlow(finallyStartOffset);
2910         generator.emitNode(dst, m_finallyBlock);
2911         generator.emitProfileControlFlow(m_finallyBlock->endOffset() + 1);
2912         generator.emitJump(finallyEndLabel.get());
2913
2914         // Uncaught exception path: invoke the finally block, then re-throw the exception.
2915         RefPtr<RegisterID> tempExceptionRegister = generator.popTryAndEmitCatch(tryData, generator.newTemporary(), preFinallyLabel.get(), HandlerType::Finally);
2916         generator.emitProfileControlFlow(finallyStartOffset);
2917         generator.emitNode(dst, m_finallyBlock);
2918         generator.emitThrow(tempExceptionRegister.get());
2919
2920         generator.emitLabel(finallyEndLabel.get());
2921         generator.emitProfileControlFlow(m_finallyBlock->endOffset() + 1);
2922     } else
2923         generator.emitProfileControlFlow(m_catchBlock->endOffset() + 1);
2924
2925 }
2926
2927 // ------------------------------ ScopeNode -----------------------------
2928
2929 inline void ScopeNode::emitStatementsBytecode(BytecodeGenerator& generator, RegisterID* dst)
2930 {
2931     if (!m_statements)
2932         return;
2933     m_statements->emitBytecode(generator, dst);
2934 }
2935
2936 // ------------------------------ ProgramNode -----------------------------
2937
2938 void ProgramNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
2939 {
2940     generator.emitDebugHook(WillExecuteProgram, startLine(), startStartOffset(), startLineStartOffset());
2941
2942     RefPtr<RegisterID> dstRegister = generator.newTemporary();
2943     generator.emitLoad(dstRegister.get(), jsUndefined());
2944     generator.emitProfileControlFlow(startStartOffset());
2945     emitStatementsBytecode(generator, dstRegister.get());
2946
2947     generator.emitDebugHook(DidExecuteProgram, lastLine(), startOffset(), lineStartOffset());
2948     generator.emitEnd(dstRegister.get());
2949 }
2950
2951 // ------------------------------ EvalNode -----------------------------
2952
2953 void EvalNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
2954 {
2955     generator.emitDebugHook(WillExecuteProgram, startLine(), startStartOffset(), startLineStartOffset());
2956
2957     RefPtr<RegisterID> dstRegister = generator.newTemporary();
2958     generator.emitLoad(dstRegister.get(), jsUndefined());
2959     emitStatementsBytecode(generator, dstRegister.get());
2960
2961     generator.emitDebugHook(DidExecuteProgram, lastLine(), startOffset(), lineStartOffset());
2962     generator.emitEnd(dstRegister.get());
2963 }
2964
2965 // ------------------------------ FunctionBodyNode -----------------------------
2966
2967 void FunctionBodyNode::emitBytecode(BytecodeGenerator&, RegisterID*)
2968 {
2969 }
2970
2971 void FunctionNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
2972 {
2973     if (generator.vm()->typeProfiler()) {
2974         for (size_t i = 0; i < m_parameters->size(); i++) {
2975             // FIXME: Handle Destructuring assignments into arguments.
2976             if (!m_parameters->at(i)->isBindingNode())
2977                 continue;
2978             BindingNode* parameter = static_cast<BindingNode*>(m_parameters->at(i));
2979             RegisterID reg(CallFrame::argumentOffset(i));
2980             generator.emitProfileType(&reg, ProfileTypeBytecodeFunctionArgument, nullptr);
2981             generator.emitTypeProfilerExpressionInfo(parameter->divotStart(), parameter->divotEnd());
2982         }
2983     }
2984
2985     generator.emitProfileControlFlow(startStartOffset());
2986     generator.emitDebugHook(DidEnterCallFrame, startLine(), startStartOffset(), startLineStartOffset());
2987     emitStatementsBytecode(generator, generator.ignoredResult());
2988
2989     StatementNode* singleStatement = this->singleStatement();
2990     ReturnNode* returnNode = 0;
2991
2992     // Check for a return statement at the end of a function composed of a single block.
2993     if (singleStatement && singleStatement->isBlock()) {
2994         StatementNode* lastStatementInBlock = static_cast<BlockNode*>(singleStatement)->lastStatement();
2995         if (lastStatementInBlock && lastStatementInBlock->isReturnNode())
2996             returnNode = static_cast<ReturnNode*>(lastStatementInBlock);
2997     }
2998
2999     // If there is no return we must automatically insert one.
3000     if (!returnNode) {
3001         RegisterID* r0 = generator.isConstructor() ? generator.thisRegister() : generator.emitLoad(0, jsUndefined());
3002         if (generator.vm()->typeProfiler())
3003             generator.emitProfileType(r0, ProfileTypeBytecodeFunctionReturnStatement, nullptr); // Do not emit expression info for this profile because it's not in the user's source code.
3004         ASSERT(startOffset() >= lineStartOffset());
3005         generator.emitDebugHook(WillLeaveCallFrame, lastLine(), startOffset(), lineStartOffset());
3006         generator.emitReturn(r0);
3007         return;
3008     }
3009 }
3010
3011 // ------------------------------ FuncDeclNode ---------------------------------
3012
3013 void FuncDeclNode::emitBytecode(BytecodeGenerator&, RegisterID*)
3014 {
3015 }
3016
3017 // ------------------------------ FuncExprNode ---------------------------------
3018
3019 RegisterID* FuncExprNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
3020 {
3021     return generator.emitNewFunctionExpression(generator.finalDestination(dst), this);
3022 }
3023
3024 #if ENABLE(ES6_CLASS_SYNTAX)
3025 // ------------------------------ ClassDeclNode ---------------------------------
3026
3027 void ClassDeclNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
3028 {
3029     generator.emitNode(dst, m_classDeclaration);
3030 }
3031
3032 // ------------------------------ ClassExprNode ---------------------------------
3033
3034 RegisterID* ClassExprNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
3035 {
3036     RefPtr<RegisterID> superclass;
3037     if (m_classHeritage) {
3038         superclass = generator.newTemporary();
3039         generator.emitNode(superclass.get(), m_classHeritage);
3040     }
3041
3042     RefPtr<RegisterID> constructor;
3043
3044     // FIXME: Make the prototype non-configurable & non-writable.
3045     if (m_constructorExpression)
3046         constructor = generator.emitNode(dst, m_constructorExpression);
3047     else {
3048         constructor = generator.emitNewDefaultConstructor(generator.finalDestination(dst),
3049             m_classHeritage ? ConstructorKind::Derived : ConstructorKind::Base, m_name);
3050     }
3051
3052     const auto& propertyNames = generator.propertyNames();
3053     RefPtr<RegisterID> prototype = generator.emitNewObject(generator.newTemporary());
3054
3055     if (superclass) {
3056         RefPtr<RegisterID> protoParent = generator.newTemporary();
3057         generator.emitLoad(protoParent.get(), jsNull());
3058
3059         RefPtr<RegisterID> tempRegister = generator.newTemporary();
3060
3061         // FIXME: Throw TypeError if it's a generator function.
3062         RefPtr<Label> superclassIsUndefinedLabel = generator.newLabel();
3063         generator.emitJumpIfTrue(generator.emitIsUndefined(tempRegister.get(), superclass.get()), superclassIsUndefinedLabel.get());
3064
3065         RefPtr<Label> superclassIsNullLabel = generator.newLabel();
3066         generator.emitJumpIfTrue(generator.emitUnaryOp(op_eq_null, tempRegister.get(), superclass.get()), superclassIsNullLabel.get());
3067
3068         RefPtr<Label> superclassIsObjectLabel = generator.newLabel();
3069         generator.emitJumpIfTrue(generator.emitIsObject(tempRegister.get(), superclass.get()), superclassIsObjectLabel.get());
3070         generator.emitLabel(superclassIsUndefinedLabel.get());
3071         generator.emitThrowTypeError(ASCIILiteral("The superclass is not an object."));
3072         generator.emitLabel(superclassIsObjectLabel.get());
3073         generator.emitGetById(protoParent.get(), superclass.get(), generator.propertyNames().prototype);
3074
3075         RefPtr<Label> protoParentIsObjectOrNullLabel = generator.newLabel();
3076         generator.emitJumpIfTrue(generator.emitUnaryOp(op_is_object_or_null, tempRegister.get(), protoParent.get()), protoParentIsObjectOrNullLabel.get());
3077         generator.emitThrowTypeError(ASCIILiteral("The superclass's prototype is not an object."));
3078         generator.emitLabel(protoParentIsObjectOrNullLabel.get());
3079
3080         generator.emitDirectPutById(constructor.get(), generator.propertyNames().underscoreProto, superclass.get(), PropertyNode::Unknown);
3081         generator.emitLabel(superclassIsNullLabel.get());
3082         generator.emitDirectPutById(prototype.get(), generator.propertyNames().underscoreProto, protoParent.get(), PropertyNode::Unknown);
3083
3084         emitPutHomeObject(generator, constructor.get(), prototype.get());
3085     }
3086
3087     RefPtr<RegisterID> constructorNameRegister = generator.emitLoad(generator.newTemporary(), propertyNames.constructor);
3088     generator.emitCallDefineProperty(prototype.get(), constructorNameRegister.get(), constructor.get(), nullptr, nullptr,
3089         BytecodeGenerator::PropertyConfigurable | BytecodeGenerator::PropertyWritable, m_position);
3090
3091     RefPtr<RegisterID> prototypeNameRegister = generator.emitLoad(generator.newTemporary(), propertyNames.prototype);
3092     generator.emitCallDefineProperty(constructor.get(), prototypeNameRegister.get(), prototype.get(), nullptr, nullptr, 0, m_position);
3093
3094     if (m_staticMethods)
3095         generator.emitNode(constructor.get(), m_staticMethods);
3096
3097     if (m_instanceMethods)
3098         generator.emitNode(prototype.get(), m_instanceMethods);
3099
3100     return generator.moveToDestinationIfNeeded(dst, constructor.get());
3101 }
3102 #endif
3103     
3104 // ------------------------------ DeconstructingAssignmentNode -----------------
3105 RegisterID* DeconstructingAssignmentNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
3106 {
3107     if (RegisterID* result = m_bindings->emitDirectBinding(generator, dst, m_initializer))
3108         return result;
3109     RefPtr<RegisterID> initializer = generator.tempDestination(dst);
3110     generator.emitNode(initializer.get(), m_initializer);
3111     m_bindings->bindValue(generator, initializer.get());
3112     return generator.moveToDestinationIfNeeded(dst, initializer.get());
3113 }
3114
3115 DeconstructionPatternNode::~DeconstructionPatternNode()
3116 {
3117 }
3118     
3119 void ArrayPatternNode::bindValue(BytecodeGenerator& generator, RegisterID* rhs) const
3120 {
3121     for (size_t i = 0; i < m_targetPatterns.size(); i++) {
3122         auto target = m_targetPatterns[i];
3123         if (!target)
3124             continue;
3125         RefPtr<RegisterID> temp = generator.newTemporary();
3126         generator.emitLoad(temp.get(), jsNumber(i));
3127         generator.emitGetByVal(temp.get(), rhs, temp.get());
3128         target->bindValue(generator, temp.get());
3129     }
3130 }
3131
3132 RegisterID* ArrayPatternNode::emitDirectBinding(BytecodeGenerator& generator, RegisterID* dst, ExpressionNode* rhs)
3133 {
3134     if (!rhs->isSimpleArray())
3135         return 0;
3136
3137     RefPtr<RegisterID> resultRegister;
3138     if (dst && dst != generator.ignoredResult())
3139         resultRegister = generator.emitNewArray(generator.newTemporary(), 0, 0);
3140     ElementNode* elementNodes = static_cast<ArrayNode*>(rhs)->elements();
3141     Vector<ExpressionNode*> elements;
3142     for (; elementNodes; elementNodes = elementNodes->next())
3143         elements.append(elementNodes->value());
3144     if (m_targetPatterns.size() != elements.size())
3145         return 0;
3146     Vector<RefPtr<RegisterID>> registers;
3147     registers.reserveCapacity(m_targetPatterns.size());
3148     for (size_t i = 0; i < m_targetPatterns.size(); i++) {
3149         registers.uncheckedAppend(generator.newTemporary());
3150         generator.emitNode(registers.last().get(), elements[i]);
3151         if (resultRegister)
3152             generator.emitPutByIndex(resultRegister.get(), i, registers.last().get());
3153     }
3154     
3155     for (size_t i = 0; i < m_targetPatterns.size(); i++) {
3156         if (m_targetPatterns[i])
3157             m_targetPatterns[i]->bindValue(generator, registers[i].get());
3158     }
3159     if (resultRegister)
3160         return generator.moveToDestinationIfNeeded(dst, resultRegister.get());
3161     return generator.emitLoad(generator.finalDestination(dst), jsUndefined());
3162 }
3163
3164 void ArrayPatternNode::toString(StringBuilder& builder) const
3165 {
3166     builder.append('[');
3167     for (size_t i = 0; i < m_targetPatterns.size(); i++) {
3168         if (!m_targetPatterns[i]) {
3169             builder.append(',');
3170             continue;
3171         }
3172         m_targetPatterns[i]->toString(builder);
3173         if (i < m_targetPatterns.size() - 1)
3174             builder.append(',');
3175     }
3176     builder.append(']');
3177 }
3178
3179 void ArrayPatternNode::collectBoundIdentifiers(Vector<Identifier>& identifiers) const
3180 {
3181     for (size_t i = 0; i < m_targetPatterns.size(); i++) {
3182         if (DeconstructionPatternNode* node = m_targetPatterns[i].get())
3183             node->collectBoundIdentifiers(identifiers);
3184     }
3185 }
3186
3187 void ObjectPatternNode::toString(StringBuilder& builder) const
3188 {
3189     builder.append('{');
3190     for (size_t i = 0; i < m_targetPatterns.size(); i++) {
3191         if (m_targetPatterns[i].wasString)
3192             builder.appendQuotedJSONString(m_targetPatterns[i].propertyName.string());
3193         else
3194             builder.append(m_targetPatterns[i].propertyName.string());
3195         builder.append(':');
3196         m_targetPatterns[i].pattern->toString(builder);
3197         if (i < m_targetPatterns.size() - 1)
3198             builder.append(',');
3199     }
3200     builder.append('}');
3201 }
3202     
3203 void ObjectPatternNode::bindValue(BytecodeGenerator& generator, RegisterID* rhs) const
3204 {
3205     for (size_t i = 0; i < m_targetPatterns.size(); i++) {
3206         auto& target = m_targetPatterns[i];
3207         RefPtr<RegisterID> temp = generator.newTemporary();
3208         generator.emitGetById(temp.get(), rhs, target.propertyName);
3209         target.pattern->bindValue(generator, temp.get());
3210     }
3211 }
3212
3213 void ObjectPatternNode::collectBoundIdentifiers(Vector<Identifier>& identifiers) const
3214 {
3215     for (size_t i = 0; i < m_targetPatterns.size(); i++)
3216         m_targetPatterns[i].pattern->collectBoundIdentifiers(identifiers);
3217 }
3218
3219 void BindingNode::bindValue(BytecodeGenerator& generator, RegisterID* value) const
3220 {
3221     Variable var = generator.variable(m_boundProperty);
3222     if (RegisterID* local = var.local()) {
3223         if (var.isReadOnly()) {
3224             generator.emitReadOnlyExceptionIfNeeded();
3225             return;
3226         }
3227         generator.emitMove(local, value);
3228         if (generator.vm()->typeProfiler())
3229             generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd());
3230         return;
3231     }
3232     if (generator.isStrictMode())
3233         generator.emitExpressionInfo(divotEnd(), divotStart(), divotEnd());
3234     RegisterID* scope = generator.emitResolveScope(nullptr, var);
3235     generator.emitExpressionInfo(divotEnd(), divotStart(), divotEnd());
3236     generator.emitPutToScope(scope, var, value, generator.isStrictMode() ? ThrowIfNotFound : DoNotThrowIfNotFound);
3237     if (generator.vm()->typeProfiler()) {
3238         generator.emitProfileType(value, var.isResolved() ? ProfileTypeBytecodePutToLocalScope : ProfileTypeBytecodePutToScope, &m_boundProperty);
3239         generator.emitTypeProfilerExpressionInfo(divotStart(), divotEnd());
3240     }
3241     return;
3242 }
3243
3244 void BindingNode::toString(StringBuilder& builder) const
3245 {
3246     builder.append(m_boundProperty.string());
3247 }
3248
3249 void BindingNode::collectBoundIdentifiers(Vector<Identifier>& identifiers) const
3250 {
3251     identifiers.append(m_boundProperty);
3252 }
3253     
3254 RegisterID* SpreadExpressionNode::emitBytecode(BytecodeGenerator&, RegisterID*)
3255 {
3256     RELEASE_ASSERT_NOT_REACHED();
3257     return 0;
3258 }
3259
3260 } // namespace JSC