summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/parser/Nodes.h
diff options
context:
space:
mode:
Diffstat (limited to 'Source/JavaScriptCore/parser/Nodes.h')
-rw-r--r--Source/JavaScriptCore/parser/Nodes.h1290
1 files changed, 927 insertions, 363 deletions
diff --git a/Source/JavaScriptCore/parser/Nodes.h b/Source/JavaScriptCore/parser/Nodes.h
index d779a178d..70606824d 100644
--- a/Source/JavaScriptCore/parser/Nodes.h
+++ b/Source/JavaScriptCore/parser/Nodes.h
@@ -1,7 +1,7 @@
/*
* 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-2009, 2013, 2015-2016 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>
@@ -23,31 +23,39 @@
*
*/
-#ifndef Nodes_h
-#define Nodes_h
+#pragma once
+#include "BuiltinNames.h"
#include "Error.h"
+#include "Interpreter.h"
#include "JITCode.h"
-#include "Opcode.h"
#include "ParserArena.h"
#include "ParserTokens.h"
#include "ResultType.h"
#include "SourceCode.h"
#include "SymbolTable.h"
+#include "VariableEnvironment.h"
#include <wtf/MathExtras.h>
+#include <wtf/SmallPtrSet.h>
namespace JSC {
+ enum OpcodeID : unsigned;
+
class ArgumentListNode;
class BytecodeGenerator;
- class FunctionBodyNode;
+ class FunctionMetadataNode;
+ class FunctionParameters;
class Label;
+ class ModuleAnalyzer;
+ class ModuleScopeData;
class PropertyListNode;
class ReadModifyResolveNode;
class RegisterID;
- class JSScope;
class ScopeNode;
+ typedef SmallPtrSet<UniquedStringImpl*> UniquedStringImplPtrSet;
+
enum Operator {
OpEqual,
OpPlusEq,
@@ -60,6 +68,7 @@ namespace JSC {
OpXOrEq,
OpOrEq,
OpModEq,
+ OpPowEq,
OpLShift,
OpRShift,
OpURShift
@@ -76,12 +85,8 @@ namespace JSC {
};
inline FallThroughMode invert(FallThroughMode fallThroughMode) { return static_cast<FallThroughMode>(!fallThroughMode); }
- typedef HashSet<RefPtr<StringImpl>, IdentifierRepHash> IdentifierSet;
-
namespace DeclarationStacks {
- enum VarAttrs { IsConstant = 1, HasInitializer = 2 };
- typedef Vector<std::pair<Identifier, unsigned>> VarStack;
- typedef Vector<FunctionBodyNode*> FunctionStack;
+ typedef Vector<FunctionMetadataNode*> FunctionStack;
}
struct SwitchInfo {
@@ -90,11 +95,17 @@ namespace JSC {
SwitchType switchType;
};
+ enum class AssignmentContext {
+ DeclarationStatement,
+ ConstDeclarationStatement,
+ AssignmentExpression
+ };
+
class ParserArenaFreeable {
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 {
@@ -103,24 +114,20 @@ namespace JSC {
// ParserArenaDeletable objects are deleted when the arena is deleted.
// Clients must not call delete directly on such objects.
- void* operator new(size_t, VM*);
- };
-
- template <typename T>
- struct ParserArenaData : ParserArenaDeletable {
- T data;
+ void* operator new(size_t, ParserArena&);
};
- class ParserArenaRefCounted : public RefCounted<ParserArenaRefCounted> {
- WTF_FASTMALLOC_OPERATORS;
+ 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 {
@@ -130,13 +137,21 @@ namespace JSC {
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; }
+
+ bool needsDebugHook() const { return m_needsDebugHook; }
+ void setNeedsDebugHook() { m_needsDebugHook = true; }
protected:
JSTextPosition m_position;
+ int m_endOffset;
+ bool m_needsDebugHook { false };
};
class ExpressionNode : public Node {
@@ -148,23 +163,34 @@ namespace JSC {
virtual bool isNumber() const { return false; }
virtual bool isString() const { return false; }
+ virtual bool isObjectLiteral() const { return false; }
+ virtual bool isArrayLiteral() 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 isAssignResolveNode() 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 isBaseFuncExprNode() const { return false; }
virtual bool isFuncExprNode() const { return false; }
+ virtual bool isArrowFuncExprNode() const { return false; }
+ virtual bool isClassExprNode() 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 bool isImportNode() const { return false; }
+ virtual bool isNewTarget() const { return false; }
+ virtual bool isBytecodeIntrinsicNode() const { return false; }
- virtual void emitBytecodeInConditionContext(BytecodeGenerator&, Label*, Label*, FallThroughMode);
+ virtual void emitBytecodeInConditionContext(BytecodeGenerator&, Label&, Label&, FallThroughMode);
virtual ExpressionNode* stripUnaryPlus() { return this; }
@@ -182,29 +208,57 @@ namespace JSC {
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 isDebuggerStatement() const { return false; }
+ virtual bool isFunctionNode() 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 isLabel() const { return false; }
virtual bool isBlock() const { return false; }
+ virtual bool isFuncDeclNode() const { return false; }
+ virtual bool isModuleDeclarationNode() const { return false; }
+ virtual bool isForOfNode() const { return false; }
protected:
+ StatementNode* m_next;
int m_lastLine;
};
+ class VariableEnvironmentNode : public ParserArenaDeletable {
+ public:
+ typedef DeclarationStacks::FunctionStack FunctionStack;
+
+ VariableEnvironmentNode()
+ {
+ }
+
+ VariableEnvironmentNode(VariableEnvironment& lexicalDeclaredVariables);
+ VariableEnvironmentNode(VariableEnvironment& lexicalDeclaredVariables, FunctionStack&&);
+
+ VariableEnvironment& lexicalVariables() { return m_lexicalVariables; }
+ FunctionStack& functionStack() { return m_functionStack; }
+
+ protected:
+ VariableEnvironment m_lexicalVariables;
+ FunctionStack m_functionStack;
+ };
+
class ConstantNode : public ExpressionNode {
public:
ConstantNode(const JSTokenLocation&, ResultType);
- virtual bool isPure(BytecodeGenerator&) const override { return true; }
- virtual bool isConstant() const override { return true; }
+ bool isPure(BytecodeGenerator&) const override { return true; }
+ 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;
+ RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+ void emitBytecodeInConditionContext(BytecodeGenerator&, Label& trueTarget, Label& falseTarget, FallThroughMode) override;
};
class NullNode : public ConstantNode {
@@ -212,8 +266,8 @@ namespace JSC {
NullNode(const JSTokenLocation&);
private:
- virtual bool isNull() const override { return true; }
- virtual JSValue jsValue(BytecodeGenerator&) const override { return jsNull(); }
+ bool isNull() const override { return true; }
+ JSValue jsValue(BytecodeGenerator&) const override { return jsNull(); }
};
class BooleanNode : public ConstantNode {
@@ -222,8 +276,8 @@ namespace JSC {
bool value() { return m_value; }
private:
- virtual bool isBoolean() const override { return true; }
- virtual JSValue jsValue(BytecodeGenerator&) const override { return jsBoolean(m_value); }
+ bool isBoolean() const override { return true; }
+ JSValue jsValue(BytecodeGenerator&) const override { return jsBoolean(m_value); }
bool m_value;
};
@@ -231,28 +285,44 @@ namespace JSC {
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;
+ RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) final;
private:
- virtual bool isNumber() const override { return true; }
- virtual JSValue jsValue(BytecodeGenerator&) const override { return jsNumber(m_value); }
+ bool isNumber() const final { return true; }
+ JSValue jsValue(BytecodeGenerator&) const override { return jsNumber(m_value); }
double m_value;
};
+ class DoubleNode : public NumberNode {
+ public:
+ DoubleNode(const JSTokenLocation&, double value);
+
+ private:
+ 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);
+ bool isIntegerNode() const final { return true; }
+ };
+
class StringNode : public ConstantNode {
public:
StringNode(const JSTokenLocation&, const Identifier&);
const Identifier& value() { return m_value; }
private:
- virtual bool isString() const override { return true; }
- virtual JSValue jsValue(BytecodeGenerator&) const override;
+ bool isString() const override { return true; }
+ JSValue jsValue(BytecodeGenerator&) const override;
const Identifier& m_value;
};
-
+
class ThrowableExpressionData {
public:
ThrowableExpressionData()
@@ -405,12 +475,80 @@ namespace JSC {
uint16_t m_subexpressionLineStartOffset;
};
+ 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:
+ 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:
+ 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:
+ RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+
+ ExpressionNode* m_tag;
+ TemplateLiteralNode* m_templateLiteral;
+ };
+
class RegExpNode : public ExpressionNode, public ThrowableExpressionData {
public:
RegExpNode(const JSTokenLocation&, const Identifier& pattern, const Identifier& flags);
private:
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+ RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
const Identifier& m_pattern;
const Identifier& m_flags;
@@ -421,7 +559,36 @@ namespace JSC {
ThisNode(const JSTokenLocation&);
private:
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+ RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+ };
+
+ class SuperNode final : public ExpressionNode {
+ public:
+ SuperNode(const JSTokenLocation&);
+
+ private:
+ bool isSuperNode() const override { return true; }
+ RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+ };
+
+ class ImportNode : public ExpressionNode, public ThrowableExpressionData {
+ public:
+ ImportNode(const JSTokenLocation&, ExpressionNode*);
+
+ private:
+ bool isImportNode() const override { return true; }
+ RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+
+ ExpressionNode* m_expr;
+ };
+
+ class NewTargetNode final : public ExpressionNode {
+ public:
+ NewTargetNode(const JSTokenLocation&);
+
+ private:
+ bool isNewTarget() const final { return true; }
+ RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
};
class ResolveNode : public ExpressionNode {
@@ -431,11 +598,11 @@ namespace JSC {
const Identifier& identifier() const { return m_ident; }
private:
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+ 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; }
+ bool isPure(BytecodeGenerator&) const override;
+ bool isLocation() const override { return true; }
+ bool isResolveNode() const override { return true; }
const Identifier& m_ident;
JSTextPosition m_start;
@@ -462,13 +629,15 @@ namespace JSC {
ArrayNode(const JSTokenLocation&, ElementNode*);
ArrayNode(const JSTokenLocation&, int elision, ElementNode*);
- ArgumentListNode* toArgumentList(VM*, int, int) const;
+ bool isArrayLiteral() const override { return true; }
+
+ ArgumentListNode* toArgumentList(ParserArena&, int, int) const;
ElementNode* elements() const { ASSERT(isSimpleArray()); return m_element; }
private:
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+ RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
- virtual bool isSimpleArray() const override;
+ bool isSimpleArray() const override;
ElementNode* m_element;
int m_elision;
@@ -477,23 +646,29 @@ namespace JSC {
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, bool isClassProperty);
+ PropertyNode(ExpressionNode* propertyName, ExpressionNode*, Type, PutType, SuperBinding, bool isClassProperty);
- 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; }
+ bool isClassProperty() const { return m_isClassProperty; }
+ 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;
+ unsigned m_isClassProperty: 1;
};
class PropertyListNode : public ExpressionNode {
@@ -501,9 +676,12 @@ namespace JSC {
PropertyListNode(const JSTokenLocation&, PropertyNode*);
PropertyListNode(const JSTokenLocation&, PropertyNode*, PropertyListNode*);
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+ bool hasStaticallyNamedProperty(const Identifier& propName);
private:
+ RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+ void emitPutConstantProperty(BytecodeGenerator&, RegisterID*, PropertyNode&);
+
PropertyNode* m_node;
PropertyListNode* m_next;
};
@@ -512,9 +690,10 @@ namespace JSC {
public:
ObjectLiteralNode(const JSTokenLocation&);
ObjectLiteralNode(const JSTokenLocation&, PropertyListNode*);
+ bool isObjectLiteral() const override { return true; }
private:
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+ RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
PropertyListNode* m_list;
};
@@ -529,10 +708,10 @@ namespace JSC {
bool subscriptHasAssignments() const { return m_subscriptHasAssignments; }
private:
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+ RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
- virtual bool isLocation() const override { return true; }
- virtual bool isBracketAccessorNode() const override { return true; }
+ bool isLocation() const override { return true; }
+ bool isBracketAccessorNode() const override { return true; }
ExpressionNode* m_base;
ExpressionNode* m_subscript;
@@ -547,10 +726,10 @@ namespace JSC {
const Identifier& identifier() const { return m_ident; }
private:
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+ RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
- virtual bool isLocation() const override { return true; }
- virtual bool isDotAccessorNode() const override { return true; }
+ bool isLocation() const override { return true; }
+ bool isDotAccessorNode() const override { return true; }
ExpressionNode* m_base;
const Identifier& m_ident;
@@ -563,9 +742,9 @@ namespace JSC {
ExpressionNode* expression() const { return m_expression; }
private:
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+ RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
- virtual bool isSpreadExpression() const override { return true; }
+ bool isSpreadExpression() const override { return true; }
ExpressionNode* m_expression;
};
@@ -578,7 +757,7 @@ namespace JSC {
ExpressionNode* m_expr;
private:
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+ RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
};
class ArgumentsNode : public ParserArenaFreeable {
@@ -595,7 +774,7 @@ namespace JSC {
NewExprNode(const JSTokenLocation&, ExpressionNode*, ArgumentsNode*);
private:
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+ RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
ExpressionNode* m_expr;
ArgumentsNode* m_args;
@@ -606,7 +785,7 @@ namespace JSC {
EvalFunctionCallNode(const JSTokenLocation&, ArgumentsNode*, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
private:
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+ RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
ArgumentsNode* m_args;
};
@@ -616,7 +795,7 @@ namespace JSC {
FunctionCallValueNode(const JSTokenLocation&, ExpressionNode*, ArgumentsNode*, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
private:
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+ RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
ExpressionNode* m_expr;
ArgumentsNode* m_args;
@@ -627,7 +806,7 @@ namespace JSC {
FunctionCallResolveNode(const JSTokenLocation&, const Identifier&, ArgumentsNode*, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
private:
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+ RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
const Identifier& m_ident;
ArgumentsNode* m_args;
@@ -635,14 +814,15 @@ namespace JSC {
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;
+ RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
ExpressionNode* m_base;
ExpressionNode* m_subscript;
ArgumentsNode* m_args;
+ bool m_subscriptHasAssignments;
};
class FunctionCallDotNode : public ExpressionNode, public ThrowableSubExpressionData {
@@ -650,7 +830,7 @@ namespace JSC {
FunctionCallDotNode(const JSTokenLocation&, ExpressionNode* base, const Identifier&, ArgumentsNode*, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
private:
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+ RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
protected:
ExpressionNode* m_base;
@@ -658,12 +838,43 @@ namespace JSC {
ArgumentsNode* m_args;
};
+ class BytecodeIntrinsicNode : public ExpressionNode, public ThrowableExpressionData {
+ public:
+ enum class Type {
+ Constant,
+ Function
+ };
+
+ typedef RegisterID* (BytecodeIntrinsicNode::* EmitterType)(BytecodeGenerator&, RegisterID*);
+
+ BytecodeIntrinsicNode(Type, const JSTokenLocation&, EmitterType, const Identifier&, ArgumentsNode*, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
+
+ bool isBytecodeIntrinsicNode() const override { return true; }
+
+ Type type() const { return m_type; }
+ EmitterType emitter() const { return m_emitter; }
+ const Identifier& identifier() const { return m_ident; }
+
+#define JSC_DECLARE_BYTECODE_INTRINSIC_FUNCTIONS(name) RegisterID* emit_intrinsic_##name(BytecodeGenerator&, RegisterID*);
+ JSC_COMMON_BYTECODE_INTRINSIC_FUNCTIONS_EACH_NAME(JSC_DECLARE_BYTECODE_INTRINSIC_FUNCTIONS)
+ JSC_COMMON_BYTECODE_INTRINSIC_CONSTANTS_EACH_NAME(JSC_DECLARE_BYTECODE_INTRINSIC_FUNCTIONS)
+#undef JSC_DECLARE_BYTECODE_INTRINSIC_FUNCTIONS
+
+ private:
+ RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+
+ Type m_type;
+ 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);
private:
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+ RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
};
class ApplyFunctionCallDotNode : public FunctionCallDotNode {
@@ -671,7 +882,7 @@ namespace JSC {
ApplyFunctionCallDotNode(const JSTokenLocation&, ExpressionNode* base, const Identifier&, ArgumentsNode*, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
private:
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+ RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
};
class DeleteResolveNode : public ExpressionNode, public ThrowableExpressionData {
@@ -679,7 +890,7 @@ namespace JSC {
DeleteResolveNode(const JSTokenLocation&, const Identifier&, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
private:
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+ RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
const Identifier& m_ident;
};
@@ -689,7 +900,7 @@ namespace JSC {
DeleteBracketNode(const JSTokenLocation&, ExpressionNode* base, ExpressionNode* subscript, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
private:
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+ RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
ExpressionNode* m_base;
ExpressionNode* m_subscript;
@@ -700,7 +911,7 @@ namespace JSC {
DeleteDotNode(const JSTokenLocation&, ExpressionNode* base, const Identifier&, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
private:
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+ RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
ExpressionNode* m_base;
const Identifier& m_ident;
@@ -711,7 +922,7 @@ namespace JSC {
DeleteValueNode(const JSTokenLocation&, ExpressionNode*);
private:
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+ RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
ExpressionNode* m_expr;
};
@@ -721,7 +932,7 @@ namespace JSC {
VoidNode(const JSTokenLocation&, ExpressionNode*);
private:
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+ RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
ExpressionNode* m_expr;
};
@@ -733,7 +944,7 @@ namespace JSC {
const Identifier& identifier() const { return m_ident; }
private:
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+ RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
const Identifier& m_ident;
};
@@ -743,7 +954,7 @@ namespace JSC {
TypeOfValueNode(const JSTokenLocation&, ExpressionNode*);
private:
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+ RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
ExpressionNode* m_expr;
};
@@ -753,7 +964,7 @@ namespace JSC {
PrefixNode(const JSTokenLocation&, ExpressionNode*, Operator, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
protected:
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+ RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
virtual RegisterID* emitResolve(BytecodeGenerator&, RegisterID* = 0);
virtual RegisterID* emitBracket(BytecodeGenerator&, RegisterID* = 0);
virtual RegisterID* emitDot(BytecodeGenerator&, RegisterID* = 0);
@@ -767,10 +978,10 @@ namespace JSC {
PostfixNode(const JSTokenLocation&, ExpressionNode*, Operator, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
private:
- 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;
+ RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+ RegisterID* emitResolve(BytecodeGenerator&, RegisterID* = 0) override;
+ RegisterID* emitBracket(BytecodeGenerator&, RegisterID* = 0) override;
+ RegisterID* emitDot(BytecodeGenerator&, RegisterID* = 0) override;
};
class UnaryOpNode : public ExpressionNode {
@@ -780,11 +991,10 @@ namespace JSC {
protected:
ExpressionNode* expr() { return m_expr; }
const ExpressionNode* expr() const { return m_expr; }
+ OpcodeID opcodeID() const { return m_opcodeID; }
private:
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
-
- OpcodeID opcodeID() const { return m_opcodeID; }
+ RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
ExpressionNode* m_expr;
OpcodeID m_opcodeID;
@@ -795,7 +1005,9 @@ namespace JSC {
UnaryPlusNode(const JSTokenLocation&, ExpressionNode*);
private:
- virtual ExpressionNode* stripUnaryPlus() override { return expr(); }
+ RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+
+ ExpressionNode* stripUnaryPlus() override { return expr(); }
};
class NegateNode : public UnaryOpNode {
@@ -812,7 +1024,7 @@ namespace JSC {
const ExpressionNode* expr() const { return m_expr; }
private:
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+ RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
ExpressionNode* m_expr;
};
@@ -821,7 +1033,7 @@ namespace JSC {
public:
LogicalNotNode(const JSTokenLocation&, ExpressionNode*);
private:
- virtual void emitBytecodeInConditionContext(BytecodeGenerator&, Label* trueTarget, Label* falseTarget, FallThroughMode) override;
+ void emitBytecodeInConditionContext(BytecodeGenerator&, Label& trueTarget, Label& falseTarget, FallThroughMode) override;
};
class BinaryOpNode : public ExpressionNode {
@@ -830,14 +1042,14 @@ namespace JSC {
BinaryOpNode(const JSTokenLocation&, ResultType, ExpressionNode* expr1, ExpressionNode* expr2, OpcodeID, bool rightHasAssignments);
RegisterID* emitStrcat(BytecodeGenerator& generator, RegisterID* destination, RegisterID* lhs = 0, ReadModifyResolveNode* emitExpressionInfoForMe = 0);
- virtual void emitBytecodeInConditionContext(BytecodeGenerator&, Label* trueTarget, Label* falseTarget, FallThroughMode) override;
+ void emitBytecodeInConditionContext(BytecodeGenerator&, Label& trueTarget, Label& falseTarget, FallThroughMode) override;
ExpressionNode* lhs() { return m_expr1; };
ExpressionNode* rhs() { return m_expr2; };
private:
void tryFoldToBranch(BytecodeGenerator&, TriState& branchCondition, ExpressionNode*& branchExpression);
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+ RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
protected:
OpcodeID opcodeID() const { return m_opcodeID; }
@@ -851,6 +1063,11 @@ namespace JSC {
bool m_rightHasAssignments;
};
+ class PowNode : public BinaryOpNode {
+ public:
+ PowNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
+ };
+
class MultNode : public BinaryOpNode {
public:
MultNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
@@ -870,14 +1087,14 @@ namespace JSC {
public:
AddNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
- virtual bool isAdd() const override { return true; }
+ bool isAdd() const override { return true; }
};
class SubNode : public BinaryOpNode {
public:
SubNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
- virtual bool isSubtract() const override { return true; }
+ bool isSubtract() const override { return true; }
};
class LeftShiftNode : public BinaryOpNode {
@@ -921,7 +1138,7 @@ namespace JSC {
ThrowableBinaryOpNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, OpcodeID, bool rightHasAssignments);
private:
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+ RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
};
class InstanceOfNode : public ThrowableBinaryOpNode {
@@ -929,12 +1146,15 @@ namespace JSC {
InstanceOfNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
private:
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+ RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
};
class InNode : public ThrowableBinaryOpNode {
public:
InNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
+
+ private:
+ RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
};
class EqualNode : public BinaryOpNode {
@@ -942,7 +1162,7 @@ namespace JSC {
EqualNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
private:
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+ RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
};
class NotEqualNode : public BinaryOpNode {
@@ -955,7 +1175,7 @@ namespace JSC {
StrictEqualNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
private:
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+ RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
};
class NotStrictEqualNode : public BinaryOpNode {
@@ -984,8 +1204,8 @@ namespace JSC {
LogicalOpNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, LogicalOperator);
private:
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
- virtual void emitBytecodeInConditionContext(BytecodeGenerator&, Label* trueTarget, Label* falseTarget, FallThroughMode) override;
+ RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+ void emitBytecodeInConditionContext(BytecodeGenerator&, Label& trueTarget, Label& falseTarget, FallThroughMode) override;
ExpressionNode* m_expr1;
ExpressionNode* m_expr2;
@@ -998,7 +1218,7 @@ namespace JSC {
ConditionalNode(const JSTokenLocation&, ExpressionNode* logical, ExpressionNode* expr1, ExpressionNode* expr2);
private:
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+ RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
ExpressionNode* m_logical;
ExpressionNode* m_expr1;
@@ -1010,7 +1230,7 @@ namespace JSC {
ReadModifyResolveNode(const JSTokenLocation&, const Identifier&, Operator, ExpressionNode* right, bool rightHasAssignments, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
private:
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+ RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
const Identifier& m_ident;
ExpressionNode* m_right;
@@ -1020,13 +1240,16 @@ namespace JSC {
class AssignResolveNode : public ExpressionNode, public ThrowableExpressionData {
public:
- AssignResolveNode(const JSTokenLocation&, const Identifier&, ExpressionNode* right);
+ AssignResolveNode(const JSTokenLocation&, const Identifier&, ExpressionNode* right, AssignmentContext);
+ bool isAssignResolveNode() const override { return true; }
+ const Identifier& identifier() const { return m_ident; }
private:
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+ RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
const Identifier& m_ident;
ExpressionNode* m_right;
+ AssignmentContext m_assignmentContext;
};
class ReadModifyBracketNode : public ExpressionNode, public ThrowableSubExpressionData {
@@ -1034,12 +1257,12 @@ namespace JSC {
ReadModifyBracketNode(const JSTokenLocation&, ExpressionNode* base, ExpressionNode* subscript, Operator, ExpressionNode* right, bool subscriptHasAssignments, bool rightHasAssignments, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
private:
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+ RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
ExpressionNode* m_base;
ExpressionNode* m_subscript;
ExpressionNode* m_right;
- Operator m_operator : 30;
+ unsigned m_operator : 30;
bool m_subscriptHasAssignments : 1;
bool m_rightHasAssignments : 1;
};
@@ -1049,7 +1272,7 @@ namespace JSC {
AssignBracketNode(const JSTokenLocation&, ExpressionNode* base, ExpressionNode* subscript, ExpressionNode* right, bool subscriptHasAssignments, bool rightHasAssignments, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
private:
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+ RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
ExpressionNode* m_base;
ExpressionNode* m_subscript;
@@ -1063,7 +1286,7 @@ namespace JSC {
AssignDotNode(const JSTokenLocation&, ExpressionNode* base, const Identifier&, ExpressionNode* right, bool rightHasAssignments, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
private:
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+ RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
ExpressionNode* m_base;
const Identifier& m_ident;
@@ -1076,12 +1299,12 @@ namespace JSC {
ReadModifyDotNode(const JSTokenLocation&, ExpressionNode* base, const Identifier&, Operator, ExpressionNode* right, bool rightHasAssignments, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
private:
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+ RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
ExpressionNode* m_base;
const Identifier& m_ident;
ExpressionNode* m_right;
- Operator m_operator : 31;
+ unsigned m_operator : 31;
bool m_rightHasAssignments : 1;
};
@@ -1090,57 +1313,25 @@ namespace JSC {
AssignErrorNode(const JSTokenLocation&, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
private:
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+ 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);
-
- using ParserArenaDeletable::operator new;
+ CommaNode(const JSTokenLocation&, ExpressionNode*);
- 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;
+ bool isCommaNode() const override { return true; }
+ RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
- ExpressionVector m_expressions;
+ ExpressionNode* m_expr;
+ CommaNode* m_next;
};
- class ConstDeclNode : public ExpressionNode {
- public:
- ConstDeclNode(const JSTokenLocation&, const Identifier&, ExpressionNode*);
-
- bool hasInitializer() const { return m_init; }
- const Identifier& ident() { return m_ident; }
-
- private:
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
- virtual RegisterID* emitCodeSingle(BytecodeGenerator&);
-
- const Identifier& m_ident;
-
- public:
- ConstDeclNode* m_next;
-
- private:
- ExpressionNode* m_init;
- };
-
- class ConstStatementNode : public StatementNode {
- public:
- ConstStatementNode(const JSTokenLocation&, ConstDeclNode* next);
-
- private:
- virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
-
- ConstDeclNode* m_next;
- };
-
- class SourceElements : public ParserArenaDeletable {
+ class SourceElements final : public ParserArenaFreeable {
public:
SourceElements();
@@ -1150,22 +1341,26 @@ namespace JSC {
StatementNode* lastStatement() const;
void emitBytecode(BytecodeGenerator&, RegisterID* destination);
+ void analyzeModule(ModuleAnalyzer&);
private:
- Vector<StatementNode*> m_statements;
+ StatementNode* m_head;
+ StatementNode* m_tail;
};
- class BlockNode : public StatementNode {
+ class BlockNode : public StatementNode, public VariableEnvironmentNode {
public:
- BlockNode(const JSTokenLocation&, SourceElements* = 0);
+ using ParserArenaDeletable::operator new;
+
+ BlockNode(const JSTokenLocation&, SourceElements*, VariableEnvironment&, FunctionStack&&);
StatementNode* singleStatement() const;
StatementNode* lastStatement() const;
private:
- virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+ void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
- virtual bool isBlock() const override { return true; }
+ bool isBlock() const override { return true; }
SourceElements* m_statements;
};
@@ -1175,17 +1370,19 @@ namespace JSC {
EmptyStatementNode(const JSTokenLocation&);
private:
- virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+ void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
- virtual bool isEmptyStatement() const override { return true; }
+ bool isEmptyStatement() const override { return true; }
};
class DebuggerStatementNode : public StatementNode {
public:
DebuggerStatementNode(const JSTokenLocation&);
+
+ bool isDebuggerStatement() const override { return true; }
private:
- virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+ void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
};
class ExprStatementNode : public StatementNode {
@@ -1195,28 +1392,48 @@ namespace JSC {
ExpressionNode* expr() const { return m_expr; }
private:
- virtual bool isExprStatement() const override { return true; }
+ bool isExprStatement() const override { return true; }
- virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+ void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
ExpressionNode* m_expr;
};
- class VarStatementNode : public StatementNode {
+ class DeclarationStatement : public StatementNode {
public:
- VarStatementNode(const JSTokenLocation&, ExpressionNode*);
+ DeclarationStatement(const JSTokenLocation&, ExpressionNode*);
private:
- virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+ void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
ExpressionNode* m_expr;
};
+ class EmptyVarExpression : public ExpressionNode {
+ public:
+ EmptyVarExpression(const JSTokenLocation&, const Identifier&);
+
+ private:
+ RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+
+ const Identifier& m_ident;
+ };
+
+ class EmptyLetExpression : public ExpressionNode {
+ public:
+ EmptyLetExpression(const JSTokenLocation&, const Identifier&);
+
+ private:
+ RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+
+ const Identifier& m_ident;
+ };
+
class IfElseNode : public StatementNode {
public:
IfElseNode(const JSTokenLocation&, ExpressionNode* condition, StatementNode* ifBlock, StatementNode* elseBlock);
private:
- virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+ void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
bool tryFoldBreakAndContinue(BytecodeGenerator&, StatementNode* ifBlock,
Label*& trueTarget, FallThroughMode&);
@@ -1230,7 +1447,7 @@ namespace JSC {
DoWhileNode(const JSTokenLocation&, StatementNode*, ExpressionNode*);
private:
- virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+ void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
StatementNode* m_statement;
ExpressionNode* m_expr;
@@ -1241,18 +1458,20 @@ namespace JSC {
WhileNode(const JSTokenLocation&, ExpressionNode*, StatementNode*);
private:
- virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+ void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
ExpressionNode* m_expr;
StatementNode* m_statement;
};
- class ForNode : public StatementNode {
+ class ForNode : public StatementNode, public VariableEnvironmentNode {
public:
- ForNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, ExpressionNode* expr3, StatementNode*);
+ using ParserArenaDeletable::operator new;
+
+ ForNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, ExpressionNode* expr3, StatementNode*, VariableEnvironment&);
private:
- virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+ void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
ExpressionNode* m_expr1;
ExpressionNode* m_expr2;
@@ -1260,13 +1479,17 @@ namespace JSC {
StatementNode* m_statement;
};
- class DeconstructionPatternNode;
+ class DestructuringPatternNode;
- class EnumerationNode : public StatementNode, public ThrowableExpressionData {
+ class EnumerationNode : public StatementNode, public ThrowableExpressionData, public VariableEnvironmentNode {
public:
- EnumerationNode(const JSTokenLocation&, ExpressionNode*, ExpressionNode*, StatementNode*);
- EnumerationNode(VM*, const JSTokenLocation&, DeconstructionPatternNode*, ExpressionNode*, StatementNode*);
-
+ using ParserArenaDeletable::operator new;
+
+ EnumerationNode(const JSTokenLocation&, ExpressionNode*, ExpressionNode*, StatementNode*, VariableEnvironment&);
+
+ ExpressionNode* lexpr() const { return m_lexpr; }
+ ExpressionNode* expr() const { return m_expr; }
+
protected:
ExpressionNode* m_lexpr;
ExpressionNode* m_expr;
@@ -1275,44 +1498,44 @@ namespace JSC {
class ForInNode : public EnumerationNode {
public:
- ForInNode(const JSTokenLocation&, ExpressionNode*, ExpressionNode*, StatementNode*);
- ForInNode(VM*, const JSTokenLocation&, DeconstructionPatternNode*, ExpressionNode*, StatementNode*);
+ ForInNode(const JSTokenLocation&, ExpressionNode*, ExpressionNode*, StatementNode*, VariableEnvironment&);
private:
- virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+ RegisterID* tryGetBoundLocal(BytecodeGenerator&);
+ void emitLoopHeader(BytecodeGenerator&, RegisterID* propertyName);
+
+ void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
};
class ForOfNode : public EnumerationNode {
public:
- ForOfNode(const JSTokenLocation&, ExpressionNode*, ExpressionNode*, StatementNode*);
- ForOfNode(VM*, const JSTokenLocation&, DeconstructionPatternNode*, ExpressionNode*, StatementNode*);
-
+ ForOfNode(const JSTokenLocation&, ExpressionNode*, ExpressionNode*, StatementNode*, VariableEnvironment&);
+ bool isForOfNode() const override { return true; }
+
private:
- virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+ 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&);
private:
- virtual bool isContinue() const override { return true; }
- virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+ bool isContinue() const override { return true; }
+ void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
const Identifier& m_ident;
};
class BreakNode : public StatementNode, public ThrowableExpressionData {
public:
- BreakNode(VM*, const JSTokenLocation&);
BreakNode(const JSTokenLocation&, const Identifier&);
Label* trivialTarget(BytecodeGenerator&);
private:
- virtual bool isBreak() const override { return true; }
- virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+ bool isBreak() const override { return true; }
+ void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
const Identifier& m_ident;
};
@@ -1324,9 +1547,9 @@ namespace JSC {
ExpressionNode* value() { return m_value; }
private:
- virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+ void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
- virtual bool isReturnNode() const override { return true; }
+ bool isReturnNode() const override { return true; }
ExpressionNode* m_value;
};
@@ -1336,7 +1559,7 @@ namespace JSC {
WithNode(const JSTokenLocation&, ExpressionNode*, StatementNode*, const JSTextPosition& divot, uint32_t expressionLength);
private:
- virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+ void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
ExpressionNode* m_expr;
StatementNode* m_statement;
@@ -1348,8 +1571,10 @@ namespace JSC {
public:
LabelNode(const JSTokenLocation&, const Identifier& name, StatementNode*);
+ bool isLabel() const override { return true; }
+
private:
- virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+ void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
const Identifier& m_name;
StatementNode* m_statement;
@@ -1360,55 +1585,33 @@ namespace JSC {
ThrowNode(const JSTokenLocation&, ExpressionNode*);
private:
- virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+ void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
ExpressionNode* m_expr;
};
- class TryNode : public StatementNode {
+ class TryNode : public StatementNode, public VariableEnvironmentNode {
public:
- TryNode(const JSTokenLocation&, StatementNode* tryBlock, const Identifier& exceptionIdent, StatementNode* catchBlock, StatementNode* finallyBlock);
+ using ParserArenaDeletable::operator new;
+
+ TryNode(const JSTokenLocation&, StatementNode* tryBlock, DestructuringPatternNode* catchPattern, StatementNode* catchBlock, VariableEnvironment& catchEnvironment, StatementNode* finallyBlock);
private:
- virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+ void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
StatementNode* m_tryBlock;
- const Identifier& m_exceptionIdent;
+ DestructuringPatternNode* m_catchPattern;
StatementNode* m_catchBlock;
StatementNode* m_finallyBlock;
};
- class ParameterNode : public ParserArenaDeletable {
+ class ScopeNode : public StatementNode, public ParserArenaRoot, public VariableEnvironmentNode {
public:
- ParameterNode(PassRefPtr<DeconstructionPatternNode>);
- ParameterNode(ParameterNode*, PassRefPtr<DeconstructionPatternNode>);
- DeconstructionPatternNode* pattern() const { return m_pattern.get(); }
- ParameterNode* nextParam() const { return m_next; }
+ ScopeNode(ParserArena&, const JSTokenLocation& start, const JSTokenLocation& end, bool inStrictContext);
+ ScopeNode(ParserArena&, const JSTokenLocation& start, const JSTokenLocation& end, const SourceCode&, SourceElements*, VariableEnvironment&, FunctionStack&&, VariableEnvironment&, UniquedStringImplPtrSet&&, CodeFeatures, InnerArrowFunctionCodeFeatures, int numConstants);
- private:
- RefPtr<DeconstructionPatternNode> m_pattern;
- ParameterNode* m_next;
- };
-
- class ScopeNode : public StatementNode, public ParserArenaRefCounted {
- 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);
-
- 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(); }
@@ -1420,21 +1623,31 @@ namespace JSC {
void setFeatures(CodeFeatures features) { m_features = features; }
CodeFeatures features() { return m_features; }
+ InnerArrowFunctionCodeFeatures innerArrowFunctionCodeFeatures() { return m_innerArrowFunctionCodeFeatures; }
+ bool doAnyInnerArrowFunctionsUseAnyFeature() { return m_innerArrowFunctionCodeFeatures != NoInnerArrowFunctionFeatures; }
+ bool doAnyInnerArrowFunctionsUseArguments() { return m_innerArrowFunctionCodeFeatures & ArgumentsInnerArrowFunctionFeature; }
+ bool doAnyInnerArrowFunctionsUseSuperCall() { return m_innerArrowFunctionCodeFeatures & SuperCallInnerArrowFunctionFeature; }
+ bool doAnyInnerArrowFunctionsUseSuperProperty() { return m_innerArrowFunctionCodeFeatures & SuperPropertyInnerArrowFunctionFeature; }
+ bool doAnyInnerArrowFunctionsUseEval() { return m_innerArrowFunctionCodeFeatures & EvalInnerArrowFunctionFeature; }
+ bool doAnyInnerArrowFunctionsUseThis() { return m_innerArrowFunctionCodeFeatures & ThisInnerArrowFunctionFeature; }
+ bool doAnyInnerArrowFunctionsUseNewTarget() { return m_innerArrowFunctionCodeFeatures & NewTargetInnerArrowFunctionFeature; }
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 usesArrowFunction() const { return m_features & ArrowFunctionFeature; }
bool isStrictMode() const { return m_features & StrictModeFeature; }
void setUsesArguments() { m_features |= ArgumentsFeature; }
bool usesThis() const { return m_features & ThisFeature; }
- bool needsActivationForMoreThanVariables() const { return m_features & (EvalFeature | WithFeature | CatchFeature); }
- bool needsActivation() const { return (hasCapturedVariables()) || (m_features & (EvalFeature | WithFeature | CatchFeature)); }
- bool hasCapturedVariables() const { return !!m_capturedVariables.size(); }
- size_t capturedVariableCount() const { return m_capturedVariables.size(); }
- bool captures(const Identifier& ident) { return m_capturedVariables.contains(ident.impl()); }
+ bool usesSuperCall() const { return m_features & SuperCallFeature; }
+ bool usesSuperProperty() const { return m_features & SuperPropertyFeature; }
+ bool usesNewTarget() const { return m_features & NewTargetFeature; }
+ bool needsActivation() const { return (hasCapturedVariables()) || (m_features & (EvalFeature | WithFeature)); }
+ bool hasCapturedVariables() const { return m_varDeclarations.hasCapturedVariables(); }
+ bool captures(UniquedStringImpl* uid) { return m_varDeclarations.captures(uid); }
+ bool captures(const Identifier& ident) { return captures(ident.impl()); }
+ bool hasSloppyModeHoistedFunction(UniquedStringImpl* uid) const { return m_sloppyModeHoistedFunctions.contains(uid); }
- VarStack& varStack() { return m_varStack; }
- FunctionStack& functionStack() { return m_functionStack; }
+ VariableEnvironment& varDeclarations() { return m_varDeclarations; }
int neededConstants()
{
@@ -1446,29 +1659,27 @@ namespace JSC {
StatementNode* singleStatement() const;
void emitStatementsBytecode(BytecodeGenerator&, RegisterID* destination);
+
+ void analyzeModule(ModuleAnalyzer&);
protected:
- void setSource(const SourceCode& source) { m_source = source; }
- ParserArena m_arena;
-
int m_startLineNumber;
unsigned m_startStartOffset;
unsigned m_startLineStartOffset;
private:
CodeFeatures m_features;
+ InnerArrowFunctionCodeFeatures m_innerArrowFunctionCodeFeatures;
SourceCode m_source;
- VarStack m_varStack;
- FunctionStack m_functionStack;
+ VariableEnvironment m_varDeclarations;
+ UniquedStringImplPtrSet m_sloppyModeHoistedFunctions;
int m_numConstants;
SourceElements* m_statements;
- IdentifierSet m_capturedVariables;
};
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*, VariableEnvironment&, FunctionStack&&, VariableEnvironment&, UniquedStringImplPtrSet&&, FunctionParameters*, const SourceCode&, CodeFeatures, InnerArrowFunctionCodeFeatures, int numConstants, RefPtr<ModuleScopeData>&&);
unsigned startColumn() const { return m_startColumn; }
unsigned endColumn() const { return m_endColumn; }
@@ -1476,18 +1687,14 @@ namespace JSC {
static const bool scopeIsFunction = false;
private:
- ProgramNode(VM*, const JSTokenLocation& start, const JSTokenLocation& end, unsigned startColumn, unsigned endColumn, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
-
- virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
-
+ void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
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*, VariableEnvironment&, FunctionStack&&, VariableEnvironment&, UniquedStringImplPtrSet&&, FunctionParameters*, const SourceCode&, CodeFeatures, InnerArrowFunctionCodeFeatures, int numConstants, RefPtr<ModuleScopeData>&&);
ALWAYS_INLINE unsigned startColumn() const { return 0; }
unsigned endColumn() const { return m_endColumn; }
@@ -1495,200 +1702,565 @@ namespace JSC {
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);
+ void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+
+ unsigned m_endColumn;
+ };
+
+ class ModuleProgramNode : public ScopeNode {
+ public:
+ ModuleProgramNode(ParserArena&, const JSTokenLocation& start, const JSTokenLocation& end, unsigned startColumn, unsigned endColumn, SourceElements*, VariableEnvironment&, FunctionStack&&, VariableEnvironment&, UniquedStringImplPtrSet&&, FunctionParameters*, const SourceCode&, CodeFeatures, InnerArrowFunctionCodeFeatures, int numConstants, RefPtr<ModuleScopeData>&&);
- virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+ unsigned startColumn() const { return m_startColumn; }
+ unsigned endColumn() const { return m_endColumn; }
+
+ static const bool scopeIsFunction = false;
+ ModuleScopeData& moduleScopeData()
+ {
+ return m_moduleScopeData;
+ }
+
+ private:
+ void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+ unsigned m_startColumn;
unsigned m_endColumn;
+ Ref<ModuleScopeData> m_moduleScopeData;
};
- class FunctionParameters : public RefCounted<FunctionParameters> {
- WTF_MAKE_FAST_ALLOCATED;
- WTF_MAKE_NONCOPYABLE(FunctionParameters);
+ class ModuleNameNode : public Node {
+ public:
+ ModuleNameNode(const JSTokenLocation&, const Identifier& moduleName);
+
+ const Identifier& moduleName() { return m_moduleName; }
+
+ private:
+ const Identifier& m_moduleName;
+ };
+
+ class ImportSpecifierNode : public Node {
+ public:
+ ImportSpecifierNode(const JSTokenLocation&, const Identifier& importedName, const Identifier& localName);
+
+ const Identifier& importedName() { return m_importedName; }
+ const Identifier& localName() { return m_localName; }
+
+ private:
+ const Identifier& m_importedName;
+ const Identifier& m_localName;
+ };
+
+ class ImportSpecifierListNode : public ParserArenaDeletable {
+ public:
+ typedef Vector<ImportSpecifierNode*, 3> Specifiers;
+
+ const Specifiers& specifiers() const { return m_specifiers; }
+ void append(ImportSpecifierNode* specifier)
+ {
+ m_specifiers.append(specifier);
+ }
+
+ private:
+ Specifiers m_specifiers;
+ };
+
+ class ModuleDeclarationNode : public StatementNode {
+ public:
+ virtual void analyzeModule(ModuleAnalyzer&) = 0;
+ bool isModuleDeclarationNode() const override { return true; }
+
+ protected:
+ ModuleDeclarationNode(const JSTokenLocation&);
+ };
+
+ class ImportDeclarationNode : public ModuleDeclarationNode {
+ public:
+ ImportDeclarationNode(const JSTokenLocation&, ImportSpecifierListNode*, ModuleNameNode*);
+
+ ImportSpecifierListNode* specifierList() const { return m_specifierList; }
+ ModuleNameNode* moduleName() const { return m_moduleName; }
+
+ private:
+ void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+ void analyzeModule(ModuleAnalyzer&) override;
+
+ ImportSpecifierListNode* m_specifierList;
+ ModuleNameNode* m_moduleName;
+ };
+
+ class ExportAllDeclarationNode : public ModuleDeclarationNode {
+ public:
+ ExportAllDeclarationNode(const JSTokenLocation&, ModuleNameNode*);
+
+ ModuleNameNode* moduleName() const { return m_moduleName; }
+
+ private:
+ void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+ void analyzeModule(ModuleAnalyzer&) override;
+
+ ModuleNameNode* m_moduleName;
+ };
+
+ class ExportDefaultDeclarationNode : public ModuleDeclarationNode {
+ public:
+ ExportDefaultDeclarationNode(const JSTokenLocation&, StatementNode*, const Identifier& localName);
+
+ const StatementNode& declaration() const { return *m_declaration; }
+ const Identifier& localName() const { return m_localName; }
+
+ private:
+ void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+ void analyzeModule(ModuleAnalyzer&) override;
+ StatementNode* m_declaration;
+ const Identifier& m_localName;
+ };
+
+ class ExportLocalDeclarationNode : public ModuleDeclarationNode {
+ public:
+ ExportLocalDeclarationNode(const JSTokenLocation&, StatementNode*);
+
+ const StatementNode& declaration() const { return *m_declaration; }
+
+ private:
+ void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+ void analyzeModule(ModuleAnalyzer&) override;
+ StatementNode* m_declaration;
+ };
+
+ class ExportSpecifierNode : public Node {
public:
- static PassRefPtr<FunctionParameters> create(ParameterNode*);
- ~FunctionParameters();
+ ExportSpecifierNode(const JSTokenLocation&, const Identifier& localName, const Identifier& exportedName);
- unsigned size() const { return m_size; }
- DeconstructionPatternNode* at(unsigned index) { ASSERT(index < m_size); return patterns()[index]; }
+ const Identifier& exportedName() { return m_exportedName; }
+ const Identifier& localName() { return m_localName; }
private:
- FunctionParameters(ParameterNode*, unsigned size);
+ const Identifier& m_localName;
+ const Identifier& m_exportedName;
+ };
- DeconstructionPatternNode** patterns() { return &m_storage; }
+ class ExportSpecifierListNode : public ParserArenaDeletable {
+ public:
+ typedef Vector<ExportSpecifierNode*, 3> Specifiers;
- unsigned m_size;
- DeconstructionPatternNode* m_storage;
+ const Specifiers& specifiers() const { return m_specifiers; }
+ void append(ExportSpecifierNode* specifier)
+ {
+ m_specifiers.append(specifier);
+ }
+
+ private:
+ Specifiers m_specifiers;
};
- class FunctionBodyNode : public ScopeNode {
+ class ExportNamedDeclarationNode : public ModuleDeclarationNode {
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);
+ ExportNamedDeclarationNode(const JSTokenLocation&, ExportSpecifierListNode*, ModuleNameNode*);
+
+ ExportSpecifierListNode* specifierList() const { return m_specifierList; }
+ ModuleNameNode* moduleName() const { return m_moduleName; }
+
+ private:
+ void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+ void analyzeModule(ModuleAnalyzer&) override;
+ ExportSpecifierListNode* m_specifierList;
+ ModuleNameNode* m_moduleName { nullptr };
+ };
- FunctionParameters* parameters() const { return m_parameters.get(); }
- size_t parameterCount() const { return m_parameters->size(); }
+ class FunctionMetadataNode final : public Node, public ParserArenaDeletable {
+ public:
+ using ParserArenaDeletable::operator new;
- virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+ FunctionMetadataNode(
+ ParserArena&, const JSTokenLocation& start, const JSTokenLocation& end,
+ unsigned startColumn, unsigned endColumn, int functionKeywordStart,
+ int functionNameStart, int parametersStart, bool isInStrictContext,
+ ConstructorKind, SuperBinding, unsigned parameterCount,
+ SourceParseMode, bool isArrowFunctionBodyExpression);
- void finishParsing(const SourceCode&, ParameterNode*, const Identifier&, FunctionNameIsInScopeToggle);
- void finishParsing(PassRefPtr<FunctionParameters>, const Identifier&, FunctionNameIsInScopeToggle);
+ void finishParsing(const SourceCode&, const Identifier&, FunctionMode);
+ void overrideName(const Identifier& ident) { m_ident = ident; }
const Identifier& ident() { return m_ident; }
+ void setEcmaName(const Identifier& ecmaName) { m_ecmaName = ecmaName; }
+ const Identifier& ecmaName() { return m_ident.isEmpty() ? m_ecmaName : m_ident; }
void setInferredName(const Identifier& inferredName) { ASSERT(!inferredName.isNull()); m_inferredName = inferredName; }
const Identifier& inferredName() { return m_inferredName.isEmpty() ? m_ident : m_inferredName; }
- bool functionNameIsInScope() { return m_functionNameIsInScopeToggle == FunctionNameIsInScope; }
- FunctionNameIsInScopeToggle functionNameIsInScopeToggle() { return m_functionNameIsInScopeToggle; }
+ 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; }
+ unsigned parameterCount() const { return m_parameterCount; }
+ SourceParseMode parseMode() const { return m_parseMode; }
void setEndPosition(JSTextPosition);
- static const bool scopeIsFunction = true;
+ const SourceCode& source() const { return m_source; }
+ const SourceCode& classSource() const { return m_classSource; }
+ void setClassSource(const SourceCode& source) { m_classSource = 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; }
+ SuperBinding superBinding() { return static_cast<SuperBinding>(m_superBinding); }
+ ConstructorKind constructorKind() { return static_cast<ConstructorKind>(m_constructorKind); }
+ bool isArrowFunctionBodyExpression() const { return m_isArrowFunctionBodyExpression; }
+ void setLoc(unsigned firstLine, unsigned lastLine, int startOffset, int lineStartOffset)
+ {
+ m_lastLine = lastLine;
+ m_position = JSTextPosition(firstLine, startOffset, lineStartOffset);
+ ASSERT(m_position.offset >= m_position.lineStartOffset);
+ }
+ unsigned lastLine() const { return m_lastLine; }
+
+ protected:
Identifier m_ident;
+ Identifier m_ecmaName;
Identifier m_inferredName;
- FunctionNameIsInScopeToggle m_functionNameIsInScopeToggle;
- RefPtr<FunctionParameters> m_parameters;
+ FunctionMode m_functionMode;
+ unsigned m_startColumn;
+ unsigned m_endColumn;
+ int m_functionKeywordStart;
int m_functionNameStart;
+ int m_parametersStart;
+ SourceCode m_source;
+ SourceCode m_classSource;
+ int m_startStartOffset;
+ unsigned m_parameterCount;
+ int m_lastLine;
+ SourceParseMode m_parseMode;
+ unsigned m_isInStrictContext : 1;
+ unsigned m_superBinding : 1;
+ unsigned m_constructorKind : 2;
+ unsigned m_isArrowFunctionBodyExpression : 1;
+ };
+
+ class FunctionNode final : public ScopeNode {
+ public:
+ FunctionNode(ParserArena&, const JSTokenLocation& start, const JSTokenLocation& end, unsigned startColumn, unsigned endColumn, SourceElements*, VariableEnvironment&, FunctionStack&&, VariableEnvironment&, UniquedStringImplPtrSet&&, FunctionParameters*, const SourceCode&, CodeFeatures, InnerArrowFunctionCodeFeatures, int numConstants, RefPtr<ModuleScopeData>&&);
+
+ FunctionParameters* parameters() const { return m_parameters; }
+
+ void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+
+ bool isFunctionNode() const override { return true; }
+
+ void finishParsing(const Identifier&, FunctionMode);
+
+ const Identifier& ident() { return m_ident; }
+
+ FunctionMode functionMode() const { 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;
+ FunctionParameters* m_parameters;
unsigned m_startColumn;
unsigned m_endColumn;
};
- class FuncExprNode : public ExpressionNode {
+ class BaseFuncExprNode : public ExpressionNode {
+ public:
+ FunctionMetadataNode* metadata() { return m_metadata; }
+
+ bool isBaseFuncExprNode() const override { return true; }
+
+ protected:
+ BaseFuncExprNode(const JSTokenLocation&, const Identifier&, FunctionMetadataNode*, const SourceCode&, FunctionMode);
+
+ FunctionMetadataNode* m_metadata;
+ };
+
+
+ class FuncExprNode : public BaseFuncExprNode {
public:
- FuncExprNode(const JSTokenLocation&, const Identifier&, FunctionBodyNode*, const SourceCode&, ParameterNode* = 0);
+ FuncExprNode(const JSTokenLocation&, const Identifier&, FunctionMetadataNode*, const SourceCode&);
- FunctionBodyNode* body() { return m_body; }
+ protected:
+ FuncExprNode(const JSTokenLocation&, const Identifier&, FunctionMetadataNode*, const SourceCode&, FunctionMode);
private:
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+ RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
- virtual bool isFuncExprNode() const override { return true; }
+ bool isFuncExprNode() const override { return true; }
+ };
- FunctionBodyNode* m_body;
+ class ArrowFuncExprNode : public BaseFuncExprNode {
+ public:
+ ArrowFuncExprNode(const JSTokenLocation&, const Identifier&, FunctionMetadataNode*, const SourceCode&);
+
+ private:
+ RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+
+ bool isArrowFuncExprNode() const override { return true; }
};
- class DeconstructionPatternNode : public RefCounted<DeconstructionPatternNode> {
- WTF_MAKE_NONCOPYABLE(DeconstructionPatternNode);
- WTF_MAKE_FAST_ALLOCATED;
+ class MethodDefinitionNode : public FuncExprNode {
+ public:
+ MethodDefinitionNode(const JSTokenLocation&, const Identifier&, FunctionMetadataNode*, const SourceCode&);
+
+ private:
+ RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+ };
+ class YieldExprNode final : public ExpressionNode, public ThrowableExpressionData {
public:
+ YieldExprNode(const JSTokenLocation&, ExpressionNode* argument, bool delegate);
+
+ ExpressionNode* argument() const { return m_argument; }
+ bool delegate() const { return m_delegate; }
+
+ private:
+ RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+
+ ExpressionNode* m_argument;
+ bool m_delegate;
+ };
+
+ class AwaitExprNode final : public ExpressionNode, public ThrowableExpressionData {
+ public:
+ AwaitExprNode(const JSTokenLocation&, ExpressionNode* argument);
+
+ ExpressionNode* argument() const { return m_argument; }
+
+ private:
+ RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+
+ ExpressionNode* m_argument;
+ };
+
+ class ClassExprNode final : public ExpressionNode, public VariableEnvironmentNode {
+ public:
+ using ParserArenaDeletable::operator new;
+
+ ClassExprNode(const JSTokenLocation&, const Identifier&, const SourceCode& classSource,
+ VariableEnvironment& classEnvironment, ExpressionNode* constructorExpresssion,
+ ExpressionNode* parentClass, PropertyListNode* instanceMethods, PropertyListNode* staticMethods);
+
+ const Identifier& name() { return m_name; }
+ const Identifier& ecmaName() { return m_ecmaName ? *m_ecmaName : m_name; }
+ void setEcmaName(const Identifier& name) { m_ecmaName = m_name.isNull() ? &name : &m_name; }
+
+ bool hasStaticProperty(const Identifier& propName) { return m_staticMethods ? m_staticMethods->hasStaticallyNamedProperty(propName) : false; }
+
+ private:
+ RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+
+ bool isClassExprNode() const override { return true; }
+
+ SourceCode m_classSource;
+ const Identifier& m_name;
+ const Identifier* m_ecmaName;
+ ExpressionNode* m_constructorExpression;
+ ExpressionNode* m_classHeritage;
+ PropertyListNode* m_instanceMethods;
+ PropertyListNode* m_staticMethods;
+ };
+
+ class DestructuringPatternNode : public ParserArenaFreeable {
+ public:
+ virtual ~DestructuringPatternNode() { }
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 bool isRestParameter() const { return false; }
virtual RegisterID* emitDirectBinding(BytecodeGenerator&, RegisterID*, ExpressionNode*) { return 0; }
- virtual ~DeconstructionPatternNode() = 0;
-
protected:
- DeconstructionPatternNode(VM*);
+ DestructuringPatternNode();
};
- class ArrayPatternNode : public DeconstructionPatternNode {
+ class ArrayPatternNode : public DestructuringPatternNode, public ThrowableExpressionData, public ParserArenaDeletable {
public:
- static PassRefPtr<ArrayPatternNode> create(VM*);
- void appendIndex(const JSTokenLocation&, DeconstructionPatternNode* node)
+ using ParserArenaDeletable::operator new;
+
+ ArrayPatternNode();
+ enum class BindingType {
+ Elision,
+ Element,
+ RestElement
+ };
+
+ void appendIndex(BindingType bindingType, const JSTokenLocation&, DestructuringPatternNode* node, ExpressionNode* defaultValue)
{
- m_targetPatterns.append(node);
+ m_targetPatterns.append({ bindingType, node, defaultValue });
}
private:
- ArrayPatternNode(VM*);
- 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;
+ struct Entry {
+ BindingType bindingType;
+ DestructuringPatternNode* pattern;
+ ExpressionNode* defaultValue;
+ };
+ void collectBoundIdentifiers(Vector<Identifier>&) const override;
+ void bindValue(BytecodeGenerator&, RegisterID*) const override;
+ RegisterID* emitDirectBinding(BytecodeGenerator&, RegisterID* dst, ExpressionNode*) override;
+ void toString(StringBuilder&) const override;
- Vector<RefPtr<DeconstructionPatternNode>> m_targetPatterns;
+ Vector<Entry> m_targetPatterns;
};
- class ObjectPatternNode : public DeconstructionPatternNode {
+ class ObjectPatternNode : public DestructuringPatternNode, public ParserArenaDeletable {
public:
- static PassRefPtr<ObjectPatternNode> create(VM*);
- void appendEntry(const JSTokenLocation&, const Identifier& identifier, bool wasString, DeconstructionPatternNode* pattern)
+ using ParserArenaDeletable::operator new;
+
+ ObjectPatternNode();
+ 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, nullptr, wasString, pattern, defaultValue });
}
-
+
+ void appendEntry(const JSTokenLocation&, ExpressionNode* propertyExpression, DestructuringPatternNode* pattern, ExpressionNode* defaultValue)
+ {
+ m_targetPatterns.append(Entry{ Identifier(), propertyExpression, false, pattern, defaultValue });
+ }
+
private:
- ObjectPatternNode(VM*);
- virtual void collectBoundIdentifiers(Vector<Identifier>&) const override;
- virtual void bindValue(BytecodeGenerator&, RegisterID*) const override;
- virtual void toString(StringBuilder&) const override;
+ void collectBoundIdentifiers(Vector<Identifier>&) const override;
+ void bindValue(BytecodeGenerator&, RegisterID*) const override;
+ void toString(StringBuilder&) const override;
struct Entry {
- Entry(const Identifier& propertyName, bool wasString, DeconstructionPatternNode* pattern)
- : propertyName(propertyName)
- , wasString(wasString)
- , pattern(pattern)
- {
- }
- Identifier propertyName;
+ const Identifier& propertyName;
+ ExpressionNode* propertyExpression;
bool wasString;
- RefPtr<DeconstructionPatternNode> pattern;
+ 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);
+ BindingNode(const Identifier& boundProperty, const JSTextPosition& start, const JSTextPosition& end, AssignmentContext);
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);
-
- virtual void collectBoundIdentifiers(Vector<Identifier>&) const override;
- virtual void bindValue(BytecodeGenerator&, RegisterID*) const override;
- virtual void toString(StringBuilder&) const override;
+ void collectBoundIdentifiers(Vector<Identifier>&) const override;
+ void bindValue(BytecodeGenerator&, RegisterID*) const override;
+ void toString(StringBuilder&) const override;
- virtual bool isBindingNode() const override { return true; }
+ bool isBindingNode() const override { return true; }
JSTextPosition m_divotStart;
JSTextPosition m_divotEnd;
- Identifier m_boundProperty;
+ const Identifier& m_boundProperty;
+ AssignmentContext m_bindingContext;
};
- class DeconstructingAssignmentNode : public ExpressionNode, public ParserArenaDeletable {
+ class RestParameterNode : public DestructuringPatternNode {
public:
- DeconstructingAssignmentNode(const JSTokenLocation&, PassRefPtr<DeconstructionPatternNode>, ExpressionNode*);
- DeconstructionPatternNode* bindings() { return m_bindings.get(); }
-
- using ParserArenaDeletable::operator new;
+ RestParameterNode(DestructuringPatternNode*, unsigned numParametersToSkip);
+
+ bool isRestParameter() const override { return true; }
+
+ void emit(BytecodeGenerator&);
+
+ private:
+ void collectBoundIdentifiers(Vector<Identifier>&) const override;
+ void bindValue(BytecodeGenerator&, RegisterID*) const override;
+ void toString(StringBuilder&) const override;
+
+ DestructuringPatternNode* m_pattern;
+ unsigned m_numParametersToSkip;
+ };
+
+ class AssignmentElementNode : public DestructuringPatternNode {
+ public:
+ AssignmentElementNode(ExpressionNode* assignmentTarget, const JSTextPosition& start, const JSTextPosition& end);
+ const ExpressionNode* assignmentTarget() { return m_assignmentTarget; }
+
+ const JSTextPosition& divotStart() const { return m_divotStart; }
+ const JSTextPosition& divotEnd() const { return m_divotEnd; }
private:
- virtual bool isLocation() const override { return true; }
- virtual bool isDeconstructionNode() const override { return true; }
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+ void collectBoundIdentifiers(Vector<Identifier>&) const override;
+ void bindValue(BytecodeGenerator&, RegisterID*) const override;
+ void toString(StringBuilder&) const override;
- RefPtr<DeconstructionPatternNode> m_bindings;
+ JSTextPosition m_divotStart;
+ JSTextPosition m_divotEnd;
+ ExpressionNode* m_assignmentTarget;
+ };
+
+ class DestructuringAssignmentNode : public ExpressionNode {
+ public:
+ DestructuringAssignmentNode(const JSTokenLocation&, DestructuringPatternNode*, ExpressionNode*);
+ DestructuringPatternNode* bindings() { return m_bindings; }
+
+ private:
+ bool isAssignmentLocation() const override { return true; }
+ bool isDestructuringNode() const override { return true; }
+ RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+
+ DestructuringPatternNode* m_bindings;
ExpressionNode* m_initializer;
};
+ class FunctionParameters : public ParserArenaDeletable {
+ public:
+ FunctionParameters();
+ ALWAYS_INLINE unsigned size() const { return m_patterns.size(); }
+ ALWAYS_INLINE std::pair<DestructuringPatternNode*, ExpressionNode*> at(unsigned index) { return m_patterns[index]; }
+ ALWAYS_INLINE void append(DestructuringPatternNode* pattern, ExpressionNode* defaultValue)
+ {
+ ASSERT(pattern);
+
+ // http://www.ecma-international.org/ecma-262/6.0/index.html#sec-functiondeclarationinstantiation
+ // This implements IsSimpleParameterList in the Ecma 2015 spec.
+ // If IsSimpleParameterList is false, we will create a strict-mode like arguments object.
+ // IsSimpleParameterList is false if the argument list contains any default parameter values,
+ // a rest parameter, or any destructuring patterns.
+ // If we do have default parameters, destructuring parameters, or a rest parameter, our parameters will be allocated in a different scope.
+
+ bool hasDefaultParameterValue = defaultValue;
+ bool isSimpleParameter = !hasDefaultParameterValue && pattern->isBindingNode();
+ m_isSimpleParameterList &= isSimpleParameter;
+
+ m_patterns.append(std::make_pair(pattern, defaultValue));
+ }
+ ALWAYS_INLINE bool isSimpleParameterList() const { return m_isSimpleParameterList; }
+
+ private:
+
+ Vector<std::pair<DestructuringPatternNode*, ExpressionNode*>, 3> m_patterns;
+ bool m_isSimpleParameterList { true };
+ };
+
class FuncDeclNode : public StatementNode {
public:
- FuncDeclNode(const JSTokenLocation&, const Identifier&, FunctionBodyNode*, const SourceCode&, ParameterNode* = 0);
+ FuncDeclNode(const JSTokenLocation&, const Identifier&, FunctionMetadataNode*, const SourceCode&);
- FunctionBodyNode* body() { return m_body; }
+ bool isFuncDeclNode() const override { return true; }
+ FunctionMetadataNode* metadata() { return m_metadata; }
private:
- virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+ void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
- FunctionBodyNode* m_body;
+ FunctionMetadataNode* m_metadata;
+ };
+
+ class ClassDeclNode final : public StatementNode {
+ public:
+ ClassDeclNode(const JSTokenLocation&, ExpressionNode* classExpression);
+
+ private:
+ void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+
+ ExpressionNode* m_classDeclaration;
};
class CaseClauseNode : public ParserArenaFreeable {
@@ -1698,10 +2270,12 @@ namespace JSC {
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 {
@@ -1731,12 +2305,14 @@ namespace JSC {
ClauseListNode* m_list2;
};
- class SwitchNode : public StatementNode {
+ class SwitchNode : public StatementNode, public VariableEnvironmentNode {
public:
- SwitchNode(const JSTokenLocation&, ExpressionNode*, CaseBlockNode*);
+ using ParserArenaDeletable::operator new;
+
+ SwitchNode(const JSTokenLocation&, ExpressionNode*, CaseBlockNode*, VariableEnvironment&, FunctionStack&&);
private:
- virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+ void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
ExpressionNode* m_expr;
CaseBlockNode* m_block;
@@ -1757,21 +2333,9 @@ namespace JSC {
ArgumentListNode* tail;
};
- struct ConstDeclList {
- ConstDeclNode* head;
- ConstDeclNode* tail;
- };
-
- struct ParameterList {
- ParameterNode* head;
- ParameterNode* tail;
- };
-
struct ClauseList {
ClauseListNode* head;
ClauseListNode* tail;
};
} // namespace JSC
-
-#endif // Nodes_h