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