initial import
[vuplus_webkit] / 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 "JSObject.h"
28
29 namespace JSC {
30
31     class ExecutableBase;
32     class FunctionExecutable;
33     class FunctionPrototype;
34     class JSActivation;
35     class JSGlobalObject;
36     class NativeExecutable;
37     class VPtrHackExecutable;
38     namespace DFG {
39     class JITCodeGenerator;
40     }
41
42     EncodedJSValue JSC_HOST_CALL callHostFunctionAsConstructor(ExecState*);
43
44     class JSFunction : public JSNonFinalObject {
45         friend class JIT;
46         friend class DFG::JITCodeGenerator;
47         friend class JSGlobalData;
48
49         JSFunction(ExecState*, JSGlobalObject*, Structure*);
50         JSFunction(ExecState*, FunctionExecutable*, ScopeChainNode*);
51         
52     public:
53         typedef JSNonFinalObject Base;
54
55         static JSFunction* create(ExecState* exec, JSGlobalObject* globalObject, Structure* structure, int length, const Identifier& name, NativeFunction nativeFunction)
56         {
57             ASSERT(structure->globalObject());
58             ASSERT(structure->globalObject() == globalObject);
59             
60             ExecutableBase* executable = (ExecutableBase*)exec->globalData().getHostFunction(nativeFunction);
61             JSFunction* function = new (allocateCell<JSFunction>(*exec->heap())) JSFunction(exec, globalObject, structure);
62             // Can't do this during initialization because getHostFunction might do a GC allocation.
63             function->finishCreation(exec, length, name, executable);
64             return function;
65         }
66
67         static JSFunction* create(ExecState* exec, JSGlobalObject* globalObject, Structure* structure, int length, const Identifier& name, NativeExecutable* nativeExecutable)
68         {
69             ASSERT(structure->globalObject());
70             ASSERT(structure->globalObject() == globalObject);
71
72             JSFunction* function = new (allocateCell<JSFunction>(*exec->heap())) JSFunction(exec, globalObject, structure);
73             function->finishCreation(exec, length, name, (ExecutableBase*)nativeExecutable);
74             return function;
75         }
76
77         static JSFunction* create(ExecState* exec, FunctionExecutable* executable, ScopeChainNode* scopeChain)
78         {
79             JSFunction* function = new (allocateCell<JSFunction>(*exec->heap())) JSFunction(exec, executable, scopeChain);
80             ASSERT(function->structure()->globalObject());
81             function->finishCreation(exec, executable, scopeChain);
82             return function;
83         }
84         
85         virtual ~JSFunction();
86
87         const UString& name(ExecState*);
88         const UString displayName(ExecState*);
89         const UString calculatedDisplayName(ExecState*);
90
91         ScopeChainNode* scope()
92         {
93             ASSERT(!isHostFunctionNonInline());
94             return m_scopeChain.get();
95         }
96         // This method may be called for host functins, in which case it
97         // will return an arbitrary value. This should only be used for
98         // optimized paths in which the return value does not matter for
99         // host functions, and checking whether the function is a host
100         // function is deemed too expensive.
101         ScopeChainNode* scopeUnchecked()
102         {
103             return m_scopeChain.get();
104         }
105         void setScope(JSGlobalData& globalData, ScopeChainNode* scopeChain)
106         {
107             ASSERT(!isHostFunctionNonInline());
108             m_scopeChain.set(globalData, this, scopeChain);
109         }
110
111         ExecutableBase* executable() const { return m_executable.get(); }
112
113         // To call either of these methods include Executable.h
114         inline bool isHostFunction() const;
115         FunctionExecutable* jsExecutable() const;
116
117         static JS_EXPORTDATA const ClassInfo s_info;
118
119         static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype) 
120         {
121             ASSERT(globalObject);
122             return Structure::create(globalData, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), &s_info); 
123         }
124
125         NativeFunction nativeFunction();
126
127         virtual ConstructType getConstructData(ConstructData&);
128         virtual CallType getCallData(CallData&);
129
130         static inline size_t offsetOfScopeChain()
131         {
132             return OBJECT_OFFSETOF(JSFunction, m_scopeChain);
133         }
134
135         static inline size_t offsetOfExecutable()
136         {
137             return OBJECT_OFFSETOF(JSFunction, m_executable);
138         }
139
140     protected:
141         const static unsigned StructureFlags = OverridesGetOwnPropertySlot | ImplementsHasInstance | OverridesVisitChildren | OverridesGetPropertyNames | JSObject::StructureFlags;
142
143         void finishCreation(ExecState*, int length, const Identifier& name, ExecutableBase*);
144         void finishCreation(ExecState*, FunctionExecutable*, ScopeChainNode*);
145
146     private:
147         explicit JSFunction(VPtrStealingHackType);
148
149         bool isHostFunctionNonInline() const;
150
151         virtual void preventExtensions(JSGlobalData&);
152         virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
153         virtual bool getOwnPropertyDescriptor(ExecState*, const Identifier&, PropertyDescriptor&);
154         virtual void getOwnPropertyNames(ExecState*, PropertyNameArray&, EnumerationMode mode = ExcludeDontEnumProperties);
155         virtual void put(ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&);
156         virtual bool deleteProperty(ExecState*, const Identifier& propertyName);
157
158         virtual void visitChildren(SlotVisitor&);
159
160         static JSValue argumentsGetter(ExecState*, JSValue, const Identifier&);
161         static JSValue callerGetter(ExecState*, JSValue, const Identifier&);
162         static JSValue lengthGetter(ExecState*, JSValue, const Identifier&);
163
164         WriteBarrier<ExecutableBase> m_executable;
165         WriteBarrier<ScopeChainNode> m_scopeChain;
166     };
167
168     JSFunction* asFunction(JSValue);
169
170     inline JSFunction* asFunction(JSValue value)
171     {
172         ASSERT(asObject(value)->inherits(&JSFunction::s_info));
173         return static_cast<JSFunction*>(asObject(value));
174     }
175
176 } // namespace JSC
177
178 #endif // JSFunction_h