diff options
author | Michaƫl Zasso <targos@protonmail.com> | 2018-01-24 20:16:06 +0100 |
---|---|---|
committer | Myles Borins <mylesborins@google.com> | 2018-01-24 15:02:20 -0800 |
commit | 4c4af643e5042d615a60c6bbc05aee9d81b903e5 (patch) | |
tree | 3fb0a97988fe4439ae3ae06f26915d1dcf8cab92 /deps/v8/src/ast | |
parent | fa9f31a4fda5a3782c652e56e394465805ebb50f (diff) | |
download | android-node-v8-4c4af643e5042d615a60c6bbc05aee9d81b903e5.tar.gz android-node-v8-4c4af643e5042d615a60c6bbc05aee9d81b903e5.tar.bz2 android-node-v8-4c4af643e5042d615a60c6bbc05aee9d81b903e5.zip |
deps: update V8 to 6.4.388.40
PR-URL: https://github.com/nodejs/node/pull/17489
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Myles Borins <myles.borins@gmail.com>
Reviewed-By: Ali Ijaz Sheikh <ofrobots@google.com>
Diffstat (limited to 'deps/v8/src/ast')
-rw-r--r-- | deps/v8/src/ast/ast-expression-rewriter.cc | 410 | ||||
-rw-r--r-- | deps/v8/src/ast/ast-expression-rewriter.h | 53 | ||||
-rw-r--r-- | deps/v8/src/ast/ast-numbering.cc | 178 | ||||
-rw-r--r-- | deps/v8/src/ast/ast-numbering.h | 9 | ||||
-rw-r--r-- | deps/v8/src/ast/ast-source-ranges.h | 42 | ||||
-rw-r--r-- | deps/v8/src/ast/ast-traversal-visitor.h | 35 | ||||
-rw-r--r-- | deps/v8/src/ast/ast-value-factory.cc | 167 | ||||
-rw-r--r-- | deps/v8/src/ast/ast-value-factory.h | 256 | ||||
-rw-r--r-- | deps/v8/src/ast/ast.cc | 479 | ||||
-rw-r--r-- | deps/v8/src/ast/ast.h | 923 | ||||
-rw-r--r-- | deps/v8/src/ast/context-slot-cache.h | 4 | ||||
-rw-r--r-- | deps/v8/src/ast/modules.h | 17 | ||||
-rw-r--r-- | deps/v8/src/ast/prettyprinter.cc | 283 | ||||
-rw-r--r-- | deps/v8/src/ast/prettyprinter.h | 16 | ||||
-rw-r--r-- | deps/v8/src/ast/scopes.cc | 78 | ||||
-rw-r--r-- | deps/v8/src/ast/scopes.h | 29 | ||||
-rw-r--r-- | deps/v8/src/ast/variables.h | 4 |
17 files changed, 948 insertions, 2035 deletions
diff --git a/deps/v8/src/ast/ast-expression-rewriter.cc b/deps/v8/src/ast/ast-expression-rewriter.cc deleted file mode 100644 index 02a4408a60..0000000000 --- a/deps/v8/src/ast/ast-expression-rewriter.cc +++ /dev/null @@ -1,410 +0,0 @@ -// Copyright 2015 the V8 project authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "src/ast/ast-expression-rewriter.h" -#include "src/ast/ast.h" -#include "src/objects-inl.h" - -namespace v8 { -namespace internal { - -// ---------------------------------------------------------------------------- -// Implementation of AstExpressionRewriter -// The AST is traversed but no actual rewriting takes place, unless the -// Visit methods are overriden in subclasses. - -#define REWRITE_THIS(node) \ - do { \ - if (!RewriteExpression(node)) return; \ - } while (false) -#define NOTHING() DCHECK_NULL(replacement_) - -void AstExpressionRewriter::VisitDeclarations(Declaration::List* declarations) { - for (Declaration::List::Iterator it = declarations->begin(); - it != declarations->end(); ++it) { - AST_REWRITE(Declaration, *it, it = replacement); - } -} - - -void AstExpressionRewriter::VisitStatements(ZoneList<Statement*>* statements) { - for (int i = 0; i < statements->length(); i++) { - AST_REWRITE_LIST_ELEMENT(Statement, statements, i); - if (statements->at(i)->IsJump()) break; - } -} - - -void AstExpressionRewriter::VisitExpressions( - ZoneList<Expression*>* expressions) { - for (int i = 0; i < expressions->length(); i++) { - // The variable statement visiting code may pass NULL expressions - // to this code. Maybe this should be handled by introducing an - // undefined expression or literal? Revisit this code if this - // changes - if (expressions->at(i) != nullptr) { - AST_REWRITE_LIST_ELEMENT(Expression, expressions, i); - } - } -} - - -void AstExpressionRewriter::VisitVariableDeclaration( - VariableDeclaration* node) { - // Not visiting `proxy_`. - NOTHING(); -} - - -void AstExpressionRewriter::VisitFunctionDeclaration( - FunctionDeclaration* node) { - // Not visiting `proxy_`. - AST_REWRITE_PROPERTY(FunctionLiteral, node, fun); -} - - -void AstExpressionRewriter::VisitBlock(Block* node) { - VisitStatements(node->statements()); -} - - -void AstExpressionRewriter::VisitExpressionStatement( - ExpressionStatement* node) { - AST_REWRITE_PROPERTY(Expression, node, expression); -} - - -void AstExpressionRewriter::VisitEmptyStatement(EmptyStatement* node) { - NOTHING(); -} - - -void AstExpressionRewriter::VisitSloppyBlockFunctionStatement( - SloppyBlockFunctionStatement* node) { - AST_REWRITE_PROPERTY(Statement, node, statement); -} - - -void AstExpressionRewriter::VisitIfStatement(IfStatement* node) { - AST_REWRITE_PROPERTY(Expression, node, condition); - AST_REWRITE_PROPERTY(Statement, node, then_statement); - AST_REWRITE_PROPERTY(Statement, node, else_statement); -} - - -void AstExpressionRewriter::VisitContinueStatement(ContinueStatement* node) { - NOTHING(); -} - - -void AstExpressionRewriter::VisitBreakStatement(BreakStatement* node) { - NOTHING(); -} - - -void AstExpressionRewriter::VisitReturnStatement(ReturnStatement* node) { - AST_REWRITE_PROPERTY(Expression, node, expression); -} - - -void AstExpressionRewriter::VisitWithStatement(WithStatement* node) { - AST_REWRITE_PROPERTY(Expression, node, expression); - AST_REWRITE_PROPERTY(Statement, node, statement); -} - - -void AstExpressionRewriter::VisitSwitchStatement(SwitchStatement* node) { - AST_REWRITE_PROPERTY(Expression, node, tag); - for (CaseClause* clause : *node->cases()) { - if (!clause->is_default()) { - AST_REWRITE_PROPERTY(Expression, clause, label); - } - VisitStatements(clause->statements()); - } -} - - -void AstExpressionRewriter::VisitDoWhileStatement(DoWhileStatement* node) { - AST_REWRITE_PROPERTY(Expression, node, cond); - AST_REWRITE_PROPERTY(Statement, node, body); -} - - -void AstExpressionRewriter::VisitWhileStatement(WhileStatement* node) { - AST_REWRITE_PROPERTY(Expression, node, cond); - AST_REWRITE_PROPERTY(Statement, node, body); -} - - -void AstExpressionRewriter::VisitForStatement(ForStatement* node) { - if (node->init() != nullptr) { - AST_REWRITE_PROPERTY(Statement, node, init); - } - if (node->cond() != nullptr) { - AST_REWRITE_PROPERTY(Expression, node, cond); - } - if (node->next() != nullptr) { - AST_REWRITE_PROPERTY(Statement, node, next); - } - AST_REWRITE_PROPERTY(Statement, node, body); -} - - -void AstExpressionRewriter::VisitForInStatement(ForInStatement* node) { - AST_REWRITE_PROPERTY(Expression, node, each); - AST_REWRITE_PROPERTY(Expression, node, subject); - AST_REWRITE_PROPERTY(Statement, node, body); -} - - -void AstExpressionRewriter::VisitForOfStatement(ForOfStatement* node) { - AST_REWRITE_PROPERTY(Expression, node, assign_iterator); - AST_REWRITE_PROPERTY(Expression, node, next_result); - AST_REWRITE_PROPERTY(Expression, node, result_done); - AST_REWRITE_PROPERTY(Expression, node, assign_each); - AST_REWRITE_PROPERTY(Statement, node, body); -} - - -void AstExpressionRewriter::VisitTryCatchStatement(TryCatchStatement* node) { - AST_REWRITE_PROPERTY(Block, node, try_block); - // Not visiting the variable. - AST_REWRITE_PROPERTY(Block, node, catch_block); -} - - -void AstExpressionRewriter::VisitTryFinallyStatement( - TryFinallyStatement* node) { - AST_REWRITE_PROPERTY(Block, node, try_block); - AST_REWRITE_PROPERTY(Block, node, finally_block); -} - - -void AstExpressionRewriter::VisitDebuggerStatement(DebuggerStatement* node) { - NOTHING(); -} - - -void AstExpressionRewriter::VisitFunctionLiteral(FunctionLiteral* node) { - REWRITE_THIS(node); - VisitDeclarations(node->scope()->declarations()); - ZoneList<Statement*>* body = node->body(); - if (body != nullptr) VisitStatements(body); -} - - -void AstExpressionRewriter::VisitClassLiteral(ClassLiteral* node) { - REWRITE_THIS(node); - // Not visiting `class_variable_proxy_`. - if (node->extends() != nullptr) { - AST_REWRITE_PROPERTY(Expression, node, extends); - } - AST_REWRITE_PROPERTY(FunctionLiteral, node, constructor); - ZoneList<typename ClassLiteral::Property*>* properties = node->properties(); - for (int i = 0; i < properties->length(); i++) { - VisitLiteralProperty(properties->at(i)); - } -} - -void AstExpressionRewriter::VisitNativeFunctionLiteral( - NativeFunctionLiteral* node) { - REWRITE_THIS(node); - NOTHING(); -} - - -void AstExpressionRewriter::VisitConditional(Conditional* node) { - REWRITE_THIS(node); - AST_REWRITE_PROPERTY(Expression, node, condition); - AST_REWRITE_PROPERTY(Expression, node, then_expression); - AST_REWRITE_PROPERTY(Expression, node, else_expression); -} - - -void AstExpressionRewriter::VisitVariableProxy(VariableProxy* node) { - REWRITE_THIS(node); - NOTHING(); -} - - -void AstExpressionRewriter::VisitLiteral(Literal* node) { - REWRITE_THIS(node); - NOTHING(); -} - - -void AstExpressionRewriter::VisitRegExpLiteral(RegExpLiteral* node) { - REWRITE_THIS(node); - NOTHING(); -} - - -void AstExpressionRewriter::VisitObjectLiteral(ObjectLiteral* node) { - REWRITE_THIS(node); - ZoneList<typename ObjectLiteral::Property*>* properties = node->properties(); - for (int i = 0; i < properties->length(); i++) { - VisitLiteralProperty(properties->at(i)); - } -} - -void AstExpressionRewriter::VisitLiteralProperty(LiteralProperty* property) { - if (property == nullptr) return; - AST_REWRITE_PROPERTY(Expression, property, key); - AST_REWRITE_PROPERTY(Expression, property, value); -} - - -void AstExpressionRewriter::VisitArrayLiteral(ArrayLiteral* node) { - REWRITE_THIS(node); - VisitExpressions(node->values()); -} - - -void AstExpressionRewriter::VisitAssignment(Assignment* node) { - REWRITE_THIS(node); - AST_REWRITE_PROPERTY(Expression, node, target); - AST_REWRITE_PROPERTY(Expression, node, value); -} - -void AstExpressionRewriter::VisitCompoundAssignment(CompoundAssignment* node) { - VisitAssignment(node); -} - -void AstExpressionRewriter::VisitYield(Yield* node) { - REWRITE_THIS(node); - AST_REWRITE_PROPERTY(Expression, node, expression); -} - -void AstExpressionRewriter::VisitYieldStar(YieldStar* node) { - REWRITE_THIS(node); - AST_REWRITE_PROPERTY(Expression, node, expression); -} - -void AstExpressionRewriter::VisitAwait(Await* node) { - REWRITE_THIS(node); - AST_REWRITE_PROPERTY(Expression, node, expression); -} - -void AstExpressionRewriter::VisitThrow(Throw* node) { - REWRITE_THIS(node); - AST_REWRITE_PROPERTY(Expression, node, exception); -} - - -void AstExpressionRewriter::VisitProperty(Property* node) { - REWRITE_THIS(node); - if (node == nullptr) return; - AST_REWRITE_PROPERTY(Expression, node, obj); - AST_REWRITE_PROPERTY(Expression, node, key); -} - - -void AstExpressionRewriter::VisitCall(Call* node) { - REWRITE_THIS(node); - AST_REWRITE_PROPERTY(Expression, node, expression); - VisitExpressions(node->arguments()); -} - - -void AstExpressionRewriter::VisitCallNew(CallNew* node) { - REWRITE_THIS(node); - AST_REWRITE_PROPERTY(Expression, node, expression); - VisitExpressions(node->arguments()); -} - - -void AstExpressionRewriter::VisitCallRuntime(CallRuntime* node) { - REWRITE_THIS(node); - VisitExpressions(node->arguments()); -} - - -void AstExpressionRewriter::VisitUnaryOperation(UnaryOperation* node) { - REWRITE_THIS(node); - AST_REWRITE_PROPERTY(Expression, node, expression); -} - - -void AstExpressionRewriter::VisitCountOperation(CountOperation* node) { - REWRITE_THIS(node); - AST_REWRITE_PROPERTY(Expression, node, expression); -} - - -void AstExpressionRewriter::VisitBinaryOperation(BinaryOperation* node) { - REWRITE_THIS(node); - AST_REWRITE_PROPERTY(Expression, node, left); - AST_REWRITE_PROPERTY(Expression, node, right); -} - - -void AstExpressionRewriter::VisitCompareOperation(CompareOperation* node) { - REWRITE_THIS(node); - AST_REWRITE_PROPERTY(Expression, node, left); - AST_REWRITE_PROPERTY(Expression, node, right); -} - - -void AstExpressionRewriter::VisitSpread(Spread* node) { - REWRITE_THIS(node); - AST_REWRITE_PROPERTY(Expression, node, expression); -} - - -void AstExpressionRewriter::VisitThisFunction(ThisFunction* node) { - REWRITE_THIS(node); - NOTHING(); -} - - -void AstExpressionRewriter::VisitSuperPropertyReference( - SuperPropertyReference* node) { - REWRITE_THIS(node); - AST_REWRITE_PROPERTY(VariableProxy, node, this_var); - AST_REWRITE_PROPERTY(Expression, node, home_object); -} - - -void AstExpressionRewriter::VisitSuperCallReference(SuperCallReference* node) { - REWRITE_THIS(node); - AST_REWRITE_PROPERTY(VariableProxy, node, this_var); - AST_REWRITE_PROPERTY(VariableProxy, node, new_target_var); - AST_REWRITE_PROPERTY(VariableProxy, node, this_function_var); -} - - -void AstExpressionRewriter::VisitEmptyParentheses(EmptyParentheses* node) { - NOTHING(); -} - -void AstExpressionRewriter::VisitGetIterator(GetIterator* node) { - AST_REWRITE_PROPERTY(Expression, node, iterable); -} - -void AstExpressionRewriter::VisitGetTemplateObject(GetTemplateObject* node) { - NOTHING(); -} - -void AstExpressionRewriter::VisitImportCallExpression( - ImportCallExpression* node) { - REWRITE_THIS(node); - AST_REWRITE_PROPERTY(Expression, node, argument); -} - -void AstExpressionRewriter::VisitDoExpression(DoExpression* node) { - REWRITE_THIS(node); - AST_REWRITE_PROPERTY(Block, node, block); - AST_REWRITE_PROPERTY(VariableProxy, node, result); -} - - -void AstExpressionRewriter::VisitRewritableExpression( - RewritableExpression* node) { - REWRITE_THIS(node); - AST_REWRITE(Expression, node->expression(), node->Rewrite(replacement)); -} - - -} // namespace internal -} // namespace v8 diff --git a/deps/v8/src/ast/ast-expression-rewriter.h b/deps/v8/src/ast/ast-expression-rewriter.h deleted file mode 100644 index c246fcd37d..0000000000 --- a/deps/v8/src/ast/ast-expression-rewriter.h +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright 2015 the V8 project authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef V8_AST_AST_EXPRESSION_REWRITER_H_ -#define V8_AST_AST_EXPRESSION_REWRITER_H_ - -#include "src/allocation.h" -#include "src/ast/ast.h" -#include "src/ast/scopes.h" -#include "src/zone/zone.h" - -namespace v8 { -namespace internal { - -// A rewriting Visitor over a CompilationInfo's AST that invokes -// VisitExpression on each expression node. - -// This AstVistor is not final, and provides the AstVisitor methods as virtual -// methods so they can be specialized by subclasses. -class AstExpressionRewriter : public AstVisitor<AstExpressionRewriter> { - public: - explicit AstExpressionRewriter(Isolate* isolate) { - InitializeAstRewriter(isolate); - } - explicit AstExpressionRewriter(uintptr_t stack_limit) { - InitializeAstRewriter(stack_limit); - } - virtual ~AstExpressionRewriter() {} - - virtual void VisitDeclarations(Declaration::List* declarations); - virtual void VisitStatements(ZoneList<Statement*>* statements); - virtual void VisitExpressions(ZoneList<Expression*>* expressions); - - virtual void VisitLiteralProperty(LiteralProperty* property); - - protected: - virtual bool RewriteExpression(Expression* expr) = 0; - - private: - DEFINE_AST_REWRITER_SUBCLASS_MEMBERS(); - -#define DECLARE_VISIT(type) virtual void Visit##type(type* node); - AST_NODE_LIST(DECLARE_VISIT) -#undef DECLARE_VISIT - - DISALLOW_COPY_AND_ASSIGN(AstExpressionRewriter); -}; - -} // namespace internal -} // namespace v8 - -#endif // V8_AST_AST_EXPRESSION_REWRITER_H_ diff --git a/deps/v8/src/ast/ast-numbering.cc b/deps/v8/src/ast/ast-numbering.cc index 3df7aae861..0736e543e2 100644 --- a/deps/v8/src/ast/ast-numbering.cc +++ b/deps/v8/src/ast/ast-numbering.cc @@ -15,16 +15,11 @@ namespace internal { class AstNumberingVisitor final : public AstVisitor<AstNumberingVisitor> { public: AstNumberingVisitor(uintptr_t stack_limit, Zone* zone, - Compiler::EagerInnerFunctionLiterals* eager_literals, - bool collect_type_profile = false) + Compiler::EagerInnerFunctionLiterals* eager_literals) : zone_(zone), eager_literals_(eager_literals), suspend_count_(0), - properties_(zone), - language_mode_(SLOPPY), - slot_cache_(zone), - dont_optimize_reason_(kNoReason), - collect_type_profile_(collect_type_profile) { + dont_optimize_reason_(kNoReason) { InitializeAstVisitor(stack_limit); } @@ -36,10 +31,6 @@ class AstNumberingVisitor final : public AstVisitor<AstNumberingVisitor> { AST_NODE_LIST(DEFINE_VISIT) #undef DEFINE_VISIT - void VisitVariableProxy(VariableProxy* node, TypeofMode typeof_mode); - void VisitVariableProxyReference(VariableProxy* node); - void VisitPropertyReference(Property* node); - void VisitReference(Expression* expr); void VisitSuspend(Suspend* node); void VisitStatementsAndDeclarations(Block* node); @@ -52,25 +43,6 @@ class AstNumberingVisitor final : public AstVisitor<AstNumberingVisitor> { dont_optimize_reason_ = reason; } - template <typename Node> - void ReserveFeedbackSlots(Node* node) { - node->AssignFeedbackSlots(properties_.get_spec(), language_mode_, - function_kind_, &slot_cache_); - } - - class LanguageModeScope { - public: - LanguageModeScope(AstNumberingVisitor* visitor, LanguageMode language_mode) - : visitor_(visitor), outer_language_mode_(visitor->language_mode_) { - visitor_->language_mode_ = language_mode; - } - ~LanguageModeScope() { visitor_->language_mode_ = outer_language_mode_; } - - private: - AstNumberingVisitor* visitor_; - LanguageMode outer_language_mode_; - }; - BailoutReason dont_optimize_reason() const { return dont_optimize_reason_; } Zone* zone() const { return zone_; } @@ -78,105 +50,72 @@ class AstNumberingVisitor final : public AstVisitor<AstNumberingVisitor> { Zone* zone_; Compiler::EagerInnerFunctionLiterals* eager_literals_; int suspend_count_; - AstProperties properties_; - LanguageMode language_mode_; FunctionKind function_kind_; - // The slot cache allows us to reuse certain feedback slots. - FeedbackSlotCache slot_cache_; BailoutReason dont_optimize_reason_; - bool collect_type_profile_; DEFINE_AST_VISITOR_SUBCLASS_MEMBERS(); DISALLOW_COPY_AND_ASSIGN(AstNumberingVisitor); }; - void AstNumberingVisitor::VisitVariableDeclaration(VariableDeclaration* node) { VisitVariableProxy(node->proxy()); } - void AstNumberingVisitor::VisitEmptyStatement(EmptyStatement* node) { } - void AstNumberingVisitor::VisitSloppyBlockFunctionStatement( SloppyBlockFunctionStatement* node) { Visit(node->statement()); } - void AstNumberingVisitor::VisitContinueStatement(ContinueStatement* node) { } - void AstNumberingVisitor::VisitBreakStatement(BreakStatement* node) { } - void AstNumberingVisitor::VisitDebuggerStatement(DebuggerStatement* node) { } - void AstNumberingVisitor::VisitNativeFunctionLiteral( NativeFunctionLiteral* node) { DisableOptimization(kNativeFunctionLiteral); - ReserveFeedbackSlots(node); } - void AstNumberingVisitor::VisitDoExpression(DoExpression* node) { Visit(node->block()); Visit(node->result()); } - void AstNumberingVisitor::VisitLiteral(Literal* node) { } - void AstNumberingVisitor::VisitRegExpLiteral(RegExpLiteral* node) { - ReserveFeedbackSlots(node); -} - - -void AstNumberingVisitor::VisitVariableProxyReference(VariableProxy* node) { -} - -void AstNumberingVisitor::VisitVariableProxy(VariableProxy* node, - TypeofMode typeof_mode) { - VisitVariableProxyReference(node); - node->AssignFeedbackSlots(properties_.get_spec(), typeof_mode, &slot_cache_); } void AstNumberingVisitor::VisitVariableProxy(VariableProxy* node) { - VisitVariableProxy(node, NOT_INSIDE_TYPEOF); } - void AstNumberingVisitor::VisitThisFunction(ThisFunction* node) { } - void AstNumberingVisitor::VisitSuperPropertyReference( SuperPropertyReference* node) { Visit(node->this_var()); Visit(node->home_object()); } - void AstNumberingVisitor::VisitSuperCallReference(SuperCallReference* node) { Visit(node->this_var()); Visit(node->new_target_var()); Visit(node->this_function_var()); } - void AstNumberingVisitor::VisitExpressionStatement(ExpressionStatement* node) { Visit(node->expression()); } - void AstNumberingVisitor::VisitReturnStatement(ReturnStatement* node) { Visit(node->expression()); } @@ -196,7 +135,6 @@ void AstNumberingVisitor::VisitYieldStar(YieldStar* node) { node->set_await_delegated_iterator_output_suspend_id(suspend_count_++); } Visit(node->expression()); - ReserveFeedbackSlots(node); } void AstNumberingVisitor::VisitAwait(Await* node) { VisitSuspend(node); } @@ -205,32 +143,16 @@ void AstNumberingVisitor::VisitThrow(Throw* node) { Visit(node->exception()); } - void AstNumberingVisitor::VisitUnaryOperation(UnaryOperation* node) { - if ((node->op() == Token::TYPEOF) && node->expression()->IsVariableProxy()) { - VariableProxy* proxy = node->expression()->AsVariableProxy(); - VisitVariableProxy(proxy, INSIDE_TYPEOF); - } else { - Visit(node->expression()); - } - ReserveFeedbackSlots(node); + Visit(node->expression()); } - void AstNumberingVisitor::VisitCountOperation(CountOperation* node) { Visit(node->expression()); - ReserveFeedbackSlots(node); } - void AstNumberingVisitor::VisitBlock(Block* node) { - Scope* scope = node->scope(); - if (scope != nullptr) { - LanguageModeScope language_mode_scope(this, scope->language_mode()); - VisitStatementsAndDeclarations(node); - } else { - VisitStatementsAndDeclarations(node); - } + VisitStatementsAndDeclarations(node); } void AstNumberingVisitor::VisitStatementsAndDeclarations(Block* node) { @@ -245,18 +167,15 @@ void AstNumberingVisitor::VisitFunctionDeclaration(FunctionDeclaration* node) { VisitFunctionLiteral(node->fun()); } - void AstNumberingVisitor::VisitCallRuntime(CallRuntime* node) { VisitArguments(node->arguments()); } - void AstNumberingVisitor::VisitWithStatement(WithStatement* node) { Visit(node->expression()); Visit(node->statement()); } - void AstNumberingVisitor::VisitDoWhileStatement(DoWhileStatement* node) { node->set_first_suspend_id(suspend_count_); Visit(node->body()); @@ -264,7 +183,6 @@ void AstNumberingVisitor::VisitDoWhileStatement(DoWhileStatement* node) { node->set_suspend_count(suspend_count_ - node->first_suspend_id()); } - void AstNumberingVisitor::VisitWhileStatement(WhileStatement* node) { node->set_first_suspend_id(suspend_count_); Visit(node->cond()); @@ -272,46 +190,25 @@ void AstNumberingVisitor::VisitWhileStatement(WhileStatement* node) { node->set_suspend_count(suspend_count_ - node->first_suspend_id()); } - void AstNumberingVisitor::VisitTryCatchStatement(TryCatchStatement* node) { DCHECK(node->scope() == nullptr || !node->scope()->HasBeenRemoved()); Visit(node->try_block()); Visit(node->catch_block()); } - void AstNumberingVisitor::VisitTryFinallyStatement(TryFinallyStatement* node) { Visit(node->try_block()); Visit(node->finally_block()); } - -void AstNumberingVisitor::VisitPropertyReference(Property* node) { +void AstNumberingVisitor::VisitProperty(Property* node) { Visit(node->key()); Visit(node->obj()); } - -void AstNumberingVisitor::VisitReference(Expression* expr) { - DCHECK(expr->IsProperty() || expr->IsVariableProxy()); - if (expr->IsProperty()) { - VisitPropertyReference(expr->AsProperty()); - } else { - VisitVariableProxyReference(expr->AsVariableProxy()); - } -} - - -void AstNumberingVisitor::VisitProperty(Property* node) { - VisitPropertyReference(node); - ReserveFeedbackSlots(node); -} - - void AstNumberingVisitor::VisitAssignment(Assignment* node) { - VisitReference(node->target()); + Visit(node->target()); Visit(node->value()); - ReserveFeedbackSlots(node); } void AstNumberingVisitor::VisitCompoundAssignment(CompoundAssignment* node) { @@ -322,14 +219,18 @@ void AstNumberingVisitor::VisitCompoundAssignment(CompoundAssignment* node) { void AstNumberingVisitor::VisitBinaryOperation(BinaryOperation* node) { Visit(node->left()); Visit(node->right()); - ReserveFeedbackSlots(node); } +void AstNumberingVisitor::VisitNaryOperation(NaryOperation* node) { + Visit(node->first()); + for (size_t i = 0; i < node->subsequent_length(); ++i) { + Visit(node->subsequent(i)); + } +} void AstNumberingVisitor::VisitCompareOperation(CompareOperation* node) { Visit(node->left()); Visit(node->right()); - ReserveFeedbackSlots(node); } void AstNumberingVisitor::VisitSpread(Spread* node) { @@ -342,7 +243,6 @@ void AstNumberingVisitor::VisitEmptyParentheses(EmptyParentheses* node) { void AstNumberingVisitor::VisitGetIterator(GetIterator* node) { Visit(node->iterable()); - ReserveFeedbackSlots(node); } void AstNumberingVisitor::VisitGetTemplateObject(GetTemplateObject* node) {} @@ -358,10 +258,8 @@ void AstNumberingVisitor::VisitForInStatement(ForInStatement* node) { Visit(node->each()); Visit(node->body()); node->set_suspend_count(suspend_count_ - node->first_suspend_id()); - ReserveFeedbackSlots(node); } - void AstNumberingVisitor::VisitForOfStatement(ForOfStatement* node) { Visit(node->assign_iterator()); // Not part of loop. node->set_first_suspend_id(suspend_count_); @@ -372,14 +270,12 @@ void AstNumberingVisitor::VisitForOfStatement(ForOfStatement* node) { node->set_suspend_count(suspend_count_ - node->first_suspend_id()); } - void AstNumberingVisitor::VisitConditional(Conditional* node) { Visit(node->condition()); Visit(node->then_expression()); Visit(node->else_expression()); } - void AstNumberingVisitor::VisitIfStatement(IfStatement* node) { Visit(node->condition()); Visit(node->then_statement()); @@ -388,37 +284,43 @@ void AstNumberingVisitor::VisitIfStatement(IfStatement* node) { } } - void AstNumberingVisitor::VisitSwitchStatement(SwitchStatement* node) { Visit(node->tag()); for (CaseClause* clause : *node->cases()) { if (!clause->is_default()) Visit(clause->label()); VisitStatements(clause->statements()); - ReserveFeedbackSlots(clause); } } - void AstNumberingVisitor::VisitForStatement(ForStatement* node) { - if (node->init() != NULL) Visit(node->init()); // Not part of loop. + if (node->init() != nullptr) Visit(node->init()); // Not part of loop. node->set_first_suspend_id(suspend_count_); - if (node->cond() != NULL) Visit(node->cond()); - if (node->next() != NULL) Visit(node->next()); + if (node->cond() != nullptr) Visit(node->cond()); + if (node->next() != nullptr) Visit(node->next()); Visit(node->body()); node->set_suspend_count(suspend_count_ - node->first_suspend_id()); } - void AstNumberingVisitor::VisitClassLiteral(ClassLiteral* node) { - LanguageModeScope language_mode_scope(this, STRICT); if (node->extends()) Visit(node->extends()); if (node->constructor()) Visit(node->constructor()); + if (node->static_fields_initializer() != nullptr) { + Visit(node->static_fields_initializer()); + } + if (node->instance_fields_initializer_function() != nullptr) { + Visit(node->instance_fields_initializer_function()); + } for (int i = 0; i < node->properties()->length(); i++) { VisitLiteralProperty(node->properties()->at(i)); } - ReserveFeedbackSlots(node); } +void AstNumberingVisitor::VisitInitializeClassFieldsStatement( + InitializeClassFieldsStatement* node) { + for (int i = 0; i < node->fields()->length(); i++) { + VisitLiteralProperty(node->fields()->at(i)); + } +} void AstNumberingVisitor::VisitObjectLiteral(ObjectLiteral* node) { for (int i = 0; i < node->properties()->length(); i++) { @@ -429,7 +331,6 @@ void AstNumberingVisitor::VisitObjectLiteral(ObjectLiteral* node) { // is shadowed by a later occurrence of the same key. For the // marked expressions, no store code will be is emitted. node->CalculateEmitStore(zone_); - ReserveFeedbackSlots(node); } void AstNumberingVisitor::VisitLiteralProperty(LiteralProperty* node) { @@ -442,26 +343,20 @@ void AstNumberingVisitor::VisitArrayLiteral(ArrayLiteral* node) { Visit(node->values()->at(i)); } node->InitDepthAndFlags(); - ReserveFeedbackSlots(node); } - void AstNumberingVisitor::VisitCall(Call* node) { - ReserveFeedbackSlots(node); Visit(node->expression()); VisitArguments(node->arguments()); } - void AstNumberingVisitor::VisitCallNew(CallNew* node) { - ReserveFeedbackSlots(node); Visit(node->expression()); VisitArguments(node->arguments()); } - void AstNumberingVisitor::VisitStatements(ZoneList<Statement*>* statements) { - if (statements == NULL) return; + if (statements == nullptr) return; for (int i = 0; i < statements->length(); i++) { Visit(statements->at(i)); if (statements->at(i)->IsJump()) break; @@ -472,14 +367,12 @@ void AstNumberingVisitor::VisitDeclarations(Declaration::List* decls) { for (Declaration* decl : *decls) Visit(decl); } - void AstNumberingVisitor::VisitArguments(ZoneList<Expression*>* arguments) { for (int i = 0; i < arguments->length(); i++) { Visit(arguments->at(i)); } } - void AstNumberingVisitor::VisitFunctionLiteral(FunctionLiteral* node) { if (node->ShouldEagerCompile()) { if (eager_literals_) { @@ -494,30 +387,21 @@ void AstNumberingVisitor::VisitFunctionLiteral(FunctionLiteral* node) { return; } } - ReserveFeedbackSlots(node); } - void AstNumberingVisitor::VisitRewritableExpression( RewritableExpression* node) { Visit(node->expression()); } - bool AstNumberingVisitor::Renumber(FunctionLiteral* node) { DeclarationScope* scope = node->scope(); DCHECK(!scope->HasBeenRemoved()); function_kind_ = node->kind(); - LanguageModeScope language_mode_scope(this, node->language_mode()); - - if (collect_type_profile_) { - properties_.get_spec()->AddTypeProfileSlot(); - } VisitDeclarations(scope->declarations()); VisitStatements(node->body()); - node->set_ast_properties(&properties_); node->set_dont_optimize_reason(dont_optimize_reason()); node->set_suspend_count(suspend_count_); @@ -526,14 +410,12 @@ bool AstNumberingVisitor::Renumber(FunctionLiteral* node) { bool AstNumbering::Renumber( uintptr_t stack_limit, Zone* zone, FunctionLiteral* function, - Compiler::EagerInnerFunctionLiterals* eager_literals, - bool collect_type_profile) { + Compiler::EagerInnerFunctionLiterals* eager_literals) { DisallowHeapAllocation no_allocation; DisallowHandleAllocation no_handles; DisallowHandleDereference no_deref; - AstNumberingVisitor visitor(stack_limit, zone, eager_literals, - collect_type_profile); + AstNumberingVisitor visitor(stack_limit, zone, eager_literals); return visitor.Renumber(function); } } // namespace internal diff --git a/deps/v8/src/ast/ast-numbering.h b/deps/v8/src/ast/ast-numbering.h index 82987ef593..11122803b8 100644 --- a/deps/v8/src/ast/ast-numbering.h +++ b/deps/v8/src/ast/ast-numbering.h @@ -22,13 +22,12 @@ template <typename T> class ZoneVector; namespace AstNumbering { -// Assign type feedback IDs, bailout IDs, and generator suspend IDs to an AST -// node tree; perform catch prediction for TryStatements. If |eager_literals| is -// non-null, adds any eager inner literal functions into it. +// Assign bailout IDs, and generator suspend IDs to an AST node tree; perform +// catch prediction for TryStatements. If |eager_literals| is non-null, adds any +// eager inner literal functions into it. bool Renumber( uintptr_t stack_limit, Zone* zone, FunctionLiteral* function, - ThreadedList<ThreadedListZoneEntry<FunctionLiteral*>>* eager_literals, - bool collect_type_profile = false); + ThreadedList<ThreadedListZoneEntry<FunctionLiteral*>>* eager_literals); } // Some details on suspend IDs diff --git a/deps/v8/src/ast/ast-source-ranges.h b/deps/v8/src/ast/ast-source-ranges.h index 55554b1043..cf7bab53da 100644 --- a/deps/v8/src/ast/ast-source-ranges.h +++ b/deps/v8/src/ast/ast-source-ranges.h @@ -30,12 +30,14 @@ struct SourceRange { // The list of ast node kinds that have associated source ranges. Note that this // macro is not undefined at the end of this file. #define AST_SOURCE_RANGE_LIST(V) \ + V(BinaryOperation) \ V(Block) \ V(CaseClause) \ V(Conditional) \ V(IfStatement) \ V(IterationStatement) \ V(JumpStatement) \ + V(NaryOperation) \ V(Suspend) \ V(SwitchStatement) \ V(Throw) \ @@ -48,6 +50,7 @@ enum class SourceRangeKind { kContinuation, kElse, kFinally, + kRight, kThen, }; @@ -57,13 +60,27 @@ class AstNodeSourceRanges : public ZoneObject { virtual SourceRange GetRange(SourceRangeKind kind) = 0; }; +class BinaryOperationSourceRanges final : public AstNodeSourceRanges { + public: + explicit BinaryOperationSourceRanges(const SourceRange& right_range) + : right_range_(right_range) {} + + SourceRange GetRange(SourceRangeKind kind) { + DCHECK_EQ(kind, SourceRangeKind::kRight); + return right_range_; + } + + private: + SourceRange right_range_; +}; + class ContinuationSourceRanges : public AstNodeSourceRanges { public: explicit ContinuationSourceRanges(int32_t continuation_position) : continuation_position_(continuation_position) {} SourceRange GetRange(SourceRangeKind kind) { - DCHECK(kind == SourceRangeKind::kContinuation); + DCHECK_EQ(kind, SourceRangeKind::kContinuation); return SourceRange::OpenEnded(continuation_position_); } @@ -83,7 +100,7 @@ class CaseClauseSourceRanges final : public AstNodeSourceRanges { : body_range_(body_range) {} SourceRange GetRange(SourceRangeKind kind) { - DCHECK(kind == SourceRangeKind::kBody); + DCHECK_EQ(kind, SourceRangeKind::kBody); return body_range_; } @@ -166,6 +183,27 @@ class JumpStatementSourceRanges final : public ContinuationSourceRanges { : ContinuationSourceRanges(continuation_position) {} }; +class NaryOperationSourceRanges final : public AstNodeSourceRanges { + public: + NaryOperationSourceRanges(Zone* zone, const SourceRange& range) + : ranges_(zone) { + AddRange(range); + } + + SourceRange GetRangeAtIndex(size_t index) { + DCHECK(index < ranges_.size()); + return ranges_[index]; + } + + void AddRange(const SourceRange& range) { ranges_.push_back(range); } + size_t RangeCount() const { return ranges_.size(); } + + SourceRange GetRange(SourceRangeKind kind) { UNREACHABLE(); } + + private: + ZoneVector<SourceRange> ranges_; +}; + class SuspendSourceRanges final : public ContinuationSourceRanges { public: explicit SuspendSourceRanges(int32_t continuation_position) diff --git a/deps/v8/src/ast/ast-traversal-visitor.h b/deps/v8/src/ast/ast-traversal-visitor.h index 0fec89a58c..6ad4df357c 100644 --- a/deps/v8/src/ast/ast-traversal-visitor.h +++ b/deps/v8/src/ast/ast-traversal-visitor.h @@ -228,13 +228,13 @@ void AstTraversalVisitor<Subclass>::VisitWhileStatement(WhileStatement* stmt) { template <class Subclass> void AstTraversalVisitor<Subclass>::VisitForStatement(ForStatement* stmt) { PROCESS_NODE(stmt); - if (stmt->init() != NULL) { + if (stmt->init() != nullptr) { RECURSE(Visit(stmt->init())); } - if (stmt->cond() != NULL) { + if (stmt->cond() != nullptr) { RECURSE(Visit(stmt->cond())); } - if (stmt->next() != NULL) { + if (stmt->next() != nullptr) { RECURSE(Visit(stmt->next())); } RECURSE(Visit(stmt->body())); @@ -444,6 +444,15 @@ void AstTraversalVisitor<Subclass>::VisitBinaryOperation( } template <class Subclass> +void AstTraversalVisitor<Subclass>::VisitNaryOperation(NaryOperation* expr) { + PROCESS_EXPRESSION(expr); + RECURSE_EXPRESSION(Visit(expr->first())); + for (size_t i = 0; i < expr->subsequent_length(); ++i) { + RECURSE_EXPRESSION(Visit(expr->subsequent(i))); + } +} + +template <class Subclass> void AstTraversalVisitor<Subclass>::VisitCompareOperation( CompareOperation* expr) { PROCESS_EXPRESSION(expr); @@ -463,6 +472,12 @@ void AstTraversalVisitor<Subclass>::VisitClassLiteral(ClassLiteral* expr) { RECURSE_EXPRESSION(Visit(expr->extends())); } RECURSE_EXPRESSION(Visit(expr->constructor())); + if (expr->static_fields_initializer() != nullptr) { + RECURSE_EXPRESSION(Visit(expr->static_fields_initializer())); + } + if (expr->instance_fields_initializer_function() != nullptr) { + RECURSE_EXPRESSION(Visit(expr->instance_fields_initializer_function())); + } ZoneList<ClassLiteralProperty*>* props = expr->properties(); for (int i = 0; i < props->length(); ++i) { ClassLiteralProperty* prop = props->at(i); @@ -474,6 +489,20 @@ void AstTraversalVisitor<Subclass>::VisitClassLiteral(ClassLiteral* expr) { } template <class Subclass> +void AstTraversalVisitor<Subclass>::VisitInitializeClassFieldsStatement( + InitializeClassFieldsStatement* stmt) { + PROCESS_NODE(stmt); + ZoneList<ClassLiteralProperty*>* props = stmt->fields(); + for (int i = 0; i < props->length(); ++i) { + ClassLiteralProperty* prop = props->at(i); + if (!prop->key()->IsLiteral()) { + RECURSE(Visit(prop->key())); + } + RECURSE(Visit(prop->value())); + } +} + +template <class Subclass> void AstTraversalVisitor<Subclass>::VisitSpread(Spread* expr) { PROCESS_EXPRESSION(expr); RECURSE_EXPRESSION(Visit(expr->expression())); diff --git a/deps/v8/src/ast/ast-value-factory.cc b/deps/v8/src/ast/ast-value-factory.cc index b83ed4547e..458afb8bc1 100644 --- a/deps/v8/src/ast/ast-value-factory.cc +++ b/deps/v8/src/ast/ast-value-factory.cc @@ -168,102 +168,18 @@ void AstConsString::Internalize(Isolate* isolate) { set_string(tmp); } -AstValue::AstValue(double n) : next_(nullptr) { - int int_value; - if (DoubleToSmiInteger(n, &int_value)) { - type_ = SMI; - smi_ = int_value; - } else { - type_ = NUMBER; - number_ = n; - } -} - -bool AstValue::ToUint32(uint32_t* value) const { - if (IsSmi()) { - int num = smi_; - if (num < 0) return false; - *value = static_cast<uint32_t>(num); - return true; - } - if (IsHeapNumber()) { - return DoubleToUint32IfEqualToSelf(number_, value); - } - return false; -} - -bool AstValue::IsPropertyName() const { - if (type_ == STRING) { - uint32_t index; - return !string_->AsArrayIndex(&index); - } - return false; -} - - -bool AstValue::BooleanValue() const { - switch (type_) { - case STRING: - DCHECK(string_ != NULL); - return !string_->IsEmpty(); - case SYMBOL: - UNREACHABLE(); - break; - case NUMBER: - return DoubleToBoolean(number_); - case SMI: - return smi_ != 0; - case BOOLEAN: - return bool_; - case NULL_TYPE: - return false; - case THE_HOLE: - UNREACHABLE(); - break; - case UNDEFINED: - return false; +std::forward_list<const AstRawString*> AstConsString::ToRawStrings() const { + std::forward_list<const AstRawString*> result; + if (IsEmpty()) { + return result; } - UNREACHABLE(); -} - -void AstValue::Internalize(Isolate* isolate) { - switch (type_) { - case STRING: - DCHECK_NOT_NULL(string_); - // Strings are already internalized. - DCHECK(!string_->string().is_null()); - break; - case SYMBOL: - switch (symbol_) { - case AstSymbol::kHomeObjectSymbol: - set_value(isolate->factory()->home_object_symbol()); - break; - } - break; - case NUMBER: - set_value(isolate->factory()->NewNumber(number_, TENURED)); - break; - case SMI: - set_value(handle(Smi::FromInt(smi_), isolate)); - break; - case BOOLEAN: - if (bool_) { - set_value(isolate->factory()->true_value()); - } else { - set_value(isolate->factory()->false_value()); - } - break; - case NULL_TYPE: - set_value(isolate->factory()->null_value()); - break; - case THE_HOLE: - set_value(isolate->factory()->the_hole_value()); - break; - case UNDEFINED: - set_value(isolate->factory()->undefined_value()); - break; + result.emplace_front(segment_.string); + for (AstConsString::Segment* current = segment_.next; current != nullptr; + current = current->next) { + result.emplace_front(current->string); } + return result; } AstStringConstants::AstStringConstants(Isolate* isolate, uint32_t hash_seed) @@ -317,7 +233,7 @@ AstRawString* AstValueFactory::GetTwoByteStringInternal( const AstRawString* AstValueFactory::GetString(Handle<String> literal) { - AstRawString* result = NULL; + AstRawString* result = nullptr; DisallowHeapAllocation no_gc; String::FlatContent content = literal->GetFlatContent(); if (content.IsOneByte()) { @@ -361,72 +277,9 @@ void AstValueFactory::Internalize(Isolate* isolate) { current = next; } - for (AstValue* current = values_; current != nullptr;) { - AstValue* next = current->next(); - current->Internalize(isolate); - current = next; - } ResetStrings(); - values_ = nullptr; -} - - -const AstValue* AstValueFactory::NewString(const AstRawString* string) { - AstValue* value = new (zone_) AstValue(string); - CHECK_NOT_NULL(string); - return AddValue(value); -} - -const AstValue* AstValueFactory::NewSymbol(AstSymbol symbol) { - AstValue* value = new (zone_) AstValue(symbol); - return AddValue(value); -} - -const AstValue* AstValueFactory::NewNumber(double number) { - AstValue* value = new (zone_) AstValue(number); - return AddValue(value); -} - -const AstValue* AstValueFactory::NewSmi(uint32_t number) { - bool cacheable_smi = number <= kMaxCachedSmi; - if (cacheable_smi && smis_[number] != nullptr) return smis_[number]; - - AstValue* value = new (zone_) AstValue(AstValue::SMI, number); - if (cacheable_smi) smis_[number] = value; - return AddValue(value); } -#define GENERATE_VALUE_GETTER(value, initializer) \ - if (!value) { \ - value = AddValue(new (zone_) AstValue(initializer)); \ - } \ - return value; - -const AstValue* AstValueFactory::NewBoolean(bool b) { - if (b) { - GENERATE_VALUE_GETTER(true_value_, true); - } else { - GENERATE_VALUE_GETTER(false_value_, false); - } -} - - -const AstValue* AstValueFactory::NewNull() { - GENERATE_VALUE_GETTER(null_value_, AstValue::NULL_TYPE); -} - - -const AstValue* AstValueFactory::NewUndefined() { - GENERATE_VALUE_GETTER(undefined_value_, AstValue::UNDEFINED); -} - - -const AstValue* AstValueFactory::NewTheHole() { - GENERATE_VALUE_GETTER(the_hole_value_, AstValue::THE_HOLE); -} - - -#undef GENERATE_VALUE_GETTER AstRawString* AstValueFactory::GetString(uint32_t hash_field, bool is_one_byte, Vector<const byte> literal_bytes) { diff --git a/deps/v8/src/ast/ast-value-factory.h b/deps/v8/src/ast/ast-value-factory.h index e67c87b4c0..6a3aea5fa0 100644 --- a/deps/v8/src/ast/ast-value-factory.h +++ b/deps/v8/src/ast/ast-value-factory.h @@ -28,6 +28,8 @@ #ifndef V8_AST_AST_VALUE_FACTORY_H_ #define V8_AST_AST_VALUE_FACTORY_H_ +#include <forward_list> + #include "src/base/hashmap.h" #include "src/conversions.h" #include "src/factory.h" @@ -35,7 +37,7 @@ #include "src/isolate.h" #include "src/utils.h" -// Ast(Raw|Cons)String, AstValue and AstValueFactory are for storing strings and +// Ast(Raw|Cons)String and AstValueFactory are for storing strings and // values independent of the V8 heap and internalizing them later. During // parsing, they are created and stored outside the heap, in AstValueFactory. // After parsing, the strings and values are internalized (moved into the V8 @@ -151,6 +153,8 @@ class AstConsString final : public ZoneObject { return Handle<String>(string_); } + std::forward_list<const AstRawString*> ToRawStrings() const; + private: friend class AstValueFactory; @@ -176,167 +180,62 @@ class AstConsString final : public ZoneObject { enum class AstSymbol : uint8_t { kHomeObjectSymbol }; -// AstValue is either a string, a symbol, a number, a string array, a boolean, -// or a special value (null, undefined, the hole). -class AstValue : public ZoneObject { +class AstBigInt { public: - bool IsString() const { - return type_ == STRING; - } - - bool IsSymbol() const { return type_ == SYMBOL; } - - bool IsNumber() const { return IsSmi() || IsHeapNumber(); } - - const AstRawString* AsString() const { - CHECK_EQ(STRING, type_); - return string_; - } + // |bigint| must be a NUL-terminated string of ASCII characters + // representing a BigInt (suitable for passing to BigIntLiteral() + // from conversions.h). + explicit AstBigInt(const char* bigint) : bigint_(bigint) {} - AstSymbol AsSymbol() const { - CHECK_EQ(SYMBOL, type_); - return symbol_; - } - - double AsNumber() const { - if (IsHeapNumber()) return number_; - if (IsSmi()) return smi_; - UNREACHABLE(); - } - - Smi* AsSmi() const { - CHECK(IsSmi()); - return Smi::FromInt(smi_); - } - - bool ToUint32(uint32_t* value) const; - - bool EqualsString(const AstRawString* string) const { - return type_ == STRING && string_ == string; - } - - bool IsPropertyName() const; - - bool BooleanValue() const; - - bool IsSmi() const { return type_ == SMI; } - bool IsHeapNumber() const { return type_ == NUMBER; } - bool IsFalse() const { return type_ == BOOLEAN && !bool_; } - bool IsTrue() const { return type_ == BOOLEAN && bool_; } - bool IsUndefined() const { return type_ == UNDEFINED; } - bool IsTheHole() const { return type_ == THE_HOLE; } - bool IsNull() const { return type_ == NULL_TYPE; } - - void Internalize(Isolate* isolate); - - // Can be called after Internalize has been called. - V8_INLINE Handle<Object> value() const { - if (type_ == STRING) { - return string_->string(); - } - DCHECK_NOT_NULL(value_); - return Handle<Object>(value_); - } - AstValue* next() const { return next_; } - void set_next(AstValue* next) { next_ = next; } + const char* c_str() const { return bigint_; } private: - void set_value(Handle<Object> object) { value_ = object.location(); } - friend class AstValueFactory; - - enum Type { - STRING, - SYMBOL, - NUMBER, - SMI, - BOOLEAN, - NULL_TYPE, - UNDEFINED, - THE_HOLE - }; - - explicit AstValue(const AstRawString* s) : type_(STRING), next_(nullptr) { - string_ = s; - } - - explicit AstValue(AstSymbol symbol) : type_(SYMBOL), next_(nullptr) { - symbol_ = symbol; - } - - explicit AstValue(double n); - - AstValue(Type t, int i) : type_(t), next_(nullptr) { - DCHECK(type_ == SMI); - smi_ = i; - } - - explicit AstValue(bool b) : type_(BOOLEAN), next_(nullptr) { bool_ = b; } - - explicit AstValue(Type t) : type_(t), next_(nullptr) { - DCHECK(t == NULL_TYPE || t == UNDEFINED || t == THE_HOLE); - } - - Type type_; - - // {value_} is stored as Object** instead of a Handle<Object> so it can be - // stored in a union with {next_}. - union { - Object** value_; // if internalized - AstValue* next_; // if !internalized - }; - - // Uninternalized value. - union { - const AstRawString* string_; - double number_; - int smi_; - bool bool_; - AstSymbol symbol_; - }; + const char* bigint_; }; // For generating constants. -#define AST_STRING_CONSTANTS(F) \ - F(anonymous_function, "(anonymous function)") \ - F(arguments, "arguments") \ - F(async, "async") \ - F(await, "await") \ - F(boolean, "boolean") \ - F(constructor, "constructor") \ - F(default, "default") \ - F(done, "done") \ - F(dot, ".") \ - F(dot_for, ".for") \ - F(dot_generator_object, ".generator_object") \ - F(dot_iterator, ".iterator") \ - F(dot_result, ".result") \ - F(dot_switch_tag, ".switch_tag") \ - F(dot_catch, ".catch") \ - F(empty, "") \ - F(eval, "eval") \ - F(function, "function") \ - F(get_space, "get ") \ - F(length, "length") \ - F(let, "let") \ - F(name, "name") \ - F(native, "native") \ - F(new_target, ".new.target") \ - F(next, "next") \ - F(number, "number") \ - F(object, "object") \ - F(proto, "__proto__") \ - F(prototype, "prototype") \ - F(return, "return") \ - F(set_space, "set ") \ - F(star_default_star, "*default*") \ - F(string, "string") \ - F(symbol, "symbol") \ - F(this, "this") \ - F(this_function, ".this_function") \ - F(throw, "throw") \ - F(undefined, "undefined") \ - F(use_asm, "use asm") \ - F(use_strict, "use strict") \ +#define AST_STRING_CONSTANTS(F) \ + F(anonymous_function, "(anonymous function)") \ + F(arguments, "arguments") \ + F(async, "async") \ + F(await, "await") \ + F(bigint, "bigint") \ + F(boolean, "boolean") \ + F(constructor, "constructor") \ + F(default, "default") \ + F(done, "done") \ + F(dot, ".") \ + F(dot_for, ".for") \ + F(dot_generator_object, ".generator_object") \ + F(dot_iterator, ".iterator") \ + F(dot_result, ".result") \ + F(dot_switch_tag, ".switch_tag") \ + F(dot_catch, ".catch") \ + F(empty, "") \ + F(eval, "eval") \ + F(function, "function") \ + F(get_space, "get ") \ + F(length, "length") \ + F(let, "let") \ + F(name, "name") \ + F(native, "native") \ + F(new_target, ".new.target") \ + F(next, "next") \ + F(number, "number") \ + F(object, "object") \ + F(proto, "__proto__") \ + F(prototype, "prototype") \ + F(return, "return") \ + F(set_space, "set ") \ + F(star_default_star, "*default*") \ + F(string, "string") \ + F(symbol, "symbol") \ + F(this, "this") \ + F(this_function, ".this_function") \ + F(throw, "throw") \ + F(undefined, "undefined") \ + F(use_asm, "use asm") \ + F(use_strict, "use strict") \ F(value, "value") class AstStringConstants final { @@ -365,19 +264,11 @@ class AstStringConstants final { DISALLOW_COPY_AND_ASSIGN(AstStringConstants); }; -#define OTHER_CONSTANTS(F) \ - F(true_value) \ - F(false_value) \ - F(null_value) \ - F(undefined_value) \ - F(the_hole_value) - class AstValueFactory { public: AstValueFactory(Zone* zone, const AstStringConstants* string_constants, uint32_t hash_seed) : string_table_(string_constants->string_table()), - values_(nullptr), strings_(nullptr), strings_end_(&strings_), cons_strings_(nullptr), @@ -386,11 +277,7 @@ class AstValueFactory { empty_cons_string_(nullptr), zone_(zone), hash_seed_(hash_seed) { -#define F(name) name##_ = nullptr; - OTHER_CONSTANTS(F) -#undef F DCHECK_EQ(hash_seed, string_constants->hash_seed()); - std::fill(smis_, smis_ + arraysize(smis_), nullptr); std::fill(one_character_strings_, one_character_strings_ + arraysize(one_character_strings_), nullptr); @@ -425,27 +312,7 @@ class AstValueFactory { #undef F const AstConsString* empty_cons_string() const { return empty_cons_string_; } - V8_EXPORT_PRIVATE const AstValue* NewString(const AstRawString* string); - // A JavaScript symbol (ECMA-262 edition 6). - const AstValue* NewSymbol(AstSymbol symbol); - V8_EXPORT_PRIVATE const AstValue* NewNumber(double number); - const AstValue* NewSmi(uint32_t number); - const AstValue* NewBoolean(bool b); - const AstValue* NewStringList(ZoneList<const AstRawString*>* strings); - const AstValue* NewNull(); - const AstValue* NewUndefined(); - const AstValue* NewTheHole(); - private: - static const uint32_t kMaxCachedSmi = 1 << 10; - - STATIC_ASSERT(kMaxCachedSmi <= Smi::kMaxValue); - - AstValue* AddValue(AstValue* value) { - value->set_next(values_); - values_ = value; - return value; - } AstRawString* AddString(AstRawString* string) { *strings_end_ = string; strings_end_ = string->next_location(); @@ -468,11 +335,8 @@ class AstValueFactory { AstRawString* GetString(uint32_t hash, bool is_one_byte, Vector<const byte> literal_bytes); - // All strings are copied here, one after another (no NULLs inbetween). + // All strings are copied here, one after another (no zeroes inbetween). base::CustomMatcherHashMap string_table_; - // For keeping track of all AstValues and AstRawStrings we've created (so that - // they can be internalized later). - AstValue* values_; // We need to keep track of strings_ in order since cons strings require their // members to be internalized first. @@ -485,22 +349,14 @@ class AstValueFactory { const AstStringConstants* string_constants_; const AstConsString* empty_cons_string_; - // Caches for faster access: small numbers, one character lowercase strings - // (for minified code). - AstValue* smis_[kMaxCachedSmi + 1]; + // Caches one character lowercase strings (for minified code). AstRawString* one_character_strings_[26]; Zone* zone_; uint32_t hash_seed_; - -#define F(name) AstValue* name##_; - OTHER_CONSTANTS(F) -#undef F }; } // namespace internal } // namespace v8 -#undef OTHER_CONSTANTS - #endif // V8_AST_AST_VALUE_FACTORY_H_ diff --git a/deps/v8/src/ast/ast.cc b/deps/v8/src/ast/ast.cc index 94abe81bda..710cbb40a5 100644 --- a/deps/v8/src/ast/ast.cc +++ b/deps/v8/src/ast/ast.cc @@ -5,6 +5,7 @@ #include "src/ast/ast.h" #include <cmath> // For isfinite. +#include <vector> #include "src/ast/compile-time-value.h" #include "src/ast/prettyprinter.h" @@ -14,7 +15,7 @@ #include "src/builtins/builtins.h" #include "src/code-stubs.h" #include "src/contexts.h" -#include "src/conversions.h" +#include "src/conversions-inl.h" #include "src/double.h" #include "src/elements.h" #include "src/objects-inl.h" @@ -90,15 +91,15 @@ MaterializedLiteral* AstNode::AsMaterializedLiteral() { #undef RETURN_NODE bool Expression::IsSmiLiteral() const { - return IsLiteral() && AsLiteral()->raw_value()->IsSmi(); + return IsLiteral() && AsLiteral()->type() == Literal::kSmi; } bool Expression::IsNumberLiteral() const { - return IsLiteral() && AsLiteral()->raw_value()->IsNumber(); + return IsLiteral() && AsLiteral()->IsNumber(); } bool Expression::IsStringLiteral() const { - return IsLiteral() && AsLiteral()->raw_value()->IsString(); + return IsLiteral() && AsLiteral()->type() == Literal::kString; } bool Expression::IsPropertyName() const { @@ -106,19 +107,22 @@ bool Expression::IsPropertyName() const { } bool Expression::IsNullLiteral() const { - if (!IsLiteral()) return false; - return AsLiteral()->raw_value()->IsNull(); + return IsLiteral() && AsLiteral()->type() == Literal::kNull; +} + +bool Expression::IsTheHoleLiteral() const { + return IsLiteral() && AsLiteral()->type() == Literal::kTheHole; } bool Expression::IsUndefinedLiteral() const { - if (IsLiteral() && AsLiteral()->raw_value()->IsUndefined()) return true; + if (IsLiteral() && AsLiteral()->type() == Literal::kUndefined) return true; const VariableProxy* var_proxy = AsVariableProxy(); if (var_proxy == nullptr) return false; Variable* var = var_proxy->var(); // The global identifier "undefined" is immutable. Everything // else could be reassigned. - return var != NULL && var->IsUnallocated() && + return var != nullptr && var->IsUnallocated() && var_proxy->raw_name()->IsOneByteEqualTo("undefined"); } @@ -201,76 +205,12 @@ void VariableProxy::BindTo(Variable* var) { if (is_assigned()) var->set_maybe_assigned(); } -void VariableProxy::AssignFeedbackSlots(FeedbackVectorSpec* spec, - TypeofMode typeof_mode, - FeedbackSlotCache* cache) { - if (UsesVariableFeedbackSlot()) { - // VariableProxies that point to the same Variable within a function can - // make their loads from the same IC slot. - if (var()->IsUnallocated() || var()->mode() == DYNAMIC_GLOBAL) { - FeedbackSlot slot = cache->Get(typeof_mode, var()); - if (!slot.IsInvalid()) { - variable_feedback_slot_ = slot; - return; - } - variable_feedback_slot_ = spec->AddLoadGlobalICSlot(typeof_mode); - cache->Put(typeof_mode, var(), variable_feedback_slot_); - } else { - variable_feedback_slot_ = spec->AddLoadICSlot(); - } - } -} - -static void AssignVectorSlots(Expression* expr, FeedbackVectorSpec* spec, - LanguageMode language_mode, - FeedbackSlot* out_slot) { - Property* property = expr->AsProperty(); - LhsKind assign_type = Property::GetAssignType(property); - // TODO(ishell): consider using ICSlotCache for variables here. - if (assign_type == VARIABLE && - expr->AsVariableProxy()->var()->IsUnallocated()) { - *out_slot = spec->AddStoreGlobalICSlot(language_mode); - - } else if (assign_type == NAMED_PROPERTY) { - *out_slot = spec->AddStoreICSlot(language_mode); - - } else if (assign_type == KEYED_PROPERTY) { - *out_slot = spec->AddKeyedStoreICSlot(language_mode); - } -} - -void ForInStatement::AssignFeedbackSlots(FeedbackVectorSpec* spec, - LanguageMode language_mode, - FunctionKind kind, - FeedbackSlotCache* cache) { - AssignVectorSlots(each(), spec, language_mode, &each_slot_); - for_in_feedback_slot_ = spec->AddForInSlot(); -} - Assignment::Assignment(NodeType node_type, Token::Value op, Expression* target, Expression* value, int pos) : Expression(pos, node_type), target_(target), value_(value) { bit_field_ |= TokenField::encode(op); } -void Assignment::AssignFeedbackSlots(FeedbackVectorSpec* spec, - LanguageMode language_mode, - FunctionKind kind, - FeedbackSlotCache* cache) { - AssignVectorSlots(target(), spec, language_mode, &slot_); -} - -void CountOperation::AssignFeedbackSlots(FeedbackVectorSpec* spec, - LanguageMode language_mode, - FunctionKind kind, - FeedbackSlotCache* cache) { - AssignVectorSlots(expression(), spec, language_mode, &slot_); - // Assign a slot to collect feedback about binary operations. Used only in - // ignition. Fullcodegen uses AstId to record type feedback. - binary_operation_slot_ = spec->AddInterpreterBinaryOpICSlot(); -} - - bool FunctionLiteral::ShouldEagerCompile() const { return scope()->ShouldEagerCompile(); } @@ -309,6 +249,34 @@ bool FunctionLiteral::NeedsHomeObject(Expression* expr) { return expr->AsFunctionLiteral()->scope()->NeedsHomeObject(); } +std::unique_ptr<char[]> FunctionLiteral::GetDebugName() const { + const AstConsString* cons_string; + if (raw_name_ != nullptr && !raw_name_->IsEmpty()) { + cons_string = raw_name_; + } else if (raw_inferred_name_ != nullptr && !raw_inferred_name_->IsEmpty()) { + cons_string = raw_inferred_name_; + } else if (!inferred_name_.is_null()) { + AllowHandleDereference allow_deref; + return inferred_name_->ToCString(); + } else { + return std::unique_ptr<char[]>(new char{'\0'}); + } + + // TODO(rmcilroy): Deal with two-character strings. + std::vector<char> result_vec; + std::forward_list<const AstRawString*> strings = cons_string->ToRawStrings(); + for (const AstRawString* string : strings) { + if (!string->is_one_byte()) break; + for (int i = 0; i < string->length(); i++) { + result_vec.push_back(string->raw_data()[i]); + } + } + std::unique_ptr<char[]> result(new char[result_vec.size() + 1]); + memcpy(result.get(), result_vec.data(), result_vec.size()); + result[result_vec.size()] = '\0'; + return result; +} + ObjectLiteralProperty::ObjectLiteralProperty(Expression* key, Expression* value, Kind kind, bool is_computed_name) : LiteralProperty(key, value, is_computed_name), @@ -319,11 +287,10 @@ ObjectLiteralProperty::ObjectLiteralProperty(AstValueFactory* ast_value_factory, Expression* key, Expression* value, bool is_computed_name) : LiteralProperty(key, value, is_computed_name), emit_store_(true) { - if (!is_computed_name && - key->AsLiteral()->raw_value()->EqualsString( - ast_value_factory->proto_string())) { + if (!is_computed_name && key->AsLiteral()->IsString() && + key->AsLiteral()->AsRawString() == ast_value_factory->proto_string()) { kind_ = PROTOTYPE; - } else if (value_->AsMaterializedLiteral() != NULL) { + } else if (value_->AsMaterializedLiteral() != nullptr) { kind_ = MATERIALIZED_LITERAL; } else if (value_->IsLiteral()) { kind_ = CONSTANT; @@ -332,16 +299,6 @@ ObjectLiteralProperty::ObjectLiteralProperty(AstValueFactory* ast_value_factory, } } -FeedbackSlot LiteralProperty::GetStoreDataPropertySlot() const { - int offset = FunctionLiteral::NeedsHomeObject(value_) ? 1 : 0; - return GetSlot(offset); -} - -void LiteralProperty::SetStoreDataPropertySlot(FeedbackSlot slot) { - int offset = FunctionLiteral::NeedsHomeObject(value_) ? 1 : 0; - return SetSlot(slot, offset); -} - bool LiteralProperty::NeedsSetFunctionName() const { return is_computed_name_ && (value_->IsAnonymousFunctionDefinition() || value_->IsConciseMethodDefinition() || @@ -353,28 +310,8 @@ ClassLiteralProperty::ClassLiteralProperty(Expression* key, Expression* value, bool is_computed_name) : LiteralProperty(key, value, is_computed_name), kind_(kind), - is_static_(is_static) {} - -void ClassLiteral::AssignFeedbackSlots(FeedbackVectorSpec* spec, - LanguageMode language_mode, - FunctionKind kind, - FeedbackSlotCache* cache) { - // This logic that computes the number of slots needed for vector store - // ICs must mirror BytecodeGenerator::VisitClassLiteral. - if (FunctionLiteral::NeedsHomeObject(constructor())) { - home_object_slot_ = spec->AddStoreICSlot(language_mode); - } - - for (int i = 0; i < properties()->length(); i++) { - ClassLiteral::Property* property = properties()->at(i); - Expression* value = property->value(); - if (FunctionLiteral::NeedsHomeObject(value)) { - property->SetSlot(spec->AddStoreICSlot(language_mode)); - } - property->SetStoreDataPropertySlot( - spec->AddStoreDataPropertyInLiteralICSlot()); - } -} + is_static_(is_static), + computed_name_var_(nullptr) {} bool ObjectLiteral::Property::IsCompileTimeValue() const { return kind_ == CONSTANT || @@ -389,77 +326,6 @@ void ObjectLiteral::Property::set_emit_store(bool emit_store) { bool ObjectLiteral::Property::emit_store() const { return emit_store_; } -void ObjectLiteral::AssignFeedbackSlots(FeedbackVectorSpec* spec, - LanguageMode language_mode, - FunctionKind kind, - FeedbackSlotCache* cache) { - // The empty object literal doesn't need any feedback vector slot. - if (this->IsEmptyObjectLiteral()) return; - - MaterializedLiteral::AssignFeedbackSlots(spec, language_mode, kind, cache); - - // This logic that computes the number of slots needed for vector store - // ics must mirror FullCodeGenerator::VisitObjectLiteral. - int property_index = 0; - for (; property_index < properties()->length(); property_index++) { - ObjectLiteral::Property* property = properties()->at(property_index); - if (property->is_computed_name()) break; - if (property->IsCompileTimeValue()) continue; - - Literal* key = property->key()->AsLiteral(); - Expression* value = property->value(); - switch (property->kind()) { - case ObjectLiteral::Property::SPREAD: - case ObjectLiteral::Property::CONSTANT: - UNREACHABLE(); - case ObjectLiteral::Property::MATERIALIZED_LITERAL: - // Fall through. - case ObjectLiteral::Property::COMPUTED: - // It is safe to use [[Put]] here because the boilerplate already - // contains computed properties with an uninitialized value. - if (key->IsStringLiteral()) { - if (property->emit_store()) { - property->SetSlot(spec->AddStoreOwnICSlot()); - if (FunctionLiteral::NeedsHomeObject(value)) { - property->SetSlot(spec->AddStoreICSlot(language_mode), 1); - } - } - break; - } - if (property->emit_store() && FunctionLiteral::NeedsHomeObject(value)) { - property->SetSlot(spec->AddStoreICSlot(language_mode)); - } - break; - case ObjectLiteral::Property::PROTOTYPE: - break; - case ObjectLiteral::Property::GETTER: - if (property->emit_store() && FunctionLiteral::NeedsHomeObject(value)) { - property->SetSlot(spec->AddStoreICSlot(language_mode)); - } - break; - case ObjectLiteral::Property::SETTER: - if (property->emit_store() && FunctionLiteral::NeedsHomeObject(value)) { - property->SetSlot(spec->AddStoreICSlot(language_mode)); - } - break; - } - } - - for (; property_index < properties()->length(); property_index++) { - ObjectLiteral::Property* property = properties()->at(property_index); - - Expression* value = property->value(); - if (!property->IsPrototype()) { - if (FunctionLiteral::NeedsHomeObject(value)) { - property->SetSlot(spec->AddStoreICSlot(language_mode)); - } - } - property->SetStoreDataPropertySlot( - spec->AddStoreDataPropertyInLiteralICSlot()); - } -} - - void ObjectLiteral::CalculateEmitStore(Zone* zone) { const auto GETTER = ObjectLiteral::Property::GETTER; const auto SETTER = ObjectLiteral::Property::SETTER; @@ -479,7 +345,7 @@ void ObjectLiteral::CalculateEmitStore(Zone* zone) { // entry was also an accessor. uint32_t hash = literal->Hash(); ZoneHashMap::Entry* entry = table.LookupOrInsert(literal, hash, allocator); - if (entry->value != NULL) { + if (entry->value != nullptr) { auto previous_kind = static_cast<ObjectLiteral::Property*>(entry->value)->kind(); if (!((property->kind() == GETTER && previous_kind == SETTER) || @@ -539,7 +405,7 @@ int ObjectLiteral::InitDepthAndFlags() { needs_initial_allocation_site |= literal->NeedsInitialAllocationSite(); } - const AstValue* key = property->key()->AsLiteral()->raw_value(); + Literal* key = property->key()->AsLiteral(); Expression* value = property->value(); bool is_compile_time_value = CompileTimeValue::IsCompileTimeValue(value); @@ -550,12 +416,11 @@ int ObjectLiteral::InitDepthAndFlags() { // much larger than the number of elements, creating an object // literal with fast elements will be a waste of space. uint32_t element_index = 0; - if (key->IsString() && key->AsString()->AsArrayIndex(&element_index)) { - max_element_index = Max(element_index, max_element_index); - elements++; - } else if (key->ToUint32(&element_index) && element_index != kMaxUInt32) { + if (key->AsArrayIndex(&element_index)) { max_element_index = Max(element_index, max_element_index); elements++; + } else { + DCHECK(key->IsPropertyName()); } nof_properties++; @@ -585,11 +450,9 @@ void ObjectLiteral::BuildConstantProperties(Isolate* isolate) { continue; } - Handle<Object> key = property->key()->AsLiteral()->value(); + Literal* key = property->key()->AsLiteral(); - uint32_t element_index = 0; - if (key->ToArrayIndex(&element_index) || - (key->IsString() && String::cast(*key)->AsArrayIndex(&element_index))) { + if (!key->IsPropertyName()) { index_keys++; } } @@ -611,22 +474,21 @@ void ObjectLiteral::BuildConstantProperties(Isolate* isolate) { DCHECK(!property->is_computed_name()); MaterializedLiteral* m_literal = property->value()->AsMaterializedLiteral(); - if (m_literal != NULL) { + if (m_literal != nullptr) { m_literal->BuildConstants(isolate); } // Add CONSTANT and COMPUTED properties to boilerplate. Use undefined // value for COMPUTED properties, the real value is filled in at // runtime. The enumeration order is maintained. - Handle<Object> key = property->key()->AsLiteral()->value(); - Handle<Object> value = GetBoilerplateValue(property->value(), isolate); - + Literal* key_literal = property->key()->AsLiteral(); uint32_t element_index = 0; - if (key->IsString() && String::cast(*key)->AsArrayIndex(&element_index)) { - key = isolate->factory()->NewNumberFromUint(element_index); - } else if (key->IsNumber() && !key->ToArrayIndex(&element_index)) { - key = isolate->factory()->NumberToString(key); - } + Handle<Object> key = + key_literal->AsArrayIndex(&element_index) + ? isolate->factory()->NewNumberFromUint(element_index) + : Handle<Object>::cast(key_literal->AsRawPropertyName()->string()); + + Handle<Object> value = GetBoilerplateValue(property->value(), isolate); // Add name, value pair to the fixed array. constant_properties->set(position++, *key); @@ -665,7 +527,7 @@ int ArrayLiteral::InitDepthAndFlags() { Expression* element = values()->at(array_index); DCHECK(!element->IsSpread()); MaterializedLiteral* literal = element->AsMaterializedLiteral(); - if (literal != NULL) { + if (literal != nullptr) { int subliteral_depth = literal->InitDepthAndFlags() + 1; if (subliteral_depth > depth_acc) depth_acc = subliteral_depth; } @@ -700,7 +562,7 @@ void ArrayLiteral::BuildConstantElements(Isolate* isolate) { Expression* element = values()->at(array_index); DCHECK(!element->IsSpread()); MaterializedLiteral* m_literal = element->AsMaterializedLiteral(); - if (m_literal != NULL) { + if (m_literal != nullptr) { m_literal->BuildConstants(isolate); } @@ -757,26 +619,6 @@ void ArrayLiteral::RewindSpreads() { first_spread_index_ = -1; } -void ArrayLiteral::AssignFeedbackSlots(FeedbackVectorSpec* spec, - LanguageMode language_mode, - FunctionKind kind, - FeedbackSlotCache* cache) { - MaterializedLiteral::AssignFeedbackSlots(spec, language_mode, kind, cache); - - // This logic that computes the number of slots needed for vector store - // ics must mirror FullCodeGenerator::VisitArrayLiteral. - for (int array_index = 0; array_index < values()->length(); array_index++) { - Expression* subexpr = values()->at(array_index); - DCHECK(!subexpr->IsSpread()); - if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue; - - // We'll reuse the same literal slot for all of the non-constant - // subexpressions that use a keyed store IC. - literal_slot_ = spec->AddKeyedStoreICSlot(language_mode); - return; - } -} - bool MaterializedLiteral::IsSimple() const { if (IsArrayLiteral()) return AsArrayLiteral()->is_simple(); if (IsObjectLiteral()) return AsObjectLiteral()->is_simple(); @@ -787,7 +629,7 @@ bool MaterializedLiteral::IsSimple() const { Handle<Object> MaterializedLiteral::GetBoilerplateValue(Expression* expression, Isolate* isolate) { if (expression->IsLiteral()) { - return expression->AsLiteral()->value(); + return expression->AsLiteral()->BuildValue(isolate); } if (CompileTimeValue::IsCompileTimeValue(expression)) { return CompileTimeValue::GetValue(isolate, expression); @@ -829,60 +671,29 @@ Handle<TemplateObjectDescription> GetTemplateObject::GetOrBuildDescription( isolate->factory()->NewFixedArray(this->raw_strings()->length(), TENURED); bool raw_and_cooked_match = true; for (int i = 0; i < raw_strings->length(); ++i) { - if (*this->raw_strings()->at(i)->value() != - *this->cooked_strings()->at(i)->value()) { + if (this->cooked_strings()->at(i) == nullptr || + *this->raw_strings()->at(i)->string() != + *this->cooked_strings()->at(i)->string()) { raw_and_cooked_match = false; } - raw_strings->set(i, *this->raw_strings()->at(i)->value()); + raw_strings->set(i, *this->raw_strings()->at(i)->string()); } Handle<FixedArray> cooked_strings = raw_strings; if (!raw_and_cooked_match) { cooked_strings = isolate->factory()->NewFixedArray( this->cooked_strings()->length(), TENURED); for (int i = 0; i < cooked_strings->length(); ++i) { - cooked_strings->set(i, *this->cooked_strings()->at(i)->value()); + if (this->cooked_strings()->at(i) != nullptr) { + cooked_strings->set(i, *this->cooked_strings()->at(i)->string()); + } else { + cooked_strings->set(i, isolate->heap()->undefined_value()); + } } } return isolate->factory()->NewTemplateObjectDescription( this->hash(), raw_strings, cooked_strings); } -void UnaryOperation::AssignFeedbackSlots(FeedbackVectorSpec* spec, - LanguageMode language_mode, - FunctionKind kind, - FeedbackSlotCache* cache) { - switch (op()) { - // Only unary plus, minus, and bitwise-not currently collect feedback. - case Token::ADD: - case Token::SUB: - case Token::BIT_NOT: - // Note that the slot kind remains "BinaryOp", as the operation - // is transformed into a binary operation in the BytecodeGenerator. - feedback_slot_ = spec->AddInterpreterBinaryOpICSlot(); - return; - default: - return; - } -} - -void BinaryOperation::AssignFeedbackSlots(FeedbackVectorSpec* spec, - LanguageMode language_mode, - FunctionKind kind, - FeedbackSlotCache* cache) { - // Feedback vector slot is only used by interpreter for binary operations. - // Full-codegen uses AstId to record type feedback. - switch (op()) { - // Comma, logical_or and logical_and do not collect type feedback. - case Token::COMMA: - case Token::AND: - case Token::OR: - return; - default: - feedback_slot_ = spec->AddInterpreterBinaryOpICSlot(); - return; - } -} - static bool IsCommutativeOperationWithSmiLiteral(Token::Value op) { // Add is not commutative due to potential for string addition. return op == Token::MUL || op == Token::BIT_AND || op == Token::BIT_OR || @@ -909,23 +720,7 @@ bool BinaryOperation::IsSmiLiteralOperation(Expression** subexpr, static bool IsTypeof(Expression* expr) { UnaryOperation* maybe_unary = expr->AsUnaryOperation(); - return maybe_unary != NULL && maybe_unary->op() == Token::TYPEOF; -} - -void CompareOperation::AssignFeedbackSlots(FeedbackVectorSpec* spec, - LanguageMode language_mode, - FunctionKind kind, - FeedbackSlotCache* cache_) { - // Feedback vector slot is only used by interpreter for binary operations. - // Full-codegen uses AstId to record type feedback. - switch (op()) { - // instanceof and in do not collect type feedback. - case Token::INSTANCEOF: - case Token::IN: - return; - default: - feedback_slot_ = spec->AddInterpreterCompareICSlot(); - } + return maybe_unary != nullptr && maybe_unary->op() == Token::TYPEOF; } // Check for the pattern: typeof <expression> equals <string literal>. @@ -949,9 +744,8 @@ bool CompareOperation::IsLiteralCompareTypeof(Expression** expr, static bool IsVoidOfLiteral(Expression* expr) { UnaryOperation* maybe_unary = expr->AsUnaryOperation(); - return maybe_unary != NULL && - maybe_unary->op() == Token::VOID && - maybe_unary->expression()->IsLiteral(); + return maybe_unary != nullptr && maybe_unary->op() == Token::VOID && + maybe_unary->expression()->IsLiteral(); } @@ -977,7 +771,6 @@ bool CompareOperation::IsLiteralCompareUndefined(Expression** expr) { MatchLiteralCompareUndefined(right_, op(), left_, expr); } - // Check for the pattern: null equals <expression> static bool MatchLiteralCompareNull(Expression* left, Token::Value op, @@ -990,25 +783,14 @@ static bool MatchLiteralCompareNull(Expression* left, return false; } - bool CompareOperation::IsLiteralCompareNull(Expression** expr) { return MatchLiteralCompareNull(left_, op(), right_, expr) || MatchLiteralCompareNull(right_, op(), left_, expr); } - -// ---------------------------------------------------------------------------- -// Recording of type feedback - -void Call::AssignFeedbackSlots(FeedbackVectorSpec* spec, - LanguageMode language_mode, FunctionKind kind, - FeedbackSlotCache* cache) { - ic_slot_ = spec->AddCallICSlot(); -} - Call::CallType Call::GetCallType() const { VariableProxy* proxy = expression()->AsVariableProxy(); - if (proxy != NULL) { + if (proxy != nullptr) { if (proxy->var()->IsUnallocated()) { return GLOBAL_CALL; } else if (proxy->var()->IsLookupSlot()) { @@ -1036,28 +818,113 @@ Call::CallType Call::GetCallType() const { CaseClause::CaseClause(Expression* label, ZoneList<Statement*>* statements) : label_(label), statements_(statements) {} -void CaseClause::AssignFeedbackSlots(FeedbackVectorSpec* spec, - LanguageMode language_mode, - FunctionKind kind, - FeedbackSlotCache* cache) { - feedback_slot_ = spec->AddInterpreterCompareICSlot(); +bool Literal::IsPropertyName() const { + if (type() != kString) return false; + uint32_t index; + return !string_->AsArrayIndex(&index); +} + +bool Literal::ToUint32(uint32_t* value) const { + switch (type()) { + case kString: + return string_->AsArrayIndex(value); + case kSmi: + if (smi_ < 0) return false; + *value = static_cast<uint32_t>(smi_); + return true; + case kHeapNumber: + return DoubleToUint32IfEqualToSelf(AsNumber(), value); + default: + return false; + } +} + +bool Literal::AsArrayIndex(uint32_t* value) const { + return ToUint32(value) && *value != kMaxUInt32; +} + +Handle<Object> Literal::BuildValue(Isolate* isolate) const { + switch (type()) { + case kSmi: + return handle(Smi::FromInt(smi_), isolate); + case kHeapNumber: + return isolate->factory()->NewNumber(number_, TENURED); + case kString: + return string_->string(); + case kSymbol: + return isolate->factory()->home_object_symbol(); + case kBoolean: + return isolate->factory()->ToBoolean(boolean_); + case kNull: + return isolate->factory()->null_value(); + case kUndefined: + return isolate->factory()->undefined_value(); + case kTheHole: + return isolate->factory()->the_hole_value(); + case kBigInt: + // This should never fail: the parser will never create a BigInt + // literal that cannot be allocated. + return BigIntLiteral(isolate, bigint_.c_str()).ToHandleChecked(); + } + UNREACHABLE(); +} + +bool Literal::ToBooleanIsTrue() const { + switch (type()) { + case kSmi: + return smi_ != 0; + case kHeapNumber: + return DoubleToBoolean(number_); + case kString: + return !string_->IsEmpty(); + case kNull: + case kUndefined: + return false; + case kBoolean: + return boolean_; + case kBigInt: { + const char* bigint_str = bigint_.c_str(); + size_t length = strlen(bigint_str); + DCHECK_GT(length, 0); + if (length == 1 && bigint_str[0] == '0') return false; + // Skip over any radix prefix; BigInts with length > 1 only + // begin with zero if they include a radix. + for (size_t i = (bigint_str[0] == '0') ? 2 : 0; i < length; ++i) { + if (bigint_str[i] != '0') return true; + } + return false; + } + case kSymbol: + return true; + case kTheHole: + UNREACHABLE(); + } + UNREACHABLE(); } uint32_t Literal::Hash() { - return raw_value()->IsString() - ? raw_value()->AsString()->Hash() - : ComputeLongHash(double_to_uint64(raw_value()->AsNumber())); + return IsString() ? AsRawString()->Hash() + : ComputeLongHash(double_to_uint64(AsNumber())); } // static -bool Literal::Match(void* literal1, void* literal2) { - const AstValue* x = static_cast<Literal*>(literal1)->raw_value(); - const AstValue* y = static_cast<Literal*>(literal2)->raw_value(); - return (x->IsString() && y->IsString() && x->AsString() == y->AsString()) || +bool Literal::Match(void* a, void* b) { + Literal* x = static_cast<Literal*>(a); + Literal* y = static_cast<Literal*>(b); + return (x->IsString() && y->IsString() && + x->AsRawString() == y->AsRawString()) || (x->IsNumber() && y->IsNumber() && x->AsNumber() == y->AsNumber()); } +Literal* AstNodeFactory::NewNumberLiteral(double number, int pos) { + int int_value; + if (DoubleToSmiInteger(number, &int_value)) { + return NewSmiLiteral(int_value, pos); + } + return new (zone_) Literal(number, pos); +} + const char* CallRuntime::debug_name() { #ifdef DEBUG return is_jsruntime() ? NameForNativeContextIntrinsicIndex(context_index_) diff --git a/deps/v8/src/ast/ast.h b/deps/v8/src/ast/ast.h index 0253e6651e..1ca192a462 100644 --- a/deps/v8/src/ast/ast.h +++ b/deps/v8/src/ast/ast.h @@ -5,6 +5,8 @@ #ifndef V8_AST_AST_H_ #define V8_AST_AST_H_ +#include <memory> + #include "src/ast/ast-value-factory.h" #include "src/ast/modules.h" #include "src/ast/variables.h" @@ -61,7 +63,8 @@ namespace internal { V(WithStatement) \ V(TryCatchStatement) \ V(TryFinallyStatement) \ - V(DebuggerStatement) + V(DebuggerStatement) \ + V(InitializeClassFieldsStatement) #define LITERAL_NODE_LIST(V) \ V(RegExpLiteral) \ @@ -73,6 +76,7 @@ namespace internal { V(Assignment) \ V(Await) \ V(BinaryOperation) \ + V(NaryOperation) \ V(Call) \ V(CallNew) \ V(CallRuntime) \ @@ -107,6 +111,7 @@ namespace internal { EXPRESSION_NODE_LIST(V) // Forward declarations +class AstNode; class AstNodeFactory; class Declaration; class BreakableStatement; @@ -121,44 +126,6 @@ class Statement; AST_NODE_LIST(DEF_FORWARD_DECLARATION) #undef DEF_FORWARD_DECLARATION -class FeedbackSlotCache { - public: - typedef std::pair<TypeofMode, Variable*> Key; - - explicit FeedbackSlotCache(Zone* zone) : map_(zone) {} - - void Put(TypeofMode typeof_mode, Variable* variable, FeedbackSlot slot) { - Key key = std::make_pair(typeof_mode, variable); - auto entry = std::make_pair(key, slot); - map_.insert(entry); - } - - FeedbackSlot Get(TypeofMode typeof_mode, Variable* variable) const { - Key key = std::make_pair(typeof_mode, variable); - auto iter = map_.find(key); - if (iter != map_.end()) { - return iter->second; - } - return FeedbackSlot(); - } - - private: - ZoneMap<Key, FeedbackSlot> map_; -}; - - -class AstProperties final BASE_EMBEDDED { - public: - explicit AstProperties(Zone* zone) : spec_(zone) {} - - const FeedbackVectorSpec* get_spec() const { return &spec_; } - FeedbackVectorSpec* get_spec() { return &spec_; } - - private: - FeedbackVectorSpec spec_; -}; - - class AstNode: public ZoneObject { public: #define DECLARE_TYPE_ENUM(type) k##type, @@ -206,7 +173,7 @@ class AstNode: public ZoneObject { class Statement : public AstNode { public: - bool IsEmpty() { return AsEmptyStatement() != NULL; } + bool IsEmpty() { return AsEmptyStatement() != nullptr; } bool IsJump() const; protected: @@ -264,6 +231,9 @@ class Expression : public AstNode { // True iff the expression is the null literal. bool IsNullLiteral() const; + // True iff the expression is the hole literal. + bool IsTheHoleLiteral() const; + // True if we can prove that the expression is the undefined literal. Note // that this also checks for loads of the global "undefined" variable. bool IsUndefinedLiteral() const; @@ -312,8 +282,8 @@ class Block : public BreakableStatement { inline ZoneList<const AstRawString*>* labels() const; bool IsJump() const { - return !statements_.is_empty() && statements_.last()->IsJump() - && labels() == NULL; // Good enough as an approximation... + return !statements_.is_empty() && statements_.last()->IsJump() && + labels() == nullptr; // Good enough as an approximation... } Scope* scope() const { return scope_; } @@ -335,7 +305,7 @@ class Block : public BreakableStatement { bool ignore_completion_value) : BreakableStatement(TARGET_FOR_NAMED_ONLY, kNoSourcePosition, kBlock), statements_(capacity, zone), - scope_(NULL) { + scope_(nullptr) { bit_field_ |= IgnoreCompletionField::encode(ignore_completion_value) | IsLabeledField::encode(labels != nullptr); } @@ -367,9 +337,7 @@ inline ZoneList<const AstRawString*>* Block::labels() const { class DoExpression final : public Expression { public: Block* block() { return block_; } - void set_block(Block* b) { block_ = b; } VariableProxy* result() { return result_; } - void set_result(VariableProxy* v) { result_ = v; } private: friend class AstNodeFactory; @@ -448,14 +416,13 @@ inline NestedVariableDeclaration* VariableDeclaration::AsNested() { class FunctionDeclaration final : public Declaration { public: FunctionLiteral* fun() const { return fun_; } - void set_fun(FunctionLiteral* f) { fun_ = f; } private: friend class AstNodeFactory; FunctionDeclaration(VariableProxy* proxy, FunctionLiteral* fun, int pos) : Declaration(proxy, pos, kFunctionDeclaration), fun_(fun) { - DCHECK(fun != NULL); + DCHECK_NOT_NULL(fun); } FunctionLiteral* fun_; @@ -481,7 +448,7 @@ class IterationStatement : public BreakableStatement { NodeType type) : BreakableStatement(TARGET_FOR_ANONYMOUS, pos, type), labels_(labels), - body_(NULL), + body_(nullptr), suspend_count_(0), first_suspend_id_(0) {} void Initialize(Statement* body) { body_ = body; } @@ -505,13 +472,12 @@ class DoWhileStatement final : public IterationStatement { } Expression* cond() const { return cond_; } - void set_cond(Expression* e) { cond_ = e; } private: friend class AstNodeFactory; DoWhileStatement(ZoneList<const AstRawString*>* labels, int pos) - : IterationStatement(labels, pos, kDoWhileStatement), cond_(NULL) {} + : IterationStatement(labels, pos, kDoWhileStatement), cond_(nullptr) {} Expression* cond_; }; @@ -525,13 +491,12 @@ class WhileStatement final : public IterationStatement { } Expression* cond() const { return cond_; } - void set_cond(Expression* e) { cond_ = e; } private: friend class AstNodeFactory; WhileStatement(ZoneList<const AstRawString*>* labels, int pos) - : IterationStatement(labels, pos, kWhileStatement), cond_(NULL) {} + : IterationStatement(labels, pos, kWhileStatement), cond_(nullptr) {} Expression* cond_; }; @@ -551,18 +516,14 @@ class ForStatement final : public IterationStatement { Expression* cond() const { return cond_; } Statement* next() const { return next_; } - void set_init(Statement* s) { init_ = s; } - void set_cond(Expression* e) { cond_ = e; } - void set_next(Statement* s) { next_ = s; } - private: friend class AstNodeFactory; ForStatement(ZoneList<const AstRawString*>* labels, int pos) : IterationStatement(labels, pos, kForStatement), - init_(NULL), - cond_(NULL), - next_(NULL) {} + init_(nullptr), + cond_(nullptr), + next_(nullptr) {} Statement* init_; Expression* cond_; @@ -605,23 +566,8 @@ class ForInStatement final : public ForEachStatement { Expression* each() const { return each_; } Expression* subject() const { return subject_; } - void set_each(Expression* e) { each_ = e; } - void set_subject(Expression* e) { subject_ = e; } - - // Type feedback information. - void AssignFeedbackSlots(FeedbackVectorSpec* spec, LanguageMode language_mode, - FunctionKind kind, FeedbackSlotCache* cache); - FeedbackSlot EachFeedbackSlot() const { return each_slot_; } - FeedbackSlot ForInFeedbackSlot() { - DCHECK(!for_in_feedback_slot_.IsInvalid()); - return for_in_feedback_slot_; - } - enum ForInType { FAST_FOR_IN, SLOW_FOR_IN }; ForInType for_in_type() const { return ForInTypeField::decode(bit_field_); } - void set_for_in_type(ForInType type) { - bit_field_ = ForInTypeField::update(bit_field_, type); - } private: friend class AstNodeFactory; @@ -635,8 +581,6 @@ class ForInStatement final : public ForEachStatement { Expression* each_; Expression* subject_; - FeedbackSlot each_slot_; - FeedbackSlot for_in_feedback_slot_; class ForInTypeField : public BitField<ForInType, ForEachStatement::kNextBitFieldIndex, 1> {}; @@ -680,21 +624,16 @@ class ForOfStatement final : public ForEachStatement { return assign_each_; } - void set_assign_iterator(Expression* e) { assign_iterator_ = e; } - void set_next_result(Expression* e) { next_result_ = e; } - void set_result_done(Expression* e) { result_done_ = e; } - void set_assign_each(Expression* e) { assign_each_ = e; } - private: friend class AstNodeFactory; ForOfStatement(ZoneList<const AstRawString*>* labels, int pos) : ForEachStatement(labels, pos, kForOfStatement), - iterator_(NULL), - assign_iterator_(NULL), - next_result_(NULL), - result_done_(NULL), - assign_each_(NULL) {} + iterator_(nullptr), + assign_iterator_(nullptr), + next_result_(nullptr), + result_done_(nullptr), + assign_each_(nullptr) {} Variable* iterator_; Expression* assign_iterator_; @@ -762,7 +701,6 @@ class ReturnStatement final : public JumpStatement { enum Type { kNormal, kAsyncReturn }; Expression* expression() const { return expression_; } - void set_expression(Expression* e) { expression_ = e; } Type type() const { return TypeField::decode(bit_field_); } bool is_async_return() const { return type() == kAsyncReturn; } @@ -790,7 +728,6 @@ class WithStatement final : public Statement { public: Scope* scope() { return scope_; } Expression* expression() const { return expression_; } - void set_expression(Expression* e) { expression_ = e; } Statement* statement() const { return statement_; } void set_statement(Statement* s) { statement_ = s; } @@ -811,25 +748,18 @@ class WithStatement final : public Statement { class CaseClause final : public ZoneObject { public: - bool is_default() const { return label_ == NULL; } + bool is_default() const { return label_ == nullptr; } Expression* label() const { DCHECK(!is_default()); return label_; } - void set_label(Expression* e) { label_ = e; } ZoneList<Statement*>* statements() const { return statements_; } - void AssignFeedbackSlots(FeedbackVectorSpec* spec, LanguageMode language_mode, - FunctionKind kind, FeedbackSlotCache* cache); - - FeedbackSlot CompareOperationFeedbackSlot() { return feedback_slot_; } - private: friend class AstNodeFactory; CaseClause(Expression* label, ZoneList<Statement*>* statements); - FeedbackSlot feedback_slot_; Expression* label_; ZoneList<Statement*>* statements_; }; @@ -874,7 +804,6 @@ class IfStatement final : public Statement { Statement* then_statement() const { return then_statement_; } Statement* else_statement() const { return else_statement_; } - void set_condition(Expression* e) { condition_ = e; } void set_then_statement(Statement* s) { then_statement_ = s; } void set_else_statement(Statement* s) { else_statement_ = s; } @@ -1036,25 +965,79 @@ class SloppyBlockFunctionStatement final : public Statement { class Literal final : public Expression { public: + enum Type { + kSmi, + kHeapNumber, + kBigInt, + kString, + kSymbol, + kBoolean, + kUndefined, + kNull, + kTheHole, + }; + + Type type() const { return TypeField::decode(bit_field_); } + // Returns true if literal represents a property name (i.e. cannot be parsed // as array indices). - bool IsPropertyName() const { return value_->IsPropertyName(); } + bool IsPropertyName() const; + + // Returns true if literal represents an array index. + // Note, that in general the following statement is not true: + // key->IsPropertyName() != key->AsArrayIndex(...) + // but for non-computed LiteralProperty properties the following is true: + // property->key()->IsPropertyName() != property->key()->AsArrayIndex(...) + bool AsArrayIndex(uint32_t* index) const; const AstRawString* AsRawPropertyName() { DCHECK(IsPropertyName()); - return value_->AsString(); + return string_; + } + + Smi* AsSmiLiteral() const { + DCHECK_EQ(kSmi, type()); + return Smi::FromInt(smi_); + } + + // Returns true if literal represents a Number. + bool IsNumber() const { return type() == kHeapNumber || type() == kSmi; } + double AsNumber() const { + DCHECK(IsNumber()); + switch (type()) { + case kSmi: + return smi_; + case kHeapNumber: + return number_; + default: + UNREACHABLE(); + } } - Smi* AsSmiLiteral() { - DCHECK(IsSmiLiteral()); - return raw_value()->AsSmi(); + AstBigInt AsBigInt() const { + DCHECK_EQ(type(), kBigInt); + return bigint_; } - bool ToBooleanIsTrue() const { return raw_value()->BooleanValue(); } - bool ToBooleanIsFalse() const { return !raw_value()->BooleanValue(); } + bool IsString() const { return type() == kString; } + const AstRawString* AsRawString() { + DCHECK_EQ(type(), kString); + return string_; + } + + AstSymbol AsSymbol() { + DCHECK_EQ(type(), kSymbol); + return symbol_; + } + + V8_EXPORT_PRIVATE bool ToBooleanIsTrue() const; + bool ToBooleanIsFalse() const { return !ToBooleanIsTrue(); } - Handle<Object> value() const { return value_->value(); } - const AstValue* raw_value() const { return value_; } + bool ToUint32(uint32_t* value) const; + + // Returns an appropriate Object representing this Literal, allocating + // a heap object if needed. + Handle<Object> BuildValue(Isolate* isolate) const; // Support for using Literal as a HashMap key. NOTE: Currently, this works // only for string and number literals! @@ -1064,29 +1047,59 @@ class Literal final : public Expression { private: friend class AstNodeFactory; - Literal(const AstValue* value, int position) - : Expression(position, kLiteral), value_(value) {} + class TypeField : public BitField<Type, Expression::kNextBitFieldIndex, 4> {}; + + Literal(int smi, int position) : Expression(position, kLiteral), smi_(smi) { + bit_field_ = TypeField::update(bit_field_, kSmi); + } + + Literal(double number, int position) + : Expression(position, kLiteral), number_(number) { + bit_field_ = TypeField::update(bit_field_, kHeapNumber); + } + + Literal(AstBigInt bigint, int position) + : Expression(position, kLiteral), bigint_(bigint) { + bit_field_ = TypeField::update(bit_field_, kBigInt); + } + + Literal(const AstRawString* string, int position) + : Expression(position, kLiteral), string_(string) { + bit_field_ = TypeField::update(bit_field_, kString); + } + + Literal(AstSymbol symbol, int position) + : Expression(position, kLiteral), symbol_(symbol) { + bit_field_ = TypeField::update(bit_field_, kSymbol); + } + + Literal(bool boolean, int position) + : Expression(position, kLiteral), boolean_(boolean) { + bit_field_ = TypeField::update(bit_field_, kBoolean); + } - const AstValue* value_; + Literal(Type type, int position) : Expression(position, kLiteral) { + DCHECK(type == kNull || type == kUndefined || type == kTheHole); + bit_field_ = TypeField::update(bit_field_, type); + } + + union { + const AstRawString* string_; + int smi_; + double number_; + AstSymbol symbol_; + AstBigInt bigint_; + bool boolean_; + }; }; // Base class for literals that need space in the type feedback vector. class MaterializedLiteral : public Expression { public: - void AssignFeedbackSlots(FeedbackVectorSpec* spec, LanguageMode language_mode, - FunctionKind kind, FeedbackSlotCache* cache) { - literal_slot_ = spec->AddLiteralSlot(); - } - - FeedbackSlot literal_slot() const { return literal_slot_; } - // A Materializedliteral is simple if the values consist of only // constants and simple object and array literals. bool IsSimple() const; - private: - FeedbackSlot literal_slot_; - protected: MaterializedLiteral(int pos, NodeType type) : Expression(pos, type) {} @@ -1199,25 +1212,8 @@ class LiteralProperty : public ZoneObject { public: Expression* key() const { return key_; } Expression* value() const { return value_; } - void set_key(Expression* e) { key_ = e; } - void set_value(Expression* e) { value_ = e; } bool is_computed_name() const { return is_computed_name_; } - - FeedbackSlot GetSlot(int offset = 0) const { - DCHECK_LT(offset, static_cast<int>(arraysize(slots_))); - return slots_[offset]; - } - - FeedbackSlot GetStoreDataPropertySlot() const; - - void SetSlot(FeedbackSlot slot, int offset = 0) { - DCHECK_LT(offset, static_cast<int>(arraysize(slots_))); - slots_[offset] = slot; - } - - void SetStoreDataPropertySlot(FeedbackSlot slot); - bool NeedsSetFunctionName() const; protected: @@ -1226,7 +1222,6 @@ class LiteralProperty : public ZoneObject { Expression* key_; Expression* value_; - FeedbackSlot slots_[2]; bool is_computed_name_; }; @@ -1348,16 +1343,11 @@ class ObjectLiteral final : public AggregateLiteral { static_cast<int>(kFastElements)); struct Accessors: public ZoneObject { - Accessors() : getter(NULL), setter(NULL) {} + Accessors() : getter(nullptr), setter(nullptr) {} ObjectLiteralProperty* getter; ObjectLiteralProperty* setter; }; - // Object literals need one feedback slot for each non-trivial value, as well - // as some slots for home objects. - void AssignFeedbackSlots(FeedbackVectorSpec* spec, LanguageMode language_mode, - FunctionKind kind, FeedbackSlotCache* cache); - private: friend class AstNodeFactory; @@ -1414,7 +1404,9 @@ class AccessorTable Iterator lookup(Literal* literal) { Iterator it = find(literal, true, ZoneAllocationPolicy(zone_)); - if (it->second == NULL) it->second = new (zone_) ObjectLiteral::Accessors(); + if (it->second == nullptr) { + it->second = new (zone_) ObjectLiteral::Accessors(); + } return it; } @@ -1467,10 +1459,6 @@ class ArrayLiteral final : public AggregateLiteral { // Rewind an array literal omitting everything from the first spread on. void RewindSpreads(); - void AssignFeedbackSlots(FeedbackVectorSpec* spec, LanguageMode language_mode, - FunctionKind kind, FeedbackSlotCache* cache); - FeedbackSlot LiteralFeedbackSlot() const { return literal_slot_; } - private: friend class AstNodeFactory; @@ -1480,7 +1468,6 @@ class ArrayLiteral final : public AggregateLiteral { values_(values) {} int first_spread_index_; - FeedbackSlot literal_slot_; Handle<ConstantElementsPair> constant_elements_; ZoneList<Expression*>* values_; }; @@ -1542,15 +1529,6 @@ class VariableProxy final : public Expression { // Bind this proxy to the variable var. void BindTo(Variable* var); - bool UsesVariableFeedbackSlot() const { - return var()->IsUnallocated() || var()->IsLookupSlot(); - } - - void AssignFeedbackSlots(FeedbackVectorSpec* spec, TypeofMode typeof_mode, - FeedbackSlotCache* cache); - - FeedbackSlot VariableFeedbackSlot() { return variable_feedback_slot_; } - void set_next_unresolved(VariableProxy* next) { next_unresolved_ = next; } VariableProxy* next_unresolved() { return next_unresolved_; } @@ -1580,7 +1558,6 @@ class VariableProxy final : public Expression { class HoleCheckModeField : public BitField<HoleCheckMode, IsNewTargetField::kNext, 1> {}; - FeedbackSlot variable_feedback_slot_; union { const AstRawString* raw_name_; // if !is_resolved_ Variable* var_; // if is_resolved_ @@ -1607,25 +1584,11 @@ class Property final : public Expression { Expression* obj() const { return obj_; } Expression* key() const { return key_; } - void set_obj(Expression* e) { obj_ = e; } - void set_key(Expression* e) { key_ = e; } - bool IsSuperAccess() { return obj()->IsSuperPropertyReference(); } - void AssignFeedbackSlots(FeedbackVectorSpec* spec, LanguageMode language_mode, - FunctionKind kind, FeedbackSlotCache* cache) { - if (key()->IsPropertyName()) { - property_feedback_slot_ = spec->AddLoadICSlot(); - } else { - property_feedback_slot_ = spec->AddKeyedLoadICSlot(); - } - } - - FeedbackSlot PropertyFeedbackSlot() const { return property_feedback_slot_; } - // Returns the properties assign type. static LhsKind GetAssignType(Property* property) { - if (property == NULL) return VARIABLE; + if (property == nullptr) return VARIABLE; bool super_access = property->IsSuperAccess(); return (property->key()->IsPropertyName()) ? (super_access ? NAMED_SUPER_PROPERTY : NAMED_PROPERTY) @@ -1639,7 +1602,6 @@ class Property final : public Expression { : Expression(pos, kProperty), obj_(obj), key_(key) { } - FeedbackSlot property_feedback_slot_; Expression* obj_; Expression* key_; }; @@ -1650,18 +1612,14 @@ class Call final : public Expression { Expression* expression() const { return expression_; } ZoneList<Expression*>* arguments() const { return arguments_; } - void set_expression(Expression* e) { expression_ = e; } - - // Type feedback information. - void AssignFeedbackSlots(FeedbackVectorSpec* spec, LanguageMode language_mode, - FunctionKind kind, FeedbackSlotCache* cache); - - FeedbackSlot CallFeedbackICSlot() const { return ic_slot_; } - bool is_possibly_eval() const { return IsPossiblyEvalField::decode(bit_field_); } + bool is_tagged_template() const { + return IsTaggedTemplateField::decode(bit_field_); + } + bool only_last_arg_is_spread() { return !arguments_->is_empty() && arguments_->last()->IsSpread(); } @@ -1685,6 +1643,8 @@ class Call final : public Expression { // Helpers to determine how to handle the call. CallType GetCallType() const; + enum class TaggedTemplateTag { kTrue }; + private: friend class AstNodeFactory; @@ -1694,13 +1654,22 @@ class Call final : public Expression { expression_(expression), arguments_(arguments) { bit_field_ |= - IsPossiblyEvalField::encode(possibly_eval == IS_POSSIBLY_EVAL); + IsPossiblyEvalField::encode(possibly_eval == IS_POSSIBLY_EVAL) | + IsTaggedTemplateField::encode(false); + } + + Call(Expression* expression, ZoneList<Expression*>* arguments, int pos, + TaggedTemplateTag tag) + : Expression(pos, kCall), expression_(expression), arguments_(arguments) { + bit_field_ |= IsPossiblyEvalField::encode(false) | + IsTaggedTemplateField::encode(true); } class IsPossiblyEvalField : public BitField<bool, Expression::kNextBitFieldIndex, 1> {}; + class IsTaggedTemplateField + : public BitField<bool, IsPossiblyEvalField::kNext, 1> {}; - FeedbackSlot ic_slot_; Expression* expression_; ZoneList<Expression*>* arguments_; }; @@ -1711,21 +1680,6 @@ class CallNew final : public Expression { Expression* expression() const { return expression_; } ZoneList<Expression*>* arguments() const { return arguments_; } - void set_expression(Expression* e) { expression_ = e; } - - // Type feedback information. - void AssignFeedbackSlots(FeedbackVectorSpec* spec, LanguageMode language_mode, - FunctionKind kind, FeedbackSlotCache* cache) { - // CallNew stores feedback in the exact same way as Call. We can - // piggyback on the type feedback infrastructure for calls. - callnew_feedback_slot_ = spec->AddCallICSlot(); - } - - FeedbackSlot CallNewFeedbackSlot() { - DCHECK(!callnew_feedback_slot_.IsInvalid()); - return callnew_feedback_slot_; - } - bool only_last_arg_is_spread() { return !arguments_->is_empty() && arguments_->last()->IsSpread(); } @@ -1739,7 +1693,6 @@ class CallNew final : public Expression { arguments_(arguments) { } - FeedbackSlot callnew_feedback_slot_; Expression* expression_; ZoneList<Expression*>* arguments_; }; @@ -1752,16 +1705,12 @@ class CallNew final : public Expression { class CallRuntime final : public Expression { public: ZoneList<Expression*>* arguments() const { return arguments_; } - bool is_jsruntime() const { return function_ == NULL; } + bool is_jsruntime() const { return function_ == nullptr; } int context_index() const { DCHECK(is_jsruntime()); return context_index_; } - void set_context_index(int index) { - DCHECK(is_jsruntime()); - context_index_ = index; - } const Runtime::Function* function() const { DCHECK(!is_jsruntime()); return function_; @@ -1780,7 +1729,7 @@ class CallRuntime final : public Expression { CallRuntime(int context_index, ZoneList<Expression*>* arguments, int pos) : Expression(pos, kCallRuntime), context_index_(context_index), - function_(NULL), + function_(nullptr), arguments_(arguments) {} int context_index_; @@ -1793,12 +1742,6 @@ class UnaryOperation final : public Expression { public: Token::Value op() const { return OperatorField::decode(bit_field_); } Expression* expression() const { return expression_; } - void set_expression(Expression* e) { expression_ = e; } - - void AssignFeedbackSlots(FeedbackVectorSpec* spec, LanguageMode language_mode, - FunctionKind kind, FeedbackSlotCache* cache); - - FeedbackSlot UnaryOperationFeedbackSlot() const { return feedback_slot_; } private: friend class AstNodeFactory; @@ -1809,7 +1752,6 @@ class UnaryOperation final : public Expression { DCHECK(Token::IsUnaryOp(op)); } - FeedbackSlot feedback_slot_; Expression* expression_; class OperatorField @@ -1821,14 +1763,7 @@ class BinaryOperation final : public Expression { public: Token::Value op() const { return OperatorField::decode(bit_field_); } Expression* left() const { return left_; } - void set_left(Expression* e) { left_ = e; } Expression* right() const { return right_; } - void set_right(Expression* e) { right_ = e; } - - void AssignFeedbackSlots(FeedbackVectorSpec* spec, LanguageMode language_mode, - FunctionKind kind, FeedbackSlotCache* cache); - - FeedbackSlot BinaryOperationFeedbackSlot() const { return feedback_slot_; } // Returns true if one side is a Smi literal, returning the other side's // sub-expression in |subexpr| and the literal Smi in |literal|. @@ -1843,7 +1778,6 @@ class BinaryOperation final : public Expression { DCHECK(Token::IsBinaryOp(op)); } - FeedbackSlot feedback_slot_; Expression* left_; Expression* right_; @@ -1851,6 +1785,65 @@ class BinaryOperation final : public Expression { : public BitField<Token::Value, Expression::kNextBitFieldIndex, 7> {}; }; +class NaryOperation final : public Expression { + public: + Token::Value op() const { return OperatorField::decode(bit_field_); } + Expression* first() const { return first_; } + Expression* subsequent(size_t index) const { + return subsequent_[index].expression; + } + + size_t subsequent_length() const { return subsequent_.size(); } + int subsequent_op_position(size_t index) const { + return subsequent_[index].op_position; + } + + void AddSubsequent(Expression* expr, int pos) { + subsequent_.emplace_back(expr, pos); + } + + private: + friend class AstNodeFactory; + + NaryOperation(Zone* zone, Token::Value op, Expression* first, + size_t initial_subsequent_size) + : Expression(first->position(), kNaryOperation), + first_(first), + subsequent_(zone) { + bit_field_ |= OperatorField::encode(op); + DCHECK(Token::IsBinaryOp(op)); + DCHECK_NE(op, Token::EXP); + subsequent_.reserve(initial_subsequent_size); + } + + // Nary operations store the first (lhs) child expression inline, and the + // child expressions (rhs of each op) are stored out-of-line, along with + // their operation's position. Note that the Nary operation expression's + // position has no meaning. + // + // So an nary add: + // + // expr + expr + expr + ... + // + // is stored as: + // + // (expr) [(+ expr), (+ expr), ...] + // '-.--' '-----------.-----------' + // first subsequent entry list + + Expression* first_; + + struct NaryOperationEntry { + Expression* expression; + int op_position; + NaryOperationEntry(Expression* e, int pos) + : expression(e), op_position(pos) {} + }; + ZoneVector<NaryOperationEntry> subsequent_; + + class OperatorField + : public BitField<Token::Value, Expression::kNextBitFieldIndex, 7> {}; +}; class CountOperation final : public Expression { public: @@ -1860,16 +1853,6 @@ class CountOperation final : public Expression { Token::Value op() const { return TokenField::decode(bit_field_); } Expression* expression() const { return expression_; } - void set_expression(Expression* e) { expression_ = e; } - - // Feedback slot for binary operation is only used by ignition. - FeedbackSlot CountBinaryOpFeedbackSlot() const { - return binary_operation_slot_; - } - - void AssignFeedbackSlots(FeedbackVectorSpec* spec, LanguageMode language_mode, - FunctionKind kind, FeedbackSlotCache* cache); - FeedbackSlot CountSlot() const { return slot_; } private: friend class AstNodeFactory; @@ -1883,8 +1866,6 @@ class CountOperation final : public Expression { : public BitField<bool, Expression::kNextBitFieldIndex, 1> {}; class TokenField : public BitField<Token::Value, IsPrefixField::kNext, 7> {}; - FeedbackSlot slot_; - FeedbackSlot binary_operation_slot_; Expression* expression_; }; @@ -1895,14 +1876,6 @@ class CompareOperation final : public Expression { Expression* left() const { return left_; } Expression* right() const { return right_; } - void set_left(Expression* e) { left_ = e; } - void set_right(Expression* e) { right_ = e; } - - void AssignFeedbackSlots(FeedbackVectorSpec* spec, LanguageMode language_mode, - FunctionKind kind, FeedbackSlotCache* cache); - - FeedbackSlot CompareOperationFeedbackSlot() const { return feedback_slot_; } - // Match special cases. bool IsLiteralCompareTypeof(Expression** expr, Literal** literal); bool IsLiteralCompareUndefined(Expression** expr); @@ -1918,7 +1891,6 @@ class CompareOperation final : public Expression { DCHECK(Token::IsCompareOp(op)); } - FeedbackSlot feedback_slot_; Expression* left_; Expression* right_; @@ -1930,7 +1902,6 @@ class CompareOperation final : public Expression { class Spread final : public Expression { public: Expression* expression() const { return expression_; } - void set_expression(Expression* e) { expression_ = e; } int expression_position() const { return expr_pos_; } @@ -1953,10 +1924,6 @@ class Conditional final : public Expression { Expression* then_expression() const { return then_expression_; } Expression* else_expression() const { return else_expression_; } - void set_condition(Expression* e) { condition_ = e; } - void set_then_expression(Expression* e) { then_expression_ = e; } - void set_else_expression(Expression* e) { else_expression_ = e; } - private: friend class AstNodeFactory; @@ -1978,9 +1945,6 @@ class Assignment : public Expression { Expression* target() const { return target_; } Expression* value() const { return value_; } - void set_target(Expression* e) { target_ = e; } - void set_value(Expression* e) { value_ = e; } - // The assignment was generated as part of block-scoped sloppy-mode // function hoisting, see // ES#sec-block-level-function-declarations-web-legacy-compatibility-semantics @@ -1993,10 +1957,6 @@ class Assignment : public Expression { LookupHoistingModeField::update(bit_field_, static_cast<bool>(mode)); } - void AssignFeedbackSlots(FeedbackVectorSpec* spec, LanguageMode language_mode, - FunctionKind kind, FeedbackSlotCache* cache); - FeedbackSlot AssignmentSlot() const { return slot_; } - protected: Assignment(NodeType type, Token::Value op, Expression* target, Expression* value, int pos); @@ -2009,7 +1969,6 @@ class Assignment : public Expression { class LookupHoistingModeField : public BitField<bool, TokenField::kNext, 1> { }; - FeedbackSlot slot_; Expression* target_; Expression* value_; }; @@ -2060,17 +2019,22 @@ class RewritableExpression final : public Expression { set_rewritten(); } + Scope* scope() const { return scope_; } + void set_scope(Scope* scope) { scope_ = scope; } + private: friend class AstNodeFactory; - explicit RewritableExpression(Expression* expression) + RewritableExpression(Expression* expression, Scope* scope) : Expression(expression->position(), kRewritableExpression), - expr_(expression) { + expr_(expression), + scope_(scope) { bit_field_ |= IsRewrittenField::encode(false); DCHECK(!expression->IsRewritableExpression()); } Expression* expr_; + Scope* scope_; class IsRewrittenField : public BitField<bool, Expression::kNextBitFieldIndex, 1> {}; @@ -2100,8 +2064,6 @@ class Suspend : public Expression { } int suspend_id() const { return suspend_id_; } - - void set_expression(Expression* e) { expression_ = e; } void set_suspend_id(int id) { suspend_id_ = id; } inline bool IsInitialYield() const { return suspend_id_ == 0 && IsYield(); } @@ -2165,63 +2127,6 @@ class YieldStar final : public Suspend { return 1; } - void AssignFeedbackSlots(FeedbackVectorSpec* spec, LanguageMode language_mode, - FunctionKind kind, FeedbackSlotCache* cache) { - load_iterable_iterator_slot_ = spec->AddLoadICSlot(); - load_iterator_return_slot_ = spec->AddLoadICSlot(); - load_iterator_next_slot_ = spec->AddLoadICSlot(); - load_iterator_throw_slot_ = spec->AddLoadICSlot(); - load_output_done_slot_ = spec->AddLoadICSlot(); - load_output_value_slot_ = spec->AddLoadICSlot(); - call_iterable_iterator_slot_ = spec->AddCallICSlot(); - call_iterator_return_slot1_ = spec->AddCallICSlot(); - call_iterator_return_slot2_ = spec->AddCallICSlot(); - call_iterator_next_slot_ = spec->AddCallICSlot(); - call_iterator_throw_slot_ = spec->AddCallICSlot(); - if (IsAsyncGeneratorFunction(kind)) { - load_iterable_async_iterator_slot_ = spec->AddLoadICSlot(); - call_iterable_async_iterator_slot_ = spec->AddCallICSlot(); - } - } - - FeedbackSlot load_iterable_iterator_slot() const { - return load_iterable_iterator_slot_; - } - FeedbackSlot load_iterator_return_slot() const { - return load_iterator_return_slot_; - } - FeedbackSlot load_iterator_next_slot() const { - return load_iterator_next_slot_; - } - FeedbackSlot load_iterator_throw_slot() const { - return load_iterator_throw_slot_; - } - FeedbackSlot load_output_done_slot() const { return load_output_done_slot_; } - FeedbackSlot load_output_value_slot() const { - return load_output_value_slot_; - } - FeedbackSlot call_iterable_iterator_slot() const { - return call_iterable_iterator_slot_; - } - FeedbackSlot call_iterator_return_slot1() const { - return call_iterator_return_slot1_; - } - FeedbackSlot call_iterator_return_slot2() const { - return call_iterator_return_slot2_; - } - FeedbackSlot call_iterator_next_slot() const { - return call_iterator_next_slot_; - } - FeedbackSlot call_iterator_throw_slot() const { - return call_iterator_throw_slot_; - } - FeedbackSlot load_iterable_async_iterator_slot() const { - return load_iterable_async_iterator_slot_; - } - FeedbackSlot call_iterable_async_iterator_slot() const { - return call_iterable_async_iterator_slot_; - } - private: friend class AstNodeFactory; @@ -2231,21 +2136,6 @@ class YieldStar final : public Suspend { await_iterator_close_suspend_id_(-1), await_delegated_iterator_output_suspend_id_(-1) {} - FeedbackSlot load_iterable_iterator_slot_; - FeedbackSlot load_iterator_return_slot_; - FeedbackSlot load_iterator_next_slot_; - FeedbackSlot load_iterator_throw_slot_; - FeedbackSlot load_output_done_slot_; - FeedbackSlot load_output_value_slot_; - FeedbackSlot call_iterable_iterator_slot_; - FeedbackSlot call_iterator_return_slot1_; - FeedbackSlot call_iterator_return_slot2_; - FeedbackSlot call_iterator_next_slot_; - FeedbackSlot call_iterator_throw_slot_; - - FeedbackSlot load_iterable_async_iterator_slot_; - FeedbackSlot call_iterable_async_iterator_slot_; - int await_iterator_close_suspend_id_; int await_delegated_iterator_output_suspend_id_; }; @@ -2261,7 +2151,6 @@ class Await final : public Suspend { class Throw final : public Expression { public: Expression* exception() const { return exception_; } - void set_exception(Expression* e) { exception_ = e; } private: friend class AstNodeFactory; @@ -2312,13 +2201,6 @@ class FunctionLiteral final : public Expression { } LanguageMode language_mode() const; - void AssignFeedbackSlots(FeedbackVectorSpec* spec, LanguageMode language_mode, - FunctionKind kind, FeedbackSlotCache* cache) { - literal_feedback_slot_ = spec->AddCreateClosureSlot(); - } - - FeedbackSlot LiteralFeedbackSlot() const { return literal_feedback_slot_; } - static bool NeedsHomeObject(Expression* expr); int expected_property_count() { @@ -2339,19 +2221,15 @@ class FunctionLiteral final : public Expression { return false; } - Handle<String> debug_name() const { - if (raw_name_ != NULL && !raw_name_->IsEmpty()) { - return raw_name_->string(); - } - return inferred_name(); - } + // Returns either name or inferred name as a cstring. + std::unique_ptr<char[]> GetDebugName() const; Handle<String> inferred_name() const { if (!inferred_name_.is_null()) { - DCHECK(raw_inferred_name_ == NULL); + DCHECK_NULL(raw_inferred_name_); return inferred_name_; } - if (raw_inferred_name_ != NULL) { + if (raw_inferred_name_ != nullptr) { return raw_inferred_name_->string(); } UNREACHABLE(); @@ -2361,12 +2239,14 @@ class FunctionLiteral final : public Expression { void set_inferred_name(Handle<String> inferred_name) { DCHECK(!inferred_name.is_null()); inferred_name_ = inferred_name; - DCHECK(raw_inferred_name_== NULL || raw_inferred_name_->IsEmpty()); - raw_inferred_name_ = NULL; + DCHECK(raw_inferred_name_ == nullptr || raw_inferred_name_->IsEmpty()); + raw_inferred_name_ = nullptr; } + const AstConsString* raw_inferred_name() { return raw_inferred_name_; } + void set_raw_inferred_name(const AstConsString* raw_inferred_name) { - DCHECK(raw_inferred_name != NULL); + DCHECK_NOT_NULL(raw_inferred_name); raw_inferred_name_ = raw_inferred_name; DCHECK(inferred_name_.is_null()); inferred_name_ = Handle<String>(); @@ -2394,13 +2274,6 @@ class FunctionLiteral final : public Expression { } FunctionKind kind() const; - void set_ast_properties(AstProperties* ast_properties) { - ast_properties_ = *ast_properties; - } - const FeedbackVectorSpec* feedback_vector_spec() const { - return ast_properties_.get_spec(); - } - bool dont_optimize() { return dont_optimize_reason() != kNoReason; } BailoutReason dont_optimize_reason() { return DontOptimizeReasonField::decode(bit_field_); @@ -2425,6 +2298,13 @@ class FunctionLiteral final : public Expression { function_literal_id_ = function_literal_id; } + void set_requires_instance_fields_initializer(bool value) { + bit_field_ = RequiresInstanceFieldsInitializer::update(bit_field_, value); + } + bool requires_instance_fields_initializer() const { + return RequiresInstanceFieldsInitializer::decode(bit_field_); + } + ProducedPreParsedScopeData* produced_preparsed_scope_data() const { return produced_preparsed_scope_data_; } @@ -2451,14 +2331,14 @@ class FunctionLiteral final : public Expression { scope_(scope), body_(body), raw_inferred_name_(ast_value_factory->empty_cons_string()), - ast_properties_(zone), function_literal_id_(function_literal_id), produced_preparsed_scope_data_(produced_preparsed_scope_data) { bit_field_ |= FunctionTypeBits::encode(function_type) | Pretenure::encode(false) | HasDuplicateParameters::encode(has_duplicate_parameters == kHasDuplicateParameters) | - DontOptimizeReasonField::encode(kNoReason); + DontOptimizeReasonField::encode(kNoReason) | + RequiresInstanceFieldsInitializer::encode(false); if (eager_compile_hint == kShouldEagerCompile) SetShouldEagerCompile(); DCHECK_EQ(body == nullptr, expected_property_count < 0); } @@ -2469,6 +2349,8 @@ class FunctionLiteral final : public Expression { class HasDuplicateParameters : public BitField<bool, Pretenure::kNext, 1> {}; class DontOptimizeReasonField : public BitField<BailoutReason, HasDuplicateParameters::kNext, 8> {}; + class RequiresInstanceFieldsInitializer + : public BitField<bool, DontOptimizeReasonField::kNext, 1> {}; int expected_property_count_; int parameter_count_; @@ -2482,9 +2364,7 @@ class FunctionLiteral final : public Expression { ZoneList<Statement*>* body_; const AstConsString* raw_inferred_name_; Handle<String> inferred_name_; - AstProperties ast_properties_; int function_literal_id_; - FeedbackSlot literal_feedback_slot_; ProducedPreParsedScopeData* produced_preparsed_scope_data_; }; @@ -2498,6 +2378,9 @@ class ClassLiteralProperty final : public LiteralProperty { bool is_static() const { return is_static_; } + void set_computed_name_var(Variable* var) { computed_name_var_ = var; } + Variable* computed_name_var() const { return computed_name_var_; } + private: friend class AstNodeFactory; @@ -2506,6 +2389,21 @@ class ClassLiteralProperty final : public LiteralProperty { Kind kind_; bool is_static_; + Variable* computed_name_var_; +}; + +class InitializeClassFieldsStatement final : public Statement { + public: + typedef ClassLiteralProperty Property; + ZoneList<Property*>* fields() const { return fields_; } + + private: + friend class AstNodeFactory; + + InitializeClassFieldsStatement(ZoneList<Property*>* fields, int pos) + : Statement(pos, kInitializeClassFieldsStatement), fields_(fields) {} + + ZoneList<Property*>* fields_; }; class ClassLiteral final : public Expression { @@ -2515,9 +2413,7 @@ class ClassLiteral final : public Expression { Scope* scope() const { return scope_; } Variable* class_variable() const { return class_variable_; } Expression* extends() const { return extends_; } - void set_extends(Expression* e) { extends_ = e; } FunctionLiteral* constructor() const { return constructor_; } - void set_constructor(FunctionLiteral* f) { constructor_ = f; } ZoneList<Property*>* properties() const { return properties_; } int start_position() const { return position(); } int end_position() const { return end_position_; } @@ -2535,18 +2431,21 @@ class ClassLiteral final : public Expression { return is_anonymous_expression(); } - // Object literals need one feedback slot for each non-trivial value, as well - // as some slots for home objects. - void AssignFeedbackSlots(FeedbackVectorSpec* spec, LanguageMode language_mode, - FunctionKind kind, FeedbackSlotCache* cache); + FunctionLiteral* static_fields_initializer() const { + return static_fields_initializer_; + } - FeedbackSlot HomeObjectSlot() const { return home_object_slot_; } + FunctionLiteral* instance_fields_initializer_function() const { + return instance_fields_initializer_function_; + } private: friend class AstNodeFactory; ClassLiteral(Scope* scope, Variable* class_variable, Expression* extends, FunctionLiteral* constructor, ZoneList<Property*>* properties, + FunctionLiteral* static_fields_initializer, + FunctionLiteral* instance_fields_initializer_function, int start_position, int end_position, bool has_name_static_property, bool has_static_computed_names, bool is_anonymous) @@ -2556,20 +2455,23 @@ class ClassLiteral final : public Expression { class_variable_(class_variable), extends_(extends), constructor_(constructor), - properties_(properties) { + properties_(properties), + static_fields_initializer_(static_fields_initializer), + instance_fields_initializer_function_( + instance_fields_initializer_function) { bit_field_ |= HasNameStaticProperty::encode(has_name_static_property) | HasStaticComputedNames::encode(has_static_computed_names) | IsAnonymousExpression::encode(is_anonymous); } int end_position_; - FeedbackSlot home_object_slot_; Scope* scope_; Variable* class_variable_; Expression* extends_; FunctionLiteral* constructor_; ZoneList<Property*>* properties_; - + FunctionLiteral* static_fields_initializer_; + FunctionLiteral* instance_fields_initializer_function_; class HasNameStaticProperty : public BitField<bool, Expression::kNextBitFieldIndex, 1> {}; class HasStaticComputedNames @@ -2582,15 +2484,8 @@ class ClassLiteral final : public Expression { class NativeFunctionLiteral final : public Expression { public: Handle<String> name() const { return name_->string(); } + const AstRawString* raw_name() const { return name_; } v8::Extension* extension() const { return extension_; } - FeedbackSlot LiteralFeedbackSlot() const { return literal_feedback_slot_; } - - void AssignFeedbackSlots(FeedbackVectorSpec* spec, LanguageMode language_mode, - FunctionKind kind, FeedbackSlotCache* cache) { - // TODO(mvstanton): The FeedbackSlotCache can be adapted - // to always return the same slot for this case. - literal_feedback_slot_ = spec->AddCreateClosureSlot(); - } private: friend class AstNodeFactory; @@ -2601,7 +2496,6 @@ class NativeFunctionLiteral final : public Expression { name_(name), extension_(extension) {} - FeedbackSlot literal_feedback_slot_; const AstRawString* name_; v8::Extension* extension_; }; @@ -2617,9 +2511,7 @@ class ThisFunction final : public Expression { class SuperPropertyReference final : public Expression { public: VariableProxy* this_var() const { return this_var_; } - void set_this_var(VariableProxy* v) { this_var_ = v; } Expression* home_object() const { return home_object_; } - void set_home_object(Expression* e) { home_object_ = e; } private: friend class AstNodeFactory; @@ -2641,11 +2533,8 @@ class SuperPropertyReference final : public Expression { class SuperCallReference final : public Expression { public: VariableProxy* this_var() const { return this_var_; } - void set_this_var(VariableProxy* v) { this_var_ = v; } VariableProxy* new_target_var() const { return new_target_var_; } - void set_new_target_var(VariableProxy* v) { new_target_var_ = v; } VariableProxy* this_function_var() const { return this_function_var_; } - void set_this_function_var(VariableProxy* v) { this_function_var_ = v; } private: friend class AstNodeFactory; @@ -2671,7 +2560,6 @@ class SuperCallReference final : public Expression { class ImportCallExpression final : public Expression { public: Expression* argument() const { return argument_; } - void set_argument(Expression* argument) { argument_ = argument; } private: friend class AstNodeFactory; @@ -2701,33 +2589,6 @@ class GetIterator final : public Expression { IteratorType hint() const { return hint_; } Expression* iterable() const { return iterable_; } - void set_iterable(Expression* iterable) { iterable_ = iterable; } - - void AssignFeedbackSlots(FeedbackVectorSpec* spec, LanguageMode language_mode, - FunctionKind kind, FeedbackSlotCache* cache) { - iterator_property_feedback_slot_ = spec->AddLoadICSlot(); - iterator_call_feedback_slot_ = spec->AddCallICSlot(); - if (hint() == IteratorType::kAsync) { - async_iterator_property_feedback_slot_ = spec->AddLoadICSlot(); - async_iterator_call_feedback_slot_ = spec->AddCallICSlot(); - } - } - - FeedbackSlot IteratorPropertyFeedbackSlot() const { - return iterator_property_feedback_slot_; - } - - FeedbackSlot IteratorCallFeedbackSlot() const { - return iterator_call_feedback_slot_; - } - - FeedbackSlot AsyncIteratorPropertyFeedbackSlot() const { - return async_iterator_property_feedback_slot_; - } - - FeedbackSlot AsyncIteratorCallFeedbackSlot() const { - return async_iterator_call_feedback_slot_; - } Expression* iterable_for_call_printer() const { return destructured_iterable_ != nullptr ? destructured_iterable_ @@ -2757,19 +2618,18 @@ class GetIterator final : public Expression { // the raw value stored in the variable proxy. This is only used for // pretty printing error messages. Expression* destructured_iterable_; - - FeedbackSlot iterator_property_feedback_slot_; - FeedbackSlot iterator_call_feedback_slot_; - FeedbackSlot async_iterator_property_feedback_slot_; - FeedbackSlot async_iterator_call_feedback_slot_; }; // Represents the spec operation `GetTemplateObject(templateLiteral)` // (defined at https://tc39.github.io/ecma262/#sec-gettemplateobject). class GetTemplateObject final : public Expression { public: - ZoneList<Literal*>* cooked_strings() const { return cooked_strings_; } - ZoneList<Literal*>* raw_strings() const { return raw_strings_; } + const ZoneList<const AstRawString*>* cooked_strings() const { + return cooked_strings_; + } + const ZoneList<const AstRawString*>* raw_strings() const { + return raw_strings_; + } int hash() const { return hash_; } Handle<TemplateObjectDescription> GetOrBuildDescription(Isolate* isolate); @@ -2777,15 +2637,16 @@ class GetTemplateObject final : public Expression { private: friend class AstNodeFactory; - GetTemplateObject(ZoneList<Literal*>* cooked_strings, - ZoneList<Literal*>* raw_strings, int hash, int pos) + GetTemplateObject(const ZoneList<const AstRawString*>* cooked_strings, + const ZoneList<const AstRawString*>* raw_strings, int hash, + int pos) : Expression(pos, kGetTemplateObject), cooked_strings_(cooked_strings), raw_strings_(raw_strings), hash_(hash) {} - ZoneList<Literal*>* cooked_strings_; - ZoneList<Literal*>* raw_strings_; + const ZoneList<const AstRawString*>* cooked_strings_; + const ZoneList<const AstRawString*>* raw_strings_; int hash_; }; @@ -2813,12 +2674,12 @@ class AstVisitor BASE_EMBEDDED { void VisitExpressions(ZoneList<Expression*>* expressions) { for (int i = 0; i < expressions->length(); i++) { - // The variable statement visiting code may pass NULL expressions + // The variable statement visiting code may pass null expressions // to this code. Maybe this should be handled by introducing an - // undefined expression or literal? Revisit this code if this - // changes + // undefined expression or literal? Revisit this code if this + // changes. Expression* expression = expressions->at(i); - if (expression != NULL) Visit(expression); + if (expression != nullptr) Visit(expression); } } @@ -2879,69 +2740,6 @@ class AstVisitor BASE_EMBEDDED { \ private: -#define DEFINE_AST_REWRITER_SUBCLASS_MEMBERS() \ - public: \ - AstNode* Rewrite(AstNode* node) { \ - DCHECK_NULL(replacement_); \ - DCHECK_NOT_NULL(node); \ - Visit(node); \ - if (HasStackOverflow()) return node; \ - if (replacement_ == nullptr) return node; \ - AstNode* result = replacement_; \ - replacement_ = nullptr; \ - return result; \ - } \ - \ - private: \ - void InitializeAstRewriter(Isolate* isolate) { \ - InitializeAstVisitor(isolate); \ - replacement_ = nullptr; \ - } \ - \ - void InitializeAstRewriter(uintptr_t stack_limit) { \ - InitializeAstVisitor(stack_limit); \ - replacement_ = nullptr; \ - } \ - \ - DEFINE_AST_VISITOR_SUBCLASS_MEMBERS(); \ - \ - protected: \ - AstNode* replacement_ -// Generic macro for rewriting things; `GET` is the expression to be -// rewritten; `SET` is a command that should do the rewriting, i.e. -// something sensible with the variable called `replacement`. -#define AST_REWRITE(Type, GET, SET) \ - do { \ - DCHECK(!HasStackOverflow()); \ - DCHECK_NULL(replacement_); \ - Visit(GET); \ - if (HasStackOverflow()) return; \ - if (replacement_ == nullptr) break; \ - Type* replacement = reinterpret_cast<Type*>(replacement_); \ - do { \ - SET; \ - } while (false); \ - replacement_ = nullptr; \ - } while (false) - -// Macro for rewriting object properties; it assumes that `object` has -// `property` with a public getter and setter. -#define AST_REWRITE_PROPERTY(Type, object, property) \ - do { \ - auto _obj = (object); \ - AST_REWRITE(Type, _obj->property(), _obj->set_##property(replacement)); \ - } while (false) - -// Macro for rewriting list elements; it assumes that `list` has methods -// `at` and `Set`. -#define AST_REWRITE_LIST_ELEMENT(Type, list, index) \ - do { \ - auto _list = (list); \ - auto _index = (index); \ - AST_REWRITE(Type, _list->at(_index), _list->Set(_index, replacement)); \ - } while (false) - - // ---------------------------------------------------------------------------- // AstNode factory @@ -3100,36 +2898,38 @@ class AstNodeFactory final BASE_EMBEDDED { } Literal* NewStringLiteral(const AstRawString* string, int pos) { - return new (zone_) Literal(ast_value_factory_->NewString(string), pos); + return new (zone_) Literal(string, pos); } // A JavaScript symbol (ECMA-262 edition 6). Literal* NewSymbolLiteral(AstSymbol symbol, int pos) { - return new (zone_) Literal(ast_value_factory_->NewSymbol(symbol), pos); + return new (zone_) Literal(symbol, pos); } - Literal* NewNumberLiteral(double number, int pos) { - return new (zone_) Literal(ast_value_factory_->NewNumber(number), pos); + Literal* NewNumberLiteral(double number, int pos); + + Literal* NewSmiLiteral(int number, int pos) { + return new (zone_) Literal(number, pos); } - Literal* NewSmiLiteral(uint32_t number, int pos) { - return new (zone_) Literal(ast_value_factory_->NewSmi(number), pos); + Literal* NewBigIntLiteral(AstBigInt bigint, int pos) { + return new (zone_) Literal(bigint, pos); } Literal* NewBooleanLiteral(bool b, int pos) { - return new (zone_) Literal(ast_value_factory_->NewBoolean(b), pos); + return new (zone_) Literal(b, pos); } Literal* NewNullLiteral(int pos) { - return new (zone_) Literal(ast_value_factory_->NewNull(), pos); + return new (zone_) Literal(Literal::kNull, pos); } Literal* NewUndefinedLiteral(int pos) { - return new (zone_) Literal(ast_value_factory_->NewUndefined(), pos); + return new (zone_) Literal(Literal::kUndefined, pos); } - Literal* NewTheHoleLiteral(int pos) { - return new (zone_) Literal(ast_value_factory_->NewTheHole(), pos); + Literal* NewTheHoleLiteral() { + return new (zone_) Literal(Literal::kTheHole, kNoSourcePosition); } ObjectLiteral* NewObjectLiteral( @@ -3198,6 +2998,12 @@ class AstNodeFactory final BASE_EMBEDDED { return new (zone_) Call(expression, arguments, pos, possibly_eval); } + Call* NewTaggedTemplate(Expression* expression, + ZoneList<Expression*>* arguments, int pos) { + return new (zone_) + Call(expression, arguments, pos, Call::TaggedTemplateTag::kTrue); + } + CallNew* NewCallNew(Expression* expression, ZoneList<Expression*>* arguments, int pos) { @@ -3232,6 +3038,11 @@ class AstNodeFactory final BASE_EMBEDDED { return new (zone_) BinaryOperation(op, left, right, pos); } + NaryOperation* NewNaryOperation(Token::Value op, Expression* first, + size_t initial_subsequent_size) { + return new (zone_) NaryOperation(zone_, op, first, initial_subsequent_size); + } + CountOperation* NewCountOperation(Token::Value op, bool is_prefix, Expression* expr, @@ -3258,9 +3069,10 @@ class AstNodeFactory final BASE_EMBEDDED { Conditional(condition, then_expression, else_expression, position); } - RewritableExpression* NewRewritableExpression(Expression* expression) { + RewritableExpression* NewRewritableExpression(Expression* expression, + Scope* scope) { DCHECK_NOT_NULL(expression); - return new (zone_) RewritableExpression(expression); + return new (zone_) RewritableExpression(expression, scope); } Assignment* NewAssignment(Token::Value op, @@ -3343,18 +3155,19 @@ class AstNodeFactory final BASE_EMBEDDED { ClassLiteral::Property(key, value, kind, is_static, is_computed_name); } - ClassLiteral* NewClassLiteral(Scope* scope, Variable* variable, - Expression* extends, - FunctionLiteral* constructor, - ZoneList<ClassLiteral::Property*>* properties, - int start_position, int end_position, - bool has_name_static_property, - bool has_static_computed_names, - bool is_anonymous) { - return new (zone_) - ClassLiteral(scope, variable, extends, constructor, properties, - start_position, end_position, has_name_static_property, - has_static_computed_names, is_anonymous); + ClassLiteral* NewClassLiteral( + Scope* scope, Variable* variable, Expression* extends, + FunctionLiteral* constructor, + ZoneList<ClassLiteral::Property*>* properties, + FunctionLiteral* static_fields_initializer, + FunctionLiteral* instance_fields_initializer_function, int start_position, + int end_position, bool has_name_static_property, + bool has_static_computed_names, bool is_anonymous) { + return new (zone_) ClassLiteral( + scope, variable, extends, constructor, properties, + static_fields_initializer, instance_fields_initializer_function, + start_position, end_position, has_name_static_property, + has_static_computed_names, is_anonymous); } NativeFunctionLiteral* NewNativeFunctionLiteral(const AstRawString* name, @@ -3401,9 +3214,9 @@ class AstNodeFactory final BASE_EMBEDDED { return new (zone_) GetIterator(iterable, hint, pos); } - GetTemplateObject* NewGetTemplateObject(ZoneList<Literal*>* cooked_strings, - ZoneList<Literal*>* raw_strings, - int hash, int pos) { + GetTemplateObject* NewGetTemplateObject( + const ZoneList<const AstRawString*>* cooked_strings, + const ZoneList<const AstRawString*>* raw_strings, int hash, int pos) { return new (zone_) GetTemplateObject(cooked_strings, raw_strings, hash, pos); } @@ -3412,6 +3225,11 @@ class AstNodeFactory final BASE_EMBEDDED { return new (zone_) ImportCallExpression(args, pos); } + InitializeClassFieldsStatement* NewInitializeClassFieldsStatement( + ZoneList<ClassLiteralProperty*>* args, int pos) { + return new (zone_) InitializeClassFieldsStatement(args, pos); + } + Zone* zone() const { return zone_; } void set_zone(Zone* zone) { zone_ = zone; } @@ -3428,38 +3246,39 @@ class AstNodeFactory final BASE_EMBEDDED { // Type testing & conversion functions overridden by concrete subclasses. // Inline functions for AstNode. -#define DECLARE_NODE_FUNCTIONS(type) \ - bool AstNode::Is##type() const { \ - NodeType mine = node_type(); \ - if (mine == AstNode::kRewritableExpression && \ - AstNode::k##type != AstNode::kRewritableExpression) \ - mine = reinterpret_cast<const RewritableExpression*>(this) \ - ->expression() \ - ->node_type(); \ - return mine == AstNode::k##type; \ - } \ - type* AstNode::As##type() { \ - NodeType mine = node_type(); \ - AstNode* result = this; \ - if (mine == AstNode::kRewritableExpression && \ - AstNode::k##type != AstNode::kRewritableExpression) { \ - result = \ - reinterpret_cast<const RewritableExpression*>(this)->expression(); \ - mine = result->node_type(); \ - } \ - return mine == AstNode::k##type ? reinterpret_cast<type*>(result) : NULL; \ - } \ - const type* AstNode::As##type() const { \ - NodeType mine = node_type(); \ - const AstNode* result = this; \ - if (mine == AstNode::kRewritableExpression && \ - AstNode::k##type != AstNode::kRewritableExpression) { \ - result = \ - reinterpret_cast<const RewritableExpression*>(this)->expression(); \ - mine = result->node_type(); \ - } \ - return mine == AstNode::k##type ? reinterpret_cast<const type*>(result) \ - : NULL; \ +#define DECLARE_NODE_FUNCTIONS(type) \ + bool AstNode::Is##type() const { \ + NodeType mine = node_type(); \ + if (mine == AstNode::kRewritableExpression && \ + AstNode::k##type != AstNode::kRewritableExpression) \ + mine = reinterpret_cast<const RewritableExpression*>(this) \ + ->expression() \ + ->node_type(); \ + return mine == AstNode::k##type; \ + } \ + type* AstNode::As##type() { \ + NodeType mine = node_type(); \ + AstNode* result = this; \ + if (mine == AstNode::kRewritableExpression && \ + AstNode::k##type != AstNode::kRewritableExpression) { \ + result = \ + reinterpret_cast<const RewritableExpression*>(this)->expression(); \ + mine = result->node_type(); \ + } \ + return mine == AstNode::k##type ? reinterpret_cast<type*>(result) \ + : nullptr; \ + } \ + const type* AstNode::As##type() const { \ + NodeType mine = node_type(); \ + const AstNode* result = this; \ + if (mine == AstNode::kRewritableExpression && \ + AstNode::k##type != AstNode::kRewritableExpression) { \ + result = \ + reinterpret_cast<const RewritableExpression*>(this)->expression(); \ + mine = result->node_type(); \ + } \ + return mine == AstNode::k##type ? reinterpret_cast<const type*>(result) \ + : nullptr; \ } AST_NODE_LIST(DECLARE_NODE_FUNCTIONS) #undef DECLARE_NODE_FUNCTIONS diff --git a/deps/v8/src/ast/context-slot-cache.h b/deps/v8/src/ast/context-slot-cache.h index b4e3590919..bf4a6d709e 100644 --- a/deps/v8/src/ast/context-slot-cache.h +++ b/deps/v8/src/ast/context-slot-cache.h @@ -36,8 +36,8 @@ class ContextSlotCache { private: ContextSlotCache() { for (int i = 0; i < kLength; ++i) { - keys_[i].data = NULL; - keys_[i].name = NULL; + keys_[i].data = nullptr; + keys_[i].name = nullptr; values_[i] = static_cast<uint32_t>(kNotFound); } } diff --git a/deps/v8/src/ast/modules.h b/deps/v8/src/ast/modules.h index d44bb46c75..465eca447f 100644 --- a/deps/v8/src/ast/modules.h +++ b/deps/v8/src/ast/modules.h @@ -21,8 +21,8 @@ class ModuleDescriptor : public ZoneObject { public: explicit ModuleDescriptor(Zone* zone) : module_requests_(zone), - special_exports_(1, zone), - namespace_imports_(1, zone), + special_exports_(zone), + namespace_imports_(zone), regular_exports_(zone), regular_imports_(zone) {} @@ -130,7 +130,7 @@ class ModuleDescriptor : public ZoneObject { } // Namespace imports. - const ZoneList<const Entry*>& namespace_imports() const { + const ZoneVector<const Entry*>& namespace_imports() const { return namespace_imports_; } @@ -140,7 +140,7 @@ class ModuleDescriptor : public ZoneObject { } // Star exports and explicitly indirect exports. - const ZoneList<const Entry*>& special_exports() const { + const ZoneVector<const Entry*>& special_exports() const { return special_exports_; } @@ -161,7 +161,7 @@ class ModuleDescriptor : public ZoneObject { void AddSpecialExport(const Entry* entry, Zone* zone) { DCHECK_NULL(entry->local_name); DCHECK_LE(0, entry->module_request); - special_exports_.Add(entry, zone); + special_exports_.push_back(entry); } void AddRegularImport(Entry* entry) { @@ -179,7 +179,7 @@ class ModuleDescriptor : public ZoneObject { DCHECK_NULL(entry->export_name); DCHECK_NOT_NULL(entry->local_name); DCHECK_LE(0, entry->module_request); - namespace_imports_.Add(entry, zone); + namespace_imports_.push_back(entry); } Handle<FixedArray> SerializeRegularExports(Isolate* isolate, @@ -188,10 +188,9 @@ class ModuleDescriptor : public ZoneObject { Handle<ModuleInfo> module_info); private: - // TODO(neis): Use STL datastructure instead of ZoneList? ZoneMap<const AstRawString*, ModuleRequest> module_requests_; - ZoneList<const Entry*> special_exports_; - ZoneList<const Entry*> namespace_imports_; + ZoneVector<const Entry*> special_exports_; + ZoneVector<const Entry*> namespace_imports_; ZoneMultimap<const AstRawString*, Entry*> regular_exports_; ZoneMap<const AstRawString*, Entry*> regular_imports_; diff --git a/deps/v8/src/ast/prettyprinter.cc b/deps/v8/src/ast/prettyprinter.cc index b3ab10aab9..f01ade8896 100644 --- a/deps/v8/src/ast/prettyprinter.cc +++ b/deps/v8/src/ast/prettyprinter.cc @@ -146,11 +146,11 @@ void CallPrinter::VisitWhileStatement(WhileStatement* node) { void CallPrinter::VisitForStatement(ForStatement* node) { - if (node->init() != NULL) { + if (node->init() != nullptr) { Find(node->init()); } - if (node->cond() != NULL) Find(node->cond()); - if (node->next() != NULL) Find(node->next()); + if (node->cond() != nullptr) Find(node->cond()); + if (node->next() != nullptr) Find(node->next()); Find(node->body()); } @@ -198,6 +198,12 @@ void CallPrinter::VisitClassLiteral(ClassLiteral* node) { } } +void CallPrinter::VisitInitializeClassFieldsStatement( + InitializeClassFieldsStatement* node) { + for (int i = 0; i < node->fields()->length(); i++) { + Find(node->fields()->at(i)->value()); + } +} void CallPrinter::VisitNativeFunctionLiteral(NativeFunctionLiteral* node) {} @@ -213,7 +219,9 @@ void CallPrinter::VisitConditional(Conditional* node) { void CallPrinter::VisitLiteral(Literal* node) { - PrintLiteral(node->value(), true); + // TODO(adamk): Teach Literal how to print its values without + // allocating on the heap. + PrintLiteral(node->BuildValue(isolate_), true); } @@ -279,10 +287,13 @@ void CallPrinter::VisitThrow(Throw* node) { Find(node->exception()); } void CallPrinter::VisitProperty(Property* node) { Expression* key = node->key(); Literal* literal = key->AsLiteral(); - if (literal != NULL && literal->value()->IsInternalizedString()) { + if (literal != nullptr && + literal->BuildValue(isolate_)->IsInternalizedString()) { Find(node->obj(), true); Print("."); - PrintLiteral(literal->value(), false); + // TODO(adamk): Teach Literal how to print its values without + // allocating on the heap. + PrintLiteral(literal->BuildValue(isolate_), false); } else { Find(node->obj(), true); Print("["); @@ -377,6 +388,17 @@ void CallPrinter::VisitBinaryOperation(BinaryOperation* node) { Print(")"); } +void CallPrinter::VisitNaryOperation(NaryOperation* node) { + Print("("); + Find(node->first(), true); + for (size_t i = 0; i < node->subsequent_length(); ++i) { + Print(" "); + Print(Token::String(node->op())); + Print(" "); + Find(node->subsequent(i), true); + } + Print(")"); +} void CallPrinter::VisitCompareOperation(CompareOperation* node) { Print("("); @@ -442,7 +464,7 @@ void CallPrinter::VisitRewritableExpression(RewritableExpression* node) { void CallPrinter::FindStatements(ZoneList<Statement*>* statements) { - if (statements == NULL) return; + if (statements == nullptr) return; for (int i = 0; i < statements->length(); i++) { Find(statements->at(i)); } @@ -488,16 +510,6 @@ void CallPrinter::PrintLiteral(const AstRawString* value, bool quote) { #ifdef DEBUG -// A helper for ast nodes that use FeedbackSlots. -static int FormatSlotNode(Vector<char>* buf, Expression* node, - const char* node_name, FeedbackSlot slot) { - int pos = SNPrintF(*buf, "%s", node_name); - if (!slot.IsInvalid()) { - pos += SNPrintF(*buf + pos, " Slot(%d)", slot.ToInt()); - } - return pos; -} - const char* AstPrinter::Print(AstNode* node) { Init(); Visit(node); @@ -506,7 +518,7 @@ const char* AstPrinter::Print(AstNode* node) { void AstPrinter::Init() { if (size_ == 0) { - DCHECK(output_ == NULL); + DCHECK_NULL(output_); const int initial_size = 256; output_ = NewArray<char>(initial_size); size_ = initial_size; @@ -542,7 +554,7 @@ void AstPrinter::Print(const char* format, ...) { } void AstPrinter::PrintLabels(ZoneList<const AstRawString*>* labels) { - if (labels != NULL) { + if (labels != nullptr) { for (int i = 0; i < labels->length(); i++) { PrintLiteral(labels->at(i), false); Print(": "); @@ -550,64 +562,70 @@ void AstPrinter::PrintLabels(ZoneList<const AstRawString*>* labels) { } } -void AstPrinter::PrintLiteral(MaybeHandle<Object> maybe_value, bool quote) { - Handle<Object> value; - if (!maybe_value.ToHandle(&value)) { - Print("<nil>"); - return; - } - Object* object = *value; - if (object->IsString()) { - String* string = String::cast(object); - if (quote) Print("\""); - for (int i = 0; i < string->length(); i++) { - Print("%c", string->Get(i)); - } - if (quote) Print("\""); - } else if (object->IsNull(isolate_)) { - Print("null"); - } else if (object->IsTrue(isolate_)) { - Print("true"); - } else if (object->IsFalse(isolate_)) { - Print("false"); - } else if (object->IsUndefined(isolate_)) { - Print("undefined"); - } else if (object->IsNumber()) { - Print("%g", object->Number()); - } else if (object->IsJSObject()) { - // regular expression - if (object->IsJSFunction()) { - Print("JS-Function"); - } else if (object->IsJSArray()) { - Print("JS-array[%u]", Smi::ToInt(JSArray::cast(object)->length())); - } else if (object->IsJSObject()) { - Print("JS-Object"); - } else { - Print("?UNKNOWN?"); - } - } else if (object->IsFixedArray()) { - Print("FixedArray"); - } else if (object->IsSymbol()) { - // Symbols can only occur as literals if they were inserted by the parser. - Symbol* symbol = Symbol::cast(object); - if (symbol->name()->IsString()) { - int length = 0; - String* string = String::cast(symbol->name()); - std::unique_ptr<char[]> desc = string->ToCString( - ALLOW_NULLS, FAST_STRING_TRAVERSAL, 0, string->length(), &length); - Print("Symbol(%*s)", length, desc.get()); - } else { - Print("Symbol()"); - } - } else { - Print("<unknown literal %p>", static_cast<void*>(object)); +void AstPrinter::PrintLiteral(Literal* literal, bool quote) { + switch (literal->type()) { + case Literal::kString: + PrintLiteral(literal->AsRawString(), quote); + break; + case Literal::kSymbol: + const char* symbol; + switch (literal->AsSymbol()) { + case AstSymbol::kHomeObjectSymbol: + symbol = "HomeObjectSymbol"; + } + Print("%s", symbol); + break; + case Literal::kSmi: + Print("%d", Smi::ToInt(literal->AsSmiLiteral())); + break; + case Literal::kHeapNumber: + Print("%g", literal->AsNumber()); + break; + case Literal::kBigInt: + Print("%sn", literal->AsBigInt().c_str()); + break; + case Literal::kNull: + Print("null"); + break; + case Literal::kUndefined: + Print("undefined"); + break; + case Literal::kTheHole: + Print("the hole"); + break; + case Literal::kBoolean: + if (literal->ToBooleanIsTrue()) { + Print("true"); + } else { + Print("false"); + } + break; } } void AstPrinter::PrintLiteral(const AstRawString* value, bool quote) { - PrintLiteral(value->string(), quote); + if (quote) Print("\""); + if (value != nullptr) { + const char* format = value->is_one_byte() ? "%c" : "%lc"; + const int increment = value->is_one_byte() ? 1 : 2; + const unsigned char* raw_bytes = value->raw_data(); + for (int i = 0; i < value->length(); i += increment) { + Print(format, raw_bytes[i]); + } + } + if (quote) Print("\""); } +void AstPrinter::PrintLiteral(const AstConsString* value, bool quote) { + if (quote) Print("\""); + if (value != nullptr) { + std::forward_list<const AstRawString*> strings = value->ToRawStrings(); + for (const AstRawString* string : strings) { + PrintLiteral(string, false); + } + } + if (quote) Print("\""); +} //----------------------------------------------------------------------------- @@ -638,13 +656,13 @@ class IndentedScope BASE_EMBEDDED { //----------------------------------------------------------------------------- -AstPrinter::AstPrinter(Isolate* isolate) - : isolate_(isolate), output_(nullptr), size_(0), pos_(0), indent_(0) { - InitializeAstVisitor(isolate); +AstPrinter::AstPrinter(uintptr_t stack_limit) + : output_(nullptr), size_(0), pos_(0), indent_(0) { + InitializeAstVisitor(stack_limit); } AstPrinter::~AstPrinter() { - DCHECK(indent_ == 0); + DCHECK_EQ(indent_, 0); DeleteArray(output_); } @@ -656,20 +674,33 @@ void AstPrinter::PrintIndented(const char* txt) { Print("%s", txt); } -void AstPrinter::PrintLiteralIndented(const char* info, - MaybeHandle<Object> maybe_value, +void AstPrinter::PrintLiteralIndented(const char* info, Literal* literal, bool quote) { PrintIndented(info); Print(" "); - PrintLiteral(maybe_value, quote); + PrintLiteral(literal, quote); Print("\n"); } +void AstPrinter::PrintLiteralIndented(const char* info, + const AstRawString* value, bool quote) { + PrintIndented(info); + Print(" "); + PrintLiteral(value, quote); + Print("\n"); +} -void AstPrinter::PrintLiteralWithModeIndented(const char* info, - Variable* var, - Handle<Object> value) { - if (var == NULL) { +void AstPrinter::PrintLiteralIndented(const char* info, + const AstConsString* value, bool quote) { + PrintIndented(info); + Print(" "); + PrintLiteral(value, quote); + Print("\n"); +} + +void AstPrinter::PrintLiteralWithModeIndented(const char* info, Variable* var, + const AstRawString* value) { + if (var == nullptr) { PrintLiteralIndented(info, value, true); } else { EmbeddedVector<char, 256> buf; @@ -683,7 +714,7 @@ void AstPrinter::PrintLiteralWithModeIndented(const char* info, void AstPrinter::PrintLabelsIndented(ZoneList<const AstRawString*>* labels) { - if (labels == NULL || labels->length() == 0) return; + if (labels == nullptr || labels->length() == 0) return; PrintIndented("LABELS "); PrintLabels(labels); Print("\n"); @@ -703,8 +734,13 @@ const char* AstPrinter::PrintProgram(FunctionLiteral* program) { Print(" %d\n", program->kind()); PrintIndented("SUSPEND COUNT"); Print(" %d\n", program->suspend_count()); - PrintLiteralIndented("NAME", program->name(), true); - PrintLiteralIndented("INFERRED NAME", program->inferred_name(), true); + PrintLiteralIndented("NAME", program->raw_name(), true); + if (program->raw_inferred_name()) { + PrintLiteralIndented("INFERRED NAME", program->raw_inferred_name(), true); + } + if (program->requires_instance_fields_initializer()) { + Print(" REQUIRES INSTANCE FIELDS INITIALIZER\n"); + } PrintParameters(program->scope()); PrintDeclarations(program->scope()->declarations()); PrintStatements(program->body()); @@ -714,7 +750,7 @@ const char* AstPrinter::PrintProgram(FunctionLiteral* program) { void AstPrinter::PrintOut(Isolate* isolate, AstNode* node) { - AstPrinter printer(isolate); + AstPrinter printer(isolate->stack_guard()->real_climit()); printer.Init(); printer.Visit(node); PrintF("%s", printer.output_); @@ -732,7 +768,7 @@ void AstPrinter::PrintParameters(DeclarationScope* scope) { IndentedScope indent(this, "PARAMS"); for (int i = 0; i < scope->num_parameters(); i++) { PrintLiteralWithModeIndented("VAR", scope->parameter(i), - scope->parameter(i)->name()); + scope->parameter(i)->raw_name()); } } } @@ -763,16 +799,16 @@ void AstPrinter::VisitBlock(Block* node) { // TODO(svenpanne) Start with IndentedScope. void AstPrinter::VisitVariableDeclaration(VariableDeclaration* node) { PrintLiteralWithModeIndented("VARIABLE", node->proxy()->var(), - node->proxy()->name()); + node->proxy()->raw_name()); } // TODO(svenpanne) Start with IndentedScope. void AstPrinter::VisitFunctionDeclaration(FunctionDeclaration* node) { PrintIndented("FUNCTION "); - PrintLiteral(node->proxy()->name(), true); + PrintLiteral(node->proxy()->raw_name(), true); Print(" = function "); - PrintLiteral(node->fun()->name(), false); + PrintLiteral(node->fun()->raw_name(), false); Print("\n"); } @@ -925,7 +961,7 @@ void AstPrinter::VisitTryCatchStatement(TryCatchStatement* node) { } Print(" %s\n", prediction); PrintLiteralWithModeIndented("CATCHVAR", node->scope()->catch_variable(), - node->scope()->catch_variable()->name()); + node->scope()->catch_variable()->raw_name()); PrintIndentedVisit("CATCH", node->catch_block()); } @@ -942,8 +978,8 @@ void AstPrinter::VisitDebuggerStatement(DebuggerStatement* node) { void AstPrinter::VisitFunctionLiteral(FunctionLiteral* node) { IndentedScope indent(this, "FUNC LITERAL", node->position()); - PrintLiteralIndented("NAME", node->name(), false); - PrintLiteralIndented("INFERRED NAME", node->inferred_name(), false); + PrintLiteralIndented("NAME", node->raw_name(), false); + PrintLiteralIndented("INFERRED NAME", node->raw_inferred_name(), false); PrintParameters(node->scope()); // We don't want to see the function literal in this case: it // will be printed via PrintProgram when the code for it is @@ -954,13 +990,27 @@ void AstPrinter::VisitFunctionLiteral(FunctionLiteral* node) { void AstPrinter::VisitClassLiteral(ClassLiteral* node) { IndentedScope indent(this, "CLASS LITERAL", node->position()); - PrintLiteralIndented("NAME", node->constructor()->name(), false); + PrintLiteralIndented("NAME", node->constructor()->raw_name(), false); if (node->extends() != nullptr) { PrintIndentedVisit("EXTENDS", node->extends()); } + if (node->static_fields_initializer() != nullptr) { + PrintIndentedVisit("STATIC FIELDS INITIALIZER", + node->static_fields_initializer()); + } + if (node->instance_fields_initializer_function() != nullptr) { + PrintIndentedVisit("INSTANCE FIELDS INITIALIZER", + node->instance_fields_initializer_function()); + } PrintClassProperties(node->properties()); } +void AstPrinter::VisitInitializeClassFieldsStatement( + InitializeClassFieldsStatement* node) { + IndentedScope indent(this, "INITIALIZE CLASS FIELDS", node->position()); + PrintClassProperties(node->fields()); +} + void AstPrinter::PrintClassProperties( ZoneList<ClassLiteral::Property*>* properties) { for (int i = 0; i < properties->length(); i++) { @@ -992,7 +1042,7 @@ void AstPrinter::PrintClassProperties( void AstPrinter::VisitNativeFunctionLiteral(NativeFunctionLiteral* node) { IndentedScope indent(this, "NATIVE FUNC LITERAL", node->position()); - PrintLiteralIndented("NAME", node->name(), false); + PrintLiteralIndented("NAME", node->raw_name(), false); } @@ -1010,19 +1060,16 @@ void AstPrinter::VisitConditional(Conditional* node) { } -// TODO(svenpanne) Start with IndentedScope. void AstPrinter::VisitLiteral(Literal* node) { - PrintLiteralIndented("LITERAL", node->value(), true); + PrintLiteralIndented("LITERAL", node, true); } void AstPrinter::VisitRegExpLiteral(RegExpLiteral* node) { IndentedScope indent(this, "REGEXP LITERAL", node->position()); - EmbeddedVector<char, 128> buf; - SNPrintF(buf, "literal_slot = %d\n", node->literal_slot().ToInt()); - PrintIndented(buf.start()); - PrintLiteralIndented("PATTERN", node->pattern(), false); + PrintLiteralIndented("PATTERN", node->raw_pattern(), false); int i = 0; + EmbeddedVector<char, 128> buf; if (node->flags() & RegExp::kGlobal) buf[i++] = 'g'; if (node->flags() & RegExp::kIgnoreCase) buf[i++] = 'i'; if (node->flags() & RegExp::kMultiline) buf[i++] = 'm'; @@ -1037,9 +1084,6 @@ void AstPrinter::VisitRegExpLiteral(RegExpLiteral* node) { void AstPrinter::VisitObjectLiteral(ObjectLiteral* node) { IndentedScope indent(this, "OBJ LITERAL", node->position()); - EmbeddedVector<char, 128> buf; - SNPrintF(buf, "literal_slot = %d\n", node->literal_slot().ToInt()); - PrintIndented(buf.start()); PrintObjectProperties(node->properties()); } @@ -1082,10 +1126,6 @@ void AstPrinter::PrintObjectProperties( void AstPrinter::VisitArrayLiteral(ArrayLiteral* node) { IndentedScope indent(this, "ARRAY LITERAL", node->position()); - - EmbeddedVector<char, 128> buf; - SNPrintF(buf, "literal_slot = %d\n", node->literal_slot().ToInt()); - PrintIndented(buf.start()); if (node->values()->length() > 0) { IndentedScope indent(this, "VALUES", node->position()); for (int i = 0; i < node->values()->length(); i++) { @@ -1097,12 +1137,11 @@ void AstPrinter::VisitArrayLiteral(ArrayLiteral* node) { void AstPrinter::VisitVariableProxy(VariableProxy* node) { EmbeddedVector<char, 128> buf; - int pos = - FormatSlotNode(&buf, node, "VAR PROXY", node->VariableFeedbackSlot()); + int pos = SNPrintF(buf, "VAR PROXY"); if (!node->is_resolved()) { SNPrintF(buf + pos, " unresolved"); - PrintLiteralWithModeIndented(buf.start(), nullptr, node->name()); + PrintLiteralWithModeIndented(buf.start(), nullptr, node->raw_name()); } else { Variable* var = node->var(); switch (var->location()) { @@ -1125,7 +1164,7 @@ void AstPrinter::VisitVariableProxy(VariableProxy* node) { SNPrintF(buf + pos, " module"); break; } - PrintLiteralWithModeIndented(buf.start(), var, node->name()); + PrintLiteralWithModeIndented(buf.start(), var, node->raw_name()); } } @@ -1169,14 +1208,17 @@ void AstPrinter::VisitThrow(Throw* node) { void AstPrinter::VisitProperty(Property* node) { EmbeddedVector<char, 128> buf; - FormatSlotNode(&buf, node, "PROPERTY", node->PropertyFeedbackSlot()); + SNPrintF(buf, "PROPERTY"); IndentedScope indent(this, buf.start(), node->position()); Visit(node->obj()); - Literal* literal = node->key()->AsLiteral(); - if (literal != NULL && literal->value()->IsInternalizedString()) { - PrintLiteralIndented("NAME", literal->value(), false); + LhsKind property_kind = Property::GetAssignType(node); + if (property_kind == NAMED_PROPERTY || + property_kind == NAMED_SUPER_PROPERTY) { + PrintLiteralIndented("NAME", node->key()->AsLiteral(), false); } else { + DCHECK(property_kind == KEYED_PROPERTY || + property_kind == KEYED_SUPER_PROPERTY); PrintIndentedVisit("KEY", node->key()); } } @@ -1184,7 +1226,7 @@ void AstPrinter::VisitProperty(Property* node) { void AstPrinter::VisitCall(Call* node) { EmbeddedVector<char, 128> buf; - FormatSlotNode(&buf, node, "CALL", node->CallFeedbackICSlot()); + SNPrintF(buf, "CALL"); IndentedScope indent(this, buf.start()); Visit(node->expression()); @@ -1229,6 +1271,13 @@ void AstPrinter::VisitBinaryOperation(BinaryOperation* node) { Visit(node->right()); } +void AstPrinter::VisitNaryOperation(NaryOperation* node) { + IndentedScope indent(this, Token::Name(node->op()), node->position()); + Visit(node->first()); + for (size_t i = 0; i < node->subsequent_length(); ++i) { + Visit(node->subsequent(i)); + } +} void AstPrinter::VisitCompareOperation(CompareOperation* node) { IndentedScope indent(this, Token::Name(node->op()), node->position()); diff --git a/deps/v8/src/ast/prettyprinter.h b/deps/v8/src/ast/prettyprinter.h index 58849a6052..97c2437877 100644 --- a/deps/v8/src/ast/prettyprinter.h +++ b/deps/v8/src/ast/prettyprinter.h @@ -64,7 +64,7 @@ class CallPrinter final : public AstVisitor<CallPrinter> { class AstPrinter final : public AstVisitor<AstPrinter> { public: - explicit AstPrinter(Isolate* isolate); + explicit AstPrinter(uintptr_t stack_limit); ~AstPrinter(); // The following routines print a node into a string. @@ -89,7 +89,8 @@ class AstPrinter final : public AstVisitor<AstPrinter> { void PrintLabels(ZoneList<const AstRawString*>* labels); void PrintLiteral(const AstRawString* value, bool quote); - void PrintLiteral(MaybeHandle<Object> maybe_value, bool quote); + void PrintLiteral(const AstConsString* value, bool quote); + void PrintLiteral(Literal* literal, bool quote); void PrintIndented(const char* txt); void PrintIndentedVisit(const char* s, AstNode* node); @@ -98,11 +99,13 @@ class AstPrinter final : public AstVisitor<AstPrinter> { void PrintParameters(DeclarationScope* scope); void PrintArguments(ZoneList<Expression*>* arguments); void PrintCaseClause(CaseClause* clause); - void PrintLiteralIndented(const char* info, MaybeHandle<Object> maybe_value, + void PrintLiteralIndented(const char* info, Literal* literal, bool quote); + void PrintLiteralIndented(const char* info, const AstRawString* value, bool quote); - void PrintLiteralWithModeIndented(const char* info, - Variable* var, - Handle<Object> value); + void PrintLiteralIndented(const char* info, const AstConsString* value, + bool quote); + void PrintLiteralWithModeIndented(const char* info, Variable* var, + const AstRawString* value); void PrintLabelsIndented(ZoneList<const AstRawString*>* labels); void PrintObjectProperties(ZoneList<ObjectLiteral::Property*>* properties); void PrintClassProperties(ZoneList<ClassLiteral::Property*>* properties); @@ -112,7 +115,6 @@ class AstPrinter final : public AstVisitor<AstPrinter> { DEFINE_AST_VISITOR_SUBCLASS_MEMBERS(); - Isolate* isolate_; char* output_; // output string buffer int size_; // output_ size int pos_; // current printing position diff --git a/deps/v8/src/ast/scopes.cc b/deps/v8/src/ast/scopes.cc index 07eacd3fe9..d012ec90f1 100644 --- a/deps/v8/src/ast/scopes.cc +++ b/deps/v8/src/ast/scopes.cc @@ -98,12 +98,12 @@ void VariableMap::Add(Zone* zone, Variable* var) { Variable* VariableMap::Lookup(const AstRawString* name) { Entry* p = ZoneHashMap::Lookup(const_cast<AstRawString*>(name), name->Hash()); - if (p != NULL) { + if (p != nullptr) { DCHECK(reinterpret_cast<const AstRawString*>(p->key) == name); - DCHECK(p->value != NULL); + DCHECK_NOT_NULL(p->value); return reinterpret_cast<Variable*>(p->value); } - return NULL; + return nullptr; } void SloppyBlockFunctionMap::Delegate::set_statement(Statement* statement) { @@ -197,7 +197,7 @@ ModuleScope::ModuleScope(DeclarationScope* script_scope, kModule) { Zone* zone = ast_value_factory->zone(); module_descriptor_ = new (zone) ModuleDescriptor(zone); - set_language_mode(STRICT); + set_language_mode(LanguageMode::kStrict); DeclareThis(ast_value_factory); } @@ -208,7 +208,7 @@ ModuleScope::ModuleScope(Handle<ScopeInfo> scope_info, Isolate* isolate = scope_info->GetIsolate(); Handle<ModuleInfo> module_info(scope_info->ModuleDescriptorInfo(), isolate); - set_language_mode(STRICT); + set_language_mode(LanguageMode::kStrict); module_descriptor_ = new (zone) ModuleDescriptor(zone); // Deserialize special exports. @@ -339,7 +339,7 @@ void Scope::SetDefaults() { num_stack_slots_ = 0; num_heap_slots_ = Context::MIN_CONTEXT_SLOTS; - set_language_mode(SLOPPY); + set_language_mode(LanguageMode::kSloppy); scope_calls_eval_ = false; scope_nonlinear_ = false; @@ -605,12 +605,10 @@ void DeclarationScope::HoistSloppyBlockFunctions(AstNodeFactory* factory) { auto declaration = factory->NewVariableDeclaration(proxy, kNoSourcePosition); // Based on the preceding checks, it doesn't matter what we pass as - // allow_harmony_restrictive_generators and // sloppy_mode_block_scope_function_redefinition. bool ok = true; DeclareVariable(declaration, VAR, - Variable::DefaultInitializationFlag(VAR), false, nullptr, - &ok); + Variable::DefaultInitializationFlag(VAR), nullptr, &ok); DCHECK(ok); } else { DCHECK(is_being_lazily_parsed_); @@ -648,9 +646,12 @@ void DeclarationScope::AttachOuterScopeInfo(ParseInfo* info, Isolate* isolate) { } void DeclarationScope::Analyze(ParseInfo* info) { - RuntimeCallTimerScope runtimeTimer(info->runtime_call_stats(), - &RuntimeCallStats::CompileScopeAnalysis); - DCHECK(info->literal() != NULL); + RuntimeCallTimerScope runtimeTimer( + info->runtime_call_stats(), + info->on_background_thread() + ? &RuntimeCallStats::CompileBackgroundScopeAnalysis + : &RuntimeCallStats::CompileScopeAnalysis); + DCHECK_NOT_NULL(info->literal()); DeclarationScope* scope = info->literal()->scope(); base::Optional<AllowHandleDereference> allow_deref; @@ -998,13 +999,11 @@ Variable* Scope::LookupInScopeInfo(const AstRawString* name) { } Variable* Scope::Lookup(const AstRawString* name) { - for (Scope* scope = this; - scope != NULL; - scope = scope->outer_scope()) { + for (Scope* scope = this; scope != nullptr; scope = scope->outer_scope()) { Variable* var = scope->LookupLocal(name); - if (var != NULL) return var; + if (var != nullptr) return var; } - return NULL; + return nullptr; } Variable* DeclarationScope::DeclareParameter( @@ -1080,7 +1079,6 @@ Variable* Scope::DeclareLocal(const AstRawString* name, VariableMode mode, Variable* Scope::DeclareVariable( Declaration* declaration, VariableMode mode, InitializationFlag init, - bool allow_harmony_restrictive_generators, bool* sloppy_mode_block_scope_function_redefinition, bool* ok) { DCHECK(IsDeclaredVariableMode(mode)); DCHECK(!already_resolved_); @@ -1089,8 +1087,8 @@ Variable* Scope::DeclareVariable( if (mode == VAR && !is_declaration_scope()) { return GetDeclarationScope()->DeclareVariable( - declaration, mode, init, allow_harmony_restrictive_generators, - sloppy_mode_block_scope_function_redefinition, ok); + declaration, mode, init, sloppy_mode_block_scope_function_redefinition, + ok); } DCHECK(!is_catch_scope()); DCHECK(!is_with_scope()); @@ -1098,7 +1096,7 @@ Variable* Scope::DeclareVariable( (IsLexicalVariableMode(mode) && is_block_scope())); VariableProxy* proxy = declaration->proxy(); - DCHECK(proxy->raw_name() != NULL); + DCHECK_NOT_NULL(proxy->raw_name()); const AstRawString* name = proxy->raw_name(); bool is_function_declaration = declaration->IsFunctionDeclaration(); @@ -1125,7 +1123,7 @@ Variable* Scope::DeclareVariable( } else { // Declare the variable in the declaration scope. var = LookupLocal(name); - if (var == NULL) { + if (var == nullptr) { // Declare the name. VariableKind kind = NORMAL_VARIABLE; if (is_function_declaration) { @@ -1151,8 +1149,7 @@ Variable* Scope::DeclareVariable( map->Lookup(const_cast<AstRawString*>(name), name->Hash()) != nullptr && !IsAsyncFunction(function_kind) && - !(allow_harmony_restrictive_generators && - IsGeneratorFunction(function_kind)); + !IsGeneratorFunction(function_kind); } if (duplicate_allowed) { *sloppy_mode_block_scope_function_redefinition = true; @@ -1391,7 +1388,7 @@ bool DeclarationScope::AllowsLazyCompilation() const { int Scope::ContextChainLength(Scope* scope) const { int n = 0; for (const Scope* s = this; s != scope; s = s->outer_scope_) { - DCHECK(s != NULL); // scope must be in the scope chain + DCHECK_NOT_NULL(s); // scope must be in the scope chain if (s->NeedsContext()) n++; } return n; @@ -1446,16 +1443,6 @@ bool Scope::NeedsScopeInfo() const { return NeedsContext(); } -ModuleScope* Scope::GetModuleScope() { - Scope* scope = this; - DCHECK(!scope->is_script_scope()); - while (!scope->is_module_scope()) { - scope = scope->outer_scope(); - DCHECK_NOT_NULL(scope); - } - return scope->AsModuleScope(); -} - DeclarationScope* Scope::GetReceiverScope() { Scope* scope = this; while (!scope->is_script_scope() && @@ -1544,7 +1531,10 @@ void DeclarationScope::AnalyzePartially(AstNodeFactory* ast_node_factory) { DCHECK(!force_eager_compilation_); VariableProxy* unresolved = nullptr; - if (!outer_scope_->is_script_scope() || FLAG_preparser_scope_analysis) { + if (!outer_scope_->is_script_scope() || + (FLAG_preparser_scope_analysis && + produced_preparsed_scope_data_ != nullptr && + produced_preparsed_scope_data_->ContainsInnerFunctions())) { // Try to resolve unresolved variables for this Scope and migrate those // which cannot be resolved inside. It doesn't make sense to try to resolve // them in the outer Scopes here, because they are incomplete. @@ -1556,12 +1546,6 @@ void DeclarationScope::AnalyzePartially(AstNodeFactory* ast_node_factory) { unresolved = copy; } - // Clear arguments_ if unused. This is used as a signal for optimization. - if (arguments_ != nullptr && - !(MustAllocate(arguments_) && !has_arguments_parameter_)) { - arguments_ = nullptr; - } - // Migrate function_ to the right Zone. if (function_ != nullptr) { function_ = ast_node_factory->CopyVariable(function_); @@ -1982,8 +1966,8 @@ void UpdateNeedsHoleCheck(Variable* var, VariableProxy* proxy, Scope* scope) { } // We should always have valid source positions. - DCHECK(var->initializer_position() != kNoSourcePosition); - DCHECK(proxy->position() != kNoSourcePosition); + DCHECK_NE(var->initializer_position(), kNoSourcePosition); + DCHECK_NE(proxy->position(), kNoSourcePosition); if (var->scope()->is_nonlinear() || var->initializer_position() >= proxy->position()) { @@ -2026,7 +2010,7 @@ void Scope::ResolveVariablesRecursively(ParseInfo* info) { // unresolved references remaining, they just need to be resolved in outer // scopes. if (is_declaration_scope() && AsDeclarationScope()->was_lazily_parsed()) { - DCHECK(variables_.occupancy() == 0); + DCHECK_EQ(variables_.occupancy(), 0); for (VariableProxy* proxy = unresolved_; proxy != nullptr; proxy = proxy->next_unresolved()) { Variable* var = outer_scope()->LookupRecursive(proxy, nullptr); @@ -2251,8 +2235,10 @@ void DeclarationScope::AllocateLocals() { // allocated in the context, it must be the last slot in the context, // because of the current ScopeInfo implementation (see // ScopeInfo::ScopeInfo(FunctionScope* scope) constructor). - if (function_ != nullptr) { + if (function_ != nullptr && MustAllocate(function_)) { AllocateNonParameterLocal(function_); + } else { + function_ = nullptr; } DCHECK(!has_rest_ || !MustAllocate(rest_parameter()) || diff --git a/deps/v8/src/ast/scopes.h b/deps/v8/src/ast/scopes.h index fe15508027..bcfd2187df 100644 --- a/deps/v8/src/ast/scopes.h +++ b/deps/v8/src/ast/scopes.h @@ -173,7 +173,8 @@ class V8_EXPORT_PRIVATE Scope : public NON_EXPORTED_BASE(ZoneObject) { // --------------------------------------------------------------------------- // Declarations - // Lookup a variable in this scope. Returns the variable or NULL if not found. + // Lookup a variable in this scope. Returns the variable or nullptr if not + // found. Variable* LookupLocal(const AstRawString* name) { Variable* result = variables_.Lookup(name); if (result != nullptr || scope_info_.is_null()) return result; @@ -183,7 +184,7 @@ class V8_EXPORT_PRIVATE Scope : public NON_EXPORTED_BASE(ZoneObject) { Variable* LookupInScopeInfo(const AstRawString* name); // Lookup a variable in this scope or outer scopes. - // Returns the variable or NULL if not found. + // Returns the variable or nullptr if not found. Variable* Lookup(const AstRawString* name); // Declare a local variable in this scope. If the variable has been @@ -195,7 +196,6 @@ class V8_EXPORT_PRIVATE Scope : public NON_EXPORTED_BASE(ZoneObject) { Variable* DeclareVariable(Declaration* declaration, VariableMode mode, InitializationFlag init, - bool allow_harmony_restrictive_generators, bool* sloppy_mode_block_scope_function_redefinition, bool* ok); @@ -385,7 +385,9 @@ class V8_EXPORT_PRIVATE Scope : public NON_EXPORTED_BASE(ZoneObject) { ScopeType scope_type() const { return scope_type_; } // The language mode of this scope. - LanguageMode language_mode() const { return is_strict_ ? STRICT : SLOPPY; } + LanguageMode language_mode() const { + return is_strict_ ? LanguageMode::kStrict : LanguageMode::kSloppy; + } // inner_scope() and sibling() together implement the inner scope list of a // scope. Inner scope points to the an inner scope of the function, and @@ -393,7 +395,7 @@ class V8_EXPORT_PRIVATE Scope : public NON_EXPORTED_BASE(ZoneObject) { Scope* inner_scope() const { return inner_scope_; } Scope* sibling() const { return sibling_; } - // The scope immediately surrounding this scope, or NULL. + // The scope immediately surrounding this scope, or nullptr. Scope* outer_scope() const { return outer_scope_; } Variable* catch_variable() const { @@ -439,9 +441,6 @@ class V8_EXPORT_PRIVATE Scope : public NON_EXPORTED_BASE(ZoneObject) { // 'this' is bound, and what determines the function kind. DeclarationScope* GetReceiverScope(); - // Find the module scope, assuming there is one. - ModuleScope* GetModuleScope(); - // Find the innermost outer scope that needs a context. Scope* GetOuterScopeWithContext(); @@ -517,7 +516,7 @@ class V8_EXPORT_PRIVATE Scope : public NON_EXPORTED_BASE(ZoneObject) { Zone* zone_; // Scope tree. - Scope* outer_scope_; // the immediately enclosing outer scope, or NULL + Scope* outer_scope_; // the immediately enclosing outer scope, or nullptr Scope* inner_scope_; // an inner scope of this scope Scope* sibling_; // a sibling inner scope of the outer scope of this scope. @@ -564,7 +563,7 @@ class V8_EXPORT_PRIVATE Scope : public NON_EXPORTED_BASE(ZoneObject) { // Scope-specific information computed during parsing. // // The language mode of this scope. - STATIC_ASSERT(LANGUAGE_END == 2); + STATIC_ASSERT(LanguageModeSize == 2); bool is_strict_ : 1; // This scope or a nested catch scope or with scope contain an 'eval' call. At // the 'eval' call site this scope is the declaration scope. @@ -762,11 +761,8 @@ class V8_EXPORT_PRIVATE DeclarationScope : public Scope { Variable* new_target_var() { return new_target_; } // The variable holding the function literal for named function - // literals, or NULL. Only valid for function scopes. - Variable* function_var() const { - DCHECK(is_function_scope()); - return function_; - } + // literals, or nullptr. Only valid for function scopes. + Variable* function_var() const { return function_; } Variable* generator_object_var() const { DCHECK(is_function_scope() || is_module_scope()); @@ -813,7 +809,8 @@ class V8_EXPORT_PRIVATE DeclarationScope : public Scope { has_simple_parameters_ = false; } - // The local variable 'arguments' if we need to allocate it; NULL otherwise. + // The local variable 'arguments' if we need to allocate it; nullptr + // otherwise. Variable* arguments() const { DCHECK(!is_arrow_scope() || arguments_ == nullptr); return arguments_; diff --git a/deps/v8/src/ast/variables.h b/deps/v8/src/ast/variables.h index 09df57ad54..4d58c8fed9 100644 --- a/deps/v8/src/ast/variables.h +++ b/deps/v8/src/ast/variables.h @@ -43,7 +43,7 @@ class Variable final : public ZoneObject { // The source code for an eval() call may refer to a variable that is // in an outer scope about which we don't know anything (it may not - // be the script scope). scope() is NULL in that case. Currently the + // be the script scope). scope() is nullptr in that case. Currently the // scope is only used to follow the context chain length. Scope* scope() const { return scope_; } @@ -137,7 +137,7 @@ class Variable final : public ZoneObject { } Variable* local_if_not_shadowed() const { - DCHECK(mode() == DYNAMIC_LOCAL && local_if_not_shadowed_ != NULL); + DCHECK(mode() == DYNAMIC_LOCAL && local_if_not_shadowed_ != nullptr); return local_if_not_shadowed_; } |