2 * Copyright (C) 2012-2015 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 "HandlerInfo.h"
34 #include "Identifier.h"
37 #include "ParserModes.h"
39 #include "SpecialPointer.h"
40 #include "SymbolTable.h"
41 #include "VirtualRegister.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
, ConstructorKind constructorKind
)
70 : m_needsActivation(needsActivation
)
71 , m_usesEval(usesEval
)
72 , m_isStrictMode(isStrictMode
)
73 , m_isConstructor(isConstructor
)
74 , m_isBuiltinFunction(isBuiltinFunction
)
75 , m_constructorKind(static_cast<unsigned>(constructorKind
))
77 ASSERT(m_constructorKind
== static_cast<unsigned>(constructorKind
));
80 bool needsActivation() const { return m_needsActivation
; }
81 bool usesEval() const { return m_usesEval
; }
82 bool isStrictMode() const { return m_isStrictMode
; }
83 bool isConstructor() const { return m_isConstructor
; }
84 bool isBuiltinFunction() const { return m_isBuiltinFunction
; }
85 ConstructorKind
constructorKind() const { return static_cast<ConstructorKind
>(m_constructorKind
); }
88 unsigned m_needsActivation
: 1;
89 unsigned m_usesEval
: 1;
90 unsigned m_isStrictMode
: 1;
91 unsigned m_isConstructor
: 1;
92 unsigned m_isBuiltinFunction
: 1;
93 unsigned m_constructorKind
: 2;
96 enum UnlinkedFunctionKind
{
97 UnlinkedNormalFunction
,
98 UnlinkedBuiltinFunction
,
101 class UnlinkedFunctionExecutable final
: public JSCell
{
103 friend class BuiltinExecutables
;
104 friend class CodeCache
;
108 static const unsigned StructureFlags
= Base::StructureFlags
| StructureIsImmortal
;
110 static UnlinkedFunctionExecutable
* create(VM
* vm
, const SourceCode
& source
, FunctionBodyNode
* node
, UnlinkedFunctionKind unlinkedFunctionKind
, RefPtr
<SourceProvider
>&& sourceOverride
= nullptr)
112 UnlinkedFunctionExecutable
* instance
= new (NotNull
, allocateCell
<UnlinkedFunctionExecutable
>(vm
->heap
))
113 UnlinkedFunctionExecutable(vm
, vm
->unlinkedFunctionExecutableStructure
.get(), source
, WTF::move(sourceOverride
), node
, unlinkedFunctionKind
);
114 instance
->finishCreation(*vm
);
118 const Identifier
& name() const { return m_name
; }
119 const Identifier
& inferredName() const { return m_inferredName
; }
120 JSString
* nameValue() const { return m_nameValue
.get(); }
121 SymbolTable
* symbolTable(CodeSpecializationKind kind
)
123 return (kind
== CodeForCall
) ? m_symbolTableForCall
.get() : m_symbolTableForConstruct
.get();
125 size_t parameterCount() const;
126 bool isInStrictContext() const { return m_isInStrictContext
; }
127 FunctionMode
functionMode() const { return static_cast<FunctionMode
>(m_functionMode
); }
128 ConstructorKind
constructorKind() const { return static_cast<ConstructorKind
>(m_constructorKind
); }
130 unsigned unlinkedFunctionNameStart() const { return m_unlinkedFunctionNameStart
; }
131 unsigned unlinkedBodyStartColumn() const { return m_unlinkedBodyStartColumn
; }
132 unsigned unlinkedBodyEndColumn() const { return m_unlinkedBodyEndColumn
; }
133 unsigned startOffset() const { return m_startOffset
; }
134 unsigned sourceLength() { return m_sourceLength
; }
135 unsigned parametersStartOffset() const { return m_parametersStartOffset
; }
136 unsigned typeProfilingStartOffset() const { return m_typeProfilingStartOffset
; }
137 unsigned typeProfilingEndOffset() const { return m_typeProfilingEndOffset
; }
139 UnlinkedFunctionCodeBlock
* codeBlockFor(
140 VM
&, const SourceCode
&, CodeSpecializationKind
, DebuggerMode
, ProfilerMode
,
143 static UnlinkedFunctionExecutable
* fromGlobalCode(
144 const Identifier
&, ExecState
&, const SourceCode
&, JSObject
*& exception
,
145 int overrideLineNumber
);
147 FunctionExecutable
* link(VM
&, const SourceCode
&, int overrideLineNumber
= -1);
149 void clearCodeForRecompilation()
151 m_symbolTableForCall
.clear();
152 m_symbolTableForConstruct
.clear();
153 m_codeBlockForCall
.clear();
154 m_codeBlockForConstruct
.clear();
157 FunctionParameters
* parameters() { return m_parameters
.get(); }
159 void recordParse(CodeFeatures features
, bool hasCapturedVariables
)
161 m_features
= features
;
162 m_hasCapturedVariables
= hasCapturedVariables
;
165 CodeFeatures
features() const { return m_features
; }
166 bool hasCapturedVariables() const { return m_hasCapturedVariables
; }
168 static const bool needsDestruction
= true;
169 static void destroy(JSCell
*);
171 bool isBuiltinFunction() const { return m_isBuiltinFunction
; }
172 bool isClassConstructorFunction() const { return constructorKind() != ConstructorKind::None
; }
175 UnlinkedFunctionExecutable(VM
*, Structure
*, const SourceCode
&, RefPtr
<SourceProvider
>&& sourceOverride
, FunctionBodyNode
*, UnlinkedFunctionKind
);
176 WriteBarrier
<UnlinkedFunctionCodeBlock
> m_codeBlockForCall
;
177 WriteBarrier
<UnlinkedFunctionCodeBlock
> m_codeBlockForConstruct
;
180 Identifier m_inferredName
;
181 WriteBarrier
<JSString
> m_nameValue
;
182 WriteBarrier
<SymbolTable
> m_symbolTableForCall
;
183 WriteBarrier
<SymbolTable
> m_symbolTableForConstruct
;
184 RefPtr
<FunctionParameters
> m_parameters
;
185 RefPtr
<SourceProvider
> m_sourceOverride
;
186 unsigned m_firstLineOffset
;
187 unsigned m_lineCount
;
188 unsigned m_unlinkedFunctionNameStart
;
189 unsigned m_unlinkedBodyStartColumn
;
190 unsigned m_unlinkedBodyEndColumn
;
191 unsigned m_startOffset
;
192 unsigned m_sourceLength
;
193 unsigned m_parametersStartOffset
;
194 unsigned m_typeProfilingStartOffset
;
195 unsigned m_typeProfilingEndOffset
;
197 CodeFeatures m_features
;
199 unsigned m_isInStrictContext
: 1;
200 unsigned m_hasCapturedVariables
: 1;
201 unsigned m_isBuiltinFunction
: 1;
202 unsigned m_constructorKind
: 2;
203 unsigned m_functionMode
: 1; // FunctionMode
206 void finishCreation(VM
& vm
)
208 Base::finishCreation(vm
);
209 m_nameValue
.set(vm
, this, jsString(&vm
, name().string()));
212 static void visitChildren(JSCell
*, SlotVisitor
&);
215 static Structure
* createStructure(VM
& vm
, JSGlobalObject
* globalObject
, JSValue proto
)
217 return Structure::create(vm
, globalObject
, proto
, TypeInfo(UnlinkedFunctionExecutableType
, StructureFlags
), info());
223 struct UnlinkedStringJumpTable
{
224 typedef HashMap
<RefPtr
<StringImpl
>, int32_t> StringOffsetTable
;
225 StringOffsetTable offsetTable
;
227 inline int32_t offsetForValue(StringImpl
* value
, int32_t defaultOffset
)
229 StringOffsetTable::const_iterator end
= offsetTable
.end();
230 StringOffsetTable::const_iterator loc
= offsetTable
.find(value
);
232 return defaultOffset
;
238 struct UnlinkedSimpleJumpTable
{
239 Vector
<int32_t> branchOffsets
;
242 int32_t offsetForValue(int32_t value
, int32_t defaultOffset
);
243 void add(int32_t key
, int32_t offset
)
245 if (!branchOffsets
[key
])
246 branchOffsets
[key
] = offset
;
250 struct UnlinkedInstruction
{
251 UnlinkedInstruction() { u
.operand
= 0; }
252 UnlinkedInstruction(OpcodeID opcode
) { u
.opcode
= opcode
; }
253 UnlinkedInstruction(int operand
) { u
.operand
= operand
; }
261 class UnlinkedCodeBlock
: public JSCell
{
264 static const unsigned StructureFlags
= Base::StructureFlags
;
266 static const bool needsDestruction
= true;
268 enum { CallFunction
, ApplyFunction
};
270 bool isConstructor() const { return m_isConstructor
; }
271 bool isStrictMode() const { return m_isStrictMode
; }
272 bool usesEval() const { return m_usesEval
; }
274 bool needsFullScopeChain() const { return m_needsFullScopeChain
; }
276 void addExpressionInfo(unsigned instructionOffset
, int divot
,
277 int startOffset
, int endOffset
, unsigned line
, unsigned column
);
279 void addTypeProfilerExpressionInfo(unsigned instructionOffset
, unsigned startDivot
, unsigned endDivot
);
281 bool hasExpressionInfo() { return m_expressionInfo
.size(); }
284 void setThisRegister(VirtualRegister thisRegister
) { m_thisRegister
= thisRegister
; }
285 void setScopeRegister(VirtualRegister scopeRegister
) { m_scopeRegister
= scopeRegister
; }
286 void setActivationRegister(VirtualRegister activationRegister
) { m_lexicalEnvironmentRegister
= activationRegister
; }
288 bool usesGlobalObject() const { return m_globalObjectRegister
.isValid(); }
289 void setGlobalObjectRegister(VirtualRegister globalObjectRegister
) { m_globalObjectRegister
= globalObjectRegister
; }
290 VirtualRegister
globalObjectRegister() const { return m_globalObjectRegister
; }
292 // Parameter information
293 void setNumParameters(int newValue
) { m_numParameters
= newValue
; }
294 void addParameter() { m_numParameters
++; }
295 unsigned numParameters() const { return m_numParameters
; }
297 unsigned addRegExp(RegExp
* r
)
299 createRareDataIfNecessary();
300 unsigned size
= m_rareData
->m_regexps
.size();
301 m_rareData
->m_regexps
.append(WriteBarrier
<RegExp
>(*m_vm
, this, r
));
304 unsigned numberOfRegExps() const
308 return m_rareData
->m_regexps
.size();
310 RegExp
* regexp(int index
) const { ASSERT(m_rareData
); return m_rareData
->m_regexps
[index
].get(); }
314 size_t numberOfIdentifiers() const { return m_identifiers
.size(); }
315 void addIdentifier(const Identifier
& i
) { return m_identifiers
.append(i
); }
316 const Identifier
& identifier(int index
) const { return m_identifiers
[index
]; }
317 const Vector
<Identifier
>& identifiers() const { return m_identifiers
; }
319 unsigned addConstant(JSValue v
, SourceCodeRepresentation sourceCodeRepresentation
= SourceCodeRepresentation::Other
)
321 unsigned result
= m_constantRegisters
.size();
322 m_constantRegisters
.append(WriteBarrier
<Unknown
>());
323 m_constantRegisters
.last().set(*m_vm
, this, v
);
324 m_constantsSourceCodeRepresentation
.append(sourceCodeRepresentation
);
327 unsigned addConstant(LinkTimeConstant type
)
329 unsigned result
= m_constantRegisters
.size();
331 unsigned index
= static_cast<unsigned>(type
);
332 ASSERT(index
< LinkTimeConstantCount
);
333 m_linkTimeConstants
[index
] = result
;
334 m_constantRegisters
.append(WriteBarrier
<Unknown
>());
335 m_constantsSourceCodeRepresentation
.append(SourceCodeRepresentation::Other
);
338 unsigned registerIndexForLinkTimeConstant(LinkTimeConstant type
)
340 unsigned index
= static_cast<unsigned>(type
);
341 ASSERT(index
< LinkTimeConstantCount
);
342 return m_linkTimeConstants
[index
];
344 const Vector
<WriteBarrier
<Unknown
>>& constantRegisters() { return m_constantRegisters
; }
345 const WriteBarrier
<Unknown
>& constantRegister(int index
) const { return m_constantRegisters
[index
- FirstConstantRegisterIndex
]; }
346 ALWAYS_INLINE
bool isConstantRegisterIndex(int index
) const { return index
>= FirstConstantRegisterIndex
; }
347 const Vector
<SourceCodeRepresentation
>& constantsSourceCodeRepresentation() { return m_constantsSourceCodeRepresentation
; }
350 size_t numberOfJumpTargets() const { return m_jumpTargets
.size(); }
351 void addJumpTarget(unsigned jumpTarget
) { m_jumpTargets
.append(jumpTarget
); }
352 unsigned jumpTarget(int index
) const { return m_jumpTargets
[index
]; }
353 unsigned lastJumpTarget() const { return m_jumpTargets
.last(); }
355 bool isBuiltinFunction() const { return m_isBuiltinFunction
; }
357 ConstructorKind
constructorKind() const { return static_cast<ConstructorKind
>(m_constructorKind
); }
361 m_jumpTargets
.shrinkToFit();
362 m_identifiers
.shrinkToFit();
363 m_constantRegisters
.shrinkToFit();
364 m_constantsSourceCodeRepresentation
.shrinkToFit();
365 m_functionDecls
.shrinkToFit();
366 m_functionExprs
.shrinkToFit();
367 m_propertyAccessInstructions
.shrinkToFit();
368 m_expressionInfo
.shrinkToFit();
370 #if ENABLE(BYTECODE_COMMENTS)
371 m_bytecodeComments
.shrinkToFit();
374 m_rareData
->m_exceptionHandlers
.shrinkToFit();
375 m_rareData
->m_regexps
.shrinkToFit();
376 m_rareData
->m_constantBuffers
.shrinkToFit();
377 m_rareData
->m_switchJumpTables
.shrinkToFit();
378 m_rareData
->m_stringSwitchJumpTables
.shrinkToFit();
379 m_rareData
->m_expressionInfoFatPositions
.shrinkToFit();
383 void setInstructions(std::unique_ptr
<UnlinkedInstructionStream
>);
384 const UnlinkedInstructionStream
& instructions() const;
387 int m_numCapturedVars
;
388 int m_numCalleeRegisters
;
392 size_t numberOfSwitchJumpTables() const { return m_rareData
? m_rareData
->m_switchJumpTables
.size() : 0; }
393 UnlinkedSimpleJumpTable
& addSwitchJumpTable() { createRareDataIfNecessary(); m_rareData
->m_switchJumpTables
.append(UnlinkedSimpleJumpTable()); return m_rareData
->m_switchJumpTables
.last(); }
394 UnlinkedSimpleJumpTable
& switchJumpTable(int tableIndex
) { ASSERT(m_rareData
); return m_rareData
->m_switchJumpTables
[tableIndex
]; }
396 size_t numberOfStringSwitchJumpTables() const { return m_rareData
? m_rareData
->m_stringSwitchJumpTables
.size() : 0; }
397 UnlinkedStringJumpTable
& addStringSwitchJumpTable() { createRareDataIfNecessary(); m_rareData
->m_stringSwitchJumpTables
.append(UnlinkedStringJumpTable()); return m_rareData
->m_stringSwitchJumpTables
.last(); }
398 UnlinkedStringJumpTable
& stringSwitchJumpTable(int tableIndex
) { ASSERT(m_rareData
); return m_rareData
->m_stringSwitchJumpTables
[tableIndex
]; }
400 unsigned addFunctionDecl(UnlinkedFunctionExecutable
* n
)
402 unsigned size
= m_functionDecls
.size();
403 m_functionDecls
.append(WriteBarrier
<UnlinkedFunctionExecutable
>());
404 m_functionDecls
.last().set(*m_vm
, this, n
);
407 UnlinkedFunctionExecutable
* functionDecl(int index
) { return m_functionDecls
[index
].get(); }
408 size_t numberOfFunctionDecls() { return m_functionDecls
.size(); }
409 unsigned addFunctionExpr(UnlinkedFunctionExecutable
* n
)
411 unsigned size
= m_functionExprs
.size();
412 m_functionExprs
.append(WriteBarrier
<UnlinkedFunctionExecutable
>());
413 m_functionExprs
.last().set(*m_vm
, this, n
);
416 UnlinkedFunctionExecutable
* functionExpr(int index
) { return m_functionExprs
[index
].get(); }
417 size_t numberOfFunctionExprs() { return m_functionExprs
.size(); }
419 // Exception handling support
420 size_t numberOfExceptionHandlers() const { return m_rareData
? m_rareData
->m_exceptionHandlers
.size() : 0; }
421 void addExceptionHandler(const UnlinkedHandlerInfo
& handler
) { createRareDataIfNecessary(); return m_rareData
->m_exceptionHandlers
.append(handler
); }
422 UnlinkedHandlerInfo
& exceptionHandler(int index
) { ASSERT(m_rareData
); return m_rareData
->m_exceptionHandlers
[index
]; }
424 SymbolTable
* symbolTable() const { return m_symbolTable
.get(); }
425 void setSymbolTable(SymbolTable
* table
) { m_symbolTable
.set(*m_vm
, this, table
); }
427 VM
* vm() const { return m_vm
; }
429 UnlinkedArrayProfile
addArrayProfile() { return m_arrayProfileCount
++; }
430 unsigned numberOfArrayProfiles() { return m_arrayProfileCount
; }
431 UnlinkedArrayAllocationProfile
addArrayAllocationProfile() { return m_arrayAllocationProfileCount
++; }
432 unsigned numberOfArrayAllocationProfiles() { return m_arrayAllocationProfileCount
; }
433 UnlinkedObjectAllocationProfile
addObjectAllocationProfile() { return m_objectAllocationProfileCount
++; }
434 unsigned numberOfObjectAllocationProfiles() { return m_objectAllocationProfileCount
; }
435 UnlinkedValueProfile
addValueProfile() { return m_valueProfileCount
++; }
436 unsigned numberOfValueProfiles() { return m_valueProfileCount
; }
438 UnlinkedLLIntCallLinkInfo
addLLIntCallLinkInfo() { return m_llintCallLinkInfoCount
++; }
439 unsigned numberOfLLintCallLinkInfos() { return m_llintCallLinkInfoCount
; }
441 CodeType
codeType() const { return m_codeType
; }
443 VirtualRegister
thisRegister() const { return m_thisRegister
; }
444 VirtualRegister
scopeRegister() const { return m_scopeRegister
; }
445 VirtualRegister
activationRegister() const { return m_lexicalEnvironmentRegister
; }
446 bool hasActivationRegister() const { return m_lexicalEnvironmentRegister
.isValid(); }
448 void addPropertyAccessInstruction(unsigned propertyAccessInstruction
)
450 m_propertyAccessInstructions
.append(propertyAccessInstruction
);
453 size_t numberOfPropertyAccessInstructions() const { return m_propertyAccessInstructions
.size(); }
454 const Vector
<unsigned>& propertyAccessInstructions() const { return m_propertyAccessInstructions
; }
456 typedef Vector
<JSValue
> ConstantBuffer
;
458 size_t constantBufferCount() { ASSERT(m_rareData
); return m_rareData
->m_constantBuffers
.size(); }
459 unsigned addConstantBuffer(unsigned length
)
461 createRareDataIfNecessary();
462 unsigned size
= m_rareData
->m_constantBuffers
.size();
463 m_rareData
->m_constantBuffers
.append(Vector
<JSValue
>(length
));
467 const ConstantBuffer
& constantBuffer(unsigned index
) const
470 return m_rareData
->m_constantBuffers
[index
];
473 ConstantBuffer
& constantBuffer(unsigned index
)
476 return m_rareData
->m_constantBuffers
[index
];
479 bool hasRareData() const { return m_rareData
.get(); }
481 int lineNumberForBytecodeOffset(unsigned bytecodeOffset
);
483 void expressionRangeForBytecodeOffset(unsigned bytecodeOffset
, int& divot
,
484 int& startOffset
, int& endOffset
, unsigned& line
, unsigned& column
);
486 bool typeProfilerExpressionInfoForBytecodeOffset(unsigned bytecodeOffset
, unsigned& startDivot
, unsigned& endDivot
);
488 void recordParse(CodeFeatures features
, bool hasCapturedVariables
, unsigned firstLine
, unsigned lineCount
, unsigned endColumn
)
490 m_features
= features
;
491 m_hasCapturedVariables
= hasCapturedVariables
;
492 m_firstLine
= firstLine
;
493 m_lineCount
= lineCount
;
494 // For the UnlinkedCodeBlock, startColumn is always 0.
495 m_endColumn
= endColumn
;
498 CodeFeatures
codeFeatures() const { return m_features
; }
499 bool hasCapturedVariables() const { return m_hasCapturedVariables
; }
500 unsigned firstLine() const { return m_firstLine
; }
501 unsigned lineCount() const { return m_lineCount
; }
502 ALWAYS_INLINE
unsigned startColumn() const { return 0; }
503 unsigned endColumn() const { return m_endColumn
; }
505 void addOpProfileControlFlowBytecodeOffset(size_t offset
) { m_opProfileControlFlowBytecodeOffsets
.append(offset
); }
506 const Vector
<size_t>& opProfileControlFlowBytecodeOffsets() const { return m_opProfileControlFlowBytecodeOffsets
; }
508 void dumpExpressionRangeInfo(); // For debugging purpose only.
511 UnlinkedCodeBlock(VM
*, Structure
*, CodeType
, const ExecutableInfo
&);
512 ~UnlinkedCodeBlock();
514 void finishCreation(VM
& vm
)
516 Base::finishCreation(vm
);
517 if (codeType() == GlobalCode
)
519 m_symbolTable
.set(vm
, this, SymbolTable::create(vm
));
524 void createRareDataIfNecessary()
527 m_rareData
= std::make_unique
<RareData
>();
530 void getLineAndColumn(ExpressionRangeInfo
&, unsigned& line
, unsigned& column
);
532 std::unique_ptr
<UnlinkedInstructionStream
> m_unlinkedInstructions
;
537 VirtualRegister m_thisRegister
;
538 VirtualRegister m_scopeRegister
;
539 VirtualRegister m_lexicalEnvironmentRegister
;
540 VirtualRegister m_globalObjectRegister
;
542 unsigned m_needsFullScopeChain
: 1;
543 unsigned m_usesEval
: 1;
544 unsigned m_isStrictMode
: 1;
545 unsigned m_isConstructor
: 1;
546 unsigned m_hasCapturedVariables
: 1;
547 unsigned m_isBuiltinFunction
: 1;
548 unsigned m_constructorKind
: 2;
550 unsigned m_firstLine
;
551 unsigned m_lineCount
;
552 unsigned m_endColumn
;
554 CodeFeatures m_features
;
557 Vector
<unsigned> m_jumpTargets
;
560 Vector
<Identifier
> m_identifiers
;
561 Vector
<WriteBarrier
<Unknown
>> m_constantRegisters
;
562 Vector
<SourceCodeRepresentation
> m_constantsSourceCodeRepresentation
;
563 std::array
<unsigned, LinkTimeConstantCount
> m_linkTimeConstants
;
564 typedef Vector
<WriteBarrier
<UnlinkedFunctionExecutable
>> FunctionExpressionVector
;
565 FunctionExpressionVector m_functionDecls
;
566 FunctionExpressionVector m_functionExprs
;
568 WriteBarrier
<SymbolTable
> m_symbolTable
;
570 Vector
<unsigned> m_propertyAccessInstructions
;
572 #if ENABLE(BYTECODE_COMMENTS)
573 Vector
<Comment
> m_bytecodeComments
;
574 size_t m_bytecodeCommentIterator
;
577 unsigned m_arrayProfileCount
;
578 unsigned m_arrayAllocationProfileCount
;
579 unsigned m_objectAllocationProfileCount
;
580 unsigned m_valueProfileCount
;
581 unsigned m_llintCallLinkInfoCount
;
585 WTF_MAKE_FAST_ALLOCATED
;
587 Vector
<UnlinkedHandlerInfo
> m_exceptionHandlers
;
590 Vector
<WriteBarrier
<RegExp
>> m_regexps
;
592 // Buffers used for large array literals
593 Vector
<ConstantBuffer
> m_constantBuffers
;
596 Vector
<UnlinkedSimpleJumpTable
> m_switchJumpTables
;
597 Vector
<UnlinkedStringJumpTable
> m_stringSwitchJumpTables
;
599 Vector
<ExpressionRangeInfo::FatPosition
> m_expressionInfoFatPositions
;
603 std::unique_ptr
<RareData
> m_rareData
;
604 Vector
<ExpressionRangeInfo
> m_expressionInfo
;
605 struct TypeProfilerExpressionRange
{
606 unsigned m_startDivot
;
609 HashMap
<unsigned, TypeProfilerExpressionRange
> m_typeProfilerInfoMap
;
610 Vector
<size_t> m_opProfileControlFlowBytecodeOffsets
;
613 static void visitChildren(JSCell
*, SlotVisitor
&);
619 class UnlinkedGlobalCodeBlock
: public UnlinkedCodeBlock
{
621 typedef UnlinkedCodeBlock Base
;
624 UnlinkedGlobalCodeBlock(VM
* vm
, Structure
* structure
, CodeType codeType
, const ExecutableInfo
& info
)
625 : Base(vm
, structure
, codeType
, info
)
632 class UnlinkedProgramCodeBlock final
: public UnlinkedGlobalCodeBlock
{
634 friend class CodeCache
;
635 static UnlinkedProgramCodeBlock
* create(VM
* vm
, const ExecutableInfo
& info
)
637 UnlinkedProgramCodeBlock
* instance
= new (NotNull
, allocateCell
<UnlinkedProgramCodeBlock
>(vm
->heap
)) UnlinkedProgramCodeBlock(vm
, vm
->unlinkedProgramCodeBlockStructure
.get(), info
);
638 instance
->finishCreation(*vm
);
643 typedef UnlinkedGlobalCodeBlock Base
;
644 static const unsigned StructureFlags
= Base::StructureFlags
| StructureIsImmortal
;
646 static void destroy(JSCell
*);
648 void addVariableDeclaration(const Identifier
& name
, bool isConstant
)
650 m_varDeclarations
.append(std::make_pair(name
, isConstant
));
653 typedef Vector
<std::pair
<Identifier
, bool>> VariableDeclations
;
655 const VariableDeclations
& variableDeclarations() const { return m_varDeclarations
; }
657 static void visitChildren(JSCell
*, SlotVisitor
&);
660 UnlinkedProgramCodeBlock(VM
* vm
, Structure
* structure
, const ExecutableInfo
& info
)
661 : Base(vm
, structure
, GlobalCode
, info
)
665 VariableDeclations m_varDeclarations
;
668 static Structure
* createStructure(VM
& vm
, JSGlobalObject
* globalObject
, JSValue proto
)
670 return Structure::create(vm
, globalObject
, proto
, TypeInfo(UnlinkedProgramCodeBlockType
, StructureFlags
), info());
676 class UnlinkedEvalCodeBlock final
: public UnlinkedGlobalCodeBlock
{
678 friend class CodeCache
;
680 static UnlinkedEvalCodeBlock
* create(VM
* vm
, const ExecutableInfo
& info
)
682 UnlinkedEvalCodeBlock
* instance
= new (NotNull
, allocateCell
<UnlinkedEvalCodeBlock
>(vm
->heap
)) UnlinkedEvalCodeBlock(vm
, vm
->unlinkedEvalCodeBlockStructure
.get(), info
);
683 instance
->finishCreation(*vm
);
688 typedef UnlinkedGlobalCodeBlock Base
;
689 static const unsigned StructureFlags
= Base::StructureFlags
| StructureIsImmortal
;
691 static void destroy(JSCell
*);
693 const Identifier
& variable(unsigned index
) { return m_variables
[index
]; }
694 unsigned numVariables() { return m_variables
.size(); }
695 void adoptVariables(Vector
<Identifier
, 0, UnsafeVectorOverflow
>& variables
)
697 ASSERT(m_variables
.isEmpty());
698 m_variables
.swap(variables
);
702 UnlinkedEvalCodeBlock(VM
* vm
, Structure
* structure
, const ExecutableInfo
& info
)
703 : Base(vm
, structure
, EvalCode
, info
)
707 Vector
<Identifier
, 0, UnsafeVectorOverflow
> m_variables
;
710 static Structure
* createStructure(VM
& vm
, JSGlobalObject
* globalObject
, JSValue proto
)
712 return Structure::create(vm
, globalObject
, proto
, TypeInfo(UnlinkedEvalCodeBlockType
, StructureFlags
), info());
718 class UnlinkedFunctionCodeBlock final
: public UnlinkedCodeBlock
{
720 typedef UnlinkedCodeBlock Base
;
721 static const unsigned StructureFlags
= Base::StructureFlags
| StructureIsImmortal
;
723 static UnlinkedFunctionCodeBlock
* create(VM
* vm
, CodeType codeType
, const ExecutableInfo
& info
)
725 UnlinkedFunctionCodeBlock
* instance
= new (NotNull
, allocateCell
<UnlinkedFunctionCodeBlock
>(vm
->heap
)) UnlinkedFunctionCodeBlock(vm
, vm
->unlinkedFunctionCodeBlockStructure
.get(), codeType
, info
);
726 instance
->finishCreation(*vm
);
730 static void destroy(JSCell
*);
733 UnlinkedFunctionCodeBlock(VM
* vm
, Structure
* structure
, CodeType codeType
, const ExecutableInfo
& info
)
734 : Base(vm
, structure
, codeType
, info
)
739 static Structure
* createStructure(VM
& vm
, JSGlobalObject
* globalObject
, JSValue proto
)
741 return Structure::create(vm
, globalObject
, proto
, TypeInfo(UnlinkedFunctionCodeBlockType
, StructureFlags
), info());
749 #endif // UnlinkedCodeBlock_h