__ Drop(2);
}
} else {
- EmitPropertyKey(property);
+ EmitPropertyKey(property, expr->GetIdForProperty(property_index));
VisitForStackValue(value);
switch (property->kind()) {
__ ldr(scratch, MemOperand(sp, 0)); // prototype
}
__ push(scratch);
- EmitPropertyKey(property);
+ EmitPropertyKey(property, lit->GetIdForProperty(i));
VisitForStackValue(value);
EmitSetHomeObjectIfNeeded(value, 2);
__ Drop(2);
}
} else {
- EmitPropertyKey(property);
+ EmitPropertyKey(property, expr->GetIdForProperty(property_index));
VisitForStackValue(value);
switch (property->kind()) {
__ Peek(scratch, 0); // prototype
}
__ Push(scratch);
- EmitPropertyKey(property);
+ EmitPropertyKey(property, lit->GetIdForProperty(i));
VisitForStackValue(value);
EmitSetHomeObjectIfNeeded(value, 2);
void AstNumberingVisitor::VisitClassLiteral(ClassLiteral* node) {
IncrementNodeCount();
DisableOptimization(kClassLiteral);
- node->set_base_id(ReserveIdRange(ClassLiteral::num_ids()));
+ node->set_base_id(ReserveIdRange(node->num_ids()));
if (node->extends()) Visit(node->extends());
if (node->constructor()) Visit(node->constructor());
if (node->class_variable_proxy()) {
void AstNumberingVisitor::VisitObjectLiteral(ObjectLiteral* node) {
IncrementNodeCount();
- node->set_base_id(ReserveIdRange(ObjectLiteral::num_ids()));
+ node->set_base_id(ReserveIdRange(node->num_ids()));
for (int i = 0; i < node->properties()->length(); i++) {
VisitObjectLiteralProperty(node->properties()->at(i));
}
BailoutId CreateLiteralId() const { return BailoutId(local_id(0)); }
- static int num_ids() { return parent_num_ids() + 1; }
+ // Return an AST id for a property that is used in simulate instructions.
+ BailoutId GetIdForProperty(int i) { return BailoutId(local_id(i + 1)); }
+
+ // Unlike other AST nodes, this number of bailout IDs allocated for an
+ // ObjectLiteral can vary, so num_ids() is not a static method.
+ int num_ids() const { return parent_num_ids() + 1 + properties()->length(); }
protected:
ObjectLiteral(Zone* zone, ZoneList<Property*>* properties, int literal_index,
int start_position() const { return position(); }
int end_position() const { return end_position_; }
- static int num_ids() { return parent_num_ids() + 3; }
BailoutId EntryId() const { return BailoutId(local_id(0)); }
BailoutId DeclsId() const { return BailoutId(local_id(1)); }
BailoutId ExitId() { return BailoutId(local_id(2)); }
+ // Return an AST id for a property that is used in simulate instructions.
+ BailoutId GetIdForProperty(int i) { return BailoutId(local_id(i + 3)); }
+
+ // Unlike other AST nodes, this number of bailout IDs allocated for an
+ // ClassLiteral can vary, so num_ids() is not a static method.
+ int num_ids() const { return parent_num_ids() + 3 + properties()->length(); }
+
protected:
ClassLiteral(Zone* zone, const AstRawString* name, Scope* scope,
VariableProxy* class_variable_proxy, Expression* extends,
environment()->Push(property->is_static() ? literal : proto);
VisitForValue(property->key());
- environment()->Push(BuildToName(environment()->Pop()));
+ environment()->Push(
+ BuildToName(environment()->Pop(), expr->GetIdForProperty(i)));
VisitForValue(property->value());
Node* value = environment()->Pop();
Node* key = environment()->Pop();
environment()->Push(literal); // Duplicate receiver.
VisitForValue(property->key());
- environment()->Push(BuildToName(environment()->Pop()));
+ environment()->Push(BuildToName(environment()->Pop(),
+ expr->GetIdForProperty(property_index)));
// TODO(mstarzinger): For ObjectLiteral::Property::PROTOTYPE the key should
// not be on the operand stack while the value is being evaluated. Come up
// with a repro for this and fix it. Also find a nice way to do so. :)
}
-Node* AstGraphBuilder::BuildToName(Node* input) {
+Node* AstGraphBuilder::BuildToName(Node* input, BailoutId bailout_id) {
// TODO(turbofan): Possible optimization is to NOP on name constants. But the
// same caveat as with BuildToBoolean applies, and it should be factored out
// into a JSOperatorReducer.
- return NewNode(javascript()->ToName(), input);
+ Node* name = NewNode(javascript()->ToName(), input);
+ PrepareFrameState(name, bailout_id);
+ return name;
}
// Builders for automatic type conversion.
Node* BuildToBoolean(Node* value);
- Node* BuildToName(Node* value);
+ Node* BuildToName(Node* value, BailoutId bailout_id);
// Builders for error reporting at runtime.
Node* BuildThrowReferenceError(Variable* var, BailoutId bailout_id);
// Conversions
case IrOpcode::kJSToObject:
case IrOpcode::kJSToNumber:
+ case IrOpcode::kJSToName:
// Properties
case IrOpcode::kJSLoadNamed:
}
-void FullCodeGenerator::EmitPropertyKey(ObjectLiteralProperty* property) {
+void FullCodeGenerator::EmitPropertyKey(ObjectLiteralProperty* property,
+ BailoutId bailout_id) {
VisitForStackValue(property->key());
__ InvokeBuiltin(Builtins::TO_NAME, CALL_FUNCTION);
+ PrepareForBailoutForId(bailout_id, NO_REGISTERS);
__ Push(result_register());
}
void EmitClassDefineProperties(ClassLiteral* lit);
// Pushes the property key as a Name on the stack.
- void EmitPropertyKey(ObjectLiteralProperty* property);
+ void EmitPropertyKey(ObjectLiteralProperty* property, BailoutId bailout_id);
// Apply the compound assignment operator. Expects the left operand on top
// of the stack and the right one in the accumulator.
__ Drop(2);
}
} else {
- EmitPropertyKey(property);
+ EmitPropertyKey(property, expr->GetIdForProperty(property_index));
VisitForStackValue(value);
switch (property->kind()) {
} else {
__ push(Operand(esp, 0)); // prototype
}
- EmitPropertyKey(property);
+ EmitPropertyKey(property, lit->GetIdForProperty(i));
VisitForStackValue(value);
EmitSetHomeObjectIfNeeded(value, 2);
__ Drop(2);
}
} else {
- EmitPropertyKey(property);
+ EmitPropertyKey(property, expr->GetIdForProperty(property_index));
VisitForStackValue(value);
switch (property->kind()) {
__ lw(scratch, MemOperand(sp, 0)); // prototype
}
__ push(scratch);
- EmitPropertyKey(property);
+ EmitPropertyKey(property, lit->GetIdForProperty(i));
VisitForStackValue(value);
EmitSetHomeObjectIfNeeded(value, 2);
__ Drop(2);
}
} else {
- EmitPropertyKey(property);
+ EmitPropertyKey(property, expr->GetIdForProperty(property_index));
VisitForStackValue(value);
switch (property->kind()) {
__ ld(scratch, MemOperand(sp, 0)); // prototype
}
__ push(scratch);
- EmitPropertyKey(property);
+ EmitPropertyKey(property, lit->GetIdForProperty(i));
VisitForStackValue(value);
EmitSetHomeObjectIfNeeded(value, 2);
__ Drop(2);
}
} else {
- EmitPropertyKey(property);
+ EmitPropertyKey(property, expr->GetIdForProperty(property_index));
VisitForStackValue(value);
switch (property->kind()) {
} else {
__ Push(Operand(rsp, 0)); // prototype
}
- EmitPropertyKey(property);
+ EmitPropertyKey(property, lit->GetIdForProperty(i));
VisitForStackValue(value);
EmitSetHomeObjectIfNeeded(value, 2);
__ Drop(2);
}
} else {
- EmitPropertyKey(property);
+ EmitPropertyKey(property, expr->GetIdForProperty(property_index));
VisitForStackValue(value);
switch (property->kind()) {
} else {
__ push(Operand(esp, 0)); // prototype
}
- EmitPropertyKey(property);
+ EmitPropertyKey(property, lit->GetIdForProperty(i));
VisitForStackValue(value);
EmitSetHomeObjectIfNeeded(value, 2);
--- /dev/null
+// Copyright 2015 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --harmony-computed-property-names --harmony-classes --harmony-sloppy
+
+assertThrows(function f() {
+ var t = { toString: function() { throw new Error(); } };
+ var o = { [t]: 23 };
+}, Error);
+
+assertThrows(function f() {
+ var t = { toString: function() { throw new Error(); } };
+ class C { [t]() { return 23; } };
+}, Error);
SHARED(ToBoolean, Operator::kPure, 1, 0, 0, 0, 1, 0),
SHARED(ToNumber, Operator::kNoProperties, 1, 1, 1, 1, 1, 1),
SHARED(ToString, Operator::kNoProperties, 1, 0, 1, 1, 1, 1),
- SHARED(ToName, Operator::kNoProperties, 1, 0, 1, 1, 1, 1),
+ SHARED(ToName, Operator::kNoProperties, 1, 1, 1, 1, 1, 1),
SHARED(ToObject, Operator::kNoProperties, 1, 1, 1, 1, 1, 1),
SHARED(Yield, Operator::kNoProperties, 1, 0, 1, 1, 1, 1),
SHARED(Create, Operator::kEliminatable, 0, 0, 1, 1, 1, 1),