kjs Library: nodes.cpp Source File (kjs Library)

| # kjs Library API Documentation
Overview | Class Hierarchy | Classes | Classes (annotated) | Members | Namespaces | Source Files

# nodes.cpp

    00001 // -*- c-basic-offset: 2 -*-
    00002 /*
    00003  *  This file is part of the KDE libraries
    00004  *  Copyright (C) 1999-2002, 2003 Harri Porten (porten@kde.org)
    00005  *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
    00006  *  Copyright (C) 2003 Apple Computer, Inc.
    00007  *
    00008  *  This library is free software; you can redistribute it and/or
    00009  *  modify it under the terms of the GNU Library General Public
    00010  *  License as published by the Free Software Foundation; either
    00011  *  version 2 of the License, or (at your option) any later version.
    00012  *
    00013  *  This library is distributed in the hope that it will be useful,
    00014  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
    00015  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    00016  *  Library General Public License for more details.
    00017  *
    00018  *  You should have received a copy of the GNU Library General Public License
    00019  *  along with this library; see the file COPYING.LIB.  If not, write to
    00020  *  the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    00021  *  Boston, MA 02111-1307, USA.
    00022  *
    00023  */
    00024
    00025 #include "nodes.h"
    00026
    00027 #include <math.h>
    00028 #include <assert.h>
    00029 #ifdef KJS_DEBUG_MEM
    00030 #include <stdio.h>
    00031 #include <typeinfo>
    00032 #endif
    00033 #ifdef KJS_VERBOSE
    00034 #include <iostream>
    00035 using namespace std;
    00036 #endif
    00037
    00038 #include "collector.h"
    00039 #include "context.h"
    00040 #include "debugger.h"
    00041 #include "function_object.h"
    00042 #include "internal.h"
    00043 #include "value.h"
    00044 #include "object.h"
    00045 #include "types.h"
    00046 #include "interpreter.h"
    00047 #include "lexer.h"
    00048 #include "operations.h"
    00049 #include "ustring.h"
    00050
    00051 using namespace KJS;
    00052
    00053 #define KJS_BREAKPOINT \
    00054   if (!hitStatement(exec)) \
    00055     return Completion(Normal);
    00056
    00057 #define KJS_ABORTPOINT \
    00058   if (exec->interpreter()->imp()->debugger() && \
    00059       exec->interpreter()->imp()->debugger()->imp()->aborted()) \
    00060     return Completion(Normal);
    00061
    00062 #define KJS_CHECKEXCEPTION \
    00063   if (exec->hadException()) \
    00064     return Completion(Throw, exec->exception()); \
    00065   if (Collector::outOfMemory()) \
    00066     return Completion(Throw, Error::create(exec,GeneralError,"Out of memory"));
    00067
    00068 #define KJS_CHECKEXCEPTIONVALUE \
    00069   if (exec->hadException()) \
    00070     return exec->exception(); \
    00071   if (Collector::outOfMemory()) \
    00072     return Undefined(); // will be picked up by KJS_CHECKEXCEPTION
    00073
    00074 #define KJS_CHECKEXCEPTIONREFERENCE \
    00075   if (exec->hadException()) \
    00076     return Reference::makeValueReference(Undefined()); \
    00077   if (Collector::outOfMemory()) \
    00078     return Reference::makeValueReference(Undefined()); // will be picked up by KJS_CHECKEXCEPTION
    00079
    00080 #define KJS_CHECKEXCEPTIONLIST \
    00081   if (exec->hadException()) \
    00082     return List(); \
    00083   if (Collector::outOfMemory()) \
    00084     return List(); // will be picked up by KJS_CHECKEXCEPTION
    00085
    00086 #ifdef KJS_DEBUG_MEM
    00087 std::list<Node *> * Node::s_nodes = 0L;
    00088 #endif
    00089
    00090 // ----------------------------- Node -----------------------------------------
    00091
    00092 Node::Node()
    00093 {
    00094   line = Lexer::curr()->lineNo();
    00095   refcount = 0;
    00096 #ifdef KJS_DEBUG_MEM
    00097   if (!s_nodes)
    00098     s_nodes = new std::list<Node *>;
    00099   s_nodes->push_back(this);
    00100 #endif
    00101 }
    00102
    00103 Node::~Node()
    00104 {
    00105 #ifdef KJS_DEBUG_MEM
    00106   s_nodes->remove( this );
    00107 #endif
    00108 }
    00109
    00110 Reference Node::evaluateReference(ExecState *exec) const
    00111 {
    00112   Value v = evaluate(exec);
    00113   KJS_CHECKEXCEPTIONREFERENCE
    00114   return Reference::makeValueReference(v);
    00115 }
    00116
    00117 // fallback for those nodes without a evaluate() reimplementation
    00118 // TODO: reimplemint in each sub class, make Node::evaluate() pure virtual
    00119 Value Node::evaluate(ExecState *exec) const
    00120 {
    00121   //  fprintf(stderr, "%s::evaluate()\n", typeid(*this).name());
    00122   return evaluateReference(exec).getValue(exec);
    00123 }
    00124
    00125 bool Node::toBoolean(ExecState *exec) const
    00126 {
    00127 //   fprintf(stderr, "Node(%s)::toBoolean()\n", typeid(*this).name());
    00128   return evaluate(exec).toBoolean(exec);
    00129 }
    00130
    00131 double Node::toNumber(ExecState *exec) const
    00132 {
    00133 //   fprintf(stderr, "Node(%s)::toNumber()\n", typeid(*this).name());
    00134   return evaluate(exec).toNumber(exec);
    00135 }
    00136
    00137 UString Node::toString(ExecState *exec) const
    00138 {
    00139   return evaluate(exec).toString(exec);
    00140 }
    00141
    00142 #ifdef KJS_DEBUG_MEM
    00143 void Node::finalCheck()
    00144 {
    00145   if (!s_nodes) {
    00146       fprintf(stderr, "Node::finalCheck(): list 0\n");
    00147       return;
    00148   }
    00149   fprintf( stderr, "Node::finalCheck(): list count       : %d\n", (int)s_nodes->size() );
    00150   std::list<Node *>::iterator it = s_nodes->begin();
    00151   for ( uint i = 0; it != s_nodes->end() ; ++it, ++i )
    00152     fprintf( stderr, "[%d] Still having node %p (%s) (refcount %d)\n", i, (void*)*it, typeid( **it ).name(), (*it)->refcount );
    00153   delete s_nodes;
    00154   s_nodes = 0L;
    00155 }
    00156 #endif
    00157
    00158 Value Node::throwError(ExecState *exec, ErrorType e, const char *msg) const
    00159 {
    00160   Object err = Error::create(exec, e, msg, lineNo(), sourceId());
    00161   exec->setException(err);
    00162   return err;
    00163 }
    00164
    00165 Value Node::throwError(ExecState *exec, ErrorType e, const char *msg,
    00166                        const Value &v, const Node *expr) const
    00167 {
    00168   char *vStr = strdup(v.toString(exec).ascii());
    00169   char *exprStr = strdup(expr->toCode().ascii());
    00170
    00171   int length =  strlen(msg) - 4 /* two %s */ + strlen(vStr) + strlen(exprStr) +
    00172  1 /* null terminator */;
    00173   char *str = new char[length];
    00174   sprintf(str, msg, vStr, exprStr);
    00175   free(vStr);
    00176   free(exprStr);
    00177
    00178   Value result = throwError(exec, e, str);
    00179   delete [] str;
    00180
    00181   return result;
    00182 }
    00183
    00184 Value Node::throwError(ExecState *exec, ErrorType e, const char *msg, Identifier label) const
    00185 {
    00186   const char *l = label.ascii();
    00187   int length = strlen(msg) - 2 /* %s */ + strlen(l) + 1 /* null terminator */;
    00188   char *message = new char[length];
    00189   sprintf(message, msg, l);
    00190
    00191   Value result = throwError(exec, e, message);
    00192   delete [] message;
    00193
    00194   return result;
    00195 }
    00196
    00197 // ----------------------------- StatementNode --------------------------------
    00198 StatementNode::StatementNode() : l0(-1), l1(-1), sourceCode(0), breakPoint(false)
    00199 {
    00200 }
    00201
    00202 StatementNode::~StatementNode()
    00203 {
    00204   if (sourceCode)
    00205     sourceCode->deref();
    00206 }
    00207
    00208 void StatementNode::setLoc(int line0, int line1, SourceCode *src)
    00209 {
    00210   // ### require these to be passed to the constructor
    00211   l0 = line0;
    00212   l1 = line1;
    00213   if (sourceCode != src) {
    00214     if (sourceCode)
    00215       sourceCode->deref();
    00216     sourceCode = src;
    00217     sourceCode->ref();
    00218   }
    00219 }
    00220
    00221 // return true if the debugger wants us to stop at this point
    00222 bool StatementNode::hitStatement(ExecState *exec)
    00223 {
    00224   assert(sourceCode);
    00225   assert(exec->context().imp()->sourceId == sourceCode->sid);
    00226   exec->context().imp()->setLines(l0,l1);
    00227   Debugger *dbg = exec->interpreter()->imp()->debugger();
    00228   if (dbg)
    00229     return dbg->atStatement(exec);
    00230   else
    00231     return true; // continue
    00232 }
    00233
    00234 // return true if the debugger wants us to stop at this point
    00235 bool StatementNode::abortStatement(ExecState *exec)
    00236 {
    00237   Debugger *dbg = exec->interpreter()->imp()->debugger();
    00238   if (dbg)
    00239     return dbg->imp()->aborted();
    00240   else
    00241     return false;
    00242 }
    00243
    00244 void StatementNode::processFuncDecl(ExecState *)
    00245 {
    00246 }
    00247
    00248 // ----------------------------- NullNode -------------------------------------
    00249
    00250 Value NullNode::evaluate(ExecState *) const
    00251 {
    00252   return Null();
    00253 }
    00254
    00255 bool NullNode::toBoolean(ExecState *) const
    00256 {
    00257   return false;
    00258 }
    00259
    00260 double NullNode::toNumber(ExecState *) const
    00261 {
    00262   return 0.0;
    00263 }
    00264
    00265 UString NullNode::toString(ExecState *) const
    00266 {
    00267   return "null";
    00268 }
    00269
    00270 // ----------------------------- BooleanNode ----------------------------------
    00271
    00272 Value BooleanNode::evaluate(ExecState *) const
    00273 {
    00274   return Boolean(val);
    00275 }
    00276
    00277 bool BooleanNode::toBoolean(ExecState *) const
    00278 {
    00279   return val;
    00280 }
    00281
    00282 double BooleanNode::toNumber(ExecState *) const
    00283 {
    00284   return val ? 1.0 : 0.0;
    00285 }
    00286
    00287 UString BooleanNode::toString(ExecState *) const
    00288 {
    00289   return val ? "true" : "false";
    00290 }
    00291
    00292 // ----------------------------- NumberNode -----------------------------------
    00293
    00294 Value NumberNode::evaluate(ExecState *) const
    00295 {
    00296   return Number(val);
    00297 }
    00298
    00299 bool NumberNode::toBoolean(ExecState *) const
    00300 {
    00301   return !((val == 0) /* || (iVal() == N0) */ || isNaN(val));
    00302 }
    00303
    00304 double NumberNode::toNumber(ExecState *) const
    00305 {
    00306   return val;
    00307 }
    00308
    00309 UString NumberNode::toString(ExecState *) const
    00310 {
    00311   return UString::from(val);
    00312 }
    00313
    00314 // ----------------------------- StringNode -----------------------------------
    00315
    00316 Value StringNode::evaluate(ExecState *) const
    00317 {
    00318   return String(val);
    00319 }
    00320
    00321 bool StringNode::toBoolean(ExecState *) const
    00322 {
    00323   return !val.isEmpty();
    00324 }
    00325
    00326 double StringNode::toNumber(ExecState *) const
    00327 {
    00328   return val.toDouble();
    00329 }
    00330
    00331 UString StringNode::toString(ExecState *) const
    00332 {
    00333   return val;
    00334 }
    00335
    00336 // ----------------------------- RegExpNode -----------------------------------
    00337
    00338 Value RegExpNode::evaluate(ExecState *exec) const
    00339 {
    00340   List list;
    00341   String p(pattern);
    00342   String f(flags);
    00343   list.append(p);
    00344   list.append(f);
    00345
    00346   Object reg = exec->interpreter()->imp()->builtinRegExp();
    00347   return reg.construct(exec,list);
    00348 }
    00349
    00350 bool RegExpNode::toBoolean(ExecState *) const
    00351 {
    00352   return true;
    00353 }
    00354
    00355 // ----------------------------- ThisNode -------------------------------------
    00356
    00357 // ECMA 11.1.1
    00358 Value ThisNode::evaluate(ExecState *exec) const
    00359 {
    00360   return exec->context().imp()->thisValue();
    00361 }
    00362
    00363 // ----------------------------- ResolveNode ----------------------------------
    00364
    00365 // ECMA 11.1.2 & 10.1.4
    00366 Value ResolveNode::evaluate(ExecState *exec) const
    00367 {
    00368   return evaluateReference(exec).getValue(exec);
    00369 }
    00370
    00371 Reference ResolveNode::evaluateReference(ExecState *exec) const
    00372 {
    00373   ScopeChain chain = exec->context().imp()->scopeChain();
    00374
    00375   while (!chain.isEmpty()) {
    00376     ObjectImp *o = chain.top();
    00377
    00378     //cerr << "Resolve: looking at '" << ident.ascii() << "'"
    00379     //     << " in " << (void*)o << " " << o->classInfo()->className << endl;
    00380     if (o->hasProperty(exec,ident)) {
    00381       //cerr << "Resolve: FOUND '" << ident.ascii() << "'"
    00382       //     << " in " << (void*)o << " " << o->classInfo()->className << endl;
    00383       return Reference(o, ident);
    00384     }
    00385
    00386     chain.pop();
    00387   }
    00388
    00389   // identifier not found
    00390 #ifdef KJS_VERBOSE
    00391   cerr << "Resolve::evaluateReference: didn't find '" << ident.ustring().ascii() << "'" << endl;
    00392 #endif
    00393   return Reference(Null(), ident);
    00394 }
    00395
    00396 // ----------------------------- GroupNode ------------------------------------
    00397
    00398 void GroupNode::ref()
    00399 {
    00400   Node::ref();
    00401   if ( group )
    00402     group->ref();
    00403 }
    00404
    00405 bool GroupNode::deref()
    00406 {
    00407   if ( group && group->deref() )
    00408     delete group;
    00409   return Node::deref();
    00410 }
    00411
    00412 // ECMA 11.1.6
    00413 Value GroupNode::evaluate(ExecState *exec) const
    00414 {
    00415   return group->evaluate(exec);
    00416 }
    00417
    00418 Reference GroupNode::evaluateReference(ExecState *exec) const
    00419 {
    00420   return group->evaluateReference(exec);
    00421 }
    00422
    00423 // ----------------------------- ElementNode ----------------------------------
    00424
    00425 void ElementNode::ref()
    00426 {
    00427   for (ElementNode *n = this; n; n = n->list) {
    00428     n->Node::ref();
    00429     if (n->node)
    00430       n->node->ref();
    00431   }
    00432 }
    00433
    00434 bool ElementNode::deref()
    00435 {
    00436   ElementNode *next;
    00437   for (ElementNode *n = this; n; n = next) {
    00438     next = n->list;
    00439     if (n->node && n->node->deref())
    00440       delete n->node;
    00441     if (n != this && n->Node::deref())
    00442       delete n;
    00443   }
    00444   return Node::deref();
    00445 }
    00446
    00447 // ECMA 11.1.4
    00448 Value ElementNode::evaluate(ExecState *exec) const
    00449 {
    00450   Object array = exec->interpreter()->builtinArray().construct(exec, List::empty());
    00451   int length = 0;
    00452   for (const ElementNode *n = this; n; n = n->list) {
    00453     Value val = n->node->evaluate(exec);
    00454     KJS_CHECKEXCEPTIONVALUE
    00455     length += n->elision;
    00456     array.put(exec, length++, val);
    00457   }
    00458   return array;
    00459 }
    00460
    00461 // ----------------------------- ArrayNode ------------------------------------
    00462
    00463 void ArrayNode::ref()
    00464 {
    00465   Node::ref();
    00466   if ( element )
    00467     element->ref();
    00468 }
    00469
    00470 bool ArrayNode::deref()
    00471 {
    00472   if ( element && element->deref() )
    00473     delete element;
    00474   return Node::deref();
    00475 }
    00476
    00477 // ECMA 11.1.4
    00478 Value ArrayNode::evaluate(ExecState *exec) const
    00479 {
    00480   Object array;
    00481   int length;
    00482
    00483   if (element) {
    00484     array = Object(static_cast<ObjectImp*>(element->evaluate(exec).imp()));
    00485     KJS_CHECKEXCEPTIONVALUE
    00486     length = opt ? array.get(exec,lengthPropertyName).toInt32(exec) : 0;
    00487   } else {
    00488     Value newArr = exec->interpreter()->builtinArray().construct(exec,List::empty());
    00489     array = Object(static_cast<ObjectImp*>(newArr.imp()));
    00490     length = 0;
    00491   }
    00492
    00493   if (opt)
    00494     array.put(exec,lengthPropertyName, Number(elision + length), DontEnum | DontDelete);
    00495
    00496   return array;
    00497 }
    00498
    00499 // ----------------------------- ObjectLiteralNode ----------------------------
    00500
    00501 void ObjectLiteralNode::ref()
    00502 {
    00503   Node::ref();
    00504   if ( list )
    00505     list->ref();
    00506 }
    00507
    00508 bool ObjectLiteralNode::deref()
    00509 {
    00510   if ( list && list->deref() )
    00511     delete list;
    00512   return Node::deref();
    00513 }
    00514
    00515 // ECMA 11.1.5
    00516 Value ObjectLiteralNode::evaluate(ExecState *exec) const
    00517 {
    00518   if (list)
    00519     return list->evaluate(exec);
    00520
    00521   return exec->interpreter()->builtinObject().construct(exec,List::empty());
    00522 }
    00523
    00524 // ----------------------------- PropertyValueNode ----------------------------
    00525
    00526 void PropertyValueNode::ref()
    00527 {
    00528   for (PropertyValueNode *n = this; n; n = n->list) {
    00529     n->Node::ref();
    00530     if (n->name)
    00531       n->name->ref();
    00532     if (n->assign)
    00533       n->assign->ref();
    00534   }
    00535 }
    00536
    00537 bool PropertyValueNode::deref()
    00538 {
    00539   PropertyValueNode *next;
    00540   for (PropertyValueNode *n = this; n; n = next) {
    00541     next = n->list;
    00542     if ( n->name && n->name->deref() )
    00543       delete n->name;
    00544     if ( n->assign && n->assign->deref() )
    00545       delete n->assign;
    00546     if (n != this && n->Node::deref() )
    00547       delete n;
    00548   }
    00549   return Node::deref();
    00550 }
    00551
    00552 // ECMA 11.1.5
    00553 Value PropertyValueNode::evaluate(ExecState *exec) const
    00554 {
    00555   Object obj = exec->interpreter()->builtinObject().construct(exec, List::empty());
    00556
    00557   for (const PropertyValueNode *p = this; p; p = p->list) {
    00558     Value n = p->name->evaluate(exec);
    00559     KJS_CHECKEXCEPTIONVALUE
    00560     Value v = p->assign->evaluate(exec);
    00561     KJS_CHECKEXCEPTIONVALUE
    00562
    00563     obj.put(exec, Identifier(n.toString(exec)), v);
    00564   }
    00565
    00566   return obj;
    00567 }
    00568
    00569 // ----------------------------- PropertyNode ---------------------------------
    00570
    00571 // ECMA 11.1.5
    00572 Value PropertyNode::evaluate(ExecState * /*exec*/) const
    00573 {
    00574   Value s;
    00575
    00576   if (str.isNull()) {
    00577     s = String(UString::from(numeric));
    00578   } else {
    00579     s = String(str.ustring());
    00580   }
    00581
    00582   return s;
    00583 }
    00584
    00585 // ----------------------------- AccessorNode1 --------------------------------
    00586
    00587 void AccessorNode1::ref()
    00588 {
    00589   Node::ref();
    00590   if ( expr1 )
    00591     expr1->ref();
    00592   if ( expr2 )
    00593     expr2->ref();
    00594 }
    00595
    00596 bool AccessorNode1::deref()
    00597 {
    00598   if ( expr1 && expr1->deref() )
    00599     delete expr1;
    00600   if ( expr2 && expr2->deref() )
    00601     delete expr2;
    00602   return Node::deref();
    00603 }
    00604
    00605 // ECMA 11.2.1a
    00606 Reference AccessorNode1::evaluateReference(ExecState *exec) const
    00607 {
    00608   Value v1 = expr1->evaluate(exec);
    00609   KJS_CHECKEXCEPTIONREFERENCE
    00610   Value v2 = expr2->evaluate(exec);
    00611   KJS_CHECKEXCEPTIONREFERENCE
    00612 #ifndef NDEBUG
    00613   // catch errors before being caught in toObject(). better error message.
    00614   if (v1.isA(UndefinedType) || v1.isA(NullType)) {
    00615     UString s = "Attempted to access property on %s object "
    00616                 "(result of expression %s)";
    00617         (void)throwError(exec, TypeError, s.cstring().c_str(), v1, this);
    00618     return Reference::makeValueReference(Undefined());
    00619   }
    00620 #endif
    00621   Object o = v1.toObject(exec);
    00622   unsigned i;
    00623   if (v2.toUInt32(i))
    00624     return Reference(o, i);
    00625   UString s = v2.toString(exec);
    00626   return Reference(o, Identifier(s));
    00627 }
    00628
    00629 // ----------------------------- AccessorNode2 --------------------------------
    00630
    00631 void AccessorNode2::ref()
    00632 {
    00633   Node::ref();
    00634   if ( expr )
    00635     expr->ref();
    00636 }
    00637
    00638 bool AccessorNode2::deref()
    00639 {
    00640   if ( expr && expr->deref() )
    00641     delete expr;
    00642   return Node::deref();
    00643 }
    00644
    00645 // ECMA 11.2.1b
    00646 Reference AccessorNode2::evaluateReference(ExecState *exec) const
    00647 {
    00648   Value v = expr->evaluate(exec);
    00649   KJS_CHECKEXCEPTIONREFERENCE
    00650   assert(v.isValid());
    00651 #ifndef NDEBUG
    00652   // catch errors before being caught in toObject(). better error message.
    00653   if (v.isA(UndefinedType) || v.isA(NullType)) {
    00654     UString s = "Attempted to access '" + ident.ustring() +
    00655                 "' property on %s object (result of expression %s)";
    00656         (void)throwError(exec, TypeError, s.cstring().c_str(), v, this);
    00657     return Reference::makeValueReference(Undefined());
    00658   }
    00659 #endif
    00660   Object o = v.toObject(exec);
    00661   return Reference(o, ident);
    00662 }
    00663
    00664 // ----------------------------- ArgumentListNode -----------------------------
    00665
    00666 void ArgumentListNode::ref()
    00667 {
    00668   for (ArgumentListNode *n = this; n; n = n->list) {
    00669     n->Node::ref();
    00670     if (n->expr)
    00671       n->expr->ref();
    00672   }
    00673 }
    00674
    00675 bool ArgumentListNode::deref()
    00676 {
    00677   ArgumentListNode *next;
    00678   for (ArgumentListNode *n = this; n; n = next) {
    00679     next = n->list;
    00680     if (n->expr && n->expr->deref())
    00681       delete n->expr;
    00682     if (n != this && n->Node::deref())
    00683       delete n;
    00684   }
    00685   return Node::deref();
    00686 }
    00687
    00688 Value ArgumentListNode::evaluate(ExecState * /*exec*/) const
    00689 {
    00690   assert(0);
    00691   return Value(); // dummy, see evaluateList()
    00692 }
    00693
    00694 // ECMA 11.2.4
    00695 List ArgumentListNode::evaluateList(ExecState *exec) const
    00696 {
    00697   List l;
    00698
    00699   for (const ArgumentListNode *n = this; n; n = n->list) {
    00700     Value v = n->expr->evaluate(exec);
    00701     KJS_CHECKEXCEPTIONLIST
    00702     l.append(v);
    00703   }
    00704
    00705   return l;
    00706 }
    00707
    00708 // ----------------------------- ArgumentsNode --------------------------------
    00709
    00710 void ArgumentsNode::ref()
    00711 {
    00712   Node::ref();
    00713   if ( list )
    00714     list->ref();
    00715 }
    00716
    00717 bool ArgumentsNode::deref()
    00718 {
    00719   if ( list && list->deref() )
    00720     delete list;
    00721   return Node::deref();
    00722 }
    00723
    00724 Value ArgumentsNode::evaluate(ExecState * /*exec*/) const
    00725 {
    00726   assert(0);
    00727   return Value(); // dummy, see evaluateList()
    00728 }
    00729
    00730 // ECMA 11.2.4
    00731 List ArgumentsNode::evaluateList(ExecState *exec) const
    00732 {
    00733   if (!list)
    00734     return List();
    00735
    00736   return list->evaluateList(exec);
    00737 }
    00738
    00739 // ----------------------------- NewExprNode ----------------------------------
    00740
    00741 // ECMA 11.2.2
    00742
    00743 void NewExprNode::ref()
    00744 {
    00745   Node::ref();
    00746   if ( expr )
    00747     expr->ref();
    00748   if ( args )
    00749     args->ref();
    00750 }
    00751
    00752 bool NewExprNode::deref()
    00753 {
    00754   if ( expr && expr->deref() )
    00755     delete expr;
    00756   if ( args && args->deref() )
    00757     delete args;
    00758   return Node::deref();
    00759 }
    00760
    00761 Value NewExprNode::evaluate(ExecState *exec) const
    00762 {
    00763   Value v = expr->evaluate(exec);
    00764   KJS_CHECKEXCEPTIONVALUE
    00765
    00766   List argList;
    00767   if (args) {
    00768     argList = args->evaluateList(exec);
    00769     KJS_CHECKEXCEPTIONVALUE
    00770   }
    00771
    00772   if (v.type() != ObjectType) {
    00773     return throwError(exec, TypeError, "Value %s (result of expression %s) is not an object. Cannot be used with new.", v, expr);
    00774   }
    00775
    00776   Object constr = Object(static_cast<ObjectImp*>(v.imp()));
    00777   if (!constr.implementsConstruct()) {
    00778     return throwError(exec, TypeError, "Value %s (result of expression %s) is not a constructor. Cannot be used with new.", v, expr);
    00779   }
    00780
    00781   Value res = constr.construct(exec,argList);
    00782
    00783   return res;
    00784 }
    00785
    00786 // ----------------------------- FunctionCallNode -----------------------------
    00787
    00788 void FunctionCallNode::ref()
    00789 {
    00790   Node::ref();
    00791   if ( expr )
    00792     expr->ref();
    00793   if ( args )
    00794     args->ref();
    00795 }
    00796
    00797 bool FunctionCallNode::deref()
    00798 {
    00799   if ( expr && expr->deref() )
    00800     delete expr;
    00801   if ( args && args->deref() )
    00802     delete args;
    00803   return Node::deref();
    00804 }
    00805
    00806 // ECMA 11.2.3
    00807 Value FunctionCallNode::evaluate(ExecState *exec) const
    00808 {
    00809   Reference ref = expr->evaluateReference(exec);
    00810   KJS_CHECKEXCEPTIONVALUE
    00811
    00812   List argList = args->evaluateList(exec);
    00813   KJS_CHECKEXCEPTIONVALUE
    00814
    00815   Value v = ref.getValue(exec);
    00816   KJS_CHECKEXCEPTIONVALUE
    00817
    00818   if (v.type() != ObjectType) {
    00819     return throwError(exec, TypeError, "Value %s (result of expression %s) is not an object. Cannot be called.", v, expr);
    00820   }
    00821
    00822   Object func = Object(static_cast<ObjectImp*>(v.imp()));
    00823
    00824   if (!func.implementsCall()) {
    00825     return throwError(exec, TypeError, "Object %s (result of expression %s) does not allow calls.", v, expr);
    00826   }
    00827
    00828   Value thisVal;
    00829   if (ref.isMutable())
    00830     thisVal = ref.getBase(exec);
    00831   else
    00832     thisVal = Null();
    00833
    00834   if (thisVal.type() == ObjectType &&
    00835       Object::dynamicCast(thisVal).inherits(&ActivationImp::info))
    00836     thisVal = Null();
    00837
    00838   if (thisVal.type() != ObjectType) {
    00839     // ECMA 11.2.3 says that in this situation the this value should be null.
    00840     // However, section 10.2.3 says that in the case where the value provided
    00841     // by the caller is null, the global object should be used. It also says
    00842     // that the section does not apply to interal functions, but for simplicity
    00843     // of implementation we use the global object anyway here. This guarantees
    00844     // that in host objects you always get a valid object for this.
    00845     // thisVal = Null();
    00846     thisVal = exec->interpreter()->globalObject();
    00847   }
    00848
    00849   Object thisObj = Object::dynamicCast(thisVal);
    00850   Value result = func.call(exec,thisObj, argList);
    00851
    00852   return result;
    00853 }
    00854
    00855 // ----------------------------- PostfixNode ----------------------------------
    00856
    00857 void PostfixNode::ref()
    00858 {
    00859   Node::ref();
    00860   if ( expr )
    00861     expr->ref();
    00862 }
    00863
    00864 bool PostfixNode::deref()
    00865 {
    00866   if ( expr && expr->deref() )
    00867     delete expr;
    00868   return Node::deref();
    00869 }
    00870
    00871 // ECMA 11.3
    00872 Value PostfixNode::evaluate(ExecState *exec) const
    00873 {
    00874   Reference ref = expr->evaluateReference(exec);
    00875   KJS_CHECKEXCEPTIONVALUE
    00876   Value v = ref.getValue(exec);
    00877   double n = v.toNumber(exec);
    00878
    00879   double newValue = (oper == OpPlusPlus) ? n + 1 : n - 1;
    00880
    00881   ref.putValue(exec, Number(newValue));
    00882
    00883   return Number(n);
    00884 }
    00885
    00886 // ----------------------------- DeleteNode -----------------------------------
    00887
    00888 void DeleteNode::ref()
    00889 {
    00890   Node::ref();
    00891   if ( expr )
    00892     expr->ref();
    00893 }
    00894
    00895 bool DeleteNode::deref()
    00896 {
    00897   if ( expr && expr->deref() )
    00898     delete expr;
    00899   return Node::deref();
    00900 }
    00901
    00902 // ECMA 11.4.1
    00903 Value DeleteNode::evaluate(ExecState *exec) const
    00904 {
    00905   Reference ref = expr->evaluateReference(exec);
    00906   KJS_CHECKEXCEPTIONVALUE
    00907   return Boolean(ref.deleteValue(exec));
    00908 }
    00909
    00910 // ----------------------------- VoidNode -------------------------------------
    00911
    00912 void VoidNode::ref()
    00913 {
    00914   Node::ref();
    00915   if ( expr )
    00916     expr->ref();
    00917 }
    00918
    00919 bool VoidNode::deref()
    00920 {
    00921   if ( expr && expr->deref() )
    00922     delete expr;
    00923   return Node::deref();
    00924 }
    00925
    00926 // ECMA 11.4.2
    00927 Value VoidNode::evaluate(ExecState *exec) const
    00928 {
    00929   Value dummy1 = expr->evaluate(exec);
    00930   KJS_CHECKEXCEPTIONVALUE
    00931
    00932   return Undefined();
    00933 }
    00934
    00935 // ----------------------------- TypeOfNode -----------------------------------
    00936
    00937 void TypeOfNode::ref()
    00938 {
    00939   Node::ref();
    00940   if ( expr )
    00941     expr->ref();
    00942 }
    00943
    00944 bool TypeOfNode::deref()
    00945 {
    00946   if ( expr && expr->deref() )
    00947     delete expr;
    00948   return Node::deref();
    00949 }
    00950
    00951 // ECMA 11.4.3
    00952 Value TypeOfNode::evaluate(ExecState *exec) const
    00953 {
    00954   const char *s = 0L;
    00955   Reference ref = expr->evaluateReference(exec);
    00956   KJS_CHECKEXCEPTIONVALUE
    00957   if (ref.isMutable()) {
    00958     Value b = ref.getBase(exec);
    00959     if (b.type() == NullType)
    00960       return String("undefined");
    00961   }
    00962   Value v = ref.getValue(exec);
    00963   switch (v.type())
    00964     {
    00965     case UndefinedType:
    00966       s = "undefined";
    00967       break;
    00968     case NullType:
    00969       s = "object";
    00970       break;
    00971     case BooleanType:
    00972       s = "boolean";
    00973       break;
    00974     case NumberType:
    00975       s = "number";
    00976       break;
    00977     case StringType:
    00978       s = "string";
    00979       break;
    00980     default:
    00981       if (v.type() == ObjectType && static_cast<ObjectImp*>(v.imp())->implementsCall())
    00982     s = "function";
    00983       else
    00984     s = "object";
    00985       break;
    00986     }
    00987
    00988   return String(s);
    00989 }
    00990
    00991 // ----------------------------- PrefixNode -----------------------------------
    00992
    00993 void PrefixNode::ref()
    00994 {
    00995   Node::ref();
    00996   if ( expr )
    00997     expr->ref();
    00998 }
    00999
    01000 bool PrefixNode::deref()
    01001 {
    01002   if ( expr && expr->deref() )
    01003     delete expr;
    01004   return Node::deref();
    01005 }
    01006
    01007 // ECMA 11.4.4 and 11.4.5
    01008 Value PrefixNode::evaluate(ExecState *exec) const
    01009 {
    01010   Reference ref = expr->evaluateReference(exec);
    01011   KJS_CHECKEXCEPTION
    01012   Value v = ref.getValue(exec);
    01013   double n = v.toNumber(exec);
    01014
    01015   double newValue = (oper == OpPlusPlus) ? n + 1 : n - 1;
    01016   Value n2 = Number(newValue);
    01017
    01018   ref.putValue(exec,n2);
    01019
    01020   return n2;
    01021 }
    01022
    01023 // ----------------------------- UnaryPlusNode --------------------------------
    01024
    01025 void UnaryPlusNode::ref()
    01026 {
    01027   Node::ref();
    01028   if ( expr )
    01029     expr->ref();
    01030 }
    01031
    01032 bool UnaryPlusNode::deref()
    01033 {
    01034   if ( expr && expr->deref() )
    01035     delete expr;
    01036   return Node::deref();
    01037 }
    01038
    01039 // ECMA 11.4.6
    01040 double UnaryPlusNode::toNumber(ExecState *exec) const
    01041 {
    01042   return expr->toNumber(exec);
    01043 }
    01044
    01045 // could go
    01046 Value UnaryPlusNode::evaluate(ExecState *exec) const
    01047 {
    01048   Value v = expr->evaluate(exec);
    01049   KJS_CHECKEXCEPTIONVALUE
    01050
    01051   return Number(v.toNumber(exec)); /* TODO: optimize */
    01052 }
    01053
    01054 // ----------------------------- NegateNode -----------------------------------
    01055
    01056 void NegateNode::ref()
    01057 {
    01058   Node::ref();
    01059   if ( expr )
    01060     expr->ref();
    01061 }
    01062
    01063 bool NegateNode::deref()
    01064 {
    01065   if ( expr && expr->deref() )
    01066     delete expr;
    01067   return Node::deref();
    01068 }
    01069
    01070 // ECMA 11.4.7
    01071 double NegateNode::toNumber(ExecState *exec) const
    01072 {
    01073   return -expr->toNumber(exec);
    01074 }
    01075
    01076 Value NegateNode::evaluate(ExecState *exec) const
    01077 {
    01078   Value v = expr->evaluate(exec);
    01079   KJS_CHECKEXCEPTIONVALUE
    01080   double d = -v.toNumber(exec);
    01081
    01082   return Number(d);
    01083 }
    01084
    01085 // ----------------------------- BitwiseNotNode -------------------------------
    01086
    01087 void BitwiseNotNode::ref()
    01088 {
    01089   Node::ref();
    01090   if ( expr )
    01091     expr->ref();
    01092 }
    01093
    01094 bool BitwiseNotNode::deref()
    01095 {
    01096   if ( expr && expr->deref() )
    01097     delete expr;
    01098   return Node::deref();
    01099 }
    01100
    01101 // ECMA 11.4.8
    01102 Value BitwiseNotNode::evaluate(ExecState *exec) const
    01103 {
    01104   Value v = expr->evaluate(exec);
    01105   KJS_CHECKEXCEPTIONVALUE
    01106   int i32 = v.toInt32(exec);
    01107
    01108   return Number(~i32);
    01109 }
    01110
    01111 // ----------------------------- LogicalNotNode -------------------------------
    01112
    01113 void LogicalNotNode::ref()
    01114 {
    01115   Node::ref();
    01116   if ( expr )
    01117     expr->ref();
    01118 }
    01119
    01120 bool LogicalNotNode::deref()
    01121 {
    01122   if ( expr && expr->deref() )
    01123     delete expr;
    01124   return Node::deref();
    01125 }
    01126
    01127 // ECMA 11.4.9
    01128 bool LogicalNotNode::toBoolean(ExecState *exec) const
    01129 {
    01130   return !expr->toBoolean(exec);
    01131 }
    01132
    01133 // could remove this
    01134 Value LogicalNotNode::evaluate(ExecState *exec) const
    01135 {
    01136   bool b = expr->toBoolean(exec);
    01137   KJS_CHECKEXCEPTIONVALUE
    01138
    01139   return Boolean(!b);
    01140 }
    01141
    01142 // ----------------------------- MultNode -------------------------------------
    01143
    01144 void MultNode::ref()
    01145 {
    01146   Node::ref();
    01147   if ( term1 )
    01148     term1->ref();
    01149   if ( term2 )
    01150     term2->ref();
    01151 }
    01152
    01153 bool MultNode::deref()
    01154 {
    01155   if ( term1 && term1->deref() )
    01156     delete term1;
    01157   if ( term2 && term2->deref() )
    01158     delete term2;
    01159   return Node::deref();
    01160 }
    01161
    01162 // ECMA 11.5
    01163 Value MultNode::evaluate(ExecState *exec) const
    01164 {
    01165   Value v1 = term1->evaluate(exec);
    01166   KJS_CHECKEXCEPTIONVALUE
    01167
    01168   Value v2 = term2->evaluate(exec);
    01169   KJS_CHECKEXCEPTIONVALUE
    01170
    01171   return mult(exec,v1, v2, oper);
    01172 }
    01173
    01174 // ----------------------------- AddNode --------------------------------------
    01175
    01176 // factory for an appropriate addition or substraction node
    01177 Node* AddNode::create(Node *t1, Node *t2, char op)
    01178 {
    01179   // ### many more combinations to check for
    01180   // fold constants
    01181   if ((t1->type() == NumberType || t1->type() == BooleanType) &&
    01182       (t2->type() == NumberType || t2->type() == BooleanType)) {
    01183     double d = t2->toNumber(0);
    01184     Node* n = new NumberNode(t1->toNumber(0) + (op == '+' ? d : -d));
    01185     delete t1;
    01186     delete t2;
    01187     return n;
    01188   }
    01189
    01190   if (op == '+' && t2->type() == StringType)
    01191     return new AppendStringNode(t1, t2->toString(0));
    01192
    01193   // fall back to generic node
    01194   return new AddNode(t1, t2, op);
    01195 }
    01196
    01197 void AddNode::ref()
    01198 {
    01199   Node::ref();
    01200   if ( term1 )
    01201     term1->ref();
    01202   if ( term2 )
    01203     term2->ref();
    01204 }
    01205
    01206 bool AddNode::deref()
    01207 {
    01208   if ( term1 && term1->deref() )
    01209     delete term1;
    01210   if ( term2 && term2->deref() )
    01211     delete term2;
    01212   return Node::deref();
    01213 }
    01214
    01215 // ECMA 11.6
    01216 Value AddNode::evaluate(ExecState *exec) const
    01217 {
    01218   Value v1 = term1->evaluate(exec);
    01219   KJS_CHECKEXCEPTIONVALUE
    01220
    01221   Value v2 = term2->evaluate(exec);
    01222   KJS_CHECKEXCEPTIONVALUE
    01223
    01224   return add(exec,v1, v2, oper);
    01225 }
    01226
    01227 // ------------------------ AddNumberNode ------------------------------------
    01228
    01229 void AppendStringNode::ref()
    01230 {
    01231   Node::ref();
    01232   term->ref();
    01233 }
    01234
    01235 bool AppendStringNode::deref()
    01236 {
    01237   if (term->deref())
    01238     delete term;
    01239   return Node::deref();
    01240 }
    01241
    01242 // ECMA 11.6 (special case of string appending)
    01243 Value AppendStringNode::evaluate(ExecState *exec) const
    01244 {
    01245   UString s = term->toString(exec);
    01246   KJS_CHECKEXCEPTIONVALUE
    01247
    01248   return String(s + str);
    01249 }
    01250
    01251 // ----------------------------- ShiftNode ------------------------------------
    01252
    01253 void ShiftNode::ref()
    01254 {
    01255   Node::ref();
    01256   if ( term1 )
    01257     term1->ref();
    01258   if ( term2 )
    01259     term2->ref();
    01260 }
    01261
    01262 bool ShiftNode::deref()
    01263 {
    01264   if ( term1 && term1->deref() )
    01265     delete term1;
    01266   if ( term2 && term2->deref() )
    01267     delete term2;
    01268   return Node::deref();
    01269 }
    01270
    01271 // ECMA 11.7
    01272 Value ShiftNode::evaluate(ExecState *exec) const
    01273 {
    01274   Value v1 = term1->evaluate(exec);
    01275   KJS_CHECKEXCEPTIONVALUE
    01276   Value v2 = term2->evaluate(exec);
    01277   KJS_CHECKEXCEPTIONVALUE
    01278   unsigned int i2 = v2.toUInt32(exec);
    01279   i2 &= 0x1f;
    01280
    01281   switch (oper) {
    01282   case OpLShift:
    01283     return Number(v1.toInt32(exec) << i2);
    01284   case OpRShift:
    01285     return Number(v1.toInt32(exec) >> i2);
    01286   case OpURShift:
    01287     return Number(v1.toUInt32(exec) >> i2);
    01288   default:
    01289     assert(!"ShiftNode: unhandled switch case");
    01290     return Undefined();
    01291   }
    01292 }
    01293
    01294 // ----------------------------- RelationalNode -------------------------------
    01295
    01296 void RelationalNode::ref()
    01297 {
    01298   Node::ref();
    01299   if ( expr1 )
    01300     expr1->ref();
    01301   if ( expr2 )
    01302     expr2->ref();
    01303 }
    01304
    01305 bool RelationalNode::deref()
    01306 {
    01307   if ( expr1 && expr1->deref() )
    01308     delete expr1;
    01309   if ( expr2 && expr2->deref() )
    01310     delete expr2;
    01311   return Node::deref();
    01312 }
    01313
    01314 // ECMA 11.8
    01315 Value RelationalNode::evaluate(ExecState *exec) const
    01316 {
    01317   Value v1 = expr1->evaluate(exec);
    01318   KJS_CHECKEXCEPTIONVALUE
    01319   Value v2 = expr2->evaluate(exec);
    01320   KJS_CHECKEXCEPTIONVALUE
    01321
    01322   bool b;
    01323   if (oper == OpLess || oper == OpGreaterEq) {
    01324     int r = relation(exec, v1, v2);
    01325     if (r < 0)
    01326       b = false;
    01327     else
    01328       b = (oper == OpLess) ? (r == 1) : (r == 0);
    01329   } else if (oper == OpGreater || oper == OpLessEq) {
    01330     int r = relation(exec, v2, v1);
    01331     if (r < 0)
    01332       b = false;
    01333     else
    01334       b = (oper == OpGreater) ? (r == 1) : (r == 0);
    01335   } else if (oper == OpIn) {
    01336       // Is all of this OK for host objects?
    01337       if (v2.type() != ObjectType)
    01338           return throwError(exec,  TypeError,
    01339                             "Value %s (result of expression %s) is not an object. Cannot be used with IN expression.", v2, expr2);
    01340       Object o2(static_cast<ObjectImp*>(v2.imp()));
    01341       b = o2.hasProperty(exec,Identifier(v1.toString(exec)));
    01342   } else {
    01343     if (v2.type() != ObjectType)
    01344         return throwError(exec,  TypeError,
    01345                           "Value %s (result of expression %s) is not an object. Cannot be used with instanceof operator.", v2, expr2);
    01346
    01347     Object o2(static_cast<ObjectImp*>(v2.imp()));
    01348     if (!o2.implementsHasInstance()) {
    01349       // According to the spec, only some types of objects "imlement" the [[HasInstance]] property.
    01350       // But we are supposed to throw an exception where the object does not "have" the [[HasInstance]]
    01351       // property. It seems that all object have the property, but not all implement it, so in this
    01352       // case we return false (consistent with mozilla)
    01353       return Boolean(false);
    01354       //      return throwError(exec, TypeError,
    01355       //            "Object does not implement the [[HasInstance]] method." );
    01356     }
    01357     return o2.hasInstance(exec, v1);
    01358   }
    01359
    01360   return Boolean(b);
    01361 }
    01362
    01363 // ----------------------------- EqualNode ------------------------------------
    01364
    01365 void EqualNode::ref()
    01366 {
    01367   Node::ref();
    01368   if ( expr1 )
    01369     expr1->ref();
    01370   if ( expr2 )
    01371     expr2->ref();
    01372 }
    01373
    01374 bool EqualNode::deref()
    01375 {
    01376   if ( expr1 && expr1->deref() )
    01377     delete expr1;
    01378   if ( expr2 && expr2->deref() )
    01379     delete expr2;
    01380   return Node::deref();
    01381 }
    01382
    01383 // ECMA 11.9
    01384 Value EqualNode::evaluate(ExecState *exec) const
    01385 {
    01386   Value v1 = expr1->evaluate(exec);
    01387   KJS_CHECKEXCEPTIONVALUE
    01388   Value v2 = expr2->evaluate(exec);
    01389   KJS_CHECKEXCEPTIONVALUE
    01390
    01391   bool result;
    01392   if (oper == OpEqEq || oper == OpNotEq) {
    01393     // == and !=
    01394     bool eq = equal(exec,v1, v2);
    01395     result = oper == OpEqEq ? eq : !eq;
    01396   } else {
    01397     // === and !==
    01398     bool eq = strictEqual(exec,v1, v2);
    01399     result = oper == OpStrEq ? eq : !eq;
    01400   }
    01401   return Boolean(result);
    01402 }
    01403
    01404 // ----------------------------- BitOperNode ----------------------------------
    01405
    01406 void BitOperNode::ref()
    01407 {
    01408   Node::ref();
    01409   if ( expr1 )
    01410     expr1->ref();
    01411   if ( expr2 )
    01412     expr2->ref();
    01413 }
    01414
    01415 bool BitOperNode::deref()
    01416 {
    01417   if ( expr1 && expr1->deref() )
    01418     delete expr1;
    01419   if ( expr2 && expr2->deref() )
    01420     delete expr2;
    01421   return Node::deref();
    01422 }
    01423
    01424 // ECMA 11.10
    01425 Value BitOperNode::evaluate(ExecState *exec) const
    01426 {
    01427   Value v1 = expr1->evaluate(exec);
    01428   KJS_CHECKEXCEPTIONVALUE
    01429   Value v2 = expr2->evaluate(exec);
    01430   KJS_CHECKEXCEPTIONVALUE
    01431   int i1 = v1.toInt32(exec);
    01432   int i2 = v2.toInt32(exec);
    01433   int result;
    01434   if (oper == OpBitAnd)
    01435     result = i1 & i2;
    01436   else if (oper == OpBitXOr)
    01437     result = i1 ^ i2;
    01438   else
    01439     result = i1 | i2;
    01440
    01441   return Number(result);
    01442 }
    01443
    01444 // ----------------------------- BinaryLogicalNode ----------------------------
    01445
    01446 void BinaryLogicalNode::ref()
    01447 {
    01448   Node::ref();
    01449   if ( expr1 )
    01450     expr1->ref();
    01451   if ( expr2 )
    01452     expr2->ref();
    01453 }
    01454
    01455 bool BinaryLogicalNode::deref()
    01456 {
    01457   if ( expr1 && expr1->deref() )
    01458     delete expr1;
    01459   if ( expr2 && expr2->deref() )
    01460     delete expr2;
    01461   return Node::deref();
    01462 }
    01463
    01464 // ECMA 11.11
    01465 Value BinaryLogicalNode::evaluate(ExecState *exec) const
    01466 {
    01467   Value v1 = expr1->evaluate(exec);
    01468   KJS_CHECKEXCEPTIONVALUE
    01469   bool b1 = v1.toBoolean(exec);
    01470   if ((!b1 && oper == OpAnd) || (b1 && oper == OpOr))
    01471     return v1;
    01472
    01473   Value v2 = expr2->evaluate(exec);
    01474   KJS_CHECKEXCEPTIONVALUE
    01475
    01476   return v2;
    01477 }
    01478
    01479 // ----------------------------- ConditionalNode ------------------------------
    01480
    01481 void ConditionalNode::ref()
    01482 {
    01483   Node::ref();
    01484   if ( expr1 )
    01485     expr1->ref();
    01486   if ( expr2 )
    01487     expr2->ref();
    01488   if ( logical )
    01489     logical->ref();
    01490 }
    01491
    01492 bool ConditionalNode::deref()
    01493 {
    01494   if ( expr1 && expr1->deref() )
    01495     delete expr1;
    01496   if ( expr2 && expr2->deref() )
    01497     delete expr2;
    01498   if ( logical && logical->deref() )
    01499     delete logical;
    01500   return Node::deref();
    01501 }
    01502
    01503 // ECMA 11.12
    01504 Value ConditionalNode::evaluate(ExecState *exec) const
    01505 {
    01506   bool b = logical->toBoolean(exec);
    01507   KJS_CHECKEXCEPTIONVALUE
    01508
    01509   Value v = b ? expr1->evaluate(exec) : expr2->evaluate(exec);
    01510   KJS_CHECKEXCEPTIONVALUE
    01511
    01512   return v;
    01513 }
    01514
    01515 // ----------------------------- AssignNode -----------------------------------
    01516
    01517 void AssignNode::ref()
    01518 {
    01519   Node::ref();
    01520   if ( left )
    01521     left->ref();
    01522   if ( expr )
    01523     expr->ref();
    01524 }
    01525
    01526 bool AssignNode::deref()
    01527 {
    01528   if ( left && left->deref() )
    01529     delete left;
    01530   if ( expr && expr->deref() )
    01531     delete expr;
    01532   return Node::deref();
    01533 }
    01534
    01535 // ECMA 11.13
    01536 Value AssignNode::evaluate(ExecState *exec) const
    01537 {
    01538   Reference l = left->evaluateReference(exec);
    01539   KJS_CHECKEXCEPTIONVALUE
    01540   Value v;
    01541   if (oper == OpEqual) {
    01542     v = expr->evaluate(exec);
    01543     KJS_CHECKEXCEPTIONVALUE
    01544   } else {
    01545     Value v1 = l.getValue(exec);
    01546     Value v2 = expr->evaluate(exec);
    01547     KJS_CHECKEXCEPTIONVALUE
    01548     int i1 = v1.toInt32(exec);
    01549     int i2 = v2.toInt32(exec);
    01550     unsigned int ui;
    01551     switch (oper) {
    01552     case OpMultEq:
    01553       v = mult(exec, v1, v2, '*');
    01554       break;
    01555     case OpDivEq:
    01556       v = mult(exec, v1, v2, '/');
    01557       break;
    01558     case OpPlusEq:
    01559       v = add(exec, v1, v2, '+');
    01560       break;
    01561     case OpMinusEq:
    01562       v = add(exec, v1, v2, '-');
    01563       break;
    01564     case OpLShift:
    01565       v = Number(i1 <<= i2);
    01566       break;
    01567     case OpRShift:
    01568       v = Number(i1 >>= i2);
    01569       break;
    01570     case OpURShift:
    01571       ui = v1.toUInt32(exec);
    01572       v = Number(ui >>= i2);
    01573       break;
    01574     case OpAndEq:
    01575       v = Number(i1 &= i2);
    01576       break;
    01577     case OpXOrEq:
    01578       v = Number(i1 ^= i2);
    01579       break;
    01580     case OpOrEq:
    01581       v = Number(i1 |= i2);
    01582       break;
    01583     case OpModEq: {
    01584       double d1 = v1.toNumber(exec);
    01585       double d2 = v2.toNumber(exec);
    01586       v = Number(fmod(d1,d2));
    01587     }
    01588       break;
    01589     default:
    01590       v = Undefined();
    01591     }
    01592   };
    01593   l.putValue(exec,v);
    01594
    01595   KJS_CHECKEXCEPTIONVALUE
    01596
    01597   return v;
    01598 }
    01599
    01600 // ----------------------------- CommaNode ------------------------------------
    01601
    01602 void CommaNode::ref()
    01603 {
    01604   Node::ref();
    01605   if ( expr1 )
    01606     expr1->ref();
    01607   if ( expr2 )
    01608     expr2->ref();
    01609 }
    01610
    01611 bool CommaNode::deref()
    01612 {
    01613   if ( expr1 && expr1->deref() )
    01614     delete expr1;
    01615   if ( expr2 && expr2->deref() )
    01616     delete expr2;
    01617   return Node::deref();
    01618 }
    01619
    01620 // ECMA 11.14
    01621 Value CommaNode::evaluate(ExecState *exec) const
    01622 {
    01623   (void) expr1->evaluate(exec);  // ignore return value
    01624   KJS_CHECKEXCEPTIONVALUE
    01625   Value v = expr2->evaluate(exec);
    01626   KJS_CHECKEXCEPTIONVALUE
    01627
    01628   return v;
    01629 }
    01630
    01631 // ----------------------------- StatListNode ---------------------------------
    01632
    01633 StatListNode::StatListNode(StatementNode *s)
    01634   : statement(s), list(this)
    01635 {
    01636   setLoc(s->firstLine(),s->lastLine(),s->code());
    01637 }
    01638
    01639 StatListNode::StatListNode(StatListNode *l, StatementNode *s)
    01640   : statement(s), list(l->list)
    01641 {
    01642   l->list = this;
    01643   setLoc(l->firstLine(),s->lastLine(),l->code());
    01644 }
    01645
    01646 void StatListNode::ref()
    01647 {
    01648   for (StatListNode *n = this; n; n = n->list) {
    01649     n->Node::ref();
    01650     if (n->statement)
    01651       n->statement->ref();
    01652   }
    01653 }
    01654
    01655 bool StatListNode::deref()
    01656 {
    01657   StatListNode *next;
    01658   for (StatListNode *n = this; n; n = next) {
    01659     next = n->list;
    01660     if (n->statement && n->statement->deref())
    01661       delete n->statement;
    01662     if (n != this && n->Node::deref())
    01663       delete n;
    01664   }
    01665   return StatementNode::deref();
    01666 }
    01667
    01668 // ECMA 12.1
    01669 Completion StatListNode::execute(ExecState *exec)
    01670 {
    01671   Completion c = statement->execute(exec);
    01672   KJS_ABORTPOINT
    01673   if (exec->hadException()) {
    01674     Value ex = exec->exception();
    01675     exec->clearException();
    01676     return Completion(Throw, ex);
    01677   }
    01678
    01679   if (c.complType() != Normal)
    01680     return c;
    01681
    01682   Value v = c.value();
    01683
    01684   for (StatListNode *n = list; n; n = n->list) {
    01685     Completion c2 = n->statement->execute(exec);
    01686     KJS_ABORTPOINT
    01687     if (c2.complType() != Normal)
    01688       return c2;
    01689
    01690     if (exec->hadException()) {
    01691       Value ex = exec->exception();
    01692       exec->clearException();
    01693       return Completion(Throw, ex);
    01694     }
    01695
    01696     if (c2.isValueCompletion())
    01697       v = c2.value();
    01698     c = c2;
    01699   }
    01700
    01701   return Completion(c.complType(), v, c.target());
    01702 }
    01703
    01704 void StatListNode::processVarDecls(ExecState *exec)
    01705 {
    01706   for (StatListNode *n = this; n; n = n->list)
    01707     n->statement->processVarDecls(exec);
    01708 }
    01709
    01710 // ----------------------------- AssignExprNode -------------------------------
    01711
    01712 void AssignExprNode::ref()
    01713 {
    01714   Node::ref();
    01715   if ( expr )
    01716     expr->ref();
    01717 }
    01718
    01719 bool AssignExprNode::deref()
    01720 {
    01721   if ( expr && expr->deref() )
    01722     delete expr;
    01723   return Node::deref();
    01724 }
    01725
    01726 // ECMA 12.2
    01727 Value AssignExprNode::evaluate(ExecState *exec) const
    01728 {
    01729   return expr->evaluate(exec);
    01730 }
    01731
    01732 // ----------------------------- VarDeclNode ----------------------------------
    01733
    01734 VarDeclNode::VarDeclNode(const Identifier &id, AssignExprNode *in)
    01735     : ident(id), init(in)
    01736 {
    01737 }
    01738
    01739 void VarDeclNode::ref()
    01740 {
    01741   Node::ref();
    01742   if ( init )
    01743     init->ref();
    01744 }
    01745
    01746 bool VarDeclNode::deref()
    01747 {
    01748   if ( init && init->deref() )
    01749     delete init;
    01750   return Node::deref();
    01751 }
    01752
    01753 // global var/const flag
    01754 static VarStatementNode::Type currentVarType;
    01755
    01756 // ECMA 12.2
    01757 Value VarDeclNode::evaluate(ExecState *exec) const
    01758 {
    01759   Object variable = Object::dynamicCast(exec->context().imp()->variableObject());
    01760
    01761   Value val;
    01762   if (init) {
    01763       val = init->evaluate(exec);
    01764       KJS_CHECKEXCEPTIONVALUE
    01765   } else {
    01766       if ( variable.hasProperty(exec, ident ) ) // already declared ?
    01767           return Value();
    01768       val = Undefined();
    01769   }
    01770
    01771 #ifdef KJS_VERBOSE
    01772   printInfo(exec,(UString("new variable ")+ident.ustring()).cstring().c_str(),val);
    01773 #endif
    01774   // We use Internal to bypass all checks in derived objects, e.g. so that
    01775   // "var location" creates a dynamic property instead of activating window.location.
    01776   int flags = Internal;
    01777   if (exec->_context->type() != EvalCode)
    01778     flags |= DontDelete;
    01779   if (currentVarType == VarStatementNode::Constant)
    01780     flags |= ReadOnly;
    01781   variable.put(exec, ident, val, flags);
    01782
    01783   // the spec wants us to return the name of the identifier here
    01784   // but we'll save the construction and copying as the return
    01785   // value isn't used by the caller
    01786   return Value();
    01787 }
    01788
    01789 void VarDeclNode::processVarDecls(ExecState *exec)
    01790 {
    01791   Object variable = exec->context().variableObject();
    01792   if ( !variable.hasProperty( exec, ident ) ) { // already declared ?
    01793     int flags = None;
    01794     if (exec->_context->type() != EvalCode)
    01795       flags |= DontDelete;
    01796     if (currentVarType == VarStatementNode::Constant)
    01797       flags |= ReadOnly;
    01798     // TODO: check for forbidden redeclaration of consts
    01799     variable.put(exec,ident, Undefined(), flags);
    01800   }
    01801   //else warning "variable %1 hides argument"
    01802 }
    01803
    01804 // ----------------------------- VarDeclListNode ------------------------------
    01805
    01806 void VarDeclListNode::ref()
    01807 {
    01808   for (VarDeclListNode *n = this; n; n = n->list) {
    01809     n->Node::ref();
    01810     if (n->var)
    01811       n->var->ref();
    01812   }
    01813 }
    01814
    01815 bool VarDeclListNode::deref()
    01816 {
    01817   VarDeclListNode *next;
    01818   for (VarDeclListNode *n = this; n; n = next) {
    01819     next = n->list;
    01820     if (n->var && n->var->deref())
    01821       delete n->var;
    01822     if (n != this && n->Node::deref())
    01823       delete n;
    01824   }
    01825   return Node::deref();
    01826 }
    01827
    01828
    01829 // ECMA 12.2
    01830 Value VarDeclListNode::evaluate(ExecState *exec) const
    01831 {
    01832   for (const VarDeclListNode *n = this; n; n = n->list) {
    01833     (void)n->var->evaluate(exec);
    01834     KJS_CHECKEXCEPTIONVALUE
    01835   }
    01836   return Undefined();
    01837 }
    01838
    01839 void VarDeclListNode::processVarDecls(ExecState *exec)
    01840 {
    01841   for (VarDeclListNode *n = this; n; n = n->list)
    01842     n->var->processVarDecls(exec);
    01843 }
    01844
    01845 // ----------------------------- VarStatementNode -----------------------------
    01846
    01847 void VarStatementNode::ref()
    01848 {
    01849   StatementNode::ref();
    01850   if ( list )
    01851     list->ref();
    01852 }
    01853
    01854 bool VarStatementNode::deref()
    01855 {
    01856   if ( list && list->deref() )
    01857     delete list;
    01858   return StatementNode::deref();
    01859 }
    01860
    01861 // ECMA 12.2
    01862 Completion VarStatementNode::execute(ExecState *exec)
    01863 {
    01864   KJS_BREAKPOINT;
    01865
    01866   // set global var/const flag
    01867   currentVarType = varType;
    01868
    01869   (void) list->evaluate(exec);
    01870   KJS_CHECKEXCEPTION
    01871
    01872   return Completion(Normal);
    01873 }
    01874
    01875 void VarStatementNode::processVarDecls(ExecState *exec)
    01876 {
    01877   // set global var/const flag
    01878   currentVarType = varType;
    01879
    01880   list->processVarDecls(exec);
    01881 }
    01882
    01883 // ----------------------------- BlockNode ------------------------------------
    01884
    01885 BlockNode::BlockNode(SourceElementsNode *s)
    01886 {
    01887   if (s) {
    01888     source = s->elements;
    01889     s->elements = 0;
    01890     setLoc(s->firstLine(), s->lastLine(), s->code());
    01891   } else {
    01892     source = 0;
    01893   }
    01894 }
    01895
    01896 void BlockNode::ref()
    01897 {
    01898   StatementNode::ref();
    01899   if ( source )
    01900     source->ref();
    01901 }
    01902
    01903 bool BlockNode::deref()
    01904 {
    01905   if ( source && source->deref() )
    01906     delete source;
    01907   return StatementNode::deref();
    01908 }
    01909
    01910 // ECMA 12.1
    01911 Completion BlockNode::execute(ExecState *exec)
    01912 {
    01913   if (!source)
    01914     return Completion(Normal);
    01915
    01916   source->processFuncDecl(exec);
    01917
    01918   return source->execute(exec);
    01919 }
    01920
    01921 void BlockNode::processVarDecls(ExecState *exec)
    01922 {
    01923   if (source)
    01924     source->processVarDecls(exec);
    01925 }
    01926
    01927 // ----------------------------- EmptyStatementNode ---------------------------
    01928
    01929 // ECMA 12.3
    01930 Completion EmptyStatementNode::execute(ExecState * /*exec*/)
    01931 {
    01932   return Completion(Normal);
    01933 }
    01934
    01935 // ----------------------------- ExprStatementNode ----------------------------
    01936
    01937 void ExprStatementNode::ref()
    01938 {
    01939   StatementNode::ref();
    01940   if ( expr )
    01941     expr->ref();
    01942 }
    01943
    01944 bool ExprStatementNode::deref()
    01945 {
    01946   if ( expr && expr->deref() )
    01947     delete expr;
    01948   return StatementNode::deref();
    01949 }
    01950
    01951 // ECMA 12.4
    01952 Completion ExprStatementNode::execute(ExecState *exec)
    01953 {
    01954   KJS_BREAKPOINT;
    01955
    01956   Value v = expr->evaluate(exec);
    01957   KJS_CHECKEXCEPTION
    01958
    01959   return Completion(Normal, v);
    01960 }
    01961
    01962 // ----------------------------- IfNode ---------------------------------------
    01963
    01964 void IfNode::ref()
    01965 {
    01966   StatementNode::ref();
    01967   if ( statement1 )
    01968     statement1->ref();
    01969   if ( statement2 )
    01970     statement2->ref();
    01971   if ( expr )
    01972     expr->ref();
    01973 }
    01974
    01975 bool IfNode::deref()
    01976 {
    01977   if ( statement1 && statement1->deref() )
    01978     delete statement1;
    01979   if ( statement2 && statement2->deref() )
    01980     delete statement2;
    01981   if ( expr && expr->deref() )
    01982     delete expr;
    01983   return StatementNode::deref();
    01984 }
    01985
    01986 // ECMA 12.5
    01987 Completion IfNode::execute(ExecState *exec)
    01988 {
    01989   KJS_BREAKPOINT;
    01990
    01991   assert(expr);
    01992   bool b = expr->toBoolean(exec);
    01993   KJS_CHECKEXCEPTION
    01994
    01995   // if ... then
    01996   if (b)
    01997     return statement1->execute(exec);
    01998
    01999   // no else
    02000   if (!statement2)
    02001     return Completion(Normal);
    02002
    02003   // else
    02004   return statement2->execute(exec);
    02005 }
    02006
    02007 void IfNode::processVarDecls(ExecState *exec)
    02008 {
    02009   statement1->processVarDecls(exec);
    02010
    02011   if (statement2)
    02012     statement2->processVarDecls(exec);
    02013 }
    02014
    02015 // ----------------------------- DoWhileNode ----------------------------------
    02016
    02017 void DoWhileNode::ref()
    02018 {
    02019   StatementNode::ref();
    02020   if ( statement )
    02021     statement->ref();
    02022   if ( expr )
    02023     expr->ref();
    02024 }
    02025
    02026 bool DoWhileNode::deref()
    02027 {
    02028   if ( statement && statement->deref() )
    02029     delete statement;
    02030   if ( expr && expr->deref() )
    02031     delete expr;
    02032   return StatementNode::deref();
    02033 }
    02034
    02035 // ECMA 12.6.1
    02036 Completion DoWhileNode::execute(ExecState *exec)
    02037 {
    02038   KJS_BREAKPOINT;
    02039
    02040   Completion c;
    02041   Value value;
    02042   bool b;
    02043
    02044   do {
    02045     // bail out on error
    02046     KJS_CHECKEXCEPTION
    02047
    02048     exec->context().imp()->seenLabels()->pushIteration();
    02049     c = statement->execute(exec);
    02050     exec->context().imp()->seenLabels()->popIteration();
    02051     if (!((c.complType() == Continue) && ls.contains(c.target()))) {
    02052       if ((c.complType() == Break) && ls.contains(c.target()))
    02053         return Completion(Normal, value);
    02054       if (c.complType() != Normal)
    02055         return c;
    02056     }
    02057     b = expr->toBoolean(exec);
    02058     KJS_CHECKEXCEPTION
    02059   } while (b);
    02060
    02061   return Completion(Normal, value);
    02062 }
    02063
    02064 void DoWhileNode::processVarDecls(ExecState *exec)
    02065 {
    02066   statement->processVarDecls(exec);
    02067 }
    02068
    02069 // ----------------------------- WhileNode ------------------------------------
    02070
    02071 void WhileNode::ref()
    02072 {
    02073   StatementNode::ref();
    02074   if ( statement )
    02075     statement->ref();
    02076   if ( expr )
    02077     expr->ref();
    02078 }
    02079
    02080 bool WhileNode::deref()
    02081 {
    02082   if ( statement && statement->deref() )
    02083     delete statement;
    02084   if ( expr && expr->deref() )
    02085     delete expr;
    02086   return StatementNode::deref();
    02087 }
    02088
    02089 // ECMA 12.6.2
    02090 Completion WhileNode::execute(ExecState *exec)
    02091 {
    02092   KJS_BREAKPOINT;
    02093
    02094   Completion c;
    02095   Value value;
    02096
    02097   while (1) {
    02098     bool b = expr->toBoolean(exec);
    02099     KJS_CHECKEXCEPTION
    02100
    02101     // bail out on error
    02102     KJS_CHECKEXCEPTION
    02103
    02104     if (!b)
    02105       return Completion(Normal, value);
    02106
    02107     exec->context().imp()->seenLabels()->pushIteration();
    02108     c = statement->execute(exec);
    02109     exec->context().imp()->seenLabels()->popIteration();
    02110     if (c.isValueCompletion())
    02111       value = c.value();
    02112
    02113     if ((c.complType() == Continue) && ls.contains(c.target()))
    02114       continue;
    02115     if ((c.complType() == Break) && ls.contains(c.target()))
    02116       return Completion(Normal, value);
    02117     if (c.complType() != Normal)
    02118       return c;
    02119   }
    02120 }
    02121
    02122 void WhileNode::processVarDecls(ExecState *exec)
    02123 {
    02124   statement->processVarDecls(exec);
    02125 }
    02126
    02127 // ----------------------------- ForNode --------------------------------------
    02128
    02129 void ForNode::ref()
    02130 {
    02131   StatementNode::ref();
    02132   if ( statement )
    02133     statement->ref();
    02134   if ( expr1 )
    02135     expr1->ref();
    02136   if ( expr2 )
    02137     expr2->ref();
    02138   if ( expr3 )
    02139     expr3->ref();
    02140 }
    02141
    02142 bool ForNode::deref()
    02143 {
    02144   if ( statement && statement->deref() )
    02145     delete statement;
    02146   if ( expr1 && expr1->deref() )
    02147     delete expr1;
    02148   if ( expr2 && expr2->deref() )
    02149     delete expr2;
    02150   if ( expr3 && expr3->deref() )
    02151     delete expr3;
    02152   return StatementNode::deref();
    02153 }
    02154
    02155 // ECMA 12.6.3
    02156 Completion ForNode::execute(ExecState *exec)
    02157 {
    02158   Value v, cval;
    02159
    02160   if (expr1) {
    02161     v = expr1->evaluate(exec);
    02162     KJS_CHECKEXCEPTION
    02163   }
    02164   for (;;) {
    02165     if (expr2) {
    02166       bool b = expr2->toBoolean(exec);
    02167       KJS_CHECKEXCEPTION
    02168       if (!b)
    02169     return Completion(Normal, cval);
    02170     }
    02171     // bail out on error
    02172     KJS_CHECKEXCEPTION
    02173
    02174     exec->context().imp()->seenLabels()->pushIteration();
    02175     Completion c = statement->execute(exec);
    02176     exec->context().imp()->seenLabels()->popIteration();
    02177     if (c.isValueCompletion())
    02178       cval = c.value();
    02179     if (!((c.complType() == Continue) && ls.contains(c.target()))) {
    02180       if ((c.complType() == Break) && ls.contains(c.target()))
    02181         return Completion(Normal, cval);
    02182       if (c.complType() != Normal)
    02183         return c;
    02184     }
    02185     if (expr3) {
    02186       v = expr3->evaluate(exec);
    02187       KJS_CHECKEXCEPTION
    02188     }
    02189   }
    02190 }
    02191
    02192 void ForNode::processVarDecls(ExecState *exec)
    02193 {
    02194   if (expr1)
    02195     expr1->processVarDecls(exec);
    02196
    02197   statement->processVarDecls(exec);
    02198 }
    02199
    02200 // ----------------------------- ForInNode ------------------------------------
    02201
    02202 ForInNode::ForInNode(Node *l, Node *e, StatementNode *s)
    02203   : init(0L), lexpr(l), expr(e), varDecl(0L), statement(s)
    02204 {
    02205 }
    02206
    02207 ForInNode::ForInNode(const Identifier &i, AssignExprNode *in, Node *e, StatementNode *s)
    02208   : ident(i), init(in), expr(e), statement(s)
    02209 {
    02210   // for( var foo = bar in baz )
    02211   varDecl = new VarDeclNode(ident, init);
    02212   lexpr = new ResolveNode(ident);
    02213 }
    02214
    02215 void ForInNode::ref()
    02216 {
    02217   StatementNode::ref();
    02218   if ( statement )
    02219     statement->ref();
    02220   if ( expr )
    02221     expr->ref();
    02222   if ( lexpr )
    02223     lexpr->ref();
    02224   if ( init )
    02225     init->ref();
    02226   if ( varDecl )
    02227     varDecl->ref();
    02228 }
    02229
    02230 bool ForInNode::deref()
    02231 {
    02232   if ( statement && statement->deref() )
    02233     delete statement;
    02234   if ( expr && expr->deref() )
    02235     delete expr;
    02236   if ( lexpr && lexpr->deref() )
    02237     delete lexpr;
    02238   if ( init && init->deref() )
    02239     delete init;
    02240   if ( varDecl && varDecl->deref() )
    02241     delete varDecl;
    02242   return StatementNode::deref();
    02243 }
    02244
    02245 // ECMA 12.6.4
    02246 Completion ForInNode::execute(ExecState *exec)
    02247 {
    02248   Value retval;
    02249   Completion c;
    02250
    02251   if ( varDecl ) {
    02252     (void)varDecl->evaluate(exec);
    02253     KJS_CHECKEXCEPTION
    02254   }
    02255
    02256   Value v = expr->evaluate(exec);
    02257   // for Null and Undefined, we want to make sure not to go through
    02258   // the loop at all, because their object wrappers will have a
    02259   // property list but will throw an exception if you attempt to
    02260   // access any property.
    02261   if (v.isA(NullType) || v.isA(UndefinedType))
    02262     return Completion(Normal, retval);
    02263
    02264   Object o = v.toObject(exec);
    02265   KJS_CHECKEXCEPTION
    02266   ReferenceList propList = o.propList(exec);
    02267
    02268   ReferenceListIterator propIt = propList.begin();
    02269
    02270   while (propIt != propList.end()) {
    02271     Identifier name = propIt->getPropertyName(exec);
    02272     if (!o.hasProperty(exec,name)) {
    02273       propIt++;
    02274       continue;
    02275     }
    02276
    02277     Reference ref = lexpr->evaluateReference(exec);
    02278     KJS_CHECKEXCEPTION
    02279     ref.putValue(exec, String(name.ustring()));
    02280
    02281     exec->context().imp()->seenLabels()->pushIteration();
    02282     c = statement->execute(exec);
    02283     exec->context().imp()->seenLabels()->popIteration();
    02284     if (c.isValueCompletion())
    02285       retval = c.value();
    02286
    02287     if (!((c.complType() == Continue) && ls.contains(c.target()))) {
    02288       if ((c.complType() == Break) && ls.contains(c.target()))
    02289         break;
    02290       if (c.complType() != Normal) {
    02291         return c;
    02292       }
    02293     }
    02294
    02295     propIt++;
    02296   }
    02297
    02298   // bail out on error
    02299   KJS_CHECKEXCEPTION
    02300
    02301   return Completion(Normal, retval);
    02302 }
    02303
    02304 void ForInNode::processVarDecls(ExecState *exec)
    02305 {
    02306   statement->processVarDecls(exec);
    02307 }
    02308
    02309 // ----------------------------- ContinueNode ---------------------------------
    02310
    02311 // ECMA 12.7
    02312 Completion ContinueNode::execute(ExecState *exec)
    02313 {
    02314   KJS_BREAKPOINT;
    02315
    02316   Value dummy;
    02317
    02318   if (ident.isEmpty() && !exec->context().imp()->seenLabels()->inIteration())
    02319     return Completion(Throw,
    02320               throwError(exec, SyntaxError, "continue used outside of iteration statement"));
    02321   else if (!ident.isEmpty() && !exec->context().imp()->seenLabels()->contains(ident))
    02322     return Completion(Throw,
    02323                       throwError(exec, SyntaxError, "Label %s not found in containing block. Can't continue.", ident));
    02324   else
    02325     return Completion(Continue, dummy, ident);
    02326 }
    02327
    02328 // ----------------------------- BreakNode ------------------------------------
    02329
    02330 // ECMA 12.8
    02331 Completion BreakNode::execute(ExecState *exec)
    02332 {
    02333   KJS_BREAKPOINT;
    02334
    02335   Value dummy;
    02336
    02337   if (ident.isEmpty() && !exec->context().imp()->seenLabels()->inIteration() &&
    02338       !exec->context().imp()->seenLabels()->inSwitch())
    02339     return Completion(Throw,
    02340               throwError(exec, SyntaxError, "break used outside of iteration or switch statement"));
    02341   else if (!ident.isEmpty() && !exec->context().imp()->seenLabels()->contains(ident))
    02342     return Completion(Throw,
    02343                       throwError(exec, SyntaxError, "Label %s not found in containing block. Can't break.", ident));
    02344   else
    02345     return Completion(Break, dummy, ident);
    02346 }
    02347
    02348 // ----------------------------- ReturnNode -----------------------------------
    02349
    02350 void ReturnNode::ref()
    02351 {
    02352   StatementNode::ref();
    02353   if ( value )
    02354     value->ref();
    02355 }
    02356
    02357 bool ReturnNode::deref()
    02358 {
    02359   if ( value && value->deref() )
    02360     delete value;
    02361   return StatementNode::deref();
    02362 }
    02363
    02364 // ECMA 12.9
    02365 Completion ReturnNode::execute(ExecState *exec)
    02366 {
    02367   KJS_BREAKPOINT;
    02368
    02369   if (!value)
    02370     return Completion(ReturnValue, Undefined());
    02371
    02372   Value v = value->evaluate(exec);
    02373   KJS_CHECKEXCEPTION
    02374
    02375   return Completion(ReturnValue, v);
    02376 }
    02377
    02378 // ----------------------------- WithNode -------------------------------------
    02379
    02380 void WithNode::ref()
    02381 {
    02382   StatementNode::ref();
    02383   if ( statement )
    02384     statement->ref();
    02385   if ( expr )
    02386     expr->ref();
    02387 }
    02388
    02389 bool WithNode::deref()
    02390 {
    02391   if ( statement && statement->deref() )
    02392     delete statement;
    02393   if ( expr && expr->deref() )
    02394     delete expr;
    02395   return StatementNode::deref();
    02396 }
    02397
    02398 // ECMA 12.10
    02399 Completion WithNode::execute(ExecState *exec)
    02400 {
    02401   KJS_BREAKPOINT;
    02402
    02403   Value v = expr->evaluate(exec);
    02404   KJS_CHECKEXCEPTION
    02405   Object o = v.toObject(exec);
    02406   KJS_CHECKEXCEPTION
    02407   exec->context().imp()->pushScope(o);
    02408   Completion res = statement->execute(exec);
    02409   exec->context().imp()->popScope();
    02410
    02411   return res;
    02412 }
    02413
    02414 void WithNode::processVarDecls(ExecState *exec)
    02415 {
    02416   statement->processVarDecls(exec);
    02417 }
    02418
    02419 // ----------------------------- CaseClauseNode -------------------------------
    02420
    02421 void CaseClauseNode::ref()
    02422 {
    02423   Node::ref();
    02424   if ( expr )
    02425     expr->ref();
    02426   if ( list )
    02427     list->ref();
    02428 }
    02429
    02430 bool CaseClauseNode::deref()
    02431 {
    02432   if ( expr && expr->deref() )
    02433     delete expr;
    02434   if ( list && list->deref() )
    02435     delete list;
    02436   return Node::deref();
    02437 }
    02438
    02439 // ECMA 12.11
    02440 Value CaseClauseNode::evaluate(ExecState *exec) const
    02441 {
    02442   Value v = expr->evaluate(exec);
    02443   KJS_CHECKEXCEPTIONVALUE
    02444
    02445   return v;
    02446 }
    02447
    02448 // ECMA 12.11
    02449 Completion CaseClauseNode::evalStatements(ExecState *exec) const
    02450 {
    02451   if (list)
    02452     return list->execute(exec);
    02453   else
    02454     return Completion(Normal, Undefined());
    02455 }
    02456
    02457 void CaseClauseNode::processVarDecls(ExecState *exec)
    02458 {
    02459   if (list)
    02460     list->processVarDecls(exec);
    02461 }
    02462
    02463 // ----------------------------- ClauseListNode -------------------------------
    02464
    02465 void ClauseListNode::ref()
    02466 {
    02467   for (ClauseListNode *n = this; n; n = n->nx) {
    02468     n->Node::ref();
    02469     if (n->cl)
    02470       n->cl->ref();
    02471   }
    02472 }
    02473
    02474 bool ClauseListNode::deref()
    02475 {
    02476   ClauseListNode *next;
    02477   for (ClauseListNode *n = this; n; n = next) {
    02478     next = n->nx;
    02479     if (n->cl && n->cl->deref())
    02480       delete n->cl;
    02481     if (n != this && n->Node::deref())
    02482       delete n;
    02483   }
    02484   return Node::deref();
    02485 }
    02486
    02487 Value ClauseListNode::evaluate(ExecState * /*exec*/) const
    02488 {
    02489   /* should never be called */
    02490   assert(false);
    02491   return Value();
    02492 }
    02493
    02494 // ECMA 12.11
    02495 void ClauseListNode::processVarDecls(ExecState *exec)
    02496 {
    02497   for (ClauseListNode *n = this; n; n = n->nx)
    02498     if (n->cl)
    02499       n->cl->processVarDecls(exec);
    02500 }
    02501
    02502 // ----------------------------- CaseBlockNode --------------------------------
    02503
    02504 CaseBlockNode::CaseBlockNode(ClauseListNode *l1, CaseClauseNode *d,
    02505                              ClauseListNode *l2)
    02506 {
    02507   def = d;
    02508   if (l1) {
    02509     list1 = l1->nx;
    02510     l1->nx = 0;
    02511   } else {
    02512     list1 = 0;
    02513   }
    02514   if (l2) {
    02515     list2 = l2->nx;
    02516     l2->nx = 0;
    02517   } else {
    02518     list2 = 0;
    02519   }
    02520 }
    02521
    02522 void CaseBlockNode::ref()
    02523 {
    02524   Node::ref();
    02525   if ( def )
    02526     def->ref();
    02527   if ( list1 )
    02528     list1->ref();
    02529   if ( list2 )
    02530     list2->ref();
    02531 }
    02532
    02533 bool CaseBlockNode::deref()
    02534 {
    02535   if ( def && def->deref() )
    02536     delete def;
    02537   if ( list1 && list1->deref() )
    02538     delete list1;
    02539   if ( list2 && list2->deref() )
    02540     delete list2;
    02541   return Node::deref();
    02542 }
    02543
    02544 Value CaseBlockNode::evaluate(ExecState * /*exec*/) const
    02545 {
    02546   /* should never be called */
    02547   assert(false);
    02548   return Value();
    02549 }
    02550
    02551 // ECMA 12.11
    02552 Completion CaseBlockNode::evalBlock(ExecState *exec, const Value& input) const
    02553 {
    02554   Value v;
    02555   Completion res;
    02556   ClauseListNode *a = list1, *b = list2;
    02557   CaseClauseNode *clause;
    02558
    02559     while (a) {
    02560       clause = a->clause();
    02561       a = a->next();
    02562       v = clause->evaluate(exec);
    02563       KJS_CHECKEXCEPTION
    02564       if (strictEqual(exec, input, v)) {
    02565     res = clause->evalStatements(exec);
    02566     if (res.complType() != Normal)
    02567       return res;
    02568     while (a) {
    02569       res = a->clause()->evalStatements(exec);
    02570       if (res.complType() != Normal)
    02571         return res;
    02572       a = a->next();
    02573     }
    02574     break;
    02575       }
    02576     }
    02577
    02578   while (b) {
    02579     clause = b->clause();
    02580     b = b->next();
    02581     v = clause->evaluate(exec);
    02582     KJS_CHECKEXCEPTION
    02583     if (strictEqual(exec, input, v)) {
    02584       res = clause->evalStatements(exec);
    02585       if (res.complType() != Normal)
    02586     return res;
    02587       goto step18;
    02588     }
    02589   }
    02590
    02591   // default clause
    02592   if (def) {
    02593     res = def->evalStatements(exec);
    02594     if (res.complType() != Normal)
    02595       return res;
    02596   }
    02597   b = list2;
    02598  step18:
    02599   while (b) {
    02600     clause = b->clause();
    02601     res = clause->evalStatements(exec);
    02602     if (res.complType() != Normal)
    02603       return res;
    02604     b = b->next();
    02605   }
    02606
    02607   // bail out on error
    02608   KJS_CHECKEXCEPTION
    02609
    02610   return Completion(Normal);
    02611 }
    02612
    02613 void CaseBlockNode::processVarDecls(ExecState *exec)
    02614 {
    02615   if (list1)
    02616     list1->processVarDecls(exec);
    02617   if (def)
    02618     def->processVarDecls(exec);
    02619   if (list2)
    02620     list2->processVarDecls(exec);
    02621 }
    02622
    02623 // ----------------------------- SwitchNode -----------------------------------
    02624
    02625 void SwitchNode::ref()
    02626 {
    02627   StatementNode::ref();
    02628   if ( expr )
    02629     expr->ref();
    02630   if ( block )
    02631     block->ref();
    02632 }
    02633
    02634 bool SwitchNode::deref()
    02635 {
    02636   if ( expr && expr->deref() )
    02637     delete expr;
    02638   if ( block && block->deref() )
    02639     delete block;
    02640   return StatementNode::deref();
    02641 }
    02642
    02643 // ECMA 12.11
    02644 Completion SwitchNode::execute(ExecState *exec)
    02645 {
    02646   KJS_BREAKPOINT;
    02647
    02648   Value v = expr->evaluate(exec);
    02649   KJS_CHECKEXCEPTION
    02650   exec->context().imp()->seenLabels()->pushSwitch();
    02651   Completion res = block->evalBlock(exec,v);
    02652   exec->context().imp()->seenLabels()->popSwitch();
    02653
    02654   if ((res.complType() == Break) && ls.contains(res.target()))
    02655     return Completion(Normal, res.value());
    02656   else
    02657     return res;
    02658 }
    02659
    02660 void SwitchNode::processVarDecls(ExecState *exec)
    02661 {
    02662   block->processVarDecls(exec);
    02663 }
    02664
    02665 // ----------------------------- LabelNode ------------------------------------
    02666
    02667 void LabelNode::ref()
    02668 {
    02669   StatementNode::ref();
    02670   if ( statement )
    02671     statement->ref();
    02672 }
    02673
    02674 bool LabelNode::deref()
    02675 {
    02676   if ( statement && statement->deref() )
    02677     delete statement;
    02678   return StatementNode::deref();
    02679 }
    02680
    02681 // ECMA 12.12
    02682 Completion LabelNode::execute(ExecState *exec)
    02683 {
    02684   Completion e;
    02685
    02686   if (!exec->context().imp()->seenLabels()->push(label)) {
    02687     return Completion( Throw,
    02688                        throwError(exec, SyntaxError, "Duplicated label %s found.", label));
    02689   };
    02690   e = statement->execute(exec);
    02691   exec->context().imp()->seenLabels()->pop();
    02692
    02693   if ((e.complType() == Break) && (e.target() == label))
    02694     return Completion(Normal, e.value());
    02695   else
    02696     return e;
    02697 }
    02698
    02699 void LabelNode::processVarDecls(ExecState *exec)
    02700 {
    02701   statement->processVarDecls(exec);
    02702 }
    02703
    02704 // ----------------------------- ThrowNode ------------------------------------
    02705
    02706 void ThrowNode::ref()
    02707 {
    02708   StatementNode::ref();
    02709   if ( expr )
    02710     expr->ref();
    02711 }
    02712
    02713 bool ThrowNode::deref()
    02714 {
    02715   if ( expr && expr->deref() )
    02716     delete expr;
    02717   return StatementNode::deref();
    02718 }
    02719
    02720 // ECMA 12.13
    02721 Completion ThrowNode::execute(ExecState *exec)
    02722 {
    02723   KJS_BREAKPOINT;
    02724
    02725   Value v = expr->evaluate(exec);
    02726   KJS_CHECKEXCEPTION
    02727
    02728   // bail out on error
    02729   KJS_CHECKEXCEPTION
    02730
    02731   Debugger *dbg = exec->interpreter()->imp()->debugger();
    02732   if (dbg)
    02733     dbg->exception(exec,v,exec->context().imp()->inTryCatch());
    02734
    02735   return Completion(Throw, v);
    02736 }
    02737
    02738 // ----------------------------- CatchNode ------------------------------------
    02739
    02740 void CatchNode::ref()
    02741 {
    02742   StatementNode::ref();
    02743   if ( block )
    02744     block->ref();
    02745 }
    02746
    02747 bool CatchNode::deref()
    02748 {
    02749   if ( block && block->deref() )
    02750     delete block;
    02751   return StatementNode::deref();
    02752 }
    02753
    02754 Completion CatchNode::execute(ExecState * /*exec*/)
    02755 {
    02756   // should never be reached. execute(exec, arg) is used instead
    02757   assert(0L);
    02758   return Completion();
    02759 }
    02760
    02761 // ECMA 12.14
    02762 Completion CatchNode::execute(ExecState *exec, const Value &arg)
    02763 {
    02764   /* TODO: correct ? Not part of the spec */
    02765
    02766   exec->clearException();
    02767
    02768   Object obj(new ObjectImp());
    02769   obj.put(exec, ident, arg, DontDelete);
    02770   exec->context().imp()->pushScope(obj);
    02771   Completion c = block->execute(exec);
    02772   exec->context().imp()->popScope();
    02773
    02774   return c;
    02775 }
    02776
    02777 void CatchNode::processVarDecls(ExecState *exec)
    02778 {
    02779   block->processVarDecls(exec);
    02780 }
    02781
    02782 // ----------------------------- FinallyNode ----------------------------------
    02783
    02784 void FinallyNode::ref()
    02785 {
    02786   StatementNode::ref();
    02787   if ( block )
    02788     block->ref();
    02789 }
    02790
    02791 bool FinallyNode::deref()
    02792 {
    02793   if ( block && block->deref() )
    02794     delete block;
    02795   return StatementNode::deref();
    02796 }
    02797
    02798 // ECMA 12.14
    02799 Completion FinallyNode::execute(ExecState *exec)
    02800 {
    02801   return block->execute(exec);
    02802 }
    02803
    02804 void FinallyNode::processVarDecls(ExecState *exec)
    02805 {
    02806   block->processVarDecls(exec);
    02807 }
    02808
    02809 // ----------------------------- TryNode --------------------------------------
    02810
    02811 void TryNode::ref()
    02812 {
    02813   StatementNode::ref();
    02814   if ( block )
    02815     block->ref();
    02816   if ( _final )
    02817     _final->ref();
    02818   if ( _catch )
    02819     _catch->ref();
    02820 }
    02821
    02822 bool TryNode::deref()
    02823 {
    02824   if ( block && block->deref() )
    02825     delete block;
    02826   if ( _final && _final->deref() )
    02827     delete _final;
    02828   if ( _catch && _catch->deref() )
    02829     delete _catch;
    02830   return StatementNode::deref();
    02831 }
    02832
    02833 // ECMA 12.14
    02834 Completion TryNode::execute(ExecState *exec)
    02835 {
    02836   KJS_BREAKPOINT;
    02837
    02838   Completion c, c2;
    02839
    02840   if (_catch)
    02841     exec->context().imp()->pushTryCatch();
    02842   c = block->execute(exec);
    02843   if (_catch)
    02844     exec->context().imp()->popTryCatch();
    02845
    02846   if (!_final) {
    02847     if (c.complType() != Throw)
    02848       return c;
    02849     return _catch->execute(exec,c.value());
    02850   }
    02851
    02852   if (!_catch) {
    02853     Value exception = exec->_exception;
    02854     exec->_exception = Value();
    02855
    02856     c2 = _final->execute(exec);
    02857
    02858     if (!exec->hadException() && c2.complType() != Throw)
    02859       exec->_exception = exception;
    02860
    02861     return (c2.complType() == Normal) ? c : c2;
    02862   }
    02863
    02864   if (c.complType() == Throw)
    02865     c = _catch->execute(exec,c.value());
    02866
    02867   c2 = _final->execute(exec);
    02868   return (c2.complType() == Normal) ? c : c2;
    02869 }
    02870
    02871 void TryNode::processVarDecls(ExecState *exec)
    02872 {
    02873   block->processVarDecls(exec);
    02874   if (_final)
    02875     _final->processVarDecls(exec);
    02876   if (_catch)
    02877     _catch->processVarDecls(exec);
    02878 }
    02879
    02880 // ----------------------------- ParameterNode --------------------------------
    02881
    02882 void ParameterNode::ref()
    02883 {
    02884   for (ParameterNode *n = this; n; n = n->next)
    02885     n->Node::ref();
    02886 }
    02887
    02888 bool ParameterNode::deref()
    02889 {
    02890   ParameterNode *next;
    02891   for (ParameterNode *n = this; n; n = next) {
    02892     next = n->next;
    02893     if (n != this && n->Node::deref())
    02894       delete n;
    02895   }
    02896   return Node::deref();
    02897 }
    02898
    02899 // ECMA 13
    02900 Value ParameterNode::evaluate(ExecState * /*exec*/) const
    02901 {
    02902   return Undefined();
    02903 }
    02904
    02905 // ----------------------------- FunctionBodyNode -----------------------------
    02906
    02907
    02908 FunctionBodyNode::FunctionBodyNode(SourceElementsNode *s)
    02909   : BlockNode(s), program(false)
    02910 {
    02911   //fprintf(stderr,"FunctionBodyNode::FunctionBodyNode %p\n",this);
    02912 }
    02913
    02914 void FunctionBodyNode::processFuncDecl(ExecState *exec)
    02915 {
    02916   if (source)
    02917     source->processFuncDecl(exec);
    02918 }
    02919
    02920 Completion FunctionBodyNode::execute(ExecState *exec)
    02921 {
    02922   Completion c = BlockNode::execute(exec);
    02923   if (program && c.complType() == ReturnValue)
    02924     return Completion(Throw,
    02925               throwError(exec, SyntaxError, "return outside of function body"));
    02926   else
    02927     return c;
    02928 }
    02929
    02930 // ----------------------------- FuncDeclNode ---------------------------------
    02931
    02932 void FuncDeclNode::ref()
    02933 {
    02934   StatementNode::ref();
    02935   if ( param )
    02936     param->ref();
    02937   if ( body )
    02938     body->ref();
    02939 }
    02940
    02941 bool FuncDeclNode::deref()
    02942 {
    02943   if ( param && param->deref() )
    02944     delete param;
    02945   if ( body && body->deref() )
    02946     delete body;
    02947   return StatementNode::deref();
    02948 }
    02949
    02950 // ECMA 13
    02951 void FuncDeclNode::processFuncDecl(ExecState *exec)
    02952 {
    02953   ContextImp *ctx = exec->context().imp();
    02954   // TODO: let this be an object with [[Class]] property "Function"
    02955   FunctionImp *fimp = new DeclaredFunctionImp(exec, ident, body, exec->context().imp()->scopeChain());
    02956   Object func(fimp); // protect from GC
    02957
    02958   //  Value proto = exec->interpreter()->builtinObject().construct(exec,List::empty());
    02959   List empty;
    02960   Object proto = exec->interpreter()->builtinObject().construct(exec,empty);
    02961   proto.put(exec, constructorPropertyName, func, ReadOnly|DontDelete|DontEnum);
    02962   func.put(exec, prototypePropertyName, proto, Internal|DontDelete);
    02963
    02964   int plen = 0;
    02965   for(const ParameterNode *p = param; p != 0L; p = p->nextParam(), plen++)
    02966     fimp->addParameter(p->ident());
    02967
    02968   func.put(exec, lengthPropertyName, Number(plen), ReadOnly|DontDelete|DontEnum);
    02969
    02970 #ifdef KJS_VERBOSE
    02971   fprintf(stderr,"KJS: new function %s in %p\n", ident.ustring().cstring().c_str(), ctx->variableObject().imp());
    02972 #endif
    02973   if (exec->_context->type() == EvalCode)
    02974     ctx->variableObject().put(exec,ident,func,Internal);
    02975   else
    02976     ctx->variableObject().put(exec,ident,func,DontDelete|Internal);
    02977
    02978   if (body) {
    02979     // hack the scope so that the function gets put as a property of func, and it's scope
    02980     // contains the func as well as our current scope
    02981     Object oldVar = ctx->variableObject();
    02982     ctx->setVariableObject(func);
    02983     ctx->pushScope(func);
    02984     body->processFuncDecl(exec);
    02985     ctx->popScope();
    02986     ctx->setVariableObject(oldVar);
    02987   }
    02988 }
    02989
    02990 // ----------------------------- FuncExprNode ---------------------------------
    02991
    02992 void FuncExprNode::ref()
    02993 {
    02994   Node::ref();
    02995   if ( param )
    02996     param->ref();
    02997   if ( body )
    02998     body->ref();
    02999 }
    03000
    03001 bool FuncExprNode::deref()
    03002 {
    03003   if ( param && param->deref() )
    03004     delete param;
    03005   if ( body && body->deref() )
    03006     delete body;
    03007   return Node::deref();
    03008 }
    03009
    03010
    03011 // ECMA 13
    03012 Value FuncExprNode::evaluate(ExecState *exec) const
    03013 {
    03014   FunctionImp *fimp = new DeclaredFunctionImp(exec, Identifier::null(), body, exec->context().imp()->scopeChain());
    03015   Value ret(fimp);
    03016   List empty;
    03017   Value proto = exec->interpreter()->builtinObject().construct(exec,empty);
    03018   fimp->put(exec, prototypePropertyName, proto, Internal|DontDelete);
    03019
    03020   for(const ParameterNode *p = param; p != 0L; p = p->nextParam())
    03021     fimp->addParameter(p->ident());
    03022
    03023   return ret;
    03024 }
    03025
    03026 // ----------------------------- SourceElementsNode ---------------------------
    03027
    03028 SourceElementsNode::SourceElementsNode(StatementNode *s1)
    03029 {
    03030   element = s1;
    03031   elements = this;
    03032   setLoc(s1->firstLine(),s1->lastLine(),s1->code());
    03033 }
    03034
    03035 SourceElementsNode::SourceElementsNode(SourceElementsNode *s1, StatementNode *s2)
    03036 {
    03037   elements = s1->elements;
    03038   s1->elements = this;
    03039   element = s2;
    03040   setLoc(s1->firstLine(),s2->lastLine(),s1->code());
    03041 }
    03042
    03043 void SourceElementsNode::ref()
    03044 {
    03045   for (SourceElementsNode *n = this; n; n = n->elements) {
    03046     n->Node::ref();
    03047     if (n->element)
    03048       n->element->ref();
    03049   }
    03050 }
    03051
    03052 bool SourceElementsNode::deref()
    03053 {
    03054   SourceElementsNode *next;
    03055   for (SourceElementsNode *n = this; n; n = next) {
    03056     next = n->elements;
    03057     if (n->element && n->element->deref())
    03058       delete n->element;
    03059     if (n != this && n->Node::deref())
    03060       delete n;
    03061   }
    03062   return StatementNode::deref();
    03063 }
    03064
    03065 // ECMA 14
    03066 Completion SourceElementsNode::execute(ExecState *exec)
    03067 {
    03068   KJS_CHECKEXCEPTION
    03069
    03070   Completion c1 = element->execute(exec);
    03071   KJS_CHECKEXCEPTION;
    03072   if (c1.complType() != Normal)
    03073     return c1;
    03074
    03075   for (SourceElementsNode *node = elements; node; node = node->elements) {
    03076     Completion c2 = node->element->execute(exec);
    03077     if (c2.complType() != Normal)
    03078       return c2;
    03079     // The spec says to return c2 here, but it seems that mozilla returns c1 if
    03080     // c2 doesn't have a value
    03081     if (c2.value().isValid())
    03082       c1 = c2;
    03083   }
    03084
    03085   return c1;
    03086 }
    03087
    03088 // ECMA 14
    03089 void SourceElementsNode::processFuncDecl(ExecState *exec)
    03090 {
    03091   for (SourceElementsNode *n = this; n; n = n->elements)
    03092     n->element->processFuncDecl(exec);
    03093 }
    03094
    03095 void SourceElementsNode::processVarDecls(ExecState *exec)
    03096 {
    03097   for (SourceElementsNode *n = this; n; n = n->elements)
    03098     n->element->processVarDecls(exec);
    03099 }

This file is part of the documentation for kjs Library Version 3.4.1.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Sat Jun 11 20:23:07 2005 by doxygen 1.4.1 written by Dimitri van Heesch, © 1997-2003