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 return String(ident.ustring());
01784 }
01785
01786 void VarDeclNode::processVarDecls(ExecState *exec)
01787 {
01788 Object variable = exec->context().variableObject();
01789 if ( !variable.hasProperty( exec, ident ) ) {
01790 int flags = None;
01791 if (exec->_context->type() != EvalCode)
01792 flags |= DontDelete;
01793 if (currentVarType == VarStatementNode::Constant)
01794 flags |= ReadOnly;
01795
01796 variable.put(exec,ident, Undefined(), flags);
01797 }
01798
01799 }
01800
01801
01802
01803 void VarDeclListNode::ref()
01804 {
01805 for (VarDeclListNode *n = this; n; n = n->list) {
01806 n->Node::ref();
01807 if (n->var)
01808 n->var->ref();
01809 }
01810 }
01811
01812 bool VarDeclListNode::deref()
01813 {
01814 VarDeclListNode *next;
01815 for (VarDeclListNode *n = this; n; n = next) {
01816 next = n->list;
01817 if (n->var && n->var->deref())
01818 delete n->var;
01819 if (n != this && n->Node::deref())
01820 delete n;
01821 }
01822 return Node::deref();
01823 }
01824
01825
01826
01827 Value VarDeclListNode::evaluate(ExecState *exec) const
01828 {
01829 for (const VarDeclListNode *n = this; n; n = n->list) {
01830 n->var->evaluate(exec);
01831 KJS_CHECKEXCEPTIONVALUE
01832 }
01833 return Undefined();
01834 }
01835
01836 void VarDeclListNode::processVarDecls(ExecState *exec)
01837 {
01838 for (VarDeclListNode *n = this; n; n = n->list)
01839 n->var->processVarDecls(exec);
01840 }
01841
01842
01843
01844 void VarStatementNode::ref()
01845 {
01846 StatementNode::ref();
01847 if ( list )
01848 list->ref();
01849 }
01850
01851 bool VarStatementNode::deref()
01852 {
01853 if ( list && list->deref() )
01854 delete list;
01855 return StatementNode::deref();
01856 }
01857
01858
01859 Completion VarStatementNode::execute(ExecState *exec)
01860 {
01861 KJS_BREAKPOINT;
01862
01863
01864 currentVarType = varType;
01865
01866 (void) list->evaluate(exec);
01867 KJS_CHECKEXCEPTION
01868
01869 return Completion(Normal);
01870 }
01871
01872 void VarStatementNode::processVarDecls(ExecState *exec)
01873 {
01874
01875 currentVarType = varType;
01876
01877 list->processVarDecls(exec);
01878 }
01879
01880
01881
01882 BlockNode::BlockNode(SourceElementsNode *s)
01883 {
01884 if (s) {
01885 source = s->elements;
01886 s->elements = 0;
01887 setLoc(s->firstLine(), s->lastLine(), s->code());
01888 } else {
01889 source = 0;
01890 }
01891 }
01892
01893 void BlockNode::ref()
01894 {
01895 StatementNode::ref();
01896 if ( source )
01897 source->ref();
01898 }
01899
01900 bool BlockNode::deref()
01901 {
01902 if ( source && source->deref() )
01903 delete source;
01904 return StatementNode::deref();
01905 }
01906
01907
01908 Completion BlockNode::execute(ExecState *exec)
01909 {
01910 if (!source)
01911 return Completion(Normal);
01912
01913 source->processFuncDecl(exec);
01914
01915 return source->execute(exec);
01916 }
01917
01918 void BlockNode::processVarDecls(ExecState *exec)
01919 {
01920 if (source)
01921 source->processVarDecls(exec);
01922 }
01923
01924
01925
01926
01927 Completion EmptyStatementNode::execute(ExecState * )
01928 {
01929 return Completion(Normal);
01930 }
01931
01932
01933
01934 void ExprStatementNode::ref()
01935 {
01936 StatementNode::ref();
01937 if ( expr )
01938 expr->ref();
01939 }
01940
01941 bool ExprStatementNode::deref()
01942 {
01943 if ( expr && expr->deref() )
01944 delete expr;
01945 return StatementNode::deref();
01946 }
01947
01948
01949 Completion ExprStatementNode::execute(ExecState *exec)
01950 {
01951 KJS_BREAKPOINT;
01952
01953 Value v = expr->evaluate(exec);
01954 KJS_CHECKEXCEPTION
01955
01956 return Completion(Normal, v);
01957 }
01958
01959
01960
01961 void IfNode::ref()
01962 {
01963 StatementNode::ref();
01964 if ( statement1 )
01965 statement1->ref();
01966 if ( statement2 )
01967 statement2->ref();
01968 if ( expr )
01969 expr->ref();
01970 }
01971
01972 bool IfNode::deref()
01973 {
01974 if ( statement1 && statement1->deref() )
01975 delete statement1;
01976 if ( statement2 && statement2->deref() )
01977 delete statement2;
01978 if ( expr && expr->deref() )
01979 delete expr;
01980 return StatementNode::deref();
01981 }
01982
01983
01984 Completion IfNode::execute(ExecState *exec)
01985 {
01986 KJS_BREAKPOINT;
01987
01988 assert(expr);
01989 bool b = expr->toBoolean(exec);
01990 KJS_CHECKEXCEPTION
01991
01992
01993 if (b)
01994 return statement1->execute(exec);
01995
01996
01997 if (!statement2)
01998 return Completion(Normal);
01999
02000
02001 return statement2->execute(exec);
02002 }
02003
02004 void IfNode::processVarDecls(ExecState *exec)
02005 {
02006 statement1->processVarDecls(exec);
02007
02008 if (statement2)
02009 statement2->processVarDecls(exec);
02010 }
02011
02012
02013
02014 void DoWhileNode::ref()
02015 {
02016 StatementNode::ref();
02017 if ( statement )
02018 statement->ref();
02019 if ( expr )
02020 expr->ref();
02021 }
02022
02023 bool DoWhileNode::deref()
02024 {
02025 if ( statement && statement->deref() )
02026 delete statement;
02027 if ( expr && expr->deref() )
02028 delete expr;
02029 return StatementNode::deref();
02030 }
02031
02032
02033 Completion DoWhileNode::execute(ExecState *exec)
02034 {
02035 KJS_BREAKPOINT;
02036
02037 Completion c;
02038 Value value;
02039 bool b;
02040
02041 do {
02042
02043 KJS_CHECKEXCEPTION
02044
02045 exec->context().imp()->seenLabels()->pushIteration();
02046 c = statement->execute(exec);
02047 exec->context().imp()->seenLabels()->popIteration();
02048 if (!((c.complType() == Continue) && ls.contains(c.target()))) {
02049 if ((c.complType() == Break) && ls.contains(c.target()))
02050 return Completion(Normal, value);
02051 if (c.complType() != Normal)
02052 return c;
02053 }
02054 b = expr->toBoolean(exec);
02055 KJS_CHECKEXCEPTION
02056 } while (b);
02057
02058 return Completion(Normal, value);
02059 }
02060
02061 void DoWhileNode::processVarDecls(ExecState *exec)
02062 {
02063 statement->processVarDecls(exec);
02064 }
02065
02066
02067
02068 void WhileNode::ref()
02069 {
02070 StatementNode::ref();
02071 if ( statement )
02072 statement->ref();
02073 if ( expr )
02074 expr->ref();
02075 }
02076
02077 bool WhileNode::deref()
02078 {
02079 if ( statement && statement->deref() )
02080 delete statement;
02081 if ( expr && expr->deref() )
02082 delete expr;
02083 return StatementNode::deref();
02084 }
02085
02086
02087 Completion WhileNode::execute(ExecState *exec)
02088 {
02089 KJS_BREAKPOINT;
02090
02091 Completion c;
02092 Value value;
02093
02094 while (1) {
02095 bool b = expr->toBoolean(exec);
02096 KJS_CHECKEXCEPTION
02097
02098
02099 KJS_CHECKEXCEPTION
02100
02101 if (!b)
02102 return Completion(Normal, value);
02103
02104 exec->context().imp()->seenLabels()->pushIteration();
02105 c = statement->execute(exec);
02106 exec->context().imp()->seenLabels()->popIteration();
02107 if (c.isValueCompletion())
02108 value = c.value();
02109
02110 if ((c.complType() == Continue) && ls.contains(c.target()))
02111 continue;
02112 if ((c.complType() == Break) && ls.contains(c.target()))
02113 return Completion(Normal, value);
02114 if (c.complType() != Normal)
02115 return c;
02116 }
02117 }
02118
02119 void WhileNode::processVarDecls(ExecState *exec)
02120 {
02121 statement->processVarDecls(exec);
02122 }
02123
02124
02125
02126 void ForNode::ref()
02127 {
02128 StatementNode::ref();
02129 if ( statement )
02130 statement->ref();
02131 if ( expr1 )
02132 expr1->ref();
02133 if ( expr2 )
02134 expr2->ref();
02135 if ( expr3 )
02136 expr3->ref();
02137 }
02138
02139 bool ForNode::deref()
02140 {
02141 if ( statement && statement->deref() )
02142 delete statement;
02143 if ( expr1 && expr1->deref() )
02144 delete expr1;
02145 if ( expr2 && expr2->deref() )
02146 delete expr2;
02147 if ( expr3 && expr3->deref() )
02148 delete expr3;
02149 return StatementNode::deref();
02150 }
02151
02152
02153 Completion ForNode::execute(ExecState *exec)
02154 {
02155 Value v, cval;
02156
02157 if (expr1) {
02158 v = expr1->evaluate(exec);
02159 KJS_CHECKEXCEPTION
02160 }
02161 for (;;) {
02162 if (expr2) {
02163 bool b = expr2->toBoolean(exec);
02164 KJS_CHECKEXCEPTION
02165 if (!b)
02166 return Completion(Normal, cval);
02167 }
02168
02169 KJS_CHECKEXCEPTION
02170
02171 exec->context().imp()->seenLabels()->pushIteration();
02172 Completion c = statement->execute(exec);
02173 exec->context().imp()->seenLabels()->popIteration();
02174 if (c.isValueCompletion())
02175 cval = c.value();
02176 if (!((c.complType() == Continue) && ls.contains(c.target()))) {
02177 if ((c.complType() == Break) && ls.contains(c.target()))
02178 return Completion(Normal, cval);
02179 if (c.complType() != Normal)
02180 return c;
02181 }
02182 if (expr3) {
02183 v = expr3->evaluate(exec);
02184 KJS_CHECKEXCEPTION
02185 }
02186 }
02187 }
02188
02189 void ForNode::processVarDecls(ExecState *exec)
02190 {
02191 if (expr1)
02192 expr1->processVarDecls(exec);
02193
02194 statement->processVarDecls(exec);
02195 }
02196
02197
02198
02199 ForInNode::ForInNode(Node *l, Node *e, StatementNode *s)
02200 : init(0L), lexpr(l), expr(e), varDecl(0L), statement(s)
02201 {
02202 }
02203
02204 ForInNode::ForInNode(const Identifier &i, AssignExprNode *in, Node *e, StatementNode *s)
02205 : ident(i), init(in), expr(e), statement(s)
02206 {
02207
02208 varDecl = new VarDeclNode(ident, init);
02209 lexpr = new ResolveNode(ident);
02210 }
02211
02212 void ForInNode::ref()
02213 {
02214 StatementNode::ref();
02215 if ( statement )
02216 statement->ref();
02217 if ( expr )
02218 expr->ref();
02219 if ( lexpr )
02220 lexpr->ref();
02221 if ( init )
02222 init->ref();
02223 if ( varDecl )
02224 varDecl->ref();
02225 }
02226
02227 bool ForInNode::deref()
02228 {
02229 if ( statement && statement->deref() )
02230 delete statement;
02231 if ( expr && expr->deref() )
02232 delete expr;
02233 if ( lexpr && lexpr->deref() )
02234 delete lexpr;
02235 if ( init && init->deref() )
02236 delete init;
02237 if ( varDecl && varDecl->deref() )
02238 delete varDecl;
02239 return StatementNode::deref();
02240 }
02241
02242
02243 Completion ForInNode::execute(ExecState *exec)
02244 {
02245 Value retval;
02246 Completion c;
02247
02248 if ( varDecl ) {
02249 varDecl->evaluate(exec);
02250 KJS_CHECKEXCEPTION
02251 }
02252
02253 Value v = expr->evaluate(exec);
02254
02255
02256
02257
02258 if (v.isA(NullType) || v.isA(UndefinedType))
02259 return Completion(Normal, retval);
02260
02261 Object o = v.toObject(exec);
02262 KJS_CHECKEXCEPTION
02263 ReferenceList propList = o.propList(exec);
02264
02265 ReferenceListIterator propIt = propList.begin();
02266
02267 while (propIt != propList.end()) {
02268 Identifier name = propIt->getPropertyName(exec);
02269 if (!o.hasProperty(exec,name)) {
02270 propIt++;
02271 continue;
02272 }
02273
02274 Reference ref = lexpr->evaluateReference(exec);
02275 KJS_CHECKEXCEPTION
02276 ref.putValue(exec, String(name.ustring()));
02277
02278 exec->context().imp()->seenLabels()->pushIteration();
02279 c = statement->execute(exec);
02280 exec->context().imp()->seenLabels()->popIteration();
02281 if (c.isValueCompletion())
02282 retval = c.value();
02283
02284 if (!((c.complType() == Continue) && ls.contains(c.target()))) {
02285 if ((c.complType() == Break) && ls.contains(c.target()))
02286 break;
02287 if (c.complType() != Normal) {
02288 return c;
02289 }
02290 }
02291
02292 propIt++;
02293 }
02294
02295
02296 KJS_CHECKEXCEPTION
02297
02298 return Completion(Normal, retval);
02299 }
02300
02301 void ForInNode::processVarDecls(ExecState *exec)
02302 {
02303 statement->processVarDecls(exec);
02304 }
02305
02306
02307
02308
02309 Completion ContinueNode::execute(ExecState *exec)
02310 {
02311 KJS_BREAKPOINT;
02312
02313 Value dummy;
02314
02315 if (ident.isEmpty() && !exec->context().imp()->seenLabels()->inIteration())
02316 return Completion(Throw,
02317 throwError(exec, SyntaxError, "continue used outside of iteration statement"));
02318 else if (!ident.isEmpty() && !exec->context().imp()->seenLabels()->contains(ident))
02319 return Completion(Throw,
02320 throwError(exec, SyntaxError, "Label %s not found in containing block. Can't continue.", ident));
02321 else
02322 return Completion(Continue, dummy, ident);
02323 }
02324
02325
02326
02327
02328 Completion BreakNode::execute(ExecState *exec)
02329 {
02330 KJS_BREAKPOINT;
02331
02332 Value dummy;
02333
02334 if (ident.isEmpty() && !exec->context().imp()->seenLabels()->inIteration() &&
02335 !exec->context().imp()->seenLabels()->inSwitch())
02336 return Completion(Throw,
02337 throwError(exec, SyntaxError, "break used outside of iteration or switch statement"));
02338 else if (!ident.isEmpty() && !exec->context().imp()->seenLabels()->contains(ident))
02339 return Completion(Throw,
02340 throwError(exec, SyntaxError, "Label %s not found in containing block. Can't break.", ident));
02341 else
02342 return Completion(Break, dummy, ident);
02343 }
02344
02345
02346
02347 void ReturnNode::ref()
02348 {
02349 StatementNode::ref();
02350 if ( value )
02351 value->ref();
02352 }
02353
02354 bool ReturnNode::deref()
02355 {
02356 if ( value && value->deref() )
02357 delete value;
02358 return StatementNode::deref();
02359 }
02360
02361
02362 Completion ReturnNode::execute(ExecState *exec)
02363 {
02364 KJS_BREAKPOINT;
02365
02366 if (!value)
02367 return Completion(ReturnValue, Undefined());
02368
02369 Value v = value->evaluate(exec);
02370 KJS_CHECKEXCEPTION
02371
02372 return Completion(ReturnValue, v);
02373 }
02374
02375
02376
02377 void WithNode::ref()
02378 {
02379 StatementNode::ref();
02380 if ( statement )
02381 statement->ref();
02382 if ( expr )
02383 expr->ref();
02384 }
02385
02386 bool WithNode::deref()
02387 {
02388 if ( statement && statement->deref() )
02389 delete statement;
02390 if ( expr && expr->deref() )
02391 delete expr;
02392 return StatementNode::deref();
02393 }
02394
02395
02396 Completion WithNode::execute(ExecState *exec)
02397 {
02398 KJS_BREAKPOINT;
02399
02400 Value v = expr->evaluate(exec);
02401 KJS_CHECKEXCEPTION
02402 Object o = v.toObject(exec);
02403 KJS_CHECKEXCEPTION
02404 exec->context().imp()->pushScope(o);
02405 Completion res = statement->execute(exec);
02406 exec->context().imp()->popScope();
02407
02408 return res;
02409 }
02410
02411 void WithNode::processVarDecls(ExecState *exec)
02412 {
02413 statement->processVarDecls(exec);
02414 }
02415
02416
02417
02418 void CaseClauseNode::ref()
02419 {
02420 Node::ref();
02421 if ( expr )
02422 expr->ref();
02423 if ( list )
02424 list->ref();
02425 }
02426
02427 bool CaseClauseNode::deref()
02428 {
02429 if ( expr && expr->deref() )
02430 delete expr;
02431 if ( list && list->deref() )
02432 delete list;
02433 return Node::deref();
02434 }
02435
02436
02437 Value CaseClauseNode::evaluate(ExecState *exec) const
02438 {
02439 Value v = expr->evaluate(exec);
02440 KJS_CHECKEXCEPTIONVALUE
02441
02442 return v;
02443 }
02444
02445
02446 Completion CaseClauseNode::evalStatements(ExecState *exec) const
02447 {
02448 if (list)
02449 return list->execute(exec);
02450 else
02451 return Completion(Normal, Undefined());
02452 }
02453
02454 void CaseClauseNode::processVarDecls(ExecState *exec)
02455 {
02456 if (list)
02457 list->processVarDecls(exec);
02458 }
02459
02460
02461
02462 void ClauseListNode::ref()
02463 {
02464 for (ClauseListNode *n = this; n; n = n->nx) {
02465 n->Node::ref();
02466 if (n->cl)
02467 n->cl->ref();
02468 }
02469 }
02470
02471 bool ClauseListNode::deref()
02472 {
02473 ClauseListNode *next;
02474 for (ClauseListNode *n = this; n; n = next) {
02475 next = n->nx;
02476 if (n->cl && n->cl->deref())
02477 delete n->cl;
02478 if (n != this && n->Node::deref())
02479 delete n;
02480 }
02481 return Node::deref();
02482 }
02483
02484 Value ClauseListNode::evaluate(ExecState * ) const
02485 {
02486
02487 assert(false);
02488 return Value();
02489 }
02490
02491
02492 void ClauseListNode::processVarDecls(ExecState *exec)
02493 {
02494 for (ClauseListNode *n = this; n; n = n->nx)
02495 if (n->cl)
02496 n->cl->processVarDecls(exec);
02497 }
02498
02499
02500
02501 CaseBlockNode::CaseBlockNode(ClauseListNode *l1, CaseClauseNode *d,
02502 ClauseListNode *l2)
02503 {
02504 def = d;
02505 if (l1) {
02506 list1 = l1->nx;
02507 l1->nx = 0;
02508 } else {
02509 list1 = 0;
02510 }
02511 if (l2) {
02512 list2 = l2->nx;
02513 l2->nx = 0;
02514 } else {
02515 list2 = 0;
02516 }
02517 }
02518
02519 void CaseBlockNode::ref()
02520 {
02521 Node::ref();
02522 if ( def )
02523 def->ref();
02524 if ( list1 )
02525 list1->ref();
02526 if ( list2 )
02527 list2->ref();
02528 }
02529
02530 bool CaseBlockNode::deref()
02531 {
02532 if ( def && def->deref() )
02533 delete def;
02534 if ( list1 && list1->deref() )
02535 delete list1;
02536 if ( list2 && list2->deref() )
02537 delete list2;
02538 return Node::deref();
02539 }
02540
02541 Value CaseBlockNode::evaluate(ExecState * ) const
02542 {
02543
02544 assert(false);
02545 return Value();
02546 }
02547
02548
02549 Completion CaseBlockNode::evalBlock(ExecState *exec, const Value& input) const
02550 {
02551 Value v;
02552 Completion res;
02553 ClauseListNode *a = list1, *b = list2;
02554 CaseClauseNode *clause;
02555
02556 while (a) {
02557 clause = a->clause();
02558 a = a->next();
02559 v = clause->evaluate(exec);
02560 KJS_CHECKEXCEPTION
02561 if (strictEqual(exec, input, v)) {
02562 res = clause->evalStatements(exec);
02563 if (res.complType() != Normal)
02564 return res;
02565 while (a) {
02566 res = a->clause()->evalStatements(exec);
02567 if (res.complType() != Normal)
02568 return res;
02569 a = a->next();
02570 }
02571 break;
02572 }
02573 }
02574
02575 while (b) {
02576 clause = b->clause();
02577 b = b->next();
02578 v = clause->evaluate(exec);
02579 KJS_CHECKEXCEPTION
02580 if (strictEqual(exec, input, v)) {
02581 res = clause->evalStatements(exec);
02582 if (res.complType() != Normal)
02583 return res;
02584 goto step18;
02585 }
02586 }
02587
02588
02589 if (def) {
02590 res = def->evalStatements(exec);
02591 if (res.complType() != Normal)
02592 return res;
02593 }
02594 b = list2;
02595 step18:
02596 while (b) {
02597 clause = b->clause();
02598 res = clause->evalStatements(exec);
02599 if (res.complType() != Normal)
02600 return res;
02601 b = b->next();
02602 }
02603
02604
02605 KJS_CHECKEXCEPTION
02606
02607 return Completion(Normal);
02608 }
02609
02610 void CaseBlockNode::processVarDecls(ExecState *exec)
02611 {
02612 if (list1)
02613 list1->processVarDecls(exec);
02614 if (def)
02615 def->processVarDecls(exec);
02616 if (list2)
02617 list2->processVarDecls(exec);
02618 }
02619
02620
02621
02622 void SwitchNode::ref()
02623 {
02624 StatementNode::ref();
02625 if ( expr )
02626 expr->ref();
02627 if ( block )
02628 block->ref();
02629 }
02630
02631 bool SwitchNode::deref()
02632 {
02633 if ( expr && expr->deref() )
02634 delete expr;
02635 if ( block && block->deref() )
02636 delete block;
02637 return StatementNode::deref();
02638 }
02639
02640
02641 Completion SwitchNode::execute(ExecState *exec)
02642 {
02643 KJS_BREAKPOINT;
02644
02645 Value v = expr->evaluate(exec);
02646 KJS_CHECKEXCEPTION
02647 exec->context().imp()->seenLabels()->pushSwitch();
02648 Completion res = block->evalBlock(exec,v);
02649 exec->context().imp()->seenLabels()->popSwitch();
02650
02651 if ((res.complType() == Break) && ls.contains(res.target()))
02652 return Completion(Normal, res.value());
02653 else
02654 return res;
02655 }
02656
02657 void SwitchNode::processVarDecls(ExecState *exec)
02658 {
02659 block->processVarDecls(exec);
02660 }
02661
02662
02663
02664 void LabelNode::ref()
02665 {
02666 StatementNode::ref();
02667 if ( statement )
02668 statement->ref();
02669 }
02670
02671 bool LabelNode::deref()
02672 {
02673 if ( statement && statement->deref() )
02674 delete statement;
02675 return StatementNode::deref();
02676 }
02677
02678
02679 Completion LabelNode::execute(ExecState *exec)
02680 {
02681 Completion e;
02682
02683 if (!exec->context().imp()->seenLabels()->push(label)) {
02684 return Completion( Throw,
02685 throwError(exec, SyntaxError, "Duplicated label %s found.", label));
02686 };
02687 e = statement->execute(exec);
02688 exec->context().imp()->seenLabels()->pop();
02689
02690 if ((e.complType() == Break) && (e.target() == label))
02691 return Completion(Normal, e.value());
02692 else
02693 return e;
02694 }
02695
02696 void LabelNode::processVarDecls(ExecState *exec)
02697 {
02698 statement->processVarDecls(exec);
02699 }
02700
02701
02702
02703 void ThrowNode::ref()
02704 {
02705 StatementNode::ref();
02706 if ( expr )
02707 expr->ref();
02708 }
02709
02710 bool ThrowNode::deref()
02711 {
02712 if ( expr && expr->deref() )
02713 delete expr;
02714 return StatementNode::deref();
02715 }
02716
02717
02718 Completion ThrowNode::execute(ExecState *exec)
02719 {
02720 KJS_BREAKPOINT;
02721
02722 Value v = expr->evaluate(exec);
02723 KJS_CHECKEXCEPTION
02724
02725
02726 KJS_CHECKEXCEPTION
02727
02728 Debugger *dbg = exec->interpreter()->imp()->debugger();
02729 if (dbg)
02730 dbg->exception(exec,v,exec->context().imp()->inTryCatch());
02731
02732 return Completion(Throw, v);
02733 }
02734
02735
02736
02737 void CatchNode::ref()
02738 {
02739 StatementNode::ref();
02740 if ( block )
02741 block->ref();
02742 }
02743
02744 bool CatchNode::deref()
02745 {
02746 if ( block && block->deref() )
02747 delete block;
02748 return StatementNode::deref();
02749 }
02750
02751 Completion CatchNode::execute(ExecState * )
02752 {
02753
02754 assert(0L);
02755 return Completion();
02756 }
02757
02758
02759 Completion CatchNode::execute(ExecState *exec, const Value &arg)
02760 {
02761
02762
02763 exec->clearException();
02764
02765 Object obj(new ObjectImp());
02766 obj.put(exec, ident, arg, DontDelete);
02767 exec->context().imp()->pushScope(obj);
02768 Completion c = block->execute(exec);
02769 exec->context().imp()->popScope();
02770
02771 return c;
02772 }
02773
02774 void CatchNode::processVarDecls(ExecState *exec)
02775 {
02776 block->processVarDecls(exec);
02777 }
02778
02779
02780
02781 void FinallyNode::ref()
02782 {
02783 StatementNode::ref();
02784 if ( block )
02785 block->ref();
02786 }
02787
02788 bool FinallyNode::deref()
02789 {
02790 if ( block && block->deref() )
02791 delete block;
02792 return StatementNode::deref();
02793 }
02794
02795
02796 Completion FinallyNode::execute(ExecState *exec)
02797 {
02798 return block->execute(exec);
02799 }
02800
02801 void FinallyNode::processVarDecls(ExecState *exec)
02802 {
02803 block->processVarDecls(exec);
02804 }
02805
02806
02807
02808 void TryNode::ref()
02809 {
02810 StatementNode::ref();
02811 if ( block )
02812 block->ref();
02813 if ( _final )
02814 _final->ref();
02815 if ( _catch )
02816 _catch->ref();
02817 }
02818
02819 bool TryNode::deref()
02820 {
02821 if ( block && block->deref() )
02822 delete block;
02823 if ( _final && _final->deref() )
02824 delete _final;
02825 if ( _catch && _catch->deref() )
02826 delete _catch;
02827 return StatementNode::deref();
02828 }
02829
02830
02831 Completion TryNode::execute(ExecState *exec)
02832 {
02833 KJS_BREAKPOINT;
02834
02835 Completion c, c2;
02836
02837 if (_catch)
02838 exec->context().imp()->pushTryCatch();
02839 c = block->execute(exec);
02840 if (_catch)
02841 exec->context().imp()->popTryCatch();
02842
02843 if (!_final) {
02844 if (c.complType() != Throw)
02845 return c;
02846 return _catch->execute(exec,c.value());
02847 }
02848
02849 if (!_catch) {
02850 Value exception = exec->_exception;
02851 exec->_exception = Value();
02852
02853 c2 = _final->execute(exec);
02854
02855 if (!exec->hadException() && c2.complType() != Throw)
02856 exec->_exception = exception;
02857
02858 return (c2.complType() == Normal) ? c : c2;
02859 }
02860
02861 if (c.complType() == Throw)
02862 c = _catch->execute(exec,c.value());
02863
02864 c2 = _final->execute(exec);
02865 return (c2.complType() == Normal) ? c : c2;
02866 }
02867
02868 void TryNode::processVarDecls(ExecState *exec)
02869 {
02870 block->processVarDecls(exec);
02871 if (_final)
02872 _final->processVarDecls(exec);
02873 if (_catch)
02874 _catch->processVarDecls(exec);
02875 }
02876
02877
02878
02879 void ParameterNode::ref()
02880 {
02881 for (ParameterNode *n = this; n; n = n->next)
02882 n->Node::ref();
02883 }
02884
02885 bool ParameterNode::deref()
02886 {
02887 ParameterNode *next;
02888 for (ParameterNode *n = this; n; n = next) {
02889 next = n->next;
02890 if (n != this && n->Node::deref())
02891 delete n;
02892 }
02893 return Node::deref();
02894 }
02895
02896
02897 Value ParameterNode::evaluate(ExecState * ) const
02898 {
02899 return Undefined();
02900 }
02901
02902
02903
02904
02905 FunctionBodyNode::FunctionBodyNode(SourceElementsNode *s)
02906 : BlockNode(s), program(false)
02907 {
02908
02909 }
02910
02911 void FunctionBodyNode::processFuncDecl(ExecState *exec)
02912 {
02913 if (source)
02914 source->processFuncDecl(exec);
02915 }
02916
02917 Completion FunctionBodyNode::execute(ExecState *exec)
02918 {
02919 Completion c = BlockNode::execute(exec);
02920 if (program && c.complType() == ReturnValue)
02921 return Completion(Throw,
02922 throwError(exec, SyntaxError, "return outside of function body"));
02923 else
02924 return c;
02925 }
02926
02927
02928
02929 void FuncDeclNode::ref()
02930 {
02931 StatementNode::ref();
02932 if ( param )
02933 param->ref();
02934 if ( body )
02935 body->ref();
02936 }
02937
02938 bool FuncDeclNode::deref()
02939 {
02940 if ( param && param->deref() )
02941 delete param;
02942 if ( body && body->deref() )
02943 delete body;
02944 return StatementNode::deref();
02945 }
02946
02947
02948 void FuncDeclNode::processFuncDecl(ExecState *exec)
02949 {
02950 ContextImp *ctx = exec->context().imp();
02951
02952 FunctionImp *fimp = new DeclaredFunctionImp(exec, ident, body, exec->context().imp()->scopeChain());
02953 Object func(fimp);
02954
02955
02956 List empty;
02957 Object proto = exec->interpreter()->builtinObject().construct(exec,empty);
02958 proto.put(exec, constructorPropertyName, func, ReadOnly|DontDelete|DontEnum);
02959 func.put(exec, prototypePropertyName, proto, Internal|DontDelete);
02960
02961 int plen = 0;
02962 for(const ParameterNode *p = param; p != 0L; p = p->nextParam(), plen++)
02963 fimp->addParameter(p->ident());
02964
02965 func.put(exec, lengthPropertyName, Number(plen), ReadOnly|DontDelete|DontEnum);
02966
02967 #ifdef KJS_VERBOSE
02968 fprintf(stderr,"KJS: new function %s in %p\n", ident.ustring().cstring().c_str(), ctx->variableObject().imp());
02969 #endif
02970 if (exec->_context->type() == EvalCode)
02971 ctx->variableObject().put(exec,ident,func,Internal);
02972 else
02973 ctx->variableObject().put(exec,ident,func,DontDelete|Internal);
02974
02975 if (body) {
02976
02977
02978 Object oldVar = ctx->variableObject();
02979 ctx->setVariableObject(func);
02980 ctx->pushScope(func);
02981 body->processFuncDecl(exec);
02982 ctx->popScope();
02983 ctx->setVariableObject(oldVar);
02984 }
02985 }
02986
02987
02988
02989 void FuncExprNode::ref()
02990 {
02991 Node::ref();
02992 if ( param )
02993 param->ref();
02994 if ( body )
02995 body->ref();
02996 }
02997
02998 bool FuncExprNode::deref()
02999 {
03000 if ( param && param->deref() )
03001 delete param;
03002 if ( body && body->deref() )
03003 delete body;
03004 return Node::deref();
03005 }
03006
03007
03008
03009 Value FuncExprNode::evaluate(ExecState *exec) const
03010 {
03011 FunctionImp *fimp = new DeclaredFunctionImp(exec, Identifier::null(), body, exec->context().imp()->scopeChain());
03012 Value ret(fimp);
03013 List empty;
03014 Value proto = exec->interpreter()->builtinObject().construct(exec,empty);
03015 fimp->put(exec, prototypePropertyName, proto, Internal|DontDelete);
03016
03017 for(const ParameterNode *p = param; p != 0L; p = p->nextParam())
03018 fimp->addParameter(p->ident());
03019
03020 return ret;
03021 }
03022
03023
03024
03025 SourceElementsNode::SourceElementsNode(StatementNode *s1)
03026 {
03027 element = s1;
03028 elements = this;
03029 setLoc(s1->firstLine(),s1->lastLine(),s1->code());
03030 }
03031
03032 SourceElementsNode::SourceElementsNode(SourceElementsNode *s1, StatementNode *s2)
03033 {
03034 elements = s1->elements;
03035 s1->elements = this;
03036 element = s2;
03037 setLoc(s1->firstLine(),s2->lastLine(),s1->code());
03038 }
03039
03040 void SourceElementsNode::ref()
03041 {
03042 for (SourceElementsNode *n = this; n; n = n->elements) {
03043 n->Node::ref();
03044 if (n->element)
03045 n->element->ref();
03046 }
03047 }
03048
03049 bool SourceElementsNode::deref()
03050 {
03051 SourceElementsNode *next;
03052 for (SourceElementsNode *n = this; n; n = next) {
03053 next = n->elements;
03054 if (n->element && n->element->deref())
03055 delete n->element;
03056 if (n != this && n->Node::deref())
03057 delete n;
03058 }
03059 return StatementNode::deref();
03060 }
03061
03062
03063 Completion SourceElementsNode::execute(ExecState *exec)
03064 {
03065 KJS_CHECKEXCEPTION
03066
03067 Completion c1 = element->execute(exec);
03068 KJS_CHECKEXCEPTION;
03069 if (c1.complType() != Normal)
03070 return c1;
03071
03072 for (SourceElementsNode *node = elements; node; node = node->elements) {
03073 Completion c2 = node->element->execute(exec);
03074 if (c2.complType() != Normal)
03075 return c2;
03076
03077
03078 if (c2.value().isValid())
03079 c1 = c2;
03080 }
03081
03082 return c1;
03083 }
03084
03085
03086 void SourceElementsNode::processFuncDecl(ExecState *exec)
03087 {
03088 for (SourceElementsNode *n = this; n; n = n->elements)
03089 n->element->processFuncDecl(exec);
03090 }
03091
03092 void SourceElementsNode::processVarDecls(ExecState *exec)
03093 {
03094 for (SourceElementsNode *n = this; n; n = n->elements)
03095 n->element->processVarDecls(exec);
03096 }