🎄

ENCA 13日目: モジュールの識別子名で Unicode 文字列が扱えるように

2024/12/14に公開

モジュールの識別子名で Unicode 文字列が扱えるように

WebAssembly が文字列として UTF-8 を使うことを採用しました。これによりモジュールの識別子名が valid な UTF-8 であることが要請されています。

https://webassembly.github.io/spec/core/syntax/values.html#syntax-name

一方で ECMAScript では今までモジュールの識別子名が変数名と同じ制限を持っていたことから、WebAssembly としては問題ない識別子名であってもそれを読み込むことが出来ない場合があると指摘されました。ということで2020年9月に valid な Unicode 文字列をモジュールの識別子名として扱えるようにする変更が承認されました。

import { "\0 any unicode" as foo } from "some-module";
export { foo as "\0 any unicode" };

https://github.com/tc39/ecma262/pull/2154

UTF-16 と WTF-16

ECMAScript では文字列を内部的に16ビットの非負整数の配列で扱います。基本的に UTF-16 であると考えてよいですが、サロゲートペア的に整合性の取れていない不正な16ビットバイト列でも問題なく扱えます。これを UTF-16 に対して WTF-16 と呼ぶことがあります。なお Web IDL では USVStringDOMString として区別しています。

ES2024 Well-Formed Unicode Strings によって String.prototype.isWellFormed で正しい UTF-16 文字列となっているかの判定をすることができ、String.prototype.toWellFormed でサロゲートペアが不正になっている部分を 0xFFFD (REPLACEMENT CHARACTER) に置き換える事ができます。

WebAssembly が UTF-8 を強制するのはよいことなのだろうか

歴史的経緯からいくつかの言語で文字列として WTF-16 が採用されています。Java や C# そして ECMAScript が例として挙げられます。WebAssembly が様々な言語からコンパイルして生成されることを考えると、valid な UTF-8 のみを強制することは WTF-16 を採用している言語からコンパイルできず互換性の問題が起きる可能性があります。

この問題について WebAssembly を生成するための言語として開発され、TypeScript ライクである AssemblyScript の作者が問題提起をしました。

https://www.youtube.com/watch?v=Ri2NMnSQo4o

しかしこれが受け入れられなかったことから大きな亀裂が生じてしまいました。

https://github.com/WebAssembly/interface-types/issues/135

https://www.assemblyscript.org/standards-objections.html

Discussion