/*
* 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, 2013 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>
};
inline FallThroughMode invert(FallThroughMode fallThroughMode) { return static_cast<FallThroughMode>(!fallThroughMode); }
- typedef HashSet<RefPtr<StringImpl>, IdentifierRepHash> IdentifierSet;
+ typedef HashSet<RefPtr<UniquedStringImpl>, IdentifierRepHash> IdentifierSet;
namespace DeclarationStacks {
enum VarAttrs { IsConstant = 1, HasInitializer = 2 };
public:
// ParserArenaFreeable objects are are freed when the arena is deleted.
// Destructors are not called. Clients must not call delete on such objects.
- void* operator new(size_t, VM*);
+ void* operator new(size_t, ParserArena&);
};
class ParserArenaDeletable {
// ParserArenaDeletable objects are deleted when the arena is deleted.
// Clients must not call delete directly on such objects.
- void* operator new(size_t, VM*);
+ void* operator new(size_t, ParserArena&);
};
- template <typename T>
- struct ParserArenaData : ParserArenaDeletable {
- T data;
- };
-
- class ParserArenaRefCounted : public RefCounted<ParserArenaRefCounted> {
+ class ParserArenaRoot {
WTF_MAKE_FAST_ALLOCATED;
protected:
- ParserArenaRefCounted(VM*);
+ ParserArenaRoot(ParserArena&);
public:
- virtual ~ParserArenaRefCounted()
- {
- ASSERT(deletionHasBegun());
- }
+ ParserArena& parserArena() { return m_arena; }
+ virtual ~ParserArenaRoot() { }
+
+ protected:
+ ParserArena m_arena;
};
class Node : public ParserArenaFreeable {
public:
virtual ~Node() { }
- int lineNo() const { return m_position.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:
JSTextPosition m_position;
+ int m_endOffset;
};
class ExpressionNode : public Node {
virtual bool isResolveNode() const { return false; }
virtual bool isBracketAccessorNode() const { return false; }
virtual bool isDotAccessorNode() const { return false; }
- virtual bool isDeconstructionNode() 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 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 void emitBytecode(BytecodeGenerator&, RegisterID* destination = 0) = 0;
void setLoc(unsigned firstLine, unsigned lastLine, int startOffset, int lineStartOffset);
- unsigned firstLine() const { return lineNo(); }
unsigned lastLine() const { return m_lastLine; }
+ StatementNode* next() { return m_next; }
+ void setNext(StatementNode* next) { m_next = next; }
+
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 NumberNode : public ConstantNode {
public:
NumberNode(const JSTokenLocation&, double value);
- double value() { return m_value; }
- void setValue(double value) { m_value = 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 { return true; }
+ virtual bool isNumber() const override final { return true; }
virtual JSValue jsValue(BytecodeGenerator&) const override { return jsNumber(m_value); }
double m_value;
};
+ class DoubleNode : public NumberNode {
+ public:
+ DoubleNode(const JSTokenLocation&, double value);
+
+ private:
+ virtual bool isIntegerNode() const override { return false; }
+ };
+
+ // An integer node represent a number represented as an integer (e.g. 42 instead of 42., 42.0, 42e0)
+ class IntegerNode : public DoubleNode {
+ public:
+ IntegerNode(const JSTokenLocation&, double value);
+ virtual bool isIntegerNode() const override final { return true; }
+ };
+
class StringNode : public ConstantNode {
public:
StringNode(const JSTokenLocation&, const Identifier&);
const Identifier& m_value;
};
-
+
class ThrowableExpressionData {
public:
ThrowableExpressionData()
uint16_t m_subexpressionLineStartOffset;
};
+#if ENABLE(ES6_TEMPLATE_LITERAL_SYNTAX)
+ class TemplateExpressionListNode : public ParserArenaFreeable {
+ public:
+ TemplateExpressionListNode(ExpressionNode*);
+ TemplateExpressionListNode(TemplateExpressionListNode*, ExpressionNode*);
+
+ ExpressionNode* value() { return m_node; }
+ TemplateExpressionListNode* next() { return m_next; }
+
+ private:
+ TemplateExpressionListNode* m_next { nullptr };
+ ExpressionNode* m_node { nullptr };
+ };
+
+ class TemplateStringNode : public ExpressionNode {
+ public:
+ TemplateStringNode(const JSTokenLocation&, const Identifier& cooked, const Identifier& raw);
+
+ 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 TemplateStringListNode : public ParserArenaFreeable {
+ public:
+ TemplateStringListNode(TemplateStringNode*);
+ TemplateStringListNode(TemplateStringListNode*, TemplateStringNode*);
+
+ TemplateStringNode* value() { return m_node; }
+ TemplateStringListNode* next() { return m_next; }
+
+ private:
+ TemplateStringListNode* m_next { nullptr };
+ TemplateStringNode* m_node { nullptr };
+ };
+
+ class TemplateLiteralNode : public ExpressionNode {
+ public:
+ TemplateLiteralNode(const JSTokenLocation&, TemplateStringListNode*);
+ TemplateLiteralNode(const JSTokenLocation&, TemplateStringListNode*, TemplateExpressionListNode*);
+
+ TemplateStringListNode* templateStrings() const { return m_templateStrings; }
+ TemplateExpressionListNode* templateExpressions() const { return m_templateExpressions; }
+
+ private:
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+
+ TemplateStringListNode* m_templateStrings;
+ TemplateExpressionListNode* m_templateExpressions;
+ };
+
+ class TaggedTemplateNode : public ExpressionNode, public ThrowableExpressionData {
+ public:
+ TaggedTemplateNode(const JSTokenLocation&, ExpressionNode*, TemplateLiteralNode*);
+
+ TemplateLiteralNode* templateLiteral() const { return m_templateLiteral; }
+
+ private:
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+
+ ExpressionNode* m_tag;
+ TemplateLiteralNode* m_templateLiteral;
+ };
+#endif
+
class RegExpNode : public ExpressionNode, public ThrowableExpressionData {
public:
RegExpNode(const JSTokenLocation&, const Identifier& pattern, const Identifier& flags);
class ThisNode : public ExpressionNode {
public:
- ThisNode(const JSTokenLocation&);
+ ThisNode(const JSTokenLocation&, ThisTDZMode);
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+
+ 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;
};
class ResolveNode : public ExpressionNode {
ArrayNode(const JSTokenLocation&, ElementNode*);
ArrayNode(const JSTokenLocation&, int elision, ElementNode*);
- ArgumentListNode* toArgumentList(VM*, int, int) const;
+ ArgumentListNode* toArgumentList(ParserArena&, int, int) const;
ElementNode* elements() const { ASSERT(isSimpleArray()); return m_element; }
private:
class PropertyNode : public ParserArenaFreeable {
public:
- enum Type { Constant = 1, Getter = 2, Setter = 4 };
+ enum Type { Constant = 1, Getter = 2, Setter = 4, Computed = 8, Shorthand = 16 };
+ enum PutType { Unknown, KnownDirect };
+
+ PropertyNode(const Identifier&, ExpressionNode*, Type, PutType, SuperBinding);
+ PropertyNode(ExpressionNode* propertyName, ExpressionNode*, Type, PutType);
- PropertyNode(VM*, const Identifier&, ExpressionNode*, Type);
- PropertyNode(VM*, double, ExpressionNode*, Type);
- PropertyNode(VM*, ExpressionNode* propertyName, ExpressionNode*, Type);
-
ExpressionNode* expressionName() const { return m_expression; }
const Identifier* name() const { return m_name; }
- Type type() const { return m_type; }
+ 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:
friend class PropertyListNode;
const Identifier* m_name;
ExpressionNode* m_expression;
ExpressionNode* m_assign;
- Type m_type;
+ unsigned m_type : 5;
+ unsigned m_needsSuperBinding : 1;
+ unsigned m_putType : 1;
};
class PropertyListNode : public ExpressionNode {
PropertyListNode(const JSTokenLocation&, PropertyNode*);
PropertyListNode(const JSTokenLocation&, PropertyNode*, PropertyListNode*);
+ private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+ void emitPutConstantProperty(BytecodeGenerator&, RegisterID*, PropertyNode&);
- private:
PropertyNode* m_node;
PropertyListNode* m_next;
};
class FunctionCallBracketNode : public ExpressionNode, public ThrowableSubExpressionData {
public:
- FunctionCallBracketNode(const JSTokenLocation&, ExpressionNode* base, ExpressionNode* subscript, ArgumentsNode*, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
+ FunctionCallBracketNode(const JSTokenLocation&, ExpressionNode* base, ExpressionNode* subscript, bool subscriptHasAssignments, ArgumentsNode*, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
private:
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 {
ArgumentsNode* m_args;
};
+ class BytecodeIntrinsicNode : public ExpressionNode, public ThrowableExpressionData {
+ public:
+ typedef RegisterID* (BytecodeIntrinsicNode::* EmitterType)(BytecodeGenerator&, RegisterID*);
+
+ BytecodeIntrinsicNode(const JSTokenLocation&, EmitterType, const Identifier&, ArgumentsNode*, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
+
+ const Identifier& identifier() const { return m_ident; }
+
+#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:
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+
+ EmitterType m_emitter;
+ const Identifier& m_ident;
+ ArgumentsNode* m_args;
+ };
+
class CallFunctionCallDotNode : public FunctionCallDotNode {
public:
CallFunctionCallDotNode(const JSTokenLocation&, ExpressionNode* base, const Identifier&, ArgumentsNode*, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
};
- typedef Vector<ExpressionNode*, 8> ExpressionVector;
-
- class CommaNode : public ExpressionNode, public ParserArenaDeletable {
+ class CommaNode final : public ExpressionNode {
public:
- CommaNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2);
+ CommaNode(const JSTokenLocation&, ExpressionNode*);
- using ParserArenaDeletable::operator new;
-
- void append(ExpressionNode* expr) { ASSERT(expr); m_expressions.append(expr); }
+ void setNext(CommaNode* next) { m_next = next; }
+ CommaNode* next() { return m_next; }
private:
virtual bool isCommaNode() const override { return true; }
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
- ExpressionVector m_expressions;
+ ExpressionNode* m_expr;
+ CommaNode* m_next;
};
class ConstDeclNode : public ExpressionNode {
ConstDeclNode* m_next;
};
- class SourceElements : public ParserArenaDeletable {
+ class SourceElements final : public ParserArenaFreeable {
public:
SourceElements();
void emitBytecode(BytecodeGenerator&, RegisterID* destination);
private:
- Vector<StatementNode*> m_statements;
+ StatementNode* m_head;
+ StatementNode* m_tail;
};
class BlockNode : public StatementNode {
ExpressionNode* m_expr;
};
+ class EmptyVarExpression : public ExpressionNode {
+ public:
+ EmptyVarExpression(const JSTokenLocation&, const Identifier&);
+
+ private:
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+
+ const Identifier& m_ident;
+ };
+
+
class IfElseNode : public StatementNode {
public:
IfElseNode(const JSTokenLocation&, ExpressionNode* condition, StatementNode* ifBlock, StatementNode* elseBlock);
StatementNode* m_statement;
};
- class DeconstructionPatternNode;
+ class DestructuringPatternNode;
class EnumerationNode : public StatementNode, public ThrowableExpressionData {
public:
EnumerationNode(const JSTokenLocation&, ExpressionNode*, ExpressionNode*, StatementNode*);
- EnumerationNode(VM*, const JSTokenLocation&, DeconstructionPatternNode*, ExpressionNode*, StatementNode*);
protected:
ExpressionNode* m_lexpr;
class ForInNode : public EnumerationNode {
public:
ForInNode(const JSTokenLocation&, ExpressionNode*, ExpressionNode*, StatementNode*);
- ForInNode(VM*, const JSTokenLocation&, DeconstructionPatternNode*, ExpressionNode*, StatementNode*);
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*);
- ForOfNode(VM*, const JSTokenLocation&, DeconstructionPatternNode*, ExpressionNode*, StatementNode*);
private:
virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
class ContinueNode : public StatementNode, public ThrowableExpressionData {
public:
- ContinueNode(VM*, const JSTokenLocation&);
ContinueNode(const JSTokenLocation&, const Identifier&);
Label* trivialTarget(BytecodeGenerator&);
class BreakNode : public StatementNode, public ThrowableExpressionData {
public:
- BreakNode(VM*, const JSTokenLocation&);
BreakNode(const JSTokenLocation&, const Identifier&);
Label* trivialTarget(BytecodeGenerator&);
virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
StatementNode* m_tryBlock;
- const Identifier& m_exceptionIdent;
+ const Identifier& m_thrownValueIdent;
StatementNode* m_catchBlock;
StatementNode* m_finallyBlock;
};
class ParameterNode : public ParserArenaDeletable {
public:
- ParameterNode(PassRefPtr<DeconstructionPatternNode>);
- ParameterNode(ParameterNode*, PassRefPtr<DeconstructionPatternNode>);
+ ParameterNode(PassRefPtr<DestructuringPatternNode>);
+ ParameterNode(ParameterNode*, PassRefPtr<DestructuringPatternNode>);
- DeconstructionPatternNode* pattern() const { return m_pattern.get(); }
+ DestructuringPatternNode* pattern() const { return m_pattern.get(); }
ParameterNode* nextParam() const { return m_next; }
private:
- RefPtr<DeconstructionPatternNode> m_pattern;
+ RefPtr<DestructuringPatternNode> m_pattern;
ParameterNode* m_next;
};
- class ScopeNode : public StatementNode, public ParserArenaRefCounted {
+ class ScopeNode : public StatementNode, public ParserArenaRoot {
public:
typedef DeclarationStacks::VarStack VarStack;
typedef DeclarationStacks::FunctionStack FunctionStack;
- ScopeNode(VM*, const JSTokenLocation& start, const JSTokenLocation& end, bool inStrictContext);
- ScopeNode(VM*, const JSTokenLocation& start, const JSTokenLocation& end, const SourceCode&, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, CodeFeatures, int numConstants);
+ 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);
- using ParserArenaRefCounted::operator new;
-
- void destroyData()
- {
- m_arena.reset();
- m_varStack.clear();
- m_functionStack.clear();
- m_statements = 0;
- m_capturedVariables.clear();
- }
+ using ParserArenaRoot::operator new;
const SourceCode& source() const { return m_source; }
const String& sourceURL() const { return m_source.provider()->url(); }
bool usesEval() const { return m_features & EvalFeature; }
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 hasCapturedVariables() const { return !!m_capturedVariables.size(); }
size_t capturedVariableCount() const { return m_capturedVariables.size(); }
const IdentifierSet& capturedVariables() const { return m_capturedVariables; }
- bool captures(const Identifier& ident) { return m_capturedVariables.contains(ident.impl()); }
+ bool captures(UniquedStringImpl* uid) { return m_capturedVariables.contains(uid); }
+ bool captures(const Identifier& ident) { return captures(ident.impl()); }
VarStack& varStack() { return m_varStack; }
FunctionStack& functionStack() { return m_functionStack; }
void emitStatementsBytecode(BytecodeGenerator&, RegisterID* destination);
- void setClosedVariables(Vector<RefPtr<StringImpl>>&&) { }
+ void setClosedVariables(Vector<RefPtr<UniquedStringImpl>>&&) { }
protected:
- void setSource(const SourceCode& source) { m_source = source; }
- ParserArena m_arena;
-
int m_startLineNumber;
unsigned m_startStartOffset;
unsigned m_startLineStartOffset;
class ProgramNode : public ScopeNode {
public:
- static const bool isFunctionNode = false;
- static PassRefPtr<ProgramNode> create(VM*, const JSTokenLocation& start, const JSTokenLocation& end, unsigned startColumn, unsigned endColumn, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
+ ProgramNode(ParserArena&, const JSTokenLocation& start, const JSTokenLocation& end, unsigned startColumn, unsigned endColumn, SourceElements*, VarStack&, FunctionStack&, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
unsigned startColumn() const { return m_startColumn; }
unsigned endColumn() const { return m_endColumn; }
static const bool scopeIsFunction = false;
- void setClosedVariables(Vector<RefPtr<StringImpl>>&&);
- const Vector<RefPtr<StringImpl>>& closedVariables() const { return m_closedVariables; }
- private:
- ProgramNode(VM*, const JSTokenLocation& start, const JSTokenLocation& end, unsigned startColumn, unsigned endColumn, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
+ void setClosedVariables(Vector<RefPtr<UniquedStringImpl>>&&);
+ const Vector<RefPtr<UniquedStringImpl>>& closedVariables() const { return m_closedVariables; }
+ private:
virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
- Vector<RefPtr<StringImpl>> m_closedVariables;
+ Vector<RefPtr<UniquedStringImpl>> m_closedVariables;
unsigned m_startColumn;
unsigned m_endColumn;
};
class EvalNode : public ScopeNode {
public:
- static const bool isFunctionNode = false;
- static PassRefPtr<EvalNode> create(VM*, const JSTokenLocation& start, const JSTokenLocation& end, unsigned, unsigned endColumn, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
+ EvalNode(ParserArena&, const JSTokenLocation& start, const JSTokenLocation& end, unsigned startColumn, unsigned endColumn, SourceElements*, VarStack&, FunctionStack&, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
ALWAYS_INLINE unsigned startColumn() const { return 0; }
unsigned endColumn() const { return m_endColumn; }
static const bool scopeIsFunction = false;
private:
- EvalNode(VM*, const JSTokenLocation& start, const JSTokenLocation& end, unsigned endColumn, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
-
virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
unsigned m_endColumn;
WTF_MAKE_FAST_ALLOCATED;
WTF_MAKE_NONCOPYABLE(FunctionParameters);
public:
- static PassRefPtr<FunctionParameters> create(ParameterNode*);
+ static Ref<FunctionParameters> create(ParameterNode*);
~FunctionParameters();
unsigned size() const { return m_size; }
- DeconstructionPatternNode* at(unsigned index) { ASSERT(index < m_size); return patterns()[index]; }
+ DestructuringPatternNode* at(unsigned index) { ASSERT(index < m_size); return patterns()[index]; }
private:
FunctionParameters(ParameterNode*, unsigned size);
- DeconstructionPatternNode** patterns() { return &m_storage; }
+ DestructuringPatternNode** patterns() { return &m_storage; }
unsigned m_size;
- DeconstructionPatternNode* m_storage;
+ DestructuringPatternNode* m_storage;
};
- class FunctionBodyNode : public ScopeNode {
+ class FunctionBodyNode final : public StatementNode, public ParserArenaDeletable {
public:
- static const bool isFunctionNode = true;
- static FunctionBodyNode* create(VM*, const JSTokenLocation& start, const JSTokenLocation& end, unsigned startColumn, unsigned endColumn, bool isStrictMode);
- static PassRefPtr<FunctionBodyNode> create(VM*, const JSTokenLocation& start, const JSTokenLocation& end, unsigned startColumn, unsigned endColumn, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
+ 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);
FunctionParameters* parameters() const { return m_parameters.get(); }
- size_t parameterCount() const { return m_parameters->size(); }
virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
void finishParsing(const SourceCode&, ParameterNode*, const Identifier&, FunctionMode);
- void finishParsing(PassRefPtr<FunctionParameters>, const Identifier&, FunctionMode);
void overrideName(const Identifier& ident) { m_ident = ident; }
const Identifier& ident() { return m_ident; }
FunctionMode functionMode() { return m_functionMode; }
- void setFunctionNameStart(int functionNameStart) { m_functionNameStart = functionNameStart; }
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; }
void setEndPosition(JSTextPosition);
- static const bool scopeIsFunction = true;
+ const SourceCode& source() const { return m_source; }
- private:
- FunctionBodyNode(VM*, const JSTokenLocation& start, const JSTokenLocation& end, unsigned startColumn, unsigned endColumn, bool inStrictContext);
- FunctionBodyNode(VM*, const JSTokenLocation& start, const JSTokenLocation& end, unsigned startColumn, unsigned endColumn, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
+ int startStartOffset() const { return m_startStartOffset; }
+ bool isInStrictContext() const { return m_isInStrictContext; }
+ ConstructorKind constructorKind() { return static_cast<ConstructorKind>(m_constructorKind); }
+ 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 FunctionNode final : public ScopeNode {
+ public:
+ 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 void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+
+ void finishParsing(PassRefPtr<FunctionParameters>, const Identifier&, FunctionMode);
+
+ const Identifier& ident() { return m_ident; }
+
+ FunctionMode functionMode() { return m_functionMode; }
+
+ unsigned startColumn() const { return m_startColumn; }
+ unsigned endColumn() const { return m_endColumn; }
+
+ static const bool scopeIsFunction = true;
+
+ private:
+ Identifier m_ident;
+ FunctionMode m_functionMode;
+ RefPtr<FunctionParameters> m_parameters;
unsigned m_startColumn;
unsigned m_endColumn;
};
FunctionBodyNode* m_body;
};
- class DeconstructionPatternNode : public RefCounted<DeconstructionPatternNode> {
- WTF_MAKE_NONCOPYABLE(DeconstructionPatternNode);
+#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:
+ 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;
public:
virtual bool isBindingNode() const { return false; }
virtual RegisterID* emitDirectBinding(BytecodeGenerator&, RegisterID*, ExpressionNode*) { return 0; }
- virtual ~DeconstructionPatternNode() = 0;
+ virtual ~DestructuringPatternNode() = 0;
protected:
- DeconstructionPatternNode(VM*);
+ DestructuringPatternNode();
};
- class ArrayPatternNode : public DeconstructionPatternNode {
+ class ArrayPatternNode : public DestructuringPatternNode, public ThrowableExpressionData {
public:
- static PassRefPtr<ArrayPatternNode> create(VM*);
- void appendIndex(const JSTokenLocation&, DeconstructionPatternNode* node)
+ enum class BindingType {
+ Elision,
+ Element,
+ RestElement
+ };
+
+ static Ref<ArrayPatternNode> create();
+ void appendIndex(BindingType bindingType, const JSTokenLocation&, DestructuringPatternNode* node, ExpressionNode* defaultValue)
{
- m_targetPatterns.append(node);
+ m_targetPatterns.append({ bindingType, node, defaultValue });
}
private:
- ArrayPatternNode(VM*);
+ 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<RefPtr<DeconstructionPatternNode>> m_targetPatterns;
+ Vector<Entry> m_targetPatterns;
};
- class ObjectPatternNode : public DeconstructionPatternNode {
+ class ObjectPatternNode : public DestructuringPatternNode {
public:
- static PassRefPtr<ObjectPatternNode> create(VM*);
- void appendEntry(const JSTokenLocation&, const Identifier& identifier, bool wasString, DeconstructionPatternNode* pattern)
+ static Ref<ObjectPatternNode> create();
+ void appendEntry(const JSTokenLocation&, const Identifier& identifier, bool wasString, DestructuringPatternNode* pattern, ExpressionNode* defaultValue)
{
- m_targetPatterns.append(Entry(identifier, wasString, pattern));
+ m_targetPatterns.append(Entry{ identifier, wasString, pattern, defaultValue });
}
private:
- ObjectPatternNode(VM*);
+ ObjectPatternNode();
virtual void collectBoundIdentifiers(Vector<Identifier>&) const override;
virtual void bindValue(BytecodeGenerator&, RegisterID*) const override;
virtual void toString(StringBuilder&) const override;
struct Entry {
- Entry(const Identifier& propertyName, bool wasString, DeconstructionPatternNode* pattern)
- : propertyName(propertyName)
- , wasString(wasString)
- , pattern(pattern)
- {
- }
Identifier propertyName;
bool wasString;
- RefPtr<DeconstructionPatternNode> pattern;
+ RefPtr<DestructuringPatternNode> pattern;
+ ExpressionNode* defaultValue;
};
Vector<Entry> m_targetPatterns;
};
- class BindingNode : public DeconstructionPatternNode {
+ class BindingNode : public DestructuringPatternNode {
public:
- static PassRefPtr<BindingNode> create(VM*, const Identifier& boundProperty, const JSTextPosition& start, const JSTextPosition& end);
+ static Ref<BindingNode> create(const Identifier& boundProperty, const JSTextPosition& start, const JSTextPosition& end);
const Identifier& boundProperty() const { return m_boundProperty; }
const JSTextPosition& divotStart() const { return m_divotStart; }
const JSTextPosition& divotEnd() const { return m_divotEnd; }
private:
- BindingNode(VM*, const Identifier& boundProperty, const JSTextPosition& start, const JSTextPosition& end);
+ BindingNode(const Identifier& boundProperty, const JSTextPosition& start, const JSTextPosition& end);
virtual void collectBoundIdentifiers(Vector<Identifier>&) const override;
virtual void bindValue(BytecodeGenerator&, RegisterID*) const override;
Identifier m_boundProperty;
};
- class DeconstructingAssignmentNode : public ExpressionNode, public ParserArenaDeletable {
+ class DestructuringAssignmentNode : public ExpressionNode, public ParserArenaDeletable {
public:
- DeconstructingAssignmentNode(const JSTokenLocation&, PassRefPtr<DeconstructionPatternNode>, ExpressionNode*);
- DeconstructionPatternNode* bindings() { return m_bindings.get(); }
+ DestructuringAssignmentNode(const JSTokenLocation&, PassRefPtr<DestructuringPatternNode>, ExpressionNode*);
+ DestructuringPatternNode* bindings() { return m_bindings.get(); }
using ParserArenaDeletable::operator new;
private:
virtual bool isAssignmentLocation() const override { return true; }
- virtual bool isDeconstructionNode() const override { return true; }
+ virtual bool isDestructuringNode() const override { return true; }
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
- RefPtr<DeconstructionPatternNode> m_bindings;
+ RefPtr<DestructuringPatternNode> m_bindings;
ExpressionNode* m_initializer;
};
public:
FuncDeclNode(const JSTokenLocation&, const Identifier&, FunctionBodyNode*, const SourceCode&, ParameterNode* = 0);
+ virtual bool isFuncDeclNode() const override { return true; }
FunctionBodyNode* body() { return m_body; }
private:
FunctionBodyNode* m_body;
};
+#if ENABLE(ES6_CLASS_SYNTAX)
+ class ClassDeclNode final : public StatementNode {
+ public:
+ ClassDeclNode(const JSTokenLocation&, ExpressionNode* classExpression);
+
+ private:
+ virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+
+ ExpressionNode* m_classDeclaration;
+ };
+#endif
+
class CaseClauseNode : public ParserArenaFreeable {
public:
CaseClauseNode(ExpressionNode*, SourceElements* = 0);
ExpressionNode* expr() const { return m_expr; }
void emitBytecode(BytecodeGenerator&, RegisterID* destination);
+ void setStartOffset(int offset) { m_startOffset = offset; }
private:
ExpressionNode* m_expr;
SourceElements* m_statements;
+ int m_startOffset;
};
class ClauseListNode : public ParserArenaFreeable {