| Index: src/crankshaft/hydrogen.cc
|
| diff --git a/src/crankshaft/hydrogen.cc b/src/crankshaft/hydrogen.cc
|
| index 22e2f7b0e5c82ffb472fcd89c6b892b1fb77c8fd..9d0a2b80b1a66beb4e0c82574cb9f69b0e452741 100644
|
| --- a/src/crankshaft/hydrogen.cc
|
| +++ b/src/crankshaft/hydrogen.cc
|
| @@ -7998,9 +7998,37 @@ void HOptimizedGraphBuilder::AddCheckPrototypeMaps(Handle<JSObject> holder,
|
| }
|
| }
|
|
|
| +void HOptimizedGraphBuilder::BuildEnsureCallable(HValue* object) {
|
| + NoObservableSideEffectsScope scope(this);
|
| + const Runtime::Function* throw_called_non_callable =
|
| + Runtime::FunctionForId(Runtime::kThrowCalledNonCallable);
|
| +
|
| + IfBuilder is_not_function(this);
|
| + HValue* smi_check = is_not_function.If<HIsSmiAndBranch>(object);
|
| + is_not_function.Or();
|
| + HValue* map = AddLoadMap(object, smi_check);
|
| + HValue* bit_field =
|
| + Add<HLoadNamedField>(map, nullptr, HObjectAccess::ForMapBitField());
|
| + HValue* bit_field_masked = AddUncasted<HBitwise>(
|
| + Token::BIT_AND, bit_field, Add<HConstant>(1 << Map::kIsCallable));
|
| + is_not_function.IfNot<HCompareNumericAndBranch>(
|
| + bit_field_masked, Add<HConstant>(1 << Map::kIsCallable), Token::EQ);
|
| + is_not_function.Then();
|
| + {
|
| + Add<HPushArguments>(object);
|
| + Add<HCallRuntime>(throw_called_non_callable, 1);
|
| + }
|
| + is_not_function.End();
|
| +}
|
| +
|
| HInstruction* HOptimizedGraphBuilder::NewCallFunction(
|
| HValue* function, int argument_count, TailCallMode syntactic_tail_call_mode,
|
| ConvertReceiverMode convert_mode, TailCallMode tail_call_mode) {
|
| + if (syntactic_tail_call_mode == TailCallMode::kAllow) {
|
| + BuildEnsureCallable(function);
|
| + } else {
|
| + DCHECK_EQ(TailCallMode::kDisallow, tail_call_mode);
|
| + }
|
| HValue* arity = Add<HConstant>(argument_count - 1);
|
|
|
| HValue* op_vals[] = {context(), function, arity};
|
| @@ -8018,6 +8046,11 @@ HInstruction* HOptimizedGraphBuilder::NewCallFunctionViaIC(
|
| HValue* function, int argument_count, TailCallMode syntactic_tail_call_mode,
|
| ConvertReceiverMode convert_mode, TailCallMode tail_call_mode,
|
| FeedbackVectorSlot slot) {
|
| + if (syntactic_tail_call_mode == TailCallMode::kAllow) {
|
| + BuildEnsureCallable(function);
|
| + } else {
|
| + DCHECK_EQ(TailCallMode::kDisallow, tail_call_mode);
|
| + }
|
| int arity = argument_count - 1;
|
| Handle<TypeFeedbackVector> vector(current_feedback_vector(), isolate());
|
| HValue* index_val = Add<HConstant>(vector->GetIndex(slot));
|
| @@ -8026,7 +8059,7 @@ HInstruction* HOptimizedGraphBuilder::NewCallFunctionViaIC(
|
| HValue* op_vals[] = {context(), function, index_val, vector_val};
|
|
|
| Callable callable = CodeFactory::CallICInOptimizedCode(
|
| - isolate(), arity, ConvertReceiverMode::kNullOrUndefined, tail_call_mode);
|
| + isolate(), arity, convert_mode, tail_call_mode);
|
| HConstant* stub = Add<HConstant>(callable.code());
|
|
|
| return New<HCallWithDescriptor>(stub, argument_count, callable.descriptor(),
|
|
|