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 &currentSourceURL(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