2 * Copyright (C) 2012, 2013 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 "CodeCache.h"
31 #include "CodeSpecializationKind.h"
33 #include "ExpressionRangeInfo.h"
34 #include "Identifier.h"
38 #include "ParserModes.h"
40 #include "SpecialPointer.h"
41 #include "SymbolTable.h"
43 #include <wtf/RefCountedArray.h>
44 #include <wtf/Vector.h>
49 class FunctionBodyNode
;
50 class FunctionExecutable
;
51 class FunctionParameters
;
54 class ScriptExecutable
;
57 class SharedSymbolTable
;
58 class UnlinkedCodeBlock
;
59 class UnlinkedFunctionCodeBlock
;
61 typedef unsigned UnlinkedValueProfile
;
62 typedef unsigned UnlinkedArrayProfile
;
63 typedef unsigned UnlinkedArrayAllocationProfile
;
64 typedef unsigned UnlinkedObjectAllocationProfile
;
65 typedef unsigned UnlinkedLLIntCallLinkInfo
;
67 struct ExecutableInfo
{
68 ExecutableInfo(bool needsActivation
, bool usesEval
, bool isStrictMode
, bool isConstructor
)
69 : m_needsActivation(needsActivation
)
70 , m_usesEval(usesEval
)
71 , m_isStrictMode(isStrictMode
)
72 , m_isConstructor(isConstructor
)
75 bool m_needsActivation
;
81 class UnlinkedFunctionExecutable
: public JSCell
{
83 friend class CodeCache
;
85 static UnlinkedFunctionExecutable
* create(VM
* vm
, const SourceCode
& source
, FunctionBodyNode
* node
)
87 UnlinkedFunctionExecutable
* instance
= new (NotNull
, allocateCell
<UnlinkedFunctionExecutable
>(vm
->heap
)) UnlinkedFunctionExecutable(vm
, vm
->unlinkedFunctionExecutableStructure
.get(), source
, node
);
88 instance
->finishCreation(*vm
);
92 const Identifier
& name() const { return m_name
; }
93 const Identifier
& inferredName() const { return m_inferredName
; }
94 JSString
* nameValue() const { return m_nameValue
.get(); }
95 SharedSymbolTable
* symbolTable(CodeSpecializationKind kind
)
97 return (kind
== CodeForCall
) ? m_symbolTableForCall
.get() : m_symbolTableForConstruct
.get();
99 size_t parameterCount() const;
100 bool isInStrictContext() const { return m_isInStrictContext
; }
101 FunctionNameIsInScopeToggle
functionNameIsInScopeToggle() const { return m_functionNameIsInScopeToggle
; }
103 unsigned firstLineOffset() const { return m_firstLineOffset
; }
104 unsigned lineCount() const { return m_lineCount
; }
105 unsigned functionStartOffset() const { return m_functionStartOffset
; }
106 unsigned functionStartColumn() const { return m_functionStartColumn
; }
107 unsigned startOffset() const { return m_startOffset
; }
108 unsigned sourceLength() { return m_sourceLength
; }
110 String
paramString() const;
112 UnlinkedFunctionCodeBlock
* codeBlockFor(VM
&, JSScope
*, const SourceCode
&, CodeSpecializationKind
, DebuggerMode
, ProfilerMode
, ParserError
&);
114 static UnlinkedFunctionExecutable
* fromGlobalCode(const Identifier
&, ExecState
*, Debugger
*, const SourceCode
&, JSObject
** exception
);
116 FunctionExecutable
* link(VM
&, const SourceCode
&, size_t lineOffset
, size_t sourceOffset
);
118 void clearCodeForRecompilation()
120 m_symbolTableForCall
.clear();
121 m_symbolTableForConstruct
.clear();
122 m_codeBlockForCall
.clear();
123 m_codeBlockForConstruct
.clear();
126 FunctionParameters
* parameters() { return m_parameters
.get(); }
128 void recordParse(CodeFeatures features
, bool hasCapturedVariables
, int firstLine
, int lastLine
)
130 m_features
= features
;
131 m_hasCapturedVariables
= hasCapturedVariables
;
132 m_lineCount
= lastLine
- firstLine
;
135 bool forceUsesArguments() const { return m_forceUsesArguments
; }
137 CodeFeatures
features() const { return m_features
; }
138 bool hasCapturedVariables() const { return m_hasCapturedVariables
; }
140 static const bool needsDestruction
= true;
141 static const bool hasImmortalStructure
= true;
142 static void destroy(JSCell
*);
145 UnlinkedFunctionExecutable(VM
*, Structure
*, const SourceCode
&, FunctionBodyNode
*);
146 WriteBarrier
<UnlinkedFunctionCodeBlock
> m_codeBlockForCall
;
147 WriteBarrier
<UnlinkedFunctionCodeBlock
> m_codeBlockForConstruct
;
149 unsigned m_numCapturedVariables
: 29;
150 bool m_forceUsesArguments
: 1;
151 bool m_isInStrictContext
: 1;
152 bool m_hasCapturedVariables
: 1;
155 Identifier m_inferredName
;
156 WriteBarrier
<JSString
> m_nameValue
;
157 WriteBarrier
<SharedSymbolTable
> m_symbolTableForCall
;
158 WriteBarrier
<SharedSymbolTable
> m_symbolTableForConstruct
;
159 RefPtr
<FunctionParameters
> m_parameters
;
160 unsigned m_firstLineOffset
;
161 unsigned m_lineCount
;
162 unsigned m_functionStartOffset
;
163 unsigned m_functionStartColumn
;
164 unsigned m_startOffset
;
165 unsigned m_sourceLength
;
167 CodeFeatures m_features
;
169 FunctionNameIsInScopeToggle m_functionNameIsInScopeToggle
;
172 void finishCreation(VM
& vm
)
174 Base::finishCreation(vm
);
175 m_nameValue
.set(vm
, this, jsString(&vm
, name().string()));
178 static void visitChildren(JSCell
*, SlotVisitor
&);
181 static Structure
* createStructure(VM
& vm
, JSGlobalObject
* globalObject
, JSValue proto
)
183 return Structure::create(vm
, globalObject
, proto
, TypeInfo(UnlinkedFunctionExecutableType
, StructureFlags
), &s_info
);
186 static const unsigned StructureFlags
= OverridesVisitChildren
| JSCell::StructureFlags
;
188 static const ClassInfo s_info
;
191 struct UnlinkedStringJumpTable
{
192 typedef HashMap
<RefPtr
<StringImpl
>, int32_t> StringOffsetTable
;
193 StringOffsetTable offsetTable
;
195 inline int32_t offsetForValue(StringImpl
* value
, int32_t defaultOffset
)
197 StringOffsetTable::const_iterator end
= offsetTable
.end();
198 StringOffsetTable::const_iterator loc
= offsetTable
.find(value
);
200 return defaultOffset
;
206 struct UnlinkedSimpleJumpTable
{
207 Vector
<int32_t> branchOffsets
;
210 int32_t offsetForValue(int32_t value
, int32_t defaultOffset
);
211 void add(int32_t key
, int32_t offset
)
213 if (!branchOffsets
[key
])
214 branchOffsets
[key
] = offset
;
218 struct UnlinkedHandlerInfo
{
225 struct UnlinkedInstruction
{
226 UnlinkedInstruction() { u
.operand
= 0; }
227 UnlinkedInstruction(OpcodeID opcode
) { u
.opcode
= opcode
; }
228 UnlinkedInstruction(int operand
) { u
.operand
= operand
; }
235 class UnlinkedCodeBlock
: public JSCell
{
238 static const bool needsDestruction
= true;
239 static const bool hasImmortalStructure
= true;
241 enum { CallFunction
, ApplyFunction
};
243 bool isConstructor() const { return m_isConstructor
; }
244 bool isStrictMode() const { return m_isStrictMode
; }
245 bool usesEval() const { return m_usesEval
; }
247 bool needsFullScopeChain() const { return m_needsFullScopeChain
; }
248 void setNeedsFullScopeChain(bool needsFullScopeChain
) { m_needsFullScopeChain
= needsFullScopeChain
; }
250 void addExpressionInfo(unsigned instructionOffset
, int divot
,
251 int startOffset
, int endOffset
, unsigned line
, unsigned column
);
253 bool hasExpressionInfo() { return m_expressionInfo
.size(); }
256 void setThisRegister(int thisRegister
) { m_thisRegister
= thisRegister
; }
257 void setActivationRegister(int activationRegister
) { m_activationRegister
= activationRegister
; }
259 void setArgumentsRegister(int argumentsRegister
) { m_argumentsRegister
= argumentsRegister
; }
260 bool usesArguments() const { return m_argumentsRegister
!= -1; }
261 int argumentsRegister() const { return m_argumentsRegister
; }
264 bool usesGlobalObject() const { return m_globalObjectRegister
!= -1; }
265 void setGlobalObjectRegister(int globalObjectRegister
) { m_globalObjectRegister
= globalObjectRegister
; }
266 int globalObjectRegister() const { return m_globalObjectRegister
; }
268 // Parameter information
269 void setNumParameters(int newValue
) { m_numParameters
= newValue
; }
270 void addParameter() { m_numParameters
++; }
271 unsigned numParameters() const { return m_numParameters
; }
273 unsigned addRegExp(RegExp
* r
)
275 createRareDataIfNecessary();
276 unsigned size
= m_rareData
->m_regexps
.size();
277 m_rareData
->m_regexps
.append(WriteBarrier
<RegExp
>(*m_vm
, this, r
));
280 unsigned numberOfRegExps() const
284 return m_rareData
->m_regexps
.size();
286 RegExp
* regexp(int index
) const { ASSERT(m_rareData
); return m_rareData
->m_regexps
[index
].get(); }
290 size_t numberOfIdentifiers() const { return m_identifiers
.size(); }
291 void addIdentifier(const Identifier
& i
) { return m_identifiers
.append(i
); }
292 const Identifier
& identifier(int index
) const { return m_identifiers
[index
]; }
293 const Vector
<Identifier
>& identifiers() const { return m_identifiers
; }
295 size_t numberOfConstantRegisters() const { return m_constantRegisters
.size(); }
296 unsigned addConstant(JSValue v
)
298 unsigned result
= m_constantRegisters
.size();
299 m_constantRegisters
.append(WriteBarrier
<Unknown
>());
300 m_constantRegisters
.last().set(*m_vm
, this, v
);
303 unsigned addOrFindConstant(JSValue
);
304 const Vector
<WriteBarrier
<Unknown
> >& constantRegisters() { return m_constantRegisters
; }
305 const WriteBarrier
<Unknown
>& constantRegister(int index
) const { return m_constantRegisters
[index
- FirstConstantRegisterIndex
]; }
306 ALWAYS_INLINE
bool isConstantRegisterIndex(int index
) const { return index
>= FirstConstantRegisterIndex
; }
307 ALWAYS_INLINE JSValue
getConstant(int index
) const { return m_constantRegisters
[index
- FirstConstantRegisterIndex
].get(); }
310 size_t numberOfJumpTargets() const { return m_jumpTargets
.size(); }
311 void addJumpTarget(unsigned jumpTarget
) { m_jumpTargets
.append(jumpTarget
); }
312 unsigned jumpTarget(int index
) const { return m_jumpTargets
[index
]; }
313 unsigned lastJumpTarget() const { return m_jumpTargets
.last(); }
315 void setIsNumericCompareFunction(bool isNumericCompareFunction
) { m_isNumericCompareFunction
= isNumericCompareFunction
; }
316 bool isNumericCompareFunction() const { return m_isNumericCompareFunction
; }
320 m_jumpTargets
.shrinkToFit();
321 m_identifiers
.shrinkToFit();
322 m_constantRegisters
.shrinkToFit();
323 m_functionDecls
.shrinkToFit();
324 m_functionExprs
.shrinkToFit();
325 m_propertyAccessInstructions
.shrinkToFit();
326 m_expressionInfo
.shrinkToFit();
328 #if ENABLE(BYTECODE_COMMENTS)
329 m_bytecodeComments
.shrinkToFit();
332 m_rareData
->m_exceptionHandlers
.shrinkToFit();
333 m_rareData
->m_regexps
.shrinkToFit();
334 m_rareData
->m_constantBuffers
.shrinkToFit();
335 m_rareData
->m_immediateSwitchJumpTables
.shrinkToFit();
336 m_rareData
->m_characterSwitchJumpTables
.shrinkToFit();
337 m_rareData
->m_stringSwitchJumpTables
.shrinkToFit();
338 m_rareData
->m_expressionInfoFatPositions
.shrinkToFit();
342 unsigned numberOfInstructions() const { return m_unlinkedInstructions
.size(); }
343 RefCountedArray
<UnlinkedInstruction
>& instructions() { return m_unlinkedInstructions
; }
344 const RefCountedArray
<UnlinkedInstruction
>& instructions() const { return m_unlinkedInstructions
; }
347 int m_numCapturedVars
;
348 int m_numCalleeRegisters
;
352 size_t numberOfImmediateSwitchJumpTables() const { return m_rareData
? m_rareData
->m_immediateSwitchJumpTables
.size() : 0; }
353 UnlinkedSimpleJumpTable
& addImmediateSwitchJumpTable() { createRareDataIfNecessary(); m_rareData
->m_immediateSwitchJumpTables
.append(UnlinkedSimpleJumpTable()); return m_rareData
->m_immediateSwitchJumpTables
.last(); }
354 UnlinkedSimpleJumpTable
& immediateSwitchJumpTable(int tableIndex
) { ASSERT(m_rareData
); return m_rareData
->m_immediateSwitchJumpTables
[tableIndex
]; }
356 size_t numberOfCharacterSwitchJumpTables() const { return m_rareData
? m_rareData
->m_characterSwitchJumpTables
.size() : 0; }
357 UnlinkedSimpleJumpTable
& addCharacterSwitchJumpTable() { createRareDataIfNecessary(); m_rareData
->m_characterSwitchJumpTables
.append(UnlinkedSimpleJumpTable()); return m_rareData
->m_characterSwitchJumpTables
.last(); }
358 UnlinkedSimpleJumpTable
& characterSwitchJumpTable(int tableIndex
) { ASSERT(m_rareData
); return m_rareData
->m_characterSwitchJumpTables
[tableIndex
]; }
360 size_t numberOfStringSwitchJumpTables() const { return m_rareData
? m_rareData
->m_stringSwitchJumpTables
.size() : 0; }
361 UnlinkedStringJumpTable
& addStringSwitchJumpTable() { createRareDataIfNecessary(); m_rareData
->m_stringSwitchJumpTables
.append(UnlinkedStringJumpTable()); return m_rareData
->m_stringSwitchJumpTables
.last(); }
362 UnlinkedStringJumpTable
& stringSwitchJumpTable(int tableIndex
) { ASSERT(m_rareData
); return m_rareData
->m_stringSwitchJumpTables
[tableIndex
]; }
364 unsigned addFunctionDecl(UnlinkedFunctionExecutable
* n
)
366 unsigned size
= m_functionDecls
.size();
367 m_functionDecls
.append(WriteBarrier
<UnlinkedFunctionExecutable
>());
368 m_functionDecls
.last().set(*m_vm
, this, n
);
371 UnlinkedFunctionExecutable
* functionDecl(int index
) { return m_functionDecls
[index
].get(); }
372 size_t numberOfFunctionDecls() { return m_functionDecls
.size(); }
373 unsigned addFunctionExpr(UnlinkedFunctionExecutable
* n
)
375 unsigned size
= m_functionExprs
.size();
376 m_functionExprs
.append(WriteBarrier
<UnlinkedFunctionExecutable
>());
377 m_functionExprs
.last().set(*m_vm
, this, n
);
380 UnlinkedFunctionExecutable
* functionExpr(int index
) { return m_functionExprs
[index
].get(); }
381 size_t numberOfFunctionExprs() { return m_functionExprs
.size(); }
383 // Exception handling support
384 size_t numberOfExceptionHandlers() const { return m_rareData
? m_rareData
->m_exceptionHandlers
.size() : 0; }
385 void addExceptionHandler(const UnlinkedHandlerInfo
& hanler
) { createRareDataIfNecessary(); return m_rareData
->m_exceptionHandlers
.append(hanler
); }
386 UnlinkedHandlerInfo
& exceptionHandler(int index
) { ASSERT(m_rareData
); return m_rareData
->m_exceptionHandlers
[index
]; }
388 SharedSymbolTable
* symbolTable() const { return m_symbolTable
.get(); }
390 VM
* vm() const { return m_vm
; }
392 unsigned addResolve() { return m_resolveOperationCount
++; }
393 unsigned numberOfResolveOperations() const { return m_resolveOperationCount
; }
394 unsigned addPutToBase() { return m_putToBaseOperationCount
++; }
395 unsigned numberOfPutToBaseOperations() const { return m_putToBaseOperationCount
; }
397 UnlinkedArrayProfile
addArrayProfile() { return m_arrayProfileCount
++; }
398 unsigned numberOfArrayProfiles() { return m_arrayProfileCount
; }
399 UnlinkedArrayAllocationProfile
addArrayAllocationProfile() { return m_arrayAllocationProfileCount
++; }
400 unsigned numberOfArrayAllocationProfiles() { return m_arrayAllocationProfileCount
; }
401 UnlinkedObjectAllocationProfile
addObjectAllocationProfile() { return m_objectAllocationProfileCount
++; }
402 unsigned numberOfObjectAllocationProfiles() { return m_objectAllocationProfileCount
; }
403 UnlinkedValueProfile
addValueProfile() { return m_valueProfileCount
++; }
404 unsigned numberOfValueProfiles() { return m_valueProfileCount
; }
406 UnlinkedLLIntCallLinkInfo
addLLIntCallLinkInfo() { return m_llintCallLinkInfoCount
++; }
407 unsigned numberOfLLintCallLinkInfos() { return m_llintCallLinkInfoCount
; }
409 CodeType
codeType() const { return m_codeType
; }
411 int thisRegister() const { return m_thisRegister
; }
412 int activationRegister() const { return m_activationRegister
; }
415 void addPropertyAccessInstruction(unsigned propertyAccessInstruction
)
417 m_propertyAccessInstructions
.append(propertyAccessInstruction
);
420 size_t numberOfPropertyAccessInstructions() const { return m_propertyAccessInstructions
.size(); }
421 const Vector
<unsigned>& propertyAccessInstructions() const { return m_propertyAccessInstructions
; }
423 typedef Vector
<JSValue
> ConstantBuffer
;
425 size_t constantBufferCount() { ASSERT(m_rareData
); return m_rareData
->m_constantBuffers
.size(); }
426 unsigned addConstantBuffer(unsigned length
)
428 createRareDataIfNecessary();
429 unsigned size
= m_rareData
->m_constantBuffers
.size();
430 m_rareData
->m_constantBuffers
.append(Vector
<JSValue
>(length
));
434 const ConstantBuffer
& constantBuffer(unsigned index
) const
437 return m_rareData
->m_constantBuffers
[index
];
440 ConstantBuffer
& constantBuffer(unsigned index
)
443 return m_rareData
->m_constantBuffers
[index
];
446 bool hasRareData() const { return m_rareData
; }
448 int lineNumberForBytecodeOffset(unsigned bytecodeOffset
);
450 void expressionRangeForBytecodeOffset(unsigned bytecodeOffset
, int& divot
,
451 int& startOffset
, int& endOffset
, unsigned& line
, unsigned& column
);
453 void recordParse(CodeFeatures features
, bool hasCapturedVariables
, unsigned firstLine
, unsigned lineCount
)
455 m_features
= features
;
456 m_hasCapturedVariables
= hasCapturedVariables
;
457 m_firstLine
= firstLine
;
458 m_lineCount
= lineCount
;
461 CodeFeatures
codeFeatures() const { return m_features
; }
462 bool hasCapturedVariables() const { return m_hasCapturedVariables
; }
463 unsigned firstLine() const { return m_firstLine
; }
464 unsigned lineCount() const { return m_lineCount
; }
466 PassRefPtr
<CodeCache
> codeCacheForEval()
468 if (m_codeType
== GlobalCode
)
469 return m_vm
->codeCache();
470 createRareDataIfNecessary();
471 if (!m_rareData
->m_evalCodeCache
)
472 m_rareData
->m_evalCodeCache
= CodeCache::create(CodeCache::NonGlobalCodeCache
);
473 return m_rareData
->m_evalCodeCache
.get();
477 UnlinkedCodeBlock(VM
*, Structure
*, CodeType
, const ExecutableInfo
&);
478 ~UnlinkedCodeBlock();
480 void finishCreation(VM
& vm
)
482 Base::finishCreation(vm
);
483 if (codeType() == GlobalCode
)
485 m_symbolTable
.set(vm
, this, SharedSymbolTable::create(vm
));
490 void createRareDataIfNecessary()
493 m_rareData
= adoptPtr(new RareData
);
496 RefCountedArray
<UnlinkedInstruction
> m_unlinkedInstructions
;
502 int m_argumentsRegister
;
503 int m_activationRegister
;
504 int m_globalObjectRegister
;
506 bool m_needsFullScopeChain
: 1;
508 bool m_isNumericCompareFunction
: 1;
509 bool m_isStrictMode
: 1;
510 bool m_isConstructor
: 1;
511 bool m_hasCapturedVariables
: 1;
512 unsigned m_firstLine
;
513 unsigned m_lineCount
;
515 CodeFeatures m_features
;
518 Vector
<unsigned> m_jumpTargets
;
521 Vector
<Identifier
> m_identifiers
;
522 Vector
<WriteBarrier
<Unknown
> > m_constantRegisters
;
523 typedef Vector
<WriteBarrier
<UnlinkedFunctionExecutable
> > FunctionExpressionVector
;
524 FunctionExpressionVector m_functionDecls
;
525 FunctionExpressionVector m_functionExprs
;
527 WriteBarrier
<SharedSymbolTable
> m_symbolTable
;
529 Vector
<unsigned> m_propertyAccessInstructions
;
531 #if ENABLE(BYTECODE_COMMENTS)
532 Vector
<Comment
> m_bytecodeComments
;
533 size_t m_bytecodeCommentIterator
;
536 unsigned m_resolveOperationCount
;
537 unsigned m_putToBaseOperationCount
;
538 unsigned m_arrayProfileCount
;
539 unsigned m_arrayAllocationProfileCount
;
540 unsigned m_objectAllocationProfileCount
;
541 unsigned m_valueProfileCount
;
542 unsigned m_llintCallLinkInfoCount
;
546 WTF_MAKE_FAST_ALLOCATED
;
548 Vector
<UnlinkedHandlerInfo
> m_exceptionHandlers
;
551 Vector
<WriteBarrier
<RegExp
> > m_regexps
;
553 // Buffers used for large array literals
554 Vector
<ConstantBuffer
> m_constantBuffers
;
557 Vector
<UnlinkedSimpleJumpTable
> m_immediateSwitchJumpTables
;
558 Vector
<UnlinkedSimpleJumpTable
> m_characterSwitchJumpTables
;
559 Vector
<UnlinkedStringJumpTable
> m_stringSwitchJumpTables
;
560 RefPtr
<CodeCache
> m_evalCodeCache
;
562 Vector
<ExpressionRangeInfo::FatPosition
> m_expressionInfoFatPositions
;
566 OwnPtr
<RareData
> m_rareData
;
567 Vector
<ExpressionRangeInfo
> m_expressionInfo
;
571 static const unsigned StructureFlags
= OverridesVisitChildren
| Base::StructureFlags
;
572 static void visitChildren(JSCell
*, SlotVisitor
&);
575 static const ClassInfo s_info
;
578 class UnlinkedGlobalCodeBlock
: public UnlinkedCodeBlock
{
580 typedef UnlinkedCodeBlock Base
;
583 UnlinkedGlobalCodeBlock(VM
* vm
, Structure
* structure
, CodeType codeType
, const ExecutableInfo
& info
)
584 : Base(vm
, structure
, codeType
, info
)
588 static const unsigned StructureFlags
= OverridesVisitChildren
| Base::StructureFlags
;
590 static const ClassInfo s_info
;
593 class UnlinkedProgramCodeBlock
: public UnlinkedGlobalCodeBlock
{
595 friend class CodeCache
;
596 static UnlinkedProgramCodeBlock
* create(VM
* vm
, const ExecutableInfo
& info
)
598 UnlinkedProgramCodeBlock
* instance
= new (NotNull
, allocateCell
<UnlinkedProgramCodeBlock
>(vm
->heap
)) UnlinkedProgramCodeBlock(vm
, vm
->unlinkedProgramCodeBlockStructure
.get(), info
);
599 instance
->finishCreation(*vm
);
604 typedef UnlinkedGlobalCodeBlock Base
;
605 static void destroy(JSCell
*);
607 void addFunctionDeclaration(VM
& vm
, const Identifier
& name
, UnlinkedFunctionExecutable
* functionExecutable
)
609 m_functionDeclarations
.append(std::make_pair(name
, WriteBarrier
<UnlinkedFunctionExecutable
>(vm
, this, functionExecutable
)));
612 void addVariableDeclaration(const Identifier
& name
, bool isConstant
)
614 m_varDeclarations
.append(std::make_pair(name
, isConstant
));
617 typedef Vector
<std::pair
<Identifier
, bool> > VariableDeclations
;
618 typedef Vector
<std::pair
<Identifier
, WriteBarrier
<UnlinkedFunctionExecutable
> > > FunctionDeclations
;
620 const VariableDeclations
& variableDeclarations() const { return m_varDeclarations
; }
621 const FunctionDeclations
& functionDeclarations() const { return m_functionDeclarations
; }
623 static void visitChildren(JSCell
*, SlotVisitor
&);
626 UnlinkedProgramCodeBlock(VM
* vm
, Structure
* structure
, const ExecutableInfo
& info
)
627 : Base(vm
, structure
, GlobalCode
, info
)
631 VariableDeclations m_varDeclarations
;
632 FunctionDeclations m_functionDeclarations
;
635 static Structure
* createStructure(VM
& vm
, JSGlobalObject
* globalObject
, JSValue proto
)
637 return Structure::create(vm
, globalObject
, proto
, TypeInfo(UnlinkedProgramCodeBlockType
, StructureFlags
), &s_info
);
640 static const unsigned StructureFlags
= OverridesVisitChildren
| Base::StructureFlags
;
642 static const ClassInfo s_info
;
645 class UnlinkedEvalCodeBlock
: public UnlinkedGlobalCodeBlock
{
647 friend class CodeCache
;
649 static UnlinkedEvalCodeBlock
* create(VM
* vm
, const ExecutableInfo
& info
)
651 UnlinkedEvalCodeBlock
* instance
= new (NotNull
, allocateCell
<UnlinkedEvalCodeBlock
>(vm
->heap
)) UnlinkedEvalCodeBlock(vm
, vm
->unlinkedEvalCodeBlockStructure
.get(), info
);
652 instance
->finishCreation(*vm
);
657 typedef UnlinkedGlobalCodeBlock Base
;
658 static void destroy(JSCell
*);
660 const Identifier
& variable(unsigned index
) { return m_variables
[index
]; }
661 unsigned numVariables() { return m_variables
.size(); }
662 void adoptVariables(Vector
<Identifier
, 0, UnsafeVectorOverflow
>& variables
)
664 ASSERT(m_variables
.isEmpty());
665 m_variables
.swap(variables
);
669 UnlinkedEvalCodeBlock(VM
* vm
, Structure
* structure
, const ExecutableInfo
& info
)
670 : Base(vm
, structure
, EvalCode
, info
)
674 Vector
<Identifier
, 0, UnsafeVectorOverflow
> m_variables
;
677 static Structure
* createStructure(VM
& vm
, JSGlobalObject
* globalObject
, JSValue proto
)
679 return Structure::create(vm
, globalObject
, proto
, TypeInfo(UnlinkedEvalCodeBlockType
, StructureFlags
), &s_info
);
682 static const unsigned StructureFlags
= OverridesVisitChildren
| Base::StructureFlags
;
684 static const ClassInfo s_info
;
687 class UnlinkedFunctionCodeBlock
: public UnlinkedCodeBlock
{
689 static UnlinkedFunctionCodeBlock
* create(VM
* vm
, CodeType codeType
, const ExecutableInfo
& info
)
691 UnlinkedFunctionCodeBlock
* instance
= new (NotNull
, allocateCell
<UnlinkedFunctionCodeBlock
>(vm
->heap
)) UnlinkedFunctionCodeBlock(vm
, vm
->unlinkedFunctionCodeBlockStructure
.get(), codeType
, info
);
692 instance
->finishCreation(*vm
);
696 typedef UnlinkedCodeBlock Base
;
697 static void destroy(JSCell
*);
700 UnlinkedFunctionCodeBlock(VM
* vm
, Structure
* structure
, CodeType codeType
, const ExecutableInfo
& info
)
701 : Base(vm
, structure
, codeType
, info
)
706 static Structure
* createStructure(VM
& vm
, JSGlobalObject
* globalObject
, JSValue proto
)
708 return Structure::create(vm
, globalObject
, proto
, TypeInfo(UnlinkedFunctionCodeBlockType
, StructureFlags
), &s_info
);
711 static const unsigned StructureFlags
= OverridesVisitChildren
| Base::StructureFlags
;
713 static const ClassInfo s_info
;
718 #endif // UnlinkedCodeBlock_h