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 33namespace 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(VM&, JSGlobalObject*, int length, const String& name, NativeFunction, Intrinsic = NoIntrinsic, NativeFunction nativeConstructor = callHostFunctionAsConstructor); 62 63 static JSFunction* create(VM& vm, FunctionExecutable* executable, JSScope* scope) 64 { 65 JSFunction* function = new (NotNull, allocateCell<JSFunction>(vm.heap)) JSFunction(vm, executable, scope); 66 ASSERT(function->structure()->globalObject()); 67 function->finishCreation(vm); 68 return function; 69 } 70 71 static JSFunction* createBuiltinFunction(VM&, FunctionExecutable*, JSGlobalObject*); 72 73 static void destroy(JSCell*); 74 75 JS_EXPORT_PRIVATE String name(ExecState*); 76 JS_EXPORT_PRIVATE String displayName(ExecState*); 77 const String calculatedDisplayName(ExecState*); 78 79 JSScope* scope() 80 { 81 ASSERT(!isHostFunctionNonInline()); 82 return m_scope.get(); 83 } 84 // This method may be called for host functins, in which case it 85 // will return an arbitrary value. This should only be used for 86 // optimized paths in which the return value does not matter for 87 // host functions, and checking whether the function is a host 88 // function is deemed too expensive. 89 JSScope* scopeUnchecked() 90 { 91 return m_scope.get(); 92 } 93 void setScope(VM& vm, JSScope* scope) 94 { 95 ASSERT(!isHostFunctionNonInline()); 96 m_scope.set(vm, this, scope); 97 } 98 void addNameScopeIfNeeded(VM&); 99 100 ExecutableBase* executable() const { return m_executable.get(); } 101 102 // To call either of these methods include Executable.h 103 bool isHostFunction() const; 104 FunctionExecutable* jsExecutable() const; 105 106 JS_EXPORT_PRIVATE const SourceCode* sourceCode() const; 107 108 DECLARE_EXPORT_INFO; 109 110 static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype) 111 { 112 ASSERT(globalObject); 113 return Structure::create(vm, globalObject, prototype, TypeInfo(JSFunctionType, StructureFlags), info()); 114 } 115 116 NativeFunction nativeFunction(); 117 NativeFunction nativeConstructor(); 118 119 static ConstructType getConstructData(JSCell*, ConstructData&); 120 static CallType getCallData(JSCell*, CallData&); 121 122 static inline ptrdiff_t offsetOfScopeChain() 123 { 124 return OBJECT_OFFSETOF(JSFunction, m_scope); 125 } 126 127 static inline ptrdiff_t offsetOfExecutable() 128 { 129 return OBJECT_OFFSETOF(JSFunction, m_executable); 130 } 131 132 static inline ptrdiff_t offsetOfAllocationProfile() 133 { 134 return OBJECT_OFFSETOF(JSFunction, m_allocationProfile); 135 } 136 137 ObjectAllocationProfile* allocationProfile(ExecState* exec, unsigned inlineCapacity) 138 { 139 if (UNLIKELY(m_allocationProfile.isNull())) 140 return createAllocationProfile(exec, inlineCapacity); 141 return &m_allocationProfile; 142 } 143 144 Structure* allocationStructure() { return m_allocationProfile.structure(); } 145 146 InlineWatchpointSet& allocationProfileWatchpointSet() 147 { 148 return m_allocationProfileWatchpoint; 149 } 150 151 bool isHostOrBuiltinFunction() const; 152 bool isBuiltinFunction() const; 153 JS_EXPORT_PRIVATE bool isHostFunctionNonInline() const; 154 155 protected: 156 const static unsigned StructureFlags = OverridesGetOwnPropertySlot | ImplementsHasInstance | OverridesVisitChildren | OverridesGetPropertyNames | JSObject::StructureFlags; 157 158 JS_EXPORT_PRIVATE JSFunction(VM&, JSGlobalObject*, Structure*); 159 JSFunction(VM&, FunctionExecutable*, JSScope*); 160 161 void finishCreation(VM&, NativeExecutable*, int length, const String& name); 162 using Base::finishCreation; 163 164 ObjectAllocationProfile* createAllocationProfile(ExecState*, size_t inlineCapacity); 165 166 static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&); 167 static void getOwnNonIndexPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode = ExcludeDontEnumProperties); 168 static bool defineOwnProperty(JSObject*, ExecState*, PropertyName, const PropertyDescriptor&, bool shouldThrow); 169 170 static void put(JSCell*, ExecState*, PropertyName, JSValue, PutPropertySlot&); 171 172 static bool deleteProperty(JSCell*, ExecState*, PropertyName); 173 174 static void visitChildren(JSCell*, SlotVisitor&); 175 176 private: 177 friend class LLIntOffsetsExtractor; 178 179 static EncodedJSValue argumentsGetter(ExecState*, JSObject*, EncodedJSValue, PropertyName); 180 static EncodedJSValue callerGetter(ExecState*, JSObject*, EncodedJSValue, PropertyName); 181 static EncodedJSValue lengthGetter(ExecState*, JSObject*, EncodedJSValue, PropertyName); 182 static EncodedJSValue nameGetter(ExecState*, JSObject*, EncodedJSValue, PropertyName); 183 184 WriteBarrier<ExecutableBase> m_executable; 185 WriteBarrier<JSScope> m_scope; 186 ObjectAllocationProfile m_allocationProfile; 187 InlineWatchpointSet m_allocationProfileWatchpoint; 188 }; 189 190} // namespace JSC 191 192#endif // JSFunction_h 193