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.
27 #include "scriptfunction.h"
28 #include "CompileState.h"
39 #include "function_object.h"
41 #include "operations.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"
55 // ------------------------------ Node -----------------------------------------
60 static unsigned count
;
64 fprintf(stderr
, "LEAK: %d KJS::Node\n", count
);
67 unsigned NodeCounter::count
= 0;
68 static NodeCounter nodeCounter
;
71 static HashSet
<Node
*>* newNodes
;
72 static HashCountedSet
<Node
*>* nodeExtraRefCounts
;
79 m_line
= lexer().lineNo();
81 newNodes
= new HashSet
<Node
*>;
94 // bumping from 0 to 1 is just removing from the new nodes set
96 HashSet
<Node
*>::iterator it
= newNodes
->find(this);
97 if (it
!= newNodes
->end()) {
99 ASSERT(!nodeExtraRefCounts
|| !nodeExtraRefCounts
->contains(this));
104 ASSERT(!newNodes
|| !newNodes
->contains(this));
106 if (!nodeExtraRefCounts
)
107 nodeExtraRefCounts
= new HashCountedSet
<Node
*>;
108 nodeExtraRefCounts
->add(this);
113 ASSERT(!newNodes
|| !newNodes
->contains(this));
115 if (!nodeExtraRefCounts
) {
120 HashCountedSet
<Node
*>::iterator it
= nodeExtraRefCounts
->find(this);
121 if (it
== nodeExtraRefCounts
->end())
124 nodeExtraRefCounts
->remove(it
);
127 unsigned Node::refcount()
129 if (newNodes
&& newNodes
->contains(this)) {
130 ASSERT(!nodeExtraRefCounts
|| !nodeExtraRefCounts
->contains(this));
134 ASSERT(!newNodes
|| !newNodes
->contains(this));
136 if (!nodeExtraRefCounts
)
139 return 1 + nodeExtraRefCounts
->count(this);
142 void Node::clearNewNodes()
148 HashSet
<Node
*>::iterator end
= newNodes
->end();
149 for (HashSet
<Node
*>::iterator it
= newNodes
->begin(); it
!= end
; ++it
)
150 ASSERT(!nodeExtraRefCounts
|| !nodeExtraRefCounts
->contains(*it
));
152 deleteAllValues(*newNodes
);
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));
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()
199 class VarDeclVisitor
: public NodeVisitor
{
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())
213 return NodeVisitor::visit(node
);
217 class FuncDeclVisitor
: public NodeVisitor
{
221 FuncDeclVisitor(ExecState
* exec
) : m_exec(exec
)
224 virtual Node
* visit(Node
* node
) {
225 node
->processFuncDecl(m_exec
);
227 if (node
->introducesNewStaticScope())
230 return NodeVisitor::visit(node
);
234 void Node::processDecls(ExecState
*exec
) {
235 VarDeclVisitor
vVisit(exec
);
238 FuncDeclVisitor
fVisit(exec
);
242 void Node::processVarDecl (ExecState
*)
245 void Node::processFuncDecl(ExecState
*)
248 // ------------------------------ NodeVisitor ----------------------------------
249 Node
* NodeVisitor::visit(Node
*node
) {
250 node
->recurseVisit(this);
254 // ------------------------------ StatementNode --------------------------------
256 StatementNode::StatementNode()
262 void StatementNode::setLoc(int firstLine
, int lastLine
) const
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()
280 n
= static_cast<GroupNode
*>(n
)->group
.get();
281 while (n
->isGroupNode());
285 void GroupNode::recurseVisit(NodeVisitor
*visitor
)
287 recurseVisitLink(visitor
, group
);
291 // ------------------------------ ElementNode ----------------------------------
293 void ElementNode::breakCycle()
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()
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()
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
)
532 JSValue
*VarDeclNode::evaluate(ExecState
*exec
)
534 JSObject
* variable
= exec
->variableObject();
538 val
= init
->evaluate(exec
);
539 KJS_CHECKEXCEPTIONVALUE
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
)
555 printInfo(exec
,(UString("new variable ")+ident
.ustring()).cstring().c_str(),val
);
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
)
562 if (varType
== VarDeclNode::Constant
)
564 variable
->put(exec
, ident
, val
, flags
);
566 return 0; //No useful value, not a true expr
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
)
579 // Are we inside a function? If so, we fill in the symbol table
580 switch (exec
->codeType()) {
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
);
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();
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()
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
)
637 source
= s
->next
.release();
638 Parser::removeNodeCycle(source
.get());
639 setLoc(s
->firstLine(), s
->lastLine());
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()
746 void ClauseListNode::recurseVisit(NodeVisitor
*visitor
)
748 recurseVisitLink(visitor
, clause
);
749 recurseVisitLink(visitor
, next
);
752 // ------------------------------ CaseBlockNode --------------------------------
754 CaseBlockNode::CaseBlockNode(ClauseListNode
*l1
, CaseClauseNode
*d
,
758 list1
= l1
->next
.release();
759 Parser::removeNodeCycle(list1
.get());
767 list2
= l2
->next
.release();
768 Parser::removeNodeCycle(list2
.get());
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()
819 void ParameterNode::recurseVisit(NodeVisitor
*visitor
)
821 recurseVisitLink(visitor
, next
);
824 // ------------------------------ FunctionBodyNode -----------------------------
826 FunctionBodyNode::FunctionBodyNode(SourceElementsNode
*s
)
828 , m_sourceURL(lexer().sourceURL())
829 , m_sourceId(parser().sourceId())
830 , m_compType(NotCompiled
)
831 , m_flags(parser().popFunctionContext())
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
)
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()) {
878 m_symbolList
[oldId
].funcDecl
= funcDecl
;
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
));
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
;
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
);
930 if (exec
->hadException())
931 result
= Completion(Throw
, exec
->exception());
933 result
= Completion(Normal
, val
);
935 exec
->initLocalStorage(0, 0);
937 exec
->clearException();
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();
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");
961 // ------------------------------ FuncDeclNode ---------------------------------
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()) {
971 // Inside a function, just need symbol info
972 exec
->currentBody()->addFunDecl(ident
, flags
, this);
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
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
);
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
)
1041 setLoc(s1
->firstLine(), s2
->lastLine());
1044 void SourceElementsNode::breakCycle()
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
;
1072 PackageObject
*pobj
= names
->resolvePackage(exec
);
1074 return Completion(Normal
);
1075 basePackage
= pobj
->package();
1078 Interpreter
* ip
= exec
->lexicalInterpreter();
1079 basePackage
= ip
->globalPackage();
1080 baseObject
= ip
->globalObject();
1084 // if a .* is specified the last identifier should
1085 // denote another package name
1086 PackageObject
* pobj
= resolvePackage(exec
, baseObject
, basePackage
);
1088 return Completion(Normal
);
1089 basePackage
= pobj
->package();
1091 basePackage
->loadAllSymbols(exec
, baseObject
);
1093 basePackage
->loadSymbol(exec
, baseObject
, id
);
1096 return Completion(Normal
);
1099 PackageObject
* PackageNameNode::resolvePackage(ExecState
* exec
)
1101 JSObject
* baseObject
;
1102 Package
* basePackage
;
1104 PackageObject
* basePackageObject
= names
->resolvePackage(exec
);
1105 if (basePackageObject
== 0)
1107 baseObject
= basePackageObject
;
1108 basePackage
= basePackageObject
->package();
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()) {
1130 throwError(exec
, GeneralError
, "Invalid type of package %s", id
);
1133 res
= static_cast<PackageObject
*>(v
);
1136 Package
*newBase
= basePackage
->loadSubPackage(id
, &err
);
1138 if (err
.isEmpty()) {
1139 throwError(exec
, GeneralError
, "Package not found");
1141 throwError(exec
, GeneralError
, err
);
1145 res
= new PackageObject(newBase
);
1146 baseObject
->put(exec
, id
, res
);
1152 void ImportStatement::processVarDecl(ExecState
* exec
)
1154 // error out if package support is not activated
1155 Package
* glob
= exec
->lexicalInterpreter()->globalPackage();
1157 throwError(exec
, GeneralError
,
1158 "Package support disabled. Import failed.");
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.");
1169 name
->loadSymbol(exec
, wld
);
1172 void ImportStatement::recurseVisit(NodeVisitor
*visitor
)
1174 recurseVisitLink(visitor
, name
);