JavaScriptCore bytecompiler does not compute scope depth correctly
[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 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 *
9 *  This library is free software; you can redistribute it and/or
10 *  modify it under the terms of the GNU Library General Public
11 *  License as published by the Free Software Foundation; either
12 *  version 2 of the License, or (at your option) any later version.
13 *
14 *  This library is distributed in the hope that it will be useful,
15 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17 *  Library General Public License for more details.
18 *
19 *  You should have received a copy of the GNU Library General Public License
20 *  along with this library; see the file COPYING.LIB.  If not, write to
21 *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
22 *  Boston, MA 02110-1301, USA.
23 *
24 */
25
26 #include "config.h"
27 #include "Nodes.h"
28 #include "NodeConstructors.h"
29
30 #include "BytecodeGenerator.h"
31 #include "CallFrame.h"
32 #include "Debugger.h"
33 #include "JIT.h"
34 #include "JSFunction.h"
35 #include "JSGlobalObject.h"
36 #include "JSStaticScopeObject.h"
37 #include "LabelScope.h"
38 #include "Lexer.h"
39 #include "Operations.h"
40 #include "Parser.h"
41 #include "PropertyNameArray.h"
42 #include "RegExpCache.h"
43 #include "RegExpObject.h"
44 #include "SamplingTool.h"
45 #include "UStringConcatenate.h"
46 #include <wtf/Assertions.h>
47 #include <wtf/RefCountedLeakCounter.h>
48 #include <wtf/Threading.h>
49
50 using namespace WTF;
51
52 namespace JSC {
53
54 /*
55     Details of the emitBytecode function.
56
57     Return value: The register holding the production's value.
58              dst: An optional parameter specifying the most efficient destination at
59                   which to store the production's value. The callee must honor dst.
60
61     The dst argument provides for a crude form of copy propagation. For example,
62
63         x = 1
64
65     becomes
66     
67         load r[x], 1
68     
69     instead of 
70
71         load r0, 1
72         mov r[x], r0
73     
74     because the assignment node, "x =", passes r[x] as dst to the number node, "1".
75 */
76
77 // ------------------------------ ThrowableExpressionData --------------------------------
78
79 RegisterID* ThrowableExpressionData::emitThrowReferenceError(BytecodeGenerator& generator, const UString& message)
80 {
81     generator.emitExpressionInfo(divot(), startOffset(), endOffset());
82     generator.emitThrowReferenceError(message);
83     return generator.newTemporary();
84 }
85
86 // ------------------------------ NullNode -------------------------------------
87
88 RegisterID* NullNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
89 {
90     if (dst == generator.ignoredResult())
91         return 0;
92     return generator.emitLoad(dst, jsNull());
93 }
94
95 // ------------------------------ BooleanNode ----------------------------------
96
97 RegisterID* BooleanNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
98 {
99     if (dst == generator.ignoredResult())
100         return 0;
101     return generator.emitLoad(dst, m_value);
102 }
103
104 // ------------------------------ NumberNode -----------------------------------
105
106 RegisterID* NumberNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
107 {
108     if (dst == generator.ignoredResult())
109         return 0;
110     return generator.emitLoad(dst, m_value);
111 }
112
113 // ------------------------------ StringNode -----------------------------------
114
115 RegisterID* StringNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
116 {
117     if (dst == generator.ignoredResult())
118         return 0;
119     return generator.emitLoad(dst, m_value);
120 }
121
122 // ------------------------------ RegExpNode -----------------------------------
123
124 RegisterID* RegExpNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
125 {
126     if (dst == generator.ignoredResult())
127         return 0;
128     return generator.emitNewRegExp(generator.finalDestination(dst), RegExp::create(*generator.globalData(), m_pattern.ustring(), regExpFlags(m_flags.ustring())));
129 }
130
131 // ------------------------------ ThisNode -------------------------------------
132
133 RegisterID* ThisNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
134 {
135     if (dst == generator.ignoredResult())
136         return 0;
137     return generator.moveToDestinationIfNeeded(dst, generator.thisRegister());
138 }
139
140 // ------------------------------ ResolveNode ----------------------------------
141
142 bool ResolveNode::isPure(BytecodeGenerator& generator) const
143 {
144     return generator.isLocal(m_ident);
145 }
146
147 RegisterID* ResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
148 {
149     if (RegisterID* local = generator.registerFor(m_ident)) {
150         if (dst == generator.ignoredResult())
151             return 0;
152         return generator.moveToDestinationIfNeeded(dst, local);
153     }
154     
155     generator.emitExpressionInfo(m_startOffset + m_ident.length(), m_ident.length(), 0);
156     return generator.emitResolve(generator.finalDestination(dst), m_ident);
157 }
158
159 // ------------------------------ ArrayNode ------------------------------------
160
161 RegisterID* ArrayNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
162 {
163     // FIXME: Should we put all of this code into emitNewArray?
164
165     unsigned length = 0;
166     ElementNode* firstPutElement;
167     for (firstPutElement = m_element; firstPutElement; firstPutElement = firstPutElement->next()) {
168         if (firstPutElement->elision())
169             break;
170         ++length;
171     }
172
173     if (!firstPutElement && !m_elision)
174         return generator.emitNewArray(generator.finalDestination(dst), m_element, length);
175
176     RefPtr<RegisterID> array = generator.emitNewArray(generator.tempDestination(dst), m_element, length);
177
178     for (ElementNode* n = firstPutElement; n; n = n->next()) {
179         RegisterID* value = generator.emitNode(n->value());
180         length += n->elision();
181         generator.emitPutByIndex(array.get(), length++, value);
182     }
183
184     if (m_elision) {
185         RegisterID* value = generator.emitLoad(0, jsNumber(m_elision + length));
186         generator.emitPutById(array.get(), generator.propertyNames().length, value);
187     }
188
189     return generator.moveToDestinationIfNeeded(dst, array.get());
190 }
191
192 bool ArrayNode::isSimpleArray() const
193 {
194     if (m_elision || m_optional)
195         return false;
196     for (ElementNode* ptr = m_element; ptr; ptr = ptr->next()) {
197         if (ptr->elision())
198             return false;
199     }
200     return true;
201 }
202
203 ArgumentListNode* ArrayNode::toArgumentList(JSGlobalData* globalData) const
204 {
205     ASSERT(!m_elision && !m_optional);
206     ElementNode* ptr = m_element;
207     if (!ptr)
208         return 0;
209     ArgumentListNode* head = new (globalData) ArgumentListNode(globalData, ptr->value());
210     ArgumentListNode* tail = head;
211     ptr = ptr->next();
212     for (; ptr; ptr = ptr->next()) {
213         ASSERT(!ptr->elision());
214         tail = new (globalData) ArgumentListNode(globalData, tail, ptr->value());
215     }
216     return head;
217 }
218
219 // ------------------------------ ObjectLiteralNode ----------------------------
220
221 RegisterID* ObjectLiteralNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
222 {
223      if (!m_list) {
224          if (dst == generator.ignoredResult())
225              return 0;
226          return generator.emitNewObject(generator.finalDestination(dst));
227      }
228      return generator.emitNode(dst, m_list);
229 }
230
231 // ------------------------------ PropertyListNode -----------------------------
232
233 RegisterID* PropertyListNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
234 {
235     RefPtr<RegisterID> newObj = generator.tempDestination(dst);
236     
237     generator.emitNewObject(newObj.get());
238     
239     for (PropertyListNode* p = this; p; p = p->m_next) {
240         RegisterID* value = generator.emitNode(p->m_node->m_assign);
241         
242         switch (p->m_node->m_type) {
243             case PropertyNode::Constant: {
244                 generator.emitDirectPutById(newObj.get(), p->m_node->name(), value);
245                 break;
246             }
247             case PropertyNode::Getter: {
248                 generator.emitPutGetter(newObj.get(), p->m_node->name(), value);
249                 break;
250             }
251             case PropertyNode::Setter: {
252                 generator.emitPutSetter(newObj.get(), p->m_node->name(), value);
253                 break;
254             }
255             default:
256                 ASSERT_NOT_REACHED();
257         }
258     }
259     
260     return generator.moveToDestinationIfNeeded(dst, newObj.get());
261 }
262
263 // ------------------------------ BracketAccessorNode --------------------------------
264
265 RegisterID* BracketAccessorNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
266 {
267     if (m_base->isResolveNode() && generator.willResolveToArguments(static_cast<ResolveNode*>(m_base)->identifier())) {
268         RegisterID* property = generator.emitNode(m_subscript);
269         generator.emitExpressionInfo(divot(), startOffset(), endOffset());    
270         return generator.emitGetArgumentByVal(generator.finalDestination(dst), generator.uncheckedRegisterForArguments(), property);
271     }
272
273     RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base, m_subscriptHasAssignments, m_subscript->isPure(generator));
274     RegisterID* property = generator.emitNode(m_subscript);
275     generator.emitExpressionInfo(divot(), startOffset(), endOffset());
276     return generator.emitGetByVal(generator.finalDestination(dst), base.get(), property);
277 }
278
279 // ------------------------------ DotAccessorNode --------------------------------
280
281 RegisterID* DotAccessorNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
282 {
283     if (m_ident == generator.propertyNames().length) {
284         if (!m_base->isResolveNode())
285             goto nonArgumentsPath;
286         ResolveNode* resolveNode = static_cast<ResolveNode*>(m_base);
287         if (!generator.willResolveToArguments(resolveNode->identifier()))
288             goto nonArgumentsPath;
289         generator.emitExpressionInfo(divot(), startOffset(), endOffset());    
290         return generator.emitGetArgumentsLength(generator.finalDestination(dst), generator.uncheckedRegisterForArguments());
291     }
292
293 nonArgumentsPath:
294     RegisterID* base = generator.emitNode(m_base);
295     generator.emitExpressionInfo(divot(), startOffset(), endOffset());
296     return generator.emitGetById(generator.finalDestination(dst), base, m_ident);
297 }
298
299 // ------------------------------ ArgumentListNode -----------------------------
300
301 RegisterID* ArgumentListNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
302 {
303     ASSERT(m_expr);
304     return generator.emitNode(dst, m_expr);
305 }
306
307 // ------------------------------ NewExprNode ----------------------------------
308
309 RegisterID* NewExprNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
310 {
311     RefPtr<RegisterID> func = generator.emitNode(m_expr);
312     CallArguments callArguments(generator, m_args);
313     return generator.emitConstruct(generator.finalDestinationOrIgnored(dst), func.get(), callArguments, divot(), startOffset(), endOffset());
314 }
315
316 CallArguments::CallArguments(BytecodeGenerator& generator, ArgumentsNode* argumentsNode)
317     : m_argumentsNode(argumentsNode)
318 {
319     if (generator.shouldEmitProfileHooks())
320         m_profileHookRegister = generator.newTemporary();
321     m_argv.append(generator.newTemporary());
322     if (argumentsNode) {
323         for (ArgumentListNode* n = argumentsNode->m_listNode; n; n = n->m_next) {
324             m_argv.append(generator.newTemporary());
325             // op_call requires the arguments to be a sequential range of registers
326             ASSERT(m_argv[m_argv.size() - 1]->index() == m_argv[m_argv.size() - 2]->index() + 1);
327         }
328     }
329 }
330
331 // ------------------------------ EvalFunctionCallNode ----------------------------------
332
333 RegisterID* EvalFunctionCallNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
334 {
335     RefPtr<RegisterID> func = generator.tempDestination(dst);
336     CallArguments callArguments(generator, m_args);
337     generator.emitExpressionInfo(divot() - startOffset() + 4, 4, 0);
338     generator.emitResolveWithThis(callArguments.thisRegister(), func.get(), generator.propertyNames().eval);
339     return generator.emitCallEval(generator.finalDestination(dst, func.get()), func.get(), callArguments, divot(), startOffset(), endOffset());
340 }
341
342 // ------------------------------ FunctionCallValueNode ----------------------------------
343
344 RegisterID* FunctionCallValueNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
345 {
346     RefPtr<RegisterID> func = generator.emitNode(m_expr);
347     CallArguments callArguments(generator, m_args);
348     generator.emitLoad(callArguments.thisRegister(), jsUndefined());
349     return generator.emitCall(generator.finalDestinationOrIgnored(dst, func.get()), func.get(), callArguments, divot(), startOffset(), endOffset());
350 }
351
352 // ------------------------------ FunctionCallResolveNode ----------------------------------
353
354 RegisterID* FunctionCallResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
355 {
356     if (RefPtr<RegisterID> local = generator.registerFor(m_ident)) {
357         CallArguments callArguments(generator, m_args);
358         generator.emitLoad(callArguments.thisRegister(), jsUndefined());
359         return generator.emitCall(generator.finalDestinationOrIgnored(dst, callArguments.thisRegister()), local.get(), callArguments, divot(), startOffset(), endOffset());
360     }
361
362     int index = 0;
363     size_t depth = 0;
364     JSObject* globalObject = 0;
365     bool requiresDynamicChecks = false;
366     if (generator.findScopedProperty(m_ident, index, depth, false, requiresDynamicChecks, globalObject) && index != missingSymbolMarker() && !requiresDynamicChecks) {
367         RefPtr<RegisterID> func = generator.emitGetScopedVar(generator.newTemporary(), depth, index, globalObject);
368         CallArguments callArguments(generator, m_args);
369         generator.emitLoad(callArguments.thisRegister(), jsUndefined());
370         return generator.emitCall(generator.finalDestinationOrIgnored(dst, func.get()), func.get(), callArguments, divot(), startOffset(), endOffset());
371     }
372
373     RefPtr<RegisterID> func = generator.newTemporary();
374     CallArguments callArguments(generator, m_args);
375     int identifierStart = divot() - startOffset();
376     generator.emitExpressionInfo(identifierStart + m_ident.length(), m_ident.length(), 0);
377     generator.emitResolveWithThis(callArguments.thisRegister(), func.get(), m_ident);
378     return generator.emitCall(generator.finalDestinationOrIgnored(dst, func.get()), func.get(), callArguments, divot(), startOffset(), endOffset());
379 }
380
381 // ------------------------------ FunctionCallBracketNode ----------------------------------
382
383 RegisterID* FunctionCallBracketNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
384 {
385     RefPtr<RegisterID> base = generator.emitNode(m_base);
386     RegisterID* property = generator.emitNode(m_subscript);
387     generator.emitExpressionInfo(divot() - m_subexpressionDivotOffset, startOffset() - m_subexpressionDivotOffset, m_subexpressionEndOffset);
388     RefPtr<RegisterID> function = generator.emitGetByVal(generator.tempDestination(dst), base.get(), property);
389     CallArguments callArguments(generator, m_args);
390     generator.emitMove(callArguments.thisRegister(), base.get());
391     return generator.emitCall(generator.finalDestinationOrIgnored(dst, function.get()), function.get(), callArguments, divot(), startOffset(), endOffset());
392 }
393
394 // ------------------------------ FunctionCallDotNode ----------------------------------
395
396 RegisterID* FunctionCallDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
397 {
398     RefPtr<RegisterID> function = generator.tempDestination(dst);
399     CallArguments callArguments(generator, m_args);
400     generator.emitNode(callArguments.thisRegister(), m_base);
401     generator.emitExpressionInfo(divot() - m_subexpressionDivotOffset, startOffset() - m_subexpressionDivotOffset, m_subexpressionEndOffset);
402     generator.emitMethodCheck();
403     generator.emitGetById(function.get(), callArguments.thisRegister(), m_ident);
404     return generator.emitCall(generator.finalDestinationOrIgnored(dst, function.get()), function.get(), callArguments, divot(), startOffset(), endOffset());
405 }
406
407 RegisterID* CallFunctionCallDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
408 {
409     RefPtr<Label> realCall = generator.newLabel();
410     RefPtr<Label> end = generator.newLabel();
411     RefPtr<RegisterID> base = generator.emitNode(m_base);
412     generator.emitExpressionInfo(divot() - m_subexpressionDivotOffset, startOffset() - m_subexpressionDivotOffset, m_subexpressionEndOffset);
413     RefPtr<RegisterID> function = generator.emitGetById(generator.tempDestination(dst), base.get(), m_ident);
414     RefPtr<RegisterID> finalDestinationOrIgnored = generator.finalDestinationOrIgnored(dst, function.get());
415     generator.emitJumpIfNotFunctionCall(function.get(), realCall.get());
416     {
417         if (m_args->m_listNode && m_args->m_listNode->m_expr) {
418             ArgumentListNode* oldList = m_args->m_listNode;
419             m_args->m_listNode = m_args->m_listNode->m_next;
420
421             RefPtr<RegisterID> realFunction = generator.emitMove(generator.tempDestination(dst), base.get());
422             CallArguments callArguments(generator, m_args);
423             generator.emitNode(callArguments.thisRegister(), oldList->m_expr);
424             generator.emitCall(finalDestinationOrIgnored.get(), realFunction.get(), callArguments, divot(), startOffset(), endOffset());
425             generator.emitJump(end.get());
426
427             m_args->m_listNode = oldList;
428
429         } else {
430             RefPtr<RegisterID> realFunction = generator.emitMove(generator.tempDestination(dst), base.get());
431             CallArguments callArguments(generator, m_args);
432             generator.emitLoad(callArguments.thisRegister(), jsUndefined());
433             generator.emitCall(finalDestinationOrIgnored.get(), realFunction.get(), callArguments, divot(), startOffset(), endOffset());
434             generator.emitJump(end.get());
435         }
436     }
437     generator.emitLabel(realCall.get());
438     {
439         CallArguments callArguments(generator, m_args);
440         generator.emitMove(callArguments.thisRegister(), base.get());
441         generator.emitCall(finalDestinationOrIgnored.get(), function.get(), callArguments, divot(), startOffset(), endOffset());
442     }
443     generator.emitLabel(end.get());
444     return finalDestinationOrIgnored.get();
445 }
446
447 static bool areTrivialApplyArguments(ArgumentsNode* args)
448 {
449     return !args->m_listNode || !args->m_listNode->m_expr || !args->m_listNode->m_next
450         || (!args->m_listNode->m_next->m_next && args->m_listNode->m_next->m_expr->isSimpleArray());
451 }
452
453 RegisterID* ApplyFunctionCallDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
454 {
455     // A few simple cases can be trivially handled as ordinary function calls.
456     // function.apply(), function.apply(arg) -> identical to function.call
457     // function.apply(thisArg, [arg0, arg1, ...]) -> can be trivially coerced into function.call(thisArg, arg0, arg1, ...) and saves object allocation
458     bool mayBeCall = areTrivialApplyArguments(m_args);
459
460     RefPtr<Label> realCall = generator.newLabel();
461     RefPtr<Label> end = generator.newLabel();
462     RefPtr<RegisterID> base = generator.emitNode(m_base);
463     generator.emitExpressionInfo(divot() - m_subexpressionDivotOffset, startOffset() - m_subexpressionDivotOffset, m_subexpressionEndOffset);
464     RefPtr<RegisterID> function = generator.emitGetById(generator.tempDestination(dst), base.get(), m_ident);
465     RefPtr<RegisterID> finalDestinationOrIgnored = generator.finalDestinationOrIgnored(dst, function.get());
466     generator.emitJumpIfNotFunctionApply(function.get(), realCall.get());
467     {
468         if (mayBeCall) {
469             if (m_args->m_listNode && m_args->m_listNode->m_expr) {
470                 ArgumentListNode* oldList = m_args->m_listNode;
471                 if (m_args->m_listNode->m_next) {
472                     ASSERT(m_args->m_listNode->m_next->m_expr->isSimpleArray());
473                     ASSERT(!m_args->m_listNode->m_next->m_next);
474                     m_args->m_listNode = static_cast<ArrayNode*>(m_args->m_listNode->m_next->m_expr)->toArgumentList(generator.globalData());
475                     RefPtr<RegisterID> realFunction = generator.emitMove(generator.tempDestination(dst), base.get());
476                     CallArguments callArguments(generator, m_args);
477                     generator.emitNode(callArguments.thisRegister(), oldList->m_expr);
478                     generator.emitCall(finalDestinationOrIgnored.get(), realFunction.get(), callArguments, divot(), startOffset(), endOffset());
479                 } else {
480                     m_args->m_listNode = m_args->m_listNode->m_next;
481                     RefPtr<RegisterID> realFunction = generator.emitMove(generator.tempDestination(dst), base.get());
482                     CallArguments callArguments(generator, m_args);
483                     generator.emitNode(callArguments.thisRegister(), oldList->m_expr);
484                     generator.emitCall(finalDestinationOrIgnored.get(), realFunction.get(), callArguments, divot(), startOffset(), endOffset());
485                 }
486                 m_args->m_listNode = oldList;
487             } else {
488                 RefPtr<RegisterID> realFunction = generator.emitMove(generator.tempDestination(dst), base.get());
489                 CallArguments callArguments(generator, m_args);
490                 generator.emitLoad(callArguments.thisRegister(), jsUndefined());
491                 generator.emitCall(finalDestinationOrIgnored.get(), realFunction.get(), callArguments, divot(), startOffset(), endOffset());
492             }
493         } else {
494             ASSERT(m_args->m_listNode && m_args->m_listNode->m_next);
495             RefPtr<RegisterID> realFunction = generator.emitMove(generator.newTemporary(), base.get());
496             RefPtr<RegisterID> argsCountRegister = generator.newTemporary();
497             RefPtr<RegisterID> thisRegister = generator.newTemporary();
498             RefPtr<RegisterID> argsRegister = generator.newTemporary();
499             generator.emitNode(thisRegister.get(), m_args->m_listNode->m_expr);
500             ArgumentListNode* args = m_args->m_listNode->m_next;
501             bool isArgumentsApply = false;
502             if (args->m_expr->isResolveNode()) {
503                 ResolveNode* resolveNode = static_cast<ResolveNode*>(args->m_expr);
504                 isArgumentsApply = generator.willResolveToArguments(resolveNode->identifier());
505                 if (isArgumentsApply)
506                     generator.emitMove(argsRegister.get(), generator.uncheckedRegisterForArguments());
507             }
508             if (!isArgumentsApply)
509                 generator.emitNode(argsRegister.get(), args->m_expr);
510             while ((args = args->m_next))
511                 generator.emitNode(args->m_expr);
512
513             generator.emitLoadVarargs(argsCountRegister.get(), thisRegister.get(), argsRegister.get());
514             generator.emitCallVarargs(finalDestinationOrIgnored.get(), realFunction.get(), thisRegister.get(), argsCountRegister.get(), divot(), startOffset(), endOffset());
515         }
516         generator.emitJump(end.get());
517     }
518     generator.emitLabel(realCall.get());
519     {
520         CallArguments callArguments(generator, m_args);
521         generator.emitMove(callArguments.thisRegister(), base.get());
522         generator.emitCall(finalDestinationOrIgnored.get(), function.get(), callArguments, divot(), startOffset(), endOffset());
523     }
524     generator.emitLabel(end.get());
525     return finalDestinationOrIgnored.get();
526 }
527
528 // ------------------------------ PostfixResolveNode ----------------------------------
529
530 static RegisterID* emitPreIncOrDec(BytecodeGenerator& generator, RegisterID* srcDst, Operator oper)
531 {
532     return (oper == OpPlusPlus) ? generator.emitPreInc(srcDst) : generator.emitPreDec(srcDst);
533 }
534
535 static RegisterID* emitPostIncOrDec(BytecodeGenerator& generator, RegisterID* dst, RegisterID* srcDst, Operator oper)
536 {
537     if (srcDst == dst)
538         return generator.emitToJSNumber(dst, srcDst);
539     return (oper == OpPlusPlus) ? generator.emitPostInc(dst, srcDst) : generator.emitPostDec(dst, srcDst);
540 }
541
542 RegisterID* PostfixResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
543 {
544     if (RegisterID* local = generator.registerFor(m_ident)) {
545         if (generator.isLocalConstant(m_ident)) {
546             if (dst == generator.ignoredResult())
547                 return 0;
548             return generator.emitToJSNumber(generator.finalDestination(dst), local);
549         }
550
551         if (dst == generator.ignoredResult())
552             return emitPreIncOrDec(generator, local, m_operator);
553         return emitPostIncOrDec(generator, generator.finalDestination(dst), local, m_operator);
554     }
555
556     int index = 0;
557     size_t depth = 0;
558     JSObject* globalObject = 0;
559     bool requiresDynamicChecks = false;
560     if (generator.findScopedProperty(m_ident, index, depth, true, requiresDynamicChecks, globalObject) && index != missingSymbolMarker() && !requiresDynamicChecks) {
561         RefPtr<RegisterID> value = generator.emitGetScopedVar(generator.newTemporary(), depth, index, globalObject);
562         RegisterID* oldValue;
563         if (dst == generator.ignoredResult()) {
564             oldValue = 0;
565             emitPreIncOrDec(generator, value.get(), m_operator);
566         } else {
567             oldValue = emitPostIncOrDec(generator, generator.finalDestination(dst), value.get(), m_operator);
568         }
569         generator.emitPutScopedVar(depth, index, value.get(), globalObject);
570         return oldValue;
571     }
572
573     generator.emitExpressionInfo(divot(), startOffset(), endOffset());
574     RefPtr<RegisterID> value = generator.newTemporary();
575     RefPtr<RegisterID> base = generator.emitResolveWithBase(generator.newTemporary(), value.get(), m_ident);
576     RegisterID* oldValue;
577     if (dst == generator.ignoredResult()) {
578         oldValue = 0;
579         emitPreIncOrDec(generator, value.get(), m_operator);
580     } else {
581         oldValue = emitPostIncOrDec(generator, generator.finalDestination(dst), value.get(), m_operator);
582     }
583     generator.emitPutById(base.get(), m_ident, value.get());
584     return oldValue;
585 }
586
587 // ------------------------------ PostfixBracketNode ----------------------------------
588
589 RegisterID* PostfixBracketNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
590 {
591     RefPtr<RegisterID> base = generator.emitNode(m_base);
592     RefPtr<RegisterID> property = generator.emitNode(m_subscript);
593
594     generator.emitExpressionInfo(divot() - m_subexpressionDivotOffset, startOffset() - m_subexpressionDivotOffset, m_subexpressionEndOffset);
595     RefPtr<RegisterID> value = generator.emitGetByVal(generator.newTemporary(), base.get(), property.get());
596     RegisterID* oldValue;
597     if (dst == generator.ignoredResult()) {
598         oldValue = 0;
599         if (m_operator == OpPlusPlus)
600             generator.emitPreInc(value.get());
601         else
602             generator.emitPreDec(value.get());
603     } else {
604         oldValue = (m_operator == OpPlusPlus) ? generator.emitPostInc(generator.finalDestination(dst), value.get()) : generator.emitPostDec(generator.finalDestination(dst), value.get());
605     }
606     generator.emitExpressionInfo(divot(), startOffset(), endOffset());
607     generator.emitPutByVal(base.get(), property.get(), value.get());
608     return oldValue;
609 }
610
611 // ------------------------------ PostfixDotNode ----------------------------------
612
613 RegisterID* PostfixDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
614 {
615     RefPtr<RegisterID> base = generator.emitNode(m_base);
616
617     generator.emitExpressionInfo(divot() - m_subexpressionDivotOffset, startOffset() - m_subexpressionDivotOffset, m_subexpressionEndOffset);
618     RefPtr<RegisterID> value = generator.emitGetById(generator.newTemporary(), base.get(), m_ident);
619     RegisterID* oldValue;
620     if (dst == generator.ignoredResult()) {
621         oldValue = 0;
622         if (m_operator == OpPlusPlus)
623             generator.emitPreInc(value.get());
624         else
625             generator.emitPreDec(value.get());
626     } else {
627         oldValue = (m_operator == OpPlusPlus) ? generator.emitPostInc(generator.finalDestination(dst), value.get()) : generator.emitPostDec(generator.finalDestination(dst), value.get());
628     }
629     generator.emitExpressionInfo(divot(), startOffset(), endOffset());
630     generator.emitPutById(base.get(), m_ident, value.get());
631     return oldValue;
632 }
633
634 // ------------------------------ PostfixErrorNode -----------------------------------
635
636 RegisterID* PostfixErrorNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
637 {
638     return emitThrowReferenceError(generator, m_operator == OpPlusPlus
639         ? "Postfix ++ operator applied to value that is not a reference."
640         : "Postfix -- operator applied to value that is not a reference.");
641 }
642
643 // ------------------------------ DeleteResolveNode -----------------------------------
644
645 RegisterID* DeleteResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
646 {
647     if (generator.registerFor(m_ident))
648         return generator.emitLoad(generator.finalDestination(dst), false);
649
650     generator.emitExpressionInfo(divot(), startOffset(), endOffset());
651     RegisterID* base = generator.emitResolveBase(generator.tempDestination(dst), m_ident);
652     return generator.emitDeleteById(generator.finalDestination(dst, base), base, m_ident);
653 }
654
655 // ------------------------------ DeleteBracketNode -----------------------------------
656
657 RegisterID* DeleteBracketNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
658 {
659     RefPtr<RegisterID> r0 = generator.emitNode(m_base);
660     RegisterID* r1 = generator.emitNode(m_subscript);
661
662     generator.emitExpressionInfo(divot(), startOffset(), endOffset());
663     return generator.emitDeleteByVal(generator.finalDestination(dst), r0.get(), r1);
664 }
665
666 // ------------------------------ DeleteDotNode -----------------------------------
667
668 RegisterID* DeleteDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
669 {
670     RegisterID* r0 = generator.emitNode(m_base);
671
672     generator.emitExpressionInfo(divot(), startOffset(), endOffset());
673     return generator.emitDeleteById(generator.finalDestination(dst), r0, m_ident);
674 }
675
676 // ------------------------------ DeleteValueNode -----------------------------------
677
678 RegisterID* DeleteValueNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
679 {
680     generator.emitNode(generator.ignoredResult(), m_expr);
681
682     // delete on a non-location expression ignores the value and returns true
683     return generator.emitLoad(generator.finalDestination(dst), true);
684 }
685
686 // ------------------------------ VoidNode -------------------------------------
687
688 RegisterID* VoidNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
689 {
690     if (dst == generator.ignoredResult()) {
691         generator.emitNode(generator.ignoredResult(), m_expr);
692         return 0;
693     }
694     RefPtr<RegisterID> r0 = generator.emitNode(m_expr);
695     return generator.emitLoad(dst, jsUndefined());
696 }
697
698 // ------------------------------ TypeOfValueNode -----------------------------------
699
700 RegisterID* TypeOfResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
701 {
702     if (RegisterID* local = generator.registerFor(m_ident)) {
703         if (dst == generator.ignoredResult())
704             return 0;
705         return generator.emitTypeOf(generator.finalDestination(dst), local);
706     }
707
708     RefPtr<RegisterID> scratch = generator.emitResolveBase(generator.tempDestination(dst), m_ident);
709     generator.emitGetById(scratch.get(), scratch.get(), m_ident);
710     if (dst == generator.ignoredResult())
711         return 0;
712     return generator.emitTypeOf(generator.finalDestination(dst, scratch.get()), scratch.get());
713 }
714
715 // ------------------------------ TypeOfValueNode -----------------------------------
716
717 RegisterID* TypeOfValueNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
718 {
719     if (dst == generator.ignoredResult()) {
720         generator.emitNode(generator.ignoredResult(), m_expr);
721         return 0;
722     }
723     RefPtr<RegisterID> src = generator.emitNode(m_expr);
724     return generator.emitTypeOf(generator.finalDestination(dst), src.get());
725 }
726
727 // ------------------------------ PrefixResolveNode ----------------------------------
728
729 RegisterID* PrefixResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
730 {
731     if (RegisterID* local = generator.registerFor(m_ident)) {
732         if (generator.isLocalConstant(m_ident)) {
733             if (dst == generator.ignoredResult())
734                 return 0;
735             RefPtr<RegisterID> r0 = generator.emitLoad(generator.finalDestination(dst), (m_operator == OpPlusPlus) ? 1.0 : -1.0);
736             return generator.emitBinaryOp(op_add, r0.get(), local, r0.get(), OperandTypes());
737         }
738
739         emitPreIncOrDec(generator, local, m_operator);
740         return generator.moveToDestinationIfNeeded(dst, local);
741     }
742
743     int index = 0;
744     size_t depth = 0;
745     JSObject* globalObject = 0;
746     bool requiresDynamicChecks = false;
747     if (generator.findScopedProperty(m_ident, index, depth, true, requiresDynamicChecks, globalObject) && index != missingSymbolMarker() && !requiresDynamicChecks) {
748         RefPtr<RegisterID> propDst = generator.emitGetScopedVar(generator.tempDestination(dst), depth, index, globalObject);
749         emitPreIncOrDec(generator, propDst.get(), m_operator);
750         generator.emitPutScopedVar(depth, index, propDst.get(), globalObject);
751         return generator.moveToDestinationIfNeeded(dst, propDst.get());
752     }
753
754     generator.emitExpressionInfo(divot(), startOffset(), endOffset());
755     RefPtr<RegisterID> propDst = generator.tempDestination(dst);
756     RefPtr<RegisterID> base = generator.emitResolveWithBase(generator.newTemporary(), propDst.get(), m_ident);
757     emitPreIncOrDec(generator, propDst.get(), m_operator);
758     generator.emitPutById(base.get(), m_ident, propDst.get());
759     return generator.moveToDestinationIfNeeded(dst, propDst.get());
760 }
761
762 // ------------------------------ PrefixBracketNode ----------------------------------
763
764 RegisterID* PrefixBracketNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
765 {
766     RefPtr<RegisterID> base = generator.emitNode(m_base);
767     RefPtr<RegisterID> property = generator.emitNode(m_subscript);
768     RefPtr<RegisterID> propDst = generator.tempDestination(dst);
769
770     generator.emitExpressionInfo(divot() + m_subexpressionDivotOffset, m_subexpressionStartOffset, endOffset() - m_subexpressionDivotOffset);
771     RegisterID* value = generator.emitGetByVal(propDst.get(), base.get(), property.get());
772     if (m_operator == OpPlusPlus)
773         generator.emitPreInc(value);
774     else
775         generator.emitPreDec(value);
776     generator.emitExpressionInfo(divot(), startOffset(), endOffset());
777     generator.emitPutByVal(base.get(), property.get(), value);
778     return generator.moveToDestinationIfNeeded(dst, propDst.get());
779 }
780
781 // ------------------------------ PrefixDotNode ----------------------------------
782
783 RegisterID* PrefixDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
784 {
785     RefPtr<RegisterID> base = generator.emitNode(m_base);
786     RefPtr<RegisterID> propDst = generator.tempDestination(dst);
787
788     generator.emitExpressionInfo(divot() + m_subexpressionDivotOffset, m_subexpressionStartOffset, endOffset() - m_subexpressionDivotOffset);
789     RegisterID* value = generator.emitGetById(propDst.get(), base.get(), m_ident);
790     if (m_operator == OpPlusPlus)
791         generator.emitPreInc(value);
792     else
793         generator.emitPreDec(value);
794     generator.emitExpressionInfo(divot(), startOffset(), endOffset());
795     generator.emitPutById(base.get(), m_ident, value);
796     return generator.moveToDestinationIfNeeded(dst, propDst.get());
797 }
798
799 // ------------------------------ PrefixErrorNode -----------------------------------
800
801 RegisterID* PrefixErrorNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
802 {
803     return emitThrowReferenceError(generator, m_operator == OpPlusPlus
804         ? "Prefix ++ operator applied to value that is not a reference."
805         : "Prefix -- operator applied to value that is not a reference.");
806 }
807
808 // ------------------------------ Unary Operation Nodes -----------------------------------
809
810 RegisterID* UnaryOpNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
811 {
812     RegisterID* src = generator.emitNode(m_expr);
813     return generator.emitUnaryOp(opcodeID(), generator.finalDestination(dst), src);
814 }
815
816
817 // ------------------------------ LogicalNotNode -----------------------------------
818
819 void LogicalNotNode::emitBytecodeInConditionContext(BytecodeGenerator& generator, Label* trueTarget, Label* falseTarget, bool fallThroughMeansTrue)
820 {
821     ASSERT(expr()->hasConditionContextCodegen());
822
823     // reverse the true and false targets
824     generator.emitNodeInConditionContext(expr(), falseTarget, trueTarget, !fallThroughMeansTrue);
825 }
826
827
828 // ------------------------------ Binary Operation Nodes -----------------------------------
829
830 // BinaryOpNode::emitStrcat:
831 //
832 // This node generates an op_strcat operation.  This opcode can handle concatenation of three or
833 // more values, where we can determine a set of separate op_add operations would be operating on
834 // string values.
835 //
836 // This function expects to be operating on a graph of AST nodes looking something like this:
837 //
838 //     (a)...     (b)
839 //          \   /
840 //           (+)     (c)
841 //              \   /
842 //      [d]     ((+))
843 //         \    /
844 //          [+=]
845 //
846 // The assignment operation is optional, if it exists the register holding the value on the
847 // lefthand side of the assignment should be passing as the optional 'lhs' argument.
848 //
849 // The method should be called on the node at the root of the tree of regular binary add
850 // operations (marked in the diagram with a double set of parentheses).  This node must
851 // be performing a string concatenation (determined by statically detecting that at least
852 // one child must be a string).  
853 //
854 // Since the minimum number of values being concatenated together is expected to be 3, if
855 // a lhs to a concatenating assignment is not provided then the  root add should have at
856 // least one left child that is also an add that can be determined to be operating on strings.
857 //
858 RegisterID* BinaryOpNode::emitStrcat(BytecodeGenerator& generator, RegisterID* dst, RegisterID* lhs, ReadModifyResolveNode* emitExpressionInfoForMe)
859 {
860     ASSERT(isAdd());
861     ASSERT(resultDescriptor().definitelyIsString());
862
863     // Create a list of expressions for all the adds in the tree of nodes we can convert into
864     // a string concatenation.  The rightmost node (c) is added first.  The rightmost node is
865     // added first, and the leftmost child is never added, so the vector produced for the
866     // example above will be [ c, b ].
867     Vector<ExpressionNode*, 16> reverseExpressionList;
868     reverseExpressionList.append(m_expr2);
869
870     // Examine the left child of the add.  So long as this is a string add, add its right-child
871     // to the list, and keep processing along the left fork.
872     ExpressionNode* leftMostAddChild = m_expr1;
873     while (leftMostAddChild->isAdd() && leftMostAddChild->resultDescriptor().definitelyIsString()) {
874         reverseExpressionList.append(static_cast<AddNode*>(leftMostAddChild)->m_expr2);
875         leftMostAddChild = static_cast<AddNode*>(leftMostAddChild)->m_expr1;
876     }
877
878     Vector<RefPtr<RegisterID>, 16> temporaryRegisters;
879
880     // If there is an assignment, allocate a temporary to hold the lhs after conversion.
881     // We could possibly avoid this (the lhs is converted last anyway, we could let the
882     // op_strcat node handle its conversion if required).
883     if (lhs)
884         temporaryRegisters.append(generator.newTemporary());
885
886     // Emit code for the leftmost node ((a) in the example).
887     temporaryRegisters.append(generator.newTemporary());
888     RegisterID* leftMostAddChildTempRegister = temporaryRegisters.last().get();
889     generator.emitNode(leftMostAddChildTempRegister, leftMostAddChild);
890
891     // Note on ordering of conversions:
892     //
893     // We maintain the same ordering of conversions as we would see if the concatenations
894     // was performed as a sequence of adds (otherwise this optimization could change
895     // behaviour should an object have been provided a valueOf or toString method).
896     //
897     // Considering the above example, the sequnce of execution is:
898     //     * evaluate operand (a)
899     //     * evaluate operand (b)
900     //     * convert (a) to primitive   <-  (this would be triggered by the first add)
901     //     * convert (b) to primitive   <-  (ditto)
902     //     * evaluate operand (c)
903     //     * convert (c) to primitive   <-  (this would be triggered by the second add)
904     // And optionally, if there is an assignment:
905     //     * convert (d) to primitive   <-  (this would be triggered by the assigning addition)
906     //
907     // As such we do not plant an op to convert the leftmost child now.  Instead, use
908     // 'leftMostAddChildTempRegister' as a flag to trigger generation of the conversion
909     // once the second node has been generated.  However, if the leftmost child is an
910     // immediate we can trivially determine that no conversion will be required.
911     // If this is the case
912     if (leftMostAddChild->isString())
913         leftMostAddChildTempRegister = 0;
914
915     while (reverseExpressionList.size()) {
916         ExpressionNode* node = reverseExpressionList.last();
917         reverseExpressionList.removeLast();
918
919         // Emit the code for the current node.
920         temporaryRegisters.append(generator.newTemporary());
921         generator.emitNode(temporaryRegisters.last().get(), node);
922
923         // On the first iteration of this loop, when we first reach this point we have just
924         // generated the second node, which means it is time to convert the leftmost operand.
925         if (leftMostAddChildTempRegister) {
926             generator.emitToPrimitive(leftMostAddChildTempRegister, leftMostAddChildTempRegister);
927             leftMostAddChildTempRegister = 0; // Only do this once.
928         }
929         // Plant a conversion for this node, if necessary.
930         if (!node->isString())
931             generator.emitToPrimitive(temporaryRegisters.last().get(), temporaryRegisters.last().get());
932     }
933     ASSERT(temporaryRegisters.size() >= 3);
934
935     // Certain read-modify nodes require expression info to be emitted *after* m_right has been generated.
936     // If this is required the node is passed as 'emitExpressionInfoForMe'; do so now.
937     if (emitExpressionInfoForMe)
938         generator.emitExpressionInfo(emitExpressionInfoForMe->divot(), emitExpressionInfoForMe->startOffset(), emitExpressionInfoForMe->endOffset());
939
940     // If there is an assignment convert the lhs now.  This will also copy lhs to
941     // the temporary register we allocated for it.
942     if (lhs)
943         generator.emitToPrimitive(temporaryRegisters[0].get(), lhs);
944
945     return generator.emitStrcat(generator.finalDestination(dst, temporaryRegisters[0].get()), temporaryRegisters[0].get(), temporaryRegisters.size());
946 }
947
948 RegisterID* BinaryOpNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
949 {
950     OpcodeID opcodeID = this->opcodeID();
951
952     if (opcodeID == op_add && m_expr1->isAdd() && m_expr1->resultDescriptor().definitelyIsString())
953         return emitStrcat(generator, dst);
954
955     if (opcodeID == op_neq) {
956         if (m_expr1->isNull() || m_expr2->isNull()) {
957             RefPtr<RegisterID> src = generator.tempDestination(dst);
958             generator.emitNode(src.get(), m_expr1->isNull() ? m_expr2 : m_expr1);
959             return generator.emitUnaryOp(op_neq_null, generator.finalDestination(dst, src.get()), src.get());
960         }
961     }
962
963     RefPtr<RegisterID> src1 = generator.emitNodeForLeftHandSide(m_expr1, m_rightHasAssignments, m_expr2->isPure(generator));
964     RegisterID* src2 = generator.emitNode(m_expr2);
965     return generator.emitBinaryOp(opcodeID, generator.finalDestination(dst, src1.get()), src1.get(), src2, OperandTypes(m_expr1->resultDescriptor(), m_expr2->resultDescriptor()));
966 }
967
968 RegisterID* EqualNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
969 {
970     if (m_expr1->isNull() || m_expr2->isNull()) {
971         RefPtr<RegisterID> src = generator.tempDestination(dst);
972         generator.emitNode(src.get(), m_expr1->isNull() ? m_expr2 : m_expr1);
973         return generator.emitUnaryOp(op_eq_null, generator.finalDestination(dst, src.get()), src.get());
974     }
975
976     RefPtr<RegisterID> src1 = generator.emitNodeForLeftHandSide(m_expr1, m_rightHasAssignments, m_expr2->isPure(generator));
977     RegisterID* src2 = generator.emitNode(m_expr2);
978     return generator.emitEqualityOp(op_eq, generator.finalDestination(dst, src1.get()), src1.get(), src2);
979 }
980
981 RegisterID* StrictEqualNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
982 {
983     RefPtr<RegisterID> src1 = generator.emitNodeForLeftHandSide(m_expr1, m_rightHasAssignments, m_expr2->isPure(generator));
984     RegisterID* src2 = generator.emitNode(m_expr2);
985     return generator.emitEqualityOp(op_stricteq, generator.finalDestination(dst, src1.get()), src1.get(), src2);
986 }
987
988 RegisterID* ThrowableBinaryOpNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
989 {
990     RefPtr<RegisterID> src1 = generator.emitNodeForLeftHandSide(m_expr1, m_rightHasAssignments, m_expr2->isPure(generator));
991     RegisterID* src2 = generator.emitNode(m_expr2);
992     generator.emitExpressionInfo(divot(), startOffset(), endOffset());
993     return generator.emitBinaryOp(opcodeID(), generator.finalDestination(dst, src1.get()), src1.get(), src2, OperandTypes(m_expr1->resultDescriptor(), m_expr2->resultDescriptor()));
994 }
995
996 RegisterID* InstanceOfNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
997 {
998     RefPtr<RegisterID> src1 = generator.emitNodeForLeftHandSide(m_expr1, m_rightHasAssignments, m_expr2->isPure(generator));
999     RefPtr<RegisterID> src2 = generator.emitNode(m_expr2);
1000
1001     generator.emitExpressionInfo(divot(), startOffset(), endOffset());
1002     generator.emitCheckHasInstance(src2.get());
1003
1004     generator.emitExpressionInfo(divot(), startOffset(), endOffset());
1005     RegisterID* src2Prototype = generator.emitGetById(generator.newTemporary(), src2.get(), generator.globalData()->propertyNames->prototype);
1006
1007     generator.emitExpressionInfo(divot(), startOffset(), endOffset());
1008     return generator.emitInstanceOf(generator.finalDestination(dst, src1.get()), src1.get(), src2.get(), src2Prototype);
1009 }
1010
1011 // ------------------------------ LogicalOpNode ----------------------------
1012
1013 RegisterID* LogicalOpNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1014 {
1015     RefPtr<RegisterID> temp = generator.tempDestination(dst);
1016     RefPtr<Label> target = generator.newLabel();
1017     
1018     generator.emitNode(temp.get(), m_expr1);
1019     if (m_operator == OpLogicalAnd)
1020         generator.emitJumpIfFalse(temp.get(), target.get());
1021     else
1022         generator.emitJumpIfTrue(temp.get(), target.get());
1023     generator.emitNode(temp.get(), m_expr2);
1024     generator.emitLabel(target.get());
1025
1026     return generator.moveToDestinationIfNeeded(dst, temp.get());
1027 }
1028
1029 void LogicalOpNode::emitBytecodeInConditionContext(BytecodeGenerator& generator, Label* trueTarget, Label* falseTarget, bool fallThroughMeansTrue)
1030 {
1031     if (m_expr1->hasConditionContextCodegen()) {
1032         RefPtr<Label> afterExpr1 = generator.newLabel();
1033         if (m_operator == OpLogicalAnd)
1034             generator.emitNodeInConditionContext(m_expr1, afterExpr1.get(), falseTarget, true);
1035         else 
1036             generator.emitNodeInConditionContext(m_expr1, trueTarget, afterExpr1.get(), false);
1037         generator.emitLabel(afterExpr1.get());
1038     } else {
1039         RegisterID* temp = generator.emitNode(m_expr1);
1040         if (m_operator == OpLogicalAnd)
1041             generator.emitJumpIfFalse(temp, falseTarget);
1042         else
1043             generator.emitJumpIfTrue(temp, trueTarget);
1044     }
1045
1046     if (m_expr2->hasConditionContextCodegen())
1047         generator.emitNodeInConditionContext(m_expr2, trueTarget, falseTarget, fallThroughMeansTrue);
1048     else {
1049         RegisterID* temp = generator.emitNode(m_expr2);
1050         if (fallThroughMeansTrue)
1051             generator.emitJumpIfFalse(temp, falseTarget);
1052         else
1053             generator.emitJumpIfTrue(temp, trueTarget);
1054     }
1055 }
1056
1057 // ------------------------------ ConditionalNode ------------------------------
1058
1059 RegisterID* ConditionalNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1060 {
1061     RefPtr<RegisterID> newDst = generator.finalDestination(dst);
1062     RefPtr<Label> beforeElse = generator.newLabel();
1063     RefPtr<Label> afterElse = generator.newLabel();
1064
1065     if (m_logical->hasConditionContextCodegen()) {
1066         RefPtr<Label> beforeThen = generator.newLabel();
1067         generator.emitNodeInConditionContext(m_logical, beforeThen.get(), beforeElse.get(), true);
1068         generator.emitLabel(beforeThen.get());
1069     } else {
1070         RegisterID* cond = generator.emitNode(m_logical);
1071         generator.emitJumpIfFalse(cond, beforeElse.get());
1072     }
1073
1074     generator.emitNode(newDst.get(), m_expr1);
1075     generator.emitJump(afterElse.get());
1076
1077     generator.emitLabel(beforeElse.get());
1078     generator.emitNode(newDst.get(), m_expr2);
1079
1080     generator.emitLabel(afterElse.get());
1081
1082     return newDst.get();
1083 }
1084
1085 // ------------------------------ ReadModifyResolveNode -----------------------------------
1086
1087 // FIXME: should this be moved to be a method on BytecodeGenerator?
1088 static ALWAYS_INLINE RegisterID* emitReadModifyAssignment(BytecodeGenerator& generator, RegisterID* dst, RegisterID* src1, ExpressionNode* m_right, Operator oper, OperandTypes types, ReadModifyResolveNode* emitExpressionInfoForMe = 0)
1089 {
1090     OpcodeID opcodeID;
1091     switch (oper) {
1092         case OpMultEq:
1093             opcodeID = op_mul;
1094             break;
1095         case OpDivEq:
1096             opcodeID = op_div;
1097             break;
1098         case OpPlusEq:
1099             if (m_right->isAdd() && m_right->resultDescriptor().definitelyIsString())
1100                 return static_cast<AddNode*>(m_right)->emitStrcat(generator, dst, src1, emitExpressionInfoForMe);
1101             opcodeID = op_add;
1102             break;
1103         case OpMinusEq:
1104             opcodeID = op_sub;
1105             break;
1106         case OpLShift:
1107             opcodeID = op_lshift;
1108             break;
1109         case OpRShift:
1110             opcodeID = op_rshift;
1111             break;
1112         case OpURShift:
1113             opcodeID = op_urshift;
1114             break;
1115         case OpAndEq:
1116             opcodeID = op_bitand;
1117             break;
1118         case OpXOrEq:
1119             opcodeID = op_bitxor;
1120             break;
1121         case OpOrEq:
1122             opcodeID = op_bitor;
1123             break;
1124         case OpModEq:
1125             opcodeID = op_mod;
1126             break;
1127         default:
1128             ASSERT_NOT_REACHED();
1129             return dst;
1130     }
1131
1132     RegisterID* src2 = generator.emitNode(m_right);
1133
1134     // Certain read-modify nodes require expression info to be emitted *after* m_right has been generated.
1135     // If this is required the node is passed as 'emitExpressionInfoForMe'; do so now.
1136     if (emitExpressionInfoForMe)
1137         generator.emitExpressionInfo(emitExpressionInfoForMe->divot(), emitExpressionInfoForMe->startOffset(), emitExpressionInfoForMe->endOffset());
1138
1139     return generator.emitBinaryOp(opcodeID, dst, src1, src2, types);
1140 }
1141
1142 RegisterID* ReadModifyResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1143 {
1144     if (RegisterID* local = generator.registerFor(m_ident)) {
1145         if (generator.isLocalConstant(m_ident)) {
1146             return emitReadModifyAssignment(generator, generator.finalDestination(dst), local, m_right, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()));
1147         }
1148         
1149         if (generator.leftHandSideNeedsCopy(m_rightHasAssignments, m_right->isPure(generator))) {
1150             RefPtr<RegisterID> result = generator.newTemporary();
1151             generator.emitMove(result.get(), local);
1152             emitReadModifyAssignment(generator, result.get(), result.get(), m_right, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()));
1153             generator.emitMove(local, result.get());
1154             return generator.moveToDestinationIfNeeded(dst, result.get());
1155         }
1156         
1157         RegisterID* result = emitReadModifyAssignment(generator, local, local, m_right, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()));
1158         return generator.moveToDestinationIfNeeded(dst, result);
1159     }
1160
1161     int index = 0;
1162     size_t depth = 0;
1163     JSObject* globalObject = 0;
1164     bool requiresDynamicChecks = false;
1165     if (generator.findScopedProperty(m_ident, index, depth, true, requiresDynamicChecks, globalObject) && index != missingSymbolMarker() && !requiresDynamicChecks) {
1166         RefPtr<RegisterID> src1 = generator.emitGetScopedVar(generator.tempDestination(dst), depth, index, globalObject);
1167         RegisterID* result = emitReadModifyAssignment(generator, generator.finalDestination(dst, src1.get()), src1.get(), m_right, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()));
1168         generator.emitPutScopedVar(depth, index, result, globalObject);
1169         return result;
1170     }
1171
1172     RefPtr<RegisterID> src1 = generator.tempDestination(dst);
1173     generator.emitExpressionInfo(divot() - startOffset() + m_ident.length(), m_ident.length(), 0);
1174     RefPtr<RegisterID> base = generator.emitResolveWithBase(generator.newTemporary(), src1.get(), m_ident);
1175     RegisterID* result = emitReadModifyAssignment(generator, generator.finalDestination(dst, src1.get()), src1.get(), m_right, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()), this);
1176     return generator.emitPutById(base.get(), m_ident, result);
1177 }
1178
1179 // ------------------------------ AssignResolveNode -----------------------------------
1180
1181 RegisterID* AssignResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1182 {
1183     if (RegisterID* local = generator.registerFor(m_ident)) {
1184         if (generator.isLocalConstant(m_ident))
1185             return generator.emitNode(dst, m_right);
1186         
1187         RegisterID* result = generator.emitNode(local, m_right);
1188         return generator.moveToDestinationIfNeeded(dst, result);
1189     }
1190
1191     int index = 0;
1192     size_t depth = 0;
1193     JSObject* globalObject = 0;
1194     bool requiresDynamicChecks = false;
1195     if (generator.findScopedProperty(m_ident, index, depth, true, requiresDynamicChecks, globalObject) && index != missingSymbolMarker() && !requiresDynamicChecks) {
1196         if (dst == generator.ignoredResult())
1197             dst = 0;
1198         RegisterID* value = generator.emitNode(dst, m_right);
1199         generator.emitPutScopedVar(depth, index, value, globalObject);
1200         return value;
1201     }
1202
1203     RefPtr<RegisterID> base = generator.emitResolveBaseForPut(generator.newTemporary(), m_ident);
1204     if (dst == generator.ignoredResult())
1205         dst = 0;
1206     RegisterID* value = generator.emitNode(dst, m_right);
1207     generator.emitExpressionInfo(divot(), startOffset(), endOffset());
1208     return generator.emitPutById(base.get(), m_ident, value);
1209 }
1210
1211 // ------------------------------ AssignDotNode -----------------------------------
1212
1213 RegisterID* AssignDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1214 {
1215     RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base, m_rightHasAssignments, m_right->isPure(generator));
1216     RefPtr<RegisterID> value = generator.destinationForAssignResult(dst);
1217     RegisterID* result = generator.emitNode(value.get(), m_right);
1218     generator.emitExpressionInfo(divot(), startOffset(), endOffset());
1219     generator.emitPutById(base.get(), m_ident, result);
1220     return generator.moveToDestinationIfNeeded(dst, result);
1221 }
1222
1223 // ------------------------------ ReadModifyDotNode -----------------------------------
1224
1225 RegisterID* ReadModifyDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1226 {
1227     RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base, m_rightHasAssignments, m_right->isPure(generator));
1228
1229     generator.emitExpressionInfo(divot() - m_subexpressionDivotOffset, startOffset() - m_subexpressionDivotOffset, m_subexpressionEndOffset);
1230     RefPtr<RegisterID> value = generator.emitGetById(generator.tempDestination(dst), base.get(), m_ident);
1231     RegisterID* updatedValue = emitReadModifyAssignment(generator, generator.finalDestination(dst, value.get()), value.get(), m_right, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()));
1232
1233     generator.emitExpressionInfo(divot(), startOffset(), endOffset());
1234     return generator.emitPutById(base.get(), m_ident, updatedValue);
1235 }
1236
1237 // ------------------------------ AssignErrorNode -----------------------------------
1238
1239 RegisterID* AssignErrorNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
1240 {
1241     return emitThrowReferenceError(generator, "Left side of assignment is not a reference.");
1242 }
1243
1244 // ------------------------------ AssignBracketNode -----------------------------------
1245
1246 RegisterID* AssignBracketNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1247 {
1248     RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base, m_subscriptHasAssignments || m_rightHasAssignments, m_subscript->isPure(generator) && m_right->isPure(generator));
1249     RefPtr<RegisterID> property = generator.emitNodeForLeftHandSide(m_subscript, m_rightHasAssignments, m_right->isPure(generator));
1250     RefPtr<RegisterID> value = generator.destinationForAssignResult(dst);
1251     RegisterID* result = generator.emitNode(value.get(), m_right);
1252
1253     generator.emitExpressionInfo(divot(), startOffset(), endOffset());
1254     generator.emitPutByVal(base.get(), property.get(), result);
1255     return generator.moveToDestinationIfNeeded(dst, result);
1256 }
1257
1258 // ------------------------------ ReadModifyBracketNode -----------------------------------
1259
1260 RegisterID* ReadModifyBracketNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1261 {
1262     RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base, m_subscriptHasAssignments || m_rightHasAssignments, m_subscript->isPure(generator) && m_right->isPure(generator));
1263     RefPtr<RegisterID> property = generator.emitNodeForLeftHandSide(m_subscript, m_rightHasAssignments, m_right->isPure(generator));
1264
1265     generator.emitExpressionInfo(divot() - m_subexpressionDivotOffset, startOffset() - m_subexpressionDivotOffset, m_subexpressionEndOffset);
1266     RefPtr<RegisterID> value = generator.emitGetByVal(generator.tempDestination(dst), base.get(), property.get());
1267     RegisterID* updatedValue = emitReadModifyAssignment(generator, generator.finalDestination(dst, value.get()), value.get(), m_right, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()));
1268
1269     generator.emitExpressionInfo(divot(), startOffset(), endOffset());
1270     generator.emitPutByVal(base.get(), property.get(), updatedValue);
1271
1272     return updatedValue;
1273 }
1274
1275 // ------------------------------ CommaNode ------------------------------------
1276
1277 RegisterID* CommaNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1278 {
1279     ASSERT(m_expressions.size() > 1);
1280     for (size_t i = 0; i < m_expressions.size() - 1; i++)
1281         generator.emitNode(generator.ignoredResult(), m_expressions[i]);
1282     return generator.emitNode(dst, m_expressions.last());
1283 }
1284
1285 // ------------------------------ ConstDeclNode ------------------------------------
1286
1287 RegisterID* ConstDeclNode::emitCodeSingle(BytecodeGenerator& generator)
1288 {
1289     // FIXME: This code does not match the behavior of const in Firefox.
1290     if (RegisterID* local = generator.constRegisterFor(m_ident)) {
1291         if (!m_init)
1292             return local;
1293
1294         return generator.emitNode(local, m_init);
1295     }
1296
1297     RefPtr<RegisterID> value = m_init ? generator.emitNode(m_init) : generator.emitLoad(0, jsUndefined());
1298
1299     ScopeChainIterator iter = generator.scopeChain()->begin();
1300     ScopeChainIterator end = generator.scopeChain()->end();
1301     size_t depth = 0;
1302     for (; iter != end; ++iter, ++depth) {
1303         JSObject* currentScope = iter->get();
1304         if (!currentScope->isVariableObject())
1305             continue;
1306         JSVariableObject* currentVariableObject = static_cast<JSVariableObject*>(currentScope);
1307         SymbolTableEntry entry = currentVariableObject->symbolTable().get(m_ident.impl());
1308         if (entry.isNull())
1309             continue;
1310
1311         return generator.emitPutScopedVar(generator.scopeDepth() + depth, entry.getIndex(), value.get(), currentVariableObject->isGlobalObject() ? currentVariableObject : 0);
1312     }
1313
1314     if (generator.codeType() != EvalCode)
1315         return value.get();
1316
1317     // FIXME: While this code should only be hit in an eval block, it will assign
1318     // to the wrong base if m_ident exists in an intervening with scope.
1319     RefPtr<RegisterID> base = generator.emitResolveBase(generator.newTemporary(), m_ident);
1320     return generator.emitPutById(base.get(), m_ident, value.get());
1321 }
1322
1323 RegisterID* ConstDeclNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
1324 {
1325     RegisterID* result = 0;
1326     for (ConstDeclNode* n = this; n; n = n->m_next)
1327         result = n->emitCodeSingle(generator);
1328
1329     return result;
1330 }
1331
1332 // ------------------------------ ConstStatementNode -----------------------------
1333
1334 RegisterID* ConstStatementNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
1335 {
1336     generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
1337     return generator.emitNode(m_next);
1338 }
1339
1340 // ------------------------------ SourceElements -------------------------------
1341
1342
1343 inline StatementNode* SourceElements::lastStatement() const
1344 {
1345     size_t size = m_statements.size();
1346     return size ? m_statements[size - 1] : 0;
1347 }
1348
1349 inline void SourceElements::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1350 {
1351     size_t size = m_statements.size();
1352     for (size_t i = 0; i < size; ++i)
1353         generator.emitNode(dst, m_statements[i]);
1354 }
1355
1356 // ------------------------------ BlockNode ------------------------------------
1357
1358 inline StatementNode* BlockNode::lastStatement() const
1359 {
1360     return m_statements ? m_statements->lastStatement() : 0;
1361 }
1362
1363 inline StatementNode* BlockNode::singleStatement() const
1364 {
1365     return m_statements ? m_statements->singleStatement() : 0;
1366 }
1367
1368 RegisterID* BlockNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1369 {
1370     if (m_statements)
1371         m_statements->emitBytecode(generator, dst);
1372     return 0;
1373 }
1374
1375 // ------------------------------ EmptyStatementNode ---------------------------
1376
1377 RegisterID* EmptyStatementNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1378 {
1379     generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
1380     return dst;
1381 }
1382
1383 // ------------------------------ DebuggerStatementNode ---------------------------
1384
1385 RegisterID* DebuggerStatementNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1386 {
1387     generator.emitDebugHook(DidReachBreakpoint, firstLine(), lastLine());
1388     return dst;
1389 }
1390
1391 // ------------------------------ ExprStatementNode ----------------------------
1392
1393 RegisterID* ExprStatementNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1394 {
1395     ASSERT(m_expr);
1396     generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine()); 
1397     return generator.emitNode(dst, m_expr);
1398 }
1399
1400 // ------------------------------ VarStatementNode ----------------------------
1401
1402 RegisterID* VarStatementNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
1403 {
1404     ASSERT(m_expr);
1405     generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
1406     return generator.emitNode(m_expr);
1407 }
1408
1409 // ------------------------------ IfNode ---------------------------------------
1410
1411 RegisterID* IfNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1412 {
1413     generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
1414     
1415     RefPtr<Label> afterThen = generator.newLabel();
1416
1417     if (m_condition->hasConditionContextCodegen()) {
1418         RefPtr<Label> beforeThen = generator.newLabel();
1419         generator.emitNodeInConditionContext(m_condition, beforeThen.get(), afterThen.get(), true);
1420         generator.emitLabel(beforeThen.get());
1421     } else {
1422         RegisterID* cond = generator.emitNode(m_condition);
1423         generator.emitJumpIfFalse(cond, afterThen.get());
1424     }
1425
1426     generator.emitNode(dst, m_ifBlock);
1427     generator.emitLabel(afterThen.get());
1428
1429     // FIXME: This should return the last statement executed so that it can be returned as a Completion.
1430     return 0;
1431 }
1432
1433 // ------------------------------ IfElseNode ---------------------------------------
1434
1435 RegisterID* IfElseNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1436 {
1437     generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
1438     
1439     RefPtr<Label> beforeElse = generator.newLabel();
1440     RefPtr<Label> afterElse = generator.newLabel();
1441
1442     if (m_condition->hasConditionContextCodegen()) {
1443         RefPtr<Label> beforeThen = generator.newLabel();
1444         generator.emitNodeInConditionContext(m_condition, beforeThen.get(), beforeElse.get(), true);
1445         generator.emitLabel(beforeThen.get());
1446     } else {
1447         RegisterID* cond = generator.emitNode(m_condition);
1448         generator.emitJumpIfFalse(cond, beforeElse.get());
1449     }
1450
1451     generator.emitNode(dst, m_ifBlock);
1452     generator.emitJump(afterElse.get());
1453
1454     generator.emitLabel(beforeElse.get());
1455
1456     generator.emitNode(dst, m_elseBlock);
1457
1458     generator.emitLabel(afterElse.get());
1459
1460     // FIXME: This should return the last statement executed so that it can be returned as a Completion.
1461     return 0;
1462 }
1463
1464 // ------------------------------ DoWhileNode ----------------------------------
1465
1466 RegisterID* DoWhileNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1467 {
1468     RefPtr<LabelScope> scope = generator.newLabelScope(LabelScope::Loop);
1469
1470     RefPtr<Label> topOfLoop = generator.newLabel();
1471     generator.emitLabel(topOfLoop.get());
1472
1473     generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
1474    
1475     RefPtr<RegisterID> result = generator.emitNode(dst, m_statement);
1476
1477     generator.emitLabel(scope->continueTarget());
1478     generator.emitDebugHook(WillExecuteStatement, m_expr->lineNo(), m_expr->lineNo());
1479     if (m_expr->hasConditionContextCodegen())
1480         generator.emitNodeInConditionContext(m_expr, topOfLoop.get(), scope->breakTarget(), false);
1481     else {
1482         RegisterID* cond = generator.emitNode(m_expr);
1483         generator.emitJumpIfTrue(cond, topOfLoop.get());
1484     }
1485
1486     generator.emitLabel(scope->breakTarget());
1487     return result.get();
1488 }
1489
1490 // ------------------------------ WhileNode ------------------------------------
1491
1492 RegisterID* WhileNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1493 {
1494     RefPtr<LabelScope> scope = generator.newLabelScope(LabelScope::Loop);
1495
1496     generator.emitJump(scope->continueTarget());
1497
1498     RefPtr<Label> topOfLoop = generator.newLabel();
1499     generator.emitLabel(topOfLoop.get());
1500     
1501     generator.emitNode(dst, m_statement);
1502
1503     generator.emitLabel(scope->continueTarget());
1504     generator.emitDebugHook(WillExecuteStatement, m_expr->lineNo(), m_expr->lineNo());
1505
1506     if (m_expr->hasConditionContextCodegen())
1507         generator.emitNodeInConditionContext(m_expr, topOfLoop.get(), scope->breakTarget(), false);
1508     else {
1509         RegisterID* cond = generator.emitNode(m_expr);
1510         generator.emitJumpIfTrue(cond, topOfLoop.get());
1511     }
1512
1513     generator.emitLabel(scope->breakTarget());
1514     
1515     // FIXME: This should return the last statement executed so that it can be returned as a Completion
1516     return 0;
1517 }
1518
1519 // ------------------------------ ForNode --------------------------------------
1520
1521 RegisterID* ForNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1522 {
1523     RefPtr<LabelScope> scope = generator.newLabelScope(LabelScope::Loop);
1524
1525     generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
1526
1527     if (m_expr1)
1528         generator.emitNode(generator.ignoredResult(), m_expr1);
1529
1530     RefPtr<Label> condition = generator.newLabel();
1531     generator.emitJump(condition.get());
1532
1533     RefPtr<Label> topOfLoop = generator.newLabel();
1534     generator.emitLabel(topOfLoop.get());
1535
1536     RefPtr<RegisterID> result = generator.emitNode(dst, m_statement);
1537
1538     generator.emitLabel(scope->continueTarget());
1539     generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
1540     if (m_expr3)
1541         generator.emitNode(generator.ignoredResult(), m_expr3);
1542
1543     generator.emitLabel(condition.get());
1544     if (m_expr2) {
1545         if (m_expr2->hasConditionContextCodegen())
1546             generator.emitNodeInConditionContext(m_expr2, topOfLoop.get(), scope->breakTarget(), false);
1547         else {
1548             RegisterID* cond = generator.emitNode(m_expr2);
1549             generator.emitJumpIfTrue(cond, topOfLoop.get());
1550         }
1551     } else
1552         generator.emitJump(topOfLoop.get());
1553
1554     generator.emitLabel(scope->breakTarget());
1555     return result.get();
1556 }
1557
1558 // ------------------------------ ForInNode ------------------------------------
1559
1560 RegisterID* ForInNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1561 {
1562     RefPtr<LabelScope> scope = generator.newLabelScope(LabelScope::Loop);
1563
1564     if (!m_lexpr->isLocation())
1565         return emitThrowReferenceError(generator, "Left side of for-in statement is not a reference.");
1566
1567     generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
1568
1569     if (m_init)
1570         generator.emitNode(generator.ignoredResult(), m_init);
1571
1572     RefPtr<RegisterID> base = generator.newTemporary();
1573     generator.emitNode(base.get(), m_expr);
1574     RefPtr<RegisterID> i = generator.newTemporary();
1575     RefPtr<RegisterID> size = generator.newTemporary();
1576     RefPtr<RegisterID> expectedSubscript;
1577     RefPtr<RegisterID> iter = generator.emitGetPropertyNames(generator.newTemporary(), base.get(), i.get(), size.get(), scope->breakTarget());
1578     generator.emitJump(scope->continueTarget());
1579
1580     RefPtr<Label> loopStart = generator.newLabel();
1581     generator.emitLabel(loopStart.get());
1582
1583     RegisterID* propertyName;
1584     bool optimizedForinAccess = false;
1585     if (m_lexpr->isResolveNode()) {
1586         const Identifier& ident = static_cast<ResolveNode*>(m_lexpr)->identifier();
1587         propertyName = generator.registerFor(ident);
1588         if (!propertyName) {
1589             propertyName = generator.newTemporary();
1590             RefPtr<RegisterID> protect = propertyName;
1591             RegisterID* base = generator.emitResolveBaseForPut(generator.newTemporary(), ident);
1592
1593             generator.emitExpressionInfo(divot(), startOffset(), endOffset());
1594             generator.emitPutById(base, ident, propertyName);
1595         } else {
1596             expectedSubscript = generator.emitMove(generator.newTemporary(), propertyName);
1597             generator.pushOptimisedForIn(expectedSubscript.get(), iter.get(), i.get(), propertyName);
1598             optimizedForinAccess = true;
1599         }
1600     } else if (m_lexpr->isDotAccessorNode()) {
1601         DotAccessorNode* assignNode = static_cast<DotAccessorNode*>(m_lexpr);
1602         const Identifier& ident = assignNode->identifier();
1603         propertyName = generator.newTemporary();
1604         RefPtr<RegisterID> protect = propertyName;
1605         RegisterID* base = generator.emitNode(assignNode->base());
1606
1607         generator.emitExpressionInfo(assignNode->divot(), assignNode->startOffset(), assignNode->endOffset());
1608         generator.emitPutById(base, ident, propertyName);
1609     } else {
1610         ASSERT(m_lexpr->isBracketAccessorNode());
1611         BracketAccessorNode* assignNode = static_cast<BracketAccessorNode*>(m_lexpr);
1612         propertyName = generator.newTemporary();
1613         RefPtr<RegisterID> protect = propertyName;
1614         RefPtr<RegisterID> base = generator.emitNode(assignNode->base());
1615         RegisterID* subscript = generator.emitNode(assignNode->subscript());
1616         
1617         generator.emitExpressionInfo(assignNode->divot(), assignNode->startOffset(), assignNode->endOffset());
1618         generator.emitPutByVal(base.get(), subscript, propertyName);
1619     }   
1620
1621     generator.emitNode(dst, m_statement);
1622
1623     if (optimizedForinAccess)
1624         generator.popOptimisedForIn();
1625
1626     generator.emitLabel(scope->continueTarget());
1627     generator.emitNextPropertyName(propertyName, base.get(), i.get(), size.get(), iter.get(), loopStart.get());
1628     generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
1629     generator.emitLabel(scope->breakTarget());
1630     return dst;
1631 }
1632
1633 // ------------------------------ ContinueNode ---------------------------------
1634
1635 // ECMA 12.7
1636 RegisterID* ContinueNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1637 {
1638     generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
1639     
1640     LabelScope* scope = generator.continueTarget(m_ident);
1641     ASSERT(scope);
1642
1643     generator.emitJumpScopes(scope->continueTarget(), scope->scopeDepth());
1644     return dst;
1645 }
1646
1647 // ------------------------------ BreakNode ------------------------------------
1648
1649 // ECMA 12.8
1650 RegisterID* BreakNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1651 {
1652     generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
1653     
1654     LabelScope* scope = generator.breakTarget(m_ident);
1655     ASSERT(scope);
1656
1657     generator.emitJumpScopes(scope->breakTarget(), scope->scopeDepth());
1658     return dst;
1659 }
1660
1661 // ------------------------------ ReturnNode -----------------------------------
1662
1663 RegisterID* ReturnNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1664 {
1665     generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
1666     ASSERT(generator.codeType() == FunctionCode);
1667
1668     if (dst == generator.ignoredResult())
1669         dst = 0;
1670     RegisterID* r0 = m_value ? generator.emitNode(dst, m_value) : generator.emitLoad(dst, jsUndefined());
1671     RefPtr<RegisterID> returnRegister;
1672     if (generator.scopeDepth()) {
1673         RefPtr<Label> l0 = generator.newLabel();
1674         if (generator.hasFinaliser() && !r0->isTemporary()) {
1675             returnRegister = generator.emitMove(generator.newTemporary(), r0);
1676             r0 = returnRegister.get();
1677         }
1678         generator.emitJumpScopes(l0.get(), 0);
1679         generator.emitLabel(l0.get());
1680     }
1681     generator.emitDebugHook(WillLeaveCallFrame, firstLine(), lastLine());
1682     return generator.emitReturn(r0);
1683 }
1684
1685 // ------------------------------ WithNode -------------------------------------
1686
1687 RegisterID* WithNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1688 {
1689     generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
1690     
1691     RefPtr<RegisterID> scope = generator.newTemporary();
1692     generator.emitNode(scope.get(), m_expr); // scope must be protected until popped
1693     generator.emitExpressionInfo(m_divot, m_expressionLength, 0);
1694     generator.emitPushScope(scope.get());
1695     RegisterID* result = generator.emitNode(dst, m_statement);
1696     generator.emitPopScope();
1697     return result;
1698 }
1699
1700 // ------------------------------ CaseClauseNode --------------------------------
1701
1702 inline void CaseClauseNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1703 {
1704     if (m_statements)
1705         m_statements->emitBytecode(generator, dst);
1706 }
1707
1708 // ------------------------------ CaseBlockNode --------------------------------
1709
1710 enum SwitchKind { 
1711     SwitchUnset = 0,
1712     SwitchNumber = 1, 
1713     SwitchString = 2, 
1714     SwitchNeither = 3 
1715 };
1716
1717 static void processClauseList(ClauseListNode* list, Vector<ExpressionNode*, 8>& literalVector, SwitchKind& typeForTable, bool& singleCharacterSwitch, int32_t& min_num, int32_t& max_num)
1718 {
1719     for (; list; list = list->getNext()) {
1720         ExpressionNode* clauseExpression = list->getClause()->expr();
1721         literalVector.append(clauseExpression);
1722         if (clauseExpression->isNumber()) {
1723             double value = static_cast<NumberNode*>(clauseExpression)->value();
1724             int32_t intVal = static_cast<int32_t>(value);
1725             if ((typeForTable & ~SwitchNumber) || (intVal != value)) {
1726                 typeForTable = SwitchNeither;
1727                 break;
1728             }
1729             if (intVal < min_num)
1730                 min_num = intVal;
1731             if (intVal > max_num)
1732                 max_num = intVal;
1733             typeForTable = SwitchNumber;
1734             continue;
1735         }
1736         if (clauseExpression->isString()) {
1737             if (typeForTable & ~SwitchString) {
1738                 typeForTable = SwitchNeither;
1739                 break;
1740             }
1741             const UString& value = static_cast<StringNode*>(clauseExpression)->value().ustring();
1742             if (singleCharacterSwitch &= value.length() == 1) {
1743                 int32_t intVal = value.impl()->characters()[0];
1744                 if (intVal < min_num)
1745                     min_num = intVal;
1746                 if (intVal > max_num)
1747                     max_num = intVal;
1748             }
1749             typeForTable = SwitchString;
1750             continue;
1751         }
1752         typeForTable = SwitchNeither;
1753         break;        
1754     }
1755 }
1756     
1757 SwitchInfo::SwitchType CaseBlockNode::tryOptimizedSwitch(Vector<ExpressionNode*, 8>& literalVector, int32_t& min_num, int32_t& max_num)
1758 {
1759     SwitchKind typeForTable = SwitchUnset;
1760     bool singleCharacterSwitch = true;
1761     
1762     processClauseList(m_list1, literalVector, typeForTable, singleCharacterSwitch, min_num, max_num);
1763     processClauseList(m_list2, literalVector, typeForTable, singleCharacterSwitch, min_num, max_num);
1764     
1765     if (typeForTable == SwitchUnset || typeForTable == SwitchNeither)
1766         return SwitchInfo::SwitchNone;
1767     
1768     if (typeForTable == SwitchNumber) {
1769         int32_t range = max_num - min_num;
1770         if (min_num <= max_num && range <= 1000 && (range / literalVector.size()) < 10)
1771             return SwitchInfo::SwitchImmediate;
1772         return SwitchInfo::SwitchNone;
1773     } 
1774     
1775     ASSERT(typeForTable == SwitchString);
1776     
1777     if (singleCharacterSwitch) {
1778         int32_t range = max_num - min_num;
1779         if (min_num <= max_num && range <= 1000 && (range / literalVector.size()) < 10)
1780             return SwitchInfo::SwitchCharacter;
1781     }
1782
1783     return SwitchInfo::SwitchString;
1784 }
1785
1786 RegisterID* CaseBlockNode::emitBytecodeForBlock(BytecodeGenerator& generator, RegisterID* switchExpression, RegisterID* dst)
1787 {
1788     RefPtr<Label> defaultLabel;
1789     Vector<RefPtr<Label>, 8> labelVector;
1790     Vector<ExpressionNode*, 8> literalVector;
1791     int32_t min_num = std::numeric_limits<int32_t>::max();
1792     int32_t max_num = std::numeric_limits<int32_t>::min();
1793     SwitchInfo::SwitchType switchType = tryOptimizedSwitch(literalVector, min_num, max_num);
1794
1795     if (switchType != SwitchInfo::SwitchNone) {
1796         // Prepare the various labels
1797         for (uint32_t i = 0; i < literalVector.size(); i++)
1798             labelVector.append(generator.newLabel());
1799         defaultLabel = generator.newLabel();
1800         generator.beginSwitch(switchExpression, switchType);
1801     } else {
1802         // Setup jumps
1803         for (ClauseListNode* list = m_list1; list; list = list->getNext()) {
1804             RefPtr<RegisterID> clauseVal = generator.newTemporary();
1805             generator.emitNode(clauseVal.get(), list->getClause()->expr());
1806             generator.emitBinaryOp(op_stricteq, clauseVal.get(), clauseVal.get(), switchExpression, OperandTypes());
1807             labelVector.append(generator.newLabel());
1808             generator.emitJumpIfTrue(clauseVal.get(), labelVector[labelVector.size() - 1].get());
1809         }
1810         
1811         for (ClauseListNode* list = m_list2; list; list = list->getNext()) {
1812             RefPtr<RegisterID> clauseVal = generator.newTemporary();
1813             generator.emitNode(clauseVal.get(), list->getClause()->expr());
1814             generator.emitBinaryOp(op_stricteq, clauseVal.get(), clauseVal.get(), switchExpression, OperandTypes());
1815             labelVector.append(generator.newLabel());
1816             generator.emitJumpIfTrue(clauseVal.get(), labelVector[labelVector.size() - 1].get());
1817         }
1818         defaultLabel = generator.newLabel();
1819         generator.emitJump(defaultLabel.get());
1820     }
1821
1822     RegisterID* result = 0;
1823
1824     size_t i = 0;
1825     for (ClauseListNode* list = m_list1; list; list = list->getNext()) {
1826         generator.emitLabel(labelVector[i++].get());
1827         list->getClause()->emitBytecode(generator, dst);
1828     }
1829
1830     if (m_defaultClause) {
1831         generator.emitLabel(defaultLabel.get());
1832         m_defaultClause->emitBytecode(generator, dst);
1833     }
1834
1835     for (ClauseListNode* list = m_list2; list; list = list->getNext()) {
1836         generator.emitLabel(labelVector[i++].get());
1837         list->getClause()->emitBytecode(generator, dst);
1838     }
1839     if (!m_defaultClause)
1840         generator.emitLabel(defaultLabel.get());
1841
1842     ASSERT(i == labelVector.size());
1843     if (switchType != SwitchInfo::SwitchNone) {
1844         ASSERT(labelVector.size() == literalVector.size());
1845         generator.endSwitch(labelVector.size(), labelVector.data(), literalVector.data(), defaultLabel.get(), min_num, max_num);
1846     }
1847     return result;
1848 }
1849
1850 // ------------------------------ SwitchNode -----------------------------------
1851
1852 RegisterID* SwitchNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1853 {
1854     generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
1855     
1856     RefPtr<LabelScope> scope = generator.newLabelScope(LabelScope::Switch);
1857
1858     RefPtr<RegisterID> r0 = generator.emitNode(m_expr);
1859     RegisterID* r1 = m_block->emitBytecodeForBlock(generator, r0.get(), dst);
1860
1861     generator.emitLabel(scope->breakTarget());
1862     return r1;
1863 }
1864
1865 // ------------------------------ LabelNode ------------------------------------
1866
1867 RegisterID* LabelNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1868 {
1869     generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
1870
1871     ASSERT(!generator.breakTarget(m_name));
1872
1873     RefPtr<LabelScope> scope = generator.newLabelScope(LabelScope::NamedLabel, &m_name);
1874     RegisterID* r0 = generator.emitNode(dst, m_statement);
1875
1876     generator.emitLabel(scope->breakTarget());
1877     return r0;
1878 }
1879
1880 // ------------------------------ ThrowNode ------------------------------------
1881
1882 RegisterID* ThrowNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1883 {
1884     generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
1885
1886     if (dst == generator.ignoredResult())
1887         dst = 0;
1888     RefPtr<RegisterID> expr = generator.emitNode(m_expr);
1889     generator.emitExpressionInfo(divot(), startOffset(), endOffset());
1890     generator.emitThrow(expr.get());
1891     return 0;
1892 }
1893
1894 // ------------------------------ TryNode --------------------------------------
1895
1896 RegisterID* TryNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
1897 {
1898     // NOTE: The catch and finally blocks must be labeled explicitly, so the
1899     // optimizer knows they may be jumped to from anywhere.
1900
1901     generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
1902
1903     RefPtr<Label> tryStartLabel = generator.newLabel();
1904     RefPtr<Label> finallyStart;
1905     RefPtr<RegisterID> finallyReturnAddr;
1906     if (m_finallyBlock) {
1907         finallyStart = generator.newLabel();
1908         finallyReturnAddr = generator.newTemporary();
1909         generator.pushFinallyContext(finallyStart.get(), finallyReturnAddr.get());
1910     }
1911
1912     generator.emitLabel(tryStartLabel.get());
1913     generator.emitNode(dst, m_tryBlock);
1914
1915     if (m_catchBlock) {
1916         RefPtr<Label> catchEndLabel = generator.newLabel();
1917         
1918         // Normal path: jump over the catch block.
1919         generator.emitJump(catchEndLabel.get());
1920
1921         // Uncaught exception path: the catch block.
1922         RefPtr<Label> here = generator.emitLabel(generator.newLabel().get());
1923         RefPtr<RegisterID> exceptionRegister = generator.emitCatch(generator.newTemporary(), tryStartLabel.get(), here.get());
1924         if (m_catchHasEval) {
1925             RefPtr<RegisterID> dynamicScopeObject = generator.emitNewObject(generator.newTemporary());
1926             generator.emitPutById(dynamicScopeObject.get(), m_exceptionIdent, exceptionRegister.get());
1927             generator.emitMove(exceptionRegister.get(), dynamicScopeObject.get());
1928             generator.emitPushScope(exceptionRegister.get());
1929         } else
1930             generator.emitPushNewScope(exceptionRegister.get(), m_exceptionIdent, exceptionRegister.get());
1931         generator.emitNode(dst, m_catchBlock);
1932         generator.emitPopScope();
1933         generator.emitLabel(catchEndLabel.get());
1934     }
1935
1936     if (m_finallyBlock) {
1937         generator.popFinallyContext();
1938         // there may be important registers live at the time we jump
1939         // to a finally block (such as for a return or throw) so we
1940         // ref the highest register ever used as a conservative
1941         // approach to not clobbering anything important
1942         RefPtr<RegisterID> highestUsedRegister = generator.highestUsedRegister();
1943         RefPtr<Label> finallyEndLabel = generator.newLabel();
1944
1945         // Normal path: invoke the finally block, then jump over it.
1946         generator.emitJumpSubroutine(finallyReturnAddr.get(), finallyStart.get());
1947         generator.emitJump(finallyEndLabel.get());
1948
1949         // Uncaught exception path: invoke the finally block, then re-throw the exception.
1950         RefPtr<Label> here = generator.emitLabel(generator.newLabel().get());
1951         RefPtr<RegisterID> tempExceptionRegister = generator.emitCatch(generator.newTemporary(), tryStartLabel.get(), here.get());
1952         generator.emitJumpSubroutine(finallyReturnAddr.get(), finallyStart.get());
1953         generator.emitThrow(tempExceptionRegister.get());
1954
1955         // The finally block.
1956         generator.emitLabel(finallyStart.get());
1957         generator.emitNode(dst, m_finallyBlock);
1958         generator.emitSubroutineReturn(finallyReturnAddr.get());
1959
1960         generator.emitLabel(finallyEndLabel.get());
1961     }
1962
1963     return dst;
1964 }
1965
1966 // ------------------------------ ScopeNode -----------------------------
1967
1968 inline void ScopeNode::emitStatementsBytecode(BytecodeGenerator& generator, RegisterID* dst)
1969 {
1970     if (m_data->m_statements)
1971         m_data->m_statements->emitBytecode(generator, dst);
1972 }
1973
1974 // ------------------------------ ProgramNode -----------------------------
1975
1976 RegisterID* ProgramNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
1977 {
1978     generator.emitDebugHook(WillExecuteProgram, firstLine(), lastLine());
1979
1980     RefPtr<RegisterID> dstRegister = generator.newTemporary();
1981     generator.emitLoad(dstRegister.get(), jsUndefined());
1982     emitStatementsBytecode(generator, dstRegister.get());
1983
1984     generator.emitDebugHook(DidExecuteProgram, firstLine(), lastLine());
1985     generator.emitEnd(dstRegister.get());
1986     return 0;
1987 }
1988
1989 // ------------------------------ EvalNode -----------------------------
1990
1991 RegisterID* EvalNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
1992 {
1993     generator.emitDebugHook(WillExecuteProgram, firstLine(), lastLine());
1994
1995     RefPtr<RegisterID> dstRegister = generator.newTemporary();
1996     generator.emitLoad(dstRegister.get(), jsUndefined());
1997     emitStatementsBytecode(generator, dstRegister.get());
1998
1999     generator.emitDebugHook(DidExecuteProgram, firstLine(), lastLine());
2000     generator.emitEnd(dstRegister.get());
2001     return 0;
2002 }
2003
2004 // ------------------------------ FunctionBodyNode -----------------------------
2005
2006 RegisterID* FunctionBodyNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
2007 {
2008     generator.emitDebugHook(DidEnterCallFrame, firstLine(), lastLine());
2009     emitStatementsBytecode(generator, generator.ignoredResult());
2010
2011     StatementNode* singleStatement = this->singleStatement();
2012     ReturnNode* returnNode = 0;
2013
2014     // Check for a return statement at the end of a function composed of a single block.
2015     if (singleStatement && singleStatement->isBlock()) {
2016         StatementNode* lastStatementInBlock = static_cast<BlockNode*>(singleStatement)->lastStatement();
2017         if (lastStatementInBlock && lastStatementInBlock->isReturnNode())
2018             returnNode = static_cast<ReturnNode*>(lastStatementInBlock);
2019     }
2020
2021     // If there is no return we must automatically insert one.
2022     if (!returnNode) {
2023         RegisterID* r0 = generator.isConstructor() ? generator.thisRegister() : generator.emitLoad(0, jsUndefined());
2024         generator.emitDebugHook(WillLeaveCallFrame, firstLine(), lastLine());
2025         generator.emitReturn(r0);
2026         return 0;
2027     }
2028
2029     // If there is a return statment, and it is the only statement in the function, check if this is a numeric compare.
2030     if (static_cast<BlockNode*>(singleStatement)->singleStatement()) {
2031         ExpressionNode* returnValueExpression = returnNode->value();
2032         if (returnValueExpression && returnValueExpression->isSubtract()) {
2033             ExpressionNode* lhsExpression = static_cast<SubNode*>(returnValueExpression)->lhs();
2034             ExpressionNode* rhsExpression = static_cast<SubNode*>(returnValueExpression)->rhs();
2035             if (lhsExpression->isResolveNode() && rhsExpression->isResolveNode()) {
2036                 generator.setIsNumericCompareFunction(generator.argumentNumberFor(static_cast<ResolveNode*>(lhsExpression)->identifier()) == 1
2037                     && generator.argumentNumberFor(static_cast<ResolveNode*>(rhsExpression)->identifier()) == 2);
2038             }
2039         }
2040     }
2041
2042     return 0;
2043 }
2044
2045 // ------------------------------ FuncDeclNode ---------------------------------
2046
2047 RegisterID* FuncDeclNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2048 {
2049     if (dst == generator.ignoredResult())
2050         dst = 0;
2051     return dst;
2052 }
2053
2054 // ------------------------------ FuncExprNode ---------------------------------
2055
2056 RegisterID* FuncExprNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
2057 {
2058     return generator.emitNewFunctionExpression(generator.finalDestination(dst), this);
2059 }
2060
2061 } // namespace JSC