Skip to content

[JSC] Complete the implementation of Iterator helpers proposal#34418

Merged
webkit-commit-queue merged 1 commit intoWebKit:mainfrom
shvaikalesh:bug-248650
Oct 3, 2024
Merged

[JSC] Complete the implementation of Iterator helpers proposal#34418
webkit-commit-queue merged 1 commit intoWebKit:mainfrom
shvaikalesh:bug-248650

Conversation

@shvaikalesh
Copy link
Copy Markdown
Member

@shvaikalesh shvaikalesh commented Sep 29, 2024

8243544

[JSC] Complete the implementation of Iterator helpers proposal
https://bugs.webkit.org/show_bug.cgi?id=248650
<rdar://problem/103171739>

Reviewed by Yusuke Suzuki.

This patch completes the implementation of Iterator helpers proposal [1] by adding map(), filter(),
take(), drop(), and flatMap() methods to Iterator.prototype, all still behind a feature flag.
Except for merging two loops in drop() [2], this change precisely follows the spec steps.

While it is possible to squeeze out a bit more performance by hand-rolling generators, we utilize
them because optimization of generators is one of long-term goals for JetStream3.

Except for flatMap(), which has complex (yet easily implementable via nested for/of loops) semantics
of closing inner and then outer iterator [3], this patch avoids iterator wrappers as much as possible.
Iterator wrappers are necessary to make an early "next" method lookup and/or prevent second @@iterator
method lookup; they are hard to get right and they will get costly once generators will get faster.

Instead of for/of loops with wrappers, this change introduces @ifAbruptCloseIterator(), which provides
complex iterator closing semantics [4] of a for/of loop as a bytecode intrinsic. The syntax is quirky,
but it is the best we can do without introducing another intrinsic node.

[1]: https://github.com/tc39/proposal-iterator-helpers
[2]: https://tc39.es/proposal-iterator-helpers/#sec-iteratorprototype.drop (steps 8.b-c)
[3]: https://tc39.es/proposal-iterator-helpers/#sec-iteratorprototype.flatmap (step 5.b.viii.4.b)
[4]: https://tc39.es/ecma262/#sec-ifabruptcloseiterator

