Skip to content

Commit cfbd161

Browse files
jakobkummerowCommit bot
authored andcommitted
[IC] Fix "compatible receiver" checks hidden behind interceptors
BUG=chromium:497632 LOG=y Review URL: https://codereview.chromium.org/1531583005 Cr-Commit-Position: refs/heads/master@{#32945}
1 parent 641cdd3 commit cfbd161

1 file changed

Lines changed: 47 additions & 29 deletions

File tree

src/ic/ic.cc

Lines changed: 47 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -972,6 +972,39 @@ Handle<Code> LoadIC::SimpleFieldLoad(FieldIndex index) {
972972
}
973973

974974

975+
bool IsCompatibleReceiver(LookupIterator* lookup, Handle<Map> receiver_map) {
976+
DCHECK(lookup->state() == LookupIterator::ACCESSOR);
977+
Isolate* isolate = lookup->isolate();
978+
Handle<Object> accessors = lookup->GetAccessors();
979+
if (accessors->IsExecutableAccessorInfo()) {
980+
Handle<ExecutableAccessorInfo> info =
981+
Handle<ExecutableAccessorInfo>::cast(accessors);
982+
if (info->getter() != NULL &&
983+
!ExecutableAccessorInfo::IsCompatibleReceiverMap(isolate, info,
984+
receiver_map)) {
985+
return false;
986+
}
987+
} else if (accessors->IsAccessorPair()) {
988+
Handle<Object> getter(Handle<AccessorPair>::cast(accessors)->getter(),
989+
isolate);
990+
Handle<JSObject> holder = lookup->GetHolder<JSObject>();
991+
Handle<Object> receiver = lookup->GetReceiver();
992+
if (getter->IsJSFunction() && holder->HasFastProperties()) {
993+
Handle<JSFunction> function = Handle<JSFunction>::cast(getter);
994+
if (receiver->IsJSObject() || function->shared()->IsBuiltin() ||
995+
!is_sloppy(function->shared()->language_mode())) {
996+
CallOptimization call_optimization(function);
997+
if (call_optimization.is_simple_api_call() &&
998+
!call_optimization.IsCompatibleReceiverMap(receiver_map, holder)) {
999+
return false;
1000+
}
1001+
}
1002+
}
1003+
}
1004+
return true;
1005+
}
1006+
1007+
9751008
void LoadIC::UpdateCaches(LookupIterator* lookup) {
9761009
if (state() == UNINITIALIZED) {
9771010
// This is the first time we execute this inline cache. Set the target to
@@ -996,35 +1029,20 @@ void LoadIC::UpdateCaches(LookupIterator* lookup) {
9961029
}
9971030
} else {
9981031
if (lookup->state() == LookupIterator::ACCESSOR) {
999-
Handle<Object> accessors = lookup->GetAccessors();
1000-
Handle<Map> map = receiver_map();
1001-
if (accessors->IsExecutableAccessorInfo()) {
1002-
Handle<ExecutableAccessorInfo> info =
1003-
Handle<ExecutableAccessorInfo>::cast(accessors);
1004-
if ((v8::ToCData<Address>(info->getter()) != 0) &&
1005-
!ExecutableAccessorInfo::IsCompatibleReceiverMap(isolate(), info,
1006-
map)) {
1007-
TRACE_GENERIC_IC(isolate(), "LoadIC", "incompatible receiver type");
1008-
code = slow_stub();
1009-
}
1010-
} else if (accessors->IsAccessorPair()) {
1011-
Handle<Object> getter(Handle<AccessorPair>::cast(accessors)->getter(),
1012-
isolate());
1013-
Handle<JSObject> holder = lookup->GetHolder<JSObject>();
1014-
Handle<Object> receiver = lookup->GetReceiver();
1015-
if (getter->IsJSFunction() && holder->HasFastProperties()) {
1016-
Handle<JSFunction> function = Handle<JSFunction>::cast(getter);
1017-
if (receiver->IsJSObject() || function->shared()->IsBuiltin() ||
1018-
!is_sloppy(function->shared()->language_mode())) {
1019-
CallOptimization call_optimization(function);
1020-
if (call_optimization.is_simple_api_call() &&
1021-
!call_optimization.IsCompatibleReceiver(receiver, holder)) {
1022-
TRACE_GENERIC_IC(isolate(), "LoadIC",
1023-
"incompatible receiver type");
1024-
code = slow_stub();
1025-
}
1026-
}
1027-
}
1032+
if (!IsCompatibleReceiver(lookup, receiver_map())) {
1033+
TRACE_GENERIC_IC(isolate(), "LoadIC", "incompatible receiver type");
1034+
code = slow_stub();
1035+
}
1036+
} else if (lookup->state() == LookupIterator::INTERCEPTOR) {
1037+
// Perform a lookup behind the interceptor. Copy the LookupIterator since
1038+
// the original iterator will be used to fetch the value.
1039+
LookupIterator it = *lookup;
1040+
it.Next();
1041+
LookupForRead(&it);
1042+
if (it.state() == LookupIterator::ACCESSOR &&
1043+
!IsCompatibleReceiver(&it, receiver_map())) {
1044+
TRACE_GENERIC_IC(isolate(), "LoadIC", "incompatible receiver type");
1045+
code = slow_stub();
10281046
}
10291047
}
10301048
if (code.is_null()) code = ComputeHandler(lookup);

0 commit comments

Comments
 (0)