Foo::s_info should be Foo::info(), so that you can change how the s_info is actually...
[WebKit-https.git] / Source / JavaScriptCore / runtime / JSFunction.h
1 /*
2  *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
3  *  Copyright (C) 2003, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
4  *  Copyright (C) 2007 Cameron Zwarich (cwzwarich@uwaterloo.ca)
5  *  Copyright (C) 2007 Maks Orlovich
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 JSFunction_h
25 #define JSFunction_h
26
27 #include "InternalFunction.h"
28 #include "JSDestructibleObject.h"
29 #include "JSScope.h"
30 #include "ObjectAllocationProfile.h"
31 #include "Watchpoint.h"
32
33 namespace JSC {
34
35     class ExecutableBase;
36     class FunctionExecutable;
37     class FunctionPrototype;
38     class JSActivation;
39     class JSGlobalObject;
40     class LLIntOffsetsExtractor;
41     class NativeExecutable;
42     class SourceCode;
43     namespace DFG {
44     class SpeculativeJIT;
45     class JITCompiler;
46     }
47
48     JS_EXPORT_PRIVATE EncodedJSValue JSC_HOST_CALL callHostFunctionAsConstructor(ExecState*);
49
50     JS_EXPORT_PRIVATE String getCalculatedDisplayName(CallFrame*, JSObject*);
51     
52     class JSFunction : public JSDestructibleObject {
53         friend class JIT;
54         friend class DFG::SpeculativeJIT;
55         friend class DFG::JITCompiler;
56         friend class VM;
57
58     public:
59         typedef JSDestructibleObject Base;
60
61         JS_EXPORT_PRIVATE static JSFunction* create(ExecState*, JSGlobalObject*, int length, const String& name, NativeFunction, Intrinsic = NoIntrinsic, NativeFunction nativeConstructor = callHostFunctionAsConstructor);
62
63         static JSFunction* create(ExecState* exec, FunctionExecutable* executable, JSScope* scope)
64         {
65             VM& vm = exec->vm();
66             JSFunction* function = new (NotNull, allocateCell<JSFunction>(vm.heap)) JSFunction(vm, executable, scope);
67             ASSERT(function->structure()->globalObject());
68             function->finishCreation(vm);
69             return function;
70         }
71         
72         static void destroy(JSCell*);
73         
74         JS_EXPORT_PRIVATE String name(ExecState*);
75         JS_EXPORT_PRIVATE String displayName(ExecState*);
76         const String calculatedDisplayName(ExecState*);
77
78         JSScope* scope()
79         {
80             ASSERT(!isHostFunctionNonInline());
81             return m_scope.get();
82         }
83         // This method may be called for host functins, in which case it
84         // will return an arbitrary value. This should only be used for
85         // optimized paths in which the return value does not matter for
86         // host functions, and checking whether the function is a host
87         // function is deemed too expensive.
88         JSScope* scopeUnchecked()
89         {
90             return m_scope.get();
91         }
92         void setScope(VM& vm, JSScope* scope)
93         {
94             ASSERT(!isHostFunctionNonInline());
95             m_scope.set(vm, this, scope);
96         }
97
98         ExecutableBase* executable() const { return m_executable.get(); }
99
100         // To call either of these methods include Executable.h
101         inline bool isHostFunction() const;
102         FunctionExecutable* jsExecutable() const;
103
104         JS_EXPORT_PRIVATE const SourceCode* sourceCode() const;
105
106         DECLARE_EXPORT_INFO;
107
108         static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype) 
109         {
110             ASSERT(globalObject);
111             return Structure::create(vm, globalObject, prototype, TypeInfo(JSFunctionType, StructureFlags), info()); 
112         }
113
114         NativeFunction nativeFunction();
115         NativeFunction nativeConstructor();
116
117         static ConstructType getConstructData(JSCell*, ConstructData&);
118         static CallType getCallData(JSCell*, CallData&);
119
120         static inline ptrdiff_t offsetOfScopeChain()
121         {
122             return OBJECT_OFFSETOF(JSFunction, m_scope);
123         }
124
125         static inline ptrdiff_t offsetOfExecutable()
126         {
127             return OBJECT_OFFSETOF(JSFunction, m_executable);
128         }
129
130         static inline ptrdiff_t offsetOfAllocationProfile()
131         {
132             return OBJECT_OFFSETOF(JSFunction, m_allocationProfile);
133         }
134
135         ObjectAllocationProfile* allocationProfile(ExecState* exec, unsigned inlineCapacity)
136         {
137             if (UNLIKELY(m_allocationProfile.isNull()))
138                 return createAllocationProfile(exec, inlineCapacity);
139             return &m_allocationProfile;
140         }
141
142         ObjectAllocationProfile* tryGetAllocationProfile()
143         {
144             if (m_allocationProfile.isNull())
145                 return 0;
146             if (m_allocationProfileWatchpoint.hasBeenInvalidated())
147                 return 0;
148             return &m_allocationProfile;
149         }
150         
151         void addAllocationProfileWatchpoint(Watchpoint* watchpoint)
152         {
153             ASSERT(tryGetAllocationProfile());
154             m_allocationProfileWatchpoint.add(watchpoint);
155         }
156         
157         InlineWatchpointSet& allocationProfileWatchpointSet()
158         {
159             return m_allocationProfileWatchpoint;
160         }
161
162     protected:
163         const static unsigned StructureFlags = OverridesGetOwnPropertySlot | ImplementsHasInstance | OverridesVisitChildren | OverridesGetPropertyNames | JSObject::StructureFlags;
164
165         JS_EXPORT_PRIVATE JSFunction(ExecState*, JSGlobalObject*, Structure*);
166         JSFunction(VM&, FunctionExecutable*, JSScope*);
167         
168         void finishCreation(ExecState*, NativeExecutable*, int length, const String& name);
169         using Base::finishCreation;
170
171         ObjectAllocationProfile* createAllocationProfile(ExecState*, size_t inlineCapacity);
172
173         static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
174         static bool getOwnPropertyDescriptor(JSObject*, ExecState*, PropertyName, PropertyDescriptor&);
175         static void getOwnNonIndexPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode = ExcludeDontEnumProperties);
176         static bool defineOwnProperty(JSObject*, ExecState*, PropertyName, PropertyDescriptor&, bool shouldThrow);
177
178         static void put(JSCell*, ExecState*, PropertyName, JSValue, PutPropertySlot&);
179
180         static bool deleteProperty(JSCell*, ExecState*, PropertyName);
181
182         static void visitChildren(JSCell*, SlotVisitor&);
183
184     private:
185         friend class LLIntOffsetsExtractor;
186         
187         JS_EXPORT_PRIVATE bool isHostFunctionNonInline() const;
188
189         static JSValue argumentsGetter(ExecState*, JSValue, PropertyName);
190         static JSValue callerGetter(ExecState*, JSValue, PropertyName);
191         static JSValue lengthGetter(ExecState*, JSValue, PropertyName);
192         static JSValue nameGetter(ExecState*, JSValue, PropertyName);
193
194         WriteBarrier<ExecutableBase> m_executable;
195         WriteBarrier<JSScope> m_scope;
196         ObjectAllocationProfile m_allocationProfile;
197         InlineWatchpointSet m_allocationProfileWatchpoint;
198     };
199
200 } // namespace JSC
201
202 #endif // JSFunction_h