source: webkit/trunk/JavaScriptCore/runtime/Executable.h@ 65146

Last change on this file since 65146 was 63675, checked in by Darin Adler, 15 years ago

2010-07-16 Darin Adler <Darin Adler>

Reviewed by Sam Weinig.

Use OwnPtr for CodeBlock objects
https://bugs.webkit.org/show_bug.cgi?id=42490

  • runtime/Executable.cpp: (JSC::EvalExecutable::EvalExecutable): Moved this here and made it non-inline. Eliminated the code that used to initialize the raw pointer since it's now an OwnPtr. (JSC::EvalExecutable::~EvalExecutable): Removed the explicit delete here. (JSC::ProgramExecutable::ProgramExecutable): Ditto. (JSC::ProgramExecutable::~ProgramExecutable): Ditto. (JSC::FunctionExecutable::FunctionExecutable): Ditto. (JSC::FunctionExecutable::~FunctionExecutable): Ditto. (JSC::EvalExecutable::compileInternal): Added use of adoptPtr and get. (JSC::ProgramExecutable::compileInternal): Ditto. (JSC::FunctionExecutable::compileForCallInternal): Ditto. (JSC::FunctionExecutable::compileForConstructInternal): Ditto. (JSC::FunctionExecutable::recompile): Use clear instead of delete followed by assignment of 0.
  • runtime/Executable.h: Moved constructors to the cpp file and changed raw pointers to OwnPtr.
