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()) \
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());
85 #define KJS_CHECKEXCEPTIONLIST \
86 if (exec->hadException()) { \
87 setExceptionDetailsIfNeeded(exec); \
90 if (Collector::outOfMemory()) \
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
330 return UString::from(val);
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
596 s =
String(UString::from(numeric));
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 &&
854 Object::dynamicCast(thisVal).inherits(&ActivationImp::info))
857 if (thisVal.
type() != ObjectType) {
868 Object thisObj = Object::dynamicCast(thisVal);
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();
1786 Object variable = Object::dynamicCast(exec->
context().imp()->variableObject());
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);
3046 FunctionImp *fimp =
new DeclaredFunctionImp(exec, Identifier::null(), body, exec->
context().imp()->scopeChain());
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);
Represents an primitive Boolean value.
Completion objects are used to convey the return status and value from functions.
Object variableObject() const
Returns the variable object for the execution context.
Represents the current state of script execution.
Context context() const
Returns the execution context associated with this execution state.
Interpreter * lexicalInterpreter() const
Returns the interpreter associated with the current scope's global object.
Interpreter * dynamicInterpreter() const
Returns the interpreter associated with this execution state.
Implementation class for functions implemented in JS.
Represents an Identifier for a Javascript object.
Object builtinObject() const
Returns the builtin "Object" object.
Object builtinArray() const
Returns the builtin "Array" object.
Object & globalObject() const
Returns the object that is used as the global object during all script execution performed by this in...
void pop()
Removes from the stack the last pushed id (what else?)
bool contains(const Identifier &id) const
Is the id in the stack?
bool push(const Identifier &id)
If id is not empty and is not in the stack already, puts it on top of the stack and returns true,...
void append(const Value &val)
Append an object to the end of the list.
Represents an primitive Null value.
Represents an primitive Number value.
bool implementsCall() const
Whether or not the object implements the call() method.
bool implementsConstruct() const
Whether or not the object implements the construct() method.
Object construct(ExecState *exec, const List &args)
Creates a new object based on this object.
ReferenceList propList(ExecState *exec, bool recursive=true)
Returns a List of References to all the properties of the object.
void put(ExecState *exec, const Identifier &propertyName, const Value &value, int attr=None)
Sets the specified property.
Value call(ExecState *exec, Object &thisObj, const List &args)
Calls this object as if it is a function.
bool hasProperty(ExecState *exec, const Identifier &propertyName) const
Checks to see whether the object (or any object in it's prototype chain) has a property with the spec...
Value get(ExecState *exec, const Identifier &propertyName) const
Retrieves the specified property from the object.
An iterator for a ReferenceList.
A list of Reference objects.
Defines a Javascript reference.
Identifier getPropertyName(ExecState *exec) const
Performs the GetPropertyName type conversion operation on this value (ECMA 8.7)
Value getBase(ExecState *exec) const
Performs the GetBase type conversion operation on this value (ECMA 8.7)
void putValue(ExecState *exec, const Value &w)
Performs the PutValue type conversion operation on this value (ECMA 8.7.1)
Value getValue(ExecState *exec) const
Performs the GetValue type conversion operation on this value (ECMA 8.7.1)
Represents an primitive String value.
char * ascii() const
Convert the Unicode string to plain ASCII chars chopping of any higher bytes.
Represents an primitive Undefined value.
Value objects are act as wrappers ("smart pointers") around ValueImp objects and their descendents.
UString toString(ExecState *exec) const
Performs the ToString type conversion operation on this value (ECMA 9.8)
bool isA(Type t) const
Checks whether or not the value is of a particular tpye.
Object toObject(ExecState *exec) const
Performs the ToObject type conversion operation on this value (ECMA 9.9)
unsigned int toUInt32(ExecState *exec) const
Performs the ToUInt32 type conversion operation on this value (ECMA 9.6)
int toInt32(ExecState *exec) const
Performs the ToInt32 type conversion operation on this value (ECMA 9.5)
bool toBoolean(ExecState *exec) const
Performs the ToBoolean type conversion operation on this value (ECMA 9.2)
bool isValid() const
Returns whether or not this is a valid value.
Type type() const
Returns the type of value.
double toNumber(ExecState *exec) const
Performs the ToNumber type conversion operation on this value (ECMA 9.3)
kndbgstream & endl(kndbgstream &s)
const TDEShortcut & next()
TQString name(StdAccel id)
TQString label(StdAccel id)