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