2 * Copyright (C) 2012, 2013, 2014 Apple Inc. All Rights Reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 #ifndef UnlinkedCodeBlock_h
27 #define UnlinkedCodeBlock_h
29 #include "BytecodeConventions.h"
30 #include "CodeSpecializationKind.h"
32 #include "ExpressionRangeInfo.h"
33 #include "Identifier.h"
36 #include "ParserModes.h"
38 #include "SpecialPointer.h"
39 #include "SymbolTable.h"
40 #include "VirtualRegister.h"
42 #include <wtf/Compression.h>
43 #include <wtf/RefCountedArray.h>
44 #include <wtf/Vector.h>
49 class FunctionBodyNode;
50 class FunctionExecutable;
51 class FunctionParameters;
54 class ScriptExecutable;
58 class UnlinkedCodeBlock;
59 class UnlinkedFunctionCodeBlock;
60 class UnlinkedInstructionStream;
62 typedef unsigned UnlinkedValueProfile;
63 typedef unsigned UnlinkedArrayProfile;
64 typedef unsigned UnlinkedArrayAllocationProfile;
65 typedef unsigned UnlinkedObjectAllocationProfile;
66 typedef unsigned UnlinkedLLIntCallLinkInfo;
68 struct ExecutableInfo {
69 ExecutableInfo(bool needsActivation, bool usesEval, bool isStrictMode, bool isConstructor, bool isBuiltinFunction)
70 : m_needsActivation(needsActivation)
71 , m_usesEval(usesEval)
72 , m_isStrictMode(isStrictMode)
73 , m_isConstructor(isConstructor)
74 , m_isBuiltinFunction(isBuiltinFunction)
77 bool m_needsActivation : 1;
79 bool m_isStrictMode : 1;
80 bool m_isConstructor : 1;
81 bool m_isBuiltinFunction : 1;
84 enum UnlinkedFunctionKind {
85 UnlinkedNormalFunction,
86 UnlinkedBuiltinFunction,
89 class UnlinkedFunctionExecutable : public JSCell {
91 friend class BuiltinExecutables;
92 friend class CodeCache;
95 static UnlinkedFunctionExecutable* create(VM* vm, const SourceCode& source, FunctionBodyNode* node, UnlinkedFunctionKind unlinkedFunctionKind)
97 UnlinkedFunctionExecutable* instance = new (NotNull, allocateCell<UnlinkedFunctionExecutable>(vm->heap)) UnlinkedFunctionExecutable(vm, vm->unlinkedFunctionExecutableStructure.get(), source, node, unlinkedFunctionKind);
98 instance->finishCreation(*vm);
102 const Identifier& name() const { return m_name; }
103 const Identifier& inferredName() const { return m_inferredName; }
104 JSString* nameValue() const { return m_nameValue.get(); }
105 SymbolTable* symbolTable(CodeSpecializationKind kind)
107 return (kind == CodeForCall) ? m_symbolTableForCall.get() : m_symbolTableForConstruct.get();
109 size_t parameterCount() const;
110 bool isInStrictContext() const { return m_isInStrictContext; }
111 FunctionMode functionMode() const { return m_functionMode; }
112 JSParserStrictness toStrictness() const
114 if (m_isBuiltinFunction)
115 return JSParseBuiltin;
116 if (m_isInStrictContext)
117 return JSParseStrict;
118 return JSParseNormal;
121 unsigned firstLineOffset() const { return m_firstLineOffset; }
122 unsigned lineCount() const { return m_lineCount; }
123 unsigned unlinkedFunctionNameStart() const { return m_unlinkedFunctionNameStart; }
124 unsigned unlinkedBodyStartColumn() const { return m_unlinkedBodyStartColumn; }
125 unsigned unlinkedBodyEndColumn() const { return m_unlinkedBodyEndColumn; }
126 unsigned startOffset() const { return m_startOffset; }
127 unsigned sourceLength() { return m_sourceLength; }
128 unsigned typeProfilingStartOffset() const { return m_typeProfilingStartOffset; }
129 unsigned typeProfilingEndOffset() const { return m_typeProfilingEndOffset; }
131 String paramString() const;
133 UnlinkedFunctionCodeBlock* codeBlockFor(VM&, const SourceCode&, CodeSpecializationKind, DebuggerMode, ProfilerMode, bool bodyIncludesBraces, ParserError&);
135 static UnlinkedFunctionExecutable* fromGlobalCode(const Identifier&, ExecState*, Debugger*, const SourceCode&, JSObject** exception);
137 FunctionExecutable* link(VM&, const SourceCode&, size_t lineOffset);
139 void clearCodeForRecompilation()
141 m_symbolTableForCall.clear();
142 m_symbolTableForConstruct.clear();
143 m_codeBlockForCall.clear();
144 m_codeBlockForConstruct.clear();
147 FunctionParameters* parameters() { return m_parameters.get(); }
149 void recordParse(CodeFeatures features, bool hasCapturedVariables)
151 m_features = features;
152 m_hasCapturedVariables = hasCapturedVariables;
155 bool forceUsesArguments() const { return m_forceUsesArguments; }
157 CodeFeatures features() const { return m_features; }
158 bool hasCapturedVariables() const { return m_hasCapturedVariables; }
160 static const bool needsDestruction = true;
161 static const bool hasImmortalStructure = true;
162 static void destroy(JSCell*);
164 bool isBuiltinFunction() const { return m_isBuiltinFunction; }
167 UnlinkedFunctionExecutable(VM*, Structure*, const SourceCode&, FunctionBodyNode*, UnlinkedFunctionKind);
168 WriteBarrier<UnlinkedFunctionCodeBlock> m_codeBlockForCall;
169 WriteBarrier<UnlinkedFunctionCodeBlock> m_codeBlockForConstruct;
171 unsigned m_numCapturedVariables : 29;
172 bool m_forceUsesArguments : 1;
173 bool m_isInStrictContext : 1;
174 bool m_hasCapturedVariables : 1;
175 bool m_isBuiltinFunction : 1;
178 Identifier m_inferredName;
179 WriteBarrier<JSString> m_nameValue;
180 WriteBarrier<SymbolTable> m_symbolTableForCall;
181 WriteBarrier<SymbolTable> m_symbolTableForConstruct;
182 RefPtr<FunctionParameters> m_parameters;
183 unsigned m_firstLineOffset;
184 unsigned m_lineCount;
185 unsigned m_unlinkedFunctionNameStart;
186 unsigned m_unlinkedBodyStartColumn;
187 unsigned m_unlinkedBodyEndColumn;
188 unsigned m_startOffset;
189 unsigned m_sourceLength;
190 unsigned m_typeProfilingStartOffset;
191 unsigned m_typeProfilingEndOffset;
193 CodeFeatures m_features;
195 FunctionMode m_functionMode;
198 void finishCreation(VM& vm)
200 Base::finishCreation(vm);
201 m_nameValue.set(vm, this, jsString(&vm, name().string()));
204 static void visitChildren(JSCell*, SlotVisitor&);
207 static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto)
209 return Structure::create(vm, globalObject, proto, TypeInfo(UnlinkedFunctionExecutableType, StructureFlags), info());
212 static const unsigned StructureFlags = StructureIsImmortal | JSCell::StructureFlags;
217 struct UnlinkedStringJumpTable {
218 typedef HashMap<RefPtr<StringImpl>, int32_t> StringOffsetTable;
219 StringOffsetTable offsetTable;
221 inline int32_t offsetForValue(StringImpl* value, int32_t defaultOffset)
223 StringOffsetTable::const_iterator end = offsetTable.end();
224 StringOffsetTable::const_iterator loc = offsetTable.find(value);
226 return defaultOffset;
232 struct UnlinkedSimpleJumpTable {
233 Vector<int32_t> branchOffsets;
236 int32_t offsetForValue(int32_t value, int32_t defaultOffset);
237 void add(int32_t key, int32_t offset)
239 if (!branchOffsets[key])
240 branchOffsets[key] = offset;
244 struct UnlinkedHandlerInfo {
251 struct UnlinkedInstruction {
252 UnlinkedInstruction() { u.operand = 0; }
253 UnlinkedInstruction(OpcodeID opcode) { u.opcode = opcode; }
254 UnlinkedInstruction(int operand) { u.operand = operand; }
262 class UnlinkedCodeBlock : public JSCell {
265 static const bool needsDestruction = true;
266 static const bool hasImmortalStructure = 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 setActivationRegister(VirtualRegister activationRegister) { m_activationRegister = activationRegister; }
287 void setArgumentsRegister(VirtualRegister argumentsRegister) { m_argumentsRegister = argumentsRegister; }
288 bool usesArguments() const { return m_argumentsRegister.isValid(); }
289 VirtualRegister argumentsRegister() const { return m_argumentsRegister; }
292 bool usesGlobalObject() const { return m_globalObjectRegister.isValid(); }
293 void setGlobalObjectRegister(VirtualRegister globalObjectRegister) { m_globalObjectRegister = globalObjectRegister; }
294 VirtualRegister globalObjectRegister() const { return m_globalObjectRegister; }
296 // Parameter information
297 void setNumParameters(int newValue) { m_numParameters = newValue; }
298 void addParameter() { m_numParameters++; }
299 unsigned numParameters() const { return m_numParameters; }
301 unsigned addRegExp(RegExp* r)
303 createRareDataIfNecessary();
304 unsigned size = m_rareData->m_regexps.size();
305 m_rareData->m_regexps.append(WriteBarrier<RegExp>(*m_vm, this, r));
308 unsigned numberOfRegExps() const
312 return m_rareData->m_regexps.size();
314 RegExp* regexp(int index) const { ASSERT(m_rareData); return m_rareData->m_regexps[index].get(); }
318 size_t numberOfIdentifiers() const { return m_identifiers.size(); }
319 void addIdentifier(const Identifier& i) { return m_identifiers.append(i); }
320 const Identifier& identifier(int index) const { return m_identifiers[index]; }
321 const Vector<Identifier>& identifiers() const { return m_identifiers; }
323 size_t numberOfConstantRegisters() const { return m_constantRegisters.size(); }
324 unsigned addConstant(JSValue v)
326 unsigned result = m_constantRegisters.size();
327 m_constantRegisters.append(WriteBarrier<Unknown>());
328 m_constantRegisters.last().set(*m_vm, this, v);
331 unsigned addOrFindConstant(JSValue);
332 const Vector<WriteBarrier<Unknown>>& constantRegisters() { return m_constantRegisters; }
333 const WriteBarrier<Unknown>& constantRegister(int index) const { return m_constantRegisters[index - FirstConstantRegisterIndex]; }
334 ALWAYS_INLINE bool isConstantRegisterIndex(int index) const { return index >= FirstConstantRegisterIndex; }
335 ALWAYS_INLINE JSValue getConstant(int index) const { return m_constantRegisters[index - FirstConstantRegisterIndex].get(); }
338 size_t numberOfJumpTargets() const { return m_jumpTargets.size(); }
339 void addJumpTarget(unsigned jumpTarget) { m_jumpTargets.append(jumpTarget); }
340 unsigned jumpTarget(int index) const { return m_jumpTargets[index]; }
341 unsigned lastJumpTarget() const { return m_jumpTargets.last(); }
343 void setIsNumericCompareFunction(bool isNumericCompareFunction) { m_isNumericCompareFunction = isNumericCompareFunction; }
344 bool isNumericCompareFunction() const { return m_isNumericCompareFunction; }
346 bool isBuiltinFunction() const { return m_isBuiltinFunction; }
350 m_jumpTargets.shrinkToFit();
351 m_identifiers.shrinkToFit();
352 m_constantRegisters.shrinkToFit();
353 m_functionDecls.shrinkToFit();
354 m_functionExprs.shrinkToFit();
355 m_propertyAccessInstructions.shrinkToFit();
356 m_expressionInfo.shrinkToFit();
358 #if ENABLE(BYTECODE_COMMENTS)
359 m_bytecodeComments.shrinkToFit();
362 m_rareData->m_exceptionHandlers.shrinkToFit();
363 m_rareData->m_regexps.shrinkToFit();
364 m_rareData->m_constantBuffers.shrinkToFit();
365 m_rareData->m_switchJumpTables.shrinkToFit();
366 m_rareData->m_stringSwitchJumpTables.shrinkToFit();
367 m_rareData->m_expressionInfoFatPositions.shrinkToFit();
371 void setInstructions(std::unique_ptr<UnlinkedInstructionStream>);
372 const UnlinkedInstructionStream& instructions() const;
375 int m_numCapturedVars;
376 int m_numCalleeRegisters;
380 size_t numberOfSwitchJumpTables() const { return m_rareData ? m_rareData->m_switchJumpTables.size() : 0; }
381 UnlinkedSimpleJumpTable& addSwitchJumpTable() { createRareDataIfNecessary(); m_rareData->m_switchJumpTables.append(UnlinkedSimpleJumpTable()); return m_rareData->m_switchJumpTables.last(); }
382 UnlinkedSimpleJumpTable& switchJumpTable(int tableIndex) { ASSERT(m_rareData); return m_rareData->m_switchJumpTables[tableIndex]; }
384 size_t numberOfStringSwitchJumpTables() const { return m_rareData ? m_rareData->m_stringSwitchJumpTables.size() : 0; }
385 UnlinkedStringJumpTable& addStringSwitchJumpTable() { createRareDataIfNecessary(); m_rareData->m_stringSwitchJumpTables.append(UnlinkedStringJumpTable()); return m_rareData->m_stringSwitchJumpTables.last(); }
386 UnlinkedStringJumpTable& stringSwitchJumpTable(int tableIndex) { ASSERT(m_rareData); return m_rareData->m_stringSwitchJumpTables[tableIndex]; }
388 unsigned addFunctionDecl(UnlinkedFunctionExecutable* n)
390 unsigned size = m_functionDecls.size();
391 m_functionDecls.append(WriteBarrier<UnlinkedFunctionExecutable>());
392 m_functionDecls.last().set(*m_vm, this, n);
395 UnlinkedFunctionExecutable* functionDecl(int index) { return m_functionDecls[index].get(); }
396 size_t numberOfFunctionDecls() { return m_functionDecls.size(); }
397 unsigned addFunctionExpr(UnlinkedFunctionExecutable* n)
399 unsigned size = m_functionExprs.size();
400 m_functionExprs.append(WriteBarrier<UnlinkedFunctionExecutable>());
401 m_functionExprs.last().set(*m_vm, this, n);
404 UnlinkedFunctionExecutable* functionExpr(int index) { return m_functionExprs[index].get(); }
405 size_t numberOfFunctionExprs() { return m_functionExprs.size(); }
407 // Exception handling support
408 size_t numberOfExceptionHandlers() const { return m_rareData ? m_rareData->m_exceptionHandlers.size() : 0; }
409 void addExceptionHandler(const UnlinkedHandlerInfo& hanler) { createRareDataIfNecessary(); return m_rareData->m_exceptionHandlers.append(hanler); }
410 UnlinkedHandlerInfo& exceptionHandler(int index) { ASSERT(m_rareData); return m_rareData->m_exceptionHandlers[index]; }
412 SymbolTable* symbolTable() const { return m_symbolTable.get(); }
413 void setSymbolTable(SymbolTable* table) { m_symbolTable.set(*m_vm, this, table); }
415 VM* vm() const { return m_vm; }
417 UnlinkedArrayProfile addArrayProfile() { return m_arrayProfileCount++; }
418 unsigned numberOfArrayProfiles() { return m_arrayProfileCount; }
419 UnlinkedArrayAllocationProfile addArrayAllocationProfile() { return m_arrayAllocationProfileCount++; }
420 unsigned numberOfArrayAllocationProfiles() { return m_arrayAllocationProfileCount; }
421 UnlinkedObjectAllocationProfile addObjectAllocationProfile() { return m_objectAllocationProfileCount++; }
422 unsigned numberOfObjectAllocationProfiles() { return m_objectAllocationProfileCount; }
423 UnlinkedValueProfile addValueProfile() { return m_valueProfileCount++; }
424 unsigned numberOfValueProfiles() { return m_valueProfileCount; }
426 UnlinkedLLIntCallLinkInfo addLLIntCallLinkInfo() { return m_llintCallLinkInfoCount++; }
427 unsigned numberOfLLintCallLinkInfos() { return m_llintCallLinkInfoCount; }
429 CodeType codeType() const { return m_codeType; }
431 VirtualRegister thisRegister() const { return m_thisRegister; }
432 VirtualRegister activationRegister() const { return m_activationRegister; }
433 bool hasActivationRegister() const { return m_activationRegister.isValid(); }
435 void addPropertyAccessInstruction(unsigned propertyAccessInstruction)
437 m_propertyAccessInstructions.append(propertyAccessInstruction);
440 size_t numberOfPropertyAccessInstructions() const { return m_propertyAccessInstructions.size(); }
441 const Vector<unsigned>& propertyAccessInstructions() const { return m_propertyAccessInstructions; }
443 typedef Vector<JSValue> ConstantBuffer;
445 size_t constantBufferCount() { ASSERT(m_rareData); return m_rareData->m_constantBuffers.size(); }
446 unsigned addConstantBuffer(unsigned length)
448 createRareDataIfNecessary();
449 unsigned size = m_rareData->m_constantBuffers.size();
450 m_rareData->m_constantBuffers.append(Vector<JSValue>(length));
454 const ConstantBuffer& constantBuffer(unsigned index) const
457 return m_rareData->m_constantBuffers[index];
460 ConstantBuffer& constantBuffer(unsigned index)
463 return m_rareData->m_constantBuffers[index];
466 bool hasRareData() const { return m_rareData; }
468 int lineNumberForBytecodeOffset(unsigned bytecodeOffset);
470 void expressionRangeForBytecodeOffset(unsigned bytecodeOffset, int& divot,
471 int& startOffset, int& endOffset, unsigned& line, unsigned& column);
473 bool typeProfilerExpressionInfoForBytecodeOffset(unsigned bytecodeOffset, unsigned& startDivot, unsigned& endDivot);
475 void recordParse(CodeFeatures features, bool hasCapturedVariables, unsigned firstLine, unsigned lineCount, unsigned endColumn)
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;
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; }
492 void dumpExpressionRangeInfo(); // For debugging purpose only.
495 UnlinkedCodeBlock(VM*, Structure*, CodeType, const ExecutableInfo&);
496 ~UnlinkedCodeBlock();
498 void finishCreation(VM& vm)
500 Base::finishCreation(vm);
501 if (codeType() == GlobalCode)
503 m_symbolTable.set(vm, this, SymbolTable::create(vm));
508 void createRareDataIfNecessary()
511 m_rareData = adoptPtr(new RareData);
514 void getLineAndColumn(ExpressionRangeInfo&, unsigned& line, unsigned& column);
516 std::unique_ptr<UnlinkedInstructionStream> m_unlinkedInstructions;
521 VirtualRegister m_thisRegister;
522 VirtualRegister m_argumentsRegister;
523 VirtualRegister m_activationRegister;
524 VirtualRegister m_globalObjectRegister;
526 bool m_needsFullScopeChain : 1;
528 bool m_isNumericCompareFunction : 1;
529 bool m_isStrictMode : 1;
530 bool m_isConstructor : 1;
531 bool m_hasCapturedVariables : 1;
532 bool m_isBuiltinFunction : 1;
533 unsigned m_firstLine;
534 unsigned m_lineCount;
535 unsigned m_endColumn;
537 CodeFeatures m_features;
540 Vector<unsigned> m_jumpTargets;
543 Vector<Identifier> m_identifiers;
544 Vector<WriteBarrier<Unknown>> m_constantRegisters;
545 typedef Vector<WriteBarrier<UnlinkedFunctionExecutable>> FunctionExpressionVector;
546 FunctionExpressionVector m_functionDecls;
547 FunctionExpressionVector m_functionExprs;
549 WriteBarrier<SymbolTable> m_symbolTable;
551 Vector<unsigned> m_propertyAccessInstructions;
553 #if ENABLE(BYTECODE_COMMENTS)
554 Vector<Comment> m_bytecodeComments;
555 size_t m_bytecodeCommentIterator;
558 unsigned m_arrayProfileCount;
559 unsigned m_arrayAllocationProfileCount;
560 unsigned m_objectAllocationProfileCount;
561 unsigned m_valueProfileCount;
562 unsigned m_llintCallLinkInfoCount;
566 WTF_MAKE_FAST_ALLOCATED;
568 Vector<UnlinkedHandlerInfo> m_exceptionHandlers;
571 Vector<WriteBarrier<RegExp>> m_regexps;
573 // Buffers used for large array literals
574 Vector<ConstantBuffer> m_constantBuffers;
577 Vector<UnlinkedSimpleJumpTable> m_switchJumpTables;
578 Vector<UnlinkedStringJumpTable> m_stringSwitchJumpTables;
580 Vector<ExpressionRangeInfo::FatPosition> m_expressionInfoFatPositions;
584 OwnPtr<RareData> m_rareData;
585 Vector<ExpressionRangeInfo> m_expressionInfo;
586 struct TypeProfilerExpressionRange {
587 unsigned m_startDivot;
590 HashMap<unsigned, TypeProfilerExpressionRange> m_typeProfilerInfoMap;
594 static const unsigned StructureFlags = StructureIsImmortal | Base::StructureFlags;
595 static void visitChildren(JSCell*, SlotVisitor&);
601 class UnlinkedGlobalCodeBlock : public UnlinkedCodeBlock {
603 typedef UnlinkedCodeBlock Base;
606 UnlinkedGlobalCodeBlock(VM* vm, Structure* structure, CodeType codeType, const ExecutableInfo& info)
607 : Base(vm, structure, codeType, info)
614 class UnlinkedProgramCodeBlock : public UnlinkedGlobalCodeBlock {
616 friend class CodeCache;
617 static UnlinkedProgramCodeBlock* create(VM* vm, const ExecutableInfo& info)
619 UnlinkedProgramCodeBlock* instance = new (NotNull, allocateCell<UnlinkedProgramCodeBlock>(vm->heap)) UnlinkedProgramCodeBlock(vm, vm->unlinkedProgramCodeBlockStructure.get(), info);
620 instance->finishCreation(*vm);
625 typedef UnlinkedGlobalCodeBlock Base;
626 static void destroy(JSCell*);
628 void addFunctionDeclaration(VM& vm, const Identifier& name, UnlinkedFunctionExecutable* functionExecutable)
630 m_functionDeclarations.append(std::make_pair(name, WriteBarrier<UnlinkedFunctionExecutable>(vm, this, functionExecutable)));
633 void addVariableDeclaration(const Identifier& name, bool isConstant)
635 m_varDeclarations.append(std::make_pair(name, isConstant));
638 typedef Vector<std::pair<Identifier, bool>> VariableDeclations;
639 typedef Vector<std::pair<Identifier, WriteBarrier<UnlinkedFunctionExecutable>> > FunctionDeclations;
641 const VariableDeclations& variableDeclarations() const { return m_varDeclarations; }
642 const FunctionDeclations& functionDeclarations() const { return m_functionDeclarations; }
644 static void visitChildren(JSCell*, SlotVisitor&);
647 UnlinkedProgramCodeBlock(VM* vm, Structure* structure, const ExecutableInfo& info)
648 : Base(vm, structure, GlobalCode, info)
652 VariableDeclations m_varDeclarations;
653 FunctionDeclations m_functionDeclarations;
656 static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto)
658 return Structure::create(vm, globalObject, proto, TypeInfo(UnlinkedProgramCodeBlockType, StructureFlags), info());
664 class UnlinkedEvalCodeBlock : public UnlinkedGlobalCodeBlock {
666 friend class CodeCache;
668 static UnlinkedEvalCodeBlock* create(VM* vm, const ExecutableInfo& info)
670 UnlinkedEvalCodeBlock* instance = new (NotNull, allocateCell<UnlinkedEvalCodeBlock>(vm->heap)) UnlinkedEvalCodeBlock(vm, vm->unlinkedEvalCodeBlockStructure.get(), info);
671 instance->finishCreation(*vm);
676 typedef UnlinkedGlobalCodeBlock Base;
677 static void destroy(JSCell*);
679 const Identifier& variable(unsigned index) { return m_variables[index]; }
680 unsigned numVariables() { return m_variables.size(); }
681 void adoptVariables(Vector<Identifier, 0, UnsafeVectorOverflow>& variables)
683 ASSERT(m_variables.isEmpty());
684 m_variables.swap(variables);
688 UnlinkedEvalCodeBlock(VM* vm, Structure* structure, const ExecutableInfo& info)
689 : Base(vm, structure, EvalCode, info)
693 Vector<Identifier, 0, UnsafeVectorOverflow> m_variables;
696 static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto)
698 return Structure::create(vm, globalObject, proto, TypeInfo(UnlinkedEvalCodeBlockType, StructureFlags), info());
704 class UnlinkedFunctionCodeBlock : public UnlinkedCodeBlock {
706 static UnlinkedFunctionCodeBlock* create(VM* vm, CodeType codeType, const ExecutableInfo& info)
708 UnlinkedFunctionCodeBlock* instance = new (NotNull, allocateCell<UnlinkedFunctionCodeBlock>(vm->heap)) UnlinkedFunctionCodeBlock(vm, vm->unlinkedFunctionCodeBlockStructure.get(), codeType, info);
709 instance->finishCreation(*vm);
713 typedef UnlinkedCodeBlock Base;
714 static void destroy(JSCell*);
717 UnlinkedFunctionCodeBlock(VM* vm, Structure* structure, CodeType codeType, const ExecutableInfo& info)
718 : Base(vm, structure, codeType, info)
723 static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto)
725 return Structure::create(vm, globalObject, proto, TypeInfo(UnlinkedFunctionCodeBlockType, StructureFlags), info());
733 #endif // UnlinkedCodeBlock_h