Skip to content

Commit 4dfafac

Browse files
BridgeARrvagg
authored andcommitted
deps: backport c608122b from upstream
Original commit message: [api][keys] Allow skipping indices for Proxies with GetPropertyNames Bug: v8:7942 Change-Id: I7b3740b04cbcaa56dc809150900ab8d821b054ce Reviewed-on: https://chromium-review.googlesource.com/1156544 Reviewed-by: Toon Verwaest <[email protected]> Commit-Queue: Camillo Bruni <[email protected]> Cr-Commit-Position: refs/heads/master@{#54821} PR-URL: #22210 Reviewed-By: Matteo Collina <[email protected]> Reviewed-By: Gus Caplan <[email protected]>
1 parent 1ed03b0 commit 4dfafac

File tree

5 files changed

+136
-26
lines changed

5 files changed

+136
-26
lines changed

common.gypi

+1-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929

3030
# Reset this number to 0 on major V8 upgrades.
3131
# Increment by one for each non-official patch applied to deps/v8.
32-
'v8_embedder_string': '-node.13',
32+
'v8_embedder_string': '-node.14',
3333

3434
# Enable disassembler for `--print-code` v8 options
3535
'v8_enable_disassembler': 1,

deps/v8/src/keys.cc

+29-17
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,10 @@ static bool ContainsOnlyValidKeys(Handle<FixedArray> array) {
3737
// static
3838
MaybeHandle<FixedArray> KeyAccumulator::GetKeys(
3939
Handle<JSReceiver> object, KeyCollectionMode mode, PropertyFilter filter,
40-
GetKeysConversion keys_conversion, bool is_for_in) {
40+
GetKeysConversion keys_conversion, bool is_for_in, bool skip_indices) {
4141
Isolate* isolate = object->GetIsolate();
42-
FastKeyAccumulator accumulator(isolate, object, mode, filter);
43-
accumulator.set_is_for_in(is_for_in);
42+
FastKeyAccumulator accumulator(isolate, object, mode, filter, is_for_in,
43+
skip_indices);
4444
return accumulator.GetKeys(keys_conversion);
4545
}
4646

@@ -356,7 +356,8 @@ Handle<FixedArray> GetFastEnumPropertyKeys(Isolate* isolate,
356356
template <bool fast_properties>
357357
MaybeHandle<FixedArray> GetOwnKeysWithElements(Isolate* isolate,
358358
Handle<JSObject> object,
359-
GetKeysConversion convert) {
359+
GetKeysConversion convert,
360+
bool skip_indices) {
360361
Handle<FixedArray> keys;
361362
ElementsAccessor* accessor = object->GetElementsAccessor();
362363
if (fast_properties) {
@@ -365,8 +366,13 @@ MaybeHandle<FixedArray> GetOwnKeysWithElements(Isolate* isolate,
365366
// TODO(cbruni): preallocate big enough array to also hold elements.
366367
keys = KeyAccumulator::GetOwnEnumPropertyKeys(isolate, object);
367368
}
368-
MaybeHandle<FixedArray> result =
369-
accessor->PrependElementIndices(object, keys, convert, ONLY_ENUMERABLE);
369+
MaybeHandle<FixedArray> result;
370+
if (skip_indices) {
371+
result = keys;
372+
} else {
373+
result =
374+
accessor->PrependElementIndices(object, keys, convert, ONLY_ENUMERABLE);
375+
}
370376

371377
if (FLAG_trace_for_in_enumerate) {
372378
PrintF("| strings=%d symbols=0 elements=%u || prototypes>=1 ||\n",
@@ -404,7 +410,8 @@ MaybeHandle<FixedArray> FastKeyAccumulator::GetKeysFast(
404410

405411
// Do not try to use the enum-cache for dict-mode objects.
406412
if (map->is_dictionary_map()) {
407-
return GetOwnKeysWithElements<false>(isolate_, object, keys_conversion);
413+
return GetOwnKeysWithElements<false>(isolate_, object, keys_conversion,
414+
skip_indices_);
408415
}
409416
int enum_length = receiver_->map()->EnumLength();
410417
if (enum_length == kInvalidEnumCacheSentinel) {
@@ -422,7 +429,8 @@ MaybeHandle<FixedArray> FastKeyAccumulator::GetKeysFast(
422429
}
423430
// The properties-only case failed because there were probably elements on the
424431
// receiver.
425-
return GetOwnKeysWithElements<true>(isolate_, object, keys_conversion);
432+
return GetOwnKeysWithElements<true>(isolate_, object, keys_conversion,
433+
skip_indices_);
426434
}
427435

428436
MaybeHandle<FixedArray>
@@ -451,6 +459,7 @@ MaybeHandle<FixedArray> FastKeyAccumulator::GetKeysSlow(
451459
GetKeysConversion keys_conversion) {
452460
KeyAccumulator accumulator(isolate_, mode_, filter_);
453461
accumulator.set_is_for_in(is_for_in_);
462+
accumulator.set_skip_indices(skip_indices_);
454463
accumulator.set_last_non_empty_prototype(last_non_empty_prototype_);
455464

456465
MAYBE_RETURN(accumulator.CollectKeys(receiver_, receiver_),
@@ -698,13 +707,15 @@ Maybe<bool> KeyAccumulator::CollectOwnPropertyNames(Handle<JSReceiver> receiver,
698707
Maybe<bool> KeyAccumulator::CollectAccessCheckInterceptorKeys(
699708
Handle<AccessCheckInfo> access_check_info, Handle<JSReceiver> receiver,
700709
Handle<JSObject> object) {
701-
MAYBE_RETURN((CollectInterceptorKeysInternal(
702-
receiver, object,
703-
handle(InterceptorInfo::cast(
704-
access_check_info->indexed_interceptor()),
705-
isolate_),
706-
this, kIndexed)),
707-
Nothing<bool>());
710+
if (!skip_indices_) {
711+
MAYBE_RETURN((CollectInterceptorKeysInternal(
712+
receiver, object,
713+
handle(InterceptorInfo::cast(
714+
access_check_info->indexed_interceptor()),
715+
isolate_),
716+
this, kIndexed)),
717+
Nothing<bool>());
718+
}
708719
MAYBE_RETURN(
709720
(CollectInterceptorKeysInternal(
710721
receiver, object,
@@ -935,8 +946,9 @@ Maybe<bool> KeyAccumulator::CollectOwnJSProxyTargetKeys(
935946
Handle<FixedArray> keys;
936947
ASSIGN_RETURN_ON_EXCEPTION_VALUE(
937948
isolate_, keys,
938-
KeyAccumulator::GetKeys(target, KeyCollectionMode::kOwnOnly, filter_,
939-
GetKeysConversion::kConvertToString, is_for_in_),
949+
KeyAccumulator::GetKeys(
950+
target, KeyCollectionMode::kOwnOnly, filter_,
951+
GetKeysConversion::kConvertToString, is_for_in_, skip_indices_),
940952
Nothing<bool>());
941953
Maybe<bool> result = AddKeysFromJSProxy(proxy, keys);
942954
return result;

deps/v8/src/keys.h

+10-4
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ class KeyAccumulator final BASE_EMBEDDED {
4040
static MaybeHandle<FixedArray> GetKeys(
4141
Handle<JSReceiver> object, KeyCollectionMode mode, PropertyFilter filter,
4242
GetKeysConversion keys_conversion = GetKeysConversion::kKeepNumbers,
43-
bool is_for_in = false);
43+
bool is_for_in = false, bool skip_indices = false);
4444

4545
Handle<FixedArray> GetKeys(
4646
GetKeysConversion convert = GetKeysConversion::kKeepNumbers);
@@ -128,14 +128,19 @@ class KeyAccumulator final BASE_EMBEDDED {
128128
class FastKeyAccumulator {
129129
public:
130130
FastKeyAccumulator(Isolate* isolate, Handle<JSReceiver> receiver,
131-
KeyCollectionMode mode, PropertyFilter filter)
132-
: isolate_(isolate), receiver_(receiver), mode_(mode), filter_(filter) {
131+
KeyCollectionMode mode, PropertyFilter filter,
132+
bool is_for_in = false, bool skip_indices = false)
133+
: isolate_(isolate),
134+
receiver_(receiver),
135+
mode_(mode),
136+
filter_(filter),
137+
is_for_in_(is_for_in),
138+
skip_indices_(skip_indices) {
133139
Prepare();
134140
}
135141

136142
bool is_receiver_simple_enum() { return is_receiver_simple_enum_; }
137143
bool has_empty_prototype() { return has_empty_prototype_; }
138-
void set_is_for_in(bool value) { is_for_in_ = value; }
139144

140145
MaybeHandle<FixedArray> GetKeys(
141146
GetKeysConversion convert = GetKeysConversion::kKeepNumbers);
@@ -153,6 +158,7 @@ class FastKeyAccumulator {
153158
KeyCollectionMode mode_;
154159
PropertyFilter filter_;
155160
bool is_for_in_ = false;
161+
bool skip_indices_ = false;
156162
bool is_receiver_simple_enum_ = false;
157163
bool has_empty_prototype_ = false;
158164

deps/v8/src/runtime/runtime-forin.cc

+1-2
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,7 @@ MaybeHandle<HeapObject> Enumerate(Handle<JSReceiver> receiver) {
2525
JSObject::MakePrototypesFast(receiver, kStartAtReceiver, isolate);
2626
FastKeyAccumulator accumulator(isolate, receiver,
2727
KeyCollectionMode::kIncludePrototypes,
28-
ENUMERABLE_STRINGS);
29-
accumulator.set_is_for_in(true);
28+
ENUMERABLE_STRINGS, true);
3029
// Test if we have an enum cache for {receiver}.
3130
if (!accumulator.is_receiver_simple_enum()) {
3231
Handle<FixedArray> keys;

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

+95-2
Original file line numberDiff line numberDiff line change
@@ -15356,14 +15356,107 @@ THREADED_TEST(PropertyEnumeration2) {
1535615356
}
1535715357
}
1535815358

15359-
THREADED_TEST(PropertyNames) {
15359+
THREADED_TEST(GetPropertyNames) {
1536015360
LocalContext context;
1536115361
v8::Isolate* isolate = context->GetIsolate();
1536215362
v8::HandleScope scope(isolate);
1536315363
v8::Local<v8::Value> result = CompileRun(
1536415364
"var result = {0: 0, 1: 1, a: 2, b: 3};"
1536515365
"result[Symbol('symbol')] = true;"
15366-
"result.__proto__ = {2: 4, 3: 5, c: 6, d: 7};"
15366+
"result.__proto__ = {__proto__:null, 2: 4, 3: 5, c: 6, d: 7};"
15367+
"result;");
15368+
v8::Local<v8::Object> object = result.As<v8::Object>();
15369+
v8::PropertyFilter default_filter =
15370+
static_cast<v8::PropertyFilter>(v8::ONLY_ENUMERABLE | v8::SKIP_SYMBOLS);
15371+
v8::PropertyFilter include_symbols_filter = v8::ONLY_ENUMERABLE;
15372+
15373+
v8::Local<v8::Array> properties =
15374+
object->GetPropertyNames(context.local()).ToLocalChecked();
15375+
const char* expected_properties1[] = {"0", "1", "a", "b", "2", "3", "c", "d"};
15376+
CheckStringArray(isolate, properties, 8, expected_properties1);
15377+
15378+
properties =
15379+
object
15380+
->GetPropertyNames(context.local(),
15381+
v8::KeyCollectionMode::kIncludePrototypes,
15382+
default_filter, v8::IndexFilter::kIncludeIndices)
15383+
.ToLocalChecked();
15384+
CheckStringArray(isolate, properties, 8, expected_properties1);
15385+
15386+
properties = object
15387+
->GetPropertyNames(context.local(),
15388+
v8::KeyCollectionMode::kIncludePrototypes,
15389+
include_symbols_filter,
15390+
v8::IndexFilter::kIncludeIndices)
15391+
.ToLocalChecked();
15392+
const char* expected_properties1_1[] = {"0", "1", "a", "b", nullptr,
15393+
"2", "3", "c", "d"};
15394+
CheckStringArray(isolate, properties, 9, expected_properties1_1);
15395+
CheckIsSymbolAt(isolate, properties, 4, "symbol");
15396+
15397+
properties =
15398+
object
15399+
->GetPropertyNames(context.local(),
15400+
v8::KeyCollectionMode::kIncludePrototypes,
15401+
default_filter, v8::IndexFilter::kSkipIndices)
15402+
.ToLocalChecked();
15403+
const char* expected_properties2[] = {"a", "b", "c", "d"};
15404+
CheckStringArray(isolate, properties, 4, expected_properties2);
15405+
15406+
properties = object
15407+
->GetPropertyNames(context.local(),
15408+
v8::KeyCollectionMode::kIncludePrototypes,
15409+
include_symbols_filter,
15410+
v8::IndexFilter::kSkipIndices)
15411+
.ToLocalChecked();
15412+
const char* expected_properties2_1[] = {"a", "b", nullptr, "c", "d"};
15413+
CheckStringArray(isolate, properties, 5, expected_properties2_1);
15414+
CheckIsSymbolAt(isolate, properties, 2, "symbol");
15415+
15416+
properties =
15417+
object
15418+
->GetPropertyNames(context.local(), v8::KeyCollectionMode::kOwnOnly,
15419+
default_filter, v8::IndexFilter::kIncludeIndices)
15420+
.ToLocalChecked();
15421+
const char* expected_properties3[] = {"0", "1", "a", "b"};
15422+
CheckStringArray(isolate, properties, 4, expected_properties3);
15423+
15424+
properties = object
15425+
->GetPropertyNames(
15426+
context.local(), v8::KeyCollectionMode::kOwnOnly,
15427+
include_symbols_filter, v8::IndexFilter::kIncludeIndices)
15428+
.ToLocalChecked();
15429+
const char* expected_properties3_1[] = {"0", "1", "a", "b", nullptr};
15430+
CheckStringArray(isolate, properties, 5, expected_properties3_1);
15431+
CheckIsSymbolAt(isolate, properties, 4, "symbol");
15432+
15433+
properties =
15434+
object
15435+
->GetPropertyNames(context.local(), v8::KeyCollectionMode::kOwnOnly,
15436+
default_filter, v8::IndexFilter::kSkipIndices)
15437+
.ToLocalChecked();
15438+
const char* expected_properties4[] = {"a", "b"};
15439+
CheckStringArray(isolate, properties, 2, expected_properties4);
15440+
15441+
properties = object
15442+
->GetPropertyNames(
15443+
context.local(), v8::KeyCollectionMode::kOwnOnly,
15444+
include_symbols_filter, v8::IndexFilter::kSkipIndices)
15445+
.ToLocalChecked();
15446+
const char* expected_properties4_1[] = {"a", "b", nullptr};
15447+
CheckStringArray(isolate, properties, 3, expected_properties4_1);
15448+
CheckIsSymbolAt(isolate, properties, 2, "symbol");
15449+
}
15450+
15451+
THREADED_TEST(ProxyGetPropertyNames) {
15452+
LocalContext context;
15453+
v8::Isolate* isolate = context->GetIsolate();
15454+
v8::HandleScope scope(isolate);
15455+
v8::Local<v8::Value> result = CompileRun(
15456+
"var target = {0: 0, 1: 1, a: 2, b: 3};"
15457+
"target[Symbol('symbol')] = true;"
15458+
"target.__proto__ = {__proto__:null, 2: 4, 3: 5, c: 6, d: 7};"
15459+
"var result = new Proxy(target, {});"
1536715460
"result;");
1536815461
v8::Local<v8::Object> object = result.As<v8::Object>();
1536915462
v8::PropertyFilter default_filter =

0 commit comments

Comments
 (0)