Slide 1

Slide 1 text

JavaScriptCoreの Object.groupBy / Map.groupBy の バグを自分で見つけて自分で直す 2023/04/25 meguro.es

Slide 2

Slide 2 text

自己紹介 SUZUKI Sosuke ユビー株式会社のプロダクト開発エンジニア Prettierのメンテナー 筑波大学の学生 最近はWebKitがアツい @__sosukesuzuki @sosukesuzuki

Slide 3

Slide 3 text

Object.groupBy / Map.groupBy とは ● ES2024から追加された新しいビルトイン ○ https://github.com/tc39/proposal-array-grouping ● LodashのgroupByと同じような便利な関数 ● このスライドでは Object.groupBy と Map.groupBy をまとめて GroupBy と呼ぶことにする

Slide 4

Slide 4 text

Object.groupBy / Map.groupBy とは

Slide 5

Slide 5 text

GroupByは何をする? GroupBy は1番目の引数として配列(items)を受け取り、2番目の引数 として関数(callbackfn)を受けとり、callbackfnを使ってitemsをグ ルーピングし、結果をオブジェクト(もしくはMap)として返す。

Slide 6

Slide 6 text

GroupByの仕様 https://tc39.es/ecma262/#sec-groupby

Slide 7

Slide 7 text

GroupByの仕様 https://tc39.es/ecma262/#sec-groupby 配列に限定されているわけではない

Slide 8

Slide 8 text

GroupByは何をする? GroupBy は1番目の引数として配列(items)を受け取り、2番目の引数 として関数(callbackfn)を受けとり、callbackfnを使ってitemsをグ ルーピングし、結果をオブジェクト(もしくはMap)として返す。 イテラブル

Slide 9

Slide 9 text

JavaScriptCoreのGroupByの実装 https://github.com/WebKit/WebKit/blob/ab951214497597d3 41962219a73d4b1ce743f19e/Source/JavaScriptCore/builtins/ ObjectConstructor.js (ライセンスは次ページ ) 内部用の関数呼び出しに @ が付いているが、基本 的には普通のJavaScript で書かれている

Slide 10

Slide 10 text

