38 #include "collector.h"
41 #include "function_object.h"
46 #include "interpreter.h"
48 #include "operations.h"
53 #define KJS_BREAKPOINT \
54 if (!hitStatement(exec)) \
55 return Completion(Normal);
57 #define KJS_ABORTPOINT \
58 if (exec->dynamicInterpreter()->imp()->debugger() && \
59 exec->dynamicInterpreter()->imp()->debugger()->imp()->aborted()) \
60 return Completion(Normal);
62 #define KJS_CHECKEXCEPTION \
63 if (exec->hadException()) { \
64 setExceptionDetailsIfNeeded(exec); \
65 return Completion(Throw, exec->exception()); \
67 if (Collector::outOfMemory()) \
68 return Completion(Throw, Error::create(exec,GeneralError,"Out of memory"));
70 #define KJS_CHECKEXCEPTIONVALUE \
71 if (exec->hadException()) { \
72 setExceptionDetailsIfNeeded(exec); \
73 return exec->exception(); \
75 if (Collector::outOfMemory()) \
76 return Undefined(); // will be picked up by KJS_CHECKEXCEPTION
78 #define KJS_CHECKEXCEPTIONREFERENCE \
79 if (exec->hadException()) { \
80 setExceptionDetailsIfNeeded(exec); \
81 return Reference::makeValueReference(Undefined()); \
83 if (Collector::outOfMemory()) \
84 return Reference::makeValueReference(Undefined()); // will be picked up by KJS_CHECKEXCEPTION
86 #define KJS_CHECKEXCEPTIONLIST \
87 if (exec->hadException()) { \
88 setExceptionDetailsIfNeeded(exec); \
91 if (Collector::outOfMemory()) \
92 return List(); // will be picked up by KJS_CHECKEXCEPTION
95 std::list<Node *> * Node::s_nodes = 0L;
102 line = Lexer::curr()->lineNo();
106 s_nodes =
new std::list<Node *>;
107 s_nodes->push_back(
this);
114 s_nodes->remove(
this );
120 Value v = evaluate(exec);
121 KJS_CHECKEXCEPTIONREFERENCE
122 return Reference::makeValueReference(v);
130 return evaluateReference(exec).getValue(exec);
133 bool Node::toBoolean(
ExecState *exec)
const
139 double Node::toNumber(
ExecState *exec)
const
142 return evaluate(exec).toNumber(exec);
147 return evaluate(exec).toString(exec);
151 void Node::finalCheck()
154 fprintf(stderr,
"Node::finalCheck(): list 0\n");
157 fprintf( stderr,
"[nodes] Node::finalCheck(): list count : %d\n", (
int)s_nodes->size() );
158 std::list<Node *>::iterator it = s_nodes->begin();
159 for ( uint i = 0; it != s_nodes->end() ; ++it, ++i )
160 fprintf( stderr,
"[nodes] [%d] Still having node %p (%s) (refcount %d)\n", i, (
void*)*it,
typeid( **it ).name(), (*it)->refcount );
166 Value Node::throwError(
ExecState *exec, ErrorType e,
const char *msg)
const
168 Object err = Error::create(exec, e, msg, lineNo(), sourceId());
169 exec->setException(err);
173 Value Node::throwError(
ExecState *exec, ErrorType e,
const char *msg,
174 const Value &v,
const Node *expr)
const
177 char *exprStr = strdup(expr->toCode().ascii());
179 int length = strlen(msg) - 4 + strlen(vStr) + strlen(exprStr) + 1 ;
180 char *str =
new char[length];
181 sprintf(str, msg, vStr, exprStr);
185 Value result = throwError(exec, e, str);
193 const char *l = label.
ascii();
194 int length = strlen(msg) - 2 + strlen(l) + 1 ;
195 char *message =
new char[length];
196 sprintf(message, msg, l);
198 Value result = throwError(exec, e, message);
205 void Node::setExceptionDetailsIfNeeded(
ExecState *exec)
const
207 if (exec->hadException()) {
211 exception.
put(exec,
"line",
Number(line));
218 StatementNode::StatementNode() : l0(-1), l1(-1), sourceCode(0), breakPoint(false)
222 StatementNode::~StatementNode()
228 void StatementNode::setLoc(
int line0,
int line1, SourceCode *src)
233 if (sourceCode != src) {
242 bool StatementNode::hitStatement(
ExecState *exec)
245 assert(exec->
context().imp()->sourceId == sourceCode->sid);
246 exec->
context().imp()->setLines(l0,l1);
249 return dbg->atStatement(exec);
255 bool StatementNode::abortStatement(
ExecState *exec)
259 return dbg->imp()->aborted();
264 void StatementNode::processFuncDecl(
ExecState *)
275 bool NullNode::toBoolean(
ExecState *)
const
280 double NullNode::toNumber(
ExecState *)
const
297 bool BooleanNode::toBoolean(
ExecState *)
const
302 double BooleanNode::toNumber(
ExecState *)
const
304 return val ? 1.0 : 0.0;
309 return val ?
"true" :
"false";
319 bool NumberNode::toBoolean(
ExecState *)
const
321 return !((val == 0) || isNaN(val));
324 double NumberNode::toNumber(
ExecState *)
const
341 bool StringNode::toBoolean(
ExecState *)
const
343 return !val.isEmpty();
346 double StringNode::toNumber(
ExecState *)
const
348 return val.toDouble();
370 bool RegExpNode::toBoolean(
ExecState *)
const
380 return exec->
context().imp()->thisValue();
388 return evaluateReference(exec).getValue(exec);
395 while (!chain.isEmpty()) {
396 ObjectImp *o = chain.top();
400 if (o->hasProperty(exec,ident)) {
411 cerr <<
"Resolve::evaluateReference: didn't find '" << ident.ustring().ascii() <<
"'" <<
endl;
418 void GroupNode::ref()
425 bool GroupNode::deref()
427 if ( group && group->deref() )
429 return Node::deref();
435 return group->evaluate(exec);
440 return group->evaluateReference(exec);
445 void ElementNode::ref()
447 for (ElementNode *n =
this; n; n = n->list) {
454 bool ElementNode::deref()
457 for (ElementNode *n =
this; n; n = next) {
459 if (n->node && n->node->deref())
461 if (n !=
this && n->Node::deref())
464 return Node::deref();
472 for (
const ElementNode *n =
this; n; n = n->list) {
473 Value val = n->node->evaluate(exec);
474 KJS_CHECKEXCEPTIONVALUE
475 length += n->elision;
476 array.
put(exec, length++, val);
483 void ArrayNode::ref()
490 bool ArrayNode::deref()
492 if ( element && element->deref() )
494 return Node::deref();
504 array =
Object(static_cast<ObjectImp*>(element->evaluate(exec).imp()));
505 KJS_CHECKEXCEPTIONVALUE
506 length = opt ? array.
get(exec,lengthPropertyName).
toInt32(exec) : 0;
509 array =
Object(static_cast<ObjectImp*>(newArr.imp()));
514 array.
put(exec,lengthPropertyName,
Number(elision + length), DontEnum | DontDelete);
521 void ObjectLiteralNode::ref()
528 bool ObjectLiteralNode::deref()
530 if ( list && list->deref() )
532 return Node::deref();
539 return list->evaluate(exec);
546 void PropertyValueNode::ref()
548 for (PropertyValueNode *n =
this; n; n = n->list) {
557 bool PropertyValueNode::deref()
559 PropertyValueNode *next;
560 for (PropertyValueNode *n =
this; n; n = next) {
562 if ( n->name && n->name->deref() )
564 if ( n->assign && n->assign->deref() )
566 if (n !=
this && n->Node::deref() )
569 return Node::deref();
577 for (
const PropertyValueNode *p =
this; p; p = p->list) {
578 Value n = p->name->evaluate(exec);
579 KJS_CHECKEXCEPTIONVALUE
580 Value v = p->assign->evaluate(exec);
581 KJS_CHECKEXCEPTIONVALUE
599 s =
String(str.ustring());
607 void AccessorNode1::ref()
616 bool AccessorNode1::deref()
618 if ( expr1 && expr1->deref() )
620 if ( expr2 && expr2->deref() )
622 return Node::deref();
628 Value v1 = expr1->evaluate(exec);
629 KJS_CHECKEXCEPTIONREFERENCE
630 Value v2 = expr2->evaluate(exec);
631 KJS_CHECKEXCEPTIONREFERENCE
634 if (v1.
isA(UndefinedType) || v1.
isA(NullType)) {
635 UString s =
"Attempted to access property on %s object "
636 "(result of expression %s)";
637 (void)throwError(exec, TypeError, s.
cstring().c_str(), v1,
this);
638 return Reference::makeValueReference(
Undefined());
651 void AccessorNode2::ref()
658 bool AccessorNode2::deref()
660 if ( expr && expr->deref() )
662 return Node::deref();
668 Value v = expr->evaluate(exec);
669 KJS_CHECKEXCEPTIONREFERENCE
673 if (v.
isA(UndefinedType) || v.
isA(NullType)) {
674 UString s =
"Attempted to access '" + ident.ustring() +
675 "' property on %s object (result of expression %s)";
676 (void)throwError(exec, TypeError, s.
cstring().c_str(), v,
this);
677 return Reference::makeValueReference(
Undefined());
686 void ArgumentListNode::ref()
688 for (ArgumentListNode *n =
this; n; n = n->list) {
695 bool ArgumentListNode::deref()
697 ArgumentListNode *next;
698 for (ArgumentListNode *n =
this; n; n = next) {
700 if (n->expr && n->expr->deref())
702 if (n !=
this && n->Node::deref())
705 return Node::deref();
719 for (
const ArgumentListNode *n =
this; n; n = n->list) {
720 Value v = n->expr->evaluate(exec);
721 KJS_CHECKEXCEPTIONLIST
730 void ArgumentsNode::ref()
737 bool ArgumentsNode::deref()
739 if ( list && list->deref() )
741 return Node::deref();
756 return list->evaluateList(exec);
763 void NewExprNode::ref()
772 bool NewExprNode::deref()
774 if ( expr && expr->deref() )
776 if ( args && args->deref() )
778 return Node::deref();
783 Value v = expr->evaluate(exec);
784 KJS_CHECKEXCEPTIONVALUE
788 argList = args->evaluateList(exec);
789 KJS_CHECKEXCEPTIONVALUE
792 if (v.
type() != ObjectType) {
793 return throwError(exec, TypeError,
"Value %s (result of expression %s) is not an object. Cannot be used with new.", v, expr);
796 Object constr =
Object(static_cast<ObjectImp*>(v.imp()));
798 return throwError(exec, TypeError,
"Value %s (result of expression %s) is not a constructor. Cannot be used with new.", v, expr);
808 void FunctionCallNode::ref()
817 bool FunctionCallNode::deref()
819 if ( expr && expr->deref() )
821 if ( args && args->deref() )
823 return Node::deref();
829 Reference ref = expr->evaluateReference(exec);
830 KJS_CHECKEXCEPTIONVALUE
832 List argList = args->evaluateList(exec);
833 KJS_CHECKEXCEPTIONVALUE
836 KJS_CHECKEXCEPTIONVALUE
838 if (v.type() != ObjectType) {
839 return throwError(exec, TypeError,
"Value %s (result of expression %s) is not an object. Cannot be called.", v, expr);
845 return throwError(exec, TypeError,
"Object %s (result of expression %s) does not allow calls.", v, expr);
854 if (thisVal.
type() == ObjectType &&
858 if (thisVal.
type() != ObjectType) {
870 Value result = func.
call(exec,thisObj, argList);
877 void PostfixNode::ref()
884 bool PostfixNode::deref()
886 if ( expr && expr->deref() )
888 return Node::deref();
894 Reference ref = expr->evaluateReference(exec);
895 KJS_CHECKEXCEPTIONVALUE
899 double newValue = (oper == OpPlusPlus) ? n + 1 : n - 1;
908 void DeleteNode::ref()
915 bool DeleteNode::deref()
917 if ( expr && expr->deref() )
919 return Node::deref();
925 Reference ref = expr->evaluateReference(exec);
926 KJS_CHECKEXCEPTIONVALUE
927 return Boolean(ref.deleteValue(exec));
939 bool VoidNode::deref()
941 if ( expr && expr->deref() )
943 return Node::deref();
949 Value dummy1 = expr->evaluate(exec);
950 KJS_CHECKEXCEPTIONVALUE
957 void TypeOfNode::ref()
964 bool TypeOfNode::deref()
966 if ( expr && expr->deref() )
968 return Node::deref();
975 Reference ref = expr->evaluateReference(exec);
976 KJS_CHECKEXCEPTIONVALUE
977 if (ref.isMutable()) {
979 if (b.
type() == NullType)
980 return String(
"undefined");
1001 if (v.
type() == ObjectType &&
static_cast<ObjectImp*
>(v.imp())->implementsCall())
1013 void PrefixNode::ref()
1020 bool PrefixNode::deref()
1022 if ( expr && expr->deref() )
1024 return Node::deref();
1030 Reference ref = expr->evaluateReference(exec);
1031 KJS_CHECKEXCEPTIONVALUE
1035 double newValue = (oper == OpPlusPlus) ? n + 1 : n - 1;
1045 void UnaryPlusNode::ref()
1052 bool UnaryPlusNode::deref()
1054 if ( expr && expr->deref() )
1056 return Node::deref();
1060 double UnaryPlusNode::toNumber(
ExecState *exec)
const
1062 return expr->toNumber(exec);
1068 Value v = expr->evaluate(exec);
1069 KJS_CHECKEXCEPTIONVALUE
1076 void NegateNode::ref()
1083 bool NegateNode::deref()
1085 if ( expr && expr->deref() )
1087 return Node::deref();
1091 double NegateNode::toNumber(
ExecState *exec)
const
1093 return -expr->toNumber(exec);
1098 Value v = expr->evaluate(exec);
1099 KJS_CHECKEXCEPTIONVALUE
1107 void BitwiseNotNode::ref()
1114 bool BitwiseNotNode::deref()
1116 if ( expr && expr->deref() )
1118 return Node::deref();
1124 Value v = expr->evaluate(exec);
1125 KJS_CHECKEXCEPTIONVALUE
1133 void LogicalNotNode::ref()
1140 bool LogicalNotNode::deref()
1142 if ( expr && expr->deref() )
1144 return Node::deref();
1148 bool LogicalNotNode::toBoolean(
ExecState *exec)
const
1150 return !expr->toBoolean(exec);
1157 KJS_CHECKEXCEPTIONVALUE
1164 void MultNode::ref()
1173 bool MultNode::deref()
1175 if ( term1 && term1->deref() )
1177 if ( term2 && term2->deref() )
1179 return Node::deref();
1185 Value v1 = term1->evaluate(exec);
1186 KJS_CHECKEXCEPTIONVALUE
1188 Value v2 = term2->evaluate(exec);
1189 KJS_CHECKEXCEPTIONVALUE
1191 return mult(exec,v1, v2, oper);
1197 Node* AddNode::create(Node *t1, Node *t2,
char op)
1201 if ((t1->type() == NumberType || t1->type() == BooleanType) &&
1202 (t2->type() == NumberType || t2->type() == BooleanType)) {
1203 double d = t2->toNumber(0);
1204 Node* n =
new NumberNode(t1->toNumber(0) + (op ==
'+' ? d : -d));
1210 if (op ==
'+' && t2->type() == StringType)
1211 return new AppendStringNode(t1, t2->toString(0));
1214 return new AddNode(t1, t2, op);
1226 bool AddNode::deref()
1228 if ( term1 && term1->deref() )
1230 if ( term2 && term2->deref() )
1232 return Node::deref();
1238 Value v1 = term1->evaluate(exec);
1239 KJS_CHECKEXCEPTIONVALUE
1241 Value v2 = term2->evaluate(exec);
1242 KJS_CHECKEXCEPTIONVALUE
1244 return add(exec,v1, v2, oper);
1249 void AppendStringNode::ref()
1255 bool AppendStringNode::deref()
1259 return Node::deref();
1265 UString s = term->toString(exec);
1266 KJS_CHECKEXCEPTIONVALUE
1273 void ShiftNode::ref()
1282 bool ShiftNode::deref()
1284 if ( term1 && term1->deref() )
1286 if ( term2 && term2->deref() )
1288 return Node::deref();
1294 Value v1 = term1->evaluate(exec);
1295 KJS_CHECKEXCEPTIONVALUE
1296 Value v2 = term2->evaluate(exec);
1297 KJS_CHECKEXCEPTIONVALUE
1298 unsigned int i2 = v2.toUInt32(exec);
1309 assert(!
"ShiftNode: unhandled switch case");
1316 void RelationalNode::ref()
1325 bool RelationalNode::deref()
1327 if ( expr1 && expr1->deref() )
1329 if ( expr2 && expr2->deref() )
1331 return Node::deref();
1337 Value v1 = expr1->evaluate(exec);
1338 KJS_CHECKEXCEPTIONVALUE
1339 Value v2 = expr2->evaluate(exec);
1340 KJS_CHECKEXCEPTIONVALUE
1343 if (oper == OpLess || oper == OpGreaterEq) {
1344 int r = relation(exec, v1, v2);
1348 b = (oper == OpLess) ? (r == 1) : (r == 0);
1349 }
else if (oper == OpGreater || oper == OpLessEq) {
1350 int r = relation(exec, v2, v1);
1354 b = (oper == OpGreater) ? (r == 1) : (r == 0);
1355 }
else if (oper == OpIn) {
1357 if (v2.type() != ObjectType)
1358 return throwError(exec, TypeError,
1359 "Value %s (result of expression %s) is not an object. Cannot be used with IN expression.", v2, expr2);
1360 Object o2(static_cast<ObjectImp*>(v2.imp()));
1363 if (v2.type() != ObjectType)
1364 return throwError(exec, TypeError,
1365 "Value %s (result of expression %s) is not an object. Cannot be used with instanceof operator.", v2, expr2);
1367 Object o2(static_cast<ObjectImp*>(v2.imp()));
1368 if (!o2.implementsHasInstance()) {
1377 return o2.hasInstance(exec, v1);
1385 void EqualNode::ref()
1394 bool EqualNode::deref()
1396 if ( expr1 && expr1->deref() )
1398 if ( expr2 && expr2->deref() )
1400 return Node::deref();
1406 Value v1 = expr1->evaluate(exec);
1407 KJS_CHECKEXCEPTIONVALUE
1408 Value v2 = expr2->evaluate(exec);
1409 KJS_CHECKEXCEPTIONVALUE
1412 if (oper == OpEqEq || oper == OpNotEq) {
1414 bool eq = equal(exec,v1, v2);
1415 result = oper == OpEqEq ? eq : !eq;
1418 bool eq = strictEqual(exec,v1, v2);
1419 result = oper == OpStrEq ? eq : !eq;
1426 void BitOperNode::ref()
1435 bool BitOperNode::deref()
1437 if ( expr1 && expr1->deref() )
1439 if ( expr2 && expr2->deref() )
1441 return Node::deref();
1447 Value v1 = expr1->evaluate(exec);
1448 KJS_CHECKEXCEPTIONVALUE
1449 Value v2 = expr2->evaluate(exec);
1450 KJS_CHECKEXCEPTIONVALUE
1452 int i2 = v2.toInt32(exec);
1454 if (oper == OpBitAnd)
1456 else if (oper == OpBitXOr)
1466 void BinaryLogicalNode::ref()
1475 bool BinaryLogicalNode::deref()
1477 if ( expr1 && expr1->deref() )
1479 if ( expr2 && expr2->deref() )
1481 return Node::deref();
1487 Value v1 = expr1->evaluate(exec);
1488 KJS_CHECKEXCEPTIONVALUE
1490 if ((!b1 && oper == OpAnd) || (b1 && oper == OpOr))
1493 Value v2 = expr2->evaluate(exec);
1494 KJS_CHECKEXCEPTIONVALUE
1501 void ConditionalNode::ref()
1512 bool ConditionalNode::deref()
1514 if ( expr1 && expr1->deref() )
1516 if ( expr2 && expr2->deref() )
1518 if ( logical && logical->deref() )
1520 return Node::deref();
1526 bool b = logical->toBoolean(exec);
1527 KJS_CHECKEXCEPTIONVALUE
1529 Value v = b ? expr1->evaluate(exec) : expr2->evaluate(exec);
1530 KJS_CHECKEXCEPTIONVALUE
1537 void AssignNode::ref()
1546 bool AssignNode::deref()
1548 if ( left && left->deref() )
1550 if ( expr && expr->deref() )
1552 return Node::deref();
1558 Reference l = left->evaluateReference(exec);
1559 KJS_CHECKEXCEPTIONVALUE
1561 if (oper == OpEqual) {
1562 v = expr->evaluate(exec);
1563 KJS_CHECKEXCEPTIONVALUE
1566 Value v2 = expr->evaluate(exec);
1567 KJS_CHECKEXCEPTIONVALUE
1573 v = mult(exec, v1, v2,
'*');
1576 v = mult(exec, v1, v2,
'/');
1579 v = add(exec, v1, v2,
'+');
1582 v = add(exec, v1, v2,
'-');
1626 KJS_CHECKEXCEPTIONVALUE
1633 void CommaNode::ref()
1642 bool CommaNode::deref()
1644 if ( expr1 && expr1->deref() )
1646 if ( expr2 && expr2->deref() )
1648 return Node::deref();
1654 (void) expr1->evaluate(exec);
1655 KJS_CHECKEXCEPTIONVALUE
1656 Value v = expr2->evaluate(exec);
1657 KJS_CHECKEXCEPTIONVALUE
1664 StatListNode::StatListNode(StatementNode *s)
1665 : statement(s), list(this)
1667 setLoc(s->firstLine(), s->lastLine(), s->code());
1670 StatListNode::StatListNode(StatListNode *l, StatementNode *s)
1671 : statement(s), list(l->list)
1674 setLoc(l->firstLine(),s->lastLine(),l->code());
1677 void StatListNode::ref()
1679 for (StatListNode *n =
this; n; n = n->list) {
1682 n->statement->ref();
1686 bool StatListNode::deref()
1689 for (StatListNode *n =
this; n; n = next) {
1691 if (n->statement && n->statement->deref())
1692 delete n->statement;
1693 if (n !=
this && n->Node::deref())
1696 return StatementNode::deref();
1704 if (exec->hadException()) {
1705 Value ex = exec->exception();
1706 exec->clearException();
1710 if (c.complType() != Normal)
1713 Value v = c.value();
1715 for (StatListNode *n = list; n; n = n->list) {
1718 if (c2.complType() != Normal)
1721 if (exec->hadException()) {
1722 Value ex = exec->exception();
1723 exec->clearException();
1727 if (c2.isValueCompletion())
1732 return Completion(c.complType(), v, c.target());
1735 void StatListNode::processVarDecls(
ExecState *exec)
1737 for (StatListNode *n =
this; n; n = n->list)
1738 n->statement->processVarDecls(exec);
1743 void AssignExprNode::ref()
1750 bool AssignExprNode::deref()
1752 if ( expr && expr->deref() )
1754 return Node::deref();
1760 return expr->evaluate(exec);
1765 VarDeclNode::VarDeclNode(
const Identifier &
id, AssignExprNode *in, Type t)
1766 : varType(t), ident(id), init(in)
1770 void VarDeclNode::ref()
1777 bool VarDeclNode::deref()
1779 if ( init && init->deref() )
1781 return Node::deref();
1791 val = init->evaluate(exec);
1792 KJS_CHECKEXCEPTIONVALUE
1795 if (variable.imp()->getDirect(ident))
1801 printInfo(exec,(
UString(
"new variable ")+ident.ustring()).cstring().c_str(),val);
1805 int flags = Internal;
1806 if (exec->
context().imp()->codeType() != EvalCode)
1807 flags |= DontDelete;
1808 if (varType == VarDeclNode::Constant)
1810 variable.
put(exec, ident, val, flags);
1818 void VarDeclNode::processVarDecls(
ExecState *exec)
1825 if (exec->_context->codeType() != EvalCode)
1826 flags |= DontDelete;
1827 if (varType == VarDeclNode::Constant)
1836 void VarDeclListNode::ref()
1838 for (VarDeclListNode *n =
this; n; n = n->list) {
1845 bool VarDeclListNode::deref()
1847 VarDeclListNode *next;
1848 for (VarDeclListNode *n =
this; n; n = next) {
1850 if (n->var && n->var->deref())
1852 if (n !=
this && n->Node::deref())
1855 return Node::deref();
1862 for (
const VarDeclListNode *n =
this; n; n = n->list) {
1863 (void)n->var->evaluate(exec);
1864 KJS_CHECKEXCEPTIONVALUE
1869 void VarDeclListNode::processVarDecls(
ExecState *exec)
1871 for (VarDeclListNode *n =
this; n; n = n->list)
1872 n->var->processVarDecls(exec);
1877 void VarStatementNode::ref()
1879 StatementNode::ref();
1884 bool VarStatementNode::deref()
1886 if ( list && list->deref() )
1888 return StatementNode::deref();
1896 (void) list->evaluate(exec);
1902 void VarStatementNode::processVarDecls(
ExecState *exec)
1904 list->processVarDecls(exec);
1909 BlockNode::BlockNode(SourceElementsNode *s)
1912 source = s->elements;
1914 setLoc(s->firstLine(), s->lastLine(), s->code());
1920 void BlockNode::ref()
1922 StatementNode::ref();
1927 bool BlockNode::deref()
1929 if ( source && source->deref() )
1931 return StatementNode::deref();
1940 source->processFuncDecl(exec);
1942 return source->execute(exec);
1945 void BlockNode::processVarDecls(
ExecState *exec)
1948 source->processVarDecls(exec);
1961 void ExprStatementNode::ref()
1963 StatementNode::ref();
1968 bool ExprStatementNode::deref()
1970 if ( expr && expr->deref() )
1972 return StatementNode::deref();
1980 Value v = expr->evaluate(exec);
1990 StatementNode::ref();
1999 bool IfNode::deref()
2001 if ( statement1 && statement1->deref() )
2003 if ( statement2 && statement2->deref() )
2005 if ( expr && expr->deref() )
2007 return StatementNode::deref();
2016 bool b = expr->toBoolean(exec);
2021 return statement1->execute(exec);
2028 return statement2->execute(exec);
2031 void IfNode::processVarDecls(
ExecState *exec)
2033 statement1->processVarDecls(exec);
2036 statement2->processVarDecls(exec);
2041 void DoWhileNode::ref()
2043 StatementNode::ref();
2050 bool DoWhileNode::deref()
2052 if ( statement && statement->deref() )
2054 if ( expr && expr->deref() )
2056 return StatementNode::deref();
2072 exec->
context().imp()->seenLabels()->pushIteration();
2073 c = statement->execute(exec);
2074 exec->
context().imp()->seenLabels()->popIteration();
2075 if (!((c.complType() == Continue) && ls.contains(c.target()))) {
2076 if ((c.complType() == Break) && ls.contains(c.target()))
2078 if (c.complType() != Normal)
2088 void DoWhileNode::processVarDecls(
ExecState *exec)
2090 statement->processVarDecls(exec);
2095 void WhileNode::ref()
2097 StatementNode::ref();
2104 bool WhileNode::deref()
2106 if ( statement && statement->deref() )
2108 if ( expr && expr->deref() )
2110 return StatementNode::deref();
2131 exec->
context().imp()->seenLabels()->pushIteration();
2132 c = statement->execute(exec);
2133 exec->
context().imp()->seenLabels()->popIteration();
2134 if (c.isValueCompletion())
2137 if ((c.complType() == Continue) && ls.contains(c.target()))
2139 if ((c.complType() == Break) && ls.contains(c.target()))
2141 if (c.complType() != Normal)
2146 void WhileNode::processVarDecls(
ExecState *exec)
2148 statement->processVarDecls(exec);
2155 StatementNode::ref();
2166 bool ForNode::deref()
2168 if ( statement && statement->deref() )
2170 if ( expr1 && expr1->deref() )
2172 if ( expr2 && expr2->deref() )
2174 if ( expr3 && expr3->deref() )
2176 return StatementNode::deref();
2185 v = expr1->evaluate(exec);
2190 bool b = expr2->toBoolean(exec);
2198 exec->
context().imp()->seenLabels()->pushIteration();
2200 exec->
context().imp()->seenLabels()->popIteration();
2201 if (c.isValueCompletion())
2203 if (!((c.complType() == Continue) && ls.contains(c.target()))) {
2204 if ((c.complType() == Break) && ls.contains(c.target()))
2206 if (c.complType() != Normal)
2210 v = expr3->evaluate(exec);
2216 void ForNode::processVarDecls(
ExecState *exec)
2219 expr1->processVarDecls(exec);
2221 statement->processVarDecls(exec);
2226 ForInNode::ForInNode(Node *l, Node *e, StatementNode *s)
2227 : init(0L), lexpr(l), expr(e), varDecl(0L), statement(s)
2231 ForInNode::ForInNode(
const Identifier &i, AssignExprNode *in, Node *e, StatementNode *s)
2232 : ident(i), init(in), expr(e), statement(s)
2235 varDecl =
new VarDeclNode(ident, init, VarDeclNode::Variable);
2236 lexpr =
new ResolveNode(ident);
2239 void ForInNode::ref()
2241 StatementNode::ref();
2254 bool ForInNode::deref()
2256 if ( statement && statement->deref() )
2258 if ( expr && expr->deref() )
2260 if ( lexpr && lexpr->deref() )
2262 if ( init && init->deref() )
2264 if ( varDecl && varDecl->deref() )
2266 return StatementNode::deref();
2276 (void)varDecl->evaluate(exec);
2280 Value v = expr->evaluate(exec);
2285 if (v.
isA(NullType) || v.
isA(UndefinedType))
2294 while (propIt != propList.end()) {
2301 Reference ref = lexpr->evaluateReference(exec);
2305 exec->
context().imp()->seenLabels()->pushIteration();
2306 c = statement->execute(exec);
2307 exec->
context().imp()->seenLabels()->popIteration();
2308 if (c.isValueCompletion())
2311 if (!((c.complType() == Continue) && ls.contains(c.target()))) {
2312 if ((c.complType() == Break) && ls.contains(c.target()))
2314 if (c.complType() != Normal) {
2328 void ForInNode::processVarDecls(
ExecState *exec)
2330 statement->processVarDecls(exec);
2342 if (ident.isEmpty() && !exec->
context().imp()->seenLabels()->inIteration())
2344 throwError(exec, SyntaxError,
"continue used outside of iteration statement"));
2345 else if (!ident.isEmpty() && !exec->
context().imp()->seenLabels()->
contains(ident))
2347 throwError(exec, SyntaxError,
"Label %s not found in containing block. Can't continue.", ident));
2361 if (ident.isEmpty() && !exec->
context().imp()->seenLabels()->inIteration() &&
2362 !exec->
context().imp()->seenLabels()->inSwitch())
2364 throwError(exec, SyntaxError,
"break used outside of iteration or switch statement"));
2365 else if (!ident.isEmpty() && !exec->
context().imp()->seenLabels()->
contains(ident))
2367 throwError(exec, SyntaxError,
"Label %s not found in containing block. Can't break.", ident));
2374 void ReturnNode::ref()
2376 StatementNode::ref();
2381 bool ReturnNode::deref()
2383 if ( value && value->deref() )
2385 return StatementNode::deref();
2393 CodeType codeType = exec->
context().imp()->codeType();
2394 if (codeType != FunctionCode) {
2395 return Completion(Throw, throwError(exec, SyntaxError,
"Invalid return statement."));
2401 Value v = value->evaluate(exec);
2409 void WithNode::ref()
2411 StatementNode::ref();
2418 bool WithNode::deref()
2420 if ( statement && statement->deref() )
2422 if ( expr && expr->deref() )
2424 return StatementNode::deref();
2432 Value v = expr->evaluate(exec);
2436 exec->
context().imp()->pushScope(o);
2438 exec->
context().imp()->popScope();
2443 void WithNode::processVarDecls(
ExecState *exec)
2445 statement->processVarDecls(exec);
2450 void CaseClauseNode::ref()
2459 bool CaseClauseNode::deref()
2461 if ( expr && expr->deref() )
2463 if ( list && list->deref() )
2465 return Node::deref();
2471 Value v = expr->evaluate(exec);
2472 KJS_CHECKEXCEPTIONVALUE
2481 return list->execute(exec);
2486 void CaseClauseNode::processVarDecls(
ExecState *exec)
2489 list->processVarDecls(exec);
2494 void ClauseListNode::ref()
2496 for (ClauseListNode *n =
this; n; n = n->nx) {
2503 bool ClauseListNode::deref()
2505 ClauseListNode *next;
2506 for (ClauseListNode *n =
this; n; n = next) {
2508 if (n->cl && n->cl->deref())
2510 if (n !=
this && n->Node::deref())
2513 return Node::deref();
2524 void ClauseListNode::processVarDecls(
ExecState *exec)
2526 for (ClauseListNode *n =
this; n; n = n->nx)
2528 n->cl->processVarDecls(exec);
2533 CaseBlockNode::CaseBlockNode(ClauseListNode *l1, CaseClauseNode *d,
2551 void CaseBlockNode::ref()
2562 bool CaseBlockNode::deref()
2564 if ( def && def->deref() )
2566 if ( list1 && list1->deref() )
2568 if ( list2 && list2->deref() )
2570 return Node::deref();
2585 ClauseListNode *a = list1, *b = list2;
2586 CaseClauseNode *clause;
2589 clause = a->clause();
2591 v = clause->evaluate(exec);
2593 if (strictEqual(exec, input, v)) {
2594 res = clause->evalStatements(exec);
2595 if (res.complType() != Normal)
2598 res = a->clause()->evalStatements(exec);
2599 if (res.complType() != Normal)
2608 clause = b->clause();
2610 v = clause->evaluate(exec);
2612 if (strictEqual(exec, input, v)) {
2613 res = clause->evalStatements(exec);
2614 if (res.complType() != Normal)
2622 res = def->evalStatements(exec);
2623 if (res.complType() != Normal)
2629 clause = b->clause();
2630 res = clause->evalStatements(exec);
2631 if (res.complType() != Normal)
2642 void CaseBlockNode::processVarDecls(
ExecState *exec)
2645 list1->processVarDecls(exec);
2647 def->processVarDecls(exec);
2649 list2->processVarDecls(exec);
2654 void SwitchNode::ref()
2656 StatementNode::ref();
2663 bool SwitchNode::deref()
2665 if ( expr && expr->deref() )
2667 if ( block && block->deref() )
2669 return StatementNode::deref();
2677 Value v = expr->evaluate(exec);
2679 exec->
context().imp()->seenLabels()->pushSwitch();
2681 exec->
context().imp()->seenLabels()->popSwitch();
2683 if ((res.complType() == Break) && ls.contains(res.target()))
2689 void SwitchNode::processVarDecls(
ExecState *exec)
2691 block->processVarDecls(exec);
2696 void LabelNode::ref()
2698 StatementNode::ref();
2703 bool LabelNode::deref()
2705 if ( statement && statement->deref() )
2707 return StatementNode::deref();
2715 if (!exec->
context().imp()->seenLabels()->
push(label)) {
2717 throwError(exec, SyntaxError,
"Duplicated label %s found.", label));
2719 e = statement->execute(exec);
2722 if ((e.complType() == Break) && (e.target() == label))
2728 void LabelNode::processVarDecls(
ExecState *exec)
2730 statement->processVarDecls(exec);
2735 void ThrowNode::ref()
2737 StatementNode::ref();
2742 bool ThrowNode::deref()
2744 if ( expr && expr->deref() )
2746 return StatementNode::deref();
2754 Value v = expr->evaluate(exec);
2760 Debugger *dbg = exec->interpreter()->imp()->debugger();
2762 dbg->exception(exec,v,exec->
context().imp()->inTryCatch());
2769 void CatchNode::ref()
2771 StatementNode::ref();
2776 bool CatchNode::deref()
2778 if ( block && block->deref() )
2780 return StatementNode::deref();
2795 exec->clearException();
2797 Object obj(
new ObjectImp());
2798 obj.
put(exec, ident, arg, DontDelete);
2799 exec->
context().imp()->pushScope(obj);
2801 exec->
context().imp()->popScope();
2806 void CatchNode::processVarDecls(
ExecState *exec)
2808 block->processVarDecls(exec);
2813 void FinallyNode::ref()
2815 StatementNode::ref();
2820 bool FinallyNode::deref()
2822 if ( block && block->deref() )
2824 return StatementNode::deref();
2830 return block->execute(exec);
2833 void FinallyNode::processVarDecls(
ExecState *exec)
2835 block->processVarDecls(exec);
2842 StatementNode::ref();
2851 bool TryNode::deref()
2853 if ( block && block->deref() )
2855 if ( _final && _final->deref() )
2857 if ( _catch && _catch->deref() )
2859 return StatementNode::deref();
2870 exec->
context().imp()->pushTryCatch();
2871 c = block->execute(exec);
2873 exec->
context().imp()->popTryCatch();
2876 if (c.complType() != Throw)
2878 return _catch->execute(exec,c.value());
2882 Value exception = exec->_exception;
2883 exec->_exception =
Value();
2885 c2 = _final->execute(exec);
2887 if (!exec->hadException() && c2.complType() != Throw)
2888 exec->_exception = exception;
2890 return (c2.complType() == Normal) ? c : c2;
2893 if (c.complType() == Throw)
2894 c = _catch->execute(exec,c.value());
2896 c2 = _final->execute(exec);
2897 return (c2.complType() == Normal) ? c : c2;
2900 void TryNode::processVarDecls(
ExecState *exec)
2902 block->processVarDecls(exec);
2904 _final->processVarDecls(exec);
2906 _catch->processVarDecls(exec);
2911 void ParameterNode::ref()
2913 for (ParameterNode *n =
this; n; n = n->next)
2917 bool ParameterNode::deref()
2919 ParameterNode *next;
2920 for (ParameterNode *n =
this; n; n = next) {
2922 if (n !=
this && n->Node::deref())
2925 return Node::deref();
2937 FunctionBodyNode::FunctionBodyNode(SourceElementsNode *s)
2943 void FunctionBodyNode::processFuncDecl(
ExecState *exec)
2946 source->processFuncDecl(exec);
2951 void FuncDeclNode::ref()
2953 StatementNode::ref();
2960 bool FuncDeclNode::deref()
2962 if ( param && param->deref() )
2964 if ( body && body->deref() )
2966 return StatementNode::deref();
2970 void FuncDeclNode::processFuncDecl(
ExecState *exec)
2974 FunctionImp *fimp =
new DeclaredFunctionImp(exec, ident, body, exec->
context().imp()->scopeChain());
2980 proto.
put(exec, constructorPropertyName, func, ReadOnly|DontDelete|DontEnum);
2981 func.
put(exec, prototypePropertyName, proto, Internal|DontDelete);
2984 for(
const ParameterNode *p = param; p != 0L; p = p->nextParam(), plen++)
2985 fimp->addParameter(p->ident());
2987 func.
put(exec, lengthPropertyName,
Number(plen), ReadOnly|DontDelete|DontEnum);
2990 fprintf(stderr,
"KJS: new function %s in %p\n", ident.ustring().cstring().c_str(), ctx->variableObject().imp());
2992 if (exec->_context->codeType() == EvalCode) {
2994 ctx->variableObject().
put(exec, ident, func, Internal);
2996 ctx->variableObject().
put(exec, ident, func, DontDelete | Internal);
3002 Object oldVar = ctx->variableObject();
3003 ctx->setVariableObject(func);
3004 ctx->pushScope(func);
3005 body->processFuncDecl(exec);
3007 ctx->setVariableObject(oldVar);
3013 void FuncExprNode::ref()
3022 bool FuncExprNode::deref()
3024 if ( param && param->deref() )
3026 if ( body && body->deref() )
3028 return Node::deref();
3036 bool named = !ident.isNull();
3037 Object functionScopeObject;
3043 functionScopeObject =
Object(
new ObjectImp());
3044 context->pushScope(functionScopeObject);
3051 fimp->put(exec, prototypePropertyName, proto, Internal|DontDelete);
3053 for(
const ParameterNode *p = param; p != 0L; p = p->nextParam())
3054 fimp->addParameter(p->ident());
3057 functionScopeObject.
put(exec, ident,
Value(fimp), ReadOnly|DontDelete);
3058 context->popScope();
3066 SourceElementsNode::SourceElementsNode(StatementNode *s1)
3070 setLoc(s1->firstLine(), s1->lastLine(), s1->code());
3073 SourceElementsNode::SourceElementsNode(SourceElementsNode *s1, StatementNode *s2)
3075 elements = s1->elements;
3076 s1->elements =
this;
3078 setLoc(s1->firstLine(), s2->lastLine(), s1->code());
3081 void SourceElementsNode::ref()
3083 for (SourceElementsNode *n =
this; n; n = n->elements) {
3090 bool SourceElementsNode::deref()
3092 SourceElementsNode *next;
3093 for (SourceElementsNode *n =
this; n; n = next) {
3095 if (n->element && n->element->deref())
3097 if (n !=
this && n->Node::deref())
3100 return StatementNode::deref();
3110 if (c1.complType() != Normal)
3113 for (SourceElementsNode *n = elements; n; n = n->elements) {
3115 if (c2.complType() != Normal)
3127 void SourceElementsNode::processFuncDecl(
ExecState *exec)
3129 for (SourceElementsNode *n =
this; n; n = n->elements)
3130 n->element->processFuncDecl(exec);
3133 void SourceElementsNode::processVarDecls(
ExecState *exec)
3135 for (SourceElementsNode *n =
this; n; n = n->elements)
3136 n->element->processVarDecls(exec);