Chromium Code Reviews| Index: src/compiler/ast-graph-builder.cc |
| diff --git a/src/compiler/ast-graph-builder.cc b/src/compiler/ast-graph-builder.cc |
| index 973104b2a907219a9085011d249c4e75bbbd0495..1c1cde1836634c992c2e721533f7a02f22e3fcd5 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,94 @@ 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); |
| + // Fall through. |
|
Michael Starzinger
2016/11/10 15:10:22
nit: Says "fall-through" but doesn't fall through
rmcilroy
2016/11/10 15:16:47
oops, done thanks.
|
| + 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 +2426,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 +2457,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 |