Don't use malloc / destructors for activation objects
[WebKit-https.git] / Source / JavaScriptCore / runtime / Executable.h
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 "CodeSpecializationKind.h"
31 #include "JSFunction.h"
32 #include "Interpreter.h"
33 #include "Nodes.h"
34 #include "SamplingTool.h"
35 #include <wtf/PassOwnPtr.h>
36
37 namespace JSC {
38
39     class CodeBlock;
40     class Debugger;
41     class EvalCodeBlock;
42     class FunctionCodeBlock;
43     class LLIntOffsetsExtractor;
44     class ProgramCodeBlock;
45     class ScopeChainNode;
46     
47     enum CompilationKind { FirstCompilation, OptimizingCompilation };
48
49     inline bool isCall(CodeSpecializationKind kind)
50     {
51         if (kind == CodeForCall)
52             return true;
53         ASSERT(kind == CodeForConstruct);
54         return false;
55     }
56
57     class ExecutableBase : public JSCell, public DoublyLinkedListNode<ExecutableBase> {
58         friend class WTF::DoublyLinkedListNode<ExecutableBase>;
59         friend class JIT;
60
61     protected:
62         static const int NUM_PARAMETERS_IS_HOST = 0;
63         static const int NUM_PARAMETERS_NOT_COMPILED = -1;
64
65         ExecutableBase(JSGlobalData& globalData, Structure* structure, int numParameters)
66             : JSCell(globalData, structure)
67             , m_numParametersForCall(numParameters)
68             , m_numParametersForConstruct(numParameters)
69         {
70         }
71
72         void finishCreation(JSGlobalData& globalData)
73         {
74             Base::finishCreation(globalData);
75         }
76
77     public:
78         typedef JSCell Base;
79
80 #if ENABLE(JIT)
81         static void destroy(JSCell*);
82 #endif
83
84         bool isFunctionExecutable()
85         {
86             return structure()->typeInfo().type() == FunctionExecutableType;
87         }
88
89         bool isHostFunction() const
90         {
91             ASSERT((m_numParametersForCall == NUM_PARAMETERS_IS_HOST) == (m_numParametersForConstruct == NUM_PARAMETERS_IS_HOST));
92             return m_numParametersForCall == NUM_PARAMETERS_IS_HOST;
93         }
94
95         static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue proto) { return Structure::create(globalData, globalObject, proto, TypeInfo(CompoundType, StructureFlags), &s_info); }
96         
97         void clearCode();
98
99         static JS_EXPORTDATA const ClassInfo s_info;
100
101     protected:
102         static const unsigned StructureFlags = 0;
103         int m_numParametersForCall;
104         int m_numParametersForConstruct;
105
106     public:
107         static void clearCodeVirtual(ExecutableBase*);
108
109 #if ENABLE(JIT)
110         JITCode& generatedJITCodeForCall()
111         {
112             ASSERT(m_jitCodeForCall);
113             return m_jitCodeForCall;
114         }
115
116         JITCode& generatedJITCodeForConstruct()
117         {
118             ASSERT(m_jitCodeForConstruct);
119             return m_jitCodeForConstruct;
120         }
121         
122         JITCode& generatedJITCodeFor(CodeSpecializationKind kind)
123         {
124             if (kind == CodeForCall)
125                 return generatedJITCodeForCall();
126             ASSERT(kind == CodeForConstruct);
127             return generatedJITCodeForConstruct();
128         }
129
130         MacroAssemblerCodePtr generatedJITCodeForCallWithArityCheck()
131         {
132             ASSERT(m_jitCodeForCall);
133             ASSERT(m_jitCodeForCallWithArityCheck);
134             return m_jitCodeForCallWithArityCheck;
135         }
136
137         MacroAssemblerCodePtr generatedJITCodeForConstructWithArityCheck()
138         {
139             ASSERT(m_jitCodeForConstruct);
140             ASSERT(m_jitCodeForConstructWithArityCheck);
141             return m_jitCodeForConstructWithArityCheck;
142         }
143         
144         MacroAssemblerCodePtr generatedJITCodeWithArityCheckFor(CodeSpecializationKind kind)
145         {
146             if (kind == CodeForCall)
147                 return generatedJITCodeForCallWithArityCheck();
148             ASSERT(kind == CodeForConstruct);
149             return generatedJITCodeForConstructWithArityCheck();
150         }
151         
152         bool hasJITCodeForCall() const
153         {
154             return m_numParametersForCall >= 0;
155         }
156         
157         bool hasJITCodeForConstruct() const
158         {
159             return m_numParametersForConstruct >= 0;
160         }
161         
162         bool hasJITCodeFor(CodeSpecializationKind kind) const
163         {
164             if (kind == CodeForCall)
165                 return hasJITCodeForCall();
166             ASSERT(kind == CodeForConstruct);
167             return hasJITCodeForConstruct();
168         }
169
170         // Intrinsics are only for calls, currently.
171         Intrinsic intrinsic() const;
172         
173         Intrinsic intrinsicFor(CodeSpecializationKind kind) const
174         {
175             if (isCall(kind))
176                 return intrinsic();
177             return NoIntrinsic;
178         }
179         
180         static ptrdiff_t offsetOfJITCodeFor(CodeSpecializationKind kind)
181         {
182             if (kind == CodeForCall)
183                 return OBJECT_OFFSETOF(ExecutableBase, m_jitCodeForCall);
184             ASSERT(kind == CodeForConstruct);
185             return OBJECT_OFFSETOF(ExecutableBase, m_jitCodeForConstruct);
186         }
187         
188         static ptrdiff_t offsetOfJITCodeWithArityCheckFor(CodeSpecializationKind kind)
189         {
190             if (kind == CodeForCall)
191                 return OBJECT_OFFSETOF(ExecutableBase, m_jitCodeForCallWithArityCheck);
192             ASSERT(kind == CodeForConstruct);
193             return OBJECT_OFFSETOF(ExecutableBase, m_jitCodeForConstructWithArityCheck);
194         }
195         
196         static ptrdiff_t offsetOfNumParametersFor(CodeSpecializationKind kind)
197         {
198             if (kind == CodeForCall)
199                 return OBJECT_OFFSETOF(ExecutableBase, m_numParametersForCall);
200             ASSERT(kind == CodeForConstruct);
201             return OBJECT_OFFSETOF(ExecutableBase, m_numParametersForConstruct);
202         }
203 #endif
204
205     protected:
206         ExecutableBase* m_prev;
207         ExecutableBase* m_next;
208
209 #if ENABLE(JIT)
210         JITCode m_jitCodeForCall;
211         JITCode m_jitCodeForConstruct;
212         MacroAssemblerCodePtr m_jitCodeForCallWithArityCheck;
213         MacroAssemblerCodePtr m_jitCodeForConstructWithArityCheck;
214 #endif
215     };
216
217     class NativeExecutable : public ExecutableBase {
218         friend class JIT;
219         friend class LLIntOffsetsExtractor;
220     public:
221         typedef ExecutableBase Base;
222
223 #if ENABLE(JIT)
224         static NativeExecutable* create(JSGlobalData& globalData, MacroAssemblerCodeRef callThunk, NativeFunction function, MacroAssemblerCodeRef constructThunk, NativeFunction constructor, Intrinsic intrinsic)
225         {
226             ASSERT(!globalData.interpreter->classicEnabled());
227             NativeExecutable* executable;
228             if (!callThunk) {
229                 executable = new (NotNull, allocateCell<NativeExecutable>(globalData.heap)) NativeExecutable(globalData, function, constructor);
230                 executable->finishCreation(globalData, JITCode(), JITCode(), intrinsic);
231             } else {
232                 executable = new (NotNull, allocateCell<NativeExecutable>(globalData.heap)) NativeExecutable(globalData, function, constructor);
233                 executable->finishCreation(globalData, JITCode::HostFunction(callThunk), JITCode::HostFunction(constructThunk), intrinsic);
234             }
235             return executable;
236         }
237 #endif
238
239 #if ENABLE(CLASSIC_INTERPRETER)
240         static NativeExecutable* create(JSGlobalData& globalData, NativeFunction function, NativeFunction constructor)
241         {
242             ASSERT(!globalData.canUseJIT());
243             NativeExecutable* executable = new (NotNull, allocateCell<NativeExecutable>(globalData.heap)) NativeExecutable(globalData, function, constructor);
244             executable->finishCreation(globalData);
245             return executable;
246         }
247 #endif
248
249 #if ENABLE(JIT)
250         static void destroy(JSCell*);
251 #endif
252
253         NativeFunction function() { return m_function; }
254         NativeFunction constructor() { return m_constructor; }
255
256         static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue proto) { return Structure::create(globalData, globalObject, proto, TypeInfo(LeafType, StructureFlags), &s_info); }
257         
258         static const ClassInfo s_info;
259
260         Intrinsic intrinsic() const;
261
262     protected:
263 #if ENABLE(JIT)
264         void finishCreation(JSGlobalData& globalData, JITCode callThunk, JITCode constructThunk, Intrinsic intrinsic)
265         {
266             ASSERT(!globalData.interpreter->classicEnabled());
267             Base::finishCreation(globalData);
268             m_jitCodeForCall = callThunk;
269             m_jitCodeForConstruct = constructThunk;
270             m_jitCodeForCallWithArityCheck = callThunk.addressForCall();
271             m_jitCodeForConstructWithArityCheck = constructThunk.addressForCall();
272             m_intrinsic = intrinsic;
273         }
274 #endif
275
276 #if ENABLE(CLASSIC_INTERPRETER)
277         void finishCreation(JSGlobalData& globalData)
278         {
279             ASSERT(!globalData.canUseJIT());
280             Base::finishCreation(globalData);
281             m_intrinsic = NoIntrinsic;
282         }
283 #endif
284
285     private:
286         NativeExecutable(JSGlobalData& globalData, NativeFunction function, NativeFunction constructor)
287             : ExecutableBase(globalData, globalData.nativeExecutableStructure.get(), NUM_PARAMETERS_IS_HOST)
288             , m_function(function)
289             , m_constructor(constructor)
290         {
291         }
292
293         NativeFunction m_function;
294         NativeFunction m_constructor;
295         
296         Intrinsic m_intrinsic;
297     };
298
299     class ScriptExecutable : public ExecutableBase {
300     public:
301         typedef ExecutableBase Base;
302
303         ScriptExecutable(Structure* structure, JSGlobalData& globalData, const SourceCode& source, bool isInStrictContext)
304             : ExecutableBase(globalData, structure, NUM_PARAMETERS_NOT_COMPILED)
305             , m_source(source)
306             , m_features(isInStrictContext ? StrictModeFeature : 0)
307         {
308         }
309
310         ScriptExecutable(Structure* structure, ExecState* exec, const SourceCode& source, bool isInStrictContext)
311             : ExecutableBase(exec->globalData(), structure, NUM_PARAMETERS_NOT_COMPILED)
312             , m_source(source)
313             , m_features(isInStrictContext ? StrictModeFeature : 0)
314         {
315         }
316
317 #if ENABLE(JIT)
318         static void destroy(JSCell*);
319 #endif
320
321         const SourceCode& source() { return m_source; }
322         intptr_t sourceID() const { return m_source.providerID(); }
323         const UString& sourceURL() const { return m_source.provider()->url(); }
324         int lineNo() const { return m_firstLine; }
325         int lastLine() const { return m_lastLine; }
326
327         bool usesEval() const { return m_features & EvalFeature; }
328         bool usesArguments() const { return m_features & ArgumentsFeature; }
329         bool needsActivation() const { return m_hasCapturedVariables || m_features & (EvalFeature | WithFeature | CatchFeature); }
330         bool isStrictMode() const { return m_features & StrictModeFeature; }
331
332         void unlinkCalls();
333         
334         static const ClassInfo s_info;
335
336     protected:
337         void finishCreation(JSGlobalData& globalData)
338         {
339             Base::finishCreation(globalData);
340             globalData.heap.addCompiledCode(this); // Balanced by Heap::deleteUnmarkedCompiledCode().
341
342 #if ENABLE(CODEBLOCK_SAMPLING)
343             if (SamplingTool* sampler = globalData.interpreter->sampler())
344                 sampler->notifyOfScope(globalData, this);
345 #endif
346         }
347
348         void recordParse(CodeFeatures features, bool hasCapturedVariables, int firstLine, int lastLine)
349         {
350             m_features = features;
351             m_hasCapturedVariables = hasCapturedVariables;
352             m_firstLine = firstLine;
353             m_lastLine = lastLine;
354         }
355
356         SourceCode m_source;
357         CodeFeatures m_features;
358         bool m_hasCapturedVariables;
359         int m_firstLine;
360         int m_lastLine;
361     };
362
363     class EvalExecutable : public ScriptExecutable {
364         friend class LLIntOffsetsExtractor;
365     public:
366         typedef ScriptExecutable Base;
367
368         static void destroy(JSCell*);
369
370         JSObject* compile(ExecState* exec, ScopeChainNode* scopeChainNode)
371         {
372             ASSERT(exec->globalData().dynamicGlobalObject);
373             JSObject* error = 0;
374             if (!m_evalCodeBlock)
375                 error = compileInternal(exec, scopeChainNode, JITCode::bottomTierJIT());
376             ASSERT(!error == !!m_evalCodeBlock);
377             return error;
378         }
379         
380         JSObject* compileOptimized(ExecState*, ScopeChainNode*, unsigned bytecodeIndex);
381         
382 #if ENABLE(JIT)
383         void jettisonOptimizedCode(JSGlobalData&);
384         bool jitCompile(ExecState*);
385 #endif
386
387         EvalCodeBlock& generatedBytecode()
388         {
389             ASSERT(m_evalCodeBlock);
390             return *m_evalCodeBlock;
391         }
392
393         static EvalExecutable* create(ExecState* exec, const SourceCode& source, bool isInStrictContext) 
394         {
395             EvalExecutable* executable = new (NotNull, allocateCell<EvalExecutable>(*exec->heap())) EvalExecutable(exec, source, isInStrictContext);
396             executable->finishCreation(exec->globalData());
397             return executable;
398         }
399
400 #if ENABLE(JIT)
401         JITCode& generatedJITCode()
402         {
403             return generatedJITCodeForCall();
404         }
405 #endif
406         static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue proto)
407         {
408             return Structure::create(globalData, globalObject, proto, TypeInfo(EvalExecutableType, StructureFlags), &s_info);
409         }
410         
411         static const ClassInfo s_info;
412
413         void unlinkCalls();
414
415         void clearCode();
416
417     private:
418         static const unsigned StructureFlags = OverridesVisitChildren | ScriptExecutable::StructureFlags;
419         EvalExecutable(ExecState*, const SourceCode&, bool);
420
421         JSObject* compileInternal(ExecState*, ScopeChainNode*, JITCode::JITType, unsigned bytecodeIndex = UINT_MAX);
422         static void visitChildren(JSCell*, SlotVisitor&);
423
424         OwnPtr<EvalCodeBlock> m_evalCodeBlock;
425     };
426
427     class ProgramExecutable : public ScriptExecutable {
428         friend class LLIntOffsetsExtractor;
429     public:
430         typedef ScriptExecutable Base;
431
432         static ProgramExecutable* create(ExecState* exec, const SourceCode& source)
433         {
434             ProgramExecutable* executable = new (NotNull, allocateCell<ProgramExecutable>(*exec->heap())) ProgramExecutable(exec, source);
435             executable->finishCreation(exec->globalData());
436             return executable;
437         }
438
439         static void destroy(JSCell*);
440
441         JSObject* compile(ExecState* exec, ScopeChainNode* scopeChainNode)
442         {
443             ASSERT(exec->globalData().dynamicGlobalObject);
444             JSObject* error = 0;
445             if (!m_programCodeBlock)
446                 error = compileInternal(exec, scopeChainNode, JITCode::bottomTierJIT());
447             ASSERT(!error == !!m_programCodeBlock);
448             return error;
449         }
450
451         JSObject* compileOptimized(ExecState*, ScopeChainNode*, unsigned bytecodeIndex);
452         
453 #if ENABLE(JIT)
454         void jettisonOptimizedCode(JSGlobalData&);
455         bool jitCompile(ExecState*);
456 #endif
457
458         ProgramCodeBlock& generatedBytecode()
459         {
460             ASSERT(m_programCodeBlock);
461             return *m_programCodeBlock;
462         }
463
464         JSObject* checkSyntax(ExecState*);
465
466 #if ENABLE(JIT)
467         JITCode& generatedJITCode()
468         {
469             return generatedJITCodeForCall();
470         }
471 #endif
472         
473         static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue proto)
474         {
475             return Structure::create(globalData, globalObject, proto, TypeInfo(ProgramExecutableType, StructureFlags), &s_info);
476         }
477         
478         static const ClassInfo s_info;
479         
480         void unlinkCalls();
481
482         void clearCode();
483
484     private:
485         static const unsigned StructureFlags = OverridesVisitChildren | ScriptExecutable::StructureFlags;
486         ProgramExecutable(ExecState*, const SourceCode&);
487
488         JSObject* compileInternal(ExecState*, ScopeChainNode*, JITCode::JITType, unsigned bytecodeIndex = UINT_MAX);
489         static void visitChildren(JSCell*, SlotVisitor&);
490
491         OwnPtr<ProgramCodeBlock> m_programCodeBlock;
492     };
493
494     class FunctionExecutable : public ScriptExecutable {
495         friend class JIT;
496         friend class LLIntOffsetsExtractor;
497     public:
498         typedef ScriptExecutable Base;
499
500         static FunctionExecutable* create(ExecState* exec, const Identifier& name, const Identifier& inferredName, const SourceCode& source, bool forceUsesArguments, FunctionParameters* parameters, bool isInStrictContext, int firstLine, int lastLine)
501         {
502             FunctionExecutable* executable = new (NotNull, allocateCell<FunctionExecutable>(*exec->heap())) FunctionExecutable(exec, name, inferredName, source, forceUsesArguments, parameters, isInStrictContext);
503             executable->finishCreation(exec->globalData(), name, firstLine, lastLine);
504             return executable;
505         }
506
507         static FunctionExecutable* create(JSGlobalData& globalData, const Identifier& name, const Identifier& inferredName, const SourceCode& source, bool forceUsesArguments, FunctionParameters* parameters, bool isInStrictContext, int firstLine, int lastLine)
508         {
509             FunctionExecutable* executable = new (NotNull, allocateCell<FunctionExecutable>(globalData.heap)) FunctionExecutable(globalData, name, inferredName, source, forceUsesArguments, parameters, isInStrictContext);
510             executable->finishCreation(globalData, name, firstLine, lastLine);
511             return executable;
512         }
513
514         static void destroy(JSCell*);
515
516         JSFunction* make(ExecState* exec, ScopeChainNode* scopeChain)
517         {
518             return JSFunction::create(exec, this, scopeChain);
519         }
520         
521         // Returns either call or construct bytecode. This can be appropriate
522         // for answering questions that that don't vary between call and construct --
523         // for example, argumentsRegister().
524         FunctionCodeBlock& generatedBytecode()
525         {
526             if (m_codeBlockForCall)
527                 return *m_codeBlockForCall;
528             ASSERT(m_codeBlockForConstruct);
529             return *m_codeBlockForConstruct;
530         }
531         
532         FunctionCodeBlock* codeBlockWithBytecodeFor(CodeSpecializationKind);
533         
534         PassOwnPtr<FunctionCodeBlock> produceCodeBlockFor(ScopeChainNode*, CompilationKind, CodeSpecializationKind, JSObject*& exception);
535
536         JSObject* compileForCall(ExecState* exec, ScopeChainNode* scopeChainNode)
537         {
538             ASSERT(exec->globalData().dynamicGlobalObject);
539             JSObject* error = 0;
540             if (!m_codeBlockForCall)
541                 error = compileForCallInternal(exec, scopeChainNode, JITCode::bottomTierJIT());
542             ASSERT(!error == !!m_codeBlockForCall);
543             return error;
544         }
545
546         JSObject* compileOptimizedForCall(ExecState*, ScopeChainNode*, unsigned bytecodeIndex);
547         
548 #if ENABLE(JIT)
549         void jettisonOptimizedCodeForCall(JSGlobalData&);
550         bool jitCompileForCall(ExecState*);
551 #endif
552
553         bool isGeneratedForCall() const
554         {
555             return m_codeBlockForCall;
556         }
557
558         FunctionCodeBlock& generatedBytecodeForCall()
559         {
560             ASSERT(m_codeBlockForCall);
561             return *m_codeBlockForCall;
562         }
563
564         JSObject* compileForConstruct(ExecState* exec, ScopeChainNode* scopeChainNode)
565         {
566             ASSERT(exec->globalData().dynamicGlobalObject);
567             JSObject* error = 0;
568             if (!m_codeBlockForConstruct)
569                 error = compileForConstructInternal(exec, scopeChainNode, JITCode::bottomTierJIT());
570             ASSERT(!error == !!m_codeBlockForConstruct);
571             return error;
572         }
573
574         JSObject* compileOptimizedForConstruct(ExecState*, ScopeChainNode*, unsigned bytecodeIndex);
575         
576 #if ENABLE(JIT)
577         void jettisonOptimizedCodeForConstruct(JSGlobalData&);
578         bool jitCompileForConstruct(ExecState*);
579 #endif
580
581         bool isGeneratedForConstruct() const
582         {
583             return m_codeBlockForConstruct;
584         }
585
586         FunctionCodeBlock& generatedBytecodeForConstruct()
587         {
588             ASSERT(m_codeBlockForConstruct);
589             return *m_codeBlockForConstruct;
590         }
591         
592         JSObject* compileFor(ExecState* exec, ScopeChainNode* scopeChainNode, CodeSpecializationKind kind)
593         {
594             ASSERT(exec->callee());
595             ASSERT(exec->callee()->inherits(&JSFunction::s_info));
596             ASSERT(jsCast<JSFunction*>(exec->callee())->jsExecutable() == this);
597
598             if (kind == CodeForCall)
599                 return compileForCall(exec, scopeChainNode);
600             ASSERT(kind == CodeForConstruct);
601             return compileForConstruct(exec, scopeChainNode);
602         }
603         
604         JSObject* compileOptimizedFor(ExecState* exec, ScopeChainNode* scopeChainNode, unsigned bytecodeIndex, CodeSpecializationKind kind)
605         {
606             ASSERT(exec->callee());
607             ASSERT(exec->callee()->inherits(&JSFunction::s_info));
608             ASSERT(jsCast<JSFunction*>(exec->callee())->jsExecutable() == this);
609             
610             if (kind == CodeForCall)
611                 return compileOptimizedForCall(exec, scopeChainNode, bytecodeIndex);
612             ASSERT(kind == CodeForConstruct);
613             return compileOptimizedForConstruct(exec, scopeChainNode, bytecodeIndex);
614         }
615         
616 #if ENABLE(JIT)
617         void jettisonOptimizedCodeFor(JSGlobalData& globalData, CodeSpecializationKind kind)
618         {
619             if (kind == CodeForCall) 
620                 jettisonOptimizedCodeForCall(globalData);
621             else {
622                 ASSERT(kind == CodeForConstruct);
623                 jettisonOptimizedCodeForConstruct(globalData);
624             }
625         }
626         
627         bool jitCompileFor(ExecState* exec, CodeSpecializationKind kind)
628         {
629             if (kind == CodeForCall)
630                 return jitCompileForCall(exec);
631             ASSERT(kind == CodeForConstruct);
632             return jitCompileForConstruct(exec);
633         }
634 #endif
635         
636         bool isGeneratedFor(CodeSpecializationKind kind)
637         {
638             if (kind == CodeForCall)
639                 return isGeneratedForCall();
640             ASSERT(kind == CodeForConstruct);
641             return isGeneratedForConstruct();
642         }
643         
644         FunctionCodeBlock& generatedBytecodeFor(CodeSpecializationKind kind)
645         {
646             if (kind == CodeForCall)
647                 return generatedBytecodeForCall();
648             ASSERT(kind == CodeForConstruct);
649             return generatedBytecodeForConstruct();
650         }
651
652         FunctionCodeBlock* baselineCodeBlockFor(CodeSpecializationKind);
653         
654         FunctionCodeBlock* profiledCodeBlockFor(CodeSpecializationKind kind)
655         {
656             return baselineCodeBlockFor(kind);
657         }
658         
659         const Identifier& name() { return m_name; }
660         const Identifier& inferredName() { return m_inferredName; }
661         JSString* nameValue() const { return m_nameValue.get(); }
662         size_t parameterCount() const { return m_parameters->size(); } // Excluding 'this'!
663         unsigned capturedVariableCount() const { return m_numCapturedVariables; }
664         UString paramString() const;
665         SharedSymbolTable* symbolTable() const { return m_symbolTable.get(); }
666
667         void clearCodeIfNotCompiling();
668         static void visitChildren(JSCell*, SlotVisitor&);
669         static FunctionExecutable* fromGlobalCode(const Identifier&, ExecState*, Debugger*, const SourceCode&, JSObject** exception);
670         static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue proto)
671         {
672             return Structure::create(globalData, globalObject, proto, TypeInfo(FunctionExecutableType, StructureFlags), &s_info);
673         }
674         
675         static const ClassInfo s_info;
676         
677         void unlinkCalls();
678
679         void clearCode();
680
681     protected:
682         void finishCreation(JSGlobalData& globalData, const Identifier& name, int firstLine, int lastLine)
683         {
684             Base::finishCreation(globalData);
685             m_firstLine = firstLine;
686             m_lastLine = lastLine;
687             m_nameValue.set(globalData, this, jsString(&globalData, name.ustring()));
688         }
689
690     private:
691         FunctionExecutable(JSGlobalData&, const Identifier& name, const Identifier& inferredName, const SourceCode&, bool forceUsesArguments, FunctionParameters*, bool);
692         FunctionExecutable(ExecState*, const Identifier& name, const Identifier& inferredName, const SourceCode&, bool forceUsesArguments, FunctionParameters*, bool);
693
694         JSObject* compileForCallInternal(ExecState*, ScopeChainNode*, JITCode::JITType, unsigned bytecodeIndex = UINT_MAX);
695         JSObject* compileForConstructInternal(ExecState*, ScopeChainNode*, JITCode::JITType, unsigned bytecodeIndex = UINT_MAX);
696         
697         OwnPtr<FunctionCodeBlock>& codeBlockFor(CodeSpecializationKind kind)
698         {
699             if (kind == CodeForCall)
700                 return m_codeBlockForCall;
701             ASSERT(kind == CodeForConstruct);
702             return m_codeBlockForConstruct;
703         }
704  
705         bool isCompiling()
706         {
707 #if ENABLE(JIT)
708             if (!m_jitCodeForCall && m_codeBlockForCall)
709                 return true;
710             if (!m_jitCodeForConstruct && m_codeBlockForConstruct)
711                 return true;
712 #endif
713             return false;
714         }
715
716         static const unsigned StructureFlags = OverridesVisitChildren | ScriptExecutable::StructureFlags;
717         unsigned m_numCapturedVariables : 31;
718         bool m_forceUsesArguments : 1;
719
720         RefPtr<FunctionParameters> m_parameters;
721         OwnPtr<FunctionCodeBlock> m_codeBlockForCall;
722         OwnPtr<FunctionCodeBlock> m_codeBlockForConstruct;
723         Identifier m_name;
724         Identifier m_inferredName;
725         WriteBarrier<JSString> m_nameValue;
726         WriteBarrier<SharedSymbolTable> m_symbolTable;
727     };
728
729     inline FunctionExecutable* JSFunction::jsExecutable() const
730     {
731         ASSERT(!isHostFunctionNonInline());
732         return static_cast<FunctionExecutable*>(m_executable.get());
733     }
734
735     inline bool JSFunction::isHostFunction() const
736     {
737         ASSERT(m_executable);
738         return m_executable->isHostFunction();
739     }
740
741     inline NativeFunction JSFunction::nativeFunction()
742     {
743         ASSERT(isHostFunction());
744         return static_cast<NativeExecutable*>(m_executable.get())->function();
745     }
746
747     inline NativeFunction JSFunction::nativeConstructor()
748     {
749         ASSERT(isHostFunction());
750         return static_cast<NativeExecutable*>(m_executable.get())->constructor();
751     }
752
753     inline bool isHostFunction(JSValue value, NativeFunction nativeFunction)
754     {
755         JSFunction* function = jsCast<JSFunction*>(getJSFunction(value));
756         if (!function || !function->isHostFunction())
757             return false;
758         return function->nativeFunction() == nativeFunction;
759     }
760
761     inline void ExecutableBase::clearCodeVirtual(ExecutableBase* executable)
762     {
763         switch (executable->structure()->typeInfo().type()) {
764         case EvalExecutableType:
765             return jsCast<EvalExecutable*>(executable)->clearCode();
766         case ProgramExecutableType:
767             return jsCast<ProgramExecutable*>(executable)->clearCode();
768         case FunctionExecutableType:
769             return jsCast<FunctionExecutable*>(executable)->clearCode();
770         default:
771             return jsCast<NativeExecutable*>(executable)->clearCode();
772         }
773     }
774
775     inline void ScriptExecutable::unlinkCalls()
776     {
777         switch (structure()->typeInfo().type()) {
778         case EvalExecutableType:
779             return jsCast<EvalExecutable*>(this)->unlinkCalls();
780         case ProgramExecutableType:
781             return jsCast<ProgramExecutable*>(this)->unlinkCalls();
782         case FunctionExecutableType:
783             return jsCast<FunctionExecutable*>(this)->unlinkCalls();
784         default:
785             ASSERT_NOT_REACHED();
786         }
787     }
788
789 }
790
791 #endif