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