diff --git a/deps/v8/include/v8-version.h b/deps/v8/include/v8-version.h index 0d920efac46d52..f1b394a8c4a1ab 100644 --- a/deps/v8/include/v8-version.h +++ b/deps/v8/include/v8-version.h @@ -11,7 +11,7 @@ #define V8_MAJOR_VERSION 5 #define V8_MINOR_VERSION 9 #define V8_BUILD_NUMBER 211 -#define V8_PATCH_LEVEL 37 +#define V8_PATCH_LEVEL 38 // Use 1 for candidates and 0 otherwise. // (Boolean macro values are not supported by all preprocessors.) diff --git a/deps/v8/src/ic/handler-configuration-inl.h b/deps/v8/src/ic/handler-configuration-inl.h index 2b9dc04b5a9395..5f31d15d46fcc3 100644 --- a/deps/v8/src/ic/handler-configuration-inl.h +++ b/deps/v8/src/ic/handler-configuration-inl.h @@ -13,6 +13,11 @@ namespace v8 { namespace internal { +// Decodes kind from Smi-handler. +LoadHandler::Kind LoadHandler::GetHandlerKind(Smi* smi_handler) { + return KindBits::decode(smi_handler->value()); +} + Handle LoadHandler::LoadNormal(Isolate* isolate) { int config = KindBits::encode(kNormal); return handle(Smi::FromInt(config), isolate); diff --git a/deps/v8/src/ic/handler-configuration.h b/deps/v8/src/ic/handler-configuration.h index ab117d5c9bd5cb..eed548b4d5edeb 100644 --- a/deps/v8/src/ic/handler-configuration.h +++ b/deps/v8/src/ic/handler-configuration.h @@ -90,6 +90,9 @@ class LoadHandler { static const int kHolderCellIndex = 2; static const int kFirstPrototypeIndex = 3; + // Decodes kind from Smi-handler. + static inline Kind GetHandlerKind(Smi* smi_handler); + // Creates a Smi-handler for loading a property from a slow object. static inline Handle LoadNormal(Isolate* isolate); diff --git a/deps/v8/src/ic/ic.cc b/deps/v8/src/ic/ic.cc index b3b0eb4c849e52..ca3f70df2ab41d 100644 --- a/deps/v8/src/ic/ic.cc +++ b/deps/v8/src/ic/ic.cc @@ -868,10 +868,15 @@ int GetPrototypeCheckCount(Isolate* isolate, Handle receiver_map, Handle(), 0); } +enum class HolderCellRequest { + kGlobalPropertyCell, + kHolder, +}; + Handle HolderCell(Isolate* isolate, Handle holder, - Handle name, Handle smi_handler) { - if (holder->IsJSGlobalObject() && - *smi_handler != *LoadHandler::LoadInterceptor(isolate)) { + Handle name, HolderCellRequest request) { + if (request == HolderCellRequest::kGlobalPropertyCell) { + DCHECK(holder->IsJSGlobalObject()); Handle global = Handle::cast(holder); GlobalDictionary* dict = global->global_dictionary(); int number = dict->FindEntry(name); @@ -908,8 +913,14 @@ Handle LoadIC::LoadFromPrototype(Handle receiver_map, Map::GetOrCreatePrototypeChainValidityCell(receiver_map, isolate()); DCHECK(!validity_cell.is_null()); - Handle holder_cell = - HolderCell(isolate(), holder, name, smi_handler); + // LoadIC dispatcher expects PropertyCell as a "holder" in case of kGlobal + // handler kind. + HolderCellRequest request = + LoadHandler::GetHandlerKind(*smi_handler) == LoadHandler::kGlobal + ? HolderCellRequest::kGlobalPropertyCell + : HolderCellRequest::kHolder; + + Handle holder_cell = HolderCell(isolate(), holder, name, request); if (checks_count == 0) { return isolate()->factory()->NewTuple3(holder_cell, smi_handler, diff --git a/deps/v8/test/cctest/test-api-interceptors.cc b/deps/v8/test/cctest/test-api-interceptors.cc index 9680b4241b8521..9e739687b4c3c5 100644 --- a/deps/v8/test/cctest/test-api-interceptors.cc +++ b/deps/v8/test/cctest/test-api-interceptors.cc @@ -1383,6 +1383,41 @@ THREADED_TEST(InterceptorLoadGlobalICGlobalWithInterceptor) { CHECK(value->BooleanValue(context.local()).FromJust()); } +// Test load of a non-existing global through prototype chain when a global +// object has an interceptor. +THREADED_TEST(InterceptorLoadICGlobalWithInterceptor) { + i::FLAG_allow_natives_syntax = true; + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); + v8::Local templ_global = v8::ObjectTemplate::New(isolate); + templ_global->SetHandler(v8::NamedPropertyHandlerConfiguration( + GenericInterceptorGetter, GenericInterceptorSetter)); + + LocalContext context(nullptr, templ_global); + i::Handle global_proxy = + v8::Utils::OpenHandle(context->Global()); + CHECK(global_proxy->IsJSGlobalProxy()); + i::Handle global( + i::JSGlobalObject::cast(global_proxy->map()->prototype())); + CHECK(global->map()->has_named_interceptor()); + + ExpectInt32( + "(function() {" + " var f = function(obj) { " + " return obj.foo;" + " };" + " var obj = { __proto__: this, _str_foo: 42 };" + " for (var i = 0; i < 1500; i++) obj['p' + i] = 0;" + " /* Ensure that |obj| is in dictionary mode. */" + " if (%HasFastProperties(obj)) return -1;" + " for (var i = 0; i < 3; i++) {" + " f(obj);" + " };" + " return f(obj);" + "})();", + 42); +} + static void InterceptorLoadICGetter0( Local name, const v8::PropertyCallbackInfo& info) { ApiTestFuzzer::Fuzz();