]>
Commit | Line | Data |
---|---|---|
1 | /* | |
2 | * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) | |
3 | * Copyright (C) 2003, 2006, 2007, 2008, 2009, 2015 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 "FunctionRareData.h" | |
28 | #include "InternalFunction.h" | |
29 | #include "JSCallee.h" | |
30 | #include "JSScope.h" | |
31 | #include "Watchpoint.h" | |
32 | ||
33 | namespace JSC { | |
34 | ||
35 | class ExecutableBase; | |
36 | class FunctionExecutable; | |
37 | class FunctionPrototype; | |
38 | class JSLexicalEnvironment; | |
39 | class JSGlobalObject; | |
40 | class LLIntOffsetsExtractor; | |
41 | class NativeExecutable; | |
42 | class SourceCode; | |
43 | namespace DFG { | |
44 | class SpeculativeJIT; | |
45 | class JITCompiler; | |
46 | } | |
47 | ||
48 | typedef std::function<EncodedJSValue (ExecState*)> NativeStdFunction; | |
49 | ||
50 | JS_EXPORT_PRIVATE EncodedJSValue JSC_HOST_CALL callHostFunctionAsConstructor(ExecState*); | |
51 | ||
52 | JS_EXPORT_PRIVATE String getCalculatedDisplayName(CallFrame*, JSObject*); | |
53 | ||
54 | class JSFunction : public JSCallee { | |
55 | friend class JIT; | |
56 | friend class DFG::SpeculativeJIT; | |
57 | friend class DFG::JITCompiler; | |
58 | friend class VM; | |
59 | ||
60 | public: | |
61 | typedef JSCallee Base; | |
62 | const static unsigned StructureFlags = Base::StructureFlags | OverridesGetOwnPropertySlot | OverridesGetPropertyNames; | |
63 | ||
64 | static size_t allocationSize(size_t inlineCapacity) | |
65 | { | |
66 | ASSERT_UNUSED(inlineCapacity, !inlineCapacity); | |
67 | return sizeof(JSFunction); | |
68 | } | |
69 | ||
70 | JS_EXPORT_PRIVATE static JSFunction* create(VM&, JSGlobalObject*, int length, const String& name, NativeFunction, Intrinsic = NoIntrinsic, NativeFunction nativeConstructor = callHostFunctionAsConstructor); | |
71 | ||
72 | static JSFunction* createWithInvalidatedReallocationWatchpoint(VM&, FunctionExecutable*, JSScope*); | |
73 | JS_EXPORT_PRIVATE static JSFunction* create(VM&, JSGlobalObject*, int length, const String& name, NativeStdFunction&&, Intrinsic = NoIntrinsic, NativeFunction nativeConstructor = callHostFunctionAsConstructor); | |
74 | ||
75 | static JSFunction* create(VM&, FunctionExecutable*, JSScope*); | |
76 | ||
77 | static JSFunction* createBuiltinFunction(VM&, FunctionExecutable*, JSGlobalObject*); | |
78 | static JSFunction* createBuiltinFunction(VM&, FunctionExecutable*, JSGlobalObject*, const String& name); | |
79 | ||
80 | JS_EXPORT_PRIVATE String name(ExecState*); | |
81 | JS_EXPORT_PRIVATE String displayName(ExecState*); | |
82 | const String calculatedDisplayName(ExecState*); | |
83 | ||
84 | ExecutableBase* executable() const { return m_executable.get(); } | |
85 | ||
86 | // To call either of these methods include Executable.h | |
87 | bool isHostFunction() const; | |
88 | FunctionExecutable* jsExecutable() const; | |
89 | ||
90 | JS_EXPORT_PRIVATE const SourceCode* sourceCode() const; | |
91 | ||
92 | DECLARE_EXPORT_INFO; | |
93 | ||
94 | static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype) | |
95 | { | |
96 | ASSERT(globalObject); | |
97 | return Structure::create(vm, globalObject, prototype, TypeInfo(JSFunctionType, StructureFlags), info()); | |
98 | } | |
99 | ||
100 | NativeFunction nativeFunction(); | |
101 | NativeFunction nativeConstructor(); | |
102 | ||
103 | static ConstructType getConstructData(JSCell*, ConstructData&); | |
104 | static CallType getCallData(JSCell*, CallData&); | |
105 | ||
106 | static inline ptrdiff_t offsetOfExecutable() | |
107 | { | |
108 | return OBJECT_OFFSETOF(JSFunction, m_executable); | |
109 | } | |
110 | ||
111 | static inline ptrdiff_t offsetOfRareData() | |
112 | { | |
113 | return OBJECT_OFFSETOF(JSFunction, m_rareData); | |
114 | } | |
115 | ||
116 | FunctionRareData* rareData(ExecState* exec, unsigned inlineCapacity) | |
117 | { | |
118 | if (UNLIKELY(!m_rareData)) | |
119 | return allocateAndInitializeRareData(exec, inlineCapacity); | |
120 | if (UNLIKELY(!m_rareData->isInitialized())) | |
121 | return initializeRareData(exec, inlineCapacity); | |
122 | return m_rareData.get(); | |
123 | } | |
124 | ||
125 | FunctionRareData* rareData() | |
126 | { | |
127 | FunctionRareData* rareData = m_rareData.get(); | |
128 | ||
129 | // The JS thread may be concurrently creating the rare data | |
130 | // If we see it, we want to ensure it has been properly created | |
131 | WTF::loadLoadFence(); | |
132 | ||
133 | return rareData; | |
134 | } | |
135 | ||
136 | bool isHostOrBuiltinFunction() const; | |
137 | bool isBuiltinFunction() const; | |
138 | JS_EXPORT_PRIVATE bool isHostFunctionNonInline() const; | |
139 | bool isClassConstructorFunction() const; | |
140 | ||
141 | protected: | |
142 | JS_EXPORT_PRIVATE JSFunction(VM&, JSGlobalObject*, Structure*); | |
143 | JSFunction(VM&, FunctionExecutable*, JSScope*); | |
144 | ||
145 | void finishCreation(VM&, NativeExecutable*, int length, const String& name); | |
146 | using Base::finishCreation; | |
147 | ||
148 | FunctionRareData* allocateAndInitializeRareData(ExecState*, size_t inlineCapacity); | |
149 | FunctionRareData* initializeRareData(ExecState*, size_t inlineCapacity); | |
150 | ||
151 | static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&); | |
152 | static void getOwnNonIndexPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode = EnumerationMode()); | |
153 | static bool defineOwnProperty(JSObject*, ExecState*, PropertyName, const PropertyDescriptor&, bool shouldThrow); | |
154 | ||
155 | static void put(JSCell*, ExecState*, PropertyName, JSValue, PutPropertySlot&); | |
156 | ||
157 | static bool deleteProperty(JSCell*, ExecState*, PropertyName); | |
158 | ||
159 | static void visitChildren(JSCell*, SlotVisitor&); | |
160 | ||
161 | private: | |
162 | static JSFunction* createImpl(VM& vm, FunctionExecutable* executable, JSScope* scope) | |
163 | { | |
164 | JSFunction* function = new (NotNull, allocateCell<JSFunction>(vm.heap)) JSFunction(vm, executable, scope); | |
165 | ASSERT(function->structure()->globalObject()); | |
166 | function->finishCreation(vm); | |
167 | return function; | |
168 | } | |
169 | ||
170 | friend class LLIntOffsetsExtractor; | |
171 | ||
172 | static EncodedJSValue argumentsGetter(ExecState*, JSObject*, EncodedJSValue, PropertyName); | |
173 | static EncodedJSValue callerGetter(ExecState*, JSObject*, EncodedJSValue, PropertyName); | |
174 | static EncodedJSValue lengthGetter(ExecState*, JSObject*, EncodedJSValue, PropertyName); | |
175 | static EncodedJSValue nameGetter(ExecState*, JSObject*, EncodedJSValue, PropertyName); | |
176 | ||
177 | WriteBarrier<ExecutableBase> m_executable; | |
178 | WriteBarrier<FunctionRareData> m_rareData; | |
179 | }; | |
180 | ||
181 | } // namespace JSC | |
182 | ||
183 | #endif // JSFunction_h |