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