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_CHECKEXCEPTIONVALUE
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 }