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