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