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