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:
85 NativeExecutable(ExecState* exec)
86 : ExecutableBase(NUM_PARAMETERS_IS_HOST)
87 {
88 m_jitCode = JITCode(JITCode::HostFunction(code: exec->globalData().jitStubs.ctiNativeCallThunk()));
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 bool isCompiled() const { return m_evalCodeBlock; }
176
177 ExceptionInfo* reparseExceptionInfo(JSGlobalData*, ScopeChainNode*, CodeBlock*);
178 static PassRefPtr<EvalExecutable> create(ExecState* exec, const SourceCode& source) { return adoptRef(p: new EvalExecutable(exec, source)); }
179
180 private:
181 EvalExecutable(ExecState* exec, const SourceCode& source)
182 : ScriptExecutable(exec, source)
183 , m_evalCodeBlock(0)
184 {
185 }
186 EvalCodeBlock* m_evalCodeBlock;
187
188#if ENABLE(JIT)
189 public:
190 JITCode& jitCode(ExecState* exec, ScopeChainNode* scopeChainNode)
191 {
192 if (!m_jitCode)
193 generateJITCode(exec, scopeChainNode);
194 return m_jitCode;
195 }
196
197 private:
198 void generateJITCode(ExecState*, ScopeChainNode*);
199#endif
200 };
201
202 class ProgramExecutable : public ScriptExecutable {
203 public:
204 static PassRefPtr<ProgramExecutable> create(ExecState* exec, const SourceCode& source)
205 {
206 return adoptRef(p: new ProgramExecutable(exec, source));
207 }
208
209 ~ProgramExecutable();
210
211 ProgramCodeBlock& bytecode(ExecState* exec, ScopeChainNode* scopeChainNode)
212 {
213 if (!m_programCodeBlock) {
214 JSObject* error = compile(exec, scopeChainNode);
215 ASSERT_UNUSED(!error, error);
216 }
217 return *m_programCodeBlock;
218 }
219
220 JSObject* checkSyntax(ExecState*);
221 JSObject* compile(ExecState*, ScopeChainNode*);
222
223 // CodeBlocks for program code are transient and therefore do not gain from from throwing out there exception information.
224 ExceptionInfo* reparseExceptionInfo(JSGlobalData*, ScopeChainNode*, CodeBlock*) { ASSERT_NOT_REACHED(); return 0; }
225
226 private:
227 ProgramExecutable(ExecState* exec, const SourceCode& source)
228 : ScriptExecutable(exec, source)
229 , m_programCodeBlock(0)
230 {
231 }
232 ProgramCodeBlock* m_programCodeBlock;
233
234#if ENABLE(JIT)
235 public:
236 JITCode& jitCode(ExecState* exec, ScopeChainNode* scopeChainNode)
237 {
238 if (!m_jitCode)
239 generateJITCode(exec, scopeChainNode);
240 return m_jitCode;
241 }
242
243 private:
244 void generateJITCode(ExecState*, ScopeChainNode*);
245#endif
246 };
247
248 class FunctionExecutable : public ScriptExecutable {
249 friend class JIT;
250 public:
251 static PassRefPtr<FunctionExecutable> create(ExecState* exec, const Identifier& name, const SourceCode& source, bool forceUsesArguments, FunctionParameters* parameters, int firstLine, int lastLine)
252 {
253 return adoptRef(p: new FunctionExecutable(exec, name, source, forceUsesArguments, parameters, firstLine, lastLine));
254 }
255
256 static PassRefPtr<FunctionExecutable> create(JSGlobalData* globalData, const Identifier& name, const SourceCode& source, bool forceUsesArguments, FunctionParameters* parameters, int firstLine, int lastLine)
257 {
258 return adoptRef(p: new FunctionExecutable(globalData, name, source, forceUsesArguments, parameters, firstLine, lastLine));
259 }
260
261 ~FunctionExecutable();
262
263 JSFunction* make(ExecState* exec, ScopeChainNode* scopeChain)
264 {
265 return new (exec) JSFunction(exec, this, scopeChain);
266 }
267
268 CodeBlock& bytecode(ExecState* exec, ScopeChainNode* scopeChainNode)
269 {
270 ASSERT(scopeChainNode);
271 if (!m_codeBlock)
272 compile(exec, scopeChainNode);
273 return *m_codeBlock;
274 }
275
276 bool isGenerated() const
277 {
278 return m_codeBlock;
279 }
280
281 CodeBlock& generatedBytecode()
282 {
283 ASSERT(m_codeBlock);
284 return *m_codeBlock;
285 }
286
287 const Identifier& name() { return m_name; }
288 size_t parameterCount() const { return m_parameters->size(); }
289 size_t variableCount() const { return m_numVariables; }
290 UString paramString() const;
291#ifdef QT_BUILD_SCRIPT_LIB
292 UString parameterName(int i) const { return (*m_parameters)[i].ustring(); }
293#endif
294
295 void recompile(ExecState*);
296 ExceptionInfo* reparseExceptionInfo(JSGlobalData*, ScopeChainNode*, CodeBlock*);
297 void markAggregate(MarkStack& markStack);
298 static PassRefPtr<FunctionExecutable> fromGlobalCode(const Identifier&, ExecState*, Debugger*, const SourceCode&, int* errLine = 0, UString* errMsg = 0);
299
300 private:
301 FunctionExecutable(JSGlobalData* globalData, const Identifier& name, const SourceCode& source, bool forceUsesArguments, FunctionParameters* parameters, int firstLine, int lastLine)
302 : ScriptExecutable(globalData, source)
303 , m_forceUsesArguments(forceUsesArguments)
304 , m_parameters(parameters)
305 , m_codeBlock(0)
306 , m_name(name)
307 , m_numVariables(0)
308 {
309 m_firstLine = firstLine;
310 m_lastLine = lastLine;
311 }
312
313 FunctionExecutable(ExecState* exec, const Identifier& name, const SourceCode& source, bool forceUsesArguments, FunctionParameters* parameters, int firstLine, int lastLine)
314 : ScriptExecutable(exec, source)
315 , m_forceUsesArguments(forceUsesArguments)
316 , m_parameters(parameters)
317 , m_codeBlock(0)
318 , m_name(name)
319 , m_numVariables(0)
320 {
321 m_firstLine = firstLine;
322 m_lastLine = lastLine;
323 }
324
325 void compile(ExecState*, ScopeChainNode*);
326
327 bool m_forceUsesArguments;
328 RefPtr<FunctionParameters> m_parameters;
329 CodeBlock* m_codeBlock;
330 Identifier m_name;
331 size_t m_numVariables;
332
333#if ENABLE(JIT)
334 public:
335 JITCode& jitCode(ExecState* exec, ScopeChainNode* scopeChainNode)
336 {
337 if (!m_jitCode)
338 generateJITCode(exec, scopeChainNode);
339 return m_jitCode;
340 }
341
342 private:
343 void generateJITCode(ExecState*, ScopeChainNode*);
344#endif
345 };
346
347 inline FunctionExecutable* JSFunction::jsExecutable() const
348 {
349 ASSERT(!isHostFunctionNonInline());
350 return static_cast<FunctionExecutable*>(m_executable.get());
351 }
352
353 inline bool JSFunction::isHostFunction() const
354 {
355 ASSERT(m_executable);
356 return m_executable->isHostFunction();
357 }
358
359}
360
361#endif
362

source code of qtscript/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Executable.h