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
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.
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.
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.
32 class FunctionExecutable;
33 class FunctionPrototype;
36 class NativeExecutable;
37 class VPtrHackExecutable;
39 class JITCodeGenerator;
42 EncodedJSValue JSC_HOST_CALL callHostFunctionAsConstructor(ExecState*);
44 class JSFunction : public JSNonFinalObject {
46 friend class DFG::JITCodeGenerator;
47 friend class JSGlobalData;
49 JSFunction(ExecState*, JSGlobalObject*, Structure*);
50 JSFunction(ExecState*, FunctionExecutable*, ScopeChainNode*);
53 typedef JSNonFinalObject Base;
55 static JSFunction* create(ExecState* exec, JSGlobalObject* globalObject, Structure* structure, int length, const Identifier& name, NativeFunction nativeFunction)
57 ASSERT(structure->globalObject());
58 ASSERT(structure->globalObject() == globalObject);
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);
67 static JSFunction* create(ExecState* exec, JSGlobalObject* globalObject, Structure* structure, int length, const Identifier& name, NativeExecutable* nativeExecutable)
69 ASSERT(structure->globalObject());
70 ASSERT(structure->globalObject() == globalObject);
72 JSFunction* function = new (allocateCell<JSFunction>(*exec->heap())) JSFunction(exec, globalObject, structure);
73 function->finishCreation(exec, length, name, (ExecutableBase*)nativeExecutable);
77 static JSFunction* create(ExecState* exec, FunctionExecutable* executable, ScopeChainNode* scopeChain)
79 JSFunction* function = new (allocateCell<JSFunction>(*exec->heap())) JSFunction(exec, executable, scopeChain);
80 ASSERT(function->structure()->globalObject());
81 function->finishCreation(exec, executable, scopeChain);
85 virtual ~JSFunction();
87 const UString& name(ExecState*);
88 const UString displayName(ExecState*);
89 const UString calculatedDisplayName(ExecState*);
91 ScopeChainNode* scope()
93 ASSERT(!isHostFunctionNonInline());
94 return m_scopeChain.get();
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()
103 return m_scopeChain.get();
105 void setScope(JSGlobalData& globalData, ScopeChainNode* scopeChain)
107 ASSERT(!isHostFunctionNonInline());
108 m_scopeChain.set(globalData, this, scopeChain);
111 ExecutableBase* executable() const { return m_executable.get(); }
113 // To call either of these methods include Executable.h
114 inline bool isHostFunction() const;
115 FunctionExecutable* jsExecutable() const;
117 static JS_EXPORTDATA const ClassInfo s_info;
119 static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype)
121 ASSERT(globalObject);
122 return Structure::create(globalData, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), &s_info);
125 NativeFunction nativeFunction();
127 virtual ConstructType getConstructData(ConstructData&);
128 virtual CallType getCallData(CallData&);
130 static inline size_t offsetOfScopeChain()
132 return OBJECT_OFFSETOF(JSFunction, m_scopeChain);
135 static inline size_t offsetOfExecutable()
137 return OBJECT_OFFSETOF(JSFunction, m_executable);
141 const static unsigned StructureFlags = OverridesGetOwnPropertySlot | ImplementsHasInstance | OverridesVisitChildren | OverridesGetPropertyNames | JSObject::StructureFlags;
143 void finishCreation(ExecState*, int length, const Identifier& name, ExecutableBase*);
144 void finishCreation(ExecState*, FunctionExecutable*, ScopeChainNode*);
147 explicit JSFunction(VPtrStealingHackType);
149 bool isHostFunctionNonInline() const;
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);
158 virtual void visitChildren(SlotVisitor&);
160 static JSValue argumentsGetter(ExecState*, JSValue, const Identifier&);
161 static JSValue callerGetter(ExecState*, JSValue, const Identifier&);
162 static JSValue lengthGetter(ExecState*, JSValue, const Identifier&);
164 WriteBarrier<ExecutableBase> m_executable;
165 WriteBarrier<ScopeChainNode> m_scopeChain;
168 JSFunction* asFunction(JSValue);
170 inline JSFunction* asFunction(JSValue value)
172 ASSERT(asObject(value)->inherits(&JSFunction::s_info));
173 return static_cast<JSFunction*>(asObject(value));
178 #endif // JSFunction_h