49a5e19f8305c3bb2e29818337a4ef25618d7bd3
[WebKit-https.git] / Source / JavaScriptCore / runtime / Executable.h
1 /*
2  * Copyright (C) 2009, 2010, 2013 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 "CodeBlockHash.h"
31 #include "CodeSpecializationKind.h"
32 #include "CompilationResult.h"
33 #include "DFGPlan.h"
34 #include "HandlerInfo.h"
35 #include "JSFunction.h"
36 #include "Interpreter.h"
37 #include "JITCode.h"
38 #include "JSGlobalObject.h"
39 #include "LLIntCLoop.h"
40 #include "SamplingTool.h"
41 #include "SourceCode.h"
42 #include "UnlinkedCodeBlock.h"
43 #include <wtf/PassOwnPtr.h>
44
45 namespace JSC {
46
47 class CodeBlock;
48 class Debugger;
49 class EvalCodeBlock;
50 class FunctionCodeBlock;
51 class LLIntOffsetsExtractor;
52 class ProgramCodeBlock;
53 class JSScope;
54     
55 enum CompilationKind { FirstCompilation, OptimizingCompilation };
56
57 inline bool isCall(CodeSpecializationKind kind)
58 {
59     if (kind == CodeForCall)
60         return true;
61     ASSERT(kind == CodeForConstruct);
62     return false;
63 }
64
65 class ExecutableBase : public JSCell, public DoublyLinkedListNode<ExecutableBase> {
66     friend class WTF::DoublyLinkedListNode<ExecutableBase>;
67     friend class JIT;
68
69 protected:
70     static const int NUM_PARAMETERS_IS_HOST = 0;
71     static const int NUM_PARAMETERS_NOT_COMPILED = -1;
72
73     ExecutableBase(VM& vm, Structure* structure, int numParameters)
74         : JSCell(vm, structure)
75         , m_numParametersForCall(numParameters)
76         , m_numParametersForConstruct(numParameters)
77     {
78     }
79
80     void finishCreation(VM& vm)
81     {
82         Base::finishCreation(vm);
83     }
84
85 public:
86     typedef JSCell Base;
87
88 #if ENABLE(JIT)
89     static const bool needsDestruction = true;
90     static const bool hasImmortalStructure = true;
91     static void destroy(JSCell*);
92 #endif
93         
94     CodeBlockHash hashFor(CodeSpecializationKind) const;
95
96     bool isFunctionExecutable()
97     {
98         return structure()->typeInfo().type() == FunctionExecutableType;
99     }
100
101     bool isHostFunction() const
102     {
103         ASSERT((m_numParametersForCall == NUM_PARAMETERS_IS_HOST) == (m_numParametersForConstruct == NUM_PARAMETERS_IS_HOST));
104         return m_numParametersForCall == NUM_PARAMETERS_IS_HOST;
105     }
106
107     static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto) { return Structure::create(vm, globalObject, proto, TypeInfo(CompoundType, StructureFlags), info()); }
108         
109     void clearCode();
110
111     DECLARE_EXPORT_INFO;
112
113 protected:
114     static const unsigned StructureFlags = 0;
115     int m_numParametersForCall;
116     int m_numParametersForConstruct;
117
118 public:
119     static void clearCodeVirtual(ExecutableBase*);
120
121 #if ENABLE(JIT)
122     PassRefPtr<JITCode> generatedJITCodeForCall()
123     {
124         ASSERT(m_jitCodeForCall);
125         return m_jitCodeForCall;
126     }
127
128     PassRefPtr<JITCode> generatedJITCodeForConstruct()
129     {
130         ASSERT(m_jitCodeForConstruct);
131         return m_jitCodeForConstruct;
132     }
133         
134     PassRefPtr<JITCode> generatedJITCodeFor(CodeSpecializationKind kind)
135     {
136         if (kind == CodeForCall)
137             return generatedJITCodeForCall();
138         ASSERT(kind == CodeForConstruct);
139         return generatedJITCodeForConstruct();
140     }
141
142     MacroAssemblerCodePtr generatedJITCodeForCallWithArityCheck()
143     {
144         ASSERT(m_jitCodeForCall);
145         ASSERT(m_jitCodeForCallWithArityCheck);
146         return m_jitCodeForCallWithArityCheck;
147     }
148
149     MacroAssemblerCodePtr generatedJITCodeForConstructWithArityCheck()
150     {
151         ASSERT(m_jitCodeForConstruct);
152         ASSERT(m_jitCodeForConstructWithArityCheck);
153         return m_jitCodeForConstructWithArityCheck;
154     }
155         
156     MacroAssemblerCodePtr generatedJITCodeWithArityCheckFor(CodeSpecializationKind kind)
157     {
158         if (kind == CodeForCall)
159             return generatedJITCodeForCallWithArityCheck();
160         ASSERT(kind == CodeForConstruct);
161         return generatedJITCodeForConstructWithArityCheck();
162     }
163         
164     static ptrdiff_t offsetOfJITCodeWithArityCheckFor(CodeSpecializationKind kind)
165     {
166         if (kind == CodeForCall)
167             return OBJECT_OFFSETOF(ExecutableBase, m_jitCodeForCallWithArityCheck);
168         ASSERT(kind == CodeForConstruct);
169         return OBJECT_OFFSETOF(ExecutableBase, m_jitCodeForConstructWithArityCheck);
170     }
171         
172     static ptrdiff_t offsetOfNumParametersFor(CodeSpecializationKind kind)
173     {
174         if (kind == CodeForCall)
175             return OBJECT_OFFSETOF(ExecutableBase, m_numParametersForCall);
176         ASSERT(kind == CodeForConstruct);
177         return OBJECT_OFFSETOF(ExecutableBase, m_numParametersForConstruct);
178     }
179 #endif // ENABLE(JIT)
180
181     bool hasJITCodeForCall() const
182     {
183         return m_numParametersForCall >= 0;
184     }
185         
186     bool hasJITCodeForConstruct() const
187     {
188         return m_numParametersForConstruct >= 0;
189     }
190         
191     bool hasJITCodeFor(CodeSpecializationKind kind) const
192     {
193         if (kind == CodeForCall)
194             return hasJITCodeForCall();
195         ASSERT(kind == CodeForConstruct);
196         return hasJITCodeForConstruct();
197     }
198
199     // Intrinsics are only for calls, currently.
200     Intrinsic intrinsic() const;
201         
202     Intrinsic intrinsicFor(CodeSpecializationKind kind) const
203     {
204         if (isCall(kind))
205             return intrinsic();
206         return NoIntrinsic;
207     }
208         
209 #if ENABLE(JIT) || ENABLE(LLINT_C_LOOP)
210     MacroAssemblerCodePtr hostCodeEntryFor(CodeSpecializationKind kind)
211     {
212 #if ENABLE(JIT)
213         return generatedJITCodeFor(kind)->addressForCall();
214 #else
215         return LLInt::CLoop::hostCodeEntryFor(kind);
216 #endif
217     }
218
219     MacroAssemblerCodePtr jsCodeEntryFor(CodeSpecializationKind kind)
220     {
221 #if ENABLE(JIT)
222         return generatedJITCodeFor(kind)->addressForCall();
223 #else
224         return LLInt::CLoop::jsCodeEntryFor(kind);
225 #endif
226     }
227
228     MacroAssemblerCodePtr jsCodeWithArityCheckEntryFor(CodeSpecializationKind kind)
229     {
230 #if ENABLE(JIT)
231         return generatedJITCodeWithArityCheckFor(kind);
232 #else
233         return LLInt::CLoop::jsCodeEntryWithArityCheckFor(kind);
234 #endif
235     }
236
237     static void* catchRoutineFor(HandlerInfo* handler, Instruction* catchPCForInterpreter)
238     {
239 #if ENABLE(JIT)
240         UNUSED_PARAM(catchPCForInterpreter);
241         return handler->nativeCode.executableAddress();
242 #else
243         UNUSED_PARAM(handler);
244         return LLInt::CLoop::catchRoutineFor(catchPCForInterpreter);
245 #endif
246     }
247     
248 #endif // ENABLE(JIT || ENABLE(LLINT_C_LOOP)
249
250 protected:
251     ExecutableBase* m_prev;
252     ExecutableBase* m_next;
253
254     RefPtr<JITCode> m_jitCodeForCall;
255     RefPtr<JITCode> m_jitCodeForConstruct;
256     MacroAssemblerCodePtr m_jitCodeForCallWithArityCheck;
257     MacroAssemblerCodePtr m_jitCodeForConstructWithArityCheck;
258 };
259
260 class NativeExecutable : public ExecutableBase {
261     friend class JIT;
262     friend class LLIntOffsetsExtractor;
263 public:
264     typedef ExecutableBase Base;
265
266 #if ENABLE(JIT)
267     static NativeExecutable* create(VM& vm, MacroAssemblerCodeRef callThunk, NativeFunction function, MacroAssemblerCodeRef constructThunk, NativeFunction constructor, Intrinsic intrinsic)
268     {
269         NativeExecutable* executable;
270         if (!callThunk) {
271             executable = new (NotNull, allocateCell<NativeExecutable>(vm.heap)) NativeExecutable(vm, function, constructor);
272             executable->finishCreation(vm, 0, 0, intrinsic);
273         } else {
274             executable = new (NotNull, allocateCell<NativeExecutable>(vm.heap)) NativeExecutable(vm, function, constructor);
275             executable->finishCreation(vm, JITCode::hostFunction(callThunk), JITCode::hostFunction(constructThunk), intrinsic);
276         }
277         return executable;
278     }
279 #endif
280
281 #if ENABLE(LLINT_C_LOOP)
282     static NativeExecutable* create(VM& vm, NativeFunction function, NativeFunction constructor)
283     {
284         ASSERT(!vm.canUseJIT());
285         NativeExecutable* executable = new (NotNull, allocateCell<NativeExecutable>(vm.heap)) NativeExecutable(vm, function, constructor);
286         executable->finishCreation(vm);
287         return executable;
288     }
289 #endif
290
291 #if ENABLE(JIT)
292     static void destroy(JSCell*);
293 #endif
294
295     CodeBlockHash hashFor(CodeSpecializationKind) const;
296
297     NativeFunction function() { return m_function; }
298     NativeFunction constructor() { return m_constructor; }
299         
300     NativeFunction nativeFunctionFor(CodeSpecializationKind kind)
301     {
302         if (kind == CodeForCall)
303             return function();
304         ASSERT(kind == CodeForConstruct);
305         return constructor();
306     }
307         
308     static ptrdiff_t offsetOfNativeFunctionFor(CodeSpecializationKind kind)
309     {
310         if (kind == CodeForCall)
311             return OBJECT_OFFSETOF(NativeExecutable, m_function);
312         ASSERT(kind == CodeForConstruct);
313         return OBJECT_OFFSETOF(NativeExecutable, m_constructor);
314     }
315
316     static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto) { return Structure::create(vm, globalObject, proto, TypeInfo(LeafType, StructureFlags), info()); }
317         
318     DECLARE_INFO;
319
320     Intrinsic intrinsic() const;
321
322 protected:
323 #if ENABLE(JIT)
324     void finishCreation(VM& vm, PassRefPtr<JITCode> callThunk, PassRefPtr<JITCode> constructThunk, Intrinsic intrinsic)
325     {
326         Base::finishCreation(vm);
327         m_jitCodeForCallWithArityCheck = callThunk ? callThunk->addressForCall() : MacroAssemblerCodePtr();
328         m_jitCodeForConstructWithArityCheck = constructThunk ? constructThunk->addressForCall() : MacroAssemblerCodePtr();
329         m_jitCodeForCall = callThunk;
330         m_jitCodeForConstruct = constructThunk;
331         m_intrinsic = intrinsic;
332     }
333 #endif
334
335 private:
336     NativeExecutable(VM& vm, NativeFunction function, NativeFunction constructor)
337         : ExecutableBase(vm, vm.nativeExecutableStructure.get(), NUM_PARAMETERS_IS_HOST)
338         , m_function(function)
339         , m_constructor(constructor)
340     {
341     }
342
343     NativeFunction m_function;
344     NativeFunction m_constructor;
345         
346     Intrinsic m_intrinsic;
347 };
348
349 class ScriptExecutable : public ExecutableBase {
350 public:
351     typedef ExecutableBase Base;
352
353     ScriptExecutable(Structure* structure, VM& vm, const SourceCode& source, bool isInStrictContext)
354         : ExecutableBase(vm, structure, NUM_PARAMETERS_NOT_COMPILED)
355         , m_source(source)
356         , m_features(isInStrictContext ? StrictModeFeature : 0)
357         , m_neverInline(false)
358     {
359     }
360
361     ScriptExecutable(Structure* structure, ExecState* exec, const SourceCode& source, bool isInStrictContext)
362         : ExecutableBase(exec->vm(), structure, NUM_PARAMETERS_NOT_COMPILED)
363         , m_source(source)
364         , m_features(isInStrictContext ? StrictModeFeature : 0)
365         , m_neverInline(false)
366     {
367     }
368
369 #if ENABLE(JIT)
370     static void destroy(JSCell*);
371 #endif
372         
373     CodeBlockHash hashFor(CodeSpecializationKind) const;
374
375     const SourceCode& source() const { return m_source; }
376     intptr_t sourceID() const { return m_source.providerID(); }
377     const String& sourceURL() const { return m_source.provider()->url(); }
378     int lineNo() const { return m_firstLine; }
379     int lastLine() const { return m_lastLine; }
380     unsigned startColumn() const { return m_startColumn; }
381
382     bool usesEval() const { return m_features & EvalFeature; }
383     bool usesArguments() const { return m_features & ArgumentsFeature; }
384     bool needsActivation() const { return m_hasCapturedVariables || m_features & (EvalFeature | WithFeature | CatchFeature); }
385     bool isStrictMode() const { return m_features & StrictModeFeature; }
386     ECMAMode ecmaMode() const { return isStrictMode() ? StrictMode : NotStrictMode; }
387         
388     void setNeverInline(bool value) { m_neverInline = value; }
389     bool neverInline() const { return m_neverInline; }
390     bool isInliningCandidate() const { return !neverInline(); }
391
392     void unlinkCalls();
393         
394     CodeFeatures features() const { return m_features; }
395         
396     DECLARE_INFO;
397
398     void recordParse(CodeFeatures features, bool hasCapturedVariables, int firstLine, int lastLine, unsigned startColumn)
399     {
400         m_features = features;
401         m_hasCapturedVariables = hasCapturedVariables;
402         m_firstLine = firstLine;
403         m_lastLine = lastLine;
404         m_startColumn = startColumn;
405     }
406
407     void installCode(CodeBlock*);
408     PassRefPtr<CodeBlock> newCodeBlockFor(CodeSpecializationKind, JSScope*, JSObject*& exception);
409     PassRefPtr<CodeBlock> newReplacementCodeBlockFor(CodeSpecializationKind);
410     
411     JSObject* prepareForExecution(ExecState* exec, JSScope* scope, CodeSpecializationKind kind)
412     {
413         if (hasJITCodeFor(kind))
414             return 0;
415         return prepareForExecutionImpl(exec, scope, kind);
416     }
417
418 private:
419     JSObject* prepareForExecutionImpl(ExecState*, JSScope*, CodeSpecializationKind);
420
421 protected:
422     void finishCreation(VM& vm)
423     {
424         Base::finishCreation(vm);
425         vm.heap.addCompiledCode(this); // Balanced by Heap::deleteUnmarkedCompiledCode().
426
427 #if ENABLE(CODEBLOCK_SAMPLING)
428         if (SamplingTool* sampler = vm.interpreter->sampler())
429             sampler->notifyOfScope(vm, this);
430 #endif
431     }
432
433     SourceCode m_source;
434     CodeFeatures m_features;
435     bool m_hasCapturedVariables;
436     bool m_neverInline;
437     int m_firstLine;
438     int m_lastLine;
439     unsigned m_startColumn;
440 };
441
442 class EvalExecutable : public ScriptExecutable {
443     friend class LLIntOffsetsExtractor;
444 public:
445     typedef ScriptExecutable Base;
446
447     static void destroy(JSCell*);
448
449     EvalCodeBlock* codeBlock()
450     {
451         return m_evalCodeBlock.get();
452     }
453
454     static EvalExecutable* create(ExecState*, const SourceCode&, bool isInStrictContext);
455
456 #if ENABLE(JIT)
457     PassRefPtr<JITCode> generatedJITCode()
458     {
459         return generatedJITCodeForCall();
460     }
461 #endif
462     static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto)
463     {
464         return Structure::create(vm, globalObject, proto, TypeInfo(EvalExecutableType, StructureFlags), info());
465     }
466         
467     DECLARE_INFO;
468
469     void unlinkCalls();
470
471     void clearCode();
472
473     ExecutableInfo executableInfo() const { return ExecutableInfo(needsActivation(), usesEval(), isStrictMode(), false); }
474
475     unsigned numVariables() { return m_unlinkedEvalCodeBlock->numVariables(); }
476     unsigned numberOfFunctionDecls() { return m_unlinkedEvalCodeBlock->numberOfFunctionDecls(); }
477
478 private:
479     friend class ScriptExecutable;
480     static const unsigned StructureFlags = OverridesVisitChildren | ScriptExecutable::StructureFlags;
481     EvalExecutable(ExecState*, const SourceCode&, bool);
482
483     static void visitChildren(JSCell*, SlotVisitor&);
484
485     RefPtr<EvalCodeBlock> m_evalCodeBlock;
486     WriteBarrier<UnlinkedEvalCodeBlock> m_unlinkedEvalCodeBlock;
487 };
488
489 class ProgramExecutable : public ScriptExecutable {
490     friend class LLIntOffsetsExtractor;
491 public:
492     typedef ScriptExecutable Base;
493
494     static ProgramExecutable* create(ExecState* exec, const SourceCode& source)
495     {
496         ProgramExecutable* executable = new (NotNull, allocateCell<ProgramExecutable>(*exec->heap())) ProgramExecutable(exec, source);
497         executable->finishCreation(exec->vm());
498         return executable;
499     }
500
501
502     JSObject* initializeGlobalProperties(VM&, CallFrame*, JSScope*);
503
504     static void destroy(JSCell*);
505
506     ProgramCodeBlock* codeBlock()
507     {
508         return m_programCodeBlock.get();
509     }
510
511     JSObject* checkSyntax(ExecState*);
512
513 #if ENABLE(JIT)
514     PassRefPtr<JITCode> generatedJITCode()
515     {
516         return generatedJITCodeForCall();
517     }
518 #endif
519         
520     static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto)
521     {
522         return Structure::create(vm, globalObject, proto, TypeInfo(ProgramExecutableType, StructureFlags), info());
523     }
524         
525     DECLARE_INFO;
526         
527     void unlinkCalls();
528
529     void clearCode();
530
531     ExecutableInfo executableInfo() const { return ExecutableInfo(needsActivation(), usesEval(), isStrictMode(), false); }
532
533 private:
534     friend class ScriptExecutable;
535     
536     static const unsigned StructureFlags = OverridesVisitChildren | ScriptExecutable::StructureFlags;
537
538     ProgramExecutable(ExecState*, const SourceCode&);
539
540     static void visitChildren(JSCell*, SlotVisitor&);
541
542     WriteBarrier<UnlinkedProgramCodeBlock> m_unlinkedProgramCodeBlock;
543     RefPtr<ProgramCodeBlock> m_programCodeBlock;
544 };
545
546 class FunctionExecutable : public ScriptExecutable {
547     friend class JIT;
548     friend class LLIntOffsetsExtractor;
549 public:
550     typedef ScriptExecutable Base;
551
552     static FunctionExecutable* create(VM& vm, const SourceCode& source, UnlinkedFunctionExecutable* unlinkedExecutable, unsigned firstLine, unsigned lastLine, unsigned startColumn)
553     {
554         FunctionExecutable* executable = new (NotNull, allocateCell<FunctionExecutable>(vm.heap)) FunctionExecutable(vm, source, unlinkedExecutable, firstLine, lastLine, startColumn);
555         executable->finishCreation(vm);
556         return executable;
557     }
558     static FunctionExecutable* fromGlobalCode(const Identifier& name, ExecState*, Debugger*, const SourceCode&, JSObject** exception);
559
560     static void destroy(JSCell*);
561         
562     UnlinkedFunctionExecutable* unlinkedExecutable()
563     {
564         return m_unlinkedExecutable.get();
565     }
566
567     // Returns either call or construct bytecode. This can be appropriate
568     // for answering questions that that don't vary between call and construct --
569     // for example, argumentsRegister().
570     FunctionCodeBlock* eitherCodeBlock()
571     {
572         if (m_codeBlockForCall)
573             return m_codeBlockForCall.get();
574         return m_codeBlockForConstruct.get();
575     }
576         
577     bool isGeneratedForCall() const
578     {
579         return m_codeBlockForCall;
580     }
581
582     FunctionCodeBlock* codeBlockForCall()
583     {
584         return m_codeBlockForCall.get();
585     }
586
587     bool isGeneratedForConstruct() const
588     {
589         return m_codeBlockForConstruct;
590     }
591
592     FunctionCodeBlock* codeBlockForConstruct()
593     {
594         return m_codeBlockForConstruct.get();
595     }
596         
597     bool isGeneratedFor(CodeSpecializationKind kind)
598     {
599         if (kind == CodeForCall)
600             return isGeneratedForCall();
601         ASSERT(kind == CodeForConstruct);
602         return isGeneratedForConstruct();
603     }
604         
605     FunctionCodeBlock* codeBlockFor(CodeSpecializationKind kind)
606     {
607         if (kind == CodeForCall)
608             return codeBlockForCall();
609         ASSERT(kind == CodeForConstruct);
610         return codeBlockForConstruct();
611     }
612
613     FunctionCodeBlock* baselineCodeBlockFor(CodeSpecializationKind);
614         
615     FunctionCodeBlock* profiledCodeBlockFor(CodeSpecializationKind kind)
616     {
617         return baselineCodeBlockFor(kind);
618     }
619         
620     const Identifier& name() { return m_unlinkedExecutable->name(); }
621     const Identifier& inferredName() { return m_unlinkedExecutable->inferredName(); }
622     JSString* nameValue() const { return m_unlinkedExecutable->nameValue(); }
623     size_t parameterCount() const { return m_unlinkedExecutable->parameterCount(); } // Excluding 'this'!
624     String paramString() const;
625     SharedSymbolTable* symbolTable(CodeSpecializationKind kind) const { return m_unlinkedExecutable->symbolTable(kind); }
626
627     void clearCodeIfNotCompiling();
628     void clearUnlinkedCodeForRecompilationIfNotCompiling();
629     static void visitChildren(JSCell*, SlotVisitor&);
630     static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto)
631     {
632         return Structure::create(vm, globalObject, proto, TypeInfo(FunctionExecutableType, StructureFlags), info());
633     }
634         
635     DECLARE_INFO;
636         
637     void unlinkCalls();
638
639     void clearCode();
640
641 private:
642     FunctionExecutable(VM&, const SourceCode&, UnlinkedFunctionExecutable*, unsigned firstLine, unsigned lastLine, unsigned startColumn);
643
644     bool isCompiling()
645     {
646 #if ENABLE(JIT)
647         if (!m_jitCodeForCall && m_codeBlockForCall)
648             return true;
649         if (!m_jitCodeForConstruct && m_codeBlockForConstruct)
650             return true;
651 #endif
652         return false;
653     }
654
655     friend class ScriptExecutable;
656
657     static const unsigned StructureFlags = OverridesVisitChildren | ScriptExecutable::StructureFlags;
658     WriteBarrier<UnlinkedFunctionExecutable> m_unlinkedExecutable;
659     RefPtr<FunctionCodeBlock> m_codeBlockForCall;
660     RefPtr<FunctionCodeBlock> m_codeBlockForConstruct;
661 };
662
663 inline bool isHostFunction(JSValue value, NativeFunction nativeFunction)
664 {
665     JSFunction* function = jsCast<JSFunction*>(getJSFunction(value));
666     if (!function || !function->isHostFunction())
667         return false;
668     return function->nativeFunction() == nativeFunction;
669 }
670
671 inline void ExecutableBase::clearCodeVirtual(ExecutableBase* executable)
672 {
673     switch (executable->structure()->typeInfo().type()) {
674     case EvalExecutableType:
675         return jsCast<EvalExecutable*>(executable)->clearCode();
676     case ProgramExecutableType:
677         return jsCast<ProgramExecutable*>(executable)->clearCode();
678     case FunctionExecutableType:
679         return jsCast<FunctionExecutable*>(executable)->clearCode();
680     default:
681         return jsCast<NativeExecutable*>(executable)->clearCode();
682     }
683 }
684
685 inline void ScriptExecutable::unlinkCalls()
686 {
687     switch (structure()->typeInfo().type()) {
688     case EvalExecutableType:
689         return jsCast<EvalExecutable*>(this)->unlinkCalls();
690     case ProgramExecutableType:
691         return jsCast<ProgramExecutable*>(this)->unlinkCalls();
692     case FunctionExecutableType:
693         return jsCast<FunctionExecutable*>(this)->unlinkCalls();
694     default:
695         RELEASE_ASSERT_NOT_REACHED();
696     }
697 }
698
699 }
700
701 #endif