Bug 221526 - [JSC] C++ iteration should support fast iterator protocol
Summary: [JSC] C++ iteration should support fast iterator protocol
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: New Bugs (show other bugs)
Version: WebKit Nightly Build
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: Yusuke Suzuki
URL:
Keywords: InRadar
Depends on:
Blocks:
 
Reported: 2021-02-07 02:38 PST by Yusuke Suzuki
Modified: 2021-02-09 21:47 PST (History)
14 users (show)

See Also:


Attachments
Patch (16.48 KB, patch)
2021-02-07 02:42 PST, Yusuke Suzuki
ews-feeder: commit-queue-
Details | Formatted Diff | Diff
Patch (18.76 KB, patch)
2021-02-07 02:48 PST, Yusuke Suzuki
ews-feeder: commit-queue-
Details | Formatted Diff | Diff
Patch (18.80 KB, patch)
2021-02-07 02:56 PST, Yusuke Suzuki
no flags Details | Formatted Diff | Diff
Patch (19.87 KB, patch)
2021-02-07 02:57 PST, Yusuke Suzuki
ews-feeder: commit-queue-
Details | Formatted Diff | Diff
Patch (19.92 KB, patch)
2021-02-07 03:17 PST, Yusuke Suzuki
ews-feeder: commit-queue-
Details | Formatted Diff | Diff
Patch (20.25 KB, patch)
2021-02-07 03:25 PST, Yusuke Suzuki
ashvayka: review+
Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Yusuke Suzuki 2021-02-07 02:38:54 PST
[JSC] C++ iteration should support fast iterator protocol
Comment 1 Yusuke Suzuki 2021-02-07 02:42:03 PST
Created attachment 419531 [details]
Patch
Comment 2 Yusuke Suzuki 2021-02-07 02:43:33 PST
Comment on attachment 419531 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=419531&action=review

> Source/JavaScriptCore/runtime/IteratorOperations.h:120
> +                JSArrayIterator* iterator = JSArrayIterator::create(vm, globalObject.arrayIteratorStructure(), array, IterationKind::Values);
> +                iterator->internalField(JSArrayIterator::Field::Index).setWithoutWriteBarrier(jsNumber(index + 1));
> +                iteratorClose(&globalObject, iterator);
> +                return;

We need to have an array iterator only when we need to catch an error. So, when we found an error, we create an array iterator with appropriate state.
Comment 3 Yusuke Suzuki 2021-02-07 02:48:44 PST
Created attachment 419532 [details]
Patch
Comment 4 Yusuke Suzuki 2021-02-07 02:56:12 PST
Created attachment 419533 [details]
Patch
Comment 5 Yusuke Suzuki 2021-02-07 02:57:51 PST
Created attachment 419534 [details]
Patch
Comment 6 Yusuke Suzuki 2021-02-07 03:17:42 PST
Created attachment 419535 [details]
Patch
Comment 7 Yusuke Suzuki 2021-02-07 03:25:56 PST
Created attachment 419536 [details]
Patch
Comment 8 Alexey Shvayka 2021-02-09 15:47:00 PST
Comment on attachment 419536 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=419536&action=review

Well done! r=me with a comment on test and a few nits.

> Source/JavaScriptCore/runtime/CommonSlowPaths.cpp:867
> +    if (prepareForFastArrayIteration(vm, globalObject, iterable, symbolIterator) == IterationMode::FastArray) {

nit: "prepare" in the name suggests the method is performing some side-effects, yet it's pure. Maybe it's worth renaming it to something like "getIterationMode"?

> Source/JavaScriptCore/runtime/IteratorOperations.cpp:249
> +    // We don't want to allocate the values function just to check if it's the same as our function at so we use the concurrent accessor.

typo: extra "at" after "function"

> Source/JavaScriptCore/runtime/IteratorOperations.cpp:264
> +    // FIXME: We want to support broader JSArrays so long as array[@@iterator] is not defined.

typo: *as* long as

> Source/JavaScriptCore/runtime/IteratorOperations.h:70
> +            JSValue nextValue = array->getIndex(globalObject, static_cast<unsigned>(index));

nit: Do we really need the static_cast<unsigned> here given that `index` is unsigned and getIndex() has only one overload.

> Source/JavaScriptCore/runtime/IteratorOperations.h:76
> +                iterator->internalField(JSArrayIterator::Field::Index).setWithoutWriteBarrier(jsNumber(index + 1));

This is very tricky, great catch! Could you please expand stress/map-constructor-hole-throw.js to cover this line?
Since we get a hold of iterator whose [[IteratedObject]] is still defined, we can test its [[ArrayIteratorNextIndex]] value by calling next(), right?

> Source/JavaScriptCore/runtime/IteratorOperations.h:112
> +            JSValue nextValue = array->getIndex(&globalObject, static_cast<unsigned>(index));

Ditto on static_cast<unsigned>.
Comment 9 Yusuke Suzuki 2021-02-09 21:44:53 PST
Comment on attachment 419536 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=419536&action=review

Thanks!

>> Source/JavaScriptCore/runtime/CommonSlowPaths.cpp:867
>> +    if (prepareForFastArrayIteration(vm, globalObject, iterable, symbolIterator) == IterationMode::FastArray) {
> 
> nit: "prepare" in the name suggests the method is performing some side-effects, yet it's pure. Maybe it's worth renaming it to something like "getIterationMode"?

Sounds good! Fixed.

>> Source/JavaScriptCore/runtime/IteratorOperations.cpp:249
>> +    // We don't want to allocate the values function just to check if it's the same as our function at so we use the concurrent accessor.
> 
> typo: extra "at" after "function"

Fixed.

>> Source/JavaScriptCore/runtime/IteratorOperations.cpp:264
>> +    // FIXME: We want to support broader JSArrays so long as array[@@iterator] is not defined.
> 
> typo: *as* long as

Fixed.

>> Source/JavaScriptCore/runtime/IteratorOperations.h:70
>> +            JSValue nextValue = array->getIndex(globalObject, static_cast<unsigned>(index));
> 
> nit: Do we really need the static_cast<unsigned> here given that `index` is unsigned and getIndex() has only one overload.

Fixed.

>> Source/JavaScriptCore/runtime/IteratorOperations.h:76
>> +                iterator->internalField(JSArrayIterator::Field::Index).setWithoutWriteBarrier(jsNumber(index + 1));
> 
> This is very tricky, great catch! Could you please expand stress/map-constructor-hole-throw.js to cover this line?
> Since we get a hold of iterator whose [[IteratedObject]] is still defined, we can test its [[ArrayIteratorNextIndex]] value by calling next(), right?

Right! Added that test :)

>> Source/JavaScriptCore/runtime/IteratorOperations.h:112
>> +            JSValue nextValue = array->getIndex(&globalObject, static_cast<unsigned>(index));
> 
> Ditto on static_cast<unsigned>.

Fixed.
Comment 10 Yusuke Suzuki 2021-02-09 21:46:10 PST
Committed r272638: <https://trac.webkit.org/changeset/272638>
Comment 11 Radar WebKit Bug Importer 2021-02-09 21:47:17 PST
<rdar://problem/74175114>