fix logic
[personal-kdelibs.git] / kjs / nodes.cpp
blob7a3286ffa600ec37de39b06f0cfa476cec2fbb5a
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)
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.
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.
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.
25 #include "nodes.h"
26 #include <config.h>
27 #include "scriptfunction.h"
28 #include "CompileState.h"
30 #include <math.h>
31 #include <stdio.h>
32 #ifdef KJS_DEBUG_MEM
33 #include <typeinfo>
34 #endif
36 //#include <iostream>
38 #include "debugger.h"
39 #include "function_object.h"
40 #include "lexer.h"
41 #include "operations.h"
42 #include "package.h"
43 #include "PropertyNameArray.h"
44 #include <wtf/AlwaysInline.h>
45 #include <wtf/Assertions.h>
46 #include <wtf/HashSet.h>
47 #include <wtf/HashCountedSet.h>
48 #include <wtf/MathExtras.h>
50 #include "CompileState.h"
51 #include "bytecode/machine.h"
53 namespace KJS {
55 // ------------------------------ Node -----------------------------------------
58 #ifndef NDEBUG
59 struct NodeCounter {
60 static unsigned count;
61 ~NodeCounter()
63 if (count)
64 fprintf(stderr, "LEAK: %d KJS::Node\n", count);
67 unsigned NodeCounter::count = 0;
68 static NodeCounter nodeCounter;
69 #endif
71 static HashSet<Node*>* newNodes;
72 static HashCountedSet<Node*>* nodeExtraRefCounts;
74 Node::Node()
76 #ifndef NDEBUG
77 ++NodeCounter::count;
78 #endif
79 m_line = lexer().lineNo();
80 if (!newNodes)
81 newNodes = new HashSet<Node*>;
82 newNodes->add(this);
85 Node::~Node()
87 #ifndef NDEBUG
88 --NodeCounter::count;
89 #endif
92 void Node::ref()
94 // bumping from 0 to 1 is just removing from the new nodes set
95 if (newNodes) {
96 HashSet<Node*>::iterator it = newNodes->find(this);
97 if (it != newNodes->end()) {
98 newNodes->remove(it);
99 ASSERT(!nodeExtraRefCounts || !nodeExtraRefCounts->contains(this));
100 return;
104 ASSERT(!newNodes || !newNodes->contains(this));
106 if (!nodeExtraRefCounts)
107 nodeExtraRefCounts = new HashCountedSet<Node*>;
108 nodeExtraRefCounts->add(this);
111 void Node::deref()
113 ASSERT(!newNodes || !newNodes->contains(this));
115 if (!nodeExtraRefCounts) {
116 delete this;
117 return;
120 HashCountedSet<Node*>::iterator it = nodeExtraRefCounts->find(this);
121 if (it == nodeExtraRefCounts->end())
122 delete this;
123 else
124 nodeExtraRefCounts->remove(it);
127 unsigned Node::refcount()
129 if (newNodes && newNodes->contains(this)) {
130 ASSERT(!nodeExtraRefCounts || !nodeExtraRefCounts->contains(this));
131 return 0;
134 ASSERT(!newNodes || !newNodes->contains(this));
136 if (!nodeExtraRefCounts)
137 return 1;
139 return 1 + nodeExtraRefCounts->count(this);
142 void Node::clearNewNodes()
144 if (!newNodes)
145 return;
147 #ifndef NDEBUG
148 HashSet<Node*>::iterator end = newNodes->end();
149 for (HashSet<Node*>::iterator it = newNodes->begin(); it != end; ++it)
150 ASSERT(!nodeExtraRefCounts || !nodeExtraRefCounts->contains(*it));
151 #endif
152 deleteAllValues(*newNodes);
153 delete newNodes;
154 newNodes = 0;
157 static void substitute(UString &string, const UString &substring)
159 int position = string.find("%s");
160 assert(position != -1);
161 UString newString = string.substr(0, position);
162 newString.append(substring);
163 newString.append(string.substr(position + 2));
164 string = newString;
167 static inline int currentSourceId(ExecState* exec)
169 return exec->currentBody()->sourceId();
172 static inline const UString& currentSourceURL(ExecState* exec)
174 return exec->currentBody()->sourceURL();
177 JSValue* Node::throwError(ExecState* exec, ErrorType e, const UString& msg)
179 return KJS::throwError(exec, e, msg, lineNo(), currentSourceId(exec), currentSourceURL(exec));
182 JSValue* Node::throwError(ExecState* exec, ErrorType e, const UString& msg, const Identifier& label)
184 UString message = msg;
185 substitute(message, label.ustring());
186 return KJS::throwError(exec, e, message, lineNo(), currentSourceId(exec), currentSourceURL(exec));
189 JSValue* Node::throwUndefinedVariableError(ExecState* exec, const Identifier& ident)
191 return throwError(exec, ReferenceError, "Cannot find variable: %s", ident);
194 Node *Node::nodeInsideAllParens()
196 return this;
199 class VarDeclVisitor: public NodeVisitor {
200 private:
201 ExecState* m_exec;
202 public:
203 VarDeclVisitor(ExecState* exec) : m_exec(exec)
206 virtual Node* visit(Node* node) {
207 node->processVarDecl(m_exec);
209 //Do not recurse inside function bodies...
210 if (node->introducesNewStaticScope())
211 return 0;
213 return NodeVisitor::visit(node);
217 class FuncDeclVisitor: public NodeVisitor {
218 private:
219 ExecState* m_exec;
220 public:
221 FuncDeclVisitor(ExecState* exec) : m_exec(exec)
224 virtual Node* visit(Node* node) {
225 node->processFuncDecl(m_exec);
227 if (node->introducesNewStaticScope())
228 return 0;
230 return NodeVisitor::visit(node);
234 void Node::processDecls(ExecState *exec) {
235 VarDeclVisitor vVisit(exec);
236 vVisit.visit(this);
238 FuncDeclVisitor fVisit(exec);
239 fVisit.visit(this);
242 void Node::processVarDecl (ExecState*)
245 void Node::processFuncDecl(ExecState*)
248 // ------------------------------ NodeVisitor ----------------------------------
249 Node* NodeVisitor::visit(Node *node) {
250 node->recurseVisit(this);
251 return 0;
254 // ------------------------------ StatementNode --------------------------------
256 StatementNode::StatementNode()
257 : m_lastLine(-1)
259 m_line = -1;
262 void StatementNode::setLoc(int firstLine, int lastLine) const
264 m_line = firstLine;
265 m_lastLine = lastLine;
268 void StatementNode::hitStatement(ExecState* exec)
270 // The debugger is always non-zero here, since otherwise this won't be involved
271 exec->dynamicInterpreter()->debugger()->reportAtStatement(exec, currentSourceId(exec), firstLine(), lastLine());
274 // ------------------------------ GroupNode ------------------------------------
276 Node *GroupNode::nodeInsideAllParens()
278 Node *n = this;
280 n = static_cast<GroupNode *>(n)->group.get();
281 while (n->isGroupNode());
282 return n;
285 void GroupNode::recurseVisit(NodeVisitor *visitor)
287 recurseVisitLink(visitor, group);
291 // ------------------------------ ElementNode ----------------------------------
293 void ElementNode::breakCycle()
295 next = 0;
298 void ElementNode::recurseVisit(NodeVisitor *visitor)
300 recurseVisitLink(visitor, next);
301 recurseVisitLink(visitor, node);
305 // ------------------------------ ArrayNode ------------------------------------
307 void ArrayNode::recurseVisit(NodeVisitor *visitor)
309 recurseVisitLink(visitor, element);
312 // ------------------------------ ObjectLiteralNode ----------------------------
314 void ObjectLiteralNode::recurseVisit(NodeVisitor *visitor)
316 recurseVisitLink(visitor, list);
319 // ------------------------------ PropertyListNode -----------------------------
321 void PropertyListNode::breakCycle()
323 next = 0;
326 void PropertyListNode::recurseVisit(NodeVisitor *visitor)
328 recurseVisitLink(visitor, node);
329 recurseVisitLink(visitor, next);
332 // ------------------------------ PropertyNode -----------------------------
333 void PropertyNode::recurseVisit(NodeVisitor *visitor)
335 recurseVisitLink(visitor, name);
336 recurseVisitLink(visitor, assign);
339 // ------------------------------ BracketAccessorNode --------------------------------
341 void BracketAccessorNode::recurseVisit(NodeVisitor *visitor)
343 recurseVisitLink(visitor, expr1);
344 recurseVisitLink(visitor, expr2);
347 // ------------------------------ DotAccessorNode --------------------------------
349 void DotAccessorNode::recurseVisit(NodeVisitor *visitor)
351 recurseVisitLink(visitor, expr);
354 // ------------------------------ ArgumentListNode -----------------------------
356 void ArgumentListNode::breakCycle()
358 next = 0;
361 void ArgumentListNode::recurseVisit(NodeVisitor *visitor)
363 recurseVisitLink(visitor, next);
364 recurseVisitLink(visitor, expr);
367 // ------------------------------ ArgumentsNode --------------------------------
369 void ArgumentsNode::recurseVisit(NodeVisitor *visitor)
371 recurseVisitLink(visitor, list);
374 // ------------------------------ NewExprNode ----------------------------------
376 void NewExprNode::recurseVisit(NodeVisitor *visitor)
378 recurseVisitLink(visitor, expr);
379 recurseVisitLink(visitor, args);
382 // ------------------------------ FunctionCallValueNode ------------------------
384 void FunctionCallValueNode::recurseVisit(NodeVisitor *visitor)
386 recurseVisitLink(visitor, expr);
387 recurseVisitLink(visitor, args);
390 // ------------------------------ FunctionCallRerefenceNode --------------------
392 void FunctionCallReferenceNode::recurseVisit(NodeVisitor *visitor)
394 recurseVisitLink(visitor, expr);
395 recurseVisitLink(visitor, args);
398 // ------------------------------ PostfixNode ----------------------------------
400 void PostfixNode::recurseVisit(NodeVisitor *visitor)
402 Node::recurseVisitLink(visitor, m_loc);
405 // ------------------------------ DeleteReferenceNode -------------------------------
407 void DeleteReferenceNode::recurseVisit(NodeVisitor *visitor)
409 Node::recurseVisitLink(visitor, loc);
412 // ------------------------------ DeleteValueNode -----------------------------------
414 void DeleteValueNode::recurseVisit(NodeVisitor *visitor)
416 recurseVisitLink(visitor, m_expr);
419 // ------------------------------ VoidNode -------------------------------------
421 void VoidNode::recurseVisit(NodeVisitor *visitor)
423 recurseVisitLink(visitor, expr);
426 // ------------------------------ TypeOfVarNode -----------------------------------
428 void TypeOfVarNode::recurseVisit(NodeVisitor *visitor)
430 Node::recurseVisitLink(visitor, loc);
433 // ------------------------------ TypeOfValueNode -----------------------------------
435 void TypeOfValueNode::recurseVisit(NodeVisitor *visitor)
437 recurseVisitLink(visitor, m_expr);
440 // ------------------------------ PrefixNode ----------------------------------------
442 void PrefixNode::recurseVisit(NodeVisitor *visitor)
444 Node::recurseVisitLink(visitor, m_loc);
447 // ------------------------------ UnaryPlusNode --------------------------------
449 void UnaryPlusNode::recurseVisit(NodeVisitor *visitor)
451 recurseVisitLink(visitor, expr);
454 // ------------------------------ NegateNode -----------------------------------
456 void NegateNode::recurseVisit(NodeVisitor *visitor)
458 recurseVisitLink(visitor, expr);
461 // ------------------------------ BitwiseNotNode -------------------------------
463 void BitwiseNotNode::recurseVisit(NodeVisitor *visitor)
465 recurseVisitLink(visitor, expr);
468 // ------------------------------ LogicalNotNode -------------------------------
470 void LogicalNotNode::recurseVisit(NodeVisitor *visitor)
472 recurseVisitLink(visitor, expr);
475 // ------------------------ BinaryOperatorNode -------------------------------
477 void BinaryOperatorNode::recurseVisit(NodeVisitor *visitor)
479 recurseVisitLink(visitor, expr1);
480 recurseVisitLink(visitor, expr2);
483 // ------------------------------ BinaryLogicalNode ----------------------------
485 void BinaryLogicalNode::recurseVisit(NodeVisitor *visitor)
487 recurseVisitLink(visitor, expr1);
488 recurseVisitLink(visitor, expr2);
491 // ------------------------------ ConditionalNode ------------------------------
493 void ConditionalNode::recurseVisit(NodeVisitor *visitor)
495 recurseVisitLink(visitor, logical);
496 recurseVisitLink(visitor, expr1);
497 recurseVisitLink(visitor, expr2);
500 // ------------------------------ AssignNode -----------------------------------
502 void AssignNode::recurseVisit(NodeVisitor *visitor)
504 Node::recurseVisitLink(visitor, m_loc);
505 Node::recurseVisitLink(visitor, m_right);
508 // ------------------------------ CommaNode ------------------------------------
510 void CommaNode::recurseVisit(NodeVisitor *visitor)
512 recurseVisitLink(visitor, expr1);
513 recurseVisitLink(visitor, expr2);
516 // ------------------------------ AssignExprNode -------------------------------
518 void AssignExprNode::recurseVisit(NodeVisitor *visitor)
520 recurseVisitLink(visitor, expr);
523 // ------------------------------ VarDeclNode ----------------------------------
525 VarDeclNode::VarDeclNode(const Identifier &id, AssignExprNode *in, Type t)
526 : varType(t), ident(id), init(in)
530 #if 0
531 // ECMA 12.2
532 JSValue *VarDeclNode::evaluate(ExecState *exec)
534 JSObject* variable = exec->variableObject();
536 JSValue* val;
537 if (init) {
538 val = init->evaluate(exec);
539 KJS_CHECKEXCEPTIONVALUE
540 } else {
541 // already declared? - check with getDirect so you can override
542 // built-in properties of the global object with var declarations.
543 // Also check for 'arguments' property. The 'arguments' cannot be found with
544 // getDirect, because it's created lazily by
545 // ActivationImp::getOwnPropertySlot.
546 // Since variable declarations are always in function scope, 'variable'
547 // will always contain instance of ActivationImp and ActivationImp will
548 // always have 'arguments' property
549 if (variable->getDirect(ident) || ident == exec->propertyNames().arguments)
550 return 0;
551 val = jsUndefined();
554 #ifdef KJS_VERBOSE
555 printInfo(exec,(UString("new variable ")+ident.ustring()).cstring().c_str(),val);
556 #endif
557 // We use Internal to bypass all checks in derived objects, e.g. so that
558 // "var location" creates a dynamic property instead of activating window.location.
559 int flags = Internal;
560 if (exec->codeType() != EvalCode)
561 flags |= DontDelete;
562 if (varType == VarDeclNode::Constant)
563 flags |= ReadOnly;
564 variable->put(exec, ident, val, flags);
566 return 0; //No useful value, not a true expr
568 #endif
570 void VarDeclNode::processVarDecl(ExecState *exec)
572 JSObject* variable = exec->variableObject();
574 // First, determine which flags we want to use..
575 int flags = DontDelete;
576 if (varType == VarDeclNode::Constant)
577 flags |= ReadOnly;
579 // Are we inside a function? If so, we fill in the symbol table
580 switch (exec->codeType()) {
581 case FunctionCode:
582 // Inside a function, we're just computing static information.
583 // so, just fill in the symbol table.
584 exec->currentBody()->addVarDecl(ident, flags, exec);
585 return;
586 case EvalCode:
587 // eval-injected variables can be deleted..
588 flags &= ~DontDelete;
590 // If a variable by this name already exists, don't clobber it -
591 // eval may be trying to inject a variable that already exists..
592 if (!variable->hasProperty(exec, ident)) {
593 variable->put(exec, ident, jsUndefined(), flags);
594 // eval injected a new local into scope! Better mark that down,
595 // so that NonLocalResolver stops skipping the local scope
596 variable->setLocalInjected();
598 break;
599 case GlobalCode:
600 // If a variable by this name already exists, don't clobber it -
601 // ### I am not sue this is needed for GlobalCode
602 if (!variable->hasProperty(exec, ident))
603 variable->put(exec, ident, jsUndefined(), flags);
607 void VarDeclNode::recurseVisit(NodeVisitor *visitor)
609 recurseVisitLink(visitor, init);
612 // ------------------------------ VarDeclListNode ------------------------------
614 void VarDeclListNode::breakCycle()
616 next = 0;
619 void VarDeclListNode::recurseVisit(NodeVisitor *visitor)
621 recurseVisitLink(visitor, var);
622 recurseVisitLink(visitor, next);
625 // ------------------------------ VarStatementNode -----------------------------
627 void VarStatementNode::recurseVisit(NodeVisitor *visitor)
629 recurseVisitLink(visitor, next);
632 // ------------------------------ BlockNode ------------------------------------
634 BlockNode::BlockNode(SourceElementsNode *s)
636 if (s) {
637 source = s->next.release();
638 Parser::removeNodeCycle(source.get());
639 setLoc(s->firstLine(), s->lastLine());
640 } else {
641 source = 0;
645 void BlockNode::recurseVisit(NodeVisitor *visitor)
647 recurseVisitLink(visitor, source);
650 // ------------------------------ ExprStatementNode ----------------------------
652 void ExprStatementNode::recurseVisit(NodeVisitor *visitor)
654 recurseVisitLink(visitor, expr);
657 // ------------------------------ IfNode ---------------------------------------
659 void IfNode::recurseVisit(NodeVisitor *visitor)
661 recurseVisitLink(visitor, expr);
662 recurseVisitLink(visitor, statement1);
663 recurseVisitLink(visitor, statement2);
666 // ------------------------------ DoWhileNode ----------------------------------
668 void DoWhileNode::recurseVisit(NodeVisitor *visitor)
670 recurseVisitLink(visitor, expr);
671 recurseVisitLink(visitor, statement);
674 // ------------------------------ WhileNode ------------------------------------
676 void WhileNode::recurseVisit(NodeVisitor *visitor)
678 recurseVisitLink(visitor, expr);
679 recurseVisitLink(visitor, statement);
682 // ------------------------------ ForNode --------------------------------------
684 void ForNode::recurseVisit(NodeVisitor *visitor)
686 recurseVisitLink(visitor, expr1);
687 recurseVisitLink(visitor, expr2);
688 recurseVisitLink(visitor, expr3);
689 recurseVisitLink(visitor, statement);
692 // ------------------------------ ForInNode ------------------------------------
694 ForInNode::ForInNode(Node *l, Node *e, StatementNode *s)
695 : init(0L), lexpr(l), expr(e), varDecl(0L), statement(s)
699 ForInNode::ForInNode(const Identifier &i, AssignExprNode *in, Node *e, StatementNode *s)
700 : ident(i), init(in), expr(e), statement(s)
702 // for( var foo = bar in baz )
703 varDecl = new VarDeclNode(ident, init.get(), VarDeclNode::Variable);
704 lexpr = new VarAccessNode(ident);
707 void ForInNode::recurseVisit(NodeVisitor *visitor)
709 recurseVisitLink(visitor, init);
710 recurseVisitLink(visitor, lexpr);
711 recurseVisitLink(visitor, expr);
712 recurseVisitLink(visitor, varDecl);
713 recurseVisitLink(visitor, statement);
716 // ------------------------------ ReturnNode -----------------------------------
718 void ReturnNode::recurseVisit(NodeVisitor *visitor)
720 recurseVisitLink(visitor, value);
723 // ------------------------------ WithNode -------------------------------------
725 void WithNode::recurseVisit(NodeVisitor *visitor)
727 recurseVisitLink(visitor, expr);
728 recurseVisitLink(visitor, statement);
731 // ------------------------------ CaseClauseNode -------------------------------
733 void CaseClauseNode::recurseVisit(NodeVisitor *visitor)
735 recurseVisitLink(visitor, expr);
736 recurseVisitLink(visitor, source);
739 // ------------------------------ ClauseListNode -------------------------------
741 void ClauseListNode::breakCycle()
743 next = 0;
746 void ClauseListNode::recurseVisit(NodeVisitor *visitor)
748 recurseVisitLink(visitor, clause);
749 recurseVisitLink(visitor, next);
752 // ------------------------------ CaseBlockNode --------------------------------
754 CaseBlockNode::CaseBlockNode(ClauseListNode *l1, CaseClauseNode *d,
755 ClauseListNode *l2)
757 if (l1) {
758 list1 = l1->next.release();
759 Parser::removeNodeCycle(list1.get());
760 } else {
761 list1 = 0;
764 def = d;
766 if (l2) {
767 list2 = l2->next.release();
768 Parser::removeNodeCycle(list2.get());
769 } else {
770 list2 = 0;
774 void CaseBlockNode::recurseVisit(NodeVisitor *visitor)
776 recurseVisitLink(visitor, list1);
777 recurseVisitLink(visitor, def);
778 recurseVisitLink(visitor, list2);
781 // ------------------------------ SwitchNode -----------------------------------
783 void SwitchNode::recurseVisit(NodeVisitor *visitor)
785 recurseVisitLink(visitor, expr);
786 recurseVisitLink(visitor, block);
789 // ------------------------------ LabelNode ------------------------------------
791 void LabelNode::recurseVisit(NodeVisitor *visitor)
793 recurseVisitLink(visitor, statement);
796 // ------------------------------ ThrowNode ------------------------------------
798 void ThrowNode::recurseVisit(NodeVisitor *visitor)
800 recurseVisitLink(visitor, expr);
803 // ------------------------------ TryNode --------------------------------------
805 void TryNode::recurseVisit(NodeVisitor *visitor)
807 recurseVisitLink(visitor, tryBlock);
808 recurseVisitLink(visitor, catchBlock);
809 recurseVisitLink(visitor, finallyBlock);
812 // ------------------------------ ParameterNode --------------------------------
814 void ParameterNode::breakCycle()
816 next = 0;
819 void ParameterNode::recurseVisit(NodeVisitor *visitor)
821 recurseVisitLink(visitor, next);
824 // ------------------------------ FunctionBodyNode -----------------------------
826 FunctionBodyNode::FunctionBodyNode(SourceElementsNode *s)
827 : BlockNode(s)
828 , m_sourceURL(lexer().sourceURL())
829 , m_sourceId(parser().sourceId())
830 , m_compType(NotCompiled)
831 , m_flags(parser().popFunctionContext())
833 setLoc(-1, -1);
837 void FunctionBodyNode::addVarDecl(const Identifier& ident, int attr, ExecState* exec)
839 // There is one nasty special case: ignore a 'var' declaration of 'arguments';
840 // it effectively doesn't do anything since the magic 'arguments' is already
841 // in scope anyway, and if we allocated a local, we would have to worry about
842 // keeping track of whether it was initialized or not on what is supposed to be the
843 // fast path. So we just make this go through the property map instead.
844 // Note that this does not matter for parameters or function declarations,
845 // since those overwrite the magic 'arguments' anyway.
846 if (ident == exec->propertyNames().arguments)
847 return;
849 (void)addSymbol(ident, attr);
852 void FunctionBodyNode::addFunDecl(const Identifier& ident, int attr, FuncDeclNode* funcDecl)
854 m_functionLocals.append(addSymbol(ident, attr, funcDecl));
857 void FunctionBodyNode::reserveSlot(size_t id, bool shouldMark)
859 ASSERT(id == m_symbolList.size());
860 m_symbolList.append(SymbolInfo(shouldMark ? 0 : DontMark, 0));
863 size_t FunctionBodyNode::addSymbol(const Identifier& ident, int flags, FuncDeclNode* funcDecl)
865 // We get symbols in the order specified in 10.1.3, but sometimes
866 // the later ones are supposed to lose. This -mostly- does not
867 // matter for us --- we primarily concern ourselves with name/ID
868 // mapping, but there is an issue of attributes and funcDecl's.
869 // However, the only flag that matters here is ReadOnly --
870 // everything else just has DontDelete set; and it's from const,
871 // so we can just ignore it on repetitions, since var/const should lose
872 // and are at the end.
874 // And for funcDecl, since functions win over everything, we always set it if non-zero
875 size_t oldId = m_symbolTable.get(ident.ustring().rep());
876 if (oldId != missingSymbolMarker()) {
877 if (funcDecl)
878 m_symbolList[oldId].funcDecl = funcDecl;
879 return oldId;
882 size_t id = m_symbolList.size(); //First entry gets 0, etc.
883 m_symbolTable.set(ident.ustring().rep(), id);
884 m_symbolList.append(SymbolInfo(flags, funcDecl));
885 return id;
888 void FunctionBodyNode::addSymbolOverwriteID(size_t id, const Identifier& ident, int flags)
890 ASSERT(id == m_symbolList.size());
892 // Remove previous one, if any
893 size_t oldId = m_symbolTable.get(ident.ustring().rep());
894 if (oldId != missingSymbolMarker())
895 m_symbolList[oldId].attr = DontMark;
897 // Add a new one
898 m_symbolTable.set(ident.ustring().rep(), id);
899 m_symbolList.append(SymbolInfo(flags, 0));
902 void FunctionBodyNode::addParam(const Identifier& ident)
904 m_paramList.append(ident);
907 Completion FunctionBodyNode::execute(ExecState *exec)
909 CodeType ctype = exec->codeType();
910 CompileType cmpType = exec->dynamicInterpreter()->debugger() ? Debug : Release;
911 compileIfNeeded(ctype, cmpType);
912 ASSERT(ctype != FunctionCode);
914 LocalStorage* store = new LocalStorage();
915 LocalStorageEntry* regs;
917 // Allocate enough space, and make sure to initialize things so we don't mark garbage
918 store->resize(m_symbolList.size());
919 regs = store->data();
920 for (size_t c = 0; c < m_symbolList.size(); ++c) {
921 regs[c].val.valueVal = jsUndefined();
922 regs[c].attributes = m_symbolList[c].attr;
925 exec->initLocalStorage(regs, m_symbolList.size());
927 JSValue* val = Machine::runBlock(exec, m_compiledCode);
929 Completion result;
930 if (exec->hadException())
931 result = Completion(Throw, exec->exception());
932 else
933 result = Completion(Normal, val);
935 exec->initLocalStorage(0, 0);
936 delete store;
937 exec->clearException();
939 return result;
942 void FunctionBodyNode::compile(CodeType ctype, CompileType compType)
944 m_compType = compType;
946 CompileState comp(ctype, compType, this, m_symbolList.size());
947 generateExecCode(&comp);
948 m_tearOffAtEnd = comp.needsClosures();
950 #if 0
951 printf("\n\n");
952 printf("\n---------------------------------\n\n");
953 printf("%s", toString().ascii());
954 printf("\n---------------------------------\n\n");
955 CodeGen::disassembleBlock(m_compiledCode);
956 printf("\n---------------------------------\n\n");
957 #endif
961 // ------------------------------ FuncDeclNode ---------------------------------
963 // ECMA 13
964 void FuncDeclNode::processFuncDecl(ExecState *exec)
966 // See whether we just need to fill in the symbol table,
967 // or actually fiddle with objects.
968 int flags = Internal | DontDelete;
969 switch (exec->codeType()) {
970 case FunctionCode:
971 // Inside a function, just need symbol info
972 exec->currentBody()->addFunDecl(ident, flags, this);
973 return;
974 case EvalCode:
975 // eval-injected symbols can be deleted...
976 flags &= ~DontDelete;
978 // eval injected a new local into scope! Better mark that down,
979 // so that NonLocalResolver stops skipping the local scope
980 exec->variableObject()->setLocalInjected();
982 // fallthrough intentional
983 case GlobalCode:
984 exec->variableObject()->put(exec, ident, makeFunctionObject(exec), flags);
988 void FuncDeclNode::addParams()
990 for (ParameterNode *p = param.get(); p != 0L; p = p->nextParam())
991 body->addParam(p->ident());
994 FunctionImp* FuncDeclNode::makeFunctionObject(ExecState *exec)
996 // TODO: let this be an object with [[Class]] property "Function"
997 FunctionImp *func = new FunctionImp(exec, ident, body.get(), exec->scopeChain());
999 JSObject *proto = exec->lexicalInterpreter()->builtinObject()->construct(exec, List::empty());
1000 proto->put(exec, exec->propertyNames().constructor, func, DontEnum);
1001 func->put(exec, exec->propertyNames().prototype, proto, Internal|DontDelete);
1003 func->put(exec, exec->propertyNames().length, jsNumber(body->numParams()), ReadOnly|DontDelete|DontEnum);
1005 return func;
1008 void FuncDeclNode::recurseVisit(NodeVisitor *visitor)
1010 recurseVisitLink(visitor, param);
1011 recurseVisitLink(visitor, body);
1014 // ------------------------------ FuncExprNode ---------------------------------
1016 void FuncExprNode::addParams()
1018 for(ParameterNode *p = param.get(); p != 0L; p = p->nextParam())
1019 body->addParam(p->ident());
1022 void FuncExprNode::recurseVisit(NodeVisitor *visitor)
1024 recurseVisitLink(visitor, param);
1025 recurseVisitLink(visitor, body);
1028 // ------------------------------ SourceElementsNode ---------------------------
1030 SourceElementsNode::SourceElementsNode(StatementNode *s1)
1031 : node(s1), next(this)
1033 Parser::noteNodeCycle(this);
1034 setLoc(s1->firstLine(), s1->lastLine());
1037 SourceElementsNode::SourceElementsNode(SourceElementsNode *s1, StatementNode *s2)
1038 : node(s2), next(s1->next)
1040 s1->next = this;
1041 setLoc(s1->firstLine(), s2->lastLine());
1044 void SourceElementsNode::breakCycle()
1046 next = 0;
1049 void SourceElementsNode::recurseVisit(NodeVisitor *visitor)
1051 recurseVisitLink(visitor, node);
1052 recurseVisitLink(visitor, next);
1055 // ------------------------------ ProgramNode ----------------------------------
1057 ProgramNode::ProgramNode(SourceElementsNode *s) : FunctionBodyNode(s)
1061 // ------------------------------ PackageNameNode ------------------------------
1062 void PackageNameNode::recurseVisit(NodeVisitor *visitor)
1064 recurseVisitLink(visitor, names);
1067 Completion PackageNameNode::loadSymbol(ExecState* exec, bool wildcard)
1069 Package* basePackage;
1070 JSObject* baseObject;
1071 if (names) {
1072 PackageObject *pobj = names->resolvePackage(exec);
1073 if (pobj == 0)
1074 return Completion(Normal);
1075 basePackage = pobj->package();
1076 baseObject = pobj;
1077 } else {
1078 Interpreter* ip = exec->lexicalInterpreter();
1079 basePackage = ip->globalPackage();
1080 baseObject = ip->globalObject();
1083 if (wildcard) {
1084 // if a .* is specified the last identifier should
1085 // denote another package name
1086 PackageObject* pobj = resolvePackage(exec, baseObject, basePackage);
1087 if (!pobj)
1088 return Completion(Normal);
1089 basePackage = pobj->package();
1090 baseObject = pobj;
1091 basePackage->loadAllSymbols(exec, baseObject);
1092 } else {
1093 basePackage->loadSymbol(exec, baseObject, id);
1096 return Completion(Normal);
1099 PackageObject* PackageNameNode::resolvePackage(ExecState* exec)
1101 JSObject* baseObject;
1102 Package* basePackage;
1103 if (names) {
1104 PackageObject* basePackageObject = names->resolvePackage(exec);
1105 if (basePackageObject == 0)
1106 return 0;
1107 baseObject = basePackageObject;
1108 basePackage = basePackageObject->package();
1109 } else {
1110 // first identifier is looked up in global object
1111 Interpreter* ip = exec->lexicalInterpreter();
1112 baseObject = ip->globalObject();
1113 basePackage = ip->globalPackage();
1116 return resolvePackage(exec, baseObject, basePackage);
1119 PackageObject* PackageNameNode::resolvePackage(ExecState* exec,
1120 JSObject* baseObject,
1121 Package* basePackage)
1123 PackageObject* res = 0;
1125 // Let's see whether the package was already resolved previously.
1126 JSValue* v = baseObject->get(exec, id);
1127 if (v && !v->isUndefined()) {
1128 if (!v->isObject()) {
1129 // Symbol conflict
1130 throwError(exec, GeneralError, "Invalid type of package %s", id);
1131 return 0;
1133 res = static_cast<PackageObject*>(v);
1134 } else {
1135 UString err;
1136 Package *newBase = basePackage->loadSubPackage(id, &err);
1137 if (newBase == 0) {
1138 if (err.isEmpty()) {
1139 throwError(exec, GeneralError, "Package not found");
1140 } else {
1141 throwError(exec, GeneralError, err);
1143 return 0;
1145 res = new PackageObject(newBase);
1146 baseObject->put(exec, id, res);
1149 return res;
1152 void ImportStatement::processVarDecl(ExecState* exec)
1154 // error out if package support is not activated
1155 Package* glob = exec->lexicalInterpreter()->globalPackage();
1156 if (!glob) {
1157 throwError(exec, GeneralError,
1158 "Package support disabled. Import failed.");
1159 return;
1162 // also error out if not used on top-level
1163 if (exec->codeType() != GlobalCode) {
1164 throwError(exec, GeneralError,
1165 "Package imports may only occur at top level.");
1166 return;
1169 name->loadSymbol(exec, wld);
1172 void ImportStatement::recurseVisit(NodeVisitor *visitor)
1174 recurseVisitLink(visitor, name);
1177 } //namespace KJS