summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.h
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@digia.com>2012-11-07 11:22:47 +0100
committerSimon Hausmann <simon.hausmann@digia.com>2012-11-07 11:22:47 +0100
commitcfd86b747d32ac22246a1aa908eaa720c63a88c1 (patch)
tree24d68c6f61c464ecba1e05670b80390ea3b0e50c /Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.h
parent69d7c744c9de19d152dbe2d8e46eb7dfd4511d1a (diff)
downloadqtwebkit-cfd86b747d32ac22246a1aa908eaa720c63a88c1.tar.gz
Imported WebKit commit 20271caf2e2c016d5cef40184cddeefeac4f1876 (http://svn.webkit.org/repository/webkit/trunk@133733)
New snapshot that contains all previous fixes as well as build fix for latest QtMultimedia API changes.
Diffstat (limited to 'Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.h')
-rw-r--r--Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.h700
1 files changed, 700 insertions, 0 deletions
diff --git a/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.h b/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.h
new file mode 100644
index 000000000..bf3f5fdff
--- /dev/null
+++ b/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.h
@@ -0,0 +1,700 @@
+/*
+ * Copyright (C) 2012 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef UnlinkedCodeBlock_h
+#define UnlinkedCodeBlock_h
+
+#include "BytecodeConventions.h"
+#include "CodeSpecializationKind.h"
+#include "CodeType.h"
+#include "ExpressionRangeInfo.h"
+#include "Identifier.h"
+#include "JSCell.h"
+#include "LineInfo.h"
+#include "Nodes.h"
+#include "RegExp.h"
+#include "SpecialPointer.h"
+
+#include <wtf/RefCountedArray.h>
+#include <wtf/Vector.h>
+
+namespace JSC {
+
+class Debugger;
+class FunctionBodyNode;
+class FunctionExecutable;
+class FunctionParameters;
+struct ParserError;
+class ScriptExecutable;
+class SourceCode;
+class SourceProvider;
+class SharedSymbolTable;
+class UnlinkedCodeBlock;
+class UnlinkedFunctionCodeBlock;
+
+typedef unsigned UnlinkedValueProfile;
+typedef unsigned UnlinkedArrayProfile;
+typedef unsigned UnlinkedLLIntCallLinkInfo;
+
+struct ExecutableInfo {
+ ExecutableInfo(bool needsActivation, bool usesEval, bool isStrictMode, bool isConstructor)
+ : m_needsActivation(needsActivation)
+ , m_usesEval(usesEval)
+ , m_isStrictMode(isStrictMode)
+ , m_isConstructor(isConstructor)
+ {
+ }
+ bool m_needsActivation;
+ bool m_usesEval;
+ bool m_isStrictMode;
+ bool m_isConstructor;
+};
+
+class UnlinkedFunctionExecutable : public JSCell {
+public:
+ friend class CodeCache;
+ typedef JSCell Base;
+ static UnlinkedFunctionExecutable* create(JSGlobalData* globalData, const SourceCode& source, FunctionBodyNode* node)
+ {
+ UnlinkedFunctionExecutable* instance = new (NotNull, allocateCell<UnlinkedFunctionExecutable>(globalData->heap)) UnlinkedFunctionExecutable(globalData, globalData->unlinkedFunctionExecutableStructure.get(), source, node);
+ instance->finishCreation(*globalData);
+ return instance;
+ }
+
+ const Identifier& name() const { return m_name; }
+ const Identifier& inferredName() const { return m_inferredName; }
+ JSString* nameValue() const { return m_nameValue.get(); }
+ SharedSymbolTable* symbolTable(CodeSpecializationKind kind)
+ {
+ return (kind == CodeForCall) ? m_symbolTableForCall.get() : m_symbolTableForConstruct.get();
+ }
+ size_t parameterCount() const { return m_parameters->size(); }
+ bool isInStrictContext() const { return m_isInStrictContext; }
+ FunctionNameIsInScopeToggle functionNameIsInScopeToggle() const { return m_functionNameIsInScopeToggle; }
+
+ unsigned firstLineOffset() const { return m_firstLineOffset; }
+ unsigned lineCount() const { return m_lineCount; }
+ unsigned startOffset() const { return m_startOffset; }
+ unsigned sourceLength() { return m_sourceLength; }
+
+ String paramString() const;
+
+ UnlinkedFunctionCodeBlock* codeBlockFor(JSGlobalData&, const SourceCode&, CodeSpecializationKind, DebuggerMode, ProfilerMode, ParserError&);
+
+ static UnlinkedFunctionExecutable* fromGlobalCode(const Identifier&, ExecState*, Debugger*, const SourceCode&, JSObject** exception);
+
+ FunctionExecutable* link(JSGlobalData&, const SourceCode&, size_t lineOffset, size_t sourceOffset);
+
+ void clearCode()
+ {
+ m_symbolTableForCall.clear();
+ m_symbolTableForConstruct.clear();
+ m_codeBlockForCall.clear();
+ m_codeBlockForConstruct.clear();
+ }
+
+ FunctionParameters* parameters() { return m_parameters.get(); }
+
+ void recordParse(CodeFeatures features, bool hasCapturedVariables, int firstLine, int lastLine)
+ {
+ m_features = features;
+ m_hasCapturedVariables = hasCapturedVariables;
+ m_lineCount = lastLine - firstLine;
+ }
+
+ bool forceUsesArguments() const { return m_forceUsesArguments; }
+
+ CodeFeatures features() const { return m_features; }
+ bool hasCapturedVariables() const { return m_hasCapturedVariables; }
+
+ static const bool needsDestruction = true;
+ static const bool hasImmortalStructure = true;
+ static void destroy(JSCell*);
+
+private:
+ UnlinkedFunctionExecutable(JSGlobalData*, Structure*, const SourceCode&, FunctionBodyNode*);
+ WriteBarrier<UnlinkedFunctionCodeBlock> m_codeBlockForCall;
+ WriteBarrier<UnlinkedFunctionCodeBlock> m_codeBlockForConstruct;
+
+ unsigned m_numCapturedVariables : 29;
+ bool m_forceUsesArguments : 1;
+ bool m_isInStrictContext : 1;
+ bool m_hasCapturedVariables : 1;
+
+ Identifier m_name;
+ Identifier m_inferredName;
+ WriteBarrier<JSString> m_nameValue;
+ WriteBarrier<SharedSymbolTable> m_symbolTableForCall;
+ WriteBarrier<SharedSymbolTable> m_symbolTableForConstruct;
+ RefPtr<FunctionParameters> m_parameters;
+ unsigned m_firstLineOffset;
+ unsigned m_lineCount;
+ unsigned m_startOffset;
+ unsigned m_sourceLength;
+
+ CodeFeatures m_features;
+
+ FunctionNameIsInScopeToggle m_functionNameIsInScopeToggle;
+
+protected:
+ void finishCreation(JSGlobalData& globalData)
+ {
+ Base::finishCreation(globalData);
+ m_nameValue.set(globalData, this, jsString(&globalData, name().string()));
+ }
+
+ static void visitChildren(JSCell*, SlotVisitor&);
+
+public:
+ static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue proto)
+ {
+ return Structure::create(globalData, globalObject, proto, TypeInfo(UnlinkedFunctionExecutableType, StructureFlags), &s_info);
+ }
+
+ static const unsigned StructureFlags = OverridesVisitChildren | JSCell::StructureFlags;
+
+ static const ClassInfo s_info;
+};
+
+struct UnlinkedStringJumpTable {
+ typedef HashMap<RefPtr<StringImpl>, int32_t> StringOffsetTable;
+ StringOffsetTable offsetTable;
+
+ inline int32_t offsetForValue(StringImpl* value, int32_t defaultOffset)
+ {
+ StringOffsetTable::const_iterator end = offsetTable.end();
+ StringOffsetTable::const_iterator loc = offsetTable.find(value);
+ if (loc == end)
+ return defaultOffset;
+ return loc->value;
+ }
+
+};
+
+struct UnlinkedSimpleJumpTable {
+ Vector<int32_t> branchOffsets;
+ int32_t min;
+
+ int32_t offsetForValue(int32_t value, int32_t defaultOffset);
+ void add(int32_t key, int32_t offset)
+ {
+ if (!branchOffsets[key])
+ branchOffsets[key] = offset;
+ }
+};
+
+struct UnlinkedHandlerInfo {
+ uint32_t start;
+ uint32_t end;
+ uint32_t target;
+ uint32_t scopeDepth;
+};
+
+struct UnlinkedInstruction {
+ UnlinkedInstruction() { u.operand = 0; }
+ UnlinkedInstruction(OpcodeID opcode) { u.opcode = opcode; }
+ UnlinkedInstruction(int operand) { u.operand = operand; }
+ union {
+ OpcodeID opcode;
+ int32_t operand;
+ } u;
+};
+
+class UnlinkedCodeBlock : public JSCell {
+public:
+ typedef JSCell Base;
+ static const bool needsDestruction = true;
+ static const bool hasImmortalStructure = true;
+
+ enum { CallFunction, ApplyFunction };
+
+ bool isConstructor() const { return m_isConstructor; }
+ bool isStrictMode() const { return m_isStrictMode; }
+ bool usesEval() const { return m_usesEval; }
+
+ bool needsFullScopeChain() const { return m_needsFullScopeChain; }
+ void setNeedsFullScopeChain(bool needsFullScopeChain) { m_needsFullScopeChain = needsFullScopeChain; }
+
+ void addExpressionInfo(const ExpressionRangeInfo& expressionInfo)
+ {
+ m_expressionInfo.append(expressionInfo);
+ }
+
+ void addLineInfo(unsigned bytecodeOffset, int lineNo)
+ {
+ Vector<LineInfo>& lineInfo = m_lineInfo;
+ if (!lineInfo.size() || lineInfo.last().lineNumber != lineNo) {
+ LineInfo info = { bytecodeOffset, lineNo };
+ lineInfo.append(info);
+ }
+ }
+
+ bool hasExpressionInfo() { return m_expressionInfo.size(); }
+
+ // Special registers
+ void setThisRegister(int thisRegister) { m_thisRegister = thisRegister; }
+ void setActivationRegister(int activationRegister) { m_activationRegister = activationRegister; }
+
+ void setArgumentsRegister(int argumentsRegister) { m_argumentsRegister = argumentsRegister; }
+ bool usesArguments() const { return m_argumentsRegister != -1; }
+ int argumentsRegister() const { return m_argumentsRegister; }
+
+ // Parameter information
+ void setNumParameters(int newValue) { m_numParameters = newValue; }
+ void addParameter() { m_numParameters++; }
+ unsigned numParameters() const { return m_numParameters; }
+
+ unsigned addRegExp(RegExp* r)
+ {
+ createRareDataIfNecessary();
+ unsigned size = m_rareData->m_regexps.size();
+ m_rareData->m_regexps.append(WriteBarrier<RegExp>(*m_globalData, this, r));
+ return size;
+ }
+ unsigned numberOfRegExps() const
+ {
+ if (!m_rareData)
+ return 0;
+ return m_rareData->m_regexps.size();
+ }
+ RegExp* regexp(int index) const { ASSERT(m_rareData); return m_rareData->m_regexps[index].get(); }
+
+ // Constant Pools
+
+ size_t numberOfIdentifiers() const { return m_identifiers.size(); }
+ void addIdentifier(const Identifier& i) { return m_identifiers.append(i); }
+ const Identifier& identifier(int index) const { return m_identifiers[index]; }
+ const Vector<Identifier>& identifiers() const { return m_identifiers; }
+
+ size_t numberOfConstantRegisters() const { return m_constantRegisters.size(); }
+ unsigned addConstant(JSValue v)
+ {
+ unsigned result = m_constantRegisters.size();
+ m_constantRegisters.append(WriteBarrier<Unknown>());
+ m_constantRegisters.last().set(*m_globalData, this, v);
+ return result;
+ }
+ unsigned addOrFindConstant(JSValue);
+ const Vector<WriteBarrier<Unknown> >& constantRegisters() { return m_constantRegisters; }
+ const WriteBarrier<Unknown>& constantRegister(int index) const { return m_constantRegisters[index - FirstConstantRegisterIndex]; }
+ ALWAYS_INLINE bool isConstantRegisterIndex(int index) const { return index >= FirstConstantRegisterIndex; }
+ ALWAYS_INLINE JSValue getConstant(int index) const { return m_constantRegisters[index - FirstConstantRegisterIndex].get(); }
+
+ // Jumps
+ size_t numberOfJumpTargets() const { return m_jumpTargets.size(); }
+ void addJumpTarget(unsigned jumpTarget) { m_jumpTargets.append(jumpTarget); }
+ unsigned jumpTarget(int index) const { return m_jumpTargets[index]; }
+ unsigned lastJumpTarget() const { return m_jumpTargets.last(); }
+
+ void setIsNumericCompareFunction(bool isNumericCompareFunction) { m_isNumericCompareFunction = isNumericCompareFunction; }
+ bool isNumericCompareFunction() const { return m_isNumericCompareFunction; }
+
+ void shrinkToFit()
+ {
+ m_jumpTargets.shrinkToFit();
+ m_identifiers.shrinkToFit();
+ m_constantRegisters.shrinkToFit();
+ m_functionDecls.shrinkToFit();
+ m_functionExprs.shrinkToFit();
+ m_lineInfo.shrinkToFit();
+ m_propertyAccessInstructions.shrinkToFit();
+ m_expressionInfo.shrinkToFit();
+
+#if ENABLE(BYTECODE_COMMENTS)
+ m_bytecodeComments.shrinkToFit();
+#endif
+ if (m_rareData) {
+ m_rareData->m_exceptionHandlers.shrinkToFit();
+ m_rareData->m_regexps.shrinkToFit();
+ m_rareData->m_constantBuffers.shrinkToFit();
+ m_rareData->m_immediateSwitchJumpTables.shrinkToFit();
+ m_rareData->m_characterSwitchJumpTables.shrinkToFit();
+ m_rareData->m_stringSwitchJumpTables.shrinkToFit();
+ }
+ }
+
+ unsigned numberOfInstructions() const { return m_unlinkedInstructions.size(); }
+ RefCountedArray<UnlinkedInstruction>& instructions() { return m_unlinkedInstructions; }
+ const RefCountedArray<UnlinkedInstruction>& instructions() const { return m_unlinkedInstructions; }
+
+ int m_numVars;
+ int m_numCapturedVars;
+ int m_numCalleeRegisters;
+
+ // Jump Tables
+
+ size_t numberOfImmediateSwitchJumpTables() const { return m_rareData ? m_rareData->m_immediateSwitchJumpTables.size() : 0; }
+ UnlinkedSimpleJumpTable& addImmediateSwitchJumpTable() { createRareDataIfNecessary(); m_rareData->m_immediateSwitchJumpTables.append(UnlinkedSimpleJumpTable()); return m_rareData->m_immediateSwitchJumpTables.last(); }
+ UnlinkedSimpleJumpTable& immediateSwitchJumpTable(int tableIndex) { ASSERT(m_rareData); return m_rareData->m_immediateSwitchJumpTables[tableIndex]; }
+
+ size_t numberOfCharacterSwitchJumpTables() const { return m_rareData ? m_rareData->m_characterSwitchJumpTables.size() : 0; }
+ UnlinkedSimpleJumpTable& addCharacterSwitchJumpTable() { createRareDataIfNecessary(); m_rareData->m_characterSwitchJumpTables.append(UnlinkedSimpleJumpTable()); return m_rareData->m_characterSwitchJumpTables.last(); }
+ UnlinkedSimpleJumpTable& characterSwitchJumpTable(int tableIndex) { ASSERT(m_rareData); return m_rareData->m_characterSwitchJumpTables[tableIndex]; }
+
+ size_t numberOfStringSwitchJumpTables() const { return m_rareData ? m_rareData->m_stringSwitchJumpTables.size() : 0; }
+ UnlinkedStringJumpTable& addStringSwitchJumpTable() { createRareDataIfNecessary(); m_rareData->m_stringSwitchJumpTables.append(UnlinkedStringJumpTable()); return m_rareData->m_stringSwitchJumpTables.last(); }
+ UnlinkedStringJumpTable& stringSwitchJumpTable(int tableIndex) { ASSERT(m_rareData); return m_rareData->m_stringSwitchJumpTables[tableIndex]; }
+
+ unsigned addFunctionDecl(UnlinkedFunctionExecutable* n)
+ {
+ unsigned size = m_functionDecls.size();
+ m_functionDecls.append(WriteBarrier<UnlinkedFunctionExecutable>());
+ m_functionDecls.last().set(*m_globalData, this, n);
+ return size;
+ }
+ UnlinkedFunctionExecutable* functionDecl(int index) { return m_functionDecls[index].get(); }
+ size_t numberOfFunctionDecls() { return m_functionDecls.size(); }
+ unsigned addFunctionExpr(UnlinkedFunctionExecutable* n)
+ {
+ unsigned size = m_functionExprs.size();
+ m_functionExprs.append(WriteBarrier<UnlinkedFunctionExecutable>());
+ m_functionExprs.last().set(*m_globalData, this, n);
+ return size;
+ }
+ UnlinkedFunctionExecutable* functionExpr(int index) { return m_functionExprs[index].get(); }
+ size_t numberOfFunctionExprs() { return m_functionExprs.size(); }
+
+ // Exception handling support
+ size_t numberOfExceptionHandlers() const { return m_rareData ? m_rareData->m_exceptionHandlers.size() : 0; }
+ void addExceptionHandler(const UnlinkedHandlerInfo& hanler) { createRareDataIfNecessary(); return m_rareData->m_exceptionHandlers.append(hanler); }
+ UnlinkedHandlerInfo& exceptionHandler(int index) { ASSERT(m_rareData); return m_rareData->m_exceptionHandlers[index]; }
+
+ SharedSymbolTable* symbolTable() const { return m_symbolTable.get(); }
+
+ JSGlobalData* globalData() const { return m_globalData; }
+
+ unsigned addResolve() { return m_resolveOperationCount++; }
+ unsigned numberOfResolveOperations() const { return m_resolveOperationCount; }
+ unsigned addPutToBase() { return m_putToBaseOperationCount++; }
+ unsigned numberOfPutToBaseOperations() const { return m_putToBaseOperationCount; }
+
+ UnlinkedArrayProfile addArrayProfile() { return m_arrayProfileCount++; }
+ unsigned numberOfArrayProfiles() { return m_arrayProfileCount; }
+ UnlinkedValueProfile addValueProfile() { return m_valueProfileCount++; }
+ unsigned numberOfValueProfiles() { return m_valueProfileCount; }
+
+ UnlinkedLLIntCallLinkInfo addLLIntCallLinkInfo() { return m_llintCallLinkInfoCount++; }
+ unsigned numberOfLLintCallLinkInfos() { return m_llintCallLinkInfoCount; }
+
+ CodeType codeType() const { return m_codeType; }
+
+ int thisRegister() const { return m_thisRegister; }
+ int activationRegister() const { return m_activationRegister; }
+
+
+ void addPropertyAccessInstruction(unsigned propertyAccessInstruction)
+ {
+ m_propertyAccessInstructions.append(propertyAccessInstruction);
+ }
+
+ size_t numberOfPropertyAccessInstructions() const { return m_propertyAccessInstructions.size(); }
+ const Vector<unsigned>& propertyAccessInstructions() const { return m_propertyAccessInstructions; }
+
+ typedef Vector<JSValue> ConstantBuffer;
+
+ size_t constantBufferCount() { ASSERT(m_rareData); return m_rareData->m_constantBuffers.size(); }
+ unsigned addConstantBuffer(unsigned length)
+ {
+ createRareDataIfNecessary();
+ unsigned size = m_rareData->m_constantBuffers.size();
+ m_rareData->m_constantBuffers.append(Vector<JSValue>(length));
+ return size;
+ }
+
+ const ConstantBuffer& constantBuffer(unsigned index) const
+ {
+ ASSERT(m_rareData);
+ return m_rareData->m_constantBuffers[index];
+ }
+
+ ConstantBuffer& constantBuffer(unsigned index)
+ {
+ ASSERT(m_rareData);
+ return m_rareData->m_constantBuffers[index];
+ }
+
+ bool hasRareData() const { return m_rareData; }
+
+ int lineNumberForBytecodeOffset(unsigned bytecodeOffset);
+
+ void expressionRangeForBytecodeOffset(unsigned bytecodeOffset, int& divot, int& startOffset, int& endOffset);
+
+ void recordParse(CodeFeatures features, bool hasCapturedVariables, unsigned firstLine, unsigned lineCount)
+ {
+ m_features = features;
+ m_hasCapturedVariables = hasCapturedVariables;
+ m_firstLine = firstLine;
+ m_lineCount = lineCount;
+ }
+
+ CodeFeatures codeFeatures() const { return m_features; }
+ bool hasCapturedVariables() const { return m_hasCapturedVariables; }
+ unsigned firstLine() const { return m_firstLine; }
+ unsigned lineCount() const { return m_lineCount; }
+
+protected:
+ UnlinkedCodeBlock(JSGlobalData*, Structure*, CodeType, const ExecutableInfo&);
+ ~UnlinkedCodeBlock();
+
+ void finishCreation(JSGlobalData& globalData)
+ {
+ Base::finishCreation(globalData);
+ if (codeType() == GlobalCode)
+ return;
+ m_symbolTable.set(globalData, this, SharedSymbolTable::create(globalData));
+ }
+
+private:
+
+ void createRareDataIfNecessary()
+ {
+ if (!m_rareData)
+ m_rareData = adoptPtr(new RareData);
+ }
+
+ RefCountedArray<UnlinkedInstruction> m_unlinkedInstructions;
+
+ int m_numParameters;
+ JSGlobalData* m_globalData;
+
+ int m_thisRegister;
+ int m_argumentsRegister;
+ int m_activationRegister;
+
+ bool m_needsFullScopeChain : 1;
+ bool m_usesEval : 1;
+ bool m_isNumericCompareFunction : 1;
+ bool m_isStrictMode : 1;
+ bool m_isConstructor : 1;
+ bool m_hasCapturedVariables : 1;
+ unsigned m_firstLine;
+ unsigned m_lineCount;
+
+ CodeFeatures m_features;
+ CodeType m_codeType;
+
+ Vector<unsigned> m_jumpTargets;
+
+ // Constant Pools
+ Vector<Identifier> m_identifiers;
+ Vector<WriteBarrier<Unknown> > m_constantRegisters;
+ typedef Vector<WriteBarrier<UnlinkedFunctionExecutable> > FunctionExpressionVector;
+ FunctionExpressionVector m_functionDecls;
+ FunctionExpressionVector m_functionExprs;
+
+ WriteBarrier<SharedSymbolTable> m_symbolTable;
+
+ Vector<LineInfo> m_lineInfo;
+
+ Vector<unsigned> m_propertyAccessInstructions;
+
+#if ENABLE(BYTECODE_COMMENTS)
+ Vector<Comment> m_bytecodeComments;
+ size_t m_bytecodeCommentIterator;
+#endif
+
+ unsigned m_resolveOperationCount;
+ unsigned m_putToBaseOperationCount;
+ unsigned m_arrayProfileCount;
+ unsigned m_valueProfileCount;
+ unsigned m_llintCallLinkInfoCount;
+
+public:
+ struct RareData {
+ WTF_MAKE_FAST_ALLOCATED;
+ public:
+ Vector<UnlinkedHandlerInfo> m_exceptionHandlers;
+
+ // Rare Constants
+ Vector<WriteBarrier<RegExp> > m_regexps;
+
+ // Buffers used for large array literals
+ Vector<ConstantBuffer> m_constantBuffers;
+
+ // Jump Tables
+ Vector<UnlinkedSimpleJumpTable> m_immediateSwitchJumpTables;
+ Vector<UnlinkedSimpleJumpTable> m_characterSwitchJumpTables;
+ Vector<UnlinkedStringJumpTable> m_stringSwitchJumpTables;
+
+ // Expression info - present if debugging.
+ };
+
+private:
+ OwnPtr<RareData> m_rareData;
+ Vector<ExpressionRangeInfo> m_expressionInfo;
+
+protected:
+
+ static const unsigned StructureFlags = OverridesVisitChildren | Base::StructureFlags;
+ static void visitChildren(JSCell*, SlotVisitor&);
+
+public:
+ static const ClassInfo s_info;
+};
+
+class UnlinkedGlobalCodeBlock : public UnlinkedCodeBlock {
+public:
+ typedef UnlinkedCodeBlock Base;
+
+protected:
+ UnlinkedGlobalCodeBlock(JSGlobalData* globalData, Structure* structure, CodeType codeType, const ExecutableInfo& info)
+ : Base(globalData, structure, codeType, info)
+ {
+ }
+
+ static const unsigned StructureFlags = OverridesVisitChildren | Base::StructureFlags;
+
+ static const ClassInfo s_info;
+};
+
+class UnlinkedProgramCodeBlock : public UnlinkedGlobalCodeBlock {
+private:
+ friend class CodeCache;
+ static UnlinkedProgramCodeBlock* create(JSGlobalData* globalData, const ExecutableInfo& info)
+ {
+ UnlinkedProgramCodeBlock* instance = new (NotNull, allocateCell<UnlinkedProgramCodeBlock>(globalData->heap)) UnlinkedProgramCodeBlock(globalData, globalData->unlinkedProgramCodeBlockStructure.get(), info);
+ instance->finishCreation(*globalData);
+ return instance;
+ }
+
+public:
+ typedef UnlinkedGlobalCodeBlock Base;
+ static void destroy(JSCell*);
+
+ void addFunctionDeclaration(JSGlobalData& globalData, const Identifier& name, UnlinkedFunctionExecutable* functionExecutable)
+ {
+ m_functionDeclarations.append(std::make_pair(name, WriteBarrier<UnlinkedFunctionExecutable>(globalData, this, functionExecutable)));
+ }
+
+ void addVariableDeclaration(const Identifier& name, bool isConstant)
+ {
+ m_varDeclarations.append(std::make_pair(name, isConstant));
+ }
+
+ typedef Vector<std::pair<Identifier, bool> > VariableDeclations;
+ typedef Vector<std::pair<Identifier, WriteBarrier<UnlinkedFunctionExecutable> > > FunctionDeclations;
+
+ const VariableDeclations& variableDeclarations() const { return m_varDeclarations; }
+ const FunctionDeclations& functionDeclarations() const { return m_functionDeclarations; }
+
+ static void visitChildren(JSCell*, SlotVisitor&);
+
+private:
+ UnlinkedProgramCodeBlock(JSGlobalData* globalData, Structure* structure, const ExecutableInfo& info)
+ : Base(globalData, structure, GlobalCode, info)
+ {
+ }
+
+ VariableDeclations m_varDeclarations;
+ FunctionDeclations m_functionDeclarations;
+
+public:
+ static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue proto)
+ {
+ return Structure::create(globalData, globalObject, proto, TypeInfo(UnlinkedProgramCodeBlockType, StructureFlags), &s_info);
+ }
+
+ static const unsigned StructureFlags = OverridesVisitChildren | Base::StructureFlags;
+
+ static const ClassInfo s_info;
+};
+
+class UnlinkedEvalCodeBlock : public UnlinkedGlobalCodeBlock {
+private:
+ friend class CodeCache;
+
+ static UnlinkedEvalCodeBlock* create(JSGlobalData* globalData, const ExecutableInfo& info)
+ {
+ UnlinkedEvalCodeBlock* instance = new (NotNull, allocateCell<UnlinkedEvalCodeBlock>(globalData->heap)) UnlinkedEvalCodeBlock(globalData, globalData->unlinkedEvalCodeBlockStructure.get(), info);
+ instance->finishCreation(*globalData);
+ return instance;
+ }
+
+public:
+ typedef UnlinkedGlobalCodeBlock Base;
+ static void destroy(JSCell*);
+
+ const Identifier& variable(unsigned index) { return m_variables[index]; }
+ unsigned numVariables() { return m_variables.size(); }
+ void adoptVariables(Vector<Identifier>& variables)
+ {
+ ASSERT(m_variables.isEmpty());
+ m_variables.swap(variables);
+ }
+
+private:
+ UnlinkedEvalCodeBlock(JSGlobalData* globalData, Structure* structure, const ExecutableInfo& info)
+ : Base(globalData, structure, EvalCode, info)
+ {
+ }
+
+ Vector<Identifier> m_variables;
+
+public:
+ static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue proto)
+ {
+ return Structure::create(globalData, globalObject, proto, TypeInfo(UnlinkedEvalCodeBlockType, StructureFlags), &s_info);
+ }
+
+ static const unsigned StructureFlags = OverridesVisitChildren | Base::StructureFlags;
+
+ static const ClassInfo s_info;
+};
+
+class UnlinkedFunctionCodeBlock : public UnlinkedCodeBlock {
+private:
+ friend class CodeCache;
+
+ static UnlinkedFunctionCodeBlock* create(JSGlobalData* globalData, CodeType codeType, const ExecutableInfo& info)
+ {
+ UnlinkedFunctionCodeBlock* instance = new (NotNull, allocateCell<UnlinkedFunctionCodeBlock>(globalData->heap)) UnlinkedFunctionCodeBlock(globalData, globalData->unlinkedFunctionCodeBlockStructure.get(), codeType, info);
+ instance->finishCreation(*globalData);
+ return instance;
+ }
+
+public:
+ typedef UnlinkedCodeBlock Base;
+ static void destroy(JSCell*);
+
+private:
+ UnlinkedFunctionCodeBlock(JSGlobalData* globalData, Structure* structure, CodeType codeType, const ExecutableInfo& info)
+ : Base(globalData, structure, codeType, info)
+ {
+ }
+
+public:
+ static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue proto)
+ {
+ return Structure::create(globalData, globalObject, proto, TypeInfo(UnlinkedFunctionCodeBlockType, StructureFlags), &s_info);
+ }
+
+ static const unsigned StructureFlags = OverridesVisitChildren | Base::StructureFlags;
+
+ static const ClassInfo s_info;
+};
+
+}
+
+#endif // UnlinkedCodeBlock_h