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