nodes.cpp

00001 // -*- c-basic-offset: 2 -*-
00002 /*
00003  *  This file is part of the KDE libraries
00004  *  Copyright (C) 1999-2002, 2003 Harri Porten (porten@kde.org)
00005  *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
00006  *  Copyright (C) 2003 Apple Computer, Inc.
00007  *
00008  *  This library is free software; you can redistribute it and/or
00009  *  modify it under the terms of the GNU Library General Public
00010  *  License as published by the Free Software Foundation; either
00011  *  version 2 of the License, or (at your option) any later version.
00012  *
00013  *  This library is distributed in the hope that it will be useful,
00014  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00016  *  Library General Public License for more details.
00017  *
00018  *  You should have received a copy of the GNU Library General Public License
00019  *  along with this library; see the file COPYING.LIB.  If not, write to
00020  *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00021  *  Boston, MA 02110-1301, USA.
00022  *
00023  */
00024 
00025 #include "nodes.h"
00026 
00027 #include <math.h>
00028 #include <assert.h>
00029 #ifdef KJS_DEBUG_MEM
00030 #include <stdio.h>
00031 #include <typeinfo>
00032 #endif
00033 #ifdef KJS_VERBOSE
00034 #include <iostream>
00035 using namespace std;
00036 #endif
00037 
00038 #include "collector.h"
00039 #include "context.h"
00040 #include "debugger.h"
00041 #include "function_object.h"
00042 #include "internal.h"
00043 #include "value.h"
00044 #include "object.h"
00045 #include "types.h"
00046 #include "interpreter.h"
00047 #include "lexer.h"
00048 #include "operations.h"
00049 #include "ustring.h"
00050 
00051 using namespace KJS;
00052 
00053 #define KJS_BREAKPOINT \
00054   if (!hitStatement(exec)) \
00055     return Completion(Normal);
00056 
00057 #define KJS_ABORTPOINT \
00058   if (exec->dynamicInterpreter()->imp()->debugger() && \
00059       exec->dynamicInterpreter()->imp()->debugger()->imp()->aborted()) \
00060     return Completion(Normal);
00061 
00062 #define KJS_CHECKEXCEPTION \
00063   if (exec->hadException()) { \
00064     setExceptionDetailsIfNeeded(exec); \
00065     return Completion(Throw, exec->exception()); \
00066   } \
00067   if (Collector::outOfMemory()) \
00068     return Completion(Throw, Error::create(exec,GeneralError,"Out of memory"));
00069 
00070 #define KJS_CHECKEXCEPTIONVALUE \
00071   if (exec->hadException()) { \
00072     setExceptionDetailsIfNeeded(exec); \
00073     return exec->exception(); \
00074   } \
00075   if (Collector::outOfMemory()) \
00076     return Undefined(); // will be picked up by KJS_CHECKEXCEPTION
00077 
00078 #define KJS_CHECKEXCEPTIONREFERENCE \
00079   if (exec->hadException()) { \
00080     setExceptionDetailsIfNeeded(exec); \
00081     return Reference::makeValueReference(Undefined()); \
00082   } \
00083   if (Collector::outOfMemory()) \
00084     return Reference::makeValueReference(Undefined()); // will be picked up by KJS_CHECKEXCEPTION
00085 
00086 #define KJS_CHECKEXCEPTIONLIST \
00087   if (exec->hadException()) { \
00088     setExceptionDetailsIfNeeded(exec); \
00089     return List(); \
00090   } \
00091   if (Collector::outOfMemory()) \
00092     return List(); // will be picked up by KJS_CHECKEXCEPTION
00093 
00094 #ifdef KJS_DEBUG_MEM
00095 std::list<Node *> * Node::s_nodes = 0L;
00096 #endif
00097 
00098 // ----------------------------- Node -----------------------------------------
00099 
00100 Node::Node()
00101 {
00102   line = Lexer::curr()->lineNo();
00103   refcount = 0;
00104 #ifdef KJS_DEBUG_MEM
00105   if (!s_nodes)
00106     s_nodes = new std::list<Node *>;
00107   s_nodes->push_back(this);
00108 #endif
00109 }
00110 
00111 Node::~Node()
00112 {
00113 #ifdef KJS_DEBUG_MEM
00114   s_nodes->remove( this );
00115 #endif
00116 }
00117 
00118 Reference Node::evaluateReference(ExecState *exec) const
00119 {
00120   Value v = evaluate(exec);
00121   KJS_CHECKEXCEPTIONREFERENCE
00122   return Reference::makeValueReference(v);
00123 }
00124 
00125 // fallback for those nodes without a evaluate() reimplementation
00126 // TODO: reimplemint in each sub class, make Node::evaluate() pure virtual
00127 Value Node::evaluate(ExecState *exec) const
00128 {
00129   //  fprintf(stderr, "%s::evaluate()\n", typeid(*this).name());
00130   return evaluateReference(exec).getValue(exec);
00131 }
00132 
00133 bool Node::toBoolean(ExecState *exec) const
00134 {
00135 //   fprintf(stderr, "Node(%s)::toBoolean()\n", typeid(*this).name());
00136   return evaluate(exec).toBoolean(exec);
00137 }
00138 
00139 double Node::toNumber(ExecState *exec) const
00140 {
00141 //   fprintf(stderr, "Node(%s)::toNumber()\n", typeid(*this).name());
00142   return evaluate(exec).toNumber(exec);
00143 }
00144 
00145 UString Node::toString(ExecState *exec) const
00146 {
00147   return evaluate(exec).toString(exec);
00148 }
00149 
00150 #ifdef KJS_DEBUG_MEM
00151 void Node::finalCheck()
00152 {
00153   if (!s_nodes) {
00154       fprintf(stderr, "Node::finalCheck(): list 0\n");
00155       return;
00156   }
00157   fprintf( stderr, "Node::finalCheck(): list count       : %d\n", (int)s_nodes->size() );
00158   std::list<Node *>::iterator it = s_nodes->begin();
00159   for ( uint i = 0; it != s_nodes->end() ; ++it, ++i )
00160     fprintf( stderr, "[%d] Still having node %p (%s) (refcount %d)\n", i, (void*)*it, typeid( **it ).name(), (*it)->refcount );
00161   delete s_nodes;
00162   s_nodes = 0L;
00163 }
00164 #endif
00165 
00166 Value Node::throwError(ExecState *exec, ErrorType e, const char *msg) const
00167 {
00168   Object err = Error::create(exec, e, msg, lineNo(), sourceId());
00169   exec->setException(err);
00170   return err;
00171 }
00172 
00173 Value Node::throwError(ExecState *exec, ErrorType e, const char *msg,
00174                        const Value &v, const Node *expr) const
00175 {
00176   char *vStr = strdup(v.toString(exec).ascii());
00177   char *exprStr = strdup(expr->toCode().ascii());
00178 
00179   int length =  strlen(msg) - 4 /* two %s */ + strlen(vStr) + strlen(exprStr) + 1 /* null terminator */;
00180   char *str = new char[length];
00181   sprintf(str, msg, vStr, exprStr);
00182   free(vStr);
00183   free(exprStr);
00184 
00185   Value result = throwError(exec, e, str);
00186   delete [] str;
00187 
00188   return result;
00189 }
00190 
00191 Value Node::throwError(ExecState *exec, ErrorType e, const char *msg, Identifier label) const
00192 {
00193   const char *l = label.ascii();
00194   int length = strlen(msg) - 2 /* %s */ + strlen(l) + 1 /* null terminator */;
00195   char *message = new char[length];
00196   sprintf(message, msg, l);
00197 
00198   Value result = throwError(exec, e, message);
00199   delete [] message;
00200 
00201   return result;
00202 }
00203 
00204 
00205 void Node::setExceptionDetailsIfNeeded(ExecState *exec) const
00206 {
00207     if (exec->hadException()) {
00208         Object exception = exec->exception().toObject(exec);
00209         if (!exception.hasProperty(exec, "line") /* &&
00210             !exception.hasProperty(exec, "sourceURL")*/ ) {
00211             exception.put(exec, "line", Number(line));
00212 //             exception.put(exec, "sourceURL", String(sourceURL));
00213         }
00214     }
00215 }
00216 
00217 // ----------------------------- StatementNode --------------------------------
00218 StatementNode::StatementNode() : l0(-1), l1(-1), sourceCode(0), breakPoint(false)
00219 {
00220 }
00221 
00222 StatementNode::~StatementNode()
00223 {
00224   if (sourceCode)
00225     sourceCode->deref();
00226 }
00227 
00228 void StatementNode::setLoc(int line0, int line1, SourceCode *src)
00229 {
00230   // ### require these to be passed to the constructor
00231   l0 = line0;
00232   l1 = line1;
00233   if (sourceCode != src) {
00234     if (sourceCode)
00235       sourceCode->deref();
00236     sourceCode = src;
00237     sourceCode->ref();
00238   }
00239 }
00240 
00241 // return true if the debugger wants us to stop at this point
00242 bool StatementNode::hitStatement(ExecState *exec)
00243 {
00244   assert(sourceCode);
00245   assert(exec->context().imp()->sourceId == sourceCode->sid);
00246   exec->context().imp()->setLines(l0,l1);
00247   Debugger *dbg = exec->dynamicInterpreter()->imp()->debugger();
00248   if (dbg)
00249     return dbg->atStatement(exec);
00250   else
00251     return true; // continue
00252 }
00253 
00254 // return true if the debugger wants us to stop at this point
00255 bool StatementNode::abortStatement(ExecState *exec)
00256 {
00257   Debugger *dbg = exec->dynamicInterpreter()->imp()->debugger();
00258   if (dbg)
00259     return dbg->imp()->aborted();
00260   else
00261     return false;
00262 }
00263 
00264 void StatementNode::processFuncDecl(ExecState *)
00265 {
00266 }
00267 
00268 // ----------------------------- NullNode -------------------------------------
00269 
00270 Value NullNode::evaluate(ExecState *) const
00271 {
00272   return Null();
00273 }
00274 
00275 bool NullNode::toBoolean(ExecState *) const
00276 {
00277   return false;
00278 }
00279 
00280 double NullNode::toNumber(ExecState *) const
00281 {
00282   return 0.0;
00283 }
00284 
00285 UString NullNode::toString(ExecState *) const
00286 {
00287   return "null";
00288 }
00289 
00290 // ----------------------------- BooleanNode ----------------------------------
00291 
00292 Value BooleanNode::evaluate(ExecState *) const
00293 {
00294   return Boolean(val);
00295 }
00296 
00297 bool BooleanNode::toBoolean(ExecState *) const
00298 {
00299   return val;
00300 }
00301 
00302 double BooleanNode::toNumber(ExecState *) const
00303 {
00304   return val ? 1.0 : 0.0;
00305 }
00306 
00307 UString BooleanNode::toString(ExecState *) const
00308 {
00309   return val ? "true" : "false";
00310 }
00311 
00312 // ----------------------------- NumberNode -----------------------------------
00313 
00314 Value NumberNode::evaluate(ExecState *) const
00315 {
00316   return Number(val);
00317 }
00318 
00319 bool NumberNode::toBoolean(ExecState *) const
00320 {
00321   return !((val == 0) /* || (iVal() == N0) */ || isNaN(val));
00322 }
00323 
00324 double NumberNode::toNumber(ExecState *) const
00325 {
00326   return val;
00327 }
00328 
00329 UString NumberNode::toString(ExecState *) const
00330 {
00331   return UString::from(val);
00332 }
00333 
00334 // ----------------------------- StringNode -----------------------------------
00335 
00336 Value StringNode::evaluate(ExecState *) const
00337 {
00338   return String(val);
00339 }
00340 
00341 bool StringNode::toBoolean(ExecState *) const
00342 {
00343   return !val.isEmpty();
00344 }
00345 
00346 double StringNode::toNumber(ExecState *) const
00347 {
00348   return val.toDouble();
00349 }
00350 
00351 UString StringNode::toString(ExecState *) const
00352 {
00353   return val;
00354 }
00355 
00356 // ----------------------------- RegExpNode -----------------------------------
00357 
00358 Value RegExpNode::evaluate(ExecState *exec) const
00359 {
00360   List list;
00361   String p(pattern);
00362   String f(flags);
00363   list.append(p);
00364   list.append(f);
00365 
00366   Object reg = exec->lexicalInterpreter()->imp()->builtinRegExp();
00367   return reg.construct(exec,list);
00368 }
00369 
00370 bool RegExpNode::toBoolean(ExecState *) const
00371 {
00372   return true;
00373 }
00374 
00375 // ----------------------------- ThisNode -------------------------------------
00376 
00377 // ECMA 11.1.1
00378 Value ThisNode::evaluate(ExecState *exec) const
00379 {
00380   return exec->context().imp()->thisValue();
00381 }
00382 
00383 // ----------------------------- ResolveNode ----------------------------------
00384 
00385 // ECMA 11.1.2 & 10.1.4
00386 Value ResolveNode::evaluate(ExecState *exec) const
00387 {
00388   return evaluateReference(exec).getValue(exec);
00389 }
00390 
00391 Reference ResolveNode::evaluateReference(ExecState *exec) const
00392 {
00393   ScopeChain chain = exec->context().imp()->scopeChain();
00394 
00395   while (!chain.isEmpty()) {
00396     ObjectImp *o = chain.top();
00397 
00398     //cerr << "Resolve: looking at '" << ident.ascii() << "'"
00399     //     << " in " << (void*)o << " " << o->classInfo()->className << endl;
00400     if (o->hasProperty(exec,ident)) {
00401       //cerr << "Resolve: FOUND '" << ident.ascii() << "'"
00402       //     << " in " << (void*)o << " " << o->classInfo()->className << endl;
00403       return Reference(o, ident);
00404     }
00405 
00406     chain.pop();
00407   }
00408 
00409   // identifier not found
00410 #ifdef KJS_VERBOSE
00411   cerr << "Resolve::evaluateReference: didn't find '" << ident.ustring().ascii() << "'" << endl;
00412 #endif
00413   return Reference(Null(), ident);
00414 }
00415 
00416 // ----------------------------- GroupNode ------------------------------------
00417 
00418 void GroupNode::ref()
00419 {
00420   Node::ref();
00421   if ( group )
00422     group->ref();
00423 }
00424 
00425 bool GroupNode::deref()
00426 {
00427   if ( group && group->deref() )
00428     delete group;
00429   return Node::deref();
00430 }
00431 
00432 // ECMA 11.1.6
00433 Value GroupNode::evaluate(ExecState *exec) const
00434 {
00435   return group->evaluate(exec);
00436 }
00437 
00438 Reference GroupNode::evaluateReference(ExecState *exec) const
00439 {
00440   return group->evaluateReference(exec);
00441 }
00442 
00443 // ----------------------------- ElementNode ----------------------------------
00444 
00445 void ElementNode::ref()
00446 {
00447   for (ElementNode *n = this; n; n = n->list) {
00448     n->Node::ref();
00449     if (n->node)
00450       n->node->ref();
00451   }
00452 }
00453 
00454 bool ElementNode::deref()
00455 {
00456   ElementNode *next;
00457   for (ElementNode *n = this; n; n = next) {
00458     next = n->list;
00459     if (n->node && n->node->deref())
00460       delete n->node;
00461     if (n != this && n->Node::deref())
00462       delete n;
00463   }
00464   return Node::deref();
00465 }
00466 
00467 // ECMA 11.1.4
00468 Value ElementNode::evaluate(ExecState *exec) const
00469 {
00470   Object array = exec->lexicalInterpreter()->builtinArray().construct(exec, List::empty());
00471   int length = 0;
00472   for (const ElementNode *n = this; n; n = n->list) {
00473     Value val = n->node->evaluate(exec);
00474     KJS_CHECKEXCEPTIONVALUE
00475     length += n->elision;
00476     array.put(exec, length++, val);
00477   }
00478   return array;
00479 }
00480 
00481 // ----------------------------- ArrayNode ------------------------------------
00482 
00483 void ArrayNode::ref()
00484 {
00485   Node::ref();
00486   if ( element )
00487     element->ref();
00488 }
00489 
00490 bool ArrayNode::deref()
00491 {
00492   if ( element && element->deref() )
00493     delete element;
00494   return Node::deref();
00495 }
00496 
00497 // ECMA 11.1.4
00498 Value ArrayNode::evaluate(ExecState *exec) const
00499 {
00500   Object array;
00501   int length;
00502 
00503   if (element) {
00504     array = Object(static_cast<ObjectImp*>(element->evaluate(exec).imp()));
00505     KJS_CHECKEXCEPTIONVALUE
00506     length = opt ? array.get(exec,lengthPropertyName).toInt32(exec) : 0;
00507   } else {
00508     Value newArr = exec->lexicalInterpreter()->builtinArray().construct(exec,List::empty());
00509     array = Object(static_cast<ObjectImp*>(newArr.imp()));
00510     length = 0;
00511   }
00512 
00513   if (opt)
00514     array.put(exec,lengthPropertyName, Number(elision + length), DontEnum | DontDelete);
00515 
00516   return array;
00517 }
00518 
00519 // ----------------------------- ObjectLiteralNode ----------------------------
00520 
00521 void ObjectLiteralNode::ref()
00522 {
00523   Node::ref();
00524   if ( list )
00525     list->ref();
00526 }
00527 
00528 bool ObjectLiteralNode::deref()
00529 {
00530   if ( list && list->deref() )
00531     delete list;
00532   return Node::deref();
00533 }
00534 
00535 // ECMA 11.1.5
00536 Value ObjectLiteralNode::evaluate(ExecState *exec) const
00537 {
00538   if (list)
00539     return list->evaluate(exec);
00540 
00541   return exec->lexicalInterpreter()->builtinObject().construct(exec,List::empty());
00542 }
00543 
00544 // ----------------------------- PropertyValueNode ----------------------------
00545 
00546 void PropertyValueNode::ref()
00547 {
00548   for (PropertyValueNode *n = this; n; n = n->list) {
00549     n->Node::ref();
00550     if (n->name)
00551       n->name->ref();
00552     if (n->assign)
00553       n->assign->ref();
00554   }
00555 }
00556 
00557 bool PropertyValueNode::deref()
00558 {
00559   PropertyValueNode *next;
00560   for (PropertyValueNode *n = this; n; n = next) {
00561     next = n->list;
00562     if ( n->name && n->name->deref() )
00563       delete n->name;
00564     if ( n->assign && n->assign->deref() )
00565       delete n->assign;
00566     if (n != this && n->Node::deref() )
00567       delete n;
00568   }
00569   return Node::deref();
00570 }
00571 
00572 // ECMA 11.1.5
00573 Value PropertyValueNode::evaluate(ExecState *exec) const
00574 {
00575   Object obj = exec->lexicalInterpreter()->builtinObject().construct(exec, List::empty());
00576 
00577   for (const PropertyValueNode *p = this; p; p = p->list) {
00578     Value n = p->name->evaluate(exec);
00579     KJS_CHECKEXCEPTIONVALUE
00580     Value v = p->assign->evaluate(exec);
00581     KJS_CHECKEXCEPTIONVALUE
00582 
00583     obj.put(exec, Identifier(n.toString(exec)), v);
00584   }
00585 
00586   return obj;
00587 }
00588 
00589 // ----------------------------- PropertyNode ---------------------------------
00590 
00591 // ECMA 11.1.5
00592 Value PropertyNode::evaluate(ExecState * /*exec*/) const
00593 {
00594   Value s;
00595 
00596   if (str.isNull()) {
00597     s = String(UString::from(numeric));
00598   } else {
00599     s = String(str.ustring());
00600   }
00601 
00602   return s;
00603 }
00604 
00605 // ----------------------------- AccessorNode1 --------------------------------
00606 
00607 void AccessorNode1::ref()
00608 {
00609   Node::ref();
00610   if ( expr1 )
00611     expr1->ref();
00612   if ( expr2 )
00613     expr2->ref();
00614 }
00615 
00616 bool AccessorNode1::deref()
00617 {
00618   if ( expr1 && expr1->deref() )
00619     delete expr1;
00620   if ( expr2 && expr2->deref() )
00621     delete expr2;
00622   return Node::deref();
00623 }
00624 
00625 // ECMA 11.2.1a
00626 Reference AccessorNode1::evaluateReference(ExecState *exec) const
00627 {
00628   Value v1 = expr1->evaluate(exec);
00629   KJS_CHECKEXCEPTIONREFERENCE
00630   Value v2 = expr2->evaluate(exec);
00631   KJS_CHECKEXCEPTIONREFERENCE
00632 #ifndef NDEBUG
00633   // catch errors before being caught in toObject(). better error message.
00634   if (v1.isA(UndefinedType) || v1.isA(NullType)) {
00635     UString s = "Attempted to access property on %s object "
00636                 "(result of expression %s)";
00637         (void)throwError(exec, TypeError, s.cstring().c_str(), v1, this);
00638     return Reference::makeValueReference(Undefined());
00639   }
00640 #endif
00641   Object o = v1.toObject(exec);
00642   unsigned i;
00643   if (v2.toUInt32(i))
00644     return Reference(o, i);
00645   UString s = v2.toString(exec);
00646   return Reference(o, Identifier(s));
00647 }
00648 
00649 // ----------------------------- AccessorNode2 --------------------------------
00650 
00651 void AccessorNode2::ref()
00652 {
00653   Node::ref();
00654   if ( expr )
00655     expr->ref();
00656 }
00657 
00658 bool AccessorNode2::deref()
00659 {
00660   if ( expr && expr->deref() )
00661     delete expr;
00662   return Node::deref();
00663 }
00664 
00665 // ECMA 11.2.1b
00666 Reference AccessorNode2::evaluateReference(ExecState *exec) const
00667 {
00668   Value v = expr->evaluate(exec);
00669   KJS_CHECKEXCEPTIONREFERENCE
00670   assert(v.isValid());
00671 #ifndef NDEBUG
00672   // catch errors before being caught in toObject(). better error message.
00673   if (v.isA(UndefinedType) || v.isA(NullType)) {
00674     UString s = "Attempted to access '" + ident.ustring() +
00675                 "' property on %s object (result of expression %s)";
00676         (void)throwError(exec, TypeError, s.cstring().c_str(), v, this);
00677     return Reference::makeValueReference(Undefined());
00678   }
00679 #endif
00680   Object o = v.toObject(exec);
00681   return Reference(o, ident);
00682 }
00683 
00684 // ----------------------------- ArgumentListNode -----------------------------
00685 
00686 void ArgumentListNode::ref()
00687 {
00688   for (ArgumentListNode *n = this; n; n = n->list) {
00689     n->Node::ref();
00690     if (n->expr)
00691       n->expr->ref();
00692   }
00693 }
00694 
00695 bool ArgumentListNode::deref()
00696 {
00697   ArgumentListNode *next;
00698   for (ArgumentListNode *n = this; n; n = next) {
00699     next = n->list;
00700     if (n->expr && n->expr->deref())
00701       delete n->expr;
00702     if (n != this && n->Node::deref())
00703       delete n;
00704   }
00705   return Node::deref();
00706 }
00707 
00708 Value ArgumentListNode::evaluate(ExecState * /*exec*/) const
00709 {
00710   assert(0);
00711   return Value(); // dummy, see evaluateList()
00712 }
00713 
00714 // ECMA 11.2.4
00715 List ArgumentListNode::evaluateList(ExecState *exec) const
00716 {
00717   List l;
00718 
00719   for (const ArgumentListNode *n = this; n; n = n->list) {
00720     Value v = n->expr->evaluate(exec);
00721     KJS_CHECKEXCEPTIONLIST
00722     l.append(v);
00723   }
00724 
00725   return l;
00726 }
00727 
00728 // ----------------------------- ArgumentsNode --------------------------------
00729 
00730 void ArgumentsNode::ref()
00731 {
00732   Node::ref();
00733   if ( list )
00734     list->ref();
00735 }
00736 
00737 bool ArgumentsNode::deref()
00738 {
00739   if ( list && list->deref() )
00740     delete list;
00741   return Node::deref();
00742 }
00743 
00744 Value ArgumentsNode::evaluate(ExecState * /*exec*/) const
00745 {
00746   assert(0);
00747   return Value(); // dummy, see evaluateList()
00748 }
00749 
00750 // ECMA 11.2.4
00751 List ArgumentsNode::evaluateList(ExecState *exec) const
00752 {
00753   if (!list)
00754     return List();
00755 
00756   return list->evaluateList(exec);
00757 }
00758 
00759 // ----------------------------- NewExprNode ----------------------------------
00760 
00761 // ECMA 11.2.2
00762 
00763 void NewExprNode::ref()
00764 {
00765   Node::ref();
00766   if ( expr )
00767     expr->ref();
00768   if ( args )
00769     args->ref();
00770 }
00771 
00772 bool NewExprNode::deref()
00773 {
00774   if ( expr && expr->deref() )
00775     delete expr;
00776   if ( args && args->deref() )
00777     delete args;
00778   return Node::deref();
00779 }
00780 
00781 Value NewExprNode::evaluate(ExecState *exec) const
00782 {
00783   Value v = expr->evaluate(exec);
00784   KJS_CHECKEXCEPTIONVALUE
00785 
00786   List argList;
00787   if (args) {
00788     argList = args->evaluateList(exec);
00789     KJS_CHECKEXCEPTIONVALUE
00790   }
00791 
00792   if (v.type() != ObjectType) {
00793     return throwError(exec, TypeError, "Value %s (result of expression %s) is not an object. Cannot be used with new.", v, expr);
00794   }
00795 
00796   Object constr = Object(static_cast<ObjectImp*>(v.imp()));
00797   if (!constr.implementsConstruct()) {
00798     return throwError(exec, TypeError, "Value %s (result of expression %s) is not a constructor. Cannot be used with new.", v, expr);
00799   }
00800 
00801   Value res = constr.construct(exec,argList);
00802 
00803   return res;
00804 }
00805 
00806 // ----------------------------- FunctionCallNode -----------------------------
00807 
00808 void FunctionCallNode::ref()
00809 {
00810   Node::ref();
00811   if ( expr )
00812     expr->ref();
00813   if ( args )
00814     args->ref();
00815 }
00816 
00817 bool FunctionCallNode::deref()
00818 {
00819   if ( expr && expr->deref() )
00820     delete expr;
00821   if ( args && args->deref() )
00822     delete args;
00823   return Node::deref();
00824 }
00825 
00826 // ECMA 11.2.3
00827 Value FunctionCallNode::evaluate(ExecState *exec) const
00828 {
00829   Reference ref = expr->evaluateReference(exec);
00830   KJS_CHECKEXCEPTIONVALUE
00831 
00832   List argList = args->evaluateList(exec);
00833   KJS_CHECKEXCEPTIONVALUE
00834 
00835   Value v = ref.getValue(exec);
00836   KJS_CHECKEXCEPTIONVALUE
00837 
00838   if (v.type() != ObjectType) {
00839     return throwError(exec, TypeError, "Value %s (result of expression %s) is not an object. Cannot be called.", v, expr);
00840   }
00841 
00842   Object func = Object(static_cast<ObjectImp*>(v.imp()));
00843 
00844   if (!func.implementsCall()) {
00845     return throwError(exec, TypeError, "Object %s (result of expression %s) does not allow calls.", v, expr);
00846   }
00847 
00848   Value thisVal;
00849   if (ref.isMutable())
00850     thisVal = ref.getBase(exec);
00851   else
00852     thisVal = Null();
00853 
00854   if (thisVal.type() == ObjectType &&
00855       Object::dynamicCast(thisVal).inherits(&ActivationImp::info))
00856     thisVal = Null();
00857 
00858   if (thisVal.type() != ObjectType) {
00859     // ECMA 11.2.3 says that in this situation the this value should be null.
00860     // However, section 10.2.3 says that in the case where the value provided
00861     // by the caller is null, the global object should be used. It also says
00862     // that the section does not apply to interal functions, but for simplicity
00863     // of implementation we use the global object anyway here. This guarantees
00864     // that in host objects you always get a valid object for this.
00865     // thisVal = Null();
00866     thisVal = exec->dynamicInterpreter()->globalObject();
00867   }
00868 
00869   Object thisObj = Object::dynamicCast(thisVal);
00870   Value result = func.call(exec,thisObj, argList);
00871 
00872   return result;
00873 }
00874 
00875 // ----------------------------- PostfixNode ----------------------------------
00876 
00877 void PostfixNode::ref()
00878 {
00879   Node::ref();
00880   if ( expr )
00881     expr->ref();
00882 }
00883 
00884 bool PostfixNode::deref()
00885 {
00886   if ( expr && expr->deref() )
00887     delete expr;
00888   return Node::deref();
00889 }
00890 
00891 // ECMA 11.3
00892 Value PostfixNode::evaluate(ExecState *exec) const
00893 {
00894   Reference ref = expr->evaluateReference(exec);
00895   KJS_CHECKEXCEPTIONVALUE
00896   Value v = ref.getValue(exec);
00897   double n = v.toNumber(exec);
00898 
00899   double newValue = (oper == OpPlusPlus) ? n + 1 : n - 1;
00900 
00901   ref.putValue(exec, Number(newValue));
00902 
00903   return Number(n);
00904 }
00905 
00906 // ----------------------------- DeleteNode -----------------------------------
00907 
00908 void DeleteNode::ref()
00909 {
00910   Node::ref();
00911   if ( expr )
00912     expr->ref();
00913 }
00914 
00915 bool DeleteNode::deref()
00916 {
00917   if ( expr && expr->deref() )
00918     delete expr;
00919   return Node::deref();
00920 }
00921 
00922 // ECMA 11.4.1
00923 Value DeleteNode::evaluate(ExecState *exec) const
00924 {
00925   Reference ref = expr->evaluateReference(exec);
00926   KJS_CHECKEXCEPTIONVALUE
00927   return Boolean(ref.deleteValue(exec));
00928 }
00929 
00930 // ----------------------------- VoidNode -------------------------------------
00931 
00932 void VoidNode::ref()
00933 {
00934   Node::ref();
00935   if ( expr )
00936     expr->ref();
00937 }
00938 
00939 bool VoidNode::deref()
00940 {
00941   if ( expr && expr->deref() )
00942     delete expr;
00943   return Node::deref();
00944 }
00945 
00946 // ECMA 11.4.2
00947 Value VoidNode::evaluate(ExecState *exec) const
00948 {
00949   Value dummy1 = expr->evaluate(exec);
00950   KJS_CHECKEXCEPTIONVALUE
00951 
00952   return Undefined();
00953 }
00954 
00955 // ----------------------------- TypeOfNode -----------------------------------
00956 
00957 void TypeOfNode::ref()
00958 {
00959   Node::ref();
00960   if ( expr )
00961     expr->ref();
00962 }
00963 
00964 bool TypeOfNode::deref()
00965 {
00966   if ( expr && expr->deref() )
00967     delete expr;
00968   return Node::deref();
00969 }
00970 
00971 // ECMA 11.4.3
00972 Value TypeOfNode::evaluate(ExecState *exec) const
00973 {
00974   const char *s = 0L;
00975   Reference ref = expr->evaluateReference(exec);
00976   KJS_CHECKEXCEPTIONVALUE
00977   if (ref.isMutable()) {
00978     Value b = ref.getBase(exec);
00979     if (b.type() == NullType)
00980       return String("undefined");
00981   }
00982   Value v = ref.getValue(exec);
00983   switch (v.type())
00984     {
00985     case UndefinedType:
00986       s = "undefined";
00987       break;
00988     case NullType:
00989       s = "object";
00990       break;
00991     case BooleanType:
00992       s = "boolean";
00993       break;
00994     case NumberType:
00995       s = "number";
00996       break;
00997     case StringType:
00998       s = "string";
00999       break;
01000     default:
01001       if (v.type() == ObjectType && static_cast<ObjectImp*>(v.imp())->implementsCall())
01002     s = "function";
01003       else
01004     s = "object";
01005       break;
01006     }
01007 
01008   return String(s);
01009 }
01010 
01011 // ----------------------------- PrefixNode -----------------------------------
01012 
01013 void PrefixNode::ref()
01014 {
01015   Node::ref();
01016   if ( expr )
01017     expr->ref();
01018 }
01019 
01020 bool PrefixNode::deref()
01021 {
01022   if ( expr && expr->deref() )
01023     delete expr;
01024   return Node::deref();
01025 }
01026 
01027 // ECMA 11.4.4 and 11.4.5
01028 Value PrefixNode::evaluate(ExecState *exec) const
01029 {
01030   Reference ref = expr->evaluateReference(exec);
01031   KJS_CHECKEXCEPTIONVALUE
01032   Value v = ref.getValue(exec);
01033   double n = v.toNumber(exec);
01034 
01035   double newValue = (oper == OpPlusPlus) ? n + 1 : n - 1;
01036   Value n2 = Number(newValue);
01037 
01038   ref.putValue(exec,n2);
01039 
01040   return n2;
01041 }
01042 
01043 // ----------------------------- UnaryPlusNode --------------------------------
01044 
01045 void UnaryPlusNode::ref()
01046 {
01047   Node::ref();
01048   if ( expr )
01049     expr->ref();
01050 }
01051 
01052 bool UnaryPlusNode::deref()
01053 {
01054   if ( expr && expr->deref() )
01055     delete expr;
01056   return Node::deref();
01057 }
01058 
01059 // ECMA 11.4.6
01060 double UnaryPlusNode::toNumber(ExecState *exec) const
01061 {
01062   return expr->toNumber(exec);
01063 }
01064 
01065 // could go
01066 Value UnaryPlusNode::evaluate(ExecState *exec) const
01067 {
01068   Value v = expr->evaluate(exec);
01069   KJS_CHECKEXCEPTIONVALUE
01070 
01071   return Number(v.toNumber(exec)); /* TODO: optimize */
01072 }
01073 
01074 // ----------------------------- NegateNode -----------------------------------
01075 
01076 void NegateNode::ref()
01077 {
01078   Node::ref();
01079   if ( expr )
01080     expr->ref();
01081 }
01082 
01083 bool NegateNode::deref()
01084 {
01085   if ( expr && expr->deref() )
01086     delete expr;
01087   return Node::deref();
01088 }
01089 
01090 // ECMA 11.4.7
01091 double NegateNode::toNumber(ExecState *exec) const
01092 {
01093   return -expr->toNumber(exec);
01094 }
01095 
01096 Value NegateNode::evaluate(ExecState *exec) const
01097 {
01098   Value v = expr->evaluate(exec);
01099   KJS_CHECKEXCEPTIONVALUE
01100   double d = -v.toNumber(exec);
01101 
01102   return Number(d);
01103 }
01104 
01105 // ----------------------------- BitwiseNotNode -------------------------------
01106 
01107 void BitwiseNotNode::ref()
01108 {
01109   Node::ref();
01110   if ( expr )
01111     expr->ref();
01112 }
01113 
01114 bool BitwiseNotNode::deref()
01115 {
01116   if ( expr && expr->deref() )
01117     delete expr;
01118   return Node::deref();
01119 }
01120 
01121 // ECMA 11.4.8
01122 Value BitwiseNotNode::evaluate(ExecState *exec) const
01123 {
01124   Value v = expr->evaluate(exec);
01125   KJS_CHECKEXCEPTIONVALUE
01126   int i32 = v.toInt32(exec);
01127 
01128   return Number(~i32);
01129 }