26 #include "scriptfunction.h"
37 #include "function_object.h"
40 #include "PropertyNameArray.h"
41 #include <wtf/AlwaysInline.h>
42 #include <wtf/Assertions.h>
43 #include <wtf/HashSet.h>
44 #include <wtf/HashCountedSet.h>
45 #include <wtf/MathExtras.h>
47 #include "bytecode/machine.h"
56 static unsigned count;
60 fprintf(stderr,
"LEAK: %d KJS::Node\n", count);
64 unsigned NodeCounter::count = 0;
65 static NodeCounter nodeCounter;
68 static HashSet<Node *> *newNodes;
69 static HashCountedSet<Node *> *nodeExtraRefCounts;
76 m_line = lexer().lineNo();
78 newNodes =
new HashSet<Node *>;
94 HashSet<Node *>::iterator it = newNodes->find(
this);
95 if (it != newNodes->end()) {
97 ASSERT(!nodeExtraRefCounts || !nodeExtraRefCounts->contains(
this));
102 ASSERT(!newNodes || !newNodes->contains(
this));
104 if (!nodeExtraRefCounts) {
105 nodeExtraRefCounts =
new HashCountedSet<Node *>;
107 nodeExtraRefCounts->add(
this);
112 ASSERT(!newNodes || !newNodes->contains(
this));
114 if (!nodeExtraRefCounts) {
119 HashCountedSet<Node *>::iterator it = nodeExtraRefCounts->find(
this);
120 if (it == nodeExtraRefCounts->end()) {
123 nodeExtraRefCounts->remove(it);
127 unsigned Node::refcount()
129 if (newNodes && newNodes->contains(
this)) {
130 ASSERT(!nodeExtraRefCounts || !nodeExtraRefCounts->contains(
this));
134 ASSERT(!newNodes || !newNodes->contains(
this));
136 if (!nodeExtraRefCounts) {
140 return 1 + nodeExtraRefCounts->count(
this);
143 void Node::clearNewNodes()
150 HashSet<Node *>::iterator
end = newNodes->end();
151 for (HashSet<Node *>::iterator it = newNodes->begin(); it != end; ++it) {
152 ASSERT(!nodeExtraRefCounts || !nodeExtraRefCounts->contains(*it));
155 deleteAllValues(*newNodes);
160 static void substitute(UString &
string,
const UString &substring)
162 int position =
string.find(
"%s");
163 assert(position != -1);
164 UString newString =
string.substr(0, position);
165 newString.append(substring);
166 newString.append(
string.substr(position + 2));
170 static inline int currentSourceId(ExecState *exec)
172 return exec->currentBody()->sourceId();
175 static inline const UString ¤tSourceURL(ExecState *exec)
177 return exec->currentBody()->sourceURL();
180 JSValue *Node::throwError(ExecState *exec, ErrorType e,
const UString &msg)
182 return KJS::throwError(exec, e, msg, lineNo(), currentSourceId(exec), currentSourceURL(exec));
185 JSValue *Node::throwError(ExecState *exec, ErrorType e,
const UString &msg,
const Identifier &label)
189 return KJS::throwError(exec, e,
message, lineNo(), currentSourceId(exec), currentSourceURL(exec));
192 JSValue *Node::throwUndefinedVariableError(ExecState *exec,
const Identifier &ident)
194 return throwError(exec, ReferenceError,
"Cannot find variable: %s", ident);
197 Node *Node::nodeInsideAllParens()
202 class VarDeclVisitor:
public NodeVisitor
207 VarDeclVisitor(ExecState *exec) : m_exec(exec)
212 node->processVarDecl(m_exec);
216 if (!node->scanForDeclarations()) {
220 return NodeVisitor::visit(node);
224 class FuncDeclVisitor:
public NodeVisitor
229 FuncDeclVisitor(ExecState *exec) : m_exec(exec)
234 node->processFuncDecl(m_exec);
236 if (!node->scanForDeclarations()) {
240 return NodeVisitor::visit(node);
244 void Node::processDecls(ExecState *exec)
246 VarDeclVisitor vVisit(exec);
249 FuncDeclVisitor fVisit(exec);
253 void Node::processVarDecl(ExecState *)
256 void Node::processFuncDecl(ExecState *)
260 Node *NodeVisitor::visit(
Node *node)
262 node->recurseVisit(
this);
268 StatementNode::StatementNode()
274 void StatementNode::setLoc(
int firstLine,
int lastLine)
const
277 m_lastLine = lastLine;
280 void StatementNode::hitStatement(ExecState *exec)
283 exec->dynamicInterpreter()->debugger()->reportAtStatement(exec, currentSourceId(exec), firstLine(), lastLine());
288 Node *GroupNode::nodeInsideAllParens()
292 n =
static_cast<GroupNode *
>(n)->group.get();
293 }
while (n->isGroupNode());
297 void GroupNode::recurseVisit(NodeVisitor *visitor)
299 recurseVisitLink(visitor, group);
304 void ElementNode::breakCycle()
309 void ElementNode::recurseVisit(NodeVisitor *visitor)
311 recurseVisitLink(visitor, next);
312 recurseVisitLink(visitor, node);
317 void ArrayNode::recurseVisit(NodeVisitor *visitor)
319 recurseVisitLink(visitor, element);
324 void ObjectLiteralNode::recurseVisit(NodeVisitor *visitor)
326 recurseVisitLink(visitor, list);
331 void PropertyListNode::breakCycle()
336 void PropertyListNode::recurseVisit(NodeVisitor *visitor)
338 recurseVisitLink(visitor, node);
339 recurseVisitLink(visitor, next);
343 void PropertyNode::recurseVisit(NodeVisitor *visitor)
345 recurseVisitLink(visitor, name);
346 recurseVisitLink(visitor, assign);
351 void BracketAccessorNode::recurseVisit(NodeVisitor *visitor)
353 recurseVisitLink(visitor, expr1);
354 recurseVisitLink(visitor, expr2);
359 void DotAccessorNode::recurseVisit(NodeVisitor *visitor)
361 recurseVisitLink(visitor, expr);
366 void ArgumentListNode::breakCycle()
371 void ArgumentListNode::recurseVisit(NodeVisitor *visitor)
373 recurseVisitLink(visitor, next);
374 recurseVisitLink(visitor, expr);
379 void ArgumentsNode::recurseVisit(NodeVisitor *visitor)
381 recurseVisitLink(visitor, list);
386 void NewExprNode::recurseVisit(NodeVisitor *visitor)
388 recurseVisitLink(visitor, expr);
389 recurseVisitLink(visitor, args);
394 void FunctionCallValueNode::recurseVisit(NodeVisitor *visitor)
396 recurseVisitLink(visitor, expr);
397 recurseVisitLink(visitor, args);
402 void FunctionCallReferenceNode::recurseVisit(NodeVisitor *visitor)
404 recurseVisitLink(visitor, expr);
405 recurseVisitLink(visitor, args);
410 void PostfixNode::recurseVisit(NodeVisitor *visitor)
412 Node::recurseVisitLink(visitor, m_loc);
417 void DeleteReferenceNode::recurseVisit(NodeVisitor *visitor)
419 Node::recurseVisitLink(visitor, loc);
424 void DeleteValueNode::recurseVisit(NodeVisitor *visitor)
426 recurseVisitLink(visitor, m_expr);
431 void VoidNode::recurseVisit(NodeVisitor *visitor)
433 recurseVisitLink(visitor, expr);
438 void TypeOfVarNode::recurseVisit(NodeVisitor *visitor)
440 Node::recurseVisitLink(visitor, loc);
445 void TypeOfValueNode::recurseVisit(NodeVisitor *visitor)
447 recurseVisitLink(visitor, m_expr);
452 void PrefixNode::recurseVisit(NodeVisitor *visitor)
454 Node::recurseVisitLink(visitor, m_loc);
459 void UnaryPlusNode::recurseVisit(NodeVisitor *visitor)
461 recurseVisitLink(visitor, expr);
466 void NegateNode::recurseVisit(NodeVisitor *visitor)
468 recurseVisitLink(visitor, expr);
473 void BitwiseNotNode::recurseVisit(NodeVisitor *visitor)
475 recurseVisitLink(visitor, expr);
480 void LogicalNotNode::recurseVisit(NodeVisitor *visitor)
482 recurseVisitLink(visitor, expr);
487 void BinaryOperatorNode::recurseVisit(NodeVisitor *visitor)
489 recurseVisitLink(visitor, expr1);
490 recurseVisitLink(visitor, expr2);
495 void BinaryLogicalNode::recurseVisit(NodeVisitor *visitor)
497 recurseVisitLink(visitor, expr1);
498 recurseVisitLink(visitor, expr2);
503 void ConditionalNode::recurseVisit(NodeVisitor *visitor)
505 recurseVisitLink(visitor, logical);
506 recurseVisitLink(visitor, expr1);
507 recurseVisitLink(visitor, expr2);
512 void AssignNode::recurseVisit(NodeVisitor *visitor)
514 Node::recurseVisitLink(visitor, m_loc);
515 Node::recurseVisitLink(visitor, m_right);
520 void CommaNode::recurseVisit(NodeVisitor *visitor)
522 recurseVisitLink(visitor, expr1);
523 recurseVisitLink(visitor, expr2);
528 void AssignExprNode::recurseVisit(NodeVisitor *visitor)
530 recurseVisitLink(visitor, expr);
535 VarDeclNode::VarDeclNode(
const Identifier &
id, AssignExprNode *in, Type t)
536 : varType(t), ident(id),
init(in)
542 JSValue *VarDeclNode::evaluate(ExecState *exec)
544 JSObject *variable = exec->variableObject();
548 val =
init->evaluate(exec);
549 KJS_CHECKEXCEPTIONVALUE
559 if (variable->getDirect(ident) || ident == exec->propertyNames().arguments) {
566 printInfo(exec, (UString(
"new variable ") + ident.ustring()).cstring().c_str(), val);
570 int flags = Internal;
571 if (exec->codeType() != EvalCode) {
574 if (varType == VarDeclNode::Constant) {
577 variable->put(exec, ident, val, flags);
583 void VarDeclNode::processVarDecl(ExecState *exec)
585 JSObject *variable = exec->variableObject();
588 int flags = DontDelete;
589 if (varType == VarDeclNode::Constant) {
594 switch (exec->codeType()) {
598 exec->currentBody()->addVarDecl(ident, flags, exec);
602 flags &= ~DontDelete;
606 if (!variable->hasProperty(exec, ident)) {
607 variable->put(exec, ident, jsUndefined(), flags);
610 variable->setLocalInjected();
616 if (!variable->hasProperty(exec, ident)) {
617 variable->put(exec, ident, jsUndefined(), flags);
622 void VarDeclNode::recurseVisit(NodeVisitor *visitor)
624 recurseVisitLink(visitor, init);
629 void VarDeclListNode::breakCycle()
634 void VarDeclListNode::recurseVisit(NodeVisitor *visitor)
636 recurseVisitLink(visitor, var);
637 recurseVisitLink(visitor, next);
642 void VarStatementNode::recurseVisit(NodeVisitor *visitor)
644 recurseVisitLink(visitor, next);
649 BlockNode::BlockNode(SourceElementsNode *s)
652 source = s->next.release();
653 Parser::removeNodeCycle(source.get());
654 setLoc(s->firstLine(), s->lastLine());
660 void BlockNode::recurseVisit(NodeVisitor *visitor)
662 recurseVisitLink(visitor, source);
667 void ExprStatementNode::recurseVisit(NodeVisitor *visitor)
669 recurseVisitLink(visitor, expr);
674 void IfNode::recurseVisit(NodeVisitor *visitor)
676 recurseVisitLink(visitor, expr);
677 recurseVisitLink(visitor, statement1);
678 recurseVisitLink(visitor, statement2);
683 void DoWhileNode::recurseVisit(NodeVisitor *visitor)
685 recurseVisitLink(visitor, expr);
686 recurseVisitLink(visitor, statement);
691 void WhileNode::recurseVisit(NodeVisitor *visitor)
693 recurseVisitLink(visitor, expr);
694 recurseVisitLink(visitor, statement);
699 void ForNode::recurseVisit(NodeVisitor *visitor)
701 recurseVisitLink(visitor, expr1);
702 recurseVisitLink(visitor, expr2);
703 recurseVisitLink(visitor, expr3);
704 recurseVisitLink(visitor, statement);
709 ForInNode::ForInNode(
Node *l,
Node *e, StatementNode *s)
710 :
init(nullptr), lexpr(l), expr(e), varDecl(nullptr), statement(s)
714 ForInNode::ForInNode(
const Identifier &i, AssignExprNode *in,
Node *e, StatementNode *s)
715 : ident(i),
init(in), expr(e), statement(s)
718 varDecl =
new VarDeclNode(ident,
init.get(), VarDeclNode::Variable);
719 lexpr =
new VarAccessNode(ident);
722 void ForInNode::recurseVisit(NodeVisitor *visitor)
724 recurseVisitLink(visitor, init);
725 recurseVisitLink(visitor, lexpr);
726 recurseVisitLink(visitor, expr);
727 recurseVisitLink(visitor, varDecl);
728 recurseVisitLink(visitor, statement);
733 void ReturnNode::recurseVisit(NodeVisitor *visitor)
735 recurseVisitLink(visitor, value);
740 void WithNode::recurseVisit(NodeVisitor *visitor)
742 recurseVisitLink(visitor, expr);
743 recurseVisitLink(visitor, statement);
748 void CaseClauseNode::recurseVisit(NodeVisitor *visitor)
750 recurseVisitLink(visitor, expr);
751 recurseVisitLink(visitor, source);
756 void ClauseListNode::breakCycle()
761 void ClauseListNode::recurseVisit(NodeVisitor *visitor)
763 recurseVisitLink(visitor, clause);
764 recurseVisitLink(visitor, next);
769 CaseBlockNode::CaseBlockNode(ClauseListNode *l1, CaseClauseNode *d,
773 list1 = l1->next.release();
774 Parser::removeNodeCycle(list1.get());
782 list2 = l2->next.release();
783 Parser::removeNodeCycle(list2.get());
789 void CaseBlockNode::recurseVisit(NodeVisitor *visitor)
791 recurseVisitLink(visitor, list1);
792 recurseVisitLink(visitor, def);
793 recurseVisitLink(visitor, list2);
798 void SwitchNode::recurseVisit(NodeVisitor *visitor)
800 recurseVisitLink(visitor, expr);
801 recurseVisitLink(visitor, block);
806 void LabelNode::recurseVisit(NodeVisitor *visitor)
808 recurseVisitLink(visitor, statement);
813 void ThrowNode::recurseVisit(NodeVisitor *visitor)
815 recurseVisitLink(visitor, expr);
820 void TryNode::recurseVisit(NodeVisitor *visitor)
822 recurseVisitLink(visitor, tryBlock);
823 recurseVisitLink(visitor, catchBlock);
824 recurseVisitLink(visitor, finallyBlock);
829 void ParameterNode::breakCycle()
834 void ParameterNode::recurseVisit(NodeVisitor *visitor)
836 recurseVisitLink(visitor, next);
841 FunctionBodyNode::FunctionBodyNode(SourceElementsNode *s)
843 , m_sourceURL(lexer().sourceURL())
844 , m_sourceId(parser().sourceId())
845 , m_compType(NotCompiled)
846 , m_flags(parser().popFunctionContext())
851 void FunctionBodyNode::addVarDecl(
const Identifier &ident,
int attr, ExecState *exec)
860 if (ident == exec->propertyNames().arguments) {
864 (void)addSymbol(ident, attr);
867 void FunctionBodyNode::addFunDecl(
const Identifier &ident,
int attr, FuncDeclNode *funcDecl)
869 m_functionLocals.append(addSymbol(ident, attr, funcDecl));
872 void FunctionBodyNode::reserveSlot(
size_t id,
bool shouldMark)
874 ASSERT(
id == m_symbolList.size());
875 m_symbolList.append(SymbolInfo(shouldMark ? 0 : DontMark,
nullptr));
878 size_t FunctionBodyNode::addSymbol(
const Identifier &ident,
int flags, FuncDeclNode *funcDecl)
890 size_t oldId = m_symbolTable.get(ident.ustring().rep());
891 if (oldId != missingSymbolMarker()) {
893 m_symbolList[oldId].funcDecl = funcDecl;
898 size_t id = m_symbolList.size();
899 m_symbolTable.set(ident.ustring().rep(),
id);
900 m_symbolList.append(SymbolInfo(flags, funcDecl));
904 void FunctionBodyNode::addSymbolOverwriteID(
size_t id,
const Identifier &ident,
int flags)
906 ASSERT(
id == m_symbolList.size());
909 size_t oldId = m_symbolTable.get(ident.ustring().rep());
910 if (oldId != missingSymbolMarker()) {
911 m_symbolList[oldId].attr = DontMark;
915 m_symbolTable.set(ident.ustring().rep(),
id);
916 m_symbolList.append(SymbolInfo(flags,
nullptr));
919 void FunctionBodyNode::addParam(
const Identifier &ident)
921 m_paramList.append(ident);
924 Completion FunctionBodyNode::execute(ExecState *exec)
926 CodeType ctype = exec->codeType();
927 CompileType cmpType = exec->dynamicInterpreter()->debugger() ? Debug :
Release;
928 compileIfNeeded(ctype, cmpType);
929 ASSERT(ctype != FunctionCode);
931 LocalStorage *store =
new LocalStorage();
932 LocalStorageEntry *regs;
935 store->resize(m_symbolList.size());
936 regs = store->data();
937 for (
size_t c = 0; c < m_symbolList.size(); ++c) {
938 regs[c].val.valueVal = jsUndefined();
939 regs[c].attributes = m_symbolList[c].attr;
942 exec->initLocalStorage(regs, m_symbolList.size());
944 JSValue *val = Machine::runBlock(exec, m_compiledCode);
947 if (exec->hadException()) {
948 result = Completion(Throw, exec->exception());
950 result = Completion(Normal, val);
953 exec->initLocalStorage(
nullptr, 0);
955 exec->clearException();
960 void FunctionBodyNode::compile(CodeType ctype, CompileType compType)
962 m_compType = compType;
964 CompileState comp(ctype, compType,
this, m_symbolList.size());
965 generateExecCode(&comp);
966 m_tearOffAtEnd = comp.needsClosures();
969 fprintf(stderr,
"\n\n");
970 fprintf(stderr,
"\n---------------------------------\n\n");
971 fprintf(stderr,
"%s",
toString().ascii());
972 fprintf(stderr,
"\n---------------------------------\n\n");
973 CodeGen::disassembleBlock(m_compiledCode);
974 fprintf(stderr,
"\n---------------------------------\n\n");
981 void FuncDeclNode::processFuncDecl(ExecState *exec)
985 int flags = Internal | DontDelete;
986 switch (exec->codeType()) {
989 exec->currentBody()->addFunDecl(ident, flags,
this);
993 flags &= ~DontDelete;
997 exec->variableObject()->setLocalInjected();
1001 exec->variableObject()->put(exec, ident, makeFunctionObject(exec), flags);
1005 void FuncDeclNode::addParams()
1007 for (ParameterNode *p = param.get(); p !=
nullptr; p = p->nextParam()) {
1008 body->addParam(p->ident());
1012 FunctionImp *FuncDeclNode::makeFunctionObject(ExecState *exec)
1015 FunctionImp *func =
new FunctionImp(exec, ident, body.get(), exec->scopeChain());
1017 JSObject *proto = exec->lexicalInterpreter()->builtinObject()->construct(exec,
List::empty());
1018 proto->put(exec, exec->propertyNames().constructor, func, DontEnum);
1020 func->put(exec, exec->propertyNames().prototype, proto, Internal | DontDelete | DontEnum);
1022 func->put(exec, exec->propertyNames().length, jsNumber(body->numParams()), ReadOnly | DontDelete | DontEnum);
1027 void FuncDeclNode::recurseVisit(NodeVisitor *visitor)
1029 recurseVisitLink(visitor, param);
1030 recurseVisitLink(visitor, body);
1035 void FuncExprNode::addParams()
1037 for (ParameterNode *p = param.get(); p !=
nullptr; p = p->nextParam()) {
1038 body->addParam(p->ident());
1042 void FuncExprNode::recurseVisit(NodeVisitor *visitor)
1044 recurseVisitLink(visitor, param);
1045 recurseVisitLink(visitor, body);
1050 SourceElementsNode::SourceElementsNode(StatementNode *s1)
1051 : node(s1),
next(this)
1053 Parser::noteNodeCycle(
this);
1054 setLoc(s1->firstLine(), s1->lastLine());
1057 SourceElementsNode::SourceElementsNode(SourceElementsNode *s1, StatementNode *s2)
1061 setLoc(s1->firstLine(), s2->lastLine());
1064 void SourceElementsNode::breakCycle()
1069 void SourceElementsNode::recurseVisit(NodeVisitor *visitor)
1071 recurseVisitLink(visitor, node);
1072 recurseVisitLink(visitor, next);
1077 ProgramNode::ProgramNode(SourceElementsNode *s) : FunctionBodyNode(s)
1082 void PackageNameNode::recurseVisit(NodeVisitor *visitor)
1084 recurseVisitLink(visitor, names);
1087 Completion PackageNameNode::loadSymbol(ExecState *exec,
bool wildcard)
1089 Package *basePackage;
1090 JSObject *baseObject;
1092 PackageObject *pobj = names->resolvePackage(exec);
1093 if (pobj ==
nullptr) {
1094 return Completion(Normal);
1096 basePackage = pobj->package();
1099 Interpreter *ip = exec->lexicalInterpreter();
1100 basePackage = ip->globalPackage();
1101 baseObject = ip->globalObject();
1107 PackageObject *pobj = resolvePackage(exec, baseObject, basePackage);
1109 return Completion(Normal);
1111 basePackage = pobj->package();
1113 basePackage->loadAllSymbols(exec, baseObject);
1115 basePackage->loadSymbol(exec, baseObject,
id);
1118 return Completion(Normal);
1121 PackageObject *PackageNameNode::resolvePackage(ExecState *exec)
1123 JSObject *baseObject;
1124 Package *basePackage;
1126 PackageObject *basePackageObject = names->resolvePackage(exec);
1127 if (basePackageObject ==
nullptr) {
1130 baseObject = basePackageObject;
1131 basePackage = basePackageObject->package();
1134 Interpreter *ip = exec->lexicalInterpreter();
1135 baseObject = ip->globalObject();
1136 basePackage = ip->globalPackage();
1139 return resolvePackage(exec, baseObject, basePackage);
1142 PackageObject *PackageNameNode::resolvePackage(ExecState *exec,
1143 JSObject *baseObject,
1144 Package *basePackage)
1146 PackageObject *res =
nullptr;
1149 JSValue *v = baseObject->get(exec,
id);
1150 if (v && !JSValue::isUndefined(v)) {
1151 if (!JSValue::isObject(v)) {
1153 throwError(exec, GeneralError,
"Invalid type of package %s",
id);
1156 res =
static_cast<PackageObject *
>(v);
1159 Package *newBase = basePackage->loadSubPackage(
id, &err);
1160 if (newBase ==
nullptr) {
1161 if (err.isEmpty()) {
1162 throwError(exec, GeneralError,
"Package not found");
1164 throwError(exec, GeneralError, err);
1168 res =
new PackageObject(newBase);
1169 baseObject->put(exec,
id, res);
1175 void ImportStatement::processVarDecl(ExecState *exec)
1178 Package *glob = exec->lexicalInterpreter()->globalPackage();
1180 throwError(exec, GeneralError,
1181 "Package support disabled. Import failed.");
1186 if (exec->codeType() != GlobalCode) {
1187 throwError(exec, GeneralError,
1188 "Package imports may only occur at top level.");
1192 name->loadSymbol(exec, wld);
1195 void ImportStatement::recurseVisit(NodeVisitor *visitor)
1197 recurseVisitLink(visitor, name);