/*
* 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) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2013 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>
#include "JITCode.h"
#include "Opcode.h"
#include "ParserArena.h"
+#include "ParserTokens.h"
#include "ResultType.h"
#include "SourceCode.h"
#include "SymbolTable.h"
class PropertyListNode;
class ReadModifyResolveNode;
class RegisterID;
- class ScopeChainNode;
+ class JSScope;
class ScopeNode;
- 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 StrictModeFeature = 1 << 7;
- const CodeFeatures ShadowsArgumentsFeature = 1 << 8;
-
-
- const CodeFeatures AllFeatures = EvalFeature | ClosureFeature | AssignFeature | ArgumentsFeature | WithFeature | CatchFeature | ThisFeature | StrictModeFeature | ShadowsArgumentsFeature;
-
enum Operator {
OpEqual,
OpPlusEq,
OpLogicalOr
};
+ enum FallThroughMode {
+ FallThroughMeansTrue = 0,
+ FallThroughMeansFalse = 1
+ };
+ inline FallThroughMode invert(FallThroughMode fallThroughMode) { return static_cast<FallThroughMode>(!fallThroughMode); }
+
typedef HashSet<RefPtr<StringImpl>, IdentifierRepHash> IdentifierSet;
namespace DeclarationStacks {
public:
// ParserArenaFreeable objects are are freed when the arena is deleted.
// Destructors are not called. Clients must not call delete on such objects.
- void* operator new(size_t, JSGlobalData*);
+ void* operator new(size_t, VM*);
};
class ParserArenaDeletable {
// ParserArenaDeletable objects are deleted when the arena is deleted.
// Clients must not call delete directly on such objects.
- void* operator new(size_t, JSGlobalData*);
+ void* operator new(size_t, VM*);
+ };
+
+ template <typename T>
+ struct ParserArenaData : ParserArenaDeletable {
+ T data;
};
class ParserArenaRefCounted : public RefCounted<ParserArenaRefCounted> {
protected:
- ParserArenaRefCounted(JSGlobalData*);
+ ParserArenaRefCounted(VM*);
public:
virtual ~ParserArenaRefCounted()
class Node : public ParserArenaFreeable {
protected:
- Node(JSGlobalData*);
+ Node(const JSTokenLocation&);
public:
virtual ~Node() { }
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* destination = 0) = 0;
-
- int lineNo() const { return m_line; }
+ int lineNo() const { return m_lineNumber; }
+ int startOffset() const { return m_startOffset; }
+ int lineStartOffset() const { return m_lineStartOffset; }
protected:
- int m_line;
+ int m_lineNumber;
+ int m_startOffset;
+ int m_lineStartOffset;
};
class ExpressionNode : public Node {
protected:
- ExpressionNode(JSGlobalData*, ResultType = ResultType::unknownType());
+ ExpressionNode(const JSTokenLocation&, ResultType = ResultType::unknownType());
public:
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* destination = 0) = 0;
+
virtual bool isNumber() const { return false; }
virtual bool isString() const { return false; }
virtual bool isNull() const { return false; }
virtual bool isPure(BytecodeGenerator&) const { return false; }
+ virtual bool isConstant() const { return false; }
virtual bool isLocation() const { return false; }
virtual bool isResolveNode() const { return false; }
virtual bool isBracketAccessorNode() const { return false; }
virtual bool isSimpleArray() const { return false; }
virtual bool isAdd() const { return false; }
virtual bool isSubtract() const { return false; }
- virtual bool hasConditionContextCodegen() const { return false; }
+ virtual bool isBoolean() const { return false; }
- virtual void emitBytecodeInConditionContext(BytecodeGenerator&, Label*, Label*, bool) { ASSERT_NOT_REACHED(); }
+ virtual void emitBytecodeInConditionContext(BytecodeGenerator&, Label*, Label*, FallThroughMode);
virtual ExpressionNode* stripUnaryPlus() { return this; }
class StatementNode : public Node {
protected:
- StatementNode(JSGlobalData*);
+ StatementNode(const JSTokenLocation&);
public:
- void setLoc(int firstLine, int lastLine);
- int firstLine() const { return lineNo(); }
- int lastLine() const { return m_lastLine; }
+ virtual void emitBytecode(BytecodeGenerator&, RegisterID* destination = 0) = 0;
+
+ void setLoc(unsigned firstLine, unsigned lastLine, int startOffset, int lineStartOffset);
+ unsigned firstLine() const { return lineNo(); }
+ unsigned lastLine() const { return m_lastLine; }
virtual bool isEmptyStatement() const { return false; }
virtual bool isReturnNode() const { return false; }
virtual bool isExprStatement() const { return false; }
-
+ virtual bool isBreak() const { return false; }
+ virtual bool isContinue() const { return false; }
virtual bool isBlock() const { return false; }
private:
int m_lastLine;
};
- class NullNode : public ExpressionNode {
+ class ConstantNode : public ExpressionNode {
public:
- NullNode(JSGlobalData*);
-
+ ConstantNode(const JSTokenLocation&, ResultType);
+ virtual bool isPure(BytecodeGenerator&) const { return true; }
+ virtual bool isConstant() const { return true; }
+ virtual JSValue jsValue(BytecodeGenerator&) const = 0;
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+ void emitBytecodeInConditionContext(BytecodeGenerator&, Label* trueTarget, Label* falseTarget, FallThroughMode);
+ };
+
+ class NullNode : public ConstantNode {
+ public:
+ NullNode(const JSTokenLocation&);
+ private:
virtual bool isNull() const { return true; }
+ virtual JSValue jsValue(BytecodeGenerator&) const { return jsNull(); }
};
- class BooleanNode : public ExpressionNode {
+ class BooleanNode : public ConstantNode {
public:
- BooleanNode(JSGlobalData*, bool value);
+ BooleanNode(const JSTokenLocation&, bool value);
+ bool value() { return m_value; }
private:
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
-
- virtual bool isPure(BytecodeGenerator&) const { return true; }
+ virtual bool isBoolean() const { return true; }
+ virtual JSValue jsValue(BytecodeGenerator&) const { return jsBoolean(m_value); }
bool m_value;
};
- class NumberNode : public ExpressionNode {
+ class NumberNode : public ConstantNode {
public:
- NumberNode(JSGlobalData*, double value);
-
- double value() const { return m_value; }
+ NumberNode(const JSTokenLocation&, double value);
+ double value() { return m_value; }
void setValue(double value) { m_value = value; }
private:
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
-
virtual bool isNumber() const { return true; }
- virtual bool isPure(BytecodeGenerator&) const { return true; }
+ virtual JSValue jsValue(BytecodeGenerator&) const { return jsNumber(m_value); }
double m_value;
};
- class StringNode : public ExpressionNode {
+ class StringNode : public ConstantNode {
public:
- StringNode(JSGlobalData*, const Identifier&);
-
+ StringNode(const JSTokenLocation&, const Identifier&);
const Identifier& value() { return m_value; }
private:
- virtual bool isPure(BytecodeGenerator&) const { return true; }
-
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
-
virtual bool isString() const { return true; }
+ virtual JSValue jsValue(BytecodeGenerator&) const;
const Identifier& m_value;
};
public:
ThrowableExpressionData()
: m_divot(static_cast<uint32_t>(-1))
- , m_startOffset(static_cast<uint16_t>(-1))
- , m_endOffset(static_cast<uint16_t>(-1))
+ , m_divotStartOffset(static_cast<uint16_t>(-1))
+ , m_divotEndOffset(static_cast<uint16_t>(-1))
+ , m_divotLine(static_cast<uint32_t>(-1))
+ , m_divotLineStart(static_cast<uint32_t>(-1))
{
}
- ThrowableExpressionData(unsigned divot, unsigned startOffset, unsigned endOffset)
+ ThrowableExpressionData(unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart)
: m_divot(divot)
- , m_startOffset(startOffset)
- , m_endOffset(endOffset)
+ , m_divotStartOffset(startOffset)
+ , m_divotEndOffset(endOffset)
+ , m_divotLine(divotLine)
+ , m_divotLineStart(divotLineStart)
{
+ ASSERT(m_divot >= m_divotLineStart);
}
- void setExceptionSourceCode(unsigned divot, unsigned startOffset, unsigned endOffset)
+ void setExceptionSourceCode(unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart)
{
+ ASSERT(divot >= divotLineStart);
m_divot = divot;
- m_startOffset = startOffset;
- m_endOffset = endOffset;
+ m_divotStartOffset = startOffset;
+ m_divotEndOffset = endOffset;
+ m_divotLine = divotLine;
+ m_divotLineStart = divotLineStart;
}
uint32_t divot() const { return m_divot; }
- uint16_t startOffset() const { return m_startOffset; }
- uint16_t endOffset() const { return m_endOffset; }
+ uint16_t divotStartOffset() const { return m_divotStartOffset; }
+ uint16_t divotEndOffset() const { return m_divotEndOffset; }
+ uint32_t divotLine() const { return m_divotLine; }
+ uint32_t divotLineStart() const { return m_divotLineStart; }
protected:
- RegisterID* emitThrowReferenceError(BytecodeGenerator&, const UString& message);
+ RegisterID* emitThrowReferenceError(BytecodeGenerator&, const String& message);
private:
uint32_t m_divot;
- uint16_t m_startOffset;
- uint16_t m_endOffset;
+ uint16_t m_divotStartOffset;
+ uint16_t m_divotEndOffset;
+ uint32_t m_divotLine;
+ uint32_t m_divotLineStart;
};
class ThrowableSubExpressionData : public ThrowableExpressionData {
ThrowableSubExpressionData()
: m_subexpressionDivotOffset(0)
, m_subexpressionEndOffset(0)
+ , m_subexpressionLineOffset(0)
+ , m_subexpressionLineStartOffset(0)
{
}
- ThrowableSubExpressionData(unsigned divot, unsigned startOffset, unsigned endOffset)
- : ThrowableExpressionData(divot, startOffset, endOffset)
+ ThrowableSubExpressionData(unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart)
+ : ThrowableExpressionData(divot, startOffset, endOffset, divotLine, divotLineStart)
, m_subexpressionDivotOffset(0)
, m_subexpressionEndOffset(0)
+ , m_subexpressionLineOffset(0)
+ , m_subexpressionLineStartOffset(0)
{
}
- void setSubexpressionInfo(uint32_t subexpressionDivot, uint16_t subexpressionOffset)
+ void setSubexpressionInfo(uint32_t subexpressionDivot, uint16_t subexpressionOffset, uint32_t subexpressionLine, uint32_t subexpressionLineStart)
{
ASSERT(subexpressionDivot <= divot());
- if ((divot() - subexpressionDivot) & ~0xFFFF) // Overflow means we can't do this safely, so just point at the primary divot
+ // Overflow means we can't do this safely, so just point at the primary divot,
+ // divotLine, or divotLineStart.
+ if ((divot() - subexpressionDivot) & ~0xFFFF)
+ return;
+ if ((divotLine() - subexpressionLine) & ~0xFFFF)
+ return;
+ if ((divotLineStart() - subexpressionLineStart) & ~0xFFFF)
return;
m_subexpressionDivotOffset = divot() - subexpressionDivot;
m_subexpressionEndOffset = subexpressionOffset;
+ m_subexpressionLineOffset = divotLine() - subexpressionLine;
+ m_subexpressionLineStartOffset = divotLineStart() - subexpressionLineStart;
}
+ unsigned subexpressionDivot() { return divot() - m_subexpressionDivotOffset; }
+ unsigned subexpressionStartOffset() { return divotStartOffset() - m_subexpressionDivotOffset; }
+ unsigned subexpressionEndOffset() { return m_subexpressionEndOffset; }
+ unsigned subexpressionLine() { return divotLine() - m_subexpressionLineOffset; }
+ unsigned subexpressionLineStart() { return divotLineStart() - m_subexpressionLineStartOffset; }
+
protected:
uint16_t m_subexpressionDivotOffset;
uint16_t m_subexpressionEndOffset;
+ uint16_t m_subexpressionLineOffset;
+ uint16_t m_subexpressionLineStartOffset;
};
class ThrowablePrefixedSubExpressionData : public ThrowableExpressionData {
ThrowablePrefixedSubExpressionData()
: m_subexpressionDivotOffset(0)
, m_subexpressionStartOffset(0)
+ , m_subexpressionLineOffset(0)
+ , m_subexpressionLineStartOffset(0)
{
}
- ThrowablePrefixedSubExpressionData(unsigned divot, unsigned startOffset, unsigned endOffset)
- : ThrowableExpressionData(divot, startOffset, endOffset)
+ ThrowablePrefixedSubExpressionData(unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart)
+ : ThrowableExpressionData(divot, startOffset, endOffset, divotLine, divotLineStart)
, m_subexpressionDivotOffset(0)
, m_subexpressionStartOffset(0)
+ , m_subexpressionLineOffset(0)
+ , m_subexpressionLineStartOffset(0)
{
}
- void setSubexpressionInfo(uint32_t subexpressionDivot, uint16_t subexpressionOffset)
+ void setSubexpressionInfo(uint32_t subexpressionDivot, uint16_t subexpressionOffset, uint32_t subexpressionLine, uint32_t subexpressionLineStart)
{
ASSERT(subexpressionDivot >= divot());
- if ((subexpressionDivot - divot()) & ~0xFFFF) // Overflow means we can't do this safely, so just point at the primary divot
+ // Overflow means we can't do this safely, so just point at the primary divot,
+ // divotLine, or divotLineStart.
+ if ((subexpressionDivot - divot()) & ~0xFFFF)
+ return;
+ if ((subexpressionLine - divotLine()) & ~0xFFFF)
+ return;
+ if ((subexpressionLineStart - divotLineStart()) & ~0xFFFF)
return;
m_subexpressionDivotOffset = subexpressionDivot - divot();
m_subexpressionStartOffset = subexpressionOffset;
+ m_subexpressionLineOffset = subexpressionLine - divotLine();
+ m_subexpressionLineStartOffset = subexpressionLineStart - divotLineStart();
}
+ unsigned subexpressionDivot() { return divot() + m_subexpressionDivotOffset; }
+ unsigned subexpressionStartOffset() { return m_subexpressionStartOffset; }
+ unsigned subexpressionEndOffset() { return divotEndOffset() + m_subexpressionDivotOffset; }
+ unsigned subexpressionLine() { return divotLine() + m_subexpressionLineOffset; }
+ unsigned subexpressionLineStart() { return divotLineStart() + m_subexpressionLineStartOffset; }
+
protected:
uint16_t m_subexpressionDivotOffset;
uint16_t m_subexpressionStartOffset;
+ uint16_t m_subexpressionLineOffset;
+ uint16_t m_subexpressionLineStartOffset;
};
class RegExpNode : public ExpressionNode, public ThrowableExpressionData {
public:
- RegExpNode(JSGlobalData*, const Identifier& pattern, const Identifier& flags);
+ RegExpNode(const JSTokenLocation&, const Identifier& pattern, const Identifier& flags);
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
class ThisNode : public ExpressionNode {
public:
- ThisNode(JSGlobalData*);
+ ThisNode(const JSTokenLocation&);
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
class ResolveNode : public ExpressionNode {
public:
- ResolveNode(JSGlobalData*, const Identifier&, int startOffset);
+ ResolveNode(const JSTokenLocation&, const Identifier&, unsigned startOffset, unsigned divotLine, unsigned divotLineStart);
const Identifier& identifier() const { return m_ident; }
virtual bool isResolveNode() const { return true; }
const Identifier& m_ident;
- int32_t m_startOffset;
+ uint32_t m_startOffset;
+ uint32_t m_divotLine;
+ uint32_t m_divotLineStart;
};
class ElementNode : public ParserArenaFreeable {
public:
- ElementNode(JSGlobalData*, int elision, ExpressionNode*);
- ElementNode(JSGlobalData*, ElementNode*, int elision, ExpressionNode*);
+ ElementNode(int elision, ExpressionNode*);
+ ElementNode(ElementNode*, int elision, ExpressionNode*);
int elision() const { return m_elision; }
ExpressionNode* value() { return m_node; }
class ArrayNode : public ExpressionNode {
public:
- ArrayNode(JSGlobalData*, int elision);
- ArrayNode(JSGlobalData*, ElementNode*);
- ArrayNode(JSGlobalData*, int elision, ElementNode*);
+ ArrayNode(const JSTokenLocation&, int elision);
+ ArrayNode(const JSTokenLocation&, ElementNode*);
+ ArrayNode(const JSTokenLocation&, int elision, ElementNode*);
- ArgumentListNode* toArgumentList(JSGlobalData*) const;
+ ArgumentListNode* toArgumentList(VM*, int, int) const;
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
public:
enum Type { Constant = 1, Getter = 2, Setter = 4 };
- PropertyNode(JSGlobalData*, const Identifier& name, ExpressionNode* value, Type);
- PropertyNode(JSGlobalData*, double name, ExpressionNode* value, Type);
+ PropertyNode(VM*, const Identifier&, ExpressionNode*, Type);
+ PropertyNode(VM*, double, ExpressionNode*, Type);
const Identifier& name() const { return m_name; }
Type type() const { return m_type; }
Type m_type;
};
- class PropertyListNode : public Node {
+ class PropertyListNode : public ExpressionNode {
public:
- PropertyListNode(JSGlobalData*, PropertyNode*);
- PropertyListNode(JSGlobalData*, PropertyNode*, PropertyListNode*);
+ PropertyListNode(const JSTokenLocation&, PropertyNode*);
+ PropertyListNode(const JSTokenLocation&, PropertyNode*, PropertyListNode*);
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
class ObjectLiteralNode : public ExpressionNode {
public:
- ObjectLiteralNode(JSGlobalData*);
- ObjectLiteralNode(JSGlobalData*, PropertyListNode*);
+ ObjectLiteralNode(const JSTokenLocation&);
+ ObjectLiteralNode(const JSTokenLocation&, PropertyListNode*);
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
class BracketAccessorNode : public ExpressionNode, public ThrowableExpressionData {
public:
- BracketAccessorNode(JSGlobalData*, ExpressionNode* base, ExpressionNode* subscript, bool subscriptHasAssignments);
+ BracketAccessorNode(const JSTokenLocation&, ExpressionNode* base, ExpressionNode* subscript, bool subscriptHasAssignments);
ExpressionNode* base() const { return m_base; }
ExpressionNode* subscript() const { return m_subscript; }
+ bool subscriptHasAssignments() const { return m_subscriptHasAssignments; }
+
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
class DotAccessorNode : public ExpressionNode, public ThrowableExpressionData {
public:
- DotAccessorNode(JSGlobalData*, ExpressionNode* base, const Identifier&);
+ DotAccessorNode(const JSTokenLocation&, ExpressionNode* base, const Identifier&);
ExpressionNode* base() const { return m_base; }
const Identifier& identifier() const { return m_ident; }
const Identifier& m_ident;
};
- class ArgumentListNode : public Node {
+ class ArgumentListNode : public ExpressionNode {
public:
- ArgumentListNode(JSGlobalData*, ExpressionNode*);
- ArgumentListNode(JSGlobalData*, ArgumentListNode*, ExpressionNode*);
+ ArgumentListNode(const JSTokenLocation&, ExpressionNode*);
+ ArgumentListNode(const JSTokenLocation&, ArgumentListNode*, ExpressionNode*);
ArgumentListNode* m_next;
ExpressionNode* m_expr;
class ArgumentsNode : public ParserArenaFreeable {
public:
- ArgumentsNode(JSGlobalData*);
- ArgumentsNode(JSGlobalData*, ArgumentListNode*);
+ ArgumentsNode();
+ ArgumentsNode(ArgumentListNode*);
ArgumentListNode* m_listNode;
};
class NewExprNode : public ExpressionNode, public ThrowableExpressionData {
public:
- NewExprNode(JSGlobalData*, ExpressionNode*);
- NewExprNode(JSGlobalData*, ExpressionNode*, ArgumentsNode*);
+ NewExprNode(const JSTokenLocation&, ExpressionNode*);
+ NewExprNode(const JSTokenLocation&, ExpressionNode*, ArgumentsNode*);
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
class EvalFunctionCallNode : public ExpressionNode, public ThrowableExpressionData {
public:
- EvalFunctionCallNode(JSGlobalData*, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset);
+ EvalFunctionCallNode(const JSTokenLocation&, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart);
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
class FunctionCallValueNode : public ExpressionNode, public ThrowableExpressionData {
public:
- FunctionCallValueNode(JSGlobalData*, ExpressionNode*, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset);
+ FunctionCallValueNode(const JSTokenLocation&, ExpressionNode*, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart);
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
class FunctionCallResolveNode : public ExpressionNode, public ThrowableExpressionData {
public:
- FunctionCallResolveNode(JSGlobalData*, const Identifier&, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset);
+ FunctionCallResolveNode(const JSTokenLocation&, const Identifier&, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart);
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
const Identifier& m_ident;
ArgumentsNode* m_args;
- size_t m_index; // Used by LocalVarFunctionCallNode.
- size_t m_scopeDepth; // Used by ScopedVarFunctionCallNode and NonLocalVarFunctionCallNode
};
class FunctionCallBracketNode : public ExpressionNode, public ThrowableSubExpressionData {
public:
- FunctionCallBracketNode(JSGlobalData*, ExpressionNode* base, ExpressionNode* subscript, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset);
+ FunctionCallBracketNode(const JSTokenLocation&, ExpressionNode* base, ExpressionNode* subscript, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart);
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
class FunctionCallDotNode : public ExpressionNode, public ThrowableSubExpressionData {
public:
- FunctionCallDotNode(JSGlobalData*, ExpressionNode* base, const Identifier&, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset);
+ FunctionCallDotNode(const JSTokenLocation&, ExpressionNode* base, const Identifier&, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart);
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
class CallFunctionCallDotNode : public FunctionCallDotNode {
public:
- CallFunctionCallDotNode(JSGlobalData*, ExpressionNode* base, const Identifier&, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset);
+ CallFunctionCallDotNode(const JSTokenLocation&, ExpressionNode* base, const Identifier&, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart);
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
class ApplyFunctionCallDotNode : public FunctionCallDotNode {
public:
- ApplyFunctionCallDotNode(JSGlobalData*, ExpressionNode* base, const Identifier&, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset);
-
- private:
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
- };
-
- class PrePostResolveNode : public ExpressionNode, public ThrowableExpressionData {
- public:
- PrePostResolveNode(JSGlobalData*, const Identifier&, unsigned divot, unsigned startOffset, unsigned endOffset);
-
- protected:
- const Identifier& m_ident;
- };
-
- class PostfixResolveNode : public PrePostResolveNode {
- public:
- PostfixResolveNode(JSGlobalData*, const Identifier&, Operator, unsigned divot, unsigned startOffset, unsigned endOffset);
-
- private:
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
-
- Operator m_operator;
- };
-
- class PostfixBracketNode : public ExpressionNode, public ThrowableSubExpressionData {
- public:
- PostfixBracketNode(JSGlobalData*, ExpressionNode* base, ExpressionNode* subscript, Operator, unsigned divot, unsigned startOffset, unsigned endOffset);
-
- private:
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
-
- ExpressionNode* m_base;
- ExpressionNode* m_subscript;
- Operator m_operator;
- };
-
- class PostfixDotNode : public ExpressionNode, public ThrowableSubExpressionData {
- public:
- PostfixDotNode(JSGlobalData*, ExpressionNode* base, const Identifier&, Operator, unsigned divot, unsigned startOffset, unsigned endOffset);
-
- private:
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
-
- ExpressionNode* m_base;
- const Identifier& m_ident;
- Operator m_operator;
- };
-
- class PostfixErrorNode : public ExpressionNode, public ThrowableSubExpressionData {
- public:
- PostfixErrorNode(JSGlobalData*, ExpressionNode*, Operator, unsigned divot, unsigned startOffset, unsigned endOffset);
+ ApplyFunctionCallDotNode(const JSTokenLocation&, ExpressionNode* base, const Identifier&, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart);
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
-
- ExpressionNode* m_expr;
- Operator m_operator;
};
class DeleteResolveNode : public ExpressionNode, public ThrowableExpressionData {
public:
- DeleteResolveNode(JSGlobalData*, const Identifier&, unsigned divot, unsigned startOffset, unsigned endOffset);
+ DeleteResolveNode(const JSTokenLocation&, const Identifier&, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart);
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
class DeleteBracketNode : public ExpressionNode, public ThrowableExpressionData {
public:
- DeleteBracketNode(JSGlobalData*, ExpressionNode* base, ExpressionNode* subscript, unsigned divot, unsigned startOffset, unsigned endOffset);
+ DeleteBracketNode(const JSTokenLocation&, ExpressionNode* base, ExpressionNode* subscript, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart);
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
class DeleteDotNode : public ExpressionNode, public ThrowableExpressionData {
public:
- DeleteDotNode(JSGlobalData*, ExpressionNode* base, const Identifier&, unsigned divot, unsigned startOffset, unsigned endOffset);
+ DeleteDotNode(const JSTokenLocation&, ExpressionNode* base, const Identifier&, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart);
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
class DeleteValueNode : public ExpressionNode {
public:
- DeleteValueNode(JSGlobalData*, ExpressionNode*);
+ DeleteValueNode(const JSTokenLocation&, ExpressionNode*);
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
class VoidNode : public ExpressionNode {
public:
- VoidNode(JSGlobalData*, ExpressionNode*);
+ VoidNode(const JSTokenLocation&, ExpressionNode*);
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
class TypeOfResolveNode : public ExpressionNode {
public:
- TypeOfResolveNode(JSGlobalData*, const Identifier&);
+ TypeOfResolveNode(const JSTokenLocation&, const Identifier&);
const Identifier& identifier() const { return m_ident; }
class TypeOfValueNode : public ExpressionNode {
public:
- TypeOfValueNode(JSGlobalData*, ExpressionNode*);
+ TypeOfValueNode(const JSTokenLocation&, ExpressionNode*);
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
ExpressionNode* m_expr;
};
- class PrefixResolveNode : public PrePostResolveNode {
- public:
- PrefixResolveNode(JSGlobalData*, const Identifier&, Operator, unsigned divot, unsigned startOffset, unsigned endOffset);
-
- private:
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
-
- Operator m_operator;
- };
-
- class PrefixBracketNode : public ExpressionNode, public ThrowablePrefixedSubExpressionData {
- public:
- PrefixBracketNode(JSGlobalData*, ExpressionNode* base, ExpressionNode* subscript, Operator, unsigned divot, unsigned startOffset, unsigned endOffset);
-
- private:
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
-
- ExpressionNode* m_base;
- ExpressionNode* m_subscript;
- Operator m_operator;
- };
-
- class PrefixDotNode : public ExpressionNode, public ThrowablePrefixedSubExpressionData {
+ class PrefixNode : public ExpressionNode, public ThrowablePrefixedSubExpressionData {
public:
- PrefixDotNode(JSGlobalData*, ExpressionNode* base, const Identifier&, Operator, unsigned divot, unsigned startOffset, unsigned endOffset);
+ PrefixNode(const JSTokenLocation&, ExpressionNode*, Operator, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart);
- private:
+ protected:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+ virtual RegisterID* emitResolve(BytecodeGenerator&, RegisterID* = 0);
+ virtual RegisterID* emitBracket(BytecodeGenerator&, RegisterID* = 0);
+ virtual RegisterID* emitDot(BytecodeGenerator&, RegisterID* = 0);
- ExpressionNode* m_base;
- const Identifier& m_ident;
+ ExpressionNode* m_expr;
Operator m_operator;
};
- class PrefixErrorNode : public ExpressionNode, public ThrowableExpressionData {
+ class PostfixNode : public PrefixNode {
public:
- PrefixErrorNode(JSGlobalData*, ExpressionNode*, Operator, unsigned divot, unsigned startOffset, unsigned endOffset);
+ PostfixNode(const JSTokenLocation&, ExpressionNode*, Operator, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart);
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
-
- ExpressionNode* m_expr;
- Operator m_operator;
+ virtual RegisterID* emitResolve(BytecodeGenerator&, RegisterID* = 0);
+ virtual RegisterID* emitBracket(BytecodeGenerator&, RegisterID* = 0);
+ virtual RegisterID* emitDot(BytecodeGenerator&, RegisterID* = 0);
};
class UnaryOpNode : public ExpressionNode {
public:
- UnaryOpNode(JSGlobalData*, ResultType, ExpressionNode*, OpcodeID);
+ UnaryOpNode(const JSTokenLocation&, ResultType, ExpressionNode*, OpcodeID);
protected:
ExpressionNode* expr() { return m_expr; }
class UnaryPlusNode : public UnaryOpNode {
public:
- UnaryPlusNode(JSGlobalData*, ExpressionNode*);
+ UnaryPlusNode(const JSTokenLocation&, ExpressionNode*);
private:
virtual ExpressionNode* stripUnaryPlus() { return expr(); }
class NegateNode : public UnaryOpNode {
public:
- NegateNode(JSGlobalData*, ExpressionNode*);
+ NegateNode(const JSTokenLocation&, ExpressionNode*);
};
- class BitwiseNotNode : public UnaryOpNode {
+ class BitwiseNotNode : public ExpressionNode {
public:
- BitwiseNotNode(JSGlobalData*, ExpressionNode*);
- };
+ BitwiseNotNode(const JSTokenLocation&, ExpressionNode*);
+ protected:
+ ExpressionNode* expr() { return m_expr; }
+ const ExpressionNode* expr() const { return m_expr; }
+
+ private:
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+
+ ExpressionNode* m_expr;
+ };
+
class LogicalNotNode : public UnaryOpNode {
public:
- LogicalNotNode(JSGlobalData*, ExpressionNode*);
+ LogicalNotNode(const JSTokenLocation&, ExpressionNode*);
private:
- void emitBytecodeInConditionContext(BytecodeGenerator&, Label* trueTarget, Label* falseTarget, bool fallThroughMeansTrue);
- virtual bool hasConditionContextCodegen() const { return expr()->hasConditionContextCodegen(); }
+ void emitBytecodeInConditionContext(BytecodeGenerator&, Label* trueTarget, Label* falseTarget, FallThroughMode);
};
class BinaryOpNode : public ExpressionNode {
public:
- BinaryOpNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, OpcodeID, bool rightHasAssignments);
- BinaryOpNode(JSGlobalData*, ResultType, ExpressionNode* expr1, ExpressionNode* expr2, OpcodeID, bool rightHasAssignments);
+ BinaryOpNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, OpcodeID, bool rightHasAssignments);
+ BinaryOpNode(const JSTokenLocation&, ResultType, ExpressionNode* expr1, ExpressionNode* expr2, OpcodeID, bool rightHasAssignments);
RegisterID* emitStrcat(BytecodeGenerator& generator, RegisterID* destination, RegisterID* lhs = 0, ReadModifyResolveNode* emitExpressionInfoForMe = 0);
+ void emitBytecodeInConditionContext(BytecodeGenerator&, Label* trueTarget, Label* falseTarget, FallThroughMode);
ExpressionNode* lhs() { return m_expr1; };
ExpressionNode* rhs() { return m_expr2; };
private:
+ void tryFoldToBranch(BytecodeGenerator&, TriState& branchCondition, ExpressionNode*& branchExpression);
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
protected:
bool m_rightHasAssignments;
};
- class ReverseBinaryOpNode : public BinaryOpNode {
- public:
- ReverseBinaryOpNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, OpcodeID, bool rightHasAssignments);
- ReverseBinaryOpNode(JSGlobalData*, ResultType, ExpressionNode* expr1, ExpressionNode* expr2, OpcodeID, bool rightHasAssignments);
-
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
- };
-
class MultNode : public BinaryOpNode {
public:
- MultNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
+ MultNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
};
class DivNode : public BinaryOpNode {
public:
- DivNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
+ DivNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
};
class ModNode : public BinaryOpNode {
public:
- ModNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
+ ModNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
};
class AddNode : public BinaryOpNode {
public:
- AddNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
+ AddNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
virtual bool isAdd() const { return true; }
};
class SubNode : public BinaryOpNode {
public:
- SubNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
+ SubNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
virtual bool isSubtract() const { return true; }
};
class LeftShiftNode : public BinaryOpNode {
public:
- LeftShiftNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
+ LeftShiftNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
};
class RightShiftNode : public BinaryOpNode {
public:
- RightShiftNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
+ RightShiftNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
};
class UnsignedRightShiftNode : public BinaryOpNode {
public:
- UnsignedRightShiftNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
+ UnsignedRightShiftNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
};
class LessNode : public BinaryOpNode {
public:
- LessNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
+ LessNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
};
- class GreaterNode : public ReverseBinaryOpNode {
+ class GreaterNode : public BinaryOpNode {
public:
- GreaterNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
+ GreaterNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
};
class LessEqNode : public BinaryOpNode {
public:
- LessEqNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
+ LessEqNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
};
- class GreaterEqNode : public ReverseBinaryOpNode {
+ class GreaterEqNode : public BinaryOpNode {
public:
- GreaterEqNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
+ GreaterEqNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
};
class ThrowableBinaryOpNode : public BinaryOpNode, public ThrowableExpressionData {
public:
- ThrowableBinaryOpNode(JSGlobalData*, ResultType, ExpressionNode* expr1, ExpressionNode* expr2, OpcodeID, bool rightHasAssignments);
- ThrowableBinaryOpNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, OpcodeID, bool rightHasAssignments);
+ ThrowableBinaryOpNode(const JSTokenLocation&, ResultType, ExpressionNode* expr1, ExpressionNode* expr2, OpcodeID, bool rightHasAssignments);
+ ThrowableBinaryOpNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, OpcodeID, bool rightHasAssignments);
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
class InstanceOfNode : public ThrowableBinaryOpNode {
public:
- InstanceOfNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
+ InstanceOfNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
class InNode : public ThrowableBinaryOpNode {
public:
- InNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
+ InNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
};
class EqualNode : public BinaryOpNode {
public:
- EqualNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
+ EqualNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
class NotEqualNode : public BinaryOpNode {
public:
- NotEqualNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
+ NotEqualNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
};
class StrictEqualNode : public BinaryOpNode {
public:
- StrictEqualNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
+ StrictEqualNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
class NotStrictEqualNode : public BinaryOpNode {
public:
- NotStrictEqualNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
+ NotStrictEqualNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
};
class BitAndNode : public BinaryOpNode {
public:
- BitAndNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
+ BitAndNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
};
class BitOrNode : public BinaryOpNode {
public:
- BitOrNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
+ BitOrNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
};
class BitXOrNode : public BinaryOpNode {
public:
- BitXOrNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
+ BitXOrNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
};
// m_expr1 && m_expr2, m_expr1 || m_expr2
class LogicalOpNode : public ExpressionNode {
public:
- LogicalOpNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, LogicalOperator);
+ LogicalOpNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, LogicalOperator);
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
- void emitBytecodeInConditionContext(BytecodeGenerator&, Label* trueTarget, Label* falseTarget, bool fallThroughMeansTrue);
- virtual bool hasConditionContextCodegen() const { return true; }
+ void emitBytecodeInConditionContext(BytecodeGenerator&, Label* trueTarget, Label* falseTarget, FallThroughMode);
ExpressionNode* m_expr1;
ExpressionNode* m_expr2;
// The ternary operator, "m_logical ? m_expr1 : m_expr2"
class ConditionalNode : public ExpressionNode {
public:
- ConditionalNode(JSGlobalData*, ExpressionNode* logical, ExpressionNode* expr1, ExpressionNode* expr2);
+ ConditionalNode(const JSTokenLocation&, ExpressionNode* logical, ExpressionNode* expr1, ExpressionNode* expr2);
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
class ReadModifyResolveNode : public ExpressionNode, public ThrowableExpressionData {
public:
- ReadModifyResolveNode(JSGlobalData*, const Identifier&, Operator, ExpressionNode* right, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset);
+ ReadModifyResolveNode(const JSTokenLocation&, const Identifier&, Operator, ExpressionNode* right, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned line, unsigned lineStart);
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
const Identifier& m_ident;
ExpressionNode* m_right;
- size_t m_index; // Used by ReadModifyLocalVarNode.
Operator m_operator;
bool m_rightHasAssignments;
};
class AssignResolveNode : public ExpressionNode, public ThrowableExpressionData {
public:
- AssignResolveNode(JSGlobalData*, const Identifier&, ExpressionNode* right, bool rightHasAssignments);
+ AssignResolveNode(const JSTokenLocation&, const Identifier&, ExpressionNode* right);
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
const Identifier& m_ident;
ExpressionNode* m_right;
- size_t m_index; // Used by ReadModifyLocalVarNode.
- bool m_rightHasAssignments;
};
class ReadModifyBracketNode : public ExpressionNode, public ThrowableSubExpressionData {
public:
- ReadModifyBracketNode(JSGlobalData*, ExpressionNode* base, ExpressionNode* subscript, Operator, ExpressionNode* right, bool subscriptHasAssignments, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset);
+ ReadModifyBracketNode(const JSTokenLocation&, ExpressionNode* base, ExpressionNode* subscript, Operator, ExpressionNode* right, bool subscriptHasAssignments, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart);
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
class AssignBracketNode : public ExpressionNode, public ThrowableExpressionData {
public:
- AssignBracketNode(JSGlobalData*, ExpressionNode* base, ExpressionNode* subscript, ExpressionNode* right, bool subscriptHasAssignments, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset);
+ AssignBracketNode(const JSTokenLocation&, ExpressionNode* base, ExpressionNode* subscript, ExpressionNode* right, bool subscriptHasAssignments, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart);
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
class AssignDotNode : public ExpressionNode, public ThrowableExpressionData {
public:
- AssignDotNode(JSGlobalData*, ExpressionNode* base, const Identifier&, ExpressionNode* right, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset);
+ AssignDotNode(const JSTokenLocation&, ExpressionNode* base, const Identifier&, ExpressionNode* right, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart);
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
class ReadModifyDotNode : public ExpressionNode, public ThrowableSubExpressionData {
public:
- ReadModifyDotNode(JSGlobalData*, ExpressionNode* base, const Identifier&, Operator, ExpressionNode* right, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset);
+ ReadModifyDotNode(const JSTokenLocation&, ExpressionNode* base, const Identifier&, Operator, ExpressionNode* right, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart);
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
class AssignErrorNode : public ExpressionNode, public ThrowableExpressionData {
public:
- AssignErrorNode(JSGlobalData*, ExpressionNode* left, Operator, ExpressionNode* right, unsigned divot, unsigned startOffset, unsigned endOffset);
+ AssignErrorNode(const JSTokenLocation&, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart);
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
-
- ExpressionNode* m_left;
- Operator m_operator;
- ExpressionNode* m_right;
};
typedef Vector<ExpressionNode*, 8> ExpressionVector;
class CommaNode : public ExpressionNode, public ParserArenaDeletable {
public:
- CommaNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2);
+ CommaNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2);
using ParserArenaDeletable::operator new;
class ConstDeclNode : public ExpressionNode {
public:
- ConstDeclNode(JSGlobalData*, const Identifier&, ExpressionNode*);
+ ConstDeclNode(const JSTokenLocation&, const Identifier&, ExpressionNode*);
bool hasInitializer() const { return m_init; }
const Identifier& ident() { return m_ident; }
class ConstStatementNode : public StatementNode {
public:
- ConstStatementNode(JSGlobalData*, ConstDeclNode* next);
+ ConstStatementNode(const JSTokenLocation&, ConstDeclNode* next);
private:
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+ virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
ConstDeclNode* m_next;
};
class SourceElements : public ParserArenaDeletable {
public:
- SourceElements(JSGlobalData*);
+ SourceElements();
void append(StatementNode*);
class BlockNode : public StatementNode {
public:
- BlockNode(JSGlobalData*, SourceElements* = 0);
+ BlockNode(const JSTokenLocation&, SourceElements* = 0);
StatementNode* singleStatement() const;
StatementNode* lastStatement() const;
private:
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+ virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
virtual bool isBlock() const { return true; }
class EmptyStatementNode : public StatementNode {
public:
- EmptyStatementNode(JSGlobalData*);
+ EmptyStatementNode(const JSTokenLocation&);
private:
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+ virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
virtual bool isEmptyStatement() const { return true; }
};
class DebuggerStatementNode : public StatementNode {
public:
- DebuggerStatementNode(JSGlobalData*);
+ DebuggerStatementNode(const JSTokenLocation&);
private:
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+ virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
};
class ExprStatementNode : public StatementNode {
public:
- ExprStatementNode(JSGlobalData*, ExpressionNode*);
+ ExprStatementNode(const JSTokenLocation&, ExpressionNode*);
ExpressionNode* expr() const { return m_expr; }
private:
virtual bool isExprStatement() const { return true; }
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+ virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
ExpressionNode* m_expr;
};
class VarStatementNode : public StatementNode {
public:
- VarStatementNode(JSGlobalData*, ExpressionNode*);
-
+ VarStatementNode(const JSTokenLocation&, ExpressionNode*);
private:
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+ virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
ExpressionNode* m_expr;
};
- class IfNode : public StatementNode {
+ class IfElseNode : public StatementNode {
public:
- IfNode(JSGlobalData*, ExpressionNode* condition, StatementNode* ifBlock);
+ IfElseNode(const JSTokenLocation&, ExpressionNode* condition, StatementNode* ifBlock, StatementNode* elseBlock);
- protected:
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+ private:
+ virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+ bool tryFoldBreakAndContinue(BytecodeGenerator&, StatementNode* ifBlock,
+ Label*& trueTarget, FallThroughMode&);
ExpressionNode* m_condition;
StatementNode* m_ifBlock;
- };
-
- class IfElseNode : public IfNode {
- public:
- IfElseNode(JSGlobalData*, ExpressionNode* condition, StatementNode* ifBlock, StatementNode* elseBlock);
-
- private:
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
-
StatementNode* m_elseBlock;
};
class DoWhileNode : public StatementNode {
public:
- DoWhileNode(JSGlobalData*, StatementNode* statement, ExpressionNode*);
+ DoWhileNode(const JSTokenLocation&, StatementNode*, ExpressionNode*);
private:
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+ virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
StatementNode* m_statement;
ExpressionNode* m_expr;
class WhileNode : public StatementNode {
public:
- WhileNode(JSGlobalData*, ExpressionNode*, StatementNode* statement);
+ WhileNode(const JSTokenLocation&, ExpressionNode*, StatementNode*);
private:
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+ virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
ExpressionNode* m_expr;
StatementNode* m_statement;
class ForNode : public StatementNode {
public:
- ForNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, ExpressionNode* expr3, StatementNode* statement, bool expr1WasVarDecl);
+ ForNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, ExpressionNode* expr3, StatementNode*);
private:
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+ virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
ExpressionNode* m_expr1;
ExpressionNode* m_expr2;
ExpressionNode* m_expr3;
StatementNode* m_statement;
- bool m_expr1WasVarDecl;
};
class ForInNode : public StatementNode, public ThrowableExpressionData {
public:
- ForInNode(JSGlobalData*, ExpressionNode*, ExpressionNode*, StatementNode*);
- ForInNode(JSGlobalData*, const Identifier&, ExpressionNode*, ExpressionNode*, StatementNode*, int divot, int startOffset, int endOffset);
+ ForInNode(const JSTokenLocation&, ExpressionNode*, ExpressionNode*, StatementNode*);
+ ForInNode(VM*, const JSTokenLocation&, const Identifier&, ExpressionNode*, ExpressionNode*, StatementNode*, unsigned divot, int startOffset, int endOffset, unsigned divotLine, unsigned divotLineStart);
private:
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+ virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
- const Identifier& m_ident;
ExpressionNode* m_init;
ExpressionNode* m_lexpr;
ExpressionNode* m_expr;
StatementNode* m_statement;
- bool m_identIsVarDecl;
};
class ContinueNode : public StatementNode, public ThrowableExpressionData {
public:
- ContinueNode(JSGlobalData*);
- ContinueNode(JSGlobalData*, const Identifier&);
+ ContinueNode(VM*, const JSTokenLocation&);
+ ContinueNode(const JSTokenLocation&, const Identifier&);
+ Label* trivialTarget(BytecodeGenerator&);
private:
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+ virtual bool isContinue() const { return true; }
+ virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
const Identifier& m_ident;
};
class BreakNode : public StatementNode, public ThrowableExpressionData {
public:
- BreakNode(JSGlobalData*);
- BreakNode(JSGlobalData*, const Identifier&);
+ BreakNode(VM*, const JSTokenLocation&);
+ BreakNode(const JSTokenLocation&, const Identifier&);
+ Label* trivialTarget(BytecodeGenerator&);
private:
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+ virtual bool isBreak() const { return true; }
+ virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
const Identifier& m_ident;
};
class ReturnNode : public StatementNode, public ThrowableExpressionData {
public:
- ReturnNode(JSGlobalData*, ExpressionNode* value);
+ ReturnNode(const JSTokenLocation&, ExpressionNode* value);
ExpressionNode* value() { return m_value; }
private:
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+ virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
virtual bool isReturnNode() const { return true; }
class WithNode : public StatementNode {
public:
- WithNode(JSGlobalData*, ExpressionNode*, StatementNode*, uint32_t divot, uint32_t expressionLength);
+ WithNode(const JSTokenLocation&, ExpressionNode*, StatementNode*, uint32_t divot, unsigned divotLine, unsigned divotLineStart, uint32_t expressionLength);
private:
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+ virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
ExpressionNode* m_expr;
StatementNode* m_statement;
uint32_t m_divot;
+ uint32_t m_divotLine;
+ uint32_t m_divotLineStart;
uint32_t m_expressionLength;
};
class LabelNode : public StatementNode, public ThrowableExpressionData {
public:
- LabelNode(JSGlobalData*, const Identifier& name, StatementNode*);
+ LabelNode(const JSTokenLocation&, const Identifier& name, StatementNode*);
private:
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+ virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
const Identifier& m_name;
StatementNode* m_statement;
class ThrowNode : public StatementNode, public ThrowableExpressionData {
public:
- ThrowNode(JSGlobalData*, ExpressionNode*);
+ ThrowNode(const JSTokenLocation&, ExpressionNode*);
private:
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+ virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
ExpressionNode* m_expr;
};
class TryNode : public StatementNode {
public:
- TryNode(JSGlobalData*, StatementNode* tryBlock, const Identifier& exceptionIdent, bool catchHasEval, StatementNode* catchBlock, StatementNode* finallyBlock);
+ TryNode(const JSTokenLocation&, StatementNode* tryBlock, const Identifier& exceptionIdent, StatementNode* catchBlock, StatementNode* finallyBlock);
private:
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+ virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
StatementNode* m_tryBlock;
const Identifier& m_exceptionIdent;
StatementNode* m_catchBlock;
StatementNode* m_finallyBlock;
- bool m_catchHasEval;
};
class ParameterNode : public ParserArenaFreeable {
public:
- ParameterNode(JSGlobalData*, const Identifier&);
- ParameterNode(JSGlobalData*, ParameterNode*, const Identifier&);
+ ParameterNode(const Identifier&);
+ ParameterNode(ParameterNode*, const Identifier&);
const Identifier& ident() const { return m_ident; }
ParameterNode* nextParam() const { return m_next; }
ParameterNode* m_next;
};
- struct ScopeNodeData {
- WTF_MAKE_FAST_ALLOCATED;
- public:
- typedef DeclarationStacks::VarStack VarStack;
- typedef DeclarationStacks::FunctionStack FunctionStack;
-
- ScopeNodeData(ParserArena&, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, int numConstants);
-
- ParserArena m_arena;
- VarStack m_varStack;
- FunctionStack m_functionStack;
- int m_numConstants;
- SourceElements* m_statements;
- IdentifierSet m_capturedVariables;
- };
-
class ScopeNode : public StatementNode, public ParserArenaRefCounted {
public:
typedef DeclarationStacks::VarStack VarStack;
typedef DeclarationStacks::FunctionStack FunctionStack;
- ScopeNode(JSGlobalData*, bool inStrictContext);
- ScopeNode(JSGlobalData*, const SourceCode&, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, CodeFeatures, int numConstants);
+ ScopeNode(VM*, const JSTokenLocation& start, const JSTokenLocation& end, bool inStrictContext);
+ ScopeNode(VM*, const JSTokenLocation& start, const JSTokenLocation& end, const SourceCode&, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, CodeFeatures, int numConstants);
using ParserArenaRefCounted::operator new;
- ScopeNodeData* data() const { return m_data.get(); }
- void destroyData() { m_data.clear(); }
+ void destroyData()
+ {
+ m_arena.reset();
+ m_varStack.clear();
+ m_functionStack.clear();
+ m_statements = 0;
+ m_capturedVariables.clear();
+ }
const SourceCode& source() const { return m_source; }
- const UString& sourceURL() const { return m_source.provider()->url(); }
- intptr_t sourceID() const { return m_source.provider()->asID(); }
+ const String& sourceURL() const { return m_source.provider()->url(); }
+ intptr_t sourceID() const { return m_source.providerID(); }
+
+ int startLine() const { return m_startLineNumber; }
+ int startStartOffset() const { return m_startStartOffset; }
+ int startLineStartOffset() const { return m_startLineStartOffset; }
void setFeatures(CodeFeatures features) { m_features = features; }
CodeFeatures features() { return m_features; }
bool isStrictMode() const { return m_features & StrictModeFeature; }
void setUsesArguments() { m_features |= ArgumentsFeature; }
bool usesThis() const { return m_features & ThisFeature; }
- bool needsActivationForMoreThanVariables() const { ASSERT(m_data); return m_features & (EvalFeature | WithFeature | CatchFeature); }
- bool needsActivation() const { ASSERT(m_data); return (hasCapturedVariables()) || (m_features & (EvalFeature | WithFeature | CatchFeature)); }
- bool hasCapturedVariables() const { return !!m_data->m_capturedVariables.size(); }
- size_t capturedVariableCount() const { return m_data->m_capturedVariables.size(); }
- bool captures(const Identifier& ident) { return m_data->m_capturedVariables.contains(ident.impl()); }
+ bool needsActivationForMoreThanVariables() const { return m_features & (EvalFeature | WithFeature | CatchFeature); }
+ bool needsActivation() const { return (hasCapturedVariables()) || (m_features & (EvalFeature | WithFeature | CatchFeature)); }
+ bool hasCapturedVariables() const { return !!m_capturedVariables.size(); }
+ size_t capturedVariableCount() const { return m_capturedVariables.size(); }
+ bool captures(const Identifier& ident) { return m_capturedVariables.contains(ident.impl()); }
- VarStack& varStack() { ASSERT(m_data); return m_data->m_varStack; }
- FunctionStack& functionStack() { ASSERT(m_data); return m_data->m_functionStack; }
+ VarStack& varStack() { return m_varStack; }
+ FunctionStack& functionStack() { return m_functionStack; }
int neededConstants()
{
- ASSERT(m_data);
// We may need 2 more constants than the count given by the parser,
// because of the various uses of jsUndefined() and jsNull().
- return m_data->m_numConstants + 2;
+ return m_numConstants + 2;
}
StatementNode* singleStatement() const;
protected:
void setSource(const SourceCode& source) { m_source = source; }
+ ParserArena m_arena;
+
+ int m_startLineNumber;
+ unsigned m_startStartOffset;
+ unsigned m_startLineStartOffset;
private:
- OwnPtr<ScopeNodeData> m_data;
CodeFeatures m_features;
SourceCode m_source;
+ VarStack m_varStack;
+ FunctionStack m_functionStack;
+ int m_numConstants;
+ SourceElements* m_statements;
+ IdentifierSet m_capturedVariables;
};
class ProgramNode : public ScopeNode {
public:
static const bool isFunctionNode = false;
- static PassRefPtr<ProgramNode> create(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
+ static PassRefPtr<ProgramNode> create(VM*, const JSTokenLocation& start, const JSTokenLocation& end, unsigned startColumn, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
+
+ unsigned startColumn() { return m_startColumn; }
static const bool scopeIsFunction = false;
private:
- ProgramNode(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
+ ProgramNode(VM*, const JSTokenLocation& start, const JSTokenLocation& end, unsigned startColumn, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+ virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+
+ unsigned m_startColumn;
};
class EvalNode : public ScopeNode {
public:
static const bool isFunctionNode = false;
- static PassRefPtr<EvalNode> create(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
+ static PassRefPtr<EvalNode> create(VM*, const JSTokenLocation& start, const JSTokenLocation& end, unsigned, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
+
+ unsigned startColumn() { return 1; }
static const bool scopeIsFunction = false;
private:
- EvalNode(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
+ EvalNode(VM*, const JSTokenLocation& start, const JSTokenLocation& end, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+ virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
};
- class FunctionParameters : public Vector<Identifier>, public RefCounted<FunctionParameters> {
+ class FunctionParameters : public RefCounted<FunctionParameters> {
WTF_MAKE_FAST_ALLOCATED;
public:
- static PassRefPtr<FunctionParameters> create(ParameterNode* firstParameter) { return adoptRef(new FunctionParameters(firstParameter)); }
+ static PassRefPtr<FunctionParameters> create(ParameterNode*);
+ ~FunctionParameters();
+
+ unsigned size() const { return m_size; }
+ const Identifier& at(unsigned index) const { ASSERT(index < m_size); return identifiers()[index]; }
private:
- FunctionParameters(ParameterNode*);
+ FunctionParameters(ParameterNode*, unsigned size);
+
+ Identifier* identifiers() { return reinterpret_cast<Identifier*>(&m_storage); }
+ const Identifier* identifiers() const { return reinterpret_cast<const Identifier*>(&m_storage); }
+
+ unsigned m_size;
+ void* m_storage;
};
class FunctionBodyNode : public ScopeNode {
public:
static const bool isFunctionNode = true;
- static FunctionBodyNode* create(JSGlobalData*, bool isStrictMode);
- static PassRefPtr<FunctionBodyNode> create(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
+ static FunctionBodyNode* create(VM*, const JSTokenLocation& start, const JSTokenLocation& end, unsigned startColumn, bool isStrictMode);
+ static PassRefPtr<FunctionBodyNode> create(VM*, const JSTokenLocation& start, const JSTokenLocation& end, unsigned startColumn, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
FunctionParameters* parameters() const { return m_parameters.get(); }
size_t parameterCount() const { return m_parameters->size(); }
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+ virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
- void finishParsing(const SourceCode&, ParameterNode*, const Identifier&);
- void finishParsing(PassRefPtr<FunctionParameters>, const Identifier&);
+ void finishParsing(const SourceCode&, ParameterNode*, const Identifier&, FunctionNameIsInScopeToggle);
+ void finishParsing(PassRefPtr<FunctionParameters>, const Identifier&, FunctionNameIsInScopeToggle);
const Identifier& ident() { return m_ident; }
+ void setInferredName(const Identifier& inferredName) { ASSERT(!inferredName.isNull()); m_inferredName = inferredName; }
+ const Identifier& inferredName() { return m_inferredName.isEmpty() ? m_ident : m_inferredName; }
+
+ bool functionNameIsInScope() { return m_functionNameIsInScopeToggle == FunctionNameIsInScope; }
+ FunctionNameIsInScopeToggle functionNameIsInScopeToggle() { return m_functionNameIsInScopeToggle; }
+
+ void setFunctionStart(int functionStart) { m_functionStart = functionStart; }
+ int functionStart() const { return m_functionStart; }
+ unsigned startColumn() const { return m_startColumn; }
static const bool scopeIsFunction = true;
private:
- FunctionBodyNode(JSGlobalData*, bool inStrictContext);
- FunctionBodyNode(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
+ FunctionBodyNode(VM*, const JSTokenLocation& start, const JSTokenLocation& end, unsigned startColumn, bool inStrictContext);
+ FunctionBodyNode(VM*, const JSTokenLocation& start, const JSTokenLocation& end, unsigned startColumn, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
Identifier m_ident;
+ Identifier m_inferredName;
+ FunctionNameIsInScopeToggle m_functionNameIsInScopeToggle;
RefPtr<FunctionParameters> m_parameters;
+ int m_functionStart;
+ unsigned m_startColumn;
};
class FuncExprNode : public ExpressionNode {
public:
- FuncExprNode(JSGlobalData*, const Identifier&, FunctionBodyNode* body, const SourceCode& source, ParameterNode* parameter = 0);
+ FuncExprNode(const JSTokenLocation&, const Identifier&, FunctionBodyNode*, const SourceCode&, ParameterNode* = 0);
FunctionBodyNode* body() { return m_body; }
class FuncDeclNode : public StatementNode {
public:
- FuncDeclNode(JSGlobalData*, const Identifier&, FunctionBodyNode*, const SourceCode&, ParameterNode* = 0);
+ FuncDeclNode(const JSTokenLocation&, const Identifier&, FunctionBodyNode*, const SourceCode&, ParameterNode* = 0);
FunctionBodyNode* body() { return m_body; }
private:
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+ virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
FunctionBodyNode* m_body;
};
class CaseClauseNode : public ParserArenaFreeable {
public:
- CaseClauseNode(JSGlobalData*, ExpressionNode*, SourceElements* = 0);
+ CaseClauseNode(ExpressionNode*, SourceElements* = 0);
ExpressionNode* expr() const { return m_expr; }
class ClauseListNode : public ParserArenaFreeable {
public:
- ClauseListNode(JSGlobalData*, CaseClauseNode*);
- ClauseListNode(JSGlobalData*, ClauseListNode*, CaseClauseNode*);
+ ClauseListNode(CaseClauseNode*);
+ ClauseListNode(ClauseListNode*, CaseClauseNode*);
CaseClauseNode* getClause() const { return m_clause; }
ClauseListNode* getNext() const { return m_next; }
class CaseBlockNode : public ParserArenaFreeable {
public:
- CaseBlockNode(JSGlobalData*, ClauseListNode* list1, CaseClauseNode* defaultClause, ClauseListNode* list2);
+ CaseBlockNode(ClauseListNode* list1, CaseClauseNode* defaultClause, ClauseListNode* list2);
- RegisterID* emitBytecodeForBlock(BytecodeGenerator&, RegisterID* input, RegisterID* destination);
+ void emitBytecodeForBlock(BytecodeGenerator&, RegisterID* input, RegisterID* destination);
private:
- SwitchInfo::SwitchType tryOptimizedSwitch(Vector<ExpressionNode*, 8>& literalVector, int32_t& min_num, int32_t& max_num);
+ SwitchInfo::SwitchType tryTableSwitch(Vector<ExpressionNode*, 8>& literalVector, int32_t& min_num, int32_t& max_num);
+ static const size_t s_tableSwitchMinimum = 10;
ClauseListNode* m_list1;
CaseClauseNode* m_defaultClause;
ClauseListNode* m_list2;
class SwitchNode : public StatementNode {
public:
- SwitchNode(JSGlobalData*, ExpressionNode*, CaseBlockNode*);
+ SwitchNode(const JSTokenLocation&, ExpressionNode*, CaseBlockNode*);
private:
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+ virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
ExpressionNode* m_expr;
CaseBlockNode* m_block;