2 * Copyright (C) 2009, 2010 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
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.
30 #include "CodeSpecializationKind.h"
31 #include "JSFunction.h"
32 #include "Interpreter.h"
34 #include "SamplingTool.h"
35 #include <wtf/PassOwnPtr.h>
42 class FunctionCodeBlock
;
43 class LLIntOffsetsExtractor
;
44 class ProgramCodeBlock
;
47 enum CompilationKind
{ FirstCompilation
, OptimizingCompilation
};
49 inline bool isCall(CodeSpecializationKind kind
)
51 if (kind
== CodeForCall
)
53 ASSERT(kind
== CodeForConstruct
);
57 class ExecutableBase
: public JSCell
{
61 static const int NUM_PARAMETERS_IS_HOST
= 0;
62 static const int NUM_PARAMETERS_NOT_COMPILED
= -1;
64 ExecutableBase(JSGlobalData
& globalData
, Structure
* structure
, int numParameters
)
65 : JSCell(globalData
, structure
)
66 , m_numParametersForCall(numParameters
)
67 , m_numParametersForConstruct(numParameters
)
71 void finishCreation(JSGlobalData
& globalData
)
73 Base::finishCreation(globalData
);
80 static void destroy(JSCell
*);
83 bool isHostFunction() const
85 ASSERT((m_numParametersForCall
== NUM_PARAMETERS_IS_HOST
) == (m_numParametersForConstruct
== NUM_PARAMETERS_IS_HOST
));
86 return m_numParametersForCall
== NUM_PARAMETERS_IS_HOST
;
89 static Structure
* createStructure(JSGlobalData
& globalData
, JSGlobalObject
* globalObject
, JSValue proto
) { return Structure::create(globalData
, globalObject
, proto
, TypeInfo(CompoundType
, StructureFlags
), &s_info
); }
91 static JS_EXPORTDATA
const ClassInfo s_info
;
94 static const unsigned StructureFlags
= 0;
95 int m_numParametersForCall
;
96 int m_numParametersForConstruct
;
100 JITCode
& generatedJITCodeForCall()
102 ASSERT(m_jitCodeForCall
);
103 return m_jitCodeForCall
;
106 JITCode
& generatedJITCodeForConstruct()
108 ASSERT(m_jitCodeForConstruct
);
109 return m_jitCodeForConstruct
;
112 JITCode
& generatedJITCodeFor(CodeSpecializationKind kind
)
114 if (kind
== CodeForCall
)
115 return generatedJITCodeForCall();
116 ASSERT(kind
== CodeForConstruct
);
117 return generatedJITCodeForConstruct();
120 MacroAssemblerCodePtr
generatedJITCodeForCallWithArityCheck()
122 ASSERT(m_jitCodeForCall
);
123 ASSERT(m_jitCodeForCallWithArityCheck
);
124 return m_jitCodeForCallWithArityCheck
;
127 MacroAssemblerCodePtr
generatedJITCodeForConstructWithArityCheck()
129 ASSERT(m_jitCodeForConstruct
);
130 ASSERT(m_jitCodeForConstructWithArityCheck
);
131 return m_jitCodeForConstructWithArityCheck
;
134 MacroAssemblerCodePtr
generatedJITCodeWithArityCheckFor(CodeSpecializationKind kind
)
136 if (kind
== CodeForCall
)
137 return generatedJITCodeForCallWithArityCheck();
138 ASSERT(kind
== CodeForConstruct
);
139 return generatedJITCodeForConstructWithArityCheck();
142 bool hasJITCodeForCall() const
144 return m_numParametersForCall
>= 0;
147 bool hasJITCodeForConstruct() const
149 return m_numParametersForConstruct
>= 0;
152 bool hasJITCodeFor(CodeSpecializationKind kind
) const
154 if (kind
== CodeForCall
)
155 return hasJITCodeForCall();
156 ASSERT(kind
== CodeForConstruct
);
157 return hasJITCodeForConstruct();
160 // Intrinsics are only for calls, currently.
161 Intrinsic
intrinsic() const;
163 Intrinsic
intrinsicFor(CodeSpecializationKind kind
) const
171 JITCode m_jitCodeForCall
;
172 JITCode m_jitCodeForConstruct
;
173 MacroAssemblerCodePtr m_jitCodeForCallWithArityCheck
;
174 MacroAssemblerCodePtr m_jitCodeForConstructWithArityCheck
;
179 class NativeExecutable
: public ExecutableBase
{
181 friend class LLIntOffsetsExtractor
;
183 typedef ExecutableBase Base
;
186 static NativeExecutable
* create(JSGlobalData
& globalData
, MacroAssemblerCodeRef callThunk
, NativeFunction function
, MacroAssemblerCodeRef constructThunk
, NativeFunction constructor
, Intrinsic intrinsic
)
188 ASSERT(!globalData
.interpreter
->classicEnabled());
189 NativeExecutable
* executable
;
191 executable
= new (NotNull
, allocateCell
<NativeExecutable
>(globalData
.heap
)) NativeExecutable(globalData
, function
, constructor
);
192 executable
->finishCreation(globalData
, JITCode(), JITCode(), intrinsic
);
194 executable
= new (NotNull
, allocateCell
<NativeExecutable
>(globalData
.heap
)) NativeExecutable(globalData
, function
, constructor
);
195 executable
->finishCreation(globalData
, JITCode::HostFunction(callThunk
), JITCode::HostFunction(constructThunk
), intrinsic
);
197 globalData
.heap
.addFinalizer(executable
, &finalize
);
202 #if ENABLE(CLASSIC_INTERPRETER)
203 static NativeExecutable
* create(JSGlobalData
& globalData
, NativeFunction function
, NativeFunction constructor
)
205 ASSERT(!globalData
.canUseJIT());
206 NativeExecutable
* executable
= new (NotNull
, allocateCell
<NativeExecutable
>(globalData
.heap
)) NativeExecutable(globalData
, function
, constructor
);
207 executable
->finishCreation(globalData
);
208 globalData
.heap
.addFinalizer(executable
, &finalize
);
214 static void destroy(JSCell
*);
217 NativeFunction
function() { return m_function
; }
218 NativeFunction
constructor() { return m_constructor
; }
220 static Structure
* createStructure(JSGlobalData
& globalData
, JSGlobalObject
* globalObject
, JSValue proto
) { return Structure::create(globalData
, globalObject
, proto
, TypeInfo(LeafType
, StructureFlags
), &s_info
); }
222 static const ClassInfo s_info
;
224 Intrinsic
intrinsic() const;
228 void finishCreation(JSGlobalData
& globalData
, JITCode callThunk
, JITCode constructThunk
, Intrinsic intrinsic
)
230 ASSERT(!globalData
.interpreter
->classicEnabled());
231 Base::finishCreation(globalData
);
232 m_jitCodeForCall
= callThunk
;
233 m_jitCodeForConstruct
= constructThunk
;
234 m_jitCodeForCallWithArityCheck
= callThunk
.addressForCall();
235 m_jitCodeForConstructWithArityCheck
= constructThunk
.addressForCall();
236 m_intrinsic
= intrinsic
;
240 #if ENABLE(CLASSIC_INTERPRETER)
241 void finishCreation(JSGlobalData
& globalData
)
243 ASSERT(!globalData
.canUseJIT());
244 Base::finishCreation(globalData
);
245 m_intrinsic
= NoIntrinsic
;
249 static void finalize(JSCell
*);
252 NativeExecutable(JSGlobalData
& globalData
, NativeFunction function
, NativeFunction constructor
)
253 : ExecutableBase(globalData
, globalData
.nativeExecutableStructure
.get(), NUM_PARAMETERS_IS_HOST
)
254 , m_function(function
)
255 , m_constructor(constructor
)
259 NativeFunction m_function
;
260 NativeFunction m_constructor
;
262 Intrinsic m_intrinsic
;
265 class ScriptExecutable
: public ExecutableBase
{
267 typedef ExecutableBase Base
;
269 ScriptExecutable(Structure
* structure
, JSGlobalData
& globalData
, const SourceCode
& source
, bool isInStrictContext
)
270 : ExecutableBase(globalData
, structure
, NUM_PARAMETERS_NOT_COMPILED
)
272 , m_features(isInStrictContext
? StrictModeFeature
: 0)
276 ScriptExecutable(Structure
* structure
, ExecState
* exec
, const SourceCode
& source
, bool isInStrictContext
)
277 : ExecutableBase(exec
->globalData(), structure
, NUM_PARAMETERS_NOT_COMPILED
)
279 , m_features(isInStrictContext
? StrictModeFeature
: 0)
284 static void destroy(JSCell
*);
287 const SourceCode
& source() { return m_source
; }
288 intptr_t sourceID() const { return m_source
.providerID(); }
289 const UString
& sourceURL() const { return m_source
.provider()->url(); }
290 int lineNo() const { return m_firstLine
; }
291 int lastLine() const { return m_lastLine
; }
293 bool usesEval() const { return m_features
& EvalFeature
; }
294 bool usesArguments() const { return m_features
& ArgumentsFeature
; }
295 bool needsActivation() const { return m_hasCapturedVariables
|| m_features
& (EvalFeature
| WithFeature
| CatchFeature
); }
296 bool isStrictMode() const { return m_features
& StrictModeFeature
; }
300 static const ClassInfo s_info
;
303 void finishCreation(JSGlobalData
& globalData
)
305 Base::finishCreation(globalData
);
306 #if ENABLE(CODEBLOCK_SAMPLING)
307 if (SamplingTool
* sampler
= globalData
.interpreter
->sampler())
308 sampler
->notifyOfScope(globalData
, this);
312 void recordParse(CodeFeatures features
, bool hasCapturedVariables
, int firstLine
, int lastLine
)
314 m_features
= features
;
315 m_hasCapturedVariables
= hasCapturedVariables
;
316 m_firstLine
= firstLine
;
317 m_lastLine
= lastLine
;
321 CodeFeatures m_features
;
322 bool m_hasCapturedVariables
;
327 class EvalExecutable
: public ScriptExecutable
{
328 friend class LLIntOffsetsExtractor
;
330 typedef ScriptExecutable Base
;
332 static void destroy(JSCell
*);
334 JSObject
* compile(ExecState
* exec
, ScopeChainNode
* scopeChainNode
)
336 ASSERT(exec
->globalData().dynamicGlobalObject
);
338 if (!m_evalCodeBlock
)
339 error
= compileInternal(exec
, scopeChainNode
, JITCode::bottomTierJIT());
340 ASSERT(!error
== !!m_evalCodeBlock
);
344 JSObject
* compileOptimized(ExecState
*, ScopeChainNode
*);
347 void jettisonOptimizedCode(JSGlobalData
&);
348 bool jitCompile(JSGlobalData
&);
351 EvalCodeBlock
& generatedBytecode()
353 ASSERT(m_evalCodeBlock
);
354 return *m_evalCodeBlock
;
357 static EvalExecutable
* create(ExecState
* exec
, const SourceCode
& source
, bool isInStrictContext
)
359 EvalExecutable
* executable
= new (NotNull
, allocateCell
<EvalExecutable
>(*exec
->heap())) EvalExecutable(exec
, source
, isInStrictContext
);
360 executable
->finishCreation(exec
->globalData());
361 exec
->globalData().heap
.addFinalizer(executable
, &finalize
);
366 JITCode
& generatedJITCode()
368 return generatedJITCodeForCall();
371 static Structure
* createStructure(JSGlobalData
& globalData
, JSGlobalObject
* globalObject
, JSValue proto
)
373 return Structure::create(globalData
, globalObject
, proto
, TypeInfo(EvalExecutableType
, StructureFlags
), &s_info
);
376 static const ClassInfo s_info
;
382 static void finalize(JSCell
*);
385 static const unsigned StructureFlags
= OverridesVisitChildren
| ScriptExecutable::StructureFlags
;
386 EvalExecutable(ExecState
*, const SourceCode
&, bool);
388 JSObject
* compileInternal(ExecState
*, ScopeChainNode
*, JITCode::JITType
);
389 static void visitChildren(JSCell
*, SlotVisitor
&);
391 OwnPtr
<EvalCodeBlock
> m_evalCodeBlock
;
394 class ProgramExecutable
: public ScriptExecutable
{
395 friend class LLIntOffsetsExtractor
;
397 typedef ScriptExecutable Base
;
399 static ProgramExecutable
* create(ExecState
* exec
, const SourceCode
& source
)
401 ProgramExecutable
* executable
= new (NotNull
, allocateCell
<ProgramExecutable
>(*exec
->heap())) ProgramExecutable(exec
, source
);
402 executable
->finishCreation(exec
->globalData());
403 exec
->globalData().heap
.addFinalizer(executable
, &finalize
);
407 static void destroy(JSCell
*);
409 JSObject
* compile(ExecState
* exec
, ScopeChainNode
* scopeChainNode
)
411 ASSERT(exec
->globalData().dynamicGlobalObject
);
413 if (!m_programCodeBlock
)
414 error
= compileInternal(exec
, scopeChainNode
, JITCode::bottomTierJIT());
415 ASSERT(!error
== !!m_programCodeBlock
);
419 JSObject
* compileOptimized(ExecState
*, ScopeChainNode
*);
422 void jettisonOptimizedCode(JSGlobalData
&);
423 bool jitCompile(JSGlobalData
&);
426 ProgramCodeBlock
& generatedBytecode()
428 ASSERT(m_programCodeBlock
);
429 return *m_programCodeBlock
;
432 JSObject
* checkSyntax(ExecState
*);
435 JITCode
& generatedJITCode()
437 return generatedJITCodeForCall();
441 static Structure
* createStructure(JSGlobalData
& globalData
, JSGlobalObject
* globalObject
, JSValue proto
)
443 return Structure::create(globalData
, globalObject
, proto
, TypeInfo(ProgramExecutableType
, StructureFlags
), &s_info
);
446 static const ClassInfo s_info
;
452 static void finalize(JSCell
*);
455 static const unsigned StructureFlags
= OverridesVisitChildren
| ScriptExecutable::StructureFlags
;
456 ProgramExecutable(ExecState
*, const SourceCode
&);
458 JSObject
* compileInternal(ExecState
*, ScopeChainNode
*, JITCode::JITType
);
459 static void visitChildren(JSCell
*, SlotVisitor
&);
461 OwnPtr
<ProgramCodeBlock
> m_programCodeBlock
;
464 class FunctionExecutable
: public ScriptExecutable
, public DoublyLinkedListNode
<FunctionExecutable
> {
466 friend class LLIntOffsetsExtractor
;
467 friend class WTF::DoublyLinkedListNode
<FunctionExecutable
>;
469 typedef ScriptExecutable Base
;
471 static FunctionExecutable
* create(ExecState
* exec
, const Identifier
& name
, const Identifier
& inferredName
, const SourceCode
& source
, bool forceUsesArguments
, FunctionParameters
* parameters
, bool isInStrictContext
, int firstLine
, int lastLine
)
473 FunctionExecutable
* executable
= new (NotNull
, allocateCell
<FunctionExecutable
>(*exec
->heap())) FunctionExecutable(exec
, name
, inferredName
, source
, forceUsesArguments
, parameters
, isInStrictContext
);
474 executable
->finishCreation(exec
->globalData(), name
, firstLine
, lastLine
);
475 exec
->globalData().heap
.addFunctionExecutable(executable
);
476 exec
->globalData().heap
.addFinalizer(executable
, &finalize
);
480 static FunctionExecutable
* create(JSGlobalData
& globalData
, const Identifier
& name
, const Identifier
& inferredName
, const SourceCode
& source
, bool forceUsesArguments
, FunctionParameters
* parameters
, bool isInStrictContext
, int firstLine
, int lastLine
)
482 FunctionExecutable
* executable
= new (NotNull
, allocateCell
<FunctionExecutable
>(globalData
.heap
)) FunctionExecutable(globalData
, name
, inferredName
, source
, forceUsesArguments
, parameters
, isInStrictContext
);
483 executable
->finishCreation(globalData
, name
, firstLine
, lastLine
);
484 globalData
.heap
.addFunctionExecutable(executable
);
485 globalData
.heap
.addFinalizer(executable
, &finalize
);
489 static void destroy(JSCell
*);
491 JSFunction
* make(ExecState
* exec
, ScopeChainNode
* scopeChain
)
493 return JSFunction::create(exec
, this, scopeChain
);
496 // Returns either call or construct bytecode. This can be appropriate
497 // for answering questions that that don't vary between call and construct --
498 // for example, argumentsRegister().
499 FunctionCodeBlock
& generatedBytecode()
501 if (m_codeBlockForCall
)
502 return *m_codeBlockForCall
;
503 ASSERT(m_codeBlockForConstruct
);
504 return *m_codeBlockForConstruct
;
507 FunctionCodeBlock
* codeBlockWithBytecodeFor(CodeSpecializationKind
);
509 PassOwnPtr
<FunctionCodeBlock
> produceCodeBlockFor(ScopeChainNode
*, CompilationKind
, CodeSpecializationKind
, JSObject
*& exception
);
511 JSObject
* compileForCall(ExecState
* exec
, ScopeChainNode
* scopeChainNode
)
513 ASSERT(exec
->globalData().dynamicGlobalObject
);
515 if (!m_codeBlockForCall
)
516 error
= compileForCallInternal(exec
, scopeChainNode
, JITCode::bottomTierJIT());
517 ASSERT(!error
== !!m_codeBlockForCall
);
521 JSObject
* compileOptimizedForCall(ExecState
*, ScopeChainNode
*);
524 void jettisonOptimizedCodeForCall(JSGlobalData
&);
525 bool jitCompileForCall(JSGlobalData
&);
528 bool isGeneratedForCall() const
530 return m_codeBlockForCall
;
533 FunctionCodeBlock
& generatedBytecodeForCall()
535 ASSERT(m_codeBlockForCall
);
536 return *m_codeBlockForCall
;
539 JSObject
* compileForConstruct(ExecState
* exec
, ScopeChainNode
* scopeChainNode
)
541 ASSERT(exec
->globalData().dynamicGlobalObject
);
543 if (!m_codeBlockForConstruct
)
544 error
= compileForConstructInternal(exec
, scopeChainNode
, JITCode::bottomTierJIT());
545 ASSERT(!error
== !!m_codeBlockForConstruct
);
549 JSObject
* compileOptimizedForConstruct(ExecState
*, ScopeChainNode
*);
552 void jettisonOptimizedCodeForConstruct(JSGlobalData
&);
553 bool jitCompileForConstruct(JSGlobalData
&);
556 bool isGeneratedForConstruct() const
558 return m_codeBlockForConstruct
;
561 FunctionCodeBlock
& generatedBytecodeForConstruct()
563 ASSERT(m_codeBlockForConstruct
);
564 return *m_codeBlockForConstruct
;
567 JSObject
* compileFor(ExecState
* exec
, ScopeChainNode
* scopeChainNode
, CodeSpecializationKind kind
)
569 ASSERT(exec
->callee());
570 ASSERT(exec
->callee()->inherits(&JSFunction::s_info
));
571 ASSERT(jsCast
<JSFunction
*>(exec
->callee())->jsExecutable() == this);
573 if (kind
== CodeForCall
)
574 return compileForCall(exec
, scopeChainNode
);
575 ASSERT(kind
== CodeForConstruct
);
576 return compileForConstruct(exec
, scopeChainNode
);
579 JSObject
* compileOptimizedFor(ExecState
* exec
, ScopeChainNode
* scopeChainNode
, CodeSpecializationKind kind
)
581 ASSERT(exec
->callee());
582 ASSERT(exec
->callee()->inherits(&JSFunction::s_info
));
583 ASSERT(jsCast
<JSFunction
*>(exec
->callee())->jsExecutable() == this);
585 if (kind
== CodeForCall
)
586 return compileOptimizedForCall(exec
, scopeChainNode
);
587 ASSERT(kind
== CodeForConstruct
);
588 return compileOptimizedForConstruct(exec
, scopeChainNode
);
593 void jettisonOptimizedCodeFor(JSGlobalData
& globalData
, CodeSpecializationKind kind
)
595 if (kind
== CodeForCall
)
596 jettisonOptimizedCodeForCall(globalData
);
598 ASSERT(kind
== CodeForConstruct
);
599 jettisonOptimizedCodeForConstruct(globalData
);
603 bool jitCompileFor(JSGlobalData
& globalData
, CodeSpecializationKind kind
)
605 if (kind
== CodeForCall
)
606 return jitCompileForCall(globalData
);
607 ASSERT(kind
== CodeForConstruct
);
608 return jitCompileForConstruct(globalData
);
612 bool isGeneratedFor(CodeSpecializationKind kind
)
614 if (kind
== CodeForCall
)
615 return isGeneratedForCall();
616 ASSERT(kind
== CodeForConstruct
);
617 return isGeneratedForConstruct();
620 FunctionCodeBlock
& generatedBytecodeFor(CodeSpecializationKind kind
)
622 if (kind
== CodeForCall
)
623 return generatedBytecodeForCall();
624 ASSERT(kind
== CodeForConstruct
);
625 return generatedBytecodeForConstruct();
628 FunctionCodeBlock
* baselineCodeBlockFor(CodeSpecializationKind
);
630 FunctionCodeBlock
* profiledCodeBlockFor(CodeSpecializationKind kind
)
632 return baselineCodeBlockFor(kind
);
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
; }
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
)
648 return Structure::create(globalData
, globalObject
, proto
, TypeInfo(FunctionExecutableType
, StructureFlags
), &s_info
);
651 static const ClassInfo s_info
;
657 static void finalize(JSCell
*);
659 void finishCreation(JSGlobalData
& globalData
, const Identifier
& name
, int firstLine
, int lastLine
)
661 Base::finishCreation(globalData
);
662 m_firstLine
= firstLine
;
663 m_lastLine
= lastLine
;
664 m_nameValue
.set(globalData
, this, jsString(&globalData
, name
.ustring()));
668 FunctionExecutable(JSGlobalData
&, const Identifier
& name
, const Identifier
& inferredName
, const SourceCode
&, bool forceUsesArguments
, FunctionParameters
*, bool);
669 FunctionExecutable(ExecState
*, const Identifier
& name
, const Identifier
& inferredName
, const SourceCode
&, bool forceUsesArguments
, FunctionParameters
*, bool);
671 JSObject
* compileForCallInternal(ExecState
*, ScopeChainNode
*, JITCode::JITType
);
672 JSObject
* compileForConstructInternal(ExecState
*, ScopeChainNode
*, JITCode::JITType
);
674 OwnPtr
<FunctionCodeBlock
>& codeBlockFor(CodeSpecializationKind kind
)
676 if (kind
== CodeForCall
)
677 return m_codeBlockForCall
;
678 ASSERT(kind
== CodeForConstruct
);
679 return m_codeBlockForConstruct
;
682 static const unsigned StructureFlags
= OverridesVisitChildren
| ScriptExecutable::StructureFlags
;
683 unsigned m_numCapturedVariables
: 31;
684 bool m_forceUsesArguments
: 1;
686 RefPtr
<FunctionParameters
> m_parameters
;
687 OwnPtr
<FunctionCodeBlock
> m_codeBlockForCall
;
688 OwnPtr
<FunctionCodeBlock
> m_codeBlockForConstruct
;
690 Identifier m_inferredName
;
691 WriteBarrier
<JSString
> m_nameValue
;
692 SharedSymbolTable
* m_symbolTable
;
693 FunctionExecutable
* m_next
;
694 FunctionExecutable
* m_prev
;
697 inline FunctionExecutable
* JSFunction::jsExecutable() const
699 ASSERT(!isHostFunctionNonInline());
700 return static_cast<FunctionExecutable
*>(m_executable
.get());
703 inline bool JSFunction::isHostFunction() const
705 ASSERT(m_executable
);
706 return m_executable
->isHostFunction();
709 inline NativeFunction
JSFunction::nativeFunction()
711 ASSERT(isHostFunction());
712 return static_cast<NativeExecutable
*>(m_executable
.get())->function();
715 inline NativeFunction
JSFunction::nativeConstructor()
717 ASSERT(isHostFunction());
718 return static_cast<NativeExecutable
*>(m_executable
.get())->constructor();
721 inline bool isHostFunction(JSValue value
, NativeFunction nativeFunction
)
723 JSFunction
* function
= jsCast
<JSFunction
*>(getJSFunction(value
));
724 if (!function
|| !function
->isHostFunction())
726 return function
->nativeFunction() == nativeFunction
;
729 inline void ScriptExecutable::unlinkCalls()
731 switch (structure()->typeInfo().type()) {
732 case EvalExecutableType
:
733 return jsCast
<EvalExecutable
*>(this)->unlinkCalls();
734 case ProgramExecutableType
:
735 return jsCast
<ProgramExecutable
*>(this)->unlinkCalls();
736 case FunctionExecutableType
:
737 return jsCast
<FunctionExecutable
*>(this)->unlinkCalls();
739 ASSERT_NOT_REACHED();