Index: src/ast/ast.cc |
diff --git a/src/ast/ast.cc b/src/ast/ast.cc |
index d7d70ae4336a0c674c3e2a1307b6f6210c477861..9b04f47ac53dc558027fd16aadf7fec1754f307c 100644 |
--- a/src/ast/ast.cc |
+++ b/src/ast/ast.cc |
@@ -490,7 +490,7 @@ void ObjectLiteral::AssignFeedbackSlots(FeedbackVectorSpec* spec, |
ObjectLiteral::Property* property = properties()->at(property_index); |
Expression* value = property->value(); |
- if (property->kind() != ObjectLiteral::Property::PROTOTYPE) { |
+ if (!property->IsPrototype()) { |
if (FunctionLiteral::NeedsHomeObject(value)) { |
property->SetSlot(spec->AddStoreICSlot(language_mode)); |
} |
@@ -512,7 +512,7 @@ void ObjectLiteral::CalculateEmitStore(Zone* zone) { |
for (int i = properties()->length() - 1; i >= 0; i--) { |
ObjectLiteral::Property* property = properties()->at(i); |
if (property->is_computed_name()) continue; |
- if (property->kind() == ObjectLiteral::Property::PROTOTYPE) continue; |
+ if (property->IsPrototype()) continue; |
Literal* literal = property->key()->AsLiteral(); |
DCHECK(!literal->IsNullLiteral()); |
@@ -532,31 +532,42 @@ void ObjectLiteral::CalculateEmitStore(Zone* zone) { |
} |
} |
- |
-bool ObjectLiteral::IsBoilerplateProperty(ObjectLiteral::Property* property) { |
- return property != NULL && |
- property->kind() != ObjectLiteral::Property::PROTOTYPE; |
+void ObjectLiteral::InitFlagsForPendingNullPrototype(int i) { |
+ // We still check for __proto__:null after computed property names. |
+ for (; i < properties()->length(); i++) { |
+ if (properties()->at(i)->IsNullPrototype()) { |
+ set_has_null_protoype(true); |
+ break; |
+ } |
+ } |
} |
void ObjectLiteral::InitDepthAndFlags() { |
- if (depth_ > 0) return; |
- |
- int position = 0; |
- // Accumulate the value in local variables and store it at the end. |
+ if (is_initialized()) return; |
bool is_simple = true; |
+ bool has_seen_prototype = false; |
int depth_acc = 1; |
- uint32_t max_element_index = 0; |
+ uint32_t nof_properties = 0; |
uint32_t elements = 0; |
+ uint32_t max_element_index = 0; |
for (int i = 0; i < properties()->length(); i++) { |
ObjectLiteral::Property* property = properties()->at(i); |
- if (!IsBoilerplateProperty(property)) { |
+ if (property->IsPrototype()) { |
+ has_seen_prototype = true; |
+ // __proto__:null has no side-effects and is set directly on the |
+ // boilerplate. |
+ if (property->IsNullPrototype()) { |
+ set_has_null_protoype(true); |
+ continue; |
+ } |
+ DCHECK(!has_null_prototype()); |
is_simple = false; |
continue; |
} |
- |
- if (static_cast<uint32_t>(position) == boilerplate_properties_ * 2) { |
+ if (nof_properties == boilerplate_properties_) { |
DCHECK(property->is_computed_name()); |
is_simple = false; |
+ if (!has_seen_prototype) InitFlagsForPendingNullPrototype(i); |
break; |
} |
DCHECK(!property->is_computed_name()); |
@@ -596,15 +607,12 @@ void ObjectLiteral::InitDepthAndFlags() { |
elements++; |
} |
- // Increment the position for the key and the value. |
- position += 2; |
+ nof_properties++; |
} |
- bit_field_ = FastElementsField::update( |
- bit_field_, |
- (max_element_index <= 32) || ((2 * elements) >= max_element_index)); |
- bit_field_ = HasElementsField::update(bit_field_, elements > 0); |
- |
+ set_fast_elements((max_element_index <= 32) || |
+ ((2 * elements) >= max_element_index)); |
+ set_has_elements(elements > 0); |
set_is_simple(is_simple); |
set_depth(depth_acc); |
} |
@@ -616,7 +624,7 @@ void ObjectLiteral::BuildConstantProperties(Isolate* isolate) { |
bool has_seen_proto = false; |
for (int i = 0; i < properties()->length(); i++) { |
ObjectLiteral::Property* property = properties()->at(i); |
- if (!IsBoilerplateProperty(property)) { |
+ if (property->IsPrototype()) { |
has_seen_proto = true; |
continue; |
} |
@@ -641,9 +649,7 @@ void ObjectLiteral::BuildConstantProperties(Isolate* isolate) { |
int position = 0; |
for (int i = 0; i < properties()->length(); i++) { |
ObjectLiteral::Property* property = properties()->at(i); |
- if (!IsBoilerplateProperty(property)) { |
- continue; |
- } |
+ if (property->IsPrototype()) continue; |
if (static_cast<uint32_t>(position) == boilerplate_properties_ * 2) { |
DCHECK(property->is_computed_name()); |
@@ -693,7 +699,7 @@ ElementsKind ArrayLiteral::constant_elements_kind() const { |
void ArrayLiteral::InitDepthAndFlags() { |
DCHECK_LT(first_spread_index_, 0); |
- if (depth_ > 0) return; |
+ if (is_initialized()) return; |
int constants_length = values()->length(); |