summaryrefslogtreecommitdiffstats
path: root/JavaScriptCore/bytecompiler/BytecodeGenerator.h
diff options
context:
space:
mode:
Diffstat (limited to 'JavaScriptCore/bytecompiler/BytecodeGenerator.h')
-rw-r--r--JavaScriptCore/bytecompiler/BytecodeGenerator.h588
1 files changed, 0 insertions, 588 deletions
diff --git a/JavaScriptCore/bytecompiler/BytecodeGenerator.h b/JavaScriptCore/bytecompiler/BytecodeGenerator.h
deleted file mode 100644
index 37756fa..0000000
--- a/JavaScriptCore/bytecompiler/BytecodeGenerator.h
+++ /dev/null
@@ -1,588 +0,0 @@
-/*
- * Copyright (C) 2008, 2009 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 BytecodeGenerator_h
-#define BytecodeGenerator_h
-
-#include "CodeBlock.h"
-#include "HashTraits.h"
-#include "Instruction.h"
-#include "Label.h"
-#include "LabelScope.h"
-#include "Interpreter.h"
-#include "RegisterID.h"
-#include "SymbolTable.h"
-#include "Debugger.h"
-#include "Nodes.h"
-#include <wtf/FastAllocBase.h>
-#include <wtf/PassRefPtr.h>
-#include <wtf/SegmentedVector.h>
-#include <wtf/Vector.h>
-
-namespace JSC {
-
- class Identifier;
- class ScopeChain;
- class ScopeNode;
-
- class CallArguments {
- public:
- CallArguments(BytecodeGenerator& generator, ArgumentsNode* argumentsNode);
-
- RegisterID* thisRegister() { return m_argv[0].get(); }
- RegisterID* argumentRegister(unsigned i) { return m_argv[i + 1].get(); }
- unsigned callFrame() { return thisRegister()->index() + count() + RegisterFile::CallFrameHeaderSize; }
- unsigned count() { return m_argv.size(); }
- RegisterID* profileHookRegister() { return m_profileHookRegister.get(); }
- ArgumentsNode* argumentsNode() { return m_argumentsNode; }
-
- private:
- RefPtr<RegisterID> m_profileHookRegister;
- ArgumentsNode* m_argumentsNode;
- Vector<RefPtr<RegisterID>, 16> m_argv;
- };
-
- struct FinallyContext {
- Label* finallyAddr;
- RegisterID* retAddrDst;
- };
-
- struct ControlFlowContext {
- bool isFinallyBlock;
- FinallyContext finallyContext;
- };
-
- struct ForInContext {
- RefPtr<RegisterID> expectedSubscriptRegister;
- RefPtr<RegisterID> iterRegister;
- RefPtr<RegisterID> indexRegister;
- RefPtr<RegisterID> propertyRegister;
- };
-
- class BytecodeGenerator : public FastAllocBase {
- public:
- typedef DeclarationStacks::VarStack VarStack;
- typedef DeclarationStacks::FunctionStack FunctionStack;
-
- static void setDumpsGeneratedCode(bool dumpsGeneratedCode);
- static bool dumpsGeneratedCode();
-
- BytecodeGenerator(ProgramNode*, const ScopeChain&, SymbolTable*, ProgramCodeBlock*);
- BytecodeGenerator(FunctionBodyNode*, const ScopeChain&, SymbolTable*, CodeBlock*);
- BytecodeGenerator(EvalNode*, const ScopeChain&, SymbolTable*, EvalCodeBlock*);
-
- JSGlobalData* globalData() const { return m_globalData; }
- const CommonIdentifiers& propertyNames() const { return *m_globalData->propertyNames; }
-
- bool isConstructor() { return m_codeBlock->m_isConstructor; }
-
- void generate();
-
- // Returns the register corresponding to a local variable, or 0 if no
- // such register exists. Registers returned by registerFor do not
- // require explicit reference counting.
- RegisterID* registerFor(const Identifier&);
-
- // Returns the agument number if this is an argument, or 0 if not.
- int argumentNumberFor(const Identifier&);
-
- void setIsNumericCompareFunction(bool isNumericCompareFunction);
-
- bool willResolveToArguments(const Identifier&);
- RegisterID* uncheckedRegisterForArguments();
-
- // Behaves as registerFor does, but ignores dynamic scope as
- // dynamic scope should not interfere with const initialisation
- RegisterID* constRegisterFor(const Identifier&);
-
- // Searches the scope chain in an attempt to statically locate the requested
- // property. Returns false if for any reason the property cannot be safely
- // optimised at all. Otherwise it will return the index and depth of the
- // VariableObject that defines the property. If the property cannot be found
- // statically, depth will contain the depth of the scope chain where dynamic
- // lookup must begin.
- bool findScopedProperty(const Identifier&, int& index, size_t& depth, bool forWriting, bool& includesDynamicScopes, JSObject*& globalObject);
-
- // Returns the register storing "this"
- RegisterID* thisRegister() { return &m_thisRegister; }
-
- bool isLocal(const Identifier&);
- bool isLocalConstant(const Identifier&);
-
- // Returns the next available temporary register. Registers returned by
- // newTemporary require a modified form of reference counting: any
- // register with a refcount of 0 is considered "available", meaning that
- // the next instruction may overwrite it.
- RegisterID* newTemporary();
-
- RegisterID* highestUsedRegister();
-
- // The same as newTemporary(), but this function returns "suggestion" if
- // "suggestion" is a temporary. This function is helpful in situations
- // where you've put "suggestion" in a RefPtr, but you'd like to allow
- // the next instruction to overwrite it anyway.
- RegisterID* newTemporaryOr(RegisterID* suggestion) { return suggestion->isTemporary() ? suggestion : newTemporary(); }
-
- // Functions for handling of dst register
-
- RegisterID* ignoredResult() { return &m_ignoredResultRegister; }
-
- // Returns a place to write intermediate values of an operation
- // which reuses dst if it is safe to do so.
- RegisterID* tempDestination(RegisterID* dst)
- {
- return (dst && dst != ignoredResult() && dst->isTemporary()) ? dst : newTemporary();
- }
-
- // Returns the place to write the final output of an operation.
- RegisterID* finalDestination(RegisterID* originalDst, RegisterID* tempDst = 0)
- {
- if (originalDst && originalDst != ignoredResult())
- return originalDst;
- ASSERT(tempDst != ignoredResult());
- if (tempDst && tempDst->isTemporary())
- return tempDst;
- return newTemporary();
- }
-
- // Returns the place to write the final output of an operation.
- RegisterID* finalDestinationOrIgnored(RegisterID* originalDst, RegisterID* tempDst = 0)
- {
- if (originalDst)
- return originalDst;
- ASSERT(tempDst != ignoredResult());
- if (tempDst && tempDst->isTemporary())
- return tempDst;
- return newTemporary();
- }
-
- RegisterID* destinationForAssignResult(RegisterID* dst)
- {
- if (dst && dst != ignoredResult() && m_codeBlock->needsFullScopeChain())
- return dst->isTemporary() ? dst : newTemporary();
- return 0;
- }
-
- // Moves src to dst if dst is not null and is different from src, otherwise just returns src.
- RegisterID* moveToDestinationIfNeeded(RegisterID* dst, RegisterID* src)
- {
- return dst == ignoredResult() ? 0 : (dst && dst != src) ? emitMove(dst, src) : src;
- }
-
- PassRefPtr<LabelScope> newLabelScope(LabelScope::Type, const Identifier* = 0);
- PassRefPtr<Label> newLabel();
-
- // The emitNode functions are just syntactic sugar for calling
- // Node::emitCode. These functions accept a 0 for the register,
- // meaning that the node should allocate a register, or ignoredResult(),
- // meaning that the node need not put the result in a register.
- // Other emit functions do not accept 0 or ignoredResult().
- RegisterID* emitNode(RegisterID* dst, Node* n)
- {
- // Node::emitCode assumes that dst, if provided, is either a local or a referenced temporary.
- ASSERT(!dst || dst == ignoredResult() || !dst->isTemporary() || dst->refCount());
- addLineInfo(n->lineNo());
- return m_stack.recursionCheck()
- ? n->emitBytecode(*this, dst)
- : emitThrowExpressionTooDeepException();
- }
-
- RegisterID* emitNode(Node* n)
- {
- return emitNode(0, n);
- }
-
- void emitNodeInConditionContext(ExpressionNode* n, Label* trueTarget, Label* falseTarget, bool fallThroughMeansTrue)
- {
- addLineInfo(n->lineNo());
- if (m_stack.recursionCheck())
- n->emitBytecodeInConditionContext(*this, trueTarget, falseTarget, fallThroughMeansTrue);
- else
- emitThrowExpressionTooDeepException();
- }
-
- void emitExpressionInfo(unsigned divot, unsigned startOffset, unsigned endOffset)
- {
- if (!m_shouldEmitRichSourceInfo)
- return;
-
- divot -= m_codeBlock->sourceOffset();
- if (divot > ExpressionRangeInfo::MaxDivot) {
- // Overflow has occurred, we can only give line number info for errors for this region
- divot = 0;
- startOffset = 0;
- endOffset = 0;
- } else if (startOffset > ExpressionRangeInfo::MaxOffset) {
- // If the start offset is out of bounds we clear both offsets
- // so we only get the divot marker. Error message will have to be reduced
- // to line and column number.
- startOffset = 0;
- endOffset = 0;
- } else if (endOffset > ExpressionRangeInfo::MaxOffset) {
- // The end offset is only used for additional context, and is much more likely
- // to overflow (eg. function call arguments) so we are willing to drop it without
- // dropping the rest of the range.
- endOffset = 0;
- }
-
- ExpressionRangeInfo info;
- info.instructionOffset = instructions().size();
- info.divotPoint = divot;
- info.startOffset = startOffset;
- info.endOffset = endOffset;
- m_codeBlock->addExpressionInfo(info);
- }
-
- ALWAYS_INLINE bool leftHandSideNeedsCopy(bool rightHasAssignments, bool rightIsPure)
- {
- return (m_codeType != FunctionCode || m_codeBlock->needsFullScopeChain() || rightHasAssignments) && !rightIsPure;
- }
-
- ALWAYS_INLINE PassRefPtr<RegisterID> emitNodeForLeftHandSide(ExpressionNode* n, bool rightHasAssignments, bool rightIsPure)
- {
- if (leftHandSideNeedsCopy(rightHasAssignments, rightIsPure)) {
- PassRefPtr<RegisterID> dst = newTemporary();
- emitNode(dst.get(), n);
- return dst;
- }
-
- return PassRefPtr<RegisterID>(emitNode(n));
- }
-
- RegisterID* emitLoad(RegisterID* dst, bool);
- RegisterID* emitLoad(RegisterID* dst, double);
- RegisterID* emitLoad(RegisterID* dst, const Identifier&);
- RegisterID* emitLoad(RegisterID* dst, JSValue);
-
- RegisterID* emitUnaryOp(OpcodeID, RegisterID* dst, RegisterID* src);
- RegisterID* emitBinaryOp(OpcodeID, RegisterID* dst, RegisterID* src1, RegisterID* src2, OperandTypes);
- RegisterID* emitEqualityOp(OpcodeID, RegisterID* dst, RegisterID* src1, RegisterID* src2);
- RegisterID* emitUnaryNoDstOp(OpcodeID, RegisterID* src);
-
- RegisterID* emitNewObject(RegisterID* dst);
- RegisterID* emitNewArray(RegisterID* dst, ElementNode*); // stops at first elision
-
- RegisterID* emitNewFunction(RegisterID* dst, FunctionBodyNode* body);
- RegisterID* emitLazyNewFunction(RegisterID* dst, FunctionBodyNode* body);
- RegisterID* emitNewFunctionInternal(RegisterID* dst, unsigned index, bool shouldNullCheck);
- RegisterID* emitNewFunctionExpression(RegisterID* dst, FuncExprNode* func);
- RegisterID* emitNewRegExp(RegisterID* dst, RegExp* regExp);
-
- RegisterID* emitMove(RegisterID* dst, RegisterID* src);
-
- RegisterID* emitToJSNumber(RegisterID* dst, RegisterID* src) { return emitUnaryOp(op_to_jsnumber, dst, src); }
- RegisterID* emitPreInc(RegisterID* srcDst);
- RegisterID* emitPreDec(RegisterID* srcDst);
- RegisterID* emitPostInc(RegisterID* dst, RegisterID* srcDst);
- RegisterID* emitPostDec(RegisterID* dst, RegisterID* srcDst);
-
- void emitCheckHasInstance(RegisterID* base);
- RegisterID* emitInstanceOf(RegisterID* dst, RegisterID* value, RegisterID* base, RegisterID* basePrototype);
- RegisterID* emitTypeOf(RegisterID* dst, RegisterID* src) { return emitUnaryOp(op_typeof, dst, src); }
- RegisterID* emitIn(RegisterID* dst, RegisterID* property, RegisterID* base) { return emitBinaryOp(op_in, dst, property, base, OperandTypes()); }
-
- RegisterID* emitResolve(RegisterID* dst, const Identifier& property);
- RegisterID* emitGetScopedVar(RegisterID* dst, size_t skip, int index, JSValue globalObject);
- RegisterID* emitPutScopedVar(size_t skip, int index, RegisterID* value, JSValue globalObject);
-
- RegisterID* emitResolveBase(RegisterID* dst, const Identifier& property);
- RegisterID* emitResolveBaseForPut(RegisterID* dst, const Identifier& property);
- RegisterID* emitResolveWithBase(RegisterID* baseDst, RegisterID* propDst, const Identifier& property);
-
- void emitMethodCheck();
-
- RegisterID* emitGetById(RegisterID* dst, RegisterID* base, const Identifier& property);
- RegisterID* emitGetArgumentsLength(RegisterID* dst, RegisterID* base);
- RegisterID* emitPutById(RegisterID* base, const Identifier& property, RegisterID* value);
- RegisterID* emitDirectPutById(RegisterID* base, const Identifier& property, RegisterID* value);
- RegisterID* emitDeleteById(RegisterID* dst, RegisterID* base, const Identifier&);
- RegisterID* emitGetByVal(RegisterID* dst, RegisterID* base, RegisterID* property);
- RegisterID* emitGetArgumentByVal(RegisterID* dst, RegisterID* base, RegisterID* property);
- RegisterID* emitPutByVal(RegisterID* base, RegisterID* property, RegisterID* value);
- RegisterID* emitDeleteByVal(RegisterID* dst, RegisterID* base, RegisterID* property);
- RegisterID* emitPutByIndex(RegisterID* base, unsigned index, RegisterID* value);
- RegisterID* emitPutGetter(RegisterID* base, const Identifier& property, RegisterID* value);
- RegisterID* emitPutSetter(RegisterID* base, const Identifier& property, RegisterID* value);
-
- RegisterID* emitCall(RegisterID* dst, RegisterID* func, CallArguments&, unsigned divot, unsigned startOffset, unsigned endOffset);
- RegisterID* emitCallEval(RegisterID* dst, RegisterID* func, CallArguments&, unsigned divot, unsigned startOffset, unsigned endOffset);
- RegisterID* emitCallVarargs(RegisterID* dst, RegisterID* func, RegisterID* thisRegister, RegisterID* argCount, unsigned divot, unsigned startOffset, unsigned endOffset);
- RegisterID* emitLoadVarargs(RegisterID* argCountDst, RegisterID* thisRegister, RegisterID* args);
-
- RegisterID* emitReturn(RegisterID* src);
- RegisterID* emitEnd(RegisterID* src) { return emitUnaryNoDstOp(op_end, src); }
-
- RegisterID* emitConstruct(RegisterID* dst, RegisterID* func, CallArguments&, unsigned divot, unsigned startOffset, unsigned endOffset);
- RegisterID* emitStrcat(RegisterID* dst, RegisterID* src, int count);
- void emitToPrimitive(RegisterID* dst, RegisterID* src);
-
- PassRefPtr<Label> emitLabel(Label*);
- PassRefPtr<Label> emitJump(Label* target);
- PassRefPtr<Label> emitJumpIfTrue(RegisterID* cond, Label* target);
- PassRefPtr<Label> emitJumpIfFalse(RegisterID* cond, Label* target);
- PassRefPtr<Label> emitJumpIfNotFunctionCall(RegisterID* cond, Label* target);
- PassRefPtr<Label> emitJumpIfNotFunctionApply(RegisterID* cond, Label* target);
- PassRefPtr<Label> emitJumpScopes(Label* target, int targetScopeDepth);
-
- PassRefPtr<Label> emitJumpSubroutine(RegisterID* retAddrDst, Label*);
- void emitSubroutineReturn(RegisterID* retAddrSrc);
-
- RegisterID* emitGetPropertyNames(RegisterID* dst, RegisterID* base, RegisterID* i, RegisterID* size, Label* breakTarget);
- RegisterID* emitNextPropertyName(RegisterID* dst, RegisterID* base, RegisterID* i, RegisterID* size, RegisterID* iter, Label* target);
-
- RegisterID* emitCatch(RegisterID*, Label* start, Label* end);
- void emitThrow(RegisterID* exc)
- {
- m_usesExceptions = true;
- emitUnaryNoDstOp(op_throw, exc);
- }
-
- void emitThrowReferenceError(const UString& message);
- void emitThrowSyntaxError(const UString& message);
-
- void emitPushNewScope(RegisterID* dst, const Identifier& property, RegisterID* value);
-
- RegisterID* emitPushScope(RegisterID* scope);
- void emitPopScope();
-
- void emitDebugHook(DebugHookID, int firstLine, int lastLine);
-
- int scopeDepth() { return m_dynamicScopeDepth + m_finallyDepth; }
- bool hasFinaliser() { return m_finallyDepth != 0; }
-
- void pushFinallyContext(Label* target, RegisterID* returnAddrDst);
- void popFinallyContext();
-
- void pushOptimisedForIn(RegisterID* expectedBase, RegisterID* iter, RegisterID* index, RegisterID* propertyRegister)
- {
- ForInContext context = { expectedBase, iter, index, propertyRegister };
- m_forInContextStack.append(context);
- }
-
- void popOptimisedForIn()
- {
- m_forInContextStack.removeLast();
- }
-
- LabelScope* breakTarget(const Identifier&);
- LabelScope* continueTarget(const Identifier&);
-
- void beginSwitch(RegisterID*, SwitchInfo::SwitchType);
- void endSwitch(uint32_t clauseCount, RefPtr<Label>*, ExpressionNode**, Label* defaultLabel, int32_t min, int32_t range);
-
- CodeType codeType() const { return m_codeType; }
-
- void setRegeneratingForExceptionInfo(CodeBlock* originalCodeBlock)
- {
- m_regeneratingForExceptionInfo = true;
- m_codeBlockBeingRegeneratedFrom = originalCodeBlock;
- }
-
- bool shouldEmitProfileHooks() { return m_shouldEmitProfileHooks; }
-
- bool isStrictMode() const { return m_codeBlock->isStrictMode(); }
-
- private:
- void emitOpcode(OpcodeID);
- void retrieveLastBinaryOp(int& dstIndex, int& src1Index, int& src2Index);
- void retrieveLastUnaryOp(int& dstIndex, int& srcIndex);
- ALWAYS_INLINE void rewindBinaryOp();
- ALWAYS_INLINE void rewindUnaryOp();
-
- PassRefPtr<Label> emitComplexJumpScopes(Label* target, ControlFlowContext* topScope, ControlFlowContext* bottomScope);
-
- typedef HashMap<EncodedJSValue, unsigned, EncodedJSValueHash, EncodedJSValueHashTraits> JSValueMap;
-
- struct IdentifierMapIndexHashTraits {
- typedef int TraitType;
- typedef IdentifierMapIndexHashTraits StorageTraits;
- static int emptyValue() { return std::numeric_limits<int>::max(); }
- static const bool emptyValueIsZero = false;
- static const bool needsDestruction = false;
- static const bool needsRef = false;
- };
-
- typedef HashMap<RefPtr<StringImpl>, int, IdentifierRepHash, HashTraits<RefPtr<StringImpl> >, IdentifierMapIndexHashTraits> IdentifierMap;
- typedef HashMap<double, JSValue> NumberMap;
- typedef HashMap<StringImpl*, JSString*, IdentifierRepHash> IdentifierStringMap;
-
- RegisterID* emitCall(OpcodeID, RegisterID* dst, RegisterID* func, CallArguments&, unsigned divot, unsigned startOffset, unsigned endOffset);
-
- RegisterID* newRegister();
-
- // Adds a var slot and maps it to the name ident in symbolTable().
- RegisterID* addVar(const Identifier& ident, bool isConstant)
- {
- RegisterID* local;
- addVar(ident, isConstant, local);
- return local;
- }
-
- // Ditto. Returns true if a new RegisterID was added, false if a pre-existing RegisterID was re-used.
- bool addVar(const Identifier&, bool isConstant, RegisterID*&);
-
- // Adds an anonymous var slot. To give this slot a name, add it to symbolTable().
- RegisterID* addVar()
- {
- ++m_codeBlock->m_numVars;
- return newRegister();
- }
-
- // Returns the RegisterID corresponding to ident.
- RegisterID* addGlobalVar(const Identifier& ident, bool isConstant)
- {
- RegisterID* local;
- addGlobalVar(ident, isConstant, local);
- return local;
- }
- // Returns true if a new RegisterID was added, false if a pre-existing RegisterID was re-used.
- bool addGlobalVar(const Identifier&, bool isConstant, RegisterID*&);
-
- void addParameter(const Identifier&, int parameterIndex);
-
- void preserveLastVar();
-
- RegisterID& registerFor(int index)
- {
- if (index >= 0)
- return m_calleeRegisters[index];
-
- if (m_parameters.size()) {
- ASSERT(!m_globals.size());
- return m_parameters[index + m_parameters.size() + RegisterFile::CallFrameHeaderSize];
- }
-
- return m_globals[-index - 1];
- }
-
- unsigned addConstant(const Identifier&);
- RegisterID* addConstantValue(JSValue);
- unsigned addRegExp(RegExp*);
-
- PassRefPtr<FunctionExecutable> makeFunction(ExecState* exec, FunctionBodyNode* body)
- {
- return FunctionExecutable::create(exec, body->ident(), body->source(), body->usesArguments(), body->parameters(), body->isStrictMode(), body->lineNo(), body->lastLine());
- }
-
- PassRefPtr<FunctionExecutable> makeFunction(JSGlobalData* globalData, FunctionBodyNode* body)
- {
- return FunctionExecutable::create(globalData, body->ident(), body->source(), body->usesArguments(), body->parameters(), body->isStrictMode(), body->lineNo(), body->lastLine());
- }
-
- void addLineInfo(unsigned lineNo)
- {
-#if !ENABLE(OPCODE_SAMPLING)
- if (m_shouldEmitRichSourceInfo)
-#endif
- m_codeBlock->addLineInfo(instructions().size(), lineNo);
- }
-
- RegisterID* emitInitLazyRegister(RegisterID*);
-
- Vector<Instruction>& instructions() { return m_codeBlock->instructions(); }
- SymbolTable& symbolTable() { return *m_symbolTable; }
-
- bool shouldOptimizeLocals() { return (m_codeType != EvalCode) && !m_dynamicScopeDepth; }
- bool canOptimizeNonLocals() { return (m_codeType == FunctionCode) && !m_dynamicScopeDepth && !m_codeBlock->usesEval(); }
-
- RegisterID* emitThrowExpressionTooDeepException();
-
- void createArgumentsIfNecessary();
- void createActivationIfNecessary();
- RegisterID* createLazyRegisterIfNecessary(RegisterID*);
-
- bool m_shouldEmitDebugHooks;
- bool m_shouldEmitProfileHooks;
- bool m_shouldEmitRichSourceInfo;
-
- const ScopeChain* m_scopeChain;
- SymbolTable* m_symbolTable;
-
- ScopeNode* m_scopeNode;
- CodeBlock* m_codeBlock;
-
- // Some of these objects keep pointers to one another. They are arranged
- // to ensure a sane destruction order that avoids references to freed memory.
- HashSet<RefPtr<StringImpl>, IdentifierRepHash> m_functions;
- RegisterID m_ignoredResultRegister;
- RegisterID m_thisRegister;
- RegisterID* m_activationRegister;
- SegmentedVector<RegisterID, 32> m_constantPoolRegisters;
- SegmentedVector<RegisterID, 32> m_calleeRegisters;
- SegmentedVector<RegisterID, 32> m_parameters;
- SegmentedVector<RegisterID, 32> m_globals;
- SegmentedVector<Label, 32> m_labels;
- SegmentedVector<LabelScope, 8> m_labelScopes;
- RefPtr<RegisterID> m_lastVar;
- int m_finallyDepth;
- int m_dynamicScopeDepth;
- int m_baseScopeDepth;
- CodeType m_codeType;
-
- Vector<ControlFlowContext> m_scopeContextStack;
- Vector<SwitchInfo> m_switchContextStack;
- Vector<ForInContext> m_forInContextStack;
-
- int m_nextGlobalIndex;
- int m_firstConstantIndex;
- int m_nextConstantOffset;
- unsigned m_globalConstantIndex;
-
- int m_globalVarStorageOffset;
-
- bool m_hasCreatedActivation;
- int m_firstLazyFunction;
- int m_lastLazyFunction;
- HashMap<unsigned int, FunctionBodyNode*, WTF::IntHash<unsigned int>, WTF::UnsignedWithZeroKeyHashTraits<unsigned int> > m_lazyFunctions;
- typedef HashMap<FunctionBodyNode*, unsigned> FunctionOffsetMap;
- FunctionOffsetMap m_functionOffsets;
-
- // Constant pool
- IdentifierMap m_identifierMap;
- JSValueMap m_jsValueMap;
- NumberMap m_numberMap;
- IdentifierStringMap m_stringMap;
-
- JSGlobalData* m_globalData;
-
- OpcodeID m_lastOpcodeID;
-#ifndef NDEBUG
- size_t m_lastOpcodePosition;
-#endif
-
- StackBounds m_stack;
-
- bool m_usesExceptions;
- bool m_regeneratingForExceptionInfo;
- CodeBlock* m_codeBlockBeingRegeneratedFrom;
- };
-
-}
-
-#endif // BytecodeGenerator_h