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