2  * Copyright (C) 2012, 2013, 2014 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. 
  26 #ifndef UnlinkedCodeBlock_h 
  27 #define UnlinkedCodeBlock_h 
  29 #include "BytecodeConventions.h" 
  30 #include "CodeSpecializationKind.h" 
  32 #include "ExpressionRangeInfo.h" 
  33 #include "Identifier.h" 
  36 #include "ParserModes.h" 
  38 #include "SpecialPointer.h" 
  39 #include "SymbolTable.h" 
  40 #include "VirtualRegister.h" 
  42 #include <wtf/Compression.h> 
  43 #include <wtf/RefCountedArray.h> 
  44 #include <wtf/Vector.h> 
  49 class FunctionBodyNode
; 
  50 class FunctionExecutable
; 
  51 class FunctionParameters
; 
  54 class ScriptExecutable
; 
  58 class UnlinkedCodeBlock
; 
  59 class UnlinkedFunctionCodeBlock
; 
  60 class UnlinkedInstructionStream
; 
  62 typedef unsigned UnlinkedValueProfile
; 
  63 typedef unsigned UnlinkedArrayProfile
; 
  64 typedef unsigned UnlinkedArrayAllocationProfile
; 
  65 typedef unsigned UnlinkedObjectAllocationProfile
; 
  66 typedef unsigned UnlinkedLLIntCallLinkInfo
