kjs Library API Documentation

nodes.cpp

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