37 #include "collector.h"
40 #include "function_object.h"
45 #include "interpreter.h"
47 #include "operations.h"
52 #define KJS_BREAKPOINT \
53 if (!hitStatement(exec)) \
54 return Completion(Normal);
56 #define KJS_ABORTPOINT \
57 if (exec->dynamicInterpreter()->imp()->debugger() && \
58 exec->dynamicInterpreter()->imp()->debugger()->imp()->aborted()) \
59 return Completion(Normal);
61 #define KJS_CHECKEXCEPTION \
62 if (exec->hadException()) { \
63 setExceptionDetailsIfNeeded(exec); \
64 return Completion(Throw, exec->exception()); \
66 if (Collector::outOfMemory()) \
67 return Completion(Throw, Error::create(exec,GeneralError,"Out of memory"));
69 #define KJS_CHECKEXCEPTIONVALUE \
70 if (exec->hadException()) { \
71 setExceptionDetailsIfNeeded(exec); \
72 return exec->exception(); \
74 if (Collector::outOfMemory()) \
75 return Undefined(); // will be picked up by KJS_CHECKEXCEPTION
77 #define KJS_CHECKEXCEPTIONREFERENCE \
78 if (exec->hadException()) { \
79 setExceptionDetailsIfNeeded(exec); \
80 return Reference::makeValueReference(Undefined()); \
82 if (Collector::outOfMemory()) \
83 return Reference::makeValueReference(Undefined()); // will be picked up by KJS_CHECKEXCEPTION
85 #define KJS_CHECKEXCEPTIONLIST \
86 if (exec->hadException()) { \
87 setExceptionDetailsIfNeeded(exec); \
90 if (Collector::outOfMemory()) \
91 return List(); // will be picked up by KJS_CHECKEXCEPTION
94 std::list<Node *> * Node::s_nodes = 0L;
101 line = Lexer::curr()->lineNo();
105 s_nodes =
new std::list<Node *>;
106 s_nodes->push_back(
this);
113 s_nodes->remove(
this );
119 Value v = evaluate(exec);
120 KJS_CHECKEXCEPTIONREFERENCE
121 return Reference::makeValueReference(v);
129 return evaluateReference(exec).getValue(exec);
132 bool Node::toBoolean(
ExecState *exec)
const
138 double Node::toNumber(
ExecState *exec)
const
141 return evaluate(exec).toNumber(exec);
146 return evaluate(exec).toString(exec);
150 void Node::finalCheck()
153 fprintf(stderr,
"Node::finalCheck(): list 0\n");
156 fprintf( stderr,
"[nodes] Node::finalCheck(): list count : %d\n", (
int)s_nodes->size() );
157 std::list<Node *>::iterator it = s_nodes->begin();
158 for ( uint i = 0; it != s_nodes->end() ; ++it, ++i )
159 fprintf( stderr,
"[nodes] [%d] Still having node %p (%s) (refcount %d)\n", i, (
void*)*it,
typeid( **it ).name(), (*it)->refcount );
165 Value Node::throwError(
ExecState *exec, ErrorType e,
const char *msg)
const
167 Object err = Error::create(exec, e, msg, lineNo(), sourceId());
168 exec->setException(err);
172 Value Node::throwError(
ExecState *exec, ErrorType e,
const char *msg,
173 const Value &v,
const Node *expr)
const
176 char *exprStr = strdup(expr->toCode().ascii());
178 int length = strlen(msg) - 4 + strlen(vStr) + strlen(exprStr) + 1 ;
179 char *str =
new char[length];
180 sprintf(str, msg, vStr, exprStr);
184 Value result = throwError(exec, e, str);
192 const char *l =
label.ascii();
193 int length = strlen(msg) - 2 + strlen(l) + 1 ;
194 char *message =
new char[length];
195 sprintf(message, msg, l);
197 Value result = throwError(exec, e, message);
204 void Node::setExceptionDetailsIfNeeded(
ExecState *exec)
const
206 if (exec->hadException()) {
210 exception.
put(exec,
"line",
Number(line));
217 StatementNode::StatementNode() : l0(-1), l1(-1), sourceCode(0), breakPoint(false)
221 StatementNode::~StatementNode()
227 void StatementNode::setLoc(
int line0,
int line1, SourceCode *src)
232 if (sourceCode != src) {
241 bool StatementNode::hitStatement(
ExecState *exec)
244 assert(exec->
context().imp()->sourceId == sourceCode->sid);
245 exec->
context().imp()->setLines(l0,l1);
248 return dbg->atStatement(exec);
254 bool StatementNode::abortStatement(
ExecState *exec)
258 return dbg->imp()->aborted();
263 void StatementNode::processFuncDecl(
ExecState *)
274 bool NullNode::toBoolean(
ExecState *)
const
279 double NullNode::toNumber(
ExecState *)
const
296 bool BooleanNode::toBoolean(
ExecState *)
const
301 double BooleanNode::toNumber(
ExecState *)
const
303 return val ? 1.0 : 0.0;
308 return val ?
"true" :
"false";
318 bool NumberNode::toBoolean(
ExecState *)
const
320 return !((val == 0) || isNaN(val));
323 double NumberNode::toNumber(
ExecState *)
const
340 bool StringNode::toBoolean(
ExecState *)
const
342 return !val.isEmpty();
345 double StringNode::toNumber(
ExecState *)
const
347 return val.toDouble();
369 bool RegExpNode::toBoolean(
ExecState *)
const
379 return exec->
context().imp()->thisValue();
387 return evaluateReference(exec).getValue(exec);
394 while (!chain.isEmpty()) {
395 ObjectImp *o = chain.top();
399 if (o->hasProperty(exec,ident)) {
410 cerr <<
"Resolve::evaluateReference: didn't find '" << ident.ustring().ascii() <<
"'" <<
endl;
417 void GroupNode::ref()
424 bool GroupNode::deref()
426 if ( group && group->deref() )
428 return Node::deref();
434 return group->evaluate(exec);
439 return group->evaluateReference(exec);
444 void ElementNode::ref()
446 for (ElementNode *n =
this; n; n = n->list) {
453 bool ElementNode::deref()
456 for (ElementNode *n =
this; n; n =
next) {
458 if (n->node && n->node->deref())
460 if (n !=
this && n->Node::deref())
463 return Node::deref();
471 for (
const ElementNode *n =
this; n; n = n->list) {
472 Value val = n->node->evaluate(exec);
473 KJS_CHECKEXCEPTIONVALUE
474 length += n->elision;
475 array.
put(exec, length++, val);
482 void ArrayNode::ref()
489 bool ArrayNode::deref()
491 if ( element && element->deref() )
493 return Node::deref();
503 array =
Object(
static_cast<ObjectImp*
>(element->evaluate(exec).imp()));
504 KJS_CHECKEXCEPTIONVALUE
505 length = opt ? array.
get(exec,lengthPropertyName).
toInt32(exec) : 0;
508 array =
Object(
static_cast<ObjectImp*
>(newArr.imp()));
513 array.
put(exec,lengthPropertyName,
Number(elision + length), DontEnum | DontDelete);
520 void ObjectLiteralNode::ref()
527 bool ObjectLiteralNode::deref()
529 if ( list && list->deref() )
531 return Node::deref();
538 return list->evaluate(exec);
545 void PropertyValueNode::ref()
547 for (PropertyValueNode *n =
this; n; n = n->list) {
556 bool PropertyValueNode::deref()
558 PropertyValueNode *
next;
559 for (PropertyValueNode *n =
this; n; n =
next) {
561 if ( n->name && n->name->deref() )
563 if ( n->assign && n->assign->deref() )
565 if (n !=
this && n->Node::deref() )
568 return Node::deref();
576 for (
const PropertyValueNode *p =
this; p; p = p->list) {
577 Value n = p->name->evaluate(exec);
578 KJS_CHECKEXCEPTIONVALUE
579 Value v = p->assign->evaluate(exec);
580 KJS_CHECKEXCEPTIONVALUE
598 s =
String(str.ustring());
606 void AccessorNode1::ref()
615 bool AccessorNode1::deref()
617 if ( expr1 && expr1->deref() )
619 if ( expr2 && expr2->deref() )
621 return Node::deref();
627 Value v1 = expr1->evaluate(exec);
628 KJS_CHECKEXCEPTIONREFERENCE
629 Value v2 = expr2->evaluate(exec);
630 KJS_CHECKEXCEPTIONREFERENCE
633 if (v1.
isA(UndefinedType) || v1.
isA(NullType)) {
634 UString s =
"Attempted to access property on %s object "
635 "(result of expression %s)";
636 (void)throwError(exec, TypeError, s.
cstring().c_str(), v1,
this);
637 return Reference::makeValueReference(
Undefined());
650 void AccessorNode2::ref()
657 bool AccessorNode2::deref()
659 if ( expr && expr->deref() )
661 return Node::deref();
667 Value v = expr->evaluate(exec);
668 KJS_CHECKEXCEPTIONREFERENCE
672 if (v.
isA(UndefinedType) || v.
isA(NullType)) {
673 UString s =
"Attempted to access '" + ident.ustring() +
674 "' property on %s object (result of expression %s)";
675 (void)throwError(exec, TypeError, s.
cstring().c_str(), v,
this);
676 return Reference::makeValueReference(
Undefined());
685 void ArgumentListNode::ref()
687 for (ArgumentListNode *n =
this; n; n = n->list) {
694 bool ArgumentListNode::deref()
696 ArgumentListNode *
next;
697 for (ArgumentListNode *n =
this; n; n =
next) {
699 if (n->expr && n->expr->deref())
701 if (n !=
this && n->Node::deref())
704 return Node::deref();
718 for (
const ArgumentListNode *n =
this; n; n = n->list) {
719 Value v = n->expr->evaluate(exec);
720 KJS_CHECKEXCEPTIONLIST
729 void ArgumentsNode::ref()
736 bool ArgumentsNode::deref()
738 if ( list && list->deref() )
740 return Node::deref();
755 return list->evaluateList(exec);
762 void NewExprNode::ref()
771 bool NewExprNode::deref()
773 if ( expr && expr->deref() )
775 if ( args && args->deref() )
777 return Node::deref();
782 Value v = expr->evaluate(exec);
783 KJS_CHECKEXCEPTIONVALUE
787 argList = args->evaluateList(exec);
788 KJS_CHECKEXCEPTIONVALUE
791 if (v.
type() != ObjectType) {
792 return throwError(exec, TypeError,
"Value %s (result of expression %s) is not an object. Cannot be used with new.", v, expr);
795 Object constr =
Object(
static_cast<ObjectImp*
>(v.imp()));
797 return throwError(exec, TypeError,
"Value %s (result of expression %s) is not a constructor. Cannot be used with new.", v, expr);
807 void FunctionCallNode::ref()
816 bool FunctionCallNode::deref()
818 if ( expr && expr->deref() )
820 if ( args && args->deref() )
822 return Node::deref();
828 Reference ref = expr->evaluateReference(exec);
829 KJS_CHECKEXCEPTIONVALUE
831 List argList = args->evaluateList(exec);
832 KJS_CHECKEXCEPTIONVALUE
835 KJS_CHECKEXCEPTIONVALUE
837 if (v.type() != ObjectType) {
838 return throwError(exec, TypeError,
"Value %s (result of expression %s) is not an object. Cannot be called.", v, expr);
844 return throwError(exec, TypeError,
"Object %s (result of expression %s) does not allow calls.", v, expr);
853 if (thisVal.
type() == ObjectType &&
857 if (thisVal.
type() != ObjectType) {
869 Value result = func.
call(exec,thisObj, argList);
876 void PostfixNode::ref()
883 bool PostfixNode::deref()
885 if ( expr && expr->deref() )
887 return Node::deref();
893 Reference ref = expr->evaluateReference(exec);
894 KJS_CHECKEXCEPTIONVALUE
898 double newValue = (oper == OpPlusPlus) ? n + 1 : n - 1;
907 void DeleteNode::ref()
914 bool DeleteNode::deref()
916 if ( expr && expr->deref() )
918 return Node::deref();
924 Reference ref = expr->evaluateReference(exec);
925 KJS_CHECKEXCEPTIONVALUE
926 return Boolean(ref.deleteValue(exec));
938 bool VoidNode::deref()
940 if ( expr && expr->deref() )
942 return Node::deref();
948 Value dummy1 = expr->evaluate(exec);
949 KJS_CHECKEXCEPTIONVALUE
956 void TypeOfNode::ref()
963 bool TypeOfNode::deref()
965 if ( expr && expr->deref() )
967 return Node::deref();
974 Reference ref = expr->evaluateReference(exec);
975 KJS_CHECKEXCEPTIONVALUE
976 if (ref.isMutable()) {
978 if (b.
type() == NullType)
979 return String(
"undefined");
1000 if (v.
type() == ObjectType &&
static_cast<ObjectImp*
>(v.imp())->implementsCall())
1012 void PrefixNode::ref()
1019 bool PrefixNode::deref()
1021 if ( expr && expr->deref() )
1023 return Node::deref();
1029 Reference ref = expr->evaluateReference(exec);
1030 KJS_CHECKEXCEPTIONVALUE
1034 double newValue = (oper == OpPlusPlus) ? n + 1 : n - 1;
1044 void UnaryPlusNode::ref()
1051 bool UnaryPlusNode::deref()
1053 if ( expr && expr->deref() )
1055 return Node::deref();
1059 double UnaryPlusNode::toNumber(
ExecState *exec)
const
1061 return expr->toNumber(exec);
1067 Value v = expr->evaluate(exec);
1068 KJS_CHECKEXCEPTIONVALUE
1075 void NegateNode::ref()
1082 bool NegateNode::deref()
1084 if ( expr && expr->deref() )
1086 return Node::deref();
1090 double NegateNode::toNumber(
ExecState *exec)
const
1092 return -expr->toNumber(exec);
1097 Value v = expr->evaluate(exec);
1098 KJS_CHECKEXCEPTIONVALUE
1106 void BitwiseNotNode::ref()
1113 bool BitwiseNotNode::deref()
1115 if ( expr && expr->deref() )
1117 return Node::deref();
1123 Value v = expr->evaluate(exec);
1124 KJS_CHECKEXCEPTIONVALUE
1132 void LogicalNotNode::ref()
1139 bool LogicalNotNode::deref()
1141 if ( expr && expr->deref() )
1143 return Node::deref();
1147 bool LogicalNotNode::toBoolean(
ExecState *exec)
const
1149 return !expr->toBoolean(exec);
1156 KJS_CHECKEXCEPTIONVALUE
1163 void MultNode::ref()
1172 bool MultNode::deref()
1174 if ( term1 && term1->deref() )
1176 if ( term2 && term2->deref() )
1178 return Node::deref();
1184 Value v1 = term1->evaluate(exec);
1185 KJS_CHECKEXCEPTIONVALUE
1187 Value v2 = term2->evaluate(exec);
1188 KJS_CHECKEXCEPTIONVALUE
1190 return mult(exec,v1, v2, oper);
1196 Node* AddNode::create(Node *t1, Node *t2,
char op)
1200 if ((t1->type() == NumberType || t1->type() == BooleanType) &&
1201 (t2->type() == NumberType || t2->type() == BooleanType)) {
1202 double d = t2->toNumber(0);
1203 Node* n =
new NumberNode(t1->toNumber(0) + (op ==
'+' ? d : -d));
1209 if (op ==
'+' && t2->type() == StringType)
1210 return new AppendStringNode(t1, t2->toString(0));
1213 return new AddNode(t1, t2, op);
1225 bool AddNode::deref()
1227 if ( term1 && term1->deref() )
1229 if ( term2 && term2->deref() )
1231 return Node::deref();
1237 Value v1 = term1->evaluate(exec);
1238 KJS_CHECKEXCEPTIONVALUE
1240 Value v2 = term2->evaluate(exec);
1241 KJS_CHECKEXCEPTIONVALUE
1243 return add(exec,v1, v2, oper);
1248 void AppendStringNode::ref()
1254 bool AppendStringNode::deref()
1258 return Node::deref();
1264 UString s = term->toString(exec);
1265 KJS_CHECKEXCEPTIONVALUE
1272 void ShiftNode::ref()
1281 bool ShiftNode::deref()
1283 if ( term1 && term1->deref() )
1285 if ( term2 && term2->deref() )
1287 return Node::deref();
1293 Value v1 = term1->evaluate(exec);
1294 KJS_CHECKEXCEPTIONVALUE
1295 Value v2 = term2->evaluate(exec);
1296 KJS_CHECKEXCEPTIONVALUE
1297 unsigned int i2 = v2.toUInt32(exec);
1308 assert(!
"ShiftNode: unhandled switch case");
1315 void RelationalNode::ref()
1324 bool RelationalNode::deref()
1326 if ( expr1 && expr1->deref() )
1328 if ( expr2 && expr2->deref() )
1330 return Node::deref();
1336 Value v1 = expr1->evaluate(exec);
1337 KJS_CHECKEXCEPTIONVALUE
1338 Value v2 = expr2->evaluate(exec);
1339 KJS_CHECKEXCEPTIONVALUE
1342 if (oper == OpLess || oper == OpGreaterEq) {
1343 int r = relation(exec, v1, v2);
1347 b = (oper == OpLess) ? (r == 1) : (r == 0);
1348 }
else if (oper == OpGreater || oper == OpLessEq) {
1349 int r = relation(exec, v2, v1);
1353 b = (oper == OpGreater) ? (r == 1) : (r == 0);
1354 }
else if (oper == OpIn) {
1356 if (v2.type() != ObjectType)
1357 return throwError(exec, TypeError,
1358 "Value %s (result of expression %s) is not an object. Cannot be used with IN expression.", v2, expr2);
1359 Object o2(
static_cast<ObjectImp*
>(v2.imp()));
1362 if (v2.type() != ObjectType)
1363 return throwError(exec, TypeError,
1364 "Value %s (result of expression %s) is not an object. Cannot be used with instanceof operator.", v2, expr2);
1366 Object o2(
static_cast<ObjectImp*
>(v2.imp()));
1367 if (!o2.implementsHasInstance()) {
1376 return o2.hasInstance(exec, v1);
1384 void EqualNode::ref()
1393 bool EqualNode::deref()
1395 if ( expr1 && expr1->deref() )
1397 if ( expr2 && expr2->deref() )
1399 return Node::deref();
1405 Value v1 = expr1->evaluate(exec);
1406 KJS_CHECKEXCEPTIONVALUE
1407 Value v2 = expr2->evaluate(exec);
1408 KJS_CHECKEXCEPTIONVALUE
1411 if (oper == OpEqEq || oper == OpNotEq) {
1413 bool eq = equal(exec,v1, v2);
1414 result = oper == OpEqEq ? eq : !eq;
1417 bool eq = strictEqual(exec,v1, v2);
1418 result = oper == OpStrEq ? eq : !eq;
1425 void BitOperNode::ref()
1434 bool BitOperNode::deref()
1436 if ( expr1 && expr1->deref() )
1438 if ( expr2 && expr2->deref() )
1440 return Node::deref();
1446 Value v1 = expr1->evaluate(exec);
1447 KJS_CHECKEXCEPTIONVALUE
1448 Value v2 = expr2->evaluate(exec);
1449 KJS_CHECKEXCEPTIONVALUE
1451 int i2 = v2.toInt32(exec);
1453 if (oper == OpBitAnd)
1455 else if (oper == OpBitXOr)
1465 void BinaryLogicalNode::ref()
1474 bool BinaryLogicalNode::deref()
1476 if ( expr1 && expr1->deref() )
1478 if ( expr2 && expr2->deref() )
1480 return Node::deref();
1486 Value v1 = expr1->evaluate(exec);
1487 KJS_CHECKEXCEPTIONVALUE
1489 if ((!b1 && oper == OpAnd) || (b1 && oper == OpOr))
1492 Value v2 = expr2->evaluate(exec);
1493 KJS_CHECKEXCEPTIONVALUE
1500 void ConditionalNode::ref()
1511 bool ConditionalNode::deref()
1513 if ( expr1 && expr1->deref() )
1515 if ( expr2 && expr2->deref() )
1517 if ( logical && logical->deref() )
1519 return Node::deref();
1525 bool b = logical->toBoolean(exec);
1526 KJS_CHECKEXCEPTIONVALUE
1528 Value v = b ? expr1->evaluate(exec) : expr2->evaluate(exec);
1529 KJS_CHECKEXCEPTIONVALUE
1536 void AssignNode::ref()
1545 bool AssignNode::deref()
1547 if ( left && left->deref() )
1549 if ( expr && expr->deref() )
1551 return Node::deref();
1557 Reference l = left->evaluateReference(exec);
1558 KJS_CHECKEXCEPTIONVALUE
1560 if (oper == OpEqual) {
1561 v = expr->evaluate(exec);
1562 KJS_CHECKEXCEPTIONVALUE
1565 Value v2 = expr->evaluate(exec);
1566 KJS_CHECKEXCEPTIONVALUE
1572 v = mult(exec, v1, v2,
'*');
1575 v = mult(exec, v1, v2,
'/');
1578 v = add(exec, v1, v2,
'+');
1581 v = add(exec, v1, v2,
'-');
1625 KJS_CHECKEXCEPTIONVALUE
1632 void CommaNode::ref()
1641 bool CommaNode::deref()
1643 if ( expr1 && expr1->deref() )
1645 if ( expr2 && expr2->deref() )
1647 return Node::deref();
1653 (void) expr1->evaluate(exec);
1654 KJS_CHECKEXCEPTIONVALUE
1655 Value v = expr2->evaluate(exec);
1656 KJS_CHECKEXCEPTIONVALUE
1663 StatListNode::StatListNode(StatementNode *s)
1664 : statement(s), list(this)
1666 setLoc(s->firstLine(), s->lastLine(), s->code());
1669 StatListNode::StatListNode(StatListNode *l, StatementNode *s)
1670 : statement(s), list(l->list)
1673 setLoc(l->firstLine(),s->lastLine(),l->code());
1676 void StatListNode::ref()
1678 for (StatListNode *n =
this; n; n = n->list) {
1681 n->statement->ref();
1685 bool StatListNode::deref()
1688 for (StatListNode *n =
this; n; n =
next) {
1690 if (n->statement && n->statement->deref())
1691 delete n->statement;
1692 if (n !=
this && n->Node::deref())
1695 return StatementNode::deref();
1703 if (exec->hadException()) {
1704 Value ex = exec->exception();
1705 exec->clearException();
1709 if (c.complType() != Normal)
1712 Value v = c.value();
1714 for (StatListNode *n = list; n; n = n->list) {
1717 if (c2.complType() != Normal)
1720 if (exec->hadException()) {
1721 Value ex = exec->exception();
1722 exec->clearException();
1726 if (c2.isValueCompletion())
1731 return Completion(c.complType(), v, c.target());
1734 void StatListNode::processVarDecls(
ExecState *exec)
1736 for (StatListNode *n =
this; n; n = n->list)
1737 n->statement->processVarDecls(exec);
1742 void AssignExprNode::ref()
1749 bool AssignExprNode::deref()
1751 if ( expr && expr->deref() )
1753 return Node::deref();
1759 return expr->evaluate(exec);
1764 VarDeclNode::VarDeclNode(
const Identifier &
id, AssignExprNode *in, Type t)
1765 : varType(t), ident(id), init(in)
1769 void VarDeclNode::ref()
1776 bool VarDeclNode::deref()
1778 if ( init && init->deref() )
1780 return Node::deref();
1790 val = init->evaluate(exec);
1791 KJS_CHECKEXCEPTIONVALUE
1794 if (variable.imp()->getDirect(ident))
1800 printInfo(exec,(
UString(
"new variable ")+ident.ustring()).cstring().c_str(),val);
1804 int flags = Internal;
1805 if (exec->
context().imp()->codeType() != EvalCode)
1806 flags |= DontDelete;
1807 if (varType == VarDeclNode::Constant)
1809 variable.
put(exec, ident, val, flags);
1817 void VarDeclNode::processVarDecls(
ExecState *exec)
1824 if (exec->_context->codeType() != EvalCode)
1825 flags |= DontDelete;
1826 if (varType == VarDeclNode::Constant)
1835 void VarDeclListNode::ref()
1837 for (VarDeclListNode *n =
this; n; n = n->list) {
1844 bool VarDeclListNode::deref()
1846 VarDeclListNode *
next;
1847 for (VarDeclListNode *n =
this; n; n =
next) {
1849 if (n->var && n->var->deref())
1851 if (n !=
this && n->Node::deref())
1854 return Node::deref();
1861 for (
const VarDeclListNode *n =
this; n; n = n->list) {
1862 (void)n->var->evaluate(exec);
1863 KJS_CHECKEXCEPTIONVALUE
1868 void VarDeclListNode::processVarDecls(
ExecState *exec)
1870 for (VarDeclListNode *n =
this; n; n = n->list)
1871 n->var->processVarDecls(exec);
1876 void VarStatementNode::ref()
1878 StatementNode::ref();
1883 bool VarStatementNode::deref()
1885 if ( list && list->deref() )
1887 return StatementNode::deref();
1895 (void) list->evaluate(exec);
1901 void VarStatementNode::processVarDecls(
ExecState *exec)
1903 list->processVarDecls(exec);
1908 BlockNode::BlockNode(SourceElementsNode *s)
1911 source = s->elements;
1913 setLoc(s->firstLine(), s->lastLine(), s->code());
1919 void BlockNode::ref()
1921 StatementNode::ref();
1926 bool BlockNode::deref()
1928 if ( source && source->deref() )
1930 return StatementNode::deref();
1939 source->processFuncDecl(exec);
1941 return source->execute(exec);
1944 void BlockNode::processVarDecls(
ExecState *exec)
1947 source->processVarDecls(exec);
1960 void ExprStatementNode::ref()
1962 StatementNode::ref();
1967 bool ExprStatementNode::deref()
1969 if ( expr && expr->deref() )
1971 return StatementNode::deref();
1979 Value v = expr->evaluate(exec);
1989 StatementNode::ref();
1998 bool IfNode::deref()
2000 if ( statement1 && statement1->deref() )
2002 if ( statement2 && statement2->deref() )
2004 if ( expr && expr->deref() )
2006 return StatementNode::deref();
2015 bool b = expr->toBoolean(exec);
2020 return statement1->execute(exec);
2027 return statement2->execute(exec);
2030 void IfNode::processVarDecls(
ExecState *exec)
2032 statement1->processVarDecls(exec);
2035 statement2->processVarDecls(exec);
2040 void DoWhileNode::ref()
2042 StatementNode::ref();
2049 bool DoWhileNode::deref()
2051 if ( statement && statement->deref() )
2053 if ( expr && expr->deref() )
2055 return StatementNode::deref();
2071 exec->
context().imp()->seenLabels()->pushIteration();
2072 c = statement->execute(exec);
2073 exec->
context().imp()->seenLabels()->popIteration();
2074 if (!((c.complType() == Continue) && ls.contains(c.target()))) {
2075 if ((c.complType() == Break) && ls.contains(c.target()))
2077 if (c.complType() != Normal)
2087 void DoWhileNode::processVarDecls(
ExecState *exec)
2089 statement->processVarDecls(exec);
2094 void WhileNode::ref()
2096 StatementNode::ref();
2103 bool WhileNode::deref()
2105 if ( statement && statement->deref() )
2107 if ( expr && expr->deref() )
2109 return StatementNode::deref();
2130 exec->
context().imp()->seenLabels()->pushIteration();
2131 c = statement->execute(exec);
2132 exec->
context().imp()->seenLabels()->popIteration();
2133 if (c.isValueCompletion())
2136 if ((c.complType() == Continue) && ls.contains(c.target()))
2138 if ((c.complType() == Break) && ls.contains(c.target()))
2140 if (c.complType() != Normal)
2145 void WhileNode::processVarDecls(
ExecState *exec)
2147 statement->processVarDecls(exec);
2154 StatementNode::ref();
2165 bool ForNode::deref()
2167 if ( statement && statement->deref() )
2169 if ( expr1 && expr1->deref() )
2171 if ( expr2 && expr2->deref() )
2173 if ( expr3 && expr3->deref() )
2175 return StatementNode::deref();
2184 v = expr1->evaluate(exec);
2189 bool b = expr2->toBoolean(exec);
2197 exec->
context().imp()->seenLabels()->pushIteration();
2199 exec->
context().imp()->seenLabels()->popIteration();
2200 if (c.isValueCompletion())
2202 if (!((c.complType() == Continue) && ls.contains(c.target()))) {
2203 if ((c.complType() == Break) && ls.contains(c.target()))
2205 if (c.complType() != Normal)
2209 v = expr3->evaluate(exec);
2215 void ForNode::processVarDecls(
ExecState *exec)
2218 expr1->processVarDecls(exec);
2220 statement->processVarDecls(exec);
2225 ForInNode::ForInNode(Node *l, Node *e, StatementNode *s)
2226 : init(0L), lexpr(l), expr(e), varDecl(0L), statement(s)
2230 ForInNode::ForInNode(
const Identifier &i, AssignExprNode *in, Node *e, StatementNode *s)
2231 : ident(i), init(in), expr(e), statement(s)
2234 varDecl =
new VarDeclNode(ident, init, VarDeclNode::Variable);
2235 lexpr =
new ResolveNode(ident);
2238 void ForInNode::ref()
2240 StatementNode::ref();
2253 bool ForInNode::deref()
2255 if ( statement && statement->deref() )
2257 if ( expr && expr->deref() )
2259 if ( lexpr && lexpr->deref() )
2261 if ( init && init->deref() )
2263 if ( varDecl && varDecl->deref() )
2265 return StatementNode::deref();
2275 (void)varDecl->evaluate(exec);
2279 Value v = expr->evaluate(exec);
2284 if (v.
isA(NullType) || v.
isA(UndefinedType))
2293 while (propIt != propList.end()) {
2300 Reference ref = lexpr->evaluateReference(exec);
2304 exec->
context().imp()->seenLabels()->pushIteration();
2305 c = statement->execute(exec);
2306 exec->
context().imp()->seenLabels()->popIteration();
2307 if (c.isValueCompletion())
2310 if (!((c.complType() == Continue) && ls.contains(c.target()))) {
2311 if ((c.complType() == Break) && ls.contains(c.target()))
2313 if (c.complType() != Normal) {
2327 void ForInNode::processVarDecls(
ExecState *exec)
2329 statement->processVarDecls(exec);
2341 if (ident.isEmpty() && !exec->
context().imp()->seenLabels()->inIteration())
2343 throwError(exec, SyntaxError,
"continue used outside of iteration statement"));
2344 else if (!ident.isEmpty() && !exec->
context().imp()->seenLabels()->
contains(ident))
2346 throwError(exec, SyntaxError,
"Label %s not found in containing block. Can't continue.", ident));
2360 if (ident.isEmpty() && !exec->
context().imp()->seenLabels()->inIteration() &&
2361 !exec->
context().imp()->seenLabels()->inSwitch())
2363 throwError(exec, SyntaxError,
"break used outside of iteration or switch statement"));
2364 else if (!ident.isEmpty() && !exec->
context().imp()->seenLabels()->
contains(ident))
2366 throwError(exec, SyntaxError,
"Label %s not found in containing block. Can't break.", ident));
2373 void ReturnNode::ref()
2375 StatementNode::ref();
2380 bool ReturnNode::deref()
2382 if ( value && value->deref() )
2384 return StatementNode::deref();
2392 CodeType codeType = exec->
context().imp()->codeType();
2393 if (codeType != FunctionCode) {
2394 return Completion(Throw, throwError(exec, SyntaxError,
"Invalid return statement."));
2400 Value v = value->evaluate(exec);
2408 void WithNode::ref()
2410 StatementNode::ref();
2417 bool WithNode::deref()
2419 if ( statement && statement->deref() )
2421 if ( expr && expr->deref() )
2423 return StatementNode::deref();
2431 Value v = expr->evaluate(exec);
2435 exec->
context().imp()->pushScope(o);
2437 exec->
context().imp()->popScope();
2442 void WithNode::processVarDecls(
ExecState *exec)
2444 statement->processVarDecls(exec);
2449 void CaseClauseNode::ref()
2458 bool CaseClauseNode::deref()
2460 if ( expr && expr->deref() )
2462 if ( list && list->deref() )
2464 return Node::deref();
2470 Value v = expr->evaluate(exec);
2471 KJS_CHECKEXCEPTIONVALUE
2480 return list->execute(exec);
2485 void CaseClauseNode::processVarDecls(
ExecState *exec)
2488 list->processVarDecls(exec);
2493 void ClauseListNode::ref()
2495 for (ClauseListNode *n =
this; n; n = n->nx) {
2502 bool ClauseListNode::deref()
2504 ClauseListNode *
next;
2505 for (ClauseListNode *n =
this; n; n =
next) {
2507 if (n->cl && n->cl->deref())
2509 if (n !=
this && n->Node::deref())
2512 return Node::deref();
2523 void ClauseListNode::processVarDecls(
ExecState *exec)
2525 for (ClauseListNode *n =
this; n; n = n->nx)
2527 n->cl->processVarDecls(exec);
2532 CaseBlockNode::CaseBlockNode(ClauseListNode *l1, CaseClauseNode *d,
2550 void CaseBlockNode::ref()
2561 bool CaseBlockNode::deref()
2563 if ( def && def->deref() )
2565 if ( list1 && list1->deref() )
2567 if ( list2 && list2->deref() )
2569 return Node::deref();
2584 ClauseListNode *a = list1, *b = list2;
2585 CaseClauseNode *clause;
2588 clause = a->clause();
2590 v = clause->evaluate(exec);
2592 if (strictEqual(exec, input, v)) {
2593 res = clause->evalStatements(exec);
2594 if (res.complType() != Normal)
2597 res = a->clause()->evalStatements(exec);
2598 if (res.complType() != Normal)
2607 clause = b->clause();
2609 v = clause->evaluate(exec);
2611 if (strictEqual(exec, input, v)) {
2612 res = clause->evalStatements(exec);
2613 if (res.complType() != Normal)
2621 res = def->evalStatements(exec);
2622 if (res.complType() != Normal)
2628 clause = b->clause();
2629 res = clause->evalStatements(exec);
2630 if (res.complType() != Normal)
2641 void CaseBlockNode::processVarDecls(
ExecState *exec)
2644 list1->processVarDecls(exec);
2646 def->processVarDecls(exec);
2648 list2->processVarDecls(exec);
2653 void SwitchNode::ref()
2655 StatementNode::ref();
2662 bool SwitchNode::deref()
2664 if ( expr && expr->deref() )
2666 if ( block && block->deref() )
2668 return StatementNode::deref();
2676 Value v = expr->evaluate(exec);
2678 exec->
context().imp()->seenLabels()->pushSwitch();
2680 exec->
context().imp()->seenLabels()->popSwitch();
2682 if ((res.complType() == Break) && ls.contains(res.target()))
2688 void SwitchNode::processVarDecls(
ExecState *exec)
2690 block->processVarDecls(exec);
2695 void LabelNode::ref()
2697 StatementNode::ref();
2702 bool LabelNode::deref()
2704 if ( statement && statement->deref() )
2706 return StatementNode::deref();
2714 if (!exec->
context().imp()->seenLabels()->
push(label)) {
2716 throwError(exec, SyntaxError,
"Duplicated label %s found.", label));
2718 e = statement->execute(exec);
2721 if ((e.complType() == Break) && (e.target() == label))
2727 void LabelNode::processVarDecls(
ExecState *exec)
2729 statement->processVarDecls(exec);
2734 void ThrowNode::ref()
2736 StatementNode::ref();
2741 bool ThrowNode::deref()
2743 if ( expr && expr->deref() )
2745 return StatementNode::deref();
2753 Value v = expr->evaluate(exec);
2759 Debugger *dbg = exec->interpreter()->imp()->debugger();
2761 dbg->exception(exec,v,exec->
context().imp()->inTryCatch());
2768 void CatchNode::ref()
2770 StatementNode::ref();
2775 bool CatchNode::deref()
2777 if ( block && block->deref() )
2779 return StatementNode::deref();
2794 exec->clearException();
2796 Object obj(
new ObjectImp());
2797 obj.
put(exec, ident, arg, DontDelete);
2798 exec->
context().imp()->pushScope(obj);
2800 exec->
context().imp()->popScope();
2805 void CatchNode::processVarDecls(
ExecState *exec)
2807 block->processVarDecls(exec);
2812 void FinallyNode::ref()
2814 StatementNode::ref();
2819 bool FinallyNode::deref()
2821 if ( block && block->deref() )
2823 return StatementNode::deref();
2829 return block->execute(exec);
2832 void FinallyNode::processVarDecls(
ExecState *exec)
2834 block->processVarDecls(exec);
2841 StatementNode::ref();
2850 bool TryNode::deref()
2852 if ( block && block->deref() )
2854 if ( _final && _final->deref() )
2856 if ( _catch && _catch->deref() )
2858 return StatementNode::deref();
2869 exec->
context().imp()->pushTryCatch();
2870 c = block->execute(exec);
2872 exec->
context().imp()->popTryCatch();
2875 if (c.complType() != Throw)
2877 return _catch->execute(exec,c.value());
2881 Value exception = exec->_exception;
2882 exec->_exception =
Value();
2884 c2 = _final->execute(exec);
2886 if (!exec->hadException() && c2.complType() != Throw)
2887 exec->_exception = exception;
2889 return (c2.complType() == Normal) ? c : c2;
2892 if (c.complType() == Throw)
2893 c = _catch->execute(exec,c.value());
2895 c2 = _final->execute(exec);
2896 return (c2.complType() == Normal) ? c : c2;
2899 void TryNode::processVarDecls(
ExecState *exec)
2901 block->processVarDecls(exec);
2903 _final->processVarDecls(exec);
2905 _catch->processVarDecls(exec);
2910 void ParameterNode::ref()
2912 for (ParameterNode *n =
this; n; n = n->next)
2916 bool ParameterNode::deref()
2918 ParameterNode *
next;
2919 for (ParameterNode *n =
this; n; n =
next) {
2921 if (n !=
this && n->Node::deref())
2924 return Node::deref();
2936 FunctionBodyNode::FunctionBodyNode(SourceElementsNode *s)
2942 void FunctionBodyNode::processFuncDecl(
ExecState *exec)
2945 source->processFuncDecl(exec);
2950 void FuncDeclNode::ref()
2952 StatementNode::ref();
2959 bool FuncDeclNode::deref()
2961 if ( param && param->deref() )
2963 if ( body && body->deref() )
2965 return StatementNode::deref();
2969 void FuncDeclNode::processFuncDecl(
ExecState *exec)
2973 FunctionImp *fimp =
new DeclaredFunctionImp(exec, ident, body, exec->
context().imp()->scopeChain());
2979 proto.
put(exec, constructorPropertyName, func, ReadOnly|DontDelete|DontEnum);
2980 func.
put(exec, prototypePropertyName, proto, Internal|DontDelete);
2983 for(
const ParameterNode *p = param; p != 0L; p = p->nextParam(), plen++)
2984 fimp->addParameter(p->ident());
2986 func.
put(exec, lengthPropertyName,
Number(plen), ReadOnly|DontDelete|DontEnum);
2989 fprintf(stderr,
"KJS: new function %s in %p\n", ident.ustring().cstring().c_str(), ctx->variableObject().imp());
2991 if (exec->_context->codeType() == EvalCode) {
2993 ctx->variableObject().
put(exec, ident, func, Internal);
2995 ctx->variableObject().
put(exec, ident, func, DontDelete | Internal);
3001 Object oldVar = ctx->variableObject();
3002 ctx->setVariableObject(func);
3003 ctx->pushScope(func);
3004 body->processFuncDecl(exec);
3006 ctx->setVariableObject(oldVar);
3012 void FuncExprNode::ref()
3021 bool FuncExprNode::deref()
3023 if ( param && param->deref() )
3025 if ( body && body->deref() )
3027 return Node::deref();
3035 bool named = !ident.isNull();
3036 Object functionScopeObject;
3042 functionScopeObject =
Object(
new ObjectImp());
3043 context->pushScope(functionScopeObject);
3050 fimp->put(exec, prototypePropertyName, proto, Internal|DontDelete);
3052 for(
const ParameterNode *p = param; p != 0L; p = p->nextParam())
3053 fimp->addParameter(p->ident());
3056 functionScopeObject.
put(exec, ident,
Value(fimp), ReadOnly|DontDelete);
3057 context->popScope();
3065 SourceElementsNode::SourceElementsNode(StatementNode *s1)
3069 setLoc(s1->firstLine(), s1->lastLine(), s1->code());
3072 SourceElementsNode::SourceElementsNode(SourceElementsNode *s1, StatementNode *s2)
3074 elements = s1->elements;
3075 s1->elements =
this;
3077 setLoc(s1->firstLine(), s2->lastLine(), s1->code());
3080 void SourceElementsNode::ref()
3082 for (SourceElementsNode *n =
this; n; n = n->elements) {
3089 bool SourceElementsNode::deref()
3091 SourceElementsNode *
next;
3092 for (SourceElementsNode *n =
this; n; n =
next) {
3094 if (n->element && n->element->deref())
3096 if (n !=
this && n->Node::deref())
3099 return StatementNode::deref();
3109 if (c1.complType() != Normal)
3112 for (SourceElementsNode *n = elements; n; n = n->elements) {
3114 if (c2.complType() != Normal)
3126 void SourceElementsNode::processFuncDecl(
ExecState *exec)
3128 for (SourceElementsNode *n =
this; n; n = n->elements)
3129 n->element->processFuncDecl(exec);
3132 void SourceElementsNode::processVarDecls(
ExecState *exec)
3134 for (SourceElementsNode *n =
this; n; n = n->elements)
3135 n->element->processVarDecls(exec);