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