Firefoxのjsエンジンのエラーメッセージを修正してみた

本記事は東京大学工学部の「電気電子情報実験・演習第二」における

「大規模ソフトウェアを手探る」という実験のレポートで作成したものです。

(初記事なので、少し他の人(特に同じ班員や、過去の作品)の書き方を参考にさせていただきました。まだhtmlが初心者みたいなもので、少し見にくいと思いますが、 ご容赦ください)

目次

はじめに

実験「大規模ソフトウェアを手探る」 では、オープンソースのソフトウェアのソースに何らかの変更を加えるという内容です。(詳細はリンク先、別のタブが開きます)

実験の初日に、チュートリアルの意味を込めて、gnuplotにおいて"plot"というコマンドの入力を省いてもplotしてくれる、という変更を行いました。 その後、各々が取り組む事柄によって班をつくり、グループ作業を行いました。

実験内容・動機

私の班では、FirefoxJavascriptエンジンである"SpiderMonkey"が出すエラーメッセージのうち、分かりにくいものとされているもの (Bugzillaというページにまとめらめている) を改善するということを テーマとしました。何故これに取り組もうと考えたかというと、実験のTAさんがSpiderMonkeyのコミッターであり、Javascript について教えていただけると考え、また自分の作成したパッチをコミットしていただけることが、自分の作品がFirefoxの役に立つことに繋がると考えたからです。

開発環境の整え方

環境構築の方法は、前述のTAさんがまとめてくださったページに記載してあり、そちらを参考にしました。

大まかな流れ

全体の大まかな流れ(コントリビュートまでの流れ)としては、同じ班のメンバーがまとめてくれた記事があります。 qiita.com

(彼がいろいろまとめてくれ、非常に助かりました)

やったこと

私は今回の実験で、2つのIssueに取り組みました。そのうち1つが解決しましたが、もう1つは未完成となってしまいました。未完成のものの状態も含め、下記に紹介したいと思います。

その1:変数定義時のエラーメッセージ

Javascript(その他C#なども)では、var x = 2; 等のように、代入演算子=を用いて、変数定義と初期化を同時に行うことが可能です。 しかし、ここで使用する演算子を、例えば複合代入演算子+=などにしてしまうと、

SyntaxError: missing ; before statement

といったエラーメッセージが表示されます。このエラーメッセージは、真の問題である演算子の誤りとは別のことを示している(セミコロンが抜けている?とは)ため、 分かりにくいです。

私は、これを

SyntaxError: SyntaxError: unexpected token: '+='
var x += 2;
.....^

というように、演算子の誤りを正しく示してくれるように変更しました。

この問題はこちらでレポートされています。

変更点

まず、上記のエラーメッセージ

SyntaxError: missing ; before statement

が、どのようにして引き起こされているかを確認します。すると、エラーメッセージがまとめて宣言されている js.msg ファイルにおいて、

JSMSG_SEMI_BEFORE_STMNT
として定義されていることが分かりました。そして、このエラーメッセージが発生させられる箇所をソース内で検索してみると、 なんと1箇所だけです。つまり、新しいエラーメッセージを定義して、これに置き換えることで、働きを意図したものに変えられるという訳です。

そこで、エラーメッセージを

SyntaxError: unexpected token: '+=':
var x += 2;
......^

となるように変更しました。(変更点はこちら)

 

その2: (未完成ですが) nullを継承したクラスを呼び出した時のエラー

Javascriptでは、nullであるものを継承したクラスを呼び出す、例えば

var B = null;
class C extends B{
    a(){ return super.x;}
}

などとすると

TypeError: function () {
} is not a constructor

のようなエラーが出ます。(functionがコンストラクタではないとは???)
この問題はこちらでレポートされています。

変更点

私は、nullを継承したクラスは、functionのプロトタイプであるとみなされるのではないかと考えました。

すると、 Interpreter.cpp というソースファイル内で、「superFunValという値がObjectまたはnullであるかどうか」によってエラー

ReportIsNotFunction(cx, superFunVal, JSDVG_IGNORE_STACK, CONSTRUCT);    

を呼び出すかどうか判別している箇所があり、 それがfunctionであるときに別のエラーメッセージを呼び出せばよいと考えました。

そのような変更をした結果、目的通り

TypeError: super constructor extends null is not a constructor

というエラーメッセージを呼び出すことに成功しました!

しかし、JavaScriptのtestでエラーが多数発生し、そこで実験の日程が終了してしまいました...

その他知っておくとよいこと

私はこの実験で、あまり多くのことをやれませんでした。その原因として、上記の変更その1において、誰か他の人が作り、Bugzillaから取り込まれる予定のパッチと、 変更点がかぶってしまったといったことがありました。これを解決するためにはrebaseということをしなければなりません。私はrebaseのやり方を全く知らなかったので、そこで多くの時間を消費してしまいました。

 

私はこちらのページ等を参考にしました。(それよりもTAさんの解説がありがたかったです)。

私のような失敗をしないためにも知っておくといいと思います。

おわりに

Firefoxを使っていた自分にとって、この実験ではこのような大規模なソフトウェアへのかかわり方を学べた有意義なものでした。JS開発の最初はやり方が分からず、またrebaseといった想定外なこともあり、 TAさんにはほぼ付きっきりで面倒を見てもらいました。TAさんや、この実験を用意してくださった先生へ感謝申し上げて、結びとさせていただきます。