2 * Copyright (C) 2012 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"
38 #include "SpecialPointer.h"
41 #include <wtf/RefCountedArray.h>
42 #include <wtf/Vector.h>
47 class FunctionBodyNode;
48 class FunctionExecutable;
49 class FunctionParameters;
51 class ScriptExecutable;
54 class SharedSymbolTable;
55 class UnlinkedCodeBlock;
56 class UnlinkedFunctionCodeBlock;
58 typedef unsigned UnlinkedValueProfile;
59 typedef unsigned UnlinkedArrayProfile;
60 typedef unsigned UnlinkedArrayAllocationProfile;
61 typedef unsigned UnlinkedObjectAllocationProfile;
62 typedef unsigned UnlinkedLLIntCallLinkInfo;
64 struct ExecutableInfo {
65 ExecutableInfo(bool needsActivation, bool usesEval, bool isStrictMode, bool isConstructor)
66 : m_needsActivation(needsActivation)
67 , m_usesEval(usesEval)
68 , m_isStrictMode(isStrictMode)
69 , m_isConstructor(isConstructor)
72 bool m_needsActivation;
78 class UnlinkedFunctionExecutable : public JSCell {
80 friend class CodeCache;
82 static UnlinkedFunctionExecutable* create(JSGlobalData* globalData, const SourceCode& source, FunctionBodyNode* node)
84 UnlinkedFunctionExecutable* instance = new (NotNull, allocateCell<UnlinkedFunctionExecutable>(globalData->heap)) UnlinkedFunctionExecutable(globalData, globalData->unlinkedFunctionExecutableStructure.get(), source, node);
85 instance->finishCreation(*globalData);
89 const Identifier& name() const { return m_name; }
90 const Identifier& inferredName() const { return m_inferredName; }
91 JSString* nameValue() const { return m_nameValue.get(); }
92 SharedSymbolTable* symbolTable(CodeSpecializationKind kind)
94 return (kind == CodeForCall) ? m_symbolTableForCall.get() : m_symbolTableForConstruct.get();
96 size_t parameterCount() const { return m_parameters->size(); }
97 bool isInStrictContext() const { return m_isInStrictContext; }
98 FunctionNameIsInScopeToggle functionNameIsInScopeToggle() const { return m_functionNameIsInScopeToggle; }
100 unsigned firstLineOffset() const { return m_firstLineOffset; }
101 unsigned lineCount() const { return m_lineCount; }
102 unsigned functionStartOffset() const { return m_functionStartOffset; }
103 unsigned startOffset() const { return m_startOffset; }
104 unsigned sourceLength() { return m_sourceLength; }
106 String paramString() const;
108 UnlinkedFunctionCodeBlock* codeBlockFor(JSGlobalData&, const SourceCode&, CodeSpecializationKind, DebuggerMode, ProfilerMode, ParserError&);
110 static UnlinkedFunctionExecutable* fromGlobalCode(const Identifier&, ExecState*, Debugger*, const SourceCode&, JSObject** exception);
112 FunctionExecutable* link(JSGlobalData&, const SourceCode&, size_t lineOffset, size_t sourceOffset);
114 void clearCodeForRecompilation()
116 m_symbolTableForCall.clear();
117 m_symbolTableForConstruct.clear();
118 m_codeBlockForCall.clear();
119 m_codeBlockForConstruct.clear();
122 FunctionParameters* parameters() { return m_parameters.get(); }
124 void recordParse(CodeFeatures features, bool hasCapturedVariables, int firstLine, int lastLine)
126 m_features = features;
127 m_hasCapturedVariables = hasCapturedVariables;
128 m_lineCount = lastLine - firstLine;
131 bool forceUsesArguments() const { return m_forceUsesArguments; }
133 CodeFeatures features() const { return m_features; }
134 bool hasCapturedVariables() const { return m_hasCapturedVariables; }
136 static const bool needsDestruction = true;
137 static const bool hasImmortalStructure = true;
138 static void destroy(JSCell*);
141 UnlinkedFunctionExecutable(JSGlobalData*, Structure*, const SourceCode&, FunctionBodyNode*);
142 Weak<UnlinkedFunctionCodeBlock> m_codeBlockForCall;
143 Weak<UnlinkedFunctionCodeBlock> m_codeBlockForConstruct;
145 unsigned m_numCapturedVariables : 29;
146 bool m_forceUsesArguments : 1;
147 bool m_isInStrictContext : 1;
148 bool m_hasCapturedVariables : 1;
151 Identifier m_inferredName;
152 WriteBarrier<JSString> m_nameValue;
153 WriteBarrier<SharedSymbolTable> m_symbolTableForCall;
154 WriteBarrier<SharedSymbolTable> m_symbolTableForConstruct;
155 RefPtr<FunctionParameters> m_parameters;
156 unsigned m_firstLineOffset;
157 unsigned m_lineCount;
158 unsigned m_functionStartOffset;
159 unsigned m_startOffset;
160 unsigned m_sourceLength;
162 CodeFeatures m_features;
164 FunctionNameIsInScopeToggle m_functionNameIsInScopeToggle;
167 void finishCreation(JSGlobalData& globalData)
169 Base::finishCreation(globalData);
170 m_nameValue.set(globalData, this, jsString(&globalData, name().string()));
173 static void visitChildren(JSCell*, SlotVisitor&);
176 static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue proto)
178 return Structure::create(globalData, globalObject, proto, TypeInfo(UnlinkedFunctionExecutableType, StructureFlags), &s_info);
181 static const unsigned StructureFlags = OverridesVisitChildren | JSCell::StructureFlags;
183 static const ClassInfo s_info;
186 struct UnlinkedStringJumpTable {
187 typedef HashMap<RefPtr<StringImpl>, int32_t> StringOffsetTable;
188 StringOffsetTable offsetTable;
190 inline int32_t offsetForValue(StringImpl* value, int32_t defaultOffset)
192 StringOffsetTable::const_iterator end = offsetTable.end();
193 StringOffsetTable::const_iterator loc = offsetTable.find(value);
195 return defaultOffset;
201 struct UnlinkedSimpleJumpTable {
202 Vector<int32_t> branchOffsets;
205 int32_t offsetForValue(int32_t value, int32_t defaultOffset);
206 void add(int32_t key, int32_t offset)
208 if (!branchOffsets[key])
209 branchOffsets[key] = offset;
213 struct UnlinkedHandlerInfo {
220 struct UnlinkedInstruction {
221 UnlinkedInstruction() { u.operand = 0; }
222 UnlinkedInstruction(OpcodeID opcode) { u.opcode = opcode; }
223 UnlinkedInstruction(int operand) { u.operand = operand; }
230 class UnlinkedCodeBlock : public JSCell {
233 static const bool needsDestruction = true;
234 static const bool hasImmortalStructure = true;
236 enum { CallFunction, ApplyFunction };
238 bool isConstructor() const { return m_isConstructor; }
239 bool isStrictMode() const { return m_isStrictMode; }
240 bool usesEval() const { return m_usesEval; }
242 bool needsFullScopeChain() const { return m_needsFullScopeChain; }
243 void setNeedsFullScopeChain(bool needsFullScopeChain) { m_needsFullScopeChain = needsFullScopeChain; }
245 void addExpressionInfo(const ExpressionRangeInfo& expressionInfo)
247 m_expressionInfo.append(expressionInfo);
250 void addLineInfo(unsigned bytecodeOffset, int lineNo)
252 Vector<LineInfo>& lineInfo = m_lineInfo;
253 if (!lineInfo.size() || lineInfo.last().lineNumber != lineNo) {
254 LineInfo info = { bytecodeOffset, lineNo };
255 lineInfo.append(info);
259 bool hasExpressionInfo() { return m_expressionInfo.size(); }
262 void setThisRegister(int thisRegister) { m_thisRegister = thisRegister; }
263 void setActivationRegister(int activationRegister) { m_activationRegister = activationRegister; }
265 void setArgumentsRegister(int argumentsRegister) { m_argumentsRegister = argumentsRegister; }
266 bool usesArguments() const { return m_argumentsRegister != -1; }
267 int argumentsRegister() const { return m_argumentsRegister; }
269 // Parameter information
270 void setNumParameters(int newValue) { m_numParameters = newValue; }
271 void addParameter() { m_numParameters++; }
272 unsigned numParameters() const { return m_numParameters; }
274 unsigned addRegExp(RegExp* r)
276 createRareDataIfNecessary();
277 unsigned size = m_rareData->m_regexps.size();
278 m_rareData->m_regexps.append(WriteBarrier<RegExp>(*m_globalData, this, r));
281 unsigned numberOfRegExps() const
285 return m_rareData->m_regexps.size();
287 RegExp* regexp(int index) const { ASSERT(m_rareData); return m_rareData->m_regexps[index].get(); }
291 size_t numberOfIdentifiers() const { return m_identifiers.size(); }
292 void addIdentifier(const Identifier& i) { return m_identifiers.append(i); }
293 const Identifier& identifier(int index) const { return m_identifiers[index]; }
294 const Vector<Identifier>& identifiers() const { return m_identifiers; }
296 size_t numberOfConstantRegisters() const { return m_constantRegisters.size(); }
297 unsigned addConstant(JSValue v)
299 unsigned result = m_constantRegisters.size();
300 m_constantRegisters.append(WriteBarrier<Unknown>());
301 m_constantRegisters.last().set(*m_globalData, this, v);
304 unsigned addOrFindConstant(JSValue);
305 const Vector<WriteBarrier<Unknown> >& constantRegisters() { return m_constantRegisters; }
306 const WriteBarrier<Unknown>& constantRegister(int index) const { return m_constantRegisters[index - FirstConstantRegisterIndex]; }
307 ALWAYS_INLINE bool isConstantRegisterIndex(int index) const { return index >= FirstConstantRegisterIndex; }
308 ALWAYS_INLINE JSValue getConstant(int index) const { return m_constantRegisters[index - FirstConstantRegisterIndex].get(); }
311 size_t numberOfJumpTargets() const { return m_jumpTargets.size(); }
312 void addJumpTarget(unsigned jumpTarget) { m_jumpTargets.append(jumpTarget); }
313 unsigned jumpTarget(int index) const { return m_jumpTargets[index]; }
314 unsigned lastJumpTarget() const { return m_jumpTargets.last(); }
316 void setIsNumericCompareFunction(bool isNumericCompareFunction) { m_isNumericCompareFunction = isNumericCompareFunction; }
317 bool isNumericCompareFunction() const { return m_isNumericCompareFunction; }
321 m_jumpTargets.shrinkToFit();
322 m_identifiers.shrinkToFit();
323 m_constantRegisters.shrinkToFit();
324 m_functionDecls.shrinkToFit();
325 m_functionExprs.shrinkToFit();
326 m_lineInfo.shrinkToFit();
327 m_propertyAccessInstructions.shrinkToFit();
328 m_expressionInfo.shrinkToFit();
330 #if ENABLE(BYTECODE_COMMENTS)
331 m_bytecodeComments.shrinkToFit();
334 m_rareData->m_exceptionHandlers.shrinkToFit();
335 m_rareData->m_regexps.shrinkToFit();
336 m_rareData->m_constantBuffers.shrinkToFit();
337 m_rareData->m_immediateSwitchJumpTables.shrinkToFit();
338 m_rareData->m_characterSwitchJumpTables.shrinkToFit();
339 m_rareData->m_stringSwitchJumpTables.shrinkToFit();
343 unsigned numberOfInstructions() const { return m_unlinkedInstructions.size(); }
344 RefCountedArray<UnlinkedInstruction>& instructions() { return m_unlinkedInstructions; }
345 const RefCountedArray<UnlinkedInstruction>& instructions() const { return m_unlinkedInstructions; }
348 int m_numCapturedVars;
349 int m_numCalleeRegisters;
353 size_t numberOfImmediateSwitchJumpTables() const { return m_rareData ? m_rareData->m_immediateSwitchJumpTables.size() : 0; }
354 UnlinkedSimpleJumpTable& addImmediateSwitchJumpTable() { createRareDataIfNecessary(); m_rareData->m_immediateSwitchJumpTables.append(UnlinkedSimpleJumpTable()); return m_rareData->m_immediateSwitchJumpTables.last(); }
355 UnlinkedSimpleJumpTable& immediateSwitchJumpTable(int tableIndex) { ASSERT(m_rareData); return m_rareData->m_immediateSwitchJumpTables[tableIndex]; }
357 size_t numberOfCharacterSwitchJumpTables() const { return m_rareData ? m_rareData->m_characterSwitchJumpTables.size() : 0; }
358 UnlinkedSimpleJumpTable& addCharacterSwitchJumpTable() { createRareDataIfNecessary(); m_rareData->m_characterSwitchJumpTables.append(UnlinkedSimpleJumpTable()); return m_rareData->m_characterSwitchJumpTables.last(); }
359 UnlinkedSimpleJumpTable& characterSwitchJumpTable(int tableIndex) { ASSERT(m_rareData); return m_rareData->m_characterSwitchJumpTables[tableIndex]; }
361 size_t numberOfStringSwitchJumpTables() const { return m_rareData ? m_rareData->m_stringSwitchJumpTables.size() : 0; }
362 UnlinkedStringJumpTable& addStringSwitchJumpTable() { createRareDataIfNecessary(); m_rareData->m_stringSwitchJumpTables.append(UnlinkedStringJumpTable()); return m_rareData->m_stringSwitchJumpTables.last(); }
363 UnlinkedStringJumpTable& stringSwitchJumpTable(int tableIndex) { ASSERT(m_rareData); return m_rareData->m_stringSwitchJumpTables[tableIndex]; }
365 unsigned addFunctionDecl(UnlinkedFunctionExecutable* n)
367 unsigned size = m_functionDecls.size();
368 m_functionDecls.append(WriteBarrier<UnlinkedFunctionExecutable>());
369 m_functionDecls.last().set(*m_globalData, this, n);
372 UnlinkedFunctionExecutable* functionDecl(int index) { return m_functionDecls[index].get(); }
373 size_t numberOfFunctionDecls() { return m_functionDecls.size(); }
374 unsigned addFunctionExpr(UnlinkedFunctionExecutable* n)
376 unsigned size = m_functionExprs.size();
377 m_functionExprs.append(WriteBarrier<UnlinkedFunctionExecutable>());
378 m_functionExprs.last().set(*m_globalData, this, n);
381 UnlinkedFunctionExecutable* functionExpr(int index) { return m_functionExprs[index].get(); }
382 size_t numberOfFunctionExprs() { return m_functionExprs.size(); }
384 // Exception handling support
385 size_t numberOfExceptionHandlers() const { return m_rareData ? m_rareData->m_exceptionHandlers.size() : 0; }
386 void addExceptionHandler(const UnlinkedHandlerInfo& hanler) { createRareDataIfNecessary(); return m_rareData->m_exceptionHandlers.append(hanler); }
387 UnlinkedHandlerInfo& exceptionHandler(int index) { ASSERT(m_rareData); return m_rareData->m_exceptionHandlers[index]; }
389 SharedSymbolTable* symbolTable() const { return m_symbolTable.get(); }
391 JSGlobalData* globalData() const { return m_globalData; }
393 unsigned addResolve() { return m_resolveOperationCount++; }
394 unsigned numberOfResolveOperations() const { return m_resolveOperationCount; }
395 unsigned addPutToBase() { return m_putToBaseOperationCount++; }
396 unsigned numberOfPutToBaseOperations() const { return m_putToBaseOperationCount; }
398 UnlinkedArrayProfile addArrayProfile() { return m_arrayProfileCount++; }
399 unsigned numberOfArrayProfiles() { return m_arrayProfileCount; }
400 UnlinkedArrayAllocationProfile addArrayAllocationProfile() { return m_arrayAllocationProfileCount++; }
401 unsigned numberOfArrayAllocationProfiles() { return m_arrayAllocationProfileCount; }
402 UnlinkedObjectAllocationProfile addObjectAllocationProfile() { return m_objectAllocationProfileCount++; }
403 unsigned numberOfObjectAllocationProfiles() { return m_objectAllocationProfileCount; }
404 UnlinkedValueProfile addValueProfile() { return m_valueProfileCount++; }
405 unsigned numberOfValueProfiles() { return m_valueProfileCount; }
407 UnlinkedLLIntCallLinkInfo addLLIntCallLinkInfo() { return m_llintCallLinkInfoCount++; }
408 unsigned numberOfLLintCallLinkInfos() { return m_llintCallLinkInfoCount; }
410 CodeType codeType() const { return m_codeType; }
412 int thisRegister() const { return m_thisRegister; }
413 int activationRegister() const { return m_activationRegister; }
416 void addPropertyAccessInstruction(unsigned propertyAccessInstruction)
418 m_propertyAccessInstructions.append(propertyAccessInstruction);
421 size_t numberOfPropertyAccessInstructions() const { return m_propertyAccessInstructions.size(); }
422 const Vector<unsigned>& propertyAccessInstructions() const { return m_propertyAccessInstructions; }
424 typedef Vector<JSValue> ConstantBuffer;
426 size_t constantBufferCount() { ASSERT(m_rareData); return m_rareData->m_constantBuffers.size(); }
427 unsigned addConstantBuffer(unsigned length)
429 createRareDataIfNecessary();
430 unsigned size = m_rareData->m_constantBuffers.size();
431 m_rareData->m_constantBuffers.append(Vector<JSValue>(length));
435 const ConstantBuffer& constantBuffer(unsigned index) const
438 return m_rareData->m_constantBuffers[index];
441 ConstantBuffer& constantBuffer(unsigned index)
444 return m_rareData->m_constantBuffers[index];
447 bool hasRareData() const { return m_rareData; }
449 int lineNumberForBytecodeOffset(unsigned bytecodeOffset);
451 void expressionRangeForBytecodeOffset(unsigned bytecodeOffset, int& divot, int& startOffset, int& endOffset);
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; }
467 UnlinkedCodeBlock(JSGlobalData*, Structure*, CodeType, const ExecutableInfo&);
468 ~UnlinkedCodeBlock();
470 void finishCreation(JSGlobalData& globalData)
472 Base::finishCreation(globalData);
473 if (codeType() == GlobalCode)
475 m_symbolTable.set(globalData, this, SharedSymbolTable::create(globalData));
480 void createRareDataIfNecessary()
483 m_rareData = adoptPtr(new RareData);
486 RefCountedArray<UnlinkedInstruction> m_unlinkedInstructions;
490 int m_argumentsRegister;
491 int m_activationRegister;
493 bool m_needsFullScopeChain : 1;
495 bool m_isNumericCompareFunction : 1;
496 bool m_isStrictMode : 1;
497 bool m_isConstructor : 1;
498 bool m_hasCapturedVariables : 1;
499 CodeType m_codeType : 2;
500 CodeFeatures m_features : 16;
502 unsigned m_firstLine;
503 unsigned m_lineCount;
505 unsigned m_resolveOperationCount;
506 unsigned m_putToBaseOperationCount;
507 unsigned m_arrayProfileCount;
508 unsigned m_arrayAllocationProfileCount;
509 unsigned m_objectAllocationProfileCount;
510 unsigned m_valueProfileCount;
511 unsigned m_llintCallLinkInfoCount;
513 JSGlobalData* m_globalData;
515 Vector<unsigned> m_jumpTargets;
518 Vector<Identifier> m_identifiers;
519 Vector<WriteBarrier<Unknown> > m_constantRegisters;
520 typedef Vector<WriteBarrier<UnlinkedFunctionExecutable> > FunctionExpressionVector;
521 FunctionExpressionVector m_functionDecls;
522 FunctionExpressionVector m_functionExprs;
524 WriteBarrier<SharedSymbolTable> m_symbolTable;
526 Vector<LineInfo> m_lineInfo;
528 Vector<unsigned> m_propertyAccessInstructions;
530 #if ENABLE(BYTECODE_COMMENTS)
531 Vector<Comment> m_bytecodeComments;
532 size_t m_bytecodeCommentIterator;
537 WTF_MAKE_FAST_ALLOCATED;
539 Vector<UnlinkedHandlerInfo> m_exceptionHandlers;
542 Vector<WriteBarrier<RegExp> > m_regexps;
544 // Buffers used for large array literals
545 Vector<ConstantBuffer> m_constantBuffers;
548 Vector<UnlinkedSimpleJumpTable> m_immediateSwitchJumpTables;
549 Vector<UnlinkedSimpleJumpTable> m_characterSwitchJumpTables;
550 Vector<UnlinkedStringJumpTable> m_stringSwitchJumpTables;
552 // Expression info - present if debugging.
556 OwnPtr<RareData> m_rareData;
557 Vector<ExpressionRangeInfo> m_expressionInfo;
561 static const unsigned StructureFlags = OverridesVisitChildren | Base::StructureFlags;
562 static void visitChildren(JSCell*, SlotVisitor&);
565 static const ClassInfo s_info;
568 class UnlinkedGlobalCodeBlock : public UnlinkedCodeBlock {
570 typedef UnlinkedCodeBlock Base;
573 UnlinkedGlobalCodeBlock(JSGlobalData* globalData, Structure* structure, CodeType codeType, const ExecutableInfo& info)
574 : Base(globalData, structure, codeType, info)
578 static const unsigned StructureFlags = OverridesVisitChildren | Base::StructureFlags;
580 static const ClassInfo s_info;
583 class UnlinkedProgramCodeBlock : public UnlinkedGlobalCodeBlock {
585 friend class CodeCache;
586 static UnlinkedProgramCodeBlock* create(JSGlobalData* globalData, const ExecutableInfo& info)
588 UnlinkedProgramCodeBlock* instance = new (NotNull, allocateCell<UnlinkedProgramCodeBlock>(globalData->heap)) UnlinkedProgramCodeBlock(globalData, globalData->unlinkedProgramCodeBlockStructure.get(), info);
589 instance->finishCreation(*globalData);
594 typedef UnlinkedGlobalCodeBlock Base;
595 static void destroy(JSCell*);
597 void addFunctionDeclaration(JSGlobalData& globalData, const Identifier& name, UnlinkedFunctionExecutable* functionExecutable)
599 m_functionDeclarations.append(std::make_pair(name, WriteBarrier<UnlinkedFunctionExecutable>(globalData, this, functionExecutable)));
602 void addVariableDeclaration(const Identifier& name, bool isConstant)
604 m_varDeclarations.append(std::make_pair(name, isConstant));
607 typedef Vector<std::pair<Identifier, bool> > VariableDeclations;
608 typedef Vector<std::pair<Identifier, WriteBarrier<UnlinkedFunctionExecutable> > > FunctionDeclations;
610 const VariableDeclations& variableDeclarations() const { return m_varDeclarations; }
611 const FunctionDeclations& functionDeclarations() const { return m_functionDeclarations; }
613 static void visitChildren(JSCell*, SlotVisitor&);
616 UnlinkedProgramCodeBlock(JSGlobalData* globalData, Structure* structure, const ExecutableInfo& info)
617 : Base(globalData, structure, GlobalCode, info)
621 VariableDeclations m_varDeclarations;
622 FunctionDeclations m_functionDeclarations;
625 static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue proto)
627 return Structure::create(globalData, globalObject, proto, TypeInfo(UnlinkedProgramCodeBlockType, StructureFlags), &s_info);
630 static const unsigned StructureFlags = OverridesVisitChildren | Base::StructureFlags;
632 static const ClassInfo s_info;
635 class UnlinkedEvalCodeBlock : public UnlinkedGlobalCodeBlock {
637 friend class CodeCache;
639 static UnlinkedEvalCodeBlock* create(JSGlobalData* globalData, const ExecutableInfo& info)
641 UnlinkedEvalCodeBlock* instance = new (NotNull, allocateCell<UnlinkedEvalCodeBlock>(globalData->heap)) UnlinkedEvalCodeBlock(globalData, globalData->unlinkedEvalCodeBlockStructure.get(), info);
642 instance->finishCreation(*globalData);
647 typedef UnlinkedGlobalCodeBlock Base;
648 static void destroy(JSCell*);
650 const Identifier& variable(unsigned index) { return m_variables[index]; }
651 unsigned numVariables() { return m_variables.size(); }
652 void adoptVariables(Vector<Identifier>& variables)
654 ASSERT(m_variables.isEmpty());
655 m_variables.swap(variables);
659 UnlinkedEvalCodeBlock(JSGlobalData* globalData, Structure* structure, const ExecutableInfo& info)
660 : Base(globalData, structure, EvalCode, info)
664 Vector<Identifier> m_variables;
667 static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue proto)
669 return Structure::create(globalData, globalObject, proto, TypeInfo(UnlinkedEvalCodeBlockType, StructureFlags), &s_info);
672 static const unsigned StructureFlags = OverridesVisitChildren | Base::StructureFlags;
674 static const ClassInfo s_info;
677 class UnlinkedFunctionCodeBlock : public UnlinkedCodeBlock {
679 friend class CodeCache;
681 static UnlinkedFunctionCodeBlock* create(JSGlobalData* globalData, CodeType codeType, const ExecutableInfo& info)
683 UnlinkedFunctionCodeBlock* instance = new (NotNull, allocateCell<UnlinkedFunctionCodeBlock>(globalData->heap)) UnlinkedFunctionCodeBlock(globalData, globalData->unlinkedFunctionCodeBlockStructure.get(), codeType, info);
684 instance->finishCreation(*globalData);
689 typedef UnlinkedCodeBlock Base;
690 static void destroy(JSCell*);
693 UnlinkedFunctionCodeBlock(JSGlobalData* globalData, Structure* structure, CodeType codeType, const ExecutableInfo& info)
694 : Base(globalData, structure, codeType, info)
699 static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue proto)
701 return Structure::create(globalData, globalObject, proto, TypeInfo(UnlinkedFunctionCodeBlockType, StructureFlags), &s_info);
704 static const unsigned StructureFlags = OverridesVisitChildren | Base::StructureFlags;
706 static const ClassInfo s_info;
711 #endif // UnlinkedCodeBlock_h