ものがたり(旧)

atsushieno.hatenablog.com に続く

昨日のせせこましい話をもう少しmoonlightに近づけて書いてみよう。

最近こっち方面で僕が関わっているのは(id:atsushieno:20070706でも書いたけど)CoreCLRのビルドである。当初、ソースに#if NET_2_1は使わずCecilベースのツールでマジカルに解決する、と予定されていたものだ。で、現実にアセンブリをいじるブツがmcs/toolsの下にlinkerとtunerとして存在していて、コレを元に作成されたアセンブリとMSのCoreCLRとのcorcompareも既に存在している

しかし実際にはソースをいじらずにはいられない部分もある。それが例えば昨日書いたXmlReaderだ。HasValueやReadAttributeValue()のように、2.1で消えてしまったpublic abstractなメンバーは、moonlightのCoreCLRでは、先のtunerによってinternal virtualになる*1。そしてそのメソッドの内容としては、単にthrow new SystemException()みたいなコードを定義しておくより他に無い。

一方、ReadAttributeValue()は、たとえばXmlWriter.WriteAttributes()の中では、属性間をMoveTo*Attribute()で回してReadAttributeValue()で属性値ノード間を回してWriteString()やWriteEntityRef()で書き込む…といった形で利用されている。

ここにCoreCLR用のXmlReaderがやってくるとどうなるかというと、XmlTextReaderの場合はpublicinternal overrideされている*2ので問題なく動作するが、System.Xml.Core.dllで定義されていないあらゆるXmlReaderが、ReadAttributeValue()を定義することを許されないまま(何しろそんなメソッドは公開されていないのである)、XmlWriterの当該メソッドを呼び出した途端に例外が投げられる、ということになってしまうのである。

こういうのは、仕方がないので、手作業で直していくしかない。

今回のXmlReaderのような件については、abstractメンバーはtunerで隠さないという方法で機械的に検出することができるので、あとは手作業でそれらを修正さえすれば良い。というわけで、手作業は発生してしまうわけである。やんぬるかな。

別ソースを書いて根本的に差し替える事例もある。System.dllのHttpWebRequestなんかがそうだ。

CLRのHttpWebRequestとCoreCLRのHttpWebRequestは、APIこそ類似しているが、実装コードは全くの別物だ。というよりCoreCLRではほとんど実装ですらない。CoreCLRにはWebRequestが存在しないので、WebRequest.Create()することもできない*3。HttpWebRequestの実装は、Silverlight上ではSystem.Silverlight.dllに含まれるBrowserHttpWebRequestしか存在しない。うーむ、moonlight deskletではどーするのだ。実装、作るんかね。

まあこういう例はHttpWebRequestくらいしか存在しない(と思う)ので、特別に対応するということになる。CLRのHttpWebRequestで使われているWebConnectionなんかはけっこうtuner泣かせなので(らしい)、ビルドしないですむなら外しておくに越したことはない。

まあ、そのうち、僕が先月作ったSystem.dll.sourcesを使うことになるかもしれない*4。僕のはファイル総数で1/4くらいまで減らしてあるわけだし。この辺でどう巻き込まれることになるかは、まだ分からない。

*1:多分。abstractだと派生クラスが定義不能であるため

*2:tunerによって書き換えられている

*3:だから、たとえばCoreCLRのXmlUrlResolverでは、HTTP URLを渡されるとNotImplementedExceptionが投げられる。XmlReader.Create()でHTTP URLを渡してみても分かる。

*4:実際にはsmcsで必要なクラスがいくつか存在しているので、もう少し残す必要のあるものがあるのだけど