File indexing completed on 2024-05-12 15:43:27
0001 /* 0002 * This file is part of the KDE libraries 0003 * Copyright (C) 1999-2002 Harri Porten (porten@kde.org) 0004 * Copyright (C) 2001 Peter Kelly (pmk@post.com) 0005 * Copyright (C) 2003, 2004, 2005, 2006, 2007 Apple Inc. All rights reserved. 0006 * Copyright (C) 2007 Maksim Orlovich (maksim@kde.org) 0007 * 0008 * This library is free software; you can redistribute it and/or 0009 * modify it under the terms of the GNU Library General Public 0010 * License as published by the Free Software Foundation; either 0011 * version 2 of the License, or (at your option) any later version. 0012 * 0013 * This library is distributed in the hope that it will be useful, 0014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0016 * Library General Public License for more details. 0017 * 0018 * You should have received a copy of the GNU Library General Public License 0019 * along with this library; see the file COPYING.LIB. If not, write to 0020 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0021 * Boston, MA 02110-1301, USA. 0022 * 0023 */ 0024 0025 #include "nodes.h" 0026 #include "scriptfunction.h" 0027 0028 #include <math.h> 0029 #include <stdio.h> 0030 #ifdef KJS_DEBUG_MEM 0031 #include <typeinfo> 0032 #endif 0033 0034 //#include <iostream> 0035 0036 #include "debugger.h" 0037 #include "function_object.h" 0038 #include "lexer.h" 0039 #include "package.h" 0040 #include "PropertyNameArray.h" 0041 #include <wtf/AlwaysInline.h> 0042 #include <wtf/Assertions.h> 0043 #include <wtf/HashSet.h> 0044 #include <wtf/HashCountedSet.h> 0045 #include <wtf/MathExtras.h> 0046 0047 #include "bytecode/machine.h" 0048 0049 namespace KJS 0050 { 0051 0052 // ------------------------------ Node ----------------------------------------- 0053 0054 #ifndef NDEBUG 0055 struct NodeCounter { 0056 static unsigned count; 0057 ~NodeCounter() 0058 { 0059 if (count) { 0060 fprintf(stderr, "LEAK: %d KJS::Node\n", count); 0061 } 0062 } 0063 }; 0064 unsigned NodeCounter::count = 0; 0065 static NodeCounter nodeCounter; 0066 #endif 0067 0068 static HashSet<Node *> *newNodes; 0069 static HashCountedSet<Node *> *nodeExtraRefCounts; 0070 0071 Node::Node() 0072 { 0073 #ifndef NDEBUG 0074 ++NodeCounter::count; 0075 #endif 0076 m_line = lexer().lineNo(); 0077 if (!newNodes) { 0078 newNodes = new HashSet<Node *>; 0079 } 0080 newNodes->add(this); 0081 } 0082 0083 Node::~Node() 0084 { 0085 #ifndef NDEBUG 0086 --NodeCounter::count; 0087 #endif 0088 } 0089 0090 void Node::ref() 0091 { 0092 // bumping from 0 to 1 is just removing from the new nodes set 0093 if (newNodes) { 0094 HashSet<Node *>::iterator it = newNodes->find(this); 0095 if (it != newNodes->end()) { 0096 newNodes->remove(it); 0097 ASSERT(!nodeExtraRefCounts || !nodeExtraRefCounts->contains(this)); 0098 return; 0099 } 0100 } 0101 0102 ASSERT(!newNodes || !newNodes->contains(this)); 0103 0104 if (!nodeExtraRefCounts) { 0105 nodeExtraRefCounts = new HashCountedSet<Node *>; 0106 } 0107 nodeExtraRefCounts->add(this); 0108 } 0109 0110 void Node::deref() 0111 { 0112 ASSERT(!newNodes || !newNodes->contains(this)); 0113 0114 if (!nodeExtraRefCounts) { 0115 delete this; 0116 return; 0117 } 0118 0119 HashCountedSet<Node *>::iterator it = nodeExtraRefCounts->find(this); 0120 if (it == nodeExtraRefCounts->end()) { 0121 delete this; 0122 } else { 0123 nodeExtraRefCounts->remove(it); 0124 } 0125 } 0126 0127 unsigned Node::refcount() 0128 { 0129 if (newNodes && newNodes->contains(this)) { 0130 ASSERT(!nodeExtraRefCounts || !nodeExtraRefCounts->contains(this)); 0131 return 0; 0132 } 0133 0134 ASSERT(!newNodes || !newNodes->contains(this)); 0135 0136 if (!nodeExtraRefCounts) { 0137 return 1; 0138 } 0139 0140 return 1 + nodeExtraRefCounts->count(this); 0141 } 0142 0143 void Node::clearNewNodes() 0144 { 0145 if (!newNodes) { 0146 return; 0147 } 0148 0149 #ifndef NDEBUG 0150 HashSet<Node *>::iterator end = newNodes->end(); 0151 for (HashSet<Node *>::iterator it = newNodes->begin(); it != end; ++it) { 0152 ASSERT(!nodeExtraRefCounts || !nodeExtraRefCounts->contains(*it)); 0153 } 0154 #endif 0155 deleteAllValues(*newNodes); 0156 delete newNodes; 0157 newNodes = nullptr; 0158 } 0159 0160 static void substitute(UString &string, const UString &substring) 0161 { 0162 int position = string.find("%s"); 0163 assert(position != -1); 0164 UString newString = string.substr(0, position); 0165 newString.append(substring); 0166 newString.append(string.substr(position + 2)); 0167 string = newString; 0168 } 0169 0170 static inline int currentSourceId(ExecState *exec) 0171 { 0172 return exec->currentBody()->sourceId(); 0173 } 0174 0175 static inline const UString ¤tSourceURL(ExecState *exec) 0176 { 0177 return exec->currentBody()->sourceURL(); 0178 } 0179 0180 JSValue *Node::throwError(ExecState *exec, ErrorType e, const UString &msg) 0181 { 0182 return KJS::throwError(exec, e, msg, lineNo(), currentSourceId(exec), currentSourceURL(exec)); 0183 } 0184 0185 JSValue *Node::throwError(ExecState *exec, ErrorType e, const UString &msg, const Identifier &label) 0186 { 0187 UString message = msg; 0188 substitute(message, label.ustring()); 0189 return KJS::throwError(exec, e, message, lineNo(), currentSourceId(exec), currentSourceURL(exec)); 0190 } 0191 0192 JSValue *Node::throwUndefinedVariableError(ExecState *exec, const Identifier &ident) 0193 { 0194 return throwError(exec, ReferenceError, "Cannot find variable: %s", ident); 0195 } 0196 0197 Node *Node::nodeInsideAllParens() 0198 { 0199 return this; 0200 } 0201 0202 class VarDeclVisitor: public NodeVisitor 0203 { 0204 private: 0205 ExecState *m_exec; 0206 public: 0207 VarDeclVisitor(ExecState *exec) : m_exec(exec) 0208 {} 0209 0210 Node *visit(Node *node) override 0211 { 0212 node->processVarDecl(m_exec); 0213 0214 //Do not recurse inside function bodies, or things that 0215 // syntactically can't contain declarations 0216 if (!node->scanForDeclarations()) { 0217 return nullptr; 0218 } 0219 0220 return NodeVisitor::visit(node); 0221 } 0222 }; 0223 0224 class FuncDeclVisitor: public NodeVisitor 0225 { 0226 private: 0227 ExecState *m_exec; 0228 public: 0229 FuncDeclVisitor(ExecState *exec) : m_exec(exec) 0230 {} 0231 0232 Node *visit(Node *node) override 0233 { 0234 node->processFuncDecl(m_exec); 0235 0236 if (!node->scanForDeclarations()) { 0237 return nullptr; 0238 } 0239 0240 return NodeVisitor::visit(node); 0241 } 0242 }; 0243 0244 void Node::processDecls(ExecState *exec) 0245 { 0246 VarDeclVisitor vVisit(exec); 0247 vVisit.visit(this); 0248 0249 FuncDeclVisitor fVisit(exec); 0250 fVisit.visit(this); 0251 } 0252 0253 void Node::processVarDecl(ExecState *) 0254 {} 0255 0256 void Node::processFuncDecl(ExecState *) 0257 {} 0258 0259 // ------------------------------ NodeVisitor ---------------------------------- 0260 Node *NodeVisitor::visit(Node *node) 0261 { 0262 node->recurseVisit(this); 0263 return nullptr; 0264 } 0265 0266 // ------------------------------ StatementNode -------------------------------- 0267 0268 StatementNode::StatementNode() 0269 : m_lastLine(-1) 0270 { 0271 m_line = -1; 0272 } 0273 0274 void StatementNode::setLoc(int firstLine, int lastLine) const 0275 { 0276 m_line = firstLine; 0277 m_lastLine = lastLine; 0278 } 0279 0280 void StatementNode::hitStatement(ExecState *exec) 0281 { 0282 // The debugger is always non-zero here, since otherwise this won't be involved 0283 exec->dynamicInterpreter()->debugger()->reportAtStatement(exec, currentSourceId(exec), firstLine(), lastLine()); 0284 } 0285 0286 // ------------------------------ GroupNode ------------------------------------ 0287 0288 Node *GroupNode::nodeInsideAllParens() 0289 { 0290 Node *n = this; 0291 do { 0292 n = static_cast<GroupNode *>(n)->group.get(); 0293 } while (n->isGroupNode()); 0294 return n; 0295 } 0296 0297 void GroupNode::recurseVisit(NodeVisitor *visitor) 0298 { 0299 recurseVisitLink(visitor, group); 0300 } 0301 0302 // ------------------------------ ElementNode ---------------------------------- 0303 0304 void ElementNode::breakCycle() 0305 { 0306 next = nullptr; 0307 } 0308 0309 void ElementNode::recurseVisit(NodeVisitor *visitor) 0310 { 0311 recurseVisitLink(visitor, next); 0312 recurseVisitLink(visitor, node); 0313 } 0314 0315 // ------------------------------ ArrayNode ------------------------------------ 0316 0317 void ArrayNode::recurseVisit(NodeVisitor *visitor) 0318 { 0319 recurseVisitLink(visitor, element); 0320 } 0321 0322 // ------------------------------ ObjectLiteralNode ---------------------------- 0323 0324 void ObjectLiteralNode::recurseVisit(NodeVisitor *visitor) 0325 { 0326 recurseVisitLink(visitor, list); 0327 } 0328 0329 // ------------------------------ PropertyListNode ----------------------------- 0330 0331 void PropertyListNode::breakCycle() 0332 { 0333 next = nullptr; 0334 } 0335 0336 void PropertyListNode::recurseVisit(NodeVisitor *visitor) 0337 { 0338 recurseVisitLink(visitor, node); 0339 recurseVisitLink(visitor, next); 0340 } 0341 0342 // ------------------------------ PropertyNode ----------------------------- 0343 void PropertyNode::recurseVisit(NodeVisitor *visitor) 0344 { 0345 recurseVisitLink(visitor, name); 0346 recurseVisitLink(visitor, assign); 0347 } 0348 0349 // ------------------------------ BracketAccessorNode -------------------------------- 0350 0351 void BracketAccessorNode::recurseVisit(NodeVisitor *visitor) 0352 { 0353 recurseVisitLink(visitor, expr1); 0354 recurseVisitLink(visitor, expr2); 0355 } 0356 0357 // ------------------------------ DotAccessorNode -------------------------------- 0358 0359 void DotAccessorNode::recurseVisit(NodeVisitor *visitor) 0360 { 0361 recurseVisitLink(visitor, expr); 0362 } 0363 0364 // ------------------------------ ArgumentListNode ----------------------------- 0365 0366 void ArgumentListNode::breakCycle() 0367 { 0368 next = nullptr; 0369 } 0370 0371 void ArgumentListNode::recurseVisit(NodeVisitor *visitor) 0372 { 0373 recurseVisitLink(visitor, next); 0374 recurseVisitLink(visitor, expr); 0375 } 0376 0377 // ------------------------------ ArgumentsNode -------------------------------- 0378 0379 void ArgumentsNode::recurseVisit(NodeVisitor *visitor) 0380 { 0381 recurseVisitLink(visitor, list); 0382 } 0383 0384 // ------------------------------ NewExprNode ---------------------------------- 0385 0386 void NewExprNode::recurseVisit(NodeVisitor *visitor) 0387 { 0388 recurseVisitLink(visitor, expr); 0389 recurseVisitLink(visitor, args); 0390 } 0391 0392 // ------------------------------ FunctionCallValueNode ------------------------ 0393 0394 void FunctionCallValueNode::recurseVisit(NodeVisitor *visitor) 0395 { 0396 recurseVisitLink(visitor, expr); 0397 recurseVisitLink(visitor, args); 0398 } 0399 0400 // ------------------------------ FunctionCallRerefenceNode -------------------- 0401 0402 void FunctionCallReferenceNode::recurseVisit(NodeVisitor *visitor) 0403 { 0404 recurseVisitLink(visitor, expr); 0405 recurseVisitLink(visitor, args); 0406 } 0407 0408 // ------------------------------ PostfixNode ---------------------------------- 0409 0410 void PostfixNode::recurseVisit(NodeVisitor *visitor) 0411 { 0412 Node::recurseVisitLink(visitor, m_loc); 0413 } 0414 0415 // ------------------------------ DeleteReferenceNode ------------------------------- 0416 0417 void DeleteReferenceNode::recurseVisit(NodeVisitor *visitor) 0418 { 0419 Node::recurseVisitLink(visitor, loc); 0420 } 0421 0422 // ------------------------------ DeleteValueNode ----------------------------------- 0423 0424 void DeleteValueNode::recurseVisit(NodeVisitor *visitor) 0425 { 0426 recurseVisitLink(visitor, m_expr); 0427 } 0428 0429 // ------------------------------ VoidNode ------------------------------------- 0430 0431 void VoidNode::recurseVisit(NodeVisitor *visitor) 0432 { 0433 recurseVisitLink(visitor, expr); 0434 } 0435 0436 // ------------------------------ TypeOfVarNode ----------------------------------- 0437 0438 void TypeOfVarNode::recurseVisit(NodeVisitor *visitor) 0439 { 0440 Node::recurseVisitLink(visitor, loc); 0441 } 0442 0443 // ------------------------------ TypeOfValueNode ----------------------------------- 0444 0445 void TypeOfValueNode::recurseVisit(NodeVisitor *visitor) 0446 { 0447 recurseVisitLink(visitor, m_expr); 0448 } 0449 0450 // ------------------------------ PrefixNode ---------------------------------------- 0451 0452 void PrefixNode::recurseVisit(NodeVisitor *visitor) 0453 { 0454 Node::recurseVisitLink(visitor, m_loc); 0455 } 0456 0457 // ------------------------------ UnaryPlusNode -------------------------------- 0458 0459 void UnaryPlusNode::recurseVisit(NodeVisitor *visitor) 0460 { 0461 recurseVisitLink(visitor, expr); 0462 } 0463 0464 // ------------------------------ NegateNode ----------------------------------- 0465 0466 void NegateNode::recurseVisit(NodeVisitor *visitor) 0467 { 0468 recurseVisitLink(visitor, expr); 0469 } 0470 0471 // ------------------------------ BitwiseNotNode ------------------------------- 0472 0473 void BitwiseNotNode::recurseVisit(NodeVisitor *visitor) 0474 { 0475 recurseVisitLink(visitor, expr); 0476 } 0477 0478 // ------------------------------ LogicalNotNode ------------------------------- 0479 0480 void LogicalNotNode::recurseVisit(NodeVisitor *visitor) 0481 { 0482 recurseVisitLink(visitor, expr); 0483 } 0484 0485 // ------------------------ BinaryOperatorNode ------------------------------- 0486 0487 void BinaryOperatorNode::recurseVisit(NodeVisitor *visitor) 0488 { 0489 recurseVisitLink(visitor, expr1); 0490 recurseVisitLink(visitor, expr2); 0491 } 0492 0493 // ------------------------------ BinaryLogicalNode ---------------------------- 0494 0495 void BinaryLogicalNode::recurseVisit(NodeVisitor *visitor) 0496 { 0497 recurseVisitLink(visitor, expr1); 0498 recurseVisitLink(visitor, expr2); 0499 } 0500 0501 // ------------------------------ ConditionalNode ------------------------------ 0502 0503 void ConditionalNode::recurseVisit(NodeVisitor *visitor) 0504 { 0505 recurseVisitLink(visitor, logical); 0506 recurseVisitLink(visitor, expr1); 0507 recurseVisitLink(visitor, expr2); 0508 } 0509 0510 // ------------------------------ AssignNode ----------------------------------- 0511 0512 void AssignNode::recurseVisit(NodeVisitor *visitor) 0513 { 0514 Node::recurseVisitLink(visitor, m_loc); 0515 Node::recurseVisitLink(visitor, m_right); 0516 } 0517 0518 // ------------------------------ CommaNode ------------------------------------ 0519 0520 void CommaNode::recurseVisit(NodeVisitor *visitor) 0521 { 0522 recurseVisitLink(visitor, expr1); 0523 recurseVisitLink(visitor, expr2); 0524 } 0525 0526 // ------------------------------ AssignExprNode ------------------------------- 0527 0528 void AssignExprNode::recurseVisit(NodeVisitor *visitor) 0529 { 0530 recurseVisitLink(visitor, expr); 0531 } 0532 0533 // ------------------------------ VarDeclNode ---------------------------------- 0534 0535 VarDeclNode::VarDeclNode(const Identifier &id, AssignExprNode *in, Type t) 0536 : varType(t), ident(id), init(in) 0537 { 0538 } 0539 0540 #if 0 0541 // ECMA 12.2 0542 JSValue *VarDeclNode::evaluate(ExecState *exec) 0543 { 0544 JSObject *variable = exec->variableObject(); 0545 0546 JSValue *val; 0547 if (init) { 0548 val = init->evaluate(exec); 0549 KJS_CHECKEXCEPTIONVALUE 0550 } else { 0551 // already declared? - check with getDirect so you can override 0552 // built-in properties of the global object with var declarations. 0553 // Also check for 'arguments' property. The 'arguments' cannot be found with 0554 // getDirect, because it's created lazily by 0555 // ActivationImp::getOwnPropertySlot. 0556 // Since variable declarations are always in function scope, 'variable' 0557 // will always contain instance of ActivationImp and ActivationImp will 0558 // always have 'arguments' property 0559 if (variable->getDirect(ident) || ident == exec->propertyNames().arguments) { 0560 return 0; 0561 } 0562 val = jsUndefined(); 0563 } 0564 0565 #ifdef KJS_VERBOSE 0566 printInfo(exec, (UString("new variable ") + ident.ustring()).cstring().c_str(), val); 0567 #endif 0568 // We use Internal to bypass all checks in derived objects, e.g. so that 0569 // "var location" creates a dynamic property instead of activating window.location. 0570 int flags = Internal; 0571 if (exec->codeType() != EvalCode) { 0572 flags |= DontDelete; 0573 } 0574 if (varType == VarDeclNode::Constant) { 0575 flags |= ReadOnly; 0576 } 0577 variable->put(exec, ident, val, flags); 0578 0579 return 0; //No useful value, not a true expr 0580 } 0581 #endif 0582 0583 void VarDeclNode::processVarDecl(ExecState *exec) 0584 { 0585 JSObject *variable = exec->variableObject(); 0586 0587 // First, determine which flags we want to use.. 0588 int flags = DontDelete; 0589 if (varType == VarDeclNode::Constant) { 0590 flags |= ReadOnly; 0591 } 0592 0593 // Are we inside a function? If so, we fill in the symbol table 0594 switch (exec->codeType()) { 0595 case FunctionCode: 0596 // Inside a function, we're just computing static information. 0597 // so, just fill in the symbol table. 0598 exec->currentBody()->addVarDecl(ident, flags, exec); 0599 return; 0600 case EvalCode: 0601 // eval-injected variables can be deleted.. 0602 flags &= ~DontDelete; 0603 0604 // If a variable by this name already exists, don't clobber it - 0605 // eval may be trying to inject a variable that already exists.. 0606 if (!variable->hasProperty(exec, ident)) { 0607 variable->put(exec, ident, jsUndefined(), flags); 0608 // eval injected a new local into scope! Better mark that down, 0609 // so that NonLocalResolver stops skipping the local scope 0610 variable->setLocalInjected(); 0611 } 0612 break; 0613 case GlobalCode: 0614 // If a variable by this name already exists, don't clobber it - 0615 // ### I am not sue this is needed for GlobalCode 0616 if (!variable->hasProperty(exec, ident)) { 0617 variable->put(exec, ident, jsUndefined(), flags); 0618 } 0619 }; 0620 } 0621 0622 void VarDeclNode::recurseVisit(NodeVisitor *visitor) 0623 { 0624 recurseVisitLink(visitor, init); 0625 } 0626 0627 // ------------------------------ VarDeclListNode ------------------------------ 0628 0629 void VarDeclListNode::breakCycle() 0630 { 0631 next = nullptr; 0632 } 0633 0634 void VarDeclListNode::recurseVisit(NodeVisitor *visitor) 0635 { 0636 recurseVisitLink(visitor, var); 0637 recurseVisitLink(visitor, next); 0638 } 0639 0640 // ------------------------------ VarStatementNode ----------------------------- 0641 0642 void VarStatementNode::recurseVisit(NodeVisitor *visitor) 0643 { 0644 recurseVisitLink(visitor, next); 0645 } 0646 0647 // ------------------------------ BlockNode ------------------------------------ 0648 0649 BlockNode::BlockNode(SourceElementsNode *s) 0650 { 0651 if (s) { 0652 source = s->next.release(); 0653 Parser::removeNodeCycle(source.get()); 0654 setLoc(s->firstLine(), s->lastLine()); 0655 } else { 0656 source = nullptr; 0657 } 0658 } 0659 0660 void BlockNode::recurseVisit(NodeVisitor *visitor) 0661 { 0662 recurseVisitLink(visitor, source); 0663 } 0664 0665 // ------------------------------ ExprStatementNode ---------------------------- 0666 0667 void ExprStatementNode::recurseVisit(NodeVisitor *visitor) 0668 { 0669 recurseVisitLink(visitor, expr); 0670 } 0671 0672 // ------------------------------ IfNode --------------------------------------- 0673 0674 void IfNode::recurseVisit(NodeVisitor *visitor) 0675 { 0676 recurseVisitLink(visitor, expr); 0677 recurseVisitLink(visitor, statement1); 0678 recurseVisitLink(visitor, statement2); 0679 } 0680 0681 // ------------------------------ DoWhileNode ---------------------------------- 0682 0683 void DoWhileNode::recurseVisit(NodeVisitor *visitor) 0684 { 0685 recurseVisitLink(visitor, expr); 0686 recurseVisitLink(visitor, statement); 0687 } 0688 0689 // ------------------------------ WhileNode ------------------------------------ 0690 0691 void WhileNode::recurseVisit(NodeVisitor *visitor) 0692 { 0693 recurseVisitLink(visitor, expr); 0694 recurseVisitLink(visitor, statement); 0695 } 0696 0697 // ------------------------------ ForNode -------------------------------------- 0698 0699 void ForNode::recurseVisit(NodeVisitor *visitor) 0700 { 0701 recurseVisitLink(visitor, expr1); 0702 recurseVisitLink(visitor, expr2); 0703 recurseVisitLink(visitor, expr3); 0704 recurseVisitLink(visitor, statement); 0705 } 0706 0707 // ------------------------------ ForInNode ------------------------------------ 0708 0709 ForInNode::ForInNode(Node *l, Node *e, StatementNode *s) 0710 : init(nullptr), lexpr(l), expr(e), varDecl(nullptr), statement(s) 0711 { 0712 } 0713 0714 ForInNode::ForInNode(const Identifier &i, AssignExprNode *in, Node *e, StatementNode *s) 0715 : ident(i), init(in), expr(e), statement(s) 0716 { 0717 // for( var foo = bar in baz ) 0718 varDecl = new VarDeclNode(ident, init.get(), VarDeclNode::Variable); 0719 lexpr = new VarAccessNode(ident); 0720 } 0721 0722 void ForInNode::recurseVisit(NodeVisitor *visitor) 0723 { 0724 recurseVisitLink(visitor, init); 0725 recurseVisitLink(visitor, lexpr); 0726 recurseVisitLink(visitor, expr); 0727 recurseVisitLink(visitor, varDecl); 0728 recurseVisitLink(visitor, statement); 0729 } 0730 0731 // ------------------------------ ReturnNode ----------------------------------- 0732 0733 void ReturnNode::recurseVisit(NodeVisitor *visitor) 0734 { 0735 recurseVisitLink(visitor, value); 0736 } 0737 0738 // ------------------------------ WithNode ------------------------------------- 0739 0740 void WithNode::recurseVisit(NodeVisitor *visitor) 0741 { 0742 recurseVisitLink(visitor, expr); 0743 recurseVisitLink(visitor, statement); 0744 } 0745 0746 // ------------------------------ CaseClauseNode ------------------------------- 0747 0748 void CaseClauseNode::recurseVisit(NodeVisitor *visitor) 0749 { 0750 recurseVisitLink(visitor, expr); 0751 recurseVisitLink(visitor, source); 0752 } 0753 0754 // ------------------------------ ClauseListNode ------------------------------- 0755 0756 void ClauseListNode::breakCycle() 0757 { 0758 next = nullptr; 0759 } 0760 0761 void ClauseListNode::recurseVisit(NodeVisitor *visitor) 0762 { 0763 recurseVisitLink(visitor, clause); 0764 recurseVisitLink(visitor, next); 0765 } 0766 0767 // ------------------------------ CaseBlockNode -------------------------------- 0768 0769 CaseBlockNode::CaseBlockNode(ClauseListNode *l1, CaseClauseNode *d, 0770 ClauseListNode *l2) 0771 { 0772 if (l1) { 0773 list1 = l1->next.release(); 0774 Parser::removeNodeCycle(list1.get()); 0775 } else { 0776 list1 = nullptr; 0777 } 0778 0779 def = d; 0780 0781 if (l2) { 0782 list2 = l2->next.release(); 0783 Parser::removeNodeCycle(list2.get()); 0784 } else { 0785 list2 = nullptr; 0786 } 0787 } 0788 0789 void CaseBlockNode::recurseVisit(NodeVisitor *visitor) 0790 { 0791 recurseVisitLink(visitor, list1); 0792 recurseVisitLink(visitor, def); 0793 recurseVisitLink(visitor, list2); 0794 } 0795 0796 // ------------------------------ SwitchNode ----------------------------------- 0797 0798 void SwitchNode::recurseVisit(NodeVisitor *visitor) 0799 { 0800 recurseVisitLink(visitor, expr); 0801 recurseVisitLink(visitor, block); 0802 } 0803 0804 // ------------------------------ LabelNode ------------------------------------ 0805 0806 void LabelNode::recurseVisit(NodeVisitor *visitor) 0807 { 0808 recurseVisitLink(visitor, statement); 0809 } 0810 0811 // ------------------------------ ThrowNode ------------------------------------ 0812 0813 void ThrowNode::recurseVisit(NodeVisitor *visitor) 0814 { 0815 recurseVisitLink(visitor, expr); 0816 } 0817 0818 // ------------------------------ TryNode -------------------------------------- 0819 0820 void TryNode::recurseVisit(NodeVisitor *visitor) 0821 { 0822 recurseVisitLink(visitor, tryBlock); 0823 recurseVisitLink(visitor, catchBlock); 0824 recurseVisitLink(visitor, finallyBlock); 0825 } 0826 0827 // ------------------------------ ParameterNode -------------------------------- 0828 0829 void ParameterNode::breakCycle() 0830 { 0831 next = nullptr; 0832 } 0833 0834 void ParameterNode::recurseVisit(NodeVisitor *visitor) 0835 { 0836 recurseVisitLink(visitor, next); 0837 } 0838 0839 // ------------------------------ FunctionBodyNode ----------------------------- 0840 0841 FunctionBodyNode::FunctionBodyNode(SourceElementsNode *s) 0842 : BlockNode(s) 0843 , m_sourceURL(lexer().sourceURL()) 0844 , m_sourceId(parser().sourceId()) 0845 , m_compType(NotCompiled) 0846 , m_flags(parser().popFunctionContext()) 0847 { 0848 setLoc(-1, -1); 0849 } 0850 0851 void FunctionBodyNode::addVarDecl(const Identifier &ident, int attr, ExecState *exec) 0852 { 0853 // There is one nasty special case: ignore a 'var' declaration of 'arguments'; 0854 // it effectively doesn't do anything since the magic 'arguments' is already 0855 // in scope anyway, and if we allocated a local, we would have to worry about 0856 // keeping track of whether it was initialized or not on what is supposed to be the 0857 // fast path. So we just make this go through the property map instead. 0858 // Note that this does not matter for parameters or function declarations, 0859 // since those overwrite the magic 'arguments' anyway. 0860 if (ident == exec->propertyNames().arguments) { 0861 return; 0862 } 0863 0864 (void)addSymbol(ident, attr); 0865 } 0866 0867 void FunctionBodyNode::addFunDecl(const Identifier &ident, int attr, FuncDeclNode *funcDecl) 0868 { 0869 m_functionLocals.append(addSymbol(ident, attr, funcDecl)); 0870 } 0871 0872 void FunctionBodyNode::reserveSlot(size_t id, bool shouldMark) 0873 { 0874 ASSERT(id == m_symbolList.size()); 0875 m_symbolList.append(SymbolInfo(shouldMark ? 0 : DontMark, nullptr)); 0876 } 0877 0878 size_t FunctionBodyNode::addSymbol(const Identifier &ident, int flags, FuncDeclNode *funcDecl) 0879 { 0880 // We get symbols in the order specified in 10.1.3, but sometimes 0881 // the later ones are supposed to lose. This -mostly- does not 0882 // matter for us --- we primarily concern ourselves with name/ID 0883 // mapping, but there is an issue of attributes and funcDecl's. 0884 // However, the only flag that matters here is ReadOnly -- 0885 // everything else just has DontDelete set; and it's from const, 0886 // so we can just ignore it on repetitions, since var/const should lose 0887 // and are at the end. 0888 // 0889 // And for funcDecl, since functions win over everything, we always set it if non-zero 0890 size_t oldId = m_symbolTable.get(ident.ustring().rep()); 0891 if (oldId != missingSymbolMarker()) { 0892 if (funcDecl) { 0893 m_symbolList[oldId].funcDecl = funcDecl; 0894 } 0895 return oldId; 0896 } 0897 0898 size_t id = m_symbolList.size(); //First entry gets 0, etc. 0899 m_symbolTable.set(ident.ustring().rep(), id); 0900 m_symbolList.append(SymbolInfo(flags, funcDecl)); 0901 return id; 0902 } 0903 0904 void FunctionBodyNode::addSymbolOverwriteID(size_t id, const Identifier &ident, int flags) 0905 { 0906 ASSERT(id == m_symbolList.size()); 0907 0908 // Remove previous one, if any 0909 size_t oldId = m_symbolTable.get(ident.ustring().rep()); 0910 if (oldId != missingSymbolMarker()) { 0911 m_symbolList[oldId].attr = DontMark; 0912 } 0913 0914 // Add a new one 0915 m_symbolTable.set(ident.ustring().rep(), id); 0916 m_symbolList.append(SymbolInfo(flags, nullptr)); 0917 } 0918 0919 void FunctionBodyNode::addParam(const Identifier &ident) 0920 { 0921 m_paramList.append(ident); 0922 } 0923 0924 Completion FunctionBodyNode::execute(ExecState *exec) 0925 { 0926 CodeType ctype = exec->codeType(); 0927 CompileType cmpType = exec->dynamicInterpreter()->debugger() ? Debug : Release; 0928 compileIfNeeded(ctype, cmpType); 0929 ASSERT(ctype != FunctionCode); 0930 0931 LocalStorage *store = new LocalStorage(); 0932 LocalStorageEntry *regs; 0933 0934 // Allocate enough space, and make sure to initialize things so we don't mark garbage 0935 store->resize(m_symbolList.size()); 0936 regs = store->data(); 0937 for (size_t c = 0; c < m_symbolList.size(); ++c) { 0938 regs[c].val.valueVal = jsUndefined(); 0939 regs[c].attributes = m_symbolList[c].attr; 0940 } 0941 0942 exec->initLocalStorage(regs, m_symbolList.size()); 0943 0944 JSValue *val = Machine::runBlock(exec, m_compiledCode); 0945 0946 Completion result; 0947 if (exec->hadException()) { 0948 result = Completion(Throw, exec->exception()); 0949 } else { 0950 result = Completion(Normal, val); 0951 } 0952 0953 exec->initLocalStorage(nullptr, 0); 0954 delete store; 0955 exec->clearException(); 0956 0957 return result; 0958 } 0959 0960 void FunctionBodyNode::compile(CodeType ctype, CompileType compType) 0961 { 0962 m_compType = compType; 0963 0964 CompileState comp(ctype, compType, this, m_symbolList.size()); 0965 generateExecCode(&comp); 0966 m_tearOffAtEnd = comp.needsClosures(); 0967 0968 #if 0 0969 fprintf(stderr, "\n\n"); 0970 fprintf(stderr, "\n---------------------------------\n\n"); 0971 fprintf(stderr, "%s", toString().ascii()); 0972 fprintf(stderr, "\n---------------------------------\n\n"); 0973 CodeGen::disassembleBlock(m_compiledCode); 0974 fprintf(stderr, "\n---------------------------------\n\n"); 0975 #endif 0976 } 0977 0978 // ------------------------------ FuncDeclNode --------------------------------- 0979 0980 // ECMA 13 0981 void FuncDeclNode::processFuncDecl(ExecState *exec) 0982 { 0983 // See whether we just need to fill in the symbol table, 0984 // or actually fiddle with objects. 0985 int flags = Internal | DontDelete; 0986 switch (exec->codeType()) { 0987 case FunctionCode: 0988 // Inside a function, just need symbol info 0989 exec->currentBody()->addFunDecl(ident, flags, this); 0990 return; 0991 case EvalCode: 0992 // eval-injected symbols can be deleted... 0993 flags &= ~DontDelete; 0994 0995 // eval injected a new local into scope! Better mark that down, 0996 // so that NonLocalResolver stops skipping the local scope 0997 exec->variableObject()->setLocalInjected(); 0998 0999 // fallthrough intentional 1000 case GlobalCode: 1001 exec->variableObject()->put(exec, ident, makeFunctionObject(exec), flags); 1002 }; 1003 } 1004 1005 void FuncDeclNode::addParams() 1006 { 1007 for (ParameterNode *p = param.get(); p != nullptr; p = p->nextParam()) { 1008 body->addParam(p->ident()); 1009 } 1010 } 1011 1012 FunctionImp *FuncDeclNode::makeFunctionObject(ExecState *exec) 1013 { 1014 // TODO: let this be an object with [[Class]] property "Function" 1015 FunctionImp *func = new FunctionImp(exec, ident, body.get(), exec->scopeChain()); 1016 1017 JSObject *proto = exec->lexicalInterpreter()->builtinObject()->construct(exec, List::empty()); 1018 proto->put(exec, exec->propertyNames().constructor, func, DontEnum); 1019 // ECMA Edition 5.1r6 - 15.3.5.2 - [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false 1020 func->put(exec, exec->propertyNames().prototype, proto, Internal | DontDelete | DontEnum); 1021 1022 func->put(exec, exec->propertyNames().length, jsNumber(body->numParams()), ReadOnly | DontDelete | DontEnum); 1023 1024 return func; 1025 } 1026 1027 void FuncDeclNode::recurseVisit(NodeVisitor *visitor) 1028 { 1029 recurseVisitLink(visitor, param); 1030 recurseVisitLink(visitor, body); 1031 } 1032 1033 // ------------------------------ FuncExprNode --------------------------------- 1034 1035 void FuncExprNode::addParams() 1036 { 1037 for (ParameterNode *p = param.get(); p != nullptr; p = p->nextParam()) { 1038 body->addParam(p->ident()); 1039 } 1040 } 1041 1042 void FuncExprNode::recurseVisit(NodeVisitor *visitor) 1043 { 1044 recurseVisitLink(visitor, param); 1045 recurseVisitLink(visitor, body); 1046 } 1047 1048 // ------------------------------ SourceElementsNode --------------------------- 1049 1050 SourceElementsNode::SourceElementsNode(StatementNode *s1) 1051 : node(s1), next(this) 1052 { 1053 Parser::noteNodeCycle(this); 1054 setLoc(s1->firstLine(), s1->lastLine()); 1055 } 1056 1057 SourceElementsNode::SourceElementsNode(SourceElementsNode *s1, StatementNode *s2) 1058 : node(s2), next(s1->next) 1059 { 1060 s1->next = this; 1061 setLoc(s1->firstLine(), s2->lastLine()); 1062 } 1063 1064 void SourceElementsNode::breakCycle() 1065 { 1066 next = nullptr; 1067 } 1068 1069 void SourceElementsNode::recurseVisit(NodeVisitor *visitor) 1070 { 1071 recurseVisitLink(visitor, node); 1072 recurseVisitLink(visitor, next); 1073 } 1074 1075 // ------------------------------ ProgramNode ---------------------------------- 1076 1077 ProgramNode::ProgramNode(SourceElementsNode *s) : FunctionBodyNode(s) 1078 { 1079 } 1080 1081 // ------------------------------ PackageNameNode ------------------------------ 1082 void PackageNameNode::recurseVisit(NodeVisitor *visitor) 1083 { 1084 recurseVisitLink(visitor, names); 1085 } 1086 1087 Completion PackageNameNode::loadSymbol(ExecState *exec, bool wildcard) 1088 { 1089 Package *basePackage; 1090 JSObject *baseObject; 1091 if (names) { 1092 PackageObject *pobj = names->resolvePackage(exec); 1093 if (pobj == nullptr) { 1094 return Completion(Normal); 1095 } 1096 basePackage = pobj->package(); 1097 baseObject = pobj; 1098 } else { 1099 Interpreter *ip = exec->lexicalInterpreter(); 1100 basePackage = ip->globalPackage(); 1101 baseObject = ip->globalObject(); 1102 } 1103 1104 if (wildcard) { 1105 // if a .* is specified the last identifier should 1106 // denote another package name 1107 PackageObject *pobj = resolvePackage(exec, baseObject, basePackage); 1108 if (!pobj) { 1109 return Completion(Normal); 1110 } 1111 basePackage = pobj->package(); 1112 baseObject = pobj; 1113 basePackage->loadAllSymbols(exec, baseObject); 1114 } else { 1115 basePackage->loadSymbol(exec, baseObject, id); 1116 } 1117 1118 return Completion(Normal); 1119 } 1120 1121 PackageObject *PackageNameNode::resolvePackage(ExecState *exec) 1122 { 1123 JSObject *baseObject; 1124 Package *basePackage; 1125 if (names) { 1126 PackageObject *basePackageObject = names->resolvePackage(exec); 1127 if (basePackageObject == nullptr) { 1128 return nullptr; 1129 } 1130 baseObject = basePackageObject; 1131 basePackage = basePackageObject->package(); 1132 } else { 1133 // first identifier is looked up in global object 1134 Interpreter *ip = exec->lexicalInterpreter(); 1135 baseObject = ip->globalObject(); 1136 basePackage = ip->globalPackage(); 1137 } 1138 1139 return resolvePackage(exec, baseObject, basePackage); 1140 } 1141 1142 PackageObject *PackageNameNode::resolvePackage(ExecState *exec, 1143 JSObject *baseObject, 1144 Package *basePackage) 1145 { 1146 PackageObject *res = nullptr; 1147 1148 // Let's see whether the package was already resolved previously. 1149 JSValue *v = baseObject->get(exec, id); 1150 if (v && !JSValue::isUndefined(v)) { 1151 if (!JSValue::isObject(v)) { 1152 // Symbol conflict 1153 throwError(exec, GeneralError, "Invalid type of package %s", id); 1154 return nullptr; 1155 } 1156 res = static_cast<PackageObject *>(v); 1157 } else { 1158 UString err; 1159 Package *newBase = basePackage->loadSubPackage(id, &err); 1160 if (newBase == nullptr) { 1161 if (err.isEmpty()) { 1162 throwError(exec, GeneralError, "Package not found"); 1163 } else { 1164 throwError(exec, GeneralError, err); 1165 } 1166 return nullptr; 1167 } 1168 res = new PackageObject(newBase); 1169 baseObject->put(exec, id, res); 1170 } 1171 1172 return res; 1173 } 1174 1175 void ImportStatement::processVarDecl(ExecState *exec) 1176 { 1177 // error out if package support is not activated 1178 Package *glob = exec->lexicalInterpreter()->globalPackage(); 1179 if (!glob) { 1180 throwError(exec, GeneralError, 1181 "Package support disabled. Import failed."); 1182 return; 1183 } 1184 1185 // also error out if not used on top-level 1186 if (exec->codeType() != GlobalCode) { 1187 throwError(exec, GeneralError, 1188 "Package imports may only occur at top level."); 1189 return; 1190 } 1191 1192 name->loadSymbol(exec, wld); 1193 } 1194 1195 void ImportStatement::recurseVisit(NodeVisitor *visitor) 1196 { 1197 recurseVisitLink(visitor, name); 1198 } 1199 1200 } //namespace KJS