* JSTests/stress/iterator-from.js: Adjust error message expectation.
* JSTests/stress/iterator-prototype-map.js: Added.
* JSTests/test262/expectations.yaml: Mark 326 tests as passing.
* Source/JavaScriptCore/CMakeLists.txt:
* Source/JavaScriptCore/DerivedSources-input.xcfilelist:
* Source/JavaScriptCore/DerivedSources-output.xcfilelist:
* Source/JavaScriptCore/DerivedSources.make:
* Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj:
* Source/JavaScriptCore/Sources.txt:
* Source/JavaScriptCore/builtins/JSIteratorConstructor.js:
(linkTimeConstant.getIteratorFlattenable):
(from):
* Source/JavaScriptCore/builtins/JSIteratorHelperPrototype.js: Added.
* Source/JavaScriptCore/builtins/JSIteratorPrototype.js:
(map):
(filter):
(take):
(drop):
(flatMap):
* Source/JavaScriptCore/bytecode/BytecodeIntrinsicRegistry.cpp:
(JSC::BytecodeIntrinsicRegistry::BytecodeIntrinsicRegistry):
* Source/JavaScriptCore/bytecode/BytecodeIntrinsicRegistry.h:
* Source/JavaScriptCore/bytecode/BytecodeList.rb:
* Source/JavaScriptCore/bytecode/BytecodeUseDef.cpp:
(JSC::computeUsesForBytecodeIndexImpl):
(JSC::computeDefsForBytecodeIndexImpl):
* Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp:
(JSC::BytecodeGenerator::emitNewIteratorHelper):
* Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h:
(JSC::BytecodeGenerator::emitIsIteratorHelper):
* Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp:
(JSC::iteratorHelperInternalFieldIndex):
(JSC::BytecodeIntrinsicNode::emit_intrinsic_getIteratorHelperInternalField):
(JSC::BytecodeIntrinsicNode::emit_intrinsic_newIteratorHelper):
(JSC::BytecodeIntrinsicNode::emit_intrinsic_iteratorGenericClose):
(JSC::BytecodeIntrinsicNode::emit_intrinsic_iteratorGenericNext):
(JSC::BytecodeIntrinsicNode::emit_intrinsic_ifAbruptCloseIterator):
* Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::parseBlock):
* Source/JavaScriptCore/dfg/DFGObjectAllocationSinkingPhase.cpp:
* Source/JavaScriptCore/dfg/DFGOperations.cpp:
(JSC::DFG::JSC_DEFINE_JIT_OPERATION):
* Source/JavaScriptCore/dfg/DFGOperations.h:
* Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp:
* Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::compileNewInternalFieldObject):
(JSC::FTL::DFG::LowerDFGToB3::compileCompareStrictEq):
* Source/JavaScriptCore/ftl/FTLOperations.cpp:
(JSC::FTL::JSC_DEFINE_NOEXCEPT_JIT_OPERATION):
* Source/JavaScriptCore/heap/Heap.h:
* Source/JavaScriptCore/heap/HeapSubspaceTypes.h:
* Source/JavaScriptCore/jit/JIT.cpp:
(JSC::JIT::privateCompileMainPass):
* Source/JavaScriptCore/llint/LowLevelInterpreter.asm:
* Source/JavaScriptCore/runtime/CommonSlowPaths.cpp:
(JSC::JSC_DEFINE_COMMON_SLOW_PATH):
* Source/JavaScriptCore/runtime/CommonSlowPaths.h:
* Source/JavaScriptCore/runtime/JSGlobalObject.cpp:
(JSC::JSGlobalObject::init):
(JSC::JSGlobalObject::visitChildrenImpl):
* Source/JavaScriptCore/runtime/JSGlobalObject.h:
(JSC::JSGlobalObject::iteratorHelperPrototype const):
(JSC::JSGlobalObject::iteratorHelperStructure const):
* Source/JavaScriptCore/runtime/JSIteratorHelper.cpp: Added.
(JSC::JSIteratorHelper::createWithInitialValues):
(JSC::JSIteratorHelper::create):
(JSC::JSIteratorHelper::createStructure):
(JSC::JSIteratorHelper::JSIteratorHelper):
(JSC::JSIteratorHelper::visitChildrenImpl):
* Source/JavaScriptCore/runtime/JSIteratorHelper.h: Added.
* Source/JavaScriptCore/runtime/JSIteratorHelperPrototype.cpp: Added.
(JSC::JSIteratorHelperPrototype::finishCreation):
* Source/JavaScriptCore/runtime/JSIteratorHelperPrototype.h: Added.
* Source/JavaScriptCore/runtime/JSIteratorHelperPrototypeInlines.h: Added.
(JSC::JSIteratorHelperPrototype::createStructure):
* Source/JavaScriptCore/runtime/JSIteratorPrototype.cpp:
(JSC::JSIteratorPrototype::finishCreation):
* Source/JavaScriptCore/runtime/JSType.cpp:
(WTF::printInternal):
* Source/JavaScriptCore/runtime/JSType.h:

Canonical link: https://commits.webkit.org/284597@main

d382242

Misc iOS, visionOS, tvOS & watchOS macOS Linux Windows
🧪 style 🛠 ios 🛠 mac 🛠 wpe 🛠 win
🛠 ios-sim 🛠 mac-AS-debug 🧪 wpe-wk2 🧪 win-tests
🧪 webkitperl 🧪 ios-wk2 🧪 api-mac 🧪 api-wpe
🧪 ios-wk2-wpt 🧪 mac-wk1 ⏳ 🛠 wpe-cairo
🛠 🧪 jsc 🧪 api-ios 🧪 mac-wk2 loading 🛠 gtk
🛠 🧪 jsc-arm64 🛠 vision 🧪 mac-AS-debug-wk2 loading 🧪 gtk-wk2
🛠 vision-sim 🧪 mac-wk2-stress loading 🧪 api-gtk
⏳ 🧪 vision-wk2 🧪 mac-intel-wk2 🛠 jsc-armv7
✅ 🛠 🧪 unsafe-merge 🛠 tv 🧪 jsc-armv7-tests
🛠 tv-sim
🛠 watch
🛠 watch-sim