File size: 13.8 KB
Line 
1/*
2 * Copyright (C) 2009, 2010 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 "CallData.h"
30#include "JSFunction.h"
31#include "Interpreter.h"
32#include "Nodes.h"
33#include "SamplingTool.h"
34#include <wtf/PassOwnPtr.h>
35
36namespace JSC {
37
38 class CodeBlock;
39 class Debugger;
40 class EvalCodeBlock;
41 class FunctionCodeBlock;
42 class ProgramCodeBlock;
43 class ScopeChainNode;
44
45 struct ExceptionInfo;
46
47 class ExecutableBase : public RefCounted<ExecutableBase> {
48 friend class JIT;
49
50 protected:
51 static const int NUM_PARAMETERS_IS_HOST = 0;
52 static const int NUM_PARAMETERS_NOT_COMPILED = -1;
53
54 public:
55 ExecutableBase(int numParameters)
56 : m_numParametersForCall(numParameters)
57 , m_numParametersForConstruct(numParameters)
58 {
59 }
60
61 virtual ~ExecutableBase() {}
62
63 bool isHostFunction() const
64 {
65 ASSERT((m_numParametersForCall == NUM_PARAMETERS_IS_HOST) == (m_numParametersForConstruct == NUM_PARAMETERS_IS_HOST));
66 return m_numParametersForCall == NUM_PARAMETERS_IS_HOST;
67 }
68
69 protected:
70 int m_numParametersForCall;
71 int m_numParametersForConstruct;
72
73#if ENABLE(JIT)
74 public:
75 JITCode& generatedJITCodeForCall()
76 {
77 ASSERT(m_jitCodeForCall);
78 return m_jitCodeForCall;
79 }
80
81 JITCode& generatedJITCodeForConstruct()
82 {
83 ASSERT(m_jitCodeForConstruct);
84 return m_jitCodeForConstruct;
85 }
86
87 protected:
88 JITCode m_jitCodeForCall;
89 JITCode m_jitCodeForConstruct;
90 MacroAssemblerCodePtr m_jitCodeForCallWithArityCheck;
91 MacroAssemblerCodePtr m_jitCodeForConstructWithArityCheck;
92#endif
93 };
94
95#if ENABLE(JIT)
96 class NativeExecutable : public ExecutableBase {
97 friend class JIT;
98 public:
99 static PassRefPtr<NativeExecutable> create(MacroAssemblerCodePtr callThunk, NativeFunction function, MacroAssemblerCodePtr constructThunk, NativeFunction constructor)
100 {
101 if (!callThunk)
102 return adoptRef(new NativeExecutable(JITCode(), function, JITCode(), constructor));
103 return adoptRef(new NativeExecutable(JITCode::HostFunction(callThunk), function, JITCode::HostFunction(constructThunk), constructor));
104 }
105
106 ~NativeExecutable();
107
108 NativeFunction function() { return m_function; }
109
110 private:
111 NativeExecutable(JITCode callThunk, NativeFunction function, JITCode constructThunk, NativeFunction constructor)
112 : ExecutableBase(NUM_PARAMETERS_IS_HOST)
113 , m_function(function)
114 , m_constructor(constructor)
115 {
116 m_jitCodeForCall = callThunk;
117 m_jitCodeForConstruct = constructThunk;
118 m_jitCodeForCallWithArityCheck = callThunk.addressForCall();
119 m_jitCodeForConstructWithArityCheck = constructThunk.addressForCall();
120 }
121
122 NativeFunction m_function;
123 // Probably should be a NativeConstructor, but this will currently require rewriting the JIT
124 // trampoline. It may be easier to make NativeFunction be passed 'this' as a part of the ArgList.
125 NativeFunction m_constructor;
126 };
127#endif
128
129 class VPtrHackExecutable : public ExecutableBase {
130 public:
131 VPtrHackExecutable()
132 : ExecutableBase(NUM_PARAMETERS_IS_HOST)
133 {
134 }
135
136 ~VPtrHackExecutable();
137 };
138
139 class ScriptExecutable : public ExecutableBase {
140 public:
141 ScriptExecutable(JSGlobalData* globalData, const SourceCode& source)
142 : ExecutableBase(NUM_PARAMETERS_NOT_COMPILED)
143 , m_source(source)
144 , m_features(0)
145 {
146#if ENABLE(CODEBLOCK_SAMPLING)
147 if (SamplingTool* sampler = globalData->interpreter->sampler())
148 sampler->notifyOfScope(this);
149#else
150 UNUSED_PARAM(globalData);
151#endif
152 }
153
154 ScriptExecutable(ExecState* exec, const SourceCode& source)
155 : ExecutableBase(NUM_PARAMETERS_NOT_COMPILED)
156 , m_source(source)
157 , m_features(0)
158 {
159#if ENABLE(CODEBLOCK_SAMPLING)
160 if (SamplingTool* sampler = exec->globalData().interpreter->sampler())
161 sampler->notifyOfScope(this);
162#else
163 UNUSED_PARAM(exec);
164#endif
165 }
166
167 const SourceCode& source() { return m_source; }
168 intptr_t sourceID() const { return m_source.provider()->asID(); }
169 const UString& sourceURL() const { return m_source.provider()->url(); }
170 int lineNo() const { return m_firstLine; }
171 int lastLine() const { return m_lastLine; }
172
173 bool usesEval() const { return m_features & EvalFeature; }
174 bool usesArguments() const { return m_features & ArgumentsFeature; }
175 bool needsActivation() const { return m_features & (EvalFeature | ClosureFeature | WithFeature | CatchFeature); }
176
177 virtual PassOwnPtr<ExceptionInfo> reparseExceptionInfo(JSGlobalData*, ScopeChainNode*, CodeBlock*) = 0;
178
179 protected:
180 void recordParse(CodeFeatures features, int firstLine, int lastLine)
181 {
182 m_features = features;
183 m_firstLine = firstLine;
184 m_lastLine = lastLine;
185 }
186
187 SourceCode m_source;
188 CodeFeatures m_features;
189 int m_firstLine;
190 int m_lastLine;
191 };
192
193 class EvalExecutable : public ScriptExecutable {
194 public:
195
196 ~EvalExecutable();
197
198 JSObject* compile(ExecState* exec, ScopeChainNode* scopeChainNode)
199 {
200 JSObject* error = 0;
201 if (!m_evalCodeBlock)
202 error = compileInternal(exec, scopeChainNode);
203 ASSERT(!error == !!m_evalCodeBlock);
204 return error;
205 }
206
207 EvalCodeBlock& generatedBytecode()
208 {
209 ASSERT(m_evalCodeBlock);
210 return *m_evalCodeBlock;
211 }
212
213 static PassRefPtr<EvalExecutable> create(ExecState* exec, const SourceCode& source) { return adoptRef(new EvalExecutable(exec, source)); }
214
215#if ENABLE(JIT)
216 JITCode& generatedJITCode()
217 {
218 return generatedJITCodeForCall();
219 }
220#endif
221
222 private:
223 EvalExecutable(ExecState*, const SourceCode&);
224
225 JSObject* compileInternal(ExecState*, ScopeChainNode*);
226
227 virtual PassOwnPtr<ExceptionInfo> reparseExceptionInfo(JSGlobalData*, ScopeChainNode*, CodeBlock*);
228
229 OwnPtr<EvalCodeBlock> m_evalCodeBlock;
230 };
231
232 class ProgramExecutable : public ScriptExecutable {
233 public:
234 static PassRefPtr<ProgramExecutable> create(ExecState* exec, const SourceCode& source)
235 {
236 return adoptRef(new ProgramExecutable(exec, source));
237 }
238
239 ~ProgramExecutable();
240
241 JSObject* compile(ExecState* exec, ScopeChainNode* scopeChainNode)
242 {
243 JSObject* error = 0;
244 if (!m_programCodeBlock)
245 error = compileInternal(exec, scopeChainNode);
246 ASSERT(!error == !!m_programCodeBlock);
247 return error;
248 }
249
250 ProgramCodeBlock& generatedBytecode()
251 {
252 ASSERT(m_programCodeBlock);
253 return *m_programCodeBlock;
254 }
255
256 JSObject* checkSyntax(ExecState*);
257
258#if ENABLE(JIT)
259 JITCode& generatedJITCode()
260 {
261 return generatedJITCodeForCall();
262 }
263#endif
264
265 private:
266 ProgramExecutable(ExecState*, const SourceCode&);
267
268 JSObject* compileInternal(ExecState*, ScopeChainNode*);
269
270 virtual PassOwnPtr<ExceptionInfo> reparseExceptionInfo(JSGlobalData*, ScopeChainNode*, CodeBlock*);
271
272 OwnPtr<ProgramCodeBlock> m_programCodeBlock;
273 };
274
275 class FunctionExecutable : public ScriptExecutable {
276 friend class JIT;
277 public:
278 static PassRefPtr<FunctionExecutable> create(ExecState* exec, const Identifier& name, const SourceCode& source, bool forceUsesArguments, FunctionParameters* parameters, int firstLine, int lastLine)
279 {
280 return adoptRef(new FunctionExecutable(exec, name, source, forceUsesArguments, parameters, firstLine, lastLine));
281 }
282
283 static PassRefPtr<FunctionExecutable> create(JSGlobalData* globalData, const Identifier& name, const SourceCode& source, bool forceUsesArguments, FunctionParameters* parameters, int firstLine, int lastLine)
284 {
285 return adoptRef(new FunctionExecutable(globalData, name, source, forceUsesArguments, parameters, firstLine, lastLine));
286 }
287
288 ~FunctionExecutable();
289
290 JSFunction* make(ExecState* exec, ScopeChainNode* scopeChain)
291 {
292 return new (exec) JSFunction(exec, this, scopeChain);
293 }
294
295 // Returns either call or construct bytecode. This can be appropriate
296 // for answering questions that that don't vary between call and construct --
297 // for example, argumentsRegister().
298 FunctionCodeBlock& generatedBytecode()
299 {
300 if (m_codeBlockForCall)
301 return *m_codeBlockForCall;
302 ASSERT(m_codeBlockForConstruct);
303 return *m_codeBlockForConstruct;
304 }
305
306 JSObject* compileForCall(ExecState* exec, ScopeChainNode* scopeChainNode)
307 {
308 JSObject* error = 0;
309 if (!m_codeBlockForCall)
310 error = compileForCallInternal(exec, scopeChainNode);
311 ASSERT(!error == !!m_codeBlockForCall);
312 return error;
313 }
314
315 bool isGeneratedForCall() const
316 {
317 return m_codeBlockForCall;
318 }
319
320 FunctionCodeBlock& generatedBytecodeForCall()
321 {
322 ASSERT(m_codeBlockForCall);
323 return *m_codeBlockForCall;
324 }
325
326 JSObject* compileForConstruct(ExecState* exec, ScopeChainNode* scopeChainNode)
327 {
328 JSObject* error = 0;
329 if (!m_codeBlockForConstruct)
330 error = compileForConstructInternal(exec, scopeChainNode);
331 ASSERT(!error == !!m_codeBlockForConstruct);
332 return error;
333 }
334
335 bool isGeneratedForConstruct() const
336 {
337 return m_codeBlockForConstruct;
338 }
339
340 FunctionCodeBlock& generatedBytecodeForConstruct()
341 {
342 ASSERT(m_codeBlockForConstruct);
343 return *m_codeBlockForConstruct;
344 }
345
346 const Identifier& name() { return m_name; }
347 size_t parameterCount() const { return m_parameters->size(); }
348 unsigned variableCount() const { return m_numVariables; }
349 UString paramString() const;
350 SharedSymbolTable* symbolTable() const { return m_symbolTable; }
351
352 void recompile(ExecState*);
353 void markAggregate(MarkStack&);
354 static PassRefPtr<FunctionExecutable> fromGlobalCode(const Identifier&, ExecState*, Debugger*, const SourceCode&, JSObject** exception);
355
356 private:
357 FunctionExecutable(JSGlobalData*, const Identifier& name, const SourceCode&, bool forceUsesArguments, FunctionParameters*, int firstLine, int lastLine);
358 FunctionExecutable(ExecState*, const Identifier& name, const SourceCode&, bool forceUsesArguments, FunctionParameters*, int firstLine, int lastLine);
359
360 JSObject* compileForCallInternal(ExecState*, ScopeChainNode*);
361 JSObject* compileForConstructInternal(ExecState*, ScopeChainNode*);
362
363 virtual PassOwnPtr<ExceptionInfo> reparseExceptionInfo(JSGlobalData*, ScopeChainNode*, CodeBlock*);
364
365 unsigned m_numVariables : 31;
366 bool m_forceUsesArguments : 1;
367
368 RefPtr<FunctionParameters> m_parameters;
369 OwnPtr<FunctionCodeBlock> m_codeBlockForCall;
370 OwnPtr<FunctionCodeBlock> m_codeBlockForConstruct;
371 Identifier m_name;
372 SharedSymbolTable* m_symbolTable;
373
374#if ENABLE(JIT)
375 public:
376 MacroAssemblerCodePtr generatedJITCodeForCallWithArityCheck()
377 {
378 ASSERT(m_jitCodeForCall);
379 ASSERT(m_jitCodeForCallWithArityCheck);
380 return m_jitCodeForCallWithArityCheck;
381 }
382
383 MacroAssemblerCodePtr generatedJITCodeForConstructWithArityCheck()
384 {
385 ASSERT(m_jitCodeForConstruct);
386 ASSERT(m_jitCodeForConstructWithArityCheck);
387 return m_jitCodeForConstructWithArityCheck;
388 }
389#endif
390 };
391
392 inline FunctionExecutable* JSFunction::jsExecutable() const
393 {
394 ASSERT(!isHostFunctionNonInline());
395 return static_cast<FunctionExecutable*>(m_executable.get());
396 }
397
398 inline bool JSFunction::isHostFunction() const
399 {
400 ASSERT(m_executable);
401 return m_executable->isHostFunction();
402 }
403
404#if ENABLE(JIT)
405 inline NativeFunction JSFunction::nativeFunction()
406 {
407 ASSERT(isHostFunction());
408 return static_cast<NativeExecutable*>(m_executable.get())->function();
409 }
410#endif
411}
412
413#endif
Note: See TracBrowser for help on using the repository browser.