# kjs Library API Documentation

Overview | Class Hierarchy | Classes | Classes (annotated) | Members | Source Files

# nodes.cpp

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

This file is part of the documentation for kdelibs Version 3.1.5.
Documentation copyright © 1996-2002 the KDE developers.
Generated on Wed Jan 28 13:08:31 2004 by doxygen 1.3.4 written by Dimitri van Heesch, © 1997-2001