summaryrefslogtreecommitdiff
path: root/chromium/v8/src/ast
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/v8/src/ast')
-rw-r--r--chromium/v8/src/ast/ast-function-literal-id-reindexer.cc4
-rw-r--r--chromium/v8/src/ast/ast-function-literal-id-reindexer.h5
-rw-r--r--chromium/v8/src/ast/ast-source-ranges.h19
-rw-r--r--chromium/v8/src/ast/ast-traversal-visitor.h37
-rw-r--r--chromium/v8/src/ast/ast-value-factory.cc128
-rw-r--r--chromium/v8/src/ast/ast-value-factory.h137
-rw-r--r--chromium/v8/src/ast/ast.cc16
-rw-r--r--chromium/v8/src/ast/ast.h216
-rw-r--r--chromium/v8/src/ast/modules.cc52
-rw-r--r--chromium/v8/src/ast/modules.h46
-rw-r--r--chromium/v8/src/ast/prettyprinter.cc104
-rw-r--r--chromium/v8/src/ast/prettyprinter.h3
-rw-r--r--chromium/v8/src/ast/scopes.cc115
-rw-r--r--chromium/v8/src/ast/scopes.h65
14 files changed, 619 insertions, 328 deletions
diff --git a/chromium/v8/src/ast/ast-function-literal-id-reindexer.cc b/chromium/v8/src/ast/ast-function-literal-id-reindexer.cc
index 8c9318bfe74..298e9ea14f7 100644
--- a/chromium/v8/src/ast/ast-function-literal-id-reindexer.cc
+++ b/chromium/v8/src/ast/ast-function-literal-id-reindexer.cc
@@ -40,8 +40,8 @@ void AstFunctionLiteralIdReindexer::VisitClassLiteral(ClassLiteral* expr) {
Visit(expr->extends());
}
Visit(expr->constructor());
- if (expr->static_fields_initializer() != nullptr) {
- Visit(expr->static_fields_initializer());
+ if (expr->static_initializer() != nullptr) {
+ Visit(expr->static_initializer());
}
if (expr->instance_members_initializer_function() != nullptr) {
Visit(expr->instance_members_initializer_function());
diff --git a/chromium/v8/src/ast/ast-function-literal-id-reindexer.h b/chromium/v8/src/ast/ast-function-literal-id-reindexer.h
index f4dac7b01e6..2c1eb108afd 100644
--- a/chromium/v8/src/ast/ast-function-literal-id-reindexer.h
+++ b/chromium/v8/src/ast/ast-function-literal-id-reindexer.h
@@ -21,6 +21,9 @@ class AstFunctionLiteralIdReindexer final
: public AstTraversalVisitor<AstFunctionLiteralIdReindexer> {
public:
AstFunctionLiteralIdReindexer(size_t stack_limit, int delta);
+ AstFunctionLiteralIdReindexer(const AstFunctionLiteralIdReindexer&) = delete;
+ AstFunctionLiteralIdReindexer& operator=(
+ const AstFunctionLiteralIdReindexer&) = delete;
~AstFunctionLiteralIdReindexer();
void Reindex(Expression* pattern);
@@ -42,8 +45,6 @@ class AstFunctionLiteralIdReindexer final
#else
void CheckVisited(Expression* expr) {}
#endif
-
- DISALLOW_COPY_AND_ASSIGN(AstFunctionLiteralIdReindexer);
};
} // namespace internal
diff --git a/chromium/v8/src/ast/ast-source-ranges.h b/chromium/v8/src/ast/ast-source-ranges.h
index 1b42a055dd6..1e96ec4c27c 100644
--- a/chromium/v8/src/ast/ast-source-ranges.h
+++ b/chromium/v8/src/ast/ast-source-ranges.h
@@ -47,6 +47,7 @@ struct SourceRange {
V(Block) \
V(CaseClause) \
V(Conditional) \
+ V(Expression) \
V(FunctionLiteral) \
V(IfStatement) \
V(IterationStatement) \
@@ -281,6 +282,24 @@ class NaryOperationSourceRanges final : public AstNodeSourceRanges {
ZoneVector<SourceRange> ranges_;
};
+class ExpressionSourceRanges final : public AstNodeSourceRanges {
+ public:
+ explicit ExpressionSourceRanges(const SourceRange& right_range)
+ : right_range_(right_range) {}
+
+ SourceRange GetRange(SourceRangeKind kind) override {
+ DCHECK(HasRange(kind));
+ return right_range_;
+ }
+
+ bool HasRange(SourceRangeKind kind) override {
+ return kind == SourceRangeKind::kRight;
+ }
+
+ private:
+ SourceRange right_range_;
+};
+
class SuspendSourceRanges final : public ContinuationSourceRanges {
public:
explicit SuspendSourceRanges(int32_t continuation_position)
diff --git a/chromium/v8/src/ast/ast-traversal-visitor.h b/chromium/v8/src/ast/ast-traversal-visitor.h
index 8a1f8b2f16e..a9e3500931a 100644
--- a/chromium/v8/src/ast/ast-traversal-visitor.h
+++ b/chromium/v8/src/ast/ast-traversal-visitor.h
@@ -30,6 +30,8 @@ class AstTraversalVisitor : public AstVisitor<Subclass> {
public:
explicit AstTraversalVisitor(Isolate* isolate, AstNode* root = nullptr);
explicit AstTraversalVisitor(uintptr_t stack_limit, AstNode* root = nullptr);
+ AstTraversalVisitor(const AstTraversalVisitor&) = delete;
+ AstTraversalVisitor& operator=(const AstTraversalVisitor&) = delete;
void Run() {
DCHECK_NOT_NULL(root_);
@@ -56,8 +58,6 @@ class AstTraversalVisitor : public AstVisitor<Subclass> {
AstNode* root_;
int depth_;
-
- DISALLOW_COPY_AND_ASSIGN(AstTraversalVisitor);
};
// ----------------------------------------------------------------------------
@@ -469,8 +469,8 @@ void AstTraversalVisitor<Subclass>::VisitClassLiteral(ClassLiteral* expr) {
RECURSE_EXPRESSION(Visit(expr->extends()));
}
RECURSE_EXPRESSION(Visit(expr->constructor()));
- if (expr->static_fields_initializer() != nullptr) {
- RECURSE_EXPRESSION(Visit(expr->static_fields_initializer()));
+ if (expr->static_initializer() != nullptr) {
+ RECURSE_EXPRESSION(Visit(expr->static_initializer()));
}
if (expr->instance_members_initializer_function() != nullptr) {
RECURSE_EXPRESSION(Visit(expr->instance_members_initializer_function()));
@@ -506,6 +506,29 @@ void AstTraversalVisitor<Subclass>::VisitInitializeClassMembersStatement(
}
template <class Subclass>
+void AstTraversalVisitor<Subclass>::VisitInitializeClassStaticElementsStatement(
+ InitializeClassStaticElementsStatement* stmt) {
+ PROCESS_NODE(stmt);
+ ZonePtrList<ClassLiteral::StaticElement>* elements = stmt->elements();
+ for (int i = 0; i < elements->length(); ++i) {
+ ClassLiteral::StaticElement* element = elements->at(i);
+ switch (element->kind()) {
+ case ClassLiteral::StaticElement::PROPERTY: {
+ ClassLiteral::Property* prop = element->property();
+ if (!prop->key()->IsLiteral()) {
+ RECURSE(Visit(prop->key()));
+ }
+ RECURSE(Visit(prop->value()));
+ break;
+ }
+ case ClassLiteral::StaticElement::STATIC_BLOCK:
+ RECURSE(Visit(element->static_block()));
+ break;
+ }
+ }
+}
+
+template <class Subclass>
void AstTraversalVisitor<Subclass>::VisitSpread(Spread* expr) {
PROCESS_EXPRESSION(expr);
RECURSE_EXPRESSION(Visit(expr->expression()));
@@ -536,14 +559,16 @@ template <class Subclass>
void AstTraversalVisitor<Subclass>::VisitImportCallExpression(
ImportCallExpression* expr) {
PROCESS_EXPRESSION(expr);
- RECURSE_EXPRESSION(Visit(expr->argument()));
+ RECURSE_EXPRESSION(Visit(expr->specifier()));
+ if (expr->import_assertions()) {
+ RECURSE_EXPRESSION(Visit(expr->import_assertions()));
+ }
}
template <class Subclass>
void AstTraversalVisitor<Subclass>::VisitSuperPropertyReference(
SuperPropertyReference* expr) {
PROCESS_EXPRESSION(expr);
- RECURSE_EXPRESSION(Visit(expr->home_object()));
}
template <class Subclass>
diff --git a/chromium/v8/src/ast/ast-value-factory.cc b/chromium/v8/src/ast/ast-value-factory.cc
index b5a39b22cf3..6e454b22f1d 100644
--- a/chromium/v8/src/ast/ast-value-factory.cc
+++ b/chromium/v8/src/ast/ast-value-factory.cc
@@ -29,6 +29,7 @@
#include "src/base/hashmap-entry.h"
#include "src/base/logging.h"
+#include "src/base/platform/wrappers.h"
#include "src/common/globals.h"
#include "src/heap/factory-inl.h"
#include "src/heap/local-factory-inl.h"
@@ -66,10 +67,10 @@ void AstRawString::Internalize(LocalIsolate* isolate) {
if (literal_bytes_.length() == 0) {
set_string(isolate->factory()->empty_string());
} else if (is_one_byte()) {
- OneByteStringKey key(hash_field_, literal_bytes_);
+ OneByteStringKey key(raw_hash_field_, literal_bytes_);
set_string(isolate->factory()->InternalizeStringWithKey(&key));
} else {
- TwoByteStringKey key(hash_field_,
+ TwoByteStringKey key(raw_hash_field_,
Vector<const uint16_t>::cast(literal_bytes_));
set_string(isolate->factory()->InternalizeStringWithKey(&key));
}
@@ -83,9 +84,9 @@ template EXPORT_TEMPLATE_DEFINE(
bool AstRawString::AsArrayIndex(uint32_t* index) const {
// The StringHasher will set up the hash. Bail out early if we know it
// can't be convertible to an array index.
- if ((hash_field_ & Name::kIsNotIntegerIndexMask) != 0) return false;
+ if ((raw_hash_field_ & Name::kIsNotIntegerIndexMask) != 0) return false;
if (length() <= Name::kMaxCachedArrayIndexLength) {
- *index = Name::ArrayIndexValueBits::decode(hash_field_);
+ *index = Name::ArrayIndexValueBits::decode(raw_hash_field_);
return true;
}
// Might be an index, but too big to cache it. Do the slow conversion. This
@@ -96,7 +97,7 @@ bool AstRawString::AsArrayIndex(uint32_t* index) const {
}
bool AstRawString::IsIntegerIndex() const {
- return (hash_field_ & Name::kIsNotIntegerIndexMask) == 0;
+ return (raw_hash_field_ & Name::kIsNotIntegerIndexMask) == 0;
}
bool AstRawString::IsOneByteEqualTo(const char* data) const {
@@ -115,7 +116,7 @@ uint16_t AstRawString::FirstCharacter() const {
return *c;
}
-bool AstRawString::Compare(const AstRawString* lhs, const AstRawString* rhs) {
+bool AstRawString::Equal(const AstRawString* lhs, const AstRawString* rhs) {
DCHECK_EQ(lhs->Hash(), rhs->Hash());
if (lhs->length() != rhs->length()) return false;
@@ -125,27 +126,65 @@ bool AstRawString::Compare(const AstRawString* lhs, const AstRawString* rhs) {
size_t length = rhs->length();
if (lhs->is_one_byte()) {
if (rhs->is_one_byte()) {
- return CompareCharsUnsigned(reinterpret_cast<const uint8_t*>(l),
- reinterpret_cast<const uint8_t*>(r),
- length) == 0;
+ return CompareCharsEqualUnsigned(reinterpret_cast<const uint8_t*>(l),
+ reinterpret_cast<const uint8_t*>(r),
+ length);
} else {
- return CompareCharsUnsigned(reinterpret_cast<const uint8_t*>(l),
- reinterpret_cast<const uint16_t*>(r),
- length) == 0;
+ return CompareCharsEqualUnsigned(reinterpret_cast<const uint8_t*>(l),
+ reinterpret_cast<const uint16_t*>(r),
+ length);
}
} else {
if (rhs->is_one_byte()) {
- return CompareCharsUnsigned(reinterpret_cast<const uint16_t*>(l),
- reinterpret_cast<const uint8_t*>(r),
- length) == 0;
+ return CompareCharsEqualUnsigned(reinterpret_cast<const uint16_t*>(l),
+ reinterpret_cast<const uint8_t*>(r),
+ length);
} else {
- return CompareCharsUnsigned(reinterpret_cast<const uint16_t*>(l),
- reinterpret_cast<const uint16_t*>(r),
- length) == 0;
+ return CompareCharsEqualUnsigned(reinterpret_cast<const uint16_t*>(l),
+ reinterpret_cast<const uint16_t*>(r),
+ length);
}
}
}
+int AstRawString::Compare(const AstRawString* lhs, const AstRawString* rhs) {
+ // Fast path for equal pointers.
+ if (lhs == rhs) return 0;
+
+ const unsigned char* lhs_data = lhs->raw_data();
+ const unsigned char* rhs_data = rhs->raw_data();
+ size_t length = std::min(lhs->length(), rhs->length());
+
+ // Code point order by contents.
+ if (lhs->is_one_byte()) {
+ if (rhs->is_one_byte()) {
+ if (int result = CompareCharsUnsigned(
+ reinterpret_cast<const uint8_t*>(lhs_data),
+ reinterpret_cast<const uint8_t*>(rhs_data), length))
+ return result;
+ } else {
+ if (int result = CompareCharsUnsigned(
+ reinterpret_cast<const uint8_t*>(lhs_data),
+ reinterpret_cast<const uint16_t*>(rhs_data), length))
+ return result;
+ }
+ } else {
+ if (rhs->is_one_byte()) {
+ if (int result = CompareCharsUnsigned(
+ reinterpret_cast<const uint16_t*>(lhs_data),
+ reinterpret_cast<const uint8_t*>(rhs_data), length))
+ return result;
+ } else {
+ if (int result = CompareCharsUnsigned(
+ reinterpret_cast<const uint16_t*>(lhs_data),
+ reinterpret_cast<const uint16_t*>(rhs_data), length))
+ return result;
+ }
+ }
+
+ return lhs->byte_length() - rhs->byte_length();
+}
+
template <typename LocalIsolate>
Handle<String> AstConsString::Allocate(LocalIsolate* isolate) const {
DCHECK(string_.is_null());
@@ -193,7 +232,7 @@ Handle<String> AstConsString::AllocateFlat(LocalIsolate* isolate) const {
isolate->factory()
->NewRawOneByteString(result_length, AllocationType::kOld)
.ToHandleChecked();
- DisallowHeapAllocation no_gc;
+ DisallowGarbageCollection no_gc;
uint8_t* dest =
result->GetChars(no_gc, SharedStringAccessGuardIfNeeded::NotNeeded()) +
result_length;
@@ -212,7 +251,7 @@ Handle<String> AstConsString::AllocateFlat(LocalIsolate* isolate) const {
isolate->factory()
->NewRawTwoByteString(result_length, AllocationType::kOld)
.ToHandleChecked();
- DisallowHeapAllocation no_gc;
+ DisallowGarbageCollection no_gc;
uint16_t* dest =
result->GetChars(no_gc, SharedStringAccessGuardIfNeeded::NotNeeded()) +
result_length;
@@ -257,18 +296,18 @@ AstStringConstants::AstStringConstants(Isolate* isolate, uint64_t hash_seed)
string_table_(),
hash_seed_(hash_seed) {
DCHECK_EQ(ThreadId::Current(), isolate->thread_id());
-#define F(name, str) \
- { \
- const char* data = str; \
- Vector<const uint8_t> literal(reinterpret_cast<const uint8_t*>(data), \
- static_cast<int>(strlen(data))); \
- uint32_t hash_field = StringHasher::HashSequentialString<uint8_t>( \
- literal.begin(), literal.length(), hash_seed_); \
- name##_string_ = zone_.New<AstRawString>(true, literal, hash_field); \
- /* The Handle returned by the factory is located on the roots */ \
- /* array, not on the temporary HandleScope, so this is safe. */ \
- name##_string_->set_string(isolate->factory()->name##_string()); \
- string_table_.InsertNew(name##_string_, name##_string_->Hash()); \
+#define F(name, str) \
+ { \
+ const char* data = str; \
+ Vector<const uint8_t> literal(reinterpret_cast<const uint8_t*>(data), \
+ static_cast<int>(strlen(data))); \
+ uint32_t raw_hash_field = StringHasher::HashSequentialString<uint8_t>( \
+ literal.begin(), literal.length(), hash_seed_); \
+ name##_string_ = zone_.New<AstRawString>(true, literal, raw_hash_field); \
+ /* The Handle returned by the factory is located on the roots */ \
+ /* array, not on the temporary HandleScope, so this is safe. */ \
+ name##_string_->set_string(isolate->factory()->name##_string()); \
+ string_table_.InsertNew(name##_string_, name##_string_->Hash()); \
}
AST_STRING_CONSTANTS(F)
#undef F
@@ -279,27 +318,27 @@ const AstRawString* AstValueFactory::GetOneByteStringInternal(
if (literal.length() == 1 && literal[0] < kMaxOneCharStringValue) {
int key = literal[0];
if (V8_UNLIKELY(one_character_strings_[key] == nullptr)) {
- uint32_t hash_field = StringHasher::HashSequentialString<uint8_t>(
+ uint32_t raw_hash_field = StringHasher::HashSequentialString<uint8_t>(
literal.begin(), literal.length(), hash_seed_);
- one_character_strings_[key] = GetString(hash_field, true, literal);
+ one_character_strings_[key] = GetString(raw_hash_field, true, literal);
}
return one_character_strings_[key];
}
- uint32_t hash_field = StringHasher::HashSequentialString<uint8_t>(
+ uint32_t raw_hash_field = StringHasher::HashSequentialString<uint8_t>(
literal.begin(), literal.length(), hash_seed_);
- return GetString(hash_field, true, literal);
+ return GetString(raw_hash_field, true, literal);
}
const AstRawString* AstValueFactory::GetTwoByteStringInternal(
Vector<const uint16_t> literal) {
- uint32_t hash_field = StringHasher::HashSequentialString<uint16_t>(
+ uint32_t raw_hash_field = StringHasher::HashSequentialString<uint16_t>(
literal.begin(), literal.length(), hash_seed_);
- return GetString(hash_field, false, Vector<const byte>::cast(literal));
+ return GetString(raw_hash_field, false, Vector<const byte>::cast(literal));
}
const AstRawString* AstValueFactory::GetString(Handle<String> literal) {
const AstRawString* result = nullptr;
- DisallowHeapAllocation no_gc;
+ DisallowGarbageCollection no_gc;
String::FlatContent content = literal->GetFlatContent(no_gc);
if (content.IsOneByte()) {
result = GetOneByteStringInternal(content.ToOneByteVector());
@@ -313,7 +352,7 @@ const AstRawString* AstValueFactory::GetString(Handle<String> literal) {
const AstRawString* AstValueFactory::CloneFromOtherFactory(
const AstRawString* raw_string) {
const AstRawString* result = GetString(
- raw_string->hash_field(), raw_string->is_one_byte(),
+ raw_string->raw_hash_field(), raw_string->is_one_byte(),
Vector<const byte>(raw_string->raw_data(), raw_string->byte_length()));
return result;
}
@@ -352,22 +391,23 @@ template EXPORT_TEMPLATE_DEFINE(
V8_EXPORT_PRIVATE) void AstValueFactory::Internalize(LocalIsolate* isolate);
const AstRawString* AstValueFactory::GetString(
- uint32_t hash_field, bool is_one_byte, Vector<const byte> literal_bytes) {
+ uint32_t raw_hash_field, bool is_one_byte,
+ Vector<const byte> literal_bytes) {
// literal_bytes here points to whatever the user passed, and this is OK
// because we use vector_compare (which checks the contents) to compare
// against the AstRawStrings which are in the string_table_. We should not
// return this AstRawString.
- AstRawString key(is_one_byte, literal_bytes, hash_field);
+ AstRawString key(is_one_byte, literal_bytes, raw_hash_field);
AstRawStringMap::Entry* entry = string_table_.LookupOrInsert(
&key, key.Hash(),
[&]() {
// Copy literal contents for later comparison.
int length = literal_bytes.length();
byte* new_literal_bytes = zone()->NewArray<byte>(length);
- memcpy(new_literal_bytes, literal_bytes.begin(), length);
+ base::Memcpy(new_literal_bytes, literal_bytes.begin(), length);
AstRawString* new_string = zone()->New<AstRawString>(
is_one_byte, Vector<const byte>(new_literal_bytes, length),
- hash_field);
+ raw_hash_field);
CHECK_NOT_NULL(new_string);
AddString(new_string);
return new_string;
diff --git a/chromium/v8/src/ast/ast-value-factory.h b/chromium/v8/src/ast/ast-value-factory.h
index 776b45a670e..b66e11f99fa 100644
--- a/chromium/v8/src/ast/ast-value-factory.h
+++ b/chromium/v8/src/ast/ast-value-factory.h
@@ -48,7 +48,12 @@ class Isolate;
class AstRawString final : public ZoneObject {
public:
- static bool Compare(const AstRawString* a, const AstRawString* b);
+ static bool Equal(const AstRawString* lhs, const AstRawString* rhs);
+
+ // Returns 0 if lhs is equal to rhs.
+ // Returns <0 if lhs is less than rhs in code point order.
+ // Returns >0 if lhs is greater than than rhs in code point order.
+ static int Compare(const AstRawString* lhs, const AstRawString* rhs);
bool IsEmpty() const { return literal_bytes_.length() == 0; }
int length() const {
@@ -71,8 +76,12 @@ class AstRawString final : public ZoneObject {
bool IsPrivateName() const { return length() > 0 && FirstCharacter() == '#'; }
// For storing AstRawStrings in a hash map.
- uint32_t hash_field() const { return hash_field_; }
- uint32_t Hash() const { return hash_field_ >> Name::kHashShift; }
+ uint32_t raw_hash_field() const { return raw_hash_field_; }
+ uint32_t Hash() const {
+ // Hash field must be computed.
+ DCHECK_EQ(raw_hash_field_ & Name::kHashNotComputedMask, 0);
+ return raw_hash_field_ >> Name::kHashShift;
+ }
// This function can be called after internalizing.
V8_INLINE Handle<String> string() const {
@@ -88,10 +97,10 @@ class AstRawString final : public ZoneObject {
// Members accessed only by the AstValueFactory & related classes:
AstRawString(bool is_one_byte, const Vector<const byte>& literal_bytes,
- uint32_t hash_field)
+ uint32_t raw_hash_field)
: next_(nullptr),
literal_bytes_(literal_bytes),
- hash_field_(hash_field),
+ raw_hash_field_(raw_hash_field),
is_one_byte_(is_one_byte) {}
AstRawString* next() {
DCHECK(!has_string_);
@@ -117,7 +126,7 @@ class AstRawString final : public ZoneObject {
};
Vector<const byte> literal_bytes_; // Memory owned by Zone.
- uint32_t hash_field_;
+ uint32_t raw_hash_field_;
bool is_one_byte_;
#ifdef DEBUG
// (Debug-only:) Verify the object life-cylce: Some functions may only be
@@ -191,8 +200,6 @@ class AstConsString final : public ZoneObject {
Segment segment_;
};
-enum class AstSymbol : uint8_t { kHomeObjectSymbol };
-
class AstBigInt {
public:
// |bigint| must be a NUL-terminated string of ASCII characters
@@ -210,7 +217,7 @@ struct AstRawStringMapMatcher {
bool operator()(uint32_t hash1, uint32_t hash2,
const AstRawString* lookup_key,
const AstRawString* entry_key) const {
- return hash1 == hash2 && AstRawString::Compare(lookup_key, entry_key);
+ return hash1 == hash2 && AstRawString::Equal(lookup_key, entry_key);
}
};
@@ -220,63 +227,67 @@ using AstRawStringMap =
base::DefaultAllocationPolicy>;
// For generating constants.
-#define AST_STRING_CONSTANTS(F) \
- F(anonymous, "anonymous") \
- F(anonymous_function, "(anonymous function)") \
- F(arguments, "arguments") \
- F(as, "as") \
- F(assert, "assert") \
- F(async, "async") \
- F(await, "await") \
- F(bigint, "bigint") \
- F(boolean, "boolean") \
- F(computed, "<computed>") \
- F(dot_brand, ".brand") \
- F(constructor, "constructor") \
- F(default, "default") \
- F(done, "done") \
- F(dot, ".") \
- F(dot_default, ".default") \
- F(dot_for, ".for") \
- F(dot_generator_object, ".generator_object") \
- F(dot_result, ".result") \
- F(dot_repl_result, ".repl_result") \
- F(dot_switch_tag, ".switch_tag") \
- F(dot_catch, ".catch") \
- F(empty, "") \
- F(eval, "eval") \
- F(from, "from") \
- F(function, "function") \
- F(get, "get") \
- F(get_space, "get ") \
- F(length, "length") \
- F(let, "let") \
- F(meta, "meta") \
- F(name, "name") \
- F(native, "native") \
- F(new_target, ".new.target") \
- F(next, "next") \
- F(number, "number") \
- F(object, "object") \
- F(of, "of") \
- F(private_constructor, "#constructor") \
- F(proto, "__proto__") \
- F(prototype, "prototype") \
- F(return, "return") \
- F(set, "set") \
- F(set_space, "set ") \
- F(string, "string") \
- F(symbol, "symbol") \
- F(target, "target") \
- F(this, "this") \
- F(this_function, ".this_function") \
- F(throw, "throw") \
- F(undefined, "undefined") \
+#define AST_STRING_CONSTANTS(F) \
+ F(anonymous, "anonymous") \
+ F(anonymous_function, "(anonymous function)") \
+ F(arguments, "arguments") \
+ F(as, "as") \
+ F(assert, "assert") \
+ F(async, "async") \
+ F(await, "await") \
+ F(bigint, "bigint") \
+ F(boolean, "boolean") \
+ F(computed, "<computed>") \
+ F(dot_brand, ".brand") \
+ F(constructor, "constructor") \
+ F(default, "default") \
+ F(done, "done") \
+ F(dot, ".") \
+ F(dot_default, ".default") \
+ F(dot_for, ".for") \
+ F(dot_generator_object, ".generator_object") \
+ F(dot_home_object, ".home_object") \
+ F(dot_result, ".result") \
+ F(dot_repl_result, ".repl_result") \
+ F(dot_static_home_object, ".static_home_object") \
+ F(dot_switch_tag, ".switch_tag") \
+ F(dot_catch, ".catch") \
+ F(empty, "") \
+ F(eval, "eval") \
+ F(from, "from") \
+ F(function, "function") \
+ F(get, "get") \
+ F(get_space, "get ") \
+ F(length, "length") \
+ F(let, "let") \
+ F(meta, "meta") \
+ F(name, "name") \
+ F(native, "native") \
+ F(new_target, ".new.target") \
+ F(next, "next") \
+ F(number, "number") \
+ F(object, "object") \
+ F(of, "of") \
+ F(private_constructor, "#constructor") \
+ F(proto, "__proto__") \
+ F(prototype, "prototype") \
+ F(return, "return") \
+ F(set, "set") \
+ F(set_space, "set ") \
+ F(string, "string") \
+ F(symbol, "symbol") \
+ F(target, "target") \
+ F(this, "this") \
+ F(this_function, ".this_function") \
+ F(throw, "throw") \
+ F(undefined, "undefined") \
F(value, "value")
class AstStringConstants final {
public:
AstStringConstants(Isolate* isolate, uint64_t hash_seed);
+ AstStringConstants(const AstStringConstants&) = delete;
+ AstStringConstants& operator=(const AstStringConstants&) = delete;
#define F(name, str) \
const AstRawString* name##_string() const { return name##_string_; }
@@ -294,8 +305,6 @@ class AstStringConstants final {
#define F(name, str) AstRawString* name##_string_;
AST_STRING_CONSTANTS(F)
#undef F
-
- DISALLOW_COPY_AND_ASSIGN(AstStringConstants);
};
class AstValueFactory {
@@ -369,7 +378,7 @@ class AstValueFactory {
V8_EXPORT_PRIVATE const AstRawString* GetOneByteStringInternal(
Vector<const uint8_t> literal);
const AstRawString* GetTwoByteStringInternal(Vector<const uint16_t> literal);
- const AstRawString* GetString(uint32_t hash, bool is_one_byte,
+ const AstRawString* GetString(uint32_t raw_hash_field, bool is_one_byte,
Vector<const byte> literal_bytes);
// All strings are copied here.
diff --git a/chromium/v8/src/ast/ast.cc b/chromium/v8/src/ast/ast.cc
index e8c7796abc2..9eddb14e613 100644
--- a/chromium/v8/src/ast/ast.cc
+++ b/chromium/v8/src/ast/ast.cc
@@ -11,6 +11,7 @@
#include "src/ast/scopes.h"
#include "src/base/hashmap.h"
#include "src/base/logging.h"
+#include "src/base/platform/wrappers.h"
#include "src/builtins/builtins-constructor.h"
#include "src/builtins/builtins.h"
#include "src/common/assert-scope.h"
@@ -235,12 +236,6 @@ LanguageMode FunctionLiteral::language_mode() const {
FunctionKind FunctionLiteral::kind() const { return scope()->function_kind(); }
-bool FunctionLiteral::NeedsHomeObject(Expression* expr) {
- if (expr == nullptr || !expr->IsFunctionLiteral()) return false;
- DCHECK_NOT_NULL(expr->AsFunctionLiteral()->scope());
- return expr->AsFunctionLiteral()->scope()->NeedsHomeObject();
-}
-
std::unique_ptr<char[]> FunctionLiteral::GetDebugName() const {
const AstConsString* cons_string;
if (raw_name_ != nullptr && !raw_name_->IsEmpty()) {
@@ -266,7 +261,7 @@ std::unique_ptr<char[]> FunctionLiteral::GetDebugName() const {
}
}
std::unique_ptr<char[]> result(new char[result_vec.size() + 1]);
- memcpy(result.get(), result_vec.data(), result_vec.size());
+ base::Memcpy(result.get(), result_vec.data(), result_vec.size());
result[result_vec.size()] = '\0';
return result;
}
@@ -580,7 +575,6 @@ int ArrayLiteral::InitDepthAndFlags() {
break;
case Literal::kBigInt:
case Literal::kString:
- case Literal::kSymbol:
case Literal::kBoolean:
case Literal::kUndefined:
case Literal::kNull:
@@ -654,7 +648,7 @@ void ArrayLiteral::BuildBoilerplateDescription(LocalIsolate* isolate) {
Object boilerplate_value = *GetBoilerplateValue(element, isolate);
// We shouldn't allocate after creating the boilerplate value.
- DisallowHeapAllocation no_gc;
+ DisallowGarbageCollection no_gc;
if (boilerplate_value.IsTheHole(isolate)) {
DCHECK(IsHoleyElementsKind(kind));
@@ -980,8 +974,6 @@ Handle<Object> Literal::BuildValue(LocalIsolate* isolate) const {
number_);
case kString:
return string_->string();
- case kSymbol:
- return isolate->factory()->home_object_symbol();
case kBoolean:
return isolate->factory()->ToBoolean(boolean_);
case kNull:
@@ -1027,8 +1019,6 @@ bool Literal::ToBooleanIsTrue() const {
}
return false;
}
- case kSymbol:
- return true;
case kTheHole:
UNREACHABLE();
}
diff --git a/chromium/v8/src/ast/ast.h b/chromium/v8/src/ast/ast.h
index 7b70181e6a0..50a0c55d4d7 100644
--- a/chromium/v8/src/ast/ast.h
+++ b/chromium/v8/src/ast/ast.h
@@ -54,21 +54,22 @@ namespace internal {
V(Block) \
V(SwitchStatement)
-#define STATEMENT_NODE_LIST(V) \
- ITERATION_NODE_LIST(V) \
- BREAKABLE_NODE_LIST(V) \
- V(ExpressionStatement) \
- V(EmptyStatement) \
- V(SloppyBlockFunctionStatement) \
- V(IfStatement) \
- V(ContinueStatement) \
- V(BreakStatement) \
- V(ReturnStatement) \
- V(WithStatement) \
- V(TryCatchStatement) \
- V(TryFinallyStatement) \
- V(DebuggerStatement) \
- V(InitializeClassMembersStatement)
+#define STATEMENT_NODE_LIST(V) \
+ ITERATION_NODE_LIST(V) \
+ BREAKABLE_NODE_LIST(V) \
+ V(ExpressionStatement) \
+ V(EmptyStatement) \
+ V(SloppyBlockFunctionStatement) \
+ V(IfStatement) \
+ V(ContinueStatement) \
+ V(BreakStatement) \
+ V(ReturnStatement) \
+ V(WithStatement) \
+ V(TryCatchStatement) \
+ V(TryFinallyStatement) \
+ V(DebuggerStatement) \
+ V(InitializeClassMembersStatement) \
+ V(InitializeClassStaticElementsStatement)
#define LITERAL_NODE_LIST(V) \
V(RegExpLiteral) \
@@ -919,7 +920,6 @@ class Literal final : public Expression {
kHeapNumber,
kBigInt,
kString,
- kSymbol,
kBoolean,
kUndefined,
kNull,
@@ -974,11 +974,6 @@ class Literal final : public Expression {
return string_;
}
- AstSymbol AsSymbol() {
- DCHECK_EQ(type(), kSymbol);
- return symbol_;
- }
-
V8_EXPORT_PRIVATE bool ToBooleanIsTrue() const;
bool ToBooleanIsFalse() const { return !ToBooleanIsTrue(); }
@@ -1019,11 +1014,6 @@ class Literal final : public Expression {
bit_field_ = TypeField::update(bit_field_, kString);
}
- Literal(AstSymbol symbol, int position)
- : Expression(position, kLiteral), symbol_(symbol) {
- bit_field_ = TypeField::update(bit_field_, kSymbol);
- }
-
Literal(bool boolean, int position)
: Expression(position, kLiteral), boolean_(boolean) {
bit_field_ = TypeField::update(bit_field_, kBoolean);
@@ -1038,7 +1028,6 @@ class Literal final : public Expression {
const AstRawString* string_;
int smi_;
double number_;
- AstSymbol symbol_;
AstBigInt bigint_;
bool boolean_;
};
@@ -1307,6 +1296,8 @@ class ObjectLiteral final : public AggregateLiteral {
return flags;
}
+ Variable* home_object() const { return home_object_; }
+
enum Flags {
kFastElements = 1 << 3,
kHasNullPrototype = 1 << 4,
@@ -1321,10 +1312,11 @@ class ObjectLiteral final : public AggregateLiteral {
ObjectLiteral(Zone* zone, const ScopedPtrList<Property>& properties,
uint32_t boilerplate_properties, int pos,
- bool has_rest_property)
+ bool has_rest_property, Variable* home_object)
: AggregateLiteral(pos, kObjectLiteral),
boilerplate_properties_(boilerplate_properties),
- properties_(properties.ToConstVector(), zone) {
+ properties_(properties.ToConstVector(), zone),
+ home_object_(home_object) {
bit_field_ |= HasElementsField::encode(false) |
HasRestPropertyField::encode(has_rest_property) |
FastElementsField::encode(false) |
@@ -1345,6 +1337,7 @@ class ObjectLiteral final : public AggregateLiteral {
uint32_t boilerplate_properties_;
Handle<ObjectBoilerplateDescription> boilerplate_description_;
ZoneList<Property*> properties_;
+ Variable* home_object_;
using HasElementsField = AggregateLiteral::NextBitField<bool, 1>;
using HasRestPropertyField = HasElementsField::Next<bool, 1>;
@@ -2141,8 +2134,6 @@ class FunctionLiteral final : public Expression {
}
V8_EXPORT_PRIVATE LanguageMode language_mode() const;
- static bool NeedsHomeObject(Expression* expr);
-
void add_expected_properties(int number_properties) {
expected_property_count_ += number_properties;
}
@@ -2363,11 +2354,6 @@ class ClassLiteralProperty final : public LiteralProperty {
return private_or_computed_name_var_;
}
- bool NeedsHomeObjectOnClassPrototype() const {
- return is_private() && kind_ == METHOD &&
- FunctionLiteral::NeedsHomeObject(value_);
- }
-
private:
friend class AstNodeFactory;
friend Zone;
@@ -2381,6 +2367,40 @@ class ClassLiteralProperty final : public LiteralProperty {
Variable* private_or_computed_name_var_;
};
+class ClassLiteralStaticElement final : public ZoneObject {
+ public:
+ enum Kind : uint8_t { PROPERTY, STATIC_BLOCK };
+
+ Kind kind() const { return kind_; }
+
+ ClassLiteralProperty* property() const {
+ DCHECK(kind() == PROPERTY);
+ return property_;
+ }
+
+ Block* static_block() const {
+ DCHECK(kind() == STATIC_BLOCK);
+ return static_block_;
+ }
+
+ private:
+ friend class AstNodeFactory;
+ friend Zone;
+
+ explicit ClassLiteralStaticElement(ClassLiteralProperty* property)
+ : kind_(PROPERTY), property_(property) {}
+
+ explicit ClassLiteralStaticElement(Block* static_block)
+ : kind_(STATIC_BLOCK), static_block_(static_block) {}
+
+ Kind kind_;
+
+ union {
+ ClassLiteralProperty* property_;
+ Block* static_block_;
+ };
+};
+
class InitializeClassMembersStatement final : public Statement {
public:
using Property = ClassLiteralProperty;
@@ -2397,9 +2417,28 @@ class InitializeClassMembersStatement final : public Statement {
ZonePtrList<Property>* fields_;
};
+class InitializeClassStaticElementsStatement final : public Statement {
+ public:
+ using StaticElement = ClassLiteralStaticElement;
+
+ ZonePtrList<StaticElement>* elements() const { return elements_; }
+
+ private:
+ friend class AstNodeFactory;
+ friend Zone;
+
+ InitializeClassStaticElementsStatement(ZonePtrList<StaticElement>* elements,
+ int pos)
+ : Statement(pos, kInitializeClassStaticElementsStatement),
+ elements_(elements) {}
+
+ ZonePtrList<StaticElement>* elements_;
+};
+
class ClassLiteral final : public Expression {
public:
using Property = ClassLiteralProperty;
+ using StaticElement = ClassLiteralStaticElement;
ClassScope* scope() const { return scope_; }
Expression* extends() const { return extends_; }
@@ -2425,14 +2464,16 @@ class ClassLiteral final : public Expression {
return is_anonymous_expression();
}
- FunctionLiteral* static_fields_initializer() const {
- return static_fields_initializer_;
- }
+ FunctionLiteral* static_initializer() const { return static_initializer_; }
FunctionLiteral* instance_members_initializer_function() const {
return instance_members_initializer_function_;
}
+ Variable* home_object() const { return home_object_; }
+
+ Variable* static_home_object() const { return static_home_object_; }
+
private:
friend class AstNodeFactory;
friend Zone;
@@ -2441,11 +2482,12 @@ class ClassLiteral final : public Expression {
FunctionLiteral* constructor,
ZonePtrList<Property>* public_members,
ZonePtrList<Property>* private_members,
- FunctionLiteral* static_fields_initializer,
+ FunctionLiteral* static_initializer,
FunctionLiteral* instance_members_initializer_function,
int start_position, int end_position,
bool has_name_static_property, bool has_static_computed_names,
- bool is_anonymous, bool has_private_methods)
+ bool is_anonymous, bool has_private_methods,
+ Variable* home_object, Variable* static_home_object)
: Expression(start_position, kClassLiteral),
end_position_(end_position),
scope_(scope),
@@ -2453,9 +2495,11 @@ class ClassLiteral final : public Expression {
constructor_(constructor),
public_members_(public_members),
private_members_(private_members),
- static_fields_initializer_(static_fields_initializer),
+ static_initializer_(static_initializer),
instance_members_initializer_function_(
- instance_members_initializer_function) {
+ instance_members_initializer_function),
+ home_object_(home_object),
+ static_home_object_(static_home_object) {
bit_field_ |= HasNameStaticProperty::encode(has_name_static_property) |
HasStaticComputedNames::encode(has_static_computed_names) |
IsAnonymousExpression::encode(is_anonymous) |
@@ -2468,12 +2512,14 @@ class ClassLiteral final : public Expression {
FunctionLiteral* constructor_;
ZonePtrList<Property>* public_members_;
ZonePtrList<Property>* private_members_;
- FunctionLiteral* static_fields_initializer_;
+ FunctionLiteral* static_initializer_;
FunctionLiteral* instance_members_initializer_function_;
using HasNameStaticProperty = Expression::NextBitField<bool, 1>;
using HasStaticComputedNames = HasNameStaticProperty::Next<bool, 1>;
using IsAnonymousExpression = HasStaticComputedNames::Next<bool, 1>;
using HasPrivateMethods = IsAnonymousExpression::Next<bool, 1>;
+ Variable* home_object_;
+ Variable* static_home_object_;
};
@@ -2500,19 +2546,16 @@ class NativeFunctionLiteral final : public Expression {
class SuperPropertyReference final : public Expression {
public:
- Expression* home_object() const { return home_object_; }
+ VariableProxy* home_object() const { return home_object_; }
private:
friend class AstNodeFactory;
friend Zone;
- // We take in ThisExpression* only as a proof that it was accessed.
- SuperPropertyReference(Expression* home_object, int pos)
- : Expression(pos, kSuperPropertyReference), home_object_(home_object) {
- DCHECK(home_object->IsProperty());
- }
+ explicit SuperPropertyReference(VariableProxy* home_object, int pos)
+ : Expression(pos, kSuperPropertyReference), home_object_(home_object) {}
- Expression* home_object_;
+ VariableProxy* home_object_;
};
@@ -2543,16 +2586,26 @@ class SuperCallReference final : public Expression {
// import(argument).
class ImportCallExpression final : public Expression {
public:
- Expression* argument() const { return argument_; }
+ Expression* specifier() const { return specifier_; }
+ Expression* import_assertions() const { return import_assertions_; }
private:
friend class AstNodeFactory;
friend Zone;
- ImportCallExpression(Expression* argument, int pos)
- : Expression(pos, kImportCallExpression), argument_(argument) {}
+ ImportCallExpression(Expression* specifier, int pos)
+ : Expression(pos, kImportCallExpression),
+ specifier_(specifier),
+ import_assertions_(nullptr) {}
+
+ ImportCallExpression(Expression* specifier, Expression* import_assertions,
+ int pos)
+ : Expression(pos, kImportCallExpression),
+ specifier_(specifier),
+ import_assertions_(import_assertions) {}
- Expression* argument_;
+ Expression* specifier_;
+ Expression* import_assertions_;
};
// This class is produced when parsing the () in arrow functions without any
@@ -2916,11 +2969,6 @@ class AstNodeFactory final {
return zone_->New<Literal>(string, pos);
}
- // A JavaScript symbol (ECMA-262 edition 6).
- Literal* NewSymbolLiteral(AstSymbol symbol, int pos) {
- return zone_->New<Literal>(symbol, pos);
- }
-
Literal* NewNumberLiteral(double number, int pos);
Literal* NewSmiLiteral(int number, int pos) {
@@ -2949,9 +2997,10 @@ class AstNodeFactory final {
ObjectLiteral* NewObjectLiteral(
const ScopedPtrList<ObjectLiteral::Property>& properties,
- uint32_t boilerplate_properties, int pos, bool has_rest_property) {
+ uint32_t boilerplate_properties, int pos, bool has_rest_property,
+ Variable* home_object = nullptr) {
return zone_->New<ObjectLiteral>(zone_, properties, boilerplate_properties,
- pos, has_rest_property);
+ pos, has_rest_property, home_object);
}
ObjectLiteral::Property* NewObjectLiteralProperty(
@@ -3177,20 +3226,32 @@ class AstNodeFactory final {
is_computed_name, is_private);
}
+ ClassLiteral::StaticElement* NewClassLiteralStaticElement(
+ ClassLiteral::Property* property) {
+ return zone_->New<ClassLiteral::StaticElement>(property);
+ }
+
+ ClassLiteral::StaticElement* NewClassLiteralStaticElement(
+ Block* static_block) {
+ return zone_->New<ClassLiteral::StaticElement>(static_block);
+ }
+
ClassLiteral* NewClassLiteral(
ClassScope* scope, Expression* extends, FunctionLiteral* constructor,
ZonePtrList<ClassLiteral::Property>* public_members,
ZonePtrList<ClassLiteral::Property>* private_members,
- FunctionLiteral* static_fields_initializer,
+ FunctionLiteral* static_initializer,
FunctionLiteral* instance_members_initializer_function,
int start_position, int end_position, bool has_name_static_property,
bool has_static_computed_names, bool is_anonymous,
- bool has_private_methods) {
+ bool has_private_methods, Variable* home_object,
+ Variable* static_home_object) {
return zone_->New<ClassLiteral>(
scope, extends, constructor, public_members, private_members,
- static_fields_initializer, instance_members_initializer_function,
+ static_initializer, instance_members_initializer_function,
start_position, end_position, has_name_static_property,
- has_static_computed_names, is_anonymous, has_private_methods);
+ has_static_computed_names, is_anonymous, has_private_methods,
+ home_object, static_home_object);
}
NativeFunctionLiteral* NewNativeFunctionLiteral(const AstRawString* name,
@@ -3199,9 +3260,9 @@ class AstNodeFactory final {
return zone_->New<NativeFunctionLiteral>(name, extension, pos);
}
- SuperPropertyReference* NewSuperPropertyReference(Expression* home_object,
- int pos) {
- return zone_->New<SuperPropertyReference>(home_object, pos);
+ SuperPropertyReference* NewSuperPropertyReference(
+ VariableProxy* home_object_var, int pos) {
+ return zone_->New<SuperPropertyReference>(home_object_var, pos);
}
SuperCallReference* NewSuperCallReference(VariableProxy* new_target_var,
@@ -3227,8 +3288,15 @@ class AstNodeFactory final {
return zone_->New<TemplateLiteral>(string_parts, substitutions, pos);
}
- ImportCallExpression* NewImportCallExpression(Expression* args, int pos) {
- return zone_->New<ImportCallExpression>(args, pos);
+ ImportCallExpression* NewImportCallExpression(Expression* specifier,
+ int pos) {
+ return zone_->New<ImportCallExpression>(specifier, pos);
+ }
+
+ ImportCallExpression* NewImportCallExpression(Expression* specifier,
+ Expression* import_assertions,
+ int pos) {
+ return zone_->New<ImportCallExpression>(specifier, import_assertions, pos);
}
InitializeClassMembersStatement* NewInitializeClassMembersStatement(
@@ -3236,6 +3304,12 @@ class AstNodeFactory final {
return zone_->New<InitializeClassMembersStatement>(args, pos);
}
+ InitializeClassStaticElementsStatement*
+ NewInitializeClassStaticElementsStatement(
+ ZonePtrList<ClassLiteral::StaticElement>* args, int pos) {
+ return zone_->New<InitializeClassStaticElementsStatement>(args, pos);
+ }
+
Zone* zone() const { return zone_; }
private:
diff --git a/chromium/v8/src/ast/modules.cc b/chromium/v8/src/ast/modules.cc
index 3c9a5080adf..62dc6191414 100644
--- a/chromium/v8/src/ast/modules.cc
+++ b/chromium/v8/src/ast/modules.cc
@@ -16,44 +16,35 @@ namespace internal {
bool SourceTextModuleDescriptor::AstRawStringComparer::operator()(
const AstRawString* lhs, const AstRawString* rhs) const {
- return ThreeWayCompare(lhs, rhs) < 0;
-}
-
-int SourceTextModuleDescriptor::AstRawStringComparer::ThreeWayCompare(
- const AstRawString* lhs, const AstRawString* rhs) {
- // Fast path for equal pointers: a pointer is not strictly less than itself.
- if (lhs == rhs) return false;
-
- // Order by contents (ordering by hash is unstable across runs).
- if (lhs->is_one_byte() != rhs->is_one_byte()) {
- return lhs->is_one_byte() ? -1 : 1;
- }
- if (lhs->byte_length() != rhs->byte_length()) {
- return lhs->byte_length() - rhs->byte_length();
- }
- return memcmp(lhs->raw_data(), rhs->raw_data(), lhs->byte_length());
+ return AstRawString::Compare(lhs, rhs) < 0;
}
bool SourceTextModuleDescriptor::ModuleRequestComparer::operator()(
const AstModuleRequest* lhs, const AstModuleRequest* rhs) const {
- if (int specifier_comparison = AstRawStringComparer::ThreeWayCompare(
- lhs->specifier(), rhs->specifier()))
+ if (int specifier_comparison =
+ AstRawString::Compare(lhs->specifier(), rhs->specifier())) {
return specifier_comparison < 0;
-
- if (lhs->import_assertions()->size() != rhs->import_assertions()->size())
- return (lhs->import_assertions()->size() <
- rhs->import_assertions()->size());
+ }
auto lhsIt = lhs->import_assertions()->cbegin();
auto rhsIt = rhs->import_assertions()->cbegin();
- for (; lhsIt != lhs->import_assertions()->cend(); ++lhsIt, ++rhsIt) {
+ for (; lhsIt != lhs->import_assertions()->cend() &&
+ rhsIt != rhs->import_assertions()->cend();
+ ++lhsIt, ++rhsIt) {
if (int assertion_key_comparison =
- AstRawStringComparer::ThreeWayCompare(lhsIt->first, rhsIt->first))
+ AstRawString::Compare(lhsIt->first, rhsIt->first)) {
return assertion_key_comparison < 0;
+ }
- if (int assertion_value_comparison = AstRawStringComparer::ThreeWayCompare(
- lhsIt->second.first, rhsIt->second.first))
+ if (int assertion_value_comparison =
+ AstRawString::Compare(lhsIt->second.first, rhsIt->second.first)) {
return assertion_value_comparison < 0;
+ }
+ }
+
+ if (lhs->import_assertions()->size() != rhs->import_assertions()->size()) {
+ return (lhs->import_assertions()->size() <
+ rhs->import_assertions()->size());
}
return false;
@@ -139,19 +130,20 @@ Handle<ModuleRequest> SourceTextModuleDescriptor::AstModuleRequest::Serialize(
// The import assertions will be stored in this array in the form:
// [key1, value1, location1, key2, value2, location2, ...]
Handle<FixedArray> import_assertions_array =
- isolate->factory()->NewFixedArray(
- static_cast<int>(import_assertions()->size() * 3));
+ isolate->factory()->NewFixedArray(static_cast<int>(
+ import_assertions()->size() * ModuleRequest::kAssertionEntrySize));
int i = 0;
for (auto iter = import_assertions()->cbegin();
- iter != import_assertions()->cend(); ++iter, i += 3) {
+ iter != import_assertions()->cend();
+ ++iter, i += ModuleRequest::kAssertionEntrySize) {
import_assertions_array->set(i, *iter->first->string());
import_assertions_array->set(i + 1, *iter->second.first->string());
import_assertions_array->set(i + 2,
Smi::FromInt(iter->second.second.beg_pos));
}
return v8::internal::ModuleRequest::New(isolate, specifier()->string(),
- import_assertions_array);
+ import_assertions_array, position());
}
template Handle<ModuleRequest>
SourceTextModuleDescriptor::AstModuleRequest::Serialize(Isolate* isolate) const;
diff --git a/chromium/v8/src/ast/modules.h b/chromium/v8/src/ast/modules.h
index f156d7a411a..f776d2b5226 100644
--- a/chromium/v8/src/ast/modules.h
+++ b/chromium/v8/src/ast/modules.h
@@ -5,6 +5,7 @@
#ifndef V8_AST_MODULES_H_
#define V8_AST_MODULES_H_
+#include "src/parsing/import-assertions.h"
#include "src/parsing/scanner.h" // Only for Scanner::Location.
#include "src/zone/zone-containers.h"
@@ -13,6 +14,7 @@ namespace internal {
class AstRawString;
+class AstRawStringComparer;
class ModuleRequest;
class SourceTextModuleInfo;
class SourceTextModuleInfoEntry;
@@ -27,10 +29,6 @@ class SourceTextModuleDescriptor : public ZoneObject {
regular_exports_(zone),
regular_imports_(zone) {}
- using ImportAssertions =
- ZoneMap<const AstRawString*,
- std::pair<const AstRawString*, Scanner::Location>>;
-
// The following Add* methods are high-level convenience functions for use by
// the parser.
@@ -126,11 +124,13 @@ class SourceTextModuleDescriptor : public ZoneObject {
class AstModuleRequest : public ZoneObject {
public:
- // TODO(v8:10958): Consider storing module request location here
- // instead of using separate ModuleRequestLocation struct.
AstModuleRequest(const AstRawString* specifier,
- const ImportAssertions* import_assertions)
- : specifier_(specifier), import_assertions_(import_assertions) {}
+ const ImportAssertions* import_assertions, int position,
+ int index)
+ : specifier_(specifier),
+ import_assertions_(import_assertions),
+ position_(position),
+ index_(index) {}
template <typename LocalIsolate>
Handle<v8::internal::ModuleRequest> Serialize(LocalIsolate* isolate) const;
@@ -140,29 +140,25 @@ class SourceTextModuleDescriptor : public ZoneObject {
return import_assertions_;
}
+ int position() const { return position_; }
+ int index() const { return index_; }
+
private:
const AstRawString* specifier_;
const ImportAssertions* import_assertions_;
- };
-
- struct ModuleRequestLocation {
- // The index at which we will place the request in SourceTextModuleInfo's
- // module_requests FixedArray.
- int index;
// The JS source code position of the request, used for reporting errors.
- int position;
+ int position_;
- ModuleRequestLocation(int index, int position)
- : index(index), position(position) {}
+ // The index at which we will place the request in SourceTextModuleInfo's
+ // module_requests FixedArray.
+ int index_;
};
// Custom content-based comparer for the below maps, to keep them stable
// across parses.
struct V8_EXPORT_PRIVATE AstRawStringComparer {
bool operator()(const AstRawString* lhs, const AstRawString* rhs) const;
- static int ThreeWayCompare(const AstRawString* lhs,
- const AstRawString* rhs);
};
struct V8_EXPORT_PRIVATE ModuleRequestComparer {
@@ -171,8 +167,7 @@ class SourceTextModuleDescriptor : public ZoneObject {
};
using ModuleRequestMap =
- ZoneMap<const AstModuleRequest*, ModuleRequestLocation,
- ModuleRequestComparer>;
+ ZoneSet<const AstModuleRequest*, ModuleRequestComparer>;
using RegularExportMap =
ZoneMultimap<const AstRawString*, Entry*, AstRawStringComparer>;
using RegularImportMap =
@@ -274,12 +269,11 @@ class SourceTextModuleDescriptor : public ZoneObject {
DCHECK_NOT_NULL(specifier);
int module_requests_count = static_cast<int>(module_requests_.size());
auto it = module_requests_
- .insert(std::make_pair(
- zone->New<AstModuleRequest>(specifier, import_assertions),
- ModuleRequestLocation(module_requests_count,
- specifier_loc.beg_pos)))
+ .insert(zone->New<AstModuleRequest>(
+ specifier, import_assertions, specifier_loc.beg_pos,
+ module_requests_count))
.first;
- return it->second.index;
+ return (*it)->index();
}
};
diff --git a/chromium/v8/src/ast/prettyprinter.cc b/chromium/v8/src/ast/prettyprinter.cc
index e53d9c9e6e1..cb8d2ec75af 100644
--- a/chromium/v8/src/ast/prettyprinter.cc
+++ b/chromium/v8/src/ast/prettyprinter.cc
@@ -235,6 +235,18 @@ void CallPrinter::VisitInitializeClassMembersStatement(
}
}
+void CallPrinter::VisitInitializeClassStaticElementsStatement(
+ InitializeClassStaticElementsStatement* node) {
+ for (int i = 0; i < node->elements()->length(); i++) {
+ ClassLiteral::StaticElement* element = node->elements()->at(i);
+ if (element->kind() == ClassLiteral::StaticElement::PROPERTY) {
+ Find(element->property()->value());
+ } else {
+ Find(element->static_block());
+ }
+ }
+}
+
void CallPrinter::VisitNativeFunctionLiteral(NativeFunctionLiteral* node) {}
@@ -256,6 +268,7 @@ void CallPrinter::VisitRegExpLiteral(RegExpLiteral* node) {
Print("/");
PrintLiteral(node->pattern(), false);
Print("/");
+ if (node->flags() & RegExp::kHasIndices) Print("d");
if (node->flags() & RegExp::kGlobal) Print("g");
if (node->flags() & RegExp::kIgnoreCase) Print("i");
if (node->flags() & RegExp::kLinear) Print("l");
@@ -551,7 +564,10 @@ void CallPrinter::VisitTemplateLiteral(TemplateLiteral* node) {
void CallPrinter::VisitImportCallExpression(ImportCallExpression* node) {
Print("ImportCall(");
- Find(node->argument(), true);
+ Find(node->specifier(), true);
+ if (node->import_assertions()) {
+ Find(node->import_assertions(), true);
+ }
Print(")");
}
@@ -659,14 +675,6 @@ void AstPrinter::PrintLiteral(Literal* literal, bool quote) {
case Literal::kString:
PrintLiteral(literal->AsRawString(), quote);
break;
- case Literal::kSymbol:
- const char* symbol;
- switch (literal->AsSymbol()) {
- case AstSymbol::kHomeObjectSymbol:
- symbol = "HomeObjectSymbol";
- }
- Print("%s", symbol);
- break;
case Literal::kSmi:
Print("%d", Smi::ToInt(literal->AsSmiLiteral()));
break;
@@ -721,7 +729,7 @@ void AstPrinter::PrintLiteral(const AstConsString* value, bool quote) {
//-----------------------------------------------------------------------------
-class IndentedScope {
+class V8_NODISCARD IndentedScope {
public:
IndentedScope(AstPrinter* printer, const char* txt)
: ast_printer_(printer) {
@@ -745,7 +753,6 @@ class IndentedScope {
AstPrinter* ast_printer_;
};
-
//-----------------------------------------------------------------------------
AstPrinter::AstPrinter(uintptr_t stack_limit)
@@ -1091,9 +1098,8 @@ void AstPrinter::VisitClassLiteral(ClassLiteral* node) {
PrintLiteralWithModeIndented("BRAND", brand, brand->raw_name());
}
}
- if (node->static_fields_initializer() != nullptr) {
- PrintIndentedVisit("STATIC FIELDS INITIALIZER",
- node->static_fields_initializer());
+ if (node->static_initializer() != nullptr) {
+ PrintIndentedVisit("STATIC INITIALIZER", node->static_initializer());
}
if (node->instance_members_initializer_function() != nullptr) {
PrintIndentedVisit("INSTANCE MEMBERS INITIALIZER",
@@ -1109,35 +1115,59 @@ void AstPrinter::VisitInitializeClassMembersStatement(
PrintClassProperties(node->fields());
}
+void AstPrinter::VisitInitializeClassStaticElementsStatement(
+ InitializeClassStaticElementsStatement* node) {
+ IndentedScope indent(this, "INITIALIZE CLASS STATIC ELEMENTS",
+ node->position());
+ PrintClassStaticElements(node->elements());
+}
+
+void AstPrinter::PrintClassProperty(ClassLiteral::Property* property) {
+ const char* prop_kind = nullptr;
+ switch (property->kind()) {
+ case ClassLiteral::Property::METHOD:
+ prop_kind = "METHOD";
+ break;
+ case ClassLiteral::Property::GETTER:
+ prop_kind = "GETTER";
+ break;
+ case ClassLiteral::Property::SETTER:
+ prop_kind = "SETTER";
+ break;
+ case ClassLiteral::Property::FIELD:
+ prop_kind = "FIELD";
+ break;
+ }
+ EmbeddedVector<char, 128> buf;
+ SNPrintF(buf, "PROPERTY%s%s - %s", property->is_static() ? " - STATIC" : "",
+ property->is_private() ? " - PRIVATE" : " - PUBLIC", prop_kind);
+ IndentedScope prop(this, buf.begin());
+ PrintIndentedVisit("KEY", property->key());
+ PrintIndentedVisit("VALUE", property->value());
+}
+
void AstPrinter::PrintClassProperties(
const ZonePtrList<ClassLiteral::Property>* properties) {
for (int i = 0; i < properties->length(); i++) {
- ClassLiteral::Property* property = properties->at(i);
- const char* prop_kind = nullptr;
- switch (property->kind()) {
- case ClassLiteral::Property::METHOD:
- prop_kind = "METHOD";
- break;
- case ClassLiteral::Property::GETTER:
- prop_kind = "GETTER";
- break;
- case ClassLiteral::Property::SETTER:
- prop_kind = "SETTER";
+ PrintClassProperty(properties->at(i));
+ }
+}
+
+void AstPrinter::PrintClassStaticElements(
+ const ZonePtrList<ClassLiteral::StaticElement>* static_elements) {
+ for (int i = 0; i < static_elements->length(); i++) {
+ ClassLiteral::StaticElement* element = static_elements->at(i);
+ switch (element->kind()) {
+ case ClassLiteral::StaticElement::PROPERTY:
+ PrintClassProperty(element->property());
break;
- case ClassLiteral::Property::FIELD:
- prop_kind = "FIELD";
+ case ClassLiteral::StaticElement::STATIC_BLOCK:
+ PrintIndentedVisit("STATIC BLOCK", element->static_block());
break;
}
- EmbeddedVector<char, 128> buf;
- SNPrintF(buf, "PROPERTY%s%s - %s", property->is_static() ? " - STATIC" : "",
- property->is_private() ? " - PRIVATE" : " - PUBLIC", prop_kind);
- IndentedScope prop(this, buf.begin());
- PrintIndentedVisit("KEY", properties->at(i)->key());
- PrintIndentedVisit("VALUE", properties->at(i)->value());
}
}
-
void AstPrinter::VisitNativeFunctionLiteral(NativeFunctionLiteral* node) {
IndentedScope indent(this, "NATIVE FUNC LITERAL", node->position());
PrintLiteralIndented("NAME", node->raw_name(), false);
@@ -1162,6 +1192,7 @@ void AstPrinter::VisitRegExpLiteral(RegExpLiteral* node) {
PrintLiteralIndented("PATTERN", node->raw_pattern(), false);
int i = 0;
EmbeddedVector<char, 128> buf;
+ if (node->flags() & RegExp::kHasIndices) buf[i++] = 'd';
if (node->flags() & RegExp::kGlobal) buf[i++] = 'g';
if (node->flags() & RegExp::kIgnoreCase) buf[i++] = 'i';
if (node->flags() & RegExp::kLinear) buf[i++] = 'l';
@@ -1435,7 +1466,10 @@ void AstPrinter::VisitTemplateLiteral(TemplateLiteral* node) {
void AstPrinter::VisitImportCallExpression(ImportCallExpression* node) {
IndentedScope indent(this, "IMPORT-CALL", node->position());
- Visit(node->argument());
+ Visit(node->specifier());
+ if (node->import_assertions()) {
+ Visit(node->import_assertions());
+ }
}
void AstPrinter::VisitThisExpression(ThisExpression* node) {
diff --git a/chromium/v8/src/ast/prettyprinter.h b/chromium/v8/src/ast/prettyprinter.h
index 4b939c7d17a..e26d98e7a39 100644
--- a/chromium/v8/src/ast/prettyprinter.h
+++ b/chromium/v8/src/ast/prettyprinter.h
@@ -133,8 +133,11 @@ class AstPrinter final : public AstVisitor<AstPrinter> {
const char* prefix = "");
void PrintObjectProperties(
const ZonePtrList<ObjectLiteral::Property>* properties);
+ void PrintClassProperty(ClassLiteral::Property* property);
void PrintClassProperties(
const ZonePtrList<ClassLiteral::Property>* properties);
+ void PrintClassStaticElements(
+ const ZonePtrList<ClassLiteral::StaticElement>* static_elements);
void inc_indent() { indent_++; }
void dec_indent() { indent_--; }
diff --git a/chromium/v8/src/ast/scopes.cc b/chromium/v8/src/ast/scopes.cc
index c9a3b400a70..4e396c457f7 100644
--- a/chromium/v8/src/ast/scopes.cc
+++ b/chromium/v8/src/ast/scopes.cc
@@ -113,6 +113,32 @@ Scope::Scope(Zone* zone, Scope* outer_scope, ScopeType scope_type)
outer_scope_->AddInnerScope(this);
}
+Variable* Scope::DeclareHomeObjectVariable(AstValueFactory* ast_value_factory) {
+ bool was_added;
+ Variable* home_object_variable = Declare(
+ zone(), ast_value_factory->dot_home_object_string(), VariableMode::kConst,
+ NORMAL_VARIABLE, InitializationFlag::kCreatedInitialized,
+ MaybeAssignedFlag::kNotAssigned, &was_added);
+ DCHECK(was_added);
+ home_object_variable->set_is_used();
+ home_object_variable->ForceContextAllocation();
+ return home_object_variable;
+}
+
+Variable* Scope::DeclareStaticHomeObjectVariable(
+ AstValueFactory* ast_value_factory) {
+ bool was_added;
+ Variable* static_home_object_variable =
+ Declare(zone(), ast_value_factory->dot_static_home_object_string(),
+ VariableMode::kConst, NORMAL_VARIABLE,
+ InitializationFlag::kCreatedInitialized,
+ MaybeAssignedFlag::kNotAssigned, &was_added);
+ DCHECK(was_added);
+ static_home_object_variable->set_is_used();
+ static_home_object_variable->ForceContextAllocation();
+ return static_home_object_variable;
+}
+
DeclarationScope::DeclarationScope(Zone* zone,
AstValueFactory* ast_value_factory,
REPLMode repl_mode)
@@ -148,7 +174,7 @@ ModuleScope::ModuleScope(DeclarationScope* script_scope,
ModuleScope::ModuleScope(Isolate* isolate, Handle<ScopeInfo> scope_info,
AstValueFactory* avfactory)
- : DeclarationScope(avfactory->zone(), MODULE_SCOPE, scope_info),
+ : DeclarationScope(avfactory->zone(), MODULE_SCOPE, avfactory, scope_info),
module_descriptor_(nullptr) {
set_language_mode(LanguageMode::kStrict);
}
@@ -163,7 +189,7 @@ ClassScope::ClassScope(Zone* zone, Scope* outer_scope, bool is_anonymous)
ClassScope::ClassScope(Isolate* isolate, Zone* zone,
AstValueFactory* ast_value_factory,
Handle<ScopeInfo> scope_info)
- : Scope(zone, CLASS_SCOPE, scope_info),
+ : Scope(zone, CLASS_SCOPE, ast_value_factory, scope_info),
rare_data_and_is_parsing_heritage_(nullptr) {
set_language_mode(LanguageMode::kStrict);
if (scope_info->HasClassBrand()) {
@@ -193,7 +219,8 @@ ClassScope::ClassScope(Isolate* isolate, Zone* zone,
}
}
-Scope::Scope(Zone* zone, ScopeType scope_type, Handle<ScopeInfo> scope_info)
+Scope::Scope(Zone* zone, ScopeType scope_type,
+ AstValueFactory* ast_value_factory, Handle<ScopeInfo> scope_info)
: outer_scope_(nullptr),
variables_(zone),
scope_info_(scope_info),
@@ -210,11 +237,31 @@ Scope::Scope(Zone* zone, ScopeType scope_type, Handle<ScopeInfo> scope_info)
// We don't really need to use the preparsed scope data; this is just to
// shorten the recursion in SetMustUsePreparseData.
must_use_preparsed_scope_data_ = true;
+
+ if (scope_type == BLOCK_SCOPE) {
+ // Set is_block_scope_for_object_literal_ based on the existince of the home
+ // object variable (we don't store it explicitly).
+ VariableMode mode;
+ InitializationFlag init_flag;
+ MaybeAssignedFlag maybe_assigned_flag;
+ IsStaticFlag is_static_flag;
+
+ DCHECK_NOT_NULL(ast_value_factory);
+ int home_object_index = ScopeInfo::ContextSlotIndex(
+ *scope_info, *(ast_value_factory->dot_home_object_string()->string()),
+ &mode, &init_flag, &maybe_assigned_flag, &is_static_flag);
+ DCHECK_IMPLIES(home_object_index >= 0,
+ scope_type == CLASS_SCOPE || scope_type == BLOCK_SCOPE);
+ if (home_object_index >= 0) {
+ is_block_scope_for_object_literal_ = true;
+ }
+ }
}
DeclarationScope::DeclarationScope(Zone* zone, ScopeType scope_type,
+ AstValueFactory* ast_value_factory,
Handle<ScopeInfo> scope_info)
- : Scope(zone, scope_type, scope_info),
+ : Scope(zone, scope_type, ast_value_factory, scope_info),
function_kind_(scope_info->function_kind()),
params_(0, zone) {
DCHECK_NE(scope_type, SCRIPT_SCOPE);
@@ -252,7 +299,7 @@ void DeclarationScope::SetDefaults() {
is_asm_module_ = false;
force_eager_compilation_ = false;
has_arguments_parameter_ = false;
- scope_uses_super_property_ = false;
+ uses_super_property_ = false;
has_checked_syntax_ = false;
has_this_reference_ = false;
has_this_declaration_ =
@@ -308,6 +355,9 @@ void Scope::SetDefaults() {
deserialized_scope_uses_external_cache_ = false;
+ needs_home_object_ = false;
+ is_block_scope_for_object_literal_ = false;
+
num_stack_slots_ = 0;
num_heap_slots_ = ContextHeaderLength();
@@ -357,13 +407,14 @@ Scope* Scope::DeserializeScopeChain(Isolate* isolate, Zone* zone,
while (!scope_info.is_null()) {
if (scope_info.scope_type() == WITH_SCOPE) {
if (scope_info.IsDebugEvaluateScope()) {
- outer_scope = zone->New<DeclarationScope>(zone, FUNCTION_SCOPE,
- handle(scope_info, isolate));
+ outer_scope =
+ zone->New<DeclarationScope>(zone, FUNCTION_SCOPE, ast_value_factory,
+ handle(scope_info, isolate));
outer_scope->set_is_debug_evaluate_scope();
} else {
// For scope analysis, debug-evaluate is equivalent to a with scope.
- outer_scope =
- zone->New<Scope>(zone, WITH_SCOPE, handle(scope_info, isolate));
+ outer_scope = zone->New<Scope>(zone, WITH_SCOPE, ast_value_factory,
+ handle(scope_info, isolate));
}
} else if (scope_info.scope_type() == SCRIPT_SCOPE) {
@@ -377,24 +428,24 @@ Scope* Scope::DeserializeScopeChain(Isolate* isolate, Zone* zone,
DCHECK(!scope_info.HasOuterScopeInfo());
break;
} else if (scope_info.scope_type() == FUNCTION_SCOPE) {
- outer_scope = zone->New<DeclarationScope>(zone, FUNCTION_SCOPE,
- handle(scope_info, isolate));
+ outer_scope = zone->New<DeclarationScope>(
+ zone, FUNCTION_SCOPE, ast_value_factory, handle(scope_info, isolate));
if (scope_info.IsAsmModule()) {
outer_scope->AsDeclarationScope()->set_is_asm_module();
}
} else if (scope_info.scope_type() == EVAL_SCOPE) {
- outer_scope = zone->New<DeclarationScope>(zone, EVAL_SCOPE,
- handle(scope_info, isolate));
+ outer_scope = zone->New<DeclarationScope>(
+ zone, EVAL_SCOPE, ast_value_factory, handle(scope_info, isolate));
} else if (scope_info.scope_type() == CLASS_SCOPE) {
outer_scope = zone->New<ClassScope>(isolate, zone, ast_value_factory,
handle(scope_info, isolate));
} else if (scope_info.scope_type() == BLOCK_SCOPE) {
if (scope_info.is_declaration_scope()) {
- outer_scope = zone->New<DeclarationScope>(zone, BLOCK_SCOPE,
- handle(scope_info, isolate));
+ outer_scope = zone->New<DeclarationScope>(
+ zone, BLOCK_SCOPE, ast_value_factory, handle(scope_info, isolate));
} else {
- outer_scope =
- zone->New<Scope>(zone, BLOCK_SCOPE, handle(scope_info, isolate));
+ outer_scope = zone->New<Scope>(zone, BLOCK_SCOPE, ast_value_factory,
+ handle(scope_info, isolate));
}
} else if (scope_info.scope_type() == MODULE_SCOPE) {
outer_scope = zone->New<ModuleScope>(isolate, handle(scope_info, isolate),
@@ -835,7 +886,7 @@ Variable* Scope::LookupInScopeInfo(const AstRawString* name, Scope* cache) {
cache != this,
cache->outer_scope()->deserialized_scope_uses_external_cache());
DCHECK_NULL(cache->variables_.Lookup(name));
- DisallowHeapAllocation no_gc;
+ DisallowGarbageCollection no_gc;
String name_handle = *name->string();
ScopeInfo scope_info = *scope_info_;
@@ -1378,6 +1429,29 @@ DeclarationScope* Scope::GetReceiverScope() {
return scope->AsDeclarationScope();
}
+Scope* Scope::GetHomeObjectScope() {
+ Scope* scope = this;
+ while (scope != nullptr && !scope->is_home_object_scope()) {
+ if (scope->is_function_scope()) {
+ FunctionKind function_kind = scope->AsDeclarationScope()->function_kind();
+ // "super" in arrow functions binds outside the arrow function. But if we
+ // find a function which doesn't bind "super" (is not a method etc.) and
+ // not an arrow function, we know "super" here doesn't bind anywhere and
+ // we can return nullptr.
+ if (!IsArrowFunction(function_kind) && !BindsSuper(function_kind)) {
+ return nullptr;
+ }
+ }
+ if (scope->private_name_lookup_skips_outer_class()) {
+ DCHECK(scope->outer_scope()->is_class_scope());
+ scope = scope->outer_scope()->outer_scope();
+ } else {
+ scope = scope->outer_scope();
+ }
+ }
+ return scope;
+}
+
DeclarationScope* Scope::GetScriptScope() {
Scope* scope = this;
while (!scope->is_script_scope()) {
@@ -1781,9 +1855,6 @@ void Scope::Print(int n) {
AsDeclarationScope()->sloppy_eval_can_extend_vars()) {
Indent(n1, "// scope calls sloppy 'eval'\n");
}
- if (is_declaration_scope() && AsDeclarationScope()->NeedsHomeObject()) {
- Indent(n1, "// scope needs home object\n");
- }
if (private_name_lookup_skips_outer_class()) {
Indent(n1, "// scope skips outer class for #-names\n");
}
@@ -2669,7 +2740,7 @@ void ClassScope::MigrateUnresolvedPrivateNameTail(
Variable* ClassScope::LookupPrivateNameInScopeInfo(const AstRawString* name) {
DCHECK(!scope_info_.is_null());
DCHECK_NULL(LookupLocalPrivateName(name));
- DisallowHeapAllocation no_gc;
+ DisallowGarbageCollection no_gc;
String name_handle = *name->string();
VariableMode mode;
diff --git a/chromium/v8/src/ast/scopes.h b/chromium/v8/src/ast/scopes.h
index e731d4c46a0..eb97c95b328 100644
--- a/chromium/v8/src/ast/scopes.h
+++ b/chromium/v8/src/ast/scopes.h
@@ -225,6 +225,9 @@ class V8_EXPORT_PRIVATE Scope : public NON_EXPORTED_BASE(ZoneObject) {
VariableKind kind = NORMAL_VARIABLE);
Variable* DeclareCatchVariableName(const AstRawString* name);
+ Variable* DeclareHomeObjectVariable(AstValueFactory* ast_value_factory);
+ Variable* DeclareStaticHomeObjectVariable(AstValueFactory* ast_value_factory);
+
// Declarations list.
base::ThreadedList<Declaration>* declarations() { return &decls_; }
@@ -369,6 +372,18 @@ class V8_EXPORT_PRIVATE Scope : public NON_EXPORTED_BASE(ZoneObject) {
bool is_with_scope() const { return scope_type_ == WITH_SCOPE; }
bool is_declaration_scope() const { return is_declaration_scope_; }
bool is_class_scope() const { return scope_type_ == CLASS_SCOPE; }
+ bool is_home_object_scope() const {
+ return is_class_scope() ||
+ (is_block_scope() && is_block_scope_for_object_literal_);
+ }
+ bool is_block_scope_for_object_literal() const {
+ DCHECK_IMPLIES(is_block_scope_for_object_literal_, is_block_scope());
+ return is_block_scope_for_object_literal_;
+ }
+ void set_is_block_scope_for_object_literal() {
+ DCHECK(is_block_scope());
+ is_block_scope_for_object_literal_ = true;
+ }
bool inner_scope_calls_eval() const { return inner_scope_calls_eval_; }
bool private_name_lookup_skips_outer_class() const {
@@ -525,6 +540,10 @@ class V8_EXPORT_PRIVATE Scope : public NON_EXPORTED_BASE(ZoneObject) {
// 'this' is bound, and what determines the function kind.
DeclarationScope* GetReceiverScope();
+ // Find the first class scope or object literal block scope. This is where
+ // 'super' is bound.
+ Scope* GetHomeObjectScope();
+
DeclarationScope* GetScriptScope();
// Find the innermost outer scope that needs a context.
@@ -570,6 +589,16 @@ class V8_EXPORT_PRIVATE Scope : public NON_EXPORTED_BASE(ZoneObject) {
return deserialized_scope_uses_external_cache_;
}
+ bool needs_home_object() const {
+ DCHECK(is_home_object_scope());
+ return needs_home_object_;
+ }
+
+ void set_needs_home_object() {
+ DCHECK(is_home_object_scope());
+ needs_home_object_ = true;
+ }
+
bool RemoveInnerScope(Scope* inner_scope) {
DCHECK_NOT_NULL(inner_scope);
if (inner_scope == inner_scope_) {
@@ -691,7 +720,8 @@ class V8_EXPORT_PRIVATE Scope : public NON_EXPORTED_BASE(ZoneObject) {
MaybeHandle<ScopeInfo> outer_scope);
// Construct a scope based on the scope info.
- Scope(Zone* zone, ScopeType type, Handle<ScopeInfo> scope_info);
+ Scope(Zone* zone, ScopeType type, AstValueFactory* ast_value_factory,
+ Handle<ScopeInfo> scope_info);
// Construct a catch scope with a binding for the name.
Scope(Zone* zone, const AstRawString* catch_variable_name,
@@ -808,6 +838,9 @@ class V8_EXPORT_PRIVATE Scope : public NON_EXPORTED_BASE(ZoneObject) {
// the compilation of the eval will have the "with" scope as the first scope
// with this flag enabled.
bool deserialized_scope_uses_external_cache_ : 1;
+
+ bool needs_home_object_ : 1;
+ bool is_block_scope_for_object_literal_ : 1;
};
class V8_EXPORT_PRIVATE DeclarationScope : public Scope {
@@ -815,6 +848,7 @@ class V8_EXPORT_PRIVATE DeclarationScope : public Scope {
DeclarationScope(Zone* zone, Scope* outer_scope, ScopeType scope_type,
FunctionKind function_kind = kNormalFunction);
DeclarationScope(Zone* zone, ScopeType scope_type,
+ AstValueFactory* ast_value_factory,
Handle<ScopeInfo> scope_info);
// Creates a script scope.
DeclarationScope(Zone* zone, AstValueFactory* ast_value_factory,
@@ -822,24 +856,21 @@ class V8_EXPORT_PRIVATE DeclarationScope : public Scope {
FunctionKind function_kind() const { return function_kind_; }
- bool is_arrow_scope() const {
- return is_function_scope() && IsArrowFunction(function_kind_);
- }
-
// Inform the scope that the corresponding code uses "super".
void RecordSuperPropertyUsage() {
DCHECK(IsConciseMethod(function_kind()) ||
IsAccessorFunction(function_kind()) ||
IsClassConstructor(function_kind()));
- scope_uses_super_property_ = true;
+ uses_super_property_ = true;
+ Scope* home_object_scope = GetHomeObjectScope();
+ DCHECK_NOT_NULL(home_object_scope);
+ home_object_scope->set_needs_home_object();
}
- // Does this scope access "super" property (super.foo).
- bool NeedsHomeObject() const {
- return scope_uses_super_property_ ||
- (inner_scope_calls_eval_ && (IsConciseMethod(function_kind()) ||
- IsAccessorFunction(function_kind()) ||
- IsClassConstructor(function_kind())));
+ bool uses_super_property() const { return uses_super_property_; }
+
+ bool is_arrow_scope() const {
+ return is_function_scope() && IsArrowFunction(function_kind_);
}
// Inform the scope and outer scopes that the corresponding code contains an
@@ -1219,7 +1250,7 @@ class V8_EXPORT_PRIVATE DeclarationScope : public Scope {
// This scope has a parameter called "arguments".
bool has_arguments_parameter_ : 1;
// This scope uses "super" property ('super.foo').
- bool scope_uses_super_property_ : 1;
+ bool uses_super_property_ : 1;
bool should_eager_compile_ : 1;
// Set to true after we have finished lazy parsing the scope.
bool was_lazily_parsed_ : 1;
@@ -1298,6 +1329,14 @@ void Scope::RecordEvalCall() {
calls_eval_ = true;
GetDeclarationScope()->RecordDeclarationScopeEvalCall();
RecordInnerScopeEvalCall();
+ // The eval contents might access "super" (if it's inside a function that
+ // binds super).
+ DeclarationScope* receiver_scope = GetReceiverScope();
+ DCHECK(!receiver_scope->is_arrow_scope());
+ FunctionKind function_kind = receiver_scope->function_kind();
+ if (BindsSuper(function_kind)) {
+ receiver_scope->RecordSuperPropertyUsage();
+ }
}
Scope::Snapshot::Snapshot(Scope* scope)