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