LibJS+LibWeb: Add fast path for builtin iterators in iterator_step()

We already have fast path for built-in iterators that skips `next()`
lookup and iteration result object allocation applied for `for..of` and
`for..in` loops. This change extends it to `iterator_step()` to cover
`Array.from()`, `[...arr]` and many other cases.

Makes following function go 2.35x faster on my computer:
```js
(function f() {
  let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
  for (let i = 0; i < 1000000; i++) {
    let [a, ...rest] = arr;
  }
})();
```
This commit is contained in:
Aliaksandr Kalenik 2025-05-12 00:31:51 +03:00 committed by Alexander Kalenik
commit bb53485dea
Notes: github-actions[bot] 2025-05-13 12:15:28 +00:00
6 changed files with 38 additions and 18 deletions

View file

@ -1766,10 +1766,10 @@ void IDL::ParameterizedType::generate_sequence_from_iterable(SourceGenerator& ge
sequence_generator.append(R"~~~(
for (;;) {
auto next@recursion_depth@ = TRY(JS::iterator_step(vm, @iterable_cpp_name@_iterator@recursion_depth@));
if (!next@recursion_depth@)
if (!next@recursion_depth@.has<JS::IterationResult>())
break;
auto next_item@recursion_depth@ = TRY(JS::iterator_value(vm, *next@recursion_depth@));
auto next_item@recursion_depth@ = TRY(next@recursion_depth@.get<JS::IterationResult>().value);
)~~~");
// FIXME: Sequences types should be TypeWithExtendedAttributes, which would allow us to get [LegacyNullToEmptyString] here.