@shvaikalesh shvaikalesh self-assigned this Sep 29, 2024
@shvaikalesh shvaikalesh added the JavaScriptCore For bugs in JavaScriptCore, the JS engine used by WebKit, other than kxmlcore issues. label Sep 29, 2024
@webkit-ews-buildbot webkit-ews-buildbot added the merging-blocked Applied to prevent a change from being merged label Sep 29, 2024
@shvaikalesh shvaikalesh removed the merging-blocked Applied to prevent a change from being merged label Sep 29, 2024
@shvaikalesh shvaikalesh marked this pull request as ready for review October 3, 2024 00:14
@shvaikalesh shvaikalesh requested a review from a team as a code owner October 3, 2024 00:14
@shvaikalesh shvaikalesh removed the request for review from a team October 3, 2024 00:21
@shvaikalesh shvaikalesh added skip-ews Applied to prevent a change from being run on EWS unsafe-merge-queue Applied to send a pull request to merge-queue, but skip building and testing labels Oct 3, 2024
https://bugs.webkit.org/show_bug.cgi?id=248650
<rdar://problem/103171739>

Reviewed by Yusuke Suzuki.

This patch completes the implementation of Iterator helpers proposal [1] by adding map(), filter(),
take(), drop(), and flatMap() methods to Iterator.prototype, all still behind a feature flag.
Except for merging two loops in drop() [2], this change precisely follows the spec steps.

While it is possible to squeeze out a bit more performance by hand-rolling generators, we utilize
them because optimization of generators is one of long-term goals for JetStream3.

Except for flatMap(), which has complex (yet easily implementable via nested for/of loops) semantics
of closing inner and then outer iterator [3], this patch avoids iterator wrappers as much as possible.
Iterator wrappers are necessary to make an early "next" method lookup and/or prevent second @@iterator
method lookup; they are hard to get right and they will get costly once generators will get faster.

Instead of for/of loops with wrappers, this change introduces @ifAbruptCloseIterator(), which provides
complex iterator closing semantics [4] of a for/of loop as a bytecode intrinsic. The syntax is quirky,
but it is the best we can do without introducing another intrinsic node.

[1]: https://github.com/tc39/proposal-iterator-helpers
[2]: https://tc39.es/proposal-iterator-helpers/#sec-iteratorprototype.drop (steps 8.b-c)
[3]: https://tc39.es/proposal-iterator-helpers/#sec-iteratorprototype.flatmap (step 5.b.viii.4.b)
[4]: https://tc39.es/ecma262/#sec-ifabruptcloseiterator