JavaScriptCoreのGroupByのライセンス /* * Copyright (C) 2016 Oleksandr Skachkov . * Copyright (C) 2015 Jordan Harband. All rights reserved. * Copyright (C) 2018 Yusuke Suzuki . * Copyright (C) 2023 Devin Rousso . * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ https://github.com/WebKit/WebKit/blob/ab951214497597d3 41962219a73d4b1ce743f19e/Source/JavaScriptCore/builtins/ ObjectConstructor.js (前ページのコードのライセンス )

Slide 11

Slide 11 text

JavaScriptCoreのGroupByの実装 https://github.com/WebKit/WebKit/blob/ab951214497597d3 41962219a73d4b1ce743f19e/Source/JavaScriptCore/builtins/ ObjectConstructor.js (ライセンスは次ページ ) itemsがオブジェクトでない場合、 その場でTypeErrorをthrowする

Slide 12

Slide 12 text

JavaScriptCoreのGroupByの実装 https://github.com/WebKit/WebKit/blob/ab951214497597d3 41962219a73d4b1ce743f19e/Source/JavaScriptCore/builtins/ ObjectConstructor.js (ライセンスは次ページ ) これでいいんだっけ?

Slide 13

Slide 13 text

JavaScriptCoreのGroupByの実装 https://github.com/WebKit/WebKit/blob/ab951214497597d3 41962219a73d4b1ce743f19e/Source/JavaScriptCore/builtins/ ObjectConstructor.js (ライセンスは次ページ ) オブジェクトではないイテラブルに対してもTypeErrorを throwしてしまうのでは?つまり...

Slide 14

Slide 14 text

JavaScriptCoreのGroupByの実装 https://github.com/WebKit/WebKit/blob/ab951214497597d3 41962219a73d4b1ce743f19e/Source/JavaScriptCore/builtins/ ObjectConstructor.js (ライセンスは次ページ ) Stringは?

Slide 15

Slide 15 text

GroupByのitemsがStringのときの正しい挙動 Chrome 123 で確認

Slide 16

Slide 16 text

GroupByのitemsがStringのときのJSCの挙動

Slide 17

Slide 17 text

バグを報告する ● GitHub issues ではなく https://bugs.webkit.org ○ https://bugs.webkit.org/show_bug.cgi?id=271524

Slide 18

Slide 18 text

バグを報告する ● GitHub issues ではなく https://bugs.webkit.org ○ https://bugs.webkit.org/show_bug.cgi?id=271524

Slide 19

Slide 19 text

JSCをローカルでビルドする ● https://github.com/WebKit/WebKit を clone する ○ デカすぎるので注意 ● JSCをビルドできるようにする ○ WebKitのビルドはCMakeとXCodeの二通りがある ○ Mac なら XCode を入れて ./Tools/Scripts/build-jsc –debug でいける ○ 自分はCMakeでのビルドを通せたことがない

Slide 20

Slide 20 text

JSCをローカルでビルドする ● デバッガの設定 ○ C++プロジェクトなのでLLDBを設定しておくと便利 ● VSCodeの設定 ○ 現時点で自分の設定を Gist に投稿しておいたので興味のある 方は参照してほしい ■ https://gist.github.com/sosukesuzuki/da19f1b789031 f19ad88ef2446beb7da

Slide 21

Slide 21 text

リポジトリのセットアップ ● WebKitが出しているガイドがいくつかあるのでこれらに従ってセット アップする(なんでいくつかあるんだ) ○ https://webkit.org/contributing-code/ ○ https://docs.webkit.org/Getting%20Started/Contributing Code.html#commit-messages ○ https://github.com/WebKit/WebKit/wiki/Contributing

Slide 22

Slide 22 text

JSCを直す https://github.com/WebKit/WebKit/pull/26383

Slide 23

Slide 23 text

JSCを直す https://github.com/WebKit/WebKit/pull/26383 !@isObject を @isUndefinedOrNull に (RequireObjectCoercible に対応する https://tc39.es/ecma262/#sec-requireobjectco ercible)

Slide 24

Slide 24 text

JSCを直す https://github.com/WebKit/WebKit/pull/26383 Symbol.iterator がないオブジェクトに対して 親切なエラーメッセージを投げる。 これがないと、58 行目の for 文で undefined is not a function になる

Slide 25

Slide 25 text

JSCを直す https://github.com/WebKit/WebKit/pull/26383 items[Symbol.iterator] がゲッターだった 場合に観測可能な副作用が生じうるので、ラッ パーオブジェクトを作成し、それを for of で回 す。

Slide 26

Slide 26 text

JSCを直す ● 最近のWebKitはGitで管理され、GitHubで開発されているが、Git の使い方にルールがあるので注意 ● ./Tools/Scripts/git-webkit を使ってcommitとかpushと かをする ● これもコントリビューションガイドに書いてある

Slide 27

Slide 27 text

JSCを直す Merged 🎉🎉

Slide 28

Slide 28 text

Test262にテストケースを追加する GroupBy のバグ直したん だ〜すごいでしょ〜 ???? へ〜

Slide 29

Slide 29 text

Test262にテストケースを追加する GroupBy のバグ直したん だ〜すごいでしょ〜 ???? で、test262 は?

Slide 30

Slide 30 text

Test262にテストケースを追加する だよね ????

Slide 31

Slide 31 text

Test262にテストケースを追加する ● test262は「Official ECMAScript Conformance Test Suite」 ○ https://github.com/tc39/test262 ● 要は「ECMAScriptを実装しているやつが満たしておくべきテスト ケース」 ● 結構エグいテストケースが多く、各エンジンの通過率は以下(2024 年4月23日)

Slide 32

Slide 32 text

Test262にテストケースを追加する ● 「GroupBy が文字列を受け取れるようになっていること」を検証する テストはtest262には存在しない ● そういうテストはあったほうが良さそう

Slide 33

Slide 33 text

Test262にテストケースを追加する https://github.com/tc39/test 262/issues/4036

Slide 34

Slide 34 text

Test262にテストケースを追加する ● こんなテストを追加 https://github.com/tc39/test262/bl ob/007b333af22d8b8466be3394b 9248345ac4445c9/test/built-ins/M ap/groupBy/string.js

Slide 35

Slide 35 text

まとめ ● GroupByのバグを自分で発見し自分で修正しtest262を更新するこ とができた ○ ぼーっと見てたらなんとなくバグを見つけただけなので発見の部 分に再現性はないが... ● WebKitのJavaScriptビルトインの実装の一部はJavaScriptで記述 されているので、C++などの知識がなくても簡単な修正なら可能