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