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