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

Unified Diff: src/ic/ic.cc

Issue 1531583005: [IC] Fix "compatible receiver" checks hidden behind interceptors (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years 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 | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/ic/ic.cc
diff --git a/src/ic/ic.cc b/src/ic/ic.cc
index 7062a5c3dc97ddc5d37ad5515db658c041704462..73ac666a41c991bfef72c6996cda50787d4a1703 100644
--- a/src/ic/ic.cc
+++ b/src/ic/ic.cc
@@ -972,6 +972,39 @@ Handle<Code> LoadIC::SimpleFieldLoad(FieldIndex index) {
}
+bool IsCompatibleReceiver(LookupIterator* lookup, Handle<Map> receiver_map) {
Jakob Kummerow 2015/12/17 11:36:31 This is factored out from below.
+ DCHECK(lookup->state() == LookupIterator::ACCESSOR);
+ Isolate* isolate = lookup->isolate();
+ Handle<Object> accessors = lookup->GetAccessors();
+ if (accessors->IsExecutableAccessorInfo()) {
+ Handle<ExecutableAccessorInfo> info =
+ Handle<ExecutableAccessorInfo>::cast(accessors);
+ if (info->getter() != NULL &&
+ !ExecutableAccessorInfo::IsCompatibleReceiverMap(isolate, info,
+ receiver_map)) {
+ return false;
+ }
+ } else if (accessors->IsAccessorPair()) {
+ Handle<Object> getter(Handle<AccessorPair>::cast(accessors)->getter(),
+ isolate);
+ Handle<JSObject> holder = lookup->GetHolder<JSObject>();
+ Handle<Object> receiver = lookup->GetReceiver();
+ if (getter->IsJSFunction() && holder->HasFastProperties()) {
+ Handle<JSFunction> function = Handle<JSFunction>::cast(getter);
+ if (receiver->IsJSObject() || function->shared()->IsBuiltin() ||
+ !is_sloppy(function->shared()->language_mode())) {
+ CallOptimization call_optimization(function);
+ if (call_optimization.is_simple_api_call() &&
+ !call_optimization.IsCompatibleReceiverMap(receiver_map, holder)) {
+ return false;
+ }
+ }
+ }
+ }
+ return true;
+}
+
+
void LoadIC::UpdateCaches(LookupIterator* lookup) {
if (state() == UNINITIALIZED) {
// This is the first time we execute this inline cache. Set the target to
@@ -996,35 +1029,20 @@ void LoadIC::UpdateCaches(LookupIterator* lookup) {
}
} else {
if (lookup->state() == LookupIterator::ACCESSOR) {
- Handle<Object> accessors = lookup->GetAccessors();
- Handle<Map> map = receiver_map();
- if (accessors->IsExecutableAccessorInfo()) {
- Handle<ExecutableAccessorInfo> info =
- Handle<ExecutableAccessorInfo>::cast(accessors);
- if ((v8::ToCData<Address>(info->getter()) != 0) &&
- !ExecutableAccessorInfo::IsCompatibleReceiverMap(isolate(), info,
- map)) {
- TRACE_GENERIC_IC(isolate(), "LoadIC", "incompatible receiver type");
- code = slow_stub();
- }
- } else if (accessors->IsAccessorPair()) {
- Handle<Object> getter(Handle<AccessorPair>::cast(accessors)->getter(),
- isolate());
- Handle<JSObject> holder = lookup->GetHolder<JSObject>();
- Handle<Object> receiver = lookup->GetReceiver();
- if (getter->IsJSFunction() && holder->HasFastProperties()) {
- Handle<JSFunction> function = Handle<JSFunction>::cast(getter);
- if (receiver->IsJSObject() || function->shared()->IsBuiltin() ||
- !is_sloppy(function->shared()->language_mode())) {
- CallOptimization call_optimization(function);
- if (call_optimization.is_simple_api_call() &&
- !call_optimization.IsCompatibleReceiver(receiver, holder)) {
- TRACE_GENERIC_IC(isolate(), "LoadIC",
- "incompatible receiver type");
- code = slow_stub();
- }
- }
- }
+ if (!IsCompatibleReceiver(lookup, receiver_map())) {
+ TRACE_GENERIC_IC(isolate(), "LoadIC", "incompatible receiver type");
+ code = slow_stub();
+ }
+ } else if (lookup->state() == LookupIterator::INTERCEPTOR) {
+ // Perform a lookup behind the interceptor. Copy the LookupIterator since
+ // the original iterator will be used to fetch the value.
+ LookupIterator it = *lookup;
+ it.Next();
+ LookupForRead(&it);
+ if (it.state() == LookupIterator::ACCESSOR &&
+ !IsCompatibleReceiver(&it, receiver_map())) {
+ TRACE_GENERIC_IC(isolate(), "LoadIC", "incompatible receiver type");
+ code = slow_stub();
}
}
if (code.is_null()) code = ComputeHandler(lookup);
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698