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