Home | History | Annotate | Download | only in bytecompiler
      1 /*
      2 *  Copyright (C) 1999-2002 Harri Porten (porten (at) kde.org)
      3 *  Copyright (C) 2001 Peter Kelly (pmk (at) post.com)
      4 *  Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
      5 *  Copyright (C) 2007 Cameron Zwarich (cwzwarich (at) uwaterloo.ca)
      6 *  Copyright (C) 2007 Maks Orlovich
      7 *  Copyright (C) 2007 Eric Seidel <eric (at) webkit.org>
      8 *
      9 *  This library is free software; you can redistribute it and/or
     10 *  modify it under the terms of the GNU Library General Public
     11 *  License as published by the Free Software Foundation; either
     12 *  version 2 of the License, or (at your option) any later version.
     13 *
     14 *  This library is distributed in the hope that it will be useful,
     15 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
     16 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     17 *  Library General Public License for more details.
     18 *
     19 *  You should have received a copy of the GNU Library General Public License
     20 *  along with this library; see the file COPYING.LIB.  If not, write to
     21 *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
     22 *  Boston, MA 02110-1301, USA.
     23 *
     24 */
     25 
     26 #include "config.h"
     27 #include "Nodes.h"
     28 #include "NodeConstructors.h"
     29 
     30 #include "BytecodeGenerator.h"
     31 #include "CallFrame.h"
     32 #include "Debugger.h"
     33 #include "JIT.h"
     34 #include "JSFunction.h"
     35 #include "JSGlobalObject.h"
     36 #include "JSStaticScopeObject.h"
     37 #include "LabelScope.h"
     38 #include "Lexer.h"
     39 #include "Operations.h"
     40 #include "Parser.h"
     41 #include "PropertyNameArray.h"
     42 #include "RegExpCache.h"
     43 #include "RegExpObject.h"
     44 #include "SamplingTool.h"
     45 #include "UStringConcatenate.h"
     46 #include <wtf/Assertions.h>
     47 #include <wtf/RefCountedLeakCounter.h>
     48 #include <wtf/Threading.h>
     49 
     50 using namespace WTF;
     51 
     52 namespace JSC {
     53 
     54 /*
     55     Details of the emitBytecode function.
     56 
     57     Return value: The register holding the production's value.
     58              dst: An optional parameter specifying the most efficient destination at
     59                   which to store the production's value. The callee must honor dst.
     60 
     61     The dst argument provides for a crude form of copy propagation. For example,
     62 
     63         x = 1
     64 
     65     becomes
     66 
     67         load r[x], 1
     68 
     69     instead of
     70 
     71         load r0, 1
     72         mov r[x], r0
     73 
     74     because the assignment node, "x =", passes r[x] as dst to the number node, "1".
     75 */
     76 
     77 // ------------------------------ ThrowableExpressionData --------------------------------
     78 
     79 RegisterID* ThrowableExpressionData::emitThrowReferenceError(BytecodeGenerator& generator, const UString& message)
     80 {
     81     generator.emitExpressionInfo(divot(), startOffset(), endOffset());
     82     generator.emitThrowReferenceError(message);
     83     return generator.newTemporary();
     84 }
     85 
     86 // ------------------------------ NullNode -------------------------------------
     87 
     88 RegisterID* NullNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
     89 {
     90     if (dst == generator.ignoredResult())
     91         return 0;
     92     return generator.emitLoad(dst, jsNull());
     93 }
     94 
     95 // ------------------------------ BooleanNode ----------------------------------
     96 
     97 RegisterID* BooleanNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
     98 {
     99     if (dst == generator.ignoredResult())
    100         return 0;
    101     return generator.emitLoad(dst, m_value);
    102 }
    103 
    104 // ------------------------------ NumberNode -----------------------------------
    105 
    106 RegisterID* NumberNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
    107 {
    108     if (dst == generator.ignoredResult())
    109         return 0;
    110     return generator.emitLoad(dst, m_value);
    111 }
    112 
    113 // ------------------------------ StringNode -----------------------------------
    114 
    115 RegisterID* StringNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
    116 {
    117     if (dst == generator.ignoredResult())
    118         return 0;
    119     return generator.emitLoad(dst, m_value);
    120 }
    121 
    122 // ------------------------------ RegExpNode -----------------------------------
    123 
    124 RegisterID* RegExpNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
    125 {
    126     if (dst == generator.ignoredResult())
    127         return 0;
    128     return generator.emitNewRegExp(generator.finalDestination(dst),
    129         generator.globalData()->regExpCache()->lookupOrCreate(m_pattern.ustring(), regExpFlags(m_flags.ustring())));
    130 }
    131 
    132 // ------------------------------ ThisNode -------------------------------------
    133 
    134 RegisterID* ThisNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
    135 {
    136     if (dst == generator.ignoredResult())
    137         return 0;
    138     return generator.moveToDestinationIfNeeded(dst, generator.thisRegister());
    139 }
    140 
    141 // ------------------------------ ResolveNode ----------------------------------
    142 
    143 bool ResolveNode::isPure(BytecodeGenerator& generator) const
    144 {
    145     return generator.isLocal(m_ident);
    146 }
    147 
    148 RegisterID* 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 
    162 RegisterID* 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 
    193 bool 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 
    204 ArgumentListNode* 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 
    222 RegisterID* 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 
    234 RegisterID* 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 
    266 RegisterID* 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 
    282 RegisterID* 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 
    294 nonArgumentsPath:
    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 
    302 RegisterID* ArgumentListNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
    303 {
    304     ASSERT(m_expr);
    305     return generator.emitNode(dst, m_expr);
    306 }
    307 
    308 // ------------------------------ NewExprNode ----------------------------------
    309 
    310 RegisterID* 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 
    317 CallArguments::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 
    334 RegisterID* 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 
    345 RegisterID* 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 
    355 RegisterID* 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 
    384 RegisterID* 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 
    397 RegisterID* 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 
    408 RegisterID* 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 
    448 static 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 
    454 RegisterID* 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 
    531 static RegisterID* emitPreIncOrDec(BytecodeGenerator& generator, RegisterID* srcDst, Operator oper)
    532 {
    533     return (oper == OpPlusPlus) ? generator.emitPreInc(srcDst) : generator.emitPreDec(srcDst);
    534 }
    535 
    536 static 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 
    543 RegisterID* 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 
    590 RegisterID* 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 
    614 RegisterID* 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 
    637 RegisterID* 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 
    646 RegisterID* 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 
    658 RegisterID* 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 
    669 RegisterID* 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 
    679 RegisterID* 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 
    689 RegisterID* 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 
    701 RegisterID* 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 
    718 RegisterID* 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 
    730 RegisterID* 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 
    765 RegisterID* 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 
    784 RegisterID* 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 
    802 RegisterID* 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 
    811 RegisterID* 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 
    820 void 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 //
    859 RegisterID* 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 
    949 RegisterID* 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 
    969 RegisterID* 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 
    982 RegisterID* 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 
    989 RegisterID* 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 
    996 RegisterID* 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 
   1004 RegisterID* 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 
   1021 RegisterID* 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 
   1037 void 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 
   1067 RegisterID* 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?
   1096 static 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 
   1150 RegisterID* 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 
   1189 RegisterID* 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 
   1221 RegisterID* 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 
   1233 RegisterID* 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 
   1247 RegisterID* AssignErrorNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
   1248 {
   1249     return emitThrowReferenceError(generator, "Left side of assignment is not a reference.");
   1250 }
   1251 
   1252 // ------------------------------ AssignBracketNode -----------------------------------
   1253 
   1254 RegisterID* 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 
   1268 RegisterID* 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 
   1285 RegisterID* 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 
   1295 RegisterID* 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 
   1317 RegisterID* 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 
   1328 RegisterID* ConstStatementNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
   1329 {
   1330     generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
   1331     return generator.emitNode(m_next);
   1332 }
   1333 
   1334 // ------------------------------ SourceElements -------------------------------
   1335 
   1336 
   1337 inline StatementNode* SourceElements::lastStatement() const
   1338 {
   1339     size_t size = m_statements.size();
   1340     return size ? m_statements[size - 1] : 0;
   1341 }
   1342 
   1343 inline 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 
   1352 inline StatementNode* BlockNode::lastStatement() const
   1353 {
   1354     return m_statements ? m_statements->lastStatement() : 0;
   1355 }
   1356 
   1357 inline StatementNode* BlockNode::singleStatement() const
   1358 {
   1359     return m_statements ? m_statements->singleStatement() : 0;
   1360 }
   1361 
   1362 RegisterID* 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 
   1371 RegisterID* EmptyStatementNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
   1372 {
   1373     generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
   1374     return dst;
   1375 }
   1376 
   1377 // ------------------------------ DebuggerStatementNode ---------------------------
   1378 
   1379 RegisterID* DebuggerStatementNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
   1380 {
   1381     generator.emitDebugHook(DidReachBreakpoint, firstLine(), lastLine());
   1382     return dst;
   1383 }
   1384 
   1385 // ------------------------------ ExprStatementNode ----------------------------
   1386 
   1387 RegisterID* 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 
   1396 RegisterID* 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 
   1405 RegisterID* 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 
   1429 RegisterID* 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 
   1460 RegisterID* 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 
   1486 RegisterID* 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 
   1515 RegisterID* 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 
   1554 RegisterID* 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
   1630 RegisterID* 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
   1644 RegisterID* 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 
   1657 RegisterID* 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 
   1681 RegisterID* 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 
   1696 inline void CaseClauseNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
   1697 {
   1698     if (m_statements)
   1699         m_statements->emitBytecode(generator, dst);
   1700 }
   1701 
   1702 // ------------------------------ CaseBlockNode --------------------------------
   1703 
   1704 enum SwitchKind {
   1705     SwitchUnset = 0,
   1706     SwitchNumber = 1,
   1707     SwitchString = 2,
   1708     SwitchNeither = 3
   1709 };
   1710 
   1711 static 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 
   1751 SwitchInfo::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 
   1780 RegisterID* 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 
   1846 RegisterID* 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 
   1861 RegisterID* 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 
   1876 RegisterID* 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 
   1890 RegisterID* 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 
   1962 inline 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 
   1970 RegisterID* 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 
   1985 RegisterID* 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 
   2000 RegisterID* 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 
   2041 RegisterID* FuncDeclNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
   2042 {
   2043     if (dst == generator.ignoredResult())
   2044         dst = 0;
   2045     return dst;
   2046 }
   2047 
   2048 // ------------------------------ FuncExprNode ---------------------------------
   2049 
   2050 RegisterID* FuncExprNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
   2051 {
   2052     return generator.emitNewFunctionExpression(generator.finalDestination(dst), this);
   2053 }
   2054 
   2055 } // namespace JSC
   2056