fromGlobalCode has an unused Debugger* argument
[WebKit-https.git] / Source / JavaScriptCore / bytecode / UnlinkedCodeBlock.h
1 /*
2  * Copyright (C) 2012, 2013, 2014 Apple Inc. All Rights Reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
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.
12  *
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.
24  */
25
26 #ifndef UnlinkedCodeBlock_h
27 #define UnlinkedCodeBlock_h
28
29 #include "BytecodeConventions.h"
30 #include "CodeSpecializationKind.h"
31 #include "CodeType.h"
32 #include "ExpressionRangeInfo.h"
33 #include "Identifier.h"
34 #include "JSCell.h"
35 #include "JSString.h"
36 #include "ParserModes.h"
37 #include "RegExp.h"
38 #include "SpecialPointer.h"
39 #include "SymbolTable.h"
40 #include "VirtualRegister.h"
41
42 #include <wtf/RefCountedArray.h>
43 #include <wtf/Vector.h>
44
45 namespace JSC {
46
47 class Debugger;
48 class FunctionBodyNode;
49 class FunctionExecutable;
50 class FunctionParameters;
51 class JSScope;
52 class ParserError;
53 class ScriptExecutable;
54 class SourceCode;
55 class SourceProvider;
56 class SymbolTable;
57 class UnlinkedCodeBlock;
58 class UnlinkedFunctionCodeBlock;
59 class UnlinkedInstructionStream;
60
61 typedef unsigned UnlinkedValueProfile;
62 typedef unsigned UnlinkedArrayProfile;
63 typedef unsigned UnlinkedArrayAllocationProfile;
64 typedef unsigned UnlinkedObjectAllocationProfile;
65 typedef unsigned UnlinkedLLIntCallLinkInfo;
66
67 struct ExecutableInfo {
68     ExecutableInfo(bool needsActivation, bool usesEval, bool isStrictMode, bool isConstructor, bool isBuiltinFunction)
69         : m_needsActivation(needsActivation)
70         , m_usesEval(usesEval)
71         , m_isStrictMode(isStrictMode)
72         , m_isConstructor(isConstructor)
73         , m_isBuiltinFunction(isBuiltinFunction)
74     {
75     }
76     bool m_needsActivation : 1;
77     bool m_usesEval : 1;
78     bool m_isStrictMode : 1;
79     bool m_isConstructor : 1;
80     bool m_isBuiltinFunction : 1;
81 };
82
83 enum UnlinkedFunctionKind {
84     UnlinkedNormalFunction,
85     UnlinkedBuiltinFunction,
86 };
87
88 class UnlinkedFunctionExecutable : public JSCell {
89 public:
90     friend class BuiltinExecutables;
91     friend class CodeCache;
92     friend class VM;
93     typedef JSCell Base;
94     static UnlinkedFunctionExecutable* create(VM* vm, const SourceCode& source, FunctionBodyNode* node, UnlinkedFunctionKind unlinkedFunctionKind)
95     {
96         UnlinkedFunctionExecutable* instance = new (NotNull, allocateCell<UnlinkedFunctionExecutable>(vm->heap)) UnlinkedFunctionExecutable(vm, vm->unlinkedFunctionExecutableStructure.get(), source, node, unlinkedFunctionKind);
97         instance->finishCreation(*vm);
98         return instance;
99     }
100
101     const Identifier& name() const { return m_name; }
102     const Identifier& inferredName() const { return m_inferredName; }
103     JSString* nameValue() const { return m_nameValue.get(); }
104     SymbolTable* symbolTable(CodeSpecializationKind kind)
105     {
106         return (kind == CodeForCall) ? m_symbolTableForCall.get() : m_symbolTableForConstruct.get();
107     }
108     size_t parameterCount() const;
109     bool isInStrictContext() const { return m_isInStrictContext; }
110     FunctionMode functionMode() const { return m_functionMode; }
111     JSParserStrictness toStrictness() const
112     {
113         if (m_isBuiltinFunction)
114             return JSParseBuiltin;
115         if (m_isInStrictContext)
116             return JSParseStrict;
117         return JSParseNormal;
118     }
119
120     unsigned firstLineOffset() const { return m_firstLineOffset; }
121     unsigned lineCount() const { return m_lineCount; }
122     unsigned unlinkedFunctionNameStart() const { return m_unlinkedFunctionNameStart; }
123     unsigned unlinkedBodyStartColumn() const { return m_unlinkedBodyStartColumn; }
124     unsigned unlinkedBodyEndColumn() const { return m_unlinkedBodyEndColumn; }
125     unsigned startOffset() const { return m_startOffset; }
126     unsigned sourceLength() { return m_sourceLength; }
127     unsigned typeProfilingStartOffset() const { return m_typeProfilingStartOffset; }
128     unsigned typeProfilingEndOffset() const { return m_typeProfilingEndOffset; }
129
130     String paramString() const;
131
132     UnlinkedFunctionCodeBlock* codeBlockFor(VM&, const SourceCode&, CodeSpecializationKind, DebuggerMode, ProfilerMode, bool bodyIncludesBraces, ParserError&);
133
134     static UnlinkedFunctionExecutable* fromGlobalCode(const Identifier&, ExecState&, const SourceCode&, JSObject*& exception);
135
136     FunctionExecutable* link(VM&, const SourceCode&, size_t lineOffset);
137
138     void clearCodeForRecompilation()
139     {
140         m_symbolTableForCall.clear();
141         m_symbolTableForConstruct.clear();
142         m_codeBlockForCall.clear();
143         m_codeBlockForConstruct.clear();
144     }
145
146     FunctionParameters* parameters() { return m_parameters.get(); }
147
148     void recordParse(CodeFeatures features, bool hasCapturedVariables)
149     {
150         m_features = features;
151         m_hasCapturedVariables = hasCapturedVariables;
152     }
153
154     CodeFeatures features() const { return m_features; }
155     bool hasCapturedVariables() const { return m_hasCapturedVariables; }
156
157     static const bool needsDestruction = true;
158     static const bool hasImmortalStructure = true;
159     static void destroy(JSCell*);
160
161     bool isBuiltinFunction() const { return m_isBuiltinFunction; }
162
163 private:
164     UnlinkedFunctionExecutable(VM*, Structure*, const SourceCode&, FunctionBodyNode*, UnlinkedFunctionKind);
165     WriteBarrier<UnlinkedFunctionCodeBlock> m_codeBlockForCall;
166     WriteBarrier<UnlinkedFunctionCodeBlock> m_codeBlockForConstruct;
167
168     bool m_isInStrictContext : 1;
169     bool m_hasCapturedVariables : 1;
170     bool m_isBuiltinFunction : 1;
171
172     Identifier m_name;
173     Identifier m_inferredName;
174     WriteBarrier<JSString> m_nameValue;
175     WriteBarrier<SymbolTable> m_symbolTableForCall;
176     WriteBarrier<SymbolTable> m_symbolTableForConstruct;
177     RefPtr<FunctionParameters> m_parameters;
178     unsigned m_firstLineOffset;
179     unsigned m_lineCount;
180     unsigned m_unlinkedFunctionNameStart;
181     unsigned m_unlinkedBodyStartColumn;
182     unsigned m_unlinkedBodyEndColumn;
183     unsigned m_startOffset;
184     unsigned m_sourceLength;
185     unsigned m_typeProfilingStartOffset;
186     unsigned m_typeProfilingEndOffset;
187
188     CodeFeatures m_features;
189
190     FunctionMode m_functionMode;
191
192 protected:
193     void finishCreation(VM& vm)
194     {
195         Base::finishCreation(vm);
196         m_nameValue.set(vm, this, jsString(&vm, name().string()));
197     }
198
199     static void visitChildren(JSCell*, SlotVisitor&);
200
201 public:
202     static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto)
203     {
204         return Structure::create(vm, globalObject, proto, TypeInfo(UnlinkedFunctionExecutableType, StructureFlags), info());
205     }
206
207     static const unsigned StructureFlags = StructureIsImmortal | JSCell::StructureFlags;
208
209     DECLARE_EXPORT_INFO;
210 };
211
212 struct UnlinkedStringJumpTable {
213     typedef HashMap<RefPtr<StringImpl>, int32_t> StringOffsetTable;
214     StringOffsetTable offsetTable;
215
216     inline int32_t offsetForValue(StringImpl* value, int32_t defaultOffset)
217     {
218         StringOffsetTable::const_iterator end = offsetTable.end();
219         StringOffsetTable::const_iterator loc = offsetTable.find(value);
220         if (loc == end)
221             return defaultOffset;
222         return loc->value;
223     }
224
225 };
226
227 struct UnlinkedSimpleJumpTable {
228     Vector<int32_t> branchOffsets;
229     int32_t min;
230
231     int32_t offsetForValue(int32_t value, int32_t defaultOffset);
232     void add(int32_t key, int32_t offset)
233     {
234         if (!branchOffsets[key])
235             branchOffsets[key] = offset;
236     }
237 };
238
239 struct UnlinkedHandlerInfo {
240     uint32_t start;
241     uint32_t end;
242     uint32_t target;
243     uint32_t scopeDepth;
244 };
245
246 struct UnlinkedInstruction {
247     UnlinkedInstruction() { u.operand = 0; }
248     UnlinkedInstruction(OpcodeID opcode) { u.opcode = opcode; }
249     UnlinkedInstruction(int operand) { u.operand = operand; }
250     union {
251         OpcodeID opcode;
252         int32_t operand;
253         unsigned index;
254     } u;
255 };
256
257 class UnlinkedCodeBlock : public JSCell {
258 public:
259     typedef JSCell Base;
260     static const bool needsDestruction = true;
261     static const bool hasImmortalStructure = true;
262
263     enum { CallFunction, ApplyFunction };
264
265     bool isConstructor() const { return m_isConstructor; }
266     bool isStrictMode() const { return m_isStrictMode; }
267     bool usesEval() const { return m_usesEval; }
268
269     bool needsFullScopeChain() const { return m_needsFullScopeChain; }
270
271     void addExpressionInfo(unsigned instructionOffset, int divot,
272         int startOffset, int endOffset, unsigned line, unsigned column);
273
274     void addTypeProfilerExpressionInfo(unsigned instructionOffset, unsigned startDivot, unsigned endDivot);
275
276     bool hasExpressionInfo() { return m_expressionInfo.size(); }
277
278     // Special registers
279     void setThisRegister(VirtualRegister thisRegister) { m_thisRegister = thisRegister; }
280     void setScopeRegister(VirtualRegister scopeRegister) { m_scopeRegister = scopeRegister; }
281     void setActivationRegister(VirtualRegister activationRegister) { m_lexicalEnvironmentRegister = activationRegister; }
282
283     void setArgumentsRegister(VirtualRegister argumentsRegister) { m_argumentsRegister = argumentsRegister; }
284     bool usesArguments() const { return m_argumentsRegister.isValid(); }
285     VirtualRegister argumentsRegister() const { return m_argumentsRegister; }
286
287
288     bool usesGlobalObject() const { return m_globalObjectRegister.isValid(); }
289     void setGlobalObjectRegister(VirtualRegister globalObjectRegister) { m_globalObjectRegister = globalObjectRegister; }
290     VirtualRegister globalObjectRegister() const { return m_globalObjectRegister; }
291
292     // Parameter information
293     void setNumParameters(int newValue) { m_numParameters = newValue; }
294     void addParameter() { m_numParameters++; }
295     unsigned numParameters() const { return m_numParameters; }
296
297     unsigned addRegExp(RegExp* r)
298     {
299         createRareDataIfNecessary();
300         unsigned size = m_rareData->m_regexps.size();
301         m_rareData->m_regexps.append(WriteBarrier<RegExp>(*m_vm, this, r));
302         return size;
303     }
304     unsigned numberOfRegExps() const
305     {
306         if (!m_rareData)
307             return 0;
308         return m_rareData->m_regexps.size();
309     }
310     RegExp* regexp(int index) const { ASSERT(m_rareData); return m_rareData->m_regexps[index].get(); }
311
312     // Constant Pools
313
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; }
318
319     size_t numberOfConstantRegisters() const { return m_constantRegisters.size(); }
320     unsigned addConstant(JSValue v, SourceCodeRepresentation sourceCodeRepresentation = SourceCodeRepresentation::Other)
321     {
322         unsigned result = m_constantRegisters.size();
323         m_constantRegisters.append(WriteBarrier<Unknown>());
324         m_constantRegisters.last().set(*m_vm, this, v);
325         m_constantsSourceCodeRepresentation.append(sourceCodeRepresentation);
326         return result;
327     }
328     unsigned addOrFindConstant(JSValue);
329     const Vector<WriteBarrier<Unknown>>& constantRegisters() { return m_constantRegisters; }
330     const WriteBarrier<Unknown>& constantRegister(int index) const { return m_constantRegisters[index - FirstConstantRegisterIndex]; }
331     ALWAYS_INLINE bool isConstantRegisterIndex(int index) const { return index >= FirstConstantRegisterIndex; }
332     ALWAYS_INLINE JSValue getConstant(int index) const { return m_constantRegisters[index - FirstConstantRegisterIndex].get(); }
333     const Vector<SourceCodeRepresentation>& constantsSourceCodeRepresentation() { return m_constantsSourceCodeRepresentation; }
334
335     // Jumps
336     size_t numberOfJumpTargets() const { return m_jumpTargets.size(); }
337     void addJumpTarget(unsigned jumpTarget) { m_jumpTargets.append(jumpTarget); }
338     unsigned jumpTarget(int index) const { return m_jumpTargets[index]; }
339     unsigned lastJumpTarget() const { return m_jumpTargets.last(); }
340
341     void setIsNumericCompareFunction(bool isNumericCompareFunction) { m_isNumericCompareFunction = isNumericCompareFunction; }
342     bool isNumericCompareFunction() const { return m_isNumericCompareFunction; }
343
344     bool isBuiltinFunction() const { return m_isBuiltinFunction; }
345     
346     void shrinkToFit()
347     {
348         m_jumpTargets.shrinkToFit();
349         m_identifiers.shrinkToFit();
350         m_constantRegisters.shrinkToFit();
351         m_constantsSourceCodeRepresentation.shrinkToFit();
352         m_functionDecls.shrinkToFit();
353         m_functionExprs.shrinkToFit();
354         m_propertyAccessInstructions.shrinkToFit();
355         m_expressionInfo.shrinkToFit();
356
357 #if ENABLE(BYTECODE_COMMENTS)
358         m_bytecodeComments.shrinkToFit();
359 #endif
360         if (m_rareData) {
361             m_rareData->m_exceptionHandlers.shrinkToFit();
362             m_rareData->m_regexps.shrinkToFit();
363             m_rareData->m_constantBuffers.shrinkToFit();
364             m_rareData->m_switchJumpTables.shrinkToFit();
365             m_rareData->m_stringSwitchJumpTables.shrinkToFit();
366             m_rareData->m_expressionInfoFatPositions.shrinkToFit();
367         }
368     }
369
370     void setInstructions(std::unique_ptr<UnlinkedInstructionStream>);
371     const UnlinkedInstructionStream& instructions() const;
372
373     int m_numVars;
374     int m_numCapturedVars;
375     int m_numCalleeRegisters;
376
377     // Jump Tables
378
379     size_t numberOfSwitchJumpTables() const { return m_rareData ? m_rareData->m_switchJumpTables.size() : 0; }
380     UnlinkedSimpleJumpTable& addSwitchJumpTable() { createRareDataIfNecessary(); m_rareData->m_switchJumpTables.append(UnlinkedSimpleJumpTable()); return m_rareData->m_switchJumpTables.last(); }
381     UnlinkedSimpleJumpTable& switchJumpTable(int tableIndex) { ASSERT(m_rareData); return m_rareData->m_switchJumpTables[tableIndex]; }
382
383     size_t numberOfStringSwitchJumpTables() const { return m_rareData ? m_rareData->m_stringSwitchJumpTables.size() : 0; }
384     UnlinkedStringJumpTable& addStringSwitchJumpTable() { createRareDataIfNecessary(); m_rareData->m_stringSwitchJumpTables.append(UnlinkedStringJumpTable()); return m_rareData->m_stringSwitchJumpTables.last(); }
385     UnlinkedStringJumpTable& stringSwitchJumpTable(int tableIndex) { ASSERT(m_rareData); return m_rareData->m_stringSwitchJumpTables[tableIndex]; }
386
387     unsigned addFunctionDecl(UnlinkedFunctionExecutable* n)
388     {
389         unsigned size = m_functionDecls.size();
390         m_functionDecls.append(WriteBarrier<UnlinkedFunctionExecutable>());
391         m_functionDecls.last().set(*m_vm, this, n);
392         return size;
393     }
394     UnlinkedFunctionExecutable* functionDecl(int index) { return m_functionDecls[index].get(); }
395     size_t numberOfFunctionDecls() { return m_functionDecls.size(); }
396     unsigned addFunctionExpr(UnlinkedFunctionExecutable* n)
397     {
398         unsigned size = m_functionExprs.size();
399         m_functionExprs.append(WriteBarrier<UnlinkedFunctionExecutable>());
400         m_functionExprs.last().set(*m_vm, this, n);
401         return size;
402     }
403     UnlinkedFunctionExecutable* functionExpr(int index) { return m_functionExprs[index].get(); }
404     size_t numberOfFunctionExprs() { return m_functionExprs.size(); }
405
406     // Exception handling support
407     size_t numberOfExceptionHandlers() const { return m_rareData ? m_rareData->m_exceptionHandlers.size() : 0; }
408     void addExceptionHandler(const UnlinkedHandlerInfo& hanler) { createRareDataIfNecessary(); return m_rareData->m_exceptionHandlers.append(hanler); }
409     UnlinkedHandlerInfo& exceptionHandler(int index) { ASSERT(m_rareData); return m_rareData->m_exceptionHandlers[index]; }
410
411     SymbolTable* symbolTable() const { return m_symbolTable.get(); }
412     void setSymbolTable(SymbolTable* table) { m_symbolTable.set(*m_vm, this, table); }
413
414     VM* vm() const { return m_vm; }
415
416     UnlinkedArrayProfile addArrayProfile() { return m_arrayProfileCount++; }
417     unsigned numberOfArrayProfiles() { return m_arrayProfileCount; }
418     UnlinkedArrayAllocationProfile addArrayAllocationProfile() { return m_arrayAllocationProfileCount++; }
419     unsigned numberOfArrayAllocationProfiles() { return m_arrayAllocationProfileCount; }
420     UnlinkedObjectAllocationProfile addObjectAllocationProfile() { return m_objectAllocationProfileCount++; }
421     unsigned numberOfObjectAllocationProfiles() { return m_objectAllocationProfileCount; }
422     UnlinkedValueProfile addValueProfile() { return m_valueProfileCount++; }
423     unsigned numberOfValueProfiles() { return m_valueProfileCount; }
424
425     UnlinkedLLIntCallLinkInfo addLLIntCallLinkInfo() { return m_llintCallLinkInfoCount++; }
426     unsigned numberOfLLintCallLinkInfos() { return m_llintCallLinkInfoCount; }
427
428     CodeType codeType() const { return m_codeType; }
429
430     VirtualRegister thisRegister() const { return m_thisRegister; }
431     VirtualRegister scopeRegister() const { return m_scopeRegister; }
432     VirtualRegister activationRegister() const { return m_lexicalEnvironmentRegister; }
433     bool hasActivationRegister() const { return m_lexicalEnvironmentRegister.isValid(); }
434
435     void addPropertyAccessInstruction(unsigned propertyAccessInstruction)
436     {
437         m_propertyAccessInstructions.append(propertyAccessInstruction);
438     }
439
440     size_t numberOfPropertyAccessInstructions() const { return m_propertyAccessInstructions.size(); }
441     const Vector<unsigned>& propertyAccessInstructions() const { return m_propertyAccessInstructions; }
442
443     typedef Vector<JSValue> ConstantBuffer;
444
445     size_t constantBufferCount() { ASSERT(m_rareData); return m_rareData->m_constantBuffers.size(); }
446     unsigned addConstantBuffer(unsigned length)
447     {
448         createRareDataIfNecessary();
449         unsigned size = m_rareData->m_constantBuffers.size();
450         m_rareData->m_constantBuffers.append(Vector<JSValue>(length));
451         return size;
452     }
453
454     const ConstantBuffer& constantBuffer(unsigned index) const
455     {
456         ASSERT(m_rareData);
457         return m_rareData->m_constantBuffers[index];
458     }
459
460     ConstantBuffer& constantBuffer(unsigned index)
461     {
462         ASSERT(m_rareData);
463         return m_rareData->m_constantBuffers[index];
464     }
465
466     bool hasRareData() const { return m_rareData.get(); }
467
468     int lineNumberForBytecodeOffset(unsigned bytecodeOffset);
469
470     void expressionRangeForBytecodeOffset(unsigned bytecodeOffset, int& divot,
471         int& startOffset, int& endOffset, unsigned& line, unsigned& column);
472
473     bool typeProfilerExpressionInfoForBytecodeOffset(unsigned bytecodeOffset, unsigned& startDivot, unsigned& endDivot);
474
475     void recordParse(CodeFeatures features, bool hasCapturedVariables, unsigned firstLine, unsigned lineCount, unsigned endColumn)
476     {
477         m_features = features;
478         m_hasCapturedVariables = hasCapturedVariables;
479         m_firstLine = firstLine;
480         m_lineCount = lineCount;
481         // For the UnlinkedCodeBlock, startColumn is always 0.
482         m_endColumn = endColumn;
483     }
484
485     CodeFeatures codeFeatures() const { return m_features; }
486     bool hasCapturedVariables() const { return m_hasCapturedVariables; }
487     unsigned firstLine() const { return m_firstLine; }
488     unsigned lineCount() const { return m_lineCount; }
489     ALWAYS_INLINE unsigned startColumn() const { return 0; }
490     unsigned endColumn() const { return m_endColumn; }
491
492     void addOpProfileControlFlowBytecodeOffset(size_t offset) { m_opProfileControlFlowBytecodeOffsets.append(offset); }
493     const Vector<size_t>& opProfileControlFlowBytecodeOffsets() const { return m_opProfileControlFlowBytecodeOffsets; }
494
495     void dumpExpressionRangeInfo(); // For debugging purpose only.
496
497 protected:
498     UnlinkedCodeBlock(VM*, Structure*, CodeType, const ExecutableInfo&);
499     ~UnlinkedCodeBlock();
500
501     void finishCreation(VM& vm)
502     {
503         Base::finishCreation(vm);
504         if (codeType() == GlobalCode)
505             return;
506         m_symbolTable.set(vm, this, SymbolTable::create(vm));
507     }
508
509 private:
510
511     void createRareDataIfNecessary()
512     {
513         if (!m_rareData)
514             m_rareData = std::make_unique<RareData>();
515     }
516
517     void getLineAndColumn(ExpressionRangeInfo&, unsigned& line, unsigned& column);
518
519     std::unique_ptr<UnlinkedInstructionStream> m_unlinkedInstructions;
520
521     int m_numParameters;
522     VM* m_vm;
523
524     VirtualRegister m_thisRegister;
525     VirtualRegister m_argumentsRegister;
526     VirtualRegister m_scopeRegister;
527     VirtualRegister m_lexicalEnvironmentRegister;
528     VirtualRegister m_globalObjectRegister;
529
530     bool m_needsFullScopeChain : 1;
531     bool m_usesEval : 1;
532     bool m_isNumericCompareFunction : 1;
533     bool m_isStrictMode : 1;
534     bool m_isConstructor : 1;
535     bool m_hasCapturedVariables : 1;
536     bool m_isBuiltinFunction : 1;
537     unsigned m_firstLine;
538     unsigned m_lineCount;
539     unsigned m_endColumn;
540
541     CodeFeatures m_features;
542     CodeType m_codeType;
543
544     Vector<unsigned> m_jumpTargets;
545
546     // Constant Pools
547     Vector<Identifier> m_identifiers;
548     Vector<WriteBarrier<Unknown>> m_constantRegisters;
549     Vector<SourceCodeRepresentation> m_constantsSourceCodeRepresentation;
550     typedef Vector<WriteBarrier<UnlinkedFunctionExecutable>> FunctionExpressionVector;
551     FunctionExpressionVector m_functionDecls;
552     FunctionExpressionVector m_functionExprs;
553
554     WriteBarrier<SymbolTable> m_symbolTable;
555
556     Vector<unsigned> m_propertyAccessInstructions;
557
558 #if ENABLE(BYTECODE_COMMENTS)
559     Vector<Comment>  m_bytecodeComments;
560     size_t m_bytecodeCommentIterator;
561 #endif
562
563     unsigned m_arrayProfileCount;
564     unsigned m_arrayAllocationProfileCount;
565     unsigned m_objectAllocationProfileCount;
566     unsigned m_valueProfileCount;
567     unsigned m_llintCallLinkInfoCount;
568
569 public:
570     struct RareData {
571         WTF_MAKE_FAST_ALLOCATED;
572     public:
573         Vector<UnlinkedHandlerInfo> m_exceptionHandlers;
574
575         // Rare Constants
576         Vector<WriteBarrier<RegExp>> m_regexps;
577
578         // Buffers used for large array literals
579         Vector<ConstantBuffer> m_constantBuffers;
580
581         // Jump Tables
582         Vector<UnlinkedSimpleJumpTable> m_switchJumpTables;
583         Vector<UnlinkedStringJumpTable> m_stringSwitchJumpTables;
584
585         Vector<ExpressionRangeInfo::FatPosition> m_expressionInfoFatPositions;
586     };
587
588 private:
589     std::unique_ptr<RareData> m_rareData;
590     Vector<ExpressionRangeInfo> m_expressionInfo;
591     struct TypeProfilerExpressionRange {
592         unsigned m_startDivot;
593         unsigned m_endDivot;
594     };
595     HashMap<unsigned, TypeProfilerExpressionRange> m_typeProfilerInfoMap;
596     Vector<size_t> m_opProfileControlFlowBytecodeOffsets;
597
598 protected:
599
600     static const unsigned StructureFlags = StructureIsImmortal | Base::StructureFlags;
601     static void visitChildren(JSCell*, SlotVisitor&);
602
603 public:
604     DECLARE_INFO;
605 };
606
607 class UnlinkedGlobalCodeBlock : public UnlinkedCodeBlock {
608 public:
609     typedef UnlinkedCodeBlock Base;
610
611 protected:
612     UnlinkedGlobalCodeBlock(VM* vm, Structure* structure, CodeType codeType, const ExecutableInfo& info)
613         : Base(vm, structure, codeType, info)
614     {
615     }
616
617     DECLARE_INFO;
618 };
619
620 class UnlinkedProgramCodeBlock : public UnlinkedGlobalCodeBlock {
621 private:
622     friend class CodeCache;
623     static UnlinkedProgramCodeBlock* create(VM* vm, const ExecutableInfo& info)
624     {
625         UnlinkedProgramCodeBlock* instance = new (NotNull, allocateCell<UnlinkedProgramCodeBlock>(vm->heap)) UnlinkedProgramCodeBlock(vm, vm->unlinkedProgramCodeBlockStructure.get(), info);
626         instance->finishCreation(*vm);
627         return instance;
628     }
629
630 public:
631     typedef UnlinkedGlobalCodeBlock Base;
632     static void destroy(JSCell*);
633
634     void addFunctionDeclaration(VM& vm, const Identifier& name, UnlinkedFunctionExecutable* functionExecutable)
635     {
636         m_functionDeclarations.append(std::make_pair(name, WriteBarrier<UnlinkedFunctionExecutable>(vm, this, functionExecutable)));
637     }
638
639     void addVariableDeclaration(const Identifier& name, bool isConstant)
640     {
641         m_varDeclarations.append(std::make_pair(name, isConstant));
642     }
643
644     typedef Vector<std::pair<Identifier, bool>> VariableDeclations;
645     typedef Vector<std::pair<Identifier, WriteBarrier<UnlinkedFunctionExecutable>> > FunctionDeclations;
646
647     const VariableDeclations& variableDeclarations() const { return m_varDeclarations; }
648     const FunctionDeclations& functionDeclarations() const { return m_functionDeclarations; }
649
650     static void visitChildren(JSCell*, SlotVisitor&);
651
652 private:
653     UnlinkedProgramCodeBlock(VM* vm, Structure* structure, const ExecutableInfo& info)
654         : Base(vm, structure, GlobalCode, info)
655     {
656     }
657
658     VariableDeclations m_varDeclarations;
659     FunctionDeclations m_functionDeclarations;
660
661 public:
662     static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto)
663     {
664         return Structure::create(vm, globalObject, proto, TypeInfo(UnlinkedProgramCodeBlockType, StructureFlags), info());
665     }
666
667     DECLARE_INFO;
668 };
669
670 class UnlinkedEvalCodeBlock : public UnlinkedGlobalCodeBlock {
671 private:
672     friend class CodeCache;
673
674     static UnlinkedEvalCodeBlock* create(VM* vm, const ExecutableInfo& info)
675     {
676         UnlinkedEvalCodeBlock* instance = new (NotNull, allocateCell<UnlinkedEvalCodeBlock>(vm->heap)) UnlinkedEvalCodeBlock(vm, vm->unlinkedEvalCodeBlockStructure.get(), info);
677         instance->finishCreation(*vm);
678         return instance;
679     }
680
681 public:
682     typedef UnlinkedGlobalCodeBlock Base;
683     static void destroy(JSCell*);
684
685     const Identifier& variable(unsigned index) { return m_variables[index]; }
686     unsigned numVariables() { return m_variables.size(); }
687     void adoptVariables(Vector<Identifier, 0, UnsafeVectorOverflow>& variables)
688     {
689         ASSERT(m_variables.isEmpty());
690         m_variables.swap(variables);
691     }
692
693 private:
694     UnlinkedEvalCodeBlock(VM* vm, Structure* structure, const ExecutableInfo& info)
695         : Base(vm, structure, EvalCode, info)
696     {
697     }
698
699     Vector<Identifier, 0, UnsafeVectorOverflow> m_variables;
700
701 public:
702     static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto)
703     {
704         return Structure::create(vm, globalObject, proto, TypeInfo(UnlinkedEvalCodeBlockType, StructureFlags), info());
705     }
706
707     DECLARE_INFO;
708 };
709
710 class UnlinkedFunctionCodeBlock : public UnlinkedCodeBlock {
711 public:
712     static UnlinkedFunctionCodeBlock* create(VM* vm, CodeType codeType, const ExecutableInfo& info)
713     {
714         UnlinkedFunctionCodeBlock* instance = new (NotNull, allocateCell<UnlinkedFunctionCodeBlock>(vm->heap)) UnlinkedFunctionCodeBlock(vm, vm->unlinkedFunctionCodeBlockStructure.get(), codeType, info);
715         instance->finishCreation(*vm);
716         return instance;
717     }
718
719     typedef UnlinkedCodeBlock Base;
720     static void destroy(JSCell*);
721
722 private:
723     UnlinkedFunctionCodeBlock(VM* vm, Structure* structure, CodeType codeType, const ExecutableInfo& info)
724         : Base(vm, structure, codeType, info)
725     {
726     }
727     
728 public:
729     static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto)
730     {
731         return Structure::create(vm, globalObject, proto, TypeInfo(UnlinkedFunctionCodeBlockType, StructureFlags), info());
732     }
733
734     DECLARE_INFO;
735 };
736
737 }
738
739 #endif // UnlinkedCodeBlock_h