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