nashornのrhinoとの互換性 - JDK8正式リリース版・走り書き

まず、LiveConnectが全滅

  • JavaObject、JavaArrayオブジェクトがないので型変換が正しく行われない
  • JavaPackage、JavaClassはあるがJavaClassとjava.lang.Classの変換をやっていない
  • 可変長引数と配列の変換が行われていない
  • 実装レベルではjsのnumberはjavaの各種primitiveで持っているので型に依存するコードがコケる(rhinoではラッパークラスで持っていてnumberとNumberに正しく変換している)

これによりスクリプトからjavaのオブジェクトを呼び出す時、シグネチャのマッチに失敗する。このためほとんどのjavaコードをまともに呼び出せない。

nashornではJavaという独自のオブジェクトがあってvar Class = Java.type(descriptor)というふうに呼び出して動的にJavaClassを作るのが主な使い方だが先に挙げた欠陥があるので結局うまくいかない。さらにこの方法では余計なグルーコードを必要とする。

実装レベルでprimitiveで扱われているというのは普段は(javaの型だけならruntime/indy間の変換はjava.lang.invokeライブラが勝手にやるので)意識しなくても良いが無意識に型に依存したコードを書いたり型が重要なjava.lang.reflect.Array.newInstanceでうまくいかなくなる。

もう一つ、原因がよくわかっていないがJNIのリンクの仕方によってはうまく機能しない。これのせいでJOGLが変な挙動をする。

更に、es5.1ではあるがfor-each inとfunction statementがある。function statementはお約束のコンパイルされてないfunctionのBindingIdentifierがその環境に存在してReferenceErrorにならないという挙動をする。大した問題ではないが以前はバグがあってもっとおかしな挙動をしてrhinoとの互換性(rhinoもこのお約束の挙動である)が低かったが今は問題ない。

ここまで見てきたようにこれらの問題のほとんどはindyの影響を受ける部分である。indyを使っても弱い型付けが出来ない事による影響だと思われる。

弱い型付け特有の型変換プロセスはruntime側に持たせるしかなく、そうするとindyの恩恵を受けられなくなるのでスループットが悪くなり、ただ単にレイテンシも悪いだけの処理系へと成り下がってしまう。多分、ここがindyの限界ではないかと思う。

jdk8の正式リリースが来たので

久しぶりにnashornを見たけどnashornのLiveConnect実装はJavaPackageとJavaClassがあってJavaObjectとJavaArrayがないんだね。(まあ、挙動からわかってたけど)

LiveConnectにこの2つがなかったら使いものにならないじゃないか。
そのくせ、ブラウザじゃないのにJSObjectがあるってなんだ!作ってコミットしてやろうか……。

rhino fork その10

indy用のbranchを切った。
別物になるくらいの変更なんでしばらく音沙汰無くなるはず。

変更点としてはSlotがMethodHandleを持つようになっていわゆるClassyLayoutベースになる(というか最近出てきたesのjava実装の主流になってるので追従する事にした)。
ついでにSlotがTypeAnnotationを持つようになったのでいずれes4/js2.0の仕様が入る。

rhino fork その9

大事なことを言い忘れていたけどrhino fork(forkの名前はまだない)はjavascript1.8とes6の一部の機能をデフォルトとする(オプションとしてstrawmanとes4の機能が入る)。
javascript1.7以下は削除される予定で1.6以下は既に削除済みの状態だけどoriginal rhinoのデフォルトが1.7なのでこれは問題ない。es6の仕様はJanuary 20, 2014 Draft Rev 22を元にしているので初めから新しい仕様だよ。ミンナニハナイショダヨ!

互換性に関してはjs1.8までに先行実装された機能とes6の同じ機能には元から互換性がないのでbreak上等。

極力両方の仕様を残すけど、js1.8のgenerator expressionsとes6のgenerator functionsなど元からbreakしてる部分もあるけどこれは仕様のせいだからどうしようもない。break the webばかり言ってるけど実際にはexpression closuresとarrow functionsみたいに互換性もクソもない仕様ばかりだからbreakは必ず起こる。

そもそも新しいシンタックス入ってるからes5とes6にソースコードレベルで互換性が無いしね。

問題があるとすればrhinoのstrict modeがes4のstrict modeをベースとしjs1.5に先行実装されたstrict modeとes5のstrict modeの両方が実装されててes5のstrict modeが完全に実装されていないことくらいじゃないかな。rhinoからみればrhinoはjavascript実装なのでecma-262実装ではないんだけど最近純粋なjs実装ってrhinoしか生き残ってないよね。

v8なんて実装汚い上に新しい仕様に合わせて再実装してるから大変だろうしspidermonkeyみたいにのんびりやるのが一番いいと思う。

break上等──大事なことなので二回言いました。