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