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