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