📄 nodes.h
字号:
/* * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) * Copyright (C) 2001 Peter Kelly (pmk@post.com) * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. * Copyright (C) 2007 Cameron Zwarich (cwzwarich@uwaterloo.ca) * Copyright (C) 2007 Maks Orlovich * Copyright (C) 2007 Eric Seidel <eric@webkit.org> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */#ifndef NODES_H_#define NODES_H_#include "Error.h"#include "Opcode.h"#include "ResultType.h"#include "SourceCode.h"#include "SymbolTable.h"#include <wtf/MathExtras.h>#include <wtf/OwnPtr.h>#include <wtf/Vector.h>#if PLATFORM(X86) && COMPILER(GCC)#define JSC_FAST_CALL __attribute__((regparm(3)))#else#define JSC_FAST_CALL#endifnamespace JSC { class CodeBlock; class BytecodeGenerator; class FuncDeclNode; class EvalCodeBlock; class JSFunction; class NodeReleaser; class ProgramCodeBlock; class PropertyListNode; class RegisterID; class ScopeChainNode; typedef unsigned CodeFeatures; const CodeFeatures NoFeatures = 0; const CodeFeatures EvalFeature = 1 << 0; const CodeFeatures ClosureFeature = 1 << 1; const CodeFeatures AssignFeature = 1 << 2; const CodeFeatures ArgumentsFeature = 1 << 3; const CodeFeatures WithFeature = 1 << 4; const CodeFeatures CatchFeature = 1 << 5; const CodeFeatures ThisFeature = 1 << 6; const CodeFeatures AllFeatures = EvalFeature | ClosureFeature | AssignFeature | ArgumentsFeature | WithFeature | CatchFeature | ThisFeature; enum Operator { OpEqual, OpPlusEq, OpMinusEq, OpMultEq, OpDivEq, OpPlusPlus, OpMinusMinus, OpAndEq, OpXOrEq, OpOrEq, OpModEq, OpLShift, OpRShift, OpURShift }; enum LogicalOperator { OpLogicalAnd, OpLogicalOr }; namespace DeclarationStacks { enum VarAttrs { IsConstant = 1, HasInitializer = 2 }; typedef Vector<std::pair<Identifier, unsigned> > VarStack; typedef Vector<RefPtr<FuncDeclNode> > FunctionStack; } struct SwitchInfo { enum SwitchType { SwitchNone, SwitchImmediate, SwitchCharacter, SwitchString }; uint32_t bytecodeOffset; SwitchType switchType; }; class ParserRefCounted : Noncopyable { protected: ParserRefCounted(JSGlobalData*) JSC_FAST_CALL; public: virtual ~ParserRefCounted(); // Nonrecursive destruction. virtual void releaseNodes(NodeReleaser&); void ref() JSC_FAST_CALL; void deref() JSC_FAST_CALL; bool hasOneRef() JSC_FAST_CALL; static void deleteNewObjects(JSGlobalData*) JSC_FAST_CALL; private: JSGlobalData* m_globalData; }; class Node : public ParserRefCounted { public: Node(JSGlobalData*) JSC_FAST_CALL; /* Return value: The register holding the production's value. dst: An optional parameter specifying the most efficient destination at which to store the production's value. The callee must honor dst. dst provides for a crude form of copy propagation. For example, x = 1 becomes load r[x], 1 instead of load r0, 1 mov r[x], r0 because the assignment node, "x =", passes r[x] as dst to the number node, "1". */ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* dst = 0) JSC_FAST_CALL = 0; int lineNo() const { return m_line; } protected: int m_line; }; class ExpressionNode : public Node { public: ExpressionNode(JSGlobalData* globalData, ResultType resultDesc = ResultType::unknownType()) JSC_FAST_CALL : Node(globalData) , m_resultDesc(resultDesc) { } virtual bool isNumber() const JSC_FAST_CALL { return false; } virtual bool isString() const JSC_FAST_CALL { return false; } virtual bool isNull() const JSC_FAST_CALL { return false; } virtual bool isPure(BytecodeGenerator&) const JSC_FAST_CALL { return false; } virtual bool isLocation() const JSC_FAST_CALL { return false; } virtual bool isResolveNode() const JSC_FAST_CALL { return false; } virtual bool isBracketAccessorNode() const JSC_FAST_CALL { return false; } virtual bool isDotAccessorNode() const JSC_FAST_CALL { return false; } virtual bool isFuncExprNode() const JSC_FAST_CALL { return false; } virtual ExpressionNode* stripUnaryPlus() { return this; } ResultType resultDescriptor() const JSC_FAST_CALL { return m_resultDesc; } // This needs to be in public in order to compile using GCC 3.x typedef enum { EvalOperator, FunctionCall } CallerType; private: ResultType m_resultDesc; }; class StatementNode : public Node { public: StatementNode(JSGlobalData*) JSC_FAST_CALL; void setLoc(int line0, int line1) JSC_FAST_CALL; int firstLine() const JSC_FAST_CALL { return lineNo(); } int lastLine() const JSC_FAST_CALL { return m_lastLine; } virtual bool isEmptyStatement() const JSC_FAST_CALL { return false; } virtual bool isReturnNode() const JSC_FAST_CALL { return false; } virtual bool isExprStatement() const JSC_FAST_CALL { return false; } virtual bool isBlock() const JSC_FAST_CALL { return false; } private: int m_lastLine; }; class NullNode : public ExpressionNode { public: NullNode(JSGlobalData* globalData) JSC_FAST_CALL : ExpressionNode(globalData, ResultType::nullType()) { } virtual bool isNull() const JSC_FAST_CALL { return true; } virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL; }; class BooleanNode : public ExpressionNode { public: BooleanNode(JSGlobalData* globalData, bool value) JSC_FAST_CALL : ExpressionNode(globalData, ResultType::booleanType()) , m_value(value) { } virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL; virtual bool isPure(BytecodeGenerator&) const JSC_FAST_CALL { return true; } private: bool m_value; }; class NumberNode : public ExpressionNode { public: NumberNode(JSGlobalData* globalData, double v) JSC_FAST_CALL : ExpressionNode(globalData, ResultType::numberType()) , m_double(v) { } virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL; virtual bool isNumber() const JSC_FAST_CALL { return true; } virtual bool isPure(BytecodeGenerator&) const JSC_FAST_CALL { return true; } double value() const JSC_FAST_CALL { return m_double; } void setValue(double d) JSC_FAST_CALL { m_double = d; } private: double m_double; }; class StringNode : public ExpressionNode { public: StringNode(JSGlobalData* globalData, const Identifier& v) JSC_FAST_CALL : ExpressionNode(globalData, ResultType::stringType()) , m_value(v) { } virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL; virtual bool isString() const JSC_FAST_CALL { return true; } const Identifier& value() { return m_value; } virtual bool isPure(BytecodeGenerator&) const JSC_FAST_CALL { return true; } private: Identifier m_value; }; class ThrowableExpressionData { public: ThrowableExpressionData() : m_divot(static_cast<uint32_t>(-1)) , m_startOffset(static_cast<uint16_t>(-1)) , m_endOffset(static_cast<uint16_t>(-1)) { } ThrowableExpressionData(unsigned divot, unsigned startOffset, unsigned endOffset) : m_divot(divot) , m_startOffset(startOffset) , m_endOffset(endOffset) { } void setExceptionSourceCode(unsigned divot, unsigned startOffset, unsigned endOffset) { m_divot = divot; m_startOffset = startOffset; m_endOffset = endOffset; } uint32_t divot() const { return m_divot; } uint16_t startOffset() const { return m_startOffset; } uint16_t endOffset() const { return m_endOffset; } protected: RegisterID* emitThrowError(BytecodeGenerator&, ErrorType, const char* msg); RegisterID* emitThrowError(BytecodeGenerator&, ErrorType, const char* msg, const Identifier&); private: uint32_t m_divot; uint16_t m_startOffset; uint16_t m_endOffset; }; class ThrowableSubExpressionData : public ThrowableExpressionData { public: ThrowableSubExpressionData() : ThrowableExpressionData() , m_subexpressionDivotOffset(0) , m_subexpressionEndOffset(0) { } ThrowableSubExpressionData(unsigned divot, unsigned startOffset, unsigned endOffset) : ThrowableExpressionData(divot, startOffset, endOffset) , m_subexpressionDivotOffset(0) , m_subexpressionEndOffset(0) { } void setSubexpressionInfo(uint32_t subexpressionDivot, uint16_t subexpressionOffset) { ASSERT(subexpressionDivot <= divot()); if ((divot() - subexpressionDivot) & ~0xFFFF) // Overflow means we can't do this safely, so just point at the primary divot return; m_subexpressionDivotOffset = divot() - subexpressionDivot; m_subexpressionEndOffset = subexpressionOffset; } protected: uint16_t m_subexpressionDivotOffset; uint16_t m_subexpressionEndOffset; }; class ThrowablePrefixedSubExpressionData : public ThrowableExpressionData { public: ThrowablePrefixedSubExpressionData() : ThrowableExpressionData() , m_subexpressionDivotOffset(0) , m_subexpressionStartOffset(0) { } ThrowablePrefixedSubExpressionData(unsigned divot, unsigned startOffset, unsigned endOffset) : ThrowableExpressionData(divot, startOffset, endOffset) , m_subexpressionDivotOffset(0) , m_subexpressionStartOffset(0) { } void setSubexpressionInfo(uint32_t subexpressionDivot, uint16_t subexpressionOffset) { ASSERT(subexpressionDivot >= divot()); if ((subexpressionDivot - divot()) & ~0xFFFF) // Overflow means we can't do this safely, so just point at the primary divot return; m_subexpressionDivotOffset = subexpressionDivot - divot(); m_subexpressionStartOffset = subexpressionOffset; } protected: uint16_t m_subexpressionDivotOffset; uint16_t m_subexpressionStartOffset; }; class RegExpNode : public ExpressionNode, public ThrowableExpressionData { public: RegExpNode(JSGlobalData* globalData, const UString& pattern, const UString& flags) JSC_FAST_CALL : ExpressionNode(globalData) , m_pattern(pattern) , m_flags(flags) { } virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL; private: UString m_pattern;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -