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