| Index: src/compiler/ast-graph-builder.cc
|
| diff --git a/src/compiler/ast-graph-builder.cc b/src/compiler/ast-graph-builder.cc
|
| index 08b2e7fe18136c92b665fd3308feba40b1c130e6..f799dac7ee1e6bb65bf01a31703b263ccd645cee 100644
|
| --- a/src/compiler/ast-graph-builder.cc
|
| +++ b/src/compiler/ast-graph-builder.cc
|
| @@ -2285,21 +2285,9 @@ void AstGraphBuilder::VisitCall(Call* expr) {
|
| ConvertReceiverMode receiver_hint = ConvertReceiverMode::kAny;
|
| Node* receiver_value = nullptr;
|
| Node* callee_value = nullptr;
|
| - bool possibly_eval = false;
|
| - switch (call_type) {
|
| - case Call::GLOBAL_CALL: {
|
| - VariableProxy* proxy = callee->AsVariableProxy();
|
| - VectorSlotPair pair = CreateVectorSlotPair(proxy->VariableFeedbackSlot());
|
| - PrepareEagerCheckpoint(BeforeId(proxy));
|
| - callee_value = BuildVariableLoad(proxy->var(), expr->expression()->id(),
|
| - pair, OutputFrameStateCombine::Push());
|
| - receiver_hint = ConvertReceiverMode::kNullOrUndefined;
|
| - receiver_value = jsgraph()->UndefinedConstant();
|
| - break;
|
| - }
|
| - case Call::WITH_CALL: {
|
| + if (expr->is_possibly_eval()) {
|
| + if (callee->AsVariableProxy()->var()->IsLookupSlot()) {
|
| Variable* variable = callee->AsVariableProxy()->var();
|
| - DCHECK(variable->location() == VariableLocation::LOOKUP);
|
| Node* name = jsgraph()->Constant(variable->name());
|
| const Operator* op =
|
| javascript()->CallRuntime(Runtime::kLoadLookupSlotForCall);
|
| @@ -2308,89 +2296,26 @@ void AstGraphBuilder::VisitCall(Call* expr) {
|
| receiver_value = NewNode(common()->Projection(1), pair);
|
| PrepareFrameState(pair, expr->LookupId(),
|
| OutputFrameStateCombine::Push(2));
|
| - break;
|
| - }
|
| - case Call::NAMED_PROPERTY_CALL: {
|
| - Property* property = callee->AsProperty();
|
| - VectorSlotPair feedback =
|
| - CreateVectorSlotPair(property->PropertyFeedbackSlot());
|
| - VisitForValue(property->obj());
|
| - Handle<Name> name = property->key()->AsLiteral()->AsPropertyName();
|
| - Node* object = environment()->Top();
|
| - callee_value = BuildNamedLoad(object, name, feedback);
|
| - PrepareFrameState(callee_value, property->LoadId(),
|
| - OutputFrameStateCombine::Push());
|
| - // Note that a property call requires the receiver to be wrapped into
|
| - // an object for sloppy callees. However the receiver is guaranteed
|
| - // not to be null or undefined at this point.
|
| - receiver_hint = ConvertReceiverMode::kNotNullOrUndefined;
|
| - receiver_value = environment()->Pop();
|
| - break;
|
| - }
|
| - case Call::KEYED_PROPERTY_CALL: {
|
| - Property* property = callee->AsProperty();
|
| - VectorSlotPair feedback =
|
| - CreateVectorSlotPair(property->PropertyFeedbackSlot());
|
| - VisitForValue(property->obj());
|
| - VisitForValue(property->key());
|
| - Node* key = environment()->Pop();
|
| - Node* object = environment()->Top();
|
| - callee_value = BuildKeyedLoad(object, key, feedback);
|
| - PrepareFrameState(callee_value, property->LoadId(),
|
| - OutputFrameStateCombine::Push());
|
| - // Note that a property call requires the receiver to be wrapped into
|
| - // an object for sloppy callees. However the receiver is guaranteed
|
| - // not to be null or undefined at this point.
|
| - receiver_hint = ConvertReceiverMode::kNotNullOrUndefined;
|
| - receiver_value = environment()->Pop();
|
| - break;
|
| - }
|
| - case Call::NAMED_SUPER_PROPERTY_CALL: {
|
| - Property* property = callee->AsProperty();
|
| - SuperPropertyReference* super_ref =
|
| - property->obj()->AsSuperPropertyReference();
|
| - VisitForValue(super_ref->home_object());
|
| - VisitForValue(super_ref->this_var());
|
| - Node* home = environment()->Peek(1);
|
| - Node* object = environment()->Top();
|
| - Handle<Name> name = property->key()->AsLiteral()->AsPropertyName();
|
| - callee_value = BuildNamedSuperLoad(object, home, name, VectorSlotPair());
|
| - PrepareFrameState(callee_value, property->LoadId(),
|
| - OutputFrameStateCombine::Push());
|
| - // Note that a property call requires the receiver to be wrapped into
|
| - // an object for sloppy callees. Since the receiver is not the target of
|
| - // the load, it could very well be null or undefined at this point.
|
| - receiver_value = environment()->Pop();
|
| - environment()->Drop(1);
|
| - break;
|
| - }
|
| - case Call::KEYED_SUPER_PROPERTY_CALL: {
|
| - Property* property = callee->AsProperty();
|
| - SuperPropertyReference* super_ref =
|
| - property->obj()->AsSuperPropertyReference();
|
| - VisitForValue(super_ref->home_object());
|
| - VisitForValue(super_ref->this_var());
|
| - environment()->Push(environment()->Top()); // Duplicate this_var.
|
| - environment()->Push(environment()->Peek(2)); // Duplicate home_obj.
|
| - VisitForValue(property->key());
|
| - Node* key = environment()->Pop();
|
| - Node* home = environment()->Pop();
|
| - Node* object = environment()->Pop();
|
| - callee_value = BuildKeyedSuperLoad(object, home, key, VectorSlotPair());
|
| - PrepareFrameState(callee_value, property->LoadId(),
|
| - OutputFrameStateCombine::Push());
|
| - // Note that a property call requires the receiver to be wrapped into
|
| - // an object for sloppy callees. Since the receiver is not the target of
|
| - // the load, it could very well be null or undefined at this point.
|
| - receiver_value = environment()->Pop();
|
| - environment()->Drop(1);
|
| - break;
|
| + } else {
|
| + VisitForValue(callee);
|
| + callee_value = environment()->Pop();
|
| + receiver_hint = ConvertReceiverMode::kNullOrUndefined;
|
| + receiver_value = jsgraph()->UndefinedConstant();
|
| }
|
| - case Call::SUPER_CALL:
|
| - return VisitCallSuper(expr);
|
| - case Call::POSSIBLY_EVAL_CALL:
|
| - possibly_eval = true;
|
| - if (callee->AsVariableProxy()->var()->IsLookupSlot()) {
|
| + } else {
|
| + switch (call_type) {
|
| + case Call::GLOBAL_CALL: {
|
| + VariableProxy* proxy = callee->AsVariableProxy();
|
| + VectorSlotPair pair =
|
| + CreateVectorSlotPair(proxy->VariableFeedbackSlot());
|
| + PrepareEagerCheckpoint(BeforeId(proxy));
|
| + callee_value = BuildVariableLoad(proxy->var(), expr->expression()->id(),
|
| + pair, OutputFrameStateCombine::Push());
|
| + receiver_hint = ConvertReceiverMode::kNullOrUndefined;
|
| + receiver_value = jsgraph()->UndefinedConstant();
|
| + break;
|
| + }
|
| + case Call::WITH_CALL: {
|
| Variable* variable = callee->AsVariableProxy()->var();
|
| Node* name = jsgraph()->Constant(variable->name());
|
| const Operator* op =
|
| @@ -2400,15 +2325,93 @@ void AstGraphBuilder::VisitCall(Call* expr) {
|
| receiver_value = NewNode(common()->Projection(1), pair);
|
| PrepareFrameState(pair, expr->LookupId(),
|
| OutputFrameStateCombine::Push(2));
|
| + }
|
| + case Call::NAMED_PROPERTY_CALL: {
|
| + Property* property = callee->AsProperty();
|
| + VectorSlotPair feedback =
|
| + CreateVectorSlotPair(property->PropertyFeedbackSlot());
|
| + VisitForValue(property->obj());
|
| + Handle<Name> name = property->key()->AsLiteral()->AsPropertyName();
|
| + Node* object = environment()->Top();
|
| + callee_value = BuildNamedLoad(object, name, feedback);
|
| + PrepareFrameState(callee_value, property->LoadId(),
|
| + OutputFrameStateCombine::Push());
|
| + // Note that a property call requires the receiver to be wrapped into
|
| + // an object for sloppy callees. However the receiver is guaranteed
|
| + // not to be null or undefined at this point.
|
| + receiver_hint = ConvertReceiverMode::kNotNullOrUndefined;
|
| + receiver_value = environment()->Pop();
|
| break;
|
| }
|
| - // Fall through.
|
| - case Call::OTHER_CALL:
|
| - VisitForValue(callee);
|
| - callee_value = environment()->Pop();
|
| - receiver_hint = ConvertReceiverMode::kNullOrUndefined;
|
| - receiver_value = jsgraph()->UndefinedConstant();
|
| - break;
|
| + case Call::KEYED_PROPERTY_CALL: {
|
| + Property* property = callee->AsProperty();
|
| + VectorSlotPair feedback =
|
| + CreateVectorSlotPair(property->PropertyFeedbackSlot());
|
| + VisitForValue(property->obj());
|
| + VisitForValue(property->key());
|
| + Node* key = environment()->Pop();
|
| + Node* object = environment()->Top();
|
| + callee_value = BuildKeyedLoad(object, key, feedback);
|
| + PrepareFrameState(callee_value, property->LoadId(),
|
| + OutputFrameStateCombine::Push());
|
| + // Note that a property call requires the receiver to be wrapped into
|
| + // an object for sloppy callees. However the receiver is guaranteed
|
| + // not to be null or undefined at this point.
|
| + receiver_hint = ConvertReceiverMode::kNotNullOrUndefined;
|
| + receiver_value = environment()->Pop();
|
| + break;
|
| + }
|
| + case Call::NAMED_SUPER_PROPERTY_CALL: {
|
| + Property* property = callee->AsProperty();
|
| + SuperPropertyReference* super_ref =
|
| + property->obj()->AsSuperPropertyReference();
|
| + VisitForValue(super_ref->home_object());
|
| + VisitForValue(super_ref->this_var());
|
| + Node* home = environment()->Peek(1);
|
| + Node* object = environment()->Top();
|
| + Handle<Name> name = property->key()->AsLiteral()->AsPropertyName();
|
| + callee_value =
|
| + BuildNamedSuperLoad(object, home, name, VectorSlotPair());
|
| + PrepareFrameState(callee_value, property->LoadId(),
|
| + OutputFrameStateCombine::Push());
|
| + // Note that a property call requires the receiver to be wrapped into
|
| + // an object for sloppy callees. Since the receiver is not the target of
|
| + // the load, it could very well be null or undefined at this point.
|
| + receiver_value = environment()->Pop();
|
| + environment()->Drop(1);
|
| + break;
|
| + }
|
| + case Call::KEYED_SUPER_PROPERTY_CALL: {
|
| + Property* property = callee->AsProperty();
|
| + SuperPropertyReference* super_ref =
|
| + property->obj()->AsSuperPropertyReference();
|
| + VisitForValue(super_ref->home_object());
|
| + VisitForValue(super_ref->this_var());
|
| + environment()->Push(environment()->Top()); // Duplicate this_var.
|
| + environment()->Push(environment()->Peek(2)); // Duplicate home_obj.
|
| + VisitForValue(property->key());
|
| + Node* key = environment()->Pop();
|
| + Node* home = environment()->Pop();
|
| + Node* object = environment()->Pop();
|
| + callee_value = BuildKeyedSuperLoad(object, home, key, VectorSlotPair());
|
| + PrepareFrameState(callee_value, property->LoadId(),
|
| + OutputFrameStateCombine::Push());
|
| + // Note that a property call requires the receiver to be wrapped into
|
| + // an object for sloppy callees. Since the receiver is not the target of
|
| + // the load, it could very well be null or undefined at this point.
|
| + receiver_value = environment()->Pop();
|
| + environment()->Drop(1);
|
| + break;
|
| + }
|
| + case Call::SUPER_CALL:
|
| + return VisitCallSuper(expr);
|
| + case Call::OTHER_CALL:
|
| + VisitForValue(callee);
|
| + callee_value = environment()->Pop();
|
| + receiver_hint = ConvertReceiverMode::kNullOrUndefined;
|
| + receiver_value = jsgraph()->UndefinedConstant();
|
| + break;
|
| + }
|
| }
|
|
|
| // The callee and the receiver both have to be pushed onto the operand stack
|
| @@ -2422,7 +2425,7 @@ void AstGraphBuilder::VisitCall(Call* expr) {
|
|
|
| // Resolve callee for a potential direct eval call. This block will mutate the
|
| // callee value pushed onto the environment.
|
| - if (possibly_eval && args->length() > 0) {
|
| + if (expr->is_possibly_eval() && args->length() > 0) {
|
| int arg_count = args->length();
|
|
|
| // Extract callee and source string from the environment.
|
| @@ -2453,7 +2456,8 @@ void AstGraphBuilder::VisitCall(Call* expr) {
|
| const Operator* call =
|
| javascript()->CallFunction(args->length() + 2, frequency, feedback,
|
| receiver_hint, expr->tail_call_mode());
|
| - PrepareEagerCheckpoint(possibly_eval ? expr->EvalId() : expr->CallId());
|
| + PrepareEagerCheckpoint(expr->is_possibly_eval() ? expr->EvalId()
|
| + : expr->CallId());
|
| Node* value = ProcessArguments(call, args->length() + 2);
|
| // The callee passed to the call, we just need to push something here to
|
| // satisfy the bailout location contract. The fullcodegen code will not
|
|
|