; 
  68 struct ExecutableInfo 
{ 
  69     ExecutableInfo(bool needsActivation
, bool usesEval
, bool isStrictMode
, bool isConstructor
, bool isBuiltinFunction
) 
  70         : m_needsActivation(needsActivation
) 
  71         , m_usesEval(usesEval
) 
  72         , m_isStrictMode(isStrictMode
) 
  73         , m_isConstructor(isConstructor
) 
  74         , m_isBuiltinFunction(isBuiltinFunction
) 
  77     bool m_needsActivation 
: 1; 
  79     bool m_isStrictMode 
: 1; 
  80     bool m_isConstructor 
: 1; 
  81     bool m_isBuiltinFunction 
: 1; 
  84 enum UnlinkedFunctionKind 
{ 
  85     UnlinkedNormalFunction
, 
  86     UnlinkedBuiltinFunction
, 
  89 class UnlinkedFunctionExecutable 
: public JSCell 
{ 
  91     friend class BuiltinExecutables
; 
  92     friend class CodeCache
; 
  95     static UnlinkedFunctionExecutable
* create(VM
* vm
, const SourceCode
& source
, FunctionBodyNode
* node
, UnlinkedFunctionKind unlinkedFunctionKind
) 
  97         UnlinkedFunctionExecutable
* instance 
= new (NotNull
, allocateCell
<UnlinkedFunctionExecutable
>(vm
->heap
)) UnlinkedFunctionExecutable(vm
, vm
->unlinkedFunctionExecutableStructure
.get(), source
, node
, unlinkedFunctionKind
); 
  98         instance
->finishCreation(*vm
); 
 102     const Identifier
& name() const { return m_name
; } 
 103     const Identifier
& inferredName() const { return m_inferredName
; } 
 104     JSString
* nameValue() const { return m_nameValue
.get(); } 
 105     SymbolTable
* symbolTable(CodeSpecializationKind kind
) 
 107         return (kind 
== CodeForCall
) ? m_symbolTableForCall
.get() : m_symbolTableForConstruct
.get(); 
 109     size_t parameterCount() const; 
 110     bool isInStrictContext() const { return m_isInStrictContext
; } 
 111     FunctionMode 
functionMode() const { return m_functionMode
; } 
 112     JSParserStrictness 
toStrictness() const 
 114         if (m_isBuiltinFunction
) 
 115             return JSParseBuiltin
; 
 116         if (m_isInStrictContext
) 
 117             return JSParseStrict
; 
 118         return JSParseNormal
; 
 121     unsigned firstLineOffset() const { return m_firstLineOffset
; } 
 122     unsigned lineCount() const { return m_lineCount
; } 
 123     unsigned unlinkedFunctionNameStart() const { return m_unlinkedFunctionNameStart
; } 
 124     unsigned unlinkedBodyStartColumn() const { return m_unlinkedBodyStartColumn
; } 
 125     unsigned unlinkedBodyEndColumn() const { return m_unlinkedBodyEndColumn
; } 
 126     unsigned startOffset() const { return m_startOffset
; } 
 127     unsigned sourceLength() { return m_sourceLength
; } 
 129     String 
paramString() const; 
 131     UnlinkedFunctionCodeBlock
* codeBlockFor(VM
&, const SourceCode
&, CodeSpecializationKind
, DebuggerMode
, ProfilerMode
, bool bodyIncludesBraces
, ParserError
&); 
 133     static UnlinkedFunctionExecutable
* fromGlobalCode(const Identifier
&, ExecState
*, Debugger
*, const SourceCode
&, JSObject
** exception
); 
 135     FunctionExecutable
* link(VM
&, const SourceCode
&, size_t lineOffset
); 
 137     void clearCodeForRecompilation() 
 139         m_symbolTableForCall
.clear(); 
 140         m_symbolTableForConstruct
.clear(); 
 141         m_codeBlockForCall
.clear(); 
 142         m_codeBlockForConstruct
.clear(); 
 145     FunctionParameters
* parameters() { return m_parameters
.get(); } 
 147     void recordParse(CodeFeatures features
, bool hasCapturedVariables
) 
 149         m_features 
= features
; 
 150         m_hasCapturedVariables 
= hasCapturedVariables
; 
 153     bool forceUsesArguments() const { return m_forceUsesArguments
; } 
 155     CodeFeatures 
features() const { return m_features
; } 
 156     bool hasCapturedVariables() const { return m_hasCapturedVariables
; } 
 158     static const bool needsDestruction 
= true; 
 159     static const bool hasImmortalStructure 
= true; 
 160     static void destroy(JSCell
*); 
 162     bool isBuiltinFunction() const { return m_isBuiltinFunction
; } 
 165     UnlinkedFunctionExecutable(VM
*, Structure
*, const SourceCode
&, FunctionBodyNode
*, UnlinkedFunctionKind
); 
 166     WriteBarrier
<UnlinkedFunctionCodeBlock
> m_codeBlockForCall
; 
 167     WriteBarrier
<UnlinkedFunctionCodeBlock
> m_codeBlockForConstruct
; 
 169     unsigned m_numCapturedVariables 
: 29; 
 170     bool m_forceUsesArguments 
: 1; 
 171     bool m_isInStrictContext 
: 1; 
 172     bool m_hasCapturedVariables 
: 1; 
 173     bool m_isBuiltinFunction 
: 1; 
 176     Identifier m_inferredName
; 
 177     WriteBarrier
<JSString
> m_nameValue
; 
 178     WriteBarrier
<SymbolTable
> m_symbolTableForCall
; 
 179     WriteBarrier
<SymbolTable
> m_symbolTableForConstruct
; 
 180     RefPtr
<FunctionParameters
> m_parameters
; 
 181     unsigned m_firstLineOffset
; 
 182     unsigned m_lineCount
; 
 183     unsigned m_unlinkedFunctionNameStart
; 
 184     unsigned m_unlinkedBodyStartColumn
; 
 185     unsigned m_unlinkedBodyEndColumn
; 
 186     unsigned m_startOffset
; 
 187     unsigned m_sourceLength
; 
 189     CodeFeatures m_features
; 
 191     FunctionMode m_functionMode
; 
 194     void finishCreation(VM
& vm
) 
 196         Base::finishCreation(vm
); 
 197         m_nameValue
.set(vm
, this, jsString(&vm
, name().string())); 
 200     static void visitChildren(JSCell
*, SlotVisitor
&); 
 203     static Structure
* createStructure(VM
& vm
, JSGlobalObject
* globalObject
, JSValue proto
) 
 205         return Structure::create(vm
, globalObject
, proto
, TypeInfo(UnlinkedFunctionExecutableType
, StructureFlags
), info()); 
 208     static const unsigned StructureFlags 
= OverridesVisitChildren 
| StructureIsImmortal 
| JSCell::StructureFlags
; 
 213 struct UnlinkedStringJumpTable 
{ 
 214     typedef HashMap
<RefPtr
<StringImpl
>, int32_t> StringOffsetTable
; 
 215     StringOffsetTable offsetTable
; 
 217     inline int32_t offsetForValue(StringImpl
* value
, int32_t defaultOffset
) 
 219         StringOffsetTable::const_iterator end 
= offsetTable
.end(); 
 220         StringOffsetTable::const_iterator loc 
= offsetTable
.find(value
); 
 222             return defaultOffset
; 
 228 struct UnlinkedSimpleJumpTable 
{ 
 229     Vector
<int32_t> branchOffsets
; 
 232     int32_t offsetForValue(int32_t value
, int32_t defaultOffset
); 
 233     void add(int32_t key
, int32_t offset
) 
 235         if (!branchOffsets
[key
]) 
 236             branchOffsets
[key
] = offset
; 
 240 struct UnlinkedHandlerInfo 
{ 
 247 struct UnlinkedInstruction 
{ 
 248     UnlinkedInstruction() { u
.operand 
= 0; } 
 249     UnlinkedInstruction(OpcodeID opcode
) { u
.opcode 
= opcode
; } 
 250     UnlinkedInstruction(int operand
) { u
.operand 
= operand
; } 
 258 class UnlinkedCodeBlock 
: public JSCell 
{ 
 261     static const bool needsDestruction 
= true; 
 262     static const bool hasImmortalStructure 
= true; 
 264     enum { CallFunction
, ApplyFunction 
}; 
 266     bool isConstructor() const { return m_isConstructor
; } 
 267     bool isStrictMode() const { return m_isStrictMode
; } 
 268     bool usesEval() const { return m_usesEval
; } 
 270     bool needsFullScopeChain() const { return m_needsFullScopeChain
; } 
 272     void addExpressionInfo(unsigned instructionOffset
, int divot
, 
 273         int startOffset
, int endOffset
, unsigned line
, unsigned column
); 
 275     bool hasExpressionInfo() { return m_expressionInfo
.size(); } 
 278     void setThisRegister(VirtualRegister thisRegister
) { m_thisRegister 
= thisRegister
; } 
 279     void setActivationRegister(VirtualRegister activationRegister
) { m_activationRegister 
= activationRegister
; } 
 281     void setArgumentsRegister(VirtualRegister argumentsRegister
) { m_argumentsRegister 
= argumentsRegister
; } 
 282     bool usesArguments() const { return m_argumentsRegister
.isValid(); } 
 283     VirtualRegister 
argumentsRegister() const { return m_argumentsRegister
; } 
 286     bool usesGlobalObject() const { return m_globalObjectRegister
.isValid(); } 
 287     void setGlobalObjectRegister(VirtualRegister globalObjectRegister
) { m_globalObjectRegister 
= globalObjectRegister
; } 
 288     VirtualRegister 
globalObjectRegister() const { return m_globalObjectRegister
; } 
 290     // Parameter information 
 291     void setNumParameters(int newValue
) { m_numParameters 
= newValue
; } 
 292     void addParameter() { m_numParameters
++; } 
 293     unsigned numParameters() const { return m_numParameters
; } 
 295     unsigned addRegExp(RegExp
* r
) 
 297         createRareDataIfNecessary(); 
 298         unsigned size 
= m_rareData
->m_regexps
.size(); 
 299         m_rareData
->m_regexps
.append(WriteBarrier
<RegExp
>(*m_vm
, this, r
)); 
 302     unsigned numberOfRegExps() const 
 306         return m_rareData
->m_regexps
.size(); 
 308     RegExp
* regexp(int index
) const { ASSERT(m_rareData
); return m_rareData
->m_regexps
[index
].get(); } 
 312     size_t numberOfIdentifiers() const { return m_identifiers
.size(); } 
 313     void addIdentifier(const Identifier
& i
) { return m_identifiers
.append(i
); } 
 314     const Identifier
& identifier(int index
) const { return m_identifiers
[index
]; } 
 315     const Vector
<Identifier
>& identifiers() const { return m_identifiers
; } 
 317     size_t numberOfConstantRegisters() const { return m_constantRegisters
.size(); } 
 318     unsigned addConstant(JSValue v
) 
 320         unsigned result 
= m_constantRegisters
.size(); 
 321         m_constantRegisters
.append(WriteBarrier
<Unknown
>()); 
 322         m_constantRegisters
.last().set(*m_vm
, this, v
); 
 325     unsigned addOrFindConstant(JSValue
); 
 326     const Vector
<WriteBarrier
<Unknown
>>& constantRegisters() { return m_constantRegisters
; } 
 327     const WriteBarrier
<Unknown
>& constantRegister(int index
) const { return m_constantRegisters
[index 
- FirstConstantRegisterIndex
]; } 
 328     ALWAYS_INLINE 
bool isConstantRegisterIndex(int index
) const { return index 
>= FirstConstantRegisterIndex
; } 
 329     ALWAYS_INLINE JSValue 
getConstant(int index
) const { return m_constantRegisters
[index 
- FirstConstantRegisterIndex
].get(); } 
 332     size_t numberOfJumpTargets() const { return m_jumpTargets
.size(); } 
 333     void addJumpTarget(unsigned jumpTarget
) { m_jumpTargets
.append(jumpTarget
); } 
 334     unsigned jumpTarget(int index
) const { return m_jumpTargets
[index
]; } 
 335     unsigned lastJumpTarget() const { return m_jumpTargets
.last(); } 
 337     void setIsNumericCompareFunction(bool isNumericCompareFunction
) { m_isNumericCompareFunction 
= isNumericCompareFunction
; } 
 338     bool isNumericCompareFunction() const { return m_isNumericCompareFunction
; } 
 340     bool isBuiltinFunction() const { return m_isBuiltinFunction
; } 
 344         m_jumpTargets
.shrinkToFit(); 
 345         m_identifiers
.shrinkToFit(); 
 346         m_constantRegisters
.shrinkToFit(); 
 347         m_functionDecls
.shrinkToFit(); 
 348         m_functionExprs
.shrinkToFit(); 
 349         m_propertyAccessInstructions
.shrinkToFit(); 
 350         m_expressionInfo
.shrinkToFit(); 
 352 #if ENABLE(BYTECODE_COMMENTS) 
 353         m_bytecodeComments
.shrinkToFit(); 
 356             m_rareData
->m_exceptionHandlers
.shrinkToFit(); 
 357             m_rareData
->m_regexps
.shrinkToFit(); 
 358             m_rareData
->m_constantBuffers
.shrinkToFit(); 
 359             m_rareData
->m_switchJumpTables
.shrinkToFit(); 
 360             m_rareData
->m_stringSwitchJumpTables
.shrinkToFit(); 
 361             m_rareData
->m_expressionInfoFatPositions
.shrinkToFit(); 
 365     void setInstructions(std::unique_ptr
<UnlinkedInstructionStream
>); 
 366     const UnlinkedInstructionStream
& instructions() const; 
 369     int m_numCapturedVars
; 
 370     int m_numCalleeRegisters
; 
 374     size_t numberOfSwitchJumpTables() const { return m_rareData 
? m_rareData
->m_switchJumpTables
.size() : 0; } 
 375     UnlinkedSimpleJumpTable
& addSwitchJumpTable() { createRareDataIfNecessary(); m_rareData
->m_switchJumpTables
.append(UnlinkedSimpleJumpTable()); return m_rareData
->m_switchJumpTables
.last(); } 
 376     UnlinkedSimpleJumpTable
& switchJumpTable(int tableIndex
) { ASSERT(m_rareData
); return m_rareData
->m_switchJumpTables
[tableIndex
]; } 
 378     size_t numberOfStringSwitchJumpTables() const { return m_rareData 
? m_rareData
->m_stringSwitchJumpTables
.size() : 0; } 
 379     UnlinkedStringJumpTable
& addStringSwitchJumpTable() { createRareDataIfNecessary(); m_rareData
->m_stringSwitchJumpTables
.append(UnlinkedStringJumpTable()); return m_rareData
->m_stringSwitchJumpTables
.last(); } 
 380     UnlinkedStringJumpTable
& stringSwitchJumpTable(int tableIndex
) { ASSERT(m_rareData
); return m_rareData
->m_stringSwitchJumpTables
[tableIndex
]; } 
 382     unsigned addFunctionDecl(UnlinkedFunctionExecutable
* n
) 
 384         unsigned size 
= m_functionDecls
.size(); 
 385         m_functionDecls
.append(WriteBarrier
<UnlinkedFunctionExecutable
>()); 
 386         m_functionDecls
.last().set(*m_vm
, this, n
); 
 389     UnlinkedFunctionExecutable
* functionDecl(int index
) { return m_functionDecls
[index
].get(); } 
 390     size_t numberOfFunctionDecls() { return m_functionDecls
.size(); } 
 391     unsigned addFunctionExpr(UnlinkedFunctionExecutable
* n
) 
 393         unsigned size 
= m_functionExprs
.size(); 
 394         m_functionExprs
.append(WriteBarrier
<UnlinkedFunctionExecutable
>()); 
 395         m_functionExprs
.last().set(*m_vm
, this, n
); 
 398     UnlinkedFunctionExecutable
* functionExpr(int index
) { return m_functionExprs
[index
].get(); } 
 399     size_t numberOfFunctionExprs() { return m_functionExprs
.size(); } 
 401     // Exception handling support 
 402     size_t numberOfExceptionHandlers() const { return m_rareData 
? m_rareData
->m_exceptionHandlers
.size() : 0; } 
 403     void addExceptionHandler(const UnlinkedHandlerInfo
& hanler
) { createRareDataIfNecessary(); return m_rareData
->m_exceptionHandlers
.append(hanler
); } 
 404     UnlinkedHandlerInfo
& exceptionHandler(int index
) { ASSERT(m_rareData
); return m_rareData
->m_exceptionHandlers
[index
]; } 
 406     SymbolTable
* symbolTable() const { return m_symbolTable
.get(); } 
 407     void setSymbolTable(SymbolTable
* table
) { m_symbolTable
.set(*m_vm
, this, table
); } 
 409     VM
* vm() const { return m_vm
; } 
 411     UnlinkedArrayProfile 
addArrayProfile() { return m_arrayProfileCount
++; } 
 412     unsigned numberOfArrayProfiles() { return m_arrayProfileCount
; } 
 413     UnlinkedArrayAllocationProfile 
addArrayAllocationProfile() { return m_arrayAllocationProfileCount
++; } 
 414     unsigned numberOfArrayAllocationProfiles() { return m_arrayAllocationProfileCount
; } 
 415     UnlinkedObjectAllocationProfile 
addObjectAllocationProfile() { return m_objectAllocationProfileCount
++; } 
 416     unsigned numberOfObjectAllocationProfiles() { return m_objectAllocationProfileCount
; } 
 417     UnlinkedValueProfile 
addValueProfile() { return m_valueProfileCount
++; } 
 418     unsigned numberOfValueProfiles() { return m_valueProfileCount
; } 
 420     UnlinkedLLIntCallLinkInfo 
addLLIntCallLinkInfo() { return m_llintCallLinkInfoCount
++; } 
 421     unsigned numberOfLLintCallLinkInfos() { return m_llintCallLinkInfoCount
; } 
 423     CodeType 
codeType() const { return m_codeType
; } 
 425     VirtualRegister 
thisRegister() const { return m_thisRegister
; } 
 426     VirtualRegister 
activationRegister() const { return m_activationRegister
; } 
 427     bool hasActivationRegister() const { return m_activationRegister
.isValid(); } 
 429     void addPropertyAccessInstruction(unsigned propertyAccessInstruction
) 
 431         m_propertyAccessInstructions
.append(propertyAccessInstruction
); 
 434     size_t numberOfPropertyAccessInstructions() const { return m_propertyAccessInstructions
.size(); } 
 435     const Vector
<unsigned>& propertyAccessInstructions() const { return m_propertyAccessInstructions
; } 
 437     typedef Vector
<JSValue
> ConstantBuffer
; 
 439     size_t constantBufferCount() { ASSERT(m_rareData
); return m_rareData
->m_constantBuffers
.size(); } 
 440     unsigned addConstantBuffer(unsigned length
) 
 442         createRareDataIfNecessary(); 
 443         unsigned size 
= m_rareData
->m_constantBuffers
.size(); 
 444         m_rareData
->m_constantBuffers
.append(Vector
<JSValue
>(length
)); 
 448     const ConstantBuffer
& constantBuffer(unsigned index
) const 
 451         return m_rareData
->m_constantBuffers
[index
]; 
 454     ConstantBuffer
& constantBuffer(unsigned index
) 
 457         return m_rareData
->m_constantBuffers
[index
]; 
 460     bool hasRareData() const { return m_rareData
; } 
 462     int lineNumberForBytecodeOffset(unsigned bytecodeOffset
); 
 464     void expressionRangeForBytecodeOffset(unsigned bytecodeOffset
, int& divot
, 
 465         int& startOffset
, int& endOffset
, unsigned& line
, unsigned& column
); 
 467     void recordParse(CodeFeatures features
, bool hasCapturedVariables
, unsigned firstLine
, unsigned lineCount
, unsigned endColumn
) 
 469         m_features 
= features
; 
 470         m_hasCapturedVariables 
= hasCapturedVariables
; 
 471         m_firstLine 
= firstLine
; 
 472         m_lineCount 
= lineCount
; 
 473         // For the UnlinkedCodeBlock, startColumn is always 0. 
 474         m_endColumn 
= endColumn
; 
 477     CodeFeatures 
codeFeatures() const { return m_features
; } 
 478     bool hasCapturedVariables() const { return m_hasCapturedVariables
; } 
 479     unsigned firstLine() const { return m_firstLine
; } 
 480     unsigned lineCount() const { return m_lineCount
; } 
 481     ALWAYS_INLINE 
unsigned startColumn() const { return 0; } 
 482     unsigned endColumn() const { return m_endColumn
; } 
 484     void dumpExpressionRangeInfo(); // For debugging purpose only. 
 487     UnlinkedCodeBlock(VM
*, Structure
*, CodeType
, const ExecutableInfo
&); 
 488     ~UnlinkedCodeBlock(); 
 490     void finishCreation(VM
& vm
) 
 492         Base::finishCreation(vm
); 
 493         if (codeType() == GlobalCode
) 
 495         m_symbolTable
.set(vm
, this, SymbolTable::create(vm
)); 
 500     void createRareDataIfNecessary() 
 503             m_rareData 
= adoptPtr(new RareData
); 
 506     void getLineAndColumn(ExpressionRangeInfo
&, unsigned& line
, unsigned& column
); 
 508     std::unique_ptr
<UnlinkedInstructionStream
> m_unlinkedInstructions
; 
 513     VirtualRegister m_thisRegister
; 
 514     VirtualRegister m_argumentsRegister
; 
 515     VirtualRegister m_activationRegister
; 
 516     VirtualRegister m_globalObjectRegister
; 
 518     bool m_needsFullScopeChain 
: 1; 
 520     bool m_isNumericCompareFunction 
: 1; 
 521     bool m_isStrictMode 
: 1; 
 522     bool m_isConstructor 
: 1; 
 523     bool m_hasCapturedVariables 
: 1; 
 524     bool m_isBuiltinFunction 
: 1; 
 525     unsigned m_firstLine
; 
 526     unsigned m_lineCount
; 
 527     unsigned m_endColumn
; 
 529     CodeFeatures m_features
; 
 532     Vector
<unsigned> m_jumpTargets
; 
 535     Vector
<Identifier
> m_identifiers
; 
 536     Vector
<WriteBarrier
<Unknown
>> m_constantRegisters
; 
 537     typedef Vector
<WriteBarrier
<UnlinkedFunctionExecutable
>> FunctionExpressionVector
; 
 538     FunctionExpressionVector m_functionDecls
; 
 539     FunctionExpressionVector m_functionExprs
; 
 541     WriteBarrier
<SymbolTable
> m_symbolTable
; 
 543     Vector
<unsigned> m_propertyAccessInstructions
; 
 545 #if ENABLE(BYTECODE_COMMENTS) 
 546     Vector
<Comment
>  m_bytecodeComments
; 
 547     size_t m_bytecodeCommentIterator
; 
 550     unsigned m_arrayProfileCount
; 
 551     unsigned m_arrayAllocationProfileCount
; 
 552     unsigned m_objectAllocationProfileCount
; 
 553     unsigned m_valueProfileCount
; 
 554     unsigned m_llintCallLinkInfoCount
; 
 558         WTF_MAKE_FAST_ALLOCATED
; 
 560         Vector
<UnlinkedHandlerInfo
> m_exceptionHandlers
; 
 563         Vector
<WriteBarrier
<RegExp
>> m_regexps
; 
 565         // Buffers used for large array literals 
 566         Vector
<ConstantBuffer
> m_constantBuffers
; 
 569         Vector
<UnlinkedSimpleJumpTable
> m_switchJumpTables
; 
 570         Vector
<UnlinkedStringJumpTable
> m_stringSwitchJumpTables
; 
 572         Vector
<ExpressionRangeInfo::FatPosition
> m_expressionInfoFatPositions
; 
 576     OwnPtr
<RareData
> m_rareData
; 
 577     Vector
<ExpressionRangeInfo
> m_expressionInfo
; 
 581     static const unsigned StructureFlags 
= OverridesVisitChildren 
| StructureIsImmortal 
| Base::StructureFlags
; 
 582     static void visitChildren(JSCell
*, SlotVisitor
&); 
 588 class UnlinkedGlobalCodeBlock 
: public UnlinkedCodeBlock 
{ 
 590     typedef UnlinkedCodeBlock Base
; 
 593     UnlinkedGlobalCodeBlock(VM
* vm
, Structure
* structure
, CodeType codeType
, const ExecutableInfo
& info
) 
 594         : Base(vm
, structure
, codeType
, info
) 
 598     static const unsigned StructureFlags 
= OverridesVisitChildren 
| Base::StructureFlags
; 
 603 class UnlinkedProgramCodeBlock 
: public UnlinkedGlobalCodeBlock 
{ 
 605     friend class CodeCache
; 
 606     static UnlinkedProgramCodeBlock
* create(VM
* vm
, const ExecutableInfo
& info
) 
 608         UnlinkedProgramCodeBlock
* instance 
= new (NotNull
, allocateCell
<UnlinkedProgramCodeBlock
>(vm
->heap
)) UnlinkedProgramCodeBlock(vm
, vm
->unlinkedProgramCodeBlockStructure
.get(), info
); 
 609         instance
->finishCreation(*vm
); 
 614     typedef UnlinkedGlobalCodeBlock Base
; 
 615     static void destroy(JSCell
*); 
 617     void addFunctionDeclaration(VM
& vm
, const Identifier
& name
, UnlinkedFunctionExecutable
* functionExecutable
) 
 619         m_functionDeclarations
.append(std::make_pair(name
, WriteBarrier
<UnlinkedFunctionExecutable
>(vm
, this, functionExecutable
))); 
 622     void addVariableDeclaration(const Identifier
& name
, bool isConstant
) 
 624         m_varDeclarations
.append(std::make_pair(name
, isConstant
)); 
 627     typedef Vector
<std::pair
<Identifier
, bool>> VariableDeclations
; 
 628     typedef Vector
<std::pair
<Identifier
, WriteBarrier
<UnlinkedFunctionExecutable
>> > FunctionDeclations
; 
 630     const VariableDeclations
& variableDeclarations() const { return m_varDeclarations
; } 
 631     const FunctionDeclations
& functionDeclarations() const { return m_functionDeclarations
; } 
 633     static void visitChildren(JSCell
*, SlotVisitor
&); 
 636     UnlinkedProgramCodeBlock(VM
* vm
, Structure
* structure
, const ExecutableInfo
& info
) 
 637         : Base(vm
, structure
, GlobalCode
, info
) 
 641     VariableDeclations m_varDeclarations
; 
 642     FunctionDeclations m_functionDeclarations
; 
 645     static Structure
* createStructure(VM
& vm
, JSGlobalObject
* globalObject
, JSValue proto
) 
 647         return Structure::create(vm
, globalObject
, proto
, TypeInfo(UnlinkedProgramCodeBlockType
, StructureFlags
), info()); 
 650     static const unsigned StructureFlags 
= OverridesVisitChildren 
| Base::StructureFlags
; 
 655 class UnlinkedEvalCodeBlock 
: public UnlinkedGlobalCodeBlock 
{ 
 657     friend class CodeCache
; 
 659     static UnlinkedEvalCodeBlock
* create(VM
* vm
, const ExecutableInfo
& info
) 
 661         UnlinkedEvalCodeBlock
* instance 
= new (NotNull
, allocateCell
<UnlinkedEvalCodeBlock
>(vm
->heap
)) UnlinkedEvalCodeBlock(vm
, vm
->unlinkedEvalCodeBlockStructure
.get(), info
); 
 662         instance
->finishCreation(*vm
); 
 667     typedef UnlinkedGlobalCodeBlock Base
; 
 668     static void destroy(JSCell
*); 
 670     const Identifier
& variable(unsigned index
) { return m_variables
[index
]; } 
 671     unsigned numVariables() { return m_variables
.size(); } 
 672     void adoptVariables(Vector
<Identifier
, 0, UnsafeVectorOverflow
>& variables
) 
 674         ASSERT(m_variables
.isEmpty()); 
 675         m_variables
.swap(variables
); 
 679     UnlinkedEvalCodeBlock(VM
* vm
, Structure
* structure
, const ExecutableInfo
& info
) 
 680         : Base(vm
, structure
, EvalCode
, info
) 
 684     Vector
<Identifier
, 0, UnsafeVectorOverflow
> m_variables
; 
 687     static Structure
* createStructure(VM
& vm
, JSGlobalObject
* globalObject
, JSValue proto
) 
 689         return Structure::create(vm
, globalObject
, proto
, TypeInfo(UnlinkedEvalCodeBlockType
, StructureFlags
), info()); 
 692     static const unsigned StructureFlags 
= OverridesVisitChildren 
| Base::StructureFlags
; 
 697 class UnlinkedFunctionCodeBlock 
: public UnlinkedCodeBlock 
{ 
 699     static UnlinkedFunctionCodeBlock
* create(VM
* vm
, CodeType codeType
, const ExecutableInfo
& info
) 
 701         UnlinkedFunctionCodeBlock
* instance 
= new (NotNull
, allocateCell
<UnlinkedFunctionCodeBlock
>(vm
->heap
)) UnlinkedFunctionCodeBlock(vm
, vm
->unlinkedFunctionCodeBlockStructure
.get(), codeType
, info
); 
 702         instance
->finishCreation(*vm
); 
 706     typedef UnlinkedCodeBlock Base
; 
 707     static void destroy(JSCell
*); 
 710     UnlinkedFunctionCodeBlock(VM
* vm
, Structure
* structure
, CodeType codeType
, const ExecutableInfo
& info
) 
 711         : Base(vm
, structure
, codeType
, info
) 
 716     static Structure
* createStructure(VM
& vm
, JSGlobalObject
* globalObject
, JSValue proto
) 
 718         return Structure::create(vm
, globalObject
, proto
, TypeInfo(UnlinkedFunctionCodeBlockType
, StructureFlags
), info()); 
 721     static const unsigned StructureFlags 
= OverridesVisitChildren 
| Base::StructureFlags
; 
 728 #endif // UnlinkedCodeBlock_h