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

Unified Diff: src/crankshaft/hydrogen.cc

Issue 1818003002: [crankshaft] Check if the function is callable before generating a tail call via Call builtin. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@tco-crank-4
Patch Set: Created 4 years, 9 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/crankshaft/hydrogen.h ('k') | test/mjsunit/regress/regress-crbug-595615.js » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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(),
« no previous file with comments | « src/crankshaft/hydrogen.h ('k') | test/mjsunit/regress/regress-crbug-595615.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698