| /* |
| * Copyright (C) 2008 Apple Inc. All rights reserved. |
| * Copyright (C) 2008 Cameron Zwarich <cwzwarich@uwaterloo.ca> |
| * |
| * 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. |
| * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of |
| * its contributors may be used to endorse or promote products derived |
| * from this software without specific prior written permission. |
| * |
| * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "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 OR ITS 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 CodeBlock_h |
| #define CodeBlock_h |
| |
| #include "Instruction.h" |
| #include "JSGlobalObject.h" |
| #include "nodes.h" |
| #include "SourceRange.h" |
| #include "ustring.h" |
| #include <wtf/RefPtr.h> |
| #include <wtf/Vector.h> |
| |
| namespace KJS { |
| |
| class ExecState; |
| |
| static ALWAYS_INLINE int missingThisObjectMarker() { return std::numeric_limits<int>::max(); } |
| |
| struct HandlerInfo { |
| uint32_t start; |
| uint32_t end; |
| uint32_t target; |
| uint32_t scopeDepth; |
| }; |
| |
| struct ExpressionRangeInfo { |
| enum { MaxOffset = (1 << 7) - 1, |
| MaxDivot = (1 << 25) - 1 |
| }; |
| uint32_t instructionOffset : 25; |
| uint32_t divotPoint : 25; |
| uint32_t startOffset : 7; |
| uint32_t endOffset : 7; |
| }; |
| |
| struct LineInfo { |
| uint32_t instructionOffset; |
| int32_t lineNumber; |
| }; |
| |
| typedef HashMap<RefPtr<UString::Rep>, int32_t> StringJumpTable; |
| struct SimpleJumpTable { |
| 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 CodeBlock { |
| CodeBlock(ScopeNode* ownerNode_, CodeType codeType_, PassRefPtr<SourceProvider> source_, unsigned sourceOffset_) |
| : ownerNode(ownerNode_) |
| , globalData(0) |
| , numTemporaries(0) |
| , numVars(0) |
| , numParameters(0) |
| , numLocals(0) |
| , needsFullScopeChain(ownerNode_->usesEval() || ownerNode_->needsClosure()) |
| , usesEval(ownerNode_->usesEval()) |
| , codeType(codeType_) |
| , source(source_) |
| , sourceOffset(sourceOffset_) |
| { |
| } |
| |
| ~CodeBlock(); |
| |
| #if !defined(NDEBUG) || ENABLE(SAMPLING_TOOL) |
| void dump(ExecState*) const; |
| void printStructureIDs(const Instruction*) const; |
| void printStructureID(const char* name, const Instruction*, int operand) const; |
| #endif |
| int expressionRangeForVPC(const Instruction*, int& divot, int& startOffset, int& endOffset); |
| int lineNumberForVPC(const Instruction* vPC); |
| bool getHandlerForVPC(const Instruction* vPC, Instruction*& target, int& scopeDepth); |
| |
| void mark(); |
| void refStructureIDs(Instruction* vPC) const; |
| void derefStructureIDs(Instruction* vPC) const; |
| |
| ScopeNode* ownerNode; |
| JSGlobalData* globalData; |
| |
| int numConstants; |
| int numTemporaries; |
| int numVars; |
| int numParameters; |
| int numLocals; |
| int thisRegister; |
| bool needsFullScopeChain; |
| bool usesEval; |
| CodeType codeType; |
| RefPtr<SourceProvider> source; |
| unsigned sourceOffset; |
| |
| Vector<Instruction> instructions; |
| Vector<size_t> structureIDInstructions; |
| |
| // Constant pool |
| Vector<Identifier> identifiers; |
| Vector<RefPtr<FuncDeclNode> > functions; |
| Vector<RefPtr<FuncExprNode> > functionExpressions; |
| Vector<Register> constantRegisters; |
| Vector<JSValue*> unexpectedConstants; |
| Vector<RefPtr<RegExp> > regexps; |
| Vector<HandlerInfo> exceptionHandlers; |
| Vector<ExpressionRangeInfo> expressionInfo; |
| Vector<LineInfo> lineInfo; |
| |
| Vector<SimpleJumpTable> immediateSwitchJumpTables; |
| Vector<SimpleJumpTable> characterSwitchJumpTables; |
| Vector<StringJumpTable> stringSwitchJumpTables; |
| |
| private: |
| #if !defined(NDEBUG) || ENABLE(SAMPLING_TOOL) |
| void dump(ExecState*, const Vector<Instruction>::const_iterator& begin, Vector<Instruction>::const_iterator&) const; |
| #endif |
| }; |
| |
| // Program code is not marked by any function, so we make the global object |
| // responsible for marking it. |
| |
| struct ProgramCodeBlock : public CodeBlock { |
| ProgramCodeBlock(ScopeNode* ownerNode_, CodeType codeType_, JSGlobalObject* globalObject_, PassRefPtr<SourceProvider> source_) |
| : CodeBlock(ownerNode_, codeType_, source_, 0) |
| , globalObject(globalObject_) |
| { |
| globalObject->codeBlocks().add(this); |
| } |
| |
| ~ProgramCodeBlock() |
| { |
| if (globalObject) |
| globalObject->codeBlocks().remove(this); |
| } |
| |
| JSGlobalObject* globalObject; // For program and eval nodes, the global object that marks the constant pool. |
| }; |
| |
| struct EvalCodeBlock : public ProgramCodeBlock { |
| EvalCodeBlock(ScopeNode* ownerNode_, JSGlobalObject* globalObject_, PassRefPtr<SourceProvider> source_) |
| : ProgramCodeBlock(ownerNode_, EvalCode, globalObject_, source_) |
| { |
| } |
| }; |
| |
| } // namespace KJS |
| |
| #endif // CodeBlock_h |