]> git.saurik.com Git - apple/javascriptcore.git/blame - runtime/Executable.h
JavaScriptCore-621.1.tar.gz
[apple/javascriptcore.git] / runtime / Executable.h
CommitLineData
f9bf01c6
A
1/*
2 * Copyright (C) 2009 Apple Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#ifndef Executable_h
27#define Executable_h
28
29#include "JSFunction.h"
30#include "Interpreter.h"
31#include "Nodes.h"
32#include "SamplingTool.h"
33
34namespace JSC {
35
36 class CodeBlock;
37 class Debugger;
38 class EvalCodeBlock;
39 class ProgramCodeBlock;
40 class ScopeChainNode;
41
42 struct ExceptionInfo;
43
44 class ExecutableBase : public RefCounted<ExecutableBase> {
45 friend class JIT;
46
47 protected:
48 static const int NUM_PARAMETERS_IS_HOST = 0;
49 static const int NUM_PARAMETERS_NOT_COMPILED = -1;
50
51 public:
52 ExecutableBase(int numParameters)
53 : m_numParameters(numParameters)
54 {
55 }
56
57 virtual ~ExecutableBase() {}
58
59 bool isHostFunction() const { return m_numParameters == NUM_PARAMETERS_IS_HOST; }
60
61 protected:
62 int m_numParameters;
63
64#if ENABLE(JIT)
65 public:
66 JITCode& generatedJITCode()
67 {
68 ASSERT(m_jitCode);
69 return m_jitCode;
70 }
71
72 ExecutablePool* getExecutablePool()
73 {
74 return m_jitCode.getExecutablePool();
75 }
76
77 protected:
78 JITCode m_jitCode;
79#endif
80 };
81
82#if ENABLE(JIT)
83 class NativeExecutable : public ExecutableBase {
84 public:
4e4e5a6f 85 NativeExecutable(JITCode thunk)
f9bf01c6
A
86 : ExecutableBase(NUM_PARAMETERS_IS_HOST)
87 {
4e4e5a6f 88 m_jitCode = thunk;
f9bf01c6
A
89 }
90
91 ~NativeExecutable();
92 };
93#endif
94
95 class VPtrHackExecutable : public ExecutableBase {
96 public:
97 VPtrHackExecutable()
98 : ExecutableBase(NUM_PARAMETERS_IS_HOST)
99 {
100 }
101
102 ~VPtrHackExecutable();
103 };
104
105 class ScriptExecutable : public ExecutableBase {
106 public:
107 ScriptExecutable(JSGlobalData* globalData, const SourceCode& source)
108 : ExecutableBase(NUM_PARAMETERS_NOT_COMPILED)
109 , m_source(source)
110 , m_features(0)
111 {
112#if ENABLE(CODEBLOCK_SAMPLING)
113 if (SamplingTool* sampler = globalData->interpreter->sampler())
114 sampler->notifyOfScope(this);
115#else
116 UNUSED_PARAM(globalData);
117#endif
118 }
119
120 ScriptExecutable(ExecState* exec, const SourceCode& source)
121 : ExecutableBase(NUM_PARAMETERS_NOT_COMPILED)
122 , m_source(source)
123 , m_features(0)
124 {
125#if ENABLE(CODEBLOCK_SAMPLING)
126 if (SamplingTool* sampler = exec->globalData().interpreter->sampler())
127 sampler->notifyOfScope(this);
128#else
129 UNUSED_PARAM(exec);
130#endif
131 }
132
133 const SourceCode& source() { return m_source; }
134 intptr_t sourceID() const { return m_source.provider()->asID(); }
135 const UString& sourceURL() const { return m_source.provider()->url(); }
136 int lineNo() const { return m_firstLine; }
137 int lastLine() const { return m_lastLine; }
138
139 bool usesEval() const { return m_features & EvalFeature; }
140 bool usesArguments() const { return m_features & ArgumentsFeature; }
141 bool needsActivation() const { return m_features & (EvalFeature | ClosureFeature | WithFeature | CatchFeature); }
142
143 virtual ExceptionInfo* reparseExceptionInfo(JSGlobalData*, ScopeChainNode*, CodeBlock*) = 0;
144
145 protected:
146 void recordParse(CodeFeatures features, int firstLine, int lastLine)
147 {
148 m_features = features;
149 m_firstLine = firstLine;
150 m_lastLine = lastLine;
151 }
152
153 SourceCode m_source;
154 CodeFeatures m_features;
155 int m_firstLine;
156 int m_lastLine;
157 };
158
159 class EvalExecutable : public ScriptExecutable {
160 public:
161
162 ~EvalExecutable();
163
164 EvalCodeBlock& bytecode(ExecState* exec, ScopeChainNode* scopeChainNode)
165 {
166 if (!m_evalCodeBlock) {
167 JSObject* error = compile(exec, scopeChainNode);
168 ASSERT_UNUSED(!error, error);
169 }
170 return *m_evalCodeBlock;
171 }
172
173 JSObject* compile(ExecState*, ScopeChainNode*);
174
175 ExceptionInfo* reparseExceptionInfo(JSGlobalData*, ScopeChainNode*, CodeBlock*);
176 static PassRefPtr<EvalExecutable> create(ExecState* exec, const SourceCode& source) { return adoptRef(new EvalExecutable(exec, source)); }
177
178 private:
179 EvalExecutable(ExecState* exec, const SourceCode& source)
180 : ScriptExecutable(exec, source)
181 , m_evalCodeBlock(0)
182 {
183 }
184 EvalCodeBlock* m_evalCodeBlock;
185
186#if ENABLE(JIT)
187 public:
188 JITCode& jitCode(ExecState* exec, ScopeChainNode* scopeChainNode)
189 {
190 if (!m_jitCode)
191 generateJITCode(exec, scopeChainNode);
192 return m_jitCode;
193 }
194
195 private:
196 void generateJITCode(ExecState*, ScopeChainNode*);
197#endif
198 };
199
200 class ProgramExecutable : public ScriptExecutable {
201 public:
202 static PassRefPtr<ProgramExecutable> create(ExecState* exec, const SourceCode& source)
203 {
204 return adoptRef(new ProgramExecutable(exec, source));
205 }
206
207 ~ProgramExecutable();
208
209 ProgramCodeBlock& bytecode(ExecState* exec, ScopeChainNode* scopeChainNode)
210 {
211 if (!m_programCodeBlock) {
212 JSObject* error = compile(exec, scopeChainNode);
213 ASSERT_UNUSED(!error, error);
214 }
215 return *m_programCodeBlock;
216 }
217
218 JSObject* checkSyntax(ExecState*);
219 JSObject* compile(ExecState*, ScopeChainNode*);
220
221 // CodeBlocks for program code are transient and therefore do not gain from from throwing out there exception information.
222 ExceptionInfo* reparseExceptionInfo(JSGlobalData*, ScopeChainNode*, CodeBlock*) { ASSERT_NOT_REACHED(); return 0; }
223
224 private:
225 ProgramExecutable(ExecState* exec, const SourceCode& source)
226 : ScriptExecutable(exec, source)
227 , m_programCodeBlock(0)
228 {
229 }
230 ProgramCodeBlock* m_programCodeBlock;
231
232#if ENABLE(JIT)
233 public:
234 JITCode& jitCode(ExecState* exec, ScopeChainNode* scopeChainNode)
235 {
236 if (!m_jitCode)
237 generateJITCode(exec, scopeChainNode);
238 return m_jitCode;
239 }
240
241 private:
242 void generateJITCode(ExecState*, ScopeChainNode*);
243#endif
244 };
245
246 class FunctionExecutable : public ScriptExecutable {
247 friend class JIT;
248 public:
249 static PassRefPtr<FunctionExecutable> create(ExecState* exec, const Identifier& name, const SourceCode& source, bool forceUsesArguments, FunctionParameters* parameters, int firstLine, int lastLine)
250 {
251 return adoptRef(new FunctionExecutable(exec, name, source, forceUsesArguments, parameters, firstLine, lastLine));
252 }
253
254 static PassRefPtr<FunctionExecutable> create(JSGlobalData* globalData, const Identifier& name, const SourceCode& source, bool forceUsesArguments, FunctionParameters* parameters, int firstLine, int lastLine)
255 {
256 return adoptRef(new FunctionExecutable(globalData, name, source, forceUsesArguments, parameters, firstLine, lastLine));
257 }
258
259 ~FunctionExecutable();
260
261 JSFunction* make(ExecState* exec, ScopeChainNode* scopeChain)
262 {
263 return new (exec) JSFunction(exec, this, scopeChain);
264 }
265
266 CodeBlock& bytecode(ExecState* exec, ScopeChainNode* scopeChainNode)
267 {
268 ASSERT(scopeChainNode);
269 if (!m_codeBlock)
270 compile(exec, scopeChainNode);
271 return *m_codeBlock;
272 }
273
274 bool isGenerated() const
275 {
276 return m_codeBlock;
277 }
278
279 CodeBlock& generatedBytecode()
280 {
281 ASSERT(m_codeBlock);
282 return *m_codeBlock;
283 }
284
285 const Identifier& name() { return m_name; }
286 size_t parameterCount() const { return m_parameters->size(); }
4e4e5a6f 287 unsigned variableCount() const { return m_numVariables; }
f9bf01c6
A
288 UString paramString() const;
289
290 void recompile(ExecState*);
291 ExceptionInfo* reparseExceptionInfo(JSGlobalData*, ScopeChainNode*, CodeBlock*);
292 void markAggregate(MarkStack& markStack);
293 static PassRefPtr<FunctionExecutable> fromGlobalCode(const Identifier&, ExecState*, Debugger*, const SourceCode&, int* errLine = 0, UString* errMsg = 0);
294
295 private:
296 FunctionExecutable(JSGlobalData* globalData, const Identifier& name, const SourceCode& source, bool forceUsesArguments, FunctionParameters* parameters, int firstLine, int lastLine)
297 : ScriptExecutable(globalData, source)
4e4e5a6f 298 , m_numVariables(0)
f9bf01c6
A
299 , m_forceUsesArguments(forceUsesArguments)
300 , m_parameters(parameters)
301 , m_codeBlock(0)
302 , m_name(name)
f9bf01c6
A
303 {
304 m_firstLine = firstLine;
305 m_lastLine = lastLine;
306 }
307
308 FunctionExecutable(ExecState* exec, const Identifier& name, const SourceCode& source, bool forceUsesArguments, FunctionParameters* parameters, int firstLine, int lastLine)
309 : ScriptExecutable(exec, source)
4e4e5a6f 310 , m_numVariables(0)
f9bf01c6
A
311 , m_forceUsesArguments(forceUsesArguments)
312 , m_parameters(parameters)
313 , m_codeBlock(0)
314 , m_name(name)
f9bf01c6
A
315 {
316 m_firstLine = firstLine;
317 m_lastLine = lastLine;
318 }
319
320 void compile(ExecState*, ScopeChainNode*);
321
4e4e5a6f
A
322 unsigned m_numVariables : 31;
323 bool m_forceUsesArguments : 1;
324
f9bf01c6
A
325 RefPtr<FunctionParameters> m_parameters;
326 CodeBlock* m_codeBlock;
327 Identifier m_name;
f9bf01c6
A
328
329#if ENABLE(JIT)
330 public:
331 JITCode& jitCode(ExecState* exec, ScopeChainNode* scopeChainNode)
332 {
333 if (!m_jitCode)
334 generateJITCode(exec, scopeChainNode);
335 return m_jitCode;
336 }
337
338 private:
339 void generateJITCode(ExecState*, ScopeChainNode*);
340#endif
341 };
342
343 inline FunctionExecutable* JSFunction::jsExecutable() const
344 {
345 ASSERT(!isHostFunctionNonInline());
346 return static_cast<FunctionExecutable*>(m_executable.get());
347 }
348
349 inline bool JSFunction::isHostFunction() const
350 {
351 ASSERT(m_executable);
352 return m_executable->isHostFunction();
353 }
354
355}
356
357#endif