summaryrefslogtreecommitdiff
path: root/deps/v8/src/ast/ast.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/ast/ast.cc')
-rw-r--r--deps/v8/src/ast/ast.cc121
1 files changed, 78 insertions, 43 deletions
diff --git a/deps/v8/src/ast/ast.cc b/deps/v8/src/ast/ast.cc
index 15b8bff61b..5a4add6039 100644
--- a/deps/v8/src/ast/ast.cc
+++ b/deps/v8/src/ast/ast.cc
@@ -7,7 +7,6 @@
#include <cmath> // For isfinite.
#include <vector>
-#include "src/ast/compile-time-value.h"
#include "src/ast/prettyprinter.h"
#include "src/ast/scopes.h"
#include "src/base/hashmap.h"
@@ -19,6 +18,7 @@
#include "src/double.h"
#include "src/elements.h"
#include "src/objects-inl.h"
+#include "src/objects/literal-objects-inl.h"
#include "src/objects/literal-objects.h"
#include "src/objects/map.h"
#include "src/property-details.h"
@@ -114,6 +114,13 @@ bool Expression::IsTheHoleLiteral() const {
return IsLiteral() && AsLiteral()->type() == Literal::kTheHole;
}
+bool Expression::IsCompileTimeValue() {
+ if (IsLiteral()) return true;
+ MaterializedLiteral* literal = AsMaterializedLiteral();
+ if (literal == nullptr) return false;
+ return literal->IsSimple();
+}
+
bool Expression::IsUndefinedLiteral() const {
if (IsLiteral() && AsLiteral()->type() == Literal::kUndefined) return true;
@@ -334,8 +341,7 @@ ClassLiteralProperty::ClassLiteralProperty(Expression* key, Expression* value,
bool ObjectLiteral::Property::IsCompileTimeValue() const {
return kind_ == CONSTANT ||
- (kind_ == MATERIALIZED_LITERAL &&
- CompileTimeValue::IsCompileTimeValue(value_));
+ (kind_ == MATERIALIZED_LITERAL && value_->IsCompileTimeValue());
}
@@ -360,19 +366,37 @@ void ObjectLiteral::CalculateEmitStore(Zone* zone) {
Literal* literal = property->key()->AsLiteral();
DCHECK(!literal->IsNullLiteral());
- // If there is an existing entry do not emit a store unless the previous
- // entry was also an accessor.
uint32_t hash = literal->Hash();
ZoneHashMap::Entry* entry = table.LookupOrInsert(literal, hash, allocator);
- if (entry->value != nullptr) {
- auto previous_kind =
+ if (entry->value == nullptr) {
+ entry->value = property;
+ } else {
+ // We already have a later definition of this property, so we don't need
+ // to emit a store for the current one.
+ //
+ // There are two subtleties here.
+ //
+ // (1) Emitting a store might actually be incorrect. For example, in {get
+ // foo() {}, foo: 42}, the getter store would override the data property
+ // (which, being a non-computed compile-time valued property, is already
+ // part of the initial literal object.
+ //
+ // (2) If the later definition is an accessor (say, a getter), and the
+ // current definition is a complementary accessor (here, a setter), then
+ // we still must emit a store for the current definition.
+
+ auto later_kind =
static_cast<ObjectLiteral::Property*>(entry->value)->kind();
- if (!((property->kind() == GETTER && previous_kind == SETTER) ||
- (property->kind() == SETTER && previous_kind == GETTER))) {
+ bool complementary_accessors =
+ (property->kind() == GETTER && later_kind == SETTER) ||
+ (property->kind() == SETTER && later_kind == GETTER);
+ if (!complementary_accessors) {
property->set_emit_store(false);
+ if (later_kind == GETTER || later_kind == SETTER) {
+ entry->value = property;
+ }
}
}
- entry->value = property;
}
}
@@ -427,7 +451,7 @@ int ObjectLiteral::InitDepthAndFlags() {
Literal* key = property->key()->AsLiteral();
Expression* value = property->value();
- bool is_compile_time_value = CompileTimeValue::IsCompileTimeValue(value);
+ bool is_compile_time_value = value->IsCompileTimeValue();
is_simple = is_simple && is_compile_time_value;
// Keep track of the number of elements in the object literal and
@@ -454,8 +478,8 @@ int ObjectLiteral::InitDepthAndFlags() {
return depth_acc;
}
-void ObjectLiteral::BuildConstantProperties(Isolate* isolate) {
- if (!constant_properties_.is_null()) return;
+void ObjectLiteral::BuildBoilerplateDescription(Isolate* isolate) {
+ if (!boilerplate_description_.is_null()) return;
int index_keys = 0;
bool has_seen_proto = false;
@@ -476,17 +500,17 @@ void ObjectLiteral::BuildConstantProperties(Isolate* isolate) {
}
}
- Handle<BoilerplateDescription> constant_properties =
- isolate->factory()->NewBoilerplateDescription(boilerplate_properties_,
- properties()->length(),
- index_keys, has_seen_proto);
+ Handle<ObjectBoilerplateDescription> boilerplate_description =
+ isolate->factory()->NewObjectBoilerplateDescription(
+ boilerplate_properties_, properties()->length(), index_keys,
+ has_seen_proto);
int position = 0;
for (int i = 0; i < properties()->length(); i++) {
ObjectLiteral::Property* property = properties()->at(i);
if (property->IsPrototype()) continue;
- if (static_cast<uint32_t>(position) == boilerplate_properties_ * 2) {
+ if (static_cast<uint32_t>(position) == boilerplate_properties_) {
DCHECK(property->is_computed_name());
break;
}
@@ -510,11 +534,12 @@ void ObjectLiteral::BuildConstantProperties(Isolate* isolate) {
Handle<Object> value = GetBoilerplateValue(property->value(), isolate);
// Add name, value pair to the fixed array.
- constant_properties->set(position++, *key);
- constant_properties->set(position++, *value);
+ boilerplate_description->set_key_value(position++, *key, *value);
}
- constant_properties_ = constant_properties;
+ boilerplate_description->set_flags(EncodeLiteralType());
+
+ boilerplate_description_ = boilerplate_description;
}
bool ObjectLiteral::IsFastCloningSupported() const {
@@ -528,8 +553,8 @@ bool ObjectLiteral::IsFastCloningSupported() const {
bool ArrayLiteral::is_empty() const {
DCHECK(is_initialized());
- return values()->is_empty() &&
- (constant_elements().is_null() || constant_elements()->is_empty());
+ return values()->is_empty() && (boilerplate_description().is_null() ||
+ boilerplate_description()->is_empty());
}
int ArrayLiteral::InitDepthAndFlags() {
@@ -550,7 +575,7 @@ int ArrayLiteral::InitDepthAndFlags() {
if (subliteral_depth > depth_acc) depth_acc = subliteral_depth;
}
- if (!CompileTimeValue::IsCompileTimeValue(element)) {
+ if (!element->IsCompileTimeValue()) {
is_simple = false;
}
}
@@ -563,8 +588,8 @@ int ArrayLiteral::InitDepthAndFlags() {
return depth_acc;
}
-void ArrayLiteral::BuildConstantElements(Isolate* isolate) {
- if (!constant_elements_.is_null()) return;
+void ArrayLiteral::BuildBoilerplateDescription(Isolate* isolate) {
+ if (!boilerplate_description_.is_null()) return;
int constants_length =
first_spread_index_ >= 0 ? first_spread_index_ : values()->length();
@@ -606,7 +631,7 @@ void ArrayLiteral::BuildConstantElements(Isolate* isolate) {
// elements array to a copy-on-write array.
if (is_simple() && depth() == 1 && array_index > 0 &&
IsSmiOrObjectElementsKind(kind)) {
- fixed_array->set_map(isolate->heap()->fixed_cow_array_map());
+ fixed_array->set_map(ReadOnlyRoots(isolate).fixed_cow_array_map());
}
Handle<FixedArrayBase> elements = fixed_array;
@@ -615,14 +640,12 @@ void ArrayLiteral::BuildConstantElements(Isolate* isolate) {
elements = isolate->factory()->NewFixedDoubleArray(constants_length);
// We are copying from non-fast-double to fast-double.
ElementsKind from_kind = TERMINAL_FAST_ELEMENTS_KIND;
- accessor->CopyElements(fixed_array, from_kind, elements, constants_length);
+ accessor->CopyElements(isolate, fixed_array, from_kind, elements,
+ constants_length);
}
- // Remember both the literal's constant values as well as the ElementsKind.
- Handle<ConstantElementsPair> literals =
- isolate->factory()->NewConstantElementsPair(kind, elements);
-
- constant_elements_ = literals;
+ boilerplate_description_ =
+ isolate->factory()->NewArrayBoilerplateDescription(kind, elements);
}
bool ArrayLiteral::IsFastCloningSupported() const {
@@ -643,8 +666,17 @@ Handle<Object> MaterializedLiteral::GetBoilerplateValue(Expression* expression,
if (expression->IsLiteral()) {
return expression->AsLiteral()->BuildValue(isolate);
}
- if (CompileTimeValue::IsCompileTimeValue(expression)) {
- return CompileTimeValue::GetValue(isolate, expression);
+ if (expression->IsCompileTimeValue()) {
+ if (expression->IsObjectLiteral()) {
+ ObjectLiteral* object_literal = expression->AsObjectLiteral();
+ DCHECK(object_literal->is_simple());
+ return object_literal->boilerplate_description();
+ } else {
+ DCHECK(expression->IsArrayLiteral());
+ ArrayLiteral* array_literal = expression->AsArrayLiteral();
+ DCHECK(array_literal->is_simple());
+ return array_literal->boilerplate_description();
+ }
}
return isolate->factory()->uninitialized_value();
}
@@ -669,10 +701,12 @@ bool MaterializedLiteral::NeedsInitialAllocationSite() {
void MaterializedLiteral::BuildConstants(Isolate* isolate) {
if (IsArrayLiteral()) {
- return AsArrayLiteral()->BuildConstantElements(isolate);
+ AsArrayLiteral()->BuildBoilerplateDescription(isolate);
+ return;
}
if (IsObjectLiteral()) {
- return AsObjectLiteral()->BuildConstantProperties(isolate);
+ AsObjectLiteral()->BuildBoilerplateDescription(isolate);
+ return;
}
DCHECK(IsRegExpLiteral());
}
@@ -698,7 +732,7 @@ Handle<TemplateObjectDescription> GetTemplateObject::GetOrBuildDescription(
if (this->cooked_strings()->at(i) != nullptr) {
cooked_strings->set(i, *this->cooked_strings()->at(i)->string());
} else {
- cooked_strings->set(i, isolate->heap()->undefined_value());
+ cooked_strings->set(i, ReadOnlyRoots(isolate).undefined_value());
}
}
}
@@ -806,9 +840,10 @@ Call::CallType Call::GetCallType() const {
if (proxy->var()->IsUnallocated()) {
return GLOBAL_CALL;
} else if (proxy->var()->IsLookupSlot()) {
- // Calls going through 'with' always use DYNAMIC rather than DYNAMIC_LOCAL
- // or DYNAMIC_GLOBAL.
- return proxy->var()->mode() == DYNAMIC ? WITH_CALL : OTHER_CALL;
+ // Calls going through 'with' always use VariableMode::kDynamic rather
+ // than VariableMode::kDynamicLocal or VariableMode::kDynamicGlobal.
+ return proxy->var()->mode() == VariableMode::kDynamic ? WITH_CALL
+ : OTHER_CALL;
}
}
@@ -831,7 +866,7 @@ Call::CallType Call::GetCallType() const {
return OTHER_CALL;
}
-CaseClause::CaseClause(Expression* label, ZoneList<Statement*>* statements)
+CaseClause::CaseClause(Expression* label, ZonePtrList<Statement>* statements)
: label_(label), statements_(statements) {}
bool Literal::IsPropertyName() const {
@@ -954,7 +989,7 @@ const char* CallRuntime::debug_name() {
case k##NodeType: \
return static_cast<const NodeType*>(this)->labels();
-ZoneList<const AstRawString*>* BreakableStatement::labels() const {
+ZonePtrList<const AstRawString>* BreakableStatement::labels() const {
switch (node_type()) {
BREAKABLE_NODE_LIST(RETURN_LABELS)
ITERATION_NODE_LIST(RETURN_LABELS)