Commit 8b8dfda8 authored by Daniel Vogelheim's avatar Daniel Vogelheim Committed by Commit Bot

[parser/ast] Remove AstString, in favour of stand-alons Ast(Raw|Cons)String.

Removes the AstString super-class and makes the two sub-classes stand-alone.
That also removes the slightly awkward implementation of a super-class with
dynamically dispatched behaviour, except it was manually implemented because
virtual function calls were considered expensive.

BUG=v8:6902

Change-Id: I079a2372557aa17ee839efcaddb9b7fe86e38b4d
Reviewed-on: https://chromium-review.googlesource.com/458428
Commit-Queue: Daniel Vogelheim <vogelheim@chromium.org>
Reviewed-by: 's avatarMarja Hölttä <marja@chromium.org>
Cr-Commit-Position: refs/heads/master@{#44104}
parent c9da6609
...@@ -84,21 +84,8 @@ class AstRawStringInternalizationKey : public HashTableKey { ...@@ -84,21 +84,8 @@ class AstRawStringInternalizationKey : public HashTableKey {
const AstRawString* string_; 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) { void AstRawString::Internalize(Isolate* isolate) {
DCHECK(!has_string_);
if (literal_bytes_.length() == 0) { if (literal_bytes_.length() == 0) {
set_string(isolate->factory()->empty_string()); set_string(isolate->factory()->empty_string());
} else { } else {
...@@ -121,18 +108,26 @@ bool AstRawString::AsArrayIndex(uint32_t* index) const { ...@@ -121,18 +108,26 @@ bool AstRawString::AsArrayIndex(uint32_t* index) const {
} }
bool AstRawString::IsOneByteEqualTo(const char* data) const { bool AstRawString::IsOneByteEqualTo(const char* data) const {
int length = static_cast<int>(strlen(data)); if (!is_one_byte()) return false;
if (is_one_byte() && literal_bytes_.length() == length) {
const char* token = reinterpret_cast<const char*>(literal_bytes_.start()); size_t length = static_cast<size_t>(literal_bytes_.length());
return !strncmp(token, data, length); if (length != strlen(data)) return false;
}
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) { bool AstRawString::Compare(void* a, void* b) {
const AstRawString* lhs = static_cast<AstRawString*>(a); const AstRawString* lhs = static_cast<AstRawString*>(a);
const AstRawString* rhs = static_cast<AstRawString*>(b); const AstRawString* rhs = static_cast<AstRawString*>(b);
DCHECK_EQ(lhs->hash(), rhs->hash()); DCHECK_EQ(lhs->hash(), rhs->hash());
if (lhs->length() != rhs->length()) return false; if (lhs->length() != rhs->length()) return false;
const unsigned char* l = lhs->raw_data(); const unsigned char* l = lhs->raw_data();
const unsigned char* r = rhs->raw_data(); const unsigned char* r = rhs->raw_data();
...@@ -161,11 +156,15 @@ bool AstRawString::Compare(void* a, void* b) { ...@@ -161,11 +156,15 @@ bool AstRawString::Compare(void* a, void* b) {
} }
void AstConsString::Internalize(Isolate* isolate) { void AstConsString::Internalize(Isolate* isolate) {
// AstRawStrings are internalized before AstConsStrings so left and right are Handle<String> tmp(isolate->factory()->empty_string());
// already internalized. for (const AstRawString* current : strings_) {
set_string(isolate->factory() // AstRawStrings are internalized before AstConsStrings, so *current is
->NewConsString(left_->string(), right_->string()) // already internalized.
.ToHandleChecked()); tmp = isolate->factory()
->NewConsString(tmp, current->string())
.ToHandleChecked();
}
set_string(tmp);
} }
bool AstValue::IsPropertyName() const { bool AstValue::IsPropertyName() const {
...@@ -285,22 +284,34 @@ const AstRawString* AstValueFactory::GetString(Handle<String> literal) { ...@@ -285,22 +284,34 @@ const AstRawString* AstValueFactory::GetString(Handle<String> literal) {
return result; return result;
} }
AstConsString* AstValueFactory::NewConsString() {
const AstConsString* AstValueFactory::NewConsString( AstConsString* new_string = new (zone_) AstConsString(zone_);
const AstString* left, const AstString* right) { DCHECK_NOT_NULL(new_string);
// This Vector will be valid as long as the Collector is alive (meaning that AddConsString(new_string);
// the AstRawString will not be moved).
AstConsString* new_string = new (zone_) AstConsString(left, right);
CHECK(new_string != nullptr);
AddString(new_string);
return new_string; return new_string;
} }
AstConsString* AstValueFactory::NewConsString(const AstRawString* str) {
return NewConsString()->AddString(str);
}
AstConsString* AstValueFactory::NewConsString(const AstRawString* str1,
const AstRawString* str2) {
return NewConsString()->AddString(str1)->AddString(str2);
}
void AstValueFactory::Internalize(Isolate* isolate) { void AstValueFactory::Internalize(Isolate* isolate) {
// Strings need to be internalized before values, because values refer to // Strings need to be internalized before values, because values refer to
// strings. // strings.
for (AstString* current = strings_; current != nullptr;) { for (AstRawString* current = strings_; current != nullptr;) {
AstString* next = current->next(); 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->Internalize(isolate);
current = next; current = next;
} }
......
...@@ -35,123 +35,128 @@ ...@@ -35,123 +35,128 @@
#include "src/isolate.h" #include "src/isolate.h"
#include "src/utils.h" #include "src/utils.h"
// AstString, AstValue and AstValueFactory are for storing strings and values // Ast(Raw|Cons)String, AstValue and AstValueFactory are for storing strings and
// independent of the V8 heap and internalizing them later. During parsing, // values independent of the V8 heap and internalizing them later. During
// AstStrings and AstValues are created and stored outside the heap, in // parsing, they are created and stored outside the heap, in AstValueFactory.
// AstValueFactory. After parsing, the strings and values are internalized // After parsing, the strings and values are internalized (moved into the V8
// (moved into the V8 heap). // heap).
namespace v8 { namespace v8 {
namespace internal { namespace internal {
class AstString : public ZoneObject { class AstRawString final : 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 {
public: public:
bool IsEmpty() const { return literal_bytes_.length() == 0; }
int length() const { int length() const {
if (is_one_byte()) return literal_bytes_.length(); return is_one_byte() ? literal_bytes_.length()
return literal_bytes_.length() / 2; : literal_bytes_.length() / 2;
} }
bool AsArrayIndex(uint32_t* index) const;
int byte_length() const { return literal_bytes_.length(); } bool IsOneByteEqualTo(const char* data) const;
uint16_t FirstCharacter() const;
void Internalize(Isolate* isolate); void Internalize(Isolate* isolate);
bool AsArrayIndex(uint32_t* index) const; // Access the physical representation:
bool is_one_byte() const { return is_one_byte_; }
// The string is not null-terminated, use length() to find out the length. int byte_length() const { return literal_bytes_.length(); }
const unsigned char* raw_data() const { const unsigned char* raw_data() const {
return literal_bytes_.start(); 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. // For storing AstRawStrings in a hash map.
uint32_t hash() const { uint32_t hash() const {
return hash_; 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: private:
friend class AstRawStringInternalizationKey; friend class AstRawStringInternalizationKey;
friend class AstStringConstants; friend class AstStringConstants;
friend class AstValueFactory; 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, AstRawString(bool is_one_byte, const Vector<const byte>& literal_bytes,
uint32_t hash) uint32_t hash)
: AstString(true), hash_(hash), literal_bytes_(literal_bytes) { : next_(nullptr),
bit_field_ |= IsOneByteBits::encode(is_one_byte); 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) { void set_string(Handle<String> string) {
bit_field_ |= IsOneByteBits::encode(true); 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_; uint32_t hash_;
// Points to memory owned by Zone. bool is_one_byte_;
Vector<const byte> literal_bytes_; #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 ZoneObject {
class AstConsString final : public AstString {
public: public:
AstConsString(const AstString* left, const AstString* right) AstConsString* AddString(const AstRawString* s) {
: AstString(false), if (s && !s->IsEmpty()) strings_.push_back(s);
length_(left->length() + right->length()), return this;
left_(left), }
right_(right) {}
int length() const { return length_; } bool IsEmpty() const { return strings_.empty(); }
void Internalize(Isolate* isolate); void Internalize(Isolate* isolate);
V8_INLINE Handle<String> string() const {
DCHECK_NOT_NULL(string_);
return Handle<String>(string_);
}
private: private:
const int length_; friend class AstValueFactory;
const AstString* left_;
const AstString* right_; explicit AstConsString(Zone* zone) : next_(nullptr), strings_(zone) {}
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_;
};
ZoneLinkedList<const AstRawString*> strings_;
}; };
enum class AstSymbol : uint8_t { kHomeObjectSymbol }; enum class AstSymbol : uint8_t { kHomeObjectSymbol };
...@@ -412,7 +417,10 @@ class AstValueFactory { ...@@ -412,7 +417,10 @@ class AstValueFactory {
values_(nullptr), values_(nullptr),
strings_(nullptr), strings_(nullptr),
strings_end_(&strings_), strings_end_(&strings_),
cons_strings_(nullptr),
cons_strings_end_(&cons_strings_),
string_constants_(string_constants), string_constants_(string_constants),
empty_cons_string_(nullptr),
zone_(zone), zone_(zone),
hash_seed_(hash_seed) { hash_seed_(hash_seed) {
#define F(name) name##_ = nullptr; #define F(name) name##_ = nullptr;
...@@ -423,6 +431,7 @@ class AstValueFactory { ...@@ -423,6 +431,7 @@ class AstValueFactory {
std::fill(one_character_strings_, std::fill(one_character_strings_,
one_character_strings_ + arraysize(one_character_strings_), one_character_strings_ + arraysize(one_character_strings_),
nullptr); nullptr);
empty_cons_string_ = NewConsString();
} }
Zone* zone() const { return zone_; } Zone* zone() const { return zone_; }
...@@ -438,17 +447,20 @@ class AstValueFactory { ...@@ -438,17 +447,20 @@ class AstValueFactory {
return GetTwoByteStringInternal(literal); return GetTwoByteStringInternal(literal);
} }
const AstRawString* GetString(Handle<String> literal); const AstRawString* GetString(Handle<String> literal);
const AstConsString* NewConsString(const AstString* left, V8_EXPORT_PRIVATE AstConsString* NewConsString();
const AstString* right); AstConsString* NewConsString(const AstRawString* str);
AstConsString* NewConsString(const AstRawString* str1,
const AstRawString* str2);
V8_EXPORT_PRIVATE void Internalize(Isolate* isolate); V8_EXPORT_PRIVATE void Internalize(Isolate* isolate);
#define F(name, str) \ #define F(name, str) \
const AstRawString* name##_string() { \ const AstRawString* name##_string() const { \
return string_constants_->name##_string(); \ return string_constants_->name##_string(); \
} }
STRING_CONSTANTS(F) STRING_CONSTANTS(F)
#undef F #undef F
const AstConsString* empty_cons_string() const { return empty_cons_string_; }
V8_EXPORT_PRIVATE const AstValue* NewString(const AstRawString* string); V8_EXPORT_PRIVATE const AstValue* NewString(const AstRawString* string);
// A JavaScript symbol (ECMA-262 edition 6). // A JavaScript symbol (ECMA-262 edition 6).
...@@ -472,14 +484,21 @@ class AstValueFactory { ...@@ -472,14 +484,21 @@ class AstValueFactory {
values_ = value; values_ = value;
return value; return value;
} }
AstString* AddString(AstString* string) { AstRawString* AddString(AstRawString* string) {
*strings_end_ = string; *strings_end_ = string;
strings_end_ = string->next_location(); strings_end_ = string->next_location();
return string; return string;
} }
AstConsString* AddConsString(AstConsString* string) {
*cons_strings_end_ = string;
cons_strings_end_ = string->next_location();
return string;
}
void ResetStrings() { void ResetStrings() {
strings_ = nullptr; strings_ = nullptr;
strings_end_ = &strings_; strings_end_ = &strings_;
cons_strings_ = nullptr;
cons_strings_end_ = &cons_strings_;
} }
V8_EXPORT_PRIVATE AstRawString* GetOneByteStringInternal( V8_EXPORT_PRIVATE AstRawString* GetOneByteStringInternal(
Vector<const uint8_t> literal); Vector<const uint8_t> literal);
...@@ -495,11 +514,14 @@ class AstValueFactory { ...@@ -495,11 +514,14 @@ class AstValueFactory {
// We need to keep track of strings_ in order since cons strings require their // We need to keep track of strings_ in order since cons strings require their
// members to be internalized first. // members to be internalized first.
AstString* strings_; AstRawString* strings_;
AstString** strings_end_; AstRawString** strings_end_;
AstConsString* cons_strings_;
AstConsString** cons_strings_end_;
// Holds constant string values which are shared across the isolate. // Holds constant string values which are shared across the isolate.
const AstStringConstants* string_constants_; const AstStringConstants* string_constants_;
const AstConsString* empty_cons_string_;
// Caches for faster access: small numbers, one character lowercase strings // Caches for faster access: small numbers, one character lowercase strings
// (for minified code). // (for minified code).
......
...@@ -164,7 +164,7 @@ void Expression::MarkTail() { ...@@ -164,7 +164,7 @@ void Expression::MarkTail() {
bool DoExpression::IsAnonymousFunctionDefinition() const { bool DoExpression::IsAnonymousFunctionDefinition() const {
// This is specifically to allow DoExpressions to represent ClassLiterals. // This is specifically to allow DoExpressions to represent ClassLiterals.
return represented_function_ != nullptr && return represented_function_ != nullptr &&
represented_function_->raw_name()->length() == 0; represented_function_->raw_name()->IsEmpty();
} }
bool Statement::IsJump() const { bool Statement::IsJump() const {
......
...@@ -2595,8 +2595,8 @@ class FunctionLiteral final : public Expression { ...@@ -2595,8 +2595,8 @@ class FunctionLiteral final : public Expression {
enum EagerCompileHint { kShouldEagerCompile, kShouldLazyCompile }; enum EagerCompileHint { kShouldEagerCompile, kShouldLazyCompile };
Handle<String> name() const { return raw_name_->string(); } Handle<String> name() const { return raw_name_->string(); }
const AstString* raw_name() const { return raw_name_; } const AstConsString* raw_name() const { return raw_name_; }
void set_raw_name(const AstString* name) { raw_name_ = name; } void set_raw_name(const AstConsString* name) { raw_name_ = name; }
DeclarationScope* scope() const { return scope_; } DeclarationScope* scope() const { return scope_; }
ZoneList<Statement*>* body() const { return body_; } ZoneList<Statement*>* body() const { return body_; }
void set_function_token_position(int pos) { function_token_position_ = pos; } void set_function_token_position(int pos) { function_token_position_ = pos; }
...@@ -2658,7 +2658,7 @@ class FunctionLiteral final : public Expression { ...@@ -2658,7 +2658,7 @@ class FunctionLiteral final : public Expression {
raw_inferred_name_ = NULL; 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); DCHECK(raw_inferred_name != NULL);
raw_inferred_name_ = raw_inferred_name; raw_inferred_name_ = raw_inferred_name;
DCHECK(inferred_name_.is_null()); DCHECK(inferred_name_.is_null());
...@@ -2729,7 +2729,7 @@ class FunctionLiteral final : public Expression { ...@@ -2729,7 +2729,7 @@ class FunctionLiteral final : public Expression {
private: private:
friend class AstNodeFactory; friend class AstNodeFactory;
FunctionLiteral(Zone* zone, const AstString* name, FunctionLiteral(Zone* zone, const AstRawString* name,
AstValueFactory* ast_value_factory, DeclarationScope* scope, AstValueFactory* ast_value_factory, DeclarationScope* scope,
ZoneList<Statement*>* body, int expected_property_count, ZoneList<Statement*>* body, int expected_property_count,
int parameter_count, int function_length, int parameter_count, int function_length,
...@@ -2744,10 +2744,10 @@ class FunctionLiteral final : public Expression { ...@@ -2744,10 +2744,10 @@ class FunctionLiteral final : public Expression {
function_token_position_(kNoSourcePosition), function_token_position_(kNoSourcePosition),
suspend_count_(0), suspend_count_(0),
has_braces_(has_braces), has_braces_(has_braces),
raw_name_(name), raw_name_(ast_value_factory->NewConsString(name)),
scope_(scope), scope_(scope),
body_(body), body_(body),
raw_inferred_name_(ast_value_factory->empty_string()), raw_inferred_name_(ast_value_factory->empty_cons_string()),
ast_properties_(zone), ast_properties_(zone),
function_literal_id_(function_literal_id) { function_literal_id_(function_literal_id) {
bit_field_ |= FunctionTypeBits::encode(function_type) | bit_field_ |= FunctionTypeBits::encode(function_type) |
...@@ -2776,10 +2776,10 @@ class FunctionLiteral final : public Expression { ...@@ -2776,10 +2776,10 @@ class FunctionLiteral final : public Expression {
int suspend_count_; int suspend_count_;
bool has_braces_; bool has_braces_;
const AstString* raw_name_; const AstConsString* raw_name_;
DeclarationScope* scope_; DeclarationScope* scope_;
ZoneList<Statement*>* body_; ZoneList<Statement*>* body_;
const AstString* raw_inferred_name_; const AstConsString* raw_inferred_name_;
Handle<String> inferred_name_; Handle<String> inferred_name_;
AstProperties ast_properties_; AstProperties ast_properties_;
int function_literal_id_; int function_literal_id_;
......
...@@ -53,35 +53,26 @@ void FuncNameInferrer::RemoveAsyncKeywordFromEnd() { ...@@ -53,35 +53,26 @@ void FuncNameInferrer::RemoveAsyncKeywordFromEnd() {
} }
} }
const AstString* FuncNameInferrer::MakeNameFromStack() { const AstConsString* FuncNameInferrer::MakeNameFromStack() {
return MakeNameFromStackHelper(0, ast_value_factory_->empty_string()); AstConsString* result = ast_value_factory_->NewConsString();
} for (int pos = 0; pos < names_stack_.length(); pos++) {
const AstString* FuncNameInferrer::MakeNameFromStackHelper(
int pos, const AstString* prev) {
if (pos >= names_stack_.length()) return prev;
if (pos < names_stack_.length() - 1 &&
names_stack_.at(pos).type == kVariableName &&
names_stack_.at(pos + 1).type == kVariableName) {
// Skip consecutive variable declarations. // Skip consecutive variable declarations.
return MakeNameFromStackHelper(pos + 1, prev); if (pos + 1 < names_stack_.length() &&
} else { names_stack_.at(pos).type == kVariableName &&
if (prev->length() > 0) { names_stack_.at(pos + 1).type == kVariableName) {
const AstRawString* name = names_stack_.at(pos).name; continue;
if (prev->length() + name->length() + 1 > String::kMaxLength) return prev;
const AstConsString* curr = ast_value_factory_->NewConsString(
ast_value_factory_->dot_string(), name);
curr = ast_value_factory_->NewConsString(prev, curr);
return MakeNameFromStackHelper(pos + 1, curr);
} else {
return MakeNameFromStackHelper(pos + 1, names_stack_.at(pos).name);
} }
// Add name. Separate names with ".".
if (!result->IsEmpty()) {
result->AddString(ast_value_factory_->dot_string());
}
result->AddString(names_stack_.at(pos).name);
} }
return result;
} }
void FuncNameInferrer::InferFunctionsNames() { void FuncNameInferrer::InferFunctionsNames() {
const AstString* func_name = MakeNameFromStack(); const AstConsString* func_name = MakeNameFromStack();
for (int i = 0; i < funcs_to_infer_.length(); ++i) { for (int i = 0; i < funcs_to_infer_.length(); ++i) {
funcs_to_infer_[i]->set_raw_inferred_name(func_name); funcs_to_infer_[i]->set_raw_inferred_name(func_name);
} }
......
...@@ -10,8 +10,8 @@ ...@@ -10,8 +10,8 @@
namespace v8 { namespace v8 {
namespace internal { namespace internal {
class AstConsString;
class AstRawString; class AstRawString;
class AstString;
class AstValueFactory; class AstValueFactory;
class FunctionLiteral; class FunctionLiteral;
...@@ -105,11 +105,7 @@ class FuncNameInferrer : public ZoneObject { ...@@ -105,11 +105,7 @@ class FuncNameInferrer : public ZoneObject {
Zone* zone() const { return zone_; } Zone* zone() const { return zone_; }
// Constructs a full name in dotted notation from gathered names. // Constructs a full name in dotted notation from gathered names.
const AstString* MakeNameFromStack(); const AstConsString* MakeNameFromStack();
// A helper function for MakeNameFromStack.
const AstString* MakeNameFromStackHelper(int pos,
const AstString* prev);
// Performs name inferring for added functions. // Performs name inferring for added functions.
void InferFunctionsNames(); void InferFunctionsNames();
......
...@@ -3311,8 +3311,8 @@ void Parser::DeclareClassProperty(const AstRawString* class_name, ...@@ -3311,8 +3311,8 @@ void Parser::DeclareClassProperty(const AstRawString* class_name,
class_info->constructor = GetPropertyValue(property)->AsFunctionLiteral(); class_info->constructor = GetPropertyValue(property)->AsFunctionLiteral();
DCHECK_NOT_NULL(class_info->constructor); DCHECK_NOT_NULL(class_info->constructor);
class_info->constructor->set_raw_name( class_info->constructor->set_raw_name(
class_name != nullptr ? class_name class_name != nullptr ? ast_value_factory()->NewConsString(class_name)
: ast_value_factory()->empty_string()); : ast_value_factory()->empty_cons_string());
return; return;
} }
...@@ -4271,10 +4271,11 @@ void Parser::SetFunctionName(Expression* value, const AstRawString* name) { ...@@ -4271,10 +4271,11 @@ void Parser::SetFunctionName(Expression* value, const AstRawString* name) {
if (!value->IsAnonymousFunctionDefinition()) return; if (!value->IsAnonymousFunctionDefinition()) return;
auto function = value->AsFunctionLiteral(); auto function = value->AsFunctionLiteral();
if (function != nullptr) { if (function != nullptr) {
function->set_raw_name(name); function->set_raw_name(ast_value_factory()->NewConsString(name));
} else { } else {
DCHECK(value->IsDoExpression()); DCHECK(value->IsDoExpression());
value->AsDoExpression()->represented_function()->set_raw_name(name); value->AsDoExpression()->represented_function()->set_raw_name(
ast_value_factory()->NewConsString(name));
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment