@@ -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+
9751008void 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