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