aboutsummaryrefslogtreecommitdiff
path: root/deps/v8/src/ast
diff options
context:
space:
mode:
authorMichaël Zasso <targos@protonmail.com>2017-06-06 10:28:14 +0200
committerMichaël Zasso <targos@protonmail.com>2017-06-07 10:33:31 +0200
commit3dc8c3bed4cf3a77607edbb0b015e33f8b60fc09 (patch)
tree9dee56e142638b34f1eccbd0ad88c3bce5377c29 /deps/v8/src/ast
parent91a1bbe3055a660194ca4d403795aa0c03e9d056 (diff)
downloadandroid-node-v8-3dc8c3bed4cf3a77607edbb0b015e33f8b60fc09.tar.gz
android-node-v8-3dc8c3bed4cf3a77607edbb0b015e33f8b60fc09.tar.bz2
android-node-v8-3dc8c3bed4cf3a77607edbb0b015e33f8b60fc09.zip
deps: update V8 to 5.9.211.32
PR-URL: https://github.com/nodejs/node/pull/13263 Reviewed-By: Gibson Fahnestock <gibfahn@gmail.com> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: Franziska Hinkelmann <franziska.hinkelmann@gmail.com> Reviewed-By: Myles Borins <myles.borins@gmail.com>
Diffstat (limited to 'deps/v8/src/ast')
-rw-r--r--deps/v8/src/ast/ast-expression-rewriter.cc9
-rw-r--r--deps/v8/src/ast/ast-numbering.cc75
-rw-r--r--deps/v8/src/ast/ast-numbering.h30
-rw-r--r--deps/v8/src/ast/ast-traversal-visitor.h9
-rw-r--r--deps/v8/src/ast/ast-types.cc4
-rw-r--r--deps/v8/src/ast/ast-value-factory.cc86
-rw-r--r--deps/v8/src/ast/ast-value-factory.h211
-rw-r--r--deps/v8/src/ast/ast.cc68
-rw-r--r--deps/v8/src/ast/ast.h175
-rw-r--r--deps/v8/src/ast/context-slot-cache.h2
-rw-r--r--deps/v8/src/ast/modules.h3
-rw-r--r--deps/v8/src/ast/prettyprinter.cc73
-rw-r--r--deps/v8/src/ast/scopes.cc264
-rw-r--r--deps/v8/src/ast/scopes.h77
-rw-r--r--deps/v8/src/ast/variables.h6
15 files changed, 691 insertions, 401 deletions
diff --git a/deps/v8/src/ast/ast-expression-rewriter.cc b/deps/v8/src/ast/ast-expression-rewriter.cc
index f46e21b410..d23612f2b4 100644
--- a/deps/v8/src/ast/ast-expression-rewriter.cc
+++ b/deps/v8/src/ast/ast-expression-rewriter.cc
@@ -265,8 +265,7 @@ void AstExpressionRewriter::VisitAssignment(Assignment* node) {
AST_REWRITE_PROPERTY(Expression, node, value);
}
-
-void AstExpressionRewriter::VisitYield(Yield* node) {
+void AstExpressionRewriter::VisitSuspend(Suspend* node) {
REWRITE_THIS(node);
AST_REWRITE_PROPERTY(Expression, node, generator_object);
AST_REWRITE_PROPERTY(Expression, node, expression);
@@ -377,6 +376,12 @@ void AstExpressionRewriter::VisitGetIterator(GetIterator* node) {
AST_REWRITE_PROPERTY(Expression, node, iterable);
}
+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);
diff --git a/deps/v8/src/ast/ast-numbering.cc b/deps/v8/src/ast/ast-numbering.cc
index 499760de14..24ccf79244 100644
--- a/deps/v8/src/ast/ast-numbering.cc
+++ b/deps/v8/src/ast/ast-numbering.cc
@@ -15,17 +15,19 @@ namespace internal {
class AstNumberingVisitor final : public AstVisitor<AstNumberingVisitor> {
public:
AstNumberingVisitor(uintptr_t stack_limit, Zone* zone,
- Compiler::EagerInnerFunctionLiterals* eager_literals)
+ Compiler::EagerInnerFunctionLiterals* eager_literals,
+ bool collect_type_profile = false)
: zone_(zone),
eager_literals_(eager_literals),
next_id_(BailoutId::FirstUsable().ToInt()),
- yield_count_(0),
+ suspend_count_(0),
properties_(zone),
language_mode_(SLOPPY),
slot_cache_(zone),
disable_crankshaft_reason_(kNoReason),
dont_optimize_reason_(kNoReason),
- catch_prediction_(HandlerTable::UNCAUGHT) {
+ catch_prediction_(HandlerTable::UNCAUGHT),
+ collect_type_profile_(collect_type_profile) {
InitializeAstVisitor(stack_limit);
}
@@ -93,7 +95,7 @@ class AstNumberingVisitor final : public AstVisitor<AstNumberingVisitor> {
Zone* zone_;
Compiler::EagerInnerFunctionLiterals* eager_literals_;
int next_id_;
- int yield_count_;
+ int suspend_count_;
AstProperties properties_;
LanguageMode language_mode_;
// The slot cache allows us to reuse certain feedback slots.
@@ -101,6 +103,7 @@ class AstNumberingVisitor final : public AstVisitor<AstNumberingVisitor> {
BailoutReason disable_crankshaft_reason_;
BailoutReason dont_optimize_reason_;
HandlerTable::CatchPrediction catch_prediction_;
+ bool collect_type_profile_;
DEFINE_AST_VISITOR_SUBCLASS_MEMBERS();
DISALLOW_COPY_AND_ASSIGN(AstNumberingVisitor);
@@ -238,12 +241,11 @@ void AstNumberingVisitor::VisitReturnStatement(ReturnStatement* node) {
properties_.flags() & AstProperties::kMustUseIgnitionTurbo);
}
-
-void AstNumberingVisitor::VisitYield(Yield* node) {
- node->set_yield_id(yield_count_);
- yield_count_++;
+void AstNumberingVisitor::VisitSuspend(Suspend* node) {
+ node->set_suspend_id(suspend_count_);
+ suspend_count_++;
IncrementNodeCount();
- node->set_base_id(ReserveIdRange(Yield::num_ids()));
+ node->set_base_id(ReserveIdRange(Suspend::num_ids()));
Visit(node->generator_object());
Visit(node->expression());
}
@@ -322,10 +324,17 @@ void AstNumberingVisitor::VisitCallRuntime(CallRuntime* node) {
// has to stash it somewhere. Changing the runtime function into another
// one in ast-numbering seemed like a simple and straightforward solution to
// that problem.
- if (node->is_jsruntime() &&
- node->context_index() == Context::ASYNC_FUNCTION_AWAIT_CAUGHT_INDEX &&
- catch_prediction_ == HandlerTable::ASYNC_AWAIT) {
- node->set_context_index(Context::ASYNC_FUNCTION_AWAIT_UNCAUGHT_INDEX);
+ if (node->is_jsruntime() && catch_prediction_ == HandlerTable::ASYNC_AWAIT) {
+ switch (node->context_index()) {
+ case Context::ASYNC_FUNCTION_AWAIT_CAUGHT_INDEX:
+ node->set_context_index(Context::ASYNC_FUNCTION_AWAIT_UNCAUGHT_INDEX);
+ break;
+ case Context::ASYNC_GENERATOR_AWAIT_CAUGHT:
+ node->set_context_index(Context::ASYNC_GENERATOR_AWAIT_UNCAUGHT);
+ break;
+ default:
+ break;
+ }
}
}
@@ -342,10 +351,10 @@ void AstNumberingVisitor::VisitDoWhileStatement(DoWhileStatement* node) {
IncrementNodeCount();
DisableSelfOptimization();
node->set_base_id(ReserveIdRange(DoWhileStatement::num_ids()));
- node->set_first_yield_id(yield_count_);
+ node->set_first_suspend_id(suspend_count_);
Visit(node->body());
Visit(node->cond());
- node->set_yield_count(yield_count_ - node->first_yield_id());
+ node->set_suspend_count(suspend_count_ - node->first_suspend_id());
}
@@ -353,10 +362,10 @@ void AstNumberingVisitor::VisitWhileStatement(WhileStatement* node) {
IncrementNodeCount();
DisableSelfOptimization();
node->set_base_id(ReserveIdRange(WhileStatement::num_ids()));
- node->set_first_yield_id(yield_count_);
+ node->set_first_suspend_id(suspend_count_);
Visit(node->cond());
Visit(node->body());
- node->set_yield_count(yield_count_ - node->first_yield_id());
+ node->set_suspend_count(suspend_count_ - node->first_suspend_id());
}
@@ -463,15 +472,22 @@ void AstNumberingVisitor::VisitGetIterator(GetIterator* node) {
ReserveFeedbackSlots(node);
}
+void AstNumberingVisitor::VisitImportCallExpression(
+ ImportCallExpression* node) {
+ IncrementNodeCount();
+ DisableFullCodegenAndCrankshaft(kDynamicImport);
+ Visit(node->argument());
+}
+
void AstNumberingVisitor::VisitForInStatement(ForInStatement* node) {
IncrementNodeCount();
DisableSelfOptimization();
node->set_base_id(ReserveIdRange(ForInStatement::num_ids()));
Visit(node->enumerable()); // Not part of loop.
- node->set_first_yield_id(yield_count_);
+ node->set_first_suspend_id(suspend_count_);
Visit(node->each());
Visit(node->body());
- node->set_yield_count(yield_count_ - node->first_yield_id());
+ node->set_suspend_count(suspend_count_ - node->first_suspend_id());
ReserveFeedbackSlots(node);
}
@@ -481,12 +497,12 @@ void AstNumberingVisitor::VisitForOfStatement(ForOfStatement* node) {
DisableFullCodegenAndCrankshaft(kForOfStatement);
node->set_base_id(ReserveIdRange(ForOfStatement::num_ids()));
Visit(node->assign_iterator()); // Not part of loop.
- node->set_first_yield_id(yield_count_);
+ node->set_first_suspend_id(suspend_count_);
Visit(node->next_result());
Visit(node->result_done());
Visit(node->assign_each());
Visit(node->body());
- node->set_yield_count(yield_count_ - node->first_yield_id());
+ node->set_suspend_count(suspend_count_ - node->first_suspend_id());
}
@@ -535,11 +551,11 @@ void AstNumberingVisitor::VisitForStatement(ForStatement* node) {
DisableSelfOptimization();
node->set_base_id(ReserveIdRange(ForStatement::num_ids()));
if (node->init() != NULL) Visit(node->init()); // Not part of loop.
- node->set_first_yield_id(yield_count_);
+ node->set_first_suspend_id(suspend_count_);
if (node->cond() != NULL) Visit(node->cond());
if (node->next() != NULL) Visit(node->next());
Visit(node->body());
- node->set_yield_count(yield_count_ - node->first_yield_id());
+ node->set_suspend_count(suspend_count_ - node->first_suspend_id());
}
@@ -616,6 +632,7 @@ void AstNumberingVisitor::VisitStatements(ZoneList<Statement*>* statements) {
if (statements == NULL) return;
for (int i = 0; i < statements->length(); i++) {
Visit(statements->at(i));
+ if (statements->at(i)->IsJump()) break;
}
}
@@ -687,12 +704,16 @@ bool AstNumberingVisitor::Renumber(FunctionLiteral* node) {
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_yield_count(yield_count_);
+ node->set_suspend_count(suspend_count_);
if (FLAG_trace_opt) {
if (disable_crankshaft_reason_ != kNoReason) {
@@ -714,12 +735,14 @@ bool AstNumberingVisitor::Renumber(FunctionLiteral* node) {
bool AstNumbering::Renumber(
uintptr_t stack_limit, Zone* zone, FunctionLiteral* function,
- Compiler::EagerInnerFunctionLiterals* eager_literals) {
+ Compiler::EagerInnerFunctionLiterals* eager_literals,
+ bool collect_type_profile) {
DisallowHeapAllocation no_allocation;
DisallowHandleAllocation no_handles;
DisallowHandleDereference no_deref;
- AstNumberingVisitor visitor(stack_limit, zone, eager_literals);
+ AstNumberingVisitor visitor(stack_limit, zone, eager_literals,
+ collect_type_profile);
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 bea441d67b..82987ef593 100644
--- a/deps/v8/src/ast/ast-numbering.h
+++ b/deps/v8/src/ast/ast-numbering.h
@@ -22,29 +22,33 @@ template <typename T>
class ZoneVector;
namespace AstNumbering {
-// Assign type feedback IDs, bailout IDs, and generator yield IDs to an AST node
-// tree; perform catch prediction for TryStatements. If |eager_literals| is
+// 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.
bool Renumber(
uintptr_t stack_limit, Zone* zone, FunctionLiteral* function,
- ThreadedList<ThreadedListZoneEntry<FunctionLiteral*>>* eager_literals);
+ ThreadedList<ThreadedListZoneEntry<FunctionLiteral*>>* eager_literals,
+ bool collect_type_profile = false);
}
-// Some details on yield IDs
+// Some details on suspend IDs
// -------------------------
//
// In order to assist Ignition in generating bytecode for a generator function,
-// we assign a unique number (the yield ID) to each Yield node in its AST. We
-// also annotate loops with the number of yields they contain (loop.yield_count)
-// and the smallest ID of those (loop.first_yield_id), and we annotate the
-// function itself with the number of yields it contains (function.yield_count).
+// we assign a unique number (the suspend ID) to each Suspend node in its AST.
+// We also annotate loops with the number of suspends they contain
+// (loop.suspend_count) and the smallest ID of those (loop.first_suspend_id),
+// and we annotate the function itself with the number of suspends it contains
+// (function.suspend_count).
//
-// The way in which we choose the IDs is simply by enumerating the Yield nodes.
+// The way in which we choose the IDs is simply by enumerating the Suspend
+// nodes.
// Ignition relies on the following properties:
-// - For each loop l and each yield y of l:
-// l.first_yield_id <= y.yield_id < l.first_yield_id + l.yield_count
-// - For the generator function f itself and each yield y of f:
-// 0 <= y.yield_id < f.yield_count
+// - For each loop l and each suspend y of l:
+// l.first_suspend_id <=
+// s.suspend_id < l.first_suspend_id + l.suspend_count
+// - For the generator function f itself and each suspend s of f:
+// 0 <= s.suspend_id < f.suspend_count
} // namespace internal
} // namespace v8
diff --git a/deps/v8/src/ast/ast-traversal-visitor.h b/deps/v8/src/ast/ast-traversal-visitor.h
index 6d0c386f3b..390ba6db3a 100644
--- a/deps/v8/src/ast/ast-traversal-visitor.h
+++ b/deps/v8/src/ast/ast-traversal-visitor.h
@@ -357,7 +357,7 @@ void AstTraversalVisitor<Subclass>::VisitAssignment(Assignment* expr) {
}
template <class Subclass>
-void AstTraversalVisitor<Subclass>::VisitYield(Yield* expr) {
+void AstTraversalVisitor<Subclass>::VisitSuspend(Suspend* expr) {
PROCESS_EXPRESSION(expr);
RECURSE_EXPRESSION(Visit(expr->generator_object()));
RECURSE_EXPRESSION(Visit(expr->expression()));
@@ -477,6 +477,13 @@ void AstTraversalVisitor<Subclass>::VisitGetIterator(GetIterator* expr) {
}
template <class Subclass>
+void AstTraversalVisitor<Subclass>::VisitImportCallExpression(
+ ImportCallExpression* expr) {
+ PROCESS_EXPRESSION(expr);
+ RECURSE_EXPRESSION(Visit(expr->argument()));
+}
+
+template <class Subclass>
void AstTraversalVisitor<Subclass>::VisitSuperPropertyReference(
SuperPropertyReference* expr) {
PROCESS_EXPRESSION(expr);
diff --git a/deps/v8/src/ast/ast-types.cc b/deps/v8/src/ast/ast-types.cc
index 3dde86413a..9e14730c97 100644
--- a/deps/v8/src/ast/ast-types.cc
+++ b/deps/v8/src/ast/ast-types.cc
@@ -186,7 +186,6 @@ AstType::bitset AstBitsetType::Lub(i::Map* map) {
if (map == heap->boolean_map()) return kBoolean;
if (map == heap->the_hole_map()) return kHole;
DCHECK(map == heap->uninitialized_map() ||
- map == heap->no_interceptor_result_sentinel_map() ||
map == heap->termination_exception_map() ||
map == heap->arguments_marker_map() ||
map == heap->optimized_out_map() ||
@@ -209,6 +208,7 @@ AstType::bitset AstBitsetType::Lub(i::Map* map) {
case JS_DATE_TYPE:
case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
case JS_GENERATOR_OBJECT_TYPE:
+ case JS_ASYNC_GENERATOR_OBJECT_TYPE:
case JS_MODULE_NAMESPACE_TYPE:
case JS_ARRAY_BUFFER_TYPE:
case JS_ARRAY_TYPE:
@@ -287,6 +287,7 @@ AstType::bitset AstBitsetType::Lub(i::Map* map) {
case PROPERTY_CELL_TYPE:
case MODULE_TYPE:
case MODULE_INFO_ENTRY_TYPE:
+ case ASYNC_GENERATOR_REQUEST_TYPE:
return kOtherInternal & kTaggedPointer;
// Remaining instance types are unsupported for now. If any of them do
@@ -311,6 +312,7 @@ AstType::bitset AstBitsetType::Lub(i::Map* map) {
case ALIASED_ARGUMENTS_ENTRY_TYPE:
case DEBUG_INFO_TYPE:
case BREAK_POINT_INFO_TYPE:
+ case STACK_FRAME_INFO_TYPE:
case CELL_TYPE:
case WEAK_CELL_TYPE:
case PROTOTYPE_INFO_TYPE:
diff --git a/deps/v8/src/ast/ast-value-factory.cc b/deps/v8/src/ast/ast-value-factory.cc
index b160c48a20..74613c5eae 100644
--- a/deps/v8/src/ast/ast-value-factory.cc
+++ b/deps/v8/src/ast/ast-value-factory.cc
@@ -84,21 +84,8 @@ class AstRawStringInternalizationKey : public HashTableKey {
const AstRawString* string_;
};
-int AstString::length() const {
- if (IsRawStringBits::decode(bit_field_)) {
- return reinterpret_cast<const AstRawString*>(this)->length();
- }
- return reinterpret_cast<const AstConsString*>(this)->length();
-}
-
-void AstString::Internalize(Isolate* isolate) {
- if (IsRawStringBits::decode(bit_field_)) {
- return reinterpret_cast<AstRawString*>(this)->Internalize(isolate);
- }
- return reinterpret_cast<AstConsString*>(this)->Internalize(isolate);
-}
-
void AstRawString::Internalize(Isolate* isolate) {
+ DCHECK(!has_string_);
if (literal_bytes_.length() == 0) {
set_string(isolate->factory()->empty_string());
} else {
@@ -121,18 +108,26 @@ bool AstRawString::AsArrayIndex(uint32_t* index) const {
}
bool AstRawString::IsOneByteEqualTo(const char* data) const {
- int length = static_cast<int>(strlen(data));
- if (is_one_byte() && literal_bytes_.length() == length) {
- const char* token = reinterpret_cast<const char*>(literal_bytes_.start());
- return !strncmp(token, data, length);
- }
- return false;
+ if (!is_one_byte()) return false;
+
+ size_t length = static_cast<size_t>(literal_bytes_.length());
+ if (length != strlen(data)) return false;
+
+ return 0 == strncmp(reinterpret_cast<const char*>(literal_bytes_.start()),
+ data, length);
+}
+
+uint16_t AstRawString::FirstCharacter() const {
+ if (is_one_byte()) return literal_bytes_[0];
+ const uint16_t* c = reinterpret_cast<const uint16_t*>(literal_bytes_.start());
+ return *c;
}
bool AstRawString::Compare(void* a, void* b) {
const AstRawString* lhs = static_cast<AstRawString*>(a);
const AstRawString* rhs = static_cast<AstRawString*>(b);
DCHECK_EQ(lhs->hash(), rhs->hash());
+
if (lhs->length() != rhs->length()) return false;
const unsigned char* l = lhs->raw_data();
const unsigned char* r = rhs->raw_data();
@@ -161,11 +156,20 @@ bool AstRawString::Compare(void* a, void* b) {
}
void AstConsString::Internalize(Isolate* isolate) {
- // AstRawStrings are internalized before AstConsStrings so left and right are
- // already internalized.
- set_string(isolate->factory()
- ->NewConsString(left_->string(), right_->string())
- .ToHandleChecked());
+ if (IsEmpty()) {
+ set_string(isolate->factory()->empty_string());
+ return;
+ }
+ // AstRawStrings are internalized before AstConsStrings, so
+ // AstRawString::string() will just work.
+ Handle<String> tmp(segment_.string->string());
+ for (AstConsString::Segment* current = segment_.next; current != nullptr;
+ current = current->next) {
+ tmp = isolate->factory()
+ ->NewConsString(current->string->string(), tmp)
+ .ToHandleChecked();
+ }
+ set_string(tmp);
}
bool AstValue::IsPropertyName() const {
@@ -285,22 +289,34 @@ const AstRawString* AstValueFactory::GetString(Handle<String> literal) {
return result;
}
-
-const AstConsString* AstValueFactory::NewConsString(
- const AstString* left, const AstString* right) {
- // This Vector will be valid as long as the Collector is alive (meaning that
- // the AstRawString will not be moved).
- AstConsString* new_string = new (zone_) AstConsString(left, right);
- CHECK(new_string != nullptr);
- AddString(new_string);
+AstConsString* AstValueFactory::NewConsString() {
+ AstConsString* new_string = new (zone_) AstConsString;
+ DCHECK_NOT_NULL(new_string);
+ AddConsString(new_string);
return new_string;
}
+AstConsString* AstValueFactory::NewConsString(const AstRawString* str) {
+ return NewConsString()->AddString(zone_, str);
+}
+
+AstConsString* AstValueFactory::NewConsString(const AstRawString* str1,
+ const AstRawString* str2) {
+ return NewConsString()->AddString(zone_, str1)->AddString(zone_, str2);
+}
+
void AstValueFactory::Internalize(Isolate* isolate) {
// Strings need to be internalized before values, because values refer to
// strings.
- for (AstString* current = strings_; current != nullptr;) {
- AstString* next = current->next();
+ for (AstRawString* current = strings_; current != nullptr;) {
+ AstRawString* next = current->next();
+ current->Internalize(isolate);
+ current = next;
+ }
+
+ // AstConsStrings refer to AstRawStrings.
+ for (AstConsString* current = cons_strings_; current != nullptr;) {
+ AstConsString* next = current->next();
current->Internalize(isolate);
current = next;
}
diff --git a/deps/v8/src/ast/ast-value-factory.h b/deps/v8/src/ast/ast-value-factory.h
index c1ed7acc57..19452bc325 100644
--- a/deps/v8/src/ast/ast-value-factory.h
+++ b/deps/v8/src/ast/ast-value-factory.h
@@ -35,123 +35,144 @@
#include "src/isolate.h"
#include "src/utils.h"
-// AstString, AstValue and AstValueFactory are for storing strings and values
-// independent of the V8 heap and internalizing them later. During parsing,
-// AstStrings and AstValues are created and stored outside the heap, in
-// AstValueFactory. After parsing, the strings and values are internalized
-// (moved into the V8 heap).
+// Ast(Raw|Cons)String, AstValue 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
+// heap).
namespace v8 {
namespace internal {
-class AstString : public ZoneObject {
- public:
- explicit AstString(bool is_raw)
- : next_(nullptr), bit_field_(IsRawStringBits::encode(is_raw)) {}
-
- int length() const;
- bool IsEmpty() const { return length() == 0; }
-
- // Puts the string into the V8 heap.
- void Internalize(Isolate* isolate);
-
- // This function can be called after internalizing.
- V8_INLINE Handle<String> string() const {
- DCHECK_NOT_NULL(string_);
- return Handle<String>(string_);
- }
-
- AstString* next() { return next_; }
- AstString** next_location() { return &next_; }
-
- protected:
- void set_string(Handle<String> string) { string_ = string.location(); }
- // {string_} is stored as String** instead of a Handle<String> so it can be
- // stored in a union with {next_}.
- union {
- AstString* next_;
- String** string_;
- };
- // Poor-man's virtual dispatch to AstRawString / AstConsString. Takes less
- // memory.
- class IsRawStringBits : public BitField<bool, 0, 1> {};
- int bit_field_;
-};
-
-
-class AstRawString final : public AstString {
+class AstRawString final : public ZoneObject {
public:
+ bool IsEmpty() const { return literal_bytes_.length() == 0; }
int length() const {
- if (is_one_byte()) return literal_bytes_.length();
- return literal_bytes_.length() / 2;
+ return is_one_byte() ? literal_bytes_.length()
+ : literal_bytes_.length() / 2;
}
-
- int byte_length() const { return literal_bytes_.length(); }
+ bool AsArrayIndex(uint32_t* index) const;
+ bool IsOneByteEqualTo(const char* data) const;
+ uint16_t FirstCharacter() const;
void Internalize(Isolate* isolate);
- bool AsArrayIndex(uint32_t* index) const;
-
- // The string is not null-terminated, use length() to find out the length.
+ // Access the physical representation:
+ bool is_one_byte() const { return is_one_byte_; }
+ int byte_length() const { return literal_bytes_.length(); }
const unsigned char* raw_data() const {
return literal_bytes_.start();
}
- bool is_one_byte() const { return IsOneByteBits::decode(bit_field_); }
-
- bool IsOneByteEqualTo(const char* data) const;
- uint16_t FirstCharacter() const {
- if (is_one_byte()) return literal_bytes_[0];
- const uint16_t* c =
- reinterpret_cast<const uint16_t*>(literal_bytes_.start());
- return *c;
- }
-
- static bool Compare(void* a, void* b);
-
// For storing AstRawStrings in a hash map.
uint32_t hash() const {
return hash_;
}
+ // This function can be called after internalizing.
+ V8_INLINE Handle<String> string() const {
+ DCHECK_NOT_NULL(string_);
+ DCHECK(has_string_);
+ return Handle<String>(string_);
+ }
+
private:
friend class AstRawStringInternalizationKey;
friend class AstStringConstants;
friend class AstValueFactory;
+ // Members accessed only by the AstValueFactory & related classes:
+ static bool Compare(void* a, void* b);
AstRawString(bool is_one_byte, const Vector<const byte>& literal_bytes,
uint32_t hash)
- : AstString(true), hash_(hash), literal_bytes_(literal_bytes) {
- bit_field_ |= IsOneByteBits::encode(is_one_byte);
+ : next_(nullptr),
+ literal_bytes_(literal_bytes),
+ hash_(hash),
+ is_one_byte_(is_one_byte) {}
+ AstRawString* next() {
+ DCHECK(!has_string_);
+ return next_;
+ }
+ AstRawString** next_location() {
+ DCHECK(!has_string_);
+ return &next_;
}
- AstRawString() : AstString(true), hash_(0) {
- bit_field_ |= IsOneByteBits::encode(true);
+ void set_string(Handle<String> string) {
+ DCHECK(!string.is_null());
+ DCHECK(!has_string_);
+ string_ = string.location();
+#ifdef DEBUG
+ has_string_ = true;
+#endif
}
- class IsOneByteBits : public BitField<bool, IsRawStringBits::kNext, 1> {};
+ // {string_} is stored as String** instead of a Handle<String> so it can be
+ // stored in a union with {next_}.
+ union {
+ AstRawString* next_;
+ String** string_;
+ };
+ Vector<const byte> literal_bytes_; // Memory owned by Zone.
uint32_t hash_;
- // Points to memory owned by Zone.
- Vector<const byte> literal_bytes_;
+ bool is_one_byte_;
+#ifdef DEBUG
+ // (Debug-only:) Verify the object life-cylce: Some functions may only be
+ // called after internalization (that is, after a v8::internal::String has
+ // been set); some only before.
+ bool has_string_ = false;
+#endif
};
-
-class AstConsString final : public AstString {
+class AstConsString final : public ZoneObject {
public:
- AstConsString(const AstString* left, const AstString* right)
- : AstString(false),
- length_(left->length() + right->length()),
- left_(left),
- right_(right) {}
+ AstConsString* AddString(Zone* zone, const AstRawString* s) {
+ if (s->IsEmpty()) return this;
+ if (!IsEmpty()) {
+ // We're putting the new string to the head of the list, meaning
+ // the string segments will be in reverse order.
+ Segment* tmp = new (zone->New(sizeof(Segment))) Segment;
+ *tmp = segment_;
+ segment_.next = tmp;
+ }
+ segment_.string = s;
+ return this;
+ }
- int length() const { return length_; }
+ bool IsEmpty() const {
+ DCHECK_IMPLIES(segment_.string == nullptr, segment_.next == nullptr);
+ DCHECK_IMPLIES(segment_.string != nullptr, !segment_.string->IsEmpty());
+ return segment_.string == nullptr;
+ }
void Internalize(Isolate* isolate);
+ V8_INLINE Handle<String> string() const {
+ DCHECK_NOT_NULL(string_);
+ return Handle<String>(string_);
+ }
+
private:
- const int length_;
- const AstString* left_;
- const AstString* right_;
+ friend class AstValueFactory;
+
+ AstConsString() : next_(nullptr), segment_({nullptr, nullptr}) {}
+
+ AstConsString* next() const { return next_; }
+ AstConsString** next_location() { return &next_; }
+
+ // {string_} is stored as String** instead of a Handle<String> so it can be
+ // stored in a union with {next_}.
+ void set_string(Handle<String> string) { string_ = string.location(); }
+ union {
+ AstConsString* next_;
+ String** string_;
+ };
+
+ struct Segment {
+ const AstRawString* string;
+ AstConsString::Segment* next;
+ };
+ Segment segment_;
};
enum class AstSymbol : uint8_t { kHomeObjectSymbol };
@@ -310,6 +331,7 @@ class AstValue : public ZoneObject {
F(arguments, "arguments") \
F(async, "async") \
F(await, "await") \
+ F(boolean, "boolean") \
F(constructor, "constructor") \
F(default, "default") \
F(done, "done") \
@@ -330,11 +352,15 @@ class AstValue : public ZoneObject {
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") \
@@ -407,7 +433,10 @@ class AstValueFactory {
values_(nullptr),
strings_(nullptr),
strings_end_(&strings_),
+ cons_strings_(nullptr),
+ cons_strings_end_(&cons_strings_),
string_constants_(string_constants),
+ empty_cons_string_(nullptr),
zone_(zone),
hash_seed_(hash_seed) {
#define F(name) name##_ = nullptr;
@@ -418,6 +447,7 @@ class AstValueFactory {
std::fill(one_character_strings_,
one_character_strings_ + arraysize(one_character_strings_),
nullptr);
+ empty_cons_string_ = NewConsString();
}
Zone* zone() const { return zone_; }
@@ -433,17 +463,20 @@ class AstValueFactory {
return GetTwoByteStringInternal(literal);
}
const AstRawString* GetString(Handle<String> literal);
- const AstConsString* NewConsString(const AstString* left,
- const AstString* right);
+ V8_EXPORT_PRIVATE AstConsString* NewConsString();
+ AstConsString* NewConsString(const AstRawString* str);
+ AstConsString* NewConsString(const AstRawString* str1,
+ const AstRawString* str2);
V8_EXPORT_PRIVATE void Internalize(Isolate* isolate);
#define F(name, str) \
- const AstRawString* name##_string() { \
+ const AstRawString* name##_string() const { \
return string_constants_->name##_string(); \
}
STRING_CONSTANTS(F)
#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).
@@ -467,14 +500,21 @@ class AstValueFactory {
values_ = value;
return value;
}
- AstString* AddString(AstString* string) {
+ AstRawString* AddString(AstRawString* string) {
*strings_end_ = string;
strings_end_ = string->next_location();
return string;
}
+ AstConsString* AddConsString(AstConsString* string) {
+ *cons_strings_end_ = string;
+ cons_strings_end_ = string->next_location();
+ return string;
+ }
void ResetStrings() {
strings_ = nullptr;
strings_end_ = &strings_;
+ cons_strings_ = nullptr;
+ cons_strings_end_ = &cons_strings_;
}
V8_EXPORT_PRIVATE AstRawString* GetOneByteStringInternal(
Vector<const uint8_t> literal);
@@ -490,11 +530,14 @@ class AstValueFactory {
// We need to keep track of strings_ in order since cons strings require their
// members to be internalized first.
- AstString* strings_;
- AstString** strings_end_;
+ AstRawString* strings_;
+ AstRawString** strings_end_;
+ AstConsString* cons_strings_;
+ AstConsString** cons_strings_end_;
// Holds constant string values which are shared across the isolate.
const AstStringConstants* string_constants_;
+ const AstConsString* empty_cons_string_;
// Caches for faster access: small numbers, one character lowercase strings
// (for minified code).
diff --git a/deps/v8/src/ast/ast.cc b/deps/v8/src/ast/ast.cc
index 5705c70057..d7d70ae433 100644
--- a/deps/v8/src/ast/ast.cc
+++ b/deps/v8/src/ast/ast.cc
@@ -51,6 +51,7 @@ static const char* NameForNativeContextIntrinsicIndex(uint32_t idx) {
void AstNode::Print() { Print(Isolate::Current()); }
void AstNode::Print(Isolate* isolate) {
+ AllowHandleDereference allow_deref;
AstPrinter::PrintOut(isolate, this);
}
@@ -163,7 +164,7 @@ void Expression::MarkTail() {
bool DoExpression::IsAnonymousFunctionDefinition() const {
// This is specifically to allow DoExpressions to represent ClassLiterals.
return represented_function_ != nullptr &&
- represented_function_->raw_name()->length() == 0;
+ represented_function_->raw_name()->IsEmpty();
}
bool Statement::IsJump() const {
@@ -249,16 +250,16 @@ static void AssignVectorSlots(Expression* expr, FeedbackVectorSpec* spec,
FeedbackSlot* out_slot) {
Property* property = expr->AsProperty();
LhsKind assign_type = Property::GetAssignType(property);
- if ((assign_type == VARIABLE &&
- expr->AsVariableProxy()->var()->IsUnallocated()) ||
- assign_type == NAMED_PROPERTY || assign_type == KEYED_PROPERTY) {
- // TODO(ishell): consider using ICSlotCache for variables here.
- if (assign_type == KEYED_PROPERTY) {
- *out_slot = spec->AddKeyedStoreICSlot(language_mode);
+ // TODO(ishell): consider using ICSlotCache for variables here.
+ if (assign_type == VARIABLE &&
+ expr->AsVariableProxy()->var()->IsUnallocated()) {
+ *out_slot = spec->AddStoreGlobalICSlot(language_mode);
- } else {
- *out_slot = spec->AddStoreICSlot(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);
}
}
@@ -681,8 +682,8 @@ bool ObjectLiteral::IsFastCloningSupported() const {
// literals don't support copy-on-write (COW) elements for now.
// TODO(mvstanton): make object literals support COW elements.
return fast_elements() && has_shallow_properties() &&
- properties_count() <= ConstructorBuiltinsAssembler::
- kMaximumClonedShallowObjectProperties;
+ properties_count() <=
+ ConstructorBuiltins::kMaximumClonedShallowObjectProperties;
}
ElementsKind ArrayLiteral::constant_elements_kind() const {
@@ -786,7 +787,7 @@ void ArrayLiteral::BuildConstantElements(Isolate* isolate) {
bool ArrayLiteral::IsFastCloningSupported() const {
return depth() <= 1 &&
values()->length() <=
- ConstructorBuiltinsAssembler::kMaximumClonedShallowArrayElements;
+ ConstructorBuiltins::kMaximumClonedShallowArrayElements;
}
void ArrayLiteral::RewindSpreads() {
@@ -883,6 +884,30 @@ void BinaryOperation::AssignFeedbackSlots(FeedbackVectorSpec* spec,
}
}
+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 ||
+ op == Token::BIT_XOR;
+}
+
+// Check for the pattern: x + 1.
+static bool MatchSmiLiteralOperation(Expression* left, Expression* right,
+ Expression** expr, Smi** literal) {
+ if (right->IsSmiLiteral()) {
+ *expr = left;
+ *literal = right->AsLiteral()->AsSmiLiteral();
+ return true;
+ }
+ return false;
+}
+
+bool BinaryOperation::IsSmiLiteralOperation(Expression** subexpr,
+ Smi** literal) {
+ return MatchSmiLiteralOperation(left_, right_, subexpr, literal) ||
+ (IsCommutativeOperationWithSmiLiteral(op()) &&
+ MatchSmiLiteralOperation(right_, left_, subexpr, literal));
+}
+
static bool IsTypeof(Expression* expr) {
UnaryOperation* maybe_unary = expr->AsUnaryOperation();
return maybe_unary != NULL && maybe_unary->op() == Token::TYPEOF;
@@ -904,24 +929,21 @@ void CompareOperation::AssignFeedbackSlots(FeedbackVectorSpec* spec,
}
// Check for the pattern: typeof <expression> equals <string literal>.
-static bool MatchLiteralCompareTypeof(Expression* left,
- Token::Value op,
- Expression* right,
- Expression** expr,
- Handle<String>* check) {
+static bool MatchLiteralCompareTypeof(Expression* left, Token::Value op,
+ Expression* right, Expression** expr,
+ Literal** literal) {
if (IsTypeof(left) && right->IsStringLiteral() && Token::IsEqualityOp(op)) {
*expr = left->AsUnaryOperation()->expression();
- *check = Handle<String>::cast(right->AsLiteral()->value());
+ *literal = right->AsLiteral();
return true;
}
return false;
}
-
bool CompareOperation::IsLiteralCompareTypeof(Expression** expr,
- Handle<String>* check) {
- return MatchLiteralCompareTypeof(left_, op(), right_, expr, check) ||
- MatchLiteralCompareTypeof(right_, op(), left_, expr, check);
+ Literal** literal) {
+ return MatchLiteralCompareTypeof(left_, op(), right_, expr, literal) ||
+ MatchLiteralCompareTypeof(right_, op(), left_, expr, literal);
}
diff --git a/deps/v8/src/ast/ast.h b/deps/v8/src/ast/ast.h
index 90e94bb87e..9d7b4de82c 100644
--- a/deps/v8/src/ast/ast.h
+++ b/deps/v8/src/ast/ast.h
@@ -91,7 +91,7 @@ namespace internal {
V(Conditional) \
V(VariableProxy) \
V(Literal) \
- V(Yield) \
+ V(Suspend) \
V(Throw) \
V(CallRuntime) \
V(UnaryOperation) \
@@ -105,7 +105,8 @@ namespace internal {
V(EmptyParentheses) \
V(GetIterator) \
V(DoExpression) \
- V(RewritableExpression)
+ V(RewritableExpression) \
+ V(ImportCallExpression)
#define AST_NODE_LIST(V) \
DECLARATION_NODE_LIST(V) \
@@ -563,11 +564,11 @@ class IterationStatement : public BreakableStatement {
Statement* body() const { return body_; }
void set_body(Statement* s) { body_ = s; }
- int yield_count() const { return yield_count_; }
- int first_yield_id() const { return first_yield_id_; }
- void set_yield_count(int yield_count) { yield_count_ = yield_count; }
- void set_first_yield_id(int first_yield_id) {
- first_yield_id_ = first_yield_id;
+ int suspend_count() const { return suspend_count_; }
+ int first_suspend_id() const { return first_suspend_id_; }
+ void set_suspend_count(int suspend_count) { suspend_count_ = suspend_count; }
+ void set_first_suspend_id(int first_suspend_id) {
+ first_suspend_id_ = first_suspend_id;
}
static int num_ids() { return parent_num_ids() + 1; }
@@ -581,8 +582,8 @@ class IterationStatement : public BreakableStatement {
NodeType type)
: BreakableStatement(labels, TARGET_FOR_ANONYMOUS, pos, type),
body_(NULL),
- yield_count_(0),
- first_yield_id_(0) {}
+ suspend_count_(0),
+ first_suspend_id_(0) {}
static int parent_num_ids() { return BreakableStatement::num_ids(); }
void Initialize(Statement* body) { body_ = body; }
@@ -594,8 +595,8 @@ class IterationStatement : public BreakableStatement {
Statement* body_;
Label continue_target_;
- int yield_count_;
- int first_yield_id_;
+ int suspend_count_;
+ int first_suspend_id_;
};
@@ -1101,7 +1102,6 @@ class TryStatement : public Statement {
class TryCatchStatement final : public TryStatement {
public:
Scope* scope() { return scope_; }
- Variable* variable() { return variable_; }
Block* catch_block() const { return catch_block_; }
void set_catch_block(Block* b) { catch_block_ = b; }
@@ -1122,18 +1122,15 @@ class TryCatchStatement final : public TryStatement {
private:
friend class AstNodeFactory;
- TryCatchStatement(Block* try_block, Scope* scope, Variable* variable,
- Block* catch_block,
+ TryCatchStatement(Block* try_block, Scope* scope, Block* catch_block,
HandlerTable::CatchPrediction catch_prediction, int pos)
: TryStatement(try_block, pos, kTryCatchStatement),
scope_(scope),
- variable_(variable),
catch_block_(catch_block) {
catch_prediction_ = catch_prediction;
}
Scope* scope_;
- Variable* variable_;
Block* catch_block_;
};
@@ -1205,6 +1202,11 @@ class Literal final : public Expression {
return value_->AsString();
}
+ Smi* AsSmiLiteral() {
+ DCHECK(IsSmiLiteral());
+ return raw_value()->AsSmi();
+ }
+
bool ToBooleanIsTrue() const { return raw_value()->BooleanValue(); }
bool ToBooleanIsFalse() const { return !raw_value()->BooleanValue(); }
@@ -2138,6 +2140,11 @@ class BinaryOperation final : public Expression {
TypeFeedbackId BinaryOperationFeedbackId() const {
return TypeFeedbackId(local_id(1));
}
+
+ // Returns true if one side is a Smi literal, returning the other side's
+ // sub-expression in |subexpr| and the literal Smi in |literal|.
+ bool IsSmiLiteralOperation(Expression** subexpr, Smi** literal);
+
Maybe<int> fixed_right_arg() const {
return has_fixed_right_arg_ ? Just(fixed_right_arg_value_) : Nothing<int>();
}
@@ -2279,7 +2286,7 @@ class CompareOperation final : public Expression {
FeedbackSlot CompareOperationFeedbackSlot() const { return feedback_slot_; }
// Match special cases.
- bool IsLiteralCompareTypeof(Expression** expr, Handle<String>* check);
+ bool IsLiteralCompareTypeof(Expression** expr, Literal** literal);
bool IsLiteralCompareUndefined(Expression** expr);
bool IsLiteralCompareNull(Expression** expr);
@@ -2493,10 +2500,16 @@ class RewritableExpression final : public Expression {
: public BitField<bool, Expression::kNextBitFieldIndex, 1> {};
};
+// There are several types of Suspend node:
+//
+// Yield
+// YieldStar
+// Await
+//
// Our Yield is different from the JS yield in that it "returns" its argument as
// is, without wrapping it in an iterator result object. Such wrapping, if
// desired, must be done beforehand (see the parser).
-class Yield final : public Expression {
+class Suspend final : public Expression {
public:
enum OnException { kOnExceptionThrow, kOnExceptionRethrow };
@@ -2508,30 +2521,59 @@ class Yield final : public Expression {
bool rethrow_on_exception() const {
return on_exception() == kOnExceptionRethrow;
}
- int yield_id() const { return yield_id_; }
+
+ int suspend_id() const { return suspend_id_; }
+ SuspendFlags flags() const { return FlagsField::decode(bit_field_); }
+ SuspendFlags suspend_type() const {
+ return flags() & SuspendFlags::kSuspendTypeMask;
+ }
+ SuspendFlags generator_type() const {
+ return flags() & SuspendFlags::kGeneratorTypeMask;
+ }
+ bool is_yield() const { return suspend_type() == SuspendFlags::kYield; }
+ bool is_yield_star() const {
+ return suspend_type() == SuspendFlags::kYieldStar;
+ }
+ bool is_await() const { return suspend_type() == SuspendFlags::kAwait; }
+ bool is_async_generator() const {
+ return generator_type() == SuspendFlags::kAsyncGenerator;
+ }
+ inline bool IsNonInitialAsyncGeneratorYield() const {
+ // Return true if is_async_generator() && !is_await() && yield_id() > 0
+ return suspend_id() > 0 && (flags() & SuspendFlags::kAsyncGeneratorAwait) ==
+ SuspendFlags::kAsyncGenerator;
+ }
void set_generator_object(Expression* e) { generator_object_ = e; }
void set_expression(Expression* e) { expression_ = e; }
- void set_yield_id(int yield_id) { yield_id_ = yield_id; }
+ void set_suspend_id(int id) { suspend_id_ = id; }
+ void set_suspend_type(SuspendFlags type) {
+ DCHECK_EQ(0, static_cast<int>(type & ~SuspendFlags::kSuspendTypeMask));
+ bit_field_ = FlagsField::update(bit_field_, type);
+ }
private:
friend class AstNodeFactory;
- Yield(Expression* generator_object, Expression* expression, int pos,
- OnException on_exception)
- : Expression(pos, kYield),
- yield_id_(-1),
+ Suspend(Expression* generator_object, Expression* expression, int pos,
+ OnException on_exception, SuspendFlags flags)
+ : Expression(pos, kSuspend),
+ suspend_id_(-1),
generator_object_(generator_object),
expression_(expression) {
- bit_field_ |= OnExceptionField::encode(on_exception);
+ bit_field_ |=
+ OnExceptionField::encode(on_exception) | FlagsField::encode(flags);
}
- int yield_id_;
+ int suspend_id_;
Expression* generator_object_;
Expression* expression_;
class OnExceptionField
: public BitField<OnException, Expression::kNextBitFieldIndex, 1> {};
+ class FlagsField
+ : public BitField<SuspendFlags, OnExceptionField::kNext,
+ static_cast<int>(SuspendFlags::kBitWidth)> {};
};
@@ -2566,8 +2608,8 @@ class FunctionLiteral final : public Expression {
enum EagerCompileHint { kShouldEagerCompile, kShouldLazyCompile };
Handle<String> name() const { return raw_name_->string(); }
- const AstString* raw_name() const { return raw_name_; }
- void set_raw_name(const AstString* name) { raw_name_ = name; }
+ const AstConsString* raw_name() const { return raw_name_; }
+ void set_raw_name(const AstConsString* name) { raw_name_ = name; }
DeclarationScope* scope() const { return scope_; }
ZoneList<Statement*>* body() const { return body_; }
void set_function_token_position(int pos) { function_token_position_ = pos; }
@@ -2593,7 +2635,11 @@ class FunctionLiteral final : public Expression {
static bool NeedsHomeObject(Expression* expr);
- int expected_property_count() { return expected_property_count_; }
+ int expected_property_count() {
+ // Not valid for lazy functions.
+ DCHECK_NOT_NULL(body_);
+ return expected_property_count_;
+ }
int parameter_count() { return parameter_count_; }
int function_length() { return function_length_; }
@@ -2626,7 +2672,7 @@ class FunctionLiteral final : public Expression {
raw_inferred_name_ = NULL;
}
- void set_raw_inferred_name(const AstString* raw_inferred_name) {
+ void set_raw_inferred_name(const AstConsString* raw_inferred_name) {
DCHECK(raw_inferred_name != NULL);
raw_inferred_name_ = raw_inferred_name;
DCHECK(inferred_name_.is_null());
@@ -2637,6 +2683,8 @@ class FunctionLiteral final : public Expression {
void set_pretenure() { bit_field_ = Pretenure::update(bit_field_, true); }
bool has_duplicate_parameters() const {
+ // Not valid for lazy functions.
+ DCHECK_NOT_NULL(body_);
return HasDuplicateParameters::decode(bit_field_);
}
@@ -2682,8 +2730,8 @@ class FunctionLiteral final : public Expression {
return is_anonymous_expression();
}
- int yield_count() { return yield_count_; }
- void set_yield_count(int yield_count) { yield_count_ = yield_count; }
+ int suspend_count() { return suspend_count_; }
+ void set_suspend_count(int suspend_count) { suspend_count_ = suspend_count; }
int return_position() {
return std::max(start_position(), end_position() - (has_braces_ ? 1 : 0));
@@ -2697,7 +2745,7 @@ class FunctionLiteral final : public Expression {
private:
friend class AstNodeFactory;
- FunctionLiteral(Zone* zone, const AstString* name,
+ FunctionLiteral(Zone* zone, const AstRawString* name,
AstValueFactory* ast_value_factory, DeclarationScope* scope,
ZoneList<Statement*>* body, int expected_property_count,
int parameter_count, int function_length,
@@ -2710,12 +2758,12 @@ class FunctionLiteral final : public Expression {
parameter_count_(parameter_count),
function_length_(function_length),
function_token_position_(kNoSourcePosition),
- yield_count_(0),
+ suspend_count_(0),
has_braces_(has_braces),
- raw_name_(name),
+ raw_name_(ast_value_factory->NewConsString(name)),
scope_(scope),
body_(body),
- raw_inferred_name_(ast_value_factory->empty_string()),
+ raw_inferred_name_(ast_value_factory->empty_cons_string()),
ast_properties_(zone),
function_literal_id_(function_literal_id) {
bit_field_ |= FunctionTypeBits::encode(function_type) |
@@ -2725,6 +2773,7 @@ class FunctionLiteral final : public Expression {
ShouldNotBeUsedOnceHintField::encode(false) |
DontOptimizeReasonField::encode(kNoReason);
if (eager_compile_hint == kShouldEagerCompile) SetShouldEagerCompile();
+ DCHECK_EQ(body == nullptr, expected_property_count < 0);
}
class FunctionTypeBits
@@ -2741,13 +2790,13 @@ class FunctionLiteral final : public Expression {
int parameter_count_;
int function_length_;
int function_token_position_;
- int yield_count_;
+ int suspend_count_;
bool has_braces_;
- const AstString* raw_name_;
+ const AstConsString* raw_name_;
DeclarationScope* scope_;
ZoneList<Statement*>* body_;
- const AstString* raw_inferred_name_;
+ const AstConsString* raw_inferred_name_;
Handle<String> inferred_name_;
AstProperties ast_properties_;
int function_literal_id_;
@@ -2925,6 +2974,21 @@ class SuperCallReference final : public Expression {
VariableProxy* this_function_var_;
};
+// This AST Node is used to represent a dynamic import call --
+// import(argument).
+class ImportCallExpression final : public Expression {
+ public:
+ Expression* argument() const { return argument_; }
+ void set_argument(Expression* argument) { argument_ = argument; }
+
+ private:
+ friend class AstNodeFactory;
+
+ ImportCallExpression(Expression* argument, int pos)
+ : Expression(pos, kImportCallExpression), argument_(argument) {}
+
+ Expression* argument_;
+};
// This class is produced when parsing the () in arrow functions without any
// arguments and is not actually a valid expression.
@@ -3245,38 +3309,33 @@ class AstNodeFactory final BASE_EMBEDDED {
}
TryCatchStatement* NewTryCatchStatement(Block* try_block, Scope* scope,
- Variable* variable,
Block* catch_block, int pos) {
- return new (zone_) TryCatchStatement(
- try_block, scope, variable, catch_block, HandlerTable::CAUGHT, pos);
+ return new (zone_) TryCatchStatement(try_block, scope, catch_block,
+ HandlerTable::CAUGHT, pos);
}
TryCatchStatement* NewTryCatchStatementForReThrow(Block* try_block,
Scope* scope,
- Variable* variable,
Block* catch_block,
int pos) {
- return new (zone_) TryCatchStatement(
- try_block, scope, variable, catch_block, HandlerTable::UNCAUGHT, pos);
+ return new (zone_) TryCatchStatement(try_block, scope, catch_block,
+ HandlerTable::UNCAUGHT, pos);
}
TryCatchStatement* NewTryCatchStatementForDesugaring(Block* try_block,
Scope* scope,
- Variable* variable,
Block* catch_block,
int pos) {
- return new (zone_) TryCatchStatement(
- try_block, scope, variable, catch_block, HandlerTable::DESUGARING, pos);
+ return new (zone_) TryCatchStatement(try_block, scope, catch_block,
+ HandlerTable::DESUGARING, pos);
}
TryCatchStatement* NewTryCatchStatementForAsyncAwait(Block* try_block,
Scope* scope,
- Variable* variable,
Block* catch_block,
int pos) {
- return new (zone_)
- TryCatchStatement(try_block, scope, variable, catch_block,
- HandlerTable::ASYNC_AWAIT, pos);
+ return new (zone_) TryCatchStatement(try_block, scope, catch_block,
+ HandlerTable::ASYNC_AWAIT, pos);
}
TryFinallyStatement* NewTryFinallyStatement(Block* try_block,
@@ -3481,10 +3540,12 @@ class AstNodeFactory final BASE_EMBEDDED {
return assign;
}
- Yield* NewYield(Expression* generator_object, Expression* expression, int pos,
- Yield::OnException on_exception) {
+ Suspend* NewSuspend(Expression* generator_object, Expression* expression,
+ int pos, Suspend::OnException on_exception,
+ SuspendFlags flags) {
if (!expression) expression = NewUndefinedLiteral(pos);
- return new (zone_) Yield(generator_object, expression, pos, on_exception);
+ return new (zone_)
+ Suspend(generator_object, expression, pos, on_exception, flags);
}
Throw* NewThrow(Expression* exception, int pos) {
@@ -3578,6 +3639,10 @@ class AstNodeFactory final BASE_EMBEDDED {
return new (zone_) GetIterator(iterable, hint, pos);
}
+ ImportCallExpression* NewImportCallExpression(Expression* args, int pos) {
+ return new (zone_) ImportCallExpression(args, pos);
+ }
+
Zone* zone() const { return zone_; }
void set_zone(Zone* zone) { zone_ = zone; }
diff --git a/deps/v8/src/ast/context-slot-cache.h b/deps/v8/src/ast/context-slot-cache.h
index 4345a65a3d..b4e3590919 100644
--- a/deps/v8/src/ast/context-slot-cache.h
+++ b/deps/v8/src/ast/context-slot-cache.h
@@ -38,7 +38,7 @@ class ContextSlotCache {
for (int i = 0; i < kLength; ++i) {
keys_[i].data = NULL;
keys_[i].name = NULL;
- values_[i] = kNotFound;
+ values_[i] = static_cast<uint32_t>(kNotFound);
}
}
diff --git a/deps/v8/src/ast/modules.h b/deps/v8/src/ast/modules.h
index ce8aba8d70..1eb6f44796 100644
--- a/deps/v8/src/ast/modules.h
+++ b/deps/v8/src/ast/modules.h
@@ -214,8 +214,9 @@ class ModuleDescriptor : public ZoneObject {
int AddModuleRequest(const AstRawString* specifier) {
DCHECK_NOT_NULL(specifier);
+ int module_requests_count = static_cast<int>(module_requests_.size());
auto it = module_requests_
- .insert(std::make_pair(specifier, module_requests_.size()))
+ .insert(std::make_pair(specifier, module_requests_count))
.first;
return it->second;
}
diff --git a/deps/v8/src/ast/prettyprinter.cc b/deps/v8/src/ast/prettyprinter.cc
index 725a8a7e7e..21ce932a08 100644
--- a/deps/v8/src/ast/prettyprinter.cc
+++ b/deps/v8/src/ast/prettyprinter.cc
@@ -254,9 +254,7 @@ void CallPrinter::VisitAssignment(Assignment* node) {
Find(node->value());
}
-
-void CallPrinter::VisitYield(Yield* node) { Find(node->expression()); }
-
+void CallPrinter::VisitSuspend(Suspend* node) { Find(node->expression()); }
void CallPrinter::VisitThrow(Throw* node) { Find(node->exception()); }
@@ -372,8 +370,23 @@ void CallPrinter::VisitEmptyParentheses(EmptyParentheses* node) {
}
void CallPrinter::VisitGetIterator(GetIterator* node) {
- Print("GetIterator(");
+ // Because CallPrinter is used by RenderCallSite() in runtime-internal.cc,
+ // and the GetIterator node results in a Call, either to a [@@iterator] or
+ // [@@asyncIterator]. It's unknown which call this error refers to, so we
+ // assume it's the first call.
+ bool was_found = !found_ && node->position() == position_;
+ if (was_found) {
+ found_ = true;
+ }
Find(node->iterable(), true);
+ Print(node->hint() == IteratorType::kNormal ? "[Symbol.iterator]"
+ : "[Symbol.asyncIterator]");
+ if (was_found) done_ = true;
+}
+
+void CallPrinter::VisitImportCallExpression(ImportCallExpression* node) {
+ Print("ImportCall(");
+ Find(node->argument(), true);
Print(")");
}
@@ -623,7 +636,8 @@ void AstPrinter::PrintLiteralWithModeIndented(const char* info,
} else {
EmbeddedVector<char, 256> buf;
int pos =
- SNPrintF(buf, "%s (mode = %s", info, VariableMode2String(var->mode()));
+ SNPrintF(buf, "%s (%p) (mode = %s", info, reinterpret_cast<void*>(var),
+ VariableMode2String(var->mode()));
SNPrintF(buf + pos, ")");
PrintLiteralIndented(buf.start(), value, true);
}
@@ -649,8 +663,8 @@ const char* AstPrinter::PrintProgram(FunctionLiteral* program) {
{ IndentedScope indent(this, "FUNC", program->position());
PrintIndented("KIND");
Print(" %d\n", program->kind());
- PrintIndented("YIELD COUNT");
- Print(" %d\n", program->yield_count());
+ PrintIndented("SUSPEND COUNT");
+ Print(" %d\n", program->suspend_count());
PrintLiteralIndented("NAME", program->name(), true);
PrintLiteralIndented("INFERRED NAME", program->inferred_name(), true);
PrintParameters(program->scope());
@@ -801,8 +815,8 @@ void AstPrinter::VisitCaseClause(CaseClause* clause) {
void AstPrinter::VisitDoWhileStatement(DoWhileStatement* node) {
IndentedScope indent(this, "DO", node->position());
- PrintIndented("YIELD COUNT");
- Print(" %d\n", node->yield_count());
+ PrintIndented("SUSPEND COUNT");
+ Print(" %d\n", node->suspend_count());
PrintLabelsIndented(node->labels());
PrintIndentedVisit("BODY", node->body());
PrintIndentedVisit("COND", node->cond());
@@ -811,8 +825,8 @@ void AstPrinter::VisitDoWhileStatement(DoWhileStatement* node) {
void AstPrinter::VisitWhileStatement(WhileStatement* node) {
IndentedScope indent(this, "WHILE", node->position());
- PrintIndented("YIELD COUNT");
- Print(" %d\n", node->yield_count());
+ PrintIndented("SUSPEND COUNT");
+ Print(" %d\n", node->suspend_count());
PrintLabelsIndented(node->labels());
PrintIndentedVisit("COND", node->cond());
PrintIndentedVisit("BODY", node->body());
@@ -821,8 +835,8 @@ void AstPrinter::VisitWhileStatement(WhileStatement* node) {
void AstPrinter::VisitForStatement(ForStatement* node) {
IndentedScope indent(this, "FOR", node->position());
- PrintIndented("YIELD COUNT");
- Print(" %d\n", node->yield_count());
+ PrintIndented("SUSPEND COUNT");
+ Print(" %d\n", node->suspend_count());
PrintLabelsIndented(node->labels());
if (node->init()) PrintIndentedVisit("INIT", node->init());
if (node->cond()) PrintIndentedVisit("COND", node->cond());
@@ -833,8 +847,8 @@ void AstPrinter::VisitForStatement(ForStatement* node) {
void AstPrinter::VisitForInStatement(ForInStatement* node) {
IndentedScope indent(this, "FOR IN", node->position());
- PrintIndented("YIELD COUNT");
- Print(" %d\n", node->yield_count());
+ PrintIndented("SUSPEND COUNT");
+ Print(" %d\n", node->suspend_count());
PrintIndentedVisit("FOR", node->each());
PrintIndentedVisit("IN", node->enumerable());
PrintIndentedVisit("BODY", node->body());
@@ -843,8 +857,8 @@ void AstPrinter::VisitForInStatement(ForInStatement* node) {
void AstPrinter::VisitForOfStatement(ForOfStatement* node) {
IndentedScope indent(this, "FOR OF", node->position());
- PrintIndented("YIELD COUNT");
- Print(" %d\n", node->yield_count());
+ PrintIndented("SUSPEND COUNT");
+ Print(" %d\n", node->suspend_count());
PrintIndentedVisit("INIT", node->assign_iterator());
PrintIndentedVisit("NEXT", node->next_result());
PrintIndentedVisit("DONE", node->result_done());
@@ -856,9 +870,8 @@ void AstPrinter::VisitForOfStatement(ForOfStatement* node) {
void AstPrinter::VisitTryCatchStatement(TryCatchStatement* node) {
IndentedScope indent(this, "TRY CATCH", node->position());
PrintTryStatement(node);
- PrintLiteralWithModeIndented("CATCHVAR",
- node->variable(),
- node->variable()->name());
+ PrintLiteralWithModeIndented("CATCHVAR", node->scope()->catch_variable(),
+ node->scope()->catch_variable()->name());
PrintIndentedVisit("CATCH", node->catch_block());
}
@@ -1095,10 +1108,9 @@ void AstPrinter::VisitAssignment(Assignment* node) {
Visit(node->value());
}
-
-void AstPrinter::VisitYield(Yield* node) {
+void AstPrinter::VisitSuspend(Suspend* node) {
EmbeddedVector<char, 128> buf;
- SNPrintF(buf, "YIELD id %d", node->yield_id());
+ SNPrintF(buf, "SUSPEND id %d", node->suspend_id());
IndentedScope indent(this, buf.start(), node->position());
Visit(node->expression());
}
@@ -1146,14 +1158,8 @@ void AstPrinter::VisitCallNew(CallNew* node) {
void AstPrinter::VisitCallRuntime(CallRuntime* node) {
EmbeddedVector<char, 128> buf;
- if (node->is_jsruntime()) {
- SNPrintF(
- buf, "CALL RUNTIME %s code = %p", node->debug_name(),
- static_cast<void*>(isolate_->context()->get(node->context_index())));
- } else {
- SNPrintF(buf, "CALL RUNTIME %s", node->debug_name());
- }
-
+ SNPrintF(buf, "CALL RUNTIME %s%s", node->debug_name(),
+ node->is_jsruntime() ? " (JS function)" : "");
IndentedScope indent(this, buf.start(), node->position());
PrintArguments(node->arguments());
}
@@ -1203,6 +1209,11 @@ void AstPrinter::VisitGetIterator(GetIterator* node) {
Visit(node->iterable());
}
+void AstPrinter::VisitImportCallExpression(ImportCallExpression* node) {
+ IndentedScope indent(this, "IMPORT-CALL", node->position());
+ Visit(node->argument());
+}
+
void AstPrinter::VisitThisFunction(ThisFunction* node) {
IndentedScope indent(this, "THIS-FUNCTION", node->position());
}
diff --git a/deps/v8/src/ast/scopes.cc b/deps/v8/src/ast/scopes.cc
index 225793c7bb..99be5cd343 100644
--- a/deps/v8/src/ast/scopes.cc
+++ b/deps/v8/src/ast/scopes.cc
@@ -112,11 +112,12 @@ void SloppyBlockFunctionMap::Delegate::set_statement(Statement* statement) {
}
SloppyBlockFunctionMap::SloppyBlockFunctionMap(Zone* zone)
- : ZoneHashMap(8, ZoneAllocationPolicy(zone)) {}
+ : ZoneHashMap(8, ZoneAllocationPolicy(zone)), count_(0) {}
-void SloppyBlockFunctionMap::Declare(
- Zone* zone, const AstRawString* name,
- SloppyBlockFunctionMap::Delegate* delegate) {
+void SloppyBlockFunctionMap::Declare(Zone* zone, const AstRawString* name,
+ Scope* scope,
+ SloppyBlockFunctionStatement* statement) {
+ auto* delegate = new (zone) Delegate(scope, statement, count_++);
// AstRawStrings are unambiguous, i.e., the same string is always represented
// by the same AstRawString*.
Entry* p =
@@ -155,14 +156,22 @@ Scope::Snapshot::Snapshot(Scope* scope)
top_inner_scope_(scope->inner_scope_),
top_unresolved_(scope->unresolved_),
top_local_(scope->GetClosureScope()->locals_.end()),
- top_decl_(scope->GetClosureScope()->decls_.end()) {}
+ top_decl_(scope->GetClosureScope()->decls_.end()),
+ outer_scope_calls_eval_(scope->scope_calls_eval_) {
+ // Reset in order to record eval calls during this Snapshot's lifetime.
+ outer_scope_->scope_calls_eval_ = false;
+}
+
+Scope::Snapshot::~Snapshot() {
+ // Restore previous calls_eval bit if needed.
+ if (outer_scope_calls_eval_) {
+ outer_scope_->scope_calls_eval_ = true;
+ }
+}
DeclarationScope::DeclarationScope(Zone* zone,
AstValueFactory* ast_value_factory)
- : Scope(zone),
- function_kind_(kNormalFunction),
- params_(4, zone),
- sloppy_block_function_map_(zone) {
+ : Scope(zone), function_kind_(kNormalFunction), params_(4, zone) {
DCHECK_EQ(scope_type_, SCRIPT_SCOPE);
SetDefaults();
@@ -176,8 +185,7 @@ DeclarationScope::DeclarationScope(Zone* zone, Scope* outer_scope,
FunctionKind function_kind)
: Scope(zone, outer_scope, scope_type),
function_kind_(function_kind),
- params_(4, zone),
- sloppy_block_function_map_(zone) {
+ params_(4, zone) {
DCHECK_NE(scope_type, SCRIPT_SCOPE);
SetDefaults();
asm_function_ = outer_scope_->IsAsmModule();
@@ -193,10 +201,11 @@ ModuleScope::ModuleScope(DeclarationScope* script_scope,
DeclareThis(ast_value_factory);
}
-ModuleScope::ModuleScope(Isolate* isolate, Handle<ScopeInfo> scope_info,
+ModuleScope::ModuleScope(Handle<ScopeInfo> scope_info,
AstValueFactory* avfactory)
: DeclarationScope(avfactory->zone(), MODULE_SCOPE, scope_info) {
Zone* zone = avfactory->zone();
+ Isolate* isolate = scope_info->GetIsolate();
Handle<ModuleInfo> module_info(scope_info->ModuleDescriptorInfo(), isolate);
set_language_mode(STRICT);
@@ -254,20 +263,22 @@ Scope::Scope(Zone* zone, ScopeType scope_type, Handle<ScopeInfo> scope_info)
set_language_mode(scope_info->language_mode());
num_heap_slots_ = scope_info->ContextLength();
DCHECK_LE(Context::MIN_CONTEXT_SLOTS, num_heap_slots_);
+ // We don't really need to use the preparsed scope data; this is just to
+ // shorten the recursion in SetMustUsePreParsedScopeData.
+ must_use_preparsed_scope_data_ = true;
}
DeclarationScope::DeclarationScope(Zone* zone, ScopeType scope_type,
Handle<ScopeInfo> scope_info)
: Scope(zone, scope_type, scope_info),
function_kind_(scope_info->function_kind()),
- params_(0, zone),
- sloppy_block_function_map_(zone) {
+ params_(0, zone) {
DCHECK_NE(scope_type, SCRIPT_SCOPE);
SetDefaults();
}
Scope::Scope(Zone* zone, const AstRawString* catch_variable_name,
- Handle<ScopeInfo> scope_info)
+ MaybeAssignedFlag maybe_assigned, Handle<ScopeInfo> scope_info)
: zone_(zone),
outer_scope_(nullptr),
variables_(zone),
@@ -280,7 +291,8 @@ Scope::Scope(Zone* zone, const AstRawString* catch_variable_name,
// Cache the catch variable, even though it's also available via the
// scope_info, as the parser expects that a catch scope always has the catch
// variable as first and only variable.
- Variable* variable = Declare(zone, catch_variable_name, VAR);
+ Variable* variable = Declare(zone, catch_variable_name, VAR, NORMAL_VARIABLE,
+ kCreatedInitialized, maybe_assigned);
AllocateHeapSlot(variable);
}
@@ -293,6 +305,7 @@ void DeclarationScope::SetDefaults() {
has_arguments_parameter_ = false;
scope_uses_super_property_ = false;
has_rest_ = false;
+ sloppy_block_function_map_ = nullptr;
receiver_ = nullptr;
new_target_ = nullptr;
function_ = nullptr;
@@ -300,6 +313,7 @@ void DeclarationScope::SetDefaults() {
rare_data_ = nullptr;
should_eager_compile_ = false;
was_lazily_parsed_ = false;
+ is_skipped_function_ = false;
#ifdef DEBUG
DeclarationScope* outer_declaration_scope =
outer_scope_ ? outer_scope_->GetDeclarationScope() : nullptr;
@@ -336,6 +350,8 @@ void Scope::SetDefaults() {
force_context_allocation_ = false;
is_declaration_scope_ = false;
+
+ must_use_preparsed_scope_data_ = false;
}
bool Scope::HasSimpleParameters() {
@@ -369,8 +385,7 @@ bool Scope::IsAsmFunction() const {
return is_function_scope() && AsDeclarationScope()->asm_function();
}
-Scope* Scope::DeserializeScopeChain(Isolate* isolate, Zone* zone,
- ScopeInfo* scope_info,
+Scope* Scope::DeserializeScopeChain(Zone* zone, ScopeInfo* scope_info,
DeclarationScope* script_scope,
AstValueFactory* ast_value_factory,
DeserializationMode deserialization_mode) {
@@ -415,15 +430,20 @@ Scope* Scope::DeserializeScopeChain(Isolate* isolate, Zone* zone,
outer_scope = new (zone) Scope(zone, BLOCK_SCOPE, handle(scope_info));
}
} else if (scope_info->scope_type() == MODULE_SCOPE) {
- outer_scope = new (zone)
- ModuleScope(isolate, handle(scope_info), ast_value_factory);
+ outer_scope =
+ new (zone) ModuleScope(handle(scope_info), ast_value_factory);
} else {
DCHECK_EQ(scope_info->scope_type(), CATCH_SCOPE);
DCHECK_EQ(scope_info->LocalCount(), 1);
- String* name = scope_info->LocalName(0);
- outer_scope = new (zone)
- Scope(zone, ast_value_factory->GetString(handle(name, isolate)),
- handle(scope_info));
+ DCHECK_EQ(scope_info->ContextLocalCount(), 1);
+ DCHECK_EQ(scope_info->ContextLocalMode(0), VAR);
+ DCHECK_EQ(scope_info->ContextLocalInitFlag(0), kCreatedInitialized);
+ String* name = scope_info->ContextLocalName(0);
+ MaybeAssignedFlag maybe_assigned =
+ scope_info->ContextLocalMaybeAssignedFlag(0);
+ outer_scope =
+ new (zone) Scope(zone, ast_value_factory->GetString(handle(name)),
+ maybe_assigned, handle(scope_info));
}
if (deserialization_mode == DeserializationMode::kScopesOnly) {
outer_scope->scope_info_ = Handle<ScopeInfo>::null();
@@ -469,9 +489,12 @@ int Scope::num_parameters() const {
void DeclarationScope::DeclareSloppyBlockFunction(
const AstRawString* name, Scope* scope,
SloppyBlockFunctionStatement* statement) {
- auto* delegate =
- new (zone()) SloppyBlockFunctionMap::Delegate(scope, statement);
- sloppy_block_function_map_.Declare(zone(), name, delegate);
+ if (sloppy_block_function_map_ == nullptr) {
+ sloppy_block_function_map_ =
+ new (zone()->New(sizeof(SloppyBlockFunctionMap)))
+ SloppyBlockFunctionMap(zone());
+ }
+ sloppy_block_function_map_->Declare(zone(), name, scope, statement);
}
void DeclarationScope::HoistSloppyBlockFunctions(AstNodeFactory* factory) {
@@ -481,12 +504,19 @@ void DeclarationScope::HoistSloppyBlockFunctions(AstNodeFactory* factory) {
DCHECK(HasSimpleParameters() || is_block_scope() || is_being_lazily_parsed_);
DCHECK_EQ(factory == nullptr, is_being_lazily_parsed_);
- bool has_simple_parameters = HasSimpleParameters();
+ SloppyBlockFunctionMap* map = sloppy_block_function_map();
+ if (map == nullptr) return;
+
+ const bool has_simple_parameters = HasSimpleParameters();
+
+ // The declarations need to be added in the order they were seen,
+ // so accumulate declared names sorted by index.
+ ZoneMap<int, const AstRawString*> names_to_declare(zone());
+
// For each variable which is used as a function declaration in a sloppy
// block,
- SloppyBlockFunctionMap* map = sloppy_block_function_map();
for (ZoneHashMap::Entry* p = map->Start(); p != nullptr; p = map->Next(p)) {
- AstRawString* name = static_cast<AstRawString*>(p->key);
+ const AstRawString* name = static_cast<AstRawString*>(p->key);
// If the variable wouldn't conflict with a lexical declaration
// or parameter,
@@ -509,7 +539,7 @@ void DeclarationScope::HoistSloppyBlockFunctions(AstNodeFactory* factory) {
}
}
- Variable* created_variable = nullptr;
+ bool declaration_queued = false;
// Write in assignments to var for each block-scoped function declaration
auto delegates = static_cast<SloppyBlockFunctionMap::Delegate*>(p->value);
@@ -543,50 +573,59 @@ void DeclarationScope::HoistSloppyBlockFunctions(AstNodeFactory* factory) {
if (!should_hoist) continue;
- // Declare a var-style binding for the function in the outer scope
+ if (!declaration_queued) {
+ declaration_queued = true;
+ names_to_declare.insert({delegate->index(), name});
+ }
+
if (factory) {
DCHECK(!is_being_lazily_parsed_);
- if (created_variable == nullptr) {
- VariableProxy* proxy =
- factory->NewVariableProxy(name, NORMAL_VARIABLE);
- auto declaration =
- factory->NewVariableDeclaration(proxy, this, kNoSourcePosition);
- // Based on the preceding check, it doesn't matter what we pass as
- // allow_harmony_restrictive_generators and
- // sloppy_mode_block_scope_function_redefinition.
- bool ok = true;
- created_variable = DeclareVariable(
- declaration, VAR, Variable::DefaultInitializationFlag(VAR), false,
- nullptr, &ok);
- CHECK(ok); // Based on the preceding check, this should not fail
- }
-
Expression* assignment = factory->NewAssignment(
Token::ASSIGN, NewUnresolved(factory, name),
delegate->scope()->NewUnresolved(factory, name), kNoSourcePosition);
Statement* statement =
factory->NewExpressionStatement(assignment, kNoSourcePosition);
delegate->set_statement(statement);
- } else {
- DCHECK(is_being_lazily_parsed_);
- if (created_variable == nullptr) {
- created_variable = DeclareVariableName(name, VAR);
- if (created_variable != kDummyPreParserVariable &&
- created_variable != kDummyPreParserLexicalVariable) {
- DCHECK(FLAG_preparser_scope_analysis);
- created_variable->set_maybe_assigned();
- }
- }
+ }
+ }
+ }
+
+ if (names_to_declare.empty()) return;
+
+ for (const auto& index_and_name : names_to_declare) {
+ const AstRawString* name = index_and_name.second;
+ if (factory) {
+ DCHECK(!is_being_lazily_parsed_);
+ VariableProxy* proxy = factory->NewVariableProxy(name, NORMAL_VARIABLE);
+ auto declaration =
+ factory->NewVariableDeclaration(proxy, this, 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);
+ DCHECK(ok);
+ } else {
+ DCHECK(is_being_lazily_parsed_);
+ Variable* var = DeclareVariableName(name, VAR);
+ if (var != kDummyPreParserVariable &&
+ var != kDummyPreParserLexicalVariable) {
+ DCHECK(FLAG_preparser_scope_analysis);
+ var->set_maybe_assigned();
}
}
}
}
-void DeclarationScope::Analyze(ParseInfo* info, AnalyzeMode mode) {
- RuntimeCallTimerScope runtimeTimer(info->isolate(),
+void DeclarationScope::Analyze(ParseInfo* info, Isolate* isolate,
+ AnalyzeMode mode) {
+ RuntimeCallTimerScope runtimeTimer(isolate,
&RuntimeCallStats::CompileScopeAnalysis);
DCHECK(info->literal() != NULL);
DeclarationScope* scope = info->literal()->scope();
+ DCHECK(scope->scope_info_.is_null());
Handle<ScopeInfo> outer_scope_info;
if (info->maybe_outer_scope_info().ToHandle(&outer_scope_info)) {
@@ -595,7 +634,7 @@ void DeclarationScope::Analyze(ParseInfo* info, AnalyzeMode mode) {
DeclarationScope(info->zone(), info->ast_value_factory());
info->set_script_scope(script_scope);
scope->ReplaceOuterScope(Scope::DeserializeScopeChain(
- info->isolate(), info->zone(), *outer_scope_info, script_scope,
+ info->zone(), *outer_scope_info, script_scope,
info->ast_value_factory(),
Scope::DeserializationMode::kIncludingVariables));
} else {
@@ -622,13 +661,19 @@ void DeclarationScope::Analyze(ParseInfo* info, AnalyzeMode mode) {
// The outer scope is never lazy.
scope->set_should_eager_compile();
- scope->AllocateVariables(info, mode);
+ if (scope->must_use_preparsed_scope_data_) {
+ DCHECK(FLAG_preparser_scope_analysis);
+ DCHECK_NOT_NULL(info->preparsed_scope_data());
+ DCHECK_EQ(scope->scope_type_, ScopeType::FUNCTION_SCOPE);
+ info->preparsed_scope_data()->RestoreData(scope);
+ }
+
+ scope->AllocateVariables(info, isolate, mode);
// Ensuring that the outer script scope has a scope info avoids having
// special case for native contexts vs other contexts.
if (info->script_scope()->scope_info_.is_null()) {
- info->script_scope()->scope_info_ =
- handle(ScopeInfo::Empty(info->isolate()));
+ info->script_scope()->scope_info_ = handle(ScopeInfo::Empty(isolate));
}
#ifdef DEBUG
@@ -722,6 +767,16 @@ Variable* DeclarationScope::DeclarePromiseVar(const AstRawString* name) {
return result;
}
+Variable* DeclarationScope::DeclareAsyncGeneratorAwaitVar(
+ const AstRawString* name) {
+ DCHECK(is_function_scope());
+ DCHECK_NULL(async_generator_await_var());
+ Variable* result = EnsureRareData()->promise = NewTemporary(name);
+ DCHECK_NULL(promise_var()); // promise is alias for generator await var
+ result->set_is_used();
+ return result;
+}
+
bool Scope::HasBeenRemoved() const {
if (sibling() == this) {
DCHECK_NULL(inner_scope_);
@@ -778,7 +833,9 @@ Scope* Scope::FinalizeBlockScope() {
unresolved_ = nullptr;
}
- PropagateUsageFlagsToScope(outer_scope_);
+ if (scope_calls_eval_) outer_scope()->scope_calls_eval_ = true;
+ if (inner_scope_calls_eval_) outer_scope()->inner_scope_calls_eval_ = true;
+
// This block does not need a context.
num_heap_slots_ = 0;
@@ -820,10 +877,15 @@ void Scope::Snapshot::Reparent(DeclarationScope* new_parent) const {
for (; inner_scope->sibling() != top_inner_scope_;
inner_scope = inner_scope->sibling()) {
inner_scope->outer_scope_ = new_parent;
+ if (inner_scope->inner_scope_calls_eval_) {
+ new_parent->inner_scope_calls_eval_ = true;
+ }
DCHECK_NE(inner_scope, new_parent);
}
inner_scope->outer_scope_ = new_parent;
-
+ if (inner_scope->inner_scope_calls_eval_) {
+ new_parent->inner_scope_calls_eval_ = true;
+ }
new_parent->inner_scope_ = new_parent->sibling_;
inner_scope->sibling_ = nullptr;
// Reset the sibling rather than the inner_scope_ since we
@@ -860,6 +922,15 @@ void Scope::Snapshot::Reparent(DeclarationScope* new_parent) const {
}
outer_closure->locals_.Rewind(top_local_);
outer_closure->decls_.Rewind(top_decl_);
+
+ // Move eval calls since Snapshot's creation into new_parent.
+ if (outer_scope_->scope_calls_eval_) {
+ new_parent->scope_calls_eval_ = true;
+ new_parent->inner_scope_calls_eval_ = true;
+ }
+ // Reset the outer_scope's eval state. It will be restored to its
+ // original value as necessary in the destructor of this class.
+ outer_scope_->scope_calls_eval_ = false;
}
void Scope::ReplaceOuterScope(Scope* outer) {
@@ -871,15 +942,6 @@ void Scope::ReplaceOuterScope(Scope* outer) {
outer_scope_ = outer;
}
-
-void Scope::PropagateUsageFlagsToScope(Scope* other) {
- DCHECK_NOT_NULL(other);
- DCHECK(!already_resolved_);
- DCHECK(!other->already_resolved_);
- if (calls_eval()) other->RecordEvalCall();
- if (inner_scope_calls_eval_) other->inner_scope_calls_eval_ = true;
-}
-
Variable* Scope::LookupInScopeInfo(const AstRawString* name) {
Handle<String> name_handle = name->string();
// The Scope is backed up by ScopeInfo. This means it cannot operate in a
@@ -946,7 +1008,7 @@ Variable* Scope::Lookup(const AstRawString* name) {
Variable* DeclarationScope::DeclareParameter(
const AstRawString* name, VariableMode mode, bool is_optional, bool is_rest,
- bool* is_duplicate, AstValueFactory* ast_value_factory) {
+ bool* is_duplicate, AstValueFactory* ast_value_factory, int position) {
DCHECK(!already_resolved_);
DCHECK(is_function_scope() || is_module_scope());
DCHECK(!has_rest_);
@@ -963,6 +1025,7 @@ Variable* DeclarationScope::DeclareParameter(
*is_duplicate = IsDeclaredParameter(name);
}
has_rest_ = is_rest;
+ var->set_initializer_position(position);
params_.Add(var, zone());
if (name == ast_value_factory->arguments_string()) {
has_arguments_parameter_ = true;
@@ -1071,12 +1134,14 @@ Variable* Scope::DeclareVariable(
// will be a permitted duplicate.
FunctionKind function_kind =
declaration->AsFunctionDeclaration()->fun()->kind();
- duplicate_allowed =
- GetDeclarationScope()->sloppy_block_function_map()->Lookup(
- const_cast<AstRawString*>(name), name->hash()) != nullptr &&
- !IsAsyncFunction(function_kind) &&
- !(allow_harmony_restrictive_generators &&
- IsGeneratorFunction(function_kind));
+ SloppyBlockFunctionMap* map =
+ GetDeclarationScope()->sloppy_block_function_map();
+ duplicate_allowed = map != nullptr &&
+ map->Lookup(const_cast<AstRawString*>(name),
+ name->hash()) != nullptr &&
+ !IsAsyncFunction(function_kind) &&
+ !(allow_harmony_restrictive_generators &&
+ IsGeneratorFunction(function_kind));
}
if (duplicate_allowed) {
*sloppy_mode_block_scope_function_redefinition = true;
@@ -1264,7 +1329,8 @@ Declaration* Scope::CheckLexDeclarationsConflictingWith(
return nullptr;
}
-void DeclarationScope::AllocateVariables(ParseInfo* info, AnalyzeMode mode) {
+void DeclarationScope::AllocateVariables(ParseInfo* info, Isolate* isolate,
+ AnalyzeMode mode) {
// Module variables must be allocated before variable resolution
// to ensure that AccessNeedsHoleCheck() can detect import variables.
if (is_module_scope()) AsModuleScope()->AllocateModuleVariables();
@@ -1275,16 +1341,16 @@ void DeclarationScope::AllocateVariables(ParseInfo* info, AnalyzeMode mode) {
MaybeHandle<ScopeInfo> outer_scope;
if (outer_scope_ != nullptr) outer_scope = outer_scope_->scope_info_;
- AllocateScopeInfosRecursively(info->isolate(), outer_scope);
+ AllocateScopeInfosRecursively(isolate, outer_scope);
if (mode == AnalyzeMode::kDebugger) {
- AllocateDebuggerScopeInfos(info->isolate(), outer_scope);
+ AllocateDebuggerScopeInfos(isolate, outer_scope);
}
// The debugger expects all shared function infos to contain a scope info.
// Since the top-most scope will end up in a shared function info, make sure
// it has one, even if it doesn't need a scope info.
// TODO(jochen|yangguo): Remove this requirement.
if (scope_info_.is_null()) {
- scope_info_ = ScopeInfo::Create(info->isolate(), zone(), this, outer_scope);
+ scope_info_ = ScopeInfo::Create(isolate, zone(), this, outer_scope);
}
}
@@ -1439,12 +1505,12 @@ void DeclarationScope::ResetAfterPreparsing(AstValueFactory* ast_value_factory,
locals_.Clear();
inner_scope_ = nullptr;
unresolved_ = nullptr;
+ sloppy_block_function_map_ = nullptr;
if (aborted) {
// Prepare scope for use in the outer zone.
zone_ = ast_value_factory->zone();
variables_.Reset(ZoneAllocationPolicy(zone_));
- sloppy_block_function_map_.Reset(ZoneAllocationPolicy(zone_));
if (!IsArrowFunction(function_kind_)) {
DeclareDefaultFunctionVariables(ast_value_factory);
}
@@ -1452,7 +1518,6 @@ void DeclarationScope::ResetAfterPreparsing(AstValueFactory* ast_value_factory,
// Make sure this scope isn't used for allocation anymore.
zone_ = nullptr;
variables_.Invalidate();
- sloppy_block_function_map_.Invalidate();
}
#ifdef DEBUG
@@ -1487,11 +1552,10 @@ void DeclarationScope::AnalyzePartially(
arguments_ = nullptr;
}
- if (FLAG_preparser_scope_analysis) {
- // Decide context allocation for the locals and parameters and store the
- // info away.
- AllocateVariablesRecursively();
- CollectVariableData(preparsed_scope_data);
+ if (FLAG_preparser_scope_analysis && preparsed_scope_data->Producing()) {
+ // Store the information needed for allocating the locals of this scope
+ // and its inner scopes.
+ preparsed_scope_data->SaveData(this);
}
}
#ifdef DEBUG
@@ -1564,7 +1628,7 @@ void PrintVar(int indent, Variable* var) {
PrintF(".%p", reinterpret_cast<void*>(var));
else
PrintName(var->raw_name());
- PrintF("; // ");
+ PrintF("; // (%p) ", reinterpret_cast<void*>(var));
PrintLocation(var);
bool comma = !var->IsUnallocated();
if (var->has_forced_context_allocation()) {
@@ -1637,7 +1701,8 @@ void Scope::Print(int n) {
function = AsDeclarationScope()->function_var();
}
- PrintF(" { // (%d, %d)\n", start_position(), end_position());
+ PrintF(" { // (%p) (%d, %d)\n", reinterpret_cast<void*>(this),
+ start_position(), end_position());
if (is_hidden()) {
Indent(n1, "// is hidden\n");
}
@@ -2269,17 +2334,6 @@ void Scope::AllocateDebuggerScopeInfos(Isolate* isolate,
}
}
-void Scope::CollectVariableData(PreParsedScopeData* data) {
- PreParsedScopeData::ScopeScope scope_scope(data, scope_type(),
- start_position(), end_position());
- for (Variable* local : locals_) {
- scope_scope.MaybeAddVariable(local);
- }
- for (Scope* inner = inner_scope_; inner != nullptr; inner = inner->sibling_) {
- inner->CollectVariableData(data);
- }
-}
-
int Scope::StackLocalCount() const {
Variable* function =
is_function_scope() ? AsDeclarationScope()->function_var() : nullptr;
diff --git a/deps/v8/src/ast/scopes.h b/deps/v8/src/ast/scopes.h
index 119d77c5c8..c7de9e88ee 100644
--- a/deps/v8/src/ast/scopes.h
+++ b/deps/v8/src/ast/scopes.h
@@ -53,22 +53,27 @@ class SloppyBlockFunctionMap : public ZoneHashMap {
public:
class Delegate : public ZoneObject {
public:
- explicit Delegate(Scope* scope,
- SloppyBlockFunctionStatement* statement = nullptr)
- : scope_(scope), statement_(statement), next_(nullptr) {}
+ Delegate(Scope* scope, SloppyBlockFunctionStatement* statement, int index)
+ : scope_(scope), statement_(statement), next_(nullptr), index_(index) {}
void set_statement(Statement* statement);
void set_next(Delegate* next) { next_ = next; }
Delegate* next() const { return next_; }
Scope* scope() const { return scope_; }
+ int index() const { return index_; }
private:
Scope* scope_;
SloppyBlockFunctionStatement* statement_;
Delegate* next_;
+ int index_;
};
explicit SloppyBlockFunctionMap(Zone* zone);
- void Declare(Zone* zone, const AstRawString* name, Delegate* delegate);
+ void Declare(Zone* zone, const AstRawString* name, Scope* scope,
+ SloppyBlockFunctionStatement* statement);
+
+ private:
+ int count_;
};
enum class AnalyzeMode { kRegular, kDebugger };
@@ -112,6 +117,7 @@ class V8_EXPORT_PRIVATE Scope : public NON_EXPORTED_BASE(ZoneObject) {
class Snapshot final BASE_EMBEDDED {
public:
explicit Snapshot(Scope* scope);
+ ~Snapshot();
void Reparent(DeclarationScope* new_parent) const;
@@ -121,12 +127,12 @@ class V8_EXPORT_PRIVATE Scope : public NON_EXPORTED_BASE(ZoneObject) {
VariableProxy* top_unresolved_;
ThreadedList<Variable>::Iterator top_local_;
ThreadedList<Declaration>::Iterator top_decl_;
+ const bool outer_scope_calls_eval_;
};
enum class DeserializationMode { kIncludingVariables, kScopesOnly };
- static Scope* DeserializeScopeChain(Isolate* isolate, Zone* zone,
- ScopeInfo* scope_info,
+ static Scope* DeserializeScopeChain(Zone* zone, ScopeInfo* scope_info,
DeclarationScope* script_scope,
AstValueFactory* ast_value_factory,
DeserializationMode deserialization_mode);
@@ -146,12 +152,22 @@ class V8_EXPORT_PRIVATE Scope : public NON_EXPORTED_BASE(ZoneObject) {
// Assumes outer_scope_ is non-null.
void ReplaceOuterScope(Scope* outer_scope);
- // Propagates any eagerly-gathered scope usage flags (such as calls_eval())
- // to the passed-in scope.
- void PropagateUsageFlagsToScope(Scope* other);
-
Zone* zone() const { return zone_; }
+ void SetMustUsePreParsedScopeData() {
+ if (must_use_preparsed_scope_data_) {
+ return;
+ }
+ must_use_preparsed_scope_data_ = true;
+ if (outer_scope_) {
+ outer_scope_->SetMustUsePreParsedScopeData();
+ }
+ }
+
+ bool must_use_preparsed_scope_data() const {
+ return must_use_preparsed_scope_data_;
+ }
+
// ---------------------------------------------------------------------------
// Declarations
@@ -357,10 +373,10 @@ class V8_EXPORT_PRIVATE Scope : public NON_EXPORTED_BASE(ZoneObject) {
// The scope immediately surrounding this scope, or NULL.
Scope* outer_scope() const { return outer_scope_; }
- const AstRawString* catch_variable_name() const {
+ Variable* catch_variable() const {
DCHECK(is_catch_scope());
DCHECK_EQ(1, num_var());
- return static_cast<AstRawString*>(variables_.Start()->key);
+ return static_cast<Variable*>(variables_.Start()->value);
}
// ---------------------------------------------------------------------------
@@ -546,12 +562,15 @@ class V8_EXPORT_PRIVATE Scope : public NON_EXPORTED_BASE(ZoneObject) {
// Temporary workaround that allows masking of 'this' in debug-evalute scopes.
bool is_debug_evaluate_scope_ : 1;
+ // True if one of the inner scopes or the scope itself calls eval.
bool inner_scope_calls_eval_ : 1;
bool force_context_allocation_ : 1;
// True if it holds 'var' declarations.
bool is_declaration_scope_ : 1;
+ bool must_use_preparsed_scope_data_ : 1;
+
// Create a non-local variable with a given name.
// These variables are looked up dynamically at runtime.
Variable* NonLocal(const AstRawString* name, VariableMode mode);
@@ -590,14 +609,12 @@ class V8_EXPORT_PRIVATE Scope : public NON_EXPORTED_BASE(ZoneObject) {
void AllocateDebuggerScopeInfos(Isolate* isolate,
MaybeHandle<ScopeInfo> outer_scope);
- void CollectVariableData(PreParsedScopeData* data);
-
// Construct a scope based on the scope info.
Scope(Zone* zone, ScopeType type, Handle<ScopeInfo> scope_info);
// Construct a catch scope with a binding for the name.
Scope(Zone* zone, const AstRawString* catch_variable_name,
- Handle<ScopeInfo> scope_info);
+ MaybeAssignedFlag maybe_assigned, Handle<ScopeInfo> scope_info);
void AddInnerScope(Scope* inner_scope) {
inner_scope->sibling_ = inner_scope_;
@@ -686,13 +703,14 @@ class V8_EXPORT_PRIVATE DeclarationScope : public Scope {
// Ignition without ScopeInfo.
Variable* DeclareGeneratorObjectVar(const AstRawString* name);
Variable* DeclarePromiseVar(const AstRawString* name);
+ Variable* DeclareAsyncGeneratorAwaitVar(const AstRawString* name);
// Declare a parameter in this scope. When there are duplicated
// parameters the rightmost one 'wins'. However, the implementation
// expects all parameters to be declared and from left to right.
Variable* DeclareParameter(const AstRawString* name, VariableMode mode,
bool is_optional, bool is_rest, bool* is_duplicate,
- AstValueFactory* ast_value_factory);
+ AstValueFactory* ast_value_factory, int position);
// Declares that a parameter with the name exists. Creates a Variable and
// returns it if FLAG_preparser_scope_analysis is on.
@@ -738,9 +756,16 @@ class V8_EXPORT_PRIVATE DeclarationScope : public Scope {
Variable* promise_var() const {
DCHECK(is_function_scope());
DCHECK(IsAsyncFunction(function_kind_));
+ if (IsAsyncGeneratorFunction(function_kind_)) return nullptr;
return GetRareVariable(RareVariable::kPromise);
}
+ Variable* async_generator_await_var() const {
+ DCHECK(is_function_scope());
+ DCHECK(IsAsyncGeneratorFunction(function_kind_));
+ return GetRareVariable(RareVariable::kAsyncGeneratorAwaitResult);
+ }
+
// Parameters. The left-most parameter has index 0.
// Only valid for function and module scopes.
Variable* parameter(int index) const {
@@ -805,13 +830,13 @@ class V8_EXPORT_PRIVATE DeclarationScope : public Scope {
void HoistSloppyBlockFunctions(AstNodeFactory* factory);
SloppyBlockFunctionMap* sloppy_block_function_map() {
- return &sloppy_block_function_map_;
+ return sloppy_block_function_map_;
}
// Compute top scope and allocate variables. For lazy compilation the top
// scope only contains the single lazily compiled function, so this
// doesn't re-allocate variables repeatedly.
- static void Analyze(ParseInfo* info, AnalyzeMode mode);
+ static void Analyze(ParseInfo* info, Isolate* isolate, AnalyzeMode mode);
// To be called during parsing. Do just enough scope analysis that we can
// discard the Scope for lazily compiled functions. In particular, this
@@ -848,6 +873,11 @@ class V8_EXPORT_PRIVATE DeclarationScope : public Scope {
void ResetAfterPreparsing(AstValueFactory* ast_value_factory, bool aborted);
+ bool is_skipped_function() const { return is_skipped_function_; }
+ void set_is_skipped_function(bool is_skipped_function) {
+ is_skipped_function_ = is_skipped_function;
+ }
+
private:
void AllocateParameter(Variable* var, int index);
@@ -859,7 +889,7 @@ class V8_EXPORT_PRIVATE DeclarationScope : public Scope {
// In the case of code compiled and run using 'eval', the context
// parameter is the context in which eval was called. In all other
// cases the context parameter is an empty handle.
- void AllocateVariables(ParseInfo* info, AnalyzeMode mode);
+ void AllocateVariables(ParseInfo* info, Isolate* isolate, AnalyzeMode mode);
void SetDefaults();
@@ -884,11 +914,12 @@ class V8_EXPORT_PRIVATE DeclarationScope : public Scope {
#if DEBUG
bool is_being_lazily_parsed_ : 1;
#endif
+ bool is_skipped_function_ : 1;
// Parameter list in source order.
ZoneList<Variable*> params_;
// Map of function names to lists of functions defined in sloppy blocks
- SloppyBlockFunctionMap sloppy_block_function_map_;
+ SloppyBlockFunctionMap* sloppy_block_function_map_;
// Convenience variable.
Variable* receiver_;
// Function variable, if any; function scopes only.
@@ -912,7 +943,8 @@ class V8_EXPORT_PRIVATE DeclarationScope : public Scope {
enum class RareVariable {
kThisFunction = offsetof(RareData, this_function),
kGeneratorObject = offsetof(RareData, generator_object),
- kPromise = offsetof(RareData, promise)
+ kPromise = offsetof(RareData, promise),
+ kAsyncGeneratorAwaitResult = kPromise
};
V8_INLINE RareData* EnsureRareData() {
@@ -950,8 +982,7 @@ class ModuleScope final : public DeclarationScope {
// The generated ModuleDescriptor does not preserve all information. In
// particular, its module_requests map will be empty because we no longer need
// the map after parsing.
- ModuleScope(Isolate* isolate, Handle<ScopeInfo> scope_info,
- AstValueFactory* ast_value_factory);
+ ModuleScope(Handle<ScopeInfo> scope_info, AstValueFactory* ast_value_factory);
ModuleDescriptor* module() const {
DCHECK_NOT_NULL(module_descriptor_);
diff --git a/deps/v8/src/ast/variables.h b/deps/v8/src/ast/variables.h
index b7d9226b1c..3eaa105168 100644
--- a/deps/v8/src/ast/variables.h
+++ b/deps/v8/src/ast/variables.h
@@ -100,6 +100,12 @@ class Variable final : public ZoneObject {
int index() const { return index_; }
+ bool IsReceiver() const {
+ DCHECK(IsParameter());
+
+ return index_ == -1;
+ }
+
bool IsExport() const {
DCHECK_EQ(location(), VariableLocation::MODULE);
DCHECK_NE(index(), 0);