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