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