Unreviewed. Build fix for !ENABLE(JIT) after r119844 and r119925.
[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 #endif
180
181     protected:
182         ExecutableBase* m_prev;
183         ExecutableBase* m_next;
184
185 #if ENABLE(JIT)
186         JITCode m_jitCodeForCall;
187         JITCode m_jitCodeForConstruct;
188         MacroAssemblerCodePtr m_jitCodeForCallWithArityCheck;
189         MacroAssemblerCodePtr m_jitCodeForConstructWithArityCheck;
190 #endif
191     };
192
193     class NativeExecutable : public ExecutableBase {
194         friend class JIT;
195         friend class LLIntOffsetsExtractor;
196     public:
197         typedef ExecutableBase Base;
198
199 #if ENABLE(JIT)
200         static NativeExecutable* create(JSGlobalData& globalData, MacroAssemblerCodeRef callThunk, NativeFunction function, MacroAssemblerCodeRef constructThunk, NativeFunction constructor, Intrinsic intrinsic)
201         {
202             ASSERT(!globalData.interpreter->classicEnabled());
203             NativeExecutable* executable;
204             if (!callThunk) {
205                 executable = new (NotNull, allocateCell<NativeExecutable>(globalData.heap)) NativeExecutable(globalData, function, constructor);
206                 executable->finishCreation(globalData, JITCode(), JITCode(), intrinsic);
207             } else {
208                 executable = new (NotNull, allocateCell<NativeExecutable>(globalData.heap)) NativeExecutable(globalData, function, constructor);
209                 executable->finishCreation(globalData, JITCode::HostFunction(callThunk), JITCode::HostFunction(constructThunk), intrinsic);
210             }
211             return executable;
212         }
213 #endif
214
215 #if ENABLE(CLASSIC_INTERPRETER)
216         static NativeExecutable* create(JSGlobalData& globalData, NativeFunction function, NativeFunction constructor)
217         {
218             ASSERT(!globalData.canUseJIT());
219             NativeExecutable* executable = new (NotNull, allocateCell<NativeExecutable>(globalData.heap)) NativeExecutable(globalData, function, constructor);
220             executable->finishCreation(globalData);
221             return executable;
222         }
223 #endif
224
225 #if ENABLE(JIT)
226         static void destroy(JSCell*);
227 #endif
228
229         NativeFunction function() { return m_function; }
230         NativeFunction constructor() { return m_constructor; }
231
232         static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue proto) { return Structure::create(globalData, globalObject, proto, TypeInfo(LeafType, StructureFlags), &s_info); }
233         
234         static const ClassInfo s_info;
235
236         Intrinsic intrinsic() const;
237
238     protected:
239 #if ENABLE(JIT)
240         void finishCreation(JSGlobalData& globalData, JITCode callThunk, JITCode constructThunk, Intrinsic intrinsic)
241         {
242             ASSERT(!globalData.interpreter->classicEnabled());
243             Base::finishCreation(globalData);
244             m_jitCodeForCall = callThunk;
245             m_jitCodeForConstruct = constructThunk;
246             m_jitCodeForCallWithArityCheck = callThunk.addressForCall();
247             m_jitCodeForConstructWithArityCheck = constructThunk.addressForCall();
248             m_intrinsic = intrinsic;
249         }
250 #endif
251
252 #if ENABLE(CLASSIC_INTERPRETER)
253         void finishCreation(JSGlobalData& globalData)
254         {
255             ASSERT(!globalData.canUseJIT());
256             Base::finishCreation(globalData);
257             m_intrinsic = NoIntrinsic;
258         }
259 #endif
260
261     private:
262         NativeExecutable(JSGlobalData& globalData, NativeFunction function, NativeFunction constructor)
263             : ExecutableBase(globalData, globalData.nativeExecutableStructure.get(), NUM_PARAMETERS_IS_HOST)
264             , m_function(function)
265             , m_constructor(constructor)
266         {
267         }
268
269         NativeFunction m_function;
270         NativeFunction m_constructor;
271         
272         Intrinsic m_intrinsic;
273     };
274
275     class ScriptExecutable : public ExecutableBase {
276     public:
277         typedef ExecutableBase Base;
278
279         ScriptExecutable(Structure* structure, JSGlobalData& globalData, const SourceCode& source, bool isInStrictContext)
280             : ExecutableBase(globalData, structure, NUM_PARAMETERS_NOT_COMPILED)
281             , m_source(source)
282             , m_features(isInStrictContext ? StrictModeFeature : 0)
283         {
284         }
285
286         ScriptExecutable(Structure* structure, ExecState* exec, const SourceCode& source, bool isInStrictContext)
287             : ExecutableBase(exec->globalData(), structure, NUM_PARAMETERS_NOT_COMPILED)
288             , m_source(source)
289             , m_features(isInStrictContext ? StrictModeFeature : 0)
290         {
291         }
292
293 #if ENABLE(JIT)
294         static void destroy(JSCell*);
295 #endif
296
297         const SourceCode& source() { return m_source; }
298         intptr_t sourceID() const { return m_source.providerID(); }
299         const UString& sourceURL() const { return m_source.provider()->url(); }
300         int lineNo() const { return m_firstLine; }
301         int lastLine() const { return m_lastLine; }
302
303         bool usesEval() const { return m_features & EvalFeature; }
304         bool usesArguments() const { return m_features & ArgumentsFeature; }
305         bool needsActivation() const { return m_hasCapturedVariables || m_features & (EvalFeature | WithFeature | CatchFeature); }
306         bool isStrictMode() const { return m_features & StrictModeFeature; }
307
308         void unlinkCalls();
309         
310         static const ClassInfo s_info;
311
312     protected:
313         void finishCreation(JSGlobalData& globalData)
314         {
315             Base::finishCreation(globalData);
316             globalData.heap.addCompiledCode(this); // Balanced by Heap::deleteUnmarkedCompiledCode().
317
318 #if ENABLE(CODEBLOCK_SAMPLING)
319             if (SamplingTool* sampler = globalData.interpreter->sampler())
320                 sampler->notifyOfScope(globalData, this);
321 #endif
322         }
323
324         void recordParse(CodeFeatures features, bool hasCapturedVariables, int firstLine, int lastLine)
325         {
326             m_features = features;
327             m_hasCapturedVariables = hasCapturedVariables;
328             m_firstLine = firstLine;
329             m_lastLine = lastLine;
330         }
331
332         SourceCode m_source;
333         CodeFeatures m_features;
334         bool m_hasCapturedVariables;
335         int m_firstLine;
336         int m_lastLine;
337     };
338
339     class EvalExecutable : public ScriptExecutable {
340         friend class LLIntOffsetsExtractor;
341     public:
342         typedef ScriptExecutable Base;
343
344         static void destroy(JSCell*);
345
346         JSObject* compile(ExecState* exec, ScopeChainNode* scopeChainNode)
347         {
348             ASSERT(exec->globalData().dynamicGlobalObject);
349             JSObject* error = 0;
350             if (!m_evalCodeBlock)
351                 error = compileInternal(exec, scopeChainNode, JITCode::bottomTierJIT());
352             ASSERT(!error == !!m_evalCodeBlock);
353             return error;
354         }
355         
356         JSObject* compileOptimized(ExecState*, ScopeChainNode*);
357         
358 #if ENABLE(JIT)
359         void jettisonOptimizedCode(JSGlobalData&);
360         bool jitCompile(ExecState*);
361 #endif
362
363         EvalCodeBlock& generatedBytecode()
364         {
365             ASSERT(m_evalCodeBlock);
366             return *m_evalCodeBlock;
367         }
368
369         static EvalExecutable* create(ExecState* exec, const SourceCode& source, bool isInStrictContext) 
370         {
371             EvalExecutable* executable = new (NotNull, allocateCell<EvalExecutable>(*exec->heap())) EvalExecutable(exec, source, isInStrictContext);
372             executable->finishCreation(exec->globalData());
373             return executable;
374         }
375
376 #if ENABLE(JIT)
377         JITCode& generatedJITCode()
378         {
379             return generatedJITCodeForCall();
380         }
381 #endif
382         static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue proto)
383         {
384             return Structure::create(globalData, globalObject, proto, TypeInfo(EvalExecutableType, StructureFlags), &s_info);
385         }
386         
387         static const ClassInfo s_info;
388
389         void unlinkCalls();
390
391         void clearCode();
392
393     private:
394         static const unsigned StructureFlags = OverridesVisitChildren | ScriptExecutable::StructureFlags;
395         EvalExecutable(ExecState*, const SourceCode&, bool);
396
397         JSObject* compileInternal(ExecState*, ScopeChainNode*, JITCode::JITType);
398         static void visitChildren(JSCell*, SlotVisitor&);
399
400         OwnPtr<EvalCodeBlock> m_evalCodeBlock;
401     };
402
403     class ProgramExecutable : public ScriptExecutable {
404         friend class LLIntOffsetsExtractor;
405     public:
406         typedef ScriptExecutable Base;
407
408         static ProgramExecutable* create(ExecState* exec, const SourceCode& source)
409         {
410             ProgramExecutable* executable = new (NotNull, allocateCell<ProgramExecutable>(*exec->heap())) ProgramExecutable(exec, source);
411             executable->finishCreation(exec->globalData());
412             return executable;
413         }
414
415         static void destroy(JSCell*);
416
417         JSObject* compile(ExecState* exec, ScopeChainNode* scopeChainNode)
418         {
419             ASSERT(exec->globalData().dynamicGlobalObject);
420             JSObject* error = 0;
421             if (!m_programCodeBlock)
422                 error = compileInternal(exec, scopeChainNode, JITCode::bottomTierJIT());
423             ASSERT(!error == !!m_programCodeBlock);
424             return error;
425         }
426
427         JSObject* compileOptimized(ExecState*, ScopeChainNode*);
428         
429 #if ENABLE(JIT)
430         void jettisonOptimizedCode(JSGlobalData&);
431         bool jitCompile(ExecState*);
432 #endif
433
434         ProgramCodeBlock& generatedBytecode()
435         {
436             ASSERT(m_programCodeBlock);
437             return *m_programCodeBlock;
438         }
439
440         JSObject* checkSyntax(ExecState*);
441
442 #if ENABLE(JIT)
443         JITCode& generatedJITCode()
444         {
445             return generatedJITCodeForCall();
446         }
447 #endif
448         
449         static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue proto)
450         {
451             return Structure::create(globalData, globalObject, proto, TypeInfo(ProgramExecutableType, StructureFlags), &s_info);
452         }
453         
454         static const ClassInfo s_info;
455         
456         void unlinkCalls();
457
458         void clearCode();
459
460     private:
461         static const unsigned StructureFlags = OverridesVisitChildren | ScriptExecutable::StructureFlags;
462         ProgramExecutable(ExecState*, const SourceCode&);
463
464         JSObject* compileInternal(ExecState*, ScopeChainNode*, JITCode::JITType);
465         static void visitChildren(JSCell*, SlotVisitor&);
466
467         OwnPtr<ProgramCodeBlock> m_programCodeBlock;
468     };
469
470     class FunctionExecutable : public ScriptExecutable {
471         friend class JIT;
472         friend class LLIntOffsetsExtractor;
473     public:
474         typedef ScriptExecutable Base;
475
476         static FunctionExecutable* create(ExecState* exec, const Identifier& name, const Identifier& inferredName, const SourceCode& source, bool forceUsesArguments, FunctionParameters* parameters, bool isInStrictContext, int firstLine, int lastLine)
477         {
478             FunctionExecutable* executable = new (NotNull, allocateCell<FunctionExecutable>(*exec->heap())) FunctionExecutable(exec, name, inferredName, source, forceUsesArguments, parameters, isInStrictContext);
479             executable->finishCreation(exec->globalData(), name, firstLine, lastLine);
480             return executable;
481         }
482
483         static FunctionExecutable* create(JSGlobalData& globalData, const Identifier& name, const Identifier& inferredName, const SourceCode& source, bool forceUsesArguments, FunctionParameters* parameters, bool isInStrictContext, int firstLine, int lastLine)
484         {
485             FunctionExecutable* executable = new (NotNull, allocateCell<FunctionExecutable>(globalData.heap)) FunctionExecutable(globalData, name, inferredName, source, forceUsesArguments, parameters, isInStrictContext);
486             executable->finishCreation(globalData, name, firstLine, lastLine);
487             return executable;
488         }
489
490         static void destroy(JSCell*);
491
492         JSFunction* make(ExecState* exec, ScopeChainNode* scopeChain)
493         {
494             return JSFunction::create(exec, this, scopeChain);
495         }
496         
497         // Returns either call or construct bytecode. This can be appropriate
498         // for answering questions that that don't vary between call and construct --
499         // for example, argumentsRegister().
500         FunctionCodeBlock& generatedBytecode()
501         {
502             if (m_codeBlockForCall)
503                 return *m_codeBlockForCall;
504             ASSERT(m_codeBlockForConstruct);
505             return *m_codeBlockForConstruct;
506         }
507         
508         FunctionCodeBlock* codeBlockWithBytecodeFor(CodeSpecializationKind);
509         
510         PassOwnPtr<FunctionCodeBlock> produceCodeBlockFor(ScopeChainNode*, CompilationKind, CodeSpecializationKind, JSObject*& exception);
511
512         JSObject* compileForCall(ExecState* exec, ScopeChainNode* scopeChainNode)
513         {
514             ASSERT(exec->globalData().dynamicGlobalObject);
515             JSObject* error = 0;
516             if (!m_codeBlockForCall)
517                 error = compileForCallInternal(exec, scopeChainNode, JITCode::bottomTierJIT());
518             ASSERT(!error == !!m_codeBlockForCall);
519             return error;
520         }
521
522         JSObject* compileOptimizedForCall(ExecState*, ScopeChainNode*);
523         
524 #if ENABLE(JIT)
525         void jettisonOptimizedCodeForCall(JSGlobalData&);
526         bool jitCompileForCall(ExecState*);
527 #endif
528
529         bool isGeneratedForCall() const
530         {
531             return m_codeBlockForCall;
532         }
533
534         FunctionCodeBlock& generatedBytecodeForCall()
535         {
536             ASSERT(m_codeBlockForCall);
537             return *m_codeBlockForCall;
538         }
539
540         JSObject* compileForConstruct(ExecState* exec, ScopeChainNode* scopeChainNode)
541         {
542             ASSERT(exec->globalData().dynamicGlobalObject);
543             JSObject* error = 0;
544             if (!m_codeBlockForConstruct)
545                 error = compileForConstructInternal(exec, scopeChainNode, JITCode::bottomTierJIT());
546             ASSERT(!error == !!m_codeBlockForConstruct);
547             return error;
548         }
549
550         JSObject* compileOptimizedForConstruct(ExecState*, ScopeChainNode*);
551         
552 #if ENABLE(JIT)
553         void jettisonOptimizedCodeForConstruct(JSGlobalData&);
554         bool jitCompileForConstruct(ExecState*);
555 #endif
556
557         bool isGeneratedForConstruct() const
558         {
559             return m_codeBlockForConstruct;
560         }
561
562         FunctionCodeBlock& generatedBytecodeForConstruct()
563         {
564             ASSERT(m_codeBlockForConstruct);
565             return *m_codeBlockForConstruct;
566         }
567         
568         JSObject* compileFor(ExecState* exec, ScopeChainNode* scopeChainNode, CodeSpecializationKind kind)
569         {
570             ASSERT(exec->callee());
571             ASSERT(exec->callee()->inherits(&JSFunction::s_info));
572             ASSERT(jsCast<JSFunction*>(exec->callee())->jsExecutable() == this);
573
574             if (kind == CodeForCall)
575                 return compileForCall(exec, scopeChainNode);
576             ASSERT(kind == CodeForConstruct);
577             return compileForConstruct(exec, scopeChainNode);
578         }
579         
580         JSObject* compileOptimizedFor(ExecState* exec, ScopeChainNode* scopeChainNode, CodeSpecializationKind kind)
581         {
582             ASSERT(exec->callee());
583             ASSERT(exec->callee()->inherits(&JSFunction::s_info));
584             ASSERT(jsCast<JSFunction*>(exec->callee())->jsExecutable() == this);
585             
586             if (kind == CodeForCall)
587                 return compileOptimizedForCall(exec, scopeChainNode);
588             ASSERT(kind == CodeForConstruct);
589             return compileOptimizedForConstruct(exec, scopeChainNode);
590         }
591         
592 #if ENABLE(JIT)
593         void jettisonOptimizedCodeFor(JSGlobalData& globalData, CodeSpecializationKind kind)
594         {
595             if (kind == CodeForCall) 
596                 jettisonOptimizedCodeForCall(globalData);
597             else {
598                 ASSERT(kind == CodeForConstruct);
599                 jettisonOptimizedCodeForConstruct(globalData);
600             }
601         }
602         
603         bool jitCompileFor(ExecState* exec, CodeSpecializationKind kind)
604         {
605             if (kind == CodeForCall)
606                 return jitCompileForCall(exec);
607             ASSERT(kind == CodeForConstruct);
608             return jitCompileForConstruct(exec);
609         }
610 #endif
611         
612         bool isGeneratedFor(CodeSpecializationKind kind)
613         {
614             if (kind == CodeForCall)
615                 return isGeneratedForCall();
616             ASSERT(kind == CodeForConstruct);
617             return isGeneratedForConstruct();
618         }
619         
620         FunctionCodeBlock& generatedBytecodeFor(CodeSpecializationKind kind)
621         {
622             if (kind == CodeForCall)
623                 return generatedBytecodeForCall();
624             ASSERT(kind == CodeForConstruct);
625             return generatedBytecodeForConstruct();
626         }
627
628         FunctionCodeBlock* baselineCodeBlockFor(CodeSpecializationKind);
629         
630         FunctionCodeBlock* profiledCodeBlockFor(CodeSpecializationKind kind)
631         {
632             return baselineCodeBlockFor(kind);
633         }
634         
635         const Identifier& name() { return m_name; }
636         const Identifier& inferredName() { return m_inferredName; }
637         JSString* nameValue() const { return m_nameValue.get(); }
638         size_t parameterCount() const { return m_parameters->size(); } // Excluding 'this'!
639         unsigned capturedVariableCount() const { return m_numCapturedVariables; }
640         UString paramString() const;
641         SharedSymbolTable* symbolTable() const { return m_symbolTable; }
642
643         void clearCodeIfNotCompiling();
644         static void visitChildren(JSCell*, SlotVisitor&);
645         static FunctionExecutable* fromGlobalCode(const Identifier&, ExecState*, Debugger*, const SourceCode&, JSObject** exception);
646         static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue proto)
647         {
648             return Structure::create(globalData, globalObject, proto, TypeInfo(FunctionExecutableType, StructureFlags), &s_info);
649         }
650         
651         static const ClassInfo s_info;
652         
653         void unlinkCalls();
654
655         void clearCode();
656
657     protected:
658         void finishCreation(JSGlobalData& globalData, const Identifier& name, int firstLine, int lastLine)
659         {
660             Base::finishCreation(globalData);
661             m_firstLine = firstLine;
662             m_lastLine = lastLine;
663             m_nameValue.set(globalData, this, jsString(&globalData, name.ustring()));
664         }
665
666     private:
667         FunctionExecutable(JSGlobalData&, const Identifier& name, const Identifier& inferredName, const SourceCode&, bool forceUsesArguments, FunctionParameters*, bool);
668         FunctionExecutable(ExecState*, const Identifier& name, const Identifier& inferredName, const SourceCode&, bool forceUsesArguments, FunctionParameters*, bool);
669
670         JSObject* compileForCallInternal(ExecState*, ScopeChainNode*, JITCode::JITType);
671         JSObject* compileForConstructInternal(ExecState*, ScopeChainNode*, JITCode::JITType);
672         
673         OwnPtr<FunctionCodeBlock>& codeBlockFor(CodeSpecializationKind kind)
674         {
675             if (kind == CodeForCall)
676                 return m_codeBlockForCall;
677             ASSERT(kind == CodeForConstruct);
678             return m_codeBlockForConstruct;
679         }
680  
681         bool isCompiling()
682         {
683 #if ENABLE(JIT)
684             if (!m_jitCodeForCall && m_codeBlockForCall)
685                 return true;
686             if (!m_jitCodeForConstruct && m_codeBlockForConstruct)
687                 return true;
688 #endif
689             return false;
690         }
691
692         static const unsigned StructureFlags = OverridesVisitChildren | ScriptExecutable::StructureFlags;
693         unsigned m_numCapturedVariables : 31;
694         bool m_forceUsesArguments : 1;
695
696         RefPtr<FunctionParameters> m_parameters;
697         OwnPtr<FunctionCodeBlock> m_codeBlockForCall;
698         OwnPtr<FunctionCodeBlock> m_codeBlockForConstruct;
699         Identifier m_name;
700         Identifier m_inferredName;
701         WriteBarrier<JSString> m_nameValue;
702         SharedSymbolTable* m_symbolTable;
703     };
704
705     inline FunctionExecutable* JSFunction::jsExecutable() const
706     {
707         ASSERT(!isHostFunctionNonInline());
708         return static_cast<FunctionExecutable*>(m_executable.get());
709     }
710
711     inline bool JSFunction::isHostFunction() const
712     {
713         ASSERT(m_executable);
714         return m_executable->isHostFunction();
715     }
716
717     inline NativeFunction JSFunction::nativeFunction()
718     {
719         ASSERT(isHostFunction());
720         return static_cast<NativeExecutable*>(m_executable.get())->function();
721     }
722
723     inline NativeFunction JSFunction::nativeConstructor()
724     {
725         ASSERT(isHostFunction());
726         return static_cast<NativeExecutable*>(m_executable.get())->constructor();
727     }
728
729     inline bool isHostFunction(JSValue value, NativeFunction nativeFunction)
730     {
731         JSFunction* function = jsCast<JSFunction*>(getJSFunction(value));
732         if (!function || !function->isHostFunction())
733             return false;
734         return function->nativeFunction() == nativeFunction;
735     }
736
737     inline void ExecutableBase::clearCodeVirtual(ExecutableBase* executable)
738     {
739         switch (executable->structure()->typeInfo().type()) {
740         case EvalExecutableType:
741             return jsCast<EvalExecutable*>(executable)->clearCode();
742         case ProgramExecutableType:
743             return jsCast<ProgramExecutable*>(executable)->clearCode();
744         case FunctionExecutableType:
745             return jsCast<FunctionExecutable*>(executable)->clearCode();
746         default:
747             return jsCast<NativeExecutable*>(executable)->clearCode();
748         }
749     }
750
751     inline void ScriptExecutable::unlinkCalls()
752     {
753         switch (structure()->typeInfo().type()) {
754         case EvalExecutableType:
755             return jsCast<EvalExecutable*>(this)->unlinkCalls();
756         case ProgramExecutableType:
757             return jsCast<ProgramExecutable*>(this)->unlinkCalls();
758         case FunctionExecutableType:
759             return jsCast<FunctionExecutable*>(this)->unlinkCalls();
760         default:
761             ASSERT_NOT_REACHED();
762         }
763     }
764
765 }
766
767 #endif