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 <config-kjs.h>
27#include "scriptfunction.h"
28#include "CompileState.h"
29
30#include <math.h>
31#include <stdio.h>
32#ifdef KJS_DEBUG_MEM
33#include <typeinfo>
34#endif
35
36//#include <iostream>
37
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>
49
50#include "bytecode/machine.h"
51
52namespace KJS {
53
54// ------------------------------ Node -----------------------------------------
55
56
57#ifndef NDEBUG
58struct NodeCounter {
59 static unsigned count;
60 ~NodeCounter()
61 {
62 if (count)
63 fprintf(stderr, "LEAK: %d KJS::Node\n", count);
64 }
65};
66unsigned NodeCounter::count = 0;
67static NodeCounter nodeCounter;
68#endif
69
70static HashSet<Node*>* newNodes;
71static HashCountedSet<Node*>* nodeExtraRefCounts;
72
73Node::Node()
74{
75#ifndef NDEBUG
76 ++NodeCounter::count;
77#endif
78 m_line = lexer().lineNo();
79 if (!newNodes)
80 newNodes = new HashSet<Node*>;
81 newNodes->add(this);
82}
83
84Node::~Node()
85{
86#ifndef NDEBUG
87 --NodeCounter::count;
88#endif
89}
90
91void Node::ref()
92{
93 // bumping from 0 to 1 is just removing from the new nodes set
94 if (newNodes) {
95 HashSet<Node*>::iterator it = newNodes->find(this);
96 if (it != newNodes->end()) {
97 newNodes->remove(it);
98 ASSERT(!nodeExtraRefCounts || !nodeExtraRefCounts->contains(this));
99 return;
100 }
101 }
102
103 ASSERT(!newNodes || !newNodes->contains(this));
104
105 if (!nodeExtraRefCounts)
106 nodeExtraRefCounts = new HashCountedSet<Node*>;
107 nodeExtraRefCounts->add(this);
108}
109
110void 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
126unsigned Node::refcount()
127{
128 if (newNodes && newNodes->contains(this)) {
129 ASSERT(!nodeExtraRefCounts || !nodeExtraRefCounts->contains(this));
130 return 0;
131 }
132
133 ASSERT(!newNodes || !newNodes->contains(this));
134
135 if (!nodeExtraRefCounts)
136 return 1;
137
138 return 1 + nodeExtraRefCounts->count(this);
139}
140
141void Node::clearNewNodes()
142{
143 if (!newNodes)
144 return;
145
146#ifndef NDEBUG
147 HashSet<Node*>::iterator end = newNodes->end();
148 for (HashSet<Node*>::iterator it = newNodes->begin(); it != end; ++it)
149 ASSERT(!nodeExtraRefCounts || !nodeExtraRefCounts->contains(*it));
150#endif
151 deleteAllValues(*newNodes);
152 delete newNodes;
153 newNodes = 0;
154}
155
156static void substitute(UString &string, const UString &substring)
157{
158 int position = string.find("%s");
159 assert(position != -1);
160 UString newString = string.substr(0, position);
161 newString.append(substring);
162 newString.append(string.substr(position + 2));
163 string = newString;
164}
165
166static inline int currentSourceId(ExecState* exec)
167{
168 return exec->currentBody()->sourceId();
169}
170
171static inline const UString& currentSourceURL(ExecState* exec)
172{
173 return exec->currentBody()->sourceURL();
174}
175
176JSValue* Node::throwError(ExecState* exec, ErrorType e, const UString& msg)
177{
178 return KJS::throwError(exec, e, msg, lineNo(), currentSourceId(exec), currentSourceURL(exec));
179}
180
181JSValue* Node::throwError(ExecState* exec, ErrorType e, const UString& msg, const Identifier& label)
182{
183 UString message = msg;
184 substitute(message, label.ustring());
185 return KJS::throwError(exec, e, message, lineNo(), currentSourceId(exec), currentSourceURL(exec));
186}
187
188JSValue* Node::throwUndefinedVariableError(ExecState* exec, const Identifier& ident)
189{
190 return throwError(exec, ReferenceError, "Cannot find variable: %s", ident);
191}
192
193Node *Node::nodeInsideAllParens()
194{
195 return this;
196}
197
198class VarDeclVisitor: public NodeVisitor {
199 private:
200 ExecState* m_exec;
201 public:
202 VarDeclVisitor(ExecState* exec) : m_exec(exec)
203 {}
204
205 virtual Node* visit(Node* node) {
206 node->processVarDecl(m_exec);
207
208 //Do not recurse inside function bodies, or things that
209 // syntactically can't contain declarations
210 if (!node->scanForDeclarations())
211 return 0;
212
213 return NodeVisitor::visit(node);
214 }
215};
216
217class FuncDeclVisitor: public NodeVisitor {
218 private:
219 ExecState* m_exec;
220 public:
221 FuncDeclVisitor(ExecState* exec) : m_exec(exec)
222 {}
223
224 virtual Node* visit(Node* node) {
225 node->processFuncDecl(m_exec);
226
227 if (!node->scanForDeclarations())
228 return 0;
229
230 return NodeVisitor::visit(node);
231 }
232};
233
234void Node::processDecls(ExecState *exec) {
235 VarDeclVisitor vVisit(exec);
236 vVisit.visit(this);
237
238 FuncDeclVisitor fVisit(exec);
239 fVisit.visit(this);
240}
241
242void Node::processVarDecl (ExecState*)
243{}
244
245void Node::processFuncDecl(ExecState*)
246{}
247
248// ------------------------------ NodeVisitor ----------------------------------
249Node* NodeVisitor::visit(Node *node) {
250 node->recurseVisit(this);
251 return 0;
252}
253
254// ------------------------------ StatementNode --------------------------------
255
256StatementNode::StatementNode()
257 : m_lastLine(-1)
258{
259 m_line = -1;
260}
261
262void StatementNode::setLoc(int firstLine, int lastLine) const
263{
264 m_line = firstLine;
265 m_lastLine = lastLine;
266}
267
268void StatementNode::hitStatement(ExecState* exec)
269{
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());
272}
273
274// ------------------------------ GroupNode ------------------------------------
275
276Node *GroupNode::nodeInsideAllParens()
277{
278 Node *n = this;
279 do
280 n = static_cast<GroupNode *>(n)->group.get();
281 while (n->isGroupNode());
282 return n;
283}
284
285void GroupNode::recurseVisit(NodeVisitor *visitor)
286{
287 recurseVisitLink(visitor, group);
288}
289
290
291// ------------------------------ ElementNode ----------------------------------
292
293void ElementNode::breakCycle()
294{
295 next = 0;
296}
297
298void ElementNode::recurseVisit(NodeVisitor *visitor)
299{
300 recurseVisitLink(visitor, next);
301 recurseVisitLink(visitor, node);
302}
303
304
305// ------------------------------ ArrayNode ------------------------------------
306
307void ArrayNode::recurseVisit(NodeVisitor *visitor)
308{
309 recurseVisitLink(visitor, element);
310}
311
312// ------------------------------ ObjectLiteralNode ----------------------------
313
314void ObjectLiteralNode::recurseVisit(NodeVisitor *visitor)
315{
316 recurseVisitLink(visitor, list);
317}
318
319// ------------------------------ PropertyListNode -----------------------------
320
321void PropertyListNode::breakCycle()
322{
323 next = 0;
324}
325
326void PropertyListNode::recurseVisit(NodeVisitor *visitor)
327{
328 recurseVisitLink(visitor, node);
329 recurseVisitLink(visitor, next);
330}
331
332// ------------------------------ PropertyNode -----------------------------
333void PropertyNode::recurseVisit(NodeVisitor *visitor)
334{
335 recurseVisitLink(visitor, name);
336 recurseVisitLink(visitor, assign);
337}
338
339// ------------------------------ BracketAccessorNode --------------------------------
340
341void BracketAccessorNode::recurseVisit(NodeVisitor *visitor)
342{
343 recurseVisitLink(visitor, expr1);
344 recurseVisitLink(visitor, expr2);
345}
346
347// ------------------------------ DotAccessorNode --------------------------------
348
349void DotAccessorNode::recurseVisit(NodeVisitor *visitor)
350{
351 recurseVisitLink(visitor, expr);
352}
353
354// ------------------------------ ArgumentListNode -----------------------------
355
356void ArgumentListNode::breakCycle()
357{
358 next = 0;
359}
360
361void ArgumentListNode::recurseVisit(NodeVisitor *visitor)
362{
363 recurseVisitLink(visitor, next);
364 recurseVisitLink(visitor, expr);
365}
366
367// ------------------------------ ArgumentsNode --------------------------------
368
369void ArgumentsNode::recurseVisit(NodeVisitor *visitor)
370{
371 recurseVisitLink(visitor, list);
372}
373
374// ------------------------------ NewExprNode ----------------------------------
375
376void NewExprNode::recurseVisit(NodeVisitor *visitor)
377{
378 recurseVisitLink(visitor, expr);
379 recurseVisitLink(visitor, args);
380}
381
382// ------------------------------ FunctionCallValueNode ------------------------
383
384void FunctionCallValueNode::recurseVisit(NodeVisitor *visitor)
385{
386 recurseVisitLink(visitor, expr);
387 recurseVisitLink(visitor, args);
388}
389
390// ------------------------------ FunctionCallRerefenceNode --------------------
391
392void FunctionCallReferenceNode::recurseVisit(NodeVisitor *visitor)
393{
394 recurseVisitLink(visitor, expr);
395 recurseVisitLink(visitor, args);
396}
397
398// ------------------------------ PostfixNode ----------------------------------
399
400void PostfixNode::recurseVisit(NodeVisitor *visitor)
401{
402 Node::recurseVisitLink(visitor, m_loc);
403}
404
405// ------------------------------ DeleteReferenceNode -------------------------------
406
407void DeleteReferenceNode::recurseVisit(NodeVisitor *visitor)
408{
409 Node::recurseVisitLink(visitor, loc);
410}
411
412// ------------------------------ DeleteValueNode -----------------------------------
413
414void DeleteValueNode::recurseVisit(NodeVisitor *visitor)
415{
416 recurseVisitLink(visitor, m_expr);
417}
418
419// ------------------------------ VoidNode -------------------------------------
420
421void VoidNode::recurseVisit(NodeVisitor *visitor)
422{
423 recurseVisitLink(visitor, expr);
424}
425
426// ------------------------------ TypeOfVarNode -----------------------------------
427
428void TypeOfVarNode::recurseVisit(NodeVisitor *visitor)
429{
430 Node::recurseVisitLink(visitor, loc);
431}
432
433// ------------------------------ TypeOfValueNode -----------------------------------
434
435void TypeOfValueNode::recurseVisit(NodeVisitor *visitor)
436{
437 recurseVisitLink(visitor, m_expr);
438}
439
440// ------------------------------ PrefixNode ----------------------------------------
441
442void PrefixNode::recurseVisit(NodeVisitor *visitor)
443{
444 Node::recurseVisitLink(visitor, m_loc);
445}
446
447// ------------------------------ UnaryPlusNode --------------------------------
448
449void UnaryPlusNode::recurseVisit(NodeVisitor *visitor)
450{
451 recurseVisitLink(visitor, expr);
452}
453
454// ------------------------------ NegateNode -----------------------------------
455
456void NegateNode::recurseVisit(NodeVisitor *visitor)
457{
458 recurseVisitLink(visitor, expr);
459}
460
461// ------------------------------ BitwiseNotNode -------------------------------
462
463void BitwiseNotNode::recurseVisit(NodeVisitor *visitor)
464{
465 recurseVisitLink(visitor, expr);
466}
467
468// ------------------------------ LogicalNotNode -------------------------------
469
470void LogicalNotNode::recurseVisit(NodeVisitor *visitor)
471{
472 recurseVisitLink(visitor, expr);
473}
474
475// ------------------------ BinaryOperatorNode -------------------------------
476
477void BinaryOperatorNode::recurseVisit(NodeVisitor *visitor)
478{
479 recurseVisitLink(visitor, expr1);
480 recurseVisitLink(visitor, expr2);
481}
482
483// ------------------------------ BinaryLogicalNode ----------------------------
484
485void BinaryLogicalNode::recurseVisit(NodeVisitor *visitor)
486{
487 recurseVisitLink(visitor, expr1);
488 recurseVisitLink(visitor, expr2);
489}
490
491// ------------------------------ ConditionalNode ------------------------------
492
493void ConditionalNode::recurseVisit(NodeVisitor *visitor)
494{
495 recurseVisitLink(visitor, logical);
496 recurseVisitLink(visitor, expr1);
497 recurseVisitLink(visitor, expr2);
498}
499
500// ------------------------------ AssignNode -----------------------------------
501
502void AssignNode::recurseVisit(NodeVisitor *visitor)
503{
504 Node::recurseVisitLink(visitor, m_loc);
505 Node::recurseVisitLink(visitor, m_right);
506}
507
508// ------------------------------ CommaNode ------------------------------------
509
510void CommaNode::recurseVisit(NodeVisitor *visitor)
511{
512 recurseVisitLink(visitor, expr1);
513 recurseVisitLink(visitor, expr2);
514}
515
516// ------------------------------ AssignExprNode -------------------------------
517
518void AssignExprNode::recurseVisit(NodeVisitor *visitor)
519{
520 recurseVisitLink(visitor, expr);
521}
522
523// ------------------------------ VarDeclNode ----------------------------------
524
525VarDeclNode::VarDeclNode(const Identifier &id, AssignExprNode *in, Type t)
526 : varType(t), ident(id), init(in)
527{
528}
529
530#if 0
531// ECMA 12.2
532JSValue *VarDeclNode::evaluate(ExecState *exec)
533{
534 JSObject* variable = exec->variableObject();
535
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();
552 }
553
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);
565
566 return 0; //No useful value, not a true expr
567}
568#endif
569
570void VarDeclNode::processVarDecl(ExecState *exec)
571{
572 JSObject* variable = exec->variableObject();
573
574 // First, determine which flags we want to use..
575 int flags = DontDelete;
576 if (varType == VarDeclNode::Constant)
577 flags |= ReadOnly;
578
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;
589
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();
597 }
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);
604 };
605}
606
607void VarDeclNode::recurseVisit(NodeVisitor *visitor)
608{
609 recurseVisitLink(visitor, init);
610}
611
612// ------------------------------ VarDeclListNode ------------------------------
613
614void VarDeclListNode::breakCycle()
615{
616 next = 0;
617}
618
619void VarDeclListNode::recurseVisit(NodeVisitor *visitor)
620{
621 recurseVisitLink(visitor, var);
622 recurseVisitLink(visitor, next);
623}
624
625// ------------------------------ VarStatementNode -----------------------------
626
627void VarStatementNode::recurseVisit(NodeVisitor *visitor)
628{
629 recurseVisitLink(visitor, next);
630}
631
632// ------------------------------ BlockNode ------------------------------------
633
634BlockNode::BlockNode(SourceElementsNode *s)
635{
636 if (s) {
637 source = s->next.release();
638 Parser::removeNodeCycle(source.get());
639 setLoc(s->firstLine(), s->lastLine());
640 } else {
641 source = 0;
642 }
643}
644
645void BlockNode::recurseVisit(NodeVisitor *visitor)
646{
647 recurseVisitLink(visitor, source);
648}
649
650// ------------------------------ ExprStatementNode ----------------------------
651
652void ExprStatementNode::recurseVisit(NodeVisitor *visitor)
653{
654 recurseVisitLink(visitor, expr);
655}
656
657// ------------------------------ IfNode ---------------------------------------
658
659void IfNode::recurseVisit(NodeVisitor *visitor)
660{
661 recurseVisitLink(visitor, expr);
662 recurseVisitLink(visitor, statement1);
663 recurseVisitLink(visitor, statement2);
664}
665
666// ------------------------------ DoWhileNode ----------------------------------
667
668void DoWhileNode::recurseVisit(NodeVisitor *visitor)
669{
670 recurseVisitLink(visitor, expr);
671 recurseVisitLink(visitor, statement);
672}
673
674// ------------------------------ WhileNode ------------------------------------
675
676void WhileNode::recurseVisit(NodeVisitor *visitor)
677{
678 recurseVisitLink(visitor, expr);
679 recurseVisitLink(visitor, statement);
680}
681
682// ------------------------------ ForNode --------------------------------------
683
684void ForNode::recurseVisit(NodeVisitor *visitor)
685{
686 recurseVisitLink(visitor, expr1);
687 recurseVisitLink(visitor, expr2);
688 recurseVisitLink(visitor, expr3);
689 recurseVisitLink(visitor, statement);
690}
691
692// ------------------------------ ForInNode ------------------------------------
693
694ForInNode::ForInNode(Node *l, Node *e, StatementNode *s)
695 : init(0L), lexpr(l), expr(e), varDecl(0L), statement(s)
696{
697}
698
699ForInNode::ForInNode(const Identifier &i, AssignExprNode *in, Node *e, StatementNode *s)
700 : ident(i), init(in), expr(e), statement(s)
701{
702 // for( var foo = bar in baz )
703 varDecl = new VarDeclNode(ident, init.get(), VarDeclNode::Variable);
704 lexpr = new VarAccessNode(ident);
705}
706
707void ForInNode::recurseVisit(NodeVisitor *visitor)
708{
709 recurseVisitLink(visitor, init);
710 recurseVisitLink(visitor, lexpr);
711 recurseVisitLink(visitor, expr);
712 recurseVisitLink(visitor, varDecl);
713 recurseVisitLink(visitor, statement);
714}
715
716// ------------------------------ ReturnNode -----------------------------------
717
718void ReturnNode::recurseVisit(NodeVisitor *visitor)
719{
720 recurseVisitLink(visitor, value);
721}
722
723// ------------------------------ WithNode -------------------------------------
724
725void WithNode::recurseVisit(NodeVisitor *visitor)
726{
727 recurseVisitLink(visitor, expr);
728 recurseVisitLink(visitor, statement);
729}
730
731// ------------------------------ CaseClauseNode -------------------------------
732
733void CaseClauseNode::recurseVisit(NodeVisitor *visitor)
734{
735 recurseVisitLink(visitor, expr);
736 recurseVisitLink(visitor, source);
737}
738
739// ------------------------------ ClauseListNode -------------------------------
740
741void ClauseListNode::breakCycle()
742{
743 next = 0;
744}
745
746void ClauseListNode::recurseVisit(NodeVisitor *visitor)
747{
748 recurseVisitLink(visitor, clause);
749 recurseVisitLink(visitor, next);
750}
751
752// ------------------------------ CaseBlockNode --------------------------------
753
754CaseBlockNode::CaseBlockNode(ClauseListNode *l1, CaseClauseNode *d,
755 ClauseListNode *l2)
756{
757 if (l1) {
758 list1 = l1->next.release();
759 Parser::removeNodeCycle(list1.get());
760 } else {
761 list1 = 0;
762 }
763
764 def = d;
765
766 if (l2) {
767 list2 = l2->next.release();
768 Parser::removeNodeCycle(list2.get());
769 } else {
770 list2 = 0;
771 }
772}
773
774void CaseBlockNode::recurseVisit(NodeVisitor *visitor)
775{
776 recurseVisitLink(visitor, list1);
777 recurseVisitLink(visitor, def);
778 recurseVisitLink(visitor, list2);
779}
780
781// ------------------------------ SwitchNode -----------------------------------
782
783void SwitchNode::recurseVisit(NodeVisitor *visitor)
784{
785 recurseVisitLink(visitor, expr);
786 recurseVisitLink(visitor, block);
787}
788
789// ------------------------------ LabelNode ------------------------------------
790
791void LabelNode::recurseVisit(NodeVisitor *visitor)
792{
793 recurseVisitLink(visitor, statement);
794}
795
796// ------------------------------ ThrowNode ------------------------------------
797
798void ThrowNode::recurseVisit(NodeVisitor *visitor)
799{
800 recurseVisitLink(visitor, expr);
801}
802
803// ------------------------------ TryNode --------------------------------------
804
805void TryNode::recurseVisit(NodeVisitor *visitor)
806{
807 recurseVisitLink(visitor, tryBlock);
808 recurseVisitLink(visitor, catchBlock);
809 recurseVisitLink(visitor, finallyBlock);
810}
811
812// ------------------------------ ParameterNode --------------------------------
813
814void ParameterNode::breakCycle()
815{
816 next = 0;
817}
818
819void ParameterNode::recurseVisit(NodeVisitor *visitor)
820{
821 recurseVisitLink(visitor, next);
822}
823
824// ------------------------------ FunctionBodyNode -----------------------------
825
826FunctionBodyNode::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())
832{
833 setLoc(-1, -1);
834}
835
836
837void FunctionBodyNode::addVarDecl(const Identifier& ident, int attr, ExecState* exec)
838{
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;
848
849 (void)addSymbol(ident, attr);
850}
851
852void FunctionBodyNode::addFunDecl(const Identifier& ident, int attr, FuncDeclNode* funcDecl)
853{
854 m_functionLocals.append(addSymbol(ident, attr, funcDecl));
855}
856
857void FunctionBodyNode::reserveSlot(size_t id, bool shouldMark)
858{
859 ASSERT(id == m_symbolList.size());
860 m_symbolList.append(SymbolInfo(shouldMark ? 0 : DontMark, 0));
861}
862
863size_t FunctionBodyNode::addSymbol(const Identifier& ident, int flags, FuncDeclNode* funcDecl)
864{
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.
873 //
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;
880 }
881
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;
886}
887
888void FunctionBodyNode::addSymbolOverwriteID(size_t id, const Identifier& ident, int flags)
889{
890 ASSERT(id == m_symbolList.size());
891
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;
896
897 // Add a new one
898 m_symbolTable.set(ident.ustring().rep(), id);
899 m_symbolList.append(SymbolInfo(flags, 0));
900}
901
902void FunctionBodyNode::addParam(const Identifier& ident)
903{
904 m_paramList.append(ident);
905}
906
907Completion FunctionBodyNode::execute(ExecState *exec)
908{
909 CodeType ctype = exec->codeType();
910 CompileType cmpType = exec->dynamicInterpreter()->debugger() ? Debug : Release;
911 compileIfNeeded(ctype, cmpType);
912 ASSERT(ctype != FunctionCode);
913
914 LocalStorage* store = new LocalStorage();
915 LocalStorageEntry* regs;
916
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;
923 }
924
925 exec->initLocalStorage(regs, m_symbolList.size());
926
927 JSValue* val = Machine::runBlock(exec, m_compiledCode);
928
929 Completion result;
930 if (exec->hadException())
931 result = Completion(Throw, exec->exception());
932 else
933 result = Completion(Normal, val);
934
935 exec->initLocalStorage(0, 0);
936 delete store;
937 exec->clearException();
938
939 return result;
940}
941
942void FunctionBodyNode::compile(CodeType ctype, CompileType compType)
943{
944 m_compType = compType;
945
946 CompileState comp(ctype, compType, this, m_symbolList.size());
947 generateExecCode(&comp);
948 m_tearOffAtEnd = comp.needsClosures();
949
950#if 0
951 fprintf(stderr, "\n\n");
952 fprintf(stderr, "\n---------------------------------\n\n");
953 fprintf(stderr, "%s", toString().ascii());
954 fprintf(stderr, "\n---------------------------------\n\n");
955 CodeGen::disassembleBlock(m_compiledCode);
956 fprintf(stderr, "\n---------------------------------\n\n");
957#endif
958}
959
960
961// ------------------------------ FuncDeclNode ---------------------------------
962
963// ECMA 13
964void FuncDeclNode::processFuncDecl(ExecState *exec)
965{
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;
977
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();
981
982 // fallthrough intentional
983 case GlobalCode:
984 exec->variableObject()->put(exec, ident, makeFunctionObject(exec), flags);
985 };
986}
987
988void FuncDeclNode::addParams()
989{
990 for (ParameterNode *p = param.get(); p != 0L; p = p->nextParam())
991 body->addParam(p->ident());
992}
993
994FunctionImp* FuncDeclNode::makeFunctionObject(ExecState *exec)
995{
996 // TODO: let this be an object with [[Class]] property "Function"
997 FunctionImp *func = new FunctionImp(exec, ident, body.get(), exec->scopeChain());
998
999 JSObject *proto = exec->lexicalInterpreter()->builtinObject()->construct(exec, List::empty());
1000 proto->put(exec, exec->propertyNames().constructor, func, DontEnum);
1001 // ECMA Edition 5.1r6 - 15.3.5.2 - [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false
1002 func->put(exec, exec->propertyNames().prototype, proto, Internal|DontDelete|DontEnum);
1003
1004 func->put(exec, exec->propertyNames().length, jsNumber(body->numParams()), ReadOnly|DontDelete|DontEnum);
1005
1006 return func;
1007}
1008
1009void FuncDeclNode::recurseVisit(NodeVisitor *visitor)
1010{
1011 recurseVisitLink(visitor, param);
1012 recurseVisitLink(visitor, body);
1013}
1014
1015// ------------------------------ FuncExprNode ---------------------------------
1016
1017void FuncExprNode::addParams()
1018{
1019 for(ParameterNode *p = param.get(); p != 0L; p = p->nextParam())
1020 body->addParam(p->ident());
1021}
1022
1023void FuncExprNode::recurseVisit(NodeVisitor *visitor)
1024{
1025 recurseVisitLink(visitor, param);
1026 recurseVisitLink(visitor, body);
1027}
1028
1029// ------------------------------ SourceElementsNode ---------------------------
1030
1031SourceElementsNode::SourceElementsNode(StatementNode *s1)
1032 : node(s1), next(this)
1033{
1034 Parser::noteNodeCycle(this);
1035 setLoc(s1->firstLine(), s1->lastLine());
1036}
1037
1038SourceElementsNode::SourceElementsNode(SourceElementsNode *s1, StatementNode *s2)
1039 : node(s2), next(s1->next)
1040{
1041 s1->next = this;
1042 setLoc(s1->firstLine(), s2->lastLine());
1043}
1044
1045void SourceElementsNode::breakCycle()
1046{
1047 next = 0;
1048}
1049
1050void SourceElementsNode::recurseVisit(NodeVisitor *visitor)
1051{
1052 recurseVisitLink(visitor, node);
1053 recurseVisitLink(visitor, next);
1054}
1055
1056// ------------------------------ ProgramNode ----------------------------------
1057
1058ProgramNode::ProgramNode(SourceElementsNode *s) : FunctionBodyNode(s)
1059{
1060}
1061
1062// ------------------------------ PackageNameNode ------------------------------
1063void PackageNameNode::recurseVisit(NodeVisitor *visitor)
1064{
1065 recurseVisitLink(visitor, names);
1066}
1067
1068Completion PackageNameNode::loadSymbol(ExecState* exec, bool wildcard)
1069{
1070 Package* basePackage;
1071 JSObject* baseObject;
1072 if (names) {
1073 PackageObject *pobj = names->resolvePackage(exec);
1074 if (pobj == 0)
1075 return Completion(Normal);
1076 basePackage = pobj->package();
1077 baseObject = pobj;
1078 } else {
1079 Interpreter* ip = exec->lexicalInterpreter();
1080 basePackage = ip->globalPackage();
1081 baseObject = ip->globalObject();
1082 }
1083
1084 if (wildcard) {
1085 // if a .* is specified the last identifier should
1086 // denote another package name
1087 PackageObject* pobj = resolvePackage(exec, baseObject, basePackage);
1088 if (!pobj)
1089 return Completion(Normal);
1090 basePackage = pobj->package();
1091 baseObject = pobj;
1092 basePackage->loadAllSymbols(exec, baseObject);
1093 } else {
1094 basePackage->loadSymbol(exec, baseObject, id);
1095 }
1096
1097 return Completion(Normal);
1098}
1099
1100PackageObject* PackageNameNode::resolvePackage(ExecState* exec)
1101{
1102 JSObject* baseObject;
1103 Package* basePackage;
1104 if (names) {
1105 PackageObject* basePackageObject = names->resolvePackage(exec);
1106 if (basePackageObject == 0)
1107 return 0;
1108 baseObject = basePackageObject;
1109 basePackage = basePackageObject->package();
1110 } else {
1111 // first identifier is looked up in global object
1112 Interpreter* ip = exec->lexicalInterpreter();
1113 baseObject = ip->globalObject();
1114 basePackage = ip->globalPackage();
1115 }
1116
1117 return resolvePackage(exec, baseObject, basePackage);
1118}
1119
1120PackageObject* PackageNameNode::resolvePackage(ExecState* exec,
1121 JSObject* baseObject,
1122 Package* basePackage)
1123{
1124 PackageObject* res = 0;
1125
1126 // Let's see whether the package was already resolved previously.
1127 JSValue* v = baseObject->get(exec, id);
1128 if (v && !v->isUndefined()) {
1129 if (!v->isObject()) {
1130 // Symbol conflict
1131 throwError(exec, GeneralError, "Invalid type of package %s", id);
1132 return 0;
1133 }
1134 res = static_cast<PackageObject*>(v);
1135 } else {
1136 UString err;
1137 Package *newBase = basePackage->loadSubPackage(id, &err);
1138 if (newBase == 0) {
1139 if (err.isEmpty()) {
1140 throwError(exec, GeneralError, "Package not found");
1141 } else {
1142 throwError(exec, GeneralError, err);
1143 }
1144 return 0;
1145 }
1146 res = new PackageObject(newBase);
1147 baseObject->put(exec, id, res);
1148 }
1149
1150 return res;
1151}
1152
1153void ImportStatement::processVarDecl(ExecState* exec)
1154{
1155 // error out if package support is not activated
1156 Package* glob = exec->lexicalInterpreter()->globalPackage();
1157 if (!glob) {
1158 throwError(exec, GeneralError,
1159 "Package support disabled. Import failed.");
1160 return;
1161 }
1162
1163 // also error out if not used on top-level
1164 if (exec->codeType() != GlobalCode) {
1165 throwError(exec, GeneralError,
1166 "Package imports may only occur at top level.");
1167 return;
1168 }
1169
1170 name->loadSymbol(exec, wld);
1171}
1172
1173void ImportStatement::recurseVisit(NodeVisitor *visitor)
1174{
1175 recurseVisitLink(visitor, name);
1176}
1177
1178} //namespace KJS
1179