2 * Copyright (C) 2012, 2013 Apple Inc. All Rights Reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 #ifndef UnlinkedCodeBlock_h
27 #define UnlinkedCodeBlock_h
29 #include "BytecodeConventions.h"
30 #include "CodeSpecializationKind.h"
32 #include "ExpressionRangeInfo.h"
33 #include "Identifier.h"
37 #include "ParserModes.h"
39 #include "SpecialPointer.h"
40 #include "SymbolTable.h"
41 #include "VirtualRegister.h"
43 #include <wtf/Compression.h>
44 #include <wtf/RefCountedArray.h>
45 #include <wtf/Vector.h>
50 class FunctionBodyNode;
51 class FunctionExecutable;
52 class FunctionParameters;
55 class ScriptExecutable;
58 class SharedSymbolTable;
59 class UnlinkedCodeBlock;
60 class UnlinkedFunctionCodeBlock;
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)
70 : m_needsActivation(needsActivation)
71 , m_usesEval(usesEval)
72 , m_isStrictMode(isStrictMode)
73 , m_isConstructor(isConstructor)
76 bool m_needsActivation;
82 class UnlinkedFunctionExecutable : public JSCell {
84 friend class CodeCache;
86 static UnlinkedFunctionExecutable* create(VM* vm, const SourceCode& source, FunctionBodyNode* node)
88 UnlinkedFunctionExecutable* instance = new (NotNull, allocateCell<UnlinkedFunctionExecutable>(vm->heap)) UnlinkedFunctionExecutable(vm, vm->unlinkedFunctionExecutableStructure.get(), source, node);
89 instance->finishCreation(*vm);
93 const Identifier& name() const { return m_name; }
94 const Identifier& inferredName() const { return m_inferredName; }
95 JSString* nameValue() const { return m_nameValue.get(); }
96 SharedSymbolTable* symbolTable(CodeSpecializationKind kind)
98 return (kind == CodeForCall) ? m_symbolTableForCall.get() : m_symbolTableForConstruct.get();
100 size_t parameterCount() const;
101 bool isInStrictContext() const { return m_isInStrictContext; }
102 FunctionNameIsInScopeToggle functionNameIsInScopeToggle() const { return m_functionNameIsInScopeToggle; }
104 unsigned firstLineOffset() const { return m_firstLineOffset; }
105 unsigned lineCount() const { return m_lineCount; }
106 unsigned functionStartOffset() const { return m_functionStartOffset; }
107 unsigned functionStartColumn() const { return m_functionStartColumn; }
108 unsigned startOffset() const { return m_startOffset; }
109 unsigned sourceLength() { return m_sourceLength; }
111 String paramString() const;
113 UnlinkedFunctionCodeBlock* codeBlockFor(VM&, const SourceCode&, CodeSpecializationKind, DebuggerMode, ProfilerMode, ParserError&);
115 static UnlinkedFunctionExecutable* fromGlobalCode(const Identifier&, ExecState*, Debugger*, const SourceCode&, JSObject** exception);
117 FunctionExecutable* link(VM&, const SourceCode&, size_t lineOffset, size_t sourceOffset);
119 void clearCodeForRecompilation()
121 m_symbolTableForCall.clear();
122 m_symbolTableForConstruct.clear();
123 m_codeBlockForCall.clear();
124 m_codeBlockForConstruct.clear();
127 FunctionParameters* parameters() { return m_parameters.get(); }
129 void recordParse(CodeFeatures features, bool hasCapturedVariables, int firstLine, int lastLine)
131 m_features = features;
132 m_hasCapturedVariables = hasCapturedVariables;
133 m_lineCount = lastLine - firstLine;
136 bool forceUsesArguments() const { return m_forceUsesArguments; }
138 CodeFeatures features() const { return m_features; }
139 bool hasCapturedVariables() const { return m_hasCapturedVariables; }
141 static const bool needsDestruction = true;
142 static const bool hasImmortalStructure = true;
143 static void destroy(JSCell*);
146 UnlinkedFunctionExecutable(VM*, Structure*, const SourceCode&, FunctionBodyNode*);
147 WriteBarrier<UnlinkedFunctionCodeBlock> m_codeBlockForCall;
148 WriteBarrier<UnlinkedFunctionCodeBlock> m_codeBlockForConstruct;
150 unsigned m_numCapturedVariables : 29;
151 bool m_forceUsesArguments : 1;
152 bool m_isInStrictContext : 1;
153 bool m_hasCapturedVariables : 1;
156 Identifier m_inferredName;
157 WriteBarrier<JSString> m_nameValue;
158 WriteBarrier<SharedSymbolTable> m_symbolTableForCall;
159 WriteBarrier<SharedSymbolTable> m_symbolTableForConstruct;
160 RefPtr<FunctionParameters> m_parameters;
161 unsigned m_firstLineOffset;
162 unsigned m_lineCount;
163 unsigned m_functionStartOffset;
164 unsigned m_functionStartColumn;
165 unsigned m_startOffset;
166 unsigned m_sourceLength;
168 CodeFeatures m_features;
170 FunctionNameIsInScopeToggle m_functionNameIsInScopeToggle;
173 void finishCreation(VM& vm)
175 Base::finishCreation(vm);
176 m_nameValue.set(vm, this, jsString(&vm, name().string()));
179 static void visitChildren(JSCell*, SlotVisitor&);
182 static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto)
184 return Structure::create(vm, globalObject, proto, TypeInfo(UnlinkedFunctionExecutableType, StructureFlags), info());
187 static const unsigned StructureFlags = OverridesVisitChildren | JSCell::StructureFlags;
192 struct UnlinkedStringJumpTable {
193 typedef HashMap<RefPtr<StringImpl>, int32_t> StringOffsetTable;
194 StringOffsetTable offsetTable;
196 inline int32_t offsetForValue(StringImpl* value, int32_t defaultOffset)
198 StringOffsetTable::const_iterator end = offsetTable.end();
199 StringOffsetTable::const_iterator loc = offsetTable.find(value);
201 return defaultOffset;
207 struct UnlinkedSimpleJumpTable {
208 Vector<int32_t> branchOffsets;
211 int32_t offsetForValue(int32_t value, int32_t defaultOffset);
212 void add(int32_t key, int32_t offset)
214 if (!branchOffsets[key])
215 branchOffsets[key] = offset;
219 struct UnlinkedHandlerInfo {
226 struct UnlinkedInstruction {
227 UnlinkedInstruction() { u.operand = 0; }
228 UnlinkedInstruction(OpcodeID opcode) { u.opcode = opcode; }
229 UnlinkedInstruction(int operand) { u.operand = operand; }
236 class UnlinkedCodeBlock : public JSCell {
239 static const bool needsDestruction = true;
240 static const bool hasImmortalStructure = true;
242 enum { CallFunction, ApplyFunction };
244 bool isConstructor() const { return m_isConstructor; }
245 bool isStrictMode() const { return m_isStrictMode; }
246 bool usesEval() const { return m_usesEval; }
248 bool needsFullScopeChain() const { return m_needsFullScopeChain; }
249 void setNeedsFullScopeChain(bool needsFullScopeChain) { m_needsFullScopeChain = needsFullScopeChain; }
251 void addExpressionInfo(unsigned instructionOffset, int divot,
252 int startOffset, int endOffset, unsigned line, unsigned column);
254 bool hasExpressionInfo() { return m_expressionInfo.size(); }
257 void setThisRegister(int thisRegister) { m_thisRegister = thisRegister; }
258 void setActivationRegister(int activationRegister) { m_activationRegister = activationRegister; }
260 void setArgumentsRegister(int argumentsRegister) { m_argumentsRegister = argumentsRegister; }
261 bool usesArguments() const { return m_argumentsRegister != (int)InvalidVirtualRegister; }
262 int argumentsRegister() const { return m_argumentsRegister; }
265 bool usesGlobalObject() const { return m_globalObjectRegister != (int)InvalidVirtualRegister; }
266 void setGlobalObjectRegister(int globalObjectRegister) { m_globalObjectRegister = globalObjectRegister; }
267 int globalObjectRegister() const { return m_globalObjectRegister; }
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_vm, 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_vm, 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_propertyAccessInstructions.shrinkToFit();
327 m_expressionInfo.shrinkToFit();
329 #if ENABLE(BYTECODE_COMMENTS)
330 m_bytecodeComments.shrinkToFit();
333 m_rareData->m_exceptionHandlers.shrinkToFit();
334 m_rareData->m_regexps.shrinkToFit();
335 m_rareData->m_constantBuffers.shrinkToFit();
336 m_rareData->m_switchJumpTables.shrinkToFit();
337 m_rareData->m_stringSwitchJumpTables.shrinkToFit();
338 m_rareData->m_expressionInfoFatPositions.shrinkToFit();
342 unsigned numberOfInstructions() const { return m_unlinkedInstructions.size(); }
343 RefCountedArray<UnlinkedInstruction>& instructions() { return m_unlinkedInstructions; }
344 const RefCountedArray<UnlinkedInstruction>& instructions() const { return m_unlinkedInstructions; }
347 int m_numCapturedVars;
348 int m_numCalleeRegisters;
352 size_t numberOfSwitchJumpTables() const { return m_rareData ? m_rareData->m_switchJumpTables.size() : 0; }
353 UnlinkedSimpleJumpTable& addSwitchJumpTable() { createRareDataIfNecessary(); m_rareData->m_switchJumpTables.append(UnlinkedSimpleJumpTable()); return m_rareData->m_switchJumpTables.last(); }
354 UnlinkedSimpleJumpTable& switchJumpTable(int tableIndex) { ASSERT(m_rareData); return m_rareData->m_switchJumpTables[tableIndex]; }
356 size_t numberOfStringSwitchJumpTables() const { return m_rareData ? m_rareData->m_stringSwitchJumpTables.size() : 0; }
357 UnlinkedStringJumpTable& addStringSwitchJumpTable() { createRareDataIfNecessary(); m_rareData->m_stringSwitchJumpTables.append(UnlinkedStringJumpTable()); return m_rareData->m_stringSwitchJumpTables.last(); }
358 UnlinkedStringJumpTable& stringSwitchJumpTable(int tableIndex) { ASSERT(m_rareData); return m_rareData->m_stringSwitchJumpTables[tableIndex]; }
360 unsigned addFunctionDecl(UnlinkedFunctionExecutable* n)
362 unsigned size = m_functionDecls.size();
363 m_functionDecls.append(WriteBarrier<UnlinkedFunctionExecutable>());
364 m_functionDecls.last().set(*m_vm, this, n);
367 UnlinkedFunctionExecutable* functionDecl(int index) { return m_functionDecls[index].get(); }
368 size_t numberOfFunctionDecls() { return m_functionDecls.size(); }
369 unsigned addFunctionExpr(UnlinkedFunctionExecutable* n)
371 unsigned size = m_functionExprs.size();
372 m_functionExprs.append(WriteBarrier<UnlinkedFunctionExecutable>());
373 m_functionExprs.last().set(*m_vm, this, n);
376 UnlinkedFunctionExecutable* functionExpr(int index) { return m_functionExprs[index].get(); }
377 size_t numberOfFunctionExprs() { return m_functionExprs.size(); }
379 // Exception handling support
380 size_t numberOfExceptionHandlers() const { return m_rareData ? m_rareData->m_exceptionHandlers.size() : 0; }
381 void addExceptionHandler(const UnlinkedHandlerInfo& hanler) { createRareDataIfNecessary(); return m_rareData->m_exceptionHandlers.append(hanler); }
382 UnlinkedHandlerInfo& exceptionHandler(int index) { ASSERT(m_rareData); return m_rareData->m_exceptionHandlers[index]; }
384 SharedSymbolTable* symbolTable() const { return m_symbolTable.get(); }
386 VM* vm() const { return m_vm; }
388 UnlinkedArrayProfile addArrayProfile() { return m_arrayProfileCount++; }
389 unsigned numberOfArrayProfiles() { return m_arrayProfileCount; }
390 UnlinkedArrayAllocationProfile addArrayAllocationProfile() { return m_arrayAllocationProfileCount++; }
391 unsigned numberOfArrayAllocationProfiles() { return m_arrayAllocationProfileCount; }
392 UnlinkedObjectAllocationProfile addObjectAllocationProfile() { return m_objectAllocationProfileCount++; }
393 unsigned numberOfObjectAllocationProfiles() { return m_objectAllocationProfileCount; }
394 UnlinkedValueProfile addValueProfile() { return m_valueProfileCount++; }
395 unsigned numberOfValueProfiles() { return m_valueProfileCount; }
397 UnlinkedLLIntCallLinkInfo addLLIntCallLinkInfo() { return m_llintCallLinkInfoCount++; }
398 unsigned numberOfLLintCallLinkInfos() { return m_llintCallLinkInfoCount; }
400 CodeType codeType() const { return m_codeType; }
402 int thisRegister() const { return m_thisRegister; }
403 int activationRegister() const { return m_activationRegister; }
406 void addPropertyAccessInstruction(unsigned propertyAccessInstruction)
408 m_propertyAccessInstructions.append(propertyAccessInstruction);
411 size_t numberOfPropertyAccessInstructions() const { return m_propertyAccessInstructions.size(); }
412 const Vector<unsigned>& propertyAccessInstructions() const { return m_propertyAccessInstructions; }
414 typedef Vector<JSValue> ConstantBuffer;
416 size_t constantBufferCount() { ASSERT(m_rareData); return m_rareData->m_constantBuffers.size(); }
417 unsigned addConstantBuffer(unsigned length)
419 createRareDataIfNecessary();
420 unsigned size = m_rareData->m_constantBuffers.size();
421 m_rareData->m_constantBuffers.append(Vector<JSValue>(length));
425 const ConstantBuffer& constantBuffer(unsigned index) const
428 return m_rareData->m_constantBuffers[index];
431 ConstantBuffer& constantBuffer(unsigned index)
434 return m_rareData->m_constantBuffers[index];
437 bool hasRareData() const { return m_rareData; }
439 int lineNumberForBytecodeOffset(unsigned bytecodeOffset);
441 void expressionRangeForBytecodeOffset(unsigned bytecodeOffset, int& divot,
442 int& startOffset, int& endOffset, unsigned& line, unsigned& column);
444 void recordParse(CodeFeatures features, bool hasCapturedVariables, unsigned firstLine, unsigned lineCount)
446 m_features = features;
447 m_hasCapturedVariables = hasCapturedVariables;
448 m_firstLine = firstLine;
449 m_lineCount = lineCount;
452 CodeFeatures codeFeatures() const { return m_features; }
453 bool hasCapturedVariables() const { return m_hasCapturedVariables; }
454 unsigned firstLine() const { return m_firstLine; }
455 unsigned lineCount() const { return m_lineCount; }
458 UnlinkedCodeBlock(VM*, Structure*, CodeType, const ExecutableInfo&);
459 ~UnlinkedCodeBlock();
461 void finishCreation(VM& vm)
463 Base::finishCreation(vm);
464 if (codeType() == GlobalCode)
466 m_symbolTable.set(vm, this, SharedSymbolTable::create(vm));
471 void createRareDataIfNecessary()
474 m_rareData = adoptPtr(new RareData);
477 RefCountedArray<UnlinkedInstruction> m_unlinkedInstructions;
483 int m_argumentsRegister;
484 int m_activationRegister;
485 int m_globalObjectRegister;
487 bool m_needsFullScopeChain : 1;
489 bool m_isNumericCompareFunction : 1;
490 bool m_isStrictMode : 1;
491 bool m_isConstructor : 1;
492 bool m_hasCapturedVariables : 1;
493 unsigned m_firstLine;
494 unsigned m_lineCount;
496 CodeFeatures m_features;
499 Vector<unsigned> m_jumpTargets;
502 Vector<Identifier> m_identifiers;
503 Vector<WriteBarrier<Unknown> > m_constantRegisters;
504 typedef Vector<WriteBarrier<UnlinkedFunctionExecutable> > FunctionExpressionVector;
505 FunctionExpressionVector m_functionDecls;
506 FunctionExpressionVector m_functionExprs;
508 WriteBarrier<SharedSymbolTable> m_symbolTable;
510 Vector<unsigned> m_propertyAccessInstructions;
512 #if ENABLE(BYTECODE_COMMENTS)
513 Vector<Comment> m_bytecodeComments;
514 size_t m_bytecodeCommentIterator;
517 unsigned m_arrayProfileCount;
518 unsigned m_arrayAllocationProfileCount;
519 unsigned m_objectAllocationProfileCount;
520 unsigned m_valueProfileCount;
521 unsigned m_llintCallLinkInfoCount;
525 WTF_MAKE_FAST_ALLOCATED;
527 Vector<UnlinkedHandlerInfo> m_exceptionHandlers;
530 Vector<WriteBarrier<RegExp> > m_regexps;
532 // Buffers used for large array literals
533 Vector<ConstantBuffer> m_constantBuffers;
536 Vector<UnlinkedSimpleJumpTable> m_switchJumpTables;
537 Vector<UnlinkedStringJumpTable> m_stringSwitchJumpTables;
539 Vector<ExpressionRangeInfo::FatPosition> m_expressionInfoFatPositions;
543 OwnPtr<RareData> m_rareData;
544 Vector<ExpressionRangeInfo> m_expressionInfo;
548 static const unsigned StructureFlags = OverridesVisitChildren | Base::StructureFlags;
549 static void visitChildren(JSCell*, SlotVisitor&);
555 class UnlinkedGlobalCodeBlock : public UnlinkedCodeBlock {
557 typedef UnlinkedCodeBlock Base;
560 UnlinkedGlobalCodeBlock(VM* vm, Structure* structure, CodeType codeType, const ExecutableInfo& info)
561 : Base(vm, structure, codeType, info)
565 static const unsigned StructureFlags = OverridesVisitChildren | Base::StructureFlags;
570 class UnlinkedProgramCodeBlock : public UnlinkedGlobalCodeBlock {
572 friend class CodeCache;
573 static UnlinkedProgramCodeBlock* create(VM* vm, const ExecutableInfo& info)
575 UnlinkedProgramCodeBlock* instance = new (NotNull, allocateCell<UnlinkedProgramCodeBlock>(vm->heap)) UnlinkedProgramCodeBlock(vm, vm->unlinkedProgramCodeBlockStructure.get(), info);
576 instance->finishCreation(*vm);
581 typedef UnlinkedGlobalCodeBlock Base;
582 static void destroy(JSCell*);
584 void addFunctionDeclaration(VM& vm, const Identifier& name, UnlinkedFunctionExecutable* functionExecutable)
586 m_functionDeclarations.append(std::make_pair(name, WriteBarrier<UnlinkedFunctionExecutable>(vm, this, functionExecutable)));
589 void addVariableDeclaration(const Identifier& name, bool isConstant)
591 m_varDeclarations.append(std::make_pair(name, isConstant));
594 typedef Vector<std::pair<Identifier, bool> > VariableDeclations;
595 typedef Vector<std::pair<Identifier, WriteBarrier<UnlinkedFunctionExecutable> > > FunctionDeclations;
597 const VariableDeclations& variableDeclarations() const { return m_varDeclarations; }
598 const FunctionDeclations& functionDeclarations() const { return m_functionDeclarations; }
600 static void visitChildren(JSCell*, SlotVisitor&);
603 UnlinkedProgramCodeBlock(VM* vm, Structure* structure, const ExecutableInfo& info)
604 : Base(vm, structure, GlobalCode, info)
608 VariableDeclations m_varDeclarations;
609 FunctionDeclations m_functionDeclarations;
612 static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto)
614 return Structure::create(vm, globalObject, proto, TypeInfo(UnlinkedProgramCodeBlockType, StructureFlags), info());
617 static const unsigned StructureFlags = OverridesVisitChildren | Base::StructureFlags;
622 class UnlinkedEvalCodeBlock : public UnlinkedGlobalCodeBlock {
624 friend class CodeCache;
626 static UnlinkedEvalCodeBlock* create(VM* vm, const ExecutableInfo& info)
628 UnlinkedEvalCodeBlock* instance = new (NotNull, allocateCell<UnlinkedEvalCodeBlock>(vm->heap)) UnlinkedEvalCodeBlock(vm, vm->unlinkedEvalCodeBlockStructure.get(), info);
629 instance->finishCreation(*vm);
634 typedef UnlinkedGlobalCodeBlock Base;
635 static void destroy(JSCell*);
637 const Identifier& variable(unsigned index) { return m_variables[index]; }
638 unsigned numVariables() { return m_variables.size(); }
639 void adoptVariables(Vector<Identifier, 0, UnsafeVectorOverflow>& variables)
641 ASSERT(m_variables.isEmpty());
642 m_variables.swap(variables);
646 UnlinkedEvalCodeBlock(VM* vm, Structure* structure, const ExecutableInfo& info)
647 : Base(vm, structure, EvalCode, info)
651 Vector<Identifier, 0, UnsafeVectorOverflow> m_variables;
654 static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto)
656 return Structure::create(vm, globalObject, proto, TypeInfo(UnlinkedEvalCodeBlockType, StructureFlags), info());
659 static const unsigned StructureFlags = OverridesVisitChildren | Base::StructureFlags;
664 class UnlinkedFunctionCodeBlock : public UnlinkedCodeBlock {
666 static UnlinkedFunctionCodeBlock* create(VM* vm, CodeType codeType, const ExecutableInfo& info)
668 UnlinkedFunctionCodeBlock* instance = new (NotNull, allocateCell<UnlinkedFunctionCodeBlock>(vm->heap)) UnlinkedFunctionCodeBlock(vm, vm->unlinkedFunctionCodeBlockStructure.get(), codeType, info);
669 instance->finishCreation(*vm);
673 typedef UnlinkedCodeBlock Base;
674 static void destroy(JSCell*);
677 UnlinkedFunctionCodeBlock(VM* vm, Structure* structure, CodeType codeType, const ExecutableInfo& info)
678 : Base(vm, structure, codeType, info)
683 static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto)
685 return Structure::create(vm, globalObject, proto, TypeInfo(UnlinkedFunctionCodeBlockType, StructureFlags), info());
688 static const unsigned StructureFlags = OverridesVisitChildren | Base::StructureFlags;
695 #endif // UnlinkedCodeBlock_h