/*
* 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, 2015 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>
*
*/
-#ifndef NODES_H_
-#define NODES_H_
+#ifndef Nodes_h
+#define Nodes_h
#include "Error.h"
+#include "JITCode.h"
#include "Opcode.h"
+#include "ParserArena.h"
+#include "ParserTokens.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
-#endif
namespace JSC {
- class CodeBlock;
+ class ArgumentListNode;
class BytecodeGenerator;
- class FuncDeclNode;
- class EvalCodeBlock;
- class JSFunction;
- class NodeReleaser;
- class ProgramCodeBlock;
+ class FunctionBodyNode;
+ class Label;
class PropertyListNode;
+ class ReadModifyResolveNode;
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;
+ class JSScope;
+ class ScopeNode;
enum Operator {
OpEqual,
OpLogicalOr
};
+ enum FallThroughMode {
+ FallThroughMeansTrue = 0,
+ FallThroughMeansFalse = 1
+ };
+ inline FallThroughMode invert(FallThroughMode fallThroughMode) { return static_cast<FallThroughMode>(!fallThroughMode); }
+
+ typedef HashSet<RefPtr<UniquedStringImpl>, IdentifierRepHash> IdentifierSet;
+
namespace DeclarationStacks {
enum VarAttrs { IsConstant = 1, HasInitializer = 2 };
- typedef Vector<std::pair<Identifier, unsigned> > VarStack;
- typedef Vector<RefPtr<FuncDeclNode> > FunctionStack;
+ typedef Vector<std::pair<Identifier, unsigned>> VarStack;
+ typedef Vector<FunctionBodyNode*> FunctionStack;
}
struct SwitchInfo {
SwitchType switchType;
};
- class ParserRefCounted : Noncopyable {
- protected:
- ParserRefCounted(JSGlobalData*) JSC_FAST_CALL;
-
+ class ParserArenaFreeable {
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;
+ // 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, ParserArena&);
};
- class Node : public ParserRefCounted {
+ class ParserArenaDeletable {
public:
- Node(JSGlobalData*) JSC_FAST_CALL;
+ virtual ~ParserArenaDeletable() { }
+
+ // ParserArenaDeletable objects are deleted when the arena is deleted.
+ // Clients must not call delete directly on such objects.
+ void* operator new(size_t, ParserArena&);
+ };
- /*
- 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.
+ class ParserArenaRoot {
+ WTF_MAKE_FAST_ALLOCATED;
+ protected:
+ ParserArenaRoot(ParserArena&);
- dst provides for a crude form of copy propagation. For example,
+ public:
+ ParserArena& parserArena() { return m_arena; }
+ virtual ~ParserArenaRoot() { }
- x = 1
+ protected:
+ ParserArena m_arena;
+ };
- becomes
-
- load r[x], 1
-
- instead of
+ class Node : public ParserArenaFreeable {
+ protected:
+ Node(const JSTokenLocation&);
- 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;
+ public:
+ virtual ~Node() { }
- int lineNo() const { return m_line; }
+ int firstLine() const { return m_position.line; }
+ int startOffset() const { return m_position.offset; }
+ int endOffset() const { return m_endOffset; }
+ int lineStartOffset() const { return m_position.lineStartOffset; }
+ const JSTextPosition& position() const { return m_position; }
+ void setEndOffset(int offset) { m_endOffset = offset; }
+ void setStartOffset(int offset) { m_position.offset = offset; }
protected:
- int m_line;
+ JSTextPosition m_position;
+ int m_endOffset;
};
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; }
+ protected:
+ 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 isAssignmentLocation() const { return isLocation(); }
+ virtual bool isResolveNode() const { return false; }
+ virtual bool isBracketAccessorNode() const { return false; }
+ virtual bool isDotAccessorNode() const { return false; }
+ virtual bool isDestructuringNode() const { return false; }
+ virtual bool isFuncExprNode() const { return false; }
+ virtual bool isCommaNode() const { return false; }
+ virtual bool isSimpleArray() const { return false; }
+ virtual bool isAdd() const { return false; }
+ virtual bool isSubtract() const { return false; }
+ virtual bool isBoolean() const { return false; }
+ virtual bool isSpreadExpression() const { return false; }
+ virtual bool isSuperNode() const { return false; }
+
+ virtual void emitBytecodeInConditionContext(BytecodeGenerator&, Label*, Label*, FallThroughMode);
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;
+ ResultType resultDescriptor() const { return m_resultType; }
private:
- ResultType m_resultDesc;
+ ResultType m_resultType;
};
class StatementNode : public Node {
+ protected:
+ StatementNode(const JSTokenLocation&);
+
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 void emitBytecode(BytecodeGenerator&, RegisterID* destination = 0) = 0;
- 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; }
+ void setLoc(unsigned firstLine, unsigned lastLine, int startOffset, int lineStartOffset);
+ unsigned lastLine() const { return m_lastLine; }
- virtual bool isBlock() const JSC_FAST_CALL { return false; }
- virtual bool isLoop() const JSC_FAST_CALL { return false; }
+ StatementNode* next() { return m_next; }
+ void setNext(StatementNode* next) { m_next = next; }
- private:
+ 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; }
+ virtual bool isFuncDeclNode() const { return false; }
+
+ protected:
+ StatementNode* m_next;
int m_lastLine;
};
- class NullNode : public ExpressionNode {
+ class ConstantNode : 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;
+ ConstantNode(const JSTokenLocation&, ResultType);
+ virtual bool isPure(BytecodeGenerator&) const override { return true; }
+ virtual bool isConstant() const override { return true; }
+ virtual JSValue jsValue(BytecodeGenerator&) const = 0;
+ private:
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+ virtual void emitBytecodeInConditionContext(BytecodeGenerator&, Label* trueTarget, Label* falseTarget, FallThroughMode) override;
};
- class BooleanNode : public ExpressionNode {
+ class NullNode : public ConstantNode {
public:
- BooleanNode(JSGlobalData* globalData, bool value) JSC_FAST_CALL
- : ExpressionNode(globalData, ResultType::booleanType())
- , m_value(value)
- {
- }
+ NullNode(const JSTokenLocation&);
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+ private:
+ virtual bool isNull() const override { return true; }
+ virtual JSValue jsValue(BytecodeGenerator&) const override { return jsNull(); }
+ };
- virtual bool isPure(BytecodeGenerator&) const JSC_FAST_CALL { return true; }
+ class BooleanNode : public ConstantNode {
+ public:
+ BooleanNode(const JSTokenLocation&, bool value);
+ bool value() { return m_value; }
private:
+ virtual bool isBoolean() const override { return true; }
+ virtual JSValue jsValue(BytecodeGenerator&) const override { return jsBoolean(m_value); }
+
bool m_value;
};
- class NumberNode : public ExpressionNode {
+ class NumberNode : public ConstantNode {
public:
- NumberNode(JSGlobalData* globalData, double v) JSC_FAST_CALL
- : ExpressionNode(globalData, ResultType::numberType())
- , m_double(v)
- {
- }
+ NumberNode(const JSTokenLocation&, double value);
+ double value() const { return m_value; }
+ virtual bool isIntegerNode() const = 0;
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override final;
+
+ private:
+ virtual bool isNumber() const override final { return true; }
+ virtual JSValue jsValue(BytecodeGenerator&) const override { return jsNumber(m_value); }
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+ double m_value;
+ };
- 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; }
+ class DoubleNode : public NumberNode {
+ public:
+ DoubleNode(const JSTokenLocation&, double value);
private:
- double m_double;
+ virtual bool isIntegerNode() const override { return false; }
};
- class StringNode : public ExpressionNode {
+ // An integer node represent a number represented as an integer (e.g. 42 instead of 42., 42.0, 42e0)
+ class IntegerNode : public DoubleNode {
public:
- StringNode(JSGlobalData* globalData, const Identifier& v) JSC_FAST_CALL
- : ExpressionNode(globalData, ResultType::stringType())
- , m_value(v)
- {
- }
+ IntegerNode(const JSTokenLocation&, double value);
+ virtual bool isIntegerNode() const override final { return true; }
+ };
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
-
- virtual bool isString() const JSC_FAST_CALL { return true; }
+ class StringNode : public ConstantNode {
+ public:
+ StringNode(const JSTokenLocation&, const Identifier&);
const Identifier& value() { return m_value; }
- virtual bool isPure(BytecodeGenerator&) const JSC_FAST_CALL { return true; }
private:
- Identifier m_value;
+ virtual bool isString() const override { return true; }
+ virtual JSValue jsValue(BytecodeGenerator&) const override;
+
+ const 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))
+ : m_divot(-1, -1, -1)
+ , m_divotStart(-1, -1, -1)
+ , m_divotEnd(-1, -1, -1)
{
}
- ThrowableExpressionData(unsigned divot, unsigned startOffset, unsigned endOffset)
+ ThrowableExpressionData(const JSTextPosition& divot, const JSTextPosition& start, const JSTextPosition& end)
: m_divot(divot)
- , m_startOffset(startOffset)
- , m_endOffset(endOffset)
+ , m_divotStart(start)
+ , m_divotEnd(end)
{
+ ASSERT(m_divot.offset >= m_divot.lineStartOffset);
+ ASSERT(m_divotStart.offset >= m_divotStart.lineStartOffset);
+ ASSERT(m_divotEnd.offset >= m_divotEnd.lineStartOffset);
}
-
- void setExceptionSourceCode(unsigned divot, unsigned startOffset, unsigned endOffset)
+
+ void setExceptionSourceCode(const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd)
{
+ ASSERT(divot.offset >= divot.lineStartOffset);
+ ASSERT(divotStart.offset >= divotStart.lineStartOffset);
+ ASSERT(divotEnd.offset >= divotEnd.lineStartOffset);
m_divot = divot;
- m_startOffset = startOffset;
- m_endOffset = endOffset;
+ m_divotStart = divotStart;
+ m_divotEnd = divotEnd;
}
- uint32_t divot() const { return m_divot; }
- uint16_t startOffset() const { return m_startOffset; }
- uint16_t endOffset() const { return m_endOffset; }
+ const JSTextPosition& divot() const { return m_divot; }
+ const JSTextPosition& divotStart() const { return m_divotStart; }
+ const JSTextPosition& divotEnd() const { return m_divotEnd; }
protected:
- RegisterID* emitThrowError(BytecodeGenerator&, ErrorType, const char* msg);
- RegisterID* emitThrowError(BytecodeGenerator&, ErrorType, const char* msg, const Identifier&);
+ RegisterID* emitThrowReferenceError(BytecodeGenerator&, const String& message);
private:
- uint32_t m_divot;
- uint16_t m_startOffset;
- uint16_t m_endOffset;
+ JSTextPosition m_divot;
+ JSTextPosition m_divotStart;
+ JSTextPosition m_divotEnd;
};
class ThrowableSubExpressionData : public ThrowableExpressionData {
public:
ThrowableSubExpressionData()
- : ThrowableExpressionData()
- , m_subexpressionDivotOffset(0)
+ : m_subexpressionDivotOffset(0)
, m_subexpressionEndOffset(0)
+ , m_subexpressionLineOffset(0)
+ , m_subexpressionLineStartOffset(0)
{
}
- ThrowableSubExpressionData(unsigned divot, unsigned startOffset, unsigned endOffset)
- : ThrowableExpressionData(divot, startOffset, endOffset)
+ ThrowableSubExpressionData(const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd)
+ : ThrowableExpressionData(divot, divotStart, divotEnd)
, m_subexpressionDivotOffset(0)
, m_subexpressionEndOffset(0)
+ , m_subexpressionLineOffset(0)
+ , m_subexpressionLineStartOffset(0)
{
}
- void setSubexpressionInfo(uint32_t subexpressionDivot, uint16_t subexpressionOffset)
+ void setSubexpressionInfo(const JSTextPosition& subexpressionDivot, int subexpressionOffset)
{
- ASSERT(subexpressionDivot <= divot());
- if ((divot() - subexpressionDivot) & ~0xFFFF) // Overflow means we can't do this safely, so just point at the primary divot
+ ASSERT(subexpressionDivot.offset <= divot().offset);
+ // Overflow means we can't do this safely, so just point at the primary divot,
+ // divotLine, or divotLineStart.
+ if ((divot() - subexpressionDivot.offset) & ~0xFFFF)
+ return;
+ if ((divot().line - subexpressionDivot.line) & ~0xFFFF)
+ return;
+ if ((divot().lineStartOffset - subexpressionDivot.lineStartOffset) & ~0xFFFF)
+ return;
+ if ((divotEnd() - subexpressionOffset) & ~0xFFFF)
return;
- m_subexpressionDivotOffset = divot() - subexpressionDivot;
- m_subexpressionEndOffset = subexpressionOffset;
+ m_subexpressionDivotOffset = divot() - subexpressionDivot.offset;
+ m_subexpressionEndOffset = divotEnd() - subexpressionOffset;
+ m_subexpressionLineOffset = divot().line - subexpressionDivot.line;
+ m_subexpressionLineStartOffset = divot().lineStartOffset - subexpressionDivot.lineStartOffset;
}
+ JSTextPosition subexpressionDivot()
+ {
+ int newLine = divot().line - m_subexpressionLineOffset;
+ int newOffset = divot().offset - m_subexpressionDivotOffset;
+ int newLineStartOffset = divot().lineStartOffset - m_subexpressionLineStartOffset;
+ return JSTextPosition(newLine, newOffset, newLineStartOffset);
+ }
+ JSTextPosition subexpressionStart() { return divotStart(); }
+ JSTextPosition subexpressionEnd() { return divotEnd() - static_cast<int>(m_subexpressionEndOffset); }
+
protected:
uint16_t m_subexpressionDivotOffset;
uint16_t m_subexpressionEndOffset;
+ uint16_t m_subexpressionLineOffset;
+ uint16_t m_subexpressionLineStartOffset;
};
class ThrowablePrefixedSubExpressionData : public ThrowableExpressionData {
public:
ThrowablePrefixedSubExpressionData()
- : ThrowableExpressionData()
- , m_subexpressionDivotOffset(0)
+ : m_subexpressionDivotOffset(0)
, m_subexpressionStartOffset(0)
+ , m_subexpressionLineOffset(0)
+ , m_subexpressionLineStartOffset(0)
{
}
- ThrowablePrefixedSubExpressionData(unsigned divot, unsigned startOffset, unsigned endOffset)
- : ThrowableExpressionData(divot, startOffset, endOffset)
+ ThrowablePrefixedSubExpressionData(const JSTextPosition& divot, const JSTextPosition& start, const JSTextPosition& end)
+ : ThrowableExpressionData(divot, start, end)
, m_subexpressionDivotOffset(0)
, m_subexpressionStartOffset(0)
+ , m_subexpressionLineOffset(0)
+ , m_subexpressionLineStartOffset(0)
{
}
- void setSubexpressionInfo(uint32_t subexpressionDivot, uint16_t subexpressionOffset)
+ void setSubexpressionInfo(const JSTextPosition& subexpressionDivot, int subexpressionOffset)
{
- ASSERT(subexpressionDivot >= divot());
- if ((subexpressionDivot - divot()) & ~0xFFFF) // Overflow means we can't do this safely, so just point at the primary divot
+ ASSERT(subexpressionDivot.offset >= divot().offset);
+ // Overflow means we can't do this safely, so just point at the primary divot,
+ // divotLine, or divotLineStart.
+ if ((subexpressionDivot.offset - divot()) & ~0xFFFF)
return;
- m_subexpressionDivotOffset = subexpressionDivot - divot();
- m_subexpressionStartOffset = subexpressionOffset;
+ if ((subexpressionDivot.line - divot().line) & ~0xFFFF)
+ return;
+ if ((subexpressionDivot.lineStartOffset - divot().lineStartOffset) & ~0xFFFF)
+ return;
+ if ((subexpressionOffset - divotStart()) & ~0xFFFF)
+ return;
+ m_subexpressionDivotOffset = subexpressionDivot.offset - divot();
+ m_subexpressionStartOffset = subexpressionOffset - divotStart();
+ m_subexpressionLineOffset = subexpressionDivot.line - divot().line;
+ m_subexpressionLineStartOffset = subexpressionDivot.lineStartOffset - divot().lineStartOffset;
+ }
+
+ JSTextPosition subexpressionDivot()
+ {
+ int newLine = divot().line + m_subexpressionLineOffset;
+ int newOffset = divot().offset + m_subexpressionDivotOffset;
+ int newLineStartOffset = divot().lineStartOffset + m_subexpressionLineStartOffset;
+ return JSTextPosition(newLine, newOffset, newLineStartOffset);
}
+ JSTextPosition subexpressionStart() { return divotStart() + static_cast<int>(m_subexpressionStartOffset); }
+ JSTextPosition subexpressionEnd() { return divotEnd(); }
protected:
uint16_t m_subexpressionDivotOffset;
uint16_t m_subexpressionStartOffset;
+ uint16_t m_subexpressionLineOffset;
+ uint16_t m_subexpressionLineStartOffset;
};
- class RegExpNode : public ExpressionNode, public ThrowableExpressionData {
+#if ENABLE(ES6_TEMPLATE_LITERAL_SYNTAX)
+ class TemplateExpressionListNode : public ParserArenaFreeable {
public:
- RegExpNode(JSGlobalData* globalData, const UString& pattern, const UString& flags) JSC_FAST_CALL
- : ExpressionNode(globalData)
- , m_pattern(pattern)
- , m_flags(flags)
- {
- }
+ TemplateExpressionListNode(ExpressionNode*);
+ TemplateExpressionListNode(TemplateExpressionListNode*, ExpressionNode*);
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+ ExpressionNode* value() { return m_node; }
+ TemplateExpressionListNode* next() { return m_next; }
private:
- UString m_pattern;
- UString m_flags;
+ TemplateExpressionListNode* m_next { nullptr };
+ ExpressionNode* m_node { nullptr };
};
- class ThisNode : public ExpressionNode {
+ class TemplateStringNode : public ExpressionNode {
public:
- ThisNode(JSGlobalData* globalData) JSC_FAST_CALL
- : ExpressionNode(globalData)
- {
- }
+ TemplateStringNode(const JSTokenLocation&, const Identifier& cooked, const Identifier& raw);
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+ const Identifier& cooked() { return m_cooked; }
+ const Identifier& raw() { return m_raw; }
+
+ private:
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+
+ const Identifier& m_cooked;
+ const Identifier& m_raw;
};
- class ResolveNode : public ExpressionNode {
+ class TemplateStringListNode : public ParserArenaFreeable {
public:
- ResolveNode(JSGlobalData* globalData, const Identifier& ident, int startOffset) JSC_FAST_CALL
- : ExpressionNode(globalData)
- , m_ident(ident)
- , m_startOffset(startOffset)
- {
- }
+ TemplateStringListNode(TemplateStringNode*);
+ TemplateStringListNode(TemplateStringListNode*, TemplateStringNode*);
+
+ TemplateStringNode* value() { return m_node; }
+ TemplateStringListNode* next() { return m_next; }
+
+ private:
+ TemplateStringListNode* m_next { nullptr };
+ TemplateStringNode* m_node { nullptr };
+ };
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+ class TemplateLiteralNode : public ExpressionNode {
+ public:
+ TemplateLiteralNode(const JSTokenLocation&, TemplateStringListNode*);
+ TemplateLiteralNode(const JSTokenLocation&, TemplateStringListNode*, TemplateExpressionListNode*);
- virtual bool isPure(BytecodeGenerator&) const JSC_FAST_CALL;
- virtual bool isLocation() const JSC_FAST_CALL { return true; }
- virtual bool isResolveNode() const JSC_FAST_CALL { return true; }
- const Identifier& identifier() const JSC_FAST_CALL { return m_ident; }
+ TemplateStringListNode* templateStrings() const { return m_templateStrings; }
+ TemplateExpressionListNode* templateExpressions() const { return m_templateExpressions; }
private:
- Identifier m_ident;
- int32_t m_startOffset;
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+
+ TemplateStringListNode* m_templateStrings;
+ TemplateExpressionListNode* m_templateExpressions;
};
- class ElementNode : public ParserRefCounted {
+ class TaggedTemplateNode : public ExpressionNode, public ThrowableExpressionData {
public:
- ElementNode(JSGlobalData* globalData, int elision, ExpressionNode* node) JSC_FAST_CALL
- : ParserRefCounted(globalData)
- , m_elision(elision)
- , m_node(node)
- {
- }
+ TaggedTemplateNode(const JSTokenLocation&, ExpressionNode*, TemplateLiteralNode*);
- ElementNode(JSGlobalData* globalData, ElementNode* l, int elision, ExpressionNode* node) JSC_FAST_CALL
- : ParserRefCounted(globalData)
- , m_elision(elision)
- , m_node(node)
- {
- l->m_next = this;
- }
+ TemplateLiteralNode* templateLiteral() const { return m_templateLiteral; }
- virtual ~ElementNode();
- virtual void releaseNodes(NodeReleaser&);
+ private:
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
- int elision() const { return m_elision; }
- ExpressionNode* value() { return m_node.get(); }
+ ExpressionNode* m_tag;
+ TemplateLiteralNode* m_templateLiteral;
+ };
+#endif
- ElementNode* next() { return m_next.get(); }
+ class RegExpNode : public ExpressionNode, public ThrowableExpressionData {
+ public:
+ RegExpNode(const JSTokenLocation&, const Identifier& pattern, const Identifier& flags);
private:
- RefPtr<ElementNode> m_next;
- int m_elision;
- RefPtr<ExpressionNode> m_node;
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+
+ const Identifier& m_pattern;
+ const Identifier& m_flags;
};
- class ArrayNode : public ExpressionNode {
+ class ThisNode : public ExpressionNode {
public:
- ArrayNode(JSGlobalData* globalData, int elision) JSC_FAST_CALL
- : ExpressionNode(globalData)
- , m_elision(elision)
- , m_optional(true)
- {
- }
+ ThisNode(const JSTokenLocation&, ThisTDZMode);
- ArrayNode(JSGlobalData* globalData, ElementNode* element) JSC_FAST_CALL
- : ExpressionNode(globalData)
- , m_element(element)
- , m_elision(0)
- , m_optional(false)
- {
- }
+ private:
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
- ArrayNode(JSGlobalData* globalData, int elision, ElementNode* element) JSC_FAST_CALL
- : ExpressionNode(globalData)
- , m_element(element)
- , m_elision(elision)
- , m_optional(true)
- {
- }
+ bool m_shouldAlwaysEmitTDZCheck;
+ };
+
+ class SuperNode final : public ExpressionNode {
+ public:
+ SuperNode(const JSTokenLocation&);
+
+ private:
+ virtual bool isSuperNode() const override { return true; }
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+ };
- virtual ~ArrayNode();
- virtual void releaseNodes(NodeReleaser&);
+ class ResolveNode : public ExpressionNode {
+ public:
+ ResolveNode(const JSTokenLocation&, const Identifier&, const JSTextPosition& start);
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+ const Identifier& identifier() const { return m_ident; }
private:
- RefPtr<ElementNode> m_element;
- int m_elision;
- bool m_optional;
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+
+ virtual bool isPure(BytecodeGenerator&) const override;
+ virtual bool isLocation() const override { return true; }
+ virtual bool isResolveNode() const override { return true; }
+
+ const Identifier& m_ident;
+ JSTextPosition m_start;
};
- class PropertyNode : public ParserRefCounted {
+ class ElementNode : public ParserArenaFreeable {
public:
- enum Type { Constant, Getter, Setter };
+ ElementNode(int elision, ExpressionNode*);
+ ElementNode(ElementNode*, int elision, ExpressionNode*);
- PropertyNode(JSGlobalData* globalData, const Identifier& name, ExpressionNode* assign, Type type) JSC_FAST_CALL
- : ParserRefCounted(globalData)
- , m_name(name)
- , m_assign(assign)
- , m_type(type)
- {
- }
+ int elision() const { return m_elision; }
+ ExpressionNode* value() { return m_node; }
+ ElementNode* next() { return m_next; }
+
+ private:
+ ElementNode* m_next;
+ int m_elision;
+ ExpressionNode* m_node;
+ };
- virtual ~PropertyNode();
- virtual void releaseNodes(NodeReleaser&);
+ class ArrayNode : public ExpressionNode {
+ public:
+ ArrayNode(const JSTokenLocation&, int elision);
+ ArrayNode(const JSTokenLocation&, ElementNode*);
+ ArrayNode(const JSTokenLocation&, int elision, ElementNode*);
- const Identifier& name() const { return m_name; }
+ ArgumentListNode* toArgumentList(ParserArena&, int, int) const;
+ ElementNode* elements() const { ASSERT(isSimpleArray()); return m_element; }
private:
- friend class PropertyListNode;
- Identifier m_name;
- RefPtr<ExpressionNode> m_assign;
- Type m_type;
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+
+ virtual bool isSimpleArray() const override;
+
+ ElementNode* m_element;
+ int m_elision;
+ bool m_optional;
};
- class PropertyListNode : public Node {
+ class PropertyNode : public ParserArenaFreeable {
public:
- PropertyListNode(JSGlobalData* globalData, PropertyNode* node) JSC_FAST_CALL
- : Node(globalData)
- , m_node(node)
- {
- }
+ enum Type { Constant = 1, Getter = 2, Setter = 4, Computed = 8, Shorthand = 16 };
+ enum PutType { Unknown, KnownDirect };
- PropertyListNode(JSGlobalData* globalData, PropertyNode* node, PropertyListNode* list) JSC_FAST_CALL
- : Node(globalData)
- , m_node(node)
- {
- list->m_next = this;
- }
+ PropertyNode(const Identifier&, ExpressionNode*, Type, PutType, SuperBinding);
+ PropertyNode(ExpressionNode* propertyName, ExpressionNode*, Type, PutType);
- virtual ~PropertyListNode();
- virtual void releaseNodes(NodeReleaser&);
+ ExpressionNode* expressionName() const { return m_expression; }
+ const Identifier* name() const { return m_name; }
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+ Type type() const { return static_cast<Type>(m_type); }
+ bool needsSuperBinding() const { return m_needsSuperBinding; }
+ PutType putType() const { return static_cast<PutType>(m_putType); }
private:
- RefPtr<PropertyNode> m_node;
- RefPtr<PropertyListNode> m_next;
+ friend class PropertyListNode;
+ const Identifier* m_name;
+ ExpressionNode* m_expression;
+ ExpressionNode* m_assign;
+ unsigned m_type : 5;
+ unsigned m_needsSuperBinding : 1;
+ unsigned m_putType : 1;
};
- class ObjectLiteralNode : public ExpressionNode {
+ class PropertyListNode : public ExpressionNode {
public:
- ObjectLiteralNode(JSGlobalData* globalData) JSC_FAST_CALL
- : ExpressionNode(globalData)
- {
- }
+ PropertyListNode(const JSTokenLocation&, PropertyNode*);
+ PropertyListNode(const JSTokenLocation&, PropertyNode*, PropertyListNode*);
- ObjectLiteralNode(JSGlobalData* globalData, PropertyListNode* list) JSC_FAST_CALL
- : ExpressionNode(globalData)
- , m_list(list)
- {
- }
+ private:
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+ void emitPutConstantProperty(BytecodeGenerator&, RegisterID*, PropertyNode&);
- virtual ~ObjectLiteralNode();
- virtual void releaseNodes(NodeReleaser&);
+ PropertyNode* m_node;
+ PropertyListNode* m_next;
+ };
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+ class ObjectLiteralNode : public ExpressionNode {
+ public:
+ ObjectLiteralNode(const JSTokenLocation&);
+ ObjectLiteralNode(const JSTokenLocation&, PropertyListNode*);
private:
- RefPtr<PropertyListNode> m_list;
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+
+ PropertyListNode* m_list;
};
class BracketAccessorNode : public ExpressionNode, public ThrowableExpressionData {
public:
- BracketAccessorNode(JSGlobalData* globalData, ExpressionNode* base, ExpressionNode* subscript, bool subscriptHasAssignments) JSC_FAST_CALL
- : ExpressionNode(globalData)
- , m_base(base)
- , m_subscript(subscript)
- , m_subscriptHasAssignments(subscriptHasAssignments)
- {
- }
-
- virtual ~BracketAccessorNode();
- virtual void releaseNodes(NodeReleaser&);
+ BracketAccessorNode(const JSTokenLocation&, ExpressionNode* base, ExpressionNode* subscript, bool subscriptHasAssignments);
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+ ExpressionNode* base() const { return m_base; }
+ ExpressionNode* subscript() const { return m_subscript; }
- virtual bool isLocation() const JSC_FAST_CALL { return true; }
- virtual bool isBracketAccessorNode() const JSC_FAST_CALL { return true; }
- ExpressionNode* base() JSC_FAST_CALL { return m_base.get(); }
- ExpressionNode* subscript() JSC_FAST_CALL { return m_subscript.get(); }
+ bool subscriptHasAssignments() const { return m_subscriptHasAssignments; }
private:
- RefPtr<ExpressionNode> m_base;
- RefPtr<ExpressionNode> m_subscript;
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+
+ virtual bool isLocation() const override { return true; }
+ virtual bool isBracketAccessorNode() const override { return true; }
+
+ ExpressionNode* m_base;
+ ExpressionNode* m_subscript;
bool m_subscriptHasAssignments;
};
class DotAccessorNode : public ExpressionNode, public ThrowableExpressionData {
public:
- DotAccessorNode(JSGlobalData* globalData, ExpressionNode* base, const Identifier& ident) JSC_FAST_CALL
- : ExpressionNode(globalData)
- , m_base(base)
- , m_ident(ident)
- {
- }
+ DotAccessorNode(const JSTokenLocation&, ExpressionNode* base, const Identifier&);
- virtual ~DotAccessorNode();
- virtual void releaseNodes(NodeReleaser&);
+ ExpressionNode* base() const { return m_base; }
+ const Identifier& identifier() const { return m_ident; }
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+ private:
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
- virtual bool isLocation() const JSC_FAST_CALL { return true; }
- virtual bool isDotAccessorNode() const JSC_FAST_CALL { return true; }
- ExpressionNode* base() const JSC_FAST_CALL { return m_base.get(); }
- const Identifier& identifier() const JSC_FAST_CALL { return m_ident; }
+ virtual bool isLocation() const override { return true; }
+ virtual bool isDotAccessorNode() const override { return true; }
- private:
- RefPtr<ExpressionNode> m_base;
- Identifier m_ident;
+ ExpressionNode* m_base;
+ const Identifier& m_ident;
};
- class ArgumentListNode : public Node {
+ class SpreadExpressionNode : public ExpressionNode, public ThrowableExpressionData {
public:
- ArgumentListNode(JSGlobalData* globalData, ExpressionNode* expr) JSC_FAST_CALL
- : Node(globalData)
- , m_expr(expr)
- {
- }
-
- ArgumentListNode(JSGlobalData* globalData, ArgumentListNode* listNode, ExpressionNode* expr) JSC_FAST_CALL
- : Node(globalData)
- , m_expr(expr)
- {
- listNode->m_next = this;
- }
+ SpreadExpressionNode(const JSTokenLocation&, ExpressionNode*);
+
+ ExpressionNode* expression() const { return m_expression; }
+
+ private:
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+
+ virtual bool isSpreadExpression() const override { return true; }
+ ExpressionNode* m_expression;
+ };
- virtual ~ArgumentListNode();
- virtual void releaseNodes(NodeReleaser&);
+ class ArgumentListNode : public ExpressionNode {
+ public:
+ ArgumentListNode(const JSTokenLocation&, ExpressionNode*);
+ ArgumentListNode(const JSTokenLocation&, ArgumentListNode*, ExpressionNode*);
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+ ArgumentListNode* m_next;
+ ExpressionNode* m_expr;
- RefPtr<ArgumentListNode> m_next;
- RefPtr<ExpressionNode> m_expr;
+ private:
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
};
- class ArgumentsNode : public ParserRefCounted {
+ class ArgumentsNode : public ParserArenaFreeable {
public:
- ArgumentsNode(JSGlobalData* globalData) JSC_FAST_CALL
- : ParserRefCounted(globalData)
- {
- }
-
- ArgumentsNode(JSGlobalData* globalData, ArgumentListNode* listNode) JSC_FAST_CALL
- : ParserRefCounted(globalData)
- , m_listNode(listNode)
- {
- }
+ ArgumentsNode();
+ ArgumentsNode(ArgumentListNode*);
- virtual ~ArgumentsNode();
- virtual void releaseNodes(NodeReleaser&);
-
- RefPtr<ArgumentListNode> m_listNode;
+ ArgumentListNode* m_listNode;
};
class NewExprNode : public ExpressionNode, public ThrowableExpressionData {
public:
- NewExprNode(JSGlobalData* globalData, ExpressionNode* expr) JSC_FAST_CALL
- : ExpressionNode(globalData)
- , m_expr(expr)
- {
- }
-
- NewExprNode(JSGlobalData* globalData, ExpressionNode* expr, ArgumentsNode* args) JSC_FAST_CALL
- : ExpressionNode(globalData)
- , m_expr(expr)
- , m_args(args)
- {
- }
-
- virtual ~NewExprNode();
- virtual void releaseNodes(NodeReleaser&);
-
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+ NewExprNode(const JSTokenLocation&, ExpressionNode*);
+ NewExprNode(const JSTokenLocation&, ExpressionNode*, ArgumentsNode*);
private:
- RefPtr<ExpressionNode> m_expr;
- RefPtr<ArgumentsNode> m_args;
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+
+ ExpressionNode* m_expr;
+ ArgumentsNode* m_args;
};
class EvalFunctionCallNode : public ExpressionNode, public ThrowableExpressionData {
public:
- EvalFunctionCallNode(JSGlobalData* globalData, ArgumentsNode* args, unsigned divot, unsigned startOffset, unsigned endOffset) JSC_FAST_CALL
- : ExpressionNode(globalData)
- , ThrowableExpressionData(divot, startOffset, endOffset)
- , m_args(args)
- {
- }
-
- virtual ~EvalFunctionCallNode();
- virtual void releaseNodes(NodeReleaser&);
-
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+ EvalFunctionCallNode(const JSTokenLocation&, ArgumentsNode*, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
private:
- RefPtr<ArgumentsNode> m_args;
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+
+ ArgumentsNode* m_args;
};
class FunctionCallValueNode : public ExpressionNode, public ThrowableExpressionData {
public:
- FunctionCallValueNode(JSGlobalData* globalData, ExpressionNode* expr, ArgumentsNode* args, unsigned divot, unsigned startOffset, unsigned endOffset) JSC_FAST_CALL
- : ExpressionNode(globalData)
- , ThrowableExpressionData(divot, startOffset, endOffset)
- , m_expr(expr)
- , m_args(args)
- {
- }
-
- virtual ~FunctionCallValueNode();
- virtual void releaseNodes(NodeReleaser&);
-
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+ FunctionCallValueNode(const JSTokenLocation&, ExpressionNode*, ArgumentsNode*, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
private:
- RefPtr<ExpressionNode> m_expr;
- RefPtr<ArgumentsNode> m_args;
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+
+ ExpressionNode* m_expr;
+ ArgumentsNode* m_args;
};
class FunctionCallResolveNode : public ExpressionNode, public ThrowableExpressionData {
public:
- FunctionCallResolveNode(JSGlobalData* globalData, const Identifier& ident, ArgumentsNode* args, unsigned divot, unsigned startOffset, unsigned endOffset) JSC_FAST_CALL
- : ExpressionNode(globalData)
- , ThrowableExpressionData(divot, startOffset, endOffset)
- , m_ident(ident)
- , m_args(args)
- {
- }
-
- virtual ~FunctionCallResolveNode();
- virtual void releaseNodes(NodeReleaser&);
-
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+ FunctionCallResolveNode(const JSTokenLocation&, const Identifier&, ArgumentsNode*, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
private:
- Identifier m_ident;
- RefPtr<ArgumentsNode> m_args;
- size_t m_index; // Used by LocalVarFunctionCallNode.
- size_t m_scopeDepth; // Used by ScopedVarFunctionCallNode and NonLocalVarFunctionCallNode
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+
+ const Identifier& m_ident;
+ ArgumentsNode* m_args;
};
class FunctionCallBracketNode : public ExpressionNode, public ThrowableSubExpressionData {
public:
- FunctionCallBracketNode(JSGlobalData* globalData, ExpressionNode* base, ExpressionNode* subscript, ArgumentsNode* args, unsigned divot, unsigned startOffset, unsigned endOffset) JSC_FAST_CALL
- : ExpressionNode(globalData)
- , ThrowableSubExpressionData(divot, startOffset, endOffset)
- , m_base(base)
- , m_subscript(subscript)
- , m_args(args)
- {
- }
-
- virtual ~FunctionCallBracketNode();
- virtual void releaseNodes(NodeReleaser&);
-
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+ FunctionCallBracketNode(const JSTokenLocation&, ExpressionNode* base, ExpressionNode* subscript, bool subscriptHasAssignments, ArgumentsNode*, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
private:
- RefPtr<ExpressionNode> m_base;
- RefPtr<ExpressionNode> m_subscript;
- RefPtr<ArgumentsNode> m_args;
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+
+ ExpressionNode* m_base;
+ ExpressionNode* m_subscript;
+ ArgumentsNode* m_args;
+ bool m_subscriptHasAssignments;
};
class FunctionCallDotNode : public ExpressionNode, public ThrowableSubExpressionData {
public:
- FunctionCallDotNode(JSGlobalData* globalData, ExpressionNode* base, const Identifier& ident, ArgumentsNode* args, unsigned divot, unsigned startOffset, unsigned endOffset) JSC_FAST_CALL
- : ExpressionNode(globalData)
- , ThrowableSubExpressionData(divot, startOffset, endOffset)
- , m_base(base)
- , m_ident(ident)
- , m_args(args)
- {
- }
-
- virtual ~FunctionCallDotNode();
- virtual void releaseNodes(NodeReleaser&);
-
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+ FunctionCallDotNode(const JSTokenLocation&, ExpressionNode* base, const Identifier&, ArgumentsNode*, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
private:
- RefPtr<ExpressionNode> m_base;
- Identifier m_ident;
- RefPtr<ArgumentsNode> m_args;
- };
-
- class PrePostResolveNode : public ExpressionNode, public ThrowableExpressionData {
- public:
- PrePostResolveNode(JSGlobalData* globalData, const Identifier& ident, unsigned divot, unsigned startOffset, unsigned endOffset) JSC_FAST_CALL
- : ExpressionNode(globalData, ResultType::numberType()) // could be reusable for pre?
- , ThrowableExpressionData(divot, startOffset, endOffset)
- , m_ident(ident)
- {
- }
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
protected:
- Identifier m_ident;
+ ExpressionNode* m_base;
+ const Identifier& m_ident;
+ ArgumentsNode* m_args;
};
- class PostfixResolveNode : public PrePostResolveNode {
+ class BytecodeIntrinsicNode : public ExpressionNode, public ThrowableExpressionData {
public:
- PostfixResolveNode(JSGlobalData* globalData, const Identifier& ident, Operator oper, unsigned divot, unsigned startOffset, unsigned endOffset) JSC_FAST_CALL
- : PrePostResolveNode(globalData, ident, divot, startOffset, endOffset)
- , m_operator(oper)
- {
- }
-
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
-
- private:
- Operator m_operator;
- };
+ typedef RegisterID* (BytecodeIntrinsicNode::* EmitterType)(BytecodeGenerator&, RegisterID*);
- class PostfixBracketNode : public ExpressionNode, public ThrowableSubExpressionData {
- public:
- PostfixBracketNode(JSGlobalData* globalData, ExpressionNode* base, ExpressionNode* subscript, Operator oper, unsigned divot, unsigned startOffset, unsigned endOffset) JSC_FAST_CALL
- : ExpressionNode(globalData)
- , ThrowableSubExpressionData(divot, startOffset, endOffset)
- , m_base(base)
- , m_subscript(subscript)
- , m_operator(oper)
- {
- }
+ BytecodeIntrinsicNode(const JSTokenLocation&, EmitterType, const Identifier&, ArgumentsNode*, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
- virtual ~PostfixBracketNode();
- virtual void releaseNodes(NodeReleaser&);
+ const Identifier& identifier() const { return m_ident; }
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+#define JSC_DECLARE_BYTECODE_INTRINSIC_FUNCTIONS(name) RegisterID* emit_intrinsic_##name(BytecodeGenerator&, RegisterID*);
+ JSC_COMMON_BYTECODE_INTRINSICS_EACH_NAME(JSC_DECLARE_BYTECODE_INTRINSIC_FUNCTIONS)
+#undef JSC_DECLARE_BYTECODE_INTRINSIC_FUNCTIONS
private:
- RefPtr<ExpressionNode> m_base;
- RefPtr<ExpressionNode> m_subscript;
- Operator m_operator;
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+
+ EmitterType m_emitter;
+ const Identifier& m_ident;
+ ArgumentsNode* m_args;
};
- class PostfixDotNode : public ExpressionNode, public ThrowableSubExpressionData {
+ class CallFunctionCallDotNode : public FunctionCallDotNode {
public:
- PostfixDotNode(JSGlobalData* globalData, ExpressionNode* base, const Identifier& ident, Operator oper, unsigned divot, unsigned startOffset, unsigned endOffset) JSC_FAST_CALL
- : ExpressionNode(globalData)
- , ThrowableSubExpressionData(divot, startOffset, endOffset)
- , m_base(base)
- , m_ident(ident)
- , m_operator(oper)
- {
- }
-
- virtual ~PostfixDotNode();
- virtual void releaseNodes(NodeReleaser&);
-
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+ CallFunctionCallDotNode(const JSTokenLocation&, ExpressionNode* base, const Identifier&, ArgumentsNode*, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
private:
- RefPtr<ExpressionNode> m_base;
- Identifier m_ident;
- Operator m_operator;
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
};
-
- class PostfixErrorNode : public ExpressionNode, public ThrowableSubExpressionData {
+
+ class ApplyFunctionCallDotNode : public FunctionCallDotNode {
public:
- PostfixErrorNode(JSGlobalData* globalData, ExpressionNode* expr, Operator oper, unsigned divot, unsigned startOffset, unsigned endOffset) JSC_FAST_CALL
- : ExpressionNode(globalData)
- , ThrowableSubExpressionData(divot, startOffset, endOffset)
- , m_expr(expr)
- , m_operator(oper)
- {
- }
-
- virtual ~PostfixErrorNode();
- virtual void releaseNodes(NodeReleaser&);
-
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+ ApplyFunctionCallDotNode(const JSTokenLocation&, ExpressionNode* base, const Identifier&, ArgumentsNode*, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
private:
- RefPtr<ExpressionNode> m_expr;
- Operator m_operator;
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
};
class DeleteResolveNode : public ExpressionNode, public ThrowableExpressionData {
public:
- DeleteResolveNode(JSGlobalData* globalData, const Identifier& ident, unsigned divot, unsigned startOffset, unsigned endOffset) JSC_FAST_CALL
- : ExpressionNode(globalData)
- , ThrowableExpressionData(divot, startOffset, endOffset)
- , m_ident(ident)
- {
- }
-
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+ DeleteResolveNode(const JSTokenLocation&, const Identifier&, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
private:
- Identifier m_ident;
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+
+ const Identifier& m_ident;
};
class DeleteBracketNode : public ExpressionNode, public ThrowableExpressionData {
public:
- DeleteBracketNode(JSGlobalData* globalData, ExpressionNode* base, ExpressionNode* subscript, unsigned divot, unsigned startOffset, unsigned endOffset) JSC_FAST_CALL
- : ExpressionNode(globalData)
- , ThrowableExpressionData(divot, startOffset, endOffset)
- , m_base(base)
- , m_subscript(subscript)
- {
- }
-
- virtual ~DeleteBracketNode();
- virtual void releaseNodes(NodeReleaser&);
-
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+ DeleteBracketNode(const JSTokenLocation&, ExpressionNode* base, ExpressionNode* subscript, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
private:
- RefPtr<ExpressionNode> m_base;
- RefPtr<ExpressionNode> m_subscript;
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+
+ ExpressionNode* m_base;
+ ExpressionNode* m_subscript;
};
class DeleteDotNode : public ExpressionNode, public ThrowableExpressionData {
public:
- DeleteDotNode(JSGlobalData* globalData, ExpressionNode* base, const Identifier& ident, unsigned divot, unsigned startOffset, unsigned endOffset) JSC_FAST_CALL
- : ExpressionNode(globalData)
- , ThrowableExpressionData(divot, startOffset, endOffset)
- , m_base(base)
- , m_ident(ident)
- {
- }
-
- virtual ~DeleteDotNode();
- virtual void releaseNodes(NodeReleaser&);
-
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+ DeleteDotNode(const JSTokenLocation&, ExpressionNode* base, const Identifier&, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
private:
- RefPtr<ExpressionNode> m_base;
- Identifier m_ident;
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+
+ ExpressionNode* m_base;
+ const Identifier& m_ident;
};
class DeleteValueNode : public ExpressionNode {
public:
- DeleteValueNode(JSGlobalData* globalData, ExpressionNode* expr) JSC_FAST_CALL
- : ExpressionNode(globalData)
- , m_expr(expr)
- {
- }
-
- virtual ~DeleteValueNode();
- virtual void releaseNodes(NodeReleaser&);
-
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+ DeleteValueNode(const JSTokenLocation&, ExpressionNode*);
private:
- RefPtr<ExpressionNode> m_expr;
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+
+ ExpressionNode* m_expr;
};
class VoidNode : public ExpressionNode {
public:
- VoidNode(JSGlobalData* globalData, ExpressionNode* expr) JSC_FAST_CALL
- : ExpressionNode(globalData)
- , m_expr(expr)
- {
- }
-
- virtual ~VoidNode();
- virtual void releaseNodes(NodeReleaser&);
-
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+ VoidNode(const JSTokenLocation&, ExpressionNode*);
private:
- RefPtr<ExpressionNode> m_expr;
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+
+ ExpressionNode* m_expr;
};
class TypeOfResolveNode : public ExpressionNode {
public:
- TypeOfResolveNode(JSGlobalData* globalData, const Identifier& ident) JSC_FAST_CALL
- : ExpressionNode(globalData, ResultType::stringType())
- , m_ident(ident)
- {
- }
-
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+ TypeOfResolveNode(const JSTokenLocation&, const Identifier&);
- const Identifier& identifier() const JSC_FAST_CALL { return m_ident; }
+ const Identifier& identifier() const { return m_ident; }
private:
- Identifier m_ident;
- };
-
- class TypeOfValueNode : public ExpressionNode {
- public:
- TypeOfValueNode(JSGlobalData* globalData, ExpressionNode* expr) JSC_FAST_CALL
- : ExpressionNode(globalData, ResultType::stringType())
- , m_expr(expr)
- {
- }
-
- virtual ~TypeOfValueNode();
- virtual void releaseNodes(NodeReleaser&);
-
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
- private:
- RefPtr<ExpressionNode> m_expr;
+ const Identifier& m_ident;
};
- class PrefixResolveNode : public PrePostResolveNode {
+ class TypeOfValueNode : public ExpressionNode {
public:
- PrefixResolveNode(JSGlobalData* globalData, const Identifier& ident, Operator oper, unsigned divot, unsigned startOffset, unsigned endOffset) JSC_FAST_CALL
- : PrePostResolveNode(globalData, ident, divot, startOffset, endOffset)
- , m_operator(oper)
- {
- }
-
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+ TypeOfValueNode(const JSTokenLocation&, ExpressionNode*);
private:
- Operator m_operator;
- };
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
- class PrefixBracketNode : public ExpressionNode, public ThrowablePrefixedSubExpressionData {
- public:
- PrefixBracketNode(JSGlobalData* globalData, ExpressionNode* base, ExpressionNode* subscript, Operator oper, unsigned divot, unsigned startOffset, unsigned endOffset) JSC_FAST_CALL
- : ExpressionNode(globalData)
- , ThrowablePrefixedSubExpressionData(divot, startOffset, endOffset)
- , m_base(base)
- , m_subscript(subscript)
- , m_operator(oper)
- {
- }
-
- virtual ~PrefixBracketNode();
- virtual void releaseNodes(NodeReleaser&);
-
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
-
- private:
- RefPtr<ExpressionNode> m_base;
- RefPtr<ExpressionNode> m_subscript;
- Operator m_operator;
+ ExpressionNode* m_expr;
};
- class PrefixDotNode : public ExpressionNode, public ThrowablePrefixedSubExpressionData {
+ class PrefixNode : public ExpressionNode, public ThrowablePrefixedSubExpressionData {
public:
- PrefixDotNode(JSGlobalData* globalData, ExpressionNode* base, const Identifier& ident, Operator oper, unsigned divot, unsigned startOffset, unsigned endOffset) JSC_FAST_CALL
- : ExpressionNode(globalData)
- , ThrowablePrefixedSubExpressionData(divot, startOffset, endOffset)
- , m_base(base)
- , m_ident(ident)
- , m_operator(oper)
- {
- }
+ PrefixNode(const JSTokenLocation&, ExpressionNode*, Operator, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
- virtual ~PrefixDotNode();
- virtual void releaseNodes(NodeReleaser&);
-
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+ protected:
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+ virtual RegisterID* emitResolve(BytecodeGenerator&, RegisterID* = 0);
+ virtual RegisterID* emitBracket(BytecodeGenerator&, RegisterID* = 0);
+ virtual RegisterID* emitDot(BytecodeGenerator&, RegisterID* = 0);
- private:
- RefPtr<ExpressionNode> m_base;
- Identifier m_ident;
+ ExpressionNode* m_expr;
Operator m_operator;
};
- class PrefixErrorNode : public ExpressionNode, public ThrowableExpressionData {
+ class PostfixNode : public PrefixNode {
public:
- PrefixErrorNode(JSGlobalData* globalData, ExpressionNode* expr, Operator oper, unsigned divot, unsigned startOffset, unsigned endOffset) JSC_FAST_CALL
- : ExpressionNode(globalData)
- , ThrowableExpressionData(divot, startOffset, endOffset)
- , m_expr(expr)
- , m_operator(oper)
- {
- }
-
- virtual ~PrefixErrorNode();
- virtual void releaseNodes(NodeReleaser&);
-
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+ PostfixNode(const JSTokenLocation&, ExpressionNode*, Operator, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
private:
- RefPtr<ExpressionNode> m_expr;
- Operator m_operator;
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+ virtual RegisterID* emitResolve(BytecodeGenerator&, RegisterID* = 0) override;
+ virtual RegisterID* emitBracket(BytecodeGenerator&, RegisterID* = 0) override;
+ virtual RegisterID* emitDot(BytecodeGenerator&, RegisterID* = 0) override;
};
class UnaryOpNode : public ExpressionNode {
public:
- UnaryOpNode(JSGlobalData* globalData, ExpressionNode* expr)
- : ExpressionNode(globalData)
- , m_expr(expr)
- {
- }
+ UnaryOpNode(const JSTokenLocation&, ResultType, ExpressionNode*, OpcodeID);
- UnaryOpNode(JSGlobalData* globalData, ResultType type, ExpressionNode* expr)
- : ExpressionNode(globalData, type)
- , m_expr(expr)
- {
- }
+ protected:
+ ExpressionNode* expr() { return m_expr; }
+ const ExpressionNode* expr() const { return m_expr; }
- virtual ~UnaryOpNode();
- virtual void releaseNodes(NodeReleaser&);
+ private:
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
- virtual OpcodeID opcodeID() const JSC_FAST_CALL = 0;
+ OpcodeID opcodeID() const { return m_opcodeID; }
- protected:
- RefPtr<ExpressionNode> m_expr;
+ ExpressionNode* m_expr;
+ OpcodeID m_opcodeID;
};
class UnaryPlusNode : public UnaryOpNode {
public:
- UnaryPlusNode(JSGlobalData* globalData, ExpressionNode* expr) JSC_FAST_CALL
- : UnaryOpNode(globalData, ResultType::numberType(), expr)
- {
- }
-
- virtual ExpressionNode* stripUnaryPlus() { return m_expr.get(); }
+ UnaryPlusNode(const JSTokenLocation&, ExpressionNode*);
- virtual OpcodeID opcodeID() const JSC_FAST_CALL { return op_to_jsnumber; }
+ private:
+ virtual ExpressionNode* stripUnaryPlus() override { return expr(); }
};
class NegateNode : public UnaryOpNode {
public:
- NegateNode(JSGlobalData* globalData, ExpressionNode* expr) JSC_FAST_CALL
- : UnaryOpNode(globalData, ResultType::numberTypeCanReuse(), expr)
- {
- }
-
- virtual OpcodeID opcodeID() const JSC_FAST_CALL { return op_negate; }
+ NegateNode(const JSTokenLocation&, ExpressionNode*);
};
- class BitwiseNotNode : public UnaryOpNode {
+ class BitwiseNotNode : public ExpressionNode {
public:
- BitwiseNotNode(JSGlobalData* globalData, ExpressionNode* expr) JSC_FAST_CALL
- : UnaryOpNode(globalData, ResultType::forBitOp(), expr)
- {
- }
+ BitwiseNotNode(const JSTokenLocation&, ExpressionNode*);
- virtual OpcodeID opcodeID() const JSC_FAST_CALL { return op_bitnot; }
- };
+ protected:
+ ExpressionNode* expr() { return m_expr; }
+ const ExpressionNode* expr() const { return m_expr; }
+
+ private:
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+ ExpressionNode* m_expr;
+ };
+
class LogicalNotNode : public UnaryOpNode {
public:
- LogicalNotNode(JSGlobalData* globalData, ExpressionNode* expr) JSC_FAST_CALL
- : UnaryOpNode(globalData, ResultType::booleanType(), expr)
- {
- }
-
- virtual OpcodeID opcodeID() const JSC_FAST_CALL { return op_not; }
+ LogicalNotNode(const JSTokenLocation&, ExpressionNode*);
+ private:
+ virtual void emitBytecodeInConditionContext(BytecodeGenerator&, Label* trueTarget, Label* falseTarget, FallThroughMode) override;
};
class BinaryOpNode : public ExpressionNode {
public:
- BinaryOpNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
- : ExpressionNode(globalData)
- , m_expr1(expr1)
- , m_expr2(expr2)
- , m_rightHasAssignments(rightHasAssignments)
- {
- }
+ BinaryOpNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, OpcodeID, bool rightHasAssignments);
+ BinaryOpNode(const JSTokenLocation&, ResultType, ExpressionNode* expr1, ExpressionNode* expr2, OpcodeID, bool rightHasAssignments);
- BinaryOpNode(JSGlobalData* globalData, ResultType type, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
- : ExpressionNode(globalData, type)
- , m_expr1(expr1)
- , m_expr2(expr2)
- , m_rightHasAssignments(rightHasAssignments)
- {
- }
+ RegisterID* emitStrcat(BytecodeGenerator& generator, RegisterID* destination, RegisterID* lhs = 0, ReadModifyResolveNode* emitExpressionInfoForMe = 0);
+ virtual void emitBytecodeInConditionContext(BytecodeGenerator&, Label* trueTarget, Label* falseTarget, FallThroughMode) override;
- virtual ~BinaryOpNode();
- virtual void releaseNodes(NodeReleaser&);
+ ExpressionNode* lhs() { return m_expr1; };
+ ExpressionNode* rhs() { return m_expr2; };
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
- virtual OpcodeID opcodeID() const JSC_FAST_CALL = 0;
+ private:
+ void tryFoldToBranch(BytecodeGenerator&, TriState& branchCondition, ExpressionNode*& branchExpression);
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
protected:
- RefPtr<ExpressionNode> m_expr1;
- RefPtr<ExpressionNode> m_expr2;
- bool m_rightHasAssignments;
- };
-
- class ReverseBinaryOpNode : public BinaryOpNode {
- public:
- ReverseBinaryOpNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
- : BinaryOpNode(globalData, expr1, expr2, rightHasAssignments)
- {
- }
-
- ReverseBinaryOpNode(JSGlobalData* globalData, ResultType type, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
- : BinaryOpNode(globalData, type, expr1, expr2, rightHasAssignments)
- {
- }
+ OpcodeID opcodeID() const { return m_opcodeID; }
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+ protected:
+ ExpressionNode* m_expr1;
+ ExpressionNode* m_expr2;
+ private:
+ OpcodeID m_opcodeID;
+ protected:
+ bool m_rightHasAssignments;
};
class MultNode : public BinaryOpNode {
public:
- MultNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) JSC_FAST_CALL
- : BinaryOpNode(globalData, ResultType::numberTypeCanReuse(), expr1, expr2, rightHasAssignments)
- {
- }
-
- virtual OpcodeID opcodeID() const JSC_FAST_CALL { return op_mul; }
+ MultNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
};
class DivNode : public BinaryOpNode {
public:
- DivNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) JSC_FAST_CALL
- : BinaryOpNode(globalData, ResultType::numberTypeCanReuse(), expr1, expr2, rightHasAssignments)
- {
- }
-
- virtual OpcodeID opcodeID() const JSC_FAST_CALL { return op_div; }
+ DivNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
};
class ModNode : public BinaryOpNode {
public:
- ModNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) JSC_FAST_CALL
- : BinaryOpNode(globalData, ResultType::numberTypeCanReuse(), expr1, expr2, rightHasAssignments)
- {
- }
-
- virtual OpcodeID opcodeID() const JSC_FAST_CALL { return op_mod; }
+ ModNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
};
class AddNode : public BinaryOpNode {
public:
- AddNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) JSC_FAST_CALL
- : BinaryOpNode(globalData, ResultType::forAdd(expr1->resultDescriptor(), expr2->resultDescriptor()), expr1, expr2, rightHasAssignments)
- {
- }
+ AddNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
- virtual OpcodeID opcodeID() const JSC_FAST_CALL { return op_add; }
+ virtual bool isAdd() const override { return true; }
};
class SubNode : public BinaryOpNode {
public:
- SubNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) JSC_FAST_CALL
- : BinaryOpNode(globalData, ResultType::numberTypeCanReuse(), expr1, expr2, rightHasAssignments)
- {
- }
+ SubNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
- virtual OpcodeID opcodeID() const JSC_FAST_CALL { return op_sub; }
+ virtual bool isSubtract() const override { return true; }
};
class LeftShiftNode : public BinaryOpNode {
public:
- LeftShiftNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) JSC_FAST_CALL
- : BinaryOpNode(globalData, ResultType::forBitOp(), expr1, expr2, rightHasAssignments)
- {
- }
-
- virtual OpcodeID opcodeID() const JSC_FAST_CALL { return op_lshift; }
+ LeftShiftNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
};
class RightShiftNode : public BinaryOpNode {
public:
- RightShiftNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) JSC_FAST_CALL
- : BinaryOpNode(globalData, ResultType::forBitOp(), expr1, expr2, rightHasAssignments)
- {
- }
-
- virtual OpcodeID opcodeID() const JSC_FAST_CALL { return op_rshift; }
+ RightShiftNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
};
class UnsignedRightShiftNode : public BinaryOpNode {
public:
- UnsignedRightShiftNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) JSC_FAST_CALL
- : BinaryOpNode(globalData, ResultType::numberTypeCanReuse(), expr1, expr2, rightHasAssignments)
- {
- }
-
- virtual OpcodeID opcodeID() const JSC_FAST_CALL { return op_urshift; }
+ UnsignedRightShiftNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
};
class LessNode : public BinaryOpNode {
public:
- LessNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) JSC_FAST_CALL
- : BinaryOpNode(globalData, ResultType::booleanType(), expr1, expr2, rightHasAssignments)
- {
- }
-
- virtual OpcodeID opcodeID() const JSC_FAST_CALL { return op_less; }
+ LessNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
};
- class GreaterNode : public ReverseBinaryOpNode {
+ class GreaterNode : public BinaryOpNode {
public:
- GreaterNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) JSC_FAST_CALL
- : ReverseBinaryOpNode(globalData, ResultType::booleanType(), expr1, expr2, rightHasAssignments)
- {
- }
-
- virtual OpcodeID opcodeID() const JSC_FAST_CALL { return op_less; }
+ GreaterNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
};
class LessEqNode : public BinaryOpNode {
public:
- LessEqNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) JSC_FAST_CALL
- : BinaryOpNode(globalData, ResultType::booleanType(), expr1, expr2, rightHasAssignments)
- {
- }
-
- virtual OpcodeID opcodeID() const JSC_FAST_CALL { return op_lesseq; }
+ LessEqNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
};
- class GreaterEqNode : public ReverseBinaryOpNode {
+ class GreaterEqNode : public BinaryOpNode {
public:
- GreaterEqNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) JSC_FAST_CALL
- : ReverseBinaryOpNode(globalData, ResultType::booleanType(), expr1, expr2, rightHasAssignments)
- {
- }
-
- virtual OpcodeID opcodeID() const JSC_FAST_CALL { return op_lesseq; }
+ GreaterEqNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
};
class ThrowableBinaryOpNode : public BinaryOpNode, public ThrowableExpressionData {
public:
- ThrowableBinaryOpNode(JSGlobalData* globalData, ResultType type, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) JSC_FAST_CALL
- : BinaryOpNode(globalData, type, expr1, expr2, rightHasAssignments)
- {
- }
- ThrowableBinaryOpNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) JSC_FAST_CALL
- : BinaryOpNode(globalData, expr1, expr2, rightHasAssignments)
- {
- }
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+ 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) override;
};
class InstanceOfNode : public ThrowableBinaryOpNode {
public:
- InstanceOfNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) JSC_FAST_CALL
- : ThrowableBinaryOpNode(globalData, ResultType::booleanType(), expr1, expr2, rightHasAssignments)
- {
- }
+ InstanceOfNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
- virtual OpcodeID opcodeID() const JSC_FAST_CALL { return op_instanceof; }
-
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+ private:
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
};
class InNode : public ThrowableBinaryOpNode {
public:
- InNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) JSC_FAST_CALL
- : ThrowableBinaryOpNode(globalData, expr1, expr2, rightHasAssignments)
- {
- }
-
- virtual OpcodeID opcodeID() const JSC_FAST_CALL { return op_in; }
+ InNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
};
class EqualNode : public BinaryOpNode {
public:
- EqualNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) JSC_FAST_CALL
- : BinaryOpNode(globalData, ResultType::booleanType(), expr1, expr2, rightHasAssignments)
- {
- }
+ EqualNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
- virtual OpcodeID opcodeID() const JSC_FAST_CALL { return op_eq; }
+ private:
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
};
class NotEqualNode : public BinaryOpNode {
public:
- NotEqualNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) JSC_FAST_CALL
- : BinaryOpNode(globalData, ResultType::booleanType(), expr1, expr2, rightHasAssignments)
- {
- }
-
- virtual OpcodeID opcodeID() const JSC_FAST_CALL { return op_neq; }
+ NotEqualNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
};
class StrictEqualNode : public BinaryOpNode {
public:
- StrictEqualNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) JSC_FAST_CALL
- : BinaryOpNode(globalData, ResultType::booleanType(), expr1, expr2, rightHasAssignments)
- {
- }
+ StrictEqualNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
- virtual OpcodeID opcodeID() const JSC_FAST_CALL { return op_stricteq; }
+ private:
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
};
class NotStrictEqualNode : public BinaryOpNode {
public:
- NotStrictEqualNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) JSC_FAST_CALL
- : BinaryOpNode(globalData, ResultType::booleanType(), expr1, expr2, rightHasAssignments)
- {
- }
-
- virtual OpcodeID opcodeID() const JSC_FAST_CALL { return op_nstricteq; }
+ NotStrictEqualNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
};
class BitAndNode : public BinaryOpNode {
public:
- BitAndNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) JSC_FAST_CALL
- : BinaryOpNode(globalData, ResultType::forBitOp(), expr1, expr2, rightHasAssignments)
- {
- }
-
- virtual OpcodeID opcodeID() const JSC_FAST_CALL { return op_bitand; }
+ BitAndNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
};
class BitOrNode : public BinaryOpNode {
public:
- BitOrNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) JSC_FAST_CALL
- : BinaryOpNode(globalData, ResultType::forBitOp(), expr1, expr2, rightHasAssignments)
- {
- }
-
- virtual OpcodeID opcodeID() const JSC_FAST_CALL { return op_bitor; }
+ BitOrNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
};
class BitXOrNode : public BinaryOpNode {
public:
- BitXOrNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) JSC_FAST_CALL
- : BinaryOpNode(globalData, ResultType::forBitOp(), expr1, expr2, rightHasAssignments)
- {
- }
-
- virtual OpcodeID opcodeID() const JSC_FAST_CALL { return op_bitxor; }
+ BitXOrNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
};
- /**
- * m_expr1 && m_expr2, m_expr1 || m_expr2
- */
+ // m_expr1 && m_expr2, m_expr1 || m_expr2
class LogicalOpNode : public ExpressionNode {
public:
- LogicalOpNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, LogicalOperator oper) JSC_FAST_CALL
- : ExpressionNode(globalData, ResultType::booleanType())
- , m_expr1(expr1)
- , m_expr2(expr2)
- , m_operator(oper)
- {
- }
-
- virtual ~LogicalOpNode();
- virtual void releaseNodes(NodeReleaser&);
-
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+ LogicalOpNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, LogicalOperator);
private:
- RefPtr<ExpressionNode> m_expr1;
- RefPtr<ExpressionNode> m_expr2;
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+ virtual void emitBytecodeInConditionContext(BytecodeGenerator&, Label* trueTarget, Label* falseTarget, FallThroughMode) override;
+
+ ExpressionNode* m_expr1;
+ ExpressionNode* m_expr2;
LogicalOperator m_operator;
};
- /**
- * The ternary operator, "m_logical ? m_expr1 : m_expr2"
- */
+ // The ternary operator, "m_logical ? m_expr1 : m_expr2"
class ConditionalNode : public ExpressionNode {
public:
- ConditionalNode(JSGlobalData* globalData, ExpressionNode* logical, ExpressionNode* expr1, ExpressionNode* expr2) JSC_FAST_CALL
- : ExpressionNode(globalData)
- , m_logical(logical)
- , m_expr1(expr1)
- , m_expr2(expr2)
- {
- }
-
- virtual ~ConditionalNode();
- virtual void releaseNodes(NodeReleaser&);
-
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+ ConditionalNode(const JSTokenLocation&, ExpressionNode* logical, ExpressionNode* expr1, ExpressionNode* expr2);
private:
- RefPtr<ExpressionNode> m_logical;
- RefPtr<ExpressionNode> m_expr1;
- RefPtr<ExpressionNode> m_expr2;
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+
+ ExpressionNode* m_logical;
+ ExpressionNode* m_expr1;
+ ExpressionNode* m_expr2;
};
class ReadModifyResolveNode : public ExpressionNode, public ThrowableExpressionData {
public:
- ReadModifyResolveNode(JSGlobalData* globalData, const Identifier& ident, Operator oper, ExpressionNode* right, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset) JSC_FAST_CALL
- : ExpressionNode(globalData)
- , ThrowableExpressionData(divot, startOffset, endOffset)
- , m_ident(ident)
- , m_right(right)
- , m_operator(oper)
- , m_rightHasAssignments(rightHasAssignments)
- {
- }
-
- virtual ~ReadModifyResolveNode();
- virtual void releaseNodes(NodeReleaser&);
-
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+ ReadModifyResolveNode(const JSTokenLocation&, const Identifier&, Operator, ExpressionNode* right, bool rightHasAssignments, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
private:
- Identifier m_ident;
- RefPtr<ExpressionNode> m_right;
- size_t m_index; // Used by ReadModifyLocalVarNode.
- Operator m_operator : 31;
- bool m_rightHasAssignments : 1;
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+
+ const Identifier& m_ident;
+ ExpressionNode* m_right;
+ Operator m_operator;
+ bool m_rightHasAssignments;
};
class AssignResolveNode : public ExpressionNode, public ThrowableExpressionData {
public:
- AssignResolveNode(JSGlobalData* globalData, const Identifier& ident, ExpressionNode* right, bool rightHasAssignments) JSC_FAST_CALL
- : ExpressionNode(globalData)
- , m_ident(ident)
- , m_right(right)
- , m_rightHasAssignments(rightHasAssignments)
- {
- }
-
- virtual ~AssignResolveNode();
- virtual void releaseNodes(NodeReleaser&);
-
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+ AssignResolveNode(const JSTokenLocation&, const Identifier&, ExpressionNode* right);
private:
- Identifier m_ident;
- RefPtr<ExpressionNode> m_right;
- size_t m_index; // Used by ReadModifyLocalVarNode.
- bool m_rightHasAssignments;
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+
+ const Identifier& m_ident;
+ ExpressionNode* m_right;
};
class ReadModifyBracketNode : public ExpressionNode, public ThrowableSubExpressionData {
public:
- ReadModifyBracketNode(JSGlobalData* globalData, ExpressionNode* base, ExpressionNode* subscript, Operator oper, ExpressionNode* right, bool subscriptHasAssignments, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset) JSC_FAST_CALL
- : ExpressionNode(globalData)
- , ThrowableSubExpressionData(divot, startOffset, endOffset)
- , m_base(base)
- , m_subscript(subscript)
- , m_right(right)
- , m_operator(oper)
- , m_subscriptHasAssignments(subscriptHasAssignments)
- , m_rightHasAssignments(rightHasAssignments)
- {
- }
-
- virtual ~ReadModifyBracketNode();
- virtual void releaseNodes(NodeReleaser&);
-
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+ ReadModifyBracketNode(const JSTokenLocation&, ExpressionNode* base, ExpressionNode* subscript, Operator, ExpressionNode* right, bool subscriptHasAssignments, bool rightHasAssignments, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
private:
- RefPtr<ExpressionNode> m_base;
- RefPtr<ExpressionNode> m_subscript;
- RefPtr<ExpressionNode> m_right;
- Operator m_operator : 30;
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+
+ ExpressionNode* m_base;
+ ExpressionNode* m_subscript;
+ ExpressionNode* m_right;
+ unsigned m_operator : 30;
bool m_subscriptHasAssignments : 1;
bool m_rightHasAssignments : 1;
};
class AssignBracketNode : public ExpressionNode, public ThrowableExpressionData {
public:
- AssignBracketNode(JSGlobalData* globalData, ExpressionNode* base, ExpressionNode* subscript, ExpressionNode* right, bool subscriptHasAssignments, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset) JSC_FAST_CALL
- : ExpressionNode(globalData)
- , ThrowableExpressionData(divot, startOffset, endOffset)
- , m_base(base)
- , m_subscript(subscript)
- , m_right(right)
- , m_subscriptHasAssignments(subscriptHasAssignments)
- , m_rightHasAssignments(rightHasAssignments)
- {
- }
-
- virtual ~AssignBracketNode();
- virtual void releaseNodes(NodeReleaser&);
-
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+ AssignBracketNode(const JSTokenLocation&, ExpressionNode* base, ExpressionNode* subscript, ExpressionNode* right, bool subscriptHasAssignments, bool rightHasAssignments, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
private:
- RefPtr<ExpressionNode> m_base;
- RefPtr<ExpressionNode> m_subscript;
- RefPtr<ExpressionNode> m_right;
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+
+ ExpressionNode* m_base;
+ ExpressionNode* m_subscript;
+ ExpressionNode* m_right;
bool m_subscriptHasAssignments : 1;
bool m_rightHasAssignments : 1;
};
class AssignDotNode : public ExpressionNode, public ThrowableExpressionData {
public:
- AssignDotNode(JSGlobalData* globalData, ExpressionNode* base, const Identifier& ident, ExpressionNode* right, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset) JSC_FAST_CALL
- : ExpressionNode(globalData)
- , ThrowableExpressionData(divot, startOffset, endOffset)
- , m_base(base)
- , m_ident(ident)
- , m_right(right)
- , m_rightHasAssignments(rightHasAssignments)
- {
- }
-
- virtual ~AssignDotNode();
- virtual void releaseNodes(NodeReleaser&);
-
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+ AssignDotNode(const JSTokenLocation&, ExpressionNode* base, const Identifier&, ExpressionNode* right, bool rightHasAssignments, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
private:
- RefPtr<ExpressionNode> m_base;
- Identifier m_ident;
- RefPtr<ExpressionNode> m_right;
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+
+ ExpressionNode* m_base;
+ const Identifier& m_ident;
+ ExpressionNode* m_right;
bool m_rightHasAssignments;
};
class ReadModifyDotNode : public ExpressionNode, public ThrowableSubExpressionData {
public:
- ReadModifyDotNode(JSGlobalData* globalData, ExpressionNode* base, const Identifier& ident, Operator oper, ExpressionNode* right, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset) JSC_FAST_CALL
- : ExpressionNode(globalData)
- , ThrowableSubExpressionData(divot, startOffset, endOffset)
- , m_base(base)
- , m_ident(ident)
- , m_right(right)
- , m_operator(oper)
- , m_rightHasAssignments(rightHasAssignments)
- {
- }
-
- virtual ~ReadModifyDotNode();
- virtual void releaseNodes(NodeReleaser&);
-
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+ ReadModifyDotNode(const JSTokenLocation&, ExpressionNode* base, const Identifier&, Operator, ExpressionNode* right, bool rightHasAssignments, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
private:
- RefPtr<ExpressionNode> m_base;
- Identifier m_ident;
- RefPtr<ExpressionNode> m_right;
- Operator m_operator : 31;
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+
+ ExpressionNode* m_base;
+ const Identifier& m_ident;
+ ExpressionNode* m_right;
+ unsigned m_operator : 31;
bool m_rightHasAssignments : 1;
};
class AssignErrorNode : public ExpressionNode, public ThrowableExpressionData {
public:
- AssignErrorNode(JSGlobalData* globalData, ExpressionNode* left, Operator oper, ExpressionNode* right, unsigned divot, unsigned startOffset, unsigned endOffset) JSC_FAST_CALL
- : ExpressionNode(globalData)
- , ThrowableExpressionData(divot, startOffset, endOffset)
- , m_left(left)
- , m_operator(oper)
- , m_right(right)
- {
- }
-
- virtual ~AssignErrorNode();
- virtual void releaseNodes(NodeReleaser&);
-
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+ AssignErrorNode(const JSTokenLocation&, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
private:
- RefPtr<ExpressionNode> m_left;
- Operator m_operator;
- RefPtr<ExpressionNode> m_right;
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
};
-
- class CommaNode : public ExpressionNode {
+
+ class CommaNode final : public ExpressionNode {
public:
- CommaNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2) JSC_FAST_CALL
- : ExpressionNode(globalData)
- , m_expr1(expr1)
- , m_expr2(expr2)
- {
- }
-
- virtual ~CommaNode();
- virtual void releaseNodes(NodeReleaser&);
+ CommaNode(const JSTokenLocation&, ExpressionNode*);
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+ void setNext(CommaNode* next) { m_next = next; }
+ CommaNode* next() { return m_next; }
private:
- RefPtr<ExpressionNode> m_expr1;
- RefPtr<ExpressionNode> m_expr2;
+ virtual bool isCommaNode() const override { return true; }
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+
+ ExpressionNode* m_expr;
+ CommaNode* m_next;
};
- class VarDeclCommaNode : public CommaNode {
- public:
- VarDeclCommaNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2) JSC_FAST_CALL
- : CommaNode(globalData, expr1, expr2)
- {
- }
- };
-
class ConstDeclNode : public ExpressionNode {
public:
- ConstDeclNode(JSGlobalData* globalData, const Identifier& ident, ExpressionNode* in) JSC_FAST_CALL;
+ ConstDeclNode(const JSTokenLocation&, const Identifier&, ExpressionNode*);
- virtual ~ConstDeclNode();
- virtual void releaseNodes(NodeReleaser&);
+ bool hasInitializer() const { return m_init; }
+ const Identifier& ident() { return m_ident; }
- Identifier m_ident;
- RefPtr<ConstDeclNode> m_next;
- RefPtr<ExpressionNode> m_init;
-
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
- virtual RegisterID* emitCodeSingle(BytecodeGenerator&) JSC_FAST_CALL;
- };
+ private:
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+ virtual RegisterID* emitCodeSingle(BytecodeGenerator&);
+
+ const Identifier& m_ident;
- class ConstStatementNode : public StatementNode {
public:
- ConstStatementNode(JSGlobalData* globalData, ConstDeclNode* next) JSC_FAST_CALL
- : StatementNode(globalData)
- , m_next(next)
- {
- }
+ ConstDeclNode* m_next;
- virtual ~ConstStatementNode();
- virtual void releaseNodes(NodeReleaser&);
+ private:
+ ExpressionNode* m_init;
+ };
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+ class ConstStatementNode : public StatementNode {
+ public:
+ ConstStatementNode(const JSTokenLocation&, ConstDeclNode* next);
private:
- RefPtr<ConstDeclNode> m_next;
- };
+ virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
- typedef Vector<RefPtr<StatementNode> > StatementVector;
+ ConstDeclNode* m_next;
+ };
- class SourceElements : public ParserRefCounted {
+ class SourceElements final : public ParserArenaFreeable {
public:
- SourceElements(JSGlobalData* globalData) : ParserRefCounted(globalData) {}
+ SourceElements();
- void append(PassRefPtr<StatementNode>);
- void releaseContentsIntoVector(StatementVector& destination)
- {
- ASSERT(destination.isEmpty());
- m_statements.swap(destination);
- destination.shrinkToFit();
- }
+ void append(StatementNode*);
+
+ StatementNode* singleStatement() const;
+ StatementNode* lastStatement() const;
+
+ void emitBytecode(BytecodeGenerator&, RegisterID* destination);
private:
- StatementVector m_statements;
+ StatementNode* m_head;
+ StatementNode* m_tail;
};
class BlockNode : public StatementNode {
public:
- BlockNode(JSGlobalData*, SourceElements* children) JSC_FAST_CALL;
-
- virtual ~BlockNode();
- virtual void releaseNodes(NodeReleaser&);
+ BlockNode(const JSTokenLocation&, SourceElements* = 0);
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+ StatementNode* singleStatement() const;
+ StatementNode* lastStatement() const;
- StatementVector& children() { return m_children; }
+ private:
+ virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
- virtual bool isBlock() const JSC_FAST_CALL { return true; }
+ virtual bool isBlock() const override { return true; }
- private:
- StatementVector m_children;
+ SourceElements* m_statements;
};
class EmptyStatementNode : public StatementNode {
public:
- EmptyStatementNode(JSGlobalData* globalData) JSC_FAST_CALL // debug
- : StatementNode(globalData)
- {
- }
+ EmptyStatementNode(const JSTokenLocation&);
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+ private:
+ virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
- virtual bool isEmptyStatement() const JSC_FAST_CALL { return true; }
+ virtual bool isEmptyStatement() const override { return true; }
};
class DebuggerStatementNode : public StatementNode {
public:
- DebuggerStatementNode(JSGlobalData* globalData) JSC_FAST_CALL
- : StatementNode(globalData)
- {
- }
+ DebuggerStatementNode(const JSTokenLocation&);
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+ private:
+ virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
};
class ExprStatementNode : public StatementNode {
public:
- ExprStatementNode(JSGlobalData* globalData, ExpressionNode* expr) JSC_FAST_CALL
- : StatementNode(globalData)
- , m_expr(expr)
- {
- }
+ ExprStatementNode(const JSTokenLocation&, ExpressionNode*);
- virtual bool isExprStatement() const JSC_FAST_CALL { return true; }
+ ExpressionNode* expr() const { return m_expr; }
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+ private:
+ virtual bool isExprStatement() const override { return true; }
- ExpressionNode* expr() const { return m_expr.get(); }
+ virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
- private:
- RefPtr<ExpressionNode> m_expr;
+ ExpressionNode* m_expr;
};
class VarStatementNode : public StatementNode {
public:
- VarStatementNode(JSGlobalData* globalData, ExpressionNode* expr) JSC_FAST_CALL
- : StatementNode(globalData)
- , m_expr(expr)
- {
- }
-
- virtual ~VarStatementNode();
- virtual void releaseNodes(NodeReleaser&);
-
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
-
+ VarStatementNode(const JSTokenLocation&, ExpressionNode*);
private:
- RefPtr<ExpressionNode> m_expr;
+ virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+
+ ExpressionNode* m_expr;
};
- class IfNode : public StatementNode {
+ class EmptyVarExpression : public ExpressionNode {
public:
- IfNode(JSGlobalData* globalData, ExpressionNode* condition, StatementNode* ifBlock) JSC_FAST_CALL
- : StatementNode(globalData)
- , m_condition(condition)
- , m_ifBlock(ifBlock)
- {
- }
+ EmptyVarExpression(const JSTokenLocation&, const Identifier&);
- virtual ~IfNode();
- virtual void releaseNodes(NodeReleaser&);
-
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+ private:
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
- protected:
- RefPtr<ExpressionNode> m_condition;
- RefPtr<StatementNode> m_ifBlock;
+ const Identifier& m_ident;
};
- class IfElseNode : public IfNode {
- public:
- IfElseNode(JSGlobalData* globalData, ExpressionNode* condition, StatementNode* ifBlock, StatementNode* elseBlock) JSC_FAST_CALL
- : IfNode(globalData, condition, ifBlock)
- , m_elseBlock(elseBlock)
- {
- }
-
- virtual ~IfElseNode();
- virtual void releaseNodes(NodeReleaser&);
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+ class IfElseNode : public StatementNode {
+ public:
+ IfElseNode(const JSTokenLocation&, ExpressionNode* condition, StatementNode* ifBlock, StatementNode* elseBlock);
private:
- RefPtr<StatementNode> m_elseBlock;
+ virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+ bool tryFoldBreakAndContinue(BytecodeGenerator&, StatementNode* ifBlock,
+ Label*& trueTarget, FallThroughMode&);
+
+ ExpressionNode* m_condition;
+ StatementNode* m_ifBlock;
+ StatementNode* m_elseBlock;
};
class DoWhileNode : public StatementNode {
public:
- DoWhileNode(JSGlobalData* globalData, StatementNode* statement, ExpressionNode* expr) JSC_FAST_CALL
- : StatementNode(globalData)
- , m_statement(statement)
- , m_expr(expr)
- {
- }
-
- virtual ~DoWhileNode();
- virtual void releaseNodes(NodeReleaser&);
-
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
-
- virtual bool isLoop() const JSC_FAST_CALL { return true; }
+ DoWhileNode(const JSTokenLocation&, StatementNode*, ExpressionNode*);
private:
- RefPtr<StatementNode> m_statement;
- RefPtr<ExpressionNode> m_expr;
+ virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+
+ StatementNode* m_statement;
+ ExpressionNode* m_expr;
};
class WhileNode : public StatementNode {
public:
- WhileNode(JSGlobalData* globalData, ExpressionNode* expr, StatementNode* statement) JSC_FAST_CALL
- : StatementNode(globalData)
- , m_expr(expr)
- , m_statement(statement)
- {
- }
-
- virtual ~WhileNode();
- virtual void releaseNodes(NodeReleaser&);
-
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
-
- virtual bool isLoop() const JSC_FAST_CALL { return true; }
+ WhileNode(const JSTokenLocation&, ExpressionNode*, StatementNode*);
private:
- RefPtr<ExpressionNode> m_expr;
- RefPtr<StatementNode> m_statement;
+ virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+
+ ExpressionNode* m_expr;
+ StatementNode* m_statement;
};
class ForNode : public StatementNode {
public:
- ForNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, ExpressionNode* expr3, StatementNode* statement, bool expr1WasVarDecl) JSC_FAST_CALL
- : StatementNode(globalData)
- , m_expr1(expr1)
- , m_expr2(expr2)
- , m_expr3(expr3)
- , m_statement(statement)
- , m_expr1WasVarDecl(expr1 && expr1WasVarDecl)
- {
- ASSERT(statement);
- }
-
- virtual ~ForNode();
- virtual void releaseNodes(NodeReleaser&);
-
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
-
- virtual bool isLoop() const JSC_FAST_CALL { return true; }
+ ForNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, ExpressionNode* expr3, StatementNode*);
private:
- RefPtr<ExpressionNode> m_expr1;
- RefPtr<ExpressionNode> m_expr2;
- RefPtr<ExpressionNode> m_expr3;
- RefPtr<StatementNode> m_statement;
- bool m_expr1WasVarDecl;
- };
+ virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
- class ForInNode : public StatementNode, public ThrowableExpressionData {
+ ExpressionNode* m_expr1;
+ ExpressionNode* m_expr2;
+ ExpressionNode* m_expr3;
+ StatementNode* m_statement;
+ };
+
+ class DestructuringPatternNode;
+
+ class EnumerationNode : public StatementNode, public ThrowableExpressionData {
public:
- ForInNode(JSGlobalData*, ExpressionNode*, ExpressionNode*, StatementNode*) JSC_FAST_CALL;
- ForInNode(JSGlobalData*, const Identifier&, ExpressionNode*, ExpressionNode*, StatementNode*, int divot, int startOffset, int endOffset) JSC_FAST_CALL;
+ EnumerationNode(const JSTokenLocation&, ExpressionNode*, ExpressionNode*, StatementNode*);
- virtual ~ForInNode();
- virtual void releaseNodes(NodeReleaser&);
-
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+ protected:
+ ExpressionNode* m_lexpr;
+ ExpressionNode* m_expr;
+ StatementNode* m_statement;
+ };
+
+ class ForInNode : public EnumerationNode {
+ public:
+ ForInNode(const JSTokenLocation&, ExpressionNode*, ExpressionNode*, StatementNode*);
- virtual bool isLoop() const JSC_FAST_CALL { return true; }
+ private:
+ RegisterID* tryGetBoundLocal(BytecodeGenerator&);
+ void emitLoopHeader(BytecodeGenerator&, RegisterID* propertyName);
+ void emitMultiLoopBytecode(BytecodeGenerator&, RegisterID* dst);
+ virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+ };
+
+ class ForOfNode : public EnumerationNode {
+ public:
+ ForOfNode(const JSTokenLocation&, ExpressionNode*, ExpressionNode*, StatementNode*);
+
private:
- Identifier m_ident;
- RefPtr<ExpressionNode> m_init;
- RefPtr<ExpressionNode> m_lexpr;
- RefPtr<ExpressionNode> m_expr;
- RefPtr<StatementNode> m_statement;
- bool m_identIsVarDecl;
+ virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
};
class ContinueNode : public StatementNode, public ThrowableExpressionData {
public:
- ContinueNode(JSGlobalData* globalData) JSC_FAST_CALL
- : StatementNode(globalData)
- {
- }
-
- ContinueNode(JSGlobalData* globalData, const Identifier& ident) JSC_FAST_CALL
- : StatementNode(globalData)
- , m_ident(ident)
- {
- }
+ ContinueNode(const JSTokenLocation&, const Identifier&);
+ Label* trivialTarget(BytecodeGenerator&);
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
-
private:
- Identifier m_ident;
+ virtual bool isContinue() const override { return true; }
+ virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+
+ const Identifier& m_ident;
};
class BreakNode : public StatementNode, public ThrowableExpressionData {
public:
- BreakNode(JSGlobalData* globalData) JSC_FAST_CALL
- : StatementNode(globalData)
- {
- }
-
- BreakNode(JSGlobalData* globalData, const Identifier& ident) JSC_FAST_CALL
- : StatementNode(globalData)
- , m_ident(ident)
- {
- }
+ BreakNode(const JSTokenLocation&, const Identifier&);
+ Label* trivialTarget(BytecodeGenerator&);
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
-
private:
- Identifier m_ident;
+ virtual bool isBreak() const override { return true; }
+ virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+
+ const Identifier& m_ident;
};
class ReturnNode : public StatementNode, public ThrowableExpressionData {
public:
- ReturnNode(JSGlobalData* globalData, ExpressionNode* value) JSC_FAST_CALL
- : StatementNode(globalData)
- , m_value(value)
- {
- }
-
- virtual ~ReturnNode();
- virtual void releaseNodes(NodeReleaser&);
+ ReturnNode(const JSTokenLocation&, ExpressionNode* value);
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
- virtual bool isReturnNode() const JSC_FAST_CALL { return true; }
+ ExpressionNode* value() { return m_value; }
private:
- RefPtr<ExpressionNode> m_value;
+ virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+
+ virtual bool isReturnNode() const override { return true; }
+
+ ExpressionNode* m_value;
};
class WithNode : public StatementNode {
public:
- WithNode(JSGlobalData* globalData, ExpressionNode* expr, StatementNode* statement, uint32_t divot, uint32_t expressionLength) JSC_FAST_CALL
- : StatementNode(globalData)
- , m_expr(expr)
- , m_statement(statement)
- , m_divot(divot)
- , m_expressionLength(expressionLength)
- {
- }
-
- virtual ~WithNode();
- virtual void releaseNodes(NodeReleaser&);
-
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+ WithNode(const JSTokenLocation&, ExpressionNode*, StatementNode*, const JSTextPosition& divot, uint32_t expressionLength);
private:
- RefPtr<ExpressionNode> m_expr;
- RefPtr<StatementNode> m_statement;
- uint32_t m_divot;
+ virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+
+ ExpressionNode* m_expr;
+ StatementNode* m_statement;
+ JSTextPosition m_divot;
uint32_t m_expressionLength;
};
class LabelNode : public StatementNode, public ThrowableExpressionData {
public:
- LabelNode(JSGlobalData* globalData, const Identifier& name, StatementNode* statement) JSC_FAST_CALL
- : StatementNode(globalData)
- , m_name(name)
- , m_statement(statement)
- {
- }
-
- virtual ~LabelNode();
- virtual void releaseNodes(NodeReleaser&);
-
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+ LabelNode(const JSTokenLocation&, const Identifier& name, StatementNode*);
private:
- Identifier m_name;
- RefPtr<StatementNode> m_statement;
+ virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+
+ const Identifier& m_name;
+ StatementNode* m_statement;
};
class ThrowNode : public StatementNode, public ThrowableExpressionData {
public:
- ThrowNode(JSGlobalData* globalData, ExpressionNode* expr) JSC_FAST_CALL
- : StatementNode(globalData)
- , m_expr(expr)
- {
- }
-
- virtual ~ThrowNode();
- virtual void releaseNodes(NodeReleaser&);
-
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+ ThrowNode(const JSTokenLocation&, ExpressionNode*);
private:
- RefPtr<ExpressionNode> m_expr;
+ virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+
+ ExpressionNode* m_expr;
};
class TryNode : public StatementNode {
public:
- TryNode(JSGlobalData* globalData, StatementNode* tryBlock, const Identifier& exceptionIdent, bool catchHasEval, StatementNode* catchBlock, StatementNode* finallyBlock) JSC_FAST_CALL
- : StatementNode(globalData)
- , m_tryBlock(tryBlock)
- , m_exceptionIdent(exceptionIdent)
- , m_catchBlock(catchBlock)
- , m_finallyBlock(finallyBlock)
- , m_catchHasEval(catchHasEval)
- {
- }
-
- virtual ~TryNode();
- virtual void releaseNodes(NodeReleaser&);
-
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* dst = 0) JSC_FAST_CALL;
+ TryNode(const JSTokenLocation&, StatementNode* tryBlock, const Identifier& exceptionIdent, StatementNode* catchBlock, StatementNode* finallyBlock);
private:
- RefPtr<StatementNode> m_tryBlock;
- Identifier m_exceptionIdent;
- RefPtr<StatementNode> m_catchBlock;
- RefPtr<StatementNode> m_finallyBlock;
- bool m_catchHasEval;
+ virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+
+ StatementNode* m_tryBlock;
+ const Identifier& m_thrownValueIdent;
+ StatementNode* m_catchBlock;
+ StatementNode* m_finallyBlock;
};
- class ParameterNode : public ParserRefCounted {
+ class ParameterNode : public ParserArenaDeletable {
public:
- ParameterNode(JSGlobalData* globalData, const Identifier& ident) JSC_FAST_CALL
- : ParserRefCounted(globalData)
- , m_ident(ident)
- {
- }
-
- ParameterNode(JSGlobalData* globalData, ParameterNode* l, const Identifier& ident) JSC_FAST_CALL
- : ParserRefCounted(globalData)
- , m_ident(ident)
- {
- l->m_next = this;
- }
+ ParameterNode(PassRefPtr<DestructuringPatternNode>);
+ ParameterNode(ParameterNode*, PassRefPtr<DestructuringPatternNode>);
- virtual ~ParameterNode();
- virtual void releaseNodes(NodeReleaser&);
-
- const Identifier& ident() const JSC_FAST_CALL { return m_ident; }
- ParameterNode* nextParam() const JSC_FAST_CALL { return m_next.get(); }
+ DestructuringPatternNode* pattern() const { return m_pattern.get(); }
+ ParameterNode* nextParam() const { return m_next; }
private:
- Identifier m_ident;
- RefPtr<ParameterNode> m_next;
- };
-
- struct ScopeNodeData {
- typedef DeclarationStacks::VarStack VarStack;
- typedef DeclarationStacks::FunctionStack FunctionStack;
-
- ScopeNodeData(SourceElements*, VarStack*, FunctionStack*, int numConstants);
-
- VarStack m_varStack;
- FunctionStack m_functionStack;
- int m_numConstants;
- StatementVector m_children;
-
- void mark();
+ RefPtr<DestructuringPatternNode> m_pattern;
+ ParameterNode* m_next;
};
- class ScopeNode : public StatementNode {
+ class ScopeNode : public StatementNode, public ParserArenaRoot {
public:
typedef DeclarationStacks::VarStack VarStack;
typedef DeclarationStacks::FunctionStack FunctionStack;
- ScopeNode(JSGlobalData*) JSC_FAST_CALL;
- ScopeNode(JSGlobalData*, const SourceCode&, SourceElements*, VarStack*, FunctionStack*, CodeFeatures, int numConstants) JSC_FAST_CALL;
- virtual ~ScopeNode();
- virtual void releaseNodes(NodeReleaser&);
+ ScopeNode(ParserArena&, const JSTokenLocation& start, const JSTokenLocation& end, bool inStrictContext);
+ ScopeNode(ParserArena&, const JSTokenLocation& start, const JSTokenLocation& end, const SourceCode&, SourceElements*, VarStack&, FunctionStack&, IdentifierSet&, CodeFeatures, int numConstants);
- void adoptData(std::auto_ptr<ScopeNodeData> data) { m_data.adopt(data); }
- ScopeNodeData* data() const { return m_data.get(); }
- void destroyData() { m_data.clear(); }
+ using ParserArenaRoot::operator new;
const SourceCode& source() const { return m_source; }
- const UString& sourceURL() const JSC_FAST_CALL { 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 usesEval() const { return m_features & EvalFeature; }
- bool usesArguments() const { return m_features & ArgumentsFeature; }
+ bool usesArguments() const { return (m_features & ArgumentsFeature) && !(m_features & ShadowsArgumentsFeature); }
+ bool modifiesParameter() const { return m_features & ModifiedParameterFeature; }
+ bool modifiesArguments() const { return m_features & (EvalFeature | ModifiedArgumentsFeature); }
+ bool isStrictMode() const { return m_features & StrictModeFeature; }
void setUsesArguments() { m_features |= ArgumentsFeature; }
bool usesThis() const { return m_features & ThisFeature; }
- bool needsActivation() const { return m_features & (EvalFeature | ClosureFeature | WithFeature | CatchFeature); }
+ 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(); }
+ const IdentifierSet& capturedVariables() const { return m_capturedVariables; }
+ bool captures(UniquedStringImpl* uid) { return m_capturedVariables.contains(uid); }
+ bool captures(const Identifier& ident) { return captures(ident.impl()); }
- VarStack& varStack() { ASSERT(m_data); return m_data->m_varStack; }
- FunctionStack& functionStack() { ASSERT(m_data); return m_data->m_functionStack; }
-
- StatementVector& children() { ASSERT(m_data); return m_data->m_children; }
+ 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;
}
- virtual void mark() { }
+ StatementNode* singleStatement() const;
+
+ void emitStatementsBytecode(BytecodeGenerator&, RegisterID* destination);
+
+ void setClosedVariables(Vector<RefPtr<UniquedStringImpl>>&&) { }
protected:
- void setSource(const SourceCode& source) { m_source = source; }
+ 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 ProgramNode* create(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, const SourceCode&, CodeFeatures, int numConstants) JSC_FAST_CALL;
+ ProgramNode(ParserArena&, const JSTokenLocation& start, const JSTokenLocation& end, unsigned startColumn, unsigned endColumn, SourceElements*, VarStack&, FunctionStack&, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
- ProgramCodeBlock& bytecode(ScopeChainNode* scopeChain) JSC_FAST_CALL
- {
- if (!m_code)
- generateBytecode(scopeChain);
- return *m_code;
- }
+ unsigned startColumn() const { return m_startColumn; }
+ unsigned endColumn() const { return m_endColumn; }
- private:
- ProgramNode(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, const SourceCode&, CodeFeatures, int numConstants) JSC_FAST_CALL;
+ static const bool scopeIsFunction = false;
- void generateBytecode(ScopeChainNode*) JSC_FAST_CALL;
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+ void setClosedVariables(Vector<RefPtr<UniquedStringImpl>>&&);
+ const Vector<RefPtr<UniquedStringImpl>>& closedVariables() const { return m_closedVariables; }
- OwnPtr<ProgramCodeBlock> m_code;
+ private:
+ virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+ Vector<RefPtr<UniquedStringImpl>> m_closedVariables;
+ unsigned m_startColumn;
+ unsigned m_endColumn;
};
class EvalNode : public ScopeNode {
public:
- static EvalNode* create(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, const SourceCode&, CodeFeatures, int numConstants) JSC_FAST_CALL;
-
- EvalCodeBlock& bytecode(ScopeChainNode* scopeChain) JSC_FAST_CALL
- {
- if (!m_code)
- generateBytecode(scopeChain);
- return *m_code;
- }
+ EvalNode(ParserArena&, const JSTokenLocation& start, const JSTokenLocation& end, unsigned startColumn, unsigned endColumn, SourceElements*, VarStack&, FunctionStack&, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
- EvalCodeBlock& bytecodeForExceptionInfoReparse(ScopeChainNode*, CodeBlock*) JSC_FAST_CALL;
+ ALWAYS_INLINE unsigned startColumn() const { return 0; }
+ unsigned endColumn() const { return m_endColumn; }
- virtual void mark();
+ static const bool scopeIsFunction = false;
private:
- EvalNode(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, const SourceCode&, CodeFeatures, int numConstants) JSC_FAST_CALL;
+ virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
- void generateBytecode(ScopeChainNode*) JSC_FAST_CALL;
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
-
- OwnPtr<EvalCodeBlock> m_code;
+ unsigned m_endColumn;
};
- class FunctionBodyNode : public ScopeNode {
- friend class JIT;
+ class FunctionParameters : public RefCounted<FunctionParameters> {
+ WTF_MAKE_FAST_ALLOCATED;
+ WTF_MAKE_NONCOPYABLE(FunctionParameters);
public:
- static FunctionBodyNode* create(JSGlobalData*) JSC_FAST_CALL;
- static FunctionBodyNode* create(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, const SourceCode&, CodeFeatures, int numConstants) JSC_FAST_CALL;
- virtual ~FunctionBodyNode();
+ static Ref<FunctionParameters> create(ParameterNode*);
+ ~FunctionParameters();
- const Identifier* parameters() const JSC_FAST_CALL { return m_parameters; }
- size_t parameterCount() const { return m_parameterCount; }
- UString paramString() const JSC_FAST_CALL;
- Identifier* copyParameters();
+ unsigned size() const { return m_size; }
+ DestructuringPatternNode* at(unsigned index) { ASSERT(index < m_size); return patterns()[index]; }
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
-
- CodeBlock& bytecode(ScopeChainNode* scopeChain) JSC_FAST_CALL
- {
- ASSERT(scopeChain);
- if (!m_code)
- generateBytecode(scopeChain);
- return *m_code;
- }
+ private:
+ FunctionParameters(ParameterNode*, unsigned size);
- CodeBlock& generatedBytecode() JSC_FAST_CALL
- {
- ASSERT(m_code);
- return *m_code;
- }
+ DestructuringPatternNode** patterns() { return &m_storage; }
- bool isGenerated() JSC_FAST_CALL
- {
- return m_code;
- }
+ unsigned m_size;
+ DestructuringPatternNode* m_storage;
+ };
+
+ class FunctionBodyNode final : public StatementNode, public ParserArenaDeletable {
+ public:
+ using ParserArenaDeletable::operator new;
+
+ FunctionBodyNode(
+ ParserArena&, const JSTokenLocation& start, const JSTokenLocation& end,
+ unsigned startColumn, unsigned endColumn, int functionKeywordStart,
+ int functionNameStart, int parametersStart, bool isInStrictContext,
+ ConstructorKind);
- virtual void mark();
+ FunctionParameters* parameters() const { return m_parameters.get(); }
- void finishParsing(const SourceCode&, ParameterNode*);
- void finishParsing(Identifier* parameters, size_t parameterCount);
+ virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+
+ void finishParsing(const SourceCode&, ParameterNode*, const Identifier&, FunctionMode);
- UString toSourceString() const JSC_FAST_CALL { return source().toString(); }
+ void overrideName(const Identifier& ident) { m_ident = ident; }
+ 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; }
- // These objects are ref/deref'd a lot in the scope chain, so this is a faster ref/deref.
- // If the virtual machine changes so this doesn't happen as much we can change back.
- void ref()
- {
- if (++m_refCount == 1)
- ScopeNode::ref();
- }
- void deref()
- {
- ASSERT(m_refCount);
- if (!--m_refCount)
- ScopeNode::deref();
- }
+ FunctionMode functionMode() { return m_functionMode; }
- CodeBlock& bytecodeForExceptionInfoReparse(ScopeChainNode*, CodeBlock*) JSC_FAST_CALL;
+ int functionNameStart() const { return m_functionNameStart; }
+ int functionKeywordStart() const { return m_functionKeywordStart; }
+ int parametersStart() const { return m_parametersStart; }
+ unsigned startColumn() const { return m_startColumn; }
+ unsigned endColumn() const { return m_endColumn; }
- private:
- FunctionBodyNode(JSGlobalData*) JSC_FAST_CALL;
- FunctionBodyNode(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, const SourceCode&, CodeFeatures, int numConstants) JSC_FAST_CALL;
+ void setEndPosition(JSTextPosition);
- void generateBytecode(ScopeChainNode*) JSC_FAST_CALL;
+ const SourceCode& source() const { return m_source; }
+
+ int startStartOffset() const { return m_startStartOffset; }
+ bool isInStrictContext() const { return m_isInStrictContext; }
+ ConstructorKind constructorKind() { return static_cast<ConstructorKind>(m_constructorKind); }
- Identifier* m_parameters;
- size_t m_parameterCount;
- OwnPtr<CodeBlock> m_code;
- unsigned m_refCount;
+ protected:
+ Identifier m_ident;
+ Identifier m_inferredName;
+ FunctionMode m_functionMode;
+ RefPtr<FunctionParameters> m_parameters;
+ unsigned m_startColumn;
+ unsigned m_endColumn;
+ int m_functionKeywordStart;
+ int m_functionNameStart;
+ int m_parametersStart;
+ SourceCode m_source;
+ int m_startStartOffset;
+ unsigned m_isInStrictContext : 1;
+ unsigned m_constructorKind : 2;
};
- class FuncExprNode : public ExpressionNode {
+ class FunctionNode final : public ScopeNode {
public:
- FuncExprNode(JSGlobalData* globalData, const Identifier& ident, FunctionBodyNode* body, const SourceCode& source, ParameterNode* parameter = 0) JSC_FAST_CALL
- : ExpressionNode(globalData)
- , m_ident(ident)
- , m_parameter(parameter)
- , m_body(body)
- {
- m_body->finishParsing(source, m_parameter.get());
- }
+ FunctionNode(ParserArena&, const JSTokenLocation& start, const JSTokenLocation& end, unsigned startColumn, unsigned endColumn, SourceElements*, VarStack&, FunctionStack&, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
+
+ FunctionParameters* parameters() const { return m_parameters.get(); }
- virtual ~FuncExprNode();
- virtual void releaseNodes(NodeReleaser&);
+ virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+
+ void finishParsing(PassRefPtr<FunctionParameters>, const Identifier&, FunctionMode);
+
+ const Identifier& ident() { return m_ident; }
- virtual bool isFuncExprNode() const JSC_FAST_CALL { return true; }
+ FunctionMode functionMode() { return m_functionMode; }
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
- JSFunction* makeFunction(ExecState*, ScopeChainNode*) JSC_FAST_CALL;
+ unsigned startColumn() const { return m_startColumn; }
+ unsigned endColumn() const { return m_endColumn; }
- FunctionBodyNode* body() { return m_body.get(); }
+ static const bool scopeIsFunction = true;
private:
Identifier m_ident;
- RefPtr<ParameterNode> m_parameter;
- RefPtr<FunctionBodyNode> m_body;
+ FunctionMode m_functionMode;
+ RefPtr<FunctionParameters> m_parameters;
+ unsigned m_startColumn;
+ unsigned m_endColumn;
};
- class FuncDeclNode : public StatementNode {
+ class FuncExprNode : public ExpressionNode {
public:
- FuncDeclNode(JSGlobalData* globalData, const Identifier& ident, FunctionBodyNode* body, const SourceCode& source, ParameterNode* parameter = 0) JSC_FAST_CALL
- : StatementNode(globalData)
- , m_ident(ident)
- , m_parameter(parameter)
- , m_body(body)
- {
- m_body->finishParsing(source, m_parameter.get());
- }
+ FuncExprNode(const JSTokenLocation&, const Identifier&, FunctionBodyNode*, const SourceCode&, ParameterNode* = 0);
- virtual ~FuncDeclNode();
- virtual void releaseNodes(NodeReleaser&);
+ FunctionBodyNode* body() { return m_body; }
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+ private:
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
- JSFunction* makeFunction(ExecState*, ScopeChainNode*) JSC_FAST_CALL;
+ virtual bool isFuncExprNode() const override { return true; }
- Identifier m_ident;
+ FunctionBodyNode* m_body;
+ };
- FunctionBodyNode* body() { return m_body.get(); }
+#if ENABLE(ES6_CLASS_SYNTAX)
+ class ClassExprNode final : public ExpressionNode {
+ public:
+ ClassExprNode(const JSTokenLocation&, const Identifier&, ExpressionNode* constructorExpresssion,
+ ExpressionNode* parentClass, PropertyListNode* instanceMethods, PropertyListNode* staticMethods);
+
+ const Identifier& name() { return m_name; }
private:
- RefPtr<ParameterNode> m_parameter;
- RefPtr<FunctionBodyNode> m_body;
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+
+ const Identifier& m_name;
+ ExpressionNode* m_constructorExpression;
+ ExpressionNode* m_classHeritage;
+ PropertyListNode* m_instanceMethods;
+ PropertyListNode* m_staticMethods;
};
+#endif
+
+ class DestructuringPatternNode : public RefCounted<DestructuringPatternNode> {
+ WTF_MAKE_NONCOPYABLE(DestructuringPatternNode);
+ WTF_MAKE_FAST_ALLOCATED;
- class CaseClauseNode : public ParserRefCounted {
public:
- CaseClauseNode(JSGlobalData* globalData, ExpressionNode* expr) JSC_FAST_CALL
- : ParserRefCounted(globalData)
- , m_expr(expr)
+ virtual void collectBoundIdentifiers(Vector<Identifier>&) const = 0;
+ virtual void bindValue(BytecodeGenerator&, RegisterID* source) const = 0;
+ virtual void toString(StringBuilder&) const = 0;
+
+ virtual bool isBindingNode() const { return false; }
+ virtual RegisterID* emitDirectBinding(BytecodeGenerator&, RegisterID*, ExpressionNode*) { return 0; }
+
+ virtual ~DestructuringPatternNode() = 0;
+
+ protected:
+ DestructuringPatternNode();
+ };
+
+ class ArrayPatternNode : public DestructuringPatternNode, public ThrowableExpressionData {
+ public:
+ enum class BindingType {
+ Elision,
+ Element,
+ RestElement
+ };
+
+ static Ref<ArrayPatternNode> create();
+ void appendIndex(BindingType bindingType, const JSTokenLocation&, DestructuringPatternNode* node, ExpressionNode* defaultValue)
{
+ m_targetPatterns.append({ bindingType, node, defaultValue });
}
- CaseClauseNode(JSGlobalData* globalData, ExpressionNode* expr, SourceElements* children) JSC_FAST_CALL
- : ParserRefCounted(globalData)
- , m_expr(expr)
+ private:
+ struct Entry {
+ BindingType bindingType;
+ RefPtr<DestructuringPatternNode> pattern;
+ ExpressionNode* defaultValue;
+ };
+ ArrayPatternNode();
+ virtual void collectBoundIdentifiers(Vector<Identifier>&) const override;
+ virtual void bindValue(BytecodeGenerator&, RegisterID*) const override;
+ virtual RegisterID* emitDirectBinding(BytecodeGenerator&, RegisterID* dst, ExpressionNode*) override;
+ virtual void toString(StringBuilder&) const override;
+
+ Vector<Entry> m_targetPatterns;
+ };
+
+ class ObjectPatternNode : public DestructuringPatternNode {
+ public:
+ static Ref<ObjectPatternNode> create();
+ void appendEntry(const JSTokenLocation&, const Identifier& identifier, bool wasString, DestructuringPatternNode* pattern, ExpressionNode* defaultValue)
{
- if (children)
- children->releaseContentsIntoVector(m_children);
+ m_targetPatterns.append(Entry{ identifier, wasString, pattern, defaultValue });
}
+
+ private:
+ ObjectPatternNode();
+ virtual void collectBoundIdentifiers(Vector<Identifier>&) const override;
+ virtual void bindValue(BytecodeGenerator&, RegisterID*) const override;
+ virtual void toString(StringBuilder&) const override;
+ struct Entry {
+ Identifier propertyName;
+ bool wasString;
+ RefPtr<DestructuringPatternNode> pattern;
+ ExpressionNode* defaultValue;
+ };
+ Vector<Entry> m_targetPatterns;
+ };
- virtual ~CaseClauseNode();
- virtual void releaseNodes(NodeReleaser&);
+ class BindingNode : public DestructuringPatternNode {
+ public:
+ static Ref<BindingNode> create(const Identifier& boundProperty, const JSTextPosition& start, const JSTextPosition& end);
+ const Identifier& boundProperty() const { return m_boundProperty; }
- ExpressionNode* expr() const { return m_expr.get(); }
- StatementVector& children() { return m_children; }
+ const JSTextPosition& divotStart() const { return m_divotStart; }
+ const JSTextPosition& divotEnd() const { return m_divotEnd; }
+
+ private:
+ BindingNode(const Identifier& boundProperty, const JSTextPosition& start, const JSTextPosition& end);
+
+ virtual void collectBoundIdentifiers(Vector<Identifier>&) const override;
+ virtual void bindValue(BytecodeGenerator&, RegisterID*) const override;
+ virtual void toString(StringBuilder&) const override;
+
+ virtual bool isBindingNode() const override { return true; }
+
+ JSTextPosition m_divotStart;
+ JSTextPosition m_divotEnd;
+ Identifier m_boundProperty;
+ };
+
+ class DestructuringAssignmentNode : public ExpressionNode, public ParserArenaDeletable {
+ public:
+ DestructuringAssignmentNode(const JSTokenLocation&, PassRefPtr<DestructuringPatternNode>, ExpressionNode*);
+ DestructuringPatternNode* bindings() { return m_bindings.get(); }
+
+ using ParserArenaDeletable::operator new;
private:
- RefPtr<ExpressionNode> m_expr;
- StatementVector m_children;
+ virtual bool isAssignmentLocation() const override { return true; }
+ virtual bool isDestructuringNode() const override { return true; }
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+
+ RefPtr<DestructuringPatternNode> m_bindings;
+ ExpressionNode* m_initializer;
};
- class ClauseListNode : public ParserRefCounted {
+ class FuncDeclNode : public StatementNode {
public:
- ClauseListNode(JSGlobalData* globalData, CaseClauseNode* clause) JSC_FAST_CALL
- : ParserRefCounted(globalData)
- , m_clause(clause)
- {
- }
+ FuncDeclNode(const JSTokenLocation&, const Identifier&, FunctionBodyNode*, const SourceCode&, ParameterNode* = 0);
- ClauseListNode(JSGlobalData* globalData, ClauseListNode* clauseList, CaseClauseNode* clause) JSC_FAST_CALL
- : ParserRefCounted(globalData)
- , m_clause(clause)
- {
- clauseList->m_next = this;
- }
+ virtual bool isFuncDeclNode() const override { return true; }
+ FunctionBodyNode* body() { return m_body; }
- virtual ~ClauseListNode();
- virtual void releaseNodes(NodeReleaser&);
+ private:
+ virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
- CaseClauseNode* getClause() const JSC_FAST_CALL { return m_clause.get(); }
- ClauseListNode* getNext() const JSC_FAST_CALL { return m_next.get(); }
+ FunctionBodyNode* m_body;
+ };
+
+#if ENABLE(ES6_CLASS_SYNTAX)
+ class ClassDeclNode final : public StatementNode {
+ public:
+ ClassDeclNode(const JSTokenLocation&, ExpressionNode* classExpression);
private:
- RefPtr<CaseClauseNode> m_clause;
- RefPtr<ClauseListNode> m_next;
+ virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+
+ ExpressionNode* m_classDeclaration;
};
+#endif
- class CaseBlockNode : public ParserRefCounted {
+ class CaseClauseNode : public ParserArenaFreeable {
public:
- CaseBlockNode(JSGlobalData* globalData, ClauseListNode* list1, CaseClauseNode* defaultClause, ClauseListNode* list2) JSC_FAST_CALL
- : ParserRefCounted(globalData)
- , m_list1(list1)
- , m_defaultClause(defaultClause)
- , m_list2(list2)
- {
- }
+ CaseClauseNode(ExpressionNode*, SourceElements* = 0);
- virtual ~CaseBlockNode();
- virtual void releaseNodes(NodeReleaser&);
+ ExpressionNode* expr() const { return m_expr; }
- RegisterID* emitBytecodeForBlock(BytecodeGenerator&, RegisterID* input, RegisterID* dst = 0) JSC_FAST_CALL;
+ void emitBytecode(BytecodeGenerator&, RegisterID* destination);
+ void setStartOffset(int offset) { m_startOffset = offset; }
private:
- SwitchInfo::SwitchType tryOptimizedSwitch(Vector<ExpressionNode*, 8>& literalVector, int32_t& min_num, int32_t& max_num);
- RefPtr<ClauseListNode> m_list1;
- RefPtr<CaseClauseNode> m_defaultClause;
- RefPtr<ClauseListNode> m_list2;
+ ExpressionNode* m_expr;
+ SourceElements* m_statements;
+ int m_startOffset;
};
- class SwitchNode : public StatementNode {
+ class ClauseListNode : public ParserArenaFreeable {
public:
- SwitchNode(JSGlobalData* globalData, ExpressionNode* expr, CaseBlockNode* block) JSC_FAST_CALL
- : StatementNode(globalData)
- , m_expr(expr)
- , m_block(block)
- {
- }
+ ClauseListNode(CaseClauseNode*);
+ ClauseListNode(ClauseListNode*, CaseClauseNode*);
+
+ CaseClauseNode* getClause() const { return m_clause; }
+ ClauseListNode* getNext() const { return m_next; }
- virtual ~SwitchNode();
- virtual void releaseNodes(NodeReleaser&);
+ private:
+ CaseClauseNode* m_clause;
+ ClauseListNode* m_next;
+ };
+
+ class CaseBlockNode : public ParserArenaFreeable {
+ public:
+ CaseBlockNode(ClauseListNode* list1, CaseClauseNode* defaultClause, ClauseListNode* list2);
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+ void emitBytecodeForBlock(BytecodeGenerator&, RegisterID* input, RegisterID* destination);
private:
- RefPtr<ExpressionNode> m_expr;
- RefPtr<CaseBlockNode> m_block;
+ SwitchInfo::SwitchType tryTableSwitch(Vector<ExpressionNode*, 8>& literalVector, int32_t& min_num, int32_t& max_num);
+ static const size_t s_tableSwitchMinimum = 3;
+ ClauseListNode* m_list1;
+ CaseClauseNode* m_defaultClause;
+ ClauseListNode* m_list2;
+ };
+
+ class SwitchNode : public StatementNode {
+ public:
+ SwitchNode(const JSTokenLocation&, ExpressionNode*, CaseBlockNode*);
+
+ private:
+ virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+
+ ExpressionNode* m_expr;
+ CaseBlockNode* m_block;
};
struct ElementList {
} // namespace JSC
-#endif // NODES_H_
+#endif // Nodes_h