Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(89)

Unified Diff: src/compiler/ast-graph-builder.cc

Issue 1149133005: [es6] Add TF support for super.property (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/compiler/ast-graph-builder.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/compiler/ast-graph-builder.cc
diff --git a/src/compiler/ast-graph-builder.cc b/src/compiler/ast-graph-builder.cc
index a200c701935333f40953e1728b4835205054b48d..d53d2c347a6a24f8d16c066af1f49c2557f6d8d3 100644
--- a/src/compiler/ast-graph-builder.cc
+++ b/src/compiler/ast-graph-builder.cc
@@ -563,8 +563,10 @@ void AstGraphBuilder::CreateGraphBody(bool stack_check) {
Variable* rest_parameter = scope->rest_parameter(&rest_index);
BuildRestArgumentsArray(rest_parameter, rest_index);
- if (scope->this_function_var() != nullptr ||
- scope->new_target_var() != nullptr) {
+ // Build .this_function var if it is used.
+ BuildThisFunctionVar(scope->this_function_var());
+
+ if (scope->new_target_var() != nullptr) {
SetStackOverflow();
}
@@ -630,22 +632,6 @@ void AstGraphBuilder::ClearNonLiveSlotsInFrameStates() {
}
-// Left-hand side can only be a property, a global or a variable slot.
-enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY };
-
-
-// Determine the left-hand side kind of an assignment.
-static LhsKind DetermineLhsKind(Expression* expr) {
- Property* property = expr->AsProperty();
- DCHECK(expr->IsValidReferenceExpression());
- LhsKind lhs_kind =
- (property == NULL) ? VARIABLE : (property->key()->IsPropertyName())
- ? NAMED_PROPERTY
- : KEYED_PROPERTY;
- return lhs_kind;
-}
-
-
// Gets the bailout id just before reading a variable proxy, but only for
// unallocated variables.
static BailoutId BeforeId(VariableProxy* proxy) {
@@ -1971,7 +1957,7 @@ void AstGraphBuilder::VisitForInAssignment(Expression* expr, Node* value,
// Left-hand side can only be a property, a global or a variable slot.
Property* property = expr->AsProperty();
- LhsKind assign_type = DetermineLhsKind(expr);
+ LhsKind assign_type = Property::GetAssignType(property);
// Evaluate LHS expression and store the value.
switch (assign_type) {
@@ -2005,6 +1991,35 @@ void AstGraphBuilder::VisitForInAssignment(Expression* expr, Node* value,
states.AddToNode(store, bailout_id, OutputFrameStateCombine::Ignore());
break;
}
+ case NAMED_SUPER_PROPERTY: {
+ environment()->Push(value);
+ VisitForValue(property->obj()->AsSuperPropertyReference()->this_var());
+ VisitForValue(property->obj()->AsSuperPropertyReference()->home_object());
+ FrameStateBeforeAndAfter states(this, property->obj()->id());
+ Node* home_object = environment()->Pop();
+ Node* receiver = environment()->Pop();
+ value = environment()->Pop();
+ Handle<Name> name = property->key()->AsLiteral()->AsPropertyName();
+ Node* store = BuildNamedSuperStore(receiver, home_object, name, value,
+ TypeFeedbackId::None());
+ states.AddToNode(store, bailout_id, OutputFrameStateCombine::Ignore());
+ break;
+ }
+ case KEYED_SUPER_PROPERTY: {
+ environment()->Push(value);
+ VisitForValue(property->obj()->AsSuperPropertyReference()->this_var());
+ VisitForValue(property->obj()->AsSuperPropertyReference()->home_object());
+ VisitForValue(property->key());
+ FrameStateBeforeAndAfter states(this, property->key()->id());
+ Node* key = environment()->Pop();
+ Node* home_object = environment()->Pop();
+ Node* receiver = environment()->Pop();
+ value = environment()->Pop();
+ Node* store = BuildKeyedSuperStore(receiver, home_object, key, value,
+ TypeFeedbackId::None());
+ states.AddToNode(store, bailout_id, OutputFrameStateCombine::Ignore());
+ break;
+ }
}
}
@@ -2014,7 +2029,7 @@ void AstGraphBuilder::VisitAssignment(Assignment* expr) {
// Left-hand side can only be a property, a global or a variable slot.
Property* property = expr->target()->AsProperty();
- LhsKind assign_type = DetermineLhsKind(expr->target());
+ LhsKind assign_type = Property::GetAssignType(property);
bool needs_frame_state_before = true;
// Evaluate LHS expression.
@@ -2031,11 +2046,19 @@ void AstGraphBuilder::VisitAssignment(Assignment* expr) {
case NAMED_PROPERTY:
VisitForValue(property->obj());
break;
- case KEYED_PROPERTY: {
+ case KEYED_PROPERTY:
VisitForValue(property->obj());
VisitForValue(property->key());
break;
- }
+ case NAMED_SUPER_PROPERTY:
+ VisitForValue(property->obj()->AsSuperPropertyReference()->this_var());
+ VisitForValue(property->obj()->AsSuperPropertyReference()->home_object());
+ break;
+ case KEYED_SUPER_PROPERTY:
+ VisitForValue(property->obj()->AsSuperPropertyReference()->this_var());
+ VisitForValue(property->obj()->AsSuperPropertyReference()->home_object());
+ VisitForValue(property->key());
+ break;
}
BailoutId before_store_id = BailoutId::None();
@@ -2076,6 +2099,30 @@ void AstGraphBuilder::VisitAssignment(Assignment* expr) {
OutputFrameStateCombine::Push());
break;
}
+ case NAMED_SUPER_PROPERTY: {
+ Node* home_object = environment()->Top();
+ Node* receiver = environment()->Peek(1);
+ Handle<Name> name = property->key()->AsLiteral()->AsPropertyName();
+ VectorSlotPair pair =
+ CreateVectorSlotPair(property->PropertyFeedbackSlot());
+ FrameStateBeforeAndAfter states(this, property->obj()->id());
+ old_value = BuildNamedSuperLoad(receiver, home_object, name, pair);
+ states.AddToNode(old_value, property->LoadId(),
+ OutputFrameStateCombine::Push());
+ break;
+ }
+ case KEYED_SUPER_PROPERTY: {
+ Node* key = environment()->Top();
+ Node* home_object = environment()->Peek(1);
+ Node* receiver = environment()->Peek(2);
+ VectorSlotPair pair =
+ CreateVectorSlotPair(property->PropertyFeedbackSlot());
+ FrameStateBeforeAndAfter states(this, property->key()->id());
+ old_value = BuildKeyedSuperLoad(receiver, home_object, key, pair);
+ states.AddToNode(old_value, property->LoadId(),
+ OutputFrameStateCombine::Push());
+ break;
+ }
}
environment()->Push(old_value);
VisitForValue(expr->value());
@@ -2127,6 +2174,26 @@ void AstGraphBuilder::VisitAssignment(Assignment* expr) {
ast_context()->GetStateCombine());
break;
}
+ case NAMED_SUPER_PROPERTY: {
+ Node* home_object = environment()->Pop();
+ Node* receiver = environment()->Pop();
+ Handle<Name> name = property->key()->AsLiteral()->AsPropertyName();
+ Node* store = BuildNamedSuperStore(receiver, home_object, name, value,
+ expr->AssignmentFeedbackId());
+ store_states.AddToNode(store, expr->id(),
+ ast_context()->GetStateCombine());
+ break;
+ }
+ case KEYED_SUPER_PROPERTY: {
+ Node* key = environment()->Pop();
+ Node* home_object = environment()->Pop();
+ Node* receiver = environment()->Pop();
+ Node* store = BuildKeyedSuperStore(receiver, home_object, key, value,
+ expr->AssignmentFeedbackId());
+ store_states.AddToNode(store, expr->id(),
+ ast_context()->GetStateCombine());
+ break;
+ }
}
ast_context()->ProduceValue(value);
@@ -2150,22 +2217,55 @@ void AstGraphBuilder::VisitThrow(Throw* expr) {
void AstGraphBuilder::VisitProperty(Property* expr) {
Node* value;
brucedawson 2015/06/08 17:24:50 It is not clear that 'value' will always be initia
+ LhsKind property_kind = Property::GetAssignType(expr);
VectorSlotPair pair = CreateVectorSlotPair(expr->PropertyFeedbackSlot());
- if (expr->key()->IsPropertyName()) {
- VisitForValue(expr->obj());
- FrameStateBeforeAndAfter states(this, expr->obj()->id());
- Node* object = environment()->Pop();
- Handle<Name> name = expr->key()->AsLiteral()->AsPropertyName();
- value = BuildNamedLoad(object, name, pair);
- states.AddToNode(value, expr->id(), ast_context()->GetStateCombine());
- } else {
- VisitForValue(expr->obj());
- VisitForValue(expr->key());
- FrameStateBeforeAndAfter states(this, expr->key()->id());
- Node* key = environment()->Pop();
- Node* object = environment()->Pop();
- value = BuildKeyedLoad(object, key, pair);
- states.AddToNode(value, expr->id(), ast_context()->GetStateCombine());
+ switch (property_kind) {
+ case VARIABLE:
+ UNREACHABLE();
+ value = nullptr;
brucedawson 2015/06/08 17:24:50 i.e.; move this assignment to the variable declara
+ break;
+ case NAMED_PROPERTY: {
+ VisitForValue(expr->obj());
+ FrameStateBeforeAndAfter states(this, expr->obj()->id());
+ Node* object = environment()->Pop();
+ Handle<Name> name = expr->key()->AsLiteral()->AsPropertyName();
+ value = BuildNamedLoad(object, name, pair);
+ states.AddToNode(value, expr->id(), ast_context()->GetStateCombine());
+ break;
+ }
+ case KEYED_PROPERTY: {
+ VisitForValue(expr->obj());
+ VisitForValue(expr->key());
+ FrameStateBeforeAndAfter states(this, expr->key()->id());
+ Node* key = environment()->Pop();
+ Node* object = environment()->Pop();
+ value = BuildKeyedLoad(object, key, pair);
+ states.AddToNode(value, expr->id(), ast_context()->GetStateCombine());
+ break;
+ }
+ case NAMED_SUPER_PROPERTY: {
+ VisitForValue(expr->obj()->AsSuperPropertyReference()->this_var());
+ VisitForValue(expr->obj()->AsSuperPropertyReference()->home_object());
+ FrameStateBeforeAndAfter states(this, expr->obj()->id());
+ Node* home_object = environment()->Pop();
+ Node* receiver = environment()->Pop();
+ Handle<Name> name = expr->key()->AsLiteral()->AsPropertyName();
+ value = BuildNamedSuperLoad(receiver, home_object, name, pair);
+ states.AddToNode(value, expr->id(), ast_context()->GetStateCombine());
+ break;
+ }
+ case KEYED_SUPER_PROPERTY: {
+ VisitForValue(expr->obj()->AsSuperPropertyReference()->this_var());
+ VisitForValue(expr->obj()->AsSuperPropertyReference()->home_object());
+ VisitForValue(expr->key());
+ FrameStateBeforeAndAfter states(this, expr->key()->id());
+ Node* key = environment()->Pop();
+ Node* home_object = environment()->Pop();
+ Node* receiver = environment()->Pop();
+ value = BuildKeyedSuperLoad(receiver, home_object, key, pair);
+ states.AddToNode(value, expr->id(), ast_context()->GetStateCombine());
+ break;
+ }
}
ast_context()->ProduceValue(value);
}
@@ -2208,29 +2308,58 @@ void AstGraphBuilder::VisitCall(Call* expr) {
}
case Call::PROPERTY_CALL: {
Property* property = callee->AsProperty();
- VisitForValue(property->obj());
- Node* object = environment()->Top();
VectorSlotPair pair =
CreateVectorSlotPair(property->PropertyFeedbackSlot());
- if (property->key()->IsPropertyName()) {
- FrameStateBeforeAndAfter states(this, property->obj()->id());
- Handle<Name> name = property->key()->AsLiteral()->AsPropertyName();
- callee_value = BuildNamedLoad(object, name, pair);
- states.AddToNode(callee_value, property->LoadId(),
- OutputFrameStateCombine::Push());
+ if (!property->IsSuperAccess()) {
Michael Starzinger 2015/06/05 13:28:19 Could this be modeled as a switch over the LhsKind
arv (Not doing code reviews) 2015/06/05 13:50:26 I tried it but reverted back to the ifs. I found t
Michael Starzinger 2015/06/05 13:53:23 Acknowledged. OK, then let's leave it as it is.
+ VisitForValue(property->obj());
+ Node* object = environment()->Top();
+
+ if (property->key()->IsPropertyName()) {
+ FrameStateBeforeAndAfter states(this, property->obj()->id());
+ Handle<Name> name = property->key()->AsLiteral()->AsPropertyName();
+ callee_value = BuildNamedLoad(object, name, pair);
+ states.AddToNode(callee_value, property->LoadId(),
+ OutputFrameStateCombine::Push());
+ } else {
+ VisitForValue(property->key());
+ FrameStateBeforeAndAfter states(this, property->key()->id());
+ Node* key = environment()->Pop();
+ callee_value = BuildKeyedLoad(object, key, pair);
+ states.AddToNode(callee_value, property->LoadId(),
+ OutputFrameStateCombine::Push());
+ }
+ receiver_value = environment()->Pop();
+ // Note that a PROPERTY_CALL requires the receiver to be wrapped into an
+ // object for sloppy callees. This could also be modeled explicitly
+ // here,
+ // thereby obsoleting the need for a flag to the call operator.
+ flags = CALL_AS_METHOD;
+
} else {
- VisitForValue(property->key());
- FrameStateBeforeAndAfter states(this, property->key()->id());
- Node* key = environment()->Pop();
- callee_value = BuildKeyedLoad(object, key, pair);
- states.AddToNode(callee_value, property->LoadId(),
- OutputFrameStateCombine::Push());
+ VisitForValue(property->obj()->AsSuperPropertyReference()->this_var());
+ VisitForValue(
+ property->obj()->AsSuperPropertyReference()->home_object());
+ Node* home_object = environment()->Pop();
+ receiver_value = environment()->Pop();
+ if (property->key()->IsPropertyName()) {
+ FrameStateBeforeAndAfter states(this, property->obj()->id());
+ Handle<Name> name = property->key()->AsLiteral()->AsPropertyName();
+ callee_value =
+ BuildNamedSuperLoad(receiver_value, home_object, name, pair);
+ states.AddToNode(callee_value, property->LoadId(),
+ OutputFrameStateCombine::Push());
+
+ } else {
+ VisitForValue(property->key());
+ FrameStateBeforeAndAfter states(this, property->key()->id());
+ Node* key = environment()->Pop();
+ callee_value =
+ BuildKeyedSuperLoad(receiver_value, home_object, key, pair);
+ states.AddToNode(callee_value, property->LoadId(),
+ OutputFrameStateCombine::Push());
+ }
}
- receiver_value = environment()->Pop();
- // Note that a PROPERTY_CALL requires the receiver to be wrapped into an
- // object for sloppy callees. This could also be modeled explicitly here,
- // thereby obsoleting the need for a flag to the call operator.
- flags = CALL_AS_METHOD;
+
break;
}
case Call::SUPER_CALL:
@@ -2400,7 +2529,7 @@ void AstGraphBuilder::VisitCountOperation(CountOperation* expr) {
// Left-hand side can only be a property, a global or a variable slot.
Property* property = expr->expression()->AsProperty();
- LhsKind assign_type = DetermineLhsKind(expr->expression());
+ LhsKind assign_type = Property::GetAssignType(property);
// Reserve space for result of postfix operation.
bool is_postfix = expr->is_postfix() && !ast_context()->IsEffect();
@@ -2447,6 +2576,37 @@ void AstGraphBuilder::VisitCountOperation(CountOperation* expr) {
stack_depth = 2;
break;
}
+ case NAMED_SUPER_PROPERTY: {
+ VisitForValue(property->obj()->AsSuperPropertyReference()->this_var());
+ VisitForValue(property->obj()->AsSuperPropertyReference()->home_object());
+ FrameStateBeforeAndAfter states(this, property->obj()->id());
+ Node* home_object = environment()->Top();
+ Node* receiver = environment()->Peek(1);
+ Handle<Name> name = property->key()->AsLiteral()->AsPropertyName();
+ VectorSlotPair pair =
+ CreateVectorSlotPair(property->PropertyFeedbackSlot());
+ old_value = BuildNamedSuperLoad(receiver, home_object, name, pair);
+ states.AddToNode(old_value, property->LoadId(),
+ OutputFrameStateCombine::Push());
+ stack_depth = 2;
+ break;
+ }
+ case KEYED_SUPER_PROPERTY: {
+ VisitForValue(property->obj()->AsSuperPropertyReference()->this_var());
+ VisitForValue(property->obj()->AsSuperPropertyReference()->home_object());
+ VisitForValue(property->key());
+ FrameStateBeforeAndAfter states(this, property->obj()->id());
+ Node* key = environment()->Top();
+ Node* home_object = environment()->Peek(1);
+ Node* receiver = environment()->Peek(2);
+ VectorSlotPair pair =
+ CreateVectorSlotPair(property->PropertyFeedbackSlot());
+ old_value = BuildKeyedSuperLoad(receiver, home_object, key, pair);
+ states.AddToNode(old_value, property->LoadId(),
+ OutputFrameStateCombine::Push());
+ stack_depth = 3;
+ break;
+ }
}
// Convert old value into a number.
@@ -2506,6 +2666,30 @@ void AstGraphBuilder::VisitCountOperation(CountOperation* expr) {
environment()->Pop();
break;
}
+ case NAMED_SUPER_PROPERTY: {
+ Node* home_object = environment()->Pop();
+ Node* receiver = environment()->Pop();
+ Handle<Name> name = property->key()->AsLiteral()->AsPropertyName();
+ Node* store = BuildNamedSuperStore(receiver, home_object, name, value,
+ expr->CountStoreFeedbackId());
+ environment()->Push(value);
+ store_states.AddToNode(store, expr->AssignmentId(),
+ OutputFrameStateCombine::Ignore());
+ environment()->Pop();
+ break;
+ }
+ case KEYED_SUPER_PROPERTY: {
+ Node* key = environment()->Pop();
+ Node* home_object = environment()->Pop();
+ Node* receiver = environment()->Pop();
+ Node* store = BuildKeyedSuperStore(receiver, home_object, key, value,
+ expr->CountStoreFeedbackId());
+ environment()->Push(value);
+ store_states.AddToNode(store, expr->AssignmentId(),
+ OutputFrameStateCombine::Ignore());
+ environment()->Pop();
+ break;
+ }
}
// Restore old value for postfix expressions.
@@ -2931,6 +3115,17 @@ Node* AstGraphBuilder::BuildRestArgumentsArray(Variable* rest, int index) {
}
+Node* AstGraphBuilder::BuildThisFunctionVar(Variable* this_function_var) {
+ if (this_function_var == nullptr) return nullptr;
+
+ Node* this_function = GetFunctionClosure();
+ FrameStateBeforeAndAfter states(this, BailoutId::None());
+ BuildVariableAssignment(this_function_var, this_function, Token::INIT_CONST,
+ BailoutId::None(), states);
+ return this_function;
+}
+
+
Node* AstGraphBuilder::BuildHoleCheckSilent(Node* value, Node* for_hole,
Node* not_hole) {
Node* the_hole = jsgraph()->TheHoleConstant();
@@ -3257,6 +3452,51 @@ Node* AstGraphBuilder::BuildNamedStore(Node* object, Handle<Name> name,
}
+Node* AstGraphBuilder::BuildNamedSuperLoad(Node* receiver, Node* home_object,
+ Handle<Name> name,
+ const VectorSlotPair& feedback) {
+ Node* name_node = jsgraph()->Constant(name);
+ const Operator* op = javascript()->CallRuntime(Runtime::kLoadFromSuper, 3);
+ Node* value = NewNode(op, receiver, home_object, name_node);
+ return Record(js_type_feedback_, value, feedback.slot());
Michael Starzinger 2015/06/05 13:28:19 Just for clarification: My understanding is that w
arv (Not doing code reviews) 2015/06/05 13:50:26 I think that is right. At some point we probably w
Michael Starzinger 2015/06/05 13:53:23 Acknowledged.
+}
+
+
+Node* AstGraphBuilder::BuildKeyedSuperLoad(Node* receiver, Node* home_object,
+ Node* key,
+ const VectorSlotPair& feedback) {
+ const Operator* op =
+ javascript()->CallRuntime(Runtime::kLoadKeyedFromSuper, 3);
+ Node* value = NewNode(op, receiver, home_object, key);
+ return Record(js_type_feedback_, value, feedback.slot());
+}
+
+
+Node* AstGraphBuilder::BuildKeyedSuperStore(Node* receiver, Node* home_object,
+ Node* key, Node* value,
+ TypeFeedbackId id) {
+ Runtime::FunctionId function_id = is_strict(language_mode())
+ ? Runtime::kStoreKeyedToSuper_Strict
+ : Runtime::kStoreKeyedToSuper_Sloppy;
+ const Operator* op = javascript()->CallRuntime(function_id, 4);
+ Node* result = NewNode(op, receiver, home_object, key, value);
+ return Record(js_type_feedback_, result, id);
+}
+
+
+Node* AstGraphBuilder::BuildNamedSuperStore(Node* receiver, Node* home_object,
+ Handle<Name> name, Node* value,
+ TypeFeedbackId id) {
+ Node* name_node = jsgraph()->Constant(name);
+ Runtime::FunctionId function_id = is_strict(language_mode())
+ ? Runtime::kStoreToSuper_Strict
+ : Runtime::kStoreToSuper_Sloppy;
+ const Operator* op = javascript()->CallRuntime(function_id, 4);
+ Node* result = NewNode(op, receiver, home_object, name_node, value);
+ return Record(js_type_feedback_, result, id);
+}
+
+
Node* AstGraphBuilder::BuildLoadObjectField(Node* object, int offset) {
return NewNode(jsgraph()->machine()->Load(kMachAnyTagged), object,
jsgraph()->IntPtrConstant(offset - kHeapObjectTag));
« no previous file with comments | « src/compiler/ast-graph-builder.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698