* JSTests/stress/iterator-from.js: Adjust error message expectation.
* JSTests/stress/iterator-prototype-map.js: Added.
* JSTests/test262/expectations.yaml: Mark 326 tests as passing.
* Source/JavaScriptCore/CMakeLists.txt:
* Source/JavaScriptCore/DerivedSources-input.xcfilelist:
* Source/JavaScriptCore/DerivedSources-output.xcfilelist:
* Source/JavaScriptCore/DerivedSources.make:
* Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj:
* Source/JavaScriptCore/Sources.txt:
* Source/JavaScriptCore/builtins/JSIteratorConstructor.js:
(linkTimeConstant.getIteratorFlattenable):
(from):
* Source/JavaScriptCore/builtins/JSIteratorHelperPrototype.js: Added.
* Source/JavaScriptCore/builtins/JSIteratorPrototype.js:
(map):
(filter):
(take):
(drop):
(flatMap):
* Source/JavaScriptCore/bytecode/BytecodeIntrinsicRegistry.cpp:
(JSC::BytecodeIntrinsicRegistry::BytecodeIntrinsicRegistry):
* Source/JavaScriptCore/bytecode/BytecodeIntrinsicRegistry.h:
* Source/JavaScriptCore/bytecode/BytecodeList.rb:
* Source/JavaScriptCore/bytecode/BytecodeUseDef.cpp:
(JSC::computeUsesForBytecodeIndexImpl):
(JSC::computeDefsForBytecodeIndexImpl):
* Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp:
(JSC::BytecodeGenerator::emitNewIteratorHelper):
* Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h:
(JSC::BytecodeGenerator::emitIsIteratorHelper):
* Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp:
(JSC::iteratorHelperInternalFieldIndex):
(JSC::BytecodeIntrinsicNode::emit_intrinsic_getIteratorHelperInternalField):
(JSC::BytecodeIntrinsicNode::emit_intrinsic_newIteratorHelper):
(JSC::BytecodeIntrinsicNode::emit_intrinsic_iteratorGenericClose):
(JSC::BytecodeIntrinsicNode::emit_intrinsic_iteratorGenericNext):
(JSC::BytecodeIntrinsicNode::emit_intrinsic_ifAbruptCloseIterator):
* Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::parseBlock):
* Source/JavaScriptCore/dfg/DFGObjectAllocationSinkingPhase.cpp:
* Source/JavaScriptCore/dfg/DFGOperations.cpp:
(JSC::DFG::JSC_DEFINE_JIT_OPERATION):
* Source/JavaScriptCore/dfg/DFGOperations.h:
* Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp:
* Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::compileNewInternalFieldObject):
(JSC::FTL::DFG::LowerDFGToB3::compileCompareStrictEq):
* Source/JavaScriptCore/ftl/FTLOperations.cpp:
(JSC::FTL::JSC_DEFINE_NOEXCEPT_JIT_OPERATION):
* Source/JavaScriptCore/heap/Heap.h:
* Source/JavaScriptCore/heap/HeapSubspaceTypes.h:
* Source/JavaScriptCore/jit/JIT.cpp:
(JSC::JIT::privateCompileMainPass):
* Source/JavaScriptCore/llint/LowLevelInterpreter.asm:
* Source/JavaScriptCore/runtime/CommonSlowPaths.cpp:
(JSC::JSC_DEFINE_COMMON_SLOW_PATH):
* Source/JavaScriptCore/runtime/CommonSlowPaths.h:
* Source/JavaScriptCore/runtime/JSGlobalObject.cpp:
(JSC::JSGlobalObject::init):
(JSC::JSGlobalObject::visitChildrenImpl):
* Source/JavaScriptCore/runtime/JSGlobalObject.h:
(JSC::JSGlobalObject::iteratorHelperPrototype const):
(JSC::JSGlobalObject::iteratorHelperStructure const):
* Source/JavaScriptCore/runtime/JSIteratorHelper.cpp: Added.
(JSC::JSIteratorHelper::createWithInitialValues):
(JSC::JSIteratorHelper::create):
(JSC::JSIteratorHelper::createStructure):
(JSC::JSIteratorHelper::JSIteratorHelper):
(JSC::JSIteratorHelper::visitChildrenImpl):
* Source/JavaScriptCore/runtime/JSIteratorHelper.h: Added.
* Source/JavaScriptCore/runtime/JSIteratorHelperPrototype.cpp: Added.
(JSC::JSIteratorHelperPrototype::finishCreation):
* Source/JavaScriptCore/runtime/JSIteratorHelperPrototype.h: Added.
* Source/JavaScriptCore/runtime/JSIteratorHelperPrototypeInlines.h: Added.
(JSC::JSIteratorHelperPrototype::createStructure):
* Source/JavaScriptCore/runtime/JSIteratorPrototype.cpp:
(JSC::JSIteratorPrototype::finishCreation):
* Source/JavaScriptCore/runtime/JSType.cpp:
(WTF::printInternal):
* Source/JavaScriptCore/runtime/JSType.h:

Canonical link: https://commits.webkit.org/284597@main
@webkit-commit-queue
Copy link
Copy Markdown
Collaborator

Committed 284597@main (8243544): https://commits.webkit.org/284597@main

Reviewed commits have been landed. Closing PR #34418 and removing active labels.

@webkit-commit-queue webkit-commit-queue merged commit 8243544 into WebKit:main Oct 3, 2024
@webkit-commit-queue webkit-commit-queue removed the unsafe-merge-queue Applied to send a pull request to merge-queue, but skip building and testing label Oct 3, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

JavaScriptCore For bugs in JavaScriptCore, the JS engine used by WebKit, other than kxmlcore issues. skip-ews Applied to prevent a change from being run on EWS

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants