23883c3fdbf6bbf2de85742b6164a5812d5511f3
[WebKit-https.git] / JavaScriptCore / kjs / function.h
1 // -*- c-basic-offset: 2 -*-
2 /*
3  *  This file is part of the KDE libraries
4  *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
5  *  Copyright (C) 2003, 2006 Apple Computer, Inc.
6  *
7  *  This library is free software; you can redistribute it and/or
8  *  modify it under the terms of the GNU Library General Public
9  *  License as published by the Free Software Foundation; either
10  *  version 2 of the License, or (at your option) any later version.
11  *
12  *  This library is distributed in the hope that it will be useful,
13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  *  Library General Public License for more details.
16  *
17  *  You should have received a copy of the GNU Library General Public License
18  *  along with this library; see the file COPYING.LIB.  If not, write to
19  *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20  *  Boston, MA 02110-1301, USA.
21  *
22  */
23
24 #ifndef KJS_FUNCTION_H
25 #define KJS_FUNCTION_H
26
27 #include "SymbolTable.h"
28 #include "object.h"
29 #include <wtf/OwnPtr.h>
30 #include <wtf/Vector.h>
31
32 namespace KJS {
33
34   class ActivationImp;
35   class FunctionBodyNode;
36   class FunctionPrototype;
37
38   class InternalFunctionImp : public JSObject {
39   public:
40     InternalFunctionImp();
41     InternalFunctionImp(FunctionPrototype*);
42     InternalFunctionImp(FunctionPrototype*, const Identifier&);
43
44     virtual bool implementsCall() const;
45     virtual JSValue* callAsFunction(ExecState*, JSObject* thisObjec, const List& args) = 0;
46     virtual bool implementsHasInstance() const;
47
48     virtual const ClassInfo* classInfo() const { return &info; }
49     static const ClassInfo info;
50     const Identifier& functionName() const { return m_name; }
51
52   private:
53     Identifier m_name;
54   };
55
56   /**
57    * @internal
58    *
59    * The initial value of Function.prototype (and thus all objects created
60    * with the Function constructor)
61    */
62   class FunctionPrototype : public InternalFunctionImp {
63   public:
64     FunctionPrototype(ExecState *exec);
65     virtual ~FunctionPrototype();
66
67     virtual JSValue *callAsFunction(ExecState *exec, JSObject *thisObj, const List &args);
68   };
69
70   class FunctionImp : public InternalFunctionImp {
71     friend class ActivationImp;
72   public:
73     FunctionImp(ExecState*, const Identifier& name, FunctionBodyNode*, const ScopeChain&);
74
75     virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
76     virtual void put(ExecState*, const Identifier& propertyName, JSValue* value, int attr = None);
77     virtual bool deleteProperty(ExecState*, const Identifier& propertyName);
78
79     virtual bool implementsConstruct() const { return true; }
80     virtual JSObject* construct(ExecState*, const List& args);
81     
82     virtual JSValue* callAsFunction(ExecState*, JSObject* thisObj, const List& args);
83     Completion execute(ExecState*);
84
85     // Note: unlike body->paramName, this returns Identifier::null for parameters 
86     // that will never get set, due to later param having the same name
87     Identifier getParameterName(int index);
88
89     virtual const ClassInfo* classInfo() const { return &info; }
90     static const ClassInfo info;
91
92     RefPtr<FunctionBodyNode> body;
93
94     void setScope(const ScopeChain& s) { _scope = s; }
95     const ScopeChain& scope() const { return _scope; }
96
97     virtual void mark();
98
99   private:
100     ScopeChain _scope;
101
102     static JSValue* argumentsGetter(ExecState*, JSObject*, const Identifier&, const PropertySlot&);
103     static JSValue* callerGetter(ExecState*, JSObject*, const Identifier&, const PropertySlot&);
104     static JSValue* lengthGetter(ExecState*, JSObject*, const Identifier&, const PropertySlot&);
105   };
106
107   class IndexToNameMap {
108   public:
109     IndexToNameMap(FunctionImp* func, const List& args);
110     ~IndexToNameMap();
111     
112     Identifier& operator[](int index);
113     Identifier& operator[](const Identifier &indexIdentifier);
114     bool isMapped(const Identifier& index) const;
115     void unMap(const Identifier& index);
116     
117   private:
118     IndexToNameMap(); // prevent construction w/o parameters
119     int size;
120     Identifier* _map;
121   };
122   
123   class Arguments : public JSObject {
124   public:
125     Arguments(ExecState*, FunctionImp* func, const List& args, ActivationImp* act);
126     virtual void mark();
127     virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
128     virtual void put(ExecState*, const Identifier& propertyName, JSValue* value, int attr = None);
129     virtual bool deleteProperty(ExecState*, const Identifier& propertyName);
130     virtual const ClassInfo* classInfo() const { return &info; }
131     static const ClassInfo info;
132   private:
133     static JSValue* mappedIndexGetter(ExecState*, JSObject*, const Identifier&, const PropertySlot& slot);
134
135     ActivationImp* _activationObject;
136     mutable IndexToNameMap indexToNameMap;
137   };
138
139   class ActivationImp : public JSObject {
140   public:
141     struct LocalStorageEntry {
142         LocalStorageEntry()
143         {
144         }
145
146         LocalStorageEntry(JSValue* v, int a)
147             : value(v)
148             , attributes(a)
149         {
150         }
151
152         JSValue* value;
153         int attributes;
154     };
155
156     typedef Vector<LocalStorageEntry, 32> LocalStorage;
157
158   private:
159     struct ActivationImpPrivate {
160         ActivationImpPrivate(FunctionImp* f, const List& a)
161             : function(f)
162             , arguments(a)
163             , argumentsObject(0)
164         {
165             ASSERT(f);
166         }
167         
168         FunctionImp* function;
169         LocalStorage localStorage;
170
171         List arguments;
172         Arguments* argumentsObject;
173     };
174
175   public:
176     ActivationImp::ActivationImp(FunctionImp* function, const List& arguments);
177
178     virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
179     virtual void put(ExecState*, const Identifier& propertyName, JSValue* value, int attr = None);
180     virtual bool deleteProperty(ExecState*, const Identifier& propertyName);
181
182     virtual const ClassInfo* classInfo() const { return &info; }
183     static const ClassInfo info;
184
185     virtual void mark();
186
187     bool isActivation() { return true; }
188
189     void releaseArguments() { d->arguments.reset(); }
190     
191     LocalStorage& localStorage() { return d->localStorage; };
192
193   private:
194     static PropertySlot::GetValueFunc getArgumentsGetter();
195     static JSValue* argumentsGetter(ExecState*, JSObject*, const Identifier&, const PropertySlot& slot);
196     void createArgumentsObject(ExecState*);
197     
198     OwnPtr<ActivationImpPrivate> d;
199     SymbolTable* symbolTable;
200   };
201
202   class GlobalFuncImp : public InternalFunctionImp {
203   public:
204     GlobalFuncImp(ExecState*, FunctionPrototype*, int i, int len, const Identifier&);
205     virtual JSValue* callAsFunction(ExecState*, JSObject* thisObj, const List& args);
206     enum { Eval, ParseInt, ParseFloat, IsNaN, IsFinite, Escape, UnEscape,
207            DecodeURI, DecodeURIComponent, EncodeURI, EncodeURIComponent
208 #ifndef NDEBUG
209            , KJSPrint
210 #endif
211 };
212   private:
213     int id;
214   };
215
216   static const double mantissaOverflowLowerBound = 9007199254740992.0;
217   double parseIntOverflow(const char* s, int length, int radix);
218
219 UString escapeStringForPrettyPrinting(const UString& s);
220
221 } // namespace
222
223 #endif