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