aboutsummaryrefslogtreecommitdiff
path: root/deps/v8/src/ast
diff options
context:
space:
mode:
authorMichaël Zasso <targos@protonmail.com>2018-09-21 09:14:51 +0200
committerMichaël Zasso <targos@protonmail.com>2018-09-22 18:29:25 +0200
commit0e7ddbd3d7e9439c67573b854c49cf82c398ae82 (patch)
tree2afe372acde921cb57ddb3444ff00c5adef8848c /deps/v8/src/ast
parent13245dc50da4cb7443c39ef6c68d419d5e6336d4 (diff)
downloadandroid-node-v8-0e7ddbd3d7e9439c67573b854c49cf82c398ae82.tar.gz
android-node-v8-0e7ddbd3d7e9439c67573b854c49cf82c398ae82.tar.bz2
android-node-v8-0e7ddbd3d7e9439c67573b854c49cf82c398ae82.zip
deps: update V8 to 7.0.276.20
PR-URL: https://github.com/nodejs/node/pull/22754 Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Refael Ackermann <refack@gmail.com> Reviewed-By: Ali Ijaz Sheikh <ofrobots@google.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Diffstat (limited to 'deps/v8/src/ast')
-rw-r--r--deps/v8/src/ast/ast-value-factory.cc1
-rw-r--r--deps/v8/src/ast/ast.h103
-rw-r--r--deps/v8/src/ast/prettyprinter.cc31
-rw-r--r--deps/v8/src/ast/prettyprinter.h10
-rw-r--r--deps/v8/src/ast/scopes.cc25
-rw-r--r--deps/v8/src/ast/scopes.h10
6 files changed, 127 insertions, 53 deletions
diff --git a/deps/v8/src/ast/ast-value-factory.cc b/deps/v8/src/ast/ast-value-factory.cc
index fc8be819f6..8cf81b24a5 100644
--- a/deps/v8/src/ast/ast-value-factory.cc
+++ b/deps/v8/src/ast/ast-value-factory.cc
@@ -27,7 +27,6 @@
#include "src/ast/ast-value-factory.h"
-#include "src/api.h"
#include "src/char-predicates-inl.h"
#include "src/objects-inl.h"
#include "src/objects.h"
diff --git a/deps/v8/src/ast/ast.h b/deps/v8/src/ast/ast.h
index 5a2346ad9f..6c1e989d30 100644
--- a/deps/v8/src/ast/ast.h
+++ b/deps/v8/src/ast/ast.h
@@ -249,7 +249,23 @@ class Expression : public AstNode {
static const uint8_t kNextBitFieldIndex = AstNode::kNextBitFieldIndex;
};
-
+// V8's notion of BreakableStatement does not correspond to the notion of
+// BreakableStatement in ECMAScript. In V8, the idea is that a
+// BreakableStatement is a statement that can be the target of a break
+// statement. The BreakableStatement AST node carries a list of labels, any of
+// which can be used as an argument to the break statement in order to target
+// it.
+//
+// Since we don't want to attach a list of labels to all kinds of statements, we
+// only declare switchs, loops, and blocks as BreakableStatements. This means
+// that we implement breaks targeting other statement forms as breaks targeting
+// a substatement thereof. For instance, in "foo: if (b) { f(); break foo; }" we
+// pretend that foo is the label of the inner block. That's okay because one
+// can't observe the difference.
+//
+// This optimization makes it harder to detect invalid continue labels, see the
+// need for own_labels in IterationStatement.
+//
class BreakableStatement : public Statement {
public:
enum BreakableType {
@@ -257,6 +273,13 @@ class BreakableStatement : public Statement {
TARGET_FOR_NAMED_ONLY
};
+ // A list of all labels declared on the path up to the previous
+ // BreakableStatement (if any).
+ //
+ // Example: "l1: for (;;) l2: l3: { l4: if (b) l5: { s } }"
+ // labels() of the ForStatement will be l1.
+ // labels() of the Block { l4: ... } will be l2, l3.
+ // labels() of the Block { s } will be l4, l5.
ZonePtrList<const AstRawString>* labels() const;
// Testers.
@@ -441,11 +464,23 @@ class IterationStatement : public BreakableStatement {
ZonePtrList<const AstRawString>* labels() const { return labels_; }
+ // A list of all labels that the iteration statement is directly prefixed
+ // with, i.e. all the labels that a continue statement in the body can use to
+ // continue this iteration statement. This is always a subset of {labels}.
+ //
+ // Example: "l1: { l2: if (b) l3: l4: for (;;) s }"
+ // labels() of the Block will be l1.
+ // labels() of the ForStatement will be l2, l3, l4.
+ // own_labels() of the ForStatement will be l3, l4.
+ ZonePtrList<const AstRawString>* own_labels() const { return own_labels_; }
+
protected:
- IterationStatement(ZonePtrList<const AstRawString>* labels, int pos,
+ IterationStatement(ZonePtrList<const AstRawString>* labels,
+ ZonePtrList<const AstRawString>* own_labels, int pos,
NodeType type)
: BreakableStatement(TARGET_FOR_ANONYMOUS, pos, type),
labels_(labels),
+ own_labels_(own_labels),
body_(nullptr) {}
void Initialize(Statement* body) { body_ = body; }
@@ -454,6 +489,7 @@ class IterationStatement : public BreakableStatement {
private:
ZonePtrList<const AstRawString>* labels_;
+ ZonePtrList<const AstRawString>* own_labels_;
Statement* body_;
};
@@ -470,8 +506,10 @@ class DoWhileStatement final : public IterationStatement {
private:
friend class AstNodeFactory;
- DoWhileStatement(ZonePtrList<const AstRawString>* labels, int pos)
- : IterationStatement(labels, pos, kDoWhileStatement), cond_(nullptr) {}
+ DoWhileStatement(ZonePtrList<const AstRawString>* labels,
+ ZonePtrList<const AstRawString>* own_labels, int pos)
+ : IterationStatement(labels, own_labels, pos, kDoWhileStatement),
+ cond_(nullptr) {}
Expression* cond_;
};
@@ -489,8 +527,10 @@ class WhileStatement final : public IterationStatement {
private:
friend class AstNodeFactory;
- WhileStatement(ZonePtrList<const AstRawString>* labels, int pos)
- : IterationStatement(labels, pos, kWhileStatement), cond_(nullptr) {}
+ WhileStatement(ZonePtrList<const AstRawString>* labels,
+ ZonePtrList<const AstRawString>* own_labels, int pos)
+ : IterationStatement(labels, own_labels, pos, kWhileStatement),
+ cond_(nullptr) {}
Expression* cond_;
};
@@ -513,8 +553,9 @@ class ForStatement final : public IterationStatement {
private:
friend class AstNodeFactory;
- ForStatement(ZonePtrList<const AstRawString>* labels, int pos)
- : IterationStatement(labels, pos, kForStatement),
+ ForStatement(ZonePtrList<const AstRawString>* labels,
+ ZonePtrList<const AstRawString>* own_labels, int pos)
+ : IterationStatement(labels, own_labels, pos, kForStatement),
init_(nullptr),
cond_(nullptr),
next_(nullptr) {}
@@ -539,9 +580,10 @@ class ForEachStatement : public IterationStatement {
}
protected:
- ForEachStatement(ZonePtrList<const AstRawString>* labels, int pos,
+ ForEachStatement(ZonePtrList<const AstRawString>* labels,
+ ZonePtrList<const AstRawString>* own_labels, int pos,
NodeType type)
- : IterationStatement(labels, pos, type) {}
+ : IterationStatement(labels, own_labels, pos, type) {}
};
@@ -566,8 +608,9 @@ class ForInStatement final : public ForEachStatement {
private:
friend class AstNodeFactory;
- ForInStatement(ZonePtrList<const AstRawString>* labels, int pos)
- : ForEachStatement(labels, pos, kForInStatement),
+ ForInStatement(ZonePtrList<const AstRawString>* labels,
+ ZonePtrList<const AstRawString>* own_labels, int pos)
+ : ForEachStatement(labels, own_labels, pos, kForInStatement),
each_(nullptr),
subject_(nullptr) {
bit_field_ = ForInTypeField::update(bit_field_, SLOW_FOR_IN);
@@ -632,8 +675,9 @@ class ForOfStatement final : public ForEachStatement {
private:
friend class AstNodeFactory;
- ForOfStatement(ZonePtrList<const AstRawString>* labels, int pos)
- : ForEachStatement(labels, pos, kForOfStatement),
+ ForOfStatement(ZonePtrList<const AstRawString>* labels,
+ ZonePtrList<const AstRawString>* own_labels, int pos)
+ : ForEachStatement(labels, own_labels, pos, kForOfStatement),
iterator_(nullptr),
assign_iterator_(nullptr),
next_result_(nullptr),
@@ -2201,6 +2245,12 @@ class FunctionLiteral final : public Expression {
bool is_anonymous_expression() const {
return function_type() == kAnonymousExpression;
}
+
+ void mark_as_iife() { bit_field_ = IIFEBit::update(bit_field_, true); }
+ bool is_iife() const { return IIFEBit::decode(bit_field_); }
+ bool is_top_level() const {
+ return function_literal_id() == FunctionLiteral::kIdTypeTopLevel;
+ }
bool is_wrapped() const { return function_type() == kWrapped; }
LanguageMode language_mode() const;
@@ -2333,7 +2383,7 @@ class FunctionLiteral final : public Expression {
kHasDuplicateParameters) |
DontOptimizeReasonField::encode(BailoutReason::kNoReason) |
RequiresInstanceFieldsInitializer::encode(false) |
- HasBracesField::encode(has_braces);
+ HasBracesField::encode(has_braces) | IIFEBit::encode(false);
if (eager_compile_hint == kShouldEagerCompile) SetShouldEagerCompile();
DCHECK_EQ(body == nullptr, expected_property_count < 0);
}
@@ -2348,6 +2398,7 @@ class FunctionLiteral final : public Expression {
: public BitField<bool, DontOptimizeReasonField::kNext, 1> {};
class HasBracesField
: public BitField<bool, RequiresInstanceFieldsInitializer::kNext, 1> {};
+ class IIFEBit : public BitField<bool, HasBracesField::kNext, 1> {};
int expected_property_count_;
int parameter_count_;
@@ -2803,9 +2854,11 @@ class AstNodeFactory final BASE_EMBEDDED {
Block(zone_, labels, capacity, ignore_completion_value);
}
-#define STATEMENT_WITH_LABELS(NodeType) \
- NodeType* New##NodeType(ZonePtrList<const AstRawString>* labels, int pos) { \
- return new (zone_) NodeType(labels, pos); \
+#define STATEMENT_WITH_LABELS(NodeType) \
+ NodeType* New##NodeType(ZonePtrList<const AstRawString>* labels, \
+ ZonePtrList<const AstRawString>* own_labels, \
+ int pos) { \
+ return new (zone_) NodeType(labels, own_labels, pos); \
}
STATEMENT_WITH_LABELS(DoWhileStatement)
STATEMENT_WITH_LABELS(WhileStatement)
@@ -2817,23 +2870,25 @@ class AstNodeFactory final BASE_EMBEDDED {
return new (zone_) SwitchStatement(zone_, labels, tag, pos);
}
- ForEachStatement* NewForEachStatement(ForEachStatement::VisitMode visit_mode,
- ZonePtrList<const AstRawString>* labels,
- int pos) {
+ ForEachStatement* NewForEachStatement(
+ ForEachStatement::VisitMode visit_mode,
+ ZonePtrList<const AstRawString>* labels,
+ ZonePtrList<const AstRawString>* own_labels, int pos) {
switch (visit_mode) {
case ForEachStatement::ENUMERATE: {
- return new (zone_) ForInStatement(labels, pos);
+ return new (zone_) ForInStatement(labels, own_labels, pos);
}
case ForEachStatement::ITERATE: {
- return new (zone_) ForOfStatement(labels, pos);
+ return new (zone_) ForOfStatement(labels, own_labels, pos);
}
}
UNREACHABLE();
}
ForOfStatement* NewForOfStatement(ZonePtrList<const AstRawString>* labels,
+ ZonePtrList<const AstRawString>* own_labels,
int pos) {
- return new (zone_) ForOfStatement(labels, pos);
+ return new (zone_) ForOfStatement(labels, own_labels, pos);
}
ExpressionStatement* NewExpressionStatement(Expression* expression, int pos) {
diff --git a/deps/v8/src/ast/prettyprinter.cc b/deps/v8/src/ast/prettyprinter.cc
index ef086bcefc..d2e56a9335 100644
--- a/deps/v8/src/ast/prettyprinter.cc
+++ b/deps/v8/src/ast/prettyprinter.cc
@@ -11,12 +11,13 @@
#include "src/base/platform/platform.h"
#include "src/globals.h"
#include "src/objects-inl.h"
+#include "src/string-builder-inl.h"
namespace v8 {
namespace internal {
CallPrinter::CallPrinter(Isolate* isolate, bool is_user_js)
- : builder_(isolate) {
+ : builder_(new IncrementalStringBuilder(isolate)) {
isolate_ = isolate;
position_ = 0;
num_prints_ = 0;
@@ -30,6 +31,8 @@ CallPrinter::CallPrinter(Isolate* isolate, bool is_user_js)
InitializeAstVisitor(isolate);
}
+CallPrinter::~CallPrinter() {}
+
CallPrinter::ErrorHint CallPrinter::GetErrorHint() const {
if (is_call_error_) {
if (is_iterator_error_) return ErrorHint::kCallAndNormalIterator;
@@ -45,7 +48,7 @@ Handle<String> CallPrinter::Print(FunctionLiteral* program, int position) {
num_prints_ = 0;
position_ = position;
Find(program);
- return builder_.Finish().ToHandleChecked();
+ return builder_->Finish().ToHandleChecked();
}
@@ -65,13 +68,13 @@ void CallPrinter::Find(AstNode* node, bool print) {
void CallPrinter::Print(const char* str) {
if (!found_ || done_) return;
num_prints_++;
- builder_.AppendCString(str);
+ builder_->AppendCString(str);
}
void CallPrinter::Print(Handle<String> str) {
if (!found_ || done_) return;
num_prints_++;
- builder_.AppendString(str);
+ builder_->AppendString(str);
}
void CallPrinter::VisitBlock(Block* node) {
@@ -746,17 +749,21 @@ void AstPrinter::PrintLiteralWithModeIndented(const char* info, Variable* var,
}
}
-void AstPrinter::PrintLabelsIndented(ZonePtrList<const AstRawString>* labels) {
+void AstPrinter::PrintLabelsIndented(ZonePtrList<const AstRawString>* labels,
+ const char* prefix) {
if (labels == nullptr || labels->length() == 0) return;
- PrintIndented("LABELS ");
+ PrintIndented(prefix);
+ Print("LABELS ");
PrintLabels(labels);
Print("\n");
}
void AstPrinter::PrintIndentedVisit(const char* s, AstNode* node) {
- IndentedScope indent(this, s, node->position());
- Visit(node);
+ if (node != nullptr) {
+ IndentedScope indent(this, s, node->position());
+ Visit(node);
+ }
}
@@ -823,6 +830,7 @@ void AstPrinter::VisitBlock(Block* node) {
const char* block_txt =
node->ignore_completion_value() ? "BLOCK NOCOMPLETIONS" : "BLOCK";
IndentedScope indent(this, block_txt, node->position());
+ PrintLabelsIndented(node->labels());
PrintStatements(node->statements());
}
@@ -916,6 +924,7 @@ void AstPrinter::VisitSwitchStatement(SwitchStatement* node) {
void AstPrinter::VisitDoWhileStatement(DoWhileStatement* node) {
IndentedScope indent(this, "DO", node->position());
PrintLabelsIndented(node->labels());
+ PrintLabelsIndented(node->own_labels(), "OWN ");
PrintIndentedVisit("BODY", node->body());
PrintIndentedVisit("COND", node->cond());
}
@@ -924,6 +933,7 @@ void AstPrinter::VisitDoWhileStatement(DoWhileStatement* node) {
void AstPrinter::VisitWhileStatement(WhileStatement* node) {
IndentedScope indent(this, "WHILE", node->position());
PrintLabelsIndented(node->labels());
+ PrintLabelsIndented(node->own_labels(), "OWN ");
PrintIndentedVisit("COND", node->cond());
PrintIndentedVisit("BODY", node->body());
}
@@ -932,6 +942,7 @@ void AstPrinter::VisitWhileStatement(WhileStatement* node) {
void AstPrinter::VisitForStatement(ForStatement* node) {
IndentedScope indent(this, "FOR", node->position());
PrintLabelsIndented(node->labels());
+ PrintLabelsIndented(node->own_labels(), "OWN ");
if (node->init()) PrintIndentedVisit("INIT", node->init());
if (node->cond()) PrintIndentedVisit("COND", node->cond());
PrintIndentedVisit("BODY", node->body());
@@ -941,6 +952,8 @@ void AstPrinter::VisitForStatement(ForStatement* node) {
void AstPrinter::VisitForInStatement(ForInStatement* node) {
IndentedScope indent(this, "FOR IN", node->position());
+ PrintLabelsIndented(node->labels());
+ PrintLabelsIndented(node->own_labels(), "OWN ");
PrintIndentedVisit("FOR", node->each());
PrintIndentedVisit("IN", node->enumerable());
PrintIndentedVisit("BODY", node->body());
@@ -949,6 +962,8 @@ void AstPrinter::VisitForInStatement(ForInStatement* node) {
void AstPrinter::VisitForOfStatement(ForOfStatement* node) {
IndentedScope indent(this, "FOR OF", node->position());
+ PrintLabelsIndented(node->labels());
+ PrintLabelsIndented(node->own_labels(), "OWN ");
PrintIndentedVisit("INIT", node->assign_iterator());
PrintIndentedVisit("NEXT", node->next_result());
PrintIndentedVisit("DONE", node->result_done());
diff --git a/deps/v8/src/ast/prettyprinter.h b/deps/v8/src/ast/prettyprinter.h
index cc29052c2d..71019fe264 100644
--- a/deps/v8/src/ast/prettyprinter.h
+++ b/deps/v8/src/ast/prettyprinter.h
@@ -8,14 +8,16 @@
#include "src/allocation.h"
#include "src/ast/ast.h"
#include "src/base/compiler-specific.h"
-#include "src/string-builder.h"
namespace v8 {
namespace internal {
+class IncrementalStringBuilder; // to avoid including string-builder-inl.h
+
class CallPrinter final : public AstVisitor<CallPrinter> {
public:
explicit CallPrinter(Isolate* isolate, bool is_user_js);
+ ~CallPrinter();
// The following routine prints the node with position |position| into a
// string.
@@ -42,7 +44,8 @@ class CallPrinter final : public AstVisitor<CallPrinter> {
Isolate* isolate_;
int num_prints_;
- IncrementalStringBuilder builder_;
+ // Allocate the builder on the heap simply because it's forward declared.
+ std::unique_ptr<IncrementalStringBuilder> builder_;
int position_; // position of ast node to print
bool found_;
bool done_;
@@ -107,7 +110,8 @@ class AstPrinter final : public AstVisitor<AstPrinter> {
bool quote);
void PrintLiteralWithModeIndented(const char* info, Variable* var,
const AstRawString* value);
- void PrintLabelsIndented(ZonePtrList<const AstRawString>* labels);
+ void PrintLabelsIndented(ZonePtrList<const AstRawString>* labels,
+ const char* prefix = "");
void PrintObjectProperties(ZonePtrList<ObjectLiteral::Property>* properties);
void PrintClassProperties(ZonePtrList<ClassLiteral::Property>* properties);
diff --git a/deps/v8/src/ast/scopes.cc b/deps/v8/src/ast/scopes.cc
index 18db88f950..74d50c44de 100644
--- a/deps/v8/src/ast/scopes.cc
+++ b/deps/v8/src/ast/scopes.cc
@@ -2178,25 +2178,16 @@ void Scope::AllocateHeapSlot(Variable* var) {
void DeclarationScope::AllocateParameterLocals() {
DCHECK(is_function_scope());
- bool uses_sloppy_arguments = false;
-
+ bool has_mapped_arguments = false;
if (arguments_ != nullptr) {
DCHECK(!is_arrow_scope());
- // 'arguments' is used. Unless there is also a parameter called
- // 'arguments', we must be conservative and allocate all parameters to
- // the context assuming they will be captured by the arguments object.
- // If we have a parameter named 'arguments', a (new) value is always
- // assigned to it via the function invocation. Then 'arguments' denotes
- // that specific parameter value and cannot be used to access the
- // parameters, which is why we don't need to allocate an arguments
- // object in that case.
if (MustAllocate(arguments_) && !has_arguments_parameter_) {
- // In strict mode 'arguments' does not alias formal parameters.
- // Therefore in strict mode we allocate parameters as if 'arguments'
- // were not used.
- // If the parameter list is not simple, arguments isn't sloppy either.
- uses_sloppy_arguments =
- is_sloppy(language_mode()) && has_simple_parameters();
+ // 'arguments' is used and does not refer to a function
+ // parameter of the same name. If the arguments object
+ // aliases formal parameters, we conservatively allocate
+ // them specially in the loop below.
+ has_mapped_arguments =
+ GetArgumentsType() == CreateArgumentsType::kMappedArguments;
} else {
// 'arguments' is unused. Tell the code generator that it does not need to
// allocate the arguments object by nulling out arguments_.
@@ -2212,7 +2203,7 @@ void DeclarationScope::AllocateParameterLocals() {
Variable* var = params_[i];
DCHECK(!has_rest_ || var != rest_parameter());
DCHECK_EQ(this, var->scope());
- if (uses_sloppy_arguments) {
+ if (has_mapped_arguments) {
var->set_is_used();
var->set_maybe_assigned();
var->ForceContextAllocation();
diff --git a/deps/v8/src/ast/scopes.h b/deps/v8/src/ast/scopes.h
index 5618adee9e..f43761af58 100644
--- a/deps/v8/src/ast/scopes.h
+++ b/deps/v8/src/ast/scopes.h
@@ -804,6 +804,16 @@ class V8_EXPORT_PRIVATE DeclarationScope : public Scope {
has_simple_parameters_ = false;
}
+ // Returns whether the arguments object aliases formal parameters.
+ CreateArgumentsType GetArgumentsType() const {
+ DCHECK(is_function_scope());
+ DCHECK(!is_arrow_scope());
+ DCHECK_NOT_NULL(arguments_);
+ return is_sloppy(language_mode()) && has_simple_parameters()
+ ? CreateArgumentsType::kMappedArguments
+ : CreateArgumentsType::kUnmappedArguments;
+ }
+
// The local variable 'arguments' if we need to allocate it; nullptr
// otherwise.
Variable* arguments() const {