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