Browse Source

deps: cherry-pick 6cb999b97b from V8 upstream

Original commit message:

    Properly handle loads from global interceptor via prototype chain.

    ... when receiver is in dictionary mode.

    Bug: v8:6490
    Change-Id: Ic5a8d214adcc4efd4cb163cbc6b351c4e6b596af
    Reviewed-on: https://chromium-review.googlesource.com/559548
    Reviewed-by: Camillo Bruni <cbruni@chromium.org>
    Commit-Queue: Igor Sheludko <ishell@chromium.org>
    Cr-Commit-Position: refs/heads/master@{#46428}

Ref: 6cb999b97b
Fixes: https://github.com/nodejs/node/issues/13804
PR-URL: https://github.com/nodejs/node/pull/14188
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: Michaël Zasso <targos@protonmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
v6
Igor Sheludko 7 years ago
committed by Anna Henningsen
parent
commit
785a9e5a57
No known key found for this signature in database GPG Key ID: D8B9F5AEAE84E4CF
  1. 2
      deps/v8/include/v8-version.h
  2. 5
      deps/v8/src/ic/handler-configuration-inl.h
  3. 3
      deps/v8/src/ic/handler-configuration.h
  4. 21
      deps/v8/src/ic/ic.cc
  5. 35
      deps/v8/test/cctest/test-api-interceptors.cc

2
deps/v8/include/v8-version.h

@ -11,7 +11,7 @@
#define V8_MAJOR_VERSION 5 #define V8_MAJOR_VERSION 5
#define V8_MINOR_VERSION 9 #define V8_MINOR_VERSION 9
#define V8_BUILD_NUMBER 211 #define V8_BUILD_NUMBER 211
#define V8_PATCH_LEVEL 37 #define V8_PATCH_LEVEL 38
// Use 1 for candidates and 0 otherwise. // Use 1 for candidates and 0 otherwise.
// (Boolean macro values are not supported by all preprocessors.) // (Boolean macro values are not supported by all preprocessors.)

5
deps/v8/src/ic/handler-configuration-inl.h

@ -13,6 +13,11 @@
namespace v8 { namespace v8 {
namespace internal { namespace internal {
// Decodes kind from Smi-handler.
LoadHandler::Kind LoadHandler::GetHandlerKind(Smi* smi_handler) {
return KindBits::decode(smi_handler->value());
}
Handle<Smi> LoadHandler::LoadNormal(Isolate* isolate) { Handle<Smi> LoadHandler::LoadNormal(Isolate* isolate) {
int config = KindBits::encode(kNormal); int config = KindBits::encode(kNormal);
return handle(Smi::FromInt(config), isolate); return handle(Smi::FromInt(config), isolate);

3
deps/v8/src/ic/handler-configuration.h

@ -90,6 +90,9 @@ class LoadHandler {
static const int kHolderCellIndex = 2; static const int kHolderCellIndex = 2;
static const int kFirstPrototypeIndex = 3; 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. // Creates a Smi-handler for loading a property from a slow object.
static inline Handle<Smi> LoadNormal(Isolate* isolate); static inline Handle<Smi> LoadNormal(Isolate* isolate);

21
deps/v8/src/ic/ic.cc

@ -868,10 +868,15 @@ int GetPrototypeCheckCount(Isolate* isolate, Handle<Map> receiver_map,
Handle<FixedArray>(), 0); Handle<FixedArray>(), 0);
} }
enum class HolderCellRequest {
kGlobalPropertyCell,
kHolder,
};
Handle<WeakCell> HolderCell(Isolate* isolate, Handle<JSObject> holder, Handle<WeakCell> HolderCell(Isolate* isolate, Handle<JSObject> holder,
Handle<Name> name, Handle<Smi> smi_handler) { Handle<Name> name, HolderCellRequest request) {
if (holder->IsJSGlobalObject() && if (request == HolderCellRequest::kGlobalPropertyCell) {
*smi_handler != *LoadHandler::LoadInterceptor(isolate)) { DCHECK(holder->IsJSGlobalObject());
Handle<JSGlobalObject> global = Handle<JSGlobalObject>::cast(holder); Handle<JSGlobalObject> global = Handle<JSGlobalObject>::cast(holder);
GlobalDictionary* dict = global->global_dictionary(); GlobalDictionary* dict = global->global_dictionary();
int number = dict->FindEntry(name); int number = dict->FindEntry(name);
@ -908,8 +913,14 @@ Handle<Object> LoadIC::LoadFromPrototype(Handle<Map> receiver_map,
Map::GetOrCreatePrototypeChainValidityCell(receiver_map, isolate()); Map::GetOrCreatePrototypeChainValidityCell(receiver_map, isolate());
DCHECK(!validity_cell.is_null()); DCHECK(!validity_cell.is_null());
Handle<WeakCell> holder_cell = // LoadIC dispatcher expects PropertyCell as a "holder" in case of kGlobal
HolderCell(isolate(), holder, name, smi_handler); // handler kind.
HolderCellRequest request =
LoadHandler::GetHandlerKind(*smi_handler) == LoadHandler::kGlobal
? HolderCellRequest::kGlobalPropertyCell
: HolderCellRequest::kHolder;
Handle<WeakCell> holder_cell = HolderCell(isolate(), holder, name, request);
if (checks_count == 0) { if (checks_count == 0) {
return isolate()->factory()->NewTuple3(holder_cell, smi_handler, return isolate()->factory()->NewTuple3(holder_cell, smi_handler,

35
deps/v8/test/cctest/test-api-interceptors.cc

@ -1383,6 +1383,41 @@ THREADED_TEST(InterceptorLoadGlobalICGlobalWithInterceptor) {
CHECK(value->BooleanValue(context.local()).FromJust()); 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<v8::ObjectTemplate> templ_global = v8::ObjectTemplate::New(isolate);
templ_global->SetHandler(v8::NamedPropertyHandlerConfiguration(
GenericInterceptorGetter, GenericInterceptorSetter));
LocalContext context(nullptr, templ_global);
i::Handle<i::JSReceiver> global_proxy =
v8::Utils::OpenHandle<Object, i::JSReceiver>(context->Global());
CHECK(global_proxy->IsJSGlobalProxy());
i::Handle<i::JSGlobalObject> 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( static void InterceptorLoadICGetter0(
Local<Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) { Local<Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) {
ApiTestFuzzer::Fuzz(); ApiTestFuzzer::Fuzz();

Loading…
Cancel
Save