1 /*
2  *  This file is part of the KDE libraries
3  *  Copyright (C) 1999-2002 Harri Porten (porten@kde.org)
4  *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
5  *  Copyright (C) 2003, 2004, 2005, 2006, 2007 Apple Inc. All rights reserved.
6  *  Copyright (C) 2007 Maksim Orlovich (maksim@kde.org)
7  *
8  *  This library is free software; you can redistribute it and/or
9  *  modify it under the terms of the GNU Library General Public
10  *  License as published by the Free Software Foundation; either
11  *  version 2 of the License, or (at your option) any later version.
12  *
13  *  This library is distributed in the hope that it will be useful,
14  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  *  Library General Public License for more details.
17  *
18  *  You should have received a copy of the GNU Library General Public License
19  *  along with this library; see the file COPYING.LIB.  If not, write to
20  *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21  *  Boston, MA 02110-1301, USA.
22  *
23  */
24 
25 #include "nodes.h"
26 #include "scriptfunction.h"
27 
28 #include <math.h>
29 #include <stdio.h>
30 #ifdef KJS_DEBUG_MEM
31 #include <typeinfo>
32 #endif
33 
34 //#include <iostream>
35 
36 #include "debugger.h"
37 #include "function_object.h"
38 #include "lexer.h"
39 #include "package.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>
46 
47 #include "bytecode/machine.h"
48 
49 namespace KJS
50 {
51 
52 // ------------------------------ Node -----------------------------------------
53 
54 #ifndef NDEBUG
55 struct NodeCounter {
56     static unsigned count;
~NodeCounterKJS::NodeCounter57     ~NodeCounter()
58     {
59         if (count) {
60             fprintf(stderr, "LEAK: %d KJS::Node\n", count);
61         }
62     }
63 };
64 unsigned NodeCounter::count = 0;
65 static NodeCounter nodeCounter;
66 #endif
67 
68 static HashSet<Node *> *newNodes;
69 static HashCountedSet<Node *> *nodeExtraRefCounts;
70 
Node()71 Node::Node()
72 {
73 #ifndef NDEBUG
74     ++NodeCounter::count;
75 #endif
76     m_line = lexer().lineNo();
77     if (!newNodes) {
78         newNodes = new HashSet<Node *>;
79     }
80     newNodes->add(this);
81 }
82 
~Node()83 Node::~Node()
84 {
85 #ifndef NDEBUG
86     --NodeCounter::count;
87 #endif
88 }
89 
ref()90 void Node::ref()
91 {
92     // bumping from 0 to 1 is just removing from the new nodes set
93     if (newNodes) {
94         HashSet<Node *>::iterator it = newNodes->find(this);
95         if (it != newNodes->end()) {
96             newNodes->remove(it);
97             ASSERT(!nodeExtraRefCounts || !nodeExtraRefCounts->contains(this));
98             return;
99         }
100     }
101 
102     ASSERT(!newNodes || !newNodes->contains(this));
103 
104     if (!nodeExtraRefCounts) {
105         nodeExtraRefCounts = new HashCountedSet<Node *>;
106     }
107     nodeExtraRefCounts->add(this);
108 }
109 
deref()110 void Node::deref()
111 {
112     ASSERT(!newNodes || !newNodes->contains(this));
113 
114     if (!nodeExtraRefCounts) {
115         delete this;
116         return;
117     }
118 
119     HashCountedSet<Node *>::iterator it = nodeExtraRefCounts->find(this);
120     if (it == nodeExtraRefCounts->end()) {
121         delete this;
122     } else {
123         nodeExtraRefCounts->remove(it);
124     }
125 }
126 
refcount()127 unsigned Node::refcount()
128 {
129     if (newNodes && newNodes->contains(this)) {
130         ASSERT(!nodeExtraRefCounts || !nodeExtraRefCounts->contains(this));
131         return 0;
132     }
133 
134     ASSERT(!newNodes || !newNodes->contains(this));
135 
136     if (!nodeExtraRefCounts) {
137         return 1;
138     }
139 
140     return 1 + nodeExtraRefCounts->count(this);
141 }
142 
clearNewNodes()143 void Node::clearNewNodes()
144 {
145     if (!newNodes) {
146         return;
147     }
148 
149 #ifndef NDEBUG
150     HashSet<Node *>::iterator end = newNodes->end();
151     for (HashSet<Node *>::iterator it = newNodes->begin(); it != end; ++it) {
152         ASSERT(!nodeExtraRefCounts || !nodeExtraRefCounts->contains(*it));
153     }
154 #endif
155     deleteAllValues(*newNodes);
156     delete newNodes;
157     newNodes = nullptr;
158 }
159 
substitute(UString & string,const UString & substring)160 static void substitute(UString &string, const UString &substring)
161 {
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));
167     string = newString;
168 }
169 
currentSourceId(ExecState * exec)170 static inline int currentSourceId(ExecState *exec)
171 {
172     return exec->currentBody()->sourceId();
173 }
174 
currentSourceURL(ExecState * exec)175 static inline const UString &currentSourceURL(ExecState *exec)
176 {
177     return exec->currentBody()->sourceURL();
178 }
179 
throwError(ExecState * exec,ErrorType e,const UString & msg)180 JSValue *Node::throwError(ExecState *exec, ErrorType e, const UString &msg)
181 {
182     return KJS::throwError(exec, e, msg, lineNo(), currentSourceId(exec), currentSourceURL(exec));
183 }
184 
throwError(ExecState * exec,ErrorType e,const UString & msg,const Identifier & label)185 JSValue *Node::throwError(ExecState *exec, ErrorType e, const UString &msg, const Identifier &label)
186 {
187     UString message = msg;
188     substitute(message, label.ustring());
189     return KJS::throwError(exec, e, message, lineNo(), currentSourceId(exec), currentSourceURL(exec));
190 }
191 
throwUndefinedVariableError(ExecState * exec,const Identifier & ident)192 JSValue *Node::throwUndefinedVariableError(ExecState *exec, const Identifier &ident)
193 {
194     return throwError(exec, ReferenceError, "Cannot find variable: %s", ident);
195 }
196 
nodeInsideAllParens()197 Node *Node::nodeInsideAllParens()
198 {
199     return this;
200 }
201 
202 class VarDeclVisitor: public NodeVisitor
203 {
204 private:
205     ExecState *m_exec;
206 public:
VarDeclVisitor(ExecState * exec)207     VarDeclVisitor(ExecState *exec) : m_exec(exec)
208     {}
209 
visit(Node * node)210     Node *visit(Node *node) override
211     {
212         node->processVarDecl(m_exec);
213 
214         //Do not recurse inside function bodies, or things that
215         // syntactically can't contain declarations
216         if (!node->scanForDeclarations()) {
217             return nullptr;
218         }
219 
220         return NodeVisitor::visit(node);
221     }
222 };
223 
224 class FuncDeclVisitor: public NodeVisitor
225 {
226 private:
227     ExecState *m_exec;
228 public:
FuncDeclVisitor(ExecState * exec)229     FuncDeclVisitor(ExecState *exec) : m_exec(exec)
230     {}
231 
visit(Node * node)232     Node *visit(Node *node) override
233     {
234         node->processFuncDecl(m_exec);
235 
236         if (!node->scanForDeclarations()) {
237             return nullptr;
238         }
239 
240         return NodeVisitor::visit(node);
241     }
242 };
243 
processDecls(ExecState * exec)244 void Node::processDecls(ExecState *exec)
245 {
246     VarDeclVisitor vVisit(exec);
247     vVisit.visit(this);
248 
249     FuncDeclVisitor fVisit(exec);
250     fVisit.visit(this);
251 }
252 
processVarDecl(ExecState *)253 void Node::processVarDecl(ExecState *)
254 {}
255 
processFuncDecl(ExecState *)256 void Node::processFuncDecl(ExecState *)
257 {}
258 
259 // ------------------------------ NodeVisitor ----------------------------------
visit(Node * node)260 Node *NodeVisitor::visit(Node *node)
261 {
262     node->recurseVisit(this);
263     return nullptr;
264 }
265 
266 // ------------------------------ StatementNode --------------------------------
267 
StatementNode()268 StatementNode::StatementNode()
269     : m_lastLine(-1)
270 {
271     m_line = -1;
272 }
273 
setLoc(int firstLine,int lastLine) const274 void StatementNode::setLoc(int firstLine, int lastLine) const
275 {
276     m_line = firstLine;
277     m_lastLine = lastLine;
278 }
279 
hitStatement(ExecState * exec)280 void StatementNode::hitStatement(ExecState *exec)
281 {
282     // The debugger is always non-zero here, since otherwise this won't be involved
283     exec->dynamicInterpreter()->debugger()->reportAtStatement(exec, currentSourceId(exec), firstLine(), lastLine());
284 }
285 
286 // ------------------------------ GroupNode ------------------------------------
287 
nodeInsideAllParens()288 Node *GroupNode::nodeInsideAllParens()
289 {
290     Node *n = this;
291     do {
292         n = static_cast<GroupNode *>(n)->group.get();
293     } while (n->isGroupNode());
294     return n;
295 }
296 
recurseVisit(NodeVisitor * visitor)297 void GroupNode::recurseVisit(NodeVisitor *visitor)
298 {
299     recurseVisitLink(visitor, group);
300 }
301 
302 // ------------------------------ ElementNode ----------------------------------
303 
breakCycle()304 void ElementNode::breakCycle()
305 {
306     next = nullptr;
307 }
308 
recurseVisit(NodeVisitor * visitor)309 void ElementNode::recurseVisit(NodeVisitor *visitor)
310 {
311     recurseVisitLink(visitor, next);
312     recurseVisitLink(visitor, node);
313 }
314 
315 // ------------------------------ ArrayNode ------------------------------------
316 
recurseVisit(NodeVisitor * visitor)317 void ArrayNode::recurseVisit(NodeVisitor *visitor)
318 {
319     recurseVisitLink(visitor, element);
320 }
321 
322 // ------------------------------ ObjectLiteralNode ----------------------------
323 
recurseVisit(NodeVisitor * visitor)324 void ObjectLiteralNode::recurseVisit(NodeVisitor *visitor)
325 {
326     recurseVisitLink(visitor, list);
327 }
328 
329 // ------------------------------ PropertyListNode -----------------------------
330 
breakCycle()331 void PropertyListNode::breakCycle()
332 {
333     next = nullptr;
334 }
335 
recurseVisit(NodeVisitor * visitor)336 void PropertyListNode::recurseVisit(NodeVisitor *visitor)
337 {
338     recurseVisitLink(visitor, node);
339     recurseVisitLink(visitor, next);
340 }
341 
342 // ------------------------------ PropertyNode -----------------------------
recurseVisit(NodeVisitor * visitor)343 void PropertyNode::recurseVisit(NodeVisitor *visitor)
344 {
345     recurseVisitLink(visitor, name);
346     recurseVisitLink(visitor, assign);
347 }
348 
349 // ------------------------------ BracketAccessorNode --------------------------------
350 
recurseVisit(NodeVisitor * visitor)351 void BracketAccessorNode::recurseVisit(NodeVisitor *visitor)
352 {
353     recurseVisitLink(visitor, expr1);
354     recurseVisitLink(visitor, expr2);
355 }
356 
357 // ------------------------------ DotAccessorNode --------------------------------
358 
recurseVisit(NodeVisitor * visitor)359 void DotAccessorNode::recurseVisit(NodeVisitor *visitor)
360 {
361     recurseVisitLink(visitor, expr);
362 }
363 
364 // ------------------------------ ArgumentListNode -----------------------------
365 
breakCycle()366 void ArgumentListNode::breakCycle()
367 {
368     next = nullptr;
369 }
370 
recurseVisit(NodeVisitor * visitor)371 void ArgumentListNode::recurseVisit(NodeVisitor *visitor)
372 {
373     recurseVisitLink(visitor, next);
374     recurseVisitLink(visitor, expr);
375 }
376 
377 // ------------------------------ ArgumentsNode --------------------------------
378 
recurseVisit(NodeVisitor * visitor)379 void ArgumentsNode::recurseVisit(NodeVisitor *visitor)
380 {
381     recurseVisitLink(visitor, list);
382 }
383 
384 // ------------------------------ NewExprNode ----------------------------------
385 
recurseVisit(NodeVisitor * visitor)386 void NewExprNode::recurseVisit(NodeVisitor *visitor)
387 {
388     recurseVisitLink(visitor, expr);
389     recurseVisitLink(visitor, args);
390 }
391 
392 // ------------------------------ FunctionCallValueNode ------------------------
393 
recurseVisit(NodeVisitor * visitor)394 void FunctionCallValueNode::recurseVisit(NodeVisitor *visitor)
395 {
396     recurseVisitLink(visitor, expr);
397     recurseVisitLink(visitor, args);
398 }
399 
400 // ------------------------------ FunctionCallRerefenceNode --------------------
401 
recurseVisit(NodeVisitor * visitor)402 void FunctionCallReferenceNode::recurseVisit(NodeVisitor *visitor)
403 {
404     recurseVisitLink(visitor, expr);
405     recurseVisitLink(visitor, args);
406 }
407 
408 // ------------------------------ PostfixNode ----------------------------------
409 
recurseVisit(NodeVisitor * visitor)410 void PostfixNode::recurseVisit(NodeVisitor *visitor)
411 {
412     Node::recurseVisitLink(visitor, m_loc);
413 }
414 
415 // ------------------------------ DeleteReferenceNode -------------------------------
416 
recurseVisit(NodeVisitor * visitor)417 void DeleteReferenceNode::recurseVisit(NodeVisitor *visitor)
418 {
419     Node::recurseVisitLink(visitor, loc);
420 }
421 
422 // ------------------------------ DeleteValueNode -----------------------------------
423 
recurseVisit(NodeVisitor * visitor)424 void DeleteValueNode::recurseVisit(NodeVisitor *visitor)
425 {
426     recurseVisitLink(visitor, m_expr);
427 }
428 
429 // ------------------------------ VoidNode -------------------------------------
430 
recurseVisit(NodeVisitor * visitor)431 void VoidNode::recurseVisit(NodeVisitor *visitor)
432 {
433     recurseVisitLink(visitor, expr);
434 }
435 
436 // ------------------------------ TypeOfVarNode -----------------------------------
437 
recurseVisit(NodeVisitor * visitor)438 void TypeOfVarNode::recurseVisit(NodeVisitor *visitor)
439 {
440     Node::recurseVisitLink(visitor, loc);
441 }
442 
443 // ------------------------------ TypeOfValueNode -----------------------------------
444 
recurseVisit(NodeVisitor * visitor)445 void TypeOfValueNode::recurseVisit(NodeVisitor *visitor)
446 {
447     recurseVisitLink(visitor, m_expr);
448 }
449 
450 // ------------------------------ PrefixNode ----------------------------------------
451 
recurseVisit(NodeVisitor * visitor)452 void PrefixNode::recurseVisit(NodeVisitor *visitor)
453 {
454     Node::recurseVisitLink(visitor, m_loc);
455 }
456 
457 // ------------------------------ UnaryPlusNode --------------------------------
458 
recurseVisit(NodeVisitor * visitor)459 void UnaryPlusNode::recurseVisit(NodeVisitor *visitor)
460 {
461     recurseVisitLink(visitor, expr);
462 }
463 
464 // ------------------------------ NegateNode -----------------------------------
465 
recurseVisit(NodeVisitor * visitor)466 void NegateNode::recurseVisit(NodeVisitor *visitor)
467 {
468     recurseVisitLink(visitor, expr);
469 }
470 
471 // ------------------------------ BitwiseNotNode -------------------------------
472 
recurseVisit(NodeVisitor * visitor)473 void BitwiseNotNode::recurseVisit(NodeVisitor *visitor)
474 {
475     recurseVisitLink(visitor, expr);
476 }
477 
478 // ------------------------------ LogicalNotNode -------------------------------
479 
recurseVisit(NodeVisitor * visitor)480 void LogicalNotNode::recurseVisit(NodeVisitor *visitor)
481 {
482     recurseVisitLink(visitor, expr);
483 }
484 
485 // ------------------------ BinaryOperatorNode -------------------------------
486 
recurseVisit(NodeVisitor * visitor)487 void BinaryOperatorNode::recurseVisit(NodeVisitor *visitor)
488 {
489     recurseVisitLink(visitor, expr1);
490     recurseVisitLink(visitor, expr2);
491 }
492 
493 // ------------------------------ BinaryLogicalNode ----------------------------
494 
recurseVisit(NodeVisitor * visitor)495 void BinaryLogicalNode::recurseVisit(NodeVisitor *visitor)
496 {
497     recurseVisitLink(visitor, expr1);
498     recurseVisitLink(visitor, expr2);
499 }
500 
501 // ------------------------------ ConditionalNode ------------------------------
502 
recurseVisit(NodeVisitor * visitor)503 void ConditionalNode::recurseVisit(NodeVisitor *visitor)
504 {
505     recurseVisitLink(visitor, logical);
506     recurseVisitLink(visitor, expr1);
507     recurseVisitLink(visitor, expr2);
508 }
509 
510 // ------------------------------ AssignNode -----------------------------------
511 
recurseVisit(NodeVisitor * visitor)512 void AssignNode::recurseVisit(NodeVisitor *visitor)
513 {
514     Node::recurseVisitLink(visitor, m_loc);
515     Node::recurseVisitLink(visitor, m_right);
516 }
517 
518 // ------------------------------ CommaNode ------------------------------------
519 
recurseVisit(NodeVisitor * visitor)520 void CommaNode::recurseVisit(NodeVisitor *visitor)
521 {
522     recurseVisitLink(visitor, expr1);
523     recurseVisitLink(visitor, expr2);
524 }
525 
526 // ------------------------------ AssignExprNode -------------------------------
527 
recurseVisit(NodeVisitor * visitor)528 void AssignExprNode::recurseVisit(NodeVisitor *visitor)
529 {
530     recurseVisitLink(visitor, expr);
531 }
532 
533 // ------------------------------ VarDeclNode ----------------------------------
534 
VarDeclNode(const Identifier & id,AssignExprNode * in,Type t)535 VarDeclNode::VarDeclNode(const Identifier &id, AssignExprNode *in, Type t)
536     : varType(t), ident(id), init(in)
537 {
538 }
539 
540 #if 0
541 // ECMA 12.2
542 JSValue *VarDeclNode::evaluate(ExecState *exec)
543 {
544     JSObject *variable = exec->variableObject();
545 
546     JSValue *val;
547     if (init) {
548         val = init->evaluate(exec);
549         KJS_CHECKEXCEPTIONVALUE
550     } else {
551         // already declared? - check with getDirect so you can override
552         // built-in properties of the global object with var declarations.
553         // Also check for 'arguments' property. The 'arguments' cannot be found with
554         // getDirect, because it's created lazily by
555         // ActivationImp::getOwnPropertySlot.
556         // Since variable declarations are always in function scope, 'variable'
557         // will always contain instance of ActivationImp and ActivationImp will
558         // always have 'arguments' property
559         if (variable->getDirect(ident) || ident == exec->propertyNames().arguments) {
560             return 0;
561         }
562         val = jsUndefined();
563     }
564 
565 #ifdef KJS_VERBOSE
566     printInfo(exec, (UString("new variable ") + ident.ustring()).cstring().c_str(), val);
567 #endif
568     // We use Internal to bypass all checks in derived objects, e.g. so that
569     // "var location" creates a dynamic property instead of activating window.location.
570     int flags = Internal;
571     if (exec->codeType() != EvalCode) {
572         flags |= DontDelete;
573     }
574     if (varType == VarDeclNode::Constant) {
575         flags |= ReadOnly;
576     }
577     variable->put(exec, ident, val, flags);
578 
579     return 0; //No useful value, not a true expr
580 }
581 #endif
582 
processVarDecl(ExecState * exec)583 void VarDeclNode::processVarDecl(ExecState *exec)
584 {
585     JSObject *variable = exec->variableObject();
586 
587     // First, determine which flags we want to use..
588     int flags = DontDelete;
589     if (varType == VarDeclNode::Constant) {
590         flags |= ReadOnly;
591     }
592 
593     // Are we inside a function? If so, we fill in the symbol table
594     switch (exec->codeType()) {
595     case FunctionCode:
596         // Inside a function, we're just computing static information.
597         // so, just fill in the symbol table.
598         exec->currentBody()->addVarDecl(ident, flags, exec);
599         return;
600     case EvalCode:
601         // eval-injected variables can be deleted..
602         flags &= ~DontDelete;
603 
604         // If a variable by this name already exists, don't clobber it -
605         // eval may be trying to inject a variable that already exists..
606         if (!variable->hasProperty(exec, ident)) {
607             variable->put(exec, ident, jsUndefined(), flags);
608             // eval injected a new local into scope! Better mark that down,
609             // so that NonLocalResolver stops skipping the local scope
610             variable->setLocalInjected();
611         }
612         break;
613     case GlobalCode:
614         // If a variable by this name already exists, don't clobber it -
615         // ### I am not sue this is needed for GlobalCode
616         if (!variable->hasProperty(exec, ident)) {
617             variable->put(exec, ident, jsUndefined(), flags);
618         }
619     };
620 }
621 
recurseVisit(NodeVisitor * visitor)622 void VarDeclNode::recurseVisit(NodeVisitor *visitor)
623 {
624     recurseVisitLink(visitor, init);
625 }
626 
627 // ------------------------------ VarDeclListNode ------------------------------
628 
breakCycle()629 void VarDeclListNode::breakCycle()
630 {
631     next = nullptr;
632 }
633 
recurseVisit(NodeVisitor * visitor)634 void VarDeclListNode::recurseVisit(NodeVisitor *visitor)
635 {
636     recurseVisitLink(visitor, var);
637     recurseVisitLink(visitor, next);
638 }
639 
640 // ------------------------------ VarStatementNode -----------------------------
641 
recurseVisit(NodeVisitor * visitor)642 void VarStatementNode::recurseVisit(NodeVisitor *visitor)
643 {
644     recurseVisitLink(visitor, next);
645 }
646 
647 // ------------------------------ BlockNode ------------------------------------
648 
BlockNode(SourceElementsNode * s)649 BlockNode::BlockNode(SourceElementsNode *s)
650 {
651     if (s) {
652         source = s->next.release();
653         Parser::removeNodeCycle(source.get());
654         setLoc(s->firstLine(), s->lastLine());
655     } else {
656         source = nullptr;
657     }
658 }
659 
recurseVisit(NodeVisitor * visitor)660 void BlockNode::recurseVisit(NodeVisitor *visitor)
661 {
662     recurseVisitLink(visitor, source);
663 }
664 
665 // ------------------------------ ExprStatementNode ----------------------------
666 
recurseVisit(NodeVisitor * visitor)667 void ExprStatementNode::recurseVisit(NodeVisitor *visitor)
668 {
669     recurseVisitLink(visitor, expr);
670 }
671 
672 // ------------------------------ IfNode ---------------------------------------
673 
recurseVisit(NodeVisitor * visitor)674 void IfNode::recurseVisit(NodeVisitor *visitor)
675 {
676     recurseVisitLink(visitor, expr);
677     recurseVisitLink(visitor, statement1);
678     recurseVisitLink(visitor, statement2);
679 }
680 
681 // ------------------------------ DoWhileNode ----------------------------------
682 
recurseVisit(NodeVisitor * visitor)683 void DoWhileNode::recurseVisit(NodeVisitor *visitor)
684 {
685     recurseVisitLink(visitor, expr);
686     recurseVisitLink(visitor, statement);
687 }
688 
689 // ------------------------------ WhileNode ------------------------------------
690 
recurseVisit(NodeVisitor * visitor)691 void WhileNode::recurseVisit(NodeVisitor *visitor)
692 {
693     recurseVisitLink(visitor, expr);
694     recurseVisitLink(visitor, statement);
695 }
696 
697 // ------------------------------ ForNode --------------------------------------
698 
recurseVisit(NodeVisitor * visitor)699 void ForNode::recurseVisit(NodeVisitor *visitor)
700 {
701     recurseVisitLink(visitor, expr1);
702     recurseVisitLink(visitor, expr2);
703     recurseVisitLink(visitor, expr3);
704     recurseVisitLink(visitor, statement);
705 }
706 
707 // ------------------------------ ForInNode ------------------------------------
708 
ForInNode(Node * l,Node * e,StatementNode * s)709 ForInNode::ForInNode(Node *l, Node *e, StatementNode *s)
710     : init(nullptr), lexpr(l), expr(e), varDecl(nullptr), statement(s)
711 {
712 }
713 
ForInNode(const Identifier & i,AssignExprNode * in,Node * e,StatementNode * s)714 ForInNode::ForInNode(const Identifier &i, AssignExprNode *in, Node *e, StatementNode *s)
715     : ident(i), init(in), expr(e), statement(s)
716 {
717     // for( var foo = bar in baz )
718     varDecl = new VarDeclNode(ident, init.get(), VarDeclNode::Variable);
719     lexpr   = new VarAccessNode(ident);
720 }
721 
recurseVisit(NodeVisitor * visitor)722 void ForInNode::recurseVisit(NodeVisitor *visitor)
723 {
724     recurseVisitLink(visitor, init);
725     recurseVisitLink(visitor, lexpr);
726     recurseVisitLink(visitor, expr);
727     recurseVisitLink(visitor, varDecl);
728     recurseVisitLink(visitor, statement);
729 }
730 
731 // ------------------------------ ReturnNode -----------------------------------
732 
recurseVisit(NodeVisitor * visitor)733 void ReturnNode::recurseVisit(NodeVisitor *visitor)
734 {
735     recurseVisitLink(visitor, value);
736 }
737 
738 // ------------------------------ WithNode -------------------------------------
739 
recurseVisit(NodeVisitor * visitor)740 void WithNode::recurseVisit(NodeVisitor *visitor)
741 {
742     recurseVisitLink(visitor, expr);
743     recurseVisitLink(visitor, statement);
744 }
745 
746 // ------------------------------ CaseClauseNode -------------------------------
747 
recurseVisit(NodeVisitor * visitor)748 void CaseClauseNode::recurseVisit(NodeVisitor *visitor)
749 {
750     recurseVisitLink(visitor, expr);
751     recurseVisitLink(visitor, source);
752 }
753 
754 // ------------------------------ ClauseListNode -------------------------------
755 
breakCycle()756 void ClauseListNode::breakCycle()
757 {
758     next = nullptr;
759 }
760 
recurseVisit(NodeVisitor * visitor)761 void ClauseListNode::recurseVisit(NodeVisitor *visitor)
762 {
763     recurseVisitLink(visitor, clause);
764     recurseVisitLink(visitor, next);
765 }
766 
767 // ------------------------------ CaseBlockNode --------------------------------
768 
CaseBlockNode(ClauseListNode * l1,CaseClauseNode * d,ClauseListNode * l2)769 CaseBlockNode::CaseBlockNode(ClauseListNode *l1, CaseClauseNode *d,
770                              ClauseListNode *l2)
771 {
772     if (l1) {
773         list1 = l1->next.release();
774         Parser::removeNodeCycle(list1.get());
775     } else {
776         list1 = nullptr;
777     }
778 
779     def = d;
780 
781     if (l2) {
782         list2 = l2->next.release();
783         Parser::removeNodeCycle(list2.get());
784     } else {
785         list2 = nullptr;
786     }
787 }
788 
recurseVisit(NodeVisitor * visitor)789 void CaseBlockNode::recurseVisit(NodeVisitor *visitor)
790 {
791     recurseVisitLink(visitor, list1);
792     recurseVisitLink(visitor, def);
793     recurseVisitLink(visitor, list2);
794 }
795 
796 // ------------------------------ SwitchNode -----------------------------------
797 
recurseVisit(NodeVisitor * visitor)798 void SwitchNode::recurseVisit(NodeVisitor *visitor)
799 {
800     recurseVisitLink(visitor, expr);
801     recurseVisitLink(visitor, block);
802 }
803 
804 // ------------------------------ LabelNode ------------------------------------
805 
recurseVisit(NodeVisitor * visitor)806 void LabelNode::recurseVisit(NodeVisitor *visitor)
807 {
808     recurseVisitLink(visitor, statement);
809 }
810 
811 // ------------------------------ ThrowNode ------------------------------------
812 
recurseVisit(NodeVisitor * visitor)813 void ThrowNode::recurseVisit(NodeVisitor *visitor)
814 {
815     recurseVisitLink(visitor, expr);
816 }
817 
818 // ------------------------------ TryNode --------------------------------------
819 
recurseVisit(NodeVisitor * visitor)820 void TryNode::recurseVisit(NodeVisitor *visitor)
821 {
822     recurseVisitLink(visitor, tryBlock);
823     recurseVisitLink(visitor, catchBlock);
824     recurseVisitLink(visitor, finallyBlock);
825 }
826 
827 // ------------------------------ ParameterNode --------------------------------
828 
breakCycle()829 void ParameterNode::breakCycle()
830 {
831     next = nullptr;
832 }
833 
recurseVisit(NodeVisitor * visitor)834 void ParameterNode::recurseVisit(NodeVisitor *visitor)
835 {
836     recurseVisitLink(visitor, next);
837 }
838 
839 // ------------------------------ FunctionBodyNode -----------------------------
840 
FunctionBodyNode(SourceElementsNode * s)841 FunctionBodyNode::FunctionBodyNode(SourceElementsNode *s)
842     : BlockNode(s)
843     , m_sourceURL(lexer().sourceURL())
844     , m_sourceId(parser().sourceId())
845     , m_compType(NotCompiled)
846     , m_flags(parser().popFunctionContext())
847 {
848     setLoc(-1, -1);
849 }
850 
addVarDecl(const Identifier & ident,int attr,ExecState * exec)851 void FunctionBodyNode::addVarDecl(const Identifier &ident, int attr, ExecState *exec)
852 {
853     // There is one nasty special case: ignore a 'var' declaration of 'arguments';
854     // it effectively doesn't do anything since the magic 'arguments' is already
855     // in scope anyway, and if we allocated a local, we would have to worry about
856     // keeping track of whether it was initialized or not on what is supposed to be the
857     // fast path. So we just make this go through the property map instead.
858     // Note that this does not matter for parameters or function declarations,
859     // since those overwrite the magic 'arguments' anyway.
860     if (ident == exec->propertyNames().arguments) {
861         return;
862     }
863 
864     (void)addSymbol(ident, attr);
865 }
866 
addFunDecl(const Identifier & ident,int attr,FuncDeclNode * funcDecl)867 void FunctionBodyNode::addFunDecl(const Identifier &ident, int attr, FuncDeclNode *funcDecl)
868 {
869     m_functionLocals.append(addSymbol(ident, attr, funcDecl));
870 }
871 
reserveSlot(size_t id,bool shouldMark)872 void FunctionBodyNode::reserveSlot(size_t id, bool shouldMark)
873 {
874     ASSERT(id == m_symbolList.size());
875     m_symbolList.append(SymbolInfo(shouldMark ? 0 : DontMark, nullptr));
876 }
877 
addSymbol(const Identifier & ident,int flags,FuncDeclNode * funcDecl)878 size_t FunctionBodyNode::addSymbol(const Identifier &ident, int flags, FuncDeclNode *funcDecl)
879 {
880     // We get symbols in the order specified in 10.1.3, but sometimes
881     // the later ones are supposed to lose. This -mostly- does not
882     // matter for us --- we primarily concern ourselves with name/ID
883     // mapping, but there is an issue of attributes and funcDecl's.
884     // However, the only flag that matters here is ReadOnly --
885     // everything else just has DontDelete set; and it's from const,
886     // so we can just ignore it on repetitions, since var/const should lose
887     // and are at the end.
888     //
889     // And for funcDecl, since functions win over everything, we always set it if non-zero
890     size_t oldId = m_symbolTable.get(ident.ustring().rep());
891     if (oldId != missingSymbolMarker()) {
892         if (funcDecl) {
893             m_symbolList[oldId].funcDecl = funcDecl;
894         }
895         return oldId;
896     }
897 
898     size_t id = m_symbolList.size();         //First entry gets 0, etc.
899     m_symbolTable.set(ident.ustring().rep(), id);
900     m_symbolList.append(SymbolInfo(flags, funcDecl));
901     return id;
902 }
903 
addSymbolOverwriteID(size_t id,const Identifier & ident,int flags)904 void FunctionBodyNode::addSymbolOverwriteID(size_t id, const Identifier &ident, int flags)
905 {
906     ASSERT(id == m_symbolList.size());
907 
908     // Remove previous one, if any
909     size_t oldId = m_symbolTable.get(ident.ustring().rep());
910     if (oldId != missingSymbolMarker()) {
911         m_symbolList[oldId].attr = DontMark;
912     }
913 
914     // Add a new one
915     m_symbolTable.set(ident.ustring().rep(), id);
916     m_symbolList.append(SymbolInfo(flags, nullptr));
917 }
918 
addParam(const Identifier & ident)919 void FunctionBodyNode::addParam(const Identifier &ident)
920 {
921     m_paramList.append(ident);
922 }
923 
execute(ExecState * exec)924 Completion FunctionBodyNode::execute(ExecState *exec)
925 {
926     CodeType    ctype   = exec->codeType();
927     CompileType cmpType = exec->dynamicInterpreter()->debugger() ? Debug : Release;
928     compileIfNeeded(ctype, cmpType);
929     ASSERT(ctype != FunctionCode);
930 
931     LocalStorage      *store = new LocalStorage();
932     LocalStorageEntry *regs;
933 
934     // Allocate enough space, and make sure to initialize things so we don't mark garbage
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;
940     }
941 
942     exec->initLocalStorage(regs, m_symbolList.size());
943 
944     JSValue *val = Machine::runBlock(exec, m_compiledCode);
945 
946     Completion result;
947     if (exec->hadException()) {
948         result = Completion(Throw, exec->exception());
949     } else {
950         result = Completion(Normal, val);
951     }
952 
953     exec->initLocalStorage(nullptr, 0);
954     delete store;
955     exec->clearException();
956 
957     return result;
958 }
959 
compile(CodeType ctype,CompileType compType)960 void FunctionBodyNode::compile(CodeType ctype, CompileType compType)
961 {
962     m_compType = compType;
963 
964     CompileState comp(ctype, compType, this, m_symbolList.size());
965     generateExecCode(&comp);
966     m_tearOffAtEnd = comp.needsClosures();
967 
968 #if 0
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");
975 #endif
976 }
977 
978 // ------------------------------ FuncDeclNode ---------------------------------
979 
980 // ECMA 13
processFuncDecl(ExecState * exec)981 void FuncDeclNode::processFuncDecl(ExecState *exec)
982 {
983     // See whether we just need to fill in the symbol table,
984     // or actually fiddle with objects.
985     int flags = Internal | DontDelete;
986     switch (exec->codeType()) {
987     case FunctionCode:
988         // Inside a function, just need symbol info
989         exec->currentBody()->addFunDecl(ident, flags, this);
990         return;
991     case EvalCode:
992         // eval-injected symbols can be deleted...
993         flags &= ~DontDelete;
994 
995         // eval injected a new local into scope! Better mark that down,
996         // so that NonLocalResolver stops skipping the local scope
997         exec->variableObject()->setLocalInjected();
998 
999     // fallthrough intentional
1000     case GlobalCode:
1001         exec->variableObject()->put(exec, ident, makeFunctionObject(exec), flags);
1002     };
1003 }
1004 
addParams()1005 void FuncDeclNode::addParams()
1006 {
1007     for (ParameterNode *p = param.get(); p != nullptr; p = p->nextParam()) {
1008         body->addParam(p->ident());
1009     }
1010 }
1011 
makeFunctionObject(ExecState * exec)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 
recurseVisit(NodeVisitor * visitor)1027 void FuncDeclNode::recurseVisit(NodeVisitor *visitor)
1028 {
1029     recurseVisitLink(visitor, param);
1030     recurseVisitLink(visitor, body);
1031 }
1032 
1033 // ------------------------------ FuncExprNode ---------------------------------
1034 
addParams()1035 void FuncExprNode::addParams()
1036 {
1037     for (ParameterNode *p = param.get(); p != nullptr; p = p->nextParam()) {
1038         body->addParam(p->ident());
1039     }
1040 }
1041 
recurseVisit(NodeVisitor * visitor)1042 void FuncExprNode::recurseVisit(NodeVisitor *visitor)
1043 {
1044     recurseVisitLink(visitor, param);
1045     recurseVisitLink(visitor, body);
1046 }
1047 
1048 // ------------------------------ SourceElementsNode ---------------------------
1049 
SourceElementsNode(StatementNode * s1)1050 SourceElementsNode::SourceElementsNode(StatementNode *s1)
1051     : node(s1), next(this)
1052 {
1053     Parser::noteNodeCycle(this);
1054     setLoc(s1->firstLine(), s1->lastLine());
1055 }
1056 
SourceElementsNode(SourceElementsNode * s1,StatementNode * s2)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 
breakCycle()1064 void SourceElementsNode::breakCycle()
1065 {
1066     next = nullptr;
1067 }
1068 
recurseVisit(NodeVisitor * visitor)1069 void SourceElementsNode::recurseVisit(NodeVisitor *visitor)
1070 {
1071     recurseVisitLink(visitor, node);
1072     recurseVisitLink(visitor, next);
1073 }
1074 
1075 // ------------------------------ ProgramNode ----------------------------------
1076 
ProgramNode(SourceElementsNode * s)1077 ProgramNode::ProgramNode(SourceElementsNode *s) : FunctionBodyNode(s)
1078 {
1079 }
1080 
1081 // ------------------------------ PackageNameNode ------------------------------
recurseVisit(NodeVisitor * visitor)1082 void PackageNameNode::recurseVisit(NodeVisitor *visitor)
1083 {
1084     recurseVisitLink(visitor, names);
1085 }
1086 
loadSymbol(ExecState * exec,bool wildcard)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 
resolvePackage(ExecState * exec)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 
resolvePackage(ExecState * exec,JSObject * baseObject,Package * basePackage)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 
processVarDecl(ExecState * exec)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 
recurseVisit(NodeVisitor * visitor)1195 void ImportStatement::recurseVisit(NodeVisitor *visitor)
1196 {
1197     recurseVisitLink(visitor, name);
1198 }
1199 
1200 } //namespace KJS
1201